16-bit SPI trying to read from 22-clock cycle ADC

This is interesting. I'm taking a look at the SSC. Never used it before. Looks like it might be possible, but I'll wait to finish reading.

Thanks!

Reply to
Bill
Loading thread data ...

That has already been proposed by others, and won't work either, without CPU intervention. Please read my other posts.

Reply to
Bill

To be more correct, for me, it is not TI's fault. It is the fault of the designers of the SPI inside everyday MCUs. Knowing that there are

16/18/20/22/24-bit ADCs/DACs around, and that they need extra clock cycles for the sampling phase, what are they waiting to implement SPIs that can handle say 32 bits in a single transfer? I don't understand it. It would be a few microdollars more of silicon.

Yes, I'm bit banging. The ADC could work up to 100 ksa/s. Thank god I'm not going that high, because in that case the CPU could do nothing else.

Yes, I'm curious to ask them.

Best,

Reply to
Bill

Disregard this sentence. It makes no sense. I was thinking about my ADC. I don't know why you are seeing that. Maybe you have CSAAT set, and you are switching between different devices?

Reply to
Bill

What about CSAAT ? Setting it allows the CS to stay low until another CS is selected.

Cheers

Reply to
Martin Riddle

Seems like a pretty poor implementation of the SPI master. I've generally rolled my own, but at least the later TI DSPs allow SPI word lengths of 1 to 32 bits.

Bit bang the sample clock then use SPI to transfer data? Use an FPGA to do your I/O?

You have a sows ear and you want a silk purse? ;-)

Reply to
krw

I'm not familiar with the AT91SAM devices (I'm not very familiar with ARMs in general - it's nearly twenty years sine I used one), so this may or may not give you some ideas...

First, is the CSAAT bit in a register adjacent to the SPI transfer register(s) ? If so, it's possible that your DMA could be set up to transfer a new value to that control register at the same time as sending another 16-bit word to the SPI transmit register. (On the Freescale devices, the equivalent to CSAAT is in a command byte that is collected from the queue along with the data to send.)

Secondly, if you have several DMA channels and they are flexible enough, it might be possible to configure a chain of DMA events. For example, the SPI transfer complete could trigger a DMA transfer. Instead of writing the next SPI transmit value, this could "manually" trigger two new DMA channels. The first of these is set up to set the CSAAT bit, and the second to write the next SPI transfer.

There are indeed a fair number of them, and (AFAIK) they all have powerful SPI peripherals and lots of flexible DMA channels. So without anything else to go on (performance, flash, external bus, timers, etc.), it would be a random guess as to which would be suitable for you (though MPC55xx or MPC56xx narrows it down a little). I've used an MPC5554, if that helps at all. If you are considering changing architecture, then you should also look at the ColdFires (specially the v2 cores) - they are easier to work with.

Sorry, I didn't mean it to sound impolite to /you/. It's just that the documentation for these devices is complicated and often unclear. The "SPI" peripherals on the MPC55xx support serial multiplexing of internal timer channels as well as SPI (which supports multiple queues amongst other features), and it's no small job figuring out what is really needed to get the SPI running as desired. Similarly with DMA. There is also a lack of appnotes for this sort of setup, so you have to be prepared for a fair amount of work figuring things out. Once you understand it all, however, you can do all sorts of wonderful things with the MPC's peripherals.

Reply to
David Brown

Ofcourse you can do this with 2 11-bit transfers (or 3 8-bit as mentioned by others) and still use the PDC (DMA). If you couldn't, how would you for example read EEPROMS?

Just set CSAAT=0 "The Peripheral Chip Select Line rises as soon as the last transfer is achieved", fill your TX buffer and point PDC to it. Then write the PDC counter and the CS will go low before the first transfer and only rise after the PDC has completed last transfer.

You ofcourse have to make sure all other settings match your hardware, check that every bit in every register is set as required, understand the function of each bit.

This is the way I always use SPI on the SAM7. I do use variable peripheral select and no CS decoding, but I don't think these options affect the CS deassertion behaviour.

--
Stef    (remove caps, dashes and .invalid from e-mail address to reply by mail)

I'm glad I was not born before tea.
 Click to see the full signature
Reply to
Stef

You missed the point: The 'N' units are in a single 'transaction', with only a single activation of the CS. There may be some (programmable) delays between the bytes within the transaction, but that should not bother your peripheral.

I think you misread "doesn't work in 8-bit transactions".

In the datasheet there is however a diagram that shows CS staying low between 2 bytes. Dec'08 datasheet, page 271, figure 28-7, see signal "Chip Select 2".

--
Stef    (remove caps, dashes and .invalid from e-mail address to reply by mail)

People who push both buttons should get their wish.
Reply to
Stef

Well, I was wrong in at least one thing: I thought that, with CSAAT=0, CS would be deasserted (high) between consecutive "word transfers" within one "block transfer", but it is not. I had clear from the beginning (from diagrams and text) that there was a way to keep CS=0 between word transfers, but I thought that it implied CSAAT=1, and it is not true. CS is 0 between consecutive word transfers (of the same block transfer) regardless of the value of CSAAT.

So, yes, I can leave CSAAT=0 permanently, there is no CPU intervention needed (other than at the beginning and at the end of each block transfer), and I can use DMA, with two 11-bit word transfers per block transfer.

This is good, but I think that it could be better. Difficult to explain, but I'll try:

Imagine my external ADC (with SPI interface) is sampling the analog input at 100 ksa/s (the TI ADS8320 that I mentioned allows that). So,

10 us between samples. Not much. Each sample needs 22-clock cycles inside each assertion of CS=0, so each sample needs one DMA block transfer (with for instance two 11-bit word transfers inside). Each DMA block transfer needs CPU intervention. So, I need CPU intervention every 10 us. That's a short time. Only 480 cycles of my 48 MHz SAM7. Since (that I know) a DMA block transfer cannot be triggered directly by a timer overflow or underflow, an interrupt service routine (triggered by a 10 us timer underflow) must be executed every so often, so that the CPU can manually trigger the DMA block transfer and collect the data. Adding up the overhead of the interrupt context switching and the instructons needed to move data from and to the block buffers, to re-trigger the block transfer, and all this in C++, I think that all that may consume a "significant" portion of those 480 cycles. And the CPU is supposed to do something with that data, and some other things. I see that hog as a killer, or at least as a pitty.

If the SPI in the MCU allowed 22-bit (word) transfers, and the DMA allowed triggering the next word transfer (inside a block transfer) when a certain timer underflows, then the DMA blocks wouldn't need to be so small. Each analog sample could travel in one single SPI word transfer, and one DMA block could be planned to carry for instance

1000 word transfers. That would be one DMA block every 10 ms. The buffer (FIFO) memory would be larger, but the CPU intervention needed would be much lower. There would be the same number of useful cycles, but much fewer wasted cycles. There wouldn't need to exist an interrupt service routine executed every 10 us, which is a killer. That would be a good SPI and a good DMA, in my opinion, and the extra cost in silicon is negligible, compared to the added benefit. Why don't most MCUs allow that? Even cheap MCUs could include that. An MCU with the price of a SAM7 should include that, in my opinion.

Best,

Reply to
Bill

If the ADC is using the SPI clock to enact the next conversion, I could imagine it might actually be bothered, in the sense of being sensitive to this rather extreme "jitter" though hopefully it is designed such that it is not.

Reply to
Chris Stratton

You might be interested to compare the blackfin's SPORT DMA capability... there the DMA can be programmed to transfer words separated in time without CPU intervention. Obviously no fixed- hardware solution (other than a built in gate array ;-) is going to have the flexibility for all needs, but this sounds like it might be along the lines of what you are looking for... so at least some silicon designers seem to be thinking along your lines.

Reply to
Chris Stratton

Processing bigger blocks does save some interrupt overhead, but you still need to handle all the data so the advantage may not be that big. And 480 cycles is still a decent amount to do some work. ;-)

But with a bit of creativity, you can get bigger blocks from your DMA. If you use "variable peripheral select" you can create a buffer with your ADC transfers and dummy transfers to another chipselect in between to get the required CS switching pattern. If you then set up the SPI clock correctly, you can let the PDC perform the 100kHz interval transfers up to 64k 'bytes' (including the dummies).

Another option is to use the SSC (as mentioned by others), this can transfer up to 32 bits per transfer. Transfers can be started on an external event on RF pin. If you tie a TC output to the RF input, you can use the TC waveform mode to initiate the transfers.

But I agree, being able to program some interval timer (maybe TC) and use that directly to initiate transfers to peripherals would be nice to have. But as long as it's not there, see what is and try to get the most out of that. And if you are not tied to the SAM7, check if there are other CPU's that have features that suit your wishes.

--
Stef    (remove caps, dashes and .invalid from e-mail address to reply by mail)

A platitude is simply a truth repeated till people get tired of hearing it.
 Click to see the full signature
Reply to
Stef

It's not a matter of silicon area, but what SPI devices do they want to cover. SPI is a thousand twisty little passages, all different. How are they going to service them all? The bottom line is that they put enough in to put the bullet on the front page of the datasheet. If you want custom I/O do it in an FPGA.

Reply to
krw

In those instances, I always revert to assembly language for the interrupt part. Handle things as quickly as you can, and a context switch suddenly isn't half that bad. No more than pushing and popping a few registers. Hell, I even did a Fast interrupt handler in C on a Motorola DSP56K. The interrupt occured every 200 ns.... (no typo). Just... be smart...

Meindert

Reply to
Meindert Sprang

What was the clock frequency of your DSP56K?

Reply to
Bill

interrupt

Hell,

interrupt

80MHz

Meindert

Reply to
Meindert Sprang

Bill skrev:

An idea:

Run a timer which is connected to the SSC input clock and ADC clock. It also clocks another timer in PWM mode generating the ADC chip select.

The ADC will see 22 active and 10 passive bits and the SSC will see 32 bits.

(Did not test this)

Best Regards Ulf Samuelsson

Reply to
Ulf Samuelsson

Bill skrev:

An idea:

Run a timer which is connected to the SSC input clock and ADC clock. It also clocks another timer in PWM mode generating the ADC chip select.

The ADC will see 22 active and 10 passive bits and the SSC will see 32 bits.

(Did not test this)

Best Regards Ulf Samuelsson

Reply to
Ulf Samuelsson

Hey, that's a wonderful idea!! It opens up a broad array of new possibilities :-)

Thanks!

Reply to
Bill

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.