improvements to the code, fixing incompatibilities with the PAC crate
This commit is contained in:
53
src/flash.rs
53
src/flash.rs
@@ -20,7 +20,7 @@
|
||||
|
||||
use crate::pac as pac;
|
||||
use crate::pac::FLASH;
|
||||
use core::{mem, ptr};
|
||||
use core::ptr;
|
||||
|
||||
/// Simple Flash error set for this minimal port
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||
@@ -193,11 +193,9 @@ impl<'a> FlashProgramming<'a> {
|
||||
let sr = self.nssr.reg().read();
|
||||
if sr.eop().bit_is_set() {
|
||||
// Write-one-to-clear EOP
|
||||
unsafe {
|
||||
self.nssr.reg().write(|w| w.eop().set_bit());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Erase a single page by index.
|
||||
///
|
||||
@@ -285,45 +283,24 @@ impl<'a> FlashProgramming<'a> {
|
||||
/// For leading/trailing partial chunks, we fill missing bytes with 0xFF,
|
||||
/// which matches erased Flash default.
|
||||
pub fn write(&mut self, address: usize, buf: &[u8]) -> Result<(), Error> {
|
||||
// Handle leading unaligned portion
|
||||
let align_off = address & 0xF;
|
||||
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;
|
||||
if buf.is_empty() {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
// Aligned middle
|
||||
let aligned_len = if cur_addr > address {
|
||||
buf.len() - (cur_addr - address)
|
||||
} 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;
|
||||
}
|
||||
let start = address & !0xF; // align down to 16
|
||||
let end = address + buf.len();
|
||||
let mut pos = start;
|
||||
|
||||
// Trailing remainder
|
||||
let rem = aligned_len - i;
|
||||
if rem > 0 {
|
||||
while pos < end {
|
||||
let mut q = [0xFFu8; 16];
|
||||
q[..rem].copy_from_slice(
|
||||
&buf[aligned_start + i..aligned_start + i + rem],
|
||||
);
|
||||
self.write_quadword(cur_addr, &q)?;
|
||||
for i in 0..16 {
|
||||
let a = pos + i;
|
||||
if a >= address && a < end {
|
||||
q[i] = buf[a - address];
|
||||
}
|
||||
}
|
||||
self.write_quadword(pos, &q)?;
|
||||
pos += 16;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
||||
@@ -109,17 +109,13 @@ pub struct Pwr {
|
||||
impl Pwr {
|
||||
/// Enable write access to the backup domain (DBP = 1)
|
||||
pub fn enable_backup_write(&mut self) {
|
||||
unsafe {
|
||||
self.dbpr.reg().modify(|_, w| w.dbp().set_bit());
|
||||
}
|
||||
}
|
||||
|
||||
/// Disable write access to the backup domain (DBP = 0)
|
||||
pub fn disable_backup_write(&mut self) {
|
||||
unsafe {
|
||||
self.dbpr.reg().modify(|_, w| w.dbp().clear_bit());
|
||||
}
|
||||
}
|
||||
|
||||
/// Enter Standby low-power mode.
|
||||
///
|
||||
@@ -148,7 +144,6 @@ impl Pwr {
|
||||
// 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,
|
||||
// but LPMS field exists in U5.
|
||||
unsafe {
|
||||
self.cr1.reg().modify(|_, w| {
|
||||
// LPMS is a field; set to Standby (0b100)
|
||||
#[allow(unused_unsafe)]
|
||||
@@ -156,7 +151,6 @@ impl Pwr {
|
||||
w.lpms().bits(0b100)
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
scb.set_sleepdeep();
|
||||
cortex_m::asm::dsb();
|
||||
@@ -186,14 +180,12 @@ impl Pwr {
|
||||
|
||||
// Configure Shutdown in CR1.LPMS
|
||||
// Typical encoding: 0b110 (consult RM for your exact part).
|
||||
unsafe {
|
||||
self.cr1.reg().modify(|_, w| {
|
||||
#[allow(unused_unsafe)]
|
||||
unsafe {
|
||||
w.lpms().bits(0b110)
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
scb.set_sleepdeep();
|
||||
cortex_m::asm::dsb();
|
||||
|
||||
@@ -614,9 +614,11 @@ impl CFGR {
|
||||
let sysclk_src_bits;
|
||||
|
||||
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);
|
||||
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);
|
||||
assert!(vco >= 128_000_000 && vco <= 544_000_000);
|
||||
let sysclk_calc = (vco / (pll.r as u64)) as u32;
|
||||
@@ -628,11 +630,21 @@ impl CFGR {
|
||||
|
||||
// Set PLL source
|
||||
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 {
|
||||
w.pll1src().bits(src_bits);
|
||||
// VCI range selection (very rough): 4..8 => range0, 8..16 => range1
|
||||
let rge = if vco_in < 8_000_000 { 0b00 } else { 0b11 };
|
||||
w.pll1rge().bits(rge);
|
||||
w.pll1rge().bits(pll1_rge_bits(vco_in));
|
||||
// M
|
||||
w.pll1m().bits(pll.m - 1);
|
||||
// Enable only R output
|
||||
|
||||
Reference in New Issue
Block a user