« Close

Datasheets and User Guides

App Notes

Software & Driver

 

4.3.10 - SPI Serial Communication

The U3 (hardware version 1.21+ only) supports Serial Peripheral Interface communication as the master only. SPI is a synchronous serial protocol typically used to communicate with chips that support SPI as slave devices.

This serial link is not an alternative to the USB connection. Rather, the host application will write/read data to/from the U3 over USB, and the U3 communicates with some other device using the serial protocol. Using this serial protocol is considered an advanced topic. A good knowledge of the protocol is recommended, and a logic analyzer or oscilloscope might be needed for troubleshooting.

There is one IOType used to write/read data over the SPI bus:


LJ_ioSPI_COMMUNICATION // Value= number of bytes (1-50). x1= array.

The following are special channels, used with the get/put config IOTypes, to configure various parameters related to the SPI bus. See the low-level function description in Section 5.2.15 for more information about these parameters:


LJ_chSPI_AUTO_CS
LJ_chSPI_DISABLE_DIR_CONFIG
LJ_chSPI_MODE
LJ_chSPI_CLOCK_FACTOR
LJ_chSPI_MOSI_PIN_NUM
LJ_chSPI_MISO_PIN_NUM
LJ_chSPI_CLK_PIN_NUM
LJ_chSPI_CS_PIN_NUM

Following is example pseudocode to configure SPI communication:


//First, configure the SPI communication.

//Enable automatic chip-select control.
AddRequest(lngHandle, LJ_ioPUT_CONFIG, LJ_chSPI_AUTO_CS,1,0,0);

//Do not disable automatic digital i/o direction configuration.
AddRequest(lngHandle, LJ_ioPUT_CONFIG, LJ_chSPI_DISABLE_DIR_CONFIG,0,0,0);

//Mode A:  CPOL=0, CPHA=0.
AddRequest(lngHandle, LJ_ioPUT_CONFIG, LJ_chSPI_MODE,0,0,0);

//Maximum clock rate (~100kHz).
AddRequest(lngHandle, LJ_ioPUT_CONFIG, LJ_chSPI_CLOCK_FACTOR,0,0,0);

//Set MOSI to FIO2.
AddRequest(lngHandle, LJ_ioPUT_CONFIG, LJ_chSPI_MOSI_PIN_NUM,2,0,0);
	
//Set MISO to FIO3.
AddRequest(lngHandle, LJ_ioPUT_CONFIG, LJ_chSPI_MISO_PIN_NUM,3,0,0);

//Set CLK to FIO0.
AddRequest(lngHandle, LJ_ioPUT_CONFIG, LJ_chSPI_CLK_PIN_NUM,0,0,0);

//Set CS to FIO1.
AddRequest(lngHandle, LJ_ioPUT_CONFIG, LJ_chSPI_CS_PIN_NUM,1,0,0);

//Execute the configuration requests.
GoOne(lngHandle);

Following is pseudocode to do the actual SPI communication:


//Transfer the data.
eGetPtr(lngHandle, LJ_ioSPI_COMMUNICATION, 0, &numBytesToTransfer, array);

8 comments

Hi,

I've used the code above for implementing an SPI interface. So far so good. When I call the eGet function, the bit pattern is shown on my scope. When I call the same eGet function again to transfer another set of bytes, nothing happens anymore. How can I use the eGet (or another function) for transfering SPI data repeatedly? I have an U3-HV with the most recent firmware and driver.

Thanks in advance,

Martin

Just tested this with our LabView example. It worked well. What language are you using? Have you looked at the examples? If the examples do not help send a simple project to support@labjack.com and we will take a look at it.

Thanks! I am using the .net driver in c#. It is using the shown example code, except that the eGet function is behind a button.

Martin

ElectroLund's picture

I'm using basically your example above, but more closely to the example code (VC6).

Without any SPI device connected to the port pins, I'm merely trying to make sure I can wiggle the SCK and MOSI pins first.  No loopback or anything.

And yet, the pins just don't do anything.  I double-checked wiring and configuration reset before attempting SPI.  In the VC6 example, the data word is a multi-byte array (dataArray).  When the write line is executed:

lngErrorcode = eGet(lngHandle, LJ_ioSPI_COMMUNICATION, 0, &numSPIBytesToTransfer, pdataArray);

my dataArray contents get wiped to 0xFF.  So that seems weird, not being connected to an SPI peripheral.

LabJack Support's picture

When performing the eGet LJ_ioSPI_COMMUNICATION call, in the one call you are sending the passed byte array over the MOSI line and the array gets updated with the read bytes over the MISO line. With no signal/connection to the MISO lines, your read data bytes (pDataArray) by default will all be 0xFF. For a quick test, connect one of the U3's GND lines to your MISO line which should then read back bytes of all zeros. This will help confirm your MISO line is receiving data on the expected pin number. The comments at the top of the SPI.c example discusses connections and the expected read bytes when the MISO line is connected to the MOSI line (loopback), GND (zeros) and nothing/VS line (0xFFs).

If you are still running into issues, how are you configuring your SPI settings and what are you wiggling to what digital lines?

ElectroLund's picture

Ah, sorry about that.  I didn't see that note.  Along with some bad scope triggering, I just wasn't seeing the clock output toggling.  Now I'm getting data bursts as expected, with a 80kHz clock.  All very good.  

When I connect the MISO to MOSI, I obviously see data on the scope mirroring the input.  But strangely, software only ever sees 0xFF, regardless of MISO connection, even to GND!

LabJack Support's picture

Can you provide your LJ_chSPI_MOSI_PIN_NUM and LJ_chSPI_MISO_PIN_NUM configuration calls? Perhaps you are not connecting to the correct digital I/O lines on your U3. Also, make sure you have a good connection to the U3s screw terminals. Connect to the inside of the terminal and not on the screw head.

ElectroLund's picture

Argh, one of those days.  You were right.  Simply bad connections into the LabJack.  Thanks for great help!  I'm off and running now.