diff options
author | Luke T. Shumaker <lukeshu@lukeshu.com> | 2025-09-28 17:01:59 -0600 |
---|---|---|
committer | Luke T. Shumaker <lukeshu@lukeshu.com> | 2025-09-28 17:01:59 -0600 |
commit | fce80f2dc24ef45142ff92f74ebf809a39e06768 (patch) | |
tree | 01c591ca26460e7ca30597a85adff173d1ffc9a0 /libhw_cr/rp2040_include | |
parent | bbf836c886a348bab4fad92d7ba448d1bbc9c910 (diff) | |
parent | 35c0f64218f4aa562f2dcde8eace87962bcab4e4 (diff) |
Diffstat (limited to 'libhw_cr/rp2040_include')
-rw-r--r-- | libhw_cr/rp2040_include/libhw/w5500.h | 24 |
1 files changed, 18 insertions, 6 deletions
diff --git a/libhw_cr/rp2040_include/libhw/w5500.h b/libhw_cr/rp2040_include/libhw/w5500.h index 43c58a3..d4ca4de 100644 --- a/libhw_cr/rp2040_include/libhw/w5500.h +++ b/libhw_cr/rp2040_include/libhw/w5500.h @@ -12,6 +12,7 @@ #include <libcr_ipc/chan.h> #include <libcr_ipc/mutex.h> #include <libcr_ipc/sema.h> +#include <libmisc/linkedlist.h> #include <libmisc/private.h> #include <libhw/generic/net.h> @@ -41,19 +42,23 @@ struct _w5500_socket { END_PRIVATE(LIBHW_W5500_H); }; +SLIST_DECLARE(_w5500_link_waitlist); + struct w5500 { BEGIN_PRIVATE(LIBHW_W5500_H); /* const-after-init */ lo_interface spi spidev; uint pin_intr; uint pin_reset; + uint pin_linkled; struct net_eth_addr hwaddr; /* mutable */ uint16_t next_local_port; struct _w5500_socket sockets[8]; struct _w5500_socket *free; - cr_sema_t intr; + cr_sema_t intr_sema; + struct _w5500_link_waitlist linkup_waiters; cr_mutex_t mu; END_PRIVATE(LIBHW_W5500_H); }; @@ -72,14 +77,21 @@ LO_IMPLEMENTATION_H(net_iface, struct w5500, w5500_if); * the MCU know that it should do an SPI RPC "get" to see what * happened.) * - A reset pin that the MCU can pull low to reset the W5500. + * + * Additionally (even though it isn't supposed to be a line of + * communication with the MCU) we watch the link-LED output of the + * W5500 (low=has link, high=no link) to know when to do an SPI RPC + * "get" on the PHYCFG register for link status, since that isn't one + * of the things that triggers the interrupt pin. */ -#define w5500_init(self, name, spi, pin_intr, pin_reset, eth_addr) do { \ - bi_decl(bi_2pins_with_names(pin_intr, name" interrupt", \ - pin_reset, name" reset")); \ - _w5500_init(self, spi, pin_intr, pin_reset, eth_addr); \ +#define w5500_init(self, name, spi, pin_intr, pin_reset, pin_linkled, eth_addr) do { \ + bi_decl(bi_3pins_with_names(pin_intr, name" interrupt", \ + pin_reset, name" reset", \ + pin_linkled, name" link-LED")); \ + _w5500_init(self, spi, pin_intr, pin_reset, pin_linkled, eth_addr); \ } while (0) void _w5500_init(struct w5500 *self, - lo_interface spi spi, uint pin_intr, uint pin_reset, + lo_interface spi spi, uint pin_intr, uint pin_reset, uint pin_linkled, struct net_eth_addr addr); /** |