Shop OBEX P1 Docs P2 Docs Learn Events
uOLED-96-Prop - COG-OBJECT - First Draft — Parallax Forums

uOLED-96-Prop - COG-OBJECT - First Draft

Greg PGreg P Posts: 58
edited 2007-11-23 06:59 in Propeller 1
If my first attempt using the "attachment manager" succeeded, you should have a first-draft of a cog-based uOLED-96-Prop graphics object to play with over Thanksgiving. The demo reads an image file (.txt) from the uSD card, two-rows of image data at a time (filling a 384 byte buffer), then writes the buffer contents to the OLED display controller using the cog-based object. Using my 2GB uSD card, I was able to read the SD & write the image in less than 60 mS ! I have included in the ZIP file a few .txt image files which you may copy into the uSD card's root directory for experimentation. I didn't include the "movie.txt" file due to its size, but it's just a concatenation of 118 .txt image files. You should comment out this section if not used.

This version is just a first draft. It works ... my uOLED-96-Prop is still running (I didn't destroy anything while playing around), but it is far from optimized. The /CS and DC lines do not need to be toggled for every couple of bytes written. Also, ideally, in the final version, the SD card object should be instructed to directly write to the uOLED the entire image without SPIN intervention. In this case, two buffers could be used, and the data double-buffered for maximum throughput. The goal is a 30 fps video rate, but this will require (perhaps) a speedup of the FAT16 object using Multiblock read instructions where the host controller of the uSD card is internally reading data from flash memory while simultaneously sending via SPI its cached buffer contents (from the previous operation) to the Propeller. I don't know if this speedup will be significant like it might with Multiblock write operations, but it is certainly worth a try.

Please note, while my code has apparently not harmed my uOLED-96-Prop, and I have closely followed the sequence of graphics controller setup instructions provided by 4D systems in their SPIN code, even adding to the .stop method a delayed power-down sequence, I can't guarantee that it will not harm your device in some unexpected manner. I don't think it will ... it's just a disclaimer in case I goofed. You may wish to double check my work before uploading. Enjoy and improve.

Comments

  • BaggersBaggers Posts: 3,019
    edited 2007-11-20 21:53
    Greg, As you may or may not be aware, I've done lots with streaming from SD, just a quick question, when you're reading in bytes, how many bytes at a time are you reading? make sure it's in 512byte chunks, as it's FASTER that way, if not, pad the files so they're in multiple of 512 bytes.

    Baggers.
  • Greg PGreg P Posts: 58
    edited 2007-11-21 00:05
    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
    NOTE: THE "CMDWRITE" OPERATION OF THE COG-BASED OLED OBJECT HAS NOT BEEN TESTED !!! SORRY, I DID SAY IT WAS A FIRST DRAFT !!! THE "DATAWRITE" WORKS FINE.

    PLEASE EXERCISE CAUTION, I.E., DON'T CALL "CMDWRITE" UNLESS YOU HAVE CAREFULLY EXAMINED THE CODE FIRST. MY APOLOGIES.
    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

    Regarding the 512-bytes:

    Its my understanding that the "SDFAT" (fsrw) object is at least internally reading in 512 byte chunks. The "sdspiqasm" SPI cog object's readblock() and writeblock() functions set their loop counters to a fixed size "sector" in the shared "mov ctr2,sector" statement. Sector is defined as a cog long = 512.

    The SDFAT (fsrw) object has its own internal buffer, buf(512), that is filled by its pfillbuf() function. Pfillbuf() calls the sdspi readblock cog-code, filling buf() when necessary to satisfy the request for additional data. The public function pread() then uses a bytemove SPIN instruction to transfer data from the internal buf() buffer to the user's buffer, ubuf().

    If new code could be added to the SDFAT (fsrw) object, call it pread_auto(), this code could be made to repeatedly and automatically write DIRECTLY to the graphics controller's internal GRAM buffer, bypassing the user buffer write entirely. This, however, may not actually be the most convenient approach as it would mix the OLED object and SDFAT object and things would become less modular. Having an intermediate pair of hub buffers between the SDFAT and OLED objects may actually have a throughput advantage as one buffer may be written to by the SDFAT object will the other may SIMULTANEOUSLY be read by the OLED object. The two objects could be made to alternate between the two buffers. Since the SD card read is likely to be slower than the OLED graphics write, the OLED object will finish its read of buffer 1, then switch to buffer 2, awaiting new data from the SDFAT object. This could go on indefinitely until the end-of-file or a stop read command is issued to the SDFAT object.

    Using my logic analyzer I noticed that the first 3 reads (of 384 bytes) are fairly slow, while the final read ( of 384 bytes) is fast. This pattern repeats during the entire image transfer. Note: 384 bytes x 4 = 1536 bytes = 512 bytes x 3. I'm guessing the SDFAT object does not have to access the uSD card via SPI during that last read, that data is simply copied from SDFAT's internal buf() buffer. At the lower sdspi cog object level each of the first 3 reads of 384 bytes require that readblock() is executed.
  • ribbotsonribbotson Posts: 7
    edited 2007-11-22 18:42
    Sorry, to ask a rookie question when you guys are moving along so fast.
    but.. How do I create the 96 * 64 565 format text files ?

    Thx
  • Greg PGreg P Posts: 58
    edited 2007-11-23 06:59
    I used some old Visual Basic 6 code. LoadPicture() function was used to load the JPG image into a picturebox. There were then some Windows functions which allow·me to access the individual red,green, and blue values for individual pixels. I checked the size of the imported image then chose a value "m" such that 96m x 64m pixels of the original were processed. The simple trick is "color averaging". Simply add the red,green, and blue·values for ALL PIXELS in a block of pixels from the original image, then divide these totals by the number of pixels in the block. This yields the "average" color for a single pixel in the final 96x64·uOLED-96-Prop·image. I then shrink the Red,Green,Blue values to the 16-bit format, and save it LSB first to a file. To test, I·wrote some VB code to read the·image file and reconstruct the image in a picturebox in VB, before moving to Propeller.·The latest version can "batch process" an entire directory of JPG images, create small BMP output image files, and the "txt" image·files for use by the Propeller. I guess I could have used the·4D system composer software but I had this code available from an earlier project.
Sign In or Register to comment.