diff options
Diffstat (limited to 'cmd/sbc_harness/hw/w5500.c')
-rw-r--r-- | cmd/sbc_harness/hw/w5500.c | 93 |
1 files changed, 46 insertions, 47 deletions
diff --git a/cmd/sbc_harness/hw/w5500.c b/cmd/sbc_harness/hw/w5500.c index bfeacee..b868eaa 100644 --- a/cmd/sbc_harness/hw/w5500.c +++ b/cmd/sbc_harness/hw/w5500.c @@ -109,43 +109,6 @@ *} */ -static struct w5500 *w5500_sock_chip(struct _w5500_listener *listener) { - assert(listener); - assert(listener->socknum < 8); - - struct _w5500_listener *sock0 = &listener[-listener->socknum]; - assert(sock0); - struct w5500 *chip = - ((void *)sock0) - offsetof(struct w5500, listeners); - assert(chip); - return chip; -} - -static inline void w5500_sock_cmd(struct _w5500_listener *listener, uint8_t cmd) { - assert(listener); - struct w5500 *chip = w5500_sock_chip(listener); - uint8_t socknum = listener->socknum; - - cr_mutex_lock(&listener->cmd_mu); - w5500ll_write_sock_reg(chip->spidev, socknum, command, cmd); - while (w5500ll_read_sock_reg(chip->spidev, socknum, command) != 0x00) - cr_yield(); - cr_mutex_unlock(&listener->cmd_mu); -} - -static void w5500_sock_cmd_close(struct _w5500_listener *listener) { - assert(listener); - struct w5500 *chip = w5500_sock_chip(listener); - uint8_t socknum = listener->socknum; - - w5500_sock_cmd(listener, CMD_CLOSE); - w5500ll_write_sock_reg(chip->spidev, socknum, interrupt, 0xFF); - while (w5500ll_read_sock_reg(chip->spidev, socknum, state) != STATE_CLOSED) - cr_yield(); - - listener->active_conn.read_open = listener->active_conn.write_open = false; -} - static COROUTINE w5500_irq_cr(void *_chip) { struct w5500 *chip = _chip; cr_begin(); @@ -196,7 +159,6 @@ static struct net_conn_vtable w5500_conn_vtable = { .close = w5500_close, }; - static struct w5500 *w5500_chips[CONFIG_W5500_NUM] = {0}; static void w5500_intrhandler(uint gpio, uint32_t UNUSED(event_mask)) { @@ -315,11 +277,48 @@ implements_net_listener *w5500_listen(struct w5500 *chip, uint8_t socknum, /* listener methods ***********************************************************/ +static struct w5500 *w5500_listener_chip(struct _w5500_listener *listener) { + assert(listener); + assert(listener->socknum < 8); + + struct _w5500_listener *sock0 = &listener[-listener->socknum]; + assert(sock0); + struct w5500 *chip = + ((void *)sock0) - offsetof(struct w5500, listeners); + assert(chip); + return chip; +} + +static inline void w5500_listener_cmd(struct _w5500_listener *listener, uint8_t cmd) { + assert(listener); + struct w5500 *chip = w5500_listener_chip(listener); + uint8_t socknum = listener->socknum; + + cr_mutex_lock(&listener->cmd_mu); + w5500ll_write_sock_reg(chip->spidev, socknum, command, cmd); + while (w5500ll_read_sock_reg(chip->spidev, socknum, command) != 0x00) + cr_yield(); + cr_mutex_unlock(&listener->cmd_mu); +} + +static inline void w5500_listener_cmd_close(struct _w5500_listener *listener) { + assert(listener); + struct w5500 *chip = w5500_listener_chip(listener); + uint8_t socknum = listener->socknum; + + w5500_listener_cmd(listener, CMD_CLOSE); + w5500ll_write_sock_reg(chip->spidev, socknum, interrupt, 0xFF); + while (w5500ll_read_sock_reg(chip->spidev, socknum, state) != STATE_CLOSED) + cr_yield(); + + listener->active_conn.read_open = listener->active_conn.write_open = false; +} + #define ASSERT_LISTENER() \ struct _w5500_listener *self = \ VCALL_SELF(struct _w5500_listener, \ implements_net_listener, _self); \ - struct w5500 *chip = w5500_sock_chip(self); \ + struct w5500 *chip = w5500_listener_chip(self); \ uint8_t socknum = self->socknum; static implements_net_conn *w5500_accept(implements_net_listener *_self) { @@ -327,15 +326,15 @@ static implements_net_conn *w5500_accept(implements_net_listener *_self) { restart: /* Mimics socket.c:socket(). */ - w5500_sock_cmd_close(self); + w5500_listener_cmd_close(self); w5500ll_write_sock_reg(chip->spidev, socknum, mode, SOCKMODE_TCP); w5500ll_write_sock_reg(chip->spidev, socknum, local_port, encode_u16be(self->port)); - w5500_sock_cmd(self, CMD_OPEN); + w5500_listener_cmd(self, CMD_OPEN); while (w5500ll_read_sock_reg(chip->spidev, socknum, state) != STATE_TCP_INIT) cr_yield(); /* Mimics socket.c:listen(). */ - w5500_sock_cmd(self, CMD_LISTEN); + w5500_listener_cmd(self, CMD_LISTEN); for (;;) { uint8_t state = w5500ll_read_sock_reg(chip->spidev, socknum, state); switch (state) { @@ -369,7 +368,7 @@ static struct _w5500_listener *w5500_conn_listener(struct _w5500_conn *conn) { struct _w5500_conn *self = \ VCALL_SELF(struct _w5500_conn, implements_net_conn, _self); \ struct _w5500_listener *listener = w5500_conn_listener(self); \ - struct w5500 *chip = w5500_sock_chip(listener); \ + struct w5500 *chip = w5500_listener_chip(listener); \ uint8_t socknum = listener->socknum; static ssize_t w5500_write(implements_net_conn *_self, void *buf, size_t count) { @@ -417,7 +416,7 @@ static ssize_t w5500_write(implements_net_conn *_self, void *buf, size_t count) w5500ll_write_sock_reg(chip->spidev, socknum, tx_write_pointer, encode_u16be(ptr+freesize)); /* Submit the queue. */ - w5500_sock_cmd(listener, CMD_SEND); + w5500_listener_cmd(listener, CMD_SEND); done += freesize; } return done; @@ -453,7 +452,7 @@ static ssize_t w5500_read(implements_net_conn *_self, void *buf, size_t count) { w5500ll_read(chip->spidev, ptr, CTL_BLOCK_SOCK(socknum, RX), &((char *)buf)[done], avail); w5500ll_write_sock_reg(chip->spidev, socknum, rx_read_pointer, encode_u16be(ptr+avail)); - w5500_sock_cmd(listener, CMD_RECV); + w5500_listener_cmd(listener, CMD_RECV); done += avail; } return done; @@ -466,7 +465,7 @@ static int w5500_close(implements_net_conn *_self, bool rd, bool wr) { self->read_open = false; if (wr && self->write_open) { - w5500_sock_cmd(listener, CMD_DISCON); + w5500_listener_cmd(listener, CMD_DISCON); while (self->write_open) { uint8_t state = w5500ll_read_sock_reg(chip->spidev, socknum, state); switch (state) { @@ -474,7 +473,7 @@ static int w5500_close(implements_net_conn *_self, bool rd, bool wr) { self->write_open = false; /* Can still read */ if (!self->read_open) - w5500_sock_cmd_close(listener); + w5500_listener_cmd_close(listener); break; case STATE_CLOSED: self->write_open = false; |