Library for running RF front-end tests.
Before using this library the radio should be powered up, ideally in the Standby-I state, and the RF clock must be enabled. The first function you must call is rf_test_init(). You are then ready to run the tests. Example of code to use for initialisation on the nrf24LE1:
RFCE = 0; RFCKEN = 1; hal_nrf_set_power_mode(HAL_NRF_PWR_UP); wait_ms(3); rf_test_init();
Example of code to use for initialisation on the nrf24LU1+:
RFCE = 0; RFCTL |= BIT_4; RFCKEN = 1; hal_nrf_set_power_mode(HAL_NRF_PWR_UP); wait_ms(3); rf_test_init();
This library can be used for the following tests :
To generate a constant TX carrier, either unmodulated or modulate with PN9, the following functions are available:
To test the LO leakage you have:
To do a channel sweep on the channel range use these funstions:
The functions for RX sensitivity sets the expected payload and caluculates the bit error rate:
Example of use without interrupt:
uint8_t expected_payload[32] = {0xff, 0x00, 0x2c, 0x20, 0x88, 0xaa, 0xee, 0xcc, 0x22, 0x33, 0x44, 0x55, 0x16, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x10, 0x20, 0x17, 0x18, 0x19, 0x03, 0x0a, 0x20, 0x1c, 0x55}; rf_test_init(); rf_test_sensitivity_init(); rf_test_sensitivity_set_expected_data(32, expected_payload); do{ wait_ms(20); rf_test_receive_and_compute_packet(); bit_error_rate = rf_test_compute_error_rate(); }while(0xFFFF == bit_error_rate); //test is finished, the result is in bit_error_rate and should be divided by 100 to set it in percentage
Example of use with interrupt (IF USING RTX-51 TINY, SET LONG_USR_INTR to 1 in file Conf_tny.A51 !):
void rf_interrupt_handler() { rf_test_ret_t ret_code; uint8_t status; status = hal_nrf_get_clear_irq_flags(); switch(status){ case (1<<HAL_NRF_TX_DS): break; case (1<<HAL_NRF_RX_DR): ret_code = rf_test_receive_and_compute_packet(); if (ret_code == RF_TEST_RC_FINISHED) { isr_send_signal(TASK_RX_SENSITIVITY); //signal the rx_sensitivity that the calculation is finished disable_rf(); //stop the RF IT } break; case (1<<HAL_NRF_MAX_RT): break; default: break; } void main_task() { uint8_t expected_payload[32] = {0xff, 0x00, 0x2c, 0x20, 0x88, 0xaa, 0xee, 0xcc, 0x22, 0x33, 0x44, 0x55, 0x16, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x10, 0x20, 0x17, 0x18, 0x19, 0x03, 0x0a, 0x20, 0x1c, 0x55}; rf_test_init(); rf_test_sensitivity_init(); rf_test_sensitivity_set_expected_data(32, expected_payload); enable_rf(); while (true){ os_wait1(K_SIG); //waits for signal from RF interrupt //test is finished, the result is in bit_error_rate and should be divided by 100 to set it in percentage ber = rf_test_compute_error_rate(); //eventually terminates this task } }
Defines | |
#define | RF_TEST_MAX_CHANNEL 81 |
Upper radio channel. | |
Enumerations | |
enum | rf_test_ret_t { RF_TEST_RC_OK, RF_TEST_RC_FINISHED, RF_TEST_RC_ERR_PARAM, RF_TEST_RC_ERR_BUFFER_FULL, RF_TEST_RC_ERR_NB_RX_BYTES } |
Function return codes. More... | |
Functions | |
void | rf_test_init () |
Initialisation function. | |
rf_test_ret_t | rf_test_sensitivity_init (uint8_t ch, hal_nrf_output_power_t pwr, hal_nrf_datarate_t datarate, uint8_t *address) |
Sensitivity test initialisation. | |
void | rf_test_sensitivity_set_expected_data (uint8_t data_size, uint8_t *p_expected_data) |
Function to define expected data for rx_sensitivity test. | |
rf_test_ret_t | rf_test_receive_and_compute_packet () |
Function to receive and evaluate the number of error in it. | |
uint16_t | rf_test_compute_error_rate () |
Function to calculate and update the overall error rate. | |
rf_test_ret_t | rf_test_init_rx_sweep (uint8_t pwr, uint8_t datarate, uint8_t *rx_mode_address, uint8_t first_channel, uint8_t last_channel) |
Function to initialize the RX sweep test. | |
rf_test_ret_t | rf_test_init_tx_sweep (uint8_t pwr, uint8_t datarate, uint8_t first_channel, uint8_t last_channel) |
Function to initialize the TX sweep test. | |
void | rf_test_txrx_sweep () |
Sweep function for RX and TX. | |
void | rf_test_set_modulation_payload () |
Function to set a modulation payload. | |
rf_test_ret_t | rf_test_start_mod_carrier (uint8_t channel, uint8_t pwr, uint8_t datarate) |
Function to start a modulated carrier. | |
void | rf_test_const_carrier_isr (void) |
RF interrupt function for TX modulated carrier. | |
rf_test_ret_t | rf_test_start_unmod_carrier (uint8_t channel, uint8_t pwr, uint8_t datarate) |
Function to start an unmodulated carrier. | |
rf_test_ret_t | rf_test_start_rx_carrier (uint8_t channel, uint8_t pwr, uint8_t datarate, uint8_t *rx_carrier_address) |
Function to start RX test. |
enum rf_test_ret_t |
Function return codes.
void rf_test_init | ( | ) |
Initialisation function.
Use this function to initialize the rf_test library
Definition at line 56 of file rf_test.c.
{ uint8_t index; rf_test_ctx.nb_computed_bytes = 0; rf_test_ctx.actual_packet_size = 0xFF; rf_test_ctx.bit_errors = 0; rf_test_ctx.bit_error_rate = 0xFFFF; rf_test_ctx.sweep_first_channel = 0; rf_test_ctx.sweep_last_channel = 80; rf_test_ctx.sweep_current_channel = 0; for(index = 0; index < ADDR_WIDTH; index ++) { rf_test_ctx.mod_tx_addr[index] = 0; } for(index = 0; index < MAX_SIZE_PACKET; index ++) { rf_test_ctx.payload[index] = 0; } }
rf_test_ret_t rf_test_sensitivity_init | ( | uint8_t | ch, |
hal_nrf_output_power_t | pwr, | ||
hal_nrf_datarate_t | datarate, | ||
uint8_t * | address | ||
) |
Sensitivity test initialisation.
Use this function to initialize the Rx Sensitivity test
ch | Radio Channel |
pwr | radio power |
datarate | radio data rate |
address | RX address (pointer to an array containing 5 bytes) |
Definition at line 101 of file rf_test.c.
{ uint8_t default_payload[MAX_SIZE_PACKET] = {0xaa, 0x1b, 0x2c, 0x10, 0x81, 0x01, 0x11, 0x1a, 0xfe, 0xee, 0xcd, 0x12, 0x13, 0xa9, 0x92, 0x13, 0x14, 0x17, 0x7d, 0x12, 0xdf, 0xfd, 0xaa, 0xaf, 0x27, 0x65, 0x41, 0x43, 0x3a, 0x2d, 0xc1, 0x55}; rf_test_ctx.bit_errors = 0; rf_test_ctx.bit_error_rate = 0xFFFF; CE_LOW(); hal_nrf_set_output_power(pwr); hal_nrf_set_datarate(datarate); hal_nrf_set_address_width(HAL_NRF_AW_5BYTES); hal_nrf_flush_rx(); hal_nrf_set_operation_mode(HAL_NRF_PRX); hal_nrf_close_pipe(HAL_NRF_ALL); // first close all radio pipes... hal_nrf_open_pipe(HAL_NRF_PIPE0, false); // Turn off all auto acknowledge functionality hal_nrf_set_auto_retr(HAL_NRF_PIPE0,0); hal_nrf_set_rf_channel(ch); hal_nrf_set_pll_mode(false); hal_nrf_set_crc_mode(HAL_NRF_CRC_OFF); hal_nrf_set_address(HAL_NRF_PIPE0, address); if (0xFF == rf_test_ctx.actual_packet_size) { //the size and expected packet has not been set rf_test_sensitivity_set_expected_data(DEFAULT_SIZE_PACKET, default_payload); //set the default values } else { rf_test_sensitivity_set_expected_data(0, NULL); //otherwise reset the previous values } CE_HIGH(); return(RF_TEST_RC_OK); }
void rf_test_sensitivity_set_expected_data | ( | uint8_t | data_size, |
uint8_t * | p_expected_data | ||
) |
Function to define expected data for rx_sensitivity test.
Use this function to set the expected data for RxSensitivity test and the expected packet size.
data_size | actual packet size |
p_expected_data | pointer to an array containing data_size bytes |
Definition at line 79 of file rf_test.c.
{ uint8_t byte_index; CE_LOW(); if (NULL == p_expected_data) { hal_nrf_set_rx_payload_width(HAL_NRF_PIPE0, rf_test_ctx.actual_packet_size); } else { rf_test_ctx.actual_packet_size = data_size; hal_nrf_set_rx_payload_width(HAL_NRF_PIPE0, rf_test_ctx.actual_packet_size); // pipe0 expect 32 byte payload for(byte_index = 0; byte_index < data_size; byte_index++) { rf_test_ctx.payload[byte_index] = p_expected_data[byte_index]; } } CE_HIGH(); }
rf_test_ret_t rf_test_receive_and_compute_packet | ( | ) |
Function to receive and evaluate the number of error in it.
For the RX Sensitivity test, this function has to be called on the RF Received data interrupt. This function get the received data and compute the number of errouneous bits.
Definition at line 158 of file rf_test.c.
{ volatile uint16_t nb_received_byte; uint8_t pload[MAX_SIZE_PACKET]; // recived from RX rf_test_ret_t ret_code = RF_TEST_RC_OK; nb_received_byte = hal_nrf_read_rx_payload(pload); // read received data nb_received_byte &= 0x00FF; //the received number of bytes is on the LSB if(rf_test_ctx.actual_packet_size != nb_received_byte) { ret_code = RF_TEST_RC_ERR_NB_RX_BYTES; } rf_test_compute_error_rate_for_one_packet(nb_received_byte, pload); if (rf_test_ctx.nb_computed_bytes >= NB_BYTES_FOR_ERROR_RATE_CALC) { ret_code = RF_TEST_RC_FINISHED; } return(ret_code); }
uint16_t rf_test_compute_error_rate | ( | ) |
Function to calculate and update the overall error rate.
Use this function to actually compute the error rate. This function should be called regurarly enough to avoid overflowing the buffer. The calculated error rate has to be divided by 100 to get a bit error rate in percent.
0xFFFF | if calculation is not finished |
Definition at line 180 of file rf_test.c.
{ uint32_t local_nb_computed_bits; uint16_t local_nb_error; local_nb_error = (uint16_t)rf_test_ctx.bit_errors; if (0xFFFF == rf_test_ctx.bit_error_rate) { local_nb_computed_bits = (uint32_t)rf_test_ctx.nb_computed_bytes; local_nb_computed_bits = local_nb_computed_bits << 3; //multiply by 8 to get the number of bits. if (rf_test_ctx.nb_computed_bytes >= NB_BYTES_FOR_ERROR_RATE_CALC) { if (local_nb_computed_bits == rf_test_ctx.bit_errors) { rf_test_ctx.bit_error_rate = 9999; } else { //calculate bit error rate //multiplied by 10000 to fit in two bytes, this value must be divided by 100 to get BER in percent. rf_test_ctx.bit_error_rate =(uint16_t)((rf_test_ctx.bit_errors*10000)/local_nb_computed_bits); } rf_test_ctx.nb_computed_bytes = 0; rf_test_ctx.bit_errors = 0; } } return(rf_test_ctx.bit_error_rate); }
rf_test_ret_t rf_test_init_rx_sweep | ( | uint8_t | pwr, |
uint8_t | datarate, | ||
uint8_t * | rx_mode_address, | ||
uint8_t | first_channel, | ||
uint8_t | last_channel | ||
) |
Function to initialize the RX sweep test.
Use this function to initialize a RX sweep test. Sets the given test parameters and initialize the RF accordingly.
pwr | : RF power to set. |
datarate | : RF data rate to set. |
rx_mode_address | : Rx adress. |
first_channel | : first channel to use. |
last_channel | : last channel to use (when reached, goes back to first_channel). |
Definition at line 209 of file rf_test.c.
{ rf_test_ctx.sweep_first_channel = first_channel; rf_test_ctx.sweep_last_channel = last_channel; rf_test_ctx.sweep_current_channel = rf_test_ctx.sweep_first_channel; CE_LOW(); hal_nrf_set_output_power(pwr); hal_nrf_set_datarate(datarate); hal_nrf_set_address_width(HAL_NRF_AW_5BYTES); hal_nrf_flush_rx(); hal_nrf_set_operation_mode(HAL_NRF_PRX); hal_nrf_close_pipe(HAL_NRF_ALL); // first close all radio pipes... hal_nrf_open_pipe(HAL_NRF_PIPE0, false); // Turn off all auto acknowledge functionality hal_nrf_set_auto_retr(HAL_NRF_PIPE0,0); hal_nrf_set_pll_mode(false); hal_nrf_set_crc_mode(HAL_NRF_CRC_OFF); hal_nrf_set_address(HAL_NRF_PIPE0, rx_mode_address); hal_nrf_set_rx_payload_width(HAL_NRF_PIPE0, DEFAULT_SIZE_PACKET); // pipe0 expect 32 byte payload CE_HIGH(); return(RF_TEST_RC_OK); }
rf_test_ret_t rf_test_init_tx_sweep | ( | uint8_t | pwr, |
uint8_t | datarate, | ||
uint8_t | first_channel, | ||
uint8_t | last_channel | ||
) |
Function to initialize the TX sweep test.
Use this function to initialize a TX sweep test. Sets the given test parameters and initialize the RF accordingly.
pwr | : RF power to set. |
datarate | : RF data rate to set. |
first_channel | : first channel to use. |
last_channel | : last channel to use (when reached, goes back to first_channel). |
Definition at line 233 of file rf_test.c.
{ rf_test_ctx.sweep_first_channel = first_channel; rf_test_ctx.sweep_last_channel = last_channel; rf_test_ctx.sweep_current_channel = rf_test_ctx.sweep_first_channel; CE_LOW(); hal_nrf_set_operation_mode(HAL_NRF_PTX); hal_nrf_set_pll_mode(true); hal_nrf_set_output_power(pwr); hal_nrf_set_datarate(datarate); hal_nrf_set_crc_mode(HAL_NRF_CRC_OFF); hal_nrf_enable_continious_wave(true); CE_HIGH(); return(RF_TEST_RC_OK); }
void rf_test_txrx_sweep | ( | ) |
Sweep function for RX and TX.
Use this function to actualy do a Tx or Rx sweep. should be called at the desired sweep rate (time per channel). Usage:
while (testing) { rf_test_txrx_sweep(); wait(channel_hold(); }
Definition at line 251 of file rf_test.c.
{ CE_LOW(); hal_nrf_set_rf_channel(rf_test_ctx.sweep_current_channel); CE_HIGH(); rf_test_ctx.sweep_current_channel++; if (rf_test_ctx.sweep_current_channel > rf_test_ctx.sweep_last_channel) { rf_test_ctx.sweep_current_channel = rf_test_ctx.sweep_first_channel; } }
void rf_test_set_modulation_payload | ( | ) |
Function to set a modulation payload.
Use this function to set a PN9 modulation payload. call this function for tx modulated carrier test.
Definition at line 265 of file rf_test.c.
{ uint8_t i; pn9_init(); for (i = 0; i < ADDR_WIDTH; i++) { rf_test_ctx.mod_tx_addr[i] = pn9_get_byte(); } for (i = 0; i < DEFAULT_SIZE_PACKET; i++) { rf_test_ctx.payload[i] = pn9_get_byte(); } }
rf_test_ret_t rf_test_start_mod_carrier | ( | uint8_t | channel, |
uint8_t | pwr, | ||
uint8_t | datarate | ||
) |
Function to start a modulated carrier.
Use this function to start a modulated carrier.
channel | : RF channel to use. |
pwr | : Rf power. |
datarate | : Rf data rate. |
Definition at line 282 of file rf_test.c.
{ if (channel > RF_TEST_MAX_CHANNEL) { return(RF_TEST_RC_ERR_PARAM); } if (pwr > HAL_NRF_0DBM){ return(RF_TEST_RC_ERR_PARAM); } if (datarate > HAL_NRF_250KBPS) { return(RF_TEST_RC_ERR_PARAM); } CE_LOW(); hal_nrf_set_output_power(pwr); hal_nrf_set_datarate(datarate); hal_nrf_set_address_width(HAL_NRF_AW_5BYTES); hal_nrf_set_operation_mode(HAL_NRF_PTX); hal_nrf_open_pipe(HAL_NRF_PIPE0, false); // Turn off all auto acknowledge functionality hal_nrf_set_auto_retr(0,0); hal_nrf_set_rf_channel(channel); hal_nrf_set_pll_mode(true); hal_nrf_set_address(HAL_NRF_TX, rf_test_ctx.mod_tx_addr); hal_nrf_write_tx_payload(rf_test_ctx.payload, DEFAULT_SIZE_PACKET); hal_nrf_set_crc_mode(HAL_NRF_CRC_OFF); CE_PULSE(); return(RF_TEST_RC_OK); }
void rf_test_const_carrier_isr | ( | void | ) |
RF interrupt function for TX modulated carrier.
Call this function from RF interrupt for TX modulated carrier. It will assure the packet is retransmitted.
Definition at line 316 of file rf_test.c.
{ static uint8_t pk_cnt_ = 0; CE_HIGH(); hal_nrf_reuse_tx(); hal_nrf_get_clear_irq_flags(); if(pk_cnt_ > 19) { CE_LOW(); pk_cnt_ = 0; CE_PULSE(); // Refresh } else { pk_cnt_++; } }
rf_test_ret_t rf_test_start_unmod_carrier | ( | uint8_t | channel, |
uint8_t | pwr, | ||
uint8_t | datarate | ||
) |
Function to start an unmodulated carrier.
Use this function to start TX unmodulated carrier.
channel | : RF channel to use. |
pwr | : Rf power. |
datarate | : Rf data rate. |
Definition at line 337 of file rf_test.c.
{ CE_LOW(); hal_nrf_set_operation_mode(HAL_NRF_PTX); hal_nrf_set_rf_channel(channel); hal_nrf_set_pll_mode(true); hal_nrf_set_output_power(pwr); hal_nrf_set_datarate(datarate); hal_nrf_set_crc_mode(HAL_NRF_CRC_OFF); hal_nrf_enable_continious_wave(true); CE_HIGH(); return(RF_TEST_RC_OK); }
rf_test_ret_t rf_test_start_rx_carrier | ( | uint8_t | channel, |
uint8_t | pwr, | ||
uint8_t | datarate, | ||
uint8_t * | rx_carrier_address | ||
) |
Function to start RX test.
Use this function to start RX constant carrier.
channel | : RF channel to use. |
pwr | : Rf power. |
datarate | : Rf data rate. |
rx_carrier_address | : address to use. |
Definition at line 352 of file rf_test.c.
{ if (channel > RF_TEST_MAX_CHANNEL) { return(RF_TEST_RC_ERR_PARAM); } if (pwr > HAL_NRF_0DBM){ return(RF_TEST_RC_ERR_PARAM); } if (datarate > HAL_NRF_250KBPS) { return(RF_TEST_RC_ERR_PARAM); } if (NULL == rx_carrier_address) { return(RF_TEST_RC_ERR_PARAM); } CE_LOW(); hal_nrf_set_output_power(pwr); hal_nrf_set_datarate(datarate); hal_nrf_set_address_width(HAL_NRF_AW_5BYTES); hal_nrf_flush_rx(); hal_nrf_set_operation_mode(HAL_NRF_PRX); hal_nrf_close_pipe(HAL_NRF_ALL); // first close all radio pipes... hal_nrf_open_pipe(HAL_NRF_PIPE0, false); // Turn off all auto acknowledge functionality hal_nrf_set_auto_retr(0,0); hal_nrf_set_rf_channel(channel); hal_nrf_set_pll_mode(false); hal_nrf_set_crc_mode(HAL_NRF_CRC_OFF); hal_nrf_set_address(HAL_NRF_PIPE0, rx_carrier_address); hal_nrf_set_rx_payload_width(HAL_NRF_PIPE0, DEFAULT_SIZE_PACKET); // pipe0 expect 32 byte payload CE_HIGH(); return(RF_TEST_RC_OK); }