extern void NRF24L01_get_received_data(uint8_t* data, uint8_t len) { NRF24L01_CSN_LOW; spi_fast_shift(NRF24L01_CMD_R_RX_PAYLOAD); spi_transfer_sync(data, data, len); NRF24L01_CSN_HIGH; NRF24L01_LOW_set_register(NRF24L01_REG_STATUS, NRF24L01_MASK_STATUS_RX_DR); }
extern void NRF24L01_set_tx_pwr(uint8_t tx_pwr) { nrf24l01_rf_setup_t* rf_setup = malloc(sizeof(nrf24l01_rf_setup_t)); rf_setup->value = NRF24L01_LOW_get_register(NRF24L01_REG_RF_SETUP); rf_setup->rf_pwr = tx_pwr; NRF24L01_LOW_set_register(NRF24L01_REG_RF_SETUP, rf_setup->value); free(rf_setup); }
///Sets the tx power of the NRF24L01 ///Must be inside range [0 .. 3] ///0 = -18 dBm -> 0.016 mW ///1 = -12 dBm -> 0.063 mW ///2 = - 6 dBm -> 0.251 mW ///3 = 0 dBm -> 1.000 mW extern void NRF24L01_set_tx_pwr(uint8_t tx_pwr) { uint8_t rf_setup = NRF24L01_LOW_get_register(NRF24L01_REG_RF_SETUP); rf_setup &= ~NRF24L01_MASK_RF_SETUP_RF_PWR; rf_setup |= (tx_pwr << 1) & NRF24L01_MASK_RF_SETUP_RF_PWR; rf_setup &= NRF24L01_MASK_RF_SETUP; NRF24L01_LOW_set_register(NRF24L01_REG_RF_SETUP, rf_setup); }
extern void NRF24L01_set_channel(uint8_t channel) { nrf24l01_rf_ch_t* rf_ch = malloc(sizeof(nrf24l01_rf_ch_t)); rf_ch->value = 0; rf_ch->rf_ch = channel; NRF24L01_LOW_set_register(NRF24L01_REG_RF_CH, rf_ch->value); free(rf_ch); }
///Puts the NRF24L01 into transmit mode void NRF24L01_set_tx(void) { uint8_t config = NRF24L01_LOW_get_register(NRF24L01_REG_CONFIG); config &= ~NRF24L01_MASK_CONFIG_PRIM_RX; config |= NRF24L01_MASK_CONFIG_PWR_UP; config &= NRF24L01_MASK_CONFIG; NRF24L01_LOW_set_register(NRF24L01_REG_CONFIG, config); }
///Enables / Disables single data pipes. By default pipe 0 and pipe 1 are enabled void NRF24L01_enable_pipe(uint8_t pipe, uint8_t state) { uint8_t pipes = NRF24L01_LOW_get_register(NRF24L01_REG_EN_RXADDR); if(state) pipes |= (1<<pipe); else pipes &= ~(1<<pipe); NRF24L01_LOW_set_register(NRF24L01_REG_EN_RXADDR, pipes); }
///Enables the dynamic payload feature for the given pipe. ///Overrides the payload width setting for the pipe. extern void NRF24L01_enable_dyn_pld_pipe(uint8_t pipe, uint8_t state) { uint8_t dynpld_pipes = NRF24L01_LOW_get_register(NRF24L01_REG_DYNPD); if(state) dynpld_pipes |= (1 << pipe); else dynpld_pipes &= ~(1 << pipe); NRF24L01_LOW_set_register(NRF24L01_REG_DYNPD, dynpld_pipes); }
void NRF24L01_set_tx(void) { nrf24l01_config_t* config = malloc(sizeof(nrf24l01_config_t)); config->value = NRF24L01_LOW_get_register(NRF24L01_REG_CONFIG); config->prim_rx = 0; config->pwr_up = 1; config->reserved = 0; NRF24L01_LOW_set_register(NRF24L01_REG_CONFIG, config->value); free(config); }
///Sets the data rate used on the RF side ///Must be inside range [0 .. 2] ///0 = 0.25 Mbps ///1 = 1.00 Mbps ///2 = 2.00 Mbps ///0.25 Mbps mode works only with NRF24L01+ extern void NRF24L01_set_rf_dr(uint8_t data_rate) { uint8_t rf_setup = NRF24L01_LOW_get_register(NRF24L01_REG_RF_SETUP); switch(data_rate) { case 0: rf_setup &= ~NRF24L01_MASK_RF_SETUP_RF_DR_HIGH; rf_setup |= NRF24L01_MASK_RF_SETUP_RF_DR_LOW; break; //250 kbps case 1: rf_setup &= ~NRF24L01_MASK_RF_SETUP_RF_DR_HIGH; rf_setup &= ~NRF24L01_MASK_RF_SETUP_RF_DR_LOW; break; //1 Mbps case 2: rf_setup |= NRF24L01_MASK_RF_SETUP_RF_DR_HIGH; rf_setup &= ~NRF24L01_MASK_RF_SETUP_RF_DR_LOW; break; //2 Mbps } rf_setup &= NRF24L01_MASK_RF_SETUP; NRF24L01_LOW_set_register(NRF24L01_REG_RF_SETUP, rf_setup); }
void conn_main() { if(conn_pipe_available != 7) { uint8_t len = NRF24L01_get_payload_len(conn_pipe_available); if(len == 0) { uart_write_async("RX: Length of payload is 0"); return; } conn_frame_t* frame = conn_create_frame(); uint8_t* data = malloc(len); if(frame == NULL || data == NULL) { conn_pipe_available = 7; NRF24L01_LOW_set_register(NRF24L01_REG_STATUS, NRF24L01_MASK_STATUS_RX_DR); //Clear data-ready flag return; } NRF24L01_get_received_data(data, len); conn_pipe_available = 7; NRF24L01_LOW_set_register(NRF24L01_REG_STATUS, NRF24L01_MASK_STATUS_RX_DR); //Clear data-ready flag conn_pack_frame(data, frame); free(data); conn_process_result_t* process_result = conn_process_frame(frame); conn_free_frame(frame); if(process_result == NULL) { uart_write_async("RX: Too few memory to save result"); } else { if(process_result->error_code != CONN_ERROR_OK) { conn_free_connection(process_result->connection); uart_send_byte(process_result->error_code); } free(process_result); } } }
extern void NRF24L01_set_rf_dr(uint8_t data_rate) { nrf24l01_rf_setup_t* rf_setup = malloc(sizeof(nrf24l01_rf_setup_t)); rf_setup->value = NRF24L01_LOW_get_register(NRF24L01_REG_RF_SETUP); switch(data_rate) { case 0: rf_setup->rf_dr_high = 0; rf_setup->rf_dr_low = 1; break; //250 kbps case 1: rf_setup->rf_dr_high = 0; rf_setup->rf_dr_low = 0; break; //1 Mbps case 2: rf_setup->rf_dr_high = 1; rf_setup->rf_dr_low = 0; break; //2 Mbps } NRF24L01_LOW_set_register(NRF24L01_REG_RF_SETUP, rf_setup->value); free(rf_setup); }
extern void NRF24L01_send_data(uint8_t* data, uint8_t len) { NRF24L01_CE_LOW; nrf24l01_config_t* config = malloc(sizeof(nrf24l01_config_t)); config->value = NRF24L01_LOW_get_register(NRF24L01_REG_CONFIG); config->prim_rx = 0; config->pwr_up = 1; NRF24L01_LOW_set_register(NRF24L01_REG_CONFIG, config->value); free(config); NRF24L01_CSN_LOW; spi_fast_shift(NRF24L01_CMD_FLUSH_TX); NRF24L01_CSN_HIGH; NRF24L01_CSN_LOW; spi_fast_shift(NRF24L01_CMD_W_TX_PAYLOAD); spi_transmit_sync(data, len); NRF24L01_CSN_HIGH; NRF24L01_CE_HIGH; _delay_us(10); NRF24L01_CE_LOW; }
//HIGH functions extern void NRF24L01_init(void) { NRF24L01_LOW_init_IO(); spi_init(); NRF24L01_flush_rx(); NRF24L01_flush_tx(); NRF24L01_LOW_set_register(NRF24L01_REG_STATUS, NRF24L01_MASK_STATUS_MAX_RT | NRF24L01_MASK_STATUS_RX_DR | NRF24L01_MASK_STATUS_TX_DS); nrf24l01_config_t* config = malloc(sizeof(nrf24l01_config_t)); config->value = 0; #if NRF24L01_PRESET_RX == TRUE config->prim_rx = 1; #endif config->pwr_up = 1; config->crco = 1; #if WIRELESS_EN_RT_IRQ != TRUE config->mask_max_rt = 1; #endif #if WIRELESS_EN_TX_IRQ != TRUE config->mask_tx_ds = 1; #endif #if WIRELESS_EN_RX_IRQ != TRUE config->mask_rx_dr = 1; #endif config->en_crc = 1; NRF24L01_LOW_set_register(NRF24L01_REG_CONFIG, config->value); free(config); nrf24l01_rf_ch_t* rf_ch = malloc(sizeof(nrf24l01_rf_ch_t)); rf_ch->value = 0; rf_ch->rf_ch = WIRELESS_CHANNEL; NRF24L01_LOW_set_register(NRF24L01_REG_RF_CH, rf_ch->value); free(rf_ch); nrf24l01_rf_setup_t* rf_setup = malloc(sizeof(nrf24l01_rf_setup_t)); rf_setup->value = 0; rf_setup->rf_pwr = NRF24L01_PRESET_TXPWR; rf_setup->rf_dr_high = NRF24L01_PRESET_BAUDRATE_HIGH; rf_setup->rf_dr_low = NRF24L01_PRESET_BAUDRATE_LOW; NRF24L01_LOW_set_register(NRF24L01_REG_RF_SETUP, rf_setup->value); free(rf_setup); nrf24l01_rx_pw_t* payload_width = malloc(sizeof(nrf24l01_rx_pw_t)); payload_width->rx_pw = WIRELESS_PACK_LEN; NRF24L01_LOW_set_register(NRF24L01_REG_RX_PW_P0, payload_width->value); NRF24L01_LOW_set_register(NRF24L01_REG_RX_PW_P1, payload_width->value); free(payload_width); NRF24L01_CE_HIGH; }
///Sets the frequency channel the NRF24L01 operates on. ///Must be inside range [0 .. 125] extern void NRF24L01_set_channel(uint8_t channel) { uint8_t rf_ch = channel; rf_ch &= NRF24L01_MASK_RF_CH_RF_CH; NRF24L01_LOW_set_register(NRF24L01_REG_RF_CH, rf_ch); }
void NRF24L01_set_payload_width(uint8_t pipe, uint8_t width) { NRF24L01_LOW_set_register(NRF24L01_REG_RX_PW_P0 + pipe, width & NRF24L01_MASK_RX_PW_P0); }
void NRF24L01_set_autoack_pipes(nrf24l01_shockburst_t* pipes) { pipes->reserved = 0; NRF24L01_LOW_set_register(NRF24L01_REG_EN_AA, pipes->value); }
void NRF24L01_set_enabled_pipes(nrf24l01_en_rxaddr_t* pipes) { pipes->reserved = 0; NRF24L01_LOW_set_register(NRF24L01_REG_EN_RXADDR, pipes->value); }
///Puts the NRF24L01 into standby mode. extern void NRF24L01_power_down(void) { uint8_t config = NRF24L01_LOW_get_register(NRF24L01_REG_STATUS); config &= ~NRF24L01_MASK_CONFIG_PWR_UP; NRF24L01_LOW_set_register(NRF24L01_REG_STATUS, config); }