From 84ec28239ab027b88233abf9f75fb5607b40f7c7 Mon Sep 17 00:00:00 2001 From: jgromes Date: Sun, 10 Feb 2019 13:10:12 +0100 Subject: [PATCH] [CC1101] Implemented output power setting --- .../CC1101_Settings/CC1101_Settings.ino | 111 ++++++++++++++++++ src/modules/CC1101.cpp | 105 +++++++++++++++-- src/modules/CC1101.h | 4 +- 3 files changed, 212 insertions(+), 8 deletions(-) create mode 100644 examples/CC1101/CC1101_Settings/CC1101_Settings.ino diff --git a/examples/CC1101/CC1101_Settings/CC1101_Settings.ino b/examples/CC1101/CC1101_Settings/CC1101_Settings.ino new file mode 100644 index 00000000..e8789d1a --- /dev/null +++ b/examples/CC1101/CC1101_Settings/CC1101_Settings.ino @@ -0,0 +1,111 @@ +/* + RadioLib CC1101 Settings Example + + This example shows how to change all the properties of RF69 radio. + RadioLib currently supports the following settings: + - pins (SPI slave select, digital IO 0, digital IO 1) + - carrier frequency + - bit rate + - receiver bandwidth + - allowed frequency deviation + - output power during transmission + - sync word +*/ + +// include the library +#include + +// CC1101 module is in slot A on the shield +CC1101 cc1 = RadioShield.ModuleA; + +// if you're not using RadioShield, you can specify +// the connection yourself +// NSS pin: 6 +// DIO0 pin: 4 +// DIO1 pin: 5 +CC1101 cc2 = new Module(6, 4, 5); + +void setup() { + Serial.begin(9600); + + // initialize CC1101 with default settings + Serial.print(F("[CC1101] Initializing ... ")); + // carrier frequency: 868.0 MHz + // bit rate: 4.8 kbps + // Rx bandwidth: 325.0 kHz + // frequency deviation: 48.0 kHz + // sync word: 0xD391 + int state = cc1.begin(); + if (state == ERR_NONE) { + Serial.println(F("success!")); + } else { + Serial.print(F("failed, code ")); + Serial.println(state); + while (true); + } + + // initialize CC1101 with non-default settings + Serial.print(F("[CC1101] Initializing ... ")); + // carrier frequency: 434.0 MHz + // bit rate: 32.0 kbps + // Rx bandwidth: 250.0 kHz + // frequency deviation: 60.0 kHz + // sync word: 0xD391 + state = cc2.begin(434.0, 32.0, 250.0, 60.0); + if (state == ERR_NONE) { + Serial.println(F("success!")); + } else { + Serial.print(F("failed, code ")); + Serial.println(state); + while (true); + } + + // you can also change the settings at runtime + // and check if the configuration was changed successfully + + // set carrier frequency to 433.5 MHz + if (cc1.setFrequency(433.5) == ERR_INVALID_FREQUENCY) { + Serial.println(F("[CC1101] Selected frequency is invalid for this module!")); + while (true); + } + + // set bit rate to 100.0 kbps + state = cc1.setBitRate(100.0); + if (state == ERR_INVALID_BIT_RATE) { + Serial.println(F("[CC1101] Selected bit rate is invalid for this module!")); + while (true); + } else if (state == ERR_INVALID_BIT_RATE_BW_RATIO) { + Serial.println(F("[CC1101] Selected bit rate to bandwidth ratio is invalid!")); + Serial.println(F("[CC1101] Increase receiver bandwidth to set this bit rate.")); + while (true); + } + + // set receiver bandwidth to 250.0 kHz + if (cc1.setRxBandwidth(250.0) == ERR_INVALID_RX_BANDWIDTH) { + Serial.println(F("[CC1101] Selected receiver bandwidth is invalid for this module!")); + while (true); + } + + // set allowed frequency deviation to 10.0 kHz + if (cc1.setFrequencyDeviation(10.0) == ERR_INVALID_FREQUENCY_DEVIATION) { + Serial.println(F("[CC1101] Selected frequency deviation is invalid for this module!")); + while (true); + } + + // set output power to 5 dBm + if (cc1.setOutputPower(5) == ERR_INVALID_OUTPUT_POWER) { + Serial.println(F("[CC1101] Selected output power is invalid for this module!")); + while (true); + } + + // 2 bytes can be set as sync word + if (cc1.setSyncWord(0x01, 0x23) == ERR_INVALID_SYNC_WORD) { + Serial.println(F("[CC1101] Selected sync word is invalid for this module!")); + while (true); + } + +} + +void loop() { + // nothing here +} diff --git a/src/modules/CC1101.cpp b/src/modules/CC1101.cpp index cf60e02a..9cc8d00d 100644 --- a/src/modules/CC1101.cpp +++ b/src/modules/CC1101.cpp @@ -4,7 +4,7 @@ CC1101::CC1101(Module* module) : PhysicalLayer(CC1101_CRYSTAL_FREQ, CC1101_DIV_E _mod = module; } -int16_t CC1101::begin(float freq, float br, float rxBw, float freqDev) { +int16_t CC1101::begin(float freq, float br, float rxBw, float freqDev, int8_t power) { // set module properties _mod->SPIreadCommand = CC1101_CMD_READ; _mod->SPIwriteCommand = CC1101_CMD_WRITE; @@ -69,6 +69,11 @@ int16_t CC1101::begin(float freq, float br, float rxBw, float freqDev) { return(state); } + state = setOutputPower(power); + if(state != ERR_NONE) { + return(state); + } + // flush FIFOs SPIsendCommand(CC1101_CMD_FLUSH_RX); SPIsendCommand(CC1101_CMD_FLUSH_TX); @@ -77,11 +82,11 @@ int16_t CC1101::begin(float freq, float br, float rxBw, float freqDev) { } int16_t CC1101::transmit(String& str, uint8_t addr) { - return(CC1101::transmit(str.c_str())); + return(CC1101::transmit(str.c_str(), addr)); } int16_t CC1101::transmit(const char* str, uint8_t addr) { - return(CC1101::transmit((uint8_t*)str, strlen(str))); + return(CC1101::transmit((uint8_t*)str, strlen(str), addr)); } int16_t CC1101::transmit(uint8_t* data, size_t len, uint8_t addr) { @@ -105,6 +110,12 @@ int16_t CC1101::transmit(uint8_t* data, size_t len, uint8_t addr) { // write packet length SPIwriteRegister(CC1101_REG_FIFO, len); + // check address filtering + uint8_t filter = SPIgetRegValue(CC1101_REG_PKTCTRL1, 1, 0); + if(filter != CC1101_ADR_CHK_NONE) { + SPIwriteRegister(CC1101_REG_FIFO, addr); + } + // write packet to FIFO SPIwriteRegisterBurst(CC1101_REG_FIFO, data, len); @@ -164,6 +175,12 @@ int16_t CC1101::receive(uint8_t* data, size_t len) { // get packet length size_t length = SPIreadRegister(CC1101_REG_RXBYTES) - 2; + + // check address filtering + uint8_t filter = SPIgetRegValue(CC1101_REG_PKTCTRL1, 1, 0); + if(filter != CC1101_ADR_CHK_NONE) { + SPIreadRegister(CC1101_REG_FIFO); + } // read packet data if(len == 0) { @@ -275,6 +292,12 @@ int16_t CC1101::startTransmit(uint8_t* data, size_t len, uint8_t addr) { // write packet length SPIwriteRegister(CC1101_REG_FIFO, len); + // check address filtering + uint8_t filter = SPIgetRegValue(CC1101_REG_PKTCTRL1, 1, 0); + if(filter != CC1101_ADR_CHK_NONE) { + SPIwriteRegister(CC1101_REG_FIFO, addr); + } + // write packet to FIFO SPIwriteRegisterBurst(CC1101_REG_FIFO, data, len); @@ -320,6 +343,12 @@ int16_t CC1101::readData(String& str, size_t len) { int16_t CC1101::readData(uint8_t* data, size_t len) { // get packet length size_t length = SPIreadRegister(CC1101_REG_RXBYTES) - 2; + + // check address filtering + uint8_t filter = SPIgetRegValue(CC1101_REG_PKTCTRL1, 1, 0); + if(filter != CC1101_ADR_CHK_NONE) { + SPIreadRegister(CC1101_REG_FIFO); + } // read packet data if(len == 0) { @@ -374,7 +403,11 @@ int16_t CC1101::setFrequency(float freq) { int16_t state = SPIsetRegValue(CC1101_REG_FREQ2, (FRF & 0xFF0000) >> 16, 7, 0); state |= SPIsetRegValue(CC1101_REG_FREQ1, (FRF & 0x00FF00) >> 8, 7, 0); state |= SPIsetRegValue(CC1101_REG_FREQ0, FRF & 0x0000FF, 7, 0); - + + if(state == ERR_NONE) { + _freq = freq; + } + return(state); } @@ -455,6 +488,67 @@ int16_t CC1101::setSyncWord(uint8_t syncH, uint8_t syncL) { return(state); } +int16_t CC1101::setOutputPower(int8_t power) { + // round to the known frequency settings + uint8_t f; + if(_freq < 374.0) { + // 315 MHz + f = 0; + } else if(_freq < 650.5) { + // 434 MHz + f = 1; + } else if(_freq < 891.5) { + // 868 MHz + f = 2; + } else { + // 915 MHz + f = 3; + } + + // get raw power setting + uint8_t paTable[8][4] = {{0x12, 0x12, 0x03, 0x03}, + {0x0D, 0x0E, 0x0F, 0x0E}, + {0x1C, 0x1D, 0x1E, 0x1E}, + {0x34, 0x34, 0x27, 0x27}, + {0x51, 0x60, 0x50, 0x8E}, + {0x85, 0x84, 0x81, 0xCD}, + {0xCB, 0xC8, 0xCB, 0xC7}, + {0xC2, 0xC0, 0xC2, 0xC0}}; + + uint8_t powerRaw; + switch(power) { + case -30: + powerRaw = paTable[0][f]; + break; + case -20: + powerRaw = paTable[1][f]; + break; + case -15: + powerRaw = paTable[2][f]; + break; + case -10: + powerRaw = paTable[3][f]; + break; + case 0: + powerRaw = paTable[4][f]; + break; + case 5: + powerRaw = paTable[5][f]; + break; + case 7: + powerRaw = paTable[6][f]; + break; + case 10: + powerRaw = paTable[7][f]; + break; + default: + return(ERR_INVALID_OUTPUT_POWER); + } + + // write raw power setting + return(SPIsetRegValue(CC1101_REG_PATABLE, powerRaw)); +} + int16_t CC1101::setNodeAddress(uint8_t nodeAddr, uint8_t numBroadcastAddrs) { if(!(numBroadcastAddrs > 0) && (numBroadcastAddrs <= 2)) { return(ERR_INVALID_NUM_BROAD_ADDRS); @@ -510,9 +604,6 @@ int16_t CC1101::config() { return(state); } - // TODO: configurable power output - SPIwriteRegister(CC1101_REG_PATABLE, 0x60); - return(state); } diff --git a/src/modules/CC1101.h b/src/modules/CC1101.h index e7d637c6..4e8dfc78 100644 --- a/src/modules/CC1101.h +++ b/src/modules/CC1101.h @@ -500,7 +500,7 @@ class CC1101: public PhysicalLayer { CC1101(Module* module); // basic methods - int16_t begin(float freq = 868.0, float br = 4.8, float rxBw = 325.0, float freqDev = 48.0); + int16_t begin(float freq = 868.0, float br = 4.8, float rxBw = 325.0, float freqDev = 48.0, int8_t power = 0); int16_t transmit(String& str, uint8_t addr = 0); int16_t transmit(const char* str, uint8_t addr = 0); int16_t transmit(uint8_t* data, size_t len, uint8_t addr = 0); @@ -526,6 +526,7 @@ class CC1101: public PhysicalLayer { int16_t setRxBandwidth(float rxBw); int16_t setFrequencyDeviation(float freqDev); int16_t setSyncWord(uint8_t syncH, uint8_t syncL); + int16_t setOutputPower(int8_t power); int16_t setNodeAddress(uint8_t nodeAddr, uint8_t numBroadcastAddrs = 0); int16_t disableAddressFiltering(); float getRSSI(); @@ -534,6 +535,7 @@ class CC1101: public PhysicalLayer { private: Module* _mod; + float _freq; uint8_t _rawRSSI; uint8_t _rawLQI;