Skip to content

Commit

Permalink
lib: Allow using lv_utils in unix / macos port.
Browse files Browse the repository at this point in the history
Fix to allow using lv_utils with asyncio when Timer not available.
  • Loading branch information
Carglglz authored and pi-anl committed Nov 11, 2024
1 parent 1fb4224 commit a4ea252
Showing 1 changed file with 41 additions and 21 deletions.
62 changes: 41 additions & 21 deletions lib/lv_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,27 +12,28 @@
# event_loop = lv_utils.event_loop()
#
#
# uasyncio example with SDL:
# asyncio example with SDL:
#
# SDL.init(auto_refresh=False)
# # Register SDL display driver.
# # Register SDL mouse driver
# event_loop = lv_utils.event_loop(asynchronous=True)
# uasyncio.Loop.run_forever()
# asyncio.Loop.run_forever()
#
# uasyncio example with ili9341:
# asyncio example with ili9341:
#
# event_loop = lv_utils.event_loop(asynchronous=True) # Optional!
# self.disp = ili9341(asynchronous=True)
# uasyncio.Loop.run_forever()
# asyncio.Loop.run_forever()
#
# MIT license; Copyright (c) 2021 Amir Gonnen
#
##############################################################################

import lvgl as lv
import micropython
import usys
import sys
import time

# Try standard machine.Timer, or custom timer from lv_timer, if available

Expand All @@ -42,26 +43,26 @@
try:
from lv_timer import Timer
except:
raise RuntimeError("Missing machine.Timer implementation!")
Timer = False

# Try to determine default timer id

default_timer_id = 0
if usys.platform == 'pyboard':
if sys.platform == 'pyboard':
# stm32 only supports SW timer -1
default_timer_id = -1

if usys.platform == 'rp2':
if sys.platform == 'rp2':
# rp2 only supports SW timer -1
default_timer_id = -1

# Try importing uasyncio, if available
# Try importing asyncio, if available

try:
import uasyncio
uasyncio_available = True
import asyncio
asyncio_available = True
except:
uasyncio_available = False
asyncio_available = False

##############################################################################

Expand All @@ -84,24 +85,34 @@ def __init__(self, freq=25, timer_id=default_timer_id, max_scheduled=2, refresh_

self.asynchronous = asynchronous
if self.asynchronous:
if not uasyncio_available:
raise RuntimeError("Cannot run asynchronous event loop. uasyncio is not available!")
self.refresh_event = uasyncio.Event()
self.refresh_task = uasyncio.create_task(self.async_refresh())
self.timer_task = uasyncio.create_task(self.async_timer())
if not asyncio_available:
raise RuntimeError("Cannot run asynchronous event loop. asyncio is not available!")
self.refresh_event = asyncio.Event()
self.refresh_task = asyncio.create_task(self.async_refresh())
self.timer_task = asyncio.create_task(self.async_timer())
else:
self.timer = Timer(timer_id)
if Timer:
self.timer = Timer(timer_id)
self.timer.init(
mode=Timer.PERIODIC, period=self.delay, callback=self.timer_cb
)
self.task_handler_ref = self.task_handler # Allocation occurs here
self.timer.init(mode=Timer.PERIODIC, period=self.delay, callback=self.timer_cb)
self.max_scheduled = max_scheduled
self.scheduled = 0

def init_async(self):
self.refresh_event = asyncio.Event()
self.refresh_task = asyncio.create_task(self.async_refresh())
self.timer_task = asyncio.create_task(self.async_timer())

def deinit(self):
if self.asynchronous:
self.refresh_task.cancel()
self.timer_task.cancel()
else:
self.timer.deinit()
if Timer:
self.timer.deinit()
event_loop._current_instance = None

def disable(self):
Expand All @@ -128,6 +139,15 @@ def task_handler(self, _):
if self.exception_sink:
self.exception_sink(e)

def tick(self):
self.timer_cb(None)

def run(self):
if not Timer:
while True:
self.tick()
time.sleep(0)

def timer_cb(self, t):
# Can be called in Interrupt context
# Use task_handler_ref since passing self.task_handler would cause allocation.
Expand All @@ -153,11 +173,11 @@ async def async_refresh(self):

async def async_timer(self):
while True:
await uasyncio.sleep_ms(self.delay)
await asyncio.sleep_ms(self.delay)
lv.tick_inc(self.delay)
self.refresh_event.set()


def default_exception_sink(self, e):
usys.print_exception(e)
sys.print_exception(e)
event_loop.current_instance().deinit()

0 comments on commit a4ea252

Please sign in to comment.