diff --git a/drivers/cyw43/cyw43.h b/drivers/cyw43/cyw43.h deleted file mode 100644 index 5ca4898318..0000000000 --- a/drivers/cyw43/cyw43.h +++ /dev/null @@ -1,144 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2018-2019 Damien P. George - * - * 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_H -#define MICROPY_INCLUDED_STM32_CYW43_H - -#include "lwip/netif.h" -#include "lwip/dhcp.h" -#include "shared/netutils/dhcpserver.h" -#include "drivers/cyw43/cyw43_ll.h" - -// For trace_flags -#define CYW43_TRACE_ASYNC_EV (0x0001) -#define CYW43_TRACE_ETH_TX (0x0002) -#define CYW43_TRACE_ETH_RX (0x0004) -#define CYW43_TRACE_ETH_FULL (0x0008) -#define CYW43_TRACE_MAC (0x0010) - -// Return value of cyw43_wifi_link_status -#define CYW43_LINK_DOWN (0) -#define CYW43_LINK_JOIN (1) -#define CYW43_LINK_NOIP (2) -#define CYW43_LINK_UP (3) -#define CYW43_LINK_FAIL (-1) -#define CYW43_LINK_NONET (-2) -#define CYW43_LINK_BADAUTH (-3) - -#ifndef MICROPY_BOARD_HOSTNAME -#define MICROPY_BOARD_HOSTNAME "PYBD" -#endif - -#ifndef MICROPY_BOARD_HOSTNAME_LENGTH -#define MICROPY_BOARD_HOSTNAME_LENGTH 16 -#endif - -typedef struct _cyw43_t { - cyw43_ll_t cyw43_ll; - - uint8_t itf_state; - uint32_t trace_flags; - - // State for async events - volatile uint32_t wifi_scan_state; - uint32_t wifi_join_state; - void *wifi_scan_env; - int (*wifi_scan_cb)(void*, const cyw43_ev_scan_result_t*); - - // Pending things to do - bool pend_disassoc; - bool pend_rejoin; - bool pend_rejoin_wpa; - - // AP settings - uint8_t ap_channel; - uint8_t ap_auth; - uint8_t ap_ssid_len; - uint8_t ap_key_len; - uint8_t ap_ssid[32]; - uint8_t ap_key[64]; - - // lwIP data - struct netif netif[2]; - struct dhcp dhcp_client; - dhcp_server_t dhcp_server; - char hostname[MICROPY_BOARD_HOSTNAME_LENGTH]; -} cyw43_t; - -extern cyw43_t cyw43_state; -extern void (*cyw43_poll)(void); -extern uint32_t cyw43_sleep; - -void cyw43_init(cyw43_t *self); -void cyw43_deinit(cyw43_t *self); - -int cyw43_ioctl(cyw43_t *self, uint32_t cmd, size_t len, uint8_t *buf, uint32_t iface); -int cyw43_send_ethernet(cyw43_t *self, int itf, size_t len, const void *buf, bool is_pbuf); - -int cyw43_wifi_pm(cyw43_t *self, uint32_t pm); -int cyw43_wifi_link_status(cyw43_t *self, int itf); -void cyw43_wifi_set_up(cyw43_t *self, int itf, bool up); -int cyw43_wifi_get_mac(cyw43_t *self, int itf, uint8_t mac[6]); -int cyw43_wifi_scan(cyw43_t *self, cyw43_wifi_scan_options_t *opts, void *env, int (*result_cb)(void*, const cyw43_ev_scan_result_t*)); - -static inline bool cyw43_wifi_scan_active(cyw43_t *self) { - return self->wifi_scan_state == 1; -} - -int cyw43_wifi_join(cyw43_t *self, size_t ssid_len, const uint8_t *ssid, size_t key_len, const uint8_t *key, uint32_t auth_type, const uint8_t *bssid, uint32_t channel); -int cyw43_wifi_leave(cyw43_t *self, int itf); - -static inline void cyw43_wifi_ap_get_ssid(cyw43_t *self, size_t *len, const uint8_t **buf) { - *len = self->ap_ssid_len; - *buf = self->ap_ssid; -} - -static inline void cyw43_wifi_ap_set_channel(cyw43_t *self, uint32_t channel) { - self->ap_channel = channel; -} - -static inline void cyw43_wifi_ap_set_ssid(cyw43_t *self, size_t len, const uint8_t *buf) { - self->ap_ssid_len = MIN(len, sizeof(self->ap_ssid)); - memcpy(self->ap_ssid, buf, self->ap_ssid_len); -} - -static inline void cyw43_wifi_ap_set_password(cyw43_t *self, size_t len, const uint8_t *buf) { - self->ap_key_len = MIN(len, sizeof(self->ap_key)); - memcpy(self->ap_key, buf, self->ap_key_len); -} - -static inline void cyw43_wifi_ap_set_auth(cyw43_t *self, uint32_t auth) { - self->ap_auth = auth; -} - -void cyw43_wifi_ap_get_stas(cyw43_t *self, int *num_stas, uint8_t *macs); - -void cyw43_tcpip_init(cyw43_t *self, int itf); -void cyw43_tcpip_deinit(cyw43_t *self, int itf); -void cyw43_tcpip_set_link_up(cyw43_t *self, int itf); -void cyw43_tcpip_set_link_down(cyw43_t *self, int itf); -int cyw43_tcpip_link_status(cyw43_t *self, int itf); - -#endif // MICROPY_INCLUDED_STM32_CYW43_H diff --git a/drivers/cyw43/cyw43_ctrl.c b/drivers/cyw43/cyw43_ctrl.c deleted file mode 100644 index 73e6e58957..0000000000 --- a/drivers/cyw43/cyw43_ctrl.c +++ /dev/null @@ -1,595 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2018-2019 Damien P. George - * - * 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. - */ - -#include -#include - -#include "py/mperrno.h" -#include "py/mphal.h" -#include "drivers/cyw43/cyw43.h" -#include "pendsv.h" -#include "sdio.h" - -#define CYW_ENTER MICROPY_PY_LWIP_ENTER -#define CYW_EXIT MICROPY_PY_LWIP_EXIT - -#ifdef pyb_pin_WL_HOST_WAKE -#define USE_SDIOIT (0) -#else -#define USE_SDIOIT (1) -#endif - -#define CYW43_SLEEP_MAX (50) - -#define WIFI_JOIN_STATE_ACTIVE (0x0001) -#define WIFI_JOIN_STATE_FAIL (0x0002) -#define WIFI_JOIN_STATE_NONET (0x0003) -#define WIFI_JOIN_STATE_BADAUTH (0x0004) -#define WIFI_JOIN_STATE_AUTH (0x0200) -#define WIFI_JOIN_STATE_LINK (0x0400) -#define WIFI_JOIN_STATE_KEYED (0x0800) -#define WIFI_JOIN_STATE_ALL (0x0e01) - -#define CYW43_STA_IS_ACTIVE(self) (((self)->itf_state >> CYW43_ITF_STA) & 1) -#define CYW43_AP_IS_ACTIVE(self) (((self)->itf_state >> CYW43_ITF_AP) & 1) - -cyw43_t cyw43_state; -void (*cyw43_poll)(void); -uint32_t cyw43_sleep; - -STATIC void cyw43_poll_func(void); -STATIC void cyw43_wifi_ap_init(cyw43_t *self); -STATIC void cyw43_wifi_ap_set_up(cyw43_t *self, bool up); - -static inline uint32_t cyw43_get_be16(const uint8_t *buf) { - return buf[0] << 8 | buf[1]; -} - -static inline uint32_t cyw43_get_be32(const uint8_t *buf) { - return buf[0] << 24 | buf[1] << 16 | buf[2] << 8 | buf[3]; -} - -static inline void cyw43_delay_ms(uint32_t ms) { - mp_hal_delay_ms(ms); -} - -/*******************************************************************************/ -// Initialisation and polling - -void cyw43_init(cyw43_t *self) { - #ifdef pyb_pin_WL_HOST_WAKE - mp_hal_pin_config(pyb_pin_WL_HOST_WAKE, MP_HAL_PIN_MODE_INPUT, MP_HAL_PIN_PULL_NONE, 0); - #endif - mp_hal_pin_config(pyb_pin_WL_REG_ON, MP_HAL_PIN_MODE_OUTPUT, MP_HAL_PIN_PULL_NONE, 0); - mp_hal_pin_low(pyb_pin_WL_REG_ON); - #ifdef pyb_pin_WL_RFSW_VDD - mp_hal_pin_config(pyb_pin_WL_RFSW_VDD, MP_HAL_PIN_MODE_OUTPUT, MP_HAL_PIN_PULL_NONE, 0); // RF-switch power - mp_hal_pin_low(pyb_pin_WL_RFSW_VDD); - #endif - - cyw43_ll_init(&self->cyw43_ll, self); - - self->itf_state = 0; - self->wifi_scan_state = 0; - self->wifi_join_state = 0; - self->pend_disassoc = false; - self->pend_rejoin= false; - self->pend_rejoin_wpa = false; - self->ap_channel = 3; - self->ap_ssid_len = 0; - self->ap_key_len = 0; - strncpy(self->hostname, MICROPY_BOARD_HOSTNAME, MICROPY_BOARD_HOSTNAME_LENGTH); - self->hostname[MICROPY_BOARD_HOSTNAME_LENGTH - 1] = 0; - - cyw43_poll = NULL; -} - -void cyw43_deinit(cyw43_t *self) { - if (cyw43_poll == NULL) { - return; - } - - CYW_ENTER - - // Stop the TCP/IP network interfaces. - cyw43_tcpip_deinit(self, 0); - cyw43_tcpip_deinit(self, 1); - - // Turn off the SDIO bus. - #if USE_SDIOIT - sdio_enable_irq(false); - #endif - sdio_deinit(); - - // Power off the WLAN chip and make sure all state is reset. - cyw43_init(self); - - CYW_EXIT -} - -STATIC int cyw43_ensure_up(cyw43_t *self) { - if (cyw43_poll != NULL) { - cyw43_ll_bus_sleep(&self->cyw43_ll, false); - return 0; - } - - CYW_ENTER - - // Disable the netif if it was previously up - cyw43_tcpip_deinit(self, CYW43_ITF_STA); - cyw43_tcpip_deinit(self, CYW43_ITF_AP); - self->itf_state = 0; - - // Reset and power up the WL chip - mp_hal_pin_low(pyb_pin_WL_REG_ON); - cyw43_delay_ms(20); - mp_hal_pin_high(pyb_pin_WL_REG_ON); - cyw43_delay_ms(50); - - // Initialise SDIO bus - // IRQ priority only needs to be higher than CYW_ENTER/EXIT protection (PENDSV) - sdio_init(NVIC_EncodePriority(NVIC_PRIORITYGROUP_4, 14, 0)); - - // Initialise the low-level driver - uint8_t mac[6]; - mp_hal_get_mac(MP_HAL_MAC_WLAN0, mac); - int ret = cyw43_ll_bus_init(&self->cyw43_ll, mac); - - if (ret != 0) { - CYW_EXIT - return ret; - } - - // Enable async events from low-level driver - cyw43_sleep = CYW43_SLEEP_MAX; - cyw43_poll = cyw43_poll_func; - #if USE_SDIOIT - sdio_enable_irq(true); - #else - extern void extint_set(const pin_obj_t *pin, uint32_t mode); - extint_set(pyb_pin_WL_HOST_WAKE, GPIO_MODE_IT_FALLING); - #endif - - CYW_EXIT - - return ret; -} - -// This function must always be executed at the level where CYW_ENTER is effectively active -STATIC void cyw43_poll_func(void) { - if (cyw43_poll == NULL) { - // Poll scheduled during deinit, just ignore it - return; - } - - cyw43_t *self = &cyw43_state; - cyw43_ll_process_packets(&self->cyw43_ll); - - if (self->pend_disassoc) { - self->pend_disassoc = false; - cyw43_ll_ioctl(&self->cyw43_ll, CYW43_IOCTL_SET_DISASSOC, 0, NULL, CYW43_ITF_STA); - } - - if (self->pend_rejoin_wpa) { - self->pend_rejoin_wpa = false; - cyw43_ll_wifi_set_wpa_auth(&self->cyw43_ll); - } - - if (self->pend_rejoin) { - self->pend_rejoin = false; - cyw43_ll_wifi_rejoin(&self->cyw43_ll); - self->wifi_join_state = WIFI_JOIN_STATE_ACTIVE; - } - - if (cyw43_sleep == 0) { - cyw43_ll_bus_sleep(&self->cyw43_ll, true); - #if !USE_SDIOIT - sdio_deinit(); // save power while WLAN bus sleeps - #endif - } - - #if USE_SDIOIT - sdio_enable_irq(true); - #endif -} - -/*******************************************************************************/ -// Callback interface to low-level driver - -int cyw43_cb_read_host_interrupt_pin(void *cb_data) { - #ifdef pyb_pin_WL_HOST_WAKE - return mp_hal_pin_read(pyb_pin_WL_HOST_WAKE); - #else - return mp_hal_pin_read(pyb_pin_WL_SDIO_1); - #endif -} - -void cyw43_cb_ensure_awake(void *cb_data) { - cyw43_sleep = CYW43_SLEEP_MAX; - #if !USE_SDIOIT - sdio_reenable(); - #endif -} - -STATIC const char *cyw43_async_event_name_table[89] = { - [0 ... 88] = NULL, - [CYW43_EV_SET_SSID] = "SET_SSID", - [CYW43_EV_JOIN] = "JOIN", - [CYW43_EV_AUTH] = "AUTH", - [CYW43_EV_DEAUTH_IND] = "DEAUTH_IND", - [CYW43_EV_ASSOC] = "ASSOC", - [CYW43_EV_DISASSOC] = "DISASSOC", - [CYW43_EV_DISASSOC_IND] = "DISASSOC_IND", - [CYW43_EV_LINK] = "LINK", - [CYW43_EV_PSK_SUP] = "PSK_SUP", - [CYW43_EV_ESCAN_RESULT] = "ESCAN_RESULT", - [CYW43_EV_CSA_COMPLETE_IND] = "CSA_COMPLETE_IND", - [CYW43_EV_ASSOC_REQ_IE] = "ASSOC_REQ_IE", - [CYW43_EV_ASSOC_RESP_IE] = "ASSOC_RESP_IE", -}; - -STATIC void cyw43_dump_async_event(const cyw43_async_event_t *ev) { - printf("[% 8d] ASYNC(%04x,", - (int)mp_hal_ticks_ms(), - (unsigned int)ev->flags - ); - if (ev->event_type < MP_ARRAY_SIZE(cyw43_async_event_name_table) - && cyw43_async_event_name_table[ev->event_type] != NULL) { - printf("%s", cyw43_async_event_name_table[ev->event_type]); - } else { - printf("%u", (unsigned int)ev->event_type); - } - printf(",%u,%u,%u)\n", - (unsigned int)ev->status, - (unsigned int)ev->reason, - (unsigned int)ev->interface - ); -} - -void cyw43_cb_process_async_event(void *cb_data, const cyw43_async_event_t *ev) { - cyw43_t *self = cb_data; - - if (self->trace_flags & CYW43_TRACE_ASYNC_EV) { - cyw43_dump_async_event(ev); - } - - if (ev->event_type == CYW43_EV_ESCAN_RESULT && self->wifi_scan_state == 1) { - // Escan result event - if (ev->status == 8) { - // Partial result - int ret = self->wifi_scan_cb(self->wifi_scan_env, &ev->u.scan_result); - if (ret != 0) { - // TODO need to abort scan, or just ignore any more results - } - } else if (ev->status == 0) { - // Scan complete - self->wifi_scan_state = 2; - } - - } else if (ev->event_type == CYW43_EV_DISASSOC) { - cyw43_tcpip_set_link_down(self, CYW43_ITF_STA); - self->wifi_join_state = 0x0000; - - /* - } else if (ev->event_type == CYW43_EV_DISASSOC_IND) { - if (ev->interface == CYW43_ITF_AP) { - // Station disassociated with our AP, let DHCP server know so it can free the IP address - dhcp_server_disassoc(&self->dhcp_server, buf + 24); - } - */ - - // WiFi join events - } else if (ev->event_type == CYW43_EV_PRUNE) { - if (ev->status == 0 && ev->reason == 8) { - // RSN mismatch, retry join with WPA auth - self->pend_rejoin = true; - self->pend_rejoin_wpa = true; - pendsv_schedule_dispatch(PENDSV_DISPATCH_CYW43, cyw43_poll_func); - } - } else if (ev->event_type == CYW43_EV_SET_SSID) { - if (ev->status == 0) { - // Success setting SSID - } else if (ev->status == 3 && ev->reason == 0) { - self->wifi_join_state = WIFI_JOIN_STATE_NONET; - // No matching SSID found (could be out of range, or down) - } else { - // Other failure setting SSID - self->wifi_join_state = WIFI_JOIN_STATE_FAIL; - } - } else if (ev->event_type == CYW43_EV_AUTH) { - if (ev->status == 0) { - self->wifi_join_state |= WIFI_JOIN_STATE_AUTH; - } else if (ev->status == 6) { - // Unsolicited auth packet, ignore it - } else { - // Cannot authenticate - self->wifi_join_state = WIFI_JOIN_STATE_BADAUTH; - } - } else if (ev->event_type == CYW43_EV_DEAUTH_IND) { - if (ev->status == 0 && ev->reason == 2) { - // Deauth, probably because password was wrong; disassociate - self->pend_disassoc = true; - pendsv_schedule_dispatch(PENDSV_DISPATCH_CYW43, cyw43_poll_func); - } - } else if (ev->event_type == CYW43_EV_LINK) { - if (ev->status == 0) { - if (ev->flags & 1) { - // Link is up - if (ev->interface == CYW43_ITF_STA) { - self->wifi_join_state |= WIFI_JOIN_STATE_LINK; - } else { - cyw43_tcpip_set_link_up(self, ev->interface); - } - } else { - // Link is down - cyw43_tcpip_set_link_down(self, ev->interface); - } - } - } else if (ev->event_type == CYW43_EV_PSK_SUP) { - if (ev->status == 6) { // WLC_SUP_KEYED - self->wifi_join_state |= WIFI_JOIN_STATE_KEYED; - } else if ((ev->status == 4 || ev->status == 8 || ev->status == 11) && ev->reason == 15) { - // Timeout waiting for key exchange M1/M3/G1 - // Probably at edge of the cell, retry - self->pend_rejoin = true; - pendsv_schedule_dispatch(PENDSV_DISPATCH_CYW43, cyw43_poll_func); - } else { - // PSK_SUP failure - self->wifi_join_state = WIFI_JOIN_STATE_BADAUTH; - } - } - - if (self->wifi_join_state == WIFI_JOIN_STATE_ALL) { - // STA connected - self->wifi_join_state = WIFI_JOIN_STATE_ACTIVE; - cyw43_tcpip_set_link_up(self, CYW43_ITF_STA); - } -} - -/*******************************************************************************/ -// Ioctl and Ethernet interface - -int cyw43_ioctl(cyw43_t *self, uint32_t cmd, size_t len, uint8_t *buf, uint32_t iface) { - int ret = cyw43_ensure_up(self); - if (ret) { - return ret; - } - - CYW_ENTER - ret = cyw43_ll_ioctl(&self->cyw43_ll, cmd, len, buf, iface); - CYW_EXIT - - return ret; -} - -int cyw43_send_ethernet(cyw43_t *self, int itf, size_t len, const void *buf, bool is_pbuf) { - int ret = cyw43_ensure_up(self); - if (ret) { - return ret; - } - - CYW_ENTER - ret = cyw43_ll_send_ethernet(&self->cyw43_ll, itf, len, buf, is_pbuf); - CYW_EXIT - - return ret; -} - -/*******************************************************************************/ -// WiFi control - -STATIC int cyw43_wifi_on(cyw43_t *self, uint32_t country) { - int ret = cyw43_ensure_up(self); - if (ret) { - return ret; - } - - #ifdef pyb_pin_WL_RFSW_VDD - // Turn the RF-switch on - mp_hal_pin_high(pyb_pin_WL_RFSW_VDD); - #endif - - CYW_ENTER - ret = cyw43_ll_wifi_on(&self->cyw43_ll, country); - CYW_EXIT - - return ret; -} - -int cyw43_wifi_pm(cyw43_t *self, uint32_t pm_in) { - int ret = cyw43_ensure_up(self); - if (ret) { - return ret; - } - - // pm_in: 0x00adbrrm - uint32_t pm = pm_in & 0xf; - uint32_t pm_sleep_ret = (pm_in >> 4) & 0xff; - uint32_t li_bcn = (pm_in >> 12) & 0xf; - uint32_t li_dtim = (pm_in >> 16) & 0xf; - uint32_t li_assoc = (pm_in >> 20) & 0xf; - - CYW_ENTER - ret = cyw43_ll_wifi_pm(&self->cyw43_ll, pm, pm_sleep_ret, li_bcn, li_dtim, li_assoc); - CYW_EXIT - - return ret; -} - -int cyw43_wifi_get_mac(cyw43_t *self, int itf, uint8_t mac[6]) { - mp_hal_get_mac(MP_HAL_MAC_WLAN0, &mac[0]); - return 0; -} - -#define MAKE_COUNTRY(a, b, rev) ((a) | (b) << 8 | (rev) << 16) - -void cyw43_wifi_set_up(cyw43_t *self, int itf, bool up) { - if (up) { - if (self->itf_state == 0) { - uint32_t country; - extern char pyb_country_code[2]; - if (pyb_country_code[0] == '\0' || pyb_country_code[1] == '\0') { - country = MAKE_COUNTRY('X', 'X', 17); // default to world-wide (passive ch 12-14) - } else { - country = MAKE_COUNTRY(pyb_country_code[0], pyb_country_code[1], 0); - } - if (cyw43_wifi_on(self, country) != 0) { - return; - } - cyw43_wifi_pm(self, 10 << 20 | 1 << 16 | 1 << 12 | 20 << 4 | 2); - } - if (itf == CYW43_ITF_AP) { - cyw43_wifi_ap_init(self); - cyw43_wifi_ap_set_up(self, true); - } - if ((self->itf_state & (1 << itf)) == 0) { - CYW_ENTER - cyw43_tcpip_deinit(self, itf); - cyw43_tcpip_init(self, itf); - self->itf_state |= 1 << itf; - CYW_EXIT - } - } else { - if (itf == CYW43_ITF_AP) { - cyw43_wifi_ap_set_up(self, false); - } - } -} - -int cyw43_wifi_scan(cyw43_t *self, cyw43_wifi_scan_options_t *opts, void *env, int (*result_cb)(void*, const cyw43_ev_scan_result_t*)) { - if (self->itf_state == 0) { - return -MP_EPERM; - } - - cyw43_ensure_up(self); - - CYW_ENTER - - // Set state and callback data - self->wifi_scan_state = 1; - self->wifi_scan_env = env; - self->wifi_scan_cb = result_cb; - - // Start the scan - int ret = cyw43_ll_wifi_scan(&self->cyw43_ll, opts); - - CYW_EXIT - - return ret; -} - -int cyw43_wifi_link_status(cyw43_t *self, int itf) { - if (itf == CYW43_ITF_STA) { - int s = self->wifi_join_state & 0xf; - if (s == WIFI_JOIN_STATE_ACTIVE) { - return CYW43_LINK_JOIN; - } else if (s == WIFI_JOIN_STATE_FAIL) { - return CYW43_LINK_FAIL; - } else if (s == WIFI_JOIN_STATE_NONET) { - return CYW43_LINK_NONET; - } else if (s == WIFI_JOIN_STATE_BADAUTH) { - return CYW43_LINK_BADAUTH; - } else { - return CYW43_LINK_DOWN; - } - } else { - return CYW43_LINK_DOWN; - } -} - -/*******************************************************************************/ -// WiFi STA - -int cyw43_wifi_join(cyw43_t *self, size_t ssid_len, const uint8_t *ssid, size_t key_len, const uint8_t *key, uint32_t auth_type, const uint8_t *bssid, uint32_t channel) { - if (!CYW43_STA_IS_ACTIVE(self)) { - return -MP_EPERM; - } - - int ret = cyw43_ensure_up(self); - if (ret) { - return ret; - } - - CYW_ENTER - - ret = cyw43_ll_wifi_join(&self->cyw43_ll, ssid_len, ssid, key_len, key, auth_type, bssid, channel); - - if (ret == 0) { - // Wait for responses: EV_AUTH, EV_LINK, EV_SET_SSID, EV_PSK_SUP - // Will get EV_DEAUTH_IND if password is invalid - self->wifi_join_state = WIFI_JOIN_STATE_ACTIVE; - - if (auth_type == 0) { - // For open security we don't need EV_PSK_SUP, so set that flag indicator now - self->wifi_join_state |= WIFI_JOIN_STATE_KEYED; - } - } - - CYW_EXIT - - return ret; -} - -int cyw43_wifi_leave(cyw43_t *self, int itf) { - // Disassociate with SSID - return cyw43_ioctl(self, CYW43_IOCTL_SET_DISASSOC, 0, NULL, itf); -} - -/*******************************************************************************/ -// WiFi AP - -STATIC void cyw43_wifi_ap_init(cyw43_t *self) { - int ret = cyw43_ensure_up(self); - if (ret) { - return; - } - - CYW_ENTER - cyw43_ll_wifi_ap_init(&self->cyw43_ll, self->ap_ssid_len, self->ap_ssid, self->ap_auth, self->ap_key_len, self->ap_key, self->ap_channel); - CYW_EXIT -} - -STATIC void cyw43_wifi_ap_set_up(cyw43_t *self, bool up) { - int ret = cyw43_ensure_up(self); - if (ret) { - return; - } - - CYW_ENTER - cyw43_ll_wifi_ap_set_up(&self->cyw43_ll, up); - CYW_EXIT -} - -void cyw43_wifi_ap_get_stas(cyw43_t *self, int *num_stas, uint8_t *macs) { - int ret = cyw43_ensure_up(self); - if (ret) { - return; - } - - CYW_ENTER - cyw43_ll_wifi_ap_get_stas(&self->cyw43_ll, num_stas, macs); - CYW_EXIT -} diff --git a/drivers/cyw43/cyw43_ll.h b/drivers/cyw43/cyw43_ll.h deleted file mode 100644 index 879367a2ed..0000000000 --- a/drivers/cyw43/cyw43_ll.h +++ /dev/null @@ -1,135 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2018-2019 Damien P. George - * - * 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_LL_H -#define MICROPY_INCLUDED_STM32_CYW43_LL_H - -// IOCTL commands -#define CYW43_IOCTL_GET_SSID (0x32) -#define CYW43_IOCTL_GET_CHANNEL (0x3a) -#define CYW43_IOCTL_SET_DISASSOC (0x69) -#define CYW43_IOCTL_GET_ANTDIV (0x7e) -#define CYW43_IOCTL_SET_ANTDIV (0x81) -#define CYW43_IOCTL_SET_MONITOR (0xd9) -#define CYW43_IOCTL_GET_VAR (0x20c) -#define CYW43_IOCTL_SET_VAR (0x20f) - -// Async events, event_type field -#define CYW43_EV_SET_SSID (0) -#define CYW43_EV_JOIN (1) -#define CYW43_EV_AUTH (3) -#define CYW43_EV_DEAUTH_IND (6) -#define CYW43_EV_ASSOC (7) -#define CYW43_EV_DISASSOC (11) -#define CYW43_EV_DISASSOC_IND (12) -#define CYW43_EV_LINK (16) -#define CYW43_EV_PRUNE (23) -#define CYW43_EV_PSK_SUP (46) -#define CYW43_EV_ESCAN_RESULT (69) -#define CYW43_EV_CSA_COMPLETE_IND (80) -#define CYW43_EV_ASSOC_REQ_IE (87) -#define CYW43_EV_ASSOC_RESP_IE (88) - -enum { - CYW43_ITF_STA, - CYW43_ITF_AP, -}; - -typedef struct _cyw43_ev_scan_result_t { - uint32_t _0[5]; - uint8_t bssid[6]; - uint16_t _1[2]; - uint8_t ssid_len; - uint8_t ssid[32]; - uint32_t _2[5]; - uint16_t channel; - uint16_t _3; - uint8_t auth_mode; - int16_t rssi; -} cyw43_ev_scan_result_t; - -typedef struct _cyw43_async_event_t { - uint16_t _0; - uint16_t flags; - uint32_t event_type; - uint32_t status; - uint32_t reason; - uint8_t _1[30]; - uint8_t interface; - uint8_t _2; - union { - cyw43_ev_scan_result_t scan_result; - } u; -} cyw43_async_event_t; - -typedef struct _cyw43_wifi_scan_options_t { - uint32_t version; - uint16_t action; - uint16_t _; - uint32_t ssid_len; // 0 to select all - uint8_t ssid[32]; - uint8_t bssid[6]; - int8_t bss_type; // fill with 0xff to select all - int8_t scan_type; // 0=active, 1=passive - int32_t nprobes; - int32_t active_time; - int32_t passive_time; - int32_t home_time; - int32_t channel_num; - uint16_t channel_list[1]; -} cyw43_wifi_scan_options_t; - -typedef struct _cyw43_ll_t { - uint32_t opaque[528]; -} cyw43_ll_t; - -void cyw43_ll_init(cyw43_ll_t *self, void *cb_data); -void cyw43_ll_deinit(cyw43_ll_t *self); - -int cyw43_ll_bus_init(cyw43_ll_t *self, const uint8_t *mac); -void cyw43_ll_bus_sleep(cyw43_ll_t *self, bool can_sleep); -void cyw43_ll_process_packets(cyw43_ll_t *self); -int cyw43_ll_ioctl(cyw43_ll_t *self, uint32_t cmd, size_t len, uint8_t *buf, uint32_t iface); -int cyw43_ll_send_ethernet(cyw43_ll_t *self, int itf, size_t len, const void *buf, bool is_pbuf); - -int cyw43_ll_wifi_on(cyw43_ll_t *self, uint32_t country); -int cyw43_ll_wifi_pm(cyw43_ll_t *self, uint32_t pm, uint32_t pm_sleep_ret, uint32_t li_bcn, uint32_t li_dtim, uint32_t li_assoc); -int cyw43_ll_wifi_scan(cyw43_ll_t *self, cyw43_wifi_scan_options_t *opts); - -int cyw43_ll_wifi_join(cyw43_ll_t *self, size_t ssid_len, const uint8_t *ssid, size_t key_len, const uint8_t *key, uint32_t auth_type, const uint8_t *bssid, uint32_t channel); -void cyw43_ll_wifi_set_wpa_auth(cyw43_ll_t *self); -void cyw43_ll_wifi_rejoin(cyw43_ll_t *self); - -int cyw43_ll_wifi_ap_init(cyw43_ll_t *self, size_t ssid_len, const uint8_t *ssid, uint32_t auth, size_t key_len, const uint8_t *key, uint32_t channel); -int cyw43_ll_wifi_ap_set_up(cyw43_ll_t *self, bool up); -int cyw43_ll_wifi_ap_get_stas(cyw43_ll_t *self, int *num_stas, uint8_t *macs); - -// Callbacks to be provided by mid-level interface -int cyw43_cb_read_host_interrupt_pin(void *cb_data); -void cyw43_cb_ensure_awake(void *cb_data); -void cyw43_cb_process_async_event(void *cb_data, const cyw43_async_event_t *ev); -void cyw43_cb_process_ethernet(void *cb_data, int itf, size_t len, const uint8_t *buf); - -#endif // MICROPY_INCLUDED_STM32_CYW43_LL_H diff --git a/drivers/cyw43/cyw43_lwip.c b/drivers/cyw43/cyw43_lwip.c deleted file mode 100644 index f12a378c5d..0000000000 --- a/drivers/cyw43/cyw43_lwip.c +++ /dev/null @@ -1,199 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2018-2019 Damien P. George - * - * 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. - */ - -#include -#include - -#include "py/mphal.h" -#include "shared/netutils/netutils.h" -#include "lwip/etharp.h" -#include "lwip/dns.h" -#include "lwip/apps/mdns.h" -#include "drivers/cyw43/cyw43.h" - -STATIC void cyw43_ethernet_trace(cyw43_t *self, struct netif *netif, size_t len, const void *data, unsigned int flags) { - bool is_tx = flags & NETUTILS_TRACE_IS_TX; - if ((is_tx && (self->trace_flags & CYW43_TRACE_ETH_TX)) - || (!is_tx && (self->trace_flags & CYW43_TRACE_ETH_RX))) { - const uint8_t *buf; - if (len == (size_t)-1) { - // data is a pbuf - const struct pbuf *pbuf = data; - buf = pbuf->payload; - len = pbuf->len; // restricted to print only the first chunk of the pbuf - } else { - // data is actual data buffer - buf = data; - } - - if (self->trace_flags & CYW43_TRACE_MAC) { - printf("[% 8d] ETH%cX itf=%c%c len=%u", (int)mp_hal_ticks_ms(), is_tx ? 'T' : 'R', netif->name[0], netif->name[1], len); - printf(" MAC type=%d subtype=%d data=", buf[0] >> 2 & 3, buf[0] >> 4); - for (size_t i = 0; i < len; ++i) { - printf(" %02x", buf[i]); - } - printf("\n"); - return; - } - - if (self->trace_flags & CYW43_TRACE_ETH_FULL) { - flags |= NETUTILS_TRACE_PAYLOAD; - } - netutils_ethernet_trace(MP_PYTHON_PRINTER, len, buf, flags); - } -} - -STATIC err_t cyw43_netif_output(struct netif *netif, struct pbuf *p) { - cyw43_t *self = netif->state; - if (self->trace_flags != 0) { - cyw43_ethernet_trace(self, netif, (size_t)-1, p, NETUTILS_TRACE_IS_TX | NETUTILS_TRACE_NEWLINE); - } - int itf = netif->name[1] - '0'; - int ret = cyw43_send_ethernet(self, itf, p->tot_len, (void*)p, true); - if (ret) { - printf("[CYW43] send_ethernet failed: %d\n", ret); - return ERR_IF; - } - return ERR_OK; -} - -STATIC err_t cyw43_netif_init(struct netif *netif) { - netif->linkoutput = cyw43_netif_output; - netif->output = etharp_output; - netif->mtu = 1500; - netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET | NETIF_FLAG_IGMP; - cyw43_wifi_get_mac(netif->state, netif->name[1] - '0', netif->hwaddr); - netif->hwaddr_len = sizeof(netif->hwaddr); - return ERR_OK; -} - -void cyw43_tcpip_init(cyw43_t *self, int itf) { - ip_addr_t ipconfig[4]; - #if LWIP_IPV6 - #define IP(x) ((x).u_addr.ip4) - #else - #define IP(x) (x) - #endif - if (itf == 0) { - // need to zero out to get isconnected() working - IP4_ADDR(&IP(ipconfig[0]), 0, 0, 0, 0); - IP4_ADDR(&IP(ipconfig[2]), 192, 168, 0, 1); - } else { - IP4_ADDR(&IP(ipconfig[0]), 192, 168, 4, 1); - IP4_ADDR(&IP(ipconfig[2]), 192, 168, 4, 1); - } - IP4_ADDR(&IP(ipconfig[1]), 255, 255, 255, 0); - IP4_ADDR(&IP(ipconfig[3]), 8, 8, 8, 8); - #undef IP - - struct netif *n = &self->netif[itf]; - n->name[0] = 'w'; - n->name[1] = '0' + itf; - #if LWIP_IPV6 - netif_add(n, &ipconfig[0].u_addr.ip4, &ipconfig[1].u_addr.ip4, &ipconfig[2].u_addr.ip4, self, cyw43_netif_init, ethernet_input); - #else - netif_add(n, &ipconfig[0], &ipconfig[1], &ipconfig[2], self, cyw43_netif_init, netif_input); - #endif - netif_set_hostname(n, self->hostname); - netif_set_default(n); - netif_set_up(n); - - if (itf == CYW43_ITF_STA) { - dns_setserver(0, &ipconfig[3]); - dhcp_set_struct(n, &self->dhcp_client); - dhcp_start(n); - } else { - dhcp_server_init(&self->dhcp_server, &ipconfig[0], &ipconfig[1]); - } - - #if LWIP_MDNS_RESPONDER - // TODO better to call after IP address is set - char mdns_hostname[9]; - int len = MIN(strlen(self->hostname), 4); - memcpy(&mdns_hostname[0], self->hostname, len); - mp_hal_get_mac_ascii(MP_HAL_MAC_WLAN0, 4 + len, 8 - len, &mdns_hostname[len]); - mdns_hostname[8] = '\0'; - mdns_resp_add_netif(n, mdns_hostname, 60); - #endif -} - -void cyw43_tcpip_deinit(cyw43_t *self, int itf) { - struct netif *n = &self->netif[itf]; - if (itf == CYW43_ITF_STA) { - dhcp_stop(n); - } else { - dhcp_server_deinit(&self->dhcp_server); - } - #if LWIP_MDNS_RESPONDER - mdns_resp_remove_netif(n); - #endif - for (struct netif *netif = netif_list; netif != NULL; netif = netif->next) { - if (netif == n) { - netif_remove(netif); - netif->ip_addr.addr = 0; - netif->flags = 0; - } - } -} - -void cyw43_cb_process_ethernet(void *cb_data, int itf, size_t len, const uint8_t *buf) { - cyw43_t *self = cb_data; - struct netif *netif = &self->netif[itf]; - if (self->trace_flags) { - cyw43_ethernet_trace(self, netif, len, buf, NETUTILS_TRACE_NEWLINE); - } - if (netif->flags & NETIF_FLAG_LINK_UP) { - struct pbuf *p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL); - if (p != NULL) { - pbuf_take(p, buf, len); - if (netif->input(p, netif) != ERR_OK) { - pbuf_free(p); - } - } - } -} - -void cyw43_tcpip_set_link_up(cyw43_t *self, int itf) { - netif_set_link_up(&self->netif[itf]); -} - -void cyw43_tcpip_set_link_down(cyw43_t *self, int itf) { - netif_set_link_down(&self->netif[itf]); -} - -int cyw43_tcpip_link_status(cyw43_t *self, int itf) { - struct netif *netif = &self->netif[itf]; - if ((netif->flags & (NETIF_FLAG_UP | NETIF_FLAG_LINK_UP)) - == (NETIF_FLAG_UP | NETIF_FLAG_LINK_UP)) { - if (netif->ip_addr.addr != 0) { - return CYW43_LINK_UP; - } else { - return CYW43_LINK_NOIP; - } - } else { - return cyw43_wifi_link_status(self, itf); - } -} diff --git a/drivers/cyw43/cywbt.c b/drivers/cyw43/cywbt.c index e394e02b33..d0e0aac009 100644 --- a/drivers/cyw43/cywbt.c +++ b/drivers/cyw43/cywbt.c @@ -35,8 +35,7 @@ #if MICROPY_PY_NETWORK_CYW43 -extern const char fw_4343WA1_7_45_98_50_start; -#define CYWBT_FW_ADDR (&fw_4343WA1_7_45_98_50_start + 749 * 512 + 29 * 256) +#include "lib/cyw43-driver/firmware/cyw43_btfw_4343A1.h" // Provided by the port. extern pyb_uart_obj_t mp_bluetooth_hci_uart_obj; @@ -195,7 +194,7 @@ int mp_bluetooth_hci_controller_init(void) { cywbt_set_baudrate(MICROPY_HW_BLE_UART_BAUDRATE_SECONDARY); mp_bluetooth_hci_uart_set_baudrate(MICROPY_HW_BLE_UART_BAUDRATE_SECONDARY); - cywbt_download_firmware((const uint8_t*)CYWBT_FW_ADDR); + cywbt_download_firmware((const uint8_t*)&cyw43_btfw_4343A1[0]); // Reset cywbt_hci_cmd(0x03, 0x0003, 0, NULL); diff --git a/drivers/cyw43/libcyw43.a b/drivers/cyw43/libcyw43.a deleted file mode 100644 index 7d0ff93dcb..0000000000 Binary files a/drivers/cyw43/libcyw43.a and /dev/null differ diff --git a/extmod/extmod.mk b/extmod/extmod.mk index 03fdb43546..5aecedc228 100644 --- a/extmod/extmod.mk +++ b/extmod/extmod.mk @@ -301,11 +301,23 @@ endif # networking ifeq ($(MICROPY_PY_NETWORK_CYW43),1) +CYW43_DIR = lib/cyw43-driver +GIT_SUBMODULES += $(CYW43_DIR) CFLAGS_EXTMOD += -DMICROPY_PY_NETWORK_CYW43=1 -DRIVERS_SRC_C += drivers/cyw43/cyw43_ctrl.c drivers/cyw43/cyw43_lwip.c -LIBS += $(TOP)/drivers/cyw43/libcyw43.a +SRC_THIRDPARTY_C += $(addprefix $(CYW43_DIR)/src/,\ + cyw43_ctrl.c \ + cyw43_lwip.c \ + cyw43_ll.c \ + cyw43_sdio.c \ + cyw43_stats.c \ + ) +ifeq ($(MICROPY_PY_BLUETOOTH),1) +DRIVERS_SRC_C += drivers/cyw43/cywbt.c endif +$(BUILD)/$(CYW43_DIR)/src/cyw43_%.o: CFLAGS += -std=c11 +endif # MICROPY_PY_NETWORK_CYW43 + ifneq ($(MICROPY_PY_NETWORK_WIZNET5K),) ifneq ($(MICROPY_PY_NETWORK_WIZNET5K),0) WIZNET5K_DIR=lib/wiznet5k diff --git a/extmod/modnetwork.c b/extmod/modnetwork.c index 438c1ed744..7c1b91de45 100644 --- a/extmod/modnetwork.c +++ b/extmod/modnetwork.c @@ -37,7 +37,7 @@ #include "shared/netutils/netutils.h" #include "modnetwork.h" -#if MICROPY_PY_NETWORK_CYW43 && MICROPY_PY_NETWORK_CYW43_USE_LIB_DRIVER +#if MICROPY_PY_NETWORK_CYW43 // So that CYW43_LINK_xxx constants are available to MICROPY_PORT_NETWORK_INTERFACES. #include "lib/cyw43-driver/src/cyw43.h" #endif diff --git a/extmod/network_cyw43.c b/extmod/network_cyw43.c index 95901eaddf..2d0b228e54 100644 --- a/extmod/network_cyw43.c +++ b/extmod/network_cyw43.c @@ -36,12 +36,8 @@ #include "extmod/network_cyw43.h" #include "modnetwork.h" -#if MICROPY_PY_NETWORK_CYW43_USE_LIB_DRIVER #include "lib/cyw43-driver/src/cyw43.h" #include "lib/cyw43-driver/src/cyw43_country.h" -#else -#include "drivers/cyw43/cyw43.h" -#endif typedef struct _network_cyw43_obj_t { mp_obj_base_t base; @@ -120,23 +116,13 @@ STATIC mp_obj_t network_cyw43_deinit(mp_obj_t self_in) { } STATIC MP_DEFINE_CONST_FUN_OBJ_1(network_cyw43_deinit_obj, network_cyw43_deinit); -#if !MICROPY_PY_NETWORK_CYW43_USE_LIB_DRIVER -// TODO: The old driver expects this to be available at link time. -char pyb_country_code[2]; -#endif - STATIC mp_obj_t network_cyw43_active(size_t n_args, const mp_obj_t *args) { network_cyw43_obj_t *self = MP_OBJ_TO_PTR(args[0]); if (n_args == 1) { return mp_obj_new_bool(cyw43_tcpip_link_status(self->cyw, self->itf)); } else { - #if MICROPY_PY_NETWORK_CYW43_USE_LIB_DRIVER uint32_t country = CYW43_COUNTRY(mod_network_country_code[0], mod_network_country_code[1], 0); cyw43_wifi_set_up(self->cyw, self->itf, mp_obj_is_true(args[1]), country); - #else - memcpy(pyb_country_code, mod_network_country_code, sizeof(pyb_country_code)); - cyw43_wifi_set_up(self->cyw, self->itf, mp_obj_is_true(args[1])); - #endif return mp_const_none; } } @@ -277,13 +263,12 @@ STATIC mp_obj_t network_cyw43_connect(size_t n_args, const mp_obj_t *pos_args, m uint32_t auth_type; if (args[ARG_security].u_int == -1) { if (key.buf == NULL || key.len == 0) { - auth_type = 0; // open security + // Default to open when no password set. + auth_type = CYW43_AUTH_OPEN; } else { - #if MICROPY_PY_NETWORK_CYW43_USE_LIB_DRIVER + // Default to WPA2 otherwise. All other modes require the security + // kwarg to be set explicitly. auth_type = CYW43_AUTH_WPA2_MIXED_PSK; - #else - auth_type = 0x008006; // WPA2_MIXED_PSK - #endif } } else { auth_type = args[ARG_security].u_int; @@ -396,11 +381,9 @@ STATIC mp_obj_t network_cyw43_config(size_t n_args, const mp_obj_t *args, mp_map return mp_obj_new_str((const char *)buf, len); } } - #if MICROPY_PY_NETWORK_CYW43_USE_LIB_DRIVER case MP_QSTR_security: { return MP_OBJ_NEW_SMALL_INT(cyw43_wifi_ap_get_auth(self->cyw)); } - #endif case MP_QSTR_mac: { uint8_t buf[6]; cyw43_wifi_get_mac(self->cyw, self->itf, buf); @@ -412,11 +395,10 @@ STATIC mp_obj_t network_cyw43_config(size_t n_args, const mp_obj_t *args, mp_map cyw43_ioctl(self->cyw, CYW43_IOCTL_GET_VAR, 13, buf, self->itf); return MP_OBJ_NEW_SMALL_INT(nw_get_le32(buf) / 4); } - #if !MICROPY_PY_NETWORK_CYW43_USE_LIB_DRIVER case MP_QSTR_hostname: { - return mp_obj_new_str(self->cyw->hostname, strlen(self->cyw->hostname)); + // TODO: Deprecated. Use network.hostname() instead. + return mp_obj_new_str(mod_network_hostname, strlen(mod_network_hostname)); } - #endif default: mp_raise_ValueError(MP_ERROR_TEXT("unknown config param")); } @@ -489,14 +471,16 @@ STATIC mp_obj_t network_cyw43_config(size_t n_args, const mp_obj_t *args, mp_map cyw43_ioctl(self->cyw, CYW43_IOCTL_SET_VAR, 9 + 4, buf, self->itf); break; } - #if !MICROPY_PY_NETWORK_CYW43_USE_LIB_DRIVER case MP_QSTR_hostname: { - const char *hostname = mp_obj_str_get_str(e->value); - strncpy(self->cyw->hostname, hostname, MICROPY_BOARD_HOSTNAME_LENGTH); - self->cyw->hostname[MICROPY_BOARD_HOSTNAME_LENGTH - 1] = 0; + // TODO: Deprecated. Use network.hostname(name) instead. + size_t len; + const char *str = mp_obj_str_get_data(args[0], &len); + if (len >= MICROPY_PY_NETWORK_HOSTNAME_MAX_LEN) { + mp_raise_ValueError(NULL); + } + strcpy(mod_network_hostname, str); break; } - #endif default: mp_raise_ValueError(MP_ERROR_TEXT("unknown config param")); } diff --git a/ports/rp2/CMakeLists.txt b/ports/rp2/CMakeLists.txt index 8e8db47355..ab09ab5148 100644 --- a/ports/rp2/CMakeLists.txt +++ b/ports/rp2/CMakeLists.txt @@ -250,7 +250,6 @@ if (MICROPY_PY_NETWORK_CYW43) target_compile_definitions(${MICROPY_TARGET} PRIVATE MICROPY_PY_NETWORK_CYW43=1 - MICROPY_PY_NETWORK_CYW43_USE_LIB_DRIVER=1 MICROPY_PY_SOCKET_DEFAULT_TIMEOUT_MS=30000 # default socket timeout ) if (CMAKE_BUILD_TYPE MATCHES Debug) diff --git a/ports/rp2/main.c b/ports/rp2/main.c index c5b5037491..570c4302f0 100644 --- a/ports/rp2/main.c +++ b/ports/rp2/main.c @@ -42,6 +42,7 @@ #include "modmachine.h" #include "modrp2.h" #include "mpbthciport.h" +#include "mpnetworkport.h" #include "genhdr/mpversion.h" #include "mp_usbd.h" diff --git a/ports/rp2/mpconfigport.h b/ports/rp2/mpconfigport.h index 180216329a..f5391b5a78 100644 --- a/ports/rp2/mpconfigport.h +++ b/ports/rp2/mpconfigport.h @@ -267,7 +267,3 @@ typedef intptr_t mp_off_t; extern uint32_t rosc_random_u32(void); extern void lwip_lock_acquire(void); extern void lwip_lock_release(void); -extern void cyw43_irq_init(void); -extern void cyw43_post_poll_hook(void); - -#define CYW43_POST_POLL_HOOK cyw43_post_poll_hook(); diff --git a/ports/rp2/mpnetworkport.h b/ports/rp2/mpnetworkport.h new file mode 100644 index 0000000000..88c190f45e --- /dev/null +++ b/ports/rp2/mpnetworkport.h @@ -0,0 +1,33 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * 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_RP2_MPNETWORKPORT_H +#define MICROPY_INCLUDED_RP2_MPNETWORKPORT_H + +#if MICROPY_PY_NETWORK_CYW43 +extern void cyw43_irq_init(void); +#endif + +#endif // MICROPY_INCLUDED_RP2_MPNETWORKPORT_H diff --git a/ports/stm32/Makefile b/ports/stm32/Makefile index 1fd2757c4a..db89b2f4f1 100644 --- a/ports/stm32/Makefile +++ b/ports/stm32/Makefile @@ -487,10 +487,7 @@ SRC_C += mpbtstackport.c MICROPY_BLUETOOTH_BTSTACK_H4 ?= 1 endif -ifeq ($(MICROPY_PY_NETWORK_CYW43),1) -DRIVERS_SRC_C += drivers/cyw43/cywbt.c -endif -endif +endif # MICROPY_PY_BLUETOOTH # SRC_O should be placed first to work around this LTO bug with binutils <2.35: # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83967 diff --git a/ports/stm32/cyw43_configport.h b/ports/stm32/cyw43_configport.h new file mode 100644 index 0000000000..666dfc43e2 --- /dev/null +++ b/ports/stm32/cyw43_configport.h @@ -0,0 +1,135 @@ +/* + * 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) + +#define CYW43_CHIPSET_FIRMWARE_INCLUDE_FILE "lib/cyw43-driver/firmware/w4343WA1_7_45_98_50_combined.h" +#define CYW43_WIFI_NVRAM_INCLUDE_FILE "lib/cyw43-driver/firmware/wifi_nvram_1dx.h" +#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_config mp_hal_pin_config +#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_PIN_WL_REG_ON pyb_pin_WL_REG_ON +#define CYW43_PIN_WL_HOST_WAKE pyb_pin_WL_HOST_WAKE +#define CYW43_PIN_WL_RFSW_VDD pyb_pin_WL_RFSW_VDD +#define CYW43_PIN_WL_SDIO_1 pyb_pin_WL_SDIO_1 + +#define cyw43_schedule_internal_poll_dispatch(func) pendsv_schedule_dispatch(PENDSV_DISPATCH_CYW43, func) + +void cyw43_post_poll_hook(void); + +static inline void cyw43_delay_us(uint32_t us) { + uint32_t start = mp_hal_ticks_us(); + while (mp_hal_ticks_us() - start < us) { + } +} + +static inline void cyw43_delay_ms(uint32_t ms) { + uint32_t us = ms * 1000; + uint32_t start = mp_hal_ticks_us(); + while (mp_hal_ticks_us() - start < us) { + MICROPY_EVENT_POLL_HOOK; + } +} + +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 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/stm32/extint.c b/ports/stm32/extint.c index fd7950de3e..e260560925 100644 --- a/ports/stm32/extint.c +++ b/ports/stm32/extint.c @@ -36,6 +36,11 @@ #include "extint.h" #include "irq.h" +#if MICROPY_PY_NETWORK_CYW43 && defined(pyb_pin_WL_HOST_WAKE) +#include "lib/cyw43-driver/src/cyw43.h" +#include "lib/cyw43-driver/src/cyw43_stats.h" +#endif + /// \moduleref pyb /// \class ExtInt - configure I/O pins to interrupt on external events /// @@ -690,9 +695,9 @@ void Handle_EXTI_Irq(uint32_t line) { mp_obj_t *cb = &MP_STATE_PORT(pyb_extint_callback)[line]; #if MICROPY_PY_NETWORK_CYW43 && defined(pyb_pin_WL_HOST_WAKE) if (pyb_extint_callback_arg[line] == MP_OBJ_FROM_PTR(pyb_pin_WL_HOST_WAKE)) { - extern void (*cyw43_poll)(void); if (cyw43_poll) { pendsv_schedule_dispatch(PENDSV_DISPATCH_CYW43, cyw43_poll); + CYW43_STAT_INC(IRQ_COUNT); } return; } diff --git a/ports/stm32/main.c b/ports/stm32/main.c index 7f864a018c..66dcb86ddc 100644 --- a/ports/stm32/main.c +++ b/ports/stm32/main.c @@ -48,7 +48,9 @@ #if MICROPY_PY_LWIP #include "lwip/init.h" #include "lwip/apps/mdns.h" -#include "drivers/cyw43/cyw43.h" +#if MICROPY_PY_NETWORK_CYW43 +#include "lib/cyw43-driver/src/cyw43.h" +#endif #endif #if MICROPY_PY_BLUETOOTH diff --git a/ports/stm32/mpnetworkport.c b/ports/stm32/mpnetworkport.c index 1ce758e7dd..62f780a35a 100644 --- a/ports/stm32/mpnetworkport.c +++ b/ports/stm32/mpnetworkport.c @@ -42,8 +42,11 @@ #include "lwip/dns.h" #include "lwip/dhcp.h" #include "lwip/apps/mdns.h" + +#if MICROPY_PY_NETWORK_CYW43 #include "extmod/network_cyw43.h" -#include "drivers/cyw43/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)