nrf: docs.

This commit is contained in:
Dario Nieuwenhuis
2023-02-01 00:48:33 +01:00
parent ca10fe7135
commit b5cf332cc0
40 changed files with 694 additions and 245 deletions

View File

@ -1,3 +1,5 @@
//! Quad Serial Peripheral Interface (QSPI) flash driver.
#![macro_use]
use core::future::poll_fn;
@ -15,6 +17,7 @@ pub use crate::pac::qspi::ifconfig0::{
pub use crate::pac::qspi::ifconfig1::SPIMODE_A as SpiMode;
use crate::{pac, Peripheral};
/// Deep power-down config.
pub struct DeepPowerDownConfig {
/// Time required for entering DPM, in units of 16us
pub enter_time: u16,
@ -22,37 +25,62 @@ pub struct DeepPowerDownConfig {
pub exit_time: u16,
}
/// QSPI bus frequency.
pub enum Frequency {
/// 32 Mhz
M32 = 0,
/// 16 Mhz
M16 = 1,
/// 10.7 Mhz
M10_7 = 2,
/// 8 Mhz
M8 = 3,
/// 6.4 Mhz
M6_4 = 4,
/// 5.3 Mhz
M5_3 = 5,
/// 4.6 Mhz
M4_6 = 6,
/// 4 Mhz
M4 = 7,
/// 3.6 Mhz
M3_6 = 8,
/// 3.2 Mhz
M3_2 = 9,
/// 2.9 Mhz
M2_9 = 10,
/// 2.7 Mhz
M2_7 = 11,
/// 2.5 Mhz
M2_5 = 12,
/// 2.3 Mhz
M2_3 = 13,
/// 2.1 Mhz
M2_1 = 14,
/// 2 Mhz
M2 = 15,
}
/// QSPI config.
#[non_exhaustive]
pub struct Config {
/// XIP offset.
pub xip_offset: u32,
/// Opcode used for read operations.
pub read_opcode: ReadOpcode,
/// Opcode used for write operations.
pub write_opcode: WriteOpcode,
/// Page size for write operations.
pub write_page_size: WritePageSize,
/// Configuration for deep power down. If None, deep power down is disabled.
pub deep_power_down: Option<DeepPowerDownConfig>,
/// QSPI bus frequency.
pub frequency: Frequency,
/// Value is specified in number of 16 MHz periods (62.5 ns)
pub sck_delay: u8,
/// Whether data is captured on the clock rising edge and data is output on a falling edge (MODE0) or vice-versa (MODE3)
pub spi_mode: SpiMode,
/// Addressing mode (24-bit or 32-bit)
pub address_mode: AddressMode,
}
@ -72,20 +100,24 @@ impl Default for Config {
}
}
/// Error
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[non_exhaustive]
pub enum Error {
/// Operation address was out of bounds.
OutOfBounds,
// TODO add "not in data memory" error and check for it
}
/// QSPI flash driver.
pub struct Qspi<'d, T: Instance, const FLASH_SIZE: usize> {
irq: PeripheralRef<'d, T::Interrupt>,
dpm_enabled: bool,
}
impl<'d, T: Instance, const FLASH_SIZE: usize> Qspi<'d, T, FLASH_SIZE> {
/// Create a new QSPI driver.
pub fn new(
_qspi: impl Peripheral<P = T> + 'd,
irq: impl Peripheral<P = T::Interrupt> + 'd,
@ -183,6 +215,7 @@ impl<'d, T: Instance, const FLASH_SIZE: usize> Qspi<'d, T, FLASH_SIZE> {
}
}
/// Do a custom QSPI instruction.
pub async fn custom_instruction(&mut self, opcode: u8, req: &[u8], resp: &mut [u8]) -> Result<(), Error> {
let bomb = DropBomb::new();
@ -198,6 +231,7 @@ impl<'d, T: Instance, const FLASH_SIZE: usize> Qspi<'d, T, FLASH_SIZE> {
Ok(())
}
/// Do a custom QSPI instruction, blocking version.
pub fn blocking_custom_instruction(&mut self, opcode: u8, req: &[u8], resp: &mut [u8]) -> Result<(), Error> {
let len = core::cmp::max(req.len(), resp.len()) as u8;
self.custom_instruction_start(opcode, req, len)?;
@ -346,6 +380,7 @@ impl<'d, T: Instance, const FLASH_SIZE: usize> Qspi<'d, T, FLASH_SIZE> {
Ok(())
}
/// Read data from the flash memory.
pub async fn read(&mut self, address: usize, data: &mut [u8]) -> Result<(), Error> {
let bomb = DropBomb::new();
@ -357,6 +392,7 @@ impl<'d, T: Instance, const FLASH_SIZE: usize> Qspi<'d, T, FLASH_SIZE> {
Ok(())
}
/// Write data to the flash memory.
pub async fn write(&mut self, address: usize, data: &[u8]) -> Result<(), Error> {
let bomb = DropBomb::new();
@ -368,6 +404,7 @@ impl<'d, T: Instance, const FLASH_SIZE: usize> Qspi<'d, T, FLASH_SIZE> {
Ok(())
}
/// Erase a sector on the flash memory.
pub async fn erase(&mut self, address: usize) -> Result<(), Error> {
let bomb = DropBomb::new();
@ -379,18 +416,21 @@ impl<'d, T: Instance, const FLASH_SIZE: usize> Qspi<'d, T, FLASH_SIZE> {
Ok(())
}
/// Read data from the flash memory, blocking version.
pub fn blocking_read(&mut self, address: usize, data: &mut [u8]) -> Result<(), Error> {
self.start_read(address, data)?;
self.blocking_wait_ready();
Ok(())
}
/// Write data to the flash memory, blocking version.
pub fn blocking_write(&mut self, address: usize, data: &[u8]) -> Result<(), Error> {
self.start_write(address, data)?;
self.blocking_wait_ready();
Ok(())
}
/// Erase a sector on the flash memory, blocking version.
pub fn blocking_erase(&mut self, address: usize) -> Result<(), Error> {
self.start_erase(address)?;
self.blocking_wait_ready();
@ -547,7 +587,9 @@ pub(crate) mod sealed {
}
}
/// QSPI peripheral instance.
pub trait Instance: Peripheral<P = Self> + sealed::Instance + 'static {
/// Interrupt for this peripheral.
type Interrupt: Interrupt;
}