pico_epaper_42 drivers async refresh: improve means of limiting blocking time.

pull/70/head
Peter Hinch 2024-07-04 18:50:23 +01:00
rodzic 7ecabf0fc1
commit df7656802a
3 zmienionych plików z 15 dodań i 7 usunięć

Wyświetl plik

@ -1447,6 +1447,10 @@ needed in more advanced asynchronous applications and their use is discussed in
seconds to enable viewing. This enables generic nanogui demos to be run on an
EPD.
Class variable:
* `MAXBLOCK = 25` Defines the maximum period (in ms) that an asynchronous
refresh can block before yielding to the scheduler.
Note that in synchronous applications with `demo_mode=False`, `refresh` returns
while the display is updating. Applications should issue `wait_until_ready`
before issuing another refresh.

Wyświetl plik

@ -118,6 +118,7 @@ def _linv(dest: ptr32, source: ptr32, length: int):
class EPD(framebuf.FrameBuffer):
MAXBLOCK = 25 # Max async blocking time in ms
# A monochrome approach should be used for coding this. The rgb method ensures
# nothing breaks if users specify colors.
@staticmethod
@ -229,7 +230,7 @@ class EPD(framebuf.FrameBuffer):
self._cs(1)
# Time to convert and transmit 1000 bytes ~ 1ms: most of that is tx @ 10MHz
# Yield every 16 transfers means blocking is ~16ms
# Yield whenever code has blocked for more than EPD.MAXBLOCK
# Total convert and transmit time for 15000 bytes is ~15ms.
# Timing @10MHz/250MHz: full refresh 2.1s, partial 740ms: the bulk of the time
# is spent spinning on the busy pin and is CPU frequency independent.
@ -238,14 +239,15 @@ class EPD(framebuf.FrameBuffer):
fbidx = 0 # Index into framebuf
nbytes = len(self._ibuf) # Bytes to send
nleft = len(self._buf) # Size of framebuf
npass = 0
tyield = time.ticks_ms() # Time of last yield
while nleft > 0:
self._bsend(fbidx, nbytes) # Invert, buffer and send nbytes
fbidx += nbytes # Adjust for bytes already sent
nleft -= nbytes
nbytes = min(nbytes, nleft)
if not ((npass := npass + 1) % 16):
await asyncio.sleep_ms(0) # Control blocking time
if time.ticks_diff(time.ticks_ms(), tyield) > EPD.MAXBLOCK:
await asyncio.sleep_ms(0) # Don't allow excessive blocking
tyield = time.ticks_ms()
self.updated.set()
self._command(b"\x12") # Nonblocking .display_on()
while not self._busy_pin(): # Wait on display hardware

Wyświetl plik

@ -112,6 +112,7 @@ def _lmap(dest: ptr8, source: ptr8, pattern: int, length: int):
class EPD(framebuf.FrameBuffer):
MAXBLOCK = 25 # Max async blocking time in ms
# The rgb method maps colors onto a 2-bit greyscale
# colors.py creates color constants with 2-bit colors which are written to FB
@staticmethod
@ -238,14 +239,15 @@ class EPD(framebuf.FrameBuffer):
nbytes = len(self.ibuf) # Bytes to send
didx = nbytes * 2 # Increment of framebuf index
nleft = len(self._buf) # Size of framebuf
npass = 0
tyield = time.ticks_ms() # Time of last yield
while nleft > 0:
self._bsend(fbidx, pattern, nbytes) # Grey-map, buffer and send nbytes
fbidx += didx # Adjust for bytes already sent
nleft -= didx
nbytes = min(nbytes, nleft)
if not ((npass := npass + 1) % 16):
await asyncio.sleep_ms(0) # Control blocking time
if time.ticks_diff(time.ticks_ms(), tyield) > EPD.MAXBLOCK:
await asyncio.sleep_ms(0) # Don't allow excessive blocking
tyield = time.ticks_ms()
self.updated.set()
self._command(b"\x12") # Nonblocking .display_on()