From 772a36098f1b30ce1a5988c84471c7caec98b119 Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Tue, 2 May 2023 12:44:05 +0200 Subject: [PATCH] mimxrt: Integrate support for WiFi via the CYW43 driver. This commit adds the necessary configuration and hooks to get the CYW43 driver working with the mimxrt port. Signed-off-by: iabdalkader --- ports/mimxrt/board_init.c | 1 + ports/mimxrt/cyw43_configport.h | 155 ++++++++++++++++++++++++++++++++ ports/mimxrt/machine_pin.c | 13 +++ ports/mimxrt/main.c | 14 +++ ports/mimxrt/mpconfigport.h | 8 ++ ports/mimxrt/mpnetworkport.c | 15 ++++ ports/mimxrt/pendsv.h | 3 + 7 files changed, 209 insertions(+) create mode 100644 ports/mimxrt/cyw43_configport.h diff --git a/ports/mimxrt/board_init.c b/ports/mimxrt/board_init.c index 78001862f0..9222b302b2 100644 --- a/ports/mimxrt/board_init.c +++ b/ports/mimxrt/board_init.c @@ -63,6 +63,7 @@ void board_init(void) { // 1ms tick timer SysTick_Config(SystemCoreClock / 1000); + NVIC_SetPriority(SysTick_IRQn, NVIC_EncodePriority(NVIC_PRIORITYGROUP_4, 0, 0)); // USB0 usb_phy0_init(0b0111, 0b0110, 0b0110); // Configure nominal values for D_CAL and TXCAL45DP/DN diff --git a/ports/mimxrt/cyw43_configport.h b/ports/mimxrt/cyw43_configport.h new file mode 100644 index 0000000000..5f96856474 --- /dev/null +++ b/ports/mimxrt/cyw43_configport.h @@ -0,0 +1,155 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 Damien P. George + * Copyright (c) 2022 Jim Mussared + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#ifndef MICROPY_INCLUDED_STM32_CYW43_CONFIGPORT_H +#define MICROPY_INCLUDED_STM32_CYW43_CONFIGPORT_H + +// The board-level config will be included here, so it can set some CYW43 values. +#include "py/mpconfig.h" +#include "py/mperrno.h" +#include "py/mphal.h" +#include "extmod/modnetwork.h" +#include "pendsv.h" +#include "sdio.h" + +#define CYW43_USE_SPI (0) +#define CYW43_LWIP (1) +#define CYW43_USE_STATS (0) + +#ifndef CYW43_CHIPSET_FIRMWARE_INCLUDE_FILE +#define CYW43_CHIPSET_FIRMWARE_INCLUDE_FILE "lib/cyw43-driver/firmware/w4343WA1_7_45_98_50_combined.h" +#endif + +#ifndef CYW43_WIFI_NVRAM_INCLUDE_FILE +#define CYW43_WIFI_NVRAM_INCLUDE_FILE "lib/cyw43-driver/firmware/wifi_nvram_1dx.h" +#endif + +#define CYW43_IOCTL_TIMEOUT_US (1000000) +#define CYW43_SLEEP_MAX (50) +#define CYW43_NETUTILS (1) +#define CYW43_CLEAR_SDIO_INT (1) + +#define CYW43_EPERM MP_EPERM // Operation not permitted +#define CYW43_EIO MP_EIO // I/O error +#define CYW43_EINVAL MP_EINVAL // Invalid argument +#define CYW43_ETIMEDOUT MP_ETIMEDOUT // Connection timed out + +#define CYW43_THREAD_ENTER MICROPY_PY_LWIP_ENTER +#define CYW43_THREAD_EXIT MICROPY_PY_LWIP_EXIT +#define CYW43_THREAD_LOCK_CHECK + +#define CYW43_HOST_NAME mod_network_hostname + +#define CYW43_SDPCM_SEND_COMMON_WAIT __WFI(); +#define CYW43_DO_IOCTL_WAIT __WFI(); + +#define CYW43_ARRAY_SIZE(a) MP_ARRAY_SIZE(a) + +#define CYW43_HAL_PIN_MODE_INPUT MP_HAL_PIN_MODE_INPUT +#define CYW43_HAL_PIN_MODE_OUTPUT MP_HAL_PIN_MODE_OUTPUT +#define CYW43_HAL_PIN_PULL_NONE MP_HAL_PIN_PULL_NONE +#define CYW43_HAL_PIN_PULL_UP MP_HAL_PIN_PULL_UP +#define CYW43_HAL_PIN_PULL_DOWN MP_HAL_PIN_PULL_DOWN + +#define CYW43_HAL_MAC_WLAN0 MP_HAL_MAC_WLAN0 + +#define cyw43_hal_ticks_us mp_hal_ticks_us +#define cyw43_hal_ticks_ms mp_hal_ticks_ms + +#define cyw43_hal_pin_obj_t mp_hal_pin_obj_t +#define cyw43_hal_pin_read mp_hal_pin_read +#define cyw43_hal_pin_low mp_hal_pin_low +#define cyw43_hal_pin_high mp_hal_pin_high + +#define cyw43_hal_get_mac mp_hal_get_mac +#define cyw43_hal_get_mac_ascii mp_hal_get_mac_ascii +#define cyw43_hal_generate_laa_mac mp_hal_generate_laa_mac + +#define cyw43_delay_us mp_hal_delay_us +#define cyw43_delay_ms mp_hal_delay_ms + +#define CYW43_PIN_WL_REG_ON MICROPY_HW_WL_REG_ON +#define CYW43_PIN_WL_HOST_WAKE MICROPY_HW_WL_HOST_WAKE +#define CYW43_PIN_WL_SDIO_1 MICROPY_HW_SDIO_D1 + +#define CYW43_PIN_BT_REG_ON MICROPY_HW_BT_REG_ON +#ifdef MICROPY_HW_BT_HOST_WAKE +#define CYW43_PIN_BT_HOST_WAKE MICROPY_HW_BT_HOST_WAKE +#endif +#ifdef MICROPY_HW_BT_DEV_WAKE +#define CYW43_PIN_BT_DEV_WAKE MICROPY_HW_BT_DEV_WAKE +#endif +#ifdef MICROPY_HW_BT_CTS +#define CYW43_PIN_BT_CTS MICROPY_HW_BT_CTS +#endif + +#if MICROPY_HW_ENABLE_RF_SWITCH +#define CYW43_PIN_WL_RFSW_VDD pin_WL_RFSW_VDD +#endif + +#define cyw43_schedule_internal_poll_dispatch(func) pendsv_schedule_dispatch(PENDSV_DISPATCH_CYW43, func) + +static inline void cyw43_hal_pin_config(cyw43_hal_pin_obj_t pin, uint8_t mode, uint8_t pull, uint8_t alt) { + machine_pin_set_mode(pin, mode); +} + +static inline void cyw43_hal_pin_config_irq_falling(cyw43_hal_pin_obj_t pin, int enable) { + if (enable) { + machine_pin_config(pin, PIN_MODE_IT_FALLING, PIN_PULL_UP_100K, 0, 0, PIN_AF_MODE_ALT5); + } +} + +static inline void cyw43_sdio_init(void) { + sdio_init(NVIC_EncodePriority(NVIC_PRIORITYGROUP_4, 14, 0)); +} + +static inline void cyw43_sdio_reinit(void) { + sdio_reenable(); +} + +static inline void cyw43_sdio_deinit(void) { + sdio_deinit(); +} + +static inline void cyw43_sdio_set_irq(bool enable) { + sdio_enable_irq(enable); +} + +static inline void cyw43_sdio_enable_high_speed_4bit(void) { + sdio_enable_high_speed_4bit(); +} + +static inline int cyw43_sdio_transfer(uint32_t cmd, uint32_t arg, uint32_t *resp) { + return sdio_transfer(cmd, arg, resp); +} + +static inline int cyw43_sdio_transfer_cmd53(bool write, uint32_t block_size, uint32_t arg, size_t len, uint8_t *buf) { + return sdio_transfer_cmd53(write, block_size, arg, len, buf); +} + +#define CYW43_EVENT_POLL_HOOK MICROPY_EVENT_POLL_HOOK + +#endif // MICROPY_INCLUDED_STM32_CYW43_CONFIGPORT_H diff --git a/ports/mimxrt/machine_pin.c b/ports/mimxrt/machine_pin.c index 5dfb2b72e2..3ebccb1755 100644 --- a/ports/mimxrt/machine_pin.c +++ b/ports/mimxrt/machine_pin.c @@ -34,6 +34,9 @@ #include "shared/runtime/mpirq.h" #include "extmod/virtpin.h" #include "pin.h" +#if MICROPY_PY_NETWORK_CYW43 +#include "pendsv.h" +#endif // Local functions STATIC mp_obj_t machine_pin_obj_init_helper(const machine_pin_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args); @@ -98,6 +101,16 @@ void call_handler(GPIO_Type *gpio, int gpio_nr, int pin) { if (isr & mask) { gpio->ISR = mask; // clear the ISR flag int index = GET_PIN_IRQ_INDEX(gpio_nr, pin); + #if MICROPY_PY_NETWORK_CYW43 + extern void (*cyw43_poll)(void); + const machine_pin_obj_t *pin = MICROPY_HW_WL_HOST_WAKE; + if (pin->gpio == gpio && pin->pin == (index % 32)) { + if (cyw43_poll) { + pendsv_schedule_dispatch(PENDSV_DISPATCH_CYW43, cyw43_poll); + } + return; + } + #endif machine_pin_irq_obj_t *irq = MP_STATE_PORT(machine_pin_irq_objects[index]); if (irq != NULL) { irq->flags = irq->trigger; diff --git a/ports/mimxrt/main.c b/ports/mimxrt/main.c index 2d0760964c..8deaa54275 100644 --- a/ports/mimxrt/main.c +++ b/ports/mimxrt/main.c @@ -43,6 +43,9 @@ #if MICROPY_PY_LWIP #include "lwip/init.h" #include "lwip/apps/mdns.h" +#if MICROPY_PY_NETWORK_CYW43 +#include "lib/cyw43-driver/src/cyw43.h" +#endif #endif #include "systick.h" #include "extmod/modnetwork.h" @@ -69,6 +72,17 @@ int main(void) { systick_enable_dispatch(SYSTICK_DISPATCH_LWIP, mod_network_lwip_poll_wrapper); #endif + #if MICROPY_PY_NETWORK_CYW43 + { + cyw43_init(&cyw43_state); + uint8_t buf[8]; + memcpy(&buf[0], "PYBD", 4); + mp_hal_get_mac_ascii(MP_HAL_MAC_WLAN0, 8, 4, (char *)&buf[4]); + cyw43_wifi_ap_set_ssid(&cyw43_state, 8, buf); + cyw43_wifi_ap_set_password(&cyw43_state, 8, (const uint8_t *)"pybd0123"); + } + #endif + for (;;) { #if defined(MICROPY_HW_LED1) led_init(); diff --git a/ports/mimxrt/mpconfigport.h b/ports/mimxrt/mpconfigport.h index cd69151ed8..eb5c3450b3 100644 --- a/ports/mimxrt/mpconfigport.h +++ b/ports/mimxrt/mpconfigport.h @@ -170,12 +170,20 @@ extern const struct _mp_obj_type_t network_lan_type; #define MICROPY_HW_NIC_ETH #endif +#if MICROPY_PY_NETWORK_CYW43 +extern const struct _mp_obj_type_t mp_network_cyw43_type; +#define MICROPY_HW_NIC_CYW43 { MP_ROM_QSTR(MP_QSTR_WLAN), MP_ROM_PTR(&mp_network_cyw43_type) }, +#else +#define MICROPY_HW_NIC_CYW43 +#endif + #ifndef MICROPY_BOARD_NETWORK_INTERFACES #define MICROPY_BOARD_NETWORK_INTERFACES #endif #define MICROPY_PORT_NETWORK_INTERFACES \ MICROPY_HW_NIC_ETH \ + MICROPY_HW_NIC_CYW43 \ MICROPY_BOARD_NETWORK_INTERFACES \ #ifndef MICROPY_BOARD_ROOT_POINTERS diff --git a/ports/mimxrt/mpnetworkport.c b/ports/mimxrt/mpnetworkport.c index 2e6a49b90e..2ca3426197 100644 --- a/ports/mimxrt/mpnetworkport.c +++ b/ports/mimxrt/mpnetworkport.c @@ -43,6 +43,11 @@ #include "lwip/dhcp.h" #include "lwip/apps/mdns.h" +#if MICROPY_PY_NETWORK_CYW43 +#include "extmod/network_cyw43.h" +#include "lib/cyw43-driver/src/cyw43.h" +#endif + // Poll lwIP every 128ms #define LWIP_TICK(tick) (((tick) & ~(SYSTICK_DISPATCH_NUM_SLOTS - 1) & 0x7f) == 0) @@ -59,6 +64,16 @@ void mod_network_lwip_poll_wrapper(uint32_t ticks_ms) { if (LWIP_TICK(ticks_ms)) { pendsv_schedule_dispatch(PENDSV_DISPATCH_LWIP, pyb_lwip_poll); } + + #if MICROPY_PY_NETWORK_CYW43 + if (cyw43_poll) { + if (cyw43_sleep != 0) { + if (--cyw43_sleep == 0) { + pendsv_schedule_dispatch(PENDSV_DISPATCH_CYW43, cyw43_poll); + } + } + } + #endif } #endif // MICROPY_PY_LWIP diff --git a/ports/mimxrt/pendsv.h b/ports/mimxrt/pendsv.h index e68f487fb4..f3369b07fe 100644 --- a/ports/mimxrt/pendsv.h +++ b/ports/mimxrt/pendsv.h @@ -31,6 +31,9 @@ enum { #if MICROPY_PY_NETWORK && MICROPY_PY_LWIP PENDSV_DISPATCH_LWIP, #endif + #if MICROPY_PY_NETWORK_CYW43 + PENDSV_DISPATCH_CYW43, + #endif MICROPY_BOARD_PENDSV_ENTRIES PENDSV_DISPATCH_MAX };