feat(stm32:qspi): convert some u8 to enum variants
This commit is contained in:
parent
6a802c4708
commit
87898501a2
2 changed files with 350 additions and 60 deletions
294
embassy-stm32/src/qspi/enums.rs
Normal file
294
embassy-stm32/src/qspi/enums.rs
Normal file
|
@ -0,0 +1,294 @@
|
|||
#[allow(dead_code)]
|
||||
#[derive(Copy, Clone)]
|
||||
pub(crate) enum QspiMode {
|
||||
IndirectWrite,
|
||||
IndirectRead,
|
||||
AutoPolling,
|
||||
MemoryMapped,
|
||||
}
|
||||
|
||||
impl Into<u8> for QspiMode {
|
||||
fn into(self) -> u8 {
|
||||
match self {
|
||||
QspiMode::IndirectWrite => 0b00,
|
||||
QspiMode::IndirectRead => 0b01,
|
||||
QspiMode::AutoPolling => 0b10,
|
||||
QspiMode::MemoryMapped => 0b11,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(Copy, Clone)]
|
||||
pub enum QspiWidth {
|
||||
NONE,
|
||||
SING,
|
||||
DUAL,
|
||||
QUAD,
|
||||
}
|
||||
|
||||
impl Into<u8> for QspiWidth {
|
||||
fn into(self) -> u8 {
|
||||
match self {
|
||||
QspiWidth::NONE => 0b00,
|
||||
QspiWidth::SING => 0b01,
|
||||
QspiWidth::DUAL => 0b10,
|
||||
QspiWidth::QUAD => 0b11,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub enum MemorySize {
|
||||
_1KiB,
|
||||
_2KiB,
|
||||
_4KiB,
|
||||
_8KiB,
|
||||
_16KiB,
|
||||
_32KiB,
|
||||
_64KiB,
|
||||
_128KiB,
|
||||
_256KiB,
|
||||
_512KiB,
|
||||
_1MiB,
|
||||
_2MiB,
|
||||
_4MiB,
|
||||
_8MiB,
|
||||
_16MiB,
|
||||
_32MiB,
|
||||
_64MiB,
|
||||
_128MiB,
|
||||
_256MiB,
|
||||
_512MiB,
|
||||
_1GiB,
|
||||
_2GiB,
|
||||
_4GiB,
|
||||
Other(u8),
|
||||
}
|
||||
|
||||
impl Into<u8> for MemorySize {
|
||||
fn into(self) -> u8 {
|
||||
match self {
|
||||
MemorySize::_1KiB => 9,
|
||||
MemorySize::_2KiB => 10,
|
||||
MemorySize::_4KiB => 11,
|
||||
MemorySize::_8KiB => 12,
|
||||
MemorySize::_16KiB => 13,
|
||||
MemorySize::_32KiB => 14,
|
||||
MemorySize::_64KiB => 15,
|
||||
MemorySize::_128KiB => 16,
|
||||
MemorySize::_256KiB => 17,
|
||||
MemorySize::_512KiB => 18,
|
||||
MemorySize::_1MiB => 19,
|
||||
MemorySize::_2MiB => 20,
|
||||
MemorySize::_4MiB => 21,
|
||||
MemorySize::_8MiB => 22,
|
||||
MemorySize::_16MiB => 23,
|
||||
MemorySize::_32MiB => 24,
|
||||
MemorySize::_64MiB => 25,
|
||||
MemorySize::_128MiB => 26,
|
||||
MemorySize::_256MiB => 27,
|
||||
MemorySize::_512MiB => 28,
|
||||
MemorySize::_1GiB => 29,
|
||||
MemorySize::_2GiB => 30,
|
||||
MemorySize::_4GiB => 31,
|
||||
MemorySize::Other(val) => val,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub enum AddressSize {
|
||||
_8Bit,
|
||||
_16Bit,
|
||||
_24bit,
|
||||
_32bit,
|
||||
}
|
||||
|
||||
impl Into<u8> for AddressSize {
|
||||
fn into(self) -> u8 {
|
||||
match self {
|
||||
AddressSize::_8Bit => 0b00,
|
||||
AddressSize::_16Bit => 0b01,
|
||||
AddressSize::_24bit => 0b10,
|
||||
AddressSize::_32bit => 0b11,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub enum ChipSelectHightTime {
|
||||
_1Cycle,
|
||||
_2Cycle,
|
||||
_3Cycle,
|
||||
_4Cycle,
|
||||
_5Cycle,
|
||||
_6Cycle,
|
||||
_7Cycle,
|
||||
_8Cycle,
|
||||
}
|
||||
|
||||
impl Into<u8> for ChipSelectHightTime {
|
||||
fn into(self) -> u8 {
|
||||
match self {
|
||||
ChipSelectHightTime::_1Cycle => 0,
|
||||
ChipSelectHightTime::_2Cycle => 1,
|
||||
ChipSelectHightTime::_3Cycle => 2,
|
||||
ChipSelectHightTime::_4Cycle => 3,
|
||||
ChipSelectHightTime::_5Cycle => 4,
|
||||
ChipSelectHightTime::_6Cycle => 5,
|
||||
ChipSelectHightTime::_7Cycle => 6,
|
||||
ChipSelectHightTime::_8Cycle => 7,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub enum FIFOThresholdLevel {
|
||||
_1Bytes,
|
||||
_2Bytes,
|
||||
_3Bytes,
|
||||
_4Bytes,
|
||||
_5Bytes,
|
||||
_6Bytes,
|
||||
_7Bytes,
|
||||
_8Bytes,
|
||||
_9Bytes,
|
||||
_10Bytes,
|
||||
_11Bytes,
|
||||
_12Bytes,
|
||||
_13Bytes,
|
||||
_14Bytes,
|
||||
_15Bytes,
|
||||
_16Bytes,
|
||||
_17Bytes,
|
||||
_18Bytes,
|
||||
_19Bytes,
|
||||
_20Bytes,
|
||||
_21Bytes,
|
||||
_22Bytes,
|
||||
_23Bytes,
|
||||
_24Bytes,
|
||||
_25Bytes,
|
||||
_26Bytes,
|
||||
_27Bytes,
|
||||
_28Bytes,
|
||||
_29Bytes,
|
||||
_30Bytes,
|
||||
_31Bytes,
|
||||
_32Bytes,
|
||||
}
|
||||
|
||||
impl Into<u8> for FIFOThresholdLevel {
|
||||
fn into(self) -> u8 {
|
||||
match self {
|
||||
FIFOThresholdLevel::_1Bytes => 0,
|
||||
FIFOThresholdLevel::_2Bytes => 1,
|
||||
FIFOThresholdLevel::_3Bytes => 2,
|
||||
FIFOThresholdLevel::_4Bytes => 3,
|
||||
FIFOThresholdLevel::_5Bytes => 4,
|
||||
FIFOThresholdLevel::_6Bytes => 5,
|
||||
FIFOThresholdLevel::_7Bytes => 6,
|
||||
FIFOThresholdLevel::_8Bytes => 7,
|
||||
FIFOThresholdLevel::_9Bytes => 8,
|
||||
FIFOThresholdLevel::_10Bytes => 9,
|
||||
FIFOThresholdLevel::_11Bytes => 10,
|
||||
FIFOThresholdLevel::_12Bytes => 11,
|
||||
FIFOThresholdLevel::_13Bytes => 12,
|
||||
FIFOThresholdLevel::_14Bytes => 13,
|
||||
FIFOThresholdLevel::_15Bytes => 14,
|
||||
FIFOThresholdLevel::_16Bytes => 15,
|
||||
FIFOThresholdLevel::_17Bytes => 16,
|
||||
FIFOThresholdLevel::_18Bytes => 17,
|
||||
FIFOThresholdLevel::_19Bytes => 18,
|
||||
FIFOThresholdLevel::_20Bytes => 19,
|
||||
FIFOThresholdLevel::_21Bytes => 20,
|
||||
FIFOThresholdLevel::_22Bytes => 21,
|
||||
FIFOThresholdLevel::_23Bytes => 22,
|
||||
FIFOThresholdLevel::_24Bytes => 23,
|
||||
FIFOThresholdLevel::_25Bytes => 24,
|
||||
FIFOThresholdLevel::_26Bytes => 25,
|
||||
FIFOThresholdLevel::_27Bytes => 26,
|
||||
FIFOThresholdLevel::_28Bytes => 27,
|
||||
FIFOThresholdLevel::_29Bytes => 28,
|
||||
FIFOThresholdLevel::_30Bytes => 29,
|
||||
FIFOThresholdLevel::_31Bytes => 30,
|
||||
FIFOThresholdLevel::_32Bytes => 31,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub enum DummyCycles {
|
||||
_0,
|
||||
_1,
|
||||
_2,
|
||||
_3,
|
||||
_4,
|
||||
_5,
|
||||
_6,
|
||||
_7,
|
||||
_8,
|
||||
_9,
|
||||
_10,
|
||||
_11,
|
||||
_12,
|
||||
_13,
|
||||
_14,
|
||||
_15,
|
||||
_16,
|
||||
_17,
|
||||
_18,
|
||||
_19,
|
||||
_20,
|
||||
_21,
|
||||
_22,
|
||||
_23,
|
||||
_24,
|
||||
_25,
|
||||
_26,
|
||||
_27,
|
||||
_28,
|
||||
_29,
|
||||
_30,
|
||||
_31,
|
||||
}
|
||||
|
||||
impl Into<u8> for DummyCycles {
|
||||
fn into(self) -> u8 {
|
||||
match self {
|
||||
DummyCycles::_0 => 0,
|
||||
DummyCycles::_1 => 1,
|
||||
DummyCycles::_2 => 2,
|
||||
DummyCycles::_3 => 3,
|
||||
DummyCycles::_4 => 4,
|
||||
DummyCycles::_5 => 5,
|
||||
DummyCycles::_6 => 6,
|
||||
DummyCycles::_7 => 7,
|
||||
DummyCycles::_8 => 8,
|
||||
DummyCycles::_9 => 9,
|
||||
DummyCycles::_10 => 10,
|
||||
DummyCycles::_11 => 11,
|
||||
DummyCycles::_12 => 12,
|
||||
DummyCycles::_13 => 13,
|
||||
DummyCycles::_14 => 14,
|
||||
DummyCycles::_15 => 15,
|
||||
DummyCycles::_16 => 16,
|
||||
DummyCycles::_17 => 17,
|
||||
DummyCycles::_18 => 18,
|
||||
DummyCycles::_19 => 19,
|
||||
DummyCycles::_20 => 20,
|
||||
DummyCycles::_21 => 21,
|
||||
DummyCycles::_22 => 22,
|
||||
DummyCycles::_23 => 23,
|
||||
DummyCycles::_24 => 24,
|
||||
DummyCycles::_25 => 25,
|
||||
DummyCycles::_26 => 26,
|
||||
DummyCycles::_27 => 27,
|
||||
DummyCycles::_28 => 28,
|
||||
DummyCycles::_29 => 29,
|
||||
DummyCycles::_30 => 30,
|
||||
DummyCycles::_31 => 31,
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,6 +1,9 @@
|
|||
#![macro_use]
|
||||
|
||||
pub mod enums;
|
||||
|
||||
use embassy_hal_common::{into_ref, PeripheralRef};
|
||||
use enums::*;
|
||||
|
||||
use crate::dma::TransferOptions;
|
||||
use crate::gpio::sealed::AFType;
|
||||
|
@ -9,37 +12,24 @@ use crate::pac::quadspi::Quadspi as Regs;
|
|||
use crate::rcc::RccPeripheral;
|
||||
use crate::{peripherals, Peripheral};
|
||||
|
||||
pub struct QspiWidth;
|
||||
|
||||
#[allow(dead_code)]
|
||||
impl QspiWidth {
|
||||
pub const NONE: u8 = 0b00;
|
||||
pub const SING: u8 = 0b01;
|
||||
pub const DUAL: u8 = 0b10;
|
||||
pub const QUAD: u8 = 0b11;
|
||||
}
|
||||
|
||||
struct QspiMode;
|
||||
|
||||
#[allow(dead_code)]
|
||||
impl QspiMode {
|
||||
pub const INDIRECT_WRITE: u8 = 0b00;
|
||||
pub const INDIRECT_READ: u8 = 0b01;
|
||||
pub const AUTO_POLLING: u8 = 0b10;
|
||||
pub const MEMORY_MAPPED: u8 = 0b11;
|
||||
}
|
||||
|
||||
pub struct QspiTransaction {
|
||||
pub iwidth: u8,
|
||||
pub awidth: u8,
|
||||
pub dwidth: u8,
|
||||
pub struct TransferConfig {
|
||||
/// Instraction width (IMODE)
|
||||
pub iwidth: QspiWidth,
|
||||
/// Address width (ADMODE)
|
||||
pub awidth: QspiWidth,
|
||||
/// Data width (DMODE)
|
||||
pub dwidth: QspiWidth,
|
||||
/// Instruction Id
|
||||
pub instruction: u8,
|
||||
/// Flash memory address
|
||||
pub address: Option<u32>,
|
||||
pub dummy: u8,
|
||||
/// Number of dummy cycles (DCYC)
|
||||
pub dummy: DummyCycles,
|
||||
/// Length of data
|
||||
pub data_len: Option<usize>,
|
||||
}
|
||||
|
||||
impl Default for QspiTransaction {
|
||||
impl Default for TransferConfig {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
iwidth: QspiWidth::NONE,
|
||||
|
@ -47,28 +37,34 @@ impl Default for QspiTransaction {
|
|||
dwidth: QspiWidth::NONE,
|
||||
instruction: 0,
|
||||
address: None,
|
||||
dummy: 0,
|
||||
dummy: DummyCycles::_0,
|
||||
data_len: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Config {
|
||||
pub memory_size: u8,
|
||||
pub address_size: u8,
|
||||
/// Flash memory size representend as 2^[0-32], as reasonable minimum 1KiB(9) was chosen.
|
||||
/// If you need other value the whose predefined use `Other` variant.
|
||||
pub memory_size: MemorySize,
|
||||
/// Address size (8/16/24/32-bit)
|
||||
pub address_size: AddressSize,
|
||||
/// Scalar factor for generating CLK [0-255]
|
||||
pub prescaler: u8,
|
||||
pub fifo_threshold: u8,
|
||||
pub cs_high_time: u8,
|
||||
/// Number of bytes to trigger FIFO threshold flag.
|
||||
pub fifo_threshold: FIFOThresholdLevel,
|
||||
/// Minimum number of cycles that chip select must be high between issued commands
|
||||
pub cs_high_time: ChipSelectHightTime,
|
||||
}
|
||||
|
||||
impl Default for Config {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
memory_size: 0,
|
||||
address_size: 2,
|
||||
memory_size: MemorySize::Other(0),
|
||||
address_size: AddressSize::_24bit,
|
||||
prescaler: 128,
|
||||
fifo_threshold: 16,
|
||||
cs_high_time: 4,
|
||||
fifo_threshold: FIFOThresholdLevel::_17Bytes,
|
||||
cs_high_time: ChipSelectHightTime::_5Cycle,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -143,7 +139,7 @@ impl<'d, T: Instance, Dma> Qspi<'d, T, Dma> {
|
|||
|
||||
T::enable();
|
||||
unsafe {
|
||||
T::REGS.cr().write(|w| w.set_fthres(config.fifo_threshold));
|
||||
T::REGS.cr().write(|w| w.set_fthres(config.fifo_threshold.into()));
|
||||
|
||||
while T::REGS.sr().read().busy() {}
|
||||
|
||||
|
@ -152,8 +148,8 @@ impl<'d, T: Instance, Dma> Qspi<'d, T, Dma> {
|
|||
w.set_en(true);
|
||||
});
|
||||
T::REGS.dcr().write(|w| {
|
||||
w.set_fsize(config.memory_size);
|
||||
w.set_csht(config.cs_high_time);
|
||||
w.set_fsize(config.memory_size.into());
|
||||
w.set_csht(config.cs_high_time.into());
|
||||
w.set_ckmode(false);
|
||||
});
|
||||
}
|
||||
|
@ -171,25 +167,25 @@ impl<'d, T: Instance, Dma> Qspi<'d, T, Dma> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn command(&mut self, transaction: QspiTransaction) {
|
||||
pub fn command(&mut self, transaction: TransferConfig) {
|
||||
unsafe {
|
||||
T::REGS.cr().modify(|v| v.set_dmaen(false));
|
||||
self.setup_transaction(QspiMode::INDIRECT_WRITE, &transaction);
|
||||
self.setup_transaction(QspiMode::IndirectWrite, &transaction);
|
||||
|
||||
while !T::REGS.sr().read().tcf() {}
|
||||
T::REGS.fcr().modify(|v| v.set_ctcf(true));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn read(&mut self, buf: &mut [u8], transaction: QspiTransaction) {
|
||||
pub fn blocking_read(&mut self, buf: &mut [u8], transaction: TransferConfig) {
|
||||
unsafe {
|
||||
T::REGS.cr().modify(|v| v.set_dmaen(false));
|
||||
self.setup_transaction(QspiMode::INDIRECT_WRITE, &transaction);
|
||||
self.setup_transaction(QspiMode::IndirectWrite, &transaction);
|
||||
|
||||
if let Some(len) = transaction.data_len {
|
||||
let current_ar = T::REGS.ar().read().address();
|
||||
T::REGS.ccr().modify(|v| {
|
||||
v.set_fmode(QspiMode::INDIRECT_READ);
|
||||
v.set_fmode(QspiMode::IndirectRead.into());
|
||||
});
|
||||
T::REGS.ar().write(|v| {
|
||||
v.set_address(current_ar);
|
||||
|
@ -206,14 +202,14 @@ impl<'d, T: Instance, Dma> Qspi<'d, T, Dma> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn write(&mut self, buf: &[u8], transaction: QspiTransaction) {
|
||||
pub fn blocking_write(&mut self, buf: &[u8], transaction: TransferConfig) {
|
||||
unsafe {
|
||||
T::REGS.cr().modify(|v| v.set_dmaen(false));
|
||||
self.setup_transaction(QspiMode::INDIRECT_WRITE, &transaction);
|
||||
self.setup_transaction(QspiMode::IndirectWrite, &transaction);
|
||||
|
||||
if let Some(len) = transaction.data_len {
|
||||
T::REGS.ccr().modify(|v| {
|
||||
v.set_fmode(QspiMode::INDIRECT_WRITE);
|
||||
v.set_fmode(QspiMode::IndirectWrite.into());
|
||||
});
|
||||
|
||||
for idx in 0..len {
|
||||
|
@ -227,18 +223,18 @@ impl<'d, T: Instance, Dma> Qspi<'d, T, Dma> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn read_dma(&mut self, buf: &mut [u8], transaction: QspiTransaction)
|
||||
pub fn blocking_read_dma(&mut self, buf: &mut [u8], transaction: TransferConfig)
|
||||
where
|
||||
Dma: QuadDma<T>,
|
||||
{
|
||||
unsafe {
|
||||
self.setup_transaction(QspiMode::INDIRECT_WRITE, &transaction);
|
||||
self.setup_transaction(QspiMode::IndirectWrite, &transaction);
|
||||
|
||||
let request = self.dma.request();
|
||||
let options = TransferOptions::default();
|
||||
|
||||
T::REGS.ccr().modify(|v| {
|
||||
v.set_fmode(QspiMode::INDIRECT_READ);
|
||||
v.set_fmode(QspiMode::IndirectRead.into());
|
||||
});
|
||||
let current_ar = T::REGS.ar().read().address();
|
||||
T::REGS.ar().write(|v| {
|
||||
|
@ -254,18 +250,18 @@ impl<'d, T: Instance, Dma> Qspi<'d, T, Dma> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn write_dma(&mut self, buf: &[u8], transaction: QspiTransaction)
|
||||
pub fn blocking_write_dma(&mut self, buf: &[u8], transaction: TransferConfig)
|
||||
where
|
||||
Dma: QuadDma<T>,
|
||||
{
|
||||
unsafe {
|
||||
self.setup_transaction(QspiMode::INDIRECT_WRITE, &transaction);
|
||||
self.setup_transaction(QspiMode::IndirectWrite, &transaction);
|
||||
|
||||
let request = self.dma.request();
|
||||
let options = TransferOptions::default();
|
||||
|
||||
T::REGS.ccr().modify(|v| {
|
||||
v.set_fmode(QspiMode::INDIRECT_WRITE);
|
||||
v.set_fmode(QspiMode::IndirectWrite.into());
|
||||
});
|
||||
|
||||
self.dma
|
||||
|
@ -277,7 +273,7 @@ impl<'d, T: Instance, Dma> Qspi<'d, T, Dma> {
|
|||
}
|
||||
}
|
||||
|
||||
fn setup_transaction(&mut self, fmode: u8, transaction: &QspiTransaction) {
|
||||
fn setup_transaction(&mut self, fmode: QspiMode, transaction: &TransferConfig) {
|
||||
unsafe {
|
||||
T::REGS.fcr().modify(|v| {
|
||||
v.set_csmf(true);
|
||||
|
@ -293,14 +289,14 @@ impl<'d, T: Instance, Dma> Qspi<'d, T, Dma> {
|
|||
}
|
||||
|
||||
T::REGS.ccr().write(|v| {
|
||||
v.set_fmode(fmode);
|
||||
v.set_imode(transaction.iwidth);
|
||||
v.set_fmode(fmode.into());
|
||||
v.set_imode(transaction.iwidth.into());
|
||||
v.set_instruction(transaction.instruction);
|
||||
v.set_admode(transaction.awidth);
|
||||
v.set_adsize(self.config.address_size);
|
||||
v.set_dmode(transaction.dwidth);
|
||||
v.set_abmode(QspiWidth::NONE);
|
||||
v.set_dcyc(transaction.dummy);
|
||||
v.set_admode(transaction.awidth.into());
|
||||
v.set_adsize(self.config.address_size.into());
|
||||
v.set_dmode(transaction.dwidth.into());
|
||||
v.set_abmode(QspiWidth::NONE.into());
|
||||
v.set_dcyc(transaction.dummy.into());
|
||||
});
|
||||
|
||||
if let Some(addr) = transaction.address {
|
||||
|
|
Loading…
Reference in a new issue