mirror of
https://github.com/meshtastic/firmware.git
synced 2025-06-08 14:12:05 +00:00
Compare commits
13 Commits
a051003490
...
01b3c7017e
Author | SHA1 | Date | |
---|---|---|---|
![]() |
01b3c7017e | ||
![]() |
46c7d74760 | ||
![]() |
15d2ae17f8 | ||
![]() |
91579c4650 | ||
![]() |
79b710a108 | ||
![]() |
ba296db701 | ||
![]() |
f084a8a11d | ||
![]() |
37857941bf | ||
![]() |
d544b41ab7 | ||
![]() |
8c53ce82f2 | ||
![]() |
7ee95f2a0c | ||
![]() |
65b50babee | ||
![]() |
3c30821337 |
@ -9,7 +9,7 @@ plugins:
|
|||||||
lint:
|
lint:
|
||||||
enabled:
|
enabled:
|
||||||
- checkov@3.2.436
|
- checkov@3.2.436
|
||||||
- renovate@40.41.0
|
- renovate@40.42.2
|
||||||
- prettier@3.5.3
|
- prettier@3.5.3
|
||||||
- trufflehog@3.88.35
|
- trufflehog@3.88.35
|
||||||
- yamllint@1.37.1
|
- yamllint@1.37.1
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit 24c7a3d287a4bd269ce191827e5dabd8ce8f57a7
|
Subproject commit db60f07ac298b6161ca553b3868b542cceadcac4
|
94
src/gps/FakeUART.cpp
Normal file
94
src/gps/FakeUART.cpp
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
#include "FakeUART.h"
|
||||||
|
|
||||||
|
#ifdef SENSECAP_INDICATOR
|
||||||
|
|
||||||
|
FakeUART::FakeUART() {}
|
||||||
|
|
||||||
|
void FakeUART::begin(unsigned long baud, uint32_t config, int8_t rxPin, int8_t txPin, bool invert, unsigned long timeout_ms,
|
||||||
|
uint8_t rxfifo_full_thrhd)
|
||||||
|
{
|
||||||
|
baudrate = baud;
|
||||||
|
FakeBuf.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FakeUART::end()
|
||||||
|
{
|
||||||
|
FakeBuf.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
int FakeUART::available()
|
||||||
|
{
|
||||||
|
return FakeBuf.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
int FakeUART::peek()
|
||||||
|
{
|
||||||
|
unsigned char ret;
|
||||||
|
if (FakeBuf.peek(ret))
|
||||||
|
return ret;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int FakeUART::read()
|
||||||
|
{
|
||||||
|
unsigned char ret;
|
||||||
|
if (FakeBuf.pop(ret))
|
||||||
|
return ret;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FakeUART::flush()
|
||||||
|
{
|
||||||
|
FakeBuf.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t FakeUART::baudRate()
|
||||||
|
{
|
||||||
|
return baudrate;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FakeUART::updateBaudRate(unsigned long speed)
|
||||||
|
{
|
||||||
|
baudrate = speed;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t FakeUART::setRxBufferSize(size_t size)
|
||||||
|
{
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t FakeUART::write(const char *buffer)
|
||||||
|
{
|
||||||
|
return write((char *)buffer, strlen(buffer));
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t FakeUART::write(uint8_t *buffer, size_t size)
|
||||||
|
{
|
||||||
|
return write((char *)buffer, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t FakeUART::write(char *buffer, size_t size)
|
||||||
|
{
|
||||||
|
meshtastic_InterdeviceMessage message = meshtastic_InterdeviceMessage_init_zero;
|
||||||
|
if (size > sizeof(message.data.nmea)) {
|
||||||
|
size = sizeof(message.data.nmea); // Truncate if buffer is too large
|
||||||
|
}
|
||||||
|
memcpy(message.data.nmea, buffer, size);
|
||||||
|
sensecapIndicator.send_uplink(message);
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t FakeUART::stuff_buffer(const char *buffer, size_t size)
|
||||||
|
{
|
||||||
|
// push buffer in a loop to FakeBuf
|
||||||
|
for (size_t i = 0; i < size; i++) {
|
||||||
|
if (!FakeBuf.push(buffer[i])) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
FakeUART *FakeSerial;
|
||||||
|
|
||||||
|
#endif
|
44
src/gps/FakeUART.h
Normal file
44
src/gps/FakeUART.h
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifndef FAKEUART_H
|
||||||
|
#define FAKEUART_H
|
||||||
|
|
||||||
|
#ifdef SENSECAP_INDICATOR
|
||||||
|
|
||||||
|
#include "../IndicatorSerial.h"
|
||||||
|
#include <RingBuf.h>
|
||||||
|
#include <Stream.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
|
||||||
|
class FakeUART : public Stream
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FakeUART();
|
||||||
|
|
||||||
|
void begin(unsigned long baud, uint32_t config = 0x800001c, int8_t rxPin = -1, int8_t txPin = -1, bool invert = false,
|
||||||
|
unsigned long timeout_ms = 20000UL, uint8_t rxfifo_full_thrhd = 112);
|
||||||
|
void end();
|
||||||
|
int available();
|
||||||
|
int peek();
|
||||||
|
int read();
|
||||||
|
void flush();
|
||||||
|
uint32_t baudRate();
|
||||||
|
void updateBaudRate(unsigned long speed);
|
||||||
|
size_t setRxBufferSize(size_t size);
|
||||||
|
size_t write(const char *buffer);
|
||||||
|
size_t write(char *buffer, size_t size);
|
||||||
|
size_t write(uint8_t *buffer, size_t size);
|
||||||
|
|
||||||
|
size_t stuff_buffer(const char *buffer, size_t size);
|
||||||
|
virtual size_t write(uint8_t c) { return write(&c, 1); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
unsigned long baudrate = 115200;
|
||||||
|
RingBuf<unsigned char, 2048> FakeBuf;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern FakeUART *FakeSerial;
|
||||||
|
|
||||||
|
#endif // SENSECAP_INDICATOR
|
||||||
|
|
||||||
|
#endif // FAKEUART_H
|
@ -40,7 +40,9 @@ template <typename T, std::size_t N> std::size_t array_count(const T (&)[N])
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if defined(NRF52840_XXAA) || defined(NRF52833_XXAA) || defined(ARCH_ESP32) || defined(ARCH_PORTDUINO)
|
#if defined(NRF52840_XXAA) || defined(NRF52833_XXAA) || defined(ARCH_ESP32) || defined(ARCH_PORTDUINO)
|
||||||
#if defined(RAK2560)
|
#if defined(SENSECAP_INDICATOR)
|
||||||
|
FakeUART *GPS::_serial_gps = nullptr;
|
||||||
|
#elif defined(RAK2560)
|
||||||
HardwareSerial *GPS::_serial_gps = &Serial2;
|
HardwareSerial *GPS::_serial_gps = &Serial2;
|
||||||
#else
|
#else
|
||||||
HardwareSerial *GPS::_serial_gps = &Serial1;
|
HardwareSerial *GPS::_serial_gps = &Serial1;
|
||||||
|
@ -11,6 +11,10 @@
|
|||||||
#include "input/UpDownInterruptImpl1.h"
|
#include "input/UpDownInterruptImpl1.h"
|
||||||
#include "modules/PositionModule.h"
|
#include "modules/PositionModule.h"
|
||||||
|
|
||||||
|
#ifdef SENSECAP_INDICATOR
|
||||||
|
#include "FakeUART.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
// Allow defining the polarity of the ENABLE output. default is active high
|
// Allow defining the polarity of the ENABLE output. default is active high
|
||||||
#ifndef GPS_EN_ACTIVE
|
#ifndef GPS_EN_ACTIVE
|
||||||
#define GPS_EN_ACTIVE 1
|
#define GPS_EN_ACTIVE 1
|
||||||
@ -188,7 +192,9 @@ class GPS : private concurrency::OSThread
|
|||||||
CallbackObserver<GPS, void *> notifyDeepSleepObserver = CallbackObserver<GPS, void *>(this, &GPS::prepareDeepSleep);
|
CallbackObserver<GPS, void *> notifyDeepSleepObserver = CallbackObserver<GPS, void *>(this, &GPS::prepareDeepSleep);
|
||||||
|
|
||||||
/** If !NULL we will use this serial port to construct our GPS */
|
/** If !NULL we will use this serial port to construct our GPS */
|
||||||
#if defined(ARCH_RP2040)
|
#if defined(SENSECAP_INDICATOR)
|
||||||
|
static FakeUART *_serial_gps;
|
||||||
|
#elif defined(ARCH_RP2040)
|
||||||
static SerialUART *_serial_gps;
|
static SerialUART *_serial_gps;
|
||||||
#else
|
#else
|
||||||
static HardwareSerial *_serial_gps;
|
static HardwareSerial *_serial_gps;
|
||||||
|
@ -5,7 +5,7 @@ E-Ink display driver
|
|||||||
- Manufacturer: DKE
|
- Manufacturer: DKE
|
||||||
- Size: 2.13 inch
|
- Size: 2.13 inch
|
||||||
- Resolution: 122px x 250px
|
- Resolution: 122px x 250px
|
||||||
- Flex connector marking: FPC-7528B
|
- Flex connector marking (not a unique identifier): FPC-7528B
|
||||||
|
|
||||||
Note: this is from an older generation of DKE panels, which still used Solomon Systech controller ICs.
|
Note: this is from an older generation of DKE panels, which still used Solomon Systech controller ICs.
|
||||||
DKE's website suggests that the latest DEPG0213BN displays may use Fitipower controllers instead.
|
DKE's website suggests that the latest DEPG0213BN displays may use Fitipower controllers instead.
|
||||||
|
@ -5,7 +5,7 @@ E-Ink display driver
|
|||||||
- Manufacturer: DKE
|
- Manufacturer: DKE
|
||||||
- Size: 2.9 inch
|
- Size: 2.9 inch
|
||||||
- Resolution: 128px x 296px
|
- Resolution: 128px x 296px
|
||||||
- Flex connector marking: FPC-7519 rev.b
|
- Flex connector marking (not a unique identifier): FPC-7519 rev.b
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ E-Ink display driver
|
|||||||
- Manufacturer: Goodisplay
|
- Manufacturer: Goodisplay
|
||||||
- Size: 1.54 inch
|
- Size: 1.54 inch
|
||||||
- Resolution: 200px x 200px
|
- Resolution: 200px x 200px
|
||||||
- Flex connector marking: FPC-B001
|
- Flex connector marking (not a unique identifier): FPC-B001
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -5,7 +5,9 @@ E-Ink display driver
|
|||||||
- Manufacturer: Goodisplay
|
- Manufacturer: Goodisplay
|
||||||
- Size: 2.13 inch
|
- Size: 2.13 inch
|
||||||
- Resolution: 250px x 122px
|
- Resolution: 250px x 122px
|
||||||
- Flex connector marking: FPC-A002
|
- Flex connector marking (not a unique identifier):
|
||||||
|
- FPC-A002
|
||||||
|
- FPC-A005 20.06.15 TRX
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ E-Ink display driver
|
|||||||
- Manufacturer: Holitech
|
- Manufacturer: Holitech
|
||||||
- Size: 4.2 inch
|
- Size: 4.2 inch
|
||||||
- Resolution: 400px x 300px
|
- Resolution: 400px x 300px
|
||||||
- Flex connector marking: HINK-E042A07-FPC-A1
|
- Flex connector marking (not a unique identifier): HINK-E042A07-FPC-A1
|
||||||
- Silver sticker with QR code, marked: HE042A87
|
- Silver sticker with QR code, marked: HE042A87
|
||||||
|
|
||||||
Note: as of Feb. 2025, these panels are used for "WeActStudio 4.2in B&W" display modules
|
Note: as of Feb. 2025, these panels are used for "WeActStudio 4.2in B&W" display modules
|
||||||
|
@ -5,7 +5,6 @@ E-Ink display driver
|
|||||||
- Manufacturer: WISEVAST
|
- Manufacturer: WISEVAST
|
||||||
- Size: 2.13 inch
|
- Size: 2.13 inch
|
||||||
- Resolution: 122px x 255px
|
- Resolution: 122px x 255px
|
||||||
- Flex connector marking: Soldering connector, no connector is needed
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ E-Ink display driver
|
|||||||
- Manufacturer: Wisevast
|
- Manufacturer: Wisevast
|
||||||
- Size: 2.13 inch
|
- Size: 2.13 inch
|
||||||
- Resolution: 122px x 250px
|
- Resolution: 122px x 250px
|
||||||
- Flex connector marking: HINK-E0213A162-FPC-A0 (Hidden, printed on back-side)
|
- Flex connector marking (not a unique identifier): HINK-E0213A162-FPC-A0 (Hidden, printed on back-side)
|
||||||
|
|
||||||
Note: this display uses an uncommon controller IC, Fitipower JD79656.
|
Note: this display uses an uncommon controller IC, Fitipower JD79656.
|
||||||
It is implemented as a "one-off", directly inheriting the EInk base class, unlike SSD16XX displays.
|
It is implemented as a "one-off", directly inheriting the EInk base class, unlike SSD16XX displays.
|
||||||
|
59
src/graphics/niche/Drivers/EInk/ZJY128296_029EAAMFGN.cpp
Normal file
59
src/graphics/niche/Drivers/EInk/ZJY128296_029EAAMFGN.cpp
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
#include "./ZJY128296_029EAAMFGN.h"
|
||||||
|
|
||||||
|
#ifdef MESHTASTIC_INCLUDE_NICHE_GRAPHICS
|
||||||
|
|
||||||
|
using namespace NicheGraphics::Drivers;
|
||||||
|
|
||||||
|
// Map the display controller IC's output to the connected panel
|
||||||
|
void ZJY128296_029EAAMFGN::configScanning()
|
||||||
|
{
|
||||||
|
// "Driver output control"
|
||||||
|
// Scan gates from 0 to 295 (vertical resolution 296px)
|
||||||
|
sendCommand(0x01);
|
||||||
|
sendData(0x27); // Number of gates (295, bits 0-7)
|
||||||
|
sendData(0x01); // Number of gates (295, bit 8)
|
||||||
|
sendData(0x00); // (Do not invert scanning order)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Specify which information is used to control the sequence of voltages applied to move the pixels
|
||||||
|
// - For this display, configUpdateSequence() specifies that a suitable LUT will be loaded from
|
||||||
|
// the controller IC's OTP memory, when the update procedure begins.
|
||||||
|
void ZJY128296_029EAAMFGN::configWaveform()
|
||||||
|
{
|
||||||
|
sendCommand(0x3C); // Border waveform:
|
||||||
|
sendData(0x05); // Screen border should follow LUT1 waveform (actively drive pixels white)
|
||||||
|
|
||||||
|
sendCommand(0x18); // Temperature sensor:
|
||||||
|
sendData(0x80); // Use internal temperature sensor to select an appropriate refresh waveform
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZJY128296_029EAAMFGN::configUpdateSequence()
|
||||||
|
{
|
||||||
|
switch (updateType) {
|
||||||
|
case FAST:
|
||||||
|
sendCommand(0x22); // Set "update sequence"
|
||||||
|
sendData(0xFF); // Will load LUT from OTP memory, Display mode 2 "differential refresh"
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FULL:
|
||||||
|
default:
|
||||||
|
sendCommand(0x22); // Set "update sequence"
|
||||||
|
sendData(0xF7); // Will load LUT from OTP memory
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Once the refresh operation has been started,
|
||||||
|
// begin periodically polling the display to check for completion, using the normal Meshtastic threading code
|
||||||
|
// Only used when refresh is "async"
|
||||||
|
void ZJY128296_029EAAMFGN::detachFromUpdate()
|
||||||
|
{
|
||||||
|
switch (updateType) {
|
||||||
|
case FAST:
|
||||||
|
return beginPolling(50, 300); // At least 300ms for fast refresh
|
||||||
|
case FULL:
|
||||||
|
default:
|
||||||
|
return beginPolling(100, 2000); // At least 2 seconds for full refresh
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // MESHTASTIC_INCLUDE_NICHE_GRAPHICS
|
44
src/graphics/niche/Drivers/EInk/ZJY128296_029EAAMFGN.h
Normal file
44
src/graphics/niche/Drivers/EInk/ZJY128296_029EAAMFGN.h
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
E-Ink display driver
|
||||||
|
- ZJY128296-029EAAMFGN
|
||||||
|
- Manufacturer: Zhongjingyuan
|
||||||
|
- Size: 2.9 inch
|
||||||
|
- Resolution: 128px x 296px
|
||||||
|
- Flex connector label (not a unique identifier): FPC-A005 20.06.15 TRX
|
||||||
|
|
||||||
|
Note: as of Feb. 2025, these panels are used for "WeActStudio 2.9in B&W" display modules
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifdef MESHTASTIC_INCLUDE_NICHE_GRAPHICS
|
||||||
|
|
||||||
|
#include "configuration.h"
|
||||||
|
|
||||||
|
#include "./SSD16XX.h"
|
||||||
|
|
||||||
|
namespace NicheGraphics::Drivers
|
||||||
|
{
|
||||||
|
class ZJY128296_029EAAMFGN : public SSD16XX
|
||||||
|
{
|
||||||
|
// Display properties
|
||||||
|
private:
|
||||||
|
static constexpr uint32_t width = 128;
|
||||||
|
static constexpr uint32_t height = 296;
|
||||||
|
static constexpr UpdateTypes supported = (UpdateTypes)(FULL | FAST);
|
||||||
|
|
||||||
|
public:
|
||||||
|
ZJY128296_029EAAMFGN() : SSD16XX(width, height, supported) {}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void configScanning() override;
|
||||||
|
void configWaveform() override;
|
||||||
|
void configUpdateSequence() override;
|
||||||
|
void detachFromUpdate() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace NicheGraphics::Drivers
|
||||||
|
|
||||||
|
#endif // MESHTASTIC_INCLUDE_NICHE_GRAPHICS
|
13
src/main.cpp
13
src/main.cpp
@ -22,6 +22,10 @@
|
|||||||
#include "error.h"
|
#include "error.h"
|
||||||
#include "power.h"
|
#include "power.h"
|
||||||
|
|
||||||
|
#ifdef SENSECAP_INDICATOR // on the indicator run the additional serial port for the RP2040
|
||||||
|
#include "IndicatorSerial.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#if !MESHTASTIC_EXCLUDE_I2C
|
#if !MESHTASTIC_EXCLUDE_I2C
|
||||||
#include "detect/ScanI2CTwoWire.h"
|
#include "detect/ScanI2CTwoWire.h"
|
||||||
#include <Wire.h>
|
#include <Wire.h>
|
||||||
@ -337,12 +341,12 @@ void setup()
|
|||||||
|
|
||||||
#ifdef LED_POWER
|
#ifdef LED_POWER
|
||||||
pinMode(LED_POWER, OUTPUT);
|
pinMode(LED_POWER, OUTPUT);
|
||||||
digitalWrite(LED_POWER, HIGH);
|
digitalWrite(LED_POWER, LED_STATE_ON);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USER_LED
|
#ifdef USER_LED
|
||||||
pinMode(USER_LED, OUTPUT);
|
pinMode(USER_LED, OUTPUT);
|
||||||
digitalWrite(USER_LED, LOW);
|
digitalWrite(USER_LED, HIGH ^ LED_STATE_ON);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(T_DECK)
|
#if defined(T_DECK)
|
||||||
@ -771,6 +775,11 @@ void setup()
|
|||||||
buttonThread = new ButtonThread();
|
buttonThread = new ButtonThread();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// If we have an indicator, start process to service secondary port
|
||||||
|
#ifdef SENSECAP_INDICATOR
|
||||||
|
sensecapIndicator.begin(Serial2);
|
||||||
|
#endif
|
||||||
|
|
||||||
// only play start melody when role is not tracker or sensor
|
// only play start melody when role is not tracker or sensor
|
||||||
if (config.power.is_power_saving == true &&
|
if (config.power.is_power_saving == true &&
|
||||||
IS_ONE_OF(config.device.role, meshtastic_Config_DeviceConfig_Role_TRACKER,
|
IS_ONE_OF(config.device.role, meshtastic_Config_DeviceConfig_Role_TRACKER,
|
||||||
|
151
src/mesh/IndicatorSerial.cpp
Normal file
151
src/mesh/IndicatorSerial.cpp
Normal file
@ -0,0 +1,151 @@
|
|||||||
|
#ifdef SENSECAP_INDICATOR
|
||||||
|
|
||||||
|
#include "IndicatorSerial.h"
|
||||||
|
#include "../modules/Telemetry/Sensor/IndicatorSensor.h"
|
||||||
|
#include "FakeUART.h"
|
||||||
|
#include <HardwareSerial.h>
|
||||||
|
#include <pb_decode.h>
|
||||||
|
#include <pb_encode.h>
|
||||||
|
|
||||||
|
extern IndicatorSensor indicatorSensor;
|
||||||
|
|
||||||
|
SensecapIndicator sensecapIndicator;
|
||||||
|
|
||||||
|
SensecapIndicator::SensecapIndicator() : OSThread("SensecapIndicator") {}
|
||||||
|
|
||||||
|
void SensecapIndicator::begin(HardwareSerial serial)
|
||||||
|
{
|
||||||
|
if (!running) {
|
||||||
|
_serial = serial;
|
||||||
|
_serial.setRxBufferSize(PB_BUFSIZE);
|
||||||
|
_serial.begin(115200);
|
||||||
|
running = true;
|
||||||
|
LOG_DEBUG("Start communication thread");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t SensecapIndicator::runOnce()
|
||||||
|
{
|
||||||
|
if (running) {
|
||||||
|
size_t bytes_read = 0;
|
||||||
|
|
||||||
|
// See if there are any more bytes to add to our buffer.
|
||||||
|
size_t space_left = PB_BUFSIZE - pb_rx_size;
|
||||||
|
|
||||||
|
bytes_read = serial_check((char *)pb_rx_buf + pb_rx_size, space_left);
|
||||||
|
|
||||||
|
pb_rx_size += bytes_read;
|
||||||
|
check_packet();
|
||||||
|
return (10);
|
||||||
|
} else {
|
||||||
|
LOG_DEBUG("Not running");
|
||||||
|
return (1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SensecapIndicator::send_uplink(meshtastic_InterdeviceMessage message)
|
||||||
|
{
|
||||||
|
pb_tx_buf[0] = MT_MAGIC_0;
|
||||||
|
pb_tx_buf[1] = MT_MAGIC_1;
|
||||||
|
|
||||||
|
pb_ostream_t stream = pb_ostream_from_buffer(pb_tx_buf + MT_HEADER_SIZE, PB_BUFSIZE);
|
||||||
|
if (!pb_encode(&stream, meshtastic_InterdeviceMessage_fields, &message)) {
|
||||||
|
LOG_DEBUG("pb_encode failed");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store the payload length in the header
|
||||||
|
pb_tx_buf[2] = stream.bytes_written / 256;
|
||||||
|
pb_tx_buf[3] = stream.bytes_written % 256;
|
||||||
|
|
||||||
|
bool rv = send((const char *)pb_tx_buf, MT_HEADER_SIZE + stream.bytes_written);
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t SensecapIndicator::serial_check(char *buf, size_t space_left)
|
||||||
|
{
|
||||||
|
size_t bytes_read = 0;
|
||||||
|
while (_serial.available()) {
|
||||||
|
char c = _serial.read();
|
||||||
|
*buf++ = c;
|
||||||
|
if (++bytes_read >= space_left) {
|
||||||
|
LOG_DEBUG("Serial overflow: %d > %d", bytes_read, space_left);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return bytes_read;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SensecapIndicator::check_packet()
|
||||||
|
{
|
||||||
|
if (pb_rx_size < MT_HEADER_SIZE) {
|
||||||
|
// We don't even have a header yet
|
||||||
|
delay(NO_NEWS_PAUSE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pb_rx_buf[0] != MT_MAGIC_0 || pb_rx_buf[1] != MT_MAGIC_1) {
|
||||||
|
LOG_DEBUG("Got bad magic");
|
||||||
|
memset(pb_rx_buf, 0, PB_BUFSIZE);
|
||||||
|
pb_rx_size = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t payload_len = pb_rx_buf[2] << 8 | pb_rx_buf[3];
|
||||||
|
if (payload_len > PB_BUFSIZE) {
|
||||||
|
LOG_DEBUG("Got packet claiming to be ridiculous length");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((size_t)(payload_len + 4) > pb_rx_size) {
|
||||||
|
delay(NO_NEWS_PAUSE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We have a complete packet, handle it
|
||||||
|
handle_packet(payload_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SensecapIndicator::handle_packet(size_t payload_len)
|
||||||
|
{
|
||||||
|
meshtastic_InterdeviceMessage message = meshtastic_InterdeviceMessage_init_zero;
|
||||||
|
|
||||||
|
// Decode the protobuf and shift forward any remaining bytes in the buffer
|
||||||
|
// (which, if present, belong to the packet that we're going to process on the
|
||||||
|
// next loop)
|
||||||
|
pb_istream_t stream = pb_istream_from_buffer(pb_rx_buf + MT_HEADER_SIZE, payload_len);
|
||||||
|
bool status = pb_decode(&stream, meshtastic_InterdeviceMessage_fields, &message);
|
||||||
|
memmove(pb_rx_buf, pb_rx_buf + MT_HEADER_SIZE + payload_len, PB_BUFSIZE - MT_HEADER_SIZE - payload_len);
|
||||||
|
pb_rx_size -= MT_HEADER_SIZE + payload_len;
|
||||||
|
|
||||||
|
if (!status) {
|
||||||
|
LOG_DEBUG("Decoding failed");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
switch (message.which_data) {
|
||||||
|
case meshtastic_InterdeviceMessage_sensor_tag:
|
||||||
|
indicatorSensor.stuff_buffer(message.data.sensor);
|
||||||
|
return true;
|
||||||
|
break;
|
||||||
|
case meshtastic_InterdeviceMessage_nmea_tag:
|
||||||
|
// send String to NMEA processing
|
||||||
|
FakeSerial->stuff_buffer(message.data.nmea, strlen(message.data.nmea));
|
||||||
|
return true;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// the other messages really only flow downstream
|
||||||
|
LOG_DEBUG("Got a message of unexpected type");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SensecapIndicator::send(const char *buf, size_t len)
|
||||||
|
{
|
||||||
|
size_t wrote = _serial.write(buf, len);
|
||||||
|
if (wrote == len)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // SENSECAP_INDICATOR
|
48
src/mesh/IndicatorSerial.h
Normal file
48
src/mesh/IndicatorSerial.h
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifndef INDICATORSERIAL_H
|
||||||
|
#define INDICATORSERIAL_H
|
||||||
|
|
||||||
|
#ifdef SENSECAP_INDICATOR
|
||||||
|
|
||||||
|
#include "concurrency/OSThread.h"
|
||||||
|
#include "configuration.h"
|
||||||
|
|
||||||
|
#include "mesh/generated/meshtastic/interdevice.pb.h"
|
||||||
|
|
||||||
|
// Magic number at the start of all MT packets
|
||||||
|
#define MT_MAGIC_0 0x94
|
||||||
|
#define MT_MAGIC_1 0xc3
|
||||||
|
|
||||||
|
// The header is the magic number plus a 16-bit payload-length field
|
||||||
|
#define MT_HEADER_SIZE 4
|
||||||
|
|
||||||
|
// Wait this many msec if there's nothing new on the channel
|
||||||
|
#define NO_NEWS_PAUSE 25
|
||||||
|
|
||||||
|
#define PB_BUFSIZE meshtastic_InterdeviceMessage_size + MT_HEADER_SIZE
|
||||||
|
|
||||||
|
class SensecapIndicator : public concurrency::OSThread
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SensecapIndicator();
|
||||||
|
void begin(HardwareSerial serial);
|
||||||
|
int32_t runOnce() override;
|
||||||
|
bool send_uplink(meshtastic_InterdeviceMessage message);
|
||||||
|
|
||||||
|
private:
|
||||||
|
pb_byte_t pb_tx_buf[PB_BUFSIZE];
|
||||||
|
pb_byte_t pb_rx_buf[PB_BUFSIZE];
|
||||||
|
size_t pb_rx_size = 0; // Number of bytes currently in the buffer
|
||||||
|
HardwareSerial _serial = Serial2;
|
||||||
|
bool running = false;
|
||||||
|
size_t serial_check(char *buf, size_t space_left);
|
||||||
|
void check_packet();
|
||||||
|
bool handle_packet(size_t payload_len);
|
||||||
|
bool send(const char *buf, size_t len);
|
||||||
|
};
|
||||||
|
|
||||||
|
extern SensecapIndicator sensecapIndicator;
|
||||||
|
|
||||||
|
#endif // SENSECAP_INDICATOR
|
||||||
|
#endif // INDICATORSERIAL_H
|
@ -65,6 +65,8 @@ PB_BIND(meshtastic_Config_SessionkeyConfig, meshtastic_Config_SessionkeyConfig,
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -88,6 +88,23 @@ typedef enum _meshtastic_Config_DeviceConfig_RebroadcastMode {
|
|||||||
meshtastic_Config_DeviceConfig_RebroadcastMode_CORE_PORTNUMS_ONLY = 5
|
meshtastic_Config_DeviceConfig_RebroadcastMode_CORE_PORTNUMS_ONLY = 5
|
||||||
} meshtastic_Config_DeviceConfig_RebroadcastMode;
|
} meshtastic_Config_DeviceConfig_RebroadcastMode;
|
||||||
|
|
||||||
|
/* Defines buzzer behavior for audio feedback */
|
||||||
|
typedef enum _meshtastic_Config_DeviceConfig_BuzzerMode {
|
||||||
|
/* Default behavior.
|
||||||
|
Buzzer is enabled for all audio feedback including button presses and alerts. */
|
||||||
|
meshtastic_Config_DeviceConfig_BuzzerMode_ALL_ENABLED = 0,
|
||||||
|
/* Disabled.
|
||||||
|
All buzzer audio feedback is disabled. */
|
||||||
|
meshtastic_Config_DeviceConfig_BuzzerMode_DISABLED = 1,
|
||||||
|
/* Notifications Only.
|
||||||
|
Buzzer is enabled only for notifications and alerts, but not for button presses.
|
||||||
|
External notification config determines the specifics of the notification behavior. */
|
||||||
|
meshtastic_Config_DeviceConfig_BuzzerMode_NOTIFICATIONS_ONLY = 2,
|
||||||
|
/* Non-notification system buzzer tones only.
|
||||||
|
Buzzer is enabled only for non-notification tones such as button presses, startup, shutdown, but not for alerts. */
|
||||||
|
meshtastic_Config_DeviceConfig_BuzzerMode_SYSTEM_ONLY = 3
|
||||||
|
} meshtastic_Config_DeviceConfig_BuzzerMode;
|
||||||
|
|
||||||
/* Bit field of boolean configuration options, indicating which optional
|
/* Bit field of boolean configuration options, indicating which optional
|
||||||
fields to include when assembling POSITION messages.
|
fields to include when assembling POSITION messages.
|
||||||
Longitude, latitude, altitude, speed, heading, and DOP
|
Longitude, latitude, altitude, speed, heading, and DOP
|
||||||
@ -335,6 +352,9 @@ typedef struct _meshtastic_Config_DeviceConfig {
|
|||||||
char tzdef[65];
|
char tzdef[65];
|
||||||
/* If true, disable the default blinking LED (LED_PIN) behavior on the device */
|
/* If true, disable the default blinking LED (LED_PIN) behavior on the device */
|
||||||
bool led_heartbeat_disabled;
|
bool led_heartbeat_disabled;
|
||||||
|
/* Controls buzzer behavior for audio feedback
|
||||||
|
Defaults to ENABLED */
|
||||||
|
meshtastic_Config_DeviceConfig_BuzzerMode buzzer_mode;
|
||||||
} meshtastic_Config_DeviceConfig;
|
} meshtastic_Config_DeviceConfig;
|
||||||
|
|
||||||
/* Position Config */
|
/* Position Config */
|
||||||
@ -618,6 +638,10 @@ extern "C" {
|
|||||||
#define _meshtastic_Config_DeviceConfig_RebroadcastMode_MAX meshtastic_Config_DeviceConfig_RebroadcastMode_CORE_PORTNUMS_ONLY
|
#define _meshtastic_Config_DeviceConfig_RebroadcastMode_MAX meshtastic_Config_DeviceConfig_RebroadcastMode_CORE_PORTNUMS_ONLY
|
||||||
#define _meshtastic_Config_DeviceConfig_RebroadcastMode_ARRAYSIZE ((meshtastic_Config_DeviceConfig_RebroadcastMode)(meshtastic_Config_DeviceConfig_RebroadcastMode_CORE_PORTNUMS_ONLY+1))
|
#define _meshtastic_Config_DeviceConfig_RebroadcastMode_ARRAYSIZE ((meshtastic_Config_DeviceConfig_RebroadcastMode)(meshtastic_Config_DeviceConfig_RebroadcastMode_CORE_PORTNUMS_ONLY+1))
|
||||||
|
|
||||||
|
#define _meshtastic_Config_DeviceConfig_BuzzerMode_MIN meshtastic_Config_DeviceConfig_BuzzerMode_ALL_ENABLED
|
||||||
|
#define _meshtastic_Config_DeviceConfig_BuzzerMode_MAX meshtastic_Config_DeviceConfig_BuzzerMode_SYSTEM_ONLY
|
||||||
|
#define _meshtastic_Config_DeviceConfig_BuzzerMode_ARRAYSIZE ((meshtastic_Config_DeviceConfig_BuzzerMode)(meshtastic_Config_DeviceConfig_BuzzerMode_SYSTEM_ONLY+1))
|
||||||
|
|
||||||
#define _meshtastic_Config_PositionConfig_PositionFlags_MIN meshtastic_Config_PositionConfig_PositionFlags_UNSET
|
#define _meshtastic_Config_PositionConfig_PositionFlags_MIN meshtastic_Config_PositionConfig_PositionFlags_UNSET
|
||||||
#define _meshtastic_Config_PositionConfig_PositionFlags_MAX meshtastic_Config_PositionConfig_PositionFlags_SPEED
|
#define _meshtastic_Config_PositionConfig_PositionFlags_MAX meshtastic_Config_PositionConfig_PositionFlags_SPEED
|
||||||
#define _meshtastic_Config_PositionConfig_PositionFlags_ARRAYSIZE ((meshtastic_Config_PositionConfig_PositionFlags)(meshtastic_Config_PositionConfig_PositionFlags_SPEED+1))
|
#define _meshtastic_Config_PositionConfig_PositionFlags_ARRAYSIZE ((meshtastic_Config_PositionConfig_PositionFlags)(meshtastic_Config_PositionConfig_PositionFlags_SPEED+1))
|
||||||
@ -669,6 +693,7 @@ extern "C" {
|
|||||||
|
|
||||||
#define meshtastic_Config_DeviceConfig_role_ENUMTYPE meshtastic_Config_DeviceConfig_Role
|
#define meshtastic_Config_DeviceConfig_role_ENUMTYPE meshtastic_Config_DeviceConfig_Role
|
||||||
#define meshtastic_Config_DeviceConfig_rebroadcast_mode_ENUMTYPE meshtastic_Config_DeviceConfig_RebroadcastMode
|
#define meshtastic_Config_DeviceConfig_rebroadcast_mode_ENUMTYPE meshtastic_Config_DeviceConfig_RebroadcastMode
|
||||||
|
#define meshtastic_Config_DeviceConfig_buzzer_mode_ENUMTYPE meshtastic_Config_DeviceConfig_BuzzerMode
|
||||||
|
|
||||||
#define meshtastic_Config_PositionConfig_gps_mode_ENUMTYPE meshtastic_Config_PositionConfig_GpsMode
|
#define meshtastic_Config_PositionConfig_gps_mode_ENUMTYPE meshtastic_Config_PositionConfig_GpsMode
|
||||||
|
|
||||||
@ -692,7 +717,7 @@ extern "C" {
|
|||||||
|
|
||||||
/* Initializer values for message structs */
|
/* Initializer values for message structs */
|
||||||
#define meshtastic_Config_init_default {0, {meshtastic_Config_DeviceConfig_init_default}}
|
#define meshtastic_Config_init_default {0, {meshtastic_Config_DeviceConfig_init_default}}
|
||||||
#define meshtastic_Config_DeviceConfig_init_default {_meshtastic_Config_DeviceConfig_Role_MIN, 0, 0, 0, _meshtastic_Config_DeviceConfig_RebroadcastMode_MIN, 0, 0, 0, 0, "", 0}
|
#define meshtastic_Config_DeviceConfig_init_default {_meshtastic_Config_DeviceConfig_Role_MIN, 0, 0, 0, _meshtastic_Config_DeviceConfig_RebroadcastMode_MIN, 0, 0, 0, 0, "", 0, _meshtastic_Config_DeviceConfig_BuzzerMode_MIN}
|
||||||
#define meshtastic_Config_PositionConfig_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _meshtastic_Config_PositionConfig_GpsMode_MIN}
|
#define meshtastic_Config_PositionConfig_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _meshtastic_Config_PositionConfig_GpsMode_MIN}
|
||||||
#define meshtastic_Config_PowerConfig_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0}
|
#define meshtastic_Config_PowerConfig_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||||
#define meshtastic_Config_NetworkConfig_init_default {0, "", "", "", 0, _meshtastic_Config_NetworkConfig_AddressMode_MIN, false, meshtastic_Config_NetworkConfig_IpV4Config_init_default, "", 0, 0}
|
#define meshtastic_Config_NetworkConfig_init_default {0, "", "", "", 0, _meshtastic_Config_NetworkConfig_AddressMode_MIN, false, meshtastic_Config_NetworkConfig_IpV4Config_init_default, "", 0, 0}
|
||||||
@ -703,7 +728,7 @@ extern "C" {
|
|||||||
#define meshtastic_Config_SecurityConfig_init_default {{0, {0}}, {0, {0}}, 0, {{0, {0}}, {0, {0}}, {0, {0}}}, 0, 0, 0, 0}
|
#define meshtastic_Config_SecurityConfig_init_default {{0, {0}}, {0, {0}}, 0, {{0, {0}}, {0, {0}}, {0, {0}}}, 0, 0, 0, 0}
|
||||||
#define meshtastic_Config_SessionkeyConfig_init_default {0}
|
#define meshtastic_Config_SessionkeyConfig_init_default {0}
|
||||||
#define meshtastic_Config_init_zero {0, {meshtastic_Config_DeviceConfig_init_zero}}
|
#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, _meshtastic_Config_DeviceConfig_RebroadcastMode_MIN, 0, 0, 0, 0, "", 0}
|
#define meshtastic_Config_DeviceConfig_init_zero {_meshtastic_Config_DeviceConfig_Role_MIN, 0, 0, 0, _meshtastic_Config_DeviceConfig_RebroadcastMode_MIN, 0, 0, 0, 0, "", 0, _meshtastic_Config_DeviceConfig_BuzzerMode_MIN}
|
||||||
#define meshtastic_Config_PositionConfig_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _meshtastic_Config_PositionConfig_GpsMode_MIN}
|
#define meshtastic_Config_PositionConfig_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _meshtastic_Config_PositionConfig_GpsMode_MIN}
|
||||||
#define meshtastic_Config_PowerConfig_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0}
|
#define meshtastic_Config_PowerConfig_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||||
#define meshtastic_Config_NetworkConfig_init_zero {0, "", "", "", 0, _meshtastic_Config_NetworkConfig_AddressMode_MIN, false, meshtastic_Config_NetworkConfig_IpV4Config_init_zero, "", 0, 0}
|
#define meshtastic_Config_NetworkConfig_init_zero {0, "", "", "", 0, _meshtastic_Config_NetworkConfig_AddressMode_MIN, false, meshtastic_Config_NetworkConfig_IpV4Config_init_zero, "", 0, 0}
|
||||||
@ -726,6 +751,7 @@ extern "C" {
|
|||||||
#define meshtastic_Config_DeviceConfig_disable_triple_click_tag 10
|
#define meshtastic_Config_DeviceConfig_disable_triple_click_tag 10
|
||||||
#define meshtastic_Config_DeviceConfig_tzdef_tag 11
|
#define meshtastic_Config_DeviceConfig_tzdef_tag 11
|
||||||
#define meshtastic_Config_DeviceConfig_led_heartbeat_disabled_tag 12
|
#define meshtastic_Config_DeviceConfig_led_heartbeat_disabled_tag 12
|
||||||
|
#define meshtastic_Config_DeviceConfig_buzzer_mode_tag 13
|
||||||
#define meshtastic_Config_PositionConfig_position_broadcast_secs_tag 1
|
#define meshtastic_Config_PositionConfig_position_broadcast_secs_tag 1
|
||||||
#define meshtastic_Config_PositionConfig_position_broadcast_smart_enabled_tag 2
|
#define meshtastic_Config_PositionConfig_position_broadcast_smart_enabled_tag 2
|
||||||
#define meshtastic_Config_PositionConfig_fixed_position_tag 3
|
#define meshtastic_Config_PositionConfig_fixed_position_tag 3
|
||||||
@ -849,7 +875,8 @@ X(a, STATIC, SINGULAR, BOOL, double_tap_as_button_press, 8) \
|
|||||||
X(a, STATIC, SINGULAR, BOOL, is_managed, 9) \
|
X(a, STATIC, SINGULAR, BOOL, is_managed, 9) \
|
||||||
X(a, STATIC, SINGULAR, BOOL, disable_triple_click, 10) \
|
X(a, STATIC, SINGULAR, BOOL, disable_triple_click, 10) \
|
||||||
X(a, STATIC, SINGULAR, STRING, tzdef, 11) \
|
X(a, STATIC, SINGULAR, STRING, tzdef, 11) \
|
||||||
X(a, STATIC, SINGULAR, BOOL, led_heartbeat_disabled, 12)
|
X(a, STATIC, SINGULAR, BOOL, led_heartbeat_disabled, 12) \
|
||||||
|
X(a, STATIC, SINGULAR, UENUM, buzzer_mode, 13)
|
||||||
#define meshtastic_Config_DeviceConfig_CALLBACK NULL
|
#define meshtastic_Config_DeviceConfig_CALLBACK NULL
|
||||||
#define meshtastic_Config_DeviceConfig_DEFAULT NULL
|
#define meshtastic_Config_DeviceConfig_DEFAULT NULL
|
||||||
|
|
||||||
@ -995,7 +1022,7 @@ extern const pb_msgdesc_t meshtastic_Config_SessionkeyConfig_msg;
|
|||||||
/* Maximum encoded size of messages (where known) */
|
/* Maximum encoded size of messages (where known) */
|
||||||
#define MESHTASTIC_MESHTASTIC_CONFIG_PB_H_MAX_SIZE meshtastic_Config_size
|
#define MESHTASTIC_MESHTASTIC_CONFIG_PB_H_MAX_SIZE meshtastic_Config_size
|
||||||
#define meshtastic_Config_BluetoothConfig_size 10
|
#define meshtastic_Config_BluetoothConfig_size 10
|
||||||
#define meshtastic_Config_DeviceConfig_size 98
|
#define meshtastic_Config_DeviceConfig_size 100
|
||||||
#define meshtastic_Config_DisplayConfig_size 32
|
#define meshtastic_Config_DisplayConfig_size 32
|
||||||
#define meshtastic_Config_LoRaConfig_size 85
|
#define meshtastic_Config_LoRaConfig_size 85
|
||||||
#define meshtastic_Config_NetworkConfig_IpV4Config_size 20
|
#define meshtastic_Config_NetworkConfig_IpV4Config_size 20
|
||||||
|
@ -55,6 +55,8 @@ typedef enum _meshtastic_Language {
|
|||||||
meshtastic_Language_SLOVENIAN = 15,
|
meshtastic_Language_SLOVENIAN = 15,
|
||||||
/* Ukrainian */
|
/* Ukrainian */
|
||||||
meshtastic_Language_UKRAINIAN = 16,
|
meshtastic_Language_UKRAINIAN = 16,
|
||||||
|
/* Bulgarian */
|
||||||
|
meshtastic_Language_BULGARIAN = 17,
|
||||||
/* Simplified Chinese (experimental) */
|
/* Simplified Chinese (experimental) */
|
||||||
meshtastic_Language_SIMPLIFIED_CHINESE = 30,
|
meshtastic_Language_SIMPLIFIED_CHINESE = 30,
|
||||||
/* Traditional Chinese (experimental) */
|
/* Traditional Chinese (experimental) */
|
||||||
|
@ -360,7 +360,7 @@ extern const pb_msgdesc_t meshtastic_BackupPreferences_msg;
|
|||||||
/* Maximum encoded size of messages (where known) */
|
/* Maximum encoded size of messages (where known) */
|
||||||
/* meshtastic_NodeDatabase_size depends on runtime parameters */
|
/* meshtastic_NodeDatabase_size depends on runtime parameters */
|
||||||
#define MESHTASTIC_MESHTASTIC_DEVICEONLY_PB_H_MAX_SIZE meshtastic_BackupPreferences_size
|
#define MESHTASTIC_MESHTASTIC_DEVICEONLY_PB_H_MAX_SIZE meshtastic_BackupPreferences_size
|
||||||
#define meshtastic_BackupPreferences_size 2269
|
#define meshtastic_BackupPreferences_size 2271
|
||||||
#define meshtastic_ChannelFile_size 718
|
#define meshtastic_ChannelFile_size 718
|
||||||
#define meshtastic_DeviceState_size 1722
|
#define meshtastic_DeviceState_size 1722
|
||||||
#define meshtastic_NodeInfoLite_size 196
|
#define meshtastic_NodeInfoLite_size 196
|
||||||
|
@ -187,7 +187,7 @@ extern const pb_msgdesc_t meshtastic_LocalModuleConfig_msg;
|
|||||||
|
|
||||||
/* Maximum encoded size of messages (where known) */
|
/* Maximum encoded size of messages (where known) */
|
||||||
#define MESHTASTIC_MESHTASTIC_LOCALONLY_PB_H_MAX_SIZE meshtastic_LocalConfig_size
|
#define MESHTASTIC_MESHTASTIC_LOCALONLY_PB_H_MAX_SIZE meshtastic_LocalConfig_size
|
||||||
#define meshtastic_LocalConfig_size 745
|
#define meshtastic_LocalConfig_size 747
|
||||||
#define meshtastic_LocalModuleConfig_size 669
|
#define meshtastic_LocalModuleConfig_size 669
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -258,6 +258,12 @@ typedef enum _meshtastic_HardwareModel {
|
|||||||
meshtastic_HardwareModel_SEEED_WIO_TRACKER_L1_EINK = 100,
|
meshtastic_HardwareModel_SEEED_WIO_TRACKER_L1_EINK = 100,
|
||||||
/* Reserved ID for future and past use */
|
/* Reserved ID for future and past use */
|
||||||
meshtastic_HardwareModel_QWANTZ_TINY_ARMS = 101,
|
meshtastic_HardwareModel_QWANTZ_TINY_ARMS = 101,
|
||||||
|
/* *
|
||||||
|
Lilygo T-Deck Pro */
|
||||||
|
meshtastic_HardwareModel_T_DECK_PRO = 102,
|
||||||
|
/* *
|
||||||
|
Lilygo TLora Pager */
|
||||||
|
meshtastic_HardwareModel_T_LORA_PAGER = 103,
|
||||||
/* ------------------------------------------------------------------------------------------------------------------------------------------
|
/* ------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
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.
|
||||||
------------------------------------------------------------------------------------------------------------------------------------------ */
|
------------------------------------------------------------------------------------------------------------------------------------------ */
|
||||||
|
@ -2,63 +2,21 @@
|
|||||||
|
|
||||||
#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && defined(SENSECAP_INDICATOR)
|
#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && defined(SENSECAP_INDICATOR)
|
||||||
|
|
||||||
#include "../mesh/generated/meshtastic/telemetry.pb.h"
|
|
||||||
#include "IndicatorSensor.h"
|
#include "IndicatorSensor.h"
|
||||||
|
#include "IndicatorSerial.h"
|
||||||
#include "TelemetrySensor.h"
|
#include "TelemetrySensor.h"
|
||||||
#include "serialization/cobs.h"
|
|
||||||
#include <Adafruit_Sensor.h>
|
#include <Adafruit_Sensor.h>
|
||||||
#include <driver/uart.h>
|
#include <driver/uart.h>
|
||||||
|
|
||||||
IndicatorSensor::IndicatorSensor() : TelemetrySensor(meshtastic_TelemetrySensorType_SENSOR_UNSET, "Indicator") {}
|
IndicatorSensor::IndicatorSensor() : TelemetrySensor(meshtastic_TelemetrySensorType_SENSOR_UNSET, "Indicator") {}
|
||||||
|
|
||||||
#define SENSOR_BUF_SIZE (512)
|
static int cmd_send(meshtastic_MessageType cmd, uint32_t value)
|
||||||
|
|
||||||
uint8_t buf[SENSOR_BUF_SIZE]; // recv
|
|
||||||
uint8_t data[SENSOR_BUF_SIZE]; // decode
|
|
||||||
|
|
||||||
#define ACK_PKT_PARA "ACK"
|
|
||||||
|
|
||||||
enum sensor_pkt_type {
|
|
||||||
PKT_TYPE_ACK = 0x00, // uin32_t
|
|
||||||
PKT_TYPE_CMD_COLLECT_INTERVAL = 0xA0, // uin32_t
|
|
||||||
PKT_TYPE_CMD_BEEP_ON = 0xA1, // uin32_t ms: on time
|
|
||||||
PKT_TYPE_CMD_BEEP_OFF = 0xA2,
|
|
||||||
PKT_TYPE_CMD_SHUTDOWN = 0xA3, // uin32_t
|
|
||||||
PKT_TYPE_CMD_POWER_ON = 0xA4,
|
|
||||||
PKT_TYPE_SENSOR_SCD41_TEMP = 0xB0, // float
|
|
||||||
PKT_TYPE_SENSOR_SCD41_HUMIDITY = 0xB1, // float
|
|
||||||
PKT_TYPE_SENSOR_SCD41_CO2 = 0xB2, // float
|
|
||||||
PKT_TYPE_SENSOR_AHT20_TEMP = 0xB3, // float
|
|
||||||
PKT_TYPE_SENSOR_AHT20_HUMIDITY = 0xB4, // float
|
|
||||||
PKT_TYPE_SENSOR_TVOC_INDEX = 0xB5, // float
|
|
||||||
};
|
|
||||||
|
|
||||||
static int cmd_send(uint8_t cmd, const char *p_data, uint8_t len)
|
|
||||||
{
|
{
|
||||||
uint8_t send_buf[32] = {0};
|
meshtastic_InterdeviceMessage message = meshtastic_InterdeviceMessage_init_zero;
|
||||||
uint8_t send_data[32] = {0};
|
|
||||||
|
|
||||||
if (len > 31) {
|
message.data.sensor.type = cmd;
|
||||||
return -1;
|
message.data.sensor.data.uint32_value = value;
|
||||||
}
|
return sensecapIndicator.send_uplink(message);
|
||||||
|
|
||||||
uint8_t index = 1;
|
|
||||||
|
|
||||||
send_data[0] = cmd;
|
|
||||||
|
|
||||||
if (len > 0 && p_data != NULL) {
|
|
||||||
memcpy(&send_data[1], p_data, len);
|
|
||||||
index += len;
|
|
||||||
}
|
|
||||||
cobs_encode_result ret = cobs_encode(send_buf, sizeof(send_buf), send_data, index);
|
|
||||||
|
|
||||||
// LOG_DEBUG("cobs TX status:%d, len:%d, type 0x%x", ret.status, ret.out_len, cmd);
|
|
||||||
|
|
||||||
if (ret.status == COBS_ENCODE_OK) {
|
|
||||||
return uart_write_bytes(SENSOR_PORT_NUM, send_buf, ret.out_len + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t IndicatorSensor::runOnce()
|
int32_t IndicatorSensor::runOnce()
|
||||||
@ -70,97 +28,64 @@ int32_t IndicatorSensor::runOnce()
|
|||||||
|
|
||||||
void IndicatorSensor::setup()
|
void IndicatorSensor::setup()
|
||||||
{
|
{
|
||||||
uart_config_t uart_config = {
|
cmd_send(meshtastic_MessageType_POWER_ON, 0);
|
||||||
.baud_rate = SENSOR_BAUD_RATE,
|
|
||||||
.data_bits = UART_DATA_8_BITS,
|
|
||||||
.parity = UART_PARITY_DISABLE,
|
|
||||||
.stop_bits = UART_STOP_BITS_1,
|
|
||||||
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
|
|
||||||
.source_clk = UART_SCLK_APB,
|
|
||||||
};
|
|
||||||
int intr_alloc_flags = 0;
|
|
||||||
char buffer[11];
|
|
||||||
|
|
||||||
uart_driver_install(SENSOR_PORT_NUM, SENSOR_BUF_SIZE * 2, 0, 0, NULL, intr_alloc_flags);
|
|
||||||
uart_param_config(SENSOR_PORT_NUM, &uart_config);
|
|
||||||
uart_set_pin(SENSOR_PORT_NUM, SENSOR_RP2040_TXD, SENSOR_RP2040_RXD, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
|
|
||||||
cmd_send(PKT_TYPE_CMD_POWER_ON, NULL, 0);
|
|
||||||
// measure and send only once every minute, for the phone API
|
// measure and send only once every minute, for the phone API
|
||||||
const char *interval = ultoa(60000, buffer, 10);
|
cmd_send(meshtastic_MessageType_COLLECT_INTERVAL, 60000);
|
||||||
cmd_send(PKT_TYPE_CMD_COLLECT_INTERVAL, interval, strlen(interval) + 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IndicatorSensor::getMetrics(meshtastic_Telemetry *measurement)
|
bool IndicatorSensor::getMetrics(meshtastic_Telemetry *measurement)
|
||||||
{
|
{
|
||||||
cobs_decode_result ret;
|
meshtastic_SensorData data = meshtastic_SensorData_init_zero;
|
||||||
int len = uart_read_bytes(SENSOR_PORT_NUM, buf, (SENSOR_BUF_SIZE - 1), 100 / portTICK_PERIOD_MS);
|
|
||||||
|
|
||||||
float value = 0.0;
|
if (ringBuf.pop(data)) {
|
||||||
uint8_t *p_buf_start = buf;
|
|
||||||
uint8_t *p_buf_end = buf;
|
|
||||||
if (len > 0) {
|
|
||||||
while (p_buf_start < (buf + len)) {
|
|
||||||
p_buf_end = p_buf_start;
|
|
||||||
while (p_buf_end < (buf + len)) {
|
|
||||||
if (*p_buf_end == 0x00) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
p_buf_end++;
|
|
||||||
}
|
|
||||||
// decode buf
|
|
||||||
memset(data, 0, sizeof(data));
|
|
||||||
ret = cobs_decode(data, sizeof(data), p_buf_start, p_buf_end - p_buf_start);
|
|
||||||
|
|
||||||
// LOG_DEBUG("cobs RX status:%d, len:%d, type:0x%x ", ret.status, ret.out_len, data[0]);
|
switch (data.type) {
|
||||||
|
case meshtastic_MessageType_SCD41_CO2: {
|
||||||
|
|
||||||
if (ret.out_len > 1 && ret.status == COBS_DECODE_OK) {
|
// LOG_DEBUG("CO2: %.1f", value);
|
||||||
|
|
||||||
value = 0.0;
|
break;
|
||||||
uint8_t pkt_type = data[0];
|
|
||||||
switch (pkt_type) {
|
|
||||||
case PKT_TYPE_SENSOR_SCD41_CO2: {
|
|
||||||
memcpy(&value, &data[1], sizeof(value));
|
|
||||||
// LOG_DEBUG("CO2: %.1f", value);
|
|
||||||
cmd_send(PKT_TYPE_ACK, ACK_PKT_PARA, 4);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case PKT_TYPE_SENSOR_AHT20_TEMP: {
|
|
||||||
memcpy(&value, &data[1], sizeof(value));
|
|
||||||
// LOG_DEBUG("Temp: %.1f", value);
|
|
||||||
cmd_send(PKT_TYPE_ACK, ACK_PKT_PARA, 4);
|
|
||||||
measurement->variant.environment_metrics.has_temperature = true;
|
|
||||||
measurement->variant.environment_metrics.temperature = value;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case PKT_TYPE_SENSOR_AHT20_HUMIDITY: {
|
|
||||||
memcpy(&value, &data[1], sizeof(value));
|
|
||||||
// LOG_DEBUG("Humidity: %.1f", value);
|
|
||||||
cmd_send(PKT_TYPE_ACK, ACK_PKT_PARA, 4);
|
|
||||||
measurement->variant.environment_metrics.has_relative_humidity = true;
|
|
||||||
measurement->variant.environment_metrics.relative_humidity = value;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case PKT_TYPE_SENSOR_TVOC_INDEX: {
|
|
||||||
memcpy(&value, &data[1], sizeof(value));
|
|
||||||
// LOG_DEBUG("Tvoc: %.1f", value);
|
|
||||||
cmd_send(PKT_TYPE_ACK, ACK_PKT_PARA, 4);
|
|
||||||
measurement->variant.environment_metrics.has_iaq = true;
|
|
||||||
measurement->variant.environment_metrics.iaq = value;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
p_buf_start = p_buf_end + 1; // next message
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case meshtastic_MessageType_AHT20_TEMP: {
|
||||||
|
|
||||||
|
// LOG_DEBUG("Temp: %.1f", value);
|
||||||
|
|
||||||
|
measurement->variant.environment_metrics.has_temperature = true;
|
||||||
|
measurement->variant.environment_metrics.temperature = data.data.float_value;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case meshtastic_MessageType_AHT20_HUMIDITY: {
|
||||||
|
|
||||||
|
// LOG_DEBUG("Humidity: %.1f", value);
|
||||||
|
|
||||||
|
measurement->variant.environment_metrics.has_relative_humidity = true;
|
||||||
|
measurement->variant.environment_metrics.relative_humidity = data.data.float_value;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case meshtastic_MessageType_TVOC_INDEX: {
|
||||||
|
|
||||||
|
// LOG_DEBUG("Tvoc: %.1f", value);
|
||||||
|
|
||||||
|
measurement->variant.environment_metrics.has_iaq = true;
|
||||||
|
measurement->variant.environment_metrics.iaq = data.data.float_value;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t IndicatorSensor::stuff_buffer(meshtastic_SensorData message)
|
||||||
|
{
|
||||||
|
|
||||||
|
return ringBuf.push(message) ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -2,8 +2,10 @@
|
|||||||
|
|
||||||
#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
|
#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
|
||||||
|
|
||||||
|
#include "../mesh/generated/meshtastic/interdevice.pb.h"
|
||||||
#include "../mesh/generated/meshtastic/telemetry.pb.h"
|
#include "../mesh/generated/meshtastic/telemetry.pb.h"
|
||||||
#include "TelemetrySensor.h"
|
#include "TelemetrySensor.h"
|
||||||
|
#include <RingBuf.h>
|
||||||
|
|
||||||
class IndicatorSensor : public TelemetrySensor
|
class IndicatorSensor : public TelemetrySensor
|
||||||
{
|
{
|
||||||
@ -14,6 +16,10 @@ class IndicatorSensor : public TelemetrySensor
|
|||||||
IndicatorSensor();
|
IndicatorSensor();
|
||||||
virtual int32_t runOnce() override;
|
virtual int32_t runOnce() override;
|
||||||
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
|
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
|
||||||
|
size_t stuff_buffer(meshtastic_SensorData message);
|
||||||
|
|
||||||
|
private:
|
||||||
|
RingBuf<meshtastic_SensorData, 16> ringBuf;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -1,129 +0,0 @@
|
|||||||
#include "cobs.h"
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#ifdef SENSECAP_INDICATOR
|
|
||||||
|
|
||||||
cobs_encode_result cobs_encode(uint8_t *dst_buf_ptr, size_t dst_buf_len, const uint8_t *src_ptr, size_t src_len)
|
|
||||||
{
|
|
||||||
|
|
||||||
cobs_encode_result result = {0, COBS_ENCODE_OK};
|
|
||||||
|
|
||||||
if (!dst_buf_ptr || !src_ptr) {
|
|
||||||
result.status = COBS_ENCODE_NULL_POINTER;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
const uint8_t *src_read_ptr = src_ptr;
|
|
||||||
const uint8_t *src_end_ptr = src_read_ptr + src_len;
|
|
||||||
uint8_t *dst_buf_start_ptr = dst_buf_ptr;
|
|
||||||
uint8_t *dst_buf_end_ptr = dst_buf_start_ptr + dst_buf_len;
|
|
||||||
uint8_t *dst_code_write_ptr = dst_buf_ptr;
|
|
||||||
uint8_t *dst_write_ptr = dst_code_write_ptr + 1;
|
|
||||||
uint8_t search_len = 1;
|
|
||||||
|
|
||||||
if (src_len != 0) {
|
|
||||||
for (;;) {
|
|
||||||
if (dst_write_ptr >= dst_buf_end_ptr) {
|
|
||||||
result.status = (cobs_encode_status)(result.status | (cobs_encode_status)COBS_ENCODE_OUT_BUFFER_OVERFLOW);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t src_byte = *src_read_ptr++;
|
|
||||||
if (src_byte == 0) {
|
|
||||||
*dst_code_write_ptr = search_len;
|
|
||||||
dst_code_write_ptr = dst_write_ptr++;
|
|
||||||
search_len = 1;
|
|
||||||
if (src_read_ptr >= src_end_ptr) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
*dst_write_ptr++ = src_byte;
|
|
||||||
search_len++;
|
|
||||||
if (src_read_ptr >= src_end_ptr) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (search_len == 0xFF) {
|
|
||||||
*dst_code_write_ptr = search_len;
|
|
||||||
dst_code_write_ptr = dst_write_ptr++;
|
|
||||||
search_len = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dst_code_write_ptr >= dst_buf_end_ptr) {
|
|
||||||
result.status = (cobs_encode_status)(result.status | (cobs_encode_status)COBS_ENCODE_OUT_BUFFER_OVERFLOW);
|
|
||||||
dst_write_ptr = dst_buf_end_ptr;
|
|
||||||
} else {
|
|
||||||
*dst_code_write_ptr = search_len;
|
|
||||||
}
|
|
||||||
|
|
||||||
result.out_len = dst_write_ptr - dst_buf_start_ptr;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
cobs_decode_result cobs_decode(uint8_t *dst_buf_ptr, size_t dst_buf_len, const uint8_t *src_ptr, size_t src_len)
|
|
||||||
{
|
|
||||||
cobs_decode_result result = {0, COBS_DECODE_OK};
|
|
||||||
|
|
||||||
if (!dst_buf_ptr || !src_ptr) {
|
|
||||||
result.status = COBS_DECODE_NULL_POINTER;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
const uint8_t *src_read_ptr = src_ptr;
|
|
||||||
const uint8_t *src_end_ptr = src_read_ptr + src_len;
|
|
||||||
uint8_t *dst_buf_start_ptr = dst_buf_ptr;
|
|
||||||
const uint8_t *dst_buf_end_ptr = dst_buf_start_ptr + dst_buf_len;
|
|
||||||
uint8_t *dst_write_ptr = dst_buf_ptr;
|
|
||||||
|
|
||||||
if (src_len != 0) {
|
|
||||||
for (;;) {
|
|
||||||
uint8_t len_code = *src_read_ptr++;
|
|
||||||
if (len_code == 0) {
|
|
||||||
result.status = (cobs_decode_status)(result.status | (cobs_decode_status)COBS_DECODE_ZERO_BYTE_IN_INPUT);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
len_code--;
|
|
||||||
|
|
||||||
size_t remaining_bytes = src_end_ptr - src_read_ptr;
|
|
||||||
if (len_code > remaining_bytes) {
|
|
||||||
result.status = (cobs_decode_status)(result.status | (cobs_decode_status)COBS_DECODE_INPUT_TOO_SHORT);
|
|
||||||
len_code = remaining_bytes;
|
|
||||||
}
|
|
||||||
|
|
||||||
remaining_bytes = dst_buf_end_ptr - dst_write_ptr;
|
|
||||||
if (len_code > remaining_bytes) {
|
|
||||||
result.status = (cobs_decode_status)(result.status | (cobs_decode_status)COBS_DECODE_OUT_BUFFER_OVERFLOW);
|
|
||||||
len_code = remaining_bytes;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (uint8_t i = len_code; i != 0; i--) {
|
|
||||||
uint8_t src_byte = *src_read_ptr++;
|
|
||||||
if (src_byte == 0) {
|
|
||||||
result.status = (cobs_decode_status)(result.status | (cobs_decode_status)COBS_DECODE_ZERO_BYTE_IN_INPUT);
|
|
||||||
}
|
|
||||||
*dst_write_ptr++ = src_byte;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (src_read_ptr >= src_end_ptr) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (len_code != 0xFE) {
|
|
||||||
if (dst_write_ptr >= dst_buf_end_ptr) {
|
|
||||||
result.status = (cobs_decode_status)(result.status | (cobs_decode_status)COBS_DECODE_OUT_BUFFER_OVERFLOW);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
*dst_write_ptr++ = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
result.out_len = dst_write_ptr - dst_buf_start_ptr;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,75 +0,0 @@
|
|||||||
#ifndef COBS_H_
|
|
||||||
#define COBS_H_
|
|
||||||
|
|
||||||
#include "configuration.h"
|
|
||||||
|
|
||||||
#ifdef SENSECAP_INDICATOR
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#define COBS_ENCODE_DST_BUF_LEN_MAX(SRC_LEN) ((SRC_LEN) + (((SRC_LEN) + 253u) / 254u))
|
|
||||||
#define COBS_DECODE_DST_BUF_LEN_MAX(SRC_LEN) (((SRC_LEN) == 0) ? 0u : ((SRC_LEN)-1u))
|
|
||||||
#define COBS_ENCODE_SRC_OFFSET(SRC_LEN) (((SRC_LEN) + 253u) / 254u)
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
COBS_ENCODE_OK = 0x00,
|
|
||||||
COBS_ENCODE_NULL_POINTER = 0x01,
|
|
||||||
COBS_ENCODE_OUT_BUFFER_OVERFLOW = 0x02
|
|
||||||
} cobs_encode_status;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
size_t out_len;
|
|
||||||
cobs_encode_status status;
|
|
||||||
} cobs_encode_result;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
COBS_DECODE_OK = 0x00,
|
|
||||||
COBS_DECODE_NULL_POINTER = 0x01,
|
|
||||||
COBS_DECODE_OUT_BUFFER_OVERFLOW = 0x02,
|
|
||||||
COBS_DECODE_ZERO_BYTE_IN_INPUT = 0x04,
|
|
||||||
COBS_DECODE_INPUT_TOO_SHORT = 0x08
|
|
||||||
} cobs_decode_status;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
size_t out_len;
|
|
||||||
cobs_decode_status status;
|
|
||||||
} cobs_decode_result;
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* COBS-encode a string of input bytes.
|
|
||||||
*
|
|
||||||
* dst_buf_ptr: The buffer into which the result will be written
|
|
||||||
* dst_buf_len: Length of the buffer into which the result will be written
|
|
||||||
* src_ptr: The byte string to be encoded
|
|
||||||
* src_len Length of the byte string to be encoded
|
|
||||||
*
|
|
||||||
* returns: A struct containing the success status of the encoding
|
|
||||||
* operation and the length of the result (that was written to
|
|
||||||
* dst_buf_ptr)
|
|
||||||
*/
|
|
||||||
cobs_encode_result cobs_encode(uint8_t *dst_buf_ptr, size_t dst_buf_len, const uint8_t *src_ptr, size_t src_len);
|
|
||||||
|
|
||||||
/* Decode a COBS byte string.
|
|
||||||
*
|
|
||||||
* dst_buf_ptr: The buffer into which the result will be written
|
|
||||||
* dst_buf_len: Length of the buffer into which the result will be written
|
|
||||||
* src_ptr: The byte string to be decoded
|
|
||||||
* src_len Length of the byte string to be decoded
|
|
||||||
*
|
|
||||||
* returns: A struct containing the success status of the decoding
|
|
||||||
* operation and the length of the result (that was written to
|
|
||||||
* dst_buf_ptr)
|
|
||||||
*/
|
|
||||||
cobs_decode_result cobs_decode(uint8_t *dst_buf_ptr, size_t dst_buf_len, const uint8_t *src_ptr, size_t src_len);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
} /* extern "C" */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* SENSECAP_INDICATOR */
|
|
||||||
|
|
||||||
#endif /* COBS_H_ */
|
|
@ -9,6 +9,8 @@
|
|||||||
#define GPS_POWER_TOGGLE // Moved definition from platformio.ini to here
|
#define GPS_POWER_TOGGLE // Moved definition from platformio.ini to here
|
||||||
|
|
||||||
#define BUTTON_PIN 39 // The middle button GPIO on the T-Beam
|
#define BUTTON_PIN 39 // The middle button GPIO on the T-Beam
|
||||||
|
// Note: On the ESP32 base version, gpio34-39 are input-only, and do not have internal pull-ups.
|
||||||
|
// If 39 is not being used for a button, it is suggested to remove the #define.
|
||||||
#define BATTERY_PIN 35 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage
|
#define BATTERY_PIN 35 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage
|
||||||
#define ADC_CHANNEL ADC1_GPIO35_CHANNEL
|
#define ADC_CHANNEL ADC1_GPIO35_CHANNEL
|
||||||
#define ADC_MULTIPLIER 1.85 // (R1 = 470k, R2 = 680k)
|
#define ADC_MULTIPLIER 1.85 // (R1 = 470k, R2 = 680k)
|
||||||
|
@ -9,7 +9,7 @@ board_check = true
|
|||||||
board_build.partitions = default_8MB.csv
|
board_build.partitions = default_8MB.csv
|
||||||
upload_protocol = esptool
|
upload_protocol = esptool
|
||||||
|
|
||||||
build_flags = ${esp32_base.build_flags}
|
build_flags = ${esp32s3_base.build_flags}
|
||||||
-Ivariants/seeed-sensecap-indicator
|
-Ivariants/seeed-sensecap-indicator
|
||||||
-DSENSECAP_INDICATOR
|
-DSENSECAP_INDICATOR
|
||||||
-DCONFIG_ARDUHAL_LOG_COLORS
|
-DCONFIG_ARDUHAL_LOG_COLORS
|
||||||
@ -27,7 +27,7 @@ lib_deps = ${esp32s3_base.lib_deps}
|
|||||||
https://github.com/mverch67/LovyanGFX/archive/4c76238c1344162a234ae917b27651af146d6fb2.zip
|
https://github.com/mverch67/LovyanGFX/archive/4c76238c1344162a234ae917b27651af146d6fb2.zip
|
||||||
earlephilhower/ESP8266Audio@^1.9.9
|
earlephilhower/ESP8266Audio@^1.9.9
|
||||||
earlephilhower/ESP8266SAM@^1.0.1
|
earlephilhower/ESP8266SAM@^1.0.1
|
||||||
|
locoduino/RingBuffer@^1.0.5
|
||||||
|
|
||||||
[env:seeed-sensecap-indicator-tft]
|
[env:seeed-sensecap-indicator-tft]
|
||||||
extends = env:seeed-sensecap-indicator
|
extends = env:seeed-sensecap-indicator
|
||||||
|
Loading…
Reference in New Issue
Block a user