C++ super fast SPI output
threadz
Posts: 56
While converting the code for a LCD display (the HXD850 from adafruit) I discovered that the Shift out command in the simpletools.h library is painfully slow.
After some revisions I was able to roughly double the output speed by doing this:
It only works for MSB first, but it's faster than the orriginal and will still be faster with another if block to make LSB first work. This got me wondering: what is the absolute fastest speed the propeller can send data over an SPI Bus?
Also - more specific to my project - what is the fastest speed that the propeller chip can send the same 16 bits of color data about 153 thousand times? Specifically, to fill a screen buffer with a single 16 bit color because the screen lacks any "set all pixes to this color" function.
The screen also has an 8 bit parallel thing for communication, but the total pin usage count for that mode is about 15, and I need atleast 20 others to be able avalible to interface with the other devices in project.
Is there some way to further up the speed by using counters or 2 cogs that are 2 clock cycles out of sync with eachother operating on each alternating bit, or some other fancy way to pull this off? I have some extra crystals lying artound so I'd willing to try overclocking.
If not, can you recommend a different 3.5 to 4.5 inch diagonal LCD module that has built in graphics processing?
Sorry if the formatting fails, I'm on mobile because my WiFi epic failed.
After some revisions I was able to roughly double the output speed by doing this:
void shiftOut (int doPin, int clkPin, int mode, int bits, int value) { int mask = 1 << bits; DIRA |= ((1 << clkPin) | (1 << doPin)); OUTA &= ~((1 << clkPin) | (1 << doPin)); do { if(mask & value) OUTA |= (1 << doPin); OUTA |= (1 << clkPin); mask >>= 1; OUTA &= ~((1 << doPin) | (1 << clkPin)); } while (buff); }
It only works for MSB first, but it's faster than the orriginal and will still be faster with another if block to make LSB first work. This got me wondering: what is the absolute fastest speed the propeller can send data over an SPI Bus?
Also - more specific to my project - what is the fastest speed that the propeller chip can send the same 16 bits of color data about 153 thousand times? Specifically, to fill a screen buffer with a single 16 bit color because the screen lacks any "set all pixes to this color" function.
The screen also has an 8 bit parallel thing for communication, but the total pin usage count for that mode is about 15, and I need atleast 20 others to be able avalible to interface with the other devices in project.
Is there some way to further up the speed by using counters or 2 cogs that are 2 clock cycles out of sync with eachother operating on each alternating bit, or some other fancy way to pull this off? I have some extra crystals lying artound so I'd willing to try overclocking.
If not, can you recommend a different 3.5 to 4.5 inch diagonal LCD module that has built in graphics processing?
Sorry if the formatting fails, I'm on mobile because my WiFi epic failed.
Comments
You're going to have to program this in ASM. You may find it easier and more reliable to program the code in SPIN and have it linked in as a binary blob. But, if you carefully program your code in a cogc file you should be able to get near optimum results if you keep the number of variables to an absolute minimum and don't use _cogmem registers. See the following post for how to write a cogc program: http://forums.parallax.com/showthread.php/159071-_COGMEM-Automatic-Variables
I'll use 2 parallel to serial shift registers and some counter cleverness to reduce the number of pins I'm using for interrupts from 13 to 3 (CLK output, enable pin, and data pin). This will free up the pins necessary for the 8 bit parallel interface with the LCD.
If my math is correct will allow me to move data more than double the fastest speed achievable by SPI.
http://forums.parallax.com/showthread.php/157441-Can-SPI-in-Simple-Libraries-be-speeded-up
The thread shows my adventures in learning how to incorporate PASM in a C program. The result is an SPI function that can have a clock rate of about 3MHz.
Post 67 (on page 4 of the thread) has a zip of the library I put together along with demos for the DS1620 digital thermometer and the MMA7455 3 axis accelerometer. Posts 68 and 69 added code for the MCP3208 ADC.
Tom
(I actually was not aware that you could embed SPIN in a C++ project.
All the time I spent trying to convert PASM to inline ASM....*sigh*)
If you add this level of HW, you should be able to also do a very fast pixel-flood, by loading the SPI registers, and then running a separate LCD strobe/mux, so you skip needing load for every pixel.
You can do a lot more than that using waitvid if only outputing and not reading MISO.
Have a look over here http://forums.parallax.com/showthread.php/143679-Looking-for-methods-for-fast-SDI-or-SQI to get you started.