incubator-nuttx/include/nuttx/wireless/cc1101.h

465 lines
17 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/****************************************************************************
* include/nuttx/wireless/cc1101.h
*
* Copyright (C) 2011 Uros Platise. All rights reserved.
*
* Authors: Uros Platise <uros.platise@isotel.eu>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/** \file
* \author Uros Platise
* \brief Chipcon CC1101 Device Driver
**/
#ifndef __INCLUDE_NUTTX_WIRELESS_CC1101_H
#define __INCLUDE_NUTTX_WIRELESS_CC1101_H
#include <nuttx/config.h>
#include <nuttx/spi.h>
#include <stdint.h>
#include <stdbool.h>
/****************************************************************************
* Pre-Processor Declarations
****************************************************************************/
/* Present maximum packet length */
#define CC1101_PACKET_MAXTOTALLEN 63
#define CC1101_PACKET_MAXDATALEN 61
/*
* General Purpose, Test Output Pin Options
*/
/* CC1101 General Purpose Pins */
#define CC1101_PIN_GDO0 2
#define CC1101_PIN_GDO1 1
#define CC1101_PIN_GDO2 0
/* Associated to the RX FIFO: Asserts when RX FIFO is filled at or above
* the RX FIFO threshold. De-asserts when RX FIFO is drained below the
* same threshold. */
#define CC1101_GDO_RXFIFO_THR 0x00
/* Associated to the RX FIFO: Asserts when RX FIFO is filled at or above
* the RX FIFO threshold or the end of packet is reached. De-asserts when
* the RX FIFO is empty. */
#define CC1101_GDO_RXFIFO_THREND 0x01
/* Associated to the TX FIFO: Asserts when the TX FIFO is filled at or
* above the TX FIFO threshold. De-asserts when the TX FIFO is below the
* same threshold. */
#define CC1101_GDO_TXFIFO_THR 0x02
/* Associated to the TX FIFO: Asserts when TX FIFO is full. De-asserts
* when the TX FIFO is drained below theTX FIFO threshold. */
#define CC1101_GDO_TXFIFO_FULL 0x03
/* Asserts when the RX FIFO has overflowed. De-asserts when the FIFO has
* been flushed. */
#define CC1101_GDO_RXFIFO_OVR 0x04
/* Asserts when the TX FIFO has underflowed. De-asserts when the FIFO is
* flushed. */
#define CC1101_GDO_TXFIFO_UNR 0x05
/* Asserts when sync word has been sent / received, and de-asserts at the
* end of the packet. In RX, the pin will de-assert when the optional
* address check fails or the RX FIFO overflows. In TX the pin will
* de-assert if the TX FIFO underflows. */
#define CC1101_GDO_SYNC 0x06
/* Asserts when a packet has been received with CRC OK. De-asserts when
* the first byte is read from the RX FIFO. */
#define CC1101_GDO_PKTRCV_CRCOK 0x07
/* Preamble Quality Reached. Asserts when the PQI is above the programmed
* PQT value. */
#define CC1101_GDO_PREAMBLE 0x08
/* Clear channel assessment. High when RSSI level is below threshold
* (dependent on the current CCA_MODE setting). */
#define CC1101_GDO_CHCLEAR 0x09
/* Lock detector output. The PLL is in lock if the lock detector output
* has a positive transition or is constantly logic high. To check for
* PLL lock the lock detector output should be used as an interrupt for
* the MCU. */
#define CC1101_GDO_LOCK 0x0A
/* Serial Clock. Synchronous to the data in synchronous serial mode.
* In RX mode, data is set up on the falling edge by CC1101 when GDOx_INV=0.
* In TX mode, data is sampled by CC1101 on the rising edge of the serial
* clock when GDOx_INV=0. */
#define CC1101_GDO_SSCLK 0x0B
/* Serial Synchronous Data Output. Used for synchronous serial mode. */
#define CC1101_GDO_SSDO 0x0C
/* Serial Data Output. Used for asynchronous serial mode. */
#define CC1101_GDO_ASDO 0x0D
/* Carrier sense. High if RSSI level is above threshold. */
#define CC1101_GDO_CARRIER 0x0E
/* CRC_OK. The last CRC comparison matched. Cleared when entering or
* restarting RX mode. */
#define CC1101_GDO_CRCOK 0x0F
/* RX_HARD_DATA[1]. Can be used together with RX_SYMBOL_TICK for
* alternative serial RX output. */
#define CC1101_GDO_RXOUT1 0x16
/* RX_HARD_DATA[0]. Can be used together with RX_SYMBOL_TICK for
* alternative serial RX output. */
#define CC1101_GDO_RXOUT0 0x17
/* PA_PD. Note: PA_PD will have the same signal level in SLEEP and TX
* states. To control an external PA or RX/TX switch in applications
* where the SLEEP state is used it is recommended to use GDOx_CFGx=0x2F
* instead. */
#define CC1101_GDO_PA_PD 0x1B
/* LNA_PD. Note: LNA_PD will have the same signal level in SLEEP and RX
* states. To control an external LNA or RX/TX switch in applications
* where the SLEEP state is used it is recommended to use GDOx_CFGx=0x2F
* instead. */
#define CC1101_GDO_LNA_PD 0x1C
/* RX_SYMBOL_TICK. Can be used together with RX_HARD_DATA for alternative
* serial RX output. */
#define CC1101_GDO_RXSYMTICK 0x1D
#define CC1101_GDO_WOR_EVNT0 0x24
#define CC1101_GDO_WOR_EVNT1 0x25
#define CC1101_GDO_CLK32K 0x27
#define CC1101_GDO_CHIP_RDYn 0x29
#define CC1101_GDO_XOSC_STABLE 0x2B
/* GDO0_Z_EN_N. When this output is 0, GDO0 is configured as input
* (for serial TX data). */
#define CC1101_GDO_GDO0_Z_EN_N 0x2D
/* High impedance (3-state). */
#define CC1101_GDO_HIZ 0x2E
/* HW to 0 (HW1 achieved by setting GDOx_INV=1). Can be used to control
* an external LNA/PA or RX/TX switch. */
#define CC1101_GDO_HW 0x2F
/* There are 3 GDO pins, but only one CLK_XOSC/n can be selected as an
* output at any time. If CLK_XOSC/n is to be monitored on one of the
* GDO pins, the other two GDO pins must be configured to values less
* than 0x30. The GDO0 default value is CLK_XOSC/192. To optimize RF
* performance, these signals should not be used while the radio is
* in RX or TX mode. */
#define CC1101_GDO_CLK_XOSC1 0x30
#define CC1101_GDO_CLK_XOSC1_5 0x31
#define CC1101_GDO_CLK_XOSC2 0x32
#define CC1101_GDO_CLK_XOSC3 0x33
#define CC1101_GDO_CLK_XOSC4 0x34
#define CC1101_GDO_CLK_XOSC6 0x35
#define CC1101_GDO_CLK_XOSC8 0x36
#define CC1101_GDO_CLK_XOSC12 0x37
#define CC1101_GDO_CLK_XOSC16 0x38
#define CC1101_GDO_CLK_XOSC24 0x39
#define CC1101_GDO_CLK_XOSC32 0x3A
#define CC1101_GDO_CLK_XOSC48 0x3B
#define CC1101_GDO_CLK_XOSC64 0x3C
#define CC1101_GDO_CLK_XOSC96 0x3D
#define CC1101_GDO_CLK_XOSC128 0x3E
#define CC1101_GDO_CLK_XOSC192 0x3F
#ifndef __ASSEMBLY__
#undef EXTERN
#if defined(__cplusplus)
#define EXTERN extern "C"
extern "C" {
#else
#define EXTERN extern
#endif
/****************************************************************************
* Public Data Types
****************************************************************************/
struct cc1101_dev_s;
/** The RF Settings includes only those fields required to configure
* the RF radio. Other configuration fields depended on this driver
* are configured by the cc1101_init().
*/
struct c1101_rfsettings_s {
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 (when FSK modulation is enabled). */
/* GAP */
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. */
/* GAP */
uint8_t FREND1; /* Front end RX configuration. */
uint8_t FREND0; /* Front end RX 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. */
/* REGULATORY LIMITS */
uint8_t CHMIN; /* Channel Range defintion MIN .. */
uint8_t CHMAX; /* .. and MAX */
uint8_t PAMAX; /* at given maximum output power */
/* Power Table, for ramp-up/down and ASK modulation defined for
* output power values as:
* PA = {-30, -20, -15, -10, -5, 0, 5, 10} [dBm]
*/
uint8_t PA[8];
};
/****************************************************************************
* RF Configuration Database
****************************************************************************/
EXTERN const struct c1101_rfsettings_s
// \todo Recalculate ERP in maximum power level
/* 868 MHz, GFSK, 100 kbps, ISM Region 1 (Europe only)
*
* ISM Region 1 (Europe) only, Band 868870 MHz
*
* Frequency bands for non-specific short range devices in Europe:
*
* Frequency ERP Duty Cycle Bandwidth Remarks
* 868 868.6 MHz +14 dBm < 1% No limits
* 868.7 869.2 MHz +14 dBm < 0.1% No limits
* 869.3 869.4 MHz +10 dBm No limits < 25 kHz Appropriate access protocol required
* 869.4 869.65 MHz +27 dBm < 10% < 25 kHz Channels may be combined to one high speed channel
* 869.7 -870 MHz +7 dBm No limits No limits
*
* Frequency Band For License-Free Specific Applications in Europe
*
* Frequency Application ERP Duty Cycle Bandwidth
* 868.6 868.7 MHz Alarms +10 dBm < 0.1% 25 kHz(1)
* 869.2 869.25 MHz Social Alarms +10 dBm < 0.1% 25 kHz
* 869.25 869.3 MHz Alarms +10 dBm < 0.1% 25 kHz
* 869.65 -869.7 MHz Alarms +14 dBm < 10% 25 kHz
* 863 865 MHz Radio Microphones +10 dBm No limits 200 kHz
* 863 -865 MHz Wireless Audio Applications +10 dBm No limits 300 kHz
*
* Duty Cycle Limit Total On Time Maximum On Time of Minimum Off Time of
* Within One Hour One Transmission Two Transmission
* < 0.1% 3.6 seconds 0.72 seconds 0.72 seconds
* < 1% 36 seconds 3.6 seconds 1.8 seconds
* < 10% 360 seconds 36 seconds 3.6 seconds
*
* Reference: TI Application Report: swra048.pdf, May 2005
* ISM-Band and Short Range Device Regulatory Compliance Overview
*/
cc1101_rfsettings_ISM1_868MHzGFSK100kbps,
/* 905 MHz, GFSK, 250 kbps, ISM Region 2 (America only)
*
* ISM Region 2 (America) only, Band 902928 MHz
*
* Cordless phones 1 W
* Microwave ovens 750 W
* Industrial heaters 100 kW
* Military radar 1000 kW
*/
cc1101_rfsettings_ISM2_905MHzGFSK250kbps;
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
/** Initialize Chipcon CC1101 Chip.
* After initialization CC1101 is ready to listen, receive and transmit
* messages on the default channel 0 at given RF configuration.
*
* \param spi SPI Device Structure
* \param isrpin Select the CC1101_PIN_GDOx used to signal interrupts
* \param rfsettings Pointer to default RF Settings loaded at boot time.
* \return Pointer to newly allocated CC1101 structure or NULL on error with errno set.
*
* Possible errno as set by this function on error:
* - ENODEV: When device addressed is not compatible or it is not a CC1101
* - EFAULT: When there is no device
* - ENOMEM: Out of kernel memory to allocate the device
* - EBUSY: When device is already addressed by other device driver (not yet supported by low-level driver)
**/
EXTERN struct cc1101_dev_s * cc1101_init(struct spi_dev_s * spi, uint8_t isrpin,
uint32_t pinset, const struct c1101_rfsettings_s * rfsettings);
/** Deinitialize Chipcon CC1101 Chip
*
* \param dev Device to CC1101 device structure, as returned by the cc1101_init()
* \return OK On success
*
**/
EXTERN int cc1101_deinit(struct cc1101_dev_s * dev);
/** Power up device, start conversion. \return Zero on success. */
EXTERN int cc1101_powerup(struct cc1101_dev_s * dev);
/** Power down device, stop conversion. \return Zero on success. */
EXTERN int cc1101_powerdown(struct cc1101_dev_s * dev);
/** Set Multi Purpose Output Function. \return Zero on success. */
EXTERN int cc1101_setgdo(struct cc1101_dev_s * dev, uint8_t pin, uint8_t function);
/** Set RF settings. Use one from the database above. */
EXTERN int cc1101_setrf(struct cc1101_dev_s * dev, const struct c1101_rfsettings_s *settings);
/** Set Channel.
* Note that regulatory check is made and sending may be prohibited.
*
* \retval 0 On success, sending and receiving is allowed.
* \retval 1 Only receive mode is allowed.
* \retval <0 On error.
*/
EXTERN int cc1101_setchannel(struct cc1101_dev_s * dev, uint8_t channel);
/** Set Output Power
*
* \param power Value from 0 - 8, where 0 means power off, and values
* from 1 .. 8 denote the following output power in dBm:
* {-30, -20, -15, -10, -5, 0, 5, 10} [dBm]
*
* If power is above the regulatory limit (defined by the RF settings)
* it is limited.
*
* \return Actual output power in range from 0..8.
*/
EXTERN uint8_t cc1101_setpower(struct cc1101_dev_s * dev, uint8_t power);
/** Convert RSSI as obtained from CC1101 to [dBm] */
EXTERN int cc1101_calcRSSIdBm(int rssi);
/** Enter receive mode and wait for a packet.
* If transmission is in progress, receive mode is entered upon its
* completion. As long cc1101_idle() is not called, each transmission
* returns to receive mode.
*
* \param dev Device to CC1101 structure
* \return Zero on success.
*/
EXTERN int cc1101_receive(struct cc1101_dev_s * dev);
/** Read received packet
*
* If size of buffer is too small then the remaining part of data can
* be discarded by the driver.
*
* Packet contains raw data, including the two bytes:
* - RSSI and
* - LQI
* appended at the end of the message.
*
* To inquery about the data pending size you the following:
* - pass buf=NULL and size > 0, returns pending data packet size
* - pass buf=NULL and size = 0, returns maximum data packet size
*
* NOTE: messages length are typically defined by the MAC, transmit/
* receive windows at some rate.
*/
EXTERN int cc1101_read(struct cc1101_dev_s * dev, uint8_t * buf, size_t size);
/** Write data to be send, using the cc1101_send()
*
* \param dev Device to CC1101 structure
* \param buf Pointer to data.
* \param size Size must be within limits, otherwise data is truncated.
* Present driver limitation supports a single cc1101_write()
* prioer cc1101_send() is called.
*/
EXTERN int cc1101_write(struct cc1101_dev_s * dev, const uint8_t * buf, size_t size);
/** Send data previously writtenusing cc1101_write()
*
* \param dev Device to CC1101 structure
* \return Zero on success.
*/
EXTERN int cc1101_send(struct cc1101_dev_s * dev);
/** Enter idle state (after reception and transmission completes).
*
* \return Zero on success.
*/
EXTERN int cc1101_idle(struct cc1101_dev_s * dev);
#undef EXTERN
#if defined(__cplusplus)
}
#endif
#endif /* __ASSEMBLY__ */
#endif /* __INCLUDE_NUTTX_WIRELESS_CC1101_H */