diff options
Diffstat (limited to 'stmhal/modwiznet5k.c')
-rw-r--r-- | stmhal/modwiznet5k.c | 228 |
1 files changed, 74 insertions, 154 deletions
diff --git a/stmhal/modwiznet5k.c b/stmhal/modwiznet5k.c index 3996c29944..3a4b25c0f6 100644 --- a/stmhal/modwiznet5k.c +++ b/stmhal/modwiznet5k.c @@ -36,7 +36,9 @@ #include "misc.h" #include "qstr.h" #include "obj.h" +#include "objlist.h" #include "runtime.h" +#include "modnetwork.h" #include "pin.h" #include "genhdr/pins.h" #include "spi.h" @@ -64,17 +66,14 @@ #define IPADDR_BUF_SIZE (4) -STATIC const mp_obj_type_t wiznet5k_type; -STATIC const mp_obj_type_t wiznet5k_socket_type; - STATIC mp_obj_t wiznet5k_socket_new(uint8_t sn, mp_uint_t type); typedef struct _wiznet5k_obj_t { mp_obj_base_t base; mp_uint_t cris_state; + SPI_HandleTypeDef *spi; const pin_obj_t *cs; const pin_obj_t *rst; - SPI_HandleTypeDef *spi; uint8_t socket_used; } wiznet5k_obj_t; @@ -106,9 +105,6 @@ STATIC void wiz_spi_write(const uint8_t *buf, uint32_t len) { (void)status; } -/******************************************************************************/ -// Miscellaneous helpers - // Check the return value from Wiz socket calls: // - on error (<0) an exception is raised // - SOCK_OK or SOCK_BUSY does nothing @@ -120,51 +116,50 @@ STATIC void check_sock_return_value(int8_t ret) { } } -STATIC void parse_ip_addr(mp_obj_t addr_in, uint8_t *out_ip) { - const char *addr_str = mp_obj_str_get_str(addr_in); - const char *s = addr_str; - for (mp_uint_t i = 0;; i++) { - mp_uint_t val = 0; - for (; *s && *s != '.'; s++) { - val = val * 10 + *s - '0'; +STATIC mp_obj_t wiznet5k_socket(mp_obj_t self_in, int domain, int type, int fileno, int *_errno) { + if (domain != MOD_NETWORK_AF_INET) { + *_errno = EAFNOSUPPORT; + return MP_OBJ_NULL; + } + + switch (type) { + case MOD_NETWORK_SOCK_STREAM: type = Sn_MR_TCP; break; + case MOD_NETWORK_SOCK_DGRAM: type = Sn_MR_UDP; break; + default: *_errno = EINVAL; return MP_OBJ_NULL; + } + + if (fileno < 0) { + // get first unused socket number + for (mp_uint_t sn = 0; sn < _WIZCHIP_SOCK_NUM_; sn++) { + if ((wiznet5k_obj.socket_used & (1 << sn)) == 0) { + fileno = sn; + break; + } } - out_ip[i] = val; - if (i == 3 && *s == '\0') { - return; - } else if (i < 3 && *s == '.') { - s++; - } else { - nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "invalid IP address")); + if (fileno < 0) { + // too many open sockets + *_errno = EMFILE; + return MP_OBJ_NULL; } } -} - -// Takes an address of the form ('192.168.0.1', 8080), returns the port and -// puts IP in out_ip (which must take at least IPADDR_BUF_SIZE bytes). -STATIC mp_uint_t parse_net_addr(mp_obj_t addr_in, uint8_t *out_ip) { - mp_obj_t *addr_items; - mp_obj_get_array_fixed_n(addr_in, 2, &addr_items); - parse_ip_addr(addr_items[0], out_ip); - return mp_obj_get_int(addr_items[1]); -} -// Takes an array with a raw IP address and returns something like '192.168.0.1'. -STATIC mp_obj_t format_ip_addr(uint8_t *ip) { - char ip_str[16]; - mp_uint_t ip_len = snprintf(ip_str, 16, "%u.%u.%u.%u", ip[0], ip[1], ip[2], ip[3]); - return mp_obj_new_str(ip_str, ip_len, false); + return wiznet5k_socket_new(fileno, type); } -// Takes an array with a raw IP address, and a port, and returns a net-address -// tuple such as ('192.168.0.1', 8080). -STATIC mp_obj_t format_net_addr(uint8_t *ip, mp_uint_t port) { - mp_obj_t tuple[2] = { - tuple[0] = format_ip_addr(ip), - tuple[1] = mp_obj_new_int(port), - }; - return mp_obj_new_tuple(2, tuple); +STATIC int wiznet5k_gethostbyname(mp_obj_t nic, const char *name, mp_uint_t len, uint8_t *out_ip) { + uint8_t dns_ip[IPADDR_BUF_SIZE] = {8, 8, 8, 8}; + uint8_t *buf = m_new(uint8_t, MAX_DNS_BUF_SIZE); + DNS_init(0, buf); + mp_int_t ret = DNS_run(dns_ip, (uint8_t*)name, out_ip); + m_del(uint8_t, buf, MAX_DNS_BUF_SIZE); + if (ret == 1) { + // success + return 0; + } else { + // failure + return ENOENT; + } } - /******************************************************************************/ // Micro Python bindings @@ -174,18 +169,18 @@ STATIC void wiznet5k_print(void (*print)(void *env, const char *fmt, ...), void print(env, "WIZnet5k()"); } -/// \classmethod \constructor() +/// \classmethod \constructor(spi, pin_cs, pin_rst) /// Create and return a WIZnet5k object. STATIC mp_obj_t wiznet5k_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) { // check arguments - mp_arg_check_num(n_args, n_kw, 0, 0, false); + mp_arg_check_num(n_args, n_kw, 3, 3, false); // init the wiznet5k object - wiznet5k_obj.base.type = &wiznet5k_type; + wiznet5k_obj.base.type = (mp_obj_type_t*)&mod_network_nic_type_wiznet5k; wiznet5k_obj.cris_state = 0; - wiznet5k_obj.cs = &pin_B12; // Y5 - wiznet5k_obj.rst = &pin_B9; // Y4 - wiznet5k_obj.spi = &SPIHandle2; // Y-skin + wiznet5k_obj.spi = spi_get_handle(args[0]); + wiznet5k_obj.cs = pin_find(args[1]); + wiznet5k_obj.rst = pin_find(args[2]); wiznet5k_obj.socket_used = 0; /*!< SPI configuration */ @@ -200,7 +195,7 @@ STATIC mp_obj_t wiznet5k_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t SPIHandle2.Init.TIMode = SPI_TIMODE_DISABLED; SPIHandle2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLED; SPIHandle2.Init.CRCPolynomial = 7; // unused - spi_init(wiznet5k_obj.spi); + spi_init(wiznet5k_obj.spi, false); GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; @@ -238,6 +233,9 @@ STATIC mp_obj_t wiznet5k_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t }; ctlnetwork(CN_SET_NETINFO, (void*)&netinfo); + // register with network module + mod_network_register_nic(&wiznet5k_obj); + // return wiznet5k object return &wiznet5k_obj; } @@ -275,98 +273,43 @@ STATIC mp_obj_t wiznet5k_ipaddr(mp_uint_t n_args, const mp_obj_t *args) { if (n_args == 1) { // get mp_obj_t tuple[4] = { - format_ip_addr(netinfo.ip), - format_ip_addr(netinfo.sn), - format_ip_addr(netinfo.gw), - format_ip_addr(netinfo.dns), + mod_network_format_ipv4_addr(netinfo.ip), + mod_network_format_ipv4_addr(netinfo.sn), + mod_network_format_ipv4_addr(netinfo.gw), + mod_network_format_ipv4_addr(netinfo.dns), }; return mp_obj_new_tuple(4, tuple); } else { // set mp_obj_t *items; mp_obj_get_array_fixed_n(args[1], 4, &items); - parse_ip_addr(items[0], netinfo.ip); - parse_ip_addr(items[1], netinfo.sn); - parse_ip_addr(items[2], netinfo.gw); - parse_ip_addr(items[3], netinfo.dns); + mod_network_parse_ipv4_addr(items[0], netinfo.ip); + mod_network_parse_ipv4_addr(items[1], netinfo.sn); + mod_network_parse_ipv4_addr(items[2], netinfo.gw); + mod_network_parse_ipv4_addr(items[3], netinfo.dns); ctlnetwork(CN_SET_NETINFO, &netinfo); return mp_const_none; } } STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(wiznet5k_ipaddr_obj, 1, 2, wiznet5k_ipaddr); -/// \method socket(family=AF_INET, type=SOCK_STREAM, fileno=-1) -/// Create a socket. -STATIC const mp_arg_t wiznet5k_socket_args[] = { - { MP_QSTR_family, MP_ARG_INT, {.u_int = 0} }, // ignored, only AF_INET supported - { MP_QSTR_type, MP_ARG_INT, {.u_int = Sn_MR_TCP} }, // SOCK_STREAM or SOCK_DGRAM - { MP_QSTR_fileno, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1} }, -}; -#define PYB_WIZNET5K_SOCKET_NUM_ARGS MP_ARRAY_SIZE(wiznet5k_socket_args) - -STATIC mp_obj_t wiznet5k_socket(mp_uint_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { - // parse args - mp_arg_val_t vals[PYB_WIZNET5K_SOCKET_NUM_ARGS]; - mp_arg_parse_all(n_args - 1, args + 1, kw_args, PYB_WIZNET5K_SOCKET_NUM_ARGS, wiznet5k_socket_args, vals); - - if (vals[2].u_int < 0) { - // get first unused socket number - for (mp_uint_t sn = 0; sn < _WIZCHIP_SOCK_NUM_; sn++) { - if ((wiznet5k_obj.socket_used & (1 << sn)) == 0) { - vals[2].u_int = sn; - break; - } - } - if (vals[2].u_int < 0) { - // too many open sockets - nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(EMFILE))); - } - } - - return wiznet5k_socket_new(vals[2].u_int, vals[1].u_int); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_KW(wiznet5k_socket_obj, 1, wiznet5k_socket); - -/// \method gethostbyname(name) -/// Use DNS to lookup a host name. Returns an IP address. -STATIC mp_obj_t wiznet5k_gethostbyname(mp_obj_t self_in, mp_obj_t name_in) { - uint8_t dns_ip[IPADDR_BUF_SIZE] = {8, 8, 8, 8}; - const char *name = mp_obj_str_get_str(name_in); - uint8_t out_ip[IPADDR_BUF_SIZE]; - uint8_t *buf = m_new(uint8_t, MAX_DNS_BUF_SIZE); - DNS_init(0, buf); - mp_int_t ret = DNS_run(dns_ip, (uint8_t*)name, out_ip); - m_del(uint8_t, buf, MAX_DNS_BUF_SIZE); - if (ret == 1) { - // success - return format_ip_addr(out_ip); - } else { - // failure - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, "DNS error %d", ret)); - } -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(wiznet5k_gethostbyname_obj, wiznet5k_gethostbyname); - STATIC const mp_map_elem_t wiznet5k_locals_dict_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_regs), (mp_obj_t)&wiznet5k_regs_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_ipaddr), (mp_obj_t)&wiznet5k_ipaddr_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_socket), (mp_obj_t)&wiznet5k_socket_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_gethostbyname), (mp_obj_t)&wiznet5k_gethostbyname_obj }, - - // class constants - { MP_OBJ_NEW_QSTR(MP_QSTR_AF_INET), MP_OBJ_NEW_SMALL_INT(0) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_SOCK_STREAM), MP_OBJ_NEW_SMALL_INT(Sn_MR_TCP) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_SOCK_DGRAM), MP_OBJ_NEW_SMALL_INT(Sn_MR_UDP) }, }; STATIC MP_DEFINE_CONST_DICT(wiznet5k_locals_dict, wiznet5k_locals_dict_table); -STATIC const mp_obj_type_t wiznet5k_type = { - { &mp_type_type }, - .name = MP_QSTR_WIZnet5k, - .print = wiznet5k_print, - .make_new = wiznet5k_make_new, - .locals_dict = (mp_obj_t)&wiznet5k_locals_dict, +const mod_network_nic_type_t mod_network_nic_type_wiznet5k = { + .base = { + { &mp_type_type }, + .name = MP_QSTR_WIZnet5k, + .print = wiznet5k_print, + .make_new = wiznet5k_make_new, + .locals_dict = (mp_obj_t)&wiznet5k_locals_dict, + }, + .socket = wiznet5k_socket, + .gethostbyname = wiznet5k_gethostbyname, }; /******************************************************************************/ @@ -378,6 +321,8 @@ typedef struct _wiznet5k_socket_obj_t { uint8_t type; } wiznet5k_socket_obj_t; +STATIC const mp_obj_type_t wiznet5k_socket_type; + STATIC mp_obj_t wiznet5k_socket_new(uint8_t sn, mp_uint_t type) { wiznet5k_socket_obj_t *s = m_new_obj(wiznet5k_socket_obj_t); s->base.type = &wiznet5k_socket_type; @@ -404,7 +349,7 @@ STATIC mp_obj_t wiznet5k_socket_bind(mp_obj_t self_in, mp_obj_t addr_in) { wiznet5k_socket_obj_t *self = self_in; uint8_t ip[IPADDR_BUF_SIZE]; - mp_uint_t port = parse_net_addr(addr_in, ip); + mp_uint_t port = mod_network_parse_inet_addr(addr_in, ip); // open the socket in server mode mp_int_t ret = socket(self->sn, self->type, port, 0); @@ -441,7 +386,7 @@ STATIC mp_obj_t wiznet5k_socket_connect(mp_obj_t self_in, mp_obj_t addr_in) { // now connect uint8_t ip[IPADDR_BUF_SIZE]; - mp_uint_t port = parse_net_addr(addr_in, ip); + mp_uint_t port = mod_network_parse_inet_addr(addr_in, ip); ret = connect(self->sn, ip, port); check_sock_return_value(ret); @@ -484,7 +429,7 @@ STATIC mp_obj_t wiznet5k_socket_sendto(mp_obj_t self_in, mp_obj_t data_in, mp_ob mp_buffer_info_t bufinfo; mp_get_buffer_raise(data_in, &bufinfo, MP_BUFFER_READ); uint8_t ip[IPADDR_BUF_SIZE]; - mp_uint_t port = parse_net_addr(addr_in, ip); + mp_uint_t port = mod_network_parse_inet_addr(addr_in, ip); mp_int_t ret = sendto(self->sn, bufinfo.buf, bufinfo.len, ip, port); check_sock_return_value(ret); return mp_obj_new_int(ret); @@ -501,7 +446,7 @@ STATIC mp_obj_t wiznet5k_socket_recvfrom(mp_obj_t self_in, mp_obj_t len_in) { check_sock_return_value(ret); mp_obj_t tuple[2] = { mp_obj_new_bytes(buf, ret), - format_net_addr(ip, port), + mod_network_format_inet_addr(ip, port), }; return mp_obj_new_tuple(2, tuple); } @@ -528,28 +473,3 @@ STATIC const mp_obj_type_t wiznet5k_socket_type = { .print = wiznet5k_socket_print, .locals_dict = (mp_obj_t)&wiznet5k_socket_locals_dict, }; - -/******************************************************************************/ -// Micro Python bindings; WIZnet5x00 module - -STATIC const mp_map_elem_t mp_module_wiznet5k_globals_table[] = { - { MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_wiznet5k) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_WIZnet5k), (mp_obj_t)&wiznet5k_type }, -}; - -STATIC const mp_obj_dict_t mp_module_wiznet5k_globals = { - .base = {&mp_type_dict}, - .map = { - .all_keys_are_qstrs = 1, - .table_is_fixed_array = 1, - .used = MP_ARRAY_SIZE(mp_module_wiznet5k_globals_table), - .alloc = MP_ARRAY_SIZE(mp_module_wiznet5k_globals_table), - .table = (mp_map_elem_t*)mp_module_wiznet5k_globals_table, - }, -}; - -const mp_obj_module_t mp_module_wiznet5k = { - .base = { &mp_type_module }, - .name = MP_QSTR_wiznet5k, - .globals = (mp_obj_dict_t*)&mp_module_wiznet5k_globals, -}; |