Merge pull request #10412 from maribu/w5100
drivers/w5100: Fixed netdev_driver_t::recv() API
This commit is contained in:
commit
82e293a496
@ -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)
|
|||||||
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)
|
|||||||
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 */
|
/* if frame received OR drop requested, remove frame from RX buffer */
|
||||||
waddr(dev, S0_RX_RD0, S0_RX_RD1, rp += psize);
|
if (max_len > 0) {
|
||||||
wreg(dev, S0_CR, CR_RECV);
|
drop(dev, num, rp, psize);
|
||||||
|
|
||||||
/* if RX buffer now empty, clear RECV interrupt flag */
|
|
||||||
if ((num - psize) == 0) {
|
|
||||||
wreg(dev, S0_IR, IR_RECV);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 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)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user