?? cc1000pic.c
字號:
#include "pic.h"
#include "cc1000.h"
#define BYTE unsigned char
#define UINT8 unsigned char
// Value of time-out timer during calibration
#define CAL_TIMEOUT 0x7FFE
#define LOCK_TIMEOUT 0x7FFE
// PA power setting
#define PA_VALUE 0xFF
//=======================================================
// CC1000的參數
//=======================================================
const unsigned char Configuration[] =
{
0x58, // 0x01, FREQ_2A
0x20, // 0x02, FREQ_1A
0x00, // 0x03, FREQ_0A
0x42, // 0x04, FREQ_2B
0x15, // 0x05, FREQ_1B
0x78, // 0x06, FREQ_0B
0x00, // 0x07, FSEP1
0xc8, // 0x08, FSEP0
0x81, // 0x09, CURRENT
0x10, // 0x0A, FRONT_END
0xFF, // 0x0B, PA_POW
0x48, // 0x0C, PLL
0x10, // 0x0D, LOCK
0x26, // 0x0E, CAL
0x8c, // 0x0F, MODEM2
0x6f, // 0x10, MODEM1
0x27, // 0x11, MODEM0
0x70, // 0x12, MATCH
0x01, // 0x13, FSCTRL
0x00, // 0x1C, PRESCALER
0x25, // 0x42, TEST4
};
/****************************************************************************/
//初始化CC1000
/* This routine sends configuration data to the CC1000 */
/****************************************************************************/
void ConfigureCC1000()
{
char i,val;
for (i=0;i<19;i++)
{
val=Configuration[i];
WriteToCC1000Register(i+1, val);
}
WriteToCC1000Register(0x1c,0x00);
WriteToCC1000Register(0x42,0x25);
}
/****************************************************************************/
// 寫單個寄存器
// IN:地址;數據
// OUT:NONE
/* This routine writes to a single CC1000 register */
/****************************************************************************/
void WriteToCC1000Register(char addr, char data)
{
unsigned char BitCounter;
PCLK=1;
PALE=0;
addr=(addr<<1)|0x01;
// Send address bits
for (BitCounter=0;BitCounter<8;BitCounter++)
{
if(addr&0x80)
{
PCLK=1;
PDATA=1;
}
else
{
PCLK=1;
PDATA=0;
}
asm("nop"); asm("nop"); asm("nop"); asm("nop");asm("nop");
PCLK=0;
addr=addr<<1;
}
PCLK=1;
PALE=1;
// Send data bits
for (BitCounter=0;BitCounter<8;BitCounter++)
{
if(data&0x80)
{
PCLK=1;
PDATA=1;
}
else
{
PCLK=1;
PDATA=0;
}
asm("nop"); asm("nop"); asm("nop"); asm("nop");asm("nop");
data=data<<1;
PCLK=0;
}
PCLK=1;
}
/****************************************************************************/
// 讀單個寄存器
// IN:地址
// OUT:數據
/* This routine reads from a single CC1000 register */
/****************************************************************************/
unsigned char ReadFromCC1000Register(unsigned char addr1)
{
char BitCounter;
unsigned char Byte;
PALE=1;
PCLK=1;
Byte=(addr1<<1)&0xFE;
PALE=0;
// Send address bits
for (BitCounter=0;BitCounter<8;BitCounter++)
{
if(Byte&0x80)
{
PCLK=1;
PDATA=1;
}
else
{
PCLK=1;
PDATA=0;
}
asm("nop"); asm("nop"); asm("nop"); asm("nop");asm("nop");
Byte=Byte<<1;
PCLK=0;
}
PCLK=1;
PDATA=1;
PALE=1;
TRISA|=0x04; // Set up PDATA as an input
Byte=0;
for (BitCounter=0;BitCounter<8;BitCounter++)
{
PCLK=0;
Byte=Byte<<1;
// Byte=Byte|PDO;
if(PDATA) Byte|=0x01;
else Byte&=0xFE;
asm("nop"); asm("nop"); asm("nop"); asm("nop");asm("nop");
PCLK=1;
}
TRISA&=~0x04; // Set up PDATA as an output again
PCLK=1;
PALE=1;
return Byte;
}
/****************************************************************************/
//復位CC1000,清所有寄存器
//IN:NONE
//OUT:NONE
/* This routine resets the CC1000, clearing all registers. */
/****************************************************************************/
void ResetCC1000(void)
{
char MainValue;
MainValue=ReadFromCC1000Register(CC1000_MAIN);
WriteToCC1000Register(CC1000_MAIN,MainValue & 0xFE); // Reset CC1000
WriteToCC1000Register(CC1000_MAIN,MainValue | 0x01); // Bring CC1000 out of reset
}
/****************************************************************************/
// 對CC1000進行校驗
//IN:NONE
//OUT:0--》失敗
/* This routine calibrates the CC1000 */
/* Returns 0 if calibration fails, non-zero otherwise. Checks the LOCK */
/* to check for success. */
/****************************************************************************/
char CalibrateCC1000(void)
{
int TimeOutCounter;
WriteToCC1000Register(CC1000_PA_POW,0x00); // Turn off PA to avoid spurs
// during calibration in TX mode
WriteToCC1000Register(CC1000_CAL,0xA6); // Start calibration
// Wait for calibration complete
for(TimeOutCounter=CAL_TIMEOUT; ((ReadFromCC1000Register(CC1000_CAL)&0x08)==0)&&(TimeOutCounter>0); TimeOutCounter--);
WriteToCC1000Register(CC1000_CAL,0x26); /* End calibration */
WriteToCC1000Register(CC1000_PA_POW,PA_VALUE); /* Restore PA setting */
// Wait for lock
for(TimeOutCounter=LOCK_TIMEOUT; ((ReadFromCC1000Register(CC1000_LOCK)&0x01)==0)&&(TimeOutCounter>0); TimeOutCounter--);
return ((ReadFromCC1000Register(CC1000_LOCK)&0x01)==1);
}
/****************************************************************************/
//從TX切換到RX。
//IN:RXCURRENT,RXPLL
//OUT:lock_status
/* This routine puts the CC1000 into RX mode (from TX). When switching to */
/* RX from PD, use WakeupC1000ToRX first */
/****************************************************************************/
char SetupCC1000RX(char RXCurrent,char RXPLL)
{
int i;
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);
}
/****************************************************************************/
//從RX切換到TX。
//IN:TXCURRENT,TXPLL
//OUT:lock_status
/* This routine puts the CC1000 into TX mode (from RX). When switching to */
/* TX from PD, use WakeupCC1000ToTX first */
/****************************************************************************/
char SetupCC1000TX(char TXCurrent, char TXPLL)
{
int i;
char lock_status;
WriteToCC1000Register(CC1000_PA_POW,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_POW,PA_VALUE); // Restore PA setting
// Return LOCK status to application
return (lock_status);
}
/****************************************************************************/
//進入省電模式
//IN:NONE
//OUT:NONE
/* This routine puts the CC1000 into power down mode. Use WakeUpCC1000ToRX */
/* followed by SetupCC1000RX or WakeupCC1000ToTX followed by SetupCC1000TX */
/* to wake up from power down */
/****************************************************************************/
void SetupCC1000PD(void)
{
WriteToCC1000Register(CC1000_MAIN,0x3F); // Put CC1000 into power-down
WriteToCC1000Register(CC1000_PA_POW,0x00); // Turn off PA to minimise current draw
}
/****************************************************************************/
//從省電模式喚醒到接收模式
//IN:RXCurrent;RXPLL
//OUT:NONE
/* This routine wakes the CC1000 up from PD mode to RX mode, call */
/* SetupCC1000RX after this routine is finished. */
/****************************************************************************/
void WakeUpCC1000ToRX(char RXCurrent, char RXPLL)
{
int i;
WriteToCC1000Register(CC1000_MAIN,0x3B); // Turn on xtal oscillator core
WriteToCC1000Register(CC1000_CURRENT,RXCurrent); // Program VCO current for RX
WriteToCC1000Register(CC1000_PLL,RXPLL); // Use RX refdiv setting
// Insert wait routine here, must wait for xtal oscillator to stabilise,
// typically takes 2-5ms.
for (i=0;i<0x7FFE;i++);
WriteToCC1000Register(CC1000_MAIN,0x39); // Turn on bias generator
// Wait for 250us, insert wait loop here
WriteToCC1000Register(CC1000_MAIN,0x31); // Turn on frequency synthesiser
}
/****************************************************************************/
//從省電模式喚醒到發送模式
//IN:TXCurrent;TXPLL
//OUT:NONE
/* This routine wakes the CC1000 up from PD mode to TX mode, call */
/* SetupCC1000TX after this routine is finished. */
/****************************************************************************/
void WakeUpCC1000ToTX(char TXCurrent,char TXPLL)
{
int i;
WriteToCC1000Register(CC1000_MAIN,0xFB); // Turn on xtal oscillator core
WriteToCC1000Register(CC1000_CURRENT,TXCurrent); // Program VCO current for TX
WriteToCC1000Register(CC1000_PLL,TXPLL); // Use TX refdiv setting
// Insert wait routine here, must wait for xtal oscillator to stabilise,
// typically takes 2-5ms.
for (i=0;i<0x7FFE;i++);
WriteToCC1000Register(CC1000_MAIN,0xF9); // Turn on bias generator
// Wait for 250us, insert wait loop here
WriteToCC1000Register(CC1000_PA_POW,PA_VALUE); // Turn on PA
WriteToCC1000Register(CC1000_MAIN,0xF1); // Turn on frequency synthesiser
}
/****************************************************************************/
/* This routine locks the averaging filter of the CC1000 */
/****************************************************************************/
/*
void AverageManualLockCC1000(void)
{
WriteToCC1000Register(CC1000_MODEM1,0x19);
}
/****************************************************************************/
/* This routine unlocks the averaging filter of the CC1000 */
/****************************************************************************/
/*
void AverageFreeRunCC1000(void)
{
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(void)
{
WriteToCC1000Register(CC1000_MODEM1,0x01);
}
/****************************************************************************/
/* This routine reads the current calibration values from the CC1000 */
/****************************************************************************/
/*
void ReadCurrentCalibration(char *val1, char *val2)
{
*val1=ReadFromCC1000Register(CC1000_TEST0);
*val2=ReadFromCC1000Register(CC1000_TEST2);
}
/****************************************************************************/
/* This routine overrides the current calibration of the CC1000 */
/****************************************************************************/
/*
void OverrideCurrentCalibration(char val1, 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(void)
{
WriteToCC1000Register(CC1000_TEST5,0x00);
WriteToCC1000Register(CC1000_TEST6,0x00);
}
/****************************************************************************/
/* This routine resets the CC1000 frequency synthesizer */
/****************************************************************************/
void ResetFreqSynth(void)
{
char modem1_value;
modem1_value = ReadFromCC1000Register(CC1000_MODEM1)&~0x01;
WriteToCC1000Register(CC1000_MODEM1,modem1_value);
WriteToCC1000Register(CC1000_MODEM1,modem1_value|0x01);
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -