Error from PSRAM default(?) with LVGL_Micropython on ESP32_S3 #77
Replies: 26 comments 76 replies
-
You are not specifying is you are using SPI ram or not..
or
If you can provide me with a link to the board you are using I will do the legwork to find out if you are using octal flash and or octal PSRAM The S3 always has PSRAM to my knowledge. I don't believe there is a version of the MCU made without it. From that error if I had to take a guess I would think that you have octal PSRAM |
Beta Was this translation helpful? Give feedback.
-
Hey, Thanks for your help, I am using the ESP32-S3FN8 chip, integrated into an M5 Dial development board. (https://shop.m5stack.com/products/m5stack-dial-esp32-s3-smart-rotary-knob-w-1-28-round-touch-screen) As far as I can tell, there is no external PSRAM chip on the board. After reading your response; I've tried building the firmware using a few variations, but I continue to get the same PSRAM error after flashing. From the ESP32_S3 datasheet, it seems that the ESP32_S3FN8 chip doesn't have PSRAM and instead has QUAD SPIRAM, which is why I tried using "BOARD_VARIANT=SPIRAM_QUAD", unfortunately to no avail. Here are the three variations I tried using:
Would you be able to provide any guidance on the correct configuration for the internal PSRAM on the ESP32-S3FN8? Or perhaps suggest any further troubleshooting steps I could take? Thanks heaps for your fast and helpful reply. |
Beta Was this translation helpful? Give feedback.
-
I appreciate your continued support so much, you've really given my project a lot of expertise that I couldn't find elsewhere. The display is connected using SPI, so the memory limitations may be less strict, but I have had some issue getting the compiled firmware working on the board, which gives me some pause about whether it's right to have you continue working on my problem when I might reach a limitation and be unable to continue with it anyway, while I am gaining experience in micropython and LVGL, as well as general embedded systems, I do feel bad about the prospect of having you spend even more time helping me, only for me to end up needing to go another direction anyway. For context at least; when I run the new compilation command; all runs fine and when I flash it to the board, I no longer get any PSRAM errors, which is a good sign; but the board doesn't have a functional REPL and I can't run scripts using mpremote or AMPY. Again, I really appreciate you going above and beyond to help me, explaining things in a way that I can understand and being honest about the potential limitations of my strategy. I think it's time for me to consider C or writing direct to framebuffer; a part of the justification for this project was to get more comfortable and familiar with micropython and python in general, so I have been reluctant to change to C. I hope you don't feel obligated to continue replying, I don't wish for you to spend anymore of your time trying to help me, at least not until I have an issue more directly relevant to the work you've been doing with this script. |
Beta Was this translation helpful? Give feedback.
-
Should I open an issue now then? I'm a bit illiterate when it comes to github, so I'm sorry about that. It would be cool to make this easier for anyone else who ends up wanting to do the same thing in the future, I can imagine how straightforward your script would make the process of compiling for a board that's fully supported. The touch sensor is the "FT3267" and the display is the "GC9A01", there is a micropython repo(github.com/mattytrentini/micropython/) that has a writeup and all the requisite drivers. Presumably I will need to make some sort of intermediary between that display driver and the LVGL bindings. Your new command worked, I now have a functional REPL and I've started trying to get the driver working (just on it's own first, not worrying about interfacing with LVGL yet). I would like some advice with whether trying to get the GC9A01 driver that already exists working makes sense, and whether such a driver is likely to work without more effort than it's worth; I expect this requires investigation, which I'm not asking you to do. I've had a look at the example you provide using the "st7796" display but struggle to decipher how my approach needs to differ, given the different displays. In any case I'm gonna sleep on it; didn't want to leave you any longer without a response, but I haven't really hit a wall yet, so might end up responding with more progress, if I manage any. |
Beta Was this translation helpful? Give feedback.
-
I managed to get Russ Hughes gc9a01py driver working, with the touchscreen using the I2C implementation from another repo, albeit very slowly, then I realized you already have a driver for the gc9a01, so I have pivoted to trying to get that working. I took your driver_use_example.py and changed the pin assignments, frequency and resolution, then I changed the script to import the "gc9a01" driver instead of the "st7796" driver and exchanged every instance of "st7796" with "gc9a01", when I try to execute this script on my board, I get the error: "TypeError: 'spi_bus' argument required". This error has me a bit confused, I gather I need an spi_bus argument in display_bus but merely initializing the SPI bus using your modified SPI implementation doesn't seem like the appropriate strategy. I would really appreciate any help, as I have hit a wall and don't know where to go from here. This is the command I used to build the firmware: "python3 make.py esp32 clean submodules mpy_cross BOARD=ESP32_GENERIC_S3 DISPLAY=gc9a01 --usb-otg CONFIG_SPIRAM_TYPE_AUTO=n CONFIG_SPIRAM_MODE_QUAD=n CONFIG_SPIRAM_SPEED_80M=n CONFIG_SPIRAM=n CONFIG_SPIRAM_BOOT_INIT=n CONFIG_SPIRAM_USE_MALLOC=n" Here is the modified "driver_use_example.py" (I had to cut the comments out for the sake of formatting, hopefully I didn't break anything more):
|
Beta Was this translation helpful? Give feedback.
-
from micropython import const # NOQA
import lcd_bus # NOQA
import machine # NOQA
_WIDTH = const(240)
_HEIGHT = const(240)
_DC_PIN = const(4)
_MOSI_PIN = const(5)
_MISO_PIN = const(16)
_SCLK_PIN = const(6)
_CS_PIN = const(7)
_FREQ = const(60000000)
_RESET_PIN = const(8)
_POWER_PIN = None
_BACKLIGHT_PIN = const(9)
_OFFSET_X = const(0)
_OFFSET_Y = const(0)
spi_bus = machine.SPI.Bus(
host=1,
sck=_SCLK_PIN,
mosi=_MOSI_PIN,
miso=_MISO_PIN,
)
display_bus = lcd_bus.SPIBus(
spi_bus=spi_bus,
dc=_DC_PIN,
freq=_FREQ,
cs=_CS_PIN,
dc_low_on_data=False,
cs_high_active=False,
)
import gc9a01 # NOQA
import lvgl as lv # NOQA
display = gc9a01.GC9A01(
data_bus=display_bus,
display_width=_WIDTH,
display_height=_HEIGHT,
# we are going to let the driver handle the allocation of the frame buffers
frame_buffer1=None,
frame_buffer2=None,
reset_pin=_RESET_PIN,
reset_state=gc9a01.STATE_HIGH,
power_pin=_POWER_PIN,
power_on_state=gc9a01.STATE_HIGH,
backlight_pin=_BACKLIGHT_PIN,
backlight_on_state=gc9a01.STATE_HIGH,
offset_x=_OFFSET_X,
offset_y=_OFFSET_Y,
color_space=lv.COLOR_FORMAT.RGB565,
rgb565_byte_swap=True
)
display.set_power(True)
display.init()
display.set_backlight(100)
import task_handler # NOQA
th = task_handler.TaskHandler() |
Beta Was this translation helpful? Give feedback.
-
Here is the complete script, apologies for not just sending the whole thing in the first place:
|
Beta Was this translation helpful? Give feedback.
-
try changing the reset pin to |
Beta Was this translation helpful? Give feedback.
-
also do you have a link to who makes the board? I want you to make sure that you have the pin numbers correct. The numbers that are being used are unusual so I want to double check them. |
Beta Was this translation helpful? Give feedback.
-
Changing the reset to STATE_LOW has the screen on, it's reversed (horizontally), which I'm sure won't be much hassle to fix and I'm very excited to see my button on the screen! Thank you so much for all your help, I'd best be off to bed, it's 3am; I'll keep working on this tomorrow. |
Beta Was this translation helpful? Give feedback.
-
OK if the display is displaying in reverse then we have to change how it is setting up the display. Give me a few to do some research... |
Beta Was this translation helpful? Give feedback.
-
OK I just updated the code in the repo. See if that fixes the problem. |
Beta Was this translation helpful? Give feedback.
-
I've been trying to get the touchscreen working now, first I used the code from "#17" and got the touch screen printing the coordinates to the REPL, I figured this would be the hard part done but quickly realized I can't just pass touch events to LVGL directly. Upon going through the display drivers in your repo I noticed (deja vu) that your "ft6x36" driver ostensibly supports the "ft3267" touch IC that my device is using; so I recompiled with that driver included and tried to get that working, I got some error that the driver needs some arguments which I guessed as being the I2C object, then I get an error: Here is the script that gives me the AtttributeError:
and here is the script that gives no errors and prints the coordinates to the REPL:
|
Beta Was this translation helpful? Give feedback.
-
It takes care of everything for you all you need to do is to initialize the touch driver and then touch will work. give me a minute to key out an example for ya. |
Beta Was this translation helpful? Give feedback.
-
from micropython import const # NOQA
import lcd_bus # NOQA
import machine # NOQA
import time
_WIDTH = const(240)
_HEIGHT = const(240)
_DC_PIN = const(4)
_MOSI_PIN = const(5)
_MISO_PIN = const(16)
_SCLK_PIN = const(6)
_CS_PIN = const(7)
_FREQ = const(60000000)
_RESET_PIN = const(8)
_POWER_PIN = None
_BACKLIGHT_PIN = const(9)
_OFFSET_X = const(0)
_OFFSET_Y = const(0)
spi_bus = machine.SPI.Bus(
host=1,
sck=_SCLK_PIN,
mosi=_MOSI_PIN,
miso=_MISO_PIN,
)
display_bus = lcd_bus.SPIBus(
spi_bus=spi_bus,
dc=_DC_PIN,
freq=_FREQ,
cs=_CS_PIN,
dc_low_on_data=False,
cs_high_active=False,
)
import gc9a01 # NOQA
import lvgl as lv # NOQA
display = gc9a01.GC9A01(
data_bus=display_bus,
display_width=_WIDTH,
display_height=_HEIGHT,
# we are going to let the driver handle the allocation of the frame buffers
frame_buffer1=None,
frame_buffer2=None,
reset_pin=_RESET_PIN,
reset_state=gc9a01.STATE_LOW,
power_pin=_POWER_PIN,
power_on_state=gc9a01.STATE_HIGH,
backlight_pin=_BACKLIGHT_PIN,
backlight_on_state=gc9a01.STATE_HIGH,
offset_x=_OFFSET_X,
offset_y=_OFFSET_Y,
color_space=lv.COLOR_FORMAT.RGB565,
rgb565_byte_swap=True
)
display.set_power(True)
display.init()
display.set_backlight(100)
import i2c
import ft6x36
i2c_bus = i2c.I2C.Bus(
host=1,
scl=12,
sda=11
)
touch_i2c = i2c.I2C.Device(
i2c_bus,
dev_id=ft6x36.I2C_ADDR,
reg_bits=ft6x36.BITS
)
indev = ft6x36.FT6x36(touch_i2c)
scr = lv.obj()
btn = lv.button(scr)
btn.align(lv.ALIGN.CENTER, 0, 0)
label = lv.label(btn)
label.set_text('btn')
lv.screen_load(scr)
import task_handler # NOQA
th = task_handler.TaskHandler() |
Beta Was this translation helpful? Give feedback.
-
First, I want to say how much I appreciate you providing so much help, I really appreciate it. I tried using that code; 13 seconds(consistently) after I start the script, I get this error:
This error is similar to one I was getting when I was playing around with a basic touch script, my solution was to use interrupts to avoid polling the touch driver when an interrupt hadn't been raised; because it seems for some reason that polling was causing the error, though with that script the error presents itself sporadically, whereas when I get the error from the code you've provided, it very consistently happens 13 seconds after running the script (I timed it because I figured if it was consistent it's more likely that i2c isn't connecting at all). Nonetheless, I continued, hoping that i2c was connecting and I would just have to figure out how to address the error after getting touch working, obviously there's no way to determine whether touch is actually working from the script, so I attempted to add an event, this was a bit confusing because I'm not really sure whether this event should be an LVGL event or whether the task_handler should deal with it. I tried both and neither gave me functional touch anyway, but here's one attempt:
I tried adding a bunch of print statements to task_handler, i2c, ft6x36 and pointer_framework, but I think that will require recompiling(I will if you think it helpful), as placing them in /lib/ either didn't work like I had hoped, or the script isn't making it into any functions in any of these modules(I doubt this). I have spent quite a lot of time reading other issues and discussions on this github, to no avail, but I tried a few different things, like using a slider instead of a button and implementing the callback differently(I think it was using the task_handler, somehow). The only other thing I can think of is sharing the basic script I wrote while I was waiting for your help getting touch working with LVGL, all it does is displays the most recent touch coordinates and current rotary encoder position in LVGL labels, I'm sure this is of little value, beyond showing that these i2c settings and pin mappings did work with the touchscreen:
|
Beta Was this translation helpful? Give feedback.
-
Now that I've compiled the new firmware, I get the error: |
Beta Was this translation helpful? Give feedback.
-
Big progress; when I use the new drivers, I get an error when I touch the button:
This is pretty exciting, because it doesn't happen when I touch the screen anywhere but the button. Unfortunately, I still get the
|
Beta Was this translation helpful? Give feedback.
-
With my other code; subclassing "_get_coords" to add interrupts, things work even better, no errors after ~2 minutes, I get the X and Y coordinates printed to REPL when I tap anywhere but the button and when I tap on the button, I get the same error. Here is that code, I will look into the error now:
|
Beta Was this translation helpful? Give feedback.
-
When I use your subclassing, the error has returned, but touch works until the error happens; at which point it locks up. I won't post it again, because I copied your code verbatim and uploaded it. |
Beta Was this translation helpful? Give feedback.
-
Ah, seems like you removed the "not", so it's returning a runtime error whenever the chip ID matches, rather than when it doesn't match.:
↓
|
Beta Was this translation helpful? Give feedback.
-
You're right that the error occurs ~13 seconds after I stop touching the screen, not 13 seconds after starting. But after compiling the firmware with the new driver, it still times out after ~13 seconds. |
Beta Was this translation helpful? Give feedback.
-
When I run the code without subclassing; I get some error from the pointer framework:
I am compiling again now and will install the ft6x36 driver straight from the repo. This is the script I've been running, after removing subclassing:
|
Beta Was this translation helpful? Give feedback.
-
I will fix the |
Beta Was this translation helpful? Give feedback.
-
you see this. Firefox using up almost 16GB of ram!!! |
Beta Was this translation helpful? Give feedback.
-
You had mentioned earlier that when I'm using the rotary encoder, I shouldn't control things from the ISR. Upon doing some research; I gather you mean that I should do something similar to what I did before, where I used a flag to control a condition in the loop. Is this what you mean? |
Beta Was this translation helpful? Give feedback.
-
I've been using this script to create firmware for my ESP32_S3, all goes perfectly smoothly. But once I flash the firmware onto the board, I get some PSRAM errors and a non-functional REPL. I've been banging my head against compiling my own fork with LVGL bindings so am very motivated to make this work, but really don't know where to go from here. The readme doesn't mention an option to choose 0 PSRAM, but perhaps it's just undocumented and exists.
Here's the make.py commands I use:
python3 make.py esp32 clean submodules mpy_cross BOARD=ESP32_GENERIC_S3
And here's the flashing commands I use:
/python_env/idf5.2_py3.11_env/bin/python -m esptool --chip esp32s3 -p /dev/ttyACM0 -b 460800 --before default_reset --after no_reset write_flash --flash_mode dio --flash_size 8MB --flash_freq 80m --erase-all 0x0 /Documents/Project/PythonFiles/lvgl_micropython/build/lvgl_micropy_ESP32_GENERIC_S3-8.bin
Here's the error I get after I flash the firmware:
<0x1b>[0;31mE (422) quad_psram: PSRAM ID read error: 0x00ffffff, PSRAESP-ROM:esp32s3-20210327 Build:Mar 27 2021 rst:0x15 (USB_UART_CHIP_RESET),boot:0x8 (SPI_FAST_FLASH_BOOT) Saved PC:0x40382ba2 SPIWP:0xee mode:DIO, clock div:1 load:0x3fce3820,len:0x105c load:0x403c9700,len:0x4 load:0x403c9704,len:0xbd8 load:0x403cc700,len:0x2e30 entry 0x403c989c <0x1b>[0;31mE (422) quad_psram: PSRAM ID read error: 0x00ffffff, PSRAM chip not found or not supported, or wrong PSRAM line mode<0x1b>[0m <0x1b>[0;31mE (423) esp_psram: PSRAM enabled but initialization failed. Bailing out.<0x1b>[0m
Beta Was this translation helpful? Give feedback.
All reactions