mirror of
https://github.com/meshcore-dev/MeshCore.git
synced 2026-03-30 12:45:45 +00:00
Merge branch 'dev' into scan_exp
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -8,3 +8,4 @@ out/
|
||||
.direnv/
|
||||
.DS_Store
|
||||
.vscode/settings.json
|
||||
.vscode/extensions.json
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
#define PIN_BOARD_SCL1 41 //SCL for PMU and PFC8563 (RTC)
|
||||
#define PIN_PMU_IRQ 40 //IRQ pin for PMU
|
||||
|
||||
#define PIN_USER_BTN 0
|
||||
//#define PIN_USER_BTN 0
|
||||
|
||||
#define P_BOARD_SPI_MOSI 35 //SPI for SD Card and QMI8653 (IMU)
|
||||
#define P_BOARD_SPI_MISO 37 //SPI for SD Card and QMI8653 (IMU)
|
||||
@@ -61,10 +61,10 @@ public:
|
||||
|
||||
void begin() {
|
||||
|
||||
power_init();
|
||||
|
||||
ESP32Board::begin();
|
||||
|
||||
power_init();
|
||||
|
||||
esp_reset_reason_t reason = esp_reset_reason();
|
||||
if (reason == ESP_RST_DEEPSLEEP) {
|
||||
long wakeup_source = esp_sleep_get_ext1_wakeup_status();
|
||||
|
||||
@@ -80,6 +80,11 @@ bool RAK4631Board::startOTAUpdate(const char* id, char reply[]) {
|
||||
Bluefruit.Advertising.setFastTimeout(30); // number of seconds in fast mode
|
||||
Bluefruit.Advertising.start(0); // 0 = Don't stop advertising after n seconds
|
||||
|
||||
strcpy(reply, "OK - started");
|
||||
uint8_t mac_addr[6];
|
||||
memset(mac_addr, 0, sizeof(mac_addr));
|
||||
Bluefruit.getAddr(mac_addr);
|
||||
sprintf(reply, "OK - mac: %02X:%02X:%02X:%02X:%02X:%02X",
|
||||
mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -17,11 +17,20 @@ build_flags =
|
||||
-D SX126X_DIO3_TCXO_VOLTAGE=1.8
|
||||
-D SX126X_CURRENT_LIMIT=140
|
||||
-D SX126X_RX_BOOSTED_GAIN=1
|
||||
-D ENV_INCLUDE_AHTX0=1
|
||||
-D ENV_INCLUDE_BME280=1
|
||||
-D ENV_INCLUDE_INA3221=1
|
||||
-D ENV_INCLUDE_INA219=1
|
||||
build_src_filter = ${esp32_base.build_src_filter}
|
||||
+<../variants/heltec_v3>
|
||||
+<helpers/sensors>
|
||||
lib_deps =
|
||||
${esp32_base.lib_deps}
|
||||
adafruit/Adafruit SSD1306 @ ^2.5.13
|
||||
adafruit/Adafruit INA3221 Library @ ^1.0.1
|
||||
adafruit/Adafruit INA219 @ ^1.2.3
|
||||
adafruit/Adafruit AHTX0 @ ^2.0.5
|
||||
adafruit/Adafruit BME280 Library @ ^2.3.0
|
||||
|
||||
[env:Heltec_v3_repeater]
|
||||
extends = Heltec_lora32_v3
|
||||
|
||||
@@ -14,7 +14,7 @@ WRAPPER_CLASS radio_driver(radio, board);
|
||||
|
||||
ESP32RTCClock fallback_clock;
|
||||
AutoDiscoverRTCClock rtc_clock(fallback_clock);
|
||||
SensorManager sensors;
|
||||
EnvironmentSensorManager sensors;
|
||||
|
||||
#ifdef DISPLAY_CLASS
|
||||
DISPLAY_CLASS display;
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <helpers/CustomSX1262Wrapper.h>
|
||||
#include <helpers/AutoDiscoverRTCClock.h>
|
||||
#include <helpers/SensorManager.h>
|
||||
#include <helpers/sensors/EnvironmentSensorManager.h>
|
||||
#ifdef DISPLAY_CLASS
|
||||
#include <helpers/ui/SSD1306Display.h>
|
||||
#endif
|
||||
@@ -14,7 +15,7 @@
|
||||
extern HeltecV3Board board;
|
||||
extern WRAPPER_CLASS radio_driver;
|
||||
extern AutoDiscoverRTCClock rtc_clock;
|
||||
extern SensorManager sensors;
|
||||
extern EnvironmentSensorManager sensors;
|
||||
|
||||
#ifdef DISPLAY_CLASS
|
||||
extern DISPLAY_CLASS display;
|
||||
|
||||
@@ -8,19 +8,22 @@ build_flags =
|
||||
-D P_LORA_TX_LED=6
|
||||
-D PIN_BOARD_SDA=17
|
||||
-D PIN_BOARD_SCL=18
|
||||
-D PIN_USER_BTN=0
|
||||
-D RADIO_CLASS=CustomSX1262
|
||||
-D WRAPPER_CLASS=CustomSX1262Wrapper
|
||||
;-D DISPLAY_CLASS=SSD1306Display ;Needs to be modified for SH1106
|
||||
-D DISPLAY_CLASS=SH1106Display
|
||||
-D SX126X_RX_BOOSTED_GAIN=1
|
||||
-D SX126X_CURRENT_LIMIT=140
|
||||
build_src_filter = ${esp32_base.build_src_filter}
|
||||
+<../variants/lilygo_tbeam_supreme_SX1262>
|
||||
+<helpers/ui/SH1106Display.cpp>
|
||||
board_build.partitions = min_spiffs.csv ; get around 4mb flash limit
|
||||
lib_deps =
|
||||
${esp32_base.lib_deps}
|
||||
lewisxhe/XPowersLib @ ^0.2.7
|
||||
;adafruit/Adafruit SSD1306 @ ^2.5.13
|
||||
adafruit/Adafruit SH110X @ ^2.1.13
|
||||
stevemarple/MicroNMEA @ ^2.0.6
|
||||
adafruit/Adafruit BME280 Library @ ^2.3.0
|
||||
|
||||
; === LILYGO T-Beam S3 Supreme with SX1262 environments ===
|
||||
[env:T_Beam_S3_Supreme_SX1262_repeater]
|
||||
@@ -64,8 +67,8 @@ build_flags =
|
||||
-D MAX_CONTACTS=100
|
||||
-D MAX_GROUP_CHANNELS=8
|
||||
-D BLE_PIN_CODE=123456
|
||||
-D BLE_DEBUG_LOGGING=1
|
||||
-D OFFLINE_QUEUE_SIZE=256
|
||||
; -D BLE_DEBUG_LOGGING=1
|
||||
; -D ENABLE_PRIVATE_KEY_IMPORT=1
|
||||
; -D ENABLE_PRIVATE_KEY_EXPORT=1
|
||||
; -D MESH_PACKET_LOGGING=8
|
||||
|
||||
@@ -4,6 +4,10 @@
|
||||
|
||||
TBeamS3SupremeBoard board;
|
||||
|
||||
#ifdef DISPLAY_CLASS
|
||||
DISPLAY_CLASS display;
|
||||
#endif
|
||||
|
||||
bool pmuIntFlag;
|
||||
|
||||
#ifndef LORA_CR
|
||||
@@ -46,7 +50,7 @@ void scanDevices(TwoWire *w)
|
||||
switch (addr) {
|
||||
case 0x77:
|
||||
case 0x76:
|
||||
Serial.println("\tFound BMX280 Sensor");
|
||||
Serial.println("\tFound BME280 Sensor");
|
||||
deviceOnline |= BME280_ONLINE;
|
||||
break;
|
||||
case 0x34:
|
||||
@@ -107,6 +111,26 @@ void TBeamS3SupremeBoard::printPMU()
|
||||
|
||||
Serial.println();
|
||||
}
|
||||
void TbeamSupSensorManager::printBMEValues() {
|
||||
Serial.print("Temperature = ");
|
||||
Serial.print(bme.readTemperature());
|
||||
Serial.println(" *C");
|
||||
|
||||
Serial.print("Pressure = ");
|
||||
|
||||
Serial.print(bme.readPressure() / 100.0F);
|
||||
Serial.println(" hPa");
|
||||
|
||||
Serial.print("Approx. Altitude = ");
|
||||
Serial.print(bme.readAltitude(SEALEVELPRESSURE_HPA));
|
||||
Serial.println(" m");
|
||||
|
||||
Serial.print("Humidity = ");
|
||||
Serial.print(bme.readHumidity());
|
||||
Serial.println(" %");
|
||||
|
||||
Serial.println();
|
||||
}
|
||||
#endif
|
||||
|
||||
bool TBeamS3SupremeBoard::power_init()
|
||||
@@ -119,9 +143,9 @@ bool TBeamS3SupremeBoard::power_init()
|
||||
PMU.setChargingLedMode(XPOWERS_CHG_LED_CTRL_CHG);
|
||||
|
||||
// Set up PMU interrupts
|
||||
// MESH_DEBUG_PRINTLN("Setting up PMU interrupts");
|
||||
// pinMode(PIN_PMU_IRQ, INPUT_PULLUP);
|
||||
// attachInterrupt(PIN_PMU_IRQ, setPMUIntFlag, FALLING);
|
||||
MESH_DEBUG_PRINTLN("Setting up PMU interrupts");
|
||||
pinMode(PIN_PMU_IRQ, INPUT_PULLUP);
|
||||
attachInterrupt(PIN_PMU_IRQ, setPMUIntFlag, FALLING);
|
||||
|
||||
// GPS
|
||||
MESH_DEBUG_PRINTLN("Setting and enabling a-ldo4 for GPS");
|
||||
@@ -164,22 +188,22 @@ bool TBeamS3SupremeBoard::power_init()
|
||||
PMU.enableBLDO1();
|
||||
|
||||
// Out to header pins
|
||||
// MESH_DEBUG_PRINTLN("Setting and enabling b-ldo2 for output to header");
|
||||
// PMU.setBLDO2Voltage(3300);
|
||||
// PMU.enableBLDO2();
|
||||
MESH_DEBUG_PRINTLN("Setting and enabling b-ldo2 for output to header");
|
||||
PMU.setBLDO2Voltage(3300);
|
||||
PMU.enableBLDO2();
|
||||
|
||||
// MESH_DEBUG_PRINTLN("Setting and enabling dcdc4 for output to header");
|
||||
// PMU.setDC4Voltage(XPOWERS_AXP2101_DCDC4_VOL2_MAX); // 1.8V
|
||||
// PMU.enableDC4();
|
||||
MESH_DEBUG_PRINTLN("Setting and enabling dcdc4 for output to header");
|
||||
PMU.setDC4Voltage(XPOWERS_AXP2101_DCDC4_VOL2_MAX); // 1.8V
|
||||
PMU.enableDC4();
|
||||
|
||||
// MESH_DEBUG_PRINTLN("Setting and enabling dcdc5 for output to header");
|
||||
// PMU.setDC5Voltage(3300);
|
||||
// PMU.enableDC5();
|
||||
MESH_DEBUG_PRINTLN("Setting and enabling dcdc5 for output to header");
|
||||
PMU.setDC5Voltage(3300);
|
||||
PMU.enableDC5();
|
||||
|
||||
// Unused power rails
|
||||
MESH_DEBUG_PRINTLN("Disabling unused supplies dcdc2, dldo1 and dldo2");
|
||||
MESH_DEBUG_PRINTLN("Disabling unused supplies dcdc2, dcdc5, dldo1 and dldo2");
|
||||
PMU.disableDC2();
|
||||
PMU.disableDC5();
|
||||
//PMU.disableDC5();
|
||||
PMU.disableDLDO1();
|
||||
PMU.disableDLDO2();
|
||||
|
||||
@@ -199,18 +223,18 @@ bool TBeamS3SupremeBoard::power_init()
|
||||
PMU.enableVbusVoltageMeasure();
|
||||
|
||||
// Reset and re-enable PMU interrupts
|
||||
// MESH_DEBUG_PRINTLN("Re-enable interrupts");
|
||||
// PMU.disableIRQ(XPOWERS_AXP2101_ALL_IRQ);
|
||||
// PMU.clearIrqStatus();
|
||||
// PMU.enableIRQ(
|
||||
// XPOWERS_AXP2101_BAT_INSERT_IRQ | XPOWERS_AXP2101_BAT_REMOVE_IRQ | // Battery interrupts
|
||||
// XPOWERS_AXP2101_VBUS_INSERT_IRQ | XPOWERS_AXP2101_VBUS_REMOVE_IRQ | // VBUS interrupts
|
||||
// XPOWERS_AXP2101_PKEY_SHORT_IRQ | XPOWERS_AXP2101_PKEY_LONG_IRQ | // Power Key interrupts
|
||||
// XPOWERS_AXP2101_BAT_CHG_DONE_IRQ | XPOWERS_AXP2101_BAT_CHG_START_IRQ // Charging interrupts
|
||||
// );
|
||||
MESH_DEBUG_PRINTLN("Re-enable interrupts");
|
||||
PMU.disableIRQ(XPOWERS_AXP2101_ALL_IRQ);
|
||||
PMU.clearIrqStatus();
|
||||
PMU.enableIRQ(
|
||||
XPOWERS_AXP2101_BAT_INSERT_IRQ | XPOWERS_AXP2101_BAT_REMOVE_IRQ | // Battery interrupts
|
||||
XPOWERS_AXP2101_VBUS_INSERT_IRQ | XPOWERS_AXP2101_VBUS_REMOVE_IRQ | // VBUS interrupts
|
||||
XPOWERS_AXP2101_PKEY_SHORT_IRQ | XPOWERS_AXP2101_PKEY_LONG_IRQ | // Power Key interrupts
|
||||
XPOWERS_AXP2101_BAT_CHG_DONE_IRQ | XPOWERS_AXP2101_BAT_CHG_START_IRQ // Charging interrupts
|
||||
);
|
||||
#ifdef MESH_DEBUG
|
||||
// scanDevices(&Wire);
|
||||
// scanDevices(&Wire1);
|
||||
scanDevices(&Wire);
|
||||
scanDevices(&Wire1);
|
||||
printPMU();
|
||||
#endif
|
||||
|
||||
@@ -235,60 +259,14 @@ static bool readStringUntil(Stream& s, char dest[], size_t max_len, char term, u
|
||||
return millis() < timeout; // false, if timed out
|
||||
}
|
||||
|
||||
static bool l76kProbe()
|
||||
{
|
||||
bool result = false;
|
||||
uint32_t startTimeout ;
|
||||
Serial1.write("$PCAS03,0,0,0,0,0,0,0,0,0,0,,,0,0*02\r\n");
|
||||
delay(5);
|
||||
// Get version information
|
||||
startTimeout = millis() + 3000;
|
||||
MESH_DEBUG_PRINTLN("Trying to init L76K GPS");
|
||||
// Serial1.flush();
|
||||
while (Serial1.available()) {
|
||||
int c = Serial1.read();
|
||||
// Serial.write(c);
|
||||
// Serial.print(".");
|
||||
// Serial.flush();
|
||||
// Serial1.flush();
|
||||
if (millis() > startTimeout) {
|
||||
MESH_DEBUG_PRINTLN("L76K NMEA timeout!");
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
Serial1.flush();
|
||||
delay(200);
|
||||
|
||||
Serial1.write("$PCAS06,0*1B\r\n");
|
||||
|
||||
char ver[100];
|
||||
if (!readStringUntil(Serial1, ver, sizeof(ver), '\n', 500)) {
|
||||
MESH_DEBUG_PRINTLN("Get L76K timeout!");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (memcmp(ver, "$GPTXT,01,01,02", 15) == 0) {
|
||||
MESH_DEBUG_PRINTLN("L76K GNSS init succeeded, using L76K GNSS Module\n");
|
||||
result = true;
|
||||
}
|
||||
delay(500);
|
||||
|
||||
// Initialize the L76K Chip, use GPS + GLONASS
|
||||
Serial1.write("$PCAS04,5*1C\r\n");
|
||||
delay(250);
|
||||
// only ask for RMC and GGA
|
||||
Serial1.write("$PCAS03,1,0,0,0,1,0,0,0,0,0,,,0,0*02\r\n");
|
||||
delay(250);
|
||||
// Switch to Vehicle Mode, since SoftRF enables Aviation < 2g
|
||||
Serial1.write("$PCAS11,3*1E\r\n");
|
||||
return result;
|
||||
}
|
||||
|
||||
bool radio_init() {
|
||||
fallback_clock.begin();
|
||||
|
||||
rtc_clock.begin(Wire1);
|
||||
|
||||
// #ifdef MESH_DEBUG
|
||||
// printBMEValues();
|
||||
// #endif
|
||||
|
||||
#ifdef SX126X_DIO3_TCXO_VOLTAGE
|
||||
float tcxo = SX126X_DIO3_TCXO_VOLTAGE;
|
||||
@@ -340,55 +318,95 @@ void TbeamSupSensorManager::sleep_gps() {
|
||||
}
|
||||
|
||||
bool TbeamSupSensorManager::begin() {
|
||||
//init BME280
|
||||
if (! bme.begin(0x77, &Wire)) {
|
||||
MESH_DEBUG_PRINTLN("Could not find a valid BME280 sensor");
|
||||
bme_active = false;
|
||||
}
|
||||
else
|
||||
MESH_DEBUG_PRINTLN("BME280 found and init!");
|
||||
bme_active = true;
|
||||
|
||||
// init GPS port
|
||||
|
||||
Serial1.begin(GPS_BAUD_RATE, SERIAL_8N1, P_GPS_RX, P_GPS_TX);
|
||||
|
||||
bool result = false;
|
||||
for ( int i = 0; i < 3; ++i) {
|
||||
result = l76kProbe();
|
||||
if (result) {
|
||||
gps_active = true;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
MESH_DEBUG_PRINTLN("Sleeping GPS for initial state");
|
||||
sleep_gps();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TbeamSupSensorManager::querySensors(uint8_t requester_permissions, CayenneLPP& telemetry) {
|
||||
if (requester_permissions & TELEM_PERM_LOCATION) { // does requester have permission?
|
||||
telemetry.addGPS(TELEM_CHANNEL_SELF, node_lat, node_lon, node_altitude);
|
||||
}
|
||||
if (requester_permissions & TELEM_PERM_ENVIRONMENT && bme_active) { // does requester have permission?
|
||||
telemetry.addTemperature(TELEM_CHANNEL_SELF, node_temp);
|
||||
telemetry.addRelativeHumidity(TELEM_CHANNEL_SELF, node_hum);
|
||||
telemetry.addBarometricPressure(TELEM_CHANNEL_SELF, node_pres);
|
||||
//telemetry.addAltitude(TELEM_CHANNEL_SELF, node_alt);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void TbeamSupSensorManager::loop() {
|
||||
static long next_gps_update = 0;
|
||||
static long next_update = 0;
|
||||
|
||||
_nmea->loop();
|
||||
|
||||
if (millis() > next_gps_update) {
|
||||
if (_nmea->isValid()) {
|
||||
if (millis() > next_update) {
|
||||
if (_nmea->isValid() && gps_active) {
|
||||
node_lat = ((double)_nmea->getLatitude())/1000000.;
|
||||
node_lon = ((double)_nmea->getLongitude())/1000000.;
|
||||
node_altitude = ((double)_nmea->getAltitude()) / 1000.0;
|
||||
//Serial.printf("lat %f lon %f\r\n", _lat, _lon);
|
||||
MESH_DEBUG_PRINT("lat %f lon %f alt %f\r\n", node_lat, node_lon, node_altitude);
|
||||
}
|
||||
next_gps_update = millis() + 1000;
|
||||
|
||||
//read BME280 values
|
||||
if(bme_active){
|
||||
//node_alt = bme.readAltitude(SEALEVELPRESSURE_HPA);
|
||||
node_temp = bme.readTemperature();
|
||||
node_hum = bme.readHumidity();
|
||||
node_pres = (bme.readPressure() / 100.0F);
|
||||
|
||||
#ifdef MESH_DEBUG
|
||||
// Serial.print("Temperature = ");
|
||||
// Serial.print(node_temp);
|
||||
// Serial.println(" *C");
|
||||
|
||||
// Serial.print("Humidity = ");
|
||||
// Serial.print(node_hum);
|
||||
// Serial.println(" %");
|
||||
|
||||
// Serial.print("Pressure = ");
|
||||
// Serial.print(node_pres);
|
||||
// Serial.println(" hPa");
|
||||
|
||||
// Serial.print("Approx. Altitude = ");
|
||||
// Serial.print(node_alt);
|
||||
// Serial.println(" m");
|
||||
#endif
|
||||
}
|
||||
|
||||
next_update = millis() + 1000;
|
||||
}
|
||||
}
|
||||
|
||||
int TbeamSupSensorManager::getNumSettings() const { return 1; } // just one supported: "gps" (power switch)
|
||||
int TbeamSupSensorManager::getNumSettings() const {
|
||||
return 1;
|
||||
}
|
||||
|
||||
const char* TbeamSupSensorManager::getSettingName(int i) const {
|
||||
return i == 0 ? "gps" : NULL;
|
||||
switch(i){
|
||||
case 0: return "gps";
|
||||
default: NULL;
|
||||
}
|
||||
}
|
||||
|
||||
const char* TbeamSupSensorManager::getSettingValue(int i) const {
|
||||
if (i == 0) {
|
||||
return gps_active ? "1" : "0";
|
||||
switch(i){
|
||||
case 0: return gps_active == true ? "1" : "0";
|
||||
default: NULL;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool TbeamSupSensorManager::setSettingValue(const char* name, const char* value) {
|
||||
|
||||
@@ -8,15 +8,21 @@
|
||||
#include <helpers/AutoDiscoverRTCClock.h>
|
||||
#include <helpers/SensorManager.h>
|
||||
#include <helpers/sensors/LocationProvider.h>
|
||||
#include <Adafruit_BME280.h>
|
||||
|
||||
class TbeamSupSensorManager: public SensorManager {
|
||||
bool gps_active = false;
|
||||
bool bme_active = false;
|
||||
LocationProvider * _nmea;
|
||||
|
||||
Adafruit_BME280 bme;
|
||||
double node_temp, node_hum, node_pres;
|
||||
|
||||
#define SEALEVELPRESSURE_HPA (1013.25)
|
||||
|
||||
void start_gps();
|
||||
void sleep_gps();
|
||||
public:
|
||||
TbeamSupSensorManager(LocationProvider &nmea): _nmea(&nmea) { }
|
||||
TbeamSupSensorManager(LocationProvider &nmea): _nmea(&nmea) {node_temp = 0; node_hum = 0; node_pres = 0;}
|
||||
bool begin() override;
|
||||
bool querySensors(uint8_t requester_permissions, CayenneLPP& telemetry) override;
|
||||
void loop() override;
|
||||
@@ -24,6 +30,11 @@ class TbeamSupSensorManager: public SensorManager {
|
||||
const char* getSettingName(int i) const override;
|
||||
const char* getSettingValue(int i) const override;
|
||||
bool setSettingValue(const char* name, const char* value) override;
|
||||
|
||||
#ifdef MESH_DEBUG
|
||||
void printBMEValues();
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
extern TBeamS3SupremeBoard board;
|
||||
@@ -31,6 +42,11 @@ extern WRAPPER_CLASS radio_driver;
|
||||
extern AutoDiscoverRTCClock rtc_clock;
|
||||
extern TbeamSupSensorManager sensors;
|
||||
|
||||
#ifdef DISPLAY_CLASS
|
||||
#include <helpers/ui/SH1106Display.h>
|
||||
extern DISPLAY_CLASS display;
|
||||
#endif
|
||||
|
||||
enum {
|
||||
POWERMANAGE_ONLINE = _BV(0),
|
||||
DISPLAY_ONLINE = _BV(1),
|
||||
@@ -48,7 +64,6 @@ enum {
|
||||
OSC32768_ONLINE = _BV(13),
|
||||
};
|
||||
|
||||
bool power_init();
|
||||
bool radio_init();
|
||||
uint32_t radio_get_rng_seed();
|
||||
void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr);
|
||||
|
||||
Reference in New Issue
Block a user