Removed global static channel_out and moved to interrupt state. TODO: make feature switch for slave specific stuff
This commit is contained in:
parent
541b479b05
commit
8399d96e24
@ -10,13 +10,14 @@ use embassy_hal_internal::drop::OnDrop;
|
|||||||
use embassy_hal_internal::{into_ref, PeripheralRef};
|
use embassy_hal_internal::{into_ref, PeripheralRef};
|
||||||
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
|
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
|
||||||
use embassy_sync::blocking_mutex::Mutex;
|
use embassy_sync::blocking_mutex::Mutex;
|
||||||
|
use embassy_sync::channel::Channel;
|
||||||
use embassy_sync::waitqueue::AtomicWaker;
|
use embassy_sync::waitqueue::AtomicWaker;
|
||||||
#[cfg(feature = "time")]
|
#[cfg(feature = "time")]
|
||||||
use embassy_time::{Duration, Instant};
|
use embassy_time::{Duration, Instant};
|
||||||
#[cfg(feature = "time")]
|
#[cfg(feature = "time")]
|
||||||
use futures::task::Poll;
|
use futures::task::Poll;
|
||||||
|
|
||||||
use super::v2slave::SlaveState;
|
use super::v2slave::{SlaveState, SlaveTransaction, SLAVE_QUEUE_DEPTH};
|
||||||
use crate::dma::NoDma;
|
use crate::dma::NoDma;
|
||||||
#[cfg(feature = "time")]
|
#[cfg(feature = "time")]
|
||||||
use crate::dma::Transfer;
|
use crate::dma::Transfer;
|
||||||
@ -106,6 +107,7 @@ impl Default for Config {
|
|||||||
|
|
||||||
pub struct State {
|
pub struct State {
|
||||||
pub(crate) waker: AtomicWaker,
|
pub(crate) waker: AtomicWaker,
|
||||||
|
pub(crate) channel_out: Channel<CriticalSectionRawMutex, SlaveTransaction, SLAVE_QUEUE_DEPTH>,
|
||||||
pub(crate) mutex: Mutex<CriticalSectionRawMutex, RefCell<SlaveState>>,
|
pub(crate) mutex: Mutex<CriticalSectionRawMutex, RefCell<SlaveState>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -113,6 +115,7 @@ impl State {
|
|||||||
pub(crate) const fn new() -> Self {
|
pub(crate) const fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
waker: AtomicWaker::new(),
|
waker: AtomicWaker::new(),
|
||||||
|
channel_out: Channel::new(),
|
||||||
mutex: Mutex::new(RefCell::new(SlaveState::new())),
|
mutex: Mutex::new(RefCell::new(SlaveState::new())),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,17 +1,15 @@
|
|||||||
use core::result::Result;
|
use core::result::Result;
|
||||||
|
|
||||||
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
|
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
|
||||||
use embassy_sync::channel::Channel;
|
use embassy_sync::channel::{Channel, Receiver};
|
||||||
use stm32_metapac::i2c;
|
use stm32_metapac::i2c;
|
||||||
|
|
||||||
use super::{AddressIndex, I2c, Instance};
|
use super::{AddressIndex, I2c, Instance};
|
||||||
use crate::i2c::{Dir, Error};
|
use crate::i2c::{Dir, Error};
|
||||||
// Declare a CHANNEL for all other tasks to communicate with this driver
|
|
||||||
static CHANNEL_OUT: Channel<CriticalSectionRawMutex, SlaveTransaction, SLAVE_QUEUE_DEPTH> = Channel::new();
|
|
||||||
|
|
||||||
pub type I2cBuffer = [u8; SLAVE_BUFFER_SIZE];
|
pub type I2cBuffer = [u8; SLAVE_BUFFER_SIZE];
|
||||||
pub const SLAVE_BUFFER_SIZE: usize = 64;
|
pub const SLAVE_BUFFER_SIZE: usize = 64;
|
||||||
const SLAVE_QUEUE_DEPTH: usize = 5;
|
pub const SLAVE_QUEUE_DEPTH: usize = 5;
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
|
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
|
||||||
#[repr(usize)]
|
#[repr(usize)]
|
||||||
@ -324,6 +322,13 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
pub fn slave_prepare_write(&self) -> Result<(), Error> {
|
||||||
|
T::state().mutex.lock(|f| {
|
||||||
|
let mut state_m = f.borrow_mut();
|
||||||
|
state_m.prepare_write();
|
||||||
|
Ok(())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
pub fn slave_reset(&self) {
|
pub fn slave_reset(&self) {
|
||||||
T::state().mutex.lock(|f| {
|
T::state().mutex.lock(|f| {
|
||||||
@ -338,23 +343,13 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
|
|||||||
state_m.error_count_reset()
|
state_m.error_count_reset()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
pub fn slave_prepare_write(&self) {
|
|
||||||
T::state().mutex.lock(|f| {
|
|
||||||
let mut state_m = f.borrow_mut();
|
|
||||||
state_m.prepare_write();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/// wait until a slave transaction is finished, and return tuple address, direction, data size and error
|
/// Get a copy of the receiver for the channel_out. User code can await on this receiver
|
||||||
pub async fn slave_transaction(&self) -> SlaveTransaction {
|
pub fn slave_transaction_receiver(
|
||||||
let result = CHANNEL_OUT.receive().await;
|
&self,
|
||||||
T::state().mutex.lock(|f| {
|
) -> Receiver<'static, CriticalSectionRawMutex, SlaveTransaction, SLAVE_QUEUE_DEPTH> {
|
||||||
let mut state_m = f.borrow_mut();
|
T::state().channel_out.receiver()
|
||||||
state_m.prepare_write();
|
|
||||||
});
|
|
||||||
result
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn slave_interupt_handler(state_m: &mut SlaveState, regs: &i2c::I2c) {
|
pub(crate) fn slave_interupt_handler(state_m: &mut SlaveState, regs: &i2c::I2c) {
|
||||||
// ============================================ slave interrupt state_m machine
|
// ============================================ slave interrupt state_m machine
|
||||||
let isr = regs.isr().read();
|
let isr = regs.isr().read();
|
||||||
@ -402,7 +397,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
|
|||||||
let transaction = state_m.take_transaction();
|
let transaction = state_m.take_transaction();
|
||||||
match transaction {
|
match transaction {
|
||||||
Some(t) => {
|
Some(t) => {
|
||||||
if let Err(_) = CHANNEL_OUT.try_send(t) {
|
if let Err(_) = T::state().channel_out.try_send(t) {
|
||||||
state_m.error_count += 1;
|
state_m.error_count += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,43 +0,0 @@
|
|||||||
[default.probe]
|
|
||||||
protocol = "Swd"
|
|
||||||
# USB vendor ID
|
|
||||||
# usb_vid = "6790"
|
|
||||||
# USB product ID
|
|
||||||
# usb_pid = "29987"
|
|
||||||
|
|
||||||
[default.flashing]
|
|
||||||
enabled = true
|
|
||||||
|
|
||||||
[default.reset]
|
|
||||||
# Whether or not the target should be reset.
|
|
||||||
# When flashing is enabled as well, the target will be reset after flashing.
|
|
||||||
enabled = true
|
|
||||||
# Whether or not the target should be halted after reset.
|
|
||||||
halt_afterwards = false
|
|
||||||
|
|
||||||
[default.general]
|
|
||||||
# The chip name of the chip to be debugged.
|
|
||||||
#chip = "STM32G030J6Mx"
|
|
||||||
chip = "STM32G070CBTx"
|
|
||||||
# A list of chip descriptions to be loaded during runtime.
|
|
||||||
chip_descriptions = []
|
|
||||||
# The default log level to be used.
|
|
||||||
log_level = "Warn"
|
|
||||||
|
|
||||||
[default.rtt]
|
|
||||||
enabled = false
|
|
||||||
# A list of channel associations to be displayed. If left empty, all channels are displayed.
|
|
||||||
channels = [
|
|
||||||
# { up = 0, down = 0, name = "name" }
|
|
||||||
]
|
|
||||||
# The duration in ms for which the logger should retry to attach to RTT.
|
|
||||||
timeout = 3000
|
|
||||||
# Whether timestamps in the RTTUI are enabled
|
|
||||||
show_timestamps = true
|
|
||||||
|
|
||||||
[default.gdb]
|
|
||||||
# Whether or not a GDB server should be opened after flashing.
|
|
||||||
# This is exclusive and cannot be used with RTT at the moment.
|
|
||||||
enabled = false
|
|
||||||
# The connection string in host:port format wher the GDB server will open a socket.
|
|
||||||
# gdb_connection_string
|
|
@ -123,6 +123,7 @@ async fn main(spawner: Spawner) {
|
|||||||
|
|
||||||
// start of the actual test
|
// start of the actual test
|
||||||
i2c.slave_start_listen().unwrap();
|
i2c.slave_start_listen().unwrap();
|
||||||
|
let receiver = i2c.slave_transaction_receiver();
|
||||||
loop {
|
loop {
|
||||||
counter += 1;
|
counter += 1;
|
||||||
writeln!(&mut writer, "Loop: {}\r", counter).unwrap();
|
writeln!(&mut writer, "Loop: {}\r", counter).unwrap();
|
||||||
@ -143,7 +144,7 @@ async fn main(spawner: Spawner) {
|
|||||||
|
|
||||||
writeln!(&mut writer, "Waiting for master activity\r").unwrap();
|
writeln!(&mut writer, "Waiting for master activity\r").unwrap();
|
||||||
|
|
||||||
let t = i2c.slave_transaction().await;
|
let t = receiver.receive().await;
|
||||||
let dir = t.dir();
|
let dir = t.dir();
|
||||||
tcount += 1;
|
tcount += 1;
|
||||||
// preparations for the next round
|
// preparations for the next round
|
||||||
|
@ -10,7 +10,7 @@ use core::fmt::{self, Write};
|
|||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
use embassy_stm32::dma::NoDma;
|
use embassy_stm32::dma::NoDma;
|
||||||
// use embassy_stm32::gpio::{Level, Output, Speed};
|
// use embassy_stm32::gpio::{Level, Output, Speed};
|
||||||
use embassy_stm32::i2c::{I2c, AddressIndex};
|
use embassy_stm32::i2c::{AddressIndex, I2c};
|
||||||
use embassy_stm32::time::Hertz;
|
use embassy_stm32::time::Hertz;
|
||||||
use embassy_stm32::usart::UartTx;
|
use embassy_stm32::usart::UartTx;
|
||||||
use embassy_stm32::{bind_interrupts, i2c, peripherals, usart};
|
use embassy_stm32::{bind_interrupts, i2c, peripherals, usart};
|
||||||
@ -83,6 +83,7 @@ async fn main(_spawner: Spawner) {
|
|||||||
|
|
||||||
// start of the actual test
|
// start of the actual test
|
||||||
i2c.slave_start_listen().unwrap();
|
i2c.slave_start_listen().unwrap();
|
||||||
|
let receiver = i2c.slave_transaction_receiver();
|
||||||
loop {
|
loop {
|
||||||
counter += 1;
|
counter += 1;
|
||||||
writeln!(&mut writer, "Loop: {}\r", counter).unwrap();
|
writeln!(&mut writer, "Loop: {}\r", counter).unwrap();
|
||||||
@ -94,7 +95,7 @@ async fn main(_spawner: Spawner) {
|
|||||||
|
|
||||||
writeln!(&mut writer, "Waiting for master activity\r").unwrap();
|
writeln!(&mut writer, "Waiting for master activity\r").unwrap();
|
||||||
|
|
||||||
let t = i2c.slave_transaction().await;
|
let t = receiver.receive().await;
|
||||||
writeln!(
|
writeln!(
|
||||||
&mut writer,
|
&mut writer,
|
||||||
"Address: x{:2x} dir: {:?} size: x{:2x}, Result:{:?}\r",
|
"Address: x{:2x} dir: {:?} size: x{:2x}, Result:{:?}\r",
|
||||||
|
Loading…
Reference in New Issue
Block a user