This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

nrf_libuarte_async TX issue

Basically, I cannot do continuous TX with nrf_libuarte_async:
Here is simple reproduce:
    static uint8_t text[] = "===TICK===\r\n";
    static uint8_t text_size = sizeof(text);
    static uint8_t text2[] = "+++TOCK+++\r\n";
    static uint8_t text2_size = sizeof(text2);
    while (true)
    {
        err_code = nrf_libuarte_async_tx(&libuarte, text, text_size);
        for (size_t i = 0; i < 1000000; i++)
        {
        }
        err_code = nrf_libuarte_async_tx(&libuarte, text2, text2_size);
        for (size_t i = 0; i < 10000000; i++)
        {
        }
    }
It only output ===TICK=== and no +++TOCK+++
Here is what I've tried:
1. I can confirm that NRF_LIBUARTE_ASYNC_EVT_TX_DONE event has been triggered during the for loop in between
2. If I increase the delay by for loop, both data got through
3. both calls returns 0x00 (SUCCESS)
4. If I put a breakpoint in between, of the NRF_LIBUARTE_ASYNC_EVT_TX_DONE  event, it works
5. I've tried in another project with RTOS and use osDelay to test the gap needed for second transmission, it seems ~300 ms is needed.
help please....
Parents
  • [Update]

    It's not libuarte related, it seems like an EasyDMA issue.

    I got another repro without using libuarte, the second message is not showing.

    volatile static bool _gotTxDone = false;
    void UARTE0_UART0_IRQHandler(void)
    {
        if (nrf_uarte_event_check(NRF_UARTE0, NRF_UARTE_EVENT_ENDTX)) {
    			nrf_uarte_event_clear(NRF_UARTE0, NRF_UARTE_EVENT_ENDTX);
    			_gotTxDone = true;
        }
    
        return;
    }
    
    // ... main...
      uint8_t text[] = "===TICK===\r\n";
      uint8_t text_size = sizeof(text);
      uint8_t text2[] = "+++TOC+++\r\n";
      uint8_t text2_size = sizeof(text2);
    
      while (true) {
    		NRF_LOG_INFO("=========");
    		NRF_LOG_FLUSH();
    
    		_gotTxDone = false;
        NRF_UARTE0->TXD.PTR = (uint32_t)text;
        NRF_UARTE0->TXD.MAXCNT = (uint32_t)text_size;
        NRF_UARTE0->TASKS_STARTTX = 1;
        while (!_gotTxDone) {; }
    
    		for (size_t i = 0; i < 100000; i++) { }
    		
    		_gotTxDone = false;
        NRF_UARTE0->TXD.PTR = (uint32_t)text2;
        NRF_UARTE0->TXD.MAXCNT = (uint32_t)text2_size;
        NRF_UARTE0->TASKS_STARTTX = 1;
        
        
        while (!_gotTxDone) {; }
        NRF_LOG_FLUSH();
    		for (size_t i = 0; i < 10000000; i++) { }
      }
    

Reply
  • [Update]

    It's not libuarte related, it seems like an EasyDMA issue.

    I got another repro without using libuarte, the second message is not showing.

    volatile static bool _gotTxDone = false;
    void UARTE0_UART0_IRQHandler(void)
    {
        if (nrf_uarte_event_check(NRF_UARTE0, NRF_UARTE_EVENT_ENDTX)) {
    			nrf_uarte_event_clear(NRF_UARTE0, NRF_UARTE_EVENT_ENDTX);
    			_gotTxDone = true;
        }
    
        return;
    }
    
    // ... main...
      uint8_t text[] = "===TICK===\r\n";
      uint8_t text_size = sizeof(text);
      uint8_t text2[] = "+++TOC+++\r\n";
      uint8_t text2_size = sizeof(text2);
    
      while (true) {
    		NRF_LOG_INFO("=========");
    		NRF_LOG_FLUSH();
    
    		_gotTxDone = false;
        NRF_UARTE0->TXD.PTR = (uint32_t)text;
        NRF_UARTE0->TXD.MAXCNT = (uint32_t)text_size;
        NRF_UARTE0->TASKS_STARTTX = 1;
        while (!_gotTxDone) {; }
    
    		for (size_t i = 0; i < 100000; i++) { }
    		
    		_gotTxDone = false;
        NRF_UARTE0->TXD.PTR = (uint32_t)text2;
        NRF_UARTE0->TXD.MAXCNT = (uint32_t)text2_size;
        NRF_UARTE0->TASKS_STARTTX = 1;
        
        
        while (!_gotTxDone) {; }
        NRF_LOG_FLUSH();
    		for (size_t i = 0; i < 10000000; i++) { }
      }
    

Children
No Data
Related