improvements to the code, fixing incompatibilities with the PAC crate

This commit is contained in:
Priec
2025-10-19 16:27:36 +02:00
parent 7445c46052
commit a8afd43992
3 changed files with 48 additions and 67 deletions

View File

@@ -20,7 +20,7 @@
use crate::pac as pac; use crate::pac as pac;
use crate::pac::FLASH; use crate::pac::FLASH;
use core::{mem, ptr}; use core::ptr;
/// Simple Flash error set for this minimal port /// Simple Flash error set for this minimal port
#[derive(Copy, Clone, Debug, Eq, PartialEq)] #[derive(Copy, Clone, Debug, Eq, PartialEq)]
@@ -193,9 +193,7 @@ impl<'a> FlashProgramming<'a> {
let sr = self.nssr.reg().read(); let sr = self.nssr.reg().read();
if sr.eop().bit_is_set() { if sr.eop().bit_is_set() {
// Write-one-to-clear EOP // Write-one-to-clear EOP
unsafe { self.nssr.reg().write(|w| w.eop().set_bit());
self.nssr.reg().write(|w| w.eop().set_bit());
}
} }
} }
@@ -285,45 +283,24 @@ impl<'a> FlashProgramming<'a> {
/// For leading/trailing partial chunks, we fill missing bytes with 0xFF, /// For leading/trailing partial chunks, we fill missing bytes with 0xFF,
/// which matches erased Flash default. /// which matches erased Flash default.
pub fn write(&mut self, address: usize, buf: &[u8]) -> Result<(), Error> { pub fn write(&mut self, address: usize, buf: &[u8]) -> Result<(), Error> {
// Handle leading unaligned portion if buf.is_empty() {
let align_off = address & 0xF; return Ok(());
let mut cur_addr = address;
if align_off != 0 {
let head = core::cmp::min(16 - align_off, buf.len());
let mut q = [0xFFu8; 16];
// Pull existing erased fill (0xFF), then overlay provided bytes
q[align_off..align_off + head].copy_from_slice(&buf[..head]);
self.write_quadword(address - align_off, &q)?;
cur_addr += head;
} }
// Aligned middle let start = address & !0xF; // align down to 16
let aligned_len = if cur_addr > address { let end = address + buf.len();
buf.len() - (cur_addr - address) let mut pos = start;
} else {
buf.len()
};
let aligned_start = buf.len() - aligned_len + (cur_addr - address);
let mut i = 0;
while i + 16 <= aligned_len {
let mut q = [0u8; 16];
q.copy_from_slice(
&buf[aligned_start + i..aligned_start + i + 16],
);
self.write_quadword(cur_addr, &q)?;
cur_addr += 16;
i += 16;
}
// Trailing remainder while pos < end {
let rem = aligned_len - i;
if rem > 0 {
let mut q = [0xFFu8; 16]; let mut q = [0xFFu8; 16];
q[..rem].copy_from_slice( for i in 0..16 {
&buf[aligned_start + i..aligned_start + i + rem], let a = pos + i;
); if a >= address && a < end {
self.write_quadword(cur_addr, &q)?; q[i] = buf[a - address];
}
}
self.write_quadword(pos, &q)?;
pos += 16;
} }
Ok(()) Ok(())

View File

@@ -109,16 +109,12 @@ pub struct Pwr {
impl Pwr { impl Pwr {
/// Enable write access to the backup domain (DBP = 1) /// Enable write access to the backup domain (DBP = 1)
pub fn enable_backup_write(&mut self) { pub fn enable_backup_write(&mut self) {
unsafe { self.dbpr.reg().modify(|_, w| w.dbp().set_bit());
self.dbpr.reg().modify(|_, w| w.dbp().set_bit());
}
} }
/// Disable write access to the backup domain (DBP = 0) /// Disable write access to the backup domain (DBP = 0)
pub fn disable_backup_write(&mut self) { pub fn disable_backup_write(&mut self) {
unsafe { self.dbpr.reg().modify(|_, w| w.dbp().clear_bit());
self.dbpr.reg().modify(|_, w| w.dbp().clear_bit());
}
} }
/// Enter Standby low-power mode. /// Enter Standby low-power mode.
@@ -148,15 +144,13 @@ impl Pwr {
// HAL C uses: MODIFY_REG(PWR->CR1, PWR_CR1_LPMS, PWR_CR1_LPMS_2); // HAL C uses: MODIFY_REG(PWR->CR1, PWR_CR1_LPMS, PWR_CR1_LPMS_2);
// We map to LPMS = 0b100 (Standby). Exact encoding may differ by die rev, // We map to LPMS = 0b100 (Standby). Exact encoding may differ by die rev,
// but LPMS field exists in U5. // but LPMS field exists in U5.
unsafe { self.cr1.reg().modify(|_, w| {
self.cr1.reg().modify(|_, w| { // LPMS is a field; set to Standby (0b100)
// LPMS is a field; set to Standby (0b100) #[allow(unused_unsafe)]
#[allow(unused_unsafe)] unsafe {
unsafe { w.lpms().bits(0b100)
w.lpms().bits(0b100) }
} });
});
}
scb.set_sleepdeep(); scb.set_sleepdeep();
cortex_m::asm::dsb(); cortex_m::asm::dsb();
@@ -186,14 +180,12 @@ impl Pwr {
// Configure Shutdown in CR1.LPMS // Configure Shutdown in CR1.LPMS
// Typical encoding: 0b110 (consult RM for your exact part). // Typical encoding: 0b110 (consult RM for your exact part).
unsafe { self.cr1.reg().modify(|_, w| {
self.cr1.reg().modify(|_, w| { #[allow(unused_unsafe)]
#[allow(unused_unsafe)] unsafe {
unsafe { w.lpms().bits(0b110)
w.lpms().bits(0b110) }
} });
});
}
scb.set_sleepdeep(); scb.set_sleepdeep();
cortex_m::asm::dsb(); cortex_m::asm::dsb();

View File

@@ -614,9 +614,11 @@ impl CFGR {
let sysclk_src_bits; let sysclk_src_bits;
if let Some(pll) = pllconf { if let Some(pll) = pllconf {
// Basic checks for VCO ranges (very simplified; FRACN/MBOOST ignored) // Basic checks for VCO input/output ranges (STM32U5; FRACN/MBOOST ignored)
let vco_in = (src_freq as u32) / (pll.m as u32); let vco_in = (src_freq as u32) / (pll.m as u32);
assert!(vco_in >= 1_000_000 && vco_in <= 16_000_000); // Typical U5: 2..16 MHz recommended VCI; tighten to 2 MHz unless you intentionally
// support 1..2 MHz (then map to 0b00 below).
assert!(vco_in >= 2_000_000 && vco_in <= 16_000_000);
let vco = (vco_in as u64) * (pll.n as u64); let vco = (vco_in as u64) * (pll.n as u64);
assert!(vco >= 128_000_000 && vco <= 544_000_000); assert!(vco >= 128_000_000 && vco <= 544_000_000);
let sysclk_calc = (vco / (pll.r as u64)) as u32; let sysclk_calc = (vco / (pll.r as u64)) as u32;
@@ -628,11 +630,21 @@ impl CFGR {
// Set PLL source // Set PLL source
let src_bits = pll_src.to_pllsrc_bits(); let src_bits = pll_src.to_pllsrc_bits();
fn pll1_rge_bits(vci_hz: u32) -> u8 {
if vci_hz < 2_000_000 {
0b00 // 1..2 MHz
} else if vci_hz < 4_000_000 {
0b01 // 2..4 MHz
} else if vci_hz < 8_000_000 {
0b10 // 4..8 MHz
} else {
0b11 // 8..16 MHz
}
}
rcc.pll1cfgr().modify(|_, w| unsafe { rcc.pll1cfgr().modify(|_, w| unsafe {
w.pll1src().bits(src_bits); w.pll1src().bits(src_bits);
// VCI range selection (very rough): 4..8 => range0, 8..16 => range1 w.pll1rge().bits(pll1_rge_bits(vco_in));
let rge = if vco_in < 8_000_000 { 0b00 } else { 0b11 };
w.pll1rge().bits(rge);
// M // M
w.pll1m().bits(pll.m - 1); w.pll1m().bits(pll.m - 1);
// Enable only R output // Enable only R output