drivers/ieee802154: Switch CC2520 to new SPI API
Finally switching to new SPI API. It makes code simpler and performs better. Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
This commit is contained in:
parent
f44ba8e7d4
commit
d4065ae73e
|
@ -23,40 +23,39 @@ if IEEE802154_CC2520
|
|||
|
||||
config SPI
|
||||
def_bool y
|
||||
config SPI_QMSI
|
||||
def_bool n
|
||||
config SPI_DW
|
||||
def_bool y
|
||||
|
||||
config GPIO
|
||||
def_bool y
|
||||
|
||||
config IEEE802154_CC2520_SPI_DRV_NAME
|
||||
default SPI_1_NAME
|
||||
config IEEE802154_CC2520_SPI_FREQ
|
||||
default 4
|
||||
default 8000000
|
||||
config IEEE802154_CC2520_SPI_SLAVE
|
||||
default 1
|
||||
|
||||
|
||||
if GPIO_QMSI
|
||||
|
||||
config IEEE802154_CC2520_GPIO_0_NAME
|
||||
default GPIO_QMSI_0_NAME
|
||||
config IEEE802154_CC2520_GPIO_1_NAME
|
||||
default GPIO_QMSI_1_NAME
|
||||
|
||||
endif # GPIO_QMSI
|
||||
|
||||
if SPI_QMSI
|
||||
config SPI_CS_GPIO
|
||||
config IEEE802154_CC2520_GPIO_SPI_CS
|
||||
def_bool y
|
||||
config SPI_1_CS_GPIO_PORT
|
||||
config IEEE802154_CC2520_GPIO_SPI_CS_DRV_NAME
|
||||
default GPIO_QMSI_0_NAME
|
||||
config SPI_1_CS_GPIO_PIN
|
||||
config IEEE802154_CC2520_GPIO_SPI_CS_PIN
|
||||
default 11
|
||||
|
||||
config IEEE802154_CC2520_GPIO_0_NAME
|
||||
string
|
||||
default GPIO_QMSI_0_NAME
|
||||
config IEEE802154_CC2520_GPIO_1_NAME
|
||||
string
|
||||
default GPIO_QMSI_1_NAME
|
||||
endif
|
||||
|
||||
endif # IEEE802154_CC2520
|
||||
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
menuconfig IEEE802154_CC2520
|
||||
bool "TI CC2520 Driver support"
|
||||
depends on NETWORKING
|
||||
select SPI_LEGACY_API
|
||||
default n
|
||||
|
||||
if IEEE802154_CC2520
|
||||
|
@ -42,6 +41,29 @@ config IEEE802154_CC2520_SPI_SLAVE
|
|||
This option sets the SPI slave number SPI controller has to switch
|
||||
to when dealing with CC2520 chip.
|
||||
|
||||
config IEEE802154_CC2520_GPIO_SPI_CS
|
||||
bool "Manage SPI CS through 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 IEEE802154_CC2520_GPIO_SPI_CS_DRV_NAME
|
||||
string "GPIO driver's name to use to drive SPI CS through"
|
||||
default ""
|
||||
depends on IEEE802154_CC2520_GPIO_SPI_CS
|
||||
help
|
||||
This option is mandatory to set which GPIO controller to use in order
|
||||
to actually emulate the SPI CS.
|
||||
|
||||
config IEEE802154_CC2520_GPIO_SPI_CS_PIN
|
||||
int "GPIO PIN to use to drive SPI CS through"
|
||||
default 0
|
||||
depends on IEEE802154_CC2520_GPIO_SPI_CS
|
||||
help
|
||||
This option is mandatory to set which GPIO pin to use in order
|
||||
to actually emulate the SPI CS.
|
||||
|
||||
config IEEE802154_CC2520_RX_STACK_SIZE
|
||||
int "Driver's internal RX thread stack size"
|
||||
default 800
|
||||
|
|
|
@ -55,6 +55,10 @@
|
|||
#define CC2520_TX_THRESHOLD (0x7F)
|
||||
#define CC2520_FCS_LENGTH (2)
|
||||
|
||||
#if defined(CONFIG_IEEE802154_CC2520_GPIO_SPI_CS)
|
||||
static struct spi_cs_control cs_ctrl;
|
||||
#endif
|
||||
|
||||
/*********
|
||||
* DEBUG *
|
||||
********/
|
||||
|
@ -64,21 +68,21 @@ static inline void _cc2520_print_gpio_config(struct device *dev)
|
|||
struct cc2520_context *cc2520 = dev->driver_data;
|
||||
|
||||
SYS_LOG_DBG("GPIOCTRL0/1/2/3/4/5 = 0x%x/0x%x/0x%x/0x%x/0x%x/0x%x",
|
||||
read_reg_gpioctrl0(&cc2520->spi),
|
||||
read_reg_gpioctrl1(&cc2520->spi),
|
||||
read_reg_gpioctrl2(&cc2520->spi),
|
||||
read_reg_gpioctrl3(&cc2520->spi),
|
||||
read_reg_gpioctrl4(&cc2520->spi),
|
||||
read_reg_gpioctrl5(&cc2520->spi));
|
||||
read_reg_gpioctrl0(cc2520),
|
||||
read_reg_gpioctrl1(cc2520),
|
||||
read_reg_gpioctrl2(cc2520),
|
||||
read_reg_gpioctrl3(cc2520),
|
||||
read_reg_gpioctrl4(cc2520),
|
||||
read_reg_gpioctrl5(cc2520));
|
||||
SYS_LOG_DBG("GPIOPOLARITY: 0x%x",
|
||||
read_reg_gpiopolarity(&cc2520->spi));
|
||||
read_reg_gpiopolarity(cc2520));
|
||||
SYS_LOG_DBG("GPIOCTRL: 0x%x",
|
||||
read_reg_gpioctrl(&cc2520->spi));
|
||||
read_reg_gpioctrl(cc2520));
|
||||
}
|
||||
|
||||
static inline void _cc2520_print_exceptions(struct cc2520_context *cc2520)
|
||||
{
|
||||
u8_t flag = read_reg_excflag0(&cc2520->spi);
|
||||
u8_t flag = read_reg_excflag0(cc2520);
|
||||
|
||||
SYS_LOG_DBG("EXCFLAG0:");
|
||||
|
||||
|
@ -116,7 +120,7 @@ static inline void _cc2520_print_exceptions(struct cc2520_context *cc2520)
|
|||
|
||||
SYS_LOG_BACKEND_FN("\n");
|
||||
|
||||
flag = read_reg_excflag1(&cc2520->spi);
|
||||
flag = read_reg_excflag1(cc2520);
|
||||
|
||||
SYS_LOG_DBG("EXCFLAG1:");
|
||||
|
||||
|
@ -157,7 +161,7 @@ static inline void _cc2520_print_exceptions(struct cc2520_context *cc2520)
|
|||
|
||||
static inline void _cc2520_print_errors(struct cc2520_context *cc2520)
|
||||
{
|
||||
u8_t flag = read_reg_excflag2(&cc2520->spi);
|
||||
u8_t flag = read_reg_excflag2(cc2520);
|
||||
|
||||
SYS_LOG_DBG("EXCFLAG2:");
|
||||
|
||||
|
@ -203,67 +207,58 @@ static inline void _cc2520_print_errors(struct cc2520_context *cc2520)
|
|||
********************/
|
||||
#define _usleep(usec) k_busy_wait(usec)
|
||||
|
||||
u8_t _cc2520_read_reg(struct cc2520_spi *spi,
|
||||
bool freg, u8_t addr)
|
||||
bool _cc2520_access(struct cc2520_context *ctx, bool read, u8_t ins,
|
||||
u16_t addr, void *data, size_t length)
|
||||
{
|
||||
u8_t len = freg ? 2 : 3;
|
||||
u8_t cmd_buf[2];
|
||||
struct spi_buf buf[2] = {
|
||||
{
|
||||
.buf = cmd_buf,
|
||||
.len = 1,
|
||||
},
|
||||
{
|
||||
.buf = data,
|
||||
.len = length,
|
||||
|
||||
spi->cmd_buf[0] = freg ? CC2520_INS_REGRD | addr : CC2520_INS_MEMRD;
|
||||
spi->cmd_buf[1] = freg ? 0 : addr;
|
||||
spi->cmd_buf[2] = 0;
|
||||
}
|
||||
};
|
||||
struct spi_buf_set tx = {
|
||||
.buffers = buf,
|
||||
};
|
||||
|
||||
spi_slave_select(spi->dev, spi->slave);
|
||||
|
||||
if (spi_transceive(spi->dev, spi->cmd_buf, len,
|
||||
spi->cmd_buf, len) == 0) {
|
||||
return spi->cmd_buf[len - 1];
|
||||
cmd_buf[0] = ins;
|
||||
|
||||
if (ins == CC2520_INS_MEMRD || ins == CC2520_INS_MEMWR) {
|
||||
buf[0].len = 2;
|
||||
cmd_buf[0] |= (u8_t)(addr >> 8);
|
||||
cmd_buf[1] = (u8_t)(addr & 0xff);
|
||||
} else if (ins == CC2520_INS_REGRD || ins == CC2520_INS_REGWR) {
|
||||
cmd_buf[0] |= (u8_t)(addr & 0xff);
|
||||
}
|
||||
|
||||
return 0;
|
||||
if (read) {
|
||||
const struct spi_buf_set rx = {
|
||||
.buffers = buf,
|
||||
.count = 2
|
||||
};
|
||||
|
||||
tx.count = 1;
|
||||
|
||||
return (spi_transceive(ctx->spi, &ctx->spi_cfg, &tx, &rx) == 0);
|
||||
}
|
||||
|
||||
tx.count = data ? 2 : 1;
|
||||
|
||||
return (spi_write(ctx->spi, &ctx->spi_cfg, &tx) == 0);
|
||||
}
|
||||
|
||||
bool _cc2520_write_reg(struct cc2520_spi *spi, bool freg,
|
||||
u8_t addr, u8_t value)
|
||||
static inline u8_t _cc2520_status(struct cc2520_context *ctx)
|
||||
{
|
||||
u8_t len = freg ? 2 : 3;
|
||||
u8_t status;
|
||||
|
||||
spi->cmd_buf[0] = freg ? CC2520_INS_REGWR | addr : CC2520_INS_MEMWR;
|
||||
spi->cmd_buf[1] = freg ? value : addr;
|
||||
spi->cmd_buf[2] = freg ? 0 : value;
|
||||
|
||||
spi_slave_select(spi->dev, spi->slave);
|
||||
|
||||
return (spi_write(spi->dev, spi->cmd_buf, len) == 0);
|
||||
}
|
||||
|
||||
bool _cc2520_write_ram(struct cc2520_spi *spi, u16_t addr,
|
||||
u8_t *data_buf, u8_t len)
|
||||
{
|
||||
#ifndef CONFIG_IEEE802154_CC2520_CRYPTO
|
||||
u8_t *cmd_data = spi->cmd_buf;
|
||||
#else
|
||||
u8_t cmd_data[128];
|
||||
#endif
|
||||
|
||||
cmd_data[0] = CC2520_INS_MEMWR | (addr >> 8);
|
||||
cmd_data[1] = addr;
|
||||
|
||||
memcpy(&cmd_data[2], data_buf, len);
|
||||
|
||||
spi_slave_select(spi->dev, spi->slave);
|
||||
|
||||
return (spi_write(spi->dev, cmd_data, len + 2) == 0);
|
||||
}
|
||||
|
||||
static u8_t _cc2520_status(struct cc2520_spi *spi)
|
||||
{
|
||||
spi->cmd_buf[0] = CC2520_INS_SNOP;
|
||||
|
||||
spi_slave_select(spi->dev, spi->slave);
|
||||
|
||||
if (spi_transceive(spi->dev, spi->cmd_buf, 1,
|
||||
spi->cmd_buf, 1) == 0) {
|
||||
return spi->cmd_buf[0];
|
||||
if (_cc2520_access(ctx, true, CC2520_INS_SNOP, 0, &status, 1)) {
|
||||
return status;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -275,7 +270,7 @@ static bool verify_osc_stabilization(struct cc2520_context *cc2520)
|
|||
u8_t status;
|
||||
|
||||
do {
|
||||
status = _cc2520_status(&cc2520->spi);
|
||||
status = _cc2520_status(cc2520);
|
||||
_usleep(1);
|
||||
timeout--;
|
||||
} while (!(status & CC2520_STATUS_XOSC_STABLE_N_RUNNING) && timeout);
|
||||
|
@ -317,7 +312,7 @@ static int _cc2520_set_pan_id(struct device *dev, u16_t pan_id)
|
|||
|
||||
pan_id = sys_le16_to_cpu(pan_id);
|
||||
|
||||
if (!write_mem_pan_id(&cc2520->spi, (u8_t *) &pan_id)) {
|
||||
if (!write_mem_pan_id(cc2520, (u8_t *) &pan_id)) {
|
||||
SYS_LOG_ERR("Failed");
|
||||
return -EIO;
|
||||
}
|
||||
|
@ -333,7 +328,7 @@ static int _cc2520_set_short_addr(struct device *dev, u16_t short_addr)
|
|||
|
||||
short_addr = sys_le16_to_cpu(short_addr);
|
||||
|
||||
if (!write_mem_short_addr(&cc2520->spi, (u8_t *) &short_addr)) {
|
||||
if (!write_mem_short_addr(cc2520, (u8_t *) &short_addr)) {
|
||||
SYS_LOG_ERR("Failed");
|
||||
return -EIO;
|
||||
}
|
||||
|
@ -345,7 +340,7 @@ static int _cc2520_set_ieee_addr(struct device *dev, const u8_t *ieee_addr)
|
|||
{
|
||||
struct cc2520_context *cc2520 = dev->driver_data;
|
||||
|
||||
if (!write_mem_ext_addr(&cc2520->spi, (void *)ieee_addr)) {
|
||||
if (!write_mem_ext_addr(cc2520, (void *)ieee_addr)) {
|
||||
SYS_LOG_ERR("Failed");
|
||||
return -EIO;
|
||||
}
|
||||
|
@ -483,35 +478,24 @@ static inline void setup_gpio_callbacks(struct device *dev)
|
|||
/****************
|
||||
* TX functions *
|
||||
***************/
|
||||
static inline bool write_txfifo_length(struct cc2520_spi *spi,
|
||||
u8_t len)
|
||||
static inline bool write_txfifo_length(struct cc2520_context *ctx, u8_t len)
|
||||
{
|
||||
spi->cmd_buf[0] = CC2520_INS_TXBUF;
|
||||
spi->cmd_buf[1] = len + CC2520_FCS_LENGTH;
|
||||
u8_t length = len + CC2520_FCS_LENGTH;
|
||||
|
||||
spi_slave_select(spi->dev, spi->slave);
|
||||
|
||||
return (spi_write(spi->dev, spi->cmd_buf, 2) == 0);
|
||||
return _cc2520_access(ctx, false, CC2520_INS_TXBUF, 0, &length, 1);
|
||||
}
|
||||
|
||||
static inline bool write_txfifo_content(struct cc2520_spi *spi,
|
||||
static inline bool write_txfifo_content(struct cc2520_context *ctx,
|
||||
u8_t *frame, u8_t len)
|
||||
{
|
||||
u8_t cmd[128];
|
||||
|
||||
cmd[0] = CC2520_INS_TXBUF;
|
||||
memcpy(&cmd[1], frame, len);
|
||||
|
||||
spi_slave_select(spi->dev, spi->slave);
|
||||
|
||||
return (spi_write(spi->dev, cmd, len + 1) == 0);
|
||||
return _cc2520_access(ctx, false, CC2520_INS_TXBUF, 0, frame, len);
|
||||
}
|
||||
|
||||
static inline bool verify_txfifo_status(struct cc2520_context *cc2520,
|
||||
u8_t len)
|
||||
{
|
||||
if (read_reg_txfifocnt(&cc2520->spi) < len ||
|
||||
(read_reg_excflag0(&cc2520->spi) & EXCFLAG0_TX_UNDERFLOW)) {
|
||||
if (read_reg_txfifocnt(cc2520) < len ||
|
||||
(read_reg_excflag0(cc2520) & EXCFLAG0_TX_UNDERFLOW)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -526,7 +510,7 @@ static inline bool verify_tx_done(struct cc2520_context *cc2520)
|
|||
do {
|
||||
_usleep(1);
|
||||
timeout--;
|
||||
status = read_reg_excflag0(&cc2520->spi);
|
||||
status = read_reg_excflag0(cc2520);
|
||||
} while (!(status & EXCFLAG0_TX_FRM_DONE) && timeout);
|
||||
|
||||
return !!(status & EXCFLAG0_TX_FRM_DONE);
|
||||
|
@ -541,49 +525,38 @@ static inline void flush_rxfifo(struct cc2520_context *cc2520)
|
|||
/* Note: Errata document - 1.1 */
|
||||
enable_fifop_interrupt(cc2520, false);
|
||||
|
||||
instruct_sflushrx(&cc2520->spi);
|
||||
instruct_sflushrx(&cc2520->spi);
|
||||
instruct_sflushrx(cc2520);
|
||||
instruct_sflushrx(cc2520);
|
||||
|
||||
enable_fifop_interrupt(cc2520, true);
|
||||
|
||||
write_reg_excflag0(&cc2520->spi, EXCFLAG0_RESET_RX_FLAGS);
|
||||
write_reg_excflag0(cc2520, EXCFLAG0_RESET_RX_FLAGS);
|
||||
}
|
||||
|
||||
static inline u8_t read_rxfifo_length(struct cc2520_spi *spi)
|
||||
static inline u8_t read_rxfifo_length(struct cc2520_context *ctx)
|
||||
{
|
||||
spi->cmd_buf[0] = CC2520_INS_RXBUF;
|
||||
spi->cmd_buf[1] = 0;
|
||||
u8_t len;
|
||||
|
||||
spi_slave_select(spi->dev, spi->slave);
|
||||
|
||||
if (spi_transceive(spi->dev, spi->cmd_buf, 2,
|
||||
spi->cmd_buf, 2) == 0) {
|
||||
return spi->cmd_buf[1];
|
||||
if (_cc2520_access(ctx, true, CC2520_INS_RXBUF, 0, &len, 1)) {
|
||||
return len;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline bool read_rxfifo_content(struct cc2520_spi *spi,
|
||||
static inline bool read_rxfifo_content(struct cc2520_context *ctx,
|
||||
struct net_buf *frag, u8_t len)
|
||||
{
|
||||
u8_t data[128+1];
|
||||
|
||||
data[0] = CC2520_INS_RXBUF;
|
||||
memset(&data[1], 0, len);
|
||||
|
||||
spi_slave_select(spi->dev, spi->slave);
|
||||
|
||||
if (spi_transceive(spi->dev, data, len+1, data, len+1) != 0) {
|
||||
if (!_cc2520_access(ctx, true, CC2520_INS_RXBUF, 0, frag->data, len)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (read_reg_excflag0(spi) & EXCFLAG0_RX_UNDERFLOW) {
|
||||
if (read_reg_excflag0(ctx) & EXCFLAG0_RX_UNDERFLOW) {
|
||||
SYS_LOG_ERR("RX underflow!");
|
||||
return false;
|
||||
}
|
||||
|
||||
memcpy(frag->data, &data[1], len);
|
||||
net_buf_add(frag, len);
|
||||
|
||||
return true;
|
||||
|
@ -617,46 +590,27 @@ static inline void insert_radio_noise_details(struct net_pkt *pkt, u8_t *buf)
|
|||
net_pkt_set_ieee802154_lqi(pkt, lqi);
|
||||
}
|
||||
|
||||
static inline bool verify_crc(struct cc2520_context *cc2520,
|
||||
struct net_pkt *pkt)
|
||||
static inline bool verify_crc(struct cc2520_context *ctx, struct net_pkt *pkt)
|
||||
{
|
||||
u8_t *noise_buf;
|
||||
u8_t fcs[2];
|
||||
|
||||
if (!IS_ENABLED(CONFIG_IEEE802154_RAW_MODE)) {
|
||||
cc2520->spi.cmd_buf[0] = CC2520_INS_RXBUF;
|
||||
cc2520->spi.cmd_buf[1] = 0;
|
||||
cc2520->spi.cmd_buf[2] = 0;
|
||||
|
||||
spi_slave_select(cc2520->spi.dev, cc2520->spi.slave);
|
||||
|
||||
if (spi_transceive(cc2520->spi.dev, cc2520->spi.cmd_buf, 3,
|
||||
cc2520->spi.cmd_buf, 3) != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!(cc2520->spi.cmd_buf[2] & CC2520_FCS_CRC_OK)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
noise_buf = &cc2520->spi.cmd_buf[1];
|
||||
} else {
|
||||
if (!(pkt->frags->data[pkt->frags->len - 1] &
|
||||
CC2520_FCS_CRC_OK)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
noise_buf = &pkt->frags->data[pkt->frags->len - 2];
|
||||
if (!_cc2520_access(ctx, true, CC2520_INS_RXBUF, 0, &fcs, 2)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
insert_radio_noise_details(pkt, noise_buf);
|
||||
if (!(fcs[1] & CC2520_FCS_CRC_OK)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
insert_radio_noise_details(pkt, fcs);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline bool verify_rxfifo_validity(struct cc2520_spi *spi,
|
||||
static inline bool verify_rxfifo_validity(struct cc2520_context *ctx,
|
||||
u8_t pkt_len)
|
||||
{
|
||||
if (pkt_len < 2 || read_reg_rxfifocnt(spi) != pkt_len) {
|
||||
if (pkt_len < 2 || read_reg_rxfifocnt(ctx) != pkt_len) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -683,8 +637,8 @@ static void cc2520_rx(int arg)
|
|||
goto flush;
|
||||
}
|
||||
|
||||
pkt_len = read_rxfifo_length(&cc2520->spi) & 0x7f;
|
||||
if (!verify_rxfifo_validity(&cc2520->spi, pkt_len)) {
|
||||
pkt_len = read_rxfifo_length(cc2520) & 0x7f;
|
||||
if (!verify_rxfifo_validity(cc2520, pkt_len)) {
|
||||
SYS_LOG_ERR("Invalid content");
|
||||
goto flush;
|
||||
}
|
||||
|
@ -707,7 +661,7 @@ static void cc2520_rx(int arg)
|
|||
pkt_len -= 2;
|
||||
}
|
||||
|
||||
if (!read_rxfifo_content(&cc2520->spi, pkt_frag, pkt_len)) {
|
||||
if (!read_rxfifo_content(cc2520, pkt_frag, pkt_len)) {
|
||||
SYS_LOG_ERR("No content read");
|
||||
goto flush;
|
||||
}
|
||||
|
@ -780,7 +734,7 @@ static int cc2520_set_channel(struct device *dev, u16_t channel)
|
|||
/* See chapter 16 */
|
||||
channel = 11 + 5 * (channel - 11);
|
||||
|
||||
if (!write_reg_freqctrl(&cc2520->spi, FREQCTRL_FREQ(channel))) {
|
||||
if (!write_reg_freqctrl(cc2520, FREQCTRL_FREQ(channel))) {
|
||||
SYS_LOG_ERR("Failed");
|
||||
return -EIO;
|
||||
}
|
||||
|
@ -845,7 +799,7 @@ static int cc2520_set_txpower(struct device *dev, s16_t dbm)
|
|||
goto error;
|
||||
}
|
||||
|
||||
if (!write_reg_txpower(&cc2520->spi, pwr)) {
|
||||
if (!write_reg_txpower(cc2520, pwr)) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
|
@ -867,9 +821,9 @@ static int cc2520_tx(struct device *dev,
|
|||
|
||||
SYS_LOG_DBG("%p (%u)", frag, len);
|
||||
|
||||
if (!write_reg_excflag0(&cc2520->spi, EXCFLAG0_RESET_TX_FLAGS) ||
|
||||
!write_txfifo_length(&cc2520->spi, len) ||
|
||||
!write_txfifo_content(&cc2520->spi, frame, len)) {
|
||||
if (!write_reg_excflag0(cc2520, EXCFLAG0_RESET_TX_FLAGS) ||
|
||||
!write_txfifo_length(cc2520, len) ||
|
||||
!write_txfifo_content(cc2520, frame, len)) {
|
||||
SYS_LOG_ERR("Cannot feed in TX fifo");
|
||||
goto error;
|
||||
}
|
||||
|
@ -888,7 +842,7 @@ static int cc2520_tx(struct device *dev,
|
|||
atomic_set(&cc2520->tx, 1);
|
||||
k_sem_init(&cc2520->tx_sync, 0, UINT_MAX);
|
||||
|
||||
if (!instruct_stxoncca(&cc2520->spi)) {
|
||||
if (!instruct_stxoncca(cc2520)) {
|
||||
SYS_LOG_ERR("Cannot start transmission");
|
||||
goto error;
|
||||
}
|
||||
|
@ -916,7 +870,7 @@ error:
|
|||
_cc2520_print_errors(cc2520);
|
||||
|
||||
atomic_set(&cc2520->tx, 0);
|
||||
instruct_sflushtx(&cc2520->spi);
|
||||
instruct_sflushtx(cc2520);
|
||||
|
||||
return -EIO;
|
||||
}
|
||||
|
@ -927,8 +881,8 @@ static int cc2520_start(struct device *dev)
|
|||
|
||||
SYS_LOG_DBG("");
|
||||
|
||||
if (!instruct_sxoscon(&cc2520->spi) ||
|
||||
!instruct_srxon(&cc2520->spi) ||
|
||||
if (!instruct_sxoscon(cc2520) ||
|
||||
!instruct_srxon(cc2520) ||
|
||||
!verify_osc_stabilization(cc2520)) {
|
||||
SYS_LOG_ERR("Error starting CC2520");
|
||||
return -EIO;
|
||||
|
@ -953,8 +907,8 @@ static int cc2520_stop(struct device *dev)
|
|||
enable_fifop_interrupt(cc2520, false);
|
||||
enable_sfd_interrupt(cc2520, false);
|
||||
|
||||
if (!instruct_srfoff(&cc2520->spi) ||
|
||||
!instruct_sxoscoff(&cc2520->spi)) {
|
||||
if (!instruct_srfoff(cc2520) ||
|
||||
!instruct_sxoscoff(cc2520)) {
|
||||
SYS_LOG_ERR("Error stopping CC2520");
|
||||
return -EIO;
|
||||
}
|
||||
|
@ -988,17 +942,17 @@ static int power_on_and_setup(struct device *dev)
|
|||
}
|
||||
|
||||
/* Default settings to always write (see chapter 28 part 1) */
|
||||
if (!write_reg_txpower(&cc2520->spi, CC2520_TXPOWER_DEFAULT) ||
|
||||
!write_reg_ccactrl0(&cc2520->spi, CC2520_CCACTRL0_DEFAULT) ||
|
||||
!write_reg_mdmctrl0(&cc2520->spi, CC2520_MDMCTRL0_DEFAULT) ||
|
||||
!write_reg_mdmctrl1(&cc2520->spi, CC2520_MDMCTRL1_DEFAULT) ||
|
||||
!write_reg_rxctrl(&cc2520->spi, CC2520_RXCTRL_DEFAULT) ||
|
||||
!write_reg_fsctrl(&cc2520->spi, CC2520_FSCTRL_DEFAULT) ||
|
||||
!write_reg_fscal1(&cc2520->spi, CC2520_FSCAL1_DEFAULT) ||
|
||||
!write_reg_agcctrl1(&cc2520->spi, CC2520_AGCCTRL1_DEFAULT) ||
|
||||
!write_reg_adctest0(&cc2520->spi, CC2520_ADCTEST0_DEFAULT) ||
|
||||
!write_reg_adctest1(&cc2520->spi, CC2520_ADCTEST1_DEFAULT) ||
|
||||
!write_reg_adctest2(&cc2520->spi, CC2520_ADCTEST2_DEFAULT)) {
|
||||
if (!write_reg_txpower(cc2520, CC2520_TXPOWER_DEFAULT) ||
|
||||
!write_reg_ccactrl0(cc2520, CC2520_CCACTRL0_DEFAULT) ||
|
||||
!write_reg_mdmctrl0(cc2520, CC2520_MDMCTRL0_DEFAULT) ||
|
||||
!write_reg_mdmctrl1(cc2520, CC2520_MDMCTRL1_DEFAULT) ||
|
||||
!write_reg_rxctrl(cc2520, CC2520_RXCTRL_DEFAULT) ||
|
||||
!write_reg_fsctrl(cc2520, CC2520_FSCTRL_DEFAULT) ||
|
||||
!write_reg_fscal1(cc2520, CC2520_FSCAL1_DEFAULT) ||
|
||||
!write_reg_agcctrl1(cc2520, CC2520_AGCCTRL1_DEFAULT) ||
|
||||
!write_reg_adctest0(cc2520, CC2520_ADCTEST0_DEFAULT) ||
|
||||
!write_reg_adctest1(cc2520, CC2520_ADCTEST1_DEFAULT) ||
|
||||
!write_reg_adctest2(cc2520, CC2520_ADCTEST2_DEFAULT)) {
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
|
@ -1008,21 +962,21 @@ static int power_on_and_setup(struct device *dev)
|
|||
* FRMFILT0: Frame filtering (setting CC2520_FRAME_FILTERING)
|
||||
* FIFOPCTRL: Set TX threshold (setting CC2520_TX_THRESHOLD)
|
||||
*/
|
||||
if (!write_reg_extclock(&cc2520->spi, 0) ||
|
||||
!write_reg_frmctrl0(&cc2520->spi, CC2520_AUTOMATISM) ||
|
||||
!write_reg_frmctrl1(&cc2520->spi, FRMCTRL1_IGNORE_TX_UNDERF |
|
||||
if (!write_reg_extclock(cc2520, 0) ||
|
||||
!write_reg_frmctrl0(cc2520, CC2520_AUTOMATISM) ||
|
||||
!write_reg_frmctrl1(cc2520, FRMCTRL1_IGNORE_TX_UNDERF |
|
||||
FRMCTRL1_SET_RXENMASK_ON_TX) ||
|
||||
!write_reg_frmfilt0(&cc2520->spi, FRMFILT0_FRAME_FILTER_EN |
|
||||
!write_reg_frmfilt0(cc2520, FRMFILT0_FRAME_FILTER_EN |
|
||||
FRMFILT0_MAX_FRAME_VERSION(3)) ||
|
||||
!write_reg_frmfilt1(&cc2520->spi, FRMFILT1_ACCEPT_ALL) ||
|
||||
!write_reg_srcmatch(&cc2520->spi, SRCMATCH_DEFAULTS) ||
|
||||
!write_reg_fifopctrl(&cc2520->spi,
|
||||
!write_reg_frmfilt1(cc2520, FRMFILT1_ACCEPT_ALL) ||
|
||||
!write_reg_srcmatch(cc2520, SRCMATCH_DEFAULTS) ||
|
||||
!write_reg_fifopctrl(cc2520,
|
||||
FIFOPCTRL_FIFOP_THR(CC2520_TX_THRESHOLD))) {
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
/* Cleaning up TX fifo */
|
||||
instruct_sflushtx(&cc2520->spi);
|
||||
instruct_sflushtx(cc2520);
|
||||
|
||||
setup_gpio_callbacks(dev);
|
||||
|
||||
|
@ -1034,27 +988,36 @@ static int power_on_and_setup(struct device *dev)
|
|||
static inline int configure_spi(struct device *dev)
|
||||
{
|
||||
struct cc2520_context *cc2520 = dev->driver_data;
|
||||
struct spi_config spi_conf = {
|
||||
.config = SPI_WORD(8),
|
||||
.max_sys_freq = CONFIG_IEEE802154_CC2520_SPI_FREQ,
|
||||
};
|
||||
|
||||
cc2520->spi.dev = device_get_binding(
|
||||
cc2520->spi = device_get_binding(
|
||||
CONFIG_IEEE802154_CC2520_SPI_DRV_NAME);
|
||||
if (!cc2520->spi.dev) {
|
||||
if (!cc2520->spi) {
|
||||
SYS_LOG_ERR("Unable to get SPI device");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
cc2520->spi.slave = CONFIG_IEEE802154_CC2520_SPI_SLAVE;
|
||||
|
||||
if (spi_configure(cc2520->spi.dev, &spi_conf) != 0 ||
|
||||
spi_slave_select(cc2520->spi.dev,
|
||||
cc2520->spi.slave) != 0) {
|
||||
cc2520->spi.dev = NULL;
|
||||
return -EIO;
|
||||
#if defined(CONFIG_IEEE802154_CC2520_GPIO_SPI_CS)
|
||||
cs_ctrl.gpio_dev = device_get_binding(
|
||||
CONFIG_IEEE802154_CC2520_GPIO_SPI_CS_DRV_NAME);
|
||||
if (!cs_ctrl.gpio_dev) {
|
||||
SYS_LOG_ERR("Unable to get GPIO SPI CS device");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
cs_ctrl.gpio_pin = CONFIG_IEEE802154_CC2520_GPIO_SPI_CS_PIN;
|
||||
cs_ctrl.delay = 0;
|
||||
|
||||
cc2520->spi_cfg.cs = &cs_ctrl;
|
||||
|
||||
SYS_LOG_DBG("SPI GPIO CS configured on %s:%u",
|
||||
CONFIG_IEEE802154_CC2520_GPIO_SPI_CS_DRV_NAME,
|
||||
CONFIG_IEEE802154_CC2520_GPIO_SPI_CS_PIN);
|
||||
#endif /* CONFIG_IEEE802154_CC2520_GPIO_SPI_CS */
|
||||
|
||||
cc2520->spi_cfg.frequency = CONFIG_IEEE802154_CC2520_SPI_FREQ;
|
||||
cc2520->spi_cfg.operation = SPI_WORD_SET(8);
|
||||
cc2520->spi_cfg.slave = CONFIG_IEEE802154_CC2520_SPI_SLAVE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1150,44 +1113,50 @@ NET_STACK_INFO_ADDR(RX, cc2520,
|
|||
|
||||
#ifdef CONFIG_IEEE802154_CC2520_CRYPTO
|
||||
|
||||
static bool _cc2520_read_ram(struct cc2520_spi *spi, u16_t addr,
|
||||
u8_t *data_buf, u8_t len)
|
||||
static inline bool _cc2520_read_ram(struct cc2520_context *ctx, u16_t addr,
|
||||
u8_t *data_buf, u8_t len)
|
||||
{
|
||||
u8_t cmd_buf[128];
|
||||
|
||||
cmd_buf[0] = CC2520_INS_MEMRD | (addr >> 8);
|
||||
cmd_buf[1] = addr;
|
||||
|
||||
spi_slave_select(spi->dev, spi->slave);
|
||||
|
||||
if (spi_transceive(spi->dev, cmd_buf, len + 2,
|
||||
cmd_buf, len + 2) != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
memcpy(data_buf, &cmd_buf[2], len);
|
||||
|
||||
return true;
|
||||
return _cc2520_access(ctx, true, CC2520_INS_MEMRD,
|
||||
addr, data_buf, len);
|
||||
}
|
||||
|
||||
static inline bool instruct_ccm(struct cc2520_context *cc2520,
|
||||
u8_t key_addr,
|
||||
u8_t auth_crypt,
|
||||
u8_t nonce_addr,
|
||||
u16_t input_addr,
|
||||
u16_t output_addr,
|
||||
u8_t in_len,
|
||||
u8_t m)
|
||||
static inline bool _cc2520_write_ram(struct cc2520_context *ctx, u16_t addr,
|
||||
u8_t *data_buf, u8_t len)
|
||||
{
|
||||
return _cc2520_access(ctx, false, CC2520_INS_MEMWR,
|
||||
addr, data_buf, len);
|
||||
}
|
||||
|
||||
static inline bool instruct_uccm_ccm(struct cc2520_context *cc2520,
|
||||
bool uccm,
|
||||
u8_t key_addr,
|
||||
u8_t auth_crypt,
|
||||
u8_t nonce_addr,
|
||||
u16_t input_addr,
|
||||
u16_t output_addr,
|
||||
u8_t in_len,
|
||||
u8_t m)
|
||||
{
|
||||
u8_t cmd[9];
|
||||
const struct spi_buf buf[1] = {
|
||||
{
|
||||
.buf = cmd,
|
||||
.len = 9,
|
||||
},
|
||||
};
|
||||
const struct spi_buf_set tx = {
|
||||
.buffers = buf,
|
||||
.count = 1
|
||||
};
|
||||
|
||||
int ret;
|
||||
|
||||
SYS_LOG_DBG("CCM(P={01} K={%02x} C={%02x} N={%02x}"
|
||||
SYS_LOG_DBG("%sCCM(P={01} K={%02x} C={%02x} N={%02x}"
|
||||
" A={%03x} E={%03x} F{%02x} M={%02x})",
|
||||
key_addr, auth_crypt, nonce_addr,
|
||||
uccm ? "U" : "", key_addr, auth_crypt, nonce_addr,
|
||||
input_addr, output_addr, in_len, m);
|
||||
|
||||
cmd[0] = CC2520_INS_CCM | 1;
|
||||
cmd[0] = uccm ? CC2520_INS_UCCM | 1 : CC2520_INS_CCM | 1;
|
||||
cmd[1] = key_addr;
|
||||
cmd[2] = (auth_crypt & 0x7f);
|
||||
cmd[3] = nonce_addr;
|
||||
|
@ -1200,54 +1169,12 @@ static inline bool instruct_ccm(struct cc2520_context *cc2520,
|
|||
|
||||
k_sem_take(&cc2520->access_lock, K_FOREVER);
|
||||
|
||||
ret = spi_write(cc2520->spi.dev, cmd, 9);
|
||||
ret = spi_write(cc2520->spi, &cc2520->spi_cfg, &tx);
|
||||
|
||||
k_sem_give(&cc2520->access_lock);
|
||||
|
||||
if (ret) {
|
||||
SYS_LOG_ERR("CCM Failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline bool instruct_uccm(struct cc2520_context *cc2520,
|
||||
u8_t key_addr,
|
||||
u8_t auth_crypt,
|
||||
u8_t nonce_addr,
|
||||
u16_t input_addr,
|
||||
u16_t output_addr,
|
||||
u8_t in_len,
|
||||
u8_t m)
|
||||
{
|
||||
u8_t cmd[9];
|
||||
int ret;
|
||||
|
||||
SYS_LOG_DBG("UCCM(P={01} K={%02x} C={%02x} N={%02x}"
|
||||
" A={%03x} E={%03x} F{%02x} M={%02x})",
|
||||
key_addr, auth_crypt, nonce_addr,
|
||||
input_addr, output_addr, in_len, m);
|
||||
|
||||
cmd[0] = CC2520_INS_UCCM | 1;
|
||||
cmd[1] = key_addr;
|
||||
cmd[2] = (auth_crypt & 0x7f);
|
||||
cmd[3] = nonce_addr;
|
||||
cmd[4] = (u8_t)(((input_addr & 0x0f00) >> 4) |
|
||||
((output_addr & 0x0f00) >> 8));
|
||||
cmd[5] = (u8_t)(input_addr & 0x00ff);
|
||||
cmd[6] = (u8_t)(output_addr & 0x00ff);
|
||||
cmd[7] = (in_len & 0x7f);
|
||||
cmd[8] = (m & 0x03);
|
||||
|
||||
k_sem_take(&cc2520->access_lock, K_FOREVER);
|
||||
|
||||
ret = spi_write(cc2520->spi.dev, cmd, 9);
|
||||
|
||||
k_sem_give(&cc2520->access_lock);
|
||||
|
||||
if (ret) {
|
||||
SYS_LOG_ERR("UCCM Failed");
|
||||
SYS_LOG_ERR("%sCCM Failed", uccm ? "U" : "");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1334,7 +1261,7 @@ static int insert_crypto_parameters(struct cipher_ctx *ctx,
|
|||
}
|
||||
|
||||
/* Writing the frame in RAM */
|
||||
if (!_cc2520_write_ram(&cc2520->spi, CC2520_MEM_DATA, in_buf, in_len)) {
|
||||
if (!_cc2520_write_ram(cc2520, CC2520_MEM_DATA, in_buf, in_len)) {
|
||||
SYS_LOG_ERR("Cannot write the frame in RAM");
|
||||
return -EIO;
|
||||
}
|
||||
|
@ -1343,7 +1270,7 @@ static int insert_crypto_parameters(struct cipher_ctx *ctx,
|
|||
sys_memcpy_swap(data, ctx->key.bit_stream, ctx->keylen);
|
||||
|
||||
/* Writing the key in RAM */
|
||||
if (!_cc2520_write_ram(&cc2520->spi, CC2520_MEM_KEY, data, 16)) {
|
||||
if (!_cc2520_write_ram(cc2520, CC2520_MEM_KEY, data, 16)) {
|
||||
SYS_LOG_ERR("Cannot write the key in RAM");
|
||||
return -EIO;
|
||||
}
|
||||
|
@ -1351,7 +1278,7 @@ static int insert_crypto_parameters(struct cipher_ctx *ctx,
|
|||
generate_nonce(ccm_nonce, data, apkt, m);
|
||||
|
||||
/* Writing the nonce in RAM */
|
||||
if (!_cc2520_write_ram(&cc2520->spi, CC2520_MEM_NONCE, data, 16)) {
|
||||
if (!_cc2520_write_ram(cc2520, CC2520_MEM_NONCE, data, 16)) {
|
||||
SYS_LOG_ERR("Cannot write the nonce in RAM");
|
||||
return -EIO;
|
||||
}
|
||||
|
@ -1392,10 +1319,10 @@ static int _cc2520_crypto_ccm(struct cipher_ctx *ctx,
|
|||
return -ENOBUFS;
|
||||
}
|
||||
|
||||
if (!instruct_ccm(cc2520, CC2520_MEM_KEY >> 4, auth_crypt,
|
||||
CC2520_MEM_NONCE >> 4, CC2520_MEM_DATA,
|
||||
0x000, apkt->ad_len, m) ||
|
||||
!_cc2520_read_ram(&cc2520->spi, CC2520_MEM_DATA,
|
||||
if (!instruct_uccm_ccm(cc2520, false, CC2520_MEM_KEY >> 4, auth_crypt,
|
||||
CC2520_MEM_NONCE >> 4, CC2520_MEM_DATA,
|
||||
0x000, apkt->ad_len, m) ||
|
||||
!_cc2520_read_ram(cc2520, CC2520_MEM_DATA,
|
||||
apkt->pkt->out_buf, apkt->pkt->out_len)) {
|
||||
SYS_LOG_ERR("CCM or reading result from RAM failed");
|
||||
return -EIO;
|
||||
|
@ -1431,16 +1358,16 @@ static int _cc2520_crypto_uccm(struct cipher_ctx *ctx,
|
|||
|
||||
apkt->pkt->out_len = apkt->pkt->in_len + apkt->ad_len;
|
||||
|
||||
if (!instruct_uccm(cc2520, CC2520_MEM_KEY >> 4, auth_crypt,
|
||||
CC2520_MEM_NONCE >> 4, CC2520_MEM_DATA,
|
||||
0x000, apkt->ad_len, m) ||
|
||||
!_cc2520_read_ram(&cc2520->spi, CC2520_MEM_DATA,
|
||||
if (!instruct_uccm_ccm(cc2520, true, CC2520_MEM_KEY >> 4, auth_crypt,
|
||||
CC2520_MEM_NONCE >> 4, CC2520_MEM_DATA,
|
||||
0x000, apkt->ad_len, m) ||
|
||||
!_cc2520_read_ram(cc2520, CC2520_MEM_DATA,
|
||||
apkt->pkt->out_buf, apkt->pkt->out_len)) {
|
||||
SYS_LOG_ERR("UCCM or reading result from RAM failed");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if (m && (!(read_reg_dpustat(&cc2520->spi) & DPUSTAT_AUTHSTAT_H))) {
|
||||
if (m && (!(read_reg_dpustat(cc2520) & DPUSTAT_AUTHSTAT_H))) {
|
||||
SYS_LOG_ERR("Authentication of the frame failed");
|
||||
return -EBADMSG;
|
||||
}
|
||||
|
|
|
@ -18,23 +18,14 @@
|
|||
/* Runtime context structure
|
||||
***************************
|
||||
*/
|
||||
struct cc2520_spi {
|
||||
struct device *dev;
|
||||
u32_t slave;
|
||||
/**
|
||||
* cmd_buf will use at most 9 bytes:
|
||||
* dummy bytes + 8 ieee address bytes
|
||||
*/
|
||||
u8_t cmd_buf[12];
|
||||
};
|
||||
|
||||
struct cc2520_context {
|
||||
struct net_if *iface;
|
||||
/**************************/
|
||||
struct cc2520_gpio_configuration *gpios;
|
||||
struct gpio_callback sfd_cb;
|
||||
struct gpio_callback fifop_cb;
|
||||
struct cc2520_spi spi;
|
||||
struct device *spi;
|
||||
struct spi_config spi_cfg;
|
||||
u8_t mac_addr[8];
|
||||
/************TX************/
|
||||
struct k_sem tx_sync;
|
||||
|
@ -57,34 +48,50 @@ struct cc2520_context {
|
|||
***************************
|
||||
*/
|
||||
|
||||
u8_t _cc2520_read_reg(struct cc2520_spi *spi,
|
||||
bool freg, u8_t addr);
|
||||
bool _cc2520_write_reg(struct cc2520_spi *spi, bool freg,
|
||||
u8_t addr, u8_t value);
|
||||
bool _cc2520_access(struct cc2520_context *ctx, bool read, u8_t ins,
|
||||
u16_t addr, void *data, size_t length);
|
||||
|
||||
#define DEFINE_REG_READ(__reg_name, __reg_addr, __freg) \
|
||||
static inline u8_t read_reg_##__reg_name(struct cc2520_spi *spi) \
|
||||
#define DEFINE_SREG_READ(__reg_name, __reg_addr) \
|
||||
static inline u8_t read_reg_##__reg_name(struct cc2520_context *ctx) \
|
||||
{ \
|
||||
return _cc2520_read_reg(spi, __freg, __reg_addr); \
|
||||
u8_t val; \
|
||||
\
|
||||
if (_cc2520_access(ctx, true, CC2520_INS_MEMRD, \
|
||||
__reg_addr, &val, 1)) { \
|
||||
return val; \
|
||||
} \
|
||||
\
|
||||
return 0; \
|
||||
}
|
||||
|
||||
#define DEFINE_REG_WRITE(__reg_name, __reg_addr, __freg) \
|
||||
static inline bool write_reg_##__reg_name(struct cc2520_spi *spi, \
|
||||
#define DEFINE_SREG_WRITE(__reg_name, __reg_addr) \
|
||||
static inline bool write_reg_##__reg_name(struct cc2520_context *ctx, \
|
||||
u8_t val) \
|
||||
{ \
|
||||
return _cc2520_write_reg(spi, __freg, __reg_addr, val); \
|
||||
return _cc2520_access(ctx, false, CC2520_INS_MEMWR, \
|
||||
__reg_addr, &val, 1); \
|
||||
}
|
||||
|
||||
#define DEFINE_FREG_READ(__reg_name, __reg_addr) \
|
||||
DEFINE_REG_READ(__reg_name, __reg_addr, true)
|
||||
#define DEFINE_FREG_WRITE(__reg_name, __reg_addr) \
|
||||
DEFINE_REG_WRITE(__reg_name, __reg_addr, true)
|
||||
|
||||
#define DEFINE_SREG_READ(__reg_name, __reg_addr) \
|
||||
DEFINE_REG_READ(__reg_name, __reg_addr, false)
|
||||
#define DEFINE_SREG_WRITE(__reg_name, __reg_addr) \
|
||||
DEFINE_REG_WRITE(__reg_name, __reg_addr, false)
|
||||
#define DEFINE_FREG_READ(__reg_name, __reg_addr) \
|
||||
static inline u8_t read_reg_##__reg_name(struct cc2520_context *ctx) \
|
||||
{ \
|
||||
u8_t val; \
|
||||
\
|
||||
if (_cc2520_access(ctx, true, CC2520_INS_REGRD, \
|
||||
__reg_addr, &val, 1)) { \
|
||||
return val; \
|
||||
} \
|
||||
\
|
||||
return 0; \
|
||||
}
|
||||
|
||||
#define DEFINE_FREG_WRITE(__reg_name, __reg_addr) \
|
||||
static inline bool write_reg_##__reg_name(struct cc2520_context *ctx, \
|
||||
u8_t val) \
|
||||
{ \
|
||||
return _cc2520_access(ctx, false, CC2520_INS_REGWR, \
|
||||
__reg_addr, &val, 1); \
|
||||
}
|
||||
|
||||
DEFINE_FREG_READ(excflag0, CC2520_FREG_EXCFLAG0)
|
||||
DEFINE_FREG_READ(excflag1, CC2520_FREG_EXCFLAG1)
|
||||
|
@ -129,14 +136,12 @@ DEFINE_SREG_WRITE(extclock, CC2520_SREG_EXTCLOCK)
|
|||
************************
|
||||
*/
|
||||
|
||||
bool _cc2520_write_ram(struct cc2520_spi *spi, u16_t addr,
|
||||
u8_t *data_buf, u8_t len);
|
||||
|
||||
#define DEFINE_MEM_WRITE(__mem_name, __addr, __sz) \
|
||||
static inline bool write_mem_##__mem_name(struct cc2520_spi *spi, \
|
||||
static inline bool write_mem_##__mem_name(struct cc2520_context *ctx, \
|
||||
u8_t *buf) \
|
||||
{ \
|
||||
return _cc2520_write_ram(spi, __addr, buf, __sz); \
|
||||
return _cc2520_access(ctx, false, CC2520_INS_MEMWR, \
|
||||
__addr, buf, __sz); \
|
||||
}
|
||||
|
||||
DEFINE_MEM_WRITE(short_addr, CC2520_MEM_SHORT_ADDR, 2)
|
||||
|
@ -148,37 +153,30 @@ DEFINE_MEM_WRITE(ext_addr, CC2520_MEM_EXT_ADDR, 8)
|
|||
******************************
|
||||
*/
|
||||
|
||||
static inline bool _cc2520_command_strobe(struct cc2520_spi *spi,
|
||||
static inline bool _cc2520_command_strobe(struct cc2520_context *ctx,
|
||||
u8_t instruction)
|
||||
{
|
||||
spi_slave_select(spi->dev, spi->slave);
|
||||
|
||||
return (spi_write(spi->dev, &instruction, 1) == 0);
|
||||
return _cc2520_access(ctx, false, instruction, 0, NULL, 0);
|
||||
}
|
||||
|
||||
static inline bool _cc2520_command_strobe_snop(struct cc2520_spi *spi,
|
||||
static inline bool _cc2520_command_strobe_snop(struct cc2520_context *ctx,
|
||||
u8_t instruction)
|
||||
{
|
||||
u8_t ins[2] = {
|
||||
instruction,
|
||||
CC2520_INS_SNOP
|
||||
};
|
||||
u8_t snop[1] = { CC2520_INS_SNOP };
|
||||
|
||||
spi_slave_select(spi->dev, spi->slave);
|
||||
|
||||
return (spi_write(spi->dev, ins, 2) == 0);
|
||||
return _cc2520_access(ctx, false, instruction, 0, snop, 1);
|
||||
}
|
||||
|
||||
#define DEFINE_STROBE_INSTRUCTION(__ins_name, __ins) \
|
||||
static inline bool instruct_##__ins_name(struct cc2520_spi *spi) \
|
||||
static inline bool instruct_##__ins_name(struct cc2520_context *ctx) \
|
||||
{ \
|
||||
return _cc2520_command_strobe(spi, __ins); \
|
||||
return _cc2520_command_strobe(ctx, __ins); \
|
||||
}
|
||||
|
||||
#define DEFINE_STROBE_SNOP_INSTRUCTION(__ins_name, __ins) \
|
||||
static inline bool instruct_##__ins_name(struct cc2520_spi *spi) \
|
||||
static inline bool instruct_##__ins_name(struct cc2520_context *ctx) \
|
||||
{ \
|
||||
return _cc2520_command_strobe_snop(spi, __ins); \
|
||||
return _cc2520_command_strobe_snop(ctx, __ins); \
|
||||
}
|
||||
|
||||
DEFINE_STROBE_INSTRUCTION(srxon, CC2520_INS_SRXON)
|
||||
|
|
Loading…
Reference in a new issue