diff --git a/ports/stm32/main.c b/ports/stm32/main.c index ef0e1e791b..1a00ef3a18 100644 --- a/ports/stm32/main.c +++ b/ports/stm32/main.c @@ -547,6 +547,7 @@ void stm32_main(uint32_t reset_mode) { // because the system timeout list (next_timeout) is only ever reset by BSS clearing. // So for now we only init the lwIP stack once on power-up. lwip_init(); + systick_enable_dispatch(SYSTICK_DISPATCH_LWIP, mod_network_lwip_poll_wrapper); #endif #if defined(MICROPY_HW_UART_REPL) diff --git a/ports/stm32/modnetwork.c b/ports/stm32/modnetwork.c index dea23b4051..4fa3d8c05b 100644 --- a/ports/stm32/modnetwork.c +++ b/ports/stm32/modnetwork.c @@ -32,6 +32,8 @@ #include "py/runtime.h" #include "py/mphal.h" #include "lib/netutils/netutils.h" +#include "systick.h" +#include "pendsv.h" #include "modnetwork.h" #if MICROPY_PY_NETWORK @@ -43,11 +45,14 @@ #include "lwip/dns.h" #include "lwip/dhcp.h" +// Poll lwIP every 128ms +#define LWIP_TICK(tick) (((tick) & ~(SYSTICK_DISPATCH_NUM_SLOTS - 1) & 0x7f) == 0) + u32_t sys_now(void) { return mp_hal_ticks_ms(); } -void pyb_lwip_poll(void) { +STATIC void pyb_lwip_poll(void) { // Poll all the NICs for incoming data for (struct netif *netif = netif_list; netif != NULL; netif = netif->next) { if (netif->flags & NETIF_FLAG_LINK_UP) { @@ -59,6 +64,12 @@ void pyb_lwip_poll(void) { sys_check_timeouts(); } +void mod_network_lwip_poll_wrapper(uint32_t ticks_ms) { + if (LWIP_TICK(ticks_ms)) { + pendsv_schedule_dispatch(PENDSV_DISPATCH_LWIP, pyb_lwip_poll); + } +} + #endif /// \module network - network configuration diff --git a/ports/stm32/modnetwork.h b/ports/stm32/modnetwork.h index f45e00fbc2..dd8113ebf5 100644 --- a/ports/stm32/modnetwork.h +++ b/ports/stm32/modnetwork.h @@ -46,6 +46,7 @@ typedef struct _mod_network_nic_type_t { extern const mp_obj_type_t mod_network_nic_type_wiznet5k; +void mod_network_lwip_poll_wrapper(uint32_t ticks_ms); mp_obj_t mod_network_nic_ifconfig(struct netif *netif, size_t n_args, const mp_obj_t *args); #else diff --git a/ports/stm32/mpconfigport.h b/ports/stm32/mpconfigport.h index 42e0bf3f13..7ae2ac77b0 100644 --- a/ports/stm32/mpconfigport.h +++ b/ports/stm32/mpconfigport.h @@ -213,17 +213,14 @@ extern const struct _mp_obj_module_t mp_module_onewire; // usocket implementation provided by lwIP #define SOCKET_BUILTIN_MODULE { MP_ROM_QSTR(MP_QSTR_usocket), MP_ROM_PTR(&mp_module_lwip) }, #define SOCKET_BUILTIN_MODULE_WEAK_LINKS { MP_ROM_QSTR(MP_QSTR_socket), MP_ROM_PTR(&mp_module_lwip) }, -#define SOCKET_POLL extern void pyb_lwip_poll(void); pyb_lwip_poll(); #elif MICROPY_PY_USOCKET // usocket implementation provided by skeleton wrapper #define SOCKET_BUILTIN_MODULE { MP_ROM_QSTR(MP_QSTR_usocket), MP_ROM_PTR(&mp_module_usocket) }, #define SOCKET_BUILTIN_MODULE_WEAK_LINKS { MP_ROM_QSTR(MP_QSTR_socket), MP_ROM_PTR(&mp_module_usocket) }, -#define SOCKET_POLL #else // no usocket module #define SOCKET_BUILTIN_MODULE #define SOCKET_BUILTIN_MODULE_WEAK_LINKS -#define SOCKET_POLL #endif #if MICROPY_PY_NETWORK @@ -339,7 +336,6 @@ static inline mp_uint_t disable_irq(void) { do { \ extern void mp_handle_pending(void); \ mp_handle_pending(); \ - SOCKET_POLL \ if (pyb_thread_enabled) { \ MP_THREAD_GIL_EXIT(); \ pyb_thread_yield(); \ @@ -355,7 +351,6 @@ static inline mp_uint_t disable_irq(void) { do { \ extern void mp_handle_pending(void); \ mp_handle_pending(); \ - SOCKET_POLL \ __WFI(); \ } while (0); diff --git a/ports/stm32/pendsv.c b/ports/stm32/pendsv.c index 6c6b3c7bff..a3d04a4ef9 100644 --- a/ports/stm32/pendsv.c +++ b/ports/stm32/pendsv.c @@ -38,13 +38,13 @@ // mp_kbd_exception which is in the root-pointer set. void *pendsv_object; -#if PENDSV_DISPATCH_NUM_SLOTS > 0 +#if defined(PENDSV_DISPATCH_NUM_SLOTS) uint32_t pendsv_dispatch_active; pendsv_dispatch_t pendsv_dispatch_table[PENDSV_DISPATCH_NUM_SLOTS]; #endif void pendsv_init(void) { - #if PENDSV_DISPATCH_NUM_SLOTS > 0 + #if defined(PENDSV_DISPATCH_NUM_SLOTS) pendsv_dispatch_active = false; #endif // set PendSV interrupt at lowest priority @@ -69,7 +69,7 @@ void pendsv_kbd_intr(void) { } } -#if PENDSV_DISPATCH_NUM_SLOTS > 0 +#if defined(PENDSV_DISPATCH_NUM_SLOTS) void pendsv_schedule_dispatch(size_t slot, pendsv_dispatch_t f) { pendsv_dispatch_table[slot] = f; pendsv_dispatch_active = true; @@ -119,7 +119,7 @@ __attribute__((naked)) void PendSV_Handler(void) { // sp[0]: ? __asm volatile ( - #if PENDSV_DISPATCH_NUM_SLOTS > 0 + #if defined(PENDSV_DISPATCH_NUM_SLOTS) // Check if there are any pending calls to dispatch to "ldr r1, pendsv_dispatch_active_ptr\n" "ldr r0, [r1]\n" @@ -174,7 +174,7 @@ __attribute__((naked)) void PendSV_Handler(void) { // Data ".align 2\n" - #if PENDSV_DISPATCH_NUM_SLOTS > 0 + #if defined(PENDSV_DISPATCH_NUM_SLOTS) "pendsv_dispatch_active_ptr: .word pendsv_dispatch_active\n" #endif "pendsv_object_ptr: .word pendsv_object\n" diff --git a/ports/stm32/pendsv.h b/ports/stm32/pendsv.h index c8cc64d762..18ae1d63e9 100644 --- a/ports/stm32/pendsv.h +++ b/ports/stm32/pendsv.h @@ -26,7 +26,16 @@ #ifndef MICROPY_INCLUDED_STM32_PENDSV_H #define MICROPY_INCLUDED_STM32_PENDSV_H -#define PENDSV_DISPATCH_NUM_SLOTS (0) +enum { + #if MICROPY_PY_NETWORK && MICROPY_PY_LWIP + PENDSV_DISPATCH_LWIP, + #endif + PENDSV_DISPATCH_MAX +}; + +#if MICROPY_PY_NETWORK && MICROPY_PY_LWIP +#define PENDSV_DISPATCH_NUM_SLOTS PENDSV_DISPATCH_MAX +#endif typedef void (*pendsv_dispatch_t)(void); diff --git a/ports/stm32/systick.h b/ports/stm32/systick.h index 3ae6be7e02..6a05a4990a 100644 --- a/ports/stm32/systick.h +++ b/ports/stm32/systick.h @@ -34,6 +34,9 @@ enum { #if MICROPY_HW_ENABLE_STORAGE SYSTICK_DISPATCH_STORAGE, #endif + #if MICROPY_PY_NETWORK && MICROPY_PY_LWIP + SYSTICK_DISPATCH_LWIP, + #endif SYSTICK_DISPATCH_MAX };