drivers/cc110x: Rewrite of the cc110x driver
The cc110x driver has been re-written from scratch to overcome the limitations
of the old driver. The main motivation of the rewrite was to achieve better
maintainability by a detailed documentation, reduce the complexity and the
overhead of the SPI communication with the device, and to allow to
simultaneously use transceivers with different configuration regarding the used
base band, the channel bandwidth, the modulation rate, and the channel map.
Features of this driver include:
- Support for the CC1100, CC1101, and the CC1100e sub-gigahertz transceivers.
- Detailed documentation of every aspect of this driver.
- An easy to use configuration API that allows setting the transceiver
configuration (modulation rate, channel bandwidth, base frequency) and the
channel map.
- Fast channel hopping by pre-calibration of the channels during device
configuration (so that no calibration is needed during hopping).
- Simplified SPI communication: Only during start-up the MCU has to wait
for the transceiver to be ready (for the power regulators and the crystal
to stabilize). The old driver did this for every SPI transfer, which
resulted in complex communication code. This driver will wait on start up
for the transceiver to power up and then use RIOT's SPI API like every other
driver. (Not only the data sheet states that this is fine, it also proved to
be reliable in practise.)
- Greatly reduced latency: The RTT on the old driver (@150 kbps data rate) was
about 16ms, the new driver (@250 kbps data rate) has as RTT of ~3ms
(depending on SPI clock and on CPU performance) (measured with ping6).
- Increased reliability: The preamble size and the sync word size have been
doubled compared to the old driver (preamble: 8 bytes instead of 4,
sync word: 4 byte instead of 2). The new values are the once recommended by
the data sheet for reliable communication.
- Basic diagnostic during driver initialization to detect common issues as
SPI communication issues and GDO pin configuration/wiring issues.
- TX power configuration with netdev_driver_t::set() API-integration
- Calls to netdev_driver_t::send() block until the transmission has completed
to ease the use of the API (implemented without busy waiting, so that the
MCU can enter lower power states or other threads can be executed).
2018-11-08 17:37:07 +01:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2018 Otto-von-Guericke-Universität Magdeburg
|
|
|
|
*
|
|
|
|
* 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.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
2019-09-04 13:15:15 +02:00
|
|
|
* @ingroup drivers_cc110x
|
drivers/cc110x: Rewrite of the cc110x driver
The cc110x driver has been re-written from scratch to overcome the limitations
of the old driver. The main motivation of the rewrite was to achieve better
maintainability by a detailed documentation, reduce the complexity and the
overhead of the SPI communication with the device, and to allow to
simultaneously use transceivers with different configuration regarding the used
base band, the channel bandwidth, the modulation rate, and the channel map.
Features of this driver include:
- Support for the CC1100, CC1101, and the CC1100e sub-gigahertz transceivers.
- Detailed documentation of every aspect of this driver.
- An easy to use configuration API that allows setting the transceiver
configuration (modulation rate, channel bandwidth, base frequency) and the
channel map.
- Fast channel hopping by pre-calibration of the channels during device
configuration (so that no calibration is needed during hopping).
- Simplified SPI communication: Only during start-up the MCU has to wait
for the transceiver to be ready (for the power regulators and the crystal
to stabilize). The old driver did this for every SPI transfer, which
resulted in complex communication code. This driver will wait on start up
for the transceiver to power up and then use RIOT's SPI API like every other
driver. (Not only the data sheet states that this is fine, it also proved to
be reliable in practise.)
- Greatly reduced latency: The RTT on the old driver (@150 kbps data rate) was
about 16ms, the new driver (@250 kbps data rate) has as RTT of ~3ms
(depending on SPI clock and on CPU performance) (measured with ping6).
- Increased reliability: The preamble size and the sync word size have been
doubled compared to the old driver (preamble: 8 bytes instead of 4,
sync word: 4 byte instead of 2). The new values are the once recommended by
the data sheet for reliable communication.
- Basic diagnostic during driver initialization to detect common issues as
SPI communication issues and GDO pin configuration/wiring issues.
- TX power configuration with netdev_driver_t::set() API-integration
- Calls to netdev_driver_t::send() block until the transmission has completed
to ease the use of the API (implemented without busy waiting, so that the
MCU can enter lower power states or other threads can be executed).
2018-11-08 17:37:07 +01:00
|
|
|
* @{
|
|
|
|
*
|
|
|
|
* @file
|
2019-09-04 13:15:15 +02:00
|
|
|
* @brief Implementation of RIOT's netdev_driver API for the CC1100/CC1101
|
|
|
|
* transceiver
|
drivers/cc110x: Rewrite of the cc110x driver
The cc110x driver has been re-written from scratch to overcome the limitations
of the old driver. The main motivation of the rewrite was to achieve better
maintainability by a detailed documentation, reduce the complexity and the
overhead of the SPI communication with the device, and to allow to
simultaneously use transceivers with different configuration regarding the used
base band, the channel bandwidth, the modulation rate, and the channel map.
Features of this driver include:
- Support for the CC1100, CC1101, and the CC1100e sub-gigahertz transceivers.
- Detailed documentation of every aspect of this driver.
- An easy to use configuration API that allows setting the transceiver
configuration (modulation rate, channel bandwidth, base frequency) and the
channel map.
- Fast channel hopping by pre-calibration of the channels during device
configuration (so that no calibration is needed during hopping).
- Simplified SPI communication: Only during start-up the MCU has to wait
for the transceiver to be ready (for the power regulators and the crystal
to stabilize). The old driver did this for every SPI transfer, which
resulted in complex communication code. This driver will wait on start up
for the transceiver to power up and then use RIOT's SPI API like every other
driver. (Not only the data sheet states that this is fine, it also proved to
be reliable in practise.)
- Greatly reduced latency: The RTT on the old driver (@150 kbps data rate) was
about 16ms, the new driver (@250 kbps data rate) has as RTT of ~3ms
(depending on SPI clock and on CPU performance) (measured with ping6).
- Increased reliability: The preamble size and the sync word size have been
doubled compared to the old driver (preamble: 8 bytes instead of 4,
sync word: 4 byte instead of 2). The new values are the once recommended by
the data sheet for reliable communication.
- Basic diagnostic during driver initialization to detect common issues as
SPI communication issues and GDO pin configuration/wiring issues.
- TX power configuration with netdev_driver_t::set() API-integration
- Calls to netdev_driver_t::send() block until the transmission has completed
to ease the use of the API (implemented without busy waiting, so that the
MCU can enter lower power states or other threads can be executed).
2018-11-08 17:37:07 +01:00
|
|
|
*
|
2019-09-04 13:15:15 +02:00
|
|
|
* @author Marian Buschsieweke <marian.buschsieweke@ovgu.de>
|
drivers/cc110x: Rewrite of the cc110x driver
The cc110x driver has been re-written from scratch to overcome the limitations
of the old driver. The main motivation of the rewrite was to achieve better
maintainability by a detailed documentation, reduce the complexity and the
overhead of the SPI communication with the device, and to allow to
simultaneously use transceivers with different configuration regarding the used
base band, the channel bandwidth, the modulation rate, and the channel map.
Features of this driver include:
- Support for the CC1100, CC1101, and the CC1100e sub-gigahertz transceivers.
- Detailed documentation of every aspect of this driver.
- An easy to use configuration API that allows setting the transceiver
configuration (modulation rate, channel bandwidth, base frequency) and the
channel map.
- Fast channel hopping by pre-calibration of the channels during device
configuration (so that no calibration is needed during hopping).
- Simplified SPI communication: Only during start-up the MCU has to wait
for the transceiver to be ready (for the power regulators and the crystal
to stabilize). The old driver did this for every SPI transfer, which
resulted in complex communication code. This driver will wait on start up
for the transceiver to power up and then use RIOT's SPI API like every other
driver. (Not only the data sheet states that this is fine, it also proved to
be reliable in practise.)
- Greatly reduced latency: The RTT on the old driver (@150 kbps data rate) was
about 16ms, the new driver (@250 kbps data rate) has as RTT of ~3ms
(depending on SPI clock and on CPU performance) (measured with ping6).
- Increased reliability: The preamble size and the sync word size have been
doubled compared to the old driver (preamble: 8 bytes instead of 4,
sync word: 4 byte instead of 2). The new values are the once recommended by
the data sheet for reliable communication.
- Basic diagnostic during driver initialization to detect common issues as
SPI communication issues and GDO pin configuration/wiring issues.
- TX power configuration with netdev_driver_t::set() API-integration
- Calls to netdev_driver_t::send() block until the transmission has completed
to ease the use of the API (implemented without busy waiting, so that the
MCU can enter lower power states or other threads can be executed).
2018-11-08 17:37:07 +01:00
|
|
|
* @}
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <errno.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
#include "assert.h"
|
|
|
|
#include "iolist.h"
|
|
|
|
#include "irq.h"
|
|
|
|
#include "mutex.h"
|
|
|
|
#include "net/eui64.h"
|
|
|
|
#include "net/netdev.h"
|
|
|
|
#include "xtimer.h"
|
|
|
|
|
|
|
|
#include "cc110x.h"
|
|
|
|
#include "cc110x_internal.h"
|
|
|
|
|
2020-10-22 11:34:31 +02:00
|
|
|
#define ENABLE_DEBUG 0
|
drivers/cc110x: Rewrite of the cc110x driver
The cc110x driver has been re-written from scratch to overcome the limitations
of the old driver. The main motivation of the rewrite was to achieve better
maintainability by a detailed documentation, reduce the complexity and the
overhead of the SPI communication with the device, and to allow to
simultaneously use transceivers with different configuration regarding the used
base band, the channel bandwidth, the modulation rate, and the channel map.
Features of this driver include:
- Support for the CC1100, CC1101, and the CC1100e sub-gigahertz transceivers.
- Detailed documentation of every aspect of this driver.
- An easy to use configuration API that allows setting the transceiver
configuration (modulation rate, channel bandwidth, base frequency) and the
channel map.
- Fast channel hopping by pre-calibration of the channels during device
configuration (so that no calibration is needed during hopping).
- Simplified SPI communication: Only during start-up the MCU has to wait
for the transceiver to be ready (for the power regulators and the crystal
to stabilize). The old driver did this for every SPI transfer, which
resulted in complex communication code. This driver will wait on start up
for the transceiver to power up and then use RIOT's SPI API like every other
driver. (Not only the data sheet states that this is fine, it also proved to
be reliable in practise.)
- Greatly reduced latency: The RTT on the old driver (@150 kbps data rate) was
about 16ms, the new driver (@250 kbps data rate) has as RTT of ~3ms
(depending on SPI clock and on CPU performance) (measured with ping6).
- Increased reliability: The preamble size and the sync word size have been
doubled compared to the old driver (preamble: 8 bytes instead of 4,
sync word: 4 byte instead of 2). The new values are the once recommended by
the data sheet for reliable communication.
- Basic diagnostic during driver initialization to detect common issues as
SPI communication issues and GDO pin configuration/wiring issues.
- TX power configuration with netdev_driver_t::set() API-integration
- Calls to netdev_driver_t::send() block until the transmission has completed
to ease the use of the API (implemented without busy waiting, so that the
MCU can enter lower power states or other threads can be executed).
2018-11-08 17:37:07 +01:00
|
|
|
#include "debug.h"
|
|
|
|
|
|
|
|
static int cc110x_init(netdev_t *netdev);
|
|
|
|
static int cc110x_recv(netdev_t *netdev, void *buf, size_t len, void *info);
|
|
|
|
static int cc110x_send(netdev_t *netdev, const iolist_t *iolist);
|
|
|
|
static int cc110x_get(netdev_t *netdev, netopt_t opt,
|
|
|
|
void *val, size_t max_len);
|
|
|
|
static int cc110x_set(netdev_t *netdev, netopt_t opt,
|
|
|
|
const void *val, size_t len);
|
|
|
|
|
|
|
|
/**
|
2019-09-04 13:15:15 +02:00
|
|
|
* @brief A lookup table to convert from dBm value to the best matching
|
|
|
|
* @ref cc110x_tx_power_t value
|
drivers/cc110x: Rewrite of the cc110x driver
The cc110x driver has been re-written from scratch to overcome the limitations
of the old driver. The main motivation of the rewrite was to achieve better
maintainability by a detailed documentation, reduce the complexity and the
overhead of the SPI communication with the device, and to allow to
simultaneously use transceivers with different configuration regarding the used
base band, the channel bandwidth, the modulation rate, and the channel map.
Features of this driver include:
- Support for the CC1100, CC1101, and the CC1100e sub-gigahertz transceivers.
- Detailed documentation of every aspect of this driver.
- An easy to use configuration API that allows setting the transceiver
configuration (modulation rate, channel bandwidth, base frequency) and the
channel map.
- Fast channel hopping by pre-calibration of the channels during device
configuration (so that no calibration is needed during hopping).
- Simplified SPI communication: Only during start-up the MCU has to wait
for the transceiver to be ready (for the power regulators and the crystal
to stabilize). The old driver did this for every SPI transfer, which
resulted in complex communication code. This driver will wait on start up
for the transceiver to power up and then use RIOT's SPI API like every other
driver. (Not only the data sheet states that this is fine, it also proved to
be reliable in practise.)
- Greatly reduced latency: The RTT on the old driver (@150 kbps data rate) was
about 16ms, the new driver (@250 kbps data rate) has as RTT of ~3ms
(depending on SPI clock and on CPU performance) (measured with ping6).
- Increased reliability: The preamble size and the sync word size have been
doubled compared to the old driver (preamble: 8 bytes instead of 4,
sync word: 4 byte instead of 2). The new values are the once recommended by
the data sheet for reliable communication.
- Basic diagnostic during driver initialization to detect common issues as
SPI communication issues and GDO pin configuration/wiring issues.
- TX power configuration with netdev_driver_t::set() API-integration
- Calls to netdev_driver_t::send() block until the transmission has completed
to ease the use of the API (implemented without busy waiting, so that the
MCU can enter lower power states or other threads can be executed).
2018-11-08 17:37:07 +01:00
|
|
|
*/
|
|
|
|
static const int8_t tx_power_from_dbm[] = {
|
|
|
|
[CC110X_TX_POWER_MINUS_30_DBM] = -25,
|
|
|
|
[CC110X_TX_POWER_MINUS_20_DBM] = -17,
|
|
|
|
[CC110X_TX_POWER_MINUS_15_DBM] = -12,
|
|
|
|
[CC110X_TX_POWER_MINUS_10_DBM] = -5,
|
|
|
|
[CC110X_TX_POWER_0_DBM] = 3,
|
|
|
|
[CC110X_TX_POWER_PLUS_5_DBM] = 6,
|
|
|
|
[CC110X_TX_POWER_PLUS_7_DBM] = 9,
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
2019-09-04 13:15:15 +02:00
|
|
|
* @brief A lookup table to convert an @ref cc110x_tx_power_t value to dBm
|
drivers/cc110x: Rewrite of the cc110x driver
The cc110x driver has been re-written from scratch to overcome the limitations
of the old driver. The main motivation of the rewrite was to achieve better
maintainability by a detailed documentation, reduce the complexity and the
overhead of the SPI communication with the device, and to allow to
simultaneously use transceivers with different configuration regarding the used
base band, the channel bandwidth, the modulation rate, and the channel map.
Features of this driver include:
- Support for the CC1100, CC1101, and the CC1100e sub-gigahertz transceivers.
- Detailed documentation of every aspect of this driver.
- An easy to use configuration API that allows setting the transceiver
configuration (modulation rate, channel bandwidth, base frequency) and the
channel map.
- Fast channel hopping by pre-calibration of the channels during device
configuration (so that no calibration is needed during hopping).
- Simplified SPI communication: Only during start-up the MCU has to wait
for the transceiver to be ready (for the power regulators and the crystal
to stabilize). The old driver did this for every SPI transfer, which
resulted in complex communication code. This driver will wait on start up
for the transceiver to power up and then use RIOT's SPI API like every other
driver. (Not only the data sheet states that this is fine, it also proved to
be reliable in practise.)
- Greatly reduced latency: The RTT on the old driver (@150 kbps data rate) was
about 16ms, the new driver (@250 kbps data rate) has as RTT of ~3ms
(depending on SPI clock and on CPU performance) (measured with ping6).
- Increased reliability: The preamble size and the sync word size have been
doubled compared to the old driver (preamble: 8 bytes instead of 4,
sync word: 4 byte instead of 2). The new values are the once recommended by
the data sheet for reliable communication.
- Basic diagnostic during driver initialization to detect common issues as
SPI communication issues and GDO pin configuration/wiring issues.
- TX power configuration with netdev_driver_t::set() API-integration
- Calls to netdev_driver_t::send() block until the transmission has completed
to ease the use of the API (implemented without busy waiting, so that the
MCU can enter lower power states or other threads can be executed).
2018-11-08 17:37:07 +01:00
|
|
|
*/
|
|
|
|
static const int8_t dbm_from_tx_power[] = {
|
|
|
|
[CC110X_TX_POWER_MINUS_30_DBM] = -30,
|
|
|
|
[CC110X_TX_POWER_MINUS_20_DBM] = -20,
|
|
|
|
[CC110X_TX_POWER_MINUS_15_DBM] = -15,
|
|
|
|
[CC110X_TX_POWER_MINUS_10_DBM] = -10,
|
|
|
|
[CC110X_TX_POWER_0_DBM] = 0,
|
|
|
|
[CC110X_TX_POWER_PLUS_5_DBM] = 5,
|
|
|
|
[CC110X_TX_POWER_PLUS_7_DBM] = 7,
|
|
|
|
[CC110X_TX_POWER_PLUS_10_DBM] = 10,
|
|
|
|
};
|
|
|
|
|
|
|
|
const netdev_driver_t cc110x_driver = {
|
|
|
|
.init = cc110x_init,
|
|
|
|
.recv = cc110x_recv,
|
|
|
|
.send = cc110x_send,
|
|
|
|
.isr = cc110x_isr,
|
|
|
|
.get = cc110x_get,
|
|
|
|
.set = cc110x_set,
|
|
|
|
};
|
|
|
|
|
|
|
|
void cc110x_on_gdo(void *_dev)
|
|
|
|
{
|
|
|
|
cc110x_t *dev = _dev;
|
|
|
|
if ((dev->state & 0x07) == CC110X_STATE_TX_MODE) {
|
|
|
|
/* Unlock mutex to unblock netdev thread */
|
|
|
|
mutex_unlock(&dev->isr_signal);
|
|
|
|
}
|
|
|
|
else {
|
2020-03-05 15:11:20 +01:00
|
|
|
netdev_trigger_event_isr(&dev->netdev);
|
drivers/cc110x: Rewrite of the cc110x driver
The cc110x driver has been re-written from scratch to overcome the limitations
of the old driver. The main motivation of the rewrite was to achieve better
maintainability by a detailed documentation, reduce the complexity and the
overhead of the SPI communication with the device, and to allow to
simultaneously use transceivers with different configuration regarding the used
base band, the channel bandwidth, the modulation rate, and the channel map.
Features of this driver include:
- Support for the CC1100, CC1101, and the CC1100e sub-gigahertz transceivers.
- Detailed documentation of every aspect of this driver.
- An easy to use configuration API that allows setting the transceiver
configuration (modulation rate, channel bandwidth, base frequency) and the
channel map.
- Fast channel hopping by pre-calibration of the channels during device
configuration (so that no calibration is needed during hopping).
- Simplified SPI communication: Only during start-up the MCU has to wait
for the transceiver to be ready (for the power regulators and the crystal
to stabilize). The old driver did this for every SPI transfer, which
resulted in complex communication code. This driver will wait on start up
for the transceiver to power up and then use RIOT's SPI API like every other
driver. (Not only the data sheet states that this is fine, it also proved to
be reliable in practise.)
- Greatly reduced latency: The RTT on the old driver (@150 kbps data rate) was
about 16ms, the new driver (@250 kbps data rate) has as RTT of ~3ms
(depending on SPI clock and on CPU performance) (measured with ping6).
- Increased reliability: The preamble size and the sync word size have been
doubled compared to the old driver (preamble: 8 bytes instead of 4,
sync word: 4 byte instead of 2). The new values are the once recommended by
the data sheet for reliable communication.
- Basic diagnostic during driver initialization to detect common issues as
SPI communication issues and GDO pin configuration/wiring issues.
- TX power configuration with netdev_driver_t::set() API-integration
- Calls to netdev_driver_t::send() block until the transmission has completed
to ease the use of the API (implemented without busy waiting, so that the
MCU can enter lower power states or other threads can be executed).
2018-11-08 17:37:07 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static int identify_device(cc110x_t *dev)
|
|
|
|
{
|
|
|
|
uint8_t partnum, version, status;
|
|
|
|
int is_ready;
|
|
|
|
cc110x_state_t state;
|
|
|
|
|
|
|
|
cc110x_read(dev, CC110X_REG_VERSION, &version);
|
|
|
|
/* Retrieving the status is reliable for non-transient status */
|
|
|
|
status = cc110x_read(dev, CC110X_REG_PARTNUM, &partnum);
|
|
|
|
state = cc110x_state_from_status(status);
|
|
|
|
/* Most significant bit should be zero, otherwise chip is not ready */
|
|
|
|
is_ready = cc110x_is_ready_from_status(status);
|
|
|
|
|
|
|
|
DEBUG("[cc110x] PARTNUM = %i, VERSION = %i, STATUS = 0x%02x, READY = %i\n",
|
|
|
|
(int)partnum, (int)version, (int)status, is_ready);
|
|
|
|
|
|
|
|
if ((state != CC110X_STATE_IDLE) || (!is_ready)) {
|
|
|
|
DEBUG("[cc110x] IC not ready or in invalid state\n");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Source: https://e2e.ti.com/support/wireless-connectivity/other-wireless/f/667/t/370643 */
|
|
|
|
if (partnum != 0) {
|
|
|
|
DEBUG("[cc110x] Device not a CC110x transceiver\n");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (version) {
|
2021-03-26 20:38:18 +01:00
|
|
|
case 3:
|
|
|
|
DEBUG("[cc110x] Detected CC1100 transceiver\n");
|
|
|
|
/* RSSI offset is 78dBm @ 868MHz & 250kBaud.
|
|
|
|
* Depends on the symbol rate and base band and ranges from
|
|
|
|
* 74dBm to 79dBm.
|
|
|
|
*/
|
|
|
|
dev->rssi_offset = 78;
|
|
|
|
return 0;
|
|
|
|
case 5:
|
|
|
|
DEBUG("[cc110x] Detected CC1100E transceiver\n");
|
|
|
|
/* RSSI offset is 79 dBm @ 250kbps & 250 kbps.
|
|
|
|
* Depends on base band and symbol rate and ranges from
|
|
|
|
* 75dBm to 79dBm
|
|
|
|
*/
|
|
|
|
dev->rssi_offset = 79;
|
|
|
|
return 0;
|
|
|
|
case 4:
|
|
|
|
/* falls through */
|
|
|
|
case 14:
|
|
|
|
/* falls through */
|
|
|
|
case 20:
|
|
|
|
/* RSSI offset for the CC1101 is independent of symbol rate and
|
|
|
|
* base 74 dBm
|
|
|
|
*/
|
|
|
|
dev->rssi_offset = 74;
|
|
|
|
DEBUG("[cc110x] Detected CC1101 transceiver\n");
|
|
|
|
return 0;
|
|
|
|
default:
|
|
|
|
DEBUG("[cc110x] Device not a CC110x transceiver\n");
|
|
|
|
return -1;
|
drivers/cc110x: Rewrite of the cc110x driver
The cc110x driver has been re-written from scratch to overcome the limitations
of the old driver. The main motivation of the rewrite was to achieve better
maintainability by a detailed documentation, reduce the complexity and the
overhead of the SPI communication with the device, and to allow to
simultaneously use transceivers with different configuration regarding the used
base band, the channel bandwidth, the modulation rate, and the channel map.
Features of this driver include:
- Support for the CC1100, CC1101, and the CC1100e sub-gigahertz transceivers.
- Detailed documentation of every aspect of this driver.
- An easy to use configuration API that allows setting the transceiver
configuration (modulation rate, channel bandwidth, base frequency) and the
channel map.
- Fast channel hopping by pre-calibration of the channels during device
configuration (so that no calibration is needed during hopping).
- Simplified SPI communication: Only during start-up the MCU has to wait
for the transceiver to be ready (for the power regulators and the crystal
to stabilize). The old driver did this for every SPI transfer, which
resulted in complex communication code. This driver will wait on start up
for the transceiver to power up and then use RIOT's SPI API like every other
driver. (Not only the data sheet states that this is fine, it also proved to
be reliable in practise.)
- Greatly reduced latency: The RTT on the old driver (@150 kbps data rate) was
about 16ms, the new driver (@250 kbps data rate) has as RTT of ~3ms
(depending on SPI clock and on CPU performance) (measured with ping6).
- Increased reliability: The preamble size and the sync word size have been
doubled compared to the old driver (preamble: 8 bytes instead of 4,
sync word: 4 byte instead of 2). The new values are the once recommended by
the data sheet for reliable communication.
- Basic diagnostic during driver initialization to detect common issues as
SPI communication issues and GDO pin configuration/wiring issues.
- TX power configuration with netdev_driver_t::set() API-integration
- Calls to netdev_driver_t::send() block until the transmission has completed
to ease the use of the API (implemented without busy waiting, so that the
MCU can enter lower power states or other threads can be executed).
2018-11-08 17:37:07 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static int check_config(cc110x_t *dev)
|
|
|
|
{
|
|
|
|
char buf[CC110X_CONF_SIZE];
|
|
|
|
|
|
|
|
/* Verify content of main config registers */
|
|
|
|
cc110x_burst_read(dev, CC110X_CONF_START, buf, sizeof(buf));
|
|
|
|
if (memcmp(buf, cc110x_conf, sizeof(buf))) {
|
|
|
|
DEBUG("[cc110x] ERROR: Verification of main config registers failed\n"
|
|
|
|
" Check SPI wiring or reduce SPI clock\n");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Verify content of "magic number" config registers */
|
|
|
|
cc110x_burst_read(dev, CC110X_REG_TEST2, buf,
|
|
|
|
sizeof(cc110x_magic_registers));
|
|
|
|
if (memcmp(buf, cc110x_magic_registers, sizeof(cc110x_magic_registers))) {
|
|
|
|
DEBUG("[cc110x] ERROR: Verification of \"magic\" registers failed\n"
|
|
|
|
" Check SPI wiring or reduce SPI clock\n");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Verify content of PA_TABLE */
|
|
|
|
cc110x_burst_read(dev, CC110X_MULTIREG_PATABLE, buf, CC110X_PATABLE_LEN);
|
|
|
|
if (memcmp(buf, dev->params.patable->data, CC110X_PATABLE_LEN)) {
|
|
|
|
DEBUG("[cc110x] ERROR: Verification of PA_TABLE failed\n"
|
|
|
|
" Check SPI wiring or reduce SPI clock\n");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEBUG("[cc110x] Content of configuration registers verified\n");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int check_gdo_pins(cc110x_t *dev)
|
|
|
|
{
|
|
|
|
/* GPIOs connected to GDOs are not yet configured, so we do this now.
|
|
|
|
* This configuration is just temporarily for testing, as gpio_init_int()
|
|
|
|
* will reconfigure them later again. We do not want to set up the
|
|
|
|
* interrupts before validating the transceiver, so we effectively configure
|
|
|
|
* the GPIOs twice.
|
|
|
|
*/
|
|
|
|
if (gpio_init(dev->params.gdo2, GPIO_IN)) {
|
|
|
|
DEBUG("[cc110x] Configuring GDO2 failed");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (gpio_init(dev->params.gdo0, GPIO_IN)) {
|
|
|
|
DEBUG("[cc110x] Configuring GDO0 failed");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Validate that GDO2 responds to configuration updates */
|
|
|
|
cc110x_write(dev, CC110X_REG_IOCFG2, CC110X_GDO_CONSTANT_HIGH);
|
|
|
|
if (!gpio_read(dev->params.gdo2)) {
|
|
|
|
DEBUG("[cc110x] GDO2 does not respond (check wiring!)\n");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
cc110x_write(dev, CC110X_REG_IOCFG2, CC110X_GDO_CONSTANT_LOW);
|
|
|
|
if (gpio_read(dev->params.gdo2)) {
|
|
|
|
DEBUG("[cc110x] GDO2 does not respond (check wiring!)\n");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Validate that GDO0 responds to configuration updates */
|
|
|
|
cc110x_write(dev, CC110X_REG_IOCFG0, CC110X_GDO_CONSTANT_HIGH);
|
|
|
|
if (!gpio_read(dev->params.gdo0)) {
|
|
|
|
DEBUG("[cc110x] GDO0 does not respond (check wiring!)\n");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
cc110x_write(dev, CC110X_REG_IOCFG0, CC110X_GDO_CONSTANT_LOW);
|
|
|
|
if (gpio_read(dev->params.gdo0)) {
|
|
|
|
DEBUG("[cc110x] GDO0 does not respond (check wiring!)\n");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Restore default GDO2 & GDO0 config */
|
|
|
|
cc110x_write(dev, CC110X_REG_IOCFG2, cc110x_conf[CC110X_REG_IOCFG2]);
|
|
|
|
cc110x_write(dev, CC110X_REG_IOCFG0, cc110x_conf[CC110X_REG_IOCFG0]);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int cc110x_init(netdev_t *netdev)
|
|
|
|
{
|
|
|
|
cc110x_t *dev = (cc110x_t *)netdev;
|
|
|
|
/* Use locked mutex to block thread on TX and un-block from ISR */
|
|
|
|
mutex_init(&dev->isr_signal);
|
|
|
|
mutex_lock(&dev->isr_signal);
|
|
|
|
|
|
|
|
/* Make sure the crystal is stable and the chip ready. This is needed as
|
|
|
|
* the reset is done via an SPI command, but the SPI interface must not be
|
|
|
|
* used unless the chip is ready according to the data sheet. After the
|
2019-08-14 17:31:33 +02:00
|
|
|
* reset, a second call to cc110x_power_on_and_acquire() is needed to finally have
|
drivers/cc110x: Rewrite of the cc110x driver
The cc110x driver has been re-written from scratch to overcome the limitations
of the old driver. The main motivation of the rewrite was to achieve better
maintainability by a detailed documentation, reduce the complexity and the
overhead of the SPI communication with the device, and to allow to
simultaneously use transceivers with different configuration regarding the used
base band, the channel bandwidth, the modulation rate, and the channel map.
Features of this driver include:
- Support for the CC1100, CC1101, and the CC1100e sub-gigahertz transceivers.
- Detailed documentation of every aspect of this driver.
- An easy to use configuration API that allows setting the transceiver
configuration (modulation rate, channel bandwidth, base frequency) and the
channel map.
- Fast channel hopping by pre-calibration of the channels during device
configuration (so that no calibration is needed during hopping).
- Simplified SPI communication: Only during start-up the MCU has to wait
for the transceiver to be ready (for the power regulators and the crystal
to stabilize). The old driver did this for every SPI transfer, which
resulted in complex communication code. This driver will wait on start up
for the transceiver to power up and then use RIOT's SPI API like every other
driver. (Not only the data sheet states that this is fine, it also proved to
be reliable in practise.)
- Greatly reduced latency: The RTT on the old driver (@150 kbps data rate) was
about 16ms, the new driver (@250 kbps data rate) has as RTT of ~3ms
(depending on SPI clock and on CPU performance) (measured with ping6).
- Increased reliability: The preamble size and the sync word size have been
doubled compared to the old driver (preamble: 8 bytes instead of 4,
sync word: 4 byte instead of 2). The new values are the once recommended by
the data sheet for reliable communication.
- Basic diagnostic during driver initialization to detect common issues as
SPI communication issues and GDO pin configuration/wiring issues.
- TX power configuration with netdev_driver_t::set() API-integration
- Calls to netdev_driver_t::send() block until the transmission has completed
to ease the use of the API (implemented without busy waiting, so that the
MCU can enter lower power states or other threads can be executed).
2018-11-08 17:37:07 +01:00
|
|
|
* the transceiver in a known state and ready for SPI communication.
|
|
|
|
*/
|
2019-08-14 17:31:33 +02:00
|
|
|
if (cc110x_power_on_and_acquire(dev)) {
|
drivers/cc110x: Rewrite of the cc110x driver
The cc110x driver has been re-written from scratch to overcome the limitations
of the old driver. The main motivation of the rewrite was to achieve better
maintainability by a detailed documentation, reduce the complexity and the
overhead of the SPI communication with the device, and to allow to
simultaneously use transceivers with different configuration regarding the used
base band, the channel bandwidth, the modulation rate, and the channel map.
Features of this driver include:
- Support for the CC1100, CC1101, and the CC1100e sub-gigahertz transceivers.
- Detailed documentation of every aspect of this driver.
- An easy to use configuration API that allows setting the transceiver
configuration (modulation rate, channel bandwidth, base frequency) and the
channel map.
- Fast channel hopping by pre-calibration of the channels during device
configuration (so that no calibration is needed during hopping).
- Simplified SPI communication: Only during start-up the MCU has to wait
for the transceiver to be ready (for the power regulators and the crystal
to stabilize). The old driver did this for every SPI transfer, which
resulted in complex communication code. This driver will wait on start up
for the transceiver to power up and then use RIOT's SPI API like every other
driver. (Not only the data sheet states that this is fine, it also proved to
be reliable in practise.)
- Greatly reduced latency: The RTT on the old driver (@150 kbps data rate) was
about 16ms, the new driver (@250 kbps data rate) has as RTT of ~3ms
(depending on SPI clock and on CPU performance) (measured with ping6).
- Increased reliability: The preamble size and the sync word size have been
doubled compared to the old driver (preamble: 8 bytes instead of 4,
sync word: 4 byte instead of 2). The new values are the once recommended by
the data sheet for reliable communication.
- Basic diagnostic during driver initialization to detect common issues as
SPI communication issues and GDO pin configuration/wiring issues.
- TX power configuration with netdev_driver_t::set() API-integration
- Calls to netdev_driver_t::send() block until the transmission has completed
to ease the use of the API (implemented without busy waiting, so that the
MCU can enter lower power states or other threads can be executed).
2018-11-08 17:37:07 +01:00
|
|
|
DEBUG("[cc110x] netdev_driver_t::init(): Failed to pull CS pin low\n");
|
|
|
|
return -EIO;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Performing a reset of the transceiver to get it in a known state */
|
|
|
|
cc110x_cmd(dev, CC110X_STROBE_RESET);
|
|
|
|
cc110x_release(dev);
|
|
|
|
|
|
|
|
/* Again, make sure the crystal is stable and the chip ready */
|
2019-08-14 17:31:33 +02:00
|
|
|
if (cc110x_power_on_and_acquire(dev)) {
|
drivers/cc110x: Rewrite of the cc110x driver
The cc110x driver has been re-written from scratch to overcome the limitations
of the old driver. The main motivation of the rewrite was to achieve better
maintainability by a detailed documentation, reduce the complexity and the
overhead of the SPI communication with the device, and to allow to
simultaneously use transceivers with different configuration regarding the used
base band, the channel bandwidth, the modulation rate, and the channel map.
Features of this driver include:
- Support for the CC1100, CC1101, and the CC1100e sub-gigahertz transceivers.
- Detailed documentation of every aspect of this driver.
- An easy to use configuration API that allows setting the transceiver
configuration (modulation rate, channel bandwidth, base frequency) and the
channel map.
- Fast channel hopping by pre-calibration of the channels during device
configuration (so that no calibration is needed during hopping).
- Simplified SPI communication: Only during start-up the MCU has to wait
for the transceiver to be ready (for the power regulators and the crystal
to stabilize). The old driver did this for every SPI transfer, which
resulted in complex communication code. This driver will wait on start up
for the transceiver to power up and then use RIOT's SPI API like every other
driver. (Not only the data sheet states that this is fine, it also proved to
be reliable in practise.)
- Greatly reduced latency: The RTT on the old driver (@150 kbps data rate) was
about 16ms, the new driver (@250 kbps data rate) has as RTT of ~3ms
(depending on SPI clock and on CPU performance) (measured with ping6).
- Increased reliability: The preamble size and the sync word size have been
doubled compared to the old driver (preamble: 8 bytes instead of 4,
sync word: 4 byte instead of 2). The new values are the once recommended by
the data sheet for reliable communication.
- Basic diagnostic during driver initialization to detect common issues as
SPI communication issues and GDO pin configuration/wiring issues.
- TX power configuration with netdev_driver_t::set() API-integration
- Calls to netdev_driver_t::send() block until the transmission has completed
to ease the use of the API (implemented without busy waiting, so that the
MCU can enter lower power states or other threads can be executed).
2018-11-08 17:37:07 +01:00
|
|
|
DEBUG("[cc110x] netdev_driver_t::init(): Failed to pull CS pin low "
|
|
|
|
"after reset\n");
|
|
|
|
return -EIO;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (identify_device(dev)) {
|
|
|
|
DEBUG("[cc110x] netdev_driver_t::init(): Device identification failed\n");
|
|
|
|
cc110x_release(dev);
|
|
|
|
return -ENOTSUP;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Upload the main configuration */
|
|
|
|
cc110x_burst_write(dev, CC110X_CONF_START, cc110x_conf, CC110X_CONF_SIZE);
|
|
|
|
/* Set TX power to match uploaded configuration */
|
|
|
|
dev->tx_power = CC110X_TX_POWER_0_DBM;
|
|
|
|
|
|
|
|
/* Upload the poorly documented magic numbers obtained via SmartRF Studio */
|
|
|
|
cc110x_burst_write(dev, CC110X_REG_TEST2, cc110x_magic_registers,
|
|
|
|
sizeof(cc110x_magic_registers));
|
|
|
|
|
|
|
|
/* Setup the selected PA_TABLE */
|
|
|
|
cc110x_burst_write(dev, CC110X_MULTIREG_PATABLE,
|
|
|
|
dev->params.patable->data, CC110X_PATABLE_LEN);
|
|
|
|
|
|
|
|
/* Verify main config, magic numbers and PA_TABLE correctly uploaded */
|
|
|
|
if (check_config(dev)) {
|
|
|
|
cc110x_release(dev);
|
|
|
|
return -EIO;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Verify that pins GDO2 and GDO0 are correctly connected */
|
|
|
|
if (check_gdo_pins(dev)) {
|
|
|
|
cc110x_release(dev);
|
|
|
|
return -EIO;
|
|
|
|
}
|
|
|
|
|
2021-04-03 18:07:37 +02:00
|
|
|
/* Setup the layer 2 address, but do not accept CC1XXX_BCAST_ADDR (which
|
drivers/cc110x: Rewrite of the cc110x driver
The cc110x driver has been re-written from scratch to overcome the limitations
of the old driver. The main motivation of the rewrite was to achieve better
maintainability by a detailed documentation, reduce the complexity and the
overhead of the SPI communication with the device, and to allow to
simultaneously use transceivers with different configuration regarding the used
base band, the channel bandwidth, the modulation rate, and the channel map.
Features of this driver include:
- Support for the CC1100, CC1101, and the CC1100e sub-gigahertz transceivers.
- Detailed documentation of every aspect of this driver.
- An easy to use configuration API that allows setting the transceiver
configuration (modulation rate, channel bandwidth, base frequency) and the
channel map.
- Fast channel hopping by pre-calibration of the channels during device
configuration (so that no calibration is needed during hopping).
- Simplified SPI communication: Only during start-up the MCU has to wait
for the transceiver to be ready (for the power regulators and the crystal
to stabilize). The old driver did this for every SPI transfer, which
resulted in complex communication code. This driver will wait on start up
for the transceiver to power up and then use RIOT's SPI API like every other
driver. (Not only the data sheet states that this is fine, it also proved to
be reliable in practise.)
- Greatly reduced latency: The RTT on the old driver (@150 kbps data rate) was
about 16ms, the new driver (@250 kbps data rate) has as RTT of ~3ms
(depending on SPI clock and on CPU performance) (measured with ping6).
- Increased reliability: The preamble size and the sync word size have been
doubled compared to the old driver (preamble: 8 bytes instead of 4,
sync word: 4 byte instead of 2). The new values are the once recommended by
the data sheet for reliable communication.
- Basic diagnostic during driver initialization to detect common issues as
SPI communication issues and GDO pin configuration/wiring issues.
- TX power configuration with netdev_driver_t::set() API-integration
- Calls to netdev_driver_t::send() block until the transmission has completed
to ease the use of the API (implemented without busy waiting, so that the
MCU can enter lower power states or other threads can be executed).
2018-11-08 17:37:07 +01:00
|
|
|
* has the value 0x00 and is used for broadcast)
|
|
|
|
*/
|
2021-04-03 18:07:37 +02:00
|
|
|
cc1xxx_eui_get(&dev->netdev, &dev->addr);
|
|
|
|
assert(dev->addr != CC1XXX_BCAST_ADDR);
|
drivers/cc110x: Rewrite of the cc110x driver
The cc110x driver has been re-written from scratch to overcome the limitations
of the old driver. The main motivation of the rewrite was to achieve better
maintainability by a detailed documentation, reduce the complexity and the
overhead of the SPI communication with the device, and to allow to
simultaneously use transceivers with different configuration regarding the used
base band, the channel bandwidth, the modulation rate, and the channel map.
Features of this driver include:
- Support for the CC1100, CC1101, and the CC1100e sub-gigahertz transceivers.
- Detailed documentation of every aspect of this driver.
- An easy to use configuration API that allows setting the transceiver
configuration (modulation rate, channel bandwidth, base frequency) and the
channel map.
- Fast channel hopping by pre-calibration of the channels during device
configuration (so that no calibration is needed during hopping).
- Simplified SPI communication: Only during start-up the MCU has to wait
for the transceiver to be ready (for the power regulators and the crystal
to stabilize). The old driver did this for every SPI transfer, which
resulted in complex communication code. This driver will wait on start up
for the transceiver to power up and then use RIOT's SPI API like every other
driver. (Not only the data sheet states that this is fine, it also proved to
be reliable in practise.)
- Greatly reduced latency: The RTT on the old driver (@150 kbps data rate) was
about 16ms, the new driver (@250 kbps data rate) has as RTT of ~3ms
(depending on SPI clock and on CPU performance) (measured with ping6).
- Increased reliability: The preamble size and the sync word size have been
doubled compared to the old driver (preamble: 8 bytes instead of 4,
sync word: 4 byte instead of 2). The new values are the once recommended by
the data sheet for reliable communication.
- Basic diagnostic during driver initialization to detect common issues as
SPI communication issues and GDO pin configuration/wiring issues.
- TX power configuration with netdev_driver_t::set() API-integration
- Calls to netdev_driver_t::send() block until the transmission has completed
to ease the use of the API (implemented without busy waiting, so that the
MCU can enter lower power states or other threads can be executed).
2018-11-08 17:37:07 +01:00
|
|
|
cc110x_write(dev, CC110X_REG_ADDR, dev->addr);
|
|
|
|
|
|
|
|
/* Setup interrupt on GDO0 */
|
|
|
|
if (gpio_init_int(dev->params.gdo0, GPIO_IN, GPIO_BOTH,
|
|
|
|
cc110x_on_gdo, dev)) {
|
|
|
|
cc110x_release(dev);
|
|
|
|
DEBUG("[cc110x] netdev_driver_t::init(): Failed to setup interrupt on "
|
|
|
|
"GDO0 pin\n");
|
|
|
|
return -EIO;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Setup interrupt on GDO2 */
|
|
|
|
if (gpio_init_int(dev->params.gdo2, GPIO_IN, GPIO_BOTH,
|
|
|
|
cc110x_on_gdo, dev)) {
|
|
|
|
gpio_irq_disable(dev->params.gdo0);
|
|
|
|
cc110x_release(dev);
|
|
|
|
DEBUG("[cc110x] netdev_driver_t::init(): Failed to setup interrupt on "
|
|
|
|
"GDO2 pin\n");
|
|
|
|
return -EIO;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Update the state of the driver/transceiver */
|
|
|
|
dev->state = CC110X_STATE_IDLE;
|
|
|
|
cc110x_release(dev);
|
|
|
|
|
|
|
|
int retval; /*< Store return value to be able to pass through error code */
|
|
|
|
/* Apply configuration (if non-NULL) and channel map, which also calls
|
|
|
|
* cc110x_full_calibration
|
|
|
|
*/
|
2019-08-21 14:33:48 +02:00
|
|
|
retval = cc110x_apply_config(dev, dev->params.config, dev->params.channels,
|
2020-04-17 19:57:01 +02:00
|
|
|
CONFIG_CC110X_DEFAULT_CHANNEL);
|
drivers/cc110x: Rewrite of the cc110x driver
The cc110x driver has been re-written from scratch to overcome the limitations
of the old driver. The main motivation of the rewrite was to achieve better
maintainability by a detailed documentation, reduce the complexity and the
overhead of the SPI communication with the device, and to allow to
simultaneously use transceivers with different configuration regarding the used
base band, the channel bandwidth, the modulation rate, and the channel map.
Features of this driver include:
- Support for the CC1100, CC1101, and the CC1100e sub-gigahertz transceivers.
- Detailed documentation of every aspect of this driver.
- An easy to use configuration API that allows setting the transceiver
configuration (modulation rate, channel bandwidth, base frequency) and the
channel map.
- Fast channel hopping by pre-calibration of the channels during device
configuration (so that no calibration is needed during hopping).
- Simplified SPI communication: Only during start-up the MCU has to wait
for the transceiver to be ready (for the power regulators and the crystal
to stabilize). The old driver did this for every SPI transfer, which
resulted in complex communication code. This driver will wait on start up
for the transceiver to power up and then use RIOT's SPI API like every other
driver. (Not only the data sheet states that this is fine, it also proved to
be reliable in practise.)
- Greatly reduced latency: The RTT on the old driver (@150 kbps data rate) was
about 16ms, the new driver (@250 kbps data rate) has as RTT of ~3ms
(depending on SPI clock and on CPU performance) (measured with ping6).
- Increased reliability: The preamble size and the sync word size have been
doubled compared to the old driver (preamble: 8 bytes instead of 4,
sync word: 4 byte instead of 2). The new values are the once recommended by
the data sheet for reliable communication.
- Basic diagnostic during driver initialization to detect common issues as
SPI communication issues and GDO pin configuration/wiring issues.
- TX power configuration with netdev_driver_t::set() API-integration
- Calls to netdev_driver_t::send() block until the transmission has completed
to ease the use of the API (implemented without busy waiting, so that the
MCU can enter lower power states or other threads can be executed).
2018-11-08 17:37:07 +01:00
|
|
|
if (retval) {
|
|
|
|
gpio_irq_disable(dev->params.gdo0);
|
|
|
|
gpio_irq_disable(dev->params.gdo2);
|
|
|
|
DEBUG("[cc110x] netdev_driver_t::init(): cc110x_apply_config() "
|
|
|
|
"failed\n");
|
2019-08-21 14:33:48 +02:00
|
|
|
/* Pass through received error code */
|
drivers/cc110x: Rewrite of the cc110x driver
The cc110x driver has been re-written from scratch to overcome the limitations
of the old driver. The main motivation of the rewrite was to achieve better
maintainability by a detailed documentation, reduce the complexity and the
overhead of the SPI communication with the device, and to allow to
simultaneously use transceivers with different configuration regarding the used
base band, the channel bandwidth, the modulation rate, and the channel map.
Features of this driver include:
- Support for the CC1100, CC1101, and the CC1100e sub-gigahertz transceivers.
- Detailed documentation of every aspect of this driver.
- An easy to use configuration API that allows setting the transceiver
configuration (modulation rate, channel bandwidth, base frequency) and the
channel map.
- Fast channel hopping by pre-calibration of the channels during device
configuration (so that no calibration is needed during hopping).
- Simplified SPI communication: Only during start-up the MCU has to wait
for the transceiver to be ready (for the power regulators and the crystal
to stabilize). The old driver did this for every SPI transfer, which
resulted in complex communication code. This driver will wait on start up
for the transceiver to power up and then use RIOT's SPI API like every other
driver. (Not only the data sheet states that this is fine, it also proved to
be reliable in practise.)
- Greatly reduced latency: The RTT on the old driver (@150 kbps data rate) was
about 16ms, the new driver (@250 kbps data rate) has as RTT of ~3ms
(depending on SPI clock and on CPU performance) (measured with ping6).
- Increased reliability: The preamble size and the sync word size have been
doubled compared to the old driver (preamble: 8 bytes instead of 4,
sync word: 4 byte instead of 2). The new values are the once recommended by
the data sheet for reliable communication.
- Basic diagnostic during driver initialization to detect common issues as
SPI communication issues and GDO pin configuration/wiring issues.
- TX power configuration with netdev_driver_t::set() API-integration
- Calls to netdev_driver_t::send() block until the transmission has completed
to ease the use of the API (implemented without busy waiting, so that the
MCU can enter lower power states or other threads can be executed).
2018-11-08 17:37:07 +01:00
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
2019-08-21 14:33:48 +02:00
|
|
|
DEBUG("[cc110x] netdev_driver_t::init(): Success\n");
|
2022-08-18 12:02:47 +02:00
|
|
|
|
|
|
|
/* signal link UP */
|
|
|
|
netdev->event_callback(netdev, NETDEV_EVENT_LINK_UP);
|
|
|
|
|
drivers/cc110x: Rewrite of the cc110x driver
The cc110x driver has been re-written from scratch to overcome the limitations
of the old driver. The main motivation of the rewrite was to achieve better
maintainability by a detailed documentation, reduce the complexity and the
overhead of the SPI communication with the device, and to allow to
simultaneously use transceivers with different configuration regarding the used
base band, the channel bandwidth, the modulation rate, and the channel map.
Features of this driver include:
- Support for the CC1100, CC1101, and the CC1100e sub-gigahertz transceivers.
- Detailed documentation of every aspect of this driver.
- An easy to use configuration API that allows setting the transceiver
configuration (modulation rate, channel bandwidth, base frequency) and the
channel map.
- Fast channel hopping by pre-calibration of the channels during device
configuration (so that no calibration is needed during hopping).
- Simplified SPI communication: Only during start-up the MCU has to wait
for the transceiver to be ready (for the power regulators and the crystal
to stabilize). The old driver did this for every SPI transfer, which
resulted in complex communication code. This driver will wait on start up
for the transceiver to power up and then use RIOT's SPI API like every other
driver. (Not only the data sheet states that this is fine, it also proved to
be reliable in practise.)
- Greatly reduced latency: The RTT on the old driver (@150 kbps data rate) was
about 16ms, the new driver (@250 kbps data rate) has as RTT of ~3ms
(depending on SPI clock and on CPU performance) (measured with ping6).
- Increased reliability: The preamble size and the sync word size have been
doubled compared to the old driver (preamble: 8 bytes instead of 4,
sync word: 4 byte instead of 2). The new values are the once recommended by
the data sheet for reliable communication.
- Basic diagnostic during driver initialization to detect common issues as
SPI communication issues and GDO pin configuration/wiring issues.
- TX power configuration with netdev_driver_t::set() API-integration
- Calls to netdev_driver_t::send() block until the transmission has completed
to ease the use of the API (implemented without busy waiting, so that the
MCU can enter lower power states or other threads can be executed).
2018-11-08 17:37:07 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int cc110x_recv(netdev_t *netdev, void *buf, size_t len, void *info)
|
|
|
|
{
|
|
|
|
cc110x_t *dev = (cc110x_t *)netdev;
|
|
|
|
|
|
|
|
/* Call to cc110x_enter_rx_mode() will clear dev->buf.len, so back up it first */
|
|
|
|
int size = dev->buf.len;
|
|
|
|
|
2021-02-01 14:25:22 +01:00
|
|
|
cc110x_acquire(dev);
|
drivers/cc110x: Rewrite of the cc110x driver
The cc110x driver has been re-written from scratch to overcome the limitations
of the old driver. The main motivation of the rewrite was to achieve better
maintainability by a detailed documentation, reduce the complexity and the
overhead of the SPI communication with the device, and to allow to
simultaneously use transceivers with different configuration regarding the used
base band, the channel bandwidth, the modulation rate, and the channel map.
Features of this driver include:
- Support for the CC1100, CC1101, and the CC1100e sub-gigahertz transceivers.
- Detailed documentation of every aspect of this driver.
- An easy to use configuration API that allows setting the transceiver
configuration (modulation rate, channel bandwidth, base frequency) and the
channel map.
- Fast channel hopping by pre-calibration of the channels during device
configuration (so that no calibration is needed during hopping).
- Simplified SPI communication: Only during start-up the MCU has to wait
for the transceiver to be ready (for the power regulators and the crystal
to stabilize). The old driver did this for every SPI transfer, which
resulted in complex communication code. This driver will wait on start up
for the transceiver to power up and then use RIOT's SPI API like every other
driver. (Not only the data sheet states that this is fine, it also proved to
be reliable in practise.)
- Greatly reduced latency: The RTT on the old driver (@150 kbps data rate) was
about 16ms, the new driver (@250 kbps data rate) has as RTT of ~3ms
(depending on SPI clock and on CPU performance) (measured with ping6).
- Increased reliability: The preamble size and the sync word size have been
doubled compared to the old driver (preamble: 8 bytes instead of 4,
sync word: 4 byte instead of 2). The new values are the once recommended by
the data sheet for reliable communication.
- Basic diagnostic during driver initialization to detect common issues as
SPI communication issues and GDO pin configuration/wiring issues.
- TX power configuration with netdev_driver_t::set() API-integration
- Calls to netdev_driver_t::send() block until the transmission has completed
to ease the use of the API (implemented without busy waiting, so that the
MCU can enter lower power states or other threads can be executed).
2018-11-08 17:37:07 +01:00
|
|
|
|
|
|
|
/* Copy RX info on last frame (if requested) */
|
|
|
|
if (info != NULL) {
|
|
|
|
*((cc1xxx_rx_info_t *)info) = dev->rx_info;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!buf) {
|
|
|
|
/* Get the size of the frame; if len > 0 then also drop the frame */
|
|
|
|
if (len > 0) {
|
|
|
|
/* Drop frame requested */
|
|
|
|
cc110x_enter_rx_mode(dev);
|
|
|
|
}
|
|
|
|
cc110x_release(dev);
|
|
|
|
return size;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (len < (size_t)size) {
|
|
|
|
/* Drop frame and return -ENOBUFS */
|
|
|
|
cc110x_enter_rx_mode(dev);
|
|
|
|
cc110x_release(dev);
|
|
|
|
return -ENOBUFS;
|
|
|
|
}
|
|
|
|
|
|
|
|
memcpy(buf, dev->buf.data, (size_t)size);
|
|
|
|
|
|
|
|
cc110x_enter_rx_mode(dev);
|
|
|
|
cc110x_release(dev);
|
|
|
|
return size;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int cc110x_send(netdev_t *netdev, const iolist_t *iolist)
|
|
|
|
{
|
|
|
|
cc110x_t *dev = (cc110x_t *)netdev;
|
|
|
|
|
|
|
|
/* assert that cc110x_send was called with valid parameters */
|
|
|
|
assert(netdev && iolist && (iolist->iol_len == sizeof(cc1xxx_l2hdr_t)));
|
|
|
|
|
2021-02-01 14:25:22 +01:00
|
|
|
cc110x_acquire(dev);
|
drivers/cc110x: Rewrite of the cc110x driver
The cc110x driver has been re-written from scratch to overcome the limitations
of the old driver. The main motivation of the rewrite was to achieve better
maintainability by a detailed documentation, reduce the complexity and the
overhead of the SPI communication with the device, and to allow to
simultaneously use transceivers with different configuration regarding the used
base band, the channel bandwidth, the modulation rate, and the channel map.
Features of this driver include:
- Support for the CC1100, CC1101, and the CC1100e sub-gigahertz transceivers.
- Detailed documentation of every aspect of this driver.
- An easy to use configuration API that allows setting the transceiver
configuration (modulation rate, channel bandwidth, base frequency) and the
channel map.
- Fast channel hopping by pre-calibration of the channels during device
configuration (so that no calibration is needed during hopping).
- Simplified SPI communication: Only during start-up the MCU has to wait
for the transceiver to be ready (for the power regulators and the crystal
to stabilize). The old driver did this for every SPI transfer, which
resulted in complex communication code. This driver will wait on start up
for the transceiver to power up and then use RIOT's SPI API like every other
driver. (Not only the data sheet states that this is fine, it also proved to
be reliable in practise.)
- Greatly reduced latency: The RTT on the old driver (@150 kbps data rate) was
about 16ms, the new driver (@250 kbps data rate) has as RTT of ~3ms
(depending on SPI clock and on CPU performance) (measured with ping6).
- Increased reliability: The preamble size and the sync word size have been
doubled compared to the old driver (preamble: 8 bytes instead of 4,
sync word: 4 byte instead of 2). The new values are the once recommended by
the data sheet for reliable communication.
- Basic diagnostic during driver initialization to detect common issues as
SPI communication issues and GDO pin configuration/wiring issues.
- TX power configuration with netdev_driver_t::set() API-integration
- Calls to netdev_driver_t::send() block until the transmission has completed
to ease the use of the API (implemented without busy waiting, so that the
MCU can enter lower power states or other threads can be executed).
2018-11-08 17:37:07 +01:00
|
|
|
|
|
|
|
switch (dev->state) {
|
2019-08-14 17:31:33 +02:00
|
|
|
case CC110X_STATE_FSTXON:
|
|
|
|
/* falls through */
|
|
|
|
case CC110X_STATE_RX_MODE:
|
|
|
|
break;
|
|
|
|
case CC110X_STATE_RECEIVING:
|
|
|
|
cc110x_release(dev);
|
|
|
|
DEBUG("[cc110x] netdev_driver_t::send(): Refusing to send while "
|
|
|
|
"receiving a frame\n");
|
|
|
|
return -EBUSY;
|
|
|
|
case CC110X_STATE_OFF:
|
|
|
|
cc110x_release(dev);
|
|
|
|
return -ENOTSUP;
|
|
|
|
default:
|
|
|
|
cc110x_release(dev);
|
|
|
|
DEBUG("[cc110x] netdev_driver_t::send(): Driver state %i prevents "
|
|
|
|
"sending\n", (int)dev->state);
|
|
|
|
return -1;
|
drivers/cc110x: Rewrite of the cc110x driver
The cc110x driver has been re-written from scratch to overcome the limitations
of the old driver. The main motivation of the rewrite was to achieve better
maintainability by a detailed documentation, reduce the complexity and the
overhead of the SPI communication with the device, and to allow to
simultaneously use transceivers with different configuration regarding the used
base band, the channel bandwidth, the modulation rate, and the channel map.
Features of this driver include:
- Support for the CC1100, CC1101, and the CC1100e sub-gigahertz transceivers.
- Detailed documentation of every aspect of this driver.
- An easy to use configuration API that allows setting the transceiver
configuration (modulation rate, channel bandwidth, base frequency) and the
channel map.
- Fast channel hopping by pre-calibration of the channels during device
configuration (so that no calibration is needed during hopping).
- Simplified SPI communication: Only during start-up the MCU has to wait
for the transceiver to be ready (for the power regulators and the crystal
to stabilize). The old driver did this for every SPI transfer, which
resulted in complex communication code. This driver will wait on start up
for the transceiver to power up and then use RIOT's SPI API like every other
driver. (Not only the data sheet states that this is fine, it also proved to
be reliable in practise.)
- Greatly reduced latency: The RTT on the old driver (@150 kbps data rate) was
about 16ms, the new driver (@250 kbps data rate) has as RTT of ~3ms
(depending on SPI clock and on CPU performance) (measured with ping6).
- Increased reliability: The preamble size and the sync word size have been
doubled compared to the old driver (preamble: 8 bytes instead of 4,
sync word: 4 byte instead of 2). The new values are the once recommended by
the data sheet for reliable communication.
- Basic diagnostic during driver initialization to detect common issues as
SPI communication issues and GDO pin configuration/wiring issues.
- TX power configuration with netdev_driver_t::set() API-integration
- Calls to netdev_driver_t::send() block until the transmission has completed
to ease the use of the API (implemented without busy waiting, so that the
MCU can enter lower power states or other threads can be executed).
2018-11-08 17:37:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Copy data to send into frame buffer */
|
|
|
|
size_t size = sizeof(cc1xxx_l2hdr_t);
|
|
|
|
memcpy(dev->buf.data, iolist->iol_base, sizeof(cc1xxx_l2hdr_t));
|
|
|
|
|
|
|
|
for (const iolist_t *iol = iolist->iol_next; iol; iol = iol->iol_next) {
|
|
|
|
if (iol->iol_len) {
|
|
|
|
if (size + iol->iol_len > CC110X_MAX_FRAME_SIZE) {
|
|
|
|
cc110x_release(dev);
|
2023-12-18 17:41:57 +01:00
|
|
|
DEBUG("[cc110x] netdev_driver_t::send(): Frame size of %"
|
|
|
|
PRIuSIZE "B exceeds maximum supported size of %uB\n",
|
|
|
|
size + iol->iol_len, (unsigned)CC110X_MAX_FRAME_SIZE);
|
drivers/cc110x: Rewrite of the cc110x driver
The cc110x driver has been re-written from scratch to overcome the limitations
of the old driver. The main motivation of the rewrite was to achieve better
maintainability by a detailed documentation, reduce the complexity and the
overhead of the SPI communication with the device, and to allow to
simultaneously use transceivers with different configuration regarding the used
base band, the channel bandwidth, the modulation rate, and the channel map.
Features of this driver include:
- Support for the CC1100, CC1101, and the CC1100e sub-gigahertz transceivers.
- Detailed documentation of every aspect of this driver.
- An easy to use configuration API that allows setting the transceiver
configuration (modulation rate, channel bandwidth, base frequency) and the
channel map.
- Fast channel hopping by pre-calibration of the channels during device
configuration (so that no calibration is needed during hopping).
- Simplified SPI communication: Only during start-up the MCU has to wait
for the transceiver to be ready (for the power regulators and the crystal
to stabilize). The old driver did this for every SPI transfer, which
resulted in complex communication code. This driver will wait on start up
for the transceiver to power up and then use RIOT's SPI API like every other
driver. (Not only the data sheet states that this is fine, it also proved to
be reliable in practise.)
- Greatly reduced latency: The RTT on the old driver (@150 kbps data rate) was
about 16ms, the new driver (@250 kbps data rate) has as RTT of ~3ms
(depending on SPI clock and on CPU performance) (measured with ping6).
- Increased reliability: The preamble size and the sync word size have been
doubled compared to the old driver (preamble: 8 bytes instead of 4,
sync word: 4 byte instead of 2). The new values are the once recommended by
the data sheet for reliable communication.
- Basic diagnostic during driver initialization to detect common issues as
SPI communication issues and GDO pin configuration/wiring issues.
- TX power configuration with netdev_driver_t::set() API-integration
- Calls to netdev_driver_t::send() block until the transmission has completed
to ease the use of the API (implemented without busy waiting, so that the
MCU can enter lower power states or other threads can be executed).
2018-11-08 17:37:07 +01:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
memcpy(dev->buf.data + size, iol->iol_base, iol->iol_len);
|
|
|
|
size += iol->iol_len;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
dev->buf.len = (uint8_t)size;
|
|
|
|
|
|
|
|
/* Disable IRQs, as GDO configuration will be changed now */
|
|
|
|
gpio_irq_disable(dev->params.gdo0);
|
|
|
|
gpio_irq_disable(dev->params.gdo2);
|
|
|
|
|
|
|
|
/* Fill the TX FIFO: First write the length, then the frame */
|
|
|
|
dev->buf.pos = (size > CC110X_FIFO_SIZE - 1) ? CC110X_FIFO_SIZE - 1 : size;
|
|
|
|
/* cc110x_framebuf_t has the same memory layout as the device expects */
|
|
|
|
cc110x_burst_write(dev, CC110X_MULTIREG_FIFO,
|
|
|
|
&dev->buf, dev->buf.pos + 1);
|
|
|
|
|
|
|
|
/* Go to TX */
|
|
|
|
cc110x_cmd(dev, CC110X_STROBE_TX);
|
|
|
|
|
|
|
|
/* Configure GDO2 and update state */
|
|
|
|
if (dev->buf.pos < dev->buf.len) {
|
|
|
|
/* We need to keep feeding TX FIFO */
|
|
|
|
cc110x_write(dev, CC110X_REG_IOCFG2, CC110X_GDO_ON_TX_DATA);
|
|
|
|
dev->state = CC110X_STATE_TX_MODE;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
/* All data in TX FIFO, just waiting for transceiver to finish */
|
|
|
|
cc110x_write(dev, CC110X_REG_IOCFG2, CC110X_GDO_CONSTANT_LOW);
|
|
|
|
dev->state = CC110X_STATE_TX_COMPLETING;
|
|
|
|
}
|
|
|
|
|
|
|
|
cc110x_release(dev);
|
|
|
|
|
|
|
|
/* Restore IRQs */
|
|
|
|
gpio_irq_enable(dev->params.gdo0);
|
|
|
|
gpio_irq_enable(dev->params.gdo2);
|
|
|
|
|
|
|
|
while ((dev->state & 0x07) == CC110X_STATE_TX_MODE) {
|
2020-03-08 11:56:49 +01:00
|
|
|
uint64_t timeout = (dev->state != CC110X_STATE_TX_COMPLETING) ?
|
|
|
|
2048 : 1024;
|
|
|
|
/* Block until mutex is unlocked from ISR, or a timeout occurs. The
|
|
|
|
* timeout prevents deadlocks when IRQs are lost. If the TX FIFO
|
|
|
|
* still needs to be filled, the timeout is 1024 µs - or after 32 Byte
|
|
|
|
* (= 50%) of the FIFO have been transmitted at 250 kbps. If
|
|
|
|
* no additional data needs to be fed into the FIFO, a timeout of
|
|
|
|
* 2048 µs is used instead to allow the frame to be completely drained
|
|
|
|
* before the timeout triggers. The ISR handler is prepared to be
|
|
|
|
* called prematurely, so we don't need to worry about extra calls
|
|
|
|
* to cc110x_isr() introduced by accident.
|
|
|
|
*/
|
|
|
|
xtimer_mutex_lock_timeout(&dev->isr_signal, timeout);
|
drivers/cc110x: Rewrite of the cc110x driver
The cc110x driver has been re-written from scratch to overcome the limitations
of the old driver. The main motivation of the rewrite was to achieve better
maintainability by a detailed documentation, reduce the complexity and the
overhead of the SPI communication with the device, and to allow to
simultaneously use transceivers with different configuration regarding the used
base band, the channel bandwidth, the modulation rate, and the channel map.
Features of this driver include:
- Support for the CC1100, CC1101, and the CC1100e sub-gigahertz transceivers.
- Detailed documentation of every aspect of this driver.
- An easy to use configuration API that allows setting the transceiver
configuration (modulation rate, channel bandwidth, base frequency) and the
channel map.
- Fast channel hopping by pre-calibration of the channels during device
configuration (so that no calibration is needed during hopping).
- Simplified SPI communication: Only during start-up the MCU has to wait
for the transceiver to be ready (for the power regulators and the crystal
to stabilize). The old driver did this for every SPI transfer, which
resulted in complex communication code. This driver will wait on start up
for the transceiver to power up and then use RIOT's SPI API like every other
driver. (Not only the data sheet states that this is fine, it also proved to
be reliable in practise.)
- Greatly reduced latency: The RTT on the old driver (@150 kbps data rate) was
about 16ms, the new driver (@250 kbps data rate) has as RTT of ~3ms
(depending on SPI clock and on CPU performance) (measured with ping6).
- Increased reliability: The preamble size and the sync word size have been
doubled compared to the old driver (preamble: 8 bytes instead of 4,
sync word: 4 byte instead of 2). The new values are the once recommended by
the data sheet for reliable communication.
- Basic diagnostic during driver initialization to detect common issues as
SPI communication issues and GDO pin configuration/wiring issues.
- TX power configuration with netdev_driver_t::set() API-integration
- Calls to netdev_driver_t::send() block until the transmission has completed
to ease the use of the API (implemented without busy waiting, so that the
MCU can enter lower power states or other threads can be executed).
2018-11-08 17:37:07 +01:00
|
|
|
cc110x_isr(&dev->netdev);
|
|
|
|
}
|
|
|
|
|
|
|
|
return (int)size;
|
|
|
|
}
|
|
|
|
|
2020-01-23 14:47:19 +01:00
|
|
|
/**
|
|
|
|
* @brief Checks if the CC110x's address filter is disabled
|
|
|
|
* @param dev Transceiver to check if in promiscuous mode
|
|
|
|
* @param dest Store the result here
|
|
|
|
*
|
|
|
|
* @return Returns the size of @ref netopt_enable_t to confirm with the API
|
|
|
|
* in @ref netdev_driver_t::get
|
|
|
|
*/
|
|
|
|
static int cc110x_get_promiscuous_mode(cc110x_t *dev, netopt_enable_t *dest)
|
|
|
|
{
|
2021-02-01 14:25:22 +01:00
|
|
|
cc110x_acquire(dev);
|
2020-01-23 14:47:19 +01:00
|
|
|
|
|
|
|
uint8_t pktctrl1;
|
|
|
|
cc110x_read(dev, CC110X_REG_PKTCTRL1, &pktctrl1);
|
|
|
|
*dest = ((pktctrl1 & CC110X_PKTCTRL1_GET_ADDR_MODE) == CC110X_PKTCTRL1_ADDR_ALL);
|
|
|
|
cc110x_release(dev);
|
|
|
|
return sizeof(netopt_enable_t);
|
|
|
|
}
|
|
|
|
|
drivers/cc110x: Rewrite of the cc110x driver
The cc110x driver has been re-written from scratch to overcome the limitations
of the old driver. The main motivation of the rewrite was to achieve better
maintainability by a detailed documentation, reduce the complexity and the
overhead of the SPI communication with the device, and to allow to
simultaneously use transceivers with different configuration regarding the used
base band, the channel bandwidth, the modulation rate, and the channel map.
Features of this driver include:
- Support for the CC1100, CC1101, and the CC1100e sub-gigahertz transceivers.
- Detailed documentation of every aspect of this driver.
- An easy to use configuration API that allows setting the transceiver
configuration (modulation rate, channel bandwidth, base frequency) and the
channel map.
- Fast channel hopping by pre-calibration of the channels during device
configuration (so that no calibration is needed during hopping).
- Simplified SPI communication: Only during start-up the MCU has to wait
for the transceiver to be ready (for the power regulators and the crystal
to stabilize). The old driver did this for every SPI transfer, which
resulted in complex communication code. This driver will wait on start up
for the transceiver to power up and then use RIOT's SPI API like every other
driver. (Not only the data sheet states that this is fine, it also proved to
be reliable in practise.)
- Greatly reduced latency: The RTT on the old driver (@150 kbps data rate) was
about 16ms, the new driver (@250 kbps data rate) has as RTT of ~3ms
(depending on SPI clock and on CPU performance) (measured with ping6).
- Increased reliability: The preamble size and the sync word size have been
doubled compared to the old driver (preamble: 8 bytes instead of 4,
sync word: 4 byte instead of 2). The new values are the once recommended by
the data sheet for reliable communication.
- Basic diagnostic during driver initialization to detect common issues as
SPI communication issues and GDO pin configuration/wiring issues.
- TX power configuration with netdev_driver_t::set() API-integration
- Calls to netdev_driver_t::send() block until the transmission has completed
to ease the use of the API (implemented without busy waiting, so that the
MCU can enter lower power states or other threads can be executed).
2018-11-08 17:37:07 +01:00
|
|
|
static int cc110x_get(netdev_t *netdev, netopt_t opt,
|
|
|
|
void *val, size_t max_len)
|
|
|
|
{
|
|
|
|
cc110x_t *dev = (cc110x_t *)netdev;
|
|
|
|
|
2020-06-25 10:55:22 +02:00
|
|
|
(void)max_len; /* only used in assert() */
|
drivers/cc110x: Rewrite of the cc110x driver
The cc110x driver has been re-written from scratch to overcome the limitations
of the old driver. The main motivation of the rewrite was to achieve better
maintainability by a detailed documentation, reduce the complexity and the
overhead of the SPI communication with the device, and to allow to
simultaneously use transceivers with different configuration regarding the used
base band, the channel bandwidth, the modulation rate, and the channel map.
Features of this driver include:
- Support for the CC1100, CC1101, and the CC1100e sub-gigahertz transceivers.
- Detailed documentation of every aspect of this driver.
- An easy to use configuration API that allows setting the transceiver
configuration (modulation rate, channel bandwidth, base frequency) and the
channel map.
- Fast channel hopping by pre-calibration of the channels during device
configuration (so that no calibration is needed during hopping).
- Simplified SPI communication: Only during start-up the MCU has to wait
for the transceiver to be ready (for the power regulators and the crystal
to stabilize). The old driver did this for every SPI transfer, which
resulted in complex communication code. This driver will wait on start up
for the transceiver to power up and then use RIOT's SPI API like every other
driver. (Not only the data sheet states that this is fine, it also proved to
be reliable in practise.)
- Greatly reduced latency: The RTT on the old driver (@150 kbps data rate) was
about 16ms, the new driver (@250 kbps data rate) has as RTT of ~3ms
(depending on SPI clock and on CPU performance) (measured with ping6).
- Increased reliability: The preamble size and the sync word size have been
doubled compared to the old driver (preamble: 8 bytes instead of 4,
sync word: 4 byte instead of 2). The new values are the once recommended by
the data sheet for reliable communication.
- Basic diagnostic during driver initialization to detect common issues as
SPI communication issues and GDO pin configuration/wiring issues.
- TX power configuration with netdev_driver_t::set() API-integration
- Calls to netdev_driver_t::send() block until the transmission has completed
to ease the use of the API (implemented without busy waiting, so that the
MCU can enter lower power states or other threads can be executed).
2018-11-08 17:37:07 +01:00
|
|
|
switch (opt) {
|
2021-03-26 20:38:18 +01:00
|
|
|
case NETOPT_DEVICE_TYPE:
|
|
|
|
assert(max_len == sizeof(uint16_t));
|
|
|
|
*((uint16_t *)val) = NETDEV_TYPE_CC110X;
|
|
|
|
return sizeof(uint16_t);
|
|
|
|
case NETOPT_PROTO:
|
|
|
|
assert(max_len == sizeof(gnrc_nettype_t));
|
|
|
|
*((gnrc_nettype_t *)val) = CC110X_DEFAULT_PROTOCOL;
|
|
|
|
return sizeof(gnrc_nettype_t);
|
|
|
|
case NETOPT_MAX_PDU_SIZE:
|
|
|
|
assert(max_len == sizeof(uint16_t));
|
|
|
|
*((uint16_t *)val) = CC110X_MAX_FRAME_SIZE - sizeof(cc1xxx_l2hdr_t);
|
|
|
|
return sizeof(uint16_t);
|
|
|
|
case NETOPT_ADDR_LEN:
|
|
|
|
/* falls through */
|
|
|
|
case NETOPT_SRC_LEN:
|
|
|
|
assert(max_len == sizeof(uint16_t));
|
|
|
|
*((uint16_t *)val) = CC1XXX_ADDR_SIZE;
|
|
|
|
return sizeof(uint16_t);
|
|
|
|
case NETOPT_ADDRESS:
|
|
|
|
assert(max_len >= CC1XXX_ADDR_SIZE);
|
|
|
|
*((uint8_t *)val) = dev->addr;
|
|
|
|
return CC1XXX_ADDR_SIZE;
|
|
|
|
case NETOPT_CHANNEL:
|
|
|
|
assert(max_len == sizeof(uint16_t));
|
|
|
|
*((uint16_t *)val) = dev->channel;
|
|
|
|
return sizeof(uint16_t);
|
|
|
|
case NETOPT_TX_POWER:
|
|
|
|
assert(max_len == sizeof(uint16_t));
|
|
|
|
*((uint16_t *)val) = dbm_from_tx_power[dev->tx_power];
|
|
|
|
return sizeof(uint16_t);
|
|
|
|
case NETOPT_PROMISCUOUSMODE:
|
|
|
|
assert(max_len == sizeof(netopt_enable_t));
|
|
|
|
return cc110x_get_promiscuous_mode(dev, val);
|
|
|
|
case NETOPT_STATE:
|
|
|
|
assert(max_len == sizeof(netopt_state_t));
|
|
|
|
{
|
|
|
|
netopt_state_t *state = val;
|
|
|
|
switch (dev->state) {
|
|
|
|
case CC110X_STATE_RECEIVING:
|
|
|
|
case CC110X_STATE_FRAME_READY:
|
|
|
|
case CC110X_STATE_RXFIFO_OVERFLOW:
|
|
|
|
*state = NETOPT_STATE_RX;
|
|
|
|
break;
|
|
|
|
case CC110X_STATE_IDLE:
|
|
|
|
*state = NETOPT_STATE_STANDBY;
|
|
|
|
break;
|
|
|
|
case CC110X_STATE_OFF:
|
|
|
|
*state = NETOPT_STATE_SLEEP;
|
|
|
|
break;
|
|
|
|
case CC110X_STATE_TX_MODE:
|
|
|
|
case CC110X_STATE_TX_COMPLETING:
|
|
|
|
case CC110X_STATE_TXFIFO_UNDERFLOW:
|
|
|
|
*state = NETOPT_STATE_TX;
|
|
|
|
break;
|
|
|
|
case CC110X_STATE_RX_MODE:
|
|
|
|
*state = NETOPT_STATE_IDLE;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
*state = NETOPT_STATE_RESET;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
drivers/cc110x: Rewrite of the cc110x driver
The cc110x driver has been re-written from scratch to overcome the limitations
of the old driver. The main motivation of the rewrite was to achieve better
maintainability by a detailed documentation, reduce the complexity and the
overhead of the SPI communication with the device, and to allow to
simultaneously use transceivers with different configuration regarding the used
base band, the channel bandwidth, the modulation rate, and the channel map.
Features of this driver include:
- Support for the CC1100, CC1101, and the CC1100e sub-gigahertz transceivers.
- Detailed documentation of every aspect of this driver.
- An easy to use configuration API that allows setting the transceiver
configuration (modulation rate, channel bandwidth, base frequency) and the
channel map.
- Fast channel hopping by pre-calibration of the channels during device
configuration (so that no calibration is needed during hopping).
- Simplified SPI communication: Only during start-up the MCU has to wait
for the transceiver to be ready (for the power regulators and the crystal
to stabilize). The old driver did this for every SPI transfer, which
resulted in complex communication code. This driver will wait on start up
for the transceiver to power up and then use RIOT's SPI API like every other
driver. (Not only the data sheet states that this is fine, it also proved to
be reliable in practise.)
- Greatly reduced latency: The RTT on the old driver (@150 kbps data rate) was
about 16ms, the new driver (@250 kbps data rate) has as RTT of ~3ms
(depending on SPI clock and on CPU performance) (measured with ping6).
- Increased reliability: The preamble size and the sync word size have been
doubled compared to the old driver (preamble: 8 bytes instead of 4,
sync word: 4 byte instead of 2). The new values are the once recommended by
the data sheet for reliable communication.
- Basic diagnostic during driver initialization to detect common issues as
SPI communication issues and GDO pin configuration/wiring issues.
- TX power configuration with netdev_driver_t::set() API-integration
- Calls to netdev_driver_t::send() block until the transmission has completed
to ease the use of the API (implemented without busy waiting, so that the
MCU can enter lower power states or other threads can be executed).
2018-11-08 17:37:07 +01:00
|
|
|
}
|
2021-03-26 20:38:18 +01:00
|
|
|
return -ENOTSUP;
|
drivers/cc110x: Rewrite of the cc110x driver
The cc110x driver has been re-written from scratch to overcome the limitations
of the old driver. The main motivation of the rewrite was to achieve better
maintainability by a detailed documentation, reduce the complexity and the
overhead of the SPI communication with the device, and to allow to
simultaneously use transceivers with different configuration regarding the used
base band, the channel bandwidth, the modulation rate, and the channel map.
Features of this driver include:
- Support for the CC1100, CC1101, and the CC1100e sub-gigahertz transceivers.
- Detailed documentation of every aspect of this driver.
- An easy to use configuration API that allows setting the transceiver
configuration (modulation rate, channel bandwidth, base frequency) and the
channel map.
- Fast channel hopping by pre-calibration of the channels during device
configuration (so that no calibration is needed during hopping).
- Simplified SPI communication: Only during start-up the MCU has to wait
for the transceiver to be ready (for the power regulators and the crystal
to stabilize). The old driver did this for every SPI transfer, which
resulted in complex communication code. This driver will wait on start up
for the transceiver to power up and then use RIOT's SPI API like every other
driver. (Not only the data sheet states that this is fine, it also proved to
be reliable in practise.)
- Greatly reduced latency: The RTT on the old driver (@150 kbps data rate) was
about 16ms, the new driver (@250 kbps data rate) has as RTT of ~3ms
(depending on SPI clock and on CPU performance) (measured with ping6).
- Increased reliability: The preamble size and the sync word size have been
doubled compared to the old driver (preamble: 8 bytes instead of 4,
sync word: 4 byte instead of 2). The new values are the once recommended by
the data sheet for reliable communication.
- Basic diagnostic during driver initialization to detect common issues as
SPI communication issues and GDO pin configuration/wiring issues.
- TX power configuration with netdev_driver_t::set() API-integration
- Calls to netdev_driver_t::send() block until the transmission has completed
to ease the use of the API (implemented without busy waiting, so that the
MCU can enter lower power states or other threads can be executed).
2018-11-08 17:37:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2019-09-04 13:15:15 +02:00
|
|
|
* @brief Set the given address as the device's layer 2 address
|
drivers/cc110x: Rewrite of the cc110x driver
The cc110x driver has been re-written from scratch to overcome the limitations
of the old driver. The main motivation of the rewrite was to achieve better
maintainability by a detailed documentation, reduce the complexity and the
overhead of the SPI communication with the device, and to allow to
simultaneously use transceivers with different configuration regarding the used
base band, the channel bandwidth, the modulation rate, and the channel map.
Features of this driver include:
- Support for the CC1100, CC1101, and the CC1100e sub-gigahertz transceivers.
- Detailed documentation of every aspect of this driver.
- An easy to use configuration API that allows setting the transceiver
configuration (modulation rate, channel bandwidth, base frequency) and the
channel map.
- Fast channel hopping by pre-calibration of the channels during device
configuration (so that no calibration is needed during hopping).
- Simplified SPI communication: Only during start-up the MCU has to wait
for the transceiver to be ready (for the power regulators and the crystal
to stabilize). The old driver did this for every SPI transfer, which
resulted in complex communication code. This driver will wait on start up
for the transceiver to power up and then use RIOT's SPI API like every other
driver. (Not only the data sheet states that this is fine, it also proved to
be reliable in practise.)
- Greatly reduced latency: The RTT on the old driver (@150 kbps data rate) was
about 16ms, the new driver (@250 kbps data rate) has as RTT of ~3ms
(depending on SPI clock and on CPU performance) (measured with ping6).
- Increased reliability: The preamble size and the sync word size have been
doubled compared to the old driver (preamble: 8 bytes instead of 4,
sync word: 4 byte instead of 2). The new values are the once recommended by
the data sheet for reliable communication.
- Basic diagnostic during driver initialization to detect common issues as
SPI communication issues and GDO pin configuration/wiring issues.
- TX power configuration with netdev_driver_t::set() API-integration
- Calls to netdev_driver_t::send() block until the transmission has completed
to ease the use of the API (implemented without busy waiting, so that the
MCU can enter lower power states or other threads can be executed).
2018-11-08 17:37:07 +01:00
|
|
|
*
|
2022-09-16 13:28:48 +02:00
|
|
|
* @param dev Device descriptor of the transceiver
|
2019-09-04 13:15:15 +02:00
|
|
|
* @param addr Address to set
|
drivers/cc110x: Rewrite of the cc110x driver
The cc110x driver has been re-written from scratch to overcome the limitations
of the old driver. The main motivation of the rewrite was to achieve better
maintainability by a detailed documentation, reduce the complexity and the
overhead of the SPI communication with the device, and to allow to
simultaneously use transceivers with different configuration regarding the used
base band, the channel bandwidth, the modulation rate, and the channel map.
Features of this driver include:
- Support for the CC1100, CC1101, and the CC1100e sub-gigahertz transceivers.
- Detailed documentation of every aspect of this driver.
- An easy to use configuration API that allows setting the transceiver
configuration (modulation rate, channel bandwidth, base frequency) and the
channel map.
- Fast channel hopping by pre-calibration of the channels during device
configuration (so that no calibration is needed during hopping).
- Simplified SPI communication: Only during start-up the MCU has to wait
for the transceiver to be ready (for the power regulators and the crystal
to stabilize). The old driver did this for every SPI transfer, which
resulted in complex communication code. This driver will wait on start up
for the transceiver to power up and then use RIOT's SPI API like every other
driver. (Not only the data sheet states that this is fine, it also proved to
be reliable in practise.)
- Greatly reduced latency: The RTT on the old driver (@150 kbps data rate) was
about 16ms, the new driver (@250 kbps data rate) has as RTT of ~3ms
(depending on SPI clock and on CPU performance) (measured with ping6).
- Increased reliability: The preamble size and the sync word size have been
doubled compared to the old driver (preamble: 8 bytes instead of 4,
sync word: 4 byte instead of 2). The new values are the once recommended by
the data sheet for reliable communication.
- Basic diagnostic during driver initialization to detect common issues as
SPI communication issues and GDO pin configuration/wiring issues.
- TX power configuration with netdev_driver_t::set() API-integration
- Calls to netdev_driver_t::send() block until the transmission has completed
to ease the use of the API (implemented without busy waiting, so that the
MCU can enter lower power states or other threads can be executed).
2018-11-08 17:37:07 +01:00
|
|
|
*/
|
|
|
|
static int cc110x_set_addr(cc110x_t *dev, uint8_t addr)
|
|
|
|
{
|
2021-02-01 14:25:22 +01:00
|
|
|
cc110x_acquire(dev);
|
drivers/cc110x: Rewrite of the cc110x driver
The cc110x driver has been re-written from scratch to overcome the limitations
of the old driver. The main motivation of the rewrite was to achieve better
maintainability by a detailed documentation, reduce the complexity and the
overhead of the SPI communication with the device, and to allow to
simultaneously use transceivers with different configuration regarding the used
base band, the channel bandwidth, the modulation rate, and the channel map.
Features of this driver include:
- Support for the CC1100, CC1101, and the CC1100e sub-gigahertz transceivers.
- Detailed documentation of every aspect of this driver.
- An easy to use configuration API that allows setting the transceiver
configuration (modulation rate, channel bandwidth, base frequency) and the
channel map.
- Fast channel hopping by pre-calibration of the channels during device
configuration (so that no calibration is needed during hopping).
- Simplified SPI communication: Only during start-up the MCU has to wait
for the transceiver to be ready (for the power regulators and the crystal
to stabilize). The old driver did this for every SPI transfer, which
resulted in complex communication code. This driver will wait on start up
for the transceiver to power up and then use RIOT's SPI API like every other
driver. (Not only the data sheet states that this is fine, it also proved to
be reliable in practise.)
- Greatly reduced latency: The RTT on the old driver (@150 kbps data rate) was
about 16ms, the new driver (@250 kbps data rate) has as RTT of ~3ms
(depending on SPI clock and on CPU performance) (measured with ping6).
- Increased reliability: The preamble size and the sync word size have been
doubled compared to the old driver (preamble: 8 bytes instead of 4,
sync word: 4 byte instead of 2). The new values are the once recommended by
the data sheet for reliable communication.
- Basic diagnostic during driver initialization to detect common issues as
SPI communication issues and GDO pin configuration/wiring issues.
- TX power configuration with netdev_driver_t::set() API-integration
- Calls to netdev_driver_t::send() block until the transmission has completed
to ease the use of the API (implemented without busy waiting, so that the
MCU can enter lower power states or other threads can be executed).
2018-11-08 17:37:07 +01:00
|
|
|
|
|
|
|
dev->addr = addr;
|
|
|
|
cc110x_write(dev, CC110X_REG_ADDR, addr);
|
|
|
|
cc110x_release(dev);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2020-01-23 14:47:19 +01:00
|
|
|
/**
|
|
|
|
* @brief Enables/disables the CC110x's address filter
|
|
|
|
* @param dev Transceiver to turn promiscuous mode on/off
|
|
|
|
* @param enable Whether to enable or disable promiscuous mode
|
|
|
|
*
|
|
|
|
* @return Returns the size of @ref netopt_enable_t to confirm with the API
|
|
|
|
* in @ref netdev_driver_t::set
|
|
|
|
*/
|
|
|
|
static int cc110x_set_promiscuous_mode(cc110x_t *dev, netopt_enable_t enable)
|
|
|
|
{
|
2021-02-01 14:25:22 +01:00
|
|
|
cc110x_acquire(dev);
|
2020-01-23 14:47:19 +01:00
|
|
|
|
|
|
|
uint8_t pktctrl1 = CC110X_PKTCTRL1_VALUE;
|
|
|
|
if (enable == NETOPT_ENABLE) {
|
|
|
|
pktctrl1 |= CC110X_PKTCTRL1_ADDR_ALL;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
pktctrl1 |= CC110X_PKTCTRL1_ADDR_MATCH;
|
|
|
|
}
|
|
|
|
cc110x_write(dev, CC110X_REG_PKTCTRL1, pktctrl1);
|
|
|
|
cc110x_release(dev);
|
|
|
|
return sizeof(netopt_enable_t);
|
|
|
|
}
|
|
|
|
|
drivers/cc110x: Rewrite of the cc110x driver
The cc110x driver has been re-written from scratch to overcome the limitations
of the old driver. The main motivation of the rewrite was to achieve better
maintainability by a detailed documentation, reduce the complexity and the
overhead of the SPI communication with the device, and to allow to
simultaneously use transceivers with different configuration regarding the used
base band, the channel bandwidth, the modulation rate, and the channel map.
Features of this driver include:
- Support for the CC1100, CC1101, and the CC1100e sub-gigahertz transceivers.
- Detailed documentation of every aspect of this driver.
- An easy to use configuration API that allows setting the transceiver
configuration (modulation rate, channel bandwidth, base frequency) and the
channel map.
- Fast channel hopping by pre-calibration of the channels during device
configuration (so that no calibration is needed during hopping).
- Simplified SPI communication: Only during start-up the MCU has to wait
for the transceiver to be ready (for the power regulators and the crystal
to stabilize). The old driver did this for every SPI transfer, which
resulted in complex communication code. This driver will wait on start up
for the transceiver to power up and then use RIOT's SPI API like every other
driver. (Not only the data sheet states that this is fine, it also proved to
be reliable in practise.)
- Greatly reduced latency: The RTT on the old driver (@150 kbps data rate) was
about 16ms, the new driver (@250 kbps data rate) has as RTT of ~3ms
(depending on SPI clock and on CPU performance) (measured with ping6).
- Increased reliability: The preamble size and the sync word size have been
doubled compared to the old driver (preamble: 8 bytes instead of 4,
sync word: 4 byte instead of 2). The new values are the once recommended by
the data sheet for reliable communication.
- Basic diagnostic during driver initialization to detect common issues as
SPI communication issues and GDO pin configuration/wiring issues.
- TX power configuration with netdev_driver_t::set() API-integration
- Calls to netdev_driver_t::send() block until the transmission has completed
to ease the use of the API (implemented without busy waiting, so that the
MCU can enter lower power states or other threads can be executed).
2018-11-08 17:37:07 +01:00
|
|
|
static int cc110x_set(netdev_t *netdev, netopt_t opt,
|
|
|
|
const void *val, size_t len)
|
|
|
|
{
|
|
|
|
(void)len;
|
|
|
|
cc110x_t *dev = (cc110x_t *)netdev;
|
|
|
|
|
|
|
|
switch (opt) {
|
2021-03-26 20:38:18 +01:00
|
|
|
case NETOPT_ADDRESS:
|
|
|
|
assert(len == CC1XXX_ADDR_SIZE);
|
|
|
|
return cc110x_set_addr(dev, *((uint8_t *)val));
|
|
|
|
case NETOPT_CHANNEL:
|
|
|
|
{
|
|
|
|
assert(len == sizeof(uint16_t));
|
|
|
|
int retval;
|
|
|
|
uint16_t channel = *((uint16_t *)val);
|
|
|
|
if (channel >= CC110X_MAX_CHANNELS) {
|
|
|
|
return -EINVAL;
|
drivers/cc110x: Rewrite of the cc110x driver
The cc110x driver has been re-written from scratch to overcome the limitations
of the old driver. The main motivation of the rewrite was to achieve better
maintainability by a detailed documentation, reduce the complexity and the
overhead of the SPI communication with the device, and to allow to
simultaneously use transceivers with different configuration regarding the used
base band, the channel bandwidth, the modulation rate, and the channel map.
Features of this driver include:
- Support for the CC1100, CC1101, and the CC1100e sub-gigahertz transceivers.
- Detailed documentation of every aspect of this driver.
- An easy to use configuration API that allows setting the transceiver
configuration (modulation rate, channel bandwidth, base frequency) and the
channel map.
- Fast channel hopping by pre-calibration of the channels during device
configuration (so that no calibration is needed during hopping).
- Simplified SPI communication: Only during start-up the MCU has to wait
for the transceiver to be ready (for the power regulators and the crystal
to stabilize). The old driver did this for every SPI transfer, which
resulted in complex communication code. This driver will wait on start up
for the transceiver to power up and then use RIOT's SPI API like every other
driver. (Not only the data sheet states that this is fine, it also proved to
be reliable in practise.)
- Greatly reduced latency: The RTT on the old driver (@150 kbps data rate) was
about 16ms, the new driver (@250 kbps data rate) has as RTT of ~3ms
(depending on SPI clock and on CPU performance) (measured with ping6).
- Increased reliability: The preamble size and the sync word size have been
doubled compared to the old driver (preamble: 8 bytes instead of 4,
sync word: 4 byte instead of 2). The new values are the once recommended by
the data sheet for reliable communication.
- Basic diagnostic during driver initialization to detect common issues as
SPI communication issues and GDO pin configuration/wiring issues.
- TX power configuration with netdev_driver_t::set() API-integration
- Calls to netdev_driver_t::send() block until the transmission has completed
to ease the use of the API (implemented without busy waiting, so that the
MCU can enter lower power states or other threads can be executed).
2018-11-08 17:37:07 +01:00
|
|
|
}
|
2021-03-26 20:38:18 +01:00
|
|
|
if ((retval = cc110x_set_channel(dev, (uint8_t)channel))) {
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return sizeof(uint16_t);
|
|
|
|
case NETOPT_TX_POWER:
|
|
|
|
{
|
|
|
|
assert(len == sizeof(int16_t));
|
|
|
|
int16_t dbm = *((int16_t *)val);
|
|
|
|
cc110x_tx_power_t power = CC110X_TX_POWER_MINUS_30_DBM;
|
|
|
|
for ( ; power < CC110X_TX_POWER_PLUS_10_DBM; power++) {
|
|
|
|
if ((int16_t)tx_power_from_dbm[power] >= dbm) {
|
|
|
|
break;
|
drivers/cc110x: Rewrite of the cc110x driver
The cc110x driver has been re-written from scratch to overcome the limitations
of the old driver. The main motivation of the rewrite was to achieve better
maintainability by a detailed documentation, reduce the complexity and the
overhead of the SPI communication with the device, and to allow to
simultaneously use transceivers with different configuration regarding the used
base band, the channel bandwidth, the modulation rate, and the channel map.
Features of this driver include:
- Support for the CC1100, CC1101, and the CC1100e sub-gigahertz transceivers.
- Detailed documentation of every aspect of this driver.
- An easy to use configuration API that allows setting the transceiver
configuration (modulation rate, channel bandwidth, base frequency) and the
channel map.
- Fast channel hopping by pre-calibration of the channels during device
configuration (so that no calibration is needed during hopping).
- Simplified SPI communication: Only during start-up the MCU has to wait
for the transceiver to be ready (for the power regulators and the crystal
to stabilize). The old driver did this for every SPI transfer, which
resulted in complex communication code. This driver will wait on start up
for the transceiver to power up and then use RIOT's SPI API like every other
driver. (Not only the data sheet states that this is fine, it also proved to
be reliable in practise.)
- Greatly reduced latency: The RTT on the old driver (@150 kbps data rate) was
about 16ms, the new driver (@250 kbps data rate) has as RTT of ~3ms
(depending on SPI clock and on CPU performance) (measured with ping6).
- Increased reliability: The preamble size and the sync word size have been
doubled compared to the old driver (preamble: 8 bytes instead of 4,
sync word: 4 byte instead of 2). The new values are the once recommended by
the data sheet for reliable communication.
- Basic diagnostic during driver initialization to detect common issues as
SPI communication issues and GDO pin configuration/wiring issues.
- TX power configuration with netdev_driver_t::set() API-integration
- Calls to netdev_driver_t::send() block until the transmission has completed
to ease the use of the API (implemented without busy waiting, so that the
MCU can enter lower power states or other threads can be executed).
2018-11-08 17:37:07 +01:00
|
|
|
}
|
|
|
|
}
|
2021-03-26 20:38:18 +01:00
|
|
|
if (cc110x_set_tx_power(dev, power)) {
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return sizeof(uint16_t);
|
|
|
|
case NETOPT_PROMISCUOUSMODE:
|
|
|
|
assert(len == sizeof(netopt_enable_t));
|
|
|
|
return cc110x_set_promiscuous_mode(dev, *((const netopt_enable_t *)val));
|
|
|
|
case NETOPT_STATE:
|
|
|
|
assert(len == sizeof(netopt_state_t));
|
|
|
|
switch (*((netopt_state_t *)val)) {
|
|
|
|
case NETOPT_STATE_RESET:
|
|
|
|
case NETOPT_STATE_IDLE:
|
|
|
|
cc110x_wakeup(dev);
|
|
|
|
return sizeof(netopt_state_t);
|
|
|
|
case NETOPT_STATE_OFF:
|
|
|
|
case NETOPT_STATE_SLEEP:
|
|
|
|
cc110x_sleep(dev);
|
|
|
|
return sizeof(netopt_state_t);
|
drivers/cc110x: Rewrite of the cc110x driver
The cc110x driver has been re-written from scratch to overcome the limitations
of the old driver. The main motivation of the rewrite was to achieve better
maintainability by a detailed documentation, reduce the complexity and the
overhead of the SPI communication with the device, and to allow to
simultaneously use transceivers with different configuration regarding the used
base band, the channel bandwidth, the modulation rate, and the channel map.
Features of this driver include:
- Support for the CC1100, CC1101, and the CC1100e sub-gigahertz transceivers.
- Detailed documentation of every aspect of this driver.
- An easy to use configuration API that allows setting the transceiver
configuration (modulation rate, channel bandwidth, base frequency) and the
channel map.
- Fast channel hopping by pre-calibration of the channels during device
configuration (so that no calibration is needed during hopping).
- Simplified SPI communication: Only during start-up the MCU has to wait
for the transceiver to be ready (for the power regulators and the crystal
to stabilize). The old driver did this for every SPI transfer, which
resulted in complex communication code. This driver will wait on start up
for the transceiver to power up and then use RIOT's SPI API like every other
driver. (Not only the data sheet states that this is fine, it also proved to
be reliable in practise.)
- Greatly reduced latency: The RTT on the old driver (@150 kbps data rate) was
about 16ms, the new driver (@250 kbps data rate) has as RTT of ~3ms
(depending on SPI clock and on CPU performance) (measured with ping6).
- Increased reliability: The preamble size and the sync word size have been
doubled compared to the old driver (preamble: 8 bytes instead of 4,
sync word: 4 byte instead of 2). The new values are the once recommended by
the data sheet for reliable communication.
- Basic diagnostic during driver initialization to detect common issues as
SPI communication issues and GDO pin configuration/wiring issues.
- TX power configuration with netdev_driver_t::set() API-integration
- Calls to netdev_driver_t::send() block until the transmission has completed
to ease the use of the API (implemented without busy waiting, so that the
MCU can enter lower power states or other threads can be executed).
2018-11-08 17:37:07 +01:00
|
|
|
default:
|
|
|
|
return -ENOTSUP;
|
2021-03-26 20:38:18 +01:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return -ENOTSUP;
|
drivers/cc110x: Rewrite of the cc110x driver
The cc110x driver has been re-written from scratch to overcome the limitations
of the old driver. The main motivation of the rewrite was to achieve better
maintainability by a detailed documentation, reduce the complexity and the
overhead of the SPI communication with the device, and to allow to
simultaneously use transceivers with different configuration regarding the used
base band, the channel bandwidth, the modulation rate, and the channel map.
Features of this driver include:
- Support for the CC1100, CC1101, and the CC1100e sub-gigahertz transceivers.
- Detailed documentation of every aspect of this driver.
- An easy to use configuration API that allows setting the transceiver
configuration (modulation rate, channel bandwidth, base frequency) and the
channel map.
- Fast channel hopping by pre-calibration of the channels during device
configuration (so that no calibration is needed during hopping).
- Simplified SPI communication: Only during start-up the MCU has to wait
for the transceiver to be ready (for the power regulators and the crystal
to stabilize). The old driver did this for every SPI transfer, which
resulted in complex communication code. This driver will wait on start up
for the transceiver to power up and then use RIOT's SPI API like every other
driver. (Not only the data sheet states that this is fine, it also proved to
be reliable in practise.)
- Greatly reduced latency: The RTT on the old driver (@150 kbps data rate) was
about 16ms, the new driver (@250 kbps data rate) has as RTT of ~3ms
(depending on SPI clock and on CPU performance) (measured with ping6).
- Increased reliability: The preamble size and the sync word size have been
doubled compared to the old driver (preamble: 8 bytes instead of 4,
sync word: 4 byte instead of 2). The new values are the once recommended by
the data sheet for reliable communication.
- Basic diagnostic during driver initialization to detect common issues as
SPI communication issues and GDO pin configuration/wiring issues.
- TX power configuration with netdev_driver_t::set() API-integration
- Calls to netdev_driver_t::send() block until the transmission has completed
to ease the use of the API (implemented without busy waiting, so that the
MCU can enter lower power states or other threads can be executed).
2018-11-08 17:37:07 +01:00
|
|
|
}
|
|
|
|
}
|