stable library for the Nordic NRF24L01+ radio transciever
nrf24l01p.cpp
- Committer:
- emoninet2
- Date:
- 2016-11-21
- Revision:
- 0:795de307e97f
File content as of revision 0:795de307e97f:
/* * nrf24l01p.cpp * * Created: 29-Mar-16 10:57:13 PM * Author: emon1 */ #include "nrf24l01p.h" // default constructor //nrf24l01p::nrf24l01p() //{ // init(); //} //nrf24l01p nrf24l01p::nrf24l01p(PinName mosi, PinName miso, PinName sck, PinName csn, PinName ce, PinName irq) : spi_(mosi, miso, sck), nCS_(csn), ce_(ce), nIRQ_(irq) { } void nrf24l01p::arch_nrf24l01p_ce_pin(bool state){ ce_ = state; } void nrf24l01p::arch_nrf24l01p_csn_pin(bool state){ nCS_ = state; } void nrf24l01p::arch_nrf24l01p_initialize(){ } void nrf24l01p::arch_spi_master_transcieve(uint8_t *data, int len){ int i=0; for(i=0;i<len;i++){ data[i] = spi_.write(data[i]); } } void nrf24l01p::ce_pin(bool state){ arch_nrf24l01p_ce_pin(state); if(state) _nrf24l01p_delay_us(_NRF24L01P_TIMING_Thce_us); //_nrf24l01p_ce_value = state; } void nrf24l01p::csn_pin(bool state){ arch_nrf24l01p_csn_pin(state); //_nrf24l01p_csn_value = state; } void nrf24l01p::read_register(uint8_t address, uint8_t *data, int len){ csn_pin(0); uint8_t temp = (address&(_NRF24L01P_REG_ADDRESS_MASK)); arch_spi_master_transcieve(&temp,1); arch_spi_master_transcieve(data,len); csn_pin(1); } void nrf24l01p::write_register(uint8_t address, uint8_t *data, int len){ csn_pin(0); uint8_t temp = (( _NRF24L01P_SPI_CMD_WR_REG | (address&(_NRF24L01P_REG_ADDRESS_MASK)))); arch_spi_master_transcieve(&temp,1); arch_spi_master_transcieve(data,len); csn_pin(1); } void nrf24l01p::read_rx_payload(uint8_t *data, int pay_len){ csn_pin(0); uint8_t temp = (_NRF24L01P_SPI_CMD_RD_RX_PAYLOAD); arch_spi_master_transcieve(&temp,1); arch_spi_master_transcieve(data,pay_len); csn_pin(1); } void nrf24l01p::write_tx_payload(uint8_t *data, int pay_len){ csn_pin(0); uint8_t temp = (_NRF24L01P_SPI_CMD_WR_TX_PAYLOAD); arch_spi_master_transcieve(&temp,1); arch_spi_master_transcieve(data,pay_len); csn_pin(1); } void nrf24l01p::flush_tx(){ csn_pin(0); uint8_t temp = (_NRF24L01P_SPI_CMD_FLUSH_TX); arch_spi_master_transcieve(&temp,1); csn_pin(1); } void nrf24l01p::flush_rx(){ csn_pin(0); uint8_t temp = (_NRF24L01P_SPI_CMD_FLUSH_RX); arch_spi_master_transcieve(&temp,1); csn_pin(1); } void nrf24l01p::reuse_tx_payload(){ csn_pin(0); uint8_t temp = (_NRF24L01P_SPI_CMD_REUSE_TX_PL); arch_spi_master_transcieve(&temp,1); csn_pin(1); } int nrf24l01p::read_rx_payload_width(){ csn_pin(0); uint8_t temp = (_NRF24L01P_SPI_CMD_R_RX_PL_WID); uint8_t temp2 = 0xff; arch_spi_master_transcieve(&temp,1); arch_spi_master_transcieve(&temp2,1); csn_pin(1); return temp2; } void nrf24l01p::write_ack_payload(_nrf24l01p_pipe_t pipe, uint8_t *data, int pay_len){ csn_pin(0); uint8_t temp = (_NRF24L01P_SPI_CMD_W_ACK_PAYLOAD | pipe); arch_spi_master_transcieve(&temp,1); arch_spi_master_transcieve(data,pay_len); csn_pin(1); } void nrf24l01p::write_tx_payload_noack(uint8_t *data, int pay_len){ csn_pin(0); uint8_t temp = (_NRF24L01P_SPI_CMD_W_TX_PYLD_NO_ACK); arch_spi_master_transcieve(&temp,1); arch_spi_master_transcieve(data,pay_len); csn_pin(1); } int nrf24l01p::get_status(){ csn_pin(0); uint8_t temp = (_NRF24L01P_SPI_CMD_NOP ); arch_spi_master_transcieve(&temp,1); csn_pin(1); return temp; } void nrf24l01p::power_up(){ uint8_t temp; read_register(_NRF24L01P_REG_CONFIG,&temp,sizeof(temp)); temp |= _NRF24L01P_CONFIG_PWR_UP; write_register(_NRF24L01P_REG_CONFIG,&temp,sizeof(temp)); } void nrf24l01p::power_down(){ uint8_t temp; read_register(_NRF24L01P_REG_CONFIG,&temp,sizeof(temp)); temp &= ~_NRF24L01P_CONFIG_PWR_UP; write_register(_NRF24L01P_REG_CONFIG,&temp,sizeof(temp)); } void nrf24l01p::rx_mode(){ uint8_t temp; read_register(_NRF24L01P_REG_CONFIG,&temp,sizeof(temp)); temp |= _NRF24L01P_CONFIG_PRIM_RX; write_register(_NRF24L01P_REG_CONFIG,&temp,sizeof(temp)); } void nrf24l01p::tx_mode(){ uint8_t temp; read_register(_NRF24L01P_REG_CONFIG,&temp,sizeof(temp)); temp &= ~_NRF24L01P_CONFIG_PRIM_RX; write_register(_NRF24L01P_REG_CONFIG,&temp,sizeof(temp)); } void nrf24l01p::set_CRC(_nrf24l01p_crc_t opt){ uint8_t temp; read_register(_NRF24L01P_REG_CONFIG,&temp,sizeof(temp)); temp &= ~(_NRF24L01P_CONFIG_CRC_MASK); temp |= opt; write_register(_NRF24L01P_REG_CONFIG,&temp,sizeof(temp)); } void nrf24l01p::enable_auto_ack(_nrf24l01p_pipe_t pipe){ uint8_t temp; read_register(_NRF24L01P_REG_EN_AA,&temp,sizeof(temp)); set_bit(temp,pipe); write_register(_NRF24L01P_REG_EN_AA,&temp,sizeof(temp)); } void nrf24l01p::disable_auto_ack(_nrf24l01p_pipe_t pipe){ uint8_t temp; read_register(_NRF24L01P_REG_EN_AA,&temp,sizeof(temp)); clr_bit(temp,pipe); write_register(_NRF24L01P_REG_EN_AA,&temp,sizeof(temp)); } void nrf24l01p::disable_auto_ack_all_pipes(){ uint8_t temp = 0; write_register(_NRF24L01P_REG_EN_AA,&temp,sizeof(temp)); } void nrf24l01p::enable_rx_on_pipe(_nrf24l01p_pipe_t pipe){ uint8_t temp; read_register(_NRF24L01P_REG_EN_RXADDR,&temp,sizeof(temp)); set_bit(temp,pipe); write_register(_NRF24L01P_REG_EN_RXADDR,&temp,sizeof(temp)); } void nrf24l01p::disable_rx_on_pipe(_nrf24l01p_pipe_t pipe){ uint8_t temp; read_register(_NRF24L01P_REG_EN_RXADDR,&temp,sizeof(temp)); clr_bit(temp,pipe); write_register(_NRF24L01P_REG_EN_RXADDR,&temp,sizeof(temp)); } void nrf24l01p::set_address_width(_nrf24l01p_aw_t width){ uint8_t temp = width; write_register(_NRF24L01P_REG_SETUP_AW,&temp,sizeof(temp)); } _nrf24l01p_aw_t nrf24l01p::get_address_width(){ uint8_t temp; read_register(_NRF24L01P_REG_SETUP_AW,&temp,sizeof(temp)); return (_nrf24l01p_aw_t) temp; } void nrf24l01p::set_auto_retransmission_count(uint8_t count){ uint8_t temp; read_register(_NRF24L01P_REG_SETUP_RETR,&temp,sizeof(temp)); temp &= ~ 0x0F; temp |= (count<<0); write_register(_NRF24L01P_REG_SETUP_RETR,&temp,sizeof(temp)); } uint8_t nrf24l01p::read_auto_retransmission_count(){ uint8_t temp; read_register(_NRF24L01P_REG_SETUP_RETR,&temp,sizeof(temp)); return temp & 0x0F; } void nrf24l01p::set_auto_retransmission_delay(uint8_t times250us){ uint8_t temp; read_register(_NRF24L01P_REG_SETUP_RETR,&temp,sizeof(temp)); temp &= ~(0xF0); temp |= (times250us<<4); write_register(_NRF24L01P_REG_SETUP_RETR,&temp,sizeof(temp)); } uint8_t nrf24l01p::read_auto_retransmission_delay(){ uint8_t temp; read_register(_NRF24L01P_REG_SETUP_RETR,&temp,sizeof(temp)); return temp & 0xF0; } void nrf24l01p::set_frequency_offset(uint8_t offset){ if( (offset >=0) && ( offset <= 125)){ write_register(_NRF24L01P_REG_RF_CH,&offset,sizeof(offset)); } } uint8_t nrf24l01p::get_frequency_offset(){ uint8_t temp; read_register(_NRF24L01P_REG_RF_CH,&temp,sizeof(temp)); return temp; } void nrf24l01p::set_DataRate(_nrf24l01p_datarate_t DataRate){ uint8_t temp; read_register(_NRF24L01P_REG_RF_SETUP,&temp,sizeof(temp)); temp &= ~_NRF24L01P_RF_SETUP_RF_DR_MASK; temp |= DataRate; write_register(_NRF24L01P_REG_RF_SETUP,&temp,sizeof(temp)); } _nrf24l01p_datarate_t nrf24l01p::get_DataRate(){ uint8_t temp; read_register(_NRF24L01P_REG_RF_SETUP,&temp,sizeof(temp)); temp &= _NRF24L01P_RF_SETUP_RF_DR_MASK; return (_nrf24l01p_datarate_t) temp; } void nrf24l01p::set_RF_Power(_nrf24l01p_RFpower_t RFpower){ uint8_t temp; read_register(_NRF24L01P_REG_RF_SETUP,&temp,sizeof(temp)); temp &= ~_NRF24L01P_RF_SETUP_RF_PWR_MASK; temp |= RFpower; write_register(_NRF24L01P_REG_RF_SETUP,&temp,sizeof(temp)); } _nrf24l01p_RFpower_t nrf24l01p::get_RF_Power(){ uint8_t temp; read_register(_NRF24L01P_REG_RF_SETUP,&temp,sizeof(temp)); temp &= _NRF24L01P_RF_SETUP_RF_PWR_MASK; return (_nrf24l01p_RFpower_t) temp; } bool nrf24l01p::get_tx_fifo_full_flag(){ bool flag; //(get_status()&_NRF24L01P_STATUS_TX_FULL)?flag = 1 : flag = 0; if(get_status()&_NRF24L01P_STATUS_TX_FULL) flag = 1; else flag = 0; return flag; } bool nrf24l01p::get_max_retry_flag(){ bool flag; //(get_status()&_NRF24L01P_STATUS_MAX_RT)?flag = 1 : flag = 0; if(get_status()&_NRF24L01P_STATUS_MAX_RT) flag = 1; else flag = 0; return flag; } void nrf24l01p::clear_max_retry_flag(){ uint8_t temp = get_status(); temp |= _NRF24L01P_STATUS_MAX_RT; write_register(_NRF24L01P_REG_STATUS,&temp,sizeof(temp)); } bool nrf24l01p::get_data_sent_flag(){ bool flag; //(get_status()&_NRF24L01P_STATUS_TX_DS)?flag = 1 : flag = 0; if(get_status()&_NRF24L01P_STATUS_TX_DS) flag = 1; else flag = 0; return flag; } void nrf24l01p::clear_data_sent_flag(){ uint8_t temp = get_status(); temp |= _NRF24L01P_STATUS_TX_DS; write_register(_NRF24L01P_REG_STATUS,&temp,sizeof(temp)); } bool nrf24l01p::get_data_ready_flag(){ bool flag; if(get_status()&_NRF24L01P_STATUS_RX_DR)flag = 1 ; else flag = 0; return flag; } void nrf24l01p::clear_data_ready_flag(){ uint8_t temp = get_status(); temp |= _NRF24L01P_STATUS_RX_DR; write_register(_NRF24L01P_REG_STATUS,&temp,sizeof(temp)); } _nrf24l01p_pipe_t nrf24l01p::get_rx_payload_pipe(){ _nrf24l01p_pipe_t pipe = (_nrf24l01p_pipe_t) ((get_status()&_NRF24L01P_STATUS_RX_P_NO)>>1); return pipe; } uint8_t nrf24l01p::get_arc_count(){ uint8_t temp; read_register(_NRF24L01P_REG_OBSERVE_TX,&temp,sizeof(temp)); return ((temp>>_NRF24L01P_OBSERVE_TX_ARC_CNT_BP)&_NRF24L01P_OBSERVE_TX_ARC_CNT_MASK); } uint8_t nrf24l01p::get_plos_count(){ uint8_t temp; read_register(_NRF24L01P_REG_OBSERVE_TX,&temp,sizeof(temp)); return ((temp>>_NRF24L01P_OBSERVE_TX_PLOS_CNT_BP)&_NRF24L01P_OBSERVE_TX_PLOS_CNT_MASK); } bool nrf24l01p::get_rpd(){ uint8_t temp; bool flag; read_register(_NRF24L01P_REG_RPD,&temp,sizeof(temp)); if(temp!=0) flag = 1 ; else flag = 0; return flag; } void nrf24l01p::set_RX_pipe_address(_nrf24l01p_pipe_t pipe,uint64_t address){ int max_pipe_addr_width = 0; if((pipe>=0) && (pipe<=1) ) { max_pipe_addr_width = 5; } else if ((pipe>=2) && (pipe<=5) ){ max_pipe_addr_width = 1; } uint8_t temp[5]; int i; for(i=0;i<max_pipe_addr_width;i++){ temp[i] = (address>>(8*i))&0xFF; } write_register(_NRF24L01P_REG_RX_ADDR_P0 + pipe,temp,max_pipe_addr_width); } uint64_t nrf24l01p::get_RX_pipe_address(_nrf24l01p_pipe_t pipe){ int max_pipe_addr_width = 0; if((pipe>=0) && (pipe<=1) ) { max_pipe_addr_width = 5; } else if ((pipe>=2) && (pipe<=5) ){ max_pipe_addr_width = 1; } uint8_t temp[5]; read_register(_NRF24L01P_REG_RX_ADDR_P0 + pipe,temp,max_pipe_addr_width); uint64_t temp_addr = 0; uint8_t *temp_addr_ptr = (uint8_t*) &temp_addr; int i; for(i=0;i<max_pipe_addr_width;i++){ *(temp_addr_ptr+i)|= (temp[i]); } return temp_addr; } void nrf24l01p::set_TX_pipe_address(uint64_t address){ uint8_t temp[5]; int i; for( i=0;i<5;i++){ temp[i] = (address>>(8*i))&0xFF; } write_register(_NRF24L01P_REG_TX_ADDR,temp,5); } uint64_t nrf24l01p::get_TX_pipe_address(){ uint8_t temp[5]; read_register(_NRF24L01P_REG_TX_ADDR,temp,5); uint64_t temp_addr = 0; uint8_t *temp_addr_ptr = (uint8_t*) &temp_addr; int i; for(i=0;i<5;i++){ *(temp_addr_ptr+i)|= (temp[i]); } return temp_addr; } uint8_t nrf24l01p::get_RX_pipe_width(_nrf24l01p_pipe_t pipe){ uint8_t temp; read_register((_NRF24L01P_REG_RX_PW_P0+pipe),&temp,sizeof(temp)); return (temp&(0x3F)); } bool nrf24l01p::get_fifo_flag_rx_empty(){ uint8_t temp; bool flag; read_register(_NRF24L01P_REG_FIFO_STATUS,&temp,sizeof(temp)); if(temp&_NRF24L01P_FIFO_STATUS_RX_EMPTY) flag = 1 ; else flag = 0; return flag; } bool nrf24l01p::get_fifo_flag_rx_full(){ uint8_t temp; bool flag; read_register(_NRF24L01P_REG_FIFO_STATUS,&temp,sizeof(temp)); if(temp&_NRF24L01P_FIFO_STATUS_RX_FULL) flag = 1 ; else flag = 0; return flag; } bool nrf24l01p::get_fifo_flag_tx_empty(){ uint8_t temp; bool flag; read_register(_NRF24L01P_REG_FIFO_STATUS,&temp,sizeof(temp)); if(temp&_NRF24L01P_FIFO_STATUS_TX_EMPTY) flag = 1 ; else flag = 0; return flag; } bool nrf24l01p::get_fifo_flag_tx_full(){ uint8_t temp; bool flag; read_register(_NRF24L01P_REG_FIFO_STATUS,&temp,sizeof(temp)); if(temp&_NRF24L01P_FIFO_STATUS_TX_FULL) flag = 1 ; else flag = 0; return flag; } bool nrf24l01p::get_fifo_flag_tx_reuse(){ uint8_t temp; bool flag; read_register(_NRF24L01P_REG_FIFO_STATUS,&temp,sizeof(temp)); if(temp&_NRF24L01P_FIFO_STATUS_RX_REUSE) flag = 1 ; else flag = 0; return flag; } void nrf24l01p::enable_dynamic_payload_pipe(_nrf24l01p_pipe_t pipe){ uint8_t temp; read_register(_NRF24L01P_REG_DYNPD,&temp,sizeof(temp)); temp |= (1<<pipe); write_register(_NRF24L01P_REG_DYNPD,&temp,sizeof(temp)); } void nrf24l01p::disable_dynamic_payload_pipe(_nrf24l01p_pipe_t pipe){ uint8_t temp; read_register(_NRF24L01P_REG_DYNPD,&temp,sizeof(temp)); temp &= ~(1<<pipe); write_register(_NRF24L01P_REG_DYNPD,&temp,sizeof(temp)); } void nrf24l01p::disable_dynamic_payload_all_pipe(){ uint8_t temp = 0x00; write_register(_NRF24L01P_REG_DYNPD,&temp,sizeof(temp)); } void nrf24l01p::enable_dynamic_payload(){ uint8_t temp; read_register(_NRF24L01P_REG_FEATURE,&temp,sizeof(temp)); temp |= _NRF24L01_FEATURE_EN_DPL; write_register(_NRF24L01P_REG_FEATURE,&temp,sizeof(temp)); } void nrf24l01p::disable_dynamic_payload(){ uint8_t temp; read_register(_NRF24L01P_REG_FEATURE,&temp,sizeof(temp)); temp &= ~_NRF24L01_FEATURE_EN_DPL; write_register(_NRF24L01P_REG_FEATURE,&temp,sizeof(temp)); } void nrf24l01p::enable_payload_with_ack(){ uint8_t temp; read_register(_NRF24L01P_REG_FEATURE,&temp,sizeof(temp)); temp |= _NRF24L01_FEATURE_EN_ACK_PAY; write_register(_NRF24L01P_REG_FEATURE,&temp,sizeof(temp)); } void nrf24l01p::disable_payload_with_ack(){ uint8_t temp; read_register(_NRF24L01P_REG_FEATURE,&temp,sizeof(temp)); temp &= ~_NRF24L01_FEATURE_EN_ACK_PAY; write_register(_NRF24L01P_REG_FEATURE,&temp,sizeof(temp)); } void nrf24l01p::enable_dynamic_payload_with_ack(){ uint8_t temp; read_register(_NRF24L01P_REG_FEATURE,&temp,sizeof(temp)); temp |= _NRF24L01_FEATURE_EN_DYN_ACK; write_register(_NRF24L01P_REG_FEATURE,&temp,sizeof(temp)); } void nrf24l01p::disable_dynamic_payload_with_ack(){ uint8_t temp; read_register(_NRF24L01P_REG_FEATURE,&temp,sizeof(temp)); temp &= ~_NRF24L01_FEATURE_EN_DYN_ACK; write_register(_NRF24L01P_REG_FEATURE,&temp,sizeof(temp)); } void nrf24l01p::init(){ arch_nrf24l01p_initialize(); startup(); default_config(); } int nrf24l01p::startup(){ ce_pin(0); csn_pin(0); _nrf24l01p_delay_ms(_NRF24L01P_TIMING_PowerOnReset_ms); stateMode(_NRF24L01P_MODE_POWER_DOWN); stateMode(_NRF24L01P_MODE_RX); clear_data_ready_flag(); flush_rx(); flush_tx(); uint8_t status_rst_val = 0x0e;//reset status write_register(_NRF24L01P_REG_STATUS, &status_rst_val,1); uint8_t config_rst_val = 0x0b;//reset config write_register(_NRF24L01P_REG_CONFIG, &config_rst_val,1); return 0; } int nrf24l01p::default_config(){ disable_auto_ack_all_pipes(); disable_dynamic_payload_all_pipe();/////////ALSO CREEATE FOR DISABLE AUTO ACK FOR ALL PIPE //_nrf24l01p_startup(); enable_dynamic_payload(); enable_payload_with_ack(); enable_auto_ack(_NRF24L01P_PIPE_P0); enable_auto_ack(_NRF24L01P_PIPE_P1); enable_auto_ack(_NRF24L01P_PIPE_P2); enable_auto_ack(_NRF24L01P_PIPE_P3); enable_auto_ack(_NRF24L01P_PIPE_P4); enable_auto_ack(_NRF24L01P_PIPE_P5); enable_dynamic_payload_pipe(_NRF24L01P_PIPE_P0); enable_dynamic_payload_pipe(_NRF24L01P_PIPE_P1); enable_dynamic_payload_pipe(_NRF24L01P_PIPE_P2); enable_dynamic_payload_pipe(_NRF24L01P_PIPE_P3); enable_dynamic_payload_pipe(_NRF24L01P_PIPE_P4); enable_dynamic_payload_pipe(_NRF24L01P_PIPE_P5); enable_rx_on_pipe(_NRF24L01P_PIPE_P0); enable_rx_on_pipe(_NRF24L01P_PIPE_P1); enable_rx_on_pipe(_NRF24L01P_PIPE_P2); enable_rx_on_pipe(_NRF24L01P_PIPE_P3); enable_rx_on_pipe(_NRF24L01P_PIPE_P4); enable_rx_on_pipe(_NRF24L01P_PIPE_P5); set_auto_retransmission_count(15); set_auto_retransmission_delay(15); set_DataRate(_NRF24L01P_RF_SETUP_RF_DR_250KBPS); return 0; } int nrf24l01p::stateMode(nRF24L01P_Mode_Type mode){ switch(mode){ case _NRF24L01P_MODE_POWER_DOWN: { power_down(); ce_pin(0); _nrf24l01p_mode = _NRF24L01P_MODE_POWER_DOWN; break; } case _NRF24L01P_MODE_STANDBY: { if(_nrf24l01p_mode == _NRF24L01P_MODE_POWER_DOWN){ power_up(); _nrf24l01p_delay_us(_NRF24L01P_TIMING_Tpd2stby_us); } else{ ce_pin(0); } _nrf24l01p_mode = _NRF24L01P_MODE_STANDBY; break; } case _NRF24L01P_MODE_RX: { rx_mode(); ce_pin(1); _nrf24l01p_delay_us(_NRF24L01P_TIMING_Tstby2a_us); _nrf24l01p_mode = _NRF24L01P_MODE_RX; break; } case _NRF24L01P_MODE_TX: { tx_mode(); ce_pin(1); _nrf24l01p_delay_us(_NRF24L01P_TIMING_Tstby2a_us); mode = _NRF24L01P_MODE_TX; break; } } return 0; } bool nrf24l01p::readable(){ bool HasData = 0; HasData = !get_fifo_flag_rx_empty(); return HasData; } bool nrf24l01p::writable(){ bool HasData = 0; HasData = !get_fifo_flag_tx_empty(); return HasData; } int nrf24l01p::send(uint8_t *data, int datalen){ if ( datalen <= 0 ) return 0; if ( datalen > _NRF24L01P_TX_FIFO_SIZE ) datalen = _NRF24L01P_TX_FIFO_SIZE; if(get_tx_fifo_full_flag()) return -1; //while(_nrf24l01p_get_tx_fifo_full_flag()); write_tx_payload(data,datalen); return 0; } int nrf24l01p::send_to_address(uint64_t address, uint8_t *data, int datalen){ //_nrf24l01p_disable_payload_with_ack(); set_TX_pipe_address(address); return send(data,datalen); } int nrf24l01p::send_to_address_ack(uint64_t address, uint8_t *data, int datalen){ //_nrf24l01p_enable_payload_with_ack(); set_TX_pipe_address(address); set_RX_pipe_address(_NRF24L01P_PIPE_P0, address); return send(data,datalen); } bool nrf24l01p::readableOnPipe(_nrf24l01p_pipe_t pipe){ bool flag = 0; if((pipe >=0) && (pipe <=5)){ int status = get_status(); if( (status&_NRF24L01P_STATUS_RX_DR) && ((status&_NRF24L01P_STATUS_RX_P_NO)>>1)==pipe){ flag = 1; } else{ flag = 0; } } return flag; } int nrf24l01p::read(_nrf24l01p_pipe_t pipe, uint8_t *data, int datalen){ int rxPayloadWidth; if ( ( pipe < 0 ) || ( pipe > 5 ) ) { return -1; } if (readableOnPipe(pipe) ) { asm("nop"); rxPayloadWidth = _NRF24L01P_TX_FIFO_SIZE; if ( ( rxPayloadWidth < 0 ) || ( rxPayloadWidth > _NRF24L01P_RX_FIFO_SIZE ) ) { flush_rx(); } else{ read_rx_payload(data,rxPayloadWidth); if(get_fifo_flag_rx_empty()) { clear_data_ready_flag(); } } return rxPayloadWidth; } //if RX FIFO is full even after reading data, then flush RX FIFO if(get_fifo_flag_rx_full()){ clear_data_ready_flag(); flush_rx(); } return 0; } int nrf24l01p::read_dyn_pld(_nrf24l01p_pipe_t pipe, uint8_t *data){ int rxPayloadWidth; if ( ( pipe < 0 ) || ( pipe > 5 ) ) { return -1; } if (readableOnPipe(pipe) ) { asm("nop"); rxPayloadWidth = read_rx_payload_width(); if ( ( rxPayloadWidth < 0 ) || ( rxPayloadWidth > _NRF24L01P_RX_FIFO_SIZE ) ) { flush_rx(); } else{ read_rx_payload(data,rxPayloadWidth); if(get_fifo_flag_rx_empty()) { clear_data_ready_flag(); } } return rxPayloadWidth; } else {//if pipe not readable return 0; } return 0; } void nrf24l01p::PTX(){ //backup original machine state nRF24L01P_Mode_Type originalMode = _nrf24l01p_mode; //switching to STANDBY to avoid data reception during state check (ATOMIC state check) stateMode(_NRF24L01P_MODE_STANDBY); //has data to write and no data to read. Do not enter PTX with data in PRX payload. //This is because, if the PRX is full, then sending a data and will forever wait for ACK //and it will never get the ACK because the PRX fifo is full if(writable() && !readable()){ //blocked until data sent while(1){ //clear data sent flag before the next packet is sent clear_data_sent_flag(); //strobe CE for single transmission stateMode(_NRF24L01P_MODE_TX); _nrf24l01p_delay_us(_NRF24L01P_TIMING_Tstby2a_us); stateMode(_NRF24L01P_MODE_STANDBY); //break when DS flag is set and a single payload is sent or all data on RX FIFO sent if(get_data_sent_flag() || !writable() ) break; //if max retry flag is set if(get_max_retry_flag() ) { break; } } //clear data sent flag clear_data_sent_flag(); //if got ack packet, just flush it if(get_data_ready_flag()){ //do what needs to be done with the ACK payload here flush_rx(); } } //restore original machine state stateMode(originalMode); } void nrf24l01p::PRX(){ //backup original machine state nRF24L01P_Mode_Type originalMode = _nrf24l01p_mode; //switching to STANDBY to avoid data reception during state check (ATOMIC state check) stateMode(_NRF24L01P_MODE_STANDBY); //if readable (if RX payload data in RX FIFO) if(readable()){ while(1){ char rxData[32]; _nrf24l01p_pipe_t pipe = get_rx_payload_pipe(); int width = read_dyn_pld(pipe, (uint8_t*)rxData); rxData[width] = '\0'; //what needs to be done with the data read printf("MESG: %s\n", rxData); if(!readable()) break; } } //restore original machine state stateMode(originalMode); } // default destructor nrf24l01p::~nrf24l01p() { } //~nrf24l01p