📄 si57x_freqprogfirmware_withf300.c
字号:
//''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
// 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 + -