diff --git a/.github/size_check.py b/.github/size_check.py new file mode 100644 index 0000000..a10d402 --- /dev/null +++ b/.github/size_check.py @@ -0,0 +1,52 @@ +"""Fail the build when the firmware leaves too little room in its app slot. + +PlatformIO only fails once the firmware no longer fits. Releases are built at +CORE_DEBUG_LEVEL=2 because the ESP32 image barely fits its 1.5 MB OTA slot, so +this warns while there is still room to act. + +Usage: python .github/size_check.py [min free KB] +Writes a line to $GITHUB_STEP_SUMMARY when it is set. +""" +import os +import struct +import sys + +ENTRY = struct.Struct(" 3 else 8 * 1024 + used = os.path.getsize(os.path.join(build_dir, "firmware.bin")) + slot = app_slot_size(os.path.join(build_dir, "partitions.bin")) + free = slot - used + ok = free >= min_free + line = (f"| {name} | {used:,} | {slot:,} | {free / 1024:.1f} KB | " + f"{'OK' if ok else f'FAIL: under {min_free // 1024} KB free'} |") + print(line) + summary = os.environ.get("GITHUB_STEP_SUMMARY") + if summary: + with open(summary, "a", encoding="utf-8") as f: + f.write("| Env | Firmware | App slot | Free | |\n|---|---|---|---|---|\n") + f.write(line + "\n") + return 0 if ok else 1 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index bbc23e1..b94857f 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -21,8 +21,9 @@ jobs: with: python-version: "3.12" + # pioarduino's fork of PlatformIO Core, which the pioarduino platform needs. - name: Install PlatformIO - run: pip install platformio + run: pip install pioarduino - name: Run native unit tests run: pio test -e native @@ -40,7 +41,9 @@ jobs: # fwname: firmware-only binary for OTA updates # obname: onboard image (bootloader + partitions + firmware + littlefs merged) # for flashing a new chip via USB/serial - # addr_bootloader: chip-dependent (ESP32: 0x1000, C3/S3/C6: 0x0) + # addr_bootloader: chip-dependent (ESP32: 0x1000, S3/C6: 0x0) + # No C3: on ESP-IDF 5.5 its image no longer fits the 1.5 MB OTA slot + # (docs/adr/0003-pioarduino-idf55.md). C3 boards stay on 3.0.x. # addr_fs: must match spiffs/littlefs offset in esp32_3MB.csv include: - env: esp32dev @@ -51,14 +54,6 @@ jobs: fwname: SomfyController.ino.esp32.bin fsname: SomfyController.littlefs.esp32.bin obname: SomfyController.onboard.esp32.bin - - env: esp32c3 - name: ESP32-C3 - chip: ESP32-C3 - addr_bootloader: "0x0" - addr_fs: "0x310000" - fwname: SomfyController.ino.esp32c3.bin - fsname: SomfyController.littlefs.esp32c3.bin - obname: SomfyController.onboard.esp32c3.bin - env: esp32s3 name: ESP32-S3 chip: ESP32-S3 @@ -112,7 +107,7 @@ jobs: python-version: "3.12" - name: Install PlatformIO and esptool - run: pip install platformio esptool + run: pip install pioarduino esptool - name: Build LittleFS image run: pio run -e ${{ matrix.env }} -t buildfs @@ -123,6 +118,9 @@ jobs: - name: Build firmware run: pio run -e ${{ matrix.env }} + - name: Check firmware size + run: python .github/size_check.py .pio/build/${{ matrix.env }} ${{ matrix.env }} 8 + - name: Restore LittleFS image run: cp littlefs.bin .pio/build/${{ matrix.env }}/littlefs.bin diff --git a/AGENTS.md b/AGENTS.md index b902d5b..c4089ab 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -2,3 +2,7 @@ - Fix any test or type errors until the whole suite is green. - Add or update tests for the code you change, even if nobody asked. - to test run `pio test -e native` + +## Building +- Firmware builds need pioarduino's Core (`pip install pioarduino`, or the pioarduino IDE extension). Stock PlatformIO Core refuses the pinned platform, see [ADR 0003](docs/adr/0003-pioarduino-idf55.md). +- The platform installs its Python packages into `~/.platformio/penv` and fails on Windows while `pio.exe` from that env is running. Run builds as `python -m platformio` from that env's Python. diff --git a/README.md b/README.md index 19c5a85..47f6043 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,9 @@ * Backup does no longer use LITTLEFS. Only RAM is used. Storage should not wear out so quick. * Added uptime info in web UI +## Building +The firmware builds on [pioarduino](https://github.com/pioarduino/platform-espressif32) (Arduino 3.x on ESP-IDF 5.5), not the stock PlatformIO platform. In VS Code use the **pioarduino IDE** extension instead of PlatformIO IDE. On the command line, `pip install pioarduino` gives you `pio`. Run the unit tests with `pio test -e native`. [ADR 0003](docs/adr/0003-pioarduino-idf55.md) explains why. + ## There is a partition layout modification it's just better to perform full ESP32 wipeout. Perform backup then wipeout the firmware and restore from the bkp. * fwname: firmware-only binary for OTA updates * obname: onboard image (bootloader + partitions + firmware + littlefs merged) for flashing a new chip via USB/serial diff --git a/data-src/index.js b/data-src/index.js index 6dd60fd..06a09ec 100644 --- a/data-src/index.js +++ b/data-src/index.js @@ -4834,7 +4834,8 @@ class Firmware { updateFirmware() { let div = this.createFileUploader('/updateFirmware'); let inst = div.querySelector('div[id=divInstText]'); - let html = '
Select a binary file [SomfyController.ino.esp32.bin] containing the device firmware then press the Upload File button.
'; + let chip = document.getElementById('divContainer').getAttribute('data-chipmodel') || ''; + let html = `
Select a binary file [SomfyController.ino.esp32${chip}.bin] containing the device firmware then press the Upload File button.
`; if (this.isMobile()) { html += `
WARNING
`; html += '
This browser does not support automatic backups. It is highly recommended that you back up your configuration using the backup button before proceeding.
'; @@ -4849,7 +4850,8 @@ class Firmware { let div = this.createFileUploader('/updateApplication'); general.reloadApp = true; let inst = div.querySelector('div[id=divInstText]'); - inst.innerHTML = '
Select a binary file [SomfyController.littlefs.bin] containing the littlefs data for the application then press the Upload File button.
'; + let chip = document.getElementById('divContainer').getAttribute('data-chipmodel') || ''; + inst.innerHTML = `
Select a binary file [SomfyController.littlefs.esp32${chip}.bin] containing the littlefs data for the application then press the Upload File button.
`; if (this.isMobile()) { inst.innerHTML += `
WARNING
`; inst.innerHTML += '
This browser does not support automatic backups. It is highly recommended that you back up your configuration using the backup button before proceeding.
'; diff --git a/docs/KNOWN_ISSUES.md b/docs/KNOWN_ISSUES.md index 402fe61..ed15935 100644 --- a/docs/KNOWN_ISSUES.md +++ b/docs/KNOWN_ISSUES.md @@ -267,3 +267,10 @@ On 2026-10-19 the log shows `web GET /controller from 192.168.1.197 total took 2 - **Fixed: a command for an unknown shade left no trace.** `handleShadeCommand`, `handleTiltCommand` and `handleGroupCommand` in [src/entryPoints/Web.cpp](../src/entryPoints/Web.cpp) now log a `not found` warning. On 2026-10-18 Home Assistant sent 10 commands to a device that had no shades yet, and the log showed only the response times. - **Fixed: `last ping 0ms ago` meant the client never pinged.** The disconnect line in [src/outputs/SocketEmitter.cpp](../src/outputs/SocketEmitter.cpp) now says `never pinged`. Browsers don't ping, so they always showed it. - **Open: `.gz does not exist` errors are noise.** `serveStatic` tries `.gz` first. For files stored without one (`appversion`, `icon.png`), LittleFS logs an `E`-level `does not exist, no permits for creation` line on every request. The fix would be for `minify.py` to gzip the plain files too. `setTryGzipFirst(false)` doesn't help: the error comes from `exists()` probing the missing variant, so it would only move the noise to the gzip-only files. + +## Installing "Main" from the update dialog always fails + +**Status:** open. Found 2026-10-20 while reviewing PR #72. +**Location:** `GitUpdater::beginUpdate` in [src/GitOTA.cpp](../src/GitOTA.cpp). + +The update dialog offers a "Main" entry next to the releases. For it, the updater downloads from `https://raw.githubusercontent.com/cjkas/ESPSomfy-RTS/master/`, but the repository holds no `.bin` files, so the firmware download 404s. Nothing is written and the device keeps running, so it does no harm, but the option can't work. Either drop the entry or point it at a build that publishes per-chip images. diff --git a/docs/SECURITY_PLAN.md b/docs/SECURITY_PLAN.md index 970c729..cd5576b 100644 --- a/docs/SECURITY_PLAN.md +++ b/docs/SECURITY_PLAN.md @@ -107,5 +107,6 @@ Everything else is checked with the `esp32devdbg` build, plus curl and websocket ## Not in this plan - TLS. +- Checking GitHub's certificate in `GitOTA`. It calls `setInsecure()`, so anyone who can intercept the update download can serve their own firmware. ESP-IDF 5.5 ([ADR 0003](adr/0003-pioarduino-idf55.md)) ships a certificate bundle, so this is possible now. It needs its own change: the full bundle costs more flash than the ESP32 build has spare, and pinning GitHub's root certificates might fit. - Session tokens with expiry. - Contents of the binary backup file (it holds no passwords, but it does hold rolling codes; `/backup` becomes a config route). diff --git a/docs/adr/0003-pioarduino-idf55.md b/docs/adr/0003-pioarduino-idf55.md new file mode 100644 index 0000000..3a6baf0 --- /dev/null +++ b/docs/adr/0003-pioarduino-idf55.md @@ -0,0 +1,18 @@ +# Firmware builds on pioarduino (Arduino 3.x, ESP-IDF 5.5), pinned to one release + +We moved every firmware env from `espressif32 @ 6.13.0` (Arduino 2.0.17 on ESP-IDF 4.4.7) to pioarduino's `55.03.312` (Arduino 3.3.12 on ESP-IDF 5.5). IDF 4.4 no longer gets security fixes for Wi-Fi, lwIP and mbedTLS, and the planned RMT radio needs IDF 5's RMT driver. The official PlatformIO platform never shipped Arduino 3.x, so pioarduino, a community fork, is the only way to get it in PlatformIO. We pin one release URL rather than `stable`, so a framework upgrade is always its own PR with its own size check and hardware test. + +## Considered Options + +- **Stay on IDF 4.4.** Rejected: no more security fixes, and no new RMT driver. +- **Rebuild the IDF libraries with `custom_sdkconfig`** to leave out PPP, NAT and provisioning (about 20 KB the firmware never uses). Deferred: it makes builds much slower, and log level 2 already makes the ESP32 build fit. +- **Grow the app slots in the partition table.** Rejected: an OTA update can't change the partition table, so every existing device would need a USB flash. + +## Consequences + +- **Firmware size.** The ESP32 image grows from 1,382,640 bytes (v3.0.14) to 1,555,472 at `CORE_DEBUG_LEVEL=2`, leaving 17 KB of the 1.5 MB OTA slot. At level 3 it doesn't fit, so release envs build at level 2 (warnings and errors) and debug envs stay at 3. PlatformIO's "Flash:" figure counts ELF sections, not the image, and reads about 45 KB low, so CI checks `firmware.bin` against the app partition and fails under 8 KB free (`.github/size_check.py`). +- **No more C3 builds.** Its image grows by 214 KB to 1,651,216 bytes, 76.5 KB over the OTA slot even at level 2. C3 boards stay on the 3.0.x releases. +- **Ethernet PHY ids are ours.** Arduino 3.x renumbered `eth_phy_type_t` (`ETH_PHY_GENERIC` is 0). NVS, backups and the web UI keep the Arduino 2.x numbers as `eth_phy_id_t` (`src/EthPhy.h`), translated by name when Ethernet starts. Never cast a stored id to the framework enum. +- **Ethernet only on the original ESP32.** Arduino 3.x has the RMII MAC API only where `CONFIG_ETH_USE_ESP32_EMAC` is set. S3 and C6 build without Ethernet. +- **Updates roll back until proven.** We override the core's `verifyRollbackLater()` hook to return true, and `loop()` marks the new firmware valid once it has run 60 s and the network is up. A reset before then boots the previous firmware. The LittleFS image an update wrote stays, so the old firmware runs with the new web UI. +- **Tooling.** pioarduino needs its own Core fork (`pip install pioarduino`, the pioarduino IDE extension in VS Code), which it installs into `~/.platformio/penv` in place of PlatformIO Core. diff --git a/lib/SmartRC-CC1101-Driver-Lib/ELECHOUSE_CC1101_SRC_DRV.cpp b/lib/SmartRC-CC1101-Driver-Lib/ELECHOUSE_CC1101_SRC_DRV.cpp new file mode 100644 index 0000000..c5f014d --- /dev/null +++ b/lib/SmartRC-CC1101-Driver-Lib/ELECHOUSE_CC1101_SRC_DRV.cpp @@ -0,0 +1,1326 @@ +/* + ELECHOUSE_CC1101.cpp - CC1101 module library + Copyright (c) 2010 Michael. + Author: Michael, + Version: November 12, 2010 + + This library is designed to use CC1101/CC1100 module on Arduino platform. + CC1101/CC1100 module is an useful wireless module.Using the functions of the + library, you can easily send and receive data by the CC1101/CC1100 module. + Just have fun! + For the details, please refer to the datasheet of CC1100/CC1101. +---------------------------------------------------------------------------------------------------------------- +cc1101 Driver for RC Switch. Mod by Little Satan. With permission to modify and publish Wilson Shen (ELECHOUSE). +---------------------------------------------------------------------------------------------------------------- +*/ +#include +#include "ELECHOUSE_CC1101_SRC_DRV.h" +#include +#ifdef ESP32 +#include +#endif + +// ESPSomfy-RTS: waits for the CC1101 to pull MISO low (CHIP_RDYn) before an +// SPI access. MISO belongs to the SPI bus by then, and Arduino 3.x logs a +// warning on every digitalRead() of a pin another peripheral owns, so on the +// ESP32 read the pad directly. Gives up after 10 ms so a missing or dead +// module can't hang the caller; the chip is ready within a few hundred us. +static void waitMisoLow(byte pin) +{ + uint32_t start = micros(); + #ifdef ESP32 + while(gpio_get_level((gpio_num_t)pin) && micros() - start < 10000); + #else + while(digitalRead(pin) && micros() - start < 10000); + #endif +} + +/****************************************************************/ +#define WRITE_BURST 0x40 //write burst +#define READ_SINGLE 0x80 //read single +#define READ_BURST 0xC0 //read burst +#define BYTES_IN_RXFIFO 0x7F //byte number in RXfifo +#define max_modul 6 + +byte modulation = 2; +byte frend0; +byte chan = 0; +int pa = 12; +byte last_pa; +byte SCK_PIN; +byte MISO_PIN; +byte MOSI_PIN; +byte SS_PIN; +byte GDO0; +byte GDO2; +byte SCK_PIN_M[max_modul]; +byte MISO_PIN_M[max_modul]; +byte MOSI_PIN_M[max_modul]; +byte SS_PIN_M[max_modul]; +byte GDO0_M[max_modul]; +byte GDO2_M[max_modul]; +byte gdo_set=0; +bool spi = 0; +bool ccmode = 0; +float MHz = 433.92; +byte m4RxBw = 0; +byte m4DaRa; +byte m2DCOFF; +byte m2MODFM; +byte m2MANCH; +byte m2SYNCM; +byte m1FEC; +byte m1PRE; +byte m1CHSP; +byte pc1PQT; +byte pc1CRC_AF; +byte pc1APP_ST; +byte pc1ADRCHK; +byte pc0WDATA; +byte pc0PktForm; +byte pc0CRC_EN; +byte pc0LenConf; +byte trxstate = 0; +byte clb1[2]= {24,28}; +byte clb2[2]= {31,38}; +byte clb3[2]= {65,76}; +byte clb4[2]= {77,79}; + +/****************************************************************/ +uint8_t PA_TABLE[8] {0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0x00}; +// -30 -20 -15 -10 0 5 7 10 +uint8_t PA_TABLE_315[8] {0x12,0x0D,0x1C,0x34,0x51,0x85,0xCB,0xC2,}; //300 - 348 +uint8_t PA_TABLE_433[8] {0x12,0x0E,0x1D,0x34,0x60,0x84,0xC8,0xC0,}; //387 - 464 +// -30 -20 -15 -10 -6 0 5 7 10 12 +uint8_t PA_TABLE_868[10] {0x03,0x17,0x1D,0x26,0x37,0x50,0x86,0xCD,0xC5,0xC0,}; //779 - 899.99 +// -30 -20 -15 -10 -6 0 5 7 10 11 +uint8_t PA_TABLE_915[10] {0x03,0x0E,0x1E,0x27,0x38,0x8E,0x84,0xCC,0xC3,0xC0,}; //900 - 928 +/**************************************************************** +*FUNCTION NAME:SpiStart +*FUNCTION :spi communication start +*INPUT :none +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::SpiStart(void) +{ + // initialize the SPI pins + pinMode(SCK_PIN, OUTPUT); + pinMode(MOSI_PIN, OUTPUT); + pinMode(MISO_PIN, INPUT); + pinMode(SS_PIN, OUTPUT); + + // enable SPI + #ifdef ESP32 + SPI.begin(SCK_PIN, MISO_PIN, MOSI_PIN, SS_PIN); + #else + SPI.begin(); + #endif +} +/**************************************************************** +*FUNCTION NAME:SpiEnd +*FUNCTION :spi communication disable +*INPUT :none +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::SpiEnd(void) +{ + // disable SPI + SPI.endTransaction(); + SPI.end(); +} +/**************************************************************** +*FUNCTION NAME: GDO_Set() +*FUNCTION : set GDO0,GDO2 pin for serial pinmode. +*INPUT : none +*OUTPUT : none +****************************************************************/ +void ELECHOUSE_CC1101::GDO_Set (void) +{ + pinMode(GDO0, OUTPUT); + pinMode(GDO2, INPUT); +} +/**************************************************************** +*FUNCTION NAME: GDO_Set() +*FUNCTION : set GDO0 for internal transmission mode. +*INPUT : none +*OUTPUT : none +****************************************************************/ +void ELECHOUSE_CC1101::GDO0_Set (void) +{ + pinMode(GDO0, INPUT); +} +/**************************************************************** +*FUNCTION NAME:Reset +*FUNCTION :CC1101 reset //details refer datasheet of CC1101/CC1100// +*INPUT :none +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::Reset (void) +{ + digitalWrite(SS_PIN, LOW); + delay(1); + digitalWrite(SS_PIN, HIGH); + delay(1); + digitalWrite(SS_PIN, LOW); + waitMisoLow(MISO_PIN); + SPI.transfer(CC1101_SRES); + waitMisoLow(MISO_PIN); + digitalWrite(SS_PIN, HIGH); +} +/**************************************************************** +*FUNCTION NAME:Init +*FUNCTION :CC1101 initialization +*INPUT :none +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::Init(void) +{ + setSpi(); + SpiStart(); //spi initialization + digitalWrite(SS_PIN, HIGH); + // ESPSomfy-RTS: no digitalWrite() on SCK and MOSI here. SpiStart() has + // handed them to the SPI bus, so Arduino 3.x refused the writes and logged + // an error; the bus already idles SCK and MOSI. + Reset(); //CC1101 reset + RegConfigSettings(); //CC1101 register config + SpiEnd(); +} +/**************************************************************** +*FUNCTION NAME:SpiWriteReg +*FUNCTION :CC1101 write data to register +*INPUT :addr: register address; value: register value +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::SpiWriteReg(byte addr, byte value) +{ + SpiStart(); + digitalWrite(SS_PIN, LOW); + waitMisoLow(MISO_PIN); + SPI.transfer(addr); + SPI.transfer(value); + digitalWrite(SS_PIN, HIGH); + SpiEnd(); +} +/**************************************************************** +*FUNCTION NAME:SpiWriteBurstReg +*FUNCTION :CC1101 write burst data to register +*INPUT :addr: register address; buffer:register value array; num:number to write +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::SpiWriteBurstReg(byte addr, byte *buffer, byte num) +{ + byte i, temp; + SpiStart(); + temp = addr | WRITE_BURST; + digitalWrite(SS_PIN, LOW); + waitMisoLow(MISO_PIN); + SPI.transfer(temp); + for (i = 0; i < num; i++) + { + SPI.transfer(buffer[i]); + } + digitalWrite(SS_PIN, HIGH); + SpiEnd(); +} +/**************************************************************** +*FUNCTION NAME:SpiStrobe +*FUNCTION :CC1101 Strobe +*INPUT :strobe: command; //refer define in CC1101.h// +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::SpiStrobe(byte strobe) +{ + SpiStart(); + digitalWrite(SS_PIN, LOW); + waitMisoLow(MISO_PIN); + SPI.transfer(strobe); + digitalWrite(SS_PIN, HIGH); + SpiEnd(); +} +/**************************************************************** +*FUNCTION NAME:SpiReadReg +*FUNCTION :CC1101 read data from register +*INPUT :addr: register address +*OUTPUT :register value +****************************************************************/ +byte ELECHOUSE_CC1101::SpiReadReg(byte addr) +{ + byte temp, value; + SpiStart(); + temp = addr| READ_SINGLE; + digitalWrite(SS_PIN, LOW); + waitMisoLow(MISO_PIN); + SPI.transfer(temp); + value=SPI.transfer(0); + digitalWrite(SS_PIN, HIGH); + SpiEnd(); + return value; +} + +/**************************************************************** +*FUNCTION NAME:SpiReadBurstReg +*FUNCTION :CC1101 read burst data from register +*INPUT :addr: register address; buffer:array to store register value; num: number to read +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::SpiReadBurstReg(byte addr, byte *buffer, byte num) +{ + byte i,temp; + SpiStart(); + temp = addr | READ_BURST; + digitalWrite(SS_PIN, LOW); + waitMisoLow(MISO_PIN); + SPI.transfer(temp); + for(i=0;i4){m=4;} +modulation = m; +Split_MDMCFG2(); +switch (m) +{ +case 0: m2MODFM=0x00; frend0=0x10; break; // 2-FSK +case 1: m2MODFM=0x10; frend0=0x10; break; // GFSK +case 2: m2MODFM=0x30; frend0=0x11; break; // ASK +case 3: m2MODFM=0x40; frend0=0x10; break; // 4-FSK +case 4: m2MODFM=0x70; frend0=0x10; break; // MSK +} +SpiWriteReg(CC1101_MDMCFG2, m2DCOFF+m2MODFM+m2MANCH+m2SYNCM); +SpiWriteReg(CC1101_FREND0, frend0); +setPA(pa); +} +/**************************************************************** +*FUNCTION NAME:PA Power +*FUNCTION :set CC1101 PA Power +*INPUT :none +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::setPA(int p) +{ +int a; +pa = p; + +if (MHz >= 300 && MHz <= 348){ +if (pa <= -30){a = PA_TABLE_315[0];} +else if (pa > -30 && pa <= -20){a = PA_TABLE_315[1];} +else if (pa > -20 && pa <= -15){a = PA_TABLE_315[2];} +else if (pa > -15 && pa <= -10){a = PA_TABLE_315[3];} +else if (pa > -10 && pa <= 0){a = PA_TABLE_315[4];} +else if (pa > 0 && pa <= 5){a = PA_TABLE_315[5];} +else if (pa > 5 && pa <= 7){a = PA_TABLE_315[6];} +else if (pa > 7){a = PA_TABLE_315[7];} +last_pa = 1; +} +else if (MHz >= 378 && MHz <= 464){ +if (pa <= -30){a = PA_TABLE_433[0];} +else if (pa > -30 && pa <= -20){a = PA_TABLE_433[1];} +else if (pa > -20 && pa <= -15){a = PA_TABLE_433[2];} +else if (pa > -15 && pa <= -10){a = PA_TABLE_433[3];} +else if (pa > -10 && pa <= 0){a = PA_TABLE_433[4];} +else if (pa > 0 && pa <= 5){a = PA_TABLE_433[5];} +else if (pa > 5 && pa <= 7){a = PA_TABLE_433[6];} +else if (pa > 7){a = PA_TABLE_433[7];} +last_pa = 2; +} +else if (MHz >= 779 && MHz <= 899.99){ +if (pa <= -30){a = PA_TABLE_868[0];} +else if (pa > -30 && pa <= -20){a = PA_TABLE_868[1];} +else if (pa > -20 && pa <= -15){a = PA_TABLE_868[2];} +else if (pa > -15 && pa <= -10){a = PA_TABLE_868[3];} +else if (pa > -10 && pa <= -6){a = PA_TABLE_868[4];} +else if (pa > -6 && pa <= 0){a = PA_TABLE_868[5];} +else if (pa > 0 && pa <= 5){a = PA_TABLE_868[6];} +else if (pa > 5 && pa <= 7){a = PA_TABLE_868[7];} +else if (pa > 7 && pa <= 10){a = PA_TABLE_868[8];} +else if (pa > 10){a = PA_TABLE_868[9];} +last_pa = 3; +} +else if (MHz >= 900 && MHz <= 928){ +if (pa <= -30){a = PA_TABLE_915[0];} +else if (pa > -30 && pa <= -20){a = PA_TABLE_915[1];} +else if (pa > -20 && pa <= -15){a = PA_TABLE_915[2];} +else if (pa > -15 && pa <= -10){a = PA_TABLE_915[3];} +else if (pa > -10 && pa <= -6){a = PA_TABLE_915[4];} +else if (pa > -6 && pa <= 0){a = PA_TABLE_915[5];} +else if (pa > 0 && pa <= 5){a = PA_TABLE_915[6];} +else if (pa > 5 && pa <= 7){a = PA_TABLE_915[7];} +else if (pa > 7 && pa <= 10){a = PA_TABLE_915[8];} +else if (pa > 10){a = PA_TABLE_915[9];} +last_pa = 4; +} +if (modulation == 2){ +PA_TABLE[0] = 0; +PA_TABLE[1] = a; +}else{ +PA_TABLE[0] = a; +PA_TABLE[1] = 0; +} +SpiWriteBurstReg(CC1101_PATABLE,PA_TABLE,8); +} +/**************************************************************** +*FUNCTION NAME:Frequency Calculator +*FUNCTION :Calculate the basic frequency. +*INPUT :none +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::setMHZ(float mhz){ +byte freq2 = 0; +byte freq1 = 0; +byte freq0 = 0; + +MHz = mhz; + +for (bool i = 0; i==0;){ +if (mhz >= 26){ +mhz-=26; +freq2+=1; +} +else if (mhz >= 0.1015625){ +mhz-=0.1015625; +freq1+=1; +} +else if (mhz >= 0.00039675){ +mhz-=0.00039675; +freq0+=1; +} +else{i=1;} +} +if (freq0 > 255){freq1+=1;freq0-=256;} + +SpiWriteReg(CC1101_FREQ2, freq2); +SpiWriteReg(CC1101_FREQ1, freq1); +SpiWriteReg(CC1101_FREQ0, freq0); + +Calibrate(); +} +/**************************************************************** +*FUNCTION NAME:Calibrate +*FUNCTION :Calibrate frequency +*INPUT :none +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::Calibrate(void){ + +if (MHz >= 300 && MHz <= 348){ +SpiWriteReg(CC1101_FSCTRL0, map(MHz, 300, 348, clb1[0], clb1[1])); +if (MHz < 322.88){SpiWriteReg(CC1101_TEST0,0x0B);} +else{ +SpiWriteReg(CC1101_TEST0,0x09); +int s = ELECHOUSE_cc1101.SpiReadStatus(CC1101_FSCAL2); +if (s<32){SpiWriteReg(CC1101_FSCAL2, s+32);} +if (last_pa != 1){setPA(pa);} +} +} +else if (MHz >= 378 && MHz <= 464){ +SpiWriteReg(CC1101_FSCTRL0, map(MHz, 378, 464, clb2[0], clb2[1])); +if (MHz < 430.5){SpiWriteReg(CC1101_TEST0,0x0B);} +else{ +SpiWriteReg(CC1101_TEST0,0x09); +int s = ELECHOUSE_cc1101.SpiReadStatus(CC1101_FSCAL2); +if (s<32){SpiWriteReg(CC1101_FSCAL2, s+32);} +if (last_pa != 2){setPA(pa);} +} +} +else if (MHz >= 779 && MHz <= 899.99){ +SpiWriteReg(CC1101_FSCTRL0, map(MHz, 779, 899, clb3[0], clb3[1])); +if (MHz < 861){SpiWriteReg(CC1101_TEST0,0x0B);} +else{ +SpiWriteReg(CC1101_TEST0,0x09); +int s = ELECHOUSE_cc1101.SpiReadStatus(CC1101_FSCAL2); +if (s<32){SpiWriteReg(CC1101_FSCAL2, s+32);} +if (last_pa != 3){setPA(pa);} +} +} +else if (MHz >= 900 && MHz <= 928){ +SpiWriteReg(CC1101_FSCTRL0, map(MHz, 900, 928, clb4[0], clb4[1])); +SpiWriteReg(CC1101_TEST0,0x09); +int s = ELECHOUSE_cc1101.SpiReadStatus(CC1101_FSCAL2); +if (s<32){SpiWriteReg(CC1101_FSCAL2, s+32);} +if (last_pa != 4){setPA(pa);} +} +} +/**************************************************************** +*FUNCTION NAME:Calibration offset +*FUNCTION :Set calibration offset +*INPUT :none +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::setClb(byte b, byte s, byte e){ +if (b == 1){ +clb1[0]=s; +clb1[1]=e; +} +else if (b == 2){ +clb2[0]=s; +clb2[1]=e; +} +else if (b == 3){ +clb3[0]=s; +clb3[1]=e; +} +else if (b == 4){ +clb4[0]=s; +clb4[1]=e; +} +} +/**************************************************************** +*FUNCTION NAME:getCC1101 +*FUNCTION :Test Spi connection and return 1 when true. +*INPUT :none +*OUTPUT :none +****************************************************************/ +bool ELECHOUSE_CC1101::getCC1101(void){ +setSpi(); +if (SpiReadStatus(0x31)>0){ +return 1; +}else{ +return 0; +} +} +/**************************************************************** +*FUNCTION NAME:getMode +*FUNCTION :Return the Mode. Sidle = 0, TX = 1, Rx = 2. +*INPUT :none +*OUTPUT :none +****************************************************************/ +byte ELECHOUSE_CC1101::getMode(void){ +return trxstate; +} +/**************************************************************** +*FUNCTION NAME:Set Sync_Word +*FUNCTION :Sync Word +*INPUT :none +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::setSyncWord(byte sh, byte sl){ +SpiWriteReg(CC1101_SYNC1, sh); +SpiWriteReg(CC1101_SYNC0, sl); +} +/**************************************************************** +*FUNCTION NAME:Set ADDR +*FUNCTION :Address used for packet filtration. Optional broadcast addresses are 0 (0x00) and 255 (0xFF). +*INPUT :none +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::setAddr(byte v){ +SpiWriteReg(CC1101_ADDR, v); +} +/**************************************************************** +*FUNCTION NAME:Set PQT +*FUNCTION :Preamble quality estimator threshold +*INPUT :none +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::setPQT(byte v){ +Split_PKTCTRL1(); +pc1PQT = 0; +if (v>7){v=7;} +pc1PQT = v*32; +SpiWriteReg(CC1101_PKTCTRL1, pc1PQT+pc1CRC_AF+pc1APP_ST+pc1ADRCHK); +} +/**************************************************************** +*FUNCTION NAME:Set CRC_AUTOFLUSH +*FUNCTION :Enable automatic flush of RX FIFO when CRC is not OK +*INPUT :none +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::setCRC_AF(bool v){ +Split_PKTCTRL1(); +pc1CRC_AF = 0; +if (v==1){pc1CRC_AF=8;} +SpiWriteReg(CC1101_PKTCTRL1, pc1PQT+pc1CRC_AF+pc1APP_ST+pc1ADRCHK); +} +/**************************************************************** +*FUNCTION NAME:Set APPEND_STATUS +*FUNCTION :When enabled, two status bytes will be appended to the payload of the packet +*INPUT :none +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::setAppendStatus(bool v){ +Split_PKTCTRL1(); +pc1APP_ST = 0; +if (v==1){pc1APP_ST=4;} +SpiWriteReg(CC1101_PKTCTRL1, pc1PQT+pc1CRC_AF+pc1APP_ST+pc1ADRCHK); +} +/**************************************************************** +*FUNCTION NAME:Set ADR_CHK +*FUNCTION :Controls address check configuration of received packages +*INPUT :none +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::setAdrChk(byte v){ +Split_PKTCTRL1(); +pc1ADRCHK = 0; +if (v>3){v=3;} +pc1ADRCHK = v; +SpiWriteReg(CC1101_PKTCTRL1, pc1PQT+pc1CRC_AF+pc1APP_ST+pc1ADRCHK); +} +/**************************************************************** +*FUNCTION NAME:Set WHITE_DATA +*FUNCTION :Turn data whitening on / off. +*INPUT :none +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::setWhiteData(bool v){ +Split_PKTCTRL0(); +pc0WDATA = 0; +if (v == 1){pc0WDATA=64;} +SpiWriteReg(CC1101_PKTCTRL0, pc0WDATA+pc0PktForm+pc0CRC_EN+pc0LenConf); +} +/**************************************************************** +*FUNCTION NAME:Set PKT_FORMAT +*FUNCTION :Format of RX and TX data +*INPUT :none +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::setPktFormat(byte v){ +Split_PKTCTRL0(); +pc0PktForm = 0; +if (v>3){v=3;} +pc0PktForm = v*16; +SpiWriteReg(CC1101_PKTCTRL0, pc0WDATA+pc0PktForm+pc0CRC_EN+pc0LenConf); +} +/**************************************************************** +*FUNCTION NAME:Set CRC +*FUNCTION :CRC calculation in TX and CRC check in RX +*INPUT :none +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::setCrc(bool v){ +Split_PKTCTRL0(); +pc0CRC_EN = 0; +if (v==1){pc0CRC_EN=4;} +SpiWriteReg(CC1101_PKTCTRL0, pc0WDATA+pc0PktForm+pc0CRC_EN+pc0LenConf); +} +/**************************************************************** +*FUNCTION NAME:Set LENGTH_CONFIG +*FUNCTION :Configure the packet length +*INPUT :none +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::setLengthConfig(byte v){ +Split_PKTCTRL0(); +pc0LenConf = 0; +if (v>3){v=3;} +pc0LenConf = v; +SpiWriteReg(CC1101_PKTCTRL0, pc0WDATA+pc0PktForm+pc0CRC_EN+pc0LenConf); +} +/**************************************************************** +*FUNCTION NAME:Set PACKET_LENGTH +*FUNCTION :Indicates the packet length +*INPUT :none +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::setPacketLength(byte v){ +SpiWriteReg(CC1101_PKTLEN, v); +} +/**************************************************************** +*FUNCTION NAME:Set DCFILT_OFF +*FUNCTION :Disable digital DC blocking filter before demodulator +*INPUT :none +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::setDcFilterOff(bool v){ +Split_MDMCFG2(); +m2DCOFF = 0; +if (v==1){m2DCOFF=128;} +SpiWriteReg(CC1101_MDMCFG2, m2DCOFF+m2MODFM+m2MANCH+m2SYNCM); +} +/**************************************************************** +*FUNCTION NAME:Set MANCHESTER +*FUNCTION :Enables Manchester encoding/decoding +*INPUT :none +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::setManchester(bool v){ +Split_MDMCFG2(); +m2MANCH = 0; +if (v==1){m2MANCH=8;} +SpiWriteReg(CC1101_MDMCFG2, m2DCOFF+m2MODFM+m2MANCH+m2SYNCM); +} +/**************************************************************** +*FUNCTION NAME:Set SYNC_MODE +*FUNCTION :Combined sync-word qualifier mode +*INPUT :none +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::setSyncMode(byte v){ +Split_MDMCFG2(); +m2SYNCM = 0; +if (v>7){v=7;} +m2SYNCM=v; +SpiWriteReg(CC1101_MDMCFG2, m2DCOFF+m2MODFM+m2MANCH+m2SYNCM); +} +/**************************************************************** +*FUNCTION NAME:Set FEC +*FUNCTION :Enable Forward Error Correction (FEC) +*INPUT :none +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::setFEC(bool v){ +Split_MDMCFG1(); +m1FEC=0; +if (v==1){m1FEC=128;} +SpiWriteReg(CC1101_MDMCFG1, m1FEC+m1PRE+m1CHSP); +} +/**************************************************************** +*FUNCTION NAME:Set PRE +*FUNCTION :Sets the minimum number of preamble bytes to be transmitted. +*INPUT :none +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::setPRE(byte v){ +Split_MDMCFG1(); +m1PRE=0; +if (v>7){v=7;} +m1PRE = v*16; +SpiWriteReg(CC1101_MDMCFG1, m1FEC+m1PRE+m1CHSP); +} +/**************************************************************** +*FUNCTION NAME:Set Channel +*FUNCTION :none +*INPUT :none +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::setChannel(byte ch){ +chan = ch; +SpiWriteReg(CC1101_CHANNR, chan); +} +/**************************************************************** +*FUNCTION NAME:Set Channel spacing +*FUNCTION :none +*INPUT :none +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::setChsp(float f){ +Split_MDMCFG1(); +byte MDMCFG0 = 0; +m1CHSP = 0; +if (f > 405.456543){f = 405.456543;} +if (f < 25.390625){f = 25.390625;} +for (int i = 0; i<5; i++){ +if (f <= 50.682068){ +f -= 25.390625; +f /= 0.0991825; +MDMCFG0 = f; +float s1 = (f - MDMCFG0) *10; +if (s1 >= 5){MDMCFG0++;} +i = 5; +}else{ +m1CHSP++; +f/=2; +} +} +SpiWriteReg(19,m1CHSP+m1FEC+m1PRE); +SpiWriteReg(20,MDMCFG0); +} +/**************************************************************** +*FUNCTION NAME:Set Receive bandwidth +*FUNCTION :none +*INPUT :none +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::setRxBW(float f){ +Split_MDMCFG4(); +int s1 = 3; +int s2 = 3; +for (int i = 0; i<3; i++){ +if (f > 101.5625){f/=2; s1--;} +else{i=3;} +} +for (int i = 0; i<3; i++){ +if (f > 58.1){f/=1.25; s2--;} +else{i=3;} +} +s1 *= 64; +s2 *= 16; +m4RxBw = s1 + s2; +SpiWriteReg(16,m4RxBw+m4DaRa); +} +/**************************************************************** +*FUNCTION NAME:Set Data Rate +*FUNCTION :none +*INPUT :none +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::setDRate(float d){ +Split_MDMCFG4(); +float c = d; +byte MDMCFG3 = 0; +if (c > 1621.83){c = 1621.83;} +if (c < 0.0247955){c = 0.0247955;} +m4DaRa = 0; +for (int i = 0; i<20; i++){ +if (c <= 0.0494942){ +c = c - 0.0247955; +c = c / 0.00009685; +MDMCFG3 = c; +float s1 = (c - MDMCFG3) *10; +if (s1 >= 5){MDMCFG3++;} +i = 20; +}else{ +m4DaRa++; +c = c/2; +} +} +SpiWriteReg(16, m4RxBw+m4DaRa); +SpiWriteReg(17, MDMCFG3); +} +/**************************************************************** +*FUNCTION NAME:Set Devitation +*FUNCTION :none +*INPUT :none +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::setDeviation(float d){ +float f = 1.586914; +float v = 0.19836425; +int c = 0; +if (d > 380.859375){d = 380.859375;} +if (d < 1.586914){d = 1.586914;} +for (int i = 0; i<255; i++){ +f+=v; +if (c==7){v*=2;c=-1;i+=8;} +if (f>=d){c=i;i=255;} +c++; +} +SpiWriteReg(21,c); +} +/**************************************************************** +*FUNCTION NAME:Split PKTCTRL0 +*FUNCTION :none +*INPUT :none +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::Split_PKTCTRL1(void){ +int calc = SpiReadStatus(7); +pc1PQT = 0; +pc1CRC_AF = 0; +pc1APP_ST = 0; +pc1ADRCHK = 0; +for (bool i = 0; i==0;){ +if (calc >= 32){calc-=32; pc1PQT+=32;} +else if (calc >= 8){calc-=8; pc1CRC_AF+=8;} +else if (calc >= 4){calc-=4; pc1APP_ST+=4;} +else {pc1ADRCHK = calc; i=1;} +} +} +/**************************************************************** +*FUNCTION NAME:Split PKTCTRL0 +*FUNCTION :none +*INPUT :none +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::Split_PKTCTRL0(void){ +int calc = SpiReadStatus(8); +pc0WDATA = 0; +pc0PktForm = 0; +pc0CRC_EN = 0; +pc0LenConf = 0; +for (bool i = 0; i==0;){ +if (calc >= 64){calc-=64; pc0WDATA+=64;} +else if (calc >= 16){calc-=16; pc0PktForm+=16;} +else if (calc >= 4){calc-=4; pc0CRC_EN+=4;} +else {pc0LenConf = calc; i=1;} +} +} +/**************************************************************** +*FUNCTION NAME:Split MDMCFG1 +*FUNCTION :none +*INPUT :none +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::Split_MDMCFG1(void){ +int calc = SpiReadStatus(19); +m1FEC = 0; +m1PRE = 0; +m1CHSP = 0; +int s2 = 0; +for (bool i = 0; i==0;){ +if (calc >= 128){calc-=128; m1FEC+=128;} +else if (calc >= 16){calc-=16; m1PRE+=16;} +else {m1CHSP = calc; i=1;} +} +} +/**************************************************************** +*FUNCTION NAME:Split MDMCFG2 +*FUNCTION :none +*INPUT :none +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::Split_MDMCFG2(void){ +int calc = SpiReadStatus(18); +m2DCOFF = 0; +m2MODFM = 0; +m2MANCH = 0; +m2SYNCM = 0; +for (bool i = 0; i==0;){ +if (calc >= 128){calc-=128; m2DCOFF+=128;} +else if (calc >= 16){calc-=16; m2MODFM+=16;} +else if (calc >= 8){calc-=8; m2MANCH+=8;} +else{m2SYNCM = calc; i=1;} +} +} +/**************************************************************** +*FUNCTION NAME:Split MDMCFG4 +*FUNCTION :none +*INPUT :none +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::Split_MDMCFG4(void){ +int calc = SpiReadStatus(16); +m4RxBw = 0; +m4DaRa = 0; +for (bool i = 0; i==0;){ +if (calc >= 64){calc-=64; m4RxBw+=64;} +else if (calc >= 16){calc -= 16; m4RxBw+=16;} +else{m4DaRa = calc; i=1;} +} +} +/**************************************************************** +*FUNCTION NAME:RegConfigSettings +*FUNCTION :CC1101 register config //details refer datasheet of CC1101/CC1100// +*INPUT :none +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::RegConfigSettings(void) +{ + SpiWriteReg(CC1101_FSCTRL1, 0x06); + + setCCMode(ccmode); + setMHZ(MHz); + + SpiWriteReg(CC1101_MDMCFG1, 0x02); + SpiWriteReg(CC1101_MDMCFG0, 0xF8); + SpiWriteReg(CC1101_CHANNR, chan); + SpiWriteReg(CC1101_DEVIATN, 0x47); + SpiWriteReg(CC1101_FREND1, 0x56); + SpiWriteReg(CC1101_MCSM0 , 0x18); + SpiWriteReg(CC1101_FOCCFG, 0x16); + SpiWriteReg(CC1101_BSCFG, 0x1C); + SpiWriteReg(CC1101_AGCCTRL2, 0xC7); + SpiWriteReg(CC1101_AGCCTRL1, 0x00); + SpiWriteReg(CC1101_AGCCTRL0, 0xB2); + SpiWriteReg(CC1101_FSCAL3, 0xE9); + SpiWriteReg(CC1101_FSCAL2, 0x2A); + SpiWriteReg(CC1101_FSCAL1, 0x00); + SpiWriteReg(CC1101_FSCAL0, 0x1F); + SpiWriteReg(CC1101_FSTEST, 0x59); + SpiWriteReg(CC1101_TEST2, 0x81); + SpiWriteReg(CC1101_TEST1, 0x35); + SpiWriteReg(CC1101_TEST0, 0x09); + SpiWriteReg(CC1101_PKTCTRL1, 0x04); + SpiWriteReg(CC1101_ADDR, 0x00); + SpiWriteReg(CC1101_PKTLEN, 0x00); +} +/**************************************************************** +*FUNCTION NAME:SetTx +*FUNCTION :set CC1101 send data +*INPUT :none +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::SetTx(void) +{ + SpiStrobe(CC1101_SIDLE); + SpiStrobe(CC1101_STX); //start send + trxstate=1; +} +/**************************************************************** +*FUNCTION NAME:SetRx +*FUNCTION :set CC1101 to receive state +*INPUT :none +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::SetRx(void) +{ + SpiStrobe(CC1101_SIDLE); + SpiStrobe(CC1101_SRX); //start receive + trxstate=2; +} +/**************************************************************** +*FUNCTION NAME:SetTx +*FUNCTION :set CC1101 send data and change frequency +*INPUT :none +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::SetTx(float mhz) +{ + SpiStrobe(CC1101_SIDLE); + setMHZ(mhz); + SpiStrobe(CC1101_STX); //start send + trxstate=1; +} +/**************************************************************** +*FUNCTION NAME:SetRx +*FUNCTION :set CC1101 to receive state and change frequency +*INPUT :none +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::SetRx(float mhz) +{ + SpiStrobe(CC1101_SIDLE); + setMHZ(mhz); + SpiStrobe(CC1101_SRX); //start receive + trxstate=2; +} +/**************************************************************** +*FUNCTION NAME:RSSI Level +*FUNCTION :Calculating the RSSI Level +*INPUT :none +*OUTPUT :none +****************************************************************/ +int ELECHOUSE_CC1101::getRssi(void) +{ +int rssi; +rssi=SpiReadStatus(CC1101_RSSI); +if (rssi >= 128){rssi = (rssi-256)/2-74;} +else{rssi = (rssi/2)-74;} +return rssi; +} +/**************************************************************** +*FUNCTION NAME:LQI Level +*FUNCTION :get Lqi state +*INPUT :none +*OUTPUT :none +****************************************************************/ +byte ELECHOUSE_CC1101::getLqi(void) +{ +byte lqi; +lqi=SpiReadStatus(CC1101_LQI); +return lqi; +} +/**************************************************************** +*FUNCTION NAME:SetSres +*FUNCTION :Reset CC1101 +*INPUT :none +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::setSres(void) +{ + SpiStrobe(CC1101_SRES); + trxstate=0; +} +/**************************************************************** +*FUNCTION NAME:setSidle +*FUNCTION :set Rx / TX Off +*INPUT :none +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::setSidle(void) +{ + SpiStrobe(CC1101_SIDLE); + trxstate=0; +} +/**************************************************************** +*FUNCTION NAME:goSleep +*FUNCTION :set cc1101 Sleep on +*INPUT :none +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::goSleep(void){ + trxstate=0; + SpiStrobe(0x36);//Exit RX / TX, turn off frequency synthesizer and exit + SpiStrobe(0x39);//Enter power down mode when CSn goes high. +} +/**************************************************************** +*FUNCTION NAME:Char direct SendData +*FUNCTION :use CC1101 send data +*INPUT :txBuffer: data array to send; size: number of data to send, no more than 61 +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::SendData(char *txchar) +{ +int len = strlen(txchar); +byte chartobyte[len]; +for (int i = 0; i sync transmitted + while (digitalRead(GDO0)); // Wait for GDO0 to be cleared -> end of packet + SpiStrobe(CC1101_SFTX); //flush TXfifo + trxstate=1; +} +/**************************************************************** +*FUNCTION NAME:Char direct SendData +*FUNCTION :use CC1101 send data without GDO +*INPUT :txBuffer: data array to send; size: number of data to send, no more than 61 +*OUTPUT :none +****************************************************************/ +void ELECHOUSE_CC1101::SendData(char *txchar,int t) +{ +int len = strlen(txchar); +byte chartobyte[len]; +for (int i = 0; i + Version: November 12, 2010 + + This library is designed to use CC1101/CC1100 module on Arduino platform. + CC1101/CC1100 module is an useful wireless module.Using the functions of the + library, you can easily send and receive data by the CC1101/CC1100 module. + Just have fun! + For the details, please refer to the datasheet of CC1100/CC1101. +---------------------------------------------------------------------------------------------------------------- +cc1101 Driver for RC Switch. Mod by Little Satan. With permission to modify and publish Wilson Shen (ELECHOUSE). +---------------------------------------------------------------------------------------------------------------- +*/ +#ifndef ELECHOUSE_CC1101_SRC_DRV_h +#define ELECHOUSE_CC1101_SRC_DRV_h + +#include + +//***************************************CC1101 define**************************************************// +// CC1101 CONFIG REGSITER +#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 INT8U +#define CC1101_SYNC0 0x05 // Sync word, low INT8U +#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 INT8U +#define CC1101_FREQ1 0x0E // Frequency control word, middle INT8U +#define CC1101_FREQ0 0x0F // Frequency control word, low INT8U +#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_AGCCTRL2 0x1B // AGC control +#define CC1101_AGCCTRL1 0x1C // AGC control +#define CC1101_AGCCTRL0 0x1D // AGC control +#define CC1101_WOREVT1 0x1E // High INT8U Event 0 timeout +#define CC1101_WOREVT0 0x1F // Low INT8U 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 + +//CC1101 Strobe commands +#define CC1101_SRES 0x30 // Reset chip. +#define CC1101_SFSTXON 0x31 // Enable and calibrate frequency synthesizer (if MCSM0.FS_AUTOCAL=1). + // If in RX/TX: Go to a wait state where only the synthesizer is + // running (for quick RX / TX turnaround). +#define CC1101_SXOFF 0x32 // Turn off crystal oscillator. +#define CC1101_SCAL 0x33 // Calibrate frequency synthesizer and turn it off + // (enables quick start). +#define CC1101_SRX 0x34 // Enable RX. Perform calibration first if coming from IDLE and + // MCSM0.FS_AUTOCAL=1. +#define CC1101_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_SIDLE 0x36 // Exit RX / TX, turn off frequency synthesizer and exit + // Wake-On-Radio mode if applicable. +#define CC1101_SAFC 0x37 // Perform AFC adjustment of the frequency synthesizer +#define CC1101_SWOR 0x38 // Start automatic RX polling sequence (Wake-on-Radio) +#define CC1101_SPWD 0x39 // Enter power down mode when CSn goes high. +#define CC1101_SFRX 0x3A // Flush the RX FIFO buffer. +#define CC1101_SFTX 0x3B // Flush the TX FIFO buffer. +#define CC1101_SWORRST 0x3C // Reset real time clock. +#define CC1101_SNOP 0x3D // No operation. May be used to pad strobe commands to two + // INT8Us for simpler software. +//CC1101 STATUS REGSITER +#define CC1101_PARTNUM 0x30 +#define CC1101_VERSION 0x31 +#define CC1101_FREQEST 0x32 +#define CC1101_LQI 0x33 +#define CC1101_RSSI 0x34 +#define CC1101_MARCSTATE 0x35 +#define CC1101_WORTIME1 0x36 +#define CC1101_WORTIME0 0x37 +#define CC1101_PKTSTATUS 0x38 +#define CC1101_VCO_VC_DAC 0x39 +#define CC1101_TXBYTES 0x3A +#define CC1101_RXBYTES 0x3B + +//CC1101 PATABLE,TXFIFO,RXFIFO +#define CC1101_PATABLE 0x3E +#define CC1101_TXFIFO 0x3F +#define CC1101_RXFIFO 0x3F + +//************************************* class **************************************************// +class ELECHOUSE_CC1101 +{ +private: + void SpiStart(void); + void SpiEnd(void); + void GDO_Set (void); + void GDO0_Set (void); + void Reset (void); + void setSpi(void); + void RegConfigSettings(void); + void Calibrate(void); + void Split_PKTCTRL0(void); + void Split_PKTCTRL1(void); + void Split_MDMCFG1(void); + void Split_MDMCFG2(void); + void Split_MDMCFG4(void); +public: + void Init(void); + byte SpiReadStatus(byte addr); + void setSpiPin(byte sck, byte miso, byte mosi, byte ss); + void addSpiPin(byte sck, byte miso, byte mosi, byte ss, byte modul); + void setGDO(byte gdo0, byte gdo2); + void setGDO0(byte gdo0); + void addGDO(byte gdo0, byte gdo2, byte modul); + void addGDO0(byte gdo0, byte modul); + void setModul(byte modul); + void setCCMode(bool s); + void setModulation(byte m); + void setPA(int p); + void setMHZ(float mhz); + void setChannel(byte chnl); + void setChsp(float f); + void setRxBW(float f); + void setDRate(float d); + void setDeviation(float d); + void SetTx(void); + void SetRx(void); + void SetTx(float mhz); + void SetRx(float mhz); + int getRssi(void); + byte getLqi(void); + void setSres(void); + void setSidle(void); + void goSleep(void); + void SendData(byte *txBuffer, byte size); + void SendData(char *txchar); + void SendData(byte *txBuffer, byte size, int t); + void SendData(char *txchar, int t); + byte CheckReceiveFlag(void); + byte ReceiveData(byte *rxBuffer); + bool CheckCRC(void); + void SpiStrobe(byte strobe); + void SpiWriteReg(byte addr, byte value); + void SpiWriteBurstReg(byte addr, byte *buffer, byte num); + byte SpiReadReg(byte addr); + void SpiReadBurstReg(byte addr, byte *buffer, byte num); + void setClb(byte b, byte s, byte e); + bool getCC1101(void); + byte getMode(void); + void setSyncWord(byte sh, byte sl); + void setAddr(byte v); + void setWhiteData(bool v); + void setPktFormat(byte v); + void setCrc(bool v); + void setLengthConfig(byte v); + void setPacketLength(byte v); + void setDcFilterOff(bool v); + void setManchester(bool v); + void setSyncMode(byte v); + void setFEC(bool v); + void setPRE(byte v); + void setPQT(byte v); + void setCRC_AF(bool v); + void setAppendStatus(bool v); + void setAdrChk(byte v); + bool CheckRxFifo(int t); +}; + +extern ELECHOUSE_CC1101 ELECHOUSE_cc1101; + +#endif diff --git a/lib/SmartRC-CC1101-Driver-Lib/LICENSE.txt b/lib/SmartRC-CC1101-Driver-Lib/LICENSE.txt new file mode 100644 index 0000000..8b4631b --- /dev/null +++ b/lib/SmartRC-CC1101-Driver-Lib/LICENSE.txt @@ -0,0 +1,22 @@ +---------------------------------------------------------------------------------------------------------------- +cc1101 Driver for RC Switch. Mod by Little Satan. With permission to modify and publish Wilson Shen (ELECHOUSE). +---------------------------------------------------------------------------------------------------------------- + + + ELECHOUSE_CC1101.cpp - CC1101 module library + Copyright (c) 2010 Michael. + Author: Michael, + Version: November 12, 2010 + + This library is designed to use CC1101/CC1100 module on Arduino platform. + CC1101/CC1100 module is an useful wireless module.Using the functions of the + library, you can easily send and receive data by the CC1101/CC1100 module. + Just have fun! + For the details, please refer to the datasheet of CC1100/CC1101. + +notes: The whole stuff that is not directly related to Rc_Switch, + NewRemoteSwitch or Elechouse_cc1101 Lib is Copyright (c) 2018 - 2020 by Little Satan. + Example calculator codes in the driver lib. + And so on... + You can freely use, edit or distribute it with reference to the source. + For everything else, the rights of the respective owners apply! \ No newline at end of file diff --git a/lib/SmartRC-CC1101-Driver-Lib/README.md b/lib/SmartRC-CC1101-Driver-Lib/README.md new file mode 100644 index 0000000..0e90dff --- /dev/null +++ b/lib/SmartRC-CC1101-Driver-Lib/README.md @@ -0,0 +1,641 @@ +# SmartRC-CC1101-Driver-Lib_V2.5.7 + +![GitHub (Pre-)Release Date](https://img.shields.io/github/release-date-pre/LSatan/SmartRC-CC1101-Driver-Lib) + +Note: Find out about the laws in your country. +Use at your own risk. + +Attention! in version 2.5.7 there are changes for the internal transfer functions regarding the gdo pin assignment! + +--------------------------------------------- +Announcements / other +--------------------------------------------- + +attention: currently i can only answer questions very belatedly. +try to scour existing problems for a solution if possible. +Problems that have not yet been closed are mostly already solved! +thanks for your understanding + +For debug and advanced functions: https://github.com/LSatan/CC1101-Debug-Service-Tool + +new library Simu_Remote: https://github.com/LSatan/Simu_Remote_CC1101 + +--------------------------------------------- +Install: +--------------------------------------------- + +Can be downloaded directly from the Arduino library manager. Just search for cc1101. + +--------------------------------------------- +Foreword: +--------------------------------------------- +First of all, thanks to Elechouse that I can make the modified library accessible to everyone. + +Link: http://www.elechouse.com/elechouse/ + + + +The library has been redesigned and some improvements have been made. + +Among other things, you can now also use the internal send / receive function. + +I would be happy to receive your suggestions for further examples from other libraries. + +All examples included are listed in the next field. + +--------------------------------------------- +Containing examples: +--------------------------------------------- +1.Elechouse CC1101: +- +Description: CC1101 Internal send / receive examples. Supported modulations 2-FSK, GFSK, ASK/OOK, 4-FSK, MSK. + +2.Rc-Switch: +- +

Description: Arduino lib to operate 433/315Mhz devices like power outlet sockets.

+

Link: https://github.com/sui77/rc-switch

+ +3.NewRemoteswitch: +- +

Description: This library provides an easy class for Arduino, to send and receive signals used by some common "new style" 433MHz remote control switches.

+

Link: https://github.com/1technophile/NewRemoteSwitch

+ +4.RemoteSensor library: +- +

Description: This library provides an easy class for Arduino, to send and receive signals used by some common weather stations using -remote 433MHz sensors.

+

Link: https://github.com/mattwire/arduino-dev/tree/master/libraries/RemoteSensor

+ +5.ESPiLight: +- +

Description:This Arduino library is a port of the pilight 433.92MHz protocols to the Arduino platform. It was tested with a ESP8266. The aim is to transmit, receive and parse many 433.92MHz protocols, by providing a simple Arduino friendly API. This should help to implement IoT bridges between the 434MHz-RF band and internet protocols.

+

Link:https://github.com/puuu/ESPiLight

+ +--------------------------------------------- +Instructions / Description: +--------------------------------------------- +This driver library can be used for many libraries that use a simple RF ASK module, +with the advantages of the cc1101 module.It offers many direct setting options as in +SmartRF Studio and calculates settings such as MHz directly. + +The most important functions at a glance: + +ELECHOUSE_cc1101.Init(); //Initialize the cc1101. Must be set first! + +ELECHOUSE_cc1101.setPA(PA); //Set transmission power. + +ELECHOUSE_cc1101.setMHZ(MHZ); //Set the basic frequency. + +ELECHOUSE_cc1101.SetTx(); //Set transmit on. + +ELECHOUSE_cc1101.SetTx(MHZ); //Sets transmit on and changes the frequency. + +ELECHOUSE_cc1101.SetRX(); //Set receive on. + +ELECHOUSE_cc1101.SetRx(MHZ); //Sets receive on and changes the frequency. + +ELECHOUSE_cc1101.setRxBW(RXBW); //Set Receive filter bandwidth + +ELECHOUSE_cc1101.setGDO(GDO0, GDO2); //Set Gdo0 (tx) and Gdo2 (rx) for serial transmission function. + + +ELECHOUSE_cc1101.setSpiPin(SCK, MISO, MOSI, CSN); //custom SPI pins. Set your own Spi Pins.Or to switch between multiple cc1101. Must be set before init and before changing the cc1101. + +ELECHOUSE_cc1101.setChannel(chnl); //Set Channel from 0 to 255. default = 0(basic frequency). + +ELECHOUSE_cc1101.setClb(fband, cal1, cal2); //Optionally enter Offset Callibration. Requirements: Sketch Calibrate_frequency.ino below [CC1101-Debug-Service-Tool](https://github.com/LSatan/CC1101-Debug-Service-Tool/tree/master/Calibrate_frequency).A SDR receiver and SDR software. + +New in V2.5.7 + +ELECHOUSE_cc1101.setGDO0(GDO0); //Sets Gdo0 for internal transfer function. + +ELECHOUSE_cc1101.addGDO0(GDO0, Modul); //Adds Gdo0 for internal transfer function (multiple cc1101). + +ELECHOUSE_cc1101.addGDO(GDO0, GDO2, Modul); //Adds Gdo0 (tx) and Gdo2 (rx) for serial transmission function (multiple cc1101). + +ELECHOUSE_cc1101.addSpiPin(SCK, MISO, MOSI, CSN, Modul); //Adds Spi Pins for multiple cc1101. + +ELECHOUSE_cc1101.setModul(Modul); //Switches between modules. from 0 to 5. So a maximum of 6. + + +The new features are not final and can be changed at any time. + +All can also be used in a loop and are applied directly. + +--------------------------------------------- +Wiring: +--------------------------------------------- + +Notes: A logic level converter is recommended for arduino. It also works well without. Use at your own risk. + + + + + + + + + + + + + +--------------------------------------------- +Donation +--------------------------------------------- + +If you like the library, I would be happy about a star. + +you can support me with a donation. + +https://www.paypal.me/LittleSatan666 + +Thank You! + +--------------------------------------------- +Changelog: SmartRC-CC1101-Driver-Lib_V2.5.7 +--------------------------------------------- +13.07.2021 + +Driver Library :Fixed a bug when initalizing multiple cc1101 + +Driver Library :new commandos for easy handling of multiple cc1101 + +--------------------------------------------- +Changelog: SmartRC-CC1101-Driver-Lib_V2.5.6 +--------------------------------------------- +06.04.2021 + +Driver Library :Add NUM_PREAMBLE. Sets the minimum number of preamble bytes to be transmitted. + +--------------------------------------------- +Changelog: SmartRC-CC1101-Driver-Lib_V2.5.5 +--------------------------------------------- +23.01.2021 + +Driver Library :Error correction for CheckRxFifo and CheckReceiveFlag (reception internal CC1101 function). + +--------------------------------------------- +Changelog: SmartRC-CC1101-Driver-Lib_V2.5.4 +--------------------------------------------- +23.01.2021 + +Driver Library :No big frequency jumps over SetRx(freq); Possible. Fixed! Big thanks to NorthernMan54 for testing! + +Driver Library :double-initaliesing option from V2.5.3 has been removed. Necessary for SetRx(freq); to use. + +--------------------------------------------- +Changelog: SmartRC-CC1101-Driver-Lib_V2.5.3 +--------------------------------------------- +22.01.2021 + +Driver Library :Putting rx tx has no effect if they are already in mode. Prevents unnecessary double-initaliesing. + +Driver Library :new command added: ELECHOUSE_cc1101.goSleep(); //Enter power down mode. For wakeup set RX or TX. + +Driver Library :new command added: ELECHOUSE_cc1101.getMode(); //Return the Mode. Sidle = 0, TX = 1, Rx = 2. + +Driver Library :new command added: ELECHOUSE_cc1101.setSidle(); //Set Rx / Tx Off. + +Driver Library :new command added: ELECHOUSE_cc1101.getCC1101(); //Test Spi connection and return 1 when true. + +Examples :RcSwitch Repeater_cc1101.ino has been shortened. + +--------------------------------------------- +Changelog: SmartRC-CC1101-Driver-Lib_V2.5.2 +--------------------------------------------- +01.10.2020 + +Driver Library :SpiWriteReg, SpiReadReg, SpiWriteBurstReg and SpiReadBurstReg change to public. Allows additional modifications from sketch. + +Driver Library :Setrx no longer has to be set to receive.(internal transmission methods) + +Driver Library :Gdo pins are now set to input / output with set gdo instead of Init. + +Driver Library :Added new sending method. Allows sending without a gdo0 pin. + +notes :The new internal send and receive methods now work completely without an additional gdo pin. + +--------------------------------------------- +Changelog: SmartRC-CC1101-Driver-Lib_V2.5.1 +--------------------------------------------- +18.08.2020 + +Driver Library :When changing from receiving to sending, the program freezes (internal send functions). fixed! + +--------------------------------------------- +Changelog: SmartRC-CC1101-Driver-Lib_V2.5.0 +--------------------------------------------- +16.08.2020 + +Driver Library :Rssi was calculated incorrectly.Fixed Thanks to zapquiyou! + +Driver Library :New receiving method for internal examples added. Allows several actions to be carried out in the loop. + +Driver Library :Internal Crc check added for internal examples. + +Driver Library :Simplification to send char added for internal transfer examples. + +Driver Library :A lot of new settings added for internal transmission examples. Everything can be set as in SmartRF Studio and is calculated automatically. An overview: setDeviation, setChsp, setRxBW, setDRate, setSyncMode, setSyncWord, setAdrChk, setAddr, setWhiteData, setPktFormat, setLengthConfig, setPacketLength, setCrc, setCRC_AF, setDcFilterOff, setManchester, setFEC, setPQT, setAppendStatus. description in the examples! + +--------------------------------------------- +Changelog: SmartRC-CC1101-Driver-Lib_V2.4.0 +--------------------------------------------- +07.05.2020 + +Driver Library :frequency calculator has been simplified. error-free calculations and less variables. + +Driver Library :Added frequency calibration option. + +Driver Library :Certain frequencies could not be set. Fixed! Big thanks to gusgorman402! + +--------------------------------------------- +Changelog: SmartRC-CC1101-Driver-Lib_V2.3.5 +--------------------------------------------- +14.04.2020 + +Driver Library :setChsp has been removed to save space. This function is available in the Service / Debug Tool as an extended function. + +--------------------------------------------- +Changelog: SmartRC-CC1101-Driver-Lib_V2.3.4 +--------------------------------------------- +01.04.2020 + +Driver Library :set AGCCTRL2 from 0x07 to 0xC7. Reception is significantly improved! + +--------------------------------------------- +Changelog: SmartRC-CC1101-Driver-Lib_V2.3.3 +--------------------------------------------- +01.04.2020 + +Driver Library :set FSCTRL1 from 0x08 to 0x06. for better receive. + +Driver Library :set SpiWriteReg to public. Make it fit for debug tool! + +Driver Library :set SpiStrobe to public. Make it fit for debug tool! + +--------------------------------------------- +Changelog: SmartRC-CC1101-Driver-Lib_V2.3.2 +--------------------------------------------- +24.03.2020 + +Driver Library :Set gdo2 from input to output. Errors in libraries that use the pins directly. + +examples :Set gdo2 from setting 2 to 0 in default examples. Gdo2 is not required for these examples. + +--------------------------------------------- +Changelog: SmartRC-CC1101-Driver-Lib_V2.3.1 +--------------------------------------------- +18.03.2020 + +Driver Library :ESP8266/32 core panik. Fixed! The cc1101 must be initialized before setting options! + +examples :all examples have been adapted. + +examples :internal cc1101 examples have been adapted for esp8266/32. + +examples :ESPiLight examples added. + +--------------------------------------------- +Changelog: SmartRC-CC1101-Driver-Lib_V2.3 +--------------------------------------------- +18.03.2020 + +Driver Library :"RcSwitch-cc1101-driver-lib" becomes "SmartRC-cc1101-driver-lib". + +Pull request :#20 Removed unnecessary initializations when setting Tx or Rx mode. Agreed / accepted improves speed when changing rx / tx. Special thanks to fleibede. + +Pull request :#19 Added spi state after SPI pins have been set for default pins. The problem was solved differently. Special thanks to fleibede. + +Pull request :#18 Updated AVR types conditional defines. Agreed / accepted. Special thanks to fleibede. + +Driver Library :Frequency calculator certain frequencies were calculated incorrectly. fixed! + +Driver Library :Intelligent Pa Table system added. When changing the band The corresponding table is set via setTx / Rx and the frequency set to basic calibrated. All module internal transmission powers can now be set according to the band. + +Driver Library :Newly calibrated base frequency on chan 0 according to the SmartRF Studio. + +Driver Library :Channel spacing calculator can enter directly the spacing area in khz. + +Driver Library :Modulation setting added for internal transmission methods + +Driver Library :ESP32 reception improvements. + +Driver Library :Direct conversion of the RSSI level in the library. + +Driver Library :Correction of version numbering. + +examples :New examples added "RemoteSensor library". + +examples :New examples added "Elechouse CC1101 default examples" + +examples :Remote Fusion has been removed and given an extra library. + +--------------------------------------------- +Changelog: RCSwitch-CC1101-Driver-Lib_V2.2.1 +--------------------------------------------- +[Download Release V2.2.1](https://drive.google.com/file/d/1YHFpp2GQC96-GKcg67Tym9wt1E4CBdFc/view?usp=sharing) + +20.01.2019 + +Driver Library :Spi options have been removed. (Problems with ESP32) FIXED! + +notes :everything was checked again. D-SUN module on esp8266 / 32 and so on. + +--------------------------------------------- +Changelog: RCSwitch-CC1101-Driver-Lib_V2.2 +--------------------------------------------- +17.01.2019 + +Version notes :Spi was reconfigured for fix some issuses. + +Driver Library :HotFix for cc1101 module with "8pins"(example DSun). Transmitting on Esp8266 based bords not work. FIXED! + +Driver Library :Change "SpiReadStatus" to public. Now can read RSSI Level! + +Driver Library :Spi transfer rate was limited to cc1101 max transfer rate (10mhz). + +Driver Library :After using Spi, it will now be disabled. (receive data from serial monitor and rx pin was not working on Esp 8266/32) FIXED! + +Add Examples :ReceiveDemo_Simple_with_RSSI_cc1101.ino (Shows reception strength) + +Add Examples :Frequency_Scanner_cc1101.ino (Scans Transmitting frequency of your remotes. No good results with cc1101-DSun) + +Add Examples :ProtocolAnalyzeDemo_cc1101.ino (for scan unknown protokolls. Requires: link is in sketch!) + +--------------------------------------------- +Changelog: RCSwitch-CC1101-Driver-Lib_V2.1 +--------------------------------------------- +3.1.2019 + +Driver Library :Spi corrections for esp32. Spi Pin changes did not work on esp32. FIXED! + +--------------------------------------------- +Changelog: RCSwitch-CC1101-Driver-Lib_V2.0 +--------------------------------------------- +18.12.2018 + +Driver Library :Own Spi pin settings possible. Allows the use of other microcontrollers. Allows you to use multiple CC1101s. More information in the commands.txt + +Add TXT :driver lib commands and examples.txt + +--------------------------------------------- +Changelog: RCSwitch-CC1101-Driver-Lib_V1.9.3 +--------------------------------------------- +27.11.2018 + +Driver Library :setESP8266 has been removed. Pins are set automatically with the init command. + +Driver Library :Arduino mega SPI pins added. + +Driver Library :Added setGDO pins (For libraries that directly address the GDO pins).Like this https://github.com/EinfachArne/Somfy_Remote . + Example ELECHOUSE_CC1101.setGDO(2, 4); // (pin2 = GDO0, pin4 = GDO2). + +Add Wiring TXT :WIRING MEGA.txt + +Add Wiring JPG :WIRING MEGA.jpg + +LICENSE :LICENSE.txt Update. + +notes :setGDO is not compatible with RC_Switch / NewRemotSwitch. + +--------------------------------------------- +Changelog: RCSwitch-CC1101-Driver-Lib_V1.9.2 +--------------------------------------------- +16.11.2018 + +Fixes Remotes Fusion :Receive mode and Repeater mode frequency, changes to the transmitter frequency after pressing on a transmitter. (RemotesFusion.ino)Fixed! + +NewRemoteSwitch :LearnCode_cc1101.ino (corrections). + +Added :Keywords.txt added. + +--------------------------------------------- +Changelog: RCSwitch-CC1101-Driver-Lib_V1.9.1 +--------------------------------------------- +07.11.2018 + +New Sketch :Clear_EEPROM.ino (if there are problems with the access point password or if you want to use your ESP for other projects). + +--------------------------------------------- +Changelog: RCSwitch-CC1101-Driver-Lib_V1.9 +--------------------------------------------- +18.10.2018 + +New Sketch :RemotesFusion.ino. + +New Apk´s :RemotesFusion_V1_en.apk / RemotesFusion_V1_de.apk. + +Add Docs :Docs and manuals for RemotesFusion. + +Changes :channel spacing and channel set was removed from the examples. unnecessary because exact frequency can be set. + +notes :RemotesFusion is an application with which Rc-Switch and NewRemoteSwitch can be controlled at the same time. + A universal remote control APP with many possibilities. Only for Esp 8266/32 modules! For more information, watch the docs. + +--------------------------------------------- +Changelog: RCSwitch-CC1101-Driver-Lib_V1.8 +--------------------------------------------- +[Download Release V1.8](https://drive.google.com/file/d/1ADKOmW0SrUoomeoDskFrm0J2SdwCLB_O/view?usp=sharing) + +02.09.2018 + +Driver Library :Added pin settings for esp32. + +Examples :Added pin settings for esp32 examples. + +Add Wiring JPG :Add Wiring JPG esp32. + +Add Wiring TXT :Add Wiring TXT esp32. + +Add Wiring JPG :Add Wiring JPG esp32 for Receive_Send_Decimal_Demo_Simple.ino. + +--------------------------------------------- +Changelog: RCSwitch-CC1101-Driver-Lib_V1.7.2 +--------------------------------------------- +[Download Release V1.7.2](https://drive.google.com/file/d/1sfMvQw2JaGARTaYXZevOjB20BFOMS0tw/view?usp=sharing) + +16.08.2018 + +Examples :All NewRemoteSwitch examples are compatible with ESP. Exception Retransmitter_cc1101.ino. + +Driver Library :Frequency calculator calibrated. Difference -0.01 MHz. (Fixed!) Frequency is now accurate. + +--------------------------------------------- +Changelog: RCSwitch-CC1101-Driver-Lib_V1.7.1 +--------------------------------------------- +[Download Release V1.7.1](https://drive.google.com/file/d/1PXa1k0AIDY8bTMxFyyQMbOljijhIn1ke/view?usp=sharing) + +10.08.2018 + +Driver Library :Now you can Switch the frequency in loop. Examples: ELECHOUSE_cc1101.SetTx(433.92); and ELECHOUSE_cc1101.SetRx(433.92);. + +--------------------------------------------- +Changelog: RCSwitch-CC1101-Driver-Lib_V1.7 +--------------------------------------------- +[Download Release V1.7](https://drive.google.com/file/d/1uxACfe1ZUrkL4S3_NPVN0DmUfzbxt6oQ/view?usp=sharing) + +09.08.2018 + +Driver Library :Now you can enter your base frequency directly.The library calculates the settings automatically. example(433.92) + +Driver Library :Remove freq2, freq1 and freq0 Settings. + +Driver Library :Removed unnecessary entries. the library shrank from 32,8kb(.cpp) and 9,38kb(.h) to 17,0kb(.cpp) and 7,87kb(.h). + +New Example :(NewRemoteSwitch Library) NewRemoteRepeater.ino. Repeat the Received signal 1to1. Best thanks to Roman for write it. + +--------------------------------------------- +Changelog: RCSwitch-CC1101-Driver-Lib_V1.6.1 +--------------------------------------------- +[Download Release V1.6.1](https://drive.google.com/file/d/1q8FV5kDnhAj1SMZf6DS0wDcm5xo4E-5-/view?usp=sharing) + +05.08.2018 + +Examples Fix (rc-switch):Fix auto receive pulse. Received pulse don´t transmit. Fixed!(Repeater.ino and Receive_Send_Decimal_Demo_Simple.ino). + +--------------------------------------------- +Changelog: RCSwitch-CC1101-Driver-Lib_V1.6 +--------------------------------------------- +[Download Release V1.6](https://drive.google.com/file/d/1p_iAxh7ZWlNWhFoqMM_tlLTLdyGK07-a/view?usp=sharing) + +03.08.2018 + +Esp8266 :Compatibility for all RC switch examples. + +Driver Library :Add the GDO2 pin for Receive. Change GDO0 to send. + +Wiring changes :Description in jpg's and txt's. + +Examples :All examples have been adjusted. + +Examples :Esp and Arduino are set automatically. + +--------------------------------------------- +Changelog: RCSwitch-CC1101-Driver-Lib_V1.5 +--------------------------------------------- +[Download Release V1.5](https://drive.google.com/file/d/1XcGPbvI5v2PcpnVBbjtOFwtuJtx3jMK4/view?usp=sharing) + +31.07.2018 + +New :Supportet NewRemoteSwitch Library. For wireless sockets by trust smart home, Smappee, DI-O Chacon, Intertechno and others. + You want to use it? Then you need that https://github.com/1technophile/NewRemoteSwitch + +Add Examples :NewRemoteSwitch Compatible examples. + +Driver Library :You can now switch directly from Tx to Rx in the loop. Without resetting the cc1101. + +Add Examples :New Repeater Example for Rc-switch. For example, to increase the range of your remote control. + +Example changes :Receive_Send_Decimal_Demo_Simple.ino (remove unnecessary commands). + +Examples Fix :Rc-Switch examples fix TypeA, TypeB and TypeD (missing from semicolon to SetTx). + +Notes :NewRemoteSwitch examples Retransmitter_cc1101.ino and LightShow_cc1101.ino only Arduino!!! + +Notes :Rc-switch example Repeater_cc1101.ino only Arduino!!! + +Notes :Rc-switch example Receive_Send_Decimal_Demo_Simple.ino only Arduino!!! + +--------------------------------------------- +Changelog: RCSwitch-CC1101-Driver-Lib_V1.4 +--------------------------------------------- +[Download Release V1.4](https://drive.google.com/file/d/1nAPGeQSutfskirJsng44adB4sXU1YU6A/view?usp=sharing) + +26.07.2018 + +Driver Library :esp8266 Compatibility (Tested with Wemos d1 mini). + +Driver Library :Change default Receive filter bandwidth to 812khz (max). + +Driver Library :Change default Tx Power to PA10 (max). + +Examples :Add set esp command and pin settings. + +Examples :Diskription change. + +Demo Example :Add auto Recive and Send pulse length. (Receive_Send_Decimal_Demo_Simple.ino) + +Add Wiring JPG :Add Wiring JPG esp8266. + +Add Wiring TXT :Add Wiring TXT esp8266. + +Notes :esp8266 pin D4 don´t work with receive, Transmit and receive is set to D2. + +Notes :esp8266 don´t work with Receive_Send_Decimal_Demo_Simple.ino (freezes when reset cc1101). + +--------------------------------------------- +Changelog: RCSwitch-CC1101-Driver-Lib_V1.3.1 +--------------------------------------------- +[Download Release V1.3.1](https://drive.google.com/file/d/1iKmagldd14O1Boa9Z_PDpXbHRECYUPdt/view?usp=sharing) + +30.03.2018: + +Driver Library Fix :no effect set by transmission power. + +Driver Library :Transmitting power can be adjusted via frequency(example in the sketches). + +Examples :Command Tx Power cleared. + +Examples Fix :set Receive filter bandwidth (command incomplete) Fixed. + +--------------------------------------------- +Changelog: RCSwitch-CC1101-Driver-Lib_V1.3 +--------------------------------------------- +[Download Release V1.3](https://drive.google.com/file/d/1q56Qewk8-Aquv1epss1gd7Gc05q4GrbO/view?usp=sharing) + +25.03.2018: + +Driver Library :Add Channel List. Now you can set channel numbers 0-255. + +Driver Library :Add bandwidth can be adjusted + +Driver Library :transmission power can be adjusted + +Driver Library :can set your own frequency settings (freq2, freq1, freq0) + +Driver Library :Channel spacing can be set. + +Examples :Add set new commands + +--------------------------------------------- +Changelog: RCSwitch-CC1101-Driver-Lib_V1.2 +--------------------------------------------- +[Download Release V1.2](https://drive.google.com/file/d/1KLJt8ygszj9rqcttiEMt5zCnJKHc_qe3/view?usp=sharing) + +20.03.2018: + +Driver Library :Add 315Mhz Support. + +Driver Library :Add Channel command for finetune (80khz steps) from 420mhz - 440mhz / 302mhz - 322mhz. + +Examples :Add set channel command in examples. + +--------------------------------------------- +Changelog: RCSwitch-CC1101-Driver-Lib_V1.1 +--------------------------------------------- +[Download Release V1.1](https://drive.google.com/file/d/1uZzcY4uoduiUjFZzXdxA-ucLoA_TtC1f/view?usp=sharing) + +19.03.2018: + +Driver Library Fix :Calibrated Frequency from 433.86 to 433.92 - 433.93 Mhz. + +Driver Library :cc1101 reset command added (allows switching between send and receive.) + +New Demo Example :Receive_Send_Decimal_Demo_Simple.ino (Sends last received decimal code) + To illustrate the change between RX and TX (press button = send / do not press button = receive) + +Add Wiring JPG :Wiring for Receive_Send_Decimal_Demo_Simple.ino + +Add Wiring JPG :Wiring for Nano / Uno + + +--------------------------------------------- +Changelog: RCSwitch-CC1101-Driver-Lib_V1.0 +--------------------------------------------- +[Download Release V1.0](https://drive.google.com/file/d/14538RtiEakZ_8yioXJT32XneheSjDqxi/view?usp=sharing) + +18.03.2018: + +cc1101 Compatibility for RC-Switch. + +cc1101 RC-Switch Compatible examples. diff --git a/lib/SmartRC-CC1101-Driver-Lib/library.json b/lib/SmartRC-CC1101-Driver-Lib/library.json new file mode 100644 index 0000000..63ef3b0 --- /dev/null +++ b/lib/SmartRC-CC1101-Driver-Lib/library.json @@ -0,0 +1,19 @@ +{ + "name": "SmartRC-CC1101-Driver-Lib", + "description": "This driver library can be used for many libraries that use a simple RF ASK module, with the advantages of the cc1101 module.It offers many direct setting options as in SmartRF Studio and calculates settings such as MHz directly.", + "keywords": "rf, radio, wireless, cc1101", + "authors": + { + "name": "Little Satan" + }, + "repository": + { + "type": "git", + "url": "https://github.com/LSatan/SmartRC-CC1101-Driver-Lib" + }, + "version": "2.5.7", + "frameworks": [ + "arduino" + ], + "platforms": "*" +} diff --git a/platformio.ini b/platformio.ini index 12645b4..c4e1bfa 100644 --- a/platformio.ini +++ b/platformio.ini @@ -15,13 +15,14 @@ src_dir = src ; Shared by every firmware env (they extend it). Kept out of [env] so the ; native test env doesn't inherit the Arduino framework and ESP32 libraries. [esp32] -platform = espressif32 @ 6.13.0 +; pioarduino: Arduino 3.3.12 on ESP-IDF 5.5. Pinned to a release so an +; upgrade is its own PR (docs/adr/0003-pioarduino-idf55.md). +platform = https://github.com/pioarduino/platform-espressif32/releases/download/55.03.312/platform-espressif32.zip framework = arduino ; Unit tests only run on the PC: pio test -e native test_ignore = * lib_deps = bblanchon/ArduinoJson@^7.2.2 - lsatan/SmartRC-CC1101-Driver-Lib@^2.5.7 knolleary/PubSubClient@^2.8 esp32async/ESPAsyncWebServer@^3.12.1 esp32async/AsyncTCP@^3.5.0 @@ -30,8 +31,9 @@ extra_scripts = pre:minify.py post:archive_elf.py board_build.filesystem = littlefs -build_flags = - -DCORE_DEBUG_LEVEL=3 +; Each env adds a CORE_DEBUG_LEVEL: 2 (warnings) for release builds, which +; only fit the 1.5 MB OTA slot without the info logs, 3 for debug builds. +build_flags = -DCONFIG_ESP_COREDUMP_ENABLE_TO_FLASH=1 -DCONFIG_ESP_COREDUMP_DATA_FORMAT_ELF=1 -DCONFIG_ESP_COREDUMP_CHECKSUM_CRC32=1 @@ -57,7 +59,9 @@ build_flags = extends = esp32 board = esp32dev board_build.partitions = esp32_3MB.csv -build_flags = ${dualcore.build_flags} +build_flags = + ${dualcore.build_flags} + -DCORE_DEBUG_LEVEL=2 [env:esp32devdbg] extends = esp32 @@ -73,39 +77,26 @@ board_build.partitions = esp32_huge_app.csv ; KBs of flash per file, so treat every file as large. build_flags = ${dualcore.build_flags} + -DCORE_DEBUG_LEVEL=3 --param=large-unit-insns=1000 -[env:esp32c3] -extends = esp32 -board = esp32-c3-devkitm-1 -board_build.partitions = esp32_3MB.csv - [env:esp32s3] extends = esp32 board = esp32-s3-devkitc-1 -build_flags = ${dualcore.build_flags} +build_flags = + ${dualcore.build_flags} + -DCORE_DEBUG_LEVEL=2 +; Released as a debug build with one 3 MB app slot, so C6 boards update over +; USB, not OTA. [env:esp32c6] extends = esp32 -platform = https://github.com/pioarduino/platform-espressif32/releases/download/stable/platform-espressif32.zip board = seeed_xiao_esp32c6 build_type = debug board_build.partitions = esp32_huge_app.csv build_flags = ${esp32.build_flags} - -DCONFIG_FREERTOS_HZ=1000 - -include "driver/gpio.h" -lib_deps = - ; Low-Level libs, frameowrks and drivers - ESP32Async/AsyncTCP - https://github.com/Viproz/SmartRC-CC1101-Driver-Lib.git - ; Commmunication Protocol - links2004/WebSockets - https://github.com/hmueller01/pubsubclient3.git - ; Data-Parsing - bblanchon/ArduinoJson - ; High-level wrappers/servers - ESP32Async/ESPAsyncWebServer + -DCORE_DEBUG_LEVEL=3 ; Host-side unit tests: pio test -e native (needs gcc/g++ on PATH). ; Only the sources the tests cover are built; test/stubs stands in for Arduino.h. diff --git a/src/ESPNetwork.cpp b/src/ESPNetwork.cpp index 5125a9c..6a51e58 100644 --- a/src/ESPNetwork.cpp +++ b/src/ESPNetwork.cpp @@ -396,7 +396,7 @@ bool ESPNetwork::connectWired() { if(!ethPhyType(settings.Ethernet.phyType, phyType)) ESP_LOGE(TAG, "Ethernet PHY type %u is not supported", (unsigned int)settings.Ethernet.phyType); else - begun = ETH.begin(settings.Ethernet.phyAddress, settings.Ethernet.PWRPin, settings.Ethernet.MDCPin, settings.Ethernet.MDIOPin, phyType, settings.Ethernet.CLKMode); + begun = ETH.begin(phyType, settings.Ethernet.phyAddress, settings.Ethernet.MDCPin, settings.Ethernet.MDIOPin, settings.Ethernet.PWRPin, settings.Ethernet.CLKMode); if(!begun) { ESP_LOGE(TAG, "Ethernet Begin failed"); this->ethStarted = false; diff --git a/src/GitOTA.cpp b/src/GitOTA.cpp index 9b13d9c..2c09b9f 100644 --- a/src/GitOTA.cpp +++ b/src/GitOTA.cpp @@ -3,7 +3,6 @@ #include #include #include -#include #include "esp_log.h" #include "ConfigSettings.h" #include "GitOTA.h" @@ -43,7 +42,9 @@ void GitRelease::setReleaseProperty(const char *key, const char *val) { void GitRelease::setAssetProperty(const char *key, const char *val) { if(strcmp(key, "name") == 0) { //Serial.println(val); - if(strstr(val, "littlefs.bin")) this->hasFS = true; + char fsFile[64]; + releaseAssetName(fsFile, sizeof(fsFile), "littlefs", settings.chipModel); + if(strcmp(val, fsFile) == 0) this->hasFS = true; else if(strstr(val, "ino.esp32.bin")) { if(strlen(this->hwVersions)) strcat(this->hwVersions, ","); strcat(this->hwVersions, "32"); @@ -353,25 +354,6 @@ void GitUpdater::emitDownloadProgress(uint8_t num, size_t total, size_t loaded, sockEmit.loop(); webServer.loop(); } -void GitUpdater::setFirmwareFile() { - esp_chip_info_t ci; - esp_chip_info(&ci); - switch(ci.model) { - case esp_chip_model_t::CHIP_ESP32S3: - strcpy(this->currentFile, "SomfyController.ino.esp32s3.bin"); - break; - case esp_chip_model_t::CHIP_ESP32S2: - strcpy(this->currentFile, "SomfyController.ino.esp32s2.bin"); - break; - case esp_chip_model_t::CHIP_ESP32C3: - strcpy(this->currentFile, "SomfyController.ino.esp32c3.bin"); - break; - default: - strcpy(this->currentFile, "SomfyController.ino.esp32.bin"); - break; - } -} - bool GitUpdater::beginUpdate(const char *version) { ESP_LOGI(TAG, "Begin update called..."); if(strcmp(version, "Main") == 0) strcpy(this->baseUrl, "https://raw.githubusercontent.com/cjkas/ESPSomfy-RTS/master/"); @@ -379,14 +361,14 @@ bool GitUpdater::beginUpdate(const char *version) { strcpy(this->targetRelease, version); this->emitUpdateCheck(); - this->setFirmwareFile(); + releaseAssetName(this->currentFile, sizeof(this->currentFile), "ino", settings.chipModel); this->partition = U_FLASH; this->lockFS = this->cancelled = false; this->error = 0; this->error = this->downloadFile(); if(this->error == 0 && !this->cancelled) { somfy.commit(); - strcpy(this->currentFile, "SomfyController.littlefs.bin"); + releaseAssetName(this->currentFile, sizeof(this->currentFile), "littlefs", settings.chipModel); this->partition = U_SPIFFS; this->lockFS = true; this->error = this->downloadFile(); @@ -405,8 +387,8 @@ bool GitUpdater::beginUpdate(const char *version) { return true; } bool GitUpdater::recoverFilesystem() { - sprintf(this->baseUrl, "https://github.com/rstrouse/ESPSomfy-RTS/releases/download/%s/", settings.fwVersion.name); - strcpy(this->currentFile, "SomfyController.littlefs.bin"); + sprintf(this->baseUrl, "https://github.com/cjkas/ESPSomfy-RTS/releases/download/%s/", settings.fwVersion.name); + releaseAssetName(this->currentFile, sizeof(this->currentFile), "littlefs", settings.chipModel); this->status = GIT_UPDATING; this->partition = U_SPIFFS; this->lockFS = true; diff --git a/src/GitOTA.h b/src/GitOTA.h index 6996f83..7a02112 100644 --- a/src/GitOTA.h +++ b/src/GitOTA.h @@ -55,7 +55,6 @@ class GitUpdater { bool beginUpdate(const char *release); bool endUpdate(); int8_t downloadFile(); - void setFirmwareFile(); void setCurrentRelease(GitRepo &repo); void loop(); diff --git a/src/LogLock.cpp b/src/LogLock.cpp index 8c68d63..0d131f6 100644 --- a/src/LogLock.cpp +++ b/src/LogLock.cpp @@ -18,7 +18,6 @@ // progress (see LogLockPolicy.h). #include #include -#include "esp_idf_version.h" #include "freertos/FreeRTOS.h" #include "freertos/semphr.h" #include "freertos/task.h" @@ -41,19 +40,12 @@ static volatile TaskHandle_t logOwner = nullptr; // line takes about 20ms at 115200 baud. #define LOG_LOCK_WAIT_MS 20 -#if ESP_IDF_VERSION_MAJOR >= 5 -#define taskOnCore(core) xTaskGetCurrentTaskHandleForCore(core) -#define taskCore(task) xTaskGetCoreID(task) -#else -#define taskOnCore(core) xTaskGetCurrentTaskHandleForCPU(core) -#define taskCore(task) xTaskGetAffinity(task) -#endif static LogHolder logHolder(TaskHandle_t owner) { if(!owner) return LogHolder::unknown; for(BaseType_t core = 0; core < portNUM_PROCESSORS; core++) - if(taskOnCore(core) == owner) return LogHolder::running; + if(xTaskGetCurrentTaskHandleForCore(core) == owner) return LogHolder::running; // A task pinned elsewhere only runs once whatever preempted it there is done. - const BaseType_t core = taskCore(owner); + const BaseType_t core = xTaskGetCoreID(owner); if(core == tskNO_AFFINITY || core == xPortGetCoreID()) return LogHolder::preemptedHere; return LogHolder::preemptedElsewhere; } diff --git a/src/SomfyController.ino b/src/SomfyController.ino index fb1dbc2..0d7d973 100644 --- a/src/SomfyController.ino +++ b/src/SomfyController.ino @@ -16,18 +16,20 @@ #include "GitOTA.h" #include "esp_core_dump.h" #include "esp_system.h" -#include "esp_idf_version.h" -#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0) #include "esp_app_desc.h" -#define getRunningElfSha esp_app_get_elf_sha256 -#else #include "esp_ota_ops.h" -#define getRunningElfSha esp_ota_get_app_elf_sha256 -#endif #include "Timing.h" static const char *TAG = "Main"; #define LOOP_SLOW_MS 100 +// How long an updated firmware has to run, and then have the network up, before +// it is kept. A reset before then rolls back to the previous firmware. +#define OTA_PROVEN_MS 60000 + +// Overrides the core's weak hook so it leaves an updated firmware unverified +// at boot. loop() confirms it once otaProven(). +extern "C" bool verifyRollbackLater() { return true; } +static bool otaPending = false; ConfigSettings settings; Web webServer; @@ -101,7 +103,7 @@ void setup() { static_assert(sizeof(crashedSha) <= sizeof(summary.app_elf_sha256), "copy would read past app_elf_sha256"); SETCHARPROP(crashedSha, (const char *)summary.app_elf_sha256, sizeof(crashedSha)); char runningSha[APP_ELF_SHA256_SZ] = {0}; - getRunningElfSha(runningSha, sizeof(runningSha)); + esp_app_get_elf_sha256(runningSha, sizeof(runningSha)); if(strcmp(crashedSha, runningSha) == 0) CRASH_LOG(" Build: %s (running %s, same build)", crashedSha, runningSha); else @@ -129,14 +131,15 @@ void setup() { net.setup(); somfy.begin(); //git.checkForUpdate(); -#if ESP_ARDUINO_VERSION_MAJOR >= 3 + // The core starts the watchdog with a 5s timeout before setup(), so + // esp_task_wdt_init() would fail and keep that. const esp_task_wdt_config_t wdt_config = { .timeout_ms = 15000, .idle_core_mask = 1, .trigger_panic = true }; - esp_task_wdt_init(&wdt_config); -#else - esp_task_wdt_init(15, true); //enable panic so ESP32 restarts -#endif + esp_task_wdt_reconfigure(&wdt_config); esp_task_wdt_add(NULL); //add current thread to WDT watch - + esp_ota_img_states_t otaState; + otaPending = esp_ota_get_state_partition(esp_ota_get_running_partition(), &otaState) == ESP_OK && + otaState == ESP_OTA_IMG_PENDING_VERIFY; + if(otaPending) ESP_LOGW(TAG, "Updated firmware, keeping it once it has run %ds with the network up", OTA_PROVEN_MS / 1000); } void loop() { @@ -183,6 +186,11 @@ void loop() { net.end(); ESP.restart(); } + if(otaPending && otaProven(net.connected(), millis(), OTA_PROVEN_MS)) { + otaPending = false; + if(esp_ota_mark_app_valid_cancel_rollback() == ESP_OK) ESP_LOGI(TAG, "Updated firmware confirmed, rollback cancelled"); + else ESP_LOGE(TAG, "Unable to confirm the updated firmware"); + } esp_task_wdt_reset(); loopStats.record(pass.us()); } diff --git a/src/Utils.cpp b/src/Utils.cpp index f329951..0fc4a0a 100644 --- a/src/Utils.cpp +++ b/src/Utils.cpp @@ -147,6 +147,12 @@ void RssiBroadcast::sent(bool broadcast, int rssi, int channel, uint32_t now) { bool worthRoaming(bool connected, int currentRssi, int apRssi, int minGain) { return !connected || apRssi >= currentRssi + minGain; } +bool otaProven(bool networkUp, unsigned long uptimeMs, unsigned long minUptimeMs) { + return networkUp && uptimeMs >= minUptimeMs; +} +void releaseAssetName(char *buf, size_t size, const char *kind, const char *chipModel) { + snprintf(buf, size, "SomfyController.%s.esp32%s.bin", kind, chipModel); +} const char *wifiAuthModeName(uint8_t authMode) { switch(authMode) { case 0: return "OPEN"; diff --git a/src/Utils.h b/src/Utils.h index e182535..7dfbb31 100644 --- a/src/Utils.h +++ b/src/Utils.h @@ -82,6 +82,14 @@ enum class heap_emit_t : uint8_t { none, client, broadcast, room }; // num is the socket client asked for, 255 for everyone. A broadcast goes out // every intervalMs; in between only the clients in room 0 get one. heap_emit_t heapEmitTarget(uint8_t num, uint32_t sinceLastMs, uint32_t intervalMs, bool roomHasClients); +// Whether a firmware the bootloader is holding for verification after an +// update has proven itself: it has run for minUptimeMs and the network is +// up. Until then a reset rolls back to the previous firmware. +bool otaProven(bool networkUp, unsigned long uptimeMs, unsigned long minUptimeMs); +// A release asset's name: "SomfyController..esp32.bin", kind +// "ino" for the firmware or "littlefs" for the web UI image, chipModel as in +// ConfigSettings ("" for the ESP32, "s3", "c3", "c6"). +void releaseAssetName(char *buf, size_t size, const char *kind, const char *chipModel); // How well loop() keeps up: the passes it made per second and its longest // pass, over the window since the last memStatus broadcast. Only the loop // task calls record(), rate(), maxUs() and publish(). publish() closes the diff --git a/test/test_utils/test_utils.cpp b/test/test_utils/test_utils.cpp index f3c2c2c..e549f73 100644 --- a/test/test_utils/test_utils.cpp +++ b/test/test_utils/test_utils.cpp @@ -257,6 +257,41 @@ static void test_worthRoaming_any_ap_while_disconnected() { TEST_ASSERT_TRUE(worthRoaming(false, 0, -90, 6)); } +/********************************************************************* + * otaProven + ********************************************************************/ +static void test_otaProven_after_the_minimum_uptime_with_network() { + TEST_ASSERT_TRUE(otaProven(true, 60000, 60000)); + TEST_ASSERT_TRUE(otaProven(true, 3600000, 60000)); +} +static void test_otaProven_not_before_the_minimum_uptime() { + TEST_ASSERT_FALSE(otaProven(true, 59999, 60000)); +} +static void test_otaProven_not_without_network() { + // A firmware that can't connect would leave the device unreachable. + TEST_ASSERT_FALSE(otaProven(false, 3600000, 60000)); +} + +/********************************************************************* + * releaseAssetName + ********************************************************************/ +static void test_releaseAssetName_matches_the_release_workflow() { + // .github/workflows/build.yaml fwname and fsname, from ConfigSettings::chipModel. + char buf[64]; + releaseAssetName(buf, sizeof(buf), "ino", ""); + TEST_ASSERT_EQUAL_STRING("SomfyController.ino.esp32.bin", buf); + releaseAssetName(buf, sizeof(buf), "littlefs", "s3"); + TEST_ASSERT_EQUAL_STRING("SomfyController.littlefs.esp32s3.bin", buf); + releaseAssetName(buf, sizeof(buf), "littlefs", "c6"); + TEST_ASSERT_EQUAL_STRING("SomfyController.littlefs.esp32c6.bin", buf); +} +static void test_releaseAssetName_keeps_c3() { + // C3 is out of the IDF 5.5 builds for now (ADR 0003) but is coming back. + char buf[64]; + releaseAssetName(buf, sizeof(buf), "ino", "c3"); + TEST_ASSERT_EQUAL_STRING("SomfyController.ino.esp32c3.bin", buf); +} + /********************************************************************* * wifiAuthModeName ********************************************************************/ @@ -384,6 +419,11 @@ int main(int argc, char **argv) { RUN_TEST(test_worthRoaming_needs_the_full_gain); RUN_TEST(test_worthRoaming_never_to_a_weaker_ap); RUN_TEST(test_worthRoaming_any_ap_while_disconnected); + RUN_TEST(test_otaProven_after_the_minimum_uptime_with_network); + RUN_TEST(test_otaProven_not_before_the_minimum_uptime); + RUN_TEST(test_otaProven_not_without_network); + RUN_TEST(test_releaseAssetName_matches_the_release_workflow); + RUN_TEST(test_releaseAssetName_keeps_c3); RUN_TEST(test_wifiAuthModeName_matches_the_idf_enum); RUN_TEST(test_wifiAuthModeName_unknown_past_the_shared_values); RUN_TEST(test_heapEmitTarget_one_client_always_gets_it);