Shop Learn
P2 running the Parallax "96 x 64 Color OLED Display Module" Product ID: 28087 - SSD1331 — Parallax Forums

P2 running the Parallax "96 x 64 Color OLED Display Module" Product ID: 28087 - SSD1331

ke4pjwke4pjw Posts: 648
edited 2022-06-23 02:54 in Propeller 2
Development of this project has been moved to Azure DevOps SSD1331

Repo can be found here: SSD1331



  • I have updated the above to include a demo video and a ToDo list.

    I would appreciate some help in someone pointing me to where to read in the P2 manual about smartpin transfer speeds. I was under the impression that the smartpins were bound to the clock speed. This one is operating at 24KHz.
    1432 x 218 - 39K
  • jmgjmg Posts: 14,946
    ke4pjw wrote: »
    I would appreciate some help in someone pointing me to where to read in the P2 manual about smartpin transfer speeds..

    Which mode ?
    Async ones say this
    "WXPIN is used to configure the baud rate and word length.
    X[31:16] establishes the number of clocks in a bit period, and in case X[31:26] is zero, X[15:10] establishes the number of fractional clocks in a bit period. The X bit period value can be simply computed as: (clocks * $1_0000) & $FFFFFC00. For example, 7.5 clocks would be $00078000, and 33.33 clocks would be $00215400.

    X[4:0] sets the number of bits, minus 1. For example, a value of 7 will set the word size to 8 bits.

    Sync mode says this
    "Words of 1 to 32 bits are shifted out on the pin, LSB first, with each new bit being output two internal clock cycles after registering a positive edge on the B input. For negative-edge clocking, the B input may be inverted by setting B[3] in WRPIN’s D value.
    ie you need to create (or input) a clock on the B-Pin mapping, and that sets the baud rate

  • This is sync mode. My reading of this would indicate that at 160MHz, outputting a byte would be sending data at about 20Mhz. (Two clock cycles per bit at 160Mhz = 80Mhz. Only sending 8 bits (1/4th of 32 bits) lands me at 20Mhz. And I am not sure about that last bit. Either way, it should be way, way higher than 24KHz.

  • cgraceycgracey Posts: 13,718

    For the synchronous serial, you need to generate the clock, ideally using a smart pin.
  • The clock is being generated by the smartpin. Do I need to configure the bitperiod the same way I would for async?
  • The only thing that would have made this better is if the slow image load at the beginning were followed up by a blast of high speed animation that was tracked to the music :smiley:
  • jmgjmg Posts: 14,946
    ke4pjw wrote: »
    The clock is being generated by the smartpin. Do I need to configure the bitperiod the same way I would for async?

    Yes, only the clock timing is done in the clock-pin setup, not in the sync-shifter pin setup.
    You can ask for any clock up to SysCLK/2 onto a pin.
    Which mode does your clock smart pin use ?
  • jmg wrote: »
    Which mode does your clock smart pin use ?

    I will need to unpack that from the code. I pulled from examples that other forum members have given me. Quite frankly, the only thing I changed was to shift on a negative clock. The documentation isn't clear how bit period is configured for sync serial. Based on what you posted above, I think I know what I need to do!
  • evanhevanh Posts: 13,113
    Aww, looks a little out of control there. System clock setting is probably not working to requested speed with that 640 MHz setting in the the source code. The measured 24 kHz bit rate would indicate the system clock is likely around 200 MHz.

    I calculate the above from 24000 x 4096 x 2. The 2 is because two clock transitions per bit. 4096 because that's the transition period set on line 468 of test_AsmDrv.spin2.

    As for the system clock setting. You've made an error in comments of _XDIV, a value of 2 gives 10 MHz, not 5. This has caused incorrect calculation for the other components. Also, I'd recommend leaving _XDIVP = 1 unless going below 20 MHz. I know the docs say 100 MHz but that's a hugely conservative number.
  • ke4pjwke4pjw Posts: 648
    edited 2019-02-26 05:34
    I got a moment to work on it again this evening. Thanks for pointing out the problems in the code. I have updated the code to run the P2 at 320Mhz. Bitclock is now running at about 12Mhz. As we say down south, "It runs like a scalded dog!".

    I removed some of the unnecessary waits I added in the TX code. I had to add waits to the clear screen. My code would start sending data before the RAM on the display could finish it's task after a clearDisplay sequence was sent.

    I will try to clean this code up soon.

    Thanks for everyone's help.

    PS: I updated the video so you can see the end result. We might be able to implement a screen buffer on this bad boy! It's fast!
  • I am having too much fun with this. We have enough RAM and data throughput with the P2, we can animate.

  • Nice!
    If you overclock it will it take off? :lol:
  • Perhaps add in-place pixel rotation? (The method of multiple skew operations, search for "Three shears" here
  • Nice Mark! Yes this is just straight frame flipping as a proof of concept. I am going to attempt to find another short animation that has more motion just to see what it looks like. Maybe add an FPS counter. What made this so cool to me was I just changed a couple of lines a code to do it. The saving grace of this hack is that the frames are loaded into RAM sequentially. I hoped that fastspin would do that, and it did!
  • ke4pjwke4pjw Posts: 648
    edited 2019-02-28 06:18
    Last one. I did this one just for @cgracey

    Fastspin started segfaulting if the program was over 300K, so I was limited to 24 frames.

    Please don't look at the code. Zero cleanup. This was my first time using raw pixel data vs 16bit 565 bmp, so the offset is set to 0.
  • You know, I haven't been here since the start...can anyone fill me in on Chip's attachment to Fozzie?
  • ke4pjwke4pjw Posts: 648
    edited 2019-03-02 16:18
    I created two new videos that show off the smoothness of the display. I have determined the best way to create videos is to take video clips or animated GIFs and convert them with ffmpeg. Below is an example of converting a GIF.
    ffmpeg -vcodec gif -i "filename.gif" -vf scale=96x64:flags=lanczos -vcodec rawvideo -f rawvideo -pix_fmt rgb565 "filename.raw"

  • Looks great!
  • RaymanRayman Posts: 12,652

    Do you notice tearing when playing your video?
    I think I see some in your video, but hard to tell...

    It's too bad none of these displays bring out the "FR" signal that would let you sync to the device...

    It appears that up to ~60 fps is possible over SPI, if I'm reading the datasheet right...
  • It appears to be quite fluid. No visible tearing that I can see. If I have time this weekend, I will create a tearing test video for it to play.

    I will have to go back and look at my captures from the logic analyzer and see if there are gains that can be had tweaking the smartpins. I seem to recall I was clocking out at 25Mhz, but there were large gaps between the bytes. The buffer was a single frame as I recall. I do not recall that gaps between the frames. I was just thrilled to get it going :smile: In Spin no less.

    @cheezus updated his SD driver, which I use to pull the video from, so there may be some gains to be had there as well.

    When the P2ES2 is available, I am going to jump back into this.
  • ke4pjwke4pjw Posts: 648
    edited 2022-01-26 20:35

    So, almost 2.5 years later, I am looking at this again :)

    We now have an official spin2 from parallax and Eric's compiler is more aligned with that now. Also, this was developed on the Rev. A silicon.

    I am going to go through this code and update it to the modern spin2 implementation. I need a short break from the W6100 ethernet project and this will give me a helpful distraction.

  • I was able to get this to compile without warnings in FlexProp and it works as expected. Unfortunately, I cannot get it to work in PropTool, yet.

    Current code is attached at the top of this thread. If anyone has this hardware and wants to have a look at the code to see why it does not work in PropTool, that would be much appreciated. There are also bugs listed above.

    Breaktime is over, back to working on the W6100 :)

  • evanhevanh Posts: 13,113

    Is the PropTool problem functional issues or are we talking compile errors? Is it worth someone without the hardware looking at the problem?

  • ke4pjwke4pjw Posts: 648
    edited 2022-01-30 02:13

    @evanh It compiles, but there is no visible output on the display. I have not broken out the logic analyzer to see if it has a pulse. There is a lot of non-standard syntax in there and holdovers from back when we only had flexgui and peanut. I suspect the cog isn't starting, or something like that. It's worth a look. Probably something silly.

  • evanhevanh Posts: 13,113

    Okay, had a look ... weird, PropTool is confused, somehow it thinks it's a Prop1 program. Even weirder is it happily appends .spin2 to the AsmDrv filename.

    Check out the difference here between PropTool 2.6 on the left and PNut 35 on the right:

  • evanhevanh Posts: 13,113
    edited 2022-01-30 03:52

    BTW: I've made some changes to clock setting. Namely removed 100% of it and just let the _clkfreq constant do its thing instead.

    Here's my hack. It might work with the hardware.

  • That was a good find. However, it still only works in FlexProp. I appreciate you looking at it!

  • evanhevanh Posts: 13,113

    PropTool is behaving weirdly. Give PNut a shot.

  • evanhevanh Posts: 13,113

    Oh, the COGINIT() needs fixed too. It should be requesting a free cog rather than specifying a particular number:

    PUB start():okay
    '' Start SPI Engine - starts a cog
    '' returns false if no cog available
        okay := cog := coginit(COGEXEC_NEW,@main, @command) + 1

    Actually, commanding the display could really just be some sub-routines. No need for a whole cog to do it.

  • @evanh said:

    Actually, commanding the display could really just be some sub-routines. No need for a whole cog to do it.

    I have thought about reworking it that way. At the time I was just using the old paradigm. Would be really easy with inline PASM2. I might just do that instead.

    No dice with changing to dynamic cog allocation.

Sign In or Register to comment.