Skip to content

Commit 65b50ba

Browse files
committed
get sensor and NMEA data from indicator. Will test tomorrow, don't merge yet.
1 parent 050f001 commit 65b50ba

File tree

13 files changed

+414
-341
lines changed

13 files changed

+414
-341
lines changed

.trunk/trunk.yaml

+3-3
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,15 @@ plugins:
88
uri: https://github.com/trunk-io/plugins
99
lint:
1010
enabled:
11-
11+
1212
1313
1414
15-
15+
1616
1717
1818
19-
19+
2020
2121
2222

src/gps/FakeUART.cpp

+90
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
#include "FakeUART.h"
2+
3+
FakeUART::FakeUART() {}
4+
5+
void FakeUART::begin(unsigned long baud, uint32_t config, int8_t rxPin, int8_t txPin, bool invert, unsigned long timeout_ms,
6+
uint8_t rxfifo_full_thrhd)
7+
{
8+
baudrate = baud;
9+
FakeBuf.clear();
10+
}
11+
12+
void FakeUART::end()
13+
{
14+
FakeBuf.clear();
15+
}
16+
17+
int FakeUART::available()
18+
{
19+
return FakeBuf.size();
20+
}
21+
22+
int FakeUART::peek()
23+
{
24+
unsigned char ret;
25+
if (FakeBuf.peek(ret))
26+
return ret;
27+
return -1;
28+
}
29+
30+
int FakeUART::read()
31+
{
32+
unsigned char ret;
33+
if (FakeBuf.pop(ret))
34+
return ret;
35+
return -1;
36+
}
37+
38+
void FakeUART::flush()
39+
{
40+
FakeBuf.clear();
41+
}
42+
43+
uint32_t FakeUART::baudRate()
44+
{
45+
return baudrate;
46+
}
47+
48+
void FakeUART::updateBaudRate(unsigned long speed)
49+
{
50+
baudrate = speed;
51+
}
52+
53+
size_t FakeUART::setRxBufferSize(size_t size)
54+
{
55+
return size;
56+
}
57+
58+
size_t FakeUART::write(const char *buffer)
59+
{
60+
return write((char *)buffer, strlen(buffer));
61+
}
62+
63+
size_t FakeUART::write(uint8_t *buffer, size_t size)
64+
{
65+
return write((char *)buffer, size);
66+
}
67+
68+
size_t FakeUART::write(char *buffer, size_t size)
69+
{
70+
meshtastic_InterdeviceMessage message = meshtastic_InterdeviceMessage_init_zero;
71+
if (size > sizeof(message.data.nmea)) {
72+
size = sizeof(message.data.nmea); // Truncate if buffer is too large
73+
}
74+
memcpy(message.data.nmea, buffer, size);
75+
sensecapIndicator.send_uplink(message);
76+
return size;
77+
}
78+
79+
size_t FakeUART::stuff_buffer(const char *buffer, size_t size)
80+
{
81+
// push buffer in a loop to FakeBuf
82+
for (size_t i = 0; i < size; i++) {
83+
if (!FakeBuf.push(buffer[i])) {
84+
return i;
85+
}
86+
}
87+
return size;
88+
}
89+
90+
FakeUART *FakeSerial;

src/gps/FakeUART.h

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#pragma once
2+
3+
#ifndef FAKEUART_H
4+
#define FAKEUART_H
5+
6+
#include "../IndicatorSerial.h"
7+
#include <RingBuf.h>
8+
#include <Stream.h>
9+
#include <inttypes.h>
10+
11+
class FakeUART : public Stream
12+
{
13+
public:
14+
FakeUART();
15+
16+
void begin(unsigned long baud, uint32_t config = 0x800001c, int8_t rxPin = -1, int8_t txPin = -1, bool invert = false,
17+
unsigned long timeout_ms = 20000UL, uint8_t rxfifo_full_thrhd = 112);
18+
void end();
19+
int available();
20+
int peek();
21+
int read();
22+
void flush();
23+
uint32_t baudRate();
24+
void updateBaudRate(unsigned long speed);
25+
size_t setRxBufferSize(size_t size);
26+
size_t write(const char *buffer);
27+
size_t write(char *buffer, size_t size);
28+
size_t write(uint8_t *buffer, size_t size);
29+
30+
size_t stuff_buffer(const char *buffer, size_t size);
31+
virtual size_t write(uint8_t c) { return write(&c, 1); }
32+
33+
private:
34+
unsigned long baudrate = 115200;
35+
RingBuf<unsigned char, 2048> FakeBuf;
36+
};
37+
38+
extern FakeUART *FakeSerial;
39+
40+
#endif // FAKEUART_H

src/gps/GPS.cpp

+3-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,9 @@ template <typename T, std::size_t N> std::size_t array_count(const T (&)[N])
3535
}
3636

3737
#if defined(NRF52840_XXAA) || defined(NRF52833_XXAA) || defined(ARCH_ESP32) || defined(ARCH_PORTDUINO)
38-
#if defined(RAK2560)
38+
#if defined(SENSECAP_INDICATOR)
39+
FakeUART *GPS::_serial_gps = nullptr;
40+
#elif defined(RAK2560)
3941
HardwareSerial *GPS::_serial_gps = &Serial2;
4042
#else
4143
HardwareSerial *GPS::_serial_gps = &Serial1;

src/gps/GPS.h

+7-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@
1111
#include "input/UpDownInterruptImpl1.h"
1212
#include "modules/PositionModule.h"
1313

14+
#ifdef SENSECAP_INDICATOR
15+
#include "FakeUART.h"
16+
#endif
17+
1418
// Allow defining the polarity of the ENABLE output. default is active high
1519
#ifndef GPS_EN_ACTIVE
1620
#define GPS_EN_ACTIVE 1
@@ -182,7 +186,9 @@ class GPS : private concurrency::OSThread
182186
CallbackObserver<GPS, void *> notifyDeepSleepObserver = CallbackObserver<GPS, void *>(this, &GPS::prepareDeepSleep);
183187

184188
/** If !NULL we will use this serial port to construct our GPS */
185-
#if defined(ARCH_RP2040)
189+
#if defined(SENSECAP_INDICATOR)
190+
static FakeUART *_serial_gps;
191+
#elif defined(ARCH_RP2040)
186192
static SerialUART *_serial_gps;
187193
#else
188194
static HardwareSerial *_serial_gps;

src/main.cpp

+9
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@
2222
#include "error.h"
2323
#include "power.h"
2424

25+
#ifdef SENSECAP_INDICATOR // on the indicator run the additional serial port for the RP2040
26+
#include "IndicatorSerial.h"
27+
#endif
28+
2529
#if !MESHTASTIC_EXCLUDE_I2C
2630
#include "detect/ScanI2CTwoWire.h"
2731
#include <Wire.h>
@@ -692,6 +696,11 @@ void setup()
692696
buttonThread = new ButtonThread();
693697
#endif
694698

699+
// If we have an indicator, start process to service secondary port
700+
#ifdef SENSECAP_INDICATOR
701+
sensecapIndicator.begin(Serial2);
702+
#endif
703+
695704
// only play start melody when role is not tracker or sensor
696705
if (config.power.is_power_saving == true &&
697706
IS_ONE_OF(config.device.role, meshtastic_Config_DeviceConfig_Role_TRACKER,

src/mesh/IndicatorSerial.cpp

+151
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
#ifdef SENSECAP_INDICATOR
2+
3+
#include "IndicatorSerial.h"
4+
#include "../modules/Telemetry/Sensor/IndicatorSensor.h"
5+
#include "FakeUART.h"
6+
#include <HardwareSerial.h>
7+
#include <pb_decode.h>
8+
#include <pb_encode.h>
9+
10+
extern IndicatorSensor indicatorSensor;
11+
12+
SensecapIndicator sensecapIndicator;
13+
14+
SensecapIndicator::SensecapIndicator() : OSThread("SensecapIndicator") {}
15+
16+
void SensecapIndicator::begin(HardwareSerial serial)
17+
{
18+
if (!running) {
19+
_serial = serial;
20+
_serial.setRxBufferSize(PB_BUFSIZE);
21+
_serial.begin(115200);
22+
running = true;
23+
LOG_DEBUG("Start communication thread");
24+
}
25+
}
26+
27+
int32_t SensecapIndicator::runOnce()
28+
{
29+
if (running) {
30+
size_t bytes_read = 0;
31+
32+
// See if there are any more bytes to add to our buffer.
33+
size_t space_left = PB_BUFSIZE - pb_rx_size;
34+
35+
bytes_read = serial_check((char *)pb_rx_buf + pb_rx_size, space_left);
36+
37+
pb_rx_size += bytes_read;
38+
check_packet();
39+
return (10);
40+
} else {
41+
LOG_DEBUG("Not running");
42+
return (1000);
43+
}
44+
}
45+
46+
bool SensecapIndicator::send_uplink(meshtastic_InterdeviceMessage message)
47+
{
48+
pb_tx_buf[0] = MT_MAGIC_0;
49+
pb_tx_buf[1] = MT_MAGIC_1;
50+
51+
pb_ostream_t stream = pb_ostream_from_buffer(pb_tx_buf + MT_HEADER_SIZE, PB_BUFSIZE);
52+
if (!pb_encode(&stream, meshtastic_InterdeviceMessage_fields, &message)) {
53+
LOG_DEBUG("pb_encode failed");
54+
return false;
55+
}
56+
57+
// Store the payload length in the header
58+
pb_tx_buf[2] = stream.bytes_written / 256;
59+
pb_tx_buf[3] = stream.bytes_written % 256;
60+
61+
bool rv = send((const char *)pb_tx_buf, MT_HEADER_SIZE + stream.bytes_written);
62+
63+
return rv;
64+
}
65+
66+
size_t SensecapIndicator::serial_check(char *buf, size_t space_left)
67+
{
68+
size_t bytes_read = 0;
69+
while (_serial.available()) {
70+
char c = _serial.read();
71+
*buf++ = c;
72+
if (++bytes_read >= space_left) {
73+
LOG_DEBUG("Serial overflow: %d > %d", bytes_read, space_left);
74+
break;
75+
}
76+
}
77+
return bytes_read;
78+
}
79+
80+
void SensecapIndicator::check_packet()
81+
{
82+
if (pb_rx_size < MT_HEADER_SIZE) {
83+
// We don't even have a header yet
84+
delay(NO_NEWS_PAUSE);
85+
return;
86+
}
87+
88+
if (pb_rx_buf[0] != MT_MAGIC_0 || pb_rx_buf[1] != MT_MAGIC_1) {
89+
LOG_DEBUG("Got bad magic");
90+
memset(pb_rx_buf, 0, PB_BUFSIZE);
91+
pb_rx_size = 0;
92+
return;
93+
}
94+
95+
uint16_t payload_len = pb_rx_buf[2] << 8 | pb_rx_buf[3];
96+
if (payload_len > PB_BUFSIZE) {
97+
LOG_DEBUG("Got packet claiming to be ridiculous length");
98+
return;
99+
}
100+
101+
if ((size_t)(payload_len + 4) > pb_rx_size) {
102+
delay(NO_NEWS_PAUSE);
103+
return;
104+
}
105+
106+
// We have a complete packet, handle it
107+
handle_packet(payload_len);
108+
}
109+
110+
bool SensecapIndicator::handle_packet(size_t payload_len)
111+
{
112+
meshtastic_InterdeviceMessage message = meshtastic_InterdeviceMessage_init_zero;
113+
114+
// Decode the protobuf and shift forward any remaining bytes in the buffer
115+
// (which, if present, belong to the packet that we're going to process on the
116+
// next loop)
117+
pb_istream_t stream = pb_istream_from_buffer(pb_rx_buf + MT_HEADER_SIZE, payload_len);
118+
bool status = pb_decode(&stream, meshtastic_InterdeviceMessage_fields, &message);
119+
memmove(pb_rx_buf, pb_rx_buf + MT_HEADER_SIZE + payload_len, PB_BUFSIZE - MT_HEADER_SIZE - payload_len);
120+
pb_rx_size -= MT_HEADER_SIZE + payload_len;
121+
122+
if (!status) {
123+
LOG_DEBUG("Decoding failed");
124+
return false;
125+
}
126+
switch (message.which_data) {
127+
case meshtastic_InterdeviceMessage_sensor_tag:
128+
indicatorSensor.stuff_buffer(message.data.sensor);
129+
return true;
130+
break;
131+
case meshtastic_InterdeviceMessage_nmea_tag:
132+
// send String to NMEA processing
133+
FakeSerial->stuff_buffer(message.data.nmea, strlen(message.data.nmea));
134+
return true;
135+
break;
136+
default:
137+
// the other messages really only flow downstream
138+
LOG_DEBUG("Got a message of unexpected type");
139+
return false;
140+
}
141+
}
142+
143+
bool SensecapIndicator::send(const char *buf, size_t len)
144+
{
145+
size_t wrote = _serial.write(buf, len);
146+
if (wrote == len)
147+
return true;
148+
return false;
149+
}
150+
151+
#endif // SENSECAP_INDICATOR

0 commit comments

Comments
 (0)