LabVIEW Embedded

Showing results for 
Search instead for 
Did you mean: 

SPI communication between ARM MCU and ADC


Hi everybody,


I've made a test circuitboard with a Luminary LM3S1968 MCU and an Analog AD7738 ADC for testing SPI communications between a ADC and an ARM MCU in LabVIEW. Basic hardware tests (UART read/write, 'blink-a-led') went fine, but SPI communication is a problem.


  • The LM3S1968 has two SSI ports for SPI communication, 0 and 1. Selecting and using port 0 works OK (nice pulse train), selecting 1 gives no result (just DC on the oscilloscope). I select the port by wiring the desired integer to the SPI subvi and I've added 'LM3S_PART_DEFINED PART_LM3S1968' to the build specification. It could be a (very specific) hardware failure, but I've got a feeling that it might be a software problem (missing define in the code for instance).
  • Attached to this post is a simple VI for acquiring one 16-bit sample from analog channel 0. It's basically figure 7, page 21 from the ADC's datasheet: When I run this VI, the outgoing pulsetrain looks OK on my oscilloscope, but I always get 255 as a return value. This might be a hardware failure, but can anyone please review the code and give comments? My ultimate goal is to continuously acquire 24-bit samples for all the 8 channels and convert them to U32 format (since U24 isn't an option).

Tomorrow I'll check the device for electrical problems, but suggestions for the LabVIEW program are greatly appreciated. Thanks for your time and happy holidays.



0 Kudos
Message 1 of 13

Hi Paul,


Thank you for your files. I will look over them and get back to you. In the meanwhile, please post back with any updates that you might have.


Warm regards,
Karunya R
National Instruments
Applications Engineer
0 Kudos
Message 2 of 13

Hi Karunya,


Thanks for looking at my code. As for updates, here's what I've found out so far:


  • Setting clock phase to second edge solved part of my problems. I guess that's logical because LabVIEW sees the rising edge as the second edge in an idle high system (see page 5 in the data sheet). The values I get from reading some of the registers seem valid. For instance: if I read the data register for analog channel 0 with AIN0 and AINCOM shorted by cable, I get two decimal U8 values: 128 and 0. Joining these numbers to a U16 value gives you 32768 (decimal U16) and this is exactly 0 volt according to the calculator at:
    So I am now trying to set and read more advanced options. I'll keep you updated.
  • Still can't get the 2nd SSI port to work, doesn't seem to be an electrical failure. I replaced and tested almost all of the parts (starts to look like a Frankenstein circuit board because of all the probes and wires).


 The trouble with SPI, especially ADC's that use it, is that you will always get a result (unless the part's dead, but even then you might get 0000 0000 as a result); making sense of the result is the hard part Smiley Wink

 Thanks for any help you can give me.



0 Kudos
Message 3 of 13

Status update:


Well, my device works ok as long as it's using SSI port 0. I can send and receive commands, connected devices work well. As for SSI port 1; I'm certain it is a software setting that needs to be adjusted in the compiler, because I still can't access the port, no matter what hardware I use. To rule out hardware errors on my part, I've used the eval-kit for LM3S1968 from Luminary to read out signal levels while I was sending SPI messages. If I continuously send data over SSI0 with a 10 ms delay between bytes, I'll get this image on my scope for S0CLK (SSI 0 clock line):




If I try to do the same for SSI1 by changing the 'chip select' value from 0 to 1, the clock line stays low. Looks like something needs to be changed in the build options. Can anybody help and/or confirm this error?

Thanks in advance.




Message Edited by Perreijn on 01-28-2009 03:22 PM
0 Kudos
Message 4 of 13

Hi Paul,


This could be due to an issue with the IO configuration when using the LM3S1968; R&D is investigating. My apologies for our lack of responsiveness on this issue.

Message Edited by Michael P on 01-29-2009 09:57 AM
Michael P
National Instruments
0 Kudos
Message 5 of 13



The driver only supports one SPI port, since that is all the 8962 has, but the 1968 has 2 SPI ports.  You assumed (reasonably) that you could use a value of 1 to use the other SPI port. The VI should be returning an error when you use 1.
The SPI is such that you can use multiple devices with 1 SPI controller by using a different chip select line for each device.  The driver does accomodate that behavior.  So one possibility is that you use SPI 0 and use a different CS spec for the two devices you want to use.
You can specify the specific GPIO pin to use by the value you encode to the SPI input as follows:
[07:00] interface number (only 0 is valid now)
  [11:08] GPIO pin number (0-7)
  [15:12] GPIO port number (1-7, where 1=A, etc)
If the upper bits are all 0, then the default Fss pin is used for the chip select, and this should be considered the normal or default behavior.  Specifying the GPIO line is a kind of advanced usage.


The other thing you can do is patch it by editing the SPI driver in your project to add support for the second SPU controller.  We can provide the specific code to add if you like.  It should not be very hard to do.

Michael P
National Instruments
0 Kudos
Message 6 of 13

Hi Michael,


Thanks for your reply and explanation. I already suspected the 'chip select' option might have something to do with the #CS pin of many SPI devices. You could call it SPI multiplexing, and it's an option I considered as a backup solution (connecting #CS pins to GPIO pins and manually switch them). Your approach is bit different, though.

However, I would like to know how to edit/patch the SPI driver myself. Could you please post the details? Thanks.




0 Kudos
Message 7 of 13



The edits made in the attached files provide the second SPI port specifically on a 1968.  This means the port pins are hard coded for a 1968.  It might not work on other chips. More extensive changes are needed to allow it to work on any chip.  The first SPI port (0) should continue to work just fine on the 8962 board or the 1968 board.
This is for the "Other" target. I assume that is what you are using since you have a 1968.  If your'e still using the 8962 target then you need to modify the following instructions accordingly:
These two files can be replaced in the individual project as follows:
Then completely rebuild the project.
If you do this it will work for your current project, but not new projects or if you ever do anything that overwrites the current project from the template.  To make this change permanent and global, replace these files in the template at the following locations:
C:\Program Files\National Instruments\LabVIEW 8.6\Targets\Keil\Embedded\RealView\Generic\LM3Sxxxx\Template\System\Startup.s
C:\Program Files\National Instruments\LabVIEW 8.6\Targets\Keil\Embedded\RealView\Generic\LM3Sxxxx\Template\Drivers\SPI\ARM_SPI.c
I suggest that you rename the original files first so that they will not be overwritten. Please keep in mind that these changes are not tested, so back up your work first

Michael P
National Instruments
Download All
0 Kudos
Message 8 of 13


I have a problom on reading data from AD7738.

Our Platform is Linux OS and the processor is  mc9328mx2.

Can you tell me on what platform you are working.

0 Kudos
Message 9 of 13

 We are facing some problem with reading data from AD7738:


The required configuration of AD7738 is:
1.) Continuous Conversion Mode.
2.) Conversion time 88h (Chopping enabled mode).
3.) Differential Channel with +/-2.5V.
4.) Dump Mode.
5.) Clamp Bit Enabled.
6.) 24 bit.

We have configured AD7738 in the following sequence with the respective Command Word:

The writing sequence is as following:

1.) Writing to Communication Register:     01h (I/O Register Address)
2.) Writing IO Port Data:            20h
3.) Writing to Communication Register:    28h (Channel Setup Register Address)
4.) Writing Channel Setup Register:    6Ch
5.) Writing to Communication Register:    30h (Conversion Time Register Address)
6.) Writing Conversion Time Register:    88h
7.) Writing to Communication Register:    38h (Mode Register Address)
8.) Writing Mode Register:        2Fh
9.) Writing Continuous Conversion
    to Communication Register:        48h

The problem that we are facing are:
1.) The ready signal is always pulled high and it is never going low.

Can you suggest any solution to us.

0 Kudos
Message 10 of 13