diff --git a/ports/atmel-samd/background.c b/ports/atmel-samd/background.c index f25ec7200d..385f0c2843 100644 --- a/ports/atmel-samd/background.c +++ b/ports/atmel-samd/background.c @@ -31,6 +31,7 @@ #include "usb_mass_storage.h" #include "shared-module/displayio/__init__.h" +#include "shared-module/network/__init__.h" volatile uint64_t last_finished_tick = 0; @@ -41,6 +42,9 @@ void run_background_tasks(void) { #ifdef CIRCUITPY_DISPLAYIO displayio_refresh_display(); #endif + #ifdef MICROPY_PY_NETWORK + network_module_background(); + #endif usb_msc_background(); usb_cdc_background(); last_finished_tick = ticks_ms; diff --git a/shared-bindings/wiznet/wiznet5k.c b/shared-bindings/wiznet/wiznet5k.c index 1dba5f3808..4e5fff8693 100644 --- a/shared-bindings/wiznet/wiznet5k.c +++ b/shared-bindings/wiznet/wiznet5k.c @@ -66,17 +66,17 @@ STATIC mp_obj_t wiznet5k_make_new(const mp_obj_type_t *type, size_t n_args, size return wiznet5k_create(args[0], args[1], args[2]); } +//| .. attribute:: connected +//| +//| is this device physically connected? +//| + STATIC mp_obj_t wiznet5k_connected_get_value(mp_obj_t self_in) { (void)self_in; return mp_obj_new_bool(wizphy_getphylink() == PHY_LINK_ON); } STATIC MP_DEFINE_CONST_FUN_OBJ_1(wiznet5k_connected_get_value_obj, wiznet5k_connected_get_value); -//| .. attribute:: connected -//| -//| is this device physically connected? -//| - const mp_obj_property_t wiznet5k_connected_obj = { .base.type = &mp_type_property, .proxy = {(mp_obj_t)&wiznet5k_connected_get_value_obj, @@ -84,6 +84,36 @@ const mp_obj_property_t wiznet5k_connected_obj = { (mp_obj_t)&mp_const_none_obj}, }; +//| .. attribute:: dhcp +//| +//| is DHCP active on this device? (set to true to activate DHCP, false to turn it off) +//| + +STATIC mp_obj_t wiznet5k_dhcp_get_value(mp_obj_t self_in) { + (void)self_in; + return mp_obj_new_bool(wiznet5k_check_dhcp()); +} + +STATIC MP_DEFINE_CONST_FUN_OBJ_1(wiznet5k_dhcp_get_value_obj, wiznet5k_dhcp_get_value); + +STATIC mp_obj_t wiznet5k_dhcp_set_value(mp_obj_t self_in, mp_obj_t value) { + (void)self_in; + if (mp_obj_is_true(value)) { + wiznet5k_start_dhcp(); + } else { + wiznet5k_stop_dhcp(); + } + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(wiznet5k_dhcp_set_value_obj, wiznet5k_dhcp_set_value); + +const mp_obj_property_t wiznet5k_dhcp_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&wiznet5k_dhcp_get_value_obj, + (mp_obj_t)&wiznet5k_dhcp_set_value_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + //| .. method:: ifconfig(...) //| //| Called without parameters, returns a tuple of @@ -121,6 +151,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(wiznet5k_ifconfig_obj, 1, 2, wiznet5k STATIC const mp_rom_map_elem_t wiznet5k_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_ifconfig), MP_ROM_PTR(&wiznet5k_ifconfig_obj) }, { MP_ROM_QSTR(MP_QSTR_connected), MP_ROM_PTR(&wiznet5k_connected_obj) }, + { MP_ROM_QSTR(MP_QSTR_dhcp), MP_ROM_PTR(&wiznet5k_dhcp_obj) }, }; STATIC MP_DEFINE_CONST_DICT(wiznet5k_locals_dict, wiznet5k_locals_dict_table); @@ -146,6 +177,7 @@ const mod_network_nic_type_t mod_network_nic_type_wiznet5k = { .setsockopt = wiznet5k_socket_setsockopt, .settimeout = wiznet5k_socket_settimeout, .ioctl = wiznet5k_socket_ioctl, + .timer_tick = wiznet5k_socket_timer_tick, }; #endif // MICROPY_PY_WIZNET5K diff --git a/shared-module/network/__init__.c b/shared-module/network/__init__.c index 6a955a0c40..a674e8478d 100644 --- a/shared-module/network/__init__.c +++ b/shared-module/network/__init__.c @@ -24,6 +24,8 @@ * THE SOFTWARE. */ +#include + #include "py/objlist.h" #include "py/runtime.h" #include "py/mphal.h" @@ -31,6 +33,8 @@ #include "shared-bindings/random/__init__.h" +#include "shared-module/network/__init__.h" + // mod_network_nic_list needs to be declared in mpconfigport.h @@ -41,6 +45,19 @@ void network_module_init(void) { void network_module_deinit(void) { } +void network_module_background(void) { + static uint32_t next_tick = 0; + uint32_t this_tick = ticks_ms; + if (this_tick < next_tick) return; + next_tick = this_tick + 1000; + + for (mp_uint_t i = 0; i < MP_STATE_PORT(mod_network_nic_list).len; i++) { + mp_obj_t nic = MP_STATE_PORT(mod_network_nic_list).items[i]; + mod_network_nic_type_t *nic_type = (mod_network_nic_type_t*)mp_obj_get_type(nic); + if (nic_type->timer_tick != NULL) nic_type->timer_tick(nic); + } +} + void network_module_register_nic(mp_obj_t nic) { for (mp_uint_t i = 0; i < MP_STATE_PORT(mod_network_nic_list).len; i++) { if (MP_STATE_PORT(mod_network_nic_list).items[i] == nic) { diff --git a/shared-module/network/__init__.h b/shared-module/network/__init__.h index ce5b4e6d31..00a3c39575 100644 --- a/shared-module/network/__init__.h +++ b/shared-module/network/__init__.h @@ -61,6 +61,7 @@ typedef struct _mod_network_nic_type_t { int (*setsockopt)(struct _mod_network_socket_obj_t *socket, mp_uint_t level, mp_uint_t opt, const void *optval, mp_uint_t optlen, int *_errno); int (*settimeout)(struct _mod_network_socket_obj_t *socket, mp_uint_t timeout_ms, int *_errno); int (*ioctl)(struct _mod_network_socket_obj_t *socket, mp_uint_t request, mp_uint_t arg, int *_errno); + void (*timer_tick)(struct _mod_network_socket_obj_t *socket); } mod_network_nic_type_t; typedef struct _mod_network_socket_obj_t { @@ -82,6 +83,7 @@ extern const mod_network_nic_type_t mod_network_nic_type_cc3k; void network_module_init(void); void network_module_deinit(void); +void network_module_background(void); void network_module_register_nic(mp_obj_t nic); mp_obj_t network_module_find_nic(const uint8_t *ip); diff --git a/shared-module/wiznet/wiznet5k.c b/shared-module/wiznet/wiznet5k.c index 5c311bf496..ee732859af 100644 --- a/shared-module/wiznet/wiznet5k.c +++ b/shared-module/wiznet/wiznet5k.c @@ -50,16 +50,7 @@ #include "internet/dns/dns.h" #include "internet/dhcp/dhcp.h" -typedef struct _wiznet5k_obj_t { - mp_obj_base_t base; - mp_uint_t cris_state; - busio_spi_obj_t *spi; - digitalio_digitalinout_obj_t cs; - digitalio_digitalinout_obj_t rst; - uint8_t socket_used; -} wiznet5k_obj_t; - -static wiznet5k_obj_t wiznet5k_obj; +#include "shared-module/wiznet/wiznet5k.h" STATIC wiznet5k_obj_t wiznet5k_obj; @@ -326,22 +317,34 @@ int wiznet5k_socket_ioctl(mod_network_socket_obj_t *socket, mp_uint_t request, m } } -static void wiznet5k_try_dhcp(void) { - DHCP_INIT_BUFFER_TYPE dhcp_buf[DHCP_INIT_BUFFER_SIZE]; - - // Set up the socket to listen on UDP 68 before calling DHCP_init - WIZCHIP_EXPORT(socket)(0, MOD_NETWORK_SOCK_DGRAM, DHCP_CLIENT_PORT, 0); - DHCP_init(0, dhcp_buf); - - // try a few times for DHCP ... XXX this should be asynchronous. - for (int i=0; i<10; i++) { +void wiznet5k_socket_timer_tick(mod_network_socket_obj_t *socket) { + if (wiznet5k_obj.dhcp_active) { DHCP_time_handler(); - int dhcp_state = DHCP_run(); - if (dhcp_state == DHCP_IP_LEASED || dhcp_state == DHCP_IP_CHANGED) break; - mp_hal_delay_ms(1000); + DHCP_run(); } - DHCP_stop(); - WIZCHIP_EXPORT(close)(0); +} + +void wiznet5k_start_dhcp(void) { + static DHCP_INIT_BUFFER_TYPE dhcp_buf[DHCP_INIT_BUFFER_SIZE]; + + if (!wiznet5k_obj.dhcp_active) { + // Set up the socket to listen on UDP 68 before calling DHCP_init + WIZCHIP_EXPORT(socket)(0, MOD_NETWORK_SOCK_DGRAM, DHCP_CLIENT_PORT, 0); + DHCP_init(0, dhcp_buf); + wiznet5k_obj.dhcp_active = 1; + } +} + +void wiznet5k_stop_dhcp(void) { + if (wiznet5k_obj.dhcp_active) { + wiznet5k_obj.dhcp_active = 0; + DHCP_stop(); + WIZCHIP_EXPORT(close)(0); + } +} + +bool wiznet5k_check_dhcp(void) { + return wiznet5k_obj.dhcp_active; } /// Create and return a WIZNET5K object. @@ -391,7 +394,7 @@ mp_obj_t wiznet5k_create(mp_obj_t spi_in, mp_obj_t cs_in, mp_obj_t rst_in) { // seems we need a small delay after init mp_hal_delay_ms(250); - wiznet5k_try_dhcp(); + wiznet5k_start_dhcp(); // register with network module network_module_register_nic(&wiznet5k_obj); diff --git a/shared-module/wiznet/wiznet5k.h b/shared-module/wiznet/wiznet5k.h index f3e3dcfe11..1284a44fd1 100644 --- a/shared-module/wiznet/wiznet5k.h +++ b/shared-module/wiznet/wiznet5k.h @@ -39,6 +39,7 @@ typedef struct _wiznet5k_obj_t { digitalio_digitalinout_obj_t cs; digitalio_digitalinout_obj_t rst; uint8_t socket_used; + bool dhcp_active; } wiznet5k_obj_t; int wiznet5k_gethostbyname(mp_obj_t nic, const char *name, mp_uint_t len, uint8_t *out_ip); @@ -55,9 +56,14 @@ mp_uint_t wiznet5k_socket_recvfrom(mod_network_socket_obj_t *socket, byte *buf, 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); int wiznet5k_socket_settimeout(mod_network_socket_obj_t *socket, mp_uint_t timeout_ms, int *_errno); int wiznet5k_socket_ioctl(mod_network_socket_obj_t *socket, mp_uint_t request, mp_uint_t arg, int *_errno); +void wiznet5k_socket_timer_tick(mod_network_socket_obj_t *socket); mp_obj_t wiznet5k_socket_disconnect(mp_obj_t self_in); mp_obj_t wiznet5k_create(mp_obj_t spi_in, mp_obj_t cs_in, mp_obj_t rst_in); +void wiznet5k_start_dhcp(void); +void wiznet5k_stop_dhcp(void); +bool wiznet5k_check_dhcp(void); + extern const mod_network_nic_type_t mod_network_nic_type_wiznet5k; #endif // MICROPY_INCLUDED_SHARED_MODULE_WIZNET_WIZNET5K_H