summaryrefslogtreecommitdiff
path: root/shared-module
diff options
context:
space:
mode:
authorScott Shawcroft <scott@adafruit.com>2019-05-10 11:31:18 -0700
committerGitHub <noreply@github.com>2019-05-10 11:31:18 -0700
commit46164c6ec6d6bc23feafbfce5b08e5307daac1f7 (patch)
treefaf166ba1979051bd8f403f6fece09bbdd518def /shared-module
parent03e000c4bea2132242db8df9da647e38248de395 (diff)
parent0d08dde62e79e293a56b3d64f4e73a25beb75d76 (diff)
Merge pull request #1837 from nickzoic/circuitpython-nickzoic-1800-wiznet-socket
WIP: Circuitpython nickzoic 1800 wiznet socket
Diffstat (limited to 'shared-module')
-rw-r--r--shared-module/network/__init__.c10
-rw-r--r--shared-module/network/__init__.h6
-rw-r--r--shared-module/wiznet/wiznet5k.c82
-rw-r--r--shared-module/wiznet/wiznet5k.h7
4 files changed, 72 insertions, 33 deletions
diff --git a/shared-module/network/__init__.c b/shared-module/network/__init__.c
index a674e8478..96648b260 100644
--- a/shared-module/network/__init__.c
+++ b/shared-module/network/__init__.c
@@ -43,6 +43,12 @@ void network_module_init(void) {
}
void network_module_deinit(void) {
+ 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->deinit != NULL) nic_type->deinit(nic);
+ }
+ mp_obj_list_set_len(&MP_STATE_PORT(mod_network_nic_list), 0);
}
void network_module_background(void) {
@@ -93,3 +99,7 @@ void network_module_create_random_mac_address(uint8_t *mac) {
mac[4] = (uint8_t)(rb2 >> 8);
mac[5] = (uint8_t)(rb2);
}
+
+uint16_t network_module_create_random_source_tcp_port(void) {
+ return 0xc000 | shared_modules_random_getrandbits(14);
+}
diff --git a/shared-module/network/__init__.h b/shared-module/network/__init__.h
index 00a3c3957..f4eb05bb5 100644
--- a/shared-module/network/__init__.h
+++ b/shared-module/network/__init__.h
@@ -25,11 +25,12 @@
* THE SOFTWARE.
*/
-void network_module_create_random_mac_address(uint8_t *mac);
-
#ifndef MICROPY_INCLUDED_SHARED_MODULE_NETWORK___INIT___H
#define MICROPY_INCLUDED_SHARED_MODULE_NETWORK___INIT___H
+void network_module_create_random_mac_address(uint8_t *mac);
+uint16_t network_module_create_random_source_tcp_port(void);
+
#define MOD_NETWORK_IPADDR_BUF_SIZE (4)
#define MOD_NETWORK_AF_INET (2)
@@ -62,6 +63,7 @@ typedef struct _mod_network_nic_type_t {
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);
+ void (*deinit)(struct _mod_network_socket_obj_t *socket);
} mod_network_nic_type_t;
typedef struct _mod_network_socket_obj_t {
diff --git a/shared-module/wiznet/wiznet5k.c b/shared-module/wiznet/wiznet5k.c
index ee732859a..3c5c5f0c8 100644
--- a/shared-module/wiznet/wiznet5k.c
+++ b/shared-module/wiznet/wiznet5k.c
@@ -93,6 +93,16 @@ int wiznet5k_gethostbyname(mp_obj_t nic, const char *name, mp_uint_t len, uint8_
}
}
+int get_available_socket(wiznet5k_obj_t *wiz) {
+ for (uint8_t sn = 0; sn < _WIZCHIP_SOCK_NUM_; sn++) {
+ if ((wiz->socket_used & (1 << sn)) == 0) {
+ wiz->socket_used |= (1 << sn);
+ return sn;
+ }
+ }
+ return -1;
+}
+
int wiznet5k_socket_socket(mod_network_socket_obj_t *socket, int *_errno) {
if (socket->u_param.domain != MOD_NETWORK_AF_INET) {
*_errno = MP_EAFNOSUPPORT;
@@ -107,13 +117,7 @@ int wiznet5k_socket_socket(mod_network_socket_obj_t *socket, int *_errno) {
if (socket->u_param.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->u_param.fileno = sn;
- break;
- }
- }
+ socket->u_param.fileno = get_available_socket(&wiznet5k_obj);
if (socket->u_param.fileno == -1) {
// too many open sockets
*_errno = MP_EMFILE;
@@ -199,8 +203,12 @@ int wiznet5k_socket_accept(mod_network_socket_obj_t *socket, mod_network_socket_
}
int wiznet5k_socket_connect(mod_network_socket_obj_t *socket, byte *ip, mp_uint_t port, int *_errno) {
+ uint16_t src_port = network_module_create_random_source_tcp_port();
+ // make sure same outgoing port number can't be in use by two different sockets.
+ src_port = (src_port & ~(_WIZCHIP_SOCK_NUM_ - 1)) | socket->u_param.fileno;
+
// use "bind" function to open the socket in client mode
- if (wiznet5k_socket_bind(socket, ip, 0, _errno) != 0) {
+ if (wiznet5k_socket_bind(socket, NULL, src_port, _errno) != 0) {
return -1;
}
@@ -318,33 +326,56 @@ int wiznet5k_socket_ioctl(mod_network_socket_obj_t *socket, mp_uint_t request, m
}
void wiznet5k_socket_timer_tick(mod_network_socket_obj_t *socket) {
- if (wiznet5k_obj.dhcp_active) {
+ if (wiznet5k_obj.dhcp_socket >= 0) {
DHCP_time_handler();
DHCP_run();
}
}
-void wiznet5k_start_dhcp(void) {
+int wiznet5k_start_dhcp(void) {
+ // XXX this should throw an error if DHCP fails
static DHCP_INIT_BUFFER_TYPE dhcp_buf[DHCP_INIT_BUFFER_SIZE];
- if (!wiznet5k_obj.dhcp_active) {
+ if (wiznet5k_obj.dhcp_socket < 0) {
// 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;
+ wiznet5k_obj.dhcp_socket = get_available_socket(&wiznet5k_obj);
+ if (wiznet5k_obj.dhcp_socket < 0) return MP_EMFILE;
+
+ WIZCHIP_EXPORT(socket)(wiznet5k_obj.dhcp_socket, MOD_NETWORK_SOCK_DGRAM, DHCP_CLIENT_PORT, 0);
+ DHCP_init(wiznet5k_obj.dhcp_socket, dhcp_buf);
}
+ return 0;
}
-void wiznet5k_stop_dhcp(void) {
- if (wiznet5k_obj.dhcp_active) {
- wiznet5k_obj.dhcp_active = 0;
+int wiznet5k_stop_dhcp(void) {
+ if (wiznet5k_obj.dhcp_socket >= 0) {
DHCP_stop();
- WIZCHIP_EXPORT(close)(0);
+ WIZCHIP_EXPORT(close)(wiznet5k_obj.dhcp_socket);
+ wiznet5k_obj.socket_used &= ~(1 << wiznet5k_obj.dhcp_socket);
+ wiznet5k_obj.dhcp_socket = -1;
}
+ return 0;
}
bool wiznet5k_check_dhcp(void) {
- return wiznet5k_obj.dhcp_active;
+ return wiznet5k_obj.dhcp_socket >= 0;
+}
+
+void wiznet5k_reset(void) {
+ if (wiznet5k_obj.rst.pin) {
+ // hardware reset if using RST pin
+ common_hal_digitalio_digitalinout_set_value(&wiznet5k_obj.rst, 0);
+ mp_hal_delay_us(10); // datasheet says 2us
+ common_hal_digitalio_digitalinout_set_value(&wiznet5k_obj.rst, 1);
+ mp_hal_delay_ms(150); // datasheet says 150ms
+ } else {
+ // otherwise, software reset
+ wizchip_sw_reset();
+ }
+}
+
+void wiznet5k_socket_deinit(mod_network_socket_obj_t *socket) {
+ wiznet5k_reset();
}
/// Create and return a WIZNET5K object.
@@ -354,9 +385,8 @@ mp_obj_t wiznet5k_create(mp_obj_t spi_in, mp_obj_t cs_in, mp_obj_t rst_in) {
wiznet5k_obj.base.type = (mp_obj_type_t*)&mod_network_nic_type_wiznet5k;
wiznet5k_obj.cris_state = 0;
wiznet5k_obj.spi = MP_OBJ_TO_PTR(spi_in);
- common_hal_digitalio_digitalinout_construct(&wiznet5k_obj.cs, cs_in);
- common_hal_digitalio_digitalinout_construct(&wiznet5k_obj.rst, rst_in);
wiznet5k_obj.socket_used = 0;
+ wiznet5k_obj.dhcp_socket = -1;
/*!< SPI configuration */
// XXX probably should check if the provided SPI is already configured, and
@@ -369,13 +399,11 @@ mp_obj_t wiznet5k_create(mp_obj_t spi_in, mp_obj_t cs_in, mp_obj_t rst_in) {
8 // 8 BITS
);
+ common_hal_digitalio_digitalinout_construct(&wiznet5k_obj.cs, cs_in);
common_hal_digitalio_digitalinout_switch_to_output(&wiznet5k_obj.cs, 1, DRIVE_MODE_PUSH_PULL);
- common_hal_digitalio_digitalinout_switch_to_output(&wiznet5k_obj.rst, 1, DRIVE_MODE_PUSH_PULL);
- common_hal_digitalio_digitalinout_set_value(&wiznet5k_obj.rst, 0);
- mp_hal_delay_us(10); // datasheet says 2us
- common_hal_digitalio_digitalinout_set_value(&wiznet5k_obj.rst, 1);
- mp_hal_delay_ms(160); // datasheet says 150ms
+ if (rst_in) common_hal_digitalio_digitalinout_construct(&wiznet5k_obj.rst, rst_in);
+ wiznet5k_reset();
reg_wizchip_cris_cbfunc(wiz_cris_enter, wiz_cris_exit);
reg_wizchip_cs_cbfunc(wiz_cs_select, wiz_cs_deselect);
@@ -394,8 +422,6 @@ 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_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 1284a44fd..0154831c7 100644
--- a/shared-module/wiznet/wiznet5k.h
+++ b/shared-module/wiznet/wiznet5k.h
@@ -39,7 +39,7 @@ typedef struct _wiznet5k_obj_t {
digitalio_digitalinout_obj_t cs;
digitalio_digitalinout_obj_t rst;
uint8_t socket_used;
- bool dhcp_active;
+ int8_t dhcp_socket; // -1 for DHCP not in use
} wiznet5k_obj_t;
int wiznet5k_gethostbyname(mp_obj_t nic, const char *name, mp_uint_t len, uint8_t *out_ip);
@@ -57,11 +57,12 @@ int wiznet5k_socket_setsockopt(mod_network_socket_obj_t *socket, mp_uint_t level
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);
+void wiznet5k_socket_deinit(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);
+int wiznet5k_start_dhcp(void);
+int wiznet5k_stop_dhcp(void);
bool wiznet5k_check_dhcp(void);
extern const mod_network_nic_type_t mod_network_nic_type_wiznet5k;