mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2025-01-17 05:12:57 +01:00
drivers/w5100: adapted to SPI API changes
This commit is contained in:
parent
5cb10ca9ea
commit
ac482fd3e2
@ -56,7 +56,7 @@ enum {
|
||||
*/
|
||||
typedef struct {
|
||||
spi_t spi; /**< SPI bus used */
|
||||
spi_speed_t spi_speed; /**< clock speed used on the selected SPI bus */
|
||||
spi_clk_t clk; /**< clock speed used on the selected SPI bus */
|
||||
gpio_t cs; /**< pin connected to the chip select line */
|
||||
gpio_t evt; /**< pin connected to the INT line */
|
||||
} w5100_params_t;
|
||||
|
@ -28,10 +28,10 @@ extern "C" {
|
||||
* @{
|
||||
*/
|
||||
#ifndef W5100_PARAM_SPI
|
||||
#define W5100_PARAM_SPI (SPI_0)
|
||||
#define W5100_PARAM_SPI (SPI_DEV(0))
|
||||
#endif
|
||||
#ifndef W5100_PARAM_SPI_SPEED
|
||||
#define W5100_PARAM_SPI_SPEED (SPI_SPEED_5MHZ)
|
||||
#ifndef W5100_PARAM_SPI_CLK
|
||||
#define W5100_PARAM_SPI_CLK (SPI_CLK_5MHZ)
|
||||
#endif
|
||||
#ifndef W5100_PARAM_CS
|
||||
#define W5100_PARAM_CS (GPIO_PIN(0, 0))
|
||||
@ -46,10 +46,10 @@ extern "C" {
|
||||
*/
|
||||
static const w5100_params_t w5100_params[] = {
|
||||
{
|
||||
.spi = W5100_PARAM_SPI,
|
||||
.spi_speed = W5100_PARAM_SPI_SPEED,
|
||||
.cs = W5100_PARAM_CS,
|
||||
.evt = W5100_PARAM_EVT
|
||||
.spi = W5100_PARAM_SPI,
|
||||
.clk = W5100_PARAM_SPI_CLK,
|
||||
.cs = W5100_PARAM_CS,
|
||||
.evt = W5100_PARAM_EVT
|
||||
},
|
||||
};
|
||||
/** @} */
|
||||
|
@ -35,7 +35,7 @@
|
||||
#include "debug.h"
|
||||
|
||||
|
||||
#define SPI_CONF SPI_CONF_FIRST_RISING
|
||||
#define SPI_CONF SPI_MODE_0
|
||||
#define RMSR_DEFAULT_VALUE (0x55)
|
||||
|
||||
#define S0_MEMSIZE (0x2000)
|
||||
@ -48,25 +48,26 @@ static const netdev2_driver_t netdev2_driver_w5100;
|
||||
static inline void send_addr(w5100_t *dev, uint16_t addr)
|
||||
{
|
||||
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||
spi_transfer_byte(dev->p.spi, (addr >> 8), NULL);
|
||||
spi_transfer_byte(dev->p.spi, (addr & 0xff), NULL);
|
||||
spi_transfer_byte(dev->p.spi, dev->p.cs, true, (addr >> 8));
|
||||
spi_transfer_byte(dev->p.spi, dev->p.cs, true, (addr & 0xff));
|
||||
#else
|
||||
spi_transfer_byte(dev->p.spi, (addr & 0xff), NULL);
|
||||
spi_transfer_byte(dev->p.spi, (addr >> 8), NULL);
|
||||
spi_transfer_byte(dev->p.spi, dev->p.cs, true, (addr & 0xff));
|
||||
spi_transfer_byte(dev->p.spi, dev->p.cs, true, (addr >> 8));
|
||||
#endif
|
||||
}
|
||||
|
||||
static uint8_t rreg(w5100_t *dev, uint16_t reg)
|
||||
{
|
||||
uint8_t data;
|
||||
|
||||
gpio_clear(dev->p.cs);
|
||||
spi_transfer_byte(dev->p.spi, CMD_READ, NULL);
|
||||
spi_transfer_byte(dev->p.spi, dev->p.cs, true, CMD_READ);
|
||||
send_addr(dev, reg++);
|
||||
spi_transfer_byte(dev->p.spi, 0, (char *)&data);
|
||||
gpio_set(dev->p.cs);
|
||||
return spi_transfer_byte(dev->p.spi, dev->p.cs, false, 0);
|
||||
}
|
||||
|
||||
return data;
|
||||
static void wreg(w5100_t *dev, uint16_t reg, uint8_t data)
|
||||
{
|
||||
spi_transfer_byte(dev->p.spi, dev->p.cs, true, CMD_WRITE);
|
||||
send_addr(dev, reg);
|
||||
spi_transfer_byte(dev->p.spi, dev->p.cs, false, data);
|
||||
}
|
||||
|
||||
static uint16_t raddr(w5100_t *dev, uint16_t addr_high, uint16_t addr_low)
|
||||
@ -76,6 +77,13 @@ static uint16_t raddr(w5100_t *dev, uint16_t addr_high, uint16_t addr_low)
|
||||
return res;
|
||||
}
|
||||
|
||||
static void waddr(w5100_t *dev,
|
||||
uint16_t addr_high, uint16_t addr_low, uint16_t val)
|
||||
{
|
||||
wreg(dev, addr_high, (uint8_t)(val >> 8));
|
||||
wreg(dev, addr_low, (uint8_t)(val & 0xff));
|
||||
}
|
||||
|
||||
static void rchunk(w5100_t *dev, uint16_t addr, uint8_t *data, size_t len)
|
||||
{
|
||||
/* reading a chunk must be split in multiple single byte reads, as the
|
||||
@ -85,22 +93,6 @@ static void rchunk(w5100_t *dev, uint16_t addr, uint8_t *data, size_t len)
|
||||
}
|
||||
}
|
||||
|
||||
static void wreg(w5100_t *dev, uint16_t reg, uint8_t data)
|
||||
{
|
||||
gpio_clear(dev->p.cs);
|
||||
spi_transfer_byte(dev->p.spi, CMD_WRITE, NULL);
|
||||
send_addr(dev, reg);
|
||||
spi_transfer_byte(dev->p.spi, data, NULL);
|
||||
gpio_set(dev->p.cs);
|
||||
}
|
||||
|
||||
static void waddr(w5100_t *dev,
|
||||
uint16_t addr_high, uint16_t addr_low, uint16_t val)
|
||||
{
|
||||
wreg(dev, addr_high, (uint8_t)(val >> 8));
|
||||
wreg(dev, addr_low, (uint8_t)(val & 0xff));
|
||||
}
|
||||
|
||||
static void wchunk(w5100_t *dev, uint16_t addr, uint8_t *data, size_t len)
|
||||
{
|
||||
/* writing a chunk must be split in multiple single byte writes, as the
|
||||
@ -129,11 +121,8 @@ void w5100_setup(w5100_t *dev, const w5100_params_t *params)
|
||||
/* initialize the device descriptor */
|
||||
memcpy(&dev->p, params, sizeof(w5100_params_t));
|
||||
|
||||
/* initialize pins and SPI */
|
||||
gpio_init(dev->p.cs, GPIO_OUT);
|
||||
gpio_set(dev->p.cs);
|
||||
spi_init_master(dev->p.spi, SPI_CONF, dev->p.spi_speed);
|
||||
|
||||
/* initialize the chip select pin and the external interrupt pin */
|
||||
spi_init_cs(dev->p.spi, dev->p.cs);
|
||||
gpio_init_int(dev->p.evt, GPIO_IN, GPIO_FALLING, extint, dev);
|
||||
}
|
||||
|
||||
@ -143,9 +132,13 @@ static int init(netdev2_t *netdev)
|
||||
uint8_t tmp;
|
||||
uint8_t hwaddr[ETHERNET_ADDR_LEN];
|
||||
|
||||
/* 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);
|
||||
|
||||
/* test the SPI connection by reading the value of the RMSR register */
|
||||
tmp = rreg(dev, REG_TMSR);
|
||||
if (tmp != RMSR_DEFAULT_VALUE) {
|
||||
spi_release(dev->p.spi);
|
||||
LOG_ERROR("[w5100] error: no SPI connection\n");
|
||||
return W5100_ERR_BUS;
|
||||
}
|
||||
@ -180,6 +173,9 @@ static int init(netdev2_t *netdev)
|
||||
/* start receiving packets */
|
||||
wreg(dev, S0_CR, CR_RECV);
|
||||
|
||||
/* release the SPI bus again */
|
||||
spi_release(dev->p.spi);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -203,6 +199,9 @@ static int send(netdev2_t *netdev, const struct iovec *vector, unsigned count)
|
||||
w5100_t *dev = (w5100_t *)netdev;
|
||||
int sum = 0;
|
||||
|
||||
/* 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);
|
||||
|
||||
uint16_t pos = raddr(dev, S0_TX_WR0, S0_TX_WR1);
|
||||
|
||||
/* the register is only set correctly after the first send pkt, so we need
|
||||
@ -211,7 +210,7 @@ static int send(netdev2_t *netdev, const struct iovec *vector, unsigned count)
|
||||
pos = S0_TX_BASE;
|
||||
}
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
for (unsigned i = 0; i < count; i++) {
|
||||
pos = tx_upload(dev, pos, vector[i].iov_base, vector[i].iov_len);
|
||||
sum += vector[i].iov_len;
|
||||
}
|
||||
@ -225,15 +224,22 @@ static int send(netdev2_t *netdev, const struct iovec *vector, unsigned count)
|
||||
|
||||
DEBUG("[w5100] send: transferred %i byte (at 0x%04x)\n", sum, (int)pos);
|
||||
|
||||
/* release the SPI bus again */
|
||||
spi_release(dev->p.spi);
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
static int recv(netdev2_t *netdev, void *buf, size_t len, void *info)
|
||||
{
|
||||
(void)info;
|
||||
w5100_t *dev = (w5100_t *)netdev;
|
||||
uint8_t *in_buf = (uint8_t *)buf;
|
||||
int n = 0;
|
||||
|
||||
/* 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);
|
||||
|
||||
uint16_t num = raddr(dev, S0_RX_RSR0, S0_RX_RSR1);
|
||||
|
||||
if (num > 0) {
|
||||
@ -267,16 +273,23 @@ static int recv(netdev2_t *netdev, void *buf, size_t len, void *info)
|
||||
}
|
||||
}
|
||||
|
||||
/* release the SPI bus again */
|
||||
spi_release(dev->p.spi);
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
static void isr(netdev2_t *netdev)
|
||||
{
|
||||
uint8_t ir;
|
||||
w5100_t *dev = (w5100_t *)netdev;
|
||||
|
||||
/* we only react on RX events, and if we see one, we read from the RX buffer
|
||||
* until it is empty */
|
||||
while (rreg(dev, S0_IR) & IR_RECV) {
|
||||
spi_acquire(dev->p.spi, dev->p.cs, SPI_CONF, dev->p.clk);
|
||||
ir = rreg(dev, S0_IR);
|
||||
spi_release(dev->p.spi);
|
||||
while (ir & IR_RECV) {
|
||||
DEBUG("[w5100] netdev2 RX complete\n");
|
||||
netdev->event_callback(netdev, NETDEV2_EVENT_RX_COMPLETE);
|
||||
}
|
||||
@ -290,7 +303,9 @@ static int get(netdev2_t *netdev, netopt_t opt, void *value, size_t max_len)
|
||||
switch (opt) {
|
||||
case NETOPT_ADDRESS:
|
||||
assert(max_len >= ETHERNET_ADDR_LEN);
|
||||
spi_acquire(dev->p.spi, dev->p.cs, SPI_CONF, dev->p.clk);
|
||||
rchunk(dev, REG_SHAR0, value, ETHERNET_ADDR_LEN);
|
||||
spi_release(dev->p.spi);
|
||||
res = ETHERNET_ADDR_LEN;
|
||||
break;
|
||||
default:
|
||||
|
Loading…
Reference in New Issue
Block a user