Skip to content
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

Can't mount SD card and display at the same time when sharing the same SPI bus #69

Closed
ryanfobel opened this issue Feb 14, 2020 · 16 comments
Labels
stale This will not be worked on

Comments

@ryanfobel
Copy link

Summary

I'm trying to use LittlevGL with an m5stack development board (esp32-based with an ili9341 display). Both the display and SD card interface share the same SPI bus, and it's not currently possible to initialize either device on an existing SPI bus.

Based on the work of @miketeachman, I was able to produce a workaround using the ILI9341 C module (details here). Basically, this involves removing the SPI initialization code in disp_spi_init() and setting the display to communicate in full-duplex instead of half-duplex mode. I have tried to port these changes to the Pure/Hybrid ili9341 driver, but I can't seem to get it work.

boot.py (v1)

The following boot.py is a minimal example of loading a LittlevGL button on the m5stack:

import machine
import os
import ili9341
import lvgl as lv

lv.init()

disp = ili9341.ili9341(spihost=1, miso=19, mosi=23, clk=18, cs=14,
                       dc=27, rst=33, backlight=32, backlight_on=1,
                       hybrid=True, mhz=25, width=320, height=240,
                       colormode=ili9341.ili9341.COLOR_MODE_BGR,
                       rot=ili9341.ili9341.MADCTL_ML, invert=True)

scr = lv.obj()
btn = lv.btn(scr)
btn.align(lv.scr_act(), lv.ALIGN.CENTER, 0, 0)
label = lv.label(btn)
label.set_text("Button")
lv.scr_load(scr)

This produces a blue button on a white screen:

image

boot.py (v2): mount SD card before initializing display

This is the same boot.py, but it tries to mount an SD card prior to initializing the display:

import machine
import os
import ili9341
import lvgl as lv

# Mount the SD card (note that this initializes the SPI bus)
os.mount(machine.SDCard(slot=3, sck=18, mosi=23, miso=19, cs=4), '/sd')

lv.init()

disp = ili9341.ili9341(spihost=1, miso=19, mosi=23, clk=18, cs=14,
                       dc=27, rst=33, backlight=32, backlight_on=1,
                       hybrid=True, mhz=25, width=320, height=240,
                       colormode=ili9341.ili9341.COLOR_MODE_BGR,
                       rot=ili9341.ili9341.MADCTL_ML, invert=True)

scr = lv.obj()
btn = lv.btn(scr)
btn.align(lv.scr_act(), lv.ALIGN.CENTER, 0, 0)
label = lv.label(btn)
label.set_text("Button")
lv.scr_load(scr)

As expected, this fails with the error:

E (420) spi: SPI2 already claimed by spi master.
E (420) spi_master: spi_bus_initialize(242): host already in use
Traceback (most recent call last):
  File "boot.py", line 15, in <module>
  File "ili9341.py", line 113, in __init__
  File "ili9341.py", line 326, in init
  File "ili9341.py", line 196, in disp_spi_init
RuntimeError: Failed initializing SPI bus

Attempted workaround

I tried modifying the pure/hybrid ili9341 driver by removing the SPI initialization code in disp_spi_init() and setting the display to communicate in full-duplex mode instead of half-duplex (the things that seemed to resolve the issue for the ILI9341 C module). The changes can be seen here. When I tried testing this modified driver with the boot.py (v2) from above, it resulted in the following error:

E (930) spi_master: check_trans_valid(1103): txdata transfer > host maximum

I'm not really sure what else to try. I'm happy to have a workaround using the C module, but it looks like the C module is being deprecated in favor of the pure/hybrid python driver, so if possible, I'd like to find a fix for that too. It would also be nice to be able to decide at run time whether you want to attach to a new or pre-initialized SPI bus.

@amirgon
Copy link
Collaborator

amirgon commented Feb 14, 2020

Hi @ryanfobel !

it looks like the C module is being deprecated in favor of the pure/hybrid python driver

That's true. I'm currently using and supporting only the micropython driver. It provides good performance (when using it in the hybrid mode), it's more flexible than the C driver and easier to maintain.

setting the display to communicate in full-duplex instead of half-duplex mode

The reason I chose half duplex mode - is performance.
According to the docs, Full-duplex transactions are not compatible with the dummy bit workaround, hence the frequency is limited.
Half duplex allows 80MHz on the dedicated SPI pins and 40MHz on GPIO-matrix-routed pins while full-duplex transfers only support speeds up to 26MHz. (see spi_bus_add_device).

This is important for high enough frame-rates, especially when using animations. In case of ili9341 we only care about writing, so half duplex makes sense.

It would also be nice to be able to decide at run time whether you want to attach to a new or pre-initialized SPI bus

This is already supported.
The ili9341 driver is built to work with shared SPI bus. If either miso, mosi or clk are set to -1, the bus is not initialized and the driver assumes it was already initialized by another driver.
I'm using this technique today to use ili9341 with xpt2046 touchscreen driver on the same bus. You can see that default miso/mosi/clk values of xpt2046 are -1, so ili9341 initializes the SPI bus and xpt2046 uses the pre-initialized bus, but it can also work the other way around.

All drivers that share the same SPI bus should be either half-duplex or full-duplex.
Can you use your SD card driver in half-duplex mode?
If you can, try to pass -1 to miso/mosi/clk on the ili9341 driver.

When I tried testing this modified driver with the boot.py (v2) from above, it resulted in the following error:

E (930) spi_master: check_trans_valid(1103): txdata transfer > host maximum

As I mentioned above, full duplex limits performance.
Try to set a lower SPI freq. Set mhz=20 on ili9341 constructor, for example.
If it works for you, we can add another parameter to ili9341 driver to let the user select half/full duplex.
Feel free to send a PR!

@ryanfobel
Copy link
Author

Hi @amirgon. Thanks for your reply and for all of your work on the micropython bindings for LittlevGL; I'm finding them super useful!

I tried running the following code based on your hint to set mosi=-1 and mhz=20:

import os
import machine

import lvgl as lv
import ili9341

os.mount(machine.SDCard(slot=3, sck=18, mosi=23, miso=19, cs=4), '/sd')

lv.init()
disp = ili9341.ili9341(spihost=1, mosi=-1, cs=14, dc=27,
              rst=33, backlight=32, mhz=20, backlight_on=1,
              hybrid=True, width=320, height=240,
              colormode=ili9341.ili9341.COLOR_MODE_BGR,
              rot=ili9341.ili9341.MADCTL_ML)
disp.send_cmd(0x21)

scr = lv.obj()
label = lv.label(scr)
label.set_text("Hello World!")
label.align(lv.scr_act(), lv.ALIGN.CENTER, 0, 0)
lv.scr_load(scr)

print(os.listdir('/sd'))

When I run the above code against the default micropython build (i.e., with the ili9341 driver initialized using half-duplex SPI), I get the following errors:

E (990) sdmmc_cmd: sdmmc_read_sectors_dma: sdmmc_send_cmd returned 0x107
['RRaA']
E (1000) spi_master: check_trans_valid(1103): txdata transfer > host maximum

If I rebuild micropython with the ili9341 driver initialized using full-duplex mode, the first error disappears, but I still get the second one:

E (1000) spi_master: check_trans_valid(1103): txdata transfer > host maximum

I couldn't find any way to mount the SD card on a pre-initialized SPI bus, but maybe that's something I should ask about on the micropython forums.

@amirgon
Copy link
Collaborator

amirgon commented Feb 14, 2020

If I rebuild micropython with the ili9341 driver initialized using full-duplex mode, the first error disappears, but I still get the second one:

E (1000) spi_master: check_trans_valid(1103): txdata transfer > host maximum

It looks like DMA size is too large.
Try decreasing it by setting factor=8 or factor=16 etc. on ili9341 constructor.

The problem is that the SD card driver initializes the bus with small DMA buffer size. If you can't configure the buffer size on the SD card driver you'd have to use smaller buffers on the ili9341 driver (= higher factors). This will impact performance but save some RAM.

@ryanfobel
Copy link
Author

I tried factor=8, factor=16 and factor=32 and I get the same error message in every case.

@amirgon
Copy link
Collaborator

amirgon commented Feb 15, 2020

I tried factor=8, factor=16 and factor=32 and I get the same error message in every case.

I'm not really sure why this happens.
If you have the time and resources, you could try building lv_micropython in DEBUG configuration and debugging it (with JTAG).

Did you see this issue: espressif/esp-idf#1597 ?

Due to the limited amount of IO pins on ESP32, it is desirable to share a SPI bus used for SD cards with other SPI devices such as a LCD display. This is currently not possible with esp-idf since the sdspi_host driver assumes the SD card will be the only device on the SPI bus.

This problem was fixed in espressif/esp-idf@067f3d2, but that commit is not included yet in Micropython (at least not on the last release v1.12, which lv_micropython is aligned to).
If you want, you can try building lv_micropython with a more up to date esp-idf that includes this fix, but you'll probably need to change the SD driver to use the new sdspi_host_init_device, sdspi_host_remove_device functions.

Another thing to try on the ili9341 driver is sending SPI transactions exclusively by Bus Acquiring.

I'm not sure why this is working at all with the C driver, but not with the micropython driver. Did you make sure it is working stably?
It might be related to the fact the the C driver is not really doing DMA in the background, like the micropython driver does. Instead, it sends the request and waits for it to complete. While very inefficient, it might prevent other devices from accessing the SPI bus while in progress.

@stale
Copy link

stale bot commented Mar 7, 2020

This issue or pull request has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the stale This will not be worked on label Mar 7, 2020
@stale stale bot closed this as completed Mar 14, 2020
@favnec5
Copy link
Contributor

favnec5 commented Aug 28, 2021

Hello guys,
Do you have a pure micropython solution to resolve with 1.14 ?
Same problem to my Core2...

@amirgon
Copy link
Collaborator

amirgon commented Aug 28, 2021

Do you have a pure micropython solution to resolve with 1.14 ?
Same problem to my Core2...

Hi @favnec5 !

I don't think there was any progress on this.
Personally I don't use SD card on my projects so I was never blocked by this problem.

Since I can't debug this, I was hoping someone from the LVGL community would face it and would want to invest some time exploring it.

I don't think we fully understand the problem yet, specifically why the C driver works where the Python driver doesn't.
Here are some related forum threads regarding this problem:

This might also be related: #80

So if you (or anyone else) would like to explore this - I'll be happy to re-open this issue.

@favnec5
Copy link
Contributor

favnec5 commented Aug 30, 2021

Hi amirgon,
I think we have to rewrite the sdCard driver but added into illixxx.py with esp idf module functions to resolve this problem. I don’t Know if it’s possible. I’m searching.

@favnec5
Copy link
Contributor

favnec5 commented Aug 31, 2021

Sorry, i don't think it's possible.
On my 1.14 lv_micropython, the esp-idf api don't have sdmmc functions :

espidf module list
espidf module
ADC1_CHANNEL
 | MAX
 | _0
 | _1
 | _2
 | _3
 | _4
 | _5
 | _6
 | _7
ADC2_CHANNEL
 | MAX
 | _0
 | _1
 | _2
 | _3
 | _4
 | _5
 | _6
 | _7
 | _8
 | _9
ADC_ATTEN
 | DB_0
 | DB_11
 | DB_2_5
 | DB_6
 | MAX
ADC_CHANNEL
 | MAX
 | _0
 | _1
 | _2
 | _3
 | _4
 | _5
 | _6
 | _7
 | _8
 | _9
ADC_ENCODE
 | MAX
 | _11BIT
 | _12BIT
ADC_I2S_DATA_SRC
 | ADC
 | IO_SIG
 | MAX
ADC_UNIT
 | ALTER
 | BOTH
 | MAX
 | _1
 | _2
ADC_WIDTH
 | BIT_10
 | BIT_11
 | BIT_12
 | BIT_9
 | MAX
BUSY
CANCEL
CHIP
 | ESP32
C_Pointer
 | SIZE
 | cast
 | cast_instance
ESP_IF
 | ETH
 | MAX
 | WIFI_AP
 | WIFI_STA
ESP_LOG
 | DEBUG
 | ERROR
 | INFO
 | NONE
 | VERBOSE
 | WARN
ESP_MAC
 | BT
 | ETH
 | WIFI_SOFTAP
 | WIFI_STA
ESP_RST
 | BROWNOUT
 | DEEPSLEEP
 | EXT
 | INT_WDT
 | PANIC
 | POWERON
 | SDIO
 | SW
 | TASK_WDT
 | UNKNOWN
 | WDT
ESP_TASK_PRIO
 | MAX
 | MIN
ETS
 | FAILED
 | OK
ETSTimer
 | SIZE
 | cast
 | cast_instance
F
 | CHUNKED
 | CONNECTION_CLOSE
 | CONNECTION_KEEP_ALIVE
 | CONNECTION_UPGRADE
 | CONTENTLENGTH
 | SKIPBODY
 | TRAILING
 | UPGRADE
FAIL
GPIO
 | FLOATING
 | PULLDOWN_ONLY
 | PULLUP_ONLY
 | PULLUP_PULLDOWN
GPIO_DRIVE_CAP
 | DEFAULT
 | MAX
 | _0
 | _1
 | _2
 | _3
GPIO_INTR
 | ANYEDGE
 | DISABLE
 | HIGH_LEVEL
 | LOW_LEVEL
 | MAX
 | NEGEDGE
 | POSEDGE
GPIO_MODE
 | DISABLE
 | INPUT
 | INPUT_OUTPUT
 | INPUT_OUTPUT_OD
 | OUTPUT
 | OUTPUT_OD
GPIO_NUM
 | MAX
 | NC
 | _0
 | _1
 | _10
 | _11
 | _12
 | _13
 | _14
 | _15
 | _16
 | _17
 | _18
 | _19
 | _2
 | _21
 | _22
 | _23
 | _25
 | _26
 | _27
 | _3
 | _32
 | _33
 | _34
 | _35
 | _36
 | _37
 | _38
 | _39
 | _4
 | _5
 | _6
 | _7
 | _8
 | _9
GPIO_PIN_INTR
 | ANYEDGE
 | DISABLE
 | HILEVEL
 | LOLEVEL
 | NEGEDGE
 | POSEDGE
GPIO_PULLDOWN
 | DISABLE
 | ENABLE
GPIO_PULLUP
 | DISABLE
 | ENABLE
HPE
 | CB_body
 | CB_chunk_complete
 | CB_chunk_header
 | CB_header_field
 | CB_header_value
 | CB_headers_complete
 | CB_message_begin
 | CB_message_complete
 | CB_status
 | CB_url
 | CLOSED_CONNECTION
 | HEADER_OVERFLOW
 | INVALID_CHUNK_SIZE
 | INVALID_CONSTANT
 | INVALID_CONTENT_LENGTH
 | INVALID_EOF_STATE
 | INVALID_FRAGMENT
 | INVALID_HEADER_TOKEN
 | INVALID_HOST
 | INVALID_INTERNAL_STATE
 | INVALID_METHOD
 | INVALID_PATH
 | INVALID_PORT
 | INVALID_QUERY_STRING
 | INVALID_STATUS
 | INVALID_URL
 | INVALID_VERSION
 | LF_EXPECTED
 | OK
 | PAUSED
 | STRICT
 | UNEXPECTED_CONTENT_LENGTH
 | UNKNOWN
HSPI_HOST
HTTP
 | ACL
 | BIND
 | BOTH
 | CHECKOUT
 | CONNECT
 | COPY
 | DELETE
 | GET
 | HEAD
 | LINK
 | LOCK
 | MERGE
 | MKACTIVITY
 | MKCALENDAR
 | MKCOL
 | MOVE
 | MSEARCH
 | NOTIFY
 | OPTIONS
 | PATCH
 | POST
 | PROPFIND
 | PROPPATCH
 | PURGE
 | PUT
 | REBIND
 | REPORT
 | REQUEST
 | RESPONSE
 | SEARCH
 | SUBSCRIBE
 | TRACE
 | UNBIND
 | UNLINK
 | UNLOCK
 | UNSUBSCRIBE
HTTP_AUTH_TYPE
 | BASIC
 | DIGEST
 | NONE
HTTP_EVENT
 | DISCONNECTED
 | ERROR
 | HEADERS_SENT
 | HEADER_SENT
 | ON_CONNECTED
 | ON_DATA
 | ON_FINISH
 | ON_HEADER
HTTP_METHOD
 | DELETE
 | GET
 | HEAD
 | MAX
 | NOTIFY
 | OPTIONS
 | PATCH
 | POST
 | PUT
 | SUBSCRIBE
 | UNSUBSCRIBE
HTTP_TRANSPORT
 | OVER_SSL
 | OVER_TCP
 | UNKNOWN
HttpStatus
 | Found
 | MovedPermanently
 | Unauthorized
I2S_BITS_PER_SAMPLE
 | _16BIT
 | _24BIT
 | _32BIT
 | _8BIT
I2S_CHANNEL
 | MONO
 | STEREO
I2S_CHANNEL_FMT
 | ALL_LEFT
 | ALL_RIGHT
 | ONLY_LEFT
 | ONLY_RIGHT
 | RIGHT_LEFT
I2S_COMM_FORMAT
 | I2S
 | I2S_LSB
 | I2S_MSB
 | PCM
 | PCM_LONG
 | PCM_SHORT
I2S_DAC_CHANNEL
 | BOTH_EN
 | DISABLE
 | LEFT_EN
 | MAX
 | RIGHT_EN
I2S_EVENT
 | DMA_ERROR
 | MAX
 | RX_DONE
 | TX_DONE
I2S_MODE
 | ADC_BUILT_IN
 | DAC_BUILT_IN
 | MASTER
 | PDM
 | RX
 | SLAVE
 | TX
I2S_NUM
 | MAX
 | _0
 | _1
I2S_PDM_DSR
 | MAX
 | _16S
 | _8S
I2S_PIN_NO
 | CHANGE
IP6
 | MULTICAST
 | UNICAST
 | UNKNOWN
IPADDR_TYPE
 | ANY
 | V4
 | V6
IP_EVENT
 | AP_STAIPASSIGNED
 | ETH_GOT_IP
 | GOT_IP6
 | STA_GOT_IP
 | STA_LOST_IP
MALLOC_CAP
 | DMA
 | INTERNAL
 | SPIRAM
MDNS_IP_PROTOCOL
 | MAX
 | V4
 | V6
OFFER
 | DNS
 | END
 | ROUTER
 | START
OK
PCNT_CHANNEL
 | MAX
 | _0
 | _1
PCNT_COUNT
 | DEC
 | DIS
 | INC
 | MAX
PCNT_EVT
 | H_LIM
 | L_LIM
 | MAX
 | THRES_0
 | THRES_1
 | ZERO
PCNT_MODE
 | DISABLE
 | KEEP
 | MAX
 | REVERSE
PCNT_UNIT
 | MAX
 | _0
 | _1
 | _2
 | _3
 | _4
 | _5
 | _6
 | _7
PDM_PCM_CONV
 | DISABLE
 | ENABLE
PDM_SAMPLE_RATE_RATIO
 | _128
 | _64
PENDING
PERIPH
 | AES_MODULE
 | BT_BASEBAND_MODULE
 | BT_LC_MODULE
 | BT_MODULE
 | CAN_MODULE
 | EMAC_MODULE
 | HSPI_MODULE
 | I2C0_MODULE
 | I2C1_MODULE
 | I2S0_MODULE
 | I2S1_MODULE
 | LEDC_MODULE
 | PCNT_MODULE
 | PWM0_MODULE
 | PWM1_MODULE
 | PWM2_MODULE
 | PWM3_MODULE
 | RMT_MODULE
 | RNG_MODULE
 | RSA_MODULE
 | SDIO_SLAVE_MODULE
 | SDMMC_MODULE
 | SHA_MODULE
 | SPI_DMA_MODULE
 | SPI_MODULE
 | TIMG0_MODULE
 | TIMG1_MODULE
 | UART0_MODULE
 | UART1_MODULE
 | UART2_MODULE
 | UHCI0_MODULE
 | UHCI1_MODULE
 | VSPI_MODULE
 | WIFI_BT_COMMON_MODULE
 | WIFI_MODULE
SH2LIB_DATA_FLAG
 | EOF
 | NONE
 | NO_COPY
 | NO_END_STREAM
SH2LIB_DATA_RECV
 | FRAME_COMPLETE
 | NONE
 | RST_STREAM
SH2LIB_ERR
 | BAD_CLIENT_MAGIC
 | BUFFER_ERROR
 | CALLBACK_FAILURE
 | CANCEL
 | DATA_EXIST
 | DEFERRED
 | DEFERRED_DATA_EXIST
 | EOF
 | FATAL
 | FLOODED
 | FLOW_CONTROL
 | FRAME_SIZE_ERROR
 | GOAWAY_ALREADY_SENT
 | HEADER_COMP
 | HTTP_HEADER
 | HTTP_MESSAGING
 | INSUFF_BUFSIZE
 | INTERNAL
 | INVALID_ARGUMENT
 | INVALID_FRAME
 | INVALID_HEADER_BLOCK
 | INVALID_STATE
 | INVALID_STREAM_ID
 | INVALID_STREAM_STATE
 | NOMEM
 | PAUSE
 | PROTO
 | PUSH_DISABLED
 | REFUSED_STREAM
 | SESSION_CLOSING
 | START_STREAM_NOT_ALLOWED
 | STREAM_CLOSED
 | STREAM_CLOSING
 | STREAM_ID_NOT_AVAILABLE
 | STREAM_SHUT_WR
 | TEMPORAL_CALLBACK_FAILURE
 | TOO_MANY_INFLIGHT_SETTINGS
 | UNSUPPORTED_VERSION
 | WOULDBLOCK
SH2LIB_NV_FLAG
 | NONE
 | NO_COPY_NAME
 | NO_COPY_VALUE
 | NO_INDEX
SPH0645_WORKAROUND
SPI1_HOST
SPI2_HOST
SPI3_HOST
SPI_DEVICE
 | BIT_LSBFIRST
 | CLK_AS_CS
 | HALFDUPLEX
 | NO_DUMMY
 | POSITIVE_CS
 | RXBIT_LSBFIRST
 | TXBIT_LSBFIRST
 | _3WIRE
SPI_HOST
SPI_TRANS
 | MODE_DIO
 | MODE_DIOQIO_ADDR
 | MODE_QIO
 | USE_RXDATA
 | USE_TXDATA
 | VARIABLE_ADDR
 | VARIABLE_CMD
TCPIP_ADAPTER
 | DOMAIN_NAME_SERVER
 | IP_ADDRESS_LEASE_TIME
 | IP_REQUEST_RETRY_TIME
 | REQUESTED_IP_ADDRESS
 | ROUTER_SOLICITATION_ADDRESS
TCPIP_ADAPTER_DHCP
 | INIT
 | STARTED
 | STATUS_MAX
 | STOPPED
TCPIP_ADAPTER_DNS
 | BACKUP
 | FALLBACK
 | MAIN
 | MAX
TCPIP_ADAPTER_IF
 | AP
 | ETH
 | MAX
 | STA
 | TEST
TCPIP_ADAPTER_OP
 | GET
 | MAX
 | SET
 | START
UF
 | FRAGMENT
 | HOST
 | MAX
 | PATH
 | PORT
 | QUERY
 | SCHEMA
 | USERINFO
VSPI_HOST
WIFI
 | ALL_CHANNEL_SCAN
 | FAST_SCAN
WIFI_ANT
 | ANT0
 | ANT1
 | MAX
WIFI_ANT_MODE
 | ANT0
 | ANT1
 | AUTO
 | MAX
WIFI_AUTH
 | MAX
 | OPEN
 | WEP
 | WPA2_ENTERPRISE
 | WPA2_PSK
 | WPA2_WPA3_PSK
 | WPA3_PSK
 | WPA_PSK
 | WPA_WPA2_PSK
WIFI_BW
 | HT20
 | HT40
WIFI_CIPHER_TYPE
 | AES_CMAC128
 | CCMP
 | NONE
 | TKIP
 | TKIP_CCMP
 | UNKNOWN
 | WEP104
 | WEP40
WIFI_CONNECT_AP_BY
 | SECURITY
 | SIGNAL
WIFI_COUNTRY_POLICY
 | AUTO
 | MANUAL
WIFI_EVENT
 | AP_PROBEREQRECVED
 | AP_STACONNECTED
 | AP_STADISCONNECTED
 | AP_START
 | AP_STOP
 | SCAN_DONE
 | STA_AUTHMODE_CHANGE
 | STA_CONNECTED
 | STA_DISCONNECTED
 | STA_START
 | STA_STOP
 | STA_WPS_ER_FAILED
 | STA_WPS_ER_PBC_OVERLAP
 | STA_WPS_ER_PIN
 | STA_WPS_ER_SUCCESS
 | STA_WPS_ER_TIMEOUT
 | WIFI_READY
WIFI_MODE
 | AP
 | APSTA
 | MAX
 | NULL
 | STA
WIFI_PHY_RATE
 | LORA_250K
 | LORA_500K
 | MAX
 | MCS0_LGI
 | MCS0_SGI
 | MCS1_LGI
 | MCS1_SGI
 | MCS2_LGI
 | MCS2_SGI
 | MCS3_LGI
 | MCS3_SGI
 | MCS4_LGI
 | MCS4_SGI
 | MCS5_LGI
 | MCS5_SGI
 | MCS6_LGI
 | MCS6_SGI
 | MCS7_LGI
 | MCS7_SGI
 | _11M_L
 | _11M_S
 | _12M
 | _18M
 | _1M_L
 | _24M
 | _2M_L
 | _2M_S
 | _36M
 | _48M
 | _54M
 | _5M_L
 | _5M_S
 | _6M
 | _9M
WIFI_PKT
 | CTRL
 | DATA
 | MGMT
 | MISC
WIFI_PS
 | MAX_MODEM
 | MIN_MODEM
 | NONE
WIFI_REASON
 | AKMP_INVALID
 | ASSOC_EXPIRE
 | ASSOC_FAIL
 | ASSOC_LEAVE
 | ASSOC_NOT_AUTHED
 | ASSOC_TOOMANY
 | AUTH_EXPIRE
 | AUTH_FAIL
 | AUTH_LEAVE
 | BEACON_TIMEOUT
 | CIPHER_SUITE_REJECTED
 | CONNECTION_FAIL
 | DISASSOC_PWRCAP_BAD
 | DISASSOC_SUPCHAN_BAD
 | GROUP_CIPHER_INVALID
 | GROUP_KEY_UPDATE_TIMEOUT
 | HANDSHAKE_TIMEOUT
 | IE_INVALID
 | IE_IN_4WAY_DIFFERS
 | INVALID_PMKID
 | INVALID_RSN_IE_CAP
 | MIC_FAILURE
 | NOT_ASSOCED
 | NOT_AUTHED
 | NO_AP_FOUND
 | PAIRWISE_CIPHER_INVALID
 | UNSPECIFIED
 | UNSUPP_RSN_IE_VERSION
 | _4WAY_HANDSHAKE_TIMEOUT
 | _802_1X_AUTH_FAILED
WIFI_SCAN_TYPE
 | ACTIVE
 | PASSIVE
WIFI_SECOND_CHAN
 | ABOVE
 | BELOW
 | NONE
WIFI_STORAGE
 | FLASH
 | RAM
WIFI_VND_IE_ID
 | _0
 | _1
WIFI_VND_IE_TYPE
 | ASSOC_REQ
 | ASSOC_RESP
 | BEACON
 | PROBE_REQ
 | PROBE_RESP
WPS_FAIL_REASON
 | MAX
 | NORMAL
 | RECV_M2D
adc1_config_channel_atten
adc1_config_width
adc1_get_raw
adc1_pad_get_io_num
adc1_ulp_enable
adc2_config_channel_atten
adc2_get_raw
adc2_pad_get_io_num
adc2_vref_to_gpio
adc_gpio_init
adc_i2s_mode_init
adc_power_off
adc_power_on
adc_set_clk_div
adc_set_data_inv
adc_set_data_width
adc_set_i2s_data_source
dhcp_ip_addr_erase
dhcp_ip_addr_restore
dhcp_ip_addr_store
dhcp_search_ip_on_mac
dhcps_dns_enabled
dhcps_dns_getserver
dhcps_dns_setserver
dhcps_option_info
dhcps_router_enabled
dhcps_set_new_lease_cb
dhcps_set_option_info
dhcps_start
dhcps_stop
esp_base_mac_addr_get
esp_base_mac_addr_set
esp_chip_info_t
 | SIZE
 | cast
 | cast_instance
 | info
esp_clk_apb_freq
esp_clk_cpu_freq
esp_clk_rtc_time
esp_clk_slowclk_cal_get
esp_clk_slowclk_cal_set
esp_clk_xtal_freq
esp_derive_local_mac
esp_efuse_mac_get_custom
esp_efuse_mac_get_default
esp_err_to_name
esp_err_to_name_r
esp_fill_random
esp_get_free_heap_size
esp_get_idf_version
esp_get_minimum_free_heap_size
esp_http_client_add_auth
esp_http_client_cleanup
esp_http_client_close
esp_http_client_config_t
 | SIZE
 | cast
 | cast_instance
 | init
 | register_event_handler
esp_http_client_delete_header
esp_http_client_event_t
 | SIZE
 | cast
 | cast_instance
esp_http_client_fetch_headers
esp_http_client_get_content_length
esp_http_client_get_header
esp_http_client_get_password
esp_http_client_get_post_field
esp_http_client_get_status_code
esp_http_client_get_transport_type
esp_http_client_get_username
esp_http_client_is_chunked_response
esp_http_client_is_complete_data_received
esp_http_client_open
esp_http_client_perform
esp_http_client_read
esp_http_client_set_header
esp_http_client_set_method
esp_http_client_set_password
esp_http_client_set_post_field
esp_http_client_set_redirection
esp_http_client_set_url
esp_http_client_set_username
esp_http_client_write
esp_intr_alloc
esp_intr_alloc_intrstatus
esp_intr_disable
esp_intr_enable
esp_intr_free
esp_intr_get_cpu
esp_intr_get_intno
esp_intr_mark_shared
esp_intr_noniram_disable
esp_intr_noniram_enable
esp_intr_reserve
esp_intr_set_in_iram
esp_log_buffer_char_internal
esp_log_buffer_hex_internal
esp_log_buffer_hexdump_internal
esp_log_early_timestamp
esp_log_level_set
esp_log_set_vprintf
esp_log_timestamp
esp_random
esp_read_mac
esp_register_shutdown_handler
esp_reset_reason
esp_restart
esp_unregister_shutdown_handler
ets_delay_us
ets_get_cpu_frequency
ets_get_detected_xtal_freq
ets_get_xtal_scale
ets_install_putc1
ets_install_putc2
ets_install_uart_printf
ets_intr_lock
ets_intr_unlock
ets_isr_attach
ets_isr_mask
ets_isr_unmask
ets_post
ets_run
ets_set_appcpu_boot_addr
ets_set_idle_cb
ets_set_startup_callback
ets_set_user_start
ets_task
ets_timer_arm
ets_timer_arm_us
ets_timer_deinit
ets_timer_disarm
ets_timer_done
ets_timer_init
ets_timer_setfn
ets_unpack_flash_code
ets_unpack_flash_code_legacy
ets_update_cpu_frequency
ets_update_cpu_frequency_rom
ets_waiti0
ets_write_char_uart
ex_spi_post_cb_isr
ex_spi_pre_cb_isr
get_ccount
gpio_config_t
 | SIZE
 | cast
 | cast_instance
 | config
gpio_deep_sleep_hold_dis
gpio_deep_sleep_hold_en
gpio_get_drive_capability
gpio_get_level
gpio_hold_dis
gpio_hold_en
gpio_init
gpio_input_get
gpio_input_get_high
gpio_install_isr_service
gpio_intr_ack
gpio_intr_ack_high
gpio_intr_disable
gpio_intr_enable
gpio_intr_handler_register
gpio_intr_pending
gpio_intr_pending_high
gpio_iomux_in
gpio_iomux_out
gpio_isr_handler_add
gpio_isr_handler_remove
gpio_isr_register
gpio_matrix_in
gpio_matrix_out
gpio_output_set
gpio_output_set_high
gpio_pad_hold
gpio_pad_pulldown
gpio_pad_pullup
gpio_pad_select_gpio
gpio_pad_set_drv
gpio_pad_unhold
gpio_pin_wakeup_disable
gpio_pin_wakeup_enable
gpio_pulldown_dis
gpio_pulldown_en
gpio_pullup_dis
gpio_pullup_en
gpio_reset_pin
gpio_set_direction
gpio_set_drive_capability
gpio_set_intr_type
gpio_set_level
gpio_set_pull_mode
gpio_uninstall_isr_service
gpio_wakeup_disable
gpio_wakeup_enable
hall_sensor_read
heap_caps_calloc
heap_caps_check_integrity
heap_caps_check_integrity_addr
heap_caps_check_integrity_all
heap_caps_dump
heap_caps_dump_all
heap_caps_free
heap_caps_get_free_size
heap_caps_get_info
heap_caps_get_largest_free_block
heap_caps_get_minimum_free_size
heap_caps_malloc
heap_caps_malloc_extmem_enable
heap_caps_print_heap_info
heap_caps_realloc
http_errno_description
http_errno_name
http_method_str
http_parser
 | SIZE
 | body_is_final
 | cast
 | cast_instance
 | parser_execute
 | parser_init
 | parser_pause
 | should_keep_alive
http_parser_parse_url
http_parser_settings
 | SIZE
 | cast
 | cast_instance
 | settings_init
http_parser_url_init
http_parser_version
i2s_adc_disable
i2s_adc_enable
i2s_config_t
 | SIZE
 | cast
 | cast_instance
i2s_driver_install
i2s_driver_uninstall
i2s_get_clk
i2s_pin_config_t
 | SIZE
 | cast
 | cast_instance
i2s_read
i2s_set_adc_mode
i2s_set_clk
i2s_set_dac_mode
i2s_set_pdm_rx_down_sample
i2s_set_pin
i2s_set_sample_rates
i2s_start
i2s_stop
i2s_write
i2s_write_expand
i2s_zero_dma_buffer
ili9xxx_flush
ili9xxx_post_cb_isr
intr_matrix_set
ip4_addr_isbroadcast_u32
ip4_addr_netmask_valid
ip4_addr_t
 | SIZE
 | cast
 | cast_instance
ip4addr_aton
ip4addr_ntoa
ip4addr_ntoa_r
ip6_addr_any
ip6_addr_t
 | SIZE
 | cast
 | cast_instance
ip6addr_aton
ip6addr_ntoa
ip6addr_ntoa_r
ip_addr_any
ip_addr_any_type
ip_addr_broadcast
ip_addr_t
 | SIZE
 | cast
 | cast_instance
 | paddr_ntoa
 | paddr_ntoa_r
ip_addr_u_addr_t
 | SIZE
 | cast
 | cast_instance
ipaddr_addr
ipaddr_aton
lwip_htonl
lwip_htons
lwip_itoa
lwip_stricmp
lwip_strnicmp
lwip_strnstr
mdns_free
mdns_handle_system_event
mdns_hostname_set
mdns_init
mdns_instance_name_set
mdns_ip_addr_t
 | SIZE
 | cast
 | cast_instance
mdns_query
mdns_query_a
mdns_query_aaaa
mdns_query_ptr
mdns_query_srv
mdns_query_txt
mdns_result_t
 | SIZE
 | cast
 | cast_instance
 | query_results_free
mdns_service_add
mdns_service_instance_name_set
mdns_service_port_set
mdns_service_remove
mdns_service_remove_all
mdns_service_txt_item_remove
mdns_service_txt_item_set
mdns_service_txt_set
mdns_txt_item_t
 | SIZE
 | cast
 | cast_instance
memcpy
memset
multi_heap_check
multi_heap_dump
multi_heap_free
multi_heap_free_size
multi_heap_get_allocated_size
multi_heap_get_info
multi_heap_info_t
 | SIZE
 | cast
 | cast_instance
multi_heap_malloc
multi_heap_minimum_free_size
multi_heap_realloc
multi_heap_register
multi_heap_set_lock
pcnt_config_t
 | SIZE
 | cast
 | cast_instance
 | unit_config
pcnt_counter_clear
pcnt_counter_pause
pcnt_counter_resume
pcnt_event_disable
pcnt_event_enable
pcnt_filter_disable
pcnt_filter_enable
pcnt_get_counter_value
pcnt_get_event_value
pcnt_get_filter_value
pcnt_intr_disable
pcnt_intr_enable
pcnt_isr_handler_add
pcnt_isr_handler_remove
pcnt_isr_register
pcnt_isr_service_install
pcnt_isr_service_uninstall
pcnt_set_event_value
pcnt_set_filter_value
pcnt_set_mode
pcnt_set_pin
periph_module_disable
periph_module_enable
periph_module_reset
portMAX
 | DELAY
sh2lib_handle
 | SIZE
 | cast
 | cast_instance
 | connect
 | connect_async
 | connect_task
 | do_get
 | do_get_with_nv
 | do_post
 | do_put
 | do_putpost_with_nv
 | execute
 | free
 | session_resume_data
sh2lib_nv
 | SIZE
 | cast
 | cast_instance
spi_bus_add_device
spi_bus_config_t
 | SIZE
 | cast
 | cast_instance
spi_bus_free
spi_bus_initialize
spi_bus_remove_device
spi_cal_clock
spi_device_acquire_bus
spi_device_get_trans_result
spi_device_interface_config_t
 | SIZE
 | cast
 | cast_instance
spi_device_polling_end
spi_device_polling_start
spi_device_polling_transmit
spi_device_queue_trans
spi_device_release_bus
spi_device_transmit
spi_get_actual_clock
spi_get_freq_limit
spi_get_timing
spi_transaction_ext_t
 | SIZE
 | cast
 | cast_instance
 | et_spi_transaction_ext
spi_transaction_set_cb
spi_transaction_t
 | SIZE
 | cast
 | cast_instance
task_delay_ms
tcpip_adapter_ap_input
tcpip_adapter_ap_start
tcpip_adapter_clear_default_eth_handlers
tcpip_adapter_clear_default_wifi_handlers
tcpip_adapter_create_ip6_linklocal
tcpip_adapter_dhcpc_get_status
tcpip_adapter_dhcpc_option
tcpip_adapter_dhcpc_start
tcpip_adapter_dhcpc_stop
tcpip_adapter_dhcps_get_status
tcpip_adapter_dhcps_option
tcpip_adapter_dhcps_start
tcpip_adapter_dhcps_stop
tcpip_adapter_dns_info_t
 | SIZE
 | cast
 | cast_instance
tcpip_adapter_down
tcpip_adapter_eth_input
tcpip_adapter_eth_start
tcpip_adapter_get_dns_info
tcpip_adapter_get_esp_if
tcpip_adapter_get_hostname
tcpip_adapter_get_ip6_global
tcpip_adapter_get_ip6_linklocal
tcpip_adapter_get_ip_info
tcpip_adapter_get_netif
tcpip_adapter_get_netif_index
tcpip_adapter_get_old_ip_info
tcpip_adapter_get_sta_list
tcpip_adapter_init
tcpip_adapter_ip_info_t
 | SIZE
 | cast
 | cast_instance
tcpip_adapter_is_netif_up
tcpip_adapter_set_default_eth_handlers
tcpip_adapter_set_default_wifi_handlers
tcpip_adapter_set_dns_info
tcpip_adapter_set_hostname
tcpip_adapter_set_ip_info
tcpip_adapter_set_old_ip_info
tcpip_adapter_sta_info_t
 | SIZE
 | cast
 | cast_instance
tcpip_adapter_sta_input
tcpip_adapter_sta_list_t
 | SIZE
 | cast
 | cast_instance
tcpip_adapter_sta_start
tcpip_adapter_stop
tcpip_adapter_test_start
tcpip_adapter_up
uxTaskPriorityGet
vPortCleanUpTCB
wifi_sta_info_t
 | SIZE
 | cast
 | cast_instance
wifi_sta_list_t
 | SIZE
 | cast
 | cast_instance
xPortGetCoreID
xt_clock_freq

@amirgon
Copy link
Collaborator

amirgon commented Aug 31, 2021

@embeddedt - I didn't know this <details> <summary> Markdown trick - cool!

@favnec5 - I'm not sure I understand. Doesn't Micropython has its own implementation for sdcard driver?
Why are you looking for esp-idf implementation?

@favnec5
Copy link
Contributor

favnec5 commented Aug 31, 2021

Sure, but sdcard.py use internal micropython machine.SPI function. it do not support -1 value into mosi/miso/cl.
I think re-create sdcard.py driver with native espidf module to implement device addition on the same SPI like the XPT2046.py driver could be a solution. But it's not easy for me and sdspi functions are not implemented.

@amirgon
Copy link
Collaborator

amirgon commented Sep 1, 2021

On my 1.14 lv_micropython, the esp-idf api don't have sdmmc functions :

espidf is a generated module.
It's possible to add new APIs from ESP-IDF into it by editing espidf.h.
If you think sdmmc functions in espidf module could help, you can try adding the relevant includes there.

The tricky part is how to not include the whole ESP-IDF because of dependent includes. This is done by defining include guards and filtering out include files explicitly in CMake.

@favnec5
Copy link
Contributor

favnec5 commented Oct 3, 2021

Hi amirgon,
i'm happy to report you that i found the solution to resolve this problem.
In fact, it was possible to create pure SPI conection for the sdcard.py driver to work at the same time the SPI ILIXXX driver.
I writed a specific sdcard.py version to do that :

from ili9XXX import ili9341
lcd = ili9341(mosi=23, miso=38, clk=18, dc=15, cs=5, invert=True, rot=0x10, width=320, height=240,
              rst=-1, power=-1, backlight=-1, half_duplex=False)

import sdcard
spi=sdcard.SPI(mosi=-1, miso=-1, clk=-1)
sd = sdcard.SDCard(spi, Pin(4))
os.mount(sd, "/sd")
print(os.listdir('/sd'))

maybe you would be interested in testing this?

reguard,
Thomas

@amirgon
Copy link
Collaborator

amirgon commented Oct 3, 2021

i'm happy to report you that i found the solution to resolve this problem.

That's great!

Could you open a PR on lv_binding_micropython to add your sdcard.py under driver/esp32/?

@favnec5
Copy link
Contributor

favnec5 commented Oct 4, 2021

Sure ! :-)

amirgon added a commit to lvgl/lv_micropython that referenced this issue Oct 20, 2021
Support some LVGL external libs. Related: lvgl/lv_binding_micropython#180

ESP32: Freeze lv_spi.py and sdcard.py. Related: lvgl/lv_binding_micropython#186, lvgl/lv_binding_micropython#69
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
stale This will not be worked on
Projects
None yet
Development

No branches or pull requests

3 participants