From 379b583b2fbff7772884f199ddb0d70fb8b86090 Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Wed, 20 Sep 2023 14:41:01 +0200 Subject: [PATCH] drivers/esp_hosted: Fix pin IRQ. This patch reinstalls the pin IRQ handler on WiFi init, as some ports disable/remove pin IRQs on soft-reboot, or deinit the pins. Signed-off-by: iabdalkader --- drivers/esp-hosted/esp_hosted_hal.c | 86 ++++++++++++++---------- drivers/esp-hosted/esp_hosted_hal.h | 1 + drivers/esp-hosted/esp_hosted_internal.h | 2 - drivers/esp-hosted/esp_hosted_wifi.c | 4 ++ 4 files changed, 55 insertions(+), 38 deletions(-) diff --git a/drivers/esp-hosted/esp_hosted_hal.c b/drivers/esp-hosted/esp_hosted_hal.c index d8e2e6ece4..85cacc0a1b 100644 --- a/drivers/esp-hosted/esp_hosted_hal.c +++ b/drivers/esp-hosted/esp_hosted_hal.c @@ -41,12 +41,9 @@ #include "esp_hosted_hal.h" #include "esp_hosted_wifi.h" -#ifndef MICROPY_HW_WIFI_IRQ -#define MICROPY_HW_WIFI_IRQ MICROPY_HW_WIFI_HANDSHAKE -#endif +extern void mod_network_poll_events(void); STATIC mp_obj_t esp_hosted_pin_irq_callback(mp_obj_t self_in) { - extern void mod_network_poll_events(void); mod_network_poll_events(); return mp_const_none; } @@ -64,34 +61,16 @@ MP_WEAK int esp_hosted_hal_init(uint32_t mode) { mp_hal_pin_input(MICROPY_HW_WIFI_HANDSHAKE); mp_hal_pin_input(MICROPY_HW_WIFI_DATAREADY); - // Enable Pin-IRQ for the handshake PIN to call esp_hosted_wifi_poll() - mp_obj_t irq_rising_attr[2]; - mp_load_method_maybe((mp_obj_t)MICROPY_HW_WIFI_IRQ, MP_QSTR_IRQ_RISING, irq_rising_attr); - - if (irq_rising_attr[0] != MP_OBJ_NULL && irq_rising_attr[1] == MP_OBJ_NULL) { // value for IRQ rising found - mp_obj_t pin_args[] = { - NULL, // Method pointer - (mp_obj_t)MICROPY_HW_WIFI_IRQ, // Pin object - (mp_obj_t)&esp_hosted_pin_irq_callback_obj, // Callback function object - NULL, // The Rising edge value is set below. - mp_const_true, // Hard IRQ, since the actual polling is scheduled. - }; - pin_args[3] = irq_rising_attr[0]; - mp_load_method_maybe((mp_obj_t)MICROPY_HW_WIFI_IRQ, MP_QSTR_irq, pin_args); - if (pin_args[0] != MP_OBJ_NULL && pin_args[1] != MP_OBJ_NULL) { - mp_call_method_n_kw(3, 0, pin_args); - } - } - // Initialize SPI. mp_obj_t args[] = { MP_OBJ_NEW_SMALL_INT(MICROPY_HW_WIFI_SPI_ID), MP_OBJ_NEW_SMALL_INT(MICROPY_HW_WIFI_SPI_BAUDRATE), + MP_OBJ_NEW_QSTR(MP_QSTR_phase), MP_OBJ_NEW_SMALL_INT(0), MP_OBJ_NEW_QSTR(MP_QSTR_polarity), MP_OBJ_NEW_SMALL_INT(1), }; MP_STATE_PORT(mp_wifi_spi) = - MP_OBJ_TYPE_GET_SLOT(&machine_spi_type, make_new)((mp_obj_t)&machine_spi_type, 2, 1, args); + MP_OBJ_TYPE_GET_SLOT(&machine_spi_type, make_new)((mp_obj_t)&machine_spi_type, 2, 2, args); // SPI might change the direction/mode of CS pin, // set it to GPIO again just in case. @@ -101,16 +80,8 @@ MP_WEAK int esp_hosted_hal_init(uint32_t mode) { } MP_WEAK int esp_hosted_hal_deinit(void) { - // Disable Pin-IRQ for the handshake PIN - mp_obj_t pin_args[] = { - NULL, // Method pointer - (mp_obj_t)MICROPY_HW_WIFI_IRQ, // Pin object - mp_const_none // Set to None - }; - mp_load_method_maybe((mp_obj_t)MICROPY_HW_WIFI_IRQ, MP_QSTR_irq, pin_args); - if (pin_args[0] && pin_args[1]) { - mp_call_method_n_kw(1, 0, pin_args); - } + // Disable pin IRQ. + esp_hosted_hal_irq_enable(false); // Remove all network interfaces and reset wifi state. esp_hosted_wifi_deinit(); @@ -134,6 +105,43 @@ MP_WEAK int esp_hosted_hal_deinit(void) { return 0; } +MP_WEAK void esp_hosted_hal_irq_enable(bool enable) { + #ifdef MICROPY_HW_WIFI_IRQ_PIN + // Disable Pin-IRQ for the handshake PIN + mp_obj_t pin_args[] = { + NULL, // Method pointer + (mp_obj_t)MICROPY_HW_WIFI_IRQ_PIN, // Pin object + mp_const_none // Set to None + }; + mp_load_method_maybe((mp_obj_t)MICROPY_HW_WIFI_IRQ_PIN, MP_QSTR_irq, pin_args); + if (pin_args[0] && pin_args[1]) { + mp_call_method_n_kw(1, 0, pin_args); + } + + if (enable) { + // Enable Pin-IRQ for the handshake PIN to call esp_hosted_wifi_poll() + mp_obj_t irq_rising_attr[2]; + mp_load_method_maybe((mp_obj_t)MICROPY_HW_WIFI_IRQ_PIN, MP_QSTR_IRQ_RISING, irq_rising_attr); + + if (irq_rising_attr[0] != MP_OBJ_NULL && irq_rising_attr[1] == MP_OBJ_NULL) { + // value for IRQ rising found + mp_obj_t pin_args[] = { + NULL, // Method pointer + (mp_obj_t)MICROPY_HW_WIFI_IRQ_PIN, // Pin object + (mp_obj_t)&esp_hosted_pin_irq_callback_obj, // Callback function object + NULL, // The Rising edge value is set below. + mp_const_true, // Hard IRQ, since the actual polling is scheduled. + }; + pin_args[3] = irq_rising_attr[0]; + mp_load_method_maybe((mp_obj_t)MICROPY_HW_WIFI_IRQ_PIN, MP_QSTR_irq, pin_args); + if (pin_args[0] != MP_OBJ_NULL && pin_args[1] != MP_OBJ_NULL) { + mp_call_method_n_kw(3, 0, pin_args); + } + } + } + #endif +} + MP_WEAK int esp_hosted_hal_atomic_enter(void) { #if MICROPY_ENABLE_SCHEDULER mp_sched_lock(); @@ -149,7 +157,7 @@ MP_WEAK int esp_hosted_hal_atomic_exit(void) { } MP_WEAK bool esp_hosted_hal_data_ready(void) { - return mp_hal_pin_read(MICROPY_HW_WIFI_DATAREADY) && mp_hal_pin_read(MICROPY_HW_WIFI_HANDSHAKE); + return mp_hal_pin_read(MICROPY_HW_WIFI_DATAREADY); } MP_WEAK int esp_hosted_hal_spi_transfer(const uint8_t *tx_buf, uint8_t *rx_buf, uint32_t size) { @@ -158,7 +166,8 @@ MP_WEAK int esp_hosted_hal_spi_transfer(const uint8_t *tx_buf, uint8_t *rx_buf, // Wait for handshake pin to go high. for (mp_uint_t start = mp_hal_ticks_ms(); ; mp_hal_delay_ms(1)) { - if (mp_hal_pin_read(MICROPY_HW_WIFI_HANDSHAKE)) { + if (mp_hal_pin_read(MICROPY_HW_WIFI_HANDSHAKE) && + (rx_buf == NULL || mp_hal_pin_read(MICROPY_HW_WIFI_DATAREADY))) { break; } if ((mp_hal_ticks_ms() - start) >= 1000) { @@ -171,6 +180,11 @@ MP_WEAK int esp_hosted_hal_spi_transfer(const uint8_t *tx_buf, uint8_t *rx_buf, mp_hal_delay_us(10); spi_proto->transfer(mp_wifi_spi, size, tx_buf, rx_buf); mp_hal_pin_write(MICROPY_HW_WIFI_SPI_CS, 1); + mp_hal_delay_us(100); + + if (esp_hosted_hal_data_ready()) { + mod_network_poll_events(); + } return 0; } diff --git a/drivers/esp-hosted/esp_hosted_hal.h b/drivers/esp-hosted/esp_hosted_hal.h index abf060c893..0bc7db9282 100644 --- a/drivers/esp-hosted/esp_hosted_hal.h +++ b/drivers/esp-hosted/esp_hosted_hal.h @@ -68,6 +68,7 @@ typedef enum { // Note A default machine-based implementation is provided in esp_hosted_hal.c. int esp_hosted_hal_init(uint32_t mode); int esp_hosted_hal_deinit(void); +void esp_hosted_hal_irq_enable(bool enable); bool esp_hosted_hal_data_ready(void); int esp_hosted_hal_atomic_enter(void); int esp_hosted_hal_atomic_exit(void); diff --git a/drivers/esp-hosted/esp_hosted_internal.h b/drivers/esp-hosted/esp_hosted_internal.h index f57cd210a1..ff8377e674 100644 --- a/drivers/esp-hosted/esp_hosted_internal.h +++ b/drivers/esp-hosted/esp_hosted_internal.h @@ -29,8 +29,6 @@ #ifndef MICROPY_INCLUDED_DRIVERS_ESP_HOSTED_INTERNAL_H #define MICROPY_INCLUDED_DRIVERS_ESP_HOSTED_INTERNAL_H -#define ESP_HOSTED_DEBUG (0) - #define ESP_FRAME_MAX_SIZE (1600) #define ESP_FRAME_MAX_PAYLOAD (ESP_FRAME_MAX_SIZE - sizeof(esp_header_t)) #define ESP_FRAME_FLAGS_FRAGMENT (1 << 0) diff --git a/drivers/esp-hosted/esp_hosted_wifi.c b/drivers/esp-hosted/esp_hosted_wifi.c index 3cc153205c..d1b6333aa0 100644 --- a/drivers/esp-hosted/esp_hosted_wifi.c +++ b/drivers/esp-hosted/esp_hosted_wifi.c @@ -476,6 +476,10 @@ int esp_hosted_wifi_init(uint32_t itf) { esp_hosted_netif_init(&esp_state, itf); info_printf("esp_hosted_init() initialized itf %lu\n", itf); } + + // Re/enable IRQ pin. + esp_hosted_hal_irq_enable(true); + return 0; }