I am noticing that particularly with the transmission of bytes over UART while scheduler is running, either some bytes go missing or the entire set of bytes aren't sent or received. (I'm seeing the UART stuff in the serial port). Though, I can send bytes from the serial port just fine: the ISR is triggered as soon as I type in something for each byte
So for according to the code snippet, I am printing Hello at the start of the app and often times I see Ello being printed and sometimes none of it
I'm wondering if there's a race condition somewhere and any assistance shall be greatly appreciated.
void Uart::TxByte(uint8_t byte)
{
setNrfEvent(NRF_UART_EVENT_TXDRDY, 0);
pUARTx->TXD = byte; // triggers the IRQ handler by writing the first byte
}
void Uart::StartTx(uint8_t *buffer, size_t bytesToSend, bool blockingTx)
{
setNrfEvent(NRF_UART_TASK_STARTTX, 1);
fifoTx.enqueElems(buffer, bytesToSend);
uint8_t val = fifoTx.deque();
TxByte(val);
}
void Uart::PrintToTerminal(const char *format, ...)
{
char buffer[100] = {0};
va_list args;
va_start (args, format);
vsnprintf (buffer, sizeof(buffer), format, args);
strcat(buffer, "\r\n");
size_t bytesToSend = strlen(buffer);
StartTx((uint8_t*) buffer, bytesToSend);
va_end (args);
}
void UARTE0_UART0_IRQHandler(void)
{
bool isTxdRdyIrqSet = getIrqRegStatus(NRF_UART_INT_MASK_TXDRDY);
bool isTxdRdyEvntSet = getNrfEventStatus(NRF_UART_EVENT_TXDRDY);
if (isTxdRdyIrqSet && isTxdRdyEvntSet)
{
setNrfEvent(NRF_UART_EVENT_TXDRDY, 0); // clear the TXDRDY bit
// continue to send bytes till the FIFO is empty
if (!fifoTx.isEmpty())
{
uint8_t byte = fifoTx.deque();
TxByte(byte);
}
else
{
// transmission ended
setNrfEvent(NRF_UART_TASK_STOPTX, 1);
}
}
}
bool Uart::getNrfEventStatus(nrf_uart_event_t reg) const
{
return (bool) *(volatile uint32_t *)((uint8_t *)pUARTx + (uint32_t)reg);
}
bool Uart::getIrqRegStatus(uint32_t mask)
{
return (bool) (pUARTx->INTENSET & mask);
}
int main()
{
uart.PrintToTerminal("Hello");
// ...
vTaskStartScheduler();
}