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

How to apply Nordic software workarounds/Errata for a given hardware revision in the field

Greetings!

This is about the errata published by Nordic, i.e., software workarounds from Nordic for a given hardware revision.

Example: nRF52840 Errata

https://infocenter.nordicsemi.com/topic/errata_nRF52840_Rev2/ERR/nRF52840/Rev2/latest/err_840_new.html 

ID    Module   Description

[20]  RTC:     Register values are invalid

This anomaly applies to IC Rev. Revision 2, build codes CKAA-Dx0, QIAA-Dx0.

In ID [20], there is a software workaround recommended by Nordic. To apply this workaround for our nRF52840 devices in the field, we need to know the build codes QIAA-Dx0 either in the Bill of Materials (BOM) or in the Non-Volatile Memory (NVM) register such as INFO.VARIANT in the chip.

The problem:

  • BOM only captures the order code: nRF52840-QIAA-R.
  • It is not clear which NVM register captures the QIAA-Dx0 in the nRF52840 Product Specification v1.1.
  • Based on my understanding, QIAA-Dx0, seems only to be available in a factory environment and the hardware/software engineers have no information about this unless we look at what is printed on the chip. So, how to DFU these Nordic Software Errata/Workaround?

Questions:

  1. Typically, the software workarounds are available in the SDK. When it is not in the SDK, are these patches available in an easy to integrate way of importing or compiling these patches? For example, are the workarounds available module-wise in a .c file for a given QIAA-Dx0?
  2. Is there any NVM register that I could look up QIAA-Dx0 to apply the patch? 
  3. Currently, there appears to be no way for a developer to know the hardware revision number (like QIAA-Dx0) being used in the factory. Is there any Nordic recommended way of patching our devices in the field for such hardware revisions? Especially when DFU or Firmware Over the Air is performed. 

Kindly let me know your thoughts on this each of the above bullets. Looking forward to your response.

Cheers,
Tilak

Parents
  • Hi,

    Errata's are typically implemented in the SDK, Softdevice, and MDK. You will have to refer to the release notes for a specific release to find if the errata's are implemented already, or if you need to take specific precautions in your own code. To determine what hardware revision you are on, you may get a way to do so by looking at the MDK files, e.g. in the system_nrf52.c you can see they are reading magic internal registers to find if the errata's should be implemented. In your case you may just re-use the same code in your project (for instance see errata_36()). In general the first if() statement in the errata_36() refer to the nRF52-variant (e.g. nRF52832 or nRF52840) and the nested if() statements refer to various hardware revisions of the variant.

    Unfortunately there is no public documented register you can read.

    Best regards,
    Kenneth

  • Hi Kenneth,

    I thought I understood your response but after looking at the code I am a little confused. Please help clarifying the following:

    1. The errata_36() appears very different in nRF52832 and nRF52840. I was expecting the code to remain the same. Hence, please explain as there is no documentation.
      1. Which if() magic register maps to nRF52832 and also for nRF52840.
      2. Which if() maps to which build code of the hardware revision (CIAA-Ex0, QFAA-Ex0, QFAB-Ex0, CIAA-EA0, QFAA-EA0) for nRF52832 and (CKAA-Dx0, QIAA-Dx0) for nRF52840
      3. I am curious to know why is there a unique file system_nrf52840.c and not a generic one like system_nrf52.c for nRF52840.

    Setup: nRF5_SDK_15.3

    /* blinky_pca10056.emProject, nRF52840:  system_nrf52840.c */
    static bool errata_36(void)
    {
        if (*(uint32_t *)0x10000130ul == 0x8ul){
            if (*(uint32_t *)0x10000134ul == 0x0ul){
                return true;
            }
            if (*(uint32_t *)0x10000134ul == 0x1ul){
                return true;
            }
            if (*(uint32_t *)0x10000134ul == 0x2ul){
                return true;
            }
            if (*(uint32_t *)0x10000134ul == 0x3ul){
                return true;
            }
        }
    
        /* Apply by default for unknown devices until errata is confirmed fixed. */
        return true;
    }
    
    /* blinky_pca10040.emProject, nRF52832:  system_nrf52.c */
    static bool errata_36(void)
    {
        if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x6) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)){
            if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x30){
                return true;
            }
            if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x40){
                return true;
            }
            if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x50){
                return true;
            }
        }
    
        return false;
    }
    

    This is really critical for us to apply the patches based the hardware version otherwise the errata document makes no sense as we cannot find the hardware version.

    Cheers,
    Tilak

    ps: If possible, please respond bullet wise to the corresponding question.

Reply
  • Hi Kenneth,

    I thought I understood your response but after looking at the code I am a little confused. Please help clarifying the following:

    1. The errata_36() appears very different in nRF52832 and nRF52840. I was expecting the code to remain the same. Hence, please explain as there is no documentation.
      1. Which if() magic register maps to nRF52832 and also for nRF52840.
      2. Which if() maps to which build code of the hardware revision (CIAA-Ex0, QFAA-Ex0, QFAB-Ex0, CIAA-EA0, QFAA-EA0) for nRF52832 and (CKAA-Dx0, QIAA-Dx0) for nRF52840
      3. I am curious to know why is there a unique file system_nrf52840.c and not a generic one like system_nrf52.c for nRF52840.

    Setup: nRF5_SDK_15.3

    /* blinky_pca10056.emProject, nRF52840:  system_nrf52840.c */
    static bool errata_36(void)
    {
        if (*(uint32_t *)0x10000130ul == 0x8ul){
            if (*(uint32_t *)0x10000134ul == 0x0ul){
                return true;
            }
            if (*(uint32_t *)0x10000134ul == 0x1ul){
                return true;
            }
            if (*(uint32_t *)0x10000134ul == 0x2ul){
                return true;
            }
            if (*(uint32_t *)0x10000134ul == 0x3ul){
                return true;
            }
        }
    
        /* Apply by default for unknown devices until errata is confirmed fixed. */
        return true;
    }
    
    /* blinky_pca10040.emProject, nRF52832:  system_nrf52.c */
    static bool errata_36(void)
    {
        if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x6) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)){
            if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x30){
                return true;
            }
            if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x40){
                return true;
            }
            if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x50){
                return true;
            }
        }
    
        return false;
    }
    

    This is really critical for us to apply the patches based the hardware version otherwise the errata document makes no sense as we cannot find the hardware version.

    Cheers,
    Tilak

    ps: If possible, please respond bullet wise to the corresponding question.

Children
Related