summaryrefslogtreecommitdiff
path: root/libhw
diff options
context:
space:
mode:
Diffstat (limited to 'libhw')
-rw-r--r--libhw/w5500.c10
-rw-r--r--libhw/w5500_ll.h41
2 files changed, 32 insertions, 19 deletions
diff --git a/libhw/w5500.c b/libhw/w5500.c
index e675ae9..7a5ba01 100644
--- a/libhw/w5500.c
+++ b/libhw/w5500.c
@@ -239,6 +239,7 @@ static COROUTINE w5500_irq_cr(void *_chip) {
struct _w5500_socket *socket = &chip->sockets[socknum];
uint8_t sockintr = w5500ll_read_sock_reg(chip->spidev, socknum, interrupt);
+ debugf("w5500_irq_cr(): sockintr=%"PRIu8, sockintr);
switch (socket->mode) {
case W5500_MODE_NONE:
@@ -363,15 +364,6 @@ void _w5500_init(struct w5500 *chip,
};
}
- /* Validate that SPI works correctly. */
- for (uint16_t a = 0; a < 0x100; a++) {
- w5500ll_write_sock_reg(chip->spidev, 0, mode, a);
- uint8_t b = w5500ll_read_sock_reg(chip->spidev, 0, mode);
- if (b != a)
- errorf("SPI to W5500 does not appear to be functional: wrote:%d != read:%d", a, b);
- }
- w5500ll_write_sock_reg(chip->spidev, 0, mode, 0);
-
/* Initialize the hardware. */
gpio_set_irq_enabled_with_callback(pin_intr, GPIO_IRQ_EDGE_FALL, true, w5500_intrhandler);
gpio_set_dir(chip->pin_reset, GPIO_OUT);
diff --git a/libhw/w5500_ll.h b/libhw/w5500_ll.h
index 5c61b6f..827d60f 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_DEBUG
+ #error config.h must define CONFIG_W5500_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,10 +48,19 @@
/* 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 */
+
+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]
/* Even though SPI is a full-duplex protocol, the W5500's spiframe on top of it is only half-duplex.
* Lame. */
@@ -54,6 +71,8 @@ w5500ll_write(implements_spi *spidev, uint16_t addr, uint8_t block, void *data,
assert((block & ~CTL_MASK_BLOCK) == 0);
assert(data);
assert(data_len);
+ debugf("w5500ll_write(spidev, addr=%#04x, block="PRI_ctl_block", data, data_len=%zu)",
+ addr, ARG_ctl_block(block), data_len);
uint8_t header[3] = {
(uint8_t)((addr >> 8) & 0xFF),
@@ -73,6 +92,8 @@ w5500ll_read(implements_spi *spidev, uint16_t addr, uint8_t block, void *data, s
assert((block & ~CTL_MASK_BLOCK) == 0);
assert(data);
assert(data_len);
+ debugf("w5500ll_read(spidev, addr=%#04x, block="PRI_ctl_block", data, data_len=%zu)",
+ addr, ARG_ctl_block(block), data_len);
uint8_t header[3] = {
(uint8_t)((addr >> 8) & 0xFF),