Skip to content
Snippets Groups Projects
Unverified Commit 82e293a4 authored by Martine Lenders's avatar Martine Lenders Committed by GitHub
Browse files

Merge pull request #10412 from maribu/w5100

drivers/w5100: Fixed netdev_driver_t::recv() API
parents 5a35e6e1 a81d3949
Branches
No related tags found
No related merge requests found
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
* @} * @}
*/ */
#include <errno.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
...@@ -230,12 +231,24 @@ static int send(netdev_t *netdev, const iolist_t *iolist) ...@@ -230,12 +231,24 @@ static int send(netdev_t *netdev, const iolist_t *iolist)
return sum; return sum;
} }
static int recv(netdev_t *netdev, void *buf, size_t len, void *info) static inline void drop(w5100_t *dev, uint16_t num, uint16_t rp, uint16_t psize)
{
/* set the new read pointer address */
waddr(dev, S0_RX_RD0, S0_RX_RD1, rp + psize);
wreg(dev, S0_CR, CR_RECV);
/* if RX buffer now empty, clear RECV interrupt flag */
if ((num - psize) == 0) {
wreg(dev, S0_IR, IR_RECV);
}
}
static int recv(netdev_t *netdev, void *buf, size_t max_len, void *info)
{ {
(void)info; (void)info;
w5100_t *dev = (w5100_t *)netdev; w5100_t *dev = (w5100_t *)netdev;
uint8_t *in_buf = (uint8_t *)buf; uint8_t *in_buf = (uint8_t *)buf;
unsigned n = 0; unsigned len = 0;
/* get access to the SPI bus for the duration of this function */ /* get access to the SPI bus for the duration of this function */
spi_acquire(dev->p.spi, dev->p.cs, SPI_CONF, dev->p.clk); spi_acquire(dev->p.spi, dev->p.cs, SPI_CONF, dev->p.clk);
...@@ -247,36 +260,38 @@ static int recv(netdev_t *netdev, void *buf, size_t len, void *info) ...@@ -247,36 +260,38 @@ static int recv(netdev_t *netdev, void *buf, size_t len, void *info)
uint16_t rp = raddr(dev, S0_RX_RD0, S0_RX_RD1); uint16_t rp = raddr(dev, S0_RX_RD0, S0_RX_RD1);
uint16_t psize = raddr(dev, (S0_RX_BASE + (rp & S0_MASK)), uint16_t psize = raddr(dev, (S0_RX_BASE + (rp & S0_MASK)),
(S0_RX_BASE + ((rp + 1) & S0_MASK))); (S0_RX_BASE + ((rp + 1) & S0_MASK)));
n = psize - 2; len = psize - 2;
DEBUG("[w5100] recv: got packet of %i byte (at 0x%04x)\n", n, (int)rp); DEBUG("[w5100] recv: got packet of %i byte (at 0x%04x)\n", len, (int)rp);
/* read the actual data into the given buffer if wanted */ /* read the actual data into the given buffer if wanted */
if (in_buf != NULL) { if (in_buf != NULL) {
/* Is provided buffer big enough? */
if (len > max_len) {
drop(dev, num, rp, psize);
spi_release(dev->p.spi);
return -ENOBUFS;
}
uint16_t pos = rp + 2; uint16_t pos = rp + 2;
len = (n <= len) ? n : len;
for (unsigned i = 0; i < len; i++) { for (unsigned i = 0; i < len; i++) {
in_buf[i] = rreg(dev, (S0_RX_BASE + ((pos++) & S0_MASK))); in_buf[i] = rreg(dev, (S0_RX_BASE + ((pos++) & S0_MASK)));
} }
DEBUG("[w5100] recv: read %i byte from device (at 0x%04x)\n", DEBUG("[w5100] recv: read %i byte from device (at 0x%04x)\n",
n, (int)rp); len, (int)rp);
}
/* set the new read pointer address */
waddr(dev, S0_RX_RD0, S0_RX_RD1, rp += psize);
wreg(dev, S0_CR, CR_RECV);
/* if RX buffer now empty, clear RECV interrupt flag */ /* if frame received OR drop requested, remove frame from RX buffer */
if ((num - psize) == 0) { if (max_len > 0) {
wreg(dev, S0_IR, IR_RECV); drop(dev, num, rp, psize);
}
} }
} }
/* release the SPI bus again */ /* release the SPI bus again */
spi_release(dev->p.spi); spi_release(dev->p.spi);
return (int)n; return (int)len;
} }
static void isr(netdev_t *netdev) static void isr(netdev_t *netdev)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment