source: rtems/bsps/arm/atsam/start/power-rtc.c @ ba619b7f

Last change on this file since ba619b7f was ba619b7f, checked in by Joel Sherrill <joel@…>, on 03/01/22 at 21:38:20

bsps/arm/: Scripted embedded brains header file clean up

Updates #4625.

  • Property mode set to 100644
File size: 2.5 KB
Line 
1/*
2 * Copyright (c) 2016 embedded brains GmbH.  All rights reserved.
3 *
4 * The license and distribution terms for this file may be
5 * found in the file LICENSE in this distribution or at
6 * http://www.rtems.org/license/LICENSE.
7 */
8
9#include <bsp.h>
10#include <bsp/power.h>
11#include <bsp/irq.h>
12
13#include <libchip/chip.h>
14
15#define ATSAM_ENABLE_ALARM_INTERRUPT RTC_IER_ALREN
16
17static void set_rtc_alarm_interrupt(uint32_t interval)
18{
19        Rtc *rtc = RTC;
20        uint8_t hour;
21        uint8_t minute;
22        uint8_t second;
23        uint32_t time;
24
25        /* Clear current status register */
26        RTC_ClearSCCR(rtc, 0x3F);
27
28        RTC_GetTime(rtc, &hour, &minute, &second);
29
30        time = UINT32_C(3600) * hour + UINT32_C(60) * minute + second;
31        time = (time + interval) % (UINT32_C(24) * 3600);
32
33        second = (uint8_t) (time % 60);
34        minute = (uint8_t) ((time / 60) % 60);
35        hour = (uint8_t) (time / 3600);
36
37        if (interval < 60) {
38                RTC_SetTimeAlarm(rtc, NULL, NULL, &second);
39        } else if (interval < 3600) {
40                RTC_SetTimeAlarm(rtc, NULL, &minute, &second);
41        } else {
42                RTC_SetTimeAlarm(rtc, &hour, &minute, &second);
43        }
44
45        RTC_EnableIt(rtc, ATSAM_ENABLE_ALARM_INTERRUPT);
46}
47
48static void rtc_interrupt_handler(void *arg)
49{
50        atsam_power_data_rtc_driver *rtc_data;
51
52        rtc_data = (atsam_power_data_rtc_driver *)arg;
53        set_rtc_alarm_interrupt(rtc_data->interval);
54}
55
56static void rtc_alarm_handler(void *arg)
57{
58        Rtc *rtc = RTC;
59        rtems_status_code sc;
60
61        /* Clear current status register */
62        RTC_ClearSCCR(rtc, 0x3F);
63
64        /* Switch off all RTC interrupts */
65        RTC_DisableIt(rtc, 0x1F);
66
67        /* Install RTC interrupt handler */
68        sc = rtems_interrupt_handler_install(RTC_IRQn,
69            "RTC",
70            RTEMS_INTERRUPT_UNIQUE,
71            rtc_interrupt_handler,
72            arg
73        );
74        assert(sc == RTEMS_SUCCESSFUL);
75}
76
77static void set_time(void)
78{
79        rtems_time_of_day tod;
80        rtems_status_code sc;
81
82        atsam_rtc_get_time(&tod);
83        sc = rtems_clock_set(&tod);
84        assert(sc == RTEMS_SUCCESSFUL);
85}
86
87void atsam_power_handler_rtc_driver(
88    const atsam_power_control *control,
89    atsam_power_state state
90)
91{
92        atsam_power_data_rtc_driver *rtc_data;
93        rtems_interrupt_level level;
94        Rtc *rtc = RTC;
95
96        rtc_data = (atsam_power_data_rtc_driver *)control->data.arg;
97
98        switch (state) {
99                case ATSAM_POWER_ON:
100                        RTC_DisableIt(rtc, ATSAM_ENABLE_ALARM_INTERRUPT);
101                        set_time();
102                        break;
103                case ATSAM_POWER_OFF:
104                        set_rtc_alarm_interrupt(rtc_data->interval);
105                        break;
106                case ATSAM_POWER_INIT:
107                        /* Enable fast startup via RTC alarm */
108                        rtems_interrupt_disable(level);
109                        PMC->PMC_FSMR |= PMC_FSMR_RTCAL;
110                        rtems_interrupt_enable(level);
111
112                        rtc_alarm_handler(rtc_data);
113                        break;
114                default:
115                        break;
116        }
117}
Note: See TracBrowser for help on using the repository browser.