summaryrefslogtreecommitdiff
path: root/libhw/w5500_ll.h
diff options
context:
space:
mode:
authorLuke T. Shumaker <lukeshu@lukeshu.com>2024-12-09 12:24:52 -0700
committerLuke T. Shumaker <lukeshu@lukeshu.com>2024-12-09 12:24:52 -0700
commit87646c7959726bc0556d28f78fb730edd8365410 (patch)
tree087f074391f4beccc08626f966d945d0cad60aba /libhw/w5500_ll.h
parent96a751d8a5d20b2acea5ae8d10ac3d051466c2c3 (diff)
parentb1414723ab4171a7ca5fc5e8a5ac7c4eb43331e2 (diff)
Merge commit 'b1414723ab4171a7ca5fc5e8a5ac7c4eb43331e2'
Diffstat (limited to 'libhw/w5500_ll.h')
-rw-r--r--libhw/w5500_ll.h67
1 files changed, 54 insertions, 13 deletions
diff --git a/libhw/w5500_ll.h b/libhw/w5500_ll.h
index c70da0d..25aa6b5 100644
--- a/libhw/w5500_ll.h
+++ b/libhw/w5500_ll.h
@@ -20,18 +20,26 @@
#include <libhw/generic/net.h> /* for struct net_eth_addr, struct net_ip4_addr */
#include <libhw/generic/spi.h> /* for implements_spi */
+/* Config *********************************************************************/
+
+#include "config.h"
+
+#ifndef CONFIG_W5500_LL_DEBUG
+ #error config.h must define CONFIG_W5500_LL_DEBUG
+#endif
+
/* Low-level protocol built on SPI frames. ***********************************/
/* A u8 control byte has 3 parts: block-ID, R/W, and operating-mode. */
/* Part 1: Block ID. */
-#define CTL_MASK_BLOCK 0b11111000
-#define _CTL_BLOCK_RES 0b00000
-#define _CTL_BLOCK_REG 0b01000
-#define _CTL_BLOCK_TX 0b10000
-#define _CTL_BLOCK_RX 0b11000
+#define CTL_MASK_BLOCK 0b11111000
+#define _CTL_BLOCK_RES 0b00000 /* chip-wide registers on socknum=0, REServed on socknum>=1 */
+#define _CTL_BLOCK_REG 0b01000 /* socknum-specific registers */
+#define _CTL_BLOCK_TX 0b10000 /* socknum-specific transmit buffer */
+#define _CTL_BLOCK_RX 0b11000 /* socknum-specific receive buffer */
#define CTL_BLOCK_SOCK(n,part) (((n)<<5)|(_CTL_BLOCK_##part))
-#define CTL_BLOCK_COMMON_REG CTL_BLOCK_SOCK(0,RES)
+#define CTL_BLOCK_COMMON_REG CTL_BLOCK_SOCK(0,RES)
/* Part 2: R/W. */
#define CTL_MASK_RW 0b100
@@ -40,20 +48,42 @@
/* 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
+#define CTL_OM_VDM 0b00 /* variable-length data mode */
+#define CTL_OM_FDM1 0b01 /* fixed-length data mode: 1 byte data length */
+#define CTL_OM_FDM2 0b10 /* fixed-length data mode: 2 byte data length */
+#define CTL_OM_FDM4 0b11 /* fixed-length data mode: 4 byte data length */
+
+#if CONFIG_W5500_LL_DEBUG
+static char *_ctl_block_part_strs[] = {
+ "RES",
+ "REG",
+ "TX",
+ "RX",
+};
+#define PRI_ctl_block "CTL_BLOCK_SOCK(%d, %s)"
+#define ARG_ctl_block(b) (((b)>>5) & 0b111), _ctl_block_part_strs[((b)>>3)&0b11]
+#endif
/* Even though SPI is a full-duplex protocol, the W5500's spiframe on top of it is only half-duplex.
* Lame. */
static inline void
-w5500ll_write(implements_spi *spidev, uint16_t addr, uint8_t block, void *data, size_t data_len) {
+#if CONFIG_W5500_LL_DEBUG
+#define w5500ll_write(...) _w5500ll_write(__func__, __VA_ARGS__)
+_w5500ll_write(const char *func,
+#else
+w5500ll_write(
+#endif
+ implements_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);
+#if CONFIG_W5500_LL_DEBUG
+ n_debugf(W5500_LL,
+ "%s(): w5500ll_write(spidev, addr=%#04x, block="PRI_ctl_block", data, data_len=%zu)",
+ func, addr, ARG_ctl_block(block), data_len);
+#endif
uint8_t header[3] = {
(uint8_t)((addr >> 8) & 0xFF),
@@ -68,11 +98,22 @@ w5500ll_write(implements_spi *spidev, uint16_t addr, uint8_t block, void *data,
}
static inline void
-w5500ll_read(implements_spi *spidev, uint16_t addr, uint8_t block, void *data, size_t data_len) {
+#if CONFIG_W5500_LL_DEBUG
+#define w5500ll_read(...) _w5500ll_read(__func__, __VA_ARGS__)
+_w5500ll_read(const char *func,
+#else
+w5500ll_read(
+#endif
+ implements_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);
+#if CONFIG_W5500_LL_DEBUG
+ n_debugf(W5500_LL,
+ "%s(): w5500ll_read(spidev, addr=%#04x, block="PRI_ctl_block", data, data_len=%zu)",
+ func, addr, ARG_ctl_block(block), data_len);
+#endif
uint8_t header[3] = {
(uint8_t)((addr >> 8) & 0xFF),
@@ -222,7 +263,7 @@ static_assert(sizeof(struct w5500ll_block_sock_reg) == 0x30);
#define SOCKINTR_SEND_TIMEOUT ((uint8_t)1<<3) /* ARP or TCP */
#define SOCKINTR_RECV_DAT ((uint8_t)1<<2) /* received data */
#define SOCKINTR_RECV_FIN ((uint8_t)1<<1) /* received FIN */
-#define SOCKINTR_CONN ((uint8_t)1<<1) /* first for SYN, then when SOCKMODE_ESTABLISHED */
+#define SOCKINTR_CONN ((uint8_t)1<<0) /* first for SYN, then when SOCKMODE_ESTABLISHED */
#define STATE_CLOSED ((uint8_t)0x00)