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

UARTE: Why does the ENDRX value not change from zero once the MAXCNT number of bytes have been received?

Folks,

Been struggling for a couple of days with a comms issue that I assumed were at the other end of my system, but am starting to think it's at the nRF52 UART end and I do not understand how this thing works. I suspect I don't understand this bizarre UART correctly, so am hoping someone can tell me what I am am missing.

Normally with DMA (well on  other Cortex Mx devices) you'd set the target number of bytes to receive in one register, set it going and once the requisite number of bytes had been received you'd get a flag being set to tell you that reception was complete.

I have set up the UARTE reception to get X bytes of data by setting the RXD.MAXCNT register to be X.

Originally I started with three and then noticed the manual seemed to be saying it should be greater than four, so tried changing it to five (and senidng more bytes INTO the nRF), but it does not help at all.

If I poll the UART by doing this:

if (NRF_UARTE0->EVENTS_ENDRX != 0) 

{

// Stuff here

}

On the rare occasions it does enter the // Stuff here bit, the EVENTS_ENDRX is still 0 in the debugger! :-o

If I poll for activity simply on the EVENTS_RXDRDY I am 100% definitely getting all the data being sent into the nRF correctly. It is just the EVENTS_ENDRX just never gets set to anything other than zero.

What am I missing here? I am clearly totally misunderstanding something with this UART. Does the ENDRX not actually work? Is there a hardware bug with it? Or am I just expecting STM/Atmel/NXP type behaviour that doesn't happen with this device? Or am I just driving it incorrectly?

FWIW, my code for starting off a reception is:

void StartDMAReceiveFromExLRT(uint8_t *BufferStart)
{



    NRF_UARTE0->TASKS_STOPRX = 1; -<---- tried with or wothout this  
    NRF_UARTE0->RXD.MAXCNT = 5;
    NRF_UARTE0->RXD.PTR = (uint32_t)BufferStart;
    NRF_UARTE0->TASKS_STARTRX = 1;

}

As an aside, I actually just want to check for three bytes most of the time. Can I simply not do a DMA receive for only three bytes?

Many thanks.

Parents
  • Hi

    The RXD.AMOUNT will count the number of bytes received in the last transaction, so I believe this value will "reset" between each transaction, as it will only count the bytes in the latest one. Please check out the  nrf_uarte_rx_amount_get function for more information.

    The PPI is a Programmable Peripheral Interconnect, please read more on the Infocenter.

    Best regards and sorry for the delayed reply,

    Simon

  • Hey Simon,

    I think the problem is that there is a load of existing code in the demo that deals with the UART and it has been interfering with my code. I thought I was only calling the existing UART init, but the interrupt handling functions are interfering with my code, I thought all my interrupts were disabled, but it's not the case.

    The code is pretty dense and I suspect it's like the STM/Atmel dev kit example code in that it's set up to work on multiple kits and so is pretty obfuscated. I need to completely rethink how serial code is received, because this is not like anormal UART.

    Thanks a lot for the help.

Reply
  • Hey Simon,

    I think the problem is that there is a load of existing code in the demo that deals with the UART and it has been interfering with my code. I thought I was only calling the existing UART init, but the interrupt handling functions are interfering with my code, I thought all my interrupts were disabled, but it's not the case.

    The code is pretty dense and I suspect it's like the STM/Atmel dev kit example code in that it's set up to work on multiple kits and so is pretty obfuscated. I need to completely rethink how serial code is received, because this is not like anormal UART.

    Thanks a lot for the help.

Children
  • Actually, I think it's worse than I thought. I think that the RXD amount does not change until the requisite number of bytes as set in the RXD.MAXCOUNT is received.Originally I thought I could see that this value was changing because I had set the value so low.

    If you have variable amounts coming in the only sensible way is to set the DMA to receive one byte and continually retrigger.

    Whoever designed this UART needs to have a word with themself.

  • DiBosco,

    I have run into the same issue that you describe. Your post has been very helpful to confirm what I have noticed.

    I totally agree with you that the design of the UARTE, with "Easy-DMA" is defective.

    What bothers me is not that there is a problem with the UARTE, but that Nordic does not document this behavior in the errata sheet or in the data sheet or some other logical place. It is up to us (the programmers) to waste enormous time and effort only to discover that things do not work as expected.

    Hopefully, Nordic will have some mercy on us and add examples, notes and limitations to the documentation.

    And now back to work with the UARTE and its "Easy-DMA" Disappointed

Related