Arbitration lost test is working. Still some test failing

This commit is contained in:
anton smeenk
2023-10-27 14:54:06 +02:00
parent 70a64e8dcb
commit ce066e92e7
5 changed files with 417 additions and 140 deletions

View File

@ -9,6 +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::{Error, I2c};
use embassy_stm32::time::Hertz;
use embassy_stm32::usart::UartTx;
@ -35,10 +36,21 @@ impl fmt::Write for SerialWriter {
Ok(())
}
}
#[embassy_executor::task]
pub async fn system_ticker(mut led: Output<'static, peripherals::PA6>) {
loop {
Timer::after(Duration::from_millis(200)).await;
led.set_high();
Timer::after(Duration::from_millis(100)).await;
led.set_low();
}
}
#[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); // nucleog070rb board
let led = Output::new(p.PA6, Level::High, Speed::Low);
let uart = usart::Uart::new(
p.USART1,
@ -71,19 +83,21 @@ async fn main(_spawner: Spawner) {
Default::default(),
);
Timer::after(Duration::from_millis(1000)).await;
spawner.spawn(system_ticker(led)).unwrap();
// start of the acutal test
let mut counter = 0;
loop {
counter += 1;
writeln!(&mut writer, "Loop counter: {:?}", counter).unwrap();
writeln!(&mut writer, "Loop counter: {:?}\r", counter).unwrap();
let mut buf_20 = [0_u8; 20];
let mut buf_20a = [0_u8; 20];
let mut buf_64 = [0_u8; 64];
let mut buf_65 = [0_u8; 65];
let mut buf_2 = [0_u8; 2];
writeln!(&mut writer, "Start of test\n\r").unwrap();
writeln!(&mut writer, "Start of test\r").unwrap();
for i in 0..buf_20.len() {
buf_20[i] = 0x20 + (i as u8)
@ -94,117 +108,126 @@ async fn main(_spawner: Spawner) {
for i in 0..buf_65.len() {
buf_65[i] = 0x60 + (i as u8)
}
// test 1: slave address 0x61 should not be addressable
match i2c.blocking_write(0x61, &buf_20) {
Ok(_) => writeln!(&mut writer, "Test 1 failed: would expect nack\n\r").unwrap(),
Err(Error::Timeout) => writeln!(&mut writer, "Operation timed out\n\r").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 20 bytes
match i2c.blocking_write(0x41, &buf_20) {
Ok(_) => writeln!(&mut writer, "Test 0x41 passed\n\r").unwrap(),
Err(Error::Timeout) => writeln!(&mut writer, "Operation timed out\n\r").unwrap(),
Err(err) => writeln!(&mut writer, "Test 0x41 failed. Error: {:?}", err).unwrap(),
Ok(_) => writeln!(&mut writer, "Test 0x41 passed\r").unwrap(),
Err(Error::Timeout) => writeln!(&mut writer, "Operation timed out\r").unwrap(),
Err(err) => writeln!(&mut writer, "Test 0x41 failed. Error: {:?}\r", err).unwrap(),
};
Timer::after(Duration::from_millis(10)).await;
// 0x42 edge case master write exact 64 bytes: must succeed on master and slave
match i2c.blocking_write(0x42, &buf_64) {
Ok(_) => writeln!(&mut writer, "Test 0x42 passed. Master write exact 64 bytes\n\r").unwrap(),
Err(Error::Timeout) => writeln!(&mut writer, "Operation timed out\n\r").unwrap(),
Err(err) => writeln!(&mut writer, "Test 0x42 failed. Got error: {:?}\r\n", err).unwrap(),
Ok(_) => writeln!(&mut writer, "Test 0x42 passed. Master write exact 64 bytes\r").unwrap(),
Err(Error::Timeout) => writeln!(&mut writer, "Operation timed out\r").unwrap(),
Err(err) => writeln!(&mut writer, "Test 0x42 failed. Got error: {:?}\r", err).unwrap(),
};
Timer::after(Duration::from_millis(10)).await;
// 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\n\r").unwrap(),
Err(Error::Timeout) => writeln!(&mut writer, "Operation timed out\n\r").unwrap(),
Ok(_) => writeln!(&mut writer, "Test 0x43 Failed. Expected a Nack\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\n",
"Test 0x43 passed: Got error NACK du to buffer of 1 too big {:?}\r",
err
)
.unwrap(),
};
// 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(_) => {
writeln!(&mut writer, "Test 0x44 Ok \r").unwrap();
writeln!(
&mut writer,
"Uppercase input should be transformed to lowercase, A -> b \r"
)
.unwrap();
print_buffer(&mut writer, &buf_20a);
}
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!\n\r").unwrap();
writeln!(&mut writer, "Test 0x48 failed. Read expected to fail!\r").unwrap();
}
Err(Error::Timeout) => writeln!(&mut writer, "Operation timed out\n\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\n",
"Test 0x48 Ok. First time, slave did not yet prepare a buffer Error: {:?}\r",
err
)
.unwrap(),
};
Timer::after(Duration::from_millis(10)).await;
// master read 20 bytes good case.
match i2c.blocking_read(0x49, &mut buf_20) {
Ok(_) => {
writeln!(&mut writer, "Test 0x49 Read Ok\n\r").unwrap();
writeln!(&mut writer, "Test 0x49 Read Ok\r").unwrap();
print_buffer(&mut writer, &buf_20);
}
Err(Error::Timeout) => writeln!(&mut writer, "Operation timed out\n\r").unwrap(),
Err(err) => writeln!(&mut writer, "Test 0x49 Error: {:?}\r\n", err).unwrap(),
Err(Error::Timeout) => writeln!(&mut writer, "Operation timed out\r").unwrap(),
Err(err) => writeln!(&mut writer, "Test 0x49 Error: {:?}\r", err).unwrap(),
};
Timer::after(Duration::from_millis(10)).await;
// 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\n\r").unwrap();
writeln!(&mut writer, "Test 0x4A failed. Expected was a NACK error\r").unwrap();
print_buffer(&mut writer, &buf_64);
}
Err(Error::Timeout) => writeln!(&mut writer, "Operation timed out\n\r").unwrap(),
Err(err) => writeln!(&mut writer, "Test 0x4A passed. Expected to fail. Error: {:?}\r\n", err).unwrap(),
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(),
};
Timer::after(Duration::from_millis(10)).await;
match i2c.blocking_read(0x4B, &mut buf_64) {
Ok(_) => {
writeln!(&mut writer, "Test 0x4B passed\n\r").unwrap();
writeln!(&mut writer, "Test 0x4B passed\r").unwrap();
print_buffer(&mut writer, &buf_64);
}
Err(Error::Timeout) => writeln!(&mut writer, "Operation timed out\n\r").unwrap(),
Err(err) => writeln!(&mut writer, "Test 0x4B failed. Error: {:?}\r\n", err).unwrap(),
Err(Error::Timeout) => writeln!(&mut writer, "Operation timed out\r").unwrap(),
Err(err) => writeln!(&mut writer, "Test 0x4B failed. Error: {:?}\r", err).unwrap(),
};
/*
match i2c.blocking_write_read(0x44, &buf_20, &mut buf_20a) {
Ok(_) => {
writeln!(&mut writer, "Test 0x44 Ok \n\r").unwrap();
writeln!(
&mut writer,
"Uppercase input should be transformed to lowercase, A -> b "
)
.unwrap();
for i in 0..buf_20a.len() {
writeln!(&mut writer, "{}", buf_20[i]).unwrap();
}
writeln!(&mut writer, "\n\r").unwrap()
}
Err(Error::Timeout) => writeln!(&mut writer, "Operation timed out\n\r").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
// test for arbitration lost. 2 slaves respond on address 10 one with 0xFF03, on with 0xFF04
// if both are online the one with 0xFF04 should report arbitration loss, here we read 0xFF03
match i2c.blocking_read(0x10, &mut buf_2) {
Ok(_) => {
writeln!(&mut writer, "Test 0x10 Received {:2x}:{:2x}\r", buf_2[0], buf_2[1]).unwrap();
writeln!(&mut writer, "Look in the log of the slaves to evaluate the result\r").unwrap();
}
Err(Error::Timeout) => writeln!(&mut writer, "Operation timed out\r").unwrap(),
Err(err) => writeln!(&mut writer, "Test 0x10 Failed: Error: {:?}", err).unwrap(),
};
// 0x4F Master does read 2 bytes with the result of the slave
let mut result: [u8; 2] = [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\n",
"Result of the whole test as reported by the slave count/errors: {}/{}\r",
result[0], result[1]
)
.unwrap(),
Err(Error::Timeout) => writeln!(&mut writer, "Operation timed out\n\r").unwrap(),
Err(err) => writeln!(&mut writer, "Test 0x4F unexpected error: {:?}\r\n", err).unwrap(),
Err(Error::Timeout) => writeln!(&mut writer, "Operation timed out\r").unwrap(),
Err(err) => writeln!(&mut writer, "Test 0x4F unexpected error: {:?}\r", err).unwrap(),
};
writeln!(&mut writer, "\n\r").unwrap();
writeln!(&mut writer, "\r").unwrap();
Timer::after(Duration::from_millis(10_000)).await;
}
fn print_buffer(writer: &mut SerialWriter, buf: &[u8]) {
for i in 0..buf.len() {
write!(writer, " {:2x} ", buf[i]).unwrap();
}
writeln!(writer, "\n\r\n\r").unwrap()
writeln!(writer, "\r\r").unwrap()
}
}

View File

@ -72,7 +72,7 @@ impl fmt::Write for SerialWriter {
#[embassy_executor::main]
async fn main(spawner: Spawner) {
let p = embassy_stm32::init(Default::default());
let mut led = Output::new(p.PA5, Level::High, Speed::Low);
let led = Output::new(p.PA5, Level::High, Speed::Low);
/*
let uart = usart::Uart::new(
@ -107,15 +107,15 @@ async fn main(spawner: Spawner) {
.unwrap();
let mut config = i2c::Config::default();
config.slave_address_7bits(0x4);
config.slave_address_7bits(0x10); // for arbitration lost test
config.slave_address_2(0x41, vals::Oamsk::MASK4);
writeln!(&mut writer, "After config:\r",).unwrap();
let mut i2c = I2c::new(p.I2C1, p.PB8, p.PB9, Irqs, NoDma, NoDma, Hertz(100_000), config);
writeln!(&mut writer, "After i2c init\r").unwrap();
let i2c = I2c::new(p.I2C1, p.PB8, p.PB9, Irqs, NoDma, NoDma, Hertz(100_000), config);
let mut buf_64 = [0; 64]; // buffer is longer than master will send: wait for STOP condition
let mut buf_20 = [0; 20]; // buffer is shorter than master will send: wait for STOP condition
let mut buf_20a = [0; 20];
let mut buf_2 = [0; 2];
let mut errors = 0;
let mut address = 0;
let mut dir = vals::Dir::READ;
@ -131,19 +131,26 @@ 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)
}
for i in 0..buf_20a.len() {
buf_20a[i] = 0x40 - (i as u8)
}
for i in 0..buf_64.len() {
buf_64[i] = 0x60 + (i as u8)
}
// content for test 0x10
buf_2[0] = 0xFF;
buf_2[1] = 0x04;
_ = i2c.slave_write_buffer(&mut buf_2, i2c::AddressType::Address1);
writeln!(&mut writer, "Waiting for master activity\r").unwrap();
// clear write buffers for sure
_ = i2c.slave_read_buffer(&mut buf_64, i2c::AddressType::GenericAddress);
_ = i2c.slave_read_buffer(&mut buf_64, i2c::AddressType::MainAddress);
let (address, dir, size, result) = i2c.slave_transaction().await;
writeln!(
&mut writer,
@ -152,30 +159,85 @@ async fn main(spawner: Spawner) {
)
.unwrap();
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);
}
0x43 => {
// 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);
}
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)
}
_ = i2c.slave_write_buffer(&buf_20, i2c::AddressType::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(),
_ => (),
}
}
0x4A => {
// prepare buffer for test 0x4B
for i in 0..buf_64.len() {
buf_64[i] = 0x4A + (i as u8)
}
match i2c.slave_write_buffer(&buf_64, i2c::AddressType::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);
}
_ => (),
}
match address {
0x41 => {
writeln!(&mut writer, "Evaluate test 0x41.\r\n").unwrap();
writeln!(&mut writer, "Evaluate test 0x41: Good case master write 20 bytes\r").unwrap();
checkIsWrite!(writer, dir);
_ = i2c.slave_read_buffer(&mut buf_20, i2c::AddressType::GenericAddress);
_ = i2c.slave_read_buffer(&mut buf_20, i2c::AddressType::Address2);
match result {
None => {
writeln!(&mut writer, "Test 0x41 passed\r\n").unwrap();
writeln!(&mut writer, "Test 0x41 passed\r").unwrap();
print_buffer(&mut writer, &buf_20);
}
Some(err) => {
errors += 1;
writeln!(&mut writer, "Test 0x41 failed. Error: {:?}\r\n", err).unwrap()
writeln!(&mut writer, "Test 0x41 failed. Error: {:?}\r", err).unwrap()
}
};
}
0x42 => {
writeln!(&mut writer, "Evaluate test 0x42.\r\n").unwrap();
writeln!(
&mut writer,
"Evaluate test 0x42: edge case master write exact 64 bytes: must succeed on master and slave\r"
)
.unwrap();
checkIsWrite!(writer, dir);
_ = i2c.slave_read_buffer(&mut buf_64, i2c::AddressType::GenericAddress);
_ = i2c.slave_read_buffer(&mut buf_64, i2c::AddressType::Address2);
match result {
None => {
writeln!(&mut writer, "Test 0x42 passed. send 64 bytes\r\n").unwrap();
writeln!(&mut writer, "Test 0x42 passed. send 64 bytes\r").unwrap();
print_buffer(&mut writer, &buf_64);
}
Some(err) => {
@ -185,9 +247,9 @@ async fn main(spawner: Spawner) {
};
}
0x43 => {
writeln!(&mut writer, "Evaluate test 0x43.\r\n").unwrap();
writeln!(&mut writer, "Evaluate test 0x43.edge case master write exact 65 bytes: 1 too many must fail on master and slave\r").unwrap();
checkIsWrite!(writer, dir);
_ = i2c.slave_read_buffer(&mut buf_64, i2c::AddressType::GenericAddress);
_ = i2c.slave_read_buffer(&mut buf_64, i2c::AddressType::Address2);
match result {
None => {
errors += 1;
@ -201,9 +263,32 @@ async fn main(spawner: Spawner) {
.unwrap(),
};
}
0x44 => {
writeln!(
&mut writer,
"Evaluate test 0x44: master write read combined transaction write 20 bytes, then read 20 bytes \r"
)
.unwrap();
checkIsRead!(writer, dir);
_ = i2c.slave_read_buffer(&mut buf_20, i2c::AddressType::Address2);
match result {
None => {
writeln!(&mut writer, "Test 0x44 passed\r").unwrap();
print_buffer(&mut writer, &buf_20)
}
Some(err) => {
errors += 1;
writeln!(&mut writer, "Test 0x44 failed. Error:{:?}\r", err).unwrap()
}
};
}
0x48 => {
// 0x48 master read slave write slave did not yet prepare a buffer, master will fail
writeln!(&mut writer, "Evaluate test 0x48.\r\n").unwrap();
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 {
None => {
@ -212,16 +297,9 @@ async fn main(spawner: Spawner) {
}
Some(err) => writeln!(&mut writer, "Test 0x48 passed. Got expected error: {:?}\r", err).unwrap(),
};
// prepare buffer for test 0x49
_ = i2c.slave_write_buffer(&buf_20, i2c::AddressType::GenericAddress);
}
0x49 => {
// prepare buffer for test 0x4A
for i in 0..buf_20.len() {
buf_20[i] = 0x50 + (i as u8)
}
_ = i2c.slave_write_buffer(&buf_20, i2c::AddressType::GenericAddress);
writeln!(&mut writer, "Evaluate test 0x49\r\n").unwrap();
writeln!(&mut writer, "Evaluate test 0x49. master read 20 bytes good case.\r").unwrap();
checkIsRead!(writer, dir);
match result {
None => {
@ -232,33 +310,22 @@ async fn main(spawner: Spawner) {
writeln!(&mut writer, "Test 0x49 failed. Error: {:?}\r", err).unwrap()
}
};
// prepare buffer for test 0x4A
_ = i2c.slave_write_buffer(&buf_20, i2c::AddressType::GenericAddress);
}
0x4A => {
// 0x4A master read slave write bad case: master expects 64 does slave does prepare 20 characters
// prepare buffer for test 0x4B
for i in 0..buf_64.len() {
buf_64[i] = 0x40 + (i as u8)
}
_ = i2c.slave_write_buffer(&buf_64, i2c::AddressType::GenericAddress);
writeln!(&mut writer, "Evaluate test 0x4A.\r\n").unwrap();
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 {
None => {
errors += 1;
writeln!(&mut writer, "Test 0x4A failed . Expected an error").unwrap();
}
Some(err) => {
errors += 1;
writeln!(&mut writer, "Test 0x4A passed. Expected error: {:?}\r", err).unwrap()
}
Some(err) => writeln!(&mut writer, "Test 0x4A passed. Expected error: {:?}\r", err).unwrap(),
}
_ = i2c.slave_write_buffer(&buf_20, i2c::AddressType::GenericAddress);
}
0x4B => {
// Master-read-slave-write Master expects 64 bytes, Should be ok
writeln!(&mut writer, "Evaluate test 0x4B. .\r\n").unwrap();
writeln!(&mut writer, "Evaluate test 0x4B. Master read 64 bytes good case.\r").unwrap();
checkIsRead!(writer, dir);
match result {
None => {
@ -269,14 +336,11 @@ async fn main(spawner: Spawner) {
writeln!(&mut writer, "Test 0x4B failed. Error: {:?}\r", err).unwrap()
}
};
// prepare for test 0x4F
let result: [u8; 2] = [tcount, errors];
_ = i2c.slave_write_buffer(&result, i2c::AddressType::GenericAddress);
}
0x4F => {
// Master-read-slave-write 2 bytes with test summary Should be ok.
checkIsRead!(writer, dir);
writeln!(&mut writer, "Evaluate test 0x4F.\r\n").unwrap();
writeln!(&mut writer, "Evaluate test 0x4F. Send test summary\r").unwrap();
match result {
None => {
writeln!(&mut writer, "Test 0x4F Result send to master\r").unwrap();
@ -296,6 +360,30 @@ async fn main(spawner: Spawner) {
tcount = 0;
errors = 0;
}
0x10 => {
// Arbitration lost test Master does read 2 bytes on 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 {
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;
}
_ => (),
}
}
@ -303,6 +391,6 @@ async fn main(spawner: Spawner) {
for i in 0..buf.len() {
write!(writer, " {:2x} ", buf[i]).unwrap();
}
writeln!(writer, "\n\r").unwrap()
writeln!(writer, "\r").unwrap()
}
}

View File

@ -0,0 +1,153 @@
#![no_std]
#![no_main]
#![feature(type_alias_impl_trait)]
// test is targeted for nucleo-g070RB board
// this test will only respond to address 0x10, master read with 0xFF03
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::{Error, I2c};
use embassy_stm32::pac::i2c::vals;
use embassy_stm32::time::Hertz;
use embassy_stm32::usart::UartTx;
use embassy_stm32::{bind_interrupts, i2c, peripherals, usart};
use embassy_time::{Duration, Timer};
use {defmt_rtt as _, panic_probe as _};
bind_interrupts!(struct Irqs {
I2C1 => i2c::InterruptHandler<peripherals::I2C1>;
USART1 => usart::InterruptHandler<peripherals::USART1>;
});
macro_rules! checkIsWrite {
($writer:ident, $direction:ident) => {
match $direction {
vals::Dir::WRITE => (),
_ => {
write!($writer, "Error incorrect direction {:?}\r", $direction as usize).unwrap();
continue;
}
}
};
}
macro_rules! checkIsRead {
($writer:ident, $direction:ident) => {
match $direction {
vals::Dir::READ => (),
_ => {
write!($writer, "Error incorrect direction {:?}\r", $direction as usize).unwrap();
continue;
}
}
};
}
pub struct SerialWriter {
tx: UartTx<'static, peripherals::USART1, peripherals::DMA1_CH1>,
}
impl SerialWriter {
pub fn new(tx: UartTx<'static, peripherals::USART1, peripherals::DMA1_CH1>) -> Self {
SerialWriter { tx }
}
}
impl fmt::Write for SerialWriter {
fn write_str(&mut self, s: &str) -> fmt::Result {
_ = self.tx.blocking_write(s.as_bytes());
Ok(())
}
}
#[embassy_executor::main]
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,
p.PB7,
p.PB6,
Irqs,
p.DMA1_CH1,
p.DMA1_CH2,
usart::Config::default(),
)
.unwrap();
/*
let uart = usart::Uart::new(
p.USART2,
p.PA3,
p.PA2,
Irqs,
p.DMA1_CH1,
p.DMA1_CH2,
usart::Config::default(),
)
.unwrap();
*/
let (tx, _rx) = uart.split();
let mut writer = SerialWriter::new(tx);
writeln!(
&mut writer,
"i2c slave test for arbitration lost. Will respond to address 0x10\r"
)
.unwrap();
let mut config = i2c::Config::default();
config.slave_address_7bits(0x10); // for arbitration lost test
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 = vals::Dir::READ;
let mut counter = 0;
let mut result: Option<Error> = None;
// start of the actual test
i2c.slave_start_listen().unwrap();
loop {
counter += 1;
writeln!(&mut writer, "Loop: {}\r", counter).unwrap();
// content for test 0x10
buf_2[0] = 0xFF;
buf_2[1] = 0x03;
_ = i2c.slave_write_buffer(&mut buf_2, i2c::AddressType::MainAddress);
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();
match 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();
checkIsRead!(writer, dir);
match result {
None => {
writeln!(&mut writer, "Test 0x10 Passed\n\r").unwrap();
}
Some(err) => writeln!(&mut writer, "Test 0x10 Failed. Error: {:?}\r", err).unwrap(),
};
writeln!(&mut writer, "-----\r").unwrap();
}
_ => (),
}
}
}