Lines 20..30 do exactly what an update of the display - also called/referenced by the term flip (buffer over to display) needs to do. Including the control data for the flip with the image data is though a mixup of concerns and a bad thing. Writing to the image buffer should not be impaired by the way the buffer has physically to be moved over to the display - in this case it is not even buffer to buffer - it is ongoing like the very old technology of dual ported ram used in the past for drawing the CRT / TV screen in sync with the drawing electron ray, 60 times - or what ever - per second, interleaved (on with slower memory, slower refresh rate) or not interleaved (with faster memory, higher refresh rate).
Separation of the concerns allows you to use the Graphics library of Espruino, a really really cool thing. Furthermore, it helps with separate timings and allows also have more than one buffer to keep currently displayed image stable while next screen update is prepared (The application knows when the (partial) update is complete and trigger a flip from build into the display buffer.
Take a look at Graphics library, sections Drivers and Internal Use. Start out with the concept used for the Charlieplex LED Driver and transform its parallel output into serial output. Instead of having a 8 x 3 x 1 pins - a pin per col (or row) 1 per color (for each R, G, and B color - color depth 3) - you have one pin and send the data serialized through that pin... - lines 24..26 - and to select the proper row (or col), you send an extra byte with just the bit in the byte on (or off) to for that row (or col) - line - 27.
Using the Espruino Graphcs lib you get all sorts of things for free: drawing lines, shapes outlined and filled, fonts, clear, set foreground and background color, etc., and even rotation. And when you write your own set/get/clear pixel graphics, it even even makes your work portable. The Espruino Graphics lib normalizes all for you.
Looking at the raspi code that is used to drive the display, it makes me understand that one 595 covers one color... in other words: the pixels are grouped by color: for example, first all all R bits - for all cols - are sent out, then all G bits, then B bits, and then the row selector.
Since the display has no buffer, you have to provide it... Initially I though you could use the Graphics buffer directly for that. But since the graphics buffer bundles the bits by pixel, it is not exactly what you are looking for. The flip implements the re-bundling. To accelerate the flip, you may run it compiled - Yes, Espruino can do that with portions of JavaScript, like inline Assembler.
Choosing the right buffer contributes also to speed. Espruino by nature stores information in 'very' small, linked blocks scattered over the memory space, which creates overhead for something like a straight forward DMA / streaming. But over time Espruino has also added ways to ask for contiguous buffer to support such things most effective.
For the .flip() from graphics - where the application draws - into display buffer - that feeds the display - the re-bundling has to happen in a way like this:
*** .flip():***
collecting red bits for 8 pixels and sticking it into one byte of display buffer.
collecting green bits for 8 pixels and sticking it into next byte of display buffer.
collecting blue bits for 8 pixels and sticking it into third byte of display buffer.
adding a byte with row bit set and sticking it into fourth byte of display buffer.
Keep doing this for all all rows. If there are more than 8 pixels in a row (more than 8 cols), do steps 1. thru 3. as many times as needed to cover a full row (all cols).
If there are more rows than 8 rows, add as many bytes as needed to cover all rows.
*** .updateDisplay():*** continuously within setInterval construct
set nss low.
ship bytes for one row one after the other
set nss high (latches the data and it shows in that row)
Keep doing this for all rows. If done for all rows, start over.
Espruino is a JavaScript interpreter for low-power Microcontrollers. This site is both a support community for Espruino and a place to share what you are working on.
Lines 20..30 do exactly what an update of the display - also called/referenced by the term flip (buffer over to display) needs to do. Including the control data for the flip with the image data is though a mixup of concerns and a bad thing. Writing to the image buffer should not be impaired by the way the buffer has physically to be moved over to the display - in this case it is not even buffer to buffer - it is ongoing like the very old technology of dual ported ram used in the past for drawing the CRT / TV screen in sync with the drawing electron ray, 60 times - or what ever - per second, interleaved (on with slower memory, slower refresh rate) or not interleaved (with faster memory, higher refresh rate).
Separation of the concerns allows you to use the Graphics library of Espruino, a really really cool thing. Furthermore, it helps with separate timings and allows also have more than one buffer to keep currently displayed image stable while next screen update is prepared (The application knows when the (partial) update is complete and trigger a flip from build into the display buffer.
Take a look at Graphics library, sections Drivers and Internal Use. Start out with the concept used for the Charlieplex LED Driver and transform its parallel output into serial output. Instead of having a 8 x 3 x 1 pins - a pin per col (or row) 1 per color (for each R, G, and B color - color depth 3) - you have one pin and send the data serialized through that pin... - lines 24..26 - and to select the proper row (or col), you send an extra byte with just the bit in the byte on (or off) to for that row (or col) - line - 27.
Using the Espruino Graphcs lib you get all sorts of things for free: drawing lines, shapes outlined and filled, fonts, clear, set foreground and background color, etc., and even rotation. And when you write your own set/get/clear pixel graphics, it even even makes your work portable. The Espruino Graphics lib normalizes all for you.
Looking at the raspi code that is used to drive the display, it makes me understand that one 595 covers one color... in other words: the pixels are grouped by color: for example, first all all R bits - for all cols - are sent out, then all G bits, then B bits, and then the row selector.
Since the display has no buffer, you have to provide it... Initially I though you could use the Graphics buffer directly for that. But since the graphics buffer bundles the bits by pixel, it is not exactly what you are looking for. The flip implements the re-bundling. To accelerate the flip, you may run it compiled - Yes, Espruino can do that with portions of JavaScript, like inline Assembler.
Choosing the right buffer contributes also to speed. Espruino by nature stores information in 'very' small, linked blocks scattered over the memory space, which creates overhead for something like a straight forward DMA / streaming. But over time Espruino has also added ways to ask for contiguous buffer to support such things most effective.
For the
.flip()
from graphics - where the application draws - into display buffer - that feeds the display - the re-bundling has to happen in a way like this:*** .flip():***
Keep doing this for all all rows. If there are more than 8 pixels in a row (more than 8 cols), do steps 1. thru 3. as many times as needed to cover a full row (all cols).
If there are more rows than 8 rows, add as many bytes as needed to cover all rows.
*** .updateDisplay():*** continuously within setInterval construct
Keep doing this for all rows. If done for all rows, start over.