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