Files
firmware/src/platform/nrf52/main-nrf52.cpp

201 lines
5.3 KiB
C++
Raw Normal View History

#include "configuration.h"
2023-01-21 14:34:29 +01:00
#include <Adafruit_nRFCrypto.h>
#include <SPI.h>
#include <Wire.h>
2020-04-23 12:47:41 -07:00
#include <assert.h>
2020-04-23 16:55:25 -07:00
#include <ble_gap.h>
#include <memory.h>
#include <stdio.h>
// #include <Adafruit_USBD_Device.h>
#include "NodeDB.h"
#include "error.h"
2023-02-03 08:50:10 -06:00
#include "main.h"
#ifdef BQ25703A_ADDR
#include "BQ25713.h"
#endif
2020-04-23 16:55:25 -07:00
2021-04-11 13:52:39 +08:00
static inline void debugger_break(void)
{
__asm volatile("bkpt #0x01\n\t"
"mov pc, lr\n\t");
2020-04-23 12:47:41 -07:00
}
2023-01-21 14:34:29 +01:00
bool loopCanSleep()
{
// turn off sleep only while connected via USB
// return true;
return !Serial; // the bool operator on the nrf52 serial class returns true if connected to a PC currently
// return !(TinyUSBDevice.mounted() && !TinyUSBDevice.suspended());
}
2020-04-23 12:47:41 -07:00
// handle standard gcc assert failures
2021-04-11 13:52:39 +08:00
void __attribute__((noreturn)) __assert_func(const char *file, int line, const char *func, const char *failedexpr)
{
LOG_ERROR("assert failed %s: %d, %s, test=%s\n", file, line, func, failedexpr);
2021-04-11 13:52:39 +08:00
// debugger_break(); FIXME doesn't work, possibly not for segger
// Reboot cpu
NVIC_SystemReset();
2020-04-23 16:55:25 -07:00
}
2021-04-11 13:52:39 +08:00
void getMacAddr(uint8_t *dmac)
{
2021-12-28 11:20:45 -06:00
const uint8_t *src = (const uint8_t *)NRF_FICR->DEVICEADDR;
dmac[5] = src[0];
dmac[4] = src[1];
dmac[3] = src[2];
dmac[2] = src[3];
dmac[1] = src[4];
dmac[0] = src[5] | 0xc0; // MSB high two bits get set elsewhere in the bluetooth stack
2020-04-23 18:02:28 -07:00
}
2021-04-12 13:25:55 +08:00
static void initBrownout()
{
auto vccthresh = POWER_POFCON_THRESHOLD_V17;
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);
// We don't bother with setting up brownout if soft device is disabled - because during production we always use softdevice
}
2020-04-23 18:02:28 -07:00
static bool bleOn = false;
2021-04-12 13:25:55 +08:00
static const bool useSoftDevice = true; // Set to false for easier debugging
2021-04-11 13:52:39 +08:00
void setBluetoothEnable(bool on)
{
if (on != bleOn && config.bluetooth.enabled == true) {
2021-04-11 13:52:39 +08:00
if (on) {
if (!nrf52Bluetooth) {
if (!useSoftDevice)
LOG_INFO("DISABLING NRF52 BLUETOOTH WHILE DEBUGGING\n");
2021-04-11 13:52:39 +08:00
else {
nrf52Bluetooth = new NRF52Bluetooth();
nrf52Bluetooth->setup();
2023-01-21 14:34:29 +01:00
2021-04-12 13:25:55 +08:00
// We delay brownout init until after BLE because BLE starts soft device
initBrownout();
2021-04-11 13:52:39 +08:00
}
}
} else if (nrf52Bluetooth) {
nrf52Bluetooth->shutdown();
2020-04-23 18:02:28 -07:00
}
2021-04-11 13:52:39 +08:00
bleOn = on;
2020-04-23 18:02:28 -07:00
}
}
/**
* Override printf to use the SEGGER output library (note - this does not effect the printf method on the debug console)
*/
2021-04-11 13:52:39 +08:00
int printf(const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
auto res = SEGGER_RTT_vprintf(0, fmt, &args);
va_end(args);
return res;
}
2021-04-11 13:52:39 +08:00
void checkSDEvents()
{
if (useSoftDevice) {
uint32_t evt;
while (NRF_SUCCESS == sd_evt_get(&evt)) {
switch (evt) {
case NRF_EVT_POWER_FAILURE_WARNING:
RECORD_CRITICALERROR(meshtastic_CriticalErrorCode_BROWNOUT);
2021-04-11 13:52:39 +08:00
break;
default:
2022-12-29 20:41:37 -06:00
LOG_DEBUG("Unexpected SDevt %d\n", evt);
2021-04-11 13:52:39 +08:00
break;
}
}
} else {
if (NRF_POWER->EVENTS_POFWARN)
RECORD_CRITICALERROR(meshtastic_CriticalErrorCode_BROWNOUT);
2021-03-08 18:12:21 +08:00
}
}
2021-04-11 13:52:39 +08:00
void nrf52Loop()
{
checkSDEvents();
}
2020-05-24 16:20:21 -07:00
2021-04-11 13:52:39 +08:00
void nrf52Setup()
{
auto why = NRF_POWER->RESETREAS;
// per
// https://infocenter.nordicsemi.com/index.jsp?topic=%2Fcom.nordic.infocenter.nrf52832.ps.v1.1%2Fpower.html
2022-12-29 20:41:37 -06:00
LOG_DEBUG("Reset reason: 0x%x\n", why);
2020-05-24 16:20:21 -07:00
2021-04-11 13:52:39 +08:00
// Per
// https://devzone.nordicsemi.com/nordic/nordic-blog/b/blog/posts/monitor-mode-debugging-with-j-link-and-gdbeclipse
// This is the recommended setting for Monitor Mode Debugging
NVIC_SetPriority(DebugMonitor_IRQn, 6UL);
2020-05-25 15:56:06 -07:00
#ifdef BQ25703A_ADDR
2021-04-11 13:52:39 +08:00
auto *bq = new BQ25713();
if (!bq->setup())
LOG_ERROR("ERROR! Charge controller init failed\n");
#endif
2020-05-27 15:31:32 -07:00
2021-04-11 13:52:39 +08:00
// Init random seed
union seedParts {
uint32_t seed32;
2023-01-21 14:34:29 +01:00
uint8_t seed8[4];
} seed;
nRFCrypto.begin();
nRFCrypto.Random.generate(seed.seed8, sizeof(seed.seed8));
2022-12-29 20:41:37 -06:00
LOG_DEBUG("Setting random seed %u\n", seed.seed32);
randomSeed(seed.seed32);
nRFCrypto.end();
2020-10-30 17:05:32 +08:00
}
2023-04-11 13:32:19 +02:00
void cpuDeepSleep(uint32_t msecToWake)
2021-04-11 13:52:39 +08:00
{
// FIXME, configure RTC or button press to wake us
// FIXME, power down SPI, I2C, RAMs
#if HAS_WIRE
2021-04-11 13:52:39 +08:00
Wire.end();
#endif
2021-04-11 13:52:39 +08:00
SPI.end();
// This may cause crashes as debug messages continue to flow.
Serial.end();
2020-10-30 17:05:32 +08:00
#ifdef PIN_SERIAL_RX1
2021-04-11 13:52:39 +08:00
Serial1.end();
#endif
2021-04-11 13:52:39 +08:00
setBluetoothEnable(false);
#ifdef RAK4630
digitalWrite(PIN_3V3_EN, LOW);
#endif
2021-04-11 13:52:39 +08:00
// FIXME, use system off mode with ram retention for key state?
// FIXME, use non-init RAM per
// 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) {
LOG_ERROR("FIXME: Ignoring soft device (EasyDMA pending?) and forcing system-off!\n");
2021-04-11 13:52:39 +08:00
NRF_POWER->SYSTEMOFF = 1;
}
// The following code should not be run, because we are off
while (1) {
delay(5000);
2022-12-29 20:41:37 -06:00
LOG_DEBUG(".");
2021-04-11 13:52:39 +08:00
}
}
2023-01-21 14:34:29 +01:00
void clearBonds()
{
if (!nrf52Bluetooth) {
nrf52Bluetooth = new NRF52Bluetooth();
nrf52Bluetooth->setup();
}
nrf52Bluetooth->clearBonds();
}