/* hw/w5500.h - libmisc/net.h implementation for the WIZnet W5500 chip * * Copyright (C) 2024 Luke T. Shumaker * SPDX-Licence-Identifier: AGPL-3.0-or-later */ #ifndef _HW_W5500_H_ #define _HW_W5500_H_ #include #include #include #include "hw/spi.h" struct _w5500_tcp_conn { /* const-after-init */ implements_net_stream_conn; /* mutable */ bool read_open; bool write_open; }; struct _w5500_tcp_listener { /* const-after-init */ implements_net_stream_listener; uint8_t socknum; struct _w5500_tcp_conn active_conn; /* mutable */ uint16_t port; cr_mutex_t cmd_mu; cr_sema_t listen_sema, read_sema; }; struct w5500 { /* const-after-init */ struct spi *spidev; uint pin_intr; uint pin_reset; struct net_eth_addr hwaddr; /* mutable */ uint16_t next_local_port; struct _w5500_tcp_listener listeners[8]; cr_sema_t intr; }; /** * Initialize a WIZnet W5500 Ethernet-and-TCP/IP-offload chip. * * The W5500 has 3 lines of communication with the MCU: * * - An SPI-based RPC protocol: * + mode: mode 0 or mode 3 * + bit-order: MSB-first * + clock frequency: 33.3MHz - 80MHz * - An interrupt pin that it pulls low when an event happens (to let * 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. */ #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); \ } while (0) void _w5500_init(struct w5500 *self, struct spi* spi, uint pin_intr, uint pin_reset, struct net_eth_addr addr); /** * TODO. */ void w5500_hard_reset(struct w5500 *self); /** * TODO. */ void w5500_soft_reset(struct w5500 *self); struct w5500_netcfg { struct net_ip4_addr gateway_addr; struct net_ip4_addr subnet_mask; struct net_ip4_addr addr; }; /** * TODO. */ void w5500_netcfg(struct w5500 *self, struct w5500_netcfg cfg); implements_net_stream_listener *w5500_tcp_listen(struct w5500 *self, uint8_t socknum, uint16_t port); /** * TODO. */ implements_net_packet_conn *w5500_udp_conn(struct w5500 *self, uint8_t socknum, uint16_t port); #endif /* _HW_W5500_H_ */