Hi Everyone
We are using nrfx_uarte library to implement the uart functionality , Everything seems to work fine with the uart , but the problem comes when we want to have a timeout in the read function.
To implement the timer we are using TIMER 2 instance , but whenever the timer gets triggered at some point of non availabilty of data , the UART reception gets blocked or gives garbage characters sometimes.
Here is the code that i am using , any help/suggestion would be appreciated
#include "nrf_serial.h"
#include "uart_lte.h"
#include "nrf_drv_timer.h"
#include "nrf_delay.h"
//Boolean flag to be set in interrupt handler;
static volatile bool uart_xfer_done=false;
static volatile bool timeout;
//Uart instance to be used.
static const nrfx_uarte_t uart1 =
NRFX_UARTE_INSTANCE (1);
const nrfx_timer_t TIMER_LED = NRFX_TIMER_INSTANCE(2);
//uart event handler decalartion
static void uarte_event_handler(nrfx_uarte_event_t const * p_event,void * p_context);
void timer_led_event_handler(nrf_timer_event_t event_type, void* p_context)
{
SEGGER_RTT_printf(0,"*");
timeout = true;
//one-shot
// stop_timer();
}
void init_timer()
{
uint32_t time_ms = 8000; //Time(in miliseconds) between consecutive compare events.
uint32_t err_code = NRF_SUCCESS;
nrfx_timer_config_t timer_cfg = NRFX_TIMER_DEFAULT_CONFIG;
timer_cfg.bit_width = NRF_TIMER_BIT_WIDTH_32;
uninit_timer();
err_code = nrfx_timer_init(&TIMER_LED, &timer_cfg, timer_led_event_handler);
APP_ERROR_CHECK(err_code);
nrfx_timer_extended_compare(&TIMER_LED,
NRF_TIMER_CC_CHANNEL2,
nrfx_timer_ms_to_ticks(&TIMER_LED, time_ms),
NRF_TIMER_SHORT_COMPARE2_CLEAR_MASK | NRF_TIMER_SHORT_COMPARE2_STOP_MASK , true
);
nrfx_timer_enable(&TIMER_LED);
stop_timer();
}
void uninit_timer()
{
nrfx_timer_uninit(&TIMER_LED);
}
void start_timer()
{
nrfx_timer_clear(&TIMER_LED);
nrfx_timer_resume(&TIMER_LED);
}
void stop_timer()
{
nrfx_timer_pause(&TIMER_LED);
}
/*
* This function uses UARTE1 peripheral instance for communication
* @param rx_pin to be used
* @param tx_pin to be used
* @return None
*/
void uarte_init(uint32_t rx_pin,uint32_t tx_pin,uint32_t baud_rate)
{
nrfx_uarte_config_t nrf_uart1;
nrf_uart1.pselrxd = rx_pin ;
nrf_uart1.pseltxd = tx_pin;
nrf_uart1.pselcts = NRF_UARTE_PSEL_DISCONNECTED;
nrf_uart1.pselrts = NRF_UARTE_PSEL_DISCONNECTED;
nrf_uart1.hwfc = NRF_UARTE_HWFC_DISABLED;
nrf_uart1.parity = NRF_UARTE_PARITY_EXCLUDED;
nrf_uart1.interrupt_priority =6;
nrf_uart1.p_context = NULL;
switch(baud_rate)
{
case baud_rate_lte_1200:
nrf_uart1.baudrate = NRF_UARTE_BAUDRATE_1200;
break;
case baud_rate_lte_2400:
nrf_uart1.baudrate = NRF_UARTE_BAUDRATE_2400;
break;
case baud_rate_lte_4800:
nrf_uart1.baudrate = NRF_UARTE_BAUDRATE_4800;
break;
case baud_rate_lte_9600:
nrf_uart1.baudrate = NRF_UARTE_BAUDRATE_9600;
break;
case baud_rate_lte_14400:
nrf_uart1.baudrate = NRF_UARTE_BAUDRATE_14400;
break;
case baud_rate_lte_19200:
nrf_uart1.baudrate = NRF_UARTE_BAUDRATE_19200;
break;
case baud_rate_lte_28800:
nrf_uart1.baudrate = NRF_UARTE_BAUDRATE_28800;
break;
case baud_rate_lte_31250:
nrf_uart1.baudrate = NRF_UARTE_BAUDRATE_31250;
break;
case baud_rate_lte_38400:
nrf_uart1.baudrate = NRF_UARTE_BAUDRATE_38400;
break;
case baud_rate_lte_56000:
nrf_uart1.baudrate = NRF_UARTE_BAUDRATE_56000;
break;
case baud_rate_lte_57600:
nrf_uart1.baudrate = NRF_UARTE_BAUDRATE_57600;
break;
case baud_rate_lte_76800:
nrf_uart1.baudrate = NRF_UARTE_BAUDRATE_76800;
break;
case baud_rate_lte_115200:
nrf_uart1.baudrate = NRF_UARTE_BAUDRATE_115200;
break;
case baud_rate_lte_921600:
nrf_uart1.baudrate = NRF_UARTE_BAUDRATE_921600;
break;
default:
break;
}
nrfx_uarte_init(&uart1,&nrf_uart1,uarte_event_handler);
init_timer();
}
/*
* This function uninitalize the UARTE1
* @param None
* @param None
* @return None
*/
void uarte_uninit()
{
uninit_timer();
nrfx_uarte_uninit(&uart1);
}
uarte_retcode_t write_byte_uarte (uint8_t data)
{
nrfx_uarte_tx(&uart1,&data,1);
return wait_for_execution();
}
uarte_retcode_t write_bytes_uarte (char* data, size_t length)
{
nrfx_uarte_tx(&uart1,data,length);
return wait_for_execution();
}
uarte_retcode_t read_byte_uarte (char* buffer)
{
nrfx_uarte_rx(&uart1,buffer,1);
return wait_for_execution();
}
uarte_retcode_t read_bytes_uarte (char* buffer, size_t length)
{
nrfx_uarte_rx(&uart1,buffer,length);
return wait_for_execution();
}
uarte_retcode_t wait_for_execution()
{
start_timer();
while(true)
{
if(uart_xfer_done)
{
uart_xfer_done=false;
return UARTE_OK;
}
else if(timeout)
{
timeout = false;
return UARTE_TIMEOUT;
}
}
}
/**
* @brief UART1 Event handler
* @param event
*/
void uarte_event_handler(nrfx_uarte_event_t const * p_event,void * p_context)
{
switch(p_event->type)
{
case NRFX_UARTE_EVT_TX_DONE:
uart_xfer_done = true;
break;
case NRFX_UARTE_EVT_RX_DONE:
uart_xfer_done = true;
//SEGGER_RTT_printf(0,"RX LTE\r\n");
break;
case NRFX_UARTE_EVT_ERROR:
break;
default:
break;
}
}
bool data_available_uarte(void)
{
return nrfx_uarte_rx_ready(&uart1);
}