diff --git a/examples/standby/Makefile b/examples/standby/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..f7cec50a39843b071ffd9d410a25a1197256ebd8 --- /dev/null +++ b/examples/standby/Makefile @@ -0,0 +1,11 @@ +all : flash + +TARGET:=standby + +CFLAGS+=-DSTDOUT_UART + +include ../../ch32v003fun/ch32v003fun.mk + +flash : cv_flash +clean : cv_clean + diff --git a/examples/standby/README.md b/examples/standby/README.md new file mode 100644 index 0000000000000000000000000000000000000000..205a20afd4985de0e516aefff821d97d109e04d1 --- /dev/null +++ b/examples/standby/README.md @@ -0,0 +1,19 @@ +# the deepest slumber + +This example serves to show how to put the CH32V003 into its lowest power state (standby) and have it wake periodically. + +Power consumption should be around 10uA. + +The MCU only toggles the LED and prints a message, then it goes to sleep. +The LED staying on demonstrates that GPIO keeps its state even when the rest of the mcu is in a coma. + +Based on the groundwork of Marek M. + +## time calculations + +The autowakeup delay can be calculated by: + +`t = AWUWR / (fLSI / AWUPSC)` + +Where AWUWR can be 1 to 63, fLSI is always 128000 and AWUPSC, for practical purposes is 2048, 4096, 10240 or 61440, though lower values are possible. +The maximum autowakeup delay is 30s. diff --git a/examples/standby/standby.c b/examples/standby/standby.c new file mode 100644 index 0000000000000000000000000000000000000000..cc0fe4295b82faadc151d4331f38cc43bbea3959 --- /dev/null +++ b/examples/standby/standby.c @@ -0,0 +1,71 @@ +// based on https://paste.sr.ht/blob/b9b4fb45cbc70f2db7e31a77a6ef7dd2a7f220fb +// Could be defined here, or in the processor defines. +#define SYSTEM_CORE_CLOCK 48000000 + +#include "ch32v003fun.h" +#include <stdio.h> + +#define APB_CLOCK SYSTEM_CORE_CLOCK + +/* somehow this ISR won't get called?? +void AWU_IRQHandler( void ) __attribute__((interrupt)); +void AWU_IRQHandler( void ) { + GPIOD->OUTDR ^= (1 << 4); +} +*/ + +int main() +{ + SystemInit48HSI(); + SetupUART( UART_BRR ); + + printf("\r\n\r\nlow power example\r\n\r\n"); + + RCC->APB2PCENR |= RCC_APB2Periph_GPIOD; + // GPIO D4 Push-Pull + GPIOD->CFGLR &= ~(0xf<<(4*4)); + GPIOD->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_PP)<<(4*4); + GPIOD->OUTDR |= (1 << 4); + + // give the user time to open the terminal connection + //Delay_Ms(5000); + printf("5000ms wait over\r\n"); + + // enable power interface module clock + RCC->APB1PCENR |= RCC_APB1Periph_PWR; + + // enable low speed oscillator (LSI) + RCC->RSTSCKR |= RCC_LSION; + while ((RCC->RSTSCKR & RCC_LSIRDY) == 0) {} + + // enable AutoWakeUp event + EXTI->EVENR |= EXTI_Line9; + EXTI->FTENR |= EXTI_Line9; + + // configure AWU prescaler + PWR->AWUPSC |= PWR_AWU_Prescaler_4096; + + // configure AWU window comparison value + PWR->AWUWR &= ~0x3f; + PWR->AWUWR |= 63; + + // enable AWU + PWR->AWUCSR |= (1 << 1); + + // select standby on power-down + PWR->CTLR |= PWR_CTLR_PDDS; + + // peripheral interrupt controller send to deep sleep + PFIC->SCTLR |= (1 << 2); + + uint16_t counter = 0; + printf("entering sleep loop\r\n"); + + for (;;) { + __WFE(); + // restore clock to full speed + SystemInit48HSI(); + printf("\r\nawake, %u\r\n", counter++); + GPIOD->OUTDR ^= (1 << 4); + } +}