Defines | Enumerations | Functions

RF tests
[Libraries (LIB)]


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 :

TX carrier wave output

To generate a constant TX carrier, either unmodulated or modulate with PN9, the following functions are available:

RX constant carrier (LO leakage)

To test the LO leakage you have:

TX/RX channel sweep

To do a channel sweep on the channel range use these funstions:

RX sentitivity

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.

Define Documentation

#define RF_TEST_MAX_CHANNEL   81

Upper radio channel.

Definition at line 149 of file rf_test.h.


Enumeration Type Documentation

Function return codes.

Enumerator:
RF_TEST_RC_OK 

No error.

RF_TEST_RC_FINISHED 

Current process is finished.

RF_TEST_RC_ERR_PARAM 

Erroneous parameter.

RF_TEST_RC_ERR_BUFFER_FULL 

The internal buffer is full.

RF_TEST_RC_ERR_NB_RX_BYTES 

The number of received bits in the last packet is different from what was expected.

Definition at line 152 of file rf_test.h.


Function Documentation

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

Parameters:
chRadio Channel
pwrradio power
datarateradio data rate
addressRX address (pointer to an array containing 5 bytes)
Returns:
RF_TEST_RC_OK if ok, error code otherwise.

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.

By default, the lib uses 32 as pascket size and the following data :
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.
Parameters:
data_sizeactual packet size
p_expected_datapointer 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.

Returns:
RF_TEST_RC_OK if ok, RF_TEST_RC_FINISHED if enough data has been received for the calulation, error code otherwise.

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.

Returns:
Calculated error rate if finished.
Return values:
0xFFFFif 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.

Parameters:
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).
Returns:
RF_TEST_RC_OK if ok, error code otherwise.

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.

Parameters:
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).
Returns:
RF_TEST_RC_OK if ok, error code otherwise.

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.

Parameters:
channel: RF channel to use.
pwr: Rf power.
datarate: Rf data rate.
Returns:
RF_TEST_RC_OK if ok, error code otherwise.

Definition at line 282 of file rf_test.c.

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.

Parameters:
channel: RF channel to use.
pwr: Rf power.
datarate: Rf data rate.
Returns:
RF_TEST_RC_OK if ok, error code otherwise.

Definition at line 337 of file rf_test.c.

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.

Parameters:
channel: RF channel to use.
pwr: Rf power.
datarate: Rf data rate.
rx_carrier_address: address to use.
Returns:
RF_TEST_RC_OK if ok, error code otherwise.

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);
}