kopia lustrzana https://github.com/meshtastic/firmware
Merge branch 'master' into RCWL-9620
commit
472db5b237
|
@ -45,6 +45,7 @@ jobs:
|
|||
|
||||
- name: build .debpkg
|
||||
run: |
|
||||
mkdir -p .debpkg/debian
|
||||
mkdir -p .debpkg/usr/share/doc/meshtasticd/web
|
||||
mkdir -p .debpkg/usr/sbin
|
||||
mkdir -p .debpkg/etc/meshtasticd
|
||||
|
@ -55,6 +56,7 @@ jobs:
|
|||
cp bin/config-dist.yaml .debpkg/etc/meshtasticd/config.yaml
|
||||
chmod +x .debpkg/usr/sbin/meshtasticd
|
||||
cp bin/meshtasticd.service .debpkg/usr/lib/systemd/system/meshtasticd.service
|
||||
echo "etc/meshtasticd/config.yaml" > .debpkg/debian/conffiles
|
||||
|
||||
- uses: jiro4989/build-deb-action@v3
|
||||
with:
|
||||
|
|
|
@ -24,7 +24,7 @@ lib_deps =
|
|||
${env.lib_deps}
|
||||
${networking_base.lib_deps}
|
||||
rweather/Crypto@^0.4.0
|
||||
lovyan03/LovyanGFX@^1.1.12
|
||||
https://github.com/lovyan03/LovyanGFX.git#d35e60f269dfecbb18a8cb0fd07d594c2fb7e7a8
|
||||
|
||||
build_flags =
|
||||
${arduino_base.build_flags}
|
||||
|
@ -34,4 +34,4 @@ build_flags =
|
|||
-DPORTDUINO_LINUX_HARDWARE
|
||||
-lbluetooth
|
||||
-lgpiod
|
||||
-lyaml-cpp
|
||||
-lyaml-cpp
|
|
@ -38,6 +38,15 @@ Lora:
|
|||
# Busy: 20
|
||||
# Reset: 18
|
||||
|
||||
# Module: sx1268 # SX1268-based modules, tested with Ebyte E22 400M33S
|
||||
# CS: 21
|
||||
# IRQ: 16
|
||||
# Busy: 20
|
||||
# Reset: 18
|
||||
# TXen: 6
|
||||
# RXen: 12
|
||||
# DIO3_TCXO_VOLTAGE: true
|
||||
|
||||
# DIO3_TCXO_VOLTAGE: true # the Waveshare Core1262 and others are known to need this setting
|
||||
|
||||
# TXen: x # TX and RX enable pins
|
||||
|
|
|
@ -78,7 +78,7 @@ lib_deps =
|
|||
https://github.com/meshtastic/esp8266-oled-ssd1306.git#ee628ee6c9588d4c56c9e3da35f0fc9448ad54a8 ; 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#964f75a72cccd6b53cd74e4add1f7a42c6f7344d
|
||||
https://github.com/meshtastic/TinyGPSPlus.git#71a82db35f3b973440044c476d4bcdc673b104f4
|
||||
https://github.com/meshtastic/ArduinoThread.git#1ae8778c85d0a2a729f989e0b1e7d7c4dc84eef0
|
||||
nanopb/Nanopb@^0.4.7
|
||||
erriez/ErriezCRC32@^1.0.1
|
||||
|
|
|
@ -136,9 +136,12 @@ int32_t ButtonThread::runOnce()
|
|||
case BUTTON_EVENT_DOUBLE_PRESSED: {
|
||||
LOG_BUTTON("Double press!\n");
|
||||
service.refreshLocalMeshNode();
|
||||
service.sendNetworkPing(NODENUM_BROADCAST, true);
|
||||
auto sentPosition = service.trySendPosition(NODENUM_BROADCAST, true);
|
||||
if (screen) {
|
||||
screen->print("Sent ad-hoc ping\n");
|
||||
if (sentPosition)
|
||||
screen->print("Sent ad-hoc position\n");
|
||||
else
|
||||
screen->print("Sent ad-hoc nodeinfo\n");
|
||||
screen->forceDisplay(true); // Force a new UI frame, then force an EInk update
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -184,7 +184,7 @@ class AnalogBatteryLevel : public HasBatteryLevel
|
|||
virtual uint16_t getBattVoltage() override
|
||||
{
|
||||
|
||||
#if defined(HAS_TELEMETRY) && !defined(ARCH_PORTDUINO) && !defined(HAS_PMU)
|
||||
#if HAS_TELEMETRY && !defined(ARCH_PORTDUINO) && !defined(HAS_PMU)
|
||||
if (hasINA()) {
|
||||
LOG_DEBUG("Using INA on I2C addr 0x%x for device battery voltage\n", config.power.device_battery_ina_address);
|
||||
return getINAVoltage();
|
||||
|
@ -360,7 +360,7 @@ 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_TELEMETRY) && !defined(ARCH_PORTDUINO)
|
||||
#if HAS_TELEMETRY && !defined(ARCH_PORTDUINO)
|
||||
uint16_t getINAVoltage()
|
||||
{
|
||||
if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA219].first == config.power.device_battery_ina_address) {
|
||||
|
|
|
@ -223,7 +223,7 @@ int32_t getTZOffset()
|
|||
now = time(NULL);
|
||||
gmt = gmtime(&now);
|
||||
gmt->tm_isdst = -1;
|
||||
return (int16_t)difftime(now, mktime(gmt));
|
||||
return (int32_t)difftime(now, mktime(gmt));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
#include "configuration.h"
|
||||
#include "main.h"
|
||||
#if ARCH_PORTDUINO
|
||||
#include "mesh_bus_spi.h"
|
||||
#include "platform/portduino/PortduinoGlue.h"
|
||||
#endif
|
||||
|
||||
|
@ -340,7 +339,7 @@ static TFT_eSPI *tft = nullptr; // Invoke library, pins defined in User_Setup.h
|
|||
class LGFX : public lgfx::LGFX_Device
|
||||
{
|
||||
lgfx::Panel_LCD *_panel_instance;
|
||||
lgfx::Mesh_Bus_SPI _bus_instance;
|
||||
lgfx::Bus_SPI _bus_instance;
|
||||
|
||||
lgfx::ITouch *_touch_instance;
|
||||
|
||||
|
@ -357,7 +356,7 @@ class LGFX : public lgfx::LGFX_Device
|
|||
_panel_instance = new lgfx::Panel_ILI9341;
|
||||
auto buscfg = _bus_instance.config();
|
||||
buscfg.spi_mode = 0;
|
||||
_bus_instance.spi_device(DisplaySPI, settingsStrings[displayspidev]);
|
||||
_bus_instance.spi_device(DisplaySPI);
|
||||
|
||||
buscfg.pin_dc = settingsMap[displayDC]; // Set SPI DC pin number (-1 = disable)
|
||||
|
||||
|
|
|
@ -1,188 +0,0 @@
|
|||
// This code has been copied from LovyanGFX to make the SPI device selectable for touchscreens.
|
||||
// Ideally this could eventually be an inherited class from BUS_SPI,
|
||||
// but currently too many internal objects are set private.
|
||||
|
||||
#include "configuration.h"
|
||||
#if ARCH_PORTDUINO
|
||||
#include "lgfx/v1/misc/pixelcopy.hpp"
|
||||
#include "main.h"
|
||||
#include "mesh_bus_spi.h"
|
||||
#include <Arduino.h>
|
||||
#include <SPI.h>
|
||||
|
||||
namespace lgfx
|
||||
{
|
||||
inline namespace v1
|
||||
{
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
void Mesh_Bus_SPI::config(const config_t &config)
|
||||
{
|
||||
_cfg = config;
|
||||
|
||||
if (_cfg.pin_dc >= 0) {
|
||||
pinMode(_cfg.pin_dc, pin_mode_t::output);
|
||||
gpio_hi(_cfg.pin_dc);
|
||||
}
|
||||
}
|
||||
|
||||
bool Mesh_Bus_SPI::init(void)
|
||||
{
|
||||
dc_h();
|
||||
pinMode(_cfg.pin_dc, pin_mode_t::output);
|
||||
if (SPIName != "")
|
||||
PrivateSPI->begin(SPIName.c_str());
|
||||
else
|
||||
PrivateSPI->begin();
|
||||
return true;
|
||||
}
|
||||
|
||||
void Mesh_Bus_SPI::release(void)
|
||||
{
|
||||
PrivateSPI->end();
|
||||
}
|
||||
|
||||
void Mesh_Bus_SPI::spi_device(HardwareSPI *newSPI, std::string newSPIName)
|
||||
{
|
||||
PrivateSPI = newSPI;
|
||||
SPIName = newSPIName;
|
||||
}
|
||||
void Mesh_Bus_SPI::beginTransaction(void)
|
||||
{
|
||||
dc_h();
|
||||
SPISettings setting(_cfg.freq_write, MSBFIRST, _cfg.spi_mode);
|
||||
PrivateSPI->beginTransaction(setting);
|
||||
}
|
||||
|
||||
void Mesh_Bus_SPI::endTransaction(void)
|
||||
{
|
||||
PrivateSPI->endTransaction();
|
||||
dc_h();
|
||||
}
|
||||
|
||||
void Mesh_Bus_SPI::beginRead(void)
|
||||
{
|
||||
PrivateSPI->endTransaction();
|
||||
// SPISettings setting(_cfg.freq_read, BitOrder::MSBFIRST, _cfg.spi_mode, false);
|
||||
SPISettings setting(_cfg.freq_read, MSBFIRST, _cfg.spi_mode);
|
||||
PrivateSPI->beginTransaction(setting);
|
||||
}
|
||||
|
||||
void Mesh_Bus_SPI::endRead(void)
|
||||
{
|
||||
PrivateSPI->endTransaction();
|
||||
beginTransaction();
|
||||
}
|
||||
|
||||
void Mesh_Bus_SPI::wait(void) {}
|
||||
|
||||
bool Mesh_Bus_SPI::busy(void) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Mesh_Bus_SPI::writeCommand(uint32_t data, uint_fast8_t bit_length)
|
||||
{
|
||||
dc_l();
|
||||
PrivateSPI->transfer((uint8_t *)&data, bit_length >> 3);
|
||||
dc_h();
|
||||
return true;
|
||||
}
|
||||
|
||||
void Mesh_Bus_SPI::writeData(uint32_t data, uint_fast8_t bit_length)
|
||||
{
|
||||
PrivateSPI->transfer((uint8_t *)&data, bit_length >> 3);
|
||||
}
|
||||
|
||||
void Mesh_Bus_SPI::writeDataRepeat(uint32_t data, uint_fast8_t bit_length, uint32_t length)
|
||||
{
|
||||
const uint8_t dst_bytes = bit_length >> 3;
|
||||
uint32_t limit = (dst_bytes == 3) ? 12 : 16;
|
||||
auto buf = _flip_buffer.getBuffer(512);
|
||||
size_t fillpos = 0;
|
||||
reinterpret_cast<uint32_t *>(buf)[0] = data;
|
||||
fillpos += dst_bytes;
|
||||
uint32_t len;
|
||||
do {
|
||||
len = ((length - 1) % limit) + 1;
|
||||
if (limit <= 64)
|
||||
limit <<= 1;
|
||||
|
||||
while (fillpos < len * dst_bytes) {
|
||||
memcpy(&buf[fillpos], buf, fillpos);
|
||||
fillpos += fillpos;
|
||||
}
|
||||
|
||||
PrivateSPI->transfer(buf, len * dst_bytes);
|
||||
} while (length -= len);
|
||||
}
|
||||
|
||||
void Mesh_Bus_SPI::writePixels(pixelcopy_t *param, uint32_t length)
|
||||
{
|
||||
const uint8_t dst_bytes = param->dst_bits >> 3;
|
||||
uint32_t limit = (dst_bytes == 3) ? 12 : 16;
|
||||
uint32_t len;
|
||||
do {
|
||||
len = ((length - 1) % limit) + 1;
|
||||
if (limit <= 32)
|
||||
limit <<= 1;
|
||||
auto buf = _flip_buffer.getBuffer(len * dst_bytes);
|
||||
param->fp_copy(buf, 0, len, param);
|
||||
PrivateSPI->transfer(buf, len * dst_bytes);
|
||||
} while (length -= len);
|
||||
}
|
||||
|
||||
void Mesh_Bus_SPI::writeBytes(const uint8_t *data, uint32_t length, bool dc, bool use_dma)
|
||||
{
|
||||
if (dc)
|
||||
dc_h();
|
||||
else
|
||||
dc_l();
|
||||
PrivateSPI->transfer(const_cast<uint8_t *>(data), length);
|
||||
if (!dc)
|
||||
dc_h();
|
||||
}
|
||||
|
||||
uint32_t Mesh_Bus_SPI::readData(uint_fast8_t bit_length)
|
||||
{
|
||||
uint32_t res = 0;
|
||||
bit_length >>= 3;
|
||||
if (!bit_length)
|
||||
return res;
|
||||
int idx = 0;
|
||||
do {
|
||||
res |= PrivateSPI->transfer(0) << idx;
|
||||
idx += 8;
|
||||
} while (--bit_length);
|
||||
return res;
|
||||
}
|
||||
|
||||
bool Mesh_Bus_SPI::readBytes(uint8_t *dst, uint32_t length, bool use_dma)
|
||||
{
|
||||
do {
|
||||
dst[0] = PrivateSPI->transfer(0);
|
||||
++dst;
|
||||
} while (--length);
|
||||
return true;
|
||||
}
|
||||
|
||||
void Mesh_Bus_SPI::readPixels(void *dst, pixelcopy_t *param, uint32_t length)
|
||||
{
|
||||
uint32_t bytes = param->src_bits >> 3;
|
||||
uint32_t dstindex = 0;
|
||||
uint32_t len = 4;
|
||||
uint8_t buf[24];
|
||||
param->src_data = buf;
|
||||
do {
|
||||
if (len > length)
|
||||
len = length;
|
||||
readBytes((uint8_t *)buf, len * bytes, true);
|
||||
param->src_x = 0;
|
||||
dstindex = param->fp_copy(dst, dstindex, dstindex + len, param);
|
||||
length -= len;
|
||||
} while (length);
|
||||
}
|
||||
|
||||
} // namespace v1
|
||||
} // namespace lgfx
|
||||
#endif
|
|
@ -1,100 +0,0 @@
|
|||
#if ARCH_PORTDUINO
|
||||
/*----------------------------------------------------------------------------/
|
||||
Lovyan GFX - Graphics library for embedded devices.
|
||||
|
||||
Original Source:
|
||||
https://github.com/lovyan03/LovyanGFX/
|
||||
|
||||
Licence:
|
||||
[FreeBSD](https://github.com/lovyan03/LovyanGFX/blob/master/license.txt)
|
||||
|
||||
Author:
|
||||
[lovyan03](https://twitter.com/lovyan03)
|
||||
|
||||
Contributors:
|
||||
[ciniml](https://github.com/ciniml)
|
||||
[mongonta0716](https://github.com/mongonta0716)
|
||||
[tobozo](https://github.com/tobozo)
|
||||
/----------------------------------------------------------------------------*/
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "lgfx/v1/Bus.hpp"
|
||||
#include "lgfx/v1/platforms/common.hpp"
|
||||
|
||||
namespace lgfx
|
||||
{
|
||||
inline namespace v1
|
||||
{
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
class Mesh_Bus_SPI : public IBus
|
||||
{
|
||||
public:
|
||||
struct config_t {
|
||||
uint32_t freq_write = 16000000;
|
||||
uint32_t freq_read = 8000000;
|
||||
// bool spi_3wire = true;
|
||||
// bool use_lock = true;
|
||||
int16_t pin_sclk = -1;
|
||||
int16_t pin_miso = -1;
|
||||
int16_t pin_mosi = -1;
|
||||
int16_t pin_dc = -1;
|
||||
uint8_t spi_mode = 0;
|
||||
};
|
||||
|
||||
const config_t &config(void) const { return _cfg; }
|
||||
|
||||
void config(const config_t &config);
|
||||
|
||||
bus_type_t busType(void) const override { return bus_type_t::bus_spi; }
|
||||
|
||||
bool init(void) override;
|
||||
void release(void) override;
|
||||
void spi_device(HardwareSPI *newSPI, std::string newSPIName);
|
||||
|
||||
void beginTransaction(void) override;
|
||||
void endTransaction(void) override;
|
||||
void wait(void) override;
|
||||
bool busy(void) const override;
|
||||
|
||||
bool writeCommand(uint32_t data, uint_fast8_t bit_length) override;
|
||||
void writeData(uint32_t data, uint_fast8_t bit_length) override;
|
||||
void writeDataRepeat(uint32_t data, uint_fast8_t bit_length, uint32_t count) override;
|
||||
void writePixels(pixelcopy_t *param, uint32_t length) override;
|
||||
void writeBytes(const uint8_t *data, uint32_t length, bool dc, bool use_dma) override;
|
||||
|
||||
void initDMA(void) {}
|
||||
void flush(void) {}
|
||||
void addDMAQueue(const uint8_t *data, uint32_t length) override { writeBytes(data, length, true, true); }
|
||||
void execDMAQueue(void) {}
|
||||
uint8_t *getDMABuffer(uint32_t length) override { return _flip_buffer.getBuffer(length); }
|
||||
|
||||
void beginRead(void) override;
|
||||
void endRead(void) override;
|
||||
uint32_t readData(uint_fast8_t bit_length) override;
|
||||
bool readBytes(uint8_t *dst, uint32_t length, bool use_dma) override;
|
||||
void readPixels(void *dst, pixelcopy_t *param, uint32_t length) override;
|
||||
|
||||
private:
|
||||
HardwareSPI *PrivateSPI;
|
||||
std::string SPIName;
|
||||
__attribute__((always_inline)) inline void dc_h(void) { gpio_hi(_cfg.pin_dc); }
|
||||
__attribute__((always_inline)) inline void dc_l(void) { gpio_lo(_cfg.pin_dc); }
|
||||
|
||||
config_t _cfg;
|
||||
FlipBuffer _flip_buffer;
|
||||
bool _need_wait;
|
||||
uint32_t _mask_reg_dc;
|
||||
uint32_t _last_apb_freq = -1;
|
||||
uint32_t _clkdiv_write;
|
||||
uint32_t _clkdiv_read;
|
||||
volatile uint32_t *_gpio_reg_dc_h;
|
||||
volatile uint32_t *_gpio_reg_dc_l;
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
} // namespace v1
|
||||
} // namespace lgfx
|
||||
#endif
|
15
src/main.cpp
15
src/main.cpp
|
@ -771,6 +771,21 @@ void setup()
|
|||
LOG_INFO("SX1280 Radio init succeeded, using SX1280 radio\n");
|
||||
}
|
||||
}
|
||||
} else if (settingsMap[use_sx1268]) {
|
||||
if (!rIf) {
|
||||
LOG_DEBUG("Attempting to activate sx1268 radio on SPI port %s\n", settingsStrings[spidev].c_str());
|
||||
LockingArduinoHal *RadioLibHAL = new LockingArduinoHal(*LoraSPI, spiSettings);
|
||||
rIf = new SX1268Interface((LockingArduinoHal *)RadioLibHAL, settingsMap[cs], settingsMap[irq], settingsMap[reset],
|
||||
settingsMap[busy]);
|
||||
if (!rIf->init()) {
|
||||
LOG_ERROR("Failed to find SX1268 radio\n");
|
||||
delete rIf;
|
||||
rIf = NULL;
|
||||
exit(EXIT_FAILURE);
|
||||
} else {
|
||||
LOG_INFO("SX1268 Radio init succeeded, using SX1268 radio\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined(HW_SPI1_DEVICE)
|
||||
|
|
|
@ -267,7 +267,7 @@ void MeshService::sendToMesh(meshtastic_MeshPacket *p, RxSource src, bool ccToPh
|
|||
}
|
||||
}
|
||||
|
||||
void MeshService::sendNetworkPing(NodeNum dest, bool wantReplies)
|
||||
bool MeshService::trySendPosition(NodeNum dest, bool wantReplies)
|
||||
{
|
||||
meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(nodeDB->getNodeNum());
|
||||
|
||||
|
@ -278,6 +278,7 @@ void MeshService::sendNetworkPing(NodeNum dest, bool wantReplies)
|
|||
if (positionModule) {
|
||||
LOG_INFO("Sending position ping to 0x%x, wantReplies=%d, channel=%d\n", dest, wantReplies, node->channel);
|
||||
positionModule->sendOurPosition(dest, wantReplies, node->channel);
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
#endif
|
||||
|
@ -286,6 +287,7 @@ void MeshService::sendNetworkPing(NodeNum dest, bool wantReplies)
|
|||
nodeInfoModule->sendOurNodeInfo(dest, wantReplies, node->channel);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void MeshService::sendToPhone(meshtastic_MeshPacket *p)
|
||||
|
|
|
@ -108,8 +108,9 @@ class MeshService
|
|||
void reloadOwner(bool shouldSave = true);
|
||||
|
||||
/// Called when the user wakes up our GUI, normally sends our latest location to the mesh (if we have it), otherwise at least
|
||||
/// sends our owner
|
||||
void sendNetworkPing(NodeNum dest, bool wantReplies = false);
|
||||
/// sends our nodeinfo
|
||||
/// returns true if we sent a position
|
||||
bool trySendPosition(NodeNum dest, bool wantReplies = false);
|
||||
|
||||
/// Send a packet into the mesh - note p must have been allocated from packetPool. We will return it to that pool after
|
||||
/// sending. This is the ONLY function you should use for sending messages into the mesh, because it also updates the nodedb
|
||||
|
|
|
@ -233,14 +233,16 @@ int32_t CannedMessageModule::runOnce()
|
|||
{
|
||||
if (((!moduleConfig.canned_message.enabled) && !CANNED_MESSAGE_MODULE_ENABLE) ||
|
||||
(this->runState == CANNED_MESSAGE_RUN_STATE_DISABLED) || (this->runState == CANNED_MESSAGE_RUN_STATE_INACTIVE)) {
|
||||
temporaryMessage = "";
|
||||
return INT32_MAX;
|
||||
}
|
||||
// LOG_DEBUG("Check status\n");
|
||||
UIFrameEvent e = {false, true};
|
||||
if ((this->runState == CANNED_MESSAGE_RUN_STATE_SENDING_ACTIVE) ||
|
||||
(this->runState == CANNED_MESSAGE_RUN_STATE_ACK_NACK_RECEIVED)) {
|
||||
// TODO: might have some feedback of sendig state
|
||||
(this->runState == CANNED_MESSAGE_RUN_STATE_ACK_NACK_RECEIVED) || (this->runState == CANNED_MESSAGE_RUN_STATE_MESSAGE)) {
|
||||
// TODO: might have some feedback of sending state
|
||||
this->runState = CANNED_MESSAGE_RUN_STATE_INACTIVE;
|
||||
temporaryMessage = "";
|
||||
e.frameChanged = true;
|
||||
this->currentMessageIndex = -1;
|
||||
this->freetext = ""; // clear freetext
|
||||
|
@ -434,7 +436,7 @@ int32_t CannedMessageModule::runOnce()
|
|||
}
|
||||
if (screen)
|
||||
screen->forceDisplay();
|
||||
runState = CANNED_MESSAGE_RUN_STATE_INACTIVE;
|
||||
showTemporaryMessage("GPS Toggled");
|
||||
break;
|
||||
|
||||
// mute (switch off/toggle) external notifications on fn+m
|
||||
|
@ -442,18 +444,21 @@ int32_t CannedMessageModule::runOnce()
|
|||
if (moduleConfig.external_notification.enabled == true) {
|
||||
if (externalNotificationModule->getMute()) {
|
||||
externalNotificationModule->setMute(false);
|
||||
runState = CANNED_MESSAGE_RUN_STATE_INACTIVE;
|
||||
showTemporaryMessage("Notifications \nEnabled");
|
||||
} else {
|
||||
externalNotificationModule->stopNow(); // this will turn off all GPIO and sounds and idle the loop
|
||||
externalNotificationModule->setMute(true);
|
||||
runState = CANNED_MESSAGE_RUN_STATE_INACTIVE;
|
||||
showTemporaryMessage("Notifications \nDisabled");
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0xaf: // fn+space send network ping like double press does
|
||||
service.refreshLocalMeshNode();
|
||||
service.sendNetworkPing(NODENUM_BROADCAST, true);
|
||||
runState = CANNED_MESSAGE_RUN_STATE_INACTIVE;
|
||||
if (service.trySendPosition(NODENUM_BROADCAST, true)) {
|
||||
showTemporaryMessage("Position \nUpdate Sent");
|
||||
} else {
|
||||
showTemporaryMessage("Node Info \nUpdate Sent");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (this->cursor == this->freetext.length()) {
|
||||
|
@ -542,12 +547,27 @@ int CannedMessageModule::getPrevIndex()
|
|||
return this->currentMessageIndex - 1;
|
||||
}
|
||||
}
|
||||
void CannedMessageModule::showTemporaryMessage(const String &message)
|
||||
{
|
||||
temporaryMessage = message;
|
||||
UIFrameEvent e = {false, true};
|
||||
e.frameChanged = true;
|
||||
notifyObservers(&e);
|
||||
runState = CANNED_MESSAGE_RUN_STATE_MESSAGE;
|
||||
// run this loop again in 2 seconds, next iteration will clear the display
|
||||
setIntervalFromNow(2000);
|
||||
}
|
||||
|
||||
void CannedMessageModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
|
||||
{
|
||||
char buffer[50];
|
||||
|
||||
if (cannedMessageModule->runState == CANNED_MESSAGE_RUN_STATE_ACK_NACK_RECEIVED) {
|
||||
if (temporaryMessage.length() != 0) {
|
||||
LOG_DEBUG("Drawing temporary message: %s", temporaryMessage.c_str());
|
||||
display->setTextAlignment(TEXT_ALIGN_CENTER);
|
||||
display->setFont(FONT_MEDIUM);
|
||||
display->drawString(display->getWidth() / 2 + x, 0 + y + 12, temporaryMessage);
|
||||
} else if (cannedMessageModule->runState == CANNED_MESSAGE_RUN_STATE_ACK_NACK_RECEIVED) {
|
||||
display->setTextAlignment(TEXT_ALIGN_CENTER);
|
||||
display->setFont(FONT_MEDIUM);
|
||||
String displayString;
|
||||
|
@ -766,4 +786,4 @@ String CannedMessageModule::drawWithCursor(String text, int cursor)
|
|||
return result;
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -10,6 +10,7 @@ enum cannedMessageModuleRunState {
|
|||
CANNED_MESSAGE_RUN_STATE_FREETEXT,
|
||||
CANNED_MESSAGE_RUN_STATE_SENDING_ACTIVE,
|
||||
CANNED_MESSAGE_RUN_STATE_ACK_NACK_RECEIVED,
|
||||
CANNED_MESSAGE_RUN_STATE_MESSAGE,
|
||||
CANNED_MESSAGE_RUN_STATE_ACTION_SELECT,
|
||||
CANNED_MESSAGE_RUN_STATE_ACTION_UP,
|
||||
CANNED_MESSAGE_RUN_STATE_ACTION_DOWN,
|
||||
|
@ -51,6 +52,8 @@ class CannedMessageModule : public SinglePortModule, public Observable<const UIF
|
|||
void handleGetCannedMessageModuleMessages(const meshtastic_MeshPacket &req, meshtastic_AdminMessage *response);
|
||||
void handleSetCannedMessageModuleMessages(const char *from_msg);
|
||||
|
||||
void showTemporaryMessage(const String &message);
|
||||
|
||||
String drawWithCursor(String text, int cursor);
|
||||
|
||||
/*
|
||||
|
@ -112,7 +115,8 @@ class CannedMessageModule : public SinglePortModule, public Observable<const UIF
|
|||
char *messages[CANNED_MESSAGE_MODULE_MESSAGE_MAX_COUNT];
|
||||
int messagesCount = 0;
|
||||
unsigned long lastTouchMillis = 0;
|
||||
String temporaryMessage;
|
||||
};
|
||||
|
||||
extern CannedMessageModule *cannedMessageModule;
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -54,9 +54,9 @@ void MQTT::onReceive(char *topic, byte *payload, size_t length)
|
|||
JSONObject json;
|
||||
json = json_value->AsObject();
|
||||
|
||||
// parse the channel name from the topic string by looking for "json/"
|
||||
const char *jsonSlash = "json/";
|
||||
char *ptr = strstr(topic, jsonSlash) + sizeof(jsonSlash) + 1; // set pointer to after "json/"
|
||||
// parse the channel name from the topic string
|
||||
// the topic has been checked above for having jsonTopic prefix, so just move past it
|
||||
char *ptr = topic + jsonTopic.length();
|
||||
ptr = strtok(ptr, "/") ? strtok(ptr, "/") : ptr; // if another "/" was added, parse string up to that character
|
||||
meshtastic_Channel sendChannel = channels.getByName(ptr);
|
||||
// We allow downlink JSON packets only on a channel named "mqtt"
|
||||
|
@ -76,6 +76,8 @@ void MQTT::onReceive(char *topic, byte *payload, size_t length)
|
|||
p->channel = json["channel"]->AsNumber();
|
||||
if (json.find("to") != json.end() && json["to"]->IsNumber())
|
||||
p->to = json["to"]->AsNumber();
|
||||
if (json.find("hopLimit") != json.end() && json["hopLimit"]->IsNumber())
|
||||
p->hop_limit = json["hopLimit"]->AsNumber();
|
||||
if (jsonPayloadStr.length() <= sizeof(p->decoded.payload.bytes)) {
|
||||
memcpy(p->decoded.payload.bytes, jsonPayloadStr.c_str(), jsonPayloadStr.length());
|
||||
p->decoded.payload.size = jsonPayloadStr.length();
|
||||
|
@ -105,6 +107,8 @@ void MQTT::onReceive(char *topic, byte *payload, size_t length)
|
|||
p->channel = json["channel"]->AsNumber();
|
||||
if (json.find("to") != json.end() && json["to"]->IsNumber())
|
||||
p->to = json["to"]->AsNumber();
|
||||
if (json.find("hopLimit") != json.end() && json["hopLimit"]->IsNumber())
|
||||
p->hop_limit = json["hopLimit"]->AsNumber();
|
||||
p->decoded.payload.size =
|
||||
pb_encode_to_bytes(p->decoded.payload.bytes, sizeof(p->decoded.payload.bytes),
|
||||
&meshtastic_Position_msg, &pos); // make the Data protobuf from position
|
||||
|
@ -548,7 +552,10 @@ void MQTT::perhapsReportToMap()
|
|||
} else {
|
||||
if (map_position_precision == 0 || (localPosition.latitude_i == 0 && localPosition.longitude_i == 0)) {
|
||||
last_report_to_map = millis();
|
||||
LOG_WARN("MQTT Map reporting is enabled, but precision is 0 or no position available.\n");
|
||||
if (map_position_precision == 0)
|
||||
LOG_WARN("MQTT Map reporting is enabled, but precision is 0\n");
|
||||
if (localPosition.latitude_i == 0 && localPosition.longitude_i == 0)
|
||||
LOG_WARN("MQTT Map reporting is enabled, but no position available.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -904,6 +911,7 @@ bool MQTT::isValidJsonEnvelope(JSONObject &json)
|
|||
{
|
||||
// if "sender" is provided, avoid processing packets we uplinked
|
||||
return (json.find("sender") != json.end() ? (json["sender"]->AsString().compare(owner.id) != 0) : true) &&
|
||||
(json.find("hopLimit") != json.end() ? json["hopLimit"]->IsNumber() : true) && // hop limit should be a number
|
||||
(json.find("from") != json.end()) && json["from"]->IsNumber() &&
|
||||
(json["from"]->AsNumber() == nodeDB->getNodeNum()) && // only accept message if the "from" is us
|
||||
(json.find("type") != json.end()) && json["type"]->IsString() && // should specify a type
|
||||
|
|
|
@ -136,6 +136,7 @@ void portduinoSetup()
|
|||
settingsMap[use_sx1262] = false;
|
||||
settingsMap[use_rf95] = false;
|
||||
settingsMap[use_sx1280] = false;
|
||||
settingsMap[use_sx1268] = false;
|
||||
|
||||
if (yamlConfig["Lora"]["Module"] && yamlConfig["Lora"]["Module"].as<std::string>("") == "sx1262") {
|
||||
settingsMap[use_sx1262] = true;
|
||||
|
@ -143,6 +144,8 @@ void portduinoSetup()
|
|||
settingsMap[use_rf95] = true;
|
||||
} else if (yamlConfig["Lora"]["Module"] && yamlConfig["Lora"]["Module"].as<std::string>("") == "sx1280") {
|
||||
settingsMap[use_sx1280] = true;
|
||||
} else if (yamlConfig["Lora"]["Module"] && yamlConfig["Lora"]["Module"].as<std::string>("") == "sx1268") {
|
||||
settingsMap[use_sx1268] = true;
|
||||
}
|
||||
settingsMap[dio2_as_rf_switch] = yamlConfig["Lora"]["DIO2_AS_RF_SWITCH"].as<bool>(false);
|
||||
settingsMap[dio3_tcxo_voltage] = yamlConfig["Lora"]["DIO3_TCXO_VOLTAGE"].as<bool>(false);
|
||||
|
|
|
@ -13,6 +13,7 @@ enum configNames {
|
|||
dio3_tcxo_voltage,
|
||||
use_rf95,
|
||||
use_sx1280,
|
||||
use_sx1268,
|
||||
user,
|
||||
gpiochip,
|
||||
spidev,
|
||||
|
|
|
@ -1,24 +1,16 @@
|
|||
#define I2C_SDA 1
|
||||
#define I2C_SCL 0
|
||||
|
||||
#define BUTTON_PIN 9
|
||||
#define BUTTON_NEED_PULLUP
|
||||
|
||||
// LED flashes brighter
|
||||
// LED pin on HT-DEV-ESP_V2 and HT-DEV-ESP_V3
|
||||
// https://resource.heltec.cn/download/HT-CT62/HT-CT62_Reference_Design.pdf
|
||||
#define LED_PIN 18 // LED
|
||||
#define LED_INVERTED 1
|
||||
// https://resource.heltec.cn/download/HT-DEV-ESP/HT-DEV-ESP_V3_Sch.pdf
|
||||
#define LED_PIN 2 // LED
|
||||
#define LED_INVERTED 0
|
||||
|
||||
#define HAS_SCREEN 1
|
||||
#define HAS_SCREEN 0
|
||||
#define HAS_GPS 0
|
||||
#undef GPS_RX_PIN
|
||||
#undef GPS_TX_PIN
|
||||
|
||||
#undef LORA_SCK
|
||||
#undef LORA_MISO
|
||||
#undef LORA_MOSI
|
||||
#undef LORA_CS
|
||||
|
||||
#define USE_SX1262
|
||||
#define LORA_SCK 10
|
||||
#define LORA_MISO 6
|
||||
|
|
|
@ -48,7 +48,7 @@
|
|||
#undef GPS_RX_PIN
|
||||
#undef GPS_TX_PIN
|
||||
|
||||
#define HAS_SDCARD 1
|
||||
// #define HAS_SDCARD 1 // causes hang if defined
|
||||
#define SDCARD_CS 43
|
||||
|
||||
#define LED_PIN 13 // the red part of the RGB LED
|
||||
|
|
|
@ -181,6 +181,7 @@ static const uint8_t SCL = PIN_WIRE_SCL;
|
|||
#define BAT_READ \
|
||||
14 // P0_14 = 14 Reads battery voltage from divider on signal board. (PIN_VBAT is reading voltage divider on XIAO and is
|
||||
// program pin 32 / or P0.31)
|
||||
#define BATTERY_SENSE_RESOLUTION_BITS 10
|
||||
#define CHARGE_LED 23 // P0_17 = 17 D23 YELLOW CHARGE LED
|
||||
#define HICHG 22 // P0_13 = 13 D22 Charge-select pin for Lipo for 100 mA instead of default 50mA charge
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
[VERSION]
|
||||
major = 2
|
||||
minor = 3
|
||||
build = 7
|
||||
build = 8
|
||||
|
|
Ładowanie…
Reference in New Issue