mirror of https://github.com/meshcore-dev/MeshCore
24 changed files with 512 additions and 19 deletions
@ -0,0 +1,38 @@ |
|||||
|
/* Linker script to configure memory regions. */ |
||||
|
|
||||
|
SEARCH_DIR(.) |
||||
|
GROUP(-lgcc -lc -lnosys) |
||||
|
|
||||
|
MEMORY |
||||
|
{ |
||||
|
FLASH (rx) : ORIGIN = 0x26000, LENGTH = 0xD4000 - 0x26000 |
||||
|
|
||||
|
/* SRAM required by Softdevice depend on |
||||
|
* - Attribute Table Size (Number of Services and Characteristics) |
||||
|
* - Vendor UUID count |
||||
|
* - Max ATT MTU |
||||
|
* - Concurrent connection peripheral + central + secure links |
||||
|
* - Event Len, HVN queue, Write CMD queue |
||||
|
*/ |
||||
|
RAM (rwx) : ORIGIN = 0x20006000, LENGTH = 0x20040000 - 0x20006000 |
||||
|
} |
||||
|
|
||||
|
SECTIONS |
||||
|
{ |
||||
|
. = ALIGN(4); |
||||
|
.svc_data : |
||||
|
{ |
||||
|
PROVIDE(__start_svc_data = .); |
||||
|
KEEP(*(.svc_data)) |
||||
|
PROVIDE(__stop_svc_data = .); |
||||
|
} > RAM |
||||
|
|
||||
|
.fs_data : |
||||
|
{ |
||||
|
PROVIDE(__start_fs_data = .); |
||||
|
KEEP(*(.fs_data)) |
||||
|
PROVIDE(__stop_fs_data = .); |
||||
|
} > RAM |
||||
|
} INSERT AFTER .data; |
||||
|
|
||||
|
INCLUDE "nrf52_common.ld" |
||||
@ -0,0 +1,38 @@ |
|||||
|
/* Linker script to configure memory regions. */ |
||||
|
|
||||
|
SEARCH_DIR(.) |
||||
|
GROUP(-lgcc -lc -lnosys) |
||||
|
|
||||
|
MEMORY |
||||
|
{ |
||||
|
FLASH (rx) : ORIGIN = 0x27000, LENGTH = 0xD4000 - 0x27000 |
||||
|
|
||||
|
/* SRAM required by Softdevice depend on |
||||
|
* - Attribute Table Size (Number of Services and Characteristics) |
||||
|
* - Vendor UUID count |
||||
|
* - Max ATT MTU |
||||
|
* - Concurrent connection peripheral + central + secure links |
||||
|
* - Event Len, HVN queue, Write CMD queue |
||||
|
*/ |
||||
|
RAM (rwx) : ORIGIN = 0x20006000, LENGTH = 0x20040000 - 0x20006000 |
||||
|
} |
||||
|
|
||||
|
SECTIONS |
||||
|
{ |
||||
|
. = ALIGN(4); |
||||
|
.svc_data : |
||||
|
{ |
||||
|
PROVIDE(__start_svc_data = .); |
||||
|
KEEP(*(.svc_data)) |
||||
|
PROVIDE(__stop_svc_data = .); |
||||
|
} > RAM |
||||
|
|
||||
|
.fs_data : |
||||
|
{ |
||||
|
PROVIDE(__start_fs_data = .); |
||||
|
KEEP(*(.fs_data)) |
||||
|
PROVIDE(__stop_fs_data = .); |
||||
|
} > RAM |
||||
|
} INSERT AFTER .data; |
||||
|
|
||||
|
INCLUDE "nrf52_common.ld" |
||||
@ -0,0 +1,223 @@ |
|||||
|
#pragma once |
||||
|
|
||||
|
#include <stdint.h> |
||||
|
|
||||
|
#define LPP_DIGITAL_INPUT 0 // 1 byte
|
||||
|
#define LPP_DIGITAL_OUTPUT 1 // 1 byte
|
||||
|
#define LPP_ANALOG_INPUT 2 // 2 bytes, 0.01 signed
|
||||
|
#define LPP_ANALOG_OUTPUT 3 // 2 bytes, 0.01 signed
|
||||
|
#define LPP_GENERIC_SENSOR 100 // 4 bytes, unsigned
|
||||
|
#define LPP_LUMINOSITY 101 // 2 bytes, 1 lux unsigned
|
||||
|
#define LPP_PRESENCE 102 // 1 byte, bool
|
||||
|
#define LPP_TEMPERATURE 103 // 2 bytes, 0.1°C signed
|
||||
|
#define LPP_RELATIVE_HUMIDITY 104 // 1 byte, 0.5% unsigned
|
||||
|
#define LPP_ACCELEROMETER 113 // 2 bytes per axis, 0.001G
|
||||
|
#define LPP_BAROMETRIC_PRESSURE 115 // 2 bytes 0.1hPa unsigned
|
||||
|
#define LPP_VOLTAGE 116 // 2 bytes 0.01V unsigned
|
||||
|
#define LPP_CURRENT 117 // 2 bytes 0.001A unsigned
|
||||
|
#define LPP_FREQUENCY 118 // 4 bytes 1Hz unsigned
|
||||
|
#define LPP_PERCENTAGE 120 // 1 byte 1-100% unsigned
|
||||
|
#define LPP_ALTITUDE 121 // 2 byte 1m signed
|
||||
|
#define LPP_CONCENTRATION 125 // 2 bytes, 1 ppm unsigned
|
||||
|
#define LPP_POWER 128 // 2 byte, 1W, unsigned
|
||||
|
#define LPP_DISTANCE 130 // 4 byte, 0.001m, unsigned
|
||||
|
#define LPP_ENERGY 131 // 4 byte, 0.001kWh, unsigned
|
||||
|
#define LPP_DIRECTION 132 // 2 bytes, 1deg, unsigned
|
||||
|
#define LPP_UNIXTIME 133 // 4 bytes, unsigned
|
||||
|
#define LPP_GYROMETER 134 // 2 bytes per axis, 0.01 °/s
|
||||
|
#define LPP_COLOUR 135 // 1 byte per RGB Color
|
||||
|
#define LPP_GPS 136 // 3 byte lon/lat 0.0001 °, 3 bytes alt 0.01 meter
|
||||
|
#define LPP_SWITCH 142 // 1 byte, 0/1
|
||||
|
#define LPP_POLYLINE 240 // 1 byte size, 1 byte delta factor, 3 byte lon/lat 0.0001° * factor, n (size-8) bytes deltas
|
||||
|
|
||||
|
// Multipliers
|
||||
|
#define LPP_DIGITAL_INPUT_MULT 1 |
||||
|
#define LPP_DIGITAL_OUTPUT_MULT 1 |
||||
|
#define LPP_ANALOG_INPUT_MULT 100 |
||||
|
#define LPP_ANALOG_OUTPUT_MULT 100 |
||||
|
#define LPP_GENERIC_SENSOR_MULT 1 |
||||
|
#define LPP_LUMINOSITY_MULT 1 |
||||
|
#define LPP_PRESENCE_MULT 1 |
||||
|
#define LPP_TEMPERATURE_MULT 10 |
||||
|
#define LPP_RELATIVE_HUMIDITY_MULT 2 |
||||
|
#define LPP_ACCELEROMETER_MULT 1000 |
||||
|
#define LPP_BAROMETRIC_PRESSURE_MULT 10 |
||||
|
#define LPP_VOLTAGE_MULT 100 |
||||
|
#define LPP_CURRENT_MULT 1000 |
||||
|
#define LPP_FREQUENCY_MULT 1 |
||||
|
#define LPP_PERCENTAGE_MULT 1 |
||||
|
#define LPP_ALTITUDE_MULT 1 |
||||
|
#define LPP_POWER_MULT 1 |
||||
|
#define LPP_DISTANCE_MULT 1000 |
||||
|
#define LPP_ENERGY_MULT 1000 |
||||
|
#define LPP_DIRECTION_MULT 1 |
||||
|
#define LPP_UNIXTIME_MULT 1 |
||||
|
#define LPP_GYROMETER_MULT 100 |
||||
|
#define LPP_GPS_LAT_LON_MULT 10000 |
||||
|
#define LPP_GPS_ALT_MULT 100 |
||||
|
#define LPP_SWITCH_MULT 1 |
||||
|
#define LPP_CONCENTRATION_MULT 1 |
||||
|
#define LPP_COLOUR_MULT 1 |
||||
|
|
||||
|
#define LPP_ERROR_OK 0 |
||||
|
#define LPP_ERROR_OVERFLOW 1 |
||||
|
#define LPP_ERROR_UNKOWN_TYPE 2 |
||||
|
|
||||
|
class LPPReader { |
||||
|
const uint8_t* _buf; |
||||
|
uint8_t _len; |
||||
|
uint8_t _pos; |
||||
|
|
||||
|
float getFloat(const uint8_t * buffer, uint8_t size, uint32_t multiplier, bool is_signed) { |
||||
|
uint32_t value = 0; |
||||
|
for (uint8_t i = 0; i < size; i++) { |
||||
|
value = (value << 8) + buffer[i]; |
||||
|
} |
||||
|
|
||||
|
int sign = 1; |
||||
|
if (is_signed) { |
||||
|
uint32_t bit = 1ul << ((size * 8) - 1); |
||||
|
if ((value & bit) == bit) { |
||||
|
value = (bit << 1) - value; |
||||
|
sign = -1; |
||||
|
} |
||||
|
} |
||||
|
return sign * ((float) value / multiplier); |
||||
|
} |
||||
|
|
||||
|
public: |
||||
|
LPPReader(const uint8_t buf[], uint8_t len) : _buf(buf), _len(len), _pos(0) { } |
||||
|
|
||||
|
void reset() { |
||||
|
_pos = 0; |
||||
|
} |
||||
|
|
||||
|
bool readHeader(uint8_t& channel, uint8_t& type) { |
||||
|
if (_pos + 2 < _len) { |
||||
|
channel = _buf[_pos++]; |
||||
|
type = _buf[_pos++]; |
||||
|
|
||||
|
return channel != 0; // channel 0 is End-of-data
|
||||
|
} |
||||
|
return false; // end-of-buffer
|
||||
|
} |
||||
|
|
||||
|
bool readGPS(float& lat, float& lon, float& alt) { |
||||
|
lat = getFloat(&_buf[_pos], 3, 10000, true); _pos += 3; |
||||
|
lon = getFloat(&_buf[_pos], 3, 10000, true); _pos += 3; |
||||
|
alt = getFloat(&_buf[_pos], 3, 100, true); _pos += 3; |
||||
|
return _pos <= _len; |
||||
|
} |
||||
|
bool readVoltage(float& voltage) { |
||||
|
voltage = getFloat(&_buf[_pos], 2, 100, false); _pos += 2; |
||||
|
return _pos <= _len; |
||||
|
} |
||||
|
bool readCurrent(float& amps) { |
||||
|
amps = getFloat(&_buf[_pos], 2, 1000, false); _pos += 2; |
||||
|
return _pos <= _len; |
||||
|
} |
||||
|
bool readPower(float& watts) { |
||||
|
watts = getFloat(&_buf[_pos], 2, 1, false); _pos += 2; |
||||
|
return _pos <= _len; |
||||
|
} |
||||
|
bool readTemperature(float& degrees_c) { |
||||
|
degrees_c = getFloat(&_buf[_pos], 2, 10, true); _pos += 2; |
||||
|
return _pos <= _len; |
||||
|
} |
||||
|
bool readPressure(float& pa) { |
||||
|
pa = getFloat(&_buf[_pos], 2, 10, false); _pos += 2; |
||||
|
return _pos <= _len; |
||||
|
} |
||||
|
bool readRelativeHumidity(float& pct) { |
||||
|
pct = getFloat(&_buf[_pos], 1, 2, false); _pos += 1; |
||||
|
return _pos <= _len; |
||||
|
} |
||||
|
bool readAltitude(float& m) { |
||||
|
m = getFloat(&_buf[_pos], 2, 1, true); _pos += 2; |
||||
|
return _pos <= _len; |
||||
|
} |
||||
|
|
||||
|
void skipData(uint8_t type) { |
||||
|
switch (type) { |
||||
|
case LPP_GPS: |
||||
|
_pos += 9; break; |
||||
|
case LPP_POLYLINE: |
||||
|
_pos += 8; break; // TODO: this is MINIMIUM
|
||||
|
case LPP_GYROMETER: |
||||
|
case LPP_ACCELEROMETER: |
||||
|
_pos += 6; break; |
||||
|
case LPP_GENERIC_SENSOR: |
||||
|
case LPP_FREQUENCY: |
||||
|
case LPP_DISTANCE: |
||||
|
case LPP_ENERGY: |
||||
|
case LPP_UNIXTIME: |
||||
|
_pos += 4; break; |
||||
|
case LPP_COLOUR: |
||||
|
_pos += 3; break; |
||||
|
case LPP_ANALOG_INPUT: |
||||
|
case LPP_ANALOG_OUTPUT: |
||||
|
case LPP_LUMINOSITY: |
||||
|
case LPP_TEMPERATURE: |
||||
|
case LPP_CONCENTRATION: |
||||
|
case LPP_BAROMETRIC_PRESSURE: |
||||
|
case LPP_ALTITUDE: |
||||
|
case LPP_VOLTAGE: |
||||
|
case LPP_CURRENT: |
||||
|
case LPP_DIRECTION: |
||||
|
case LPP_POWER: |
||||
|
_pos += 2; break; |
||||
|
default: |
||||
|
_pos++; |
||||
|
} |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
class LPPWriter { |
||||
|
uint8_t* _buf; |
||||
|
uint8_t _max_len; |
||||
|
uint8_t _len; |
||||
|
|
||||
|
void write(uint16_t value) { |
||||
|
_buf[_len++] = (value >> 8) & 0xFF; // MSB
|
||||
|
_buf[_len++] = value & 0xFF; // LSB
|
||||
|
} |
||||
|
|
||||
|
public: |
||||
|
LPPWriter(uint8_t buf[], uint8_t max_len): _buf(buf), _max_len(max_len), _len(0) { } |
||||
|
|
||||
|
bool writeVoltage(uint8_t channel, float voltage) { |
||||
|
if (_len + 4 <= _max_len) { |
||||
|
_buf[_len++] = channel; |
||||
|
_buf[_len++] = LPP_VOLTAGE; |
||||
|
uint16_t value = voltage * 100; |
||||
|
write(value); |
||||
|
return true; |
||||
|
} |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
bool writeGPS(uint8_t channel, float lat, float lon, float alt) { |
||||
|
if (_len + 11 <= _max_len) { |
||||
|
_buf[_len++] = channel; |
||||
|
_buf[_len++] = LPP_GPS; |
||||
|
|
||||
|
int32_t lati = lat * 10000; // we lose some precision :-(
|
||||
|
int32_t loni = lon * 10000; |
||||
|
int32_t alti = alt * 100; |
||||
|
|
||||
|
_buf[_len++] = lati >> 16; |
||||
|
_buf[_len++] = lati >> 8; |
||||
|
_buf[_len++] = lati; |
||||
|
_buf[_len++] = loni >> 16; |
||||
|
_buf[_len++] = loni >> 8; |
||||
|
_buf[_len++] = loni; |
||||
|
_buf[_len++] = alti >> 16; |
||||
|
_buf[_len++] = alti >> 8; |
||||
|
_buf[_len++] = alti; |
||||
|
return true; |
||||
|
} |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
uint8_t length() { return _len; } |
||||
|
}; |
||||
Loading…
Reference in new issue