-
Notifications
You must be signed in to change notification settings - Fork 2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #3716 from kaspar030/ng_cc110x
drivers: add cc110x driver
- Loading branch information
Showing
21 changed files
with
2,281 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,7 @@ | ||
export INCLUDES += -I$(RIOTBOARD)/msba2/include | ||
|
||
ifneq (,$(filter gnrc_netif_default,$(USEMODULE))) | ||
USEMODULE += cc110x gnrc_netdev2 gnrc_cc110x | ||
endif | ||
|
||
include $(RIOTBOARD)/msba2-common/Makefile.include |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
/* | ||
* Copyright (C) 2015 Kaspar Schleiser <kaspar@schleiser.de> | ||
* | ||
* 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. | ||
*/ | ||
|
||
/** | ||
* @ingroup board_msba2 | ||
* @{ | ||
* | ||
* @file | ||
* @brief cc110x board specific configuration | ||
* | ||
* @author Kaspar Schleiser <kaspar@schleiser.de> | ||
*/ | ||
|
||
#ifndef CC110X_PARAMS_H | ||
#define CC110X_PARAMS_H | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
/** | ||
* @name CC110X configuration | ||
*/ | ||
const cc110x_params_t cc110x_params[] = { | ||
{ | ||
.spi = 0, | ||
.cs = 53, | ||
.gdo0 = 27, | ||
.gdo1 = 55, | ||
.gdo2 = 28 | ||
}, | ||
}; | ||
/** @} */ | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif | ||
#endif /* CC110X_PARAMS_H */ | ||
/** @} */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
DIRS += gnrc_cc110x | ||
|
||
include $(RIOTBASE)/Makefile.base |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
/* | ||
* Copyright (C) 2013 INRIA | ||
* 2015 Kaspar Schleiser <kaspar@schleiser.de> | ||
* | ||
* 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. | ||
*/ | ||
|
||
/** | ||
* @ingroup drivers_cc110x | ||
* @{ | ||
* | ||
* @file | ||
* @brief TI Chipcon CC110x default settings | ||
* | ||
* @author Thomas Hillebrandt <hillebra@inf.fu-berlin.de> | ||
* @author Heiko Will <hwill@inf.fu-berlin.de> | ||
* @author Oliver Hahm <oliver.hahm@inria.fr> | ||
* @author Kaspar Schleiser <kaspar@schleiser.de> | ||
* @} | ||
*/ | ||
|
||
#include "board.h" | ||
#include "cc110x.h" | ||
|
||
/** | ||
* @brief PATABLE with available output powers | ||
* @note If changed in size, adjust MAX_OUTPUT_POWER definition | ||
* in CC110x interface | ||
*/ | ||
const char cc110x_default_pa_table[8] = { | ||
0x00, /*< -52 dBm */ | ||
0x0D, /*< -20 dBm */ | ||
0x34, /*< -10 dBm */ | ||
0x57, /*< - 5 dBm */ | ||
0x8E, /*< 0 dBm */ | ||
0x85, /*< + 5 dBm */ | ||
0xCC, /*< + 7 dBm */ | ||
0xC3 /*< +10 dBm */ | ||
}; | ||
|
||
const char cc110x_default_base_freq[3] = { 0x21, 0x71, 0x7F }; | ||
|
||
/** | ||
* @brief cc110x default settings | ||
*/ | ||
const char cc110x_default_conf[] = { | ||
0x06, /* IOCFG2 */ | ||
0x2E, /* IOCFG1 */ | ||
/* some boards use cc110x' GDO0 as clock source, so for those, we allow | ||
* overriding of the corresponding setting, e.g., in board.h */ | ||
#ifdef CC110X_IOCONF0_VAL | ||
CC110X_IOCONF0_VAL, | ||
#else | ||
0x0E, /* IOCFG0 */ | ||
#endif | ||
0x07, /* FIFOTHR */ | ||
0x9B, /* SYNC1 */ | ||
0xAD, /* SYNC0 */ | ||
0xFF, /* PKTLEN */ | ||
0x06, /* PKTCTRL1 */ | ||
0x45, /* PKTCTRL0 (variable packet length) */ | ||
0xFF, /* ADDR */ | ||
0x00, /* CHANNR */ | ||
0x0F, /* FSCTRL1 */ | ||
0x00, /* FSCTRL0 */ | ||
0x21, /* FREQ2 */ | ||
0x71, /* FREQ1 */ | ||
0x7A, /* FREQ0 */ | ||
0x7C, /* MDMCFG4 */ | ||
0x7A, /* MDMCFG3 */ | ||
0x06, /* MDMCFG2 */ | ||
0xC0, /* MDMCFG1 */ | ||
0xF8, /* MDMCFG0 */ | ||
0x44, /* DEVIATN */ | ||
0x07, /* MCSM2 */ | ||
0x03, /* MCSM1 */ | ||
0x18, /* MCSM0 */ | ||
0x16, /* FOCCFG */ | ||
0x6C, /* BSCFG */ | ||
0x45, /* AGCCTRL2 */ | ||
0x40, /* AGCCTRL1 */ | ||
0x91, /* AGCCTRL0 */ | ||
0x87, /* WOREVT1 */ | ||
0x6B, /* WOREVT0 */ | ||
0xF8, /* WORCTRL */ | ||
0x56, /* FREND1 */ | ||
0x17, /* FREND0 */ | ||
0xEA, /* FSCAL3 */ | ||
0x2A, /* FSCAL2 */ | ||
0x00, /* FSCAL1 */ | ||
0x1F, /* FSCAL0 */ | ||
0x00 /* padding to 4 bytes */ | ||
}; | ||
|
||
/** | ||
* @brief The size of the configuration array for CC110X in bytes | ||
* */ | ||
const uint8_t cc110x_default_conf_size = sizeof(cc110x_default_conf); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,218 @@ | ||
/* | ||
* Copyright (C) 2014 Freie Universität Berlin | ||
* 2015 Kaspar Schleiser <kaspar@schleiser.de> | ||
* | ||
* 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. | ||
*/ | ||
|
||
/** | ||
* @ingroup drivers_cc110x | ||
* @{ | ||
* @file | ||
* @brief Implementation of netdev2 interface for cc110x | ||
* | ||
* @author Fabian Nack <nack@inf.fu-berlin.de> | ||
* @author Kaspar Schleiser <kaspar@schleiser.de> | ||
* @} | ||
*/ | ||
|
||
#include <assert.h> | ||
#include <stdlib.h> | ||
#include <string.h> | ||
#include <errno.h> | ||
|
||
#include "cc110x.h" | ||
#include "cc110x/cc110x-netdev2.h" | ||
#include "cc110x/cc110x-internal.h" | ||
#include "cc110x/cc110x-interface.h" | ||
#include "net/eui64.h" | ||
|
||
#include "periph/cpuid.h" | ||
#include "periph/gpio.h" | ||
#include "net/netdev2.h" | ||
#include "net/gnrc/nettype.h" | ||
|
||
#define ENABLE_DEBUG (0) | ||
#include "debug.h" | ||
|
||
static int _send(netdev2_t *dev, const struct iovec *vector, int count) | ||
{ | ||
DEBUG("%s:%u\n", __func__, __LINE__); | ||
|
||
netdev2_cc110x_t *netdev2_cc110x = (netdev2_cc110x_t*) dev; | ||
cc110x_pkt_t *cc110x_pkt = vector[0].iov_base; | ||
|
||
return cc110x_send(&netdev2_cc110x->cc110x, cc110x_pkt); | ||
} | ||
|
||
static int _recv(netdev2_t *dev, char* buf, int len) | ||
{ | ||
DEBUG("%s:%u\n", __func__, __LINE__); | ||
|
||
cc110x_t *cc110x = &((netdev2_cc110x_t*) dev)->cc110x; | ||
|
||
cc110x_pkt_t *cc110x_pkt = &cc110x->pkt_buf.packet; | ||
if (cc110x_pkt->length > len) { | ||
return -ENOSPC; | ||
} | ||
|
||
memcpy(buf, (void*)cc110x_pkt, cc110x_pkt->length); | ||
return cc110x_pkt->length; | ||
} | ||
|
||
static inline int _get_iid(netdev2_t *netdev, eui64_t *value, size_t max_len) | ||
{ | ||
if (max_len < sizeof(eui64_t)) { | ||
return -EOVERFLOW; | ||
} | ||
|
||
uint8_t *eui64 = (uint8_t*) value; | ||
#ifdef CPUID_ID_LEN | ||
int n = (CPUID_ID_LEN < sizeof(eui64_t)) | ||
? CPUID_ID_LEN | ||
: sizeof(eui64_t); | ||
|
||
char cpuid[CPUID_ID_LEN]; | ||
cpuid_get(cpuid); | ||
|
||
memcpy(eui64 + 8 - n, cpuid, n); | ||
|
||
#else | ||
for (int i = 0; i < 8; i++) { | ||
eui64[i] = i; | ||
} | ||
#endif | ||
|
||
/* make sure we mark the address as non-multicast and not globally unique */ | ||
eui64[0] &= ~(0x01); | ||
eui64[0] |= 0x02; | ||
|
||
return sizeof(eui64_t); | ||
} | ||
|
||
static int _get(netdev2_t *dev, netopt_t opt, void *value, size_t value_len) | ||
{ | ||
cc110x_t *cc110x = &((netdev2_cc110x_t*) dev)->cc110x; | ||
|
||
switch (opt) { | ||
case NETOPT_DEVICE_TYPE: | ||
assert(value_len == 2); | ||
*((uint16_t *) value) = NETDEV2_TYPE_CC110X; | ||
return 2; | ||
case NETOPT_PROTO: | ||
assert(value_len == sizeof(gnrc_nettype_t)); | ||
#ifdef MODULE_GNRC_SIXLOWPAN | ||
*((gnrc_nettype_t*)value) = GNRC_NETTYPE_SIXLOWPAN; | ||
#else | ||
*((gnrc_nettype_t*)value) = GNRC_NETTYPE_UNDEF; | ||
#endif | ||
return sizeof(gnrc_nettype_t); | ||
case NETOPT_CHANNEL: | ||
assert(value_len > 1); | ||
*((uint16_t *)value) = (uint16_t)cc110x->radio_channel; | ||
return 2; | ||
case NETOPT_ADDRESS: | ||
assert(value_len > 0); | ||
*((uint8_t *)value) = cc110x->radio_address; | ||
return 1; | ||
case NETOPT_MAX_PACKET_SIZE: | ||
assert(value_len > 0); | ||
*((uint8_t *)value) = CC110X_PACKET_LENGTH; | ||
return 1; | ||
case NETOPT_IPV6_IID: | ||
return _get_iid(dev, value, value_len); | ||
default: | ||
break; | ||
} | ||
|
||
return -ENOTSUP; | ||
} | ||
|
||
static int _set(netdev2_t *dev, netopt_t opt, void *value, size_t value_len) | ||
{ | ||
cc110x_t *cc110x = &((netdev2_cc110x_t*) dev)->cc110x; | ||
|
||
switch (opt) { | ||
case NETOPT_CHANNEL: | ||
{ | ||
uint8_t *arg = (uint8_t*)value; | ||
uint8_t channel = arg[value_len-1]; | ||
if ((channel < CC110X_MIN_CHANNR) || (channel > CC110X_MAX_CHANNR)) { | ||
return -EINVAL; | ||
} | ||
if (cc110x_set_channel(cc110x, channel) == -1) { | ||
return -EINVAL; | ||
} | ||
return 1; | ||
} | ||
case NETOPT_ADDRESS: | ||
if (value_len < 1) { | ||
return -EINVAL; | ||
} | ||
if (!cc110x_set_address(cc110x, *(uint8_t*)value)) { | ||
return -EINVAL; | ||
} | ||
return 1; | ||
default: | ||
return -ENOTSUP; | ||
} | ||
|
||
return 0; | ||
} | ||
|
||
static void _netdev2_cc110x_isr(void *arg) | ||
{ | ||
netdev2_t *netdev2 = (netdev2_t*) arg; | ||
netdev2->event_callback(netdev2, NETDEV2_EVENT_ISR, netdev2->isr_arg); | ||
} | ||
|
||
static void _netdev2_cc110x_rx_callback(void *arg) | ||
{ | ||
netdev2_t *netdev2 = (netdev2_t*) arg; | ||
cc110x_t *cc110x = &((netdev2_cc110x_t*) arg)->cc110x; | ||
gpio_irq_disable(cc110x->params.gdo2); | ||
netdev2->event_callback(netdev2, NETDEV2_EVENT_RX_COMPLETE, netdev2->isr_arg); | ||
} | ||
|
||
static void _isr(netdev2_t *dev) | ||
{ | ||
cc110x_t *cc110x = &((netdev2_cc110x_t*) dev)->cc110x; | ||
cc110x_isr_handler(cc110x, _netdev2_cc110x_rx_callback, (void*)dev); | ||
} | ||
|
||
static int _init(netdev2_t *dev) | ||
{ | ||
DEBUG("%s:%u\n", __func__, __LINE__); | ||
|
||
cc110x_t *cc110x = &((netdev2_cc110x_t*) dev)->cc110x; | ||
|
||
gpio_init_int(cc110x->params.gdo2, GPIO_NOPULL, GPIO_BOTH, | ||
&_netdev2_cc110x_isr, (void*)dev); | ||
|
||
gpio_set(cc110x->params.gdo2); | ||
gpio_irq_disable(cc110x->params.gdo2); | ||
|
||
/* Switch to RX mode */ | ||
cc110x_rd_set_mode(cc110x, RADIO_MODE_ON); | ||
|
||
return 0; | ||
} | ||
|
||
const netdev2_driver_t netdev2_cc110x_driver = { | ||
.send=_send, | ||
.recv=_recv, | ||
.init=_init, | ||
.get=_get, | ||
.set=_set, | ||
.isr=_isr | ||
}; | ||
|
||
int netdev2_cc110x_setup(netdev2_cc110x_t *netdev2_cc110x, const cc110x_params_t *params) | ||
{ | ||
DEBUG("netdev2_cc110x_setup()\n"); | ||
netdev2_cc110x->netdev.driver = &netdev2_cc110x_driver; | ||
|
||
return cc110x_setup(&netdev2_cc110x->cc110x, params); | ||
} |
Oops, something went wrong.