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

nRF9160 CTRL-AP access using J-Link Commander/GDB

I've managed to find some magic numbers/commands for working with nRF5x devices using the CTRL-AP interface, but having no such luck with the commands on an nRF9160. I've tried (using J-Link Commander):

J-Link>connect
Please specify device / core. <Default>: CORTEX-M33
Type '?' for selection dialog
Device>
Please specify target interface:
J) JTAG (Default)
S) SWD
T) cJTAG
TIF>
Device position in JTAG chain (IRPre,DRPre) <Default>: -1,-1 => Auto-detect
JTAGConf>
Specify target interface speed [kHz]. <Default>: 4000 kHz
Speed>
Device "CORTEX-M33" selected.


Selected interface (JTAG) is not supported by the connected probe.
J-Link>SWDSelect
Select SWD by sending SWD switching sequence.
Found SWD-DP with ID 0x6BA02477
J-Link>SWDWriteDP 1 0x50000000
Write DP register 1 = 0x50000000
J-Link>SWDWriteDP 2 0x01000000
Write DP register 2 = 0x01000000
J-Link>SWDWriteAP 1 0x00000001
Write AP register 1 = 0x00000001
J-Link>SWDReadAP 2
Read AP register 2 = 0x02000000
J-Link>SWDReadAP 2
Read AP register 2 = 0x00000000

Is there something different to be done on the nRF9160? I would have thought that, after having done the above, the device would have performed a mass erase of its flash.

The nRF9160 has sections on using things like the "mailbox" interface with CTRL-AP, but little to absolutely no examples/documentation on opening a terminal and actually using it (that I've found, anyway).

Parents
  • Hi,

     

    The algorithm is slightly changed, as the nRF9160 reset behavior is changed on the SWJ-DP compared to nRF52-devices:

    https://infocenter.nordicsemi.com/topic/ps_nrf9160/pmureset.html?cp=2_0_0_4_0_4_7#reset_behaviour

    https://infocenter.nordicsemi.com/topic/ps_nrf52840/power.html?cp=4_0_0_4_2_5_7#concept_res_behav 

     

    *Updated script* Could you try this script?

    SWDSelect   // Activate SWD
    SWDWriteDP 1 0x50000000  // Enable debug power
    SWDWriteDP 2 0x04000000  // Selects the 0x04XXXXXX Access Port and 0xXXXX00XX Register bank in the access port
    SWDWriteAP 1 0x00000001  // CTRL-AP Bank 0, register offset 1 (ERASEALL 0x004): Erase all command
    
    SWDReadAP 2 // CTRL-AP Bank 0, register offset 2 (ERASEALLSTATUS 0x008): Erase all command status
    SWDReadAP 2 // Must read twice to get the value.
    
    // Wait a good amount of time, so eraseall process is done.
    sleep 500
    
    // Perform a pin reset
    r0
    sleep 10
    r1
    sleep 10
    
    SWDSelect   // Activate SWD
    SWDWriteDP 1 0x50000000  // Enable debug power
    SWDWriteDP 2 0x04000000  // Selects the 0x04XXXXXX Access Port and 0xXXXX00XX Register bank in the access port
    
    SWDReadAP 3 // CTRL-AP Bank 0, register offset 3 (APPROTECTSTATUS 0x00C): Access port protection status
    SWDReadAP 3 // //Second read returns the value: 0: enabled 1: not enabled
    
    exit

     

    Kind regards,

    Håkon

  • I also am not even able to write from the debugger to MAILBOX.TXDATA:

    J-Link>SWDSelect
    Select SWD by sending SWD switching sequence.
    Found SWD-DP with ID 0x6BA02477
    J-Link>SWDWriteDP 1 0x50000000
    Write DP register 1 = 0x50000000
    J-Link>SWDWriteDP 2 0x04000000
    Write DP register 2 = 0x04000000
    J-Link>SWDWriteAP 8 0x12345678
    Write AP register 8 = 0x12345678 ***ERROR

    The register address is 0x020 = 32, 32/4 = 8.

    Do I need to be selecting a different register bank than 0 or something?

Reply
  • I also am not even able to write from the debugger to MAILBOX.TXDATA:

    J-Link>SWDSelect
    Select SWD by sending SWD switching sequence.
    Found SWD-DP with ID 0x6BA02477
    J-Link>SWDWriteDP 1 0x50000000
    Write DP register 1 = 0x50000000
    J-Link>SWDWriteDP 2 0x04000000
    Write DP register 2 = 0x04000000
    J-Link>SWDWriteAP 8 0x12345678
    Write AP register 8 = 0x12345678 ***ERROR

    The register address is 0x020 = 32, 32/4 = 8.

    Do I need to be selecting a different register bank than 0 or something?

Children
  • The documented form for selecting the bank seems to be incorrect in the comments in the script.

    It seems that the first byte is the address offset.

    Each bank has 8 entries, from 0 to 7. Reading register 8 will not work, as you'll need to switch bank.

     

    Here's an example of reading IDR (0x0FC):

    SWDSelect

    SWDWriteDP 1 0x50000000

    SWDWriteDP 2 0x040000f0 // Select the correct bank

    SWDReadAP 3 // Read register offset 3 (0xc)

    SWDReadAP 3 // 0x12880000 should be read back

     

    So, writing to 0x20 would be like this:

    SWDSelect

    SWDWriteDP 1 0x50000000

    SWDWriteDP 2 0x04000020 // Select the correct bank per the register offset

    SWDWriteAP 0 0x12341234

    SWDReadAP 0 // Read register offset 0 (0x0)

    SWDReadAP 0 // Should now read back what you wrote

     

    Opened up a gdb session, and read the register from the MCU:

    # addr from MCU: https://infocenter.nordicsemi.com/topic/ps_nrf9160/chapters/dif/ctrl-ap.html?cp=2_0_0_8_1_5#unique_1026387282
    (gdb) print *0x50006400
    $2 = 0x12341234
    
      

    Could you see if this works?

     

    Cheers,

    Håkon

  • Perfect! I was able to successfully use ERASEPROTECT.DISABLE to recover a completely locked-down device, and I am able to read and write from the mailbox interface successfully.

    Thanks a ton for the help with this!

Related