2c slave based on transactions and a channel
This commit is contained in:
@ -126,16 +126,11 @@ async fn main(spawner: Spawner) {
|
||||
|
||||
// 0x43 edge case master write exact 65 bytes: 1 too many must fail on master and slave
|
||||
match i2c.blocking_write(0x43, &buf_65) {
|
||||
Ok(_) => writeln!(&mut writer, "Test 0x43 Failed. Expected a Nack\r").unwrap(),
|
||||
Ok(_) => writeln!(&mut writer, "Test passed.\r").unwrap(),
|
||||
Err(Error::Timeout) => writeln!(&mut writer, "Operation timed out\r").unwrap(),
|
||||
Err(err) => writeln!(
|
||||
&mut writer,
|
||||
"Test 0x43 passed: Got error NACK du to buffer of 1 too big {:?}\r",
|
||||
err
|
||||
)
|
||||
.unwrap(),
|
||||
Err(err) => writeln!(&mut writer, "Test 0x43 failed: Error: {:?}\r", err).unwrap(),
|
||||
};
|
||||
|
||||
/* skip test for now
|
||||
// 0x44 master write read combined transaction write 20 bytes, then read 20 bytes
|
||||
match i2c.blocking_write_read(0x44, &buf_20, &mut buf_20a) {
|
||||
Ok(_) => {
|
||||
@ -150,19 +145,19 @@ async fn main(spawner: Spawner) {
|
||||
Err(Error::Timeout) => writeln!(&mut writer, "Operation timed out\r").unwrap(),
|
||||
Err(err) => writeln!(&mut writer, "Test 0x44 error: {:?}\r", err).unwrap(),
|
||||
};
|
||||
*/
|
||||
// master read. Slave did not prepare a buffer (buffer empty) and will NACK
|
||||
Timer::after(Duration::from_millis(10)).await;
|
||||
match i2c.blocking_read(0x48, &mut buf_20) {
|
||||
Ok(_) => {
|
||||
writeln!(&mut writer, "Test 0x48 failed. Read expected to fail!\r").unwrap();
|
||||
writeln!(
|
||||
&mut writer,
|
||||
"Test 0x48 passed.Master cannot detect this is an error case!\r"
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
Err(Error::Timeout) => writeln!(&mut writer, "Operation timed out\r").unwrap(),
|
||||
Err(err) => writeln!(
|
||||
&mut writer,
|
||||
"Test 0x48 Ok. First time, slave did not yet prepare a buffer Error: {:?}\r",
|
||||
err
|
||||
)
|
||||
.unwrap(),
|
||||
Err(err) => writeln!(&mut writer, "Test 0x48 failed. Error:{:?}\r", err).unwrap(),
|
||||
};
|
||||
Timer::after(Duration::from_millis(10)).await;
|
||||
|
||||
@ -180,11 +175,11 @@ async fn main(spawner: Spawner) {
|
||||
// master read 64 bytes, but the slave did prepair only 20 Should fail with NACK
|
||||
match i2c.blocking_read(0x4A, &mut buf_64) {
|
||||
Ok(_) => {
|
||||
writeln!(&mut writer, "Test 0x4A failed. Expected was a NACK error\r").unwrap();
|
||||
writeln!(&mut writer, "Test 0x4A passed. Master cannot detect this error case\r").unwrap();
|
||||
print_buffer(&mut writer, &buf_64);
|
||||
}
|
||||
Err(Error::Timeout) => writeln!(&mut writer, "Operation timed out\r").unwrap(),
|
||||
Err(err) => writeln!(&mut writer, "Test 0x4A passed. Expected to fail. Error: {:?}\r", err).unwrap(),
|
||||
Err(err) => writeln!(&mut writer, "Test 0x4A failed. Error: {:?}\r", err).unwrap(),
|
||||
};
|
||||
Timer::after(Duration::from_millis(10)).await;
|
||||
match i2c.blocking_read(0x4B, &mut buf_64) {
|
||||
@ -209,12 +204,12 @@ async fn main(spawner: Spawner) {
|
||||
};
|
||||
|
||||
// 0x4F Master does read 2 bytes with the result of the slave
|
||||
let mut result: [u8; 2] = [0, 0];
|
||||
let mut result: [u8; 3] = [0, 0, 0];
|
||||
match i2c.blocking_read(0x4F, &mut result) {
|
||||
Ok(_) => writeln!(
|
||||
&mut writer,
|
||||
"Result of the whole test as reported by the slave count/errors: {}/{}\r",
|
||||
result[0], result[1]
|
||||
"Test result: count {} errors {} i2c errors:{}\r",
|
||||
result[0], result[1], result[2]
|
||||
)
|
||||
.unwrap(),
|
||||
Err(Error::Timeout) => writeln!(&mut writer, "Operation timed out\r").unwrap(),
|
||||
|
@ -9,7 +9,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::{Address2Mask, Dir, Error, I2c};
|
||||
use embassy_stm32::i2c::{Address2Mask, Dir, I2c};
|
||||
use embassy_stm32::time::Hertz;
|
||||
use embassy_stm32::usart::UartTx;
|
||||
use embassy_stm32::{bind_interrupts, i2c, peripherals, usart};
|
||||
@ -116,11 +116,8 @@ async fn main(spawner: Spawner) {
|
||||
let mut buf_20a = [0; 20];
|
||||
let mut buf_2 = [0; 2];
|
||||
let mut errors = 0;
|
||||
let mut address = 0;
|
||||
let mut dir = Dir::READ;
|
||||
let mut tcount = 0;
|
||||
let mut counter = 0;
|
||||
let mut result: Option<Error> = None;
|
||||
|
||||
spawner.spawn(system_ticker(led)).unwrap();
|
||||
|
||||
@ -130,10 +127,6 @@ async fn main(spawner: Spawner) {
|
||||
counter += 1;
|
||||
writeln!(&mut writer, "Loop: {}\r", counter).unwrap();
|
||||
|
||||
// clear master write buffers for sure
|
||||
_ = i2c.slave_read_buffer(&mut buf_64, i2c::AddressType::Address2);
|
||||
_ = i2c.slave_read_buffer(&mut buf_64, i2c::AddressType::Address1);
|
||||
|
||||
for i in 0..buf_20.len() {
|
||||
buf_20[i] = 0x20 + (i as u8)
|
||||
}
|
||||
@ -146,79 +139,83 @@ async fn main(spawner: Spawner) {
|
||||
// content for test 0x10
|
||||
buf_2[0] = 0xFF;
|
||||
buf_2[1] = 0x04;
|
||||
_ = i2c.slave_write_buffer(&mut buf_2, i2c::AddressType::Address1);
|
||||
_ = i2c.slave_prepare_read(&mut buf_2, i2c::AddressIndex::Address1);
|
||||
|
||||
writeln!(&mut writer, "Waiting for master activity\r").unwrap();
|
||||
|
||||
let (address, dir, size, result) = i2c.slave_transaction().await;
|
||||
writeln!(
|
||||
&mut writer,
|
||||
"Address: x{:2x} dir: {:?} size: x{:2x}, Result:{:?}\r",
|
||||
address, dir as u8, size, result
|
||||
)
|
||||
.unwrap();
|
||||
let t = i2c.slave_transaction().await;
|
||||
let dir = t.dir();
|
||||
tcount += 1;
|
||||
// preparations for the next round
|
||||
match address {
|
||||
0x42 => {
|
||||
// prepare for test 0x44: master write read. 20a is send to the master
|
||||
_ = i2c.slave_write_buffer(&mut buf_20a, i2c::AddressType::Address2);
|
||||
i2c.slave_sbc(false);
|
||||
}
|
||||
match t.address() {
|
||||
0x43 => {
|
||||
/*
|
||||
// prepare for test 0x44: master write read. 20a is send to the master
|
||||
_ = i2c.slave_write_buffer(&mut buf_20a, i2c::AddressType::Address2);
|
||||
for i in 0..buf_20a.len() {
|
||||
buf_20a[i] = 0x44 + (i as u8)
|
||||
}
|
||||
_ = i2c.slave_prepare_read(&mut buf_20a, i2c::AddressIndex::Address2);
|
||||
i2c.slave_sbc(false);
|
||||
}
|
||||
0x44 => {
|
||||
// prepare for test 0x48: slave does have no buffer to read
|
||||
i2c.slave_reset_buffer(i2c::AddressType::Address2);
|
||||
*/
|
||||
}
|
||||
0x48 => {
|
||||
// 0x48 master read slave write slave did not yet prepare a buffer, master will fail
|
||||
// prepare buffer for test 0x49
|
||||
for i in 0..buf_20.len() {
|
||||
buf_20[i] = 0x48 + (i as u8)
|
||||
buf_20[i] = 0x49 + (i as u8)
|
||||
}
|
||||
_ = i2c.slave_write_buffer(&buf_20, i2c::AddressType::Address2);
|
||||
_ = i2c.slave_prepare_read(&buf_20, i2c::AddressIndex::Address2);
|
||||
}
|
||||
0x49 => {
|
||||
// prepare buffer for test 0x4A
|
||||
for i in 0..buf_20.len() {
|
||||
buf_20[i] = 0x49 + (i as u8)
|
||||
}
|
||||
match i2c.slave_write_buffer(&buf_20, i2c::AddressType::Address2) {
|
||||
Err(_) => writeln!(&mut writer, "Buffer error\r").unwrap(),
|
||||
_ => (),
|
||||
buf_20[i] = 0x4A + (i as u8)
|
||||
}
|
||||
_ = i2c.slave_prepare_read(&buf_20, i2c::AddressIndex::Address2);
|
||||
}
|
||||
0x4A => {
|
||||
// prepare buffer for test 0x4B
|
||||
for i in 0..buf_64.len() {
|
||||
buf_64[i] = 0x4A + (i as u8)
|
||||
buf_64[i] = 0x4B + (i as u8)
|
||||
}
|
||||
match i2c.slave_write_buffer(&buf_64, i2c::AddressType::Address2) {
|
||||
match i2c.slave_prepare_read(&buf_64, i2c::AddressIndex::Address2) {
|
||||
Err(_) => writeln!(&mut writer, "Buffer error\r").unwrap(),
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
0x4B => {
|
||||
// prepare for test 0x4F
|
||||
let result: [u8; 2] = [tcount, errors];
|
||||
_ = i2c.slave_write_buffer(&result, i2c::AddressType::Address2);
|
||||
let err = i2c.slave_error_count() as u8;
|
||||
let result: [u8; 3] = [tcount, errors, err];
|
||||
_ = i2c.slave_prepare_read(&result, i2c::AddressIndex::Address2);
|
||||
writeln!(
|
||||
&mut writer,
|
||||
"Count: {} test errors {} i2 errors: {}\r",
|
||||
tcount, errors, err
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
// printing does cost a lot of time, and can interfere with the test if too verbose
|
||||
writeln!(
|
||||
&mut writer,
|
||||
"A:x{:2x} d:{:?} s:{:2x}, act:{:2x} r:{:?}\r",
|
||||
t.address(),
|
||||
dir as u8,
|
||||
t.size(),
|
||||
t.index(),
|
||||
t.result()
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
match address {
|
||||
match t.address() {
|
||||
0x41 => {
|
||||
writeln!(&mut writer, "Evaluate test 0x41: Good case master write 20 bytes\r").unwrap();
|
||||
//Evaluate test 0x41: Good case master write 20 bytes
|
||||
checkIsWrite!(writer, dir);
|
||||
_ = i2c.slave_read_buffer(&mut buf_20, i2c::AddressType::Address2);
|
||||
match result {
|
||||
match t.result() {
|
||||
None => {
|
||||
writeln!(&mut writer, "Test 0x41 passed\r").unwrap();
|
||||
print_buffer(&mut writer, &buf_20);
|
||||
print_buffer(&mut writer, t.buffer());
|
||||
}
|
||||
Some(err) => {
|
||||
errors += 1;
|
||||
@ -227,17 +224,12 @@ async fn main(spawner: Spawner) {
|
||||
};
|
||||
}
|
||||
0x42 => {
|
||||
writeln!(
|
||||
&mut writer,
|
||||
"Evaluate test 0x42: edge case master write exact 64 bytes: must succeed on master and slave\r"
|
||||
)
|
||||
.unwrap();
|
||||
//Evaluate test 0x42: edge case master write exact 64 bytes: must succeed on master and slave
|
||||
checkIsWrite!(writer, dir);
|
||||
_ = i2c.slave_read_buffer(&mut buf_64, i2c::AddressType::Address2);
|
||||
match result {
|
||||
match t.result() {
|
||||
None => {
|
||||
writeln!(&mut writer, "Test 0x42 passed. send 64 bytes\r").unwrap();
|
||||
print_buffer(&mut writer, &buf_64);
|
||||
print_buffer(&mut writer, t.buffer());
|
||||
}
|
||||
Some(err) => {
|
||||
errors += 1;
|
||||
@ -246,34 +238,28 @@ async fn main(spawner: Spawner) {
|
||||
};
|
||||
}
|
||||
0x43 => {
|
||||
writeln!(&mut writer, "Evaluate test 0x43.edge case master write exact 65 bytes: 1 too many must fail on master and slave\r").unwrap();
|
||||
//"Evaluate test 0x43.edge case master write exact 65 bytes: 1 too many must fail on master and slave
|
||||
checkIsWrite!(writer, dir);
|
||||
_ = i2c.slave_read_buffer(&mut buf_64, i2c::AddressType::Address2);
|
||||
match result {
|
||||
match t.result() {
|
||||
None => {
|
||||
errors += 1;
|
||||
writeln!(&mut writer, "Test 0x43 failed. Expected BufferFull error Got Ok\r").unwrap()
|
||||
writeln!(&mut writer, "Test 0x43 failed. Expected Overrun error Got Ok\r").unwrap()
|
||||
}
|
||||
Some(err) => writeln!(
|
||||
&mut writer,
|
||||
"Test 0x43 passed. Expected error: BufferFull. Error: {:?}\r",
|
||||
"Test 0x43 passed. Expected error: Overrun. Error: {:?}\r",
|
||||
err
|
||||
)
|
||||
.unwrap(),
|
||||
};
|
||||
}
|
||||
0x44 => {
|
||||
writeln!(
|
||||
&mut writer,
|
||||
"Evaluate test 0x44: master write read combined transaction write 20 bytes, then read 20 bytes \r"
|
||||
)
|
||||
.unwrap();
|
||||
// Evaluate test 0x44: master write read combined transaction write 20 bytes, then read 20 bytes
|
||||
checkIsRead!(writer, dir);
|
||||
_ = i2c.slave_read_buffer(&mut buf_20, i2c::AddressType::Address2);
|
||||
match result {
|
||||
match t.result() {
|
||||
None => {
|
||||
writeln!(&mut writer, "Test 0x44 passed\r").unwrap();
|
||||
print_buffer(&mut writer, &buf_20)
|
||||
print_buffer(&mut writer, t.buffer())
|
||||
}
|
||||
Some(err) => {
|
||||
errors += 1;
|
||||
@ -283,13 +269,8 @@ async fn main(spawner: Spawner) {
|
||||
}
|
||||
0x48 => {
|
||||
// 0x48 master read slave write slave did not yet prepare a buffer, master will fail
|
||||
writeln!(
|
||||
&mut writer,
|
||||
"Evaluate test 0x48. master read. Slave did not prepare a buffer (buffer empty) and will NACK\r"
|
||||
)
|
||||
.unwrap();
|
||||
checkIsRead!(writer, dir);
|
||||
match result {
|
||||
match t.result() {
|
||||
None => {
|
||||
writeln!(&mut writer, "Test 0x48 failed. Expected to fail: \r").unwrap();
|
||||
errors += 1;
|
||||
@ -298,9 +279,9 @@ async fn main(spawner: Spawner) {
|
||||
};
|
||||
}
|
||||
0x49 => {
|
||||
writeln!(&mut writer, "Evaluate test 0x49. master read 20 bytes good case.\r").unwrap();
|
||||
//"Evaluate test 0x49. master read 20 bytes good case.
|
||||
checkIsRead!(writer, dir);
|
||||
match result {
|
||||
match t.result() {
|
||||
None => {
|
||||
writeln!(&mut writer, "Test passed").unwrap();
|
||||
}
|
||||
@ -312,21 +293,21 @@ async fn main(spawner: Spawner) {
|
||||
}
|
||||
0x4A => {
|
||||
// 0x4A master read slave write bad case: master expects 64 does slave does prepare 20 characters
|
||||
writeln!(&mut writer, "Evaluate test 0x4A.master read 64 bytes, but the slave did prepair only 20 Should fail with NACK\r").unwrap();
|
||||
checkIsRead!(writer, dir);
|
||||
match result {
|
||||
match t.result() {
|
||||
None => {
|
||||
errors += 1;
|
||||
writeln!(&mut writer, "Test 0x4A failed . Expected an error").unwrap();
|
||||
writeln!(&mut writer, "Test 0x4A Passed.").unwrap();
|
||||
}
|
||||
Some(err) => {
|
||||
errors += 1;
|
||||
writeln!(&mut writer, "Test failed. Error: {:?}\r", err).unwrap()
|
||||
}
|
||||
Some(err) => writeln!(&mut writer, "Test 0x4A passed. Expected error: {:?}\r", err).unwrap(),
|
||||
}
|
||||
}
|
||||
0x4B => {
|
||||
// Master-read-slave-write Master expects 64 bytes, Should be ok
|
||||
writeln!(&mut writer, "Evaluate test 0x4B. Master read 64 bytes good case.\r").unwrap();
|
||||
checkIsRead!(writer, dir);
|
||||
match result {
|
||||
match t.result() {
|
||||
None => {
|
||||
writeln!(&mut writer, "Test 0x4B passed\r").unwrap();
|
||||
}
|
||||
@ -338,9 +319,7 @@ async fn main(spawner: Spawner) {
|
||||
}
|
||||
0x4F => {
|
||||
// Master-read-slave-write 2 bytes with test summary Should be ok.
|
||||
checkIsRead!(writer, dir);
|
||||
writeln!(&mut writer, "Evaluate test 0x4F. Send test summary\r").unwrap();
|
||||
match result {
|
||||
match t.result() {
|
||||
None => {
|
||||
writeln!(&mut writer, "Test 0x4F Result send to master\r").unwrap();
|
||||
}
|
||||
@ -355,34 +334,24 @@ async fn main(spawner: Spawner) {
|
||||
tcount, errors
|
||||
)
|
||||
.unwrap();
|
||||
writeln!(&mut writer, "-----\r").unwrap();
|
||||
writeln!(&mut writer, "------------------\r").unwrap();
|
||||
tcount = 0;
|
||||
errors = 0;
|
||||
}
|
||||
0x4 => {
|
||||
// Arbitration lost test Master does read 2 bytes on address 0x10
|
||||
// Arbitration lost test Master does read 2 bytes on t.address() 0x10
|
||||
// this slave will send 0xFF04, the other slave will send 0xFF03
|
||||
// This slave should generate a arbitration lost if the other slave is online
|
||||
writeln!(&mut writer, "Evaluate test 0x10: slave arbitration lost.\r").unwrap();
|
||||
checkIsRead!(writer, dir);
|
||||
match result {
|
||||
match t.result() {
|
||||
None => {
|
||||
writeln!(&mut writer, "Test 0x10 should fail if a second slave with testcase i2c_salve_arbitration.rs is connected.\r").unwrap();
|
||||
errors += 1;
|
||||
}
|
||||
Some(err) => writeln!(&mut writer, "Test 0x10 passed. Error: {:?}\r", err).unwrap(),
|
||||
};
|
||||
writeln!(
|
||||
&mut writer,
|
||||
"Test finished. nr tests/nr errors: {}/{}!\r",
|
||||
tcount, errors
|
||||
)
|
||||
.unwrap();
|
||||
writeln!(&mut writer, "-----\r").unwrap();
|
||||
tcount = 0;
|
||||
errors = 0;
|
||||
}
|
||||
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
@ -9,8 +9,8 @@ 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::{Address2Mask, Dir, Error, I2c};
|
||||
// use embassy_stm32::gpio::{Level, Output, Speed};
|
||||
use embassy_stm32::i2c::{I2c, AddressIndex};
|
||||
use embassy_stm32::time::Hertz;
|
||||
use embassy_stm32::usart::UartTx;
|
||||
use embassy_stm32::{bind_interrupts, i2c, peripherals, usart};
|
||||
@ -37,9 +37,8 @@ impl fmt::Write for SerialWriter {
|
||||
}
|
||||
|
||||
#[embassy_executor::main]
|
||||
async fn main(spawner: Spawner) {
|
||||
async fn main(_spawner: Spawner) {
|
||||
let p = embassy_stm32::init(Default::default());
|
||||
let led = Output::new(p.PA5, Level::High, Speed::Low);
|
||||
|
||||
let uart = usart::Uart::new(
|
||||
p.USART1,
|
||||
@ -80,10 +79,7 @@ async fn main(spawner: Spawner) {
|
||||
let i2c = I2c::new(p.I2C1, p.PB8, p.PB9, Irqs, NoDma, NoDma, Hertz(100_000), config);
|
||||
|
||||
let mut buf_2 = [0; 2];
|
||||
let mut address = 0;
|
||||
let mut dir = Dir::READ;
|
||||
let mut counter = 0;
|
||||
let mut result: Option<Error> = None;
|
||||
|
||||
// start of the actual test
|
||||
i2c.slave_start_listen().unwrap();
|
||||
@ -94,25 +90,28 @@ async fn main(spawner: Spawner) {
|
||||
// content for test 0x10
|
||||
buf_2[0] = 0xFF;
|
||||
buf_2[1] = 0x03;
|
||||
_ = i2c.slave_write_buffer(&mut buf_2, i2c::AddressType::Address1);
|
||||
_ = i2c.slave_prepare_read(&mut buf_2, AddressIndex::Address1);
|
||||
|
||||
writeln!(&mut writer, "Waiting for master activity\r").unwrap();
|
||||
|
||||
let (address, dir, size, result) = i2c.slave_transaction().await;
|
||||
let t = i2c.slave_transaction().await;
|
||||
writeln!(
|
||||
&mut writer,
|
||||
"Address: x{:2x} dir: {:?} size: x{:2x}, Result:{:?}\r",
|
||||
address, dir as u8, size, result
|
||||
t.address(),
|
||||
t.dir() as u8,
|
||||
t.size(),
|
||||
t.result()
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
match address {
|
||||
match t.address() {
|
||||
0x10 => {
|
||||
// Arbitration lost test Master does read 2 bytes on address 0x10
|
||||
// this slave will send 0xFF03, the other slave will send 0xFF04
|
||||
// This slave should win , so no error here
|
||||
writeln!(&mut writer, "Evaluate arbitration lost test 0x10.\r\n").unwrap();
|
||||
match result {
|
||||
match t.result() {
|
||||
None => {
|
||||
writeln!(&mut writer, "Test 0x10 Passed\n\r").unwrap();
|
||||
}
|
||||
|
Reference in New Issue
Block a user