SPI Communication Problem

I tried to send one byte via GPIO.SPIDataRW using the following code:

[i]If GPIO.SPISetup(1,100000)<0 Then
Print “SPI Setup failed!”
Print “SPI Setup successful!”
End If

Dim m As New MemoryBlock(4)
Dim Result As Integer

Print "Reply: "+Str(Asc((m.CString(0)))[/i]

Sending this byte works without any problem (I checked this with a logic analyzer).

Depending on the fact that this is a looped shift register, the “answer” to my byte should occur in cell m.Byte(0). But this does not happen, I always get the sent byte back as a reply.

Are my conclusions wrong?

It’s a heavy stuff, it seems … 100 views but still no answer :-))

The documentation to GPIO.SPIDataRW says:

	// This performs a simultaneous write/read transaction over the selected SPI bus.
	// Data that was in your buffer [b]is overwritten by data returned from the SPI bus[/b].

Did anyone have success so far in trying this function with XOJO ?

Another question is:

What does the documentation mean with using the standard read() and write() system calls ?

	//  It is possible to do simple read and writes over the SPI bus using the standard read() and write() system calls though

In case they shed more light on this, the source docs for SPIDataRW are here: http://wiringpi.com/reference/spi-library/

Thanks, Paul, for the tip, but there I find the same text that I quoted here …

@Paul Lefebvre:

I finally found the bug by myself - GPIO.SPIDataRW is only ONE WAY!

The documentation to GPIO.SPIDataRW says:

// This performs a simultaneous write/read transaction over the selected SPI bus.

In reality this function does not allow to read back a value!

You can alter this by using Pointers instead of CStrings (because CStrings can not be overwritten by the GPIO.SPIDataRW function).

I think this should be altered in the delivered function and the documentation of the SPI feature of the GPIO module

If you think this is a problem with the Xojo GPIO library, submit a pull request to the GitHub project so that we can update it: https://github.com/xojo/GPIO

If the official WiringPi functionality wrong then you should report that to the WiringPi folks. The Xojo GPIO library simply maps the the official WiringPi library: http://wiringpi.com/contact/

No Paul, wiringPi works. Your implementation can only write. I’ve used a variation to RW on SPI (for a working RFID reader)

Protected Function SPIDataRW1(channel As Integer, data As Ptr, len As Integer) as Integer

#If TargetARM And TargetLinux Then
Soft Declare Function wpWiringPiSPIDataRW Lib “libwiringPi.so” Alias “wiringPiSPIDataRW” (channel As Integer, data As Ptr, len As Integer) As Integer
Return wpWiringPiSPIDataRW(channel, data, len)
End Function

I use it with memory block in calls like:
ok= GPIO.SPIDataRW1(channel, mm, mm.size)
where mm is a memory block
the contents when you exit is what you need

I see what you mean now. That should be easy enough to change. Do you think there is benefit in keeping the version that is there with CString? Or is one using Ptr the only practical way to go here?

Teorically the Cstring version could be a write only , but since you can ignore the change (if any ) in the memory block one I would go with using Ptr.

I named it RW1 just to be compatible with your lib

I also think that the RW version is better - if someone needs only writing, he could also use the RW version without caveats. But if there is only the write version, beginners like me have problems to find the right solution for RW.

To avoid confusion you could create a SPItransfer method (that’s how generally is called)
some thing like:

function SPItransfer(channel as integer, m as memoryblock) as memoryblock
dim blockToReadWrite as memoryblock

if SPIDataRW(channel, blockToReadWrite, blockToReadWrite)>0 then
return blockToReadWrite
return Nil
end if
end function

That’s for:
1- the size of what you read is the same of what you write
2- the contents of you what you write is overwritten and someone could be surprised by this side effect
3- return nil is, for many, a more clear indicator that something went wrong

I have pushed an update to GitHub with the correct method signature for SPIDataRW. Thanks Friedrich and Antonio!


When you have time correct the usage note. You left the RW1 of my “compatible” function instead of RW.