From fa1811fe73e8beae5f41526b81cfb698ffe4c735 Mon Sep 17 00:00:00 2001 From: OBones Date: Mon, 28 Feb 2022 17:27:29 +0100 Subject: [PATCH 1/2] Introduce asynchronous reception and transmission for CC1101 --- src/modules/CC1101/CC1101.cpp | 48 +++++++++++++++++++++++++++++++++++ src/modules/CC1101/CC1101.h | 17 +++++++++++++ 2 files changed, 65 insertions(+) diff --git a/src/modules/CC1101/CC1101.cpp b/src/modules/CC1101/CC1101.cpp index 7af7fa82..228c988c 100644 --- a/src/modules/CC1101/CC1101.cpp +++ b/src/modules/CC1101/CC1101.cpp @@ -208,6 +208,41 @@ int16_t CC1101::receiveDirect() { return(RADIOLIB_ERR_NONE); } +int16_t CC1101::transmitDirectAsync(uint32_t frf) { + // set RF switch (if present) + _mod->setRfSwitchState(LOW, HIGH); + + // user requested to start transmitting immediately (required for RTTY) + if(frf != 0) { + SPIwriteRegister(RADIOLIB_CC1101_REG_FREQ2, (frf & 0xFF0000) >> 16); + SPIwriteRegister(RADIOLIB_CC1101_REG_FREQ1, (frf & 0x00FF00) >> 8); + SPIwriteRegister(RADIOLIB_CC1101_REG_FREQ0, frf & 0x0000FF); + + SPIsendCommand(RADIOLIB_CC1101_CMD_TX); + } + + // activate asynchronous direct mode + int16_t state = asyncDirectMode(); + RADIOLIB_ASSERT(state); + + // start transmitting + SPIsendCommand(RADIOLIB_CC1101_CMD_TX); + return(state); +} + +int16_t CC1101::receiveDirectAsync() { + // set RF switch (if present) + _mod->setRfSwitchState(HIGH, LOW); + + // activate asynchronous direct mode + int16_t state = asyncDirectMode(); + RADIOLIB_ASSERT(state); + + // start receiving + SPIsendCommand(RADIOLIB_CC1101_CMD_RX); + return(ERR_NONE); +} + int16_t CC1101::packetMode() { int16_t state = SPIsetRegValue(RADIOLIB_CC1101_REG_PKTCTRL1, RADIOLIB_CC1101_CRC_AUTOFLUSH_OFF | RADIOLIB_CC1101_APPEND_STATUS_ON | RADIOLIB_CC1101_ADR_CHK_NONE, 3, 0); state |= SPIsetRegValue(RADIOLIB_CC1101_REG_PKTCTRL0, RADIOLIB_CC1101_WHITE_DATA_OFF | RADIOLIB_CC1101_PKT_FORMAT_NORMAL, 6, 4); @@ -902,6 +937,19 @@ int16_t CC1101::directMode() { return(state); } +int16_t CC1101::asyncDirectMode() { + // set mode to standby + SPIsendCommand(RADIOLIB_CC1101_CMD_IDLE); + + // set GDO0 mapping + int16_t state = SPIsetRegValue(RADIOLIB_CC1101_REG_IOCFG0, RADIOLIB_CC1101_GDOX_SERIAL_DATA_ASYNC , 5, 0); + + // set asynchronous continuous mode + state |= SPIsetRegValue(RADIOLIB_CC1101_REG_PKTCTRL0, RADIOLIB_CC1101_PKT_FORMAT_ASYNCHRONOUS, 5, 4); + state |= SPIsetRegValue(RADIOLIB_CC1101_REG_PKTCTRL0, RADIOLIB_CC1101_LENGTH_CONFIG_INFINITE, 1, 0); + return(state); +} + void CC1101::getExpMant(float target, uint16_t mantOffset, uint8_t divExp, uint8_t expMax, uint8_t& exp, uint8_t& mant) { // get table origin point (exp = 0, mant = 0) float origin = (mantOffset * RADIOLIB_CC1101_CRYSTAL_FREQ * 1000000.0)/((uint32_t)1 << divExp); diff --git a/src/modules/CC1101/CC1101.h b/src/modules/CC1101/CC1101.h index 5391203e..2aeb0bbe 100644 --- a/src/modules/CC1101/CC1101.h +++ b/src/modules/CC1101/CC1101.h @@ -591,6 +591,22 @@ class CC1101: public PhysicalLayer { */ int16_t receiveDirect() override; + /*! + \brief Starts asynchronous 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 transmitDirectAsync(uint32_t frf = 0); + + /*! + \brief Starts asynchronous direct mode reception. + + \returns \ref status_codes + */ + int16_t receiveDirectAsync(); + /*! \brief Stops direct mode. It is required to call this method to switch from direct transmissions to packet-based transmissions. */ @@ -953,6 +969,7 @@ class CC1101: public PhysicalLayer { int16_t config(); int16_t directMode(); + int16_t asyncDirectMode(); static void getExpMant(float target, uint16_t mantOffset, uint8_t divExp, uint8_t expMax, uint8_t& exp, uint8_t& mant); int16_t setPacketMode(uint8_t mode, uint16_t len); }; From 14184700388b38ae53733dec837309d2376794b3 Mon Sep 17 00:00:00 2001 From: OBones Date: Fri, 4 Mar 2022 09:38:59 +0100 Subject: [PATCH 2/2] Use protected overloads that accept the sync mode to avoid code duplication --- src/modules/CC1101/CC1101.cpp | 87 +++++++++++++---------------------- src/modules/CC1101/CC1101.h | 5 +- 2 files changed, 36 insertions(+), 56 deletions(-) diff --git a/src/modules/CC1101/CC1101.cpp b/src/modules/CC1101/CC1101.cpp index 228c988c..a5ee25cb 100644 --- a/src/modules/CC1101/CC1101.cpp +++ b/src/modules/CC1101/CC1101.cpp @@ -174,6 +174,14 @@ int16_t CC1101::standby() { } int16_t CC1101::transmitDirect(uint32_t frf) { + return transmitDirect(true, frf); +} + +int16_t CC1101::transmitDirectAsync(uint32_t frf) { + return transmitDirect(false, frf); +} + +int16_t CC1101::transmitDirect(bool sync, uint32_t frf) { // set RF switch (if present) _mod->setRfSwitchState(LOW, HIGH); @@ -187,7 +195,7 @@ int16_t CC1101::transmitDirect(uint32_t frf) { } // activate direct mode - int16_t state = directMode(); + int16_t state = directMode(sync); RADIOLIB_ASSERT(state); // start transmitting @@ -196,11 +204,19 @@ int16_t CC1101::transmitDirect(uint32_t frf) { } int16_t CC1101::receiveDirect() { + return receiveDirect(true); +} + +int16_t CC1101::receiveDirectAsync() { + return receiveDirect(false); +} + +int16_t CC1101::receiveDirect(bool sync) { // set RF switch (if present) _mod->setRfSwitchState(HIGH, LOW); // activate direct mode - int16_t state = directMode(); + int16_t state = directMode(sync); RADIOLIB_ASSERT(state); // start receiving @@ -208,41 +224,6 @@ int16_t CC1101::receiveDirect() { return(RADIOLIB_ERR_NONE); } -int16_t CC1101::transmitDirectAsync(uint32_t frf) { - // set RF switch (if present) - _mod->setRfSwitchState(LOW, HIGH); - - // user requested to start transmitting immediately (required for RTTY) - if(frf != 0) { - SPIwriteRegister(RADIOLIB_CC1101_REG_FREQ2, (frf & 0xFF0000) >> 16); - SPIwriteRegister(RADIOLIB_CC1101_REG_FREQ1, (frf & 0x00FF00) >> 8); - SPIwriteRegister(RADIOLIB_CC1101_REG_FREQ0, frf & 0x0000FF); - - SPIsendCommand(RADIOLIB_CC1101_CMD_TX); - } - - // activate asynchronous direct mode - int16_t state = asyncDirectMode(); - RADIOLIB_ASSERT(state); - - // start transmitting - SPIsendCommand(RADIOLIB_CC1101_CMD_TX); - return(state); -} - -int16_t CC1101::receiveDirectAsync() { - // set RF switch (if present) - _mod->setRfSwitchState(HIGH, LOW); - - // activate asynchronous direct mode - int16_t state = asyncDirectMode(); - RADIOLIB_ASSERT(state); - - // start receiving - SPIsendCommand(RADIOLIB_CC1101_CMD_RX); - return(ERR_NONE); -} - int16_t CC1101::packetMode() { int16_t state = SPIsetRegValue(RADIOLIB_CC1101_REG_PKTCTRL1, RADIOLIB_CC1101_CRC_AUTOFLUSH_OFF | RADIOLIB_CC1101_APPEND_STATUS_ON | RADIOLIB_CC1101_ADR_CHK_NONE, 3, 0); state |= SPIsetRegValue(RADIOLIB_CC1101_REG_PKTCTRL0, RADIOLIB_CC1101_WHITE_DATA_OFF | RADIOLIB_CC1101_PKT_FORMAT_NORMAL, 6, 4); @@ -923,29 +904,27 @@ int16_t CC1101::config() { return(state); } -int16_t CC1101::directMode() { +int16_t CC1101::directMode(bool sync) { // set mode to standby SPIsendCommand(RADIOLIB_CC1101_CMD_IDLE); - // set GDO0 and GDO2 mapping - int16_t state = SPIsetRegValue(RADIOLIB_CC1101_REG_IOCFG0, RADIOLIB_CC1101_GDOX_SERIAL_CLOCK , 5, 0); - state |= SPIsetRegValue(RADIOLIB_CC1101_REG_IOCFG2, RADIOLIB_CC1101_GDOX_SERIAL_DATA_SYNC , 5, 0); + int16_t state = 0; + if (sync) { + // set GDO0 and GDO2 mapping + state |= SPIsetRegValue(RADIOLIB_CC1101_REG_IOCFG0, RADIOLIB_CC1101_GDOX_SERIAL_CLOCK , 5, 0); + state |= SPIsetRegValue(RADIOLIB_CC1101_REG_IOCFG2, RADIOLIB_CC1101_GDOX_SERIAL_DATA_SYNC , 5, 0); - // set continuous mode - state |= SPIsetRegValue(RADIOLIB_CC1101_REG_PKTCTRL0, RADIOLIB_CC1101_PKT_FORMAT_SYNCHRONOUS, 5, 4); - state |= SPIsetRegValue(RADIOLIB_CC1101_REG_PKTCTRL0, RADIOLIB_CC1101_LENGTH_CONFIG_INFINITE, 1, 0); - return(state); -} + // set continuous mode + state |= SPIsetRegValue(RADIOLIB_CC1101_REG_PKTCTRL0, RADIOLIB_CC1101_PKT_FORMAT_SYNCHRONOUS, 5, 4); + } + else { + // set GDO0 mapping + state |= SPIsetRegValue(RADIOLIB_CC1101_REG_IOCFG0, RADIOLIB_CC1101_GDOX_SERIAL_DATA_ASYNC , 5, 0); -int16_t CC1101::asyncDirectMode() { - // set mode to standby - SPIsendCommand(RADIOLIB_CC1101_CMD_IDLE); + // set asynchronous continuous mode + state |= SPIsetRegValue(RADIOLIB_CC1101_REG_PKTCTRL0, RADIOLIB_CC1101_PKT_FORMAT_ASYNCHRONOUS, 5, 4); + } - // set GDO0 mapping - int16_t state = SPIsetRegValue(RADIOLIB_CC1101_REG_IOCFG0, RADIOLIB_CC1101_GDOX_SERIAL_DATA_ASYNC , 5, 0); - - // set asynchronous continuous mode - state |= SPIsetRegValue(RADIOLIB_CC1101_REG_PKTCTRL0, RADIOLIB_CC1101_PKT_FORMAT_ASYNCHRONOUS, 5, 4); state |= SPIsetRegValue(RADIOLIB_CC1101_REG_PKTCTRL0, RADIOLIB_CC1101_LENGTH_CONFIG_INFINITE, 1, 0); return(state); } diff --git a/src/modules/CC1101/CC1101.h b/src/modules/CC1101/CC1101.h index 2aeb0bbe..05afd0f1 100644 --- a/src/modules/CC1101/CC1101.h +++ b/src/modules/CC1101/CC1101.h @@ -968,8 +968,9 @@ class CC1101: public PhysicalLayer { int8_t _power = 0; int16_t config(); - int16_t directMode(); - int16_t asyncDirectMode(); + int16_t transmitDirect(bool sync, uint32_t frf); + int16_t receiveDirect(bool sync); + int16_t directMode(bool sync); static void getExpMant(float target, uint16_t mantOffset, uint8_t divExp, uint8_t expMax, uint8_t& exp, uint8_t& mant); int16_t setPacketMode(uint8_t mode, uint16_t len); };