-
Notifications
You must be signed in to change notification settings - Fork 212
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Async SPI transaction with [write, read] operation broken on esp32 #2059
Comments
Thanks for the snippet, mind making it bigger? Is that with DMA? If so, how big are the buffers? |
Yes, with async fullduplex DMA with buffer length of 1024. edit: I can't seem to reproduce this with single device based HIL test though. |
@Dominaezzz I managed to find some kind of "anomaly": let write_buf = &[0xaa];
let mut read: [u8; 2] = [0xff; 2];
let mut ops = [Operation::Write(write_buf), Operation::Read(&mut read)];
let _ = spi_dev.transaction(&mut ops).await;
defmt::info!("Test 1... result: {:?}", read);
// why do we get 0xff, 0xff here?
assert_eq!(read, [0xff, 0xff]);
let write_buf = &[0xaa];
let mut read: [u8; 1] = [0xffu8; 1];
let mut ops = [Operation::Write(write_buf), Operation::Read(&mut read)];
let _ = spi_dev.transaction(&mut ops).await;
defmt::info!("Test 2... result: {:?}", read);
// ... but 0x00 here?
assert_eq!(read, [0xff]); Self contained test-case can be found from here: https://github.com/plaes/rust-lilygo-ttgo-lora32/blob/c79b7f0cb16310beaee593b894472bdf5e45adb0/src/spi_dma_transaction.rs#L79-L93 |
Try changing I'm curious to see if the driver isn't writing anything to the buffer at all or if it's write 1s (from a pull up or something). |
Well, no pullup issue:
|
Does the same happen for blocking mode? |
I haven't yet figured out blocking + DMA + transaction, but blocking + transaction gives following output:
|
I've been able to reproduce it. (Without your full example I wouldn't have been able to, it only comes out in particular circumstances it seems) |
Basically, it seems once a write happens, reads stop working correctly. Only one byte is read. Happens in both blocking and async mode at least, and it seems the peripheral itself just won't return more data to the DMA. transfer also doesn't work correctly after a write is done With a larger buffer to read, the read works as expected until the last 8 bytes.... I'm able to reproduce this with older commits, I can reproduce it before the DMA Move Api PR at least 😅 . transfer then read is fine, but write then read is not.... hhmmm |
It appears to be a silicon bug in the base ESP32. This stuff should really go in the errata. Looks like the ESP32 will need special logic in the SPI driver.... 😞 |
To reproduce, take the |
I also see problems on ESP32-S2: there a |
I have a driver that does spi.transaction with sequential write and read operations.
It seems that whenever the
read_buffer
is longer than one byte, it doesn't get updated with read data, ie with this coderead_buffer
still contains[0xa, 0xa, 0xa, 0xa]
after transaction.This is issue is present with 0.20.1 and current HEAD c5e342a
The text was updated successfully, but these errors were encountered: