Skip to content

Instantly share code, notes, and snippets.

@BKSalman
Last active May 27, 2025 11:18
Show Gist options
  • Save BKSalman/056bd832b0aad2786a797d65cb640f07 to your computer and use it in GitHub Desktop.
Save BKSalman/056bd832b0aad2786a797d65cb640f07 to your computer and use it in GitHub Desktop.
MCXN947 patch following CMSIS pack sequence
diff --git a/probe-rs/src/vendor/nxp/sequences/mcx.rs b/probe-rs/src/vendor/nxp/sequences/mcx.rs
index f631a949..6befc2d8 100644
--- a/probe-rs/src/vendor/nxp/sequences/mcx.rs
+++ b/probe-rs/src/vendor/nxp/sequences/mcx.rs
@@ -7,7 +7,7 @@ use std::{
};
use bitfield::BitMut;
-use debugmailbox::{DMCSW, DMREQUEST};
+use debugmailbox::{DMCSW, DMREQUEST, DMRETURN};
use probe_rs_target::CoreType;
use crate::{
@@ -63,6 +63,18 @@ mod debugmailbox {
}),
to: value => value.Request
);
+
+ define_ap_register!(
+ name: DMRETURN,
+ address: 0x08,
+ fields: [
+ Return: u32
+ ],
+ from: value => Ok(DMRETURN {
+ Return: value
+ }),
+ to: value => value.Return
+ );
}
/// Debug sequences for MCX family MCUs.
@@ -84,6 +96,21 @@ impl MCX {
];
// const VARIANT_A2: [&str; 3] = ["MCXA16", "MCXA17", "MCXA27"];
const VARIANT_N: [&str; 1] = ["MCXN"];
+ const VARIANT_N0: [&str; 1] = ["MCXN947"];
+
+ // MCXN947 specific register addresses
+ const SYSCON_NS_BASE: u64 = 0x40000000;
+ const TRACECLKSEL_ADDR: u64 = Self::SYSCON_NS_BASE + 0x268;
+ const TRACECLKDIV_ADDR: u64 = Self::SYSCON_NS_BASE + 0x308;
+ const AHBCLKCTRLSET0_ADDR: u64 = Self::SYSCON_NS_BASE + 0x220;
+
+ // Flash controller addresses for MCXN947
+ const FLASH_BASE: u64 = 0x40034000;
+ const FLASH_STARTA: u64 = Self::FLASH_BASE + 0x10;
+ const FLASH_STOPA: u64 = Self::FLASH_BASE + 0x14;
+ const FLASH_DATAW0: u64 = Self::FLASH_BASE + 0x80;
+ const FLASH_CMD: u64 = Self::FLASH_BASE + 0x00;
+ const FLASH_INT_CLR_STATUS: u64 = Self::FLASH_BASE + 0xFE8;
fn is_variant<'a, V>(&self, v: V) -> bool
where
@@ -149,21 +176,64 @@ impl MCX {
.try_into()?;
tracing::info!("DPIDR: {:?}", dpidr);
- tracing::info!("active DebugMailbox");
+ // Write RESYNCH_REQ + CHIP_RESET_REQ (0x21 = 0x20 | 0x01)
interface.write_raw_ap_register(&ap, DMCSW::ADDRESS, 0x0000_0021)?;
- thread::sleep(Duration::from_millis(30));
- interface.read_raw_ap_register(&ap, 0x0)?;
- interface.flush()?;
- tracing::info!("DebugMailbox command: start debug session");
+ // Poll CSW register for zero return, indicating success
+ let start = Instant::now();
+ loop {
+ let csw_val = interface.read_raw_ap_register(&ap, DMCSW::ADDRESS)?;
+ if (csw_val & 0xFFFF) == 0 {
+ break;
+ }
+ if start.elapsed() > Duration::from_millis(1000) {
+ return Err(ArmError::Timeout);
+ }
+ thread::sleep(Duration::from_millis(10));
+ }
+ tracing::info!("RESYNC_REQ + CHIP_RESET_REQ: success");
+
+ // Write START_DBG_SESSION to REQUEST register
+ tracing::info!("DebugMailbox command: start debug session (0x07)");
interface.write_raw_ap_register(&ap, DMREQUEST::ADDRESS, 0x0000_0007)?;
- thread::sleep(Duration::from_millis(30));
- interface.read_raw_ap_register(&ap, 0x0)?;
+
+ // Poll RETURN register for zero return
+ let start = Instant::now();
+ loop {
+ let return_val = interface.read_raw_ap_register(&ap, DMRETURN::ADDRESS)? & 0xFFFF;
+ if return_val == 0 {
+ break;
+ }
+ if start.elapsed() > Duration::from_millis(1000) {
+ return Err(ArmError::Timeout);
+ }
+ thread::sleep(Duration::from_millis(10));
+ }
+ tracing::info!("DEBUG_SESSION_REQ: success");
+
interface.flush()?;
Ok(true)
}
+ fn configure_trace_clock(
+ &self,
+ interface: &mut dyn ArmMemoryInterface,
+ ) -> Result<(), ArmError> {
+ tracing::info!("configuring trace clock");
+
+ // Select Trace divided clock
+ interface.write_word_32(Self::TRACECLKSEL_ADDR, 0x0)?;
+ // Set trace clock divider
+ interface.write_word_32(Self::TRACECLKDIV_ADDR, 0x2)?;
+
+ // Enable PORT0 clock for trace pins
+ interface.write_word_32(Self::AHBCLKCTRLSET0_ADDR, 1 << 13)?;
+
+ interface.flush()?;
+ Ok(())
+ }
+
fn wait_for_stop_after_reset(
&self,
interface: &mut dyn ArmMemoryInterface,
@@ -173,15 +243,30 @@ impl MCX {
tracing::info!("wait for stop after reset");
// Give bootloader time to do what it needs to do
- thread::sleep(Duration::from_millis(100));
+ if self.is_variant(Self::VARIANT_N0) {
+ thread::sleep(Duration::from_millis(1000));
+ } else {
+ thread::sleep(Duration::from_millis(100));
+ }
let ap = interface.fully_qualified_address();
let dp = ap.dp();
+
let start = Instant::now();
- while self.is_ap_enable(interface.get_dap_access()?, &ap)?
- && start.elapsed() < Duration::from_millis(300)
- {}
- self.enable_debug_mailbox(interface.get_dap_access()?, dp)?;
+ let timeout = if self.is_variant(Self::VARIANT_N0) {
+ Duration::from_millis(500)
+ } else {
+ Duration::from_millis(300)
+ };
+
+ while !self.is_ap_enable(interface.get_dap_access()?, &ap)? && start.elapsed() < timeout {
+ thread::sleep(Duration::from_millis(10));
+ }
+
+ // Try to enable debug mailbox if AP is still not enabled
+ if !self.is_ap_enable(interface.get_dap_access()?, &ap)? {
+ self.enable_debug_mailbox(interface.get_dap_access()?, dp)?;
+ }
// Halt the core in case it didn't stop at a breakpoint
let mut dhcsr = Dhcsr(0);
@@ -191,7 +276,7 @@ impl MCX {
interface.write_word_32(Dhcsr::get_mmio_address(), dhcsr.into())?;
interface.flush()?;
- // Clear watch point
+ // Clear watch points
interface.write_word_32(0xE000_1020, 0x0)?;
interface.write_word_32(0xE000_1028, 0x0)?;
interface.write_word_32(0xE000_1030, 0x0)?;
@@ -220,7 +305,10 @@ impl ArmDebugSequence for MCX {
) -> Result<(), ArmError> {
use crate::architecture::arm::dp::{Abort, Ctrl, SelectV1};
- tracing::info!("debug port start");
+ tracing::info!("debug port start for MCX variant: {}", self.variant);
+
+ // Switch to DP Register Bank 0
+ interface.write_dp_register(dp, SelectV1(0))?;
// Clear WDATAERR, STICKYORUN, STICKYCMP, STICKYERR
let mut abort = Abort(0);
@@ -230,41 +318,40 @@ impl ArmDebugSequence for MCX {
abort.set_stkerrclr(true);
interface.write_dp_register(dp, abort)?;
- // Switch to DP Register Bank 0
- interface.write_dp_register(dp, SelectV1(0))?;
-
// Read DP CTRL/STAT Register and check if CSYSPWRUPACK and CDBGPWRUPACK bits are set
let ctrl: Ctrl = interface.read_dp_register(dp)?;
let powered_down = !ctrl.csyspwrupack() || !ctrl.cdbgpwrupack();
- if !powered_down {
- return Ok(());
- }
-
- // Request Debug/System Power-Up
- let mut ctrl = Ctrl(0);
- ctrl.set_csyspwrupreq(true);
- ctrl.set_cdbgpwrupreq(true);
- interface.write_dp_register(dp, ctrl)?;
+ if powered_down {
+ // Request Debug/System Power-Up
+ let mut ctrl = Ctrl(0);
+ ctrl.set_csyspwrupreq(true);
+ ctrl.set_cdbgpwrupreq(true);
+ interface.write_dp_register(dp, ctrl)?;
- // Wait for Power-Up request to be acknowledged
- let start = Instant::now();
- loop {
- let ctrl: Ctrl = interface.read_dp_register(dp)?;
- if ctrl.csyspwrupack() && ctrl.cdbgpwrupack() {
- break;
- }
- if start.elapsed() > Duration::from_millis(1000) {
- return Err(ArmError::Timeout);
+ // Wait for Power-Up request to be acknowledged
+ let start = Instant::now();
+ let timeout = if self.is_variant(Self::VARIANT_N0) {
+ Duration::from_millis(1000)
+ } else {
+ Duration::from_millis(500)
+ };
+
+ loop {
+ let ctrl: Ctrl = interface.read_dp_register(dp)?;
+ if ctrl.csyspwrupack() && ctrl.cdbgpwrupack() {
+ break;
+ }
+ if start.elapsed() > timeout {
+ return Err(ArmError::Timeout);
+ }
+ thread::sleep(Duration::from_millis(10));
}
}
if let Some(protocol) = interface.try_dap_probe().and_then(|f| f.active_protocol()) {
match protocol {
WireProtocol::Jtag => {
- // Init AP Transfer Mode, Transaction Counter, and
- // Lane Mask (Normal Transfer Mode, Include all Byte Lanes)
- // Additionally clear STICKYORUN, STICKCMP, and STICKYERR bits
let mut ctrl = Ctrl(0);
ctrl.set_csyspwrupreq(true);
ctrl.set_cdbgpwrupreq(true);
@@ -275,16 +362,12 @@ impl ArmDebugSequence for MCX {
interface.write_dp_register(dp, ctrl)?;
}
WireProtocol::Swd => {
- // Init AP Transfer Mode, Transaction Counter, and
- // Lane Mask (Normal Transfer Mode, Include all Byte Lanes)
let mut ctrl = Ctrl(0);
ctrl.set_csyspwrupreq(true);
ctrl.set_cdbgpwrupreq(true);
ctrl.set_mask_lane(0b1111);
interface.write_dp_register(dp, ctrl)?;
- // Clear WDATAERR, STICKYORUN, STICKYCMP, and STICKYERR bits
- // of CTRL/STAT Register by write to ABORT register
let mut abort = Abort(0);
abort.set_wderrclr(true);
abort.set_orunerrclr(true);
@@ -293,11 +376,12 @@ impl ArmDebugSequence for MCX {
interface.write_dp_register(dp, abort)?;
}
}
+ }
- let ap = FullyQualifiedApAddress::v1_with_dp(dp, 0);
- if !self.is_ap_enable(interface, &ap)? {
- self.enable_debug_mailbox(interface, dp)?;
- }
+ // Check if AP0 is disabled and enable debug mailbox if needed
+ let ap = FullyQualifiedApAddress::v1_with_dp(dp, 0);
+ if !self.is_ap_enable(interface, &ap)? {
+ self.enable_debug_mailbox(interface, dp)?;
}
Ok(())
@@ -311,7 +395,7 @@ impl ArmDebugSequence for MCX {
) -> Result<(), ArmError> {
use crate::architecture::arm::core::armv8m::{Aircr, Demcr, Dhcsr};
- tracing::info!("reset system");
+ tracing::info!("reset system for MCX variant: {}", self.variant);
// Halt the core
let mut dhcsr = Dhcsr(0);
@@ -327,14 +411,30 @@ impl ArmDebugSequence for MCX {
interface.write_word_32(Demcr::get_mmio_address(), demcr.into())?;
interface.flush()?;
- // Set watch point
+ // Set watch points based on variant
if self.is_variant(Self::VARIANT_A0) || self.is_variant(Self::VARIANT_A1) {
interface.write_word_32(0xE000_1020, 0x4009_1036)?;
interface.write_word_32(0xE000_1028, 0xF000_0412)?;
interface.write_word_32(0xE000_1030, 0x4009_1040)?;
interface.write_word_32(0xE000_1038, 0xF000_0403)?;
+ } else if self.is_variant(Self::VARIANT_N0) {
+ interface.write_word_32(0xE000_1020, 0x0000_0000)?;
+ interface.write_word_32(0xE000_1028, 0x0000_0412)?;
+ interface.write_word_32(0xE000_1030, 0x00FF_FFFF)?;
+ interface.write_word_32(0xE000_1038, 0x0000_0403)?;
+
+ interface.write_word_32(0xE000_1040, 0x8000_0000)?;
+ interface.write_word_32(0xE000_1048, 0x0000_0412)?;
+ interface.write_word_32(0xE000_1050, 0x8FFF_FFFF)?;
+ interface.write_word_32(0xE000_1058, 0x0000_0403)?;
+
+ // Reinit clock
+ interface.write_word_32(0x4000_0220, 0x401)?;
+ interface.write_word_32(0x4000_0140, 0x401)?;
+ interface.write_word_32(0x4000_0220, 0xE000)?;
+ interface.write_word_32(0x4000_0140, 0xE000)?;
} else {
- tracing::warn!("unknwon variant, try to set watch point");
+ tracing::warn!("unknown variant, using default watchpoint configuration");
interface.write_word_32(0xE000_1020, 0x0000_0000)?;
interface.write_word_32(0xE000_1028, 0x0000_0412)?;
interface.write_word_32(0xE000_1030, 0x000F_FFFF)?;
@@ -348,6 +448,9 @@ impl ArmDebugSequence for MCX {
aircr.set_sysresetreq(true);
let _ = interface.write_word_32(Aircr::get_mmio_address(), aircr.into());
+ // Configure trace clock
+ let _ = self.configure_trace_clock(interface);
+
let _ = self.wait_for_stop_after_reset(interface);
Ok(())
@@ -361,28 +464,65 @@ impl ArmDebugSequence for MCX {
) -> Result<(), ArmError> {
use crate::architecture::arm::armv8m::{Demcr, Dhcsr};
- tracing::info!("reset catch set");
+ tracing::info!("reset catch set for MCX variant: {}", self.variant);
let mut demcr: Demcr = core.read_word_32(Demcr::get_mmio_address())?.into();
demcr.set_vc_corereset(false);
core.write_word_32(Demcr::get_mmio_address(), demcr.into())?;
core.flush()?;
- let reset_vector = core.read_word_32(0x0000_0004)?;
+ let reset_vector = if self.is_variant(Self::VARIANT_N0) {
+ tracing::info!("reading reset vector via flash controller");
+
+ // Program Flash Word Start/Stop Address to 0x0
+ core.write_word_32(Self::FLASH_STARTA, 0x0)?;
+ core.write_word_32(Self::FLASH_STOPA, 0x0)?;
+
+ // Clear data words
+ for i in 0..8 {
+ core.write_word_32(Self::FLASH_DATAW0 + (i * 4), 0x0)?;
+ }
+
+ // Clear flash controller status
+ core.write_word_32(Self::FLASH_INT_CLR_STATUS, 0x0000_000F)?;
+
+ // Read single flash word command
+ core.write_word_32(Self::FLASH_CMD, 0x0000_0003)?;
+
+ core.flush()?;
+
+ // Try to read reset vector via AHB
+ let reset_vector = core.read_word_32(0x0000_0004)?;
+
+ // Check if we need to use secure address space
+ let enable_secure_check1 = core.read_word_32(0x4012_0FFC)? & 0xC;
+ let enable_secure_check2 = core.read_word_32(0x4012_0FF8)? & 0xC;
+
+ if enable_secure_check1 != 0x8 || enable_secure_check2 != 0x8 {
+ tracing::info!("reading reset vector from secure address space");
+ core.read_word_32(0x1000_0004)?
+ } else {
+ reset_vector
+ }
+ } else {
+ core.read_word_32(0x0000_0004)?
+ };
// Breakpoint on user application reset vector
if reset_vector != 0xFFFF_FFFF {
+ tracing::info!("setting breakpoint on reset vector: 0x{:08X}", reset_vector);
core.write_word_32(0xE000_2008, reset_vector | 0x1)?;
core.write_word_32(0xE000_2000, 0x0000_0003)?;
- }
- // Enable reset vector catch
- if reset_vector == 0xFFFF_FFFF {
+ } else {
+ // Enable reset vector catch
+ tracing::info!("enabling reset vector catch");
let mut demcr: Demcr = core.read_word_32(Demcr::get_mmio_address())?.into();
demcr.set_vc_corereset(true);
core.write_word_32(Demcr::get_mmio_address(), demcr.into())?;
}
core.flush()?;
+ // Read DHCSR to clear potentially set DHCSR.S_RESET_ST bit
core.read_word_32(Dhcsr::get_mmio_address())?;
Ok(())
@@ -398,9 +538,13 @@ impl ArmDebugSequence for MCX {
tracing::info!("reset catch clear");
+ // Clear FPB Comparators
core.write_word_32(0xE000_2008, 0x0000_0000)?;
+
+ // Disable FPB
core.write_word_32(0xE000_2000, 0x0000_0002)?;
+ // Clear reset vector catch
let mut demcr: Demcr = core.read_word_32(Demcr::get_mmio_address())?.into();
demcr.set_vc_corereset(false);
core.write_word_32(Demcr::get_mmio_address(), demcr.into())?;
@@ -413,12 +557,17 @@ impl ArmDebugSequence for MCX {
probe: &mut dyn ArmProbeInterface,
_default_ap: &FullyQualifiedApAddress,
) -> Result<(), ArmError> {
- tracing::info!("reset hardware deassert");
+ tracing::info!("reset hardware deassert for MCX variant: {}", self.variant);
let n_reset = Pins(0x80).0 as u32;
let can_read_pins = probe.swj_pins(0, n_reset, 0)? != 0xFFFF_FFFF;
- thread::sleep(Duration::from_millis(50));
+ let reset_duration = if self.is_variant(Self::VARIANT_N0) {
+ Duration::from_millis(100)
+ } else {
+ Duration::from_millis(50)
+ };
+ thread::sleep(reset_duration);
let mut assert_n_reset = || probe.swj_pins(n_reset, n_reset, 0);
if can_read_pins {
@@ -428,7 +577,12 @@ impl ArmDebugSequence for MCX {
while assert_n_reset()? & n_reset == 0 && !timeout_occured() {}
} else {
assert_n_reset()?;
- thread::sleep(Duration::from_millis(100));
+ let recovery_time = if self.is_variant(Self::VARIANT_N0) {
+ Duration::from_millis(200)
+ } else {
+ Duration::from_millis(100)
+ };
+ thread::sleep(recovery_time);
}
let ap = FullyQualifiedApAddress::v1_with_dp(probe.current_debug_port().unwrap(), 0);
diff --git a/probe-rs/targets/MCXN947.yaml b/probe-rs/targets/MCXN947.yaml
new file mode 100644
index 00000000..a980d42b
--- /dev/null
+++ b/probe-rs/targets/MCXN947.yaml
@@ -0,0 +1,278 @@
+name: MCXN947
+manufacturer:
+ id: 0x15
+ cc: 0x0
+generated_from_pack: true
+pack_file_release: 25.03.00
+variants:
+- name: MCXN947
+ cores:
+ - name: cm33_core0
+ type: armv8m
+ core_access_options: !Arm
+ ap: !v1 0
+ # - name: cm33_core1
+ # type: armv8m
+ # core_access_options: !Arm
+ # ap: !v1 1
+ memory_map:
+ - !Nvm
+ name: PROGRAM_FLASH0
+ range:
+ start: 0x0
+ end: 0x100000
+ cores:
+ - cm33_core0
+ # - cm33_core1
+ access:
+ write: false
+ read: true
+ execute: true
+ boot: true
+ - !Nvm
+ name: PROGRAM_FLASH1
+ range:
+ start: 0x100000
+ end: 0x200000
+ cores:
+ - cm33_core0
+ # - cm33_core1
+ access:
+ write: false
+ read: true
+ execute: true
+ boot: true
+ - !Generic
+ name: BootROM
+ range:
+ start: 0x3000000
+ end: 0x3040000
+ cores:
+ - cm33_core0
+ # - cm33_core1
+ access:
+ write: false
+ read: true
+ execute: true
+ - !Ram
+ name: SRAMX
+ range:
+ start: 0x4000000
+ end: 0x4018000
+ cores:
+ - cm33_core0
+ # - cm33_core1
+ access:
+ read: true
+ write: true
+ - !Generic
+ name: PROGRAM_FLASH_alias0
+ range:
+ start: 0x10000000
+ end: 0x10100000
+ cores:
+ - cm33_core0
+ # - cm33_core1
+ access:
+ write: false
+ read: true
+ - !Generic
+ name: PROGRAM_FLASH_alias1
+ range:
+ start: 0x10100000
+ end: 0x10200000
+ cores:
+ - cm33_core0
+ # - cm33_core1
+ access:
+ write: false
+ read: true
+ - !Generic
+ name: BootROM_alias
+ range:
+ start: 0x13000000
+ end: 0x13040000
+ cores:
+ - cm33_core0
+ # - cm33_core1
+ access:
+ write: false
+ read: true
+ execute: true
+ - !Generic
+ name: SRAMX_alias
+ range:
+ start: 0x14000000
+ end: 0x14018000
+ cores:
+ - cm33_core0
+ # - cm33_core1
+ access:
+ execute: false
+ - !Ram
+ name: SRAM
+ range:
+ start: 0x20000000
+ end: 0x20060000
+ cores:
+ - cm33_core0
+ # - cm33_core1
+ access:
+ read: true
+ write: true
+ - !Ram
+ name: SRAMH
+ range:
+ start: 0x20060000
+ end: 0x20068000
+ cores:
+ - cm33_core0
+ # - cm33_core1
+ access:
+ read: true
+ write: true
+ execute: false
+ - !Generic
+ name: SRAM_alias
+ range:
+ start: 0x30000000
+ end: 0x30060000
+ cores:
+ - cm33_core0
+ # - cm33_core1
+ access:
+ read: true
+ write: true
+ execute: false
+ - !Generic
+ name: SRAMH_alias
+ range:
+ start: 0x30060000
+ end: 0x30068000
+ cores:
+ - cm33_core0
+ # - cm33_core1
+ access:
+ read: true
+ write: true
+ execute: false
+ - !Ram
+ name: USB_RAM
+ range:
+ start: 0x400ba000
+ end: 0x400bb000
+ cores:
+ - cm33_core0
+ # - cm33_core1
+ access:
+ read: true
+ write: true
+ execute: false
+ - !Generic
+ name: USB_RAM_alias
+ range:
+ start: 0x500ba000
+ end: 0x500bb000
+ cores:
+ - cm33_core0
+ # - cm33_core1
+ access:
+ read: true
+ write: true
+ execute: false
+ flash_algorithms:
+ - mcxn9xx_2048
+ - mcxn9xx_2048_s
+ - mcxn9xx_w25q64
+ - mcxn9xx_w25q64_s
+flash_algorithms:
+- name: mcxn9xx_2048
+ description: MCXN9XX IAP 2048kB Flash
+ default: true
+ instructions: sLVE8gAwxPIEAAAhgWABaCH0AAEBYAFoQfAQAQFgAWhB8AEBAWAAvwFoyQFcvwFoX+rBEQXUAWjJAQLUAWjJAfLVT/YUUc/2/3FP8EByQlBP9hBRz/b/cUJYAvBwYrLxQH8R0EJYAvBwYrLxQH8L0EJYAvBwYrLxQH8F0EJYAvBwYrLxQH/n0UDyBAXA8gAFCesFBCBGRCEA8Mv5IEYA8JP4ACgcvwEgsL0J6wUAAPDX+AAoGL8BILC9AL9E8gBMwPaVDEb2AENgRcDy3CMev5hCASBwR0TyADHCGsTyBAEYvwEiimAKaJhCIvQAAgpgAdEQIALgYEUD0SAgCmgQQwhgCGhA8AEACGAE4AhowAFEvwAgcEcIaMABBtQIaMABXL8IaF/qwBDw1QAgcEcAvwAgcEeAtUDyBADA8gAARvJsY0hEACHG9mUzT/QAEgDwQ/gAKBi/ASCAvQC/gLUg8HBBQPIEAMDyAABG8mxjSETG9mUzT/QAUgDwLvgAKBi/ASCAvYC1C0Yg8HBBQPIEAMDyAABIRLP1AH+Yv0/0AHMA8CT4ACgYvwEggL2wtQxGBUYg8HBAEUYiRgDwDvkAKAi/JUQoRrC9T/YQQcHyAzEJaEloCEcAv0/2EEzB8gM83PgAwNz4CMBgRwC/T/YQTMHyAzzc+ADA3PgMwGBHAL9P9hBDwfIDMxtoG2kYRwC/T/YQTMHyAzzc+ADA3PhQwGBHAL9P9hBMwfIDPNz4AMDc+BTAYEcAv0/2EEPB8gMzG2ibaRhHAL9I9kFDwfICMxhHAL9I9qFDwfICMxhHAL9P9hBBwfIDMQloiWoIRwC/T/YQQcHyAzEJaMlqCEcAv0/2EEPB8gMzG2gbaxhHAL9P9hBCwfIDMhJoUmsQRwC/T/YQTMHyAzzc+ADA3Pg4wGBHAL9P9hBCwfIDMhJo0msQRwC/T/YQQ8HyAzMbaJtsGEcAv0/2EEzB8gM83PgAwNz4TMBgRwC/T/YQTMHyAzzc+ADA3PhYwGBHAL9P9ixCwfIDMhJoUmgQRwC/T/YsTMHyAzzc+ADA3PgIwGBHAL9P9ixCwfIDMhJo0mgQRwC/T/YsTMHyAzzc+ADA3PgQwGBHAL9P9ixDwfIDMxtoW2kYRwC/T/YsQ8HyAzMbaJtpGEcAv0/2LEDB8gMwAGgAaHBHAL9P9ixDwfIDMxto22kYRwC/T/YsTMHyAzzc+ADA3PggwGBHAL9P9ixCwfIDMhJoUmoQRwC/T/YsTMHyAzzc+ADA3PgowGBHAL9P9ixBwfIDMQloyWoIRwC/T/YsQ8HyAzMbaBtrGEdA6gEDELWbBw/RBCoN0xDICMkSH5xC+NAguhm6iEIB2QEgEL1P8P8wEL0asdMHA9BSHAfgACAQvRD4ATsR+AFLGxsH0RD4ATsR+AFLGxsB0ZIe8dEYRhC9T/AAAgC1E0aURpZGIDkiv6DoDFCg6AxQsfEgAb/0968JByi/oOgMUEi/DMBd+ATriQAov0D4BCsIv3BHSL8g+AIrEfCATxi/APgBK3BHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ load_address: 0x20000008
+ pc_init: 0x1
+ pc_uninit: 0x131
+ pc_program_page: 0x185
+ pc_erase_sector: 0x15d
+ pc_erase_all: 0x135
+ pc_verify: 0x1ad
+ data_section_offset: 0x480
+ flash_properties:
+ address_range:
+ start: 0x0
+ end: 0x200000
+ page_size: 0x200
+ erased_byte_value: 0xff
+ program_page_timeout: 300
+ erase_sector_timeout: 3000
+ sectors:
+ - size: 0x2000
+ address: 0x0
+- name: mcxn9xx_2048_s
+ description: MCXN9XX S IAP 2048kB Flash
+ default: true
+ instructions: sLVE8gAwxPIEAAAhgWABaCH0AAEBYAFoQfAQAQFgAWhB8AEBAWAAvwFoyQFcvwFoX+rBEQXUAWjJAQLUAWjJAfLVT/YUUc/2/3FP8EByQlBP9hBRz/b/cUJYAvBwYrLxQH8R0EJYAvBwYrLxQH8L0EJYAvBwYrLxQH8F0EJYAvBwYrLxQH/n0UDyBAXA8gAFCesFBCBGRCEA8Mv5IEYA8JP4ACgcvwEgsL0J6wUAAPDX+AAoGL8BILC9AL9E8gBMwPaVDEb2AENgRcDy3CMev5hCASBwR0TyADHCGsTyBAEYvwEiimAKaJhCIvQAAgpgAdEQIALgYEUD0SAgCmgQQwhgCGhA8AEACGAE4AhowAFEvwAgcEcIaMABBtQIaMABXL8IaF/qwBDw1QAgcEcAvwAgcEeAtUDyBADA8gAARvJsY0hEACHG9mUzT/QAEgDwQ/gAKBi/ASCAvQC/gLUg8HBBQPIEAMDyAABG8mxjSETG9mUzT/QAUgDwLvgAKBi/ASCAvYC1C0Yg8HBBQPIEAMDyAABIRLP1AH+Yv0/0AHMA8CT4ACgYvwEggL2wtQxGBUYg8HBAEUYiRgDwDvkAKAi/JUQoRrC9T/YQQcHyAzEJaEloCEcAv0/2EEzB8gM83PgAwNz4CMBgRwC/T/YQTMHyAzzc+ADA3PgMwGBHAL9P9hBDwfIDMxtoG2kYRwC/T/YQTMHyAzzc+ADA3PhQwGBHAL9P9hBMwfIDPNz4AMDc+BTAYEcAv0/2EEPB8gMzG2ibaRhHAL9I9kFDwfICMxhHAL9I9qFDwfICMxhHAL9P9hBBwfIDMQloiWoIRwC/T/YQQcHyAzEJaMlqCEcAv0/2EEPB8gMzG2gbaxhHAL9P9hBCwfIDMhJoUmsQRwC/T/YQTMHyAzzc+ADA3Pg4wGBHAL9P9hBCwfIDMhJo0msQRwC/T/YQQ8HyAzMbaJtsGEcAv0/2EEzB8gM83PgAwNz4TMBgRwC/T/YQTMHyAzzc+ADA3PhYwGBHAL9P9ixCwfIDMhJoUmgQRwC/T/YsTMHyAzzc+ADA3PgIwGBHAL9P9ixCwfIDMhJo0mgQRwC/T/YsTMHyAzzc+ADA3PgQwGBHAL9P9ixDwfIDMxtoW2kYRwC/T/YsQ8HyAzMbaJtpGEcAv0/2LEDB8gMwAGgAaHBHAL9P9ixDwfIDMxto22kYRwC/T/YsTMHyAzzc+ADA3PggwGBHAL9P9ixCwfIDMhJoUmoQRwC/T/YsTMHyAzzc+ADA3PgowGBHAL9P9ixBwfIDMQloyWoIRwC/T/YsQ8HyAzMbaBtrGEdA6gEDELWbBw/RBCoN0xDICMkSH5xC+NAguhm6iEIB2QEgEL1P8P8wEL0asdMHA9BSHAfgACAQvRD4ATsR+AFLGxsH0RD4ATsR+AFLGxsB0ZIe8dEYRhC9T/AAAgC1E0aURpZGIDkiv6DoDFCg6AxQsfEgAb/0968JByi/oOgMUEi/DMBd+ATriQAov0D4BCsIv3BHSL8g+AIrEfCATxi/APgBK3BHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ load_address: 0x20000008
+ pc_init: 0x1
+ pc_uninit: 0x131
+ pc_program_page: 0x185
+ pc_erase_sector: 0x15d
+ pc_erase_all: 0x135
+ pc_verify: 0x1ad
+ data_section_offset: 0x480
+ flash_properties:
+ address_range:
+ start: 0x10000000
+ end: 0x10200000
+ page_size: 0x200
+ erased_byte_value: 0xff
+ program_page_timeout: 300
+ erase_sector_timeout: 3000
+ sectors:
+ - size: 0x2000
+ address: 0x0
+- name: mcxn9xx_w25q64
+ description: MCXN W25Q64 8MB Flash
+ default: true
+ instructions: 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
+ load_address: 0x20000008
+ pc_init: 0x1
+ pc_uninit: 0x149
+ pc_program_page: 0x18d
+ pc_erase_sector: 0x169
+ pc_erase_all: 0x14d
+ data_section_offset: 0x5e0
+ flash_properties:
+ address_range:
+ start: 0x80000000
+ end: 0x80800000
+ page_size: 0x200
+ erased_byte_value: 0xff
+ program_page_timeout: 3000
+ erase_sector_timeout: 3000
+ sectors:
+ - size: 0x1000
+ address: 0x0
+- name: mcxn9xx_w25q64_s
+ description: MCXN W25Q64 8MB S Flash
+ default: true
+ instructions: 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
+ load_address: 0x20000008
+ pc_init: 0x1
+ pc_uninit: 0x149
+ pc_program_page: 0x18d
+ pc_erase_sector: 0x169
+ pc_erase_all: 0x14d
+ data_section_offset: 0x5e0
+ flash_properties:
+ address_range:
+ start: 0x90000000
+ end: 0x90800000
+ page_size: 0x200
+ erased_byte_value: 0xff
+ program_page_timeout: 3000
+ erase_sector_timeout: 3000
+ sectors:
+ - size: 0x1000
+ address: 0x0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment