Sfoglia il codice sorgente

update:app初始化函数改成插件风格加载
update:新DAC播放的API
add:RTC定时唤醒功能
add:低功耗休眠,可以由RTC,键盘和IO低电平中断唤醒
update:每个IO单独中断回调
update:ADC开启时关闭上拉
update:task的event和delay从queue改成freertos专用的notify,据说能提高响应速度
add:串口sleep,强制休眠和唤醒, luat_lvgl_tick_sleep来开关lvgl的timer,为后续支持lptimer的应用做准备

alienwalker 4 anni fa
parent
commit
56629f0c10

+ 6 - 1
application/include/luat_conf_bsp.h

@@ -70,9 +70,14 @@
 //----------------------------
 // 高级功能, 其中shell是推荐启用, 除非你打算uart0也读数据
 #define LUAT_USE_SHELL 
-#define LUAT_USE_OTA
 #define LUAT_USE_DBG
 
+#define LUAT_USE_OTA
+
+// 多虚拟机支持,实验性,一般不启用 
+// #define LUAT_USE_VMX 1 
+// #define LUAT_USE_NES
+
 //---------------------
 // UI
 #define LUAT_USE_LCD

+ 29 - 0
application/src/luat_adc_air105.c

@@ -73,6 +73,35 @@ int luat_adc_read(int ch, int *val, int *val2)
 }
 
 int luat_adc_close(int ch){
+    switch (ch)
+    {
+    case 1:
+        GPIO_PullConfig(GPIOC_00, 1, 1);
+        GPIO_Iomux(GPIOC_00, 1);
+
+        break;
+    case 2:
+        GPIO_PullConfig(GPIOC_01, 1, 1);
+        GPIO_Iomux(GPIOC_01, 1);
+
+        break;
+    case 4:
+        GPIO_PullConfig(GPIOC_03, 1, 1);
+        GPIO_Iomux(GPIOC_03, 1);
+
+        break;
+    case 5:
+        GPIO_PullConfig(GPIOC_04, 1, 1);
+        GPIO_Iomux(GPIOC_04, 1);
+
+        break;
+    case 6:
+        GPIO_PullConfig(GPIOC_05, 1, 1);
+        GPIO_Iomux(GPIOC_05, 1);
+        break;
+    default:
+        return -1;
+    }
     if (ch)
         ADC_ChannelOnOff(ch, 0);
     return 0;

+ 17 - 0
application/src/luat_base_air105.c

@@ -190,6 +190,12 @@ static const luaL_Reg loadedlibs[] = {
 #endif
 #ifdef LUAT_USE_ZLIB
   {"zlib", luaopen_zlib},
+#endif
+#ifdef LUAT_USE_VMX   
+  {"vmx",       luaopen_vmx}, 
+#endif 
+#ifdef LUAT_USE_NES   
+  {"nes", luaopen_nes}, 
 #endif
   {"usbapp", luaopen_usbapp},
   {NULL, NULL}
@@ -246,6 +252,17 @@ static int32_t _lvgl_handler(void *pData, void *pParam) {
     msg.handler = luat_lvg_handler;
     luat_msgbus_put(&msg, 0);
 }
+void luat_lvgl_tick_sleep(uint8_t OnOff)
+{
+	if (OnOff)
+	{
+		Timer_StartMS(lv_timer, LVGL_TICK_PERIOD, 1);
+	}
+	else
+	{
+		Timer_Stop(lv_timer);
+	}
+}
 #endif
 
 void luat_shell_poweron(int _drv);

+ 2 - 1
application/src/luat_dac_air105.c

@@ -51,7 +51,8 @@ int luat_dac_write(uint32_t ch, uint16_t* buff, size_t len) {
 }
 
 int luat_dac_close(uint32_t ch) {
-	DAC_ForceStop(ch);
+	DAC_Stop(ch);
+	GPIO_Iomux(GPIOC_01, 1);
     return 0; // 暂不支持关闭
 }
 

+ 26 - 23
application/src/luat_gpio_air105.c

@@ -28,24 +28,24 @@
 #include "platform_define.h"
 #include "luat_irq.h"
 
-typedef struct wm_gpio_conf
-{
-    luat_gpio_irq_cb cb;
-    void* args;
-}wm_gpio_conf_t;
+//typedef struct wm_gpio_conf
+//{
+//    luat_gpio_irq_cb cb;
+//    void* args;
+//}wm_gpio_conf_t;
+//
+//
+//static wm_gpio_conf_t confs[HAL_GPIO_MAX];
 
-
-static wm_gpio_conf_t confs[HAL_GPIO_MAX];
-
-static void luat_gpio_irq_callback(void *ptr, void *pParam)
-{
-    int pin = (int)ptr;
-    luat_gpio_irq_cb cb = confs[pin].cb;
-    if (cb == NULL)
-        luat_irq_gpio_cb(pin, confs[pin].args);
-    else
-        cb(pin, confs[pin].args);
-}
+//static void luat_gpio_irq_callback(void *ptr, void *pParam)
+//{
+//    int pin = (int)ptr;
+//    luat_gpio_irq_cb cb = confs[pin].cb;
+//    if (cb == NULL)
+//        luat_irq_gpio_cb(pin, confs[pin].args);
+//    else
+//        cb(pin, confs[pin].args);
+//}
 
 int luat_gpio_setup(luat_gpio_t *gpio){
     if (gpio->pin < HAL_GPIO_2 || gpio->pin > HAL_GPIO_MAX) return 0;
@@ -71,8 +71,11 @@ int luat_gpio_setup(luat_gpio_t *gpio){
                     break;
             }
             if (gpio->irq_cb) {
-                confs[gpio->pin].cb = gpio->irq_cb;
-                confs[gpio->pin].args = gpio->irq_args;
+            	GPIO_ExtiSetCB(gpio->pin, gpio->irq_cb, gpio->irq_args);
+            }
+            else
+            {
+            	GPIO_ExtiSetCB(gpio->pin, luat_irq_gpio_cb, gpio->irq_args);
             }
 
         }break;
@@ -108,19 +111,19 @@ int luat_gpio_get(int pin){
 
 void luat_gpio_close(int pin){
     if (pin < HAL_GPIO_2 || pin >= HAL_GPIO_MAX) return ;
-    confs[pin].cb = NULL;
+    GPIO_ExtiSetCB(pin, NULL, 0);
+    GPIO_ExtiConfig(pin, 0,0,0);
     return ;
 }
 
 void luat_gpio_init(void){
-    GPIO_GlobalInit(luat_gpio_irq_callback);
+//    GPIO_GlobalInit(luat_gpio_irq_callback);
 }
 
 int luat_gpio_set_irq_cb(int pin, luat_gpio_irq_cb cb, void* args) {
     if (pin < HAL_GPIO_2 || pin >= HAL_GPIO_MAX) return -1;
     if (cb) {
-        confs[pin].cb = cb;
-        confs[pin].args = args;
+    	GPIO_ExtiSetCB(pin, cb, args);
     }
     return 0;
 }

+ 54 - 0
application/src/luat_rtos_air105.c

@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2022 OpenLuat & AirM2M
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#include "luat_base.h"
+#include "luat_rtos.h"
+#include "app_interface.h"
+#include "FreeRTOS.h"
+#include "semphr.h"
+#include "task.h"
+
+#define LUAT_LOG_TAG "luat.rtos"
+#include "luat_log.h"
+
+int luat_thread_start(luat_thread_t* thread){
+    Task_Create(thread->thread, NULL, thread->stack_size, thread->priority, thread->name);
+    return 0;
+}
+
+int luat_sem_create(luat_sem_t* semaphore){
+    semaphore->userdata = xSemaphoreCreateBinary();
+    return 0;
+}
+int luat_sem_delete(luat_sem_t* semaphore){
+    vSemaphoreDelete(semaphore->userdata);
+    return 0;
+}
+
+int luat_sem_take(luat_sem_t* semaphore,uint32_t timeout){
+    return xSemaphoreTake(semaphore->userdata, timeout);
+}
+
+int luat_sem_release(luat_sem_t* semaphore){
+    OS_MutexRelease(semaphore->userdata);
+    return 0;
+}

+ 0 - 159
bsp/air105/chip/include/air105_ssc.h

@@ -1,159 +0,0 @@
-/*
- * Copyright (c) 2022 OpenLuat & AirM2M
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
- * the Software, and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
- * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-
-
-#ifndef __AIR105_SSC_H
-#define __AIR105_SSC_H
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-/* Includes ------------------------------------------------------------------*/
-#include "air105.h"
-
-
-#define	SSC_ITSysXTAL12M					BIT(18)	//ϵͳ��12Mʱ�ӱ�־
-#define	SSC_ITSysGlitch						BIT(17)	//����Դë�̱�־
-#define	SSC_ITSysVolHigh					BIT(16)	//����Դ��ѹ��־
-#define	SSC_ITSysVolLow						BIT(15)	//����ԴǷѹ��־
-
-typedef struct
-{
-	FunctionalState ParityCheck;								//��żУ��ʹ��
-}SSC_InitTypeDef;
-
-
-/*
- *	��BPK��Ϊ4��ÿ��256����Ϊ��λ���ö�дȨ��
- *	SSC_BPKAccessCtrBlock_0Ϊ��ʼ0��ַ��
- */
-#define SSC_BPKAccessCtrBlock_0				(0x01)
-#define SSC_BPKAccessCtrBlock_1				(0x02)
-#define SSC_BPKAccessCtrBlock_All			(0x03)
-
-typedef enum
-{
-	SSC_BPKReadOnly		= 0x01,		//BPK��ֻ��
-	SSC_BPKWriteOnly	= 0x02,		//BPK��ֻд
-	SSC_BPKReadWrite	= 0x03		//BPK���д
-}SSC_BPKAccessCtrlTypeDef;
-#define IS_BPK_ACCESS_CTRL(CTRL) (((CTRL) == SSC_BPKReadOnly) || ((CTRL) == SSC_BPKWriteOnly) || \
-								((CTRL) == SSC_BPKReadWrite))
-
-#define SSC_SENSOR_XTAL12M							((uint32_t)0x00000001)
-#define SSC_SENSOR_VOL_LOW							((uint32_t)0x00000002)
-#define SSC_SENSOR_VOL_HIGH							((uint32_t)0x00000004)
-#define SSC_SENSOR_VOLGLITCH						((uint32_t)0x00000008)
-#define IS_SSC_SENSOR(SENSOR)						((((SENSOR) & (uint32_t)0xFFFFFFF0) == 0x00) && ((SENSOR) != (uint32_t)0x00))
-
-typedef enum
-{
-	SSC_SENSOR_CPUReset  = 0,
-	SSC_SENSOR_Interrupt = 1
-}SSC_SENSOR_RespModeTypeDef;
-#define IS_SSC_SENSOR_RESP_MODE(Mode)				((Mode) == SSC_SENSOR_CPUReset ||\
-													(Mode) == SSC_SENSOR_Interrupt)
-
-/**
-  * @method	SSC_Init
-  * @brief	SSC��ȫ���Գ�ʼ��
-  * @param	SSC_InitTypeDef SSC_InitStruct
-  * @retval void
-  */
-void SSC_Init(SSC_InitTypeDef *SSC_InitStruct);
-
-
-/**
-  * @method	SSC_GetITStatus
-  * @brief	SSC��ȫ�ж�״̬
-  * @param	uint32_t SSC_IT
-  * @retval ITStatus
-  */
-ITStatus SSC_GetITStatus(uint32_t SSC_IT);
-
-
-/**
-  * @method	SSC_ClearITPendingBit
-  * @brief	SSC��ȫ�ж����
-  * @param	uint32_t SSC_IT
-  * @retval void
-  */
-void SSC_ClearITPendingBit( uint32_t SSC_IT);
-
-
-/**
-  * @method	SSC_SetDataRAMScrambler
-  * @brief	��������RAM����
-  * @param	uint32_t Scrambler
-  * @retval void
-  */
-void SSC_SetDataRAMScrambler(uint32_t Scrambler);
-
-
-/**
-  * @method	SSC_BPKAccessCtrConfig
-  * @brief	����BPK����Ȩ��
-  * @param	uint32_t SSC_BPKAccessCtrBlock
-  * @param	SSC_BPKAccessCtrlTypeDef SSC_BPKAccessCtr
-  * @retval void
-  */
-void SSC_BPKAccessCtrlConfig(uint32_t SSC_BPKAccessCtrBlock, SSC_BPKAccessCtrlTypeDef SSC_BPKAccessCtr);
-
-
-/**
-  * @method	SSC_SENSOR_Enable
-  * @brief	����ϵͳSensor
-  * @param	SSC_SENSOR
-  * @retval 
-  */
-uint32_t SSC_SENSORCmd(uint32_t SSC_SENSOR, FunctionalState NewState);
-
-
-/**
-  * @method	SSC_SENSORLock
-  * @brief	����ϵͳSensor����״̬
-  * @param	SSC_SENSOR
-  * @retval 
-  */
-void SSC_SENSORLock(uint32_t SSC_SENSOR);
-
-
-/**
-  * @method	SSC_SENSOR_AttackRespMode
-  * @brief	ϵͳSensor��Ӧ��ʽ
-  * @param	SSC_SENSOR_RespMode
-  * @retval 
-  */
-void SSC_SENSORAttackRespMode(SSC_SENSOR_RespModeTypeDef SSC_SENSOR_RespMode);
-
-
-void SSC_SENSORKeyClearCmd(uint32_t SSC_SENSOR, FunctionalState KeyClearEn);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif 
-
-/**************************      (C) COPYRIGHT Megahunt    *****END OF FILE****/

+ 4 - 0
bsp/air105/hal/core_dac.c

@@ -88,6 +88,8 @@ void DAC_Setup(uint8_t DAC_ID, uint32_t Freq, uint32_t OutRMode)
 void DAC_Send(uint8_t DAC_ID, const uint16_t *Data, uint32_t Len, CBFuncEx_t Callback, void *pParam)
 {
 	uint32_t TxLevel;
+	PM_SetHardwareRunFlag(PM_HW_DAC_0 + DAC_ID, 1);
+//	PM_SetHardwareRunFlag(PM_HW_DAC_0, 1);
 	if (prvDAC.IsBusy)
 	{
 		DMA_PrintReg(prvDAC.DMATxStream);
@@ -133,4 +135,6 @@ void DAC_ForceStop(uint8_t DAC_ID)
 	DMA_StopStream(prvDAC.DMATxStream);
 	DAC->DAC_CR1 |= (1 << 4);
 	DAC->DAC_CR1 &= ~0x04;
+	PM_SetHardwareRunFlag(PM_HW_DAC_0 + DAC_ID, 0);
+//	PM_SetHardwareRunFlag(PM_HW_DAC_0, 0);
 }

+ 2 - 0
bsp/air105/hal/core_dcmi.c

@@ -138,6 +138,7 @@ void DCMI_CaptureSwitch(uint8_t OnOff, uint32_t BufLen, uint32_t ImageW, uint32_
 	uint32_t WDataLen, HLen;
 	if (OnOff)
 	{
+		PM_SetHardwareRunFlag(PM_HW_DCMI_0, 1);
 		if (DCMI->CR & DCMI_CR_CAPTURE) return;
 		if (!BufLen)
 		{
@@ -193,6 +194,7 @@ void DCMI_CaptureSwitch(uint8_t OnOff, uint32_t BufLen, uint32_t ImageW, uint32_
 				prvDCMI.uBuf[i].pu32 = 0;
 			}
 		}
+		PM_SetHardwareRunFlag(PM_HW_DCMI_0, 0);
 	}
 }
 

+ 1 - 0
bsp/air105/hal/core_debug.c

@@ -731,6 +731,7 @@ void DBG_Init(uint8_t AppMode)
 	}
 	prvDBGCtrl.InitDone = 1;
 	prvDBGCtrl.Fun = DBG_DummyRx;
+	PM_SetDriverRunFlag(PM_DRV_DBG, 1);
 }
 
 void DBG_SetRxCB(CBFuncEx_t cb)

+ 55 - 12
bsp/air105/hal/core_gpio.c

@@ -30,9 +30,13 @@ typedef struct
 
 typedef struct
 {
-	CBFuncEx_t AllCB;
-	CBFuncEx_t HWTimerCB;
+	CBFuncEx_t CB;
 	void *pParam;
+}EXTI_CBStruct;
+
+typedef struct
+{
+	EXTI_CBStruct ExtiCB[GPIO_MAX];
 }GPIO_CtrlStruct;
 
 static GPIO_CtrlStruct prvGPIO;
@@ -79,19 +83,21 @@ static int32_t GPIO_IrqDummyCB(void *pData, void *pParam)
 static void __FUNC_IN_RAM__ GPIO_IrqHandle(int32_t IrqLine, void *pData)
 {
 	volatile uint32_t Port = (uint32_t)pData;
-	volatile uint32_t Sn, i;
+	volatile uint32_t Sn, i, Pin;
+	CBFuncEx_t CB;
 	if (GPIO->INTP_TYPE_STA[Port].INTP_STA)
 	{
 		Sn = GPIO->INTP_TYPE_STA[Port].INTP_STA;
 		GPIO->INTP_TYPE_STA[Port].INTP_STA = 0xffff;
-		prvGPIO.HWTimerCB((Port << 16) | Sn, prvGPIO.pParam);
 		Port = (Port << 4);
 
 		for(i = 0; i < 16; i++)
 		{
 			if (Sn & (1 << i))
 			{
-				prvGPIO.AllCB((void *)(Port+i), 0);
+				Pin = Port+i;
+				//DBG("%d,%x,%x", Pin, prvGPIO.ExtiCB[Pin].CB, prvGPIO.ExtiCB[Pin].pParam);
+				prvGPIO.ExtiCB[Pin].CB((void *)Pin, prvGPIO.ExtiCB[Pin].pParam);
 			}
 		}
 	}
@@ -103,13 +109,18 @@ void GPIO_GlobalInit(CBFuncEx_t Fun)
 	uint32_t i;
 	if (Fun)
 	{
-		prvGPIO.AllCB = Fun;
+		for(i = 0; i < GPIO_MAX; i++)
+		{
+			prvGPIO.ExtiCB[i].CB = Fun;
+		}
 	}
 	else
 	{
-		prvGPIO.AllCB = GPIO_IrqDummyCB;
+		for(i = 0; i < GPIO_MAX; i++)
+		{
+			prvGPIO.ExtiCB[i].CB = GPIO_IrqDummyCB;
+		}
 	}
-	prvGPIO.HWTimerCB = GPIO_IrqDummyCB;
 	for(i = 0; i < 6; i++)
 	{
 		GPIO->INTP_TYPE_STA[i].INTP_TYPE = 0;
@@ -196,19 +207,51 @@ void GPIO_ExtiConfig(uint32_t Pin, uint8_t IsLevel, uint8_t IsRiseHigh, uint8_t
 		}
 	}
 	GPIO->INTP_TYPE_STA[Port].INTP_TYPE = (GPIO->INTP_TYPE_STA[Port].INTP_TYPE & Mask) | Type;
+	uint32_t Sn = Pin / 32;
+	uint32_t Pos = 1 << (Pin % 32);
+	if (!IsLevel)
+	{
+		switch(Sn)
+		{
+		case 0:
+			GPIO->WAKE_P0_EN |= Pos;
+			break;
+		case 1:
+			GPIO->WAKE_P1_EN |= Pos;
+			break;
+		case 2:
+			GPIO->WAKE_P2_EN |= Pos;
+			break;
+		}
+	}
+	else
+	{
+		switch(Sn)
+		{
+		case 0:
+			GPIO->WAKE_P0_EN &= ~Pos;
+			break;
+		case 1:
+			GPIO->WAKE_P1_EN &= ~Pos;
+			break;
+		case 2:
+			GPIO->WAKE_P2_EN &= ~Pos;
+			break;
+		}
+	}
 }
 
-void GPIO_ExtiSetHWTimerCB(CBFuncEx_t CB, void *pParam)
+void GPIO_ExtiSetCB(uint32_t Pin, CBFuncEx_t CB, void *pParam)
 {
 	if (CB)
 	{
-		prvGPIO.HWTimerCB = CB;
+		prvGPIO.ExtiCB[Pin].CB = CB;
 	}
 	else
 	{
-		prvGPIO.HWTimerCB = GPIO_IrqDummyCB;
+		prvGPIO.ExtiCB[Pin].CB = GPIO_IrqDummyCB;
 	}
-	prvGPIO.pParam = pParam;
+	prvGPIO.ExtiCB[Pin].pParam = pParam;
 }
 
 void __FUNC_IN_RAM__ GPIO_Iomux(uint32_t Pin, uint32_t Function)

+ 7 - 5
bsp/air105/hal/core_hwtimer.c

@@ -109,7 +109,7 @@ static int32_t __FUNC_IN_RAM__ prvHWTimer_OperationQueuExti(void *pData, void *p
 	uint32_t HWTimerID = (uint32_t)pParam;
 	uint32_t pin = (uint32_t)pData;
 //	DBG("%x,%x", pin, prvHWTimer[HWTimerID].CapturePin);
-	if ((pin & prvHWTimer[HWTimerID].CapturePin) == prvHWTimer[HWTimerID].CapturePin)
+	if (pin == prvHWTimer[HWTimerID].CapturePin)
 	{
 		prvHWTimer_StartOperationQueue(HWTimerID, &prvHWTimer[HWTimerID]);
 	}
@@ -186,12 +186,11 @@ static void __FUNC_IN_RAM__ prvHWTimer_StartOperationQueue(uint8_t HWTimerID, HW
 		case OP_QUEUE_CMD_CAPTURE_SET:
 			GPIO_PullConfig(HWTimer->Cmd[HWTimer->CurCount].Arg1, HWTimer->Cmd[HWTimer->CurCount].uArg.ExitArg.PullMode, (HWTimer->Cmd[HWTimer->CurCount].uArg.ExitArg.PullMode > 1)?0:1);
 			GPIO_Config(HWTimer->Cmd[HWTimer->CurCount].Arg1, 1, 0);
-			HWTimer->CapturePin = HWTimer->Cmd[HWTimer->CurCount].Arg1 & 0xf0;
-			HWTimer->CapturePin = (HWTimer->CapturePin << 12) | (1 << (HWTimer->Cmd[HWTimer->CurCount].Arg1 & 0x0000000f));
+			HWTimer->CapturePin = HWTimer->Cmd[HWTimer->CurCount].Arg1;
 			TIMM0->TIM[HWTimerID].ControlReg = 0;
 			TIMM0->TIM[HWTimerID].LoadCount = HWTimer->Cmd[HWTimer->CurCount].uParam.MaxCnt;
 			TIMM0->TIM[HWTimerID].ControlReg = TIMER_CONTROL_REG_TIMER_ENABLE|TIMER_CONTROL_REG_TIMER_MODE;
-			GPIO_ExtiSetHWTimerCB(prvHWTimer_OperationQueuExti, HWTimerID);
+			GPIO_ExtiSetCB(HWTimer->Cmd[HWTimer->CurCount].Arg1, prvHWTimer_OperationQueuExti, HWTimerID);
 			prvHWTimer[HWTimerID].ContinueDelay = 0;
 			switch(HWTimer->Cmd[HWTimer->CurCount].uArg.ExitArg.ExtiMode)
 			{
@@ -210,8 +209,8 @@ static void __FUNC_IN_RAM__ prvHWTimer_StartOperationQueue(uint8_t HWTimerID, HW
 			return;
 			break;
 		case OP_QUEUE_CMD_CAPTURE_END:
+			GPIO_ExtiSetCB(HWTimer->Cmd[HWTimer->CurCount].Arg1, NULL, NULL);
 			TIMM0->TIM[HWTimerID].ControlReg = 0;
-			GPIO_ExtiSetHWTimerCB(NULL, NULL);
 			HWTimer->CurCount++;
 			break;
 		case OP_QUEUE_CMD_END:
@@ -274,6 +273,7 @@ void HWTimer_StartPWM(uint8_t HWTimerID, uint32_t HighCnt, uint32_t LowCnt, uint
 	{
 		TIMM0->TIM[HWTimerID].ControlReg = TIMER_CONTROL_REG_TIMER_PWM|TIMER_CONTROL_REG_TIMER_MODE|TIMER_CONTROL_REG_TIMER_ENABLE|TIMER_CONTROL_REG_TIMER_INTERRUPT;
 	}
+	PM_SetHardwareRunFlag(PM_HW_TIMER_0 + HWTimerID, 1);
 }
 
 void HWTimer_SetPWM(uint8_t HWTimerID, uint32_t Period, uint16_t Duty, uint8_t IsOnePulse)
@@ -333,6 +333,7 @@ void HWTimer_Stop(uint8_t HWTimerID)
 	ISR_Clear(prvHWTimer[HWTimerID].IrqLine);
 	prvHWTimer[HWTimerID].IsQueueRunning = 0;
 	prvHWTimer[HWTimerID].ContinueDelay = 0;
+	PM_SetHardwareRunFlag(PM_HW_TIMER_0 + HWTimerID, 0);
 }
 
 void HWTimer_InitOperationQueue(uint8_t HWTimerID, uint32_t nCount, uint32_t Repeat, uint32_t InputByte, CBFuncEx_t CmdDoneCB, void *pCmdDoneParam)
@@ -411,6 +412,7 @@ void HWTimer_StartOperationQueue(uint8_t HWTimerID)
 	prvHWTimer[HWTimerID].IsQueueRunning = 1;
 	prvHWTimer_StartOperationQueue(HWTimerID, &prvHWTimer[HWTimerID]);
 	ISR_OnOff(prvHWTimer[HWTimerID].IrqLine, 1);
+	PM_SetHardwareRunFlag(PM_HW_TIMER_0 + HWTimerID, 1);
 }
 
 void HWTimer_ClearOperationQueue(uint8_t HWTimerID)

+ 7 - 4
bsp/air105/hal/core_i2c.c

@@ -64,8 +64,9 @@ static I2C_CtrlStruct prvI2C = {
 		I2C0_IRQn,
 };
 
-static void prvI2C_Done(int32_t Result)
+static void prvI2C_Done(uint8_t I2CID, int32_t Result)
 {
+	PM_SetHardwareRunFlag(PM_HW_I2C_0 + I2CID, 0);
 	prvI2C.State = I2C_STATE_FREE;
 	prvI2C.Result = Result;
 	prvI2C.IsBusy = 0;
@@ -73,6 +74,7 @@ static void prvI2C_Done(int32_t Result)
 	if (prvI2C.IsBlockMode) OS_MutexRelease(prvI2C.Sem);
 #endif
 	prvI2C.Callback(I2C_ID0, prvI2C.pParam);
+
 }
 
 static int32_t prvI2C_DummyCB(void *pData, void *pParam)
@@ -86,7 +88,7 @@ static int32_t prvI2C_TimerUpCB(void *pData, void *pParam)
 	IIC_DBG("%d,%x",prvI2C.State, I2C->IC_RAW_INTR_STAT);
 	I2C->IC_ENABLE |= I2C_IC_ENABLE_ABORT;
 	I2C->IC_INTR_MASK = 0;
-	prvI2C_Done(-ERROR_TIMEOUT);
+	prvI2C_Done(0, -ERROR_TIMEOUT);
 	while(I2C->IC_ENABLE & I2C_IC_ENABLE_ABORT){;}
 	return 0;
 }
@@ -166,7 +168,7 @@ static void I2C_IrqHandle(int32_t IrqLine, void *pData)
 I2C_DONE:
 	Timer_Stop(prvI2C.ToTimer);
 	I2C->IC_INTR_MASK = 0;
-	prvI2C_Done(ERROR_NONE);
+	prvI2C_Done(0, ERROR_NONE);
 }
 
 static void I2C_IrqHandleRegQueue(int32_t IrqLine, void *pData)
@@ -207,7 +209,7 @@ static void I2C_IrqHandleRegQueue(int32_t IrqLine, void *pData)
 I2C_DONE:
 	Timer_Stop(prvI2C.ToTimer);
 	I2C->IC_INTR_MASK = 0;
-	prvI2C_Done(ERROR_NONE);
+	prvI2C_Done(0, ERROR_NONE);
 }
 
 void I2C_GlobalInit(void)
@@ -284,6 +286,7 @@ void I2C_MasterXfer(uint8_t I2CID, uint8_t Operate, uint8_t RegAddress, uint8_t
 {
 	I2C_TypeDef *I2C = prvI2C.RegBase;
 	uint32_t RegValue;
+	PM_SetHardwareRunFlag(PM_HW_I2C_0 + I2CID, 1);
 	I2C->IC_INTR_MASK = 0;
 	ISR_OnOff(prvI2C.IrqLine, 0);
 	if (prvI2C.IsBusy)

+ 68 - 0
bsp/air105/hal/core_pm.c

@@ -0,0 +1,68 @@
+#include "user.h"
+
+typedef struct
+{
+	uint32_t HWFlagBit;
+	uint32_t DrvFlagBit;
+}PM_CtrlStruct;
+static PM_CtrlStruct prvPM;
+
+void PM_Init(void)
+{
+	GPIO->WAKE_TYPE_EN = (1 << 12) | (1 << 11);
+//	GPIO->WAKE_P0_EN = 0xffffffff;
+//	GPIO->WAKE_P1_EN = 0xffffffff;
+//	GPIO->WAKE_P2_EN = 0xffffffff;
+	GPIO->WAKE_P0_EN = 0;
+	GPIO->WAKE_P1_EN = 0;
+	GPIO->WAKE_P2_EN = 0;
+}
+
+void PM_SetHardwareRunFlag(uint32_t PmHWSn, uint32_t OnOff)
+{
+	if (OnOff)
+	{
+		prvPM.HWFlagBit |= (1 << PmHWSn);
+	}
+	else
+	{
+		prvPM.HWFlagBit &= ~(1 << PmHWSn);
+	}
+}
+
+void PM_SetDriverRunFlag(uint32_t PmDrvSn, uint32_t OnOff)
+{
+	if (OnOff)
+	{
+		prvPM.DrvFlagBit |= (1 << PmDrvSn);
+	}
+	else
+	{
+		prvPM.DrvFlagBit &= ~(1 << PmDrvSn);
+	}
+}
+
+void PM_Print(void)
+{
+	DBG("%x,%x", prvPM.HWFlagBit, prvPM.DrvFlagBit);
+}
+
+int32_t PM_Sleep(void)
+{
+	uint64_t StartTick;
+	uint32_t Temp;
+	if (prvPM.HWFlagBit || prvPM.DrvFlagBit) return -ERROR_DEVICE_BUSY;
+	__disable_irq();
+	StartTick = RTC_GetUTC();
+	SYSCTRL->FREQ_SEL = (SYSCTRL->FREQ_SEL & ~(SYSCTRL_FREQ_SEL_POWERMODE_Mask)) | SYSCTRL_FREQ_SEL_POWERMODE_CLOSE_CPU_MEM;
+	Temp = TRNG->RNG_ANA;
+	TRNG->RNG_ANA = Temp | TRNG_RNG_AMA_PD_ALL_Mask;
+	__WFI();
+	TRNG->RNG_ANA = Temp;
+	WDT_Feed();
+	SysTickAddSleepTime((RTC_GetUTC() - StartTick) * CORE_TICK_1S);
+	Timer_WakeupRun();
+	__enable_irq();
+	return ERROR_NONE;
+
+}

+ 44 - 1
bsp/air105/hal/core_rtc.c

@@ -21,6 +21,22 @@
 
 #include "user.h"
 
+static int32_t RTC_DummyCB(void *pData, void *pParam)
+{
+	DBG("!");
+	return 0;
+}
+
+static CBFuncEx_t prvRTCCB;
+static void *prvParam;
+
+static void RTC_IrqHandler(int32_t Line, void *pData)
+{
+	RTC->RTC_INTCLR = 1;
+	ISR_OnOff(RTC_IRQn, 0);
+	prvRTCCB(pData, prvParam);
+}
+
 void RTC_GlobalInit(void)
 {
 	int8_t Buf[4][6];
@@ -30,6 +46,7 @@ void RTC_GlobalInit(void)
 	CmdParam CP;
 	Date_UserDataStruct BuildDate;
 	Time_UserDataStruct BuildTime;
+	prvRTCCB = RTC_DummyCB;
 	if (!RTC->RTC_REF)
 	{
 		memset(&CP, 0, sizeof(CP));
@@ -75,7 +92,12 @@ void RTC_GlobalInit(void)
 		BuildTime.Sec = Sec;
 		RTC_SetDateTime(&BuildDate, &BuildTime, 0);
 	}
-
+#ifdef __BUILD_OS__
+	ISR_SetPriority(RTC_IRQn, IRQ_MAX_PRIORITY + 1);
+#else
+	ISR_SetPriority(RTC_IRQn, 3);
+#endif
+	ISR_SetHandler(RTC_IRQn, RTC_IrqHandler, NULL);
 //	RTC_GetDateTime(&uBuildDate, &uBuildTime);
 //	DBG("%04u-%02u-%02u %02u:%02u:%02u", uBuildDate.Date.Year, uBuildDate.Date.Mon,
 //			uBuildDate.Date.Day, uBuildTime.Time.Hour, uBuildTime.Time.Min,
@@ -126,6 +148,27 @@ uint64_t RTC_GetUTC(void)
 	return curTime;
 }
 
+void RTC_SetAlarm(uint32_t TimeSecond, CBFuncEx_t CB, void *pParam)
+{
+	while (!(RTC->RTC_CS & RTC_CS_READY)) {;}
+	RTC->RTC_INTCLR = 1;
+	RTC->RTC_CS &= ~RTC_CS_ALARM_EN;
+	RTC->RTC_CS |= RTC_CS_LOCK_TIM;
+	RTC->RTC_ARM = RTC->RTC_TIM + TimeSecond;
+	RTC->RTC_CS &= ~RTC_CS_LOCK_TIM;
+	if (CB)
+	{
+		prvRTCCB = CB;
+	}
+	else
+	{
+		prvRTCCB = RTC_DummyCB;
+	}
+	prvParam = pParam;
+	RTC->RTC_CS |= RTC_CS_ALARM_EN;
+	ISR_OnOff(RTC_IRQn, 1);
+}
+
 #ifdef __BUILD_APP__
 INIT_HW_EXPORT(RTC_GlobalInit, "1");
 #endif

+ 15 - 2
bsp/air105/hal/core_spi.c

@@ -176,6 +176,7 @@ static void HSPI_IrqHandle(int32_t IrqLine, void *pData)
 			OS_MutexRelease(prvSPI[SpiID].Sem);
 		}
 #endif
+		PM_SetHardwareRunFlag(PM_HW_HSPI, 0);
 		prvSPI[SpiID].Callback((void *)SpiID, prvSPI[SpiID].pParam);
 		return;
 	}
@@ -249,6 +250,14 @@ static int32_t SPI_DMADoneCB(void *pData, void *pParam)
 			OS_MutexRelease(prvSPI[SpiID].Sem);
 		}
 #endif
+		if (SpiID)
+		{
+			PM_SetHardwareRunFlag(PM_HW_HSPI, 0);
+		}
+		else
+		{
+			PM_SetHardwareRunFlag(PM_HW_SPI_0 + SpiID - 1, 0);
+		}
 		prvSPI[SpiID].Callback((void *)SpiID, prvSPI[SpiID].pParam);
 	}
 
@@ -309,6 +318,7 @@ static void SPI_IrqHandle(int32_t IrqLine, void *pData)
 			OS_MutexRelease(prvSPI[SpiID].Sem);
 		}
 #endif
+		PM_SetHardwareRunFlag(PM_HW_SPI_0 + SpiID - 1, 0);
 		prvSPI[SpiID].Callback((void *)SpiID, prvSPI[SpiID].pParam);
 		return;
 	}
@@ -507,6 +517,7 @@ static int32_t HSPI_Transfer(uint8_t SpiID, uint8_t UseDMA)
 {
 	HSPIM_TypeDef *SPI = (HSPIM_TypeDef *)prvSPI[SpiID].RegBase;
 	uint32_t TxLen, i;
+	PM_SetHardwareRunFlag(PM_HW_HSPI, 1);
 	if (UseDMA)
 	{
 		SPI->CR0 &= ~(7 << HSPIM_CR0_PARAM_INTERRPUT_ENABLE_POS);
@@ -560,7 +571,7 @@ int32_t SPI_Transfer(uint8_t SpiID, const uint8_t *TxData, uint8_t *RxData, uint
 		return -ERROR_DEVICE_BUSY;
 	}
 	prvSPI[SpiID].IsBusy = 1;
-//
+
 	uint32_t RxLevel, i, TxLen;
 	Buffer_StaticInit(&prvSPI[SpiID].TxBuf, TxData, Len);
 	Buffer_StaticInit(&prvSPI[SpiID].RxBuf, RxData, Len);
@@ -581,6 +592,7 @@ int32_t SPI_Transfer(uint8_t SpiID, const uint8_t *TxData, uint8_t *RxData, uint
 	default:
 		return -ERROR_ID_INVALID;
 	}
+	PM_SetHardwareRunFlag(PM_HW_SPI_0 + SpiID - 1, 1);
 	SPI = (SPI_TypeDef *)prvSPI[SpiID].RegBase;
 	SPI->SER = 0;
 	if (UseDMA)
@@ -1061,6 +1073,7 @@ void SPI_TransferStop(uint8_t SpiID)
 		HSPI->CR0 &= ~(7 << HSPIM_CR0_PARAM_INTERRPUT_ENABLE_POS);
 		HSPI->FCR = (32 << HSPIM_FCR_PARAM_TRANSIMIT_FIFO_EMPTY_THRESHOULD_POS)|(32 << HSPIM_FCR_PARAM_RECEIVE_FIFO_FULL_THRESHOULD_POS)|(3 << 6)|(63);
 		HSPI->FCR &= ~(3 << 6);
+		PM_SetHardwareRunFlag(PM_HW_HSPI, 0);
 		break;
 	case SPI_ID0:
 		SYSCTRL->PHER_CTRL &= ~SYSCTRL_PHER_CTRL_SPI0_SLV_EN;
@@ -1077,7 +1090,7 @@ void SPI_TransferStop(uint8_t SpiID)
 	default:
 		return ;
 	}
-
+	PM_SetHardwareRunFlag(PM_HW_SPI_0 + SpiID - 1, 0);
 	prvSPI[SpiID].IsBusy = 0;
 
 }

+ 59 - 2
bsp/air105/hal/core_task.c

@@ -21,14 +21,21 @@
 
 #include "user.h"
 #ifdef __BUILD_OS__
+#define __USE_FREERTOS_NOTIFY__
 enum
 {
 	TASK_POINT_LIST_HEAD,
+#ifdef __USE_SEMAPHORE__
 	TASK_POINT_EVENT_SEM,
-	TASK_POINT_EVENT_TIMER,
 	TASK_POINT_DELAY_SEM,
+#endif
+	TASK_POINT_EVENT_TIMER,
 	TASK_POINT_DELAY_TIMER,
 	TASK_POINT_DEBUG,
+#ifdef __USE_FREERTOS_NOTIFY__
+	TASK_NOTIFY_EVENT = tskDEFAULT_INDEX_TO_NOTIFY,
+	TASK_NOTIFY_DELAY,
+#endif
 };
 
 typedef struct
@@ -54,8 +61,18 @@ static int32_t prvTaskTimerCallback(void *pData, void *pParam)
 
 static int32_t prvTaskDelayTimerCallback(void *pData, void *pParam)
 {
+#ifdef __USE_SEMAPHORE__
 	SemaphoreHandle_t sem = (SemaphoreHandle_t)vTaskGetPoint(pParam, TASK_POINT_DELAY_SEM);
 	OS_MutexRelease(sem);
+#endif
+#ifdef __USE_FREERTOS_NOTIFY__
+	BaseType_t xHigherPriorityTaskWoken = pdFALSE;
+	vTaskGenericNotifyGiveFromISR(pParam, TASK_NOTIFY_DELAY, &xHigherPriorityTaskWoken);
+	if (xHigherPriorityTaskWoken)
+	{
+		portYIELD_WITHIN_API();
+	}
+#endif
 	return 0;
 }
 
@@ -64,23 +81,29 @@ HANDLE Task_Create(TaskFun_t EntryFunction, void *Param, uint32_t StackSize, uin
 	TaskHandle_t Handle;
 	llist_head *Head;
 	Timer_t *Timer, *DelayTimer;
+#ifdef __USE_SEMAPHORE__
 	SemaphoreHandle_t Sem, DelaySem;
+#endif
 	if (pdPASS != xTaskCreate(EntryFunction, Name, StackSize>>2, Param, Priority, &Handle))
 	{
 		return NULL;
 	}
 	if (!Handle) return NULL;
 	Head = OS_Zalloc(sizeof(llist_head));
+#ifdef __USE_SEMAPHORE__
 	Sem = OS_MutexCreate();
 	DelaySem = OS_MutexCreate();
+#endif
 	Timer = Timer_Create(prvTaskTimerCallback, Handle, NULL);
 	DelayTimer = Timer_Create(prvTaskDelayTimerCallback, Handle, NULL);
 	INIT_LLIST_HEAD(Head);
 	vTaskSetPoint(Handle, TASK_POINT_LIST_HEAD, Head);
+#ifdef __USE_SEMAPHORE__
 	vTaskSetPoint(Handle, TASK_POINT_EVENT_SEM, Sem);
-	vTaskSetPoint(Handle, TASK_POINT_EVENT_TIMER, Timer);
 	vTaskSetPoint(Handle, TASK_POINT_DELAY_SEM, DelaySem);
+#endif
 	vTaskSetPoint(Handle, TASK_POINT_DELAY_TIMER, DelayTimer);
+	vTaskSetPoint(Handle, TASK_POINT_EVENT_TIMER, Timer);
 	vTaskSetPoint(Handle, TASK_POINT_DEBUG, 0);
 //	DBG("%s, %x", Name, Handle);
 	return Handle;
@@ -91,7 +114,9 @@ void Task_SendEvent(HANDLE TaskHandle, uint32_t ID, uint32_t P1, uint32_t P2, ui
 	if (!TaskHandle) return;
 	uint32_t Critical;
 	llist_head *Head = (llist_head *)vTaskGetPoint(TaskHandle, TASK_POINT_LIST_HEAD);
+#ifdef __USE_SEMAPHORE__
 	SemaphoreHandle_t sem = (SemaphoreHandle_t)vTaskGetPoint(TaskHandle, TASK_POINT_EVENT_SEM);
+#endif
 	Core_EventStruct *Event = OS_Zalloc(sizeof(Core_EventStruct));
 	Event->ID = ID;
 	Event->Param1 = P1;
@@ -108,7 +133,25 @@ void Task_SendEvent(HANDLE TaskHandle, uint32_t ID, uint32_t P1, uint32_t P2, ui
 		while(1) {;}
 	}
 	OS_ExitCritical(Critical);
+#ifdef __USE_SEMAPHORE__
 	OS_MutexRelease(sem);
+#endif
+#ifdef __USE_FREERTOS_NOTIFY__
+	BaseType_t xHigherPriorityTaskWoken = pdFALSE;
+	if (OS_CheckInIrq())
+	{
+		vTaskGenericNotifyGiveFromISR(TaskHandle, TASK_NOTIFY_EVENT, &xHigherPriorityTaskWoken);
+		if (xHigherPriorityTaskWoken)
+		{
+			portYIELD_WITHIN_API();
+		}
+	}
+	else
+	{
+		xTaskGenericNotify(TaskHandle, TASK_NOTIFY_EVENT, ( 0 ), eIncrement, NULL );
+	}
+
+#endif
 }
 
 int32_t Task_GetEvent(HANDLE TaskHandle, uint32_t TargetEventID, Task_EventStruct *OutEvent, CBFuncEx_t Callback, uint64_t Tick)
@@ -123,7 +166,9 @@ int32_t Task_GetEvent(HANDLE TaskHandle, uint32_t TargetEventID, Task_EventStruc
 	}
 	if (!TaskHandle) return -ERROR_PARAM_INVALID;
 	llist_head *Head = (llist_head *)vTaskGetPoint(TaskHandle, TASK_POINT_LIST_HEAD);
+#ifdef __USE_SEMAPHORE__
 	SemaphoreHandle_t sem = (SemaphoreHandle_t)vTaskGetPoint(TaskHandle, TASK_POINT_EVENT_SEM);
+#endif
 	Timer_t *Timer = (Timer_t *)vTaskGetPoint(TaskHandle, TASK_POINT_EVENT_TIMER);
 	if (Tick)
 	{
@@ -199,7 +244,12 @@ WAIT_NEW_EVENT:
 			goto GET_EVENT_DONE;
 		}
 	}
+#ifdef __USE_SEMAPHORE__
 	OS_MutexLock(sem);
+#endif
+#ifdef __USE_FREERTOS_NOTIFY__
+	xTaskGenericNotifyWait(TASK_NOTIFY_EVENT, 0, 0, NULL, portMAX_DELAY);
+#endif
 	goto GET_NEW_EVENT;
 GET_EVENT_DONE:
 	Timer_Stop(Timer);
@@ -233,10 +283,17 @@ void Task_DelayTick(uint64_t Tick)
 		return;
 	}
 	HANDLE TaskHandle = vTaskGetCurrent();
+#ifdef __USE_SEMAPHORE__
 	SemaphoreHandle_t sem = (SemaphoreHandle_t)vTaskGetPoint(TaskHandle, TASK_POINT_DELAY_SEM);
+#endif
 	Timer_t *Timer = (Timer_t *)vTaskGetPoint(TaskHandle, TASK_POINT_DELAY_TIMER);
 	Timer_Start(Timer, Tick, 0);
+#ifdef __USE_SEMAPHORE__
 	OS_MutexLock(sem);
+#endif
+#ifdef __USE_FREERTOS_NOTIFY__
+	xTaskGenericNotifyWait(TASK_NOTIFY_DELAY, 0, 0, NULL, portMAX_DELAY);
+#endif
 }
 
 void Task_DelayUS(uint32_t US)

+ 4 - 0
bsp/air105/hal/core_tick.c

@@ -56,6 +56,10 @@ uint64_t GetSysTickMS(void)
 	return GetSysTick()/CORE_TICK_1MS;
 }
 
+void SysTickAddSleepTime(uint64_t Tick)
+{
+	PowerOnTickCnt += Tick;
+}
 
 void SysTickDelay(uint32_t Tick)
 {

+ 12 - 5
bsp/air105/hal/core_timer.c

@@ -39,7 +39,7 @@ typedef struct
 	llist_head Head;
 	uint64_t NextTick;
 	uint32_t IDSn;
-
+	uint8_t SleepFlush;
 }Timer_CtrlStruct;
 static Timer_t prvTimer[TIMER_SN_MAX];
 static Timer_CtrlStruct prvTimerCtrl;
@@ -141,7 +141,7 @@ static void SystemTimerIrqHandler( int32_t Line, void *pData)
 		if (Timer->AddTick)
 		{
 			Critical = OS_EnterCritical();
-			Timer_Update(Timer, Timer->AddTick, 0);
+			Timer_Update(Timer, Timer->AddTick, prvTimerCtrl.SleepFlush);
 			if (llist_empty(&prvTimerCtrl.Head))
 			{
 				llist_add_tail(&Timer->Node, &prvTimerCtrl.Head);
@@ -181,7 +181,7 @@ void Timer_Init(void)
 	INIT_LLIST_HEAD(&prvTimerCtrl.Head);
 	TIMM0->TIM[SYS_TIMER_TIM].ControlReg = 0;
 	ISR_OnOff(SYS_TIMER_IRQ, 0);
-	ISR_SetHandler(SYS_TIMER_IRQ, SystemTimerIrqHandler);
+	ISR_SetHandler(SYS_TIMER_IRQ, SystemTimerIrqHandler, NULL);
 #ifdef __BUILD_OS__
 	ISR_SetPriority(SYS_TIMER_IRQ, IRQ_LOWEST_PRIORITY - 1);
 #else
@@ -196,9 +196,16 @@ void Timer_Task(void *Param)
 
 }
 
-void Timer_Run(void)
+void Timer_WakeupRun(void)
 {
-	Timer_Task(NULL);
+	if (GetSysTick() >= prvTimerCtrl.NextTick)
+	{
+		ISR_OnOff(SYS_TIMER_IRQ, 0);
+		prvTimerCtrl.SleepFlush = 1;
+		SystemTimerIrqHandler(SYS_TIMER_IRQ, NULL);
+		prvTimerCtrl.SleepFlush = 0;
+		ISR_OnOff(SYS_TIMER_IRQ, 1);
+	}
 }
 
 

+ 16 - 1
bsp/air105/hal/core_uart.c

@@ -282,6 +282,10 @@ void Uart_BaseInit(uint8_t UartID, uint32_t BaudRate, uint8_t IsRxCacheEnable, u
 #endif
     }
 #endif
+    if (UartID != DBG_UART_ID)
+    {
+    	PM_SetHardwareRunFlag(PM_HW_UART_0 + UartID, 1);
+    }
 }
 
 
@@ -311,7 +315,10 @@ void Uart_DeInit(uint8_t UartID)
 
 	/* LCR = 0 */
 	Uart->LCR &= ~UART_LCR_DLAB;
-
+	if (UartID != DBG_UART_ID)
+    {
+    	PM_SetHardwareRunFlag(PM_HW_UART_0 + UartID, 0);
+    }
 
 }
 
@@ -718,3 +725,11 @@ uint32_t Uart_GetLastError(uint8_t UartID)
 {
 	return prvUart[UartID].LastError;
 }
+
+void Uart_Sleep(uint8_t UartID, uint8_t OnOff)
+{
+    if (UartID != DBG_UART_ID)
+    {
+    	PM_SetHardwareRunFlag(PM_HW_UART_0 + UartID, OnOff);
+    }
+}

+ 3 - 1
bsp/air105/include/FreeRTOSConfig.h

@@ -96,7 +96,9 @@
 #define configUSE_APPLICATION_TASK_TAG    0
 #define configUSE_COUNTING_SEMAPHORES     1
 #define configGENERATE_RUN_TIME_STATS     0
-#define configNUM_THREAD_LOCAL_STORAGE_POINTERS 6
+#define configNUM_THREAD_LOCAL_STORAGE_POINTERS 4
+#define configUSE_TASK_NOTIFICATIONS		1
+#define configTASK_NOTIFICATION_ARRAY_ENTRIES    2
 /* Co-routine definitions. */
 #define configUSE_CO_ROUTINES           0
 #define configMAX_CO_ROUTINE_PRIORITIES (2)

+ 1 - 0
bsp/air105/include/bl_inc.h

@@ -40,6 +40,7 @@
 #include "core_uart.h"
 #include "core_rtc.h"
 #include "core_i2c.h"
+#include "core_pm.h"
 
 #include "usb_driver.h"
 #include "usb_device.h"

+ 1 - 1
bsp/air105/include/core_gpio.h

@@ -100,6 +100,6 @@ void GPIO_OutputMulti(uint32_t Port, uint32_t Pins, uint32_t Level);
  */
 uint32_t GPIO_InputMulti(uint32_t Port);
 
-void GPIO_ExtiSetHWTimerCB(CBFuncEx_t CB, void *pParam);
+void GPIO_ExtiSetCB(uint32_t Pin, CBFuncEx_t CB, void *pParam);
 void GPIO_ODConfig(uint32_t Pin, uint8_t InitValue);
 #endif

+ 48 - 0
bsp/air105/include/core_pm.h

@@ -0,0 +1,48 @@
+#ifndef __CORE_PM_H__
+#define __CORE_PM_H__
+enum
+{
+	PM_HW_UART_0,
+	PM_HW_UART_1,
+	PM_HW_UART_2,
+	PM_HW_UART_3,
+	PM_HW_UART_4,
+	PM_HW_UART_5,
+	PM_HW_UART_6,
+	PM_HW_UART_7,
+	PM_HW_SPI_0,
+	PM_HW_SPI_1,
+	PM_HW_SPI_2,
+	PM_HW_SPI_3,
+	PM_HW_SPI_4,
+	PM_HW_SPI_5,
+	PM_HW_HSPI,
+	PM_HW_QSPI,
+	PM_HW_TIMER_0,
+	PM_HW_TIMER_1,
+	PM_HW_TIMER_2,
+	PM_HW_TIMER_3,
+	PM_HW_TIMER_4,
+	PM_HW_TIMER_5,
+	PM_HW_TIMER_6,
+	PM_HW_TIMER_7,
+	PM_HW_I2C_0,
+	PM_HW_I2C_1,
+	PM_HW_I2C_2,
+	PM_HW_I2C_3,
+	PM_HW_I2C_4,
+	PM_HW_I2C_5,
+	PM_HW_DAC_0,
+	PM_HW_DCMI_0,
+	PM_HW_MAX = 32,
+	PM_DRV_USB = 0,
+	PM_DRV_DBG,
+	PM_DRV_USER,
+	PM_DRV_MAX = 32,
+};
+
+void PM_Init(void);
+void PM_SetHardwareRunFlag(uint32_t PmHWSn, uint32_t OnOff);
+void PM_SetDriverRunFlag(uint32_t PmDrvSn, uint32_t OnOff);
+int32_t PM_Sleep(void);
+#endif

+ 1 - 1
bsp/air105/include/core_rtc.h

@@ -30,5 +30,5 @@ void RTC_GetDateTime(Date_UserDataStruct *pDate, Time_UserDataStruct *pTime);
 
 uint64_t RTC_GetUTC(void);
 
-
+void RTC_SetAlarm(uint32_t TimeSecond, CBFuncEx_t CB, void *pParam);
 #endif

+ 1 - 0
bsp/air105/include/core_tick.h

@@ -27,4 +27,5 @@ void SysTickDelayUntil(uint64_t StartTick, uint32_t Tick);
 void CoreTick_Init(void);
 uint64_t GetSysTickMS(void);
 uint64_t GetSysTickUS(void);
+void SysTickAddSleepTime(uint64_t Tick);
 #endif

+ 1 - 1
bsp/air105/include/core_timer.h

@@ -34,7 +34,7 @@ typedef struct Timer_InfoStruct Timer_t;
 
 void Timer_Init(void);
 //void Timer_Task(void *Param);
-//void Timer_Run(void);
+void Timer_WakeupRun(void);
 Timer_t * Timer_Create(CBFuncEx_t CB, void *Param, void *NotifyTask);
 Timer_t * Timer_GetStatic(uint32_t Sn, CBFuncEx_t CB, void *Param, void *NotifyTask);
 int Timer_Start(Timer_t *Timer, uint64_t Tick, uint8_t IsRepeat);

+ 1 - 0
bsp/air105/include/core_uart.h

@@ -102,4 +102,5 @@ void Uart_PrintReg(uint8_t UartID);
 void Uart_ChangeBR(uint8_t UartID, uint32_t BaudRate);
 uint32_t Uart_GetLastError(uint8_t UartID);
 void Uart_GlobalInit(void);
+void Uart_Sleep(uint8_t UartID, uint8_t OnOff);
 #endif

+ 10 - 16
bsp/air105/platform/app_main.c

@@ -67,6 +67,13 @@ void SystemInit(void)
 	SYSCTRL->PHER_CTRL &= ~(1 << 20);
     SYSCTRL->SOFT_RST2 &= ~SYSCTRL_USB_RESET;
     SYSCTRL->LOCK_R |= SYSCTRL_USB_RESET;
+//    BPU->SEN_ANA0 &= ~(1 << 10);
+#ifdef __USE_32K_XTL__
+	BPU->SEN_ANA0 |= (1 << 10)|(7 << 25) | (2 << 29);	//外部32768+最大充电电流+最大晶振供电
+#else
+	BPU->SEN_ANA0 &= ~(1 << 10);
+	BPU->SEN_ANA0 |= (7 << 25) | (2 << 29);	//内部32K+最大充电电流+最大晶振供电
+#endif
 	__enable_irq();
 }
 
@@ -103,22 +110,7 @@ void vApplicationIdleHook( void )
 		WDT_Feed();
 		Timer_StartMS(prvWDTTimer, 12000, 1);
 	}
-	if (Core_GetSleepFlag())
-	{
-		SYSCTRL->FREQ_SEL = (SYSCTRL->FREQ_SEL & ~(SYSCTRL_FREQ_SEL_POWERMODE_Mask)) | SYSCTRL_FREQ_SEL_POWERMODE_CLOSE_CPU;
-		while (!(SYSCTRL->FREQ_SEL & (~SYSCTRL_FREQ_SEL_POWERMODE_CLOSE_CPU)));
-		__disable_irq();
-		__WFI();
-		__enable_irq();
-		if (gMainWDTEnable)
-		{
-			WDT_Feed();
-
-		}
-		Timer_Stop(prvWDTTimer);
-
-	}
-
+	PM_Sleep();
 }
 
 
@@ -167,7 +159,9 @@ int main(void)
 	Uart_GlobalInit();
 	DMA_TakeStream(DMA1_STREAM_1);//for qspi
 	DBG_Init(1);
+	PM_Init();
 	Timer_Init();
+	GPIO_GlobalInit(NULL);
 	prvHW_Init();
 	prvDrv_Init();
 	gMainWDTEnable = 1;

+ 1 - 0
bsp/air105/test/test_dht11.c

@@ -104,6 +104,7 @@ void DHT11_TestOnce(uint8_t Pin, CBFuncEx_t CB)
 		HWTimer_AddOperation(HWTimerID, &OPCmd);
 	}
 	OPCmd.Operation = OP_QUEUE_CMD_CAPTURE_END;
+	OPCmd.Arg1 = Pin;
 	HWTimer_AddOperation(HWTimerID, &OPCmd);
 	HWTimer_StartOperationQueue(HWTimerID);
 }

+ 28 - 0
bsp/air105/test/test_pm.c

@@ -0,0 +1,28 @@
+#include "user.h"
+
+static int32_t test_done(void *pData, void *pParam)
+{
+	DBG("RTC唤醒, 测试结束");
+	PM_SetDriverRunFlag(PM_DRV_DBG, 1);
+}
+
+void prvPM_Test(void *p)
+{
+	DBG("测试在1秒后开始,休眠60秒后RTC唤醒恢复");
+	Task_DelayMS(1000);
+	PM_SetDriverRunFlag(PM_DRV_DBG, 0);	//DBG是开机就打开的,如果没有其他外设使用,关闭这个就可以进入低功耗
+	RTC_SetAlarm(60, test_done, 1);	//开个RTC唤醒一下,或者键盘,或者GPIO
+	while(1)
+	{
+		Task_DelayMS(1000);
+		DBG("UTC %llu", RTC_GetUTC());
+	}
+}
+
+
+void PM_TestInit(void)
+{
+	Task_Create(prvPM_Test, NULL, 1024, SERVICE_TASK_PRO, "pm task");
+}
+
+//INIT_TASK_EXPORT(PM_TestInit, "3");

+ 1 - 2
bsp/audio/src/audio_ll_drv.c

@@ -87,7 +87,6 @@ int32_t Audio_StartRaw(Audio_StreamStruct *pStream)
 	{
 	case AUSTREAM_BUS_DAC:
 		GPIO_Iomux(GPIOC_00, 2);
-		GPIO_PullConfig(GPIOC_00, 0, 0);
 		DAC_ForceStop(pStream->BusID);
 		DAC_DMAInit(0, DAC_TX_DMA_STREAM);
 		DAC_Setup(pStream->BusID, pStream->SampleRate, prvAudio.DACOutRMode);
@@ -221,7 +220,7 @@ void Audio_Stop(Audio_StreamStruct *pStream)
 	switch(pStream->BusType)
 	{
 	case AUSTREAM_BUS_DAC:
-		DAC_ForceStop(pStream->BusID);
+		DAC_Stop(pStream->BusID);
 		llist_traversal(&pStream->DataHead, prvAudio_DeleteData, NULL);
 		break;
 	default:

+ 1 - 12
bsp/common/src/core_service.c

@@ -113,7 +113,6 @@ typedef struct
 	uint64_t LCDDrawDoneByte;
 	uint32_t InitAllocMem;
 	uint32_t LastAllocMem;
-	uint8_t SleepEnable;
 
 }Service_CtrlStruct;
 
@@ -1403,6 +1402,7 @@ static void prvCore_PrintTaskStack(HANDLE TaskHandle)
 {
 	uint32_t SP, StackAddress, Len, i, PC;
 	uint32_t Buffer[16];
+	if (!TaskHandle) return;
 	char *Name = vTaskInfo(TaskHandle, &SP, &StackAddress, &Len);
 	Len *= 4;
 	DBG_Trace("%s call stack info:", Name);
@@ -1432,16 +1432,6 @@ void Core_PrintServiceStack(void)
 	prvCore_PrintTaskStack(prvService.ServiceHandle);
 }
 
-void Core_SetSleepEnable(uint8_t OnOff)
-{
-	prvService.SleepEnable = OnOff;
-}
-
-uint8_t Core_GetSleepFlag(void)
-{
-	return prvService.SleepEnable;
-}
-
 void Core_DebugMem(uint8_t HeapID, const char *FuncName, uint32_t Line)
 {
 	int32_t curalloc, totfree, maxfree;
@@ -1466,7 +1456,6 @@ void Core_HWTaskInit(void)
 
 void Core_ServiceInit(void)
 {
-	prvService.SleepEnable = 0;
 	prvService.ServiceHandle = Task_Create(prvService_Task, NULL, 8 * 1024, SERVICE_TASK_PRO, "Serv task");
 }
 

+ 3 - 0
bsp/usb/src/core_usb_stack.c

@@ -551,6 +551,7 @@ void USB_StackDeviceBusChange(uint8_t USB_ID, uint8_t Type)
 	switch (Type)
 	{
 	case USBD_BUS_TYPE_SUSPEND:
+		PM_SetDriverRunFlag(PM_DRV_USB, 0);
 		Core_USBAction(USB_ID, SERV_USB_SUSPEND, USBCore->pHWCtrl);
 		USBCore->Setup.CB(uPV.u32, USBCore->Setup.pUserData);
 		break;
@@ -559,6 +560,7 @@ void USB_StackDeviceBusChange(uint8_t USB_ID, uint8_t Type)
 		USBCore->Setup.CB(uPV.u32, USBCore->Setup.pUserData);
 		break;
 	case USBD_BUS_TYPE_RESET:
+		PM_SetDriverRunFlag(PM_DRV_USB, 1);
 		for(i = 0; i < USB_EP_MAX; i++)
 		{
 			USB_StackResetEpBuffer(USB_ID, i);
@@ -569,6 +571,7 @@ void USB_StackDeviceBusChange(uint8_t USB_ID, uint8_t Type)
 	case USBD_BUS_TYPE_NEW_SOF:
 		break;
 	case USBD_BUS_TYPE_DISCONNECT:
+		PM_SetDriverRunFlag(PM_DRV_USB, 0);
 		if (USBCore->DeviceState != USB_STATE_DETACHED)
 		{
 			USB_Stop(USBCore->pHWCtrl);