We are trying to receive high speed data using UART. Currently our source is set to transmit an 8 byte packet once every second.
I have initialised the serial port in IRQ mode and my baudrate is set to 921600. I have also set a GPIO pin to go high upon receiving an interrupt.
Am I correct in assuming that I should see an interrupt for every byte received? If so, why am I seeing my interrupts so delayed? What is the maximum frequency for interrupts?
The logic analyser is capturing the incoming data on the RX line, and also the GPIO pin that is set on every "NRF_SERIAL_EVENT_RX_DATA" interrupt.
My code is as follows:
#include <stdint.h> #include <stdbool.h> #include <stddef.h> #include "nrf.h" #include "nrf_drv_clock.h" #include "nrf_gpio.h" #include "nrf_delay.h" #include "nrf_log.h" #include "nrf_log_ctrl.h" #include "nrf_drv_power.h" #include "nrf_serial.h" #include "app_timer.h" #include "app_error.h" #include "app_util.h" #include "boards.h" //Logging #include "nrf_log.h" #include "nrf_log_ctrl.h" #include "nrf_log_default_backends.h" /** @file * @defgroup nrf_serial_example main.c * @{ * @ingroup nrf_serial_example * @brief Example of @ref nrf_serial usage. Simple loopback. * */ #define OP_QUEUES_SIZE 3 #define APP_TIMER_PRESCALER NRF_SERIAL_APP_TIMER_PRESCALER //Buttons static uint32_t button_state_1; static uint32_t button_state_2; //Payloads #define payload_size 8 uint8_t tx_payload0[5] = {1,2,3,4,5};//{50,100,150,200,250}; uint8_t tx_payload[payload_size]; uint8_t rx_payload[8]; //RTC #include "nrf_drv_rtc.h" const nrf_drv_rtc_t rtc = NRF_DRV_RTC_INSTANCE(0); /**< Declaring an instance of nrf_drv_rtc for RTC0. */ uint32_t timer_old; uint32_t timer_new; uint32_t delta; //Custom TX & RX pins #define ctx_pin_number 3 #define crx_pin_number 4 char c; static void sleep_handler(void) { __WFE(); __SEV(); __WFE(); } NRF_SERIAL_DRV_UART_CONFIG_DEF(m_uart0_drv_config, crx_pin_number, ctx_pin_number, RTS_PIN_NUMBER, CTS_PIN_NUMBER, NRF_UART_HWFC_DISABLED, NRF_UART_PARITY_EXCLUDED, NRF_UART_BAUDRATE_921600, UART_DEFAULT_CONFIG_IRQ_PRIORITY); /* NRF_SERIAL_DRV_UART_CONFIG_DEF(m_uart0_drv_config, RX_PIN_NUMBER, TX_PIN_NUMBER, RTS_PIN_NUMBER, CTS_PIN_NUMBER, NRF_UART_HWFC_DISABLED, NRF_UART_PARITY_EXCLUDED, NRF_UART_BAUDRATE_921600, UART_DEFAULT_CONFIG_IRQ_PRIORITY); */ #define SERIAL_FIFO_TX_SIZE 32 #define SERIAL_FIFO_RX_SIZE 32 NRF_SERIAL_QUEUES_DEF(serial_queues, SERIAL_FIFO_TX_SIZE, SERIAL_FIFO_RX_SIZE); #define SERIAL_BUFF_TX_SIZE 1 #define SERIAL_BUFF_RX_SIZE 1 NRF_SERIAL_BUFFERS_DEF(serial_buffs, SERIAL_BUFF_TX_SIZE, SERIAL_BUFF_RX_SIZE); NRF_SERIAL_UART_DEF(serial_uart, 0); void clocks_start( void ) { // Start HFCLK and wait for it to start. NRF_CLOCK->EVENTS_HFCLKSTARTED = 0; NRF_CLOCK->TASKS_HFCLKSTART = 1; while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0); } static void lfclk_config(void) { ret_code_t err_code = nrf_drv_clock_init(); APP_ERROR_CHECK(err_code); nrf_drv_clock_lfclk_request(NULL); } static void rtc_handler(nrf_drv_rtc_int_type_t int_type) { //Do nothing. Interrupts are disabled anyway. } static void rtc_config(void) { uint32_t err_code; //Initialize RTC instance nrf_drv_rtc_config_t config = NRF_DRV_RTC_DEFAULT_CONFIG; //config.prescaler = 4095; err_code = nrf_drv_rtc_init(&rtc, &config, rtc_handler); APP_ERROR_CHECK(err_code); //Power on RTC instance nrf_drv_rtc_enable(&rtc); //nrf_drv_rtc_int_disable(&rtc,); } static void serial_event_handler(struct nrf_serial_s const * p_serial, nrf_serial_event_t event) { switch (event) { case NRF_SERIAL_EVENT_TX_DONE: break; case NRF_SERIAL_EVENT_RX_DATA: nrf_gpio_pin_set(LED_2); //nrf_serial_read(&serial_uart, &rx_payload, sizeof(rx_payload), NULL, 0); nrf_queue_read(p_serial->p_ctx->p_config->p_queues->p_rxq, &c, sizeof(c)); nrf_gpio_pin_clear(LED_2); //NRF_LOG_DEBUG("%s", rx_payload); break; case NRF_SERIAL_EVENT_DRV_ERR: break; case NRF_SERIAL_EVENT_FIFO_ERR: break; default: break; } } NRF_SERIAL_CONFIG_DEF(serial_config, NRF_SERIAL_MODE_IRQ, &serial_queues, &serial_buffs,serial_event_handler, NULL); uint32_t logging_init( void ) { uint32_t err_code; err_code = NRF_LOG_INIT(NULL); NRF_LOG_DEFAULT_BACKENDS_INIT(); return err_code; } void gpio_init( void ) { nrf_gpio_cfg_output(LED_1); nrf_gpio_cfg_output(LED_2); // Workaround for PAN_028 rev1.1 anomaly 22 - System: Issues with disable System OFF mechanism nrf_delay_ms(1); bsp_board_init(BSP_INIT_LEDS); } int main(void) { ret_code_t ret; ret = nrf_drv_clock_init(); APP_ERROR_CHECK(ret); ret = nrf_drv_power_init(NULL); APP_ERROR_CHECK(ret); nrf_drv_clock_lfclk_request(NULL); ret = app_timer_init(); APP_ERROR_CHECK(ret); //CLOCKS clocks_start(); //timer rtc_config(); //lfclk_config(); gpio_init(); ret = nrf_serial_init(&serial_uart, &m_uart0_drv_config, &serial_config); APP_ERROR_CHECK(ret); //Init Logging logging_init(); static char tx_message[] = "Hello nrf_serial!\n\r"; NRF_LOG_DEBUG("MM Serial initialised"); /*ret = nrf_serial_write(&serial_uart, tx_message, strlen(tx_message), NULL, NRF_SERIAL_MAX_TIMEOUT); APP_ERROR_CHECK(ret); uint32_t timer;*/ while (true) { NRF_LOG_PROCESS(); } } /** @} */
Thanks for you help!