@@ -93,6 +93,16 @@ int wiznet5k_gethostbyname(mp_obj_t nic, const char *name, mp_uint_t len, uint8_
9393 }
9494}
9595
96+ int get_available_socket (wiznet5k_obj_t * wiz ) {
97+ for (uint8_t sn = 0 ; sn < _WIZCHIP_SOCK_NUM_ ; sn ++ ) {
98+ if ((wiz -> socket_used & (1 << sn )) == 0 ) {
99+ wiz -> socket_used |= (1 << sn );
100+ return sn ;
101+ }
102+ }
103+ return -1 ;
104+ }
105+
96106int wiznet5k_socket_socket (mod_network_socket_obj_t * socket , int * _errno ) {
97107 if (socket -> u_param .domain != MOD_NETWORK_AF_INET ) {
98108 * _errno = MP_EAFNOSUPPORT ;
@@ -107,13 +117,7 @@ int wiznet5k_socket_socket(mod_network_socket_obj_t *socket, int *_errno) {
107117
108118 if (socket -> u_param .fileno == -1 ) {
109119 // get first unused socket number
110- for (mp_uint_t sn = 0 ; sn < _WIZCHIP_SOCK_NUM_ ; sn ++ ) {
111- if ((wiznet5k_obj .socket_used & (1 << sn )) == 0 ) {
112- wiznet5k_obj .socket_used |= (1 << sn );
113- socket -> u_param .fileno = sn ;
114- break ;
115- }
116- }
120+ socket -> u_param .fileno = get_available_socket (& wiznet5k_obj );
117121 if (socket -> u_param .fileno == -1 ) {
118122 // too many open sockets
119123 * _errno = MP_EMFILE ;
@@ -199,8 +203,12 @@ int wiznet5k_socket_accept(mod_network_socket_obj_t *socket, mod_network_socket_
199203}
200204
201205int wiznet5k_socket_connect (mod_network_socket_obj_t * socket , byte * ip , mp_uint_t port , int * _errno ) {
206+ uint16_t src_port = network_module_create_random_source_tcp_port ();
207+ // make sure same outgoing port number can't be in use by two different sockets.
208+ src_port = (src_port & ~(_WIZCHIP_SOCK_NUM_ - 1 )) | socket -> u_param .fileno ;
209+
202210 // use "bind" function to open the socket in client mode
203- if (wiznet5k_socket_bind (socket , ip , 0 , _errno ) != 0 ) {
211+ if (wiznet5k_socket_bind (socket , NULL , src_port , _errno ) != 0 ) {
204212 return -1 ;
205213 }
206214
@@ -318,33 +326,56 @@ int wiznet5k_socket_ioctl(mod_network_socket_obj_t *socket, mp_uint_t request, m
318326}
319327
320328void wiznet5k_socket_timer_tick (mod_network_socket_obj_t * socket ) {
321- if (wiznet5k_obj .dhcp_active ) {
329+ if (wiznet5k_obj .dhcp_socket >= 0 ) {
322330 DHCP_time_handler ();
323331 DHCP_run ();
324332 }
325333}
326334
327- void wiznet5k_start_dhcp (void ) {
335+ int wiznet5k_start_dhcp (void ) {
336+ // XXX this should throw an error if DHCP fails
328337 static DHCP_INIT_BUFFER_TYPE dhcp_buf [DHCP_INIT_BUFFER_SIZE ];
329338
330- if (! wiznet5k_obj .dhcp_active ) {
339+ if (wiznet5k_obj .dhcp_socket < 0 ) {
331340 // Set up the socket to listen on UDP 68 before calling DHCP_init
332- WIZCHIP_EXPORT (socket )(0 , MOD_NETWORK_SOCK_DGRAM , DHCP_CLIENT_PORT , 0 );
333- DHCP_init (0 , dhcp_buf );
334- wiznet5k_obj .dhcp_active = 1 ;
341+ wiznet5k_obj .dhcp_socket = get_available_socket (& wiznet5k_obj );
342+ if (wiznet5k_obj .dhcp_socket < 0 ) return MP_EMFILE ;
343+
344+ WIZCHIP_EXPORT (socket )(wiznet5k_obj .dhcp_socket , MOD_NETWORK_SOCK_DGRAM , DHCP_CLIENT_PORT , 0 );
345+ DHCP_init (wiznet5k_obj .dhcp_socket , dhcp_buf );
335346 }
347+ return 0 ;
336348}
337349
338- void wiznet5k_stop_dhcp (void ) {
339- if (wiznet5k_obj .dhcp_active ) {
340- wiznet5k_obj .dhcp_active = 0 ;
350+ int wiznet5k_stop_dhcp (void ) {
351+ if (wiznet5k_obj .dhcp_socket >= 0 ) {
341352 DHCP_stop ();
342- WIZCHIP_EXPORT (close )(0 );
353+ WIZCHIP_EXPORT (close )(wiznet5k_obj .dhcp_socket );
354+ wiznet5k_obj .socket_used &= ~(1 << wiznet5k_obj .dhcp_socket );
355+ wiznet5k_obj .dhcp_socket = -1 ;
343356 }
357+ return 0 ;
344358}
345359
346360bool wiznet5k_check_dhcp (void ) {
347- return wiznet5k_obj .dhcp_active ;
361+ return wiznet5k_obj .dhcp_socket >= 0 ;
362+ }
363+
364+ void wiznet5k_reset (void ) {
365+ if (wiznet5k_obj .rst .pin ) {
366+ // hardware reset if using RST pin
367+ common_hal_digitalio_digitalinout_set_value (& wiznet5k_obj .rst , 0 );
368+ mp_hal_delay_us (10 ); // datasheet says 2us
369+ common_hal_digitalio_digitalinout_set_value (& wiznet5k_obj .rst , 1 );
370+ mp_hal_delay_ms (150 ); // datasheet says 150ms
371+ } else {
372+ // otherwise, software reset
373+ wizchip_sw_reset ();
374+ }
375+ }
376+
377+ void wiznet5k_socket_deinit (mod_network_socket_obj_t * socket ) {
378+ wiznet5k_reset ();
348379}
349380
350381/// 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) {
354385 wiznet5k_obj .base .type = (mp_obj_type_t * )& mod_network_nic_type_wiznet5k ;
355386 wiznet5k_obj .cris_state = 0 ;
356387 wiznet5k_obj .spi = MP_OBJ_TO_PTR (spi_in );
357- common_hal_digitalio_digitalinout_construct (& wiznet5k_obj .cs , cs_in );
358- common_hal_digitalio_digitalinout_construct (& wiznet5k_obj .rst , rst_in );
359388 wiznet5k_obj .socket_used = 0 ;
389+ wiznet5k_obj .dhcp_socket = -1 ;
360390
361391 /*!< SPI configuration */
362392 // 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) {
369399 8 // 8 BITS
370400 );
371401
402+ common_hal_digitalio_digitalinout_construct (& wiznet5k_obj .cs , cs_in );
372403 common_hal_digitalio_digitalinout_switch_to_output (& wiznet5k_obj .cs , 1 , DRIVE_MODE_PUSH_PULL );
373- common_hal_digitalio_digitalinout_switch_to_output (& wiznet5k_obj .rst , 1 , DRIVE_MODE_PUSH_PULL );
374404
375- common_hal_digitalio_digitalinout_set_value (& wiznet5k_obj .rst , 0 );
376- mp_hal_delay_us (10 ); // datasheet says 2us
377- common_hal_digitalio_digitalinout_set_value (& wiznet5k_obj .rst , 1 );
378- mp_hal_delay_ms (160 ); // datasheet says 150ms
405+ if (rst_in ) common_hal_digitalio_digitalinout_construct (& wiznet5k_obj .rst , rst_in );
406+ wiznet5k_reset ();
379407
380408 reg_wizchip_cris_cbfunc (wiz_cris_enter , wiz_cris_exit );
381409 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) {
394422 // seems we need a small delay after init
395423 mp_hal_delay_ms (250 );
396424
397- wiznet5k_start_dhcp ();
398-
399425 // register with network module
400426 network_module_register_nic (& wiznet5k_obj );
401427
0 commit comments