diff --git a/drivers/Jamfile b/drivers/Jamfile index e0223c05a1..9713df17fd 100644 --- a/drivers/Jamfile +++ b/drivers/Jamfile @@ -32,3 +32,4 @@ Module sht11 : sht11.c : hwtimer ; Module ltc4150 : ltc4150.c : board_ltc4150 ; SubInclude TOP drivers cc110x ; +SubInclude TOP drivers cc110x_ng ; diff --git a/drivers/cc110x_ng/Jamfile b/drivers/cc110x_ng/Jamfile new file mode 100755 index 0000000000..93d557720e --- /dev/null +++ b/drivers/cc110x_ng/Jamfile @@ -0,0 +1,33 @@ +# ****************************************************************************** +# Copyright 2010, Freie Universitaet Berlin (FUB). All rights reserved. +# +# These sources were developed at the Freie Universitaet Berlin, Computer +# Systems and Telematics group (http://cst.mi.fu-berlin.de). +# ------------------------------------------------------------------------------ +# This file is part of µkleos. +# +# This program is free software: you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation, either version 3 of the License, or (at your option) any later +# version. +# +# FeuerWare is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along with +# this program. If not, see http://www.gnu.org/licenses/ . +# ------------------------------------------------------------------------------ +# For further information and questions please use the web site +# http://scatterweb.mi.fu-berlin.de +# and the mailinglist (subscription via web site) +# scatterweb@lists.spline.inf.fu-berlin.de +# ****************************************************************************** +# $Id: Jamfile 832 2009-03-13 16:45:41Z kaspar $ + +SubDir TOP drivers cc110x_ng ; + +HDRS += $(TOP)/drivers/cc110x_ng ; + +Module cc110x_ng : cc1100.c cc1100-defaultSettings.c cc1100_spi.c : board_cc1100 swtimer gpioint ; + diff --git a/drivers/cc110x_ng/cc1100-arch.h b/drivers/cc110x_ng/cc1100-arch.h new file mode 100644 index 0000000000..ef61dd61c9 --- /dev/null +++ b/drivers/cc110x_ng/cc1100-arch.h @@ -0,0 +1,50 @@ +/****************************************************************************** +Copyright 2008, Freie Universitaet Berlin (FUB). All rights reserved. + +These sources were developed at the Freie Universitaet Berlin, Computer Systems +and Telematics group (http://cst.mi.fu-berlin.de). +------------------------------------------------------------------------------- +This file is part of FeuerWare. + +This program is free software: you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation, either version 3 of the License, or (at your option) any later +version. + +FeuerWare is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see http://www.gnu.org/licenses/ . +-------------------------------------------------------------------------------- +For further information and questions please use the web site + http://scatterweb.mi.fu-berlin.de +and the mailinglist (subscription via web site) + scatterweb@lists.spline.inf.fu-berlin.de +*******************************************************************************/ + +/** + * @file + * @ingroup LPC2387 + * @brief CC1100 LPC2387 dependend functions + * + * @author Freie Universität Berlin, Computer Systems & Telematics, FeuerWhere project + * @author Heiko Will + * @version $Revision: 1775 $ + * + * @note $Id: arch_cc1100.h 1775 2010-01-26 09:37:03Z hillebra $ + */ + +#include + +uint8_t cc1100_txrx(uint8_t c); + +void cc1100_gdo0_enable(void); +void cc1100_gdo0_disable(void); +void cc1100_gdo2_enable(void); +void cc1100_gdo2_disable(void); +void cc1100_init_interrupts(void); + +void cc1100_before_send(void); +void cc1100_after_send(void); diff --git a/drivers/cc110x_ng/cc1100-config.h b/drivers/cc110x_ng/cc1100-config.h new file mode 100644 index 0000000000..e7e039d882 --- /dev/null +++ b/drivers/cc110x_ng/cc1100-config.h @@ -0,0 +1,94 @@ +#ifndef CC1100_CONFIG_H +#define CC1100_CONFIG_H + +/** CC1100 register configuration */ +typedef struct { + uint8_t IOCFG2; + uint8_t IOCFG1; + uint8_t IOCFG0; + uint8_t FIFOTHR; + uint8_t SYNC1; + uint8_t SYNC0; + uint8_t PKTLEN; + uint8_t PKTCTRL1; + uint8_t PKTCTRL0; + uint8_t ADDR; + uint8_t CHANNR; + uint8_t FSCTRL1; + uint8_t FSCTRL0; + uint8_t FREQ2; + uint8_t FREQ1; + uint8_t FREQ0; + uint8_t MDMCFG4; + uint8_t MDMCFG3; + uint8_t MDMCFG2; + uint8_t MDMCFG1; + uint8_t MDMCFG0; + uint8_t DEVIATN; + uint8_t MCSM2; + uint8_t MCSM1; + uint8_t MCSM0; + uint8_t FOCCFG; + uint8_t BSCFG; + uint8_t AGCCTRL2; + uint8_t AGCCTRL1; + uint8_t AGCCTRL0; + uint8_t WOREVT1; + uint8_t WOREVT0; + uint8_t WORCTRL; + uint8_t FREND1; + uint8_t FREND0; + uint8_t FSCAL3; + uint8_t FSCAL2; + uint8_t FSCAL1; + uint8_t FSCAL0; +} cc1100_reg_t; + +/** CC1100 radio configuration */ +typedef struct { + cc1100_reg_t reg_cfg; ///< CC1100 register configuration + uint8_t pa_power; ///< Output power setting +} cc1100_cfg_t; + +/** + * @brief Radio Control Flags + */ +typedef struct +{ + uint32_t TOF; ///< Time of flight of the last packet and last ACK + uint32_t TCP; ///< Time to compute packet + unsigned RPS : 16; ///< Raw packets sent to transmit last packet + unsigned RTC : 8; ///< Retransmission count of last send packet + unsigned RSSI : 8; ///< The RSSI value of last received packet + unsigned RSSI_SEND : 8; ///< The RSSI value of the last send unicast packet of this node + unsigned LQI : 8; ///< The LQI value of the last received packet + unsigned LL_ACK : 1; ///< Is set if Link-Level ACK is received, otherwise 0 (reset on new burst) + unsigned CAA : 1; ///< The status of the air (1 = air free, 0 = air not free) + unsigned CRC : 1; ///< The CRC status of last received packet (1 = OK, 0 = not OK) + unsigned SEQ : 1; ///< Sequence number (toggles between 0 and 1) + unsigned MAN_WOR : 1; ///< Manual WOR set (for randomized WOR times => no synch) + unsigned KT_RES_ERR : 1; ///< A hwtimer resource error has occurred (no free timers available) + unsigned TX : 1; ///< State machine TX lock, only ACKs will be received + unsigned WOR_RST : 1; ///< Reset CC1100 real time clock (WOR) on next WOR strobe +} cc1100_flags; + +/** + * @brief Statistic interface for debugging + */ +typedef struct cc1100_statistic { + uint32_t packets_in; + uint32_t packets_in_crc_fail; + uint32_t packets_in_while_tx; + uint32_t packets_in_dups; + uint32_t packets_in_up; + uint32_t packets_out; + uint32_t packets_out_acked; + uint32_t packets_out_broadcast; + uint32_t raw_packets_out; + uint32_t raw_packets_out_acked; + uint32_t acks_send; + uint32_t rx_buffer_max; + uint32_t watch_dog_resets; +} cc1100_statistic_t; + +#endif diff --git a/drivers/cc110x_ng/cc1100-defaultSettings.c b/drivers/cc110x_ng/cc1100-defaultSettings.c new file mode 100644 index 0000000000..f19214914a --- /dev/null +++ b/drivers/cc110x_ng/cc1100-defaultSettings.c @@ -0,0 +1,155 @@ +/****************************************************************************** +Copyright 2008, Freie Universitaet Berlin (FUB). All rights reserved. + +These sources were developed at the Freie Universitaet Berlin, Computer Systems +and Telematics group (http://cst.mi.fu-berlin.de). +------------------------------------------------------------------------------- +This file is part of FeuerWare. + +This program is free software: you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation, either version 3 of the License, or (at your option) any later +version. + +FeuerWare is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see http://www.gnu.org/licenses/ . +-------------------------------------------------------------------------------- +For further information and questions please use the web site + http://scatterweb.mi.fu-berlin.de +and the mailinglist (subscription via web site) + scatterweb@lists.spline.inf.fu-berlin.de +*******************************************************************************/ + +/** + * @ingroup dev_cc110x + * @{ + */ + +/** + * @file + * @brief TI Chipcon CC110x default settings + * + * @author Freie Universität Berlin, Computer Systems & Telematics, FeuerWhere project + * @author Thomas Hillebrandt + * @author Heiko Will + * @version $Revision: 2058 $ + * + * @note $Id: cc1100-defaultSettings.c 2058 2010-03-31 08:59:31Z hillebra $ + */ + +#include + +/** + * Usable, non overlapping channels and corresponding frequencies + * for use with CC1100. CHANNR is the register for selecting a channel. + * + * channel number | CHANNR | frequency [MHz] + * ----------------------------------------- + * 0 | 0 | 869.525 + * 1 | 10 | 871.61 + * 2 | 20 | 873.58 ~ seems to be bad (hang-ups with this channel) + * 3 | 30 | 875.61 + * 4 | 40 | 877.58 + * 5 | 50 | 879.61 + * 6 | 60 | 881.58 + * 7 | 70 | 883.61 + * 8 | 80 | 885.58 + * 9 | 90 | 887.61 + * 10 | 100 | 889.58 + * 11 | 110 | 891.57 + * 12 | 120 | 893.58 + * 13 | 130 | 895.61 + * 14 | 140 | 897.58 + * 15 | 150 | 899.57 + * 16 | 160 | 901.57 + * 17 | 170 | 903.61 + * 18 | 180 | 905.57 + * 19 | 190 | 907.57 + * 20 | 200 | 909.57 + * 21 | 210 | 911.57 + * 22 | 220 | 913.57 + * 23 | 230 | 915.61 + * 24 | 240 | 917.61 + */ + +// 400 kbps, MSK, X-tal: 26 MHz (Chip Revision F) +char cc1100_conf[] = { + 0x06, // IOCFG2 + 0x2E, // IOCFG1 + 0x0E, // IOCFG0 + 0x0F, // FIFOTHR + 0x9B, // SYNC1 + 0xAD, // SYNC0 + 0x3D, // PKTLEN (maximum value of packet length byte = 61) + 0x06, // PKTCTRL1 + 0x45, // PKTCTRL0 (variable packet length) + 0xFF, // ADDR + CC1100_DEFAULT_CHANNR*10, // CHANNR + 0x0B, // FSCTRL1 + 0x00, // FSCTRL0 + 0x21, // FREQ2 + 0x71, // FREQ1 + 0x7A, // FREQ0 + 0x2D, // MDMCFG4 + 0xF8, // MDMCFG3 + 0x73, // MDMCFG2 + 0x42, // MDMCFG1 + 0xF8, // MDMCFG0 + 0x00, // DEVIATN + 0x07, // MCSM2 + 0x03, // MCSM1 + 0x18, // MCSM0 + 0x1D, // FOCCFG + 0x1C, // BSCFG + 0xC0, // AGCCTRL2 + 0x49, // AGCCTRL1, (old value was 0x49 -> made carrier sense less sensitive!) + // 0x47 - 7 dB above MAGN_TARGET setting + 0xB2, // AGCCTRL0 + 0x87, // WOREVT1 + 0x6B, // WOREVT0 + 0xF8, // WORCTRL + 0xB6, // FREND1 + 0x10, // FREND0 + 0xEA, // FSCAL3 + 0x2A, // FSCAL2 + 0x00, // FSCAL1 + 0x1F, // FSCAL0 + 0x00 // padding to 4 bytes +}; + +static uint8_t pa_table_index = PATABLE; ///< Current PATABLE Index +static uint8_t pa_table[] = { ///< PATABLE with available output powers + 0x00, ///< -52 dBm + 0x03, ///< -30 dBm + 0x0D, ///< -20 dBm + 0x1C, ///< -15 dBm + 0x34, ///< -10 dBm + 0x57, ///< - 5 dBm + 0x3F, ///< - 1 dBm + 0x8E, ///< 0 dBm + 0x85, ///< + 5 dBm + 0xCC, ///< + 7 dBm + 0xC6, ///< + 9 dBm + 0xC3 ///< +10 dBm +}; // If PATABLE is changed in size, adjust MAX_OUTPUT_POWER definition in CC1100 interface! + +static int8_t pa_table_dBm[] = { ///< Values of the PATABLE in dBm + -52, + -30, + -20, + -15, + -10, + -5, + -1, + 0, + 5, + 7, + 9, + 10 +}; + +/** @} */ diff --git a/drivers/cc110x_ng/cc1100-defaultSettings.h b/drivers/cc110x_ng/cc1100-defaultSettings.h new file mode 100644 index 0000000000..d3c92d4a09 --- /dev/null +++ b/drivers/cc110x_ng/cc1100-defaultSettings.h @@ -0,0 +1,110 @@ +/****************************************************************************** +Copyright 2008, Freie Universitaet Berlin (FUB). All rights reserved. + +These sources were developed at the Freie Universitaet Berlin, Computer Systems +and Telematics group (http://cst.mi.fu-berlin.de). +------------------------------------------------------------------------------- +This file is part of FeuerWare. + +This program is free software: you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation, either version 3 of the License, or (at your option) any later +version. + +FeuerWare is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see http://www.gnu.org/licenses/ . +-------------------------------------------------------------------------------- +For further information and questions please use the web site + http://scatterweb.mi.fu-berlin.de +and the mailinglist (subscription via web site) + scatterweb@lists.spline.inf.fu-berlin.de +*******************************************************************************/ + +#ifndef CC1100_DEFAULTSETTINGS_H +#define CC1100_DEFAULTSETTINGS_H + +/** + * @ingroup dev_cc110x + * @{ + */ + +/** + * @file + * @brief TI Chipcon CC110x default settings + * + * @author Freie Universität Berlin, Computer Systems & Telematics, FeuerWhere project + * @author Thomas Hillebrandt + * @author Heiko Will + * @version $Revision: 2139 $ + * + * @note $Id: cc1100-defaultSettings.h 2139 2010-05-26 08:04:04Z hillebra $ + */ + +#include + +// returns hwtimer ticks per us +#define RTIMER_TICKS(us) HWTIMER_TICKS(us) + +#define TIMER_TICK_USEC_RES (122) + +// Default PA table index (output power) +#define PATABLE (11) + +// Watchdog cycle time in seconds, set 0 to disable watchdog +#define CC1100_WATCHDOG_PERIOD (5) + +// Number of transmission retries for unicast packets (constant RX mode) +#define TRANSMISSION_RETRIES_CRX_UC (5) + +// Number of transmission retries for unicast packets (WOR mode) +#define TRANSMISSION_RETRIES_WOR_UC (1) + +// Number of transmission retries for broadcast packets (constant RX mode) +#define TRANSMISSION_RETRIES_CRX_BC (0) + +// Number of transmission retries for broadcast packets (WOR mode) +#define TRANSMISSION_RETRIES_WOR_BC (0) + +// Time before chip goes back to RX (= stays in PWD after incoming packet) +#define WOR_TIMEOUT_1 (3200) // ~ 32 milliseconds + +// Time before chip goes back to WOR (= stays in RX after elapsed WOR_TIMEOUT_1) +#define WOR_TIMEOUT_2 (800) // ~ 8 milliseconds + +// XOSC startup + FS calibration (300 + 809 us ~ 1.38 ms) +#define FS_CAL_TIME RTIMER_TICKS(12 * TIMER_TICK_USEC_RES) + +// Manual FS calibration (721 us) +#define MANUAL_FS_CAL_TIME RTIMER_TICKS(7 * TIMER_TICK_USEC_RES) + +// Reset wait time (in reset procedure) +#define RESET_WAIT_TIME RTIMER_TICKS(4 * TIMER_TICK_USEC_RES) + +// Time chip needs to go to RX +#define IDLE_TO_RX_TIME RTIMER_TICKS(1 * TIMER_TICK_USEC_RES) + +// Time chip needs to go to RX and CS signal is ready +#define CS_READY_TIME RTIMER_TICKS(3 * TIMER_TICK_USEC_RES) + +// Default RX interval for WOR in milliseconds +#define T_RX_INTERVAL (542) + +// Time of packet interval in microseconds (at 400 kbps) +#define T_PACKET_INTERVAL (3800) + +// The size of the configuration array for CC1100 in bytes +#define CC1100_CONF_SIZE (39) + +// The default channel number (0-24) for CC1100 +#define CC1100_DEFAULT_CHANNR (0) + +// Burst retry to TX switch time (measured ~ 230 us) +#define BURST_RETRY_TX_SWITCH_TIME (23) + + +/** @} */ +#endif diff --git a/drivers/cc110x_ng/cc1100-internal.h b/drivers/cc110x_ng/cc1100-internal.h new file mode 100644 index 0000000000..54ddabde70 --- /dev/null +++ b/drivers/cc110x_ng/cc1100-internal.h @@ -0,0 +1,218 @@ +/****************************************************************************** +Copyright 2008, Freie Universitaet Berlin (FUB). All rights reserved. + +These sources were developed at the Freie Universitaet Berlin, Computer Systems +and Telematics group (http://cst.mi.fu-berlin.de). +------------------------------------------------------------------------------- +This file is part of FeuerWare. + +This program is free software: you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation, either version 3 of the License, or (at your option) any later +version. + +FeuerWare is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see http://www.gnu.org/licenses/ . +-------------------------------------------------------------------------------- +For further information and questions please use the web site + http://scatterweb.mi.fu-berlin.de +and the mailinglist (subscription via web site) + scatterweb@lists.spline.inf.fu-berlin.de +*******************************************************************************/ + +#ifndef CC1100_INTERNAL_H +#define CC1100_INTERNAL_H + +/** + * @ingroup dev_cc110x + * @{ + */ + +/** + * @file + * @internal + * @brief TI Chipcon CC110x internal hardware constants + * + * @author Freie Universität Berlin, Computer Systems & Telematics, FeuerWhere project + * @author Thomas Hillebrandt + * @author Heiko Will + * @version $Revision: 1231 $ + * + * @note $Id: cc1100-internal.h 1231 2009-08-20 08:31:32Z baar $ + */ + +#define FIXED_PKTLEN (0x00) ///< Fixed length packets, length configured in PKTLEN register. +#define VARIABLE_PKTLEN (0x01) ///< Variable length packets, packet length configured by the first + ///< byte after synch word. + +/** + * @name Bitmasks for reading out status register values + * @{ + */ + +/** + * @brief Bitmask (=10000000) for reading CRC_OK. + * + * If CRC_OK == 1: CRC for received data OK (or CRC disabled). + * If CRC_OK == 0: CRC error in received data. + */ +#define CRC_OK (0x80) +/** + * @brief Bitmask (=01111111) for reading LQI_EST. + * + * The Link Quality Indicator estimates how easily a received signal can be demodulated. + */ +#define LQI_EST (0x7F) +#define I_RSSI (0x00) ///< Index 0 contains RSSI information (from optionally appended packet status bytes). +#define I_LQI (0x01) ///< Index 1 contains LQI & CRC_OK information (from optionally appended packet status bytes). +#define MARC_STATE (0x1F) ///< Bitmask (=00011111) for reading MARC_STATE in MARCSTATE status register. +#define CS (0x40) ///< Bitmask (=01000000) for reading CS (Carrier Sense) in PKTSTATUS status register. +#define PQT_REACHED (0x20) ///< Bitmask (=00100000) for reading PQT_REACHED (Preamble Quality reached) in PKTSTATUS status register. +#define CCA (0x10) ///< Bitmask (=00010000) for reading CCA (clear channel assessment) in PKTSTATUS status register. +#define SFD (0x08) ///< Bitmask (=00001000) for reading SFD (Sync word found) in PKTSTATUS status register. +#define GDO2 (0x04) ///< Bitmask (=00000100) for reading GDO2 (current value on GDO2 pin) in PKTSTATUS status register. +#define GDO1 (0x02) ///< Bitmask (=00000010) for reading GDO1 (current value on GDO1 pin) in PKTSTATUS status register. +#define GDO0 (0x01) ///< Bitmask (=00000001) for reading GDO0 (current value on GDO0 pin) in PKTSTATUS status register. +#define TXFIFO_UNDERFLOW (0x80) ///< Bitmask (=10000000) for reading TXFIFO_UNDERFLOW in TXBYTES status register. +#define BYTES_IN_TXFIFO (0x7F) ///< Bitmask (=01111111) for reading NUM_TXBYTES in TXBYTES status register. +#define RXFIFO_OVERFLOW (0x80) ///< Bitmask (=10000000) for reading RXFIFO_OVERFLOW in RXBYTES status register. +#define BYTES_IN_RXFIFO (0x7F) ///< Bitmask (=01111111) for reading NUM_RXBYTES in RXBYTES status register. +/** @} */ + +/** + * @name Bitmasks for reading out configuration register values + * @{ + */ +#define PKT_LENGTH_CONFIG (0x03) ///< Bitmask (=00000011) for reading LENGTH_CONFIG in PKTCTRL0 configuration register. +/** @} */ + +/** + * @name Definitions to support burst/single access + * @{ + */ +#define CC1100_WRITE_BURST (0x40) ///< Offset for burst write. +#define CC1100_READ_SINGLE (0x80) ///< Offset for read single byte. +#define CC1100_READ_BURST (0xC0) ///< Offset for read burst. +#define CC1100_NOBYTE (0x00) ///< No command (for reading). +/** @} */ + +/** + * @name Configuration Registers (47x) + * @{ + */ +#define CC1100_IOCFG2 (0x00) ///< GDO2 output pin configuration +#define CC1100_IOCFG1 (0x01) ///< GDO1 output pin configuration +#define CC1100_IOCFG0 (0x02) ///< GDO0 output pin configuration +#define CC1100_FIFOTHR (0x03) ///< RX FIFO and TX FIFO thresholds +#define CC1100_SYNC1 (0x04) ///< Sync word, high byte +#define CC1100_SYNC0 (0x05) ///< Sync word, low byte +#define CC1100_PKTLEN (0x06) ///< Packet length +#define CC1100_PKTCTRL1 (0x07) ///< Packet automation control +#define CC1100_PKTCTRL0 (0x08) ///< Packet automation control +#define CC1100_ADDR (0x09) ///< Device address +#define CC1100_CHANNR (0x0A) ///< Channel number +#define CC1100_FSCTRL1 (0x0B) ///< Frequency synthesizer control +#define CC1100_FSCTRL0 (0x0C) ///< Frequency synthesizer control +#define CC1100_FREQ2 (0x0D) ///< Frequency control word, high byte +#define CC1100_FREQ1 (0x0E) ///< Frequency control word, middle byte +#define CC1100_FREQ0 (0x0F) ///< Frequency control word, low byte +#define CC1100_MDMCFG4 (0x10) ///< Modem configuration +#define CC1100_MDMCFG3 (0x11) ///< Modem configuration +#define CC1100_MDMCFG2 (0x12) ///< Modem configuration +#define CC1100_MDMCFG1 (0x13) ///< Modem configuration +#define CC1100_MDMCFG0 (0x14) ///< Modem configuration +#define CC1100_DEVIATN (0x15) ///< Modem deviation setting +#define CC1100_MCSM2 (0x16) ///< Main Radio Control State Machine configuration +#define CC1100_MCSM1 (0x17) ///< Main Radio Control State Machine configuration +#define CC1100_MCSM0 (0x18) ///< Main Radio Control State Machine configuration +#define CC1100_FOCCFG (0x19) ///< Frequency Offset Compensation configuration +#define CC1100_BSCFG (0x1A) ///< Bit Synchronization configuration +#define CC1100_AGCCTRL2 (0x1B) ///< AGC control +#define CC1100_AGCCTRL1 (0x1C) ///< AGC control +#define CC1100_AGCCTRL0 (0x1D) ///< AGC control +#define CC1100_WOREVT1 (0x1E) ///< High byte Event 0 timeout +#define CC1100_WOREVT0 (0x1F) ///< Low byte Event 0 timeout +#define CC1100_WORCTRL (0x20) ///< Wake On Radio control +#define CC1100_FREND1 (0x21) ///< Front end RX configuration +#define CC1100_FREND0 (0x22) ///< Front end TX configuration +#define CC1100_FSCAL3 (0x23) ///< Frequency synthesizer calibration +#define CC1100_FSCAL2 (0x24) ///< Frequency synthesizer calibration +#define CC1100_FSCAL1 (0x25) ///< Frequency synthesizer calibration +#define CC1100_FSCAL0 (0x26) ///< Frequency synthesizer calibration +#define CC1100_RCCTRL1 (0x27) ///< RC oscillator configuration +#define CC1100_RCCTRL0 (0x28) ///< RC oscillator configuration +#define CC1100_FSTEST (0x29) ///< Frequency synthesizer calibration control +#define CC1100_PTEST (0x2A) ///< Production test +#define CC1100_AGCTEST (0x2B) ///< AGC test +#define CC1100_TEST2 (0x2C) ///< Various test settings +#define CC1100_TEST1 (0x2D) ///< Various test settings +#define CC1100_TEST0 (0x2E) ///< Various test settings +/** @} */ + +/** + * @name Strobe commands (14x) + * @{ + */ +#define CC1100_SRES (0x30) ///< Reset chip. +/** + * @brief Enable and calibrate frequency synthesizer (if MCSM0.FS_AUTOCAL=1). + * + * If in RX/TX: Go to a wait state where only the synthesizer is running (for quick RX / TX turnaround). + */ +#define CC1100_SFSTXON (0x31) +#define CC1100_SXOFF (0x32) ///< Turn off crystal oscillator. +#define CC1100_SCAL (0x33) ///< Calibrate frequency synthesizer and turn it off (enables quick start). +#define CC1100_SRX (0x34) ///< Enable RX. Perform calibration first if coming from IDLE and MCSM0.FS_AUTOCAL=1. +/** + * In IDLE state: Enable TX. Perform calibration first if MCSM0.FS_AUTOCAL=1. + * If in RX state and CCA is enabled: Only go to TX if channel is clear. + */ +#define CC1100_STX (0x35) +#define CC1100_SIDLE (0x36) ///< Exit RX / TX, turn off frequency synthesizer and exit WOR mode if applicable. +#define CC1100_SAFC (0x37) ///< Perform AFC adjustment of the frequency synthesizer +#define CC1100_SWOR (0x38) ///< Start automatic RX polling sequence (Wake-on-Radio) +#define CC1100_SPWD (0x39) ///< Enter power down mode when CSn goes high. +#define CC1100_SFRX (0x3A) ///< Flush the RX FIFO buffer (CC1100 should be in IDLE state). +#define CC1100_SFTX (0x3B) ///< Flush the TX FIFO buffer (CC1100 should be in IDLE state). +#define CC1100_SWORRST (0x3C) ///< Reset real time clock. +#define CC1100_SNOP (0x3D) ///< No operation. May be used to pad strobe commands to two bytes for simpler software. +/** @} */ + +/** + * @name Status registers (12x) + * @{ + */ +#define CC1100_PARTNUM (0x30) ///< Part number of CC1100. +#define CC1100_VERSION (0x31) ///< Current version number. +#define CC1100_FREQEST (0x32) ///< Frequency Offset Estimate. +#define CC1100_LQI (0x33) ///< Demodulator estimate for Link Quality. +#define CC1100_RSSI (0x34) ///< Received signal strength indication. +#define CC1100_MARCSTATE (0x35) ///< Control state machine state. +#define CC1100_WORTIME1 (0x36) ///< High byte of WOR timer. +#define CC1100_WORTIME0 (0x37) ///< Low byte of WOR timer. +#define CC1100_PKTSTATUS (0x38) ///< Current GDOx status and packet status. +#define CC1100_VCO_VC_DAC (0x39) ///< Current setting from PLL calibration module. +#define CC1100_TXBYTES (0x3A) ///< Underflow and number of bytes in the TX FIFO. +#define CC1100_RXBYTES (0x3B) ///< Overflow and number of bytes in the RX FIFO. +/** @} */ + +/** + * @name Multi byte registers + * @{ + */ +/** + * @brief Register for eight user selected output power settings. + * + * 3-bit FREND0.PA_POWER value selects the PATABLE entry to use. + */ +#define CC1100_PATABLE (0x3E) +#define CC1100_TXFIFO (0x3F) ///< TX FIFO: Write operations write to the TX FIFO (SB: +0x00; BURST: +0x40) +#define CC1100_RXFIFO (0x3F) ///< RX FIFO: Read operations read from the RX FIFO (SB: +0x80; BURST: +0xC0) + +/** @} */ + +#endif diff --git a/drivers/cc110x_ng/cc1100.c b/drivers/cc110x_ng/cc1100.c new file mode 100644 index 0000000000..6668934221 --- /dev/null +++ b/drivers/cc110x_ng/cc1100.c @@ -0,0 +1,260 @@ +#include +#include +#include +#include +#include +#include + +#include + +#define RX_BUF_SIZE (10) + +/* some externals */ +extern uint8_t pa_table[]; ///< PATABLE with available output powers +extern uint8_t pa_table_index; ///< Current PATABLE Index + +/* global variables */ + +static rx_buffer_t rx_buffer[RX_BUF_SIZE]; ///< RX buffer + +volatile cc1100_flags rflags; ///< Radio control flags +volatile uint8_t radio_state = RADIO_UNKNOWN; ///< Radio state + +static volatile uint8_t rx_buffer_tail; ///< RX queue tail + +static uint8_t radio_address; ///< Radio address +static uint8_t radio_channel; ///< Radio channel + +cc1100_statistic_t cc1100_statistic; + +/* internal function prototypes */ +static uint8_t receive_packet_variable(uint8_t *rxBuffer, uint8_t length); +static uint8_t receive_packet(uint8_t *rxBuffer, uint8_t length); +static void reset(void); +static void power_up_reset(void); +static void write_register(uint8_t r, uint8_t value); + +static void setup_rx_mode(void); +static void switch_to_rx(void); +static void wakeup_from_rx(void); +static void switch_to_pwd(void); + +/*---------------------------------------------------------------------------*/ +// Radio Driver API +/*---------------------------------------------------------------------------*/ +void cc1100_init(void) { + rx_buffer_tail = 0; + + /* Initialize SPI */ + cc1100_spi_init(); + + /* Load driver & reset */ + power_up_reset(); + + /* Write configuration to configuration registers */ + cc1100_spi_writeburst_reg(0x00, cc1100_conf, CC1100_CONF_SIZE); + + /* Write PATABLE (power settings) */ + cc1100_spi_write_reg(CC1100_PATABLE, pa_table[pa_table_index]); + + /* Initialize Radio Flags */ + rflags.RSSI = 0x00; + rflags.LL_ACK = 0; + rflags.CAA = 0; + rflags.CRC = 0; + rflags.SEQ = 0; + rflags.MAN_WOR = 0; + rflags.KT_RES_ERR = 0; + rflags.TX = 0; + rflags.WOR_RST = 0; + + /* Set default channel number */ + radio_channel = CC1100_DEFAULT_CHANNR; +} + +void cc1100_disable_interrupts(void) { + cc1100_gdo2_disable(); + cc1100_gdo0_disable(); +} + +void cc1100_gdo0_irq(void) { + // Air was not free -> Clear CCA flag + rflags.CAA = false; + // Disable carrier sense detection (GDO0 interrupt) + cc1100_gdo0_disable(); +} + +void cc1100_gdo2_irq(void) { + cc1100_rx_handler(); +} + +void cc1100_rx_handler(void) { + uint8_t res = 0; + + res = receive_packet((uint8_t*)&(rx_buffer[rx_buffer_tail].packet), sizeof(cc1100_packet_t)); +} + +uint8_t cc1100_set_address(radio_address_t address) { + if ((address < MIN_UID) || (address > MAX_UID)) { + return 0; + } + + uint8_t id = (uint8_t) address; + if (radio_state != RADIO_UNKNOWN) { + write_register(CC1100_ADDR, id); + } + + radio_address = id; + return 0; +} +/*---------------------------------------------------------------------------*/ +/* Internal functions */ +/*---------------------------------------------------------------------------*/ + +static uint8_t receive_packet_variable(uint8_t *rxBuffer, uint8_t length) { + uint8_t status[2]; + uint8_t packetLength = 0; + + /* Any bytes available in RX FIFO? */ + if ((cc1100_spi_read_status(CC1100_RXBYTES) & BYTES_IN_RXFIFO)) + { + // Read length byte (first byte in RX FIFO) + packetLength = cc1100_spi_read_reg(CC1100_RXFIFO); + // Read data from RX FIFO and store in rxBuffer + if (packetLength <= length) + { + // Put length byte at first position in RX Buffer + rxBuffer[0] = packetLength; + + // Read the rest of the packet + cc1100_spi_readburst_reg(CC1100_RXFIFO, (char*)rxBuffer+1, packetLength); + + // Read the 2 appended status bytes (status[0] = RSSI, status[1] = LQI) + cc1100_spi_readburst_reg(CC1100_RXFIFO, (char*)status, 2); + + // Store RSSI value of packet + rflags.RSSI = status[I_RSSI]; + + // MSB of LQI is the CRC_OK bit + rflags.CRC = (status[I_LQI] & CRC_OK) >> 7; + if (!rflags.CRC) { + cc1100_statistic.packets_in_crc_fail++; + } + + // Bit 0-6 of LQI indicates the link quality (LQI) + rflags.LQI = status[I_LQI] & LQI_EST; + + return rflags.CRC; + } + /* too many bytes in FIFO */ + else { + // RX FIFO get automatically flushed if return value is false + return 0; + } + } + /* no bytes in RX FIFO */ + else { + // RX FIFO get automatically flushed if return value is false + return 0; + } +} + +static uint8_t receive_packet(uint8_t *rxBuffer, uint8_t length) { + uint8_t pkt_len_cfg = cc1100_spi_read_reg(CC1100_PKTCTRL0) & PKT_LENGTH_CONFIG; + if (pkt_len_cfg == VARIABLE_PKTLEN) + { + return receive_packet_variable(rxBuffer, length); + } + // Fixed packet length not supported. + // RX FIFO get automatically flushed if return value is false + return 0; +} + +/*---------------------------------------------------------------------------*/ +// CC1100 reset functionality +/*---------------------------------------------------------------------------*/ + +static void reset(void) { + wakeup_from_rx(); + cc1100_spi_select(); + cc1100_spi_strobe(CC1100_SRES); + hwtimer_wait(RTIMER_TICKS(10)); +} + +static void power_up_reset(void) { + cc1100_spi_unselect(); + cc1100_spi_cs(); + cc1100_spi_unselect(); + hwtimer_wait(RESET_WAIT_TIME); + reset(); + radio_state = RADIO_IDLE; +} + +static void write_register(uint8_t r, uint8_t value) { + // Save old radio state + uint8_t old_state = radio_state; + + /* Wake up from WOR/RX (if in WOR/RX, else no effect) */ + wakeup_from_rx(); + cc1100_spi_write_reg(r, value); + + // Have to put radio back to WOR/RX if old radio state + // was WOR/RX, otherwise no action is necessary + if ((old_state == RADIO_WOR) || (old_state == RADIO_RX)) { + switch_to_rx(); + } +} + +static int rd_set_mode(int mode) { + int result; + + // Get current radio mode + if ((radio_state == RADIO_UNKNOWN) || (radio_state == RADIO_PWD)) { + result = RADIO_MODE_OFF; + } + else { + result = RADIO_MODE_ON; + } + + switch (mode) { + case RADIO_MODE_ON: + cc1100_init_interrupts(); // Enable interrupts + setup_rx_mode(); // Set chip to desired mode + break; + case RADIO_MODE_OFF: + cc1100_disable_interrupts(); // Disable interrupts + switch_to_pwd(); // Set chip to power down mode + break; + case RADIO_MODE_GET: + // do nothing, just return current mode + default: + // do nothing + break; + } + + // Return previous mode + return result; +} + +static void setup_rx_mode(void) { + // Stay in RX mode until end of packet + cc1100_spi_write_reg(CC1100_MCSM2, 0x07); + switch_to_rx(); +} + +static void switch_to_rx(void) { + radio_state = RADIO_RX; + cc1100_spi_strobe(CC1100_SRX); +} + +static void wakeup_from_rx(void) { + if (radio_state != RADIO_RX) return; + cc1100_spi_strobe(CC1100_SIDLE); + radio_state = RADIO_IDLE; +} + +static void switch_to_pwd(void) { + wakeup_from_rx(); + cc1100_spi_strobe(CC1100_SPWD); + radio_state = RADIO_PWD; +} diff --git a/drivers/cc110x_ng/cc1100.h b/drivers/cc110x_ng/cc1100.h new file mode 100644 index 0000000000..01c98fe588 --- /dev/null +++ b/drivers/cc110x_ng/cc1100.h @@ -0,0 +1,82 @@ +#include +#include +#include +#include + +#define MAX_DATA_LENGTH (58) + +#define CC1100_BROADCAST_ADDRESS (0x00) ///< CC1100 broadcast address + +#define MAX_UID (0xFF) ///< Maximum UID of a node is 255 +#define MIN_UID (0x01) ///< Minimum UID of a node is 1 + +#define MIN_CHANNR (0) ///< Minimum channel number +#define MAX_CHANNR (24) ///< Maximum channel number + +#define MIN_OUTPUT_POWER (0) ///< Minimum output power value +#define MAX_OUTPUT_POWER (11) ///< Maximum output power value + +/** + * @name Defines used as state values for state machine + * @{ + */ +#define RADIO_UNKNOWN (0) +#define RADIO_AIR_FREE_WAITING (1) +#define RADIO_WOR (2) +#define RADIO_IDLE (3) +#define RADIO_SEND_BURST (4) +#define RADIO_RX (5) +#define RADIO_SEND_ACK (6) +#define RADIO_PWD (7) + +/** @} */ +extern volatile cc1100_flags rflags; ///< Radio flags +extern char cc1100_conf[]; + +/** + * @brief CC1100 layer 0 protocol + * + *
+---------------------------------------------------
+|        |         |         |       |            |
+| Length | Address | PhySrc  | Flags |    Data    |
+|        |         |         |       |            |
+---------------------------------------------------
+  1 byte   1 byte    1 byte   1 byte   <= 58 bytes
+
+Flags:
+		Bit | Meaning
+		--------------------
+		7:4	| -
+		3:1 | Protocol
+		  0 | Identification
+
+Notes: +\li length & address are given by CC1100 +\li Identification is increased is used to scan duplicates. It must be increased + for each new packet and kept for packet retransmissions. + */ +typedef struct __attribute__ ((packed)) { + uint8_t length; ///< Length of the packet (without length byte) + uint8_t address; ///< Destination address + uint8_t phy_src; ///< Source address (physical source) + uint8_t flags; ///< Flags + uint8_t data[MAX_DATA_LENGTH]; ///< Data (high layer protocol) +} cc1100_packet_t; + +typedef struct { + cc1100_packet_t packet; + packet_info_t info; +} rx_buffer_t; + +enum radio_mode { + RADIO_MODE_GET = -1, ///< leave mode unchanged + RADIO_MODE_OFF = 0, ///< turn radio off + RADIO_MODE_ON = 1 ///< turn radio on +}; + +void cc1100_init(void); + +void cc1100_rx_handler(void); + +void cc1100_disable_interrupts(void); diff --git a/drivers/cc110x_ng/cc1100_spi.c b/drivers/cc110x_ng/cc1100_spi.c new file mode 100644 index 0000000000..010f31a5ed --- /dev/null +++ b/drivers/cc110x_ng/cc1100_spi.c @@ -0,0 +1,128 @@ +/****************************************************************************** +Copyright 2010, Freie Universitaet Berlin (FUB). All rights reserved. + +These sources were developed at the Freie Universitaet Berlin, Computer Systems +and Telematics group (http://cst.mi.fu-berlin.de). +------------------------------------------------------------------------------- +This file is part of µkleos. + +This program is free software: you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation, either version 3 of the License, or (at your option) any later +version. + +FeuerWare is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see http://www.gnu.org/licenses/ . +-------------------------------------------------------------------------------- +For further information and questions please use the web site + http://scatterweb.mi.fu-berlin.de +and the mailinglist (subscription via web site) + scatterweb@lists.spline.inf.fu-berlin.de +*******************************************************************************/ + +/** + * @ingroup dev_cc110x + * @{ + */ + +/** + * @file + * @internal + * @brief TI Chipcon CC1100 SPI driver + * + * @author Freie Universität Berlin, Computer Systems & Telematics, FeuerWhere project + * @author Thomas Hillebrandt + * @author Heiko Will + * @version $Revision: 1775 $ + * + * @note $Id: cc1100_spi.c 1775 2010-01-26 09:37:03Z hillebra $ + */ + +#include + +#include +#include +#include +#include + +#include + +/*---------------------------------------------------------------------------*/ +// CC1100 SPI access +/*---------------------------------------------------------------------------*/ + +#define NOBYTE 0xFF + +uint8_t cc1100_spi_writeburst_reg(uint8_t addr, char *src, uint8_t count) { + int i = 0; + unsigned int cpsr = disableIRQ(); + cc1100_spi_select(); + cc1100_txrx(addr | CC1100_WRITE_BURST); + while (i < count) { + cc1100_txrx(src[i]); + i++; + } + cc1100_spi_unselect(); + restoreIRQ(cpsr); + return count; +} + +void cc1100_spi_readburst_reg(uint8_t addr, char *buffer, uint8_t count) { + int i = 0; + unsigned int cpsr = disableIRQ(); + cc1100_spi_select(); + cc1100_txrx(addr | CC1100_READ_BURST); + while (i < count) { + buffer[i] = cc1100_txrx(NOBYTE); + i++; + } + cc1100_spi_unselect(); + restoreIRQ(cpsr); +} + +void cc1100_spi_write_reg(uint8_t addr, uint8_t value) { + unsigned int cpsr = disableIRQ(); + cc1100_spi_select(); + cc1100_txrx(addr); + cc1100_txrx(value); + cc1100_spi_unselect(); + restoreIRQ(cpsr); +} + +uint8_t cc1100_spi_read_reg(uint8_t addr) { + uint8_t result; + unsigned int cpsr = disableIRQ(); + cc1100_spi_select(); + cc1100_txrx(addr | CC1100_READ_SINGLE); + result = cc1100_txrx(NOBYTE); + cc1100_spi_unselect(); + restoreIRQ(cpsr); + return result; +} + +uint8_t cc1100_spi_read_status(uint8_t addr) { + uint8_t result; + unsigned int cpsr = disableIRQ(); + cc1100_spi_select(); + cc1100_txrx(addr | CC1100_READ_BURST); + result = cc1100_txrx(NOBYTE); + cc1100_spi_unselect(); + restoreIRQ(cpsr); + return result; +} + +uint8_t cc1100_spi_strobe(uint8_t c) { + uint8_t result; + unsigned int cpsr = disableIRQ(); + cc1100_spi_select(); + result = cc1100_txrx(c); + cc1100_spi_unselect(); + restoreIRQ(cpsr); + return result; +} + +/** @} */ diff --git a/drivers/cc110x_ng/cc1100_spi.h b/drivers/cc110x_ng/cc1100_spi.h new file mode 100644 index 0000000000..736f982187 --- /dev/null +++ b/drivers/cc110x_ng/cc1100_spi.h @@ -0,0 +1,64 @@ +/****************************************************************************** +Copyright 2008, Freie Universitaet Berlin (FUB). All rights reserved. + +These sources were developed at the Freie Universitaet Berlin, Computer Systems +and Telematics group (http://cst.mi.fu-berlin.de). +------------------------------------------------------------------------------- +This file is part of FeuerWare. + +This program is free software: you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation, either version 3 of the License, or (at your option) any later +version. + +FeuerWare is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see http://www.gnu.org/licenses/ . +-------------------------------------------------------------------------------- +For further information and questions please use the web site + http://scatterweb.mi.fu-berlin.de +and the mailinglist (subscription via web site) + scatterweb@lists.spline.inf.fu-berlin.de +*******************************************************************************/ +/** + * @ingroup dev_cc110x + * @{ + */ + +/** + * @file + * @internal + * @brief TI Chipcon CC1100 SPI driver + * + * @author Freie Universität Berlin, Computer Systems & Telematics, FeuerWhere project + * @author Thomas Hillebrandt + * @author Heiko Will + * @version $Revision: 1775 $ + * + * @note $Id: cc1100_spi.h 1775 2010-01-26 09:37:03Z hillebra $ + */ + +#ifndef CC1100_SPI_H_ +#define CC1100_SPI_H_ + +int cc1100_get_gdo0(void); +int cc1100_get_gdo1(void); +int cc1100_get_gdo2(void); + +void cc1100_spi_init(void); +void cc1100_spi_cs(void); +void cc1100_spi_select(void); +void cc1100_spi_unselect(void); + +uint8_t cc1100_spi_writeburst_reg(uint8_t addr, char *buffer, uint8_t count); +void cc1100_spi_readburst_reg(uint8_t addr, char *buffer, uint8_t count); +void cc1100_spi_write_reg(uint8_t addr, uint8_t value); +uint8_t cc1100_spi_read_reg(uint8_t addr); +uint8_t cc1100_spi_read_status(uint8_t addr); +uint8_t cc1100_spi_strobe(uint8_t c); + +/** @} */ +#endif /* CC1100_SPI_H_ */