summaryrefslogtreecommitdiffstatshomepage
path: root/stmhal/modwiznet5k.c
diff options
context:
space:
mode:
Diffstat (limited to 'stmhal/modwiznet5k.c')
-rw-r--r--stmhal/modwiznet5k.c228
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,
-};