Busy debugging the i2c slave

This commit is contained in:
anton smeenk 2023-10-21 12:11:32 +02:00
parent 007855423e
commit b1afd5141c
4 changed files with 146 additions and 131 deletions

View File

@ -25,7 +25,6 @@ pub enum Error {
BufferNotEmpty, BufferNotEmpty,
BufferNotFilled, BufferNotFilled,
BufferSize, BufferSize,
OkBufferTransferred, // not really an error, but signalling that the slave does nack the last byte
} }
pub(crate) mod sealed { pub(crate) mod sealed {

View File

@ -46,11 +46,10 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl
regs.icr().modify(|w| { regs.icr().modify(|w| {
w.set_berrcf(true); w.set_berrcf(true);
}); });
state_m.errors += 1; state_m.result = Some(Error::Bus);
state_m.result = Err(Error::Bus);
} else if isr.arlo() { } else if isr.arlo() {
regs.icr().write(|w| w.set_arlocf(true)); regs.icr().write(|w| w.set_arlocf(true));
state_m.result = Err(Error::Arbitration); state_m.result = Some(Error::Arbitration);
} else if isr.nackf() { } else if isr.nackf() {
regs.icr().write(|w| w.set_nackcf(true)); regs.icr().write(|w| w.set_nackcf(true));
// Make one extra loop to wait on the stop condition // Make one extra loop to wait on the stop condition
@ -58,16 +57,8 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl
// send the next byte to the master, or NACK in case of error, then end transaction // send the next byte to the master, or NACK in case of error, then end transaction
match state_m.read_byte() { match state_m.read_byte() {
Ok(b) => regs.txdr().write(|w| w.set_txdata(b)), Ok(b) => regs.txdr().write(|w| w.set_txdata(b)),
Err(Error::OkBufferTransferred) => {
state_m.result = Ok(());
// Send a NACK, set nbytes to clear tcr flag
regs.cr2().modify(|w| {
w.set_nack(true);
})
}
Err(e) => { Err(e) => {
state_m.result = Err(e); state_m.result = Some(e);
state_m.errors += 1;
// Send a NACK, set nbytes to clear tcr flag // Send a NACK, set nbytes to clear tcr flag
regs.cr2().modify(|w| { regs.cr2().modify(|w| {
w.set_nack(true); w.set_nack(true);
@ -80,8 +71,7 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl
match state_m.write_byte(b) { match state_m.write_byte(b) {
Ok(()) => (), Ok(()) => (),
Err(e) => { Err(e) => {
state_m.result = Err(e); state_m.result = Some(e);
state_m.errors += 1;
// Send a NACK, set nbytes to clear tcr flag // Send a NACK, set nbytes to clear tcr flag
regs.cr2().modify(|w| { regs.cr2().modify(|w| {
w.set_nack(true); w.set_nack(true);
@ -104,6 +94,8 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl
// handle the slave is addressed case, first step in the transaction // handle the slave is addressed case, first step in the transaction
state_m.current_address = isr.addcode(); state_m.current_address = isr.addcode();
state_m.dir = isr.dir(); state_m.dir = isr.dir();
state_m.result = None;
if state_m.dir == vals::Dir::READ { if state_m.dir == vals::Dir::READ {
// Set the nbytes START and prepare to receive bytes into `buffer`. // Set the nbytes START and prepare to receive bytes into `buffer`.
regs.cr2().modify(|w| { regs.cr2().modify(|w| {
@ -202,13 +194,12 @@ impl State {
} }
struct I2cStateMachine { struct I2cStateMachine {
buffers: [[I2cBuffer; 2]; 2], buffers: [[I2cBuffer; 2]; 2],
result: Result<(), Error>, result: Option<Error>,
slave_mode: bool, slave_mode: bool,
dir: vals::Dir,
address1: u16, address1: u16,
current_address: u8,
errors: u32,
ready: bool, ready: bool,
current_address: u8,
dir: vals::Dir,
} }
impl I2cStateMachine { impl I2cStateMachine {
pub(crate) const fn new() -> Self { pub(crate) const fn new() -> Self {
@ -218,12 +209,11 @@ impl I2cStateMachine {
[I2cBuffer::new(), I2cBuffer::new()], [I2cBuffer::new(), I2cBuffer::new()],
[I2cBuffer::new(), I2cBuffer::new()], [I2cBuffer::new(), I2cBuffer::new()],
], ],
result: Ok(()), result: None,
slave_mode: false, slave_mode: false,
dir: vals::Dir::READ,
address1: 0, address1: 0,
current_address: 0, current_address: 0,
errors: 0, dir: vals::Dir::READ,
ready: false, ready: false,
} }
} }
@ -290,7 +280,7 @@ impl I2cBuffer {
Ok(b) Ok(b)
} else { } else {
self.size = 0; // mark buffer empty self.size = 0; // mark buffer empty
Err(Error::OkBufferTransferred) // not really an error, but to signal slave should send NACK Err(Error::Overrun) // too many bytes asked
} }
} }
/// master write slave read scenario. Master can write until buffer full /// master write slave read scenario. Master can write until buffer full
@ -1080,31 +1070,25 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
Ok(()) Ok(())
} }
/// Prepare write data to master (master_read_slave_write) before transaction starts /// Prepare write data to master (master_read_slave_write) before transaction starts
/// Only possible if the buffer is empty, other wise error BufferNotEmpty error /// Will return buffersize error in case the incoming buffer is too big
pub fn slave_write_buffer(&mut self, buffer: &[u8], address_type: AddressType) -> Result<(), super::Error> { pub fn slave_write_buffer(&mut self, buffer: &[u8], address_type: AddressType) -> Result<(), super::Error> {
T::state().mutex.lock(|f| { T::state().mutex.lock(|f| {
let mut state_m = f.borrow_mut(); let mut state_m = f.borrow_mut();
let buf = &mut state_m.buffers[address_type as usize][vals::Dir::READ as usize]; let buf = &mut state_m.buffers[address_type as usize][vals::Dir::READ as usize];
if buf.size > 0 {
return Err(Error::BufferNotEmpty);
};
buf.from_buffer(buffer) buf.from_buffer(buffer)
}) })
} }
/// Read data from master (master_write_slave_read) after transaction is finished /// Read data from master (master_write_slave_read) after transaction is finished
/// Only possible if the buffer is not empty, other wise error BufferNotFilled error /// Will fail if the size if the incoming buffer is smaller than the received bytes
pub fn slave_read_buffer(&mut self, buffer: &mut [u8], address_type: AddressType) -> Result<(), super::Error> { pub fn slave_read_buffer(&mut self, buffer: &mut [u8], address_type: AddressType) -> Result<(), super::Error> {
T::state().mutex.lock(|f| { T::state().mutex.lock(|f| {
let mut state_m = f.borrow_mut(); let mut state_m = f.borrow_mut();
let buf = &mut state_m.buffers[address_type as usize][vals::Dir::WRITE as usize]; let buf = &mut state_m.buffers[address_type as usize][vals::Dir::WRITE as usize];
if buf.size == 0 {
return Err(Error::BufferEmpty);
};
buf.to_buffer(buffer) buf.to_buffer(buffer)
}) })
} }
/// wait until a slave transaction is finished, and return tuple address, direction and data size /// wait until a slave transaction is finished, and return tuple address, direction, data size and error
pub async fn slave_transaction(&mut self) -> Result<(u8, vals::Dir, u8), Error> { pub async fn slave_transaction(&mut self) -> (u8, vals::Dir, u8, Option<Error>) {
// async wait until addressed // async wait until addressed
poll_fn(|cx| { poll_fn(|cx| {
T::state().waker.register(cx.waker()); T::state().waker.register(cx.waker());
@ -1112,11 +1096,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
let mut state_m = f.borrow_mut(); let mut state_m = f.borrow_mut();
if state_m.ready { if state_m.ready {
state_m.ready = false; state_m.ready = false;
// if the dir bit is set it is a master write slave read operation return Poll::Ready((state_m.current_address, state_m.dir, state_m.get_size(), state_m.result));
match state_m.result {
Ok(()) => return Poll::Ready(Ok((state_m.current_address, state_m.dir, state_m.get_size()))),
Err(e) => return Poll::Ready(Err(e)),
}
} else { } else {
return Poll::Pending; return Poll::Pending;
} }

View File

@ -79,7 +79,7 @@ async fn main(_spawner: Spawner) {
let mut buf_64 = [0_u8; 64]; let mut buf_64 = [0_u8; 64];
let mut buf_65 = [0_u8; 65]; let mut buf_65 = [0_u8; 65];
writeln!(&mut writer, "Start of test").unwrap(); writeln!(&mut writer, "Start of test\n\r").unwrap();
for i in 0..buf_20.len() { for i in 0..buf_20.len() {
buf_20[i] = 0x20 + (i as u8) buf_20[i] = 0x20 + (i as u8)
@ -92,74 +92,80 @@ async fn main(_spawner: Spawner) {
} }
// test 1: slave address 0x61 should not be addressable // test 1: slave address 0x61 should not be addressable
match i2c.blocking_write(0x61, &buf_20) { match i2c.blocking_write(0x61, &buf_20) {
Ok(_) => writeln!(&mut writer, "Test 1 Error: would expect nack").unwrap(), Ok(_) => writeln!(&mut writer, "Test 1 failed: would expect nack\n\r").unwrap(),
Err(Error::Timeout) => writeln!(&mut writer, "Operation timed out").unwrap(), Err(Error::Timeout) => writeln!(&mut writer, "Operation timed out\n\r").unwrap(),
Err(err) => writeln!(&mut writer, "Test 1 OK: expected NACK error: {:?}", err).unwrap(), Err(err) => writeln!(&mut writer, "Test 1 passed: expected NACK error: {:?}", err).unwrap(),
}; };
// 0x41 good case master write slave read: master does send 20 bytes slave receives 20 bytes // 0x41 good case master write slave read: master does send 20 bytes slave receives 20 bytes
match i2c.blocking_write(0x41, &buf_20) { match i2c.blocking_write(0x41, &buf_20) {
Ok(_) => writeln!(&mut writer, "Test 0x41 Ok").unwrap(), Ok(_) => writeln!(&mut writer, "Test 0x41 passed\n\r").unwrap(),
Err(Error::Timeout) => writeln!(&mut writer, "Operation timed out").unwrap(), Err(Error::Timeout) => writeln!(&mut writer, "Operation timed out\n\r").unwrap(),
Err(err) => writeln!(&mut writer, "Test 0x41 Error: {:?}", err).unwrap(), Err(err) => writeln!(&mut writer, "Test 0x41 failed. Error: {:?}", err).unwrap(),
}; };
Timer::after(Duration::from_millis(10)).await;
// 0x42 edge case master write exact 64 bytes: must succeed on master and slave // 0x42 edge case master write exact 64 bytes: must succeed on master and slave
match i2c.blocking_write(0x42, &buf_64) { match i2c.blocking_write(0x42, &buf_64) {
Ok(_) => writeln!(&mut writer, "Test 0x42 Ok. Master write exact 64 bytes").unwrap(), Ok(_) => writeln!(&mut writer, "Test 0x42 passed. Master write exact 64 bytes\n\r").unwrap(),
Err(Error::Timeout) => writeln!(&mut writer, "Operation timed out").unwrap(), Err(Error::Timeout) => writeln!(&mut writer, "Operation timed out\n\r").unwrap(),
Err(err) => writeln!(&mut writer, "Test 0x42 error IncorrectFramesize: {:?}", err).unwrap(), Err(err) => writeln!(&mut writer, "Test 0x42 failed. Got error: {:?}\r\n", err).unwrap(),
}; };
// 0x43 edge case master write exact 65 bytes: 1 too manyu must fail on master and slave Timer::after(Duration::from_millis(10)).await;
match i2c.blocking_write(0x43, &buf_64) { // 0x43 edge case master write exact 65 bytes: 1 too many must fail on master and slave
Ok(_) => writeln!(&mut writer, "Test 0x42 Failed. Expected a Nack").unwrap(), match i2c.blocking_write(0x43, &buf_65) {
Err(Error::Timeout) => writeln!(&mut writer, "Operation timed out").unwrap(), Ok(_) => writeln!(&mut writer, "Test 0x43 Failed. Expected a Nack\n\r").unwrap(),
Err(Error::Timeout) => writeln!(&mut writer, "Operation timed out\n\r").unwrap(),
Err(err) => writeln!( Err(err) => writeln!(
&mut writer, &mut writer,
"Test 0x43 Ok: Got error NACK du to buffer of 1 too big {:?}", "Test 0x43 passed: Got error NACK du to buffer of 1 too big {:?}\r\n",
err err
) )
.unwrap(), .unwrap(),
}; };
Timer::after(Duration::from_millis(10)).await;
match i2c.blocking_read(0x48, &mut buf_20) { match i2c.blocking_read(0x48, &mut buf_20) {
Ok(_) => { Ok(_) => {
writeln!(&mut writer, "Test 0x48 Read expected to fail!").unwrap(); writeln!(&mut writer, "Test 0x48 failed. Read expected to fail!\n\r").unwrap();
} }
Err(Error::Timeout) => writeln!(&mut writer, "Operation timed out").unwrap(), Err(Error::Timeout) => writeln!(&mut writer, "Operation timed out\n\r").unwrap(),
Err(err) => writeln!( Err(err) => writeln!(
&mut writer, &mut writer,
"Test 0x48 Ok. First time, slave did not yet prepare a buffer Error: {:?}", "Test 0x48 Ok. First time, slave did not yet prepare a buffer Error: {:?}\r\n",
err err
) )
.unwrap(), .unwrap(),
}; };
Timer::after(Duration::from_millis(10)).await;
match i2c.blocking_read(0x49, &mut buf_20) { match i2c.blocking_read(0x49, &mut buf_20) {
Ok(_) => { Ok(_) => {
writeln!(&mut writer, "Test 0x49 Read Ok").unwrap(); writeln!(&mut writer, "Test 0x49 Read Ok\n\r").unwrap();
print_buffer(&mut writer, &buf_20); print_buffer(&mut writer, &buf_20);
} }
Err(Error::Timeout) => writeln!(&mut writer, "Operation timed out").unwrap(), Err(Error::Timeout) => writeln!(&mut writer, "Operation timed out\n\r").unwrap(),
Err(err) => writeln!(&mut writer, "Test 0x49 Error: {:?}", err).unwrap(), Err(err) => writeln!(&mut writer, "Test 0x49 Error: {:?}\r\n", err).unwrap(),
}; };
Timer::after(Duration::from_millis(10)).await;
match i2c.blocking_read(0x4A, &mut buf_64) { match i2c.blocking_read(0x4A, &mut buf_64) {
Ok(_) => { Ok(_) => {
writeln!(&mut writer, "Test 0x4A failed. Expected was a NACK error").unwrap(); writeln!(&mut writer, "Test 0x4A failed. Expected was a NACK error\n\r").unwrap();
print_buffer(&mut writer, &buf_64); print_buffer(&mut writer, &buf_64);
} }
Err(Error::Timeout) => writeln!(&mut writer, "Operation timed out").unwrap(), Err(Error::Timeout) => writeln!(&mut writer, "Operation timed out\n\r").unwrap(),
Err(err) => writeln!(&mut writer, "Test 0x4A Ok. Expected to fail. Error: {:?}", err).unwrap(), Err(err) => writeln!(&mut writer, "Test 0x4A passed. Expected to fail. Error: {:?}\r\n", err).unwrap(),
}; };
Timer::after(Duration::from_millis(10)).await;
match i2c.blocking_read(0x4B, &mut buf_64) { match i2c.blocking_read(0x4B, &mut buf_64) {
Ok(_) => { Ok(_) => {
writeln!(&mut writer, "Test 0x4B succeeded: edge case read exact the buffer size").unwrap(); writeln!(&mut writer, "Test 0x4B passed\n\r").unwrap();
print_buffer(&mut writer, &buf_64); print_buffer(&mut writer, &buf_64);
} }
Err(Error::Timeout) => writeln!(&mut writer, "Operation timed out").unwrap(), Err(Error::Timeout) => writeln!(&mut writer, "Operation timed out\n\r").unwrap(),
Err(err) => writeln!(&mut writer, "Test 0x4B failed. Error: {:?}", err).unwrap(), Err(err) => writeln!(&mut writer, "Test 0x4B failed. Error: {:?}\r\n", err).unwrap(),
}; };
/* /*
match i2c.blocking_write_read(0x44, &buf_20, &mut buf_64) { match i2c.blocking_write_read(0x44, &buf_20, &mut buf_64) {
Ok(_) => { Ok(_) => {
writeln!(&mut writer, "Test 0x44 Ok ").unwrap(); writeln!(&mut writer, "Test 0x44 Ok \n\r").unwrap();
writeln!( writeln!(
&mut writer, &mut writer,
"Uppercase input should be transformed to lowercase, A -> b " "Uppercase input should be transformed to lowercase, A -> b "
@ -169,31 +175,32 @@ async fn main(_spawner: Spawner) {
for i in 0..buf_rcv.len() { for i in 0..buf_rcv.len() {
writeln!(&mut writer, "{}", buf_rcv[i]).unwrap(); writeln!(&mut writer, "{}", buf_rcv[i]).unwrap();
} }
writeln!(&mut writer, "").unwrap() writeln!(&mut writer, "\n\r").unwrap()
} }
Err(Error::Timeout) => writeln!(&mut writer, "Operation timed out").unwrap(), Err(Error::Timeout) => writeln!(&mut writer, "Operation timed out\n\r").unwrap(),
Err(err) => writeln!(&mut writer, "Test 0x44 error: {:?}", err).unwrap(), Err(err) => writeln!(&mut writer, "Test 0x44 error: {:?}", err).unwrap(),
}; };
*/ */
Timer::after(Duration::from_millis(10)).await;
// 0x4F test end and slave will present results // 0x4F test end and slave will present results
let mut result: [u8; 2] = [0, 0]; let mut result: [u8; 2] = [0, 0];
match i2c.blocking_read(0x4F, &mut result) { match i2c.blocking_read(0x4F, &mut result) {
Ok(_) => writeln!( Ok(_) => writeln!(
&mut writer, &mut writer,
"Result of the whole test as reported by the slave count/errors: {}/{}\r", "Result of the whole test as reported by the slave count/errors: {}/{}\r\n",
result[0], result[1] result[0], result[1]
) )
.unwrap(), .unwrap(),
Err(Error::Timeout) => writeln!(&mut writer, "Operation timed out").unwrap(), Err(Error::Timeout) => writeln!(&mut writer, "Operation timed out\n\r").unwrap(),
Err(err) => writeln!(&mut writer, "Test 0x4F unexpected error: {:?}", err).unwrap(), Err(err) => writeln!(&mut writer, "Test 0x4F unexpected error: {:?}\r\n", err).unwrap(),
}; };
writeln!(&mut writer, "").unwrap(); writeln!(&mut writer, "\n\r").unwrap();
Timer::after(Duration::from_millis(10_000)).await; Timer::after(Duration::from_millis(10_000)).await;
} }
fn print_buffer(writer: &mut SerialWriter, buf: &[u8]) { fn print_buffer(writer: &mut SerialWriter, buf: &[u8]) {
for i in 0..buf.len() { for i in 0..buf.len() {
write!(writer, " {:2x} ", buf[i]).unwrap(); write!(writer, " {:2x} ", buf[i]).unwrap();
} }
writeln!(writer, "\n\r").unwrap() writeln!(writer, "\n\r\n\r").unwrap()
} }
} }

View File

@ -6,7 +6,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::i2c::I2c; use embassy_stm32::i2c::{Error, I2c};
use embassy_stm32::pac::i2c::vals; use embassy_stm32::pac::i2c::vals;
use embassy_stm32::time::Hertz; use embassy_stm32::time::Hertz;
use embassy_stm32::usart::UartTx; use embassy_stm32::usart::UartTx;
@ -95,7 +95,7 @@ async fn main(_spawner: Spawner) {
let mut dir = vals::Dir::READ; let mut dir = vals::Dir::READ;
let mut tcount = 0; let mut tcount = 0;
let mut counter = 0; let mut counter = 0;
let mut error = Ok((0, vals::Dir::READ, 0)); let mut result: Option<Error> = None;
// start of the actual test // start of the actual test
i2c.slave_start_listen().unwrap(); i2c.slave_start_listen().unwrap();
@ -112,81 +112,92 @@ async fn main(_spawner: Spawner) {
writeln!(&mut writer, "Waiting for master activity\r").unwrap(); writeln!(&mut writer, "Waiting for master activity\r").unwrap();
error = Ok((0, vals::Dir::WRITE, 0)); // clear write buffers for sure
match i2c.slave_transaction().await { _ = i2c.slave_read_buffer(&mut buf_64, i2c::AddressType::GenericAddress);
Ok((taddr, tdir, tsize)) => { _ = i2c.slave_read_buffer(&mut buf_64, i2c::AddressType::MainAddress);
address = taddr;
dir = tdir; let (address, dir, size, result) = i2c.slave_transaction().await;
writeln!( writeln!(
&mut writer, &mut writer,
"Test ok. Address: x{:2x} dir: {:?} size: x{:2x}\r", "Address: x{:2x} dir: {:?} size: x{:2x}, Result:{:?}\r",
taddr, tdir as u8, tsize address, dir as u8, size, result
) )
.unwrap(); .unwrap();
}
Err(e) => {
error = Err(e);
writeln!(&mut writer, "Test failed: Error: {:?}", e).unwrap()
}
}
tcount += 1; tcount += 1;
match address { match address {
0x41 => { 0x41 => {
// 0x41 good case master write slave read: master does send 20 bytes slave receives 20 bytes writeln!(
&mut writer,
"Start test 0x41. Master-write-slave-read 20 bytes. Should be ok\r\n"
)
.unwrap();
checkIsWrite!(writer, dir); checkIsWrite!(writer, dir);
_ = i2c.slave_read_buffer(&mut buf_20, i2c::AddressType::GenericAddress); _ = i2c.slave_read_buffer(&mut buf_20, i2c::AddressType::GenericAddress);
match error { match result {
Ok(_) => { None => {
writeln!(&mut writer, "Test 0x41 Ok. send 20 bytes").unwrap(); writeln!(&mut writer, "Test 0x41 passed\r\n").unwrap();
print_buffer(&mut writer, &buf_20); print_buffer(&mut writer, &buf_20);
} }
Err(err) => { Some(err) => {
errors += 1; errors += 1;
writeln!(&mut writer, "Test 0x41 failed. Error: {:?}\r", err).unwrap() writeln!(&mut writer, "Test 0x41 failed. Error: {:?}\r\n", err).unwrap()
} }
}; };
} }
0x42 => { 0x42 => {
// 0x42 good case edge case: exact 64 bytes master write slave read: writeln!(
&mut writer,
"Start test 0x42. Master-write-slave-read 64 bytes. Should be ok\r\n"
)
.unwrap();
checkIsWrite!(writer, dir); checkIsWrite!(writer, dir);
_ = i2c.slave_read_buffer(&mut buf_64, i2c::AddressType::GenericAddress); _ = i2c.slave_read_buffer(&mut buf_64, i2c::AddressType::GenericAddress);
match error { match result {
Ok(_) => { None => {
writeln!(&mut writer, "Test 0x42 Ok. send 64 bytes").unwrap(); writeln!(&mut writer, "Test 0x42 passed. send 64 bytes").unwrap();
print_buffer(&mut writer, &buf_64); print_buffer(&mut writer, &buf_64);
} }
Err(err) => { Some(err) => {
errors += 1; errors += 1;
writeln!(&mut writer, "Test 0x42 failed. Error: {:?}\r", err).unwrap() writeln!(&mut writer, "Test 0x42 failed. Error: {:?}\r", err).unwrap()
} }
}; };
} }
0x43 => { 0x43 => {
// 0x43 bad case master write slave read: master does send more than 64 bytes, slave does NACK writeln!(
&mut writer,
"Start test 0x43. Master-write-slave-read 65 bytes. Slave should NACK at 65 byte\r\n"
)
.unwrap();
checkIsWrite!(writer, dir); checkIsWrite!(writer, dir);
_ = i2c.slave_read_buffer(&mut buf_64, i2c::AddressType::GenericAddress); _ = i2c.slave_read_buffer(&mut buf_64, i2c::AddressType::GenericAddress);
match i2c.slave_read_buffer(&mut buf_64, i2c::AddressType::GenericAddress) { match result {
Ok(_) => { None => {
{ {
writeln!(&mut writer, "Test 0x43 failed. Expected to fail. with FrameError\r").unwrap() writeln!(&mut writer, "Test 0x43 failed. Expected to fail Got Ok\r").unwrap()
}; };
} }
Err(err) => { Some(err) => {
errors += 1; errors += 1;
writeln!(&mut writer, "Test 0x43 Ok Expected error. Error: {:?}\r", err).unwrap() writeln!(&mut writer, "Test 0x43 passed. Get expected error. Error: {:?}\r", err).unwrap()
} }
}; };
} }
0x48 => { 0x48 => {
// 0x48 master read slave write slave did not yet prepare a buffer, master will fail // 0x48 master read slave write slave did not yet prepare a buffer, master will fail
writeln!(
&mut writer,
"Start test 0x48. Master-read-slave-write 20 bytes. Should first time (buffer empty)\r\n"
)
.unwrap();
checkIsRead!(writer, dir); checkIsRead!(writer, dir);
match error { match result {
Ok(_) => { None => {
writeln!(&mut writer, "Test 0x48 fail expected to fail: \r").unwrap(); writeln!(&mut writer, "Test 0x48 failed. Expected to fail: \r").unwrap();
errors += 1; errors += 1;
} }
Err(err) => writeln!(&mut writer, "Test 0x48 Ok. Expected error: {:?}\r", err).unwrap(), Some(err) => writeln!(&mut writer, "Test 0x48 passed. Got expected error: {:?}\r", err).unwrap(),
}; };
// prepare buffer for next round // prepare buffer for next round
for i in 0..buf_20.len() { for i in 0..buf_20.len() {
@ -195,13 +206,17 @@ async fn main(_spawner: Spawner) {
_ = i2c.slave_write_buffer(&buf_20, i2c::AddressType::GenericAddress); _ = i2c.slave_write_buffer(&buf_20, i2c::AddressType::GenericAddress);
} }
0x49 => { 0x49 => {
// 0x49 master read slave write bad case: master expects 50 does slave does send 20 characters writeln!(
&mut writer,
"Start test 0x49. Master-read-slave-write 20 bytes. Should be ok\r\n"
)
.unwrap();
checkIsRead!(writer, dir); checkIsRead!(writer, dir);
match error { match result {
Ok(_) => { None => {
writeln!(&mut writer, "Test 0x49 Ok. master did read 20 bytes").unwrap(); writeln!(&mut writer, "Test passed").unwrap();
} }
Err(err) => { Some(err) => {
errors += 1; errors += 1;
writeln!(&mut writer, "Test 0x49 failed. Error: {:?}\r", err).unwrap() writeln!(&mut writer, "Test 0x49 failed. Error: {:?}\r", err).unwrap()
} }
@ -214,14 +229,19 @@ async fn main(_spawner: Spawner) {
} }
0x4A => { 0x4A => {
// 0x4A master read slave write bad case: master expects 64 does slave does prepare 20 characters // 0x4A master read slave write bad case: master expects 64 does slave does prepare 20 characters
writeln!(
&mut writer,
"Start test 0x4A. Master-read-slave-write Master expects 64 bytes, slave sends 20.\r\n"
)
.unwrap();
checkIsRead!(writer, dir); checkIsRead!(writer, dir);
match error { match result {
Ok(_) => { None => {
writeln!(&mut writer, "Test 0x4A failed . Expected an errpr").unwrap(); writeln!(&mut writer, "Test 0x4A failed . Expected an error").unwrap();
} }
Err(err) => { Some(err) => {
errors += 1; errors += 1;
writeln!(&mut writer, "Test 0x4A ok. Expected errore rror: {:?}\r", err).unwrap() writeln!(&mut writer, "Test 0x4A passed. Expected errore rror: {:?}\r", err).unwrap()
} }
} }
_ = i2c.slave_write_buffer(&buf_20, i2c::AddressType::GenericAddress); _ = i2c.slave_write_buffer(&buf_20, i2c::AddressType::GenericAddress);
@ -232,13 +252,17 @@ async fn main(_spawner: Spawner) {
_ = i2c.slave_write_buffer(&buf_64, i2c::AddressType::GenericAddress); _ = i2c.slave_write_buffer(&buf_64, i2c::AddressType::GenericAddress);
} }
0x4B => { 0x4B => {
// 0x4B master write_read good case each 20 chars writeln!(
&mut writer,
"Start test 0x4B. Master-read-slave-write Master expects 64 bytes, Should be ok.\r\n"
)
.unwrap();
checkIsRead!(writer, dir); checkIsRead!(writer, dir);
match error { match result {
Ok(_) => { None => {
writeln!(&mut writer, "Test 0x4B Ok\r").unwrap(); writeln!(&mut writer, "Test 0x4B passed\r").unwrap();
} }
Err(err) => { Some(err) => {
errors += 1; errors += 1;
writeln!(&mut writer, "Test 0x4B failed. Error: {:?}\r", err).unwrap() writeln!(&mut writer, "Test 0x4B failed. Error: {:?}\r", err).unwrap()
} }
@ -248,11 +272,16 @@ async fn main(_spawner: Spawner) {
} }
0x4F => { 0x4F => {
checkIsRead!(writer, dir); checkIsRead!(writer, dir);
match error { writeln!(
Ok(_) => { &mut writer,
"Start test 0x4B. Master-read-slave-write 2 bytes with test summary Should be ok.\r\n"
)
.unwrap();
match result {
None => {
writeln!(&mut writer, "Test 0x4F Result send to master\r").unwrap(); writeln!(&mut writer, "Test 0x4F Result send to master\r").unwrap();
} }
Err(err) => { Some(err) => {
errors += 1; errors += 1;
writeln!(&mut writer, "Test 0x4F failed. Error: {:?}\r", err).unwrap() writeln!(&mut writer, "Test 0x4F failed. Error: {:?}\r", err).unwrap()
} }