#include "board.h" #include "myRadio.h" #include "myRadio_gpio.h" #include "stm32f10x_it.h" /**-------------------------radio include----------------------------------**/ #include "math.h" #include "A7169_hal.h" #include "A7169reg.h" #include "A7169config_433Mhz10kbps.h" #include "A7169config_433Mhz50kbps.h" #include "A7169config_433Mhz100kbps.h" /**-------------------------radio include end----------------------------------**/ static int8_t rfTxPower; static uint32_t rfFrequence; static uint32_t rfBaudrate; static rfRxCallBack rxCb; static uint8_t rfRxBuffer[255]; static uint32_t rf_handle; static uint8_t rf_workProcess; static uint8_t chipType; /**-------------------------radio params----------------------------------**/ static bool rf_irq; static irqCallback_ts myIrqCallback_tim1; A7169Config_ts A7169ConfigList[MAX_RF_BAUDRATE_COUNT] = { { .config = A7169Config_433Mhz10kbps, .pageA = A7169Config_PageA_433Mhz10kbps, .pageB = A7169Config_PageB_433Mhz10kbps, }, { .config = A7169Config_433Mhz50kbps, .pageA = A7169Config_PageA_433Mhz50kbps, .pageB = A7169Config_PageB_433Mhz50kbps, }, { .config = A7169Config_433Mhz100kbps, .pageA = A7169Config_PageA_433Mhz100kbps, .pageB = A7169Config_PageB_433Mhz100kbps, } }; rfTxPowerReg_ts rfTxPowerList_433[RF_TX_PWR_MAX_COUNT] = { {.power = -14, .tbg = 0, .tdc = 2, .pac = 1,}, {.power = -13, .tbg = 2, .tdc = 0, .pac = 0,}, {.power = -12, .tbg = 3, .tdc = 0, .pac = 0,}, {.power = -11, .tbg = 6, .tdc = 0, .pac = 0,}, {.power = -10, .tbg = 9, .tdc = 0, .pac = 0,}, {.power = -9, .tbg = 11, .tdc = 0, .pac = 0,}, {.power = -8, .tbg = 14, .tdc = 0, .pac = 0,}, {.power = -7, .tbg = 16, .tdc = 0, .pac = 0,}, {.power = -6, .tbg = 1, .tdc = 0, .pac = 1,}, {.power = -5, .tbg = 21, .tdc = 0, .pac = 0,}, {.power = -4, .tbg = 23, .tdc = 0, .pac = 0,}, {.power = -3, .tbg = 1, .tdc = 1, .pac = 1,}, {.power = -2, .tbg = 3, .tdc = 1, .pac = 1,}, {.power = -1, .tbg = 3, .tdc = 2, .pac = 1,}, {.power = 0, .tbg = 4, .tdc = 1, .pac = 1,}, {.power = 1, .tbg = 10, .tdc = 2, .pac = 1,}, {.power = 2, .tbg = 13, .tdc = 2, .pac = 1,}, {.power = 3, .tbg = 17, .tdc = 2, .pac = 1,}, {.power = 4, .tbg = 21, .tdc = 2, .pac = 1,}, {.power = 5, .tbg = 25, .tdc = 2, .pac = 1,}, {.power = 6, .tbg = 29, .tdc = 2, .pac = 1,}, {.power = 7, .tbg = 32, .tdc = 2, .pac = 1,}, {.power = 8, .tbg = 35, .tdc = 2, .pac = 1,}, {.power = 9, .tbg = 38, .tdc = 2, .pac = 1,}, {.power = 10, .tbg = 41, .tdc = 2, .pac = 1,}, {.power = 11, .tbg = 44, .tdc = 2, .pac = 1,}, {.power = 12, .tbg = 47, .tdc = 2, .pac = 1,}, {.power = 13, .tbg = 51, .tdc = 2, .pac = 1,}, {.power = 14, .tbg = 54, .tdc = 2, .pac = 1,}, {.power = 15, .tbg = 57, .tdc = 2, .pac = 1,}, {.power = 16, .tbg = 59, .tdc = 2, .pac = 1,}, {.power = 17, .tbg = 61, .tdc = 2, .pac = 1,}, {.power = 18, .tbg = 62, .tdc = 2, .pac = 1,}, {.power = 19, .tbg = 63, .tdc = 2, .pac = 1,}, {.power = 20, .tbg = 63, .tdc = 2, .pac = 1,}, }; static void tim1_callback(uint8_t status, uint32_t param); uint8_t getRfPowerTabIndex(int8_t power); /**-------------------------radio params end----------------------------------**/ void myRadio_delay(uint32_t time_ms) { uint32_t i, j; i = time_ms; while (i --) { for ( j = 0; j < 1000; j++) { ; } } } /** * @brief IO口中断回调 * IO口产生中断后会执行该函数 * 用于接收射频工作的中断响应 * * @param index */ void myRadio_gpioCallback(uint8_t index) { if (rf_handle != 0xe5) { return; } if ((rf_workProcess != RWP_TX) && (rf_workProcess != RWP_RX)) { return; } rf_irq = true; } /** * @brief 射频初始化 * * @param agr0 * @param agr1_ptr 无线工作状态响应回调 * 产生回调给外部使用,@rfRxCallBack */ void myRadio_init(int agr0, void *agr1_ptr) { myRadio_gpio_init(myRadio_gpioCallback); /**-------------------------radio init----------------------------------**/ A7169_SetConfig(A7169ConfigList[rfBaudrate]); A7169_POR(); if(InitRF()) //init RF { // entry_deep_sleep_mode(); // myRadio_delay(2); // wake_up_from_deep_sleep_mode(); rf_workProcess = RWP_IDLE; } /**-------------------------radio init end----------------------------------**/ RF_EXT_PA_TO_IDLE(); if ((rfRxCallBack )agr1_ptr) { rxCb = (rfRxCallBack )agr1_ptr; } rf_handle = 0xe5; } /** * @brief 射频底层执行程序 * 要放在主循环中执行 * */ void myRadio_process(void) { rfRxPacket_ts packet; if (rf_handle == 0) { return; } if (rf_irq == false) { return; } rf_irq = false; switch (rf_workProcess) { case RWP_TX: {//Tx done rxCb(TX_STA_SECCESS, packet); rf_workProcess = RWP_IDLE; } break; case RWP_RX: {//Rx done packet.rssi = 127; RxPacket_ReadFifo(packet.payload, packet.len); rxCb(RX_STA_SECCESS, packet); rf_workProcess = RWP_IDLE; } break; default: break; } } /** * @brief 退出射频进入休眠 * */ void myRadio_abort(void) { if (rf_handle == 0) { return; } rf_workProcess = RWP_IDLE; RF_EXT_PA_TO_IDLE(); entry_deep_sleep_mode(); } /** * @brief 获取射频工作中心频率 * * @return uint32_t */ uint32_t myRadio_getFrequency(void) { if (rf_handle == 0) { return 0; } return rfFrequence; } /** * @brief 设置射频工作中心频率 * * @param freq * 具体频点,单位:Hz * 参考数据手册【13. Tranceiver Frequency】章节 * 433频段:具体使用范围:410~456MHz */ void myRadio_setFrequency(uint32_t freq) { if (rf_handle == 0) { return; } rfFrequence = freq; pll1_tu pll1_reg; double freqFloat; double integerPartFloat; //整数部分 uint32_t integerPart; //整数部分 double integerOffsetPart; //整数部分剩余的小数 uint32_t freactionalPart; //小数部分 freqFloat = (double)rfFrequence / 1000000; integerOffsetPart = freqFloat / 12.8; integerOffsetPart = modf (integerOffsetPart , &integerPartFloat); integerPart = (uint16_t)integerPartFloat; freactionalPart = (uint32_t)(integerOffsetPart * 65535); pll1_reg.value = A7169ConfigBuffer.config[PLL1_REG]; pll1_reg.bits_w.ip = integerPart; A7169ConfigBuffer.config[PLL1_REG] = pll1_reg.value; A7169ConfigBuffer.config[PLL2_REG] = freactionalPart; A7169_WriteReg(PLL1_REG, pll1_reg.value); A7169_WriteReg(PLL2_REG, freactionalPart); } // When DCM[1:0] = 01, 10, 11, chip will execute preamble length detection automatically. // [000]: 0 bit (Note: When PMD=[000], DC is not hold after ID detected.) // [001]: 4 bits // [010]: 8 bits (Default value) // [011]: 16 bits // [100]: 24 bits. // [101] and [11x]: 32bits. void myRadio_setRxDetectPreambLen(uint8_t len) { rx2_tu rx2; rx2.value = A7169ConfigBuffer.config[RX2_REG]; rx2.bits_w.PMD = len; A7169ConfigBuffer.config[RX2_REG] = rx2.value; A7169_WriteReg(RX2_REG, rx2.value); } // [000]: 1 byte. // [001]: 2 bytes. // [010]: 3 bytes. // [011]: 4 bytes. // [100]: 16 byte. // [101]: 32 bytes. // [110]: 48 bytes. // [111]: 64 bytes. void myRadio_setTxPreambLen(uint8_t len) { pageA_code_tu pageA_code; pageA_code.value = A7169ConfigList[rfBaudrate].pageA[CODE_PAGEA]; pageA_code.bits_w.PML = len; A7169_WritePageA(CODE_PAGEA, pageA_code.value); } // @mode: gioModeSlt_e void myRadio_setGio1Int(gioModeSlt_e mode) { pageA_gio_tu pageA_gio; pageA_gio.value = A7169ConfigList[rfBaudrate].pageA[GIO_PAGEA]; pageA_gio.bits_w.gio1s = mode; A7169ConfigList[rfBaudrate].pageA[GIO_PAGEA] = pageA_gio.value; A7169_WritePageA(GIO_PAGEA, pageA_gio.value); } // [00]: 2 bytes. // [01]: 4 bytes. // [10]: 6 bytes. // [11]: 8 bytes. void myRadio_setIdCodeLen(uint8_t len) { pageA_code_tu pageA_code; pageA_code.value = A7169ConfigList[rfBaudrate].pageA[CODE_PAGEA]; pageA_code.bits_w.IDL0 = len & 0x01; pageA_code.bits_w.IDL1 = len & 0x02; A7169ConfigList[rfBaudrate].pageA[CODE_PAGEA] = pageA_code.value; A7169_WritePageA(CODE_PAGEA, pageA_code.value); } // @return: 0: success, 1: fail int myRadio_setIdCode(uint8_t *id, uint8_t len) { uint8_t i; uint8_t d1, d2, d3, d4; myRadio_setIdCodeLen(len); BOARD_A7169_SCS_L(); myRadioSpi_wByte(CMD_ID_W); for(i=0; i < len; i++) myRadioSpi_wByte(id[i]); BOARD_A7169_SCS_H(); BOARD_A7169_SCS_L(); myRadioSpi_wByte(CMD_ID_R); d1=myRadioSpi_rByte(); d2=myRadioSpi_rByte(); d3=myRadioSpi_rByte(); d4=myRadioSpi_rByte(); BOARD_A7169_SCS_H(); if((d1!=id[0]) || (d2!=id[1]) || (d3!=id[2]) || (d4!=id[3])) { return 1; } return 0; } void myRadio_setWor(uint8_t *id, uint8_t len) { base_modeControl_tu base_modeControl; base_modeControl.value = A7169ConfigBuffer.config[MODE_REG];; base_modeControl.bits_w.wore = 1; A7169_WriteReg(MODE_REG, base_modeControl.value); // } /** * @brief 获取发射功率 * * @return int8_t */ int8_t myRadio_getTxPower(void) { if (rf_handle == 0) { return 0; } return rfTxPower; } /** * @brief 设置发射功率 * TBG[5:0]-> TX Buffer Gain setting. * TBG[5:3]:MISC_CFG2 (Address: 09h) Page21 的bit8 ~ bit10 * TBG[2:0]:TX II (Address: 09h) Page 0 的bit0 ~ bit2 * TDC-> TX Driver current setting. * TDC[1:0] TX II (Address: 09h) Page 0 的bit3 ~ bit4 * PAC-> PA current setting. * PAC[1:0] TX II (Address: 09h) Page 0 的bit5 ~ bit6 * @param power * 单位:dbm */ void myRadio_setTxPower(int8_t power) { if (rf_handle == 0) { return; } rfTxPower = power; pageB_tx2_tu pageB_tx2; pageB_misc_cfg2_tu pageB_misc_cfg2; uint8_t tbg; pageB_tx2.value = A7169ConfigList[rfBaudrate].pageB[TX2_PAGEB]; pageB_misc_cfg2.value = A7169ConfigList[rfBaudrate].pageB[Misc_CFG2_PAGEB]; tbg = rfTxPowerList_433[getRfPowerTabIndex(power)].tbg; pageB_tx2.bits_w.tdc = rfTxPowerList_433[getRfPowerTabIndex(power)].tdc; pageB_tx2.bits_w.pac = rfTxPowerList_433[getRfPowerTabIndex(power)].pac; pageB_tx2.bits_w.tbg0_2 = tbg & 0x07; pageB_misc_cfg2.bits_w.tbg3_5 = (tbg>>3) & 0x07; A7169_WritePageB(TX2_PAGEB, pageB_tx2.value); A7169_WritePageB(Misc_CFG2_PAGEB, pageB_misc_cfg2.value); } /** * 获取射频波特率 * @param : br-> */ uint32_t myRadio_getBaudrate(void) { if (rf_handle == 0) { return 0; } return rfBaudrate; } /** * 设置射频波特率 * @param : br-> */ void myRadio_setBaudrate(uint32_t br) { rfBaudrate = br; } /** * @brief 设置模组型号 * * @param type */ void myRadio_setChipType(uint8_t type) { chipType = type; } /** * @brief 获取模组型号 * * @return uint8_t */ uint8_t myRadio_getChipType(void) { return chipType; } int16_t myRadio_getRssi(void) { return 0; } /** * @brief 无线发送数据包 * * @param packet */ void myRadio_transmit(rfTxPacket_ts *packet) { if (rf_handle == 0) { return; } RF_EXT_PA_TO_TX(); if (rf_workProcess == RWP_IDLE) { rf_workProcess = RWP_IDLE; wake_up_from_deep_sleep_mode(); myRadio_setFrequency(rfFrequence); myRadio_setTxPower(rfTxPower); } if ((rf_workProcess == RWP_RX) || (rf_workProcess == RWP_SLEEP)) { rf_workProcess = RWP_IDLE; StrobeCMD(CMD_STBY); } A7169_FifoWrite(packet->payload, packet->len); //write data to TX FIFO StrobeCMD(CMD_TX); rf_workProcess = RWP_TX; } /** * @brief 进入无线接收 * */ void myRadio_receiver(void) { if (rf_handle == 0) { return; } RF_EXT_PA_TO_RX(); if (rf_workProcess == RWP_IDLE) { rf_workProcess = RWP_IDLE; wake_up_from_deep_sleep_mode(); myRadio_setFrequency(rfFrequence); } if ((rf_workProcess == RWP_TX) || (rf_workProcess == RWP_SLEEP)) { rf_workProcess = RWP_IDLE; StrobeCMD(CMD_STBY); } A7169_WritePageA(FIFO_PAGEA,0x003F);//设置RX FIFO长度阀值为64个字节 StrobeCMD(CMD_RFR);//清接收FIFO指针 StrobeCMD(CMD_RX); rf_workProcess = RWP_RX; } void myRadio_setCtrl(controlMode_te mode, uint32_t value) { if (rf_handle == 0) { return; } myRadio_init(0, 0); switch (mode) { case RADIO_EXT_CONTROL_TX_UNMODULATED: { RF_EXT_PA_TO_TX(); myRadio_setTxPower(rfTxPower); myRadio_setFrequency(rfFrequence); pageA_tx1_tu pageA_tx1; pageA_tx1.value = 0; A7169_WritePageA(TX1_PAGEA, pageA_tx1.value); StrobeCMD(CMD_TX); } break; case RADIO_EXT_CONTROL_TX_MODULATED: { RF_EXT_PA_TO_TX(); myRadio_setTxPower(rfTxPower); myRadio_setFrequency(rfFrequence); A7169_WritePageA(CKO_PAGEA, 0xD28B); //CKO=RCK base_modeControl_tu base_modeControl; base_modeControl.value = 0xffff; base_modeControl.bits_w.fms = 0; A7169_WriteReg(MODE_REG, base_modeControl.value); //set FMS=0, Direct mode StrobeCMD(CMD_TX); myRadio_delay(10); pageA_gio_tu pageA_gio; pageA_gio.value = 0; pageA_gio.bits_w.g1oe = 1; pageA_gio.bits_w.gio1s = GIOMD_TRXD; A7169_WritePageA(GIO_PAGEA, pageA_gio.value); //GIO1=TRXD SET_A7169_GPIO1_OUT(); //通过定时器控制GIO1的状态 myIrqCallback_tim1.thisCb = tim1_callback; TIM1_callbackRegiste(&myIrqCallback_tim1); } break; case RADIO_EXT_CONTROL_RX_SENSITIVITY: { RF_EXT_PA_TO_RX(); pageA_gio_tu pageA_gio; pageA_gio.value = 0; pageA_gio.bits_w.g1oe = 1; pageA_gio.bits_w.gio1s = GIOMD_EOAC_FSYNC; A7169_WritePageA(GIO_PAGEA, pageA_gio.value); //GIO1=TRXD A7169_WritePageA(CKO_PAGEA, 0xD28B); //CKO=RCK base_modeControl_tu base_modeControl; base_modeControl.value = 0; base_modeControl.bits_w.fms = 0; base_modeControl.bits_w.trsr = 0; base_modeControl.bits_w.cer = 1; base_modeControl.bits_w.cce = 1; A7169_WriteReg(MODE_REG, base_modeControl.value); //set FMS=0, Direct mode StrobeCMD(CMD_RX); // myRadio_delay(10); pageA_gio.value = 0; pageA_gio.bits_w.g1oe = 1; pageA_gio.bits_w.gio1s = GIOMD_RXD; A7169_WritePageA(GIO_PAGEA, pageA_gio.value); //GIO1=TRXD } break; default: break; } } /**-------------------------radio funtion----------------------------------**/ static void tim1_callback(uint8_t status, uint32_t param) { if (rand()&0x01) { RF_A7169_GPIO1_H(); } else { RF_A7169_GPIO1_L(); } } uint8_t getRfPowerTabIndex(int8_t power) { for (int i = 0; i < sizeof(rfTxPowerList_433)/sizeof(rfTxPowerReg_ts); i++) { if (rfTxPowerList_433[i].power >= power) { return i; } } return sizeof(rfTxPowerList_433)/sizeof(rfTxPowerReg_ts) - 1; } /**-------------------------radio funtion end----------------------------------**/