-
Notifications
You must be signed in to change notification settings - Fork 24
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
OK folks, I need an accounting of what problems still exist. #65
Comments
I just pulled the latest version (commit ee1bdbc ) from github. For non SPIRAM it comples fine, but when using SPIRAM I get the IRAM error:
with this error:
Is there a simple fix for this IRAM overflow error? |
do you get this error if you compile vanilla MicroPython 1.23 as well?? I think this issue might be upstream and if it is I will open a PR there. I will clone MicroPython and see if there is an issue. Not a big deal to do, |
That would be great. I just compiled vanilla python 1.24. Works fine with native installed esp-idf 5.0.4 |
OK so it does compile for vanilla MicroPython. I wonder if there is not enough IRAM for the esp_lcd component to run. I will ask the folks over at MicroPython about squeezing more space. I am pretty sure that is what the issue is. It may end up being a case of the ESP32 not being supported or I am going to have to write custom drivers possibly. we will see what they say over there. |
Have you tried with SPIRAM support. Without SPIRAM support your code compiles fine. |
with SPIRAM the code size is larger and there is more that is placed into IRAM. I just pushed a commit which takes the keyboard exception and scheduling exceptions and places them into flash instead of IRAM. See if that does the trick for ya. |
3k in space is not a whole lot of space to try and free up. I don't know how much IRAM a function uses up and I am hoping that between the 2 things I moved it solves the issue. Basically what I am doing is this... This code block is in mpconfigport.h #if !(CONFIG_IDF_TARGET_ESP32 && CONFIG_SPIRAM && CONFIG_SPIRAM_CACHE_WORKAROUND)
#define MICROPY_WRAP_MP_BINARY_OP(f) IRAM_ATTR f
#endif
#define MICROPY_WRAP_MP_EXECUTE_BYTECODE(f) IRAM_ATTR f
#define MICROPY_WRAP_MP_LOAD_GLOBAL(f) IRAM_ATTR f
#define MICROPY_WRAP_MP_LOAD_NAME(f) IRAM_ATTR f
#define MICROPY_WRAP_MP_MAP_LOOKUP(f) IRAM_ATTR f
#define MICROPY_WRAP_MP_OBJ_GET_TYPE(f) IRAM_ATTR f
#define MICROPY_WRAP_MP_SCHED_EXCEPTION(f) IRAM_ATTR f
#define MICROPY_WRAP_MP_SCHED_KEYBOARD_INTERRUPT(f) IRAM_ATTR f I am changing it to read.. #if !(CONFIG_IDF_TARGET_ESP32 && CONFIG_SPIRAM && CONFIG_SPIRAM_CACHE_WORKAROUND)
#define MICROPY_WRAP_MP_SCHED_KEYBOARD_INTERRUPT(f) IRAM_ATTR f
#define MICROPY_WRAP_MP_SCHED_EXCEPTION(f) IRAM_ATTR f
#define MICROPY_WRAP_MP_BINARY_OP(f) IRAM_ATTR f
#endif
#define MICROPY_WRAP_MP_EXECUTE_BYTECODE(f) IRAM_ATTR f
#define MICROPY_WRAP_MP_LOAD_GLOBAL(f) IRAM_ATTR f
#define MICROPY_WRAP_MP_LOAD_NAME(f) IRAM_ATTR f
#define MICROPY_WRAP_MP_MAP_LOOKUP(f) IRAM_ATTR f
#define MICROPY_WRAP_MP_OBJ_GET_TYPE(f) IRAM_ATTR f The other things I really want to leave in IRAM because if they are taken out of IRAM it could end up causing a pretty large performance hit. |
You can also change the following in the same file #ifndef MICROPY_PY_MACHINE_I2S
#define MICROPY_PY_MACHINE_I2S (SOC_I2S_SUPPORTED)
#endif to read #ifndef MICROPY_PY_MACHINE_I2S
#define MICROPY_PY_MACHINE_I2S (0)
#endif If you are not using I2S. There are a couple of function that MicroPython has defined using IRAM when using I2S. |
You can also change the following code in the same file #define MICROPY_PY_MACHINE_BITSTREAM (1) to #define MICROPY_PY_MACHINE_BITSTREAM (0) if you are not using the cycle counter in MicroPython ( |
There is a typo in /lvgl_micropython/builder/esp32.py. Line 856
should be
I toke the branch with the changed mpconfigport.h (lines moved for IRM), disabled I2S, but I need bitstream as it is needed for NeoPixels. Still runs out of IRAM. What would be the reason the the former lvgl_micropython version did not have this problem? |
Hi Kevin... Using ESP32 SPIRAM..
Build went fine !!! Flashed to ESP32 Ran the following code with no issues
Doubble checked my pins... I know, I am using VSPI by the way... |
OH Hey what's going on? I will get you up and running as fast as I am able to. Having the underscore prefix to a constant means it is not a variable. IE if you have a module named
In a second module named
You will get an attribute error. This is because _TEST is not actually a variable so it is not accessible. Using const works in a similar manner to using the c preprocessor macro define ( VSPI pins are defined as MISO: 19 It looks like you have MISO and MOSI flip flopped. Your CS pin is also wrong as well. Pin 5 is the standard pin for the CS line. This is from the ESP-IDF #define VSPI_IOMUX_PIN_NUM_MISO 19
#define VSPI_IOMUX_PIN_NUM_MOSI 23
#define VSPI_IOMUX_PIN_NUM_CLK 18
#define VSPI_IOMUX_PIN_NUM_CS 5
#define VSPI_IOMUX_PIN_NUM_WP 22
#define VSPI_IOMUX_PIN_NUM_HD 21 You can use also replace import task_handler
th = task_handler.TaskHandler() |
You are correct. good catch!!! |
That was it... I swapped MO and MI Thank you very much Kevin !!! |
yes they can all exist right now. give me a few to key out some examples for ya, |
Here is an example if the display touch and SDCard are all on the same bus, import lcd_bus
from machine import SPI # NOQA
from micropython import const # NOQA
# Display settings
_WIDTH = const(240)
_HEIGHT = const(320)
# Display SPI bus settings
_SPI_HOST = const(2) # I use vspi which is
_SPI_MISO = const(19)
_SPI_MOSI = const(23)
_SPI_SCK = const(18)
_LCD_FREQ = const(400000)
_LCD_CS = const(15)
_LCD_DC = const(13)
_LCD_BKL = const(27)
_SD_CS = const(5) # change this
_SD_FREQ = const(10000) # change this
_TS_CS = const(10) # change this
_TS_FREQ = const(1000) # change this
# create the SPI bus for the display
spi_bus = SPI(
_SPI_HOST,
_TS_FREQ,
mosi=_SPI_MOSI,
miso=_SPI_MISO,
sck=_SPI_SCK,
cs=_TS_CS
)
# create the SPI device on the bus for the display
display_bus = lcd_bus.SPIBus(
spi_bus=spi_bus,
dc=_LCD_DC,
freq=_LCD_FREQ,
cs=_LCD_CS
)
import lvgl as lv # NOQA
import ili9341 # NOQA
# create the display driver
display = ili9341.ILI9341(
data_bus=display_bus,
display_width=_WIDTH,
display_height=_HEIGHT,
reset_pin=None,
power_pin=None,
backlight_pin=_LCD_BKL,
color_space=lv.COLOR_FORMAT.RGB565,
rgb565_byte_swap=True
)
from machine import SDCard # NOQA
sdcard = SDCard(
spi_bus=spi_bus,
cs=_SD_CS,
freq=_SD_FREQ
)
display.init()
display.set_backlight(100)
import xpt2046 # NOQA
import task_handler # NOQA
touch = xpt2046.XPT2046(spi_bus)
th = task_handler.TaskHandler()
scrn = lv.screen_active()
label = lv.label(scrn)
label.set_text('HELLO WORLD!')
label.align(lv.ALIGN.CENTER, 0, 50) |
I am going to very strongly suggest people use an esp32-s3 with octal flash and octal spiram. I was able to get a crap load of LVGL functions into IRAM which really steps up the performance. and I was also able to overclock both the spiram and the flash to 120Mhz (actually 240Hz because of DDR) which is a HUGE performance gain over the original 80 MHZ. I recommend adding some form of passive cooling to the ESP32 if you are going to do this. |
I take it there "is" a pecking order for the spi bus Trying to understand where you're going with this a little bit. Then So what is lcd_bus.SPIBus doing ?? My display background is black my text is white and my buttons are yellow. btn_cb() and the response seems to be a little bit slow.
lv.display_get_screen_active() does not give me currently loaded screen. from lvgl... Thanks again Kevin this is great work !!!! |
So went in and changed lv_conf.h |
lv_display_get_screen_active is not at the module level. it is apart of the display you created display = ili9341.ILI9341(
data_bus=display_bus,
display_width=240,
display_height=320,
reset_pin=None,
power_pin=None,
backlight_pin=27,
color_space=lv.COLOR_FORMAT.RGB565,
rgb565_byte_swap=True
)
scrn = display.get_screen_active() But lets say you created the display in the this is import ili9341
display = ili9341.ILI9341.get_default()
scrn = display.get_screen_active() I thought of damned near everything. 😃 There are some things that I will be addressing when I eventually decide to redo the C code generator. One of those things would solve this issue. display = ili9341.ILI9341(
data_bus=display_bus,
display_width=240,
display_height=320,
reset_pin=None,
power_pin=None,
backlight_pin=27,
color_space=lv.COLOR_FORMAT.RGB565,
rgb565_byte_swap=True
)
scrn = display.get_screen_active()
print(display == scrn.get_display()) that evaluates to The reason why it doesn't work as a sub class is because of how the binding code is written. in order for it to work properly the first field in every structure in LVGL would need to be a void pointer that could be used to hold a micropython base type. That would be the only way it could be done so that things would get returned properly. |
I need to change the machine.SPI class so it is a little easier to understand what is happening. I need to make an |
Also. There is a reason why I have the imports all scattered through the code. This is because of memory use. You want to have as much SRAM free as possible when the frame buffers get allocated. This is even more important if using the ESP32 because there is only a small amount of DMA memory available for the ESP32. With the ESP32-S3 you can allocate SPIRAM as DMA memory, this is not possible with the ESP32. So the more you import the less chance there is of having enough DMA'able memory for running double buffering. For convenience purposes I have written the code so the display driver will create the frame buffer(s). It will first try to create the buffers as DMA in SRAM. If that fails then it will try and create the buffers in DMA SPIRAM. If that fails then it will try and create a single buffer in SRAM and if that fails then it will try and make it in SPIRAM. The best is going to be 2 buffers that are DMA in SRAM. That is going to give the best performance. This is a good example that shows some really advanced use. It shows how to ensure that the frame buffers get allocated in SRAM using DMA memory and double buffering. It also shows how to check for the SDCard without having to keep on rebooting the ESP32. AND it even goes into using threads and a mutex/lock to ensure that everything is going to p[lay nice nice with each other. AND it also shows you how to use timers in LVGL instead of having to make a change and then telling LVGL to update the display then pausing the program before making another change. Click here for example codeimport lcd_bus
import machine # NOQA
# Create the SPI bus
spi_bus = machine.SPI(2, 1000, miso=19, mosi=23, sck=18, cs=5)
# SPI device for display
display_bus = lcd_bus.SPIBus(spi_bus=spi_bus, cs=15, freq=400_000, dc=13)
# doing is this way makes sure that less SRAM
# is used prior to the frame buffers being made
# as you can see the imports for LVGL and also the display driver happen
# after the buffers get created.
fb1 = display_bus.allocate_framebuffer(240 * 320 * 2, lcd_bus.MEMORY_INTERNAL | lcd_bus.MEMORY_SPIRAM)
fb2 = display_bus.allocate_framebuffer(240 * 320 * 2, lcd_bus.MEMORY_INTERNAL | lcd_bus.MEMORY_SPIRAM)
import ili9341
import lvgl as lv
# Start display driver
display = ili9341.ILI9341(
data_bus=display_bus,
display_width=240,
display_height=320,
frame_buffer1=fb1,
frame_buffer2=fb2,
reset_pin=None,
power_pin=None,
backlight_pin=27,
color_space=lv.COLOR_FORMAT.RGB565,
rgb565_byte_swap=True
)
# you need to initilize the display
# prior to constructing the touch driver
display.init()
import xpt2046 # NOQA
# Start touch driver
touch = xpt2046.XPT2046(spi_bus)
# Mount SD Card
import os, time, _thread
lock = _thread.allocate_lock()
import task_handler
th = task_handler.TaskHandler()
# overrides the calling of lv.task_handler so we can call
# it here with a lock object
def new_handler(event, user_data):
with lock:
lv.task_handler()
# tells task_handler.TaskHandler not to call lv.task_handler
return False
th.add_event_cb(new_handler, th.TASK_HANDLER_STARTED, None)
def timer2_callback(_):
with lock:
msg_txt.set_text('Do Again !!')
def timer1_callback(_):
with lock:
msg_txt.set_text('I feel you')
timer2.reset()
timer1 = lv.timer_create(timer1_callback, 1000, None)
timer1.set_repeat_count(1)
timer1.set_auto_delete(False)
timer1.pause()
timer2 = lv.timer_create(timer2_callback, 2000, None)
timer2.set_repeat_count(1)
timer2.set_auto_delete(False)
timer2.pause()
def btn_cb(event):
if event.get_code() == lv.EVENT.CLICKED:
if not timer1.get_paused():
timer1.pause()
if not timer2.get_paused():
timer2.pause()
scr_txt('clicked')
timer1.reset()
def scr_txt(x):
with lock:
try:
if lv.screen_active() == main:
msg_txt.set_text(x)
except: # NOQA
pass
sd = None
def try_load_sd():
global sd
try:
# I used the 10000 as an example. I do not know if that
# is what the frequency is supposed to be. That is something
# you will haver to check on.
# there are also other pins like cd (Card Detect) and
# wp "Write Protect". so you need to see if those are available as well.
# I have not messed about with using the SDCard in MicroPython.
sd = machine.SDCard(spi_bus=spi_bus, cs=14, freq=10000)
os.mount(sd, '/sd')
return True
except: # NOQA
return False
exit_thread = False
# this allows for the script to keep on checking
# to see if the SD Card is available.
def run():
while not exit_thread:
if sd is None and try_load_sd():
scr_txt(f'Flash Mounted\n\n{"\n".join(os.listdir("/"))}')
# you can run whatever other code you want from here.
# this will allow the repl to still function so if you nmeed to access
# the esp32 you can do so while the program is running. You just have
# to remember that you cannot access anything in LVGL from the repl
# because you would be doing so from 2 different threads and LVGL is not
# thread safe.
# you can force this thread to exist from the repl by typing in
# exit_thread = True
time.sleep(1)
main = lv.obj()
msg_txt = lv.label(main)
msg_txt.align(lv.ALIGN.CENTER, 0, 50)
msg_txt.set_text('Hello World !!')
btn = lv.button(main)
btn.set_size(90, 40)
btn.align(lv.ALIGN.CENTER, 0, 0)
btn.add_event_cb(btn_cb, lv.EVENT.CLICKED, None)
btn_lbl = lv.label(btn)
btn_lbl.set_text("Click Me !")
btn_lbl.align(lv.ALIGN.LEFT_MID, 0, 0)
lv.screen_load(main)
display.set_backlight(100)
# you will notice there is a lock object. This is because
# the task_handler.TaskHander insteance works by using an interrupt timer
# to schedule a micropython task that gets executed in the main thread.
# you don't want to call lv.TaskHander from the main thread while possibly
# updating an object from the thread that does the SD Card checking.
# start the SDCard check thread
_thread.start_new_thread(run, ()) |
Kevin... that code is giving me sensory overload !!!
It makes me question if MicroPython is ready for mainstream use The example had an error... I have 4mb ESP32-WROVER-E-N4R8 ... lv_display_get_screen_active issue By the way... what is the standard button color? |
the N4R8 is 4 MB of flash and 8mb of ram. The reason why you are getting the memory error is because there is not enough DMA'able memory available. I forgot to divide the buffers sizes by 10. changes the lines that read fb1 = display_bus.allocate_framebuffer(240 * 320 * 2, lcd_bus.MEMORY_INTERNAL | lcd_bus.MEMORY_SPIRAM)
fb2 = display_bus.allocate_framebuffer(240 * 320 * 2, lcd_bus.MEMORY_INTERNAL | lcd_bus.MEMORY_SPIRAM) to fb1 = display_bus.allocate_framebuffer(int(240 * 320 * 2 / 10), lcd_bus.MEMORY_INTERNAL | lcd_bus.MEMORY_SPIRAM)
fb2 = display_bus.allocate_framebuffer(int(240 * 320 * 2 / 10), lcd_bus.MEMORY_INTERNAL | lcd_bus.MEMORY_SPIRAM) |
some of the ILI series of displays for whatever reason hold the bytes in their internal GRAM reversed. so you need to change this code display = ili9341.ILI9341(
data_bus=display_bus,
display_width=240,
display_height=320,
frame_buffer1=fb1,
frame_buffer2=fb2,
reset_pin=None,
power_pin=None,
backlight_pin=27,
color_space=lv.COLOR_FORMAT.RGB565,
rgb565_byte_swap=True
) to read display = ili9341.ILI9341(
data_bus=display_bus,
display_width=240,
display_height=320,
frame_buffer1=fb1,
frame_buffer2=fb2,
reset_pin=None,
power_pin=None,
backlight_pin=27,
color_space=lv.COLOR_FORMAT.RGB565,
color_byte_order=ili9341.BYTE_ORDER_BGR,
# if the colors still are not right then remove the comment marker for the next line
# rgb565_byte_swap=True
) |
There is no intention of changing the way the SPI works in MicroPython. It's just how they decided to code it. They decided on a design that would make the API work across all boards and use less memory and flash space instead. You can make it work the way they have it but it ends up costing more in the end. The thought process is that most people only have a single device attached to the bus. The big issue is the SDCard CANNOT work properly if there is more than one device on the bus using the ESP32 series of MCU's. It is an impossibility to get it to work properly with the way the MicroPython SPI is done. It's fine the way it is and it works... It's a shortcoming that I was able to rectify so not a big deal. |
so the color is good to go...
frame buffer divided... incremented by 10 up to 80
still got...
|
I am wondering if the machine.SPI is chewing up all of the available SRAM and that is what is causing the allocation issue. I am going to have to rework the machine.SPI driver so instead of needing to pass a machine.SPI instance\ it will instead take the host number. Give me a day to hammer that out. That has got to be what is causing the problem. Can you do one thing for me. change the buffer allocation code to read this... try:
fb1 = display_bus.allocate_framebuffer(int(240 * 320 * 2 / 80), lcd_bus.MEMORY_INTERNAL | lcd_bus.MEMORY_SPIRAM)
except MemoryError:
raise RuntimeError('Failing on first buffer')
try:
fb2 = display_bus.allocate_framebuffer(int(240 * 320 * 2 / 80), lcd_bus.MEMORY_INTERNAL | lcd_bus.MEMORY_SPIRAM)
except MemoryError:
raise RuntimeError('Failing on second buffer') tell me if it is failing on the first or second buffer. |
I also changed display freq to 40Mhz and is running snappy now.
So I'm not doing any animations or needing any kind of fast screen refreshes at all. I am having an issue with a widget..
getting error...
I posted on LVGL fourm also. |
There are these methods to set things
|
I need to see the code you are running to make sure that the rotation is being done correctly. If it's not it can cause this kind of an issue. I want to make sure before I go messing about with any of the drivers. |
what is the display IC you are using? |
This morning I tried since a long time to compile the newest firmware and test it on both my 8MB and 4MB flash SPIRAM ESP32-WROVER boards. The compilation went smooth. However, when I execute this little program:
I get this error:
Also when changing the LCD_HOST to 0, or 1. On both my boards. Would it have something to do with the SPIRAM that is using a SPI controller internally? I compiled the firmware with:
and without the I also compiled firmware without SPIRAM support and tested that on a normal ESP32. Same result, unfortunately. |
You are starting the SPI wrong. Take a look at the README.md file |
I must have missed these changes completely. I just copied a quite recent example code from the discussion.
Is there any way how I can debug things? I tried to pass parametes such as |
Ok, so I dug into this. There were only 4 commits to the ST7796 module from the point on where the text started showing backwards and all your changes were related to the orientation table. Creating a test class and through a process of trial an error, the orientation table that displayed the text direction correctly and the touch layer working in the correct direction for each of the rotations is as follows. I have no idea what I am changing so thought I would drop it here in case this is specific to my dev board WT32-SC01-Plus only.
|
change the code and submit a PR for it. This way you get the credit for fixing it. You were next on my list but you beat me to it,... For some reason this display differs from the other ST displays with how the orientation table works. I don't know why that is. |
I'll take care of putting the code in and mentioning you in the PR... |
This fix come from @marksull #65 (comment)
OK it has been added. so you no longer need to monkey path the code. |
So, I complied with the latest and alas, I see the interface for I2CBus has changed. Previously was using:
I see that your documentation mentioned that you now split out the Bus and the Device, so I converted the above to:
I see that the Touch appears to initialize correctly:
But the touch layer is not responsive. Any ideas why with the new Bus/Device interface the touch is not working? |
Got it working! I needed to add the active low reset to the display initialization. it read now:
Now, still the touch does not working. I try to figure out what happens with the |
I found the mistake:
Now, the callibration is still mirrored horizontally. |
I try to run I have another weird problem. When displaying an arc with this code:
It shows an arc, but it lets me just one time change the indicator by touching it. Ataching a call back to the arc keeps working, but the indicator 'hangs' after one time chnaging it using touch. I tried the same code on an older LVGL 8.0 micropython instance, and there it works as expected. Does anyone has an explanation for this behaviour? |
don't use the calibrate for the time being. It is not yet finished. The whole calibration routine has changed and I just haven't gotten the chance to test it and correct any issue with it. Both the SPI and the I2C has changed. I changed this because of confusion from the users on how to make things work. But most importantly the ability to share the display bus with a touch controller and also an SDCard reader is now possible where it wasn't before. There are touch IC's made that can use say an SPI connection or an I2C connection depending on how it is wired. I didn't want to have duplicate code just to handle the type of connection. So I made the touch drivers unaware of what type of connection is being used. Because after all it shouldn't really matter what type of connection is used. In order to do that I had to make the API for I2C and also SPI be the same. Here was the tricky bit. How do I do that while retaining as much of the original MicroPython API as possible? That is when I came up with the API that is now being used. here is the API for SPI, I2C and SDCard. from typing import Optional, Union, ClassVar
from typing import TYPE_CHECKING
if TYPE_CHECKING:
import array
_BUFFER_TYPE = Union[bytearray, bytes, memoryview, array.array]
# this is in the i2c module
class I2C(object):
class Bus(object):
def __init__(
self,
host: Union[str, int],
scl: Union[str, int],
sda: Union[str, int],
freq: int = 4000000,
use_locks: bool = False
):
...
def __enter__(self) -> "I2C.Bus":
...
def __exit__(self, exc_type, exc_val, exc_tb) -> None:
...
def scan(self) -> list:
...
def start(self) -> None:
...
def stop(self) -> None:
...
def readinto(self, buf: _BUFFER_TYPE, nack: bool = True) -> None:
...
def write(self, buf: _BUFFER_TYPE) -> None:
...
def readfrom(self, addr: int, nbytes: int, stop: bool = True) -> bytes:
...
def readfrom_into(self, addr: int, buf: _BUFFER_TYPE, stop: bool = True) -> None:
...
def writeto(self, addr: int, buf: _BUFFER_TYPE, stop: bool = True) -> None:
...
def writevto(self, addr: int, vector: list, stop: bool = True) -> None:
...
def readfrom_mem(self, addr: int, memaddr: int, nbytes: int, addrsize: int = 8) -> bytes:
...
def readfrom_mem_into(self, addr: int, memaddr: int, buf: _BUFFER_TYPE, addrsize: int = 8) -> None:
...
def writeto_mem(self, addr: int, memaddr: int, buf: _BUFFER_TYPE, addrsize: int = 8) -> None:
...
class Device(object):
_bus: "I2C.Bus" = ...
dev_id: int = ...
_reg_bits: int = ...
def __init__(self, bus: "I2C.Bus", dev_id: int, reg_bits: int = 8):
...
def write_readinto(self, write_buf: _BUFFER_TYPE, read_buf: _BUFFER_TYPE) -> None:
...
def read_mem(self, memaddr: int, num_bytes: Optional[int] = None, buf: Optional[_BUFFER_TYPE] = None) -> Optional[bytes]:
...
def write_mem(self, memaddr: int, buf: _BUFFER_TYPE):
...
def read(self, nbytes: Optional[int] = None, buf: Optional[_BUFFER_TYPE] = None, stop: bool=True) -> Optional[bytes]:
...
def write(self, buf: _BUFFER_TYPE, stop: bool=True) -> None:
...
# this is in the machine module
class SPI(object):
MSB: ClassVar = 0
LSB: ClassVar = 1
class Bus(object):
def __init__(
self,
host: Union[str, int],
mosi: Union[str, int],
miso: Union[str, int],
sck: Union[str, int]
):
...
class Device(object):
def __init__(
self,
spi_bus: "SPI.Bus",
freq: int,
cs: Union[str, int],
polarity: int = 0,
phase: int = 0,
firstbit: int = 0
):
...
def write_readinto(
self,
write_buf: _BUFFER_TYPE,
read_buf: _BUFFER_TYPE
) -> None:
...
def read(
self, nbytes: Optional[int] = None,
buf: Optional[_BUFFER_TYPE] = None
) -> Optional[bytes]:
...
def write(self, buf: _BUFFER_TYPE) -> None:
...
class SDCard(object):
def __init__(
self,
slot: int = 1,
width: int = 1,
cd: Union[str, int] = -1,
wp: Union[str, int] = -1,
# these nexy 3 are if you are using an SPI card reader
spi_bus: Optional[SPI.Bus] = None,
cs: Union[str, int] = -1,
freq: int = 20000000
):
...
# the rest of the API is the same as the original SDCard API |
If the touch is outputting it's information correctly on startup it should be working. I am going to have to take a look see to find out what is happening. Give me a bit to do that... |
hey, long time since i've been here.. Had other business. |
I know, I have to make some proper documentation. I have been actually working on it over the last couple of weeks. I am fixing things upstream in LVGL that will allow an actual full blown documentation to be made that would include the entire API of LVGL in MicroPython. It would also generate a complete stub file for use with VSCode or PyCharm so code completion and intellisense work properly, it would also allow the documentation to be accessible from inside of the IDE as well. I have already started on writing the ReST files for the mechanics of the binding that includes all of the wrappers and changes made to some of the builtin parts of MicroPython. I am not sure as to why the GT911 driver is having an issue.... Is the code you are using look like this?? import gt911
import i2c
i2c_bus = i2c.I2C.Bus(
host=1,
sda=10,
sdl=11,
freq=400000
)
i2c_device = i2c.I2C.Device(
i2c_bus,
dev_id=gt911.I2C_ADDR,
reg_bits=gt911.BITS
)
indev = gt911.GT911(i2c_device) |
Well, almost. except that i2c cannot find Bus or Device since they are inside the I2C class. working around by using
haven't tested much with it so far. i saw a slider which didn't work. Well.. going back to the former issue as soon as i have any information on that. |
sorry I goofed that code example.. it should be I went back and corrected it. |
once I get around to it I will be modifying the machine.I2C class so the python wrapper will not need to be used.. I have to look at the ESP-IDF to see how it is actually supposed to work since I am willing to bet that it is broken into a bus/device organization like the SPI is. The reason why I made the change was to keep the API similar to what is seen with the SPI. That has also changed so it is There are people that complain about how "bloated" the ESP-IDF is but if you think about it if a user had to add all of the code to manage the SPI guess what? It is just as bloated as the SPI in the ESP-IDF. If a person only wants to use a single device and they don't need the additional code to handle multiple devices they can copy and paste the relevant parts of the SPI code to their application to allow it to work using only a single device without any of the bloat. There is also a general misunderstanding on how it works as well. People like to keep reference to the config structures for the SPI which doesn't need to be done. The drivers copy the data out of the structure and place it into a different structure that the driver uses internally. It was done this way so a user is able to initialize a bus or a device on the bus without having to malloc a structure of the config settings. That all gets handled in the driver. |
I found a strange problem. This ft6x36 driver seems to only handle LV_EVENT_SHORT_CLICKED events. It doesn't seem to handle long presses, or real-time page refreshes when sliding. Why is this? This is my device
I tested it with the following code
Here is a video of my testing process 87c4b1ed9d88cb388318adf6515d3845.mp4In short, whenever I keep my finger on the display for too long, the display interrupts all animations. Why? |
Friends, forgive me for being a bit long-winded. I just found something interesting. I found the file https://github.com/lvgl/lv_binding_micropython/blob/master/driver/generic/ft6x36.py ,copied its code into the f7a9e48e381cecdf8df8007f1dc218a7.mp4Following is my test code
Please forgive me that it is a bit long, because from line 83 onwards I copied and pasted the entire test code from https://github.com/Phil-CN/lv_binding_micropython/tree/master/examples/advanced_demo.py. I just changed the init_gui_esp32 method in the AdvancedDemoApplication class and replaced the content of this method with "pass". |
EEE gad man. As a suggestion, If you are going to use large block of code like that to the following.. <details>
<summary>Click for code</summary>
code block here wrapped in the triple back ticks
</details> I recommend doing that for any repo you are posting an issue to where you are posting a large code block. It save from having to scroll so much.. |
As far as the screen updating with the FT6x36 driver goes. I believe what is happening is in version 9.1 of LVGL something might be broken. In LVGL the indev code is written so the callback could set a flag You can adjust this behavior by overriding the callback function for the indev driver... import ft6x36
import i2c
class FT6x36(ft6x36.FT6x36):
def _read(self, drv, data):
ft6x36.FT6x36._read(self, drv, data)
data.continue_reading = False
i2c_bus = i2c.I2C.Bus(
host=1,
sda=0,
scl=0,
freq=400000
)
i2c_device = i2c.I2C.Device(
i2c_bus,
ft6x36.I2C_ADDR,
ft6x36.BITS
)
# and now you use the FT6x36 class that is made above
# just like you would normally.
indev = FT6x36(i2c_device) |
I will open up an issue with regards to it not working properly. |
Sorry, I am not familiar with markdown syntax, but I will remember this trick, thank you. |
Hey there was a time when I didn't know about using the XML tags to do that with Github. Personally I think that code blocks above a set number of line should automatically turn into a collapsible panel. This is an improvement that should be made for Github. It should be automatic.. But it is not something they decided to add tho they did leave holes that someone found and was able to exploit for a good use. |
I did open up that issue with LVGL and it not working properly. I am going to correct the issue in LVGL and submit a PR for it. |
This is what I know still has an issue.
ST display drivers have issue with the rotation being out of sorts. This is causing the text to display backwards. I have to do a little bit more research on this issue. as per the data sheet the rotation I have set for it should be correct but for some reason it is not.
There were reports of the REPL not working, This is not happening for everyone and the people that are having the issue have a common thing. They are using Thonny. Thonny is known to cause problems and I recommend not using it. Download a program called Putty if you are running on Windows. I know this work properly when connecting to the ESP32. The other possibility could be with MicroPython and using the built in USB for the USB instead of the UART. I would need more information to confirm what MCU is being used and what the MicroPython default settings are to nail down what the issue might be.
There was a report of the TaskHandler causing the MCU to freeze. I want to say this was with the RGBBus. The Freeze should now be fixed but the RGBBus driver is still not working. I am in the process of sorting this one out. I am really wanting a way for LVGL to exit the refresh instead of sitting there spinning it's wheels waiting for the buffer to finish flushing. This is a complex issue I am trying to come up with the best way to handle it.
The touch screen calibration is not working. I have not done anything as of yet to get this sorted out. It is on my TODO list.
The Unix port crashes if the display window is resized. This is a work in progress. I made some changes locally but I have not tested them yet. I was attempting to reallocate the buffers and that would cause a crash. I don't recall what the exact error was but it some something that didn't help to isolate the issue. What my local code does is it frees the existing frame buffer and then allocates a new buffer. I am going to change the default heap size to 8mb. Right now it is at 4mb which is not going to be anywhere near enough if a display is created that is larger than 800x600x24 using double buffering. A single buffer for a display size of 1024x768x24 is 2,334,720 bytes.
The text was updated successfully, but these errors were encountered: