I hope you can get your replacement screen soon.
I can confirm now you can change the memory mode without doing a full reset. So for example your text routines can be optimized for 3bpp mode and then if you want to support higher depth graphics you can just change the mode and render more colors.
-Dave
That sounds nice, but it adds way more complexity to the design, and may very well be slower in practice due to the added complexity.
If youâre using a shadow frame buffer that is blasted down all at once, you could reset the âfull depthâ flag on a screen clear, and only set the flag if something renders in a âcomplexâ color. Based on that flag, either blast down two pixels per byte or two bytes per pixel.
EDIT - I think I posted these numbers elsewhere, but I can do a screen full of 8x8 text in 11.2ms in 3bpp mode, and 34.4ms in 16bpp mode. This is by sending down 320x8 regions one row at a time.
The problem with this approach for the PicoCalc terminal emulators, both graphical and text-only is that they use a âdirty rectangleâ approach where all graphics or text in a dirty rectangle is draw to the screen line-by-line at once regardless of whether a given pixel itself was updated or not.
As a result, to implement this approach each pixel or character in a line would have to be tested for whether it could be represented with 3-bit color or not, which would add extra overhead that would offset any gains from 3-bit color.
Nice find. Too bad we cannot set a palette for 3-bit mode.
Yeah, the choice to do 1bpp mode as direct color value is quite⌠odd. Were it palette-based, itâd be an optimal choice for text rendering, but as is, the utility of 3bpp display is quite limited.
Has anyone tried a practical implementation of the 565 16bpp mode for display? Itâs mentioned once in the 4-wire mode info, but never described as a pixel format for it â though apparently works, and is apparently the mode MicroPython uses routinely for ili9488. I need to take a closer look at how MicroPython handles the packets to understand the format better.
16bpp would still substantially reduce the amount of data transfer needed, esp. using partial updates, yet leaves plenty of colorspace for most purposes.
For zeptoforth on the PicoCalc I use RGB565 mode for communicating pixels to the display even though I use RGB332 for my actual framebuffer in order to have only one byte per pixel. I have had no problems with RGB565 even though the ILI9488 does not support it with the IM setting that is specified in the schematic, indicating that it is not a real ILI9488 display.
Yes in picocalc-lua (and many others)
I created a heavily character optimized display driver (no graphics) which doesnât use a frame buffer, similar to PicoCalc-Lua. I know this because when I was building my driver I learned from anything I could get my hands on.
It will write text and scroll at about 425 lines per second with an average of 25 characters per line.
It âbrokeâ out of nowhere on the weekend where the colours became messed up after working fine for many days. I may have been pushing data too fast (guessing) since I finally fixed it with a âmagicâ sleep_us.
I dug into this a bit more, and according to the datasheet on the PicoCalc GitHub repo, the maximum SPI clock frequency is 62.5 MHz, but it seems operate ok with a overclock of 75 MHz so this was not the problem.
I am now thinking that my magic sleep worked because I must not have been respecting the minimum chip select âHâ pulse width. I replaced the sleep with a series of nop instructions to wait about 40ns and it has been stable (so far).
My understanding is that the function to set spi speed (spi_init) actually ârequestsâ that speed, and sets the divider of the main frequency to something close to what you requested. 75MHz might be clipped to a lower frequency this way. The highest I have been able to make it work is between 50 and 60MHz. Beyond that there is a transition where pixels get corrupted, and then the display stops working altogether.
Well, the spi_init() call does return that it selected 75Mhz and I do notice a speed increase when switching between 60Mhz and 75 MHz. This discussion is really pushing me to hook it up to the 'scope to see what is happening.
You can try spi_get_baudrate to read the spi speed
Necroing the thread here, but thinking about balancing framebuffer size with color depth and framerate, you might be able to have the best of all worlds by storing a framebuffer in whatever format you like, DMA that framebuffer to a PIO which will pad the bits out to the 666 format, and then DMA that back to the SPI controller.
For example you could store 3/2/3 bits per pixel in your framebuffer, 1 Byte per pixel, and then have the PIO program pad each channelâs components with zeros for 666.
You could probably also palletize 8 colors this way, not getting the FPS benefit but you could store 24 pixels in 8 bytes of framebuffer
Combining this with only redrawing areas of the screen that have changed might make for reasonably snappy and highly colorful displays without too much CPU overhead.
What I do is use a lookup table to convert RGB332 (which I chose to save SRAM and because blue is the color that humans are least sensitive to) to RGB565 in RAM on a line-by-line basis prior to sending each line to the display. A similar scheme could potentially be used to select an arbitrary palette rather than hard-coded RGB332 color as I have chosen.
line by line with a lookup table is also how the SMS Plus emulator renders, so thatâs a good trick for speedy full-screen updates :] (thereâs also the fact that there isnât a full framebuffer as the background tiles and sprites are generated line-by-line on the fly from VDP registers and VRAM as well)
This is something I do in zeptoforth â I keep track of a âdirty rectangleâ so that when I update the display I only send over what is necessary for the changes that have been made. This enables significantly speeding up display updates if only small portions of the display have changed.
In my text-only PicoCalc terminal emulator (as opposed to my graphical PicoCalc terminal emulator) I create the image data for each line on the fly, line by line, so I can avoid keeping a big framebuffer in SRAM. This is necessary for zeptoforth to be practical with PicoCalcs with an RP2040 installed (but I donât use it much because I use an RP2350 in my PicoCalc) as the graphical framebuffer does not leave much SRAM left on the RP2040 with everything else (e.g. the zeptoforth kernel and the flash dictionary index) that is also in SRAM.