Hi Richard,
sure I did what you suggested.
In fact, I see m
uarttask is not NULL breaking at configASSERT in the callback function and no interrupt execution prior to send any char to uart. Please see detailed information below.
The code behaves as following steps:
0- clock and gpio initialization;
1- UART Task is created successfuly;
2- Scheduler is started successfuly;
3- UART task is executed, calling hook function and Rx UARTE initialized successfuly;
4- While not sending any char thru terminal to PC comm port, there is no trigger at IRQ handler in the debugger and callback function is not called/triggered. That is all right.
5- Now, I remove the breakpoint at IRQ Handler to avoid stop here when I send the first char in the terminal.
6- Now, I have only a break at configASSERT in ISR callback function and send only one char;
7- Break it, where m
uarttask contains the value (0x20007900), looking the memory dump in details:
m
uarttask is stored statically at address 0x2000A070 and contains 0x20007900 that points to address 0x20007874 that points to address 0x200078E4 that contains 0x00000000.
Is it clear ? Hope this can help to understand what is the fault.
As per your request, here goes code to:
UARTE initialization:
static void uarte0
init(void * pcontext)
{
uint32
t errcode;
const nrf
drvuart
configt uart
config =
{
.pseltxd = TXPIN
NUMBER, ///< TXD pin number.
.pselrxd = RXPIN
NUMBER, ///< RXD pin number.
.pselcts = CTSPIN
NUMBER, ///< CTS pin number.
.pselrts = RTSPIN
NUMBER, ///< RTS pin number.
.pcontext = p
context, ///< Context of UARTE instance passed to interrupt handler.
.hwfc = (nrfuart
hwfct) NRF
UARTEHWFC
DISABLED, ///< Flow control configuration.
.parity = (nrfuart
parityt) NRF
UARTEPARITY
EXCLUDED, ///< Parity configuration.
.baudrate = (nrfuart
baudratet) NRF
UARTEBAUDRATE
115200, ///< Baudrate.
.interruptpriority = UART
DEFAULTCONFIG
IRQPRIORITY, ///< Interrupt priority.
” #ifdef UARTE
PRESENT
.useeasy_dma = true,
” #endif
};
err_code = nrf_drv_uart_init(p_context,
&uart_config,
uarte_interrupt_handler); /* using callback for UARTE IRQ */
APP_ERROR_CHECK(err_code);
NRF_LOG_INFO("UARTE initialized");
}
Task creation:
/**@brief Function for creating a task to retrieve UART events.
* @param[in] hook
fn Function to run in the UART FreeRTOS task,
* before entering the task loop.
* @param[in] pcontext Parameter for the function @p hook.
*/
void nrf_uart_freertos_init(nrf_uart_freertos_task_hook_t hook_fn, void * p_context)
{
NRF_LOG_INFO(“Creating a UART task.”);
m_uart_hook = hook_fn;
BaseType_t xReturned = xTaskCreate(uart_task,
"UART",
NRF_BLE_FREERTOS_UART_TASK_STACK,
p_context,
NRF_BLE_FREERTOS_UART_TASK_PRIO,
&m_uart_task);
if (xReturned != pdPASS)
{
NRF_LOG_ERROR("UART task not created.");
APP_ERROR_HANDLER(NRF_ERROR_NO_MEM);
}
}
functions calling ISR callback:
__STATIC
INLINE void rxdone
event(uartcontrol
blockt * p
uartcb, uint8
t bytes, uint8t * p
data)
{
nrfdrv
uartevent_t event;
event.type = NRF_DRV_UART_EVT_RX_DONE;
event.data.rxtx.bytes = bytes;
event.data.rxtx.p_data = p_data;
/* is non-blocking mode, callback function */
configASSERT(p_uart_cb->handler != NULL)
p_uart_cb->handler(&event, p_uart_cb->p_context); /* ISR callback function is called here */
}
__STATIC
INLINE void txdone
event(uartcontrol
blockt * p
uartcb, uint8
t bytes)
{
nrfdrv
uartevent_t event;
event.type = NRF_DRV_UART_EVT_TX_DONE;
event.data.rxtx.bytes = bytes;
event.data.rxtx.p_data = (uint8_t *)p_uart_cb->p_tx_buffer;
p_uart_cb->tx_buffer_length = 0;
NRF_LOG_INFO("TX done len:%d", bytes);
/* non-blocking mode, callback function */
configASSERT(p_uart_cb->handler != NULL)
p_uart_cb->handler(&event, p_uart_cb->p_context); /* ISR callback function is called here */
}
IRQ Handler:
__STATIC
INLINE void uarteirq
handler(NRFUARTE
Type * puarte, uart
controlblock
t * puart
cb)
{
/* Tracealyzer defitions for tracing ISRs */
traceHandle UARTEIRQ
Handle = xTraceSetISRProperties(“IRQUARTE”, UART
DEFAULTCONFIG
IRQPRIORITY);
vTraceStoreISRBegin(UARTE_IRQ_Handle); /* Tracelyzer ISR tracing */
BaseType_t yield_req = pdFALSE;
/* End of transmition */
if (nrf_uarte_event_check(p_uarte, NRF_UARTE_EVENT_ENDTX))
{
nrf_uarte_event_clear(p_uarte, NRF_UARTE_EVENT_ENDTX);
if (p_uart_cb->tx_buffer_length)
{
tx_done_event(p_uart_cb, nrf_uarte_tx_amount_get(p_uarte));
}
}
/* End of reception ? */
else if (nrf_uarte_event_check(p_uarte, NRF_UARTE_EVENT_ENDRX))
{
nrf_uarte_event_clear(p_uarte, NRF_UARTE_EVENT_ENDRX);
uint8_t amount = nrf_uarte_rx_amount_get(p_uarte);
// If the transfer was stopped before completion, amount of transfered bytes
// will not be equal to the buffer length. Interrupted transfer is ignored.
if (amount == p_uart_cb->rx_buffer_length)
{
if (p_uart_cb->rx_secondary_buffer_length)
{
nrf_uarte_shorts_disable(p_uarte, NRF_UARTE_SHORT_ENDRX_STARTRX);
p_uart_cb->rx_buffer_length = p_uart_cb->rx_secondary_buffer_length;
p_uart_cb->p_rx_buffer = p_uart_cb->p_rx_secondary_buffer;
p_uart_cb->rx_secondary_buffer_length = 0;
rx_done_event(p_uart_cb, amount, p_uart_cb->p_rx_buffer);
}
else
{ /* reset rx buffer length due to trunked transfer */
p_uart_cb->rx_buffer_length = 0;
rx_done_event(p_uart_cb, amount, p_uart_cb->p_rx_buffer);
}
}
/* verify error event has occurred in the reception */
if (nrf_uarte_event_check(p_uarte, NRF_UARTE_EVENT_ERROR))
{
nrf_drv_uart_event_t event;
nrf_uarte_event_clear(p_uarte, NRF_UARTE_EVENT_ERROR);
event.type = NRF_DRV_UART_EVT_ERROR;
event.data.error.error_mask = nrf_uarte_errorsrc_get_and_clear(p_uarte);
event.data.error.rxtx.bytes = nrf_uarte_rx_amount_get(p_uarte);
event.data.error.rxtx.p_data = p_uart_cb->p_rx_buffer;
//abort transfer
p_uart_cb->rx_buffer_length = 0;
p_uart_cb->rx_secondary_buffer_length = 0;
/* non-blocking mode, callback function */
configASSERT(p_uart_cb->handler != NULL)
p_uart_cb->handler(&event, p_uart_cb->p_context);
}
/* Timeout event has occurred in the reception? */
else if (nrf_uarte_event_check(p_uarte, NRF_UARTE_EVENT_RXTO))
{
nrf_uarte_event_clear(p_uarte, NRF_UARTE_EVENT_RXTO);
if (p_uart_cb->rx_buffer_length)
{ /* reset rx buffer length */
p_uart_cb->rx_buffer_length = 0;
rx_done_event(p_uart_cb, nrf_uarte_rx_amount_get(p_uarte), p_uart_cb->p_rx_buffer);
}
}
} // end-of-reception
/* Switch the task if required. */
portYIELD_FROM_ISR(yield_req);
vTraceStoreISREnd(yield_req); /* Stops ISR tracing */
}
Thanks for your attention to this issue.
Have a nice day.