Fixing master read: first byte was flushed. Fixing set i2c_address_1.

This commit is contained in:
anton smeenk 2023-10-29 09:45:06 +01:00
parent a03407d08c
commit 9474f1576a
2 changed files with 20 additions and 20 deletions

View File

@ -3,8 +3,6 @@ use core::cmp;
#[cfg(feature = "time")]
use core::future::poll_fn;
use core::marker::PhantomData;
#[cfg(feature = "time")]
use core::task::Poll;
use embassy_embedded_hal::SetConfig;
#[cfg(feature = "time")]
@ -15,6 +13,8 @@ use embassy_sync::blocking_mutex::Mutex;
use embassy_sync::waitqueue::AtomicWaker;
#[cfg(feature = "time")]
use embassy_time::{Duration, Instant};
#[cfg(feature = "time")]
use futures::task::Poll;
use stm32_metapac::i2c::vals;
use crate::dma::NoDma;
@ -98,28 +98,26 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl
state_m.result = None;
if state_m.dir == Dir::READ {
// flush i2c tx register
regs.isr().write(|w| w.set_txe(true));
// Set the nbytes START and prepare to receive bytes into `buffer`.
// Set the actual number of bytes to transfer
// error case that n = 0 cannot be handled by i2c, we need to send at least 1 byte.
let (b, size) = match state_m.read_byte() {
Ok(b) => (b, state_m.get_size()),
_ => (0xFF, 1),
};
regs.cr2().modify(|w| {
// Set number of bytes to transfer: maximum as all incoming bytes will be ACK'ed
w.set_nbytes(state_m.get_size());
w.set_nbytes(size);
// during sending nbytes automatically send a ACK, stretch clock after last byte
w.set_reload(vals::Reload::COMPLETED);
});
regs.txdr().write(|w| w.set_txdata(b));
// restore sbc after a master_write_read transaction
T::regs().cr1().modify(|reg| {
reg.set_sbc(true);
});
// flush i2c tx register
regs.isr().write(|w| w.set_txe(true));
// fill rx data with the first byte
let b = match state_m.read_byte() {
Ok(b) => b,
Err(e) => {
state_m.result = Some(e);
0xFF
}
};
regs.txdr().write(|w| w.set_txdata(b));
} else {
// Set the nbytes to the maximum buffer size and wait for the bytes from the master
regs.cr2().modify(|w| {
@ -1088,16 +1086,18 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
}
pub fn set_address_1(&self, address7: u8) -> Result<(), Error> {
T::regs().oar1().modify(|reg| {
T::regs().oar1().write(|reg| {
reg.set_oa1en(false);
});
T::regs().oar1().modify(|reg| {
reg.set_oa1(address7 as u16);
let adress_u16 = address7 as u16;
T::regs().oar1().write(|reg| {
reg.set_oa1(adress_u16 << 1);
reg.set_oa1mode(vals::Addmode::BIT7);
reg.set_oa1en(true);
});
T::state().mutex.lock(|f| {
let mut state_m = f.borrow_mut();
state_m.address1 = address7 as u16;
state_m.address1 = adress_u16;
});
Ok(())
}

View File

@ -10,7 +10,7 @@ use core::fmt::{self, Write};
use embassy_executor::Spawner;
use embassy_stm32::dma::NoDma;
use embassy_stm32::gpio::{Level, Output, Speed};
use embassy_stm32::i2c::{Dir, Error, I2c};
use embassy_stm32::i2c::{Address2Mask, Dir, Error, I2c};
use embassy_stm32::time::Hertz;
use embassy_stm32::usart::UartTx;
use embassy_stm32::{bind_interrupts, i2c, peripherals, usart};