Read the register of wrong value

Hi,

I found a odd thing when I try to get the value of ERRORSRC of uarte0 in the problem.

Sometimes the project of my customer have an uart error, when they read the value of ERRORSRC with:

*p_errSrc = nrf_uarte_errorsrc_get_and_clear(&p_serial->instance.p_reg);

when they print the value of the result, it's 0x06.

But when they stimulate and stop at the function, we can see the value of ERRORSRC is 0x08.

I have tried with sample ble_app_uart(nrf5 SDK 17.0.2) on nRF52DK, I change the RX pin to P0.26 and give it a zero level.

When I stimulate with SES and stop at the function uart_event_handle (case APP_UART_COMMUNICATION_ERROR:)

I can see the value of ERRORSRC is 0x0c.

But when I read it with nrf_uarte_errorsrc_get_and_clear or get it directly with var = NRF_UART0->ERRORSRC, I will get 0x8 or 0 as a result.

It's so odd.

Is there any restrict on how to read the value of register in the project?

Parents
  • Hi,

    All the numbers you describe are valid values of ERRORSRC, but some with multiple flags set (like 0x6). I do not see from the description in what occurrences you get the different error reasons, but I understand you see different values while debugging. Can you elaborate, both with description and code what you do and when you see this? For instance, what do you mean by "But when they stimulate and stop at the function"?

  • Hi,

    I use the sample "……\AA_nRF5_SDK_17.0.2_d674dde\examples\peripheral\uart\pca10056\blank\ses".

    In order to generate the problem, I configure the RX_PIN_NUMBER as 26(it was decault 8) in pca10056.h.

    Then I start stimulation with SES, when the pin 0.26 has a jitter, an APP_UART_COMMUNICATION_ERROR will occur, and I make a breakpoint there.

    We can see the ERRORSOC form the debuging window is 0x0c.

    but when I use var = NRF_UART0->ERRORSRC to get the value(I want to print it), the variate never became the right value. 

    I will get 0 or 0x08, that's what I mean.

  • What happens here is that when you pause with the debugger, another issue is also triggered, so there is nothing wrong with reading the registers here. You can expand a bit to see it more clearly.

    First, remember that BREAK is 0x8 and FRAMING is 0x4, so if you have both you read 0xC. Now, we can modify the uart_error_handle() a bit more like this:

    static uint32_t var1 = 0;
    static uint32_t var2 = 0;
    static uint32_t dummy = 0;
    
    void uart_error_handle(app_uart_evt_t * p_event)
    {
        if (p_event->evt_type == APP_UART_COMMUNICATION_ERROR)
        {
            var1 = NRF_UART0->ERRORSRC;
            //APP_ERROR_HANDLER(p_event->data.error_communication);
            dummy++;
            var2 = NRF_UART0->ERRORSRC;
        }
        else if (p_event->evt_type == APP_UART_FIFO_ERROR)
        {
            APP_ERROR_HANDLER(p_event->data.error_code);
        }
    }

    If I set the breakpoint on the line with "dummy++" I will see this:

    Here the debugger shows that both BREAK and FRAMING are set, but if you look at the watch var1 only has BREAK. Now let me step a few lines so that var2 is also set, with the current ERRORSRC value:

    Here you see that var2 is 0xC, so both BREAK and FRAMING are set, which is the same as we see with the debugger.

    Now let us only set the breakpoint at the end of the function and run to it from the start:

    Here you see that both var1 and var2 is 0x8, so only BREAK was set originally. However, the register view also shows that FRAMING is set. So the FRAMING bit was set a bit later, before it was read out by the debugger.

    In other words, there is nothing wrong with reading the registers in any way, but it does not (and cannot) happen instantaneously, so depending on the timing you will see the change (remember that the UART peripheral is not paused just because the debugger pauses the CPU).

  • Hi Einar,

    Thanks for your patient explanation, I know why it seems so strange.

    It seems that there isn't an effective way to read the ERRORSRC register, do you have any advise?

    We want to do this because my customer found that they will miss some data from uart. when this happened they read the ERRORSRC and get 0x06.

    Which means a parity error, but we are sure the customer have enable hardware parity.

    So we are afraid if there is memory leak that lead to the parity error.

    Do you have any idea why we would get the parity error?

Reply
  • Hi Einar,

    Thanks for your patient explanation, I know why it seems so strange.

    It seems that there isn't an effective way to read the ERRORSRC register, do you have any advise?

    We want to do this because my customer found that they will miss some data from uart. when this happened they read the ERRORSRC and get 0x06.

    Which means a parity error, but we are sure the customer have enable hardware parity.

    So we are afraid if there is memory leak that lead to the parity error.

    Do you have any idea why we would get the parity error?

Children
  • Hi,

    helen said:

    It seems that there isn't an effective way to read the ERRORSRC register, do you have any advise?

    The effective way to read the ERRORSRC registers would be to copy it to a variable and read that variable. That way you will see the value at the time of the copy (which is typically close to when the error occurred and), and not a later error.

    helen said:
    Which means a parity error, but we are sure the customer have enable hardware parity.

    Are you sure the customer have enabled parity or have not enabled parity? You should only get PARITY flag if H parity is enabled and an error occurred. Perhaps the customer enabled HW parity on the nRF but that is not used by the other device?

    helen said:

    So we are afraid if there is memory leak that lead to the parity error.

    Do you have any idea why we would get the parity error?

    If parity is enabled but should not be, then disable it and check. If it should be enabled, perhaps a parity error actually happened for some reason? It would be interesting to know the configuration in both ends, and if that all seems correct, then a possible next step is to check the UART communication with a logic analyzer and see if you can capture the moment when the nRF gets the PARITY error and see if that matches what you see on the logic trace.

    How often does this happen? Is it consistent?

    Regarding a memory corruption issue that could of course be a problem though I do not immediately see why. And the  ERRORSRC register would not be corrupted like this, is only read if there already was a UART error. And it is not possible to write to it other than to clear flags (so you cannot possibly have set a flag by an accidental write). Theoretically there could have been accidental writes to other registers that could cause issues, but I do not see anything in what you have described so far that points to that being the case (though I do not have the full picture).

Related