Skip to content

Commit

Permalink
feat(flash): timing sequence config
Browse files Browse the repository at this point in the history
  • Loading branch information
decaday committed Jan 6, 2025
1 parent e646d6c commit 1c8733a
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 41 deletions.
48 changes: 19 additions & 29 deletions src/flash/low_level.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use core::ptr::write_volatile;
use core::sync::atomic::{fence, Ordering};

use crate::pac;
use crate::pac::rcc::vals::HsiFs;

use super::{Error, FlashUnit};
use super::values::*;
Expand All @@ -17,35 +18,6 @@ pub(crate) unsafe fn unlock() {
}
}

// unsafe fn timing_sequence_config() {
// let hsifs = pac::RCC.icscr().read().hsi_fs();

// let timing = get_timing_sequence(hsifs);

// pac::FLASH.ts0().write(|w| w.set_ts0(timing.ts0));
// pac::FLASH.ts1().write(|w| w.set_ts1(timing.ts1));
// pac::FLASH.ts3().write(|w| w.set_ts3(timing.ts3));
// pac::FLASH.ts2p().write(|w| w.set_ts2p(timing.ts2p));
// pac::FLASH.tps3().write(|w| w.set_tps3(timing.tps3));
// pac::FLASH.pertpe().write(|w| w.set_pertpe(timing.pertpe));
// pac::FLASH.smertpe().write(|w| w.set_smertpe(timing.smertpe));
// pac::FLASH.prgtpe().write(|w| w.set_prgtpe(timing.prgtpe));
// pac::FLASH.pretpe().write(|w| w.set_pretpe(timing.pretpe));

// }

struct Timing {
ts0: u8,
ts1: u16,
ts3: u8,
ts2p: u8,
tps3: u16,
pertpe: u32,
smertpe: u32,
prgtpe: u16,
pretpe: u16,
}

pub(crate) unsafe fn enable_blocking_write() {
pac::FLASH.cr().modify(|w| w.set_pg(true));
pac::FLASH.cr().modify(|w| w.set_eopie(true));
Expand Down Expand Up @@ -147,4 +119,22 @@ pub(crate) unsafe fn clear_all_err() {
// read and write back the same value.
// This clears all "write 1 to clear" bits.
pac::FLASH.sr().modify(|_| {});
}

pub(crate) unsafe fn timing_sequence_config(configured: Option<HsiFs>) {
let hsifs = pac::RCC.icscr().read().hsi_fs();

if Some(hsifs) != configured {
let eppara = pac::CONFIGBYTES.eppara(hsifs as usize);

pac::FLASH.ts0().write(|w| w.set_ts0(eppara.eppara0().read().ts0()));
pac::FLASH.ts1().write(|w| w.set_ts1(eppara.eppara0().read().ts1()));
pac::FLASH.ts3().write(|w| w.set_ts3(eppara.eppara0().read().ts3()));
pac::FLASH.ts2p().write(|w| w.set_ts2p(eppara.eppara1().read().ts2p()));
pac::FLASH.tps3().write(|w| w.set_tps3(eppara.eppara1().read().tps3()));
pac::FLASH.pertpe().write(|w| w.set_pertpe(eppara.eppara2().read().pertpe()));
pac::FLASH.smertpe().write(|w| w.set_smertpe(eppara.eppara3().read().smertpe()));
pac::FLASH.pretpe().write(|w| w.set_pretpe(eppara.eppara4().read().pretpe()));
pac::FLASH.prgtpe().write(|w| w.set_prgtpe(eppara.eppara4().read().prgtpe()));
}
}
37 changes: 25 additions & 12 deletions src/flash/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use core::sync::atomic::{fence, Ordering};
use embassy_hal_internal::drop::OnDrop;
use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef};
use embedded_storage::nor_flash::{NorFlashError, NorFlashErrorKind};
use crate::pac::rcc::vals::HsiFs;

use crate::mode::{Async, Blocking};
use crate::peripherals::FLASH;
Expand Down Expand Up @@ -47,18 +48,26 @@ pub enum FlashUnit {

/// Internal flash memory driver.
pub struct Flash<'d, MODE = Async> {
pub(crate) inner: PeripheralRef<'d, FLASH>,
pub(crate) _inner: PeripheralRef<'d, FLASH>,
pub(crate) _mode: PhantomData<MODE>,
// size_of::<Option<crate::pac::rcc::vals::HsiFs>>() == 1 byte
// TODO: PY32F072 timing regs reset value is 24mhz. Should we use that?
pub(crate) timing_configured: Option<HsiFs>,
}

impl<'d> Flash<'d, Blocking> {
/// Create a new flash driver, usable in blocking mode.
pub fn new_blocking(p: impl Peripheral<P = FLASH> + 'd) -> Self {
into_ref!(p);

// unsafe { low_level::timing_sequence_config() };
// let ts1 = crate::pac::FLASH.ts1().read().ts1();
// info!("FLASH TS1: 0x{:x}", ts1 as u16);

Self {
inner: p,
_inner: p,
_mode: PhantomData,
timing_configured: None,
}
}
}
Expand Down Expand Up @@ -95,7 +104,7 @@ impl<'d, MODE> Flash<'d, MODE> {
let mut address = FLASH_BASE + offset;
trace!("Writing {} bytes at 0x{:x}", bytes.len(), address);
for chunk in bytes.chunks(WRITE_SIZE) {
unsafe { write_chunk_with_critical_section(address, chunk) }?;
unsafe { write_chunk_with_critical_section(address, chunk, self.timing_configured) }?;
address += WRITE_SIZE as u32;
}
Ok(())
Expand Down Expand Up @@ -124,20 +133,20 @@ impl<'d, MODE> Flash<'d, MODE> {
if use_sector {
let sector = get_sector(address);
trace!("Erasing sector: {:?}", sector);
unsafe { erase_unit_unlocked(&FlashUnit::Sector(sector)) }?;
unsafe { erase_unit_with_critical_section(&FlashUnit::Sector(sector), self.timing_configured) }?;
address += SECTOR_SIZE;
} else {
let page = get_page(address);
trace!("Erasing page: {:?}", page);
unsafe { erase_unit_unlocked(&FlashUnit::Page(page)) }?;
unsafe { erase_unit_with_critical_section(&FlashUnit::Page(page), self.timing_configured) }?;
address += PAGE_SIZE;
}
}
Ok(())
}
}

#[cfg(py32f072)]
// #[cfg(py32f072)]
pub mod values {
pub const WRITE_SIZE: usize = 0x100;
pub const READ_SIZE: usize = 1;
Expand All @@ -152,11 +161,13 @@ pub mod values {
}
use values::*;

pub(super) unsafe fn write_chunk_unlocked(address: u32, chunk: &[u8]) -> Result<(), Error> {
pub(super) unsafe fn write_chunk_unlocked(address: u32, chunk: &[u8], timing_configured: Option<HsiFs>) -> Result<(), Error> {
low_level::clear_all_err();
fence(Ordering::SeqCst);
low_level::unlock();
fence(Ordering::SeqCst);
low_level::timing_sequence_config(timing_configured);
fence(Ordering::SeqCst);
low_level::enable_blocking_write();
fence(Ordering::SeqCst);

Expand All @@ -169,23 +180,25 @@ pub(super) unsafe fn write_chunk_unlocked(address: u32, chunk: &[u8]) -> Result<
low_level::blocking_write(address, unwrap!(chunk.try_into()))
}

pub(super) unsafe fn write_chunk_with_critical_section(address: u32, chunk: &[u8]) -> Result<(), Error> {
critical_section::with(|_| write_chunk_unlocked(address, chunk))
pub(super) unsafe fn write_chunk_with_critical_section(address: u32, chunk: &[u8], timing_configured: Option<HsiFs>) -> Result<(), Error> {
critical_section::with(|_| write_chunk_unlocked(address, chunk, timing_configured))
}

pub(super) unsafe fn erase_unit_unlocked(unit: &FlashUnit) -> Result<(), Error> {
pub(super) unsafe fn erase_unit_unlocked(unit: &FlashUnit, timing_configured: Option<HsiFs>) -> Result<(), Error> {
low_level::clear_all_err();
fence(Ordering::SeqCst);
low_level::unlock();
fence(Ordering::SeqCst);
low_level::timing_sequence_config(timing_configured);
fence(Ordering::SeqCst);

let _on_drop = OnDrop::new(|| low_level::lock());

low_level::blocking_erase_unit(unit)
}

pub(super) unsafe fn erase_unit_with_critical_section(unit: &FlashUnit) -> Result<(), Error> {
critical_section::with(|_| erase_unit_unlocked(unit))
pub(super) unsafe fn erase_unit_with_critical_section(unit: &FlashUnit, timing_configured: Option<HsiFs>) -> Result<(), Error> {
critical_section::with(|_| erase_unit_unlocked(unit, timing_configured))
}

pub(super) fn get_sector(address: u32) -> FlashSector {
Expand Down

0 comments on commit 1c8733a

Please sign in to comment.