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 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 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 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 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 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 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 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 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 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 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 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 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 192 uint16_t RTC_C_convertBCDToBinary(uint16_t valueToConvert) 193 { 194 RTC_C->BCD2BIN = valueToConvert; 195 return (RTC_C->BCD2BIN); 196 } 197 198 uint16_t RTC_C_convertBinaryToBCD(uint16_t valueToConvert) 199 { 200 RTC_C->BIN2BCD = valueToConvert; 201 return (RTC_C->BIN2BCD); 202 } 203 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 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 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 285 uint_fast8_t RTC_C_getEnabledInterruptStatus(void) 286 { 287 288 uint16_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 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 346 void RTC_C_registerInterrupt(void (*intHandler)(void)) 347 { 348 Interrupt_registerInterrupt(INT_RTC_C, intHandler); 349 Interrupt_enableInterrupt(INT_RTC_C); 350 } 351 352 void RTC_C_unregisterInterrupt(void) 353 { 354 Interrupt_disableInterrupt(INT_RTC_C); 355 Interrupt_unregisterInterrupt(INT_RTC_C); 356 } 357 358