?? cc1020.c
字號(hào):
// Monitor actual calibration start (ref. Errata Note 04 - CC1020)
for(TimeOutCounter=CAL_TIMEOUT; ((ReadFromCC1020Register(CC1020_STATUS)&0x80)==0x80)&&(TimeOutCounter>0); TimeOutCounter--);
// Important note:
// In active mode the CC1020 should theoretically initiate an internal action/process more or less
// instantly upon receiving any command from e.g. an MCU. However, upon sending a [calibration start]
// command to CC1020, tests shows that the [STATUS.CAL_COMPLETE]-signal sometimes remains asserted
// (or idle) close to 100 usec after the command has been originally issued. Consequently this process
// must be carefully monitored to avoid premature PLL LOCK monitoring; do not proceed with subsequent
// PLL LOCK monitoring before the calibration has actually completed inside the CC1020! Errata Note 04
// suggests that [calibration start] should be monitored by a fixed timeout > 100 usec. However, the
// above method implements an adaptive monitoring of [calibration start], which basically waits for the
// [STATUS.CAL_COMPLETE]-signal to initialise/deassert (indicating calibration has actually started)
// before proceeding with monitoring calibration complete and PLL LOCK. Chipcon considers both methods
// safe, and thus leaves it up to the user, which one to use.
// Monitor calibration complete
for(TimeOutCounter=CAL_TIMEOUT; ((ReadFromCC1020Register(CC1020_STATUS)&0x80)==0x00)&&(TimeOutCounter>0); TimeOutCounter--);
// Monitor lock
for(TimeOutCounter=LOCK_TIMEOUT; ((ReadFromCC1020Register(CC1020_STATUS)&0x10)==0x00)&&(TimeOutCounter>0); TimeOutCounter--);
// Abort further recalibration attempts if successful LOCK
if((ReadFromCC1020Register(CC1020_STATUS)&0x10) == 0x10) {
break;
}
}
// Restore PA setting
WriteToCC1020Register(CC1020_PA_POWER, PA_POWER);
// Return state of LOCK_CONTINUOUS bit
return ((ReadFromCC1020Register(CC1020_STATUS)&0x10)==0x10);
}
/****************************************************************************/
/* This routine puts the CC1020 into RX mode (from TX). When switching to */
/* RX from PD, use WakeupC1020ToRX first */
/****************************************************************************/
char SetupCC1020RX(char RXANALOG, char PA_POWER)
{
volatile int TimeOutCounter;
char lock_status;
// Switch into RX, switch to freq. reg A
WriteToCC1020Register(CC1020_MAIN,0x11);
// Setup bias current adjustment
WriteToCC1020Register(CC1020_ANALOG,RXANALOG);
// Monitor LOCK
for(TimeOutCounter=LOCK_TIMEOUT; ((ReadFromCC1020Register(CC1020_STATUS)&0x10)==0)&&(TimeOutCounter>0); TimeOutCounter--);
// If PLL in lock
if((ReadFromCC1020Register(CC1020_STATUS)&0x10)==0x10){
// Indicate PLL in LOCK
lock_status = LOCK_OK;
// Else (PLL out of LOCK)
}else{
// If recalibration ok
if(CalibrateCC1020(PA_POWER)){
// Indicate PLL in LOCK
lock_status = LOCK_RECAL_OK;
// Else (recalibration failed)
}else{
// Indicate PLL out of LOCK
lock_status = LOCK_NOK;
}
}
// Switch RX part of CC1020 on
WriteToCC1020Register(CC1020_MAIN,0x01);
// Return LOCK status to application
return (lock_status);
}
/****************************************************************************/
/* This routine puts the CC1020 into TX mode (from RX). When switching to */
/* TX from PD, use WakeupCC1020ToTX first */
/****************************************************************************/
char SetupCC1020TX(char TXANALOG, char PA_POWER)
{
volatile int TimeOutCounter;
char lock_status;
// Turn off PA to avoid frequency splatter
WriteToCC1020Register(CC1020_PA_POWER,0x00);
// Setup bias current adjustment
WriteToCC1020Register(CC1020_ANALOG,TXANALOG);
// Switch into TX, switch to freq. reg B
WriteToCC1020Register(CC1020_MAIN,0xC1);
// Monitor LOCK
for(TimeOutCounter=LOCK_TIMEOUT; ((ReadFromCC1020Register(CC1020_STATUS)&0x10)==0)&&(TimeOutCounter>0); TimeOutCounter--);
// If PLL in lock
if((ReadFromCC1020Register(CC1020_STATUS)&0x10)==0x10){
// Indicate PLL in LOCK
lock_status = LOCK_OK;
// Else (PLL out of LOCK)
}else{
// If recalibration ok
if(CalibrateCC1020(PA_POWER)){
// Indicate PLL in LOCK
lock_status = LOCK_RECAL_OK;
// Else (recalibration failed)
}else{
// Indicate PLL out of LOCK
lock_status = LOCK_NOK;
}
}
// Restore PA setting
WriteToCC1020Register(CC1020_PA_POWER,PA_POWER);
// Turn OFF DCLK squelch in TX
WriteToCC1020Register(CC1020_INTERFACE,ReadFromCC1020Register(CC1020_INTERFACE)&~0x10);
// Return LOCK status to application
return (lock_status);
}
/****************************************************************************/
/* This routine puts the CC1020 into power down mode. Use WakeUpCC1020ToRX */
/* followed by SetupCC1020RX or WakeupCC1020ToTX followed by SetupCC1020TX */
/* to wake up from power down */
/****************************************************************************/
void SetupCC1020PD(void)
{
// Put CC1020 into power-down
WriteToCC1020Register(CC1020_MAIN,0x1F);
// Turn off PA to minimise current draw
WriteToCC1020Register(CC1020_PA_POWER,0x00);
}
/****************************************************************************/
/* This routine wakes the CC1020 up from PD mode to RX mode */
/****************************************************************************/
void WakeUpCC1020ToRX(char RXANALOG)
{
volatile int i;
// Turn on xtal oscillator core
WriteToCC1020Register(CC1020_MAIN,0x1B);
// Setup bias current adjustment
WriteToCC1020Register(CC1020_ANALOG,RXANALOG);
// Insert wait routine here, must wait for xtal oscillator to stabilise,
// typically takes 2-5ms.
for (i=0x0260; i > 0; i--);
// Turn on bias generator
WriteToCC1020Register(CC1020_MAIN,0x19);
// Wait for 150 usec
for (i=0x0010; i > 0; i--);
// Turn on frequency synthesiser
WriteToCC1020Register(CC1020_MAIN,0x11);
}
/****************************************************************************/
/* This routine wakes the CC1020 up from PD mode to TX mode */
/****************************************************************************/
void WakeUpCC1020ToTX(char TXANALOG)
{
volatile int i;
// Turn on xtal oscillator core
WriteToCC1020Register(CC1020_MAIN,0xDB);
// Setup bias current adjustment
WriteToCC1020Register(CC1020_ANALOG,TXANALOG);
// Insert wait routine here, must wait for xtal oscillator to stabilise,
// typically takes 2-5ms.
for (i=0x0260; i > 0; i--);
// Turn on bias generator
WriteToCC1020Register(CC1020_MAIN,0xD9);
// Wait for 150 usec
for (i=0x0010; i > 0; i--);
// Turn on frequency synthesiser
WriteToCC1020Register(CC1020_MAIN,0xD1);
}
/****************************************************************************/
/* This routine acquires the average RSSI level in dBm */
/****************************************************************************/
int ReadRSSIlevelCC1020(void){
char i;
unsigned char RSSI[5];
unsigned char FILTER;
int RSSI_dBm;
// RSSI formula based on CC1020 datahseet and application note 30:
// P = 1.5 x RSSI - 3 x VGA_SETTING - RSSI_Offset [dBm]
/*
VGA_SETTING based on SmartRF Studio - CC1020, v5.3.0.0
Note: these settings could be subject to optimisation.
434MHz range:
-------------------------------------------------
12.5 => VGA3 = 0x31 => VGA_SETTING = 0x11 = 17dec
25 => VGA3 = 0x2F => VGA_SETTING = 0x0F = 15dec
50 => VGA3 = 0x2E => VGA_SETTING = 0x0E = 14dec
100 => VGA3 = 0x2D => VGA_SETTING = 0x0D = 13dec
150 => VGA3 = 0x2F => VGA_SETTING = 0x0F = 15dec
200 => VGA3 = 0x32 => VGA_SETTING = 0x12 = 18dec
500 => VGA3 = 0x33 => VGA_SETTING = 0x13 = 19dec
868MHz range:
-------------------------------------------------
12.5 => VGA3 = 0x2F => VGA_SETTING = 0x0F = 15dec
25 => VGA3 = 0x2E => VGA_SETTING = 0x0E = 14dec
50 => VGA3 = 0x2D => VGA_SETTING = 0x0D = 13dec
100 => VGA3 = 0x2D => VGA_SETTING = 0x0D = 13dec
150 => VGA3 = 0x2E => VGA_SETTING = 0x0E = 14dec
200 => VGA3 = 0x30 => VGA_SETTING = 0x10 = 16dec
500 => VGA3 = 0x34 => VGA_SETTING = 0x14 = 20dec
*/
// Get current channel spacing
FILTER = ReadFromCC1020Register(CC1020_FILTER)&0x7F;
// Calculate average RSSI in dBm (initially without offset):
for(i = 0; i < 5; i++) {
RSSI[i] = ReadFromCC1020Register(CC1020_RSSI);
}
RSSI_dBm = (int)((((unsigned int)RSSI[0]+(unsigned int)RSSI[1]+(unsigned int)RSSI[2]+(unsigned int)RSSI[3]+(unsigned int)RSSI[4])*3)/(2*5));
RSSI_dBm = ((RSSI_dBm*3) - (3*(int)(ReadFromCC1020Register(CC1020_VGA3)&0x1F)*2)) / 2;
// Calculate average RSSI in dBm with offset, according to frequency band:
// Active frequency is in 800 MHz band
if( (ReadFromCC1020Register(CC1020_ANALOG)&0x80) == 0x80 ) {
switch ( FILTER ) {
case 0x58://12.5 kHz spacing
case 0x3F://12.5 kHz spacing, optimal sensitivity
RSSI_dBm = RSSI_dBm - 95;
break;
case 0x2F://25 kHz spacing
RSSI_dBm = RSSI_dBm - 96;
break;
case 0x2B://50 kHz spacing
RSSI_dBm = RSSI_dBm - 95;
break;
case 0x25://100 kHz spacing
RSSI_dBm = RSSI_dBm - 96;
break;
case 0x22://150 kHz spacing
RSSI_dBm = RSSI_dBm - 99;
break;
case 0x01://200 kHz spacing
RSSI_dBm = RSSI_dBm - 99;
break;
case 0x00://500 kHz spacing
RSSI_dBm = RSSI_dBm - 101;
break;
}
// Active frequency is in 434 MHz band
} else {
switch ( FILTER ) {
case 0x38://12.5 kHz spacing
case 0x2F://25 kHz spacing
RSSI_dBm = RSSI_dBm - 102;
break;
case 0x2B://50 kHz spacing
RSSI_dBm = RSSI_dBm - 100;
break;
case 0x25://100 kHz spacing
RSSI_dBm = RSSI_dBm - 99;
break;
case 0x22://150 kHz spacing
RSSI_dBm = RSSI_dBm - 101;
break;
case 0x01://200 kHz spacing
RSSI_dBm = RSSI_dBm - 102;
break;
case 0x00://500 kHz spacing
RSSI_dBm = RSSI_dBm - 103;
break;
}
}
return(RSSI_dBm);
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -