lower brownout threshold to 1.7V

This commit is contained in:
Kevin Hester 2021-04-11 13:52:39 +08:00
parent 328b24537f
commit f9a58b9dd1

View File

@ -13,174 +13,173 @@
#include "BQ25713.h" #include "BQ25713.h"
#endif #endif
static inline void debugger_break(void)
static inline void debugger_break(void) { {
__asm volatile( __asm volatile("bkpt #0x01\n\t"
"bkpt #0x01\n\t" "mov pc, lr\n\t");
"mov pc, lr\n\t");
} }
// handle standard gcc assert failures // handle standard gcc assert failures
void __attribute__((noreturn)) void __attribute__((noreturn)) __assert_func(const char *file, int line, const char *func, const char *failedexpr)
__assert_func(const char *file, int line, const char *func, {
const char *failedexpr) { DEBUG_MSG("assert failed %s: %d, %s, test=%s\n", file, line, func, failedexpr);
DEBUG_MSG("assert failed %s: %d, %s, test=%s\n", file, line, func, // debugger_break(); FIXME doesn't work, possibly not for segger
failedexpr); while (1)
// debugger_break(); FIXME doesn't work, possibly not for segger ; // FIXME, reboot!
while (1)
; // FIXME, reboot!
} }
void getMacAddr(uint8_t *dmac) { void getMacAddr(uint8_t *dmac)
ble_gap_addr_t addr; {
if (sd_ble_gap_addr_get(&addr) == NRF_SUCCESS) { ble_gap_addr_t addr;
memcpy(dmac, addr.addr, 6); if (sd_ble_gap_addr_get(&addr) == NRF_SUCCESS) {
} else { memcpy(dmac, addr.addr, 6);
const uint8_t *src = (const uint8_t *)NRF_FICR->DEVICEADDR; } else {
dmac[5] = src[0]; const uint8_t *src = (const uint8_t *)NRF_FICR->DEVICEADDR;
dmac[4] = src[1]; dmac[5] = src[0];
dmac[3] = src[2]; dmac[4] = src[1];
dmac[2] = src[3]; dmac[3] = src[2];
dmac[1] = src[4]; dmac[2] = src[3];
dmac[0] = src[5] | dmac[1] = src[4];
0xc0; // MSB high two bits get set elsewhere in the bluetooth stack dmac[0] = src[5] | 0xc0; // MSB high two bits get set elsewhere in the bluetooth stack
} }
} }
NRF52Bluetooth *nrf52Bluetooth; NRF52Bluetooth *nrf52Bluetooth;
static bool bleOn = false; static bool bleOn = false;
static const bool useSoftDevice = true; // Set to false for easier debugging static const bool useSoftDevice = false; // Set to false for easier debugging
void setBluetoothEnable(bool on) { void setBluetoothEnable(bool on)
if (on != bleOn) { {
if (on) { if (on != bleOn) {
if (!nrf52Bluetooth) { if (on) {
if (!useSoftDevice) if (!nrf52Bluetooth) {
DEBUG_MSG("DISABLING NRF52 BLUETOOTH WHILE DEBUGGING\n"); if (!useSoftDevice)
else { DEBUG_MSG("DISABLING NRF52 BLUETOOTH WHILE DEBUGGING\n");
nrf52Bluetooth = new NRF52Bluetooth(); else {
nrf52Bluetooth->setup(); nrf52Bluetooth = new NRF52Bluetooth();
nrf52Bluetooth->setup();
}
}
} else {
if (nrf52Bluetooth)
nrf52Bluetooth->shutdown();
} }
} bleOn = on;
} else {
if (nrf52Bluetooth) nrf52Bluetooth->shutdown();
} }
bleOn = on;
}
} }
/** /**
* Override printf to use the SEGGER output library * Override printf to use the SEGGER output library
*/ */
int printf(const char *fmt, ...) { int printf(const char *fmt, ...)
va_list args; {
va_start(args, fmt); va_list args;
auto res = SEGGER_RTT_vprintf(0, fmt, &args); va_start(args, fmt);
va_end(args); auto res = SEGGER_RTT_vprintf(0, fmt, &args);
return res; va_end(args);
return res;
} }
void initBrownout() { void initBrownout()
auto vccthresh = POWER_POFCON_THRESHOLD_V28; {
auto vccthresh = POWER_POFCON_THRESHOLD_V17;
if (useSoftDevice) { if (useSoftDevice) {
auto err_code = sd_power_pof_enable(POWER_POFCON_POF_Enabled); auto err_code = sd_power_pof_enable(POWER_POFCON_POF_Enabled);
assert(err_code == NRF_SUCCESS); assert(err_code == NRF_SUCCESS);
err_code = sd_power_pof_threshold_set(vccthresh); err_code = sd_power_pof_threshold_set(vccthresh);
assert(err_code == NRF_SUCCESS); assert(err_code == NRF_SUCCESS);
} else {
uint32_t pof_flags = POWER_POFCON_POF_Enabled | (vccthresh << POWER_POFCON_THRESHOLD_Pos);
#ifdef POWER_POFCON_THRESHOLDVDDH_Msk
auto vcchthresh = POWER_POFCON_THRESHOLDVDDH_V27;
pof_flags |= (vcchthresh << POWER_POFCON_THRESHOLDVDDH_Pos);
#endif
NRF_POWER->POFCON = pof_flags;
}
}
void checkSDEvents() {
if (useSoftDevice) {
uint32_t evt;
while (NRF_SUCCESS == 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 { // We don't bother with setting up brownout if soft device is disabled - because during production we always use softdevice
if (NRF_POWER->EVENTS_POFWARN)
recordCriticalError(CriticalErrorCode_Brownout);
}
} }
void nrf52Loop() { checkSDEvents(); } void checkSDEvents()
{
if (useSoftDevice) {
uint32_t evt;
while (NRF_SUCCESS == sd_evt_get(&evt)) {
switch (evt) {
case NRF_EVT_POWER_FAILURE_WARNING:
recordCriticalError(CriticalErrorCode_Brownout);
break;
void nrf52Setup() { default:
auto why = NRF_POWER->RESETREAS; DEBUG_MSG("Unexpected SDevt %d\n", evt);
// per break;
// https://infocenter.nordicsemi.com/index.jsp?topic=%2Fcom.nordic.infocenter.nrf52832.ps.v1.1%2Fpower.html }
DEBUG_MSG("Reset reason: 0x%x\n", why); }
} else {
if (NRF_POWER->EVENTS_POFWARN)
recordCriticalError(CriticalErrorCode_Brownout);
}
}
// Per void nrf52Loop()
// 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 checkSDEvents();
NVIC_SetPriority(DebugMonitor_IRQn, 6UL); }
void nrf52Setup()
{
auto why = NRF_POWER->RESETREAS;
// per
// https://infocenter.nordicsemi.com/index.jsp?topic=%2Fcom.nordic.infocenter.nrf52832.ps.v1.1%2Fpower.html
DEBUG_MSG("Reset reason: 0x%x\n", why);
// 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);
#ifdef BQ25703A_ADDR #ifdef BQ25703A_ADDR
auto *bq = new BQ25713(); auto *bq = new BQ25713();
if (!bq->setup()) DEBUG_MSG("ERROR! Charge controller init failed\n"); if (!bq->setup())
DEBUG_MSG("ERROR! Charge controller init failed\n");
#endif #endif
// Init random seed // Init random seed
// FIXME - use this to get random numbers // FIXME - use this to get random numbers
// #include "nrf_rng.h" // #include "nrf_rng.h"
// uint32_t r; // uint32_t r;
// ble_controller_rand_vector_get_blocking(&r, sizeof(r)); // ble_controller_rand_vector_get_blocking(&r, sizeof(r));
// randomSeed(r); // randomSeed(r);
DEBUG_MSG("FIXME, call randomSeed\n"); DEBUG_MSG("FIXME, call randomSeed\n");
// ::printf("TESTING PRINTF\n"); // ::printf("TESTING PRINTF\n");
initBrownout(); initBrownout();
} }
void cpuDeepSleep(uint64_t msecToWake) { void cpuDeepSleep(uint64_t msecToWake)
// FIXME, configure RTC or button press to wake us {
// FIXME, power down SPI, I2C, RAMs // FIXME, configure RTC or button press to wake us
// FIXME, power down SPI, I2C, RAMs
#ifndef NO_WIRE #ifndef NO_WIRE
Wire.end(); Wire.end();
#endif #endif
SPI.end(); SPI.end();
// This may cause crashes as debug messages continue to flow. // This may cause crashes as debug messages continue to flow.
Serial.end(); Serial.end();
#ifdef PIN_SERIAL_RX1 #ifdef PIN_SERIAL_RX1
Serial1.end(); Serial1.end();
#endif #endif
setBluetoothEnable(false); setBluetoothEnable(false);
// FIXME, use system off mode with ram retention for key state? // FIXME, use system off mode with ram retention for key state?
// FIXME, use non-init RAM per // FIXME, use non-init RAM per
// https://devzone.nordicsemi.com/f/nordic-q-a/48919/ram-retention-settings-with-softdevice-enabled // https://devzone.nordicsemi.com/f/nordic-q-a/48919/ram-retention-settings-with-softdevice-enabled
auto ok = sd_power_system_off(); auto ok = sd_power_system_off();
if (ok != NRF_SUCCESS) { if (ok != NRF_SUCCESS) {
DEBUG_MSG( DEBUG_MSG("FIXME: Ignoring soft device (EasyDMA pending?) and forcing "
"FIXME: Ignoring soft device (EasyDMA pending?) and forcing " "system-off!\n");
"system-off!\n"); NRF_POWER->SYSTEMOFF = 1;
NRF_POWER->SYSTEMOFF = 1; }
}
// The following code should not be run, because we are off // The following code should not be run, because we are off
while (1) { while (1) {
delay(5000); delay(5000);
DEBUG_MSG("."); DEBUG_MSG(".");
} }
} }