Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: CC1200-MorseEncoder CC1200-Examples
Revision 1:98af824b145e, committed 2020-08-09
- Comitter:
- Jamie Smith
- Date:
- Sun Aug 09 23:39:21 2020 -0700
- Parent:
- 0:0c3532738887
- Child:
- 2:2a447e8e50b8
- Commit message:
- Add a few new features, fix issue with reading from wrong FIFO
Changed in this revision
--- a/CC1200.cpp Tue Jun 30 02:26:28 2020 -0700
+++ b/CC1200.cpp Sun Aug 09 23:39:21 2020 -0700
@@ -1,3 +1,5 @@
+#pragma clang diagnostic push
+#pragma ide diagnostic ignored "readability-magic-numbers"
//
// Created by jamie on 3/27/2020.
//
@@ -283,11 +285,11 @@
writeRegister(Register::RFEND_CFG0, rfendCfg0);
}
-void CC1200::setOnTransmitState(CC1200::State state)
+void CC1200::setOnTransmitState(CC1200::State txState)
{
uint8_t rfendCfg0 = readRegister(Register::RFEND_CFG0);
rfendCfg0 &= ~(0b11 << RFEND_CFG0_TXOFF_MODE);
- rfendCfg0 |= getOffModeBits(state) << RFEND_CFG0_TXOFF_MODE;
+ rfendCfg0 |= getOffModeBits(txState) << RFEND_CFG0_TXOFF_MODE;
writeRegister(Register::RFEND_CFG0, rfendCfg0);
}
@@ -569,7 +571,7 @@
return CC1200_OSC_FREQ / (static_cast<float>(adcDecimation) * static_cast<float>(cicDecimation) * 2);
}
-void CC1200::setRXFilterBandwidth(float bandwidthHz, bool isCC1201)
+void CC1200::setRXFilterBandwidth(float bandwidthHz)
{
// settings that the chip supports
const uint8_t possibleADCDecimations[] = {12, 24, 48}; // indexes in this array represent the register value
@@ -629,6 +631,20 @@
writeRegister(Register::MDMCFG1, mdmCfg1Value);
+ // also set MDMCFG0.DATA_FILTER_EN, which should be 0b11 iff bandwidth / symbol rate > 10
+ uint8_t mdmCfg0Val = readRegister(Register::MDMCFG0);
+
+ if(bandwidthHz / symbolRateSps > 10.0f)
+ {
+ mdmCfg0Val |= 0b11 << MDMCFG0_DATA_FILTER_EN;
+ }
+ else
+ {
+ mdmCfg0Val &= ~(0b11 << MDMCFG0_DATA_FILTER_EN);
+ }
+
+ writeRegister(Register::MDMCFG0, mdmCfg0Val);
+
// finally, we need to set RX_CONFIG_LIMITATION. It's not exactly clear what this does, but its setting changes
// based on the filter BW.
uint8_t syncCfg0Value = readRegister(Register::SYNC_CFG0);
@@ -716,6 +732,62 @@
writeRegister(Register::PREAMBLE_CFG1, preambleCfg1);
}
+void CC1200::setPARampRate(uint8_t firstRampLevel, uint8_t secondRampLevel, CC1200::RampTime rampTime)
+{
+ uint8_t paCfg0Val = 0;
+ paCfg0Val |= (firstRampLevel << PA_CFG0_FIRST_IPL);
+ paCfg0Val |= (secondRampLevel << PA_CFG0_SECOND_IPL);
+ paCfg0Val |= (static_cast<uint8_t>(rampTime) << PA_CFG0_RAMP_SHAPE);
+
+ writeRegister(Register::PA_CFG0, paCfg0Val);
+}
+
+void CC1200::setAGCReferenceLevel(uint8_t level)
+{
+ writeRegister(Register::AGC_REF, level);
+}
+
+void CC1200::setAGCSyncBehavior(CC1200::SyncBehavior behavior)
+{
+ uint8_t agcCfg3Val = readRegister(Register::AGC_CFG3);
+ agcCfg3Val &= ~(0b111 << AGC_CFG3_AGC_SYNC_BEHAVIOUR);
+ agcCfg3Val |= static_cast<uint8_t>(behavior) << AGC_CFG3_AGC_SYNC_BEHAVIOUR;
+ writeRegister(Register::AGC_CFG3, agcCfg3Val);
+}
+
+void CC1200::setAGCGainTable(CC1200::GainTable table, uint8_t minGainIndex, uint8_t maxGainIndex)
+{
+ uint8_t agcCfg3Val = readRegister(Register::AGC_CFG3);
+ uint8_t agcCfg2Val = readRegister(Register::AGC_CFG2);
+
+ agcCfg3Val &= ~(0b11111 << AGC_CFG3_AGC_MIN_GAIN);
+ agcCfg2Val &= ~(0b11 << AGC_CFG2_FE_PERFORMANCE_MODE);
+ agcCfg2Val &= ~(0b11111 << AGC_CFG2_AGC_MAX_GAIN);
+
+ agcCfg3Val |= maxGainIndex << AGC_CFG3_AGC_MIN_GAIN;
+ agcCfg2Val |= static_cast<uint8_t>(table) << AGC_CFG2_FE_PERFORMANCE_MODE;
+ agcCfg2Val |= maxGainIndex << AGC_CFG2_AGC_MAX_GAIN;
+
+ writeRegister(Register::AGC_CFG3, agcCfg3Val);
+ writeRegister(Register::AGC_CFG2, agcCfg2Val);
+}
+
+void CC1200::setAGCHysteresis(uint8_t hysteresisCfg)
+{
+ uint8_t agcCfg0Val = readRegister(Register::AGC_CFG0);
+ agcCfg0Val &= ~(0b11 << AGC_CFG0_AGC_HYST_LEVEL);
+ agcCfg0Val |= hysteresisCfg << AGC_CFG0_AGC_HYST_LEVEL;
+ writeRegister(Register::AGC_CFG0, agcCfg0Val);
+}
+
+void CC1200::setAGCSlewRate(uint8_t slewrateCfg)
+{
+ uint8_t agcCfg0Val = readRegister(Register::AGC_CFG0);
+ agcCfg0Val &= ~(0b11 << AGC_CFG0_AGC_SLEWRATE_LIMIT);
+ agcCfg0Val |= slewrateCfg << AGC_CFG0_AGC_SLEWRATE_LIMIT;
+ writeRegister(Register::AGC_CFG0, agcCfg0Val);
+}
+
void CC1200::setIFMixCFG(uint8_t value)
{
uint8_t ifMixCfg = readRegister(ExtRegister::IF_MIX_CFG);
@@ -846,7 +918,7 @@
{
spi.select();
loadStatusByte(spi.write(CC1200_READ | CC1200_MEM_ACCESS));
- uint8_t value = spi.write(CC1200_TX_FIFO | address);
+ uint8_t value = spi.write(CC1200_RX_FIFO | address);
spi.deselect();
#if CC1200_REGISTER_LEVEL_DEBUG
@@ -857,25 +929,4 @@
}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+#pragma clang diagnostic pop
\ No newline at end of file
--- a/CC1200.h Tue Jun 30 02:26:28 2020 -0700
+++ b/CC1200.h Sun Aug 09 23:39:21 2020 -0700
@@ -174,7 +174,7 @@
private:
// chip data variables
bool chipReady = false;
- State state;
+ State state = State::IDLE;
bool isCC1201;
// current state variables
@@ -284,10 +284,10 @@
/**
* Set what state the radio will enter when a packet is sent.
- * @param state State when a packet is transmitted.
+ * @param txState State when a packet is transmitted.
* Accepts State::TX, State::IDLE, State::FAST_TX_ON, and State::RX.
*/
- void setOnTransmitState(State state);
+ void setOnTransmitState(State txState);
enum class FSCalMode : uint8_t
{
@@ -406,10 +406,17 @@
* NOTE: The symbol rate and the RX filter bandwidth must be compatible with each other.
* See the user guide for details.
*
+ * A number of different registers must be configured in order to properly configure the radio for a given bandwidth.
+ * This call currently sets the following register fields:
+ * - CHAN_BW.ADC_CIC_DECFACT
+ * - CHAN_BW.BB_CIC_DECFACT
+ * - MDMCFG1.DVGA_GAIN
+ * - MDMCFG0.DATA_FILTER_EN
+ * - SYNC_CFG0.RX_CONFIG_LIMITATION
+ *
* @param bandwidthHz the bandwidth in Hz
- * @param isCC1201 whether the current chip is a CC1201 instead of a CC1200. The CC1201 has a more limited set of valid bandwidth settings.
*/
- void setRXFilterBandwidth(float bandwidthHz, bool isCC1201 = false);
+ void setRXFilterBandwidth(float bandwidthHz);
/**
* Get the ADC CIC decimation that was calculated by the most recent setRXFilterBandwidth() call.
@@ -492,6 +499,90 @@
*/
void configurePreamble(uint8_t preambleLengthCfg, uint8_t preambleFormatCfg);
+ /**
+ * Enum for different PA ramp times.
+ */
+ enum class RampTime : uint8_t
+ {
+ RAMP_3_8_SYMBOL = 0b0,
+ RAMP_3_2_SYMBOL = 0b1,
+ RAMP_3_SYMBOL = 0b10,
+ RAMP_6_SYMBOL = 0b11
+ };
+
+ /**
+ * Set the length and shape of the power amplifier ramp-up curve.
+ * See section 7.1 for details.
+ *
+ * The PA will gradually ramp from off to full amplitude in rampTime relative to the
+ * symbol rate. At 1/3 of rampTime it will have ramped to (firstRampLevel / 16) * full amplitude,
+ * and at 2/3 of rampTime it will have ramped to ((secondRampLevel + 7) / 16) * full amplitude.
+ */
+ void setPARampRate(uint8_t firstRampLevel, uint8_t secondRampLevel, RampTime rampTime);
+
+ // Automatic Gain Control (AGC) Config
+ // ------------------------------------------------------------------------------
+
+ /**
+ * Set the AGC reference level which is the internal target power level that
+ * the AGC tries to adjust to.
+ *
+ * The user manual section 6.4 gives a rough formula to calculate this, but I've just used the SmartRF values.
+ *
+ * @param level Internal power level in dB.
+ */
+ void setAGCReferenceLevel(uint8_t level);
+
+ /**
+ * Enum for possible AGC actions after is a sync word detection.
+ * See AGC_CFG3 register description for more info.
+ */
+ enum class SyncBehavior : uint8_t
+ {
+ FREEZE_NONE = 0b000,
+ FREEZE_GAIN = 0b001,
+ AGC_SLOWMODE = 0b010,
+ FREEZE_BOTH = 0b011
+ };
+
+ /**
+ * Set the AGC behavior after a sync word is detected.
+ * @param behavior
+ */
+ void setAGCSyncBehavior(SyncBehavior behavior);
+
+ /**
+ * Enum for possible gain tables to use.
+ * See AGC_CFG2 register description for more info.
+ */
+ enum class GainTable : uint8_t
+ {
+ OPTIMIZED_LINEARITY = 0b00,
+ NORMAL = 0b01,
+ LOW_POWER = 0b10,
+ ZERO_IF = 0b11
+ };
+
+ /**
+ * Set the gain table and min and max values within that table to use.
+ * Min and max values are indexes into the current selected table.
+ */
+ void setAGCGainTable(GainTable table, uint8_t minGainIndex, uint8_t maxGainIndex);
+
+ /**
+ * Configure the change in input signal power that must be sensed before the AGC starts to adjust itself.
+ * See the register description for AGC_CFG0.AGC_HYST_LEVEL
+ * @param hysteresisCfg
+ */
+ void setAGCHysteresis(uint8_t hysteresisCfg);
+
+ /**
+ * Configure the rate that the AGC changes the receive gain.
+ * See the register description for AGC_CFG0.AGC_SLEWRATE_LIMIT
+ * @param slewrateCfg
+ */
+ void setAGCSlewRate(uint8_t slewrateCfg);
+
// Register level functions
// ------------------------------------------------------------------------------
--- a/CC1200Bits.h Tue Jun 30 02:26:28 2020 -0700 +++ b/CC1200Bits.h Sun Aug 09 23:39:21 2020 -0700 @@ -108,4 +108,20 @@ #define PREAMBLE_CFG0_PQT_VALID_TIMEOUT 4 #define PREAMBLE_CFG0_PQT 0 +#define AGC_CFG3_AGC_SYNC_BEHAVIOUR 5 +#define AGC_CFG3_AGC_MIN_GAIN 0 + +#define AGC_CFG2_START_PREVIOUS_GAIN_EN 7 +#define AGC_CFG2_FE_PERFORMANCE_MODE 5 +#define AGC_CFG2_AGC_MAX_GAIN 0 + +#define AGC_CFG1_RSSI_STEP_THR 6 +#define AGC_CFG1_AGC_WIN_SIZE 3 +#define AGC_CFG1_AGC_SETTLE_WAIT 0 + +#define AGC_CFG0_AGC_HYST_LEVEL 6 +#define AGC_CFG0_AGC_SLEWRATE_LIMIT 4 +#define AGC_CFG0_RSSI_VALID_CNT 2 +#define AGC_CFG0_AGC_ASK_DECAY 0 + #endif //LIGHTSPEEDRANGEFINDER_CC1200BITS_H
CC1200