Skip to content
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

Allow to change SPI mode #708

Open
sre opened this issue Dec 5, 2023 · 6 comments
Open

Allow to change SPI mode #708

sre opened this issue Dec 5, 2023 · 6 comments

Comments

@sre
Copy link

sre commented Dec 5, 2023

Hi,

Right now SPI mode is configured when initializing the SPI bus controller. But in a shared SPI bus each device might require a different SPI mode. Please provide an API to change the SPI mode before doing a transaction.

Thanks,

-- Sebastian

@burrbull
Copy link
Contributor

Please add usage example.

How this API should look like?

@sre
Copy link
Author

sre commented Jul 28, 2024

I ran into this by having MAX31913 (mode 0) and TMC5072 (mode 3) being used on the same SPI bus.

I suppose ideally it would be similar to how Linux handles it with the mode being part of the SPI device instead of the SPI bus. Linux automatically configures the bus into the correct mode based on the device doing a transaction.

The alternative would be providing a bus function, which can be used to change the bus mode. Then this function needs to be called before doing a transaction.

Edit: My local workaround is using MODE 3 for both devices. This results in the first bit missing for the MAX31913 communication. This quick hack works for me, since I have nothing important connected to the matching input channel. But it is obviously is not a good general solution.

@burrbull
Copy link
Contributor

I suppose ideally it would be similar to how Linux handles it with the mode being part of the SPI device instead of the SPI bus. Linux automatically configures the bus into the correct mode based on the device doing a transaction.

I'm not familiar with Linux SPI. From your description looks like linux saves config for each device and dynamically changes it on each transaction.
But:

  1. embedded-hal traits does not know anything about connected device. So it will be incompatible with e-h.
  2. Changing context on each transaction can slow down connection + firmware growing.

The alternative would be providing a bus function, which can be used to change the bus mode. Then this function needs to be called before doing a transaction.

Manual switch looks more reasonable. Some spi.set_mode()? Should it wait for previous transaction to complete? Stop peripheral?

@sre
Copy link
Author

sre commented Jul 28, 2024

embedded-hal traits does not know anything about connected device. So it will be incompatible with e-h.

It got changed a little bit in 1.0, so that there is a SpiDevice, but it only knows about the chip select and not any other SPI information. But I agree that this solution would requires further extensions to the embedded-hal trait.

Changing context on each transaction can slow down connection + firmware growing.

IIRC Linux only changes the context if its needed by caching the information about the currently set mode. But obviously that needs some extra code and increases the firmware size.

Manual switch looks more reasonable. Some spi.set_mode()? Should it wait for previous transaction to complete? Stop peripheral?

Right. That obviously needs to wait for the previous transaction to complete, otherwise thins will break apart :) I quickly skipped over the TRM and it does not seem like the peripheral needs to be stopped to change CPOL/CPHA.

I just discussed this quickly at my Hackerspace and got one more suggestion, which should not require changing embedded-hal and does not require as many manual calls to spi.set_mode(): Allow creating two SpiBus instances for the same hardware like this:

  • STM32 SPI1
    • SpiBus in Mode 3
      • SpiDevice 1
      • SpiDevice 2
    • SpiBus in Mode 1
      • SpiDevice 3
      • SpiDevice 4

@burrbull
Copy link
Contributor

Looks like most legal is to just make custom SpiDevice implementation which set mode on each transaction. Not the fastest way, but simple and flexible.

@burrbull
Copy link
Contributor

@sre Could you test #523 if you have something which uses SpiBus::write ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants