drivers/ethernet: Switch enc28j60 to new SPI API
Let's use the new SPI API and ditch the old one. Signed-off-by: Matthias Boesl <matthias.boesl@gmail.com> Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
This commit is contained in:
parent
659f0f2d20
commit
2a14d289e5
3 changed files with 188 additions and 51 deletions
|
@ -10,7 +10,6 @@ menuconfig ETH_ENC28J60
|
||||||
bool "ENC28J60C Ethernet Controller"
|
bool "ENC28J60C Ethernet Controller"
|
||||||
depends on NET_L2_ETHERNET
|
depends on NET_L2_ETHERNET
|
||||||
depends on SPI
|
depends on SPI
|
||||||
select SPI_LEGACY_API
|
|
||||||
default n
|
default n
|
||||||
help
|
help
|
||||||
ENC28J60C Stand-Alone Ethernet Controller
|
ENC28J60C Stand-Alone Ethernet Controller
|
||||||
|
@ -84,11 +83,32 @@ config ETH_ENC28J60_0_SLAVE
|
||||||
help
|
help
|
||||||
ENC28J60C chip select pin.
|
ENC28J60C chip select pin.
|
||||||
|
|
||||||
|
config ETH_ENC28J60_0_GPIO_SPI_CS
|
||||||
|
bool "Manage SPI CS throug a GPIO pin"
|
||||||
|
default n
|
||||||
|
help
|
||||||
|
This option is useful if one needs to manage SPI CS through a GPIO
|
||||||
|
pin to by-pass the SPI controller's CS logic.
|
||||||
|
|
||||||
|
config ETH_ENC28J60_0_SPI_CS_PORT_NAME
|
||||||
|
string "SPI cs port name"
|
||||||
|
default ""
|
||||||
|
depends on ETH_ENC28J60_0_GPIO_SPI_CS
|
||||||
|
help
|
||||||
|
Master SPI port name through which ENC28J60C chip is accessed.
|
||||||
|
|
||||||
|
config ETH_ENC28J60_0_SPI_CS_PIN
|
||||||
|
int "SPI CS pin"
|
||||||
|
default 0
|
||||||
|
depends on ETH_ENC28J60_0_GPIO_SPI_CS
|
||||||
|
help
|
||||||
|
CS pin used for the SPI device
|
||||||
|
|
||||||
config ETH_ENC28J60_0_SPI_BUS_FREQ
|
config ETH_ENC28J60_0_SPI_BUS_FREQ
|
||||||
int "ENC28J60C SPI bus speed in Hz"
|
int "ENC28J60C SPI bus speed in Hz"
|
||||||
default 128
|
default 128000
|
||||||
help
|
help
|
||||||
This is the maximum supported SPI bus frequency.
|
This is the SPI bus frequency for accessing the device.
|
||||||
|
|
||||||
config ETH_ENC28J60_0_MAC3
|
config ETH_ENC28J60_0_MAC3
|
||||||
hex "MAC Address Byte 3"
|
hex "MAC Address Byte 3"
|
||||||
|
|
|
@ -29,25 +29,55 @@ static int eth_enc28j60_soft_reset(struct device *dev)
|
||||||
{
|
{
|
||||||
struct eth_enc28j60_runtime *context = dev->driver_data;
|
struct eth_enc28j60_runtime *context = dev->driver_data;
|
||||||
u8_t tx_buf[2] = {ENC28J60_SPI_SC, 0xFF};
|
u8_t tx_buf[2] = {ENC28J60_SPI_SC, 0xFF};
|
||||||
|
const struct spi_buf tx_bufs[] = {
|
||||||
|
{
|
||||||
|
.buf = tx_buf,
|
||||||
|
.len = 1,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const struct spi_buf_set tx = {
|
||||||
|
.buffers = tx_bufs,
|
||||||
|
.count = ARRAY_SIZE(tx_bufs)
|
||||||
|
};
|
||||||
|
|
||||||
return spi_write(context->spi, tx_buf, 2);
|
return spi_write(context->spi, &context->spi_cfg, &tx);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void eth_enc28j60_set_bank(struct device *dev, u16_t reg_addr)
|
static void eth_enc28j60_set_bank(struct device *dev, u16_t reg_addr)
|
||||||
{
|
{
|
||||||
struct eth_enc28j60_runtime *context = dev->driver_data;
|
struct eth_enc28j60_runtime *context = dev->driver_data;
|
||||||
|
struct spi_buf tx_bufs[1];
|
||||||
|
struct spi_buf rx_bufs[1];
|
||||||
|
const struct spi_buf_set tx = {
|
||||||
|
.buffers = tx_bufs,
|
||||||
|
.count = ARRAY_SIZE(tx_bufs)
|
||||||
|
};
|
||||||
|
const struct spi_buf_set rx = {
|
||||||
|
.buffers = rx_bufs,
|
||||||
|
.count = ARRAY_SIZE(rx_bufs)
|
||||||
|
};
|
||||||
u8_t tx_buf[2];
|
u8_t tx_buf[2];
|
||||||
|
u8_t rx_buf[2];
|
||||||
|
int ret;
|
||||||
|
|
||||||
k_sem_take(&context->spi_sem, K_FOREVER);
|
k_sem_take(&context->spi_sem, K_FOREVER);
|
||||||
|
|
||||||
tx_buf[0] = ENC28J60_SPI_RCR | ENC28J60_REG_ECON1;
|
tx_buf[0] = ENC28J60_SPI_RCR | ENC28J60_REG_ECON1;
|
||||||
tx_buf[1] = 0x0;
|
tx_buf[1] = 0x0;
|
||||||
|
|
||||||
if (!spi_transceive(context->spi, tx_buf, 2, tx_buf, 2)) {
|
tx_bufs[0].buf = tx_buf;
|
||||||
tx_buf[0] = ENC28J60_SPI_WCR | ENC28J60_REG_ECON1;
|
tx_bufs[0].len = 2;
|
||||||
tx_buf[1] = (tx_buf[1] & 0xFC) | ((reg_addr >> 8) & 0x0F);
|
rx_bufs[0].buf = rx_buf;
|
||||||
|
rx_bufs[0].len = 2;
|
||||||
|
|
||||||
spi_write(context->spi, tx_buf, 2);
|
ret = spi_transceive(context->spi, &context->spi_cfg, &tx, &rx);
|
||||||
|
if (!ret) {
|
||||||
|
tx_buf[0] = ENC28J60_SPI_WCR | ENC28J60_REG_ECON1;
|
||||||
|
tx_buf[1] = (rx_buf[1] & 0xFC) | ((reg_addr >> 8) & 0x0F);
|
||||||
|
|
||||||
|
tx_bufs[0].buf = tx_buf;
|
||||||
|
tx_bufs[0].len = 2;
|
||||||
|
spi_write(context->spi, &context->spi_cfg, &tx);
|
||||||
} else {
|
} else {
|
||||||
SYS_LOG_DBG("Failure while setting bank to %d", reg_addr);
|
SYS_LOG_DBG("Failure while setting bank to %d", reg_addr);
|
||||||
}
|
}
|
||||||
|
@ -60,14 +90,23 @@ static void eth_enc28j60_write_reg(struct device *dev, u16_t reg_addr,
|
||||||
{
|
{
|
||||||
struct eth_enc28j60_runtime *context = dev->driver_data;
|
struct eth_enc28j60_runtime *context = dev->driver_data;
|
||||||
u8_t tx_buf[2];
|
u8_t tx_buf[2];
|
||||||
|
const struct spi_buf tx_bufs[] = {
|
||||||
|
{
|
||||||
|
.buf = tx_buf,
|
||||||
|
.len = 2
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const struct spi_buf_set tx = {
|
||||||
|
.buffers = tx_bufs,
|
||||||
|
.count = ARRAY_SIZE(tx_bufs)
|
||||||
|
};
|
||||||
|
|
||||||
k_sem_take(&context->spi_sem, K_FOREVER);
|
k_sem_take(&context->spi_sem, K_FOREVER);
|
||||||
|
|
||||||
tx_buf[0] = ENC28J60_SPI_WCR | (reg_addr & 0xFF);
|
tx_buf[0] = ENC28J60_SPI_WCR | (reg_addr & 0xFF);
|
||||||
tx_buf[1] = value;
|
tx_buf[1] = value;
|
||||||
|
|
||||||
spi_write(context->spi, tx_buf, 2);
|
spi_write(context->spi, &context->spi_cfg, &tx);
|
||||||
|
|
||||||
k_sem_give(&context->spi_sem);
|
k_sem_give(&context->spi_sem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,20 +114,44 @@ static void eth_enc28j60_read_reg(struct device *dev, u16_t reg_addr,
|
||||||
u8_t *value)
|
u8_t *value)
|
||||||
{
|
{
|
||||||
struct eth_enc28j60_runtime *context = dev->driver_data;
|
struct eth_enc28j60_runtime *context = dev->driver_data;
|
||||||
u8_t tx_size = 2;
|
u8_t tx_buf[2];
|
||||||
u8_t tx_buf[3];
|
const struct spi_buf tx_bufs[1] = {
|
||||||
|
{
|
||||||
|
.buf = tx_buf,
|
||||||
|
.len = 2
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const struct spi_buf_set tx = {
|
||||||
|
.buffers = tx_bufs,
|
||||||
|
.count = ARRAY_SIZE(tx_bufs)
|
||||||
|
};
|
||||||
|
u8_t rx_buf[3];
|
||||||
|
struct spi_buf rx_bufs[1] = {
|
||||||
|
{
|
||||||
|
.buf = rx_buf,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const struct spi_buf_set rx = {
|
||||||
|
.buffers = rx_bufs,
|
||||||
|
.count = ARRAY_SIZE(rx_bufs)
|
||||||
|
};
|
||||||
|
u8_t rx_size = 2;
|
||||||
|
int ret;
|
||||||
|
|
||||||
k_sem_take(&context->spi_sem, K_FOREVER);
|
k_sem_take(&context->spi_sem, K_FOREVER);
|
||||||
|
|
||||||
if (reg_addr & 0xF000) {
|
if (reg_addr & 0xF000) {
|
||||||
tx_size = 3;
|
rx_size = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
tx_buf[0] = ENC28J60_SPI_RCR | (reg_addr & 0xFF);
|
tx_buf[0] = ENC28J60_SPI_RCR | (reg_addr & 0xFF);
|
||||||
tx_buf[1] = 0x0;
|
tx_buf[1] = 0x0;
|
||||||
|
|
||||||
if (!spi_transceive(context->spi, tx_buf, tx_size, tx_buf, tx_size)) {
|
rx_bufs[0].len = rx_size;
|
||||||
*value = tx_buf[tx_size - 1];
|
|
||||||
|
ret = spi_transceive(context->spi, &context->spi_cfg, &tx, &rx);
|
||||||
|
if (!ret) {
|
||||||
|
*value = rx_buf[rx_size - 1];
|
||||||
} else {
|
} else {
|
||||||
SYS_LOG_DBG("Failure while reading register %d", reg_addr);
|
SYS_LOG_DBG("Failure while reading register %d", reg_addr);
|
||||||
*value = 0;
|
*value = 0;
|
||||||
|
@ -102,13 +165,23 @@ static void eth_enc28j60_set_eth_reg(struct device *dev, u16_t reg_addr,
|
||||||
{
|
{
|
||||||
struct eth_enc28j60_runtime *context = dev->driver_data;
|
struct eth_enc28j60_runtime *context = dev->driver_data;
|
||||||
u8_t tx_buf[2];
|
u8_t tx_buf[2];
|
||||||
|
const struct spi_buf tx_bufs[1] = {
|
||||||
|
{
|
||||||
|
.buf = tx_buf,
|
||||||
|
.len = 2
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const struct spi_buf_set tx = {
|
||||||
|
.buffers = tx_bufs,
|
||||||
|
.count = ARRAY_SIZE(tx_bufs)
|
||||||
|
};
|
||||||
|
|
||||||
k_sem_take(&context->spi_sem, K_FOREVER);
|
k_sem_take(&context->spi_sem, K_FOREVER);
|
||||||
|
|
||||||
tx_buf[0] = ENC28J60_SPI_BFS | (reg_addr & 0xFF);
|
tx_buf[0] = ENC28J60_SPI_BFS | (reg_addr & 0xFF);
|
||||||
tx_buf[1] = value;
|
tx_buf[1] = value;
|
||||||
|
|
||||||
spi_write(context->spi, tx_buf, 2);
|
spi_write(context->spi, &context->spi_cfg, &tx);
|
||||||
|
|
||||||
k_sem_give(&context->spi_sem);
|
k_sem_give(&context->spi_sem);
|
||||||
}
|
}
|
||||||
|
@ -119,13 +192,23 @@ static void eth_enc28j60_clear_eth_reg(struct device *dev, u16_t reg_addr,
|
||||||
{
|
{
|
||||||
struct eth_enc28j60_runtime *context = dev->driver_data;
|
struct eth_enc28j60_runtime *context = dev->driver_data;
|
||||||
u8_t tx_buf[2];
|
u8_t tx_buf[2];
|
||||||
|
const struct spi_buf tx_bufs[1] = {
|
||||||
|
{
|
||||||
|
.buf = tx_buf,
|
||||||
|
.len = ARRAY_SIZE(tx_bufs)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const struct spi_buf_set tx = {
|
||||||
|
.buffers = tx_bufs,
|
||||||
|
.count = ARRAY_SIZE(tx_bufs)
|
||||||
|
};
|
||||||
|
|
||||||
k_sem_take(&context->spi_sem, K_FOREVER);
|
k_sem_take(&context->spi_sem, K_FOREVER);
|
||||||
|
|
||||||
tx_buf[0] = ENC28J60_SPI_BFC | (reg_addr & 0xFF);
|
tx_buf[0] = ENC28J60_SPI_BFC | (reg_addr & 0xFF);
|
||||||
tx_buf[1] = value;
|
tx_buf[1] = value;
|
||||||
|
|
||||||
spi_write(context->spi, tx_buf, 2);
|
spi_write(context->spi, &context->spi_cfg, &tx);
|
||||||
|
|
||||||
k_sem_give(&context->spi_sem);
|
k_sem_give(&context->spi_sem);
|
||||||
}
|
}
|
||||||
|
@ -134,6 +217,11 @@ static void eth_enc28j60_write_mem(struct device *dev, u8_t *data_buffer,
|
||||||
u16_t buf_len)
|
u16_t buf_len)
|
||||||
{
|
{
|
||||||
struct eth_enc28j60_runtime *context = dev->driver_data;
|
struct eth_enc28j60_runtime *context = dev->driver_data;
|
||||||
|
struct spi_buf tx_bufs[1];
|
||||||
|
const struct spi_buf_set tx = {
|
||||||
|
.buffers = tx_bufs,
|
||||||
|
.count = ARRAY_SIZE(tx_bufs)
|
||||||
|
};
|
||||||
u8_t *index_buf;
|
u8_t *index_buf;
|
||||||
u16_t num_segments;
|
u16_t num_segments;
|
||||||
u16_t num_remaining;
|
u16_t num_remaining;
|
||||||
|
@ -148,14 +236,19 @@ static void eth_enc28j60_write_mem(struct device *dev, u8_t *data_buffer,
|
||||||
++i, index_buf += MAX_BUFFER_LENGTH) {
|
++i, index_buf += MAX_BUFFER_LENGTH) {
|
||||||
context->mem_buf[0] = ENC28J60_SPI_WBM;
|
context->mem_buf[0] = ENC28J60_SPI_WBM;
|
||||||
memcpy(context->mem_buf + 1, index_buf, MAX_BUFFER_LENGTH);
|
memcpy(context->mem_buf + 1, index_buf, MAX_BUFFER_LENGTH);
|
||||||
spi_write(context->spi,
|
tx_bufs[0].buf = context->mem_buf;
|
||||||
context->mem_buf, MAX_BUFFER_LENGTH + 1);
|
tx_bufs[0].len = MAX_BUFFER_LENGTH + 1;
|
||||||
|
|
||||||
|
spi_write(context->spi, &context->spi_cfg, &tx);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (num_remaining > 0) {
|
if (num_remaining > 0) {
|
||||||
context->mem_buf[0] = ENC28J60_SPI_WBM;
|
context->mem_buf[0] = ENC28J60_SPI_WBM;
|
||||||
memcpy(context->mem_buf + 1, index_buf, num_remaining);
|
memcpy(context->mem_buf + 1, index_buf, num_remaining);
|
||||||
spi_write(context->spi, context->mem_buf, num_remaining + 1);
|
tx_bufs[0].buf = context->mem_buf;
|
||||||
|
tx_bufs[0].len = num_remaining + 1;
|
||||||
|
|
||||||
|
spi_write(context->spi, &context->spi_cfg, &tx);
|
||||||
}
|
}
|
||||||
|
|
||||||
k_sem_give(&context->spi_sem);
|
k_sem_give(&context->spi_sem);
|
||||||
|
@ -165,8 +258,14 @@ static void eth_enc28j60_read_mem(struct device *dev, u8_t *data_buffer,
|
||||||
u16_t buf_len)
|
u16_t buf_len)
|
||||||
{
|
{
|
||||||
struct eth_enc28j60_runtime *context = dev->driver_data;
|
struct eth_enc28j60_runtime *context = dev->driver_data;
|
||||||
|
struct spi_buf tx_bufs[1];
|
||||||
|
const struct spi_buf_set tx = {
|
||||||
|
.buffers = tx_bufs,
|
||||||
|
.count = ARRAY_SIZE(tx_bufs)
|
||||||
|
};
|
||||||
u16_t num_segments;
|
u16_t num_segments;
|
||||||
u16_t num_remaining;
|
u16_t num_remaining;
|
||||||
|
int ret;
|
||||||
|
|
||||||
num_segments = buf_len / MAX_BUFFER_LENGTH;
|
num_segments = buf_len / MAX_BUFFER_LENGTH;
|
||||||
num_remaining = buf_len - MAX_BUFFER_LENGTH * num_segments;
|
num_remaining = buf_len - MAX_BUFFER_LENGTH * num_segments;
|
||||||
|
@ -177,9 +276,11 @@ static void eth_enc28j60_read_mem(struct device *dev, u8_t *data_buffer,
|
||||||
++i, data_buffer += MAX_BUFFER_LENGTH) {
|
++i, data_buffer += MAX_BUFFER_LENGTH) {
|
||||||
context->mem_buf[0] = ENC28J60_SPI_RBM;
|
context->mem_buf[0] = ENC28J60_SPI_RBM;
|
||||||
|
|
||||||
if (!spi_transceive(context->spi,
|
tx_bufs[0].buf = context->mem_buf;
|
||||||
context->mem_buf, MAX_BUFFER_LENGTH + 1,
|
tx_bufs[0].len = MAX_BUFFER_LENGTH + 1;
|
||||||
context->mem_buf, MAX_BUFFER_LENGTH + 1)) {
|
|
||||||
|
ret = spi_transceive(context->spi, &context->spi_cfg, &tx, &tx);
|
||||||
|
if (!ret) {
|
||||||
if (data_buffer) {
|
if (data_buffer) {
|
||||||
memcpy(data_buffer, context->mem_buf + 1,
|
memcpy(data_buffer, context->mem_buf + 1,
|
||||||
MAX_BUFFER_LENGTH);
|
MAX_BUFFER_LENGTH);
|
||||||
|
@ -192,9 +293,11 @@ static void eth_enc28j60_read_mem(struct device *dev, u8_t *data_buffer,
|
||||||
if (num_remaining > 0) {
|
if (num_remaining > 0) {
|
||||||
context->mem_buf[0] = ENC28J60_SPI_RBM;
|
context->mem_buf[0] = ENC28J60_SPI_RBM;
|
||||||
|
|
||||||
if (!spi_transceive(context->spi,
|
tx_bufs[0].buf = context->mem_buf;
|
||||||
context->mem_buf, num_remaining + 1,
|
tx_bufs[0].len = num_remaining + 1;
|
||||||
context->mem_buf, num_remaining + 1)) {
|
|
||||||
|
ret = spi_transceive(context->spi, &context->spi_cfg, &tx, &tx);
|
||||||
|
if (!ret) {
|
||||||
if (data_buffer) {
|
if (data_buffer) {
|
||||||
memcpy(data_buffer, context->mem_buf + 1,
|
memcpy(data_buffer, context->mem_buf + 1,
|
||||||
num_remaining);
|
num_remaining);
|
||||||
|
@ -348,23 +451,40 @@ static int eth_enc28j60_init(struct device *dev)
|
||||||
{
|
{
|
||||||
const struct eth_enc28j60_config *config = dev->config->config_info;
|
const struct eth_enc28j60_config *config = dev->config->config_info;
|
||||||
struct eth_enc28j60_runtime *context = dev->driver_data;
|
struct eth_enc28j60_runtime *context = dev->driver_data;
|
||||||
struct spi_config spi_cfg;
|
|
||||||
|
|
||||||
k_sem_init(&context->spi_sem, 1, UINT_MAX);
|
k_sem_init(&context->spi_sem, 1, UINT_MAX);
|
||||||
|
|
||||||
|
/* SPI config */
|
||||||
|
context->spi_cfg.operation = SPI_WORD_SET(8);
|
||||||
|
context->spi_cfg.frequency = config->spi_freq;
|
||||||
|
context->spi_cfg.slave = config->spi_slave;
|
||||||
|
|
||||||
|
context->spi = device_get_binding((char *)config->spi_port);
|
||||||
|
if (!context->spi) {
|
||||||
|
|
||||||
|
SYS_LOG_ERR("SPI master port %s not found", config->spi_port);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_ETH_ENC28J60_0_GPIO_SPI_CS
|
||||||
|
context->spi_cs.gpio_dev =
|
||||||
|
device_get_binding((char *)config->spi_cs_port);
|
||||||
|
if (!context->spi_cs.gpio_dev) {
|
||||||
|
SYS_LOG_ERR("SPI CS port %s not found", config->spi_cs_port);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
context->spi_cs.gpio_pin = config->spi_cs_pin;
|
||||||
|
context->spi_cfg.cs = &context->spi_cs;
|
||||||
|
#endif /* CONFIG_ETH_ENC28J60_0_GPIO_SPI_CS */
|
||||||
|
|
||||||
|
/* Initialize GPIO */
|
||||||
context->gpio = device_get_binding((char *)config->gpio_port);
|
context->gpio = device_get_binding((char *)config->gpio_port);
|
||||||
if (!context->gpio) {
|
if (!context->gpio) {
|
||||||
SYS_LOG_ERR("GPIO port %s not found", config->gpio_port);
|
SYS_LOG_ERR("GPIO port %s not found", config->gpio_port);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
context->spi = device_get_binding((char *)config->spi_port);
|
|
||||||
if (!context->spi) {
|
|
||||||
SYS_LOG_ERR("SPI master port %s not found", config->spi_port);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Initialize GPIO */
|
|
||||||
if (gpio_pin_configure(context->gpio, config->gpio_pin,
|
if (gpio_pin_configure(context->gpio, config->gpio_pin,
|
||||||
(GPIO_DIR_IN | GPIO_INT | GPIO_INT_EDGE
|
(GPIO_DIR_IN | GPIO_INT | GPIO_INT_EDGE
|
||||||
| GPIO_INT_ACTIVE_LOW | GPIO_INT_DEBOUNCE))) {
|
| GPIO_INT_ACTIVE_LOW | GPIO_INT_DEBOUNCE))) {
|
||||||
|
@ -384,27 +504,12 @@ static int eth_enc28j60_init(struct device *dev)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize SPI:
|
|
||||||
* Mode: 0/0; Size: 8 bits; MSB
|
|
||||||
*/
|
|
||||||
spi_cfg.config = 8 << 4;
|
|
||||||
spi_cfg.max_sys_freq = config->spi_freq;
|
|
||||||
|
|
||||||
if (spi_configure(context->spi, &spi_cfg) < 0) {
|
|
||||||
SYS_LOG_ERR("Failed to configure SPI");
|
|
||||||
return -EIO;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (spi_slave_select(context->spi, config->spi_slave) < 0) {
|
|
||||||
return -EIO;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (eth_enc28j60_soft_reset(dev)) {
|
if (eth_enc28j60_soft_reset(dev)) {
|
||||||
SYS_LOG_ERR("Soft-reset failed");
|
SYS_LOG_ERR("Soft-reset failed");
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Errata B7/2 */
|
/* Errata B7/1 */
|
||||||
k_busy_wait(D10D24S);
|
k_busy_wait(D10D24S);
|
||||||
|
|
||||||
eth_enc28j60_init_buffers(dev);
|
eth_enc28j60_init_buffers(dev);
|
||||||
|
@ -528,6 +633,11 @@ static int eth_enc28j60_rx(struct device *dev)
|
||||||
* does not reliably/accurately report the status of pending packet.
|
* does not reliably/accurately report the status of pending packet.
|
||||||
* Use EPKTCNT register instead.
|
* Use EPKTCNT register instead.
|
||||||
*/
|
*/
|
||||||
|
eth_enc28j60_set_bank(dev, ENC28J60_REG_EPKTCNT);
|
||||||
|
eth_enc28j60_read_reg(dev, ENC28J60_REG_EPKTCNT, &counter);
|
||||||
|
if (!counter) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
SYS_LOG_DBG("");
|
SYS_LOG_DBG("");
|
||||||
|
|
||||||
|
@ -658,7 +768,6 @@ static void enc28j60_thread_main(void *arg1, void *unused1, void *unused2)
|
||||||
while (1) {
|
while (1) {
|
||||||
k_sem_take(&context->int_sem, K_FOREVER);
|
k_sem_take(&context->int_sem, K_FOREVER);
|
||||||
eth_enc28j60_read_reg(dev, ENC28J60_REG_EIR, &int_stat);
|
eth_enc28j60_read_reg(dev, ENC28J60_REG_EIR, &int_stat);
|
||||||
|
|
||||||
if (int_stat & ENC28J60_BIT_EIR_PKTIF) {
|
if (int_stat & ENC28J60_BIT_EIR_PKTIF) {
|
||||||
eth_enc28j60_rx(dev);
|
eth_enc28j60_rx(dev);
|
||||||
/* Clear rx interruption flag */
|
/* Clear rx interruption flag */
|
||||||
|
@ -718,6 +827,10 @@ static const struct eth_enc28j60_config eth_enc28j60_0_config = {
|
||||||
.spi_port = CONFIG_ETH_ENC28J60_0_SPI_PORT_NAME,
|
.spi_port = CONFIG_ETH_ENC28J60_0_SPI_PORT_NAME,
|
||||||
.spi_freq = CONFIG_ETH_ENC28J60_0_SPI_BUS_FREQ,
|
.spi_freq = CONFIG_ETH_ENC28J60_0_SPI_BUS_FREQ,
|
||||||
.spi_slave = CONFIG_ETH_ENC28J60_0_SLAVE,
|
.spi_slave = CONFIG_ETH_ENC28J60_0_SLAVE,
|
||||||
|
#ifdef CONFIG_ETH_ENC28J60_0_GPIO_SPI_CS
|
||||||
|
.spi_cs_port = CONFIG_ETH_ENC28J60_0_SPI_CS_PORT_NAME,
|
||||||
|
.spi_cs_pin = CONFIG_ETH_ENC28J60_0_SPI_CS_PIN,
|
||||||
|
#endif /* CONFIG_ETH_ENC28J60_0_GPIO_SPI_CS */
|
||||||
.full_duplex = CONFIG_ETH_EN28J60_0_FULL_DUPLEX,
|
.full_duplex = CONFIG_ETH_EN28J60_0_FULL_DUPLEX,
|
||||||
.timeout = CONFIG_ETH_EN28J60_TIMEOUT,
|
.timeout = CONFIG_ETH_EN28J60_TIMEOUT,
|
||||||
};
|
};
|
||||||
|
|
|
@ -217,6 +217,8 @@ struct eth_enc28j60_config {
|
||||||
const char *gpio_port;
|
const char *gpio_port;
|
||||||
u8_t gpio_pin;
|
u8_t gpio_pin;
|
||||||
const char *spi_port;
|
const char *spi_port;
|
||||||
|
u8_t spi_cs_pin;
|
||||||
|
const char *spi_cs_port;
|
||||||
u32_t spi_freq;
|
u32_t spi_freq;
|
||||||
u8_t spi_slave;
|
u8_t spi_slave;
|
||||||
u8_t full_duplex;
|
u8_t full_duplex;
|
||||||
|
@ -230,6 +232,8 @@ struct eth_enc28j60_runtime {
|
||||||
struct k_thread thread;
|
struct k_thread thread;
|
||||||
struct device *gpio;
|
struct device *gpio;
|
||||||
struct device *spi;
|
struct device *spi;
|
||||||
|
struct spi_cs_control spi_cs;
|
||||||
|
struct spi_config spi_cfg;
|
||||||
struct gpio_callback gpio_cb;
|
struct gpio_callback gpio_cb;
|
||||||
u8_t mem_buf[MAX_BUFFER_LENGTH + 1];
|
u8_t mem_buf[MAX_BUFFER_LENGTH + 1];
|
||||||
u8_t tx_tsv[TSV_SIZE];
|
u8_t tx_tsv[TSV_SIZE];
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue