stm32: add some docs.
This commit is contained in:
@ -59,7 +59,7 @@ impl embedded_storage_async::nor_flash::ReadNorFlash for Flash<'_, Async> {
|
||||
const READ_SIZE: usize = super::READ_SIZE;
|
||||
|
||||
async fn read(&mut self, offset: u32, bytes: &mut [u8]) -> Result<(), Self::Error> {
|
||||
self.read(offset, bytes)
|
||||
self.blocking_read(offset, bytes)
|
||||
}
|
||||
|
||||
fn capacity(&self) -> usize {
|
||||
|
@ -12,12 +12,14 @@ use super::{
|
||||
use crate::peripherals::FLASH;
|
||||
use crate::Peripheral;
|
||||
|
||||
/// Internal flash memory driver.
|
||||
pub struct Flash<'d, MODE = Async> {
|
||||
pub(crate) inner: PeripheralRef<'d, FLASH>,
|
||||
pub(crate) _mode: PhantomData<MODE>,
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
@ -29,15 +31,26 @@ impl<'d> Flash<'d, Blocking> {
|
||||
}
|
||||
|
||||
impl<'d, MODE> Flash<'d, MODE> {
|
||||
/// Split this flash driver into one instance per flash memory region.
|
||||
///
|
||||
/// See module-level documentation for details on how memory regions work.
|
||||
pub fn into_blocking_regions(self) -> FlashLayout<'d, Blocking> {
|
||||
assert!(family::is_default_layout());
|
||||
FlashLayout::new(self.inner)
|
||||
}
|
||||
|
||||
pub fn read(&mut self, offset: u32, bytes: &mut [u8]) -> Result<(), Error> {
|
||||
/// Blocking read.
|
||||
///
|
||||
/// NOTE: `offset` is an offset from the flash start, NOT an absolute address.
|
||||
/// For example, to read address `0x0800_1234` you have to use offset `0x1234`.
|
||||
pub fn blocking_read(&mut self, offset: u32, bytes: &mut [u8]) -> Result<(), Error> {
|
||||
blocking_read(FLASH_BASE as u32, FLASH_SIZE as u32, offset, bytes)
|
||||
}
|
||||
|
||||
/// Blocking write.
|
||||
///
|
||||
/// NOTE: `offset` is an offset from the flash start, NOT an absolute address.
|
||||
/// For example, to write address `0x0800_1234` you have to use offset `0x1234`.
|
||||
pub fn blocking_write(&mut self, offset: u32, bytes: &[u8]) -> Result<(), Error> {
|
||||
unsafe {
|
||||
blocking_write(
|
||||
@ -50,6 +63,10 @@ impl<'d, MODE> Flash<'d, MODE> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Blocking erase.
|
||||
///
|
||||
/// NOTE: `from` and `to` are offsets from the flash start, NOT an absolute address.
|
||||
/// For example, to erase address `0x0801_0000` you have to use offset `0x1_0000`.
|
||||
pub fn blocking_erase(&mut self, from: u32, to: u32) -> Result<(), Error> {
|
||||
unsafe { blocking_erase(FLASH_BASE as u32, from, to, erase_sector_unlocked) }
|
||||
}
|
||||
@ -206,7 +223,7 @@ impl<MODE> embedded_storage::nor_flash::ReadNorFlash for Flash<'_, MODE> {
|
||||
const READ_SIZE: usize = READ_SIZE;
|
||||
|
||||
fn read(&mut self, offset: u32, bytes: &mut [u8]) -> Result<(), Self::Error> {
|
||||
self.read(offset, bytes)
|
||||
self.blocking_read(offset, bytes)
|
||||
}
|
||||
|
||||
fn capacity(&self) -> usize {
|
||||
@ -230,16 +247,28 @@ impl<MODE> embedded_storage::nor_flash::NorFlash for Flash<'_, MODE> {
|
||||
foreach_flash_region! {
|
||||
($type_name:ident, $write_size:literal, $erase_size:literal) => {
|
||||
impl<MODE> crate::_generated::flash_regions::$type_name<'_, MODE> {
|
||||
/// Blocking read.
|
||||
///
|
||||
/// NOTE: `offset` is an offset from the flash start, NOT an absolute address.
|
||||
/// For example, to read address `0x0800_1234` you have to use offset `0x1234`.
|
||||
pub fn blocking_read(&mut self, offset: u32, bytes: &mut [u8]) -> Result<(), Error> {
|
||||
blocking_read(self.0.base, self.0.size, offset, bytes)
|
||||
}
|
||||
}
|
||||
|
||||
impl crate::_generated::flash_regions::$type_name<'_, Blocking> {
|
||||
/// Blocking write.
|
||||
///
|
||||
/// NOTE: `offset` is an offset from the flash start, NOT an absolute address.
|
||||
/// For example, to write address `0x0800_1234` you have to use offset `0x1234`.
|
||||
pub fn blocking_write(&mut self, offset: u32, bytes: &[u8]) -> Result<(), Error> {
|
||||
unsafe { blocking_write(self.0.base, self.0.size, offset, bytes, write_chunk_with_critical_section) }
|
||||
}
|
||||
|
||||
/// Blocking erase.
|
||||
///
|
||||
/// NOTE: `from` and `to` are offsets from the flash start, NOT an absolute address.
|
||||
/// For example, to erase address `0x0801_0000` you have to use offset `0x1_0000`.
|
||||
pub fn blocking_erase(&mut self, from: u32, to: u32) -> Result<(), Error> {
|
||||
unsafe { blocking_erase(self.0.base, from, to, erase_sector_with_critical_section) }
|
||||
}
|
||||
|
@ -6,11 +6,11 @@ use super::{FlashRegion, FlashSector, FLASH_REGIONS, WRITE_SIZE};
|
||||
use crate::flash::Error;
|
||||
use crate::pac;
|
||||
|
||||
pub const fn is_default_layout() -> bool {
|
||||
pub(crate) const fn is_default_layout() -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
pub const fn get_flash_regions() -> &'static [&'static FlashRegion] {
|
||||
pub(crate) const fn get_flash_regions() -> &'static [&'static FlashRegion] {
|
||||
&FLASH_REGIONS
|
||||
}
|
||||
|
||||
|
@ -6,11 +6,11 @@ use super::{FlashRegion, FlashSector, FLASH_REGIONS, WRITE_SIZE};
|
||||
use crate::flash::Error;
|
||||
use crate::pac;
|
||||
|
||||
pub const fn is_default_layout() -> bool {
|
||||
pub(crate) const fn is_default_layout() -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
pub const fn get_flash_regions() -> &'static [&'static FlashRegion] {
|
||||
pub(crate) const fn get_flash_regions() -> &'static [&'static FlashRegion] {
|
||||
&FLASH_REGIONS
|
||||
}
|
||||
|
||||
|
@ -6,11 +6,11 @@ use super::{FlashRegion, FlashSector, FLASH_REGIONS, WRITE_SIZE};
|
||||
use crate::flash::Error;
|
||||
use crate::pac;
|
||||
|
||||
pub const fn is_default_layout() -> bool {
|
||||
pub(crate) const fn is_default_layout() -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
pub const fn get_flash_regions() -> &'static [&'static FlashRegion] {
|
||||
pub(crate) const fn get_flash_regions() -> &'static [&'static FlashRegion] {
|
||||
&FLASH_REGIONS
|
||||
}
|
||||
|
||||
|
@ -8,11 +8,11 @@ use super::{FlashRegion, FlashSector, FLASH_REGIONS, WRITE_SIZE};
|
||||
use crate::flash::Error;
|
||||
use crate::pac;
|
||||
|
||||
pub const fn is_default_layout() -> bool {
|
||||
pub(crate) const fn is_default_layout() -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
pub const fn get_flash_regions() -> &'static [&'static FlashRegion] {
|
||||
pub(crate) const fn get_flash_regions() -> &'static [&'static FlashRegion] {
|
||||
&FLASH_REGIONS
|
||||
}
|
||||
|
||||
|
@ -6,7 +6,7 @@ use super::{FlashRegion, FlashSector, BANK1_REGION, FLASH_REGIONS, WRITE_SIZE};
|
||||
use crate::flash::Error;
|
||||
use crate::pac;
|
||||
|
||||
pub const fn is_default_layout() -> bool {
|
||||
pub(crate) const fn is_default_layout() -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
@ -14,7 +14,7 @@ const fn is_dual_bank() -> bool {
|
||||
FLASH_REGIONS.len() >= 2
|
||||
}
|
||||
|
||||
pub fn get_flash_regions() -> &'static [&'static FlashRegion] {
|
||||
pub(crate) fn get_flash_regions() -> &'static [&'static FlashRegion] {
|
||||
&FLASH_REGIONS
|
||||
}
|
||||
|
||||
|
@ -5,11 +5,11 @@ use super::{FlashRegion, FlashSector, FLASH_REGIONS, WRITE_SIZE};
|
||||
use crate::flash::Error;
|
||||
use crate::pac;
|
||||
|
||||
pub const fn is_default_layout() -> bool {
|
||||
pub(crate) const fn is_default_layout() -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
pub const fn get_flash_regions() -> &'static [&'static FlashRegion] {
|
||||
pub(crate) const fn get_flash_regions() -> &'static [&'static FlashRegion] {
|
||||
&FLASH_REGIONS
|
||||
}
|
||||
|
||||
|
@ -14,50 +14,84 @@ pub use crate::_generated::flash_regions::*;
|
||||
pub use crate::_generated::MAX_ERASE_SIZE;
|
||||
pub use crate::pac::{FLASH_BASE, FLASH_SIZE, WRITE_SIZE};
|
||||
|
||||
/// Get whether the default flash layout is being used.
|
||||
///
|
||||
/// In some chips, dual-bank is not default. This will then return `false`
|
||||
/// when dual-bank is enabled.
|
||||
pub fn is_default_layout() -> bool {
|
||||
family::is_default_layout()
|
||||
}
|
||||
|
||||
/// Get all flash regions.
|
||||
pub fn get_flash_regions() -> &'static [&'static FlashRegion] {
|
||||
family::get_flash_regions()
|
||||
}
|
||||
|
||||
/// Read size (always 1)
|
||||
pub const READ_SIZE: usize = 1;
|
||||
|
||||
pub struct Blocking;
|
||||
pub struct Async;
|
||||
/// Blocking flash mode typestate.
|
||||
pub enum Blocking {}
|
||||
/// Async flash mode typestate.
|
||||
pub enum Async {}
|
||||
|
||||
/// Flash memory region
|
||||
#[derive(Debug)]
|
||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||
pub struct FlashRegion {
|
||||
/// Bank number.
|
||||
pub bank: FlashBank,
|
||||
/// Absolute base address.
|
||||
pub base: u32,
|
||||
/// Size in bytes.
|
||||
pub size: u32,
|
||||
/// Erase size (sector size).
|
||||
pub erase_size: u32,
|
||||
/// Minimum write size.
|
||||
pub write_size: u32,
|
||||
/// Erase value (usually `0xFF`, but is `0x00` in some chips)
|
||||
pub erase_value: u8,
|
||||
pub(crate) _ensure_internal: (),
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||
pub struct FlashSector {
|
||||
pub bank: FlashBank,
|
||||
pub index_in_bank: u8,
|
||||
pub start: u32,
|
||||
pub size: u32,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||
pub enum FlashBank {
|
||||
Bank1 = 0,
|
||||
Bank2 = 1,
|
||||
Otp,
|
||||
}
|
||||
|
||||
impl FlashRegion {
|
||||
/// Absolute end address.
|
||||
pub const fn end(&self) -> u32 {
|
||||
self.base + self.size
|
||||
}
|
||||
|
||||
/// Number of sectors in the region.
|
||||
pub const fn sectors(&self) -> u8 {
|
||||
(self.size / self.erase_size) as u8
|
||||
}
|
||||
}
|
||||
|
||||
/// Flash sector.
|
||||
#[derive(Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||
pub struct FlashSector {
|
||||
/// Bank number.
|
||||
pub bank: FlashBank,
|
||||
/// Sector number within the bank.
|
||||
pub index_in_bank: u8,
|
||||
/// Absolute start address.
|
||||
pub start: u32,
|
||||
/// Size in bytes.
|
||||
pub size: u32,
|
||||
}
|
||||
|
||||
/// Flash bank.
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||
pub enum FlashBank {
|
||||
/// Bank 1
|
||||
Bank1 = 0,
|
||||
/// Bank 2
|
||||
Bank2 = 1,
|
||||
/// OTP region
|
||||
Otp,
|
||||
}
|
||||
|
||||
#[cfg_attr(any(flash_l0, flash_l1, flash_l4, flash_wl, flash_wb), path = "l.rs")]
|
||||
#[cfg_attr(flash_f0, path = "f0.rs")]
|
||||
#[cfg_attr(flash_f3, path = "f3.rs")]
|
||||
@ -78,6 +112,10 @@ mod family;
|
||||
#[allow(unused_imports)]
|
||||
pub use family::*;
|
||||
|
||||
/// Flash error
|
||||
///
|
||||
/// See STM32 Reference Manual for your chip for details.
|
||||
#[allow(missing_docs)]
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||
pub enum Error {
|
||||
|
@ -2,11 +2,11 @@
|
||||
|
||||
use super::{Error, FlashRegion, FlashSector, FLASH_REGIONS, WRITE_SIZE};
|
||||
|
||||
pub const fn is_default_layout() -> bool {
|
||||
pub(crate) const fn is_default_layout() -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
pub const fn get_flash_regions() -> &'static [&'static FlashRegion] {
|
||||
pub(crate) const fn get_flash_regions() -> &'static [&'static FlashRegion] {
|
||||
&FLASH_REGIONS
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user