From 13f5690a7c22e272efc6fc3d35a3ccc73c091093 Mon Sep 17 00:00:00 2001
From: recallmenot <edmund.raile@proton.me>
Date: Mon, 22 May 2023 17:07:35 +0200
Subject: [PATCH] sleep example with button

---
 examples/standby_btn/Makefile      | 11 +++++
 examples/standby_btn/README.md     | 15 +++++++
 examples/standby_btn/standby_btn.c | 65 ++++++++++++++++++++++++++++++
 3 files changed, 91 insertions(+)
 create mode 100644 examples/standby_btn/Makefile
 create mode 100644 examples/standby_btn/README.md
 create mode 100644 examples/standby_btn/standby_btn.c

diff --git a/examples/standby_btn/Makefile b/examples/standby_btn/Makefile
new file mode 100644
index 0000000..36f69f6
--- /dev/null
+++ b/examples/standby_btn/Makefile
@@ -0,0 +1,11 @@
+all : flash
+
+TARGET:=standby_btn
+
+CFLAGS+=-DSTDOUT_UART
+
+include ../../ch32v003fun/ch32v003fun.mk
+
+flash : cv_flash
+clean : cv_clean
+
diff --git a/examples/standby_btn/README.md b/examples/standby_btn/README.md
new file mode 100644
index 0000000..794e8b4
--- /dev/null
+++ b/examples/standby_btn/README.md
@@ -0,0 +1,15 @@
+# the deepest slumber
+
+This example serves to show how to put the CH32V003 into its lowest power state (standby) and have it wake with a button press.  
+
+Power consumption should be around 10uA.  
+
+The MCU only toggles the LED and prints a message, then it goes back 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.  
+
+## circuit
+
+Connect LED to PD4 (with resistor), connect button to GND and PD2.  
+There is no debouncing but it should suffice for waking the chip.
diff --git a/examples/standby_btn/standby_btn.c b/examples/standby_btn/standby_btn.c
new file mode 100644
index 0000000..de1a846
--- /dev/null
+++ b/examples/standby_btn/standby_btn.c
@@ -0,0 +1,65 @@
+// based on https://paste.sr.ht/blob/b9b4fb45cbc70f2db7e31a77a6ef7dd2a7f220fb
+// Could be defined here, or in the processor defines.
+#define SYSTEM_CORE_CLOCK 48000000
+
+#include "../../ch32v003fun/ch32v003fun.h"
+#include <stdio.h>
+
+#define APB_CLOCK SYSTEM_CORE_CLOCK
+
+void EXTI7_0_IRQHandler( void ) __attribute__((interrupt));
+void EXTI7_0_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 alternate IO function module clock
+	RCC->APB2PCENR |= RCC_AFIOEN;
+
+	// configure button on PD2 as input, pullup
+	GPIOD->CFGLR &= ~(0xf<<(2*4));
+	GPIOD->CFGLR |= (GPIO_CNF_IN_PUPD)<<(2*4);
+	GPIOD->BSHR = (1 << 2);
+
+	// assign pin 2 interrupt from portD (0b11) to EXTI channel 2
+	AFIO->EXTICR |= (uint32_t)(0b11 << (2 * 2));
+
+	// enable line2 interrupt event
+	EXTI->EVENR |= EXTI_Line2;
+	EXTI->FTENR |= EXTI_Line2;
+
+	// 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);
+	}
+}
-- 
GitLab