lvgl-micropython / lvgl_micropython

LVGL module for MicroPython
MIT License
79 stars 25 forks source link

SPI_TRANS_USE_TXDATA only available for txdata transfer <= 32 bits #59

Closed Bigmaxmafia closed 4 months ago

Bigmaxmafia commented 4 months ago

commit c4f225a2f7052f750b53823f729718a0be6103f9 esp32-s3 octal

Hello. Maybe you can help me with the problem? When I try to connect the pn532 module with ili9341 via spi I get an error E (5165) spi_master: check_trans_valid(699): SPI_TRANS_USE_TXDATA only available for txdata transfer <= 32 bits ili9341 without connecting pn532 works well.

Previously, on version 8x from lvgl repo I had no problems and everything worked together.

spi_bus_pn532 = SPI( 2, baudrate=1000000, sck=Pin(_SCK_PIN_PN532), mosi=Pin(_MOSI_PIN_PN532), miso=Pin(_MISO_PIN_PN532), )

PN_CS = 15 cs_pin = Pin(PN_CS, Pin.OUT) nfc = PN532(spi_bus_pn532, cs_pin) nfc.SAM_configuration()

I attached the pn532 library NFC_PN532.txt

kdschlosser commented 4 months ago

I need the EXACT trace back that is seen and I also need the code you are wanting to run. The initialization code for the display bus, display driver and touch_screen and any other initialization that is used for other connected hardware.

This repo doesn't use the stock MicroPython SPI implementation, it uses a modified version and this is the reason why I need to see the initialization code you are running for everything.

Just to let you know this repo is NOT the official MicroPython binding for LVGL. This is an upgraded version of it and it doesn't function like the official one does. This repo is written to it supports more displays and more touch drivers and it overcomes issues like a display and a touch screen both using SPI on the same bus. This repo is written so displays can be swapped without the need to recompile and flash the firmware. Displays can be "hot plugged" without ever having to restart the MCU.

I say this because you are saying that your code worked with LVGL v8.x and this repo has never worked with v8.x. It has only worked with v9.x

Bigmaxmafia commented 4 months ago

I need the EXACT trace back that is seen and I also need the code you are wanting to run. The initialization code for the display bus, display driver and touch_screen and any other initialization that is used for other connected hardware.

This repo doesn't use the stock MicroPython SPI implementation, it uses a modified version and this is the reason why I need to see the initialization code you are running for everything.

Just to let you know this repo is NOT the official MicroPython binding for LVGL. This is an upgraded version of it and it doesn't function like the official one does. This repo is written to it supports more displays and more touch drivers and it overcomes issues like a display and a touch screen both using SPI on the same bus. This repo is written so displays can be swapped without the need to recompile and flash the firmware. Displays can be "hot plugged" without ever having to restart the MCU.

I say this because you are saying that your code worked with LVGL v8.x and this repo has never worked with v8.x. It has only worked with v9.x

boot.py

from micropython import const
from machine import Pin, SPI
from NFC_PN532 import PN532
import ili9341
import lcd_bus
import lvgl as lv
import time
import gc

#
_WIDTH = const(240)
_HEIGHT = const(320)

_DC_PIN = const(7)
_MOSI_PIN = const(11)
_MISO_PIN = const(13)
_SCLK_PIN = const(12)
_CS_PIN = const(10)
_RESET_PIN = const(6)
_BACKLIGHT_PIN = const(5)
#

# PN532 PINs
_MOSI_PIN_PN532 = const(14)
_MISO_PIN_PN532 = const(19)
_SCK_PIN_PN532 = const(18)
#

_FREQ = const(40_000_000)
_OFFSET_X = const(0)
_OFFSET_Y = const(0)

gc.collect()

display_bus = lcd_bus.SPIBus(
    dc=_DC_PIN,
    host=1,
    sclk=_SCLK_PIN,
    freq=_FREQ,
    mosi=_MOSI_PIN,
    miso=_MISO_PIN,
    cs=_CS_PIN,
)

display = ili9341.ILI9341(
    data_bus=display_bus,
    display_width=_WIDTH,
    display_height=_HEIGHT,
    frame_buffer1=None,
    frame_buffer2=None,
    reset_pin=_RESET_PIN,
    reset_state=ili9341.STATE_LOW,
    backlight_pin=_BACKLIGHT_PIN,
    backlight_on_state=ili9341.STATE_HIGH,
    offset_x=_OFFSET_X,
    offset_y=_OFFSET_Y,
    color_space=lv.COLOR_FORMAT.RGB565,
    rgb565_byte_swap=True
)

display.init()
display.set_backlight(100)

import ui_images

dispp = lv.display_get_default()
theme = lv.theme_simple_init(dispp)
dispp.set_theme(theme)

def ui_theme_set(idx):
   return

def SetFlag( obj, flag, value):
    if (value):
        obj.add_flag(flag)
    else:
        obj.remove_flag(flag)
    return

_ui_comp_table = {}
_ui_comp_prev = None
_ui_name_prev = None
_ui_child_prev = None
_ui_comp_table.clear()

def _ui_comp_del_event(e):
    target = e.get_target()
    _ui_comp_table[id(target)].remove()

def ui_comp_get_child(comp, child_name):
    return _ui_comp_table[id(comp)][child_name]

def ui_comp_get_root_from_child(child, compname):
    for component in _ui_comp_table:
        if _ui_comp_table[component]["_CompName"]==compname:
            for part in _ui_comp_table[component]:
                if id(_ui_comp_table[component][part]) == id(child):
                    return _ui_comp_table[component]
    return None
def SetBarProperty(target, id, val):
   if id == 'Value_with_anim': target.set_value(val, lv.ANIM.ON)
   if id == 'Value': target.set_value(val, lv.ANIM.OFF)
   return

def SetPanelProperty(target, id, val):
   if id == 'Position_X': target.set_x(val)
   if id == 'Position_Y': target.set_y(val)
   if id == 'Width': target.set_width(val)
   if id == 'Height': target.set_height(val)
   return

def SetDropdownProperty(target, id, val):
   if id == 'Selected':
      target.set_selected(val)
   return

def SetImageProperty(target, id, val, val2):
   if id == 'Image': target.set_src(val)
   if id == 'Angle': target.set_rotation(val2)
   if id == 'Zoom': target.set_scale(val2)
   return

def SetLabelProperty(target, id, val):
   if id == 'Text': target.set_text(val)
   return

def SetRollerProperty(target, id, val):
   if id == 'Selected':
      target.set_selected(val, lv.ANIM.OFF)
   if id == 'Selected_with_anim':
      target.set_selected(val, lv.ANIM.ON)
   return

def SetSliderProperty(target, id, val):
   if id == 'Value_with_anim': target.set_value(val, lv.ANIM.ON)
   if id == 'Value': target.set_value(val, lv.ANIM.OFF)
   return

def ChangeScreen( src, fademode, speed, delay):
    lv.screen_load_anim(src, fademode, speed, delay, False)
    return

def DeleteScreen(src):
    return

def IncrementArc( trg, val):
    trg.set_value(trg.get_value()+val)
    trg.send_event(lv.EVENT.VALUE_CHANGED, None)
    return

def IncrementBar( trg, val, anim):
    trg.set_value(trg.get_value()+val,anim)
    return

def IncrementSlider( trg, val, anim):
    trg.set_value(trg.get_value()+val,anim)
    trg.send_event(lv.EVENT.VALUE_CHANGED, None)
    return

def KeyboardSetTarget( keyboard, textarea):
    keyboard.set_textarea(textarea)
    return

def ModifyFlag( obj, flag, value):
    if (value=="TOGGLE"):
        if ( obj.has_flag(flag) ):
            obj.remove_flag(flag)
        else:
            obj.add_flag(flag)
        return

    if (value=="ADD"):
        obj.add_flag(flag)
    else:
        obj.remove_flag(flag)
    return

def ModifyState( obj, state, value):
    if (value=="TOGGLE"):
        if ( obj.has_state(state) ):
            obj.remove_state(state)
        else:
            obj.add_state(state)
        return

    if (value=="ADD"):
        obj.add_state(state)
    else:
        obj.remove_state(state)
    return

def TextAreaMoveCursor( trg, val):
    if val=="UP" : trg.cursor_up()
    if val=="RIGHT" : trg.cursor_right()
    if val=="DOWN" : trg.cursor_down()
    if val=="LEFT" : trg.cursor_left()
    trg.add_state(lv.STATE.FOCUSED)
    return

def set_opacity(obj, v):
    obj.set_style_opa(v, lv.STATE.DEFAULT|lv.PART.MAIN)
    return

def SetTextValueArc( trg, src, prefix, postfix):
    trg.set_text(prefix+str(src.get_value())+postfix)
    return

def SetTextValueSlider( trg, src, prefix, postfix):
    trg.set_text(prefix+str(src.get_value())+postfix)
    return

def SetTextValueChecked( trg, src, txton, txtoff):
    if src.has_state(lv.STATE.CHECKED):
        trg.set_text(txton)
    else:
        trg.set_text(txtoff)
    return

def StepSpinbox( trg, val):
    if val==1 : trg.increment()
    if val==-1 : trg.decrement()
    trg.send_event(lv.EVENT.VALUE_CHANGED, None)
    return

def SwitchTheme(val):
    ui_theme_set(val)
    return

# COMPONENTS
ui____initial_actions0 = lv.obj()

ui_Screen1 = lv.obj()
SetFlag(ui_Screen1, lv.obj.FLAG.SCROLLABLE, False)

ui_Image1 = lv.image(ui_Screen1)
ui_Image1.set_src(ui_images.ui_img_1361182409)
ui_Image1.set_width(lv.SIZE_CONTENT)    # 1
ui_Image1.set_height(lv.SIZE_CONTENT)   # 1
ui_Image1.set_x(-1)
ui_Image1.set_y(-124)
if (lv.image.ALIGN.CENTER == lv.image.ALIGN.STRETCH ): ui_Image1.set_inner_align(lv.image.ALIGN.TILE)  # LVGL9.1 bug fix patch CENTER, 1, 1
ui_Image1.set_inner_align(lv.image.ALIGN.CENTER)  # LVGL9.1 bug fix patch 1, 1
ui_Image1.set_align( lv.ALIGN.CENTER) # LVGL9.1 bug fix patch CENTER, 1, 1
SetFlag(ui_Image1, lv.obj.FLAG.CLICKABLE, True)
SetFlag(ui_Image1, lv.obj.FLAG.SCROLLABLE, False)

ui_Image2 = lv.image(ui_Screen1)
ui_Image2.set_src(ui_images.ui_img_2034924223)
ui_Image2.set_width(lv.SIZE_CONTENT)    # 220
ui_Image2.set_height(lv.SIZE_CONTENT)   # 94
ui_Image2.set_x(2)
ui_Image2.set_y(104)
if (lv.image.ALIGN.CENTER == lv.image.ALIGN.STRETCH ): ui_Image2.set_inner_align(lv.image.ALIGN.TILE)  # LVGL9.1 bug fix patch CENTER, 220, 94
ui_Image2.set_inner_align(lv.image.ALIGN.CENTER)  # LVGL9.1 bug fix patch 220, 94
ui_Image2.set_align( lv.ALIGN.CENTER) # LVGL9.1 bug fix patch CENTER, 220, 94
SetFlag(ui_Image2, lv.obj.FLAG.CLICKABLE, True)
SetFlag(ui_Image2, lv.obj.FLAG.SCROLLABLE, False)

ui_Label2 = lv.label(ui_Screen1)
ui_Label2.set_text("EXIT 1")
ui_Label2.set_width(lv.SIZE_CONTENT)    # 1
ui_Label2.set_height(lv.SIZE_CONTENT)   # 1
ui_Label2.set_x(-2)
ui_Label2.set_y(-60)
ui_Label2.set_align( lv.ALIGN.CENTER)
ui_Label2.set_style_text_color(lv.color_hex(0x000000), lv.PART.MAIN | lv.STATE.DEFAULT )
ui_Label2.set_style_text_opa(255, lv.PART.MAIN| lv.STATE.DEFAULT )

ui_Switch1 = lv.switch(ui_Screen1)
ui_Switch1.set_width(50)
ui_Switch1.set_height(25)
ui_Switch1.set_x(-1)
ui_Switch1.set_y(-23)
ui_Switch1.set_align( lv.ALIGN.CENTER)

lv.screen_load(ui_Screen1)

import task_handler

th = task_handler.TaskHandler()

# pn532 spi
spi_bus_pn532 = SPI(
    2,
    baudrate=1000000,
    sck=Pin(_SCK_PIN_PN532),
    mosi=Pin(_MOSI_PIN_PN532),
    miso=Pin(_MISO_PIN_PN532),
)

PN_CS = 15
cs_pin = Pin(PN_CS, Pin.OUT)
nfc = PN532(spi_bus_pn532, cs_pin)
nfc.SAM_configuration()
#

def main_loop():
    a = 1
    while True:
        ui_Label2.set_text(str(a))
        a = a + 1
        time.sleep(1)  

main_loop()

log ESP-ROM:esp32s3-20210327 Build:Mar 27 2021 rst:0x1 (POWERON),boot:0x9 (SPI_FAST_FLASH_BOOT) SPIWP:0xee mode:DIO, clock div:1 load:0x3fce3810,len:0xf8c load:0x403c9700,len:0xb3c load:0x403cc700,len:0x2dd4 entry 0x403c989c E (5235) spi_master: check_trans_valid(699): SPI_TRANS_USE_TXDATA only available for txdata transfer <= 32 bits

kdschlosser commented 4 months ago

I really go hate the code that is generated by Squareline Studio. It is the most inefficient code and it has horrible formatting, they also add a crap load of stuff that simply doesn't need to be added.

Here is a revised version. There is a change you need to make to the PN532 driver. Currently you have to pass the cs pin to that driver. You need to remove the drivers handling of the cs pin. This is something that is now done in the SPI driver. Once you make that change and upload the driver and the code below it should work.

from micropython import const   # NOQA

# display
_WIDTH = const(240)
_HEIGHT = const(320)
_HOST_DISP = const(1)
_FREQ_DISP = const(40000000)
_DC_PIN_DISP = const(7)
_MOSI_PIN_DISP = const(11)
_MISO_PIN_DISP = const(13)
_SCLK_PIN_DISP = const(12)
_CS_PIN_DISP = const(10)
_RESET_PIN_DISP = const(6)
_BACKLIGHT_PIN_DISP = const(5)

# PN532
_HOST_PN532 = const(2)
_FREQ_PN532 = const(1000000)
_CS_PIN_PN532 = const(15)
_MOSI_PIN_PN532 = const(14)
_MISO_PIN_PN532 = const(19)
_SCK_PIN_PN532 = const(18)

from machine import SPI  # NOQA
import lcd_bus  # NOQA

lcd_spi_bus = SPI(
    _HOST_DISP,
    _FREQ_DISP,
    sck=_SCLK_PIN_DISP,
    mosi=_MOSI_PIN_DISP,
    miso=_MISO_PIN_DISP
)

display_bus = lcd_bus.SPIBus(
    spi_bus=lcd_spi_bus,
    dc=_DC_PIN_DISP,
    cs=_CS_PIN_DISP,
    freq=_FREQ_DISP
)

import ili9341  # NOQA
import lvgl as lv  # NOQA

display = ili9341.ILI9341(
    data_bus=display_bus,
    display_width=_WIDTH,
    display_height=_HEIGHT,
    reset_pin=_RESET_PIN_DISP,
    reset_state=ili9341.STATE_LOW,
    backlight_pin=_BACKLIGHT_PIN_DISP,
    backlight_on_state=ili9341.STATE_HIGH,
    color_space=lv.COLOR_FORMAT.RGB565,
    rgb565_byte_swap=True
)

display.init()
display.set_backlight(100)

from NFC_PN532 import PN532  # NOQA

# pn532 spi
spi_bus_pn532 = SPI(
    _HOST_PN532,
    _FREQ_PN532,
    sck=_SCK_PIN_PN532,
    mosi=_MOSI_PIN_PN532,
    miso=_MISO_PIN_PN532,
    cs=_CS_PIN_PN532
)

# **** IMPORTANT ****
# you need to modify this module and remove it's handling of the CS pin.
# The SPI bus handles the CS pin. This is a feature that is available in this
# binding. It is not dione in MicroPython
nfc = PN532(spi_bus_pn532)
nfc.SAM_configuration()

import time  # NOQA
import ui_images  # NOQA

ui_Screen1 = lv.obj()
ui_Screen1.remove_flag(lv.obj.FLAG.SCROLLABLE)

ui_Image1 = lv.image(ui_Screen1)
ui_Image1.set_src(ui_images.ui_img_1361182409)
ui_Image1.set_width(lv.SIZE_CONTENT)  # 1
ui_Image1.set_height(lv.SIZE_CONTENT)  # 1
ui_Image1.set_x(-1)
ui_Image1.set_y(-124)

# LVGL9.1 bug fix patch 1, 1
ui_Image1.set_inner_align(lv.image.ALIGN.CENTER)

ui_Image1.center()
ui_Image1.add_flag(lv.obj.FLAG.CLICKABLE)
ui_Image1.remove_flag(lv.obj.FLAG.SCROLLABLE)

ui_Image2 = lv.image(ui_Screen1)
ui_Image2.set_src(ui_images.ui_img_2034924223)
ui_Image2.set_width(lv.SIZE_CONTENT)  # 220
ui_Image2.set_height(lv.SIZE_CONTENT)  # 94
ui_Image2.set_x(2)
ui_Image2.set_y(104)

# LVGL9.1 bug fix patch 220, 94
ui_Image2.set_inner_align(lv.image.ALIGN.CENTER)

# LVGL9.1 bug fix patch CENTER, 220, 94
ui_Image2.center()
ui_Image2.add_flag(lv.obj.FLAG.CLICKABLE)
ui_Image2.remove_flag(lv.obj.FLAG.SCROLLABLE)

ui_Label2 = lv.label(ui_Screen1)
ui_Label2.set_text("EXIT 1")
ui_Label2.set_width(lv.SIZE_CONTENT)  # 1
ui_Label2.set_height(lv.SIZE_CONTENT)  # 1
ui_Label2.set_x(-2)
ui_Label2.set_y(-60)
ui_Label2.set_align(lv.ALIGN.CENTER)
ui_Label2.set_style_text_color(
    lv.color_hex(0x000000), 
    lv.PART.MAIN | lv.STATE.DEFAULT
)
ui_Label2.set_style_text_opa(255, lv.PART.MAIN | lv.STATE.DEFAULT)

ui_Switch1 = lv.switch(ui_Screen1)
ui_Switch1.set_width(50)
ui_Switch1.set_height(25)
ui_Switch1.set_x(-1)
ui_Switch1.set_y(-23)
ui_Switch1.set_align(lv.ALIGN.CENTER)

lv.screen_load(ui_Screen1)

import task_handler  # NOQA

th = task_handler.TaskHandler()

# this is a better way to handle updating on a set schedule. This doesn't block
# the main thread making it easier to interrupt the running program when 
# needing to do something like uploading files.
# the other thing is it doesn't block the repl so you can connect over the USB 
# and you will get a repl prompt and be able to pass code to it.
# this all works because of the task handler above and it scheduling a task 
# that interrupts the main thread to update the display

a = 1

def timer_callback(_):
    global a
    ui_Label2.set_text(str(a))
    a += 1

timer = lv.timer_create(timer_callback, 1000, None)
timer.set_repeat_count(-1)
timer.enable(True)
Bigmaxmafia commented 4 months ago

@kdschlosser what commit do I need to compile for this code? I have this now

ESP-ROM:esp32s3-20210327
Build:Mar 27 2021
rst:0x1 (POWERON),boot:0x9 (SPI_FAST_FLASH_BOOT)
SPIWP:0xee
mode:DIO, clock div:1
load:0x3fce3810,len:0xf8c
load:0x403c9700,len:0xb3c
load:0x403cc700,len:0x2dd4
entry 0x403c989c
Traceback (most recent call last):
  File "boot.py", line 38, in <module>
TypeError: 'host' argument required
MicroPython v1.22.1-dirty on 2024-06-12; Generic ESP32S3 module with Octal-SPIRAM with ESP32S3
Type "help()" for more information.

I'm using commit c4f225a. I assume this code won't work on this commit?

kdschlosser commented 4 months ago

you need to be using the code in the master branch.

either clone the repo into a new location or remove the one you have and then clone it again

git clone https://github.com/kdschlosser/lvgl_micropython

kdschlosser commented 4 months ago

yeah that commit is OLD. I have had I cannot even tell you how many more changes made since then. I know it was only a few days ago but I do a lot of work in a short amount of time.