Compare commits
98 Commits
salty-upda
...
boot-nrf-s
Author | SHA1 | Date | |
---|---|---|---|
896690c415 | |||
c8eb128a56 | |||
22ee868f04 | |||
1c3cf347cb | |||
13c107e815 | |||
52a801fdb7 | |||
fc6e70caa5 | |||
f9d0daad80 | |||
97e919ea64 | |||
c7841a37fa | |||
589a16b255 | |||
4567b87482 | |||
12de90e13d | |||
871ed538b1 | |||
efd5dbe019 | |||
9d46ee0758 | |||
e5912972ec | |||
c8c8b89104 | |||
189b15c426 | |||
41c3c26beb | |||
7ec1ed4de3 | |||
6564c04531 | |||
f97ef61ef8 | |||
9ddf8b08e4 | |||
71584409d9 | |||
1ea87ec6e7 | |||
7d9a76da00 | |||
c995732b0e | |||
39c166ef9b | |||
5e76c8b41a | |||
f4b77c967f | |||
ca2e3759ad | |||
3e2e109437 | |||
6f21f0680e | |||
486b67e895 | |||
e45e3e76b5 | |||
fc724dd707 | |||
254d587385 | |||
08e9a4d84a | |||
e1f588f520 | |||
49534cd405 | |||
138318f611 | |||
c45418787c | |||
4deae51e65 | |||
c952ae0f49 | |||
4ed7747a98 | |||
227ace6c3c | |||
124478c5e9 | |||
59d2977c0a | |||
87c8d9df94 | |||
21fce1e195 | |||
2b497c1e57 | |||
3f0920c400 | |||
7044e53af4 | |||
88e77c733c | |||
2a542bc143 | |||
c0cfd68c0c | |||
80c9d04bbd | |||
9959c8c3e3 | |||
b857334f92 | |||
a2d4bab2f8 | |||
a5379e708c | |||
2a7a44477e | |||
f6bc96dfbd | |||
ccf602b333 | |||
3568e4a5ff | |||
858987263b | |||
b966f55883 | |||
ea1e1973eb | |||
560e728132 | |||
c17fee27bb | |||
a8d0da91dc | |||
e5e85ba02b | |||
77e372e842 | |||
a165d73eed | |||
df0f41c41c | |||
98481c20fe | |||
5ec2fbe3a2 | |||
33e8943e5b | |||
9f9f6e75bb | |||
cbc8ccc51e | |||
485765320a | |||
27d054aa68 | |||
e579095a90 | |||
a34abd849f | |||
138ed87b95 | |||
d81395fab3 | |||
ef692c5141 | |||
9cc5d8ac89 | |||
c1438fe87b | |||
e27e00f628 | |||
b60b3f4eb8 | |||
702d2a1a19 | |||
c2942f2727 | |||
6bf70e14fb | |||
2afec225e3 | |||
976a7ae22a | |||
d596a1091d |
4
ci.sh
4
ci.sh
@ -91,12 +91,12 @@ cargo batch \
|
|||||||
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f417zg,defmt,exti,time-driver-any,time \
|
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f417zg,defmt,exti,time-driver-any,time \
|
||||||
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f423zh,defmt,exti,time-driver-any,time \
|
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f423zh,defmt,exti,time-driver-any,time \
|
||||||
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f427zi,defmt,exti,time-driver-any,time \
|
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f427zi,defmt,exti,time-driver-any,time \
|
||||||
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f429zi,log,exti,time-driver-any,embedded-sdmmc,time \
|
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f429zi,log,exti,time-driver-any,time \
|
||||||
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f437zi,log,exti,time-driver-any,time \
|
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f437zi,log,exti,time-driver-any,time \
|
||||||
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f439zi,defmt,exti,time-driver-any,time \
|
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f439zi,defmt,exti,time-driver-any,time \
|
||||||
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f446ze,defmt,exti,time-driver-any,time \
|
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f446ze,defmt,exti,time-driver-any,time \
|
||||||
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f469zi,defmt,exti,time-driver-any,time \
|
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f469zi,defmt,exti,time-driver-any,time \
|
||||||
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f479zi,defmt,exti,time-driver-any,embedded-sdmmc,time \
|
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f479zi,defmt,exti,time-driver-any,time \
|
||||||
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f730i8,defmt,exti,time-driver-any,time \
|
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f730i8,defmt,exti,time-driver-any,time \
|
||||||
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32h753zi,defmt,exti,time-driver-any,time \
|
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32h753zi,defmt,exti,time-driver-any,time \
|
||||||
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32h735zg,defmt,exti,time-driver-any,time \
|
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32h735zg,defmt,exti,time-driver-any,time \
|
||||||
|
@ -4,6 +4,12 @@ name = "embassy-boot-nrf"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
description = "Bootloader lib for nRF chips"
|
description = "Bootloader lib for nRF chips"
|
||||||
license = "MIT OR Apache-2.0"
|
license = "MIT OR Apache-2.0"
|
||||||
|
repository = "https://github.com/embassy-rs/embassy"
|
||||||
|
categories = [
|
||||||
|
"embedded",
|
||||||
|
"no-std",
|
||||||
|
"asynchronous",
|
||||||
|
]
|
||||||
|
|
||||||
[package.metadata.embassy_docs]
|
[package.metadata.embassy_docs]
|
||||||
src_base = "https://github.com/embassy-rs/embassy/blob/embassy-boot-nrf-v$VERSION/embassy-boot/nrf/src/"
|
src_base = "https://github.com/embassy-rs/embassy/blob/embassy-boot-nrf-v$VERSION/embassy-boot/nrf/src/"
|
||||||
@ -25,7 +31,7 @@ embedded-storage = "0.3.1"
|
|||||||
embedded-storage-async = { version = "0.4.1" }
|
embedded-storage-async = { version = "0.4.1" }
|
||||||
cfg-if = "1.0.0"
|
cfg-if = "1.0.0"
|
||||||
|
|
||||||
nrf-softdevice-mbr = { version = "0.1.0", git = "https://github.com/embassy-rs/nrf-softdevice.git", branch = "master", optional = true }
|
nrf-softdevice-mbr = { version = "0.2.0", optional = true }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
defmt = [
|
defmt = [
|
||||||
|
@ -4,6 +4,12 @@ name = "embassy-boot-rp"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
description = "Bootloader lib for RP2040 chips"
|
description = "Bootloader lib for RP2040 chips"
|
||||||
license = "MIT OR Apache-2.0"
|
license = "MIT OR Apache-2.0"
|
||||||
|
repository = "https://github.com/embassy-rs/embassy"
|
||||||
|
categories = [
|
||||||
|
"embedded",
|
||||||
|
"no-std",
|
||||||
|
"asynchronous",
|
||||||
|
]
|
||||||
|
|
||||||
[package.metadata.embassy_docs]
|
[package.metadata.embassy_docs]
|
||||||
src_base = "https://github.com/embassy-rs/embassy/blob/embassy-boot-rp-v$VERSION/src/"
|
src_base = "https://github.com/embassy-rs/embassy/blob/embassy-boot-rp-v$VERSION/src/"
|
||||||
|
@ -4,6 +4,12 @@ name = "embassy-boot-stm32"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
description = "Bootloader lib for STM32 chips"
|
description = "Bootloader lib for STM32 chips"
|
||||||
license = "MIT OR Apache-2.0"
|
license = "MIT OR Apache-2.0"
|
||||||
|
repository = "https://github.com/embassy-rs/embassy"
|
||||||
|
categories = [
|
||||||
|
"embedded",
|
||||||
|
"no-std",
|
||||||
|
"asynchronous",
|
||||||
|
]
|
||||||
|
|
||||||
[package.metadata.embassy_docs]
|
[package.metadata.embassy_docs]
|
||||||
src_base = "https://github.com/embassy-rs/embassy/blob/embassy-boot-nrf-v$VERSION/embassy-boot/stm32/src/"
|
src_base = "https://github.com/embassy-rs/embassy/blob/embassy-boot-nrf-v$VERSION/embassy-boot/stm32/src/"
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#![no_std]
|
#![no_std]
|
||||||
#![doc = include_str!("../README.md")]
|
#![doc = include_str!("../README.md")]
|
||||||
|
#![warn(missing_docs)]
|
||||||
|
|
||||||
// must go first!
|
// must go first!
|
||||||
mod fmt;
|
mod fmt;
|
||||||
@ -15,6 +16,9 @@ use embassy_sync::blocking_mutex::Mutex;
|
|||||||
use embassy_sync::waitqueue::WakerRegistration;
|
use embassy_sync::waitqueue::WakerRegistration;
|
||||||
use embassy_sync::zerocopy_channel;
|
use embassy_sync::zerocopy_channel;
|
||||||
|
|
||||||
|
/// Channel state.
|
||||||
|
///
|
||||||
|
/// Holds a buffer of packets with size MTU, for both TX and RX.
|
||||||
pub struct State<const MTU: usize, const N_RX: usize, const N_TX: usize> {
|
pub struct State<const MTU: usize, const N_RX: usize, const N_TX: usize> {
|
||||||
rx: [PacketBuf<MTU>; N_RX],
|
rx: [PacketBuf<MTU>; N_RX],
|
||||||
tx: [PacketBuf<MTU>; N_TX],
|
tx: [PacketBuf<MTU>; N_TX],
|
||||||
@ -24,6 +28,7 @@ pub struct State<const MTU: usize, const N_RX: usize, const N_TX: usize> {
|
|||||||
impl<const MTU: usize, const N_RX: usize, const N_TX: usize> State<MTU, N_RX, N_TX> {
|
impl<const MTU: usize, const N_RX: usize, const N_TX: usize> State<MTU, N_RX, N_TX> {
|
||||||
const NEW_PACKET: PacketBuf<MTU> = PacketBuf::new();
|
const NEW_PACKET: PacketBuf<MTU> = PacketBuf::new();
|
||||||
|
|
||||||
|
/// Create a new channel state.
|
||||||
pub const fn new() -> Self {
|
pub const fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
rx: [Self::NEW_PACKET; N_RX],
|
rx: [Self::NEW_PACKET; N_RX],
|
||||||
@ -39,33 +44,45 @@ struct StateInner<'d, const MTU: usize> {
|
|||||||
shared: Mutex<NoopRawMutex, RefCell<Shared>>,
|
shared: Mutex<NoopRawMutex, RefCell<Shared>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// State of the LinkState
|
|
||||||
struct Shared {
|
struct Shared {
|
||||||
link_state: LinkState,
|
link_state: LinkState,
|
||||||
waker: WakerRegistration,
|
waker: WakerRegistration,
|
||||||
hardware_address: driver::HardwareAddress,
|
hardware_address: driver::HardwareAddress,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Channel runner.
|
||||||
|
///
|
||||||
|
/// Holds the shared state and the lower end of channels for inbound and outbound packets.
|
||||||
pub struct Runner<'d, const MTU: usize> {
|
pub struct Runner<'d, const MTU: usize> {
|
||||||
tx_chan: zerocopy_channel::Receiver<'d, NoopRawMutex, PacketBuf<MTU>>,
|
tx_chan: zerocopy_channel::Receiver<'d, NoopRawMutex, PacketBuf<MTU>>,
|
||||||
rx_chan: zerocopy_channel::Sender<'d, NoopRawMutex, PacketBuf<MTU>>,
|
rx_chan: zerocopy_channel::Sender<'d, NoopRawMutex, PacketBuf<MTU>>,
|
||||||
shared: &'d Mutex<NoopRawMutex, RefCell<Shared>>,
|
shared: &'d Mutex<NoopRawMutex, RefCell<Shared>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// State runner.
|
||||||
|
///
|
||||||
|
/// Holds the shared state of the channel such as link state.
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub struct StateRunner<'d> {
|
pub struct StateRunner<'d> {
|
||||||
shared: &'d Mutex<NoopRawMutex, RefCell<Shared>>,
|
shared: &'d Mutex<NoopRawMutex, RefCell<Shared>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// RX runner.
|
||||||
|
///
|
||||||
|
/// Holds the lower end of the channel for passing inbound packets up the stack.
|
||||||
pub struct RxRunner<'d, const MTU: usize> {
|
pub struct RxRunner<'d, const MTU: usize> {
|
||||||
rx_chan: zerocopy_channel::Sender<'d, NoopRawMutex, PacketBuf<MTU>>,
|
rx_chan: zerocopy_channel::Sender<'d, NoopRawMutex, PacketBuf<MTU>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// TX runner.
|
||||||
|
///
|
||||||
|
/// Holds the lower end of the channel for passing outbound packets down the stack.
|
||||||
pub struct TxRunner<'d, const MTU: usize> {
|
pub struct TxRunner<'d, const MTU: usize> {
|
||||||
tx_chan: zerocopy_channel::Receiver<'d, NoopRawMutex, PacketBuf<MTU>>,
|
tx_chan: zerocopy_channel::Receiver<'d, NoopRawMutex, PacketBuf<MTU>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, const MTU: usize> Runner<'d, MTU> {
|
impl<'d, const MTU: usize> Runner<'d, MTU> {
|
||||||
|
/// Split the runner into separate runners for controlling state, rx and tx.
|
||||||
pub fn split(self) -> (StateRunner<'d>, RxRunner<'d, MTU>, TxRunner<'d, MTU>) {
|
pub fn split(self) -> (StateRunner<'d>, RxRunner<'d, MTU>, TxRunner<'d, MTU>) {
|
||||||
(
|
(
|
||||||
StateRunner { shared: self.shared },
|
StateRunner { shared: self.shared },
|
||||||
@ -74,6 +91,7 @@ impl<'d, const MTU: usize> Runner<'d, MTU> {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Split the runner into separate runners for controlling state, rx and tx borrowing the underlying state.
|
||||||
pub fn borrow_split(&mut self) -> (StateRunner<'_>, RxRunner<'_, MTU>, TxRunner<'_, MTU>) {
|
pub fn borrow_split(&mut self) -> (StateRunner<'_>, RxRunner<'_, MTU>, TxRunner<'_, MTU>) {
|
||||||
(
|
(
|
||||||
StateRunner { shared: self.shared },
|
StateRunner { shared: self.shared },
|
||||||
@ -86,10 +104,12 @@ impl<'d, const MTU: usize> Runner<'d, MTU> {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create a state runner sharing the state channel.
|
||||||
pub fn state_runner(&self) -> StateRunner<'d> {
|
pub fn state_runner(&self) -> StateRunner<'d> {
|
||||||
StateRunner { shared: self.shared }
|
StateRunner { shared: self.shared }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set the link state.
|
||||||
pub fn set_link_state(&mut self, state: LinkState) {
|
pub fn set_link_state(&mut self, state: LinkState) {
|
||||||
self.shared.lock(|s| {
|
self.shared.lock(|s| {
|
||||||
let s = &mut *s.borrow_mut();
|
let s = &mut *s.borrow_mut();
|
||||||
@ -98,6 +118,7 @@ impl<'d, const MTU: usize> Runner<'d, MTU> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set the hardware address.
|
||||||
pub fn set_hardware_address(&mut self, address: driver::HardwareAddress) {
|
pub fn set_hardware_address(&mut self, address: driver::HardwareAddress) {
|
||||||
self.shared.lock(|s| {
|
self.shared.lock(|s| {
|
||||||
let s = &mut *s.borrow_mut();
|
let s = &mut *s.borrow_mut();
|
||||||
@ -106,16 +127,19 @@ impl<'d, const MTU: usize> Runner<'d, MTU> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Wait until there is space for more inbound packets and return a slice they can be copied into.
|
||||||
pub async fn rx_buf(&mut self) -> &mut [u8] {
|
pub async fn rx_buf(&mut self) -> &mut [u8] {
|
||||||
let p = self.rx_chan.send().await;
|
let p = self.rx_chan.send().await;
|
||||||
&mut p.buf
|
&mut p.buf
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Check if there is space for more inbound packets right now.
|
||||||
pub fn try_rx_buf(&mut self) -> Option<&mut [u8]> {
|
pub fn try_rx_buf(&mut self) -> Option<&mut [u8]> {
|
||||||
let p = self.rx_chan.try_send()?;
|
let p = self.rx_chan.try_send()?;
|
||||||
Some(&mut p.buf)
|
Some(&mut p.buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Polling the inbound channel if there is space for packets.
|
||||||
pub fn poll_rx_buf(&mut self, cx: &mut Context) -> Poll<&mut [u8]> {
|
pub fn poll_rx_buf(&mut self, cx: &mut Context) -> Poll<&mut [u8]> {
|
||||||
match self.rx_chan.poll_send(cx) {
|
match self.rx_chan.poll_send(cx) {
|
||||||
Poll::Ready(p) => Poll::Ready(&mut p.buf),
|
Poll::Ready(p) => Poll::Ready(&mut p.buf),
|
||||||
@ -123,22 +147,26 @@ impl<'d, const MTU: usize> Runner<'d, MTU> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Mark packet of len bytes as pushed to the inbound channel.
|
||||||
pub fn rx_done(&mut self, len: usize) {
|
pub fn rx_done(&mut self, len: usize) {
|
||||||
let p = self.rx_chan.try_send().unwrap();
|
let p = self.rx_chan.try_send().unwrap();
|
||||||
p.len = len;
|
p.len = len;
|
||||||
self.rx_chan.send_done();
|
self.rx_chan.send_done();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Wait until there is space for more outbound packets and return a slice they can be copied into.
|
||||||
pub async fn tx_buf(&mut self) -> &mut [u8] {
|
pub async fn tx_buf(&mut self) -> &mut [u8] {
|
||||||
let p = self.tx_chan.receive().await;
|
let p = self.tx_chan.receive().await;
|
||||||
&mut p.buf[..p.len]
|
&mut p.buf[..p.len]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Check if there is space for more outbound packets right now.
|
||||||
pub fn try_tx_buf(&mut self) -> Option<&mut [u8]> {
|
pub fn try_tx_buf(&mut self) -> Option<&mut [u8]> {
|
||||||
let p = self.tx_chan.try_receive()?;
|
let p = self.tx_chan.try_receive()?;
|
||||||
Some(&mut p.buf[..p.len])
|
Some(&mut p.buf[..p.len])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Polling the outbound channel if there is space for packets.
|
||||||
pub fn poll_tx_buf(&mut self, cx: &mut Context) -> Poll<&mut [u8]> {
|
pub fn poll_tx_buf(&mut self, cx: &mut Context) -> Poll<&mut [u8]> {
|
||||||
match self.tx_chan.poll_receive(cx) {
|
match self.tx_chan.poll_receive(cx) {
|
||||||
Poll::Ready(p) => Poll::Ready(&mut p.buf[..p.len]),
|
Poll::Ready(p) => Poll::Ready(&mut p.buf[..p.len]),
|
||||||
@ -146,12 +174,14 @@ impl<'d, const MTU: usize> Runner<'d, MTU> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Mark outbound packet as copied.
|
||||||
pub fn tx_done(&mut self) {
|
pub fn tx_done(&mut self) {
|
||||||
self.tx_chan.receive_done();
|
self.tx_chan.receive_done();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d> StateRunner<'d> {
|
impl<'d> StateRunner<'d> {
|
||||||
|
/// Set link state.
|
||||||
pub fn set_link_state(&self, state: LinkState) {
|
pub fn set_link_state(&self, state: LinkState) {
|
||||||
self.shared.lock(|s| {
|
self.shared.lock(|s| {
|
||||||
let s = &mut *s.borrow_mut();
|
let s = &mut *s.borrow_mut();
|
||||||
@ -160,6 +190,7 @@ impl<'d> StateRunner<'d> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set the hardware address.
|
||||||
pub fn set_hardware_address(&self, address: driver::HardwareAddress) {
|
pub fn set_hardware_address(&self, address: driver::HardwareAddress) {
|
||||||
self.shared.lock(|s| {
|
self.shared.lock(|s| {
|
||||||
let s = &mut *s.borrow_mut();
|
let s = &mut *s.borrow_mut();
|
||||||
@ -170,16 +201,19 @@ impl<'d> StateRunner<'d> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, const MTU: usize> RxRunner<'d, MTU> {
|
impl<'d, const MTU: usize> RxRunner<'d, MTU> {
|
||||||
|
/// Wait until there is space for more inbound packets and return a slice they can be copied into.
|
||||||
pub async fn rx_buf(&mut self) -> &mut [u8] {
|
pub async fn rx_buf(&mut self) -> &mut [u8] {
|
||||||
let p = self.rx_chan.send().await;
|
let p = self.rx_chan.send().await;
|
||||||
&mut p.buf
|
&mut p.buf
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Check if there is space for more inbound packets right now.
|
||||||
pub fn try_rx_buf(&mut self) -> Option<&mut [u8]> {
|
pub fn try_rx_buf(&mut self) -> Option<&mut [u8]> {
|
||||||
let p = self.rx_chan.try_send()?;
|
let p = self.rx_chan.try_send()?;
|
||||||
Some(&mut p.buf)
|
Some(&mut p.buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Polling the inbound channel if there is space for packets.
|
||||||
pub fn poll_rx_buf(&mut self, cx: &mut Context) -> Poll<&mut [u8]> {
|
pub fn poll_rx_buf(&mut self, cx: &mut Context) -> Poll<&mut [u8]> {
|
||||||
match self.rx_chan.poll_send(cx) {
|
match self.rx_chan.poll_send(cx) {
|
||||||
Poll::Ready(p) => Poll::Ready(&mut p.buf),
|
Poll::Ready(p) => Poll::Ready(&mut p.buf),
|
||||||
@ -187,6 +221,7 @@ impl<'d, const MTU: usize> RxRunner<'d, MTU> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Mark packet of len bytes as pushed to the inbound channel.
|
||||||
pub fn rx_done(&mut self, len: usize) {
|
pub fn rx_done(&mut self, len: usize) {
|
||||||
let p = self.rx_chan.try_send().unwrap();
|
let p = self.rx_chan.try_send().unwrap();
|
||||||
p.len = len;
|
p.len = len;
|
||||||
@ -195,16 +230,19 @@ impl<'d, const MTU: usize> RxRunner<'d, MTU> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, const MTU: usize> TxRunner<'d, MTU> {
|
impl<'d, const MTU: usize> TxRunner<'d, MTU> {
|
||||||
|
/// Wait until there is space for more outbound packets and return a slice they can be copied into.
|
||||||
pub async fn tx_buf(&mut self) -> &mut [u8] {
|
pub async fn tx_buf(&mut self) -> &mut [u8] {
|
||||||
let p = self.tx_chan.receive().await;
|
let p = self.tx_chan.receive().await;
|
||||||
&mut p.buf[..p.len]
|
&mut p.buf[..p.len]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Check if there is space for more outbound packets right now.
|
||||||
pub fn try_tx_buf(&mut self) -> Option<&mut [u8]> {
|
pub fn try_tx_buf(&mut self) -> Option<&mut [u8]> {
|
||||||
let p = self.tx_chan.try_receive()?;
|
let p = self.tx_chan.try_receive()?;
|
||||||
Some(&mut p.buf[..p.len])
|
Some(&mut p.buf[..p.len])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Polling the outbound channel if there is space for packets.
|
||||||
pub fn poll_tx_buf(&mut self, cx: &mut Context) -> Poll<&mut [u8]> {
|
pub fn poll_tx_buf(&mut self, cx: &mut Context) -> Poll<&mut [u8]> {
|
||||||
match self.tx_chan.poll_receive(cx) {
|
match self.tx_chan.poll_receive(cx) {
|
||||||
Poll::Ready(p) => Poll::Ready(&mut p.buf[..p.len]),
|
Poll::Ready(p) => Poll::Ready(&mut p.buf[..p.len]),
|
||||||
@ -212,11 +250,18 @@ impl<'d, const MTU: usize> TxRunner<'d, MTU> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Mark outbound packet as copied.
|
||||||
pub fn tx_done(&mut self) {
|
pub fn tx_done(&mut self) {
|
||||||
self.tx_chan.receive_done();
|
self.tx_chan.receive_done();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create a channel.
|
||||||
|
///
|
||||||
|
/// Returns a pair of handles for interfacing with the peripheral and the networking stack.
|
||||||
|
///
|
||||||
|
/// The runner is interfacing with the peripheral at the lower part of the stack.
|
||||||
|
/// The device is interfacing with the networking stack on the layer above.
|
||||||
pub fn new<'d, const MTU: usize, const N_RX: usize, const N_TX: usize>(
|
pub fn new<'d, const MTU: usize, const N_RX: usize, const N_TX: usize>(
|
||||||
state: &'d mut State<MTU, N_RX, N_TX>,
|
state: &'d mut State<MTU, N_RX, N_TX>,
|
||||||
hardware_address: driver::HardwareAddress,
|
hardware_address: driver::HardwareAddress,
|
||||||
@ -257,17 +302,22 @@ pub fn new<'d, const MTU: usize, const N_RX: usize, const N_TX: usize>(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Represents a packet of size MTU.
|
||||||
pub struct PacketBuf<const MTU: usize> {
|
pub struct PacketBuf<const MTU: usize> {
|
||||||
len: usize,
|
len: usize,
|
||||||
buf: [u8; MTU],
|
buf: [u8; MTU],
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<const MTU: usize> PacketBuf<MTU> {
|
impl<const MTU: usize> PacketBuf<MTU> {
|
||||||
|
/// Create a new packet buffer.
|
||||||
pub const fn new() -> Self {
|
pub const fn new() -> Self {
|
||||||
Self { len: 0, buf: [0; MTU] }
|
Self { len: 0, buf: [0; MTU] }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Channel device.
|
||||||
|
///
|
||||||
|
/// Holds the shared state and upper end of channels for inbound and outbound packets.
|
||||||
pub struct Device<'d, const MTU: usize> {
|
pub struct Device<'d, const MTU: usize> {
|
||||||
rx: zerocopy_channel::Receiver<'d, NoopRawMutex, PacketBuf<MTU>>,
|
rx: zerocopy_channel::Receiver<'d, NoopRawMutex, PacketBuf<MTU>>,
|
||||||
tx: zerocopy_channel::Sender<'d, NoopRawMutex, PacketBuf<MTU>>,
|
tx: zerocopy_channel::Sender<'d, NoopRawMutex, PacketBuf<MTU>>,
|
||||||
@ -314,6 +364,9 @@ impl<'d, const MTU: usize> embassy_net_driver::Driver for Device<'d, MTU> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A rx token.
|
||||||
|
///
|
||||||
|
/// Holds inbound receive channel and interfaces with embassy-net-driver.
|
||||||
pub struct RxToken<'a, const MTU: usize> {
|
pub struct RxToken<'a, const MTU: usize> {
|
||||||
rx: zerocopy_channel::Receiver<'a, NoopRawMutex, PacketBuf<MTU>>,
|
rx: zerocopy_channel::Receiver<'a, NoopRawMutex, PacketBuf<MTU>>,
|
||||||
}
|
}
|
||||||
@ -331,6 +384,9 @@ impl<'a, const MTU: usize> embassy_net_driver::RxToken for RxToken<'a, MTU> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A tx token.
|
||||||
|
///
|
||||||
|
/// Holds outbound transmit channel and interfaces with embassy-net-driver.
|
||||||
pub struct TxToken<'a, const MTU: usize> {
|
pub struct TxToken<'a, const MTU: usize> {
|
||||||
tx: zerocopy_channel::Sender<'a, NoopRawMutex, PacketBuf<MTU>>,
|
tx: zerocopy_channel::Sender<'a, NoopRawMutex, PacketBuf<MTU>>,
|
||||||
}
|
}
|
||||||
|
@ -56,7 +56,6 @@ cortex-m = "0.7.6"
|
|||||||
futures = { version = "0.3.17", default-features = false, features = ["async-await"] }
|
futures = { version = "0.3.17", default-features = false, features = ["async-await"] }
|
||||||
rand_core = "0.6.3"
|
rand_core = "0.6.3"
|
||||||
sdio-host = "0.5.0"
|
sdio-host = "0.5.0"
|
||||||
embedded-sdmmc = { git = "https://github.com/embassy-rs/embedded-sdmmc-rs", rev = "a4f293d3a6f72158385f79c98634cb8a14d0d2fc", optional = true }
|
|
||||||
critical-section = "1.1"
|
critical-section = "1.1"
|
||||||
stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-2234f380f51d16d0398b8e547088b33ea623cc7c" }
|
stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-2234f380f51d16d0398b8e547088b33ea623cc7c" }
|
||||||
vcell = "0.1.3"
|
vcell = "0.1.3"
|
||||||
|
@ -130,7 +130,7 @@ impl RtcTimeProvider {
|
|||||||
let weekday = day_of_week_from_u8(dr.wdu()).map_err(RtcError::InvalidDateTime)?;
|
let weekday = day_of_week_from_u8(dr.wdu()).map_err(RtcError::InvalidDateTime)?;
|
||||||
let day = bcd2_to_byte((dr.dt(), dr.du()));
|
let day = bcd2_to_byte((dr.dt(), dr.du()));
|
||||||
let month = bcd2_to_byte((dr.mt() as u8, dr.mu()));
|
let month = bcd2_to_byte((dr.mt() as u8, dr.mu()));
|
||||||
let year = bcd2_to_byte((dr.yt(), dr.yu())) as u16 + 1970_u16;
|
let year = bcd2_to_byte((dr.yt(), dr.yu())) as u16 + 2000_u16;
|
||||||
|
|
||||||
DateTime::from(year, month, day, weekday, hour, minute, second).map_err(RtcError::InvalidDateTime)
|
DateTime::from(year, month, day, weekday, hour, minute, second).map_err(RtcError::InvalidDateTime)
|
||||||
})
|
})
|
||||||
@ -261,7 +261,7 @@ impl Rtc {
|
|||||||
let (dt, du) = byte_to_bcd2(t.day() as u8);
|
let (dt, du) = byte_to_bcd2(t.day() as u8);
|
||||||
let (mt, mu) = byte_to_bcd2(t.month() as u8);
|
let (mt, mu) = byte_to_bcd2(t.month() as u8);
|
||||||
let yr = t.year() as u16;
|
let yr = t.year() as u16;
|
||||||
let yr_offset = (yr - 1970_u16) as u8;
|
let yr_offset = (yr - 2000_u16) as u8;
|
||||||
let (yt, yu) = byte_to_bcd2(yr_offset);
|
let (yt, yu) = byte_to_bcd2(yr_offset);
|
||||||
|
|
||||||
use crate::pac::rtc::vals::Ampm;
|
use crate::pac::rtc::vals::Ampm;
|
||||||
|
@ -1538,53 +1538,3 @@ foreach_peripheral!(
|
|||||||
impl Instance for peripherals::$inst {}
|
impl Instance for peripherals::$inst {}
|
||||||
};
|
};
|
||||||
);
|
);
|
||||||
|
|
||||||
#[cfg(feature = "embedded-sdmmc")]
|
|
||||||
mod sdmmc_rs {
|
|
||||||
use embedded_sdmmc::{Block, BlockCount, BlockDevice, BlockIdx};
|
|
||||||
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
impl<'d, T: Instance, Dma: SdmmcDma<T>> BlockDevice for Sdmmc<'d, T, Dma> {
|
|
||||||
type Error = Error;
|
|
||||||
|
|
||||||
async fn read(
|
|
||||||
&mut self,
|
|
||||||
blocks: &mut [Block],
|
|
||||||
start_block_idx: BlockIdx,
|
|
||||||
_reason: &str,
|
|
||||||
) -> Result<(), Self::Error> {
|
|
||||||
let mut address = start_block_idx.0;
|
|
||||||
|
|
||||||
for block in blocks.iter_mut() {
|
|
||||||
let block: &mut [u8; 512] = &mut block.contents;
|
|
||||||
|
|
||||||
// NOTE(unsafe) Block uses align(4)
|
|
||||||
let block = unsafe { &mut *(block as *mut _ as *mut DataBlock) };
|
|
||||||
self.read_block(address, block).await?;
|
|
||||||
address += 1;
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn write(&mut self, blocks: &[Block], start_block_idx: BlockIdx) -> Result<(), Self::Error> {
|
|
||||||
let mut address = start_block_idx.0;
|
|
||||||
|
|
||||||
for block in blocks.iter() {
|
|
||||||
let block: &[u8; 512] = &block.contents;
|
|
||||||
|
|
||||||
// NOTE(unsafe) DataBlock uses align 4
|
|
||||||
let block = unsafe { &*(block as *const _ as *const DataBlock) };
|
|
||||||
self.write_block(address, block).await?;
|
|
||||||
address += 1;
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn num_blocks(&self) -> Result<BlockCount, Self::Error> {
|
|
||||||
let card = self.card()?;
|
|
||||||
let count = card.csd.block_count();
|
|
||||||
Ok(BlockCount(count))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -111,6 +111,20 @@ where
|
|||||||
poll_fn(move |cx| self.poll_wait(cx))
|
poll_fn(move |cx| self.poll_wait(cx))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// non-blocking method to try and take the signal value.
|
||||||
|
pub fn try_take(&self) -> Option<T> {
|
||||||
|
self.state.lock(|cell| {
|
||||||
|
let state = cell.replace(State::None);
|
||||||
|
match state {
|
||||||
|
State::Signaled(res) => Some(res),
|
||||||
|
state => {
|
||||||
|
cell.set(state);
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/// non-blocking method to check whether this signal has been signaled.
|
/// non-blocking method to check whether this signal has been signaled.
|
||||||
pub fn signaled(&self) -> bool {
|
pub fn signaled(&self) -> bool {
|
||||||
self.state.lock(|cell| {
|
self.state.lock(|cell| {
|
||||||
|
@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
# Change stm32f429zi to your chip name, if necessary.
|
# Change stm32f429zi to your chip name, if necessary.
|
||||||
embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "stm32f429zi", "unstable-pac", "memory-x", "time-driver-any", "exti", "embedded-sdmmc", "chrono"] }
|
embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "stm32f429zi", "unstable-pac", "memory-x", "time-driver-any", "exti", "chrono"] }
|
||||||
embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] }
|
embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] }
|
||||||
embassy-executor = { version = "0.4.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] }
|
embassy-executor = { version = "0.4.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] }
|
||||||
embassy-time = { version = "0.2", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
|
embassy-time = { version = "0.2", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
|
||||||
|
Reference in New Issue
Block a user