void rf_dngl_init(void) { nRF_Init(); // set the addresses nRF_WriteAddrReg(RX_ADDR_P0, DongleAddr, NRF_ADDR_SIZE); #if defined(NRF_CHECK_MODULE) && defined(AVR) nRF_data[1] = 0; nRF_data[2] = 0; nRF_data[3] = 0; nRF_data[4] = 0; nRF_data[5] = 0; nRF_ReadAddrReg(RX_ADDR_P0, 5); // read the address back // compare if (memcmp(nRF_data + 1, &DongleAddr, NRF_ADDR_SIZE) != 0) { //printf("buff=%02x %02x %02x %02x %02x\n", buff[0], buff[1], buff[2], buff[3], buff[4]); //printf("nRF_=%02x %02x %02x %02x %02x\n", nRF_data[1], nRF_data[2], nRF_data[3], nRF_data[4], nRF_data[5]); // toggle the LED forever for (;;) { TogBit(PORT(LED1_PORT), LED1_BIT); _delay_ms(300); } } #endif // NRF_CHECK_MODULE nRF_WriteReg(EN_AA, vENAA_P0); // enable auto acknowledge nRF_WriteReg(SETUP_RETR, vARD_250us); // ARD=250us, ARC=disabled nRF_WriteReg(RF_SETUP, vRF_DR_2MBPS // data rate | vRF_PWR_0DBM); // output power nRF_WriteReg(FEATURE, vEN_DPL | vEN_ACK_PAY); // enable dynamic payload length and ACK payload nRF_WriteReg(DYNPD, vDPL_P0); // enable dynamic payload length for pipe 0 nRF_FlushRX(); nRF_FlushTX(); nRF_WriteReg(EN_RXADDR, vERX_P0); // enable RX address nRF_WriteReg(STATUS, vRX_DR | vTX_DS | vMAX_RT); // reset the IRQ flags nRF_WriteReg(RF_CH, CHANNEL_NUM); // set the channel nRF_WriteReg(CONFIG, vEN_CRC | vCRCO // enable a 2 byte CRC | vMASK_TX_DS // we don't care about the TX_DS status flag | vPRIM_RX // RX mode | vPWR_UP); // power up the transceiver nRF_CE_hi(); // start receiving }
uint8_t rf_dngl_recv(__xdata void* buff, uint8_t buff_size) { uint8_t ret_val = 0; // check if there's data in the RX FIFO nRF_ReadReg(FIFO_STATUS); if ((nRF_data[1] & vRX_EMPTY) == 0) { LED_on(); // read the payload nRF_ReadRxPayloadWidth(); ret_val = nRF_data[1]; // the nRF specs state I have to drop the packet if the length is > 32 if (ret_val > 32) { nRF_FlushRX(); ret_val = 0; } else { nRF_ReadRxPayload(ret_val); memcpy_X(buff, nRF_data + 1, ret_val > buff_size ? buff_size : ret_val); } // reset the TX_DS if (nRF_data[0] & vTX_DS) nRF_WriteReg(STATUS, vTX_DS); LED_off(); } return ret_val; }
/*=====================================================================================================*/ u8 nRF_Rx_Data( u8 *RxBuf ) { u8 Sta; NRF_CE = 1; while(NRF_IRQ!=0); NRF_CE = 0; Sta = nRF_ReadReg(STATUS); nRF_WriteReg(NRF_WRITE+STATUS, Sta); if(Sta&RX_DR) { nRF_ReadBuf(RD_RX_PLOAD, RxBuf, RX_PLOAD_WIDTH); nRF_WriteReg(FLUSH_RX, NOP); return RX_DR; } else return ERROR; }
void rf_ctrl_init(void) { nRF_Init(); // write the addresses nRF_WriteAddrReg(TX_ADDR, DongleAddr, 5); // we need to set the RX address to the same as TX to be // able to receive ACK nRF_WriteAddrReg(RX_ADDR_P0, DongleAddr, 5); #ifdef NRF_CHECK_MODULE nRF_data[1] = 0; nRF_data[2] = 0; nRF_data[3] = 0; nRF_data[4] = 0; nRF_data[5] = 0; nRF_ReadAddrReg(TX_ADDR, 5); // read the address back // compare if (memcmp_P(nRF_data + 1, &DongleAddr, 5) != 0) { //printf("buff=%02x %02x %02x %02x %02x\n", buff[0], buff[1], buff[2], buff[3], buff[4]); //printf("nRF_=%02x %02x %02x %02x %02x\n", nRF_data[1], nRF_data[2], nRF_data[3], nRF_data[4], nRF_data[5]); // toggle the CAPS LED forever //uint8_t c; //for (c = 0; c < 10; ++c) for (;;) { TogBit(PORT(LED_CAPS_PORT), LED_CAPS_BIT); _delay_ms(300); } } #endif // NRF_CHECK_MODULE nRF_WriteReg(EN_AA, vENAA_P0); // enable auto acknowledge nRF_WriteReg(EN_RXADDR, vERX_P0); // enable RX address (for ACK) nRF_WriteReg(SETUP_RETR, vARD_250us // auto retransmit delay - ARD | 0x0f); // auto retransmit count - ARC nRF_WriteReg(FEATURE, vEN_DPL | vEN_ACK_PAY); // enable dynamic payload length and ACK payload nRF_WriteReg(DYNPD, vDPL_P0); // enable dynamic payload length for pipe 0 nRF_FlushRX(); nRF_FlushTX(); nRF_WriteReg(STATUS, vRX_DR | vTX_DS | vMAX_RT); // reset the IRQ flags nRF_WriteReg(RF_CH, CHANNEL_NUM); // set the channel // reset the the lost packet counters plos_total = arc_total = rf_packets_total = 0; }
/*=====================================================================================================*/ u8 nRF_Tx_Data( u8 *TxBuf ) { u8 Sta; NRF_CE = 0; nRF_WriteBuf(WR_TX_PLOAD, TxBuf, TX_PLOAD_WIDTH); NRF_CE = 1; while(NRF_IRQ!=0); Sta = nRF_ReadReg(STATUS); nRF_WriteReg(NRF_WRITE+STATUS, Sta); nRF_WriteReg(FLUSH_TX, NOP); if(Sta&MAX_RT) return MAX_RT; else if(Sta&TX_DS) return TX_DS; else return ERROR; }
/*=====================================================================================================*/ void nRF_RX_Mode( void ) { NRF_CE = 0; nRF_WriteBuf(NRF_WRITE+RX_ADDR_P0, RX_ADDRESS, RX_ADR_WIDTH); // 寫RX節點地址 nRF_WriteReg(NRF_WRITE+EN_AA, 0x01); // 使能通道 0 的自動應答 nRF_WriteReg(NRF_WRITE+EN_RXADDR, 0x01); // 使能通道 0 的接收地址 nRF_WriteReg(NRF_WRITE+RF_CH, CHANAL); // 設置 RF 通信頻率 nRF_WriteReg(NRF_WRITE+RX_PW_P0, RX_PLOAD_WIDTH); // 選擇通道0的有效數據寬度 nRF_WriteReg(NRF_WRITE+RF_SETUP, 0x0f); // 設置TX發射參數, 0db增益, 2Mbps, 低噪聲增益開啟 nRF_WriteReg(NRF_WRITE+CONFIG, 0x0f); // 配置基本工作模式的參數; PWR_UP, EN_CRC, 16BIT_CRC, 接收模式 NRF_CE = 1; }
/*=====================================================================================================*/ void nRF_TX_Mode( void ) { NRF_CE = 0; nRF_WriteBuf(NRF_WRITE+TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH); // 寫 TX 節點地址 nRF_WriteBuf(NRF_WRITE+RX_ADDR_P0, RX_ADDRESS, RX_ADR_WIDTH); // 設置 TX 節點地址, 主要為了使能 ACK nRF_WriteReg(NRF_WRITE+EN_AA, 0x01); // 使能通道 0 的自動應答 nRF_WriteReg(NRF_WRITE+EN_RXADDR, 0x01); // 使能通道 0 的接收地址 nRF_WriteReg(NRF_WRITE+SETUP_RETR, 0x05); // 設置自動重發間隔時間 : 250us + 86us,最大自動重發次數 : 5 次 nRF_WriteReg(NRF_WRITE+RF_CH, CHANAL); // 設置 RF 通道為 CHANAL nRF_WriteReg(NRF_WRITE+RF_SETUP, 0x0f); // 設置 TX 發射參數, 0db增益, 2Mbps, 低噪聲增益開啟 nRF_WriteReg(NRF_WRITE+CONFIG, 0x0e); // 配置基本工作模式的參數; PWR_UP, EN_CRC, 16BIT_CRC, 發射模式, 開啟所有中斷 NRF_CE = 1; // Delay_1us(12); // CE 要拉高一段時間才進入發送模式 }
bool rf_ctrl_send_message(const void* buff, const uint8_t num_bytes) { nRF_WriteReg(RF_SETUP, vRF_DR_2MBPS // data rate | get_nrf_output_power()); // output power nRF_FlushTX(); nRF_WriteReg(CONFIG, vEN_CRC | vCRCO | vPWR_UP); // power up nRF_WriteReg(STATUS, vTX_DS | vRX_DR | vMAX_RT); // reset the status flag nRF_WriteTxPayload(buff, num_bytes); bool is_sent; uint8_t attempts = 0; const uint8_t MAX_ATTEMPTS = 45; uint8_t ticks = 15; const uint8_t TICKS_INCREMENT = 20; do { nRF_CE_hi(); // signal the transceiver to send the packet // wait for the nRF to signal an event sleep_ticks(3); while (PIN(NRF_IRQ_PORT) & _BV(NRF_IRQ_BIT)) sleep_ticks(1); nRF_CE_lo(); uint8_t status = nRF_NOP(); // read the status reg is_sent = (status & vTX_DS) != 0; // did we get an ACK? nRF_WriteReg(STATUS, vMAX_RT | vTX_DS | vRX_DR); // reset the status flags // read the ARC nRF_ReadReg(OBSERVE_TX); arc_total += nRF_data[1] & 0x0f; ++rf_packets_total; if (!is_sent) { ++plos_total; nRF_ReuseTxPayload(); // send the last message again if (ticks >= 0xfe - TICKS_INCREMENT) { sleep_max(5); // 63ms*5 == 0.315sec } else { sleep_ticks(ticks); ticks += TICKS_INCREMENT; } } ++attempts; } while (!is_sent && attempts < MAX_ATTEMPTS); nRF_WriteReg(CONFIG, vEN_CRC | vCRCO); // nRF power down return is_sent; }