Shop Learn P1 Docs P2 Docs
C++ super fast SPI output — Parallax Forums

C++ super fast SPI output

threadzthreadz Posts: 56
edited 2015-01-11 17:22 in Propeller 1
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:
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

  • KyeKye Posts: 2,200
    edited 2015-01-08 16:31
    The Propeller can do 20 MHz SPI burst rates. You have to use a counter to generate the clock and some very carefully coded instructions to write out the data. You can fit all the code you need in an FCache loop. However, if you're going to be sending data continuously you might as well just launch a cog and have it DMA the data out through the SPI bus. See, the ASM in this object for what to do for 1-bit SPI output. http://obex.parallax.com/object/16

    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
  • threadzthreadz Posts: 56
    edited 2015-01-08 17:45
    Thanks for the advice, and I will defiantly put it to use for faster data transfer to my other SPI devices. But I figured out another way to get my project to work:

    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.
  • twm47099twm47099 Posts: 867
    edited 2015-01-08 18:04
    I've developed an C SPI library that uses the modified PASM code from SPI_Asm.spin (taken from the Prop Tool Library) in this thread:
    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
  • threadzthreadz Posts: 56
    edited 2015-01-09 09:49
    AWESOME! Thanks 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*)
  • jmgjmg Posts: 14,950
    edited 2015-01-10 13:42
    threadz wrote: »
    .... But I figured out another way to get my project to work:

    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.

    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.
  • Mark_TMark_T Posts: 1,981
    edited 2015-01-11 11:47
    Kye wrote: »
    The Propeller can do 20 MHz SPI burst rates.

    You can do a lot more than that using waitvid if only outputing and not reading MISO.
  • threadzthreadz Posts: 56
    edited 2015-01-11 13:09
    Mark_T wrote: »
    You can do a lot more than that using waitvid if only outputing and not reading MISO.
    Really? How?
  • kuronekokuroneko Posts: 3,623
    edited 2015-01-11 14:14
    threadz wrote: »
    Really? How?

    Have a look over here http://forums.parallax.com/showthread.php/143679-Looking-for-methods-for-fast-SDI-or-SQI to get you started.
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2015-01-11 17:22
    I use 4MHz clock rate SPI instructions in my Tachyon kernel, these instructions co-exist with other instructions and take up very little cog memory and of course do not require a dedicated cog. Now the problem I see with dedicating a cog to SPI to have it run faster (at least in transmitting) is that it does not necessarily translate to higher throughput as there are bottlenecks elsewhere and one is the speed of the application itself. My smartphone may be able to issue a GET and all that data may be received and buffered in a fraction of a second but it still has to render that data in the browser which seems to take a second or more, so high transfer rates don't really help that much sometimes
Sign In or Register to comment.