embedded-hal icon indicating copy to clipboard operation
embedded-hal copied to clipboard

spi: interdependent operations/operations sharing data

Open jordens opened this issue 11 months ago • 1 comments
trafficstars

There is currently no support for SPI operations (in a transaction slice) to mutably share data.

Use case: SPI devices often implement the following behavior (happy to provide numerous examples if this is in doubt) to implement an atomic update of several bits.

  • Load "active" bits into the SPI shift register (that sits between SDI and SDO) on CS assertion.
  • Load new bits from shift register into "active" register on CS deassertion.

The intention is to implement a read of the active bits without altering them (not even a transient alteration).

The approach would be to keep CS asserted accross a transaction of reading and writing the same values again.

let mut bits = [0; 4];
spi_device.transaction(&mut [Operation::Read(&mut bits), Operation::Write(&bits)]);

This is currently not possible with the Operation enum.

jordens avatar Nov 25 '24 16:11 jordens

I just encountered the same issue.

Not sure how it could be solved exactly, maybe using Borrow/BorrowMut (i.e. it needs to work like a RefCell without the runtime overhead), or by making transaction take a closure instead of a slice of operations? In any case it will be a breaking change.

For now, I am using a hacky workaround, treating Operation::Write(&[]) followed by Operation::DelayNs(0) in a special way to mean “write the last read value” by storing the last read buffer in the SpiDevice implementation. Of course, this makes the code unportable, defeating the point of using embedded_hal in the first place.

reitermarkus avatar Jun 13 '25 11:06 reitermarkus