1
0
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:
Hauke Petersen 2016-11-08 18:44:16 +01:00
parent 5cb10ca9ea
commit ac482fd3e2
3 changed files with 58 additions and 43 deletions

View File

@ -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;

View File

@ -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
},
};
/** @} */

View File

@ -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: