diff --git a/src/drivers/ninaw10/include/nina.h b/src/drivers/ninaw10/include/nina.h deleted file mode 100644 index 6aecb8e09..000000000 --- a/src/drivers/ninaw10/include/nina.h +++ /dev/null @@ -1,106 +0,0 @@ -/* - * This file is part of the OpenMV project. - * - * Copyright (c) 2013-2021 Ibrahim Abdelkader - * Copyright (c) 2013-2021 Kwabena W. Agyeman - * - * This work is licensed under the MIT license, see the file LICENSE for details. - * - * NINA-W10 WiFi driver. - */ -#ifndef __NINA_H__ -#define __NINA_H__ - -#define NINA_FW_VER_LEN (6) -#define NINA_IPV4_ADDR_LEN (4) -#define NINA_MAC_ADDR_LEN (6) -#define NINA_MAX_SSID_LEN (32) -#define NINA_MAX_WEP_LEN (13) -#define NINA_MAX_WPA_LEN (63) -#define NINA_MAX_NETWORK_LIST (10) -#define NINA_MAX_SOCKET (10) - -#define NINA_FW_VER_MAJOR (1) -#define NINA_FW_VER_MINOR (4) -#define NINA_FW_VER_PATCH (8) - -#define NINA_FW_VER_MAJOR_OFFS (0) -#define NINA_FW_VER_MINOR_OFFS (2) -#define NINA_FW_VER_PATCH_OFFS (4) - -typedef enum { - NINA_SEC_INVALID = 0, - NINA_SEC_OPEN, - NINA_SEC_WPA_PSK, - NINA_SEC_WEP -} nina_security_t; - -typedef enum { - NINA_SOCKET_TYPE_TCP = 0, - NINA_SOCKET_TYPE_UDP, - NINA_SOCKET_TYPE_TLS, - NINA_SOCKET_TYPE_UDP_MULTICAST, - NINA_SOCKET_TYPE_TLS_BEARSSL -} nina_socket_type_t; - -typedef enum { - NINA_ERROR_IO = -1, - NINA_ERROR_TIMEOUT = -2, -} nina_error_t; - -typedef enum { - NINA_WIFI_MODE_STA = 0, - NINA_WIFI_MODE_AP, -} nina_wifi_mode_t; - -typedef struct { - uint8_t ip_addr[NINA_IPV4_ADDR_LEN]; - uint8_t subnet_addr[NINA_IPV4_ADDR_LEN]; - uint8_t gateway_addr[NINA_IPV4_ADDR_LEN]; - uint8_t dns_addr[NINA_IPV4_ADDR_LEN]; -} nina_ifconfig_t; - -typedef struct { - int32_t rssi; - uint8_t security; - uint8_t channel; - uint8_t bssid[NINA_MAC_ADDR_LEN]; - char ssid[NINA_MAX_SSID_LEN]; -} nina_scan_result_t; - -typedef struct { - int32_t rssi; - uint8_t security; - char ssid[NINA_MAX_SSID_LEN]; - uint8_t bssid[NINA_MAC_ADDR_LEN]; -} nina_netinfo_t; - -typedef int (*nina_scan_callback_t)(nina_scan_result_t *, void *); - -int nina_init(void); -int nina_deinit(void); -int nina_connect(const char *ssid, uint8_t security, const char *key, uint16_t channel); -int nina_start_ap(const char *ssid, uint8_t security, const char *key, uint16_t channel); -int nina_disconnect(void); -int nina_isconnected(void); -int nina_connected_sta(uint32_t *sta_ip); -int nina_wait_for_sta(uint32_t *sta_ip, uint32_t timeout); -int nina_ifconfig(nina_ifconfig_t *ifconfig, bool set); -int nina_netinfo(nina_netinfo_t *netinfo); -int nina_scan(nina_scan_callback_t scan_callback, void *arg, uint32_t timeout); -int nina_get_rssi(void); -int nina_fw_version(uint8_t *fw_ver); -int nina_set_hostname(const char *name); -int nina_gethostbyname(const char *name, uint8_t *out_ip); -int nina_socket_socket(uint8_t type); -int nina_socket_close(int fd); -int nina_socket_bind(int fd, uint8_t *ip, uint16_t port, int type); -int nina_socket_listen(int fd, uint32_t backlog); -int nina_socket_accept(int fd, uint8_t *ip, uint16_t *port, int *fd_out, uint32_t timeout); -int nina_socket_connect(int fd, uint8_t *ip, uint16_t port, uint32_t timeout); -int nina_socket_send(int fd, const uint8_t *buf, uint32_t len, uint32_t timeout); -int nina_socket_recv(int fd, uint8_t *buf, uint32_t len, uint32_t timeout); -int nina_socket_sendto(int fd, const uint8_t *buf, uint32_t len, uint8_t *ip, uint16_t port, uint32_t timeout); -int nina_socket_recvfrom(int fd, uint8_t *buf, uint32_t len, uint8_t *ip, uint16_t *port, uint32_t timeout); -int nina_socket_setsockopt(int fd, uint32_t level, uint32_t opt, const void *optval, uint32_t optlen); -#endif //define __NINA_H__ diff --git a/src/drivers/ninaw10/include/nina_bsp.h b/src/drivers/ninaw10/include/nina_bsp.h deleted file mode 100644 index 526823433..000000000 --- a/src/drivers/ninaw10/include/nina_bsp.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * This file is part of the OpenMV project. - * - * Copyright (c) 2013-2021 Ibrahim Abdelkader - * Copyright (c) 2013-2021 Kwabena W. Agyeman - * - * This work is licensed under the MIT license, see the file LICENSE for details. - * - * NINA-W10 driver BSP. - */ -#ifndef __NINA_BSP_H__ -#define __NINA_BSP_H__ -int nina_bsp_init(); -int nina_bsp_deinit(); -int nina_bsp_read_irq(); -int nina_bsp_spi_slave_select(uint32_t timeout); -int nina_bsp_spi_slave_deselect(); -int nina_bsp_spi_transfer(const uint8_t *tx_buf, uint8_t *rx_buf, uint32_t size); -#endif //define __NINA_BSP_H__ diff --git a/src/drivers/ninaw10/src/nina.c b/src/drivers/ninaw10/src/nina.c deleted file mode 100644 index d46151948..000000000 --- a/src/drivers/ninaw10/src/nina.c +++ /dev/null @@ -1,910 +0,0 @@ -/* - * This file is part of the OpenMV project. - * - * Copyright (c) 2013-2021 Ibrahim Abdelkader - * Copyright (c) 2013-2021 Kwabena W. Agyeman - * - * This work is licensed under the MIT license, see the file LICENSE for details. - * - * NINA-W10 WiFi driver. - */ -#include "py/mphal.h" - -#if MICROPY_PY_NINAW10 - -#include -#include -#include - -#include "nina_bsp.h" -#include "nina.h" - -#define SPI_ACK (1) -#define SPI_ERR (0xFF) - -#define NO_SOCKET_AVAIL (255) - -#define CMD_START (0xE0) -#define CMD_END (0xEE) -#define CMD_ERROR (0xEF) -#define CMD_REPLY (1 << 7) - -#define ARG_8BITS (1) -#define ARG_16BITS (2) - -#define ARG_STR(x) {strlen(x), (const void *)x} -#define ARG_BYTE(x) {1, (uint8_t [1]) {x}} -#define ARG_SHORT(x) {2, (uint16_t [1]) {x}} -#define ARG_WORD(x) {4, (uint32_t [1]) {x}} - -#define NINA_ARGS(...) (nina_args_t []) {__VA_ARGS__} -#define NINA_VALS(...) (nina_vals_t []) {__VA_ARGS__} - -#define NINA_SSELECT_TIMEOUT (10000) -#define NINA_RESPONSE_TIMEOUT (1000) -#define NINA_CONNECT_TIMEOUT (10000) - -#if NINA_DEBUG -#define debug_printf(...) mp_printf(&mp_plat_print, __VA_ARGS__) -#else -#define debug_printf(...) -#endif - -#ifndef __REVSH -#define __REVSH(x) ((((uint16_t)x) << 8) | (((uint16_t)x) >> 8)) -#endif - -typedef struct { - uint16_t size; - const void *data; -} nina_args_t; - -typedef struct { - uint16_t *size; - void *data; -} nina_vals_t; - -typedef enum { - // STA mode commands. - NINA_CMD_CONNECT_OPEN = 0x10, - NINA_CMD_CONNECT_WEP = 0x11, - NINA_CMD_CONNECT_WPA = 0x12, - NINA_CMD_GET_SSID = 0x23, - NINA_CMD_GET_BSSID = 0x24, - NINA_CMD_GET_RSSI = 0x25, - NINA_CMD_GET_ENCRYPT = 0x26, - - // AP mode commands. - NINA_CMD_START_AP_OPEN = 0x18, - NINA_CMD_START_AP_WEP = 0x19, - - // AP mode scan commands. - NINA_CMD_AP_START_SCAN = 0x36, - NINA_CMD_AP_SCAN_RESULT = 0x27, - NINA_CMD_AP_GET_RSSI = 0x32, - NINA_CMD_AP_GET_ENCRYPT = 0x33, - NINA_CMD_AP_GET_BSSID = 0x3C, - NINA_CMD_AP_GET_CHANNEL = 0x3D, - - // Disonnect/status commands. - NINA_CMD_DISCONNECT = 0x30, - NINA_CMD_CONN_STATUS = 0x20, - - // Interface config commands. - NINA_CMD_SET_IF_CONFIG = 0x14, - NINA_CMD_GET_IF_CONFIG = 0x21, - NINA_CMD_SET_DNS_CONFIG = 0x15, - - // Hostname/Resolv commands. - NINA_CMD_SET_HOSTNAME = 0x16, - NINA_CMD_HOST_BY_NAME = 0x34, - NINA_CMD_GET_HOST_BY_NAME = 0x35, - - // Misc commands. - NINA_CMD_SET_POWER = 0x17, - NINA_CMD_PING = 0x3E, - NINA_CMD_GET_TIME = 0x3B, - NINA_CMD_GET_FW_VERSION = 0x37, - NINA_CMD_DEBUG_MODE = 0x1A, - NINA_CMD_TEMP_SENSOR = 0x1B, - NINA_CMD_GET_MAC_ADDR = 0x22, - - // Sockets commands. - NINA_CMD_SOCKET_OPEN = 0x3F, - NINA_CMD_SOCKET_CLOSE = 0x2E, - NINA_CMD_SOCKET_CONNECT = 0x2D, - NINA_CMD_SOCKET_ACCEPT = 0x2B, - NINA_CMD_SOCKET_BIND = 0x28, - NINA_CMD_SOCKET_STATE = 0x2F, - NINA_CMD_SOCKET_REMOTE_ADDR = 0x3A, - - // TCP commands - NINA_CMD_TCP_SEND = 0x44, - NINA_CMD_TCP_RECV = 0x45, - NINA_CMD_TCP_ACK = 0x2A, - - // UDP commands. - NINA_CMD_UDP_SEND = 0x46, - NINA_CMD_UDP_RECV = 0x45, - NINA_CMD_UDP_ACK = 0x39, - - // Pin control commands. - NINA_CMD_SET_PIN_MODE = 0x50, - NINA_CMD_SET_DIGITAL_WRITE = 0x51, - NINA_CMD_GET_DIGITAL_READ = 0x53, - NINA_CMD_SET_ANALOG_WRITE = 0x52, - NINA_CMD_GET_ANALOG_READ = 0x54, - - // File send/recv commands. - NINA_CMD_CMD_WRITE_FILE = 0x60, - NINA_CMD_CMD_READ_FILE = 0x61, - NINA_CMD_CMD_DELETE_FILE = 0x62, - NINA_CMD_CMD_EXISTS_FILE = 0x63, - NINA_CMD_CMD_DOWNLOAD_FILE = 0x64, - - // OTA upgrade commands. - NINA_CMD_CMD_APPLY_OTA = 0x65, - NINA_CMD_CMD_RENAME_FILE = 0x66, - NINA_CMD_CMD_DOWNLOAD_OTA = 0x67, -} nina_cmd_t; - -typedef enum { - NINA_STATUS_IDLE = 0, - NINA_STATUS_NO_SSID_AVAIL, - NINA_STATUS_SCAN_COMPLETED, - NINA_STATUS_CONNECTED, - NINA_STATUS_CONNECT_FAILED, - NINA_STATUS_CONNECTION_LOST, - NINA_STATUS_DISCONNECTED, - NINA_STATUS_AP_LISTENING, - NINA_STATUS_AP_CONNECTED, - NINA_STATUS_AP_FAILED -} nina_status_t; - -typedef enum { - SOCKET_STATE_CLOSED = 0, - SOCKET_STATE_LISTEN, - SOCKET_STATE_SYN_SENT, - SOCKET_STATE_SYN_RCVD, - SOCKET_STATE_ESTABLISHED, - SOCKET_STATE_FIN_WAIT_1, - SOCKET_STATE_FIN_WAIT_2, - SOCKET_STATE_CLOSE_WAIT, - SOCKET_STATE_CLOSING, - SOCKET_STATE_LAST_ACK, - SOCKET_STATE_TIME_WAIT -} nina_sock_state_t; - -static uint8_t nina_bsp_spi_read_byte(void) { - uint8_t byte = 0; - nina_bsp_spi_transfer(NULL, &byte, 1); - return byte; -} - -static int nina_wait_for_cmd(uint8_t cmd, uint32_t timeout) { - uint8_t buf = 0; - for (mp_uint_t start = mp_hal_ticks_ms(); ;) { - buf = nina_bsp_spi_read_byte(); - if (buf == CMD_ERROR || buf == cmd - || ((mp_hal_ticks_ms() - start) >= timeout)) { - break; - } - mp_hal_delay_ms(1); - } - - return (buf == cmd) ? 0 : -1; -} - -static int nina_send_command(uint32_t cmd, uint32_t nargs, uint32_t width, nina_args_t *args) { - int ret = -1; - uint32_t length = 4; // 3 bytes header + 1 end byte - - debug_printf("nina_send_command (cmd 0x%x nargs %d width %d): ", cmd, nargs, width); - - if (nina_bsp_spi_slave_select(NINA_SSELECT_TIMEOUT) != 0) { - return -1; - } - - // Send command header. - uint8_t cmdbuf_hdr[3] = {CMD_START, cmd, nargs}; - if (nina_bsp_spi_transfer(cmdbuf_hdr, NULL, sizeof(cmdbuf_hdr)) != 0) { - goto error_out; - } - - // Send command arg(s). - for (uint32_t i = 0; i < nargs; i++) { - // Send size MSB first if 2 bytes. - uint16_t size = (width == ARG_8BITS) ? args[i].size : __REVSH(args[i].size); - - // Send arg length. - if (nina_bsp_spi_transfer((uint8_t *)&size, NULL, width) != 0) { - goto error_out; - } - - // Send arg value. - if (nina_bsp_spi_transfer(args[i].data, NULL, args[i].size) != 0) { - goto error_out; - } - length += args[i].size + width; - } - - // Send END byte + padding to multiple of 4. - uint8_t cmdbuf_end[4] = {CMD_END, 0xFF, 0xFF, 0xFF}; - if (nina_bsp_spi_transfer(cmdbuf_end, NULL, 1 + (length % 4)) != 0) { - goto error_out; - } - - // All good - ret = 0; - -error_out: - debug_printf("\n"); - nina_bsp_spi_slave_deselect(); - return ret; -} - -static int nina_read_response(uint32_t cmd, uint32_t nvals, uint32_t width, nina_vals_t *vals) { - int ret = -1; - - debug_printf("nina_read_response(cmd 0x%x nvals %d width %d): ", cmd, nvals, width); - - // Read reply - if (nina_bsp_spi_slave_select(NINA_SSELECT_TIMEOUT) != 0) { - return -1; - } - - // Wait for CMD_START - if (nina_wait_for_cmd(CMD_START, NINA_RESPONSE_TIMEOUT) != 0) { - goto error_out; - } - - // Should return CMD + REPLY flag. - if (nina_bsp_spi_read_byte() != (cmd | CMD_REPLY)) { - goto error_out; - } - - // Sanity check the number of returned values. - // NOTE: This is to handle the special case for the scan command. - uint32_t rvals = nina_bsp_spi_read_byte(); - if (nvals > rvals) { - nvals = rvals; - } - - // Read return value(s). - for (uint32_t i = 0; i < nvals; i++) { - // Read return value size. - uint16_t bytes = nina_bsp_spi_read_byte(); - if (width == ARG_16BITS) { - bytes = (bytes << 8) | nina_bsp_spi_read_byte(); - } - - // Check the val fits the buffer. - if (*(vals[i].size) < bytes) { - goto error_out; - } - - // Read the returned value. - if (nina_bsp_spi_transfer(NULL, vals[i].data, bytes) != 0) { - goto error_out; - } - - // Set the size. - *(vals[i].size) = bytes; - } - - if (nina_bsp_spi_read_byte() != CMD_END) { - goto error_out; - } - - // All good - ret = 0; - -error_out: - debug_printf("\n"); - nina_bsp_spi_slave_deselect(); - return ret; -} - -static int nina_send_command_read_ack(uint32_t cmd, uint32_t nargs, uint32_t width, nina_args_t *args) { - uint16_t size = 1; - uint8_t rval = SPI_ERR; - if (nina_send_command(cmd, nargs, width, args) != 0 || - nina_read_response(cmd, 1, ARG_8BITS, NINA_VALS({&size, &rval})) != 0) { - return -1; - } - return rval; -} - -static int nina_send_command_read_vals(uint32_t cmd, uint32_t nargs, - uint32_t argsw, nina_args_t *args, uint32_t nvals, uint32_t valsw, nina_vals_t *vals) { - - if (nina_send_command(cmd, nargs, argsw, args) != 0 || - nina_read_response(cmd, nvals, valsw, vals) != 0) { - return -1; - } - return 0; -} - -static void nina_fix_mac_addr(uint8_t *mac) { - for (int i = 0; i < 3; i++) { - uint8_t b = mac[i]; - mac[i] = mac[5 - i]; - mac[5 - i] = b; - } -} - -int nina_init(void) { - // Initialize the BSP. - nina_bsp_init(); - return 0; -} - -int nina_deinit(void) { - return nina_bsp_deinit(); -} - -static int nina_connection_status() { - return nina_send_command_read_ack(NINA_CMD_CONN_STATUS, 0, ARG_8BITS, NULL); -} - -static int nina_socket_status(uint8_t fd) { - return nina_send_command_read_ack(NINA_CMD_SOCKET_STATE, - 1, ARG_8BITS, NINA_ARGS(ARG_BYTE(fd))); -} - -static int nina_server_socket_status(uint8_t fd) { - return nina_send_command_read_ack(NINA_CMD_SOCKET_STATE & 0xF9, - 1, ARG_8BITS, NINA_ARGS(ARG_BYTE(fd))); -} - -int nina_connect(const char *ssid, uint8_t security, const char *key, uint16_t channel) { - uint8_t status = NINA_STATUS_CONNECT_FAILED; - - if (key == NULL && security != NINA_SEC_OPEN) { - return -1; - } - - switch (security) { - case NINA_SEC_OPEN: - if (nina_send_command_read_ack(NINA_CMD_CONNECT_OPEN, - 1, ARG_8BITS, NINA_ARGS(ARG_STR(ssid))) != SPI_ACK) { - return -1; - } - break; - case NINA_SEC_WEP: - if (nina_send_command_read_ack(NINA_CMD_CONNECT_WEP, - 2, ARG_8BITS, NINA_ARGS(ARG_STR(ssid), ARG_STR(key))) != SPI_ACK) { - return -1; - } - break; - case NINA_SEC_WPA_PSK: - if (nina_send_command_read_ack(NINA_CMD_CONNECT_WPA, - 3, ARG_8BITS, NINA_ARGS(ARG_STR(ssid), ARG_BYTE(0), ARG_STR(key))) != SPI_ACK) { - return -1; - } - break; - default: - return -1; - } - - for (mp_uint_t start = mp_hal_ticks_ms(); ; mp_hal_delay_ms(10)) { - status = nina_connection_status(); - if ((status != NINA_STATUS_IDLE) && (status != NINA_STATUS_NO_SSID_AVAIL) && (status != NINA_STATUS_SCAN_COMPLETED)) { - break; - } - - if ((mp_hal_ticks_ms() - start) >= NINA_CONNECT_TIMEOUT) { - break; - } - } - - return (status == NINA_STATUS_CONNECTED) ? 0 : -1; -} - -int nina_start_ap(const char *ssid, uint8_t security, const char *key, uint16_t channel) { - uint8_t status = NINA_STATUS_AP_FAILED; - - if ((key == NULL && security != NINA_SEC_OPEN) || - (security != NINA_SEC_OPEN && security != NINA_SEC_WEP)) { - return -1; - } - - switch (security) { - case NINA_SEC_OPEN: - if (nina_send_command_read_ack(NINA_CMD_START_AP_OPEN, - 2, ARG_8BITS, NINA_ARGS(ARG_STR(ssid), ARG_BYTE(channel))) != SPI_ACK) { - return -1; - } - break; - case NINA_SEC_WEP: - if (nina_send_command_read_ack(NINA_CMD_START_AP_WEP, - 3, ARG_8BITS, NINA_ARGS(ARG_STR(ssid), ARG_STR(key), ARG_BYTE(channel))) != SPI_ACK) { - return -1; - } - break; - default: - return -1; - } - - for (mp_uint_t start = mp_hal_ticks_ms(); ; mp_hal_delay_ms(10)) { - status = nina_connection_status(); - if ((status != NINA_STATUS_IDLE) && (status != NINA_STATUS_NO_SSID_AVAIL) && (status != NINA_STATUS_SCAN_COMPLETED)) { - break; - } - - if ((mp_hal_ticks_ms() - start) >= NINA_CONNECT_TIMEOUT) { - break; - } - } - - return (status == NINA_STATUS_AP_LISTENING) ? 0 : -1; -} - -int nina_disconnect(void) { - if (nina_send_command_read_ack(NINA_CMD_DISCONNECT, - 1, ARG_8BITS, NINA_ARGS(ARG_BYTE(0xFF))) != SPI_ACK) { - return -1; - } - return 0; -} - -int nina_isconnected(void) { - int status = nina_connection_status(); - if (status == -1) { - return -1; - } - return status == NINA_STATUS_CONNECTED; -} - -int nina_connected_sta(uint32_t *sta_ip) { - return -1; -} - -int nina_wait_for_sta(uint32_t *sta_ip, uint32_t timeout) { - return NINA_ERROR_TIMEOUT; -} - -int nina_ifconfig(nina_ifconfig_t *ifconfig, bool set) { - uint16_t ip_len = NINA_IPV4_ADDR_LEN; - uint16_t sub_len = NINA_IPV4_ADDR_LEN; - uint16_t gw_len = NINA_IPV4_ADDR_LEN; - uint16_t dns_len = NINA_IPV4_ADDR_LEN; - - if (set) { - if (nina_send_command_read_ack(NINA_CMD_SET_IF_CONFIG, - 4, ARG_8BITS, - NINA_ARGS( - ARG_BYTE(3), // Valid number of args. - {ip_len, ifconfig->ip_addr}, - {gw_len, ifconfig->gateway_addr}, - {sub_len, ifconfig->subnet_addr})) != 0) { - return -1; - } - - uint8_t dns2[4] = {8, 8, 8, 8}; - if (nina_send_command_read_ack(NINA_CMD_SET_DNS_CONFIG, - 3, ARG_8BITS, - NINA_ARGS( - ARG_BYTE(1), // Valid number of args. - {dns_len, ifconfig->dns_addr}, - {dns_len, dns2})) != SPI_ACK) { - return -1; - } - - } else { - if (nina_send_command_read_vals(NINA_CMD_GET_IF_CONFIG, - 1, ARG_8BITS, NINA_ARGS(ARG_BYTE(0xFF)), - 3, ARG_8BITS, - NINA_VALS( - {&ip_len, ifconfig->ip_addr}, - {&sub_len, ifconfig->subnet_addr}, - {&gw_len, ifconfig->gateway_addr})) != 0) { - return -1; - } - // No command to get DNS ? - memcpy(ifconfig->dns_addr, ifconfig->gateway_addr, NINA_IPV4_ADDR_LEN); - } - return 0; -} - -int nina_netinfo(nina_netinfo_t *netinfo) { - uint16_t rssi_len = 4; - uint16_t sec_len = 1; - uint16_t ssid_len = NINA_MAX_SSID_LEN; - uint16_t bssid_len = NINA_MAC_ADDR_LEN; - - if (nina_send_command_read_vals(NINA_CMD_GET_RSSI, - 1, ARG_8BITS, NINA_ARGS(ARG_BYTE(0xFF)), - 1, ARG_8BITS, NINA_VALS({&rssi_len, &netinfo->rssi})) != 0) { - return -1; - } - - if (nina_send_command_read_vals(NINA_CMD_GET_ENCRYPT, - 1, ARG_8BITS, NINA_ARGS(ARG_BYTE(0xFF)), - 1, ARG_8BITS, NINA_VALS({&sec_len, &netinfo->security})) != 0) { - return -1; - } - - if (nina_send_command_read_vals(NINA_CMD_GET_SSID, - 1, ARG_8BITS, NINA_ARGS(ARG_BYTE(0xFF)), - 1, ARG_8BITS, NINA_VALS({&ssid_len, &netinfo->ssid})) != 0) { - return -1; - } - - // Null terminate SSID. - netinfo->ssid[MIN((NINA_MAX_SSID_LEN - 1), ssid_len)] = 0; - - if (nina_send_command_read_vals(NINA_CMD_GET_BSSID, - 1, ARG_8BITS, NINA_ARGS(ARG_BYTE(0xFF)), - 1, ARG_8BITS, NINA_VALS({&bssid_len, &netinfo->bssid})) != 0) { - return -1; - } - - // The MAC address is read in reverse from the firmware. - nina_fix_mac_addr(netinfo->bssid); - return 0; -} - -int nina_scan(nina_scan_callback_t scan_callback, void *arg, uint32_t timeout) { - uint16_t sizes[NINA_MAX_NETWORK_LIST]; - char ssids[NINA_MAX_NETWORK_LIST][NINA_MAX_SSID_LEN]; - nina_vals_t vals[NINA_MAX_NETWORK_LIST]; - - // Initialize the values list. - for (int i = 0; i < NINA_MAX_NETWORK_LIST; i++) { - sizes[i] = NINA_MAX_SSID_LEN - 1; - memset(ssids[i], 0, NINA_MAX_SSID_LEN); - vals[i].size = &sizes[i]; - vals[i].data = ssids[i]; - } - - if (nina_send_command_read_ack(NINA_CMD_AP_START_SCAN, - 0, ARG_8BITS, NULL) != SPI_ACK) { - return -1; - } - - for (mp_uint_t start = mp_hal_ticks_ms(); ;) { - if (nina_send_command_read_vals(NINA_CMD_AP_SCAN_RESULT, - 0, ARG_8BITS, NULL, - NINA_MAX_NETWORK_LIST, ARG_8BITS, vals) != 0) { - return -1; - } - - if (ssids[0][0] != 0) { - // Found at least 1 network. - break; - } - - if (timeout && (mp_hal_ticks_ms() - start) >= timeout) { - // Timeout, no networks. - return NINA_ERROR_TIMEOUT; - } - - mp_hal_delay_ms(100); - } - - for (int i = 0; i < NINA_MAX_NETWORK_LIST; i++) { - uint16_t rssi_len = 4; - uint16_t sec_len = 1; - uint16_t chan_len = 1; - uint16_t bssid_len = NINA_MAC_ADDR_LEN; - nina_scan_result_t scan_result; - - if (ssids[i][0] == 0) { - break; - } - - // Set AP SSID - strncpy(scan_result.ssid, ssids[i], NINA_MAX_SSID_LEN); - - // Read AP RSSI - if (nina_send_command_read_vals(NINA_CMD_AP_GET_RSSI, - 1, ARG_8BITS, NINA_ARGS(ARG_BYTE(i)), - 1, ARG_8BITS, NINA_VALS({&rssi_len, &scan_result.rssi})) != 0) { - return -1; - } - - // Read AP encryption type - if (nina_send_command_read_vals(NINA_CMD_AP_GET_ENCRYPT, - 1, ARG_8BITS, NINA_ARGS(ARG_BYTE(i)), - 1, ARG_8BITS, NINA_VALS({&sec_len, &scan_result.security})) != 0) { - return -1; - } - - // Read AP channel - if (nina_send_command_read_vals(NINA_CMD_AP_GET_CHANNEL, - 1, ARG_8BITS, NINA_ARGS(ARG_BYTE(i)), - 1, ARG_8BITS, NINA_VALS({&chan_len, &scan_result.channel})) != 0) { - return -1; - } - - // Read AP bssid - if (nina_send_command_read_vals(NINA_CMD_AP_GET_BSSID, - 1, ARG_8BITS, NINA_ARGS(ARG_BYTE(i)), - 1, ARG_8BITS, NINA_VALS({&bssid_len, scan_result.bssid})) != 0) { - return -1; - } - - // The MAC address is read in reverse from the firmware. - nina_fix_mac_addr(scan_result.bssid); - scan_callback(&scan_result, arg); - } - - return 0; -} - -int nina_get_rssi(void) { - uint16_t size = 4; - int32_t rssi = 0; - if (nina_send_command_read_vals(NINA_CMD_GET_RSSI, - 1, ARG_8BITS, NINA_ARGS(ARG_BYTE(0xFF)), - 1, ARG_8BITS, NINA_VALS({&size, &rssi})) != 0) { - return -1; - } - - return rssi; -} - -int nina_fw_version(uint8_t *fw_ver) { - uint16_t size = NINA_FW_VER_LEN; - if (nina_send_command_read_vals(NINA_CMD_GET_FW_VERSION, - 0, ARG_8BITS, NULL, - 1, ARG_8BITS, NINA_VALS({&size, fw_ver})) != 0) { - return -1; - } - return 0; -} - -int nina_set_hostname(const char *hostname) { - if (nina_send_command_read_ack(NINA_CMD_SET_HOSTNAME, - 1, ARG_8BITS, NINA_ARGS(ARG_STR(hostname))) != SPI_ACK) { - return -1; - } - return 0; -} - -int nina_gethostbyname(const char *name, uint8_t *out_ip) { - uint16_t size = 4; - - if (nina_send_command_read_ack(NINA_CMD_HOST_BY_NAME, - 1, ARG_8BITS, NINA_ARGS(ARG_STR(name))) != SPI_ACK) { - return -1; - } - - if (nina_send_command_read_vals(NINA_CMD_GET_HOST_BY_NAME, - 0, ARG_8BITS, NULL, - 1, ARG_8BITS, NINA_VALS({&size, out_ip})) != 0) { - return -1; - } - return 0; -} - -int nina_socket_socket(uint8_t type) { - uint16_t size = 1; - uint8_t sock = 0; - - if (nina_send_command_read_vals(NINA_CMD_SOCKET_OPEN, - 0, ARG_8BITS, NULL, - 1, ARG_8BITS, NINA_VALS({&size, &sock})) != 0) { - return -1; - } - return sock; -} - -int nina_socket_close(int fd) { - if (fd > 0 && fd < 255) { - if (nina_send_command_read_ack(NINA_CMD_SOCKET_CLOSE, - 1, ARG_8BITS, NINA_ARGS(ARG_BYTE(fd))) != SPI_ACK) { - return -1; - } - for (mp_uint_t start = mp_hal_ticks_ms(); ; mp_hal_delay_ms(10)) { - if (nina_socket_status(fd) == SOCKET_STATE_CLOSED) { - break; - } - if ((mp_hal_ticks_ms() - start) >= 5000) { - return NINA_ERROR_TIMEOUT; - } - } - } - return 0; -} - -int nina_socket_bind(int fd, uint8_t *ip, uint16_t port, int type) { - if (nina_send_command_read_ack(NINA_CMD_SOCKET_BIND, - 3, ARG_8BITS, - NINA_ARGS( - ARG_SHORT(__REVSH(port)), - ARG_BYTE(fd), - ARG_BYTE(type))) != SPI_ACK) { - return -1; - } - - // Only TCP sockets' states should be checked. - if (type == NINA_SOCKET_TYPE_TCP && - nina_server_socket_status(fd) != SOCKET_STATE_LISTEN) { - return -1; - } - return 0; -} - -int nina_socket_listen(int fd, uint32_t backlog) { - return 0; // No listen ? -} - -int nina_socket_accept(int fd, uint8_t *ip, uint16_t *port, int *fd_out, uint32_t timeout) { - uint16_t size = 2; - uint16_t sock = NO_SOCKET_AVAIL; - - if (nina_server_socket_status(fd) != SOCKET_STATE_LISTEN) { - return -1; - } - - for (mp_uint_t start = mp_hal_ticks_ms(); sock == 0 || sock == NO_SOCKET_AVAIL; mp_hal_delay_ms(10)) { - if (nina_send_command_read_vals(NINA_CMD_SOCKET_ACCEPT, - 1, ARG_8BITS, NINA_ARGS(ARG_BYTE(fd)), - 1, ARG_8BITS, NINA_VALS({&size, &sock})) != 0) { - return -1; - } - - if (timeout && (mp_hal_ticks_ms() - start) >= timeout) { - return NINA_ERROR_TIMEOUT; - } - } - - uint16_t port_len = 2; - uint16_t ip_len = NINA_IPV4_ADDR_LEN; - if (nina_send_command_read_vals(NINA_CMD_SOCKET_REMOTE_ADDR, - 1, ARG_8BITS, NINA_ARGS(ARG_BYTE(sock)), - 2, ARG_8BITS, NINA_VALS({&ip_len, ip}, {&port_len, port})) != 0) { - return -1; - } - *fd_out = sock; - *port = __REVSH(*port); - return 0; -} - -int nina_socket_connect(int fd, uint8_t *ip, uint16_t port, uint32_t timeout) { - if (nina_send_command_read_ack(NINA_CMD_SOCKET_CONNECT, - 4, ARG_8BITS, - NINA_ARGS( - ARG_WORD((*(uint32_t *)ip)), - ARG_SHORT(__REVSH(port)), - ARG_BYTE(fd), - ARG_BYTE(NINA_SOCKET_TYPE_TCP))) != SPI_ACK) { - return -1; - } - - for (mp_uint_t start = mp_hal_ticks_ms(); ; mp_hal_delay_ms(10)) { - int state = nina_socket_status(fd); - if (state == -1) { - return -1; - } - - if (state == SOCKET_STATE_ESTABLISHED) { - break; - } - - if (timeout && (mp_hal_ticks_ms() - start) >= timeout) { - return NINA_ERROR_TIMEOUT; - } - } - - return 0; -} - -int nina_socket_send(int fd, const uint8_t *buf, uint32_t len, uint32_t timeout) { - uint16_t size = 2; - uint16_t bytes = 0; - - if (nina_socket_status(fd) != SOCKET_STATE_ESTABLISHED) { - return -1; - } - - if (nina_send_command_read_vals(NINA_CMD_TCP_SEND, - 2, ARG_16BITS, NINA_ARGS(ARG_BYTE(fd), {len, buf}), - 1, ARG_8BITS, NINA_VALS({&size, &bytes})) != 0 || bytes <= 0) { - return -1; - } - - for (mp_uint_t start = mp_hal_ticks_ms(); ;) { - int resp = nina_send_command_read_ack(NINA_CMD_TCP_ACK, - 1, ARG_8BITS, NINA_ARGS(ARG_BYTE(fd))); - - if (resp == -1) { - return -1; - } - - if (resp == SPI_ACK) { - break; - } - - if (timeout && (mp_hal_ticks_ms() - start) >= timeout) { - return NINA_ERROR_TIMEOUT; - } - mp_hal_delay_ms(1); - } - - return bytes; -} - -int nina_socket_recv(int fd, uint8_t *buf, uint32_t len, uint32_t timeout) { - uint16_t bytes = 0; - - if (nina_socket_status(fd) != SOCKET_STATE_ESTABLISHED) { - return -1; - } - - for (mp_uint_t start = mp_hal_ticks_ms(); bytes == 0; mp_hal_delay_ms(1)) { - bytes = len; - if (nina_send_command_read_vals(NINA_CMD_TCP_RECV, - 2, ARG_16BITS, NINA_ARGS(ARG_BYTE(fd), ARG_SHORT(bytes)), - 1, ARG_16BITS, NINA_VALS({&bytes, buf})) != 0) { - return -1; - } - - if (timeout && (mp_hal_ticks_ms() - start) >= timeout) { - return NINA_ERROR_TIMEOUT; - } - } - return bytes; -} - -// Check from the upper layer if the socket is bound, if not then auto-bind it first. -int nina_socket_sendto(int fd, const uint8_t *buf, uint32_t len, uint8_t *ip, uint16_t port, uint32_t timeout) { - // TODO do we need to split the packet somewhere? - if (nina_send_command_read_ack(NINA_CMD_SOCKET_CONNECT, - 4, ARG_8BITS, - NINA_ARGS( - ARG_WORD((*(uint32_t *)ip)), - ARG_SHORT(__REVSH(port)), - ARG_BYTE(fd), - ARG_BYTE(NINA_SOCKET_TYPE_UDP))) != SPI_ACK) { - return -1; - } - - // Buffer length and socket number are passed as 16bits. - if (nina_send_command_read_ack(NINA_CMD_UDP_SEND, - 2, ARG_16BITS, NINA_ARGS(ARG_BYTE(fd), {len, buf})) != SPI_ACK) { - return -1; - } - - if (nina_send_command_read_ack(NINA_CMD_UDP_ACK, - 1, ARG_8BITS, NINA_ARGS(ARG_BYTE(fd))) != SPI_ACK) { - return -1; - } - - return 0; -} - -// Check from the upper layer if the socket is bound, if not then auto-bind it first. -int nina_socket_recvfrom(int fd, uint8_t *buf, uint32_t len, uint8_t *ip, uint16_t *port, uint32_t timeout) { - uint16_t bytes = 0; - uint16_t port_len = 2; - uint16_t ip_len = NINA_IPV4_ADDR_LEN; - - for (mp_uint_t start = mp_hal_ticks_ms(); bytes == 0; mp_hal_delay_ms(1)) { - bytes = len; - if (nina_send_command_read_vals(NINA_CMD_UDP_RECV, - 2, ARG_16BITS, NINA_ARGS(ARG_BYTE(fd), ARG_SHORT(bytes)), - 1, ARG_16BITS, NINA_VALS({&bytes, buf})) != 0) { - return -1; - } - - if (timeout && (mp_hal_ticks_ms() - start) >= timeout) { - return NINA_ERROR_TIMEOUT; - } - } - if (nina_send_command_read_vals(NINA_CMD_SOCKET_REMOTE_ADDR, - 1, ARG_8BITS, NINA_ARGS(ARG_BYTE(fd)), - 2, ARG_8BITS, NINA_VALS({&ip_len, ip}, {&port_len, port})) != 0) { - return -1; - } - - return bytes; -} - -int nina_socket_setsockopt(int fd, uint32_t level, uint32_t opt, const void *optval, uint32_t optlen) { - return -1; -} - -#endif // MICROPY_PY_NINAW10 diff --git a/src/omv/ports/rp2/modules/py_nina.c b/src/omv/ports/rp2/modules/py_nina.c deleted file mode 100644 index b746ef24c..000000000 --- a/src/omv/ports/rp2/modules/py_nina.c +++ /dev/null @@ -1,600 +0,0 @@ -/* - * This file is part of the OpenMV project. - * - * Copyright (c) 2013-2021 Ibrahim Abdelkader - * Copyright (c) 2013-2021 Kwabena W. Agyeman - * - * This work is licensed under the MIT license, see the file LICENSE for details. - * - * NINA-W10 Python module. - */ -#if MICROPY_PY_NINAW10 -#include -#include -#include -#include - -#include "py/nlr.h" -#include "py/mphal.h" -#include "py/objtuple.h" -#include "py/objlist.h" -#include "py/stream.h" -#include "py/runtime.h" - -#include "mperrno.h" -#include "shared/netutils/netutils.h" -#include "modnetwork.h" - -#include "nina.h" - -#define NINA_MIN(a,b) \ -({ \ - __typeof__ (a) _a = (a); \ - __typeof__ (b) _b = (b); \ - _a < _b ? _a : _b; \ -}) - - -#define NINA_MAX(a,b) \ -({ \ - __typeof__ (a) _a = (a); \ - __typeof__ (b) _b = (b); \ - _a > _b ? _a : _b; \ -}) - -typedef struct _nina_obj_t { - mp_obj_base_t base; - bool active; - uint32_t itf; -} nina_obj_t; - -// For auto-binding UDP sockets -#define BIND_PORT_RANGE_MIN (65000) -#define BIND_PORT_RANGE_MAX (65535) - -static uint16_t bind_port = BIND_PORT_RANGE_MIN; -static nina_obj_t nina_obj = {{(mp_obj_type_t*) &mod_network_nic_type_nina}, false, NINA_WIFI_MODE_STA}; - -// Initialise the module using the given SPI bus and pins and return a nina object. -static mp_obj_t py_nina_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) -{ - mp_arg_check_num(n_args, n_kw, 0, 1, false); - - nina_obj.active = false; - if (n_args == 0) { - nina_obj.itf = NINA_WIFI_MODE_STA; - } else { - nina_obj.itf = mp_obj_get_int(args[0]); - } - - // Reset autobind port. - bind_port = BIND_PORT_RANGE_MIN; - - // Register with network module - mod_network_register_nic(MP_OBJ_FROM_PTR(&nina_obj)); - - return MP_OBJ_FROM_PTR(&nina_obj); -} - -static mp_obj_t py_nina_active(size_t n_args, const mp_obj_t *args) -{ - nina_obj_t *self = MP_OBJ_TO_PTR(args[0]); - if (n_args == 2) { - bool active = mp_obj_is_true(args[1]); - if (active) { - int error = 0; - if ((error = nina_init()) != 0) { - mp_raise_msg_varg(&mp_type_OSError, - MP_ERROR_TEXT("Failed to initialize Nina-W10 module, error: %d\n"), error); - } - // check firmware version - uint8_t fw_ver[NINA_FW_VER_LEN]; - if (nina_fw_version(fw_ver) != 0) { - nina_deinit(); - mp_raise_msg_varg(&mp_type_OSError, - MP_ERROR_TEXT("Failed to read firmware version, error: %d\n"), error); - } - - // Check fw version matches the driver. - if ((fw_ver[NINA_FW_VER_MAJOR_OFFS] - 48) != NINA_FW_VER_MAJOR || - (fw_ver[NINA_FW_VER_MINOR_OFFS] - 48) != NINA_FW_VER_MINOR || - (fw_ver[NINA_FW_VER_PATCH_OFFS] - 48) != NINA_FW_VER_PATCH) { - mp_printf(&mp_plat_print, - "Warning: firmware version mismatch, expected %d.%d.%d found: %d.%d.%d\n", - NINA_FW_VER_MAJOR, NINA_FW_VER_MINOR, NINA_FW_VER_PATCH, - fw_ver[NINA_FW_VER_MAJOR_OFFS] - 48, - fw_ver[NINA_FW_VER_MINOR_OFFS] - 48, - fw_ver[NINA_FW_VER_PATCH_OFFS] - 48); - } - } else { - nina_deinit(); - } - self->active = active; - } - return mp_obj_new_bool(self->active); -} - -// method connect(ssid, key=None, *, security=WPA2, bssid=None) -static mp_obj_t py_nina_connect(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) -{ - static const mp_arg_t allowed_args[] = { - { MP_QSTR_essid, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, - { MP_QSTR_key, MP_ARG_OBJ, {.u_obj = mp_const_none} }, - { MP_QSTR_security, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = NINA_SEC_WPA_PSK} }, - { MP_QSTR_channel, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 1} }, - }; - - // parse args - nina_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); - mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; - mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - - // get ssid - const char *ssid = mp_obj_str_get_str(args[0].u_obj); - - if (strlen(ssid) == 0) { - mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("SSID can't be empty!")); - } - - // get key and sec - const char *key = NULL; - mp_uint_t security = NINA_SEC_OPEN; - - if (args[1].u_obj != mp_const_none) { - key = mp_obj_str_get_str(args[1].u_obj); - security = args[2].u_int; - } - - if (security != NINA_SEC_OPEN && strlen(key) == 0) { - mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("Key can't be empty!")); - } - - // Disconnect active connections first. - if (nina_isconnected()) { - nina_disconnect(); - } - - if (self->itf == NINA_WIFI_MODE_STA) { - // Initialize WiFi in Station mode. - if (nina_connect(ssid, security, key, 0) != 0) { - mp_raise_msg_varg(&mp_type_OSError, - MP_ERROR_TEXT("could not connect to ssid=%s, sec=%d, key=%s\n"), ssid, security, key); - } - } else { - mp_uint_t channel = args[3].u_int; - - if (security != NINA_SEC_OPEN && security != NINA_SEC_WEP) { - mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("AP mode supports WEP security only.")); - } - - // Initialize WiFi in AP mode. - if (nina_start_ap(ssid, security, key, channel) != 0) { - mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("failed to start in AP mode")); - } - } - return mp_const_none; -} - -static mp_obj_t py_nina_disconnect(mp_obj_t self_in) -{ - nina_disconnect(); - return mp_const_none; -} - -static mp_obj_t py_nina_isconnected(mp_obj_t self_in) -{ - return mp_obj_new_bool(nina_isconnected()); -} - -static mp_obj_t py_nina_connected_sta(mp_obj_t self_in) -{ - uint32_t sta_ip = 0; - mp_obj_t sta_list = mp_obj_new_list(0, NULL); - - if (nina_connected_sta(&sta_ip) == 0) { - mp_obj_list_append(sta_list, netutils_format_inet_addr( - (uint8_t*)&sta_ip, 0, NETUTILS_BIG)); - } - - return sta_list; -} - -static mp_obj_t py_nina_wait_for_sta(mp_obj_t self_in, mp_obj_t timeout_in) -{ - uint32_t sta_ip; - // get timeout - mp_obj_t sta_list = mp_obj_new_list(0, NULL); - mp_uint_t timeout = mp_obj_get_int(timeout_in); - - if (nina_wait_for_sta(&sta_ip, timeout) == 0) { - mp_obj_list_append(sta_list, netutils_format_inet_addr( - (uint8_t*)&sta_ip, 0, NETUTILS_BIG)); - } - - return sta_list; -} - -static mp_obj_t py_nina_ifconfig(size_t n_args, const mp_obj_t *args) -{ - nina_ifconfig_t ifconfig; - if (n_args == 1) { - // get ifconfig info - nina_ifconfig(&ifconfig, false); - mp_obj_t tuple[4] = { - netutils_format_ipv4_addr(ifconfig.ip_addr, NETUTILS_BIG), - netutils_format_ipv4_addr(ifconfig.subnet_addr, NETUTILS_BIG), - netutils_format_ipv4_addr(ifconfig.gateway_addr, NETUTILS_BIG), - netutils_format_ipv4_addr(ifconfig.dns_addr, NETUTILS_BIG), - }; - return mp_obj_new_tuple(4, tuple); - } else { - // set ifconfig info - mp_obj_t *items; - mp_obj_get_array_fixed_n(args[1], 4, &items); - netutils_parse_ipv4_addr(items[0], ifconfig.ip_addr, NETUTILS_BIG); - netutils_parse_ipv4_addr(items[1], ifconfig.subnet_addr, NETUTILS_BIG); - netutils_parse_ipv4_addr(items[2], ifconfig.gateway_addr, NETUTILS_BIG); - netutils_parse_ipv4_addr(items[3], ifconfig.dns_addr, NETUTILS_BIG); - nina_ifconfig(&ifconfig, true); - return mp_const_none; - } -} - -static mp_obj_t py_nina_netinfo(mp_obj_t self_in) -{ - nina_netinfo_t netinfo; - nina_netinfo(&netinfo); - - // Format MAC address - VSTR_FIXED(bssid_vstr, 18); - vstr_printf(&bssid_vstr, "%02x:%02x:%02x:%02x:%02x:%02x", - netinfo.bssid[0], netinfo.bssid[1], netinfo.bssid[2], - netinfo.bssid[3], netinfo.bssid[4], netinfo.bssid[5]); - - // Add connection info - mp_obj_t tuple[4] = { - mp_obj_new_int(netinfo.rssi), - mp_obj_new_int(netinfo.security), - mp_obj_new_str(netinfo.ssid, strlen(netinfo.ssid)), - mp_obj_new_str(bssid_vstr.buf, bssid_vstr.len), - }; - return mp_obj_new_tuple(4, tuple); -} - -static int nina_scan_callback(nina_scan_result_t *scan_result, void *arg) -{ - mp_obj_t scan_list = (mp_obj_t)arg; - mp_obj_t ap[6] = { - mp_obj_new_bytes((uint8_t *)scan_result->ssid, strlen(scan_result->ssid)), - mp_obj_new_bytes(scan_result->bssid, sizeof(scan_result->bssid)), - mp_obj_new_int(scan_result->channel), - mp_obj_new_int(scan_result->rssi), - mp_obj_new_int(scan_result->security), - MP_OBJ_NEW_SMALL_INT(1), // N - }; - mp_obj_list_append(scan_list, mp_obj_new_tuple(MP_ARRAY_SIZE(ap), ap)); - return 0; -} - -static mp_obj_t py_nina_scan(mp_obj_t self_in) -{ - mp_obj_t scan_list; - scan_list = mp_obj_new_list(0, NULL); - nina_scan(nina_scan_callback, scan_list, 10000); - return scan_list; -} - -static mp_obj_t py_nina_get_rssi(mp_obj_t self_in) -{ - return mp_obj_new_int(nina_get_rssi()); -} - -static mp_obj_t py_nina_fw_version(mp_obj_t self_in) -{ - uint8_t fwver[NINA_FW_VER_LEN]; - nina_fw_version(fwver); - - // Firmware version is a string like "1.4.7" - mp_obj_tuple_t *t_fwver = mp_obj_new_tuple(3, NULL); - for (int i=0; i<3; i++) { - t_fwver->items[i] = mp_obj_new_int(fwver[i*2] - 48); - } - return t_fwver; -} - -static int py_nina_gethostbyname(mp_obj_t nic, const char *name, mp_uint_t len, uint8_t *out_ip) -{ - return nina_gethostbyname(name, out_ip); -} - -static int py_nina_socket_socket(mod_network_socket_obj_t *socket, int *_errno) -{ - uint8_t type; - - if (socket->domain != MOD_NETWORK_AF_INET) { - *_errno = MP_EAFNOSUPPORT; - return -1; - } - - switch (socket->type) { - case MOD_NETWORK_SOCK_STREAM: - type = NINA_SOCKET_TYPE_TCP; - break; - - case MOD_NETWORK_SOCK_DGRAM: - type = NINA_SOCKET_TYPE_UDP; - break; - - default: - *_errno = MP_EINVAL; - return -1; - } - - // open socket - int fd = nina_socket_socket(type); - if (fd < 0) { - *_errno = fd; - return -1; - } - - // store state of this socket - socket->fd = fd; - socket->timeout = 0; // blocking - socket->port = 0; - socket->bound = false; - return 0; -} - -static void py_nina_socket_close(mod_network_socket_obj_t *socket) -{ - if (socket->fd >= 0) { - nina_socket_close(socket->fd); - socket->fd = -1; // Mark socket FD as invalid - } -} - -static int py_nina_socket_bind(mod_network_socket_obj_t *socket, byte *ip, mp_uint_t port, int *_errno) -{ - uint8_t type; - switch (socket->type) { - case MOD_NETWORK_SOCK_STREAM: - type = NINA_SOCKET_TYPE_TCP; - break; - - case MOD_NETWORK_SOCK_DGRAM: - type = NINA_SOCKET_TYPE_UDP; - break; - - default: - *_errno = MP_EINVAL; - return -1; - } - - int ret = nina_socket_bind(socket->fd, ip, port, type); - if (ret < 0) { - *_errno = ret; - py_nina_socket_close(socket); - return -1; - } - - // Set bound port and mark socket as bound to avoid auto-binding. - socket->port = port; - socket->bound = true; - return 0; -} - -static int py_nina_socket_listen(mod_network_socket_obj_t *socket, mp_int_t backlog, int *_errno) -{ - int ret = nina_socket_listen(socket->fd, backlog); - if (ret < 0) { - *_errno = ret; - py_nina_socket_close(socket); - return -1; - } - return 0; -} - -static int py_nina_socket_accept(mod_network_socket_obj_t *socket, - mod_network_socket_obj_t *socket2, byte *ip, mp_uint_t *port, int *_errno) -{ - int fd = 0; - // Call accept. - int ret = nina_socket_accept(socket->fd, ip, (uint16_t*) port, &fd, socket->timeout); - if (ret < 0) { - *_errno = ret; - py_nina_socket_close(socket); - return -1; - } - - // Set default socket timeout. - socket2->fd = fd; - socket2->timeout = 0; - socket2->bound = false; - return 0; -} - -static int py_nina_socket_connect(mod_network_socket_obj_t *socket, byte *ip, mp_uint_t port, int *_errno) -{ - int ret = nina_socket_connect(socket->fd, ip, port, socket->timeout); - if (ret < 0) { - *_errno = ret; - py_nina_socket_close(socket); - return -1; - } - return 0; -} - -static mp_uint_t py_nina_socket_send(mod_network_socket_obj_t *socket, const byte *buf, mp_uint_t len, int *_errno) -{ - int ret = nina_socket_send(socket->fd, buf, len, socket->timeout); - if (ret == NINA_ERROR_TIMEOUT) { - // The socket is Not closed on timeout when calling functions that accept a timeout. - *_errno = MP_ETIMEDOUT; - return -1; - } else if (ret < 0) { - // Close the socket on any other errors. - *_errno = ret; - py_nina_socket_close(socket); - return -1; - } - return ret; -} - -static mp_uint_t py_nina_socket_recv(mod_network_socket_obj_t *socket, byte *buf, mp_uint_t len, int *_errno) -{ - int ret = nina_socket_recv(socket->fd, buf, len, socket->timeout); - if (ret == NINA_ERROR_TIMEOUT) { - // The socket is Not closed on timeout when calling functions that accept a timeout. - *_errno = MP_ETIMEDOUT; - return -1; - } else if (ret < 0) { - // Close the socket on any other errors. - *_errno = ret; - py_nina_socket_close(socket); - return -1; - } - return ret; -} - -static mp_uint_t py_nina_socket_auto_bind(mod_network_socket_obj_t *socket, int *_errno) -{ - if (socket->bound == false) { - if (py_nina_socket_bind(socket, NULL, bind_port, _errno) != 0) { - return -1; - } - bind_port++; - bind_port = NINA_MIN(NINA_MAX(bind_port, BIND_PORT_RANGE_MIN), BIND_PORT_RANGE_MAX); - } - return 0; -} - -static mp_uint_t py_nina_socket_sendto(mod_network_socket_obj_t *socket, - const byte *buf, mp_uint_t len, byte *ip, mp_uint_t port, int *_errno) -{ - // Auto-bind the socket first if the socket is unbound. - if (py_nina_socket_auto_bind(socket, _errno) != 0) { - return -1; - } - - int ret = nina_socket_sendto(socket->fd, buf, len, ip, port, socket->timeout); - if (ret == NINA_ERROR_TIMEOUT) { - // The socket is Not closed on timeout when calling functions that accept a timeout. - *_errno = MP_ETIMEDOUT; - return -1; - } else if (ret < 0) { - *_errno = ret; - py_nina_socket_close(socket); - return -1; - } - return ret; -} - -static mp_uint_t py_nina_socket_recvfrom(mod_network_socket_obj_t *socket, - byte *buf, mp_uint_t len, byte *ip, mp_uint_t *port, int *_errno) -{ - // Auto-bind the socket first if the socket is unbound. - if (py_nina_socket_auto_bind(socket, _errno) != 0) { - return -1; - } - - int ret = nina_socket_recvfrom(socket->fd, buf, len, ip, (uint16_t *) port, socket->timeout); - if (ret == NINA_ERROR_TIMEOUT) { - // The socket is Not closed on timeout when calling functions that accept a timeout. - *_errno = MP_ETIMEDOUT; - return -1; - } else if (ret < 0) { - // Close the socket on any other errors. - *_errno = ret; - py_nina_socket_close(socket); - return -1; - } - return ret; -} - -static int py_nina_socket_setsockopt(mod_network_socket_obj_t *socket, mp_uint_t - level, mp_uint_t opt, const void *optval, mp_uint_t optlen, int *_errno) -{ - int ret = nina_socket_setsockopt(socket->fd, level, opt, optval, optlen); - if (ret < 0) { - *_errno = ret; - py_nina_socket_close(socket); - return -1; - } - return 0; -} - -static int py_nina_socket_settimeout(mod_network_socket_obj_t *socket, mp_uint_t timeout_ms, int *_errno) -{ - if (timeout_ms == UINT32_MAX) { - // no timeout is given, set the socket to blocking mode. - timeout_ms = 0; - } - socket->timeout = timeout_ms; - return 0; -} - -static int py_nina_socket_ioctl(mod_network_socket_obj_t *socket, mp_uint_t request, mp_uint_t arg, int *_errno) -{ - *_errno = MP_EIO; - return -1; -} - -static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(py_nina_active_obj, 1, 2, py_nina_active); -static MP_DEFINE_CONST_FUN_OBJ_KW(py_nina_connect_obj, 1, py_nina_connect); -static MP_DEFINE_CONST_FUN_OBJ_1(py_nina_disconnect_obj, py_nina_disconnect); -static MP_DEFINE_CONST_FUN_OBJ_1(py_nina_isconnected_obj, py_nina_isconnected); -static MP_DEFINE_CONST_FUN_OBJ_1(py_nina_connected_sta_obj, py_nina_connected_sta); -static MP_DEFINE_CONST_FUN_OBJ_2(py_nina_wait_for_sta_obj, py_nina_wait_for_sta); -static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(py_nina_ifconfig_obj, 1, 2, py_nina_ifconfig); -static MP_DEFINE_CONST_FUN_OBJ_1(py_nina_netinfo_obj, py_nina_netinfo); -static MP_DEFINE_CONST_FUN_OBJ_1(py_nina_scan_obj, py_nina_scan); -static MP_DEFINE_CONST_FUN_OBJ_1(py_nina_get_rssi_obj, py_nina_get_rssi); -static MP_DEFINE_CONST_FUN_OBJ_1(py_nina_fw_version_obj, py_nina_fw_version); - -static const mp_rom_map_elem_t nina_locals_dict_table[] = { - { MP_ROM_QSTR(MP_QSTR_active), MP_ROM_PTR(&py_nina_active_obj) }, - { MP_ROM_QSTR(MP_QSTR_connect), MP_ROM_PTR(&py_nina_connect_obj) }, - { MP_ROM_QSTR(MP_QSTR_config), MP_ROM_PTR(&py_nina_connect_obj) }, - { MP_ROM_QSTR(MP_QSTR_start_ap), MP_ROM_PTR(&py_nina_connect_obj) }, - { MP_ROM_QSTR(MP_QSTR_disconnect), MP_ROM_PTR(&py_nina_disconnect_obj) }, - { MP_ROM_QSTR(MP_QSTR_isconnected), MP_ROM_PTR(&py_nina_isconnected_obj) }, - { MP_ROM_QSTR(MP_QSTR_connected_sta), MP_ROM_PTR(&py_nina_connected_sta_obj) }, - { MP_ROM_QSTR(MP_QSTR_wait_for_sta), MP_ROM_PTR(&py_nina_wait_for_sta_obj) }, - { MP_ROM_QSTR(MP_QSTR_ifconfig), MP_ROM_PTR(&py_nina_ifconfig_obj) }, - { MP_ROM_QSTR(MP_QSTR_netinfo), MP_ROM_PTR(&py_nina_netinfo_obj) }, - { MP_ROM_QSTR(MP_QSTR_scan), MP_ROM_PTR(&py_nina_scan_obj) }, - { MP_ROM_QSTR(MP_QSTR_rssi), MP_ROM_PTR(&py_nina_get_rssi_obj) }, - { MP_ROM_QSTR(MP_QSTR_fw_version), MP_ROM_PTR(&py_nina_fw_version_obj) }, - // Network is not secured. - { MP_ROM_QSTR(MP_QSTR_OPEN), MP_ROM_INT(NINA_SEC_OPEN) }, - // Security type WEP (40 or 104). - { MP_ROM_QSTR(MP_QSTR_WEP), MP_ROM_INT(NINA_SEC_WEP) }, - // Network secured with WPA/WPA2 personal(PSK). - { MP_ROM_QSTR(MP_QSTR_WPA_PSK), MP_ROM_INT(NINA_SEC_WPA_PSK) }, -}; - -static MP_DEFINE_CONST_DICT(nina_locals_dict, nina_locals_dict_table); - -const mod_network_nic_type_t mod_network_nic_type_nina = { - .base = { - { &mp_type_type }, - .name = MP_QSTR_nina, - .make_new = py_nina_make_new, - .locals_dict = (mp_obj_t)&nina_locals_dict, - }, - .gethostbyname = py_nina_gethostbyname, - .socket = py_nina_socket_socket, - .close = py_nina_socket_close, - .bind = py_nina_socket_bind, - .listen = py_nina_socket_listen, - .accept = py_nina_socket_accept, - .connect = py_nina_socket_connect, - .send = py_nina_socket_send, - .recv = py_nina_socket_recv, - .sendto = py_nina_socket_sendto, - .recvfrom = py_nina_socket_recvfrom, - .setsockopt = py_nina_socket_setsockopt, - .settimeout = py_nina_socket_settimeout, - .ioctl = py_nina_socket_ioctl, -}; -#endif // MICROPY_PY_NINAW10 diff --git a/src/omv/ports/rp2/nina_bsp.c b/src/omv/ports/rp2/nina_bsp.c deleted file mode 100644 index de6cdffa0..000000000 --- a/src/omv/ports/rp2/nina_bsp.c +++ /dev/null @@ -1,142 +0,0 @@ -/* - * This file is part of the OpenMV project. - * - * Copyright (c) 2013-2021 Ibrahim Abdelkader - * Copyright (c) 2013-2021 Kwabena W. Agyeman - * - * This work is licensed under the MIT license, see the file LICENSE for details. - * - * NINA-W10 driver BSP implementation. - */ -#if MICROPY_PY_NINAW10 -#include -#include -#include "py/mphal.h" - -#include "pico/stdlib.h" -#include "hardware/spi.h" -#include "omv_boardconfig.h" - -#include "nina.h" -#include "nina_bsp.h" - -#define debug_printf(...) mp_printf(&mp_plat_print, __VA_ARGS__) - -int nina_bsp_init() -{ - gpio_init(WIFI_CS_PIN); - gpio_set_dir(WIFI_CS_PIN, GPIO_OUT); - - gpio_init(WIFI_ACK_PIN); - gpio_set_dir(WIFI_ACK_PIN, GPIO_IN); - gpio_set_pulls(WIFI_ACK_PIN, true, false); - - gpio_init(WIFI_RST_PIN); - gpio_set_dir(WIFI_RST_PIN, GPIO_OUT); - - gpio_init(WIFI_GPIO0_PIN); - gpio_set_dir(WIFI_GPIO0_PIN, GPIO_OUT); - - gpio_init(WIFI_SCLK_PIN); - gpio_set_function(WIFI_SCLK_PIN, GPIO_FUNC_SPI); - - gpio_init(WIFI_MOSI_PIN); - gpio_set_function(WIFI_MOSI_PIN, GPIO_FUNC_SPI); - - gpio_init(WIFI_MISO_PIN); - gpio_set_function(WIFI_MISO_PIN, GPIO_FUNC_SPI); - - // Reset module in WiFi mode - gpio_put(WIFI_CS_PIN, 1); - gpio_put(WIFI_GPIO0_PIN, 1); - - gpio_put(WIFI_RST_PIN, 0); - mp_hal_delay_ms(100); - - gpio_put(WIFI_RST_PIN, 1); - mp_hal_delay_ms(750); - - gpio_put(WIFI_GPIO0_PIN, 0); - gpio_set_dir(WIFI_GPIO0_PIN, GPIO_IN); - gpio_set_pulls(WIFI_GPIO0_PIN, true, false); - - // Initialize SPI. - spi_init(WIFI_SPI, 8 * 1000 * 1000); - spi_set_slave(WIFI_SPI, false); - spi_set_format(WIFI_SPI, 8, SPI_CPOL_0, SPI_CPHA_0, SPI_MSB_FIRST); - return 0; -} - -int nina_bsp_deinit() -{ - gpio_init(WIFI_CS_PIN); - gpio_set_dir(WIFI_CS_PIN, GPIO_OUT); - gpio_put(WIFI_CS_PIN, 1); - - gpio_init(WIFI_RST_PIN); - gpio_set_dir(WIFI_RST_PIN, GPIO_OUT); - gpio_put(WIFI_RST_PIN, 0); - mp_hal_delay_ms(100); - - gpio_init(WIFI_GPIO0_PIN); - gpio_set_dir(WIFI_GPIO0_PIN, GPIO_OUT); - gpio_put(WIFI_GPIO0_PIN, 1); - return 0; -} - -int nina_bsp_read_irq() -{ - return gpio_get(WIFI_GPIO0_PIN); -} - -int nina_bsp_spi_slave_select(uint32_t timeout) -{ - // Wait for ACK to go low. - for (mp_uint_t start = mp_hal_ticks_ms(); gpio_get(WIFI_ACK_PIN) == 1; mp_hal_delay_ms(1)) { - if ((mp_hal_ticks_ms() - start) >= timeout) { - return -1; - } - } - - // Chip select. - gpio_put(WIFI_CS_PIN, 0); - - // Wait for ACK to go high. - for (mp_uint_t start = mp_hal_ticks_ms(); gpio_get(WIFI_ACK_PIN) == 0; mp_hal_delay_ms(1)) { - if ((mp_hal_ticks_ms() - start) >= 100) { - gpio_put(WIFI_CS_PIN, 1); - return -1; - } - } - - return 0; -} - -int nina_bsp_spi_slave_deselect() -{ - gpio_put(WIFI_CS_PIN, 1); - return 0; -} - -int nina_bsp_spi_transfer(const uint8_t *tx_buf, uint8_t *rx_buf, uint32_t size) -{ - int rsize = 0; - if (tx_buf && rx_buf) { - rsize = spi_write_read_blocking(WIFI_SPI, tx_buf, rx_buf, size); - } else if (tx_buf) { - rsize = spi_write_blocking(WIFI_SPI, tx_buf, size); - } else if (rx_buf) { - rsize = spi_read_blocking(WIFI_SPI, 0xFF, rx_buf, size); - } - #if NINA_DEBUG - for (int i=0; i