TinyCircuits / TinyCircuits-Thumby-Code-Editor

https://code.thumby.us/
GNU General Public License v3.0
30 stars 20 forks source link

OLED GDDRAM is not cleared on initialisation #52

Closed ace-dent closed 1 year ago

ace-dent commented 1 year ago

Problem:

When working with a customised main.py, we cannot rely on the screen buffer overwriting the OLED onboard 'Graphic Display Data RAM' (GDDRAM). This can lead to the unexpected result of showing random data on first boot, or restoring the last image after a reset. Data persists after power cycling On 0xAF / Off (sleep screen) 0xAE, and also Reset (toggling GPIO pin 20) does not clear the GDDRAM. This makes sense for some applications; it allows quick resume from sleep without the MCU needing to resend the last screen.


This function was originally provided with self.fill(0) lines (now commented out/ removed).

Proposed solution:

Zero the OLED RAM whenever we initialise the display:

Note: I have a working code solution and can provide a PR, if this approach is acceptable. It could be argued that clearing the GDDRAM could happen at various points- I just went for the lowest level controller.

ace-dent commented 1 year ago

From testing my proposed solution ~

# @micropython.native
def clear(self):
    self.write_window_cmd()
    self.write_data(bytearray(360))

Benchmarking with micropython.mem_info() shows it adds +448 bytes before GC / +48 bytes after GC. Using @native adds +608 bytes before GC / +208 bytes after GC. I don't think execution speed is rate limiting here, as we have to wait on SPI transfers... suggest saving ~160 bytes RAM and not using native.

masonova1 commented 1 year ago

This makes sense to me. If you want to do a PR, I'll take it; Otherwise, I can implement as well. Clearing on-init seems to be the most sane option here.

ace-dent commented 1 year ago

Thanks @masanova1. Wasn't sure if we should do this in main.py (effectively what we've been doing)- as it adds an opportunity to inject graphics... but then again, it is functionally related to init the SSD1306... I wanted to hard-code the number of bytes but waiting on feedback here.

I already have the PR ready. Just let me know. Cheers.

masonova1 commented 1 year ago

upon further review, we've decided to just add back the self.fill call - We aren't sure why it was removed to begin with, and the optimization of a single-frame clear on initialization isn't critical here. Thanks for pointing it out.

ace-dent commented 1 year ago

This solution may be sub-optimal. It relies on overwriting the MCU buffer then copying the buffer into the OLED GDDRAM. There may be a situation where we want to init the OLED and keep the buffer intact (or vice versa).

masonova1 commented 1 year ago

Reopened to see if this has any way of impacting the emulator - this may not be necessary there. Are there any examples of persistent OLED garbage through restart for the emulator?

Secondly, I agree. we're going with display commands.

ace-dent commented 1 year ago

+1 I like your fix; short and sweet! No need to add to the emulator (I would guess it initialises with a zero filled array).

masonova1 commented 1 year ago

Sounds good. Closing for now.