Merge branch 'master' into regulatory-gain

This commit is contained in:
Thomas Göttgens 2024-06-20 16:13:54 +02:00 committed by GitHub
commit f0a38a5cf0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
33 changed files with 880 additions and 58 deletions

View File

@ -254,7 +254,7 @@ jobs:
chmod +x ./output/device-update.sh
- name: Zip firmware
run: zip -j -9 -r ./firmware-${{ steps.version.outputs.version }}.zip ./output
run: zip -j -9 -r ./firmware-${{ steps.version.outputs.version }}.zip ./output -x *.deb
- uses: actions/download-artifact@v4
with:

2
.trunk/configs/.bandit Normal file
View File

@ -0,0 +1,2 @@
[bandit]
skips = B101

View File

@ -2,7 +2,7 @@
// See http://go.microsoft.com/fwlink/?LinkId=827846
// for the documentation about the extensions.json format
"recommendations": [
"ms-vscode.cpptools",
"ms-vscode.cpptools",
"platformio.platformio-ide",
"trunk.io"
],

View File

@ -3,5 +3,6 @@
"editor.defaultFormatter": "trunk.io",
"trunk.enableWindows": true,
"files.insertFinalNewline": false,
"files.trimFinalNewlines": false
"files.trimFinalNewlines": false,
"cmake.configureOnOpen": false
}

View File

@ -29,6 +29,7 @@ default_envs = tbeam
;default_envs = meshtastic-dr-dev
;default_envs = m5stack-coreink
;default_envs = rak4631
;default_envs = rak2560
;default_envs = rak10701
;default_envs = wio-e5
;default_envs = radiomaster_900_bandit_nano
@ -79,7 +80,7 @@ monitor_speed = 115200
lib_deps =
jgromes/RadioLib@~6.6.0
https://github.com/meshtastic/esp8266-oled-ssd1306.git#69ba98fa30e67b12d4577b121f210f3eb7049d6b ; ESP8266_SSD1306
https://github.com/meshtastic/esp8266-oled-ssd1306.git#2b40affbe7f7dc63b6c00fa88e7e12ed1f8e1719 ; ESP8266_SSD1306
mathertel/OneButton@^2.5.0 ; OneButton library for non-blocking button debounce
https://github.com/meshtastic/arduino-fsm.git#7db3702bf0cfe97b783d6c72595e3f38e0b19159
https://github.com/meshtastic/TinyGPSPlus.git#71a82db35f3b973440044c476d4bcdc673b104f4

@ -1 +1 @@
Subproject commit dc066c89f73fce882e5a47648cba18a1967a7f56
Subproject commit 1c3029f2868e5fc49809fd378f6c0c66aee0eaf4

View File

@ -75,6 +75,10 @@ INA219Sensor ina219Sensor;
INA3221Sensor ina3221Sensor;
#endif
#if HAS_RAKPROT && !defined(ARCH_PORTDUINO)
RAK9154Sensor rak9154Sensor;
#endif
#ifdef HAS_PMU
#include "XPowersAXP192.tpp"
#include "XPowersAXP2101.tpp"
@ -145,6 +149,12 @@ class AnalogBatteryLevel : public HasBatteryLevel
*/
virtual int getBatteryPercent() override
{
#if defined(HAS_RAKPROT) && !defined(ARCH_PORTDUINO) && !defined(HAS_PMU)
if (hasRAK()) {
return rak9154Sensor.getBusBatteryPercent();
}
#endif
float v = getBattVoltage();
if (v < noBatVolt)
@ -184,6 +194,12 @@ class AnalogBatteryLevel : public HasBatteryLevel
virtual uint16_t getBattVoltage() override
{
#if defined(HAS_RAKPROT) && !defined(ARCH_PORTDUINO) && !defined(HAS_PMU)
if (hasRAK()) {
return getRAKVoltage();
}
#endif
#if HAS_TELEMETRY && !defined(ARCH_PORTDUINO) && !defined(HAS_PMU) && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
if (hasINA()) {
LOG_DEBUG("Using INA on I2C addr 0x%x for device battery voltage\n", config.power.device_battery_ina_address);
@ -335,19 +351,19 @@ class AnalogBatteryLevel : public HasBatteryLevel
virtual bool isVbusIn() override
{
#ifdef EXT_PWR_DETECT
#ifdef HELTEC_CAPSULE_SENSOR_V3
// if external powered that pin will be pulled down
if (digitalRead(EXT_PWR_DETECT) == LOW) {
return true;
}
// if it's not LOW - check the battery
#else
// if external powered that pin will be pulled up
if (digitalRead(EXT_PWR_DETECT) == HIGH) {
return true;
}
// if it's not HIGH - check the battery
#endif
#ifdef HELTEC_CAPSULE_SENSOR_V3
// if external powered that pin will be pulled down
if (digitalRead(EXT_PWR_DETECT) == LOW) {
return true;
}
// if it's not LOW - check the battery
#else
// if external powered that pin will be pulled up
if (digitalRead(EXT_PWR_DETECT) == HIGH) {
return true;
}
// if it's not HIGH - check the battery
#endif
#endif
return getBattVoltage() > chargingVolt;
}
@ -356,6 +372,11 @@ class AnalogBatteryLevel : public HasBatteryLevel
/// we can't be smart enough to say 'full'?
virtual bool isCharging() override
{
#if defined(HAS_RAKPROT) && !defined(ARCH_PORTDUINO) && !defined(HAS_PMU)
if (hasRAK()) {
return (rak9154Sensor.isCharging()) ? OptTrue : OptFalse;
}
#endif
#ifdef EXT_CHRG_DETECT
return digitalRead(EXT_CHRG_DETECT) == ext_chrg_detect_value;
#else
@ -379,6 +400,18 @@ class AnalogBatteryLevel : public HasBatteryLevel
float last_read_value = (OCV[NUM_OCV_POINTS - 1] * NUM_CELLS);
uint32_t last_read_time_ms = 0;
#if defined(HAS_RAKPROT)
uint16_t getRAKVoltage() { return rak9154Sensor.getBusVoltageMv(); }
bool hasRAK()
{
if (!rak9154Sensor.isInitialized())
return rak9154Sensor.runOnce() > 0;
return rak9154Sensor.isRunning();
}
#endif
#if HAS_TELEMETRY && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && !defined(ARCH_PORTDUINO)
uint16_t getINAVoltage()
{
@ -428,11 +461,11 @@ Power::Power() : OSThread("Power")
bool Power::analogInit()
{
#ifdef EXT_PWR_DETECT
#ifdef HELTEC_CAPSULE_SENSOR_V3
pinMode(EXT_PWR_DETECT, INPUT_PULLUP);
#else
pinMode(EXT_PWR_DETECT, INPUT);
#endif
#ifdef HELTEC_CAPSULE_SENSOR_V3
pinMode(EXT_PWR_DETECT, INPUT_PULLUP);
#else
pinMode(EXT_PWR_DETECT, INPUT);
#endif
#endif
#ifdef EXT_CHRG_DETECT
pinMode(EXT_CHRG_DETECT, ext_chrg_detect_mode);

View File

@ -6,6 +6,7 @@ const ScanI2C::FoundDevice ScanI2C::DEVICE_NONE = ScanI2C::FoundDevice(ScanI2C::
ScanI2C::ScanI2C() = default;
void ScanI2C::scanPort(ScanI2C::I2CPort port) {}
void ScanI2C::scanPort(ScanI2C::I2CPort port, uint8_t *address, uint8_t asize) {}
void ScanI2C::setSuppressScreen()
{

View File

@ -88,6 +88,7 @@ class ScanI2C
ScanI2C();
virtual void scanPort(ScanI2C::I2CPort);
virtual void scanPort(ScanI2C::I2CPort, uint8_t *, uint8_t);
/*
* A bit of a hack, this tells the scanner not to tell later systems there is a screen to avoid enabling it.

View File

@ -14,6 +14,15 @@
#define XPOWERS_AXP192_AXP2101_ADDRESS 0x34
#endif
bool in_array(uint8_t *array, int size, uint8_t lookfor)
{
int i;
for (i = 0; i < size; i++)
if (lookfor == array[i])
return true;
return false;
}
ScanI2C::FoundDevice ScanI2CTwoWire::find(ScanI2C::DeviceType type) const
{
concurrency::LockGuard guard((concurrency::Lock *)&lock);
@ -135,11 +144,11 @@ uint16_t ScanI2CTwoWire::getRegisterValue(const ScanI2CTwoWire::RegisterLocation
type = T; \
break;
void ScanI2CTwoWire::scanPort(I2CPort port)
void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
{
concurrency::LockGuard guard((concurrency::Lock *)&lock);
LOG_DEBUG("Scanning for i2c devices on port %d\n", port);
LOG_DEBUG("Scanning for I2C devices on port %d\n", port);
uint8_t err;
@ -163,6 +172,11 @@ void ScanI2CTwoWire::scanPort(I2CPort port)
#endif
for (addr.address = 1; addr.address < 127; addr.address++) {
if (asize != 0) {
if (!in_array(address, asize, addr.address))
continue;
LOG_DEBUG("Scanning address 0x%x\n", addr.address);
}
i2cBus->beginTransmission(addr.address);
#ifdef ARCH_PORTDUINO
if (i2cBus->read() != -1)
@ -356,7 +370,7 @@ void ScanI2CTwoWire::scanPort(I2CPort port)
LOG_INFO("Device found at address 0x%x was not able to be enumerated\n", addr.address);
}
} else if (err == 4) {
LOG_ERROR("Unknown error at address 0x%x\n", addr);
LOG_ERROR("Unknown error at address 0x%x\n", addr.address);
}
// Check if a type was found for the enumerated device - save, if so
@ -367,6 +381,11 @@ void ScanI2CTwoWire::scanPort(I2CPort port)
}
}
void ScanI2CTwoWire::scanPort(I2CPort port)
{
scanPort(port, nullptr, 0);
}
TwoWire *ScanI2CTwoWire::fetchI2CBus(ScanI2C::DeviceAddress address) const
{
if (address.port == ScanI2C::I2CPort::WIRE) {

View File

@ -16,6 +16,8 @@ class ScanI2CTwoWire : public ScanI2C
public:
void scanPort(ScanI2C::I2CPort) override;
void scanPort(ScanI2C::I2CPort, uint8_t *, uint8_t) override;
ScanI2C::FoundDevice find(ScanI2C::DeviceType) const override;
TwoWire *fetchI2CBus(ScanI2C::DeviceAddress) const;
@ -53,4 +55,4 @@ class ScanI2CTwoWire : public ScanI2C
uint16_t getRegisterValue(const RegisterLocation &, ResponseWidth) const;
DeviceType probeOLED(ScanI2C::DeviceAddress) const;
};
};

View File

@ -1,7 +1,7 @@
#include "InputBroker.h"
#include "PowerFSM.h" // needed for event trigger
InputBroker *inputBroker;
InputBroker *inputBroker = nullptr;
InputBroker::InputBroker(){};

View File

@ -1,5 +1,7 @@
#include "cardKbI2cImpl.h"
#include "InputBroker.h"
#include "detect/ScanI2CTwoWire.h"
#include "main.h"
CardKbI2cImpl *cardKbI2cImpl;
@ -7,10 +9,52 @@ CardKbI2cImpl::CardKbI2cImpl() : KbI2cBase("cardKB") {}
void CardKbI2cImpl::init()
{
#ifndef ARCH_PORTDUINO
if (cardkb_found.address == 0x00) {
LOG_DEBUG("Rescanning for I2C keyboard\n");
uint8_t i2caddr_scan[] = {CARDKB_ADDR, TDECK_KB_ADDR, BBQ10_KB_ADDR};
uint8_t i2caddr_asize = 3;
auto i2cScanner = std::unique_ptr<ScanI2CTwoWire>(new ScanI2CTwoWire());
#if defined(I2C_SDA1)
i2cScanner->scanPort(ScanI2C::I2CPort::WIRE1, i2caddr_scan, i2caddr_asize);
#endif
i2cScanner->scanPort(ScanI2C::I2CPort::WIRE, i2caddr_scan, i2caddr_asize);
auto kb_info = i2cScanner->firstKeyboard();
if (kb_info.type != ScanI2C::DeviceType::NONE) {
cardkb_found = kb_info.address;
switch (kb_info.type) {
case ScanI2C::DeviceType::RAK14004:
kb_model = 0x02;
break;
case ScanI2C::DeviceType::CARDKB:
kb_model = 0x00;
break;
case ScanI2C::DeviceType::TDECKKB:
// assign an arbitrary value to distinguish from other models
kb_model = 0x10;
break;
case ScanI2C::DeviceType::BBQ10KB:
// assign an arbitrary value to distinguish from other models
kb_model = 0x11;
break;
default:
// use this as default since it's also just zero
LOG_WARN("kb_info.type is unknown(0x%02x), setting kb_model=0x00\n", kb_info.type);
kb_model = 0x00;
}
}
if (cardkb_found.address == 0x00) {
disable();
return;
}
}
#else
if (cardkb_found.address == 0x00) {
disable();
return;
}
#endif
inputBroker->registerSource(this);
}

View File

@ -1,6 +1,5 @@
#pragma once
#include "kbI2cBase.h"
#include "main.h"
/**
* @brief The idea behind this class to have static methods for the event handlers.

View File

@ -1,6 +1,7 @@
#include "kbI2cBase.h"
#include "configuration.h"
#include "detect/ScanI2C.h"
#include "detect/ScanI2CTwoWire.h"
extern ScanI2C::DeviceAddress cardkb_found;
extern uint8_t kb_model;
@ -29,11 +30,6 @@ uint8_t read_from_14004(TwoWire *i2cBus, uint8_t reg, uint8_t *data, uint8_t len
int32_t KbI2cBase::runOnce()
{
if (cardkb_found.address == 0x00) {
// Input device is not detected.
return INT32_MAX;
}
if (!i2cBus) {
switch (cardkb_found.port) {
case ScanI2C::WIRE1:

View File

@ -41,13 +41,14 @@
#endif
#if !MESHTASTIC_EXCLUDE_BLUETOOTH
#include "nimble/NimbleBluetooth.h"
NimbleBluetooth *nimbleBluetooth;
NimbleBluetooth *nimbleBluetooth = nullptr;
#endif
#endif
#ifdef ARCH_NRF52
#include "NRF52Bluetooth.h"
NRF52Bluetooth *nrf52Bluetooth;
NRF52Bluetooth *nrf52Bluetooth = nullptr;
;
#endif
#if HAS_WIFI
@ -94,23 +95,23 @@ NRF52Bluetooth *nrf52Bluetooth;
#include "ButtonThread.h"
#endif
#include "AmbientLightingThread.h"
#include "PowerFSMThread.h"
#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
#include "AccelerometerThread.h"
#include "AmbientLightingThread.h"
AccelerometerThread *accelerometerThread;
AccelerometerThread *accelerometerThread = nullptr;
#endif
#ifdef HAS_I2S
#include "AudioThread.h"
AudioThread *audioThread;
AudioThread *audioThread = nullptr;
#endif
using namespace concurrency;
// We always create a screen object, but we only init it if we find the hardware
graphics::Screen *screen;
graphics::Screen *screen = nullptr;
// Global power status
meshtastic::PowerStatus *powerStatus = new meshtastic::PowerStatus();
@ -421,10 +422,6 @@ void setup()
auto i2cCount = i2cScanner->countDevices();
if (i2cCount == 0) {
LOG_INFO("No I2C devices found\n");
Wire.end();
#ifdef I2C_SDA1
Wire1.end();
#endif
} else {
LOG_INFO("%i I2C devices found\n", i2cCount);
}

View File

@ -511,6 +511,8 @@ typedef struct _meshtastic_Config_BluetoothConfig {
meshtastic_Config_BluetoothConfig_PairingMode mode;
/* Specified PIN for PairingMode.FixedPin */
uint32_t fixed_pin;
/* Enables device (serial style logs) over Bluetooth */
bool device_logging_enabled;
} meshtastic_Config_BluetoothConfig;
typedef struct _meshtastic_Config {
@ -615,7 +617,7 @@ extern "C" {
#define meshtastic_Config_NetworkConfig_IpV4Config_init_default {0, 0, 0, 0}
#define meshtastic_Config_DisplayConfig_init_default {0, _meshtastic_Config_DisplayConfig_GpsCoordinateFormat_MIN, 0, 0, 0, _meshtastic_Config_DisplayConfig_DisplayUnits_MIN, _meshtastic_Config_DisplayConfig_OledType_MIN, _meshtastic_Config_DisplayConfig_DisplayMode_MIN, 0, 0, _meshtastic_Config_DisplayConfig_CompassOrientation_MIN}
#define meshtastic_Config_LoRaConfig_init_default {0, _meshtastic_Config_LoRaConfig_ModemPreset_MIN, 0, 0, 0, 0, _meshtastic_Config_LoRaConfig_RegionCode_MIN, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0}, 0}
#define meshtastic_Config_BluetoothConfig_init_default {0, _meshtastic_Config_BluetoothConfig_PairingMode_MIN, 0}
#define meshtastic_Config_BluetoothConfig_init_default {0, _meshtastic_Config_BluetoothConfig_PairingMode_MIN, 0, 0}
#define meshtastic_Config_init_zero {0, {meshtastic_Config_DeviceConfig_init_zero}}
#define meshtastic_Config_DeviceConfig_init_zero {_meshtastic_Config_DeviceConfig_Role_MIN, 0, 0, 0, 0, _meshtastic_Config_DeviceConfig_RebroadcastMode_MIN, 0, 0, 0, 0, "", 0}
#define meshtastic_Config_PositionConfig_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _meshtastic_Config_PositionConfig_GpsMode_MIN}
@ -624,7 +626,7 @@ extern "C" {
#define meshtastic_Config_NetworkConfig_IpV4Config_init_zero {0, 0, 0, 0}
#define meshtastic_Config_DisplayConfig_init_zero {0, _meshtastic_Config_DisplayConfig_GpsCoordinateFormat_MIN, 0, 0, 0, _meshtastic_Config_DisplayConfig_DisplayUnits_MIN, _meshtastic_Config_DisplayConfig_OledType_MIN, _meshtastic_Config_DisplayConfig_DisplayMode_MIN, 0, 0, _meshtastic_Config_DisplayConfig_CompassOrientation_MIN}
#define meshtastic_Config_LoRaConfig_init_zero {0, _meshtastic_Config_LoRaConfig_ModemPreset_MIN, 0, 0, 0, 0, _meshtastic_Config_LoRaConfig_RegionCode_MIN, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0}, 0}
#define meshtastic_Config_BluetoothConfig_init_zero {0, _meshtastic_Config_BluetoothConfig_PairingMode_MIN, 0}
#define meshtastic_Config_BluetoothConfig_init_zero {0, _meshtastic_Config_BluetoothConfig_PairingMode_MIN, 0, 0}
/* Field tags (for use in manual encoding/decoding) */
#define meshtastic_Config_DeviceConfig_role_tag 1
@ -702,6 +704,7 @@ extern "C" {
#define meshtastic_Config_BluetoothConfig_enabled_tag 1
#define meshtastic_Config_BluetoothConfig_mode_tag 2
#define meshtastic_Config_BluetoothConfig_fixed_pin_tag 3
#define meshtastic_Config_BluetoothConfig_device_logging_enabled_tag 4
#define meshtastic_Config_device_tag 1
#define meshtastic_Config_position_tag 2
#define meshtastic_Config_power_tag 3
@ -833,7 +836,8 @@ X(a, STATIC, SINGULAR, BOOL, ignore_mqtt, 104)
#define meshtastic_Config_BluetoothConfig_FIELDLIST(X, a) \
X(a, STATIC, SINGULAR, BOOL, enabled, 1) \
X(a, STATIC, SINGULAR, UENUM, mode, 2) \
X(a, STATIC, SINGULAR, UINT32, fixed_pin, 3)
X(a, STATIC, SINGULAR, UINT32, fixed_pin, 3) \
X(a, STATIC, SINGULAR, BOOL, device_logging_enabled, 4)
#define meshtastic_Config_BluetoothConfig_CALLBACK NULL
#define meshtastic_Config_BluetoothConfig_DEFAULT NULL
@ -860,7 +864,7 @@ extern const pb_msgdesc_t meshtastic_Config_BluetoothConfig_msg;
/* Maximum encoded size of messages (where known) */
#define MESHTASTIC_MESHTASTIC_CONFIG_PB_H_MAX_SIZE meshtastic_Config_size
#define meshtastic_Config_BluetoothConfig_size 10
#define meshtastic_Config_BluetoothConfig_size 12
#define meshtastic_Config_DeviceConfig_size 100
#define meshtastic_Config_DisplayConfig_size 30
#define meshtastic_Config_LoRaConfig_size 80

View File

@ -308,7 +308,7 @@ extern const pb_msgdesc_t meshtastic_OEMStore_msg;
#define MESHTASTIC_MESHTASTIC_DEVICEONLY_PB_H_MAX_SIZE meshtastic_OEMStore_size
#define meshtastic_ChannelFile_size 718
#define meshtastic_NodeInfoLite_size 166
#define meshtastic_OEMStore_size 3370
#define meshtastic_OEMStore_size 3372
#define meshtastic_PositionLite_size 28
#ifdef __cplusplus

View File

@ -181,7 +181,7 @@ extern const pb_msgdesc_t meshtastic_LocalModuleConfig_msg;
/* Maximum encoded size of messages (where known) */
#define MESHTASTIC_MESHTASTIC_LOCALONLY_PB_H_MAX_SIZE meshtastic_LocalModuleConfig_size
#define meshtastic_LocalConfig_size 539
#define meshtastic_LocalConfig_size 541
#define meshtastic_LocalModuleConfig_size 685
#ifdef __cplusplus

View File

@ -67,6 +67,10 @@ typedef enum _meshtastic_HardwareModel {
meshtastic_HardwareModel_WIPHONE = 20,
/* WIO Tracker WM1110 family from Seeed Studio. Includes wio-1110-tracker and wio-1110-sdk */
meshtastic_HardwareModel_WIO_WM1110 = 21,
/* RAK2560 Solar base station based on RAK4630 */
meshtastic_HardwareModel_RAK2560 = 22,
/* Heltec HRU-3601: https://heltec.org/project/hru-3601/ */
meshtastic_HardwareModel_HELTEC_HRU_3601 = 23,
/* B&Q Consulting Station Edition G1: https://uniteng.com/wiki/doku.php?id=meshtastic:station */
meshtastic_HardwareModel_STATION_G1 = 25,
/* RAK11310 (RP2040 + SX1262) */

View File

@ -42,6 +42,7 @@
#include "modules/Telemetry/DeviceTelemetry.h"
#endif
#if HAS_SENSOR && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
#include "main.h"
#include "modules/Telemetry/AirQualityTelemetry.h"
#include "modules/Telemetry/EnvironmentTelemetry.h"
#endif

View File

@ -1,7 +1,10 @@
#include "OPT3001Sensor.h"
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "TelemetrySensor.h"
#include "configuration.h"
#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "OPT3001Sensor.h"
#include "TelemetrySensor.h"
#include <ClosedCube_OPT3001.h>
OPT3001Sensor::OPT3001Sensor() : TelemetrySensor(meshtastic_TelemetrySensorType_OPT3001, "OPT3001") {}
@ -41,4 +44,6 @@ bool OPT3001Sensor::getMetrics(meshtastic_Telemetry *measurement)
LOG_INFO("Lux: %f\n", measurement->variant.environment_metrics.lux);
return true;
}
}
#endif

View File

@ -1,3 +1,8 @@
#pragma once
#include "configuration.h"
#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "TelemetrySensor.h"
#include <ClosedCube_OPT3001.h>
@ -14,4 +19,6 @@ class OPT3001Sensor : public TelemetrySensor
OPT3001Sensor();
virtual int32_t runOnce() override;
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
};
};
#endif

View File

@ -42,6 +42,8 @@
#define HW_VENDOR meshtastic_HardwareModel_NRF52840DK
#elif defined(ARDUINO_NRF52840_PPR)
#define HW_VENDOR meshtastic_HardwareModel_PPR
#elif defined(RAK2560)
#define HW_VENDOR meshtastic_HardwareModel_RAK2560
#elif defined(RAK4630)
#define HW_VENDOR meshtastic_HardwareModel_RAK4631
#elif defined(TTGO_T_ECHO)

View File

@ -1,7 +1,9 @@
#pragma once
#include "../variants/rak2560/RAK9154Sensor.h"
#include "PowerStatus.h"
#include "concurrency/OSThread.h"
#include "configuration.h"
#ifdef ARCH_ESP32
#include <esp_adc_cal.h>
#include <soc/adc_channel.h>
@ -46,6 +48,11 @@ extern INA219Sensor ina219Sensor;
extern INA3221Sensor ina3221Sensor;
#endif
#if HAS_RAKPROT && !defined(ARCH_PORTDUINO)
#include "../variants/rak2560/RAK9154Sensor.h"
extern RAK9154Sensor rak9154Sensor;
#endif
class Power : private concurrency::OSThread
{

View File

@ -0,0 +1,183 @@
#ifdef HAS_RAKPROT
#include "../variants/rak2560/RAK9154Sensor.h"
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "../modules/Telemetry/Sensor/TelemetrySensor.h"
#include "configuration.h"
#include "concurrency/Periodic.h"
#include <RAK-OneWireSerial.h>
using namespace concurrency;
#define BOOT_DATA_REQ
RAK9154Sensor::RAK9154Sensor() : TelemetrySensor(meshtastic_TelemetrySensorType_SENSOR_UNSET, "RAK1954") {}
static Periodic *onewirePeriodic;
static SoftwareHalfSerial mySerial(HALF_UART_PIN); // Wire pin P0.15
static uint8_t buff[0x100];
static uint16_t bufflen = 0;
static int16_t dc_cur = 0;
static uint16_t dc_vol = 0;
static uint8_t dc_prec = 0;
static uint8_t provision = 0;
static void onewire_evt(const uint8_t pid, const uint8_t sid, const SNHUBAPI_EVT_E eid, uint8_t *msg, uint16_t len)
{
switch (eid) {
case SNHUBAPI_EVT_RECV_REQ:
case SNHUBAPI_EVT_RECV_RSP:
break;
case SNHUBAPI_EVT_QSEND:
mySerial.write(msg, len);
break;
case SNHUBAPI_EVT_ADD_SID:
// LOG_INFO("+ADD:SID:[%02x]\r\n", msg[0]);
break;
case SNHUBAPI_EVT_ADD_PID:
// LOG_INFO("+ADD:PID:[%02x]\r\n", msg[0]);
#ifdef BOOT_DATA_REQ
provision = msg[0];
#endif
break;
case SNHUBAPI_EVT_GET_INTV:
break;
case SNHUBAPI_EVT_GET_ENABLE:
break;
case SNHUBAPI_EVT_SDATA_REQ:
// LOG_INFO("+EVT:PID[%02x],IPSO[%02x]\r\n",pid,msg[0]);
// for( uint16_t i=1; i<len; i++)
// {
// LOG_INFO("%02x,", msg[i]);
// }
// LOG_INFO("\r\n");
switch (msg[0]) {
case RAK_IPSO_CAPACITY:
dc_prec = msg[1];
if (dc_prec > 100) {
dc_prec = 100;
}
break;
case RAK_IPSO_DC_CURRENT:
dc_cur = (msg[2] << 8) + msg[1];
break;
case RAK_IPSO_DC_VOLTAGE:
dc_vol = (msg[2] << 8) + msg[1];
dc_vol *= 10;
break;
default:
break;
}
break;
case SNHUBAPI_EVT_REPORT:
// LOG_INFO("+EVT:PID[%02x],IPSO[%02x]\r\n",pid,msg[0]);
// for( uint16_t i=1; i<len; i++)
// {
// LOG_INFO("%02x,", msg[i]);
// }
// LOG_INFO("\r\n");
switch (msg[0]) {
case RAK_IPSO_CAPACITY:
dc_prec = msg[1];
if (dc_prec > 100) {
dc_prec = 100;
}
break;
case RAK_IPSO_DC_CURRENT:
dc_cur = (msg[1] << 8) + msg[2];
break;
case RAK_IPSO_DC_VOLTAGE:
dc_vol = (msg[1] << 8) + msg[2];
dc_vol *= 10;
break;
default:
break;
}
break;
case SNHUBAPI_EVT_CHKSUM_ERR:
LOG_INFO("+ERR:CHKSUM\r\n");
break;
case SNHUBAPI_EVT_SEQ_ERR:
LOG_INFO("+ERR:SEQUCE\r\n");
break;
default:
break;
}
}
static int32_t onewireHandle()
{
if (provision != 0) {
RakSNHub_Protocl_API.get.data(provision);
provision = 0;
}
while (mySerial.available()) {
char a = mySerial.read();
buff[bufflen++] = a;
delay(2); // continue data, timeout=2ms
}
if (bufflen != 0) {
RakSNHub_Protocl_API.process((uint8_t *)buff, bufflen);
bufflen = 0;
}
return 50;
}
int32_t RAK9154Sensor::runOnce()
{
onewirePeriodic = new Periodic("onewireHandle", onewireHandle);
mySerial.begin(9600);
RakSNHub_Protocl_API.init(onewire_evt);
status = true;
initialized = true;
return 0;
}
void RAK9154Sensor::setup()
{
// Set up oversampling and filter initialization
}
bool RAK9154Sensor::getMetrics(meshtastic_Telemetry *measurement)
{
return true;
}
uint16_t RAK9154Sensor::getBusVoltageMv()
{
return dc_vol;
}
int RAK9154Sensor::getBusBatteryPercent()
{
return (int)dc_prec;
}
bool RAK9154Sensor::isCharging()
{
return (dc_cur > 0) ? true : false;
}
#endif // HAS_RAKPROT

View File

@ -0,0 +1,23 @@
#ifdef HAS_RAKPROT
#ifndef _RAK9154SENSOR_H
#define _RAK9154SENSOR_H 1
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "../modules/Telemetry/Sensor/TelemetrySensor.h"
#include "../modules/Telemetry/Sensor/VoltageSensor.h"
class RAK9154Sensor : public TelemetrySensor, VoltageSensor
{
private:
protected:
virtual void setup() override;
public:
RAK9154Sensor();
virtual int32_t runOnce() override;
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
virtual uint16_t getBusVoltageMv() override;
int getBusBatteryPercent();
bool isCharging();
};
#endif // _RAK9154SENSOR_H
#endif // HAS_RAKPROT

View File

@ -0,0 +1,113 @@
import struct
Import("env") # noqa: F821
# Parse input and create UF2 file
def create_uf2(source, target, env):
# source_hex = target[0].get_abspath()
source_hex = target[0].get_string(False)
source_hex = ".\\" + source_hex
print("#########################################################")
print("Create UF2 from " + source_hex)
print("#########################################################")
# print("Source: " + source_hex)
target = source_hex.replace(".hex", "")
target = target + ".uf2"
# print("Target: " + target)
with open(source_hex, mode="rb") as f:
inpbuf = f.read()
outbuf = convert_from_hex_to_uf2(inpbuf.decode("utf-8"))
write_file(target, outbuf)
print("#########################################################")
print(target + " is ready to flash to target device")
print("#########################################################")
# Add callback after .hex file was created
env.AddPostAction("$BUILD_DIR/${PROGNAME}.hex", create_uf2) # noqa: F821
# UF2 creation taken from uf2conv.py
UF2_MAGIC_START0 = 0x0A324655 # "UF2\n"
UF2_MAGIC_START1 = 0x9E5D5157 # Randomly selected
UF2_MAGIC_END = 0x0AB16F30 # Ditto
familyid = 0xADA52840
class Block:
def __init__(self, addr):
self.addr = addr
self.bytes = bytearray(256)
def encode(self, blockno, numblocks):
global familyid
flags = 0x0
if familyid:
flags |= 0x2000
hd = struct.pack(
"<IIIIIIII",
UF2_MAGIC_START0,
UF2_MAGIC_START1,
flags,
self.addr,
256,
blockno,
numblocks,
familyid,
)
hd += self.bytes[0:256]
while len(hd) < 512 - 4:
hd += b"\x00"
hd += struct.pack("<I", UF2_MAGIC_END)
return hd
def write_file(name, buf):
with open(name, "wb") as f:
f.write(buf)
# print("Wrote %d bytes to %s." % (len(buf), name))
def convert_from_hex_to_uf2(buf):
global appstartaddr
appstartaddr = None
upper = 0
currblock = None
blocks = []
for line in buf.split("\n"):
if line[0] != ":":
continue
i = 1
rec = []
while i < len(line) - 1:
rec.append(int(line[i : i + 2], 16))
i += 2
tp = rec[3]
if tp == 4:
upper = ((rec[4] << 8) | rec[5]) << 16
elif tp == 2:
upper = ((rec[4] << 8) | rec[5]) << 4
assert (upper & 0xFFFF) == 0
elif tp == 1:
break
elif tp == 0:
addr = upper | (rec[1] << 8) | rec[2]
if appstartaddr is None:
appstartaddr = addr
i = 4
while i < len(rec) - 1:
if not currblock or currblock.addr & ~0xFF != addr & ~0xFF:
currblock = Block(addr & ~0xFF)
blocks.append(currblock)
currblock.bytes[addr & 0xFF] = rec[i]
addr += 1
i += 1
numblocks = len(blocks)
resfile = b""
for i in range(0, numblocks):
resfile += blocks[i].encode(i, numblocks)
return resfile

View File

@ -0,0 +1,21 @@
; The very slick RAK wireless RAK 4631 / 4630 board - Unified firmware for 5005/19003, with or without OLED RAK 1921
[env:rak2560]
extends = nrf52840_base
board = wiscore_rak4631
board_check = true
build_flags = ${nrf52840_base.build_flags} -Ivariants/rak2560 -D RAK_4631
-L "${platformio.libdeps_dir}/${this.__env__}/bsec2/src/cortex-m4/fpv4-sp-d16-hard"
-DGPS_POWER_TOGGLE ; comment this line to disable triple press function on the user button to turn off gps entirely.
-DHAS_RAKPROT=1 ; Define if RAk OneWireSerial is used (disables GPS)
build_src_filter = ${nrf52_base.build_src_filter} +<../variants/rak2560> +<mesh/eth/> +<mesh/api/> +<mqtt/>
lib_deps =
${nrf52840_base.lib_deps}
${networking_base.lib_deps}
melopero/Melopero RV3028@^1.1.0
https://github.com/RAKWireless/RAK13800-W5100S.git#1.0.2
rakwireless/RAKwireless NCP5623 RGB LED library@^1.0.2
beegee-tokyo/RAKwireless RAK12034@^1.0.0
https://github.com/beegee-tokyo/RAK-OneWireSerial.git
debug_tool = jlink
; If not set we will default to uploading over serial (first it forces bootloader entry by talking 1200bps to cdcacm)
;upload_protocol = jlink

View File

@ -0,0 +1,45 @@
/*
Copyright (c) 2014-2015 Arduino LLC. All right reserved.
Copyright (c) 2016 Sandeep Mistry All right reserved.
Copyright (c) 2018, Adafruit Industries (adafruit.com)
This library 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 2.1 of the License, or (at your option) any later version.
This library 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 this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "variant.h"
#include "nrf.h"
#include "wiring_constants.h"
#include "wiring_digital.h"
const uint32_t g_ADigitalPinMap[] = {
// P0
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
// P1
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47};
void initVariant()
{
// LED1 & LED2
pinMode(PIN_LED1, OUTPUT);
ledOff(PIN_LED1);
pinMode(PIN_LED2, OUTPUT);
ledOff(PIN_LED2);
// 3V3 Power Rail
pinMode(PIN_3V3_EN, OUTPUT);
digitalWrite(PIN_3V3_EN, HIGH);
}

281
variants/rak2560/variant.h Normal file
View File

@ -0,0 +1,281 @@
/*
Copyright (c) 2014-2015 Arduino LLC. All right reserved.
Copyright (c) 2016 Sandeep Mistry All right reserved.
Copyright (c) 2018, Adafruit Industries (adafruit.com)
This library 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 2.1 of the License, or (at your option) any later version.
This library 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 this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _VARIANT_RAK2560_
#define _VARIANT_RAK2560_
#define RAK4630
#define RAK2560
/** Master clock frequency */
#define VARIANT_MCK (64000000ul)
#define USE_LFXO // Board uses 32khz crystal for LF
// define USE_LFRC // Board uses RC for LF
/*----------------------------------------------------------------------------
* Headers
*----------------------------------------------------------------------------*/
#include "WVariant.h"
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
// Number of pins defined in PinDescription array
#define PINS_COUNT (48)
#define NUM_DIGITAL_PINS (48)
#define NUM_ANALOG_INPUTS (6)
#define NUM_ANALOG_OUTPUTS (0)
// LEDs
#define PIN_LED1 (35)
#define PIN_LED2 (36)
#define LED_BUILTIN PIN_LED1
#define LED_CONN PIN_LED2
#define LED_GREEN PIN_LED1
#define LED_BLUE PIN_LED2
#define LED_STATE_ON 1 // State when LED is litted
/*
* Buttons
*/
#define PIN_BUTTON1 9 // Pin for button on E-ink button module or IO expansion
#define BUTTON_NEED_PULLUP
#define PIN_BUTTON2 12
#define PIN_BUTTON3 24
#define PIN_BUTTON4 25
/*
* Analog pins
*/
#define PIN_A0 (5)
#define PIN_A1 (31)
#define PIN_A2 (28)
#define PIN_A3 (29)
#define PIN_A4 (30)
#define PIN_A5 (31)
#define PIN_A6 (0xff)
#define PIN_A7 (0xff)
static const uint8_t A0 = PIN_A0;
static const uint8_t A1 = PIN_A1;
static const uint8_t A2 = PIN_A2;
static const uint8_t A3 = PIN_A3;
static const uint8_t A4 = PIN_A4;
static const uint8_t A5 = PIN_A5;
static const uint8_t A6 = PIN_A6;
static const uint8_t A7 = PIN_A7;
#define ADC_RESOLUTION 14
// Other pins
#define PIN_AREF (2)
#define PIN_NFC1 (9)
#define PIN_NFC2 (10)
static const uint8_t AREF = PIN_AREF;
/*
* Serial interfaces
*/
#define PIN_SERIAL1_RX (15)
#define PIN_SERIAL1_TX (16)
// Connected to Serial 2
#define PIN_SERIAL2_RX (19)
#define PIN_SERIAL2_TX (20)
/*
* SPI Interfaces
*/
#define SPI_INTERFACES_COUNT 2
#define PIN_SPI_MISO (45)
#define PIN_SPI_MOSI (44)
#define PIN_SPI_SCK (43)
#define PIN_SPI1_MISO (29) // (0 + 29)
#define PIN_SPI1_MOSI (30) // (0 + 30)
#define PIN_SPI1_SCK (3) // (0 + 3)
static const uint8_t SS = 42;
static const uint8_t MOSI = PIN_SPI_MOSI;
static const uint8_t MISO = PIN_SPI_MISO;
static const uint8_t SCK = PIN_SPI_SCK;
/*
* eink display pins
*/
#define PIN_EINK_CS (0 + 26)
#define PIN_EINK_BUSY (0 + 4)
#define PIN_EINK_DC (0 + 17)
#define PIN_EINK_RES (-1)
#define PIN_EINK_SCLK (0 + 3)
#define PIN_EINK_MOSI (0 + 30) // also called SDI
// #define USE_EINK
/*
* Wire Interfaces
*/
#define WIRE_INTERFACES_COUNT 1
#define PIN_WIRE_SDA (13)
#define PIN_WIRE_SCL (14)
// QSPI Pins
#define PIN_QSPI_SCK 3
#define PIN_QSPI_CS 26
#define PIN_QSPI_IO0 30
#define PIN_QSPI_IO1 29
#define PIN_QSPI_IO2 28
#define PIN_QSPI_IO3 2
/* @note RAK5005-O GPIO mapping to RAK4631 GPIO ports
RAK5005-O <-> nRF52840
IO1 <-> P0.17 (Arduino GPIO number 17)
IO2 <-> P1.02 (Arduino GPIO number 34)
IO3 <-> P0.21 (Arduino GPIO number 21)
IO4 <-> P0.04 (Arduino GPIO number 4)
IO5 <-> P0.09 (Arduino GPIO number 9)
IO6 <-> P0.10 (Arduino GPIO number 10)
IO7 <-> P0.28 (Arduino GPIO number 28)
SW1 <-> P0.01 (Arduino GPIO number 1)
A0 <-> P0.04/AIN2 (Arduino Analog A2
A1 <-> P0.31/AIN7 (Arduino Analog A7
SPI_CS <-> P0.26 (Arduino GPIO number 26)
*/
// RAK4630 LoRa module
/* Setup of the SX1262 LoRa module ( https://docs.rakwireless.com/Product-Categories/WisBlock/RAK4631/Datasheet/ )
P1.10 NSS SPI NSS (Arduino GPIO number 42)
P1.11 SCK SPI CLK (Arduino GPIO number 43)
P1.12 MOSI SPI MOSI (Arduino GPIO number 44)
P1.13 MISO SPI MISO (Arduino GPIO number 45)
P1.14 BUSY BUSY signal (Arduino GPIO number 46)
P1.15 DIO1 DIO1 event interrupt (Arduino GPIO number 47)
P1.06 NRESET NRESET manual reset of the SX1262 (Arduino GPIO number 38)
Important for successful SX1262 initialization:
* Setup DIO2 to control the antenna switch
* Setup DIO3 to control the TCXO power supply
* Setup the SX1262 to use it's DCDC regulator and not the LDO
* RAK4630 schematics show GPIO P1.07 connected to the antenna switch, but it should not be initialized, as DIO2 will do the
control of the antenna switch
SO GPIO 39/TXEN MAY NOT BE DEFINED FOR SUCCESSFUL OPERATION OF THE SX1262 - TG
*/
#define DETECTION_SENSOR_EN 4
#define USE_SX1262
#define SX126X_CS (42)
#define SX126X_DIO1 (47)
#define SX126X_BUSY (46)
#define SX126X_RESET (38)
// #define SX126X_TXEN (39)
// #define SX126X_RXEN (37)
#define SX126X_POWER_EN (37)
// DIO2 controlls an antenna switch and the TCXO voltage is controlled by DIO3
#define SX126X_DIO2_AS_RF_SWITCH
#define SX126X_DIO3_TCXO_VOLTAGE 1.8
// Testing USB detection
#define NRF_APM
// enables 3.3V periphery like GPS or IO Module
// Do not toggle this for GPS power savings
#define PIN_3V3_EN (34)
// RAK1910 GPS module
// If using the wisblock GPS module and pluged into Port A on WisBlock base
// IO1 is hooked to PPS (pin 12 on header) = gpio 17
// IO2 is hooked to GPS RESET = gpio 34, but it can not be used to this because IO2 is ALSO used to control 3V3_S power (1 is on).
// Therefore must be 1 to keep peripherals powered
// Power is on the controllable 3V3_S rail
// #define PIN_GPS_RESET (34)
// #define PIN_GPS_EN PIN_3V3_EN
#define PIN_GPS_PPS (17) // Pulse per second input from the GPS
// On RAK2560 the GPS is be on a different UART
// #define GPS_RX_PIN PIN_SERIAL2_RX
// #define GPS_TX_PIN PIN_SERIAL2_TX
// #define PIN_GPS_EN PIN_3V3_EN
// Disable GPS
#define MESHTASTIC_EXCLUDE_GPS 1
// Define pin to enable GPS toggle (set GPIO to LOW) via user button triple press
// RAK12002 RTC Module
#define RV3028_RTC (uint8_t)0b1010010
// RAK18001 Buzzer in Slot C
// #define PIN_BUZZER 21 // IO3 is PWM2
// NEW: set this via protobuf instead!
// Battery
// The battery sense is hooked to pin A0 (5)
#define BATTERY_PIN PIN_A0
// and has 12 bit resolution
#define BATTERY_SENSE_RESOLUTION_BITS 12
#define BATTERY_SENSE_RESOLUTION 4096.0
#undef AREF_VOLTAGE
#define AREF_VOLTAGE 3.0
#define VBAT_AR_INTERNAL AR_INTERNAL_3_0
#define ADC_MULTIPLIER 1.73
#define HAS_RTC 1
#define HAS_ETHERNET 1
#define RAK_4631 1
#define HALF_UART_PIN PIN_SERIAL1_RX
#if defined(GPS_RX_PIN) && (GPS_RX_PIN == HALF_UART_PIN)
#error pin 15 collision
#endif
#if defined(GPS_TX_PIN) && (GPS_RX_PIN == HALF_UART_PIN)
#error pin 15 collision
#endif
#define PIN_ETHERNET_RESET 21
#define PIN_ETHERNET_SS PIN_EINK_CS
#define ETH_SPI_PORT SPI1
#define AQ_SET_PIN 10
#ifdef __cplusplus
}
#endif
/*----------------------------------------------------------------------------
* Arduino objects - C++ only
*----------------------------------------------------------------------------*/
#endif

View File

@ -18,5 +18,35 @@ lib_deps =
rakwireless/RAKwireless NCP5623 RGB LED library@^1.0.2
https://github.com/meshtastic/RAK12034-BMX160.git#4821355fb10390ba8557dc43ca29a023bcfbb9d9
debug_tool = jlink
; If not set we will default to uploading over serial (first it forces bootloader entry by talking 1200bps to cdcacm)
;upload_protocol = jlink
; Note: as of 6/2013 the serial/bootloader based programming takes approximately 30 seconds
;upload_protocol = jlink
; Allows programming and debug via the RAK NanoDAP as the default debugger tool for the RAK4631 (it is only $10!)
; programming time is about the same as the bootloader version.
; For information on this see the meshtastic developers documentation for "Development on the NRF52"
[env:rak4631_dap]
extends = env:rak4631
board_level = extra
; pyocd pack --i nrf52840
; eventually use platformio/tool-pyocd@^2.3600.0 instad
upload_protocol = custom
upload_command = pyocd flash -t nrf52840 $UPLOADERFLAGS $SOURCE
; Only reprogram the board if the code has changed
debug_load_mode = modified
;debug_load_mode = manual
debug_tool = custom
; We manually pass in the elf file so that pyocd can reverse engineer FreeRTOS data (running threads, etc...)
debug_server =
pyocd
gdbserver
-t
nrf52840
--elf
${platformio.build_dir}/${this.__env__}/firmware.elf
; The following is not needed because it automatically tries do this
;debug_server_ready_pattern = -.*GDB server started on port \d+.*
;debug_port = localhost:3333

View File

@ -1,4 +1,4 @@
[VERSION]
major = 2
minor = 3
build = 13
build = 14