mirror of
https://github.com/meshtastic/firmware.git
synced 2025-06-10 07:02:11 +00:00
Add RAK2560/RAK9154
This commit is contained in:
parent
a38a18da0d
commit
d7c52c33b9
7
.vscode/extensions.json
vendored
7
.vscode/extensions.json
vendored
@ -2,8 +2,9 @@
|
||||
// See http://go.microsoft.com/fwlink/?LinkId=827846
|
||||
// for the documentation about the extensions.json format
|
||||
"recommendations": [
|
||||
"ms-vscode.cpptools",
|
||||
"platformio.platformio-ide",
|
||||
"trunk.io"
|
||||
"platformio.platformio-ide"
|
||||
],
|
||||
"unwantedRecommendations": [
|
||||
"ms-vscode.cpptools-extension-pack"
|
||||
]
|
||||
}
|
||||
|
@ -29,6 +29,7 @@ default_envs = tbeam
|
||||
;default_envs = meshtastic-dr-dev
|
||||
;default_envs = m5stack-coreink
|
||||
;default_envs = rak4631
|
||||
;default_envs = rak2560
|
||||
;default_envs = rak10701
|
||||
;default_envs = wio-e5
|
||||
;default_envs = radiomaster_900_bandit_nano
|
||||
|
@ -75,6 +75,10 @@ INA219Sensor ina219Sensor;
|
||||
INA3221Sensor ina3221Sensor;
|
||||
#endif
|
||||
|
||||
#if HAS_RAKPROT && !defined(ARCH_PORTDUINO)
|
||||
RAK9154Sensor rak9154Sensor;
|
||||
#endif
|
||||
|
||||
#ifdef HAS_PMU
|
||||
#include "XPowersAXP192.tpp"
|
||||
#include "XPowersAXP2101.tpp"
|
||||
@ -145,6 +149,12 @@ class AnalogBatteryLevel : public HasBatteryLevel
|
||||
*/
|
||||
virtual int getBatteryPercent() override
|
||||
{
|
||||
#if defined(HAS_RAKPROT) && !defined(ARCH_PORTDUINO) && !defined(HAS_PMU)
|
||||
if (hasRAK()) {
|
||||
return rak9154Sensor.getBusBatteryPercent();
|
||||
}
|
||||
#endif
|
||||
|
||||
float v = getBattVoltage();
|
||||
|
||||
if (v < noBatVolt)
|
||||
@ -184,6 +194,12 @@ class AnalogBatteryLevel : public HasBatteryLevel
|
||||
virtual uint16_t getBattVoltage() override
|
||||
{
|
||||
|
||||
#if defined(HAS_RAKPROT) && !defined(ARCH_PORTDUINO) && !defined(HAS_PMU)
|
||||
if (hasRAK()) {
|
||||
return getRAKVoltage();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if HAS_TELEMETRY && !defined(ARCH_PORTDUINO) && !defined(HAS_PMU) && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
|
||||
if (hasINA()) {
|
||||
LOG_DEBUG("Using INA on I2C addr 0x%x for device battery voltage\n", config.power.device_battery_ina_address);
|
||||
@ -356,6 +372,11 @@ class AnalogBatteryLevel : public HasBatteryLevel
|
||||
/// we can't be smart enough to say 'full'?
|
||||
virtual bool isCharging() override
|
||||
{
|
||||
#if defined(HAS_RAKPROT) && !defined(ARCH_PORTDUINO) && !defined(HAS_PMU)
|
||||
if (hasRAK()) {
|
||||
return (rak9154Sensor.isCharging()) ? OptTrue : OptFalse;
|
||||
}
|
||||
#endif
|
||||
#ifdef EXT_CHRG_DETECT
|
||||
return digitalRead(EXT_CHRG_DETECT) == ext_chrg_detect_value;
|
||||
#else
|
||||
@ -379,6 +400,18 @@ 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_RAKPROT)
|
||||
|
||||
uint16_t getRAKVoltage() { return rak9154Sensor.getBusVoltageMv(); }
|
||||
|
||||
bool hasRAK()
|
||||
{
|
||||
if (!rak9154Sensor.isInitialized())
|
||||
return rak9154Sensor.runOnce() > 0;
|
||||
return rak9154Sensor.isRunning();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if HAS_TELEMETRY && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && !defined(ARCH_PORTDUINO)
|
||||
uint16_t getINAVoltage()
|
||||
{
|
||||
|
189
src/modules/Telemetry/Sensor/RAK9154Sensor.cpp
Normal file
189
src/modules/Telemetry/Sensor/RAK9154Sensor.cpp
Normal file
@ -0,0 +1,189 @@
|
||||
#include "RAK9154Sensor.h"
|
||||
#include "../mesh/generated/meshtastic/telemetry.pb.h"
|
||||
#include "TelemetrySensor.h"
|
||||
#include "configuration.h"
|
||||
|
||||
#include <RAK-OneWireSerial.h>
|
||||
#include "concurrency/Periodic.h"
|
||||
|
||||
using namespace concurrency;
|
||||
|
||||
#define BOOT_DATA_REQ
|
||||
|
||||
RAK9154Sensor::RAK9154Sensor() : TelemetrySensor(meshtastic_TelemetrySensorType_SENSOR_UNSET, "RAK1954") {}
|
||||
|
||||
static Periodic *onewirePeriodic;
|
||||
|
||||
static SoftwareHalfSerial mySerial(HALF_UART_PIN); // Wire pin P0.15
|
||||
|
||||
static uint8_t buff[0x100];
|
||||
static uint16_t bufflen = 0;
|
||||
|
||||
static int16_t dc_cur = 0;
|
||||
static uint16_t dc_vol = 0;
|
||||
static uint8_t dc_prec = 0;
|
||||
static uint8_t provision = 0;
|
||||
|
||||
static void onewire_evt(const uint8_t pid, const uint8_t sid, const SNHUBAPI_EVT_E eid, uint8_t *msg, uint16_t len)
|
||||
{
|
||||
switch (eid)
|
||||
{
|
||||
case SNHUBAPI_EVT_RECV_REQ:
|
||||
case SNHUBAPI_EVT_RECV_RSP:
|
||||
break;
|
||||
|
||||
case SNHUBAPI_EVT_QSEND:
|
||||
mySerial.write(msg, len);
|
||||
break;
|
||||
|
||||
case SNHUBAPI_EVT_ADD_SID:
|
||||
// LOG_INFO("+ADD:SID:[%02x]\r\n", msg[0]);
|
||||
break;
|
||||
|
||||
case SNHUBAPI_EVT_ADD_PID:
|
||||
// LOG_INFO("+ADD:PID:[%02x]\r\n", msg[0]);
|
||||
#ifdef BOOT_DATA_REQ
|
||||
provision = msg[0];
|
||||
#endif
|
||||
break;
|
||||
|
||||
case SNHUBAPI_EVT_GET_INTV:
|
||||
break;
|
||||
|
||||
case SNHUBAPI_EVT_GET_ENABLE:
|
||||
break;
|
||||
|
||||
case SNHUBAPI_EVT_SDATA_REQ:
|
||||
|
||||
// LOG_INFO("+EVT:PID[%02x],IPSO[%02x]\r\n",pid,msg[0]);
|
||||
// for( uint16_t i=1; i<len; i++)
|
||||
// {
|
||||
// LOG_INFO("%02x,", msg[i]);
|
||||
// }
|
||||
// LOG_INFO("\r\n");
|
||||
switch (msg[0])
|
||||
{
|
||||
case RAK_IPSO_CAPACITY:
|
||||
dc_prec = msg[1];
|
||||
if (dc_prec > 100)
|
||||
{
|
||||
dc_prec = 100;
|
||||
}
|
||||
break;
|
||||
case RAK_IPSO_DC_CURRENT:
|
||||
dc_cur = (msg[2] << 8) + msg[1];
|
||||
break;
|
||||
case RAK_IPSO_DC_VOLTAGE:
|
||||
dc_vol = (msg[2] << 8) + msg[1];
|
||||
dc_vol *= 10;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
case SNHUBAPI_EVT_REPORT:
|
||||
|
||||
// LOG_INFO("+EVT:PID[%02x],IPSO[%02x]\r\n",pid,msg[0]);
|
||||
// for( uint16_t i=1; i<len; i++)
|
||||
// {
|
||||
// LOG_INFO("%02x,", msg[i]);
|
||||
// }
|
||||
// LOG_INFO("\r\n");
|
||||
|
||||
switch (msg[0])
|
||||
{
|
||||
case RAK_IPSO_CAPACITY:
|
||||
dc_prec = msg[1];
|
||||
if (dc_prec > 100)
|
||||
{
|
||||
dc_prec = 100;
|
||||
}
|
||||
break;
|
||||
case RAK_IPSO_DC_CURRENT:
|
||||
dc_cur = (msg[1] << 8) + msg[2];
|
||||
break;
|
||||
case RAK_IPSO_DC_VOLTAGE:
|
||||
dc_vol = (msg[1] << 8) + msg[2];
|
||||
dc_vol *= 10;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case SNHUBAPI_EVT_CHKSUM_ERR:
|
||||
LOG_INFO("+ERR:CHKSUM\r\n");
|
||||
break;
|
||||
|
||||
case SNHUBAPI_EVT_SEQ_ERR:
|
||||
LOG_INFO("+ERR:SEQUCE\r\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int32_t onewireHandle()
|
||||
{
|
||||
if (provision != 0)
|
||||
{
|
||||
RakSNHub_Protocl_API.get.data(provision);
|
||||
provision = 0;
|
||||
}
|
||||
|
||||
while (mySerial.available())
|
||||
{
|
||||
char a = mySerial.read();
|
||||
buff[bufflen++] = a;
|
||||
delay(2); // continue data, timeout=2ms
|
||||
}
|
||||
|
||||
if (bufflen != 0)
|
||||
{
|
||||
RakSNHub_Protocl_API.process((uint8_t *)buff, bufflen);
|
||||
bufflen = 0;
|
||||
}
|
||||
|
||||
return 50;
|
||||
}
|
||||
|
||||
int32_t RAK9154Sensor::runOnce()
|
||||
{
|
||||
onewirePeriodic = new Periodic("onewireHandle", onewireHandle);
|
||||
|
||||
mySerial.begin(9600);
|
||||
|
||||
RakSNHub_Protocl_API.init(onewire_evt);
|
||||
|
||||
status = true;
|
||||
initialized = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void RAK9154Sensor::setup()
|
||||
{
|
||||
// Set up oversampling and filter initialization
|
||||
}
|
||||
|
||||
bool RAK9154Sensor::getMetrics(meshtastic_Telemetry *measurement)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
uint16_t RAK9154Sensor::getBusVoltageMv()
|
||||
{
|
||||
return dc_vol;
|
||||
}
|
||||
|
||||
int RAK9154Sensor::getBusBatteryPercent()
|
||||
{
|
||||
return (int)dc_prec;
|
||||
}
|
||||
|
||||
bool RAK9154Sensor::isCharging()
|
||||
{
|
||||
return (dc_cur > 0) ? true : false;
|
||||
}
|
18
src/modules/Telemetry/Sensor/RAK9154Sensor.h
Normal file
18
src/modules/Telemetry/Sensor/RAK9154Sensor.h
Normal file
@ -0,0 +1,18 @@
|
||||
#include "../mesh/generated/meshtastic/telemetry.pb.h"
|
||||
#include "TelemetrySensor.h"
|
||||
#include "VoltageSensor.h"
|
||||
|
||||
class RAK9154Sensor : public TelemetrySensor, VoltageSensor
|
||||
{
|
||||
private:
|
||||
protected:
|
||||
virtual void setup() override;
|
||||
|
||||
public:
|
||||
RAK9154Sensor();
|
||||
virtual int32_t runOnce() override;
|
||||
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
|
||||
virtual uint16_t getBusVoltageMv() override;
|
||||
int getBusBatteryPercent();
|
||||
bool isCharging();
|
||||
};
|
@ -46,6 +46,11 @@ extern INA219Sensor ina219Sensor;
|
||||
extern INA3221Sensor ina3221Sensor;
|
||||
#endif
|
||||
|
||||
#if HAS_RAKPROT && !defined(ARCH_PORTDUINO)
|
||||
#include "modules/Telemetry/Sensor/RAK9154Sensor.h"
|
||||
extern RAK9154Sensor rak9154Sensor;
|
||||
#endif
|
||||
|
||||
class Power : private concurrency::OSThread
|
||||
{
|
||||
|
||||
|
105
variants/rak2560/create_uf2.py
Normal file
105
variants/rak2560/create_uf2.py
Normal file
@ -0,0 +1,105 @@
|
||||
import sys
|
||||
import struct
|
||||
|
||||
Import("env")
|
||||
|
||||
# Parse input and create UF2 file
|
||||
def create_uf2(source, target, env):
|
||||
# source_hex = target[0].get_abspath()
|
||||
source_hex = target[0].get_string(False)
|
||||
source_hex = '.\\'+source_hex
|
||||
print("#########################################################")
|
||||
print("Create UF2 from "+source_hex)
|
||||
print("#########################################################")
|
||||
# print("Source: " + source_hex)
|
||||
target = source_hex.replace(".hex", "")
|
||||
target = target + ".uf2"
|
||||
# print("Target: " + target)
|
||||
|
||||
with open(source_hex, mode='rb') as f:
|
||||
inpbuf = f.read()
|
||||
|
||||
outbuf = convert_from_hex_to_uf2(inpbuf.decode("utf-8"))
|
||||
|
||||
write_file(target, outbuf)
|
||||
print("#########################################################")
|
||||
print(target + " is ready to flash to target device")
|
||||
print("#########################################################")
|
||||
|
||||
|
||||
# Add callback after .hex file was created
|
||||
env.AddPostAction("$BUILD_DIR/${PROGNAME}.hex", create_uf2)
|
||||
|
||||
# UF2 creation taken from uf2conv.py
|
||||
UF2_MAGIC_START0 = 0x0A324655 # "UF2\n"
|
||||
UF2_MAGIC_START1 = 0x9E5D5157 # Randomly selected
|
||||
UF2_MAGIC_END = 0x0AB16F30 # Ditto
|
||||
|
||||
familyid = 0xADA52840
|
||||
|
||||
|
||||
class Block:
|
||||
def __init__(self, addr):
|
||||
self.addr = addr
|
||||
self.bytes = bytearray(256)
|
||||
|
||||
def encode(self, blockno, numblocks):
|
||||
global familyid
|
||||
flags = 0x0
|
||||
if familyid:
|
||||
flags |= 0x2000
|
||||
hd = struct.pack("<IIIIIIII",
|
||||
UF2_MAGIC_START0, UF2_MAGIC_START1,
|
||||
flags, self.addr, 256, blockno, numblocks, familyid)
|
||||
hd += self.bytes[0:256]
|
||||
while len(hd) < 512 - 4:
|
||||
hd += b"\x00"
|
||||
hd += struct.pack("<I", UF2_MAGIC_END)
|
||||
return hd
|
||||
|
||||
|
||||
def write_file(name, buf):
|
||||
with open(name, "wb") as f:
|
||||
f.write(buf)
|
||||
# print("Wrote %d bytes to %s." % (len(buf), name))
|
||||
|
||||
|
||||
def convert_from_hex_to_uf2(buf):
|
||||
global appstartaddr
|
||||
appstartaddr = None
|
||||
upper = 0
|
||||
currblock = None
|
||||
blocks = []
|
||||
for line in buf.split('\n'):
|
||||
if line[0] != ":":
|
||||
continue
|
||||
i = 1
|
||||
rec = []
|
||||
while i < len(line) - 1:
|
||||
rec.append(int(line[i:i+2], 16))
|
||||
i += 2
|
||||
tp = rec[3]
|
||||
if tp == 4:
|
||||
upper = ((rec[4] << 8) | rec[5]) << 16
|
||||
elif tp == 2:
|
||||
upper = ((rec[4] << 8) | rec[5]) << 4
|
||||
assert (upper & 0xffff) == 0
|
||||
elif tp == 1:
|
||||
break
|
||||
elif tp == 0:
|
||||
addr = upper | (rec[1] << 8) | rec[2]
|
||||
if appstartaddr == None:
|
||||
appstartaddr = addr
|
||||
i = 4
|
||||
while i < len(rec) - 1:
|
||||
if not currblock or currblock.addr & ~0xff != addr & ~0xff:
|
||||
currblock = Block(addr & ~0xff)
|
||||
blocks.append(currblock)
|
||||
currblock.bytes[addr & 0xff] = rec[i]
|
||||
addr += 1
|
||||
i += 1
|
||||
numblocks = len(blocks)
|
||||
resfile = b""
|
||||
for i in range(0, numblocks):
|
||||
resfile += blocks[i].encode(i, numblocks)
|
||||
return resfile
|
27
variants/rak2560/platformio.ini
Normal file
27
variants/rak2560/platformio.ini
Normal file
@ -0,0 +1,27 @@
|
||||
; The very slick RAK wireless RAK 4631 / 4630 board - Unified firmware for 5005/19003, with or without OLED RAK 1921
|
||||
[env:rak2560]
|
||||
extends = nrf52840_base
|
||||
board = wiscore_rak4631
|
||||
board_check = true
|
||||
build_flags = ${nrf52840_base.build_flags} -Ivariants/rak4631 -D RAK_4631
|
||||
-L "${platformio.libdeps_dir}/${this.__env__}/bsec2/src/cortex-m4/fpv4-sp-d16-hard"
|
||||
-DGPS_POWER_TOGGLE ; comment this line to disable triple press function on the user button to turn off gps entirely.
|
||||
-DEINK_DISPLAY_MODEL=GxEPD2_213_BN
|
||||
-DEINK_WIDTH=250
|
||||
-DEINK_HEIGHT=122
|
||||
-DHAS_RAKPROT=1 ; Define if RAk OneWireSerial is used (disables GPS)
|
||||
build_src_filter = ${nrf52_base.build_src_filter} +<../variants/rak4631> +<mesh/eth/> +<mesh/api/> +<mqtt/>
|
||||
lib_deps =
|
||||
${nrf52840_base.lib_deps}
|
||||
${networking_base.lib_deps}
|
||||
melopero/Melopero RV3028@^1.1.0
|
||||
https://github.com/RAKWireless/RAK13800-W5100S.git#1.0.2
|
||||
rakwireless/RAKwireless NCP5623 RGB LED library@^1.0.2
|
||||
beegee-tokyo/RAKwireless RAK12034@^1.0.0
|
||||
https://github.com/beegee-tokyo/RAK-OneWireSerial.git
|
||||
debug_tool = jlink
|
||||
; If not set we will default to uploading over serial (first it forces bootloader entry by talking 1200bps to cdcacm)
|
||||
;upload_protocol = jlink
|
||||
extra_scripts =
|
||||
${env.extra_scripts}
|
||||
../firmware/variants/rak2560/create_uf2.py
|
@ -100,9 +100,9 @@ static const uint8_t AREF = PIN_AREF;
|
||||
#define PIN_SERIAL1_RX (15)
|
||||
#define PIN_SERIAL1_TX (16)
|
||||
|
||||
// Connected to Jlink CDC
|
||||
#define PIN_SERIAL2_RX (8)
|
||||
#define PIN_SERIAL2_TX (6)
|
||||
// Connected to Serial 2
|
||||
#define PIN_SERIAL2_RX (19)
|
||||
#define PIN_SERIAL2_TX (20)
|
||||
|
||||
/*
|
||||
* SPI Interfaces
|
||||
@ -228,9 +228,18 @@ SO GPIO 39/TXEN MAY NOT BE DEFINED FOR SUCCESSFUL OPERATION OF THE SX1262 - TG
|
||||
// #define PIN_GPS_EN PIN_3V3_EN
|
||||
#define PIN_GPS_PPS (17) // Pulse per second input from the GPS
|
||||
|
||||
// On RAK2560 the GPS is be on a different UART
|
||||
#ifdef HAS_RAKPROT
|
||||
// #define GPS_RX_PIN PIN_SERIAL2_RX
|
||||
// #define GPS_TX_PIN PIN_SERIAL2_TX
|
||||
// #define PIN_GPS_EN PIN_3V3_EN
|
||||
// Disable GPS
|
||||
#define MESHTASTIC_EXCLUDE_GPS 1
|
||||
#else
|
||||
// Enable GPS
|
||||
#define GPS_RX_PIN PIN_SERIAL1_RX
|
||||
#define GPS_TX_PIN PIN_SERIAL1_TX
|
||||
|
||||
#endif
|
||||
// Define pin to enable GPS toggle (set GPIO to LOW) via user button triple press
|
||||
|
||||
// RAK12002 RTC Module
|
||||
@ -257,6 +266,21 @@ SO GPIO 39/TXEN MAY NOT BE DEFINED FOR SUCCESSFUL OPERATION OF THE SX1262 - TG
|
||||
|
||||
#define RAK_4631 1
|
||||
|
||||
#ifdef HAS_RAKPROT
|
||||
|
||||
#define HALF_UART_PIN PIN_SERIAL1_RX
|
||||
|
||||
#if defined(GPS_RX_PIN) && (GPS_RX_PIN == HALF_UART_PIN)
|
||||
#error pin 15 collision
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(GPS_TX_PIN) && (GPS_RX_PIN == HALF_UART_PIN)
|
||||
#error pin 15 collision
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#define PIN_ETHERNET_RESET 21
|
||||
#define PIN_ETHERNET_SS PIN_EINK_CS
|
||||
#define ETH_SPI_PORT SPI1
|
||||
|
Loading…
Reference in New Issue
Block a user