2013-11-27 17:54:30 +01:00
|
|
|
/*
|
2013-08-16 10:20:23 +02:00
|
|
|
* Copyright 2008, Freie Universitaet Berlin (FUB). All rights reserved.
|
|
|
|
*
|
2014-08-23 15:43:13 +02:00
|
|
|
* This file is subject to the terms and conditions of the GNU Lesser
|
|
|
|
* General Public License v2.1. See the file LICENSE in the top level
|
|
|
|
* directory for more details.
|
2014-08-27 18:47:31 +02:00
|
|
|
*/
|
2010-09-22 15:10:42 +02:00
|
|
|
|
|
|
|
/**
|
2014-10-26 22:02:18 +01:00
|
|
|
* @defgroup drivers_cc110x_legacy_csma CC110X_LEGACY_CSMA
|
2013-11-27 17:54:30 +01:00
|
|
|
* @ingroup drivers
|
2014-05-24 16:06:05 +02:00
|
|
|
* @brief Driver for Texas Instruments CC110x (including CMSA/CA MAC)
|
2010-09-22 15:10:42 +02:00
|
|
|
*
|
|
|
|
* <h3>Quick links</h3>
|
2013-11-27 17:54:30 +01:00
|
|
|
* \li \ref cc1100_packet_layer0_t MAC packet format
|
2010-09-22 15:10:42 +02:00
|
|
|
*
|
|
|
|
* @{
|
2013-11-27 17:54:30 +01:00
|
|
|
*
|
2010-09-22 15:10:42 +02:00
|
|
|
* @file
|
2013-11-27 17:54:30 +01:00
|
|
|
* @brief TI Chipcon CC110x radio driver
|
2010-09-22 15:10:42 +02:00
|
|
|
*
|
2013-11-27 17:54:30 +01:00
|
|
|
* @author Thomas Hillebrandt <hillebra@inf.fu-berlin.de>
|
|
|
|
* @author Heiko Will <hwill@inf.fu-berlin.de>
|
2010-09-22 15:10:42 +02:00
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef CC1100_H
|
|
|
|
#define CC1100_H
|
|
|
|
|
|
|
|
#include <stdbool.h>
|
2014-10-26 22:02:18 +01:00
|
|
|
#include "cc110x_legacy_csma.h"
|
2010-09-22 15:10:42 +02:00
|
|
|
|
2014-10-13 15:49:17 +02:00
|
|
|
#ifdef __cplusplus
|
|
|
|
extern "C" {
|
|
|
|
#endif
|
|
|
|
|
2010-09-22 15:10:42 +02:00
|
|
|
/**
|
2013-11-27 17:54:30 +01:00
|
|
|
* @name Defines used as state values for state machine
|
2010-09-22 15:10:42 +02:00
|
|
|
* @{
|
|
|
|
*/
|
2013-11-27 17:54:30 +01:00
|
|
|
#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)
|
2010-09-22 15:10:42 +02:00
|
|
|
|
|
|
|
/** @} */
|
|
|
|
|
2014-12-06 17:28:13 +01:00
|
|
|
/** @brief CC1100 register configuration */
|
2010-09-22 15:10:42 +02:00
|
|
|
typedef struct cc1100_reg {
|
2014-12-06 17:28:13 +01:00
|
|
|
uint8_t IOCFG2; /**< GDO2 output pin configuration */
|
|
|
|
uint8_t IOCFG1; /**< GDO1 output pin configuration */
|
|
|
|
uint8_t IOCFG0; /**< GDO0 output pin configuration */
|
|
|
|
uint8_t FIFOTHR; /**< RX FIFO and TX FIFO thresholds */
|
|
|
|
uint8_t SYNC1; /**< Sync word, high byte */
|
|
|
|
uint8_t SYNC0; /**< Sync word, low byte */
|
|
|
|
uint8_t PKTLEN; /**< Packet length */
|
|
|
|
uint8_t PKTCTRL1; /**< Packet automation control */
|
|
|
|
uint8_t PKTCTRL0; /**< Packet automation control */
|
|
|
|
uint8_t ADDR; /**< Device address */
|
|
|
|
uint8_t CHANNR; /**< Channel number */
|
|
|
|
uint8_t FSCTRL1; /**< Frequency synthesizer control */
|
|
|
|
uint8_t FSCTRL0; /**< Frequency synthesizer control */
|
|
|
|
uint8_t FREQ2; /**< Frequency control word, high byte */
|
|
|
|
uint8_t FREQ1; /**< Frequency control word, middle byte */
|
|
|
|
uint8_t FREQ0; /**< Frequency control word, low byte */
|
|
|
|
uint8_t MDMCFG4; /**< Modem configuration */
|
|
|
|
uint8_t MDMCFG3; /**< Modem configuration */
|
|
|
|
uint8_t MDMCFG2; /**< Modem configuration */
|
|
|
|
uint8_t MDMCFG1; /**< Modem configuration */
|
|
|
|
uint8_t MDMCFG0; /**< Modem configuration */
|
|
|
|
uint8_t DEVIATN; /**< Modem deviation setting */
|
|
|
|
uint8_t MCSM2; /**< Main Radio Control State Machine configuration */
|
|
|
|
uint8_t MCSM1; /**< Main Radio Control State Machine configuration */
|
|
|
|
uint8_t MCSM0; /**< Main Radio Control State Machine configuration */
|
|
|
|
uint8_t FOCCFG; /**< Frequency Offset Compensation configuration */
|
|
|
|
uint8_t BSCFG; /**< Bit Synchronization configuration */
|
|
|
|
uint8_t AGCCTRL2; /**< AGC control */
|
|
|
|
uint8_t AGCCTRL1; /**< AGC control */
|
|
|
|
uint8_t AGCCTRL0; /**< AGC control */
|
|
|
|
uint8_t WOREVT1; /**< High byte Event 0 timeout */
|
|
|
|
uint8_t WOREVT0; /**< Low byte Event 0 timeout */
|
|
|
|
uint8_t WORCTRL; /**< Wake On Radio control */
|
|
|
|
uint8_t FREND1; /**< Front end RX configuration */
|
|
|
|
uint8_t FREND0; /**< Front end TX configuration */
|
|
|
|
uint8_t FSCAL3; /**< Frequency synthesizer calibration */
|
|
|
|
uint8_t FSCAL2; /**< Frequency synthesizer calibration */
|
|
|
|
uint8_t FSCAL1; /**< Frequency synthesizer calibration */
|
|
|
|
uint8_t FSCAL0; /**< Frequency synthesizer calibration */
|
2010-09-22 15:10:42 +02:00
|
|
|
} cc1100_reg_t;
|
|
|
|
|
|
|
|
/** CC1100 radio configuration */
|
|
|
|
typedef struct cc1100_cfg_t {
|
2014-12-06 17:28:13 +01:00
|
|
|
cc1100_reg_t reg_cfg; /**< CC1100 register configuration */
|
|
|
|
uint8_t pa_power; /**< Output power setting */
|
2010-09-22 15:10:42 +02:00
|
|
|
} cc1100_cfg_t;
|
|
|
|
|
|
|
|
/**
|
2013-11-27 17:54:30 +01:00
|
|
|
* @brief Radio Control Flags
|
2010-09-22 15:10:42 +02:00
|
|
|
*/
|
2013-06-21 22:36:48 +02:00
|
|
|
typedef struct cc1100_flags {
|
2014-12-06 17:28:13 +01:00
|
|
|
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 RETC : 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_STATE : 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 */
|
2010-09-22 15:10:42 +02:00
|
|
|
} cc1100_flags;
|
|
|
|
|
|
|
|
/**
|
2013-11-27 17:54:30 +01:00
|
|
|
* @brief Statistic interface for debugging
|
2010-09-22 15:10:42 +02:00
|
|
|
*/
|
|
|
|
typedef struct cc1100_statistic {
|
2013-11-27 17:54:30 +01:00
|
|
|
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;
|
2010-09-22 15:10:42 +02:00
|
|
|
} cc1100_statistic_t;
|
|
|
|
|
|
|
|
enum radio_mode {
|
2014-12-06 17:28:13 +01:00
|
|
|
RADIO_MODE_GET = -1, /**< leave mode unchanged */
|
|
|
|
RADIO_MODE_OFF = 0, /**< turn radio off */
|
|
|
|
RADIO_MODE_ON = 1 /**< turn radio on */
|
2010-09-22 15:10:42 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
enum radio_result {
|
2014-12-06 17:28:13 +01:00
|
|
|
RADIO_PAYLOAD_TOO_LONG = -1, /**< payload too long */
|
|
|
|
RADIO_WRONG_MODE = -2, /**< operation not supported in current mode */
|
|
|
|
RADIO_ADDR_OUT_OF_RANGE = -3, /**< address out of range */
|
|
|
|
RADIO_OP_FAILED = -4, /**< operation failed */
|
|
|
|
RADIO_CS_TIMEOUT = -5, /**< Carrier Sense timeout: air was never free */
|
|
|
|
RADIO_INVALID_PARAM = -6 /**< Invalid parameters passed to radio */
|
2010-09-22 15:10:42 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
/* ------------------------------------------------------------------------- */
|
2013-11-27 17:54:30 +01:00
|
|
|
// Variable declarations (also used in other files)
|
2010-09-22 15:10:42 +02:00
|
|
|
/* ------------------------------------------------------------------------- */
|
|
|
|
|
2013-11-27 17:54:30 +01:00
|
|
|
extern volatile cc1100_flags rflags; ///< Radio flags
|
2010-09-22 15:10:42 +02:00
|
|
|
|
2013-11-27 17:54:30 +01:00
|
|
|
extern volatile uint8_t radio_mode; ///< Radio mode
|
|
|
|
extern volatile uint8_t radio_state; ///< Radio state
|
2010-09-22 15:10:42 +02:00
|
|
|
|
|
|
|
/** Mode callback functions */
|
|
|
|
typedef void (*cc1100_mode_callback_t)(void);
|
|
|
|
extern volatile cc1100_mode_callback_t cc1100_go_idle;
|
|
|
|
extern volatile cc1100_mode_callback_t cc1100_go_receive;
|
|
|
|
extern volatile cc1100_mode_callback_t cc1100_go_after_tx;
|
|
|
|
extern volatile cc1100_mode_callback_t cc1100_setup_mode;
|
|
|
|
|
2013-11-27 17:54:30 +01:00
|
|
|
extern volatile int wor_hwtimer_id; ///< WOR hwtimer identifier
|
2010-09-22 15:10:42 +02:00
|
|
|
|
|
|
|
/* ------------------------------------------------------------------------- */
|
2013-11-27 17:54:30 +01:00
|
|
|
// CC1100 radio driver API
|
2010-09-22 15:10:42 +02:00
|
|
|
/* ------------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
/**
|
2013-11-27 17:54:30 +01:00
|
|
|
* @brief Set chip and state machine to IDLE mode.
|
2010-09-22 15:10:42 +02:00
|
|
|
*/
|
|
|
|
void cc1100_set_idle(void);
|
|
|
|
|
|
|
|
/**
|
2013-11-27 17:54:30 +01:00
|
|
|
* @brief Convert radio mode to textual representation.
|
2010-09-22 15:10:42 +02:00
|
|
|
*
|
2013-11-27 17:54:30 +01:00
|
|
|
* @param mode The radio mode to convert.
|
2010-09-22 15:10:42 +02:00
|
|
|
*
|
2013-11-27 17:54:30 +01:00
|
|
|
* @return Textual representation of radio mode.
|
2010-09-22 15:10:42 +02:00
|
|
|
*/
|
2013-06-21 22:36:48 +02:00
|
|
|
char *cc1100_mode_to_text(uint8_t mode);
|
2010-09-22 15:10:42 +02:00
|
|
|
|
|
|
|
/**
|
2013-11-27 17:54:30 +01:00
|
|
|
* @brief Convert radio state to textual representation.
|
2010-09-22 15:10:42 +02:00
|
|
|
*
|
2014-11-30 22:34:50 +01:00
|
|
|
* @param state The radio state to convert.
|
2010-09-22 15:10:42 +02:00
|
|
|
*
|
2013-11-27 17:54:30 +01:00
|
|
|
* @return Textual representation of radio state.
|
2010-09-22 15:10:42 +02:00
|
|
|
*/
|
2013-06-21 22:36:48 +02:00
|
|
|
char *cc1100_state_to_text(uint8_t state);
|
2010-09-22 15:10:42 +02:00
|
|
|
|
|
|
|
/**
|
2013-11-27 17:54:30 +01:00
|
|
|
* @brief Convert current output power to textual representation.
|
2010-09-22 15:10:42 +02:00
|
|
|
*
|
2013-11-27 17:54:30 +01:00
|
|
|
* @return Textual representation of current output power in dBm.
|
2010-09-22 15:10:42 +02:00
|
|
|
*/
|
2013-06-21 22:36:48 +02:00
|
|
|
char *cc1100_get_output_power(char *buf);
|
2010-09-22 15:10:42 +02:00
|
|
|
|
|
|
|
/**
|
2013-11-27 17:54:30 +01:00
|
|
|
* @brief Read out main radio control FSM state.
|
2010-09-22 15:10:42 +02:00
|
|
|
*
|
2013-11-27 17:54:30 +01:00
|
|
|
* @return Textual representation of current main radio control FSM state.
|
2010-09-22 15:10:42 +02:00
|
|
|
*/
|
2013-06-21 22:36:48 +02:00
|
|
|
char *cc1100_get_marc_state(void);
|
2010-09-22 15:10:42 +02:00
|
|
|
|
|
|
|
/**
|
2013-11-27 17:54:30 +01:00
|
|
|
* @brief hwtimer wrapper function.
|
2010-09-22 15:10:42 +02:00
|
|
|
*
|
|
|
|
* This wrapper function puts the radio to receive mode.
|
|
|
|
*
|
2013-11-27 17:54:30 +01:00
|
|
|
* @param ptr Optional data (only to match hwtimer interface).
|
2010-09-22 15:10:42 +02:00
|
|
|
*/
|
|
|
|
void cc1100_hwtimer_go_receive_wrapper(void *ptr);
|
|
|
|
|
|
|
|
/**
|
2013-11-27 17:54:30 +01:00
|
|
|
* @brief GDO0 interrupt handler.
|
2010-09-22 15:10:42 +02:00
|
|
|
*/
|
|
|
|
void cc1100_gdo0_irq(void);
|
|
|
|
|
|
|
|
/**
|
2013-11-27 17:54:30 +01:00
|
|
|
* @brief GDO2 interrupt handler.
|
2010-09-22 15:10:42 +02:00
|
|
|
*
|
2013-11-27 17:54:30 +01:00
|
|
|
* @note Wakes up MCU on packet reception.
|
2010-09-22 15:10:42 +02:00
|
|
|
*/
|
|
|
|
void cc1100_gdo2_irq(void);
|
|
|
|
|
|
|
|
/**
|
2013-11-27 17:54:30 +01:00
|
|
|
* @brief Transfer packet from CC1100 RX FIFO.
|
2010-09-22 15:10:42 +02:00
|
|
|
*
|
|
|
|
* Transfers a packet from CC1100 RX FIFO into a buffer.
|
|
|
|
*
|
2013-11-27 17:54:30 +01:00
|
|
|
* @param rxBuffer The buffer in which to transfer the packet.
|
|
|
|
* @param length The size of the buffer in which to transfer the packet.
|
2010-09-22 15:10:42 +02:00
|
|
|
*
|
2013-11-27 17:54:30 +01:00
|
|
|
* @return true if operation succeeded; false otherwise (e.g. no data
|
2010-09-22 15:10:42 +02:00
|
|
|
* available, buffer to small or CRC check failed).
|
|
|
|
*/
|
2014-07-07 00:35:29 +02:00
|
|
|
bool cc1100_spi_receive_packet(uint8_t *rxBuffer, radio_packet_length_t length);
|
2010-09-22 15:10:42 +02:00
|
|
|
|
|
|
|
/**
|
2013-11-27 17:54:30 +01:00
|
|
|
* @brief Sends raw data.
|
2010-09-22 15:10:42 +02:00
|
|
|
*
|
|
|
|
* Sends the data of the given buffer. The first two bytes of the
|
|
|
|
* buffer must match the CC1100 packet format (so address interpretation
|
|
|
|
* succeeds).
|
|
|
|
* <p>
|
2013-06-24 22:37:35 +02:00
|
|
|
* This function is not mode safe!The radio must be woke up before
|
2010-09-22 15:10:42 +02:00
|
|
|
* sending and has to be put back manually to receive mode.
|
|
|
|
*
|
2013-11-27 17:54:30 +01:00
|
|
|
* @param tx_buffer Data source buffer.
|
|
|
|
* @param size The size of the data source buffer (maximum: 62 bytes).
|
2010-09-22 15:10:42 +02:00
|
|
|
*/
|
|
|
|
void cc1100_send_raw(uint8_t *tx_buffer, uint8_t size);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @name Carrier Sense interface
|
|
|
|
* @{
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
2013-11-27 17:54:30 +01:00
|
|
|
* @brief Initialize radio for carrier sense detection.
|
2010-09-22 15:10:42 +02:00
|
|
|
*/
|
|
|
|
void cc1100_cs_init(void);
|
|
|
|
|
|
|
|
/**
|
2013-11-27 17:54:30 +01:00
|
|
|
* @brief Enable or disable carrier sense detections.
|
2010-09-22 15:10:42 +02:00
|
|
|
*
|
|
|
|
* Turns interrupts for carrier sense on or off.
|
|
|
|
*
|
2013-11-27 17:54:30 +01:00
|
|
|
* @param enabled true if carrier sense detection should
|
2010-09-22 15:10:42 +02:00
|
|
|
* be enabled; false otherwise.
|
|
|
|
*/
|
|
|
|
void cc1100_cs_set_enabled(bool enabled);
|
|
|
|
|
|
|
|
/**
|
2013-11-27 17:54:30 +01:00
|
|
|
* @brief Read carrier sense signal.
|
2010-09-22 15:10:42 +02:00
|
|
|
*
|
2013-11-27 17:54:30 +01:00
|
|
|
* @return High (1) if air is not free; low (0) if air is
|
2010-09-22 15:10:42 +02:00
|
|
|
* currently free.
|
|
|
|
*/
|
|
|
|
int cc1100_cs_read(void);
|
|
|
|
|
|
|
|
/**
|
2013-11-27 17:54:30 +01:00
|
|
|
* @brief Reads the CCA (Clear Channel Assessment) flag.
|
2010-09-22 15:10:42 +02:00
|
|
|
*
|
|
|
|
* The CCA flag is set by an interrupt service routine, after
|
|
|
|
* carrier sense detection is enabled. So the status of the
|
|
|
|
* carrier sense signal can be evaluated in a non blocking
|
|
|
|
* manner.
|
|
|
|
*
|
2013-11-27 17:54:30 +01:00
|
|
|
* @return The current value of the CCA flag (High: air is free,
|
|
|
|
* low: air is not free).
|
2010-09-22 15:10:42 +02:00
|
|
|
*/
|
|
|
|
int cc1100_cs_read_cca(void);
|
|
|
|
|
|
|
|
/**
|
2013-11-27 17:54:30 +01:00
|
|
|
* @brief Sets the CCA flag.
|
2010-09-22 15:10:42 +02:00
|
|
|
*
|
2013-11-27 17:54:30 +01:00
|
|
|
* @param cca The new value for the CCA flag.
|
2010-09-22 15:10:42 +02:00
|
|
|
*/
|
|
|
|
void cc1100_cs_write_cca(const int cca);
|
|
|
|
|
|
|
|
/** @} */
|
|
|
|
|
|
|
|
/**
|
2013-11-27 17:54:30 +01:00
|
|
|
* @name Statistic interface
|
2010-09-22 15:10:42 +02:00
|
|
|
* @{
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
2013-11-27 17:54:30 +01:00
|
|
|
* @brief Reset radio statistics.
|
2010-09-22 15:10:42 +02:00
|
|
|
*/
|
|
|
|
void cc1100_reset_statistic(void);
|
|
|
|
|
|
|
|
/** @} */
|
|
|
|
|
2014-10-13 15:49:17 +02:00
|
|
|
#ifdef __cplusplus
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2010-09-22 15:10:42 +02:00
|
|
|
/** @} */
|
|
|
|
#endif
|