Bus_SPI: restore SPI_USER_REG before releasing the bus lock - #271
Merged
Conversation
endTransaction() wrote SPI_USER_REG back to its idle value after spi::endTransaction() had already released the bus mutex. Another task that was blocked on the mutex could therefore have its own transaction configured and running when the late write landed and cleared ck_out_edge, which corrupts the next transfer of a mode 1/2 device sharing the bus (measured on ESP32-S3: same core / same priority as the panel task, ~1 hit per 100k chunks; none with the write moved inside the lock).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this changes
Bus_SPI::endTransaction()restoredSPI_USER_REGto its idle value (USR_MOSI | USR_MISO | DOUTDIN) afterspi::endTransaction()had released the bus mutex. This moves the restore above the unlock. One line, no behaviour change for a bus that is not shared.Why
Another task blocked on the mutex can already have its own transaction configured and running when the late write lands. The write clears
ck_out_edge, so a mode 1/2 device sharing the bus gets its next chunk on the wrong clock edge.Measured on ESP32-S3 (SPI panel at 40 MHz with DMA + a second task holding
SPI.beginTransaction(SPI_MODE2)and checkingck_out_edgeafter each 64-byte chunk):ck_out_edgelostThe window is only hit when the panel task is preempted between the unlock and the write (same core, tick round-robin). Mode-0 devices are unaffected either way (the late write equals what they program themselves) — a 5-minute SD card soak on the shared bus showed 0 errors before and after.