mirror of
https://github.com/meshtastic/firmware.git
synced 2025-04-24 01:16:55 +00:00
commit
0b358674ff
@ -1,3 +1,3 @@
|
||||
|
||||
|
||||
JLinkGDBServerCLExe -if SWD -select USB -port 2331 -device NRF52840_XXAA
|
||||
JLinkGDBServerCLExe -if SWD -select USB -port 2331 -device NRF52840_XXAA -SuppressInfoUpdateFW -DisableAutoUpdateFW -rtos GDBServer/RTOSPlugin_FreeRTOS
|
||||
|
@ -29,6 +29,7 @@ You probably don't care about this section - skip to the next one.
|
||||
* DONE release protobufs
|
||||
* DONE release to developers
|
||||
* DONE fix setch-fast in python tool
|
||||
* turn off fault 8: https://github.com/meshtastic/Meshtastic-device/issues/734
|
||||
* age out pendingrequests in the python API
|
||||
* DONE stress test channel download from python, sometimes it seems like we don't get all replies, bug was due to simultaneous android connection
|
||||
* DONE combine acks and responses in a single message if possible (do routing plugin LAST and drop ACK if someone else has already replied)
|
||||
@ -83,17 +84,32 @@ You probably don't care about this section - skip to the next one.
|
||||
|
||||
eink:
|
||||
|
||||
* DONE check email of reported issues
|
||||
* DONE turn off vbus driving (in bootloader)
|
||||
* new battery level sensing
|
||||
* measure current draw
|
||||
* current draw no good
|
||||
* DONE: fix backlight
|
||||
* USB is busted because of power enable mode?
|
||||
* DONE - USB is busted because of power enable mode?
|
||||
* test CPU voltage? something is bad with RAM (removing eink module does not help)
|
||||
* test that board leaves bootloader always
|
||||
* test USB - works in bootloader
|
||||
* test LEDs
|
||||
* Test BME280
|
||||
* test gps
|
||||
* check GPS fast locking
|
||||
* tested! dlora
|
||||
* test eink backlight
|
||||
* tested! eink
|
||||
* test buttons
|
||||
* test battery charging
|
||||
* test serial flash
|
||||
* send updated app and bootloader image
|
||||
* OHH BME280! THAT IS GREAT!
|
||||
* make new screen work, ask for datasheet
|
||||
* say I think you could ship this
|
||||
* leds seem busted
|
||||
* usb doesn't stay connected
|
||||
* check GPS works
|
||||
* check GPS fast locking
|
||||
* fix hw_model: "nrf52unknown"
|
||||
* use larger icon for meshtastic logo
|
||||
* send email about variants & faster flash programming - https://github.com/geeksville/Meshtastic-esp32/commit/f110225173a77326aac029321cdb6491bfa640f6
|
||||
* send PR for bootloader
|
||||
* fix nrf52 time/date
|
||||
|
@ -16,6 +16,7 @@ default_envs = tbeam
|
||||
;default_envs = tlora-v2
|
||||
;default_envs = lora-relay-v1 # nrf board
|
||||
;default_envs = eink
|
||||
;default_envs = nrf52840dk-geeksville
|
||||
;default_envs = linux # lora-relay-v1 # nrf52840dk-geeksville # linux # or if you'd like to change the default to something like lora-relay-v1 put that here
|
||||
|
||||
[common]
|
||||
@ -33,6 +34,8 @@ default_envs = tbeam
|
||||
extra_scripts = bin/platformio-custom.py
|
||||
|
||||
; note: we add src to our include search path so that lmic_project_config can override
|
||||
; note: TINYGPS_OPTION_NO_CUSTOM_FIELDS is VERY important. We don't use custom fields and somewhere in that pile
|
||||
; of code is a heap corruption bug!
|
||||
; FIXME: fix lib/BluetoothOTA dependency back on src/ so we can remove -Isrc
|
||||
build_flags = -Wno-missing-field-initializers
|
||||
-Wno-format
|
||||
@ -40,7 +43,7 @@ build_flags = -Wno-missing-field-initializers
|
||||
-DHW_VERSION_${sysenv.COUNTRY}
|
||||
-DHW_VERSION=${sysenv.HW_VERSION}
|
||||
-DUSE_THREAD_NAMES
|
||||
-DTINYGPSPLUS_OPTION_NO_CUSTOM_FIELDS
|
||||
-DTINYGPS_OPTION_NO_CUSTOM_FIELDS
|
||||
|
||||
; leave this commented out to avoid breaking Windows
|
||||
;upload_port = /dev/ttyUSB0
|
||||
@ -74,7 +77,7 @@ lib_deps =
|
||||
https://github.com/meshtastic/arduino-fsm.git#2f106146071fc7bc620e1e8d4b88dc4e0266ce39
|
||||
https://github.com/meshtastic/SparkFun_Ublox_Arduino_Library.git#31015a55e630a2df77d9d714669c621a5bf355ad
|
||||
https://github.com/meshtastic/RadioLib.git#07de964e929238949035fb0d5887026a3058df1a
|
||||
https://github.com/meshtastic/TinyGPSPlus.git#9c1d584d2469523381e077b0b9c1bf868d6c0206
|
||||
https://github.com/meshtastic/TinyGPSPlus.git#f0f47067ef2f67c856475933188251c1ef615e79
|
||||
https://github.com/meshtastic/AXP202X_Library.git#8404abb6d4b486748636bc6ad72d2a47baaf5460
|
||||
Wire ; explicitly needed here because the AXP202 library forgets to add it
|
||||
SPI
|
||||
@ -184,7 +187,6 @@ src_filter =
|
||||
; platform = nordicnrf52
|
||||
platform = https://github.com/meshtastic/platform-nordicnrf52.git#1a2639a6b0f79b5df66bea3e3089f0d5285fdc63
|
||||
extends = arduino_base
|
||||
debug_tool = jlink
|
||||
build_type = debug ; I'm debugging with ICE a lot now
|
||||
; note: liboberon provides the AES256 implementation for NRF52 (though not using the hardware acceleration of the NRF52840 - FIXME)
|
||||
build_flags =
|
||||
@ -198,6 +200,26 @@ lib_ignore =
|
||||
BluetoothOTA
|
||||
monitor_port = /dev/ttyACM1
|
||||
|
||||
# we pass in options to jlink so it can understand freertos (note: we don't use "jlink" as the tool)
|
||||
debug_tool = jlink
|
||||
debug_port = :2331
|
||||
# Note: the ARGUMENTS MUST BE on multiple lines. Otherwise platformio/commands/debug/helpers.py misparses everything into the "executable"
|
||||
# attribute and leaves "arguments" empty
|
||||
# /home/kevinh/.platformio/packages/tool-jlink/JLinkGDBServerCLExe
|
||||
debug_server =
|
||||
/usr/bin/JLinkGDBServerCLExe
|
||||
-singlerun
|
||||
-if
|
||||
SWD
|
||||
-select
|
||||
USB
|
||||
-device
|
||||
nRF52840_xxAA
|
||||
-port
|
||||
2331
|
||||
-rtos
|
||||
GDBServer/RTOSPlugin_FreeRTOS
|
||||
|
||||
debug_extra_cmds =
|
||||
source gdbinit
|
||||
|
||||
|
2
proto
2
proto
@ -1 +1 @@
|
||||
Subproject commit 7c025b9a4d54bb410ec17ee653122861b413f177
|
||||
Subproject commit e56f2770c33216ba94f289e2fb7f0b2dfd33aca2
|
@ -1,9 +1,9 @@
|
||||
#include "RedirectablePrint.h"
|
||||
#include "concurrency/OSThread.h"
|
||||
#include "configuration.h"
|
||||
#include <assert.h>
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
#include "concurrency/OSThread.h"
|
||||
|
||||
/**
|
||||
* A printer that doesn't go anywhere
|
||||
@ -20,7 +20,7 @@ size_t RedirectablePrint::write(uint8_t c)
|
||||
{
|
||||
// Always send the characters to our segger JTAG debugger
|
||||
#ifdef SEGGER_STDOUT_CH
|
||||
SEGGER_RTT_PutCharSkip(SEGGER_STDOUT_CH, c);
|
||||
SEGGER_RTT_PutChar(SEGGER_STDOUT_CH, c);
|
||||
#endif
|
||||
|
||||
dest->write(c);
|
||||
@ -38,7 +38,7 @@ size_t RedirectablePrint::vprintf(const char *format, va_list arg)
|
||||
va_end(arg);
|
||||
return 0;
|
||||
};
|
||||
if (len >= printBufLen) {
|
||||
if (len >= (int)printBufLen) {
|
||||
delete[] printBuf;
|
||||
printBufLen *= 2;
|
||||
printBuf = new char[printBufLen];
|
||||
@ -55,45 +55,52 @@ size_t RedirectablePrint::vprintf(const char *format, va_list arg)
|
||||
|
||||
size_t RedirectablePrint::logDebug(const char *format, ...)
|
||||
{
|
||||
va_list arg;
|
||||
va_start(arg, format);
|
||||
|
||||
// Cope with 0 len format strings, but look for new line terminator
|
||||
bool hasNewline = *format && format[strlen(format) - 1] == '\n';
|
||||
|
||||
size_t r = 0;
|
||||
|
||||
// If we are the first message on a report, include the header
|
||||
if (!isContinuationMessage) {
|
||||
struct timeval tv;
|
||||
if (!gettimeofday(&tv, NULL)) {
|
||||
long hms = tv.tv_sec % SEC_PER_DAY;
|
||||
//hms += tz.tz_dsttime * SEC_PER_HOUR;
|
||||
//hms -= tz.tz_minuteswest * SEC_PER_MIN;
|
||||
// mod `hms` to ensure in positive range of [0...SEC_PER_DAY)
|
||||
hms = (hms + SEC_PER_DAY) % SEC_PER_DAY;
|
||||
if (!inDebugPrint) {
|
||||
inDebugPrint = true;
|
||||
|
||||
// Tear apart hms into h:m:s
|
||||
int hour = hms / SEC_PER_HOUR;
|
||||
int min = (hms % SEC_PER_HOUR) / SEC_PER_MIN;
|
||||
int sec = (hms % SEC_PER_HOUR) % SEC_PER_MIN; // or hms % SEC_PER_MIN
|
||||
va_list arg;
|
||||
va_start(arg, format);
|
||||
|
||||
r += printf("%02d:%02d:%02d %u ", hour, min, sec, millis() / 1000);
|
||||
} else
|
||||
r += printf("??:??:?? %u ", millis() / 1000);
|
||||
// Cope with 0 len format strings, but look for new line terminator
|
||||
bool hasNewline = *format && format[strlen(format) - 1] == '\n';
|
||||
|
||||
auto thread = concurrency::OSThread::currentThread;
|
||||
if(thread) {
|
||||
print("[");
|
||||
print(thread->ThreadName);
|
||||
print("] ");
|
||||
// If we are the first message on a report, include the header
|
||||
if (!isContinuationMessage) {
|
||||
struct timeval tv;
|
||||
if (!gettimeofday(&tv, NULL)) {
|
||||
long hms = tv.tv_sec % SEC_PER_DAY;
|
||||
// hms += tz.tz_dsttime * SEC_PER_HOUR;
|
||||
// hms -= tz.tz_minuteswest * SEC_PER_MIN;
|
||||
// mod `hms` to ensure in positive range of [0...SEC_PER_DAY)
|
||||
hms = (hms + SEC_PER_DAY) % SEC_PER_DAY;
|
||||
|
||||
// Tear apart hms into h:m:s
|
||||
int hour = hms / SEC_PER_HOUR;
|
||||
int min = (hms % SEC_PER_HOUR) / SEC_PER_MIN;
|
||||
int sec = (hms % SEC_PER_HOUR) % SEC_PER_MIN; // or hms % SEC_PER_MIN
|
||||
|
||||
r += printf("%02d:%02d:%02d %u ", hour, min, sec, millis() / 1000);
|
||||
} else
|
||||
r += printf("??:??:?? %u ", millis() / 1000);
|
||||
|
||||
auto thread = concurrency::OSThread::currentThread;
|
||||
if (thread) {
|
||||
print("[");
|
||||
// printf("%p ", thread);
|
||||
// assert(thread->ThreadName.length());
|
||||
print(thread->ThreadName);
|
||||
print("] ");
|
||||
}
|
||||
}
|
||||
|
||||
r += vprintf(format, arg);
|
||||
va_end(arg);
|
||||
|
||||
isContinuationMessage = !hasNewline;
|
||||
inDebugPrint = false;
|
||||
}
|
||||
|
||||
r += vprintf(format, arg);
|
||||
va_end(arg);
|
||||
|
||||
isContinuationMessage = !hasNewline;
|
||||
|
||||
return r;
|
||||
}
|
@ -19,6 +19,8 @@ class RedirectablePrint : public Print
|
||||
/// Used to allow multiple logDebug messages to appear on a single log line
|
||||
bool isContinuationMessage = false;
|
||||
|
||||
volatile bool inDebugPrint = false;
|
||||
|
||||
public:
|
||||
RedirectablePrint(Print *_dest) : dest(_dest) {}
|
||||
|
||||
|
@ -1,13 +1,21 @@
|
||||
#include "SerialConsole.h"
|
||||
#include "NodeDB.h"
|
||||
#include "PowerFSM.h"
|
||||
#include "configuration.h"
|
||||
#include "NodeDB.h"
|
||||
#include <Arduino.h>
|
||||
|
||||
#define Port Serial
|
||||
|
||||
SerialConsole console;
|
||||
|
||||
void consolePrintf(const char *format, ...)
|
||||
{
|
||||
va_list arg;
|
||||
va_start(arg, format);
|
||||
console.vprintf(format, arg);
|
||||
va_end(arg);
|
||||
}
|
||||
|
||||
SerialConsole::SerialConsole() : StreamAPI(&Port), RedirectablePrint(&Port)
|
||||
{
|
||||
canWrite = false; // We don't send packets to our port until it has talked to us first
|
||||
@ -29,7 +37,7 @@ void SerialConsole::init()
|
||||
void SerialConsole::handleToRadio(const uint8_t *buf, size_t len)
|
||||
{
|
||||
// Turn off debug serial printing once the API is activated, because other threads could print and corrupt packets
|
||||
if(!radioConfig.preferences.debug_log_enabled)
|
||||
if (!radioConfig.preferences.debug_log_enabled)
|
||||
setDestination(&noopPrint);
|
||||
canWrite = true;
|
||||
|
||||
|
@ -32,4 +32,7 @@ class SerialConsole : public StreamAPI, public RedirectablePrint
|
||||
virtual void onConnectionChanged(bool connected);
|
||||
};
|
||||
|
||||
// A simple wrapper to allow non class aware code write to the console
|
||||
void consolePrintf(const char *format, ...);
|
||||
|
||||
extern SerialConsole console;
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include "concurrency/BinarySemaphoreFreeRTOS.h"
|
||||
#include "configuration.h"
|
||||
#include <assert.h>
|
||||
|
||||
#ifdef HAS_FREE_RTOS
|
||||
|
||||
@ -9,6 +10,7 @@ namespace concurrency
|
||||
BinarySemaphoreFreeRTOS::BinarySemaphoreFreeRTOS()
|
||||
{
|
||||
semaphore = xSemaphoreCreateBinary();
|
||||
assert(semaphore);
|
||||
}
|
||||
|
||||
BinarySemaphoreFreeRTOS::~BinarySemaphoreFreeRTOS()
|
||||
|
@ -25,7 +25,7 @@ uint8_t GPS::i2cAddress = 0;
|
||||
|
||||
GPS *gps;
|
||||
|
||||
/// Multiple GPS instances might use the same serial port (in sequence), but we can
|
||||
/// Multiple GPS instances might use the same serial port (in sequence), but we can
|
||||
/// only init that port once.
|
||||
static bool didSerialInit;
|
||||
|
||||
@ -33,7 +33,7 @@ bool GPS::setupGPS()
|
||||
{
|
||||
if (_serial_gps && !didSerialInit) {
|
||||
didSerialInit = true;
|
||||
|
||||
|
||||
#ifdef GPS_RX_PIN
|
||||
_serial_gps->begin(GPS_BAUDRATE, SERIAL_8N1, GPS_RX_PIN, GPS_TX_PIN);
|
||||
#else
|
||||
@ -73,6 +73,13 @@ bool GPS::setup()
|
||||
return ok;
|
||||
}
|
||||
|
||||
GPS::~GPS()
|
||||
{
|
||||
// we really should unregister our sleep observer
|
||||
notifySleepObserver.unobserve();
|
||||
notifyDeepSleepObserver.unobserve();
|
||||
}
|
||||
|
||||
// Allow defining the polarity of the WAKE output. default is active high
|
||||
#ifndef GPS_WAKE_ACTIVE
|
||||
#define GPS_WAKE_ACTIVE 1
|
||||
@ -86,8 +93,8 @@ void GPS::wake()
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void GPS::sleep() {
|
||||
void GPS::sleep()
|
||||
{
|
||||
#ifdef PIN_GPS_WAKE
|
||||
digitalWrite(PIN_GPS_WAKE, GPS_WAKE_ACTIVE ? 0 : 1);
|
||||
pinMode(PIN_GPS_WAKE, OUTPUT);
|
||||
@ -158,7 +165,8 @@ uint32_t GPS::getWakeTime() const
|
||||
return t; // already maxint
|
||||
|
||||
if (t == 0)
|
||||
t = radioConfig.preferences.is_router ? 5 * 60 : 15 * 60; // Allow up to 15 mins for each attempt (probably will be much less if we can find sats) or less if a router
|
||||
t = radioConfig.preferences.is_router ? 5 * 60 : 15 * 60; // Allow up to 15 mins for each attempt (probably will be much
|
||||
// less if we can find sats) or less if a router
|
||||
|
||||
t *= 1000; // msecs
|
||||
|
||||
@ -179,8 +187,8 @@ uint32_t GPS::getSleepTime() const
|
||||
if (t == UINT32_MAX)
|
||||
return t; // already maxint
|
||||
|
||||
if (t == 0) // default - unset in preferences
|
||||
t = radioConfig.preferences.is_router ? 24 * 60 * 60 : 2 * 60; // 2 mins or once per day for routers
|
||||
if (t == 0) // default - unset in preferences
|
||||
t = radioConfig.preferences.is_router ? 24 * 60 * 60 : 2 * 60; // 2 mins or once per day for routers
|
||||
|
||||
t *= 1000;
|
||||
|
||||
|
@ -47,7 +47,7 @@ class GPS : private concurrency::OSThread
|
||||
|
||||
GPS() : concurrency::OSThread("GPS") {}
|
||||
|
||||
virtual ~GPS() {} // FIXME, we really should unregister our sleep observer
|
||||
virtual ~GPS();
|
||||
|
||||
/** We will notify this observable anytime GPS state has changed meaningfully */
|
||||
Observable<const meshtastic::GPSStatus *> newStatus;
|
||||
|
@ -143,11 +143,13 @@ static void drawBootScreen(OLEDDisplay *display, OLEDDisplayUiState *state, int1
|
||||
drawIconScreen(region, display, state, x, y);
|
||||
}
|
||||
|
||||
#ifdef HAS_EINK
|
||||
/// Used on eink displays while in deep sleep
|
||||
static void drawSleepScreen(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
|
||||
{
|
||||
drawIconScreen("Sleeping...", display, state, x, y);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void drawPluginFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
|
||||
{
|
||||
@ -791,7 +793,8 @@ void Screen::setup()
|
||||
powerStatusObserver.observe(&powerStatus->onNewStatus);
|
||||
gpsStatusObserver.observe(&gpsStatus->onNewStatus);
|
||||
nodeStatusObserver.observe(&nodeStatus->onNewStatus);
|
||||
textMessageObserver.observe(textMessagePlugin);
|
||||
if(textMessagePlugin)
|
||||
textMessageObserver.observe(textMessagePlugin);
|
||||
}
|
||||
|
||||
void Screen::forceDisplay()
|
||||
@ -849,7 +852,7 @@ int32_t Screen::runOnce()
|
||||
free(cmd.print_text);
|
||||
break;
|
||||
default:
|
||||
DEBUG_MSG("BUG: invalid cmd");
|
||||
DEBUG_MSG("BUG: invalid cmd\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
11
src/main.cpp
11
src/main.cpp
@ -279,7 +279,13 @@ void setup()
|
||||
concurrency::hasBeenSetup = true;
|
||||
|
||||
#ifdef SEGGER_STDOUT_CH
|
||||
SEGGER_RTT_ConfigUpBuffer(SEGGER_STDOUT_CH, NULL, NULL, 1024, SEGGER_RTT_MODE_NO_BLOCK_TRIM);
|
||||
auto mode = true ? SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL : SEGGER_RTT_MODE_NO_BLOCK_TRIM;
|
||||
#ifdef NRF52840_XXAA
|
||||
auto buflen = 4096; // this board has a fair amount of ram
|
||||
#else
|
||||
auto buflen = 256; // this board has a fair amount of ram
|
||||
#endif
|
||||
SEGGER_RTT_ConfigUpBuffer(SEGGER_STDOUT_CH, NULL, NULL, buflen, mode);
|
||||
#endif
|
||||
|
||||
#ifdef USE_SEGGER
|
||||
@ -583,6 +589,9 @@ void loop()
|
||||
#ifndef NO_ESP32
|
||||
esp32Loop();
|
||||
#endif
|
||||
#ifdef NRF52_SERIES
|
||||
nrf52Loop();
|
||||
#endif
|
||||
|
||||
// For debugging
|
||||
// if (rIf) ((RadioLibInterface *)rIf)->isActivelyReceiving();
|
||||
|
@ -13,7 +13,7 @@ Channels channels;
|
||||
uint8_t xorHash(const uint8_t *p, size_t len)
|
||||
{
|
||||
uint8_t code = 0;
|
||||
for (int i = 0; i < len; i++)
|
||||
for (size_t i = 0; i < len; i++)
|
||||
code ^= p[i];
|
||||
return code;
|
||||
}
|
||||
|
@ -101,25 +101,30 @@ template <class T> class MemoryPool : public Allocator<T>
|
||||
/// Return a buffer for use by others
|
||||
virtual void release(T *p)
|
||||
{
|
||||
assert(dead.enqueue(p, 0));
|
||||
assert(p >= buf &&
|
||||
(size_t)(p - buf) <
|
||||
maxElements); // sanity check to make sure a programmer didn't free something that didn't come from this pool
|
||||
assert(dead.enqueue(p, 0));
|
||||
}
|
||||
|
||||
#ifdef HAS_FREE_RTOS
|
||||
/// Return a buffer from an ISR, if higherPriWoken is set to true you have some work to do ;-)
|
||||
void releaseFromISR(T *p, BaseType_t *higherPriWoken)
|
||||
{
|
||||
assert(dead.enqueueFromISR(p, higherPriWoken));
|
||||
assert(p >= buf &&
|
||||
(size_t)(p - buf) <
|
||||
maxElements); // sanity check to make sure a programmer didn't free something that didn't come from this pool
|
||||
assert(dead.enqueueFromISR(p, higherPriWoken));
|
||||
}
|
||||
#endif
|
||||
|
||||
protected:
|
||||
/// Return a queable object which has been prefilled with zeros - allow timeout to wait for available buffers (you
|
||||
/// probably don't want this version).
|
||||
virtual T *alloc(TickType_t maxWait) { return dead.dequeuePtr(maxWait); }
|
||||
virtual T *alloc(TickType_t maxWait)
|
||||
{
|
||||
T *p = dead.dequeuePtr(maxWait);
|
||||
assert(p);
|
||||
return p;
|
||||
}
|
||||
};
|
||||
|
@ -25,7 +25,8 @@ typedef enum _CriticalErrorCode {
|
||||
CriticalErrorCode_UBloxInitFailed = 5,
|
||||
CriticalErrorCode_NoAXP192 = 6,
|
||||
CriticalErrorCode_InvalidRadioSetting = 7,
|
||||
CriticalErrorCode_TransmitFailed = 8
|
||||
CriticalErrorCode_TransmitFailed = 8,
|
||||
CriticalErrorCode_Brownout = 9
|
||||
} CriticalErrorCode;
|
||||
|
||||
typedef enum _Routing_Error {
|
||||
@ -177,8 +178,8 @@ typedef struct _ToRadio {
|
||||
#define _Constants_ARRAYSIZE ((Constants)(Constants_DATA_PAYLOAD_LEN+1))
|
||||
|
||||
#define _CriticalErrorCode_MIN CriticalErrorCode_None
|
||||
#define _CriticalErrorCode_MAX CriticalErrorCode_TransmitFailed
|
||||
#define _CriticalErrorCode_ARRAYSIZE ((CriticalErrorCode)(CriticalErrorCode_TransmitFailed+1))
|
||||
#define _CriticalErrorCode_MAX CriticalErrorCode_Brownout
|
||||
#define _CriticalErrorCode_ARRAYSIZE ((CriticalErrorCode)(CriticalErrorCode_Brownout+1))
|
||||
|
||||
#define _Routing_Error_MIN Routing_Error_NONE
|
||||
#define _Routing_Error_MAX Routing_Error_TOO_LARGE
|
||||
|
@ -82,8 +82,34 @@ extern "C" void HardFault_Impl(uint32_t stack[])
|
||||
// while (1) ;
|
||||
}
|
||||
|
||||
#ifndef INC_FREERTOS_H
|
||||
// This is a generic cortex M entrypoint that doesn't assume freertos
|
||||
|
||||
extern "C" void HardFault_Handler(void)
|
||||
{
|
||||
asm volatile(" mrs r0,msp\n"
|
||||
" b HardFault_Impl \n");
|
||||
}
|
||||
#else
|
||||
|
||||
/* The prototype shows it is a naked function - in effect this is just an
|
||||
assembly function. */
|
||||
extern "C" void HardFault_Handler( void ) __attribute__( ( naked ) );
|
||||
|
||||
/* The fault handler implementation calls a function called
|
||||
prvGetRegistersFromStack(). */
|
||||
extern "C" void HardFault_Handler(void)
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" tst lr, #4 \n"
|
||||
" ite eq \n"
|
||||
" mrseq r0, msp \n"
|
||||
" mrsne r0, psp \n"
|
||||
" ldr r1, [r0, #24] \n"
|
||||
" ldr r2, handler2_address_const \n"
|
||||
" bx r2 \n"
|
||||
" handler2_address_const: .word HardFault_Impl \n"
|
||||
);
|
||||
}
|
||||
#endif
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include "NRF52Bluetooth.h"
|
||||
#include "configuration.h"
|
||||
#include "error.h"
|
||||
#include "graphics/TFTDisplay.h"
|
||||
#include <SPI.h>
|
||||
#include <Wire.h>
|
||||
@ -51,14 +52,14 @@ void getMacAddr(uint8_t *dmac)
|
||||
NRF52Bluetooth *nrf52Bluetooth;
|
||||
|
||||
static bool bleOn = false;
|
||||
static const bool enableBle = false; // Set to false for easier debugging
|
||||
static const bool useSoftDevice = false; // Set to false for easier debugging
|
||||
|
||||
void setBluetoothEnable(bool on)
|
||||
{
|
||||
if (on != bleOn) {
|
||||
if (on) {
|
||||
if (!nrf52Bluetooth) {
|
||||
if (!enableBle)
|
||||
if (!useSoftDevice)
|
||||
DEBUG_MSG("DISABLING NRF52 BLUETOOTH WHILE DEBUGGING\n");
|
||||
else {
|
||||
nrf52Bluetooth = new NRF52Bluetooth();
|
||||
@ -87,6 +88,49 @@ int printf(const char *fmt, ...)
|
||||
|
||||
#include "BQ25713.h"
|
||||
|
||||
void initBrownout()
|
||||
{
|
||||
auto vccthresh = POWER_POFCON_THRESHOLD_V28;
|
||||
auto vcchthresh = POWER_POFCON_THRESHOLDVDDH_V27;
|
||||
|
||||
if (useSoftDevice) {
|
||||
auto err_code = sd_power_pof_enable(POWER_POFCON_POF_Enabled);
|
||||
assert(err_code == NRF_SUCCESS);
|
||||
|
||||
err_code = sd_power_pof_threshold_set(vccthresh);
|
||||
assert(err_code == NRF_SUCCESS);
|
||||
}
|
||||
else {
|
||||
NRF_POWER->POFCON = POWER_POFCON_POF_Msk | (vccthresh << POWER_POFCON_THRESHOLD_Pos) | (vcchthresh << POWER_POFCON_THRESHOLDVDDH_Pos);
|
||||
}
|
||||
}
|
||||
|
||||
void checkSDEvents()
|
||||
{
|
||||
if (useSoftDevice) {
|
||||
uint32_t evt;
|
||||
while (NRF_ERROR_NOT_FOUND == sd_evt_get(&evt)) {
|
||||
switch (evt) {
|
||||
case NRF_EVT_POWER_FAILURE_WARNING:
|
||||
recordCriticalError(CriticalErrorCode_Brownout);
|
||||
break;
|
||||
|
||||
default:
|
||||
DEBUG_MSG("Unexpected SDevt %d\n", evt);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if(NRF_POWER->EVENTS_POFWARN)
|
||||
recordCriticalError(CriticalErrorCode_Brownout);
|
||||
}
|
||||
}
|
||||
|
||||
void nrf52Loop()
|
||||
{
|
||||
checkSDEvents();
|
||||
}
|
||||
|
||||
void nrf52Setup()
|
||||
{
|
||||
|
||||
@ -112,6 +156,8 @@ void nrf52Setup()
|
||||
// randomSeed(r);
|
||||
DEBUG_MSG("FIXME, call randomSeed\n");
|
||||
// ::printf("TESTING PRINTF\n");
|
||||
|
||||
initBrownout();
|
||||
}
|
||||
|
||||
void cpuDeepSleep(uint64_t msecToWake)
|
||||
@ -128,7 +174,7 @@ void cpuDeepSleep(uint64_t msecToWake)
|
||||
// https://devzone.nordicsemi.com/f/nordic-q-a/48919/ram-retention-settings-with-softdevice-enabled
|
||||
|
||||
auto ok = sd_power_system_off();
|
||||
if(ok != NRF_SUCCESS) {
|
||||
if (ok != NRF_SUCCESS) {
|
||||
DEBUG_MSG("FIXME: Ignoring soft device (EasyDMA pending?) and forcing system-off!\n");
|
||||
NRF_POWER->SYSTEMOFF = 1;
|
||||
}
|
||||
|
@ -114,7 +114,8 @@ int32_t ExternalNotificationPlugin::runOnce()
|
||||
|
||||
return (INT32_MAX);
|
||||
}
|
||||
|
||||
#else
|
||||
return INT32_MAX;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -19,9 +19,11 @@ bool NodeInfoPlugin::handleReceivedProtobuf(const MeshPacket &mp, const User *pp
|
||||
// Show new nodes on LCD screen
|
||||
if (wasBroadcast) {
|
||||
String lcd = String("Joined: ") + p.long_name + "\n";
|
||||
screen->print(lcd.c_str());
|
||||
if(screen)
|
||||
screen->print(lcd.c_str());
|
||||
}
|
||||
|
||||
// DEBUG_MSG("did handleReceived\n");
|
||||
return false; // Let others look at this message also if they want
|
||||
}
|
||||
|
||||
|
@ -124,7 +124,8 @@ int32_t SerialPlugin::runOnce()
|
||||
|
||||
return (INT32_MAX);
|
||||
}
|
||||
|
||||
#else
|
||||
return INT32_MAX;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -99,16 +99,16 @@ extern "C" {
|
||||
#define NUM_ANALOG_OUTPUTS (0)
|
||||
|
||||
// LEDs
|
||||
#define PIN_LED1 (0 + 13) // red (confirmed on 1.0 board)
|
||||
#define PIN_LED2 (0 + 14) // blue (seems busted!)
|
||||
#define PIN_LED3 (0 + 15) // green (seems busted!)
|
||||
#define PIN_LED1 (0 + 14) // 13 red (confirmed on 1.0 board)
|
||||
#define PIN_LED2 (0 + 15) // 14 blue
|
||||
#define PIN_LED3 (0 + 13) // 15 green
|
||||
|
||||
#define LED_RED PIN_LED3
|
||||
#define LED_GREEN PIN_LED1
|
||||
#define LED_BLUE PIN_LED2
|
||||
#define LED_BLUE PIN_LED1
|
||||
#define LED_GREEN PIN_LED2
|
||||
|
||||
#define LED_BUILTIN LED_GREEN
|
||||
#define LED_CONN PIN_BLUE
|
||||
#define LED_BUILTIN LED_BLUE
|
||||
#define LED_CONN PIN_GREEN
|
||||
|
||||
#define LED_STATE_ON 0 // State when LED is lit
|
||||
#define LED_INVERTED 1
|
||||
@ -192,6 +192,9 @@ External serial flash WP25R1635FZUIL0
|
||||
|
||||
// #define LORA_DISABLE_SENDING // Define this to disable transmission for testing (power testing etc...)
|
||||
|
||||
// #undef SX1262_CS
|
||||
// #define USE_SIM_RADIO // define to not use the lora radio hardware at all
|
||||
|
||||
/*
|
||||
* eink display pins
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user