init
This commit is contained in:
13
.devcontainer/Dockerfile
Normal file
13
.devcontainer/Dockerfile
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
ARG DOCKER_TAG=latest
|
||||||
|
FROM espressif/idf:${DOCKER_TAG}
|
||||||
|
|
||||||
|
ENV LC_ALL=C.UTF-8
|
||||||
|
ENV LANG=C.UTF-8
|
||||||
|
|
||||||
|
RUN apt-get update -y && apt-get install udev -y
|
||||||
|
|
||||||
|
RUN echo "source /opt/esp/idf/export.sh > /dev/null 2>&1" >> ~/.bashrc
|
||||||
|
|
||||||
|
ENTRYPOINT [ "/opt/esp/entrypoint.sh" ]
|
||||||
|
|
||||||
|
CMD ["/bin/bash", "-c"]
|
21
.devcontainer/devcontainer.json
Normal file
21
.devcontainer/devcontainer.json
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
{
|
||||||
|
"name": "ESP-IDF QEMU",
|
||||||
|
"build": {
|
||||||
|
"dockerfile": "Dockerfile"
|
||||||
|
},
|
||||||
|
"customizations": {
|
||||||
|
"vscode": {
|
||||||
|
"settings": {
|
||||||
|
"terminal.integrated.defaultProfile.linux": "bash",
|
||||||
|
"idf.espIdfPath": "/opt/esp/idf",
|
||||||
|
"idf.toolsPath": "/opt/esp",
|
||||||
|
"idf.gitPath": "/usr/bin/git"
|
||||||
|
},
|
||||||
|
"extensions": [
|
||||||
|
"espressif.esp-idf-extension",
|
||||||
|
"espressif.esp-idf-web"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"runArgs": ["--privileged"]
|
||||||
|
}
|
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
build/
|
||||||
|
sdkconfig
|
||||||
|
sdkconfig.old
|
23
.vscode/c_cpp_properties.json
vendored
Normal file
23
.vscode/c_cpp_properties.json
vendored
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "ESP-IDF",
|
||||||
|
"compilerPath": "${config:idf.toolsPath}/tools/xtensa-esp-elf/esp-14.2.0_20241119/xtensa-esp-elf/bin/xtensa-esp32s3-elf-gcc",
|
||||||
|
"compileCommands": "${config:idf.buildPath}/compile_commands.json",
|
||||||
|
"includePath": [
|
||||||
|
"${config:idf.espIdfPath}/components/**",
|
||||||
|
"${config:idf.espIdfPathWin}/components/**",
|
||||||
|
"${workspaceFolder}/**"
|
||||||
|
],
|
||||||
|
"browse": {
|
||||||
|
"path": [
|
||||||
|
"${config:idf.espIdfPath}/components",
|
||||||
|
"${config:idf.espIdfPathWin}/components",
|
||||||
|
"${workspaceFolder}"
|
||||||
|
],
|
||||||
|
"limitSymbolsToIncludedHeaders": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"version": 4
|
||||||
|
}
|
15
.vscode/launch.json
vendored
Normal file
15
.vscode/launch.json
vendored
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"type": "gdbtarget",
|
||||||
|
"request": "attach",
|
||||||
|
"name": "Eclipse CDT GDB Adapter"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "espidf",
|
||||||
|
"name": "Launch",
|
||||||
|
"request": "launch"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
20
.vscode/settings.json
vendored
Normal file
20
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"C_Cpp.intelliSenseEngine": "default",
|
||||||
|
"idf.espIdfPath": "/home/bruno/esp/master/esp-idf",
|
||||||
|
"idf.pythonInstallPath": "/usr/bin/python",
|
||||||
|
"idf.openOcdConfigs": [
|
||||||
|
"board/esp32s3-builtin.cfg"
|
||||||
|
],
|
||||||
|
"idf.port": "/dev/ttyUSB0",
|
||||||
|
"idf.toolsPath": "/home/bruno/.espressif",
|
||||||
|
"idf.flashType": "UART",
|
||||||
|
"idf.customExtraVars": {
|
||||||
|
"OPENOCD_SCRIPTS": "/home/bruno/.espressif/tools/openocd-esp32/v0.12.0-esp32-20240821/openocd-esp32/share/openocd/scripts",
|
||||||
|
"ESP_ROM_ELF_DIR": "/home/bruno/.espressif/tools/esp-rom-elfs/20240305/",
|
||||||
|
"IDF_TARGET": "esp32s3"
|
||||||
|
},
|
||||||
|
"files.associations": {
|
||||||
|
"**/debian/*.install": "plain",
|
||||||
|
"sx1262.h": "c"
|
||||||
|
}
|
||||||
|
}
|
9
CMakeLists.txt
Normal file
9
CMakeLists.txt
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
# For more information about build system see
|
||||||
|
# https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/build-system.html
|
||||||
|
# The following five lines of boilerplate have to be in your project's
|
||||||
|
# CMakeLists in this exact order for cmake to work correctly
|
||||||
|
cmake_minimum_required(VERSION 3.5)
|
||||||
|
|
||||||
|
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||||
|
|
||||||
|
project(LoRaIDF)
|
32
README.md
Normal file
32
README.md
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
# _Sample project_
|
||||||
|
|
||||||
|
(See the README.md file in the upper level 'examples' directory for more information about examples.)
|
||||||
|
|
||||||
|
This is the simplest buildable example. The example is used by command `idf.py create-project`
|
||||||
|
that copies the project to user specified path and set it's name. For more information follow the [docs page](https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/build-system.html#start-a-new-project)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## How to use example
|
||||||
|
We encourage the users to use the example as a template for the new projects.
|
||||||
|
A recommended way is to follow the instructions on a [docs page](https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/build-system.html#start-a-new-project).
|
||||||
|
|
||||||
|
## Example folder contents
|
||||||
|
|
||||||
|
The project **sample_project** contains one source file in C language [main.c](main/main.c). The file is located in folder [main](main).
|
||||||
|
|
||||||
|
ESP-IDF projects are built using CMake. The project build configuration is contained in `CMakeLists.txt`
|
||||||
|
files that provide set of directives and instructions describing the project's source files and targets
|
||||||
|
(executable, library, or both).
|
||||||
|
|
||||||
|
Below is short explanation of remaining files in the project folder.
|
||||||
|
|
||||||
|
```
|
||||||
|
├── CMakeLists.txt
|
||||||
|
├── main
|
||||||
|
│ ├── CMakeLists.txt
|
||||||
|
│ └── main.c
|
||||||
|
└── README.md This is the file you are currently reading
|
||||||
|
```
|
||||||
|
Additionally, the sample project contains Makefile and component.mk files, used for the legacy Make based build system.
|
||||||
|
They are not used or needed when building with CMake and idf.py.
|
2
main/CMakeLists.txt
Normal file
2
main/CMakeLists.txt
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
idf_component_register(SRCS "sx1262.c" "sx1262.h" "main.c"
|
||||||
|
INCLUDE_DIRS ".")
|
215
main/main.c
Normal file
215
main/main.c
Normal file
@@ -0,0 +1,215 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include "sx1262.h"
|
||||||
|
|
||||||
|
#define TAG "SX1262"
|
||||||
|
|
||||||
|
const char *msg = "Testing 123 test why is this not on air";
|
||||||
|
|
||||||
|
void app_main(void)
|
||||||
|
{
|
||||||
|
sx1262_init();
|
||||||
|
sx1262_resetStats();
|
||||||
|
ESP_LOGI(TAG, "Setting standby RC");
|
||||||
|
sx1262_setStandby(SX1262_STANDBY_RC);
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "Getting version");
|
||||||
|
unsigned char versDat[16];
|
||||||
|
sx1262_readRegister(0x0320, versDat, 16);
|
||||||
|
ESP_LOGI(TAG, "Version: %s", versDat);
|
||||||
|
|
||||||
|
sx1262_status_t status = sx1262_get_status();
|
||||||
|
|
||||||
|
// Read status
|
||||||
|
status = sx1262_get_status();
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "Setting TCXO");
|
||||||
|
sx1262_setDIO3AsTCXOCtrl(SX1262_TCXO_VOLTAGE18dV, 320);
|
||||||
|
|
||||||
|
status = sx1262_get_status();
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "Setting Buffer base address");
|
||||||
|
sx1262_setBufferBaseAddress(0, 0);
|
||||||
|
status = sx1262_get_status();
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "Setting packet Type");
|
||||||
|
sx1262_setPacketType(SX1262_PACKET_TYPE_LORA);
|
||||||
|
status = sx1262_get_status();
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "Setting RXTX fallback mode");
|
||||||
|
sx1262_setRxTXFallbackMode(SX1262_FALLBACK_RC);
|
||||||
|
status = sx1262_get_status();
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "Setting CAD params");
|
||||||
|
sx1262_setCadParams(0x03, 0x16, 0x0A, 0, 0);
|
||||||
|
status = sx1262_get_status();
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "Clearing IRQ status");
|
||||||
|
sx1262_clearIrqStatus(0x43FF);
|
||||||
|
status = sx1262_get_status();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "Setting Image rejection");
|
||||||
|
sx1262_calibrateImage(0xD7, 0xDB);
|
||||||
|
|
||||||
|
status = sx1262_get_status();
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "Calibrating Image rejection");
|
||||||
|
sx1262_calibrate(SX1262_CALIBRATION_ALL);
|
||||||
|
status = sx1262_get_status();
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "Setting regulator");
|
||||||
|
sx1262_setRegulatorMode(SX1262_REGULATOR_DC_DC_LDO);
|
||||||
|
status = sx1262_get_status();
|
||||||
|
|
||||||
|
uint8_t modType;
|
||||||
|
modType = sx1262_getPacketType();
|
||||||
|
status = sx1262_get_status();
|
||||||
|
ESP_LOGI(TAG, "ModType %d", modType);
|
||||||
|
|
||||||
|
sx1262_LoRaModulationParams_t loraModParams;
|
||||||
|
|
||||||
|
loraModParams.bandwidth = SX1262_LORA_BW_125;
|
||||||
|
loraModParams.codingRate = SX1262_LORA_CR_4_5;
|
||||||
|
loraModParams.lowDataRateOpt = 1;
|
||||||
|
loraModParams.spreadingFactor = SX1262_LORA_SF7;
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "Setting modulation params");
|
||||||
|
sx1262_setLoRaModulationParams(&loraModParams);
|
||||||
|
|
||||||
|
status = sx1262_get_status();
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "Setting Sync word");
|
||||||
|
uint8_t syncWord[2] = {0x14, 0x24};
|
||||||
|
|
||||||
|
sx1262_writeRegister(SX1262_LORA_SYNC_WORD_MSB, syncWord, 2);
|
||||||
|
status = sx1262_get_status();
|
||||||
|
|
||||||
|
uint8_t ocpBuf[1] = {SX126X_OCP_LEVEL_SX1262};
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "Setting overcurrent protection");
|
||||||
|
sx1262_writeRegister(SX126X_OCP_CONFIGURATION, ocpBuf, 1);
|
||||||
|
|
||||||
|
status = sx1262_get_status();
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "Setting RF Switch out");
|
||||||
|
sx1262_setDIO2AsRfSwitchCtrl(1);
|
||||||
|
|
||||||
|
status = sx1262_get_status();
|
||||||
|
|
||||||
|
sx1262_LoRaPacketParams_t loraPacketParams;
|
||||||
|
loraPacketParams.preambleLength = 10;
|
||||||
|
loraPacketParams.crcType = SX1262_CRC_ON;
|
||||||
|
loraPacketParams.headerType = SX1262_HEADER_TYPE_VARIABLE;
|
||||||
|
loraPacketParams.invertIQ = SX1262_STANDARD_IQ;
|
||||||
|
loraPacketParams.payloadLength = sizeof(msg);
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "Setting packet params");
|
||||||
|
sx1262_setLoRaPacketParams(&loraPacketParams);
|
||||||
|
|
||||||
|
status = sx1262_get_status();
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "Setting frequency");
|
||||||
|
sx1262_setFrequency(869525000);
|
||||||
|
|
||||||
|
uint8_t clampConfig[1] = {0xDE};
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "Setting TX clamp");
|
||||||
|
sx1262_writeRegister(SX126X_TX_CLAMP_CONFIG, clampConfig, 1);
|
||||||
|
status = sx1262_get_status();
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "Setting TX power");
|
||||||
|
sx1262_configure_tx_power(0x04, 0x07, 0x01, 22, SX1262_Ramp_200U);
|
||||||
|
|
||||||
|
status = sx1262_get_status();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
status = sx1262_get_status();
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "Setting standby XOSC");
|
||||||
|
sx1262_setStandby(SX1262_STANDBY_XOSC);
|
||||||
|
|
||||||
|
status = sx1262_get_status();
|
||||||
|
|
||||||
|
|
||||||
|
sx1262_setDioIrqParams(SX1262_IRQ_ALL, SX1262_IRQ_TXDone, 0, 0);
|
||||||
|
|
||||||
|
|
||||||
|
status = sx1262_get_status();
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "Setting buffer base address");
|
||||||
|
sx1262_setBufferBaseAddress(0, 0);
|
||||||
|
|
||||||
|
status = sx1262_get_status();
|
||||||
|
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "Writing message");
|
||||||
|
sx1262_writeBuffer(0, (uint8_t *)msg, sizeof(msg));
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "Clearing IRQs");
|
||||||
|
sx1262_clearIrqStatus(SX1262_IRQ_ALL);
|
||||||
|
|
||||||
|
// sx1262_setTxContinuousWave();
|
||||||
|
status = sx1262_get_status();
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "Getting modulation type...");
|
||||||
|
modType = sx1262_getPacketType();
|
||||||
|
ESP_LOGI(TAG, "ModType %d", modType);
|
||||||
|
status = sx1262_get_status();
|
||||||
|
|
||||||
|
// ESP_LOGI(TAG, "Enabling CW...");
|
||||||
|
// sx1262_setTxContinuousWave();
|
||||||
|
// status = sx1262_get_status();
|
||||||
|
|
||||||
|
uint8_t txModulation[1] = {0x04};
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "Setting modulation thing");
|
||||||
|
sx1262_writeRegister(SX126X_TX_MODULATION, txModulation, 1);
|
||||||
|
status = sx1262_get_status();
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "Clearing IRQs");
|
||||||
|
sx1262_clearIrqStatus(SX1262_IRQ_ALL);
|
||||||
|
status = sx1262_get_status();
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "Enabling TX...");
|
||||||
|
sx1262_setMode(SX1262_TRANSMIT_MODE, 0);
|
||||||
|
status = sx1262_get_status();
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "Waiting for TX finish");
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
if (gpio_get_level(PIN_DIO1))
|
||||||
|
{
|
||||||
|
ESP_LOGI(TAG, "Got IRQin");
|
||||||
|
uint16_t irqS = sx1262_getIrqStatus();
|
||||||
|
if (irqS & SX1262_IRQ_TXDone)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(10));
|
||||||
|
}
|
||||||
|
|
||||||
|
// vTaskDelay(pdMS_TO_TICKS(2000));
|
||||||
|
// ESP_LOGI(TAG, "Returning back to sleep");
|
||||||
|
// sx1262_setStandby(SX1262_STANDBY_XOSC);
|
||||||
|
|
||||||
|
// status = sx1262_get_status();
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "Clearing IRQs");
|
||||||
|
sx1262_clearIrqStatus(SX1262_IRQ_TXDone);
|
||||||
|
|
||||||
|
status = sx1262_get_status();
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Set frequency to 868 MHz
|
||||||
|
|
||||||
|
// Set TX power to 22 dBm
|
||||||
|
|
||||||
|
// sx1262_setTxContinuousWave();
|
||||||
|
}
|
591
main/sx1262.c
Normal file
591
main/sx1262.c
Normal file
@@ -0,0 +1,591 @@
|
|||||||
|
#include "sx1262.h"
|
||||||
|
|
||||||
|
spi_device_handle_t spiSXko;
|
||||||
|
|
||||||
|
#define TAG_SPIDUMP "[SPI]"
|
||||||
|
|
||||||
|
void sx1262_init()
|
||||||
|
{
|
||||||
|
ESP_LOGI(TAG, "Initializing SX1262...");
|
||||||
|
|
||||||
|
gpio_set_direction(PIN_NSS, GPIO_MODE_OUTPUT);
|
||||||
|
gpio_set_direction(PIN_RESET, GPIO_MODE_OUTPUT);
|
||||||
|
gpio_set_direction(PIN_BUSY, GPIO_MODE_INPUT);
|
||||||
|
|
||||||
|
gpio_set_level(PIN_NSS, 1);
|
||||||
|
gpio_set_level(PIN_RESET, 1);
|
||||||
|
|
||||||
|
spi_bus_config_t buscfg;
|
||||||
|
memset(&buscfg, 0, sizeof(spi_bus_config_t));
|
||||||
|
buscfg.miso_io_num = PIN_MISO;
|
||||||
|
buscfg.mosi_io_num = PIN_MOSI;
|
||||||
|
buscfg.sclk_io_num = PIN_SCK;
|
||||||
|
buscfg.max_transfer_sz = 32;
|
||||||
|
buscfg.quadwp_io_num = -1;
|
||||||
|
buscfg.quadhd_io_num = -1;
|
||||||
|
|
||||||
|
spi_device_interface_config_t devcfg = {
|
||||||
|
.command_bits = 0,
|
||||||
|
.address_bits = 0,
|
||||||
|
.mode = 0,
|
||||||
|
.cs_ena_pretrans = 10,
|
||||||
|
.clock_speed_hz = 8 * 1000 * 1000,
|
||||||
|
.spics_io_num = -1,
|
||||||
|
.flags = 0,
|
||||||
|
.queue_size = 1};
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "Initializing SPI bus...");
|
||||||
|
esp_err_t ret = spi_bus_initialize(LORA_SPI_HOST, &buscfg, SPI_DMA_CH_AUTO);
|
||||||
|
if (ret != ESP_OK)
|
||||||
|
{
|
||||||
|
ESP_LOGE(TAG, "SPI bus init failed!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "Adding SPI device...");
|
||||||
|
ret = spi_bus_add_device(LORA_SPI_HOST, &devcfg, &spiSXko);
|
||||||
|
if (ret != ESP_OK)
|
||||||
|
{
|
||||||
|
ESP_LOGE(TAG, "SPI device init failed!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "SX1262 Initialized");
|
||||||
|
sx1262_reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void sx1262_reset()
|
||||||
|
{
|
||||||
|
ESP_LOGI(TAG, "Resetting SX1262...");
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(10));
|
||||||
|
gpio_set_level(PIN_RESET, 0);
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(20));
|
||||||
|
gpio_set_level(PIN_RESET, 1);
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(10));
|
||||||
|
sx1262_wait_for_busy();
|
||||||
|
ESP_LOGI(TAG, "SX1262 Reset complete.");
|
||||||
|
}
|
||||||
|
|
||||||
|
void sx1262_wait_for_busy()
|
||||||
|
{
|
||||||
|
ESP_LOGV("WAIT", "Waiting for SX1262 to be ready...");
|
||||||
|
while (gpio_get_level(PIN_BUSY) == 1)
|
||||||
|
{
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(10));
|
||||||
|
}
|
||||||
|
ESP_LOGV("WAIT", "SX1262 is ready.");
|
||||||
|
}
|
||||||
|
|
||||||
|
void sx1262_write_command(uint8_t cmd, uint8_t *data, uint8_t len)
|
||||||
|
{
|
||||||
|
ESP_LOGV(TAG, "Writing command 0x%02X with length %d", cmd, len);
|
||||||
|
spi_transaction_t t;
|
||||||
|
memset(&t, 0, sizeof(t));
|
||||||
|
t.length = (len + 1) * 8;
|
||||||
|
uint8_t *tx_data = malloc(len + 1);
|
||||||
|
memset(tx_data, 0, len + 1);
|
||||||
|
tx_data[0] = cmd;
|
||||||
|
if (len)
|
||||||
|
{
|
||||||
|
memcpy(tx_data + 1, data, len);
|
||||||
|
}
|
||||||
|
t.tx_buffer = tx_data;
|
||||||
|
|
||||||
|
sx1262_wait_for_busy();
|
||||||
|
|
||||||
|
ESP_LOGI(TAG_SPIDUMP, "SPI TX (cmd 0x%02X):", cmd);
|
||||||
|
ESP_LOG_BUFFER_HEXDUMP(TAG_SPIDUMP, tx_data, len + 1, ESP_LOG_INFO);
|
||||||
|
|
||||||
|
gpio_set_level(PIN_NSS, 0);
|
||||||
|
esp_err_t ret = spi_device_transmit(spiSXko, &t);
|
||||||
|
gpio_set_level(PIN_NSS, 1);
|
||||||
|
|
||||||
|
if (ret != ESP_OK)
|
||||||
|
{
|
||||||
|
ESP_LOGE(TAG, "SPI write failed!");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ESP_LOGV(TAG, "SPI write successful");
|
||||||
|
}
|
||||||
|
free(tx_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t SX1262_STATUS = 0;
|
||||||
|
|
||||||
|
void sx1262_read_command(uint8_t cmd, uint8_t *tx_payload_buffer, uint8_t tx_payload_len, uint8_t *rx_buffer, uint8_t len)
|
||||||
|
{
|
||||||
|
ESP_LOGV(TAG, "Reading command 0x%02X with expected length %d", cmd, len);
|
||||||
|
spi_transaction_t t;
|
||||||
|
memset(&t, 0, sizeof(t));
|
||||||
|
t.length = (len + 2) * 8;
|
||||||
|
uint8_t *tx_data = malloc(len + 2);
|
||||||
|
uint8_t *rx_data = malloc(len + 2);
|
||||||
|
memset(tx_data, 0, len + 2);
|
||||||
|
memset(rx_data, 0, len + 2);
|
||||||
|
|
||||||
|
memset(tx_data, 0, sizeof(tx_data));
|
||||||
|
memset(rx_data, 0, sizeof(rx_data));
|
||||||
|
if (tx_payload_buffer != NULL && tx_payload_len > 0)
|
||||||
|
{
|
||||||
|
if (tx_payload_len > len + 1)
|
||||||
|
{
|
||||||
|
tx_payload_len = len + 1;
|
||||||
|
}
|
||||||
|
memcpy(tx_data + 1, tx_payload_buffer, tx_payload_len);
|
||||||
|
}
|
||||||
|
tx_data[0] = cmd;
|
||||||
|
|
||||||
|
t.tx_buffer = tx_data;
|
||||||
|
t.rx_buffer = rx_data;
|
||||||
|
|
||||||
|
sx1262_wait_for_busy();
|
||||||
|
|
||||||
|
ESP_LOGI(TAG_SPIDUMP, "SPI TX (cmd 0x%02X):", cmd);
|
||||||
|
ESP_LOG_BUFFER_HEXDUMP(TAG_SPIDUMP, tx_data, len + 1, ESP_LOG_INFO);
|
||||||
|
|
||||||
|
gpio_set_level(PIN_NSS, 0);
|
||||||
|
esp_err_t ret = spi_device_transmit(spiSXko, &t);
|
||||||
|
gpio_set_level(PIN_NSS, 1);
|
||||||
|
|
||||||
|
if (ret == ESP_OK)
|
||||||
|
{
|
||||||
|
SX1262_STATUS = rx_data[1];
|
||||||
|
memcpy(rx_buffer, &rx_data[2], len);
|
||||||
|
ESP_LOGI(TAG_SPIDUMP, "SPI RX (cmd 0x%02X):", cmd);
|
||||||
|
ESP_LOG_BUFFER_HEXDUMP(TAG_SPIDUMP, rx_data, len + 2, ESP_LOG_INFO);
|
||||||
|
ESP_LOGV(TAG_SPIDUMP, "SPI read successful, status: 0x%02X", SX1262_STATUS);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ESP_LOGE(TAG, "SPI read failed!");
|
||||||
|
}
|
||||||
|
free(rx_data);
|
||||||
|
free(tx_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void resolve_status_byte(uint8_t status, uint16_t op_error)
|
||||||
|
{
|
||||||
|
const char *chip_modes[] = {
|
||||||
|
"Unused", "RFU", "STBY_RC", "STBY_XOSC",
|
||||||
|
"FS", "RX", "TX", "RFU"};
|
||||||
|
|
||||||
|
const char *command_statuses[] = {
|
||||||
|
"Reserved", "RFU", "Data is available to host", "Command timeout",
|
||||||
|
"Command processing error", "Failure to execute command", "Command TX done", "RFU"};
|
||||||
|
|
||||||
|
uint8_t chip_mode = (status >> 4) & 0x07; // Bits 6:4
|
||||||
|
uint8_t command_status = (status >> 1) & 0x07; // Bits 3:1
|
||||||
|
|
||||||
|
const char *chip_mode_str = chip_modes[chip_mode];
|
||||||
|
const char *command_status_str = command_statuses[command_status];
|
||||||
|
|
||||||
|
const char *op_errors[] = {
|
||||||
|
"RC64k calibration failed",
|
||||||
|
"RC13M calibration failed",
|
||||||
|
"PLL calibration failed",
|
||||||
|
"ADC calibration failed",
|
||||||
|
"IMG calibration failed",
|
||||||
|
"XOSC failed to start",
|
||||||
|
"PLL failed to lock",
|
||||||
|
"RFU",
|
||||||
|
"PA ramping failed"};
|
||||||
|
|
||||||
|
char errorStr[1024];
|
||||||
|
memset(errorStr, 0, sizeof(errorStr));
|
||||||
|
|
||||||
|
if (command_status == 0x05)
|
||||||
|
{
|
||||||
|
strcat(errorStr, "Command error: ");
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < 9; i++)
|
||||||
|
{
|
||||||
|
if (op_error & (1 << i))
|
||||||
|
{
|
||||||
|
strcat(errorStr, op_errors[i]);
|
||||||
|
strcat(errorStr, ", ");
|
||||||
|
ESP_LOGV(TAG, "OpError: %s", op_errors[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "Chip Mode: %s(0x%02X), Command Status: %s(0x%02X) %s", chip_mode_str, chip_mode, command_status_str, command_status, errorStr);
|
||||||
|
}
|
||||||
|
|
||||||
|
sx1262_status_t sx1262_get_status()
|
||||||
|
{
|
||||||
|
ESP_LOGV(TAG, "Getting SX1262 status...");
|
||||||
|
sx1262_status_t status;
|
||||||
|
uint8_t buffer[1] = {0};
|
||||||
|
sx1262_read_command(0xC0, NULL, 0, buffer, 1);
|
||||||
|
status.status = buffer[0];
|
||||||
|
status.error = sx1262_getDeviceErrors();
|
||||||
|
sx1262_clearDeviceErrors();
|
||||||
|
resolve_status_byte(status.status, status.error);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
void sx1262_setSleep(uint8_t sleepCFG)
|
||||||
|
{
|
||||||
|
sx1262_write_command(0x84, &sleepCFG, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sx1262_setStandby(uint8_t standbyConf)
|
||||||
|
{
|
||||||
|
sx1262_write_command(0x80, &standbyConf, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sx1262_setFrequencySynthesis()
|
||||||
|
{
|
||||||
|
sx1262_write_command(0xC1, NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sx1262_setMode(uint8_t mode, uint32_t timeout)
|
||||||
|
{
|
||||||
|
|
||||||
|
uint32_t timeoutUnits = 0;
|
||||||
|
|
||||||
|
if (timeout != 0)
|
||||||
|
{
|
||||||
|
uint64_t timeoutInUs = (uint64_t)timeout * 1000; // Convert ms → us
|
||||||
|
timeoutUnits = (uint32_t)((timeoutInUs * 64) / 1000); // Convert us → SX1262 units
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t buffer[4] = {
|
||||||
|
(uint8_t)((timeoutUnits >> 24) & 0xFF),
|
||||||
|
(uint8_t)((timeoutUnits >> 16) & 0xFF),
|
||||||
|
(uint8_t)((timeoutUnits >> 8) & 0xFF),
|
||||||
|
(uint8_t)((timeoutUnits) & 0xFF)};
|
||||||
|
if (mode)
|
||||||
|
{
|
||||||
|
sx1262_write_command(0x83, buffer, 3);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sx1262_write_command(0x82, buffer, 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void sx1262_stopTimerOnPreamble(uint8_t enable)
|
||||||
|
{
|
||||||
|
sx1262_write_command(0x9F, &enable, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sx1262_setRxDutyCycle(uint32_t rxPeriod, uint32_t sleepPeriod)
|
||||||
|
{
|
||||||
|
uint8_t payload[6];
|
||||||
|
payload[0] = (rxPeriod >> 16) & 0xFF;
|
||||||
|
payload[1] = (rxPeriod >> 8) & 0xFF;
|
||||||
|
payload[2] = rxPeriod & 0xFF;
|
||||||
|
payload[3] = (sleepPeriod >> 16) & 0xFF;
|
||||||
|
payload[4] = (sleepPeriod >> 8) & 0xFF;
|
||||||
|
payload[5] = sleepPeriod & 0xFF;
|
||||||
|
sx1262_write_command(0x94, payload, 6);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sx1262_setChannelActivityDetection(void)
|
||||||
|
{
|
||||||
|
sx1262_write_command(0xC5, NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sx1262_setTxContinuousWave(void)
|
||||||
|
{
|
||||||
|
sx1262_write_command(0xD1, NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sx1262_setTxInfinitePreamble(void)
|
||||||
|
{
|
||||||
|
sx1262_write_command(0xD2, NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sx1262_setRegulatorMode(uint8_t mode)
|
||||||
|
{
|
||||||
|
sx1262_write_command(0x96, &mode, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sx1262_calibrate(uint8_t calibParam)
|
||||||
|
{
|
||||||
|
sx1262_write_command(0x89, &calibParam, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sx1262_calibrateImage(uint8_t freq1, uint8_t freq2)
|
||||||
|
{
|
||||||
|
uint8_t payload[2] = {freq1, freq2};
|
||||||
|
sx1262_write_command(0x98, payload, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sx1262_setRxTXFallbackMode(uint8_t fallbackMode)
|
||||||
|
{
|
||||||
|
sx1262_write_command(0x93, &fallbackMode, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write to register function
|
||||||
|
void sx1262_writeRegister(uint16_t address, const uint8_t *data, size_t length)
|
||||||
|
{
|
||||||
|
uint8_t payload[length + 2];
|
||||||
|
payload[0] = (address >> 8) & 0xFF;
|
||||||
|
payload[1] = address & 0xFF;
|
||||||
|
for (size_t i = 0; i < length; i++)
|
||||||
|
{
|
||||||
|
payload[i + 2] = data[i];
|
||||||
|
}
|
||||||
|
sx1262_write_command(0x0D, payload, length + 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read from register function
|
||||||
|
void sx1262_readRegister(uint16_t address, uint8_t *data, size_t length)
|
||||||
|
{
|
||||||
|
uint8_t payload[2];
|
||||||
|
payload[0] = (address >> 8) & 0xFF;
|
||||||
|
payload[1] = address & 0xFF;
|
||||||
|
uint8_t rx_payload[2 + length];
|
||||||
|
sx1262_read_command(0x1D, payload, 2, rx_payload, 2 + length);
|
||||||
|
for (size_t i = 0; i < length; i++)
|
||||||
|
{
|
||||||
|
data[i] = rx_payload[i + 2];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write to buffer function
|
||||||
|
void sx1262_writeBuffer(uint8_t offset, const uint8_t *data, size_t length)
|
||||||
|
{
|
||||||
|
uint8_t payload[length + 1];
|
||||||
|
payload[0] = offset;
|
||||||
|
for (size_t i = 0; i < length; i++)
|
||||||
|
{
|
||||||
|
payload[i + 1] = data[i];
|
||||||
|
}
|
||||||
|
sx1262_write_command(0x0E, payload, length + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read from buffer function
|
||||||
|
void sx1262_readBuffer(uint8_t offset, uint8_t *data, size_t length)
|
||||||
|
{
|
||||||
|
uint8_t tx_payload[1];
|
||||||
|
uint8_t payload[1 + length];
|
||||||
|
tx_payload[0] = offset;
|
||||||
|
sx1262_read_command(0x1E, tx_payload, 1, payload, 1 + length);
|
||||||
|
for (size_t i = 0; i < length; i++)
|
||||||
|
{
|
||||||
|
data[i] = payload[i + 1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void sx1262_setDioIrqParams(uint16_t irqMask, uint16_t dio1Mask, uint16_t dio2Mask, uint16_t dio3Mask)
|
||||||
|
{
|
||||||
|
uint8_t payload[8] = {
|
||||||
|
(uint8_t)((irqMask >> 8) & 0xFF), (uint8_t)((irqMask) & 0xFF),
|
||||||
|
(uint8_t)((dio1Mask >> 8) & 0xFF), (uint8_t)(dio1Mask & 0xFF),
|
||||||
|
(uint8_t)((dio2Mask >> 8) & 0xFF), (uint8_t)(dio2Mask & 0xFF),
|
||||||
|
(uint8_t)((dio3Mask >> 8) & 0xFF), (uint8_t)(dio3Mask & 0xFF)};
|
||||||
|
sx1262_write_command(0x08, payload, 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t sx1262_getIrqStatus(void)
|
||||||
|
{
|
||||||
|
uint8_t response[2] = {0};
|
||||||
|
sx1262_read_command(0x12, NULL, 0, response, 2);
|
||||||
|
return (response[0] << 8) | response[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
void sx1262_clearIrqStatus(uint16_t clearIrqParam)
|
||||||
|
{
|
||||||
|
uint8_t payload[2] = {
|
||||||
|
(uint8_t)((clearIrqParam >> 8) & 0xFF),
|
||||||
|
(uint8_t)(clearIrqParam & 0xFF)};
|
||||||
|
sx1262_write_command(0x02, payload, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sx1262_setDIO2AsRfSwitchCtrl(uint8_t enable)
|
||||||
|
{
|
||||||
|
uint8_t buf[1];
|
||||||
|
buf[0] = enable;
|
||||||
|
sx1262_write_command(0x9D, buf, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sx1262_setDIO3AsTCXOCtrl(uint8_t tcxoVoltage, uint32_t delay)
|
||||||
|
{
|
||||||
|
uint8_t payload[4] = {
|
||||||
|
tcxoVoltage,
|
||||||
|
(uint8_t)((delay >> 16) & 0xFF),
|
||||||
|
(uint8_t)((delay >> 8) & 0xFF),
|
||||||
|
(uint8_t)(delay & 0xFF)};
|
||||||
|
sx1262_write_command(0x97, payload, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sx1262_setFrequency(uint32_t frequency)
|
||||||
|
{
|
||||||
|
uint32_t freq_reg = frequency * FREQ_STEP;
|
||||||
|
uint8_t buffer[4] = {
|
||||||
|
(uint8_t)((freq_reg >> 24) & 0xFF),
|
||||||
|
(uint8_t)((freq_reg >> 16) & 0xFF),
|
||||||
|
(uint8_t)((freq_reg >> 8) & 0xFF),
|
||||||
|
(uint8_t)((freq_reg) & 0xFF)};
|
||||||
|
sx1262_write_command(0x86, buffer, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sx1262_setPacketType(uint8_t packetType)
|
||||||
|
{
|
||||||
|
uint8_t data[1];
|
||||||
|
data[0] = packetType;
|
||||||
|
sx1262_write_command(0x8A, data, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sx1262_setLoRaModulationParams(const sx1262_LoRaModulationParams_t *params)
|
||||||
|
{
|
||||||
|
uint8_t payload[4] = {
|
||||||
|
params->spreadingFactor,
|
||||||
|
params->bandwidth,
|
||||||
|
params->codingRate,
|
||||||
|
params->lowDataRateOpt};
|
||||||
|
sx1262_write_command(0x8B, payload, sizeof(payload));
|
||||||
|
}
|
||||||
|
|
||||||
|
void sx1262_setGFSKModulationParams(const sx1262_GFSKModulationParams_t *params)
|
||||||
|
{
|
||||||
|
uint8_t payload[8] = {
|
||||||
|
(uint8_t)((params->bitRate >> 16) & 0xFF),
|
||||||
|
(uint8_t)((params->bitRate >> 8) & 0xFF),
|
||||||
|
(uint8_t)(params->bitRate & 0xFF),
|
||||||
|
params->pulseShape,
|
||||||
|
params->bandwidth,
|
||||||
|
(uint8_t)((params->frequencyDev >> 16) & 0xFF),
|
||||||
|
(uint8_t)((params->frequencyDev >> 8) & 0xFF),
|
||||||
|
(uint8_t)(params->frequencyDev & 0xFF)};
|
||||||
|
sx1262_write_command(0x8B, payload, sizeof(payload));
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t sx1262_getPacketType()
|
||||||
|
{
|
||||||
|
uint8_t response;
|
||||||
|
sx1262_read_command(0x11, NULL, 0, &response, 1);
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
void sx1262_configure_tx_power(uint8_t paDutyCycle, uint8_t hpMax, uint8_t paLut, int8_t power, uint8_t rampTime)
|
||||||
|
{
|
||||||
|
if (paDutyCycle > 0x04)
|
||||||
|
paDutyCycle = 0x04;
|
||||||
|
if (rampTime > 0x07)
|
||||||
|
rampTime = 0x07;
|
||||||
|
if (hpMax > 0x07)
|
||||||
|
hpMax = 0x07;
|
||||||
|
|
||||||
|
uint8_t deviceSel;
|
||||||
|
if (power >= -9)
|
||||||
|
{
|
||||||
|
deviceSel = 0x00; // High Power PA
|
||||||
|
if (power > 22)
|
||||||
|
power = 22;
|
||||||
|
if (power < -9)
|
||||||
|
power = -9;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
deviceSel = 0x01; // Low Power PA
|
||||||
|
if (power > 14)
|
||||||
|
power = 14;
|
||||||
|
if (power < -17)
|
||||||
|
power = -17;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t paConfig[4] = {paDutyCycle, hpMax, deviceSel, paLut};
|
||||||
|
sx1262_write_command(0x95, paConfig, 4);
|
||||||
|
|
||||||
|
// Direct cast keeps correct 2's complement representation
|
||||||
|
uint8_t txPower[2] = {(uint8_t)power, rampTime};
|
||||||
|
sx1262_write_command(0x8E, txPower, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sx1262_setLoRaPacketParams(sx1262_LoRaPacketParams_t *params)
|
||||||
|
{
|
||||||
|
uint8_t payload[6] = {
|
||||||
|
(uint8_t)((params->preambleLength >> 8) & 0xFF),
|
||||||
|
(uint8_t)(params->preambleLength & 0xFF),
|
||||||
|
params->headerType,
|
||||||
|
params->payloadLength,
|
||||||
|
params->crcType,
|
||||||
|
params->invertIQ};
|
||||||
|
sx1262_write_command(0x8C, payload, sizeof(payload));
|
||||||
|
}
|
||||||
|
|
||||||
|
void sx1262_setCadParams(uint8_t cadSymbolNum, uint8_t cadDetPeak, uint8_t cadDetMin, uint8_t cadExitMode, uint32_t cadTimeout)
|
||||||
|
{
|
||||||
|
uint8_t payload[7] = {
|
||||||
|
cadSymbolNum,
|
||||||
|
cadDetPeak,
|
||||||
|
cadDetMin,
|
||||||
|
cadExitMode,
|
||||||
|
(uint8_t)((cadTimeout >> 16) & 0xFF),
|
||||||
|
(uint8_t)((cadTimeout >> 8) & 0xFF),
|
||||||
|
(uint8_t)(cadTimeout & 0xFF)};
|
||||||
|
sx1262_write_command(0x88, payload, sizeof(payload));
|
||||||
|
}
|
||||||
|
|
||||||
|
void sx1262_setBufferBaseAddress(uint8_t txBaseAddr, uint8_t rxBaseAddr)
|
||||||
|
{
|
||||||
|
uint8_t payload[2] = {txBaseAddr, rxBaseAddr};
|
||||||
|
sx1262_write_command(0x8F, payload, sizeof(payload));
|
||||||
|
}
|
||||||
|
|
||||||
|
void sx1262_setLoRaSymbNumTimeout(uint8_t symbNum)
|
||||||
|
{
|
||||||
|
sx1262_write_command(0xA0, &symbNum, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sx1262_getStatus(uint8_t *status)
|
||||||
|
{
|
||||||
|
sx1262_read_command(0xC0, NULL, 0, status, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sx1262_getRxBufferStatus(uint8_t *payloadLengthRx, uint8_t *rxStartBufferPointer)
|
||||||
|
{
|
||||||
|
uint8_t response[2];
|
||||||
|
sx1262_read_command(0x13, NULL, 0, response, sizeof(response));
|
||||||
|
*payloadLengthRx = response[0];
|
||||||
|
*rxStartBufferPointer = response[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
void sx1262_getPacketStatus(uint8_t *rssi, uint8_t *snr, uint8_t *signalRssi)
|
||||||
|
{
|
||||||
|
uint8_t response[3];
|
||||||
|
sx1262_read_command(0x14, NULL, 0, response, sizeof(response));
|
||||||
|
*rssi = response[0];
|
||||||
|
*snr = response[1];
|
||||||
|
*signalRssi = response[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t sx1262_getRssiInst(uint8_t *rssiInst)
|
||||||
|
{
|
||||||
|
uint8_t response;
|
||||||
|
sx1262_read_command(0x15, NULL, 0, &response, 1);
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
void sx1262_getStats(uint16_t *pktReceived, uint16_t *pktCrcError, uint16_t *pktHeaderErr)
|
||||||
|
{
|
||||||
|
uint8_t response[6];
|
||||||
|
sx1262_read_command(0x10, NULL, 0, response, sizeof(response));
|
||||||
|
*pktReceived = (response[0] << 8) | response[1];
|
||||||
|
*pktCrcError = (response[2] << 8) | response[3];
|
||||||
|
*pktHeaderErr = (response[4] << 8) | response[5];
|
||||||
|
}
|
||||||
|
|
||||||
|
void sx1262_resetStats(void)
|
||||||
|
{
|
||||||
|
uint8_t payload[6] = {0};
|
||||||
|
sx1262_write_command(0x00, payload, sizeof(payload));
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t sx1262_getDeviceErrors()
|
||||||
|
{
|
||||||
|
uint8_t response[2];
|
||||||
|
sx1262_read_command(0x17, NULL, 0, response, sizeof(response));
|
||||||
|
return (((uint16_t)response[0]) << 8) | (uint16_t)response[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
void sx1262_clearDeviceErrors(void)
|
||||||
|
{
|
||||||
|
uint8_t payload[2] = {0x00, 0x00};
|
||||||
|
sx1262_write_command(0x07, payload, sizeof(payload));
|
||||||
|
}
|
335
main/sx1262.h
Normal file
335
main/sx1262.h
Normal file
@@ -0,0 +1,335 @@
|
|||||||
|
#ifndef SX1262_H
|
||||||
|
#define SX1262_H
|
||||||
|
|
||||||
|
#include "driver/spi_master.h"
|
||||||
|
#include "driver/gpio.h"
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "esp_task.h"
|
||||||
|
|
||||||
|
#define TAG "SX1262"
|
||||||
|
|
||||||
|
#define LOG_LOCAL_LEVEL ESP_LOG_DEBUG
|
||||||
|
#include "esp_log.h"
|
||||||
|
|
||||||
|
#define LOG_LOCAL_LEVEL ESP_LOG_DEBUG
|
||||||
|
|
||||||
|
#define LORA_SPI_HOST SPI2_HOST
|
||||||
|
#define PIN_MOSI GPIO_NUM_10
|
||||||
|
#define PIN_MISO GPIO_NUM_11
|
||||||
|
#define PIN_SCK GPIO_NUM_9
|
||||||
|
#define PIN_NSS GPIO_NUM_8
|
||||||
|
#define PIN_RESET GPIO_NUM_12
|
||||||
|
#define PIN_BUSY GPIO_NUM_13
|
||||||
|
#define PIN_DIO1 GPIO_NUM_14
|
||||||
|
|
||||||
|
extern spi_device_handle_t spi;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint8_t status;
|
||||||
|
uint16_t error;
|
||||||
|
} sx1262_status_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint16_t preambleLength;
|
||||||
|
uint8_t headerType;
|
||||||
|
uint8_t payloadLength;
|
||||||
|
uint8_t crcType;
|
||||||
|
uint8_t invertIQ;
|
||||||
|
} sx1262_LoRaPacketParams_t;
|
||||||
|
|
||||||
|
#define SX126X_DIOX_OUTPUT_ENABLE 0x0580
|
||||||
|
#define SX126X_DIOX_INPUT_ENABLE 0x0583
|
||||||
|
#define SX126X_DIOX_PULL_UP_CONTROL 0x0584
|
||||||
|
#define SX126X_DIOX_PULL_DOWN_CONTROL 0x0585
|
||||||
|
|
||||||
|
#define SX126X_WHITENING_INIT_MSB 0x06B8
|
||||||
|
#define SX126X_WHITENING_INIT_LSB 0x06B9
|
||||||
|
|
||||||
|
#define SX126X_CRC_INIT_MSB 0x06BC
|
||||||
|
#define SX126X_CRC_INIT_LSB 0x06BD
|
||||||
|
|
||||||
|
#define SX126X_CRC_POLY_MSB 0x06BE
|
||||||
|
#define SX126X_CRC_POLY_LSB 0x06BF
|
||||||
|
|
||||||
|
#define SX126X_SYNCWORD_0 0x06C0
|
||||||
|
#define SX126X_SYNCWORD_1 0x06C1
|
||||||
|
#define SX126X_SYNCWORD_2 0x06C2
|
||||||
|
#define SX126X_SYNCWORD_3 0x06C3
|
||||||
|
#define SX126X_SYNCWORD_4 0x06C4
|
||||||
|
#define SX126X_SYNCWORD_5 0x06C5
|
||||||
|
#define SX126X_SYNCWORD_6 0x06C6
|
||||||
|
#define SX126X_SYNCWORD_7 0x06C7
|
||||||
|
|
||||||
|
#define SX126X_NODE_ADDRESS 0x06CD
|
||||||
|
#define SX126X_BROADCAST_ADDRESS 0x06CE
|
||||||
|
|
||||||
|
#define SX126X_IQ_POLARITY_SETUP 0x0736
|
||||||
|
|
||||||
|
#define SX126X_LORA_SYNCWORD_MSB 0x0740
|
||||||
|
#define SX126X_LORA_SYNCWORD_LSB 0x0741
|
||||||
|
|
||||||
|
#define SX126X_RANDOM_NUMBER_0 0x0819
|
||||||
|
#define SX126X_RANDOM_NUMBER_1 0x081A
|
||||||
|
#define SX126X_RANDOM_NUMBER_2 0x081B
|
||||||
|
#define SX126X_RANDOM_NUMBER_3 0x081C
|
||||||
|
|
||||||
|
#define SX126X_TX_MODULATION 0x0889
|
||||||
|
#define SX126X_RX_GAIN 0x08AC
|
||||||
|
|
||||||
|
#define SX126X_TX_CLAMP_CONFIG 0x08D8
|
||||||
|
#define SX126X_OCP_CONFIGURATION 0x08E7
|
||||||
|
|
||||||
|
#define SX126X_RTC_CONTROL 0x0902
|
||||||
|
|
||||||
|
#define SX126X_XTA_TRIM 0x0911
|
||||||
|
#define SX126X_XTB_TRIM 0x0912
|
||||||
|
|
||||||
|
#define SX126X_DIO3_OUTPUT_VOLTAGE 0x0920
|
||||||
|
#define SX126X_EVENT_MASK 0x0944
|
||||||
|
|
||||||
|
// Default values where applicable
|
||||||
|
#define SX126X_RX_GAIN_POWER_SAVING 0x94
|
||||||
|
#define SX126X_RX_GAIN_BOOSTED 0x96
|
||||||
|
|
||||||
|
#define SX126X_LORA_SYNCWORD_PUBLIC 0x3444
|
||||||
|
#define SX126X_LORA_SYNCWORD_PRIVATE 0x1424
|
||||||
|
|
||||||
|
#define SX126X_OCP_LEVEL_SX1262 0x38 // 140mA
|
||||||
|
#define SX126X_OCP_LEVEL_SX1261 0x18 // 60mA
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint8_t spreadingFactor; // LoRa SF: 0x05 (SF5) to 0x0C (SF12)
|
||||||
|
uint8_t bandwidth; // LoRa BW: 0x00 (7.81 kHz) to 0x06 (500 kHz)
|
||||||
|
uint8_t codingRate; // LoRa CR: 0x01 (4/5) to 0x04 (4/8)
|
||||||
|
uint8_t lowDataRateOpt; // LDRO: 0x00 (disabled) or 0x01 (enabled)
|
||||||
|
} sx1262_LoRaModulationParams_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint32_t bitRate; // GFSK bitrate (BR), calculated as 32 * Fxtal / BR
|
||||||
|
uint8_t pulseShape; // GFSK filter: 0x00 (none) to 0x0B (Gaussian BT 1)
|
||||||
|
uint8_t bandwidth; // GFSK RX bandwidth: 0x1F (4.8 kHz) to 0x09 (467 kHz)
|
||||||
|
uint32_t frequencyDev; // GFSK frequency deviation (Fdev)
|
||||||
|
} sx1262_GFSKModulationParams_t;
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
#define XTAL_FREQ (double)32000000
|
||||||
|
#define FREQ_DIV (double)pow(2.0, 25.0)
|
||||||
|
#define FREQ_STEP (double)(XTAL_FREQ / FREQ_DIV)
|
||||||
|
|
||||||
|
#define SX1262_SLEEPCFG_ColdStart_RTCDisable 0
|
||||||
|
#define SX1262_SLEEPCFG_ColdStart_RTCEnable 1
|
||||||
|
#define SX1262_SLEEPCFG_WarmStart_RTCDisable 4
|
||||||
|
#define SX1262_SLEEPCFG_WarmStart_RTCEnable 5
|
||||||
|
|
||||||
|
#define SX1262_STANDBY_RC 0
|
||||||
|
#define SX1262_STANDBY_XOSC 1
|
||||||
|
|
||||||
|
#define SX1262_TIMEOUT_ONCE 0
|
||||||
|
#define SX1262_TIMEOUT_RX_CONTINOUS 0xFFFFFF
|
||||||
|
|
||||||
|
#define SX1262_RECEIVE_MODE 0
|
||||||
|
#define SX1262_TRANSMIT_MODE 1
|
||||||
|
|
||||||
|
#define SX1262_STOP_TIMER_ON_PREAMBLE_DISABLE 0x00
|
||||||
|
#define SX1262_STOP_TIMER_ON_PREAMBLE_ENABLE 0x01
|
||||||
|
|
||||||
|
#define SX1262_REGULATOR_LDO_ONLY 0x00
|
||||||
|
#define SX1262_REGULATOR_DC_DC_LDO 0x01
|
||||||
|
|
||||||
|
#define SX1262_FALLBACK_FS 0x40
|
||||||
|
#define SX1262_FALLBACK_STANDBY_XOSC 0x30
|
||||||
|
#define SX1262_FALLBACK_RC 0x20
|
||||||
|
|
||||||
|
#define SX1262_IRQ_TXDone (1 << 0)
|
||||||
|
#define SX1262_IRQ_RXDone (1 << 1)
|
||||||
|
#define SX1262_IRQ_PreambleDetected (1 << 2)
|
||||||
|
#define SX1262_IRQ_SyncWordValid (1 << 3)
|
||||||
|
#define SX1262_IRQ_HeaderValid (1 << 4)
|
||||||
|
#define SX1262_IRQ_HeaderError (1 << 5)
|
||||||
|
#define SX1262_IRQ_CRCError (1 << 6)
|
||||||
|
#define SX1262_IRQ_ChannelActivityDetectionDone (1 << 7)
|
||||||
|
#define SX1262_IRQ_ChannelActivityDetected (1 << 8)
|
||||||
|
#define SX1262_IRQ_Timeout (1 << 9)
|
||||||
|
#define SX1262_IRQ_ALL (SX1262_IRQ_TXDone | SX1262_IRQ_RXDone | SX1262_IRQ_PreambleDetected | SX1262_IRQ_SyncWordValid | SX1262_IRQ_HeaderValid | SX1262_IRQ_HeaderError | SX1262_IRQ_CRCError | SX1262_IRQ_ChannelActivityDetectionDone | SX1262_IRQ_ChannelActivityDetected | SX1262_IRQ_Timeout)
|
||||||
|
|
||||||
|
#define SX1262_TCXO_VOLTAGE16dV 0x00
|
||||||
|
#define SX1262_TCXO_VOLTAGE17dV 0x01
|
||||||
|
#define SX1262_TCXO_VOLTAGE18dV 0x02
|
||||||
|
#define SX1262_TCXO_VOLTAGE22dV 0x03
|
||||||
|
#define SX1262_TCXO_VOLTAGE24dV 0x04
|
||||||
|
#define SX1262_TCXO_VOLTAGE27dV 0x05
|
||||||
|
#define SX1262_TCXO_VOLTAGE30dV 0x06
|
||||||
|
#define SX1262_TCXO_VOLTAGE33dV 0x07
|
||||||
|
|
||||||
|
#define SX1262_PACKET_TYPE_GFSK 0x00
|
||||||
|
#define SX1262_PACKET_TYPE_LORA 0x01
|
||||||
|
|
||||||
|
#define SX1262_Ramp_10U (0x00)
|
||||||
|
#define SX1262_Ramp_20U (0x01)
|
||||||
|
#define SX1262_Ramp_40U (0x02)
|
||||||
|
#define SX1262_Ramp_80U (0x03)
|
||||||
|
#define SX1262_Ramp_200U (0x04)
|
||||||
|
#define SX1262_Ramp_800U (0x05)
|
||||||
|
#define SX1262_Ramp_1700U (0x06)
|
||||||
|
#define SX1262_Ramp_3400U (0x07)
|
||||||
|
|
||||||
|
#define SX1262_HEADER_TYPE_VARIABLE 0x00
|
||||||
|
#define SX1262_HEADER_TYPE_FIXED 0x01
|
||||||
|
|
||||||
|
#define SX1262_CRC_OFF 0x00
|
||||||
|
#define SX1262_CRC_ON 0x01
|
||||||
|
|
||||||
|
#define SX1262_STANDARD_IQ 0x00
|
||||||
|
#define SX1262_INVERTED_IQ 0x01
|
||||||
|
|
||||||
|
#define SX1262_CAD_ON_1_SYMB 0x00
|
||||||
|
#define SX1262_CAD_ON_2_SYMB 0x01
|
||||||
|
#define SX1262_CAD_ON_4_SYMB 0x02
|
||||||
|
#define SX1262_CAD_ON_8_SYMB 0x03
|
||||||
|
#define SX1262_CAD_ON_16_SYMB 0x04
|
||||||
|
#define SX1262_CAD_ONLY 0x00
|
||||||
|
#define SX1262_CAD_RX 0x01
|
||||||
|
|
||||||
|
#define SX1262_ERROR_CALIBRATION_RC64K (1 << 0)
|
||||||
|
#define SX1262_ERROR_CALIBRATION_RC13M (1 << 1)
|
||||||
|
#define SX1262_ERROR_CALIBRATION_PLL (1 << 2)
|
||||||
|
#define SX1262_ERROR_CALIBRATION_ADC (1 << 3)
|
||||||
|
#define SX1262_ERROR_CALIBRATION_IMG (1 << 4)
|
||||||
|
#define SX1262_ERROR_CALIBRATION_XOSC (1 << 5)
|
||||||
|
#define SX1262_ERROR_PLL_LOCK (1 << 6)
|
||||||
|
#define SX1262_ERROR_PA_RAMP (1 << 8)
|
||||||
|
|
||||||
|
#define SX1262_CALIB_RC64K (1 << 0) // RC64k calibration enabled
|
||||||
|
#define SX1262_CALIB_RC13M (1 << 1) // RC13M calibration enabled
|
||||||
|
#define SX1262_CALIB_PLL (1 << 2) // PLL calibration enabled
|
||||||
|
#define SX1262_CALIB_ADC_PULSE (1 << 3) // ADC pulse calibration enabled
|
||||||
|
#define SX1262_CALIB_ADC_BULK_N (1 << 4) // ADC bulk N calibration enabled
|
||||||
|
#define SX1262_CALIB_ADC_BULK_P (1 << 5) // ADC bulk P calibration enabled
|
||||||
|
#define SX1262_CALIB_IMAGE (1 << 6) // Image calibration enabled
|
||||||
|
#define SX1262_CALIB_RESERVED (1 << 7) // Reserved bit (RFU)
|
||||||
|
|
||||||
|
// Combined mask for all calibration settings
|
||||||
|
#define SX1262_CALIBRATION_ALL (SX1262_CALIB_RC64K | SX1262_CALIB_RC13M | \
|
||||||
|
SX1262_CALIB_PLL | SX1262_CALIB_ADC_PULSE | \
|
||||||
|
SX1262_CALIB_ADC_BULK_N | SX1262_CALIB_ADC_BULK_P | \
|
||||||
|
SX1262_CALIB_IMAGE)
|
||||||
|
|
||||||
|
// GFSK Pulse Shape
|
||||||
|
#define SX1262_GFSK_NO_FILTER (0x00)
|
||||||
|
#define SX1262_GFSK_BT_0_3 (0x08)
|
||||||
|
#define SX1262_GFSK_BT_0_5 (0x09)
|
||||||
|
#define SX1262_GFSK_BT_0_7 (0x0A)
|
||||||
|
#define SX1262_GFSK_BT_1_0 (0x0B)
|
||||||
|
|
||||||
|
// GFSK Bandwidth
|
||||||
|
#define SX1262_GFSK_RX_BW_4800 (0x1F)
|
||||||
|
#define SX1262_GFSK_RX_BW_5800 (0x17)
|
||||||
|
#define SX1262_GFSK_RX_BW_7300 (0x0F)
|
||||||
|
#define SX1262_GFSK_RX_BW_9700 (0x1E)
|
||||||
|
#define SX1262_GFSK_RX_BW_11700 (0x16)
|
||||||
|
#define SX1262_GFSK_RX_BW_14600 (0x0E)
|
||||||
|
#define SX1262_GFSK_RX_BW_19500 (0x1D)
|
||||||
|
#define SX1262_GFSK_RX_BW_23400 (0x15)
|
||||||
|
#define SX1262_GFSK_RX_BW_29300 (0x0D)
|
||||||
|
#define SX1262_GFSK_RX_BW_39000 (0x1C)
|
||||||
|
#define SX1262_GFSK_RX_BW_46900 (0x14)
|
||||||
|
#define SX1262_GFSK_RX_BW_58600 (0x0C)
|
||||||
|
#define SX1262_GFSK_RX_BW_78200 (0x1B)
|
||||||
|
#define SX1262_GFSK_RX_BW_93800 (0x13)
|
||||||
|
#define SX1262_GFSK_RX_BW_117300 (0x0B)
|
||||||
|
#define SX1262_GFSK_RX_BW_156200 (0x1A)
|
||||||
|
#define SX1262_GFSK_RX_BW_187200 (0x12)
|
||||||
|
#define SX1262_GFSK_RX_BW_234300 (0x0A)
|
||||||
|
#define SX1262_GFSK_RX_BW_312000 (0x19)
|
||||||
|
#define SX1262_GFSK_RX_BW_373600 (0x11)
|
||||||
|
#define SX1262_GFSK_RX_BW_467000 (0x09)
|
||||||
|
|
||||||
|
// LoRa Spreading Factor (SF)
|
||||||
|
#define SX1262_LORA_SF5 (0x05)
|
||||||
|
#define SX1262_LORA_SF6 (0x06)
|
||||||
|
#define SX1262_LORA_SF7 (0x07)
|
||||||
|
#define SX1262_LORA_SF8 (0x08)
|
||||||
|
#define SX1262_LORA_SF9 (0x09)
|
||||||
|
#define SX1262_LORA_SF10 (0x0A)
|
||||||
|
#define SX1262_LORA_SF11 (0x0B)
|
||||||
|
#define SX1262_LORA_SF12 (0x0C)
|
||||||
|
|
||||||
|
// LoRa Bandwidth (BW)
|
||||||
|
#define SX1262_LORA_BW_7 (0x00) // 7.81 kHz
|
||||||
|
#define SX1262_LORA_BW_10 (0x08) // 10.42 kHz
|
||||||
|
#define SX1262_LORA_BW_15 (0x01) // 15.63 kHz
|
||||||
|
#define SX1262_LORA_BW_20 (0x09) // 20.83 kHz
|
||||||
|
#define SX1262_LORA_BW_31 (0x02) // 31.25 kHz
|
||||||
|
#define SX1262_LORA_BW_41 (0x0A) // 41.67 kHz
|
||||||
|
#define SX1262_LORA_BW_62 (0x03) // 62.50 kHz
|
||||||
|
#define SX1262_LORA_BW_125 (0x04) // 125 kHz
|
||||||
|
#define SX1262_LORA_BW_250 (0x05) // 250 kHz
|
||||||
|
#define SX1262_LORA_BW_500 (0x06) // 500 kHz
|
||||||
|
|
||||||
|
// LoRa Coding Rate (CR)
|
||||||
|
#define SX1262_LORA_CR_4_5 (0x01)
|
||||||
|
#define SX1262_LORA_CR_4_6 (0x02)
|
||||||
|
#define SX1262_LORA_CR_4_7 (0x03)
|
||||||
|
#define SX1262_LORA_CR_4_8 (0x04)
|
||||||
|
|
||||||
|
#define SX1262_LORA_SYNC_WORD_MSB (0x0740)
|
||||||
|
#define SX1262_LORA_SYNC_WORD_LSB (0x0741)
|
||||||
|
|
||||||
|
void sx1262_setPacketType(uint8_t packetType);
|
||||||
|
void sx1262_init();
|
||||||
|
void sx1262_reset();
|
||||||
|
void sx1262_wait_for_busy();
|
||||||
|
void sx1262_write_command(uint8_t cmd, uint8_t *data, uint8_t len);
|
||||||
|
void sx1262_read_command(uint8_t cmd, uint8_t *tx_payload_buffer, uint8_t tx_payload_len, uint8_t *rx_buffer, uint8_t len);
|
||||||
|
sx1262_status_t sx1262_get_status();
|
||||||
|
void sx1262_setSleep(uint8_t sleepCFG);
|
||||||
|
void sx1262_setStandby(uint8_t standbyConf);
|
||||||
|
void sx1262_setFrequencySynthesis();
|
||||||
|
void sx1262_setMode(uint8_t mode, uint32_t timeout);
|
||||||
|
void sx1262_stopTimerOnPreamble(uint8_t enable);
|
||||||
|
void sx1262_setRxDutyCycle(uint32_t rxPeriod, uint32_t sleepPeriod);
|
||||||
|
void sx1262_setChannelActivityDetection(void);
|
||||||
|
void sx1262_setTxContinuousWave(void);
|
||||||
|
void sx1262_setTxInfinitePreamble(void);
|
||||||
|
void sx1262_setRegulatorMode(uint8_t mode);
|
||||||
|
void sx1262_calibrate(uint8_t calibParam);
|
||||||
|
void sx1262_calibrateImage(uint8_t freq1, uint8_t freq2);
|
||||||
|
void sx1262_setRxTXFallbackMode(uint8_t fallbackMode);
|
||||||
|
void sx1262_writeRegister(uint16_t address, const uint8_t *data, size_t length);
|
||||||
|
void sx1262_readRegister(uint16_t address, uint8_t *data, size_t length);
|
||||||
|
void sx1262_writeBuffer(uint8_t offset, const uint8_t *data, size_t length);
|
||||||
|
void sx1262_readBuffer(uint8_t offset, uint8_t *data, size_t length);
|
||||||
|
void sx1262_setDioIrqParams(uint16_t irqMask, uint16_t dio1Mask, uint16_t dio2Mask, uint16_t dio3Mask);
|
||||||
|
uint16_t sx1262_getIrqStatus(void);
|
||||||
|
void sx1262_clearIrqStatus(uint16_t clearIrqParam);
|
||||||
|
void sx1262_setDIO2AsRfSwitchCtrl(uint8_t enable);
|
||||||
|
void sx1262_setDIO3AsTCXOCtrl(uint8_t tcxoVoltage, uint32_t delay);
|
||||||
|
void sx1262_setFrequency(uint32_t frequency);
|
||||||
|
uint8_t sx1262_getPacketType();
|
||||||
|
void sx1262_configure_tx_power(uint8_t paDutyCycle, uint8_t hpMax, uint8_t paLut, int8_t power, uint8_t rampTime);
|
||||||
|
void sx1262_setLoRaPacketParams(sx1262_LoRaPacketParams_t *params);
|
||||||
|
void sx1262_setCadParams(uint8_t cadSymbolNum, uint8_t cadDetPeak, uint8_t cadDetMin, uint8_t cadExitMode, uint32_t cadTimeout);
|
||||||
|
void sx1262_setBufferBaseAddress(uint8_t txBaseAddr, uint8_t rxBaseAddr);
|
||||||
|
void sx1262_setLoRaSymbNumTimeout(uint8_t symbNum);
|
||||||
|
void sx1262_getStatus(uint8_t *status);
|
||||||
|
void sx1262_getRxBufferStatus(uint8_t *payloadLengthRx, uint8_t *rxStartBufferPointer);
|
||||||
|
void sx1262_getPacketStatus(uint8_t *rssi, uint8_t *snr, uint8_t *signalRssi);
|
||||||
|
uint8_t sx1262_getRssiInst(uint8_t *rssiInst);
|
||||||
|
void sx1262_getStats(uint16_t *pktReceived, uint16_t *pktCrcError, uint16_t *pktHeaderErr);
|
||||||
|
void sx1262_resetStats(void);
|
||||||
|
uint16_t sx1262_getDeviceErrors();
|
||||||
|
void sx1262_clearDeviceErrors(void);
|
||||||
|
|
||||||
|
void sx1262_setLoRaModulationParams(const sx1262_LoRaModulationParams_t *params);
|
||||||
|
|
||||||
|
void sx1262_setGFSKModulationParams(const sx1262_GFSKModulationParams_t *params);
|
||||||
|
|
||||||
|
#endif
|
Reference in New Issue
Block a user