So I've solved the problem with the
ESysfsSPITransfer: Cannot transfer <1> data byte(s) through SPI bus.
The C versions with the spi_ioc_transfer structure declared inside the
transfer() function work on both the Beagle and Pi3.
Here's the BBB version from and you can see the code is identical for both the
Pi and the Beagle.
https://github.com/derekmolloy/exploringBB/blob/version2/chp08/spi/spidev_test/spidev_test.c
==============================================================================================
uint8_t rx[ARRAY_SIZE(tx)] = {0, };
struct spi_ioc_transfer tr = {
.tx_buf = (unsigned long)tx,
.rx_buf = (unsigned long)rx,
.len = ARRAY_SIZE(tx),
.delay_usecs = delay,
.speed_hz = speed,
.bits_per_word = bits,
};
ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);
if (ret < 1)
pabort("can't send spi message");
==============================================================================
Here's the Pi version from exploringPi Chp08 spidev_test.c
struct spi_ioc_transfer tr = {
.tx_buf = (unsigned long)tx,
.rx_buf = (unsigned long)rx,
.len = ARRAY_SIZE(tx),
.delay_usecs = delay,
.speed_hz = speed,
.bits_per_word = bits,
};
ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);
if (ret < 1)
pabort("can't send spi message");
==============================================================================
Both identical.
So now let's look at the Lazarus Free Pascal version from inside the pxl
library PXL.Sysfs.SPI and see if there's anything different.
Data.tx_buf := PtrUInt(WriteBuffer);
Data.rx_buf := PtrUInt(ReadBuffer);
Data.len := BufferSize;
Data.delay_usecs := 0;
Data.speed_hz := FFrequency;
Data.bits_per_word := FBitsPerWord;
Res := fpioctl(FHandle, SPI_IOC_MESSAGE(1), @Data);
if Res < 0 then
raise ESysfsSPITransfer.Create(Format(SCannotSPITransferBytes,
[BufferSize]));
==============================================================================
Doesn't seem like there's any difference yet the Lazarus version fails. After
more searching on the net I stumbled onto a posting in a Pi forum where someone
else was having similar problems. A reply to his question was an example that
was working but unfortunately that link was "404 not found". However the
original poster did state what the difference between the working code and his
and his solution.
Now the Pascal version succeeds without an error. I've yet to check if SPI
data is showing up in hardware but I imagine it will. The good thing is the
runtime error is now gone.
FillByte(Data, Sizeof(Data), 0); // Without this FillByte() fpioctl fails.
Data.tx_buf := PtrUInt(WriteBuffer);
Data.rx_buf := PtrUInt(ReadBuffer);
Data.len := BufferSize;
Data.delay_usecs := 0;
Data.speed_hz := FFrequency;
Data.bits_per_word := FBitsPerWord;
Res := fpioctl(FHandle, SPI_IOC_MESSAGE(1), @Data);
if Res < 0 then
raise ESysfsSPITransfer.Create(Format(SCannotSPITransferBytes,
[BufferSize]));
It's likely the C compiler clears this structure when it's declared or extends
0's out on an assignment that isn't done by the FreePascal compiler. And that
it was required in that Pi forum posting for C code suggests it's perhaps even
somewhat random. Compiler flags maybe?
So that's the solution for this run time error. Clear the data structure
before initializing parameters and calling ioctl().
If I get a chance today I'll see if SPI data is actually coming out of the
processor but based on the sample application behavior it likely is.
John
--
For more options, visit http://beagleboard.org/discuss
---
You received this message because you are subscribed to the Google Groups
"BeagleBoard" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/beagleboard/01b401d75185%2465e25170%2431a6f450%24%40autoartisans.com.