![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
Andrei S
Joined: 08 Aug 2014 Posts: 6
|
HW SPI clocking 12 bits between SS... Can it be done? |
Posted: Fri Aug 08, 2014 8:24 am |
|
|
Hi, I'm new to PIC's and the forum so please go easy...
I'm trying to interface with an existing FPGA design (meaning I can't change it) using a 18F4550 as a SPI slave. On a scope I can clearly see the SS, CLK(1.25Mhz), and SDI signals. The data coming over SDI is inherently 12 bit and the FPGA is clocking the 12 bits between each SS signal. Again, I can't change the way the FPGA presents the data.
From reading the PIC data sheet and the forum it appears the HW SPI must clock 8 bits at a time. Furthermore, ever attempt to read buffer with ( spi_xfer_in() ) returns incorrect/random data.
Am I overlooking some way to get this 12 bits of data in with the HW SPI?
Thanks, |
|
![](templates/subSilver/images/spacer.gif) |
temtronic
Joined: 01 Jul 2010 Posts: 9174 Location: Greensville,Ontario
|
|
Posted: Fri Aug 08, 2014 8:44 am |
|
|
quik response.
no...
HW SPI is always 8 bits(well it's 'supposed' to be....)
however nothing prevents you from coding a 12 bit SPI interface
in fact since the 4550 is the slave(FPGA is master) it's a fairly simple chuck of code.
you might check in the code library or use google. you aren't the first one who need 'non8bit' SPI data!
hth
jay |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19369
|
|
Posted: Fri Aug 08, 2014 8:54 am |
|
|
It is not simple code, if the speed is fast, and especially if there is low latency between SS and the first clock.....
All depends on the clock rate?.
and, agreed, the hardware SPI on the xx50, cannot do anything but multiples of 8 bits. Whoever designed the FPGA, should be driven over with something painful. If you look at devices using 12bit of similar 'odd' word lengths, they generally generate 16 clocks, even when only 12bits are actually used.
Last edited by Ttelmah on Fri Aug 08, 2014 8:59 am; edited 1 time in total |
|
![](templates/subSilver/images/spacer.gif) |
Andrei S
Joined: 08 Aug 2014 Posts: 6
|
|
Posted: Fri Aug 08, 2014 8:58 am |
|
|
I have a 20Mhz ext osc running the PIC. Perhaps a newbie assumption that a bit-banging software spi using GPIO wouldn't keep up with the 1.25Mhz FPGA clock? |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19369
|
|
Posted: Fri Aug 08, 2014 9:04 am |
|
|
Keeping up is not REALLY the problem. It is the latency between the SS dropping, and being ready to handle the first bit. This is the critical timing. Typically takes up to 30 instruction times to get into an interrupt handler, so unless there is some warning, and you can sit doing nothing else and waiting for the first bit, 'difficult', unless there is some guaranteed delay...
At 20MHz, you can clock the CPU at 48MHz (with HSPLL), so 12MIPS. However it is still going to be tight per bit.
Consider just using an external shift register, and interrupting the PIC when the last bit is received, and then getting the data from this. |
|
![](templates/subSilver/images/spacer.gif) |
Andrei S
Joined: 08 Aug 2014 Posts: 6
|
|
Posted: Fri Aug 08, 2014 9:38 am |
|
|
Thanks for details. The PIC has no time critical duties in my application and the SPI data will be fetched at only 5hz to update a UI. The FPGA itself is doing all the work. Perhaps I will use the first SS falling edge as the interrupt signal, but then use the next falling edge of SS as the start of the data stream?
I hope I can monitor the SS pin while in the ISR of the SS pin?
Thanks again, |
|
![](templates/subSilver/images/spacer.gif) |
temtronic
Joined: 01 Jul 2010 Posts: 9174 Location: Greensville,Ontario
|
|
Posted: Fri Aug 08, 2014 11:16 am |
|
|
one possible option based on what I did 20 years ago on another micro.....
since the FPGA supplies the clock...
tie that signal to an interrupt, forget about using SS
you get 12 databits, one for each clock.
you'll have to adjust the timing to read the databits at the correct time(maybe 1 or 2 NOPs ?)
and of course count the 12 clocks coming in.
if you write your own ISR instead of using the CCS handler, you could gain some speed.
hth
jay |
|
![](templates/subSilver/images/spacer.gif) |
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Fri Aug 08, 2014 4:39 pm |
|
|
Or change to a hardware platform that supports 12-bit SPI.
Since you are new to PIC this might be a smaller step than trying to fix this SPI mismatch.
For example the LPC1769 is an ARM Cortex-M3 based processor with much more performance and capabilities than the PIC processors. It handles SPI from 8 to 16 bits and everything in between.
The development IDE is an Eclipse based C/C++ compiler and free of charge: LPCXpresso
A development board with processor, I/O pins and integrated JTAG debugger costs about €20, that's less than I paid for my PicKit3 In Circuit Debugger for the PIC.
This is just an example. Many other manufacturers have come up in recent years with similar cheap priced development kits.
PIC processors are great when you are producing large quantities of a product and have to save every cent possible. Surprisingly, for a hobbyist it is often cheaper to select one of the more powerful processors from these recent kits. |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19369
|
|
Posted: Sat Aug 09, 2014 2:05 am |
|
|
Have to agree.
Some comments though:
First thing is the comment that nothing else timing critical is being done by the chip. This is a USB chip. If USB is being used, then this is timing critical. If not, why use this chip?.
Then it may be possible to do this, but only by sitting being 'ready' for the SS to drop. If the clock line feeds a pin supporting an interrupt on the edge that wants to be sampled, the 'trick' is to use the interrupt _flag_, but not the interrupt.
So you sit just polling the flag, and when it sets immediately read the input, rotate this into the variable required, clear the flag, and loop back.
It may _just_ (and very much 'just'....) be about possible, but there is no margin at all.
This becomes much easier, if there is some time between SS dropping, and the first clock, since then the SS dropping can be used as the 'signal' to say 'start looking at the clock'. Without this the code is going to have to go 'early' to the scanning operation. If there is perhaps a couple of uSec between these two events, then using a physical interrupt on the SS line could then call the required routine.
This all becomes a lot easier using a much faster PIC. One of the DsPIC's, would have the 'pin changed' flag available on it's inputs, and instead of having just ten instruction times between the clock edges, give about 5* more. However even on these, unless there is some 'warning' time from SS, it'll be relatively hard.
It is a job that is hundreds of times easier to do reliably using hardware, just because of the tight timings involved.
It is unbelievably simple to do with three 4bit shift registers, and an interrupt to the PIC when the last bit shifts in, or with a chip that supports programmable word length on the SPI (as Ckielstra points out). I'd possibly consider a small programmable logic chip, as being far easier than trying to get this working in the PIC... |
|
![](templates/subSilver/images/spacer.gif) |
Andrei S
Joined: 08 Aug 2014 Posts: 6
|
|
Posted: Tue Aug 12, 2014 12:29 pm |
|
|
Huh, won't rely on the email notification of new post I guess... Anyway, sorry for delay.
Ckielstra, Thanks for the response. I happen to have an mbed LPC1768 dev board at home that I had bought in an effort to learn a little something about MCU's. No chance with two little ones at home. Perhaps this is my opportunity to mess with it.
Unfortunately, the PIC 18F4550 is already shuffling configuration data (one-way) to the FPGA. So I need to modify the existing PIC code to include the spi as well as connect the signals back from the FPGA.
Ttelmah, The PIC is getting infrequent serial commands that contain configuration data for an FPGA. It services these random commands and then sits idle. I think I could poll for the interrupt flag in the same loop where I'm waiting/polling for a serial command to be ready. I like that idea and I believe it is worth a test. Thanks for the details.
Andrei |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19369
|
|
Posted: Tue Aug 12, 2014 1:42 pm |
|
|
You've not given the critical bit of data though.
Whether there is any 'lead time' between SS dropping, and the clocks?.
This really is critical.
Thing to understand, is that 1.25Mhz, is just under 10 instructions. Now, if you used this clock as your 'warning', you have no chance, unless you are sitting polling the edge detection, and doing nothing else. Even simply reading a serial byte and writing it to a buffer will take longer than this. Typically a buffer access takes about 10 cycles. Result bit missed....
However if (for instance), CS drops a few uSec, before the first clock, then this gives enough time to 'get ready'.
So, timings are everything. |
|
![](templates/subSilver/images/spacer.gif) |
Andrei S
Joined: 08 Aug 2014 Posts: 6
|
|
Posted: Tue Aug 12, 2014 1:56 pm |
|
|
SS drops and the rising edge of the clock comes in about 275ns later. I will then sample data on falling clock, just 250 ns after that.
Can I attach an image (scope screenshot) without hosting it?
Thanks again, |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19369
|
|
Posted: Tue Aug 12, 2014 2:24 pm |
|
|
Ouch.
Back to 'provided the PIC can be sat waiting'.
Is the time between messages fixed?.
If so then an software/hardware timer (interrupt tick with a counter), that expires perhaps 10uSec before the first clock. Go into the interrupt routine for this, and sit polling an interrupt flag on the rising edge of the clock. By the time you have detected this, you will already be 100nSec later. clear the interrupt (gives another cycle of delay), then read the data line, and rotate it into the int16. Decrement counter and loop if not zero. Then reset the timer interrupt, and exit.
It _might_ just be possible. Very much 'just' though. |
|
![](templates/subSilver/images/spacer.gif) |
Andrei S
Joined: 08 Aug 2014 Posts: 6
|
|
Posted: Wed Aug 13, 2014 11:07 am |
|
|
Holly smokes, in a dark corner of the FPGA board there is a jumper that controls the output SPI timing. Format still bad, but I can slow it down to the point that SS drops and the first clock is about 125us later and the clock freq is 2.5K.
I'll try to implement my fist software SPI then turn up the clock to see what I can get away with. Thanks all.
Quote: | Is the time between messages fixed?.
If so then an software/hardware timer (interrupt tick with a counter), that expires perhaps 10uSec before the first clock. Go into the interrupt routine for this... |
Ttelmah, thanks for the advice, admittedly I'll have to chew on that for a bit because I can't say that I understand. Thanks again,
Andrei |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19369
|
|
Posted: Thu Aug 14, 2014 12:53 am |
|
|
If the messages are at a fixed interval, then it is relatively (relatively...) easy, to have you hardware/code 'time' from when it completes the last 'receive', so it 'knows', when the next one is 'coming due'. This way it can stop doing other things, and sit waiting for the clock.
It is a pity that the jumper makes such a large change to the rate. 1000:1. 10:1, would shift it from 'difficult', to 'easy'.... |
|
![](templates/subSilver/images/spacer.gif) |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|