📄 cc1100.c
字号:
/*
* 文件名:cc1100.c
* 功能 : cc1100 的功能实现函数
* author: 陈思
*/
#include "cc1100.h"
extern ChipState fCC1100;
RF_SETTINGS rfSettings = {
0x06, // FSCTRL1 Frequency synthesizer control.
0x00, // FSCTRL0 Frequency synthesizer control.
0x10, // FREQ2 Frequency control word, high byte.
0x12, // FREQ1 434MHz
0xF6, // FREQ0 434MHz
// 0x09, // FREQ1 433MHz
// 0x7B, // FREQ0 433MHz
0xF5, // MDMCFG4 Modem configuration.
0x75, // MDMCFG3 Modem configuration.
0x03, // MDMCFG2 Modem configuration.
0x20, // MDMCFG1 Modem configuration. oooooooooooooooooo
0xE5, // MDMCFG0 Modem configuration.
0x00, // CHANNR Channel number.
0x14, // DEVIATN Modem deviation setting (when FSK modulation is enabled).
0x56, // FREND1 Front end RX configuration.
0x00, // FREND0 Front end RX configuration.
0x18, // MCSM0 Main Radio Control State Machine configuration.
0x16, // FOCCFG Frequency Offset Compensation Configuration.
0x6C, // BSCFG Bit synchronization Configuration.
0x03, // AGCCTRL2 AGC control.
0x40, // AGCCTRL1 AGC control.
0x91, // AGCCTRL0 AGC control.
0xE9, // FSCAL3 Frequency synthesizer calibration.
0x0A, // FSCAL2 Frequency synthesizer calibration.
0x20, // FSCAL1 Frequency synthesizer calibration.
0x0D, // FSCAL0 Frequency synthesizer calibration.
0x59, // FSTEST Frequency synthesizer calibration.
0x81, // TEST2 Various test settings.
0x35, // TEST1 Various test settings.
0x09, // TEST0 Various test settings.
};
// 发射功率相关定义
BYTE paTable[] = {0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
void Wait(BYTE timeout)
{
// This sequence uses exactly 2 clock cycle for each round
do {
NOP();
} while (--timeout);
}
void resetCC1100(void)
{
PORT_SPI &= 1<<SCLK;
PORT_SPI &= ~(1<<MOSI);
SPI_OFF();
Wait(2);
SPI_ON();
Wait(2);
SPI_OFF();
Wait(20);
SPI_ON();
while ((PORT_SPI & 1<<MISO));
SPI_TX(CC1100_SRES);
SPI_WAIT();
while ((PORT_SPI & 1<<MISO));
SPI_OFF();
fCC1100 = IDLE;
}
// CC1100初始化和寄存器配置
void cc1100Init()
{
resetCC1100();
spiWriteRfSettings();
}
BYTE spiReadReg(BYTE addr)
{
UINT8 x;
SPI_ON();
while((PORT_SPI & 1<<MISO));
NOP();
SPI_TX(addr | READ_SINGLE);
SPI_RX(x);
SPI_OFF();
return x;
}
BYTE spiReadStatus(BYTE addr)
{
UINT8 x;
SPI_ON();
NOP();
while(PORT_SPI&1<<MISO);
NOP();
SPI_TX(addr | READ_BURST);
SPI_RX(x);
NOP();
SPI_OFF();
return x;
}
void spiReadBurstReg(BYTE addr, BYTE *buffer, BYTE count)
{
UINT8 i;
SPI_ON();
while(PORT_SPI&1<<MISO);
NOP();
SPI_TX(addr | READ_BURST);
for (i = 0; i < count; i++)
{
SPI_RX(buffer[i]);
}
NOP();
SPI_OFF();
//buffer[i] = 0; // add a terminal char
}
void spiStrobe(BYTE strobe)
{
SPI_ON();
NOP();
while(PORT_SPI&1<<MISO);
NOP();
SPI_TX(strobe);
NOP();
SPI_OFF();
}
void spiWriteReg(BYTE addr, BYTE value)
{
SPI_ON();
NOP();
while(PORT_SPI&1<<MISO);
NOP();
SPI_TX(addr);
SPI_TX(value);
NOP();
SPI_OFF();
}
void spiWriteBurstReg(BYTE addr, BYTE *buffer, BYTE count)
{
UINT8 i;
SPI_ON();
while((PORT_SPI&1<<MISO));
SPI_TX(addr | WRITE_BURST);
for (i = 0; i < count; i++)
{
SPI_TX(buffer[i]);
}
SPI_OFF();
}
void spiWriteRfSettings()
{
// Write register settings
spiWriteReg(CC1100_FSCTRL1, rfSettings.FSCTRL1);
spiWriteReg(CC1100_FSCTRL0, rfSettings.FSCTRL0);
spiWriteReg(CC1100_FREQ2, rfSettings.FREQ2);
spiWriteReg(CC1100_FREQ1, rfSettings.FREQ1);
spiWriteReg(CC1100_FREQ0, rfSettings.FREQ0);
spiWriteReg(CC1100_MDMCFG4, rfSettings.MDMCFG4);
spiWriteReg(CC1100_MDMCFG3, rfSettings.MDMCFG3);
spiWriteReg(CC1100_MDMCFG2, rfSettings.MDMCFG2);
spiWriteReg(CC1100_MDMCFG1, rfSettings.MDMCFG1);
spiWriteReg(CC1100_MDMCFG0, rfSettings.MDMCFG0);
spiWriteReg(CC1100_CHANNR, rfSettings.CHANNR);
spiWriteReg(CC1100_DEVIATN, rfSettings.DEVIATN);
spiWriteReg(CC1100_FREND1, rfSettings.FREND1);
spiWriteReg(CC1100_FREND0, rfSettings.FREND0);
spiWriteReg(CC1100_MCSM0 , rfSettings.MCSM0 );
spiWriteReg(CC1100_FOCCFG, rfSettings.FOCCFG);
spiWriteReg(CC1100_BSCFG, rfSettings.BSCFG);
spiWriteReg(CC1100_AGCCTRL2, rfSettings.AGCCTRL2);
spiWriteReg(CC1100_AGCCTRL1, rfSettings.AGCCTRL1);
spiWriteReg(CC1100_AGCCTRL0, rfSettings.AGCCTRL0);
spiWriteReg(CC1100_FSCAL3, rfSettings.FSCAL3);
spiWriteReg(CC1100_FSCAL2, rfSettings.FSCAL2);
spiWriteReg(CC1100_FSCAL1, rfSettings.FSCAL1);
spiWriteReg(CC1100_FSCAL0, rfSettings.FSCAL0);
spiWriteReg(CC1100_FSTEST, rfSettings.FSTEST);
spiWriteReg(CC1100_TEST2, rfSettings.TEST2);
spiWriteReg(CC1100_TEST1, rfSettings.TEST1);
spiWriteReg(CC1100_TEST0, rfSettings.TEST0);
// Set Syn Byte
spiWriteReg(CC1100_SYNC1, 0x12);
spiWriteReg(CC1100_SYNC0, 0x34);
spiWriteBurstReg(CC1100_PATABLE, paTable, sizeof(paTable));
}
void spiSendPacket(BYTE *txBuffer, UINT8 size)
{
BYTE status;
// 写发送缓冲区
spiWriteBurstReg(CC1100_TXFIFO, txBuffer, size);
spiStrobe(CC1100_STX);
fCC1100 = SEND;
// 循环直到数据发送完成
while(1)
{
status = spiReadStatus(0x35);
if(status == 1)
break;
}
/*
while(!GDO0_PIN);
while(GDO0_PIN);
*/
fCC1100 = IDLE;
}
BOOL spiReceivePacket(BYTE *rxBuffer,UINT8 length)
{
UINT8 packetLength;
BYTE rxStatus[2];
BYTE status = 0;
memset(rxBuffer,0,10);
spiStrobe(CC1100_SRX);
fCC1100 = RECIEVE;
while(1)
{
status = spiReadStatus(0x35);
if(status == 1)
{
break;
}
}
fCC1100 = IDLE;
if ((spiReadStatus(CC1100_RXBYTES) & BYTES_IN_RXFIFO))
{
// Read the first byte, also is the length byte
packetLength = spiReadReg(CC1100_RXFIFO);
// Read data from RX FIFO and store in rxBuffer
if (packetLength <= length)
{
spiReadBurstReg(CC1100_RXFIFO, rxBuffer, packetLength);
length = packetLength;
spiReadBurstReg(CC1100_RXFIFO, rxStatus, 2);
return TRUE;
}
else
{
length = packetLength;
spiStrobe(CC1100_SFRX);
return FALSE;
}
}
return FALSE;
}
void recPacket(BYTE *rxBuffer,UINT8 length)
{
UINT8 packetLength;
BYTE rxStatus[2];
if ((spiReadStatus(CC1100_RXBYTES) & BYTES_IN_RXFIFO))
{
packetLength = spiReadReg(CC1100_RXFIFO);
// Read data from RX FIFO and store in rxBuffer
if (packetLength <= length)
{
spiReadBurstReg(CC1100_RXFIFO, rxBuffer, packetLength);
length = packetLength;
spiReadBurstReg(CC1100_RXFIFO, rxStatus, 2);
}
else
{
length = packetLength;
}
}
spiStrobe(CC1100_SFRX);
fCC1100 = IDLE;
}
void initWorMode(void)
{
// Enable automatic initial calibration of RCosc.
// Set T_event1 ~ 1.4 ms, enough for XOSC stabilize and FS calibration before RX.
// Enable RC oscillator before starting with WOR (or else it will not wake up).
spiWriteReg(CC1100_WORCTRL, 0x78); // Not using AUTO_SYNC function.
// Set Event0 timeout = 1 s (RX polling interval)
// WOR_RES = 0
// T_event0 = 750 / f_xosc * EVENT0 * 2^(5*WOR_RES) = 1 s,f_xosc = 27 MHz
// => EVENT0 = 0x8CA0
spiWriteReg(CC1100_WOREVT1, 0x8C); // High byte Event0 timeout
spiWriteReg(CC1100_WOREVT0, 0xA0); // Low byte Event0 timeout.
// Setting Rx_timeout =2.596 ms.
// MCSM2.RX_TIME = 000b
// => Rx_timeout = EVENT0*C(RX_TIME, WOR_RES)
spiWriteReg(CC1100_MCSM2, 0x00);
// Enable automatic FS calibration when going from IDLE to RX/TX/FSTXON (in between EVENT0 and EVENT1)
spiWriteReg(CC1100_MCSM0, 0x18);
spiStrobe(CC1100_SWORRST);
spiStrobe(CC1100_SWOR);
fCC1100 = SLEEP;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -