summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/cc1101.c850
-rw-r--r--lib/cc1101.h144
-rw-r--r--lib/cc1101_defines.h235
3 files changed, 1229 insertions, 0 deletions
diff --git a/lib/cc1101.c b/lib/cc1101.c
new file mode 100644
index 0000000..20a2bda
--- /dev/null
+++ b/lib/cc1101.c
@@ -0,0 +1,850 @@
+/*
+ * spreadspace avr utils
+ *
+ *
+ * Copyright (C) 2013-2015 Christian Pointner <equinox@spreadspace.org>
+ *
+ * This file is part of spreadspace avr utils.
+ *
+ * spreadspace avr utils 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
+ * any later version.
+ *
+ * spreadspace avr utils 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 spreadspace avr utils. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdio.h>
+
+#include "cc1101.h"
+#include "cc1101_defines.h"
+
+static cc1101_driver_conf_t drv = {
+ .spi_cs_enable = NULL,
+ .spi_cs_disable = NULL,
+ .spi_read_miso = NULL,
+ .spi_write_byte = NULL,
+ .spi_read_byte = NULL,
+ .spi_transfer_byte = NULL,
+ .freq_corr = 1.0
+};
+
+static uint8_t const pa_table_values_[] = { 0x00, 0x30, 0x20, 0x10, 0x01, 0x02, 0x11, 0x03,
+ 0x12, 0x04, 0x05, 0x13, 0x06, 0x07, 0x21, 0x14, 0x08, 0x09, 0x0A, 0x15,
+ 0x0B, 0x31, 0x16, 0x0C, 0x0D, 0x0E, 0x17, 0x0F, 0x22, 0x18, 0x19, 0x1A,
+ 0x1B, 0x32, 0x23, 0x1C, 0x6F, 0x1D, 0x1E, 0x1F, 0x24, 0x33, 0x25, 0x34,
+ 0x26, 0x6E, 0x27, 0x35, 0x28, 0x6D, 0x6C, 0x29, 0x36, 0x6B, 0x2A, 0x6A,
+ 0x37, 0x69, 0x2B, 0x68, 0x38, 0x2C, 0x8F, 0x67, 0x2D, 0x57, 0x39, 0x66,
+ 0x2E, 0x56, 0x3A, 0x2F, 0x65, 0x55, 0x3B, 0x64, 0x54, 0x3C, 0x63, 0x3D,
+ 0x53, 0x3E, 0x62, 0x3F, 0x52, 0x40, 0x61, 0x51, 0x60, 0x50, 0x8E, 0x8D,
+ 0x8C, 0xCF, 0x8B, 0x8A, 0x89, 0x88, 0x87, 0x86, 0x85, 0xCE, 0x84, 0x83,
+ 0xCD, 0x82, 0xCC, 0x81, 0xCB, 0x80, 0xCA, 0xC9, 0xC8, 0xC7, 0xC6, 0xC5,
+ 0xC4, 0xC3, 0xC2, 0xC1, 0xC0 };
+
+#define PA_TABLE_VALUES_MAX ((sizeof(pa_table_values_)/sizeof(uint8_t))-1)
+
+/*
+ * internal functions
+ */
+
+static inline void cc1101_spi_wait_rdy(void)
+{
+ while(drv.spi_read_miso()); // wait for CHP_RDY to go low, TODO: timeout...
+}
+
+static uint8_t cc1101_spi_strobe_command(const uint8_t cmd)
+{
+ if(cmd < CC1101_CMD_MIN || cmd > CC1101_CMD_MAX)
+ return -1;
+
+ drv.spi_cs_enable();
+ cc1101_spi_wait_rdy();
+
+ uint8_t status = drv.spi_transfer_byte(CC1101_HEADER_COMMAND | cmd);
+
+ drv.spi_cs_disable();
+ return status;
+}
+
+static uint8_t cc1101_spi_read_register(const uint8_t addr)
+{
+ if(addr > CC1101_ADDR_MAX || (addr >= CC1101_CMD_MIN && addr <= CC1101_CMD_MAX))
+ return 0xFF;
+
+ uint8_t hdr = addr;
+ if(addr >= CC1101_REG_RO_MIN && addr <= CC1101_REG_RO_MAX)
+ hdr |= CC1101_HEADER_READONLY;
+ else
+ hdr |= CC1101_HEADER_READ;
+
+ drv.spi_cs_enable();
+ cc1101_spi_wait_rdy();
+
+ drv.spi_write_byte(hdr);
+ uint8_t data = drv.spi_read_byte();
+
+ drv.spi_cs_disable();
+ return data;
+}
+
+static void cc1101_spi_write_register(const uint8_t addr, const uint8_t data)
+{
+ if(addr > CC1101_REG_RW_MAX && addr != CC1101_REG_PATABLE && addr != CC1101_REG_FIFO)
+ return;
+
+ drv.spi_cs_enable();
+ cc1101_spi_wait_rdy();
+
+ drv.spi_write_byte(CC1101_HEADER_WRITE | addr);
+ drv.spi_write_byte(data);
+
+ drv.spi_cs_disable();
+}
+
+// this is an internal-internal function - never use this outside of internal functions
+static uint8_t cc1101_spi_read_register_burst_raw(const uint8_t addr, uint8_t* data, const uint8_t l)
+{
+ drv.spi_cs_enable();
+ cc1101_spi_wait_rdy();
+
+ drv.spi_write_byte(CC1101_HEADER_READ | CC1101_HEADER_BURST | addr);
+ uint8_t i;
+ for(i = 0; i < l; ++i)
+ data[i] = drv.spi_read_byte();
+
+ drv.spi_cs_disable();
+ return i;
+}
+
+static uint8_t cc1101_spi_read_register_burst(const uint8_t addr, uint8_t* data, const uint8_t len)
+{
+ if(addr <= CC1101_REG_RW_MAX) {
+ uint8_t l = (CC1101_REG_RW_MAX - addr) + 1;
+ l = (len > l) ? l : len;
+ return cc1101_spi_read_register_burst_raw(addr, data, l);
+
+ } else if(CC1101_REG_PATABLE) {
+ uint8_t l = (len > CC1101_PATABLE_SIZE) ? CC1101_PATABLE_SIZE : len;
+ return cc1101_spi_read_register_burst_raw(addr, data, l);
+
+ } else if(CC1101_REG_FIFO) {
+ uint8_t l = (len > CC1101_FIFO_MAX_LEN) ? CC1101_FIFO_MAX_LEN : len;
+ return cc1101_spi_read_register_burst_raw(addr, data, l);
+ }
+ return 0;
+}
+
+// this is an internal-internal function - never use this outside of internal functions
+static uint8_t cc1101_spi_write_register_burst_raw(const uint8_t addr, uint8_t* data, const uint8_t l)
+{
+ drv.spi_cs_enable();
+ cc1101_spi_wait_rdy();
+
+ drv.spi_write_byte(CC1101_HEADER_WRITE | CC1101_HEADER_BURST | addr);
+ uint8_t i;
+ for(i = 0; i < l; ++i)
+ drv.spi_write_byte(data[i]);
+
+ drv.spi_cs_disable();
+ return i;
+}
+
+static uint8_t cc1101_spi_write_register_burst(const uint8_t addr, uint8_t* data, const uint8_t len)
+{
+ if(addr <= CC1101_REG_RW_MAX) {
+ uint8_t l = (CC1101_REG_RW_MAX - addr) + 1;
+ l = (len > l) ? l : len;
+ return cc1101_spi_write_register_burst_raw(addr, data, l);
+
+ } else if(CC1101_REG_PATABLE) {
+ uint8_t l = (len > CC1101_PATABLE_SIZE) ? CC1101_PATABLE_SIZE : len;
+ return cc1101_spi_write_register_burst_raw(addr, data, l);
+
+ } else if(CC1101_REG_FIFO) {
+ uint8_t l = (len > CC1101_FIFO_MAX_LEN) ? CC1101_FIFO_MAX_LEN : len;
+ return cc1101_spi_write_register_burst_raw(addr, data, l);
+ }
+ return 0;
+}
+
+
+/*
+ * EXTERNAL INTERFACE
+ */
+
+void cc1101_init(cc1101_driver_conf_t conf)
+{
+ drv = conf;
+ cc1101_soft_reset();
+}
+
+void cc1101_reg_init(void)
+{
+ cc1101_set_iocfg0(CC1101_GDO_CFG_3STATE);
+ cc1101_set_iocfg1(CC1101_GDO_CFG_3STATE);
+ cc1101_set_iocfg2(CC1101_GDO_CFG_3STATE);
+}
+
+void cc1101_soft_reset(void)
+{
+ cc1101_spi_strobe_command(CC1101_CMD_SRES);
+}
+
+
+void cc1101_powerdown(void)
+{
+ cc1101_spi_strobe_command(CC1101_CMD_SPWD);
+}
+
+void cc1101_idle(void)
+{
+ cc1101_spi_strobe_command(CC1101_CMD_SIDLE);
+}
+
+void cc1101_osc_off(void)
+{
+ cc1101_spi_strobe_command(CC1101_CMD_SXOFF);
+}
+
+void cc1101_calibrate(void)
+{
+ cc1101_spi_strobe_command(CC1101_CMD_SCAL);
+}
+
+void cc1101_fasttxon(void)
+{
+ cc1101_spi_strobe_command(CC1101_CMD_SFSTXON);
+}
+
+void cc1101_rx(void)
+{
+ cc1101_spi_strobe_command(CC1101_CMD_SRX);
+}
+
+void cc1101_tx(void)
+{
+ cc1101_spi_strobe_command(CC1101_CMD_STX);
+}
+
+char* cc1101_state_to_string(cc1101_state_t state)
+{
+ switch(state) {
+ case sleep: return "sleep";
+ case idle: return "idle";
+ case xoff: return "xoff";
+ case mancal: return "mancal";
+ case fs_wakeup: return "fs_wakeup";
+ case calibrate: return "calibrate";
+ case settling: return "settling";
+ case rx: return "rx";
+ case txrx_settling: return "txrx_settling";
+ case rxfifo_overflow: return "rxfifo_overflow";
+ case fstxon: return "fstxon";
+ case tx: return "tx";
+ case rxtx_settling: return "rxtx_settling";
+ case txfifo_underflow: return "txfifo_underflow";
+ default: return "unknown";
+ }
+}
+
+static cc1101_state_t cc1101_marcstate_to_state(uint8_t marcstate)
+{
+ switch(marcstate) {
+ case CC1101_MARCSTATE_SLEEP: return sleep;
+ case CC1101_MARCSTATE_IDLE: return idle;
+ case CC1101_MARCSTATE_XOFF: return xoff;
+ case CC1101_MARCSTATE_VCOON_MC:
+ case CC1101_MARCSTATE_REGON_MC:
+ case CC1101_MARCSTATE_MANCAL: return mancal;
+ case CC1101_MARCSTATE_VCOON:
+ case CC1101_MARCSTATE_REGON: return fs_wakeup;
+ case CC1101_MARCSTATE_STARTCAL: return calibrate;
+ case CC1101_MARCSTATE_BWBOOST:
+ case CC1101_MARCSTATE_FS_LOCK:
+ case CC1101_MARCSTATE_IFADCON: return settling;
+ case CC1101_MARCSTATE_ENDCAL: return calibrate;
+ case CC1101_MARCSTATE_RX:
+ case CC1101_MARCSTATE_RX_END:
+ case CC1101_MARCSTATE_RX_RST: return rx;
+ case CC1101_MARCSTATE_TXRX_SWITCH: return txrx_settling;
+ case CC1101_MARCSTATE_RXFIFO_OVERFLOW: return rxfifo_overflow;
+ case CC1101_MARCSTATE_FSTXON: return fstxon;
+ case CC1101_MARCSTATE_TX:
+ case CC1101_MARCSTATE_TX_END: return tx;
+ case CC1101_MARCSTATE_RXTX_SWITCH: return rxtx_settling;
+ case CC1101_MARCSTATE_TXFIFO_UNDERFLOW: return txfifo_underflow;
+ default: return unknown;
+ }
+}
+
+cc1101_state_t cc1101_get_state(void)
+{
+ return cc1101_marcstate_to_state(cc1101_get_marcstate());
+}
+
+
+
+
+
+uint32_t cc1101_get_freq_hz(void)
+{
+ return (uint32_t)((float)(cc1101_get_freq()) * drv.freq_corr);
+}
+
+void cc1101_set_freq_hz(uint32_t hz)
+{
+ uint32_t freq = (uint32_t)((float)hz / drv.freq_corr);
+ cc1101_set_freq(freq);
+}
+
+
+
+// normalized register access
+
+uint8_t cc1101_get_iocfg0(void)
+{
+ return cc1101_spi_read_register(CC1101_REG_RW_IOCFG0) & CC1101_REG_RW_IOCFG0_MASK;
+}
+
+void cc1101_set_iocfg0(uint8_t iocfg)
+{
+ cc1101_spi_write_register(CC1101_REG_RW_IOCFG0, iocfg & CC1101_REG_RW_IOCFG0_MASK);
+}
+
+uint8_t cc1101_get_iocfg1(void)
+{
+ return cc1101_spi_read_register(CC1101_REG_RW_IOCFG1) & CC1101_REG_RW_IOCFG1_MASK;
+}
+
+void cc1101_set_iocfg1(uint8_t iocfg)
+{
+ cc1101_spi_write_register(CC1101_REG_RW_IOCFG1, iocfg & CC1101_REG_RW_IOCFG1_MASK);
+}
+
+uint8_t cc1101_get_iocfg2(void)
+{
+ return cc1101_spi_read_register(CC1101_REG_RW_IOCFG2) & CC1101_REG_RW_IOCFG2_MASK;
+}
+
+void cc1101_set_iocfg2(uint8_t iocfg)
+{
+ cc1101_spi_write_register(CC1101_REG_RW_IOCFG2, iocfg & CC1101_REG_RW_IOCFG2_MASK);
+}
+
+
+uint8_t cc1101_get_fifothr(void)
+{
+ return cc1101_spi_read_register(CC1101_REG_RW_FIFOTHR) & CC1101_REG_RW_FIFOTHR_MASK;
+}
+
+void cc1101_set_fifothr(uint8_t fifothr)
+{
+ cc1101_spi_write_register(CC1101_REG_RW_FIFOTHR, fifothr & CC1101_REG_RW_FIFOTHR_MASK);
+}
+
+
+uint16_t cc1101_get_sync(void)
+{
+ uint16_t sync = cc1101_spi_read_register(CC1101_REG_RW_SYNC1) & CC1101_REG_RW_SYNC1_MASK;
+ sync = sync << 8;
+ sync |= cc1101_spi_read_register(CC1101_REG_RW_SYNC0) & CC1101_REG_RW_SYNC0_MASK;
+ return sync;
+}
+
+void cc1101_set_sync(uint16_t sync)
+{
+ cc1101_spi_write_register(CC1101_REG_RW_SYNC0, (uint8_t)(sync) & CC1101_REG_RW_SYNC0_MASK);
+ sync = sync >> 8;
+ cc1101_spi_write_register(CC1101_REG_RW_SYNC1, (uint8_t)(sync) & CC1101_REG_RW_SYNC1_MASK);
+}
+
+uint8_t cc1101_get_pktlen(void)
+{
+ return cc1101_spi_read_register(CC1101_REG_RW_PKTLEN) & CC1101_REG_RW_PKTLEN_MASK;
+}
+
+void cc1101_set_pktlen(uint8_t len)
+{
+ cc1101_spi_write_register(CC1101_REG_RW_PKTLEN, len & CC1101_REG_RW_PKTLEN_MASK);
+}
+
+uint16_t cc1101_get_pktctrl(void)
+{
+ uint16_t ctrl = cc1101_spi_read_register(CC1101_REG_RW_PKTCTRL1) & CC1101_REG_RW_PKTCTRL1_MASK;
+ ctrl = ctrl << 8;
+ ctrl |= cc1101_spi_read_register(CC1101_REG_RW_PKTCTRL0) & CC1101_REG_RW_PKTCTRL0_MASK;
+ return ctrl;
+}
+
+void cc1101_set_pktctrl(uint16_t ctrl)
+{
+ cc1101_spi_write_register(CC1101_REG_RW_PKTCTRL0, (uint8_t)(ctrl) & CC1101_REG_RW_PKTCTRL0_MASK);
+ ctrl = ctrl >> 8;
+ cc1101_spi_write_register(CC1101_REG_RW_PKTCTRL1, (uint8_t)(ctrl) & CC1101_REG_RW_PKTCTRL1_MASK);
+}
+
+uint8_t cc1101_get_addr(void)
+{
+ return cc1101_spi_read_register(CC1101_REG_RW_ADDR) & CC1101_REG_RW_ADDR_MASK;
+}
+
+void cc1101_set_addr(uint8_t addr)
+{
+ cc1101_spi_write_register(CC1101_REG_RW_ADDR, addr & CC1101_REG_RW_ADDR_MASK);
+}
+
+
+uint8_t cc1101_get_channr(void)
+{
+ return cc1101_spi_read_register(CC1101_REG_RW_CHANNR) & CC1101_REG_RW_CHANNR_MASK;
+}
+
+void cc1101_set_channr(uint8_t nr)
+{
+ cc1101_spi_write_register(CC1101_REG_RW_CHANNR, nr & CC1101_REG_RW_CHANNR_MASK);
+}
+
+uint8_t cc1101_get_iffreq(void)
+{
+ return cc1101_spi_read_register(CC1101_REG_RW_FSCTRL1) & CC1101_REG_RW_FSCTRL1_MASK;
+}
+
+void cc1101_set_iffreq(uint8_t iffreq)
+{
+ cc1101_spi_write_register(CC1101_REG_RW_FSCTRL1, iffreq & CC1101_REG_RW_FSCTRL1_MASK);
+}
+
+uint8_t cc1101_get_freq_offset(void)
+{
+ return cc1101_spi_read_register(CC1101_REG_RW_FSCTRL0) & CC1101_REG_RW_FSCTRL0_MASK;
+}
+
+void cc1101_set_freq_offset(uint8_t freqoff)
+{
+ cc1101_spi_write_register(CC1101_REG_RW_FSCTRL0, freqoff & CC1101_REG_RW_FSCTRL0_MASK);
+}
+
+uint32_t cc1101_get_freq(void)
+{
+ uint32_t freq = cc1101_spi_read_register(CC1101_REG_RW_FREQ2) & CC1101_REG_RW_FREQ2_MASK;
+ freq = freq << 8;
+ freq |= cc1101_spi_read_register(CC1101_REG_RW_FREQ1) & CC1101_REG_RW_FREQ1_MASK;
+ freq = freq << 8;
+ freq |= cc1101_spi_read_register(CC1101_REG_RW_FREQ0) & CC1101_REG_RW_FREQ0_MASK;
+ return freq;
+}
+
+void cc1101_set_freq(uint32_t freq)
+{
+ cc1101_spi_write_register(CC1101_REG_RW_FREQ0, (uint8_t)(freq) & CC1101_REG_RW_FREQ0_MASK);
+ freq = freq >> 8;
+ cc1101_spi_write_register(CC1101_REG_RW_FREQ1, (uint8_t)(freq) & CC1101_REG_RW_FREQ1_MASK);
+ freq = freq >> 8;
+ cc1101_spi_write_register(CC1101_REG_RW_FREQ2, (uint8_t)(freq) & CC1101_REG_RW_FREQ2_MASK);
+}
+
+uint64_t cc1101_get_modemcfg(void)
+{
+ uint64_t cfg = cc1101_spi_read_register(CC1101_REG_RW_MDMCFG4) & CC1101_REG_RW_MDMCFG4_MASK;
+ cfg = cfg << 8;
+ cfg |= cc1101_spi_read_register(CC1101_REG_RW_MDMCFG3) & CC1101_REG_RW_MDMCFG3_MASK;
+ cfg = cfg << 8;
+ cfg |= cc1101_spi_read_register(CC1101_REG_RW_MDMCFG2) & CC1101_REG_RW_MDMCFG2_MASK;
+ cfg = cfg << 8;
+ cfg |= cc1101_spi_read_register(CC1101_REG_RW_MDMCFG1) & CC1101_REG_RW_MDMCFG1_MASK;
+ cfg = cfg << 8;
+ cfg |= cc1101_spi_read_register(CC1101_REG_RW_MDMCFG0) & CC1101_REG_RW_MDMCFG0_MASK;
+ return cfg;
+}
+
+void cc1101_set_modemcfg(uint64_t cfg)
+{
+ cc1101_spi_write_register(CC1101_REG_RW_MDMCFG0, cfg & CC1101_REG_RW_MDMCFG0_MASK);
+ cfg = cfg >> 8;
+ cc1101_spi_write_register(CC1101_REG_RW_MDMCFG1, cfg & CC1101_REG_RW_MDMCFG1_MASK);
+ cfg = cfg >> 8;
+ cc1101_spi_write_register(CC1101_REG_RW_MDMCFG2, cfg & CC1101_REG_RW_MDMCFG2_MASK);
+ cfg = cfg >> 8;
+ cc1101_spi_write_register(CC1101_REG_RW_MDMCFG3, cfg & CC1101_REG_RW_MDMCFG3_MASK);
+ cfg = cfg >> 8;
+ cc1101_spi_write_register(CC1101_REG_RW_MDMCFG4, cfg & CC1101_REG_RW_MDMCFG4_MASK);
+}
+
+uint8_t cc1101_get_deviatn(void)
+{
+ return cc1101_spi_read_register(CC1101_REG_RW_DEVIATN) & CC1101_REG_RW_DEVIATN_MASK;
+}
+
+void cc1101_set_deviatn(uint8_t dev)
+{
+ cc1101_spi_write_register(CC1101_REG_RW_DEVIATN, dev & CC1101_REG_RW_DEVIATN_MASK);
+}
+
+
+
+uint32_t cc1101_get_mcsm(void)
+{
+ uint32_t cfg = cc1101_spi_read_register(CC1101_REG_RW_MCSM2) & CC1101_REG_RW_MCSM2_MASK;
+ cfg = cfg << 8;
+ cfg |= cc1101_spi_read_register(CC1101_REG_RW_MCSM1) & CC1101_REG_RW_MCSM1_MASK;
+ cfg = cfg << 8;
+ cfg |= cc1101_spi_read_register(CC1101_REG_RW_MCSM0) & CC1101_REG_RW_MCSM0_MASK;
+ return cfg;
+}
+
+void cc1101_set_mcsm(uint32_t cfg)
+{
+ cc1101_spi_write_register(CC1101_REG_RW_MCSM0, cfg & CC1101_REG_RW_MCSM0_MASK);
+ cfg = cfg >> 8;
+ cc1101_spi_write_register(CC1101_REG_RW_MCSM1, cfg & CC1101_REG_RW_MCSM1_MASK);
+ cfg = cfg >> 8;
+ cc1101_spi_write_register(CC1101_REG_RW_MCSM2, cfg & CC1101_REG_RW_MCSM2_MASK);
+}
+
+
+uint8_t cc1101_get_foccfg(void)
+{
+ return cc1101_spi_read_register(CC1101_REG_RW_FOCCFG) & CC1101_REG_RW_FOCCFG_MASK;
+}
+
+void cc1101_set_foccfg(uint8_t cfg)
+{
+ cc1101_spi_write_register(CC1101_REG_RW_FOCCFG, cfg & CC1101_REG_RW_FOCCFG_MASK);
+}
+
+uint8_t cc1101_get_bscfg(void)
+{
+ return cc1101_spi_read_register(CC1101_REG_RW_BSCFG) & CC1101_REG_RW_BSCFG_MASK;
+}
+
+void cc1101_set_bscfg(uint8_t cfg)
+{
+ cc1101_spi_write_register(CC1101_REG_RW_BSCFG, cfg & CC1101_REG_RW_BSCFG_MASK);
+}
+
+uint32_t cc1101_get_agcctrl(void)
+{
+ uint32_t ctrl = cc1101_spi_read_register(CC1101_REG_RW_AGCCTRL2) & CC1101_REG_RW_AGCCTRL2_MASK;
+ ctrl = ctrl << 8;
+ ctrl |= cc1101_spi_read_register(CC1101_REG_RW_AGCCTRL1) & CC1101_REG_RW_AGCCTRL1_MASK;
+ ctrl = ctrl << 8;
+ ctrl |= cc1101_spi_read_register(CC1101_REG_RW_AGCCTRL0) & CC1101_REG_RW_AGCCTRL0_MASK;
+ return ctrl;
+}
+
+void cc1101_set_agcctrl(uint32_t ctrl)
+{
+ cc1101_spi_write_register(CC1101_REG_RW_AGCCTRL0, ctrl & CC1101_REG_RW_AGCCTRL0_MASK);
+ ctrl = ctrl >> 8;
+ cc1101_spi_write_register(CC1101_REG_RW_AGCCTRL1, ctrl & CC1101_REG_RW_AGCCTRL1_MASK);
+ ctrl = ctrl >> 8;
+ cc1101_spi_write_register(CC1101_REG_RW_AGCCTRL2, ctrl & CC1101_REG_RW_AGCCTRL2_MASK);
+}
+
+uint16_t cc1101_get_worevt(void)
+{
+ uint16_t timeout = cc1101_spi_read_register(CC1101_REG_RW_WOREVT1) & CC1101_REG_RW_WOREVT1_MASK;
+ timeout = timeout << 8;
+ timeout |= cc1101_spi_read_register(CC1101_REG_RW_WOREVT0) & CC1101_REG_RW_WOREVT0_MASK;
+ return timeout;
+}
+
+void cc1101_set_worevt(uint16_t timeout)
+{
+ cc1101_spi_write_register(CC1101_REG_RW_WOREVT0, timeout & CC1101_REG_RW_WOREVT0_MASK);
+ timeout = timeout >> 8;
+ cc1101_spi_write_register(CC1101_REG_RW_WOREVT1, timeout & CC1101_REG_RW_WOREVT1_MASK);
+}
+
+uint8_t cc1101_get_worctrl(void)
+{
+ return cc1101_spi_read_register(CC1101_REG_RW_WORCTRL) & CC1101_REG_RW_WORCTRL_MASK;
+}
+
+void cc1101_set_worctrl(uint8_t ctrl)
+{
+ cc1101_spi_write_register(CC1101_REG_RW_WORCTRL, ctrl & CC1101_REG_RW_WORCTRL_MASK);
+}
+
+
+uint16_t cc1101_get_frend(void)
+{
+ uint16_t cfg = cc1101_spi_read_register(CC1101_REG_RW_FREND1) & CC1101_REG_RW_FREND1_MASK;
+ cfg = cfg << 8;
+ cfg |= cc1101_spi_read_register(CC1101_REG_RW_FREND0) & CC1101_REG_RW_FREND0_MASK;
+ return cfg;
+}
+
+void cc1101_set_frend(uint16_t cfg)
+{
+ cc1101_spi_write_register(CC1101_REG_RW_FREND0, cfg & CC1101_REG_RW_FREND0_MASK);
+ cfg = cfg >> 8;
+ cc1101_spi_write_register(CC1101_REG_RW_FREND1, cfg & CC1101_REG_RW_FREND1_MASK);
+}
+
+uint32_t cc1101_get_fscal(void)
+{
+ uint32_t cal = cc1101_spi_read_register(CC1101_REG_RW_FSCAL3) & CC1101_REG_RW_FSCAL3_MASK;
+ cal = cal << 8;
+ cal = cc1101_spi_read_register(CC1101_REG_RW_FSCAL2) & CC1101_REG_RW_FSCAL2_MASK;
+ cal = cal << 8;
+ cal |= cc1101_spi_read_register(CC1101_REG_RW_FSCAL1) & CC1101_REG_RW_FSCAL1_MASK;
+ cal = cal << 8;
+ cal |= cc1101_spi_read_register(CC1101_REG_RW_FSCAL0) & CC1101_REG_RW_FSCAL0_MASK;
+ return cal;
+}
+
+void cc1101_set_fscal(uint32_t cal)
+{
+ cc1101_spi_write_register(CC1101_REG_RW_FSCAL0, cal & CC1101_REG_RW_FSCAL0_MASK);
+ cal = cal >> 8;
+ cc1101_spi_write_register(CC1101_REG_RW_FSCAL1, cal & CC1101_REG_RW_FSCAL1_MASK);
+ cal = cal >> 8;
+ cc1101_spi_write_register(CC1101_REG_RW_FSCAL2, cal & CC1101_REG_RW_FSCAL2_MASK);
+ cal = cal >> 8;
+ cc1101_spi_write_register(CC1101_REG_RW_FSCAL3, cal & CC1101_REG_RW_FSCAL3_MASK);
+}
+
+uint16_t cc1101_get_rcctrl(void)
+{
+ uint16_t ctrl = cc1101_spi_read_register(CC1101_REG_RW_RCCTRL1) & CC1101_REG_RW_RCCTRL1_MASK;
+ ctrl = ctrl << 8;
+ ctrl |= cc1101_spi_read_register(CC1101_REG_RW_RCCTRL0) & CC1101_REG_RW_RCCTRL0_MASK;
+ return ctrl;
+}
+
+void cc1101_set_rcctrl(uint16_t ctrl)
+{
+ cc1101_spi_write_register(CC1101_REG_RW_RCCTRL0, ctrl & CC1101_REG_RW_RCCTRL0_MASK);
+ ctrl = ctrl >> 8;
+ cc1101_spi_write_register(CC1101_REG_RW_RCCTRL1, ctrl & CC1101_REG_RW_RCCTRL1_MASK);
+}
+
+
+uint8_t cc1101_get_fstest(void)
+{
+ return cc1101_spi_read_register(CC1101_REG_RW_FSTEST) & CC1101_REG_RW_FSTEST_MASK;
+}
+
+void cc1101_set_fstest(uint8_t test)
+{
+ cc1101_spi_write_register(CC1101_REG_RW_FSTEST, test & CC1101_REG_RW_FSTEST_MASK);
+}
+
+uint8_t cc1101_get_ptest(void)
+{
+ return cc1101_spi_read_register(CC1101_REG_RW_PTEST) & CC1101_REG_RW_PTEST_MASK;
+}
+
+void cc1101_set_ptest(uint8_t test)
+{
+ cc1101_spi_write_register(CC1101_REG_RW_PTEST, test & CC1101_REG_RW_PTEST_MASK);
+}
+
+uint8_t cc1101_get_agctest(void)
+{
+ return cc1101_spi_read_register(CC1101_REG_RW_AGCTEST) & CC1101_REG_RW_AGCTEST_MASK;
+}
+
+void cc1101_set_agctest(uint8_t test)
+{
+ cc1101_spi_write_register(CC1101_REG_RW_AGCTEST, test & CC1101_REG_RW_AGCTEST_MASK);
+}
+
+uint8_t cc1101_get_test0(void)
+{
+ return cc1101_spi_read_register(CC1101_REG_RW_TEST0) & CC1101_REG_RW_TEST0_MASK;
+}
+
+void cc1101_set_test0(uint8_t test)
+{
+ cc1101_spi_write_register(CC1101_REG_RW_TEST0, test & CC1101_REG_RW_TEST0_MASK);
+}
+
+uint8_t cc1101_get_test1(void)
+{
+ return cc1101_spi_read_register(CC1101_REG_RW_TEST1) & CC1101_REG_RW_TEST1_MASK;
+}
+
+void cc1101_set_test1(uint8_t test)
+{
+ cc1101_spi_write_register(CC1101_REG_RW_TEST1, test & CC1101_REG_RW_TEST1_MASK);
+}
+
+uint8_t cc1101_get_test2(void)
+{
+ return cc1101_spi_read_register(CC1101_REG_RW_TEST2) & CC1101_REG_RW_TEST2_MASK;
+}
+
+void cc1101_set_test2(uint8_t test)
+{
+ cc1101_spi_write_register(CC1101_REG_RW_TEST2, test & CC1101_REG_RW_TEST2_MASK);
+}
+
+
+uint8_t cc1101_get_partnum(void)
+{
+ return cc1101_spi_read_register(CC1101_REG_RO_PARTNUM) & CC1101_REG_RO_PARTNUM_MASK;
+}
+
+uint8_t cc1101_get_chip_version(void)
+{
+ return cc1101_spi_read_register(CC1101_REG_RO_VERSION) & CC1101_REG_RO_VERSION_MASK;
+}
+
+uint8_t cc1101_get_freq_offset_est(void)
+{
+ return cc1101_spi_read_register(CC1101_REG_RO_FREQUEST) & CC1101_REG_RO_FREQUEST_MASK;
+}
+
+uint8_t cc1101_get_lqi(void)
+{
+ return cc1101_spi_read_register(CC1101_REG_RO_LQI) & CC1101_REG_RO_LQI_MASK;
+}
+
+int8_t cc1101_get_rssi(void)
+{
+ return (int8_t)cc1101_spi_read_register(CC1101_REG_RO_RSSI) & CC1101_REG_RO_RSSI_MASK;
+}
+
+uint8_t cc1101_get_marcstate(void)
+{
+ return cc1101_spi_read_register(CC1101_REG_RO_MARCSTATE) & CC1101_REG_RO_MARCSTATE_MASK;
+}
+
+uint16_t cc1101_get_wortime(void)
+{
+ uint16_t w = cc1101_spi_read_register(CC1101_REG_RO_WORTIME1) & CC1101_REG_RO_WORTIME1_MASK;
+ w = w << 8;
+ w |= cc1101_spi_read_register(CC1101_REG_RO_WORTIME0) & CC1101_REG_RO_WORTIME0_MASK;
+ return w;
+}
+
+uint8_t cc1101_get_pkt_status(void)
+{
+ return cc1101_spi_read_register(CC1101_REG_RO_PKTSTATUS) & CC1101_REG_RO_PKTSTATUS_MASK;
+}
+
+uint8_t cc1101_get_tx_bytes(void)
+{
+ return cc1101_spi_read_register(CC1101_REG_RO_TXBYTES) & CC1101_REG_RO_TXBYTES_MASK;
+}
+
+uint8_t cc1101_get_rx_bytes(void)
+{
+ return cc1101_spi_read_register(CC1101_REG_RO_RXBYTES) & CC1101_REG_RO_RXBYTES_MASK;
+}
+
+uint8_t cc1101_get_rcctrl0_status(void)
+{
+ return cc1101_spi_read_register(CC1101_REG_RO_RCCTRL0_STATUS) & CC1101_REG_RO_RCCTRL0_STATUS_MASK;
+}
+
+uint8_t cc1101_get_rcctrl1_status(void)
+{
+ return cc1101_spi_read_register(CC1101_REG_RO_RCCTRL1_STATUS) & CC1101_REG_RO_RCCTRL1_STATUS_MASK;
+}
+
+
+
+static char* cc1101_config_reg_to_string(uint8_t addr)
+{
+ switch(addr) {
+ case CC1101_REG_RW_IOCFG2: return "IOCFG2";
+ case CC1101_REG_RW_IOCFG1: return "IOCFG1";
+ case CC1101_REG_RW_IOCFG0: return "IOCFG0";
+ case CC1101_REG_RW_FIFOTHR: return "FIFOTHR";
+ case CC1101_REG_RW_SYNC1: return "SYNC1";
+ case CC1101_REG_RW_SYNC0: return "SYNC0";
+ case CC1101_REG_RW_PKTLEN: return "PKTLEN";
+ case CC1101_REG_RW_PKTCTRL1: return "PKTCTRL1";
+ case CC1101_REG_RW_PKTCTRL0: return "PKTCTRL0";
+ case CC1101_REG_RW_ADDR: return "ADDR";
+ case CC1101_REG_RW_CHANNR: return "CHANNR";
+ case CC1101_REG_RW_FSCTRL1: return "FSCTRL1";
+ case CC1101_REG_RW_FSCTRL0: return "FSCTRL0";
+ case CC1101_REG_RW_FREQ2: return "FREQ2";
+ case CC1101_REG_RW_FREQ1: return "FREQ1";
+ case CC1101_REG_RW_FREQ0: return "FREQ0";
+ case CC1101_REG_RW_MDMCFG4: return "MDMCFG4";
+ case CC1101_REG_RW_MDMCFG3: return "MDMCFG3";
+ case CC1101_REG_RW_MDMCFG2: return "MDMCFG2";
+ case CC1101_REG_RW_MDMCFG1: return "MDMCFG1";
+ case CC1101_REG_RW_MDMCFG0: return "MDMCFG0";
+ case CC1101_REG_RW_DEVIATN: return "DEVIATN";
+ case CC1101_REG_RW_MCSM2: return "MCSM2";
+ case CC1101_REG_RW_MCSM1: return "MCSM1";
+ case CC1101_REG_RW_MCSM0: return "MCSM0";
+ case CC1101_REG_RW_FOCCFG: return "FOCCFG";
+ case CC1101_REG_RW_BSCFG: return "BSCFG";
+ case CC1101_REG_RW_AGCCTRL2: return "AGCCTRL2";
+ case CC1101_REG_RW_AGCCTRL1: return "AGCCTRL1";
+ case CC1101_REG_RW_AGCCTRL0: return "AGCCTRL0";
+ case CC1101_REG_RW_WOREVT1: return "WOREVT1";
+ case CC1101_REG_RW_WOREVT0: return "WOREVT0";
+ case CC1101_REG_RW_WORCTRL: return "WORCTRL";
+ case CC1101_REG_RW_FREND1: return "FREND1";
+ case CC1101_REG_RW_FREND0: return "FREND0";
+ case CC1101_REG_RW_FSCAL3: return "FSCAL3";
+ case CC1101_REG_RW_FSCAL2: return "FSCAL2";
+ case CC1101_REG_RW_FSCAL1: return "FSCAL1";
+ case CC1101_REG_RW_FSCAL0: return "FSCAL0";
+ case CC1101_REG_RW_RCCTRL1: return "RCCTRL1";
+ case CC1101_REG_RW_RCCTRL0: return "RCCTRL0";
+ case CC1101_REG_RW_FSTEST: return "FSTEST";
+ case CC1101_REG_RW_PTEST: return "PTEST";
+ case CC1101_REG_RW_AGCTEST: return "AGCTEST";
+ case CC1101_REG_RW_TEST2: return "TEST2";
+ case CC1101_REG_RW_TEST1: return "TEST1";
+ case CC1101_REG_RW_TEST0: return "TEST0";
+ default: return "unknown";
+ }
+}
+
+static char* cc1101_status_reg_to_string(uint8_t addr)
+{
+ switch(addr) {
+ case CC1101_REG_RO_PARTNUM: return "PARTNUM";
+ case CC1101_REG_RO_VERSION: return "VERSION";
+ case CC1101_REG_RO_FREQUEST: return "FREQUEST";
+ case CC1101_REG_RO_LQI: return "LQI";
+ case CC1101_REG_RO_RSSI: return "RSSI";
+ case CC1101_REG_RO_MARCSTATE: return "MARCSTATE";
+ case CC1101_REG_RO_WORTIME1: return "WORTIME1";
+ case CC1101_REG_RO_WORTIME0: return "WORTIME0";
+ case CC1101_REG_RO_PKTSTATUS: return "PKTSTATUS";
+ case CC1101_REG_RO_VCO_VC_DAC: return "VCO_VC_DAC";
+ case CC1101_REG_RO_TXBYTES: return "TXBYTES";
+ case CC1101_REG_RO_RXBYTES: return "RXBYTES";
+ case CC1101_REG_RO_RCCTRL1_STATUS: return "RCCTRL1_STATUS";
+ case CC1101_REG_RO_RCCTRL0_STATUS: return "RCCTRL0_STATUS";
+ default: return "unknown";
+ }
+}
+
+void cc1101_dump_register(void)
+{
+ printf("CC1101: register dump\r\n\r\n");
+
+ int i;
+
+ printf(" config (read/write) register:\r\n");
+ for(i=0; i<=CC1101_REG_RW_MAX; ++i) {
+ uint8_t data = cc1101_spi_read_register(i); // TODO: use burst mode...
+ printf(" 0x%02X (%s): 0x%02X\r\n", i, cc1101_config_reg_to_string(i), data);
+ }
+ printf("\r\n");
+
+ printf(" status (read-only) register:\r\n");
+ for(i=CC1101_REG_RO_MIN; i<=CC1101_REG_RO_MAX; ++i) {
+ uint8_t data = cc1101_spi_read_register(i);
+ printf(" 0x%02X (%s): 0x%02X\r\n", i, cc1101_status_reg_to_string(i), data);
+ }
+ printf("\r\n");
+}
diff --git a/lib/cc1101.h b/lib/cc1101.h
new file mode 100644
index 0000000..48454b6
--- /dev/null
+++ b/lib/cc1101.h
@@ -0,0 +1,144 @@
+/*
+ * spreadspace avr utils
+ *
+ *
+ * Copyright (C) 2013-2015 Christian Pointner <equinox@spreadspace.org>
+ *
+ * This file is part of spreadspace avr utils.
+ *
+ * spreadspace avr utils 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
+ * any later version.
+ *
+ * spreadspace avr utils 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 spreadspace avr utils. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef SPREADAVR_cc1101_h_INCLUDED
+#define SPREADAVR_cc1101_h_INCLUDED
+
+typedef enum { unknown, sleep, idle, xoff, mancal, fs_wakeup, calibrate, settling, rx, txrx_settling,
+ rxfifo_overflow, fstxon, tx, rxtx_settling, txfifo_underflow } cc1101_state_t;
+char* cc1101_state_to_string(cc1101_state_t);
+
+#define CC1101_FREQ_CORR(xtal) ((float)(xtal/65536.0))
+
+typedef struct {
+ void (*spi_cs_enable)(void);
+ void (*spi_cs_disable)(void);
+ uint8_t (*spi_read_miso)(void);
+ void (*spi_write_byte)(const uint8_t);
+ uint8_t (*spi_read_byte)(void);
+ uint8_t (*spi_transfer_byte)(const uint8_t);
+ float freq_corr;
+} cc1101_driver_conf_t;
+
+// high level interface
+
+void cc1101_init(cc1101_driver_conf_t conf);
+void cc1101_reg_init(void);
+void cc1101_soft_reset(void);
+
+void cc1101_powerdown(void);
+void cc1101_idle(void);
+void cc1101_osc_off(void);
+void cc1101_calibrate(void);
+void cc1101_fasttxon(void);
+void cc1101_rx(void);
+void cc1101_tx(void);
+cc1101_state_t cc1101_get_state(void);
+
+uint32_t cc1101_get_freq_hz(void);
+void cc1101_set_freq_hz(uint32_t hz);
+
+
+// normalized register access
+
+uint8_t cc1101_get_iocfg0(void);
+void cc1101_set_iocfg0(uint8_t iocfg);
+uint8_t cc1101_get_iocfg1(void);
+void cc1101_set_iocfg1(uint8_t iocfg);
+uint8_t cc1101_get_iocfg2(void);
+void cc1101_set_iocfg2(uint8_t iocfg);
+
+uint8_t cc1101_get_fifothr(void);
+void cc1101_set_fifothr(uint8_t fifothr);
+
+uint16_t cc1101_get_sync(void);
+void cc1101_set_sync(uint16_t sync);
+uint8_t cc1101_get_pktlen(void);
+void cc1101_set_pktlen(uint8_t len);
+uint16_t cc1101_get_pktctrl(void);
+void cc1101_set_pktctrl(uint16_t ctrl);
+uint8_t cc1101_get_addr(void);
+void cc1101_set_addr(uint8_t addr);
+
+uint8_t cc1101_get_channr(void);
+void cc1101_set_channr(uint8_t nr);
+uint8_t cc1101_get_iffreq(void);
+void cc1101_set_iffreq(uint8_t iffreq);
+uint8_t cc1101_get_freq_offset(void);
+void cc1101_set_freq_offset(uint8_t freqoff);
+uint32_t cc1101_get_freq(void);
+void cc1101_set_freq(uint32_t freq);
+uint64_t cc1101_get_modemcfg(void);
+void cc1101_set_modemcfg(uint64_t cfg);
+uint8_t cc1101_get_deviatn(void);
+void cc1101_set_deviatn(uint8_t dev);
+
+uint32_t cc1101_get_mcsm(void);
+void cc1101_set_mcsm(uint32_t cfg);
+
+uint8_t cc1101_get_foccfg(void);
+void cc1101_set_foccfg(uint8_t cfg);
+uint8_t cc1101_get_bscfg(void);
+void cc1101_set_bscfg(uint8_t cfg);
+uint32_t cc1101_get_agcctrl(void);
+void cc1101_set_agcctrl(uint32_t ctrl);
+uint16_t cc1101_get_worevt(void);
+void cc1101_set_worevt(uint16_t timeout);
+uint8_t cc1101_get_worctrl(void);
+void cc1101_set_worctrl(uint8_t ctrl);
+
+uint16_t cc1101_get_frend(void);
+void cc1101_set_frend(uint16_t cfg);
+uint32_t cc1101_get_fscal(void);
+void cc1101_set_fscal(uint32_t cal);
+uint16_t cc1101_get_rcctrl(void);
+void cc1101_set_rcctrl(uint16_t ctrl);
+
+uint8_t cc1101_get_fstest(void);
+void cc1101_set_fstest(uint8_t test);
+uint8_t cc1101_get_ptest(void);
+void cc1101_set_ptest(uint8_t test);
+uint8_t cc1101_get_agctest(void);
+void cc1101_set_agctest(uint8_t test);
+uint8_t cc1101_get_test0(void);
+void cc1101_set_test0(uint8_t test);
+uint8_t cc1101_get_test1(void);
+void cc1101_set_test1(uint8_t test);
+uint8_t cc1101_get_test2(void);
+void cc1101_set_test2(uint8_t test);
+
+uint8_t cc1101_get_partnum(void);
+uint8_t cc1101_get_chip_version(void);
+uint8_t cc1101_get_freq_offset_est(void);
+uint8_t cc1101_get_lqi(void);
+int8_t cc1101_get_rssi(void);
+uint8_t cc1101_get_marcstate(void);
+uint16_t cc1101_get_wortime(void);
+uint8_t cc1101_get_pkt_status(void);
+uint8_t cc1101_get_tx_bytes(void);
+uint8_t cc1101_get_rx_bytes(void);
+uint8_t cc1101_get_rcctrl0_status(void);
+uint8_t cc1101_get_rcctrl1_status(void);
+
+void cc1101_dump_register(void);
+
+#endif
diff --git a/lib/cc1101_defines.h b/lib/cc1101_defines.h
new file mode 100644
index 0000000..6018e60
--- /dev/null
+++ b/lib/cc1101_defines.h
@@ -0,0 +1,235 @@
+/*
+ * spreadspace avr utils
+ *
+ *
+ * Copyright (C) 2013-2015 Christian Pointner <equinox@spreadspace.org>
+ *
+ * This file is part of spreadspace avr utils.
+ *
+ * spreadspace avr utils 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
+ * any later version.
+ *
+ * spreadspace avr utils 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 spreadspace avr utils. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef SPREADAVR_CC1101_defines_h_INCLUDED
+#define SPREADAVR_CC1101_defines_h_INCLUDED
+
+//// header byte
+#define CC1101_HEADER_READ 0x80
+#define CC1101_HEADER_WRITE 0x00
+#define CC1101_HEADER_BURST 0x40
+#define CC1101_HEADER_READONLY 0xC0
+#define CC1101_HEADER_COMMAND 0x00
+
+//read/write config registers:
+#define CC1101_REG_RW_IOCFG2 0x00
+#define CC1101_REG_RW_IOCFG1 0x01
+#define CC1101_REG_RW_IOCFG0 0x02
+#define CC1101_REG_RW_FIFOTHR 0x03
+#define CC1101_REG_RW_SYNC1 0x04
+#define CC1101_REG_RW_SYNC0 0x05
+#define CC1101_REG_RW_PKTLEN 0x06
+#define CC1101_REG_RW_PKTCTRL1 0x07
+#define CC1101_REG_RW_PKTCTRL0 0x08
+#define CC1101_REG_RW_ADDR 0x09
+#define CC1101_REG_RW_CHANNR 0x0A
+#define CC1101_REG_RW_FSCTRL1 0x0B
+#define CC1101_REG_RW_FSCTRL0 0x0C
+#define CC1101_REG_RW_FREQ2 0x0D
+#define CC1101_REG_RW_FREQ1 0x0E
+#define CC1101_REG_RW_FREQ0 0x0F
+#define CC1101_REG_RW_MDMCFG4 0x10
+#define CC1101_REG_RW_MDMCFG3 0x11
+#define CC1101_REG_RW_MDMCFG2 0x12
+#define CC1101_REG_RW_MDMCFG1 0x13
+#define CC1101_REG_RW_MDMCFG0 0x14
+#define CC1101_REG_RW_DEVIATN 0x15
+#define CC1101_REG_RW_MCSM2 0x16
+#define CC1101_REG_RW_MCSM1 0x17
+#define CC1101_REG_RW_MCSM0 0x18
+#define CC1101_REG_RW_FOCCFG 0x19
+#define CC1101_REG_RW_BSCFG 0x1A
+#define CC1101_REG_RW_AGCCTRL2 0x1B
+#define CC1101_REG_RW_AGCCTRL1 0x1C
+#define CC1101_REG_RW_AGCCTRL0 0x1D
+#define CC1101_REG_RW_WOREVT1 0x1E
+#define CC1101_REG_RW_WOREVT0 0x1F
+#define CC1101_REG_RW_WORCTRL 0x20
+#define CC1101_REG_RW_FREND1 0x21
+#define CC1101_REG_RW_FREND0 0x22
+#define CC1101_REG_RW_FSCAL3 0x23
+#define CC1101_REG_RW_FSCAL2 0x24
+#define CC1101_REG_RW_FSCAL1 0x25
+#define CC1101_REG_RW_FSCAL0 0x26
+#define CC1101_REG_RW_RCCTRL1 0x27
+#define CC1101_REG_RW_RCCTRL0 0x28
+#define CC1101_REG_RW_FSTEST 0x29
+#define CC1101_REG_RW_PTEST 0x2A
+#define CC1101_REG_RW_AGCTEST 0x2B
+#define CC1101_REG_RW_TEST2 0x2C
+#define CC1101_REG_RW_TEST1 0x2D
+#define CC1101_REG_RW_TEST0 0x2E
+
+#define CC1101_REG_RW_MAX 0x2E
+
+//read-only status registers:
+#define CC1101_REG_RO_PARTNUM 0x30
+#define CC1101_REG_RO_VERSION 0x31
+#define CC1101_REG_RO_FREQUEST 0x32
+#define CC1101_REG_RO_LQI 0x33
+#define CC1101_REG_RO_RSSI 0x34
+#define CC1101_REG_RO_MARCSTATE 0x35
+#define CC1101_REG_RO_WORTIME1 0x36
+#define CC1101_REG_RO_WORTIME0 0x37
+#define CC1101_REG_RO_PKTSTATUS 0x38
+#define CC1101_REG_RO_VCO_VC_DAC 0x39
+#define CC1101_REG_RO_TXBYTES 0x3A
+#define CC1101_REG_RO_RXBYTES 0x3B
+#define CC1101_REG_RO_RCCTRL1_STATUS 0x3C
+#define CC1101_REG_RO_RCCTRL0_STATUS 0x3D
+
+#define CC1101_REG_RO_MIN 0x30
+#define CC1101_REG_RO_MAX 0x3D
+
+//commands:
+#define CC1101_CMD_SRES 0x30
+#define CC1101_CMD_SFSTXON 0x31
+#define CC1101_CMD_SXOFF 0x32
+#define CC1101_CMD_SCAL 0x33
+#define CC1101_CMD_SRX 0x34
+#define CC1101_CMD_STX 0x35
+#define CC1101_CMD_SIDLE 0x36
+#define CC1101_CMD_SWOR 0x38
+#define CC1101_CMD_SPWD 0x39
+#define CC1101_CMD_SFRX 0x3A
+#define CC1101_CMD_SFTX 0x3B
+#define CC1101_CMD_SWORRST 0x3C
+#define CC1101_CMD_SNOP 0x3D
+
+#define CC1101_CMD_MIN 0x30
+#define CC1101_CMD_MAX 0x3D
+
+//power amplifier table
+#define CC1101_REG_PATABLE 0x3E
+#define CC1101_PATABLE_SIZE 8
+//data FIFOs
+#define CC1101_REG_FIFO 0x3F
+#define CC1101_FIFO_MAX_LEN 64
+
+
+#define CC1101_ADDR_MAX 0x3F
+
+
+////status byte:
+#define CC1101_STATUS_CHIP_NOT_RDY(x) (x & 0b10000000)
+#define CC1101_STATUS_IDLE(x) ((x & 0b01110000) == 0b00000000)
+#define CC1101_STATUS_RXMODE(x) ((x & 0b01110000) == 0b00010000)
+#define CC1101_STATUS_TXMODE(x) ((x & 0b01110000) == 0b00100000)
+#define CC1101_STATUS_FSTXON(x) ((x & 0b01110000) == 0b00110000)
+#define CC1101_STATUS_CALIBRATE(x) ((x & 0b01110000) == 0b01000000)
+#define CC1101_STATUS_SETTLING(x) ((x & 0b01110000) == 0b01010000)
+#define CC1101_STATUS_RXFIFO_OVERFLOW(x) ((x & 0b01110000) == 0b01100000)
+#define CC1101_STATUS_TXFIFO_OVERFLOW(x) ((x & 0b01110000) == 0b01110000)
+#define CC1101_STATUS_FIFO_BYTES_AVAILABLE(x) (x & 0b00001111)
+
+
+#define CC1101_MARCSTATE_SLEEP 0x00
+#define CC1101_MARCSTATE_IDLE 0x01
+#define CC1101_MARCSTATE_XOFF 0x02
+#define CC1101_MARCSTATE_VCOON_MC 0x03
+#define CC1101_MARCSTATE_REGON_MC 0x04
+#define CC1101_MARCSTATE_MANCAL 0x05
+#define CC1101_MARCSTATE_VCOON 0x06
+#define CC1101_MARCSTATE_REGON 0x07
+#define CC1101_MARCSTATE_STARTCAL 0x08
+#define CC1101_MARCSTATE_BWBOOST 0x09
+#define CC1101_MARCSTATE_FS_LOCK 0x0A
+#define CC1101_MARCSTATE_IFADCON 0x0B
+#define CC1101_MARCSTATE_ENDCAL 0x0C
+#define CC1101_MARCSTATE_RX 0x0D
+#define CC1101_MARCSTATE_RX_END 0x0E
+#define CC1101_MARCSTATE_RX_RST 0x0F
+#define CC1101_MARCSTATE_TXRX_SWITCH 0x10
+#define CC1101_MARCSTATE_RXFIFO_OVERFLOW 0x11
+#define CC1101_MARCSTATE_FSTXON 0x12
+#define CC1101_MARCSTATE_TX 0x13
+#define CC1101_MARCSTATE_TX_END 0x14
+#define CC1101_MARCSTATE_RXTX_SWITCH 0x15
+#define CC1101_MARCSTATE_TXFIFO_UNDERFLOW 0x16
+
+#define CC1101_GDO_CFG_3STATE 0x2E
+
+
+//register masks
+#define CC1101_REG_RW_IOCFG2_MASK 0x7F
+#define CC1101_REG_RW_IOCFG1_MASK 0xFF
+#define CC1101_REG_RW_IOCFG0_MASK 0xFF
+#define CC1101_REG_RW_FIFOTHR_MASK 0x7F
+#define CC1101_REG_RW_SYNC1_MASK 0xFF
+#define CC1101_REG_RW_SYNC0_MASK 0xFF
+#define CC1101_REG_RW_PKTLEN_MASK 0xFF
+#define CC1101_REG_RW_PKTCTRL1_MASK 0xEF
+#define CC1101_REG_RW_PKTCTRL0_MASK 0x77
+#define CC1101_REG_RW_ADDR_MASK 0xFF
+#define CC1101_REG_RW_CHANNR_MASK 0xFF
+#define CC1101_REG_RW_FSCTRL1_MASK 0x1F
+#define CC1101_REG_RW_FSCTRL0_MASK 0xFF
+#define CC1101_REG_RW_FREQ2_MASK 0x3F
+#define CC1101_REG_RW_FREQ1_MASK 0xFF
+#define CC1101_REG_RW_FREQ0_MASK 0xFF
+#define CC1101_REG_RW_MDMCFG4_MASK 0xFF
+#define CC1101_REG_RW_MDMCFG3_MASK 0xFF
+#define CC1101_REG_RW_MDMCFG2_MASK 0xFF
+#define CC1101_REG_RW_MDMCFG1_MASK 0xF3
+#define CC1101_REG_RW_MDMCFG0_MASK 0xFF
+#define CC1101_REG_RW_DEVIATN_MASK 0x77
+#define CC1101_REG_RW_MCSM2_MASK 0x1F
+#define CC1101_REG_RW_MCSM1_MASK 0x3F
+#define CC1101_REG_RW_MCSM0_MASK 0x3F
+#define CC1101_REG_RW_FOCCFG_MASK 0x3F
+#define CC1101_REG_RW_BSCFG_MASK 0xFF
+#define CC1101_REG_RW_AGCCTRL2_MASK 0xFF
+#define CC1101_REG_RW_AGCCTRL1_MASK 0x7F
+#define CC1101_REG_RW_AGCCTRL0_MASK 0xFF
+#define CC1101_REG_RW_WOREVT1_MASK 0xFF
+#define CC1101_REG_RW_WOREVT0_MASK 0xFF
+#define CC1101_REG_RW_WORCTRL_MASK 0xFB
+#define CC1101_REG_RW_FREND1_MASK 0xFF
+#define CC1101_REG_RW_FREND0_MASK 0x37
+#define CC1101_REG_RW_FSCAL3_MASK 0xFF
+#define CC1101_REG_RW_FSCAL2_MASK 0x3F
+#define CC1101_REG_RW_FSCAL1_MASK 0x3F
+#define CC1101_REG_RW_FSCAL0_MASK 0x7F
+#define CC1101_REG_RW_RCCTRL1_MASK 0x7F
+#define CC1101_REG_RW_RCCTRL0_MASK 0x7F
+#define CC1101_REG_RW_FSTEST_MASK 0xFF
+#define CC1101_REG_RW_PTEST_MASK 0xFF
+#define CC1101_REG_RW_AGCTEST_MASK 0xFF
+#define CC1101_REG_RW_TEST2_MASK 0xFF
+#define CC1101_REG_RW_TEST1_MASK 0xFF
+#define CC1101_REG_RW_TEST0_MASK 0xFF
+#define CC1101_REG_RO_PARTNUM_MASK 0xFF
+#define CC1101_REG_RO_VERSION_MASK 0xFF
+#define CC1101_REG_RO_FREQUEST_MASK 0xFF
+#define CC1101_REG_RO_LQI_MASK 0xFF
+#define CC1101_REG_RO_RSSI_MASK 0xFF
+#define CC1101_REG_RO_MARCSTATE_MASK 0x1F
+#define CC1101_REG_RO_WORTIME1_MASK 0xFF
+#define CC1101_REG_RO_WORTIME0_MASK 0xFF
+#define CC1101_REG_RO_PKTSTATUS_MASK 0xFF
+#define CC1101_REG_RO_VCO_VC_DAC_MASK 0xFF
+#define CC1101_REG_RO_TXBYTES_MASK 0xFF
+#define CC1101_REG_RO_RXBYTES_MASK 0xFF
+#define CC1101_REG_RO_RCCTRL1_STATUS_MASK 0x7F
+#define CC1101_REG_RO_RCCTRL0_STATUS_MASK 0x7F
+
+#endif