diff options
author | Luke T. Shumaker <lukeshu@lukeshu.com> | 2024-11-30 10:30:42 -0700 |
---|---|---|
committer | Luke T. Shumaker <lukeshu@lukeshu.com> | 2024-11-30 10:33:27 -0700 |
commit | e8f09fdd0e0aa7e17317a58474058b9272a12f93 (patch) | |
tree | 255e43c5d4f9a2a3974af2f8764ee93cbd975bb2 /libhw/w5500.c | |
parent | 4258cb9dc66296e2222e706df8924878867b8a23 (diff) |
w5500: Verify that the INTR line goes high before blocking
Diffstat (limited to 'libhw/w5500.c')
-rw-r--r-- | libhw/w5500.c | 60 |
1 files changed, 31 insertions, 29 deletions
diff --git a/libhw/w5500.c b/libhw/w5500.c index 563fd8b..c1607f1 100644 --- a/libhw/w5500.c +++ b/libhw/w5500.c @@ -206,37 +206,39 @@ static COROUTINE w5500_irq_cr(void *_chip) { cr_begin(); for (;;) { - cr_sema_wait(&chip->intr); - if (w5500ll_read_common_reg(chip->spidev, chip_interrupt)) - w5500ll_write_common_reg(chip->spidev, chip_interrupt, 0xFF); - - uint8_t sockmask = w5500ll_read_common_reg(chip->spidev, sock_interrupt); - for (uint8_t socknum = 0; socknum < 8; socknum++) { - if (!(sockmask & (1<<socknum))) - continue; - struct _w5500_socket *socket = &chip->sockets[socknum]; - - uint8_t sockintr = w5500ll_read_sock_reg(chip->spidev, socknum, interrupt); - - switch (socket->mode) { - case W5500_MODE_NONE: - break; - case W5500_MODE_TCP: case W5500_MODE_UDP: - uint8_t listen_bits = sockintr & SOCKINTR_CONN, - send_bits = sockintr & (SOCKINTR_SEND_OK|SOCKINTR_SEND_TIMEOUT), - recv_bits = sockintr & (SOCKINTR_RECV_DAT|SOCKINTR_RECV_FIN); - - if (listen_bits) - cr_sema_signal(&socket->listen_sema); - if (recv_bits) - cr_sema_signal(&socket->read_sema); - if (send_bits) - _w5500_sockintr_ch_send(&socket->write_ch, send_bits); - break; + while (!gpio_get(chip->pin_intr)) { + if (w5500ll_read_common_reg(chip->spidev, chip_interrupt)) + w5500ll_write_common_reg(chip->spidev, chip_interrupt, 0xFF); + + uint8_t sockmask = w5500ll_read_common_reg(chip->spidev, sock_interrupt); + for (uint8_t socknum = 0; socknum < 8; socknum++) { + if (!(sockmask & (1<<socknum))) + continue; + struct _w5500_socket *socket = &chip->sockets[socknum]; + + uint8_t sockintr = w5500ll_read_sock_reg(chip->spidev, socknum, interrupt); + + switch (socket->mode) { + case W5500_MODE_NONE: + break; + case W5500_MODE_TCP: case W5500_MODE_UDP: + uint8_t listen_bits = sockintr & SOCKINTR_CONN, + send_bits = sockintr & (SOCKINTR_SEND_OK|SOCKINTR_SEND_TIMEOUT), + recv_bits = sockintr & (SOCKINTR_RECV_DAT|SOCKINTR_RECV_FIN); + + if (listen_bits) + cr_sema_signal(&socket->listen_sema); + if (recv_bits) + cr_sema_signal(&socket->read_sema); + if (send_bits) + _w5500_sockintr_ch_send(&socket->write_ch, send_bits); + break; + } + + w5500ll_write_sock_reg(chip->spidev, socknum, interrupt, sockintr); } - - w5500ll_write_sock_reg(chip->spidev, socknum, interrupt, sockintr); } + cr_sema_wait(&chip->intr); } cr_end(); |