Hobbyist Toolkit

Showing results for 
Search instead for 
Did you mean: 

SPI not at its max speed with LINX on rPI



I was making some tests with LINX (LV2020 CE) and the SPI ports provided on the rPI 4.

I appears that there is a speed issue with the LINX driver.


Indeed, I was trying to see how fast I could communicate on a SPI bus with LINX. And I noticed immediately that the CS duration is very LOOOOOOOOOONG !

So I went further in my investigation.


To be clear, SPI clock and MOSI signals are handled with the dedicated SPI driver of the rPI. That's fine !

But using LINX you have to specify the CS line to be used. And here comes the problem : you can't specifiy the specific CS line driven by the rPI's SPI driver !

The CS you specifiy has to a GPIO. That's great if you have to handle many devices on the SPI port, but only if you're not trying to reach the fast communication speed.

Indeed, controlling a GPIO takes time ! And LINX first set the CS GPIO line state, then give the data to send to the native rPI's SPI driver, wait for the communication to end, and turns the CS line back to its initial state.

To give an idea, at 32MHz, we spend 80% of the time not emitting data nor clock ! 80% of the time is taken for the CS to go down and then go up again at the end of transmission !


Digging a bit more, it appears that the specific CS line driven by the SPI driver works well. In my case, CS1 was going low then back high when transmitting of the port. It means that the SPI driver works well and perfectly does its job.

However, as LINX is controlling the CS line specified (GPIO), you cannot send a new message until this GPIO goes back to high state.

Which means that, even if you want to use the native CS line, you have to wait because LINX drives a GPIO.


Too bad !


Would it be possible to updgrade the LINX driver and allow people to specifiy the native CS lines operated by the rPI SPI driver ?

In that case, LINX wouldn't have to wait for the GPIO to go down and up.

If people set the CS deliberately on a GPIO line, then LINX would wait for the CS line to operate.

CLA, CTA, LV Champion
View Cyril Gambini's profile on LinkedIn
This post is made under CC BY 4.0 DEED licensing
0 Kudos
Message 1 of 4

Cyril and I have already chatted on Twitter about this but I wanted to also provide this info here as well as some other insights on the Linx Toolkit.


My suspicion is that nearly every Linx function is implemented to work across BeagleBones and Pis as identically as possible, or just in a naive manner, perhaps with the intention of providing more flexibility, without realizing how it would impact usage. Since these implementations are in lower level libraries compiled for the specific boards I find it unlikely to be fixed anytime soon. Maybe someone knows whether or not these lower level shared libraries are open sourced somewhere? They don't appear to be in the MakerHub/Linx github.


Back when Linx was only available for 2014 someone developed their own library for the Pi that can fully utilize the hardware CS functionality which you can find info on at https://www.labviewmakerhub.com/forums/viewtopic.php?f=12&t=2145 and I'm pretty sure I saw that people got it working with the 2020 CE Beta version.


Given enough time I'm sure people will be developing all sorts of these types of libraries to fully realize each platform's hardware potential. Hopefully down the road NI finds a workflow for integrating these platform differences into the officially supported libraries.

0 Kudos
Message 2 of 4

Indeed, having access to the source code used to create the .so file that LINX works with would be greatly appreciated.


But even with that, you must have some advance knowledge to compile a custom for the targets (cross-compiling env, somme good Linux knowledge,...).

Which is not what's expected for people people working with LabVIEW (G libs are used to make abstraction of such 'constraints').

Here LINX can be used to run code on TWO targets (rPI and BeagleBone, Arduino apart because the custom code do not really run on the target). With such low number of hardware supported (I understand that this number may increase in the years to come) I would have expected that specific IOs would have been handled more 'specifically' (based on directive target HW).


Here for SPI on a rPI, you've got a specific service that can handle the SPI on a very elegant way. The weakness of the design of the rPI is that it only exposes 2 CS lines (on the header). These two lines are very well known and documented, they are not 'dynamically' set.

Therefore, it would have been great if the LINX .so lib distinguished the line number requested for the CS. If the CS line requested is a native CS line, they plenty use the original driver. If the CS line is not one of the reserved lines, then yes control a GPIO.


To be more generic, this tool now being integrated within the LabVIEW IDE, I would have expected the same 'rigourousness' (might not be the correct word here, sorry for my lack of English vocabulary) that we can find using NI DAQ cards : getting the most of the HW capabilities with a 'simple' driver.


But I'm sure that the tool will evolve and we will have nice surprises in future releases, don't we ? 🙂

CLA, CTA, LV Champion
View Cyril Gambini's profile on LinkedIn
This post is made under CC BY 4.0 DEED licensing
0 Kudos
Message 3 of 4

@CyGa wrote:

Indeed, having access to the source code used to create the .so file that LINX works with would be greatly appreciated.

You actually have the sources for that on your computer. It is inside <Program Files x86>/LabVIEW 20xx/vi.lib/MakerHub/LINX/Firmware. Also the entire Linx source tree is also here on Github.


That said, the library does indeed do custom CS handling in ADDITION to whatever the device driver does. And since Linx does no disable the CS handling in the driver, it will work with whatever the configured CS signal is for that driver. Default this is CE1 for the only Linx supported SPI channel 1. I'm not quite sure why they didn't add SPI channel 0 as well to the supported list. You should be able to specify a different GPIO pin for the CS handling in the /boot/config.txt file on the line for the SPI. Currently there is no way to disable the custom CS handling. So you have to use a GPIO pin that is not used for anything else.


As to expecting the same experience as with DAQmx, that is a bit far fetched. For one the Linx Toolkit for LabVIEW 2020 was mainly just cleaned up a little to make it work with LabVIEW 2020 and newer hardware. They don't have a team of zillion software developers that all work on the Linx Toolkit. The project was largely developed as voluntary project by non NI empleyees with some help from NI engineers and will likely stay like that for the time being. As it is not selling hardware for NI they are not going to spend huge development teams on it. DAQmx is a middleware that helps sell the NI hardware and its development is paid through that. For Linx that doesn't work like that.


If you want to see improvements in Linx you will have to sit down and work through the sources and understand it all and then after that create a pull request from your changes to the original Makerhub github repository. Do not expect NI to make Linx a full blown DAQmx replacment. That is never going to happen.

Rolf Kalbermatter
My Blog
Message 4 of 4