Using the video generator for SPI, i2s etc
Ahle2
Posts: 1,179
I realized that It might be a good idea to share a piece of code that has been lying on my self for a couple of years now.
It's a video-generator-driven SPI driver. I think it's possible to use the same "trick" for other serial protocols as well. (i2s?)
The thing is that it's actually possible to do some crunching simultanesouly with an byte being transfered using the video generator.
In short it works like described below.
Each byte in a data stream is picked from a table in cog memory (address 0 - 255). Evey position in the table has got an 8bit value and the clock interleaved.
The video generator is then setup in certain way to output a clock signal on one pin and the bit stream on another pin.
I will soon upload something... stay tuned!
It's a video-generator-driven SPI driver. I think it's possible to use the same "trick" for other serial protocols as well. (i2s?)
The thing is that it's actually possible to do some crunching simultanesouly with an byte being transfered using the video generator.
In short it works like described below.
Each byte in a data stream is picked from a table in cog memory (address 0 - 255). Evey position in the table has got an 8bit value and the clock interleaved.
The video generator is then setup in certain way to output a clock signal on one pin and the bit stream on another pin.
I will soon upload something... stay tuned!
Comments
Because then I can't output both clock and data simultaneously without any pasm intervention.
I can simply do
How long does the video generation technique take to start up and tear-down? - surely the PLL has to stabilise (haven't seen this mentioned in the manual - perhaps its very quick).
Give it some milliseconds to stabilize, but it is one time job.
The PLL is set at startup and isn't touched after that.
It's then up to the code to feed the video generator at a steady rate.
I was able to achieve true 20 Mbit from hub-RAM to SPI-RAM on my C3 without any hickups. when the PLL was aligned to the hub window.
I am pretty sure it's possible to do better than that with some clever unrolling in combination with rdlong. (of course, the SPI-RAM on the C3 can't handle more than 20 Mbit)
It was more than a year ago I did anything on this. First of all I have to locate the code somewhere on my drives.
Then I may have to do some code cleaning.
Thanks,
Ahle2 is talking about using the video generator to output SPI at 20Mhz while freeing the COG to do other work.
C.W.
I've been looking at the code for both FSRW and the FATEngine... and as far as I can tell they only bursts out bytes at 20 Mbit. The real continuous performance from hub RAM to SPI is far less.
I'm talking about a loop of "rdbyte-from-HUB-output-to-SPI-RAM" with a real bandwidth of 20 Mbit witouth any kind of hickup. That's impossible with the technique used in the objects you are talking about, because you can't read data from hub simultanously with an byte being sent.
Since the video generator obviously can't read data, I am not able to boost read performance though.
But I think it's possible to do more than 20 Mbit (hopefully 40 Mbit) for I2S and other "oneway protocols" with my technique. And that's where it's getting interesting.
This
Can be replaced with
"0-0" can be any byte value and will point to the LUT.
Both clock and data are interleaved in the lookup.
Here's the code to generate the interleaved clk+data LUT from address 0 to 255
The video generator is then initialized for 4 color VGA mode on pin group 1 (where the SPI pins are on the C3) and the pixel clock is set to 40 Mhz (since each spi clock equals two "pixels")
For it to work I need to setup the 4 "colors" as seen below.
When everything is setup correctly, a simple
will send a full byte on the SPI bus.
X is the byte to send.
PCM1795DB seems like a good candidate for my experiments, has anyone tried it?
[h=1][/h]
No, but its got current outputs (needs dual RtR opamp on output), and has an SPI interface - the WM8759 is cheaper, is simpler to solder (SOIC14), can drive headphones directly and doesn't need any SPI programming so takes up fewer Prop pins.
I can almost buy 10 x WM8759 for the same price as one PCM1795DB. I think I will order 6 pcs for some experimentation!
I've got an MPC4922 (two channel 12 bit thru-hole DAC) hooked up via SPI to my SpinStudio board. I can successfully drive audio rate (48khz) through out, but only one channel. Once I get to two, the cog I'm using can't keep up and I have to drop the bitrate below 20khz. I'm doing this all in propgcc (C++ code, lmm mode FWIW.)
Anyways, came across this old post, and was wondering if the WAITVID technique is applicable here. Seems like a lot of the time in my loop is spent iterating the bits in the word to toggle the serial output line; seems like waitvid could be used to send all 16 bits per channel (or 32 bits for both channels?) at once?
Unfortunately I'm also a bit of a propeller newbie (have had this board for years and just learning it now) and PASM is unfamiliar to me, and the video generation hardware even more so.
Any tips on how to set up the video hardware for doing SPI this way? I'd _love_ to be able to push high bitrate audio out this way to the DAC.