2015-03-24 23:24:21 +01:00
|
|
|
/*
|
2016-11-11 11:11:41 +01:00
|
|
|
* Copyright (C) 2015-2017 Freie Universität Berlin
|
2015-03-24 23:24:21 +01:00
|
|
|
*
|
|
|
|
* This file is subject to the terms and conditions of the GNU Lesser
|
|
|
|
* General Public License v2.1. See the file LICENSE in the top level
|
|
|
|
* directory for more details.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
2016-11-11 11:44:43 +01:00
|
|
|
* @ingroup drivers_nrf5x_nrfmin
|
2015-03-24 23:24:21 +01:00
|
|
|
* @{
|
|
|
|
*
|
|
|
|
* @file
|
2016-11-11 11:11:41 +01:00
|
|
|
* @brief Implementation of the nrfmin radio driver for nRF51 radios
|
2015-03-24 23:24:21 +01:00
|
|
|
*
|
|
|
|
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
|
|
|
|
*
|
|
|
|
* @}
|
|
|
|
*/
|
|
|
|
|
2016-11-11 11:11:41 +01:00
|
|
|
#include <string.h>
|
|
|
|
#include <errno.h>
|
|
|
|
|
2015-03-24 23:24:21 +01:00
|
|
|
#include "cpu.h"
|
|
|
|
#include "mutex.h"
|
2016-11-11 11:11:41 +01:00
|
|
|
#include "assert.h"
|
|
|
|
|
2015-03-24 23:24:21 +01:00
|
|
|
#include "periph_conf.h"
|
|
|
|
#include "periph/cpuid.h"
|
2016-11-11 11:11:41 +01:00
|
|
|
|
2015-03-24 23:24:21 +01:00
|
|
|
#include "nrfmin.h"
|
2017-02-15 13:07:34 +01:00
|
|
|
#include "net/netdev.h"
|
2015-03-24 23:24:21 +01:00
|
|
|
|
2018-01-18 12:59:57 +01:00
|
|
|
#ifdef MODULE_GNRC_SIXLOWPAN
|
|
|
|
#include "net/gnrc/nettype.h"
|
|
|
|
#endif
|
|
|
|
|
2016-11-11 11:11:41 +01:00
|
|
|
#define ENABLE_DEBUG (0)
|
2015-03-24 23:24:21 +01:00
|
|
|
#include "debug.h"
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Driver specific device configuration
|
|
|
|
* @{
|
|
|
|
*/
|
2016-11-11 11:11:41 +01:00
|
|
|
#define CONF_MODE RADIO_MODE_MODE_Nrf_1Mbit
|
2015-03-24 23:24:21 +01:00
|
|
|
#define CONF_LEN (8U)
|
|
|
|
#define CONF_S0 (0U)
|
|
|
|
#define CONF_S1 (0U)
|
|
|
|
#define CONF_STATLEN (0U)
|
|
|
|
#define CONF_BASE_ADDR_LEN (4U)
|
|
|
|
#define CONF_ENDIAN RADIO_PCNF1_ENDIAN_Big
|
|
|
|
#define CONF_WHITENING RADIO_PCNF1_WHITEEN_Disabled
|
|
|
|
#define CONF_CRC_LEN (2U)
|
|
|
|
#define CONF_CRC_POLY (0x11021)
|
|
|
|
#define CONF_CRC_INIT (0xf0f0f0)
|
|
|
|
/** @} */
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Driver specific address configuration
|
|
|
|
* @{
|
|
|
|
*/
|
2016-11-11 11:11:41 +01:00
|
|
|
#define CONF_ADDR_PREFIX0 (0xe7e7e7e7)
|
|
|
|
#define CONF_ADDR_BASE (0xe7e70000)
|
|
|
|
#define CONF_ADDR_BCAST (CONF_ADDR_BASE | NRFMIN_ADDR_BCAST)
|
2015-03-24 23:24:21 +01:00
|
|
|
/** @} */
|
|
|
|
|
2016-11-11 11:11:41 +01:00
|
|
|
/**
|
|
|
|
* @brief We define a pseudo NID for compliance to 6LoWPAN
|
|
|
|
*/
|
|
|
|
#define CONF_PSEUDO_NID (0xaffe)
|
|
|
|
|
2015-03-24 23:24:21 +01:00
|
|
|
/**
|
|
|
|
* @brief Driver specific (interrupt) events (not all of them used currently)
|
|
|
|
* @{
|
|
|
|
*/
|
|
|
|
#define ISR_EVENT_RX_START (0x0001)
|
|
|
|
#define ISR_EVENT_RX_DONE (0x0002)
|
|
|
|
#define ISR_EVENT_TX_START (0x0004)
|
|
|
|
#define ISR_EVENT_TX_DONE (0x0008)
|
|
|
|
#define ISR_EVENT_WRONG_CHKSUM (0x0010)
|
|
|
|
/** @} */
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Possible internal device states
|
|
|
|
*/
|
|
|
|
typedef enum {
|
2016-11-11 11:11:41 +01:00
|
|
|
STATE_OFF, /**< device is powered off */
|
|
|
|
STATE_IDLE, /**< device is in idle mode */
|
|
|
|
STATE_RX, /**< device is in receive mode */
|
|
|
|
STATE_TX, /**< device is transmitting data */
|
2015-03-24 23:24:21 +01:00
|
|
|
} state_t;
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2016-11-11 11:11:41 +01:00
|
|
|
* @brief Since there can only be 1 nrfmin device, we allocate it right here
|
2015-03-24 23:24:21 +01:00
|
|
|
*/
|
2017-02-15 13:07:34 +01:00
|
|
|
netdev_t nrfmin_dev;
|
2015-03-24 23:24:21 +01:00
|
|
|
|
|
|
|
/**
|
2016-11-11 11:11:41 +01:00
|
|
|
* @brief For faster lookup we remember our own 16-bit address
|
2015-03-24 23:24:21 +01:00
|
|
|
*/
|
2016-11-11 11:11:41 +01:00
|
|
|
static uint16_t my_addr;
|
2015-03-24 23:24:21 +01:00
|
|
|
|
|
|
|
/**
|
2016-11-11 11:11:41 +01:00
|
|
|
* @brief We need to keep track of the radio state in SW (-> PAN ID 20)
|
|
|
|
*
|
|
|
|
* See nRF51822 PAN ID 20: RADIO State Register is not functional.
|
2015-03-24 23:24:21 +01:00
|
|
|
*/
|
2016-11-11 11:11:41 +01:00
|
|
|
static volatile state_t state = STATE_OFF;
|
2015-03-24 23:24:21 +01:00
|
|
|
|
|
|
|
/**
|
2016-11-11 11:11:41 +01:00
|
|
|
* @brief We also remember the 'long-term' state, so we can resume after TX
|
2015-03-24 23:24:21 +01:00
|
|
|
*/
|
2016-11-11 11:11:41 +01:00
|
|
|
static volatile state_t target_state = STATE_OFF;
|
2015-03-24 23:24:21 +01:00
|
|
|
|
|
|
|
/**
|
2016-11-11 11:11:41 +01:00
|
|
|
* @brief When sending out data, the data needs to be in one continuous memory
|
|
|
|
* region. So we need to buffer outgoing data on the driver level.
|
2015-03-24 23:24:21 +01:00
|
|
|
*/
|
2016-11-11 11:11:41 +01:00
|
|
|
static nrfmin_pkt_t tx_buf;
|
2015-03-24 23:24:21 +01:00
|
|
|
|
|
|
|
/**
|
2016-11-11 11:11:41 +01:00
|
|
|
* @brief As the device is memory mapped, we need some space to save incoming
|
|
|
|
* data to.
|
|
|
|
*
|
|
|
|
* @todo Improve the RX buffering to at least use double buffering
|
2015-03-24 23:24:21 +01:00
|
|
|
*/
|
2016-11-11 11:11:41 +01:00
|
|
|
static nrfmin_pkt_t rx_buf;
|
2015-03-24 23:24:21 +01:00
|
|
|
|
|
|
|
/**
|
2016-11-11 11:11:41 +01:00
|
|
|
* @brief While we listen for incoming data, we lock the RX buffer
|
2015-03-24 23:24:21 +01:00
|
|
|
*/
|
2016-11-11 11:11:41 +01:00
|
|
|
static volatile uint8_t rx_lock = 0;
|
2015-03-24 23:24:21 +01:00
|
|
|
|
2016-11-11 11:11:41 +01:00
|
|
|
/**
|
|
|
|
* @brief Set radio into idle (DISABLED) state
|
2015-03-24 23:24:21 +01:00
|
|
|
*/
|
2016-11-11 11:11:41 +01:00
|
|
|
static void go_idle(void)
|
2015-03-24 23:24:21 +01:00
|
|
|
{
|
2016-11-11 11:11:41 +01:00
|
|
|
/* set device into basic disabled state */
|
2015-03-24 23:24:21 +01:00
|
|
|
NRF_RADIO->EVENTS_DISABLED = 0;
|
|
|
|
NRF_RADIO->TASKS_DISABLE = 1;
|
2016-01-27 08:04:02 +01:00
|
|
|
while (NRF_RADIO->EVENTS_DISABLED == 0) {}
|
2016-11-11 11:11:41 +01:00
|
|
|
/* also release any existing lock on the RX buffer */
|
|
|
|
rx_lock = 0;
|
|
|
|
state = STATE_IDLE;
|
2015-03-24 23:24:21 +01:00
|
|
|
}
|
|
|
|
|
2016-11-11 11:11:41 +01:00
|
|
|
/**
|
|
|
|
* @brief Set radio into the target state as defined by `target_state`
|
|
|
|
*
|
|
|
|
* Trick here is, that the driver can go back to it's previous state after a
|
|
|
|
* send operation, so it can differentiate if the driver was in DISABLED or in
|
|
|
|
* RX mode before the send process had started.
|
2015-03-24 23:24:21 +01:00
|
|
|
*/
|
2016-11-11 11:11:41 +01:00
|
|
|
static void goto_target_state(void)
|
2015-03-24 23:24:21 +01:00
|
|
|
{
|
2016-11-11 11:11:41 +01:00
|
|
|
go_idle();
|
2015-03-24 23:24:21 +01:00
|
|
|
|
2016-11-11 11:11:41 +01:00
|
|
|
if ((target_state == STATE_RX) && (rx_buf.pkt.hdr.len == 0)) {
|
|
|
|
/* set receive buffer and our own address */
|
|
|
|
rx_lock = 1;
|
|
|
|
NRF_RADIO->PACKETPTR = (uint32_t)(&rx_buf);
|
|
|
|
NRF_RADIO->BASE0 = (CONF_ADDR_BASE | my_addr);
|
|
|
|
/* goto RX mode */
|
|
|
|
NRF_RADIO->TASKS_RXEN = 1;
|
|
|
|
state = STATE_RX;
|
2015-03-24 23:24:21 +01:00
|
|
|
}
|
2016-11-11 11:11:41 +01:00
|
|
|
|
|
|
|
if (target_state == STATE_OFF) {
|
|
|
|
NRF_RADIO->POWER = 0;
|
|
|
|
state = STATE_OFF;
|
2015-03-24 23:24:21 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-11-11 11:11:41 +01:00
|
|
|
void nrfmin_setup(void)
|
2015-03-24 23:24:21 +01:00
|
|
|
{
|
2016-11-11 11:11:41 +01:00
|
|
|
nrfmin_dev.driver = &nrfmin_netdev;
|
|
|
|
nrfmin_dev.event_callback = NULL;
|
|
|
|
nrfmin_dev.context = NULL;
|
2015-03-24 23:24:21 +01:00
|
|
|
}
|
|
|
|
|
2016-11-11 11:11:41 +01:00
|
|
|
uint16_t nrfmin_get_addr(void)
|
2015-03-24 23:24:21 +01:00
|
|
|
{
|
2016-11-11 11:11:41 +01:00
|
|
|
return my_addr;
|
2015-03-24 23:24:21 +01:00
|
|
|
}
|
|
|
|
|
2016-11-11 11:11:41 +01:00
|
|
|
void nrfmin_get_iid(uint16_t *iid)
|
2015-03-24 23:24:21 +01:00
|
|
|
{
|
2016-11-11 11:11:41 +01:00
|
|
|
iid[0] = 0;
|
|
|
|
iid[1] = 0xff00;
|
|
|
|
iid[2] = 0x00fe;
|
|
|
|
iid[3] = my_addr;
|
2015-03-24 23:24:21 +01:00
|
|
|
}
|
|
|
|
|
2016-11-11 11:11:41 +01:00
|
|
|
uint16_t nrfmin_get_channel(void)
|
2015-03-24 23:24:21 +01:00
|
|
|
{
|
2016-11-11 11:11:41 +01:00
|
|
|
return (uint16_t)(NRF_RADIO->FREQUENCY >> 2);
|
2015-03-24 23:24:21 +01:00
|
|
|
}
|
|
|
|
|
2016-11-11 11:11:41 +01:00
|
|
|
netopt_state_t nrfmin_get_state(void)
|
2015-03-24 23:24:21 +01:00
|
|
|
{
|
2016-11-11 11:11:41 +01:00
|
|
|
switch (state) {
|
|
|
|
case STATE_OFF: return NETOPT_STATE_OFF;
|
|
|
|
case STATE_IDLE: return NETOPT_STATE_SLEEP;
|
|
|
|
case STATE_RX: return NETOPT_STATE_IDLE;
|
|
|
|
case STATE_TX: return NETOPT_STATE_TX;
|
|
|
|
default: return NETOPT_STATE_RESET; /* should never show */
|
2015-03-24 23:24:21 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-11-11 11:11:41 +01:00
|
|
|
int16_t nrfmin_get_txpower(void)
|
2015-03-24 23:24:21 +01:00
|
|
|
{
|
2016-11-11 11:11:41 +01:00
|
|
|
int8_t p = (int8_t)NRF_RADIO->TXPOWER;
|
|
|
|
if (p < 0) {
|
|
|
|
return (int16_t)(0xff00 | p);
|
2015-03-24 23:24:21 +01:00
|
|
|
}
|
2016-11-11 11:11:41 +01:00
|
|
|
return (int16_t)p;
|
2015-03-24 23:24:21 +01:00
|
|
|
}
|
|
|
|
|
2016-11-11 11:11:41 +01:00
|
|
|
void nrfmin_set_addr(uint16_t addr)
|
2015-03-24 23:24:21 +01:00
|
|
|
{
|
2016-11-11 11:11:41 +01:00
|
|
|
my_addr = addr;
|
|
|
|
goto_target_state();
|
2015-03-24 23:24:21 +01:00
|
|
|
}
|
|
|
|
|
2016-11-11 11:11:41 +01:00
|
|
|
int nrfmin_set_channel(uint16_t chan)
|
2015-03-24 23:24:21 +01:00
|
|
|
{
|
2016-11-11 11:11:41 +01:00
|
|
|
if (chan > NRFMIN_CHAN_MAX) {
|
|
|
|
return -EOVERFLOW;
|
2015-03-24 23:24:21 +01:00
|
|
|
}
|
|
|
|
|
2016-11-11 11:11:41 +01:00
|
|
|
NRF_RADIO->FREQUENCY = (chan << 2);
|
|
|
|
goto_target_state();
|
|
|
|
|
|
|
|
return sizeof(uint16_t);
|
|
|
|
}
|
|
|
|
|
|
|
|
void nrfmin_set_txpower(int16_t power)
|
|
|
|
{
|
2015-03-24 23:24:21 +01:00
|
|
|
if (power > 2) {
|
2016-11-11 11:11:41 +01:00
|
|
|
NRF_RADIO->TXPOWER = RADIO_TXPOWER_TXPOWER_Pos4dBm;
|
2015-03-24 23:24:21 +01:00
|
|
|
}
|
|
|
|
else if (power > -2) {
|
2016-11-11 11:11:41 +01:00
|
|
|
NRF_RADIO->TXPOWER = RADIO_TXPOWER_TXPOWER_0dBm;
|
2015-03-24 23:24:21 +01:00
|
|
|
}
|
|
|
|
else if (power > -6) {
|
2016-11-11 11:11:41 +01:00
|
|
|
NRF_RADIO->TXPOWER = RADIO_TXPOWER_TXPOWER_Neg4dBm;
|
2015-03-24 23:24:21 +01:00
|
|
|
}
|
|
|
|
else if (power > -10) {
|
2016-11-11 11:11:41 +01:00
|
|
|
NRF_RADIO->TXPOWER = RADIO_TXPOWER_TXPOWER_Neg8dBm;
|
2015-03-24 23:24:21 +01:00
|
|
|
}
|
|
|
|
else if (power > -14) {
|
2016-11-11 11:11:41 +01:00
|
|
|
NRF_RADIO->TXPOWER = RADIO_TXPOWER_TXPOWER_Neg12dBm;
|
2015-03-24 23:24:21 +01:00
|
|
|
}
|
|
|
|
else if (power > -18) {
|
2016-11-11 11:11:41 +01:00
|
|
|
NRF_RADIO->TXPOWER = RADIO_TXPOWER_TXPOWER_Neg16dBm;
|
|
|
|
}
|
|
|
|
else if (power > -25) {
|
|
|
|
NRF_RADIO->TXPOWER = RADIO_TXPOWER_TXPOWER_Neg20dBm;
|
2015-03-24 23:24:21 +01:00
|
|
|
}
|
|
|
|
else {
|
2016-11-11 11:11:41 +01:00
|
|
|
NRF_RADIO->TXPOWER = RADIO_TXPOWER_TXPOWER_Neg30dBm;
|
2015-03-24 23:24:21 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-11-11 11:11:41 +01:00
|
|
|
int nrfmin_set_state(netopt_state_t val)
|
|
|
|
{
|
|
|
|
/* make sure radio is turned on and no transmission is in progress */
|
|
|
|
NRF_RADIO->POWER = 1;
|
|
|
|
|
|
|
|
switch (val) {
|
|
|
|
case NETOPT_STATE_OFF:
|
|
|
|
target_state = STATE_OFF;
|
|
|
|
break;
|
|
|
|
case NETOPT_STATE_SLEEP:
|
|
|
|
target_state = STATE_IDLE;
|
|
|
|
break;
|
|
|
|
case NETOPT_STATE_IDLE:
|
|
|
|
target_state = STATE_RX;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return -ENOTSUP;
|
|
|
|
}
|
|
|
|
|
|
|
|
goto_target_state();
|
|
|
|
|
|
|
|
return sizeof(netopt_state_t);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Radio interrupt routine
|
2015-03-24 23:24:21 +01:00
|
|
|
*/
|
|
|
|
void isr_radio(void)
|
|
|
|
{
|
|
|
|
if (NRF_RADIO->EVENTS_END == 1) {
|
|
|
|
NRF_RADIO->EVENTS_END = 0;
|
|
|
|
/* did we just send or receive something? */
|
2016-11-11 11:11:41 +01:00
|
|
|
if (state == STATE_RX) {
|
2015-03-24 23:24:21 +01:00
|
|
|
/* drop packet on invalid CRC */
|
2016-11-11 11:11:41 +01:00
|
|
|
if ((NRF_RADIO->CRCSTATUS != 1) || !(nrfmin_dev.event_callback)) {
|
|
|
|
rx_buf.pkt.hdr.len = 0;
|
|
|
|
NRF_RADIO->TASKS_START = 1;
|
2015-03-24 23:24:21 +01:00
|
|
|
}
|
2019-04-15 13:15:26 +02:00
|
|
|
else {
|
|
|
|
rx_lock = 0;
|
|
|
|
nrfmin_dev.event_callback(&nrfmin_dev, NETDEV_EVENT_ISR);
|
|
|
|
}
|
2015-03-24 23:24:21 +01:00
|
|
|
}
|
2016-11-11 11:11:41 +01:00
|
|
|
else if (state == STATE_TX) {
|
|
|
|
goto_target_state();
|
2015-03-24 23:24:21 +01:00
|
|
|
}
|
|
|
|
}
|
2016-11-11 11:11:41 +01:00
|
|
|
|
2016-11-30 18:26:05 +01:00
|
|
|
cortexm_isr_end();
|
2015-03-24 23:24:21 +01:00
|
|
|
}
|
|
|
|
|
2018-01-12 00:19:03 +01:00
|
|
|
static int nrfmin_send(netdev_t *dev, const iolist_t *iolist)
|
2015-03-24 23:24:21 +01:00
|
|
|
{
|
2016-11-11 11:11:41 +01:00
|
|
|
(void)dev;
|
|
|
|
|
2018-01-12 00:19:03 +01:00
|
|
|
assert((iolist) && (state != STATE_OFF));
|
2016-11-11 11:11:41 +01:00
|
|
|
|
|
|
|
/* wait for any ongoing transmission to finish and go into idle state */
|
|
|
|
while (state == STATE_TX) {}
|
|
|
|
go_idle();
|
|
|
|
|
|
|
|
/* copy packet data into the transmit buffer */
|
|
|
|
int pos = 0;
|
2018-01-12 00:19:03 +01:00
|
|
|
for (const iolist_t *iol = iolist; iol; iol = iol->iol_next) {
|
|
|
|
if ((pos + iol->iol_len) > NRFMIN_PKT_MAX) {
|
2016-11-11 11:11:41 +01:00
|
|
|
DEBUG("[nrfmin] send: unable to do so, packet is too large!\n");
|
|
|
|
return -EOVERFLOW;
|
|
|
|
}
|
2018-01-12 00:19:03 +01:00
|
|
|
memcpy(&tx_buf.raw[pos], iol->iol_base, iol->iol_len);
|
|
|
|
pos += iol->iol_len;
|
2015-03-24 23:24:21 +01:00
|
|
|
}
|
|
|
|
|
2016-11-11 11:11:41 +01:00
|
|
|
/* set output buffer and destination address */
|
2018-01-12 00:19:03 +01:00
|
|
|
nrfmin_hdr_t *hdr = (nrfmin_hdr_t *)iolist->iol_base;
|
2016-11-11 11:11:41 +01:00
|
|
|
NRF_RADIO->PACKETPTR = (uint32_t)(&tx_buf);
|
|
|
|
NRF_RADIO->BASE0 = (CONF_ADDR_BASE | hdr->dst_addr);
|
|
|
|
|
|
|
|
/* trigger the actual transmission */
|
|
|
|
DEBUG("[nrfmin] send: putting %i byte into the ether\n", (int)hdr->len);
|
|
|
|
state = STATE_TX;
|
|
|
|
NRF_RADIO->TASKS_TXEN = 1;
|
|
|
|
|
2018-01-12 00:19:03 +01:00
|
|
|
return (int)pos;
|
2016-11-11 11:11:41 +01:00
|
|
|
}
|
|
|
|
|
2017-02-15 13:07:34 +01:00
|
|
|
static int nrfmin_recv(netdev_t *dev, void *buf, size_t len, void *info)
|
2016-11-11 11:11:41 +01:00
|
|
|
{
|
|
|
|
(void)dev;
|
|
|
|
(void)info;
|
|
|
|
|
|
|
|
assert(state != STATE_OFF);
|
|
|
|
|
make: fix sign-compare errors
cpu, nrf5x_common: fix sign-compare in periph/flashpage
drivers, periph_common: fix sign-compare in flashpage
cpu, sam0_common: fix sign-compare error in periph/gpio
cpu, cc2538: fix sign-compare in periph/timer
cpu, sam3: fix sign-compare in periph/gpio
cpu, stm32_common: fix sign-compare in periph/pwm
cpu, stm32_common: fix sign-compare in periph/timer
cpu, stm32_common: fix sign-compare in periph/flashpage
cpu, nrf5x_common: fix sign-compare in radio/nrfmin
cpu, samd21: fix sign-compare in periph/pwm
cpu, ezr32wg: fix sign-compare in periph/gpio
cpu, ezr32wg: fix sign-compare in periph/timer
drivers, ethos: fix sign-compare
sys, net: fix sign-compare
cpu, atmega_common: fix sign-compare error
cpu, msp430fxyz: fix sign-compare in periph/gpio
boards, msb-430-common: fix sign-compare in board_init
driver, cc2420: fix sign-compared
sys/net: fix sign-compare in gnrc_tftp
driver, pcd8544: fix sign-compare
driver, pn532: fix sign-compare
driver, sdcard_spi: fix sign-compare
tests: fix sign_compare
sys/net, lwmac: fix sign_compare
pkg, lwip: fix sign-compare
boards, waspmote: make CORECLOCK unsigned long to fix sign_compare error
tests, sock_ip: fix sign compare
tests, msg_avail: fix sign compare
tests, sock_udp: fix sign compare
boards: fix sign-compare for calliope and microbit matrix
2017-10-31 11:57:40 +01:00
|
|
|
unsigned pktlen = rx_buf.pkt.hdr.len;
|
2015-03-24 23:24:21 +01:00
|
|
|
|
2016-11-11 11:11:41 +01:00
|
|
|
/* check if packet data is readable */
|
|
|
|
if (rx_lock || (pktlen == 0)) {
|
|
|
|
DEBUG("[nrfmin] recv: no packet data available\n");
|
|
|
|
return 0;
|
2015-03-24 23:24:21 +01:00
|
|
|
}
|
2016-11-11 11:11:41 +01:00
|
|
|
|
|
|
|
if (buf == NULL) {
|
|
|
|
if (len > 0) {
|
|
|
|
/* drop packet */
|
|
|
|
DEBUG("[nrfmin] recv: dropping packet of length %i\n", pktlen);
|
|
|
|
rx_buf.pkt.hdr.len = 0;
|
|
|
|
goto_target_state();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
DEBUG("[nrfmin] recv: reading packet of length %i\n", pktlen);
|
|
|
|
|
|
|
|
pktlen = (len < pktlen) ? len : pktlen;
|
|
|
|
memcpy(buf, rx_buf.raw, pktlen);
|
|
|
|
rx_buf.pkt.hdr.len = 0;
|
|
|
|
goto_target_state();
|
2015-03-24 23:24:21 +01:00
|
|
|
}
|
|
|
|
|
2016-11-11 11:11:41 +01:00
|
|
|
return pktlen;
|
2015-03-24 23:24:21 +01:00
|
|
|
}
|
|
|
|
|
2017-02-15 13:07:34 +01:00
|
|
|
static int nrfmin_init(netdev_t *dev)
|
2015-03-24 23:24:21 +01:00
|
|
|
{
|
build: fix unused parameter errors
cpu, sam0_common: fix unused parameter in periph/spi
cpu, kinetis_common: fix unused parameter in periph/spi
cpu, cc2538: fix unused param in periph/i2c
cpu, cc2538: fix unused param in periph/spi
cpu, sam3: fix unused param in periph/spi
cpu, stm32_common: fix unused param in periph/pm
cpu, stm32f3: fix unused params in periph/i2c
cpu, nrf5x_common: fix unused param in periph/gpio
cpu, nrf5x_common: fix unused param in periph/spi
cpu, lpc2387: fix unused params in periph/spi
cpu, cc2538: fix unused params in radio/netdev
cpu, cc2650: fix unused params in periph/uart
cpu, lm4f120: fix unused param in periph/spi
cpu, lm4f120: fix unused params in periph/timer
cpu, lm4f120: fix unused params in periph/uart
cpu, stm32_common: fix unused params in periph/dac
cpu, stm32l0: fix unused params in periph/i2c
cpu, msp430fxyz: fix unused params in periph/uart
cpu, mips: fix unused params
cpu, cc430: fix unused-params in periph/timer
cpu, msp430fxyz: fix unused params in periph/spi
drivers, cc2420: fix unused param
cpu, mips32r2_common: fix unused params in periph/timer
cpu, cc2538: fix unused-param in periph/i2c
cpu, mips32r2_common: fix unused-param in periph/timer
cpu, msp430fxyz: fix unused params in periph/timer
cpu, atmega_common: fix unused params in periph/spi
driver, nrfmin: fix unused params
cpu, cc2538_rf: fix unused params
driver, netdev_ieee802514: fix unused param
cpu, mip_pic32m: fix unused params
cpu, lpc2387: fix unused params in periph/pwm
tests/driver_sdcard_spi: fix unused params
cpu, sam3: fix unused param in periph/pwm
tests/driver_dynamixel: fix unused params, and style issues
cpu, cc430: fix unused param in periph/rtc
cpu, atmega_common: fix unused params in periph/i2c
2017-10-31 12:09:11 +01:00
|
|
|
(void)dev;
|
2016-02-07 20:35:27 +01:00
|
|
|
uint8_t cpuid[CPUID_LEN];
|
2015-03-24 23:24:21 +01:00
|
|
|
|
|
|
|
/* check given device descriptor */
|
2016-11-11 11:11:41 +01:00
|
|
|
assert(dev);
|
|
|
|
|
|
|
|
/* initialize our own address from the CPU ID */
|
|
|
|
my_addr = 0;
|
|
|
|
cpuid_get(cpuid);
|
make: fix sign-compare errors
cpu, nrf5x_common: fix sign-compare in periph/flashpage
drivers, periph_common: fix sign-compare in flashpage
cpu, sam0_common: fix sign-compare error in periph/gpio
cpu, cc2538: fix sign-compare in periph/timer
cpu, sam3: fix sign-compare in periph/gpio
cpu, stm32_common: fix sign-compare in periph/pwm
cpu, stm32_common: fix sign-compare in periph/timer
cpu, stm32_common: fix sign-compare in periph/flashpage
cpu, nrf5x_common: fix sign-compare in radio/nrfmin
cpu, samd21: fix sign-compare in periph/pwm
cpu, ezr32wg: fix sign-compare in periph/gpio
cpu, ezr32wg: fix sign-compare in periph/timer
drivers, ethos: fix sign-compare
sys, net: fix sign-compare
cpu, atmega_common: fix sign-compare error
cpu, msp430fxyz: fix sign-compare in periph/gpio
boards, msb-430-common: fix sign-compare in board_init
driver, cc2420: fix sign-compared
sys/net: fix sign-compare in gnrc_tftp
driver, pcd8544: fix sign-compare
driver, pn532: fix sign-compare
driver, sdcard_spi: fix sign-compare
tests: fix sign_compare
sys/net, lwmac: fix sign_compare
pkg, lwip: fix sign-compare
boards, waspmote: make CORECLOCK unsigned long to fix sign_compare error
tests, sock_ip: fix sign compare
tests, msg_avail: fix sign compare
tests, sock_udp: fix sign compare
boards: fix sign-compare for calliope and microbit matrix
2017-10-31 11:57:40 +01:00
|
|
|
for (unsigned i = 0; i < CPUID_LEN; i++) {
|
2016-11-11 11:11:41 +01:00
|
|
|
my_addr ^= cpuid[i] << (8 * (i & 0x01));
|
2015-03-24 23:24:21 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* power on the NRFs radio */
|
|
|
|
NRF_RADIO->POWER = 1;
|
|
|
|
/* load driver specific configuration */
|
|
|
|
NRF_RADIO->MODE = CONF_MODE;
|
|
|
|
/* configure variable parameters to default values */
|
2016-11-11 11:11:41 +01:00
|
|
|
NRF_RADIO->TXPOWER = NRFMIN_TXPOWER_DEFAULT;
|
|
|
|
NRF_RADIO->FREQUENCY = NRFMIN_CHAN_DEFAULT;
|
2015-03-24 23:24:21 +01:00
|
|
|
/* pre-configure radio addresses */
|
|
|
|
NRF_RADIO->PREFIX0 = CONF_ADDR_PREFIX0;
|
2016-11-11 11:11:41 +01:00
|
|
|
NRF_RADIO->BASE0 = (CONF_ADDR_BASE | my_addr);
|
|
|
|
NRF_RADIO->BASE1 = CONF_ADDR_BCAST;
|
|
|
|
/* always send from logical address 0 */
|
|
|
|
NRF_RADIO->TXADDRESS = 0x00UL;
|
|
|
|
/* and listen to logical addresses 0 and 1 */
|
|
|
|
NRF_RADIO->RXADDRESSES = 0x03UL;
|
2015-03-24 23:24:21 +01:00
|
|
|
/* configure data fields and packet length whitening and endianess */
|
2016-11-11 11:11:41 +01:00
|
|
|
NRF_RADIO->PCNF0 = ((CONF_S1 << RADIO_PCNF0_S1LEN_Pos) |
|
|
|
|
(CONF_S0 << RADIO_PCNF0_S0LEN_Pos) |
|
|
|
|
(CONF_LEN << RADIO_PCNF0_LFLEN_Pos));
|
|
|
|
NRF_RADIO->PCNF1 = ((CONF_WHITENING << RADIO_PCNF1_WHITEEN_Pos) |
|
|
|
|
(CONF_ENDIAN << RADIO_PCNF1_ENDIAN_Pos) |
|
|
|
|
(CONF_BASE_ADDR_LEN << RADIO_PCNF1_BALEN_Pos) |
|
|
|
|
(CONF_STATLEN << RADIO_PCNF1_STATLEN_Pos) |
|
|
|
|
(NRFMIN_PKT_MAX << RADIO_PCNF1_MAXLEN_Pos));
|
2016-11-11 11:44:43 +01:00
|
|
|
/* configure the CRC unit, we skip the address field as this seems to lead
|
|
|
|
* to wrong checksum calculation on nRF52 devices in some cases */
|
|
|
|
NRF_RADIO->CRCCNF = CONF_CRC_LEN | RADIO_CRCCNF_SKIPADDR_Msk;
|
2015-03-24 23:24:21 +01:00
|
|
|
NRF_RADIO->CRCPOLY = CONF_CRC_POLY;
|
|
|
|
NRF_RADIO->CRCINIT = CONF_CRC_INIT;
|
|
|
|
/* set shortcuts for more efficient transfer */
|
2016-11-11 11:11:41 +01:00
|
|
|
NRF_RADIO->SHORTS = RADIO_SHORTS_READY_START_Msk;
|
2015-03-24 23:24:21 +01:00
|
|
|
/* enable interrupts */
|
|
|
|
NVIC_EnableIRQ(RADIO_IRQn);
|
|
|
|
/* enable END interrupt */
|
|
|
|
NRF_RADIO->EVENTS_END = 0;
|
2016-11-11 11:11:41 +01:00
|
|
|
NRF_RADIO->INTENSET = RADIO_INTENSET_END_Msk;
|
2015-03-24 23:24:21 +01:00
|
|
|
/* put device in receive mode */
|
2016-11-11 11:11:41 +01:00
|
|
|
target_state = STATE_RX;
|
|
|
|
goto_target_state();
|
2015-03-24 23:24:21 +01:00
|
|
|
|
2016-11-11 11:11:41 +01:00
|
|
|
DEBUG("[nrfmin] initialization successful\n");
|
2015-03-24 23:24:21 +01:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2017-02-15 13:07:34 +01:00
|
|
|
static void nrfmin_isr(netdev_t *dev)
|
2015-03-24 23:24:21 +01:00
|
|
|
{
|
2016-11-11 11:11:41 +01:00
|
|
|
if (nrfmin_dev.event_callback) {
|
2017-02-15 13:07:34 +01:00
|
|
|
nrfmin_dev.event_callback(dev, NETDEV_EVENT_RX_COMPLETE);
|
2015-03-24 23:24:21 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-02-15 13:07:34 +01:00
|
|
|
static int nrfmin_get(netdev_t *dev, netopt_t opt, void *val, size_t max_len)
|
2015-03-24 23:24:21 +01:00
|
|
|
{
|
|
|
|
(void)dev;
|
build: fix unused parameter errors
cpu, sam0_common: fix unused parameter in periph/spi
cpu, kinetis_common: fix unused parameter in periph/spi
cpu, cc2538: fix unused param in periph/i2c
cpu, cc2538: fix unused param in periph/spi
cpu, sam3: fix unused param in periph/spi
cpu, stm32_common: fix unused param in periph/pm
cpu, stm32f3: fix unused params in periph/i2c
cpu, nrf5x_common: fix unused param in periph/gpio
cpu, nrf5x_common: fix unused param in periph/spi
cpu, lpc2387: fix unused params in periph/spi
cpu, cc2538: fix unused params in radio/netdev
cpu, cc2650: fix unused params in periph/uart
cpu, lm4f120: fix unused param in periph/spi
cpu, lm4f120: fix unused params in periph/timer
cpu, lm4f120: fix unused params in periph/uart
cpu, stm32_common: fix unused params in periph/dac
cpu, stm32l0: fix unused params in periph/i2c
cpu, msp430fxyz: fix unused params in periph/uart
cpu, mips: fix unused params
cpu, cc430: fix unused-params in periph/timer
cpu, msp430fxyz: fix unused params in periph/spi
drivers, cc2420: fix unused param
cpu, mips32r2_common: fix unused params in periph/timer
cpu, cc2538: fix unused-param in periph/i2c
cpu, mips32r2_common: fix unused-param in periph/timer
cpu, msp430fxyz: fix unused params in periph/timer
cpu, atmega_common: fix unused params in periph/spi
driver, nrfmin: fix unused params
cpu, cc2538_rf: fix unused params
driver, netdev_ieee802514: fix unused param
cpu, mip_pic32m: fix unused params
cpu, lpc2387: fix unused params in periph/pwm
tests/driver_sdcard_spi: fix unused params
cpu, sam3: fix unused param in periph/pwm
tests/driver_dynamixel: fix unused params, and style issues
cpu, cc430: fix unused param in periph/rtc
cpu, atmega_common: fix unused params in periph/i2c
2017-10-31 12:09:11 +01:00
|
|
|
(void)max_len;
|
2015-03-24 23:24:21 +01:00
|
|
|
|
|
|
|
switch (opt) {
|
2015-08-06 15:36:56 +02:00
|
|
|
case NETOPT_CHANNEL:
|
2016-11-11 11:11:41 +01:00
|
|
|
assert(max_len >= sizeof(uint16_t));
|
|
|
|
*((uint16_t *)val) = nrfmin_get_channel();
|
|
|
|
return sizeof(uint16_t);
|
|
|
|
case NETOPT_ADDRESS:
|
|
|
|
assert(max_len >= sizeof(uint16_t));
|
|
|
|
*((uint16_t *)val) = nrfmin_get_addr();
|
|
|
|
return sizeof(uint16_t);
|
2015-08-06 15:36:56 +02:00
|
|
|
case NETOPT_STATE:
|
2016-11-11 11:11:41 +01:00
|
|
|
assert(max_len >= sizeof(netopt_state_t));
|
|
|
|
*((netopt_state_t *)val) = nrfmin_get_state();
|
|
|
|
return sizeof(netopt_state_t);
|
|
|
|
case NETOPT_TX_POWER:
|
|
|
|
assert(max_len >= sizeof(int16_t));
|
|
|
|
*((int16_t *)val) = nrfmin_get_txpower();
|
|
|
|
return sizeof(int16_t);
|
2019-02-04 12:43:07 +01:00
|
|
|
case NETOPT_MAX_PDU_SIZE:
|
2017-05-05 13:57:01 +02:00
|
|
|
assert(max_len >= sizeof(uint16_t));
|
|
|
|
*((uint16_t *)val) = NRFMIN_PAYLOAD_MAX;
|
2017-07-26 13:54:25 +02:00
|
|
|
return sizeof(uint16_t);
|
2016-11-11 11:11:41 +01:00
|
|
|
case NETOPT_ADDR_LEN:
|
|
|
|
assert(max_len >= sizeof(uint16_t));
|
|
|
|
*((uint16_t *)val) = 2;
|
|
|
|
return sizeof(uint16_t);
|
|
|
|
case NETOPT_NID:
|
|
|
|
assert(max_len >= sizeof(uint16_t));
|
|
|
|
*((uint16_t*)val) = CONF_PSEUDO_NID;
|
|
|
|
return sizeof(uint16_t);
|
2018-01-18 12:59:57 +01:00
|
|
|
#ifdef MODULE_GNRC_SIXLOWPAN
|
2016-11-11 11:11:41 +01:00
|
|
|
case NETOPT_PROTO:
|
2019-01-18 18:02:37 +01:00
|
|
|
assert(max_len == sizeof(gnrc_nettype_t));
|
|
|
|
*((gnrc_nettype_t *)val) = GNRC_NETTYPE_SIXLOWPAN;
|
|
|
|
return sizeof(gnrc_nettype_t);
|
2018-01-18 12:59:57 +01:00
|
|
|
#endif
|
2016-11-11 11:11:41 +01:00
|
|
|
case NETOPT_DEVICE_TYPE:
|
|
|
|
assert(max_len >= sizeof(uint16_t));
|
2017-02-15 13:07:34 +01:00
|
|
|
*((uint16_t *)val) = NETDEV_TYPE_NRFMIN;
|
2016-11-11 11:11:41 +01:00
|
|
|
return sizeof(uint16_t);
|
|
|
|
case NETOPT_IPV6_IID:
|
|
|
|
assert(max_len >= sizeof(uint64_t));
|
|
|
|
nrfmin_get_iid((uint16_t *)val);
|
|
|
|
return sizeof(uint64_t);
|
2015-03-24 23:24:21 +01:00
|
|
|
default:
|
|
|
|
return -ENOTSUP;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-08-25 07:34:03 +02:00
|
|
|
static int nrfmin_set(netdev_t *dev, netopt_t opt, const void *val, size_t len)
|
2015-03-24 23:24:21 +01:00
|
|
|
{
|
|
|
|
(void)dev;
|
build: fix unused parameter errors
cpu, sam0_common: fix unused parameter in periph/spi
cpu, kinetis_common: fix unused parameter in periph/spi
cpu, cc2538: fix unused param in periph/i2c
cpu, cc2538: fix unused param in periph/spi
cpu, sam3: fix unused param in periph/spi
cpu, stm32_common: fix unused param in periph/pm
cpu, stm32f3: fix unused params in periph/i2c
cpu, nrf5x_common: fix unused param in periph/gpio
cpu, nrf5x_common: fix unused param in periph/spi
cpu, lpc2387: fix unused params in periph/spi
cpu, cc2538: fix unused params in radio/netdev
cpu, cc2650: fix unused params in periph/uart
cpu, lm4f120: fix unused param in periph/spi
cpu, lm4f120: fix unused params in periph/timer
cpu, lm4f120: fix unused params in periph/uart
cpu, stm32_common: fix unused params in periph/dac
cpu, stm32l0: fix unused params in periph/i2c
cpu, msp430fxyz: fix unused params in periph/uart
cpu, mips: fix unused params
cpu, cc430: fix unused-params in periph/timer
cpu, msp430fxyz: fix unused params in periph/spi
drivers, cc2420: fix unused param
cpu, mips32r2_common: fix unused params in periph/timer
cpu, cc2538: fix unused-param in periph/i2c
cpu, mips32r2_common: fix unused-param in periph/timer
cpu, msp430fxyz: fix unused params in periph/timer
cpu, atmega_common: fix unused params in periph/spi
driver, nrfmin: fix unused params
cpu, cc2538_rf: fix unused params
driver, netdev_ieee802514: fix unused param
cpu, mip_pic32m: fix unused params
cpu, lpc2387: fix unused params in periph/pwm
tests/driver_sdcard_spi: fix unused params
cpu, sam3: fix unused param in periph/pwm
tests/driver_dynamixel: fix unused params, and style issues
cpu, cc430: fix unused param in periph/rtc
cpu, atmega_common: fix unused params in periph/i2c
2017-10-31 12:09:11 +01:00
|
|
|
(void)len;
|
2015-03-24 23:24:21 +01:00
|
|
|
|
|
|
|
switch (opt) {
|
2015-08-06 15:36:56 +02:00
|
|
|
case NETOPT_CHANNEL:
|
2016-11-11 11:11:41 +01:00
|
|
|
assert(len == sizeof(uint16_t));
|
2017-08-25 07:34:03 +02:00
|
|
|
return nrfmin_set_channel(*((const uint16_t *)val));
|
2016-11-11 11:11:41 +01:00
|
|
|
case NETOPT_ADDRESS:
|
|
|
|
assert(len == sizeof(uint16_t));
|
2017-08-25 07:34:03 +02:00
|
|
|
nrfmin_set_addr(*((const uint16_t *)val));
|
2016-11-11 11:11:41 +01:00
|
|
|
return sizeof(uint16_t);
|
|
|
|
case NETOPT_ADDR_LEN:
|
|
|
|
case NETOPT_SRC_LEN:
|
|
|
|
assert(len == sizeof(uint16_t));
|
2017-08-25 07:34:03 +02:00
|
|
|
if (*((const uint16_t *)val) != 2) {
|
2016-11-11 11:11:41 +01:00
|
|
|
return -EAFNOSUPPORT;
|
|
|
|
}
|
|
|
|
return sizeof(uint16_t);
|
2015-08-06 15:36:56 +02:00
|
|
|
case NETOPT_STATE:
|
2016-11-11 11:11:41 +01:00
|
|
|
assert(len == sizeof(netopt_state_t));
|
2017-08-25 07:34:03 +02:00
|
|
|
return nrfmin_set_state(*((const netopt_state_t *)val));
|
2016-11-11 11:11:41 +01:00
|
|
|
case NETOPT_TX_POWER:
|
|
|
|
assert(len == sizeof(int16_t));
|
2017-08-25 07:34:03 +02:00
|
|
|
nrfmin_set_txpower(*((const int16_t *)val));
|
2016-11-11 11:11:41 +01:00
|
|
|
return sizeof(int16_t);
|
2015-03-24 23:24:21 +01:00
|
|
|
default:
|
|
|
|
return -ENOTSUP;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-11-11 11:11:41 +01:00
|
|
|
/**
|
2017-02-15 13:07:34 +01:00
|
|
|
* @brief Export of the netdev interface
|
2015-03-24 23:24:21 +01:00
|
|
|
*/
|
2017-02-15 13:07:34 +01:00
|
|
|
const netdev_driver_t nrfmin_netdev = {
|
2016-11-11 11:11:41 +01:00
|
|
|
.send = nrfmin_send,
|
|
|
|
.recv = nrfmin_recv,
|
|
|
|
.init = nrfmin_init,
|
|
|
|
.isr = nrfmin_isr,
|
|
|
|
.get = nrfmin_get,
|
|
|
|
.set = nrfmin_set
|
2015-03-24 23:24:21 +01:00
|
|
|
};
|