SpiDma read/write: copy as little as possible#5290
SpiDma read/write: copy as little as possible#5290bugadani wants to merge 19 commits intoesp-rs:mainfrom
Conversation
|
New commits in main has made this PR unmergable. Please resolve the conflicts. |
| if copy_before > 0 { | ||
| self.write_async_impl(MaybeCopyTxBuf::Copy(tx_buffer), &words[..copy_before]) | ||
| .await?; | ||
| } |
There was a problem hiding this comment.
This cries for a "block for short transfers" setting. Whether we want that even for CPU-controlled async transfers is a good question, I think really fast SPI busses justify it.
This comment was marked as outdated.
This comment was marked as outdated.
38fd120 to
85d8576
Compare
5e99f7f to
38a1636
Compare
|
/hil full |
|
/test-size embassy_spi esp32s3 |
Binary Size Report
|
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
|
Triggered full HIL run for #5290. Run: https://github.com/esp-rs/esp-hal/actions/runs/23854189810 Status update: ❌ HIL (full) run failed (conclusion: failure). |
| #[cfg(esp32)] | ||
| if !(buffer.as_ptr() as usize).is_multiple_of(4) { | ||
| return false; | ||
| } |
There was a problem hiding this comment.
I'll highlight this just to mention that I don't want to bother with this PR any more just to get it to work on ESP32. We still skip copying if the data is aligned, but resolving this here would take probably more changes than this PR needs to have. The solution would be to add a copy buffer to MaybeCopyTxBuffer::Direct, and pipe it through prepare_for_tx, but it can be done in the future if we really need to do it.
|
New commits in main has made this PR unmergable. Please resolve the conflicts. |
|
New commits in main has made this PR unmergable. Please resolve the conflicts. |
be7262a to
c3da565
Compare
f66878d to
09ff5b1
Compare
09ff5b1 to
44dbde7
Compare
44dbde7 to
049b4c1
Compare
| #[cfg(esp32s2)] | ||
| if _direction == TransferDirection::In | ||
| && !((buffer.as_ptr() as usize).is_multiple_of(16) | ||
| && buffer.len().is_multiple_of(16)) | ||
| { | ||
| // When EDMA accesses external RAM, fields in linked list descriptors should be | ||
| // aligned with block size. Specifically, size and buffer | ||
| // address pointer in receive descriptors should be 16-byte, 32-byte or 64-byte | ||
| // aligned. For data frame whose length is not a multiple of 16 bytes, 32 bytes, | ||
| // or 64 bytes, EDMA adds padding bytes to the end. | ||
| // | ||
| // FIXME: the above should be handled by `prepare_for_rx`, but for now we just | ||
| // skip the no-copy optimization. | ||
| return false; | ||
| } |
There was a problem hiding this comment.
Makes me wonder why AES doesn't have this issue - are we lucky with the tests?
1e2fb66 to
9c1aa53
Compare
9c1aa53 to
7fa46f6
Compare
Using code developed for AES DMA, this PR tries its best to avoid copying data before DMA-enabled SPI transfers. This PR enables us to send/receive data to/from DRAM and PSRAM without configuring copy buffers.
Non-copying transfers are disabled on ESP32 for unaligned data. ESP32 is the only device we have that requires a TX-side copy buffer due to alignment requirements, and the code we've had for AES-DMA doesn't implement that yet.
Closes #3125 by removing most of the copying that a display driver would do.