-
Notifications
You must be signed in to change notification settings - Fork 11
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
RGBDisplay frame buffer allocation failure on ESP32-S3 #20
Comments
I need to make a change to the code to handle that issue. This is due to how the RGB driver works. In the meantime here is what you can do. import micropython
micropython.mem_info()
import lcd_bus
display_bus = lcd_bus.RGBBus(
hsync = 39,
vsync = 41,
de = 40,
disp = -1,
pclk = (12 * 1000 * 1000),
data0 = 8, data1 = 3, data2 = 46, data3 = 9, data4 = 1, # B
data5 = 5, data6 = 6, data7 = 7, data8 = 15, data9 = 16, data10 = 4, # G
data11 = 45, data12 = 48, data13 = 47, data14 = 21, data15 = 14, # R
hsync_front_porch = 8,
hsync_back_porch = 8,
hsync_pulse_width = 4,
hsync_idle_low = True,
vsync_front_porch = 8,
vsync_back_porch = 8,
vsync_pulse_width = 4,
vsync_idle_low = True,
de_idle_high = False,
pclk_idle_high = False,
pclk_active_low = True,
disp_active_low = False,
)
buf1 = display_bus.allocate_framebuffer(800 * 480 * 2, lcd_bus.MEMORY_SPIRAM)
buf2 = display_bus.allocate_framebuffer(800 * 480 * 2, lcd_bus.MEMORY_SPIRAM)
import rgb_display
import lvgl as lv
display = rgb_display.RGBDisplay(
data_bus = display_bus,
display_width = 800,
display_height = 480,
frame_buffer1=buf1,
frame_buffer2=buf2,
color_byte_order = rgb_display.BYTE_ORDER_BGR,
color_space = lv.COLOR_FORMAT.RGB565,
) |
I updated the code so clone it again and give it a try the problem should be fixed without you needing to manually create the buffers like in my last post. |
Thanks very much for that, @kdschlosser! Sadly, either way I do it (manually or the newly-updated way), I get this failure immediately after the
It appears this may be a result of accessing an illegal memory location; unfortunately, I'm not yet quite ESP32-savvy enough to determine if this might be my fault somehow, or beyond my control. |
Lets decode the backtrace.
You may have to adjust the path to xtensa-esp32-elf-addr2line. I am not sure where it gets put on MACOS |
download the attached file and unzip it. The upload it to your MCU. When the driver framework loads it will use this one ionstead of the one that is baked into the firmware automatically. I added a bunch of print statements to see where it is tanking. The backtrace stuff isn't going to give any insight into location for the python code so this will help locate the function call that is tanking it. |
Here's the output from your alternate
|
I just realized that this line from my
was written under the assumption that |
Yup I just saw that too. |
I mean JUST now I saw that... LOL.. |
pclk you set to 42 |
Everything else looks to be correct. |
You might have to dink about with the freq setting a bit if your display image is not centered.. You might be able to push it up to a higher clock frequency than 12mhz. you have to test it to find out. I have a waveshare display here that in the docs it says 16mhz but 13mhz is what works with the image centered correctly and not scrolling horizontally when the display redraws |
It will work like it should once you make those changes. |
The crash is gone, and the output with your alternate
I added It's very late for me here, so I'll tackle this again after I've slept. Thanks very much for your help to this point! |
display = rgb_display.RGBDisplay(
data_bus = display_bus,
display_width = 800,
display_height = 480,
backlight_pin = 2,
color_byte_order = rgb_display.BYTE_ORDER_BGR,
color_space = lv.COLOR_FORMAT.RGB565,
)
display.init()
display.set_backlight(100)
scrn = lv.screen_active()
scrn.set_style_bg_color(lv.color_hex(0x000000), 0)
slider = lv.slider(scrn)
slider.set_size(200, 50)
slider.center()
import time
while True:
time.sleep_ms(1)
lv.tick_inc(1)
lv.task_handler() That will get you rolling. |
Thanks so much, @kdschlosser, both for your time creating At this point, the backlight is on and I have a white screen, but nothing renders. Would you guess I'm up against a problem in my definition of either Or is it more likely I'm mishandling Here's import time, micropython
micropython.mem_info()
import lcd_bus
display_bus = lcd_bus.RGBBus(
hsync = 39,
vsync = 41,
de = 40,
disp = -1,
pclk = 42, # to TFT DCLK
data0 = 8, data1 = 3, data2 = 46, data3 = 9, data4 = 1, # B
data5 = 5, data6 = 6, data7 = 7, data8 = 15, data9 = 16, data10 = 4, # G
data11 = 45, data12 = 48, data13 = 47, data14 = 21, data15 = 14, # R
freq = 12000000,
hsync_front_porch = 8,
hsync_back_porch = 8,
hsync_pulse_width = 4,
hsync_idle_low = True,
vsync_front_porch = 8,
vsync_back_porch = 8,
vsync_pulse_width = 4,
vsync_idle_low = True,
de_idle_high = False,
pclk_idle_high = False,
pclk_active_low = True,
disp_active_low = False,
)
import rgb_display
import lvgl as lv
display = rgb_display.RGBDisplay(
data_bus = display_bus,
display_width = 800,
display_height = 480,
backlight_pin = 2,
color_byte_order = rgb_display.BYTE_ORDER_BGR,
color_space = lv.COLOR_FORMAT.RGB565,
)
display.init()
display.set_backlight(100)
scrn = lv.screen_active()
scrn.set_style_bg_color(lv.color_hex(0x000000), 0)
slider = lv.slider(scrn)
slider.set_size(200, 50)
slider.center()
while True:
time.sleep_ms(1)
lv.tick_inc(1)
lv.task_handler() |
By looking at the specs for the display I am going to say this is what you need to be running.. import time, micropython
micropython.mem_info()
import lcd_bus
display_bus = lcd_bus.RGBBus(
hsync = 39,
vsync = 41,
de = 40,
disp = -1,
pclk = 42, # to TFT DCLK
data0 = 8, data1 = 3, data2 = 46, data3 = 9, data4 = 1, # B
data5 = 5, data6 = 6, data7 = 7, data8 = 15, data9 = 16, data10 = 4, # G
data11 = 45, data12 = 48, data13 = 47, data14 = 21, data15 = 14, # R
freq = 12000000,
hsync_front_porch = 8,
hsync_back_porch = 8,
hsync_pulse_width = 4,
hsync_idle_low = True,
vsync_front_porch = 8,
vsync_back_porch = 8,
vsync_pulse_width = 4,
vsync_idle_low = True,
de_idle_high = False,
pclk_idle_high = False,
pclk_active_low = True,
disp_active_low = False,
)
import rgb_display
import lvgl as lv
display = rgb_display.RGBDisplay(
data_bus = display_bus,
display_width = 800,
display_height = 480,
backlight_pin = 2,
color_space = lv.COLOR_FORMAT.RGB565,
rgb565_byte_swap=True
)
display.init()
display.set_backlight(100)
scrn = lv.screen_active()
scrn.set_style_bg_color(lv.color_hex(0x000000), 0)
slider = lv.slider(scrn)
slider.set_size(200, 50)
slider.center()
while True:
time.sleep_ms(1)
lv.tick_inc(1)
lv.task_handler() |
I know it works. it's just a matter of dialing in the right settings for your display. Unfortunately the information is just published to a datasheet somewhere. we have to go digging through the code examples that are used in order to get it to display properly. The code example I just gave you is only as a test. if it works then we will change some other stuff around so we don't have to iterate over the buffer to move bytes around. This will give you better performance. |
I just updated the code to deal with using rgb565_byte_swap in a different manner. It will increase the performance by about 30%. |
I'll do more digging for display specs. FYI, a couple sources assert that this is the screen being used, and at first glance it certainly appears consistent with what's mounted on the board. EDIT: Also, this page appears to be a dumping ground for technical data on this specific ESP32-8048S043 board. EDIT 2: Based on the sample LovyanGFX configuration code from that page, I bumped the Also, zones across the top and bottom of the screen are flickering at a high frequency. This progress is inspirational! I'll continue to experiment. |
turn the freq down to 14mhz or even 13mhz and that will fix the slider moving. |
I believe the flickering will go away once you get the frequency dialed in EDIT I am going to double check your vsync and hsync settings just to make sure they are right. |
And so it did! 13mhz appears solid. Very exciting, thank you. Your work on this is well-conceived, nicely executed, and incredibly appreciated--is there a link I can use to buy you a coffee, beer or microcontroller? :) |
The settings look right with what is in the examples for the display so it should just be a matter of dialing in the pixel clock. I want to let you know what the last few code changes I made actually do. The very last one combines the 3 bin files into a single binary for easier flashing of the firmware. In the second to last code change what I did was add code that checks to see if rgb565 byte swapping is wanted, if it is then I check to make sure the color depth is 16bpp and if 16 lanes are being used. If all 3 of those conditions are met then I change the order of the pins instead of iterating the frame buffer moving bytes around. Same effect just much faster, about 30% faster. so give the new code a shot and lower that pixel clock and that should do the trick for ya. |
I pulled your changes and tried to build, but eventually got this failure:
Note the comma trailing |
Quit drinking over a decade ago so beer is not something I would use. An MCU would be nice. can never have too many of those. |
yup that's a fat finger. lemme fix it. |
all fixed |
I am super happy we got you up and running. I knew the RGB bus driver worked but you having issues with it exposed the memory issue which is now fixed and it also exposed a better way of handling the RGB565 byte swap that should be a HUGE improvement in performance. I still have to tell you how to get the gt911 driver working... you need to change the Now I added a special way of dealing with I2C in MicroPython. it actually makes it easier to use and it will deal with using I2C from more than one thread. The ESP32 supports threading and if you have any attached I2C devices you are able to collect or send data to those devices in a thread. so this is how the gt911 driver works import i2c
import gt911
i2c_bus = i2c.I2CBus(scl=10, sda=11, freq=4000000, host=None, use_pullups=False, use_locks=False)
touch_driver = gt911.GT911(i2c_bus=i2c_bus, reset_pin=None, interrupt_pin=None, touch_cal=None) You can change the host if you like and you can specify to use built in pullups if you like. The The
|
Works fine now, thanks! And I've sent a gift your way 🎁 Two quick notes:
|
I'm not sure that makes any sense, unless the bootloader can and does behave differently on power-up than it does for soft/hard resets. |
don't worry about the response you get when doing a scan. I don't think that I2C has an official way of collecting the device id's It is kind of a hack thing that it is doing to detect them. It is sending out empty packets and if no errors occurs then it adds the ID to the list. I really wouldn't 100% trust that method. Use the display driver and the gt911 driver as it is. If you run into a problem lemme know from there. I am happy that we did find the cause of the pins getting mucked up. There could still be something that is causing an issue with those pins. I did open an issue on micropython's repo for the problem and the main author was in agreement that the automatic assignment of the USB OTG to those 2 pins is wrong. Because of how this binding is written it makes it super easy to update the version of micropython that is being used. so as soon as they make a release with the fix I will be able to add it. I only made a modification for what I saw. there could be others areas buried in the source code for the ESP32 port that I missed. |
Thanks so much for everything you've put into this! You certainly didn't owe me all this patience and assistance, and I'm incredibly appreciative that you've been so generous. Also, FYI, I've figured out the 95 vs 20 I2C address weirdness. 95 (0x5d) and 20 (0x14) are both valid GT911 addresses, decided by the status of the GT911 INT pin while its RESET pin (GPIO 38 per this board) goes low for >100µs. As this board is shipped, however, the INT pin appears to be disconnected (from GPIO 18) by an open pad. So, if I pull GPIO 38 low for a moment after any power-up or reset, the GT911 address reliably becomes 95 (0x5d). And perhaps the GT911 driver already handles that maneuver itself--I'll find out soon :) |
The 2 addresses are for read a write so don't worry about the address flip flopping and just use the thing already. It should work the way it is. The INT pin we don't have to worry about because we are not changing the standard address to the secondary one and LVGL collects the touch input by use of polling. The reset pin really is going to do nothing as well. You don't have to bother passing those to the GT911 constructor in order for it to work. Everything should now work exactly as it should. Give it a go test it out. Here is a sample script to test with to see if it works. Just upload it to your MCU and see if it works and if the colors are all correct. You are going to have to enter you pin numbers and your display settings before you upload it. from micropython import const # NOQA
import i2c
_WIDTH = const(800)
_HEIGHT = const(480)
_CTP_SCL = const(9)
_CTP_SDA = const(8)
_CTP_IRQ = const(4)
_SD_MOSI = const(11)
_SD_SCK = const(12)
_SD_MISO = const(13)
_LCD_FREQ = const(13000000)
_PCLK_ACTIVE_NEG = const(0)
_HSYNC_PULSE_WIDTH = const(10)
_HSYNC_BACK_PORCH = const(10)
_HSYNC_FRONT_PORCH = const(10)
_VSYNC_PULSE_WIDTH = const(10)
_VSYNC_BACK_PORCH = const(10)
_VSYNC_FRONT_PORCH = const(20)
_PCLK = const(7)
_HSYNC = const(46)
_VSYNC = const(3)
_DE = const(5)
_DISP = const(-1)
_BCKL = None
_DRST = None
_DPWR = None
I2C_BUS = i2c.I2CBus(
scl=_CTP_SCL,
sda=_CTP_SDA,
freq=400000,
use_locks=False
)
_DATA15 = const(10) # B7
_DATA14 = const(17) # B6
_DATA13 = const(18) # B5
_DATA12 = const(38) # B4
_DATA11 = const(14) # B3
_DATA10 = const(21) # G7
_DATA9 = const(47) # G6
_DATA8 = const(48) # G5
_DATA7 = const(45) # G4
_DATA6 = const(0) # G3
_DATA5 = const(39) # G2
_DATA4 = const(40) # R7
_DATA3 = const(41) # R6
_DATA2 = const(42) # R5
_DATA1 = const(2) # R4
_DATA0 = const(1) # R3
import lcd_bus # NOQA
bus = lcd_bus.RGBBus(
hsync=_HSYNC,
vsync=_VSYNC,
de=_DE,
disp=_DISP,
pclk=_PCLK,
data0=_DATA0,
data1=_DATA1,
data2=_DATA2,
data3=_DATA3,
data4=_DATA4,
data5=_DATA5,
data6=_DATA6,
data7=_DATA7,
data8=_DATA8,
data9=_DATA9,
data10=_DATA10,
data11=_DATA11,
data12=_DATA12,
data13=_DATA13,
data14=_DATA14,
data15=_DATA15,
freq=_LCD_FREQ,
hsync_front_porch=_HSYNC_FRONT_PORCH,
hsync_back_porch=_HSYNC_BACK_PORCH,
hsync_pulse_width=_HSYNC_PULSE_WIDTH,
hsync_idle_low=False,
vsync_front_porch=_VSYNC_FRONT_PORCH,
vsync_back_porch=_VSYNC_BACK_PORCH,
vsync_pulse_width=_VSYNC_PULSE_WIDTH,
vsync_idle_low=False,
de_idle_high=False,
pclk_idle_high=False,
pclk_active_low=_PCLK_ACTIVE_NEG,
disp_active_low=False,
refresh_on_demand=False
)
buf1 = bus.allocate_framebuffer(_WIDTH * _HEIGHT * 2, lcd_bus.MEMORY_SPIRAM)
buf2 = bus.allocate_framebuffer(_WIDTH * _HEIGHT * 2, lcd_bus.MEMORY_SPIRAM)
import lvgl as lv # NOQA
import rgb_display # NOQA
lv.init()
display = rgb_display.RGBDisplay(
data_bus=bus,
display_width=_WIDTH,
display_height=_HEIGHT,
frame_buffer1=buf1,
frame_buffer2=buf2,
reset_pin=_DRST,
reset_state=rgb_display.STATE_HIGH,
power_pin=_DPWR,
power_on_state=rgb_display.STATE_HIGH,
backlight_pin=_BCKL,
backlight_on_state=rgb_display.STATE_HIGH,
color_space=lv.COLOR_FORMAT.RGB565,
rgb565_byte_swap=True
)
display.set_power(True)
display.init()
display.set_backlight(100)
import time # NOQA
import gt911 # NOQA
indev = gt911.GT911(I2C_BUS)
scrn = lv.screen_active()
scrn.set_style_bg_color(lv.color_hex(0x000000), 0)
slider = lv.slider(scrn)
slider.set_size(500, 75)
slider.center()
while True:
time.sleep_ms(1)
lv.tick_inc(1)
lv.task_handler() I also want to note that since we are not using an interrupt based timer to handle calling the task handler you you optionally edit #define LV_DEF_REFR_PERIOD 33 to #define LV_DEF_REFR_PERIOD 1 That will greatly improve the touch input and also how smooth the UI responds. |
They are aware of the problem upstream in MicroPython so hopefully they will update it in the next release to fix this issue. It's kind of a biggie so I would imagine that it should get fixed sooner than later. |
I added something new that you might like. if you add |
That sounds great, and I'll check as soon as I get things running, thanks! At the moment, I can't build the latest:
|
I just pushed a commit so if you can try it again. |
Thanks--that builds. When I try the test script you provided above, I get this:
|
fixed. |
When I run the sample code you provided above, the slider GUI renders, and the GT911 driver fundamentally works (I can tell by printing The problem is that I can't actually interact with the slider. Is there something else I need to do to associate |
nope. it should work. |
It wasn't working because the touch digitizer and display are different resolutions, which I now have it working, and happy to share my changes to |
The resolution differences between the display and the touch need to be handled at the hardware level. When the driver starts this is what you are seeing.
That is the resolution the touch IC is set to at the hardware level. If this doesn't match what the resolution of the display is it can be changed using the You do not want to set any rotation on the display when you do this. Does the display show natively in landscape or portrait? if it's portrait then the resolutions needs to be reversed in the touch IC. The purpose to the _remap function is ONLY to handle rotation changes and calibration. The calibration I have set up is the user touches a cross that appears in each corner of the display. Those touches are used to locate where the corners should be. 0,0 on a display might have 21,11 for touch coordinates and that function is what remaps the touch value to display coordinates. It sounds like all that you needed to do was to run the calibration program to correct your problem. You should undo any changes you have made and try that to see if it fixes the issue. Take the code below and put it into a file called import esp32
class TouchCalData(object):
def __init__(self, name):
self._config = esp32.NVS(name)
try:
self._left = self._config.get_i32('left')
if self._left == -1:
self._left = None
except OSError:
self._left = None
try:
self._right = self._config.get_i32('right')
if self._right == -1:
self._right = None
except OSError:
self._right = None
try:
self._top = self._config.get_i32('top')
if self._top == -1:
self._top = None
except OSError:
self._top = None
try:
self._bottom = self._config.get_i32('bottom')
if self._bottom == -1:
self._bottom = None
except OSError:
self._bottom = None
self._is_dirty = False
def save(self):
if self._is_dirty:
self._config.commit()
@property
def left(self):
return self._left
@left.setter
def left(self, value):
self._left = value
if value is None:
value = -1
self._config.set_i32('left', value)
self._is_dirty = True
@property
def right(self):
return self._right
@right.setter
def right(self, value):
self._right = value
if value is None:
value = -1
self._config.set_i32('right', value)
self._is_dirty = True
@property
def top(self):
return self._top
@top.setter
def top(self, value):
self._top = value
if value is None:
value = -1
self._config.set_i32('top', value)
self._is_dirty = True
@property
def bottom(self):
return self._bottom
@bottom.setter
def bottom(self, value):
self._bottom = value
if value is None:
value = -1
self._config.set_i32('bottom', value)
self._is_dirty = True and this is the script you want to run making changes for your board as needed. from micropython import const # NOQA
import i2c
_WIDTH = const(800)
_HEIGHT = const(480)
_CTP_SCL = const(9)
_CTP_SDA = const(8)
_CTP_IRQ = const(4)
_SD_MOSI = const(11)
_SD_SCK = const(12)
_SD_MISO = const(13)
_LCD_FREQ = const(13000000)
_PCLK_ACTIVE_NEG = const(0)
_HSYNC_PULSE_WIDTH = const(10)
_HSYNC_BACK_PORCH = const(10)
_HSYNC_FRONT_PORCH = const(10)
_VSYNC_PULSE_WIDTH = const(10)
_VSYNC_BACK_PORCH = const(10)
_VSYNC_FRONT_PORCH = const(20)
_PCLK = const(7)
_HSYNC = const(46)
_VSYNC = const(3)
_DE = const(5)
_DISP = const(-1)
_BCKL = None
_DRST = None
_DPWR = None
I2C_BUS = i2c.I2CBus(
scl=_CTP_SCL,
sda=_CTP_SDA,
freq=400000,
use_locks=False
)
_DATA15 = const(10) # B7
_DATA14 = const(17) # B6
_DATA13 = const(18) # B5
_DATA12 = const(38) # B4
_DATA11 = const(14) # B3
_DATA10 = const(21) # G7
_DATA9 = const(47) # G6
_DATA8 = const(48) # G5
_DATA7 = const(45) # G4
_DATA6 = const(0) # G3
_DATA5 = const(39) # G2
_DATA4 = const(40) # R7
_DATA3 = const(41) # R6
_DATA2 = const(42) # R5
_DATA1 = const(2) # R4
_DATA0 = const(1) # R3
import lcd_bus # NOQA
bus = lcd_bus.RGBBus(
hsync=_HSYNC,
vsync=_VSYNC,
de=_DE,
disp=_DISP,
pclk=_PCLK,
data0=_DATA0,
data1=_DATA1,
data2=_DATA2,
data3=_DATA3,
data4=_DATA4,
data5=_DATA5,
data6=_DATA6,
data7=_DATA7,
data8=_DATA8,
data9=_DATA9,
data10=_DATA10,
data11=_DATA11,
data12=_DATA12,
data13=_DATA13,
data14=_DATA14,
data15=_DATA15,
freq=_LCD_FREQ,
hsync_front_porch=_HSYNC_FRONT_PORCH,
hsync_back_porch=_HSYNC_BACK_PORCH,
hsync_pulse_width=_HSYNC_PULSE_WIDTH,
hsync_idle_low=False,
vsync_front_porch=_VSYNC_FRONT_PORCH,
vsync_back_porch=_VSYNC_BACK_PORCH,
vsync_pulse_width=_VSYNC_PULSE_WIDTH,
vsync_idle_low=False,
de_idle_high=False,
pclk_idle_high=False,
pclk_active_low=_PCLK_ACTIVE_NEG,
disp_active_low=False,
refresh_on_demand=False
)
buf1 = bus.allocate_framebuffer(_WIDTH * _HEIGHT * 2, lcd_bus.MEMORY_SPIRAM)
buf2 = bus.allocate_framebuffer(_WIDTH * _HEIGHT * 2, lcd_bus.MEMORY_SPIRAM)
import lvgl as lv # NOQA
import rgb_display # NOQA
lv.init()
display = rgb_display.RGBDisplay(
data_bus=bus,
display_width=_WIDTH,
display_height=_HEIGHT,
frame_buffer1=buf1,
frame_buffer2=buf2,
reset_pin=_DRST,
reset_state=rgb_display.STATE_HIGH,
power_pin=_DPWR,
power_on_state=rgb_display.STATE_HIGH,
backlight_pin=_BCKL,
backlight_on_state=rgb_display.STATE_HIGH,
color_space=lv.COLOR_FORMAT.RGB565,
rgb565_byte_swap=True
)
display.set_power(True)
display.init()
display.set_backlight(100)
import time # NOQA
import gt911 # NOQA
indev = gt911.GT911(I2C_BUS)
scrn = lv.screen_active()
if not indev.is_calibrated:
indev.calibrate()
scrn.set_style_bg_color(lv.color_hex(0x000000), 0)
slider = lv.slider(scrn)
slider.set_size(500, 75)
slider.center()
while True:
time.sleep_ms(1)
lv.tick_inc(1)
lv.task_handler() The touch calibration will only run a single time. the settings get saved into NVRAM on the ESP32. At the moment there are 2 ways to reset the saved settings, a full erase and flash again or access |
Yes I have already built into the firmware a way to calibrate the touchscreen. 😄 That would make it a whole lot easier then having to make sure you modify code each and every time you want to update from the repo. |
OH I did want to mention the downside in your situation. Because your display is 800x480 and the resolution that is set currently for the touch is 480x272 you are going to loose touch resolution by using just the calibration. The better way to do it is going to be updating the resolution for the touch at the hardware level to the 800x480 resolution. I would still recommend doing the calibration after you do that. |
I understand what you are saying, and I'll do it, thanks. And would also suggest that since the EDIT: Or, alternately, it would be pretty slick if the But, no big deal either way, as I can simply make that change to the GT911 configuration in my code, before the driver initializes. |
Doing that might not be an ideal way to go about it if there are any offsets. I also have not tested the code that writes the firmware yet. |
I have since tested it, and it nearly works--the only change needed is that |
Where did you get this information? according to the datasheet the config data is 185 bytes long... |
I got it from Goodix datasheet The checksum documentation in the table on Page 10 says that the checksum byte at |
yes but the checksum byte is the 185th byte. and that needs to be set. While I don't dump the entire config back to the touch IC that is the reason why it is there. The byte is allocated dynamically so it's not causing any memory use that is resident in memory all the time. In fact you would only really use that function to change the resolution of the touch just a single time and that's it. The code would never need to be run again. I probably shouldn't even have it added. It should be in a separate module the user is able import and run IF the resolution is not correct. When the python code gets loaded form a module that takes up memory so the smaller the code footprint the lower the memory use is going to be. I think I am going to cut that code out of the touch driver and make a new source file for it. I will do more work on that driver to improve it. It is commonly used driver so adding more bells and whistles is a good thing to have but only if it needs to be used... |
Typically when the config gets set in most drivers I have seen the entire config including the checksum gets written in a single go. where as I target the specific registers to set the width and height and calculate the checksum and those 3 things get set separately. The entire config still needs to be gotten in order to calculate the checksum. |
Yes, the 185th byte needs to be written, but it mustn't be considered in the calculation of the checksum. It seems clear to me that changing the size of |
I reworked the gt911 driver. I made the change with the buffer size as you have suggested. I also moved the code for the firmware portion of the driver to it's own module. That module will get imported if needing to adjust the firmware. If the firmware doesn't need to be changed at all the module will not be imported and that is going to be a reduction in memory use due to the code footprint being smaller for the driver. What is returned is a class instance. Using properties you are able top set the I also made a change to the driver that allows for programmatically adjusting the firmware set width and height. import gt911
from micropython import const
import i2c
i2c_bus = i2c.I2CBus(sdl=20, sca=19)
_WIDTH = const(800)
_HEIGH = const(480)
indev = gt911.G911(i2c_bus)
if indev.hw_size != (_WIDTH, _HEIGHT):
fw_config = indev.firmware_config
fw_config.width = _WIDTH
fw_config.height = _HEIGHT
fw_config.save() |
Thanks for that! I'll give it a try very soon, and start a new issue if there's any issues. |
no worries m8 |
I am going to close this issue as the original problem has been solved. |
I have a Sunton ESP32-8048S043 board with ESP32-S3 (16MB QIO flash / 8MB OPI SPIRAM), 800×480 parallel IPS display, and GT911 capacitive touch digitizer.
lvgl_micropython
is building, installing and fundamentally working, but I'm running into a problem allocating theRGBDisplay
frame buffer.Here's how I'm building the firmware under macOS Sonoma:
python3 make.py esp32 clean mpy_cross BOARD=ESP32_GENERIC_S3 BOARD_VARIANT=SPIRAM_OCT DISPLAY=rgb_display INDEV=GT911
Here's my
main.py
:And here's the resulting output:
Any thoughts on what I'm getting wrong, or what I might try next?
The text was updated successfully, but these errors were encountered: