691 lines
18 KiB
C
691 lines
18 KiB
C
#include "xc_24g_register.h"
|
|
#include "xc60xx.h"
|
|
#include "xc_24g.h"
|
|
|
|
static volatile uint8_t nrf_tx_status = 0; //发送完成中断
|
|
|
|
//定义接收队列
|
|
uint8_t rxfifo[8][RF_BUFF_LEN+2]; //包含1RSSI+1字节包长度
|
|
uint8_t rxread = 0, rxwrite = 0;
|
|
|
|
//定义RF配置
|
|
struct _rf_cfg_t
|
|
{
|
|
uint16_t tx_chan; //发射信道
|
|
uint16_t rx_chan; //接收信道
|
|
uint32_t tx_addr; //发射地址
|
|
uint32_t rx_addr; //接收地址
|
|
}rf_cfg = { RF_BLE_CHN37, RF_BLE_CHN37, RF_BLE_ADDR, RF_BLE_ADDR };
|
|
|
|
static void nop_cnt(uint32_t cnt)
|
|
{
|
|
for (uint32_t i = 0; i < cnt; i++)
|
|
__nop();
|
|
}
|
|
|
|
static void nrf_rc_calib(void)
|
|
{
|
|
static uint8_t calib_flag = false;
|
|
if (calib_flag)
|
|
return;
|
|
|
|
uint16_t r_val = 0;
|
|
XC_BT_RF->rccal_reg_l &= ~(0x7 << 8);
|
|
XC_BT_RF->rccal_reg_l |= (0x5 << 8);
|
|
delay_us(20);
|
|
XC_BT_RF->rccal_reg_l |= (0x1 << 5); //RG_RCCAL_RESETN = 1
|
|
delay_us(20);
|
|
XC_BT_RF->rccal_reg_l &= ~(0x1 << 3); //RG_RCCAL_SEL = 0
|
|
delay_us(20);
|
|
XC_BT_RF->rccal_reg_l |= (0x1 << 2); //RG_RCCAL_EN = 1
|
|
delay_us(02);
|
|
XC_BT_RF->rccal_reg_l |= (0x1 << 4); //RG_RCCAL_START = 1
|
|
delay_us(20);
|
|
r_val = XC_BT_RF->rccal_rslt_l;
|
|
// Waiting for AD_RCCAL_FINISH raises the calibration value AD_RCCAL_
|
|
while (!(r_val & 0x8000)) { r_val = XC_BT_RF->rccal_rslt_l; }
|
|
r_val = (XC_BT_RF->rccal_rslt_l & 0x7FFF) >> 10;
|
|
XC_BT_RF->rccal_reg_l |= (0x1 << 3); //RG_RCCAL_SEL = 1
|
|
XC_BT_RF->rccal_reg_l &= ~(0x1 << 2); //RG_RCCAL_EN = 0
|
|
XC_BT_RF->rccal_reg_l &= ~(0x1 << 4); //RG_RCCAL_START = 0
|
|
XC_BT_RF->rccal_reg_l &= ~(0x1F << 11);
|
|
XC_BT_RF->rccal_reg_l |= r_val << 11;
|
|
calib_flag = true;
|
|
}
|
|
|
|
static void rf_freq_ctune(uint8_t val)
|
|
{
|
|
uint32_t value = cprao_aon_rf_aonreg_get();
|
|
cprao_aon_rf_aonreg_set((value & (~(0x3f << 20))) | ((val & 0x3f) << 20));
|
|
}
|
|
|
|
static void rf_reset(void)
|
|
{
|
|
uint32_t value = cpr_rf_reg1_get();
|
|
cpr_rf_reg1_set(value & ~(1 << 21));
|
|
delay_ms(2);
|
|
cpr_rf_reg1_set(value | (1 << 21));
|
|
delay_ms(1);
|
|
}
|
|
|
|
static void nrf_modem_init(void)
|
|
{
|
|
cpr_bt_clk_ctl__bt_clk_en__setf(ENABLE); //BT_CLK clock control register
|
|
cpr_bt_modem_clk_ctl__bt_modem_clk_en__setf(ENABLE); //BT_MODEM_CLK clock control register
|
|
cpr_ctlapbclken_grctl__bt_pclk_en__setf(ENABLE); //Configure BT_PCLK_EN enable
|
|
cprao_aon_coreldo_en_set(ENABLE);
|
|
XC_BT_RF->ana18_reg_l &= ~((0x7 << 3) | (0x7));
|
|
XC_BT_RF->ana18_reg_l |= (0x1 << 3);
|
|
}
|
|
|
|
static void nrf_24g_config(void)
|
|
{
|
|
// Set sel_24G_rfchan, sel_24G_rfldoen, sel_24G_rampout regs to use 2.4G signal
|
|
XC_BT_RF->BT.rx_ctrl_sel_l |= 0xE000;
|
|
|
|
#if (XINCX_RF_RATE == RATE_1M)
|
|
XC_BT_RF->ana21_reg_l = (XC_BT_RF->ana21_reg_l & (0xFFFF8FFF)) | 0x3000;
|
|
#elif (XINCX_RF_RATE == DR_2M)
|
|
XC_BT_RF->ana21_reg_l = (XC_BT_RF->ana21_reg_l & (0xFFFF8FFF)) | 0x2000;
|
|
XC_BT_RF->ana3_reg_l |= 0x01;
|
|
#else
|
|
XC_BT_RF->ana21_reg_l = (XC_BT_RF->ana21_reg_l & (0xFFFF8FFF)) | 0x6000;
|
|
#endif
|
|
|
|
XC_BT_RF->ana29_reg_l |= 0x02; // Manual afc
|
|
XC_BT_RF->ana28_reg_l |= 0x01; // Afc pulse
|
|
|
|
rf_reset(); //reset
|
|
// enable 2.4G_mclk 2.4G_hclk 2div of 32MHz
|
|
cpr_rf_reg1__rf24g_mclk_div__setf(1);
|
|
cpr_rf_reg1__rf24g_hclk_en__setf(ENABLE);
|
|
cpr_rf_reg1__rf24g_mclk_en__setf(ENABLE);
|
|
// set 2.4G agc and iq from 2.4 modem
|
|
cpr_rf_reg0__sel__24g_agc__setf(ENABLE);
|
|
cpr_rf_reg0__sel__24g_hwpin__setf(ENABLE);
|
|
|
|
*BLE_COMN_RF24G_CTRL |= 0x700;
|
|
|
|
XC_BT_RF->BT.rf_ctrl1_l |= (1 << 13);
|
|
XC_BT_RF->BT.rf_ctrl1_l &= ~(1 << 12);
|
|
XC_BT_RF->ana2_reg_l &= ~((0xf << 5) | (0x7 << 13));
|
|
XC_BT_RF->ana2_reg_l |= (0x9 << 5) | (0x3 << 13);
|
|
}
|
|
|
|
static void nrf_set_dynpd(uint8_t dynpd)
|
|
{
|
|
XC_RF_2_4G->DYNPD = dynpd;
|
|
}
|
|
|
|
static void nrf_set_feature(uint8_t long_pld, uint8_t fec, uint8_t whiten, uint8_t dpl, uint8_t ack_pay, uint8_t dyn_ack)
|
|
{
|
|
XC_RF_2_4G->FEATURE = (XC_RF_2_4G->FEATURE & (~0x3f)) | (long_pld << 5) | (fec << 4) | (whiten << 3) | (dpl << 2) | (ack_pay << 1) | dyn_ack;
|
|
}
|
|
|
|
static void nrf_set_compatility_featue(uint8_t guard_cfg, uint8_t long_pld_type, uint8_t preamble_num, uint8_t preamble_type,
|
|
uint8_t crc_scope_header, uint8_t crc_scope_addr)
|
|
{
|
|
XC_RF_2_4G->FEATURE = (XC_RF_2_4G->FEATURE & ~(0xff<<8)) | (guard_cfg << 15) | (long_pld_type << 14) | (preamble_num << 12) |
|
|
(preamble_type << 11) | (crc_scope_header << 9) | (crc_scope_addr << 8);
|
|
}
|
|
|
|
static void nrf_set_preamble(uint32_t preamble_word)
|
|
{
|
|
if(XC_RF_2_4G->FEATURE & ~(1 << 11))
|
|
{
|
|
XC_RF_2_4G->PREAMBLE = preamble_word;
|
|
}
|
|
}
|
|
|
|
static void nrf_set_guard_word(uint16_t guard_word)
|
|
{
|
|
XC_RF_2_4G->GUARD = guard_word;
|
|
}
|
|
|
|
static void nrf_set_cfg_top(void)
|
|
{
|
|
#if (XINCX_RF_RATE == RATE_2M)
|
|
XC_RF_2_4G->CFG_TOP = (XC_RF_2_4G->CFG_TOP & (~0x1ffff3)) | 0x1b8672;
|
|
#else
|
|
XC_RF_2_4G->CFG_TOP = (XC_RF_2_4G->CFG_TOP & (~0x1ffff3)) | 0x0b8272;
|
|
#endif
|
|
}
|
|
|
|
static void nrf_set_crc(uint8_t enable, uint8_t crc_bit)
|
|
{
|
|
if (enable)
|
|
{
|
|
if (crc_bit == CRC_1BIT)
|
|
{
|
|
XC_RF_2_4G->CFG_TOP = (XC_RF_2_4G->CFG_TOP & (~0x0c)) | (2 << 2);
|
|
}
|
|
else
|
|
{
|
|
XC_RF_2_4G->CFG_TOP = (XC_RF_2_4G->CFG_TOP & (~0x0c)) | (3 << 2);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
XC_RF_2_4G->CFG_TOP = (XC_RF_2_4G->CFG_TOP & (~0x0c)) | (1 << 2);
|
|
}
|
|
}
|
|
|
|
static void nrf_set_retr(uint8_t cnt, uint8_t delay)
|
|
{
|
|
XC_RF_2_4G->SETUP_RETR = cnt | (delay << 4);
|
|
}
|
|
|
|
static void nrf_set_enaa(uint8_t enaa)
|
|
{
|
|
XC_RF_2_4G->EN_AA = (enaa << 0) | (enaa << 1) | (enaa << 2) | (enaa << 3) | (enaa << 4) | (enaa << 5);
|
|
}
|
|
|
|
static void nrf_set_txaddr_width(uint8_t bytes)
|
|
{
|
|
switch (bytes)
|
|
{
|
|
case 3:
|
|
XC_RF_2_4G->SETUP_AW = 0xa5;
|
|
break;
|
|
case 4:
|
|
XC_RF_2_4G->SETUP_AW = 0xaa;
|
|
break;
|
|
case 5:
|
|
XC_RF_2_4G->SETUP_AW = 0xaf;
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void nrf_set_txaddr(uint32_t addr_l, uint32_t addr_h)
|
|
{
|
|
XC_RF_2_4G->TX_ADDR_L = addr_l;
|
|
XC_RF_2_4G->TX_ADDR_H = (XC_RF_2_4G->TX_ADDR_H & 0xFF00) | (addr_h & 0xFF);
|
|
}
|
|
|
|
static void nrf_set_rxaddr(uint32_t addr_l, uint32_t addr_h)
|
|
{
|
|
XC_RF_2_4G->RX_ADDR_P0_L = addr_l;
|
|
XC_RF_2_4G->RX_ADDR_P0_H = addr_h & 0xff;
|
|
}
|
|
|
|
static void nrf_set_rxlen(uint8_t len)
|
|
{
|
|
XC_RF_2_4G->RX_PW_Px_L = len | (0 << 8) | (0 << 16) | (0 << 24);
|
|
XC_RF_2_4G->RX_PW_Px_H = 0 | (0 << 8);
|
|
}
|
|
|
|
static void nrf_set_data_rate(uint8_t rate)
|
|
{
|
|
XC_RF_2_4G->SETUP_RF = rate;
|
|
}
|
|
|
|
static void nrf_rssi_init(void)
|
|
{
|
|
uint8_t agc_map[5] = {0x44, 0x3a, 0x30, 0x26, 0x1c};
|
|
|
|
XC_RF_2_4G->RSSI = 1 << 6; //使能
|
|
XC_RF_2_4G->AGC_SETTING &= ~(0xf << 16);
|
|
XC_RF_2_4G->AGC_SETTING |= (2 << 16);
|
|
delay_us(1);
|
|
XC_RF_2_4G->PGA_SETTING = agc_map[0] | (agc_map[1] << 8) | (agc_map[2] << 16) | (agc_map[3] << 24);
|
|
XC_RF_2_4G->TX_ADDR_H &= ~(0xFF << 8);
|
|
XC_RF_2_4G->TX_ADDR_H |= (agc_map[4] << 8);
|
|
}
|
|
|
|
//计算RSSI
|
|
static uint8_t nrf_get_rssi(void)
|
|
{
|
|
int16_t rssi_dbm = 0;
|
|
int16_t esti_dbm = (XC_RF_2_4G->RSSI >> 16) & 0xfff;
|
|
uint16_t agc_gain = (XC_RF_2_4G->RSSI >> 8) & 0x7f;
|
|
uint16_t agc = ((agc_gain >> 4) + 1) * 6 + (agc_gain & 0xf) * 2;
|
|
|
|
uint8_t loca_agc = (XC_RF_2_4G->PGA_SETTING >> 24) & 0xff;
|
|
|
|
if (loca_agc == agc) {
|
|
rssi_dbm = ((esti_dbm * 100) / 16 - (87 + agc + 10) * 100) / 100;
|
|
} else {
|
|
rssi_dbm = ((esti_dbm * 100) / 16 - (87 + agc) * 100) / 100;
|
|
}
|
|
if (rssi_dbm <= (-90)) {
|
|
rssi_dbm = rssi_dbm - (90 + rssi_dbm) / 2 - (90 + rssi_dbm) % 2;
|
|
} else if ((rssi_dbm <= (-80)) && (rssi_dbm > (-90))) {
|
|
rssi_dbm = rssi_dbm - (80 + rssi_dbm) / 2 - (80 + rssi_dbm) % 2;
|
|
} else if ((rssi_dbm <= (-70)) && (rssi_dbm > (-80))) {
|
|
rssi_dbm = rssi_dbm - (70 + rssi_dbm) / 2 - (70 + rssi_dbm) % 2;
|
|
} else if ((rssi_dbm <= (-60)) && (rssi_dbm > (-70))) {
|
|
rssi_dbm = rssi_dbm - (60 + rssi_dbm) / 2 - (60 + rssi_dbm) % 2;
|
|
} else if ((rssi_dbm <= (-50)) && (rssi_dbm > (-60))) {
|
|
rssi_dbm = rssi_dbm - (50 + rssi_dbm) / 2 - (50 + rssi_dbm) % 2;
|
|
} else if (rssi_dbm <= (-40)) {
|
|
rssi_dbm = rssi_dbm - (40 + rssi_dbm) / 2 - (40 + rssi_dbm) % 2;
|
|
}
|
|
return (uint8_t)(-rssi_dbm);
|
|
}
|
|
|
|
void nrf_set_power(uint8_t tx_pwr)
|
|
{
|
|
XC_BT_RF->ana21_reg_l = (XC_BT_RF->ana21_reg_l & (~0xfc0)) | ((tx_pwr & 0x3f) << 6);
|
|
XC_RF_2_4G->RF_CH = (XC_RF_2_4G->RF_CH & (~0x3f0000)) | (tx_pwr << 16);
|
|
}
|
|
|
|
void nrf_set_channel(uint16_t channel)
|
|
{
|
|
#if (XINCX_RF_RATE == RATE_2M)
|
|
XC_RF_2_4G->RF_CH = ((XC_RF_2_4G->CFG_TOP & 0x01) ? (channel - 2) : channel);
|
|
#else
|
|
XC_RF_2_4G->RF_CH = ((XC_RF_2_4G->CFG_TOP & 0x01) ? (channel - 1) : channel);
|
|
#endif
|
|
delay_us(2);
|
|
XC_BT_RF->ana28_reg_l &= (~0x1); // Afc pulse
|
|
delay_us(2);
|
|
XC_BT_RF->ana28_reg_l |= 0x1; // Afc pulse
|
|
delay_us(2);
|
|
}
|
|
|
|
//L: standby, H: tx/rx mode
|
|
#define NRF_CE_H (XC_RF_2_4G->CFG_TOP |= 0x4000)
|
|
#define NRF_CE_L (XC_RF_2_4G->CFG_TOP &= ~0x4000)
|
|
|
|
void nrf_set_mode(uint8_t mode)
|
|
{
|
|
NRF_CE_L; //standby
|
|
if(mode == TX_MODE)
|
|
{
|
|
XC_RF_2_4G->CFG_TOP &= ~0x01;
|
|
XC_RF_2_4G->TX_ADDR_L = rf_cfg.tx_addr; //设置发射地址
|
|
nrf_set_channel(rf_cfg.tx_chan); //设置发射信道
|
|
}
|
|
else if(mode == RX_MODE)
|
|
{
|
|
XC_RF_2_4G->CFG_TOP |= 0x01;
|
|
XC_RF_2_4G->RX_ADDR_P0_L = rf_cfg.rx_addr; //设置接收地址
|
|
nrf_set_channel(rf_cfg.rx_chan); //设置接收信道
|
|
}
|
|
NRF_CE_H; //trx mode
|
|
}
|
|
|
|
__RAM_CODE uint8_t nrf_tx_event(uint8_t *buff, uint8_t len)
|
|
{
|
|
uint8_t sucess = 0;
|
|
uint8_t timeout = 200; //2ms超时
|
|
|
|
nrf_tx_status = 0;
|
|
__disable_irq();
|
|
nrf_set_mode(TX_MODE); //设置发射模式
|
|
XC_RF_2_4G->CMD_CFG = CMD_DONE | FLUSH_TX; //清除TX_FIFO
|
|
XC_RF_2_4G->STATUS |= MASK_ALL_INTER; //清除所有中断
|
|
for (uint8_t i = 0; i < SEND_CMD_CNT; i++)
|
|
XC_RF_2_4G->CMD_CFG = CMD_DONE | W_TX_PLOAD;
|
|
for (uint8_t i = 0; i < len; i++)
|
|
XC_RF_2_4G->TX_FIFO_DATA = buff[i];
|
|
delay_us(100);
|
|
//等待发送完成
|
|
while(timeout--)
|
|
{
|
|
delay_us(10);
|
|
if((XC_RF_2_4G->STATUS & MASK_TX_DS) || (nrf_tx_status & MASK_TX_DS)) //发送完成
|
|
{
|
|
sucess = 1; //发送成功
|
|
break;
|
|
}
|
|
else if((XC_RF_2_4G->STATUS & MASK_MAX_RT) || (nrf_tx_status & MASK_MAX_RT)) //到达最大重发次数
|
|
{
|
|
sucess = 0;
|
|
break;
|
|
}
|
|
}
|
|
__enable_irq();
|
|
XC_RF_2_4G->CMD_CFG = CMD_DONE | FLUSH_TX; //清除TX_FIFO
|
|
XC_RF_2_4G->CMD_CFG = CMD_DONE | FLUSH_RX; //清空RX_FIFO
|
|
//XC_RF_2_4G->STATUS |= MASK_TX_DS | MASK_MAX_RT;
|
|
XC_RF_2_4G->STATUS |= MASK_ALL_INTER; //清除所有中断
|
|
nrf_set_mode(RX_MODE); //设置接收模式
|
|
|
|
return sucess;
|
|
}
|
|
|
|
__RAM_CODE uint8_t nrf_rx_event(uint8_t *buff, uint8_t *rssi)
|
|
{
|
|
uint8_t length = 0;
|
|
|
|
if (XC_RF_2_4G->STATUS & MASK_RX_DR) //接收到有效数据
|
|
{
|
|
XC_RF_2_4G->CMD_CFG = CMD_DONE | R_RX_PL_WID;
|
|
length = XC_RF_2_4G->RX_FIFO_LEN & 0xff; //读接收长度
|
|
if(length != 0)
|
|
{
|
|
for (uint8_t i = 0; i < RECV_CMD_CNT; i++)
|
|
{
|
|
nop_cnt(16);
|
|
XC_RF_2_4G->CMD_CFG = CMD_DONE | R_RX_PLOAD;
|
|
nop_cnt(16);
|
|
}
|
|
for (uint8_t i = 0; i < length; i++)
|
|
{
|
|
buff[i] = XC_RF_2_4G->RX_FIFO_DATA;
|
|
}
|
|
*rssi = nrf_get_rssi();
|
|
}
|
|
XC_RF_2_4G->CMD_CFG = CMD_DONE | FLUSH_RX; //清空RX_FIFO
|
|
XC_RF_2_4G->STATUS |= MASK_RX_DR; //清空接收中断
|
|
}
|
|
return length;
|
|
}
|
|
|
|
extern void rf_24g_handle(void); //测试接收中断
|
|
|
|
uint32_t regmap[32];
|
|
void readreg(void)
|
|
{
|
|
uint8_t index = 0;
|
|
|
|
regmap[index++] = XC_RF_2_4G->CFG_TOP;
|
|
regmap[index++] = XC_RF_2_4G->EN_AA;
|
|
regmap[index++] = XC_RF_2_4G->EN_RXADDR;
|
|
regmap[index++] = XC_RF_2_4G->SETUP_AW;
|
|
regmap[index++] = XC_RF_2_4G->SETUP_RETR;
|
|
regmap[index++] = XC_RF_2_4G->RF_CH;
|
|
regmap[index++] = XC_RF_2_4G->SETUP_RF;
|
|
regmap[index++] = XC_RF_2_4G->STATUS;
|
|
regmap[index++] = XC_RF_2_4G->OBSERVE_TX; //
|
|
regmap[index++] = XC_RF_2_4G->RSSI;
|
|
regmap[index++] = XC_RF_2_4G->RX_ADDR_P0_H;
|
|
regmap[index++] = XC_RF_2_4G->RX_ADDR_P0_L;
|
|
regmap[index++] = XC_RF_2_4G->RX_ADDR_P1_H;
|
|
regmap[index++] = XC_RF_2_4G->RX_ADDR_P1_L;
|
|
regmap[index++] = XC_RF_2_4G->RX_ADDR_P2TOP5;
|
|
regmap[index++] = XC_RF_2_4G->BER_ERR_CNT;
|
|
regmap[index++] = XC_RF_2_4G->BER_RECV_CNT;
|
|
regmap[index++] = XC_RF_2_4G->AGC_SETTING;
|
|
regmap[index++] = XC_RF_2_4G->TX_ADDR_H;
|
|
regmap[index++] = XC_RF_2_4G->TX_ADDR_L;
|
|
regmap[index++] = XC_RF_2_4G->PGA_SETTING;
|
|
regmap[index++] = XC_RF_2_4G->RX_PW_Px_H;
|
|
regmap[index++] = XC_RF_2_4G->RX_PW_Px_L;
|
|
regmap[index++] = XC_RF_2_4G->STATUS_FIFO;
|
|
regmap[index++] = XC_RF_2_4G->RSSIREC; //
|
|
regmap[index++] = XC_RF_2_4G->TXPROC_CFG;
|
|
regmap[index++] = XC_RF_2_4G->RXPROC_CFG_H;
|
|
regmap[index++] = XC_RF_2_4G->RXPROC_CFG_L;
|
|
regmap[index++] = XC_RF_2_4G->DYNPD;
|
|
regmap[index++] = XC_RF_2_4G->FEATURE;
|
|
}
|
|
|
|
//接收中断
|
|
__RAM_CODE void RF24G_Handler(void)
|
|
{
|
|
// NRF_CE_L;
|
|
if(XC_RF_2_4G->STATUS & MASK_RX_DR) //接收中断
|
|
{
|
|
rf_24g_handle();
|
|
|
|
rxfifo[rxwrite][1] = nrf_rx_event(rxfifo[rxwrite]+2, rxfifo[rxwrite]);
|
|
if(rxfifo[rxwrite][1] == RF_BUFF_LEN)
|
|
{
|
|
if(((rxwrite + 1) & 7) == rxread)
|
|
{
|
|
rxread = (rxread + 1) & 7;
|
|
}
|
|
rxwrite = (rxwrite + 1) & 7;
|
|
}
|
|
XC_RF_2_4G->STATUS |= MASK_RX_DR;
|
|
}
|
|
if(XC_RF_2_4G->STATUS & (MASK_TX_DS|MASK_MAX_RT)) //发射中断
|
|
{
|
|
nrf_tx_status = XC_RF_2_4G->STATUS;
|
|
XC_RF_2_4G->CMD_CFG = CMD_DONE | FLUSH_TX;
|
|
XC_RF_2_4G->STATUS |= MASK_TX_DS|MASK_MAX_RT;
|
|
}
|
|
nop_cnt(4);
|
|
|
|
}
|
|
|
|
void nrf_24g_init(uint32_t addr, uint16_t chan)
|
|
{
|
|
rf_cfg.tx_addr = addr;
|
|
rf_cfg.rx_addr = addr;
|
|
rf_cfg.tx_chan = chan;
|
|
rf_cfg.rx_chan = chan;
|
|
|
|
/* Rf modem init*/
|
|
nrf_modem_init();
|
|
/* Set up 2.4G RF modem*/
|
|
nrf_24g_config();
|
|
/* Set up crystal oscillator capacitor array */
|
|
rf_freq_ctune(XINCX_RF_CRY_CPT_ARRAY);
|
|
/* Set up dynamic load */
|
|
nrf_set_dynpd(XINCX_RF_DYNPD);
|
|
/* Set retransmission delay and retransmission frequency */
|
|
nrf_set_retr(XINCX_RF_ARC, XINCX_RF_ARD);
|
|
/* Set address width */
|
|
nrf_set_txaddr_width(XINCX_RF_TX_ADDR_WIDTH);
|
|
/* Set PTX address */
|
|
nrf_set_txaddr(RF_BLE_ADDR, XINCX_RF_ADDR_H);
|
|
/* Set PRX address */
|
|
nrf_set_rxaddr(RF_BLE_ADDR, XINCX_RF_ADDR_H);
|
|
/* Set transfer rate */
|
|
nrf_set_data_rate(XINCX_RF_RATE);
|
|
/* Set CFG_TOP */
|
|
nrf_set_cfg_top();
|
|
/* Set CRC */
|
|
nrf_set_crc(XINCX_RF_CRC_ENABLE, XINCX_RF_CRC_BYTE);
|
|
/* Set data frame format */
|
|
nrf_set_feature(XINCX_RF_LONG_PLD, XINCX_RF_FEC, XINCX_RF_WHITEN, XINCX_RF_DPL, XINCX_RF_ACK_PAY,
|
|
XINCX_RF_DYN_ACK);
|
|
nrf_set_compatility_featue(XINCX_RF_GUARD_CFG, XINCX_RF_LONG_PLD_TYPE, XINCX_RF_PREAMBLE_NUM,
|
|
XINCX_RF_PREAMBLE_TYPE, XINCX_RF_CRC_SCOPE_HEADER, XINCX_RF_CRC_SCOPE_ADDR);
|
|
/* Set the leading code */
|
|
nrf_set_preamble(XINCX_RF_PREAMBLE);
|
|
/* Set guard field */
|
|
nrf_set_guard_word(XINCX_RF_GUARD);
|
|
/* Set Payload */
|
|
nrf_set_rxlen(XINCX_RF_PIPE_LEN);
|
|
/*Set ack pipe*/
|
|
nrf_set_enaa(XINCX_RF_PIPE_ENAA);
|
|
/* RC filtering calibration */
|
|
nrf_rc_calib();
|
|
|
|
nrf_set_power(XINCX_RF_POWER); //设置功率
|
|
nrf_set_mode(RX_MODE); //设置接收模式
|
|
|
|
nrf_rssi_init();
|
|
|
|
#if (1 == XINCX_RF_NVIC_MODE)
|
|
NVIC_EnableIRQ(RF24G_IRQn); //开启中断
|
|
#endif
|
|
}
|
|
|
|
//蓝牙模式初始化
|
|
void nrf_ble_init(uint32_t addr, uint16_t chan)
|
|
{
|
|
rf_cfg.tx_addr = addr;
|
|
rf_cfg.rx_addr = addr;
|
|
rf_cfg.tx_chan = chan;
|
|
rf_cfg.rx_chan = chan;
|
|
|
|
/* Rf modem init*/
|
|
nrf_modem_init();
|
|
/* Set up 2.4G RF modem*/
|
|
nrf_24g_config();
|
|
nrf_set_dynpd(XINCX_RF_DYNPD);
|
|
/* Set PTX address */
|
|
nrf_set_txaddr(RF_BLE_ADDR, XINCX_RF_ADDR_H);
|
|
/* Set PRX address */
|
|
nrf_set_rxaddr(RF_BLE_ADDR, XINCX_RF_ADDR_H);
|
|
/* Set address width */
|
|
nrf_set_txaddr_width(XINCX_RF_TX_ADDR_WIDTH);
|
|
/* Set transfer rate */
|
|
nrf_set_data_rate(XINCX_RF_RATE);
|
|
/* Set CFG_TOP */
|
|
nrf_set_cfg_top();
|
|
/* Set CRC */
|
|
nrf_set_crc(XINCX_RF_CRC_ENABLE, XINCX_RF_CRC_BYTE);
|
|
/* Set data frame format */
|
|
nrf_set_feature(XINCX_RF_LONG_PLD, XINCX_RF_FEC, XINCX_RF_WHITEN,
|
|
XINCX_RF_DPL, XINCX_RF_ACK_PAY, XINCX_RF_DYN_ACK);
|
|
/* Set Payload */
|
|
nrf_set_rxlen(XINCX_RF_PIPE_LEN);
|
|
/*Set ack pipe*/
|
|
nrf_set_enaa(XINCX_RF_PIPE_ENAA);
|
|
/* RC filtering calibration */
|
|
nrf_rc_calib();
|
|
|
|
//XC_RF_2_4G->TXPROC_CFG = (XC_RF_2_4G->TXPROC_CFG & (~0xFF)) | 0xEE;
|
|
|
|
nrf_rssi_init();
|
|
|
|
nrf_set_power(XINCX_RF_POWER); //设置功率
|
|
nrf_set_mode(RX_MODE); //设置接收模式
|
|
|
|
#if (1 == XINCX_RF_NVIC_MODE) //开启中断
|
|
NVIC_EnableIRQ(RF24G_IRQn);
|
|
#endif
|
|
}
|
|
|
|
/********************************* 伪蓝牙白化及CRC校验 ***************************************/
|
|
//字节高地位反转
|
|
static uint8_t reverseBits(uint8_t input)
|
|
{
|
|
uint8_t temp = 0;
|
|
if(input & 0x80) temp |= 0x01;
|
|
if(input & 0x40) temp |= 0x02;
|
|
if(input & 0x20) temp |= 0x04;
|
|
if(input & 0x10) temp |= 0x08;
|
|
if(input & 0x08) temp |= 0x10;
|
|
if(input & 0x04) temp |= 0x20;
|
|
if(input & 0x02) temp |= 0x40;
|
|
if(input & 0x01) temp |= 0x80;
|
|
return temp;
|
|
}
|
|
|
|
//白化
|
|
static void ble_whiten(uint8_t *data, uint8_t len, uint16_t freq)
|
|
{
|
|
uint8_t chan = (freq == RF_BLE_CHN38) ? 38 : ((freq == RF_BLE_CHN37) ? 37 : 39);
|
|
uint8_t coeff = reverseBits(chan) | 2;
|
|
|
|
for (uint8_t i = 0; i < len; i++)
|
|
{
|
|
for (uint8_t m = 1; m; m <<= 1)
|
|
{
|
|
if (coeff & 0x80)
|
|
{
|
|
coeff ^= 0x11;
|
|
data[i] ^= m;
|
|
}
|
|
coeff <<= 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
//计算CRC
|
|
static void ble_crc(uint8_t *data, uint8_t len, uint8_t *dst)
|
|
{
|
|
dst[0] = dst[1] = dst[2] = 0x55;
|
|
|
|
uint8_t temp, tempData;
|
|
for (uint8_t i = 0; i < len; i++)
|
|
{
|
|
tempData = data[i];
|
|
for (uint8_t b = 0; b < 8; b++, tempData >>= 1)
|
|
{
|
|
temp = dst[0] >> 7;
|
|
dst[0] <<= 1;
|
|
if (dst[1] & 0x80) {
|
|
dst[0] |= 1;
|
|
}
|
|
dst[1] <<= 1;
|
|
if (dst[2] & 0x80) {
|
|
dst[1] |= 1;
|
|
}
|
|
dst[2] <<= 1;
|
|
if (temp != (tempData & 1)) {
|
|
dst[2] ^= 0x5B;
|
|
dst[1] ^= 0x06;
|
|
}
|
|
}
|
|
}
|
|
dst[2] = reverseBits(dst[2]);
|
|
dst[1] = reverseBits(dst[1]);
|
|
dst[0] = reverseBits(dst[0]);
|
|
}
|
|
|
|
uint8_t ble_buff[RF_BUFF_LEN]; //BLE数据包
|
|
|
|
//发送数据
|
|
//type: 0-EMN数据包,1-BLE广播包
|
|
uint8_t nrf_ble_send(uint8_t *data, uint8_t txlen)
|
|
{
|
|
uint8_t length = 0;
|
|
|
|
if(txlen > (RF_BUFF_LEN - 5)) {
|
|
return 0;
|
|
}
|
|
|
|
ble_buff[0] = 0;
|
|
ble_buff[1] = txlen; //data length
|
|
for(uint8_t i = 0; i < txlen; i++)
|
|
{
|
|
ble_buff[2+i] = data[i];
|
|
}
|
|
length = ble_buff[1] + 5; //head(1) + len(1) + data(len) + crc(3)
|
|
//添加BLE_CRC和白化
|
|
ble_crc(ble_buff, length - 3, ble_buff + length - 3);
|
|
ble_whiten(ble_buff, length, rf_cfg.tx_chan);
|
|
for(int i = 0; i < length; i++)
|
|
{
|
|
ble_buff[i] = reverseBits(ble_buff[i]);
|
|
}
|
|
return nrf_tx_event(ble_buff, length); //发送数据包
|
|
}
|
|
|
|
//接收数据
|
|
uint8_t nrf_ble_recv(uint8_t *data, uint8_t *rssi)
|
|
{
|
|
uint8_t length = 0;
|
|
uint32_t blecrc = 0;
|
|
|
|
#if (1 == XINCX_RF_NVIC_MODE) //开启中断
|
|
if(rxread != rxwrite)
|
|
{
|
|
*rssi = rxfifo[rxread][0]; //RSSI
|
|
length = rxfifo[rxread][1];//数据包长度
|
|
for(uint8_t i = 0; i < length; i++)
|
|
{
|
|
ble_buff[i] = rxfifo[rxread][2+i];
|
|
}
|
|
rxread = (rxread + 1) & 7;
|
|
}
|
|
#else
|
|
length = nrf_rx_event(ble_buff, rssi);
|
|
#endif
|
|
|
|
if(length != 0)
|
|
{
|
|
//反白化
|
|
for(int i = 0; i < length; i++)
|
|
{
|
|
ble_buff[i] = reverseBits(ble_buff[i]);
|
|
}
|
|
ble_whiten(ble_buff, length, rf_cfg.rx_chan);
|
|
//计算有效数据长度
|
|
length = ble_buff[1] + 5; //head(1) + len(1) + data(len) + crc(3)
|
|
//CRC校验
|
|
blecrc = (ble_buff[length-1]<<16) + (ble_buff[length-2]<<8) + ble_buff[length-3];
|
|
ble_crc(ble_buff, length-3, ble_buff+length-3);
|
|
if(blecrc != ((ble_buff[length-1] << 16) + (ble_buff[length-2]<<8) + ble_buff[length-3]))
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
length = ble_buff[1]; //数据长度
|
|
for(uint8_t i = 0; i < length; i++)
|
|
{
|
|
data[i] = ble_buff[2+i];
|
|
}
|
|
}
|
|
|
|
return length;
|
|
}
|