📄 cc1020config.c
字号:
/****************************************************************************/
/* Microcontroller (PIC) software library for CC1020 application */
/* */
/* File: cc1020pic.c */
/* */
/* Microcontroller: */
/* Microchip PIC16F876 */
/* */
/* Written for the IAR PIC16 compiler */
/* */
/* Author: Arne Rogndalen, Design Engineer, Chipcon */
/* Torgeir Sundet, FAE Software, Chipcon */
/* */
/* Contact: Chipcon AS +47 22 95 85 44 */
/* support@chipcon.com */
/* */
/****************************************************************************/
/****************************************************************************/
/* This library contains functions for configuring the CC1020. These */
/* routines use bit-banging to program the CC1020, faster configuration is */
/* possible by using a synchronous serial port such as a SPI interface. */
/* The header file "modemhw.h" contains definitions for the various I/O */
/* pins, the user should make a similar file to name the pins used to */
/* communicate with the CC1020. Routines to read and write the calibration */
/* values in the CC1020 are provided, they are not used in this reference */
/* application, but are useful in other applications, most notably */
/* frequency-agile and frequency hopping applications. See application */
/* note AN009 for more information. */
/* The routines in this file will have to be adapted depending on the MCU */
/* and compiler used. The method used for shifting data in and out may have */
/* to be changed if the bit ordering for bitfields is different from the */
/* IAR PIC compiler. */
/* */
/* Configuration routines are included in two versions: one using general */
/* I/O ports ("bit-banging"), and one using the built-in SPI interface of */
/* the PIC16F876. If possible, the SPI version should be used, as this is */
/* much faster. The SPI versions are used if the symbol "SPI" is defined, */
/* otherwise the general I/O-based version is used. */
/****************************************************************************/
/* *
* Revision history: *
*
* LY: modified for Atmega8L 2006-8-24 Begin
*
*
* *
* $Log: cc1020pic.c,v $
* Revision 1.7 2005/11/22 15:25:36 tos
* Removed osbolete code (AGC freeze).
*
* Revision 1.6 2005/11/22 14:31:40 tos
* Mods:
* - Finalised support for Errata Note 04.
* - Tydied-up implementation of RSSI measurement.
*
* Revision 1.5 2005/04/21 14:14:08 tos
* Modified calibration function according to Errata Note 04.
* Synchronised implementation of RSSI function with corresponding application note AN030.
*
* Revision 1.4 2004/03/23 16:44:23 tos
* Introduced RSSI measurement (based on algorithm in SmartRF Studio).
*
* Revision 1.3 2003/12/16 14:58:58 tos
* Removed 5 msec delay/wait before LOCK monitor.
*
* Revision 1.2 2003/09/17 15:58:02 tos
* Mod's:
* - tuned AFC_CONTROL for optimum preamble performance.
* - turn on TX before PA is increased.
*
* Revision 1.1 2003/07/31 13:17:16 tos
* Initial version in CVS.
*
*
* *
****************************************************************************/
#include "mega8.h"
#include "CC1020.h"
#include "MCU_interface.h"
/****************************************************************************/
/* This routine sends new configuration data to the CC1020 */
/****************************************************************************/
void ConfigureCC1020(char Count, short Configuration[])
{
short val;
char i;
for (i=0;i<Count;i++) {
val=Configuration[i];
WriteToCC1020RegisterWord(val);
}
}
/****************************************************************************/
/* General I/O pin "bit-bashing" versions of configuration routines. */
/****************************************************************************/
/****************************************************************************/
/* This routine writes to a single CC1020 register */
/****************************************************************************/
void WriteToCC1020Register(char addr, char data)
{
short val;
val=(((short)(addr&0x7F))<<9) | (((short) data)&0x00FF);
WriteToCC1020RegisterWord(val);
}
/****************************************************************************/
/* This routine writes to a single CC1020 register, with address and data */
/* given in the same variable */
/****************************************************************************/
void WriteToCC1020RegisterWord(short addranddata) //this 'PDI' is output
{
char BitCounter;
char data;
char addr;
unsigned short temp;
PSEL=1;
temp=addranddata;
data=(char)(temp&0x00ff); // Right!
addr=(char)((temp&0xff00)>>8); // Right?
PSEL=0; //PSEL avtive low!
// Low=LowByte;
// Send address bits
for (BitCounter=0;BitCounter<7;BitCounter++)
{
PCLK=0;
PDI=((addr&0x80)>>7);
addr=addr<<1;
PCLK=1;
}
// Send read/write bit
// Ignore bit in data, always use 1
PCLK=0;
PDI=1;
PCLK=1;
PCLK=0;
// High=HighByte;
// Send data bits
for (BitCounter=0;BitCounter<8;BitCounter++)
{
PCLK=0;
PDI=((data&0x80)>>7); //from here, we can know that the High is not changed!
data=data<<1; //
PCLK=1;
}
PCLK=0;
PSEL=1;
}
/****************************************************************************/
/* This routine reads from a single CC1020 register */
/****************************************************************************/
char ReadFromCC1020Register(char addr) // this 'PDO' is input
{
char BitCounter;
char Byte;
PSEL=1;
Byte=addr<<1; // 7 bits address.
PSEL=0;
// Send address bits
for (BitCounter=0;BitCounter<7;BitCounter++)
{
PCLK=0;
PDI=((Byte&0x80)>>7);
Byte=Byte<<1;
PCLK=1; //send out on the rising edge???
}
// Send read/write bit
// Ignore bit in data, always use 0
PCLK=0;
PDI=0;
PCLK=1;
PCLK=0;
// Receive data bits
PDI=1;
DDRC.3=0; //SET PDO as input //TRISC|=0x20; // Set up PDATA as an input //Posssible Error
for (BitCounter=0;BitCounter<8;BitCounter++)
{
PCLK=1;
Byte=Byte<<1;
Byte=Byte|((PINC&0x08)>>3);//? //Byte=Byte|readPDO;
PCLK=0; //Read on the falling edge???
}
DDRC.3=1; // SET PDO as output //TRISC&=~0x20; // Set up PDATA as an output //Possible Error
PSEL=1;
return Byte;
}
/****************************************************************************/
/* This routine resets the CC1020, clearing all registers. */
/****************************************************************************/
void ResetCC1020(void)
{
// Reset CC1020
WriteToCC1020Register(CC1020_MAIN, 0x0F&~0x01);
// Bring CC1020 out of reset
WriteToCC1020Register(CC1020_MAIN, 0x1F);
}
/****************************************************************************/
/* This routine calibrates the CC1020 */
/* Returns 0 if calibration fails, non-zero otherwise. Checks the LOCK */
/* to check for success. */
/****************************************************************************/
char CalibrateCC1020(char PA_POWER)
{
volatile int TimeOutCounter,i;
volatile int nCalAttempt;
// Turn off PA to avoid spurs during calibration in TX mode
WriteToCC1020Register(CC1020_PA_POWER,0x00);
// Calibrate, and re-calibrate if necessary:
for (nCalAttempt = CAL_ATTEMPT_MAX; (nCalAttempt>0); nCalAttempt--) {
// Start calibration
WriteToCC1020Register(CC1020_CALIBRATE,0xB4);
for (i=0x0010; i > 0; i--);
// 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--);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -