mirror of
https://github.com/embassy-rs/embassy.git
synced 2025-09-26 20:00:27 +00:00
Add embassy-imxrt
Adds initial support for MIMXRT600 series MCUs from NXP. Subsequent PRs will add more drivers.
This commit is contained in:
parent
0ec3e78c1b
commit
aa9a16e569
2
ci.sh
2
ci.sh
@ -53,6 +53,8 @@ cargo batch \
|
||||
--- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv4,proto-ipv6,medium-ip \
|
||||
--- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv4,proto-ipv6,medium-ip,medium-ethernet \
|
||||
--- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv4,proto-ipv6,medium-ip,medium-ethernet,medium-ieee802154 \
|
||||
--- build --release --manifest-path embassy-imxrt/Cargo.toml --target thumbv8m.main-none-eabihf --features mimxrt633s,defmt,unstable-pac \
|
||||
--- build --release --manifest-path embassy-imxrt/Cargo.toml --target thumbv8m.main-none-eabihf --features mimxrt685s,defmt,unstable-pac \
|
||||
--- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv6m-none-eabi --features nrf51,gpiote,time,time-driver-rtc1 \
|
||||
--- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nrf52805,gpiote,time,time-driver-rtc1 \
|
||||
--- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nrf52810,gpiote,time,time-driver-rtc1 \
|
||||
|
13
docs/pages/imxrt.adoc
Normal file
13
docs/pages/imxrt.adoc
Normal file
@ -0,0 +1,13 @@
|
||||
= Embassy iMXRT HAL
|
||||
|
||||
The link: link:https://github.com/embassy-rs/embassy/tree/main/embassy-imxrt[Embassy iMXRT HAL] is based on the following PACs (Peripheral Access Crate):
|
||||
|
||||
* link:https://github.com/OpenDevicePartnership/mimxrt685s-pac[mimxrt685s-pac]
|
||||
* link:https://github.com/OpenDevicePartnership/mimxrt633s-pac[mimxrt633s-pac]
|
||||
|
||||
== Peripherals
|
||||
|
||||
The following peripherals have a HAL implementation at present
|
||||
|
||||
* GPIO
|
||||
|
@ -6,6 +6,7 @@ include::runtime.adoc[leveloffset = 2]
|
||||
include::bootloader.adoc[leveloffset = 2]
|
||||
include::time_keeping.adoc[leveloffset = 2]
|
||||
include::hal.adoc[leveloffset = 2]
|
||||
include::imxrt.adoc[leveloffset = 2]
|
||||
include::nrf.adoc[leveloffset = 2]
|
||||
include::stm32.adoc[leveloffset = 2]
|
||||
include::sharing_peripherals.adoc[leveloffset = 2]
|
||||
|
84
embassy-imxrt/Cargo.toml
Normal file
84
embassy-imxrt/Cargo.toml
Normal file
@ -0,0 +1,84 @@
|
||||
[package]
|
||||
name = "embassy-imxrt"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
description = "Embassy Hardware Abstraction Layer (HAL) for the IMXRT microcontroller"
|
||||
keywords = ["embedded", "async", "imxrt", "rt600", "embedded-hal"]
|
||||
categories = ["embedded", "hardware-support", "no-std", "asynchronous"]
|
||||
repository = "https://github.com/embassy-rs/embassy"
|
||||
documentation = "https://docs.embassy.dev/embassy-imxrt"
|
||||
|
||||
[package.metadata.embassy_docs]
|
||||
src_base = "https://github.com/embassy-rs/embassy/blob/embassy-imxrt-v$VERSION/embassy-imxrt/src/"
|
||||
src_base_git = "https://github.com/embassy-rs/embassy/blob/$COMMIT/embassy-imxrt/src/"
|
||||
features = ["defmt", "unstable-pac"]
|
||||
flavors = [
|
||||
{ regex_feature = "mimxrt6.*", target = "thumbv8m.main-none-eabihf" }
|
||||
]
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
features = ["mimxrt685s", "defmt", "unstable-pac"]
|
||||
rustdoc-args = ["--cfg", "docsrs"]
|
||||
|
||||
[features]
|
||||
default = ["rt"]
|
||||
|
||||
## Cortex-M runtime (enabled by default)
|
||||
rt = [
|
||||
"mimxrt685s-pac?/rt",
|
||||
"mimxrt633s-pac?/rt",
|
||||
]
|
||||
|
||||
## Enable defmt
|
||||
defmt = ["dep:defmt", "embassy-hal-internal/defmt", "embassy-sync/defmt", "mimxrt685s-pac?/defmt", "mimxrt633s-pac?/defmt"]
|
||||
|
||||
## Reexport the PAC for the currently enabled chip at `embassy_imxrt::pac` (unstable)
|
||||
unstable-pac = []
|
||||
|
||||
# Features starting with `_` are for internal use only. They're not intended
|
||||
# to be enabled by other crates, and are not covered by semver guarantees.
|
||||
|
||||
_mimxrt685s = []
|
||||
_mimxrt633s = ["_espi"]
|
||||
|
||||
# Peripherals
|
||||
_espi = []
|
||||
|
||||
#! ### Chip selection features
|
||||
## MIMXRT685S
|
||||
mimxrt685s = ["mimxrt685s-pac", "_mimxrt685s"]
|
||||
## MIMXRT633S
|
||||
mimxrt633s = ["mimxrt633s-pac", "_mimxrt633s"]
|
||||
|
||||
[dependencies]
|
||||
embassy-sync = { version = "0.6.2", path = "../embassy-sync" }
|
||||
embassy-hal-internal = { version = "0.2.0", path = "../embassy-hal-internal", features = ["cortex-m", "prio-bits-3"] }
|
||||
embassy-embedded-hal = { version = "0.3.0", path = "../embassy-embedded-hal", default-features = false }
|
||||
embassy-futures = { version = "0.1.1", path = "../embassy-futures" }
|
||||
|
||||
defmt = { version = "1.0", optional = true }
|
||||
log = { version = "0.4.14", optional = true }
|
||||
nb = "1.0.0"
|
||||
cfg-if = "1.0.0"
|
||||
cortex-m-rt = ">=0.7.3,<0.8"
|
||||
cortex-m = "0.7.6"
|
||||
critical-section = "1.1"
|
||||
embedded-io = { version = "0.6.1" }
|
||||
embedded-io-async = { version = "0.6.1" }
|
||||
rand_core = "0.6.4"
|
||||
fixed = "1.23.1"
|
||||
|
||||
embedded-hal-02 = { package = "embedded-hal", version = "0.2.6", features = [
|
||||
"unproven",
|
||||
] }
|
||||
embedded-hal-1 = { package = "embedded-hal", version = "1.0" }
|
||||
embedded-hal-async = { version = "1.0" }
|
||||
embedded-hal-nb = { version = "1.0" }
|
||||
|
||||
document-features = "0.2.7"
|
||||
paste = "1.0"
|
||||
|
||||
# PACs
|
||||
mimxrt685s-pac = { version = "0.4.0", optional = true, features = ["rt", "critical-section"] }
|
||||
mimxrt633s-pac = { version = "0.4.0", optional = true, features = ["rt", "critical-section"] }
|
59
embassy-imxrt/README.md
Normal file
59
embassy-imxrt/README.md
Normal file
@ -0,0 +1,59 @@
|
||||
# Embassy iMXRT HAL
|
||||
|
||||
## Introduction
|
||||
|
||||
HALs implement safe, idiomatic Rust APIs to use the hardware capabilities, so
|
||||
raw register manipulation is not needed.
|
||||
|
||||
The Embassy iMXRT HAL targets the NXP iMXRT Family of MCUs. The HAL implements
|
||||
both blocking and async APIs for many peripherals. The benefit of using the
|
||||
async APIs is that the HAL takes care of waiting for peripherals to complete
|
||||
operations in low power mode and handling of interrupts, so that applications
|
||||
can focus on business logic.
|
||||
|
||||
NOTE: The Embassy HALs can be used both for non-async and async operations. For
|
||||
async, you can choose which runtime you want to use.
|
||||
|
||||
For a complete list of available peripherals and features, see the
|
||||
[embassy-imxrt documentation](https://docs.embassy.dev/embassy-imxrt).
|
||||
|
||||
## Hardware support
|
||||
|
||||
The `embassy-imxrt` HAL currently supports two main variants of the iMXRT
|
||||
family:
|
||||
|
||||
* MIMXRT685S
|
||||
([examples](https://github.com/OpenDevicePartnership/embassy-imxrt/tree/main/examples/rt685s-evk))
|
||||
* MIMXRT633s
|
||||
([examples](https://github.com/OpenDevicePartnership/embassy-imxrt/tree/main/examples/rt633))
|
||||
|
||||
Several peripherals are supported and tested on both supported chip variants. To
|
||||
check what's available, make sure to the MCU you're targetting in the top menu
|
||||
in the [documentation](https://docs.embassy.dev/embassy-imxrt).
|
||||
|
||||
## TrustZone support
|
||||
|
||||
TrustZone support is yet to be implemented.
|
||||
|
||||
## Time driver
|
||||
|
||||
If the `time-driver` feature is enabled, the HAL uses the RTC peripheral as a
|
||||
global time driver for [embassy-time](https://crates.io/crates/embassy-time),
|
||||
with a tick rate of 32768 Hz.
|
||||
|
||||
## Embedded-hal
|
||||
|
||||
The `embassy-imxrt` HAL implements the traits from
|
||||
[embedded-hal](https://crates.io/crates/embedded-hal) (v0.2 and 1.0) and
|
||||
[embedded-hal-async](https://crates.io/crates/embedded-hal-async), as well as
|
||||
[embedded-io](https://crates.io/crates/embedded-io) and
|
||||
[embedded-io-async](https://crates.io/crates/embedded-io-async).
|
||||
|
||||
## Interoperability
|
||||
|
||||
This crate can run on any executor.
|
||||
|
||||
Optionally, some features requiring
|
||||
[`embassy-time`](https://crates.io/crates/embassy-time) can be activated with
|
||||
the `time` feature. If you enable it, you must link an `embassy-time` driver in
|
||||
your project.
|
389
embassy-imxrt/src/chips/mimxrt633s.rs
Normal file
389
embassy-imxrt/src/chips/mimxrt633s.rs
Normal file
@ -0,0 +1,389 @@
|
||||
pub use mimxrt633s_pac as pac;
|
||||
|
||||
#[allow(clippy::missing_safety_doc)]
|
||||
pub mod interrupts {
|
||||
embassy_hal_internal::interrupt_mod!(
|
||||
ACMP,
|
||||
ADC0,
|
||||
CASPER,
|
||||
CTIMER0,
|
||||
CTIMER1,
|
||||
CTIMER2,
|
||||
CTIMER3,
|
||||
CTIMER4,
|
||||
DMA0,
|
||||
DMA1,
|
||||
DMIC0,
|
||||
ESPI,
|
||||
FLEXCOMM0,
|
||||
FLEXCOMM1,
|
||||
FLEXCOMM14,
|
||||
FLEXCOMM15,
|
||||
FLEXCOMM2,
|
||||
FLEXCOMM3,
|
||||
FLEXCOMM4,
|
||||
FLEXCOMM5,
|
||||
FLEXCOMM6,
|
||||
FLEXCOMM7,
|
||||
FLEXSPI,
|
||||
GPIO_INTA,
|
||||
GPIO_INTB,
|
||||
HASHCRYPT,
|
||||
HWVAD0,
|
||||
HYPERVISOR,
|
||||
I3C0,
|
||||
MRT0,
|
||||
MU_A,
|
||||
OS_EVENT,
|
||||
PIN_INT0,
|
||||
PIN_INT1,
|
||||
PIN_INT2,
|
||||
PIN_INT3,
|
||||
PIN_INT4,
|
||||
PIN_INT5,
|
||||
PIN_INT6,
|
||||
PIN_INT7,
|
||||
PMC_PMIC,
|
||||
POWERQUAD,
|
||||
PUF,
|
||||
RNG,
|
||||
RTC,
|
||||
SCT0,
|
||||
SECUREVIOLATION,
|
||||
SGPIO_INTA,
|
||||
SGPIO_INTB,
|
||||
USB,
|
||||
USBPHY_DCD,
|
||||
USB_WAKEUP,
|
||||
USDHC0,
|
||||
USDHC1,
|
||||
UTICK0,
|
||||
WDT0,
|
||||
WDT1,
|
||||
);
|
||||
}
|
||||
|
||||
embassy_hal_internal::peripherals!(
|
||||
ACMP,
|
||||
ADC0,
|
||||
CASPER,
|
||||
CRC,
|
||||
CTIMER0_COUNT_CHANNEL0,
|
||||
CTIMER0_COUNT_CHANNEL1,
|
||||
CTIMER0_COUNT_CHANNEL2,
|
||||
CTIMER0_COUNT_CHANNEL3,
|
||||
CTIMER0_CAPTURE_CHANNEL0,
|
||||
CTIMER0_CAPTURE_CHANNEL1,
|
||||
CTIMER0_CAPTURE_CHANNEL2,
|
||||
CTIMER0_CAPTURE_CHANNEL3,
|
||||
CTIMER1_COUNT_CHANNEL0,
|
||||
CTIMER1_COUNT_CHANNEL1,
|
||||
CTIMER1_COUNT_CHANNEL2,
|
||||
CTIMER1_COUNT_CHANNEL3,
|
||||
CTIMER1_CAPTURE_CHANNEL0,
|
||||
CTIMER1_CAPTURE_CHANNEL1,
|
||||
CTIMER1_CAPTURE_CHANNEL2,
|
||||
CTIMER1_CAPTURE_CHANNEL3,
|
||||
CTIMER2_COUNT_CHANNEL0,
|
||||
CTIMER2_COUNT_CHANNEL1,
|
||||
CTIMER2_COUNT_CHANNEL2,
|
||||
CTIMER2_COUNT_CHANNEL3,
|
||||
CTIMER2_CAPTURE_CHANNEL0,
|
||||
CTIMER2_CAPTURE_CHANNEL1,
|
||||
CTIMER2_CAPTURE_CHANNEL2,
|
||||
CTIMER2_CAPTURE_CHANNEL3,
|
||||
CTIMER3_COUNT_CHANNEL0,
|
||||
CTIMER3_COUNT_CHANNEL1,
|
||||
CTIMER3_COUNT_CHANNEL2,
|
||||
CTIMER3_COUNT_CHANNEL3,
|
||||
CTIMER3_CAPTURE_CHANNEL0,
|
||||
CTIMER3_CAPTURE_CHANNEL1,
|
||||
CTIMER3_CAPTURE_CHANNEL2,
|
||||
CTIMER3_CAPTURE_CHANNEL3,
|
||||
CTIMER4_COUNT_CHANNEL0,
|
||||
CTIMER4_COUNT_CHANNEL1,
|
||||
CTIMER4_COUNT_CHANNEL2,
|
||||
CTIMER4_COUNT_CHANNEL3,
|
||||
CTIMER4_CAPTURE_CHANNEL0,
|
||||
CTIMER4_CAPTURE_CHANNEL1,
|
||||
CTIMER4_CAPTURE_CHANNEL2,
|
||||
CTIMER4_CAPTURE_CHANNEL3,
|
||||
DMA0,
|
||||
DMA0_CH0,
|
||||
DMA0_CH1,
|
||||
DMA0_CH2,
|
||||
DMA0_CH3,
|
||||
DMA0_CH4,
|
||||
DMA0_CH5,
|
||||
DMA0_CH6,
|
||||
DMA0_CH7,
|
||||
DMA0_CH8,
|
||||
DMA0_CH9,
|
||||
DMA0_CH10,
|
||||
DMA0_CH11,
|
||||
DMA0_CH12,
|
||||
DMA0_CH13,
|
||||
DMA0_CH14,
|
||||
DMA0_CH15,
|
||||
DMA0_CH16,
|
||||
DMA0_CH17,
|
||||
DMA0_CH18,
|
||||
DMA0_CH19,
|
||||
DMA0_CH20,
|
||||
DMA0_CH21,
|
||||
DMA0_CH22,
|
||||
DMA0_CH23,
|
||||
DMA0_CH24,
|
||||
DMA0_CH25,
|
||||
DMA0_CH26,
|
||||
DMA0_CH27,
|
||||
DMA0_CH28,
|
||||
DMA0_CH29,
|
||||
DMA0_CH30,
|
||||
DMA0_CH31,
|
||||
DMA0_CH32,
|
||||
DMA1,
|
||||
DMA1_CH0,
|
||||
DMA1_CH1,
|
||||
DMA1_CH2,
|
||||
DMA1_CH3,
|
||||
DMA1_CH4,
|
||||
DMA1_CH5,
|
||||
DMA1_CH6,
|
||||
DMA1_CH7,
|
||||
DMA1_CH8,
|
||||
DMA1_CH9,
|
||||
DMA1_CH10,
|
||||
DMA1_CH11,
|
||||
DMA1_CH12,
|
||||
DMA1_CH13,
|
||||
DMA1_CH14,
|
||||
DMA1_CH15,
|
||||
DMA1_CH16,
|
||||
DMA1_CH17,
|
||||
DMA1_CH18,
|
||||
DMA1_CH19,
|
||||
DMA1_CH20,
|
||||
DMA1_CH21,
|
||||
DMA1_CH22,
|
||||
DMA1_CH23,
|
||||
DMA1_CH24,
|
||||
DMA1_CH25,
|
||||
DMA1_CH26,
|
||||
DMA1_CH27,
|
||||
DMA1_CH28,
|
||||
DMA1_CH29,
|
||||
DMA1_CH30,
|
||||
DMA1_CH31,
|
||||
DMA1_CH32,
|
||||
DMIC0,
|
||||
DSPWAKE,
|
||||
ESPI,
|
||||
FLEXCOMM0,
|
||||
FLEXCOMM1,
|
||||
FLEXCOMM14,
|
||||
FLEXCOMM15,
|
||||
FLEXCOMM2,
|
||||
FLEXCOMM3,
|
||||
FLEXCOMM4,
|
||||
FLEXCOMM5,
|
||||
FLEXCOMM6,
|
||||
FLEXCOMM7,
|
||||
FLEXSPI,
|
||||
FREQME,
|
||||
GPIO_INTA,
|
||||
GPIO_INTB,
|
||||
HASHCRYPT,
|
||||
HSGPIO0,
|
||||
HSGPIO1,
|
||||
HSGPIO2,
|
||||
HSGPIO3,
|
||||
HSGPIO4,
|
||||
HSGPIO5,
|
||||
HSGPIO6,
|
||||
HSGPIO7,
|
||||
HWVAD0,
|
||||
HYPERVISOR,
|
||||
I3C0,
|
||||
MRT0,
|
||||
MU_A,
|
||||
OS_EVENT,
|
||||
PIN_INT0,
|
||||
PIN_INT1,
|
||||
PIN_INT2,
|
||||
PIN_INT3,
|
||||
PIN_INT4,
|
||||
PIN_INT5,
|
||||
PIN_INT6,
|
||||
PIN_INT7,
|
||||
PIO0_0,
|
||||
PIO0_1,
|
||||
PIO0_10,
|
||||
PIO0_11,
|
||||
PIO0_12,
|
||||
PIO0_13,
|
||||
PIO0_14,
|
||||
PIO0_15,
|
||||
PIO0_16,
|
||||
PIO0_17,
|
||||
PIO0_18,
|
||||
PIO0_19,
|
||||
PIO0_2,
|
||||
PIO0_20,
|
||||
PIO0_21,
|
||||
PIO0_22,
|
||||
PIO0_23,
|
||||
PIO0_24,
|
||||
PIO0_25,
|
||||
PIO0_26,
|
||||
PIO0_27,
|
||||
PIO0_28,
|
||||
PIO0_29,
|
||||
PIO0_3,
|
||||
PIO0_30,
|
||||
PIO0_31,
|
||||
PIO0_4,
|
||||
PIO0_5,
|
||||
PIO0_6,
|
||||
PIO0_7,
|
||||
PIO0_8,
|
||||
PIO0_9,
|
||||
PIO1_0,
|
||||
PIO1_1,
|
||||
PIO1_10,
|
||||
PIO1_11,
|
||||
PIO1_12,
|
||||
PIO1_13,
|
||||
PIO1_14,
|
||||
PIO1_15,
|
||||
PIO1_16,
|
||||
PIO1_17,
|
||||
PIO1_18,
|
||||
PIO1_19,
|
||||
PIO1_2,
|
||||
PIO1_20,
|
||||
PIO1_21,
|
||||
PIO1_22,
|
||||
PIO1_23,
|
||||
PIO1_24,
|
||||
PIO1_25,
|
||||
PIO1_26,
|
||||
PIO1_27,
|
||||
PIO1_28,
|
||||
PIO1_29,
|
||||
PIO1_3,
|
||||
PIO1_30,
|
||||
PIO1_31,
|
||||
PIO1_4,
|
||||
PIO1_5,
|
||||
PIO1_6,
|
||||
PIO1_7,
|
||||
PIO1_8,
|
||||
PIO1_9,
|
||||
PIO2_0,
|
||||
PIO2_1,
|
||||
PIO2_10,
|
||||
PIO2_11,
|
||||
PIO2_12,
|
||||
PIO2_13,
|
||||
PIO2_14,
|
||||
PIO2_15,
|
||||
PIO2_16,
|
||||
PIO2_17,
|
||||
PIO2_18,
|
||||
PIO2_19,
|
||||
PIO2_2,
|
||||
PIO2_20,
|
||||
PIO2_21,
|
||||
PIO2_22,
|
||||
PIO2_23,
|
||||
PIO2_24,
|
||||
PIO2_25,
|
||||
PIO2_26,
|
||||
PIO2_27,
|
||||
PIO2_28,
|
||||
PIO2_29,
|
||||
PIO2_3,
|
||||
PIO2_30,
|
||||
PIO2_31,
|
||||
PIO2_4,
|
||||
PIO2_5,
|
||||
PIO2_6,
|
||||
PIO2_7,
|
||||
PIO2_8,
|
||||
PIO2_9,
|
||||
PIO3_0,
|
||||
PIO3_1,
|
||||
PIO3_10,
|
||||
PIO3_11,
|
||||
PIO3_12,
|
||||
PIO3_13,
|
||||
PIO3_14,
|
||||
PIO3_15,
|
||||
PIO3_16,
|
||||
PIO3_17,
|
||||
PIO3_18,
|
||||
PIO3_19,
|
||||
PIO3_2,
|
||||
PIO3_20,
|
||||
PIO3_21,
|
||||
PIO3_22,
|
||||
PIO3_23,
|
||||
PIO3_24,
|
||||
PIO3_25,
|
||||
PIO3_26,
|
||||
PIO3_27,
|
||||
PIO3_28,
|
||||
PIO3_29,
|
||||
PIO3_3,
|
||||
PIO3_30,
|
||||
PIO3_31,
|
||||
PIO3_4,
|
||||
PIO3_5,
|
||||
PIO3_6,
|
||||
PIO3_7,
|
||||
PIO3_8,
|
||||
PIO3_9,
|
||||
PIO4_0,
|
||||
PIO4_1,
|
||||
PIO4_10,
|
||||
PIO4_2,
|
||||
PIO4_3,
|
||||
PIO4_4,
|
||||
PIO4_5,
|
||||
PIO4_6,
|
||||
PIO4_7,
|
||||
PIO4_8,
|
||||
PIO4_9,
|
||||
PIO7_24,
|
||||
PIO7_25,
|
||||
PIO7_26,
|
||||
PIO7_27,
|
||||
PIO7_28,
|
||||
PIO7_29,
|
||||
PIO7_30,
|
||||
PIO7_31,
|
||||
PIOFC15_SCL,
|
||||
PIOFC15_SDA,
|
||||
PMC_PMIC,
|
||||
PIMCTL,
|
||||
POWERQUAD,
|
||||
PUF,
|
||||
RNG,
|
||||
RTC,
|
||||
SCT0,
|
||||
SECGPIO,
|
||||
SECUREVIOLATION,
|
||||
SEMA42,
|
||||
SGPIO_INTA,
|
||||
SGPIO_INTB,
|
||||
USBHSD,
|
||||
USBHSH,
|
||||
USBPHY,
|
||||
USB_WAKEUP,
|
||||
USDHC0,
|
||||
USDHC1,
|
||||
UTICK0,
|
||||
WDT0,
|
||||
WDT1,
|
||||
);
|
388
embassy-imxrt/src/chips/mimxrt685s.rs
Normal file
388
embassy-imxrt/src/chips/mimxrt685s.rs
Normal file
@ -0,0 +1,388 @@
|
||||
pub use mimxrt685s_pac as pac;
|
||||
|
||||
#[allow(clippy::missing_safety_doc)]
|
||||
pub mod interrupts {
|
||||
embassy_hal_internal::interrupt_mod!(
|
||||
ACMP,
|
||||
ADC0,
|
||||
CASPER,
|
||||
CTIMER0,
|
||||
CTIMER1,
|
||||
CTIMER2,
|
||||
CTIMER3,
|
||||
CTIMER4,
|
||||
DMA0,
|
||||
DMA1,
|
||||
DMIC0,
|
||||
DSPWAKE,
|
||||
FLEXCOMM0,
|
||||
FLEXCOMM1,
|
||||
FLEXCOMM14,
|
||||
FLEXCOMM15,
|
||||
FLEXCOMM2,
|
||||
FLEXCOMM3,
|
||||
FLEXCOMM4,
|
||||
FLEXCOMM5,
|
||||
FLEXCOMM6,
|
||||
FLEXCOMM7,
|
||||
FLEXSPI,
|
||||
GPIO_INTA,
|
||||
GPIO_INTB,
|
||||
HASHCRYPT,
|
||||
HWVAD0,
|
||||
HYPERVISOR,
|
||||
I3C0,
|
||||
MRT0,
|
||||
MU_A,
|
||||
OS_EVENT,
|
||||
PIN_INT0,
|
||||
PIN_INT1,
|
||||
PIN_INT2,
|
||||
PIN_INT3,
|
||||
PIN_INT4,
|
||||
PIN_INT5,
|
||||
PIN_INT6,
|
||||
PIN_INT7,
|
||||
PMC_PMIC,
|
||||
POWERQUAD,
|
||||
PUF,
|
||||
RNG,
|
||||
RTC,
|
||||
SCT0,
|
||||
SECUREVIOLATION,
|
||||
SGPIO_INTA,
|
||||
SGPIO_INTB,
|
||||
USB,
|
||||
USBPHY_DCD,
|
||||
USB_WAKEUP,
|
||||
USDHC0,
|
||||
USDHC1,
|
||||
UTICK0,
|
||||
WDT0,
|
||||
WDT1,
|
||||
);
|
||||
}
|
||||
|
||||
embassy_hal_internal::peripherals!(
|
||||
ACMP,
|
||||
ADC0,
|
||||
CASPER,
|
||||
CRC,
|
||||
CTIMER0_COUNT_CHANNEL0,
|
||||
CTIMER0_COUNT_CHANNEL1,
|
||||
CTIMER0_COUNT_CHANNEL2,
|
||||
CTIMER0_COUNT_CHANNEL3,
|
||||
CTIMER0_CAPTURE_CHANNEL0,
|
||||
CTIMER0_CAPTURE_CHANNEL1,
|
||||
CTIMER0_CAPTURE_CHANNEL2,
|
||||
CTIMER0_CAPTURE_CHANNEL3,
|
||||
CTIMER1_COUNT_CHANNEL0,
|
||||
CTIMER1_COUNT_CHANNEL1,
|
||||
CTIMER1_COUNT_CHANNEL2,
|
||||
CTIMER1_COUNT_CHANNEL3,
|
||||
CTIMER1_CAPTURE_CHANNEL0,
|
||||
CTIMER1_CAPTURE_CHANNEL1,
|
||||
CTIMER1_CAPTURE_CHANNEL2,
|
||||
CTIMER1_CAPTURE_CHANNEL3,
|
||||
CTIMER2_COUNT_CHANNEL0,
|
||||
CTIMER2_COUNT_CHANNEL1,
|
||||
CTIMER2_COUNT_CHANNEL2,
|
||||
CTIMER2_COUNT_CHANNEL3,
|
||||
CTIMER2_CAPTURE_CHANNEL0,
|
||||
CTIMER2_CAPTURE_CHANNEL1,
|
||||
CTIMER2_CAPTURE_CHANNEL2,
|
||||
CTIMER2_CAPTURE_CHANNEL3,
|
||||
CTIMER3_COUNT_CHANNEL0,
|
||||
CTIMER3_COUNT_CHANNEL1,
|
||||
CTIMER3_COUNT_CHANNEL2,
|
||||
CTIMER3_COUNT_CHANNEL3,
|
||||
CTIMER3_CAPTURE_CHANNEL0,
|
||||
CTIMER3_CAPTURE_CHANNEL1,
|
||||
CTIMER3_CAPTURE_CHANNEL2,
|
||||
CTIMER3_CAPTURE_CHANNEL3,
|
||||
CTIMER4_COUNT_CHANNEL0,
|
||||
CTIMER4_COUNT_CHANNEL1,
|
||||
CTIMER4_COUNT_CHANNEL2,
|
||||
CTIMER4_COUNT_CHANNEL3,
|
||||
CTIMER4_CAPTURE_CHANNEL0,
|
||||
CTIMER4_CAPTURE_CHANNEL1,
|
||||
CTIMER4_CAPTURE_CHANNEL2,
|
||||
CTIMER4_CAPTURE_CHANNEL3,
|
||||
DMA0,
|
||||
DMA0_CH0,
|
||||
DMA0_CH1,
|
||||
DMA0_CH2,
|
||||
DMA0_CH3,
|
||||
DMA0_CH4,
|
||||
DMA0_CH5,
|
||||
DMA0_CH6,
|
||||
DMA0_CH7,
|
||||
DMA0_CH8,
|
||||
DMA0_CH9,
|
||||
DMA0_CH10,
|
||||
DMA0_CH11,
|
||||
DMA0_CH12,
|
||||
DMA0_CH13,
|
||||
DMA0_CH14,
|
||||
DMA0_CH15,
|
||||
DMA0_CH16,
|
||||
DMA0_CH17,
|
||||
DMA0_CH18,
|
||||
DMA0_CH19,
|
||||
DMA0_CH20,
|
||||
DMA0_CH21,
|
||||
DMA0_CH22,
|
||||
DMA0_CH23,
|
||||
DMA0_CH24,
|
||||
DMA0_CH25,
|
||||
DMA0_CH26,
|
||||
DMA0_CH27,
|
||||
DMA0_CH28,
|
||||
DMA0_CH29,
|
||||
DMA0_CH30,
|
||||
DMA0_CH31,
|
||||
DMA0_CH32,
|
||||
DMA1,
|
||||
DMA1_CH0,
|
||||
DMA1_CH1,
|
||||
DMA1_CH2,
|
||||
DMA1_CH3,
|
||||
DMA1_CH4,
|
||||
DMA1_CH5,
|
||||
DMA1_CH6,
|
||||
DMA1_CH7,
|
||||
DMA1_CH8,
|
||||
DMA1_CH9,
|
||||
DMA1_CH10,
|
||||
DMA1_CH11,
|
||||
DMA1_CH12,
|
||||
DMA1_CH13,
|
||||
DMA1_CH14,
|
||||
DMA1_CH15,
|
||||
DMA1_CH16,
|
||||
DMA1_CH17,
|
||||
DMA1_CH18,
|
||||
DMA1_CH19,
|
||||
DMA1_CH20,
|
||||
DMA1_CH21,
|
||||
DMA1_CH22,
|
||||
DMA1_CH23,
|
||||
DMA1_CH24,
|
||||
DMA1_CH25,
|
||||
DMA1_CH26,
|
||||
DMA1_CH27,
|
||||
DMA1_CH28,
|
||||
DMA1_CH29,
|
||||
DMA1_CH30,
|
||||
DMA1_CH31,
|
||||
DMA1_CH32,
|
||||
DMIC0,
|
||||
DSPWAKE,
|
||||
FLEXCOMM0,
|
||||
FLEXCOMM1,
|
||||
FLEXCOMM14,
|
||||
FLEXCOMM15,
|
||||
FLEXCOMM2,
|
||||
FLEXCOMM3,
|
||||
FLEXCOMM4,
|
||||
FLEXCOMM5,
|
||||
FLEXCOMM6,
|
||||
FLEXCOMM7,
|
||||
FLEXSPI,
|
||||
FREQME,
|
||||
GPIO_INTA,
|
||||
GPIO_INTB,
|
||||
HASHCRYPT,
|
||||
HSGPIO0,
|
||||
HSGPIO1,
|
||||
HSGPIO2,
|
||||
HSGPIO3,
|
||||
HSGPIO4,
|
||||
HSGPIO5,
|
||||
HSGPIO6,
|
||||
HSGPIO7,
|
||||
HWVAD0,
|
||||
HYPERVISOR,
|
||||
I3C0,
|
||||
MRT0,
|
||||
MU_A,
|
||||
OS_EVENT,
|
||||
PIN_INT0,
|
||||
PIN_INT1,
|
||||
PIN_INT2,
|
||||
PIN_INT3,
|
||||
PIN_INT4,
|
||||
PIN_INT5,
|
||||
PIN_INT6,
|
||||
PIN_INT7,
|
||||
PIO0_0,
|
||||
PIO0_1,
|
||||
PIO0_10,
|
||||
PIO0_11,
|
||||
PIO0_12,
|
||||
PIO0_13,
|
||||
PIO0_14,
|
||||
PIO0_15,
|
||||
PIO0_16,
|
||||
PIO0_17,
|
||||
PIO0_18,
|
||||
PIO0_19,
|
||||
PIO0_2,
|
||||
PIO0_20,
|
||||
PIO0_21,
|
||||
PIO0_22,
|
||||
PIO0_23,
|
||||
PIO0_24,
|
||||
PIO0_25,
|
||||
PIO0_26,
|
||||
PIO0_27,
|
||||
PIO0_28,
|
||||
PIO0_29,
|
||||
PIO0_3,
|
||||
PIO0_30,
|
||||
PIO0_31,
|
||||
PIO0_4,
|
||||
PIO0_5,
|
||||
PIO0_6,
|
||||
PIO0_7,
|
||||
PIO0_8,
|
||||
PIO0_9,
|
||||
PIO1_0,
|
||||
PIO1_1,
|
||||
PIO1_10,
|
||||
PIO1_11,
|
||||
PIO1_12,
|
||||
PIO1_13,
|
||||
PIO1_14,
|
||||
PIO1_15,
|
||||
PIO1_16,
|
||||
PIO1_17,
|
||||
PIO1_18,
|
||||
PIO1_19,
|
||||
PIO1_2,
|
||||
PIO1_20,
|
||||
PIO1_21,
|
||||
PIO1_22,
|
||||
PIO1_23,
|
||||
PIO1_24,
|
||||
PIO1_25,
|
||||
PIO1_26,
|
||||
PIO1_27,
|
||||
PIO1_28,
|
||||
PIO1_29,
|
||||
PIO1_3,
|
||||
PIO1_30,
|
||||
PIO1_31,
|
||||
PIO1_4,
|
||||
PIO1_5,
|
||||
PIO1_6,
|
||||
PIO1_7,
|
||||
PIO1_8,
|
||||
PIO1_9,
|
||||
PIO2_0,
|
||||
PIO2_1,
|
||||
PIO2_10,
|
||||
PIO2_11,
|
||||
PIO2_12,
|
||||
PIO2_13,
|
||||
PIO2_14,
|
||||
PIO2_15,
|
||||
PIO2_16,
|
||||
PIO2_17,
|
||||
PIO2_18,
|
||||
PIO2_19,
|
||||
PIO2_2,
|
||||
PIO2_20,
|
||||
PIO2_21,
|
||||
PIO2_22,
|
||||
PIO2_23,
|
||||
PIO2_24,
|
||||
PIO2_25,
|
||||
PIO2_26,
|
||||
PIO2_27,
|
||||
PIO2_28,
|
||||
PIO2_29,
|
||||
PIO2_3,
|
||||
PIO2_30,
|
||||
PIO2_31,
|
||||
PIO2_4,
|
||||
PIO2_5,
|
||||
PIO2_6,
|
||||
PIO2_7,
|
||||
PIO2_8,
|
||||
PIO2_9,
|
||||
PIO3_0,
|
||||
PIO3_1,
|
||||
PIO3_10,
|
||||
PIO3_11,
|
||||
PIO3_12,
|
||||
PIO3_13,
|
||||
PIO3_14,
|
||||
PIO3_15,
|
||||
PIO3_16,
|
||||
PIO3_17,
|
||||
PIO3_18,
|
||||
PIO3_19,
|
||||
PIO3_2,
|
||||
PIO3_20,
|
||||
PIO3_21,
|
||||
PIO3_22,
|
||||
PIO3_23,
|
||||
PIO3_24,
|
||||
PIO3_25,
|
||||
PIO3_26,
|
||||
PIO3_27,
|
||||
PIO3_28,
|
||||
PIO3_29,
|
||||
PIO3_3,
|
||||
PIO3_30,
|
||||
PIO3_31,
|
||||
PIO3_4,
|
||||
PIO3_5,
|
||||
PIO3_6,
|
||||
PIO3_7,
|
||||
PIO3_8,
|
||||
PIO3_9,
|
||||
PIO4_0,
|
||||
PIO4_1,
|
||||
PIO4_10,
|
||||
PIO4_2,
|
||||
PIO4_3,
|
||||
PIO4_4,
|
||||
PIO4_5,
|
||||
PIO4_6,
|
||||
PIO4_7,
|
||||
PIO4_8,
|
||||
PIO4_9,
|
||||
PIO7_24,
|
||||
PIO7_25,
|
||||
PIO7_26,
|
||||
PIO7_27,
|
||||
PIO7_28,
|
||||
PIO7_29,
|
||||
PIO7_30,
|
||||
PIO7_31,
|
||||
PIOFC15_SCL,
|
||||
PIOFC15_SDA,
|
||||
PMC_PMIC,
|
||||
PIMCTL,
|
||||
POWERQUAD,
|
||||
PUF,
|
||||
RNG,
|
||||
RTC,
|
||||
SCT0,
|
||||
SECGPIO,
|
||||
SECUREVIOLATION,
|
||||
SEMA42,
|
||||
SGPIO_INTA,
|
||||
SGPIO_INTB,
|
||||
USBHSD,
|
||||
USBHSH,
|
||||
USBPHY,
|
||||
USB_WAKEUP,
|
||||
USDHC0,
|
||||
USDHC1,
|
||||
UTICK0,
|
||||
WDT0,
|
||||
WDT1,
|
||||
);
|
1687
embassy-imxrt/src/clocks.rs
Normal file
1687
embassy-imxrt/src/clocks.rs
Normal file
File diff suppressed because it is too large
Load Diff
257
embassy-imxrt/src/fmt.rs
Normal file
257
embassy-imxrt/src/fmt.rs
Normal file
@ -0,0 +1,257 @@
|
||||
#![macro_use]
|
||||
#![allow(unused)]
|
||||
|
||||
use core::fmt::{Debug, Display, LowerHex};
|
||||
|
||||
#[collapse_debuginfo(yes)]
|
||||
macro_rules! assert {
|
||||
($($x:tt)*) => {
|
||||
{
|
||||
#[cfg(not(feature = "defmt"))]
|
||||
::core::assert!($($x)*);
|
||||
#[cfg(feature = "defmt")]
|
||||
::defmt::assert!($($x)*);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[collapse_debuginfo(yes)]
|
||||
macro_rules! assert_eq {
|
||||
($($x:tt)*) => {
|
||||
{
|
||||
#[cfg(not(feature = "defmt"))]
|
||||
::core::assert_eq!($($x)*);
|
||||
#[cfg(feature = "defmt")]
|
||||
::defmt::assert_eq!($($x)*);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[collapse_debuginfo(yes)]
|
||||
macro_rules! assert_ne {
|
||||
($($x:tt)*) => {
|
||||
{
|
||||
#[cfg(not(feature = "defmt"))]
|
||||
::core::assert_ne!($($x)*);
|
||||
#[cfg(feature = "defmt")]
|
||||
::defmt::assert_ne!($($x)*);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[collapse_debuginfo(yes)]
|
||||
macro_rules! debug_assert {
|
||||
($($x:tt)*) => {
|
||||
{
|
||||
#[cfg(not(feature = "defmt"))]
|
||||
::core::debug_assert!($($x)*);
|
||||
#[cfg(feature = "defmt")]
|
||||
::defmt::debug_assert!($($x)*);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[collapse_debuginfo(yes)]
|
||||
macro_rules! debug_assert_eq {
|
||||
($($x:tt)*) => {
|
||||
{
|
||||
#[cfg(not(feature = "defmt"))]
|
||||
::core::debug_assert_eq!($($x)*);
|
||||
#[cfg(feature = "defmt")]
|
||||
::defmt::debug_assert_eq!($($x)*);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[collapse_debuginfo(yes)]
|
||||
macro_rules! debug_assert_ne {
|
||||
($($x:tt)*) => {
|
||||
{
|
||||
#[cfg(not(feature = "defmt"))]
|
||||
::core::debug_assert_ne!($($x)*);
|
||||
#[cfg(feature = "defmt")]
|
||||
::defmt::debug_assert_ne!($($x)*);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[collapse_debuginfo(yes)]
|
||||
macro_rules! todo {
|
||||
($($x:tt)*) => {
|
||||
{
|
||||
#[cfg(not(feature = "defmt"))]
|
||||
::core::todo!($($x)*);
|
||||
#[cfg(feature = "defmt")]
|
||||
::defmt::todo!($($x)*);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[collapse_debuginfo(yes)]
|
||||
macro_rules! unreachable {
|
||||
($($x:tt)*) => {
|
||||
{
|
||||
#[cfg(not(feature = "defmt"))]
|
||||
::core::unreachable!($($x)*);
|
||||
#[cfg(feature = "defmt")]
|
||||
::defmt::unreachable!($($x)*);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[collapse_debuginfo(yes)]
|
||||
macro_rules! panic {
|
||||
($($x:tt)*) => {
|
||||
{
|
||||
#[cfg(not(feature = "defmt"))]
|
||||
::core::panic!($($x)*);
|
||||
#[cfg(feature = "defmt")]
|
||||
::defmt::panic!($($x)*);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[collapse_debuginfo(yes)]
|
||||
macro_rules! trace {
|
||||
($s:literal $(, $x:expr)* $(,)?) => {
|
||||
{
|
||||
#[cfg(feature = "defmt")]
|
||||
::defmt::trace!($s $(, $x)*);
|
||||
#[cfg(not(feature = "defmt"))]
|
||||
let _ = ($( & $x ),*);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[collapse_debuginfo(yes)]
|
||||
macro_rules! debug {
|
||||
($s:literal $(, $x:expr)* $(,)?) => {
|
||||
{
|
||||
#[cfg(feature = "defmt")]
|
||||
::defmt::debug!($s $(, $x)*);
|
||||
#[cfg(not(feature = "defmt"))]
|
||||
let _ = ($( & $x ),*);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[collapse_debuginfo(yes)]
|
||||
macro_rules! info {
|
||||
($s:literal $(, $x:expr)* $(,)?) => {
|
||||
{
|
||||
#[cfg(feature = "defmt")]
|
||||
::defmt::info!($s $(, $x)*);
|
||||
#[cfg(not(feature = "defmt"))]
|
||||
let _ = ($( & $x ),*);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[collapse_debuginfo(yes)]
|
||||
macro_rules! warn {
|
||||
($s:literal $(, $x:expr)* $(,)?) => {
|
||||
{
|
||||
#[cfg(feature = "defmt")]
|
||||
::defmt::warn!($s $(, $x)*);
|
||||
#[cfg(not(feature = "defmt"))]
|
||||
let _ = ($( & $x ),*);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[collapse_debuginfo(yes)]
|
||||
macro_rules! error {
|
||||
($s:literal $(, $x:expr)* $(,)?) => {
|
||||
{
|
||||
#[cfg(feature = "defmt")]
|
||||
::defmt::error!($s $(, $x)*);
|
||||
#[cfg(not(feature = "defmt"))]
|
||||
let _ = ($( & $x ),*);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[cfg(feature = "defmt")]
|
||||
#[collapse_debuginfo(yes)]
|
||||
macro_rules! unwrap {
|
||||
($($x:tt)*) => {
|
||||
::defmt::unwrap!($($x)*)
|
||||
};
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "defmt"))]
|
||||
#[collapse_debuginfo(yes)]
|
||||
macro_rules! unwrap {
|
||||
($arg:expr) => {
|
||||
match $crate::fmt::Try::into_result($arg) {
|
||||
::core::result::Result::Ok(t) => t,
|
||||
::core::result::Result::Err(e) => {
|
||||
::core::panic!("unwrap of `{}` failed: {:?}", ::core::stringify!($arg), e);
|
||||
}
|
||||
}
|
||||
};
|
||||
($arg:expr, $($msg:expr),+ $(,)? ) => {
|
||||
match $crate::fmt::Try::into_result($arg) {
|
||||
::core::result::Result::Ok(t) => t,
|
||||
::core::result::Result::Err(e) => {
|
||||
::core::panic!("unwrap of `{}` failed: {}: {:?}", ::core::stringify!($arg), ::core::format_args!($($msg,)*), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
||||
pub struct NoneError;
|
||||
|
||||
pub trait Try {
|
||||
type Ok;
|
||||
type Error;
|
||||
fn into_result(self) -> Result<Self::Ok, Self::Error>;
|
||||
}
|
||||
|
||||
impl<T> Try for Option<T> {
|
||||
type Ok = T;
|
||||
type Error = NoneError;
|
||||
|
||||
#[inline]
|
||||
fn into_result(self) -> Result<T, NoneError> {
|
||||
self.ok_or(NoneError)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, E> Try for Result<T, E> {
|
||||
type Ok = T;
|
||||
type Error = E;
|
||||
|
||||
#[inline]
|
||||
fn into_result(self) -> Self {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) struct Bytes<'a>(pub &'a [u8]);
|
||||
|
||||
impl Debug for Bytes<'_> {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
write!(f, "{:#02x?}", self.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Bytes<'_> {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
write!(f, "{:#02x?}", self.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl LowerHex for Bytes<'_> {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
write!(f, "{:#02x?}", self.0)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "defmt")]
|
||||
impl defmt::Format for Bytes<'_> {
|
||||
fn format(&self, fmt: defmt::Formatter) {
|
||||
defmt::write!(fmt, "{:02x}", self.0)
|
||||
}
|
||||
}
|
1060
embassy-imxrt/src/gpio.rs
Normal file
1060
embassy-imxrt/src/gpio.rs
Normal file
File diff suppressed because it is too large
Load Diff
717
embassy-imxrt/src/iopctl.rs
Normal file
717
embassy-imxrt/src/iopctl.rs
Normal file
@ -0,0 +1,717 @@
|
||||
//! IO Pad Controller (IOPCTL)
|
||||
//!
|
||||
//! Also known as IO Pin Configuration (IOCON)
|
||||
|
||||
use crate::pac::{iopctl, Iopctl};
|
||||
|
||||
// A generic pin of any type.
|
||||
//
|
||||
// The actual pin type used here is arbitrary,
|
||||
// as all PioM_N types provide the same methods.
|
||||
//
|
||||
// Merely need some pin type to cast a raw pointer
|
||||
// to in order to access the provided methods.
|
||||
#[allow(non_camel_case_types)]
|
||||
type PioM_N = iopctl::Pio0_0;
|
||||
|
||||
/// Pin function number.
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||
pub enum Function {
|
||||
/// Function 0
|
||||
F0,
|
||||
/// Function 1
|
||||
F1,
|
||||
/// Function 2
|
||||
F2,
|
||||
/// Function 3
|
||||
F3,
|
||||
/// Function 4
|
||||
F4,
|
||||
/// Function 5
|
||||
F5,
|
||||
/// Function 6
|
||||
F6,
|
||||
/// Function 7
|
||||
F7,
|
||||
/// Function 8
|
||||
F8,
|
||||
}
|
||||
|
||||
/// Internal pull-up/down resistors on a pin.
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||
pub enum Pull {
|
||||
/// No pull-up or pull-down resistor selected
|
||||
None,
|
||||
/// Pull-up resistor
|
||||
Up,
|
||||
/// Pull-down resistor
|
||||
Down,
|
||||
}
|
||||
|
||||
/// Pin slew rate.
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||
pub enum SlewRate {
|
||||
/// Standard slew rate
|
||||
Standard,
|
||||
/// Slow slew rate
|
||||
Slow,
|
||||
}
|
||||
|
||||
/// Output drive strength of a pin.
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||
pub enum DriveStrength {
|
||||
/// Normal
|
||||
Normal,
|
||||
/// Full
|
||||
Full,
|
||||
}
|
||||
|
||||
/// Output drive mode of a pin.
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||
pub enum DriveMode {
|
||||
/// Push-Pull
|
||||
PushPull,
|
||||
/// Pseudo Open-Drain
|
||||
OpenDrain,
|
||||
}
|
||||
|
||||
/// Input inverter of a pin.
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||
pub enum Inverter {
|
||||
/// No inverter
|
||||
Disabled,
|
||||
/// Enable input inverter on the input port. A low signal will be
|
||||
/// seen as a high signal by the pin.
|
||||
Enabled,
|
||||
}
|
||||
|
||||
trait SealedPin {}
|
||||
trait ToAnyPin: SealedPin {
|
||||
#[inline]
|
||||
fn to_raw(port: u8, pin: u8) -> AnyPin {
|
||||
// SAFETY: This is safe since this is only called from within the module,
|
||||
// where the port and pin numbers have been verified to be correct.
|
||||
unsafe { AnyPin::steal(port, pin) }
|
||||
}
|
||||
}
|
||||
|
||||
trait ToFC15Pin: SealedPin {
|
||||
#[inline]
|
||||
fn to_raw(pin: u8) -> FC15Pin {
|
||||
// SAFETY: This is safe since this is only called from within the module,
|
||||
// where the port and pin numbers have been verified to be correct.
|
||||
unsafe { FC15Pin::steal(pin) }
|
||||
}
|
||||
}
|
||||
|
||||
/// A pin that can be configured via iopctl.
|
||||
#[allow(private_bounds)]
|
||||
pub trait IopctlPin: SealedPin {
|
||||
/// Sets the function number of a pin.
|
||||
///
|
||||
/// This number corresponds to a specific function that the pin supports.
|
||||
///
|
||||
/// Typically, function 0 corresponds to GPIO while other numbers correspond to a special function.
|
||||
///
|
||||
/// See Section 7.5.3 in reference manual for list of pins and their supported functions.
|
||||
fn set_function(&self, function: Function) -> &Self;
|
||||
|
||||
/// Enables either a pull-up or pull-down resistor on a pin.
|
||||
///
|
||||
/// Setting this to [`Pull::None`] will disable the resistor.
|
||||
fn set_pull(&self, pull: Pull) -> &Self;
|
||||
|
||||
/// Enables the input buffer of a pin.
|
||||
///
|
||||
/// This must be enabled for any pin acting as an input,
|
||||
/// and some peripheral pins acting as output may need this enabled as well.
|
||||
///
|
||||
/// If there is any doubt, it is best to enable the input buffer.
|
||||
///
|
||||
/// See Section 7.4.2.3 of reference manual.
|
||||
fn enable_input_buffer(&self) -> &Self;
|
||||
|
||||
/// Disables the input buffer of a pin.
|
||||
fn disable_input_buffer(&self) -> &Self;
|
||||
|
||||
/// Sets the slew rate of a pin.
|
||||
///
|
||||
/// This controls the speed at which a pin can toggle,
|
||||
/// which is voltage and load dependent.
|
||||
fn set_slew_rate(&self, slew_rate: SlewRate) -> &Self;
|
||||
|
||||
/// Sets the output drive strength of a pin.
|
||||
///
|
||||
/// A drive strength of [`DriveStrength::Full`] has twice the
|
||||
/// high and low drive capability of the [`DriveStrength::Normal`] setting.
|
||||
fn set_drive_strength(&self, strength: DriveStrength) -> &Self;
|
||||
|
||||
/// Enables the analog multiplexer of a pin.
|
||||
///
|
||||
/// This must be called to allow analog functionalities of a pin.
|
||||
///
|
||||
/// To protect the analog input, [`IopctlPin::set_function`] should be
|
||||
/// called with [`Function::F0`] to disable digital functions.
|
||||
///
|
||||
/// Additionally, [`IopctlPin::disable_input_buffer`] and [`IopctlPin::set_pull`]
|
||||
/// with [`Pull::None`] should be called.
|
||||
fn enable_analog_multiplex(&self) -> &Self;
|
||||
|
||||
/// Disables the analog multiplexer of a pin.
|
||||
fn disable_analog_multiplex(&self) -> &Self;
|
||||
|
||||
/// Sets the ouput drive mode of a pin.
|
||||
///
|
||||
/// A pin configured as [`DriveMode::OpenDrain`] actually operates in
|
||||
/// a "pseudo" open-drain mode which is somewhat different than true open-drain.
|
||||
///
|
||||
/// See Section 7.4.2.7 of reference manual.
|
||||
fn set_drive_mode(&self, mode: DriveMode) -> &Self;
|
||||
|
||||
/// Sets the input inverter of an input pin.
|
||||
///
|
||||
/// Setting this to [`Inverter::Enabled`] will invert
|
||||
/// the input signal.
|
||||
fn set_input_inverter(&self, inverter: Inverter) -> &Self;
|
||||
|
||||
/// Returns a pin to its reset state.
|
||||
fn reset(&self) -> &Self;
|
||||
}
|
||||
|
||||
/// Represents a pin peripheral created at run-time from given port and pin numbers.
|
||||
pub struct AnyPin {
|
||||
pin_port: u8,
|
||||
reg: &'static PioM_N,
|
||||
}
|
||||
|
||||
impl AnyPin {
|
||||
/// Creates a pin from raw port and pin numbers which can then be configured.
|
||||
///
|
||||
/// This should ONLY be called when there is no other choice
|
||||
/// (e.g. from a type-erased GPIO pin).
|
||||
///
|
||||
/// Otherwise, pin peripherals should be configured directly.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// The caller MUST ensure valid port and pin numbers are provided,
|
||||
/// and that multiple instances of [`AnyPin`] with the same port
|
||||
/// and pin combination are not being used simultaneously.
|
||||
///
|
||||
/// Failure to uphold these requirements will result in undefined behavior.
|
||||
///
|
||||
/// See Table 297 in reference manual for a list of valid
|
||||
/// pin and port number combinations.
|
||||
#[must_use]
|
||||
pub unsafe fn steal(port: u8, pin: u8) -> Self {
|
||||
// Calculates the offset from the beginning of the IOPCTL register block
|
||||
// address to the register address representing the pin.
|
||||
//
|
||||
// See Table 297 in reference manual for how this offset is calculated.
|
||||
let offset = ((port as usize) << 7) + ((pin as usize) << 2);
|
||||
|
||||
// SAFETY: This is safe assuming the caller of this function satisfies the safety requirements above.
|
||||
let reg = unsafe { &*Iopctl::ptr().byte_offset(offset as isize).cast() };
|
||||
Self {
|
||||
pin_port: port * 32 + pin,
|
||||
reg,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the pin's port and pin combination.
|
||||
#[must_use]
|
||||
pub fn pin_port(&self) -> usize {
|
||||
self.pin_port as usize
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents a FC15 pin peripheral created at run-time from given pin number.
|
||||
pub struct FC15Pin {
|
||||
reg: &'static PioM_N,
|
||||
}
|
||||
|
||||
impl FC15Pin {
|
||||
/// Creates an FC15 pin from raw pin number which can then be configured.
|
||||
///
|
||||
/// This should ONLY be called when there is no other choice
|
||||
/// (e.g. from a type-erased GPIO pin).
|
||||
///
|
||||
/// Otherwise, pin peripherals should be configured directly.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// The caller MUST ensure valid port and pin numbers are provided,
|
||||
/// and that multiple instances of [`AnyPin`] with the same port
|
||||
/// and pin combination are not being used simultaneously.
|
||||
///
|
||||
/// Failure to uphold these requirements will result in undefined behavior.
|
||||
///
|
||||
/// See Table 297 in reference manual for a list of valid
|
||||
/// pin and port number combinations.
|
||||
#[must_use]
|
||||
pub unsafe fn steal(pin: u8) -> Self {
|
||||
// Table 297: FC15_I2C_SCL offset = 0x400, FC15_I2C_SCL offset = 0x404
|
||||
let iopctl = unsafe { crate::pac::Iopctl::steal() };
|
||||
|
||||
let reg = if pin == 0 {
|
||||
&*iopctl.fc15_i2c_scl().as_ptr().cast()
|
||||
} else {
|
||||
&*iopctl.fc15_i2c_sda().as_ptr().cast()
|
||||
};
|
||||
|
||||
Self { reg }
|
||||
}
|
||||
}
|
||||
|
||||
// This allows AnyPin/FC15Pin to be used in HAL constructors that require types
|
||||
// which impl Peripheral. Used primarily by GPIO HAL to convert type-erased
|
||||
// GPIO pins back into an Output or Input pin specifically.
|
||||
embassy_hal_internal::impl_peripheral!(AnyPin);
|
||||
|
||||
impl SealedPin for AnyPin {}
|
||||
|
||||
embassy_hal_internal::impl_peripheral!(FC15Pin);
|
||||
|
||||
impl SealedPin for FC15Pin {}
|
||||
|
||||
macro_rules! impl_iopctlpin {
|
||||
($pintype:ident) => {
|
||||
impl IopctlPin for $pintype {
|
||||
fn set_function(&self, function: Function) -> &Self {
|
||||
critical_section::with(|_| match function {
|
||||
Function::F0 => {
|
||||
self.reg.modify(|_, w| w.fsel().function_0());
|
||||
}
|
||||
Function::F1 => {
|
||||
self.reg.modify(|_, w| w.fsel().function_1());
|
||||
}
|
||||
Function::F2 => {
|
||||
self.reg.modify(|_, w| w.fsel().function_2());
|
||||
}
|
||||
Function::F3 => {
|
||||
self.reg.modify(|_, w| w.fsel().function_3());
|
||||
}
|
||||
Function::F4 => {
|
||||
self.reg.modify(|_, w| w.fsel().function_4());
|
||||
}
|
||||
Function::F5 => {
|
||||
self.reg.modify(|_, w| w.fsel().function_5());
|
||||
}
|
||||
Function::F6 => {
|
||||
self.reg.modify(|_, w| w.fsel().function_6());
|
||||
}
|
||||
Function::F7 => {
|
||||
self.reg.modify(|_, w| w.fsel().function_7());
|
||||
}
|
||||
Function::F8 => {
|
||||
self.reg.modify(|_, w| w.fsel().function_8());
|
||||
}
|
||||
});
|
||||
self
|
||||
}
|
||||
|
||||
fn set_pull(&self, pull: Pull) -> &Self {
|
||||
critical_section::with(|_| {
|
||||
match pull {
|
||||
Pull::None => {
|
||||
self.reg.modify(|_, w| w.pupdena().disabled());
|
||||
}
|
||||
Pull::Up => {
|
||||
self.reg.modify(|_, w| w.pupdena().enabled().pupdsel().pull_up());
|
||||
}
|
||||
Pull::Down => {
|
||||
self.reg
|
||||
.modify(|_, w| w.pupdena().enabled().pupdsel().pull_down());
|
||||
}
|
||||
}
|
||||
self
|
||||
})
|
||||
}
|
||||
|
||||
fn enable_input_buffer(&self) -> &Self {
|
||||
critical_section::with(|_| self.reg.modify(|_, w| w.ibena().enabled()));
|
||||
self
|
||||
}
|
||||
|
||||
fn disable_input_buffer(&self) -> &Self {
|
||||
critical_section::with(|_| self.reg.modify(|_, w| w.ibena().disabled()));
|
||||
self
|
||||
}
|
||||
|
||||
fn set_slew_rate(&self, slew_rate: SlewRate) -> &Self {
|
||||
critical_section::with(|_| match slew_rate {
|
||||
SlewRate::Standard => {
|
||||
self.reg.modify(|_, w| w.slewrate().normal());
|
||||
}
|
||||
SlewRate::Slow => {
|
||||
self.reg.modify(|_, w| w.slewrate().slow());
|
||||
}
|
||||
});
|
||||
self
|
||||
}
|
||||
|
||||
fn set_drive_strength(&self, strength: DriveStrength) -> &Self {
|
||||
critical_section::with(|_| match strength {
|
||||
DriveStrength::Normal => {
|
||||
self.reg.modify(|_, w| w.fulldrive().normal_drive());
|
||||
}
|
||||
DriveStrength::Full => {
|
||||
self.reg.modify(|_, w| w.fulldrive().full_drive());
|
||||
}
|
||||
});
|
||||
self
|
||||
}
|
||||
|
||||
fn enable_analog_multiplex(&self) -> &Self {
|
||||
critical_section::with(|_| self.reg.modify(|_, w| w.amena().enabled()));
|
||||
self
|
||||
}
|
||||
|
||||
fn disable_analog_multiplex(&self) -> &Self {
|
||||
critical_section::with(|_| self.reg.modify(|_, w| w.amena().disabled()));
|
||||
self
|
||||
}
|
||||
|
||||
fn set_drive_mode(&self, mode: DriveMode) -> &Self {
|
||||
critical_section::with(|_| match mode {
|
||||
DriveMode::PushPull => {
|
||||
self.reg.modify(|_, w| w.odena().disabled());
|
||||
}
|
||||
DriveMode::OpenDrain => {
|
||||
self.reg.modify(|_, w| w.odena().enabled());
|
||||
}
|
||||
});
|
||||
self
|
||||
}
|
||||
|
||||
fn set_input_inverter(&self, inverter: Inverter) -> &Self {
|
||||
critical_section::with(|_| match inverter {
|
||||
Inverter::Disabled => {
|
||||
self.reg.modify(|_, w| w.iiena().disabled());
|
||||
}
|
||||
Inverter::Enabled => {
|
||||
self.reg.modify(|_, w| w.iiena().enabled());
|
||||
}
|
||||
});
|
||||
self
|
||||
}
|
||||
|
||||
fn reset(&self) -> &Self {
|
||||
self.reg.reset();
|
||||
self
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
impl_iopctlpin!(AnyPin);
|
||||
impl_iopctlpin!(FC15Pin);
|
||||
|
||||
macro_rules! impl_FC15pin {
|
||||
($pin_periph:ident, $pin_no:expr) => {
|
||||
impl SealedPin for crate::peripherals::$pin_periph {}
|
||||
impl ToFC15Pin for crate::peripherals::$pin_periph {}
|
||||
impl IopctlPin for crate::peripherals::$pin_periph {
|
||||
#[inline]
|
||||
fn set_function(&self, _function: Function) -> &Self {
|
||||
//No function configuration for FC15 pin
|
||||
self
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_pull(&self, pull: Pull) -> &Self {
|
||||
Self::to_raw($pin_no).set_pull(pull);
|
||||
self
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn enable_input_buffer(&self) -> &Self {
|
||||
Self::to_raw($pin_no).enable_input_buffer();
|
||||
self
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn disable_input_buffer(&self) -> &Self {
|
||||
Self::to_raw($pin_no).disable_input_buffer();
|
||||
self
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_slew_rate(&self, slew_rate: SlewRate) -> &Self {
|
||||
Self::to_raw($pin_no).set_slew_rate(slew_rate);
|
||||
self
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_drive_strength(&self, strength: DriveStrength) -> &Self {
|
||||
Self::to_raw($pin_no).set_drive_strength(strength);
|
||||
self
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn enable_analog_multiplex(&self) -> &Self {
|
||||
Self::to_raw($pin_no).enable_analog_multiplex();
|
||||
self
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn disable_analog_multiplex(&self) -> &Self {
|
||||
Self::to_raw($pin_no).disable_analog_multiplex();
|
||||
self
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_drive_mode(&self, mode: DriveMode) -> &Self {
|
||||
Self::to_raw($pin_no).set_drive_mode(mode);
|
||||
self
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_input_inverter(&self, inverter: Inverter) -> &Self {
|
||||
Self::to_raw($pin_no).set_input_inverter(inverter);
|
||||
self
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn reset(&self) -> &Self {
|
||||
Self::to_raw($pin_no).reset();
|
||||
self
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! impl_pin {
|
||||
($pin_periph:ident, $pin_port:expr, $pin_no:expr) => {
|
||||
impl SealedPin for crate::peripherals::$pin_periph {}
|
||||
impl ToAnyPin for crate::peripherals::$pin_periph {}
|
||||
impl IopctlPin for crate::peripherals::$pin_periph {
|
||||
#[inline]
|
||||
fn set_function(&self, function: Function) -> &Self {
|
||||
Self::to_raw($pin_port, $pin_no).set_function(function);
|
||||
self
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_pull(&self, pull: Pull) -> &Self {
|
||||
Self::to_raw($pin_port, $pin_no).set_pull(pull);
|
||||
self
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn enable_input_buffer(&self) -> &Self {
|
||||
Self::to_raw($pin_port, $pin_no).enable_input_buffer();
|
||||
self
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn disable_input_buffer(&self) -> &Self {
|
||||
Self::to_raw($pin_port, $pin_no).disable_input_buffer();
|
||||
self
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_slew_rate(&self, slew_rate: SlewRate) -> &Self {
|
||||
Self::to_raw($pin_port, $pin_no).set_slew_rate(slew_rate);
|
||||
self
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_drive_strength(&self, strength: DriveStrength) -> &Self {
|
||||
Self::to_raw($pin_port, $pin_no).set_drive_strength(strength);
|
||||
self
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn enable_analog_multiplex(&self) -> &Self {
|
||||
Self::to_raw($pin_port, $pin_no).enable_analog_multiplex();
|
||||
self
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn disable_analog_multiplex(&self) -> &Self {
|
||||
Self::to_raw($pin_port, $pin_no).disable_analog_multiplex();
|
||||
self
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_drive_mode(&self, mode: DriveMode) -> &Self {
|
||||
Self::to_raw($pin_port, $pin_no).set_drive_mode(mode);
|
||||
self
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_input_inverter(&self, inverter: Inverter) -> &Self {
|
||||
Self::to_raw($pin_port, $pin_no).set_input_inverter(inverter);
|
||||
self
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn reset(&self) -> &Self {
|
||||
Self::to_raw($pin_port, $pin_no).reset();
|
||||
self
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
impl_pin!(PIO0_0, 0, 0);
|
||||
impl_pin!(PIO0_1, 0, 1);
|
||||
impl_pin!(PIO0_2, 0, 2);
|
||||
impl_pin!(PIO0_3, 0, 3);
|
||||
impl_pin!(PIO0_4, 0, 4);
|
||||
impl_pin!(PIO0_5, 0, 5);
|
||||
impl_pin!(PIO0_6, 0, 6);
|
||||
impl_pin!(PIO0_7, 0, 7);
|
||||
impl_pin!(PIO0_8, 0, 8);
|
||||
impl_pin!(PIO0_9, 0, 9);
|
||||
impl_pin!(PIO0_10, 0, 10);
|
||||
impl_pin!(PIO0_11, 0, 11);
|
||||
impl_pin!(PIO0_12, 0, 12);
|
||||
impl_pin!(PIO0_13, 0, 13);
|
||||
impl_pin!(PIO0_14, 0, 14);
|
||||
impl_pin!(PIO0_15, 0, 15);
|
||||
impl_pin!(PIO0_16, 0, 16);
|
||||
impl_pin!(PIO0_17, 0, 17);
|
||||
impl_pin!(PIO0_18, 0, 18);
|
||||
impl_pin!(PIO0_19, 0, 19);
|
||||
impl_pin!(PIO0_20, 0, 20);
|
||||
impl_pin!(PIO0_21, 0, 21);
|
||||
impl_pin!(PIO0_22, 0, 22);
|
||||
impl_pin!(PIO0_23, 0, 23);
|
||||
impl_pin!(PIO0_24, 0, 24);
|
||||
impl_pin!(PIO0_25, 0, 25);
|
||||
impl_pin!(PIO0_26, 0, 26);
|
||||
impl_pin!(PIO0_27, 0, 27);
|
||||
impl_pin!(PIO0_28, 0, 28);
|
||||
impl_pin!(PIO0_29, 0, 29);
|
||||
impl_pin!(PIO0_30, 0, 30);
|
||||
impl_pin!(PIO0_31, 0, 31);
|
||||
impl_pin!(PIO1_0, 1, 0);
|
||||
impl_pin!(PIO1_1, 1, 1);
|
||||
impl_pin!(PIO1_2, 1, 2);
|
||||
impl_pin!(PIO1_3, 1, 3);
|
||||
impl_pin!(PIO1_4, 1, 4);
|
||||
impl_pin!(PIO1_5, 1, 5);
|
||||
impl_pin!(PIO1_6, 1, 6);
|
||||
impl_pin!(PIO1_7, 1, 7);
|
||||
impl_pin!(PIO1_8, 1, 8);
|
||||
impl_pin!(PIO1_9, 1, 9);
|
||||
impl_pin!(PIO1_10, 1, 10);
|
||||
impl_pin!(PIO1_11, 1, 11);
|
||||
impl_pin!(PIO1_12, 1, 12);
|
||||
impl_pin!(PIO1_13, 1, 13);
|
||||
impl_pin!(PIO1_14, 1, 14);
|
||||
impl_pin!(PIO1_15, 1, 15);
|
||||
impl_pin!(PIO1_16, 1, 16);
|
||||
impl_pin!(PIO1_17, 1, 17);
|
||||
impl_pin!(PIO1_18, 1, 18);
|
||||
impl_pin!(PIO1_19, 1, 19);
|
||||
impl_pin!(PIO1_20, 1, 20);
|
||||
impl_pin!(PIO1_21, 1, 21);
|
||||
impl_pin!(PIO1_22, 1, 22);
|
||||
impl_pin!(PIO1_23, 1, 23);
|
||||
impl_pin!(PIO1_24, 1, 24);
|
||||
impl_pin!(PIO1_25, 1, 25);
|
||||
impl_pin!(PIO1_26, 1, 26);
|
||||
impl_pin!(PIO1_27, 1, 27);
|
||||
impl_pin!(PIO1_28, 1, 28);
|
||||
impl_pin!(PIO1_29, 1, 29);
|
||||
impl_pin!(PIO1_30, 1, 30);
|
||||
impl_pin!(PIO1_31, 1, 31);
|
||||
impl_pin!(PIO2_0, 2, 0);
|
||||
impl_pin!(PIO2_1, 2, 1);
|
||||
impl_pin!(PIO2_2, 2, 2);
|
||||
impl_pin!(PIO2_3, 2, 3);
|
||||
impl_pin!(PIO2_4, 2, 4);
|
||||
impl_pin!(PIO2_5, 2, 5);
|
||||
impl_pin!(PIO2_6, 2, 6);
|
||||
impl_pin!(PIO2_7, 2, 7);
|
||||
impl_pin!(PIO2_8, 2, 8);
|
||||
impl_pin!(PIO2_9, 2, 9);
|
||||
impl_pin!(PIO2_10, 2, 10);
|
||||
impl_pin!(PIO2_11, 2, 11);
|
||||
impl_pin!(PIO2_12, 2, 12);
|
||||
impl_pin!(PIO2_13, 2, 13);
|
||||
impl_pin!(PIO2_14, 2, 14);
|
||||
impl_pin!(PIO2_15, 2, 15);
|
||||
impl_pin!(PIO2_16, 2, 16);
|
||||
impl_pin!(PIO2_17, 2, 17);
|
||||
impl_pin!(PIO2_18, 2, 18);
|
||||
impl_pin!(PIO2_19, 2, 19);
|
||||
impl_pin!(PIO2_20, 2, 20);
|
||||
impl_pin!(PIO2_21, 2, 21);
|
||||
impl_pin!(PIO2_22, 2, 22);
|
||||
impl_pin!(PIO2_23, 2, 23);
|
||||
impl_pin!(PIO2_24, 2, 24);
|
||||
|
||||
// Note: These have have reset values of 0x41 to support SWD by default
|
||||
impl_pin!(PIO2_25, 2, 25);
|
||||
impl_pin!(PIO2_26, 2, 26);
|
||||
|
||||
impl_pin!(PIO2_27, 2, 27);
|
||||
impl_pin!(PIO2_28, 2, 28);
|
||||
impl_pin!(PIO2_29, 2, 29);
|
||||
impl_pin!(PIO2_30, 2, 30);
|
||||
impl_pin!(PIO2_31, 2, 31);
|
||||
impl_pin!(PIO3_0, 3, 0);
|
||||
impl_pin!(PIO3_1, 3, 1);
|
||||
impl_pin!(PIO3_2, 3, 2);
|
||||
impl_pin!(PIO3_3, 3, 3);
|
||||
impl_pin!(PIO3_4, 3, 4);
|
||||
impl_pin!(PIO3_5, 3, 5);
|
||||
impl_pin!(PIO3_6, 3, 6);
|
||||
impl_pin!(PIO3_7, 3, 7);
|
||||
impl_pin!(PIO3_8, 3, 8);
|
||||
impl_pin!(PIO3_9, 3, 9);
|
||||
impl_pin!(PIO3_10, 3, 10);
|
||||
impl_pin!(PIO3_11, 3, 11);
|
||||
impl_pin!(PIO3_12, 3, 12);
|
||||
impl_pin!(PIO3_13, 3, 13);
|
||||
impl_pin!(PIO3_14, 3, 14);
|
||||
impl_pin!(PIO3_15, 3, 15);
|
||||
impl_pin!(PIO3_16, 3, 16);
|
||||
impl_pin!(PIO3_17, 3, 17);
|
||||
impl_pin!(PIO3_18, 3, 18);
|
||||
impl_pin!(PIO3_19, 3, 19);
|
||||
impl_pin!(PIO3_20, 3, 20);
|
||||
impl_pin!(PIO3_21, 3, 21);
|
||||
impl_pin!(PIO3_22, 3, 22);
|
||||
impl_pin!(PIO3_23, 3, 23);
|
||||
impl_pin!(PIO3_24, 3, 24);
|
||||
impl_pin!(PIO3_25, 3, 25);
|
||||
impl_pin!(PIO3_26, 3, 26);
|
||||
impl_pin!(PIO3_27, 3, 27);
|
||||
impl_pin!(PIO3_28, 3, 28);
|
||||
impl_pin!(PIO3_29, 3, 29);
|
||||
impl_pin!(PIO3_30, 3, 30);
|
||||
impl_pin!(PIO3_31, 3, 31);
|
||||
impl_pin!(PIO4_0, 4, 0);
|
||||
impl_pin!(PIO4_1, 4, 1);
|
||||
impl_pin!(PIO4_2, 4, 2);
|
||||
impl_pin!(PIO4_3, 4, 3);
|
||||
impl_pin!(PIO4_4, 4, 4);
|
||||
impl_pin!(PIO4_5, 4, 5);
|
||||
impl_pin!(PIO4_6, 4, 6);
|
||||
impl_pin!(PIO4_7, 4, 7);
|
||||
impl_pin!(PIO4_8, 4, 8);
|
||||
impl_pin!(PIO4_9, 4, 9);
|
||||
impl_pin!(PIO4_10, 4, 10);
|
||||
impl_pin!(PIO7_24, 7, 24);
|
||||
impl_pin!(PIO7_25, 7, 25);
|
||||
impl_pin!(PIO7_26, 7, 26);
|
||||
impl_pin!(PIO7_27, 7, 27);
|
||||
impl_pin!(PIO7_28, 7, 28);
|
||||
impl_pin!(PIO7_29, 7, 29);
|
||||
impl_pin!(PIO7_30, 7, 30);
|
||||
impl_pin!(PIO7_31, 7, 31);
|
||||
|
||||
// FC15 pins
|
||||
impl_FC15pin!(PIOFC15_SCL, 0);
|
||||
impl_FC15pin!(PIOFC15_SDA, 1);
|
130
embassy-imxrt/src/lib.rs
Normal file
130
embassy-imxrt/src/lib.rs
Normal file
@ -0,0 +1,130 @@
|
||||
#![no_std]
|
||||
#![allow(async_fn_in_trait)]
|
||||
#![doc = include_str!("../README.md")]
|
||||
#![warn(missing_docs)]
|
||||
|
||||
//! ## Feature flags
|
||||
#![doc = document_features::document_features!(feature_label = r#"<span class="stab portability"><code>{feature}</code></span>"#)]
|
||||
|
||||
#[cfg(not(any(feature = "mimxrt633s", feature = "mimxrt685s",)))]
|
||||
compile_error!(
|
||||
"No chip feature activated. You must activate exactly one of the following features:
|
||||
mimxrt633s,
|
||||
mimxrt685s,
|
||||
"
|
||||
);
|
||||
|
||||
// This mod MUST go first, so that the others see its macros.
|
||||
pub(crate) mod fmt;
|
||||
|
||||
pub mod clocks;
|
||||
pub mod gpio;
|
||||
pub mod iopctl;
|
||||
|
||||
// This mod MUST go last, so that it sees all the `impl_foo!' macros
|
||||
#[cfg_attr(feature = "mimxrt633s", path = "chips/mimxrt633s.rs")]
|
||||
#[cfg_attr(feature = "mimxrt685s", path = "chips/mimxrt685s.rs")]
|
||||
mod chip;
|
||||
|
||||
// Reexports
|
||||
pub use chip::interrupts::*;
|
||||
#[cfg(feature = "unstable-pac")]
|
||||
pub use chip::pac;
|
||||
#[cfg(not(feature = "unstable-pac"))]
|
||||
pub(crate) use chip::pac;
|
||||
pub use chip::{peripherals, Peripherals};
|
||||
pub use embassy_hal_internal::{Peri, PeripheralType};
|
||||
|
||||
#[cfg(feature = "rt")]
|
||||
pub use crate::pac::NVIC_PRIO_BITS;
|
||||
|
||||
/// Macro to bind interrupts to handlers.
|
||||
///
|
||||
/// This defines the right interrupt handlers, and creates a unit struct (like `struct Irqs;`)
|
||||
/// and implements the right \[`Binding`\]s for it. You can pass this struct to drivers to
|
||||
/// prove at compile-time that the right interrupts have been bound.
|
||||
///
|
||||
/// Example of how to bind one interrupt:
|
||||
///
|
||||
/// ```rust,ignore
|
||||
/// use embassy_imxrt::{bind_interrupts, flexspi, peripherals};
|
||||
///
|
||||
/// bind_interrupts!(struct Irqs {
|
||||
/// FLEXSPI_IRQ => flexspi::InterruptHandler<peripherals::FLEXSPI>;
|
||||
/// });
|
||||
/// ```
|
||||
///
|
||||
// developer note: this macro can't be in `embassy-hal-internal` due to the use of `$crate`.
|
||||
#[macro_export]
|
||||
macro_rules! bind_interrupts {
|
||||
($vis:vis struct $name:ident { $($irq:ident => $($handler:ty),*;)* }) => {
|
||||
#[derive(Copy, Clone)]
|
||||
$vis struct $name;
|
||||
|
||||
$(
|
||||
#[allow(non_snake_case)]
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn $irq() {
|
||||
$(
|
||||
<$handler as $crate::interrupt::typelevel::Handler<$crate::interrupt::typelevel::$irq>>::on_interrupt();
|
||||
)*
|
||||
}
|
||||
|
||||
$(
|
||||
unsafe impl $crate::interrupt::typelevel::Binding<$crate::interrupt::typelevel::$irq, $handler> for $name {}
|
||||
)*
|
||||
)*
|
||||
};
|
||||
}
|
||||
|
||||
/// HAL configuration for iMX RT600.
|
||||
pub mod config {
|
||||
use crate::clocks::ClockConfig;
|
||||
|
||||
/// HAL configuration passed when initializing.
|
||||
#[non_exhaustive]
|
||||
pub struct Config {
|
||||
/// Clock configuration.
|
||||
pub clocks: ClockConfig,
|
||||
}
|
||||
|
||||
impl Default for Config {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
clocks: ClockConfig::crystal(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Config {
|
||||
/// Create a new configuration with the provided clock config.
|
||||
pub fn new(clocks: ClockConfig) -> Self {
|
||||
Self { clocks }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Initialize the `embassy-imxrt` HAL with the provided configuration.
|
||||
///
|
||||
/// This returns the peripheral singletons that can be used for creating drivers.
|
||||
///
|
||||
/// This should only be called once at startup, otherwise it panics.
|
||||
pub fn init(config: config::Config) -> Peripherals {
|
||||
// Do this first, so that it panics if user is calling `init` a second time
|
||||
// before doing anything important.
|
||||
let peripherals = Peripherals::take();
|
||||
|
||||
unsafe {
|
||||
if let Err(e) = clocks::init(config.clocks) {
|
||||
error!("unable to initialize Clocks for reason: {:?}", e);
|
||||
// Panic here?
|
||||
}
|
||||
gpio::init();
|
||||
}
|
||||
|
||||
peripherals
|
||||
}
|
||||
|
||||
pub(crate) mod sealed {
|
||||
pub trait Sealed {}
|
||||
}
|
17
examples/mimxrt6/.cargo/config.toml
Normal file
17
examples/mimxrt6/.cargo/config.toml
Normal file
@ -0,0 +1,17 @@
|
||||
[target.thumbv8m.main-none-eabihf]
|
||||
runner = 'probe-rs run --chip MIMXRT685SFVKB'
|
||||
|
||||
rustflags = [
|
||||
"-C", "linker=flip-link",
|
||||
"-C", "link-arg=-Tlink.x",
|
||||
"-C", "link-arg=-Tdefmt.x",
|
||||
# This is needed if your flash or ram addresses are not aligned to 0x10000 in memory.x
|
||||
# See https://github.com/rust-embedded/cortex-m-quickstart/pull/95
|
||||
"-C", "link-arg=--nmagic",
|
||||
]
|
||||
|
||||
[build]
|
||||
target = "thumbv8m.main-none-eabihf" # Cortex-M33
|
||||
|
||||
[env]
|
||||
DEFMT_LOG = "trace"
|
14
examples/mimxrt6/.gitignore
vendored
Normal file
14
examples/mimxrt6/.gitignore
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
# Generated by Cargo
|
||||
# will have compiled files and executables
|
||||
/debug
|
||||
/target
|
||||
|
||||
# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
|
||||
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
|
||||
Cargo.lock
|
||||
|
||||
# These are backup files generated by rustfmt
|
||||
**/*.rs.bk
|
||||
|
||||
# MSVC Windows builds of rustc generate these, which store debugging information
|
||||
*.pdb
|
60
examples/mimxrt6/Cargo.toml
Normal file
60
examples/mimxrt6/Cargo.toml
Normal file
@ -0,0 +1,60 @@
|
||||
[package]
|
||||
name = "embassy-imxrt-examples"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
license = "MIT or Apache-2.0"
|
||||
|
||||
[dependencies]
|
||||
cortex-m = { version = "0.7.7", features = ["inline-asm", "critical-section-single-core"] }
|
||||
cortex-m-rt = "0.7.3"
|
||||
defmt = "1.0"
|
||||
defmt-rtt = "1.0"
|
||||
|
||||
embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt", "defmt"] }
|
||||
embassy-futures = { version = "0.1.1", path = "../../embassy-futures" }
|
||||
embassy-imxrt = { version = "0.1.0", path = "../../embassy-imxrt", features = ["defmt", "mimxrt685s", "unstable-pac"] }
|
||||
embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] }
|
||||
embedded-hal-1 = { package = "embedded-hal", version = "1.0" }
|
||||
embedded-hal-async = "1.0.0"
|
||||
|
||||
mimxrt600-fcb = "0.1.0"
|
||||
panic-probe = { version = "0.3", features = ["print-defmt"] }
|
||||
rand = { version = "0.8.5", default-features = false }
|
||||
|
||||
# cargo build/run
|
||||
[profile.dev]
|
||||
codegen-units = 1
|
||||
debug = 2
|
||||
debug-assertions = true # <-
|
||||
incremental = false
|
||||
opt-level = 3 # <-
|
||||
overflow-checks = true # <-
|
||||
|
||||
# cargo test
|
||||
[profile.test]
|
||||
codegen-units = 1
|
||||
debug = 2
|
||||
debug-assertions = true # <-
|
||||
incremental = false
|
||||
opt-level = 3 # <-
|
||||
overflow-checks = true # <-
|
||||
|
||||
# cargo build/run --release
|
||||
[profile.release]
|
||||
codegen-units = 1
|
||||
debug = 2
|
||||
debug-assertions = false # <-
|
||||
incremental = false
|
||||
lto = 'fat'
|
||||
opt-level = 3 # <-
|
||||
overflow-checks = false # <-
|
||||
|
||||
# cargo test --release
|
||||
[profile.bench]
|
||||
codegen-units = 1
|
||||
debug = 2
|
||||
debug-assertions = false # <-
|
||||
incremental = false
|
||||
lto = 'fat'
|
||||
opt-level = 3 # <-
|
||||
overflow-checks = false # <-
|
18
examples/mimxrt6/README.md
Normal file
18
examples/mimxrt6/README.md
Normal file
@ -0,0 +1,18 @@
|
||||
# embassy-imxrt-examples
|
||||
|
||||
## Introduction
|
||||
|
||||
These examples illustrates how to use the embassy-imxrt HAL.
|
||||
|
||||
## Adding Examples
|
||||
Add uniquely named example to `src/bin` like `adc.rs`
|
||||
|
||||
## Build
|
||||
`cd` to examples folder
|
||||
`cargo build --bin <example_name>` for example, `cargo build --bin adc`
|
||||
|
||||
## Run
|
||||
Assuming RT685 is powered and connected to Jlink debug probe and the latest probe-rs is installed via
|
||||
`$ cargo install probe-rs-tools --git https://github.com/probe-rs/probe-rs --locked`
|
||||
`cd` to examples folder
|
||||
`cargo run --bin <example_name>` for example, `cargo run --bin adc`
|
45
examples/mimxrt6/build.rs
Normal file
45
examples/mimxrt6/build.rs
Normal file
@ -0,0 +1,45 @@
|
||||
use std::env;
|
||||
use std::fs::File;
|
||||
use std::io::Write;
|
||||
use std::path::PathBuf;
|
||||
|
||||
fn main() {
|
||||
// Put `memory.x` in our output directory and ensure it's
|
||||
// on the linker search path.
|
||||
let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
|
||||
File::create(out.join("memory.x"))
|
||||
.unwrap()
|
||||
.write_all(include_bytes!("memory.x"))
|
||||
.unwrap();
|
||||
println!("cargo:rustc-link-search={}", out.display());
|
||||
|
||||
// By default, Cargo will re-run a build script whenever
|
||||
// any file in the project changes. By specifying `memory.x`
|
||||
// here, we ensure the build script is only re-run when
|
||||
// `memory.x` is changed.
|
||||
println!("cargo:rerun-if-changed=memory.x");
|
||||
|
||||
// Inject crate version into the .biv section.
|
||||
File::create(out.join("biv.rs"))
|
||||
.unwrap()
|
||||
.write_all(
|
||||
format!(
|
||||
r##"
|
||||
#[link_section = ".biv"]
|
||||
#[used]
|
||||
static BOOT_IMAGE_VERSION: u32 = 0x{:02x}{:02x}{:02x}00;
|
||||
"##,
|
||||
env!("CARGO_PKG_VERSION_MAJOR")
|
||||
.parse::<u8>()
|
||||
.expect("should have major version"),
|
||||
env!("CARGO_PKG_VERSION_MINOR")
|
||||
.parse::<u8>()
|
||||
.expect("should have minor version"),
|
||||
env!("CARGO_PKG_VERSION_PATCH")
|
||||
.parse::<u8>()
|
||||
.expect("should have patch version"),
|
||||
)
|
||||
.as_bytes(),
|
||||
)
|
||||
.unwrap();
|
||||
}
|
34
examples/mimxrt6/memory.x
Normal file
34
examples/mimxrt6/memory.x
Normal file
@ -0,0 +1,34 @@
|
||||
MEMORY {
|
||||
OTFAD : ORIGIN = 0x08000000, LENGTH = 256
|
||||
FCB : ORIGIN = 0x08000400, LENGTH = 512
|
||||
BIV : ORIGIN = 0x08000600, LENGTH = 4
|
||||
KEYSTORE : ORIGIN = 0x08000800, LENGTH = 2K
|
||||
FLASH : ORIGIN = 0x08001000, LENGTH = 1M
|
||||
RAM : ORIGIN = 0x20080000, LENGTH = 1536K
|
||||
}
|
||||
|
||||
SECTIONS {
|
||||
.otfad : {
|
||||
. = ALIGN(4);
|
||||
KEEP(* (.otfad))
|
||||
. = ALIGN(4);
|
||||
} > OTFAD
|
||||
|
||||
.fcb : {
|
||||
. = ALIGN(4);
|
||||
KEEP(* (.fcb))
|
||||
. = ALIGN(4);
|
||||
} > FCB
|
||||
|
||||
.biv : {
|
||||
. = ALIGN(4);
|
||||
KEEP(* (.biv))
|
||||
. = ALIGN(4);
|
||||
} > BIV
|
||||
|
||||
.keystore : {
|
||||
. = ALIGN(4);
|
||||
KEEP(* (.keystore))
|
||||
. = ALIGN(4);
|
||||
} > KEYSTORE
|
||||
}
|
29
examples/mimxrt6/src/bin/blinky.rs
Normal file
29
examples/mimxrt6/src/bin/blinky.rs
Normal file
@ -0,0 +1,29 @@
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
extern crate embassy_imxrt_examples;
|
||||
|
||||
use defmt::info;
|
||||
use embassy_executor::Spawner;
|
||||
use embassy_imxrt::gpio;
|
||||
|
||||
#[embassy_executor::main]
|
||||
async fn main(_spawner: Spawner) {
|
||||
let p = embassy_imxrt::init(Default::default());
|
||||
|
||||
info!("Initializing GPIO");
|
||||
|
||||
let mut led = gpio::Output::new(
|
||||
p.PIO0_26,
|
||||
gpio::Level::Low,
|
||||
gpio::DriveMode::PushPull,
|
||||
gpio::DriveStrength::Normal,
|
||||
gpio::SlewRate::Standard,
|
||||
);
|
||||
|
||||
loop {
|
||||
info!("Toggling LED");
|
||||
led.toggle();
|
||||
cortex_m::asm::delay(5_000_000);
|
||||
}
|
||||
}
|
17
examples/mimxrt6/src/bin/hello.rs
Normal file
17
examples/mimxrt6/src/bin/hello.rs
Normal file
@ -0,0 +1,17 @@
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
extern crate embassy_imxrt_examples;
|
||||
|
||||
use defmt::info;
|
||||
use embassy_executor::Spawner;
|
||||
use {defmt_rtt as _, panic_probe as _};
|
||||
|
||||
#[embassy_executor::main]
|
||||
async fn main(_spawner: Spawner) -> ! {
|
||||
let _p = embassy_imxrt::init(Default::default());
|
||||
loop {
|
||||
info!("Hello");
|
||||
cortex_m::asm::delay(5_000_000);
|
||||
}
|
||||
}
|
20
examples/mimxrt6/src/lib.rs
Normal file
20
examples/mimxrt6/src/lib.rs
Normal file
@ -0,0 +1,20 @@
|
||||
#![no_std]
|
||||
|
||||
use mimxrt600_fcb::FlexSPIFlashConfigurationBlock;
|
||||
use {defmt_rtt as _, panic_probe as _};
|
||||
|
||||
// auto-generated version information from Cargo.toml
|
||||
include!(concat!(env!("OUT_DIR"), "/biv.rs"));
|
||||
|
||||
#[link_section = ".otfad"]
|
||||
#[used]
|
||||
static OTFAD: [u8; 256] = [0; 256];
|
||||
|
||||
#[rustfmt::skip]
|
||||
#[link_section = ".fcb"]
|
||||
#[used]
|
||||
static FCB: FlexSPIFlashConfigurationBlock = FlexSPIFlashConfigurationBlock::build();
|
||||
|
||||
#[link_section = ".keystore"]
|
||||
#[used]
|
||||
static KEYSTORE: [u8; 2048] = [0; 2048];
|
Loading…
x
Reference in New Issue
Block a user