RadioLibSmol/src/modules/CC1101.h
2019-06-16 14:33:46 +02:00

767 lines
50 KiB
C++

#ifndef _RADIOLIB_CC1101_H
#define _RADIOLIB_CC1101_H
#include "TypeDef.h"
#include "Module.h"
#include "../protocols/PhysicalLayer.h"
// CC1101 physical layer properties
#define CC1101_CRYSTAL_FREQ 26.0
#define CC1101_DIV_EXPONENT 16
#define CC1101_MAX_PACKET_LENGTH 63
// CC1101 SPI commands
#define CC1101_CMD_READ 0b10000000
#define CC1101_CMD_WRITE 0b00000000
#define CC1101_CMD_BURST 0b01000000
#define CC1101_CMD_ACCESS_STATUS_REG 0b01000000
#define CC1101_CMD_FIFO_RX 0b10000000
#define CC1101_CMD_FIFO_TX 0b00000000
#define CC1101_CMD_RESET 0x30
#define CC1101_CMD_FSTXON 0x31
#define CC1101_CMD_XOFF 0x32
#define CC1101_CMD_CAL 0x33
#define CC1101_CMD_RX 0x34
#define CC1101_CMD_TX 0x35
#define CC1101_CMD_IDLE 0x36
#define CC1101_CMD_WOR 0x38
#define CC1101_CMD_POWER_DOWN 0x39
#define CC1101_CMD_FLUSH_RX 0x3A
#define CC1101_CMD_FLUSH_TX 0x3B
#define CC1101_CMD_WOR_RESET 0x3C
#define CC1101_CMD_NOP 0x3D
// CC1101 register map
#define CC1101_REG_IOCFG2 0x00
#define CC1101_REG_IOCFG1 0x01
#define CC1101_REG_IOCFG0 0x02
#define CC1101_REG_FIFOTHR 0x03
#define CC1101_REG_SYNC1 0x04
#define CC1101_REG_SYNC0 0x05
#define CC1101_REG_PKTLEN 0x06
#define CC1101_REG_PKTCTRL1 0x07
#define CC1101_REG_PKTCTRL0 0x08
#define CC1101_REG_ADDR 0x09
#define CC1101_REG_CHANNR 0x0A
#define CC1101_REG_FSCTRL1 0x0B
#define CC1101_REG_FSCTRL0 0x0C
#define CC1101_REG_FREQ2 0x0D
#define CC1101_REG_FREQ1 0x0E
#define CC1101_REG_FREQ0 0x0F
#define CC1101_REG_MDMCFG4 0x10
#define CC1101_REG_MDMCFG3 0x11
#define CC1101_REG_MDMCFG2 0x12
#define CC1101_REG_MDMCFG1 0x13
#define CC1101_REG_MDMCFG0 0x14
#define CC1101_REG_DEVIATN 0x15
#define CC1101_REG_MCSM2 0x16
#define CC1101_REG_MCSM1 0x17
#define CC1101_REG_MCSM0 0x18
#define CC1101_REG_FOCCFG 0x19
#define CC1101_REG_BSCFG 0x1A
#define CC1101_REG_AGCCTRL2 0x1B
#define CC1101_REG_AGCCTRL1 0x1C
#define CC1101_REG_AGCCTRL0 0x1D
#define CC1101_REG_WOREVT1 0x1E
#define CC1101_REG_WOREVT0 0x1F
#define CC1101_REG_WORCTRL 0x20
#define CC1101_REG_FREND1 0x21
#define CC1101_REG_FREND0 0x22
#define CC1101_REG_FSCAL3 0x23
#define CC1101_REG_FSCAL2 0x24
#define CC1101_REG_FSCAL1 0x25
#define CC1101_REG_FSCAL0 0x26
#define CC1101_REG_RCCTRL1 0x27
#define CC1101_REG_RCCTRL0 0x28
#define CC1101_REG_FSTEST 0x29
#define CC1101_REG_PTEST 0x2A
#define CC1101_REG_AGCTEST 0x2B
#define CC1101_REG_TEST2 0x2C
#define CC1101_REG_TEST1 0x2D
#define CC1101_REG_TEST0 0x2E
#define CC1101_REG_PARTNUM 0x30
#define CC1101_REG_VERSION 0x31
#define CC1101_REG_FREQEST 0x32
#define CC1101_REG_LQI 0x33
#define CC1101_REG_RSSI 0x34
#define CC1101_REG_MARCSTATE 0x35
#define CC1101_REG_WORTIME1 0x36
#define CC1101_REG_WORTIME0 0x37
#define CC1101_REG_PKTSTATUS 0x38
#define CC1101_REG_VCO_VC_DAC 0x39
#define CC1101_REG_TXBYTES 0x3A
#define CC1101_REG_RXBYTES 0x3B
#define CC1101_REG_RCCTRL1_STATUS 0x3C
#define CC1101_REG_RCCTRL0_STATUS 0x3D
#define CC1101_REG_PATABLE 0x3E
#define CC1101_REG_FIFO 0x3F
// CC1101_REG_IOCFG2 MSB LSB DESCRIPTION
#define CC1101_GDO2_NORM 0b00000000 // 6 6 GDO2 output: active high (default)
#define CC1101_GDO2_INV 0b01000000 // 6 6 active low
// CC1101_REG_IOCFG1
#define CC1101_GDO1_DS_LOW 0b00000000 // 7 7 GDO1 output drive strength: low (default)
#define CC1101_GDO1_DS_HIGH 0b10000000 // 7 7 high
#define CC1101_GDO1_NORM 0b00000000 // 6 6 GDO1 output: active high (default)
#define CC1101_GDO1_INV 0b01000000 // 6 6 active low
// CC1101_REG_IOCFG0
#define CC1101_GDO0_TEMP_SENSOR_OFF 0b00000000 // 7 7 analog temperature sensor output: disabled (default)
#define CC1101_GDO0_TEMP_SENSOR_ON 0b10000000 // 7 0 enabled
#define CC1101_GDO0_NORM 0b00000000 // 6 6 GDO0 output: active high (default)
#define CC1101_GDO0_INV 0b01000000 // 6 6 active low
// CC1101_REG_IOCFG2 + REG_IOCFG1 + REG_IOCFG0
#define CC1101_GDOX_RX_FIFO_FULL 0x00 // 5 0 Rx FIFO full or above threshold
#define CC1101_GDOX_RX_FIFO_FULL_OR_PKT_END 0x01 // 5 0 Rx FIFO full or above threshold or reached packet end
#define CC1101_GDOX_TX_FIFO_ABOVE_THR 0x02 // 5 0 Tx FIFO above threshold
#define CC1101_GDOX_TX_FIFO_FULL 0x03 // 5 0 Tx FIFO full
#define CC1101_GDOX_RX_FIFO_OVERFLOW 0x04 // 5 0 Rx FIFO overflowed
#define CC1101_GDOX_TX_FIFO_UNDERFLOW 0x05 // 5 0 Tx FIFO underflowed
#define CC1101_GDOX_SYNC_WORD_SENT_OR_RECEIVED 0x06 // 5 0 sync word was sent or received
#define CC1101_GDOX_PKT_RECEIVED_CRC_OK 0x07 // 5 0 packet received and CRC check passed
#define CC1101_GDOX_PREAMBLE_QUALITY_REACHED 0x08 // 5 0 received preamble quality is above threshold
#define CC1101_GDOX_CHANNEL_CLEAR 0x09 // 5 0 RSSI level below threshold (channel is clear)
#define CC1101_GDOX_PLL_LOCKED 0x0A // 5 0 PLL is locked
#define CC1101_GDOX_SERIAL_CLOCK 0x0B // 5 0 serial data clock
#define CC1101_GDOX_SERIAL_DATA_SYNC 0x0C // 5 0 serial data output in: synchronous mode
#define CC1101_GDOX_SERIAL_DATA_ASYNC 0x0D // 5 0 asynchronous mode
#define CC1101_GDOX_CARRIER_SENSE 0x0E // 5 0 RSSI above threshold
#define CC1101_GDOX_CRC_OK 0x0F // 5 0 CRC check passed
#define CC1101_GDOX_RX_HARD_DATA1 0x16 // 5 0 direct access to demodulated data
#define CC1101_GDOX_RX_HARD_DATA0 0x17 // 5 0 direct access to demodulated data
#define CC1101_GDOX_PA_PD 0x1B // 5 0 power amplifier circuit is powered down
#define CC1101_GDOX_LNA_PD 0x1C // 5 0 low-noise amplifier circuit is powered down
#define CC1101_GDOX_RX_SYMBOL_TICK 0x1D // 5 0 direct access to symbol tick of received data
#define CC1101_GDOX_WOR_EVNT0 0x24 // 5 0 wake-on-radio event 0
#define CC1101_GDOX_WOR_EVNT1 0x25 // 5 0 wake-on-radio event 1
#define CC1101_GDOX_CLK_256 0x26 // 5 0 256 Hz clock
#define CC1101_GDOX_CLK_32K 0x27 // 5 0 32 kHz clock
#define CC1101_GDOX_CHIP_RDYN 0x29 // 5 0 (default for GDO2)
#define CC1101_GDOX_XOSC_STABLE 0x2B // 5 0
#define CC1101_GDOX_HIGH_Z 0x2E // 5 0 high impedance state (default for GDO1)
#define CC1101_GDOX_HW_TO_0 0x2F // 5 0
#define CC1101_GDOX_CLOCK_XOSC_1 0x30 // 5 0 crystal oscillator clock: f = f(XOSC)/1
#define CC1101_GDOX_CLOCK_XOSC_1_5 0x31 // 5 0 f = f(XOSC)/1.5
#define CC1101_GDOX_CLOCK_XOSC_2 0x32 // 5 0 f = f(XOSC)/2
#define CC1101_GDOX_CLOCK_XOSC_3 0x33 // 5 0 f = f(XOSC)/3
#define CC1101_GDOX_CLOCK_XOSC_4 0x34 // 5 0 f = f(XOSC)/4
#define CC1101_GDOX_CLOCK_XOSC_6 0x35 // 5 0 f = f(XOSC)/6
#define CC1101_GDOX_CLOCK_XOSC_8 0x36 // 5 0 f = f(XOSC)/8
#define CC1101_GDOX_CLOCK_XOSC_12 0x37 // 5 0 f = f(XOSC)/12
#define CC1101_GDOX_CLOCK_XOSC_16 0x38 // 5 0 f = f(XOSC)/16
#define CC1101_GDOX_CLOCK_XOSC_24 0x39 // 5 0 f = f(XOSC)/24
#define CC1101_GDOX_CLOCK_XOSC_32 0x3A // 5 0 f = f(XOSC)/32
#define CC1101_GDOX_CLOCK_XOSC_48 0x3B // 5 0 f = f(XOSC)/48
#define CC1101_GDOX_CLOCK_XOSC_64 0x3C // 5 0 f = f(XOSC)/64
#define CC1101_GDOX_CLOCK_XOSC_96 0x3D // 5 0 f = f(XOSC)/96
#define CC1101_GDOX_CLOCK_XOSC_128 0x3E // 5 0 f = f(XOSC)/128
#define CC1101_GDOX_CLOCK_XOSC_192 0x3F // 5 0 f = f(XOSC)/192 (default for GDO0)
// CC1101_REG_FIFOTHR
#define CC1101_ADC_RETENTION_OFF 0b00000000 // 6 6 do not retain ADC settings in sleep mode (default)
#define CC1101_ADC_RETENTION_ON 0b01000000 // 6 6 retain ADC settings in sleep mode
#define CC1101_RX_ATTEN_0_DB 0b00000000 // 5 4 Rx attenuation: 0 dB (default)
#define CC1101_RX_ATTEN_6_DB 0b00010000 // 5 4 6 dB
#define CC1101_RX_ATTEN_12_DB 0b00100000 // 5 4 12 dB
#define CC1101_RX_ATTEN_18_DB 0b00110000 // 5 4 18 dB
#define CC1101_FIFO_THR 0b00000111 // 5 4 Rx FIFO threshold [bytes] = CC1101_FIFO_THR * 4; Tx FIFO threshold [bytes] = 65 - (CC1101_FIFO_THR * 4)
// CC1101_REG_SYNC1
#define CC1101_SYNC_WORD_MSB 0xD3 // 7 0 sync word MSB
// CC1101_REG_SYNC0
#define CC1101_SYNC_WORD_LSB 0x91 // 7 0 sync word LSB
// CC1101_REG_PKTLEN
#define CC1101_PACKET_LENGTH 0xFF // 7 0 packet length in bytes
// CC1101_REG_PKTCTRL1
#define CC1101_PQT 0x00 // 7 5 preamble quality threshold
#define CC1101_CRC_AUTOFLUSH_OFF 0b00000000 // 3 3 automatic Rx FIFO flush on CRC check fail: disabled (default)
#define CC1101_CRC_AUTOFLUSH_ON 0b00001000 // 3 3 enabled
#define CC1101_APPEND_STATUS_OFF 0b00000000 // 2 2 append 2 status bytes to packet: disabled
#define CC1101_APPEND_STATUS_ON 0b00000100 // 2 2 enabled (default)
#define CC1101_ADR_CHK_NONE 0b00000000 // 1 0 address check: none (default)
#define CC1101_ADR_CHK_NO_BROADCAST 0b00000001 // 1 0 without broadcast
#define CC1101_ADR_CHK_SINGLE_BROADCAST 0b00000010 // 1 0 broadcast address 0x00
#define CC1101_ADR_CHK_DOUBLE_BROADCAST 0b00000011 // 1 0 broadcast addresses 0x00 and 0xFF
// CC1101_REG_PKTCTRL0
#define CC1101_WHITE_DATA_OFF 0b00000000 // 6 6 data whitening: disabled
#define CC1101_WHITE_DATA_ON 0b01000000 // 6 6 enabled (default)
#define CC1101_PKT_FORMAT_NORMAL 0b00000000 // 5 4 packet format: normal (FIFOs)
#define CC1101_PKT_FORMAT_SYNCHRONOUS 0b00010000 // 5 4 synchronous serial
#define CC1101_PKT_FORMAT_RANDOM 0b00100000 // 5 4 random transmissions
#define CC1101_PKT_FORMAT_ASYNCHRONOUS 0b00110000 // 5 4 asynchronous serial
#define CC1101_CRC_OFF 0b00000000 // 2 2 CRC disabled
#define CC1101_CRC_ON 0b00000100 // 2 2 CRC enabled (default)
#define CC1101_LENGTH_CONFIG_FIXED 0b00000000 // 1 0 packet length: fixed
#define CC1101_LENGTH_CONFIG_VARIABLE 0b00000001 // 1 0 variable (default)
#define CC1101_LENGTH_CONFIG_INFINITE 0b00000010 // 1 0 infinite
// CC1101_REG_ADDR
#define CC1101_DEVICE_ADDR 0x00 // 7 0 device address
// CC1101_REG_CHANNR
#define CC1101_CHAN 0x00 // 7 0 channel number
// CC1101_REG_FSCTRL1
#define CC1101_FREQ_IF 0x0F // 4 0 IF frequency setting; f_IF = (f(XOSC) / 2^10) * CC1101_FREQ_IF
// CC1101_REG_FSCTRL0
#define CC1101_FREQOFF 0x00 // 7 0 base frequency offset (2s-compliment)
// CC1101_REG_FREQ2 + REG_FREQ1 + REG_FREQ0
#define CC1101_FREQ_MSB 0x1E // 5 0 base frequency setting: f_carrier = (f(XOSC) / 2^16) * FREQ
#define CC1101_FREQ_MID 0xC4 // 7 0 where f(XOSC) = 26 MHz
#define CC1101_FREQ_LSB 0xEC // 7 0 FREQ = 3-byte value of FREQ registers
// CC1101_REG_MDMCFG4
#define CC1101_CHANBW_E 0b10000000 // 7 6 channel bandwidth: BW_channel = f(XOSC) / (8 * (4 + CHANBW_M)*2^CHANBW_E) [Hz]
#define CC1101_CHANBW_M 0b00000000 // 5 4 default value for 26 MHz crystal: 203 125 Hz
#define CC1101_DRATE_E 0x0C // 3 0 symbol rate: R_data = (((256 + DRATE_M) * 2^DRATE_E) / 2^28) * f(XOSC) [Baud]
// CC1101_REG_MDMCFG3
#define CC1101_DRATE_M 0x22 // 7 0 default value for 26 MHz crystal: 115 051 Baud
// CC1101_REG_MDMCFG2
#define CC1101_DEM_DCFILT_OFF 0b10000000 // 7 7 digital DC filter: disabled
#define CC1101_DEM_DCFILT_ON 0b00000000 // 7 7 enabled - only for data rates above 250 kBaud (default)
#define CC1101_MOD_FORMAT_2_FSK 0b00000000 // 6 4 modulation format: 2-FSK (default)
#define CC1101_MOD_FORMAT_GFSK 0b00010000 // 6 4 GFSK
#define CC1101_MOD_FORMAT_ASK_OOK 0b00110000 // 6 4 ASK/OOK
#define CC1101_MOD_FORMAT_4_FSK 0b01000000 // 6 4 4-FSK
#define CC1101_MOD_FORMAT_MFSK 0b01110000 // 6 4 MFSK - only for data rates above 26 kBaud
#define CC1101_MANCHESTER_EN_OFF 0b00000000 // 3 3 Manchester encoding: disabled (default)
#define CC1101_MANCHESTER_EN_ON 0b00001000 // 3 3 enabled
#define CC1101_SYNC_MODE_NONE 0b00000000 // 2 0 synchronization: no preamble sync
#define CC1101_SYNC_MODE_15_16 0b00000001 // 2 0 15/16 sync word bits
#define CC1101_SYNC_MODE_16_16 0b00000010 // 2 0 16/16 sync word bits (default)
#define CC1101_SYNC_MODE_30_32 0b00000011 // 2 0 30/32 sync word bits
#define CC1101_SYNC_MODE_NONE_THR 0b00000100 // 2 0 no preamble sync, carrier sense above threshold
#define CC1101_SYNC_MODE_15_16_THR 0b00000101 // 2 0 15/16 sync word bits, carrier sense above threshold
#define CC1101_SYNC_MODE_16_16_THR 0b00000110 // 2 0 16/16 sync word bits, carrier sense above threshold
#define CC1101_SYNC_MODE_30_32_THR 0b00000111 // 2 0 30/32 sync word bits, carrier sense above threshold
// CC1101_REG_MDMCFG1
#define CC1101_FEC_OFF 0b00000000 // 7 7 forward error correction: disabled (default)
#define CC1101_FEC_ON 0b10000000 // 7 7 enabled - only for fixed packet length
#define CC1101_NUM_PREAMBLE_2 0b00000000 // 6 4 number of preamble bytes: 2
#define CC1101_NUM_PREAMBLE_3 0b00010000 // 6 4 3
#define CC1101_NUM_PREAMBLE_4 0b00100000 // 6 4 4 (default)
#define CC1101_NUM_PREAMBLE_6 0b00110000 // 6 4 6
#define CC1101_NUM_PREAMBLE_8 0b01000000 // 6 4 8
#define CC1101_NUM_PREAMBLE_12 0b01010000 // 6 4 12
#define CC1101_NUM_PREAMBLE_16 0b01100000 // 6 4 16
#define CC1101_NUM_PREAMBLE_24 0b01110000 // 6 4 24
#define CC1101_CHANSPC_E 0x02 // 1 0 channel spacing: df_channel = (f(XOSC) / 2^18) * (256 + CHANSPC_M) * 2^CHANSPC_E [Hz]
// CC1101_REG_MDMCFG0
#define CC1101_CHANSPC_M 0xF8 // 7 0 default value for 26 MHz crystal: 199 951 kHz
// CC1101_REG_DEVIATN
#define CC1101_DEVIATION_E 0b01000000 // 6 4 frequency deviation: f_dev = (f(XOSC) / 2^17) * (8 + DEVIATION_M) * 2^DEVIATION_E [Hz]
#define CC1101_DEVIATION_M 0b00000111 // 2 0 default value for 26 MHz crystal: +- 47 607 Hz
#define CC1101_MSK_PHASE_CHANGE_PERIOD 0x07 // 2 0 phase change symbol period fraction: 1 / (MSK_PHASE_CHANGE_PERIOD + 1)
// CC1101_REG_MCSM2
#define CC1101_RX_TIMEOUT_RSSI_OFF 0b00000000 // 4 4 Rx timeout based on RSSI value: disabled (default)
#define CC1101_RX_TIMEOUT_RSSI_ON 0b00010000 // 4 4 enabled
#define CC1101_RX_TIMEOUT_QUAL_OFF 0b00000000 // 3 3 check for sync word on Rx timeout
#define CC1101_RX_TIMEOUT_QUAL_ON 0b00001000 // 3 3 check for PQI set on Rx timeout
#define CC1101_RX_TIMEOUT_OFF 0b00000111 // 2 0 Rx timeout: disabled (default)
#define CC1101_RX_TIMEOUT_MAX 0b00000000 // 2 0 max value (actual value depends on WOR_RES, EVENT0 and f(XOSC))
// CC1101_REG_MCSM1
#define CC1101_CCA_MODE_ALWAYS 0b00000000 // 5 4 clear channel indication: always
#define CC1101_CCA_MODE_RSSI_THR 0b00010000 // 5 4 RSSI below threshold
#define CC1101_CCA_MODE_RX_PKT 0b00100000 // 5 4 unless receiving packet
#define CC1101_CCA_MODE_RSSI_THR_RX_PKT 0b00110000 // 5 4 RSSI below threshold unless receiving packet (default)
#define CC1101_RXOFF_IDLE 0b00000000 // 3 2 next mode after packet reception: idle (default)
#define CC1101_RXOFF_FSTXON 0b00000100 // 3 2 FSTxOn
#define CC1101_RXOFF_TX 0b00001000 // 3 2 Tx
#define CC1101_RXOFF_RX 0b00001100 // 3 2 Rx
#define CC1101_TXOFF_IDLE 0b00000000 // 1 0 next mode after packet transmission: idle (default)
#define CC1101_TXOFF_FSTXON 0b00000001 // 1 0 FSTxOn
#define CC1101_TXOFF_TX 0b00000010 // 1 0 Tx
#define CC1101_TXOFF_RX 0b00000011 // 1 0 Rx
// CC1101_REG_MCSM0
#define CC1101_FS_AUTOCAL_NEVER 0b00000000 // 5 4 automatic calibration: never (default)
#define CC1101_FS_AUTOCAL_IDLE_TO_RXTX 0b00010000 // 5 4 every transition from idle to Rx/Tx
#define CC1101_FS_AUTOCAL_RXTX_TO_IDLE 0b00100000 // 5 4 every transition from Rx/Tx to idle
#define CC1101_FS_AUTOCAL_RXTX_TO_IDLE_4TH 0b00110000 // 5 4 every 4th transition from Rx/Tx to idle
#define CC1101_PO_TIMEOUT_COUNT_1 0b00000000 // 3 2 number of counter expirations before CHP_RDYN goes low: 1 (default)
#define CC1101_PO_TIMEOUT_COUNT_16 0b00000100 // 3 2 16
#define CC1101_PO_TIMEOUT_COUNT_64 0b00001000 // 3 2 64
#define CC1101_PO_TIMEOUT_COUNT_256 0b00001100 // 3 2 256
#define CC1101_PIN_CTRL_OFF 0b00000000 // 1 1 pin radio control: disabled (default)
#define CC1101_PIN_CTRL_ON 0b00000010 // 1 1 enabled
#define CC1101_XOSC_FORCE_OFF 0b00000000 // 0 0 do not force XOSC to remain on in sleep (default)
#define CC1101_XOSC_FORCE_ON 0b00000001 // 0 0 force XOSC to remain on in sleep
// CC1101_REG_FOCCFG
#define CC1101_FOC_BS_CS_GATE_OFF 0b00000000 // 5 5 do not freeze frequency compensation until CS goes high
#define CC1101_FOC_BS_CS_GATE_ON 0b00100000 // 5 5 freeze frequency compensation until CS goes high (default)
#define CC1101_FOC_PRE_K 0b00000000 // 4 3 frequency compensation loop gain before sync word: K
#define CC1101_FOC_PRE_2K 0b00001000 // 4 3 2K
#define CC1101_FOC_PRE_3K 0b00010000 // 4 3 3K (default)
#define CC1101_FOC_PRE_4K 0b00011000 // 4 3 4K
#define CC1101_FOC_POST_K 0b00000000 // 2 2 frequency compensation loop gain after sync word: same as FOC_PRE
#define CC1101_FOC_POST_K_2 0b00000100 // 2 2 K/2 (default)
#define CC1101_FOC_LIMIT_NO_COMPENSATION 0b00000000 // 1 0 frequency compensation saturation point: no compensation - required for ASK/OOK
#define CC1101_FOC_LIMIT_BW_CHAN_8 0b00000001 // 1 0 +- BW_chan/8
#define CC1101_FOC_LIMIT_BW_CHAN_4 0b00000010 // 1 0 +- BW_chan/4 (default)
#define CC1101_FOC_LIMIT_BW_CHAN_2 0b00000011 // 1 0 +- BW_chan/2
// CC1101_REG_BSCFG
#define CC1101_BS_PRE_KI 0b00000000 // 7 6 clock recovery integral gain before sync word: Ki
#define CC1101_BS_PRE_2KI 0b01000000 // 7 6 2Ki (default)
#define CC1101_BS_PRE_3KI 0b10000000 // 7 6 3Ki
#define CC1101_BS_PRE_4KI 0b11000000 // 7 6 4Ki
#define CC1101_BS_PRE_KP 0b00000000 // 5 4 clock recovery proportional gain before sync word: Kp
#define CC1101_BS_PRE_2KP 0b00010000 // 5 4 2Kp
#define CC1101_BS_PRE_3KP 0b00100000 // 5 4 3Kp (default)
#define CC1101_BS_PRE_4KP 0b00110000 // 5 4 4Kp
#define CC1101_BS_POST_KI 0b00000000 // 3 3 clock recovery integral gain after sync word: same as BS_PRE
#define CC1101_BS_POST_KI_2 0b00001000 // 3 3 Ki/2 (default)
#define CC1101_BS_POST_KP 0b00000000 // 2 2 clock recovery proportional gain after sync word: same as BS_PRE
#define CC1101_BS_POST_KP_1 0b00000100 // 2 2 Kp (default)
#define CC1101_BS_LIMIT_NO_COMPENSATION 0b00000000 // 1 0 data rate compensation saturation point: no compensation
#define CC1101_BS_LIMIT_3_125 0b00000001 // 1 0 +- 3.125 %
#define CC1101_BS_LIMIT_6_25 0b00000010 // 1 0 +- 6.25 %
#define CC1101_BS_LIMIT_12_5 0b00000011 // 1 0 +- 12.5 %
// CC1101_REG_AGCCTRL2
#define CC1101_MAX_DVGA_GAIN_0 0b00000000 // 7 6 reduce maximum available DVGA gain: no reduction (default)
#define CC1101_MAX_DVGA_GAIN_1 0b01000000 // 7 6 disable top gain setting
#define CC1101_MAX_DVGA_GAIN_2 0b10000000 // 7 6 disable top two gain setting
#define CC1101_MAX_DVGA_GAIN_3 0b11000000 // 7 6 disable top three gain setting
#define CC1101_LNA_GAIN_REDUCE_0_DB 0b00000000 // 5 3 reduce maximum LNA gain by: 0 dB (default)
#define CC1101_LNA_GAIN_REDUCE_2_6_DB 0b00001000 // 5 3 2.6 dB
#define CC1101_LNA_GAIN_REDUCE_6_1_DB 0b00010000 // 5 3 6.1 dB
#define CC1101_LNA_GAIN_REDUCE_7_4_DB 0b00011000 // 5 3 7.4 dB
#define CC1101_LNA_GAIN_REDUCE_9_2_DB 0b00100000 // 5 3 9.2 dB
#define CC1101_LNA_GAIN_REDUCE_11_5_DB 0b00101000 // 5 3 11.5 dB
#define CC1101_LNA_GAIN_REDUCE_14_6_DB 0b00110000 // 5 3 14.6 dB
#define CC1101_LNA_GAIN_REDUCE_17_1_DB 0b00111000 // 5 3 17.1 dB
#define CC1101_MAGN_TARGET_24_DB 0b00000000 // 2 0 average amplitude target for filter: 24 dB
#define CC1101_MAGN_TARGET_27_DB 0b00000001 // 2 0 27 dB
#define CC1101_MAGN_TARGET_30_DB 0b00000010 // 2 0 30 dB
#define CC1101_MAGN_TARGET_33_DB 0b00000011 // 2 0 33 dB (default)
#define CC1101_MAGN_TARGET_36_DB 0b00000100 // 2 0 36 dB
#define CC1101_MAGN_TARGET_38_DB 0b00000101 // 2 0 38 dB
#define CC1101_MAGN_TARGET_40_DB 0b00000110 // 2 0 40 dB
#define CC1101_MAGN_TARGET_42_DB 0b00000111 // 2 0 42 dB
// CC1101_REG_AGCCTRL1
#define CC1101_AGC_LNA_PRIORITY_LNA2 0b00000000 // 6 6 LNA priority setting: LNA2 first
#define CC1101_AGC_LNA_PRIORITY_LNA 0b01000000 // 6 6 LNA first (default)
#define CC1101_CARRIER_SENSE_REL_THR_OFF 0b00000000 // 5 4 RSSI relative change to assert carrier sense: disabled (default)
#define CC1101_CARRIER_SENSE_REL_THR_6_DB 0b00010000 // 5 4 6 dB
#define CC1101_CARRIER_SENSE_REL_THR_10_DB 0b00100000 // 5 4 10 dB
#define CC1101_CARRIER_SENSE_REL_THR_14_DB 0b00110000 // 5 4 14 dB
#define CC1101_CARRIER_SENSE_ABS_THR 0x00 // 3 0 RSSI threshold to assert carrier sense in 2s compliment, Thr = MAGN_TARGET + CARRIER_SENSE_ABS_TH [dB]
// CC1101_REG_AGCCTRL0
#define CC1101_HYST_LEVEL_NONE 0b00000000 // 7 6 AGC hysteresis level: none
#define CC1101_HYST_LEVEL_LOW 0b01000000 // 7 6 low
#define CC1101_HYST_LEVEL_MEDIUM 0b10000000 // 7 6 medium (default)
#define CC1101_HYST_LEVEL_HIGH 0b11000000 // 7 6 high
#define CC1101_WAIT_TIME_8_SAMPLES 0b00000000 // 5 4 AGC wait time: 8 samples
#define CC1101_WAIT_TIME_16_SAMPLES 0b00010000 // 5 4 16 samples (default)
#define CC1101_WAIT_TIME_24_SAMPLES 0b00100000 // 5 4 24 samples
#define CC1101_WAIT_TIME_32_SAMPLES 0b00110000 // 5 4 32 samples
#define CC1101_AGC_FREEZE_NEVER 0b00000000 // 3 2 freeze AGC gain: never (default)
#define CC1101_AGC_FREEZE_SYNC_WORD 0b00000100 // 3 2 when sync word is found
#define CC1101_AGC_FREEZE_MANUAL_A 0b00001000 // 3 2 manually freeze analog control
#define CC1101_AGC_FREEZE_MANUAL_AD 0b00001100 // 3 2 manually freeze analog and digital control
#define CC1101_FILTER_LENGTH_8 0b00000000 // 1 0 averaging length for channel filter: 8 samples
#define CC1101_FILTER_LENGTH_16 0b00000001 // 1 0 16 samples (default)
#define CC1101_FILTER_LENGTH_32 0b00000010 // 1 0 32 samples
#define CC1101_FILTER_LENGTH_64 0b00000011 // 1 0 64 samples
#define CC1101_ASK_OOK_BOUNDARY_4_DB 0b00000000 // 1 0 ASK/OOK decision boundary: 4 dB
#define CC1101_ASK_OOK_BOUNDARY_8_DB 0b00000001 // 1 0 8 dB (default)
#define CC1101_ASK_OOK_BOUNDARY_12_DB 0b00000010 // 1 0 12 dB
#define CC1101_ASK_OOK_BOUNDARY_16_DB 0b00000011 // 1 0 16 dB
// CC1101_REG_WOREVT1 + REG_WOREVT0
#define CC1101_EVENT0_TIMEOUT_MSB 0x87 // 7 0 EVENT0 timeout: t_event0 = (750 / f(XOSC)) * EVENT0_TIMEOUT * 2^(5 * WOR_RES) [s]
#define CC1101_EVENT0_TIMEOUT_LSB 0x6B // 7 0 default value for 26 MHz crystal: 1.0 s
// CC1101_REG_WORCTRL
#define CC1101_RC_POWER_UP 0b00000000 // 7 7 power up RC oscillator
#define CC1101_RC_POWER_DOWN 0b10000000 // 7 7 power down RC oscillator
#define CC1101_EVENT1_TIMEOUT_4 0b00000000 // 6 4 EVENT1 timeout: 4 RC periods
#define CC1101_EVENT1_TIMEOUT_6 0b00010000 // 6 4 6 RC periods
#define CC1101_EVENT1_TIMEOUT_8 0b00100000 // 6 4 8 RC periods
#define CC1101_EVENT1_TIMEOUT_12 0b00110000 // 6 4 12 RC periods
#define CC1101_EVENT1_TIMEOUT_16 0b01000000 // 6 4 16 RC periods
#define CC1101_EVENT1_TIMEOUT_24 0b01010000 // 6 4 24 RC periods
#define CC1101_EVENT1_TIMEOUT_32 0b01100000 // 6 4 32 RC periods
#define CC1101_EVENT1_TIMEOUT_48 0b01110000 // 6 4 48 RC periods (default)
#define CC1101_RC_CAL_OFF 0b00000000 // 3 3 disable RC oscillator calibration
#define CC1101_RC_CAL_ON 0b00001000 // 3 3 enable RC oscillator calibration (default)
#define CC1101_WOR_RES_1 0b00000000 // 1 0 EVENT0 resolution: 1 period (default)
#define CC1101_WOR_RES_2_5 0b00000001 // 1 0 2^5 periods
#define CC1101_WOR_RES_2_10 0b00000010 // 1 0 2^10 periods
#define CC1101_WOR_RES_2_15 0b00000011 // 1 0 2^15 periods
// CC1101_REG_FREND1
#define CC1101_LNA_CURRENT 0x01 // 7 6 front-end LNA PTAT current output adjustment
#define CC1101_LNA2MIX_CURRENT 0x01 // 5 4 front-end PTAT output adjustment
#define CC1101_LODIV_BUF_CURRENT_RX 0x01 // 3 2 Rx LO buffer current adjustment
#define CC1101_MIX_CURRENT 0x02 // 1 0 mixer current adjustment
// CC1101_REG_FREND0
#define CC1101_LODIV_BUF_CURRENT_TX 0x01 // 5 4 Tx LO buffer current adjustment
#define CC1101_PA_POWER 0x00 // 2 0 set power amplifier power according to PATABLE
// CC1101_REG_FSCAL3
#define CC1101_CHP_CURR_CAL_OFF 0b00000000 // 5 4 disable charge pump calibration
#define CC1101_CHP_CURR_CAL_ON 0b00100000 // 5 4 enable charge pump calibration (default)
#define CC1101_FSCAL3 0x09 // 3 0 charge pump output current: I_out = I_0 * 2^(FSCAL3/4) [A]
// CC1101_REG_FSCAL2
#define CC1101_VCO_CORE_LOW 0b00000000 // 5 5 VCO: low (default)
#define CC1101_VCO_CORE_HIGH 0b00100000 // 5 5 high
#define CC1101_FSCAL2 0x0A // 4 0 VCO current result/override
// CC1101_REG_FSCAL1
#define CC1101_FSCAL1 0x20 // 5 0 capacitor array setting for coarse VCO tuning
// CC1101_REG_FSCAL0
#define CC1101_FSCAL0 0x0D // 6 0 frequency synthesizer calibration setting
// CC1101_REG_RCCTRL1
#define CC1101_RCCTRL1 0x41 // 6 0 RC oscillator configuration
// CC1101_REG_RCCTRL0
#define CC1101_RCCTRL0 0x00 // 6 0 RC oscillator configuration
// CC1101_REG_PTEST
#define CC1101_TEMP_SENS_IDLE_OFF 0x7F // 7 0 temperature sensor will not be available in idle mode (default)
#define CC1101_TEMP_SENS_IDLE_ON 0xBF // 7 0 temperature sensor will be available in idle mode
// CC1101_REG_TEST0
#define CC1101_VCO_SEL_CAL_OFF 0b00000000 // 1 1 disable VCO selection calibration stage
#define CC1101_VCO_SEL_CAL_ON 0b00000010 // 1 1 enable VCO selection calibration stage
// CC1101_REG_PARTNUM
#define CC1101_PARTNUM 0x00
// CC1101_REG_VERSION
#define CC1101_VERSION 0x14
// CC1101_REG_MARCSTATE
#define CC1101_MARC_STATE_SLEEP 0x00 // 4 0 main radio control state: sleep
#define CC1101_MARC_STATE_IDLE 0x01 // 4 0 idle
#define CC1101_MARC_STATE_XOFF 0x02 // 4 0 XOFF
#define CC1101_MARC_STATE_VCOON_MC 0x03 // 4 0 VCOON_MC
#define CC1101_MARC_STATE_REGON_MC 0x04 // 4 0 REGON_MC
#define CC1101_MARC_STATE_MANCAL 0x05 // 4 0 MANCAL
#define CC1101_MARC_STATE_VCOON 0x06 // 4 0 VCOON
#define CC1101_MARC_STATE_REGON 0x07 // 4 0 REGON
#define CC1101_MARC_STATE_STARTCAL 0x08 // 4 0 STARTCAL
#define CC1101_MARC_STATE_BWBOOST 0x09 // 4 0 BWBOOST
#define CC1101_MARC_STATE_FS_LOCK 0x0A // 4 0 FS_LOCK
#define CC1101_MARC_STATE_IFADCON 0x0B // 4 0 IFADCON
#define CC1101_MARC_STATE_ENDCAL 0x0C // 4 0 ENDCAL
#define CC1101_MARC_STATE_RX 0x0D // 4 0 RX
#define CC1101_MARC_STATE_RX_END 0x0E // 4 0 RX_END
#define CC1101_MARC_STATE_RX_RST 0x0F // 4 0 RX_RST
#define CC1101_MARC_STATE_TXRX_SWITCH 0x10 // 4 0 TXRX_SWITCH
#define CC1101_MARC_STATE_RXFIFO_OVERFLOW 0x11 // 4 0 RXFIFO_OVERFLOW
#define CC1101_MARC_STATE_FSTXON 0x12 // 4 0 FSTXON
#define CC1101_MARC_STATE_TX 0x13 // 4 0 TX
#define CC1101_MARC_STATE_TX_END 0x14 // 4 0 TX_END
#define CC1101_MARC_STATE_RXTX_SWITCH 0x15 // 4 0 RXTX_SWITCH
#define CC1101_MARC_STATE_TXFIFO_UNDERFLOW 0x16 // 4 0 TXFIFO_UNDERFLOW
// CC1101_REG_WORTIME1 + REG_WORTIME0
#define CC1101_WORTIME_MSB 0x00 // 7 0 WOR timer value
#define CC1101_WORTIME_LSB 0x00 // 7 0
// CC1101_REG_PKTSTATUS
#define CC1101_CRC_OK 0b10000000 // 7 7 CRC check passed
#define CC1101_CRC_ERROR 0b00000000 // 7 7 CRC check failed
#define CC1101_CS 0b01000000 // 6 6 carrier sense
#define CC1101_PQT_REACHED 0b00100000 // 5 5 preamble quality reached
#define CC1101_CCA 0b00010000 // 4 4 channel clear
#define CC1101_SFD 0b00001000 // 3 3 start of frame delimiter - sync word received
#define CC1101_GDO2_ACTIVE 0b00000100 // 2 2 GDO2 is active/asserted
#define CC1101_GDO0_ACTIVE 0b00000001 // 0 0 GDO0 is active/asserted
/*!
\class CC1101
\brief Control class for %CC1101 module.
*/
class CC1101: public PhysicalLayer {
public:
// introduce PhysicalLayer overloads
using PhysicalLayer::transmit;
using PhysicalLayer::receive;
using PhysicalLayer::startTransmit;
using PhysicalLayer::readData;
/*!
\brief Default constructor.
\param mod Instance of Module that will be used to communicate with the radio.
*/
CC1101(Module* module);
// basic methods
/*!
\brief Initialization method.
\param freq Carrier frequency in MHz. Defaults to 868.0 MHz.
\param br Bit rate to be used in kbps. Defaults to 4.8 kbps.
\param rxBw Receiver bandwidth in kHz. Defaults to 325.0 kHz.
\param freqDev Frequency deviation from carrier frequency in kHz Defaults to 48.0 kHz.
\param power Output power in dBm. Defaults to 0 dBm.
\returns \ref status_codes
*/
int16_t begin(float freq = 868.0, float br = 4.8, float rxBw = 325.0, float freqDev = 48.0, int8_t power = 0);
/*!
\brief Blocking binary transmit method.
Overloads for string-based transmissions are implemented in PhysicalLayer.
\param data Binary data to be sent.
\param len Number of bytes to send.
\param addr Address to send the data to. Will only be added if address filtering was enabled.
\returns \ref status_codes
*/
int16_t transmit(uint8_t* data, size_t len, uint8_t addr = 0);
/*!
\brief Blocking binary receive method.
Overloads for string-based transmissions are implemented in PhysicalLayer.
\param data Binary data to be sent.
\param len Number of bytes to send.
\returns \ref status_codes
*/
int16_t receive(uint8_t* data, size_t len);
/*!
\brief Sets the module to standby mode.
\returns \ref status_codes
*/
int16_t standby();
/*!
\brief Starts direct mode transmission.
\param frf Raw RF frequency value. Defaults to 0, required for quick frequency shifts in RTTY.
\returns \ref status_codes
*/
int16_t transmitDirect(uint32_t frf = 0);
/*!
\brief Starts direct mode reception.
\returns \ref status_codes
*/
int16_t receiveDirect();
/*!
\brief Stops direct mode. It is required to call this method to switch from direct transmissions to packet-based transmissions.
*/
int16_t packetMode();
// interrupt methods
/*!
\brief Sets interrupt service routine to call when GDO0 activates.
\param func ISR to call.
\param dir Signal change direction. Defaults to FALLING.
*/
void setGdo0Action(void (*func)(void), uint8_t dir = FALLING);
/*!
\brief Sets interrupt service routine to call when GDO2 activates.
\param func ISR to call.
\param dir Signal change direction. Defaults to FALLING.
*/
void setGdo2Action(void (*func)(void), uint8_t dir = FALLING);
/*!
\brief Interrupt-driven binary transmit method.
Overloads for string-based transmissions are implemented in PhysicalLayer.
\param data Binary data to be sent.
\param len Number of bytes to send.
\param addr Address to send the data to. Will only be added if address filtering was enabled.
\returns \ref status_codes
*/
int16_t startTransmit(uint8_t* data, size_t len, uint8_t addr = 0);
/*!
\brief Interrupt-driven receive method. GDO0 will be activated when full packet is received.
\returns \ref status_codes
*/
int16_t startReceive();
/*!
\brief Reads data received after calling startReceive method.
\param data Pointer to array to save the received binary data.
\param len Number of bytes that will be received. Must be known in advance for binary transmissions.
\returns \ref status_codes
*/
int16_t readData(uint8_t* data, size_t len);
// configuration methods
/*!
\brief Sets carrier frequency. Allowed values are in bands 300.0 to 348.0 MHz, 387.0 to 464.0 MHz and 779.0 to 928.0 MHz.
\param freq Carrier frequency to be set in MHz.
\returns \ref status_codes
*/
int16_t setFrequency(float freq);
/*!
\brief Sets bit rate. Allowed values range from 0.025 to 600.0 kbps.
\param br Bit rate to be set in kbps.
\returns \ref status_codes
*/
int16_t setBitRate(float br);
/*!
\brief Sets receiver bandwidth. Allowed values range from 58.0 to 812.0 kHz.
\param rxBw Receiver bandwidth to be set in kHz.
\returns \ref status_codes
*/
int16_t setRxBandwidth(float rxBw);
/*!
\brief Sets frequency deviation. Allowed values range from 1.587 to 380.8 kHz.
\param freqDev Frequency deviation to be set in kHz.
\returns \ref status_codes
*/
int16_t setFrequencyDeviation(float freqDev);
/*!
\brief Sets output power. Allowed values are -30, -20, -15, -10, 0, 5, 7 or 10 dBm.
\param power Output power to be set in dBm.
\returns \ref status_codes
*/
int16_t setOutputPower(int8_t power);
/*!
\brief Sets 16-bit sync word as a two byte value.
\param syncH MSB of the sync word.
\param syncL LSB of the sync word.
\returns \ref status_codes
*/
int16_t setSyncWord(uint8_t syncH, uint8_t syncL);
/*!
\brief Sets node and broadcast addresses. Calling this method will also enable address filtering.
\param nodeAddr Node address to be set.
\param numBroadcastAddrs Number of broadcast addresses to be used. Can be set to 0 (no broadcast), 1 (broadcast at 0x00) or 2 (broadcast at 0x00 and 0xFF).
\returns \ref status_codes
*/
int16_t setNodeAddress(uint8_t nodeAddr, uint8_t numBroadcastAddrs = 0);
/*!
\brief Disables address filtering. Calling this method will also erase previously set addresses.
\returns \ref status_codes
*/
int16_t disableAddressFiltering();
/*!
\brief Gets RSSI (Recorded Signal Strength Indicator) of the last received packet.
\returns Last packet RSSI in dBm.
*/
float getRSSI();
/*!
\brief Gets LQI (Link Quality Indicator) of the last received packet.
\returns Last packet LQI (lower is better).
*/
uint8_t getLQI();
/*!
\brief Query modem for the packet length of received payload.
\param update Update received packet length. Will return cached value when set to false.
\returns Length of last received packet in bytes.
*/
size_t getPacketLength(bool update = true);
private:
Module* _mod;
float _freq;
uint8_t _rawRSSI;
uint8_t _rawLQI;
size_t _packetLength;
bool _packetLengthQueried;
int16_t config();
int16_t directMode();
void getExpMant(float target, uint16_t mantOffset, uint8_t divExp, uint8_t expMax, uint8_t& exp, uint8_t& mant);
// SPI read overrides to set bit for burst write and status registers access
int16_t SPIgetRegValue(uint8_t reg, uint8_t msb = 7, uint8_t lsb = 0);
int16_t SPIsetRegValue(uint8_t reg, uint8_t value, uint8_t msb = 7, uint8_t lsb = 0, uint8_t checkInterval = 2);
void SPIreadRegisterBurst(uint8_t reg, uint8_t numBytes, uint8_t* inBytes);
uint8_t SPIreadRegister(uint8_t reg);
void SPIwriteRegisterBurst(uint8_t reg, uint8_t* data, size_t len);
void SPIwriteRegister(uint8_t reg, uint8_t data);
void SPIsendCommand(uint8_t cmd);
};
#endif