LabVIEW Embedded

cancel
Showing results for 
Search instead for 
Did you mean: 

Blackfin Multiple SPI Devices

Solved!
Go to solution

Hi guys:

 

Sorry to post this question, but I really can't make it work!

I can configure each SPI device and they work alone, when I try to config 2 devices, I simply can't get both CS lines to go up!

Note: here is my code, I choose Slave Select 4 so it can be easily accessed via SPI Connector on the board (pin 14).. SS1 is pin 9!

Thanks in advance

António Veríssimo de Freitas
Universidade de Aveiro Student
0 Kudos
Message 1 of 19
(9,662 Views)

Some developments:

 

It looks like when working with an interface we can only have one buffer for that (only one buffer for SPI)..

 

I managed to switch between SPI devices, using SPI Control and simply doing (Disable Slave "A" and Enable Slave "B") and vice-versa, but now the problem is I'm doing this in a while loop, so the buffer get filled with samples like: A A B B B A B A A A B B...

Is there a way to do this right? As I can only have one buffer, it was good to have the buffer like: A B C D E F A B C D E F A B C D E F G, etc.

Thanks in advance

António Veríssimo de Freitas
Universidade de Aveiro Student
0 Kudos
Message 2 of 19
(9,642 Views)
Solution
Accepted by freitas

I like your "main.vi" instrument, but unfortunately, I think the AD7476A driver has not been designed with multiple ADCs in mind, so let's dig a little deeper.


"Declare Slave Select" command limits the value 1-7 because the SPI peripheral can drive directly only this amount of devices, each of them being validated in concordance with SPI_FLAG register. Notice that in DMA transfer mode (AD7476A driver case) CPHA =0 and SS pins are automatically selected at the beginning of each transfer: for each bit set to one in SPI_FLAG a low pulse will be generated at the corresponding pin! (These bits are set to one by Enable Slave Select or Declare Slave Select).

It would had been great if the reading would switch the slaves but is not.

I am hopping you'll not expect 1 MSPS for all ADCs. The conversion timing of AD7476A is determined by the serial clock: the driver sets the SPI clock about 16 times sample rate. That's why you have to give a higher value to the sample clock passed to BF AD7476A Control.vi:
For a system with 5 ADCs and 100 KSPS the value should be 500000. Notice that inter-channel delay is in this case 2 microseconds, so the time-difference between first sample of first channel and 5th channel is 8 us (almost equal with sample period) - this might be an issue in some applications.

However, more information can be accessed in hardware description (ADSP-BF537 Blackfin Processor Hardware Reference ), peripheral driver documentation (C:\Program Files\Analog Devices\VisualDSP 5.0\Blackfin\docs), and drivers source code (C:\Program Files\Analog Devices\VisualDSP 5.0\Blackfin\lib\src\drivers). Here I would just say that it seems circular buffer are not supported (see VisualDSP 5.0\Blackfin\docs \spi\adi_spi_int.pdf and adi_spi_dma.pdf), and move to some solutions:


1.Reconfigure the SPI to use interrupts and use callbacks to switch programmatically the slaves using  BF SPI Control.vi  "Select/Deselect Slave" (of course, each of the salves pins should be "Declare Slave Select" with  BF AD7476A Control.vi or "Enable Slave Select" using BF SPI Control.vi). This will add some overhead and, depending on sample rate, you might lose some samples. Also there is a limit of only 7 slaves.

 

2.Set DMA for a single word and switch slaves in the callback after each conversion result (of course, this will have the same cons as #1).

 

3.Add a simple external hardware to select automatically ADCs (for example a  counter+decoder clocked by one of the seven SS pins and reset using EIO). Then play with buffers to identify channels (e.g. 1D buffers with 5 elements for 5 ADCs). This will add less overhead, as callbacks will be triggered after one sample from all channels has been acquired (or even better after n samples, if buffer length is nx5, etc.)

 

In all above solutions you have to open and close AD7476a driver only one time in the "main.vi.

 

#1 and #2 looks like your solution posted previously but the command should be Select/Deselect for interrupts and Enable/Disable for DMA. Also the slaves should be switched exactly at the end/beggining of each received word.

 

 

Message Edited by NicB on 09-11-2009 06:21 AM
Message 3 of 19
(9,625 Views)

Hi NicB:

 

Thanks for your detailed explanation! I'll try the first two options, and leave the option #3 as backup!

Today I'll do some tests..

Thanks once more,

António Veríssimo de Freitas
Universidade de Aveiro Student
0 Kudos
Message 4 of 19
(9,603 Views)

Hi Antonio,

 

It appears your solution of using multiple ADCs connected through SPI (digital MUX) is quite the same as using a single ADC with an analog MUX (http://forums.ni.com/ni/board/message?board.id=420&message.id=1004#M1004).
Did your supervisor approve the new solution?

 

Nic

0 Kudos
Message 5 of 19
(9,581 Views)

Hi NicB: 

 

Now I simply don't know what to do anymore, I'm getting desesperated..

These are the things I can do:

- read like 1024 (for example) samples, and do a "callback" when the buffer is full, and process data, using only one ADC.

          but when reading just one ADC or one channel of the MUX and don't know what happened in that time in the others...

- read samples from separate ADC's but the number of each Slave Select are not always equal (for low sample buffers) and depend of the Sample Rate.

          I think I can ignore others readings or maybe enable/disable faster, it should be a way to do only one reading and then enable other Slave Select.

          example: @ 1ksps I have one reading for each SS, but @ 5ksps i get 3 or 4.. this was done using the vi of "wait for buffer flag", I don't see logic using interrupts for reading one sample at a time..

I'll have to talk to my "guiding teacher" and decide what to do, I want to finish this project as this is my last work in college, I must finish it very soon..

Thanks for everything,

 

p.s. - the perfection was to read one sample for each ADC and put them into a circular buffer or something like that..

António Veríssimo de Freitas
Universidade de Aveiro Student
0 Kudos
Message 6 of 19
(9,577 Views)

Hi Antonio

 

I don't know if you understood my proposals, so I draw a small project in a hurry (didn't test in real hardware). Current settings are for 4 channels but could be modified up to 7. Let me know if the SS are switched in callback.

 

For desperate situations unconventional solutions might be more appropriate. I think your supervisor will be more satisfied if you'll use PPI, reading all ADCs in parallel. Of course, there will be a little bit processing after each sample has been acquired.

0 Kudos
Message 7 of 19
(9,565 Views)

Thanks for your replys!

 

I'll see the code right now.

I'm not familiared with PPI is it like a SPI with multi and paralel MISO? That would be good!

I'll post soon,

António Veríssimo de Freitas
Universidade de Aveiro Student
0 Kudos
Message 8 of 19
(9,563 Views)

Your program runs but it doesn't activate SPI or change slaves, I'm going to debug it! I'll work on that a bit longer.

Meanwhile, I talked to my guiding teacher, and he decides that PPI was problaly the best solution, reading a BUS is a lot better than reading a MISO line!

I'm going to choose an ADC (paralel) and prepare the interface for PPI, do you agree?

Trully thanks for your effort 😉

António Veríssimo de Freitas
Universidade de Aveiro Student
0 Kudos
Message 9 of 19
(9,557 Views)

I admit I was blindly drawing the project, but your reply adds some frustration.
What means runs?
Is the callback called? (Are the mean results updated on front panel?)
Have you looked with a scope and cannot see SCLK and SS?
What about configuring 128x4 single word 1D buffers?


1 element 1D buffer.PNG

 


freitas wrote:

Meanwhile, I talked to my guiding teacher, and he decides that PPI was problaly the best solution, reading a BUS is a lot better than reading a MISO line!

I'm going to choose an ADC (paralel) and prepare the interface for PPI, do you agree?

Trully thanks for your effort 😉


Actually, I was thinking to use multiple AD7476a connected to PPI in RX mode, 1 external frame Sync. The connection could be something like this:
-PPI frame sync to all ADCs /CS;
-SDATA of each ADC to a pin of PPI,
-PPI_CLK to SCLK of all ADCs
With this arrangement conversion time could be independent of sample rate and channels are synchronous sampled. 16 words have to be read for each sample, and then transpose the bit array in software.

0 Kudos
Message 10 of 19
(9,540 Views)