diff --git a/extmod/network_wiznet5k.c b/extmod/network_wiznet5k.c index b8ca075b3d..e881d1cd92 100644 --- a/extmod/network_wiznet5k.c +++ b/extmod/network_wiznet5k.c @@ -37,6 +37,7 @@ #if MICROPY_PY_NETWORK_WIZNET5K #include "shared/netutils/netutils.h" +#include "shared/runtime/softtimer.h" #include "extmod/modnetwork.h" #include "extmod/modmachine.h" #include "extmod/virtpin.h" @@ -74,6 +75,14 @@ #include "lib/wiznet5k/Internet/DNS/dns.h" #include "lib/wiznet5k/Internet/DHCP/dhcp.h" +// Poll WIZnet every 64ms by default (if not using interrupt pin) +#define WIZNET5K_TICK_RATE_MS 64 +// In DHCP.c, RIP_MSG max size is defined as 312 + 256 (sadly, not in the header) +#define MAX_DHCP_BUF_SIZE 568 + +// Soft timer for polling and running DHCP in the background. +static soft_timer_entry_t mp_network_soft_timer; + #endif #ifndef printf @@ -99,9 +108,9 @@ typedef struct _wiznet5k_obj_t { void (*spi_transfer)(mp_obj_base_t *obj, size_t len, const uint8_t *src, uint8_t *dest); mp_hal_pin_obj_t cs; mp_hal_pin_obj_t rst; - #if WIZNET5K_WITH_LWIP_STACK mp_hal_pin_obj_t pin_intn; bool use_interrupt; + #if WIZNET5K_WITH_LWIP_STACK uint8_t eth_frame[1514]; uint32_t trace_flags; struct netif netif; @@ -110,9 +119,21 @@ typedef struct _wiznet5k_obj_t { wiz_NetInfo netinfo; uint8_t socket_used; bool active; + uint8_t *dhcp_buf; + uint8_t dhcp_retry; + uint8_t dhcp_state; + mp_int_t dhcp_socket; + uint32_t dhcp_timeout; #endif } wiznet5k_obj_t; +#if WIZNET5K_PROVIDED_STACK +typedef struct _wiznet5k_socket_extra_t { + byte remote_ip[4]; + mp_uint_t remote_port; +} wiznet5k_socket_extra_t; +#endif + #if WIZNET5K_WITH_LWIP_STACK #define IS_ACTIVE(self) (self->netif.flags & NETIF_FLAG_UP) #else // WIZNET5K_PROVIDED_STACK @@ -170,11 +191,7 @@ static void wiznet5k_get_mac_address(wiznet5k_obj_t *self, uint8_t mac[6]) { getSHAR(mac); } -#if WIZNET5K_WITH_LWIP_STACK - void wiznet5k_try_poll(void); -static void wiznet5k_lwip_init(wiznet5k_obj_t *self); - static mp_obj_t mpy_wiznet_read_int(mp_obj_t none_in) { (void)none_in; // Handle incoming data, unless the SPI bus is busy @@ -197,6 +214,9 @@ static void wiznet5k_config_interrupt(bool enabled) { ); } +#if WIZNET5K_WITH_LWIP_STACK +static void wiznet5k_lwip_init(wiznet5k_obj_t *self); + void wiznet5k_deinit(void) { for (struct netif *netif = netif_list; netif != NULL; netif = netif->next) { if (netif == &wiznet5k_obj.netif) { @@ -350,6 +370,59 @@ void wiznet5k_poll(void) { #if WIZNET5K_PROVIDED_STACK +static mp_int_t wiznet5k_allocate_socket(void) { + // get first unused socket number + for (mp_uint_t sn = 0; sn < _WIZCHIP_SOCK_NUM_; sn++) { + if ((wiznet5k_obj.socket_used & (1 << sn)) == 0) { + wiznet5k_obj.socket_used |= (1 << sn); + return sn; + } + } + + return -1; +} + +extern uint8_t DHCP_SOCKET; +static void wiznet5k_dhcp_poll(void) { + if (wiznet5k_obj.dhcp_socket != -1) { + wiznet5k_obj.dhcp_state = DHCP_run(); + } + + if (wiznet5k_obj.dhcp_state == DHCP_IP_LEASED) { + // Every few seconds, check in about renewing the IP + if (wiznet5k_obj.dhcp_socket != -1) { + // Release socket and reset timeout + wiznet5k_obj.socket_used &= ~(1 << wiznet5k_obj.dhcp_socket); + wiznet5k_obj.dhcp_socket = -1; + + // Run about once per minute + wiznet5k_obj.dhcp_timeout = mp_hal_ticks_ms() + 60000; + } else if (mp_hal_ticks_ms() > wiznet5k_obj.dhcp_timeout) { + mp_uint_t sn = wiznet5k_allocate_socket(); + if (sn != -1) { + DHCP_SOCKET = sn; + wiznet5k_obj.dhcp_socket = sn; + wiznet5k_obj.dhcp_state = DHCP_run(); + } + } + } else if (wiznet5k_obj.dhcp_state == DHCP_FAILED || wiznet5k_obj.dhcp_state == DHCP_STOPPED) { + if (wiznet5k_obj.dhcp_socket != -1) { + wiznet5k_obj.socket_used &= ~(1 << wiznet5k_obj.dhcp_socket); + wiznet5k_obj.dhcp_socket = -1; + } + } +} + +void wiznet5k_try_poll(void) { + // If using DHCP for the interface, periodically renew/update the address + wiznet5k_dhcp_poll(); + + // There's really nothing to do here. The interrupt that triggered this will + // release a WFE() wait and will trigger a poll() loop which will + // wiznet5k_socket_ioctl will detect the readable or writeable state of the + // respective socket(s). +} + static void wiz_dhcp_assign(void) { getIPfromDHCP(wiznet5k_obj.netinfo.ip); getGWfromDHCP(wiznet5k_obj.netinfo.gw); @@ -359,7 +432,7 @@ static void wiz_dhcp_assign(void) { } static void wiz_dhcp_update(void) { - ; + wiz_dhcp_assign(); } @@ -367,6 +440,22 @@ static void wiz_dhcp_conflict(void) { ; } +// This is called by soft_timer and executes at PendSV level. +static void mp_network_soft_timer_callback(soft_timer_entry_t *self) { + wiznet5k_try_poll(); +} + +static void mod_network_wiznet5k_poll_init(void) { + soft_timer_static_init( + &mp_network_soft_timer, + SOFT_TIMER_MODE_PERIODIC, + WIZNET5K_TICK_RATE_MS, + mp_network_soft_timer_callback + ); + + soft_timer_reinsert(&mp_network_soft_timer, WIZNET5K_TICK_RATE_MS); +} + static void wiznet5k_init(void) { // Configure wiznet provided TCP / socket interface @@ -388,21 +477,46 @@ static void wiznet5k_init(void) { }; wiznet5k_obj.netinfo = netinfo; + if (wiznet5k_obj.use_interrupt) { + mp_hal_pin_input(wiznet5k_obj.pin_intn); + wiznet5k_config_interrupt(true); + wizchip_setinterruptmask(IK_SOCK_ALL); + + #if _WIZCHIP_ == W5100S + // Enable interrupt pin + setMR2(getMR2() | MR2_G_IEN); + #endif + } + // register with network module mod_network_register_nic(&wiznet5k_obj); + mod_network_wiznet5k_poll_init(); wiznet5k_obj.active = true; + wiznet5k_obj.dhcp_socket = -1; + wiznet5k_obj.dhcp_state = DHCP_STOPPED; } static int wiznet5k_gethostbyname(mp_obj_t nic, const char *name, mp_uint_t len, uint8_t *out_ip) { uint8_t dns_ip[MOD_NETWORK_IPADDR_BUF_SIZE] = {8, 8, 8, 8}; uint8_t *buf = m_new(uint8_t, MAX_DNS_BUF_SIZE); - DNS_init(2, buf); + mp_int_t sn = wiznet5k_allocate_socket(); + if (sn == -1) { + return -2; + } + + DNS_init(sn, buf); if (wiznet5k_obj.netinfo.dns[0]) { memcpy(dns_ip, wiznet5k_obj.netinfo.dns, MOD_NETWORK_IPADDR_BUF_SIZE); } mp_int_t ret = DNS_run(dns_ip, (uint8_t *)name, out_ip); m_del(uint8_t, buf, MAX_DNS_BUF_SIZE); + + // NOTE: DNS_run will close the socket, so it just needs to be marked as + // unused here and clear any interrupts. + wiznet5k_obj.socket_used &= ~(1 << sn); + wizchip_clrinterrupt(IK_SOCK_0 << sn); + if (ret == 1) { // success return 0; @@ -432,18 +546,19 @@ static int wiznet5k_socket_socket(mod_network_socket_obj_t *socket, int *_errno) if (socket->fileno == -1) { // get first unused socket number - for (mp_uint_t sn = 0; sn < _WIZCHIP_SOCK_NUM_; sn++) { - if ((wiznet5k_obj.socket_used & (1 << sn)) == 0) { - wiznet5k_obj.socket_used |= (1 << sn); - socket->fileno = sn; - break; - } - } + socket->fileno = wiznet5k_allocate_socket(); if (socket->fileno == -1) { // too many open sockets *_errno = MP_EMFILE; return -1; } + + socket->_private = NULL; + + // Enable data receive interrupt + if (wiznet5k_obj.use_interrupt) { + setSn_IMR(socket->fileno, (Sn_IR_RECV | Sn_IR_CON | Sn_IR_DISCON)); + } } // WIZNET does not have a concept of pure "open socket". You need to know @@ -461,12 +576,27 @@ static void wiznet5k_socket_close(mod_network_socket_obj_t *socket) { if (sn < _WIZCHIP_SOCK_NUM_) { wiznet5k_obj.socket_used &= ~(1 << sn); WIZCHIP_EXPORT(close)(sn); + + // Disable receive interrupts + if (wiznet5k_obj.use_interrupt) { + setSn_IMR(sn, 0); + } } + + m_del(wiznet5k_socket_extra_t, socket->_private, 1); + socket->_private = NULL; } static int wiznet5k_socket_bind(mod_network_socket_obj_t *socket, byte *ip, mp_uint_t port, int *_errno) { + uint8_t flag = 0; + if (socket->timeout == 0) { + // Setup non-blocking mode + flag |= SOCK_IO_NONBLOCK; + } + // open the socket in server mode (if port != 0) - mp_int_t ret = WIZCHIP_EXPORT(socket)(socket->fileno, socket->type, port, 0); + mp_int_t ret = WIZCHIP_EXPORT(socket)(socket->fileno, socket->type, port, flag); + if (ret < 0) { wiznet5k_socket_close(socket); *_errno = -ret; @@ -531,22 +661,51 @@ static int wiznet5k_socket_connect(mod_network_socket_obj_t *socket, byte *ip, m return -1; } - // now connect - MP_THREAD_GIL_EXIT(); - mp_int_t ret = WIZCHIP_EXPORT(connect)(socket->fileno, ip, port); - MP_THREAD_GIL_ENTER(); + // WIZnet doesn't support connect on UDP sockets. TODO: Stash the remote + // information for use with the ::send method, if used on this UDP socket. + if (socket->type == Sn_MR_TCP) { + // now connect + MP_THREAD_GIL_EXIT(); + mp_int_t ret = WIZCHIP_EXPORT(connect)(socket->fileno, ip, port); + MP_THREAD_GIL_ENTER(); - if (ret < 0) { - wiznet5k_socket_close(socket); - *_errno = -ret; - return -1; + if (ret < 0) { + wiznet5k_socket_close(socket); + *_errno = -ret; + return -1; + } + else if (ret == SOCK_BUSY) { + *_errno = MP_EAGAIN; + return -1; + } + } + else if (socket->type == Sn_MR_UDP) { + // For POSIX usage of ::send later, stash the remote IP and port + wiznet5k_socket_extra_t *extra = m_new_maybe(wiznet5k_socket_extra_t, 1); + if (extra == NULL) { + *_errno = MP_ENOMEM; + return -1; + } + memcpy(extra->remote_ip, ip, 4); + extra->remote_port = port; + socket->_private = extra; } // success return 0; } +static mp_uint_t wiznet5k_socket_sendto(mod_network_socket_obj_t *socket, const byte *buf, mp_uint_t len, byte *ip, mp_uint_t port, int *_errno); static mp_uint_t wiznet5k_socket_send(mod_network_socket_obj_t *socket, const byte *buf, mp_uint_t len, int *_errno) { + if (socket->type == Sn_MR_UDP) { + if (socket->_private != NULL) { + wiznet5k_socket_extra_t *extra = (wiznet5k_socket_extra_t*) socket->_private; + return wiznet5k_socket_sendto(socket, buf, len, extra->remote_ip, extra->remote_port, _errno); + } + *_errno = MP_ENOTCONN; + return -1; + } + MP_THREAD_GIL_EXIT(); mp_int_t ret = WIZCHIP_EXPORT(send)(socket->fileno, (byte *)buf, len); MP_THREAD_GIL_ENTER(); @@ -557,10 +716,25 @@ static mp_uint_t wiznet5k_socket_send(mod_network_socket_obj_t *socket, const by *_errno = -ret; return -1; } + else if (ret == SOCK_BUSY && getSn_SR(socket->fileno) == SOCK_ESTABLISHED) { + *_errno = MP_EAGAIN; + return -1; + } return ret; } static mp_uint_t wiznet5k_socket_recv(mod_network_socket_obj_t *socket, byte *buf, mp_uint_t len, int *_errno) { + if (socket->timeout > 0) { + mp_uint_t start = mp_hal_ticks_ms(); + while (getSn_SR(socket->fileno) == SOCK_ESTABLISHED && getSn_RX_RSR(socket->fileno) == 0) { + if (mp_hal_ticks_ms() - start > socket->timeout) { + *_errno = MP_ETIMEDOUT; + return -1; + } + mp_event_wait_ms(1); + } + } + MP_THREAD_GIL_EXIT(); mp_int_t ret = WIZCHIP_EXPORT(recv)(socket->fileno, buf, len); MP_THREAD_GIL_ENTER(); @@ -571,6 +745,12 @@ static mp_uint_t wiznet5k_socket_recv(mod_network_socket_obj_t *socket, byte *bu *_errno = -ret; return -1; } + // NOTE: SOCK_BUSY is zero (0) which is confusing if the socket is closed + // and at EOF + else if (ret == SOCK_BUSY && getSn_SR(socket->fileno) == SOCK_ESTABLISHED) { + *_errno = MP_EAGAIN; + return -1; + } return ret; } @@ -591,11 +771,27 @@ static mp_uint_t wiznet5k_socket_sendto(mod_network_socket_obj_t *socket, const *_errno = -ret; return -1; } + else if (ret == SOCK_BUSY) { + *_errno = MP_EAGAIN; + return -1; + } return ret; } static mp_uint_t wiznet5k_socket_recvfrom(mod_network_socket_obj_t *socket, byte *buf, mp_uint_t len, byte *ip, mp_uint_t *port, int *_errno) { uint16_t port2; + + if (socket->timeout > 0) { + mp_uint_t start = mp_hal_ticks_ms(); + while (getSn_SR(socket->fileno) != SOCK_CLOSED && getSn_RX_RSR(socket->fileno) == 0) { + if (mp_hal_ticks_ms() - start > socket->timeout) { + *_errno = MP_ETIMEDOUT; + return -1; + } + mp_event_wait_ms(1); + } + } + MP_THREAD_GIL_EXIT(); mp_int_t ret = WIZCHIP_EXPORT(recvfrom)(socket->fileno, buf, len, ip, &port2); MP_THREAD_GIL_ENTER(); @@ -605,38 +801,79 @@ static mp_uint_t wiznet5k_socket_recvfrom(mod_network_socket_obj_t *socket, byte *_errno = -ret; return -1; } + else if (ret == SOCK_BUSY) { + *_errno = MP_EAGAIN; + return -1; + } return ret; } static int wiznet5k_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) { - // TODO - *_errno = MP_EINVAL; - return -1; + switch (opt) { + // level: SOL_SOCKET + case MOD_NETWORK_SO_REUSEADDR: + case MOD_NETWORK_SO_BROADCAST: + // Implied/not-required in Wiznet sockets + break; + + default: + *_errno = MP_EINVAL; + return -1; + } + + return 0; } static int wiznet5k_socket_settimeout(mod_network_socket_obj_t *socket, mp_uint_t timeout_ms, int *_errno) { - // TODO - *_errno = MP_EINVAL; - return -1; - - /* + uint8_t arg; if (timeout_ms == 0) { // set non-blocking mode - uint8_t arg = SOCK_IO_NONBLOCK; - WIZCHIP_EXPORT(ctlsocket)(socket->fileno, CS_SET_IOMODE, &arg); + arg = SOCK_IO_NONBLOCK; } - */ + else { + arg = SOCK_IO_BLOCK; + } + + mp_int_t ret = WIZCHIP_EXPORT(ctlsocket)(socket->fileno, CS_SET_IOMODE, &arg); + if (ret < 0) { + *_errno = -ret; + return -1; + } + + socket->timeout = timeout_ms; + return 0; } static int wiznet5k_socket_ioctl(mod_network_socket_obj_t *socket, mp_uint_t request, mp_uint_t arg, int *_errno) { + uint8_t sn = (uint8_t)socket->fileno; + if (request == MP_STREAM_POLL) { int ret = 0; - if (arg & MP_STREAM_POLL_RD && getSn_RX_RSR(socket->fileno) != 0) { - ret |= MP_STREAM_POLL_RD; + if (sn < _WIZCHIP_SOCK_NUM_) { + if (arg & MP_STREAM_POLL_RD && getSn_RX_RSR(sn) != 0) { + ret |= MP_STREAM_POLL_RD; + } + if (arg & MP_STREAM_POLL_WR && getSn_TX_FSR(sn) != 0) { + ret |= MP_STREAM_POLL_WR; + } + + uint8_t status = getSn_SR(sn); + if (status == SOCK_CLOSE_WAIT || getSn_IR(sn) & Sn_IR_DISCON) { + // Peer-closed socket is both readable and writable: read will + // return EOF, write - error. Without this poll will hang on a + // socket which was closed by peer. + ret |= arg & (MP_STREAM_POLL_RD | MP_STREAM_POLL_WR); + } else if (status == SOCK_CLOSED) { + ret |= MP_STREAM_POLL_ERR; + } + } else { + ret |= MP_STREAM_POLL_NVAL; } - if (arg & MP_STREAM_POLL_WR && getSn_TX_FSR(socket->fileno) != 0) { - ret |= MP_STREAM_POLL_WR; + + if (wiznet5k_obj.use_interrupt) { + setSn_IR(sn, (Sn_IR_RECV | Sn_IR_CON | Sn_IR_DISCON)); } + return ret; } else { *_errno = MP_EINVAL; @@ -645,23 +882,31 @@ static int wiznet5k_socket_ioctl(mod_network_socket_obj_t *socket, mp_uint_t req } static void wiznet5k_dhcp_init(wiznet5k_obj_t *self) { - uint8_t test_buf[2048]; - uint8_t ret = 0; uint8_t dhcp_retry = 0; + self->dhcp_state = DHCP_STOPPED; + self->dhcp_buf = m_new_maybe(uint8_t, MAX_DHCP_BUF_SIZE); + if (self->dhcp_buf == NULL) { + return; + } - while (ret != DHCP_IP_LEASED) { + self->dhcp_socket = wiznet5k_allocate_socket(); + if (self->dhcp_socket == -1) { + return; + } + + + while (self->dhcp_state != DHCP_IP_LEASED) { mp_uint_t timeout = mp_hal_ticks_ms() + 3000; - DHCP_init(1, test_buf); + DHCP_init(self->dhcp_socket, self->dhcp_buf); while (1) { - ret = DHCP_run(); - if (ret == DHCP_IP_LEASED) { + mpy_wiznet_yield(); + if (self->dhcp_state == DHCP_IP_LEASED) { break; - } else if (ret == DHCP_FAILED || mp_hal_ticks_ms() > timeout) { + } else if (self->dhcp_state == DHCP_FAILED || mp_hal_ticks_ms() > timeout) { dhcp_retry++; break; } - mpy_wiznet_yield(); } if (dhcp_retry > 3) { @@ -673,6 +918,8 @@ static void wiznet5k_dhcp_init(wiznet5k_obj_t *self) { if (ret == DHCP_IP_LEASED) { ctlnetwork(CN_GET_NETINFO, &self->netinfo); } + + wizchip_clrinterrupt(IK_SOCK_0 << self->dhcp_socket); } #endif // WIZNET5K_PROVIDED_STACK @@ -686,11 +933,10 @@ static mp_obj_t wiznet5k_make_new(const mp_obj_type_t *type, size_t n_args, size mp_obj_base_t *spi; mp_hal_pin_obj_t cs; mp_hal_pin_obj_t rst; - - #if WIZNET5K_WITH_LWIP_STACK mp_hal_pin_obj_t pin_intn = (mp_hal_pin_obj_t)NULL; bool use_interrupt = false; + #if WIZNET5K_WITH_LWIP_STACK // Bring down interface while configuring wiznet5k_obj.netif.flags = 0; #endif @@ -713,7 +959,7 @@ static mp_obj_t wiznet5k_make_new(const mp_obj_type_t *type, size_t n_args, size cs = mp_hal_get_pin_obj(mp_pin_make_new(NULL, 1, 0, (mp_obj_t[]) {MP_OBJ_NEW_SMALL_INT(MICROPY_HW_WIZNET_PIN_CS)})); rst = mp_hal_get_pin_obj(mp_pin_make_new(NULL, 1, 0, (mp_obj_t[]) {MP_OBJ_NEW_SMALL_INT(MICROPY_HW_WIZNET_PIN_RST)})); - #if WIZNET5K_WITH_LWIP_STACK && defined(MICROPY_HW_WIZNET_PIN_INTN) + #ifdef MICROPY_HW_WIZNET_PIN_INTN pin_intn = mp_hal_get_pin_obj(mp_pin_make_new(NULL, 1, 0, (mp_obj_t[]) {MP_OBJ_NEW_SMALL_INT(MICROPY_HW_WIZNET_PIN_INTN)})); use_interrupt = true; #endif @@ -722,20 +968,14 @@ static mp_obj_t wiznet5k_make_new(const mp_obj_type_t *type, size_t n_args, size #endif { // If passing in args, must supply spi, pin_cs, pin_rst and optionally pin_intn - #if WIZNET5K_WITH_LWIP_STACK mp_arg_check_num(n_args, n_kw, 3, 4, false); - #else - mp_arg_check_num(n_args, n_kw, 3, 3, false); - #endif spi = mp_hal_get_spi_obj(args[0]); cs = mp_hal_get_pin_obj(args[1]); rst = mp_hal_get_pin_obj(args[2]); - #if WIZNET5K_WITH_LWIP_STACK if (n_args > 3) { pin_intn = mp_hal_get_pin_obj(args[3]); use_interrupt = true; } - #endif } mp_hal_pin_output(cs); @@ -748,9 +988,9 @@ static mp_obj_t wiznet5k_make_new(const mp_obj_type_t *type, size_t n_args, size wiznet5k_obj.spi_transfer = ((mp_machine_spi_p_t *)MP_OBJ_TYPE_GET_SLOT(spi->type, protocol))->transfer; wiznet5k_obj.cs = cs; wiznet5k_obj.rst = rst; - #if WIZNET5K_WITH_LWIP_STACK wiznet5k_obj.pin_intn = pin_intn; wiznet5k_obj.use_interrupt = use_interrupt; + #if WIZNET5K_WITH_LWIP_STACK wiznet5k_obj.trace_flags = 0; #else // WIZNET5K_PROVIDED_STACK wiznet5k_obj.active = false; @@ -894,6 +1134,11 @@ static mp_obj_t wiznet5k_ifconfig(size_t n_args, const mp_obj_t *args) { } else { // Set static IP addresses self->netinfo.dhcp = NETINFO_STATIC; + self->dhcp_state = DHCP_STOPPED; + if (self->dhcp_buf) { + m_del(uint8_t, self->dhcp_buf, MAX_DHCP_BUF_SIZE); + self->dhcp_buf = NULL; + } mp_obj_t *items; mp_obj_get_array_fixed_n(args[1], 4, &items); netutils_parse_ipv4_addr(items[0], netinfo.ip, NETUTILS_BIG); diff --git a/ports/rp2/mpconfigport.h b/ports/rp2/mpconfigport.h index a29692d0be..1f01a75058 100644 --- a/ports/rp2/mpconfigport.h +++ b/ports/rp2/mpconfigport.h @@ -218,6 +218,10 @@ extern const struct _mp_obj_type_t mod_network_nic_type_nina; #if MICROPY_PY_NETWORK_WIZNET5K extern const struct _mp_obj_type_t mod_network_nic_type_wiznet5k; #define MICROPY_HW_NIC_WIZNET5K { MP_ROM_QSTR(MP_QSTR_WIZNET5K), MP_ROM_PTR(&mod_network_nic_type_wiznet5k) }, +// This Network interface requires the extended socket state for timeouts and non-blocking +#ifndef MICROPY_PY_SOCKET_EXTENDED_STATE +#define MICROPY_PY_SOCKET_EXTENDED_STATE (1) +#endif #else #define MICROPY_HW_NIC_WIZNET5K #endif diff --git a/ports/stm32/mpconfigport.h b/ports/stm32/mpconfigport.h index 9e1e24cf23..4043ecdd2a 100644 --- a/ports/stm32/mpconfigport.h +++ b/ports/stm32/mpconfigport.h @@ -202,6 +202,10 @@ extern const struct _mp_obj_type_t mp_network_cyw43_type; #if MICROPY_PY_NETWORK_WIZNET5K extern const struct _mp_obj_type_t mod_network_nic_type_wiznet5k; #define MICROPY_HW_NIC_WIZNET5K { MP_ROM_QSTR(MP_QSTR_WIZNET5K), MP_ROM_PTR(&mod_network_nic_type_wiznet5k) }, +// This Network interface requires the extended socket state for timeouts and non-blocking +#ifndef MICROPY_PY_SOCKET_EXTENDED_STATE +#define MICROPY_PY_SOCKET_EXTENDED_STATE (1) +#endif #else #define MICROPY_HW_NIC_WIZNET5K #endif