diff options
Diffstat (limited to 'firmware/drivers/rtc/rtc_as3514.c')
-rw-r--r-- | firmware/drivers/rtc/rtc_as3514.c | 107 |
1 files changed, 106 insertions, 1 deletions
diff --git a/firmware/drivers/rtc/rtc_as3514.c b/firmware/drivers/rtc/rtc_as3514.c index 8597d138fb..fe2921b433 100644 --- a/firmware/drivers/rtc/rtc_as3514.c +++ b/firmware/drivers/rtc/rtc_as3514.c | |||
@@ -51,6 +51,112 @@ static inline bool is_leapyear(int year) | |||
51 | return false; | 51 | return false; |
52 | } | 52 | } |
53 | 53 | ||
54 | #ifdef HAVE_RTC_ALARM /* as3543 */ | ||
55 | static int wakeup_h; | ||
56 | static int wakeup_m; | ||
57 | static bool alarm_enabled = false; | ||
58 | |||
59 | void rtc_set_alarm(int h, int m) | ||
60 | { | ||
61 | wakeup_h = h; | ||
62 | wakeup_m = m; | ||
63 | } | ||
64 | |||
65 | void rtc_get_alarm(int *h, int *m) | ||
66 | { | ||
67 | *h = wakeup_h; | ||
68 | *m = wakeup_m; | ||
69 | } | ||
70 | |||
71 | void rtc_alarm_poweroff(void) | ||
72 | { | ||
73 | if(!alarm_enabled) | ||
74 | return; | ||
75 | |||
76 | struct tm tm; | ||
77 | rtc_read_datetime(&tm); | ||
78 | int hours = wakeup_h - tm.tm_hour; | ||
79 | int mins = wakeup_m - tm.tm_min; | ||
80 | if(mins < 0) | ||
81 | { | ||
82 | mins += 60; | ||
83 | hours -= 1; | ||
84 | } | ||
85 | if(hours < 0) | ||
86 | hours += 24; | ||
87 | |||
88 | uint32_t seconds = hours*3600 + mins*60; | ||
89 | if(seconds == 0) | ||
90 | seconds = 24*3600; | ||
91 | |||
92 | seconds -= tm.tm_sec; | ||
93 | |||
94 | disable_irq(); | ||
95 | |||
96 | ascodec_write_pmu(0x1a, 4, 0x0); // In_Cntr : disable hearbeat source | ||
97 | |||
98 | ascodec_write(AS3543_WAKEUP, seconds); | ||
99 | seconds >>= 8; | ||
100 | ascodec_write(AS3543_WAKEUP, seconds); | ||
101 | seconds >>= 8; | ||
102 | seconds |= 1<<7; /* enable bit */ | ||
103 | ascodec_write(AS3543_WAKEUP, seconds); | ||
104 | |||
105 | /* write our watermark : desired time of wake up */ | ||
106 | ascodec_write(AS3543_WAKEUP, wakeup_h); | ||
107 | ascodec_write(AS3543_WAKEUP, wakeup_m); | ||
108 | |||
109 | ascodec_write(AS3514_SYSTEM, (1<<3) | (1<<0)); // enable hearbeat watchdog | ||
110 | |||
111 | while(1); | ||
112 | } | ||
113 | |||
114 | bool rtc_enable_alarm(bool enable) | ||
115 | { | ||
116 | return alarm_enabled = enable; | ||
117 | } | ||
118 | |||
119 | bool rtc_check_alarm_started(bool release_alarm) | ||
120 | { | ||
121 | (void) release_alarm; | ||
122 | |||
123 | /* was it an alarm that triggered power on ? */ | ||
124 | bool alarm_start = false; | ||
125 | |||
126 | /* 3 first reads give the 23 bits counter and enable bit */ | ||
127 | ascodec_read(AS3543_WAKEUP); /* bits 7:0 */ | ||
128 | ascodec_read(AS3543_WAKEUP); /* bits 15:8 */ | ||
129 | if(ascodec_read(AS3543_WAKEUP) & (1<<7)) /* enable bit */ | ||
130 | { | ||
131 | alarm_enabled = true; | ||
132 | |||
133 | /* subsequent reads give the 16 bytes static SRAM */ | ||
134 | wakeup_h = ascodec_read(AS3543_WAKEUP); | ||
135 | wakeup_m = ascodec_read(AS3543_WAKEUP); | ||
136 | |||
137 | struct tm tm; | ||
138 | rtc_read_datetime(&tm); | ||
139 | |||
140 | /* do we wake up at the programmed time, or for another reason ? */ | ||
141 | if(wakeup_h == tm.tm_hour && wakeup_m == tm.tm_min) | ||
142 | alarm_start = true; | ||
143 | } | ||
144 | |||
145 | /* disable alarm */ | ||
146 | ascodec_write(AS3543_WAKEUP, 0); /* bits 7:0 */ | ||
147 | ascodec_write(AS3543_WAKEUP, 0); /* bits 15:8 */ | ||
148 | ascodec_write(AS3543_WAKEUP, 0); /* bits 22:16 + enable bit */ | ||
149 | |||
150 | return alarm_start; | ||
151 | } | ||
152 | |||
153 | bool rtc_check_alarm_flag(void) | ||
154 | { | ||
155 | /* We don't need to do anything special if it has already fired */ | ||
156 | return false; | ||
157 | } | ||
158 | #endif /* HAVE_RTC_ALARM */ | ||
159 | |||
54 | void rtc_init(void) | 160 | void rtc_init(void) |
55 | { | 161 | { |
56 | } | 162 | } |
@@ -168,4 +274,3 @@ int rtc_write_datetime(const struct tm *tm) | |||
168 | } | 274 | } |
169 | return 1; | 275 | return 1; |
170 | } | 276 | } |
171 | |||