Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: add pyocd docs #445

Merged
merged 1 commit into from
Nov 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,37 @@ When using an external debugger, you can flash using this command:
west flash --erase
```

Experimental: You can also use [pyOCD](https://github.com/pyocd/pyOCD) to flash the nRF9151 using the CMSIS-DAP interface provided by the Connectivity Bridge firmware.

Note: **Don't use pyOCD with JLink probes**, use [nrfutil-device](https://docs.nordicsemi.com/bundle/nrfutil/page/README.html) or the west runner in that case. pyOCD seems to be unmaintained at the moment, so this might not be fixed.

Another note: Sometimes, the nRF9151 is detected as protected and is mass-erased automatically. In that case, simply flash the bootloader as well.

To flash just the app:

```
pyocd flash build/app/zephyr/zephyr.signed.hex
```

To flash the bootloader (included in releases):

```
pyocd flash nrf91-bl-v2.hex
```

To erase the chip including UICR:

```
pyocd erase --mass
```

Experimental: You can update the modem firmware using pyOCD. A simple way to do this is to use the included `nrf91_flasher` script:

```
python3 scripts/nrf91_flasher.py -m mfw_nrf91x1_2.0.1.zip
```


### LED pattern

| LED effect | Color | Meaning | Duration (seconds) |
Expand Down
89 changes: 89 additions & 0 deletions scripts/nrf91_flasher.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
#!/usr/bin/env python3
#
# Copyright (c) 2024 Nordic Semiconductor ASA
#
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause

from pyocd.core.helpers import ConnectHelper
from pyocd.flash.file_programmer import FileProgrammer
from pyocd.core.target import Target
from pyocd.target.family.target_nRF91 import ModemUpdater
from pyocd.core.exceptions import TargetError
from intelhex import IntelHex
from tempfile import TemporaryDirectory
import os
from timeit import default_timer as timer
import argparse

import logging
logging.basicConfig(level=logging.INFO)

parser = argparse.ArgumentParser(description="Wrapper around pyOCD to flash nRF91")
parser.add_argument("-e", "--erase", help = "perform mass_erase", action='store_true')
parser.add_argument("-p", "--program", help = "program file (hex, elf, bin)")
parser.add_argument("-m", "--modem", help = "modem update zip file")
parser.add_argument("-u", "--uid", help = "probe uid")

args = parser.parse_args()

options = {
"target_override" : "nrf91",
"cmsis_dap.limit_packets" : False,
"frequency" : 8000000,
"logging" : {
"loggers": {
"pyocd.coresight" : {"level": logging.INFO}
}
}
}

with ConnectHelper.session_with_chosen_probe(unique_id=args.uid, options=options) as session:

board = session.board
target = board.target
flash = target.memory_map.get_boot_memory()

if args.erase:
logging.info("perform mass erase")
target.mass_erase()

if args.program:
if args.program.endswith("hex"):
# Load firmware into device.
logging.info("flashing program")
input = IntelHex(args.program)
flash = input[0x00000000:0x00100000]
uicr = input[0x00FF8000:0x00FF9000]
with TemporaryDirectory() as tempdir:
if len(uicr.segments()) > 0:
logging.info("writing UICR")
for start, end in uicr.segments():
target.write_flash(start, uicr[start:end].tobinarray())

logging.info("writing flash")
flash_file = os.path.join(tempdir, "flash.hex")
flash.tofile(flash_file, format="hex")
FileProgrammer(session).program(flash_file)
else:
logging.info("not a HEX file, flashing without range checks")
FileProgrammer(session).program(args.program)

if args.modem:
modem_needs_update = False

# Check modem firmware version
try:
ModemUpdater(session).verify(args.modem)
except TargetError as e:
modem_needs_update = True

# Update modem firmware.
if modem_needs_update:
logging.warning("modem verify failed, updating modem firmware")
start = timer()
ModemUpdater(session).program_and_verify(args.modem)
end = timer()
logging.info(f"modem update took {end-start} seconds")
# Reset, run.
logging.info("resetting device")
target.reset()
Empty file modified scripts/nsib_signature_check.py
100644 → 100755
Empty file.
Empty file modified scripts/read_flash.py
100644 → 100755
Empty file.
Loading