drivers: cc2520: Add a new IP stack ready adaptation of CC2520 driver

It's basically a copy/paste of original driver,
using native IP stack API.

This is meant to avoid cluttering the original driver
code with #ifdef, and in future it will help removing
the old driver as well.

Change-Id: I67d974ad7440d258583a5c7c6c7160e99210808c
Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
This commit is contained in:
Tomasz Bursztyka 2016-06-15 10:46:10 +02:00 committed by Jukka Rissanen
commit 4c0d9bcf9a
8 changed files with 1374 additions and 284 deletions

View file

@ -21,6 +21,11 @@ menu "Device Drivers"
source "drivers/bluetooth/Kconfig" source "drivers/bluetooth/Kconfig"
config IEEE802154
bool
default n
default y if NETWORKING_WITH_15_4 || NET_L2_IEEE802154
source "drivers/ieee802154/Kconfig" source "drivers/ieee802154/Kconfig"
source "drivers/console/Kconfig" source "drivers/console/Kconfig"

View file

@ -18,7 +18,7 @@ obj-$(CONFIG_PWM) += pwm/
obj-$(CONFIG_ADC) += adc/ obj-$(CONFIG_ADC) += adc/
obj-$(CONFIG_ETHERNET) += ethernet/ obj-$(CONFIG_ETHERNET) += ethernet/
obj-$(CONFIG_SLIP) += slip/ obj-$(CONFIG_SLIP) += slip/
obj-$(CONFIG_NETWORKING_WITH_15_4) += ieee802154/ obj-$(CONFIG_IEEE802154) += ieee802154/
obj-$(CONFIG_WATCHDOG) += watchdog/ obj-$(CONFIG_WATCHDOG) += watchdog/
obj-$(CONFIG_RTC) += rtc/ obj-$(CONFIG_RTC) += rtc/
obj-$(CONFIG_CLOCK_CONTROL) += clock_control/ obj-$(CONFIG_CLOCK_CONTROL) += clock_control/

View file

@ -33,10 +33,20 @@
# #
# IEEE 802.15.4 options # IEEE 802.15.4 options
# #
menu "IEEE 802.15.4 Options" menu "IEEE 802.15.4 drivers options"
depends on NETWORKING_WITH_15_4 depends on NETWORKING_WITH_15_4 || NET_L2_IEEE802154
if NETWORKING_WITH_15_4_TI_CC2520 config TI_CC2520_LEGACY
bool "TI CC2520 Driver support"
depends on NETWORKING_WITH_15_4_TI_CC2520
default n
config TI_CC2520
bool "TI CC2520 Driver support"
depends on NET_L2_IEEE802154
default n
if TI_CC2520_LEGACY || TI_CC2520
config SYS_LOG_TI_CC2520_LEVEL config SYS_LOG_TI_CC2520_LEVEL
int int
@ -112,6 +122,7 @@ config TI_CC2520_AUTO_CRC
config TI_CC2520_LINK_DETAILS config TI_CC2520_LINK_DETAILS
bool "Forward RSSI and link information on reception to upper stack" bool "Forward RSSI and link information on reception to upper stack"
default n default n
depends on TI_CC2520_LEGACY
select TI_CC2520_AUTO_CRC select TI_CC2520_AUTO_CRC
help help
If necessary, it will be possible to grab link and RSSI information If necessary, it will be possible to grab link and RSSI information
@ -127,7 +138,5 @@ config TI_CC2520_AUTO_ACK
this feature requires the chip to get hardware filtering on, and this feature requires the chip to get hardware filtering on, and
thus the above stack needs to provide the right information for such thus the above stack needs to provide the right information for such
filtering feature to work. filtering feature to work.
endif endif
endmenu endmenu

View file

@ -3,4 +3,5 @@ subdir-ccflags-y +=-I${srctree}/net/ip/contiki/os/lib
subdir-ccflags-y +=-I${srctree}/net/ip/contiki/os subdir-ccflags-y +=-I${srctree}/net/ip/contiki/os
subdir-ccflags-y +=-I${srctree}/net/ip subdir-ccflags-y +=-I${srctree}/net/ip
obj-$(CONFIG_NETWORKING_WITH_15_4_TI_CC2520) = ieee802154_cc2520.o obj-$(CONFIG_TI_CC2520_LEGACY) += ieee802154_cc2520_legacy.o
obj-$(CONFIG_TI_CC2520) += ieee802154_cc2520.o

View file

@ -1,4 +1,4 @@
/* ieee802154_cc2520.c - IEEE 802.15.4 driver for TI CC2520 */ /* ieee802154_cc2520_yaip.c - YAIP version of TI CC2520 driver */
/* /*
* Copyright (c) 2016 Intel Corporation. * Copyright (c) 2016 Intel Corporation.
@ -24,6 +24,8 @@
#include <board.h> #include <board.h>
#include <device.h> #include <device.h>
#include <init.h> #include <init.h>
#include <net/net_if.h>
#include <net/nbuf.h>
#include <misc/byteorder.h> #include <misc/byteorder.h>
#include <string.h> #include <string.h>
@ -31,12 +33,7 @@
#include <gpio.h> #include <gpio.h>
#include <net/l2_buf.h> #include <net/ieee802154_radio.h>
#include <packetbuf.h>
#include <dev/radio.h>
#include <net_driver_15_4.h>
static struct device *cc2520_sglt;
#include "ieee802154_cc2520.h" #include "ieee802154_cc2520.h"
@ -53,7 +50,7 @@ static struct device *cc2520_sglt;
*/ */
#if defined(CONFIG_TI_CC2520_AUTO_CRC) && defined(CONFIG_TI_CC2520_AUTO_ACK) #if defined(CONFIG_TI_CC2520_AUTO_CRC) && defined(CONFIG_TI_CC2520_AUTO_ACK)
#define CC2520_AUTOMATISM (FRMCTRL0_AUTOCRC | FRMCTRL0_AUTOACK) #define CC2520_AUTOMATISM (FRMCTRL0_AUTOCRC | FRMCTRL0_AUTOACK)
#elif defined(CONFIG_TI_CC2520_AUTO_CRC) #elif defined(CONFIG_TI_CC2520_AUTO_CRC)
#define CC2520_AUTOMATISM (FRMCTRL0_AUTOCRC) #define CC2520_AUTOMATISM (FRMCTRL0_AUTOCRC)
@ -270,6 +267,23 @@ static bool verify_osc_stabilization(struct cc2520_context *cc2520)
} }
static inline uint8_t *get_mac(struct device *dev)
{
struct cc2520_context *cc2520 = dev->driver_data;
cc2520->mac_addr[0] = 0x00;
cc2520->mac_addr[1] = 0x12;
cc2520->mac_addr[2] = 0x4b;
cc2520->mac_addr[3] = 0x00;
UNALIGNED_PUT(sys_cpu_to_be32(sys_rand32_get()),
(uint32_t *) ((void *)cc2520->mac_addr+4));
cc2520->mac_addr[7] = (cc2520->mac_addr[7] & ~0x01) | 0x02;
return cc2520->mac_addr;
}
/****************** /******************
* GPIO functions * * GPIO functions *
*****************/ *****************/
@ -396,7 +410,8 @@ static inline bool write_txfifo_length(struct cc2520_spi *spi,
struct net_buf *buf) struct net_buf *buf)
{ {
spi->cmd_buf[0] = CC2520_INS_TXBUF; spi->cmd_buf[0] = CC2520_INS_TXBUF;
spi->cmd_buf[1] = packetbuf_totlen(buf) + CC2520_FCS_LENGTH; spi->cmd_buf[1] = net_nbuf_ll_reserve(buf) +
net_buf_frags_len(buf) + CC2520_FCS_LENGTH;
spi_slave_select(spi->dev, spi->slave); spi_slave_select(spi->dev, spi->slave);
@ -409,17 +424,20 @@ static inline bool write_txfifo_content(struct cc2520_spi *spi,
uint8_t cmd[128 + 1]; uint8_t cmd[128 + 1];
cmd[0] = CC2520_INS_TXBUF; cmd[0] = CC2520_INS_TXBUF;
memcpy(&cmd[1], packetbuf_hdrptr(buf), packetbuf_totlen(buf)); memcpy(&cmd[1], net_nbuf_ll(buf),
net_nbuf_ll_reserve(buf) + net_buf_frags_len(buf));
spi_slave_select(spi->dev, spi->slave); spi_slave_select(spi->dev, spi->slave);
return (spi_write(spi->dev, cmd, packetbuf_totlen(buf) + 1) == 0); return (spi_write(spi->dev, cmd, net_nbuf_ll_reserve(buf) +
net_buf_frags_len(buf) + 1) == 0);
} }
static inline bool verify_txfifo_status(struct cc2520_context *cc2520, static inline bool verify_txfifo_status(struct cc2520_context *cc2520,
struct net_buf *buf) struct net_buf *buf)
{ {
if (read_reg_txfifocnt(&cc2520->spi) < (packetbuf_totlen(buf) + 1) || if (read_reg_txfifocnt(&cc2520->spi) < (net_nbuf_ll_reserve(buf) +
net_buf_frags_len(buf)) ||
(read_reg_excflag0(&cc2520->spi) & EXCFLAG0_TX_UNDERFLOW)) { (read_reg_excflag0(&cc2520->spi) & EXCFLAG0_TX_UNDERFLOW)) {
return false; return false;
} }
@ -510,28 +528,12 @@ static inline bool read_rxfifo_content(struct cc2520_spi *spi,
return false; return false;
} }
memcpy(packetbuf_dataptr(buf), &data[1], len); memcpy(buf->data, &data[1], len);
packetbuf_set_datalen(buf, len); net_buf_add(buf, len);
return true; return true;
} }
static inline bool read_rxfifo_footer(struct cc2520_spi *spi, uint8_t *buf)
{
spi->cmd_buf[0] = CC2520_INS_RXBUF;
memset(&spi->cmd_buf[1], 0, CC2520_FCS_LENGTH);
spi_slave_select(spi->dev, spi->slave);
if (spi_transceive(spi->dev, spi->cmd_buf, CC2520_FCS_LENGTH+1,
spi->cmd_buf, CC2520_FCS_LENGTH+1) != 0) {
return false;
}
memcpy(buf, &spi->cmd_buf[1], CC2520_FCS_LENGTH);
return true;
}
#else /* CONFIG_SPI_QMSI */ #else /* CONFIG_SPI_QMSI */
static inline uint8_t read_rxfifo_length(struct cc2520_spi *spi) static inline uint8_t read_rxfifo_length(struct cc2520_spi *spi)
{ {
@ -564,24 +566,8 @@ static inline bool read_rxfifo_content(struct cc2520_spi *spi,
return false; return false;
} }
memcpy(packetbuf_dataptr(buf), &data[1], len); memcpy(buf->data, &data[1], len);
packetbuf_set_datalen(buf, len); net_buf_add(buf, len);
return true;
}
static inline bool read_rxfifo_footer(struct cc2520_spi *spi, uint8_t *buf)
{
spi->cmd_buf[0] = CC2520_INS_RXBUF;
spi_slave_select(spi->dev, spi->slave);
if (spi_transceive(spi->dev, spi->cmd_buf, 1,
spi->cmd_buf, CC2520_FCS_LENGTH+1) != 0) {
return false;
}
memcpy(buf, &spi->cmd_buf[1], CC2520_FCS_LENGTH);
return true; return true;
} }
@ -602,10 +588,8 @@ static void cc2520_rx(int arg, int unused2)
struct device *dev = INT_TO_POINTER(arg); struct device *dev = INT_TO_POINTER(arg);
struct cc2520_context *cc2520 = dev->driver_data; struct cc2520_context *cc2520 = dev->driver_data;
struct net_buf *pkt_buf = NULL; struct net_buf *pkt_buf = NULL;
struct net_buf *buf = NULL;
uint8_t pkt_len; uint8_t pkt_len;
#ifdef CONFIG_TI_CC2520_AUTO_CRC
uint8_t buf[CC2520_FCS_LENGTH];
#endif
ARG_UNUSED(unused2); ARG_UNUSED(unused2);
@ -615,6 +599,7 @@ static void cc2520_rx(int arg, int unused2)
if (cc2520->overflow) { if (cc2520->overflow) {
SYS_LOG_DBG("RX overflow!\n"); SYS_LOG_DBG("RX overflow!\n");
cc2520->overflow = false; cc2520->overflow = false;
goto flush; goto flush;
} }
@ -624,59 +609,70 @@ static void cc2520_rx(int arg, int unused2)
goto flush; goto flush;
} }
pkt_buf = l2_buf_get_reserve(0); buf = net_nbuf_get_reserve_rx(0);
if (!pkt_buf) { if (!buf) {
SYS_LOG_DBG("No pkt buf available\n"); SYS_LOG_DBG("No buf available\n");
goto flush; goto flush;
} }
if (!read_rxfifo_content(&cc2520->spi, pkt_buf, pkt_buf = net_nbuf_get_reserve_data(0);
pkt_len - CC2520_FCS_LENGTH)) { if (!pkt_buf) {
SYS_LOG_ERR("No content read\n"); SYS_LOG_DBG("No pkt_buf available\n");
goto error; goto out;
}
#ifdef CONFIG_TI_CC2520_AUTO_CRC
if (!read_rxfifo_footer(&cc2520->spi, buf)) {
SYS_LOG_ERR("No footer read\n");
goto error;
} }
if (!(buf[1] & CC2520_FCS_CRC_OK)) { net_buf_frag_insert(buf, pkt_buf);
SYS_LOG_ERR("Bad packet CRC\n");
goto error; if (!read_rxfifo_content(&cc2520->spi, pkt_buf, pkt_len)) {
SYS_LOG_DBG("No content read\n");
goto out;
}
#ifdef CONFIG_TI_CC2520_AUTO_CRC
if (!(pkt_buf->data[pkt_len - 1] & CC2520_FCS_CRC_OK)) {
SYS_LOG_DBG("Bad packet CRC\n");
goto out;
} }
#ifdef CONFIG_TI_CC2520_LINK_DETAILS
packetbuf_set_attr(pkt_buf, PACKETBUF_ATTR_RSSI,
buf[0]);
packetbuf_set_attr(pkt_buf, PACKETBUF_ATTR_LINK_QUALITY,
buf[1] & CC2520_FCS_CORRELATION);
#endif /* CONFIG_TI_CC2520_LINK_DETAILS */
#endif /* CONFIG_TI_CC2520_AUTO_CRC */ #endif /* CONFIG_TI_CC2520_AUTO_CRC */
SYS_LOG_DBG("Caught a packet (%u)\n", if (ieee802154_radio_handle_ack(cc2520->iface, buf) == NET_OK) {
pkt_len - CC2520_FCS_LENGTH); SYS_LOG_DBG("ACK packet handled");
goto out;
}
if (net_driver_15_4_recv_from_hw(pkt_buf) < 0) { SYS_LOG_DBG("Caught a packet (%u)\n", pkt_len - CC2520_FCS_LENGTH);
SYS_LOG_ERR("Packet dropped by NET stack\n");
goto error; if (net_recv_data(cc2520->iface, buf) < 0) {
SYS_LOG_DBG("Packet dropped by NET stack\n");
goto out;
} }
net_analyze_stack("CC2520 Rx Fiber stack", net_analyze_stack("CC2520 Rx Fiber stack",
(unsigned char *)cc2520->cc2520_rx_stack, (unsigned char *)cc2520->cc2520_rx_stack,
CONFIG_CC2520_RX_STACK_SIZE); CONFIG_CC2520_RX_STACK_SIZE);
goto flush; goto flush;
error: out:
l2_buf_unref(pkt_buf); net_buf_unref(buf);
flush: flush:
flush_rxfifo(cc2520); flush_rxfifo(cc2520);
} }
} }
/******************** /********************
* Radio device API * * Radio device API *
*******************/ *******************/
static inline int cc2520_set_channel(struct device *dev, uint16_t channel) static int cc2520_cca(struct device *dev)
{
struct cc2520_context *cc2520 = dev->driver_data;
if (!get_cca(cc2520)) {
return -EBUSY;
}
return 0;
}
static int cc2520_set_channel(struct device *dev, uint16_t channel)
{ {
struct cc2520_context *cc2520 = dev->driver_data; struct cc2520_context *cc2520 = dev->driver_data;
@ -697,7 +693,7 @@ static inline int cc2520_set_channel(struct device *dev, uint16_t channel)
return 0; return 0;
} }
static inline int cc2520_set_pan_id(struct device *dev, uint16_t pan_id) static int cc2520_set_pan_id(struct device *dev, uint16_t pan_id)
{ {
struct cc2520_context *cc2520 = dev->driver_data; struct cc2520_context *cc2520 = dev->driver_data;
@ -713,7 +709,7 @@ static inline int cc2520_set_pan_id(struct device *dev, uint16_t pan_id)
return 0; return 0;
} }
static inline int cc2520_set_short_addr(struct device *dev, uint16_t short_addr) static int cc2520_set_short_addr(struct device *dev, uint16_t short_addr)
{ {
struct cc2520_context *cc2520 = dev->driver_data; struct cc2520_context *cc2520 = dev->driver_data;
@ -729,8 +725,7 @@ static inline int cc2520_set_short_addr(struct device *dev, uint16_t short_addr)
return 0; return 0;
} }
static inline int cc2520_set_ieee_addr(struct device *dev, static int cc2520_set_ieee_addr(struct device *dev, const uint8_t *ieee_addr)
const uint8_t *ieee_addr)
{ {
struct cc2520_context *cc2520 = dev->driver_data; struct cc2520_context *cc2520 = dev->driver_data;
uint8_t ext_addr[8]; uint8_t ext_addr[8];
@ -752,13 +747,64 @@ static inline int cc2520_set_ieee_addr(struct device *dev,
return 0; return 0;
} }
static inline int cc2520_tx(struct device *dev, struct net_buf *buf) static int cc2520_set_txpower(struct device *dev, int16_t dbm)
{
struct cc2520_context *cc2520 = dev->driver_data;
uint8_t pwr;
SYS_LOG_DBG("%s: %d\n", dbm);
/* See chapter 19 part 8 */
switch (dbm) {
case 5:
pwr = 0xF7;
break;
case 3:
pwr = 0xF2;
break;
case 2:
pwr = 0xAB;
break;
case 1:
pwr = 0x13;
break;
case 0:
pwr = 0x32;
break;
case -2:
pwr = 0x81;
break;
case -4:
pwr = 0x88;
break;
case -7:
pwr = 0x2C;
break;
case -18:
pwr = 0x03;
break;
default:
goto error;
}
if (!write_reg_txpower(&cc2520->spi, pwr)) {
goto error;
}
return 0;
error:
SYS_LOG_DBG("%s: FAILED\n");
return -EIO;
}
static int cc2520_tx(struct device *dev, struct net_buf *buf)
{ {
struct cc2520_context *cc2520 = dev->driver_data; struct cc2520_context *cc2520 = dev->driver_data;
uint8_t retry = 2; uint8_t retry = 2;
bool status; bool status;
SYS_LOG_DBG(" %p (%u)\n", buf, packetbuf_totlen(buf)); SYS_LOG_DBG("%s: %p (%u)\n", __func__,
buf, net_nbuf_ll_reserve(buf) + net_buf_frags_len(buf));
if (!write_reg_excflag0(&cc2520->spi, EXCFLAG0_RESET_TX_FLAGS) || if (!write_reg_excflag0(&cc2520->spi, EXCFLAG0_RESET_TX_FLAGS) ||
!write_txfifo_length(&cc2520->spi, buf) || !write_txfifo_length(&cc2520->spi, buf) ||
@ -805,27 +851,7 @@ error:
return -EIO; return -EIO;
} }
static inline uint8_t *cc2520_get_mac(struct device *dev) static int cc2520_start(struct device *dev)
{
struct cc2520_context *cc2520 = dev->driver_data;
if (cc2520->mac_addr[1] == 0x00) {
/* TI OUI */
cc2520->mac_addr[0] = 0x00;
cc2520->mac_addr[1] = 0x12;
cc2520->mac_addr[2] = 0x4b;
cc2520->mac_addr[3] = 0x00;
UNALIGNED_PUT(sys_cpu_to_be32(sys_rand32_get()),
(uint32_t *) ((void *)cc2520->mac_addr+4));
cc2520->mac_addr[7] = (cc2520->mac_addr[7] & ~0x01) | 0x02;
}
return cc2520->mac_addr;
}
static inline int cc2520_start(struct device *dev)
{ {
struct cc2520_context *cc2520 = dev->driver_data; struct cc2520_context *cc2520 = dev->driver_data;
@ -845,7 +871,7 @@ static inline int cc2520_start(struct device *dev)
return 0; return 0;
} }
static inline int cc2520_stop(struct device *dev) static int cc2520_stop(struct device *dev)
{ {
struct cc2520_context *cc2520 = dev->driver_data; struct cc2520_context *cc2520 = dev->driver_data;
@ -865,159 +891,6 @@ static inline int cc2520_stop(struct device *dev)
} }
/***************************
* Legacy Radio device API *
**************************/
/**
* NOTE: This legacy API DOES NOT FIT within Zephyr device driver model
* and, as such, will be made obsolete soon (well, hopefully...)
*/
static int cc2520_initialize(void)
{
const uint8_t *mac = cc2520_get_mac(cc2520_sglt);
uint16_t short_addr;
/** That is not great either, basically ieee802154/net stack,
* should get the mac, then set what's relevant. It's not up
* to the driver to do such thing.
*/
net_set_mac((uint8_t *)mac, 8);
/* Setting short address... */
short_addr = (mac[0] << 8) + mac[1];
cc2520_set_short_addr(cc2520_sglt, short_addr);
/* ... And ieee address */
cc2520_set_ieee_addr(cc2520_sglt, mac);
return 1;
}
static int cc2520_prepare(const void *payload, unsigned short payload_len)
{
return 0;
}
static int cc2520_transmit(struct net_buf *buf, unsigned short transmit_len)
{
if (cc2520_tx(cc2520_sglt, buf) != 0) {
return RADIO_TX_ERR;
}
return RADIO_TX_OK;
}
static int cc2520_send(struct net_buf *buf,
const void *payload, unsigned short payload_len)
{
return cc2520_transmit(buf, payload_len);
}
static int cc2520_read(void *buf, unsigned short buf_len)
{
return 0;
}
static int cc2520_channel_clear(void)
{
struct cc2520_context *cc2520 = cc2520_sglt->driver_data;
return get_cca(cc2520);
}
static int cc2520_receiving_packet(void)
{
return 0;
}
static int cc2520_pending_packet(void)
{
return 0;
}
static int cc2520_on(void)
{
return (cc2520_start(cc2520_sglt) == 0);
}
static int cc2520_off(void)
{
return (cc2520_stop(cc2520_sglt) == 0);
}
static radio_result_t cc2520_get_value(radio_param_t param,
radio_value_t *value)
{
switch (param) {
case RADIO_PARAM_POWER_MODE:
*value = RADIO_POWER_MODE_ON;
break;
case RADIO_PARAM_CHANNEL:
*value = CONFIG_TI_CC2520_CHANNEL;
break;
case RADIO_CONST_CHANNEL_MIN:
*value = 11;
break;
case RADIO_CONST_CHANNEL_MAX:
*value = 26;
break;
default:
return RADIO_RESULT_NOT_SUPPORTED;
}
return RADIO_RESULT_OK;
}
static radio_result_t cc2520_set_value(radio_param_t param,
radio_value_t value)
{
switch (param) {
case RADIO_PARAM_POWER_MODE:
break;
case RADIO_PARAM_CHANNEL:
cc2520_set_channel(cc2520_sglt, value);
break;
case RADIO_PARAM_PAN_ID:
cc2520_set_pan_id(cc2520_sglt, value);
break;
case RADIO_PARAM_RX_MODE:
default:
return RADIO_RESULT_NOT_SUPPORTED;
}
return RADIO_RESULT_OK;
}
static radio_result_t cc2520_get_object(radio_param_t param,
void *dest, size_t size)
{
return RADIO_RESULT_NOT_SUPPORTED;
}
static radio_result_t cc2520_set_object(radio_param_t param,
const void *src, size_t size)
{
return RADIO_RESULT_NOT_SUPPORTED;
}
struct radio_driver cc2520_15_4_radio_driver = {
.init = cc2520_initialize,
.prepare = cc2520_prepare,
.transmit = cc2520_transmit,
.send = cc2520_send,
.read = cc2520_read,
.channel_clear = cc2520_channel_clear,
.receiving_packet = cc2520_receiving_packet,
.pending_packet = cc2520_pending_packet,
.on = cc2520_on,
.off = cc2520_off,
.get_value = cc2520_get_value,
.set_value = cc2520_set_value,
.get_object = cc2520_get_object,
.set_object = cc2520_set_object,
};
/****************** /******************
* Initialization * * Initialization *
*****************/ *****************/
@ -1114,8 +987,6 @@ static int cc2520_init(struct device *dev)
{ {
struct cc2520_context *cc2520 = dev->driver_data; struct cc2520_context *cc2520 = dev->driver_data;
dev->driver_api = NULL;
device_sync_call_init(&cc2520->tx_sync); device_sync_call_init(&cc2520->tx_sync);
atomic_set(&cc2520->tx, 0); atomic_set(&cc2520->tx, 0);
nano_sem_init(&cc2520->rx_lock); nano_sem_init(&cc2520->rx_lock);
@ -1138,26 +1009,48 @@ static int cc2520_init(struct device *dev)
return -EIO; return -EIO;
} }
/* That should not be done here... */
if (cc2520_set_pan_id(dev, 0xFFFF) != 0 ||
cc2520_set_short_addr(dev, 0x0000) != 0 ||
cc2520_set_channel(dev, CONFIG_TI_CC2520_CHANNEL) != 0) {
SYS_LOG_ERR("Could not initialize properly cc2520\n");
return -EIO;
}
task_fiber_start(cc2520->cc2520_rx_stack, task_fiber_start(cc2520->cc2520_rx_stack,
CONFIG_CC2520_RX_STACK_SIZE, CONFIG_CC2520_RX_STACK_SIZE,
cc2520_rx, POINTER_TO_INT(dev), cc2520_rx, POINTER_TO_INT(dev),
0, 0, 0); 0, 0, 0);
cc2520_sglt = dev;
return 0; return 0;
} }
static void cc2520_iface_init(struct net_if *iface)
{
struct device *dev = net_if_get_device(iface);
struct cc2520_context *cc2520 = dev->driver_data;
uint8_t *mac = get_mac(dev);
SYS_LOG_DBG("cc2520_iface_init\n");
net_if_set_link_addr(iface, mac, 8);
cc2520->iface = iface;
ieee802154_init(iface);
}
static struct cc2520_context cc2520_context_data; static struct cc2520_context cc2520_context_data;
DEVICE_INIT(cc2520, CONFIG_TI_CC2520_DRV_NAME, static struct ieee802154_radio_api cc2520_radio_api = {
cc2520_init, &cc2520_context_data, NULL, .iface_api.init = cc2520_iface_init,
APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); .iface_api.send = ieee802154_radio_send,
.cca = cc2520_cca,
.set_channel = cc2520_set_channel,
.set_pan_id = cc2520_set_pan_id,
.set_short_addr = cc2520_set_short_addr,
.set_ieee_addr = cc2520_set_ieee_addr,
.set_txpower = cc2520_set_txpower,
.start = cc2520_start,
.stop = cc2520_stop,
.tx = cc2520_tx,
};
NET_DEVICE_INIT(cc2520, CONFIG_TI_CC2520_DRV_NAME,
cc2520_init, &cc2520_context_data, NULL,
CONFIG_KERNEL_INIT_PRIORITY_DEFAULT,
&cc2520_radio_api, IEEE802154_L2,
NET_L2_GET_CTX_TYPE(IEEE802154_L2), 127);

View file

@ -43,6 +43,9 @@ struct cc2520_spi {
}; };
struct cc2520_context { struct cc2520_context {
#ifdef CONFIG_NET_YAIP
struct net_if *iface;
#endif
/**************************/ /**************************/
struct device **gpios; struct device **gpios;
struct gpio_callback sfd_cb; struct gpio_callback sfd_cb;

File diff suppressed because it is too large Load diff

View file

@ -400,6 +400,7 @@ config NETWORKING_WITH_15_4_TI_CC2520
bool bool
prompt "TI CC2520" prompt "TI CC2520"
select TEST_RANDOM_GENERATOR select TEST_RANDOM_GENERATOR
select TI_CC2520_LEGACY
help help
Enable Texas Instruments CC2520 802.15.4 radio driver. Enable Texas Instruments CC2520 802.15.4 radio driver.