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