I have a custom board built around the nRF52840, which spends most of its life sleeping. I'm able to achieve ~3uA current draw when it is sleeping, but I've recently started running into corner cases where the current draw is much higher. I suspect that it is an issue with UART0.
As a specific example, if I disable UART0 and the other peripherals before going to sleep, I hit 3uA. However, if I transmit on the UART just before disabling it, I see ~620uA of current in sleep. Waiting on nrfx_uarte_tx_in_progress() and using delays does not seem to resolve the issue.
Here's a stripped down version of my code. The "printf("Going to sleep...\r\n");
" is the offending line. If I comment that out, the sleep current is ok. Any idea how to fix this?
int main(void)
{
int32_t r;
// Initialize HW peripherals
r = HWC_UartInit();
if(r) SC_printf("HWC_UartInit: failed to initialize (%i)\r\n", r);
printf("Going to sleep...\r\n");
// Uninitialize UART
HWC_UartDeinit();
__SEV(); // Send an event (guarantees an event is set)
__WFE(); // Will wake up immediately, clearing the event
__WFE(); // This will put the device to sleep for realzies
// Reinitialize the UART
HWC_UartInit();
SC_printf("Awake again...\r\n");
while(1);
}
int32_t HWC_UartInit()
{
nrfx_uarte_config_t uartConfig = NRFX_UARTE_DEFAULT_CONFIG;
uartConfig.pseltxd = PIN_UART_TX;
uartConfig.pselrxd = PIN_UART_RX;
uartConfig.hwfc = NRF_UARTE_HWFC_DISABLED;
uartConfig.parity = NRF_UARTE_PARITY_EXCLUDED;
uartConfig.baudrate = NRF_UARTE_BAUDRATE_115200;
nrfx_err_t e = nrfx_uarte_init(&uartInstance, &uartConfig, HWC_UartEventHandle);
if(NRFX_SUCCESS==e) e = nrfx_uarte_rx(&uartInstance, &rxByte, 1);
return NRFX_SUCCESS == e ? 0 : -1;
}
void HWC_UartDeinit()
{
nrfx_uarte_rx_abort(&uartInstance);
nrfx_uarte_uninit(&uartInstance);
// Need to restart UARTE0 to reduce power. This may be related to an erratum.
// devzone.nordicsemi.com/.../184882
*(volatile uint32_t *)0x40002FFC = 0;
*(volatile uint32_t *)0x40002FFC;
*(volatile uint32_t *)0x40002FFC = 1;
}