Snapshot: full project state

This commit is contained in:
2026-10-06 23:43:26 -07:00
commit c1f5e0ff42
15 changed files with 2816 additions and 0 deletions

224
include/radio_cc1101.h Normal file
View File

@@ -0,0 +1,224 @@
#ifndef RADIO_CC1101_H
#define RADIO_CC1101_H
#include <SPI.h>
#include "board_config.h"
// CC1101 SubGHz Radio Driver
// Supports 300-928 MHz, optional E07-433M20S PA module (20dBm amplified)
class RadioCC1101 {
public:
// Frequency bands
enum FreqBand {
BAND_433MHZ = 0,
BAND_868MHZ = 1,
BAND_915MHZ = 2,
};
// Initialize SPI and radio
static bool begin(FreqBand band = BAND_433MHZ, bool use_pa_module = false) {
// Setup GPIO
pinMode(CC1101_CS, OUTPUT);
pinMode(CC1101_GDO0, INPUT); // TX/data out
pinMode(CC1101_GDO2, INPUT); // RX/data in
if (use_pa_module) {
pinMode(CC1101_TX_EN, OUTPUT);
pinMode(CC1101_RX_EN, OUTPUT);
digitalWrite(CC1101_TX_EN, LOW);
digitalWrite(CC1101_RX_EN, LOW);
}
// Start SPI
SPI.begin(RADIO_SPI_CLK, RADIO_SPI_MISO, RADIO_SPI_MOSI);
SPI.setFrequency(10000000); // 10 MHz
SPI.setDataMode(SPI_MODE0);
// Reset radio
reset();
delay(100);
// Verify chip
uint8_t id = readReg(0x0F);
if (id != 0x04) {
return false; // Not a CC1101
}
// Configure for band
switch (band) {
case BAND_433MHZ:
setFreq(433.92f);
break;
case BAND_868MHZ:
setFreq(868.0f);
break;
case BAND_915MHZ:
setFreq(915.0f);
break;
}
// RX mode
setRxMode();
return true;
}
// Set frequency (MHz)
static void setFreq(float freq_mhz) {
// CC1101 frequency = FREQ_REG * (Fxosc / 2^16)
// Fxosc = 26 MHz
uint32_t freq = (uint32_t)(freq_mhz / (26.0f / 65536.0f));
writeReg(0x0D, (freq >> 16) & 0xFF);
writeReg(0x0E, (freq >> 8) & 0xFF);
writeReg(0x0F, freq & 0xFF);
}
// Set TX power (dBm)
// 0xFF = +10dBm, 0xFE = +7dBm, 0x84 = +5dBm, etc.
static void setTxPower(uint8_t pwr) {
writeReg(0x3E, pwr);
}
// Set max power (12dBm for stock, 20dBm with E07 PA)
static void setMaxPower(bool use_pa_module = false) {
if (use_pa_module) {
// E07 PA module: TX_EN + RX_EN control
setTxPower(0xFF); // +10 dBm + 10 dBm from PA = ~20 dBm
} else {
// Stock CC1101: +12 dBm
setTxPower(0x84);
}
}
// Switch to RX mode
static void setRxMode() {
strobe(0x34); // RX enable
}
// Switch to TX mode
static void setTxMode() {
strobe(0x35); // TX enable
}
// Transmit data
static void transmit(const uint8_t* data, uint8_t len) {
// Clear TX FIFO
strobe(0x3B);
delay(10);
// Fill TX FIFO
digitalWrite(CC1101_CS, LOW);
SPI.transfer(0x3F); // FIFO address
for (uint8_t i = 0; i < len; i++) {
SPI.transfer(data[i]);
}
digitalWrite(CC1101_CS, HIGH);
// TX
setTxMode();
}
// Receive data (blocking)
// Returns length of received packet or 0 if none
static uint8_t receive(uint8_t* buffer, uint8_t max_len, uint32_t timeout_ms) {
uint32_t start = millis();
setRxMode();
while (millis() - start < timeout_ms) {
// Check for RX packet (GDO0)
if (digitalRead(CC1101_GDO0) == HIGH) {
// Read FIFO
uint8_t rx_len = readReg(0x3F);
if (rx_len > 0 && rx_len <= max_len) {
digitalWrite(CC1101_CS, LOW);
SPI.transfer(0xBF); // RX FIFO read
for (uint8_t i = 0; i < rx_len; i++) {
buffer[i] = SPI.transfer(0x00);
}
digitalWrite(CC1101_CS, HIGH);
// Clear RX FIFO
strobe(0x3A);
return rx_len;
}
}
delayMicroseconds(100);
}
return 0; // Timeout
}
// Get RSSI (signal strength)
static int8_t getRSSI() {
uint8_t raw = readReg(0x34);
if (raw >= 128) {
return (raw - 256) / 2 - 74;
}
return raw / 2 - 74;
}
// Sleep mode (low power)
static void sleep() {
strobe(0x36); // IDLE
delay(10);
strobe(0x39); // Sleep
}
static void wakeup() {
strobe(0x3C); // Wakeup
delay(10);
}
private:
// Reset CC1101
static void reset() {
digitalWrite(CC1101_CS, LOW);
delayMicroseconds(10);
digitalWrite(CC1101_CS, HIGH);
delayMicroseconds(40);
digitalWrite(CC1101_CS, LOW);
while (digitalRead(RADIO_SPI_MISO) == HIGH);
SPI.transfer(0x30); // SRES (reset strobe)
while (digitalRead(RADIO_SPI_MISO) == HIGH);
digitalWrite(CC1101_CS, HIGH);
delayMicroseconds(40);
}
// Send strobe command
static void strobe(uint8_t cmd) {
digitalWrite(CC1101_CS, LOW);
while (digitalRead(RADIO_SPI_MISO) == HIGH);
SPI.transfer(cmd);
while (digitalRead(RADIO_SPI_MISO) == HIGH);
digitalWrite(CC1101_CS, HIGH);
}
// Read register
static uint8_t readReg(uint8_t reg) {
digitalWrite(CC1101_CS, LOW);
while (digitalRead(RADIO_SPI_MISO) == HIGH);
SPI.transfer(0x80 | reg); // Read bit
uint8_t val = SPI.transfer(0x00);
while (digitalRead(RADIO_SPI_MISO) == HIGH);
digitalWrite(CC1101_CS, HIGH);
return val;
}
// Write register
static void writeReg(uint8_t reg, uint8_t val) {
digitalWrite(CC1101_CS, LOW);
while (digitalRead(RADIO_SPI_MISO) == HIGH);
SPI.transfer(reg);
SPI.transfer(val);
while (digitalRead(RADIO_SPI_MISO) == HIGH);
digitalWrite(CC1101_CS, HIGH);
}
};
#endif // RADIO_CC1101_H