Created
February 13, 2023 05:08
-
-
Save mcbridejc/86ddbd097af29325ad2198b8fae9acdc to your computer and use it in GitHub Desktop.
Setting GPNVM bits using PyOCD on Microchip SAM MCUs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"""Program GPNVM bits on a SAM microcontroller using pyocd | |
You'll need pyocd installed (`pip install pyocd`) | |
""" | |
from pyocd.core.helpers import ConnectHelper | |
import time | |
session = ConnectHelper.session_with_chosen_probe() | |
FCMD_ADDR = 0x400E0A04 | |
FSR_ADDR = 0x400E0A08 | |
FRR_ADDR = 0x400E0A0C | |
FKEY = 0x5A << 24 | |
SGPB_CMD = 0xB | |
CGPB_CMD = 0xC | |
GGPB_CMD = 0xD | |
TIMEOUT = 3.0 | |
def set_gpnvm(target, bit): | |
target.write32(FCMD_ADDR, SGPB_CMD | FKEY | (bit<< 8)) | |
start = time.time() | |
fsr = target.read32(FSR_ADDR) | |
while fsr == 0: | |
if time.time() - start > TIMEOUT: | |
raise RuntimeError("Timeout waiting for flash status") | |
fsr = target.read32(FSR_ADDR) | |
def clear_gpnvm(target, bit): | |
target.write32(FCMD_ADDR, CGPB_CMD | FKEY | (bit<< 8)) | |
start = time.time() | |
fsr = target.read32(FSR_ADDR) | |
while fsr == 0: | |
if time.time() - start > TIMEOUT: | |
raise RuntimeError("Timeout waiting for flash status") | |
fsr = target.read32(FSR_ADDR) | |
def read_gpnvm(target): | |
target.write32(FCMD_ADDR, GGPB_CMD | FKEY) | |
start = time.time() | |
fsr = target.read32(FSR_ADDR) | |
while fsr == 0: | |
if time.time() - start > TIMEOUT: | |
raise RuntimeError("Timeout waiting for flash status") | |
fsr = target.read32(FSR_ADDR) | |
return target.read32(FRR_ADDR) | |
# Simple example to set the BOOTMODE (bit 1) in the GPNVM bits | |
# On many SAM MCUs (including SAM3X and SAMG family) GPNVM bit 1 is the boot | |
# mode. Setting it boots straight from flash instead of the built-in BOOT ROM. | |
with session: | |
target = session.board.target | |
print(f"Initial value: {read_gpnvm(target)}") | |
set_gpnvm(target, 1) # Set the BOOTMODE bit | |
print(f"Updated value: {read_gpnvm(target)}") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment