瀏覽代碼

更新MCU工程(iram版本和sram-nos版本)的RTC模块休眠唤醒相关代码
1.优化休眠掉电及唤醒上电延时时间为100ms及MCU复位延时为100ms。
2.添加保存和获取休眠数据及上电检测唤醒源接口。
3.优化配置唤醒源接口。
4.添加ACC/RTC/GPIO0/GPIO1休眠唤醒demo。

helen 6 月之前
父節點
當前提交
46616deee1

+ 3 - 0
amt630hv160-mcu/amt630hv160-mcu-iram/amt630hv160.ewp

@@ -2097,6 +2097,9 @@
             <file>
                 <name>$PROJ_DIR$\src\App\osdtest.c</name>
             </file>
+            <file>
+                <name>$PROJ_DIR$\src\App\rtc_demo.c</name>
+            </file>
             <file>
                 <name>$PROJ_DIR$\src\App\secure_funcs.c</name>
             </file>

+ 141 - 0
amt630hv160-mcu/amt630hv160-mcu-iram/src/App/rtc_demo.c

@@ -0,0 +1,141 @@
+#include <stdio.h>
+#include "amt630hv160_lib.h"
+
+
+#ifdef _RTC
+#if RTC_DEMO
+static uint8_t __attribute__( ( section( "sleep_critical_data" ) ) ) PRIVATE1_RAM_BUFFER[16];
+static uint8_t __attribute__( ( section( "sleep_critical_data" ) ) ) PRIVATE2_RAM_BUFFER[16];
+
+/*
+	唤醒源配置可提前在系统启动时配置
+*/
+#if RTC_DEMO == RTC_ACCWAKEUP_DEMO
+void entry_acc_sleep(int fastboot, u8 wakeup_mode)
+{
+	if (wakeup_mode >= RTC_WAKEUP_HIGHLEVEL) {
+		printf("acc not support wakeup mode, sleep fail.\n");
+		return;
+	}
+
+	//wakeup source config
+	RTC_SetWakeup(RTC_WAKEUP_GPIO0, RTC_WAKEUP_RISING, 0);
+	RTC_SetWakeup(RTC_WAKEUP_GPIO1, RTC_WAKEUP_RISING, 0);
+	RTC_SetWakeup(RTC_WAKEUP_CAN1, RTC_WAKEUP_RISING, 0);
+	RTC_SetWakeup(RTC_WAKEUP_CAN0, RTC_WAKEUP_RISING, 0);
+	RTC_SetWakeup(RTC_WAKEUP_RTC, RTC_WAKEUP_RISING, 0);
+	RTC_SetWakeup(RTC_WAKEUP_ACC, RTC_WAKEUP_RISING, 1);
+	if (RTC_SaveSleepData())
+		return;
+
+	printf("entry sleep.\n");
+	RTC_SendCmd(RTC_SleepMode, 1);
+	RTC_PowerDown(fastboot);
+}
+
+#elif RTC_DEMO == RTC_RTCWAKEUP_DEMO
+void entry_rtc_sleep(u32 time_s)
+{
+	if (time_s == 0)
+		time_s = 1;
+
+	//wakeup source config
+	RTC_SetWakeup(RTC_WAKEUP_GPIO0, RTC_WAKEUP_RISING, 0);
+	RTC_SetWakeup(RTC_WAKEUP_GPIO1, RTC_WAKEUP_RISING, 0);
+	RTC_SetWakeup(RTC_WAKEUP_CAN1, RTC_WAKEUP_RISING, 0);
+	RTC_SetWakeup(RTC_WAKEUP_CAN0, RTC_WAKEUP_RISING, 0);
+	RTC_SetWakeup(RTC_WAKEUP_RTC, RTC_WAKEUP_RISING, 1);
+	RTC_SetWakeup(RTC_WAKEUP_ACC, RTC_WAKEUP_RISING, 0);
+
+	printf("entry sleep time %ds.\n", time_s);
+	RTC_SendCmd(RTC_DelayWakeUp, 1);
+	if (RTC->CNT_L > 0x6000)	//若小数部分超过0.75s,则加1s
+		time_s += 1;
+
+	RTC_WriteReg(RTC_RAMH, &RTC->RAM_H, RTC->CNT_H + time_s);//config sleep time
+	RTC_SendCmd(RTC_SleepMode, 1);
+	RTC_PowerDown(0);
+}
+#elif RTC_DEMO == RTC_GPIO0WAKEUP_DEMO
+void entry_gpio0_sleep(int fastboot, u8 wakeup_mode)
+{
+	if (wakeup_mode >= RTC_WAKEUP_NOCHANGE) {
+		printf("gpio0 not support wakeup mode, sleep fail.\n");
+		return;
+	}
+
+	//wakeup source config
+	RTC_SetWakeup(RTC_WAKEUP_GPIO0, wakeup_mode, 1);
+	RTC_SetWakeup(RTC_WAKEUP_GPIO1, RTC_WAKEUP_RISING, 0);
+	RTC_SetWakeup(RTC_WAKEUP_CAN1, RTC_WAKEUP_RISING, 0);
+	RTC_SetWakeup(RTC_WAKEUP_CAN0, RTC_WAKEUP_RISING, 0);
+	RTC_SetWakeup(RTC_WAKEUP_RTC, RTC_WAKEUP_RISING, 0);
+	RTC_SetWakeup(RTC_WAKEUP_ACC, RTC_WAKEUP_RISING, 0);
+
+	printf("entry sleep.\n");
+	RTC_SendCmd(RTC_SleepMode, 1);
+	RTC_PowerDown(fastboot);
+}
+#elif RTC_DEMO == RTC_GPIO1WAKEUP_DEMO
+void entry_gpio1_sleep(int fastboot, u8 wakeup_mode)
+{
+	if (wakeup_mode >= RTC_WAKEUP_NOCHANGE) {
+		printf("gpio1 not support wakeup mode, sleep fail.\n");
+		return;
+	}
+
+	//wakeup source config
+	RTC_SetWakeup(RTC_WAKEUP_GPIO0, RTC_WAKEUP_RISING, 0);
+	RTC_SetWakeup(RTC_WAKEUP_GPIO1, wakeup_mode, 1);
+	RTC_SetWakeup(RTC_WAKEUP_CAN1, RTC_WAKEUP_RISING, 0);
+	RTC_SetWakeup(RTC_WAKEUP_CAN0, RTC_WAKEUP_RISING, 0);
+	RTC_SetWakeup(RTC_WAKEUP_RTC, RTC_WAKEUP_RISING, 0);
+	RTC_SetWakeup(RTC_WAKEUP_ACC, RTC_WAKEUP_RISING, 0);
+
+	printf("entry sleep.\n");
+	RTC_SendCmd(RTC_SleepMode, 1);
+	RTC_PowerDown(fastboot);
+}
+#endif
+
+void rtc_wakeup_demo(void)
+{
+	if (!RTC_ReadSleepData()) {
+		printf("P1_BUF[0]: 0x%x, P1_BUF[15]: 0x%x, P2_BUF[0]: 0x%x, P2_BUF[15]: 0x%x.\n",
+		PRIVATE1_RAM_BUFFER[0], PRIVATE1_RAM_BUFFER[15], PRIVATE2_RAM_BUFFER[0], PRIVATE2_RAM_BUFFER[15]);
+	}
+}
+
+void rtc_sleep_demo(void)
+{
+	vTaskDelay(5000);		//系统延时5s后进入休眠
+	if (!(RTC->RTCSTA & RTC_STA_SLEEPMODE)) {
+#if RTC_DEMO == RTC_ACCWAKEUP_DEMO
+		//The simulation goes to sleep after accessing swl data
+		PRIVATE1_RAM_BUFFER[0] = 0x55;
+		PRIVATE1_RAM_BUFFER[15] = 0xaa;
+		PRIVATE2_RAM_BUFFER[0] = 0x5a;
+		PRIVATE2_RAM_BUFFER[15] = 0xa5;
+
+		entry_acc_sleep(0, RTC_WAKEUP_RISING);
+#elif RTC_DEMO == RTC_RTCWAKEUP_DEMO
+		entry_rtc_sleep(10);
+#elif RTC_DEMO == RTC_GPIO0WAKEUP_DEMO
+		entry_gpio0_sleep(0, RTC_WAKEUP_RISING);
+#elif RTC_DEMO == RTC_GPIO1WAKEUP_DEMO
+		entry_gpio1_sleep(0, RTC_WAKEUP_RISING);
+#endif
+	} else {
+		printf("normal running.\n");
+		//The simulated fault generation results in a wdt reset.
+#if RTC_DEMO == RTC_ACCWAKEUP_DEMO
+		//wakeup boot delay 10s entry wdt reset
+		if (RTC->RTCSTA & RTC_STA_ACCACT) {
+			vTaskDelay(10000);
+			WDT_CpuReboot();
+		}
+#endif
+	}
+}
+#endif
+#endif

+ 41 - 34
amt630hv160-mcu/amt630hv160-mcu-iram/src/ArkmicroFiles/libcpu-amt630hv160/include/amt630hv160_rtc.h

@@ -17,7 +17,6 @@
 #include "amt630hv160_map.h"
 
 /* Exported types ------------------------------------------------------------*/
-/* Exported constants --------------------------------------------------------*/
 typedef enum {
 	RTC_PowerOff,
 	RTC_DelayWakeUp,
@@ -59,6 +58,40 @@ typedef enum {
 	RTC_WAKEUP_NOCHANGE,
 } eRTCWakeupMode;
 
+/*
+ * The struct used to pass data via the following ioctl. Similar to the
+ * struct tm in <time.h>, but it needs to be here so that the kernel
+ * source is self contained, allowing cross-compiles, etc. etc.
+ */
+typedef struct rtc_time {
+	int tm_sec;
+	int tm_min;
+	int tm_hour;
+	int tm_mday;
+	int tm_mon;
+	int tm_year;
+	int tm_wday;
+	int tm_yday;
+} SystemTime_t;
+
+/*
+ * This data structure is inspired by the EFI (v0.92) wakeup
+ * alarm API.
+ */
+struct rtc_wkalrm {
+	unsigned char enabled;	/* 0 = alarm disabled, 1 = alarm enabled */
+	unsigned char pending;  /* 0 = alarm not pending, 1 = alarm pending */
+	struct rtc_time time;	/* time the alarm is set to */
+};
+
+/* Exported constants --------------------------------------------------------*/
+static inline int is_leap_year(unsigned int year)
+{
+	return (!(year % 4) && (year % 100)) || !(year % 400);
+}
+
+#pragma section = "sleep_critical_data"
+
 /* Exported macro ------------------------------------------------------------*/
 //RTC_CTL register fields defination
 #define CTL_CTL3_VALUE(x)				(x<<23)
@@ -118,50 +151,24 @@ typedef enum {
 #define RTC_STA_RTCACT					(1 << 14)
 #define RTC_STA_GPIO0IN					(1 << 15)
 
+#define IRAM_SLEEP_DATA_MAX_SIZE		(0x2000 - 8)
+
 /* Exported functions ------------------------------------------------------- */
+//	Sleep and wake-up related
 void RTC_SendCmd(eRTCCmd cmd, int enable);
 void RTC_WriteReg(eRTCCmd cmd, vu32 *reg, u32 value);
 void RTC_SetWatchdog(eRTCWdtTmo tmo, int enable);
 void RTC_PowerDown(int fastboot);
-void RTC_WaitNotBusy(void);
 void RTC_CanStbOut(int id, int value);
 void RTC_SetWakeup(eRTCWakeupSource src, eRTCWakeupMode mode, int enable);
+void RTC_WakeupDetect(void);
+int RTC_SaveSleepData(void);
+int RTC_ReadSleepData(void);
 
-/*
- * The struct used to pass data via the following ioctl. Similar to the
- * struct tm in <time.h>, but it needs to be here so that the kernel
- * source is self contained, allowing cross-compiles, etc. etc.
- */
-typedef struct rtc_time {
-	int tm_sec;
-	int tm_min;
-	int tm_hour;
-	int tm_mday;
-	int tm_mon;
-	int tm_year;
-	int tm_wday;
-	int tm_yday;
-} SystemTime_t;
-
-/*
- * This data structure is inspired by the EFI (v0.92) wakeup
- * alarm API.
- */
-struct rtc_wkalrm {
-	unsigned char enabled;	/* 0 = alarm disabled, 1 = alarm enabled */
-	unsigned char pending;  /* 0 = alarm not pending, 1 = alarm pending */
-	struct rtc_time time;	/* time the alarm is set to */
-};
-
-static inline int is_leap_year(unsigned int year)
-{
-	return (!(year % 4) && (year % 100)) || !(year % 400);
-}
 
+//	Real-time clock related
 int rtc_time_init(void);
-
 int iGetLocalTime(SystemTime_t *tm);
-
 void vSetLocalTime(SystemTime_t *tm);
 
 

+ 140 - 7
amt630hv160-mcu/amt630hv160-mcu-iram/src/ArkmicroFiles/libcpu-amt630hv160/source/amt630hv160_rtc.c

@@ -10,6 +10,8 @@
 
 /* Includes ------------------------------------------------------------------*/
 #include <intrinsics.h>
+#include <stdio.h>
+#include <string.h>
 #include "amt630hv160_lib.h"
 
 /* 2020-01-01 Wednesday */
@@ -79,6 +81,7 @@ void RTC_PowerDown(int fastboot)
 	u32 val = RTC->PARA;
 
 	__disable_interrupt();
+
 	RTC_SendCmd(RTC_ISOForce, 0);
 
 	val &= ~(0xff << 24);
@@ -90,16 +93,22 @@ void RTC_PowerDown(int fastboot)
 		RTC_WriteReg(RTC_PARA, &RTC->PARA, val);
 	}
 
-	//rtc mcu power delay 4ms
+	//rtc mcu reset delay 100ms
 	val = RTC->RAM_L;
 	val &= ~0xff;
-	val |= 0x4;
+	val |= 100;					//确保power信号拉高到MCU开始工作时间大于所有电源稳定时间
 	RTC_WriteReg(RTC_RAML, &RTC->RAM_L, val);
 
+	//rtc mcu power on/off delay 100ms
+	val = RTC->PMC;
+	val &= ~(0xff << 8);
+	val |= (100 << 8);			//确保延时时间的一半大于休眠时从power信号拉低到外部器件完全掉电的时间
+	RTC_WriteReg(RTC_PMC, &RTC->PMC, val);
+
 	//rtc switch to 32k crystal
 	RTC_SendCmd(RTC_Clk32KSel, 1);
 
-	TIMER_Mdelay(100);
+	TIMER_Mdelay(10);
 	//power off
 	RTC_SendCmd(RTC_PowerOff, 1);
 }
@@ -124,6 +133,9 @@ void RTC_CanStbOut(int id, int value)
 	RTC_WriteReg(RTC_GPIO, &RTC->GPIO, val);
 }
 
+/*
+	各唤醒源默认为打开状态,不使用的唤醒源需手动将其关闭
+*/
 void RTC_SetWakeup(eRTCWakeupSource src, eRTCWakeupMode mode, int enable)
 {
 	u8 enbit;
@@ -133,25 +145,146 @@ void RTC_SetWakeup(eRTCWakeupSource src, eRTCWakeupMode mode, int enable)
 	int mask = !enable;
 
 	val = RTC->PMC;
-	//RTC_WAKEUP only support rise edge
+
 	if (src == RTC_WAKEUP_RTC) {
 		RTC_SendCmd(RTC_DelayWakeUp, 1);
-	} else {
+	} else if (src == RTC_WAKEUP_ACC) {
+		//ACC_WAKEUP only support edge wakeup
 		mbit = modebits[src - RTC_WAKEUP_GPIO1];
 		if (mode == RTC_WAKEUP_RISING)
 			val &= ~(1 << mbit);
 		else if (mode == RTC_WAKEUP_FALLING)
 			val |= 1 << mbit;
+	} else {
+		mbit = modebits[src - RTC_WAKEUP_GPIO1];
+		switch (mode) {
+		case RTC_WAKEUP_RISING:
+			val &= ~(1 << mbit);
+			val &= ~(1 << (mbit - 1));
+			break;
+		case RTC_WAKEUP_FALLING:
+			val |= 1 << mbit;
+			val &= ~(1 << (mbit - 1));
+			break;
+		case RTC_WAKEUP_HIGHLEVEL:
+			val &= ~(1 << mbit);
+			val |= 1 << (mbit - 1);
+			break;
+		case RTC_WAKEUP_LOWLEVEL:
+			val |= 1 << mbit;
+			val |= 1 << (mbit - 1);
+			break;
+		}
 	}
 
 	enbit = 26 + (src - RTC_WAKEUP_GPIO1);
-	if (mask)
+	if (mask) {
 		val |= 1 << enbit;
-	else
+		//关闭唤醒需要切换到沿唤醒模式
+		if (src != RTC_WAKEUP_RTC && src != RTC_WAKEUP_ACC)
+			val &= ~(1 << (mbit - 1));
+	} else {
 		val &= ~(1 << enbit);
+	}
 	RTC_WriteReg(RTC_PMC, &RTC->PMC, val);
 }
 
+/*
+	获取芯片启动状态
+*/
+void RTC_WakeupDetect(void)
+{
+	printf("###########################\n");
+	if (!(RTC->RTCSTA & RTC_STA_SLEEPMODE)) {
+		printf("chip is power boot.\n");
+	} else {
+		if (RTC->RTCSTA & RTC_STA_GPIO0ACT) {
+			printf("chip is gpio0 wakeup boot.\n");
+		} else if (RTC->RTCSTA & RTC_STA_GPIO1ACT) {
+			printf("chip is gpio1 wakeup boot.\n");
+		} else if (RTC->RTCSTA & RTC_STA_CAN0ACT) {
+			printf("chip is can0 wakeup boot.\n");
+		} else if (RTC->RTCSTA & RTC_STA_CAN1ACT) {
+			printf("chip is can1 wakeup boot.\n");
+		} else if (RTC->RTCSTA & RTC_STA_ACCACT) {
+			printf("chip is acc wakeup boot.\n");
+		} else if (RTC->RTCSTA & RTC_STA_RTCACT) {
+			printf("chip is rtc wakeup boot.\n");
+		}
+	}
+	printf("###########################\n");
+}
+
+int RTC_ReadSleepData(void)
+{
+	uint32_t sleep_data_size, sleep_data_crc;
+	uint32_t sleep_data_phy_addr = MCU_IRAM_BASE + FASTBOOT_MAX_SIZE;	//change FASTBOOT_MAX_SIZE to 0x2000;
+	uint32_t sleep_data_virt_addr = (uint32_t)__section_begin("sleep_critical_data");
+
+	if (__section_size("sleep_critical_data") > IRAM_SLEEP_DATA_MAX_SIZE) {
+		printf("%s, sleep_data_size over the sleep section size.\n", __func__);
+		return -1;
+	}
+
+	RTC_SendCmd(RTC_ISOForce, 1);
+	sleep_data_size = *(uint32_t *)sleep_data_phy_addr;
+	if (sleep_data_size != __section_size("sleep_critical_data")) {
+		//printf("sleep_data_size:%d, section : %d.\n", sleep_data_size, __section_size("sleep_critical_data"));
+		RTC_SendCmd(RTC_ISOForce, 0);
+		printf("%s, invalid sleep data.\n", __func__);
+		return -1;
+	}
+	//printf("read sleep data size %d.\n", sleep_data_size);
+	sleep_data_crc = *(uint32_t *)(sleep_data_phy_addr + 4);
+	if (sleep_data_crc != xcrc32((void *)(sleep_data_phy_addr + 8), sleep_data_size, 0xFFFFFFFF, HARD_CALC_CRC)) {
+		//printf("sleep_data_crc:%d, calc : %d.\n", sleep_data_crc, xcrc32((void *)(sleep_data_phy_addr + 8), sleep_data_size, 0xFFFFFFFF, HARD_CALC_CRC));
+		RTC_SendCmd(RTC_ISOForce, 0);
+		printf("%s, invalid sleep data check fail.\n", __func__);
+		return -1;
+	}
+
+	memcpy((void *)sleep_data_virt_addr, (void *)(sleep_data_phy_addr + 8), sleep_data_size);
+	RTC_SendCmd(RTC_ISOForce, 0);
+	return 0;
+}
+
+int RTC_SaveSleepData(void)
+{
+	uint32_t sleep_data_size = __section_size("sleep_critical_data");
+	uint32_t sleep_data_phy_addr = MCU_IRAM_BASE + FASTBOOT_MAX_SIZE;	//change FASTBOOT_MAX_SIZE to 0x2000;
+	uint32_t sleep_data_virt_addr = (uint32_t)__section_begin("sleep_critical_data");
+
+	if (sleep_data_size > IRAM_SLEEP_DATA_MAX_SIZE) {
+		printf("%s, sleep_data_size over the sleep section size.\n", __func__);
+		return -1;
+	}
+
+	RTC_SendCmd(RTC_ISOForce, 1);
+	__disable_interrupt();
+	*(uint32_t *)sleep_data_phy_addr = sleep_data_size;
+	*(uint32_t *)(sleep_data_phy_addr + 4) = xcrc32((void *)sleep_data_virt_addr, sleep_data_size, 0xFFFFFFFF, SOFT_CALC_CRC);
+	if (*(uint32_t *)(sleep_data_phy_addr + 4) == 0xffffffff) {
+		printf("%s, crc calc error.\n", __func__);
+		__enable_interrupt();
+		RTC_SendCmd(RTC_ISOForce, 0);
+		return -1;
+	}
+	memcpy((void *)(sleep_data_phy_addr + 8), (void *)sleep_data_virt_addr, sleep_data_size);
+
+	//read back check
+	if ((*(uint32_t *)sleep_data_phy_addr != sleep_data_size) ||
+		(*(uint32_t *)(sleep_data_phy_addr + 4) != xcrc32((void *)(sleep_data_phy_addr + 8), sleep_data_size, 0xFFFFFFFF, SOFT_CALC_CRC))) {
+		printf("save sleep data fail.\n");
+	} else {
+		printf("save sleep data ok.\n");
+		//printf("sleep data size %d.\n", sleep_data_size);
+	}
+	__enable_interrupt();
+
+	RTC_SendCmd(RTC_ISOForce, 0);
+	return 0;
+}
+
 /*
  * The number of days in the month.
  */

+ 7 - 2
amt630hv160-mcu/amt630hv160-mcu-iram/src/amt630hv160_conf.h

@@ -96,6 +96,11 @@
 
 /************************************* RTC ************************************/
 #define _RTC
+#define RTC_ACCWAKEUP_DEMO		1
+#define RTC_RTCWAKEUP_DEMO		2
+#define RTC_GPIO0WAKEUP_DEMO	3
+#define RTC_GPIO1WAKEUP_DEMO	4
+#define RTC_DEMO				0//RTC_ACCWAKEUP_DEMO
 
 /************************************* CANFD ************************************/
 #define _CANFD
@@ -328,7 +333,7 @@
 #define IMAGE_MAX_SIZE				0x1E000
 #define FASTBOOTA_OFFSET			0x40000
 #define FASTBOOTB_OFFSET			0x44000
-#define FASTBOOT_MAX_SIZE			0x4000
+#define FASTBOOT_MAX_SIZE			0x2000
 #define DCIC_ROM_OFFSETA			0x48000
 #define DCIC_ROM_OFFSETB			0x66000
 #define DCIC_ROM_MAX_SIZE			0x1e000
@@ -346,7 +351,7 @@
 #define IMAGE_MAX_SIZE				0x80000
 #define FASTBOOTA_OFFSET			0x200000
 #define FASTBOOTB_OFFSET			0x280000
-#define FASTBOOT_MAX_SIZE			0x4000
+#define FASTBOOT_MAX_SIZE			0x2000
 #define DCIC_ROM_OFFSETA			0x300000
 #define DCIC_ROM_OFFSETB			0x380000
 #define DCIC_ROM_MAX_SIZE			0x80000

+ 14 - 0
amt630hv160-mcu/amt630hv160-mcu-iram/src/main.c

@@ -40,6 +40,10 @@ extern void adc_demo(void);
 #endif
 #ifdef MEDIA_UPDATE_SUPPORT
 extern void MediaUpdateReceiveDemo(void);
+#if RTC_DEMO
+extern void rtc_sleep_demo(void);
+extern void rtc_wakeup_demo(void);
+#endif
 #endif
 
 void SystemInit(void)
@@ -142,6 +146,12 @@ static void prvSetupHardware( void )
 #ifdef _MCU_GPIO
 	GPIO_IrqRegister();
 #endif
+#ifdef 	_RTC
+	RTC_WakeupDetect();
+#if RTC_DEMO
+	rtc_wakeup_demo();
+#endif
+#endif
 }
 
 #ifdef APP_FOR_BURN
@@ -610,6 +620,10 @@ static void MainTask(void *pvParameters)
 	adc_demo();
 #endif
 
+#if RTC_DEMO
+	rtc_sleep_demo();
+#endif
+
 #if CAN_DEMO
 	RTC_CanStbOut(0, 0);
 	RTC_CanStbOut(1, 0);

+ 3 - 0
amt630hv160-mcu/amt630hv160-mcu-sram-nos/amt630hv160.ewp

@@ -2091,6 +2091,9 @@
             <file>
                 <name>$PROJ_DIR$\src\App\mpu_demo.c</name>
             </file>
+            <file>
+                <name>$PROJ_DIR$\src\App\rtc_demo.c</name>
+            </file>
             <file>
                 <name>$PROJ_DIR$\src\App\secure_funcs.c</name>
             </file>

+ 141 - 0
amt630hv160-mcu/amt630hv160-mcu-sram-nos/src/App/rtc_demo.c

@@ -0,0 +1,141 @@
+#include <stdio.h>
+#include "amt630hv160_lib.h"
+
+
+#ifdef _RTC
+#if RTC_DEMO
+static uint8_t __attribute__( ( section( "sleep_critical_data" ) ) ) PRIVATE1_RAM_BUFFER[16];
+static uint8_t __attribute__( ( section( "sleep_critical_data" ) ) ) PRIVATE2_RAM_BUFFER[16];
+
+/*
+	唤醒源配置可提前在系统启动时配置
+*/
+#if RTC_DEMO == RTC_ACCWAKEUP_DEMO
+void entry_acc_sleep(int fastboot, u8 wakeup_mode)
+{
+	if (wakeup_mode >= RTC_WAKEUP_HIGHLEVEL) {
+		printf("acc not support wakeup mode, sleep fail.\n");
+		return;
+	}
+
+	//wakeup source config
+	RTC_SetWakeup(RTC_WAKEUP_GPIO0, RTC_WAKEUP_RISING, 0);
+	RTC_SetWakeup(RTC_WAKEUP_GPIO1, RTC_WAKEUP_RISING, 0);
+	RTC_SetWakeup(RTC_WAKEUP_CAN1, RTC_WAKEUP_RISING, 0);
+	RTC_SetWakeup(RTC_WAKEUP_CAN0, RTC_WAKEUP_RISING, 0);
+	RTC_SetWakeup(RTC_WAKEUP_RTC, RTC_WAKEUP_RISING, 0);
+	RTC_SetWakeup(RTC_WAKEUP_ACC, RTC_WAKEUP_RISING, 1);
+	if (RTC_SaveSleepData())
+		return;
+
+	printf("entry sleep.\n");
+	RTC_SendCmd(RTC_SleepMode, 1);
+	RTC_PowerDown(fastboot);
+}
+
+#elif RTC_DEMO == RTC_RTCWAKEUP_DEMO
+void entry_rtc_sleep(u32 time_s)
+{
+	if (time_s == 0)
+		time_s = 1;
+
+	//wakeup source config
+	RTC_SetWakeup(RTC_WAKEUP_GPIO0, RTC_WAKEUP_RISING, 0);
+	RTC_SetWakeup(RTC_WAKEUP_GPIO1, RTC_WAKEUP_RISING, 0);
+	RTC_SetWakeup(RTC_WAKEUP_CAN1, RTC_WAKEUP_RISING, 0);
+	RTC_SetWakeup(RTC_WAKEUP_CAN0, RTC_WAKEUP_RISING, 0);
+	RTC_SetWakeup(RTC_WAKEUP_RTC, RTC_WAKEUP_RISING, 1);
+	RTC_SetWakeup(RTC_WAKEUP_ACC, RTC_WAKEUP_RISING, 0);
+
+	printf("entry sleep time %ds.\n", time_s);
+	RTC_SendCmd(RTC_DelayWakeUp, 1);
+	if (RTC->CNT_L > 0x6000)	//若小数部分超过0.75s,则加1s
+		time_s += 1;
+
+	RTC_WriteReg(RTC_RAMH, &RTC->RAM_H, RTC->CNT_H + time_s);//config sleep time
+	RTC_SendCmd(RTC_SleepMode, 1);
+	RTC_PowerDown(0);
+}
+#elif RTC_DEMO == RTC_GPIO0WAKEUP_DEMO
+void entry_gpio0_sleep(int fastboot, u8 wakeup_mode)
+{
+	if (wakeup_mode >= RTC_WAKEUP_NOCHANGE) {
+		printf("gpio0 not support wakeup mode, sleep fail.\n");
+		return;
+	}
+
+	//wakeup source config
+	RTC_SetWakeup(RTC_WAKEUP_GPIO0, wakeup_mode, 1);
+	RTC_SetWakeup(RTC_WAKEUP_GPIO1, RTC_WAKEUP_RISING, 0);
+	RTC_SetWakeup(RTC_WAKEUP_CAN1, RTC_WAKEUP_RISING, 0);
+	RTC_SetWakeup(RTC_WAKEUP_CAN0, RTC_WAKEUP_RISING, 0);
+	RTC_SetWakeup(RTC_WAKEUP_RTC, RTC_WAKEUP_RISING, 0);
+	RTC_SetWakeup(RTC_WAKEUP_ACC, RTC_WAKEUP_RISING, 0);
+
+	printf("entry sleep.\n");
+	RTC_SendCmd(RTC_SleepMode, 1);
+	RTC_PowerDown(fastboot);
+}
+#elif RTC_DEMO == RTC_GPIO1WAKEUP_DEMO
+void entry_gpio1_sleep(int fastboot, u8 wakeup_mode)
+{
+	if (wakeup_mode >= RTC_WAKEUP_NOCHANGE) {
+		printf("gpio1 not support wakeup mode, sleep fail.\n");
+		return;
+	}
+
+	//wakeup source config
+	RTC_SetWakeup(RTC_WAKEUP_GPIO0, RTC_WAKEUP_RISING, 0);
+	RTC_SetWakeup(RTC_WAKEUP_GPIO1, wakeup_mode, 1);
+	RTC_SetWakeup(RTC_WAKEUP_CAN1, RTC_WAKEUP_RISING, 0);
+	RTC_SetWakeup(RTC_WAKEUP_CAN0, RTC_WAKEUP_RISING, 0);
+	RTC_SetWakeup(RTC_WAKEUP_RTC, RTC_WAKEUP_RISING, 0);
+	RTC_SetWakeup(RTC_WAKEUP_ACC, RTC_WAKEUP_RISING, 0);
+
+	printf("entry sleep.\n");
+	RTC_SendCmd(RTC_SleepMode, 1);
+	RTC_PowerDown(fastboot);
+}
+#endif
+
+void rtc_wakeup_demo(void)
+{
+	if (!RTC_ReadSleepData()) {
+		printf("P1_BUF[0]: 0x%x, P1_BUF[15]: 0x%x, P2_BUF[0]: 0x%x, P2_BUF[15]: 0x%x.\n",
+		PRIVATE1_RAM_BUFFER[0], PRIVATE1_RAM_BUFFER[15], PRIVATE2_RAM_BUFFER[0], PRIVATE2_RAM_BUFFER[15]);
+	}
+}
+
+void rtc_sleep_demo(void)
+{
+	TIMER_Mdelay(5000);		//系统延时5s后进入休眠
+	if (!(RTC->RTCSTA & RTC_STA_SLEEPMODE)) {
+#if RTC_DEMO == RTC_ACCWAKEUP_DEMO
+		//The simulation goes to sleep after accessing swl data
+		PRIVATE1_RAM_BUFFER[0] = 0x55;
+		PRIVATE1_RAM_BUFFER[15] = 0xaa;
+		PRIVATE2_RAM_BUFFER[0] = 0x5a;
+		PRIVATE2_RAM_BUFFER[15] = 0xa5;
+
+		entry_acc_sleep(0, RTC_WAKEUP_RISING);
+#elif RTC_DEMO == RTC_RTCWAKEUP_DEMO
+		entry_rtc_sleep(10);
+#elif RTC_DEMO == RTC_GPIO0WAKEUP_DEMO
+		entry_gpio0_sleep(0, RTC_WAKEUP_RISING);
+#elif RTC_DEMO == RTC_GPIO1WAKEUP_DEMO
+		entry_gpio1_sleep(0, RTC_WAKEUP_RISING);
+#endif
+	} else {
+		printf("normal running.\n");
+		//The simulated fault generation results in a wdt reset.
+#if RTC_DEMO == RTC_ACCWAKEUP_DEMO
+		//wakeup boot delay 10s entry wdt reset
+		if (RTC->RTCSTA & RTC_STA_ACCACT) {
+			TIMER_Mdelay(10000);
+			WDT_CpuReboot();
+		}
+#endif
+	}
+}
+#endif
+#endif

+ 41 - 34
amt630hv160-mcu/amt630hv160-mcu-sram-nos/src/ArkmicroFiles/libcpu-amt630hv160/include/amt630hv160_rtc.h

@@ -17,7 +17,6 @@
 #include "amt630hv160_map.h"
 
 /* Exported types ------------------------------------------------------------*/
-/* Exported constants --------------------------------------------------------*/
 typedef enum {
 	RTC_PowerOff,
 	RTC_DelayWakeUp,
@@ -59,6 +58,40 @@ typedef enum {
 	RTC_WAKEUP_NOCHANGE,
 } eRTCWakeupMode;
 
+/*
+ * The struct used to pass data via the following ioctl. Similar to the
+ * struct tm in <time.h>, but it needs to be here so that the kernel
+ * source is self contained, allowing cross-compiles, etc. etc.
+ */
+typedef struct rtc_time {
+	int tm_sec;
+	int tm_min;
+	int tm_hour;
+	int tm_mday;
+	int tm_mon;
+	int tm_year;
+	int tm_wday;
+	int tm_yday;
+} SystemTime_t;
+
+/*
+ * This data structure is inspired by the EFI (v0.92) wakeup
+ * alarm API.
+ */
+struct rtc_wkalrm {
+	unsigned char enabled;	/* 0 = alarm disabled, 1 = alarm enabled */
+	unsigned char pending;  /* 0 = alarm not pending, 1 = alarm pending */
+	struct rtc_time time;	/* time the alarm is set to */
+};
+
+/* Exported constants --------------------------------------------------------*/
+static inline int is_leap_year(unsigned int year)
+{
+	return (!(year % 4) && (year % 100)) || !(year % 400);
+}
+
+#pragma section = "sleep_critical_data"
+
 /* Exported macro ------------------------------------------------------------*/
 //RTC_CTL register fields defination
 #define CTL_CTL3_VALUE(x)				(x<<23)
@@ -118,50 +151,24 @@ typedef enum {
 #define RTC_STA_RTCACT					(1 << 14)
 #define RTC_STA_GPIO0IN					(1 << 15)
 
+#define IRAM_SLEEP_DATA_MAX_SIZE		(0x2000 - 8)
+
 /* Exported functions ------------------------------------------------------- */
+//	Sleep and wake-up related
 void RTC_SendCmd(eRTCCmd cmd, int enable);
 void RTC_WriteReg(eRTCCmd cmd, vu32 *reg, u32 value);
 void RTC_SetWatchdog(eRTCWdtTmo tmo, int enable);
 void RTC_PowerDown(int fastboot);
-void RTC_WaitNotBusy(void);
 void RTC_CanStbOut(int id, int value);
 void RTC_SetWakeup(eRTCWakeupSource src, eRTCWakeupMode mode, int enable);
+void RTC_WakeupDetect(void);
+int RTC_SaveSleepData(void);
+int RTC_ReadSleepData(void);
 
-/*
- * The struct used to pass data via the following ioctl. Similar to the
- * struct tm in <time.h>, but it needs to be here so that the kernel
- * source is self contained, allowing cross-compiles, etc. etc.
- */
-typedef struct rtc_time {
-	int tm_sec;
-	int tm_min;
-	int tm_hour;
-	int tm_mday;
-	int tm_mon;
-	int tm_year;
-	int tm_wday;
-	int tm_yday;
-} SystemTime_t;
-
-/*
- * This data structure is inspired by the EFI (v0.92) wakeup
- * alarm API.
- */
-struct rtc_wkalrm {
-	unsigned char enabled;	/* 0 = alarm disabled, 1 = alarm enabled */
-	unsigned char pending;  /* 0 = alarm not pending, 1 = alarm pending */
-	struct rtc_time time;	/* time the alarm is set to */
-};
-
-static inline int is_leap_year(unsigned int year)
-{
-	return (!(year % 4) && (year % 100)) || !(year % 400);
-}
 
+//	Real-time clock related
 int rtc_time_init(void);
-
 int iGetLocalTime(SystemTime_t *tm);
-
 void vSetLocalTime(SystemTime_t *tm);
 
 

+ 140 - 7
amt630hv160-mcu/amt630hv160-mcu-sram-nos/src/ArkmicroFiles/libcpu-amt630hv160/source/amt630hv160_rtc.c

@@ -10,6 +10,8 @@
 
 /* Includes ------------------------------------------------------------------*/
 #include <intrinsics.h>
+#include <stdio.h>
+#include <string.h>
 #include "amt630hv160_lib.h"
 
 /* 2020-01-01 Wednesday */
@@ -79,6 +81,7 @@ void RTC_PowerDown(int fastboot)
 	u32 val = RTC->PARA;
 
 	__disable_interrupt();
+
 	RTC_SendCmd(RTC_ISOForce, 0);
 
 	val &= ~(0xff << 24);
@@ -90,16 +93,22 @@ void RTC_PowerDown(int fastboot)
 		RTC_WriteReg(RTC_PARA, &RTC->PARA, val);
 	}
 
-	//rtc mcu power delay 4ms
+	//rtc mcu reset delay 100ms
 	val = RTC->RAM_L;
 	val &= ~0xff;
-	val |= 0x4;
+	val |= 100;					//确保power信号拉高到MCU开始工作时间大于所有电源稳定时间
 	RTC_WriteReg(RTC_RAML, &RTC->RAM_L, val);
 
+	//rtc mcu power on/off delay 100ms
+	val = RTC->PMC;
+	val &= ~(0xff << 8);
+	val |= (100 << 8);			//确保延时时间的一半大于休眠时从power信号拉低到外部器件完全掉电的时间
+	RTC_WriteReg(RTC_PMC, &RTC->PMC, val);
+
 	//rtc switch to 32k crystal
 	RTC_SendCmd(RTC_Clk32KSel, 1);
 
-	TIMER_Mdelay(100);
+	TIMER_Mdelay(10);
 	//power off
 	RTC_SendCmd(RTC_PowerOff, 1);
 }
@@ -124,6 +133,9 @@ void RTC_CanStbOut(int id, int value)
 	RTC_WriteReg(RTC_GPIO, &RTC->GPIO, val);
 }
 
+/*
+	各唤醒源默认为打开状态,不使用的唤醒源需手动将其关闭
+*/
 void RTC_SetWakeup(eRTCWakeupSource src, eRTCWakeupMode mode, int enable)
 {
 	u8 enbit;
@@ -133,25 +145,146 @@ void RTC_SetWakeup(eRTCWakeupSource src, eRTCWakeupMode mode, int enable)
 	int mask = !enable;
 
 	val = RTC->PMC;
-	//RTC_WAKEUP only support rise edge
+
 	if (src == RTC_WAKEUP_RTC) {
 		RTC_SendCmd(RTC_DelayWakeUp, 1);
-	} else {
+	} else if (src == RTC_WAKEUP_ACC) {
+		//ACC_WAKEUP only support edge wakeup
 		mbit = modebits[src - RTC_WAKEUP_GPIO1];
 		if (mode == RTC_WAKEUP_RISING)
 			val &= ~(1 << mbit);
 		else if (mode == RTC_WAKEUP_FALLING)
 			val |= 1 << mbit;
+	} else {
+		mbit = modebits[src - RTC_WAKEUP_GPIO1];
+		switch (mode) {
+		case RTC_WAKEUP_RISING:
+			val &= ~(1 << mbit);
+			val &= ~(1 << (mbit - 1));
+			break;
+		case RTC_WAKEUP_FALLING:
+			val |= 1 << mbit;
+			val &= ~(1 << (mbit - 1));
+			break;
+		case RTC_WAKEUP_HIGHLEVEL:
+			val &= ~(1 << mbit);
+			val |= 1 << (mbit - 1);
+			break;
+		case RTC_WAKEUP_LOWLEVEL:
+			val |= 1 << mbit;
+			val |= 1 << (mbit - 1);
+			break;
+		}
 	}
 
 	enbit = 26 + (src - RTC_WAKEUP_GPIO1);
-	if (mask)
+	if (mask) {
 		val |= 1 << enbit;
-	else
+		//关闭唤醒需要切换到沿唤醒模式
+		if (src != RTC_WAKEUP_RTC && src != RTC_WAKEUP_ACC)
+			val &= ~(1 << (mbit - 1));
+	} else {
 		val &= ~(1 << enbit);
+	}
 	RTC_WriteReg(RTC_PMC, &RTC->PMC, val);
 }
 
+/*
+	获取芯片启动状态
+*/
+void RTC_WakeupDetect(void)
+{
+	printf("###########################\n");
+	if (!(RTC->RTCSTA & RTC_STA_SLEEPMODE)) {
+		printf("chip is power boot.\n");
+	} else {
+		if (RTC->RTCSTA & RTC_STA_GPIO0ACT) {
+			printf("chip is gpio0 wakeup boot.\n");
+		} else if (RTC->RTCSTA & RTC_STA_GPIO1ACT) {
+			printf("chip is gpio1 wakeup boot.\n");
+		} else if (RTC->RTCSTA & RTC_STA_CAN0ACT) {
+			printf("chip is can0 wakeup boot.\n");
+		} else if (RTC->RTCSTA & RTC_STA_CAN1ACT) {
+			printf("chip is can1 wakeup boot.\n");
+		} else if (RTC->RTCSTA & RTC_STA_ACCACT) {
+			printf("chip is acc wakeup boot.\n");
+		} else if (RTC->RTCSTA & RTC_STA_RTCACT) {
+			printf("chip is rtc wakeup boot.\n");
+		}
+	}
+	printf("###########################\n");
+}
+
+int RTC_ReadSleepData(void)
+{
+	uint32_t sleep_data_size, sleep_data_crc;
+	uint32_t sleep_data_phy_addr = MCU_IRAM_BASE + FASTBOOT_MAX_SIZE;	//change FASTBOOT_MAX_SIZE to 0x2000;
+	uint32_t sleep_data_virt_addr = (uint32_t)__section_begin("sleep_critical_data");
+
+	if (__section_size("sleep_critical_data") > IRAM_SLEEP_DATA_MAX_SIZE) {
+		printf("%s, sleep_data_size over the sleep section size.\n", __func__);
+		return -1;
+	}
+
+	RTC_SendCmd(RTC_ISOForce, 1);
+	sleep_data_size = *(uint32_t *)sleep_data_phy_addr;
+	if (sleep_data_size != __section_size("sleep_critical_data")) {
+		//printf("sleep_data_size:%d, section : %d.\n", sleep_data_size, __section_size("sleep_critical_data"));
+		RTC_SendCmd(RTC_ISOForce, 0);
+		printf("%s, invalid sleep data.\n", __func__);
+		return -1;
+	}
+	//printf("read sleep data size %d.\n", sleep_data_size);
+	sleep_data_crc = *(uint32_t *)(sleep_data_phy_addr + 4);
+	if (sleep_data_crc != xcrc32((void *)(sleep_data_phy_addr + 8), sleep_data_size, 0xFFFFFFFF, HARD_CALC_CRC)) {
+		//printf("sleep_data_crc:%d, calc : %d.\n", sleep_data_crc, xcrc32((void *)(sleep_data_phy_addr + 8), sleep_data_size, 0xFFFFFFFF, HARD_CALC_CRC));
+		RTC_SendCmd(RTC_ISOForce, 0);
+		printf("%s, invalid sleep data check fail.\n", __func__);
+		return -1;
+	}
+
+	memcpy((void *)sleep_data_virt_addr, (void *)(sleep_data_phy_addr + 8), sleep_data_size);
+	RTC_SendCmd(RTC_ISOForce, 0);
+	return 0;
+}
+
+int RTC_SaveSleepData(void)
+{
+	uint32_t sleep_data_size = __section_size("sleep_critical_data");
+	uint32_t sleep_data_phy_addr = MCU_IRAM_BASE + FASTBOOT_MAX_SIZE;	//change FASTBOOT_MAX_SIZE to 0x2000;
+	uint32_t sleep_data_virt_addr = (uint32_t)__section_begin("sleep_critical_data");
+
+	if (sleep_data_size > IRAM_SLEEP_DATA_MAX_SIZE) {
+		printf("%s, sleep_data_size over the sleep section size.\n", __func__);
+		return -1;
+	}
+
+	RTC_SendCmd(RTC_ISOForce, 1);
+	__disable_interrupt();
+	*(uint32_t *)sleep_data_phy_addr = sleep_data_size;
+	*(uint32_t *)(sleep_data_phy_addr + 4) = xcrc32((void *)sleep_data_virt_addr, sleep_data_size, 0xFFFFFFFF, SOFT_CALC_CRC);
+	if (*(uint32_t *)(sleep_data_phy_addr + 4) == 0xffffffff) {
+		printf("%s, crc calc error.\n", __func__);
+		__enable_interrupt();
+		RTC_SendCmd(RTC_ISOForce, 0);
+		return -1;
+	}
+	memcpy((void *)(sleep_data_phy_addr + 8), (void *)sleep_data_virt_addr, sleep_data_size);
+
+	//read back check
+	if ((*(uint32_t *)sleep_data_phy_addr != sleep_data_size) ||
+		(*(uint32_t *)(sleep_data_phy_addr + 4) != xcrc32((void *)(sleep_data_phy_addr + 8), sleep_data_size, 0xFFFFFFFF, SOFT_CALC_CRC))) {
+		printf("save sleep data fail.\n");
+	} else {
+		printf("save sleep data ok.\n");
+		//printf("sleep data size %d.\n", sleep_data_size);
+	}
+	__enable_interrupt();
+
+	RTC_SendCmd(RTC_ISOForce, 0);
+	return 0;
+}
+
 /*
  * The number of days in the month.
  */

+ 5 - 3
amt630hv160-mcu/amt630hv160-mcu-sram-nos/src/amt630hv160_conf.h

@@ -98,7 +98,9 @@
 #define _RTC
 #define RTC_ACCWAKEUP_DEMO		1
 #define RTC_RTCWAKEUP_DEMO		2
-#define RTC_DEMO				0
+#define RTC_GPIO0WAKEUP_DEMO	3
+#define RTC_GPIO1WAKEUP_DEMO	4
+#define RTC_DEMO				0//RTC_ACCWAKEUP_DEMO
 
 /************************************* CANFD ************************************/
 #define _CANFD
@@ -329,7 +331,7 @@
 #define IMAGE_MAX_SIZE				0x1E000
 #define FASTBOOTA_OFFSET			0x40000
 #define FASTBOOTB_OFFSET			0x44000
-#define FASTBOOT_MAX_SIZE			0x4000
+#define FASTBOOT_MAX_SIZE			0x2000
 #define CPU_SYSINFOA_OFFSET			0x100000
 #define CPU_SYSINFOB_OFFSET			0x101000
 #define CPU_LOADERA_OFFSET			0x102000
@@ -344,7 +346,7 @@
 #define IMAGE_MAX_SIZE				0x80000
 #define FASTBOOTA_OFFSET			0x200000
 #define FASTBOOTB_OFFSET			0x280000
-#define FASTBOOT_MAX_SIZE			0x4000
+#define FASTBOOT_MAX_SIZE			0x2000
 #define CPU_SYSINFOA_OFFSET			0x1000000
 #define CPU_SYSINFOB_OFFSET			0X1080000
 #define CPU_LOADERA_OFFSET			0X1100000

+ 11 - 87
amt630hv160-mcu/amt630hv160-mcu-sram-nos/src/main.c

@@ -36,60 +36,8 @@ extern void can_ecu_demo(void);
 extern void can_host_demo(void);
 
 #if RTC_DEMO
-void rtc_wakeup_detect(void)
-{
-	RTC_SendCmd(RTC_ISOForce, 1);
-	printf("###########################\n");
-	if (!(RTC->RTCSTA & RTC_STA_SLEEPMODE)) {
-	  printf("chip is power boot.\n");
-	} else {
-		if (RTC->RTCSTA & RTC_STA_GPIO0ACT) {
-			printf("chip is gpio0 wakeup boot.\n");
-		} else if (RTC->RTCSTA & RTC_STA_GPIO1ACT) {
-			printf("chip is gpio1 wakeup boot.\n");
-		} else if (RTC->RTCSTA & RTC_STA_CAN0ACT) {
-			printf("chip is can0 wakeup boot.\n");
-		} else if (RTC->RTCSTA & RTC_STA_CAN1ACT) {
-			printf("chip is can1 wakeup boot.\n");
-		} else if (RTC->RTCSTA & RTC_STA_ACCACT) {
-			printf("chip is acc wakeup boot.\n");
-		} else if (RTC->RTCSTA & RTC_STA_RTCACT) {
-			printf("chip is rtc wakeup boot.\n");
-		}
-	}
-	printf("###########################\n");
-
-}
-
-
-#if RTC_DEMO == RTC_ACCWAKEUP_DEMO
-//#define FASTBOOT_DEMO
-#ifndef FASTBOOT_DEMO
-__attribute__( ( section( "swl_critical_data" ) ) )
-static uint32_t data;
-#endif
-#endif
-
-#if RTC_DEMO == RTC_RTCWAKEUP_DEMO
-void entry_rtc_sleep(u32 time_s)
-{
-	RTC_SetWakeup(RTC_WAKEUP_GPIO0, RTC_WAKEUP_RISING, 0);
-	RTC_SetWakeup(RTC_WAKEUP_GPIO1, RTC_WAKEUP_RISING, 0);
-	RTC_SetWakeup(RTC_WAKEUP_CAN1, RTC_WAKEUP_RISING, 0);
-	RTC_SetWakeup(RTC_WAKEUP_CAN0, RTC_WAKEUP_RISING, 0);
-	RTC_SetWakeup(RTC_WAKEUP_RTC, RTC_WAKEUP_RISING, 1);
-	RTC_SetWakeup(RTC_WAKEUP_ACC, RTC_WAKEUP_RISING, 0);
-	if (!(RTC->RTCSTA & RTC_STA_SLEEPMODE)) {
-		printf("entry sleep time %ds.\n", time_s);
-		RTC_SendCmd(RTC_DelayWakeUp, 1);
-		RTC_WriteReg(RTC_RAMH, &RTC->RAM_H, RTC->CNT_H + time_s);//config sleep time
-		//printf("cnt_h:%d,ramh:%d\n", RTC->CNT_H, RTC->RAM_H);
-		RTC_SendCmd(RTC_SleepMode, 1);
-		RTC_PowerDown(0);
-	}
-	printf("normal running.\n");
-}
-#endif
+extern void rtc_sleep_demo(void);
+extern void rtc_wakeup_demo(void);
 #endif
 
 void SystemInit(void)
@@ -136,9 +84,6 @@ static void prvSetupHardware( void )
 #ifdef _RTC
 	RTC_SendCmd(RTC_Clk32KSel, 1);
 	//rtc_time_init();
-#if RTC_DEMO
-	rtc_wakeup_detect();
-#endif
 #endif
 #ifdef _SPI0
 	SPI0_SetBusClk(SPI0_FREQ);
@@ -195,6 +140,13 @@ static void prvSetupHardware( void )
 #ifdef _MCU_GPIO
 	GPIO_IrqRegister();
 #endif
+
+#ifdef 	_RTC
+	RTC_WakeupDetect();
+#if RTC_DEMO
+	rtc_wakeup_demo();
+#endif
+#endif
 }
 
 int LoadFastboot(void)
@@ -304,38 +256,10 @@ int main(void)
 #endif
 
 #if RTC_DEMO
-	TIMER_Mdelay(5000);//延时5s后进入休眠
-#if RTC_DEMO == RTC_ACCWAKEUP_DEMO
-	u8 value = 0;
-#ifndef FASTBOOT_DEMO
-	printf("addr:0x%x,data:0x%x\n", &data, data);
-	data = 0x11223344;
-#endif
-	RTC_SetWakeup(RTC_WAKEUP_GPIO0, RTC_WAKEUP_RISING, 0);
-	RTC_SetWakeup(RTC_WAKEUP_GPIO1, RTC_WAKEUP_RISING, 0);
-	RTC_SetWakeup(RTC_WAKEUP_CAN1, RTC_WAKEUP_RISING, 0);
-	RTC_SetWakeup(RTC_WAKEUP_CAN0, RTC_WAKEUP_RISING, 0);
-	RTC_SetWakeup(RTC_WAKEUP_RTC, RTC_WAKEUP_RISING, 0);
-	RTC_SetWakeup(RTC_WAKEUP_ACC, RTC_WAKEUP_RISING, 1);
-	if (!(RTC->RTCSTA & RTC_STA_SLEEPMODE)) {
-#ifdef FASTBOOT_DEMO
-		value = 1;
-#endif
-		if (value) {
-			LoadFastboot();
-			printf("load fast boot ok, ");
-		}
-		printf("entry sleep.\n");
-		RTC_SendCmd(RTC_SleepMode, 1);
-		RTC_PowerDown(value);
-	}
-	printf("normal running.\n");
-#elif RTC_DEMO == RTC_RTCWAKEUP_DEMO
-	entry_rtc_sleep(10);
-#endif
+	rtc_sleep_demo();
 #endif
 
-	for(;;) {
+	for (;;) {
 #if CAN_DEMO
 #if CAN_DEMO == CAN_ECU_DEMO
 		can_ecu_demo();