mirror of
https://github.com/meshtastic/firmware.git
synced 2025-09-28 20:24:25 +00:00
Merge branch 'master' into apollo
This commit is contained in:
commit
acbbc95ebf
2
.trunk/.gitignore
vendored
2
.trunk/.gitignore
vendored
@ -5,4 +5,4 @@
|
|||||||
plugins
|
plugins
|
||||||
user_trunk.yaml
|
user_trunk.yaml
|
||||||
user.yaml
|
user.yaml
|
||||||
shims
|
tools
|
||||||
|
@ -1,37 +1,42 @@
|
|||||||
version: 0.1
|
version: 0.1
|
||||||
cli:
|
cli:
|
||||||
version: 1.10.0
|
version: 1.13.0
|
||||||
plugins:
|
plugins:
|
||||||
sources:
|
sources:
|
||||||
- id: trunk
|
- id: trunk
|
||||||
ref: v0.0.17
|
ref: v1.1.1
|
||||||
uri: https://github.com/trunk-io/plugins
|
uri: https://github.com/trunk-io/plugins
|
||||||
lint:
|
lint:
|
||||||
enabled:
|
enabled:
|
||||||
- taplo@0.7.0
|
- bandit@1.7.5
|
||||||
- ruff@0.0.265
|
- checkov@2.4.1
|
||||||
|
- terrascan@1.18.3
|
||||||
|
- trivy@0.44.1
|
||||||
|
- trufflehog@3.48.0
|
||||||
|
- taplo@0.8.1
|
||||||
|
- ruff@0.0.284
|
||||||
- yamllint@1.32.0
|
- yamllint@1.32.0
|
||||||
- isort@5.12.0
|
- isort@5.12.0
|
||||||
- markdownlint@0.34.0
|
- markdownlint@0.35.0
|
||||||
- oxipng@8.0.0
|
- oxipng@8.0.0
|
||||||
- svgo@3.0.2
|
- svgo@3.0.2
|
||||||
- actionlint@1.6.24
|
- actionlint@1.6.25
|
||||||
- flake8@6.0.0
|
- flake8@6.1.0
|
||||||
- hadolint@2.12.0
|
- hadolint@2.12.0
|
||||||
- shfmt@3.5.0
|
- shfmt@3.6.0
|
||||||
- shellcheck@0.9.0
|
- shellcheck@0.9.0
|
||||||
- black@23.3.0
|
- black@23.7.0
|
||||||
- git-diff-check
|
- git-diff-check
|
||||||
- gitleaks@8.16.3
|
- gitleaks@8.17.0
|
||||||
- clang-format@14.0.0
|
- clang-format@16.0.3
|
||||||
- prettier@2.8.8
|
- prettier@3.0.2
|
||||||
disabled:
|
disabled:
|
||||||
- taplo@0.7.0
|
- taplo@0.8.1
|
||||||
- shellcheck@0.9.0
|
- shellcheck@0.9.0
|
||||||
- shfmt@3.5.0
|
- shfmt@3.6.0
|
||||||
- oxipng@8.0.0
|
- oxipng@8.0.0
|
||||||
- actionlint@1.6.22
|
- actionlint@1.6.22
|
||||||
- markdownlint@0.34.0
|
- markdownlint@0.35.0
|
||||||
- hadolint@2.12.0
|
- hadolint@2.12.0
|
||||||
- svgo@3.0.2
|
- svgo@3.0.2
|
||||||
runtimes:
|
runtimes:
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit dc28ae3d128b76707c0b87b6f3b2514c7f8514bd
|
Subproject commit 468ff2e2457d7534a907af0a21bdede9f4042cb7
|
@ -16,8 +16,8 @@
|
|||||||
#include "buzz/buzz.h"
|
#include "buzz/buzz.h"
|
||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
|
#include "meshUtils.h"
|
||||||
#include "sleep.h"
|
#include "sleep.h"
|
||||||
#include "utils.h"
|
|
||||||
|
|
||||||
#ifdef DEBUG_HEAP_MQTT
|
#ifdef DEBUG_HEAP_MQTT
|
||||||
#include "mqtt/MQTT.h"
|
#include "mqtt/MQTT.h"
|
||||||
@ -221,10 +221,7 @@ class AnalogBatteryLevel : public HasBatteryLevel
|
|||||||
/**
|
/**
|
||||||
* return true if there is a battery installed in this unit
|
* return true if there is a battery installed in this unit
|
||||||
*/
|
*/
|
||||||
virtual bool isBatteryConnect() override
|
virtual bool isBatteryConnect() override { return getBatteryPercent() != -1; }
|
||||||
{
|
|
||||||
return getBatteryPercent() != -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// If we see a battery voltage higher than physics allows - assume charger is pumping
|
/// If we see a battery voltage higher than physics allows - assume charger is pumping
|
||||||
/// in power
|
/// in power
|
||||||
@ -245,10 +242,7 @@ class AnalogBatteryLevel : public HasBatteryLevel
|
|||||||
|
|
||||||
/// Assume charging if we have a battery and external power is connected.
|
/// Assume charging if we have a battery and external power is connected.
|
||||||
/// we can't be smart enough to say 'full'?
|
/// we can't be smart enough to say 'full'?
|
||||||
virtual bool isCharging() override
|
virtual bool isCharging() override { return isBatteryConnect() && isVbusIn(); }
|
||||||
{
|
|
||||||
return isBatteryConnect() && isVbusIn();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// If we see a battery voltage higher than physics allows - assume charger is pumping
|
/// If we see a battery voltage higher than physics allows - assume charger is pumping
|
||||||
|
@ -101,6 +101,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
// I2C Keyboards (M5Stack, RAK14004, T-Deck)
|
// I2C Keyboards (M5Stack, RAK14004, T-Deck)
|
||||||
#define CARDKB_ADDR 0x5F
|
#define CARDKB_ADDR 0x5F
|
||||||
#define TDECK_KB_ADDR 0x55
|
#define TDECK_KB_ADDR 0x55
|
||||||
|
#define BBQ10_KB_ADDR 0x1F
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// SENSOR
|
// SENSOR
|
||||||
|
@ -30,8 +30,8 @@ ScanI2C::FoundDevice ScanI2C::firstRTC() const
|
|||||||
|
|
||||||
ScanI2C::FoundDevice ScanI2C::firstKeyboard() const
|
ScanI2C::FoundDevice ScanI2C::firstKeyboard() const
|
||||||
{
|
{
|
||||||
ScanI2C::DeviceType types[] = {CARDKB, TDECKKB, RAK14004};
|
ScanI2C::DeviceType types[] = {CARDKB, TDECKKB, BBQ10KB, RAK14004};
|
||||||
return firstOfOrNONE(3, types);
|
return firstOfOrNONE(4, types);
|
||||||
}
|
}
|
||||||
|
|
||||||
ScanI2C::FoundDevice ScanI2C::firstAccelerometer() const
|
ScanI2C::FoundDevice ScanI2C::firstAccelerometer() const
|
||||||
|
@ -17,6 +17,7 @@ class ScanI2C
|
|||||||
RTC_PCF8563,
|
RTC_PCF8563,
|
||||||
CARDKB,
|
CARDKB,
|
||||||
TDECKKB,
|
TDECKKB,
|
||||||
|
BBQ10KB,
|
||||||
RAK14004,
|
RAK14004,
|
||||||
PMU_AXP192_AXP2101,
|
PMU_AXP192_AXP2101,
|
||||||
BME_680,
|
BME_680,
|
||||||
|
@ -213,6 +213,7 @@ void ScanI2CTwoWire::scanPort(I2CPort port)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
SCAN_SIMPLE_CASE(TDECK_KB_ADDR, TDECKKB, "T-Deck keyboard found\n");
|
SCAN_SIMPLE_CASE(TDECK_KB_ADDR, TDECKKB, "T-Deck keyboard found\n");
|
||||||
|
SCAN_SIMPLE_CASE(BBQ10_KB_ADDR, BBQ10KB, "BB Q10 keyboard found\n");
|
||||||
SCAN_SIMPLE_CASE(ST7567_ADDRESS, SCREEN_ST7567, "st7567 display found\n");
|
SCAN_SIMPLE_CASE(ST7567_ADDRESS, SCREEN_ST7567, "st7567 display found\n");
|
||||||
#ifdef HAS_NCP5623
|
#ifdef HAS_NCP5623
|
||||||
SCAN_SIMPLE_CASE(NCP5623_ADDR, NCP5623, "NCP5623 RGB LED found\n");
|
SCAN_SIMPLE_CASE(NCP5623_ADDR, NCP5623, "NCP5623 RGB LED found\n");
|
||||||
|
@ -188,8 +188,8 @@ bool GPS::setupGPS()
|
|||||||
config.position.tx_gpio = GPS_TX_PIN;
|
config.position.tx_gpio = GPS_TX_PIN;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//#define BAUD_RATE 115200
|
// #define BAUD_RATE 115200
|
||||||
// ESP32 has a special set of parameters vs other arduino ports
|
// ESP32 has a special set of parameters vs other arduino ports
|
||||||
#if defined(ARCH_ESP32)
|
#if defined(ARCH_ESP32)
|
||||||
if (config.position.rx_gpio) {
|
if (config.position.rx_gpio) {
|
||||||
LOG_DEBUG("Using GPIO%d for GPS RX\n", config.position.rx_gpio);
|
LOG_DEBUG("Using GPIO%d for GPS RX\n", config.position.rx_gpio);
|
||||||
@ -267,7 +267,6 @@ bool GPS::setupGPS()
|
|||||||
LOG_INFO("GNSS configured for GPS+SBAS+GLONASS. Pause for 0.75s before sending next command.\n");
|
LOG_INFO("GNSS configured for GPS+SBAS+GLONASS. Pause for 0.75s before sending next command.\n");
|
||||||
// Documentation say, we need wait atleast 0.5s after reconfiguration of GNSS module, before sending next commands
|
// Documentation say, we need wait atleast 0.5s after reconfiguration of GNSS module, before sending next commands
|
||||||
delay(750);
|
delay(750);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enable interference resistance, because we are using LoRa, WiFi and Bluetooth on same board,
|
// Enable interference resistance, because we are using LoRa, WiFi and Bluetooth on same board,
|
||||||
@ -535,7 +534,8 @@ bool GPS::setupGPS()
|
|||||||
_serial_gps->write(UBX_CFG_PMS, sizeof(UBX_CFG_PMS));
|
_serial_gps->write(UBX_CFG_PMS, sizeof(UBX_CFG_PMS));
|
||||||
if (!getACK(0x06, 0x86)) {
|
if (!getACK(0x06, 0x86)) {
|
||||||
LOG_WARN("Unable to enable powersaving for GPS.\n");
|
LOG_WARN("Unable to enable powersaving for GPS.\n");
|
||||||
return true;
|
// T-beam doesn't support this mode.
|
||||||
|
// Don't bail from function early.
|
||||||
}
|
}
|
||||||
|
|
||||||
// We need save configuration to flash to make our config changes persistent
|
// We need save configuration to flash to make our config changes persistent
|
||||||
@ -675,6 +675,7 @@ void GPS::setAwake(bool on)
|
|||||||
if (isAwake != on) {
|
if (isAwake != on) {
|
||||||
LOG_DEBUG("WANT GPS=%d\n", on);
|
LOG_DEBUG("WANT GPS=%d\n", on);
|
||||||
if (on) {
|
if (on) {
|
||||||
|
clearBuffer(); // drop any old data waiting in the buffer
|
||||||
lastWakeStartMsec = millis();
|
lastWakeStartMsec = millis();
|
||||||
wake();
|
wake();
|
||||||
} else {
|
} else {
|
||||||
@ -858,7 +859,7 @@ GnssModel_t GPS::probe()
|
|||||||
{
|
{
|
||||||
memset(&info, 0, sizeof(struct uBloxGnssModelInfo));
|
memset(&info, 0, sizeof(struct uBloxGnssModelInfo));
|
||||||
// return immediately if the model is set by the variant.h file
|
// return immediately if the model is set by the variant.h file
|
||||||
//#ifdef GPS_UBLOX (unless it's a ublox, because we might want to know the module info!
|
// #ifdef GPS_UBLOX (unless it's a ublox, because we might want to know the module info!
|
||||||
// return GNSS_MODEL_UBLOX; think about removing this macro and return)
|
// return GNSS_MODEL_UBLOX; think about removing this macro and return)
|
||||||
#if defined(GPS_L76K)
|
#if defined(GPS_L76K)
|
||||||
return GNSS_MODEL_MTK;
|
return GNSS_MODEL_MTK;
|
||||||
@ -891,7 +892,8 @@ GnssModel_t GPS::probe()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t cfg_rate[] = {0xB5, 0x62, 0x06, 0x08, 0x00, 0x00, 0x0E, 0x30};
|
uint8_t cfg_rate[] = {0xB5, 0x62, 0x06, 0x08, 0x00, 0x00, 0x00, 0x00};
|
||||||
|
UBXChecksum(cfg_rate, sizeof(cfg_rate));
|
||||||
_serial_gps->write(cfg_rate, sizeof(cfg_rate));
|
_serial_gps->write(cfg_rate, sizeof(cfg_rate));
|
||||||
// Check that the returned response class and message ID are correct
|
// Check that the returned response class and message ID are correct
|
||||||
if (!getAck(buffer, 384, 0x06, 0x08)) {
|
if (!getAck(buffer, 384, 0x06, 0x08)) {
|
||||||
|
@ -36,11 +36,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
#include "mesh-pb-constants.h"
|
#include "mesh-pb-constants.h"
|
||||||
#include "mesh/Channels.h"
|
#include "mesh/Channels.h"
|
||||||
#include "mesh/generated/meshtastic/deviceonly.pb.h"
|
#include "mesh/generated/meshtastic/deviceonly.pb.h"
|
||||||
|
#include "meshUtils.h"
|
||||||
#include "modules/ExternalNotificationModule.h"
|
#include "modules/ExternalNotificationModule.h"
|
||||||
#include "modules/TextMessageModule.h"
|
#include "modules/TextMessageModule.h"
|
||||||
#include "sleep.h"
|
#include "sleep.h"
|
||||||
#include "target_specific.h"
|
#include "target_specific.h"
|
||||||
#include "utils.h"
|
|
||||||
|
|
||||||
#ifdef ARCH_ESP32
|
#ifdef ARCH_ESP32
|
||||||
#include "esp_task_wdt.h"
|
#include "esp_task_wdt.h"
|
||||||
@ -365,7 +365,7 @@ static void drawCriticalFaultFrame(OLEDDisplay *display, OLEDDisplayUiState *sta
|
|||||||
// Ignore messages originating from phone (from the current node 0x0) unless range test or store and forward module are enabled
|
// Ignore messages originating from phone (from the current node 0x0) unless range test or store and forward module are enabled
|
||||||
static bool shouldDrawMessage(const meshtastic_MeshPacket *packet)
|
static bool shouldDrawMessage(const meshtastic_MeshPacket *packet)
|
||||||
{
|
{
|
||||||
return packet->from != 0 && !moduleConfig.range_test.enabled && !moduleConfig.store_forward.enabled;
|
return packet->from != 0 && !moduleConfig.store_forward.enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Draw the last text message we received
|
/// Draw the last text message we received
|
||||||
|
181
src/input/BBQ10Keyboard.cpp
Normal file
181
src/input/BBQ10Keyboard.cpp
Normal file
@ -0,0 +1,181 @@
|
|||||||
|
// Based on arturo182 arduino_bbq10kbd library https://github.com/arturo182/arduino_bbq10kbd
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
|
||||||
|
#include "BBQ10Keyboard.h"
|
||||||
|
|
||||||
|
#define _REG_VER 1
|
||||||
|
#define _REG_CFG 2
|
||||||
|
#define _REG_INT 3
|
||||||
|
#define _REG_KEY 4
|
||||||
|
#define _REG_BKL 5
|
||||||
|
#define _REG_DEB 6
|
||||||
|
#define _REG_FRQ 7
|
||||||
|
#define _REG_RST 8
|
||||||
|
#define _REG_FIF 9
|
||||||
|
|
||||||
|
#define _WRITE_MASK (1 << 7)
|
||||||
|
|
||||||
|
#define CFG_OVERFLOW_ON (1 << 0)
|
||||||
|
#define CFG_OVERFLOW_INT (1 << 1)
|
||||||
|
#define CFG_CAPSLOCK_INT (1 << 2)
|
||||||
|
#define CFG_NUMLOCK_INT (1 << 3)
|
||||||
|
#define CFG_KEY_INT (1 << 4)
|
||||||
|
#define CFG_PANIC_INT (1 << 5)
|
||||||
|
#define CFG_REPORT_MODS (1 << 6)
|
||||||
|
#define CFG_USE_MODS (1 << 7)
|
||||||
|
|
||||||
|
#define INT_OVERFLOW (1 << 0)
|
||||||
|
#define INT_CAPSLOCK (1 << 1)
|
||||||
|
#define INT_NUMLOCK (1 << 2)
|
||||||
|
#define INT_KEY (1 << 3)
|
||||||
|
#define INT_PANIC (1 << 4)
|
||||||
|
|
||||||
|
#define KEY_CAPSLOCK (1 << 5)
|
||||||
|
#define KEY_NUMLOCK (1 << 6)
|
||||||
|
#define KEY_COUNT_MASK (0x1F)
|
||||||
|
|
||||||
|
BBQ10Keyboard::BBQ10Keyboard() : m_wire(nullptr), m_addr(0), readCallback(nullptr), writeCallback(nullptr) {}
|
||||||
|
|
||||||
|
void BBQ10Keyboard::begin(uint8_t addr, TwoWire *wire)
|
||||||
|
{
|
||||||
|
m_addr = addr;
|
||||||
|
m_wire = wire;
|
||||||
|
|
||||||
|
m_wire->begin();
|
||||||
|
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void BBQ10Keyboard::begin(i2c_com_fptr_t r, i2c_com_fptr_t w, uint8_t addr)
|
||||||
|
{
|
||||||
|
m_addr = addr;
|
||||||
|
m_wire = nullptr;
|
||||||
|
writeCallback = w;
|
||||||
|
readCallback = r;
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void BBQ10Keyboard::reset()
|
||||||
|
{
|
||||||
|
if (m_wire) {
|
||||||
|
m_wire->beginTransmission(m_addr);
|
||||||
|
m_wire->write(_REG_RST);
|
||||||
|
m_wire->endTransmission();
|
||||||
|
}
|
||||||
|
if (writeCallback) {
|
||||||
|
uint8_t data = 0;
|
||||||
|
writeCallback(m_addr, _REG_RST, &data, 0);
|
||||||
|
}
|
||||||
|
delay(100);
|
||||||
|
writeRegister(_REG_CFG, readRegister8(_REG_CFG) | CFG_REPORT_MODS);
|
||||||
|
delay(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BBQ10Keyboard::attachInterrupt(uint8_t pin, void (*func)(void)) const
|
||||||
|
{
|
||||||
|
pinMode(pin, INPUT_PULLUP);
|
||||||
|
::attachInterrupt(digitalPinToInterrupt(pin), func, RISING);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BBQ10Keyboard::detachInterrupt(uint8_t pin) const
|
||||||
|
{
|
||||||
|
::detachInterrupt(pin);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BBQ10Keyboard::clearInterruptStatus()
|
||||||
|
{
|
||||||
|
writeRegister(_REG_INT, 0x00);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t BBQ10Keyboard::status() const
|
||||||
|
{
|
||||||
|
return readRegister8(_REG_KEY);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t BBQ10Keyboard::keyCount() const
|
||||||
|
{
|
||||||
|
return status() & KEY_COUNT_MASK;
|
||||||
|
}
|
||||||
|
|
||||||
|
BBQ10Keyboard::KeyEvent BBQ10Keyboard::keyEvent() const
|
||||||
|
{
|
||||||
|
KeyEvent event = {.key = '\0', .state = StateIdle};
|
||||||
|
|
||||||
|
if (keyCount() == 0)
|
||||||
|
return event;
|
||||||
|
|
||||||
|
const uint16_t buf = readRegister16(_REG_FIF);
|
||||||
|
event.key = buf >> 8;
|
||||||
|
event.state = KeyState(buf & 0xFF);
|
||||||
|
|
||||||
|
return event;
|
||||||
|
}
|
||||||
|
|
||||||
|
float BBQ10Keyboard::backlight() const
|
||||||
|
{
|
||||||
|
return readRegister8(_REG_BKL) / 255.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BBQ10Keyboard::setBacklight(float value)
|
||||||
|
{
|
||||||
|
writeRegister(_REG_BKL, value * 255);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t BBQ10Keyboard::readRegister8(uint8_t reg) const
|
||||||
|
{
|
||||||
|
if (m_wire) {
|
||||||
|
m_wire->beginTransmission(m_addr);
|
||||||
|
m_wire->write(reg);
|
||||||
|
m_wire->endTransmission();
|
||||||
|
|
||||||
|
m_wire->requestFrom(m_addr, (uint8_t)1);
|
||||||
|
if (m_wire->available() < 1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return m_wire->read();
|
||||||
|
}
|
||||||
|
if (readCallback) {
|
||||||
|
uint8_t data;
|
||||||
|
readCallback(m_addr, reg, &data, 1);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t BBQ10Keyboard::readRegister16(uint8_t reg) const
|
||||||
|
{
|
||||||
|
uint8_t data[2] = {0};
|
||||||
|
// uint8_t low = 0, high = 0;
|
||||||
|
if (m_wire) {
|
||||||
|
m_wire->beginTransmission(m_addr);
|
||||||
|
m_wire->write(reg);
|
||||||
|
m_wire->endTransmission();
|
||||||
|
|
||||||
|
m_wire->requestFrom(m_addr, (uint8_t)2);
|
||||||
|
if (m_wire->available() < 2)
|
||||||
|
return 0;
|
||||||
|
data[0] = m_wire->read();
|
||||||
|
data[1] = m_wire->read();
|
||||||
|
}
|
||||||
|
if (readCallback) {
|
||||||
|
readCallback(m_addr, reg, data, 2);
|
||||||
|
}
|
||||||
|
return (data[1] << 8) | data[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
void BBQ10Keyboard::writeRegister(uint8_t reg, uint8_t value)
|
||||||
|
{
|
||||||
|
uint8_t data[2];
|
||||||
|
data[0] = reg | _WRITE_MASK;
|
||||||
|
data[1] = value;
|
||||||
|
|
||||||
|
if (m_wire) {
|
||||||
|
m_wire->beginTransmission(m_addr);
|
||||||
|
m_wire->write(data, sizeof(uint8_t) * 2);
|
||||||
|
m_wire->endTransmission();
|
||||||
|
}
|
||||||
|
if (writeCallback) {
|
||||||
|
writeCallback(m_addr, data[0], &(data[1]), 1);
|
||||||
|
}
|
||||||
|
}
|
51
src/input/BBQ10Keyboard.h
Normal file
51
src/input/BBQ10Keyboard.h
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
// Based on arturo182 arduino_bbq10kbd library https://github.com/arturo182/arduino_bbq10kbd
|
||||||
|
|
||||||
|
#include "configuration.h"
|
||||||
|
#include <Wire.h>
|
||||||
|
|
||||||
|
#define KEY_MOD_ALT (0x1A)
|
||||||
|
#define KEY_MOD_SHL (0x1B)
|
||||||
|
#define KEY_MOD_SHR (0x1C)
|
||||||
|
#define KEY_MOD_SYM (0x1D)
|
||||||
|
|
||||||
|
class BBQ10Keyboard
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef uint8_t (*i2c_com_fptr_t)(uint8_t dev_addr, uint8_t reg_addr, uint8_t *data, uint8_t len);
|
||||||
|
|
||||||
|
enum KeyState { StateIdle = 0, StatePress, StateLongPress, StateRelease };
|
||||||
|
|
||||||
|
struct KeyEvent {
|
||||||
|
char key;
|
||||||
|
KeyState state;
|
||||||
|
};
|
||||||
|
|
||||||
|
BBQ10Keyboard();
|
||||||
|
|
||||||
|
void begin(uint8_t addr = BBQ10_KB_ADDR, TwoWire *wire = &Wire);
|
||||||
|
|
||||||
|
void begin(i2c_com_fptr_t r, i2c_com_fptr_t w, uint8_t addr = BBQ10_KB_ADDR);
|
||||||
|
|
||||||
|
void reset(void);
|
||||||
|
|
||||||
|
void attachInterrupt(uint8_t pin, void (*func)(void)) const;
|
||||||
|
void detachInterrupt(uint8_t pin) const;
|
||||||
|
void clearInterruptStatus(void);
|
||||||
|
|
||||||
|
uint8_t status(void) const;
|
||||||
|
uint8_t keyCount(void) const;
|
||||||
|
KeyEvent keyEvent(void) const;
|
||||||
|
|
||||||
|
float backlight() const;
|
||||||
|
void setBacklight(float value);
|
||||||
|
|
||||||
|
uint8_t readRegister8(uint8_t reg) const;
|
||||||
|
uint16_t readRegister16(uint8_t reg) const;
|
||||||
|
void writeRegister(uint8_t reg, uint8_t value);
|
||||||
|
|
||||||
|
private:
|
||||||
|
TwoWire *m_wire;
|
||||||
|
uint8_t m_addr;
|
||||||
|
i2c_com_fptr_t readCallback;
|
||||||
|
i2c_com_fptr_t writeCallback;
|
||||||
|
};
|
@ -7,7 +7,7 @@ CardKbI2cImpl::CardKbI2cImpl() : KbI2cBase("cardKB") {}
|
|||||||
|
|
||||||
void CardKbI2cImpl::init()
|
void CardKbI2cImpl::init()
|
||||||
{
|
{
|
||||||
if (cardkb_found.address != CARDKB_ADDR && cardkb_found.address != TDECK_KB_ADDR) {
|
if (cardkb_found.address == 0x00) {
|
||||||
disable();
|
disable();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,7 @@ uint8_t read_from_14004(TwoWire *i2cBus, uint8_t reg, uint8_t *data, uint8_t len
|
|||||||
|
|
||||||
int32_t KbI2cBase::runOnce()
|
int32_t KbI2cBase::runOnce()
|
||||||
{
|
{
|
||||||
if (cardkb_found.address != CARDKB_ADDR && cardkb_found.address != TDECK_KB_ADDR) {
|
if (cardkb_found.address == 0x00) {
|
||||||
// Input device is not detected.
|
// Input device is not detected.
|
||||||
return INT32_MAX;
|
return INT32_MAX;
|
||||||
}
|
}
|
||||||
@ -41,11 +41,19 @@ int32_t KbI2cBase::runOnce()
|
|||||||
#ifdef I2C_SDA1
|
#ifdef I2C_SDA1
|
||||||
LOG_DEBUG("Using I2C Bus 1 (the second one)\n");
|
LOG_DEBUG("Using I2C Bus 1 (the second one)\n");
|
||||||
i2cBus = &Wire1;
|
i2cBus = &Wire1;
|
||||||
|
if (cardkb_found.address == BBQ10_KB_ADDR) {
|
||||||
|
Q10keyboard.begin(BBQ10_KB_ADDR, &Wire1);
|
||||||
|
Q10keyboard.setBacklight(0);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
case ScanI2C::WIRE:
|
case ScanI2C::WIRE:
|
||||||
LOG_DEBUG("Using I2C Bus 0 (the first one)\n");
|
LOG_DEBUG("Using I2C Bus 0 (the first one)\n");
|
||||||
i2cBus = &Wire;
|
i2cBus = &Wire;
|
||||||
|
if (cardkb_found.address == BBQ10_KB_ADDR) {
|
||||||
|
Q10keyboard.begin(BBQ10_KB_ADDR, &Wire);
|
||||||
|
Q10keyboard.setBacklight(0);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case ScanI2C::NO_I2C:
|
case ScanI2C::NO_I2C:
|
||||||
default:
|
default:
|
||||||
@ -53,7 +61,105 @@ int32_t KbI2cBase::runOnce()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (kb_model == 0x02) {
|
switch (kb_model) {
|
||||||
|
case 0x11: { // BB Q10
|
||||||
|
int keyCount = Q10keyboard.keyCount();
|
||||||
|
while (keyCount--) {
|
||||||
|
const BBQ10Keyboard::KeyEvent key = Q10keyboard.keyEvent();
|
||||||
|
if ((key.key != 0x00) && (key.state == BBQ10Keyboard::StateRelease)) {
|
||||||
|
InputEvent e;
|
||||||
|
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE;
|
||||||
|
e.source = this->_originName;
|
||||||
|
switch (key.key) {
|
||||||
|
case 'p': // TAB
|
||||||
|
case 't': // TAB as well
|
||||||
|
if (is_sym) {
|
||||||
|
e.inputEvent = ANYKEY;
|
||||||
|
e.kbchar = 0x09; // TAB Scancode
|
||||||
|
is_sym = false; // reset sym state after second keypress
|
||||||
|
} else {
|
||||||
|
e.inputEvent = ANYKEY;
|
||||||
|
e.kbchar = key.key;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'q': // ESC
|
||||||
|
if (is_sym) {
|
||||||
|
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_CANCEL;
|
||||||
|
e.kbchar = 0x1b;
|
||||||
|
is_sym = false; // reset sym state after second keypress
|
||||||
|
} else {
|
||||||
|
e.inputEvent = ANYKEY;
|
||||||
|
e.kbchar = key.key;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0x08: // Back
|
||||||
|
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_BACK;
|
||||||
|
e.kbchar = key.key;
|
||||||
|
break;
|
||||||
|
case 'e': // sym e
|
||||||
|
if (is_sym) {
|
||||||
|
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_UP;
|
||||||
|
e.kbchar = 0xb5;
|
||||||
|
is_sym = false; // reset sym state after second keypress
|
||||||
|
} else {
|
||||||
|
e.inputEvent = ANYKEY;
|
||||||
|
e.kbchar = key.key;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'x': // sym x
|
||||||
|
if (is_sym) {
|
||||||
|
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_DOWN;
|
||||||
|
e.kbchar = 0xb6;
|
||||||
|
is_sym = false; // reset sym state after second keypress
|
||||||
|
} else {
|
||||||
|
e.inputEvent = ANYKEY;
|
||||||
|
e.kbchar = key.key;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 's': // sym s
|
||||||
|
if (is_sym) {
|
||||||
|
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT;
|
||||||
|
e.kbchar = 0x00; // tweak for destSelect
|
||||||
|
is_sym = false; // reset sym state after second keypress
|
||||||
|
} else {
|
||||||
|
e.inputEvent = ANYKEY;
|
||||||
|
e.kbchar = key.key;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'f': // sym f
|
||||||
|
if (is_sym) {
|
||||||
|
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT;
|
||||||
|
e.kbchar = 0x00; // tweak for destSelect
|
||||||
|
is_sym = false; // reset sym state after second keypress
|
||||||
|
} else {
|
||||||
|
e.inputEvent = ANYKEY;
|
||||||
|
e.kbchar = key.key;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0x13: // Code scanner says the SYM key is 0x13
|
||||||
|
is_sym = !is_sym;
|
||||||
|
break;
|
||||||
|
case 0x0a: // apparently Enter on Q10 is a line feed instead of carriage return
|
||||||
|
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_SELECT;
|
||||||
|
break;
|
||||||
|
case 0x00: // nopress
|
||||||
|
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE;
|
||||||
|
break;
|
||||||
|
default: // all other keys
|
||||||
|
e.inputEvent = ANYKEY;
|
||||||
|
e.kbchar = key.key;
|
||||||
|
is_sym = false; // reset sym state after second keypress
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e.inputEvent != meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE) {
|
||||||
|
this->notifyObservers(&e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 0x02: {
|
||||||
// RAK14004
|
// RAK14004
|
||||||
uint8_t rDataBuf[8] = {0};
|
uint8_t rDataBuf[8] = {0};
|
||||||
uint8_t PrintDataBuf = 0;
|
uint8_t PrintDataBuf = 0;
|
||||||
@ -74,9 +180,12 @@ int32_t KbI2cBase::runOnce()
|
|||||||
e.kbchar = PrintDataBuf;
|
e.kbchar = PrintDataBuf;
|
||||||
this->notifyObservers(&e);
|
this->notifyObservers(&e);
|
||||||
}
|
}
|
||||||
} else if (kb_model == 0x00 || kb_model == 0x10) {
|
break;
|
||||||
// m5 cardkb and T-Deck
|
}
|
||||||
i2cBus->requestFrom(kb_model == 0x00 ? CARDKB_ADDR : TDECK_KB_ADDR, 1);
|
case 0x00: // CARDKB
|
||||||
|
case 0x10: { // T-DECK
|
||||||
|
|
||||||
|
i2cBus->requestFrom((int)cardkb_found.address, 1);
|
||||||
|
|
||||||
while (i2cBus->available()) {
|
while (i2cBus->available()) {
|
||||||
char c = i2cBus->read();
|
char c = i2cBus->read();
|
||||||
@ -93,17 +202,19 @@ int32_t KbI2cBase::runOnce()
|
|||||||
break;
|
break;
|
||||||
case 0xb5: // Up
|
case 0xb5: // Up
|
||||||
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_UP;
|
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_UP;
|
||||||
|
e.kbchar = 0xb5;
|
||||||
break;
|
break;
|
||||||
case 0xb6: // Down
|
case 0xb6: // Down
|
||||||
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_DOWN;
|
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_DOWN;
|
||||||
|
e.kbchar = 0xb6;
|
||||||
break;
|
break;
|
||||||
case 0xb4: // Left
|
case 0xb4: // Left
|
||||||
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT;
|
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT;
|
||||||
e.kbchar = c;
|
e.kbchar = 0xb4;
|
||||||
break;
|
break;
|
||||||
case 0xb7: // Right
|
case 0xb7: // Right
|
||||||
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT;
|
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT;
|
||||||
e.kbchar = c;
|
e.kbchar = 0xb7;
|
||||||
break;
|
break;
|
||||||
case 0x0d: // Enter
|
case 0x0d: // Enter
|
||||||
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_SELECT;
|
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_SELECT;
|
||||||
@ -121,7 +232,9 @@ int32_t KbI2cBase::runOnce()
|
|||||||
this->notifyObservers(&e);
|
this->notifyObservers(&e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
LOG_WARN("Unknown kb_model 0x%02x\n", kb_model);
|
LOG_WARN("Unknown kb_model 0x%02x\n", kb_model);
|
||||||
}
|
}
|
||||||
return 300;
|
return 300;
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "BBQ10Keyboard.h"
|
||||||
#include "InputBroker.h"
|
#include "InputBroker.h"
|
||||||
#include "Wire.h"
|
#include "Wire.h"
|
||||||
#include "concurrency/OSThread.h"
|
#include "concurrency/OSThread.h"
|
||||||
@ -16,4 +17,7 @@ class KbI2cBase : public Observable<const InputEvent *>, public concurrency::OST
|
|||||||
const char *_originName;
|
const char *_originName;
|
||||||
|
|
||||||
TwoWire *i2cBus = 0;
|
TwoWire *i2cBus = 0;
|
||||||
|
|
||||||
|
BBQ10Keyboard Q10keyboard;
|
||||||
|
bool is_sym = false;
|
||||||
};
|
};
|
||||||
|
@ -387,6 +387,10 @@ void setup()
|
|||||||
// assign an arbitrary value to distinguish from other models
|
// assign an arbitrary value to distinguish from other models
|
||||||
kb_model = 0x10;
|
kb_model = 0x10;
|
||||||
break;
|
break;
|
||||||
|
case ScanI2C::DeviceType::BBQ10KB:
|
||||||
|
// assign an arbitrary value to distinguish from other models
|
||||||
|
kb_model = 0x11;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
// use this as default since it's also just zero
|
// 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);
|
LOG_WARN("kb_info.type is unknown(0x%02x), setting kb_model=0x00\n", kb_info.type);
|
||||||
|
@ -327,15 +327,15 @@ int MeshService::onGPSChanged(const meshtastic::GPSStatus *newStatus)
|
|||||||
// load data from GPS object, will add timestamp + battery further down
|
// load data from GPS object, will add timestamp + battery further down
|
||||||
pos = gps->p;
|
pos = gps->p;
|
||||||
} else {
|
} else {
|
||||||
// The GPS has lost lock, if we are fixed position we should just keep using
|
// The GPS has lost lock
|
||||||
// the old position
|
|
||||||
#ifdef GPS_EXTRAVERBOSE
|
#ifdef GPS_EXTRAVERBOSE
|
||||||
LOG_DEBUG("onGPSchanged() - lost validLocation\n");
|
LOG_DEBUG("onGPSchanged() - lost validLocation\n");
|
||||||
#endif
|
#endif
|
||||||
if (config.position.fixed_position) {
|
}
|
||||||
LOG_WARN("Using fixed position\n");
|
// Used fixed position if configured regalrdless of GPS lock
|
||||||
pos = ConvertToPosition(node->position);
|
if (config.position.fixed_position) {
|
||||||
}
|
LOG_WARN("Using fixed position\n");
|
||||||
|
pos = ConvertToPosition(node->position);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finally add a fresh timestamp and battery level reading
|
// Finally add a fresh timestamp and battery level reading
|
||||||
|
@ -48,6 +48,14 @@ class MeshService
|
|||||||
uint32_t oldFromNum = 0;
|
uint32_t oldFromNum = 0;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
static bool isTextPayload(const meshtastic_MeshPacket *p)
|
||||||
|
{
|
||||||
|
if (moduleConfig.range_test.enabled && p->decoded.portnum == meshtastic_PortNum_RANGE_TEST_APP) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return p->decoded.portnum == meshtastic_PortNum_TEXT_MESSAGE_APP ||
|
||||||
|
p->decoded.portnum == meshtastic_PortNum_DETECTION_SENSOR_APP;
|
||||||
|
}
|
||||||
/// Called when some new packets have arrived from one of the radios
|
/// Called when some new packets have arrived from one of the radios
|
||||||
Observable<uint32_t> fromNumChanged;
|
Observable<uint32_t> fromNumChanged;
|
||||||
|
|
||||||
|
@ -111,6 +111,8 @@ typedef enum _meshtastic_HardwareModel {
|
|||||||
meshtastic_HardwareModel_T_WATCH_S3 = 51,
|
meshtastic_HardwareModel_T_WATCH_S3 = 51,
|
||||||
/* Bobricius Picomputer with ESP32-S3 CPU, Keyboard and IPS display */
|
/* Bobricius Picomputer with ESP32-S3 CPU, Keyboard and IPS display */
|
||||||
meshtastic_HardwareModel_PICOMPUTER_S3 = 52,
|
meshtastic_HardwareModel_PICOMPUTER_S3 = 52,
|
||||||
|
/* Heltec HT-CT62 with ESP32-C3 CPU and SX1262 LoRa */
|
||||||
|
meshtastic_HardwareModel_HELTEC_HT62 = 53,
|
||||||
/* ------------------------------------------------------------------------------------------------------------------------------------------
|
/* ------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
Reserved ID For developing private Ports. These will show up in live traffic sparsely, so we can use a high number. Keep it within 8 bits.
|
Reserved ID For developing private Ports. These will show up in live traffic sparsely, so we can use a high number. Keep it within 8 bits.
|
||||||
------------------------------------------------------------------------------------------------------------------------------------------ */
|
------------------------------------------------------------------------------------------------------------------------------------------ */
|
||||||
|
@ -69,6 +69,8 @@ typedef enum _meshtastic_PortNum {
|
|||||||
NOTE: audio frames contain a 3 byte header (0xc0 0xde 0xc2) and a one byte marker for the decompressed bitrate.
|
NOTE: audio frames contain a 3 byte header (0xc0 0xde 0xc2) and a one byte marker for the decompressed bitrate.
|
||||||
This marker comes from the 'moduleConfig.audio.bitrate' enum minus one. */
|
This marker comes from the 'moduleConfig.audio.bitrate' enum minus one. */
|
||||||
meshtastic_PortNum_AUDIO_APP = 9,
|
meshtastic_PortNum_AUDIO_APP = 9,
|
||||||
|
/* Same as Text Message but originating from Detection Sensor Module. */
|
||||||
|
meshtastic_PortNum_DETECTION_SENSOR_APP = 10,
|
||||||
/* Provides a 'ping' service that replies to any packet it receives.
|
/* Provides a 'ping' service that replies to any packet it receives.
|
||||||
Also serves as a small example module.
|
Also serves as a small example module.
|
||||||
ENCODING: ASCII Plaintext */
|
ENCODING: ASCII Plaintext */
|
||||||
|
@ -65,8 +65,8 @@ CannedMessageModule::CannedMessageModule()
|
|||||||
{
|
{
|
||||||
if (moduleConfig.canned_message.enabled || CANNED_MESSAGE_MODULE_ENABLE) {
|
if (moduleConfig.canned_message.enabled || CANNED_MESSAGE_MODULE_ENABLE) {
|
||||||
this->loadProtoForModule();
|
this->loadProtoForModule();
|
||||||
if ((this->splitConfiguredMessages() <= 0) && (cardkb_found.address != CARDKB_ADDR) &&
|
if ((this->splitConfiguredMessages() <= 0) && (cardkb_found.address == 0x00) && !INPUTBROKER_MATRIX_TYPE &&
|
||||||
(cardkb_found.address != TDECK_KB_ADDR) && !INPUTBROKER_MATRIX_TYPE && !CANNED_MESSAGE_MODULE_ENABLE) {
|
!CANNED_MESSAGE_MODULE_ENABLE) {
|
||||||
LOG_INFO("CannedMessageModule: No messages are configured. Module is disabled\n");
|
LOG_INFO("CannedMessageModule: No messages are configured. Module is disabled\n");
|
||||||
this->runState = CANNED_MESSAGE_RUN_STATE_DISABLED;
|
this->runState = CANNED_MESSAGE_RUN_STATE_DISABLED;
|
||||||
disable();
|
disable();
|
||||||
@ -171,7 +171,7 @@ int CannedMessageModule::handleInputEvent(const InputEvent *event)
|
|||||||
(event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT)) ||
|
(event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT)) ||
|
||||||
(event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT))) {
|
(event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT))) {
|
||||||
// LOG_DEBUG("Canned message event (%x)\n", event->kbchar);
|
// LOG_DEBUG("Canned message event (%x)\n", event->kbchar);
|
||||||
// tweak for left/right events generated via trackball/touch with empty kbchar
|
// tweak for left/right events generated via trackball/touch with empty kbchar
|
||||||
if (!event->kbchar) {
|
if (!event->kbchar) {
|
||||||
if (event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT)) {
|
if (event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT)) {
|
||||||
this->payload = 0xb4;
|
this->payload = 0xb4;
|
||||||
@ -195,6 +195,7 @@ int CannedMessageModule::handleInputEvent(const InputEvent *event)
|
|||||||
this->runState = CANNED_MESSAGE_RUN_STATE_FREETEXT;
|
this->runState = CANNED_MESSAGE_RUN_STATE_FREETEXT;
|
||||||
}
|
}
|
||||||
// pass the pressed key
|
// pass the pressed key
|
||||||
|
// LOG_DEBUG("Canned message ANYKEY (%x)\n", event->kbchar);
|
||||||
this->payload = event->kbchar;
|
this->payload = event->kbchar;
|
||||||
this->lastTouchMillis = millis();
|
this->lastTouchMillis = millis();
|
||||||
validEvent = true;
|
validEvent = true;
|
||||||
@ -649,4 +650,4 @@ String CannedMessageModule::drawWithCursor(String text, int cursor)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -46,10 +46,7 @@ int32_t DetectionSensorModule::runOnce()
|
|||||||
if ((millis() - lastSentToMesh) >= getConfiguredOrDefaultMs(moduleConfig.detection_sensor.minimum_broadcast_secs) &&
|
if ((millis() - lastSentToMesh) >= getConfiguredOrDefaultMs(moduleConfig.detection_sensor.minimum_broadcast_secs) &&
|
||||||
hasDetectionEvent()) {
|
hasDetectionEvent()) {
|
||||||
sendDetectionMessage();
|
sendDetectionMessage();
|
||||||
return getConfiguredOrDefaultMs(moduleConfig.detection_sensor.minimum_broadcast_secs <
|
return DELAYED_INTERVAL;
|
||||||
moduleConfig.detection_sensor.state_broadcast_secs
|
|
||||||
? moduleConfig.detection_sensor.minimum_broadcast_secs
|
|
||||||
: moduleConfig.detection_sensor.state_broadcast_secs);
|
|
||||||
}
|
}
|
||||||
// Even if we haven't detected an event, broadcast our current state to the mesh on the scheduled interval as a sort
|
// Even if we haven't detected an event, broadcast our current state to the mesh on the scheduled interval as a sort
|
||||||
// of heartbeat. We only do this if the minimum broadcast interval is greater than zero, otherwise we'll only broadcast state
|
// of heartbeat. We only do this if the minimum broadcast interval is greater than zero, otherwise we'll only broadcast state
|
||||||
@ -57,10 +54,7 @@ int32_t DetectionSensorModule::runOnce()
|
|||||||
else if (moduleConfig.detection_sensor.state_broadcast_secs > 0 &&
|
else if (moduleConfig.detection_sensor.state_broadcast_secs > 0 &&
|
||||||
(millis() - lastSentToMesh) >= getConfiguredOrDefaultMs(moduleConfig.detection_sensor.state_broadcast_secs)) {
|
(millis() - lastSentToMesh) >= getConfiguredOrDefaultMs(moduleConfig.detection_sensor.state_broadcast_secs)) {
|
||||||
sendCurrentStateMessage();
|
sendCurrentStateMessage();
|
||||||
return getConfiguredOrDefaultMs(moduleConfig.detection_sensor.minimum_broadcast_secs <
|
return DELAYED_INTERVAL;
|
||||||
moduleConfig.detection_sensor.state_broadcast_secs
|
|
||||||
? moduleConfig.detection_sensor.minimum_broadcast_secs
|
|
||||||
: moduleConfig.detection_sensor.state_broadcast_secs);
|
|
||||||
}
|
}
|
||||||
return GPIO_POLLING_INTERVAL;
|
return GPIO_POLLING_INTERVAL;
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ class DetectionSensorModule : public SinglePortModule, private concurrency::OSTh
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DetectionSensorModule()
|
DetectionSensorModule()
|
||||||
: SinglePortModule("detection", meshtastic_PortNum_TEXT_MESSAGE_APP), OSThread("DetectionSensorModule")
|
: SinglePortModule("detection", meshtastic_PortNum_DETECTION_SENSOR_APP), OSThread("DetectionSensorModule")
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,6 +128,11 @@ int32_t ExternalNotificationModule::runOnce()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ExternalNotificationModule::wantPacket(const meshtastic_MeshPacket *p)
|
||||||
|
{
|
||||||
|
return MeshService::isTextPayload(p);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the external notification on for the specified index.
|
* Sets the external notification on for the specified index.
|
||||||
*
|
*
|
||||||
@ -212,8 +217,8 @@ void ExternalNotificationModule::stopNow()
|
|||||||
}
|
}
|
||||||
|
|
||||||
ExternalNotificationModule::ExternalNotificationModule()
|
ExternalNotificationModule::ExternalNotificationModule()
|
||||||
: SinglePortModule("ExternalNotificationModule", meshtastic_PortNum_TEXT_MESSAGE_APP), concurrency::OSThread(
|
: SinglePortModule("ExternalNotificationModule", meshtastic_PortNum_TEXT_MESSAGE_APP),
|
||||||
"ExternalNotificationModule")
|
concurrency::OSThread("ExternalNotificationModule")
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
Uncomment the preferences below if you want to use the module
|
Uncomment the preferences below if you want to use the module
|
||||||
|
@ -52,6 +52,8 @@ class ExternalNotificationModule : public SinglePortModule, private concurrency:
|
|||||||
|
|
||||||
virtual int32_t runOnce() override;
|
virtual int32_t runOnce() override;
|
||||||
|
|
||||||
|
virtual bool wantPacket(const meshtastic_MeshPacket *p) override;
|
||||||
|
|
||||||
bool isNagging = false;
|
bool isNagging = false;
|
||||||
|
|
||||||
virtual AdminMessageHandleResult handleAdminMessageForModule(const meshtastic_MeshPacket &mp,
|
virtual AdminMessageHandleResult handleAdminMessageForModule(const meshtastic_MeshPacket &mp,
|
||||||
@ -59,4 +61,4 @@ class ExternalNotificationModule : public SinglePortModule, private concurrency:
|
|||||||
meshtastic_AdminMessage *response) override;
|
meshtastic_AdminMessage *response) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern ExternalNotificationModule *externalNotificationModule;
|
extern ExternalNotificationModule *externalNotificationModule;
|
@ -15,12 +15,12 @@ NOTE: For debugging only
|
|||||||
*/
|
*/
|
||||||
void NeighborInfoModule::printNeighborInfo(const char *header, const meshtastic_NeighborInfo *np)
|
void NeighborInfoModule::printNeighborInfo(const char *header, const meshtastic_NeighborInfo *np)
|
||||||
{
|
{
|
||||||
LOG_DEBUG("%s NEIGHBORINFO PACKET from Node %d to Node %d (last sent by %d)\n", header, np->node_id, nodeDB.getNodeNum(),
|
LOG_DEBUG("%s NEIGHBORINFO PACKET from Node 0x%x to Node 0x%x (last sent by 0x%x)\n", header, np->node_id,
|
||||||
np->last_sent_by_id);
|
nodeDB.getNodeNum(), np->last_sent_by_id);
|
||||||
LOG_DEBUG("----------------\n");
|
LOG_DEBUG("----------------\n");
|
||||||
LOG_DEBUG("Packet contains %d neighbors\n", np->neighbors_count);
|
LOG_DEBUG("Packet contains %d neighbors\n", np->neighbors_count);
|
||||||
for (int i = 0; i < np->neighbors_count; i++) {
|
for (int i = 0; i < np->neighbors_count; i++) {
|
||||||
LOG_DEBUG("Neighbor %d: node_id=%d, snr=%.2f\n", i, np->neighbors[i].node_id, np->neighbors[i].snr);
|
LOG_DEBUG("Neighbor %d: node_id=0x%x, snr=%.2f\n", i, np->neighbors[i].node_id, np->neighbors[i].snr);
|
||||||
}
|
}
|
||||||
LOG_DEBUG("----------------\n");
|
LOG_DEBUG("----------------\n");
|
||||||
}
|
}
|
||||||
@ -31,12 +31,12 @@ NOTE: for debugging only
|
|||||||
void NeighborInfoModule::printNodeDBNodes(const char *header)
|
void NeighborInfoModule::printNodeDBNodes(const char *header)
|
||||||
{
|
{
|
||||||
int num_nodes = nodeDB.getNumMeshNodes();
|
int num_nodes = nodeDB.getNumMeshNodes();
|
||||||
LOG_DEBUG("%s NODEDB SELECTION from Node %d:\n", header, nodeDB.getNodeNum());
|
LOG_DEBUG("%s NODEDB SELECTION from Node 0x%x:\n", header, nodeDB.getNodeNum());
|
||||||
LOG_DEBUG("----------------\n");
|
LOG_DEBUG("----------------\n");
|
||||||
LOG_DEBUG("DB contains %d nodes\n", num_nodes);
|
LOG_DEBUG("DB contains %d nodes\n", num_nodes);
|
||||||
for (int i = 0; i < num_nodes; i++) {
|
for (int i = 0; i < num_nodes; i++) {
|
||||||
const meshtastic_NodeInfoLite *dbEntry = nodeDB.getMeshNodeByIndex(i);
|
const meshtastic_NodeInfoLite *dbEntry = nodeDB.getMeshNodeByIndex(i);
|
||||||
LOG_DEBUG(" Node %d: node_id=%d, snr=%.2f\n", i, dbEntry->num, dbEntry->snr);
|
LOG_DEBUG(" Node %d: node_id=0x%x, snr=%.2f\n", i, dbEntry->num, dbEntry->snr);
|
||||||
}
|
}
|
||||||
LOG_DEBUG("----------------\n");
|
LOG_DEBUG("----------------\n");
|
||||||
}
|
}
|
||||||
@ -48,12 +48,12 @@ NOTE: for debugging only
|
|||||||
void NeighborInfoModule::printNodeDBNeighbors(const char *header)
|
void NeighborInfoModule::printNodeDBNeighbors(const char *header)
|
||||||
{
|
{
|
||||||
int num_neighbors = getNumNeighbors();
|
int num_neighbors = getNumNeighbors();
|
||||||
LOG_DEBUG("%s NODEDB SELECTION from Node %d:\n", header, nodeDB.getNodeNum());
|
LOG_DEBUG("%s NODEDB SELECTION from Node 0x%x:\n", header, nodeDB.getNodeNum());
|
||||||
LOG_DEBUG("----------------\n");
|
LOG_DEBUG("----------------\n");
|
||||||
LOG_DEBUG("DB contains %d neighbors\n", num_neighbors);
|
LOG_DEBUG("DB contains %d neighbors\n", num_neighbors);
|
||||||
for (int i = 0; i < num_neighbors; i++) {
|
for (int i = 0; i < num_neighbors; i++) {
|
||||||
const meshtastic_Neighbor *dbEntry = getNeighborByIndex(i);
|
const meshtastic_Neighbor *dbEntry = getNeighborByIndex(i);
|
||||||
LOG_DEBUG(" Node %d: node_id=%d, snr=%.2f\n", i, dbEntry->node_id, dbEntry->snr);
|
LOG_DEBUG(" Node %d: node_id=0x%x, snr=%.2f\n", i, dbEntry->node_id, dbEntry->snr);
|
||||||
}
|
}
|
||||||
LOG_DEBUG("----------------\n");
|
LOG_DEBUG("----------------\n");
|
||||||
}
|
}
|
||||||
@ -66,7 +66,7 @@ NOTE: For debugging only
|
|||||||
void NeighborInfoModule::printNodeDBSelection(const char *header, const meshtastic_NeighborInfo *np)
|
void NeighborInfoModule::printNodeDBSelection(const char *header, const meshtastic_NeighborInfo *np)
|
||||||
{
|
{
|
||||||
int num_neighbors = getNumNeighbors();
|
int num_neighbors = getNumNeighbors();
|
||||||
LOG_DEBUG("%s NODEDB SELECTION from Node %d:\n", header, nodeDB.getNodeNum());
|
LOG_DEBUG("%s NODEDB SELECTION from Node 0x%x:\n", header, nodeDB.getNodeNum());
|
||||||
LOG_DEBUG("----------------\n");
|
LOG_DEBUG("----------------\n");
|
||||||
LOG_DEBUG("Selected %d neighbors of %d DB neighbors\n", np->neighbors_count, num_neighbors);
|
LOG_DEBUG("Selected %d neighbors of %d DB neighbors\n", np->neighbors_count, num_neighbors);
|
||||||
for (int i = 0; i < num_neighbors; i++) {
|
for (int i = 0; i < num_neighbors; i++) {
|
||||||
@ -78,9 +78,9 @@ void NeighborInfoModule::printNodeDBSelection(const char *header, const meshtast
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!chosen) {
|
if (!chosen) {
|
||||||
LOG_DEBUG(" Node %d: neighbor=%d, snr=%.2f\n", i, dbEntry->node_id, dbEntry->snr);
|
LOG_DEBUG(" Node %d: neighbor=0x%x, snr=%.2f\n", i, dbEntry->node_id, dbEntry->snr);
|
||||||
} else {
|
} else {
|
||||||
LOG_DEBUG("---> Node %d: neighbor=%d, snr=%.2f\n", i, dbEntry->node_id, dbEntry->snr);
|
LOG_DEBUG("---> Node %d: neighbor=0x%x, snr=%.2f\n", i, dbEntry->node_id, dbEntry->snr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LOG_DEBUG("----------------\n");
|
LOG_DEBUG("----------------\n");
|
||||||
@ -120,7 +120,7 @@ Assumes that the neighborInfo packet has been allocated
|
|||||||
*/
|
*/
|
||||||
uint32_t NeighborInfoModule::collectNeighborInfo(meshtastic_NeighborInfo *neighborInfo)
|
uint32_t NeighborInfoModule::collectNeighborInfo(meshtastic_NeighborInfo *neighborInfo)
|
||||||
{
|
{
|
||||||
int my_node_id = nodeDB.getNodeNum();
|
uint my_node_id = nodeDB.getNodeNum();
|
||||||
neighborInfo->node_id = my_node_id;
|
neighborInfo->node_id = my_node_id;
|
||||||
neighborInfo->last_sent_by_id = my_node_id;
|
neighborInfo->last_sent_by_id = my_node_id;
|
||||||
neighborInfo->node_broadcast_interval_secs = moduleConfig.neighbor_info.update_interval;
|
neighborInfo->node_broadcast_interval_secs = moduleConfig.neighbor_info.update_interval;
|
||||||
@ -255,7 +255,7 @@ void NeighborInfoModule::updateNeighbors(const meshtastic_MeshPacket &mp, const
|
|||||||
}
|
}
|
||||||
|
|
||||||
meshtastic_Neighbor *NeighborInfoModule::getOrCreateNeighbor(NodeNum originalSender, NodeNum n,
|
meshtastic_Neighbor *NeighborInfoModule::getOrCreateNeighbor(NodeNum originalSender, NodeNum n,
|
||||||
uint32_t node_broadcast_interval_secs, int snr)
|
uint32_t node_broadcast_interval_secs, float snr)
|
||||||
{
|
{
|
||||||
// our node and the phone are the same node (not neighbors)
|
// our node and the phone are the same node (not neighbors)
|
||||||
if (n == 0) {
|
if (n == 0) {
|
||||||
|
@ -49,7 +49,7 @@ class NeighborInfoModule : public ProtobufModule<meshtastic_NeighborInfo>, priva
|
|||||||
meshtastic_NeighborInfo *allocateNeighborInfoPacket();
|
meshtastic_NeighborInfo *allocateNeighborInfoPacket();
|
||||||
|
|
||||||
// Find a neighbor in our DB, create an empty neighbor if missing
|
// Find a neighbor in our DB, create an empty neighbor if missing
|
||||||
meshtastic_Neighbor *getOrCreateNeighbor(NodeNum originalSender, NodeNum n, uint32_t node_broadcast_interval_secs, int snr);
|
meshtastic_Neighbor *getOrCreateNeighbor(NodeNum originalSender, NodeNum n, uint32_t node_broadcast_interval_secs, float snr);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Send info on our node's neighbors into the mesh
|
* Send info on our node's neighbors into the mesh
|
||||||
|
@ -11,8 +11,8 @@
|
|||||||
PositionModule *positionModule;
|
PositionModule *positionModule;
|
||||||
|
|
||||||
PositionModule::PositionModule()
|
PositionModule::PositionModule()
|
||||||
: ProtobufModule("position", meshtastic_PortNum_POSITION_APP, &meshtastic_Position_msg), concurrency::OSThread(
|
: ProtobufModule("position", meshtastic_PortNum_POSITION_APP, &meshtastic_Position_msg),
|
||||||
"PositionModule")
|
concurrency::OSThread("PositionModule")
|
||||||
{
|
{
|
||||||
isPromiscuous = true; // We always want to update our nodedb, even if we are sniffing on others
|
isPromiscuous = true; // We always want to update our nodedb, even if we are sniffing on others
|
||||||
setIntervalFromNow(60 * 1000); // Send our initial position 60 seconds after we start (to give GPS time to setup)
|
setIntervalFromNow(60 * 1000); // Send our initial position 60 seconds after we start (to give GPS time to setup)
|
||||||
@ -65,7 +65,7 @@ bool PositionModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, mes
|
|||||||
meshtastic_MeshPacket *PositionModule::allocReply()
|
meshtastic_MeshPacket *PositionModule::allocReply()
|
||||||
{
|
{
|
||||||
if (ignoreRequest) {
|
if (ignoreRequest) {
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
meshtastic_NodeInfoLite *node = service.refreshLocalMeshNode(); // should guarantee there is now a position
|
meshtastic_NodeInfoLite *node = service.refreshLocalMeshNode(); // should guarantee there is now a position
|
||||||
@ -142,6 +142,11 @@ void PositionModule::sendOurPosition(NodeNum dest, bool wantReplies, uint8_t cha
|
|||||||
service.cancelSending(prevPacketId);
|
service.cancelSending(prevPacketId);
|
||||||
|
|
||||||
meshtastic_MeshPacket *p = allocReply();
|
meshtastic_MeshPacket *p = allocReply();
|
||||||
|
if (p == nullptr) {
|
||||||
|
LOG_WARN("allocReply returned a nullptr");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
p->to = dest;
|
p->to = dest;
|
||||||
p->decoded.want_response = wantReplies;
|
p->decoded.want_response = wantReplies;
|
||||||
if (config.device.role == meshtastic_Config_DeviceConfig_Role_TRACKER)
|
if (config.device.role == meshtastic_Config_DeviceConfig_Role_TRACKER)
|
||||||
|
@ -29,7 +29,7 @@ class RangeTestModuleRadio : public SinglePortModule
|
|||||||
uint32_t lastRxID = 0;
|
uint32_t lastRxID = 0;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RangeTestModuleRadio() : SinglePortModule("RangeTestModuleRadio", meshtastic_PortNum_TEXT_MESSAGE_APP)
|
RangeTestModuleRadio() : SinglePortModule("RangeTestModuleRadio", meshtastic_PortNum_RANGE_TEST_APP)
|
||||||
{
|
{
|
||||||
loopbackOk = true; // Allow locally generated messages to loop back to the client
|
loopbackOk = true; // Allow locally generated messages to loop back to the client
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include "TextMessageModule.h"
|
#include "TextMessageModule.h"
|
||||||
|
#include "MeshService.h"
|
||||||
#include "NodeDB.h"
|
#include "NodeDB.h"
|
||||||
#include "PowerFSM.h"
|
#include "PowerFSM.h"
|
||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
@ -22,3 +23,8 @@ ProcessMessage TextMessageModule::handleReceived(const meshtastic_MeshPacket &mp
|
|||||||
|
|
||||||
return ProcessMessage::CONTINUE; // Let others look at this message also if they want
|
return ProcessMessage::CONTINUE; // Let others look at this message also if they want
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool TextMessageModule::wantPacket(const meshtastic_MeshPacket *p)
|
||||||
|
{
|
||||||
|
return MeshService::isTextPayload(p);
|
||||||
|
}
|
@ -20,6 +20,7 @@ class TextMessageModule : public SinglePortModule, public Observable<const mesht
|
|||||||
it
|
it
|
||||||
*/
|
*/
|
||||||
virtual ProcessMessage handleReceived(const meshtastic_MeshPacket &mp) override;
|
virtual ProcessMessage handleReceived(const meshtastic_MeshPacket &mp) override;
|
||||||
|
virtual bool wantPacket(const meshtastic_MeshPacket *p) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern TextMessageModule *textMessageModule;
|
extern TextMessageModule *textMessageModule;
|
@ -119,6 +119,8 @@
|
|||||||
#define HW_VENDOR meshtastic_HardwareModel_BETAFPV_900_NANO_TX
|
#define HW_VENDOR meshtastic_HardwareModel_BETAFPV_900_NANO_TX
|
||||||
#elif defined(PICOMPUTER_S3)
|
#elif defined(PICOMPUTER_S3)
|
||||||
#define HW_VENDOR meshtastic_HardwareModel_PICOMPUTER_S3
|
#define HW_VENDOR meshtastic_HardwareModel_PICOMPUTER_S3
|
||||||
|
#elif defined(HELTEC_HT62)
|
||||||
|
#define HW_VENDOR meshtastic_HardwareModel_HELTEC_HT62
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -149,4 +151,4 @@
|
|||||||
#define RF95_NSS 18
|
#define RF95_NSS 18
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define SERIAL0_RX_GPIO 3 // Always GPIO3 on ESP32
|
#define SERIAL0_RX_GPIO 3 // Always GPIO3 on ESP32
|
||||||
|
@ -9,10 +9,10 @@
|
|||||||
#include "BleOta.h"
|
#include "BleOta.h"
|
||||||
#include "mesh/http/WiFiAPClient.h"
|
#include "mesh/http/WiFiAPClient.h"
|
||||||
|
|
||||||
|
#include "meshUtils.h"
|
||||||
#include "sleep.h"
|
#include "sleep.h"
|
||||||
#include "soc/rtc.h"
|
#include "soc/rtc.h"
|
||||||
#include "target_specific.h"
|
#include "target_specific.h"
|
||||||
#include "utils.h"
|
|
||||||
#include <Preferences.h>
|
#include <Preferences.h>
|
||||||
#include <driver/rtc_io.h>
|
#include <driver/rtc_io.h>
|
||||||
#include <nvs.h>
|
#include <nvs.h>
|
||||||
@ -220,4 +220,4 @@ void cpuDeepSleep(uint32_t msecToWake)
|
|||||||
|
|
||||||
esp_sleep_enable_timer_wakeup(msecToWake * 1000ULL); // call expects usecs
|
esp_sleep_enable_timer_wakeup(msecToWake * 1000ULL); // call expects usecs
|
||||||
esp_deep_sleep_start(); // TBD mA sleep current (battery)
|
esp_deep_sleep_start(); // TBD mA sleep current (battery)
|
||||||
}
|
}
|
32
variants/heltec_esp32c3/pins_arduino.h
Normal file
32
variants/heltec_esp32c3/pins_arduino.h
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
#ifndef Pins_Arduino_h
|
||||||
|
#define Pins_Arduino_h
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define EXTERNAL_NUM_INTERRUPTS 22
|
||||||
|
#define NUM_DIGITAL_PINS 22
|
||||||
|
#define NUM_ANALOG_INPUTS 6
|
||||||
|
|
||||||
|
#define analogInputToDigitalPin(p) (((p) < NUM_ANALOG_INPUTS) ? (esp32_adc2gpio[(p)]) : -1)
|
||||||
|
#define digitalPinToInterrupt(p) (((p) < NUM_DIGITAL_PINS) ? (p) : -1)
|
||||||
|
#define digitalPinHasPWM(p) (p < EXTERNAL_NUM_INTERRUPTS)
|
||||||
|
|
||||||
|
static const uint8_t TX = 21;
|
||||||
|
static const uint8_t RX = 20;
|
||||||
|
|
||||||
|
static const uint8_t SDA = 1;
|
||||||
|
static const uint8_t SCL = 0;
|
||||||
|
|
||||||
|
static const uint8_t SS = 8;
|
||||||
|
static const uint8_t MOSI = 7;
|
||||||
|
static const uint8_t MISO = 6;
|
||||||
|
static const uint8_t SCK = 10;
|
||||||
|
|
||||||
|
static const uint8_t A0 = 0;
|
||||||
|
static const uint8_t A1 = 1;
|
||||||
|
static const uint8_t A2 = 2;
|
||||||
|
static const uint8_t A3 = 3;
|
||||||
|
static const uint8_t A4 = 4;
|
||||||
|
static const uint8_t A5 = 5;
|
||||||
|
|
||||||
|
#endif /* Pins_Arduino_h */
|
12
variants/heltec_esp32c3/platformio.ini
Normal file
12
variants/heltec_esp32c3/platformio.ini
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
[env:heltec-ht62-esp32c3-sx1262]
|
||||||
|
extends = esp32c3_base
|
||||||
|
board = esp32-c3-devkitm-1
|
||||||
|
board_level = extra
|
||||||
|
build_flags =
|
||||||
|
${esp32_base.build_flags}
|
||||||
|
-D HELTEC_HT62
|
||||||
|
-I variants/heltec_esp32c3
|
||||||
|
monitor_speed = 115200
|
||||||
|
upload_protocol = esptool
|
||||||
|
upload_port = /dev/ttyUSB0
|
||||||
|
upload_speed = 921600
|
36
variants/heltec_esp32c3/variant.h
Normal file
36
variants/heltec_esp32c3/variant.h
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
#define I2C_SDA 1
|
||||||
|
#define I2C_SCL 0
|
||||||
|
|
||||||
|
#define BUTTON_PIN 9
|
||||||
|
#define BUTTON_NEED_PULLUP
|
||||||
|
|
||||||
|
// LED flashes brighter
|
||||||
|
// https://resource.heltec.cn/download/HT-CT62/HT-CT62_Reference_Design.pdf
|
||||||
|
#define LED_PIN 18 // LED
|
||||||
|
#define LED_INVERTED 1
|
||||||
|
|
||||||
|
#define HAS_SCREEN 0
|
||||||
|
#define HAS_GPS 0
|
||||||
|
#undef GPS_RX_PIN
|
||||||
|
#undef GPS_TX_PIN
|
||||||
|
|
||||||
|
#undef RF95_SCK
|
||||||
|
#undef RF95_MISO
|
||||||
|
#undef RF95_MOSI
|
||||||
|
#undef RF95_NSS
|
||||||
|
|
||||||
|
#define USE_SX1262
|
||||||
|
#define RF95_SCK 10
|
||||||
|
#define RF95_MISO 6
|
||||||
|
#define RF95_MOSI 7
|
||||||
|
#define RF95_NSS 8
|
||||||
|
#define LORA_DIO0 RADIOLIB_NC
|
||||||
|
#define LORA_RESET 5
|
||||||
|
#define LORA_DIO1 3
|
||||||
|
#define LORA_DIO2 RADIOLIB_NC
|
||||||
|
#define LORA_BUSY 4
|
||||||
|
#define SX126X_CS RF95_NSS
|
||||||
|
#define SX126X_DIO1 LORA_DIO1
|
||||||
|
#define SX126X_BUSY LORA_BUSY
|
||||||
|
#define SX126X_RESET LORA_RESET
|
||||||
|
#define SX126X_E22
|
@ -1,4 +1,4 @@
|
|||||||
[VERSION]
|
[VERSION]
|
||||||
major = 2
|
major = 2
|
||||||
minor = 2
|
minor = 2
|
||||||
build = 2
|
build = 4
|
||||||
|
Loading…
Reference in New Issue
Block a user