-
Notifications
You must be signed in to change notification settings - Fork 39
Description
Another observation...
With v2.1 of the core, we need to manually re-enable the Serial TX and RX pins after disabling them to reduce power consumption during SLEEP_DEEP.
With v1.2 of the core, we didn't need to do this.
Steps to reproduce:
RedBoard Artemis ATP
v2.1 of the core
Run the following example:
extern "C" void am_stimer_cmpr6_isr(void)
{
uint32_t ui32Status = am_hal_stimer_int_status_get(false);
if (ui32Status & AM_HAL_STIMER_INT_COMPAREG)
{
am_hal_stimer_int_clear(AM_HAL_STIMER_INT_COMPAREG);
}
}
void setup() {
Serial.begin(115200);
Serial.println(F("Apollo3: Serial and micros after deep sleep test"));
Serial.flush();
}
void loop() {
Serial.end();
//Force UART0 off
am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_PERIPH_UART0);
//Disable the TX and RX pins
am_hal_gpio_pinconfig(48 , g_AM_HAL_GPIO_DISABLE); //TX0
am_hal_gpio_pinconfig(49 , g_AM_HAL_GPIO_DISABLE); //RX0
//We use counter/timer 6 to cause us to wake up from sleep but 0 to 7 are available
//CT 7 is used for Software Serial. All CTs are used for Servo.
am_hal_stimer_int_clear(AM_HAL_STIMER_INT_COMPAREG); //Clear CT6
am_hal_stimer_int_enable(AM_HAL_STIMER_INT_COMPAREG); //Enable C/T G=6
//Use the lower power 32kHz clock. Use it to run CT6 as well.
am_hal_stimer_config(AM_HAL_STIMER_CFG_CLEAR | AM_HAL_STIMER_CFG_FREEZE);
am_hal_stimer_config(AM_HAL_STIMER_XTAL_32KHZ | AM_HAL_STIMER_CFG_COMPARE_G_ENABLE);
//Setup interrupt to trigger when the number of ms have elapsed
am_hal_stimer_compare_delta_set(6, 32768); // Sleep for 32768 clock ticks = 1 second at 32768Hz
//Power down cache, flash, SRAM
am_hal_pwrctrl_memory_deepsleep_powerdown(AM_HAL_PWRCTRL_MEM_ALL); // Power down all flash and cache
am_hal_pwrctrl_memory_deepsleep_retain(AM_HAL_PWRCTRL_MEM_SRAM_384K); // Retain all SRAM
//Enable the timer interrupt in the NVIC.
NVIC_EnableIRQ(STIMER_CMPR6_IRQn);
//Deep Sleep
am_hal_sysctrl_sleep(AM_HAL_SYSCTRL_SLEEP_DEEP);
//Turn off interrupt
NVIC_DisableIRQ(STIMER_CMPR6_IRQn);
am_hal_stimer_int_disable(AM_HAL_STIMER_INT_COMPAREG); //Disable C/T G=6
// Power up SRAM, turn on entire Flash
am_hal_pwrctrl_memory_deepsleep_powerdown(AM_HAL_PWRCTRL_MEM_MAX);
//Go back to using the main clock
am_hal_stimer_config(AM_HAL_STIMER_CFG_CLEAR | AM_HAL_STIMER_CFG_FREEZE);
am_hal_stimer_config(AM_HAL_STIMER_HFRC_3MHZ);
//We need to re-enable the TX and RX pins manually. Serial.begin does not do it for us...
// If you comment the next four lines, the code stops working on v2.1 of the core:
am_hal_gpio_pincfg_t txPinCfg = g_AM_BSP_GPIO_COM_UART_TX;
pin_config(PinName(48), txPinCfg);
am_hal_gpio_pincfg_t rxPinCfg = g_AM_BSP_GPIO_COM_UART_RX;
pin_config(PinName(49), rxPinCfg);
//Restart Serial
Serial.begin(115200);
Serial.println();
Serial.print(F("Micros: "));
Serial.println(micros());
Serial.flush();
}
Here is the Serial output:
Note that micros
does not behave well after waking from SLEEP_DEEP.
The reverse question marks probably are expected - caused by turning the pin off and on again, generating a spurious start bit.
If you comment the four lines which re-enable the TX and RX pins, the code stops working on v2.1:
// If you comment the next four lines, the code stops working on v2.1 of the core:
// am_hal_gpio_pincfg_t txPinCfg = g_AM_BSP_GPIO_COM_UART_TX;
// pin_config(PinName(48), txPinCfg);
// am_hal_gpio_pincfg_t rxPinCfg = g_AM_BSP_GPIO_COM_UART_RX;
// pin_config(PinName(49), rxPinCfg);
But if you switch to v1.2.1 of the core, the code does work with those same four lines commented. I guess Serial.begin must be re-initializing the pins for us? Note micros is better behaved too...
Cheers,
Paul