You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This is related to #176 but since it also affect the non-async api I figured it deserves it's own issue.
As discussed in #176 (comment), according to several non-official sources, SD cards that share the bus with other slaves need to be sent a dummy 0xFF byte with CS deasserted after every communication, before communicating with other slaves. Otherwise a bus conflict can occur.
If you share the SPI bus with other slaves, always send another "dummy" byte (or more) with the CS line inactive (high) after each communication to the SD card before accessing other slaves. Otherwise, the SD card will keep the DO/MISO ((master in slave out)) output active and cause two slaves to drive/short-circuit the MISO line! So: CS low, exchange data with SD card, CS high, send dummy data (e.g. one byte 0xFF), then you can communicate with other slaves.
In the SPI bus, each slave device is selected with separated CS signals, and plural devices can be attached to an SPI bus. Generic SPI slave device enables/disables its DO output by CS signal asynchronously to share an SPI bus. However MMC/SDC enables/disables the DO output in synchronising to the SCLK. This means there is a posibility of bus conflict with MMC/SDC and another SPI slave that shares an SPI bus. [...] Therefore to make MMC/SDC release the MISO line, the master device needs to send a byte after the CS signal is deasserted.
I brought this up on matrix and the conclusion was that this requirement is fundamentally not compatible with the SpiDevice trait. Workarounds like using a second SpiDevice don't solve the problem. This applies to both the blocking and the async versions because in both cases there's no way to guarantee that other tasks or threads don't sneak in and use the bus between the main communication and sending the dummy byte.
The solution proposed in chat and in rust-embedded/embedded-hal#478 is to define a new trait SdCardDevice and provide impls for (OutputPin, &RefCell<SpiBus>), (OutputPin, &Mutex<SpiBus>), (OutputPin, SpiBus) (for exclusive use of the bus) that have the desired behavior. This still allows the bus to be shared with other devices by using embedded-hal-bus types. If backwards compatibility is important there could also be an impl for SpiDevice that keeps the current possibly incorrect behavior.
This seems like a feasible approach but it adds some boilerplate to the crate and probably an optional dependency on embassy-sync to allow users to share the bus in embassy projects. I'm happy to give this a go but I wanted to first ask if these downsides are acceptable. embasys-sync is not 1.0 yet so this would add a small maintenance burden.
This is related to #176 but since it also affect the non-async api I figured it deserves it's own issue.
As discussed in #176 (comment), according to several non-official sources, SD cards that share the bus with other slaves need to be sent a dummy
0xFF
byte with CS deasserted after every communication, before communicating with other slaves. Otherwise a bus conflict can occur.https://electronics.stackexchange.com/a/602106/256470
http://elm-chan.org/docs/mmc/mmc_e.html#spibus
I brought this up on matrix and the conclusion was that this requirement is fundamentally not compatible with the
SpiDevice
trait. Workarounds like using a secondSpiDevice
don't solve the problem. This applies to both the blocking and the async versions because in both cases there's no way to guarantee that other tasks or threads don't sneak in and use the bus between the main communication and sending the dummy byte.The solution proposed in chat and in rust-embedded/embedded-hal#478 is to define a new trait
SdCardDevice
and provide impls for(OutputPin, &RefCell<SpiBus>)
,(OutputPin, &Mutex<SpiBus>)
,(OutputPin, SpiBus)
(for exclusive use of the bus) that have the desired behavior. This still allows the bus to be shared with other devices by usingembedded-hal-bus
types. If backwards compatibility is important there could also be an impl forSpiDevice
that keeps the current possibly incorrect behavior.This seems like a feasible approach but it adds some boilerplate to the crate and probably an optional dependency on
embassy-sync
to allow users to share the bus in embassy projects. I'm happy to give this a go but I wanted to first ask if these downsides are acceptable.embasys-sync
is not 1.0 yet so this would add a small maintenance burden.cc @Be-ing
The text was updated successfully, but these errors were encountered: