1 /*******************************************************************************
2  * Copyright 2019-2020 Microchip FPGA Embedded Systems Solutions.
3  *
4  * SPDX-License-Identifier: MIT
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to
8  * deal in the Software without restriction, including without limitation the
9  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10  * sell copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22  * IN THE SOFTWARE.
23  *
24  * PolarFire SoC Microprocessor subsystem RTC bare metal software driver public
25  * APIs.
26  */
27 
28 /*=========================================================================*//**
29   @mainpage PolarFire MSS RTC Bare Metal Driver.
30 
31   ==============================================================================
32   Introduction
33   ==============================================================================
34   The PolarFire SoC Microprocessor Subsystem (MSS) includes a real time counter
35   (RTC) that can generate alarms and wake-up functions in real time. The RTC core
36   also provides the feature of real time clock. This software driver provides a
37   set of functions for controlling the MSS RTC as part of a bare metal system
38   where no operating system is available. The driver can be adapted for use as
39   part of an operating system, but the implementation of the adaptation layer
40   between the driver and the operating system's driver model is outside the
41   scope of the driver.
42 
43   The MSS RTC driver provides support for the following features:
44     - Initialization of the RTC
45     - Configuration of the RTC time-base
46     - Configuration as a calendar or binary mode counter
47     - Set the current calendar or binary mode count
48     - Get the current calendar or binary mode count
49     - Start and stop the RTC counting
50     - Set alarm conditions
51     - Enable, disable and clear the wake-up interrupt
52 
53   ==============================================================================
54   Hardware Flow Dependencies
55   ==============================================================================
56   The configuration of all features of the MSS RTC driver is covered by this
57   driver except for the clock source driving the MSS RTC clock(RTCCLK) input.
58   The PolarFire SoC MSS clock controller supplies single clock source of 1 MHz
59   to the MSS RTC clock input.
60   On PolarFire SoC an AXI switch forms a bus matrix interconnect among multiple
61   masters and multiple slaves. Five RISC-V CPUs connect to the Master ports M10
62   to M14 of the AXI switch. By default, all the APB peripherals are accessible
63   on AXI-Slave 5 of the AXI switch via the AXI to AHB and AHB to APB bridges
64   (referred as main APB bus). However, to support logical separation in the
65   Asymmetric Multi-Processing (AMP) mode of operation, the APB peripherals can
66   alternatively be accessed on the AXI-Slave 6 via the AXI to AHB and AHB to
67   APB bridges (referred as the AMP APB bus).
68   Application must make sure that the RTC is appropriately configured on one of
69   the APB bus described above by configuring the PolarFire SoC system registers
70   (SYSREG) as per the application need and that the appropriate data structures
71   are provided to this driver as parameter to the functions provided by this
72   driver.
73   The base address and register addresses and interrupt number assignment for
74   the MSS RTC block are defined as constants in the PolarFire SoC MPFS HAL. You
75   must ensure that the latest PolarFire SoC MPFS HAL is included in the project
76   settings of the software tool chain used to build your project and that it is
77   generated into your project.
78 
79   ==============================================================================
80   Theory of Operation
81   ==============================================================================
82   The MSS RTC driver functions are grouped into the following categories:
83     - Initialization of the RTC driver and hardware
84     - Setting and reading the RTC counter current value
85     - Setting RTC alarm values
86     - Starting and stopping the RTC
87     - Interrupt Control
88 
89   --------------------------------
90   Initialization of the RTC driver and hardware
91   --------------------------------
92   The MSS RTC driver is initialized through a call to the MSS_RTC_init()
93   function. The MSS_RTC_init() function must be called before any other MSS RTC
94   driver functions are called.
95   The MSS_RTC_init() function:
96     •   Stops the RTC counters and disables the RTC alarm
97     •   Disables the RTC wake-up interrupt in the RTC and in the Platform Level
98         Interrupt Controller (PLIC).
99     •   Clears any pending RTC wake-up interrupt in the RTC and in the Platform
100         Level Interrupt Controller (PLIC).
101     •   Enables the RTC_WAKEUP_CR[0] mask bit in the MSS System Register to
102         connect the RTC wake-up interrupt to the Platform Level Interrupt
103         Controller.
104     •   Resets the RTC counters, alarm and the compare registers
105     •   Sets the RTC's operating mode to binary counter mode or calendar
106         counter mode, as specified by the mode parameter
107     •   Sets the RTC's prescaler register to the value specified by the
108         prescaler parameter. The frequency of the clock source driving the MSS
109         RTC clock (RTCCLK) input is required to calculate the prescaler value.
110 
111   --------------------------------------------
112   Setting and Reading the RTC Counter Value
113   --------------------------------------------
114   The MSS RTC supports two mode of operation – binary mode and calendar mode.
115   The following functions are used to set and read the current value of the
116   counter when the MSS RTC is configured to operate in binary mode:
117     •   MSS_RTC_set_binary_count() – This function is used to set the current
118                                      value of the RTC binary counter.
119     •   MSS_RTC_get_binary_count() – This function is used to read the current
120                                       value of the RTC binary counter.
121 
122   The following functions are used to set and read the current value of the
123   counter the MSS RTC is configured to operate in calendar mode:
124     •   MSS_RTC_set_calendar_count() – This function is used to set the current
125                                        value of the RTC calendar counter.
126     •   MSS_RTC_get_calendar_count() – This function is used to read the current
127                                        value of the RTC calendar counter.
128 
129   The following functions resets the RTC counter in either binary or calendar
130   operating mode:
131     •   MSS_RTC_reset_counter() – This function resets the RTC counter.
132 
133 
134   --------------------------------------------
135   Setting RTC Alarms
136   --------------------------------------------
137   The MSS RTC can generate alarms when the counter matches a specified count
138   value in binary mode or a date and time in calendar mode.
139   The following functions are used to set up alarms:
140     •   MSS_RTC_set_binary_count_alarm() – This function sets up one-shot or
141                                            periodic alarms when the MSS RTC is
142                                            configured to operate in binary mode.
143     •   MSS_RTC_set_calendar_count_alarm() – This function sets up one-shot or
144                                              periodic alarms when the MSS RTC is
145                                              configured to operate in calendar
146                                              mode.
147   Note: The alarm asserts a wake-up interrupt to the RISC-V Core. This function
148   enables the RTC’s wake-up interrupt output, however the RTC wake-up interrupt
149   input to the RISC-V PLIC must be enabled separately by calling the
150   MSS_RTC_enable_irq() function. The alarm can be disabled at any time by
151   calling the MSS_RTC_disable_irq() function.
152 
153   --------------------------------------------
154   Starting and Stopping the RTC Counter
155   --------------------------------------------
156   The following functions start and stop the RTC counter:
157     - MSS_RTC_start() – This function starts the RTC counter.
158     - MSS_RTC_stop() – This function stops the RTC counter.
159 
160   -------------------------------------------
161   Interrupt Control
162   -------------------------------------------
163   The MSS_RTC_enable_irq () function enables the RTC_WAKEUP_CR[0] mask bit in
164   the MSS System Register to connect the RTC wake-up interrupt to the Platform
165   Level Interrupt Controller.
166   An rtc_wakeup_plic_IRQHandler () default implementation is defined, with weak
167   linkage, in the PolarFire SoC MPFS HAL. You must provide your own
168   implementation of the rtc_wakeup_plic_IRQHandler () function, which will
169   override the default implementation, to suit your application.
170   The function prototype for the RTC wake-up interrupt handler is as follows:
171       uint8_t  rtc_wakeup_plic_IRQHandler(void);
172 
173   The RTC wake-up interrupt is controlled using the following functions:
174     •   MSS_RTC_enable_irq() – The MSS_RTC_enable_irq() function enables the RTC
175                                 to interrupt the MSS when a wake-up alarm occurs.
176     •   MSS_RTC_disable_irq() – The MSS_RTC_disable_irq() function disables the
177                                 RTC from interrupting the MSS when a wake-up
178                                 alarm occurs.
179     •   MSS_RTC_clear_irq() – The MSS_RTC_clear_irq() function clears a pending
180                               RTC wake-up interrupt at the RTC wake-up output.
181                               You must call the MSS_RTC_clear_irq() function as
182                               part of your implementation of the
183                               rtc_wakeup_plic_IRQHandler() interrupt service
184                               routine (ISR) in order to prevent the same
185                               interrupt event retriggering a call to the ISR.
186 
187 *//*=========================================================================*/
188 #ifndef MSS_RTC_H_
189 #define MSS_RTC_H_
190 
191 #include "mss_rtc_regs.h"
192 
193 #ifdef __cplusplus
194 extern "C" {
195 #endif
196 
197 /*-------------------------------------------------------------------------*//**
198   The MSS_RTC_BINARY_MODE constant is used to specify the mode parameter to the
199   MSS_RTC_init() function. The RTC will run in binary mode if this constant is
200   used. In binary mode, the calendar counter counts consecutively from 0 all the
201   way to 2^43.
202  */
203 #define MSS_RTC_BINARY_MODE               0u
204 
205 /*-------------------------------------------------------------------------*//**
206   The MSS_RTC_CALENDAR_MODE constant is used to specify the mode parameter to
207   the MSS_RTC_init() function. The RTC will run in calendar mode if this
208   constant is used. In calendar mode, the calendar counter counts seconds,
209   minutes, hours, days, months, years, weekdays and weeks.
210  */
211 #define MSS_RTC_CALENDAR_MODE             1u
212 
213 /*-------------------------------------------------------------------------*//**
214   The alarm_value parameter of the MSS_RTC_set_calendar_count_alarm() function
215   is a pointer to an mss_rtc_calender_t data structure specifying the date and
216   time at which the alarm is to occur. You must assign the required date and
217   time values to the mss_rtc_calender_t structure before calling the function.
218   Any of the fields of the mss_rtc_calender_t structure can be set to
219   MSS_RTC_CALENDAR_DONT_CARE, to indicate that they are not to be considered in
220   deciding when the alarm will occur; this is necessary when setting periodic
221   alarms.
222  */
223 #define MSS_RTC_CALENDAR_DONT_CARE      0xFFu
224 
225 /*-------------------------------------------------------------------------*//**
226   Days of the week.
227  */
228 #define MSS_RTC_SUNDAY      1u
229 #define MSS_RTC_MONDAY      2u
230 #define MSS_RTC_TUESDAY     3u
231 #define MSS_RTC_WEDNESDAY   4u
232 #define MSS_RTC_THRUSDAY    5u
233 #define MSS_RTC_FRIDAY      6u
234 #define MSS_RTC_SATURDAY    7u
235 
236 /***************************************************************************//**
237   MSS RTC base addresses.
238   These definitions provides access to the MSS RTC mapped at two different
239   memory regions. User can provide one of these constants to the MSS_RTC_init()
240   function for configuring the MSS RTC block.
241  */
242 #define MSS_RTC_LO_BASE                 (RTC_TypeDef *)MSS_RTC_LO_ADDR
243 #define MSS_RTC_HI_BASE                 (RTC_TypeDef *)MSS_RTC_HI_ADDR
244 
245 /*-------------------------------------------------------------------------*//**
246   The mss_rtc_alarm_type_t enumeration is used as the alarm_type parameter for
247   the MSS_RTC_set_calendar_count_alarm() and MSS_RTC_set_binary_count_alarm()
248   functions to specify whether the requested alarm should occur only one time or
249   periodically.
250  */
251 typedef enum {
252     MSS_RTC_SINGLE_SHOT_ALARM,
253     MSS_RTC_PERIODIC_ALARM
254 } mss_rtc_alarm_type_t;
255 
256 /*-------------------------------------------------------------------------*//**
257   A pointer to an instance of the mss_rtc_calender_t data structure is used to
258   write new date and time values to the RTC using the
259   MSS_RTC_set_rtc_calendar_count() and MSS_RTC_set_calendar_count_alarm()
260   functions. The MSS_RTC_get_calendar_count() function also uses a pointer to an
261   instance of the mss_rtc_calender_t data structure to read the current date and
262   time value from the RTC.
263  */
264 typedef struct mss_rtc_calender
265 {
266     uint8_t second;
267     uint8_t minute;
268     uint8_t hour;
269     uint8_t day;
270     uint8_t month;
271     uint8_t year;
272     uint8_t weekday;
273     uint8_t week;
274 } mss_rtc_calender_t ;
275 
276 /*-------------------------------------------------------------------------*//**
277   The MSS_RTC_init() function initializes the RTC driver and hardware to a known
278   state. To initialize the RTC hardware, this function:
279     •   Stops the RTC counters and disables the RTC alarm
280     •   Disables the RTC wakeup interrupt in the RTC and in the PolarFire SoC
281         MSS Platform Level Interrupt Controller (PLIC).
282     •   Clears any pending RTC wakeup interrupt in the RTC and in the PolarFire
283         SoC MSS Platform Level Interrupt Controller (PLIC).
284     •   Resets the RTC counters and the alarm and compare registers
285     •   Sets the RTC's operating mode to binary counter mode or calendar counter
286         mode, as specified by the mode parameter
287     •   Sets the RTC's prescaler register to the value specified by the
288         prescaler parameter
289     •   The MSS clock controller can supply one of three clock sources to the
290         RTC clock input (RTCCLK):
291         -   Crystal Oscillator 32.768 kHz
292         -   1MHz Oscillator
293         -   50MHz Oscillator.  (25 MHz in a 1.0v part).
294 
295   For calendar mode, program the prescaler register to generate a 1Hz signal
296   from the active RTCCLK according to the following equation:
297         prescaler = RTCCLK – 1  (where RTCCLK unit is Hz)
298   For a 32.768 kHz clock, set the prescaler to 32768 - 1 = 32767.
299   The prescaler register is 26 bits wide, allowing clock sources of up to 67 MHz
300   to generate the 1Hz time base.
301 
302   For binary mode, the prescaler register can be programmed to generate a 1Hz
303   time base or a different time base, as required.
304 
305   @param base_address
306     The base address parameter provides the base address of the MSS RTC
307     peripheral. The MSS RTC can appear on either the AXI slave 5 or slave 6 per
308     SYSREG configurations. The corresponding base address of this peripheral
309     must be provided per your configuration.
310 
311   @param mode
312     The mode parameter is used to specify the operating mode of the RTC. The
313     allowed values for mode are:
314       - MSS_RTC_BINARY_MODE
315       - MSS_RTC_CALENDAR_MODE
316 
317   @param prescaler
318     The prescaler parameter specifies the value to divide the incoming RTC clock
319     by, to generate the RTC time base signal. For calendar mode, set the
320     prescaler value to generate a 1Hz time base from the incoming RTC clock
321     according to the following equation:
322         prescaler = RTCCLK – 1    (where the RTCCLK unit is Hz)
323     For binary mode, set the prescaler value to generate a 1Hz time base or a
324     different time base, as required.
325     The prescaler parameter can be any integer value in the range 2 to 2^26.
326 
327   @return
328     This function does not return any value.
329 
330   Example:
331   The example code below shows how the RTC can be initialized only after a
332   power-on reset.
333   @code
334     #define PO_RESET_DETECT_MASK    0x00000001u
335 
336     void e51(void)
337     {
338         uint32_t power_on_reset;
339         power_on_reset = SYSREG->RESET_SOURCE_CR & PO_RESET_DETECT_MASK;
340         if(power_on_reset)
341         {
342             MSS_RTC_init(MSS_RTC_LO_BASE, MSS_RTC_BINARY_MODE,
343                          RTC_PERIPH_PRESCALER/ 10u );
344             SYSREG->RESET_SOURCE_CR = PO_RESET_DETECT_MASK;
345         }
346     }
347 
348   @endcode
349  */
350 void
351 MSS_RTC_init
352 (
353     RTC_TypeDef *base_address,
354     uint8_t mode,
355     uint32_t prescaler
356 );
357 
358 /*-------------------------------------------------------------------------*//**
359   The MSS_RTC_set_binary_count() function sets the current value of the RTC
360   binary counter.
361   Note: This function must only be used when the RTC is configured to operate in
362         binary counter mode.
363 
364   @param new_rtc_value
365     The new_rtc_value parameter specifies the new count value from which the RTC
366     will increment. The binary counter is 43 bits wide, so the maximum allowed
367     binary value is 2^43.
368 
369   @return
370     This function does not return a value.
371  */
372 
373 void
374 MSS_RTC_set_binary_count
375 (
376     uint64_t new_rtc_value
377 );
378 
379 /*-------------------------------------------------------------------------*//**
380   The MSS_RTC_set_rtc_calendar_count() function sets the current value of the
381   RTC calendar counter.
382   Note: This function must only be used when the RTC is configured to operate in
383         calendar counter mode.
384 
385   @param new_rtc_value
386     The new_rtc_value parameter is a pointer to an mss_rtc_calender_t data
387     structure specifying the new date and time value from which the RTC will
388     increment. You must populate the mss_rtc_calender_t structure with the
389     required date and time values before calling this function.
390 
391   @return
392     This function does not return a value.
393  */
394 
395 void
396 MSS_RTC_set_calendar_count
397 (
398     const mss_rtc_calender_t *new_rtc_value
399 );
400 
401 /*-------------------------------------------------------------------------*//**
402   The MSS_RTC_get_calendar_count() function returns the current value of the RTC
403   calendar counter via the data structure pointed to by the p_rtc_calendar
404   parameter.
405   Note: This function must only be used when the RTC is configured to operate in
406         calendar counter mode.
407 
408   @param p_rtc_calendar
409     The p_rtc_calendar parameter is a pointer to an mss_rtc_calender_t data
410     structure where the current value of the calendar counter will be written by
411     the MSS_RTC_get_calendar_count() function
412 
413   @return
414     This function does not return a value.
415  */
416 void
417 MSS_RTC_get_calendar_count
418 (
419     mss_rtc_calender_t *p_rtc_calendar
420 );
421 
422 /*-------------------------------------------------------------------------*//**
423   The MSS_RTC_get_binary_count() function returns the current value of the RTC
424   binary counter.
425   Note: This function must only be used when the RTC is configured to operate in
426         binary counter mode.
427 
428   @param
429     This function takes no parameters.
430 
431   @return
432     This function returns the current value of the RTC binary counter as an
433     unsigned 64-bit integer.
434  */
435 uint64_t
436 MSS_RTC_get_binary_count
437 (
438     void
439 );
440 
441 /*-------------------------------------------------------------------------*//**
442   The MSS_RTC_start() function starts the RTC incrementing.
443 
444   @param
445     This function takes no parameters.
446 
447   @return
448     This function does not return a value.
449  */
450 void
451 MSS_RTC_start
452 (
453     void
454 );
455 
456 /*-------------------------------------------------------------------------*//**
457   The MSS_RTC_stop() function stops the RTC from incrementing.
458 
459   @param
460     This function takes no parameters.
461 
462   @return
463     This function does not return a value.
464  */
465 void
466 MSS_RTC_stop
467 (
468     void
469 );
470 
471 /*-------------------------------------------------------------------------*//**
472   The MSS_RTC_reset_counter() function resets the RTC counters. If the counter
473   was running before calling this function, then it continues incrementing from
474   the counter’s reset value.
475 
476   @param
477     This function takes no parameters.
478 
479   @return
480     This function does not return a value.
481  */
482 void
483 MSS_RTC_reset_counter
484 (
485     void
486 );
487 
488 /*-------------------------------------------------------------------------*//**
489   The MSS_RTC_enable_irq() function enables the RTC wakeup output to interrupt
490   the MSS when an alarm occurs. It enables the RTC wakeup interrupt
491   (RTC_Wakeup_IRQn) in the PoalrFire SoC PLIC. The rtc_wakeup_plic_IRQHandler()
492   function will be called when an RTC wakeup interrupt occurs.
493 
494   Note: The rtc_wakeup_plic_IRQHandler() default implementation is defined,
495   with weak linkage, in the PoalrFire SoC MPFS HAL. You must provide your own
496   implementation of the rtc_wakeup_plic_IRQHandler() function, which will
497   override the default implementation, to suit your application.
498 
499   Note: This function only enables the RTC wakeup interrupt at the PolarFire SoC
500   PLIC level. The alarm setting functions enable the wakeup interrupt output
501   from the RTC.
502 
503    @param
504      This function takes no parameters.
505 
506    @return
507      This function does not return a value.
508  */
509 void
510 MSS_RTC_enable_irq
511 (
512     void
513 );
514 
515 /*-------------------------------------------------------------------------*//**
516   The MSS_RTC_disable_irq() function disables the RTC wakeup interrupt
517   (RTC_WAKEUP_PLIC)in the PolarFire SoC MSS PLIC.
518   Note: This function only disables the RTC wakeup interrupt at the PolarFire
519   SoC PLIC level. It does not disable the wakeup interrupt output from the RTC.
520 
521    @param
522      This function takes no parameters.
523 
524    @return
525      This function does not return a value.
526  */
527 void
528 MSS_RTC_disable_irq
529 (
530     void
531 );
532 
533 /*-------------------------------------------------------------------------*//**
534   The MSS_RTC_clear_irq() function clears a pending wakeup interrupt from the
535   RTC. This function does not clear the interrupt in the PolarFire SoC PLIC; it
536   only clears the wakeup output from the RTC.
537   Note: You must call the MSS_RTC_clear_irq() function as part of your
538   implementation of the rtc_wakeup_plic_IRQHandler() RTC wakeup interrupt
539   service routine (ISR) in order to prevent the same interrupt event
540   retriggering a call to the ISR.
541 
542   @param
543     This function takes no parameters.
544 
545   @return
546     This function does not return a value.
547 
548   Example:
549   The example code below demonstrates how the MSS_RTC_clear_irq() function is
550   intended to be used as part of the RTC wakeup interrupt service routine used
551   by an application to handle RTC alarms.
552   @code
553     #if defined(__GNUC__)
554     __attribute__((__interrupt__)) void rtc_wakeup_plic_IRQHandler( void )
555     #else
556     void rtc_wakeup_plic_IRQHandler( void )
557     #endif
558     {
559         process_alarm();
560         MSS_RTC_clear_irq();
561     }
562   @endcode
563 */
564 void
565 MSS_RTC_clear_irq
566 (
567     void
568 );
569 
570 /*-------------------------------------------------------------------------*//**
571   The MSS_RTC_set_calendar_count_alarm() function sets up the RTC to generate an
572   alarm when the RTC count reaches the time/date specified by the alarm_value
573   parameter. The alarm asserts a wakeup interrupt to the MSS. This function
574   enables the RTC’s wakeup interrupt output, however the RTC wakeup interrupt
575   input to the PolarFire SoC PLIC must be enabled separately by calling the
576   MSS_RTC_enable_irq() function. The alarm can be disabled at any time by
577   calling the MSS_RTC_disable_irq() function.
578 
579   Single-shot alarm
580   The alarm can be a single-shot alarm, which will generate a single wakeup
581   interrupt the first time the RTC count reaches the time/date specified by
582   alarm_value. A single shot alarm is achieved by specifying a value for every
583   field of the mss_rtc_calender_t data structure pointed to by the alarm_value
584   parameter. The RTC counter will keep incrementing after a single shot alarm
585   occurs.
586 
587   Periodic alarm
588   The alarm can also be a periodic alarm, which will generate a wakeup interrupt
589   every time the RTC count reaches the time/date specified by alarm_value, with
590   the counter running in a continuous loop. The periodic alarm can be set to
591   occur every minute, hour, day, month, year, week, day of the week, or any
592   valid combination of these. This is achieved by setting some of the fields of
593   the mss_rtc_calender_t data structure pointed to by the alarm_value parameter,
594   to MSS_RTC_CALENDAR_DONT_CARE. For example, setting the weekday field to
595   MSS_RTC_MONDAY and all other fields to MSS_RTC_CALENDAR_DONT_CARE will result
596   in an alarm occurring every Monday. You can refine the time at which the alarm
597   will occur by specifying values for the hour, minute and second fields.
598 
599   Note: This function must only be used when the RTC is configured to operate
600         in calendar counter mode.
601 
602 
603   @param alarm_value
604     The alarm_value parameter is a pointer to an mss_rtc_calender_t data
605     structure specifying the date and time at which the alarm is to occur. You
606     must assign the required date and time values to the mss_rtc_calender_t
607     structure before calling this function. Some of the fields within the
608     mss_rtc_calender_t structure can be set to MSS_RTC_CALENDAR_DONT_CARE, to
609     indicate that they are not to be considered in deciding when the alarm will
610     occur; this is necessary when setting periodic alarms.
611 
612   @return
613     This function does not return a value.
614 
615   Examples:
616 
617   The following example code demonstrates how to configure the RTC to generate a
618   single calendar alarm at a specific date and time. The alarm will only occur
619   once and the RTC will keep incrementing regardless of the alarm taking place.
620 
621   @code
622     const mss_rtc_calender_t initial_calendar_count =
623     {
624         15u,     second
625         30u,     minute
626         6u,      hour
627         6u,      day
628         9u,      month
629         12u,     year
630         5u,      weekday
631         37u      week
632     };
633 
634     mss_rtc_calender_t alarm_calendar_count =
635     {
636         17u,     second
637         30u,     minute
638         6u,      hour
639         6u,      day
640         9u,      month
641         12u,     year
642         5u,      weekday
643         37u      week
644     };
645 
646     MSS_RTC_init(MSS_RTC_LO_BASE, MSS_RTC_BINARY_MODE, RTC_PERIPH_PRESCALER/ 10u);
647     MSS_RTC_clear_irq();
648     MSS_RTC_set_calendar_count(&initial_calendar_count);
649     MSS_RTC_enable_irq();
650     MSS_RTC_start();
651 
652     MSS_RTC_set_calendar_count_alarm(&alarm_calendar_count);
653   @endcode
654 
655   The following example code demonstrates how to configure the RTC to generate a
656   periodic calendar alarm. The RTC is configured to generate an alarm every
657   Tuesday at 16:45:00. The alarm will reoccur every week until the RTC wakeup
658   interrupt is disabled using a call to MSS_RTC_disable_irq().
659 
660   @code
661     mss_rtc_calender_t initial_calendar_count =
662     {
663         58u,                            <--second
664         59u,                            <--minute
665         23u,                            <--hour
666         10u,                            <--day
667         9u,                             <--month
668         12u,                            <--year
669         MSS_RTC_MONDAY,                 <--weekday
670         37u                             <--week
671     };
672 
673     mss_rtc_calender_t alarm_calendar_count =
674     {
675         MSS_RTC_CALENDAR_DONT_CARE,     <--second
676         45u,                            <--minute
677         16u,                            <--hour
678         MSS_RTC_CALENDAR_DONT_CARE,     <--day
679         MSS_RTC_CALENDAR_DONT_CARE,     <--month
680         MSS_RTC_CALENDAR_DONT_CARE,     <--year
681         MSS_RTC_TUESDAY,                <--weekday
682         MSS_RTC_CALENDAR_DONT_CARE      <--week
683     };
684 
685     MSS_RTC_init(MSS_RTC_LO_BASE, MSS_RTC_BINARY_MODE, RTC_PERIPH_PRESCALER/ 10u);
686     MSS_RTC_set_calendar_count(&initial_calendar_count);
687     MSS_RTC_enable_irq();
688     MSS_RTC_start();
689 
690     MSS_RTC_set_calendar_count_alarm(&alarm_calendar_count);
691   @endcode
692 
693   The following example code demonstrates the code that you need to include in
694   your application to handle alarms. It is the interrupt service routine for the
695   RTC wakeup interrupt input to the PolarFire SoC PLIC. You need to add your
696   application code in this function in place of the process_alarm() function but
697   you must retain the call to MSS_RTC_clear_irq() to ensure that the same alarm
698   does not retrigger the interrupt.
699 
700   @code
701     #if defined(__GNUC__)
702     __attribute__((__interrupt__)) void rtc_wakeup_plic_IRQHandler( void )
703     #else
704     void rtc_wakeup_plic_IRQHandler( void )
705     #endif
706     {
707         process_alarm();
708         MSS_RTC_clear_irq();
709     }
710   @endcode
711  */
712 void
713 MSS_RTC_set_calendar_count_alarm
714 (
715     const mss_rtc_calender_t * alarm_value
716 );
717 
718 /*-------------------------------------------------------------------------*//**
719   The MSS_RTC_set_binary_count_alarm() function sets up the RTC to generate an
720   alarm when the RTC count reaches the value specified by the alarm_value
721   parameter. The alarm asserts a wakeup interrupt to the MSS. This function
722   enables the RTC’s wakeup interrupt output, however the RTC wakeup interrupt
723   input to the PolarFire SoC PLIC must be enabled separately by calling the
724   MSS_RTC_enable_irq() function. The alarm can be disabled at any time by
725   calling the MSS_RTC_disable_irq() function.
726 
727   Single-shot alarm
728   The alarm can be a single-shot alarm, which will generate a single wakeup
729   interrupt the first time the RTC count reaches the value specified by the
730   alarm_value parameter. Setting the alarm_value parameter to
731   MSS_RTC_PERIODIC_ALARM produces a single-shot alarm. The RTC counter continues
732   incrementing when a single shot alarm occurs.
733 
734   Periodic alarm
735   The alarm can also be a periodic alarm, which will generate a wakeup interrupt
736   every time the RTC count reaches the value specified by the alarm_value
737   parameter. Setting the alarm_value parameter to MSS_RTC_SINGLE_SHOT_ALARM
738   produces a periodic alarm. The RTC counter automatically wraps around to zero
739   and continues incrementing when a periodic alarm occurs.
740 
741   Note: This function must only be used when the RTC is configured to operate
742         in binary counter mode.
743 
744   @param alarm_value
745     The alarm_value parameter is a 64-bit unsigned value specifying the RTC
746     counter value that must be reached for the requested alarm to occur.
747 
748   @param alarm_type
749     The alarm_type parameter specifies whether the requested alarm is a single
750     shot or periodic alarm. It can only take one of these two values:
751      - MSS_RTC_SINGLE_SHOT_ALARM,
752      - MSS_RTC_PERIODIC_ALARM
753 
754   @return
755     This function does not return a value.
756  */
757 void
758 MSS_RTC_set_binary_count_alarm
759 (
760     uint64_t alarm_value,
761     mss_rtc_alarm_type_t alarm_type
762 );
763 
764 /*-------------------------------------------------------------------------*//**
765   The MSS_RTC_get_update_flag() function indicates if the RTC counter has
766   incremented since the last call to MSS_RTC_clear_update_flag(). It returns
767   zero if no RTC counter increment has occurred. It returns a non-zero value if
768   the RTC counter has incremented. This function can be used whether the RTC is
769   configured to operate in calendar or binary counter mode.
770 
771   @return
772    This function returns,
773 
774    |Value    |  Description                                              |
775    |---------|-----------------------------------------------------------|
776    |zero:    |  if the RTC has not incremented since the last call to    |
777    |         |  MSS_RTC_clear_update_flag(),                             |
778    |---------|-----------------------------------------------------------|
779    |non-zero:|  if the RTC has incremented since the last call to        |
780    |         |  MSS_RTC_clear_update_flag().                             |
781 
782   Example
783   This example waits for the RTC timer to increment by one second.
784   @code
785     void wait_start_of_second(void)
786     {
787         uint32_t rtc_count_updated;
788         MSS_RTC_clear_update_flag();
789         do {
790             rtc_count_updated = MSS_RTC_get_update_flag();
791         } while(!rtc_count_updated)
792     }
793   @endcode
794  */
795 uint32_t
796 MSS_RTC_get_update_flag
797 (
798     void
799 );
800 
801 /*-------------------------------------------------------------------------*//**
802   The MSS_RTC_clear_update_flag() function clears the CONTROL register flag that
803   is set when the RTC counter increments. It is used alongside function
804   MSS_RTC_get_update_flag() to detect RTC counter increments.
805 
806   @return
807     This function does not return a value.
808 
809   Example
810   The example below will wait for the RTC timer to increment by one second.
811   @code
812   void wait_start_of_second(void)
813   {
814       uint32_t rtc_count_updated;
815       MSS_RTC_clear_update_flag();
816       do {
817           rtc_count_updated = MSS_RTC_get_update_flag();
818       } while(!rtc_count_updated)
819   }
820   @endcode
821  */
822 void
823 MSS_RTC_clear_update_flag
824 (
825     void
826 );
827 
828 #ifdef __cplusplus
829 }
830 #endif
831 
832 #endif /* MSS_RTC_H_ */
833