⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 si57x_freqprogfirmware_withf300.c

📁 C8051F300 & Si57x ANSI C Reference Design
💻 C
📖 第 1 页 / 共 3 页
字号:
//''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
// Copyright 2007 by Silicon Laboratories
// 
// Si57x_FreqProgFirmware_withF300.c
//
// Distributed by: Silicon Laboratories, Inc.
//
// This file contains proprietary information.
// No dissemination allowed without prior written permission
// from Silicon Laboratories, Inc.
//
// Released August 30, 2007
//
//''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
#include <compiler_defs.h>
#include <c8051F300_defs.h>
#include <math.h>                      // Used for the floorf() function

//-----------------------------------------------------------------------------
// Global CONSTANTS
//-----------------------------------------------------------------------------

#define USE_I2C                       // enable this if I2C is going to 
                                      // be used to get to the target device

#define DEBUG                         // enable this to run DEBUG code to verify the I2C    

//these must be floating point number especially 2^28 so that
//there is enough memory to use them in the calculation
#define POW_2_16              65536.0
#define POW_2_24           16777216.0
#define POW_2_28          268435456.0


#define SYSCLK            24500000        // System clock frequency in Hz

#define SMB_FREQUENCY     100000          // Target SCL clock rate
                                          // Can be 100kHz or 400kHz

#define RESET_DELAY_TIME  0.015           // time of delay after the Si57x reset in seconds

#define WRITE             0x00            // SMBus WRITE command
#define READ              0x01            // SMBus READ command

#define INTERRUPT_TIMER2    5             // Timer2 Overflow

// Device addresses (7 bits, lsb is a don't care)
#define  DEVICE_ADDR      0xAA //55//00            // Device address for slave target--must be loaded into upper 7 bits
                                       
// SMBus Buffer Size
#define  SMB_BUFF_SIZE    0x08            // Defines the maximum number of bytes
                                          // that can be sent or received in a
                                          // single transfer

// Status vector - top 4 bits only
#define  SMB_MTSTA        0xE0            // (MT) start transmitted
#define  SMB_MTDB         0xC0            // (MT) data byte transmitted
#define  SMB_MRDB         0x80            // (MR) data byte received
// End status vector definition

#define FREQ_LIST_LENGTH	38				//length of the frequency list (includes start-up frequency)

//------------------------------------------------------------------------------------
// conversion and find dividers variables
//------------------------------------------------------------------------------------

// Change the fout0 and fout1 to configure the Si57x
// frequency plan. See datasheet for fout0 and fout1 ranges.
// Both values must be given in MHz.
#define FOUT_START_UP 622.08				//MHz

code const float fout0 = FOUT_START_UP;

code const float fout1[FREQ_LIST_LENGTH] =	//MHz
{27.000000 ,
61.440000 , 
74.175824 , 
74.250000 ,
100.000000 ,
106.250000 ,
125.000000 ,
133.333300 ,
155.520000 ,
156.250000 ,
161.132813 ,
164.355469 ,
167.331646 ,
167.410714 ,
172.642300 ,
173.370747 ,
176.095145 ,
176.838163 ,
200.000000 ,
212.500000 ,
368.640000 ,
491.520000 ,
622.080000 ,
625.000000 ,
644.531250 ,
657.421875 ,
666.514286 ,
669.326580 ,
672.162712 ,
690.569196 ,
693.482991 ,
704.380580 ,
707.352650 ,
800.000000 ,
933.120000 ,
1000.000000 ,
1400.000000 ,
FOUT_START_UP };								//keeps start up frequency in the loop


// Si57x's fdco range -- DO NOT EDIT
code const float FDCO_MAX = 5670; //MHz 
code const float FDCO_MIN = 4850; //MHz

code const unsigned char HS_DIV[6] = {11, 9, 7, 6, 5, 4};

unsigned char reg[6];
unsigned char counter;
unsigned char n1;
unsigned char initial_n1;
unsigned char hsdiv;
unsigned char initial_hsdiv;
unsigned char done = 0;
unsigned char validCombo;
unsigned char reg137;
unsigned char next = 0;

unsigned int divider_max;
unsigned int curr_div;
unsigned int whole;

unsigned long temp_bits;
unsigned long frac_bits;

float rfreq;
float fxtal;
float curr_n1;
float n1_tmp;

float currentFrequency;
int currFreq;
unsigned long initial_rfreq_long;
unsigned long final_rfreq_long;

//-----------------------------------------------------------------------------
// Global VARIABLES
//-----------------------------------------------------------------------------
unsigned char* pSMB_DATA_IN;           // Global pointer for SMBus data
                                       // All receive data is written here

unsigned char SMB_SINGLEBYTE_OUT;      // Global holder for single byte writes.

unsigned char* pSMB_DATA_OUT;          // Global pointer for SMBus data.
                                       // All transmit data is read from here

unsigned char SMB_DATA_LEN;            // Global holder for number of bytes
                                       // to send or receive in the current
                                       // SMBus transfer.

unsigned char WORD_ADDR;               // Global holder for the  word
                                       // address that will be accessed in
                                       // the next transfer

unsigned char TARGET;                  // Target SMBus slave address

bit SMB_BUSY = 0;                      // Software flag to indicate when the
                                       // I2C_ByteRead() or
                                       // I2C_ByteWrite()
                                       // functions have claimed the SMBus

bit SMB_RW;                            // Software flag to indicate the
                                       // direction of the current transfer

bit SMB_SENDWORDADDR;                  // When set, this flag causes the ISR
                                       // to send the 8-bit <WORD_ADDR>
                                       // after sending the slave address.


bit SMB_RANDOMREAD;                    // When set, this flag causes the ISR
                                       // to send a START signal after sending
                                       // the word address.                                      
                                       // The ISR handles this
                                       // switchover if the <SMB_RANDOMREAD>
                                       // bit is set.

bit SMB_ACKPOLL;                       // When set, this flag causes the ISR
                                       // to send a repeated START until the
                                       // slave has acknowledged its address

/*
#ifdef DEBUG
SBIT(LED, SFR_P0, 2); //sbit LED = P0^2;                       // LED on port P0.2
SBIT(RESET_TEST_SIGNAL, SFR_P0, 3); //sbit RESET_TEST_SIGNAL = P0^3;         // toggled when the reset delay is running
#endif
*/

SBIT(SDA, SFR_P0, 0); //sbit SDA = P0^0;                       // SMBus on P0.0
SBIT(SCL, SFR_P0, 1); //sbit SCL = P0^1;                       // and P0.1

//-----------------------------------------------------------------------------
// Function PROTOTYPES
//-----------------------------------------------------------------------------


void SMBus_Init(void);
void Timer_Init(void);
void Timer1_Init(void);
void Timer2_Init(void);
void Port_Initializer(void);
void Peripheral_Config(void);
void ReadStartUpConfiguration(void);
void RunFreqProg(void);
void UpdateStatusOutput(void);
unsigned char SetBits(unsigned char original, unsigned char reset_mask, 
                      unsigned char new_val);

//void SMBus_ISR(void);
void I2C_ByteWrite(unsigned char addr, unsigned char dat);
unsigned char I2C_ByteRead(unsigned char addr);

//-----------------------------------------------------------------------------
// MAIN Routine
//-----------------------------------------------------------------------------

void main (void){

   Peripheral_Config();

   IE0 = 0;
   currFreq = FREQ_LIST_LENGTH - 1;
   ReadStartUpConfiguration();
   UpdateStatusOutput();
   currFreq = 0;

   while(1)								//always run
   {
      while(next == 0) {}				//wait for button to be pressed
      RunFreqProg();
	  next = 0;
	  UpdateStatusOutput();
	  currFreq = currFreq + 1;
	  if (currFreq > (FREQ_LIST_LENGTH - 1)) currFreq = 0;
   }
}

//
// Interrupt to handle the button press; when button is pressed set 'next' to high to allow main(void) to proceed
//
void ButtonPushed(void) interrupt INTERRUPT_INT0 
{
  next = 1;
}


//
// Update status outputs
//
void UpdateStatusOutput(void)
{
	P0 = (0x80 | ((~currFreq) << 2)); //need to setup cross bar to support writing out on P0
}

//
// Set frequency using synchronous parallel interface; this function runs whenever button is pressed
//
unsigned char ReadSynchronousSelectInputs()
{
	return (P0 >> 2);
}

//
// Set frequency using asynchronous parallel interface; this function runs continuously
//
unsigned char ReadAsynchronousSelectInputs()
{
	return (P0 >> 2);
}
	


//
// Reads start-up register contents for RFREQ, HS_DIV, and N1 and calculates the internal crystal frequency (fxtal)
//
void ReadStartUpConfiguration(void)
{

	I2C_ByteWrite(135, 0x01); 			//recall the initial state of the device into NVM

	// read registers 7 to 12
	// reg[0] is equivalent to register 7 in the device
	// reg[5] is register 12 in the device
	for(counter=0; counter<6; counter++)
	{
		reg[counter] = I2C_ByteRead(counter+7); 
	}

	// HS_DIV conversion
	initial_hsdiv = ((reg[0] & 0xE0) >> 5) + 4; // get reg 7 bits 5, 6, 7
	// initial_hsdiv's value could be verified here to ensure that it is one

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -