-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Description
Description
In PR #10072, the nrf52_resetpin_cfg
tool was introduced, allowing to program the persistent UICR register on the nRF52 boards.
Something must have changed since 2018, but when an nRF52 is programmed via the J-Link (not via bootloader), the UCIR register is always reset and therefore the pinreset does not work anymore.
Usually the programming sequence is somewhat like this:
- Unlock (or recover) the device (this erases all of the Flash and the UICR, which holds the Pinreset configuration)
- Perform a chiperase
- Write the bin/hex
- Verify
- (optionally) write the UCIR
- on the first reset or power down, power up, the nRF has the readback protection enabled which you can only disable by "unlocking" or "recovering" the device, deleting Flash and UICR
nrfjprog
shows the issue nicely. I try to read the UICR register after powering up an nRF52840DK board. It fails because the readback protection is activated. Then I recover the device, which deletes the Flash and UICR area. After that I can read out the UICR, but it is blank.
To see how it should look like, I activate the pinreset (without powering the device down in between!) and read it out again.
chris@ThinkPias:~$ nrfjprog --readuicr asdf.hex
[error] [ Client] - Encountered error -90: Command read_device_info executed for 2 milliseconds with result -90
[error] [ Worker] - Access protection is enabled, can't read device version.
[error] [ Client] - Encountered error -90: Command read_memory_descriptors executed for 2 milliseconds with result -90
[error] [ Worker] - Can't read memory descriptors, ap-protection is enabled.
ERROR: The operation attempted is unavailable due to readback protection in
ERROR: your device. Please use --recover to unlock the device.
NOTE: For additional output, try running again with logging enabled (--log).
NOTE: Any generated log error messages will be displayed.
chris@ThinkPias:~$ nrfjprog --recover
Recovering device. This operation might take 30s.
Erasing user code and UICR flash areas.
Writing image to disable ap protect.
chris@ThinkPias:~$ nrfjprog --readuicr asdf.hex
Storing data in 'asdf.hex'.
chris@ThinkPias:~$ nrfjprog --pinresetenable
Enabling pin reset.
chris@ThinkPias:~$ nrfjprog --readuicr asdf2.hex
Storing data in 'asdf2.hex'.
On the left side, the UICR is shown before enabling the pinreset and on the right side it is shown after the pinreset.
Programming with J-Link is pretty much the same, but nrfjprog
is a lot more verbose about what it does and why it does (or does not) do something.
So essentially what I want to say is that it would be nice to be able to activate the Pinreset when flashing a RIOT image with make flash
.
@benpicco proposed a software based solution in #19833, but the nRF52s do have the Pinreset registers in UICR, so why not use them? (However I am still in favor of merging that PR, it is nice to have a software option as well.)
Now... the thing is that with nrfjprog
it is very easy to activate the Pinreset, just call nrfjprog --pinresetenable
after programming (and before the first reset). With J-Link it is not so easy because it does not have a dedicated option to do it.
In general I see two main possibilities:
- Create a
JLINK_POST_FLASH
define for dist/tools/jlink.sh, that writes the right values into the UICR. So far nobody seems to useJLINK_POST_FLASH
for anything. - Activate the pinreset with
nrfjprog
. This would require an additional dependency, which is probably not favorable.
Option 1 seems to work. The base address for the UICR register is 0x10001000 for the nRF52840 and the offset for of the PSELRESET registers is 0x200 and 0x204. Essentially I just copied the memory content from what `nrfjprog` puts into the registers. Setting the registers with the J-Link programmer works when I add `JLINK_POST_FLASH` to the command like this:
JLINK_POST_FLASH='Write4 0x10001200 00000012 00000012' BOARD=nrf52840dk make flash term
We can check the burn file that is created by makefiles/tools/jlink.inc.mk has the right post-flash operation:
chris@ThinkPias:~/flashdev-riot/RIOT/examples/default$ cat bin/nrf52840dk/burn.seg
loadfile /home/chris/SmartSensors/spacepatch-riot/RIOT/examples/default/bin/nrf52840dk/default.elf
Write4 0x10001200 00000012 00000012
r
g
exit
HOWEVER when I add JLINK_POST_FLASH = Write4 0x10001200 00000012 00000012
to the boards/nrf52840dk/Makefile.include and just call BOARD=nrf52840dk make flash term
, it does not work. What's odd though is that it does work when I call JLINK_POST_FLASH='' BOARD=nrf52840dk make flash term
.
Then I tried it with JLINK_PRE_FLASH
because that is actually used by some boards, but it has the same behavior.
What's odd as well is that the 'stk3200' board, which uses JLINK_PRE_FLASH
in it's boards/stk3200/Makefile.include shows the same behavior. Without adding JLINK_PRE_FLASH=''
or similar to the command line, the r
from the Makefile is not added to the burn.seg file.
Maybe someone has some guidance on that or generally some feedback about the approach.
Useful links
Documentation about the UICR:
https://docs.nordicsemi.com/bundle/ps_nrf52832/page/uicr.html#register.PSELRESET-0
Documentation about the Pinreset (not very much unfortunately):
https://docs.nordicsemi.com/bundle/ps_nrf52832/page/power.html#d935e411