📄 cc1000pic.c
字号:
/****************************************************************************/
/* Application note AN009 */
/* CC1000 interface library */
/* */
/* File: cc1000.c */
/* Revision: 2.1 */
/* */
/* Microcontroller: */
/* Microchip PIC16F876 */
/* Written for the IAR PIC16 compiler */
/* */
/* Author: Karl H. Torvmark, Field Applications Engineer, Chipcon */
/* */
/* Contact: Chipcon AS +47 22 95 85 44 */
/* wireless@chipcon.com */
/* */
/* Changes: */
/* 2.1 : Added change of PLL register between RX and TX */
/* 2.0 : Changed file into library format, many other changes, added */
/* SPI code */
/* 1.0 : First version */
/****************************************************************************/
/****************************************************************************/
/* This library contains functions for configuring the CC1000. These */
/* routines use bit-banging to program the CC1000, 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 CC1000. Routines to read and write the calibration */
/* values in the CC1000 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: *
* *
* $Log: cc1000pic.c,v $
* Revision 2.5 2003/05/08 10:03:30 tos
* Corrected LOCK monitor in Calibrate.
*
* Revision 2.4 2003/05/08 09:43:12 tos
* Corrections according to Errata Note 01: reset freq.synth if unable to lock PLL.
*
* Revision 2.3 2003/04/25 14:03:22 tos
* Corrected inconsistent monitoring of CC1000: [calibration complete] + [lock].
*
*
* *
****************************************************************************/
#include "io16f876.h"
#include "CC1000.h"
#include "modemhw.h"
// Value of time-out timer during calibration
#define CAL_TIMEOUT 0x7FFE
#define LOCK_TIMEOUT 0x7FFE
// PA power setting
#define PA_VALUE 0xF0
/****************************************************************************/
/* This routine sends new configuration data to the CC1000 */
/****************************************************************************/
void ConfigureCC1000(char Count, short Configuration[])
{
short val;
char i;
for (i=0;i<Count;i++) {
val=Configuration[i];
WriteToCC1000RegisterWord(val);
}
}
/****************************************************************************/
/* SPI versions of configuration routines. The SPI interface must be */
/* initialised correctly before use */
/****************************************************************************/
#ifdef SPI
/****************************************************************************/
/* This routine writes to a single CC1000 register */
/****************************************************************************/
void WriteToCC1000Register(char addr, char data)
{
char dummy;
PALE=0;
dummy=SSPBUF;
SSPBUF=(addr<<1)|0x01; // Write address to CC1000, write bit is always 1
// Wait until data is written
while (BF==0)
;
PALE=1;
dummy=SSPBUF;
SSPBUF=data;
while (BF==0)
;
}
/****************************************************************************/
/* This routine writes to a single CC1000 register, with data and address */
/* given in the same variable */
/****************************************************************************/
void WriteToCC1000RegisterWord(short addranddata)
{
char dummy;
union {
unsigned short data;
struct {
char LowByte;
char HighByte;
};
};
data=addranddata;
PALE=0;
dummy=SSPBUF;
SSPBUF=LowByte|0x01; // Write address to CC1000, write bit is always 1
// Wait until data is written
while (BF==0);
PALE=1;
dummy=SSPBUF;
SSPBUF=HighByte;
while (BF==0)
;
}
/****************************************************************************/
/* This routine reads from a single CC1000 register */
/****************************************************************************/
char ReadFromCC1000Register(char addr)
{
char Value;
PALE=0;
Value=SSPBUF;
SSPBUF=(addr<<1)&0xFE; // Write address to CC1000, write bit is always 0
// Wait until data is written
while (BF==0);
SSPOV=0;
// Switch direction
PDATA_OUT=1;
TRISC|=0x20; // Set up PDATAOUT as an input
PALE=1;
SSPBUF=0xFF; // Dummy write
while (BF==0);
Value=SSPBUF;
TRISC&=~0x20; // Set PDATAOUT as an output
return Value;
}
#else
/****************************************************************************/
/* General I/O pin "bit-bashing" versions of configuration routines. */
/****************************************************************************/
/****************************************************************************/
/* This routine writes to a single CC1000 register */
/****************************************************************************/
void WriteToCC1000Register(char addr, char data)
{
short val;
val=(short) (addr&0x7F)<<9 | (short) data &0x00FF;
WriteToCC1000RegisterWord(val);
}
/****************************************************************************/
/* This routine writes to a single CC1000 register, with address and data */
/* given in the same variable */
/****************************************************************************/
void WriteToCC1000RegisterWord(short addranddata)
{
char BitCounter;
union { // This union is used to easily access the most significant
// bit of the configuration data
// Note : This assumes that the C compiler stores bit-fields
// with the first field going into the LSB. If this is not the
// case, move the MSB definition to the first bit
unsigned short Data;
struct
{
unsigned short :1;
unsigned short :1;
unsigned short :1;
unsigned short :1;
unsigned short :1;
unsigned short :1;
unsigned short :1;
unsigned short :1;
unsigned short :1;
unsigned short :1;
unsigned short :1;
unsigned short :1;
unsigned short :1;
unsigned short :1;
unsigned short :1;
unsigned short MSB :1;
};
};
PALE=1;
Data=addranddata;
PALE=0;
// Send address bits
for (BitCounter=0;BitCounter<7;BitCounter++)
{
PCLK=1;
PDATA_OUT=MSB;
Data=Data<<1;
PCLK=0;
}
// Send read/write bit
// Ignore bit in data, always use 1
PCLK=1;
PDATA_OUT=1;
PCLK=0;
Data=Data<<1;
PCLK=1;
PALE=1;
// Send data bits
for (BitCounter=0;BitCounter<8;BitCounter++)
{
PCLK=1;
PDATA_OUT=MSB;
Data=Data<<1;
PCLK=0;
}
PCLK=1;
}
/****************************************************************************/
/* This routine reads from a single CC1000 register */
/****************************************************************************/
char ReadFromCC1000Register(char addr)
{
char BitCounter;
union { // This unit is used to easily access the most significant
// bit of the configuration data
// Note : This assumes that the C compiler stores bit-fields
// with the first field going into the LSB. If this is not the
// case, switch the MSB and LSB definitions
unsigned char Data;
struct
{
unsigned char LSB :1;
unsigned char :1;
unsigned char :1;
unsigned char :1;
unsigned char :1;
unsigned char :1;
unsigned char :1;
unsigned char MSB :1;
};
};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -