mirror of
https://github.com/OpenEPaperLink/OpenEPaperLink.git
synced 2026-03-21 07:06:36 +01:00
Add support for SubGhz radio. Working end to end for tag registration. (#270)
This commit is contained in:
@@ -2,6 +2,8 @@ idf_component_register( SRCS
|
||||
SRCS "utils.c"
|
||||
SRCS "second_uart.c"
|
||||
SRCS "radio.c"
|
||||
SRCS "SubGigRadio.c"
|
||||
SRCS "cc1101_radio.c"
|
||||
SRCS "led.c"
|
||||
SRCS "main.c"
|
||||
INCLUDE_DIRS ".")
|
||||
|
||||
@@ -25,4 +25,79 @@ menu "OEPL Hardware config"
|
||||
int "GPIO - UART RX"
|
||||
default 2
|
||||
|
||||
config OEPL_SUBGIG_SUPPORT
|
||||
bool "Enable SubGhz Support"
|
||||
default "n"
|
||||
|
||||
menu "CC1101 Configuration"
|
||||
depends on OEPL_SUBGIG_SUPPORT
|
||||
|
||||
config GPIO_RANGE_MAX
|
||||
int
|
||||
default 33 if IDF_TARGET_ESP32
|
||||
default 46 if IDF_TARGET_ESP32S2
|
||||
default 48 if IDF_TARGET_ESP32S3
|
||||
default 18 if IDF_TARGET_ESP32C2
|
||||
default 19 if IDF_TARGET_ESP32C3
|
||||
default 30 if IDF_TARGET_ESP32C6
|
||||
|
||||
config MISO_GPIO
|
||||
int "CC1101 MISO GPIO"
|
||||
range 0 GPIO_RANGE_MAX
|
||||
default 7
|
||||
help
|
||||
Pin Number to be used as the MISO SPI signal.
|
||||
|
||||
config SCK_GPIO
|
||||
int "CC1101 SCK GPIO"
|
||||
range 0 GPIO_RANGE_MAX
|
||||
default 0
|
||||
help
|
||||
Pin Number to be used as the SCK SPI signal.
|
||||
|
||||
config MOSI_GPIO
|
||||
int "CC1101 MOSI GPIO"
|
||||
default 1
|
||||
help
|
||||
Pin Number to be used as the MOSI SPI signal.
|
||||
|
||||
config CSN_GPIO
|
||||
int "CC1101 CSN GPIO"
|
||||
range 0 GPIO_RANGE_MAX
|
||||
default 4
|
||||
help
|
||||
Pin Number to be used as the CSN SPI signal.
|
||||
|
||||
config GDO0_GPIO
|
||||
int "CC1101 GDO0 GPIO"
|
||||
range 0 GPIO_RANGE_MAX
|
||||
default 5
|
||||
help
|
||||
Pin Number to be used as the GDO0 signal.
|
||||
|
||||
config GDO2_GPIO
|
||||
int "CC1101 GDO2 GPIO"
|
||||
range 0 GPIO_RANGE_MAX
|
||||
default 6
|
||||
help
|
||||
Pin Number to be used as the GDO2 signal.
|
||||
|
||||
choice SPI_HOST
|
||||
prompt "SPI peripheral that controls this bus"
|
||||
default SPI2_HOST
|
||||
help
|
||||
Select SPI peripheral that controls this bus.
|
||||
config SPI2_HOST
|
||||
bool "SPI2_HOST"
|
||||
help
|
||||
Use SPI2_HOST. This is also called HSPI_HOST.
|
||||
config SPI3_HOST
|
||||
depends on IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3
|
||||
bool "SPI3_HOST"
|
||||
help
|
||||
USE SPI3_HOST. This is also called VSPI_HOST
|
||||
endchoice
|
||||
endmenu
|
||||
endmenu
|
||||
|
||||
|
||||
|
||||
542
ARM_Tag_FW/OpenEPaperLink_esp32_C6_AP/main/SubGigRadio.c
Executable file
542
ARM_Tag_FW/OpenEPaperLink_esp32_C6_AP/main/SubGigRadio.c
Executable file
@@ -0,0 +1,542 @@
|
||||
#include "sdkconfig.h"
|
||||
#ifdef CONFIG_OEPL_SUBGIG_SUPPORT
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
|
||||
#include <driver/spi_master.h>
|
||||
#include <driver/gpio.h>
|
||||
#include "esp_log.h"
|
||||
|
||||
#include "radio.h"
|
||||
#include "proto.h"
|
||||
#include "cc1101_radio.h"
|
||||
#include "SubGigRadio.h"
|
||||
|
||||
void DumpHex(void *AdrIn,int Len);
|
||||
|
||||
#if 0
|
||||
#define LOG(format, ... ) printf("%s: " format,__FUNCTION__,## __VA_ARGS__)
|
||||
#define LOG_RAW(format, ... ) printf(format,## __VA_ARGS__)
|
||||
#define LOG_HEX(x,y) DumpHex(x,y)
|
||||
#else
|
||||
#define LOG(format, ... )
|
||||
#define LOG_RAW(format, ... )
|
||||
#define LOG_HEX(x,y)
|
||||
#endif
|
||||
|
||||
|
||||
// SPI Stuff
|
||||
#if CONFIG_SPI2_HOST
|
||||
#define HOST_ID SPI2_HOST
|
||||
#elif CONFIG_SPI3_HOST
|
||||
#define HOST_ID SPI3_HOST
|
||||
#endif
|
||||
|
||||
// Address Config = No address check
|
||||
// Base Frequency = xxx.xxx
|
||||
// CRC Enable = false
|
||||
// Carrier Frequency = 915.000000
|
||||
// Channel Number = 0
|
||||
// Channel Spacing = 199.951172
|
||||
// Data Rate = 1.19948
|
||||
// Deviation = 5.157471
|
||||
// Device Address = 0
|
||||
// Manchester Enable = false
|
||||
// Modulated = false
|
||||
// Modulation Format = ASK/OOK
|
||||
// PA Ramping = false
|
||||
// Packet Length = 255
|
||||
// Packet Length Mode = Reserved
|
||||
// Preamble Count = 4
|
||||
// RX Filter BW = 58.035714
|
||||
// Sync Word Qualifier Mode = No preamble/sync
|
||||
// TX Power = 10
|
||||
// Whitening = false
|
||||
// Rf settings for CC1110
|
||||
const RfSetting gCW[] = {
|
||||
{CC1101_PKTCTRL0,0x22}, // PKTCTRL0: Packet Automation Control
|
||||
{CC1101_FSCTRL1,0x06}, // FSCTRL1: Frequency Synthesizer Control
|
||||
{CC1101_MDMCFG4,0xF5}, // MDMCFG4: Modem configuration
|
||||
{CC1101_MDMCFG3,0x83}, // MDMCFG3: Modem Configuration
|
||||
{CC1101_MDMCFG2,0xb0}, // MDMCFG2: Modem Configuration
|
||||
{CC1101_DEVIATN,0x15}, // DEVIATN: Modem Deviation Setting
|
||||
{CC1101_MCSM0,0x18}, // MCSM0: Main Radio Control State Machine Configuration
|
||||
{CC1101_FOCCFG,0x17}, // FOCCFG: Frequency Offset Compensation Configuration
|
||||
{CC1101_FSCAL3,0xE9}, // FSCAL3: Frequency Synthesizer Calibration
|
||||
{CC1101_FSCAL2,0x2A}, // FSCAL2: Frequency Synthesizer Calibration
|
||||
{CC1101_FSCAL1,0x00}, // FSCAL1: Frequency Synthesizer Calibration
|
||||
{CC1101_FSCAL0,0x1F}, // FSCAL0: Frequency Synthesizer Calibration
|
||||
{CC1101_TEST1,0x31}, // TEST1: Various Test Settings
|
||||
{CC1101_TEST0,0x09}, // TEST0: Various Test Settings
|
||||
{0xff,0} // end of table
|
||||
};
|
||||
|
||||
|
||||
// Set Base Frequency to 865.999634
|
||||
const RfSetting g866Mhz[] = {
|
||||
{CC1101_FREQ2,0x21}, // FREQ2: Frequency Control Word, High Byte
|
||||
{CC1101_FREQ1,0x4e}, // FREQ1: Frequency Control Word, Middle Byte
|
||||
{CC1101_FREQ0,0xc4}, // FREQ0: Frequency Control Word, Low Byte
|
||||
{0xff,0} // end of table
|
||||
};
|
||||
|
||||
// Set Base Frequency to 863.999756
|
||||
const RfSetting g864Mhz[] = {
|
||||
{CC1101_FREQ2,0x21}, // FREQ2: Frequency Control Word, High Byte
|
||||
{CC1101_FREQ1,0x3b}, // FREQ1: Frequency Control Word, Middle Byte
|
||||
{CC1101_FREQ0,0x13}, // FREQ0: Frequency Control Word, Low Byte
|
||||
{0xff,0} // end of table
|
||||
};
|
||||
|
||||
// Set Base Frequency to 902.999756
|
||||
const RfSetting g903Mhz[] = {
|
||||
{CC1101_FREQ2,0x22}, // FREQ2: Frequency Control Word, High Byte
|
||||
{CC1101_FREQ1,0xbb}, // FREQ1: Frequency Control Word, Middle Byte
|
||||
{CC1101_FREQ0,0x13}, // FREQ0: Frequency Control Word, Low Byte
|
||||
{0xff,0} // end of table
|
||||
};
|
||||
|
||||
|
||||
// Seet Base Frequency to 915.000000
|
||||
const RfSetting g915Mhz[] = {
|
||||
{CC1101_FREQ2,0x23}, // FREQ2: Frequency Control Word, High Byte
|
||||
{CC1101_FREQ1,0x31}, // FREQ1: Frequency Control Word, Middle Byte
|
||||
{CC1101_FREQ0,0x3B}, // FREQ0: Frequency Control Word, Low Byte
|
||||
{0xff,0} // end of table
|
||||
};
|
||||
|
||||
// Address Config = No address check
|
||||
// Base Frequency = 901.934937 (adjusted to compensate for the crappy crystal on the CC1101 board)
|
||||
// CRC Enable = true
|
||||
// Carrier Frequency = 901.934937
|
||||
// Channel Number = 0
|
||||
// Channel Spacing = 199.951172
|
||||
// Data Rate = 38.3835
|
||||
// Deviation = 20.629883
|
||||
// Device Address = ff
|
||||
// Manchester Enable = false
|
||||
// Modulated = true
|
||||
// Modulation Format = GFSK
|
||||
// PA Ramping = false
|
||||
// Packet Length = 61
|
||||
// Packet Length Mode = Variable packet length mode. Packet length configured by the first byte after sync word
|
||||
// Preamble Count = 4
|
||||
// RX Filter BW = 101.562500
|
||||
// Sync Word Qualifier Mode = 30/32 sync word bits detected
|
||||
// TX Power = 10
|
||||
// Whitening = false
|
||||
// The following was generated by setting the spec for Register to "{CC1101_@RN@,0x@VH@},"
|
||||
const RfSetting gIDF_Basic[] = {
|
||||
{CC1101_SYNC1,0xC7},
|
||||
{CC1101_SYNC0,0x0A},
|
||||
{CC1101_PKTLEN,0x3D},
|
||||
{CC1101_PKTCTRL0,0x05},
|
||||
{CC1101_ADDR,0xFF},
|
||||
{CC1101_FSCTRL1,0x08},
|
||||
{CC1101_FREQ2,0x22},
|
||||
{CC1101_FREQ1,0xB1},
|
||||
{CC1101_FREQ0,0x3B},
|
||||
{CC1101_MDMCFG4,0xCA},
|
||||
{CC1101_MDMCFG3,0x83},
|
||||
{CC1101_MDMCFG2,0x93},
|
||||
{CC1101_DEVIATN,0x35},
|
||||
// {CC1101_MCSM0,0x18}, FS_AUTOCAL = 1, PO_TIMEOUT = 2
|
||||
{CC1101_MCSM0,0x18},
|
||||
{CC1101_FOCCFG,0x16},
|
||||
{CC1101_AGCCTRL2,0x43},
|
||||
{CC1101_FSCAL3,0xEF},
|
||||
{CC1101_FSCAL2,0x2D},
|
||||
{CC1101_FSCAL1,0x25},
|
||||
{CC1101_FSCAL0,0x1F},
|
||||
{CC1101_TEST2,0x81},
|
||||
{CC1101_TEST1,0x35},
|
||||
{CC1101_TEST0,0x09},
|
||||
{0xff,0} // end of table
|
||||
};
|
||||
|
||||
// RF configuration from Dimitry's orginal code
|
||||
// Address Config = No address check
|
||||
// Base Frequency = 902.999756
|
||||
// CRC Autoflush = false
|
||||
// CRC Enable = true
|
||||
// Carrier Frequency = 902.999756
|
||||
// Channel Number = 0
|
||||
// Channel Spacing = 335.632324
|
||||
// Data Format = Normal mode
|
||||
// Data Rate = 249.939
|
||||
// Deviation = 165.039063
|
||||
// Device Address = 22
|
||||
// Manchester Enable = false
|
||||
// Modulated = true
|
||||
// Modulation Format = GFSK
|
||||
// PA Ramping = false
|
||||
// Packet Length = 255
|
||||
// Packet Length Mode = Variable packet length mode. Packet length configured by the first byte after sync word
|
||||
// Preamble Count = 24
|
||||
// RX Filter BW = 650.000000
|
||||
// Sync Word Qualifier Mode = 30/32 sync word bits detected
|
||||
// TX Power = 0
|
||||
// Whitening = true
|
||||
// Rf settings for CC1101
|
||||
// The following was generated by setting the spec for Register to "{CC1101_@RN@,0x@VH@},"
|
||||
const RfSetting gDmitry915[] = {
|
||||
{CC1101_FREQ2,0x22},
|
||||
{CC1101_FREQ1,0xBB},
|
||||
{CC1101_FREQ0,0x13},
|
||||
{CC1101_MDMCFG4,0x1D},
|
||||
{CC1101_MDMCFG3,0x3B},
|
||||
{CC1101_MDMCFG2,0x13},
|
||||
{CC1101_MDMCFG1,0x73},
|
||||
{CC1101_MDMCFG0,0xA7},
|
||||
{CC1101_DEVIATN,0x65},
|
||||
{CC1101_MCSM0,0x18},
|
||||
{CC1101_FOCCFG,0x1E},
|
||||
{CC1101_BSCFG,0x1C},
|
||||
{CC1101_AGCCTRL2,0xC7},
|
||||
{CC1101_AGCCTRL1,0x00},
|
||||
{CC1101_AGCCTRL0,0xB0},
|
||||
{CC1101_FREND1,0xB6},
|
||||
{CC1101_FSCAL3,0xEA},
|
||||
{CC1101_FSCAL2,0x2A},
|
||||
{CC1101_FSCAL1,0x00},
|
||||
{CC1101_FSCAL0,0x1F},
|
||||
{CC1101_TEST0,0x09},
|
||||
{0xff,0} // end of table
|
||||
};
|
||||
|
||||
SubGigData gSubGigData;
|
||||
|
||||
int CheckSubGigState(void);
|
||||
void SubGig_CC1101_reset(void);
|
||||
void SubGig_CC1101_SetConfig(const RfSetting *pConfig);
|
||||
|
||||
static void IRAM_ATTR gpio_isr_handler(void *arg)
|
||||
{
|
||||
gSubGigData.RxAvailable = true;
|
||||
}
|
||||
|
||||
SubGigErr SubGig_radio_init(uint8_t ch)
|
||||
{
|
||||
esp_err_t Err;
|
||||
spi_device_interface_config_t devcfg = {
|
||||
.clock_speed_hz = 5000000, // SPI clock is 5 MHz!
|
||||
.queue_size = 7,
|
||||
.mode = 0, // SPI mode 0
|
||||
.spics_io_num = -1, // we will use manual CS control
|
||||
.flags = SPI_DEVICE_NO_DUMMY
|
||||
};
|
||||
gpio_config_t io_conf = {
|
||||
.intr_type = GPIO_INTR_NEGEDGE, // GPIO interrupt type : falling edge
|
||||
//bit mask of the pins
|
||||
.pin_bit_mask = 1ULL<<CONFIG_GDO0_GPIO,
|
||||
//set as input mode
|
||||
.mode = GPIO_MODE_INPUT,
|
||||
//enable pull-up mode
|
||||
.pull_up_en = 1,
|
||||
.pull_down_en = 0
|
||||
};
|
||||
int ErrLine = 0;
|
||||
SubGigErr Ret = SUBGIG_ERR_NONE;
|
||||
|
||||
do {
|
||||
gpio_reset_pin(CONFIG_CSN_GPIO);
|
||||
gpio_set_direction(CONFIG_CSN_GPIO, GPIO_MODE_OUTPUT);
|
||||
gpio_set_level(CONFIG_CSN_GPIO, 1);
|
||||
|
||||
spi_bus_config_t buscfg = {
|
||||
.sclk_io_num = CONFIG_SCK_GPIO,
|
||||
.mosi_io_num = CONFIG_MOSI_GPIO,
|
||||
.miso_io_num = CONFIG_MISO_GPIO,
|
||||
.quadwp_io_num = -1,
|
||||
.quadhd_io_num = -1
|
||||
};
|
||||
|
||||
if((Err = spi_bus_initialize(HOST_ID,&buscfg,SPI_DMA_CH_AUTO)) != 0) {
|
||||
ErrLine = __LINE__;
|
||||
break;
|
||||
}
|
||||
|
||||
if((Err = spi_bus_add_device(HOST_ID,&devcfg,&gSpiHndl)) != 0) {
|
||||
ErrLine = __LINE__;
|
||||
break;
|
||||
}
|
||||
|
||||
// Configure GDO0, interrupt on falling edge
|
||||
if((Err = gpio_config(&io_conf)) != 0) {
|
||||
ErrLine = __LINE__;
|
||||
break;
|
||||
}
|
||||
|
||||
// Configure GDO2, interrupts disabled
|
||||
io_conf.intr_type = GPIO_INTR_DISABLE;
|
||||
io_conf.pin_bit_mask = 1ULL<<CONFIG_GDO2_GPIO;
|
||||
if((Err = gpio_config(&io_conf)) != 0) {
|
||||
ErrLine = __LINE__;
|
||||
break;
|
||||
}
|
||||
|
||||
// install gpio isr service
|
||||
if((Err = gpio_install_isr_service(0)) != 0) {
|
||||
ErrLine = __LINE__;
|
||||
break;
|
||||
}
|
||||
//hook isr handler for specific gpio pin
|
||||
Err = gpio_isr_handler_add(CONFIG_GDO0_GPIO,gpio_isr_handler,
|
||||
(void*) CONFIG_GDO0_GPIO);
|
||||
if(Err != 0) {
|
||||
ErrLine = __LINE__;
|
||||
break;
|
||||
}
|
||||
// Check Chip ID
|
||||
if(!CC1101_Present()) {
|
||||
Ret = SUBGIG_CC1101_NOT_FOUND;
|
||||
break;
|
||||
}
|
||||
gSubGigData.Present = true;
|
||||
SubGig_CC1101_reset();
|
||||
CC1101_SetConfig(NULL);
|
||||
SubGig_CC1101_SetConfig(gDmitry915);
|
||||
#if 1
|
||||
CC1101_DumpRegs();
|
||||
#endif
|
||||
if(ch != 0) {
|
||||
SubGig_radioSetChannel(ch);
|
||||
}
|
||||
// good to go!
|
||||
Ret = true;
|
||||
} while(false);
|
||||
|
||||
if(ErrLine != 0) {
|
||||
LOG("%s#%d: failed %d\n",__FUNCTION__,ErrLine,Err);
|
||||
}
|
||||
return Ret;
|
||||
}
|
||||
|
||||
SubGigErr SubGig_radioSetChannel(uint8_t ch)
|
||||
{
|
||||
SubGigErr Ret = SUBGIG_ERR_NONE;
|
||||
|
||||
RfSetting SetChannr[2] = {
|
||||
{CC1101_CHANNR,0},
|
||||
{0xff,0} // end of table
|
||||
};
|
||||
|
||||
do {
|
||||
if(!gSubGigData.Enabled && gSubGigData.Present && ch != 0) {
|
||||
gSubGigData.Enabled = true;
|
||||
LOG("SubGhz enabled\n");
|
||||
}
|
||||
if((Ret = CheckSubGigState()) != SUBGIG_ERR_NONE) {
|
||||
break;
|
||||
}
|
||||
if(ch == 0) {
|
||||
// Disable SubGhz
|
||||
LOG("SubGhz disabled\n");
|
||||
gSubGigData.Enabled = false;
|
||||
break;
|
||||
}
|
||||
LOG("Set channel %d\n",ch);
|
||||
|
||||
if(ch >= FIRST_866_CHAN && ch < FIRST_866_CHAN + NUM_866_CHANNELS) {
|
||||
// Base Frequency = 863.999756
|
||||
// total channels 6 (0 -> 5) (CHANNR 0 -> 15)
|
||||
// Channel 100 / CHANNR 0: 863.999756
|
||||
// Channel 101 / CHANNR 3: 865.006 Mhz
|
||||
// Channel 102 / CHANNR 6: 866.014 Mhz
|
||||
// Channel 103 / CHANNR 9: 867.020 Mhz
|
||||
// Channel 104 / CHANNR 12: 868.027 Mhz
|
||||
// Channel 105 / CHANNR 15: 869.034 Mhz
|
||||
SubGig_CC1101_SetConfig(g864Mhz);
|
||||
SetChannr[0].Value = (ch - FIRST_866_CHAN) * 3;
|
||||
}
|
||||
else {
|
||||
// Base Frequency = 902.999756
|
||||
// Dmitry's orginal code used 25 channels in 915 Mhz
|
||||
// We don't want to have to scan that many so for OEPL we'll just use 6
|
||||
// to match 866.
|
||||
// Channel 200 / CHANNR 0: 903.000 Mhz
|
||||
// Channel 201 / CHANNR 12: 907.027 Mhz
|
||||
// Channel 202 / CHANNR 24: 911.054 Mhz
|
||||
// Channel 203 / CHANNR 24: 915.083 Mhz
|
||||
// Channel 204 / CHANNR 48: 919.110 Mhz
|
||||
// Channel 205 / CHANNR 60: 923.138 Mhz
|
||||
SubGig_CC1101_SetConfig(g903Mhz);
|
||||
|
||||
if(ch >= FIRST_915_CHAN && ch < FIRST_915_CHAN + NUM_915_CHANNELS) {
|
||||
SetChannr[0].Value = (ch - FIRST_915_CHAN) * 12;
|
||||
}
|
||||
else {
|
||||
Ret = SUBGIG_INVALID_CHANNEL;
|
||||
SetChannr[0].Value = 0; // default to the first channel on 915
|
||||
}
|
||||
}
|
||||
SubGig_CC1101_SetConfig(SetChannr);
|
||||
} while(false);
|
||||
|
||||
return Ret;
|
||||
}
|
||||
|
||||
SubGigErr SubGig_radioTx(uint8_t *packet)
|
||||
{
|
||||
SubGigErr Ret = SUBGIG_ERR_NONE;
|
||||
|
||||
do {
|
||||
if(gSubGigData.FreqTest) {
|
||||
break;
|
||||
}
|
||||
if((Ret = CheckSubGigState()) != SUBGIG_ERR_NONE) {
|
||||
break;
|
||||
}
|
||||
|
||||
if(packet[0] < 3 || packet[0] > RADIO_MAX_PACKET_LEN + RAW_PKT_PADDING) {
|
||||
Ret = SUBGIG_TX_BAD_LEN;
|
||||
break;
|
||||
}
|
||||
|
||||
// All packets seem to be padded by RAW_PKT_PADDING (2 bytes)
|
||||
// Remove the padding before sending so the length is correct when received
|
||||
packet[0] -= RAW_PKT_PADDING;
|
||||
LOG("Sending %d byte subgig frame:\n",packet[0]);
|
||||
LOG_HEX(&packet[1],packet[0]);
|
||||
if(CC1101_Tx(packet)) {
|
||||
Ret = SUBGIG_TX_FAILED;
|
||||
}
|
||||
// restore original len just in case anyone cares
|
||||
packet[0] += RAW_PKT_PADDING;
|
||||
} while(false);
|
||||
|
||||
return Ret;
|
||||
}
|
||||
|
||||
// returns packet size in bytes data in data
|
||||
int8_t SubGig_commsRxUnencrypted(uint8_t *data)
|
||||
{
|
||||
int RxBytes;
|
||||
int8_t Ret = 0;
|
||||
|
||||
do {
|
||||
if(CheckSubGigState() != SUBGIG_ERR_NONE) {
|
||||
break;
|
||||
}
|
||||
|
||||
if(gSubGigData.FreqTest) {
|
||||
break;
|
||||
}
|
||||
if(gSubGigData.RxAvailable) {
|
||||
gSubGigData.RxAvailable = false;
|
||||
RxBytes = CC1101_Rx(data,128,NULL,NULL);
|
||||
|
||||
if(RxBytes >= 2) {
|
||||
// NB: RxBytes includes the CRC, deduct it
|
||||
Ret = (uint8_t) RxBytes - 2;
|
||||
LOG("Received %d byte subgig frame:\n",Ret);
|
||||
LOG_HEX(data,Ret);
|
||||
}
|
||||
}
|
||||
} while(false);
|
||||
|
||||
return Ret;
|
||||
}
|
||||
|
||||
int CheckSubGigState()
|
||||
{
|
||||
int Err = SUBGIG_ERR_NONE;
|
||||
|
||||
if(!gSubGigData.Present) {
|
||||
Err = SUBGIG_CC1101_NOT_FOUND;
|
||||
}
|
||||
else if(!gSubGigData.Initialized) {
|
||||
Err = SUBGIG_NOT_INITIALIZED;
|
||||
}
|
||||
else if(!gSubGigData.Enabled) {
|
||||
Err = SUBGIG_NOT_ENABLED;
|
||||
}
|
||||
|
||||
if(Err != SUBGIG_ERR_NONE) {
|
||||
LOG("CheckSubGigState: returing %d\n",Err);
|
||||
}
|
||||
|
||||
return Err;
|
||||
}
|
||||
|
||||
SubGigErr SubGig_FreqTest(bool b866Mhz,bool bStart)
|
||||
{
|
||||
SubGigErr Err = SUBGIG_ERR_NONE;
|
||||
#if 0
|
||||
uint8_t TxData = 0; // len = 0
|
||||
|
||||
do {
|
||||
if((Err = CheckSubGigState()) != SUBGIG_ERR_NONE) {
|
||||
break;
|
||||
}
|
||||
if(bStart) {
|
||||
LOG_RAW("Starting %sMhz Freq test\n",b866Mhz ? "866" : "915");
|
||||
SubGig_CC1101_reset();
|
||||
SubGig_CC1101_SetConfig(gCW);
|
||||
SubGig_CC1101_SetConfig(b866Mhz ? g866Mhz : g915Mhz);
|
||||
CC1101_cmdStrobe(CC1101_SIDLE);
|
||||
CC1101_cmdStrobe(CC1101_SFTX); // flush Tx Fifo
|
||||
CC1101_cmdStrobe(CC1101_STX);
|
||||
gRfState = RFSTATE_TX;
|
||||
gSubGigData.FreqTest = true;
|
||||
}
|
||||
else {
|
||||
LOG_RAW("Ending Freq test\n");
|
||||
gSubGigData.FreqTest = false;
|
||||
SubGig_CC1101_reset();
|
||||
SubGig_CC1101_SetConfig(gSubGigData.pConfig);
|
||||
}
|
||||
} while(false);
|
||||
#endif
|
||||
return Err;
|
||||
}
|
||||
|
||||
void SubGig_CC1101_reset()
|
||||
{
|
||||
gSubGigData.Initialized = false;
|
||||
gSubGigData.FixedRegsSet = false;
|
||||
CC1101_reset();
|
||||
}
|
||||
|
||||
void SubGig_CC1101_SetConfig(const RfSetting *pConfig)
|
||||
{
|
||||
CC1101_SetConfig(pConfig);
|
||||
gSubGigData.Initialized = true;
|
||||
}
|
||||
|
||||
void DumpHex(void *AdrIn,int Len)
|
||||
{
|
||||
unsigned char *Adr = (unsigned char *) AdrIn;
|
||||
int i = 0;
|
||||
int j;
|
||||
|
||||
while(i < Len) {
|
||||
for(j = 0; j < 16; j++) {
|
||||
if((i + j) == Len) {
|
||||
break;
|
||||
}
|
||||
LOG_RAW("%02x ",Adr[i+j]);
|
||||
}
|
||||
|
||||
LOG_RAW(" ");
|
||||
for(j = 0; j < 16; j++) {
|
||||
if((i + j) == Len) {
|
||||
break;
|
||||
}
|
||||
if(isprint(Adr[i+j])) {
|
||||
LOG_RAW("%c",Adr[i+j]);
|
||||
}
|
||||
else {
|
||||
LOG_RAW(".");
|
||||
}
|
||||
}
|
||||
i += 16;
|
||||
LOG_RAW("\n");
|
||||
}
|
||||
}
|
||||
#endif // CONFIG_OEPL_SUBGIG_SUPPORT
|
||||
|
||||
40
ARM_Tag_FW/OpenEPaperLink_esp32_C6_AP/main/SubGigRadio.h
Executable file
40
ARM_Tag_FW/OpenEPaperLink_esp32_C6_AP/main/SubGigRadio.h
Executable file
@@ -0,0 +1,40 @@
|
||||
#ifndef _SUBGIG_RADIO_H_
|
||||
#define _SUBGIG_RADIO_H_
|
||||
|
||||
//sub-GHz 866 Mhz channels start at 100
|
||||
#define FIRST_866_CHAN (100)
|
||||
#define NUM_866_CHANNELS (6)
|
||||
|
||||
//sub-GHz 915 Mhz channels start at 200
|
||||
#define FIRST_915_CHAN (200)
|
||||
#define NUM_915_CHANNELS (25)
|
||||
|
||||
typedef enum {
|
||||
SUBGIG_ERR_NONE,
|
||||
SUBGIG_CC1101_NOT_FOUND,
|
||||
SUBGIG_NOT_INITIALIZED,
|
||||
SUBGIG_NOT_ENABLED,
|
||||
SUBGIG_TX_FAILED,
|
||||
SUBGIG_TX_BAD_LEN,
|
||||
SUBGIG_INVALID_CHANNEL,
|
||||
} SubGigErr;
|
||||
|
||||
typedef struct {
|
||||
uint8_t Present:1;
|
||||
uint8_t Enabled:1;
|
||||
uint8_t FreqTest:1;
|
||||
uint8_t RxAvailable:1;
|
||||
uint8_t Initialized:1;
|
||||
uint8_t FixedRegsSet:1;
|
||||
} SubGigData;
|
||||
|
||||
extern SubGigData gSubGigData;
|
||||
|
||||
SubGigErr SubGig_radio_init(uint8_t ch);
|
||||
SubGigErr SubGig_radioTx(uint8_t *packet);
|
||||
SubGigErr SubGig_radioSetChannel(uint8_t ch);
|
||||
int8_t SubGig_commsRxUnencrypted(uint8_t *data);
|
||||
SubGigErr SubGig_FreqTest(bool b866Mhz,bool bStart);
|
||||
|
||||
#endif // _SUBGIG_RADIO_H_
|
||||
|
||||
706
ARM_Tag_FW/OpenEPaperLink_esp32_C6_AP/main/cc1101_radio.c
Executable file
706
ARM_Tag_FW/OpenEPaperLink_esp32_C6_AP/main/cc1101_radio.c
Executable file
@@ -0,0 +1,706 @@
|
||||
// Large portions of this code was copied from:
|
||||
// https://github.com/nopnop2002/esp-idf-cc1101 with the following copyright
|
||||
|
||||
/*
|
||||
* Copyright (c) 2011 panStamp <contact@panstamp.com>
|
||||
* Copyright (c) 2016 Tyler Sommer <contact@tylersommer.pro>
|
||||
*
|
||||
* This file is part of the CC1101 project.
|
||||
*
|
||||
* CC1101 is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* CC1101 is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with CC1101; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
|
||||
* USA
|
||||
*
|
||||
* Author: Daniel Berenguer
|
||||
* Creation date: 03/03/2011
|
||||
*/
|
||||
|
||||
#include "sdkconfig.h"
|
||||
#ifdef CONFIG_OEPL_SUBGIG_SUPPORT
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <driver/spi_master.h>
|
||||
#include "proto.h"
|
||||
#include "cc1101_radio.h"
|
||||
#include "radio.h"
|
||||
|
||||
#define ENABLE_LOGGING 0
|
||||
|
||||
#if ENABLE_LOGGING
|
||||
#define LOG(format, ... ) printf("%s: " format,__FUNCTION__,## __VA_ARGS__)
|
||||
#define LOG_RAW(format, ... ) printf(format,## __VA_ARGS__)
|
||||
#else
|
||||
#define LOG(format, ... )
|
||||
#define LOG_RAW(format, ... )
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
|
||||
#include <driver/spi_master.h>
|
||||
#include <driver/gpio.h>
|
||||
#include "esp_log.h"
|
||||
|
||||
#include "sdkconfig.h"
|
||||
|
||||
/**
|
||||
* RF STATES
|
||||
*/
|
||||
enum RFSTATE {
|
||||
RFSTATE_IDLE = 0,
|
||||
RFSTATE_RX,
|
||||
RFSTATE_TX
|
||||
};
|
||||
|
||||
/**
|
||||
* Type of transfers
|
||||
*/
|
||||
#define WRITE_BURST 0x40
|
||||
#define READ_SINGLE 0x80
|
||||
#define READ_BURST 0xC0
|
||||
|
||||
/**
|
||||
* Type of register
|
||||
*/
|
||||
#define CC1101_CONFIG_REGISTER READ_SINGLE
|
||||
#define CC1101_STATUS_REGISTER READ_BURST
|
||||
|
||||
/**
|
||||
* PATABLE & FIFO's
|
||||
*/
|
||||
#define CC1101_PATABLE 0x3E // PATABLE address
|
||||
#define CC1101_TXFIFO 0x3F // TX FIFO address
|
||||
#define CC1101_RXFIFO 0x3F // RX FIFO address
|
||||
|
||||
/**
|
||||
* Command strobes
|
||||
*/
|
||||
#define CC1101_SRES 0x30 // Reset CC1101 chip
|
||||
#define CC1101_SFSTXON 0x31 // Enable and calibrate frequency synthesizer (if MCSM0.FS_AUTOCAL=1). If in RX (with CCA):
|
||||
// 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. SCAL can be strobed from IDLE mode without
|
||||
// setting manual calibration mode (MCSM0.FS_AUTOCAL=0)
|
||||
#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_SWOR 0x38 // Start automatic RX polling sequence (Wake-on-Radio) as described in Section 19.5 if
|
||||
// WORCTRL.RC_PD=0
|
||||
#define CC1101_SPWD 0x39 // Enter power down mode when CSn goes high
|
||||
#define CC1101_SFRX 0x3A // Flush the RX FIFO buffer. Only issue SFRX in IDLE or RXFIFO_OVERFLOW states
|
||||
#define CC1101_SFTX 0x3B // Flush the TX FIFO buffer. Only issue SFTX in IDLE or TXFIFO_UNDERFLOW states
|
||||
#define CC1101_SWORRST 0x3C // Reset real time clock to Event1 value
|
||||
#define CC1101_SNOP 0x3D // No operation. May be used to get access to the chip status byte
|
||||
|
||||
#define CC1101_STATE_SLEEP 0x00
|
||||
#define CC1101_STATE_IDLE 0x01
|
||||
#define CC1101_STATE_XOFF 0x02
|
||||
#define CC1101_STATE_VCOON_MC 0x03
|
||||
#define CC1101_STATE_REGON_MC 0x04
|
||||
#define CC1101_STATE_MANCAL 0x05
|
||||
#define CC1101_STATE_VCOON 0x06
|
||||
#define CC1101_STATE_REGON 0x07
|
||||
#define CC1101_STATE_STARTCAL 0x08
|
||||
#define CC1101_STATE_BWBOOST 0x09
|
||||
#define CC1101_STATE_FS_LOCK 0x0A
|
||||
#define CC1101_STATE_IFADCON 0x0B
|
||||
#define CC1101_STATE_ENDCAL 0x0C
|
||||
#define CC1101_STATE_RX 0x0D
|
||||
#define CC1101_STATE_RX_END 0x0E
|
||||
#define CC1101_STATE_RX_RST 0x0F
|
||||
#define CC1101_STATE_TXRX_SWITCH 0x10
|
||||
#define CC1101_STATE_RXFIFO_OVERFLOW 0x11
|
||||
#define CC1101_STATE_FSTXON 0x12
|
||||
#define CC1101_STATE_TX 0x13
|
||||
#define CC1101_STATE_TX_END 0x14
|
||||
#define CC1101_STATE_RXTX_SWITCH 0x15
|
||||
#define CC1101_STATE_TXFIFO_UNDERFLOW 0x16
|
||||
|
||||
// Masks for first byte read from RXFIFO
|
||||
#define CC1101_NUM_RXBYTES_MASK 0x7f
|
||||
#define CC1101_RXFIFO_OVERFLOW_MASK 0x80
|
||||
|
||||
// Masks for last byte read from RXFIFO
|
||||
#define CC1101_LQI_MASK 0x7f
|
||||
#define CC1101_CRC_OK_MASK 0x6f
|
||||
|
||||
// IOCFG2 GDO2: high when TX FIFO at or above the TX FIFO threshold
|
||||
#define CC1101_DEFVAL_IOCFG2 0x02
|
||||
#define CC1101_DEFVAL_IOCFG1 0x2E
|
||||
// GDO0 Asserts when sync word has been sent / received, and
|
||||
// de-asserts at the end of the packet.
|
||||
#define CC1101_DEFVAL_IOCFG0 0x06
|
||||
#define CC1101_DEFVAL_FIFOTHR 0x07
|
||||
#define CC1101_DEFVAL_RCCTRL1 0x41
|
||||
#define CC1101_DEFVAL_RCCTRL0 0x00
|
||||
#define CC1101_DEFVAL_AGCTEST 0x3F
|
||||
#define CC1101_DEFVAL_MCSM1 0x20
|
||||
#define CC1101_DEFVAL_WORCTRL 0xFB
|
||||
#define CC1101_DEFVAL_FSCTRL0 40 // Your value may be different!
|
||||
#define CC1101_DEFVAL_PATABLE 0xc0 // full power
|
||||
|
||||
RfSetting gFixedConfig[] = {
|
||||
{CC1101_IOCFG2,CC1101_DEFVAL_IOCFG2},
|
||||
{CC1101_IOCFG1,CC1101_DEFVAL_IOCFG1},
|
||||
{CC1101_IOCFG0,CC1101_DEFVAL_IOCFG0},
|
||||
{CC1101_FIFOTHR,CC1101_DEFVAL_FIFOTHR},
|
||||
{CC1101_FSCTRL0,CC1101_DEFVAL_FSCTRL0},
|
||||
{CC1101_RCCTRL1,CC1101_DEFVAL_RCCTRL1},
|
||||
{CC1101_RCCTRL0,CC1101_DEFVAL_RCCTRL0},
|
||||
{CC1101_MCSM1,CC1101_DEFVAL_MCSM1},
|
||||
{CC1101_WORCTRL,CC1101_DEFVAL_WORCTRL},
|
||||
{0xff,0},
|
||||
};
|
||||
|
||||
void CC1101_readBurstReg(uint8_t *buffer,uint8_t regAddr,uint8_t len);
|
||||
void CC1101_cmdStrobe(uint8_t cmd);
|
||||
void CC1101_wakeUp(void);
|
||||
uint8_t CC1101_readReg(uint8_t regAddr, uint8_t regType);
|
||||
void CC1101_writeReg(uint8_t regAddr, uint8_t value);
|
||||
void CC1101_setRxState(void);
|
||||
void CC1101_setTxState(void);
|
||||
|
||||
spi_device_handle_t gSpiHndl;
|
||||
|
||||
#define readConfigReg(regAddr) CC1101_readReg(regAddr, CC1101_CONFIG_REGISTER)
|
||||
#define readStatusReg(regAddr) CC1101_readReg(regAddr, CC1101_STATUS_REGISTER)
|
||||
#define setIdleState() CC1101_cmdStrobe(CC1101_SIDLE)
|
||||
#define flushRxFifo() CC1101_cmdStrobe(CC1101_SFRX)
|
||||
#define flushTxFifo() CC1101_cmdStrobe(CC1101_SFTX)
|
||||
|
||||
const char *RegNamesCC1101[] = {
|
||||
"IOCFG2", // 0x00 GDO2 output pin configuration
|
||||
"IOCFG1", // 0x01 GDO1 output pin configuration
|
||||
"IOCFG0", // 0x02 GDO0 output pin configuration
|
||||
"FIFOTHR", // 0x03 RX FIFO and TX FIFO thresholds
|
||||
"SYNC1", // 0x04 Sync word, high INT8U
|
||||
"SYNC0", // 0x05 Sync word, low INT8U
|
||||
"PKTLEN", // 0x06 Packet length
|
||||
"PKTCTRL1", // 0x07 Packet automation control
|
||||
"PKTCTRL0", // 0x08 Packet automation control
|
||||
"ADDR", // 0x09 Device address
|
||||
"CHANNR", // 0x0A Channel number
|
||||
"FSCTRL1", // 0x0B Frequency synthesizer control
|
||||
"FSCTRL0", // 0x0C Frequency synthesizer control
|
||||
"FREQ2", // 0x0D Frequency control word, high INT8U
|
||||
"FREQ1", // 0x0E Frequency control word, middle INT8U
|
||||
"FREQ0", // 0x0F Frequency control word, low INT8U
|
||||
"MDMCFG4", // 0x10 Modem configuration
|
||||
"MDMCFG3", // 0x11 Modem configuration
|
||||
"MDMCFG2", // 0x12 Modem configuration
|
||||
"MDMCFG1", // 0x13 Modem configuration
|
||||
"MDMCFG0", // 0x14 Modem configuration
|
||||
"DEVIATN", // 0x15 Modem deviation setting
|
||||
"MCSM2", // 0x16 Main Radio Control State Machine configuration
|
||||
"MCSM1", // 0x17 Main Radio Control State Machine configuration
|
||||
"MCSM0", // 0x18 Main Radio Control State Machine configuration
|
||||
"FOCCFG", // 0x19 Frequency Offset Compensation configuration
|
||||
"BSCFG", // 0x1A Bit Synchronization configuration
|
||||
"AGCCTRL2", // 0x1B AGC control
|
||||
"AGCCTRL1", // 0x1C AGC control
|
||||
"AGCCTRL0", // 0x1D AGC control
|
||||
"WOREVT1", // 0x1E High INT8U Event 0 timeout
|
||||
"WOREVT0", // 0x1F Low INT8U Event 0 timeout
|
||||
"WORCTRL", // 0x20 Wake On Radio control
|
||||
"FREND1", // 0x21 Front end RX configuration
|
||||
"FREND0", // 0x22 Front end TX configuration
|
||||
"FSCAL3", // 0x23 Frequency synthesizer calibration
|
||||
"FSCAL2", // 0x24 Frequency synthesizer calibration
|
||||
"FSCAL1", // 0x25 Frequency synthesizer calibration
|
||||
"FSCAL0", // 0x26 Frequency synthesizer calibration
|
||||
"RCCTRL1", // 0x27 RC oscillator configuration
|
||||
"RCCTRL0", // 0x28 RC oscillator configuration
|
||||
"FSTEST", // 0x29 Frequency synthesizer calibration control
|
||||
"PTEST", // 0x2A Production test
|
||||
"AGCTEST", // 0x2B AGC test
|
||||
"TEST2", // 0x2C Various test settings
|
||||
"TEST1", // 0x2D Various test settings
|
||||
"TEST0", // 0x2E Various test settings
|
||||
"0x2f", // 0x2f
|
||||
//CC1101 Strobe commands
|
||||
"SRES", // 0x30 Reset chip.
|
||||
"SFSTXON", // 0x31 Enable and calibrate frequency synthesizer (if MCSM0.FS_AUTOCAL=1).
|
||||
"SXOFF", // 0x32 Turn off crystal oscillator.
|
||||
"SCAL", // 0x33 Calibrate frequency synthesizer and turn it off
|
||||
"SRX", // 0x34 Enable RX. Perform calibration first if coming from IDLE and
|
||||
"STX", // 0x35 In IDLE state: Enable TX. Perform calibration first if
|
||||
"SIDLE", // 0x36 Exit RX / TX, turn off frequency synthesizer and exit
|
||||
"SAFC", // 0x37 Perform AFC adjustment of the frequency synthesizer
|
||||
"SWOR", // 0x38 Start automatic RX polling sequence (Wake-on-Radio)
|
||||
"SPWD", // 0x39 Enter power down mode when CSn goes high.
|
||||
"SFRX", // 0x3A Flush the RX FIFO buffer.
|
||||
"SFTX", // 0x3B Flush the TX FIFO buffer.
|
||||
"SWORRST", // 0x3C Reset real time clock.
|
||||
"SNOP", // 0x3D No operation. May be used to pad strobe commands to two
|
||||
"PATABLE" // 0x3E
|
||||
};
|
||||
|
||||
|
||||
// SPI Stuff
|
||||
#if CONFIG_SPI2_HOST
|
||||
#define HOST_ID SPI2_HOST
|
||||
#elif CONFIG_SPI3_HOST
|
||||
#define HOST_ID SPI3_HOST
|
||||
#endif
|
||||
|
||||
/*
|
||||
* RF state
|
||||
*/
|
||||
static uint8_t gRfState;
|
||||
|
||||
#define cc1101_Select() gpio_set_level(CONFIG_CSN_GPIO, LOW)
|
||||
#define cc1101_Deselect() gpio_set_level(CONFIG_CSN_GPIO, HIGH)
|
||||
#define wait_Miso() while(gpio_get_level(CONFIG_MISO_GPIO)>0)
|
||||
#define getGDO0state() gpio_get_level(CONFIG_GDO0_GPIO)
|
||||
#define wait_GDO0_high() while(!getGDO0state())
|
||||
#define wait_GDO0_low() while(getGDO0state())
|
||||
#define getGDO2state() gpio_get_level(CONFIG_GDO2_GPIO)
|
||||
#define wait_GDO2_low() while(getGDO2state())
|
||||
|
||||
/**
|
||||
* Arduino Macros
|
||||
*/
|
||||
#define bitRead(value, bit) (((value) >> (bit)) & 0x01)
|
||||
#define bitSet(value, bit) ((value) |= (1UL << (bit)))
|
||||
#define bitClear(value, bit) ((value) &= ~(1UL << (bit)))
|
||||
#define bitWrite(value, bit, bitvalue) ((bitvalue) ? bitSet(value, bit) : bitClear(value, bit))
|
||||
#define delayMicroseconds(us) esp_rom_delay_us(us)
|
||||
#define LOW 0
|
||||
#define HIGH 1
|
||||
|
||||
bool spi_write_byte(uint8_t* Dataout,size_t DataLength)
|
||||
{
|
||||
spi_transaction_t SPITransaction;
|
||||
|
||||
if(DataLength > 0) {
|
||||
memset(&SPITransaction,0,sizeof(spi_transaction_t));
|
||||
SPITransaction.length = DataLength * 8;
|
||||
SPITransaction.tx_buffer = Dataout;
|
||||
SPITransaction.rx_buffer = NULL;
|
||||
spi_device_transmit(gSpiHndl,&SPITransaction);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool spi_read_byte(uint8_t* Datain,uint8_t* Dataout,size_t DataLength)
|
||||
{
|
||||
spi_transaction_t SPITransaction;
|
||||
|
||||
if(DataLength > 0) {
|
||||
memset(&SPITransaction,0,sizeof(spi_transaction_t));
|
||||
SPITransaction.length = DataLength * 8;
|
||||
SPITransaction.tx_buffer = Dataout;
|
||||
SPITransaction.rx_buffer = Datain;
|
||||
spi_device_transmit(gSpiHndl,&SPITransaction);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
uint8_t spi_transfer(uint8_t address)
|
||||
{
|
||||
uint8_t datain[1];
|
||||
uint8_t dataout[1];
|
||||
dataout[0] = address;
|
||||
//spi_write_byte(dev, dataout, 1 );
|
||||
//spi_read_byte(datain, dataout, 1 );
|
||||
|
||||
spi_transaction_t SPITransaction;
|
||||
memset(&SPITransaction,0,sizeof(spi_transaction_t));
|
||||
SPITransaction.length = 8;
|
||||
SPITransaction.tx_buffer = dataout;
|
||||
SPITransaction.rx_buffer = datain;
|
||||
spi_device_transmit(gSpiHndl,&SPITransaction);
|
||||
|
||||
return datain[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* CC1101_wakeUp
|
||||
*
|
||||
* Wake up CC1101 from Power Down state
|
||||
*/
|
||||
void CC1101_wakeUp(void)
|
||||
{
|
||||
cc1101_Select();
|
||||
wait_Miso();
|
||||
cc1101_Deselect();
|
||||
}
|
||||
|
||||
/**
|
||||
* CC1101_writeReg
|
||||
*
|
||||
* Write single register into the CC1101 IC via SPI
|
||||
*
|
||||
* @param regAddr Register address
|
||||
* @param value Value to be writen
|
||||
*/
|
||||
void CC1101_writeReg(uint8_t regAddr, uint8_t value)
|
||||
{
|
||||
if(regAddr < 0x3f) {
|
||||
LOG("0x%x -> %s(0x%x)\n",value,RegNamesCC1101[regAddr],regAddr);
|
||||
}
|
||||
else {
|
||||
LOG("0x%x -> 0x%x\n",value,regAddr);
|
||||
}
|
||||
cc1101_Select(); // Select CC1101
|
||||
wait_Miso(); // Wait until MISO goes low
|
||||
spi_transfer(regAddr); // Send register address
|
||||
spi_transfer(value); // Send value
|
||||
cc1101_Deselect(); // Deselect CC1101
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* CC1101_cmdStrobe
|
||||
*
|
||||
* Send command strobe to the CC1101 IC via SPI
|
||||
*
|
||||
* @param cmd Command strobe
|
||||
*/
|
||||
void CC1101_cmdStrobe(uint8_t cmd)
|
||||
{
|
||||
cc1101_Select();
|
||||
wait_Miso();
|
||||
spi_transfer(cmd);
|
||||
cc1101_Deselect();
|
||||
}
|
||||
|
||||
/**
|
||||
* CC1101_readReg
|
||||
*
|
||||
* Read CC1101 register via SPI
|
||||
*
|
||||
* @param regAddr Register address
|
||||
* @param regType Type of register: CONFIG_REGISTER or STATUS_REGISTER
|
||||
*
|
||||
* Return:
|
||||
* Data uint8_t returned by the CC1101 IC
|
||||
*/
|
||||
uint8_t CC1101_readReg(uint8_t regAddr,uint8_t regType)
|
||||
{
|
||||
uint8_t addr, val;
|
||||
|
||||
addr = regAddr | regType;
|
||||
cc1101_Select();
|
||||
wait_Miso();
|
||||
spi_transfer(addr);
|
||||
val = spi_transfer(0x00); // Read result
|
||||
cc1101_Deselect();
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
/**
|
||||
* CC1101_readBurstReg
|
||||
*
|
||||
* Read burst data from CC1101 via SPI
|
||||
*
|
||||
* @param buffer Buffer where to copy the result to
|
||||
* @param regAddr Register address
|
||||
* @param len Data length
|
||||
*/
|
||||
void CC1101_readBurstReg(uint8_t *buffer,uint8_t regAddr,uint8_t len)
|
||||
{
|
||||
uint8_t addr, i;
|
||||
|
||||
addr = regAddr | READ_BURST;
|
||||
cc1101_Select();
|
||||
wait_Miso();
|
||||
spi_transfer(addr); // Send register address
|
||||
for(i = 0; i < len; i++) {
|
||||
buffer[i] = spi_transfer(0x00); // Read result uint8_t by uint8_t
|
||||
}
|
||||
cc1101_Deselect();
|
||||
}
|
||||
|
||||
/**
|
||||
* reset
|
||||
*
|
||||
* Reset CC1101
|
||||
*/
|
||||
void CC1101_reset(void)
|
||||
{
|
||||
// See sectin 19.1.2 of the CC1101 spec sheet for reasons for the following
|
||||
cc1101_Deselect();
|
||||
delayMicroseconds(5);
|
||||
cc1101_Select();
|
||||
delayMicroseconds(10);
|
||||
cc1101_Deselect();
|
||||
delayMicroseconds(41);
|
||||
cc1101_Select();
|
||||
|
||||
// Wait until MISO goes low indicating XOSC stable
|
||||
wait_Miso();
|
||||
spi_transfer(CC1101_SRES); // Send reset command strobe
|
||||
wait_Miso();
|
||||
cc1101_Deselect();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* CC1101_setRxState
|
||||
*
|
||||
* Enter Rx state
|
||||
*/
|
||||
void CC1101_setRxState(void)
|
||||
{
|
||||
CC1101_cmdStrobe(CC1101_SRX);
|
||||
gRfState = RFSTATE_RX;
|
||||
}
|
||||
|
||||
/**
|
||||
* CC1101_setTxState
|
||||
*
|
||||
* Enter Tx state
|
||||
*/
|
||||
void CC1101_setTxState(void)
|
||||
{
|
||||
CC1101_cmdStrobe(CC1101_STX);
|
||||
gRfState = RFSTATE_TX;
|
||||
}
|
||||
|
||||
|
||||
void CC1101_DumpRegs()
|
||||
{
|
||||
#if ENABLE_LOGGING
|
||||
uint8_t regAddr;
|
||||
uint8_t value;
|
||||
|
||||
LOG("\n");
|
||||
for(regAddr = 0; regAddr < 0x2f; regAddr++) {
|
||||
value = CC1101_readReg(regAddr,READ_SINGLE);
|
||||
LOG("%02x %s: 0x%02X\n",regAddr,RegNamesCC1101[regAddr],value);
|
||||
}
|
||||
|
||||
#if 0
|
||||
for(regAddr = 0; regAddr < 0x2f; regAddr++) {
|
||||
value = CC1101_readReg(regAddr,READ_SINGLE);
|
||||
LOG("<Register><Name>%s</Name><Value>0x%02X</Value></Register>\n",RegNamesCC1101[regAddr],value);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
bool CC1101_Tx(uint8_t *TxData)
|
||||
{
|
||||
bool Ret = false;
|
||||
int ErrLine = 0;
|
||||
spi_transaction_t SPITransaction;
|
||||
uint8_t BytesSent = 0;
|
||||
uint8_t Bytes2Send;
|
||||
uint8_t len;
|
||||
uint8_t CanSend;
|
||||
esp_err_t Err;
|
||||
|
||||
do {
|
||||
// The first byte in the buffer is the number of data bytes to send,
|
||||
// we also need to send the first byte
|
||||
len = 1 + *TxData;
|
||||
memset(&SPITransaction,0,sizeof(spi_transaction_t));
|
||||
SPITransaction.tx_buffer = TxData;
|
||||
|
||||
setIdleState();
|
||||
flushTxFifo();
|
||||
|
||||
while(BytesSent < len) {
|
||||
Bytes2Send = len - BytesSent;
|
||||
if(BytesSent == 0) {
|
||||
// First chunk, the FIFO is empty and can take 64 bytes
|
||||
if(Bytes2Send > 64) {
|
||||
Bytes2Send = 64;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Not the first chunk, we can only send FIFO_THRESHOLD bytes
|
||||
// and only when GDO2 says we can
|
||||
if(getGDO2state()) {
|
||||
wait_GDO2_low();
|
||||
}
|
||||
CanSend = readStatusReg(CC1101_TXBYTES);
|
||||
if(CanSend & 0x80) {
|
||||
LOG("TX FIFO underflow, BytesSent %d\n",BytesSent);
|
||||
ErrLine = __LINE__;
|
||||
break;
|
||||
}
|
||||
CanSend = 64 - CanSend;
|
||||
if(CanSend == 0) {
|
||||
LOG("CanSend == 0, GDO2 problem\n");
|
||||
ErrLine = __LINE__;
|
||||
break;
|
||||
}
|
||||
|
||||
if(Bytes2Send > CanSend) {
|
||||
Bytes2Send = CanSend;
|
||||
}
|
||||
}
|
||||
SPITransaction.length = Bytes2Send * 8;
|
||||
SPITransaction.rxlength = 0;
|
||||
cc1101_Select();
|
||||
wait_Miso();
|
||||
spi_transfer(CC1101_TXFIFO | WRITE_BURST);
|
||||
if((Err = spi_device_transmit(gSpiHndl,&SPITransaction)) != ESP_OK) {
|
||||
ErrLine = __LINE__;
|
||||
LOG("spi_device_transmit failed %d\n",Err);
|
||||
break;
|
||||
}
|
||||
cc1101_Deselect();
|
||||
// LOG("Sending %d bytes\n",Bytes2Send);
|
||||
if(BytesSent == 0) {
|
||||
// some or all of the tx data has been written to the FIFO,
|
||||
// start transmitting
|
||||
// LOG("Start tx\n");
|
||||
CC1101_setTxState();
|
||||
// Wait for the sync word to be transmitted
|
||||
wait_GDO0_high();
|
||||
}
|
||||
SPITransaction.tx_buffer += Bytes2Send;
|
||||
BytesSent += Bytes2Send;
|
||||
}
|
||||
|
||||
// Wait until the end of the TxData transmission
|
||||
wait_GDO0_low();
|
||||
Ret = true;
|
||||
} while(false);
|
||||
|
||||
setIdleState();
|
||||
CC1101_setRxState();
|
||||
|
||||
if(ErrLine != 0) {
|
||||
LOG("%s#%d: failure\n",__FUNCTION__,ErrLine);
|
||||
}
|
||||
|
||||
return Ret;
|
||||
}
|
||||
|
||||
int CC1101_Rx(uint8_t *RxBuf,size_t RxBufLen,uint8_t *pRssi,uint8_t *pLqi)
|
||||
{
|
||||
uint8_t rxBytes = readStatusReg(CC1101_RXBYTES);
|
||||
uint8_t Rssi;
|
||||
uint8_t Lqi;
|
||||
int Ret;
|
||||
|
||||
Ret = rxBytes & CC1101_NUM_RXBYTES_MASK;
|
||||
// Any uint8_t waiting to be read and no overflow?
|
||||
if(rxBytes & CC1101_RXFIFO_OVERFLOW_MASK) {
|
||||
LOG("RxFifo overflow\n");
|
||||
Ret = -2;
|
||||
}
|
||||
else if(Ret != 0) {
|
||||
// Read RxBuf length
|
||||
Ret = readConfigReg(CC1101_RXFIFO);
|
||||
// If TxData is too long
|
||||
if(Ret > RxBufLen) {
|
||||
// Toss the data
|
||||
LOG("RxBuf too small %d < %d\n",RxBufLen,Ret);
|
||||
Ret = -1;
|
||||
}
|
||||
else {
|
||||
// Read RxBuf TxData
|
||||
CC1101_readBurstReg(RxBuf,CC1101_RXFIFO,Ret);
|
||||
// Read RSSI
|
||||
Rssi = readConfigReg(CC1101_RXFIFO);
|
||||
// Read LQI and CRC_OK
|
||||
Lqi = readConfigReg(CC1101_RXFIFO);
|
||||
if(Lqi & CC1101_CRC_OK_MASK) {
|
||||
// CRC is valid
|
||||
if(pRssi != NULL) {
|
||||
*pRssi = Rssi;
|
||||
}
|
||||
if(pLqi != NULL) {
|
||||
*pLqi = Lqi & CC1101_LQI_MASK;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Crc error, ignore the packet
|
||||
Ret = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setIdleState();
|
||||
flushRxFifo();
|
||||
CC1101_setRxState();
|
||||
|
||||
return Ret;
|
||||
}
|
||||
|
||||
bool CC1101_Present()
|
||||
{
|
||||
bool Ret = false;
|
||||
uint8_t PartNum = CC1101_readReg(CC1101_PARTNUM, CC1101_STATUS_REGISTER);
|
||||
uint8_t ChipVersion = CC1101_readReg(CC1101_VERSION, CC1101_STATUS_REGISTER);
|
||||
|
||||
if(PartNum == 0 && ChipVersion == 20) {
|
||||
LOG("CC1101 detected\n");
|
||||
Ret = true;
|
||||
}
|
||||
|
||||
return Ret;
|
||||
}
|
||||
|
||||
void CC1101_SetConfig(const RfSetting *pConfig)
|
||||
{
|
||||
int i;
|
||||
uint8_t RegWasSet[CC1101_TEST0 + 1];
|
||||
uint8_t Reg;
|
||||
|
||||
memset(RegWasSet,0,sizeof(RegWasSet));
|
||||
|
||||
if(pConfig == NULL) {
|
||||
// Just set the fixed registers
|
||||
LOG("Setting fixed registers\n");
|
||||
for(i = 0; (Reg = gFixedConfig[i].Reg) != 0xff; i++) {
|
||||
CC1101_writeReg(Reg,gFixedConfig[i].Value);
|
||||
}
|
||||
// Set TX power
|
||||
CC1101_writeReg(CC1101_PATABLE,CC1101_DEFVAL_PATABLE);
|
||||
}
|
||||
else {
|
||||
for(i = 0; (Reg = gFixedConfig[i].Reg) != 0xff; i++) {
|
||||
RegWasSet[Reg] = 1;
|
||||
}
|
||||
|
||||
while((Reg = pConfig->Reg) != 0xff) {
|
||||
if(RegWasSet[Reg] == 1) {
|
||||
LOG("%s value ignored\n",RegNamesCC1101[Reg]);
|
||||
}
|
||||
else {
|
||||
if(RegWasSet[Reg] == 2) {
|
||||
LOG("%s value set before\n",RegNamesCC1101[Reg]);
|
||||
}
|
||||
CC1101_writeReg(pConfig->Reg,pConfig->Value);
|
||||
RegWasSet[Reg] = 2;
|
||||
}
|
||||
pConfig++;
|
||||
}
|
||||
#if 0
|
||||
for(Reg = 0; Reg <= CC1101_TEST0; Reg++) {
|
||||
if(RegWasSet[Reg] == 0) {
|
||||
LOG("%s value not set\n",RegNamesCC1101[Reg]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#endif // CONFIG_OEPL_SUBGIG_SUPPORT
|
||||
|
||||
116
ARM_Tag_FW/OpenEPaperLink_esp32_C6_AP/main/cc1101_radio.h
Executable file
116
ARM_Tag_FW/OpenEPaperLink_esp32_C6_AP/main/cc1101_radio.h
Executable file
@@ -0,0 +1,116 @@
|
||||
// Large portions of this code was copied from:
|
||||
// https://github.com/nopnop2002/esp-idf-cc1101 with the following copyright
|
||||
|
||||
/*
|
||||
* Copyright (c) 2011 panStamp <contact@panstamp.com>
|
||||
* Copyright (c) 2016 Tyler Sommer <contact@tylersommer.pro>
|
||||
*
|
||||
* This file is part of the CC1101 project.
|
||||
*
|
||||
* CC1101 is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* CC1101 is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with CC1101; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
|
||||
* USA
|
||||
*
|
||||
* Author: Daniel Berenguer
|
||||
* Creation date: 03/03/2011
|
||||
*/
|
||||
|
||||
#ifndef __CC1101_RADIO_H_
|
||||
#define __CC1101_RADIO_H_
|
||||
|
||||
/**
|
||||
* CC1101 configuration registers
|
||||
*/
|
||||
#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 Byte
|
||||
#define CC1101_SYNC0 0x05 // Sync Word, Low Byte
|
||||
#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 Byte
|
||||
#define CC1101_FREQ1 0x0E // Frequency Control Word, Middle Byte
|
||||
#define CC1101_FREQ0 0x0F // Frequency Control Word, Low Byte
|
||||
#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 Byte Event0 Timeout
|
||||
#define CC1101_WOREVT0 0x1F // Low Byte Event0 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
|
||||
|
||||
/**
|
||||
* Status registers
|
||||
*/
|
||||
#define CC1101_PARTNUM 0x30 // Chip ID
|
||||
#define CC1101_VERSION 0x31 // Chip ID
|
||||
#define CC1101_FREQEST 0x32 // Frequency Offset Estimate from Demodulator
|
||||
#define CC1101_LQI 0x33 // Demodulator Estimate for Link Quality
|
||||
#define CC1101_RSSI 0x34 // Received Signal Strength Indication
|
||||
#define CC1101_MARCSTATE 0x35 // Main Radio Control State Machine State
|
||||
#define CC1101_WORTIME1 0x36 // High Byte of WOR Time
|
||||
#define CC1101_WORTIME0 0x37 // Low Byte of WOR Time
|
||||
#define CC1101_PKTSTATUS 0x38 // Current GDOx Status and Packet Status
|
||||
#define CC1101_VCO_VC_DAC 0x39 // Current Setting from PLL Calibration Module
|
||||
#define CC1101_TXBYTES 0x3A // Underflow and Number of Bytes
|
||||
#define CC1101_RXBYTES 0x3B // Overflow and Number of Bytes
|
||||
#define CC1101_RCCTRL1_STATUS 0x3C // Last RC Oscillator Calibration Result
|
||||
#define CC1101_RCCTRL0_STATUS 0x3D // Last RC Oscillator Calibration Result
|
||||
|
||||
typedef struct {
|
||||
uint16_t Reg;
|
||||
uint8_t Value;
|
||||
} RfSetting;
|
||||
|
||||
extern spi_device_handle_t gSpiHndl;
|
||||
|
||||
void CC1101_SetConfig(const RfSetting *pConfig);
|
||||
int CC1101_Rx(uint8_t *RxBuf,size_t RxBufLen,uint8_t *pRssi,uint8_t *pLqi);
|
||||
bool CC1101_Tx(uint8_t *TxData);
|
||||
bool CC1101_Present(void);
|
||||
void CC1101_DumpRegs(void);
|
||||
void CC1101_reset(void);
|
||||
|
||||
#endif // __CC1101_RADIO_H_
|
||||
|
||||
@@ -26,6 +26,8 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include "SubGigRadio.h"
|
||||
|
||||
|
||||
static const char *TAG = "MAIN";
|
||||
|
||||
@@ -66,6 +68,8 @@ uint32_t lastBlockRequest = 0;
|
||||
uint8_t lastBlockMac[8];
|
||||
uint8_t lastTagReturn[8];
|
||||
|
||||
#define NO_SUBGHZ_CHANNEL 255
|
||||
uint8_t curSubGhzChannel;
|
||||
uint8_t curChannel = 25;
|
||||
uint8_t curPower = 10;
|
||||
|
||||
@@ -320,7 +324,20 @@ void processSerial(uint8_t lastchar) {
|
||||
bytesRemain--;
|
||||
if (bytesRemain == 0) {
|
||||
if (checkCRC(serialbuffer, sizeof(struct espSetChannelPower))) {
|
||||
struct espSetChannelPower *scp = (struct espSetChannelPower *) serialbuffer;
|
||||
struct espSetChannelPower *scp = (struct espSetChannelPower *) serialbuffer;
|
||||
#ifdef CONFIG_OEPL_SUBGIG_SUPPORT
|
||||
if(curSubGhzChannel != scp->subghzchannel
|
||||
&& curSubGhzChannel != NO_SUBGHZ_CHANNEL)
|
||||
{
|
||||
curSubGhzChannel = scp->subghzchannel;
|
||||
ESP_LOGI(TAG,"Set SubGhz channel: %d",curSubGhzChannel);
|
||||
SubGig_radioSetChannel(scp->subghzchannel);
|
||||
if(scp->channel == 0) {
|
||||
// Not setting 802.15.4 channel
|
||||
goto SCPchannelFound;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
for (uint8_t c = 0; c < sizeof(channelList); c++) {
|
||||
if (channelList[c] == scp->channel) goto SCPchannelFound;
|
||||
}
|
||||
@@ -405,6 +422,9 @@ void espNotifyAPInfo() {
|
||||
pr("%02X%02X", mSelfMac[4], mSelfMac[5]);
|
||||
pr("%02X%02X", mSelfMac[6], mSelfMac[7]);
|
||||
pr("ZCH>%02X", curChannel);
|
||||
#ifdef CONFIG_OEPL_SUBGIG_SUPPORT
|
||||
pr("SCH>%03d",curSubGhzChannel);
|
||||
#endif
|
||||
pr("ZPW>%02X", curPower);
|
||||
countSlots();
|
||||
pr("PEN>%02X", curPendingData);
|
||||
@@ -684,6 +704,12 @@ void sendPong(void *buf) {
|
||||
struct MacFrameBcast *rxframe = (struct MacFrameBcast *) buf;
|
||||
struct MacFrameNormal *frameHeader = (struct MacFrameNormal *) (radiotxbuffer + 1);
|
||||
radiotxbuffer[sizeof(struct MacFrameNormal) + 1] = PKT_PONG;
|
||||
#ifdef CONFIG_OEPL_SUBGIG_SUPPORT
|
||||
if(rxframe->srcPan == PROTO_PAN_ID_SUBGHZ) {
|
||||
radiotxbuffer[sizeof(struct MacFrameNormal) + 2] = curSubGhzChannel;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
radiotxbuffer[sizeof(struct MacFrameNormal) + 2] = curChannel;
|
||||
radiotxbuffer[0] = sizeof(struct MacFrameNormal) + 1 + 1 + RAW_PKT_PADDING;
|
||||
memcpy(frameHeader->src, mSelfMac, 8);
|
||||
@@ -707,6 +733,16 @@ void app_main(void) {
|
||||
memset(pendingDataArr, 0, sizeof(pendingDataArr));
|
||||
|
||||
radio_init(curChannel);
|
||||
#ifdef CONFIG_OEPL_SUBGIG_SUPPORT
|
||||
if(!SubGig_radio_init(curSubGhzChannel)) {
|
||||
// Ether we don't have a cc1101 or it's not working
|
||||
curSubGhzChannel = NO_SUBGHZ_CHANNEL;
|
||||
ESP_LOGI(TAG,"CC1101 NOT detected.");
|
||||
}
|
||||
else {
|
||||
ESP_LOGI(TAG,"CC1101 detected.");
|
||||
}
|
||||
#endif
|
||||
radioSetTxPower(10);
|
||||
|
||||
pr("RES>");
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#define LED2 23
|
||||
|
||||
#define PROTO_PAN_ID (0x4447) // PAN ID compression shall be used
|
||||
#define PROTO_PAN_ID_SUBGHZ (0x1337) // PAN ID compression shall be used
|
||||
|
||||
#define RADIO_MAX_PACKET_LEN (125) // useful payload, not including the crc
|
||||
|
||||
@@ -178,6 +179,9 @@ struct espSetChannelPower {
|
||||
uint8_t checksum;
|
||||
uint8_t channel;
|
||||
uint8_t power;
|
||||
#ifdef CONFIG_OEPL_SUBGIG_SUPPORT
|
||||
uint8_t subghzchannel;
|
||||
#endif
|
||||
} __attribute__((packed, aligned(1)));
|
||||
|
||||
struct espTagReturnData {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#include <stddef.h>
|
||||
#include "radio.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "driver/uart.h"
|
||||
@@ -23,6 +24,8 @@
|
||||
#include <math.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include "SubGigRadio.h"
|
||||
|
||||
|
||||
static const char *TAG = "RADIO";
|
||||
|
||||
@@ -91,7 +94,12 @@ void radio_init(uint8_t ch) {
|
||||
|
||||
// uint32_t lastZbTx = 0;
|
||||
bool radioTx(uint8_t *packet) {
|
||||
#ifdef CONFIG_OEPL_SUBGIG_SUPPORT
|
||||
// The subghz driver uses DMA
|
||||
static DMA_ATTR uint8_t txPKT[130];
|
||||
#else
|
||||
static uint8_t txPKT[130];
|
||||
#endif
|
||||
led_flash(1);
|
||||
while (isInTransmit) {
|
||||
}
|
||||
@@ -99,6 +107,13 @@ bool radioTx(uint8_t *packet) {
|
||||
// }
|
||||
// lastZbTx = getMillis();
|
||||
memcpy(txPKT, packet, packet[0]);
|
||||
#ifdef CONFIG_OEPL_SUBGIG_SUPPORT
|
||||
struct MacFrameNormal *txHeader = (struct MacFrameNormal *) (packet + 1);
|
||||
|
||||
if(txHeader->pan == PROTO_PAN_ID_SUBGHZ) {
|
||||
return SubGig_radioTx(packet);
|
||||
}
|
||||
#endif
|
||||
isInTransmit = 1;
|
||||
esp_ieee802154_transmit(txPKT, false);
|
||||
return true;
|
||||
@@ -116,5 +131,13 @@ int8_t commsRxUnencrypted(uint8_t *data) {
|
||||
memcpy(data, &inner_rxPKT_out[1], inner_rxPKT_out[0] + 1);
|
||||
return inner_rxPKT_out[0] - 2;
|
||||
}
|
||||
#ifdef CONFIG_OEPL_SUBGIG_SUPPORT
|
||||
if(gSubGigData.Enabled) {
|
||||
int8_t Ret = SubGig_commsRxUnencrypted(data);
|
||||
if(Ret > 0) {
|
||||
return Ret;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2,10 +2,19 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define RAW_PKT_PADDING 2
|
||||
extern uint8_t mSelfMac[8];
|
||||
|
||||
void radio_init(uint8_t ch);
|
||||
bool radioTx(uint8_t *packet);
|
||||
void radioSetChannel(uint8_t ch);
|
||||
void radioSetTxPower(uint8_t power);
|
||||
int8_t commsRxUnencrypted(uint8_t *data);
|
||||
int8_t commsRxUnencrypted(uint8_t *data);
|
||||
|
||||
#ifdef SUBGIG_SUPPORT
|
||||
void SubGig_radio_init(uint8_t ch);
|
||||
bool SubGig_radioTx(uint8_t *packet);
|
||||
void SubGig_radioSetChannel(uint8_t ch);
|
||||
void SubGig_radioSetTxPower(uint8_t power);
|
||||
int8_t SubGig_commsRxUnencrypted(uint8_t *data);
|
||||
#endif
|
||||
@@ -6,3 +6,5 @@ CONFIG_ESPTOOLPY_FLASHMODE_QIO=y
|
||||
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
|
||||
CONFIG_ESPTOOLPY_HEADER_FLASHSIZE_UPDATE=y
|
||||
CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||
CONFIG_OEPL_SUBGIG_SUPPORT=y
|
||||
|
||||
|
||||
Reference in New Issue
Block a user