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.

  • Hi

    If I poll for activity simply on the EVENTS_RXDRDY I am 100% definitely getting all the data being sent into the nRF correctly.

    What do you mean by this? Do you not receive the data without the END_RX event? As stated in the Infocenter's reception chapter: "The UARTE will generate the ENDRX event after completing the FLUSHRX task even if the RX FIFO was empty or if the RX buffer does not get filled up." So is the FLUSHRX task being done in your application? That should cause the ENDRX event to trigger.

    If you want a better understanding of these functions overall, this case has a very in-depth discussion on the various UARTE functions, ENDRX included. 

    If this isn't of help, I am sorry, but I am not entirely sure what exactly your problem is, so, please describe what exactly is not working.

    Best regards,

    Simon

  • Hi Simon,

    The problem is that ENDRX does not change from 0 to non-zero when the requisite number of bytes have been received by the UART. I would expect that when you set up the DMA to receive three bytes the ENDRX signal would change from non zero. To one I'd assume, but whatever, it never changes from zero.

    I have to confess I do not get this FLUSH signal at all. I suspect I think the UART should work in a traditional UART way and it's a bit funky, with me just not able to understand it at all. I've read through the data sheet multiple times and I still don't get it.

    I'd already seen that post you've linked to and was still as mystified after reading it over and over.

    I'm clearly missing something fundamental here.

    Let's start with this:

    If I set this:

    NRF_UARTE0->RXD.MAXCNT = 5;

    Should

    NRF_UARTE0->EVENTS_ENDRX

    Be set to a non-zero value when five bytes have come in over the UART?

    If my understanding is correct, what could I be doing that means it doesn't happen?

    If I misunderstand something, how do we get a notification that the number of bytes received by the UART is the value set in NRF_UARTE0->RXD.MAXCNT?

    Also, you say:

    "What do you mean by this?"

    What I mean is that if I stop the debugger I can clearly see that the data that has been sent from the computer to the nRF is in memory. So, even if I set NRF_UARTE0->RXD.MAXCNT to five, if the computer sends twenty bytes out, I get twenty bytes in my receive buffer, but I never get a notification that I have received the number of bytes in RXD.MAXCNT. ie EVENTS_ENDRX never changes value.

    Thanks :)

  • Hi

    Value of ENDRX will be updated once you will stop the receiver.

  • Hi Jakub,

    So are you saying that there is no way to automatically flag the UART has a received X bytes? You have to manually change another bit for the end of receive flag to be set?

  • There is no way to check how many bytes have been received thus it is not easy to write a robust UARTE driver. Hence Nordic has implemented library called: `LibUARTE`.

    It is using timer and PPI to calculate how many bytes you have in the buffer.

Related