mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
aa0e5e7afa
binary constants are a GCC extension
331 lines
12 KiB
C
331 lines
12 KiB
C
/*
|
|
* 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.
|
|
*/
|
|
|
|
/**
|
|
* @ingroup drivers_cc110x
|
|
* @{
|
|
*
|
|
* @file
|
|
* @brief On-chip settings for the TI CC1100/CC1101 transceiver
|
|
*
|
|
* @author Marian Buschsieweke <marian.buschsieweke@ovgu.de>
|
|
* @}
|
|
*/
|
|
|
|
#include "cc110x.h"
|
|
#include "cc110x_internal.h"
|
|
|
|
const uint8_t cc110x_conf[CC110X_CONF_SIZE] = {
|
|
/*
|
|
* IOCFG2; default: 0x29 (CHIP_RDYn)
|
|
* Invert GDO2: off,
|
|
* GDO2: Go high when RX data should be read
|
|
*
|
|
* Why not default?
|
|
* GDO2 will be used to be notified about FIFO events (e.g. refilling TX
|
|
* FIFO is needed during transmission, reading from RX FIFO is needed
|
|
* during reception)
|
|
*/
|
|
CC110X_GDO_ON_RX_DATA,
|
|
/*
|
|
* IOCFG1; default: 0x2E (3-state)
|
|
* Invert GDO1: off,
|
|
* GDO1: 3-state (required when SPI interface is shared with other devices)
|
|
*/
|
|
0x2E,
|
|
/*
|
|
* IOCFG0; default: 0x3F (CLK_XOSC/192)
|
|
* Invert GDO0: off,
|
|
* GDO0: Go high on PLL in lock
|
|
*
|
|
* Why not default?
|
|
* GDO0 will be used to be notified when a packet is coming while in RX
|
|
* mode (will go high during transmission) and when sending is completed
|
|
* while in TX (remains high during transmission and will go back low when
|
|
* done).
|
|
*/
|
|
CC110X_GDO_ON_TRANSMISSION,
|
|
/*
|
|
* FIFOTHR; default: 0x07
|
|
* TEST1 = 0x31 and TEST2 = 0x88 when waking up from SLEEP,
|
|
* 0dB RX attenuation,
|
|
* threshold for FIFOs: TX FIFO = 33, RX FIFO = 32
|
|
*/
|
|
0x07,
|
|
/*
|
|
* SYNC1, SYNC0; defaults: 0xD3, 0x91
|
|
* Use 0xD3,0x91 as sync word
|
|
*/
|
|
0xD3, /*< SYNC1 */
|
|
0x91, /*< SYNC0 */
|
|
/*
|
|
* PKTLEN; default: 0xFF
|
|
* Packet length in bytes in fixed length mode, else maximum length
|
|
*/
|
|
0xff,
|
|
/*
|
|
* PKTCTRL1; default: 0x04
|
|
* PQT: Accept all sync words, regardless of preamble quality
|
|
* CRC_AUTOFLUSH: Do not auto-flush RX FIFO on incorrect CRC
|
|
* APPEND_STATUS: Do not add 2 bytes of status information in RX FIFO
|
|
* ADDR_CHK: Filter incoming frames in hardware by address: Only frames
|
|
* with destination address 0x00 (broadcast) or with with the
|
|
* layer-2 address of the transceiver are accepted.
|
|
*
|
|
* Why not default?
|
|
* - The RSSI, LQI and CRC info are also available via status registers.
|
|
* Thus, it is not worth to sacrifice two bytes of RX FIFO for it.
|
|
* - Hardware address filtering could reduce the number IRQs generated
|
|
* (e.g. a huge frame is dropped before it fully received) which reduces
|
|
* the system's load. Thus, it is enabled.
|
|
*/
|
|
CC110X_PKTCTRL1_VALUE | CC110X_PKTCTRL1_ADDR_MATCH,
|
|
/*
|
|
* PKTCTRL0; default: 0x45
|
|
* Data whitening enabled, use RX/TX FIFOs, CRC enabled,
|
|
* variable packet length
|
|
*/
|
|
0x45,
|
|
/*
|
|
* ADDR; default: 0x00
|
|
* Address will overwritten later
|
|
*
|
|
* Why not default?
|
|
* 0x00 is used as broadcast address. Using it would increase chance to
|
|
* receive message during device initialization and thus power consumption.
|
|
*/
|
|
0xFF,
|
|
/*
|
|
* CHANNR; default: 0x00
|
|
* Channel number 0 by default
|
|
*/
|
|
0x00,
|
|
/*
|
|
* FSCTRL1; default: 0x0C
|
|
* Intermediate frequency: 0x0C * 26MHz / 1024 = 304.7kHz
|
|
*
|
|
* Why not defaults?
|
|
* See MDMCFG4, MDMCFG3
|
|
*/
|
|
0x0C,
|
|
/*
|
|
* FSCTRL0; default: 0x00
|
|
* Frequency offset to base frequency: 0kHz
|
|
*/
|
|
0x00,
|
|
/*
|
|
* FREQ2, FREQ1, FREQ0; defaults: 0x1E, 0xC4, 0xEC
|
|
* 0x2146E4 * 26MHz / 65536 = 865.1998 MHz (LoRa Channel 10)
|
|
*
|
|
* Why not defaults?
|
|
* Default is 800.000 MHz, which is not in a license free frequency band.
|
|
* Using LoRa channel 10 instead.
|
|
*/
|
|
0x21, /*< FREQ2 */
|
|
0x46, /*< FREQ1 */
|
|
0xE4, /*< FREQ0 */
|
|
/*
|
|
* MDMCFG4, MDMCFG3; defaults: 0x8C, 0x22
|
|
* 541.67 kHz channel filter bandwidth,
|
|
* 249.94 kBaud symbol rate
|
|
*
|
|
* Why not defaults?
|
|
* Using 250 kBaud (==> 250kBit/s when 2-FSK/GFSK/ASK) to compete with
|
|
* 802.15.4 in data rate.
|
|
* Using settings listed in Table 7 (pages 12ff in the data sheet):
|
|
* - 250 kBaud
|
|
* - GFSK modulation
|
|
* - 304 kHz IF frequency
|
|
* - 540 kHz channel filter bandwidth
|
|
* - 127 kHz deviation
|
|
*/
|
|
0x2D, /*< MDMCFG4 */
|
|
0x3B, /*< MDMCFG3 */
|
|
/*
|
|
* MDMCFG2; default: 0x02
|
|
* DC blocking filter on,
|
|
* GFSK modulation,
|
|
* no manchester code,
|
|
* Enable RX when 30 bits of the 32 bits sync word are received correctly
|
|
*
|
|
* Why not default?
|
|
* Default expects all 16 bits of a two byte sync word to be correctly
|
|
* received. The data sheet recommends to expect 30 bits of a four byte
|
|
* sync word to be correctly received instead (see section 15 on page 37),
|
|
* so we go for this.
|
|
*
|
|
* Using GFSK instead of 2-FSK reduces the modulated spectrum width and is
|
|
* suggested in Table 7 of the datasheet, see MDMCFG4, MDMCFG3
|
|
*/
|
|
0x13,
|
|
/*
|
|
* MDMCFG1, MDMCFG0; defaults: 0x22, 0xF8
|
|
* FEC disabled,
|
|
* 4 preamble bytes,
|
|
* 49.99 kHz distance between channel centre frequencies (closest to 50kHz)
|
|
*
|
|
* Why not defaults?
|
|
* This driver uses an translation layer between physical channels (with
|
|
* 50 kHz distance) and "virtual" channel numbers as seen outside of the
|
|
* driver. This allows to set the frequency in a range of 12.75 MHz with
|
|
* a resolution of 50kHz - this seems to allow to configure all desired
|
|
* channel layouts.
|
|
*/
|
|
0x20, /*< MDMCFG1 */
|
|
0xF8, /*< MDMCFG0 */
|
|
/*
|
|
* DEVIATN; default: 0x47
|
|
* Deviation of frequency to encode data: +- 126.953kHz in 2-FSK/4-FSK/GFSK
|
|
*
|
|
* Why not default?
|
|
* Higher deviation required for reliable operation at 250 kbps data rate.
|
|
*/
|
|
0x62,
|
|
/*
|
|
* MCSM2; default: 0x07
|
|
* No direct RX termination on RSSI measurement (only for ASK/OOK),
|
|
* on RX timeout check for sync word and ignore PQI,
|
|
* no RX timeout
|
|
*/
|
|
0x07,
|
|
/*
|
|
* MCSM1; default: 0x30
|
|
* CCA: Enter TX even when channel is detected busy
|
|
* go to idle after packet received,
|
|
* go to idle after packet sent
|
|
*
|
|
* Why not default?
|
|
* By default the transceiver refuses to enter TX when the channel is
|
|
* detected busy. While this is desired, checking if TX was successfully
|
|
* entered is too slow and generated interrupts on the GDO2 pin are easily
|
|
* missed. However, reading the carrier sense value in the PKTSTATUS
|
|
* registers allows to implement this feature in software in a faster
|
|
* way. In addition to not missing GDO2 interrupts, this allows the send
|
|
* function to give feedback right away when the channel is busy.
|
|
*/
|
|
0x00,
|
|
/*
|
|
* MCSM0; default: 0x04
|
|
* Auto calibration: Disabled, driver has to manage
|
|
* delay to allow supply voltage to stabilize: 149-155 microseconds
|
|
* pin radio control option is off,
|
|
* oscillator is off in sleep state
|
|
*
|
|
* Why not default?
|
|
* Using 149µs-155µs instead of the default 37µs-39µs as PO_TIMEOUT is
|
|
* encouraged by the data sheet for robust operation
|
|
*/
|
|
0x08,
|
|
/*
|
|
* FOCCFG; default: 0x36
|
|
* Freeze frequency offset compensation etc until CS high: yes
|
|
* frequency compensation loop gain before sync word: 3K
|
|
* frequency compensation loop gain after sync word: K/2
|
|
* saturation point for frequency offset compensation: 25% channel bandwidth
|
|
* (incompatible with ASK/OOK)
|
|
*/
|
|
0x36,
|
|
/*
|
|
* BSCFG; default: 0x6C
|
|
* Clock recovery feedback loop integral gain before sync word: 2K_i,
|
|
* clock recovery feedback loop proportional gain before sync word: 3K_p,
|
|
* clock recovery feedback loop integral gain after sync word: K_i/2
|
|
* clock recovery feedback loop proportional gain after sync word: K_p,
|
|
* data rate offset compensation: Disabled
|
|
*/
|
|
0x6C,
|
|
/*
|
|
* AGCCTRL2; default: 0x03
|
|
* Maximum allowable DVGA gain: No limitation, maximum DVGA gain can be used
|
|
* Maximum allowable LNA + LNA2 gain: No limitation
|
|
* target amplitude from channel filter: 33 dB (default)
|
|
*/
|
|
0x03,
|
|
/*
|
|
* AGCCTRL1; default: 0x40
|
|
* LNA priority: Decrease LNA gain first, start decreasing LNA2 gain when
|
|
* LNA gain reached minimum
|
|
* Relative carrier sense threshold: Disabled
|
|
* Absolute carrier sense threshold: At MAGN_TARGET
|
|
*/
|
|
0x40,
|
|
/*
|
|
* AGCCTRL0; default: 0x91
|
|
* HYST_LEVEL: Medium hysteresis, medium asymmetric dead zone, medium gain
|
|
* Adjust gain after how many channel filter samples: After 16 samples
|
|
* Freeze AGC gain: Never; perform gain adjustments as required
|
|
* FILTER_LENGTH:
|
|
* - 16 channel filter samples when 2-FSK, 4-FSK, or MSK is used
|
|
* - 8 dB decision baundry when OOK/ASK is used
|
|
*/
|
|
0x91,
|
|
/*
|
|
* WOREVT1, WOREVT0, WORCTRL; defaults: 0x87, 0x6B, 0xF8
|
|
* Event0 Timeout: 1.000 seconds
|
|
* RC_PD: 1 (The datasheet is quite cryptic regarding this setting)
|
|
* Event1 Timeout: 1.333ms - 1.385ms (depending on crystal frequency)
|
|
* RC oscillator calibration: Enabled
|
|
* WOR_RES: 0 (Relevant for Event0 resolution and maximum timeout)
|
|
*/
|
|
0x87, /*< WOREVT1 */
|
|
0x6B, /*< WOREVT0 */
|
|
0xF8, /*< WORCTRL */
|
|
/*
|
|
* FREND1; default: 0x56
|
|
* LNA_CURRENT: 0b01
|
|
* LNA2MIX_CURRENT: 0b01
|
|
* LODIV_BUF_CURRENT_RW: 0b01
|
|
* MIX_CURRENT: 0b10
|
|
*/
|
|
0x56,
|
|
/*
|
|
* FREND0; default: 0x10
|
|
* LODIV_BUF_CURRENT_TX: 0b01
|
|
* Index in PA_POWER table (in 0..7, default is 0): 4 (0dBm)
|
|
*
|
|
* Why not default:
|
|
* Use a reasonable TX power level instead of the lowest.
|
|
*/
|
|
0x10 | CC110X_TX_POWER_0_DBM,
|
|
/*
|
|
* FSCAL3, FSCAL2, FSCAL1, FSCAL0; defaults: 0xA9, 0x0A, 0x20, 0x0d
|
|
* These values store calibration date of the CC1100/CC1101 transceiver.
|
|
* Once the transceiver performs a calibration, those registers are updated
|
|
* with the new calibration data. In a "stable" environment (e.g. constant
|
|
* channel/frequency, stable humidity, temperature, supply voltage etc.)
|
|
* the obtained values could be written to the transceiver and calibration
|
|
* could be turned off completely.
|
|
*
|
|
* Fast channel hopping could be performed by obtaining the FSCAL1
|
|
* calibration data for each channel and storing it in the MCU's RAM.
|
|
* The other calibration values is frequency independent according to the
|
|
* data sheet, but depends on temperature etc.
|
|
*
|
|
* Once the FSCAL1 values for each channel are stored, the calibration can
|
|
* be disabled and the stored FSCAL1 data can be uploaded for each channel
|
|
* hop. A re-calibration from time to time is suggested to cope with changes
|
|
* in the environment, e.g. in temperature or supply voltage.
|
|
*
|
|
* Why not defaults?
|
|
* Using "magic" values obtained with SmartRF Studio software for 868 MHz
|
|
* band.
|
|
*/
|
|
0xEA, /*< FSCAL3: charge pump current calibration, frequency independent */
|
|
0x2A, /*< FSCAL2: VCO current calibration, frequency independent */
|
|
0x00, /*< FSCAL1: VCO capacitance calibration, frequency dependent */
|
|
0x1F, /*< FSCAL0: "Magic number", use SmartRF Studio to obtain */
|
|
/*
|
|
* RCCTRL1, RCCTRL0; defaults: 0x41, 0x00
|
|
* RC oscillator configuration, no explanation given in data sheet.
|
|
*/
|
|
0x41, /*< RCCTRL1 */
|
|
0x00, /*< RCCTRL0 */
|
|
};
|
|
|
|
const uint8_t cc110x_magic_registers[3] = { 0x88, 0x31, 0x09 };
|