Dear Nordic fellow,
I'm in the process of testing the Bluetooth radio chip of the Nordic nrf52832 sold by Rigado.
As I've read here, I can use the radio_test example. The product I have uses the serial to communicate with another device, so I adapted the function calls to the radio_test.c as saw in the example Nordic provided.
The key differences are:
- I have the internal clock only (No external oscillator), so in the sdk_config.h I have set
- NRFX_CLOCK_CONFIG_LF_SRC 0
- CLOCK_CONFIG_LF_SRC 0
- I see the log via the Segger RTT, and the output is telling me that the radio is transmitting/receiving when I set so.
- I have a serial packet, that will tell me which test to perform
I'll share the main.c I'm using, so that it will be easier for everyone to see
#include "radio_test.h" #include "sdk_config.h" #include "nrfx_config.h" #include "nrf_log.h" #include "nrf_log_ctrl.h" #include "nrf_log_default_backends.h" #include "nrf_gpio.h" #include "nrfx_uarte.h" //#include "app_timer.h" #include "nrf.h" /* * Payload of the message coming via UART. I'll choose the test to do */ #define RX_FIRST_CH 0 // G1 = 0, G2 = 0 #define RX_LAST_CH 1 // G1 = 0, G2 = 1 #define TX_FIRST_CH 2 // G1 = 1, G2 = 0 #define TX_LAST_CH 3 // G1 = 1, G2 = 1 #define PIN_NOT_CONNECTED 0xFFFFFFFF #define TX_PIN_NUMBER 6 /**< UART TX pin. P0.06 = pin 8. Use xx (in the P0.xx) to make it work */ #define RX_PIN_NUMBER 8 /**< UART RX pin. P0.08 = pin 10 Use xx (in the P0.xx) to make it work*/ #define FIRST_CH 2 /** Channel 37 is frequency 2402, and according to nordic 2400MHz+ chNum. It's the lowest freq */ #define LAST_CH 80 /** Channel 39 is frequency 2480, and according to nordic 2400MHz+ chNum. It's the highest freq */ /** * function definition * */ static void timer_tick(void* p_ctxt); static void set_test_next(uint8_t p_test); static void init_uart(void); static void reset_uart(void); static void start_rx(uint8_t len); static void process_uart(void); /** * * VARIABLES * */ uint8_t test_prev = 5; uint8_t test_next = 5; bool lock_test_next; uint8_t rx_serial[20] = {}; uint8_t rx_serial_idx = 0; uint8_t rx_tmp[20] = {}; uint8_t rx_tmp_idx = 0; static nrfx_uarte_t m_uart_instance; /** * * FUNCTIONS TO SET VARIABLES * */ void set_test_next(uint8_t next) { lock_test_next = true; test_next = next & 0x3; lock_test_next = false; } static void init_log() { ret_code_t err_code = NRF_LOG_INIT(NULL); APP_ERROR_CHECK(err_code); NRF_LOG_DEFAULT_BACKENDS_INIT(); } static void init() { init_uart(); //bottom of file, where all uart area is init_log(); //just above } /* * * RUNTIME * */ static void do_test_tx_first() { radio_modulated_tx_carrier(RADIO_TXPOWER_TXPOWER_0dBm, RADIO_MODE_MODE_Ble_1Mbit, FIRST_CH); } static void do_test_tx_last() { radio_modulated_tx_carrier(RADIO_TXPOWER_TXPOWER_0dBm, RADIO_MODE_MODE_Ble_1Mbit, LAST_CH); } static void do_test_rx_first() { radio_rx(RADIO_MODE_MODE_Ble_1Mbit, LAST_CH); } static void do_test_rx_last() { radio_rx(RADIO_MODE_MODE_Ble_1Mbit, LAST_CH); } /** * * */ int main(void) { NRF_RNG->TASKS_START = 1; // initialize the environment vars init(); //Check periodically if the test changed. NVIC_DisableIRQ(SysTick_IRQn); SysTick_Config(64000*100); // every 100ms NVIC_SetPriority(SysTick_IRQn,3); NRF_LOG_INFO("Set systick"); NRF_LOG_PROCESS(); NVIC_EnableIRQ(SysTick_IRQn); __enable_irq(); NRF_LOG_INFO("Started radio test"); NRF_LOG_PROCESS(); while(1) { NRF_LOG_PROCESS(); } } /** * * ******** SysTick callback to check if the test is changed *********** * */ //void timer_tick(void* p_ctxt) void SysTick_Handler() { process_uart(); //NRF_LOG_INFO("."); NRF_LOG_INFO("R:%d",NRF_RADIO->STATE); if(lock_test_next){ return;} if(test_next != test_prev) { NRF_LOG_INFO("Switched test from %d to %d", test_prev, test_next); test_prev = test_next; radio_disable(); switch(test_next) { case(TX_FIRST_CH): { do_test_tx_first(); break; } case(TX_LAST_CH): { do_test_tx_last(); break; } case(RX_FIRST_CH): { do_test_rx_first(); break; } case(RX_LAST_CH): { do_test_rx_last(); break; } } } } /**** ********* ***** **** UART AREA *********** ********** ********** **** */ static void start_rx(uint8_t len) { /** Interrupt model */ //disable interrupts for now m_uart_instance.p_reg->INTENCLR = NRF_UARTE_INT_ERROR_MASK | NRF_UARTE_INT_ENDRX_MASK; m_uart_instance.p_reg->RXD.MAXCNT = len; m_uart_instance.p_reg->RXD.PTR = (volatile uint32_t) rx_tmp; m_uart_instance.p_reg->SHORTS = (1 << 5); // endrx-startrx m_uart_instance.p_reg->ENABLE = 0x08; // enable m_uart_instance.p_reg->EVENTS_RXSTARTED = 0; m_uart_instance.p_reg->TASKS_STARTRX = 1; m_uart_instance.p_reg->INTENSET = NRF_UARTE_INT_ERROR_MASK | NRF_UARTE_INT_ENDRX_MASK; rx_tmp_idx=0; } static void reset_uart() { rx_tmp_idx=0; rx_tmp[0]=0; start_rx(1); } /** * * UART INITIALIZATION * */ static void init_uart() { nrfx_uarte_config_t uart_conf; memset(&uart_conf,0,sizeof(uart_conf)); uart_conf.baudrate = NRF_UARTE_BAUDRATE_115200;//p_init->serial.baud; uart_conf.hwfc = NRF_UARTE_HWFC_DISABLED;//p_init->serial.hwfc; uart_conf.interrupt_priority = APP_TIMER_CONFIG_IRQ_PRIORITY; // 7 uart_conf.p_context = 0 ; //initialized by the nrfx init function uart_conf.parity = NRF_UARTE_PARITY_EXCLUDED;//p_init->serial.parity; uart_conf.pselcts = NRF_UARTE_PSEL_DISCONNECTED; //NOT_CONNECTED uart_conf.pselrts = NRF_UARTE_PSEL_DISCONNECTED; uart_conf.pselrxd = RX_PIN_NUMBER; //8 uart_conf.pseltxd = TX_PIN_NUMBER; //6 // create uart instance m_uart_instance = (nrfx_uarte_t)NRFX_UARTE_INSTANCE(0); //initialize UARTE0. the cast is safe to do /** APPLY CONFIG*/ //set tx pin as output pin nrf_gpio_pin_set(TX_PIN_NUMBER); nrf_gpio_cfg_output(TX_PIN_NUMBER); nrf_gpio_cfg_input(RX_PIN_NUMBER, NRF_GPIO_PIN_NOPULL); m_uart_instance.p_reg->BAUDRATE = NRF_UARTE_BAUDRATE_115200; m_uart_instance.p_reg->PSEL.CTS = NRF_UARTE_PSEL_DISCONNECTED; m_uart_instance.p_reg->PSEL.RTS = NRF_UARTE_PSEL_DISCONNECTED; m_uart_instance.p_reg->CONFIG = (uint32_t)NRF_UARTE_PARITY_EXCLUDED | (uint32_t)NRF_UARTE_HWFC_DISABLED; m_uart_instance.p_reg->PSEL.RXD = RX_PIN_NUMBER; m_uart_instance.p_reg->PSEL.TXD = TX_PIN_NUMBER; /** END APPLY CONFIG*/ /** INTERRUPT ENABLE */ m_uart_instance.p_reg->EVENTS_ENDRX = 0; m_uart_instance.p_reg->EVENTS_ENDTX = 0; m_uart_instance.p_reg->EVENTS_ERROR = 0; m_uart_instance.p_reg->EVENTS_RXTO = 0; m_uart_instance.p_reg->EVENTS_RXSTARTED = 0; m_uart_instance.p_reg->SHORTS = (1<<5);//NRF_UARTE_SHORT_ENDRX_STARTRX; m_uart_instance.p_reg->TASKS_STARTRX = 1; //enable receiver m_uart_instance.p_reg->INTENSET = (NRF_UARTE_INT_ENDRX_MASK |NRF_UARTE_INT_ENDTX_MASK | NRF_UARTE_INT_RXDRDY_MASK| NRF_UARTE_INT_RXSTARTED_MASK | NRF_UARTE_INT_ERROR_MASK | NRF_UARTE_INT_RXTO_MASK); // NVIC_SetPriority(UARTE0_UART0_IRQn,7); NVIC_EnableIRQ(UARTE0_UART0_IRQn); m_uart_instance.p_reg->ENABLE = UARTE_ENABLE_ENABLE_Enabled; // ENABLE UARTE //END of INIT reset_uart(); } static void process_uart(void){ //command is generic error. Check that what I received is a generic error // packet is as follows. Put the <code> in the test_next variable // {0xC4, 0x05, <code>, <CRC1>, <CRC2>} uint8_t PKT_LEN = 5; if(rx_serial_idx>(PKT_LEN-1)) //I can update the log { if((rx_serial[0] == 0xC4) && (rx_serial[1] == PKT_LEN)) { set_test_next(rx_serial[2] & 0x3); //set the next test rx_serial_idx= 0; //set to 0 the index of the packet received. If I received another packet, simply discard it. //It will switch to the next test, during the following packet } else { // wrong packet. Just reset the index and discard the packet. NRF_LOG_WARNING("U:D %d b", rx_serial_idx); NRF_LOG_HEXDUMP_WARNING(rx_serial,rx_serial_idx); rx_serial_idx=0; } } } /** * UART interrupt handler * */ void UARTE0_UART0_IRQHandler(void) { if (m_uart_instance.p_reg->EVENTS_RXSTARTED) { m_uart_instance.p_reg->EVENTS_RXSTARTED = 0; // clear register } if(m_uart_instance.p_reg->EVENTS_RXDRDY) { m_uart_instance.p_reg->EVENTS_RXDRDY=0; //clear register uint32_t amount = m_uart_instance.p_reg->RXD.AMOUNT; } if(m_uart_instance.p_reg->EVENTS_ENDRX) { m_uart_instance.p_reg->EVENTS_ENDRX=0; //clear register uint8_t amount = m_uart_instance.p_reg->RXD.AMOUNT; memcpy(&(rx_serial[rx_serial_idx]),rx_tmp,amount); rx_serial_idx += amount; start_rx(1); } if(m_uart_instance.p_reg->EVENTS_ENDTX) { m_uart_instance.p_reg->EVENTS_ENDTX=0; //clear register - never happening } if(m_uart_instance.p_reg->EVENTS_ERROR) { // err_code = m_uart_instance.p_reg->ERRORSRC; // m_uart_instance.p_reg->ERRORSRC = err_code; m_uart_instance.p_reg->EVENTS_ERROR=0; //clear register uint32_t amount = m_uart_instance.p_reg->RXD.AMOUNT; NRF_LOG_WARNING("U:E"); //write uart error } }
During the radio test, the certification company, saw that both the tx test at 2402MHz and 2480MHz were transmitting at 2028MHz. The EMC testing, which used SoftDevice, went fine.
Do you have any insight on where I did the mistake?