📄 cc1000.c
字号:
#pragma sfr
#pragma nop
#define PCLK P2.0
#define PALE P2.1
#define PDATA P2.2
#define PDATA_mode PM2.2
/* Register addresses */
#define CC1000_MAIN 0x00
#define CC1000_FREQ_2A 0x01
#define CC1000_FREQ_1A 0x02
#define CC1000_FREQ_0A 0x03
#define CC1000_FREQ_2B 0x04
#define CC1000_FREQ_1B 0x05
#define CC1000_FREQ_0B 0x06
#define CC1000_FSEP1 0x07
#define CC1000_FSEP0 0x08
#define CC1000_CURRENT 0x09
#define CC1000_FRONT_END 0x0A
#define CC1000_PA_PDW 0x0B
#define CC1000_PLL 0x0C
#define CC1000_LOCK 0x0D
#define CC1000_CAL 0x0E
#define CC1000_MODEM2 0x0F
#define CC1000_MODEM1 0x10
#define CC1000_MODEM0 0x11
#define CC1000_MATCH 0x12
#define CC1000_FSCTRL 0x13
#define CC1000_FSHAPE7 0x14
#define CC1000_FSHAPE6 0x15
#define CC1000_FSHAPE5 0x16
#define CC1000_FSHAPE4 0x17
#define CC1000_FSHAPE3 0x18
#define CC1000_FSHAPE2 0x19
#define CC1000_FSHAPE1 0x1A
#define CC1000_FSDELAY 0x1B
#define CC1000_PRESCALER 0x1C
#define CC1000_TEST6 0x40
#define CC1000_TEST5 0x41
#define CC1000_TEST4 0x42
#define CC1000_TEST3 0x43
#define CC1000_TEST2 0x44
#define CC1000_TEST1 0x45
#define CC1000_TEST0 0x46
#define LOCK_NOK 0x00
#define LOCK_OK 0x01
#define LOCK_RECAL_OK 0x02
#define TXCurrent 0xF3
#define RXCurrent 0x8C
// Value of time-out timer during calibration
#define CAL_TIMEOUT 0x7FFE
#define LOCK_TIMEOUT 0x7FFE
// PA power setting
#define PA_VALUE 0xF0
sreg unsigned char addr;
sreg unsigned char data;
// 869.850 MHz, +5 dBm output (Europe) // address
const unsigned char DefaultConfig868[35] = {0x58,0x60,0x00,0x58,0x5B,0x43,0x01,0xAB,0x8C,0x32, // 01 ~ 0a
0xFF,0x30,0x10,0x26,0x90,0x69,0x07,0x10,0x01,0x1c, // 0b ~ 14
0x16,0x10,0x0A,0x06,0x03,0x01,0x0F,0x00,0x00,0x00, // 15 ~ 1c, 40,41
0x3F,0x00 };
const unsigned char TXPLL = 0x30;
const unsigned char RXPLL = 0x30;
void WriteToCC1000Register(char reg_addr, char reg_data)
{
unsigned char BitCounter;
PDATA_mode = 0;
addr = reg_addr;
data = reg_data;
PALE=1;
NOP();
PALE=0;
for (BitCounter=0;BitCounter<7;BitCounter++)
{
PCLK=1;
addr=addr<<1;
PDATA = addr.7 ;
NOP();
PCLK=0;
}
NOP();
PCLK=1;
PDATA=1;
NOP();
PCLK=0;
NOP();
PCLK=1;
NOP();
PALE=1;
for (BitCounter=0;BitCounter<8;BitCounter++)
{
PCLK=1;
PDATA = data.7 ;
data=data<<1;
NOP();
PCLK=0;
}
NOP();
PCLK=1;
}
unsigned char ReadFromCC1000Register(char read_addr)
{
unsigned char BitCounter;
addr = read_addr;
PDATA_mode = 0;
PALE=1;
NOP();
PALE=0;
for (BitCounter=0;BitCounter<7;BitCounter++)
{
PCLK=1;
addr=addr<<1;
PDATA = addr.7 ;
NOP();
PCLK=0;
}
NOP();
PCLK=1;
PDATA=0;
NOP();
PCLK=0;
NOP();
PCLK=1;
NOP();
PALE=1;
NOP();
NOP();
PDATA_mode = 1;
NOP();
NOP();
for (BitCounter=0;BitCounter<8;BitCounter++)
{
PCLK=0;
data = data<<1;
data.0 = PDATA;
NOP();
PCLK=1;
}
NOP();
PCLK=1;
return(data);
}
/****************************************************************************/
/* This routine set up all register of CC1000. */
/****************************************************************************/
void SetupCC1000All()
{
unsigned char counter;
unsigned char value;
for (counter=0x01;counter<=0x1C;counter++) {
value=DefaultConfig868[counter-1];
WriteToCC1000Register(counter,value);
}
for (counter=0x40;counter<=0x44;counter++) {
value=DefaultConfig868[counter-0x40+0x1C];
WriteToCC1000Register(counter,value);
}
}
/****************************************************************************/
/* This routine resets the CC1000, clearing all registers. */
/****************************************************************************/
void ResetCC1000()
{
unsigned int i;
unsigned char MainValue;
MainValue=ReadFromCC1000Register(CC1000_MAIN);
WriteToCC1000Register(CC1000_MAIN,MainValue & 0xFE); // Reset CC1000
WriteToCC1000Register(CC1000_MAIN,MainValue | 0x01); // Bring CC1000 out of reset
for (i=0;i<0x10000;i++);
}
void CalibrateCC1000()
{
unsigned int i;
// unsigned int TimeOutCounter;
WriteToCC1000Register(CC1000_MAIN,0x11);
WriteToCC1000Register(CC1000_CAL,0xA6); // Start calibration
// Wait for calibration complete
// for(TimeOutCounter=CAL_TIMEOUT; ((ReadFromCC1000Register(CC1000_CAL)&0x08)==0)&&(TimeOutCounter>0); TimeOutCounter--);
// Wait for lock
// for(TimeOutCounter=LOCK_TIMEOUT; ((ReadFromCC1000Register(CC1000_LOCK)&0x01)==0)&&(TimeOutCounter>0); TimeOutCounter--);
for (i=0;i<0x50000;i++);
WriteToCC1000Register(CC1000_CAL,0x26); /* End calibration */
WriteToCC1000Register(CC1000_PA_PDW,0x00); // Turn off PA to avoid spurs
// during calibration in TX mode
WriteToCC1000Register(CC1000_MAIN,0xE1);
WriteToCC1000Register(CC1000_CAL,0xA6); // Start calibration
for (i=0;i<0x50000;i++);
// Wait for calibration complete
// for(TimeOutCounter=CAL_TIMEOUT; ((ReadFromCC1000Register(CC1000_CAL)&0x08)==0)&&(TimeOutCounter>0); TimeOutCounter--);
// Wait for lock
// for(TimeOutCounter=LOCK_TIMEOUT; ((ReadFromCC1000Register(CC1000_LOCK)&0x01)==0)&&(TimeOutCounter>0); TimeOutCounter--);
WriteToCC1000Register(CC1000_CAL,0x26); /* End calibration */
WriteToCC1000Register(CC1000_MAIN,0xFB);
for (i=0;i<0x50000;i++);
// return ((ReadFromCC1000Register(CC1000_LOCK)&0x01)==1);
}
/****************************************************************************/
/* This routine resets the CC1000 frequency synthesizer */
/****************************************************************************/
void ResetFreqSynth()
{
unsigned char modem1_value;
modem1_value = ReadFromCC1000Register(CC1000_MODEM1)&~0x01;
WriteToCC1000Register(CC1000_MODEM1,modem1_value);
WriteToCC1000Register(CC1000_MODEM1,modem1_value|0x01);
}
/****************************************************************************/
/* This routine puts the CC1000 into RX mode (from TX). When switching to */
/* RX from PD, use WakeupC1000ToRX first */
/****************************************************************************/
void SetupCC1000ToRX()
{
unsigned int i;
unsigned char lock_status;
WriteToCC1000Register(CC1000_MAIN,0x11); // Switch into RX, switch to freq. reg A
WriteToCC1000Register(CC1000_PLL,RXPLL); // Use RX refdiv setting
WriteToCC1000Register(CC1000_CURRENT,RXCurrent); // Program VCO current for RX
// Wait 250us before monitoring LOCK
for (i=0;i<0x1000;i++);
// Wait for lock
// for(i=LOCK_TIMEOUT; ((ReadFromCC1000Register(CC1000_LOCK)&0x01)==0)&&(i>0); i--);
// If PLL in lock
// if ((ReadFromCC1000Register(CC1000_LOCK)&0x01)==0x01){
// Indicate PLL in LOCK
// lock_status = LOCK_OK;
// Else (PLL out of LOCK)
// }else{
// If recalibration ok
// if(CalibrateCC1000()){
// Indicate PLL in LOCK
// lock_status = LOCK_RECAL_OK;
// Else (recalibration failed)
// }else{
// Reset frequency syncthesizer (ref.: Errata Note 01)
// ResetFreqSynth();
// Indicate PLL out of LOCK
// lock_status = LOCK_NOK;
// }
// }
// Return LOCK status to application
// return (lock_status);
}
void StopCC1000RX()
{
WriteToCC1000Register(CC1000_MAIN,0x3B);
}
/****************************************************************************/
/* This routine puts the CC1000 into TX mode (from RX). When switching to */
/* TX from PD, use WakeupCC1000ToTX first */
/****************************************************************************/
void SetupCC1000ToTX()
{
unsigned int i;
unsigned char lock_status;
WriteToCC1000Register(CC1000_PA_PDW,0x00); // Turn off PA to avoid frequency splatter
WriteToCC1000Register(CC1000_MAIN,0xE1); // Switch into TX, switch to freq. reg B
WriteToCC1000Register(CC1000_PLL,TXPLL); // Use TX refdiv setting
WriteToCC1000Register(CC1000_CURRENT,TXCurrent); // Program VCO current for TX
// Wait 250us before monitoring LOCK
for (i=0;i<0x1000;i++);
// Wait for lock
// for(i=LOCK_TIMEOUT; ((ReadFromCC1000Register(CC1000_LOCK)&0x01)==0x00)&&(i>0); i--);
// If PLL in lock
// if ((ReadFromCC1000Register(CC1000_LOCK)&0x01)==0x01){
// Indicate PLL in LOCK
// lock_status = LOCK_OK;
// Else (PLL out of LOCK)
// }else{
// If recalibration ok
// if(CalibrateCC1000()){
// Indicate PLL in LOCK
// lock_status = LOCK_RECAL_OK;
// Else (recalibration failed)
// }else{
// Reset frequency syncthesizer (ref.: Errata Note 01)
// ResetFreqSynth();
// Indicate PLL out of LOCK
// lock_status = LOCK_NOK;
// }
// }
// Increase output power
WriteToCC1000Register(CC1000_PA_PDW,PA_VALUE); // Restore PA setting
for (i=0;i<0x100;i++);
// Return LOCK status to application
// return (lock_status);
}
void StopCC1000TX()
{
WriteToCC1000Register(CC1000_MAIN,0x3B);
WriteToCC1000Register(CC1000_PA_PDW,0x00);
}
/****************************************************************************/
/* This routine locks the averaging filter of the CC1000 */
/****************************************************************************/
void AverageManualLockCC1000()
{
WriteToCC1000Register(CC1000_MODEM1,0x19);
}
/****************************************************************************/
/* This routine unlocks the averaging filter of the CC1000 */
/****************************************************************************/
void AverageFreeRunCC1000()
{
WriteToCC1000Register(CC1000_MODEM1,0x09);
}
/****************************************************************************/
/* This routine sets up the averaging filter of the CC1000 for automatic */
/* lock. This can be used in polled receivers. */
/****************************************************************************/
void AverageAutoLockCC1000()
{
WriteToCC1000Register(CC1000_MODEM1,0x01);
}
/****************************************************************************/
/* This routine reads the current calibration values from the CC1000 */
/****************************************************************************/
void ReadCurrentCalibration(unsigned char *val1, unsigned char *val2)
{
*val1=ReadFromCC1000Register(CC1000_TEST0);
*val2=ReadFromCC1000Register(CC1000_TEST2);
}
/****************************************************************************/
/* This routine overrides the current calibration of the CC1000 */
/****************************************************************************/
void OverrideCurrentCalibration(unsigned char val1, unsigned char val2)
{
WriteToCC1000Register(CC1000_TEST5,(val1&0x0F)|0x10);
WriteToCC1000Register(CC1000_TEST6,(val2&0x1F)|0x20);
}
/****************************************************************************/
/* This routine stops override of the CC1000 calibration values */
/****************************************************************************/
void StopOverridingCalibration()
{
WriteToCC1000Register(CC1000_TEST5,0x00);
WriteToCC1000Register(CC1000_TEST6,0x00);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -