This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

UART transmission seems to be working weirdly

I created a simple driver call for UART transmission and when I debug the program and put breakpoints at every transmission, it seems to work fine (I see the characters sent being printed to the serial console) but when I run the program without any breakpoints, all I see is "?" being printed to the console.

The receiver part works fine: as soon as I enter a character in serial, I see an IRQ handler getting fired where the value is read off RXD register.


 .

// main.cpp

Uart uart;  

int main()
{
    char s[] = "hello";

    uart.StartTx((uint8_t *) s, strlen(s));
}

// uart.cpp
bool Uart::getNrfEventStatus(nrf_uart_event_t reg) const
{
    return (bool) *(volatile uint32_t *)((uint8_t *)pUARTx + (uint32_t)reg);	
}
void Uart::TxByte(uint8_t byte)
{
        setNrfEvent(NRF_UART_EVENT_TXDRDY, 0);  
        pUARTx->TXD = byte;
}

void Uart::TxBlocking(uint8_t *buffer, size_t bytesToSend)
{
    for (uint8_t idx = 0; idx < bytesToSend; idx++)
    {   
        TxByte(buffer[idx]);    // NRF_UART_EVENT_TXDRDY is set right after writing to TXD
        bool volatile txdRdyEvnt = getNrfEventStatus(NRF_UART_EVENT_TXDRDY);    
while (txdRdyEvnt);     // wait till NRF_UART_EVENT_TXDRDY is reset in IRQ handler
    } 
}

 void Uart::StartTx(uint8_t *buffer, size_t bytesToSend) 
{ 
      setNrfEvent(NRF_UART_EVENT_TXDRDY, 0); 
      setNrfEvent(NRF_UART_TASK_STARTTX, 1);   // trigger NRF_UART_TASK_STARTTX
      TxBlocking(buffer, bytesToSend); 
      setNrfEvent(NRF_UART_TASK_STOPTX, 1); 
}

void Uart::setNrfEvent(T reg, uint32_t value) // TODO - change fctn name 
{ 
      *((volatile uint32_t *)((uint8_t *)pUARTx + (uint32_t)reg)) = value; 
       #if __CORTEX_M == 0x04 
       volatile uint32_t dummy = *( (volatile uint32_t *) ((uint8_t *)pUARTx + (uint32_t)reg) ); 
       (void)dummy; 
       #endif 
}


Thanks for the help

  • Well, the issue certainly was with the flags.


    - First issue: `while (txdRdyEvnt); `isn't taking into account the updated value.

    - Second: the following flow and disabling TxdRdy interrupt flag did the trick!

    void Uart::TxBlocking(uint8_t *buffer, size_t bytesToSend)
    {
        for (uint8_t idx = 0; idx < bytesToSend; idx++)
        {   
            setNrfEvent(NRF_UART_EVENT_TXDRDY, 0);
            TxByte(buffer[idx]);
            while (getNrfEventStatus(NRF_UART_EVENT_TXDRDY) == 0);
        }
    }
Related