1 /*
2  * Copyright (C) 2018 Alibaba Group Holding Limited
3  */
4 
5 /*
6  * This file supplied RTC one-shot start/stop services for CPU tickless
7  * module, verifyied on STM32L496-DISCOVERY with C3/C4 mode.
8  * C3: stop mode.
9  * C4: standby mode.
10  */
11 #include <k_api.h>
12 
13 #if (AOS_COMP_PWRMGMT > 0)
14 #include <stdint.h>
15 #include <stdbool.h>
16 
17 #include <cpu_tickless.h>
18 
19 #include "ameba_soc.h"
20 
21 #define TIMER_FREQ 32768
22 
23 int cpu_pwr_ready_status_get(void);
24 
25 uint32_t pmu_set_sysactive_time(uint32_t timeout);
26 
27 static pwr_status_t rtc_init(void);
28 static uint32_t     rtc_one_shot_max_seconds(void);
29 static pwr_status_t rtc_one_shot_start(uint64_t planUs);
30 static pwr_status_t rtc_one_shot_stop(uint64_t *pPassedUs);
31 
32 uint64_t expeted_sleep_ms = 0;
33 
34 one_shot_timer_t rtc_one_shot = {
35     rtc_init,
36     rtc_one_shot_max_seconds,
37     rtc_one_shot_start,
38     rtc_one_shot_stop,
39 };
40 
41 static uint32_t timer_counter_start = 0;
42 
rtc_init(void)43 static pwr_status_t rtc_init(void)
44 {
45     SYSTIMER_Init();
46     return PWR_OK;
47 }
48 
rtc_one_shot_start(uint64_t planUs)49 static pwr_status_t rtc_one_shot_start(uint64_t planUs)
50 {
51     expeted_sleep_ms = planUs / 1000;
52     timer_counter_start = SYSTIMER_TickGet();
53     return PWR_OK;
54 }
55 
rtc_one_shot_stop(uint64_t * pPassedUs)56 static pwr_status_t rtc_one_shot_stop(uint64_t *pPassedUs)
57 {
58     uint32_t timer_counter_end = SYSTIMER_TickGet();
59 
60     if (timer_counter_end >= timer_counter_start) {
61         *pPassedUs = (timer_counter_end - timer_counter_start) * (uint64_t)1000000 / TIMER_FREQ;
62     } else {
63         *pPassedUs = (0xffffffff + timer_counter_end - timer_counter_start) * (uint64_t)1000000 / TIMER_FREQ;
64     }
65 
66 //    pmu_set_sysactive_time(2 + (*pPassedUs) / 1000);
67     return PWR_OK;
68 }
69 
rtc_one_shot_max_seconds(void)70 static uint32_t rtc_one_shot_max_seconds(void)
71 {
72     if (cpu_pwr_ready_status_get() == 1) {
73         return (0xffffffff / TIMER_FREQ);
74     } else {
75         return 0;
76     }
77 }
78 
79 #endif /* AOS_COMP_PWRMGMT */
80