1 // From module: RTC - Real Time Counter in Count Mode (Polled APIs)
2 #include <rtc_count.h>
3 #include <rtc_count_interrupt.h>
4 // #include <rtc_tamper.h>
5 #include <power.h>
6 #include <port.h>
7 
8 #include <rtthread.h>
9 
10 /* RTC module instance */
11 static struct rtc_module rtc_instance;
12 
_rtc_timer_int_cb(void)13 static void _rtc_timer_int_cb(void)
14 {
15 	port_pin_toggle_output_level(PIN_PB30);
16 }
17 
18 /* Init RTC as ADC sample timer */
_rtc_timer_init(void)19 static void _rtc_timer_init(void)
20 {
21 	struct rtc_count_config conf;
22 
23 	rtc_count_get_config_defaults(&conf);
24 
25 	conf.prescaler         = RTC_COUNT_PRESCALER_DIV_1;
26 	conf.mode              = RTC_COUNT_MODE_32BIT;
27 	conf.clear_on_match    = false;
28 	conf.compare_values[0] = 0;
29 
30 	// struct rtc_count_events evconfig;
31 	// evconfig.generate_event_on_compare[0] = true;
32 
33 	rtc_count_init(&rtc_instance, RTC, &conf);
34 	// rtc_count_enable_events(&rtc_instance, &evconfig);
35     // rtc_count_enable(&rtc_instance);
36 	rtc_count_set_count(&rtc_instance, 0);
37 	rtc_count_register_callback(&rtc_instance, _rtc_timer_int_cb, RTC_COUNT_CALLBACK_COMPARE_0);
38 	// rtc_count_enable_callback(&rtc_instance, RTC_COUNT_CALLBACK_COMPARE_0);
39 }
40 
_rtc_timer_start(uint32_t ms)41 static void _rtc_timer_start(uint32_t ms)
42 {
43 	uint32_t compare = 0;
44 
45 	compare = (uint32_t)(32.768 * ms);
46 
47 	// rtc_count_register_callback(&rtc_instance, _rtc_timer_int_cb, RTC_COUNT_CALLBACK_COMPARE_0);
48 	rtc_count_enable_callback(&rtc_instance, RTC_COUNT_CALLBACK_COMPARE_0);
49 
50 	rtc_count_set_count(&rtc_instance, 0);
51 	rtc_count_set_compare(&rtc_instance, compare, RTC_COUNT_COMPARE_0);
52 	rtc_count_enable(&rtc_instance);
53 }
54 
sleep_tick_adjust(uint32_t ms)55 static void sleep_tick_adjust(uint32_t ms)
56 {
57 	uint32_t diff;
58 
59 	diff = rt_tick_from_millisecond(ms);
60 
61 	rt_tick_set(rt_tick_get() + diff);
62 	{
63 		struct rt_thread *thread;
64 
65 		/* check time slice */
66 		thread = rt_thread_self();
67 
68 		if (thread->remaining_tick <= diff)
69 		{
70 			/* change to initialized tick */
71 			thread->remaining_tick = thread->init_tick;
72 
73 			/* yield */
74 			rt_thread_yield();
75 		}
76 		else
77 		{
78 			thread->remaining_tick -= diff;
79 		}
80 
81 		/* check timer */
82 		rt_timer_check();
83 	}
84 }
85 
_sleep_entry(void)86 static void _sleep_entry(void)
87 {
88 	rt_tick_t timeout;
89 	rt_uint32_t ms;
90 	rt_uint32_t count;
91 
92 	system_set_sleepmode(SYSTEM_SLEEPMODE_STANDBY);
93 	timeout = rt_timer_next_timeout_tick() - rt_tick_get();
94 
95 	ms = timeout * (1000 / RT_TICK_PER_SECOND);
96 	rt_kprintf("os tick:%u entry sleep:%u tick\r\n", rt_tick_get(), timeout);
97 
98 	_rtc_timer_start(ms);
99 
100 	system_sleep();
101 
102 	rt_enter_critical();
103 	count = rtc_count_get_count(&rtc_instance);
104 	ms = (count + 32) / 32.768;
105 	rtc_count_disable(&rtc_instance);
106 	sleep_tick_adjust(ms);
107 	timeout = rt_tick_get();
108 	rt_exit_critical();
109 	rt_kprintf("sleep exited, os tick:%u\n", timeout);
110 }
111 
sleep_timer_init(void)112 void sleep_timer_init(void)
113 {
114 	_rtc_timer_init();
115 	rt_thread_idle_sethook(_sleep_entry);
116 }
117 
sleep_timer_start(uint32_t ms)118 void sleep_timer_start(uint32_t ms)
119 {
120 	_rtc_timer_start(ms);
121 }
122 
sleep_timer_stop(void)123 void sleep_timer_stop(void)
124 {
125 	rtc_count_disable(&rtc_instance);
126 }
127