1 //*****************************************************************************
2 //
3 //! @file am_hal_rtc.c
4 //!
5 //! @brief Functions for Interfacing and Accessing the Real-Time Clock (RTC).
6 //!
7 //! @addtogroup rtc3 RTC - Real-Time Clock
8 //! @ingroup apollo3_hal
9 //! @{
10 //
11 //*****************************************************************************
12 
13 //*****************************************************************************
14 //
15 // Copyright (c) 2024, Ambiq Micro, Inc.
16 // All rights reserved.
17 //
18 // Redistribution and use in source and binary forms, with or without
19 // modification, are permitted provided that the following conditions are met:
20 //
21 // 1. Redistributions of source code must retain the above copyright notice,
22 // this list of conditions and the following disclaimer.
23 //
24 // 2. Redistributions in binary form must reproduce the above copyright
25 // notice, this list of conditions and the following disclaimer in the
26 // documentation and/or other materials provided with the distribution.
27 //
28 // 3. Neither the name of the copyright holder nor the names of its
29 // contributors may be used to endorse or promote products derived from this
30 // software without specific prior written permission.
31 //
32 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
33 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
34 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
35 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
36 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
37 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
38 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
39 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
40 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
41 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42 // POSSIBILITY OF SUCH DAMAGE.
43 //
44 // This is part of revision release_sdk_3_2_0-dd5f40c14b of the AmbiqSuite Development Package.
45 //
46 //*****************************************************************************
47 
48 #include <stdint.h>
49 #include <stdbool.h>
50 #include "am_mcu_apollo.h"
51 
52 //*****************************************************************************
53 //
54 // Converts a Binary Coded Decimal (BCD) byte to its Decimal form.
55 //
56 //*****************************************************************************
57 static uint8_t
bcd_to_dec(uint8_t ui8BCDByte)58 bcd_to_dec(uint8_t ui8BCDByte)
59 {
60     return (((ui8BCDByte & 0xF0) >> 4) * 10) + (ui8BCDByte & 0x0F);
61 }
62 
63 //*****************************************************************************
64 //
65 // Converts a Decimal byte to its Binary Coded Decimal (BCD) form.
66 //
67 //*****************************************************************************
68 static uint8_t
dec_to_bcd(uint8_t ui8DecimalByte)69 dec_to_bcd(uint8_t ui8DecimalByte)
70 {
71     return (((ui8DecimalByte / 10) << 4) | (ui8DecimalByte % 10));
72 }
73 
74 //*****************************************************************************
75 //! @brief Validates the user defined date & time
76 //!
77 //! @param *pTime - A pointer to the time structure.
78 //!
79 //! Validates the input required to have the time set to a specific period
80 //!
81 //! @return returns true if the pTime structure input values are with in range
82 //*****************************************************************************
83 static bool
time_input_validate(am_hal_rtc_time_t * pTime)84 time_input_validate(am_hal_rtc_time_t *pTime)
85 {
86 
87     bool bValidateStatus = true;
88 
89     if (pTime->ui32Hundredths > 99)
90     {
91         bValidateStatus = false;
92         return bValidateStatus;
93     }
94 
95     if (pTime->ui32Second >= 60)
96     {
97         bValidateStatus = false;
98         return bValidateStatus;
99     }
100 
101     if (pTime->ui32Minute >= 60)
102     {
103         bValidateStatus = false;
104         return bValidateStatus;
105     }
106 
107     if (pTime->ui32Hour >= 24)
108     {
109         bValidateStatus = false;
110         return bValidateStatus;
111     }
112 
113     if (pTime->ui32DayOfMonth < 1 || pTime->ui32DayOfMonth > 31)
114     {
115         bValidateStatus = false;
116         return bValidateStatus;
117     }
118 
119     if (pTime->ui32Month < 1 || pTime->ui32Month > 12)
120     {
121         bValidateStatus = false;
122         return bValidateStatus;
123     }
124 
125     if (pTime->ui32Year > 100)
126     {
127         bValidateStatus = false;
128         return bValidateStatus;
129     }
130 
131     if (pTime->ui32Weekday < 1 || pTime->ui32Weekday > 7)
132     {
133         bValidateStatus = false;
134         return bValidateStatus;
135     }
136 
137     return bValidateStatus;
138 
139 }
140 
141 //*****************************************************************************
142 //
143 // @brief Selects the clock source for the RTC.
144 //
145 // @param ui32OSC the clock source for the RTC.
146 //
147 // This function selects the clock source for the RTC.
148 //
149 // Valid values for ui32OSC are:
150 //
151 //     AM_HAL_RTC_OSC_XT
152 //
153 // @note After selection of the RTC oscillator, a 2 second delay occurs before
154 // the new setting is reflected in status. Therefore the CLKGEN.STATUS.OMODE
155 // bit will not reflect the new status until after the 2s wait period.
156 //
157 //
158 //*****************************************************************************
159 void
am_hal_rtc_osc_select(uint32_t ui32OSC)160 am_hal_rtc_osc_select(uint32_t ui32OSC)
161 {
162     if ( ui32OSC == AM_HAL_RTC_OSC_XT )
163     {
164         // Clear bit to 0 for XTAL
165         CLKGEN->OCTRL &= ~CLKGEN_OCTRL_OSEL_Msk;
166     }
167 }
168 
169 //*****************************************************************************
170 //
171 // @brief Enable/Start the RTC oscillator.
172 //
173 // Starts the RTC oscillator.
174 //
175 //*****************************************************************************
176 void
am_hal_rtc_osc_enable(void)177 am_hal_rtc_osc_enable(void)
178 {
179     //
180     // Start the RTC Oscillator.
181     //
182     RTC->RTCCTL_b.RSTOP = 0;
183 
184 }
185 
186 //*****************************************************************************
187 //
188 // @brief Disable/Stop the RTC oscillator.
189 //
190 // Stops the RTC oscillator.
191 //
192 //*****************************************************************************
193 void
am_hal_rtc_osc_disable(void)194 am_hal_rtc_osc_disable(void)
195 {
196     //
197     // Stop the RTC Oscillator.
198     //
199     RTC->RTCCTL_b.RSTOP = 1;
200 }
201 
202 //*****************************************************************************
203 //
204 // @brief Configures the RTC for 12 or 24 hour time keeping.
205 //
206 // @param b12Hour - A 'true' configures the RTC for 12 hour time keeping.
207 //
208 // Configures the RTC for 12 (true) or 24 (false) hour time keeping.
209 //
210 //*****************************************************************************
211 void
am_hal_rtc_time_12hour(bool b12Hour)212 am_hal_rtc_time_12hour(bool b12Hour)
213 {
214     //
215     // Set the 12/24 hour bit.
216     //
217     RTC->RTCCTL_b.HR1224 = b12Hour;
218 }
219 
220 //*****************************************************************************
221 //
222 // @brief Enable selected RTC interrupts.
223 //
224 // @param ui32Interrupt - desired interrupts
225 //
226 // Enables the RTC interrupts.
227 //
228 // ui32Interrupt should be the following:
229 //
230 //     AM_HAL_RTC_INT_ALM
231 //
232 //*****************************************************************************
233 void
am_hal_rtc_int_enable(uint32_t ui32Interrupt)234 am_hal_rtc_int_enable(uint32_t ui32Interrupt)
235 {
236     //
237     // Enable the interrupts.
238     //
239     RTC->INTEN |= ui32Interrupt;
240 }
241 
242 //*****************************************************************************
243 //
244 // @brief Return the enabled RTC interrupts.
245 //
246 // Returns the enabled RTC interrupts.
247 //
248 // @return enabled RTC interrupts. Return is 0 or:
249 //
250 //     AM_HAL_RTC_INT_ALM
251 //
252 //*****************************************************************************
253 uint32_t
am_hal_rtc_int_enable_get(void)254 am_hal_rtc_int_enable_get(void)
255 {
256     //
257     // Read the RTC interrupt enable register, and return its contents.
258     //
259     return RTC->INTEN;
260 }
261 
262 //*****************************************************************************
263 //
264 // @brief Disable selected RTC interrupts.
265 //
266 // @param ui32Interrupt - desired interrupts
267 //
268 // Disables the RTC interrupts.
269 //
270 // ui32Interrupt should be the following:
271 //
272 //     AM_HAL_RTC_INT_ALM
273 //
274 //*****************************************************************************
275 void
am_hal_rtc_int_disable(uint32_t ui32Interrupt)276 am_hal_rtc_int_disable(uint32_t ui32Interrupt)
277 {
278     //
279     // Disable the interrupts.
280     //
281     RTC->INTEN &= ~ui32Interrupt;
282 
283 }
284 
285 //*****************************************************************************
286 //
287 // @brief Sets the selected RTC interrupts.
288 //
289 // @param ui32Interrupt - desired interrupts
290 //
291 // Sets the RTC interrupts causing them to immediately trigger.
292 //
293 // ui32Interrupt should be the following:
294 //
295 //     AM_HAL_RTC_INT_ALM
296 //
297 //*****************************************************************************
298 void
am_hal_rtc_int_set(uint32_t ui32Interrupt)299 am_hal_rtc_int_set(uint32_t ui32Interrupt)
300 {
301     //
302     // Set the interrupts.
303     //
304     RTC->INTSET = ui32Interrupt;
305 }
306 
307 //*****************************************************************************
308 //
309 // @brief Clear selected RTC interrupts.
310 //
311 // @param ui32Interrupt - desired interrupts
312 //
313 // Clears the RTC interrupts.
314 //
315 // ui32Interrupt should be the following:
316 //
317 //     AM_HAL_RTC_INT_ALM
318 //
319 //*****************************************************************************
320 void
am_hal_rtc_int_clear(uint32_t ui32Interrupt)321 am_hal_rtc_int_clear(uint32_t ui32Interrupt)
322 {
323     //
324     // Clear the interrupts.
325     //
326     RTC->INTCLR = ui32Interrupt;
327 }
328 
329 //*****************************************************************************
330 //
331 // @brief Returns the RTC interrupt status.
332 //
333 // @param bEnabledOnly - return the status of only the enabled interrupts.
334 //
335 // Returns the RTC interrupt status.
336 //
337 // @return Bitwise representation of the current interrupt status.
338 //
339 // The return value will be 0 or the following:
340 //
341 //     AM_HAL_RTC_INT_ALM
342 //
343 //*****************************************************************************
344 uint32_t
am_hal_rtc_int_status_get(bool bEnabledOnly)345 am_hal_rtc_int_status_get(bool bEnabledOnly)
346 {
347     //
348     // Get the interrupt status.
349     //
350     if ( bEnabledOnly )
351     {
352         uint32_t ui32RetVal;
353         ui32RetVal  = RTC->INTSTAT;
354         ui32RetVal &= RTC->INTEN;
355         return ui32RetVal & (AM_HAL_RTC_INT_ALM);
356     }
357     else
358     {
359         return RTC->INTSTAT & (AM_HAL_RTC_INT_ALM);
360     }
361 }
362 
363 //*****************************************************************************
364 //
365 // @brief Set the Real Time Clock counter registers.
366 //
367 // @param *pTime - A pointer to the time structure.
368 //
369 // Sets the RTC counter registers to the supplied values.
370 //
371 //*****************************************************************************
372 uint32_t
am_hal_rtc_time_set(am_hal_rtc_time_t * pTime)373 am_hal_rtc_time_set(am_hal_rtc_time_t *pTime)
374 {
375     //
376     // Validate the user defined date and time setting
377     //
378 
379     if (!time_input_validate(pTime))
380     {
381         return AM_HAL_STATUS_FAIL;
382     }
383 
384     //
385     // Enable writing to the counters.
386     //
387     RTC->RTCCTL_b.WRTC = RTC_RTCCTL_WRTC_EN;
388 
389     //
390     // Write the RTCLOW register.
391     //
392     RTC->CTRLOW =
393         _VAL2FLD(RTC_CTRLOW_CTRHR,  dec_to_bcd(pTime->ui32Hour))         |
394         _VAL2FLD(RTC_CTRLOW_CTRMIN, dec_to_bcd(pTime->ui32Minute))       |
395         _VAL2FLD(RTC_CTRLOW_CTRSEC, dec_to_bcd(pTime->ui32Second))       |
396         _VAL2FLD(RTC_CTRLOW_CTR100, dec_to_bcd(pTime->ui32Hundredths));
397 
398     //
399     // Write the RTCUP register.
400     //
401     RTC->CTRUP =
402         _VAL2FLD(RTC_CTRUP_CEB,     (pTime->ui32CenturyEnable))          |
403         _VAL2FLD(RTC_CTRUP_CB,      (pTime->ui32Century))                |
404         _VAL2FLD(RTC_CTRUP_CTRWKDY, (pTime->ui32Weekday))                |
405         _VAL2FLD(RTC_CTRUP_CTRYR,   dec_to_bcd((pTime->ui32Year)))       |
406         _VAL2FLD(RTC_CTRUP_CTRMO,   dec_to_bcd((pTime->ui32Month)))      |
407         _VAL2FLD(RTC_CTRUP_CTRDATE, dec_to_bcd((pTime->ui32DayOfMonth)));
408 
409     //
410     // Disable writing to the counters.
411     //
412     RTC->RTCCTL_b.WRTC = RTC_RTCCTL_WRTC_DIS;
413 
414     return AM_HAL_STATUS_SUCCESS;
415 }
416 
417 //*****************************************************************************
418 //
419 // @brief Get the Real Time Clock current time.
420 //
421 // @param *pTime - A pointer to the time structure to store the current time.
422 //
423 // Gets the RTC's current time
424 //
425 // @return 0 for success and 1 for error.
426 //
427 //*****************************************************************************
428 uint32_t
am_hal_rtc_time_get(am_hal_rtc_time_t * pTime)429 am_hal_rtc_time_get(am_hal_rtc_time_t *pTime)
430 {
431     uint32_t ui32RTCLow, ui32RTCUp, ui32Value;
432 
433     //
434     // Read the upper and lower RTC registers.
435     //
436     ui32RTCLow = RTC->CTRLOW;
437     ui32RTCUp  = RTC->CTRUP;
438 
439     //
440     // Break out the lower word.
441     //
442     ui32Value =
443         ((ui32RTCLow & RTC_CTRLOW_CTRHR_Msk) >> RTC_CTRLOW_CTRHR_Pos);
444     pTime->ui32Hour = bcd_to_dec(ui32Value);
445 
446     ui32Value =
447         ((ui32RTCLow & RTC_CTRLOW_CTRMIN_Msk) >> RTC_CTRLOW_CTRMIN_Pos);
448     pTime->ui32Minute = bcd_to_dec(ui32Value);
449 
450     ui32Value =
451         ((ui32RTCLow & RTC_CTRLOW_CTRSEC_Msk) >> RTC_CTRLOW_CTRSEC_Pos);
452     pTime->ui32Second = bcd_to_dec(ui32Value);
453 
454     ui32Value =
455         ((ui32RTCLow & RTC_CTRLOW_CTR100_Msk) >> RTC_CTRLOW_CTR100_Pos);
456     pTime->ui32Hundredths = bcd_to_dec(ui32Value);
457 
458     //
459     // Break out the upper word.
460     //
461     pTime->ui32ReadError =
462         ((ui32RTCUp & RTC_CTRUP_CTERR_Msk) >> RTC_CTRUP_CTERR_Pos);
463 
464     pTime->ui32CenturyEnable =
465         ((ui32RTCUp & RTC_CTRUP_CEB_Msk) >> RTC_CTRUP_CEB_Pos);
466 
467     pTime->ui32Century =
468         ((ui32RTCUp & RTC_CTRUP_CB_Msk) >> RTC_CTRUP_CB_Pos);
469 
470     ui32Value =
471         ((ui32RTCUp & RTC_CTRUP_CTRWKDY_Msk) >> RTC_CTRUP_CTRWKDY_Pos);
472     pTime->ui32Weekday = bcd_to_dec(ui32Value);
473 
474     ui32Value =
475         ((ui32RTCUp & RTC_CTRUP_CTRYR_Msk) >> RTC_CTRUP_CTRYR_Pos);
476     pTime->ui32Year = bcd_to_dec(ui32Value);
477 
478     ui32Value =
479         ((ui32RTCUp & RTC_CTRUP_CTRMO_Msk) >> RTC_CTRUP_CTRMO_Pos);
480     pTime->ui32Month = bcd_to_dec(ui32Value);
481 
482     ui32Value =
483         ((ui32RTCUp & RTC_CTRUP_CTRDATE_Msk) >> RTC_CTRUP_CTRDATE_Pos);
484 
485     pTime->ui32DayOfMonth = bcd_to_dec(ui32Value);
486 
487     //
488     // Was there a read error?
489     //
490     if (pTime->ui32ReadError)
491     {
492         return 1;
493     }
494     else
495     {
496         return 0;
497     }
498 }
499 
500 //*****************************************************************************
501 //
502 // @brief Sets the alarm repeat interval.
503 //
504 // @param ui32RepeatInterval the desired repeat interval.
505 //
506 // Sets the alarm repeat interval.
507 //
508 // Valid values for ui32RepeatInterval:
509 //
510 //     AM_HAL_RTC_ALM_RPT_DIS
511 //     AM_HAL_RTC_ALM_RPT_YR
512 //     AM_HAL_RTC_ALM_RPT_MTH
513 //     AM_HAL_RTC_ALM_RPT_WK
514 //     AM_HAL_RTC_ALM_RPT_DAY
515 //     AM_HAL_RTC_ALM_RPT_HR
516 //     AM_HAL_RTC_ALM_RPT_MIN
517 //     AM_HAL_RTC_ALM_RPT_SEC
518 //     AM_HAL_RTC_ALM_RPT_10TH
519 //     AM_HAL_RTC_ALM_RPT_100TH
520 //
521 //*****************************************************************************
522 void
am_hal_rtc_alarm_interval_set(uint32_t ui32RepeatInterval)523 am_hal_rtc_alarm_interval_set(uint32_t ui32RepeatInterval)
524 {
525     uint32_t ui32RptInt, ui32Alm100, ui32Value;
526 
527     switch(ui32RepeatInterval)
528     {
529         //
530         // If repeat every 10th set RPT and ALM100 field accordinly
531         //
532         case AM_HAL_RTC_ALM_RPT_10TH:
533             ui32RptInt = AM_HAL_RTC_ALM_RPT_SEC;
534             ui32Alm100 = AM_HAL_RTC_ALM100_10TH;
535             break;
536         //
537         // If repeat every 100th set RPT and ALM100 field accordinly
538         //
539         case AM_HAL_RTC_ALM_RPT_100TH:
540             ui32RptInt = AM_HAL_RTC_ALM_RPT_SEC;
541             ui32Alm100 = AM_HAL_RTC_ALM100_100TH;
542             break;
543         //
544         // Otherwise set RPT as value passed.  ALM100 values need to be 0xnn
545         // in this setting where n = 0-9.
546         //
547         default:
548             //
549             // Get the current value of the ALM100 field.
550             //
551             ui32Value = RTC->ALMLOW_b.ALM100;
552 
553             //
554             // If ALM100 was previous EVERY_10TH or EVERY_100TH reset to zero
555             // otherwise keep previous setting.
556             //
557             ui32Alm100 = ui32Value >= 0xF0 ? 0 : ui32Value;
558 
559             //
560             // Set RPT value to value passed.
561             //
562             ui32RptInt = ui32RepeatInterval;
563             break;
564     }
565 
566 
567     //
568     // Write the interval to the register.
569     //
570     RTC->RTCCTL_b.RPT = ui32RptInt;
571 
572     //
573     // Write the Alarm 100 bits in the ALM100 register.
574     //
575     RTC->ALMLOW_b.ALM100 = ui32Alm100;
576 }
577 
578 //*****************************************************************************
579 //
580 // @brief Sets the RTC's Alarm.
581 //
582 // @param *pTime - A pointer to the time structure.
583 // @param ui32RepeatInterval - the desired alarm repeat interval.
584 //
585 // Set the Real Time Clock Alarm Parameters.
586 //
587 // Valid values for ui32RepeatInterval:
588 //
589 //     AM_HAL_RTC_ALM_RPT_DIS
590 //     AM_HAL_RTC_ALM_RPT_YR
591 //     AM_HAL_RTC_ALM_RPT_MTH
592 //     AM_HAL_RTC_ALM_RPT_WK
593 //     AM_HAL_RTC_ALM_RPT_DAY
594 //     AM_HAL_RTC_ALM_RPT_HR
595 //     AM_HAL_RTC_ALM_RPT_MIN
596 //     AM_HAL_RTC_ALM_RPT_SEC
597 //     AM_HAL_RTC_ALM_RPT_10TH
598 //     AM_HAL_RTC_ALM_RPT_EVERY_100TH
599 //
600 //*****************************************************************************
601 void
am_hal_rtc_alarm_set(am_hal_rtc_time_t * pTime,uint32_t ui32RepeatInterval)602 am_hal_rtc_alarm_set(am_hal_rtc_time_t *pTime, uint32_t ui32RepeatInterval)
603 {
604     uint8_t ui8Value = 0;
605 
606     //
607     // Write the interval to the register.
608     //
609     RTC->RTCCTL |= _VAL2FLD(RTC_RTCCTL_RPT, (ui32RepeatInterval > 0x7 ? 0x7 : ui32RepeatInterval));
610 
611     //
612     // Check if the interval is 10th or every 100th and track it in ui8Value.
613     //
614     if (ui32RepeatInterval == AM_HAL_RTC_ALM_RPT_10TH)
615     {
616         ui8Value = 0xF0;
617     }
618     else if (ui32RepeatInterval == AM_HAL_RTC_ALM_RPT_100TH)
619     {
620         ui8Value = 0xFF;
621     }
622 
623     //
624     // Write the ALMUP register.
625     //
626     RTC->ALMUP =
627         _VAL2FLD(RTC_ALMUP_ALMWKDY, (pTime->ui32Weekday))                   |
628         _VAL2FLD(RTC_ALMUP_ALMMO,   dec_to_bcd((pTime->ui32Month)))         |
629         _VAL2FLD(RTC_ALMUP_ALMDATE, dec_to_bcd((pTime->ui32DayOfMonth)));
630 
631     //
632     // Write the ALMLOW register.
633     //
634     RTC->ALMLOW =
635         _VAL2FLD(RTC_ALMLOW_ALMHR,  dec_to_bcd(pTime->ui32Hour))            |
636         _VAL2FLD(RTC_ALMLOW_ALMMIN, dec_to_bcd(pTime->ui32Minute))          |
637         _VAL2FLD(RTC_ALMLOW_ALMSEC, dec_to_bcd(pTime->ui32Second))          |
638         _VAL2FLD(RTC_ALMLOW_ALM100, dec_to_bcd(pTime->ui32Hundredths) | ui8Value);
639 }
640 
641 //*****************************************************************************
642 //
643 // @brief Get the Real Time Clock Alarm Parameters
644 // @note Gets the RTC's Alarm time
645 //
646 // @param *pTime - A pointer to the time structure to store the current alarm.
647 //
648 //*****************************************************************************
649 void
am_hal_rtc_alarm_get(am_hal_rtc_time_t * pTime)650 am_hal_rtc_alarm_get(am_hal_rtc_time_t *pTime)
651 {
652     uint32_t ui32ALMLow, ui32ALMUp, ui32Value;
653 
654     //
655     // Read the upper and lower RTC registers.
656     //
657     ui32ALMLow = RTC->ALMLOW;
658     ui32ALMUp  = RTC->ALMUP;
659 
660     //
661     // Break out the lower word.
662     //
663     ui32Value = ((ui32ALMLow & RTC_ALMLOW_ALMHR_Msk) >> RTC_ALMLOW_ALMHR_Pos);
664     pTime->ui32Hour = bcd_to_dec(ui32Value);
665 
666     ui32Value = ((ui32ALMLow & RTC_ALMLOW_ALMMIN_Msk) >> RTC_ALMLOW_ALMMIN_Pos);
667     pTime->ui32Minute = bcd_to_dec(ui32Value);
668 
669     ui32Value = ((ui32ALMLow & RTC_ALMLOW_ALMSEC_Msk) >> RTC_ALMLOW_ALMSEC_Pos);
670     pTime->ui32Second = bcd_to_dec(ui32Value);
671 
672     ui32Value = ((ui32ALMLow & RTC_ALMLOW_ALM100_Msk) >> RTC_ALMLOW_ALM100_Pos);
673     pTime->ui32Hundredths = bcd_to_dec(ui32Value);
674 
675     //
676     // Break out the upper word.
677     //
678     pTime->ui32ReadError = 0;
679     pTime->ui32CenturyEnable = 0;
680     pTime->ui32Century = 0;
681 
682     ui32Value = ((ui32ALMUp & RTC_ALMUP_ALMWKDY_Msk) >> RTC_ALMUP_ALMWKDY_Pos);
683     pTime->ui32Weekday = bcd_to_dec(ui32Value);
684 
685     pTime->ui32Year = 0;
686 
687     ui32Value = ((ui32ALMUp & RTC_ALMUP_ALMMO_Msk) >> RTC_ALMUP_ALMMO_Pos);
688     pTime->ui32Month = bcd_to_dec(ui32Value);
689 
690     ui32Value = ((ui32ALMUp & RTC_ALMUP_ALMDATE_Msk) >> RTC_ALMUP_ALMDATE_Pos);
691     pTime->ui32DayOfMonth = bcd_to_dec(ui32Value);
692 }
693 
694 //*****************************************************************************
695 //
696 // End Doxygen group.
697 //! @}
698 //
699 //*****************************************************************************
700