说明:

作者:霍宏鹏

程序编写平台: keil5 MDK

MCU 平台 : GD32


我的这个驱动是针对cc1101编写的,程序里面有控制EN1、EN2,这两个是电路中做了天线发射的功率放大电路,通过EN1和EN2来选择是接收还是发送,如果没有收发电路,一般应用里面是不需要的。程序的特点,发送和接收都是基于缓冲区的,也就是说发送过程中基本不会阻塞,也就是不会占用CPU资源,接收过程中应为有缓冲区,不用担心丢包问题,也不用考虑cc1101里面的FIFO大小。有问题希望批评指正。

剪>>>>>>>>>>>>>>>>>>>>>>>>>>>>====================================================================================================


#ifndef __DEVICE_CC1101_H__
#define __DEVICE_CC1101_H__


/* common register */
#define RF_IOCFG2 0x00 // IOCFG2 - GDO2 output pin configuration
#define RF_IOCFG1 0x01 // IOCFG1 - GDO1 output pin configuration
#define RF_IOCFG0 0x02 // IOCFG1 - GDO0 output pin configuration
#define RF_FIFOTHR 0x03 // FIFOTHR - RX FIFO and TX FIFO thresholds
#define RF_SYNC1 0x04 // SYNC1 - Sync word, high byte
#define RF_SYNC0 0x05 // SYNC0 - Sync word, low byte
#define RF_PKTLEN 0x06 // PKTLEN - Packet length
#define RF_PKTCTRL1 0x07 // PKTCTRL1 - Packet automation control
#define RF_PKTCTRL0 0x08 // PKTCTRL0 - Packet automation control
#define RF_ADDR 0x09 // ADDR - Device address
#define RF_CHANNR 0x0A // CHANNR - Channel number
#define RF_FSCTRL1 0x0B // FSCTRL1 - Frequency synthesizer control
#define RF_FSCTRL0 0x0C // FSCTRL0 - Frequency synthesizer control
#define RF_FREQ2 0x0D // FREQ2 - Frequency control word, high byte
#define RF_FREQ1 0x0E // FREQ1 - Frequency control word, middle byte
#define RF_FREQ0 0x0F // FREQ0 - Frequency control word, low byte
#define RF_MDMCFG4 0x10 // MDMCFG4 - Modem configuration
#define RF_MDMCFG3 0x11 // MDMCFG3 - Modem configuration
#define RF_MDMCFG2 0x12 // MDMCFG2 - Modem configuration
#define RF_MDMCFG1 0x13 // MDMCFG1 - Modem configuration
#define RF_MDMCFG0 0x14 // MDMCFG0 - Modem configuration
#define RF_DEVIATN 0x15 // DEVIATN - Modem deviation setting
#define RF_MCSM2 0x16 // MCSM2 - Main Radio Control State Machine configuration
#define RF_MCSM1 0x17 // MCSM1 - Main Radio Control State Machine configuration
#define RF_MCSM0 0x18 // MCSM0 - Main Radio Control State Machine configuration
#define RF_FOCCFG 0x19 // FOCCFG - Frequency Offset Compensation configuration
#define RF_BSCFG 0x1A // BSCFG - Bit Synchronization configuration
#define RF_AGCCTRL2 0x1B // AGCCTRL2 - AGC control
#define RF_AGCCTRL1 0x1C // AGCCTRL1 - AGC control
#define RF_AGCCTRL0 0x1D // AGCCTRL0 - AGC control
#define RF_WOREVT1 0x1E // WOREVT1 - High byte Event0 timeout
#define RF_WOREVT0 0x1F // WOREVT0 - Low byte Event0 timeout
#define RF_WORCTRL 0x20 // WORCTRL - Wake On Radio control
#define RF_FREND1 0x21 // FREND1 - Front end RX configuration
#define RF_FREND0 0x22 // FREDN0 - Front end TX configuration
#define RF_FSCAL3 0x23 // FSCAL3 - Frequency synthesizer calibration
#define RF_FSCAL2 0x24 // FSCAL2 - Frequency synthesizer calibration
#define RF_FSCAL1 0x25 // FSCAL1 - Frequency synthesizer calibration
#define RF_FSCAL0 0x26 // FSCAL0 - Frequency synthesizer calibration
#define RF_RCCTRL1 0x27 // RCCTRL1 - RC oscillator configuration
#define RF_RCCTRL0 0x28 // RCCTRL0 - RC oscillator configuration
#define RF_FSTEST 0x29 // FSTEST - Frequency synthesizer calibration control
#define RF_PTEST 0x2A // PTEST - Production test
#define RF_AGCTEST 0x2B // AGCTEST - AGC test
#define RF_TEST2 0x2C // TEST2 - Various test settings
#define RF_TEST1 0x2D // TEST1 - Various test settings
#define RF_TEST0 0x2E // TEST0 - Various test settings


#define IOCFG2 0x00 // IOCFG2 - GDO2 output pin configuration
#define IOCFG1 0x01 // IOCFG1 - GDO1 output pin configuration
#define IOCFG0 0x02 // IOCFG1 - GDO0 output pin configuration
#define FIFOTHR 0x03 // FIFOTHR - RX FIFO and TX FIFO thresholds
#define SYNC1 0x04 // SYNC1 - Sync word, high byte
#define SYNC0 0x05 // SYNC0 - Sync word, low byte
#define PKTLEN 0x06 // PKTLEN - Packet length
#define PKTCTRL1 0x07 // PKTCTRL1 - Packet automation control
#define PKTCTRL0 0x08 // PKTCTRL0 - Packet automation control
#define ADDR 0x09 // ADDR - Device address
#define CHANNR 0x0A // CHANNR - Channel number
#define FSCTRL1 0x0B // FSCTRL1 - Frequency synthesizer control
#define FSCTRL0 0x0C // FSCTRL0 - Frequency synthesizer control
#define FREQ2 0x0D // FREQ2 - Frequency control word, high byte
#define FREQ1 0x0E // FREQ1 - Frequency control word, middle byte
#define FREQ0 0x0F // FREQ0 - Frequency control word, low byte
#define MDMCFG4 0x10 // MDMCFG4 - Modem configuration
#define MDMCFG3 0x11 // MDMCFG3 - Modem configuration
#define MDMCFG2 0x12 // MDMCFG2 - Modem configuration
#define MDMCFG1 0x13 // MDMCFG1 - Modem configuration
#define MDMCFG0 0x14 // MDMCFG0 - Modem configuration
#define DEVIATN 0x15 // DEVIATN - Modem deviation setting
#define MCSM2 0x16 // MCSM2 - Main Radio Control State Machine configuration
#define MCSM1 0x17 // MCSM1 - Main Radio Control State Machine configuration
#define MCSM0 0x18 // MCSM0 - Main Radio Control State Machine configuration
#define FOCCFG 0x19 // FOCCFG - Frequency Offset Compensation configuration
#define BSCFG 0x1A // BSCFG - Bit Synchronization configuration
#define AGCCTRL2 0x1B // AGCCTRL2 - AGC control
#define AGCCTRL1 0x1C // AGCCTRL1 - AGC control
#define AGCCTRL0 0x1D // AGCCTRL0 - AGC control
#define WOREVT1 0x1E // WOREVT1 - High byte Event0 timeout
#define WOREVT0 0x1F // WOREVT0 - Low byte Event0 timeout
#define WORCTRL 0x20 // WORCTRL - Wake On Radio control
#define FREND1 0x21 // FREND1 - Front end RX configuration
#define FREND0 0x22 // FREDN0 - Front end TX configuration
#define FSCAL3 0x23 // FSCAL3 - Frequency synthesizer calibration
#define FSCAL2 0x24 // FSCAL2 - Frequency synthesizer calibration
#define FSCAL1 0x25 // FSCAL1 - Frequency synthesizer calibration
#define FSCAL0 0x26 // FSCAL0 - Frequency synthesizer calibration
#define RCCTRL1 0x27 // RCCTRL1 - RC oscillator configuration
#define RCCTRL0 0x28 // RCCTRL0 - RC oscillator configuration
#define FSTEST 0x29 // FSTEST - Frequency synthesizer calibration control
#define PTEST 0x2A // PTEST - Production test
#define AGCTEST 0x2B // AGCTEST - AGC test
#define TEST2 0x2C // TEST2 - Various test settings
#define TEST1 0x2D // TEST1 - Various test settings
#define TEST0 0x2E // TEST0 - Various test settings


/* status registers CC1101 */
#define RF_PARTNUM 0x30 // PARTNUM - Chip ID
#define RF_VERSION 0x31 // VERSION - Chip ID
#define RF_FREQEST 0x32 // FREQEST - Frequency Offset Estimate from demodulator
#define RF_LQI 0x33 // LQI - Demodulator estimate for Link Quality
#define RF_RSSI 0x34 // RSSI - Received signal strength indication
#define RF_MARCSTATE 0x35 // MARCSTATE - Main Radio Control State Machine state
#define RF_WORTIME1 0x36 // WORTIME1 - High byte of WOR time
#define RF_WORTIME0 0x37 // WORTIME0 - Low byte of WOR time
#define RF_PKTSTATUS 0x38 // PKTSTATUS - Current GDOx status and packet status
#define RF_VCO_VC_DAC 0x39 // VCO_VC_DAC - Current setting from PLL calibration module
#define RF_TXBYTES 0x3A // TXBYTES - Underflow and number of bytes
#define RF_RXBYTES 0x3B // RXBYTES - Overflow and number of bytes

/* burst write registers */
#define RF_PA_TABLE0 0x3E // PA_TABLE0 - PA control settings table
#define RF_RXFIFO 0x3F // FIFO - Transmit FIFO
#define RF_TXFIFO 0x3F // FIFO - Receive FIFO

/* Other register bit fields */
#define RF_LQI_CRC_OK_BM 0x80
#define RF_LQI_EST_BM 0x7F

/* CC1101 Command strobe registers */
#define RF_SRES 0x30 // SRES - Reset chip.
#define RF_SFSTXON 0x31 // SFSTXON - Enable and calibrate frequency synthesizer.
#define RF_SXOFF 0x32 // SXOFF - Turn off crystal oscillator.
#define RF_SCAL 0x33 // SCAL - Calibrate frequency synthesizer and turn it off.
#define RF_SRX 0x34 // SRX - Enable RX. Perform calibration if enabled.
#define RF_STX 0x35 // STX - Enable TX. If in RX state, only enable TX if CCA passes.
#define RF_SIDLE 0x36 // SIDLE - Exit RX / TX, turn off frequency synthesizer.
#define RF_SPWD 0x39 // SPWD - Enter power down mode when CSn goes high.
#define RF_SFRX 0x3A // SFRX - Flush the RX FIFO buffer.
#define RF_SFTX 0x3B // SFTX - Flush the TX FIFO buffer.
#define RF_SNOP 0x3D // SNOP - No operation. Returns status byte.

/* CC1101 Chip states returned in status byte */
#define RF_STATE_IDLE 0x00
#define RF_STATE_RX 0x10
#define RF_STATE_TX 0x20
#define RF_STATE_FSTXON 0x30
#define RF_STATE_CALIBRATE 0x40
#define RF_STATE_SETTLING 0x50
#define RF_STATE_RXFIFO_ERROR 0x60
#define RF_STATE_TXFIFO_ERROR 0x70

#define RF_BURST_ACCESS 0x40
#define RF_SINGLE_ACCESS 0x00
#define RF_READ_ACCESS 0x80
#define RF_WRITE_ACCESS 0x00


void cc1101_config_init(void);
void cc1101_send_write(void*_buf, unsigned short count);
int cc1101_receive_read(unsigned char *buf, int count);
void cc1101_gdo0_it(void);
#endif




/*******************************************************************************
file : device_cc1101.c.c
author : huohongpeng
date : 2017-02-15
description : cc1101 driver lib
*******************************************************************************/

#include "device_cc1101.h"
#include "platform_spi.h"
#include "platform_delay.h"
#include "platform_usart.h"

#define __CC1101_DEBUG__ (1)

#if __CC1101_DEBUG__

#define cc1101_printf printf

#define cc1101_hex_printf(buf, count) \
{\
int i;\
for(i = 0; i < count; i++)\
{\
printf("%02X ", buf[i]);\
}\
}

#else

#define cc1101_printf(...)
#define cc1101_hex_printf(...)
#endif


#define TX_BUF_SIZE 128
#define RX_BUF_SIZE 256

#define MODE_RX 0x00
#define MODE_TX 0x01

/* rf receive or transmit max packet size at one time */
#define MAX_FIFO_SIZE 0x38

#define halRfWriteReg cc1101_write_signle_reg

static unsigned char cc1101_write_signle_reg(unsigned char addr, unsigned char data);


/*
status[16] : 0 - rx
1 - tx

*/
struct rf_dev
{
unsigned char tx_buf[TX_BUF_SIZE];
unsigned short tx_rd;
unsigned short tx_wr;
unsigned char rx_buf[RX_BUF_SIZE];
unsigned short rx_rd;
unsigned short rx_wr;
unsigned short mode;
};

static struct rf_dev rf_dev;


void cc1101_reg_config_433(void)
{
halRfWriteReg(IOCFG0,0x06); //GDO0 Output Pin Configuration
halRfWriteReg(PKTCTRL0,0x05);//Packet Automation Control
halRfWriteReg(FSCTRL1,0x0C); //Frequency Synthesizer Control
halRfWriteReg(FREQ2,0x21); //Frequency Control Word, High Byte
halRfWriteReg(FREQ1,0x62); //Frequency Control Word, Middle Byte
halRfWriteReg(FREQ0,0x76); //Frequency Control Word, Low Byte
halRfWriteReg(MDMCFG4,0x2D); //Modem Configuration
halRfWriteReg(MDMCFG3,0x3B); //Modem Configuration
halRfWriteReg(MDMCFG2,0x13); //Modem Configuration
halRfWriteReg(DEVIATN,0x62); //Modem Deviation Setting
halRfWriteReg(MCSM0,0x18); //Main Radio Control State Machine Configuration
halRfWriteReg(FOCCFG,0x1D); //Frequency Offset Compensation Configuration
halRfWriteReg(BSCFG,0x1C); //Bit Synchronization Configuration
halRfWriteReg(AGCCTRL2,0xC7);//AGC Control
halRfWriteReg(AGCCTRL1,0x00);//AGC Control
halRfWriteReg(AGCCTRL0,0xB0);//AGC Control
halRfWriteReg(WORCTRL,0xFB); //Wake On Radio Control
halRfWriteReg(FREND1,0xB6); //Front End RX Configuration
halRfWriteReg(FSCAL3,0xEA); //Frequency Synthesizer Calibration
halRfWriteReg(FSCAL2,0x2A); //Frequency Synthesizer Calibration
halRfWriteReg(FSCAL1,0x00); //Frequency Synthesizer Calibration
halRfWriteReg(FSCAL0,0x1F); //Frequency Synthesizer Calibration
halRfWriteReg(TEST0,0x09); //Various Test Settings

halRfWriteReg(RF_PA_TABLE0,0xc0);
}

/**
description : rf device hardware interface init and config
param : None
retval : None
author : huohongpeng
date : 2017-02-15

-----------------------
| rf | mcu |
-----------------------
| GDO0 | GPIOA.1 |
-----------------------
| SI | GPIOA.7 |
-----------------------
| SO | GPIOA.6 |
-----------------------
| SCK | GPIOA.5 |
-----------------------
| CS | GPIOA.4 |
-----------------------
| EN1 | GPIOA.3 |
-----------------------
| EN2 | GPIOA.2 |
-----------------------

*/

static void cc1101_hw_interface_init(void)
{
GPIO_InitPara GPIO_InitParaStruct;

RCC_AHBPeriphClock_Enable(RCC_AHBPERIPH_GPIOA, ENABLE);

GPIO_InitParaStruct.GPIO_Mode = GPIO_MODE_OUT;
GPIO_InitParaStruct.GPIO_OType = GPIO_OTYPE_PP;
GPIO_InitParaStruct.GPIO_PuPd = GPIO_PUPD_PULLUP;
GPIO_InitParaStruct.GPIO_Speed = GPIO_SPEED_50MHZ;
GPIO_InitParaStruct.GPIO_Pin = GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4;
GPIO_Init(GPIOA, &GPIO_InitParaStruct);

spi_init(1);
}

/**
description : enable receive hardware circuit
param : None
retval : None
author : huohongpeng
date : 2017-02-15

mode EN1 EN2
reveive 0 1
transmit 1 0

*/
static void cc1101_en1_en2_rx(void)
{
GPIO_ResetBits(GPIOA, GPIO_PIN_3);
GPIO_SetBits(GPIOA, GPIO_PIN_2);
}

/**
description : enable transmit hardware circuit
param : None
retval : None
author : huohongpeng
date : 2017-02-15

mode EN1 EN2
reveive 0 1
transmit 1 0
*/
static void cc1101_en1_en2_tx(void)
{
GPIO_SetBits(GPIOA, GPIO_PIN_3);
GPIO_ResetBits(GPIOA, GPIO_PIN_2);
}

/**
description : enable and config gdo0 interrupt
param : None
retval : None
author : huohongpeng
date : 2017-02-15

*/
static void cc1101_gdo0_int_enable(void)
{
GPIO_InitPara GPIO_InitParaStruct;
EXTI_InitPara EXTI_InitParaStruct;

RCC_AHBPeriphClock_Enable(RCC_AHBPERIPH_GPIOA, ENABLE);
RCC_APB2PeriphClock_Enable(RCC_APB2PERIPH_CFG, ENABLE);
SYSCFG_EXTILine_Config(EXTI_SOURCE_GPIOA, EXTI_SOURCE_PIN1);

GPIO_InitParaStruct.GPIO_Mode = GPIO_MODE_IN;
GPIO_InitParaStruct.GPIO_PuPd = GPIO_PUPD_PULLUP;
GPIO_InitParaStruct.GPIO_Speed = GPIO_SPEED_50MHZ;
GPIO_InitParaStruct.GPIO_Pin = GPIO_PIN_1;
GPIO_Init(GPIOA, &GPIO_InitParaStruct);

EXTI_InitParaStruct.EXTI_LINE = EXTI_LINE1;
EXTI_InitParaStruct.EXTI_LINEEnable = ENABLE;
EXTI_InitParaStruct.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitParaStruct.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_Init(&EXTI_InitParaStruct);
}
/**
description : cc1101 spi communication interface
param : data - send data
retval : receive data
author : huohongpeng
date : 2017-02-15
*/
static unsigned short cc1101_spi_interface(unsigned short data)
{
return spi_write_read(1, data);
}

/**
description : cc1101 spi delay us
param : us - us count
retval : None
author : huohongpeng
date : 2017-02-15
*/
static void cc1101_delay_us(unsigned int us)
{
delay_us(us);
}

/**
description : read so pin status
param : None
retval : pin state
author : huohongpeng
date : 2017-02-15
*/
static unsigned char cc1101_read_so(void)
{
if(GPIO_ReadInputBit(GPIOA, GPIO_PIN_6) == Bit_SET)
{
return 0x01;
}
else
{
return 0x00;
}
}

/**
description : set cs pin to 1
param : None
retval : None
author : huohongpeng
date : 2017-02-15
*/
static void cc1101_cs_h(void)
{
GPIO_SetBits(GPIOA, GPIO_PIN_4);
}

/**
description : set cs pin to 0
param : None
retval : None
author : huohongpeng
date : 2017-02-15
*/
static void cc1101_cs_l(void)
{
GPIO_ResetBits(GPIOA, GPIO_PIN_4);
}

/**
description : read register on signle mode
param : addr - register address
retval : register value
author : huohongpeng
date : 2017-02-15
*/
static unsigned char cc1101_read_signle_reg(unsigned char addr)
{
unsigned char ret;

addr &= 0x3f;
addr |= (RF_READ_ACCESS | RF_SINGLE_ACCESS);

cc1101_cs_l();

while(cc1101_read_so());

cc1101_spi_interface(addr);
ret = cc1101_spi_interface(0);

cc1101_cs_h();

return ret;
}

/**
description : write register on signle mode
param : addr - register address
data - register value
retval : 0 - success
author : huohongpeng
date : 2017-02-15
*/
static unsigned char cc1101_write_signle_reg(unsigned char addr, unsigned char data)
{
unsigned char ret;

addr &= 0x3f;
addr |= (RF_WRITE_ACCESS | RF_SINGLE_ACCESS);

cc1101_cs_l();

while(cc1101_read_so());

cc1101_spi_interface(addr);
ret = cc1101_spi_interface(data);

cc1101_cs_h();

return ret;
}

/**
description : read register on burst mode
param : addr - register address
buf - register buffer pointer
count - read count
retval : 0 - success
author : huohongpeng
date : 2017-02-15
*/
static unsigned char cc1101_read_burst_reg(unsigned char addr, unsigned char *buf, unsigned char count)
{
unsigned char ret, i;

addr &= 0x3f;
addr |= (RF_READ_ACCESS | RF_BURST_ACCESS);

cc1101_cs_l();

while(cc1101_read_so());

ret = cc1101_spi_interface(addr);

for(i = 0; i < count; i++)
{
buf[i] = cc1101_spi_interface(0);
}

cc1101_cs_h();

return ret;
}

/**
description : write register on burst mode
param : addr - register address
buf - register buffer pointer
count - writer count
retval : 0 - success
author : huohongpeng
date : 2017-02-15
*/
static unsigned char cc1101_write_burst_reg(unsigned char addr, const unsigned char *buf, unsigned char count)
{
unsigned char ret, i;

addr &= 0x3f;
addr |= (RF_WRITE_ACCESS | RF_BURST_ACCESS);

cc1101_cs_l();

while(cc1101_read_so());

ret = cc1101_spi_interface(addr);

for(i = 0; i < count; i++)
{
ret = cc1101_spi_interface(buf[i]);
}

cc1101_cs_h();

return ret;
}

/**
description : read device status
param : addr - register address (0x30 - 0x3b)
retval : 0 - success
author : huohongpeng
date : 2017-02-15
*/
static unsigned char cc1101_read_status(unsigned char addr)
{
unsigned char ret;

addr &= 0x3f;
addr |= (RF_BURST_ACCESS | RF_READ_ACCESS);

cc1101_cs_l();

while(cc1101_read_so());

cc1101_spi_interface(addr);
ret = cc1101_spi_interface(0);

cc1101_cs_h();

return ret;
}

/**
description : send Command Strobes
param : addr - register address (0x30 - 0x3d)
retval : 0 - success
author : huohongpeng
date : 2017-02-15
*/
static unsigned char cc1101_write_strobe(unsigned char addr)
{
unsigned char ret;

addr &= 0x3f;

cc1101_cs_l();

while(cc1101_read_so());

ret = cc1101_spi_interface(addr);

cc1101_cs_h();

return ret;
}

/**
description : power on reset device
param : None
retval : None
author : huohongpeng
date : 2017-02-16
*/
static void cc1101_poweron_reset(void)
{
cc1101_cs_l();
cc1101_delay_us(10);
cc1101_cs_h();
cc1101_delay_us(40);
cc1101_cs_l();
while(cc1101_read_so());
cc1101_spi_interface(RF_SRES);
while(cc1101_read_so());
cc1101_cs_l();
}

/**
description : set device to receive mode
param : None
retval : None
author : huohongpeng
date : 2017-02-16
*/
static void cc1101_set_rx_mode(void)
{
cc1101_en1_en2_rx();
cc1101_write_strobe(RF_SFRX);
cc1101_write_strobe(RF_SIDLE);
cc1101_write_strobe(RF_SRX);

rf_dev.mode = MODE_RX;
}

/**
description : set device to transmit mode
param : None
retval : None
author : huohongpeng
date : 2017-02-16
*/
static void cc1101_set_tx_mode(void)
{
cc1101_en1_en2_tx();
cc1101_write_strobe(RF_SIDLE);
cc1101_write_strobe(RF_STX);

rf_dev.mode = MODE_TX;
}

/**
description : c1101 receive packet from fifo.
param :
in :
count - receive count pointer
out :
buf - receive buffer pointer
count - actual receive count
retval : 0 - success
-1 - fifo data count is 0
-2 - receive data crc is error
-3 - receive count(fifo frist byte) is error
author : huohongpeng
date : 2017-02-16
*/
static int cc1101_receive_packet(unsigned char *buf, unsigned char *count)
{
unsigned char packet_len, status[2];

if((cc1101_read_status(RF_RXBYTES) & 0x7f) == 0)
{
return -1;
}

packet_len = cc1101_read_signle_reg(RF_RXFIFO);

if(packet_len <= *count)
{
cc1101_read_burst_reg(RF_RXFIFO, buf, packet_len);
cc1101_read_burst_reg(RF_RXFIFO, status, 2);
*count = packet_len;
return ((status[1] & 0x80) ? 0 : -2);
}
else
{
cc1101_set_rx_mode();

return -3;
}

}

/**
description : c1101 transmit packet to fifo.
param :
buf - receive buffer pointer
count - receive count
retval : 0 - success
-1 - fifo data count is 0
-2 - receive data crc is error
-3 - receive count(fifo frist byte) is error
author : huohongpeng
date : 2017-02-16
*/
static int cc1101_send_packet(unsigned char *buf, unsigned char count)
{

cc1101_printf("cc1101 send data:");
cc1101_hex_printf(buf, count);
cc1101_printf("\r\n");
cc1101_write_signle_reg(RF_TXFIFO, count);
cc1101_write_burst_reg(RF_RXFIFO, buf, count);

return 0;
}

/**
description : in receive mode , gdo0 pin interrupt handle
param : None
retval : None
author : huohongpeng
date : 2017-02-16
*/
static void cc1101_gdo0_rx_it(void)
{
unsigned char rx_buf[MAX_FIFO_SIZE], rx_count;
int ret, i;

rx_count = MAX_FIFO_SIZE;

ret = cc1101_receive_packet(rx_buf, &rx_count);

cc1101_set_rx_mode();

if(ret == 0)
{
for(i = 0; i < rx_count; i++)
{
rf_dev.rx_buf[rf_dev.rx_wr++] = rx_buf[i];
rf_dev.rx_wr %= RX_BUF_SIZE;

/*
overflow handle
*/
if(rf_dev.rx_wr == rf_dev.rx_rd)
{
rf_dev.rx_rd++;
rf_dev.rx_rd %= RX_BUF_SIZE;
}
}

cc1101_printf("cc1101 receive data:");
cc1101_hex_printf(rx_buf, rx_count);
cc1101_printf("\r\n");
}
}

/**
description : get transmit buffer count of wait transmit.
param : None
retval : wait transmit count
author : huohongpeng
date : 2017-02-17
*/
static unsigned short cc1101_get_tx_buf_count(void)
{
unsigned short count;

if(rf_dev.tx_rd < rf_dev.tx_wr)
{
count = rf_dev.tx_wr - rf_dev.tx_rd;
}
else if(rf_dev.tx_rd == rf_dev.tx_wr)
{
count = 0;
}
else
{
count = TX_BUF_SIZE - rf_dev.tx_rd + rf_dev.tx_wr;
}

return count;
}

/**
description : read "count" byte from rf_dev.tx_buf
param : _buf - data buffer pointer
count - data count
retval : read real count
author : huohongpeng
date : 2017-02-17
*/
static int cc1101_read_tx_buf(void *_buf, int count)
{
unsigned char *buf = (unsigned char *)_buf;
int i, real_count;

for(i = 0, real_count = 0; i < count; i++)
{
if(rf_dev.tx_rd == rf_dev.tx_wr)
{
return real_count;
}
else
{
buf[i] = rf_dev.tx_buf[rf_dev.tx_rd++];
rf_dev.tx_rd %= TX_BUF_SIZE;
real_count++;
}
}

return real_count;
}

/**
description : write "count" byte to rf_dev.tx_buf
param : _buf - data buffer pointer
count - data count
retval : None
author : huohongpeng
date : 2017-02-17
*/
static void cc1101_write_tx_buf(void *_buf, int count)
{
unsigned char *buf = (unsigned char *)_buf;
int i;

for(i = 0; i < count; i++)
{
while(((rf_dev.tx_wr+1) % TX_BUF_SIZE) == rf_dev.tx_rd);
rf_dev.tx_buf[rf_dev.tx_wr++] = buf[i];
rf_dev.tx_wr %= TX_BUF_SIZE;
}
}

/**
description : in transmit mode , gdo0 pin interrupt handle
param : None
retval : None
author : huohongpeng
date : 2017-02-17
*/
static void cc1101_gdo0_tx_it(void)
{
short wait_tx_count;
unsigned char buf_tmp[TX_BUF_SIZE], status;

wait_tx_count = cc1101_get_tx_buf_count();

status = cc1101_write_strobe(RF_SFTX);

/*
wait device to IDLE status, very important !!!!
ohterwise, transmit loss packet.
if device into IDLE, prove transmit end.
*/
while(status & 0x70)
{
status = cc1101_write_strobe(RF_SNOP);
}

if(wait_tx_count == 0)
{
cc1101_set_rx_mode();
}
else if(wait_tx_count < MAX_FIFO_SIZE)
{
cc1101_read_tx_buf(buf_tmp, wait_tx_count);
cc1101_send_packet(buf_tmp, wait_tx_count);
cc1101_set_tx_mode();
}
else if(wait_tx_count >= MAX_FIFO_SIZE)
{
cc1101_read_tx_buf(buf_tmp, MAX_FIFO_SIZE);
cc1101_send_packet(buf_tmp, MAX_FIFO_SIZE);
cc1101_set_tx_mode();
}
}

/**
description : rf device config and init
param : None
retval : None
author : huohongpeng
date : 2017-02-17
*/
void cc1101_config_init(void)
{
unsigned char chip_id = 0;

cc1101_hw_interface_init();
cc1101_poweron_reset();

while(chip_id != 0x14)
{
chip_id = cc1101_read_status(RF_VERSION);
cc1101_printf("RF_VERSION : 0x%x \r\n", chip_id);
}

cc1101_reg_config_433();
cc1101_gdo0_int_enable();
cc1101_set_rx_mode();
cc1101_printf("cc1101 init ok ...\r\n");
}


/**
description : rf device transmit data.
param : buf - transmit buffer pointer
count - transmit count(0 - TX_BUF_SIZE)
retval : None
author : huohongpeng
date : 2017-02-17
*/
static void cc1101_send(void*_buf, unsigned short count)
{
unsigned char *buf = (unsigned char *)_buf;
unsigned char buf_tmp[TX_BUF_SIZE];

if(count == 0 || count > TX_BUF_SIZE)
{
return;
}

/*
if device is transmit mode, write data to transmit buffer,
and interrupt auto transmit data.
don't write data to device fifo directly.

if device is receive mode, tx buf free size is TX_BUF_SIZE
*/

cc1101_write_tx_buf(buf, count);

if(rf_dev.mode == MODE_RX)
{
if(count < MAX_FIFO_SIZE)
{
cc1101_read_tx_buf(buf_tmp, count);
cc1101_send_packet(buf_tmp, count);
}
else if(count >= MAX_FIFO_SIZE)
{
cc1101_read_tx_buf(buf_tmp, MAX_FIFO_SIZE);
cc1101_send_packet(buf_tmp, MAX_FIFO_SIZE);
}

cc1101_set_tx_mode();
}
}

/**
description : rf device transmit data.
param : buf - transmit buffer pointer
count - transmit count(any)
retval : None
author : huohongpeng
date : 2017-02-17
*/
void cc1101_send_write(void*_buf, unsigned short count)
{
int n1, n2, i;
unsigned char *buf = (unsigned char *)_buf;

n1 = count / TX_BUF_SIZE;
n2 = count % TX_BUF_SIZE;

for(i = 0; i < n1; i++)
{
cc1101_send(buf, TX_BUF_SIZE);
buf += TX_BUF_SIZE;
}

cc1101_send(buf, n2);
}
/**
description : rf device transmit data.
param : buf - transmit buffer pointer
count - transmit count
retval : None
author : huohongpeng
date : 2017-02-17
*/
int cc1101_receive_read(unsigned char *buf, int count)
{
int i, real_read_count;

for(i = 0, real_read_count = 0; i < count; i++)
{
if(rf_dev.rx_rd == rf_dev.rx_wr)
{
return real_read_count;
}
else
{
buf[i] = rf_dev.rx_buf[rf_dev.rx_rd++];
rf_dev.rx_rd %= RX_BUF_SIZE;
real_read_count++;
}
}

return real_read_count;
}


/**
description : rf device gdo0 pin interrupt handle function.
param : None
None
retval : None
author : huohongpeng
date : 2017-02-17

call :
in gdo0 extern interrupt handle function
*/
void cc1101_gdo0_it(void)
{
if(rf_dev.mode == MODE_RX)
{
cc1101_gdo0_rx_it();
}
else if(rf_dev.mode == MODE_TX)
{
cc1101_gdo0_tx_it();
}
else
{
rf_dev.mode = MODE_RX;
}
}