I'm trying to use the NI USB-8451 to read SPI data from a Honeywell digital pressure transducer. The difficulty arises because the Honeywell part only uses SPI in a half-duplex mode, i.e. it only transmits data, but does not require anything beyond the appropriate chip select signal and SCLK in order to begin transmitting its 32-bit sensor data. To facilitate experimentation with the sensor, I purchased a USB-8451 SPI Interface thinking I could easily configure the 8451 to read the transducer data.
However, if I understand the situation correctly, there is a problem. The 8451 assumes full duplex data, i.e. that a data word must first be sent to the SPI device in question before the device will begin transmitting back data of its own. And since the MOSI write data is clocked, since this particular device starts transmitting immediately once a clock is applied, clocking the unused address data will cause the device will return its data before the 8451 begins to listen for the returning data. The call used by the 8451 to perform a write read action cannot be divided into the individual read and write actions by any way that I've been able to uncover.
Can anyone tell me if I've missed anything in how this works, or if there are any quick little tricks I might use to be able to use the 8451 for this purpose? Thanks!
Solved! Go to Solution.
The way the SPI works, you need to just send out dummy data. Each byte that is in the output array will generate 8 clocks. Since the device doesn't have MOSI connected, they bytes don't matter (you can just initialize an N-byte array).
That is just the nature of SPI. All I/O is a data exchange. Very often garbage data is sent/received since most devices actually use half-duplex communication over the full-duplex bus.
There is no address in SPI, just data exchange. Any protocol is implemented by the user and the device. 845x hardware always does an SPI read and write simulateously. On every clock, a bit of data is exchanged. The data can be valid or it can be "dummy", but a bit is exchanged in both directions on each clock.
Hi GPIB Guru, thanks for taking the time to respond to my issue!
So I think I've got my wires crossed on exactly how this SPI business works. Most of the NI examples on the 845x products show how to conduct SPI data transfers to memory devices, and I thought in such cases, one needed to provide an address prior to reading out the data from said memory address so that the SPI slave device in question knows just what data to send. This is why I've been thinking the exchanges used a model where the 8541 sends out an entire byte/word before receiving one in return.
You say that the transfer is instead simultaneous, one bit is returned for every bit sent out by the 8451. If that's the way it works, then I understand that I should be able to send dummy data in order to receive back my transducer data. But I can't make that jibe with the idea that an SPI memory device would require an entire address before it would be ready to return any data in response. Can you see where my logic on this is faulty?
So... memory devices are generally half-duplex... In this case during the data exchange depending on which byte is being sent, one side is doing "dummy" data.
In the case of an EEPROM (AT25080A is a good one since that is the example we ship with), you can take a look at the data sheet.
You can get the data sheet at http://www.atmel.com/Images/doc3347.pdf
If you look on page 13, figure 4-4 that shows the best picture.
The NI-845x API needs to know what bit to transmit on each clock pulse. If the protocol between your device and the master have don't care bits, then you would just pad the transfer with whatever you want (0x00 or 0xFF are reasonable choices, but in theory it doesn't matter if you wanted to pick a random number). Likewise, on the input side, the response buffer will contain a byte for each 8-bits clocked on the SPI bus. If (as the case with the first example), you only care about bits 8-15, you would discard the first byte and just look at the second byte.
If you are using LabVIEW, you can open up the Atmel AT25080A Read.vi from the NI-845x basic examples, you will see that the response from the SPI Write/Read is a U8 array and the block diagram is discarding the first 3 bytes since they are don't care (this is the figure from 4-6 that is being implemented, if I recall correctly).
If you are using C, you can open up Basic\Atmel AT25080 Read\Atmel AT25080 Read.c and look near line 123 (in the 2.0 driver) and you will see that the subsequent lines are doing a for loop to display the received data and it is looping from 3 to N, again discarding the first 3 bytes which were dummy bytes read from the EEPROM.
Does this clarify anything?
Yes, it does, thank you.
To recap: My goof is that I've been stuck on the parallel model of data transfers to memory: set an address, clock out the data. But of course, when conducting the transfer via SPI, the target device makes the serial-to-parallel conversion internally, invisibly to the 8451 master, managing the process as necessary. So in the case you cite, the 8451 transmits an address while the EEPROM listens, half-duplexed. Once it has the whole byte, the EEPROM, managing the transfer, reconfigures to half-duplex mode in the other direction. SO goes active, and transmits the resulting data from the received address. The 8451 was listening and recording the whole time, but the user programatically has LabVIEW ignore the data received during the address transmission, using only that received during the second half (data phase) of the exchange. But the 8451 still sends out data during this second phase, but it is dummy data, ignored by the EEPROM.
In my case, the target is a Honeywell HSC Series Pressure Transducer. It transmits 32 bits of SPI data, and requires only the CS be enabled, and the SCLK to conduct the readout. So while I've been trying to make this complicated, all I really require LabVIEW to do is to send 4 bytes of dummy data (since the 8451 must operate in 8-bit chunks) to generate 32 cycles of SCLK, and to read the resulting data recorded via the SO line. I think I've got it now.
Exactly correct. It is nice when things are easier than you expect. Hope it works as easy as it sounds.
Hey I am having a similar problem do you think that you might be able to show some of your code that you had success with I am also trying to use a Honeywell HSC pressure transducer and I still don't understand how you set up the read data I have looked at the example that was recommended, but I think the write data in has to be changed in order for the device to work, but I can't seem to figure it out.
Thanks for your help.
Let's see if I can make this work. I'm attaching a simplified version of the VI I eventually used to read and record from a pair of Honeywell HSC sensors, and to parse the data from the retrieved words afterwards. I've done a quick strip of some other stuff I had added to the VI in order to concentrate just on the Honeywell SPI reading process, so it's possible there are still bits unneeded for the SPI read proper.
There may well be easier/better ways to get this task done, but at my limited level of experience with LabView, this is what I came up with. Hopefully the attachment will be readable. It is moderately well commented, but please feel free to ask questions, and I'll try to remember what I was doing when I wrote this six months ago.