SPI in .NET Core on Torizon

I’m having good success with accessing GPIO, UART and Ethernet from .NET Core running in a container on Torizon on an iMX7. The next thing I want to demonstrate is access to an SPI port.

There is a class available called System.Device.Spi.Spi.Drivers.UnixSpiDevice which looks promising. It contains low-level methods to read and write bytes over the SPI bus, that’s all I need. But how do I use this class in practice?

The constructor for UnixSpiDevice takes a parameter of type SpiConnectionSettings, and the constructor for that class is SpiConnectionSettings(int busId, int chipSelectLine). What do I pass in as busId? For chipSelectLine do I just use the Linux GPIO number of the pin I want to use as a chip select?

I can’t find any documentation online for these classes. Are they standard parts of .NET Core which are provided by Microsoft?

Currently the implementation relies on /dev/spidev being exposed by the kernel. Currently our configurations don’t enable any SPI device. I’ll put this in our own internal to-do list, but can’t give you any timeline or even an answer about wether we will support such a feature.

Thanks for your reply @valter.tx. Using SPI is a core feature that we need to access on the SoCs, and I’m sure it is for other people too, so I’d like to encourage you to give this a reasonably high priority.

What I’ll try while I wait for you is to run .NET Core on bare Linux without using Torizon to see if I can access SPI that way.

It depends on how the linux kernel is configured.
If you have a /dev/spidev*.* device available then you can access it from the .NET app (and, of course, share it inside a container).
You may enable this also on Torizon, using device-tree overlays, but ATM we don’t have documentation about this and writing those overlays isn’t exactly intuitive.

I installed a non-Torizon Linux image via Toradex Easy Installer. The version reported by uname is 4.9.166-2.8.6+gd899927728be. But this image has no SPI devices in /dev either so that doesn’t really help me.

I see that you are using imx7. For that platform you need to change the device tree and rebuild your image to have SPI enabled:

Thanks for that pointer. I have .NET Core up and running on my iMX7 with bare Linux (Not Torizon). The next step is to get control of that SPI port following the link that you posted.

@valter.tx, I need a bit of help with modifying the device tree. I learned how to modify the device tree for Torizon by simply editing the .dts file, recompiling the device tree, copying the new device tree to /boot/ostree and then rebooting. But there is no /boot/ostree folder now that I am working with the non-Torizon image. I think that means that what I need to do is to edit the .dts file, then rebuild the entire kernel, then install the new kernel into my module. Can you confirm that this is correct?

The image I currently have installed is Linux colibri-imx7-emmc 4.9.166-2.8.6+gd899927728be. Can you tell me which branch of the source code from linux-toradex.git - Linux kernel for Apalis, Colibri and Verdin modules I should use to match the image which I have installed? I can’t figure out which branch name matches the installed kernel version.

I think I know how to build the kernel, but can you point me towards a page that tells me how to install it after I build it?

@valter.tx I just noticed that the dtb file in the non-Torizon image is stored here /media/mmcblk0p1/imx7d-colibri-emmc-eval-v3.dtb. Can I just overwrite that file with a new version and then reboot the module, without having to actually build and update the whole kernel?

@MikeS

Yes as you have noticed in our non-torizon Linux the device tree and kernel binaries are stored on a separate boot partition as opposed to in the root file system. Changing the binaries there should update the binary after a quick reboot.

Hi MikeS,
I am also interested on this Topic, will follow, hope they do a better Job on SPI Interface as with WEC 2013.

With best regards

gerhard

Thanks @jeremias.tx, that makes sense and looks pretty straightforward. I’m going to use the device tree source code in the toradex_4.14-2.0.x-imx-next branch. Is that branch a good guess to match the Linux colibri-imx7-emmc 4.9.166-2.8.6+gd899927728be kernel which is installed on my iMX7?

@MikeS

The tables on this document show which kernel version goes with which BSP version and such: Build U-Boot and Linux Kernel from Source Code | Toradex Developer Center

@valter.tx and @jeremias.tx I was traveling for a while so was delayed in trying your suggestions. Today I was able to edit the device tree to get access to the spidev driver with regular embedded Linux (Not Torizon), and I was also able to edit the device tree to assign multiple chip select pins to the SPI device. I was then able to open the SPI port using .NET Core and write data to the port.

So I’m all set for now on this topic. I’m going to develop my application using regular Linux rather than Torizon for now because access to SPI is a key requirement for our system. I would like to test SPI with Torizon in the future when you are ready, so please do keep encouraging the Torizon team to add support for it.

One thing that slowed me down a bit is that the tables on Build U-Boot and Linux Kernel from Source Code | Toradex Developer Center are a bit out of date. I’m using image 2.8b6 which isn’t in the table on that page. But by looking at the tag in git for that image I figured out that the branch it came from was toradex_4.9-2.3.x-imx-next, although I don’t think any of the device tree files changed between branch toradex_4.9-2.3.x-imx for image 2.8b5 and branch toradex_4.9-2.3.x-imx-next for image 2.8b6.

One other lesson that I learned the hard way is that if I reset the Colibri too quickly after copying the new device tree into /media then the file is discarded and the module boots using the previous device tree. This caused me a bit of head scratching about why my device tree changes were having no effect before I realized what was going on and started to wait for the cache to be flushed before resetting the module. Is there a command that can be used at the prompt to flush cached writes out to flash?

@MikeS

Glad to hear you got SPI going, we’ll make sure to keep you posted on any updates with SPI in Torizon. The issue is in the team’s queue currently.

As for your file writing issue, in linux there is a command line utility called “sync” (sync(8): synchronize data on disk with memory - Linux man page). You should run this after any significant changes to the file system to allow it to “settle”.

@MikeS,

The latest nightly builds of Torizon on our continuous integration feeds off of our easy installer should now have the fix that adds spi devices.

Let me know if there are any further issues regarding SPI.

Best Regards,
Jeremias

Just confirming that SPI support does work in the newer builds of Torizon in a nice, simple way with no configuration required.

That’s good to hear.

Best Regards,
Jeremias