Reading SPI1 on BBB

I am having trouble reading from SPI1 on BBB. I am certain that I have the device overlay tree set up properly.

I do not have any sensor hooked up at the moment. On a scope, the CS and CLK pins are getting driven as expected (up to delays that I will play with later.

To debug the problem, I am driving the MISO pin with a square wave generator, and looking at what I read on the BBB. I am ultimately interested in reading a single uint16_t value, but for debugging I am reading in a uint32_t.

For MISO pulled to GND, I read all 0x00000000, for 3.3V I get 0xFFFFFFFF. For an infrequently transitioning square wave, the transition in the bitstream is not as expected. For a falling transition I would expect to get a pattern like this:

0xFFFFFFFF 11111111111111111111111111111111
0xFFFFFFFF 11111111111111111111111111111111
0xFFFFFFFF 11111111111111111111111111111111
0xFFFFFFFF 11111111111111111111111111111111
0xFFFFFE00 11111111111111111111111000000000 (If a rare transition falls in the middle of an spi frame read)
0x00000000 00000000000000000000000000000000
0x00000000 0000000000000000000000000000000
0x00000000 0000000000000000000000000000000
0x00000000 0000000000000000000000000000000

Instead, I get patterns like:
0xFFFFFFFF 11111111111111111111111111111111
0xFFFFFFFF 11111111111111111111111111111111
0xFFFFFFFE 11111111111111111111111111111110
0xFFFFFFF8 11111111111111111111111111111000
0xFFFFFFE0 11111111111111111111111111100000
0xFFFFFF80 11111111111111111111111110000000
0xFFFFFE00 11111111111111111111111000000000
0xFFFFF800 11111111111111111111100000000000
0xFFFFE000 11111111111111111110000000000000
0xFFFF8000 11111111111111111000000000000000
0xFFFE0000 11111111111111100000000000000000
0xFFF80000 11111111111110000000000000000000
0xFFE00000 11111111111000000000000000000000
0xFF800000 11111111100000000000000000000000
0xFE000000 11111110000000000000000000000000
0xF8000000 11111000000000000000000000000000
0xE0000000 11100000000000000000000000000000
0x80000000 10000000000000000000000000000000
0x00000000 00000000000000000000000000000000
0x00000000 0000000000000000000000000000000

Here is how I am settng my spi_ioc_transfer structure, along with some notes on a sweep I did on len:

#define RESPONSE_TYPE uint32_t
struct spi_ioc_transfer tr_azimuth[1];
memset(&tr_azimuth[0], 0, sizeof(tr_azimuth));
tr_azimuth[0].rx_buf = &rsp_azimuth; // Throws build time warning
tr_azimuth[0].tx_buf = 0; // NULL pointer is OK
//tr_azimuth[1].len = 0; // crash! Inappropriate ioctl for device
//tr_azimuth[0].len = 1; // No time varying data gets through
//tr_azimuth[0].len = 2; // No time varying data gets through
//tr_azimuth[0].len = 3; // No time varying data gets through
//tr_azimuth[0].len = 4; // 2 bit shift per read
//tr_azimuth[0].len = 5; // 1 bit shift per read
//tr_azimuth[0].len = 6; // 1 bit shift per read
//tr_azimuth[0].len = 7; // 1 bit shift per read
//tr_azimuth[0].len = 8; // 1 bit shift per read
//tr_azimuth[0].len = 9; // varying 0-1 bit shift per read
//tr_azimuth[0].len = 10; // varying 0-1 bit shift per read
//tr_azimuth[0].len = 11; // varying 0-1 bit shift per read
//tr_azimuth[0].len = 12; // 2 bit shift per read
//tr_azimuth[0].len = 13; // crash! bad file descriptor
//tr_azimuth[0].len = 14; // crash! bad file descriptor
//tr_azimuth[1].len = 15; // crash! bad file descriptor
//tr_azimuth[1].len = 16; // crash! bad file descriptor
//tr_azimuth[0].len = 8*sizeof(RESPONSE_TYPE); // in bits, causes crash!
tr_azimuth[0].len = sizeof(RESPONSE_TYPE); // in bytes
tr_azimuth[0].delay_usecs = 100;
tr_azimuth[0].speed_hz = 100000;
tr_azimuth[0].bits_per_word = sizeof(RESPONSE_TYPE)*8;
tr_azimuth[0].cs_change = 1;
int ret_azimuth = ioctl(fd_azimuth, SPI_IOC_MESSAGE(1), &tr_azimuth);

Does anyone have an example that is known to work on BBB with angstrom? I’m not sure if I’m configuring the struct improperly, or if the spi drivers are just new and buggy. They certainly aren’t that well documented; some of the units (bits vs. bytes) for the struct fields aren’t even there.

If there is an angel out there who knows linux spi driver stuff and can point me in the right direction, I would be grateful for all eternity!

Did you disable the HDMI?


Preferably start using half-duplex access on spidev. Using IOCTL to set bits per word, mode and frecuency. If that works you can try “full-duplex” mode using spi_ioc_transfer struct. After setting parameters with ioctl just read with read :slight_smile:

You can learn by looking py-spidev code which is a Python wrapper for spidev.

The compiler warning is probably due to your calling a function
without a prototype in scope; I’d have to see more of the code
for a more exact answer, but it’s something you definitely need
to fix.

Have you tried the spidev_fdx.c and spidev_test.c programs from
the Documentation/spi directory?