Help using SPI(or not) to read in 32 bits of clocked serial data

Status
Not open for further replies.

John k2ox

Member
Hi,

I'm new to the Teensy hardware and I am hoping it will help solve my problem.

I am trying to read some serial data from an FPGA. The data is not truly SPI. It is clocked at 1uS and was designed to load 4 serial to parallel chips. The clock line is normally low and puts out 32 1uS 50% duty cycle pulses. A third wire sends a load signal after the 32 bits are sent on the data line.

I programmed a 328p at 16MHz to read in the data using an SPI interrupt. In the ISR I read the first byte and waited for the SPIF flag to read bytes 2,3 and four.

Unfortunately, it totally misses all 32 bits about 1 out of 20 transmissions. After spending hours on this I decided I need a new approach.

I looked over the data sheet for the Teensy 3.2 and the SPI hardware looks much more capable. It has a 32 bit shift register.

Any ideas?

Regards,
John
 
ISR isn't the place to be doing serial I/O and busy loops! And interrupt latency can be dozens of microseconds, especially on an AVR.
So the FPGA's output needs to allow the MCU (AVR, ARM) time to recognize the data is coming; the FPGA can't just blast data out without giving say, 50 microseconds of lead time. And the MCU has to have preemptive priority on that bit (say, slave select with the MCU as an SPI slave, not master).

You say the FPGA clocks its output data at 1uSec (per bit). So the MCU interface has to be a slave API, accepting the FPGA's clock. And setup to latch on the correct clock edge, perhaps the falling edge since you say the clock is quiescently low. An API slave needs a slave select bit so as to know when the clock and data are relevant, and to know the boundary of a frame. Maybe the load signal is a slave select, true only when the 32 bits are shifting, false before and after.

It would seem the hardware, with slave select signaling the first bit time, can input 4 bytes just like an SPI slave would do.
Note too that slave mode SPI is an odd case in thes MCU libraries - and may be buggy.

Lots of other ways to do this... if the FPGA's clock is clean, then you could setup the SPI for a 4 byte DMA read and get an interrupt from the DMA controller when that completes. Or from a pin change on the FPGA bit that signals end of data. Or other. These, if you don't use SPI slave mode. And to do that, you have to "own" the SPI port exclusively whenever the FPGA might elect to send data.

Others here may have an idea - but it would be ARM/Teensy based, I'd think. Rather than AVR. Though maybe the Teensy 2's SPI can do this. Life's easier with the ARM Cortex CPU than the old AVRs.
 
Last edited:
The SPI port is much more capable, but its shift register is only 16 bits. It does have a 4 word fifo, so in theory it should be able to capture 64 bits.

Maybe you could configure the SPI in slave mode, and use attachInterrupt() to respond to the load pulse. Then just read the SPI FIFO to get the captured bits?
 
Status
Not open for further replies.
Back
Top