-
Notifications
You must be signed in to change notification settings - Fork 574
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
[Proposal] Provide a Software implementation of the SPI protocol. #122
Comments
I believe what you ant here is the ability of having software SPI instead of hardware SPI as we have today. If that's the case, I would instead prefer having the device binding take in the GPIO pin numbers instead of taking in a device, and inside its implementation it would do the software SPI. This is the way that a lot of Adafruit device bindings work today as well. Here is an example of a binding already in our repo that does it: iot/src/devices/Mcp3008/Mcp3008.cs Lines 33 to 52 in a0afb05
As you can see, this binding will allow for you to initialize it with a spidevice, but it will also support you passing in the pin numbers manually and it will instead use GPIO to do a software SPI. |
I guess I was thinking it would be no different than passing in a UnixSpiDevice or a newly offered GpioSpiDevice for the abstract. You still have to pass in the pin numbers and settings info for a GpioController or GpioSpiDevice. As attempted here, you pass in the related info and the GpioSpiDevice creates the GpioController behind the scenes. I guess you could pass in the pin numbers and settings like you suggested and have the GpioSpiDevice be created behind the scenes for the binding. I like the GpioSpiDevice concept for a couple of reasons...
I have not had time, but think this same concept applies for a GpioI2cDevice, as well. |
There has been some changes lately around what to do with communication protocols. We now plan to create protocol interfaces, Once we have that, device bindings can have constructors like |
I think this should be something like |
Marking as up-for-grabs. The next step in this issue would be to send a PR with the software implementation of SPI protocol. Initially we would want to have it under the devices tree, and once we have the interfaces for the SPI protocol ready then we can move this to the main library. In terms of Api Surface, this class should have the same signatures as our regular SpiDevice, except that it would take pin numbers instead of Spi Channels and connection settings. |
I think the constructor would still use // Bus ID = 0, Chip Select Pin = 25.
var settings = new SpiConnectionSettings(0, 25)
{
ChipSelectLineActiveState = PinValue.High,
DataBitLength = 5,
DataFlow = DataFlow.LsbFirst,
// other properties set as needed.
}
// SCLK = 18, MISO = 23, MOSI = 24.
var spiDevice = new GpioSpiDevice(18, 23, 24, settings);
var myBinding = new MyBinding(spiDevice); |
@shaggygi do you feel this is still to be open? With all the recent addition to SPI and I2C, I feel this could be closed. |
@Ellerbach We have this one, but I was thinking it was eventually going to be moved within core API. We can go ahead and close for now. |
Core Objective
As a device binding producer, I would like the ability to instantiate the binding with a GPIO SPI implementation instead of redundant code to bit-bang logic within each binding. This would be similar to how a
UnixSpiDevice
orWindows10SpiDevice
is currently used to create a binding.NOTE: There is a "very early" prototype located here.
Use the Mcp23xxx binding and a UnixSpiDevice for example:
Having a
GpioSpiDevice
offering, there could be something like the following:NOTE:
chipSelectActiveLow
is active low in most cases, but some chips and hardware designs use active high.public GpioSpiDevice(int sclk, int miso, int mosi, SpiConnectionSettings connectionSettings, bool chipSelectActiveLow = true)
Therefore, you could pass in the GpioSpiDevice like below:
NOTE: Notice different modes can also be used and low-level should accommodate (assuming the device supports that mode 😄). Frequency (clock delay) is not currently coded in prototype.
GpioSpiDevice
would be located with the other current SpiDevice drivers.This might help with having abstract classes using the different types of interface devices. For example...
A few thoughts to point out
busId
doesn't really mean anything in this scenario. It could be ignored by creating an overloaded constructornew SpiConnectionSettings(chipSelectLine)
.chipSelectActiveLow
seems to be more for settings so it could be added to SpiConnectionSettings and defaulted to TRUE instead of passing intoGpioSpiDevice
constructor. So the following could be used:new SpiConnectionSettings(chipSelectLine, chipSelectActiveLow)
. This might confuse peeps when using for native interface and configured elsewhere. I'm on the fence with this.There is a proposal for a GPIO Toggle helper where it would help support logic in other areas, as well.
It would be nice to have some bit helper methods to perform MSB/LSB as this varies with components.
It would be nice to have a helper for PinValue.Low = false or PinValue.High = true. There is a proposal related to this here: [Proposal] Add ReadBool and WriteBool to GpioController #121
One other thing to point out, is how much code can be reduced like in the Mcp3008 binding. The current code to read via GPIO SPI shown below:
Basically, can use the same code as the ReadSpi method (replacing with the GpioSpiDevice, of course 😄):
As mentioned, this is just a prototype, but works. I'm still testing bits/modes and such.
Thoughts?
The text was updated successfully, but these errors were encountered: