[FL-950] CC1101 Stage1, SPI Refactoring, Drivers layer (#386)

* API HAL SPI: refactoring, split into layers, prepare ST HAL separation. API HAL SubGhz: initialize on start. Drivers: add basic cc1101 driver. Update API usage. Debug: increase max debugger port speed. Remove subghz apps.
* CC1101: chip status handling. ApiHalSpi: increase SubGhz bus speed to 8mhz. F4: backport subghz initialization.
* Api Hal SubGhz: rx path and frequency. CC1101: frequency control.
* SubGhz Application: basic tests
* SubGhz app: tone and packet test. API HAL SUBGHZ: update configs, add missing bits and pieces.
This commit is contained in:
あく
2021-03-31 20:52:26 +03:00
committed by GitHub
parent 5309bfae41
commit 5439e232cc
60 changed files with 2364 additions and 2500 deletions

View File

@@ -7,6 +7,7 @@
static osThreadAttr_t platform_irq_thread_attr;
static volatile osThreadId_t platform_irq_thread_id = NULL;
static volatile PlatformIrqCallback platform_irq_callback = NULL;
static ApiHalSpiDevice* platform_st25r3916 = NULL;
void nfc_isr(void* _pin, void* _ctx) {
uint32_t pin = (uint32_t)_pin;
@@ -36,27 +37,30 @@ void platformSetIrqCallback(PlatformIrqCallback callback) {
}
HAL_StatusTypeDef platformSpiTxRx(const uint8_t *txBuf, uint8_t *rxBuf, uint16_t len) {
HAL_StatusTypeDef ret;
bool ret = false;
if (txBuf && rxBuf) {
ret = HAL_SPI_TransmitReceive(&SPI_R, (uint8_t*)txBuf, rxBuf, len, HAL_MAX_DELAY);
ret = api_hal_spi_bus_trx(platform_st25r3916->bus, (uint8_t*)txBuf, rxBuf, len, 1000);
} else if (txBuf) {
ret = HAL_SPI_Transmit(&SPI_R, (uint8_t*)txBuf, len, HAL_MAX_DELAY);
ret = api_hal_spi_bus_tx(platform_st25r3916->bus, (uint8_t*)txBuf, len, 1000);
} else if (rxBuf) {
ret = HAL_SPI_Receive(&SPI_R, (uint8_t*)rxBuf, len, HAL_MAX_DELAY);
ret = api_hal_spi_bus_rx(platform_st25r3916->bus, (uint8_t*)rxBuf, len, 1000);
}
if(ret != HAL_OK) {
if(!ret) {
asm("bkpt 1");
exit(255);
return HAL_ERROR;
} else {
return HAL_OK;
}
return ret;
}
void platformProtectST25RComm() {
api_hal_spi_lock(&SPI_R);
NFC_SPI_Reconfigure();
furi_assert(platform_st25r3916 == NULL);
platform_st25r3916 = (ApiHalSpiDevice*)api_hal_spi_device_get(ApiHalSpiDeviceIdNfc);
}
void platformUnprotectST25RComm() {
api_hal_spi_unlock(&SPI_R);
furi_assert(platform_st25r3916);
api_hal_spi_device_return(platform_st25r3916);
platform_st25r3916 = NULL;
}

View File

@@ -58,40 +58,40 @@ void platformUnprotectST25RComm();
#define platformIrqST25RSetCallback( cb ) platformSetIrqCallback(cb)
#define platformProtectST25RIrqStatus() platformProtectST25RComm() /*!< Protect unique access to IRQ status var - IRQ disable on single thread environment (MCU) ; Mutex lock on a multi thread environment */
#define platformUnprotectST25RIrqStatus() platformUnprotectST25RComm() /*!< Unprotect the IRQ status var - IRQ enable on a single thread environment (MCU) ; Mutex unlock on a multi thread environment */
#define platformProtectST25RIrqStatus() platformProtectST25RComm() /*!< Protect unique access to IRQ status var - IRQ disable on single thread environment (MCU) ; Mutex lock on a multi thread environment */
#define platformUnprotectST25RIrqStatus() platformUnprotectST25RComm() /*!< Unprotect the IRQ status var - IRQ enable on a single thread environment (MCU) ; Mutex unlock on a multi thread environment */
#define platformLedOff( port, pin ) api_hal_light_set(pin, 0x00)
#define platformLedOn( port, pin ) api_hal_light_set(pin, 0xFF)
#define platformLedOff( port, pin ) api_hal_light_set(pin, 0x00)
#define platformLedOn( port, pin ) api_hal_light_set(pin, 0xFF)
#define platformGpioSet( port, pin ) HAL_GPIO_WritePin(port, pin, GPIO_PIN_SET) /*!< Turns the given GPIO High */
#define platformGpioClear( port, pin ) HAL_GPIO_WritePin(port, pin, GPIO_PIN_RESET) /*!< Turns the given GPIO Low */
#define platformGpioToogle( port, pin ) HAL_GPIO_TogglePin(port, pin) /*!< Toogles the given GPIO */
#define platformGpioIsHigh( port, pin ) (HAL_GPIO_ReadPin(port, pin) == GPIO_PIN_SET) /*!< Checks if the given LED is High */
#define platformGpioIsLow( port, pin ) (!platformGpioIsHigh(port, pin)) /*!< Checks if the given LED is Low */
#define platformGpioSet( port, pin ) HAL_GPIO_WritePin(port, pin, GPIO_PIN_SET) /*!< Turns the given GPIO High */
#define platformGpioClear( port, pin ) HAL_GPIO_WritePin(port, pin, GPIO_PIN_RESET) /*!< Turns the given GPIO Low */
#define platformGpioToogle( port, pin ) HAL_GPIO_TogglePin(port, pin) /*!< Toogles the given GPIO */
#define platformGpioIsHigh( port, pin ) (HAL_GPIO_ReadPin(port, pin) == GPIO_PIN_SET) /*!< Checks if the given LED is High */
#define platformGpioIsLow( port, pin ) (!platformGpioIsHigh(port, pin)) /*!< Checks if the given LED is Low */
#define platformTimerCreate( t ) timerCalculateTimer(t) /*!< Create a timer with the given time (ms) */
#define platformTimerIsExpired( timer ) timerIsExpired(timer) /*!< Checks if the given timer is expired */
#define platformDelay( t ) osDelay( t ) /*!< Performs a delay for the given time (ms) */
#define platformTimerCreate( t ) timerCalculateTimer(t) /*!< Create a timer with the given time (ms) */
#define platformTimerIsExpired( timer ) timerIsExpired(timer) /*!< Checks if the given timer is expired */
#define platformDelay( t ) osDelay( t ) /*!< Performs a delay for the given time (ms) */
#define platformGetSysTick() osKernelGetTickCount() /*!< Get System Tick (1 tick = 1 ms) */
#define platformGetSysTick() osKernelGetTickCount() /*!< Get System Tick (1 tick = 1 ms) */
#define platformAssert( exp ) assert_param( exp ) /*!< Asserts whether the given expression is true*/
// #define platformErrorHandle() Error_Handler() /*!< Global error handle\trap */
#define platformAssert( exp ) assert_param( exp ) /*!< Asserts whether the given expression is true*/
#define platformErrorHandle() Error_Handler() /*!< Global error handle\trap */
#define platformSpiSelect() platformGpioClear( ST25R_SS_PORT, ST25R_SS_PIN ) /*!< SPI SS\CS: Chip|Slave Select */
#define platformSpiDeselect() platformGpioSet( ST25R_SS_PORT, ST25R_SS_PIN ) /*!< SPI SS\CS: Chip|Slave Deselect */
#define platformSpiSelect() platformGpioClear( ST25R_SS_PORT, ST25R_SS_PIN ) /*!< SPI SS\CS: Chip|Slave Select */
#define platformSpiDeselect() platformGpioSet( ST25R_SS_PORT, ST25R_SS_PIN ) /*!< SPI SS\CS: Chip|Slave Deselect */
#define platformI2CTx( txBuf, len, last, txOnly ) /*!< I2C Transmit */
#define platformI2CRx( txBuf, len ) /*!< I2C Receive */
#define platformI2CStart() /*!< I2C Start condition */
#define platformI2CStop() /*!< I2C Stop condition */
#define platformI2CRepeatStart() /*!< I2C Repeat Start */
#define platformI2CSlaveAddrWR(add) /*!< I2C Slave address for Write operation */
#define platformI2CSlaveAddrRD(add) /*!< I2C Slave address for Read operation */
#define platformI2CTx( txBuf, len, last, txOnly ) /*!< I2C Transmit */
#define platformI2CRx( txBuf, len ) /*!< I2C Receive */
#define platformI2CStart() /*!< I2C Start condition */
#define platformI2CStop() /*!< I2C Stop condition */
#define platformI2CRepeatStart() /*!< I2C Repeat Start */
#define platformI2CSlaveAddrWR(add) /*!< I2C Slave address for Write operation */
#define platformI2CSlaveAddrRD(add) /*!< I2C Slave address for Read operation */
#define platformLog(...) /*!< Log method */
#define platformLog(...) /*!< Log method */
/*
******************************************************************************

171
lib/drivers/cc1101.c Normal file
View File

@@ -0,0 +1,171 @@
#include "cc1101.h"
#include <cmsis_os2.h>
#include <api-hal-delay.h>
#include <assert.h>
#include <string.h>
CC1101Status cc1101_strobe(const ApiHalSpiDevice* device, uint8_t strobe) {
uint8_t tx[1] = { strobe };
CC1101Status rx[1] = { 0 };
hal_gpio_write(device->chip_select, false);
while(hal_gpio_read(device->bus->miso));
api_hal_spi_bus_trx(device->bus, tx, (uint8_t*)rx, 1, CC1101_TIMEOUT);
hal_gpio_write(device->chip_select, true);
assert(rx[0].CHIP_RDYn == 0);
return rx[0];
}
CC1101Status cc1101_write_reg(const ApiHalSpiDevice* device, uint8_t reg, uint8_t data) {
uint8_t tx[2] = { reg, data };
CC1101Status rx[2] = { 0 };
hal_gpio_write(device->chip_select, false);
while(hal_gpio_read(device->bus->miso));
api_hal_spi_bus_trx(device->bus, tx, (uint8_t*)rx, 2, CC1101_TIMEOUT);
hal_gpio_write(device->chip_select, true);
assert((rx[0].CHIP_RDYn|rx[1].CHIP_RDYn) == 0);
return rx[1];
}
CC1101Status cc1101_read_reg(const ApiHalSpiDevice* device, uint8_t reg, uint8_t* data) {
assert(sizeof(CC1101Status) == 1);
uint8_t tx[2] = { reg|CC1101_READ, 0};
CC1101Status rx[2] = { 0 };
hal_gpio_write(device->chip_select, false);
while(hal_gpio_read(device->bus->miso));
api_hal_spi_bus_trx(device->bus, tx, (uint8_t*)rx, 2, CC1101_TIMEOUT);
hal_gpio_write(device->chip_select, true);
assert((rx[0].CHIP_RDYn) == 0);
*data = *(uint8_t*)&rx[1];
return rx[0];
}
uint8_t cc1101_get_partnumber(const ApiHalSpiDevice* device) {
uint8_t partnumber=0;
cc1101_read_reg(device, CC1101_STATUS_PARTNUM|CC1101_BURST, &partnumber);
return partnumber;
}
uint8_t cc1101_get_version(const ApiHalSpiDevice* device) {
uint8_t version=0;
cc1101_read_reg(device, CC1101_STATUS_VERSION|CC1101_BURST, &version);
return version;
}
uint8_t cc1101_get_rssi(const ApiHalSpiDevice* device) {
uint8_t rssi=0;
cc1101_read_reg(device, CC1101_STATUS_RSSI|CC1101_BURST, &rssi);
return rssi;
}
void cc1101_reset(const ApiHalSpiDevice* device) {
hal_gpio_write(device->chip_select, false);
delay_us(1000);
hal_gpio_write(device->chip_select, true);
delay_us(1000);
cc1101_strobe(device, CC1101_STROBE_SRES);
}
void cc1101_shutdown(const ApiHalSpiDevice* device) {
cc1101_strobe(device, CC1101_STROBE_SPWD);
}
void cc1101_calibrate(const ApiHalSpiDevice* device) {
cc1101_strobe(device, CC1101_STROBE_SCAL);
}
void cc1101_switch_to_idle(const ApiHalSpiDevice* device) {
cc1101_strobe(device, CC1101_STROBE_SIDLE);
}
void cc1101_switch_to_rx(const ApiHalSpiDevice* device) {
cc1101_strobe(device, CC1101_STROBE_SRX);
}
void cc1101_switch_to_tx(const ApiHalSpiDevice* device) {
cc1101_strobe(device, CC1101_STROBE_STX);
}
void cc1101_flush_rx(const ApiHalSpiDevice* device) {
cc1101_strobe(device, CC1101_STROBE_SFRX);
}
void cc1101_flush_tx(const ApiHalSpiDevice* device) {
cc1101_strobe(device, CC1101_STROBE_SFTX);
}
uint32_t cc1101_set_frequency(const ApiHalSpiDevice* device, uint32_t value) {
uint64_t real_value = (uint64_t)value * 0xFFFF / CC1101_QUARTZ;
// Sanity check
assert((real_value & 0xFFFFFF) == real_value);
cc1101_write_reg(device, CC1101_FREQ2, (real_value >> 16) & 0xFF);
cc1101_write_reg(device, CC1101_FREQ1, (real_value >> 8 ) & 0xFF);
cc1101_write_reg(device, CC1101_FREQ0, (real_value >> 0 ) & 0xFF);
uint64_t real_frequency = real_value * CC1101_QUARTZ / 0xFFFF;
return (uint32_t)real_frequency;
}
uint32_t cc1101_get_frequency_step(const ApiHalSpiDevice* device) {
return CC1101_QUARTZ / 0xFFFF;
}
uint32_t cc1101_set_frequency_offset(const ApiHalSpiDevice* device, uint32_t value) {
uint64_t real_value = value * 0x4000 / CC1101_QUARTZ;
assert((real_value & 0xFF) == real_value);
cc1101_write_reg(device, CC1101_FSCTRL0, (real_value >> 0 ) & 0xFF);
uint64_t real_frequency = real_value * CC1101_QUARTZ / 0x4000;
return (uint32_t)real_frequency;
}
uint32_t cc1101_get_frequency_offset_step(const ApiHalSpiDevice* device) {
return CC1101_QUARTZ / 0x4000;
}
void cc1101_set_pa_table(const ApiHalSpiDevice* device, const uint8_t value[8]) {
uint8_t tx[9] = { CC1101_PATABLE | CC1101_BURST };
CC1101Status rx[9] = { 0 };
memcpy(&tx[1], &value[0], 8);
hal_gpio_write(device->chip_select, false);
while(hal_gpio_read(device->bus->miso));
api_hal_spi_bus_trx(device->bus, tx, (uint8_t*)rx, 2, CC1101_TIMEOUT);
hal_gpio_write(device->chip_select, true);
assert((rx[0].CHIP_RDYn|rx[8].CHIP_RDYn) == 0);
}
uint8_t cc1101_write_fifo(const ApiHalSpiDevice* device, const uint8_t* data, uint8_t size) {
uint8_t tx = CC1101_FIFO | CC1101_BURST;
CC1101Status rx = { 0 };
// Start transaction
hal_gpio_write(device->chip_select, false);
// Wait IC to become ready
while(hal_gpio_read(device->bus->miso));
// Tell IC what we want
api_hal_spi_bus_trx(device->bus, &tx, (uint8_t*)&rx, 1, CC1101_TIMEOUT);
assert((rx.CHIP_RDYn) == 0);
// Transmit data
api_hal_spi_bus_tx(device->bus, (uint8_t*)data, size, CC1101_TIMEOUT);
// Finish transaction
hal_gpio_write(device->chip_select, true);
return size;
}
uint8_t cc1101_read_fifo(const ApiHalSpiDevice* device, uint8_t* data, uint8_t size) {
return size;
}

153
lib/drivers/cc1101.h Normal file
View File

@@ -0,0 +1,153 @@
#pragma once
#include "cc1101_regs.h"
#include <stdbool.h>
#include <stdint.h>
#include <api-hal-spi.h>
#ifdef __cplusplus
extern "C" {
#endif
/* Low level API */
/** Strobe command to the device
* @param device - pointer to ApiHalSpiDevice
* @param strobe - command to execute
* @return device status
*/
CC1101Status cc1101_strobe(const ApiHalSpiDevice* device, uint8_t strobe);
/** Write device register
* @param device - pointer to ApiHalSpiDevice
* @param reg - register
* @param data - data to write
* @return device status
*/
CC1101Status cc1101_write_reg(const ApiHalSpiDevice* device, uint8_t reg, uint8_t data);
/** Read device register
* @param device - pointer to ApiHalSpiDevice
* @param reg - register
* @param[out] data - pointer to data
* @return device status
*/
CC1101Status cc1101_read_reg(const ApiHalSpiDevice* device, uint8_t reg, uint8_t* data);
/* High level API */
/** Reset
* @param device - pointer to ApiHalSpiDevice
*/
void cc1101_reset(const ApiHalSpiDevice* device);
/** Enable shutdown mode
* @param device - pointer to ApiHalSpiDevice
*/
void cc1101_shutdown(const ApiHalSpiDevice* device);
/** Get Partnumber
* @param device - pointer to ApiHalSpiDevice
*/
uint8_t cc1101_get_partnumber(const ApiHalSpiDevice* device);
/** Get Version
* @param device - pointer to ApiHalSpiDevice
*/
uint8_t cc1101_get_version(const ApiHalSpiDevice* device);
/** Get raw RSSI value
* @param device - pointer to ApiHalSpiDevice
*/
uint8_t cc1101_get_rssi(const ApiHalSpiDevice* device);
/** Calibrate oscillator
* @param device - pointer to ApiHalSpiDevice
*/
void cc1101_calibrate(const ApiHalSpiDevice* device);
/** Switch to idle
* @param device - pointer to ApiHalSpiDevice
*/
void cc1101_switch_to_idle(const ApiHalSpiDevice* device);
/** Switch to RX
* @param device - pointer to ApiHalSpiDevice
*/
void cc1101_switch_to_rx(const ApiHalSpiDevice* device);
/** Switch to TX
* @param device - pointer to ApiHalSpiDevice
*/
void cc1101_switch_to_tx(const ApiHalSpiDevice* device);
/** Flush RX FIFO
* @param device - pointer to ApiHalSpiDevice
*/
void cc1101_flush_rx(const ApiHalSpiDevice* device);
/** Flush TX FIFO
* @param device - pointer to ApiHalSpiDevice
*/
void cc1101_flush_tx(const ApiHalSpiDevice* device);
/** Set Frequency
* Is not 100% precise, depends on quartz used
* @param device - pointer to ApiHalSpiDevice
* @param value - frequency in herz
* @return real frequency that were set
*/
uint32_t cc1101_set_frequency(const ApiHalSpiDevice* device, uint32_t value);
/** Get Frequency Step
* @param device - pointer to ApiHalSpiDevice
* @return frequency step
*/
uint32_t cc1101_get_frequency_step(const ApiHalSpiDevice* device);
/** Set Frequency Offset
* Is not 100% precise, depends on quartz used
* @param device - pointer to ApiHalSpiDevice
* @param value - frequency offset in herz
* @return real frequency that were set
*/
uint32_t cc1101_set_frequency_offset(const ApiHalSpiDevice* device, uint32_t value);
/** Get Frequency Offset Step
* @param device - pointer to ApiHalSpiDevice
* @return frequency offset step
*/
uint32_t cc1101_get_frequency_offset_step(const ApiHalSpiDevice* device);
/** Set Power Amplifier level table, ramp
* @param device - pointer to ApiHalSpiDevice
* @param value - array of power level values
*/
void cc1101_set_pa_table(const ApiHalSpiDevice* device, const uint8_t value[8]);
/** Set Power Amplifier level table, ramp
* @param device - pointer to ApiHalSpiDevice
* @param value - array of power level values
*/
void cc1101_set_pa_table(const ApiHalSpiDevice* device, const uint8_t value[8]);
/** Write FIFO
* @param device - pointer to ApiHalSpiDevice
* @param data, pointer to byte array
* @param size, write bytes count
* @return size, written bytes count
*/
uint8_t cc1101_write_fifo(const ApiHalSpiDevice* device, const uint8_t* data, uint8_t size);
/** Read FIFO
* @param device - pointer to ApiHalSpiDevice
* @param data, pointer to byte array
* @param size, bytes to read from fifo
* @return size, read bytes count
*/
uint8_t cc1101_read_fifo(const ApiHalSpiDevice* device, uint8_t* data, uint8_t size);
#ifdef __cplusplus
}
#endif

131
lib/drivers/cc1101_regs.h Normal file
View File

@@ -0,0 +1,131 @@
#pragma once
#include <stdbool.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
#define CC1101_QUARTZ 26000000
#define CC1101_TIMEOUT 500
#define CC1101_READ (1<<7) /** Read Bit */
#define CC1101_BURST (1<<6) /** Burst Bit */
/* Common registers, CC1101_BURST and CC1101_WRITE behaves as expected */
#define CC1101_IOCFG2 0x00 /** GDO2 output pin configuration */
#define CC1101_IOCFG1 0x01 /** GDO1 output pin configuration */
#define CC1101_IOCFG0 0x02 /** GDO0 output pin configuration */
#define CC1101_FIFOTHR 0x03 /** RX FIFO and TX FIFO thresholds */
#define CC1101_SYNC1 0x04 /** Sync word, high byte */
#define CC1101_SYNC0 0x05 /** Sync word, low byte */
#define CC1101_PKTLEN 0x06 /** Packet length */
#define CC1101_PKTCTRL1 0x07 /** Packet automation control */
#define CC1101_PKTCTRL0 0x08 /** Packet automation control */
#define CC1101_ADDR 0x09 /** Device address */
#define CC1101_CHANNR 0x0A /** Channel number */
#define CC1101_FSCTRL1 0x0B /** Frequency synthesizer control */
#define CC1101_FSCTRL0 0x0C /** Frequency synthesizer control */
#define CC1101_FREQ2 0x0D /** Frequency control word, high byte */
#define CC1101_FREQ1 0x0E /** Frequency control word, middle byte */
#define CC1101_FREQ0 0x0F /** Frequency control word, low byte */
#define CC1101_MDMCFG4 0x10 /** Modem configuration */
#define CC1101_MDMCFG3 0x11 /** Modem configuration */
#define CC1101_MDMCFG2 0x12 /** Modem configuration */
#define CC1101_MDMCFG1 0x13 /** Modem configuration */
#define CC1101_MDMCFG0 0x14 /** Modem configuration */
#define CC1101_DEVIATN 0x15 /** Modem deviation setting */
#define CC1101_MCSM2 0x16 /** Main Radio Control State Machine configuration */
#define CC1101_MCSM1 0x17 /** Main Radio Control State Machine configuration */
#define CC1101_MCSM0 0x18 /** Main Radio Control State Machine configuration */
#define CC1101_FOCCFG 0x19 /** Frequency Offset Compensation configuration */
#define CC1101_BSCFG 0x1A /** Bit Synchronization configuration */
#define CC1101_AGCTRL2 0x1B /** AGC control */
#define CC1101_AGCTRL1 0x1C /** AGC control */
#define CC1101_AGCTRL0 0x1D /** AGC control */
#define CC1101_WOREVT1 0x1E /** High byte Event 0 timeout */
#define CC1101_WOREVT0 0x1F /** Low byte Event 0 timeout */
#define CC1101_WORCTRL 0x20 /** Wake On Radio control */
#define CC1101_FREND1 0x21 /** Front end RX configuration */
#define CC1101_FREND0 0x22 /** Front end TX configuration */
#define CC1101_FSCAL3 0x23 /** Frequency synthesizer calibration */
#define CC1101_FSCAL2 0x24 /** Frequency synthesizer calibration */
#define CC1101_FSCAL1 0x25 /** Frequency synthesizer calibration */
#define CC1101_FSCAL0 0x26 /** Frequency synthesizer calibration */
#define CC1101_RCCTRL1 0x27 /** RC oscillator configuration */
#define CC1101_RCCTRL0 0x28 /** RC oscillator configuration */
#define CC1101_FSTEST 0x29 /** Frequency synthesizer calibration control */
#define CC1101_PTEST 0x2A /** Production test */
#define CC1101_AGCTEST 0x2B /** AGC test */
#define CC1101_TEST2 0x2C /** Various test settings */
#define CC1101_TEST1 0x2D /** Various test settings */
#define CC1101_TEST0 0x2E /** Various test settings */
/* Strobe registers, CC1101_BURST is not available, CC1101_WRITE ignored */
#define CC1101_STROBE_SRES 0x30 /** Reset chip. */
#define CC1101_STROBE_SFSTXON 0x31 /** Enable and calibrate frequency synthesizer (if MCSM0.FS_AUTOCAL=1). If in RX (with CCA): Go to a wait state where only the synthesizer is running (for quick RX / TX turnaround). */
#define CC1101_STROBE_SXOFF 0x32 /** Turn off crystal oscillator. */
#define CC1101_STROBE_SCAL 0x33 /** Calibrate frequency synthesizer and turn it off. SCAL can be strobed from IDLE mode without setting manual calibration mode (MCSM0.FS_AUTOCAL=0) */
#define CC1101_STROBE_SRX 0x34 /** Enable RX. Perform calibration first if coming from IDLE and MCSM0.FS_AUTOCAL=1. */
#define CC1101_STROBE_STX 0x35 /** In IDLE state: Enable TX. Perform calibration first if MCSM0.FS_AUTOCAL=1. If in RX state and CCA is enabled: Only go to TX if channel is clear. */
#define CC1101_STROBE_SIDLE 0x36 /** Exit RX / TX, turn off frequency synthesizer and exit Wake-On-Radio mode if applicable. */
#define CC1101_STROBE_SWOR 0x38 /** Start automatic RX polling sequence (Wake-on-Radio) as described in Section 19.5 if WORCTRL.RC_PD=0. */
/* 0x37 is unused */
#define CC1101_STROBE_SPWD 0x39 /** Enter power down mode when CSn goes high. */
#define CC1101_STROBE_SFRX 0x3A /** Flush the RX FIFO buffer. Only issue SFRX in IDLE or RXFIFO_OVERFLOW states. */
#define CC1101_STROBE_SFTX 0x3B /** Flush the TX FIFO buffer. Only issue SFTX in IDLE or TXFIFO_UNDERFLOW states. */
#define CC1101_STROBE_SWORRST 0x3C /** Reset real time clock to Event1 value. */
#define CC1101_STROBE_SNOP 0x3D /** No operation. May be used to get access to the chip status byte.*/
/* Status registers, must be accessed with CC1101_BURST, but one by one */
#define CC1101_STATUS_PARTNUM 0x30 /** Chip ID Part Number */
#define CC1101_STATUS_VERSION 0x31 /** Chip ID Version */
#define CC1101_STATUS_FREQEST 0x32 /** Frequency Offset Estimate from Demodulator */
#define CC1101_STATUS_LQI 0x33 /** Demodulator Estimate for Link Quality */
#define CC1101_STATUS_RSSI 0x34 /** Received Signal Strength Indication */
#define CC1101_STATUS_MARCSTATE 0x35 /** Main Radio Control State Machine State */
#define CC1101_STATUS_WORTIME1 0x36 /** High Byte of WOR Time */
#define CC1101_STATUS_WORTIME0 0x37 /** Low Byte of WOR Time */
#define CC1101_STATUS_PKTSTATUS 0x38 /** Current GDOx Status and Packet Status */
#define CC1101_STATUS_VCO_VC_DAC 0x39 /** Current Setting from PLL Calibration Module */
#define CC1101_STATUS_TXBYTES 0x3A /** Underflow and Number of Bytes */
#define CC1101_STATUS_RXBYTES 0x3B /** Overflow and Number of Bytes */
#define CC1101_STATUS_RCCTRL1_STATUS 0x3C /** Last RC Oscillator Calibration Result */
#define CC1101_STATUS_RCCTRL0_STATUS 0x3D /** Last RC Oscillator Calibration Result */
/* Some special registers, use CC1101_BURST to read/write data */
#define CC1101_PATABLE 0x3E /** PATABLE register number, an 8-byte table that defines the PA control settings */
#define CC1101_FIFO 0x3F /** FIFO register nunmber, can be combined with CC1101_WRITE and/or CC1101_BURST */
typedef enum {
CC1101StateIDLE=0b000, /** IDLE state */
CC1101StateRX=0b001, /** Receive mode */
CC1101StateTX=0b010, /** Transmit mode */
CC1101StateFSTXON=0b011, /** Fast TX ready */
CC1101StateCALIBRATE=0b100, /** Frequency synthesizer calibration is running */
CC1101StateSETTLING=0b101, /** PLL is settling */
CC1101StateRXFIFO_OVERFLOW=0b110, /** RX FIFO has overflowed. Read out any useful data, then flush the FIFO with SFRX */
CC1101StateTXFIFO_UNDERFLOW=0b111, /** TX FIFO has underflowed. Acknowledge with SFTX */
} CC1101State;
typedef struct {
uint8_t FIFO_BYTES_AVAILABLE:4;
CC1101State STATE:3;
bool CHIP_RDYn:1;
} CC1101Status;
typedef struct {
uint8_t NUM_TXBYTES:7;
bool TXFIFO_UNDERFLOW:1;
} CC1101TxBytes;
typedef struct {
uint8_t NUM_RXBYTES:7;
bool RXFIFO_OVERFLOW:1;
} CC1101RxBytes;
#ifdef __cplusplus
}
#endif