|
|
@@ -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.
|
|
|
*/
|