diff options
author | Luke T. Shumaker <lukeshu@lukeshu.com> | 2024-10-13 22:28:39 -0600 |
---|---|---|
committer | Luke T. Shumaker <lukeshu@lukeshu.com> | 2024-10-13 22:28:39 -0600 |
commit | 1427269e8650964713505728eda84bfec1f685e1 (patch) | |
tree | 121f2e0113d38d258d8a69a90e0a58e9a870063a /libnetio | |
parent | 7efdc721db9220642778a1183ec24ee2762b8ee8 (diff) |
wip
Diffstat (limited to 'libnetio')
-rw-r--r-- | libnetio/w5500_spiframe.c | 144 |
1 files changed, 0 insertions, 144 deletions
diff --git a/libnetio/w5500_spiframe.c b/libnetio/w5500_spiframe.c deleted file mode 100644 index d300999..0000000 --- a/libnetio/w5500_spiframe.c +++ /dev/null @@ -1,144 +0,0 @@ -/* A u8 control byte has 3 parts: block-ID, R/W, and - * operating-mode. */ - -/* Part 1: Block ID. */ -#define CTL_MASK_BLOCK 0b11111'000 -#define _CTL_BLOCK_RES (0b00'000) -#define _CTL_BLOCK_REG (0b01'000) -#define _CTL_BLOCK_TX (0b10'000) -#define _CTL_BLOCK_RX (0b11'000) -#define CTL_BLOCK_SOCK(n,part) (((n)<<5)|(_CTL_BLOCK_##part)) -#define CTL_BLOCK_COMMON_REG CTL_BLOCK_SOCK(0,RES) - -/* Part 2: R/W. */ -#define CTL_MASK_RW 0b1'00 -#define CTL_R 0b0'00 -#define CTL_W 0b1'00 - -/* Part 3: Operating mode. */ -#define CTL_MASK_OM 0b11 -#define CTL_OM_VDM 0b00 -#define CTL_OM_FDM1 0b01 -#define CTL_OM_FDM2 0b10 -#define CTL_OM_FDM4 0b11 - -/* The W5500 has 2 channels 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.) - * - * Even though SPI is a full-duplex protocol, the W5500's RPC protocol - * on top of it is only half-duplex. Lame. - */ - -void w5500_spiframe_write(struct spi *spidev, uint16_t addr, uint8_t block, void *data, size_t data_len) { - assert(spidev); - assert((block & ~CTL_MASK_BLOCK) == 0); - assert(data); - assert(data_len); - - uint8_t header[3] = { - (uint8_t)((addr >> 8) & 0xFF), - (uint8_t)(addr & 0xFF), - (block & CTL_MASK_BLOCK) | CTL_W | CTL_OM_VDM, - }; - struct bidi_iovec iov[] = { - {.iov_read_dst = NULL, .iov_write_src = header, .iov_len = sizeof(header)}, - {.iov_read_dst = NULL, .iov_write_src = data, .iov_len = data_len}, - }; - spidev->vtable->readwritev(spidev, iov, 2); -} - -void w5500_spiframe_read(uint16_t addr, uint8_t ctl, void *data, size_t data_len) { - assert(spidev); - assert((block & ~CTL_MASK_BLOCK) == 0); - assert(data); - assert(data_len); - - uint8_t header[3] = { - (uint8_t)((addr >> 8) & 0xFF), - (uint8_t)(addr & 0xFF), - (block & CTL_MASK_BLOCK) | CTL_R | CTL_OM_VDM, - }; - struct bidi_iovec iov[] = { - {.iov_read_dst = NULL, .iov_write_src = header, .iov_len = sizeof(header)}, - {.iov_read_dst = data, .iov_write_src = NULL, .iov_len = data_len}, - }; - spidev->vtable->readwritev(spidev, iov, 2); -} - -struct w5500_block_common_reg { - uint8_t mode; /* MR */ - uint8_t ip_gateway_addr[4]; /* GAR0 ... GAR3 */ - uint8_t ip_subnet_mask[4]; /* SUBR0 ... SUBR3 */ - uint8_t eth_addr[6]; /* SHAR0 ... SHAR5 */ - uint8_t ip_addr[4]; /* SIPR0 ... SIPR3 */ - - uint8_t intlevel_0; /* INTLEVEL0 */ - uint8_t intlevel_1; /* INTLEVEL1 */ - uint8_t interrupt; /* IR */ - uint8_t interrupt_mask; /* IMR */ - uint8_t sock_interrupt; /* SIR */ - uint8_t sock_interrupt_mask; /* SIMR */ - uint8_t retry_time_0; /* RTR0 */ - uint8_t retry_time_1; /* RTR0 */ - uint8_t retry_count; /* RCR */ - - uint8_t ppp_lcp_request_timer; /* PTIMER */ - uint8_t ppp_lcp_magic_bumber; /* PMAGIC */ - uint8_t ppp_dst_eth_addr[6]; /* PHAR0 ... PHAR5 */ - uint8_t ppp_sess_id[2]; /* PSID0 ... PSID1 */ - uint8_t ppp_max_seg_size[2]; /* PMRU0 ... PMRU1 */ - - uint8_t unreachable_ip_addr[4]; /* UIPR0 ... UIPR3 */ - uint8_t unreachable_port[2]; /* UPORTR0, UPROTR1 */ - - uint8_t phy_cfg; /* PHYCFGR */ - - uint8_t _reserved[10]; - - uint8_t chip_version; /* VERSIONR */ -}; -static_assert(sizeof(struct w5500_block_common_reg) == 0x3A); - -struct w5500_block_sock_reg { - uint8_t mode; /* Sn_MR */ - uint8_t command; /* Sn_CR */ - uint8_t interrupt; /* Sn_IR */ - uint8_t status; /* Sn_SR */ - uint8_t src_port[2]; /* Sn_PORT0, Sn_PORT1 */ - uint8_t dst_eth_addr[6]; /* Sn_DHAR0 ... SnDHAR5 */ - uint8_t dst_ip_addr[4]; /* Sn_DIPR0 ... Sn_DIP3 */ - uint8_t dst_port[2]; /* Sn_DPORT0 ... Sn_DPORT1 */ - - uint8_t max_seg_size[2]; /* Sn_MSSR0, Sn_MSSR1 */ - uint8_t _reserved0[1]; - uint8_t ip_tos; /* Sn_TOS */ - uint8_t ip_ttl; /* Sn_TTL */ - uint8_t _reserved1[7]; - - uint8_t rx_buf_size; /* Sn_RXBUF_SIZE */ - uint8_t tx_buf_size; /* Sn_TXBUF_SIZE */ - uint8_t tx_free_size[2]; /* Sn_TX_FSR0, Sn_TX_FSR1 */ - uint8_t tx_read_pointer[2]; /* Sn_TX_RD0, Sn_TX_RD1 */ - uint8_t tx_write_pointer[2]; /* Sn_TX_WR0, Sn_TX_WR1 */ - uint8_t rx_size[2]; /* Sn_RX_RSR0, Sn_RX_RSR1 */ - uint8_t rx_read_pointer[2]; /* Sn_RX_RD0, Sn_RX_RD1 */ - uint8_t rx_write_pointer[2]; /* Sn_RX_WR0, Sn_RX_WR1 */ - - uint8_t interrupt_mask; /* Sn_IMR */ - uint8_t fragment_offset[2]; /* Sn_FRAG0, Sn_FRAG1 */ - uint8_t keepalive_timer; /* Sn_KPALVTR */ -}; -static_assert(sizeof(struct w5500_block_sock_reg) == 0x30); - - -struct w5500_socket { - struct spi *spidev; - uint8_t socknum; /* 0-7 */ -}; |