Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
mbed-os/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_rtc.c@0:9fca2b23d0ba, 2019-02-23 (annotated)
- Committer:
- marcozecchini
- Date:
- Sat Feb 23 12:13:36 2019 +0000
- Revision:
- 0:9fca2b23d0ba
final commit
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| marcozecchini | 0:9fca2b23d0ba | 1 | /* |
| marcozecchini | 0:9fca2b23d0ba | 2 | * Copyright (c) 2015, Freescale Semiconductor, Inc. |
| marcozecchini | 0:9fca2b23d0ba | 3 | * Copyright 2016-2017 NXP |
| marcozecchini | 0:9fca2b23d0ba | 4 | * |
| marcozecchini | 0:9fca2b23d0ba | 5 | * Redistribution and use in source and binary forms, with or without modification, |
| marcozecchini | 0:9fca2b23d0ba | 6 | * are permitted provided that the following conditions are met: |
| marcozecchini | 0:9fca2b23d0ba | 7 | * |
| marcozecchini | 0:9fca2b23d0ba | 8 | * o Redistributions of source code must retain the above copyright notice, this list |
| marcozecchini | 0:9fca2b23d0ba | 9 | * of conditions and the following disclaimer. |
| marcozecchini | 0:9fca2b23d0ba | 10 | * |
| marcozecchini | 0:9fca2b23d0ba | 11 | * o Redistributions in binary form must reproduce the above copyright notice, this |
| marcozecchini | 0:9fca2b23d0ba | 12 | * list of conditions and the following disclaimer in the documentation and/or |
| marcozecchini | 0:9fca2b23d0ba | 13 | * other materials provided with the distribution. |
| marcozecchini | 0:9fca2b23d0ba | 14 | * |
| marcozecchini | 0:9fca2b23d0ba | 15 | * o Neither the name of the copyright holder nor the names of its |
| marcozecchini | 0:9fca2b23d0ba | 16 | * contributors may be used to endorse or promote products derived from this |
| marcozecchini | 0:9fca2b23d0ba | 17 | * software without specific prior written permission. |
| marcozecchini | 0:9fca2b23d0ba | 18 | * |
| marcozecchini | 0:9fca2b23d0ba | 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
| marcozecchini | 0:9fca2b23d0ba | 20 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| marcozecchini | 0:9fca2b23d0ba | 21 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
| marcozecchini | 0:9fca2b23d0ba | 22 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR |
| marcozecchini | 0:9fca2b23d0ba | 23 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
| marcozecchini | 0:9fca2b23d0ba | 24 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
| marcozecchini | 0:9fca2b23d0ba | 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON |
| marcozecchini | 0:9fca2b23d0ba | 26 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| marcozecchini | 0:9fca2b23d0ba | 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
| marcozecchini | 0:9fca2b23d0ba | 28 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| marcozecchini | 0:9fca2b23d0ba | 29 | */ |
| marcozecchini | 0:9fca2b23d0ba | 30 | |
| marcozecchini | 0:9fca2b23d0ba | 31 | #include "fsl_rtc.h" |
| marcozecchini | 0:9fca2b23d0ba | 32 | |
| marcozecchini | 0:9fca2b23d0ba | 33 | /******************************************************************************* |
| marcozecchini | 0:9fca2b23d0ba | 34 | * Definitions |
| marcozecchini | 0:9fca2b23d0ba | 35 | ******************************************************************************/ |
| marcozecchini | 0:9fca2b23d0ba | 36 | #define SECONDS_IN_A_DAY (86400U) |
| marcozecchini | 0:9fca2b23d0ba | 37 | #define SECONDS_IN_A_HOUR (3600U) |
| marcozecchini | 0:9fca2b23d0ba | 38 | #define SECONDS_IN_A_MINUTE (60U) |
| marcozecchini | 0:9fca2b23d0ba | 39 | #define DAYS_IN_A_YEAR (365U) |
| marcozecchini | 0:9fca2b23d0ba | 40 | #define YEAR_RANGE_START (1970U) |
| marcozecchini | 0:9fca2b23d0ba | 41 | #define YEAR_RANGE_END (2099U) |
| marcozecchini | 0:9fca2b23d0ba | 42 | |
| marcozecchini | 0:9fca2b23d0ba | 43 | /******************************************************************************* |
| marcozecchini | 0:9fca2b23d0ba | 44 | * Prototypes |
| marcozecchini | 0:9fca2b23d0ba | 45 | ******************************************************************************/ |
| marcozecchini | 0:9fca2b23d0ba | 46 | /*! |
| marcozecchini | 0:9fca2b23d0ba | 47 | * @brief Checks whether the date and time passed in is valid |
| marcozecchini | 0:9fca2b23d0ba | 48 | * |
| marcozecchini | 0:9fca2b23d0ba | 49 | * @param datetime Pointer to structure where the date and time details are stored |
| marcozecchini | 0:9fca2b23d0ba | 50 | * |
| marcozecchini | 0:9fca2b23d0ba | 51 | * @return Returns false if the date & time details are out of range; true if in range |
| marcozecchini | 0:9fca2b23d0ba | 52 | */ |
| marcozecchini | 0:9fca2b23d0ba | 53 | static bool RTC_CheckDatetimeFormat(const rtc_datetime_t *datetime); |
| marcozecchini | 0:9fca2b23d0ba | 54 | |
| marcozecchini | 0:9fca2b23d0ba | 55 | /*! |
| marcozecchini | 0:9fca2b23d0ba | 56 | * @brief Converts time data from datetime to seconds |
| marcozecchini | 0:9fca2b23d0ba | 57 | * |
| marcozecchini | 0:9fca2b23d0ba | 58 | * @param datetime Pointer to datetime structure where the date and time details are stored |
| marcozecchini | 0:9fca2b23d0ba | 59 | * |
| marcozecchini | 0:9fca2b23d0ba | 60 | * @return The result of the conversion in seconds |
| marcozecchini | 0:9fca2b23d0ba | 61 | */ |
| marcozecchini | 0:9fca2b23d0ba | 62 | static uint32_t RTC_ConvertDatetimeToSeconds(const rtc_datetime_t *datetime); |
| marcozecchini | 0:9fca2b23d0ba | 63 | |
| marcozecchini | 0:9fca2b23d0ba | 64 | /*! |
| marcozecchini | 0:9fca2b23d0ba | 65 | * @brief Converts time data from seconds to a datetime structure |
| marcozecchini | 0:9fca2b23d0ba | 66 | * |
| marcozecchini | 0:9fca2b23d0ba | 67 | * @param seconds Seconds value that needs to be converted to datetime format |
| marcozecchini | 0:9fca2b23d0ba | 68 | * @param datetime Pointer to the datetime structure where the result of the conversion is stored |
| marcozecchini | 0:9fca2b23d0ba | 69 | */ |
| marcozecchini | 0:9fca2b23d0ba | 70 | static void RTC_ConvertSecondsToDatetime(uint32_t seconds, rtc_datetime_t *datetime); |
| marcozecchini | 0:9fca2b23d0ba | 71 | |
| marcozecchini | 0:9fca2b23d0ba | 72 | /******************************************************************************* |
| marcozecchini | 0:9fca2b23d0ba | 73 | * Code |
| marcozecchini | 0:9fca2b23d0ba | 74 | ******************************************************************************/ |
| marcozecchini | 0:9fca2b23d0ba | 75 | static bool RTC_CheckDatetimeFormat(const rtc_datetime_t *datetime) |
| marcozecchini | 0:9fca2b23d0ba | 76 | { |
| marcozecchini | 0:9fca2b23d0ba | 77 | assert(datetime); |
| marcozecchini | 0:9fca2b23d0ba | 78 | |
| marcozecchini | 0:9fca2b23d0ba | 79 | /* Table of days in a month for a non leap year. First entry in the table is not used, |
| marcozecchini | 0:9fca2b23d0ba | 80 | * valid months start from 1 |
| marcozecchini | 0:9fca2b23d0ba | 81 | */ |
| marcozecchini | 0:9fca2b23d0ba | 82 | uint8_t daysPerMonth[] = {0U, 31U, 28U, 31U, 30U, 31U, 30U, 31U, 31U, 30U, 31U, 30U, 31U}; |
| marcozecchini | 0:9fca2b23d0ba | 83 | |
| marcozecchini | 0:9fca2b23d0ba | 84 | /* Check year, month, hour, minute, seconds */ |
| marcozecchini | 0:9fca2b23d0ba | 85 | if ((datetime->year < YEAR_RANGE_START) || (datetime->year > YEAR_RANGE_END) || (datetime->month > 12U) || |
| marcozecchini | 0:9fca2b23d0ba | 86 | (datetime->month < 1U) || (datetime->hour >= 24U) || (datetime->minute >= 60U) || (datetime->second >= 60U)) |
| marcozecchini | 0:9fca2b23d0ba | 87 | { |
| marcozecchini | 0:9fca2b23d0ba | 88 | /* If not correct then error*/ |
| marcozecchini | 0:9fca2b23d0ba | 89 | return false; |
| marcozecchini | 0:9fca2b23d0ba | 90 | } |
| marcozecchini | 0:9fca2b23d0ba | 91 | |
| marcozecchini | 0:9fca2b23d0ba | 92 | /* Adjust the days in February for a leap year */ |
| marcozecchini | 0:9fca2b23d0ba | 93 | if ((((datetime->year & 3U) == 0) && (datetime->year % 100 != 0)) || (datetime->year % 400 == 0)) |
| marcozecchini | 0:9fca2b23d0ba | 94 | { |
| marcozecchini | 0:9fca2b23d0ba | 95 | daysPerMonth[2] = 29U; |
| marcozecchini | 0:9fca2b23d0ba | 96 | } |
| marcozecchini | 0:9fca2b23d0ba | 97 | |
| marcozecchini | 0:9fca2b23d0ba | 98 | /* Check the validity of the day */ |
| marcozecchini | 0:9fca2b23d0ba | 99 | if ((datetime->day > daysPerMonth[datetime->month]) || (datetime->day < 1U)) |
| marcozecchini | 0:9fca2b23d0ba | 100 | { |
| marcozecchini | 0:9fca2b23d0ba | 101 | return false; |
| marcozecchini | 0:9fca2b23d0ba | 102 | } |
| marcozecchini | 0:9fca2b23d0ba | 103 | |
| marcozecchini | 0:9fca2b23d0ba | 104 | return true; |
| marcozecchini | 0:9fca2b23d0ba | 105 | } |
| marcozecchini | 0:9fca2b23d0ba | 106 | |
| marcozecchini | 0:9fca2b23d0ba | 107 | static uint32_t RTC_ConvertDatetimeToSeconds(const rtc_datetime_t *datetime) |
| marcozecchini | 0:9fca2b23d0ba | 108 | { |
| marcozecchini | 0:9fca2b23d0ba | 109 | assert(datetime); |
| marcozecchini | 0:9fca2b23d0ba | 110 | |
| marcozecchini | 0:9fca2b23d0ba | 111 | /* Number of days from begin of the non Leap-year*/ |
| marcozecchini | 0:9fca2b23d0ba | 112 | /* Number of days from begin of the non Leap-year*/ |
| marcozecchini | 0:9fca2b23d0ba | 113 | uint16_t monthDays[] = {0U, 0U, 31U, 59U, 90U, 120U, 151U, 181U, 212U, 243U, 273U, 304U, 334U}; |
| marcozecchini | 0:9fca2b23d0ba | 114 | uint32_t seconds; |
| marcozecchini | 0:9fca2b23d0ba | 115 | |
| marcozecchini | 0:9fca2b23d0ba | 116 | /* Compute number of days from 1970 till given year*/ |
| marcozecchini | 0:9fca2b23d0ba | 117 | seconds = (datetime->year - 1970U) * DAYS_IN_A_YEAR; |
| marcozecchini | 0:9fca2b23d0ba | 118 | /* Add leap year days */ |
| marcozecchini | 0:9fca2b23d0ba | 119 | seconds += ((datetime->year / 4) - (1970U / 4)); |
| marcozecchini | 0:9fca2b23d0ba | 120 | /* Add number of days till given month*/ |
| marcozecchini | 0:9fca2b23d0ba | 121 | seconds += monthDays[datetime->month]; |
| marcozecchini | 0:9fca2b23d0ba | 122 | /* Add days in given month. We subtract the current day as it is |
| marcozecchini | 0:9fca2b23d0ba | 123 | * represented in the hours, minutes and seconds field*/ |
| marcozecchini | 0:9fca2b23d0ba | 124 | seconds += (datetime->day - 1); |
| marcozecchini | 0:9fca2b23d0ba | 125 | /* For leap year if month less than or equal to Febraury, decrement day counter*/ |
| marcozecchini | 0:9fca2b23d0ba | 126 | if ((!(datetime->year & 3U)) && (datetime->month <= 2U)) |
| marcozecchini | 0:9fca2b23d0ba | 127 | { |
| marcozecchini | 0:9fca2b23d0ba | 128 | seconds--; |
| marcozecchini | 0:9fca2b23d0ba | 129 | } |
| marcozecchini | 0:9fca2b23d0ba | 130 | |
| marcozecchini | 0:9fca2b23d0ba | 131 | seconds = (seconds * SECONDS_IN_A_DAY) + (datetime->hour * SECONDS_IN_A_HOUR) + |
| marcozecchini | 0:9fca2b23d0ba | 132 | (datetime->minute * SECONDS_IN_A_MINUTE) + datetime->second; |
| marcozecchini | 0:9fca2b23d0ba | 133 | |
| marcozecchini | 0:9fca2b23d0ba | 134 | return seconds; |
| marcozecchini | 0:9fca2b23d0ba | 135 | } |
| marcozecchini | 0:9fca2b23d0ba | 136 | |
| marcozecchini | 0:9fca2b23d0ba | 137 | static void RTC_ConvertSecondsToDatetime(uint32_t seconds, rtc_datetime_t *datetime) |
| marcozecchini | 0:9fca2b23d0ba | 138 | { |
| marcozecchini | 0:9fca2b23d0ba | 139 | assert(datetime); |
| marcozecchini | 0:9fca2b23d0ba | 140 | |
| marcozecchini | 0:9fca2b23d0ba | 141 | uint32_t x; |
| marcozecchini | 0:9fca2b23d0ba | 142 | uint32_t secondsRemaining, days; |
| marcozecchini | 0:9fca2b23d0ba | 143 | uint16_t daysInYear; |
| marcozecchini | 0:9fca2b23d0ba | 144 | /* Table of days in a month for a non leap year. First entry in the table is not used, |
| marcozecchini | 0:9fca2b23d0ba | 145 | * valid months start from 1 |
| marcozecchini | 0:9fca2b23d0ba | 146 | */ |
| marcozecchini | 0:9fca2b23d0ba | 147 | uint8_t daysPerMonth[] = {0U, 31U, 28U, 31U, 30U, 31U, 30U, 31U, 31U, 30U, 31U, 30U, 31U}; |
| marcozecchini | 0:9fca2b23d0ba | 148 | |
| marcozecchini | 0:9fca2b23d0ba | 149 | /* Start with the seconds value that is passed in to be converted to date time format */ |
| marcozecchini | 0:9fca2b23d0ba | 150 | secondsRemaining = seconds; |
| marcozecchini | 0:9fca2b23d0ba | 151 | |
| marcozecchini | 0:9fca2b23d0ba | 152 | /* Calcuate the number of days, we add 1 for the current day which is represented in the |
| marcozecchini | 0:9fca2b23d0ba | 153 | * hours and seconds field |
| marcozecchini | 0:9fca2b23d0ba | 154 | */ |
| marcozecchini | 0:9fca2b23d0ba | 155 | days = secondsRemaining / SECONDS_IN_A_DAY + 1; |
| marcozecchini | 0:9fca2b23d0ba | 156 | |
| marcozecchini | 0:9fca2b23d0ba | 157 | /* Update seconds left*/ |
| marcozecchini | 0:9fca2b23d0ba | 158 | secondsRemaining = secondsRemaining % SECONDS_IN_A_DAY; |
| marcozecchini | 0:9fca2b23d0ba | 159 | |
| marcozecchini | 0:9fca2b23d0ba | 160 | /* Calculate the datetime hour, minute and second fields */ |
| marcozecchini | 0:9fca2b23d0ba | 161 | datetime->hour = secondsRemaining / SECONDS_IN_A_HOUR; |
| marcozecchini | 0:9fca2b23d0ba | 162 | secondsRemaining = secondsRemaining % SECONDS_IN_A_HOUR; |
| marcozecchini | 0:9fca2b23d0ba | 163 | datetime->minute = secondsRemaining / 60U; |
| marcozecchini | 0:9fca2b23d0ba | 164 | datetime->second = secondsRemaining % SECONDS_IN_A_MINUTE; |
| marcozecchini | 0:9fca2b23d0ba | 165 | |
| marcozecchini | 0:9fca2b23d0ba | 166 | /* Calculate year */ |
| marcozecchini | 0:9fca2b23d0ba | 167 | daysInYear = DAYS_IN_A_YEAR; |
| marcozecchini | 0:9fca2b23d0ba | 168 | datetime->year = YEAR_RANGE_START; |
| marcozecchini | 0:9fca2b23d0ba | 169 | while (days > daysInYear) |
| marcozecchini | 0:9fca2b23d0ba | 170 | { |
| marcozecchini | 0:9fca2b23d0ba | 171 | /* Decrease day count by a year and increment year by 1 */ |
| marcozecchini | 0:9fca2b23d0ba | 172 | days -= daysInYear; |
| marcozecchini | 0:9fca2b23d0ba | 173 | datetime->year++; |
| marcozecchini | 0:9fca2b23d0ba | 174 | |
| marcozecchini | 0:9fca2b23d0ba | 175 | /* Adjust the number of days for a leap year */ |
| marcozecchini | 0:9fca2b23d0ba | 176 | if (datetime->year & 3U) |
| marcozecchini | 0:9fca2b23d0ba | 177 | { |
| marcozecchini | 0:9fca2b23d0ba | 178 | daysInYear = DAYS_IN_A_YEAR; |
| marcozecchini | 0:9fca2b23d0ba | 179 | } |
| marcozecchini | 0:9fca2b23d0ba | 180 | else |
| marcozecchini | 0:9fca2b23d0ba | 181 | { |
| marcozecchini | 0:9fca2b23d0ba | 182 | daysInYear = DAYS_IN_A_YEAR + 1; |
| marcozecchini | 0:9fca2b23d0ba | 183 | } |
| marcozecchini | 0:9fca2b23d0ba | 184 | } |
| marcozecchini | 0:9fca2b23d0ba | 185 | |
| marcozecchini | 0:9fca2b23d0ba | 186 | /* Adjust the days in February for a leap year */ |
| marcozecchini | 0:9fca2b23d0ba | 187 | if (!(datetime->year & 3U)) |
| marcozecchini | 0:9fca2b23d0ba | 188 | { |
| marcozecchini | 0:9fca2b23d0ba | 189 | daysPerMonth[2] = 29U; |
| marcozecchini | 0:9fca2b23d0ba | 190 | } |
| marcozecchini | 0:9fca2b23d0ba | 191 | |
| marcozecchini | 0:9fca2b23d0ba | 192 | for (x = 1U; x <= 12U; x++) |
| marcozecchini | 0:9fca2b23d0ba | 193 | { |
| marcozecchini | 0:9fca2b23d0ba | 194 | if (days <= daysPerMonth[x]) |
| marcozecchini | 0:9fca2b23d0ba | 195 | { |
| marcozecchini | 0:9fca2b23d0ba | 196 | datetime->month = x; |
| marcozecchini | 0:9fca2b23d0ba | 197 | break; |
| marcozecchini | 0:9fca2b23d0ba | 198 | } |
| marcozecchini | 0:9fca2b23d0ba | 199 | else |
| marcozecchini | 0:9fca2b23d0ba | 200 | { |
| marcozecchini | 0:9fca2b23d0ba | 201 | days -= daysPerMonth[x]; |
| marcozecchini | 0:9fca2b23d0ba | 202 | } |
| marcozecchini | 0:9fca2b23d0ba | 203 | } |
| marcozecchini | 0:9fca2b23d0ba | 204 | |
| marcozecchini | 0:9fca2b23d0ba | 205 | datetime->day = days; |
| marcozecchini | 0:9fca2b23d0ba | 206 | } |
| marcozecchini | 0:9fca2b23d0ba | 207 | |
| marcozecchini | 0:9fca2b23d0ba | 208 | void RTC_Init(RTC_Type *base, const rtc_config_t *config) |
| marcozecchini | 0:9fca2b23d0ba | 209 | { |
| marcozecchini | 0:9fca2b23d0ba | 210 | assert(config); |
| marcozecchini | 0:9fca2b23d0ba | 211 | |
| marcozecchini | 0:9fca2b23d0ba | 212 | uint32_t reg; |
| marcozecchini | 0:9fca2b23d0ba | 213 | |
| marcozecchini | 0:9fca2b23d0ba | 214 | #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) |
| marcozecchini | 0:9fca2b23d0ba | 215 | CLOCK_EnableClock(kCLOCK_Rtc0); |
| marcozecchini | 0:9fca2b23d0ba | 216 | #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ |
| marcozecchini | 0:9fca2b23d0ba | 217 | |
| marcozecchini | 0:9fca2b23d0ba | 218 | /* Issue a software reset if timer is invalid */ |
| marcozecchini | 0:9fca2b23d0ba | 219 | if (RTC_GetStatusFlags(RTC) & kRTC_TimeInvalidFlag) |
| marcozecchini | 0:9fca2b23d0ba | 220 | { |
| marcozecchini | 0:9fca2b23d0ba | 221 | RTC_Reset(RTC); |
| marcozecchini | 0:9fca2b23d0ba | 222 | } |
| marcozecchini | 0:9fca2b23d0ba | 223 | |
| marcozecchini | 0:9fca2b23d0ba | 224 | reg = base->CR; |
| marcozecchini | 0:9fca2b23d0ba | 225 | /* Setup the update mode and supervisor access mode */ |
| marcozecchini | 0:9fca2b23d0ba | 226 | reg &= ~(RTC_CR_UM_MASK | RTC_CR_SUP_MASK); |
| marcozecchini | 0:9fca2b23d0ba | 227 | reg |= RTC_CR_UM(config->updateMode) | RTC_CR_SUP(config->supervisorAccess); |
| marcozecchini | 0:9fca2b23d0ba | 228 | #if defined(FSL_FEATURE_RTC_HAS_WAKEUP_PIN_SELECTION) && FSL_FEATURE_RTC_HAS_WAKEUP_PIN_SELECTION |
| marcozecchini | 0:9fca2b23d0ba | 229 | /* Setup the wakeup pin select */ |
| marcozecchini | 0:9fca2b23d0ba | 230 | reg &= ~(RTC_CR_WPS_MASK); |
| marcozecchini | 0:9fca2b23d0ba | 231 | reg |= RTC_CR_WPS(config->wakeupSelect); |
| marcozecchini | 0:9fca2b23d0ba | 232 | #endif /* FSL_FEATURE_RTC_HAS_WAKEUP_PIN */ |
| marcozecchini | 0:9fca2b23d0ba | 233 | base->CR = reg; |
| marcozecchini | 0:9fca2b23d0ba | 234 | |
| marcozecchini | 0:9fca2b23d0ba | 235 | /* Configure the RTC time compensation register */ |
| marcozecchini | 0:9fca2b23d0ba | 236 | base->TCR = (RTC_TCR_CIR(config->compensationInterval) | RTC_TCR_TCR(config->compensationTime)); |
| marcozecchini | 0:9fca2b23d0ba | 237 | } |
| marcozecchini | 0:9fca2b23d0ba | 238 | |
| marcozecchini | 0:9fca2b23d0ba | 239 | void RTC_GetDefaultConfig(rtc_config_t *config) |
| marcozecchini | 0:9fca2b23d0ba | 240 | { |
| marcozecchini | 0:9fca2b23d0ba | 241 | assert(config); |
| marcozecchini | 0:9fca2b23d0ba | 242 | |
| marcozecchini | 0:9fca2b23d0ba | 243 | /* Wakeup pin will assert if the RTC interrupt asserts or if the wakeup pin is turned on */ |
| marcozecchini | 0:9fca2b23d0ba | 244 | config->wakeupSelect = false; |
| marcozecchini | 0:9fca2b23d0ba | 245 | /* Registers cannot be written when locked */ |
| marcozecchini | 0:9fca2b23d0ba | 246 | config->updateMode = false; |
| marcozecchini | 0:9fca2b23d0ba | 247 | /* Non-supervisor mode write accesses are not supported and will generate a bus error */ |
| marcozecchini | 0:9fca2b23d0ba | 248 | config->supervisorAccess = false; |
| marcozecchini | 0:9fca2b23d0ba | 249 | /* Compensation interval used by the crystal compensation logic */ |
| marcozecchini | 0:9fca2b23d0ba | 250 | config->compensationInterval = 0; |
| marcozecchini | 0:9fca2b23d0ba | 251 | /* Compensation time used by the crystal compensation logic */ |
| marcozecchini | 0:9fca2b23d0ba | 252 | config->compensationTime = 0; |
| marcozecchini | 0:9fca2b23d0ba | 253 | } |
| marcozecchini | 0:9fca2b23d0ba | 254 | |
| marcozecchini | 0:9fca2b23d0ba | 255 | status_t RTC_SetDatetime(RTC_Type *base, const rtc_datetime_t *datetime) |
| marcozecchini | 0:9fca2b23d0ba | 256 | { |
| marcozecchini | 0:9fca2b23d0ba | 257 | assert(datetime); |
| marcozecchini | 0:9fca2b23d0ba | 258 | |
| marcozecchini | 0:9fca2b23d0ba | 259 | /* Return error if the time provided is not valid */ |
| marcozecchini | 0:9fca2b23d0ba | 260 | if (!(RTC_CheckDatetimeFormat(datetime))) |
| marcozecchini | 0:9fca2b23d0ba | 261 | { |
| marcozecchini | 0:9fca2b23d0ba | 262 | return kStatus_InvalidArgument; |
| marcozecchini | 0:9fca2b23d0ba | 263 | } |
| marcozecchini | 0:9fca2b23d0ba | 264 | |
| marcozecchini | 0:9fca2b23d0ba | 265 | /* Set time in seconds */ |
| marcozecchini | 0:9fca2b23d0ba | 266 | base->TSR = RTC_ConvertDatetimeToSeconds(datetime); |
| marcozecchini | 0:9fca2b23d0ba | 267 | |
| marcozecchini | 0:9fca2b23d0ba | 268 | return kStatus_Success; |
| marcozecchini | 0:9fca2b23d0ba | 269 | } |
| marcozecchini | 0:9fca2b23d0ba | 270 | |
| marcozecchini | 0:9fca2b23d0ba | 271 | void RTC_GetDatetime(RTC_Type *base, rtc_datetime_t *datetime) |
| marcozecchini | 0:9fca2b23d0ba | 272 | { |
| marcozecchini | 0:9fca2b23d0ba | 273 | assert(datetime); |
| marcozecchini | 0:9fca2b23d0ba | 274 | |
| marcozecchini | 0:9fca2b23d0ba | 275 | uint32_t seconds = 0; |
| marcozecchini | 0:9fca2b23d0ba | 276 | |
| marcozecchini | 0:9fca2b23d0ba | 277 | seconds = base->TSR; |
| marcozecchini | 0:9fca2b23d0ba | 278 | RTC_ConvertSecondsToDatetime(seconds, datetime); |
| marcozecchini | 0:9fca2b23d0ba | 279 | } |
| marcozecchini | 0:9fca2b23d0ba | 280 | |
| marcozecchini | 0:9fca2b23d0ba | 281 | status_t RTC_SetAlarm(RTC_Type *base, const rtc_datetime_t *alarmTime) |
| marcozecchini | 0:9fca2b23d0ba | 282 | { |
| marcozecchini | 0:9fca2b23d0ba | 283 | assert(alarmTime); |
| marcozecchini | 0:9fca2b23d0ba | 284 | |
| marcozecchini | 0:9fca2b23d0ba | 285 | uint32_t alarmSeconds = 0; |
| marcozecchini | 0:9fca2b23d0ba | 286 | uint32_t currSeconds = 0; |
| marcozecchini | 0:9fca2b23d0ba | 287 | |
| marcozecchini | 0:9fca2b23d0ba | 288 | /* Return error if the alarm time provided is not valid */ |
| marcozecchini | 0:9fca2b23d0ba | 289 | if (!(RTC_CheckDatetimeFormat(alarmTime))) |
| marcozecchini | 0:9fca2b23d0ba | 290 | { |
| marcozecchini | 0:9fca2b23d0ba | 291 | return kStatus_InvalidArgument; |
| marcozecchini | 0:9fca2b23d0ba | 292 | } |
| marcozecchini | 0:9fca2b23d0ba | 293 | |
| marcozecchini | 0:9fca2b23d0ba | 294 | alarmSeconds = RTC_ConvertDatetimeToSeconds(alarmTime); |
| marcozecchini | 0:9fca2b23d0ba | 295 | |
| marcozecchini | 0:9fca2b23d0ba | 296 | /* Get the current time */ |
| marcozecchini | 0:9fca2b23d0ba | 297 | currSeconds = base->TSR; |
| marcozecchini | 0:9fca2b23d0ba | 298 | |
| marcozecchini | 0:9fca2b23d0ba | 299 | /* Return error if the alarm time has passed */ |
| marcozecchini | 0:9fca2b23d0ba | 300 | if (alarmSeconds < currSeconds) |
| marcozecchini | 0:9fca2b23d0ba | 301 | { |
| marcozecchini | 0:9fca2b23d0ba | 302 | return kStatus_Fail; |
| marcozecchini | 0:9fca2b23d0ba | 303 | } |
| marcozecchini | 0:9fca2b23d0ba | 304 | |
| marcozecchini | 0:9fca2b23d0ba | 305 | /* Set alarm in seconds*/ |
| marcozecchini | 0:9fca2b23d0ba | 306 | base->TAR = alarmSeconds; |
| marcozecchini | 0:9fca2b23d0ba | 307 | |
| marcozecchini | 0:9fca2b23d0ba | 308 | return kStatus_Success; |
| marcozecchini | 0:9fca2b23d0ba | 309 | } |
| marcozecchini | 0:9fca2b23d0ba | 310 | |
| marcozecchini | 0:9fca2b23d0ba | 311 | void RTC_GetAlarm(RTC_Type *base, rtc_datetime_t *datetime) |
| marcozecchini | 0:9fca2b23d0ba | 312 | { |
| marcozecchini | 0:9fca2b23d0ba | 313 | assert(datetime); |
| marcozecchini | 0:9fca2b23d0ba | 314 | |
| marcozecchini | 0:9fca2b23d0ba | 315 | uint32_t alarmSeconds = 0; |
| marcozecchini | 0:9fca2b23d0ba | 316 | |
| marcozecchini | 0:9fca2b23d0ba | 317 | /* Get alarm in seconds */ |
| marcozecchini | 0:9fca2b23d0ba | 318 | alarmSeconds = base->TAR; |
| marcozecchini | 0:9fca2b23d0ba | 319 | |
| marcozecchini | 0:9fca2b23d0ba | 320 | RTC_ConvertSecondsToDatetime(alarmSeconds, datetime); |
| marcozecchini | 0:9fca2b23d0ba | 321 | } |
| marcozecchini | 0:9fca2b23d0ba | 322 | |
| marcozecchini | 0:9fca2b23d0ba | 323 | void RTC_ClearStatusFlags(RTC_Type *base, uint32_t mask) |
| marcozecchini | 0:9fca2b23d0ba | 324 | { |
| marcozecchini | 0:9fca2b23d0ba | 325 | /* The alarm flag is cleared by writing to the TAR register */ |
| marcozecchini | 0:9fca2b23d0ba | 326 | if (mask & kRTC_AlarmFlag) |
| marcozecchini | 0:9fca2b23d0ba | 327 | { |
| marcozecchini | 0:9fca2b23d0ba | 328 | base->TAR = 0U; |
| marcozecchini | 0:9fca2b23d0ba | 329 | } |
| marcozecchini | 0:9fca2b23d0ba | 330 | |
| marcozecchini | 0:9fca2b23d0ba | 331 | /* The timer overflow flag is cleared by initializing the TSR register. |
| marcozecchini | 0:9fca2b23d0ba | 332 | * The time counter should be disabled for this write to be successful |
| marcozecchini | 0:9fca2b23d0ba | 333 | */ |
| marcozecchini | 0:9fca2b23d0ba | 334 | if (mask & kRTC_TimeOverflowFlag) |
| marcozecchini | 0:9fca2b23d0ba | 335 | { |
| marcozecchini | 0:9fca2b23d0ba | 336 | base->TSR = 1U; |
| marcozecchini | 0:9fca2b23d0ba | 337 | } |
| marcozecchini | 0:9fca2b23d0ba | 338 | |
| marcozecchini | 0:9fca2b23d0ba | 339 | /* The timer overflow flag is cleared by initializing the TSR register. |
| marcozecchini | 0:9fca2b23d0ba | 340 | * The time counter should be disabled for this write to be successful |
| marcozecchini | 0:9fca2b23d0ba | 341 | */ |
| marcozecchini | 0:9fca2b23d0ba | 342 | if (mask & kRTC_TimeInvalidFlag) |
| marcozecchini | 0:9fca2b23d0ba | 343 | { |
| marcozecchini | 0:9fca2b23d0ba | 344 | base->TSR = 1U; |
| marcozecchini | 0:9fca2b23d0ba | 345 | } |
| marcozecchini | 0:9fca2b23d0ba | 346 | } |
| marcozecchini | 0:9fca2b23d0ba | 347 | |
| marcozecchini | 0:9fca2b23d0ba | 348 | #if defined(FSL_FEATURE_RTC_HAS_MONOTONIC) && (FSL_FEATURE_RTC_HAS_MONOTONIC) |
| marcozecchini | 0:9fca2b23d0ba | 349 | |
| marcozecchini | 0:9fca2b23d0ba | 350 | void RTC_GetMonotonicCounter(RTC_Type *base, uint64_t *counter) |
| marcozecchini | 0:9fca2b23d0ba | 351 | { |
| marcozecchini | 0:9fca2b23d0ba | 352 | assert(counter); |
| marcozecchini | 0:9fca2b23d0ba | 353 | |
| marcozecchini | 0:9fca2b23d0ba | 354 | *counter = (((uint64_t)base->MCHR << 32) | ((uint64_t)base->MCLR)); |
| marcozecchini | 0:9fca2b23d0ba | 355 | } |
| marcozecchini | 0:9fca2b23d0ba | 356 | |
| marcozecchini | 0:9fca2b23d0ba | 357 | void RTC_SetMonotonicCounter(RTC_Type *base, uint64_t counter) |
| marcozecchini | 0:9fca2b23d0ba | 358 | { |
| marcozecchini | 0:9fca2b23d0ba | 359 | /* Prepare to initialize the register with the new value written */ |
| marcozecchini | 0:9fca2b23d0ba | 360 | base->MER &= ~RTC_MER_MCE_MASK; |
| marcozecchini | 0:9fca2b23d0ba | 361 | |
| marcozecchini | 0:9fca2b23d0ba | 362 | base->MCHR = (uint32_t)((counter) >> 32); |
| marcozecchini | 0:9fca2b23d0ba | 363 | base->MCLR = (uint32_t)(counter); |
| marcozecchini | 0:9fca2b23d0ba | 364 | } |
| marcozecchini | 0:9fca2b23d0ba | 365 | |
| marcozecchini | 0:9fca2b23d0ba | 366 | status_t RTC_IncrementMonotonicCounter(RTC_Type *base) |
| marcozecchini | 0:9fca2b23d0ba | 367 | { |
| marcozecchini | 0:9fca2b23d0ba | 368 | if (base->SR & (RTC_SR_MOF_MASK | RTC_SR_TIF_MASK)) |
| marcozecchini | 0:9fca2b23d0ba | 369 | { |
| marcozecchini | 0:9fca2b23d0ba | 370 | return kStatus_Fail; |
| marcozecchini | 0:9fca2b23d0ba | 371 | } |
| marcozecchini | 0:9fca2b23d0ba | 372 | |
| marcozecchini | 0:9fca2b23d0ba | 373 | /* Prepare to switch to increment mode */ |
| marcozecchini | 0:9fca2b23d0ba | 374 | base->MER |= RTC_MER_MCE_MASK; |
| marcozecchini | 0:9fca2b23d0ba | 375 | /* Write anything so the counter increments*/ |
| marcozecchini | 0:9fca2b23d0ba | 376 | base->MCLR = 1U; |
| marcozecchini | 0:9fca2b23d0ba | 377 | |
| marcozecchini | 0:9fca2b23d0ba | 378 | return kStatus_Success; |
| marcozecchini | 0:9fca2b23d0ba | 379 | } |
| marcozecchini | 0:9fca2b23d0ba | 380 | |
| marcozecchini | 0:9fca2b23d0ba | 381 | #endif /* FSL_FEATURE_RTC_HAS_MONOTONIC */ |