Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions docs/pages/mcxa.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,7 @@ The following peripherals have a HAL implementation at present
* CTIMER
* CRC
* DMA
* FlexSPI (MCXA5xx)

FlexSPI support currently targets MCXA5xx devices and the `FLEXSPI0`
peripheral.
5 changes: 3 additions & 2 deletions embassy-mcxa/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ heapless = "0.9"
maitake-sync = { version = "0.3.0", default-features = false, features = ["critical-section", "no-cache-pad"] }
nb = "1.1.0"
nxp-pac = { git = "https://github.com/embassy-rs/nxp-pac.git", rev = "b644ff07f59805b1fb362eee45a2de7becf29172", features = ["rt"] }
nxp-pac-flexspi = { package = "nxp-pac", git = "https://github.com/embassy-rs/nxp-pac.git", rev = "c2f056f666c766563c7a22cb48d5f7a199714d7f", default-features = false, features = ["mcxa577"], optional = true }
paste = "1.0.15"

rand-core-06 = { package = "rand_core", version = "0.6" }
Expand All @@ -71,7 +72,7 @@ default = ["rt", "swd-swo-as-gpio", "dma-ipd-req"]

# Base defmt feature enables core + panic handler
# Use with one logger feature: defmt-rtt (preferred) or defmt-uart (fallback)
defmt = ["dep:defmt", "nxp-pac/defmt"]
defmt = ["dep:defmt", "nxp-pac/defmt", "nxp-pac-flexspi?/defmt"]

# Enable optional embedded-mcu-hal traits
embedded-mcu-hal = ["dep:embedded-mcu-hal"]
Expand Down Expand Up @@ -150,7 +151,7 @@ unstable-osc32k = []
# Chip family selection
#
mcxa2xx = ["nxp-pac/mcxa256"]
mcxa5xx = ["nxp-pac/mcxa577"]
mcxa5xx = ["nxp-pac/mcxa577", "dep:nxp-pac-flexspi"]

[dev-dependencies]
embassy-executor = { version = "0.10.0", path = "../embassy-executor", features = ["platform-cortex-m", "executor-interrupt", "executor-thread"] }
Expand Down
11 changes: 9 additions & 2 deletions embassy-mcxa/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
# Embassy NXP MCX-A MCUs HAL

A Hardware Abstraction Layer (HAL) for the NXP MCX-A family of
microcontrollers using the Embassy async framework. This HAL provides
safe, idiomatic Rust interfaces for GPIO, UART, and OSTIMER
microcontrollers using the Embassy async framework.

The `embassy-mcxa` HAL currently provides safe, idiomatic Rust
interfaces for clocks, GPIO, ADC, CLKOUT, CDOG, CRC, CTIMER, DMA,
FlexSPI, I2C, I3C, LPUART, OSTIMER, RTC, SPI, TRNG, and WWDT
peripherals.

FlexSPI support currently targets MCXA5xx devices and the `FLEXSPI0`
peripheral, with blocking, interrupt-driven async, and DMA-backed async
APIs for NOR flash style transfers.
9 changes: 7 additions & 2 deletions embassy-mcxa/src/chips/mcxa5xx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ mod inner_periph {
// Need more work on the DMA driver before we can enable this
// EDMA0_TCD1,

FLEXSPI0,

// EIM0,
// EQDC0,
// EQDC1,
Expand Down Expand Up @@ -405,6 +407,8 @@ mod inner_interrupt {
// FREQME0,
// GLIKEY0,

FLEXSPI0,

GPIO0,
GPIO1,
GPIO2,
Expand Down Expand Up @@ -719,8 +723,8 @@ pub(crate) mod peripheral_gating {

use crate::clocks::Gate;
use crate::clocks::periph_helpers::{
AdcConfig, CTimerConfig, Clk1MConfig, I3cConfig, Lpi2cConfig, LpspiConfig, LpuartConfig, NoConfig,
OsTimerConfig,
AdcConfig, CTimerConfig, Clk1MConfig, FlexspiConfig, I3cConfig, Lpi2cConfig, LpspiConfig, LpuartConfig,
NoConfig, OsTimerConfig,
};
use crate::{impl_cc_gate, pac};

Expand Down Expand Up @@ -787,6 +791,7 @@ pub(crate) mod peripheral_gating {
impl_cc_gate!(LPSPI3, mrcc_glb_acc1, mrcc_glb_rst1, lpspi3, LpspiConfig);
impl_cc_gate!(LPSPI4, mrcc_glb_acc1, mrcc_glb_rst1, lpspi4, LpspiConfig);
impl_cc_gate!(LPSPI5, mrcc_glb_acc1, mrcc_glb_rst1, lpspi5, LpspiConfig);
impl_cc_gate!(FLEXSPI0, mrcc_glb_cc2, mrcc_glb_rst2, flexspi0, FlexspiConfig);

impl_cc_gate!(WWDT0, mrcc_glb_acc0, wwdt0, Clk1MConfig);
impl_cc_gate!(WWDT1, mrcc_glb_acc0, wwdt1, Clk1MConfig);
Expand Down
61 changes: 61 additions & 0 deletions embassy-mcxa/src/clocks/periph_helpers/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@

use super::{ClockError, Clocks, PoweredClock, WakeGuard};
use crate::clocks::VddLevel;
#[cfg(feature = "mcxa5xx")]
use crate::pac::mrcc::FlexspiClkselMux;
use crate::pac::mrcc::{
AdcClkselMux, ClkdivHalt, ClkdivReset, ClkdivUnstab, CtimerClkselMux, FclkClkselMux, Lpi2cClkselMux,
LpspiClkselMux, LpuartClkselMux, OstimerClkselMux,
Expand Down Expand Up @@ -436,6 +438,65 @@ impl SPConfHelper for OsTimerConfig {
}
}

//
// FlexSPI
//

/// Selectable clocks for `FlexSPI` peripherals.
#[cfg(feature = "mcxa5xx")]
#[derive(Debug, Clone, Copy)]
pub enum FlexspiClockSel {
/// Gated FRO_HF / FIRC clock.
FroHf,
/// PLL1 clock after its divider.
Pll1ClkDiv,
}

/// Which instance of the `FlexSPI` peripheral is this?
#[cfg(feature = "mcxa5xx")]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum FlexspiInstance {
/// Instance 0.
Flexspi0,
}

/// Top level configuration for `FlexSPI` instances.
#[cfg(feature = "mcxa5xx")]
pub struct FlexspiConfig {
/// Power state required for this peripheral.
pub power: PoweredClock,
/// Clock source.
pub source: FlexspiClockSel,
/// Clock divisor.
pub div: Div4,
/// Which instance is this?
pub(crate) instance: FlexspiInstance,
}

#[cfg(feature = "mcxa5xx")]
impl SPConfHelper for FlexspiConfig {
fn pre_enable_config(&self, clocks: &Clocks) -> Result<PreEnableParts, ClockError> {
let mrcc0 = crate::pac::MRCC0;

let (clkdiv, clksel) = match self.instance {
FlexspiInstance::Flexspi0 => (mrcc0.mrcc_flexspi0_clkdiv(), mrcc0.mrcc_flexspi0_clksel()),
};

let (freq, variant) = match self.source {
FlexspiClockSel::FroHf => (
clocks.ensure_fro_hf_active(&self.power)?,
FlexspiClkselMux::I1_CLKROOT_FIRC_GATED,
),
FlexspiClockSel::Pll1ClkDiv => (
clocks.ensure_pll1_clk_div_active(&self.power)?,
FlexspiClkselMux::I6_CLKROOT_SPLL,
),
};

apply_div4!(self, clksel, clkdiv, variant, freq)
}
}

//
// LPSPI
//
Expand Down
6 changes: 3 additions & 3 deletions embassy-mcxa/src/dma.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1040,7 +1040,7 @@ impl DmaChannel<'_> {
options: TransferOptions,
) -> Result<Transfer<'_>, InvalidParameters> {
unsafe { self.setup_write_to_peripheral(buf, peri_addr, false, options)? };
Ok(Transfer::new(self.reborrow()))
Ok(unsafe { self.start_transfer() })
}

/// Read data from a peripheral register to memory.
Expand All @@ -1065,7 +1065,7 @@ impl DmaChannel<'_> {
options: TransferOptions,
) -> Result<Transfer<'_>, InvalidParameters> {
unsafe { self.setup_read_from_peripheral(peri_addr, buf, false, options)? };
Ok(Transfer::new(self.reborrow()))
Ok(unsafe { self.start_transfer() })
}

/// Configure a memory-to-peripheral DMA transfer without starting it.
Expand Down Expand Up @@ -1644,7 +1644,7 @@ impl<'a> Transfer<'a> {
///
/// Each error variant can be queried separately, or all errors can be iterated by using [TransferErrors::into_iter].
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[derive(Copy, Clone, Debug)]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct TransferErrors(u8);

/// Iterator to extract all [TransferError]s using [TransferErrors::into_iter].
Expand Down
Loading