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; }
uint8_t rf_ctrl_read_ack_payload(void* buff, const uint8_t buff_size) { uint8_t ret_val = 0; nRF_ReadReg(FIFO_STATUS); uint8_t fifo_status = nRF_data[1]; if ((fifo_status & vRX_EMPTY) == 0) { nRF_ReadRxPayloadWidth(); uint8_t ack_bytes = nRF_data[1]; // the max ACK payload size has to be 2 if (ack_bytes <= 32) { // read the entire payload nRF_ReadRxPayload(ack_bytes); // copy up to buff_size bytes ret_val = ack_bytes < buff_size ? ack_bytes : buff_size; memcpy(buff, nRF_data + 1, ret_val); } else { nRF_FlushRX(); } } return ret_val; }
void rf_ctrl_get_observe(uint8_t* arc, uint8_t* plos) { nRF_ReadReg(OBSERVE_TX); if (arc) *arc = nRF_data[1] & 0x0f; if (plos) *plos = nRF_data[1] >> 4; }
void rf_dngl_queue_ack_payload(__xdata void* buff, const uint8_t num_bytes) { // get the TX FIFO status nRF_ReadReg(FIFO_STATUS); // clear any unsent ACK payloads if (!(nRF_data[1] & vTX_EMPTY)) nRF_FlushTX(); // send the payload nRF_WriteAckPayload(buff, num_bytes, 0); // pipe 0 }
/*=====================================================================================================*/ 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; }
/*=====================================================================================================*/ 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; }
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; }