nRF52840 Dongle Failed on SWD with Lowlevel error: NOT_AVAILABLE_BECAUSE_PROTECTION (ffffffa6)

It seems this is a new problem with PCA10059 2.1.0, but not 2.0.0 or 2.0.1 that we previously used.

I use a nrf52-dk to connect its P19 to the SWD pins on the dongle. With the newer version 2.1.0, nrf-connect programmer fails to identify the dongle. Two of the version 2.1.0 dongles failed the same. While the same setup works on a version 2.0.0 dongle. All three dongles are fresh from the package.

I also tried to flash a bootloader (/cfs-file/__key/communityserver-discussions-components-files/4/4263.pca10059_5F00_bootloader.zip) found on the programming tutorial page (https://devzone.nordicsemi.com/guides/short-range-guides/b/getting-started/posts/nrf52840-dongle-programming-tutorial). It gets an error saying "... The init packet does not contain a signature. This bootloader requires DFU updates to be signed.".

Has something changed in version 2.1.0? Especially when compared to version 2.0.x, what are the reasons for these failures?

Software versions used: Jlink 6.88a. Segger embedded studio 5.40c. Nrf-connect v3.6.1, nrf programmer v1.4.8. I hesitate to upgrade software versions because we have previous devices using the dongle, that we try to avoid upgrading them. We'd like to use firmware previously built without having to upgrade the IDE and rebuild.

Here is the log when connecting 2.1.0 and 2.0.0:

PCA10059 2.1.0: using nrf52-dk p19 to debug through SWD
2022-09-06T00:34:32.701Z INFO Using nrfjprog to communicate with target
2022-09-06T00:34:32.961Z INFO Using J-Link Software version 6.88
2022-09-06T00:34:33.238Z INFO Segger serial:  682851047
2022-09-06T00:34:33.238Z INFO Segger speed:  2000  kHz
2022-09-06T00:34:33.239Z INFO Segger version:  J-Link OB-SAM3U128-V2-NordicSemi compiled Mar 17 2020 14:43:00
2022-09-06T00:34:33.243Z ERROR Error when getting device info: Error: Error: Error occured when get device info. Errorcode: CouldNotCallFunction (0x9)
Lowlevel error: NOT_AVAILABLE_BECAUSE_PROTECTION (ffffffa6)

2022-09-06T00:34:33.244Z ERROR Could not fetch memory size of target devkit: Cannot read property 'family' of undefined
2022-09-06T00:34:33.269Z INFO Device is closed without reset due to app protection
2022-09-06T00:35:24.235Z INFO Target device closed.

PCA10059 2.0.0: using nrf52-dk p19 to debug through SWD
2022-09-06T00:46:48.810Z INFO Using nrfjprog to communicate with target
2022-09-06T00:46:49.211Z INFO Using J-Link Software version 6.88
2022-09-06T00:46:49.580Z INFO Segger serial:  682851047
2022-09-06T00:46:49.581Z INFO Segger speed:  2000  kHz
2022-09-06T00:46:49.581Z INFO Segger version:  J-Link OB-SAM3U128-V2-NordicSemi compiled Mar 17 2020 14:43:00
2022-09-06T00:46:49.581Z INFO Core probed: 682851047
2022-09-06T00:46:49.581Z INFO Core RAM: 256KiB
2022-09-06T00:46:49.581Z INFO Core ROM: 1024KiB in pages of 4KiB
2022-09-06T00:46:49.698Z INFO Model: NRF52840_xxAA_REV2.
2022-09-06T00:46:50.111Z INFO Core0: Reading device non-volatile memory. This may take a few seconds.
2022-09-06T00:46:50.545Z INFO Core0: UICR has been read. Click read button to read full non-volatile memory.
2022-09-06T00:47:21.106Z INFO Target device closed.

Thanks.

Parents Reply Children
  • I deleted one message in the middle, that by accident deleted all replies after it. I'll try to post a little history in the deleted thread:

    I compared the schematics for 2.1.0 and 2.0.0. No obvious difference could be seen.

    It turned out the chip on hardware 2.1.0 is a rev3, instead of a rev2 on hardware 2.0.0. The rev3 needs a work-around to set "NRF_APPROTECT->DISABLE" to 0x5A by its errata and by the production specification trace and debug section. Thus I added the following code to the main(), that did not solve the problem:

    static void ap_protect_disable()
    {
        NRF_LOG_INFO("function called ap_protect_disable()\n");
        log_wait_ms(2); /* flush cli logging */
        /* show status @0x4000000C */
        NRF_LOG_INFO("APPROTECT STATUS 0x%x\n", *((__IOM uint32_t *)0X4000000C) );
        log_wait_ms(2); /* flush cli logging */
        /* APPROTECT FORCEPROTECT @0x40000550 */
        NRF_LOG_INFO("APPROTECT FORCEPROTECT 0x%x\n", *((__IOM uint32_t *)0X40000550) );
        log_wait_ms(2); /* flush cli logging */
        /* APPROTECT DISABLE @0x40000558 */
        NRF_LOG_INFO("APPROTECT DISABLE 0x%x\n", *((__IOM uint32_t *)0X40000558) );
        log_wait_ms(2); /* flush cli logging */
    
        /* UICR APPROTECT is 0xFFFFFFFF */
        NRF_LOG_INFO("UICR APPROTECT 0x%x\n", NRF_UICR->APPROTECT);
        log_wait_ms(2); /* flush cli logging */
        /* UICR modify ... ignore for now */
        NRF_LOG_INFO("UICR APPROTECT 0x%x\n", NRF_UICR->APPROTECT);
        log_wait_ms(2); /* flush cli logging */
    
        /* disable. though it's always 0x5A from the beginning. */
        //NRF_APPROTECT->DISABLE = APPROTECT_DISABLE_DISABLE_SwDisable; /* rev3 chip errata */
        *((__IOM uint32_t *)0X40000558) = 0x5A;
        NRF_LOG_INFO("APPROTECT DISABLE written\n");
        log_wait_ms(2); /* flush cli logging */
        /* APPROTECT DISABLE @0x40000558 */
        NRF_LOG_INFO("APPROTECT DISABLE 0x%x\n", *((__IOM uint32_t *)0X40000558) );
        log_wait_ms(2); /* flush cli logging */
    
        /* show twice */
        NRF_LOG_INFO("APPROTECT STATUS 0x%x\n", *((__IOM uint32_t *)0X4000000C) );
        log_wait_ms(2); /* flush cli logging */
        NRF_LOG_INFO("APPROTECT STATUS 0x%x\n", *((__IOM uint32_t *)0X4000000C) );
        log_wait_ms(2); /* flush cli logging */
    }
    

    Dejan suggested to set both the UICR register and the APPROTECT register. I believe that makes sense.

  • Here is the new developments:

    The code follows is added to the "/* UICR modify ... */" point, that has solved the problem.

        /* UICR modify ... */
        NRF_LOG_INFO("* Enabling access port *\n");
        log_wait_ms(2); /* flush cli logging */
        //NRF_UICR->APPROTECT = 0xFFFFFF5A;
        //*((__IOM uint32_t *)&(NRF_UICR->APPROTECT)) = 0xFFFFFF5A;
        int rc = write_word_to_uicr( (uint32_t *)0x10001208, 0xFFFFFF5A);
        if ( rc == 0 ) {
            NRF_LOG_INFO("* Enabling access port * already enabled!\n");
        } else if ( rc == 1 ) {
            NRF_LOG_INFO("* Enabling access port * failed!\n");
        } else {
            NRF_LOG_INFO("* Enabled access port * reset now\n");
            log_wait_ms(200); /* flush cli logging */
            NVIC_SystemReset();;
        }
        NRF_LOG_INFO("UICR APPROTECT written\n");
        log_wait_ms(2); /* flush cli logging */
    

    Its function "write _word_to_uicr()" is adapted from another QnA when searching for "nrf52840 write uicr flash". I modified it to return 0 or 1 or 2 for different cases.

    Despite, the APPROTECTSTATUS at 0x4000000C shows always 0. That cannot be used as an indication of what the current protection status is, while the product spec seems to suggest it can/should.

    Thanks!

  • Hi,

    I am glad that your issue has been resolved.

    Best regards,
    Dejan

  • Hi, Dejan,

    Really appreciate your suggestions those came just at right timing and to the right points!

    One more question: Should the APPROTECTSTATUS change to 1 when the protection is effectively disabled, like at the end of my code example after setting both UICR and APPROTECT registers? I see the register readings are always 0.

    Thanks.

  • Hi,

    It is correct that the value of APPROTECTSTATUS register should be 1 if access port protection has been disabled. The same content should be in UICR.APPROTECT and APPROTECT.DISABLE registers. UICR register is read only at the time of reset. Therefore, after writing to UICR register, reset should be performed.

    Best regards,
    Dejan

Related