RF routines for the Nordic nRF24L01 chip. More...
Go to the source code of this file.
Data Structures | |
struct | rf_config |
Defines | |
#define | CONFIG_CRCO 2 |
#define | CONFIG_EN_CRC 3 |
#define | CONFIG_MASK_MAX_RT 4 |
#define | CONFIG_MASK_RX_DR 6 |
#define | CONFIG_MASK_TX_DS 5 |
#define | CONFIG_PRIM_RX 0 |
#define | CONFIG_PWR_UP 1 |
#define | FIFO_STATUS_RX_EMPTY 0 |
#define | FIFO_STATUS_RX_FULL 1 |
#define | FIFO_STATUS_TX_EMPTY 4 |
#define | FIFO_STATUS_TX_FULL 5 |
#define | FIFO_STATUS_TX_REUSE 6 |
#define | OP_ENABLE_1_MBPS 5 |
#define | OP_ENABLE_CH2 7 |
#define | OP_ENABLE_CRC 2 |
#define | OP_ENABLE_RECEIVE 0 |
#define | OP_ENABLE_SHOCKBURST 6 |
#define | OP_LONG_CRC 1 |
#define | pic_rf_get_status() pic_rf_read_register(RF_NOP, 0, 0) |
#define | pic_rf_receive_mode() pic_rf_set_mode(RECEIVE_MODE) |
#define | pic_rf_set_status(status) pic_rf_send_command(RF_WR_REG_STATUS, status, 1) |
#define | pic_rf_transmit_mode() pic_rf_set_mode(TRANSMIT_MODE) |
#define | RECEIVE_MODE 1 |
#define | RF_FLUSH_RX 0b11100010 |
#define | RF_FLUSH_TX 0b11100001 |
#define | RF_NOP 0b11111111 |
#define | RF_R_RX_PAYLOAD 0b01100001 |
#define | RF_RD_REG_CD 0b00001001 |
#define | RF_RD_REG_CONFIG_REG 0b00000000 |
#define | RF_RD_REG_FIFO_STATUS 0b00010111 |
#define | RF_RD_REG_RX_PW_P0 0b00010001 |
#define | RF_RD_REG_STATUS 0b00000111 |
#define | RF_W_TX_PAYLOAD 0b10100000 |
#define | RF_WR_REG_CONFIG_REG 0b00100000 |
#define | RF_WR_REG_EN_AA 0b00100001 |
#define | RF_WR_REG_RF_CH 0b00100101 |
#define | RF_WR_REG_RF_SETUP 0b00100110 |
#define | RF_WR_REG_RX_ADDR_P0 0b00101010 |
#define | RF_WR_REG_RX_PW_P0 0b00110001 |
#define | RF_WR_REG_SETUP_AW 0b00100011 |
#define | RF_WR_REG_SETUP_RETR 0b00100100 |
#define | RF_WR_REG_STATUS 0b00100111 |
#define | RF_WR_REG_TX_ADDR 0b00110000 |
#define | STATUS_MAX_RT 4 |
#define | STATUS_RX_DR 6 |
#define | STATUS_TX_DS 5 |
#define | STATUS_TX_FULL 0 |
#define | TRANSMIT_MODE 0 |
Functions | |
void | pic_rf_init (rf_config *my_config) |
Initialise nRF24L01 chip with config. | |
void | pic_rf_quick_init (char *my_config, uns8 my_channel, bit my_receive_on) |
Initialise nrf2401a chip with quick config. | |
uns8 | pic_rf_read_register (uns8 cmd, uns8 *data, uns8 data_len) |
Read nRF24L01 register. | |
uns8 | pic_rf_read_register_inline (uns8 cmd, uns8 *data, uns8 data_len) |
Read nRF24L01 register (inline). | |
uns8 | pic_rf_receive (uns8 *data, uns8 bytes_to_receive) |
Receive data from nRF24L01. | |
void | pic_rf_receive_inline (uns8 *data, uns8 bytes_to_receive) |
Receive data from nRF24L01. | |
uns8 | pic_rf_send_byte (uns8 b) |
Clock a byte into the nRF24L01. | |
uns8 | pic_rf_send_byte_int (uns8 b) |
Clock a byte into the nRF24L01. | |
uns8 | pic_rf_send_command (uns8 cmd, uns8 *data, uns8 data_len) |
Send command to the nrf24l01. | |
uns8 | pic_rf_send_command_inline (uns8 cmd, uns8 *data, uns8 data_len) |
Send command to the nrf24l01 (inline). | |
uns8 | pic_rf_send_command_single (uns8 cmd, uns8 data) |
Send a single data byte command to the nrf24l01. | |
void | pic_rf_set_channel (uns8 channel) |
Receive data from nRF24L01 (inline). | |
void | pic_rf_set_mode (uns8 mode) |
Set rf mode to transmit or receive. | |
void | pic_rf_setup () |
Setup ports and pins for communication with nRF24L01. | |
void | pic_rf_transmit (uns8 *data, uns8 bytes_to_transmit) |
Transmit data from nRF24L01. | |
Variables | |
static uns8 | rf_current_channel = 2 |
static bit | rf_current_mode_receive = 0 |
RF routines for the Nordic nRF24L01 chip
#define CONFIG_CRCO 2 |
#define CONFIG_EN_CRC 3 |
#define CONFIG_MASK_MAX_RT 4 |
#define CONFIG_MASK_RX_DR 6 |
#define CONFIG_MASK_TX_DS 5 |
#define CONFIG_PRIM_RX 0 |
#define CONFIG_PWR_UP 1 |
#define FIFO_STATUS_RX_EMPTY 0 |
#define FIFO_STATUS_RX_FULL 1 |
#define FIFO_STATUS_TX_EMPTY 4 |
#define FIFO_STATUS_TX_FULL 5 |
#define FIFO_STATUS_TX_REUSE 6 |
#define OP_ENABLE_1_MBPS 5 |
rf_config options - enable 1 MPS transmition (otherwise 250Kbps)
#define OP_ENABLE_CH2 7 |
rf_config options - enable channel 2 reception
#define OP_ENABLE_CRC 2 |
rf_config options - enable CRC (recommended!)
#define OP_ENABLE_RECEIVE 0 |
rf_config options - enable receive
#define OP_ENABLE_SHOCKBURST 6 |
rf_config options - enable shockburst transmition
#define OP_LONG_CRC 1 |
rf_config options - enable 16 bit CRC (otherwise 8 bit CRC if 0)
#define pic_rf_get_status | ( | ) | pic_rf_read_register(RF_NOP, 0, 0) |
#define pic_rf_receive_mode | ( | ) | pic_rf_set_mode(RECEIVE_MODE) |
#define pic_rf_set_status | ( | status | ) | pic_rf_send_command(RF_WR_REG_STATUS, status, 1) |
#define pic_rf_transmit_mode | ( | ) | pic_rf_set_mode(TRANSMIT_MODE) |
#define RECEIVE_MODE 1 |
Mode selection - receive
#define RF_FLUSH_RX 0b11100010 |
#define RF_FLUSH_TX 0b11100001 |
#define RF_NOP 0b11111111 |
#define RF_R_RX_PAYLOAD 0b01100001 |
#define RF_RD_REG_CD 0b00001001 |
#define RF_RD_REG_CONFIG_REG 0b00000000 |
#define RF_RD_REG_FIFO_STATUS 0b00010111 |
#define RF_RD_REG_RX_PW_P0 0b00010001 |
#define RF_RD_REG_STATUS 0b00000111 |
#define RF_W_TX_PAYLOAD 0b10100000 |
#define RF_WR_REG_CONFIG_REG 0b00100000 |
#define RF_WR_REG_EN_AA 0b00100001 |
#define RF_WR_REG_RF_CH 0b00100101 |
#define RF_WR_REG_RF_SETUP 0b00100110 |
#define RF_WR_REG_RX_ADDR_P0 0b00101010 |
#define RF_WR_REG_RX_PW_P0 0b00110001 |
#define RF_WR_REG_SETUP_AW 0b00100011 |
#define RF_WR_REG_SETUP_RETR 0b00100100 |
#define RF_WR_REG_STATUS 0b00100111 |
#define RF_WR_REG_TX_ADDR 0b00110000 |
#define STATUS_MAX_RT 4 |
#define STATUS_RX_DR 6 |
#define STATUS_TX_DS 5 |
#define STATUS_TX_FULL 0 |
#define TRANSMIT_MODE 0 |
Mode selection - transmit
void pic_rf_init | ( | rf_config * | my_config | ) |
Sends the configuration to the Nordic nRF24L01 chip ready to begin communication. This routine assumes you have already set my_config to the correct values.
Initialise nRF24L01 chip with config.
Sends the configuration to the Nordic nrf2401a chip ready to begin communication. This routine assumes you have already set my_config to the correct values.
00084 { 00085 uns8 temp; 00086 uns8 options; 00087 00088 make_output(rf_data_port, rf_data_pin); // make data pin output 00089 clear_pin(rf_clk1_port, rf_clk1_pin); // make sure it's 0 00090 00091 pic_rf_chip_enable(0); 00092 pic_rf_chip_select(1); // config mode 00093 00094 pic_rf_send_byte(my_config->payload_width_ch2); 00095 pic_rf_send_byte(my_config->payload_width_ch1); 00096 pic_rf_send_bytes(my_config->address_ch2, 5); 00097 pic_rf_send_bytes(my_config->address_ch1, 5); 00098 00099 options = my_config->options; 00100 00101 temp = my_config->address_width << 2; 00102 temp.1 = options.OP_LONG_CRC; // |= my_config->long_crc << 1; 00103 temp.0 = options.OP_ENABLE_CRC; // |= my_config->enable_crc; 00104 00105 pic_rf_send_byte(temp); 00106 00107 temp = options & 0b11100000; //pull off top three bits 00108 //temp.7 = options.ENABLE_CH2; // |= my_config->enable_ch2 << 7; 00109 //temp.6 = options.ENABLE_SHOCKBURST; // |= my_config->enable_shockburst << 6; 00110 //temp.5 = options.ENABLE_1_MBPS; //my_config->enable_1_mbps << 5; 00111 temp |= (my_config->crystal & 0b00000111) << 2; // bits 4,3,2 - mask 3 bit range 00112 temp |= (my_config->output_power & 0b00000011); // bits 1,0 - mask 2 bit range 00113 00114 pic_rf_send_byte(temp); 00115 00116 temp = my_config->channel << 1; 00117 rf_current_channel = my_config->channel; 00118 00119 temp |= options.OP_ENABLE_RECEIVE; // my_config->enable_receive; 00120 rf_current_mode_receive = options.OP_ENABLE_RECEIVE; 00121 00122 pic_rf_send_byte(temp); 00123 00124 pic_rf_chip_select(0); // config mode ended 00125 pic_rf_chip_enable(1); // on the air! 00126 00127 }
void pic_rf_quick_init | ( | char * | my_config, | |
uns8 | my_channel, | |||
bit | my_receive_on | |||
) |
While the usual pic_rf_init() routine is excellent when you want to programatically change the 2401a config, if you're only doing this once (at the start) then it's likely you're burning a lot of instructions (154 words on a PIC16 device) just to send some bytes of config out to the 2401a. If you know your config in advance, then you can just send the byte-stream config using this routine. Use the nrf2401a_config.pl script in the tools directory to generate this string.
00062 { 00063 00064 uns8 byte_counter; 00065 make_output(rf_data_port, rf_data_pin); // make data pin output 00066 clear_pin(rf_clk1_port, rf_clk1_pin); // make sure it's 0 00067 00068 pic_rf_chip_enable(0); 00069 pic_rf_chip_select(1); // config mode 00070 00071 for(byte_counter = 0 ; byte_counter < 15 ; byte_counter++) { 00072 pic_rf_send_byte(my_config[byte_counter]); 00073 } 00074 rf_current_channel = my_channel; 00075 rf_current_mode_receive = my_receive_on; 00076 00077 pic_rf_chip_select(0); // config mode ended 00078 pic_rf_chip_enable(1); // on the air! 00079 00080 }
uns8 pic_rf_read_register | ( | uns8 | cmd, | |
uns8 * | data, | |||
uns8 | data_len | |||
) |
Internal routine to read a particular nRF24L01 register. Clocks out data_len bytes from the chip. Internal routine.
cmd | Read register command, eg RF_RD_REG_STATUS | |
data | Pointer to array of bytes where data will be put | |
data_len | Number of bytes to clock out |
00092 { // returns status 00093 00094 uns8 byte_counter, status; 00095 00096 clear_pin(rf_csn_port, rf_csn_pin); 00097 status = pic_rf_send_byte(cmd); 00098 for(byte_counter = 0 ; byte_counter < data_len ; byte_counter++) { 00099 data[byte_counter] = pic_rf_send_byte(0); 00100 } 00101 00102 set_pin(rf_csn_port, rf_csn_pin); 00103 return status; 00104 }
uns8 pic_rf_read_register_inline | ( | uns8 | cmd, | |
uns8 * | data, | |||
uns8 | data_len | |||
) | [inline] |
Internal routine to read a particular nRF24L01 register. Clocks out data_len bytes from the chip. Internal routine. Inline version.
cmd | Read register command, eg RF_RD_REG_STATUS | |
data | Pointer to array of bytes where data will be put | |
data_len | Number of bytes to clock out |
00326 { 00327 00328 uns8 byte_counter, status; 00329 00330 clear_pin(rf_csn_port, rf_csn_pin); 00331 00332 status = pic_rf_send_byte_int(cmd); 00333 00334 for(byte_counter = 0 ; byte_counter < data_len ; byte_counter++) { 00335 data[byte_counter] = pic_rf_send_byte_int(0); // dummy send to get byte back 00336 } 00337 00338 set_pin(rf_csn_port, rf_csn_pin); 00339 00340 return status; 00341 }
uns8 pic_rf_receive | ( | uns8 * | data, | |
uns8 | bytes_to_receive | |||
) |
Having been notified that there is data available, call this routine to clock the data in from the nRF24L01.
Receive data from nRF24L01.
Having been notified that there is data available, call this routine to clock the data in from the nrf2401a.
!pic_rf_chip_enable(0); // save power
pic_rf_chip_enable(1); // turn chip back on
!pic_rf_chip_enable(0); // save power
pic_rf_chip_enable(1); // turn chip back on
00130 { 00131 uns8 byte_count, bit_count, temp; 00132 00134 bit my_store_gie = intcon.GIE; 00135 kill_interrupts(); 00136 00137 make_input(rf_data_port, rf_data_pin); // make data pin input 00138 00139 for (byte_count = 0; byte_count < bytes_to_receive; byte_count++) { 00140 00141 for (bit_count = 0; bit_count < 8; bit_count++) { 00142 temp <<= 1; 00143 temp.0 = test_pin(rf_data_port, rf_data_pin); 00144 set_pin(rf_clk1_port, rf_clk1_pin); // clock it out 00145 clear_pin(rf_clk1_port, rf_clk1_pin); // ready for next bit 00146 } 00147 data[byte_count] = temp; 00148 } 00149 00151 intcon.GIE = my_store_gie; 00152 }
void pic_rf_receive_inline | ( | uns8 * | data, | |
uns8 | bytes_to_receive | |||
) | [inline] |
Having been notified that there is data available, call this routine to clock the data in from the nRF24L01.
00348 { 00349 pic_rf_read_register_inline(RF_R_RX_PAYLOAD, data, bytes_to_receive); 00350 }
uns8 pic_rf_send_byte | ( | uns8 | b | ) |
Clock one byte into the nRF24L01. Internal routine.
b | The byte to send |
Clock a byte into the nRF24L01.
Internal routine to send a byte to the nrf2401a. Generally you shouldn't need to use this, see pic_rf_transmit instead
00042 { 00043 uns8 bit_counter; 00044 for(bit_counter = 0 ; bit_counter < 8 ; bit_counter++) { 00045 change_pin(rf_data_port, rf_data_pin, b.7); // Put data on data pin 00046 set_pin(rf_clk1_port, rf_clk1_pin); // clock it in (positive edge) 00047 clear_pin(rf_clk1_port, rf_clk1_pin); // ready for next bit 00048 00049 b <<= 1; // Move all the bits left 00050 } // repeat until finished 00051 00052 } // pic_rf_send_byte
uns8 pic_rf_send_byte_int | ( | uns8 | b | ) |
Clock one byte into the nRF24L01. Internal routine.
b | The byte to send |
00141 { 00142 uns8 bit_counter, status; 00143 // - For debug: print_int_hex(b); putc(' '); 00144 for(bit_counter = 0 ; bit_counter < 8 ; bit_counter++) { 00145 change_pin(rf_mosi_port, rf_mosi_pin, b.7); // Put data on data pin 00146 set_pin(rf_sck_port, rf_sck_pin); // clock it in (positive edge) 00147 status <<= 1; 00148 status.0 = test_pin(rf_miso_port, rf_miso_pin); 00149 clear_pin(rf_sck_port, rf_sck_pin); // ready for next bit 00150 00151 b <<= 1; // Move all the bits left 00152 } // repeat until finished 00153 return status; 00154 } // pic_rf_send_byte
uns8 pic_rf_send_command | ( | uns8 | cmd, | |
uns8 * | data, | |||
uns8 | data_len | |||
) |
Send a command and associated data to the nRF24L01
cmd | Command to send, eg, RF_WR_REG_SETUP_RETR | |
data | Pointer to an array of bytes to send as data for the command | |
data_len | Number of bytes in the array |
00066 { 00067 00068 uns8 byte_counter, status; 00069 00070 clear_pin(rf_csn_port, rf_csn_pin); 00071 status = pic_rf_send_byte(cmd); 00072 for(byte_counter = 0 ; byte_counter < data_len ; byte_counter++) { 00073 pic_rf_send_byte(data[byte_counter]); 00074 } 00075 00076 set_pin(rf_csn_port, rf_csn_pin); 00077 return status; 00078 }
uns8 pic_rf_send_command_inline | ( | uns8 | cmd, | |
uns8 * | data, | |||
uns8 | data_len | |||
) | [inline] |
Send a command and associated data to the nRF24L01. Internal routine. Inline version.
cmd | Command to send, eg, RF_WR_REG_SETUP_RETR | |
data | Pointer to an array of bytes to send as data for the command | |
data_len | Number of bytes in the array |
00354 { 00355 00356 uns8 byte_counter, status; 00357 00358 clear_pin(rf_csn_port, rf_csn_pin); 00359 status = pic_rf_send_byte_int(cmd); 00360 for(byte_counter = 0 ; byte_counter < data_len ; byte_counter++) { 00361 pic_rf_send_byte_int(data[byte_counter]); 00362 } 00363 00364 set_pin(rf_csn_port, rf_csn_pin); 00365 return status; 00366 }
uns8 pic_rf_send_command_single | ( | uns8 | cmd, | |
uns8 | data | |||
) |
Send a command and 1 byte of data to the nRF24L01
cmd | Command to send, eg, RF_WR_REG_SETUP_RETR | |
data | One byte of data for the command |
00080 { 00081 00082 uns8 byte_counter, status; 00083 00084 clear_pin(rf_csn_port, rf_csn_pin); 00085 status = pic_rf_send_byte(cmd); 00086 pic_rf_send_byte(data); 00087 set_pin(rf_csn_port, rf_csn_pin); 00088 return status; 00089 }
void pic_rf_set_channel | ( | uns8 | channel | ) |
Having been notified that there is data available, call this routine to clock the data in from the nRF24L01. Change channel on the nRF24L01 Changes the current channel used by the nRF24L01.
Receive data from nRF24L01 (inline).
Reclocks the essential config to change the current channel used by the nrf2401a.
00200 { 00201 bit my_store_gie = intcon.GIE; 00202 kill_interrupts(); 00203 00204 clear_bit(tris_array[rf_data_port - PORTA], rf_data_pin); // make data pin output 00205 00206 pic_rf_chip_enable(0); 00207 pic_rf_chip_select(1); // config mode 00208 00209 rf_current_channel = channel; 00210 channel <<= 1; 00211 channel |= rf_current_mode_receive; 00212 00213 pic_rf_send_byte(channel); 00214 00215 pic_rf_chip_select(0); // config mode ended 00216 pic_rf_chip_enable(1); 00217 00218 intcon.GIE = my_store_gie; 00219 }
void pic_rf_set_mode | ( | uns8 | mode | ) |
Pass RECEIVE_MODE or TRANSMIT_MODE to change current mode. Generally, you shouldn't need to call this routine. The library assumes you want to receive until you transmit, in which case it switches automatically to transmit mode and back to receive afterwards.
00179 { 00180 bit my_store_gie = intcon.GIE; 00181 kill_interrupts(); 00182 00183 make_output(rf_data_port, rf_data_pin); // make data pin output 00184 pic_rf_chip_enable(0); 00185 pic_rf_chip_select(1); // config mode 00186 00187 change_pin(rf_data_port, rf_data_pin, mode); // send a zero 00188 set_pin(rf_clk1_port, rf_clk1_pin); // clock it in (positive edge) 00189 clear_pin(rf_clk1_port, rf_clk1_pin); // ready for next bit 00190 00191 pic_rf_chip_select(0); // config mode ended 00192 pic_rf_chip_enable(1); 00193 00194 rf_current_mode_receive = mode; 00195 00196 intcon.GIE = my_store_gie; 00197 }
void pic_rf_setup | ( | ) |
Set up ports and pins to correct input/output for communication with Nordic nRF24L01
Setup ports and pins for communication with nRF24L01.
Set up ports and pins to correct input/output for communication with Nordif nrf2401a
00221 { 00222 00223 make_output(rf_data_port, rf_data_pin); // make data pin output 00224 make_output(rf_cs_port, rf_cs_pin); // make cs pin output 00225 make_output(rf_ce_port, rf_ce_pin); // make ce pin output 00226 make_input (rf_dr1_port, rf_dr1_pin); // make dr1 pin input 00227 make_output(rf_clk1_port, rf_clk1_pin); // make clk1 pin output 00228 00229 }
void pic_rf_transmit | ( | uns8 * | data, | |
uns8 | bytes_to_transmit | |||
) |
Changes to transmit mode, clocks data into the nrf24L01 and hits the shockburst button. Returns to receive mode when finished.
00326 { 00327 00328 uns8 byte_count, bit_count, temp, cd; 00329 start_crit_sec(); 00330 00331 pic_rf_set_mode(TRANSMIT_MODE); 00332 00333 //pic_rf_send_command (RF_FLUSH_TX, 0, 0 ); 00334 pic_rf_read_register_inline(RF_RD_REG_CD, &cd, 1); 00335 serial_print_str("\n cd="); 00336 serial_print_int(cd); 00337 serial_print_nl(); 00338 pic_rf_send_command(RF_W_TX_PAYLOAD, data, bytes_to_transmit); 00339 00340 set_pin(rf_ce_port, rf_ce_pin); 00341 delay_us(10); // 10us pulse - send packet out on airways 00342 clear_pin(rf_ce_port, rf_ce_pin); 00343 delay_us(130); // TX settling 00344 pic_rf_set_mode(RECEIVE_MODE); // go back to receive mode 00345 00346 end_crit_sec(); 00347 }
uns8 rf_current_channel = 2 [static] |
Maintain state of current channel
bit rf_current_mode_receive = 0 [static] |
Maintain state of current mode (1 = receive mode)