my ssd1306 can draw rectangles:
0x24
,0,
2, // row
fuzz_d2, // pattern to fill
4, // row
32 // xstart
,64 // xend
my ssd1306 can draw rectangles:
0x24
,0,
2, // row
fuzz_d2, // pattern to fill
4, // row
32 // xstart
,64 // xend
Interesting, I wonder if this would be performant compared to just continuously drawing the buffer, I think switching from data to command mode might take more time than just pushing the pixel buffer?
on spi this should be pretty fast, its just a pin that gets switched, on i2c this is not as good, because i have to raise sda, and send a start condition (slowly at 400khz to be compatible). but i have not benchmarked it, i guess the draw happens in the retrace like the scroll, the scroll is enormously fast if mux=1, i estimated i can scroll 3600px/second
i think the following can be done and should be tried:
trigger vsync frame display mux:1 → mux 63 → 150us wait mux 1
→ the display shows the current frame, either wait until it is finished (timer)
or just send data
now it is idling and doing retraces like crazy, do the following:
either just send display data, or if you send a scroll or draw_box command, just append enough nops (e3?) after the scroll, on i2c it is enough to append:
0xe3,0xe3,0xe3,0xe3,0xe3,0xe3,0xe3,0xe3,0xe3,0xe3,
after the mux 63, before the mux 1, so the ssd1306 hhas displayed more than one line (fastest freq setting i guess) on i2c this should be enough or just a few more nops (deppending how long the retrace takes) that these commands can just be inserted in the data stream and appear to happen at once… *if they are finished when the retrace is finished (because they are done in some way in the retrace like using the display x counter to write to vram or move vram or something like that) there will be no vram corruption when the engine writes…the only thing that needs to be done is to wait more than one or two retraces(?) at mux 1 by sending nops after the command…this can easily be tested, just transfer a image and send scroll, left,nops, scroll, right, nop, while idling on mux 1: when enough nops are appended the image should not move more than 1px because ne scroll commands are lost.
@bateske
i tested it:
on mux 1 i expanded my scroll and rectangle function by just adding nops until the operation is stable, i had to add 120 (added 132 for safety, so its a little faster in reality…) nops after my function:
void GfxApiSetDisplayDrawRect (u8 direction, u8 x_start,u8 row_start,u8 x_end, u8 row_end, u8 clear_pixels)
{
const u8 init1306[] = {
0,// 0xd6, 1, 0xda, fuzz_d2
0x24,direction,row_start,clear_pixels,row_end,x_start,x_end,
// 132 nop
0xe3,0xe3,0xe3,0xe3,0xe3,0xe3,0xe3,0xe3,
0xe3,0xe3,0xe3,0xe3,0xe3,0xe3,0xe3,0xe3,
0xe3,0xe3,0xe3,0xe3,0xe3,0xe3,0xe3,0xe3,
0xe3,0xe3,0xe3,0xe3,0xe3,0xe3,0xe3,0xe3,
0xe3,0xe3,0xe3,0xe3,0xe3,0xe3,0xe3,0xe3,
0xe3,0xe3,0xe3,0xe3,0xe3,0xe3,0xe3,0xe3,
0xe3,0xe3,0xe3,0xe3,0xe3,0xe3,0xe3,0xe3,
0xe3,0xe3,0xe3,0xe3,0xe3,0xe3,0xe3,0xe3,
0xe3,0xe3,0xe3,0xe3,0xe3,0xe3,0xe3,0xe3,
0xe3,0xe3,0xe3,0xe3,0xe3,0xe3,0xe3,0xe3,
0xe3,0xe3,0xe3,0xe3,0xe3,0xe3,0xe3,0xe3,
0xe3,0xe3,0xe3,0xe3,0xe3,0xe3,0xe3,0xe3,
0xe3,0xe3,0xe3,0xe3,0xe3,0xe3,0xe3,0xe3,
0xe3,0xe3,0xe3,0xe3,0xe3,0xe3,0xe3,0xe3,
0xe3,0xe3,0xe3,0xe3,0xe3,0xe3,0xe3,0xe3,
0xe3,0xe3,0xe3,0xe3,0xe3,0xe3,0xe3,0xe3,
0xe3,0xe3,0xe3,0xe3,0xe3,0xe3,0xe3,0xe3,
};
os_i2c_write(init1306, sizeof(init1306));
}
this is something i can just call and it has finished drawing when it returns. obviously it would be more clever to not send nops and trigger the command with a timer and use the calculation time otherwise
the size of the rectangle (or scroll area is irrelevant).
when i this it taks 2100us for one screen clear. in the same time i can send about 130 byte to the display vram. (everything on my terrible fuzzing test application)
→ one can clear the screen / perform a scroll 475 times a second using this
3. 891.200 → 3.8 megapixel fill rate for the commands (if they modify the whole screen, the fill rate will half when drawing only the half screen)…
(the number of nops should not really matter, this is just my esp32 hack i use to test, i don’t even know how fast the bitbanged i2c is right now)
at mux 1, precharge 0, freq 0xf0, i can get it down to 1700us
→ 580 clears /s