NRF52840 UART Rx received data incorrectly when use HFINT internal oscillator as clock source

Hello, I am currently working on nrf52840 using nrf-sdk v2.2. to build a Matter firmware. I encountered an issue that a small number of chips UART received data incorrectly. I obtained the data waveform using an oscilloscope and did not find any abnormalities. 

I use ’mpsl_clock_hfclk_is_running' interface to check if HFXO is enabled, the result is no. Then I try to enable HFXO as clock source and this issue never occurred again.

Given that this issue only occurs in a small number of chips, I believe it is a hardware issue caused by individual differences in the internal oscillators of different chips.

Is my inference reasonable?  Will individual differences in the internal oscillator of nrf52849 lead to unstable serial port timing?

Here are some supplementary information:

Due to the low power consumption requirements of the product. UART enters "sleep" when it is not in use, the RX turns to GPIO mode. When data comming, RX generates a falling edge (UART start bit), triggering a GPIO falling edge interrupt. In interrupt processing, UART will be enabled again. This process is called "wakeup". This issue occurs during the initial wake-up period of UART, and then returns to normal until UART goes back to sleep.

Parents Reply Children
  • Right. The value used in the UART documentation and drivers are not the best value. But the ones used in the UARTE docs and drivers should be better.

    I believe hmolesworth discussed that in depth here:  RE: Technical question regarding UART baud rate generator (BAUDRATE register, offset 0x524) .

     How about lowering the baud rate? At lower baud rate, the lower accuracy of HFINT could be less impactful. However, please note again that this is not what the UART peripheral was designed to run with, so we cannot guarantee long term reliability.

  • Thank you for your suggestion, but I observed an anomaly under the condition of a baud rate of 9600

  • The baud rate is 9600 right now, so lower baud rate may not solve my problem. The power I mentioned refers to the average value over a period of time, so suspending the UART when it is not working will result in an average value much less than 600uA and is acceptable.  So what I need to do is switch HFINT to HFXO, so that UART can work properly. Do you think this method is feasible?

  • Right, and for baud rate 9600, the issue that hmolesworth mentioned is not relevant, so we don't have anything to improve in this direction.

    Damon Liu said:
    The power I mentioned refers to the average value over a period of time, so suspending the UART when it is not working will result in an average value much less than 600uA and is acceptable.  So what I need to do is switch HFINT to HFXO, so that UART can work properly. Do you think this method is feasible?

    If the suspending then resuming strategy works for you, I think you should use it. Especially when it still satisfies your power requirement when HFXO is in used.

    Is this the answer you are looking for or did I misunderstand the question?

  • Quite, at 9600 the frequency is unlikely to be an issue. Worth checking something else when waking from sleep; depending on the driver sometimes I see unexpected events incorrectly left enabled. In the case of EVENTS_CTS this is always set by hardware regardless of whether the HW flow control is ever used or not. Maybe capture these registers and print values:

    Event:  CLOCK->EVENTS_HFCLKSTARTED      0x4000'0100 = 1 (No Enable Field)       IntEnable 0x4000'0300=         0
    Event:  CLOCK->EVENTS_LFCLKSTARTED      0x4000'0104 = 1 (No Enable Field)       IntEnable 0x4000'0300=         0
    Event:  POWER->EVENTS_SLEEPENTER        0x4000'0114 = 1 (No Enable Field)       IntEnable 0x4000'0300=         0
    Event:  UARTE->EVENTS_CTS               0x4000'2100 = 1 Enable 0x4000'2500=0x00 IntEnable 0x4000'2300=         0, Shorts 0x4000'2200=0
    Event:  UARTE->EVENTS_TXDRDY            0x4000'211C = 1 Enable 0x4000'2500=0x00 IntEnable 0x4000'2300=         0, Shorts 0x4000'2200=0

Related