Merge remote-tracking branch 'origin/main' into bxcan_timestamp
This commit is contained in:
commit
780569c08a
2
.github/ci/test.sh
vendored
2
.github/ci/test.sh
vendored
@ -13,7 +13,7 @@ hashtime save /ci/cache/filetime.json
|
||||
|
||||
cargo test --manifest-path ./embassy-sync/Cargo.toml
|
||||
cargo test --manifest-path ./embassy-embedded-hal/Cargo.toml
|
||||
cargo test --manifest-path ./embassy-hal-common/Cargo.toml
|
||||
cargo test --manifest-path ./embassy-hal-internal/Cargo.toml
|
||||
cargo test --manifest-path ./embassy-time/Cargo.toml --features generic-queue
|
||||
|
||||
cargo test --manifest-path ./embassy-boot/boot/Cargo.toml
|
||||
|
1
.vscode/settings.json
vendored
1
.vscode/settings.json
vendored
@ -25,6 +25,7 @@
|
||||
// "examples/stm32f1/Cargo.toml",
|
||||
// "examples/stm32f2/Cargo.toml",
|
||||
// "examples/stm32f3/Cargo.toml",
|
||||
// "examples/stm32f334/Cargo.toml",
|
||||
// "examples/stm32f4/Cargo.toml",
|
||||
// "examples/stm32f7/Cargo.toml",
|
||||
// "examples/stm32g0/Cargo.toml",
|
||||
|
3
ci.sh
3
ci.sh
@ -27,6 +27,8 @@ cargo batch \
|
||||
--- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,dhcpv4,medium-ethernet,nightly \
|
||||
--- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,dhcpv4,medium-ethernet,unstable-traits,nightly \
|
||||
--- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv6,medium-ethernet \
|
||||
--- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv6,medium-ieee802154 \
|
||||
--- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv6,medium-ethernet,medium-ieee802154 \
|
||||
--- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv6,medium-ethernet,unstable-traits \
|
||||
--- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv6,medium-ethernet,nightly \
|
||||
--- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv6,medium-ethernet,unstable-traits,nightly \
|
||||
@ -115,6 +117,7 @@ cargo batch \
|
||||
--- build --release --manifest-path examples/stm32f1/Cargo.toml --target thumbv7m-none-eabi --out-dir out/examples/stm32f1 \
|
||||
--- build --release --manifest-path examples/stm32f2/Cargo.toml --target thumbv7m-none-eabi --out-dir out/examples/stm32f2 \
|
||||
--- build --release --manifest-path examples/stm32f3/Cargo.toml --target thumbv7em-none-eabihf --out-dir out/examples/stm32f3 \
|
||||
--- build --release --manifest-path examples/stm32f334/Cargo.toml --target thumbv7em-none-eabihf --out-dir out/examples/stm32f334 \
|
||||
--- build --release --manifest-path examples/stm32f4/Cargo.toml --target thumbv7em-none-eabi --out-dir out/examples/stm32f4 \
|
||||
--- build --release --manifest-path examples/stm32f7/Cargo.toml --target thumbv7em-none-eabihf --out-dir out/examples/stm32f7 \
|
||||
--- build --release --manifest-path examples/stm32c0/Cargo.toml --target thumbv6m-none-eabi --out-dir out/examples/stm32c0 \
|
||||
|
Binary file not shown.
Binary file not shown.
@ -3,3 +3,7 @@
|
||||
Firmware obtained from https://github.com/Infineon/wifi-host-driver/tree/master/WiFi_Host_Driver/resources/firmware/COMPONENT_43439
|
||||
|
||||
Licensed under the [Infineon Permissive Binary License](./LICENSE-permissive-binary-license-1.0.txt)
|
||||
|
||||
## Changelog
|
||||
|
||||
* 2023-07-28: synced with `ad3bad0` - Update 43439 fw from 7.95.55 ot 7.95.62
|
||||
|
@ -8,7 +8,6 @@ use cyw43::SpiBusCyw43;
|
||||
use embassy_rp::dma::Channel;
|
||||
use embassy_rp::gpio::{Drive, Level, Output, Pin, Pull, SlewRate};
|
||||
use embassy_rp::pio::{Common, Config, Direction, Instance, Irq, PioPin, ShiftDirection, StateMachine};
|
||||
use embassy_rp::relocate::RelocatedProgram;
|
||||
use embassy_rp::{pio_instr_util, Peripheral, PeripheralRef};
|
||||
use fixed::FixedU32;
|
||||
use pio_proc::pio_asm;
|
||||
@ -88,8 +87,6 @@ where
|
||||
".wrap"
|
||||
);
|
||||
|
||||
let relocated = RelocatedProgram::new(&program.program);
|
||||
|
||||
let mut pin_io: embassy_rp::pio::Pin<PIO> = common.make_pio_pin(dio);
|
||||
pin_io.set_pull(Pull::None);
|
||||
pin_io.set_schmitt(true);
|
||||
@ -102,7 +99,8 @@ where
|
||||
pin_clk.set_slew_rate(SlewRate::Fast);
|
||||
|
||||
let mut cfg = Config::default();
|
||||
cfg.use_program(&common.load_program(&relocated), &[&pin_clk]);
|
||||
let loaded_program = common.load_program(&program.program);
|
||||
cfg.use_program(&loaded_program, &[&pin_clk]);
|
||||
cfg.set_out_pins(&[&pin_io]);
|
||||
cfg.set_in_pins(&[&pin_io]);
|
||||
cfg.set_set_pins(&[&pin_io]);
|
||||
@ -142,7 +140,7 @@ where
|
||||
sm,
|
||||
irq,
|
||||
dma: dma.into_ref(),
|
||||
wrap_target: relocated.wrap().target,
|
||||
wrap_target: loaded_program.wrap.target,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6,7 +6,7 @@ mod fmt;
|
||||
#[cfg(feature = "nightly")]
|
||||
pub use embassy_boot::FirmwareUpdater;
|
||||
pub use embassy_boot::{AlignedBuffer, BlockingFirmwareUpdater, BootLoaderConfig, FirmwareUpdaterConfig, State};
|
||||
use embassy_rp::flash::{Flash, ERASE_SIZE};
|
||||
use embassy_rp::flash::{Blocking, Flash, ERASE_SIZE};
|
||||
use embassy_rp::peripherals::{FLASH, WATCHDOG};
|
||||
use embassy_rp::watchdog::Watchdog;
|
||||
use embassy_time::Duration;
|
||||
@ -58,14 +58,14 @@ impl<ACTIVE: NorFlash, DFU: NorFlash, STATE: NorFlash, const BUFFER_SIZE: usize>
|
||||
|
||||
/// A flash implementation that will feed a watchdog when touching flash.
|
||||
pub struct WatchdogFlash<'d, const SIZE: usize> {
|
||||
flash: Flash<'d, FLASH, SIZE>,
|
||||
flash: Flash<'d, FLASH, Blocking, SIZE>,
|
||||
watchdog: Watchdog,
|
||||
}
|
||||
|
||||
impl<'d, const SIZE: usize> WatchdogFlash<'d, SIZE> {
|
||||
/// Start a new watchdog with a given flash and watchdog peripheral and a timeout
|
||||
pub fn start(flash: FLASH, watchdog: WATCHDOG, timeout: Duration) -> Self {
|
||||
let flash: Flash<'_, FLASH, SIZE> = Flash::new(flash);
|
||||
let flash = Flash::<_, Blocking, SIZE>::new(flash);
|
||||
let mut watchdog = Watchdog::new(watchdog);
|
||||
watchdog.start(timeout);
|
||||
Self { flash, watchdog }
|
||||
@ -73,12 +73,12 @@ impl<'d, const SIZE: usize> WatchdogFlash<'d, SIZE> {
|
||||
}
|
||||
|
||||
impl<'d, const SIZE: usize> ErrorType for WatchdogFlash<'d, SIZE> {
|
||||
type Error = <Flash<'d, FLASH, SIZE> as ErrorType>::Error;
|
||||
type Error = <Flash<'d, FLASH, Blocking, SIZE> as ErrorType>::Error;
|
||||
}
|
||||
|
||||
impl<'d, const SIZE: usize> NorFlash for WatchdogFlash<'d, SIZE> {
|
||||
const WRITE_SIZE: usize = <Flash<'d, FLASH, SIZE> as NorFlash>::WRITE_SIZE;
|
||||
const ERASE_SIZE: usize = <Flash<'d, FLASH, SIZE> as NorFlash>::ERASE_SIZE;
|
||||
const WRITE_SIZE: usize = <Flash<'d, FLASH, Blocking, SIZE> as NorFlash>::WRITE_SIZE;
|
||||
const ERASE_SIZE: usize = <Flash<'d, FLASH, Blocking, SIZE> as NorFlash>::ERASE_SIZE;
|
||||
|
||||
fn erase(&mut self, from: u32, to: u32) -> Result<(), Self::Error> {
|
||||
self.watchdog.feed();
|
||||
@ -91,7 +91,7 @@ impl<'d, const SIZE: usize> NorFlash for WatchdogFlash<'d, SIZE> {
|
||||
}
|
||||
|
||||
impl<'d, const SIZE: usize> ReadNorFlash for WatchdogFlash<'d, SIZE> {
|
||||
const READ_SIZE: usize = <Flash<'d, FLASH, SIZE> as ReadNorFlash>::READ_SIZE;
|
||||
const READ_SIZE: usize = <Flash<'d, FLASH, Blocking, SIZE> as ReadNorFlash>::READ_SIZE;
|
||||
fn read(&mut self, offset: u32, data: &mut [u8]) -> Result<(), Self::Error> {
|
||||
self.watchdog.feed();
|
||||
self.flash.read(offset, data)
|
||||
|
@ -1,5 +1,5 @@
|
||||
[package]
|
||||
name = "embassy-hal-common"
|
||||
name = "embassy-hal-internal"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
license = "MIT OR Apache-2.0"
|
16
embassy-hal-internal/README.md
Normal file
16
embassy-hal-internal/README.md
Normal file
@ -0,0 +1,16 @@
|
||||
# embassy-macros
|
||||
|
||||
An [Embassy](https://embassy.dev) project.
|
||||
|
||||
Internal implementation details for Embassy HALs. DO NOT USE DIRECTLY. Embassy HALs (`embassy-nrf`, `embassy-stm32`, `embassy-rp`) already reexport
|
||||
everything you need to use them effectively.
|
||||
|
||||
## License
|
||||
|
||||
This work is licensed under either of
|
||||
|
||||
- Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or
|
||||
<http://www.apache.org/licenses/LICENSE-2.0>)
|
||||
- MIT license ([LICENSE-MIT](LICENSE-MIT) or <http://opensource.org/licenses/MIT>)
|
||||
|
||||
at your option.
|
@ -1,5 +1,6 @@
|
||||
#![no_std]
|
||||
#![allow(clippy::new_without_default)]
|
||||
#![doc = include_str!("../README.md")]
|
||||
|
||||
// This mod MUST go first, so that the others see its macros.
|
||||
pub(crate) mod fmt;
|
@ -12,7 +12,7 @@ target = "thumbv7em-none-eabi"
|
||||
|
||||
[features]
|
||||
stm32wl = ["dep:embassy-stm32"]
|
||||
time = []
|
||||
time = ["embassy-time", "lorawan-device"]
|
||||
defmt = ["dep:defmt", "lorawan-device/defmt"]
|
||||
|
||||
[dependencies]
|
||||
@ -20,18 +20,12 @@ defmt = ["dep:defmt", "lorawan-device/defmt"]
|
||||
defmt = { version = "0.3", optional = true }
|
||||
log = { version = "0.4.14", optional = true }
|
||||
|
||||
embassy-time = { version = "0.1.2", path = "../embassy-time" }
|
||||
embassy-time = { version = "0.1.2", path = "../embassy-time", optional = true }
|
||||
embassy-sync = { version = "0.2.0", path = "../embassy-sync" }
|
||||
embassy-stm32 = { version = "0.1.0", path = "../embassy-stm32", default-features = false, optional = true }
|
||||
embedded-hal-1 = { package = "embedded-hal", version = "=1.0.0-alpha.11" }
|
||||
embedded-hal-async = { version = "=0.2.0-alpha.2" }
|
||||
embassy-hal-common = { version = "0.1.0", path = "../embassy-hal-common", default-features = false }
|
||||
futures = { version = "0.3.17", default-features = false, features = [ "async-await" ] }
|
||||
embedded-hal = { version = "0.2", features = ["unproven"] }
|
||||
bit_field = { version = "0.10" }
|
||||
|
||||
futures = { version = "0.3.17", default-features = false, features = [ "async-await" ] }
|
||||
lora-phy = { version = "1" }
|
||||
lorawan-device = { version = "0.10.0", default-features = false, features = ["async"] }
|
||||
|
||||
[patch.crates-io]
|
||||
lora-phy = { git = "https://github.com/embassy-rs/lora-phy", rev = "ad289428fd44b02788e2fa2116445cc8f640a265" }
|
||||
lorawan-device = { version = "0.10.0", default-features = false, features = ["async"], optional = true }
|
||||
|
@ -1,5 +1,4 @@
|
||||
use ch::driver::LinkState;
|
||||
use defmt::Debug2Format;
|
||||
use embassy_net_driver_channel as ch;
|
||||
use heapless::String;
|
||||
|
||||
@ -57,7 +56,6 @@ impl<'a> Control<'a> {
|
||||
let proto::CtrlMsgPayload::RespConnectAp(resp) = resp.payload.unwrap() else {
|
||||
panic!("unexpected resp")
|
||||
};
|
||||
debug!("======= {:?}", Debug2Format(&resp));
|
||||
assert_eq!(resp.resp, 0);
|
||||
self.state_ch.set_link_state(LinkState::Up);
|
||||
}
|
||||
|
@ -32,12 +32,14 @@ pub use smoltcp::iface::MulticastError;
|
||||
use smoltcp::iface::{Interface, SocketHandle, SocketSet, SocketStorage};
|
||||
#[cfg(feature = "dhcpv4")]
|
||||
use smoltcp::socket::dhcpv4::{self, RetryConfig};
|
||||
#[cfg(feature = "medium-ethernet")]
|
||||
pub use smoltcp::wire::EthernetAddress;
|
||||
#[cfg(any(feature = "medium-ethernet", feature = "medium-ieee802154"))]
|
||||
pub use smoltcp::wire::HardwareAddress;
|
||||
#[cfg(feature = "udp")]
|
||||
pub use smoltcp::wire::IpListenEndpoint;
|
||||
#[cfg(feature = "medium-ethernet")]
|
||||
pub use smoltcp::wire::{EthernetAddress, HardwareAddress};
|
||||
#[cfg(feature = "medium-ieee802154")]
|
||||
pub use smoltcp::wire::{HardwareAddress, Ieee802154Address};
|
||||
pub use smoltcp::wire::{Ieee802154Address, Ieee802154Frame};
|
||||
pub use smoltcp::wire::{IpAddress, IpCidr, IpEndpoint};
|
||||
#[cfg(feature = "proto-ipv4")]
|
||||
pub use smoltcp::wire::{Ipv4Address, Ipv4Cidr};
|
||||
@ -583,7 +585,7 @@ impl SocketStack {
|
||||
impl<D: Driver + 'static> Inner<D> {
|
||||
#[cfg(feature = "proto-ipv4")]
|
||||
fn apply_config_v4(&mut self, s: &mut SocketStack, config: StaticConfigV4) {
|
||||
#[cfg(feature = "medium-ethernet")]
|
||||
#[cfg(any(feature = "medium-ethernet", feature = "medium-ieee802154"))]
|
||||
let medium = self.device.capabilities().medium;
|
||||
|
||||
debug!("Acquired IP configuration:");
|
||||
|
@ -93,7 +93,7 @@ _gpio-p1 = []
|
||||
[dependencies]
|
||||
embassy-time = { version = "0.1.2", path = "../embassy-time", optional = true }
|
||||
embassy-sync = { version = "0.2.0", path = "../embassy-sync" }
|
||||
embassy-hal-common = {version = "0.1.0", path = "../embassy-hal-common", features = ["cortex-m", "prio-bits-3"] }
|
||||
embassy-hal-internal = {version = "0.1.0", path = "../embassy-hal-internal", features = ["cortex-m", "prio-bits-3"] }
|
||||
embassy-embedded-hal = {version = "0.1.0", path = "../embassy-embedded-hal" }
|
||||
embassy-usb-driver = {version = "0.1.0", path = "../embassy-usb-driver", optional=true }
|
||||
|
||||
|
@ -15,8 +15,8 @@ use core::slice;
|
||||
use core::sync::atomic::{compiler_fence, AtomicU8, AtomicUsize, Ordering};
|
||||
use core::task::Poll;
|
||||
|
||||
use embassy_hal_common::atomic_ring_buffer::RingBuffer;
|
||||
use embassy_hal_common::{into_ref, PeripheralRef};
|
||||
use embassy_hal_internal::atomic_ring_buffer::RingBuffer;
|
||||
use embassy_hal_internal::{into_ref, PeripheralRef};
|
||||
use embassy_sync::waitqueue::AtomicWaker;
|
||||
// Re-export SVD variants to allow user to directly set values
|
||||
pub use pac::uarte0::{baudrate::BAUDRATE_A as Baudrate, config::PARITY_A as Parity};
|
||||
|
@ -8,7 +8,7 @@ pub const FLASH_SIZE: usize = 192 * 1024;
|
||||
|
||||
pub const RESET_PIN: u32 = 21;
|
||||
|
||||
embassy_hal_common::peripherals! {
|
||||
embassy_hal_internal::peripherals! {
|
||||
// RTC
|
||||
RTC0,
|
||||
RTC1,
|
||||
@ -208,7 +208,7 @@ impl_ppi_channel!(PPI_CH31, 31 => static);
|
||||
impl_saadc_input!(P0_04, ANALOG_INPUT2);
|
||||
impl_saadc_input!(P0_05, ANALOG_INPUT3);
|
||||
|
||||
embassy_hal_common::interrupt_mod!(
|
||||
embassy_hal_internal::interrupt_mod!(
|
||||
POWER_CLOCK,
|
||||
RADIO,
|
||||
UARTE0_UART0,
|
||||
|
@ -8,7 +8,7 @@ pub const FLASH_SIZE: usize = 192 * 1024;
|
||||
|
||||
pub const RESET_PIN: u32 = 21;
|
||||
|
||||
embassy_hal_common::peripherals! {
|
||||
embassy_hal_internal::peripherals! {
|
||||
// RTC
|
||||
RTC0,
|
||||
RTC1,
|
||||
@ -234,7 +234,7 @@ impl_saadc_input!(P0_29, ANALOG_INPUT5);
|
||||
impl_saadc_input!(P0_30, ANALOG_INPUT6);
|
||||
impl_saadc_input!(P0_31, ANALOG_INPUT7);
|
||||
|
||||
embassy_hal_common::interrupt_mod!(
|
||||
embassy_hal_internal::interrupt_mod!(
|
||||
POWER_CLOCK,
|
||||
RADIO,
|
||||
UARTE0_UART0,
|
||||
|
@ -8,7 +8,7 @@ pub const FLASH_SIZE: usize = 192 * 1024;
|
||||
|
||||
pub const RESET_PIN: u32 = 21;
|
||||
|
||||
embassy_hal_common::peripherals! {
|
||||
embassy_hal_internal::peripherals! {
|
||||
// RTC
|
||||
RTC0,
|
||||
RTC1,
|
||||
@ -236,7 +236,7 @@ impl_saadc_input!(P0_29, ANALOG_INPUT5);
|
||||
impl_saadc_input!(P0_30, ANALOG_INPUT6);
|
||||
impl_saadc_input!(P0_31, ANALOG_INPUT7);
|
||||
|
||||
embassy_hal_common::interrupt_mod!(
|
||||
embassy_hal_internal::interrupt_mod!(
|
||||
POWER_CLOCK,
|
||||
RADIO,
|
||||
UARTE0_UART0,
|
||||
|
@ -8,7 +8,7 @@ pub const FLASH_SIZE: usize = 256 * 1024;
|
||||
|
||||
pub const RESET_PIN: u32 = 18;
|
||||
|
||||
embassy_hal_common::peripherals! {
|
||||
embassy_hal_internal::peripherals! {
|
||||
// USB
|
||||
USBD,
|
||||
|
||||
@ -224,7 +224,7 @@ impl_ppi_channel!(PPI_CH29, 29 => static);
|
||||
impl_ppi_channel!(PPI_CH30, 30 => static);
|
||||
impl_ppi_channel!(PPI_CH31, 31 => static);
|
||||
|
||||
embassy_hal_common::interrupt_mod!(
|
||||
embassy_hal_internal::interrupt_mod!(
|
||||
POWER_CLOCK,
|
||||
RADIO,
|
||||
UARTE0_UART0,
|
||||
|
@ -12,7 +12,7 @@ pub const FLASH_SIZE: usize = 512 * 1024;
|
||||
|
||||
pub const RESET_PIN: u32 = 21;
|
||||
|
||||
embassy_hal_common::peripherals! {
|
||||
embassy_hal_internal::peripherals! {
|
||||
// RTC
|
||||
RTC0,
|
||||
RTC1,
|
||||
@ -263,7 +263,7 @@ impl_saadc_input!(P0_31, ANALOG_INPUT7);
|
||||
|
||||
impl_i2s!(I2S, I2S, I2S);
|
||||
|
||||
embassy_hal_common::interrupt_mod!(
|
||||
embassy_hal_internal::interrupt_mod!(
|
||||
POWER_CLOCK,
|
||||
RADIO,
|
||||
UARTE0_UART0,
|
||||
|
@ -8,7 +8,7 @@ pub const FLASH_SIZE: usize = 512 * 1024;
|
||||
|
||||
pub const RESET_PIN: u32 = 18;
|
||||
|
||||
embassy_hal_common::peripherals! {
|
||||
embassy_hal_internal::peripherals! {
|
||||
// USB
|
||||
USBD,
|
||||
|
||||
@ -306,7 +306,7 @@ impl_saadc_input!(P0_31, ANALOG_INPUT7);
|
||||
|
||||
impl_i2s!(I2S, I2S, I2S);
|
||||
|
||||
embassy_hal_common::interrupt_mod!(
|
||||
embassy_hal_internal::interrupt_mod!(
|
||||
POWER_CLOCK,
|
||||
RADIO,
|
||||
UARTE0_UART0,
|
||||
|
@ -8,7 +8,7 @@ pub const FLASH_SIZE: usize = 1024 * 1024;
|
||||
|
||||
pub const RESET_PIN: u32 = 18;
|
||||
|
||||
embassy_hal_common::peripherals! {
|
||||
embassy_hal_internal::peripherals! {
|
||||
// USB
|
||||
USBD,
|
||||
|
||||
@ -311,7 +311,7 @@ impl_saadc_input!(P0_31, ANALOG_INPUT7);
|
||||
|
||||
impl_i2s!(I2S, I2S, I2S);
|
||||
|
||||
embassy_hal_common::interrupt_mod!(
|
||||
embassy_hal_internal::interrupt_mod!(
|
||||
POWER_CLOCK,
|
||||
RADIO,
|
||||
UARTE0_UART0,
|
||||
|
@ -218,7 +218,7 @@ pub const FORCE_COPY_BUFFER_SIZE: usize = 1024;
|
||||
|
||||
pub const FLASH_SIZE: usize = 1024 * 1024;
|
||||
|
||||
embassy_hal_common::peripherals! {
|
||||
embassy_hal_internal::peripherals! {
|
||||
// USB
|
||||
USBD,
|
||||
|
||||
@ -506,7 +506,7 @@ impl_saadc_input!(P0_18, ANALOG_INPUT5);
|
||||
impl_saadc_input!(P0_19, ANALOG_INPUT6);
|
||||
impl_saadc_input!(P0_20, ANALOG_INPUT7);
|
||||
|
||||
embassy_hal_common::interrupt_mod!(
|
||||
embassy_hal_internal::interrupt_mod!(
|
||||
FPU,
|
||||
CACHE,
|
||||
SPU,
|
||||
|
@ -109,7 +109,7 @@ pub const FORCE_COPY_BUFFER_SIZE: usize = 1024;
|
||||
|
||||
pub const FLASH_SIZE: usize = 256 * 1024;
|
||||
|
||||
embassy_hal_common::peripherals! {
|
||||
embassy_hal_internal::peripherals! {
|
||||
// RTC
|
||||
RTC0,
|
||||
RTC1,
|
||||
@ -342,7 +342,7 @@ impl_ppi_channel!(PPI_CH29, 29 => configurable);
|
||||
impl_ppi_channel!(PPI_CH30, 30 => configurable);
|
||||
impl_ppi_channel!(PPI_CH31, 31 => configurable);
|
||||
|
||||
embassy_hal_common::interrupt_mod!(
|
||||
embassy_hal_internal::interrupt_mod!(
|
||||
CLOCK_POWER,
|
||||
RADIO,
|
||||
RNG,
|
||||
|
@ -169,7 +169,7 @@ pub const FORCE_COPY_BUFFER_SIZE: usize = 1024;
|
||||
|
||||
pub const FLASH_SIZE: usize = 1024 * 1024;
|
||||
|
||||
embassy_hal_common::peripherals! {
|
||||
embassy_hal_internal::peripherals! {
|
||||
// RTC
|
||||
RTC0,
|
||||
RTC1,
|
||||
@ -368,7 +368,7 @@ impl_saadc_input!(P0_18, ANALOG_INPUT5);
|
||||
impl_saadc_input!(P0_19, ANALOG_INPUT6);
|
||||
impl_saadc_input!(P0_20, ANALOG_INPUT7);
|
||||
|
||||
embassy_hal_common::interrupt_mod!(
|
||||
embassy_hal_internal::interrupt_mod!(
|
||||
SPU,
|
||||
CLOCK_POWER,
|
||||
UARTE0_SPIM0_SPIS0_TWIM0_TWIS0,
|
||||
|
@ -5,7 +5,7 @@ use core::convert::Infallible;
|
||||
use core::hint::unreachable_unchecked;
|
||||
|
||||
use cfg_if::cfg_if;
|
||||
use embassy_hal_common::{impl_peripheral, into_ref, PeripheralRef};
|
||||
use embassy_hal_internal::{impl_peripheral, into_ref, PeripheralRef};
|
||||
|
||||
use self::sealed::Pin as _;
|
||||
use crate::pac::p0 as gpio;
|
||||
|
@ -4,7 +4,7 @@ use core::convert::Infallible;
|
||||
use core::future::{poll_fn, Future};
|
||||
use core::task::{Context, Poll};
|
||||
|
||||
use embassy_hal_common::{impl_peripheral, into_ref, Peripheral, PeripheralRef};
|
||||
use embassy_hal_internal::{impl_peripheral, into_ref, Peripheral, PeripheralRef};
|
||||
use embassy_sync::waitqueue::AtomicWaker;
|
||||
|
||||
use crate::gpio::sealed::Pin as _;
|
||||
|
@ -9,8 +9,8 @@ use core::ops::{Deref, DerefMut};
|
||||
use core::sync::atomic::{compiler_fence, Ordering};
|
||||
use core::task::Poll;
|
||||
|
||||
use embassy_hal_common::drop::OnDrop;
|
||||
use embassy_hal_common::{into_ref, PeripheralRef};
|
||||
use embassy_hal_internal::drop::OnDrop;
|
||||
use embassy_hal_internal::{into_ref, PeripheralRef};
|
||||
|
||||
use crate::gpio::{AnyPin, Pin as GpioPin};
|
||||
use crate::interrupt::typelevel::Interrupt;
|
||||
|
@ -98,7 +98,7 @@ mod chip;
|
||||
/// 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.
|
||||
// developer note: this macro can't be in `embassy-hal-common` due to the use of `$crate`.
|
||||
// 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),*;)* }) => {
|
||||
@ -127,7 +127,7 @@ pub use chip::pac;
|
||||
#[cfg(not(feature = "unstable-pac"))]
|
||||
pub(crate) use chip::pac;
|
||||
pub use chip::{peripherals, Peripherals, EASY_DMA_SIZE};
|
||||
pub use embassy_hal_common::{into_ref, Peripheral, PeripheralRef};
|
||||
pub use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef};
|
||||
|
||||
pub use crate::chip::interrupt;
|
||||
pub use crate::pac::NVIC_PRIO_BITS;
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
use core::{ptr, slice};
|
||||
|
||||
use embassy_hal_common::{into_ref, PeripheralRef};
|
||||
use embassy_hal_internal::{into_ref, PeripheralRef};
|
||||
use embedded_storage::nor_flash::{
|
||||
ErrorType, MultiwriteNorFlash, NorFlash, NorFlashError, NorFlashErrorKind, ReadNorFlash,
|
||||
};
|
||||
|
@ -6,8 +6,8 @@ use core::marker::PhantomData;
|
||||
use core::sync::atomic::{compiler_fence, Ordering};
|
||||
use core::task::Poll;
|
||||
|
||||
use embassy_hal_common::drop::OnDrop;
|
||||
use embassy_hal_common::{into_ref, PeripheralRef};
|
||||
use embassy_hal_internal::drop::OnDrop;
|
||||
use embassy_hal_internal::{into_ref, PeripheralRef};
|
||||
use fixed::types::I7F1;
|
||||
use futures::future::poll_fn;
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
use embassy_hal_common::into_ref;
|
||||
use embassy_hal_internal::into_ref;
|
||||
|
||||
use super::{Channel, ConfigurableChannel, Event, Ppi, Task};
|
||||
use crate::{pac, Peripheral};
|
||||
|
@ -18,7 +18,7 @@
|
||||
use core::marker::PhantomData;
|
||||
use core::ptr::NonNull;
|
||||
|
||||
use embassy_hal_common::{impl_peripheral, into_ref, PeripheralRef};
|
||||
use embassy_hal_internal::{impl_peripheral, into_ref, PeripheralRef};
|
||||
|
||||
use crate::{peripherals, Peripheral};
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
use embassy_hal_common::into_ref;
|
||||
use embassy_hal_internal::into_ref;
|
||||
|
||||
use super::{Channel, ConfigurableChannel, Event, Ppi, StaticChannel, Task};
|
||||
use crate::{pac, Peripheral};
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
use core::sync::atomic::{compiler_fence, Ordering};
|
||||
|
||||
use embassy_hal_common::{into_ref, PeripheralRef};
|
||||
use embassy_hal_internal::{into_ref, PeripheralRef};
|
||||
|
||||
use crate::gpio::sealed::Pin as _;
|
||||
use crate::gpio::{AnyPin, Pin as GpioPin, PselBits};
|
||||
|
@ -6,7 +6,7 @@ use core::future::poll_fn;
|
||||
use core::marker::PhantomData;
|
||||
use core::task::Poll;
|
||||
|
||||
use embassy_hal_common::{into_ref, PeripheralRef};
|
||||
use embassy_hal_internal::{into_ref, PeripheralRef};
|
||||
|
||||
use crate::gpio::sealed::Pin as _;
|
||||
use crate::gpio::{AnyPin, Pin as GpioPin};
|
||||
|
@ -7,8 +7,8 @@ use core::marker::PhantomData;
|
||||
use core::ptr;
|
||||
use core::task::Poll;
|
||||
|
||||
use embassy_hal_common::drop::OnDrop;
|
||||
use embassy_hal_common::{into_ref, PeripheralRef};
|
||||
use embassy_hal_internal::drop::OnDrop;
|
||||
use embassy_hal_internal::{into_ref, PeripheralRef};
|
||||
use embedded_storage::nor_flash::{ErrorType, NorFlash, NorFlashError, NorFlashErrorKind, ReadNorFlash};
|
||||
|
||||
use crate::gpio::{self, Pin as GpioPin};
|
||||
|
@ -8,8 +8,8 @@ use core::ptr;
|
||||
use core::sync::atomic::{AtomicPtr, Ordering};
|
||||
use core::task::Poll;
|
||||
|
||||
use embassy_hal_common::drop::OnDrop;
|
||||
use embassy_hal_common::{into_ref, PeripheralRef};
|
||||
use embassy_hal_internal::drop::OnDrop;
|
||||
use embassy_hal_internal::{into_ref, PeripheralRef};
|
||||
use embassy_sync::waitqueue::AtomicWaker;
|
||||
|
||||
use crate::interrupt::typelevel::Interrupt;
|
||||
|
@ -6,8 +6,8 @@ use core::future::poll_fn;
|
||||
use core::sync::atomic::{compiler_fence, Ordering};
|
||||
use core::task::Poll;
|
||||
|
||||
use embassy_hal_common::drop::OnDrop;
|
||||
use embassy_hal_common::{impl_peripheral, into_ref, PeripheralRef};
|
||||
use embassy_hal_internal::drop::OnDrop;
|
||||
use embassy_hal_internal::{impl_peripheral, into_ref, PeripheralRef};
|
||||
use embassy_sync::waitqueue::AtomicWaker;
|
||||
use pac::{saadc, SAADC};
|
||||
use saadc::ch::config::{GAIN_A, REFSEL_A, RESP_A, TACQ_A};
|
||||
|
@ -8,7 +8,7 @@ use core::sync::atomic::{compiler_fence, Ordering};
|
||||
use core::task::Poll;
|
||||
|
||||
use embassy_embedded_hal::SetConfig;
|
||||
use embassy_hal_common::{into_ref, PeripheralRef};
|
||||
use embassy_hal_internal::{into_ref, PeripheralRef};
|
||||
pub use embedded_hal_02::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3};
|
||||
pub use pac::spim0::frequency::FREQUENCY_A as Frequency;
|
||||
|
||||
|
@ -7,7 +7,7 @@ use core::sync::atomic::{compiler_fence, Ordering};
|
||||
use core::task::Poll;
|
||||
|
||||
use embassy_embedded_hal::SetConfig;
|
||||
use embassy_hal_common::{into_ref, PeripheralRef};
|
||||
use embassy_hal_internal::{into_ref, PeripheralRef};
|
||||
pub use embedded_hal_02::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3};
|
||||
|
||||
use crate::chip::FORCE_COPY_BUFFER_SIZE;
|
||||
|
@ -3,8 +3,8 @@
|
||||
use core::future::poll_fn;
|
||||
use core::task::Poll;
|
||||
|
||||
use embassy_hal_common::drop::OnDrop;
|
||||
use embassy_hal_common::{into_ref, PeripheralRef};
|
||||
use embassy_hal_internal::drop::OnDrop;
|
||||
use embassy_hal_internal::{into_ref, PeripheralRef};
|
||||
use embassy_sync::waitqueue::AtomicWaker;
|
||||
use fixed::types::I30F2;
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
#![macro_use]
|
||||
|
||||
use embassy_hal_common::{into_ref, PeripheralRef};
|
||||
use embassy_hal_internal::{into_ref, PeripheralRef};
|
||||
|
||||
use crate::ppi::{Event, Task};
|
||||
use crate::{pac, Peripheral};
|
||||
|
@ -9,7 +9,7 @@ use core::sync::atomic::Ordering::SeqCst;
|
||||
use core::task::Poll;
|
||||
|
||||
use embassy_embedded_hal::SetConfig;
|
||||
use embassy_hal_common::{into_ref, PeripheralRef};
|
||||
use embassy_hal_internal::{into_ref, PeripheralRef};
|
||||
use embassy_sync::waitqueue::AtomicWaker;
|
||||
#[cfg(feature = "time")]
|
||||
use embassy_time::{Duration, Instant};
|
||||
|
@ -8,7 +8,7 @@ use core::sync::atomic::compiler_fence;
|
||||
use core::sync::atomic::Ordering::SeqCst;
|
||||
use core::task::Poll;
|
||||
|
||||
use embassy_hal_common::{into_ref, PeripheralRef};
|
||||
use embassy_hal_internal::{into_ref, PeripheralRef};
|
||||
use embassy_sync::waitqueue::AtomicWaker;
|
||||
#[cfg(feature = "time")]
|
||||
use embassy_time::{Duration, Instant};
|
||||
|
@ -18,8 +18,8 @@ use core::marker::PhantomData;
|
||||
use core::sync::atomic::{compiler_fence, Ordering};
|
||||
use core::task::Poll;
|
||||
|
||||
use embassy_hal_common::drop::OnDrop;
|
||||
use embassy_hal_common::{into_ref, PeripheralRef};
|
||||
use embassy_hal_internal::drop::OnDrop;
|
||||
use embassy_hal_internal::{into_ref, PeripheralRef};
|
||||
use pac::uarte0::RegisterBlock;
|
||||
// Re-export SVD variants to allow user to directly set values.
|
||||
pub use pac::uarte0::{baudrate::BAUDRATE_A as Baudrate, config::PARITY_A as Parity};
|
||||
|
@ -11,7 +11,7 @@ use core::sync::atomic::{compiler_fence, AtomicU32, Ordering};
|
||||
use core::task::Poll;
|
||||
|
||||
use cortex_m::peripheral::NVIC;
|
||||
use embassy_hal_common::{into_ref, PeripheralRef};
|
||||
use embassy_hal_internal::{into_ref, PeripheralRef};
|
||||
use embassy_sync::waitqueue::AtomicWaker;
|
||||
use embassy_usb_driver as driver;
|
||||
use embassy_usb_driver::{Direction, EndpointAddress, EndpointError, EndpointInfo, EndpointType, Event, Unsupported};
|
||||
|
@ -16,7 +16,7 @@ flavors = [
|
||||
default = [ "rt" ]
|
||||
rt = [ "rp-pac/rt" ]
|
||||
|
||||
defmt = ["dep:defmt", "embassy-usb-driver?/defmt", "embassy-hal-common/defmt"]
|
||||
defmt = ["dep:defmt", "embassy-usb-driver?/defmt", "embassy-hal-internal/defmt"]
|
||||
|
||||
# critical section that is safe for multicore use
|
||||
critical-section-impl = ["critical-section/restore-state-u8"]
|
||||
@ -48,7 +48,7 @@ boot2-w25x10cl = []
|
||||
run-from-ram = []
|
||||
|
||||
# Enable nightly-only features
|
||||
nightly = ["embedded-hal-1", "embedded-hal-async", "embassy-embedded-hal/nightly", "dep:embassy-usb-driver", "dep:embedded-io"]
|
||||
nightly = ["embedded-hal-1", "embedded-hal-async", "embedded-storage-async", "embassy-embedded-hal/nightly", "dep:embassy-usb-driver", "dep:embedded-io"]
|
||||
|
||||
# Implement embedded-hal 1.0 alpha traits.
|
||||
# Implement embedded-hal-async traits if `nightly` is set as well.
|
||||
@ -58,7 +58,7 @@ unstable-traits = ["embedded-hal-1", "embedded-hal-nb"]
|
||||
embassy-sync = { version = "0.2.0", path = "../embassy-sync" }
|
||||
embassy-time = { version = "0.1.2", path = "../embassy-time", features = [ "tick-hz-1_000_000" ] }
|
||||
embassy-futures = { version = "0.1.0", path = "../embassy-futures" }
|
||||
embassy-hal-common = {version = "0.1.0", path = "../embassy-hal-common", features = ["cortex-m", "prio-bits-2"] }
|
||||
embassy-hal-internal = {version = "0.1.0", path = "../embassy-hal-internal", features = ["cortex-m", "prio-bits-2"] }
|
||||
embassy-embedded-hal = {version = "0.1.0", path = "../embassy-embedded-hal" }
|
||||
embassy-usb-driver = {version = "0.1.0", path = "../embassy-usb-driver", optional = true }
|
||||
atomic-polyfill = "1.0.1"
|
||||
@ -73,6 +73,7 @@ futures = { version = "0.3.17", default-features = false, features = ["async-awa
|
||||
chrono = { version = "0.4", default-features = false, optional = true }
|
||||
embedded-io = { version = "0.4.0", features = ["async"], optional = true }
|
||||
embedded-storage = { version = "0.3" }
|
||||
embedded-storage-async = { version = "0.4.0", optional = true }
|
||||
rand_core = "0.6.4"
|
||||
fixed = "1.23.1"
|
||||
|
||||
|
@ -3,7 +3,7 @@ use core::marker::PhantomData;
|
||||
use core::sync::atomic::{compiler_fence, Ordering};
|
||||
use core::task::Poll;
|
||||
|
||||
use embassy_hal_common::{into_ref, PeripheralRef};
|
||||
use embassy_hal_internal::{into_ref, PeripheralRef};
|
||||
use embassy_sync::waitqueue::AtomicWaker;
|
||||
|
||||
use crate::gpio::sealed::Pin as GpioPin;
|
||||
|
@ -1,7 +1,7 @@
|
||||
use core::marker::PhantomData;
|
||||
use core::sync::atomic::{AtomicU16, AtomicU32, Ordering};
|
||||
|
||||
use embassy_hal_common::{into_ref, PeripheralRef};
|
||||
use embassy_hal_internal::{into_ref, PeripheralRef};
|
||||
use pac::clocks::vals::*;
|
||||
|
||||
use crate::gpio::sealed::Pin;
|
||||
|
@ -4,7 +4,7 @@ use core::pin::Pin;
|
||||
use core::sync::atomic::{compiler_fence, Ordering};
|
||||
use core::task::{Context, Poll};
|
||||
|
||||
use embassy_hal_common::{impl_peripheral, into_ref, Peripheral, PeripheralRef};
|
||||
use embassy_hal_internal::{impl_peripheral, into_ref, Peripheral, PeripheralRef};
|
||||
use embassy_sync::waitqueue::AtomicWaker;
|
||||
use pac::dma::vals::DataSize;
|
||||
|
||||
|
@ -1,11 +1,15 @@
|
||||
use core::future::Future;
|
||||
use core::marker::PhantomData;
|
||||
use core::pin::Pin;
|
||||
use core::task::{Context, Poll};
|
||||
|
||||
use embassy_hal_common::Peripheral;
|
||||
use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef};
|
||||
use embedded_storage::nor_flash::{
|
||||
check_erase, check_read, check_write, ErrorType, MultiwriteNorFlash, NorFlash, NorFlashError, NorFlashErrorKind,
|
||||
ReadNorFlash,
|
||||
};
|
||||
|
||||
use crate::dma::{AnyChannel, Channel, Transfer};
|
||||
use crate::pac;
|
||||
use crate::peripherals::FLASH;
|
||||
|
||||
@ -24,6 +28,7 @@ pub const PAGE_SIZE: usize = 256;
|
||||
pub const WRITE_SIZE: usize = 1;
|
||||
pub const READ_SIZE: usize = 1;
|
||||
pub const ERASE_SIZE: usize = 4096;
|
||||
pub const ASYNC_READ_SIZE: usize = 4;
|
||||
|
||||
/// Error type for NVMC operations.
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||
@ -57,13 +62,46 @@ impl NorFlashError for Error {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Flash<'d, T: Instance, const FLASH_SIZE: usize>(PhantomData<&'d mut T>);
|
||||
/// Future that waits for completion of a background read
|
||||
#[must_use = "futures do nothing unless you `.await` or poll them"]
|
||||
pub struct BackgroundRead<'a, 'd, T: Instance, const FLASH_SIZE: usize> {
|
||||
flash: PhantomData<&'a mut Flash<'d, T, Async, FLASH_SIZE>>,
|
||||
transfer: Transfer<'a, AnyChannel>,
|
||||
}
|
||||
|
||||
impl<'d, T: Instance, const FLASH_SIZE: usize> Flash<'d, T, FLASH_SIZE> {
|
||||
pub fn new(_flash: impl Peripheral<P = T> + 'd) -> Self {
|
||||
Self(PhantomData)
|
||||
impl<'a, 'd, T: Instance, const FLASH_SIZE: usize> Future for BackgroundRead<'a, 'd, T, FLASH_SIZE> {
|
||||
type Output = ();
|
||||
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||
Pin::new(&mut self.transfer).poll(cx)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'd, T: Instance, const FLASH_SIZE: usize> Drop for BackgroundRead<'a, 'd, T, FLASH_SIZE> {
|
||||
fn drop(&mut self) {
|
||||
if pac::XIP_CTRL.stream_ctr().read().0 == 0 {
|
||||
return;
|
||||
}
|
||||
pac::XIP_CTRL
|
||||
.stream_ctr()
|
||||
.write_value(pac::xip_ctrl::regs::StreamCtr(0));
|
||||
core::sync::atomic::compiler_fence(core::sync::atomic::Ordering::SeqCst);
|
||||
// Errata RP2040-E8: Perform an uncached read to make sure there's not a transfer in
|
||||
// flight that might effect an address written to start a new transfer. This stalls
|
||||
// until after any transfer is complete, so the address will not change anymore.
|
||||
const XIP_NOCACHE_NOALLOC_BASE: *const u32 = 0x13000000 as *const _;
|
||||
unsafe {
|
||||
core::ptr::read_volatile(XIP_NOCACHE_NOALLOC_BASE);
|
||||
}
|
||||
core::sync::atomic::compiler_fence(core::sync::atomic::Ordering::SeqCst);
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Flash<'d, T: Instance, M: Mode, const FLASH_SIZE: usize> {
|
||||
dma: Option<PeripheralRef<'d, AnyChannel>>,
|
||||
phantom: PhantomData<(&'d mut T, M)>,
|
||||
}
|
||||
|
||||
impl<'d, T: Instance, M: Mode, const FLASH_SIZE: usize> Flash<'d, T, M, FLASH_SIZE> {
|
||||
pub fn read(&mut self, offset: u32, bytes: &mut [u8]) -> Result<(), Error> {
|
||||
trace!(
|
||||
"Reading from 0x{:x} to 0x{:x}",
|
||||
@ -182,6 +220,8 @@ impl<'d, T: Instance, const FLASH_SIZE: usize> Flash<'d, T, FLASH_SIZE> {
|
||||
let ch = crate::pac::DMA.ch(n);
|
||||
while ch.read_addr().read() < SRAM_LOWER && ch.ctrl_trig().read().busy() {}
|
||||
}
|
||||
// Wait for completion of any background reads
|
||||
while pac::XIP_CTRL.stream_ctr().read().0 > 0 {}
|
||||
|
||||
// Run our flash operation in RAM
|
||||
operation();
|
||||
@ -210,11 +250,73 @@ impl<'d, T: Instance, const FLASH_SIZE: usize> Flash<'d, T, FLASH_SIZE> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T: Instance, const FLASH_SIZE: usize> ErrorType for Flash<'d, T, FLASH_SIZE> {
|
||||
impl<'d, T: Instance, const FLASH_SIZE: usize> Flash<'d, T, Blocking, FLASH_SIZE> {
|
||||
pub fn new(_flash: impl Peripheral<P = T> + 'd) -> Self {
|
||||
Self {
|
||||
dma: None,
|
||||
phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T: Instance, const FLASH_SIZE: usize> Flash<'d, T, Async, FLASH_SIZE> {
|
||||
pub fn new(_flash: impl Peripheral<P = T> + 'd, dma: impl Peripheral<P = impl Channel> + 'd) -> Self {
|
||||
into_ref!(dma);
|
||||
Self {
|
||||
dma: Some(dma.map_into()),
|
||||
phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn background_read<'a>(
|
||||
&'a mut self,
|
||||
offset: u32,
|
||||
data: &'a mut [u32],
|
||||
) -> Result<BackgroundRead<'a, 'd, T, FLASH_SIZE>, Error> {
|
||||
trace!(
|
||||
"Reading in background from 0x{:x} to 0x{:x}",
|
||||
FLASH_BASE as u32 + offset,
|
||||
FLASH_BASE as u32 + offset + (data.len() * 4) as u32
|
||||
);
|
||||
// Can't use check_read because we need to enforce 4-byte alignment
|
||||
let offset = offset as usize;
|
||||
let length = data.len() * 4;
|
||||
if length > self.capacity() || offset > self.capacity() - length {
|
||||
return Err(Error::OutOfBounds);
|
||||
}
|
||||
if offset % 4 != 0 {
|
||||
return Err(Error::Unaligned);
|
||||
}
|
||||
|
||||
while !pac::XIP_CTRL.stat().read().fifo_empty() {
|
||||
pac::XIP_CTRL.stream_fifo().read();
|
||||
}
|
||||
|
||||
pac::XIP_CTRL
|
||||
.stream_addr()
|
||||
.write_value(pac::xip_ctrl::regs::StreamAddr(FLASH_BASE as u32 + offset as u32));
|
||||
pac::XIP_CTRL
|
||||
.stream_ctr()
|
||||
.write_value(pac::xip_ctrl::regs::StreamCtr(data.len() as u32));
|
||||
|
||||
// Use the XIP AUX bus port, rather than the FIFO register access (e.x.
|
||||
// pac::XIP_CTRL.stream_fifo().as_ptr()) to avoid DMA stalling on
|
||||
// general XIP access.
|
||||
const XIP_AUX_BASE: *const u32 = 0x50400000 as *const _;
|
||||
let transfer = unsafe { crate::dma::read(self.dma.as_mut().unwrap(), XIP_AUX_BASE, data, 37) };
|
||||
|
||||
Ok(BackgroundRead {
|
||||
flash: PhantomData,
|
||||
transfer,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T: Instance, M: Mode, const FLASH_SIZE: usize> ErrorType for Flash<'d, T, M, FLASH_SIZE> {
|
||||
type Error = Error;
|
||||
}
|
||||
|
||||
impl<'d, T: Instance, const FLASH_SIZE: usize> ReadNorFlash for Flash<'d, T, FLASH_SIZE> {
|
||||
impl<'d, T: Instance, M: Mode, const FLASH_SIZE: usize> ReadNorFlash for Flash<'d, T, M, FLASH_SIZE> {
|
||||
const READ_SIZE: usize = READ_SIZE;
|
||||
|
||||
fn read(&mut self, offset: u32, bytes: &mut [u8]) -> Result<(), Self::Error> {
|
||||
@ -226,9 +328,9 @@ impl<'d, T: Instance, const FLASH_SIZE: usize> ReadNorFlash for Flash<'d, T, FLA
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T: Instance, const FLASH_SIZE: usize> MultiwriteNorFlash for Flash<'d, T, FLASH_SIZE> {}
|
||||
impl<'d, T: Instance, M: Mode, const FLASH_SIZE: usize> MultiwriteNorFlash for Flash<'d, T, M, FLASH_SIZE> {}
|
||||
|
||||
impl<'d, T: Instance, const FLASH_SIZE: usize> NorFlash for Flash<'d, T, FLASH_SIZE> {
|
||||
impl<'d, T: Instance, M: Mode, const FLASH_SIZE: usize> NorFlash for Flash<'d, T, M, FLASH_SIZE> {
|
||||
const WRITE_SIZE: usize = WRITE_SIZE;
|
||||
|
||||
const ERASE_SIZE: usize = ERASE_SIZE;
|
||||
@ -242,6 +344,74 @@ impl<'d, T: Instance, const FLASH_SIZE: usize> NorFlash for Flash<'d, T, FLASH_S
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "nightly")]
|
||||
impl<'d, T: Instance, const FLASH_SIZE: usize> embedded_storage_async::nor_flash::ReadNorFlash
|
||||
for Flash<'d, T, Async, FLASH_SIZE>
|
||||
{
|
||||
const READ_SIZE: usize = ASYNC_READ_SIZE;
|
||||
|
||||
async fn read(&mut self, offset: u32, bytes: &mut [u8]) -> Result<(), Self::Error> {
|
||||
use core::mem::MaybeUninit;
|
||||
|
||||
// Checked early to simplify address validity checks
|
||||
if bytes.len() % 4 != 0 {
|
||||
return Err(Error::Unaligned);
|
||||
}
|
||||
|
||||
// If the destination address is already aligned, then we can just DMA directly
|
||||
if (bytes.as_ptr() as u32) % 4 == 0 {
|
||||
// Safety: alignment and size have been checked for compatibility
|
||||
let mut buf: &mut [u32] =
|
||||
unsafe { core::slice::from_raw_parts_mut(bytes.as_mut_ptr() as *mut u32, bytes.len() / 4) };
|
||||
self.background_read(offset, &mut buf)?.await;
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
// Destination address is unaligned, so use an intermediate buffer
|
||||
const REALIGN_CHUNK: usize = PAGE_SIZE;
|
||||
// Safety: MaybeUninit requires no initialization
|
||||
let mut buf: [MaybeUninit<u32>; REALIGN_CHUNK / 4] = unsafe { MaybeUninit::uninit().assume_init() };
|
||||
let mut chunk_offset: usize = 0;
|
||||
while chunk_offset < bytes.len() {
|
||||
let chunk_size = (bytes.len() - chunk_offset).min(REALIGN_CHUNK);
|
||||
let buf = &mut buf[..(chunk_size / 4)];
|
||||
|
||||
// Safety: this is written to completely by DMA before any reads
|
||||
let buf = unsafe { &mut *(buf as *mut [MaybeUninit<u32>] as *mut [u32]) };
|
||||
self.background_read(offset + chunk_offset as u32, buf)?.await;
|
||||
|
||||
// Safety: [u8] has more relaxed alignment and size requirements than [u32], so this is just aliasing
|
||||
let buf = unsafe { core::slice::from_raw_parts(buf.as_ptr() as *const _, buf.len() * 4) };
|
||||
bytes[chunk_offset..(chunk_offset + chunk_size)].copy_from_slice(&buf[..chunk_size]);
|
||||
|
||||
chunk_offset += chunk_size;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn capacity(&self) -> usize {
|
||||
self.capacity()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "nightly")]
|
||||
impl<'d, T: Instance, const FLASH_SIZE: usize> embedded_storage_async::nor_flash::NorFlash
|
||||
for Flash<'d, T, Async, FLASH_SIZE>
|
||||
{
|
||||
const WRITE_SIZE: usize = WRITE_SIZE;
|
||||
|
||||
const ERASE_SIZE: usize = ERASE_SIZE;
|
||||
|
||||
async fn erase(&mut self, from: u32, to: u32) -> Result<(), Self::Error> {
|
||||
self.erase(from, to)
|
||||
}
|
||||
|
||||
async fn write(&mut self, offset: u32, bytes: &[u8]) -> Result<(), Self::Error> {
|
||||
self.write(offset, bytes)
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
mod ram_helpers {
|
||||
use core::marker::PhantomData;
|
||||
@ -699,9 +869,24 @@ mod ram_helpers {
|
||||
|
||||
mod sealed {
|
||||
pub trait Instance {}
|
||||
pub trait Mode {}
|
||||
}
|
||||
|
||||
pub trait Instance: sealed::Instance {}
|
||||
pub trait Mode: sealed::Mode {}
|
||||
|
||||
impl sealed::Instance for FLASH {}
|
||||
impl Instance for FLASH {}
|
||||
|
||||
macro_rules! impl_mode {
|
||||
($name:ident) => {
|
||||
impl sealed::Mode for $name {}
|
||||
impl Mode for $name {}
|
||||
};
|
||||
}
|
||||
|
||||
pub struct Blocking;
|
||||
pub struct Async;
|
||||
|
||||
impl_mode!(Blocking);
|
||||
impl_mode!(Async);
|
||||
|
@ -3,7 +3,7 @@ use core::future::Future;
|
||||
use core::pin::Pin as FuturePin;
|
||||
use core::task::{Context, Poll};
|
||||
|
||||
use embassy_hal_common::{impl_peripheral, into_ref, PeripheralRef};
|
||||
use embassy_hal_internal::{impl_peripheral, into_ref, PeripheralRef};
|
||||
use embassy_sync::waitqueue::AtomicWaker;
|
||||
|
||||
use crate::interrupt::InterruptExt;
|
||||
|
@ -2,7 +2,7 @@ use core::future;
|
||||
use core::marker::PhantomData;
|
||||
use core::task::Poll;
|
||||
|
||||
use embassy_hal_common::{into_ref, PeripheralRef};
|
||||
use embassy_hal_internal::{into_ref, PeripheralRef};
|
||||
use embassy_sync::waitqueue::AtomicWaker;
|
||||
use pac::i2c;
|
||||
|
||||
|
@ -33,10 +33,10 @@ pub mod watchdog;
|
||||
// TODO: move `pio_instr_util` and `relocate` to inside `pio`
|
||||
pub mod pio;
|
||||
pub mod pio_instr_util;
|
||||
pub mod relocate;
|
||||
pub(crate) mod relocate;
|
||||
|
||||
// Reexports
|
||||
pub use embassy_hal_common::{into_ref, Peripheral, PeripheralRef};
|
||||
pub use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef};
|
||||
#[cfg(feature = "unstable-pac")]
|
||||
pub use rp_pac as pac;
|
||||
#[cfg(not(feature = "unstable-pac"))]
|
||||
@ -45,7 +45,7 @@ pub(crate) use rp_pac as pac;
|
||||
#[cfg(feature = "rt")]
|
||||
pub use crate::pac::NVIC_PRIO_BITS;
|
||||
|
||||
embassy_hal_common::interrupt_mod!(
|
||||
embassy_hal_internal::interrupt_mod!(
|
||||
TIMER_IRQ_0,
|
||||
TIMER_IRQ_1,
|
||||
TIMER_IRQ_2,
|
||||
@ -85,7 +85,7 @@ embassy_hal_common::interrupt_mod!(
|
||||
/// 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.
|
||||
// developer note: this macro can't be in `embassy-hal-common` due to the use of `$crate`.
|
||||
// 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),*;)* }) => {
|
||||
@ -107,7 +107,7 @@ macro_rules! bind_interrupts {
|
||||
};
|
||||
}
|
||||
|
||||
embassy_hal_common::peripherals! {
|
||||
embassy_hal_internal::peripherals! {
|
||||
PIN_0,
|
||||
PIN_1,
|
||||
PIN_2,
|
||||
@ -219,6 +219,74 @@ select_bootloader! {
|
||||
default => BOOT_LOADER_W25Q080
|
||||
}
|
||||
|
||||
/// Installs a stack guard for the CORE0 stack in MPU region 0.
|
||||
/// Will fail if the MPU is already confgigured. This function requires
|
||||
/// a `_stack_end` symbol to be defined by the linker script, and expexcts
|
||||
/// `_stack_end` to be located at the lowest address (largest depth) of
|
||||
/// the stack.
|
||||
///
|
||||
/// This method can *only* set up stack guards on the currently
|
||||
/// executing core. Stack guards for CORE1 are set up automatically,
|
||||
/// only CORE0 should ever use this.
|
||||
///
|
||||
/// # Usage
|
||||
///
|
||||
/// ```no_run
|
||||
/// #![feature(type_alias_impl_trait)]
|
||||
/// use embassy_rp::install_core0_stack_guard;
|
||||
/// use embassy_executor::{Executor, Spawner};
|
||||
///
|
||||
/// #[embassy_executor::main]
|
||||
/// async fn main(_spawner: Spawner) {
|
||||
/// // set up by the linker as follows:
|
||||
/// //
|
||||
/// // MEMORY {
|
||||
/// // STACK0: ORIGIN = 0x20040000, LENGTH = 4K
|
||||
/// // }
|
||||
/// //
|
||||
/// // _stack_end = ORIGIN(STACK0);
|
||||
/// // _stack_start = _stack_end + LENGTH(STACK0);
|
||||
/// //
|
||||
/// install_core0_stack_guard().expect("MPU already configured");
|
||||
/// let p = embassy_rp::init(Default::default());
|
||||
///
|
||||
/// // ...
|
||||
/// }
|
||||
/// ```
|
||||
pub fn install_core0_stack_guard() -> Result<(), ()> {
|
||||
extern "C" {
|
||||
static mut _stack_end: usize;
|
||||
}
|
||||
unsafe { install_stack_guard(&mut _stack_end as *mut usize) }
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn install_stack_guard(stack_bottom: *mut usize) -> Result<(), ()> {
|
||||
let core = unsafe { cortex_m::Peripherals::steal() };
|
||||
|
||||
// Fail if MPU is already configured
|
||||
if core.MPU.ctrl.read() != 0 {
|
||||
return Err(());
|
||||
}
|
||||
|
||||
// The minimum we can protect is 32 bytes on a 32 byte boundary, so round up which will
|
||||
// just shorten the valid stack range a tad.
|
||||
let addr = (stack_bottom as u32 + 31) & !31;
|
||||
// Mask is 1 bit per 32 bytes of the 256 byte range... clear the bit for the segment we want
|
||||
let subregion_select = 0xff ^ (1 << ((addr >> 5) & 7));
|
||||
unsafe {
|
||||
core.MPU.ctrl.write(5); // enable mpu with background default map
|
||||
core.MPU.rbar.write((addr & !0xff) | (1 << 4)); // set address and update RNR
|
||||
core.MPU.rasr.write(
|
||||
1 // enable region
|
||||
| (0x7 << 1) // size 2^(7 + 1) = 256
|
||||
| (subregion_select << 8)
|
||||
| 0x10000000, // XN = disable instruction fetch; no other bits means no permissions
|
||||
);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub mod config {
|
||||
use crate::clocks::ClockConfig;
|
||||
|
||||
|
@ -52,41 +52,20 @@ use core::sync::atomic::{compiler_fence, AtomicBool, Ordering};
|
||||
|
||||
use crate::interrupt::InterruptExt;
|
||||
use crate::peripherals::CORE1;
|
||||
use crate::{gpio, interrupt, pac};
|
||||
use crate::{gpio, install_stack_guard, interrupt, pac};
|
||||
|
||||
const PAUSE_TOKEN: u32 = 0xDEADBEEF;
|
||||
const RESUME_TOKEN: u32 = !0xDEADBEEF;
|
||||
static IS_CORE1_INIT: AtomicBool = AtomicBool::new(false);
|
||||
|
||||
#[inline(always)]
|
||||
fn install_stack_guard(stack_bottom: *mut usize) {
|
||||
let core = unsafe { cortex_m::Peripherals::steal() };
|
||||
|
||||
// Trap if MPU is already configured
|
||||
if core.MPU.ctrl.read() != 0 {
|
||||
fn core1_setup(stack_bottom: *mut usize) {
|
||||
if let Err(_) = install_stack_guard(stack_bottom) {
|
||||
// currently only happens if the MPU was already set up, which
|
||||
// would indicate that the core is already in use from outside
|
||||
// embassy, somehow. trap if so since we can't deal with that.
|
||||
cortex_m::asm::udf();
|
||||
}
|
||||
|
||||
// The minimum we can protect is 32 bytes on a 32 byte boundary, so round up which will
|
||||
// just shorten the valid stack range a tad.
|
||||
let addr = (stack_bottom as u32 + 31) & !31;
|
||||
// Mask is 1 bit per 32 bytes of the 256 byte range... clear the bit for the segment we want
|
||||
let subregion_select = 0xff ^ (1 << ((addr >> 5) & 7));
|
||||
unsafe {
|
||||
core.MPU.ctrl.write(5); // enable mpu with background default map
|
||||
core.MPU.rbar.write((addr & !0xff) | 0x8);
|
||||
core.MPU.rasr.write(
|
||||
1 // enable region
|
||||
| (0x7 << 1) // size 2^(7 + 1) = 256
|
||||
| (subregion_select << 8)
|
||||
| 0x10000000, // XN = disable instruction fetch; no other bits means no permissions
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn core1_setup(stack_bottom: *mut usize) {
|
||||
install_stack_guard(stack_bottom);
|
||||
unsafe {
|
||||
gpio::init();
|
||||
}
|
||||
|
@ -5,13 +5,13 @@ use core::sync::atomic::{compiler_fence, Ordering};
|
||||
use core::task::{Context, Poll};
|
||||
|
||||
use atomic_polyfill::{AtomicU32, AtomicU8};
|
||||
use embassy_hal_common::{into_ref, Peripheral, PeripheralRef};
|
||||
use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef};
|
||||
use embassy_sync::waitqueue::AtomicWaker;
|
||||
use fixed::types::extra::U8;
|
||||
use fixed::FixedU32;
|
||||
use pac::io::vals::Gpio0ctrlFuncsel;
|
||||
use pac::pio::vals::SmExecctrlStatusSel;
|
||||
use pio::{SideSet, Wrap};
|
||||
use pio::{Program, SideSet, Wrap};
|
||||
|
||||
use crate::dma::{Channel, Transfer, Word};
|
||||
use crate::gpio::sealed::Pin as SealedPin;
|
||||
@ -734,23 +734,67 @@ pub struct InstanceMemory<'d, PIO: Instance> {
|
||||
|
||||
pub struct LoadedProgram<'d, PIO: Instance> {
|
||||
pub used_memory: InstanceMemory<'d, PIO>,
|
||||
origin: u8,
|
||||
wrap: Wrap,
|
||||
side_set: SideSet,
|
||||
pub origin: u8,
|
||||
pub wrap: Wrap,
|
||||
pub side_set: SideSet,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||
pub enum LoadError {
|
||||
/// Insufficient consecutive free instruction space to load program.
|
||||
InsufficientSpace,
|
||||
/// Loading the program would overwrite an instruction address already
|
||||
/// used by another program.
|
||||
AddressInUse(usize),
|
||||
}
|
||||
|
||||
impl<'d, PIO: Instance> Common<'d, PIO> {
|
||||
pub fn load_program<const SIZE: usize>(&mut self, prog: &RelocatedProgram<SIZE>) -> LoadedProgram<'d, PIO> {
|
||||
/// Load a PIO program. This will automatically relocate the program to
|
||||
/// an available chunk of free instruction memory if the program origin
|
||||
/// was not explicitly specified, otherwise it will attempt to load the
|
||||
/// program only at its origin.
|
||||
pub fn load_program<const SIZE: usize>(&mut self, prog: &Program<SIZE>) -> LoadedProgram<'d, PIO> {
|
||||
match self.try_load_program(prog) {
|
||||
Ok(r) => r,
|
||||
Err(at) => panic!("Trying to write already used PIO instruction memory at {}", at),
|
||||
Err(e) => panic!("Failed to load PIO program: {:?}", e),
|
||||
}
|
||||
}
|
||||
|
||||
/// Load a PIO program. This will automatically relocate the program to
|
||||
/// an available chunk of free instruction memory if the program origin
|
||||
/// was not explicitly specified, otherwise it will attempt to load the
|
||||
/// program only at its origin.
|
||||
pub fn try_load_program<const SIZE: usize>(
|
||||
&mut self,
|
||||
prog: &RelocatedProgram<SIZE>,
|
||||
prog: &Program<SIZE>,
|
||||
) -> Result<LoadedProgram<'d, PIO>, LoadError> {
|
||||
match prog.origin {
|
||||
Some(origin) => self
|
||||
.try_load_program_at(prog, origin)
|
||||
.map_err(|a| LoadError::AddressInUse(a)),
|
||||
None => {
|
||||
// naively search for free space, allowing wraparound since
|
||||
// PIO does support that. with only 32 instruction slots it
|
||||
// doesn't make much sense to do anything more fancy.
|
||||
let mut origin = 0;
|
||||
while origin < 32 {
|
||||
match self.try_load_program_at(prog, origin as _) {
|
||||
Ok(r) => return Ok(r),
|
||||
Err(a) => origin = a + 1,
|
||||
}
|
||||
}
|
||||
Err(LoadError::InsufficientSpace)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn try_load_program_at<const SIZE: usize>(
|
||||
&mut self,
|
||||
prog: &Program<SIZE>,
|
||||
origin: u8,
|
||||
) -> Result<LoadedProgram<'d, PIO>, usize> {
|
||||
let prog = RelocatedProgram::new_with_origin(prog, origin);
|
||||
let used_memory = self.try_write_instr(prog.origin() as _, prog.code())?;
|
||||
Ok(LoadedProgram {
|
||||
used_memory,
|
||||
@ -760,7 +804,7 @@ impl<'d, PIO: Instance> Common<'d, PIO> {
|
||||
})
|
||||
}
|
||||
|
||||
pub fn try_write_instr<I>(&mut self, start: usize, instrs: I) -> Result<InstanceMemory<'d, PIO>, usize>
|
||||
fn try_write_instr<I>(&mut self, start: usize, instrs: I) -> Result<InstanceMemory<'d, PIO>, usize>
|
||||
where
|
||||
I: Iterator<Item = u16>,
|
||||
{
|
||||
|
@ -1,6 +1,6 @@
|
||||
//! Pulse Width Modulation (PWM)
|
||||
|
||||
use embassy_hal_common::{into_ref, Peripheral, PeripheralRef};
|
||||
use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef};
|
||||
use fixed::traits::ToFixed;
|
||||
use fixed::FixedU16;
|
||||
use pac::pwm::regs::{ChDiv, Intr};
|
||||
|
@ -41,11 +41,6 @@ pub struct RelocatedProgram<'a, const PROGRAM_SIZE: usize> {
|
||||
}
|
||||
|
||||
impl<'a, const PROGRAM_SIZE: usize> RelocatedProgram<'a, PROGRAM_SIZE> {
|
||||
pub fn new(program: &Program<PROGRAM_SIZE>) -> RelocatedProgram<PROGRAM_SIZE> {
|
||||
let origin = program.origin.unwrap_or(0);
|
||||
RelocatedProgram { program, origin }
|
||||
}
|
||||
|
||||
pub fn new_with_origin(program: &Program<PROGRAM_SIZE>, origin: u8) -> RelocatedProgram<PROGRAM_SIZE> {
|
||||
RelocatedProgram { program, origin }
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
mod filter;
|
||||
|
||||
use embassy_hal_common::{into_ref, Peripheral, PeripheralRef};
|
||||
use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef};
|
||||
|
||||
pub use self::filter::DateTimeFilter;
|
||||
|
||||
|
@ -3,7 +3,7 @@ use core::marker::PhantomData;
|
||||
|
||||
use embassy_embedded_hal::SetConfig;
|
||||
use embassy_futures::join::join;
|
||||
use embassy_hal_common::{into_ref, PeripheralRef};
|
||||
use embassy_hal_internal::{into_ref, PeripheralRef};
|
||||
pub use embedded_hal_02::spi::{Phase, Polarity};
|
||||
|
||||
use crate::dma::{AnyChannel, Channel};
|
||||
|
@ -3,7 +3,7 @@ use core::slice;
|
||||
use core::task::Poll;
|
||||
|
||||
use atomic_polyfill::{AtomicU8, Ordering};
|
||||
use embassy_hal_common::atomic_ring_buffer::RingBuffer;
|
||||
use embassy_hal_internal::atomic_ring_buffer::RingBuffer;
|
||||
use embassy_sync::waitqueue::AtomicWaker;
|
||||
use embassy_time::{Duration, Timer};
|
||||
|
||||
|
@ -4,7 +4,7 @@ use core::task::Poll;
|
||||
|
||||
use atomic_polyfill::{AtomicU16, Ordering};
|
||||
use embassy_futures::select::{select, Either};
|
||||
use embassy_hal_common::{into_ref, PeripheralRef};
|
||||
use embassy_hal_internal::{into_ref, PeripheralRef};
|
||||
use embassy_sync::waitqueue::AtomicWaker;
|
||||
use embassy_time::{Duration, Timer};
|
||||
use pac::uart::regs::Uartris;
|
||||
|
@ -15,7 +15,7 @@ embassy-stm32 = { version = "0.1.0", path = "../embassy-stm32" }
|
||||
embassy-sync = { version = "0.2.0", path = "../embassy-sync" }
|
||||
embassy-time = { version = "0.1.2", path = "../embassy-time", optional = true }
|
||||
embassy-futures = { version = "0.1.0", path = "../embassy-futures" }
|
||||
embassy-hal-common = { version = "0.1.0", path = "../embassy-hal-common" }
|
||||
embassy-hal-internal = { version = "0.1.0", path = "../embassy-hal-internal" }
|
||||
embassy-embedded-hal = { version = "0.1.0", path = "../embassy-embedded-hal" }
|
||||
embassy-net-driver = { version = "0.1.0", path = "../embassy-net-driver", optional=true }
|
||||
|
||||
@ -26,12 +26,12 @@ aligned = "0.4.1"
|
||||
|
||||
bit_field = "0.10.2"
|
||||
stm32-device-signature = { version = "0.3.3", features = ["stm32wb5x"] }
|
||||
stm32wb-hci = { version = "0.1.3", optional = true }
|
||||
stm32wb-hci = { version = "0.1.4", optional = true }
|
||||
futures = { version = "0.3.17", default-features = false, features = ["async-await"] }
|
||||
bitflags = { version = "2.3.3", optional = true }
|
||||
|
||||
[features]
|
||||
defmt = ["dep:defmt", "embassy-sync/defmt", "embassy-embedded-hal/defmt", "embassy-hal-common/defmt", "stm32wb-hci?/defmt"]
|
||||
defmt = ["dep:defmt", "embassy-sync/defmt", "embassy-embedded-hal/defmt", "embassy-hal-internal/defmt", "stm32wb-hci?/defmt"]
|
||||
|
||||
ble = ["dep:stm32wb-hci"]
|
||||
mac = ["dep:bitflags", "dep:embassy-net-driver" ]
|
||||
|
@ -8,7 +8,7 @@ pub mod fmt;
|
||||
use core::mem::MaybeUninit;
|
||||
use core::sync::atomic::{compiler_fence, Ordering};
|
||||
|
||||
use embassy_hal_common::{into_ref, Peripheral, PeripheralRef};
|
||||
use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef};
|
||||
use embassy_stm32::interrupt;
|
||||
use embassy_stm32::ipcc::{Config, Ipcc, ReceiveInterruptHandler, TransmitInterruptHandler};
|
||||
use embassy_stm32::peripherals::IPCC;
|
||||
|
@ -34,7 +34,7 @@ flavors = [
|
||||
embassy-sync = { version = "0.2.0", path = "../embassy-sync" }
|
||||
embassy-time = { version = "0.1.2", path = "../embassy-time", optional = true }
|
||||
embassy-futures = { version = "0.1.0", path = "../embassy-futures" }
|
||||
embassy-hal-common = {version = "0.1.0", path = "../embassy-hal-common", features = ["cortex-m", "prio-bits-4"] }
|
||||
embassy-hal-internal = {version = "0.1.0", path = "../embassy-hal-internal", features = ["cortex-m", "prio-bits-4"] }
|
||||
embassy-embedded-hal = {version = "0.1.0", path = "../embassy-embedded-hal" }
|
||||
embassy-net-driver = { version = "0.1.0", path = "../embassy-net-driver" }
|
||||
embassy-usb-driver = {version = "0.1.0", path = "../embassy-usb-driver", optional = true }
|
||||
@ -57,7 +57,7 @@ sdio-host = "0.5.0"
|
||||
embedded-sdmmc = { git = "https://github.com/embassy-rs/embedded-sdmmc-rs", rev = "a4f293d3a6f72158385f79c98634cb8a14d0d2fc", optional = true }
|
||||
critical-section = "1.1"
|
||||
atomic-polyfill = "1.0.1"
|
||||
stm32-metapac = "13"
|
||||
stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-1f8ab493e029fc601edebc6bac105a63cc9858fe" }
|
||||
vcell = "0.1.3"
|
||||
bxcan = "0.7.0"
|
||||
nb = "1.0.0"
|
||||
@ -67,6 +67,7 @@ cfg-if = "1.0.0"
|
||||
embedded-io = { version = "0.4.0", features = ["async"], optional = true }
|
||||
chrono = { version = "^0.4", default-features = false, optional = true}
|
||||
bit_field = "0.10.2"
|
||||
document-features = "0.2.7"
|
||||
|
||||
[dev-dependencies]
|
||||
critical-section = { version = "1.1", features = ["std"] }
|
||||
@ -74,44 +75,67 @@ critical-section = { version = "1.1", features = ["std"] }
|
||||
[build-dependencies]
|
||||
proc-macro2 = "1.0.36"
|
||||
quote = "1.0.15"
|
||||
stm32-metapac = { version = "13", default-features = false, features = ["metadata"]}
|
||||
stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-1f8ab493e029fc601edebc6bac105a63cc9858fe", default-features = false, features = ["metadata"]}
|
||||
|
||||
[features]
|
||||
default = ["rt"]
|
||||
|
||||
## Enable `stm32-metapac`'s `rt` feature
|
||||
rt = ["stm32-metapac/rt"]
|
||||
|
||||
defmt = ["dep:defmt", "bxcan/unstable-defmt", "embassy-sync/defmt", "embassy-embedded-hal/defmt", "embassy-hal-common/defmt", "embedded-io?/defmt", "embassy-usb-driver?/defmt", "embassy-net-driver/defmt", "embassy-time?/defmt"]
|
||||
memory-x = ["stm32-metapac/memory-x"]
|
||||
## Use [`defmt`](https://docs.rs/defmt/latest/defmt/) for logging
|
||||
defmt = ["dep:defmt", "bxcan/unstable-defmt", "embassy-sync/defmt", "embassy-embedded-hal/defmt", "embassy-hal-internal/defmt", "embedded-io?/defmt", "embassy-usb-driver?/defmt", "embassy-net-driver/defmt", "embassy-time?/defmt"]
|
||||
|
||||
exti = []
|
||||
|
||||
# Enables additional driver features that depend on embassy-time
|
||||
## Automatically generate `memory.x` file using [`stm32-metapac`](https://docs.rs/stm32-metapac/)
|
||||
memory-x = ["stm32-metapac/memory-x"]
|
||||
|
||||
## Enable nightly-only features
|
||||
nightly = ["embedded-hal-1", "embedded-hal-async", "embedded-storage-async", "dep:embedded-io", "dep:embassy-usb-driver", "embassy-embedded-hal/nightly"]
|
||||
|
||||
## Re-export stm32-metapac at `embassy_stm32::pac`.
|
||||
## This is unstable because semver-minor (non-breaking) releases of embassy-stm32 may major-bump (breaking) the stm32-metapac version.
|
||||
## If this is an issue for you, you're encouraged to directly depend on a fixed version of the PAC.
|
||||
## There are no plans to make this stable.
|
||||
unstable-pac = []
|
||||
|
||||
## Implement embedded-hal 1.0 alpha traits.
|
||||
## Implement embedded-hal-async traits if `nightly` is set as well.
|
||||
unstable-traits = ["embedded-hal-1", "dep:embedded-hal-nb"]
|
||||
|
||||
#! ## Time
|
||||
|
||||
## Enables additional driver features that depend on embassy-time
|
||||
time = ["dep:embassy-time"]
|
||||
|
||||
# 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.
|
||||
_time-driver = ["time"]
|
||||
|
||||
## Use any time driver
|
||||
time-driver-any = ["_time-driver"]
|
||||
## Use TIM2 as time driver
|
||||
time-driver-tim2 = ["_time-driver"]
|
||||
## Use TIM3 as time driver
|
||||
time-driver-tim3 = ["_time-driver"]
|
||||
## Use TIM4 as time driver
|
||||
time-driver-tim4 = ["_time-driver"]
|
||||
## Use TIM5 as time driver
|
||||
time-driver-tim5 = ["_time-driver"]
|
||||
## Use TIM12 as time driver
|
||||
time-driver-tim12 = ["_time-driver"]
|
||||
## Use TIM15 as time driver
|
||||
time-driver-tim15 = ["_time-driver"]
|
||||
|
||||
# Enable nightly-only features
|
||||
nightly = ["embedded-hal-1", "embedded-hal-async", "embedded-storage-async", "dep:embedded-io", "dep:embassy-usb-driver", "embassy-embedded-hal/nightly"]
|
||||
|
||||
# Reexport stm32-metapac at `embassy_stm32::pac`.
|
||||
# This is unstable because semver-minor (non-breaking) releases of embassy-stm32 may major-bump (breaking) the stm32-metapac version.
|
||||
# If this is an issue for you, you're encouraged to directly depend on a fixed version of the PAC.
|
||||
# There are no plans to make this stable.
|
||||
unstable-pac = []
|
||||
#! ## Chip-selection features
|
||||
#! Select your chip by specifying the model as a feature, e.g. `stm32c011d6`.
|
||||
#! Check the `Cargo.toml` for the latest list of supported chips.
|
||||
#!
|
||||
#! **Important:** Do not forget to adapt the target chip in your toolchain,
|
||||
#! e.g. in `.cargo/config.toml`.
|
||||
|
||||
# Implement embedded-hal 1.0 alpha traits.
|
||||
# Implement embedded-hal-async traits if `nightly` is set as well.
|
||||
unstable-traits = ["embedded-hal-1", "dep:embedded-hal-nb"]
|
||||
|
||||
# Chip-selection features
|
||||
stm32c011d6 = [ "stm32-metapac/stm32c011d6" ]
|
||||
stm32c011f4 = [ "stm32-metapac/stm32c011f4" ]
|
||||
stm32c011f6 = [ "stm32-metapac/stm32c011f6" ]
|
||||
|
@ -138,7 +138,7 @@ fn main() {
|
||||
let singleton_tokens: Vec<_> = singletons.iter().map(|s| format_ident!("{}", s)).collect();
|
||||
|
||||
g.extend(quote! {
|
||||
embassy_hal_common::peripherals_definition!(#(#singleton_tokens),*);
|
||||
embassy_hal_internal::peripherals_definition!(#(#singleton_tokens),*);
|
||||
});
|
||||
|
||||
let singleton_tokens: Vec<_> = singletons
|
||||
@ -148,7 +148,7 @@ fn main() {
|
||||
.collect();
|
||||
|
||||
g.extend(quote! {
|
||||
embassy_hal_common::peripherals_struct!(#(#singleton_tokens),*);
|
||||
embassy_hal_internal::peripherals_struct!(#(#singleton_tokens),*);
|
||||
});
|
||||
|
||||
// ========
|
||||
@ -160,7 +160,7 @@ fn main() {
|
||||
}
|
||||
|
||||
g.extend(quote! {
|
||||
embassy_hal_common::interrupt_mod!(
|
||||
embassy_hal_internal::interrupt_mod!(
|
||||
#(
|
||||
#irqs,
|
||||
)*
|
||||
@ -211,7 +211,7 @@ fn main() {
|
||||
let region_type = format_ident!("{}", get_flash_region_type_name(region.name));
|
||||
flash_regions.extend(quote! {
|
||||
#[cfg(flash)]
|
||||
pub struct #region_type<'d, MODE = crate::flash::Async>(pub &'static crate::flash::FlashRegion, pub(crate) embassy_hal_common::PeripheralRef<'d, crate::peripherals::FLASH>, pub(crate) core::marker::PhantomData<MODE>);
|
||||
pub struct #region_type<'d, MODE = crate::flash::Async>(pub &'static crate::flash::FlashRegion, pub(crate) embassy_hal_internal::PeripheralRef<'d, crate::peripherals::FLASH>, pub(crate) core::marker::PhantomData<MODE>);
|
||||
});
|
||||
}
|
||||
|
||||
@ -243,7 +243,7 @@ fn main() {
|
||||
|
||||
#[cfg(flash)]
|
||||
impl<'d, MODE> FlashLayout<'d, MODE> {
|
||||
pub(crate) fn new(p: embassy_hal_common::PeripheralRef<'d, crate::peripherals::FLASH>) -> Self {
|
||||
pub(crate) fn new(p: embassy_hal_internal::PeripheralRef<'d, crate::peripherals::FLASH>) -> Self {
|
||||
Self {
|
||||
#(#inits),*,
|
||||
_mode: core::marker::PhantomData,
|
||||
@ -572,21 +572,31 @@ fn main() {
|
||||
(("fmc", "Clk"), quote!(crate::fmc::ClkPin)),
|
||||
(("fmc", "BA0"), quote!(crate::fmc::BA0Pin)),
|
||||
(("fmc", "BA1"), quote!(crate::fmc::BA1Pin)),
|
||||
(("timer", "CH1"), quote!(crate::pwm::Channel1Pin)),
|
||||
(("timer", "CH1N"), quote!(crate::pwm::Channel1ComplementaryPin)),
|
||||
(("timer", "CH2"), quote!(crate::pwm::Channel2Pin)),
|
||||
(("timer", "CH2N"), quote!(crate::pwm::Channel2ComplementaryPin)),
|
||||
(("timer", "CH3"), quote!(crate::pwm::Channel3Pin)),
|
||||
(("timer", "CH3N"), quote!(crate::pwm::Channel3ComplementaryPin)),
|
||||
(("timer", "CH4"), quote!(crate::pwm::Channel4Pin)),
|
||||
(("timer", "CH4N"), quote!(crate::pwm::Channel4ComplementaryPin)),
|
||||
(("timer", "ETR"), quote!(crate::pwm::ExternalTriggerPin)),
|
||||
(("timer", "BKIN"), quote!(crate::pwm::BreakInputPin)),
|
||||
(("timer", "BKIN_COMP1"), quote!(crate::pwm::BreakInputComparator1Pin)),
|
||||
(("timer", "BKIN_COMP2"), quote!(crate::pwm::BreakInputComparator2Pin)),
|
||||
(("timer", "BKIN2"), quote!(crate::pwm::BreakInput2Pin)),
|
||||
(("timer", "BKIN2_COMP1"), quote!(crate::pwm::BreakInput2Comparator1Pin)),
|
||||
(("timer", "BKIN2_COMP2"), quote!(crate::pwm::BreakInput2Comparator2Pin)),
|
||||
(("timer", "CH1"), quote!(crate::timer::Channel1Pin)),
|
||||
(("timer", "CH1N"), quote!(crate::timer::Channel1ComplementaryPin)),
|
||||
(("timer", "CH2"), quote!(crate::timer::Channel2Pin)),
|
||||
(("timer", "CH2N"), quote!(crate::timer::Channel2ComplementaryPin)),
|
||||
(("timer", "CH3"), quote!(crate::timer::Channel3Pin)),
|
||||
(("timer", "CH3N"), quote!(crate::timer::Channel3ComplementaryPin)),
|
||||
(("timer", "CH4"), quote!(crate::timer::Channel4Pin)),
|
||||
(("timer", "CH4N"), quote!(crate::timer::Channel4ComplementaryPin)),
|
||||
(("timer", "ETR"), quote!(crate::timer::ExternalTriggerPin)),
|
||||
(("timer", "BKIN"), quote!(crate::timer::BreakInputPin)),
|
||||
(("timer", "BKIN_COMP1"), quote!(crate::timer::BreakInputComparator1Pin)),
|
||||
(("timer", "BKIN_COMP2"), quote!(crate::timer::BreakInputComparator2Pin)),
|
||||
(("timer", "BKIN2"), quote!(crate::timer::BreakInput2Pin)),
|
||||
(("timer", "BKIN2_COMP1"), quote!(crate::timer::BreakInput2Comparator1Pin)),
|
||||
(("timer", "BKIN2_COMP2"), quote!(crate::timer::BreakInput2Comparator2Pin)),
|
||||
(("hrtim", "CHA1"), quote!(crate::hrtim::ChannelAPin)),
|
||||
(("hrtim", "CHA2"), quote!(crate::hrtim::ChannelAComplementaryPin)),
|
||||
(("hrtim", "CHB1"), quote!(crate::hrtim::ChannelBPin)),
|
||||
(("hrtim", "CHB2"), quote!(crate::hrtim::ChannelBComplementaryPin)),
|
||||
(("hrtim", "CHC1"), quote!(crate::hrtim::ChannelCPin)),
|
||||
(("hrtim", "CHC2"), quote!(crate::hrtim::ChannelCComplementaryPin)),
|
||||
(("hrtim", "CHD1"), quote!(crate::hrtim::ChannelDPin)),
|
||||
(("hrtim", "CHD2"), quote!(crate::hrtim::ChannelDComplementaryPin)),
|
||||
(("hrtim", "CHE1"), quote!(crate::hrtim::ChannelEPin)),
|
||||
(("hrtim", "CHE2"), quote!(crate::hrtim::ChannelEComplementaryPin)),
|
||||
(("sdmmc", "CK"), quote!(crate::sdmmc::CkPin)),
|
||||
(("sdmmc", "CMD"), quote!(crate::sdmmc::CmdPin)),
|
||||
(("sdmmc", "D0"), quote!(crate::sdmmc::D0Pin)),
|
||||
|
@ -1,4 +1,4 @@
|
||||
use embassy_hal_common::into_ref;
|
||||
use embassy_hal_internal::into_ref;
|
||||
use embedded_hal_02::blocking::delay::DelayUs;
|
||||
|
||||
use crate::adc::{Adc, AdcPin, Instance, SampleTime};
|
||||
|
@ -1,4 +1,4 @@
|
||||
use embassy_hal_common::into_ref;
|
||||
use embassy_hal_internal::into_ref;
|
||||
use embedded_hal_02::blocking::delay::DelayUs;
|
||||
|
||||
use crate::adc::{Adc, AdcPin, Instance, InternalChannel, Resolution, SampleTime};
|
||||
|
@ -1,4 +1,4 @@
|
||||
use embassy_hal_common::into_ref;
|
||||
use embassy_hal_internal::into_ref;
|
||||
use embedded_hal_02::blocking::delay::DelayUs;
|
||||
|
||||
use super::InternalChannel;
|
||||
|
@ -1,4 +1,4 @@
|
||||
use embassy_hal_common::into_ref;
|
||||
use embassy_hal_internal::into_ref;
|
||||
use embedded_hal_02::blocking::delay::DelayUs;
|
||||
|
||||
use crate::adc::{Adc, AdcPin, Instance, Resolution, SampleTime};
|
||||
|
@ -226,7 +226,7 @@ impl Prescaler {
|
||||
|
||||
impl<'d, T: Instance> Adc<'d, T> {
|
||||
pub fn new(adc: impl Peripheral<P = T> + 'd, delay: &mut impl DelayUs<u16>) -> Self {
|
||||
embassy_hal_common::into_ref!(adc);
|
||||
embassy_hal_internal::into_ref!(adc);
|
||||
T::enable();
|
||||
T::reset();
|
||||
|
||||
|
@ -6,7 +6,7 @@ use core::task::Poll;
|
||||
|
||||
pub use bxcan;
|
||||
use bxcan::{Data, ExtendedId, Frame, Id, StandardId};
|
||||
use embassy_hal_common::{into_ref, PeripheralRef};
|
||||
use embassy_hal_internal::{into_ref, PeripheralRef};
|
||||
use futures::FutureExt;
|
||||
|
||||
use crate::gpio::sealed::AFType;
|
||||
@ -88,6 +88,7 @@ pub struct Can<'d, T: Instance> {
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||
pub enum BusError {
|
||||
Stuff,
|
||||
Form,
|
||||
@ -101,6 +102,22 @@ pub enum BusError {
|
||||
BusWarning,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||
pub enum TryReadError {
|
||||
/// Bus error
|
||||
BusError(BusError),
|
||||
/// Receive buffer is empty
|
||||
Empty,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||
pub enum TryWriteError {
|
||||
/// All transmit mailboxes are full
|
||||
Full,
|
||||
}
|
||||
|
||||
impl<'d, T: Instance> Can<'d, T> {
|
||||
/// Creates a new Bxcan instance, keeping the peripheral in sleep mode.
|
||||
/// You must call [Can::enable_non_blocking] to use the peripheral.
|
||||
@ -186,56 +203,46 @@ impl<'d, T: Instance> Can<'d, T> {
|
||||
|
||||
/// Queues the message to be sent but exerts backpressure
|
||||
pub async fn write(&mut self, frame: &Frame) -> bxcan::TransmitStatus {
|
||||
poll_fn(|cx| {
|
||||
T::state().tx_waker.register(cx.waker());
|
||||
if let Ok(status) = self.can.borrow_mut().transmit(frame) {
|
||||
return Poll::Ready(status);
|
||||
}
|
||||
|
||||
Poll::Pending
|
||||
})
|
||||
.await
|
||||
CanTx { can: &self.can }.write(frame).await
|
||||
}
|
||||
|
||||
pub async fn flush(&self, mb: bxcan::Mailbox) {
|
||||
poll_fn(|cx| {
|
||||
T::state().tx_waker.register(cx.waker());
|
||||
if T::regs().tsr().read().tme(mb.index()) {
|
||||
return Poll::Ready(());
|
||||
}
|
||||
/// Attempts to transmit a frame without blocking.
|
||||
///
|
||||
/// Returns [Err(TryWriteError::Full)] if all transmit mailboxes are full.
|
||||
pub fn try_write(&mut self, frame: &Frame) -> Result<bxcan::TransmitStatus, TryWriteError> {
|
||||
CanTx { can: &self.can }.try_write(frame)
|
||||
}
|
||||
|
||||
Poll::Pending
|
||||
})
|
||||
.await;
|
||||
/// Waits for a specific transmit mailbox to become empty
|
||||
pub async fn flush(&self, mb: bxcan::Mailbox) {
|
||||
CanTx { can: &self.can }.flush(mb).await
|
||||
}
|
||||
|
||||
/// Waits until any of the transmit mailboxes become empty
|
||||
pub async fn flush_any(&self) {
|
||||
CanTx { can: &self.can }.flush_any().await
|
||||
}
|
||||
|
||||
/// Waits until all of the transmit mailboxes become empty
|
||||
pub async fn flush_all(&self) {
|
||||
CanTx { can: &self.can }.flush_all().await
|
||||
}
|
||||
|
||||
/// Returns a tuple of the time the message was received and the message frame
|
||||
pub async fn read(&mut self) -> Result<Envelope, BusError> {
|
||||
poll_fn(|cx| {
|
||||
T::state().err_waker.register(cx.waker());
|
||||
if let Poll::Ready(envelope) = T::state().rx_queue.recv().poll_unpin(cx) {
|
||||
return Poll::Ready(Ok(envelope));
|
||||
} else if let Some(err) = self.curr_error() {
|
||||
return Poll::Ready(Err(err));
|
||||
}
|
||||
|
||||
Poll::Pending
|
||||
})
|
||||
.await
|
||||
CanRx { can: &self.can }.read().await
|
||||
}
|
||||
|
||||
fn curr_error(&self) -> Option<BusError> {
|
||||
let err = { T::regs().esr().read() };
|
||||
if err.boff() {
|
||||
return Some(BusError::BusOff);
|
||||
} else if err.epvf() {
|
||||
return Some(BusError::BusPassive);
|
||||
} else if err.ewgf() {
|
||||
return Some(BusError::BusWarning);
|
||||
} else if let Some(err) = err.lec().into_bus_err() {
|
||||
return Some(err);
|
||||
}
|
||||
None
|
||||
/// Attempts to read a can frame without blocking.
|
||||
///
|
||||
/// Returns [Err(TryReadError::Empty)] if there are no frames in the rx queue.
|
||||
pub fn try_read(&mut self) -> Result<Envelope, TryReadError> {
|
||||
CanRx { can: &self.can }.try_read()
|
||||
}
|
||||
|
||||
/// Waits while receive queue is empty.
|
||||
pub async fn wait_not_empty(&mut self) {
|
||||
CanRx { can: &self.can }.wait_not_empty().await
|
||||
}
|
||||
|
||||
unsafe fn receive_fifo(fifo: RxFifo) {
|
||||
@ -405,6 +412,14 @@ impl<'c, 'd, T: Instance> CanTx<'c, 'd, T> {
|
||||
.await
|
||||
}
|
||||
|
||||
/// Attempts to transmit a frame without blocking.
|
||||
///
|
||||
/// Returns [Err(TryWriteError::Full)] if all transmit mailboxes are full.
|
||||
pub fn try_write(&mut self, frame: &Frame) -> Result<bxcan::TransmitStatus, TryWriteError> {
|
||||
self.can.borrow_mut().transmit(frame).map_err(|_| TryWriteError::Full)
|
||||
}
|
||||
|
||||
/// Waits for a specific transmit mailbox to become empty
|
||||
pub async fn flush(&self, mb: bxcan::Mailbox) {
|
||||
poll_fn(|cx| {
|
||||
T::state().tx_waker.register(cx.waker());
|
||||
@ -416,6 +431,42 @@ impl<'c, 'd, T: Instance> CanTx<'c, 'd, T> {
|
||||
})
|
||||
.await;
|
||||
}
|
||||
|
||||
/// Waits until any of the transmit mailboxes become empty
|
||||
pub async fn flush_any(&self) {
|
||||
poll_fn(|cx| {
|
||||
T::state().tx_waker.register(cx.waker());
|
||||
|
||||
let tsr = T::regs().tsr().read();
|
||||
if tsr.tme(bxcan::Mailbox::Mailbox0.index())
|
||||
|| tsr.tme(bxcan::Mailbox::Mailbox1.index())
|
||||
|| tsr.tme(bxcan::Mailbox::Mailbox2.index())
|
||||
{
|
||||
return Poll::Ready(());
|
||||
}
|
||||
|
||||
Poll::Pending
|
||||
})
|
||||
.await;
|
||||
}
|
||||
|
||||
/// Waits until all of the transmit mailboxes become empty
|
||||
pub async fn flush_all(&self) {
|
||||
poll_fn(|cx| {
|
||||
T::state().tx_waker.register(cx.waker());
|
||||
|
||||
let tsr = T::regs().tsr().read();
|
||||
if tsr.tme(bxcan::Mailbox::Mailbox0.index())
|
||||
&& tsr.tme(bxcan::Mailbox::Mailbox1.index())
|
||||
&& tsr.tme(bxcan::Mailbox::Mailbox2.index())
|
||||
{
|
||||
return Poll::Ready(());
|
||||
}
|
||||
|
||||
Poll::Pending
|
||||
})
|
||||
.await;
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
@ -438,6 +489,33 @@ impl<'c, 'd, T: Instance> CanRx<'c, 'd, T> {
|
||||
.await
|
||||
}
|
||||
|
||||
/// Attempts to read a CAN frame without blocking.
|
||||
///
|
||||
/// Returns [Err(TryReadError::Empty)] if there are no frames in the rx queue.
|
||||
pub fn try_read(&mut self) -> Result<Envelope, TryReadError> {
|
||||
if let Ok(envelope) = T::state().rx_queue.try_recv() {
|
||||
return Ok(envelope);
|
||||
}
|
||||
|
||||
if let Some(err) = self.curr_error() {
|
||||
return Err(TryReadError::BusError(err));
|
||||
}
|
||||
|
||||
Err(TryReadError::Empty)
|
||||
}
|
||||
|
||||
/// Waits while receive queue is empty.
|
||||
pub async fn wait_not_empty(&mut self) {
|
||||
poll_fn(|cx| {
|
||||
if T::state().rx_queue.poll_ready_to_receive(cx) {
|
||||
Poll::Ready(())
|
||||
} else {
|
||||
Poll::Pending
|
||||
}
|
||||
})
|
||||
.await
|
||||
}
|
||||
|
||||
fn curr_error(&self) -> Option<BusError> {
|
||||
let err = { T::regs().esr().read() };
|
||||
if err.boff() {
|
||||
|
@ -1,5 +1,5 @@
|
||||
pub use bxcan;
|
||||
use embassy_hal_common::PeripheralRef;
|
||||
use embassy_hal_internal::PeripheralRef;
|
||||
|
||||
use crate::peripherals;
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
use embassy_hal_common::{into_ref, PeripheralRef};
|
||||
use embassy_hal_internal::{into_ref, PeripheralRef};
|
||||
|
||||
use crate::pac::CRC as PAC_CRC;
|
||||
use crate::peripherals::CRC;
|
||||
|
@ -1,4 +1,4 @@
|
||||
use embassy_hal_common::{into_ref, PeripheralRef};
|
||||
use embassy_hal_internal::{into_ref, PeripheralRef};
|
||||
|
||||
use crate::pac::crc::vals;
|
||||
use crate::pac::CRC as PAC_CRC;
|
||||
|
@ -3,7 +3,7 @@
|
||||
//! Provide access to the STM32 digital-to-analog converter (DAC).
|
||||
use core::marker::PhantomData;
|
||||
|
||||
use embassy_hal_common::{into_ref, PeripheralRef};
|
||||
use embassy_hal_internal::{into_ref, PeripheralRef};
|
||||
|
||||
use crate::pac::dac;
|
||||
use crate::rcc::RccPeripheral;
|
||||
|
@ -2,7 +2,7 @@ use core::future::poll_fn;
|
||||
use core::marker::PhantomData;
|
||||
use core::task::Poll;
|
||||
|
||||
use embassy_hal_common::{into_ref, PeripheralRef};
|
||||
use embassy_hal_internal::{into_ref, PeripheralRef};
|
||||
use embassy_sync::waitqueue::AtomicWaker;
|
||||
|
||||
use crate::dma::Transfer;
|
||||
|
@ -6,7 +6,7 @@ use core::sync::atomic::{fence, Ordering};
|
||||
use core::task::{Context, Poll, Waker};
|
||||
|
||||
use atomic_polyfill::AtomicUsize;
|
||||
use embassy_hal_common::{into_ref, Peripheral, PeripheralRef};
|
||||
use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef};
|
||||
use embassy_sync::waitqueue::AtomicWaker;
|
||||
|
||||
use super::ringbuffer::{DmaCtrl, DmaRingBuffer, OverrunError};
|
||||
@ -466,15 +466,53 @@ impl<'a, C: Channel, W: Word> RingBuffer<'a, C, W> {
|
||||
self.ringbuf.clear(DmaCtrlImpl(self.channel.reborrow()));
|
||||
}
|
||||
|
||||
/// Read bytes from the ring buffer
|
||||
/// Read elements from the ring buffer
|
||||
/// Return a tuple of the length read and the length remaining in the buffer
|
||||
/// If not all of the bytes were read, then there will be some bytes in the buffer remaining
|
||||
/// The length remaining is the capacity, ring_buf.len(), less the bytes remaining after the read
|
||||
/// If not all of the elements were read, then there will be some elements in the buffer remaining
|
||||
/// The length remaining is the capacity, ring_buf.len(), less the elements remaining after the read
|
||||
/// OverrunError is returned if the portion to be read was overwritten by the DMA controller.
|
||||
pub fn read(&mut self, buf: &mut [W]) -> Result<(usize, usize), OverrunError> {
|
||||
self.ringbuf.read(DmaCtrlImpl(self.channel.reborrow()), buf)
|
||||
}
|
||||
|
||||
/// Read an exact number of elements from the ringbuffer.
|
||||
///
|
||||
/// Returns the remaining number of elements available for immediate reading.
|
||||
/// OverrunError is returned if the portion to be read was overwritten by the DMA controller.
|
||||
///
|
||||
/// Async/Wake Behavior:
|
||||
/// The underlying DMA peripheral only can wake us when its buffer pointer has reached the halfway point,
|
||||
/// and when it wraps around. This means that when called with a buffer of length 'M', when this
|
||||
/// ring buffer was created with a buffer of size 'N':
|
||||
/// - If M equals N/2 or N/2 divides evenly into M, this function will return every N/2 elements read on the DMA source.
|
||||
/// - Otherwise, this function may need up to N/2 extra elements to arrive before returning.
|
||||
pub async fn read_exact(&mut self, buffer: &mut [W]) -> Result<usize, OverrunError> {
|
||||
use core::future::poll_fn;
|
||||
use core::sync::atomic::compiler_fence;
|
||||
|
||||
let mut read_data = 0;
|
||||
let buffer_len = buffer.len();
|
||||
|
||||
poll_fn(|cx| {
|
||||
self.set_waker(cx.waker());
|
||||
|
||||
compiler_fence(Ordering::SeqCst);
|
||||
|
||||
match self.read(&mut buffer[read_data..buffer_len]) {
|
||||
Ok((len, remaining)) => {
|
||||
read_data += len;
|
||||
if read_data == buffer_len {
|
||||
Poll::Ready(Ok(remaining))
|
||||
} else {
|
||||
Poll::Pending
|
||||
}
|
||||
}
|
||||
Err(e) => Poll::Ready(Err(e)),
|
||||
}
|
||||
})
|
||||
.await
|
||||
}
|
||||
|
||||
/// The capacity of the ringbuffer
|
||||
pub fn cap(&self) -> usize {
|
||||
self.ringbuf.cap()
|
||||
|
@ -4,7 +4,7 @@ use core::pin::Pin;
|
||||
use core::sync::atomic::{fence, AtomicUsize, Ordering};
|
||||
use core::task::{Context, Poll, Waker};
|
||||
|
||||
use embassy_hal_common::{into_ref, Peripheral, PeripheralRef};
|
||||
use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef};
|
||||
use embassy_sync::waitqueue::AtomicWaker;
|
||||
|
||||
use super::ringbuffer::{DmaCtrl, DmaRingBuffer, OverrunError};
|
||||
@ -711,15 +711,53 @@ impl<'a, C: Channel, W: Word> RingBuffer<'a, C, W> {
|
||||
self.ringbuf.clear(DmaCtrlImpl(self.channel.reborrow()));
|
||||
}
|
||||
|
||||
/// Read bytes from the ring buffer
|
||||
/// Read elements from the ring buffer
|
||||
/// Return a tuple of the length read and the length remaining in the buffer
|
||||
/// If not all of the bytes were read, then there will be some bytes in the buffer remaining
|
||||
/// The length remaining is the capacity, ring_buf.len(), less the bytes remaining after the read
|
||||
/// If not all of the elements were read, then there will be some elements in the buffer remaining
|
||||
/// The length remaining is the capacity, ring_buf.len(), less the elements remaining after the read
|
||||
/// OverrunError is returned if the portion to be read was overwritten by the DMA controller.
|
||||
pub fn read(&mut self, buf: &mut [W]) -> Result<(usize, usize), OverrunError> {
|
||||
self.ringbuf.read(DmaCtrlImpl(self.channel.reborrow()), buf)
|
||||
}
|
||||
|
||||
/// Read an exact number of elements from the ringbuffer.
|
||||
///
|
||||
/// Returns the remaining number of elements available for immediate reading.
|
||||
/// OverrunError is returned if the portion to be read was overwritten by the DMA controller.
|
||||
///
|
||||
/// Async/Wake Behavior:
|
||||
/// The underlying DMA peripheral only can wake us when its buffer pointer has reached the halfway point,
|
||||
/// and when it wraps around. This means that when called with a buffer of length 'M', when this
|
||||
/// ring buffer was created with a buffer of size 'N':
|
||||
/// - If M equals N/2 or N/2 divides evenly into M, this function will return every N/2 elements read on the DMA source.
|
||||
/// - Otherwise, this function may need up to N/2 extra elements to arrive before returning.
|
||||
pub async fn read_exact(&mut self, buffer: &mut [W]) -> Result<usize, OverrunError> {
|
||||
use core::future::poll_fn;
|
||||
use core::sync::atomic::compiler_fence;
|
||||
|
||||
let mut read_data = 0;
|
||||
let buffer_len = buffer.len();
|
||||
|
||||
poll_fn(|cx| {
|
||||
self.set_waker(cx.waker());
|
||||
|
||||
compiler_fence(Ordering::SeqCst);
|
||||
|
||||
match self.read(&mut buffer[read_data..buffer_len]) {
|
||||
Ok((len, remaining)) => {
|
||||
read_data += len;
|
||||
if read_data == buffer_len {
|
||||
Poll::Ready(Ok(remaining))
|
||||
} else {
|
||||
Poll::Pending
|
||||
}
|
||||
}
|
||||
Err(e) => Poll::Ready(Err(e)),
|
||||
}
|
||||
})
|
||||
.await
|
||||
}
|
||||
|
||||
// The capacity of the ringbuffer
|
||||
pub fn cap(&self) -> usize {
|
||||
self.ringbuf.cap()
|
||||
|
@ -5,7 +5,7 @@ use core::pin::Pin;
|
||||
use core::sync::atomic::{fence, Ordering};
|
||||
use core::task::{Context, Poll};
|
||||
|
||||
use embassy_hal_common::{into_ref, Peripheral, PeripheralRef};
|
||||
use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef};
|
||||
use embassy_sync::waitqueue::AtomicWaker;
|
||||
|
||||
use super::word::{Word, WordSize};
|
||||
|
@ -26,7 +26,7 @@ pub mod word;
|
||||
|
||||
use core::mem;
|
||||
|
||||
use embassy_hal_common::impl_peripheral;
|
||||
use embassy_hal_internal::impl_peripheral;
|
||||
|
||||
#[cfg(dmamux)]
|
||||
pub use self::dmamux::*;
|
||||
|
@ -72,10 +72,10 @@ impl<'a, W: Word> DmaRingBuffer<'a, W> {
|
||||
self.cap() - remaining_transfers
|
||||
}
|
||||
|
||||
/// Read bytes from the ring buffer
|
||||
/// Read elements from the ring buffer
|
||||
/// Return a tuple of the length read and the length remaining in the buffer
|
||||
/// If not all of the bytes were read, then there will be some bytes in the buffer remaining
|
||||
/// The length remaining is the capacity, ring_buf.len(), less the bytes remaining after the read
|
||||
/// If not all of the elements were read, then there will be some elements in the buffer remaining
|
||||
/// The length remaining is the capacity, ring_buf.len(), less the elements remaining after the read
|
||||
/// OverrunError is returned if the portion to be read was overwritten by the DMA controller.
|
||||
pub fn read(&mut self, mut dma: impl DmaCtrl, buf: &mut [W]) -> Result<(usize, usize), OverrunError> {
|
||||
/*
|
||||
@ -95,11 +95,11 @@ impl<'a, W: Word> DmaRingBuffer<'a, W> {
|
||||
*/
|
||||
let end = self.pos(dma.get_remaining_transfers());
|
||||
if self.start == end && dma.get_complete_count() == 0 {
|
||||
// No bytes are available in the buffer
|
||||
// No elements are available in the buffer
|
||||
Ok((0, self.cap()))
|
||||
} else if self.start < end {
|
||||
// The available, unread portion in the ring buffer DOES NOT wrap
|
||||
// Copy out the bytes from the dma buffer
|
||||
// Copy out the elements from the dma buffer
|
||||
let len = self.copy_to(buf, self.start..end);
|
||||
|
||||
compiler_fence(Ordering::SeqCst);
|
||||
@ -128,7 +128,7 @@ impl<'a, W: Word> DmaRingBuffer<'a, W> {
|
||||
// The DMA writer has wrapped since we last read and is currently
|
||||
// writing (or the next byte added will be) in the beginning of the ring buffer.
|
||||
|
||||
// The provided read buffer is not large enough to include all bytes from the tail of the dma buffer.
|
||||
// The provided read buffer is not large enough to include all elements from the tail of the dma buffer.
|
||||
|
||||
// Copy out from the dma buffer
|
||||
let len = self.copy_to(buf, self.start..self.cap());
|
||||
@ -154,8 +154,8 @@ impl<'a, W: Word> DmaRingBuffer<'a, W> {
|
||||
// The DMA writer has wrapped since we last read and is currently
|
||||
// writing (or the next byte added will be) in the beginning of the ring buffer.
|
||||
|
||||
// The provided read buffer is large enough to include all bytes from the tail of the dma buffer,
|
||||
// so the next read will not have any unread tail bytes in the ring buffer.
|
||||
// The provided read buffer is large enough to include all elements from the tail of the dma buffer,
|
||||
// so the next read will not have any unread tail elements in the ring buffer.
|
||||
|
||||
// Copy out from the dma buffer
|
||||
let tail = self.copy_to(buf, self.start..self.cap());
|
||||
@ -180,7 +180,7 @@ impl<'a, W: Word> DmaRingBuffer<'a, W> {
|
||||
}
|
||||
/// Copy from the dma buffer at `data_range` into `buf`
|
||||
fn copy_to(&mut self, buf: &mut [W], data_range: Range<usize>) -> usize {
|
||||
// Limit the number of bytes that can be copied
|
||||
// Limit the number of elements that can be copied
|
||||
let length = usize::min(data_range.len(), buf.len());
|
||||
|
||||
// Copy from dma buffer into read buffer
|
||||
|
@ -6,7 +6,7 @@ mod tx_desc;
|
||||
use core::marker::PhantomData;
|
||||
use core::sync::atomic::{fence, Ordering};
|
||||
|
||||
use embassy_hal_common::{into_ref, PeripheralRef};
|
||||
use embassy_hal_internal::{into_ref, PeripheralRef};
|
||||
use stm32_metapac::eth::vals::{Apcs, Cr, Dm, DmaomrSr, Fes, Ftf, Ifg, MbProgress, Mw, Pbl, Rsf, St, Tsf};
|
||||
|
||||
pub(crate) use self::rx_desc::{RDes, RDesRing};
|
||||
|
@ -3,7 +3,7 @@ mod descriptors;
|
||||
use core::marker::PhantomData;
|
||||
use core::sync::atomic::{fence, Ordering};
|
||||
|
||||
use embassy_hal_common::{into_ref, PeripheralRef};
|
||||
use embassy_hal_internal::{into_ref, PeripheralRef};
|
||||
|
||||
pub(crate) use self::descriptors::{RDes, RDesRing, TDes, TDesRing};
|
||||
use super::*;
|
||||
|
@ -3,7 +3,7 @@ use core::marker::PhantomData;
|
||||
use core::pin::Pin;
|
||||
use core::task::{Context, Poll};
|
||||
|
||||
use embassy_hal_common::impl_peripheral;
|
||||
use embassy_hal_internal::impl_peripheral;
|
||||
use embassy_sync::waitqueue::AtomicWaker;
|
||||
|
||||
use crate::gpio::{AnyPin, Input, Pin as GpioPin};
|
||||
|
@ -1,8 +1,8 @@
|
||||
use core::marker::PhantomData;
|
||||
use core::sync::atomic::{fence, Ordering};
|
||||
|
||||
use embassy_hal_common::drop::OnDrop;
|
||||
use embassy_hal_common::into_ref;
|
||||
use embassy_hal_internal::drop::OnDrop;
|
||||
use embassy_hal_internal::into_ref;
|
||||
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
|
||||
use embassy_sync::mutex::Mutex;
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
use core::marker::PhantomData;
|
||||
use core::sync::atomic::{fence, Ordering};
|
||||
|
||||
use embassy_hal_common::drop::OnDrop;
|
||||
use embassy_hal_common::{into_ref, PeripheralRef};
|
||||
use embassy_hal_internal::drop::OnDrop;
|
||||
use embassy_hal_internal::{into_ref, PeripheralRef};
|
||||
use stm32_metapac::FLASH_BASE;
|
||||
|
||||
use super::{
|
||||
|
@ -14,7 +14,7 @@ use crate::pac;
|
||||
mod alt_regions {
|
||||
use core::marker::PhantomData;
|
||||
|
||||
use embassy_hal_common::PeripheralRef;
|
||||
use embassy_hal_internal::PeripheralRef;
|
||||
use stm32_metapac::FLASH_SIZE;
|
||||
|
||||
use crate::_generated::flash_regions::{OTPRegion, BANK1_REGION1, BANK1_REGION2, BANK1_REGION3, OTP_REGION};
|
||||
|
@ -1,6 +1,6 @@
|
||||
use core::marker::PhantomData;
|
||||
|
||||
use embassy_hal_common::into_ref;
|
||||
use embassy_hal_internal::into_ref;
|
||||
|
||||
use crate::gpio::sealed::AFType;
|
||||
use crate::gpio::{Pull, Speed};
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user