diff --git a/hal/src/peripherals/nvm/mod.rs b/hal/src/peripherals/nvm/mod.rs index e4082db3f19f..db9911b244af 100644 --- a/hal/src/peripherals/nvm/mod.rs +++ b/hal/src/peripherals/nvm/mod.rs @@ -22,6 +22,11 @@ pub mod smart_eeprom; +use crate::clock::v2::{ + ahb::AhbClk, + apb::ApbClk, + types::{NvmCtrl, NvmCtrlSmeeProm}, +}; use crate::pac::Nvmctrl; pub use crate::pac::nvmctrl::ctrla::Prmselect; use crate::pac::nvmctrl::ctrlb::Cmdselect; @@ -75,6 +80,10 @@ pub const QUADWORDSIZE: u32 = 16; pub struct Nvm { /// PAC peripheral nvm: Nvmctrl, + /// AHB bus clock + ahb_clk: AhbClk, + /// APB bus clock + apb_clk: ApbClk, } /// Errors generated by the NVM peripheral @@ -172,8 +181,18 @@ impl Nvm { /// Create a new NVM controller or handle failure from DSU #[inline] - pub fn new(nvm: Nvmctrl) -> Self { - Self { nvm } + pub fn new(nvm: Nvmctrl, ahb_clk: AhbClk, apb_clk: ApbClk) -> Self { + Self { + nvm, + ahb_clk, + apb_clk, + } + } + + /// Destroy the NVM controller and returns the underlying resources + #[inline] + pub fn free(self) -> (Nvmctrl, AhbClk, ApbClk) { + (self.nvm, self.ahb_clk, self.apb_clk) } /// Raw access to the registers. @@ -727,8 +746,8 @@ impl Nvm { /// Retrieve SmartEEPROM #[inline] - pub fn smart_eeprom(&mut self) -> smart_eeprom::Result<'_> { - smart_eeprom::SmartEepromMode::retrieve(self) + pub fn smart_eeprom(&mut self, ahb_clk: AhbClk) -> smart_eeprom::Result<'_> { + smart_eeprom::SmartEepromMode::retrieve(self, ahb_clk) } } diff --git a/hal/src/peripherals/nvm/smart_eeprom.rs b/hal/src/peripherals/nvm/smart_eeprom.rs index e287a2b16ade..d6e6dd7fff43 100644 --- a/hal/src/peripherals/nvm/smart_eeprom.rs +++ b/hal/src/peripherals/nvm/smart_eeprom.rs @@ -32,6 +32,7 @@ use core::marker::PhantomData; use super::Nvm; +use crate::clock::v2::{ahb::AhbClk, types::NvmCtrlSmeeProm}; use crate::pac::{Nvmctrl, nvmctrl::ctrlb::Cmdselect}; use crate::typelevel::Sealed; @@ -42,6 +43,7 @@ use crate::typelevel::Sealed; /// - current state ([`Locked`]/[`Unlocked`]) pub struct SmartEeprom<'a, T: SmartEepromState> { nvm: &'a mut Nvm, + ahb_clk: AhbClk, virtual_size: usize, __: PhantomData, } @@ -103,7 +105,7 @@ fn wait_if_busy() { impl<'a> SmartEepromMode<'a> { /// Retrieve [`SmartEeprom`] instance using information found in relevant HW /// registers. - pub(super) fn retrieve(nvm: &'a mut Nvm) -> Result<'a> { + pub(super) fn retrieve(nvm: &'a mut Nvm, ahb_clk: AhbClk) -> Result<'a> { use SmartEepromMode as Mode; use SmartEepromRetrievalFailure::*; if nvm.nvm.seecfg().read().aprdis().bit_is_set() { @@ -125,12 +127,14 @@ impl<'a> SmartEepromMode<'a> { if nvm.nvm.seestat().read().lock().bit_is_set() { Ok(Mode::Locked(SmartEeprom { nvm, + ahb_clk, virtual_size, __: PhantomData::, })) } else { Ok(Mode::Unlocked(SmartEeprom { nvm, + ahb_clk, virtual_size, __: PhantomData::, })) @@ -209,6 +213,12 @@ impl SmartEepromPointableSize for u8 {} impl SmartEepromPointableSize for u16 {} impl SmartEepromPointableSize for u32 {} +impl<'a, T: SmartEepromState> SmartEeprom<'a, T> { + /// Destroy the SmartEEPROM instance and return the bus clock + pub fn free(self) -> AhbClk { + self.ahb_clk + } +} impl<'a> SmartEeprom<'a, Unlocked> { /// Returns a mutable slice to SmartEEPROM mapped address space. /// @@ -257,10 +267,14 @@ impl<'a> SmartEeprom<'a, Unlocked> { .command_sync(Cmdselect::Lsee) .expect("SmartEEPROM locking failed"); let Self { - nvm, virtual_size, .. + nvm, + ahb_clk, + virtual_size, + .. } = self; SmartEeprom { nvm, + ahb_clk, virtual_size, __: PhantomData, } @@ -275,10 +289,14 @@ impl<'a> SmartEeprom<'a, Locked> { .command_sync(Cmdselect::Usee) .expect("SmartEEPROM unlocking failed"); let Self { - nvm, virtual_size, .. + nvm, + ahb_clk, + virtual_size, + .. } = self; SmartEeprom { nvm, + ahb_clk, virtual_size, __: PhantomData, }