stm32: add some docs.

This commit is contained in:
Dario Nieuwenhuis
2023-12-17 22:09:14 +01:00
parent a2d4bab2f8
commit 80c9d04bbd
37 changed files with 544 additions and 124 deletions

View File

@ -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 {

View File

@ -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) }
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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 {

View File

@ -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
}