Digital I/O

cancel
Showing results for 
Search instead for 
Did you mean: 

PXI-6289 SPI Protocol, Simultaneous Generation & Acquisition

Solved!
Go to solution

Good day all, 

I am trying to implement the SPI protocol in a PXI-6289. I am generating the SPI waveform with the SPI Digital Waveform library, then outputting through regular I/O (CS,SCLK, MOSI) as shown bellow. 

VI:  Attached below.

 

D15_S_03.PNG

D15_S_04.PNG

D15_S_01.PNG

Note: I am aware of the thin clock cycle at the start of the transmission, but that is probably tied to my SPI settings. Not an Issue.


What I have not quite figured out is how to read/sample digital inputs (MISO) during the exact same time as my other signals are being outputted. This is to emulate the full duplex communication.

 

Ideally, I would test this by tying MOSI and MISO together and see how off these are on the scope.  

 

I have tried a couple of options with Triggers, Timing blocks and Events, but these seems to be restricted due to the hardware I'm using. Since this PXI 6289 is all I can use for now, I am asking for any suggestion of what I could do in this scenario. 

I appreciate your responses. Thank you, 

Sebastian B. 

0 Kudos
Message 1 of 14
(4,039 Views)

Use the DAQmx Timing VI before you start the task and set the clock source to be your SPI clock.


GCentral
There are only two ways to tell somebody thanks: Kudos and Marked Solutions
Unofficial Forum Rules and Guidelines
"Not that we are sufficient in ourselves to claim anything as coming from us, but our sufficiency is from God" - 2 Corinthians 3:5
Message 2 of 14
(4,014 Views)

Thank you for the reply. Here's what I'm seeing with the timing block. The first time I run the operation, it seems to sample the MOSI data properly.  However, I get an error since I must be mismatching the sample rates, and number of samples I'm supposed to acquire. Also, reads after the first are off and sample the data at wrong times.

 

It shows the error shown below.



D15_S_06.PNG

D15_S_07.PNG


I have a Sample rate of 80000, Finite Samples, Number of samples on timing block is 32 (2 for every clock cycle is my reasoning).

And for the Read number of samples I tried the same number of counts as the SPI waveform (820) but this would cause it to stall and be unresponsive, so I lowered it, I guess 32 samples after the clock triggers are enough to see the data. 

I'm not sure on how to work with the proportions of Sample rate and Number of samples for these VIs. Would you know how these could aling?

Thank you for your time. 

0 Kudos
Message 3 of 14
(4,002 Views)

The # samples input to the DAQmx Timing block is going to set the task's buffer size for your Finite Sampling task.  That's all it's gonna capture, and when you requested a larger # samples from DAQmx Read, it timed out because the rest were never going to happen.

 

If you're going to want to collect 820 samples, wire 820 to *both* the DAQmx Timing and DAQmx Read inputs.

 

And aren't you going to similarly need to drive your DO task from that same external SPI clock?   I don't know SPI protocol, but your description makes it sound like the DO and DI should be sync'ed up.

 

 

-Kevin P

 

P.S.  As this is yet *another* time where the "# samples" inputs to DAQmx Timing and DAQmx Read have been a source of confusion, please consider adding kudos to this suggestion.

ALERT! LabVIEW's subscription-only policy came to an end (finally!). Unfortunately, pricing favors the captured and committed over new adopters -- so tread carefully.
0 Kudos
Message 4 of 14
(3,994 Views)

Thank you for your reply Kevin, 

I have matched the buffer size, for the Timing block and Read block, but I am still seeing the same error. 

- I also tried leaving the Timing block at 1400 while only reading 1200. (Not using the full buffer)

 


As far as triggering, I am not using an external clock, in SPI the Master generates the clock SCLK and that guides the transaction. For this reason I am trying to start generating the SCLK with my DO, then trigger the read on that. There are two scenarios I tried:
- Trigger on SCLK where I trigger on the rising edge of the DO, but I am concerned this is causing multiple instances of capture to appear since the clock rises 16 times per transaction.
- Trigger on CS (Chip select) falling edge, which in SPI, remains high and then goes low for the duration of the transaction. This one gives just one instance of capture, but I actually could not see any output from this trial. 

If I was to add a timing block to my DO, where would I source it's start?

D15_S_08.PNG

 

 

 

Thank you for your time, 

Sebastian B.

 

0 Kudos
Message 5 of 14
(3,988 Views)

Your 6289 is an M-series device, and is thus limited in its support for hw-timed DIO.  The terminology promoted by NI was to call it "correlated DIO" and that search term should help you find things.

 

It basically means that DO and DI tasks are not capable of deriving their own sample clocks from the internal timebases on the board.  They must "borrow" one from elsewhere, thus the samples will be *correlated* to that external clock signal.

 

Further, correlated DIO is only supported on port 0 (which you're already configured to use, good!) but these digital signals on port 0 do *NOT* carry "PFI" functionality where they can be internally routed for use as timing and synchronization signals.

 

You would need to physically wire from your SCLK line on port 0 over to a PFI line.  Then you could configure your DI task to use the signal on the PFI line as its sample clock.  However, all this would leave you in a bind for your DO task that still can't generate the SCLK signal at a fixed rate without some *other* external clock signal to drive its task.

 

So scrap all that and try this instead.  Define a counter output task to generate a pulse train output at your desired SCLK frequency.  Physically wire it into your system so it can *replace* your DO task's SCLK signal.  Also use the counter output signal as the sample clock for DI and DO.   I'll assume you can define the other SPI signals appropriately.

 

It sounds like the biggest problem thus far is that you wanted precision hw-timed DIO, but initially didn't configure the tasks to use hw-timing.  Then you configured DI to use a hw clock, but didn't provide an actual clock signal.  Thus your Read function timed out waiting for samples that would never be captured.

 

 

-Kevin P

 

[Edit: P.S. In a hw-timed DO task, I would configure DAQmx Timing before calling DAQmx Write.  Also, DAQmx Write *must* be called before DAQmx Start.  With software-timed tasks, you start before you write.]

ALERT! LabVIEW's subscription-only policy came to an end (finally!). Unfortunately, pricing favors the captured and committed over new adopters -- so tread carefully.
0 Kudos
Message 6 of 14
(3,978 Views)

Hi Kevin, 

I was already wiring as you mentioned with:

SCLK->PFI1  (PFI1 being the source to the timing block)
MOSI->MISO

I am confused as to what you mean by not providing a clock signal, I was under the impression the timing block was just waiting for the edge trigger on the "clock" SCLK = PFI1, then immediately sampling  a specific #Samples at SamplingRateValue.  

But I'll give a try to what you suggest. I will share my results later.


Thank you,

Sebastian B.

0 Kudos
Message 7 of 14
(3,968 Views)

I know you've put a lot of work into this, but it might be worth just getting a USB-8451 or USB-8452.  They have a simple API for doing SPI and I2C communications.


GCentral
There are only two ways to tell somebody thanks: Kudos and Marked Solutions
Unofficial Forum Rules and Guidelines
"Not that we are sufficient in ourselves to claim anything as coming from us, but our sufficiency is from God" - 2 Corinthians 3:5
0 Kudos
Message 8 of 14
(3,964 Views)
Solution
Accepted by topic author sbetancur

@sbetancur wrote:

I was under the impression the timing block was just waiting for the edge trigger on the "clock" SCLK = PFI1, then immediately sampling  a specific #Samples at SamplingRateValue.  

Nope.  Under DAQmx, sample *timing* and task *triggering* are very distinct.  Your impression of things isn't unreasonable, but it *is* wrong.

 

To handle a 1-time trigger, you'd use a call to DAQmx Trigger to configure it.   To handle *correlated* DI/DO on an M-series device:

- you need to specify the source for an external clock signal

- the clock signal needs to be present there and actively "clocking" to drive sampling in your DI/DO task.  The DI/DO subsystems cannot generate their own sample clocks on M-series devices.

- you should also specify the expected rate of that clock signal (use the max if it can vary).  The main reason is for buffer sizing.  Your actual sample rate will be driven by the clock signal, not by the rate value you estimated.

 

crossrulz makes an excellent point.  There are dedicated devices available for SPI work.  Other than the learning you'll do while going at this your way (i.e., the hard way), it's unlikely to be worth it.

 

 

-Kevin P

ALERT! LabVIEW's subscription-only policy came to an end (finally!). Unfortunately, pricing favors the captured and committed over new adopters -- so tread carefully.
Message 9 of 14
(3,919 Views)

Thanks Kevin, that makes sense. While I'm still figuring out the details with the generated pulse/counter, I'd like to ask if this USB8451 could be used along with NI chassis and other cards?

 

The whole point of what I'm trying to make is a generic/modular SPI block that can be implemented with simple I/O for a variety of cards. Of course, easier said than done, but I think this should be very similar to simple BitBang of a protocol. 

Thanks to both Cross and Kevin for these recommendations.

0 Kudos
Message 10 of 14
(3,911 Views)