1 /* --COPYRIGHT--,BSD
2 * Copyright (c) 2017, Texas Instruments Incorporated
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * * Neither the name of Texas Instruments Incorporated nor the names of
17 * its contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 * --/COPYRIGHT--*/
32 #include <ti/devices/msp432p4xx/driverlib/rtc_c.h>
33 #include <ti/devices/msp432p4xx/driverlib/interrupt.h>
34 #include <ti/devices/msp432p4xx/driverlib/debug.h>
35
36
RTC_C_startClock(void)37 void RTC_C_startClock(void)
38 {
39 RTC_C->CTL0 = (RTC_C->CTL0 & ~RTC_C_CTL0_KEY_MASK) | RTC_C_KEY;
40 BITBAND_PERI(RTC_C->CTL13, RTC_C_CTL13_HOLD_OFS) = 0;
41 BITBAND_PERI(RTC_C->CTL0, RTC_C_CTL0_KEY_OFS) = 0;
42 }
43
RTC_C_holdClock(void)44 void RTC_C_holdClock(void)
45 {
46 RTC_C->CTL0 = (RTC_C->CTL0 & ~RTC_C_CTL0_KEY_MASK) | RTC_C_KEY;
47 BITBAND_PERI(RTC_C->CTL13, RTC_C_CTL13_HOLD_OFS) = 1;
48 BITBAND_PERI(RTC_C->CTL0, RTC_C_CTL0_KEY_OFS) = 0;
49 }
50
RTC_C_setCalibrationFrequency(uint_fast16_t frequencySelect)51 void RTC_C_setCalibrationFrequency(uint_fast16_t frequencySelect)
52 {
53 RTC_C->CTL0 = (RTC_C->CTL0 & ~RTC_C_CTL0_KEY_MASK) | RTC_C_KEY;
54 RTC_C->CTL13 = (RTC_C->CTL13 & ~(RTC_C_CTL13_CALF_3)) | frequencySelect;
55 BITBAND_PERI(RTC_C->CTL0, RTC_C_CTL0_KEY_OFS) = 0;
56 }
57
RTC_C_setCalibrationData(uint_fast8_t offsetDirection,uint_fast8_t offsetValue)58 void RTC_C_setCalibrationData(uint_fast8_t offsetDirection,
59 uint_fast8_t offsetValue)
60 {
61 RTC_C->CTL0 = (RTC_C->CTL0 & ~RTC_C_CTL0_KEY_MASK) | RTC_C_KEY;
62 RTC_C->OCAL = offsetValue + offsetDirection;
63 BITBAND_PERI(RTC_C->CTL0, RTC_C_CTL0_KEY_OFS) = 0;
64 }
65
RTC_C_setTemperatureCompensation(uint_fast16_t offsetDirection,uint_fast8_t offsetValue)66 bool RTC_C_setTemperatureCompensation(uint_fast16_t offsetDirection,
67 uint_fast8_t offsetValue)
68 {
69 while (!BITBAND_PERI(RTC_C->TCMP, RTC_C_TCMP_TCRDY_OFS))
70 ;
71
72 RTC_C->TCMP = offsetValue + offsetDirection;
73
74 if (BITBAND_PERI(RTC_C->TCMP, RTC_C_TCMP_TCOK_OFS))
75 return true;
76 else
77 return false;
78 }
79
RTC_C_initCalendar(const RTC_C_Calendar * calendarTime,uint_fast16_t formatSelect)80 void RTC_C_initCalendar(const RTC_C_Calendar *calendarTime,
81 uint_fast16_t formatSelect)
82 {
83 RTC_C->CTL0 = (RTC_C->CTL0 & ~RTC_C_CTL0_KEY_MASK) | RTC_C_KEY;
84
85 BITBAND_PERI(RTC_C->CTL13, RTC_C_CTL13_HOLD_OFS) = 1;
86
87 if (formatSelect)
88 BITBAND_PERI(RTC_C->CTL13, RTC_C_CTL13_BCD_OFS) = 1;
89 else
90 BITBAND_PERI(RTC_C->CTL13, RTC_C_CTL13_BCD_OFS) = 0;
91
92 RTC_C->TIM0 = (calendarTime->minutes << RTC_C_TIM0_MIN_OFS)
93 | calendarTime->seconds;
94 RTC_C->TIM1 = (calendarTime->dayOfWeek << RTC_C_TIM1_DOW_OFS)
95 | calendarTime->hours;
96 RTC_C->DATE = (calendarTime->month << RTC_C_DATE_MON_OFS)
97 | calendarTime->dayOfmonth;
98 RTC_C->YEAR = calendarTime->year;
99
100 BITBAND_PERI(RTC_C->CTL0, RTC_C_CTL0_KEY_OFS) = 0;
101 }
102
103
RTC_C_getCalendarTime(void)104 RTC_C_Calendar RTC_C_getCalendarTime(void)
105 {
106 RTC_C_Calendar tempCal;
107
108 while (!(BITBAND_PERI(RTC_C->CTL13, RTC_C_CTL13_RDY_OFS)))
109 ;
110
111 tempCal.seconds = RTC_C->TIM0
112 & (RTC_C_TIM0_SEC_LD_MASK | RTC_C_TIM0_SEC_HD_MASK);
113 tempCal.minutes = (RTC_C->TIM0
114 & (RTC_C_TIM0_MIN_LD_MASK | RTC_C_TIM0_MIN_HD_MASK))
115 >> RTC_C_TIM0_MIN_OFS;
116 tempCal.hours = RTC_C->TIM1
117 & (RTC_C_TIM1_HOUR_LD_MASK | RTC_C_TIM1_HOUR_HD_MASK);
118 tempCal.dayOfWeek = (RTC_C->TIM1
119 & (RTC_C_TIM1_DOW_MASK)) >> RTC_C_TIM1_DOW_OFS;
120 tempCal.dayOfmonth = RTC_C->DATE
121 & (RTC_C_DATE_DAY_LD_MASK | RTC_C_DATE_DAY_HD_MASK);
122 tempCal.month = (RTC_C->DATE & (RTC_C_DATE_MON_LD_MASK | RTC_C_DATE_MON_HD))
123 >> RTC_C_DATE_MON_OFS;
124 tempCal.year = RTC_C->YEAR;
125
126 return (tempCal);
127 }
128
129
RTC_C_setCalendarAlarm(uint_fast8_t minutesAlarm,uint_fast8_t hoursAlarm,uint_fast8_t dayOfWeekAlarm,uint_fast8_t dayOfmonthAlarm)130 void RTC_C_setCalendarAlarm(uint_fast8_t minutesAlarm, uint_fast8_t hoursAlarm,
131 uint_fast8_t dayOfWeekAlarm, uint_fast8_t dayOfmonthAlarm)
132 {
133 //Each of these is XORed with 0x80 to turn on if an integer is passed,
134 //or turn OFF if RTC_ALARM_OFF (0x80) is passed.
135 RTC_C->AMINHR = ((hoursAlarm ^ 0x80) << 8 )| (minutesAlarm ^ 0x80);
136 RTC_C->ADOWDAY = ((dayOfmonthAlarm ^ 0x80) << 8 )| (dayOfWeekAlarm ^ 0x80);
137 }
138
RTC_C_setCalendarEvent(uint_fast16_t eventSelect)139 void RTC_C_setCalendarEvent(uint_fast16_t eventSelect)
140 {
141 RTC_C->CTL0 = (RTC_C->CTL0 & ~RTC_C_CTL0_KEY_MASK) | RTC_C_KEY;
142 RTC_C->CTL13 = (RTC_C->CTL13 & ~(RTC_C_CTL13_TEV_3)) | eventSelect;
143 BITBAND_PERI(RTC_C->CTL0, RTC_C_CTL0_KEY_OFS) = 0;
144 }
145
RTC_C_definePrescaleEvent(uint_fast8_t prescaleSelect,uint_fast8_t prescaleEventDivider)146 void RTC_C_definePrescaleEvent(uint_fast8_t prescaleSelect,
147 uint_fast8_t prescaleEventDivider)
148 {
149 if(prescaleSelect == RTC_C_PRESCALE_0)
150 {
151 HWREG8(&RTC_C->PS0CTL) &= ~(RTC_C_PS0CTL_RT0IP_7);
152 HWREG8(&RTC_C->PS0CTL) |= prescaleEventDivider;
153 }
154 else if(prescaleSelect == RTC_C_PRESCALE_1)
155 {
156 HWREG8(&RTC_C->PS1CTL) &= ~(RTC_C_PS0CTL_RT0IP_7);
157 HWREG8(&RTC_C->PS1CTL) |= prescaleEventDivider;
158 }
159 }
160
RTC_C_getPrescaleValue(uint_fast8_t prescaleSelect)161 uint_fast8_t RTC_C_getPrescaleValue(uint_fast8_t prescaleSelect)
162 {
163 if (RTC_C_PRESCALE_0 == prescaleSelect)
164 {
165 return (RTC_C->PS & RTC_C_PS_RT0PS_MASK);
166 } else if (RTC_C_PRESCALE_1 == prescaleSelect)
167 {
168 return (RTC_C->PS & RTC_C_PS_RT1PS_MASK)>>RTC_C_PS_RT1PS_OFS;
169 } else
170 {
171 return (0);
172 }
173 }
174
RTC_C_setPrescaleValue(uint_fast8_t prescaleSelect,uint_fast8_t prescaleCounterValue)175 void RTC_C_setPrescaleValue(uint_fast8_t prescaleSelect,
176 uint_fast8_t prescaleCounterValue)
177 {
178 RTC_C->CTL0 = (RTC_C->CTL0 & ~RTC_C_CTL0_KEY_MASK) | RTC_C_KEY;
179
180 if (RTC_C_PRESCALE_0 == prescaleSelect)
181 {
182 RTC_C->PS = (RTC_C->PS & ~RTC_C_PS_RT0PS_MASK) | prescaleCounterValue;
183 } else if (RTC_C_PRESCALE_1 == prescaleSelect)
184 {
185 RTC_C->PS = (RTC_C->PS & ~RTC_C_PS_RT1PS_MASK)
186 | (prescaleCounterValue << RTC_C_PS_RT1PS_OFS);
187 }
188
189 BITBAND_PERI(RTC_C->CTL0, RTC_C_CTL0_KEY_OFS) = 0;
190 }
191
RTC_C_convertBCDToBinary(uint16_t valueToConvert)192 uint16_t RTC_C_convertBCDToBinary(uint16_t valueToConvert)
193 {
194 RTC_C->BCD2BIN = valueToConvert;
195 return (RTC_C->BCD2BIN);
196 }
197
RTC_C_convertBinaryToBCD(uint16_t valueToConvert)198 uint16_t RTC_C_convertBinaryToBCD(uint16_t valueToConvert)
199 {
200 RTC_C->BIN2BCD = valueToConvert;
201 return (RTC_C->BIN2BCD);
202 }
203
RTC_C_enableInterrupt(uint8_t interruptMask)204 void RTC_C_enableInterrupt(uint8_t interruptMask)
205 {
206 if (interruptMask
207 & (RTC_C_CTL0_OFIE + RTC_C_CTL0_TEVIE + RTC_C_CTL0_AIE
208 + RTC_C_CTL0_RDYIE))
209 {
210 RTC_C->CTL0 = (RTC_C->CTL0 & ~RTC_C_CTL0_KEY_MASK)
211 | (RTC_C_KEY
212 | (interruptMask
213 & (RTC_C_CTL0_OFIE + RTC_C_CTL0_TEVIE
214 + RTC_C_CTL0_AIE + RTC_C_CTL0_RDYIE)));
215 BITBAND_PERI(RTC_C->CTL0, RTC_C_CTL0_KEY_OFS) = 0;
216 }
217
218 if (interruptMask & RTC_C_PRESCALE_TIMER0_INTERRUPT)
219 {
220 BITBAND_PERI(RTC_C->PS0CTL, RTC_C_PS0CTL_RT0PSIE_OFS) = 1;
221 }
222
223 if (interruptMask & RTC_C_PRESCALE_TIMER1_INTERRUPT)
224 {
225 BITBAND_PERI(RTC_C->PS1CTL,RTC_C_PS1CTL_RT1PSIE_OFS) = 1;
226 }
227 }
228
RTC_C_disableInterrupt(uint8_t interruptMask)229 void RTC_C_disableInterrupt(uint8_t interruptMask)
230 {
231 uint16_t allIntMask = (RTC_C_CTL0_OFIE + RTC_C_CTL0_TEVIE + RTC_C_CTL0_AIE
232 + RTC_C_CTL0_RDYIE);
233
234 if (interruptMask & allIntMask)
235 {
236 RTC_C->CTL0 = (RTC_C->CTL0
237 & ~((interruptMask & allIntMask) | RTC_C_CTL0_KEY_MASK))
238 | RTC_C_KEY;
239
240 BITBAND_PERI(RTC_C->CTL0, RTC_C_CTL0_KEY_OFS) = 0;
241 }
242
243 if (interruptMask & RTC_C_PRESCALE_TIMER0_INTERRUPT)
244 {
245 BITBAND_PERI(RTC_C->PS0CTL, RTC_C_PS0CTL_RT0PSIE_OFS) = 0;
246 }
247
248 if (interruptMask & RTC_C_PRESCALE_TIMER1_INTERRUPT)
249 {
250 BITBAND_PERI(RTC_C->PS1CTL, RTC_C_PS1CTL_RT1PSIE_OFS) = 0;
251 }
252 }
253
RTC_C_getInterruptStatus(void)254 uint_fast8_t RTC_C_getInterruptStatus(void)
255 {
256 uint_fast8_t tempInterruptFlagMask = 0x00;
257 uint_fast8_t interruptFlagMask = RTC_C_TIME_EVENT_INTERRUPT
258 | RTC_C_CLOCK_ALARM_INTERRUPT | RTC_C_CLOCK_READ_READY_INTERRUPT
259 | RTC_C_PRESCALE_TIMER0_INTERRUPT | RTC_C_PRESCALE_TIMER1_INTERRUPT
260 | RTC_C_OSCILLATOR_FAULT_INTERRUPT;
261
262 tempInterruptFlagMask |= (RTC_C->CTL0 & (interruptFlagMask >> 4));
263
264 tempInterruptFlagMask = tempInterruptFlagMask << 4;
265
266 if (interruptFlagMask & RTC_C_PRESCALE_TIMER0_INTERRUPT)
267 {
268 if (BITBAND_PERI(RTC_C->PS0CTL, RTC_C_PS0CTL_RT0PSIFG_OFS))
269 {
270 tempInterruptFlagMask |= RTC_C_PRESCALE_TIMER0_INTERRUPT;
271 }
272 }
273
274 if (interruptFlagMask & RTC_C_PRESCALE_TIMER1_INTERRUPT)
275 {
276 if (BITBAND_PERI(RTC_C->PS1CTL, RTC_C_PS1CTL_RT1PSIFG_OFS))
277 {
278 tempInterruptFlagMask |= RTC_C_PRESCALE_TIMER1_INTERRUPT;
279 }
280 }
281
282 return (tempInterruptFlagMask);
283 }
284
RTC_C_getEnabledInterruptStatus(void)285 uint_fast8_t RTC_C_getEnabledInterruptStatus(void)
286 {
287
288 uint32_t intStatus = RTC_C_getInterruptStatus();
289
290 if (!BITBAND_PERI(RTC_C->CTL0, RTC_C_CTL0_OFIE_OFS))
291 {
292 intStatus &= ~RTC_C_OSCILLATOR_FAULT_INTERRUPT;
293 }
294
295 if (!BITBAND_PERI(RTC_C->CTL0, RTC_C_CTL0_TEVIE_OFS))
296 {
297 intStatus &= ~RTC_C_TIME_EVENT_INTERRUPT;
298 }
299
300 if (!BITBAND_PERI(RTC_C->CTL0, RTC_C_CTL0_AIE_OFS))
301 {
302 intStatus &= ~RTC_C_CLOCK_ALARM_INTERRUPT;
303 }
304
305 if (!BITBAND_PERI(RTC_C->CTL0, RTC_C_CTL0_RDYIE_OFS))
306 {
307 intStatus &= ~RTC_C_CLOCK_READ_READY_INTERRUPT;
308 }
309
310 if (!BITBAND_PERI(RTC_C->PS0CTL, RTC_C_PS0CTL_RT0PSIE_OFS))
311 {
312 intStatus &= ~RTC_C_PRESCALE_TIMER0_INTERRUPT;
313 }
314
315 if (!BITBAND_PERI(RTC_C->PS1CTL, RTC_C_PS1CTL_RT1PSIE_OFS))
316 {
317 intStatus &= ~RTC_C_PRESCALE_TIMER1_INTERRUPT;
318 }
319
320 return intStatus;
321 }
322
RTC_C_clearInterruptFlag(uint_fast8_t interruptFlagMask)323 void RTC_C_clearInterruptFlag(uint_fast8_t interruptFlagMask)
324 {
325 if (interruptFlagMask
326 & (RTC_C_TIME_EVENT_INTERRUPT + RTC_C_CLOCK_ALARM_INTERRUPT
327 + RTC_C_CLOCK_READ_READY_INTERRUPT
328 + RTC_C_OSCILLATOR_FAULT_INTERRUPT))
329 {
330 RTC_C->CTL0 = RTC_C_KEY
331 | (RTC_C->CTL0 & ~((interruptFlagMask >> 4) | RTC_C_CTL0_KEY_MASK));
332 BITBAND_PERI(RTC_C->CTL0, RTC_C_CTL0_KEY_OFS) = 0;
333 }
334
335 if (interruptFlagMask & RTC_C_PRESCALE_TIMER0_INTERRUPT)
336 {
337 BITBAND_PERI(RTC_C->PS0CTL, RTC_C_PS0CTL_RT0PSIFG_OFS) = 0;
338 }
339
340 if (interruptFlagMask & RTC_C_PRESCALE_TIMER1_INTERRUPT)
341 {
342 BITBAND_PERI(RTC_C->PS1CTL, RTC_C_PS1CTL_RT1PSIFG_OFS) = 0;
343 }
344 }
345
RTC_C_registerInterrupt(void (* intHandler)(void))346 void RTC_C_registerInterrupt(void (*intHandler)(void))
347 {
348 Interrupt_registerInterrupt(INT_RTC_C, intHandler);
349 Interrupt_enableInterrupt(INT_RTC_C);
350 }
351
RTC_C_unregisterInterrupt(void)352 void RTC_C_unregisterInterrupt(void)
353 {
354 Interrupt_disableInterrupt(INT_RTC_C);
355 Interrupt_unregisterInterrupt(INT_RTC_C);
356 }
357
358