Bootload from SD card to sector 0, and jump to sector 24 where new firmware resides
Fork of Panel-Controller-Bootloader by
rtc.c@0:c3a652eff606, 2015-04-21 (annotated)
- Committer:
- bonchenko
- Date:
- Tue Apr 21 09:30:11 2015 +0000
- Revision:
- 0:c3a652eff606
Able to remove flash content, write new firmware from sd card, and jump to that new firmware. But its still not running completely
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
bonchenko | 0:c3a652eff606 | 1 | /*-------------------------------------------------------------------------- */ |
bonchenko | 0:c3a652eff606 | 2 | /* RTC controls for STM32 */ |
bonchenko | 0:c3a652eff606 | 3 | /* Copyright (c) 2009, Martin Thomas 4/2009, 3BSD-license */ |
bonchenko | 0:c3a652eff606 | 4 | /* partly based on code from STMircoelectronics, Peter Dannegger, "LaLaDumm" */ |
bonchenko | 0:c3a652eff606 | 5 | /*-------------------------------------------------------------------------- */ |
bonchenko | 0:c3a652eff606 | 6 | |
bonchenko | 0:c3a652eff606 | 7 | #include <stdint.h> |
bonchenko | 0:c3a652eff606 | 8 | #include <stdbool.h> |
bonchenko | 0:c3a652eff606 | 9 | #include "stm32f10x.h" |
bonchenko | 0:c3a652eff606 | 10 | #include "rtc.h" |
bonchenko | 0:c3a652eff606 | 11 | |
bonchenko | 0:c3a652eff606 | 12 | #define FIRSTYEAR 2000 // start year |
bonchenko | 0:c3a652eff606 | 13 | #define FIRSTDAY 6 // 0 = Sunday |
bonchenko | 0:c3a652eff606 | 14 | |
bonchenko | 0:c3a652eff606 | 15 | static const uint8_t DaysInMonth[] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; |
bonchenko | 0:c3a652eff606 | 16 | |
bonchenko | 0:c3a652eff606 | 17 | /******************************************************************************* |
bonchenko | 0:c3a652eff606 | 18 | * Function Name : isDST |
bonchenko | 0:c3a652eff606 | 19 | * Description : checks if given time is in Daylight Saving time-span. |
bonchenko | 0:c3a652eff606 | 20 | * Input : time-struct, must be fully populated including weekday |
bonchenko | 0:c3a652eff606 | 21 | * Output : none |
bonchenko | 0:c3a652eff606 | 22 | * Return : false: no DST ("winter"), true: in DST ("summer") |
bonchenko | 0:c3a652eff606 | 23 | * DST according to German standard |
bonchenko | 0:c3a652eff606 | 24 | * Based on code from Peter Dannegger found in the microcontroller.net forum. |
bonchenko | 0:c3a652eff606 | 25 | *******************************************************************************/ |
bonchenko | 0:c3a652eff606 | 26 | static bool isDST( const RTC_t *t ) |
bonchenko | 0:c3a652eff606 | 27 | { |
bonchenko | 0:c3a652eff606 | 28 | uint8_t wday, month; // locals for faster access |
bonchenko | 0:c3a652eff606 | 29 | |
bonchenko | 0:c3a652eff606 | 30 | month = t->month; |
bonchenko | 0:c3a652eff606 | 31 | |
bonchenko | 0:c3a652eff606 | 32 | if( month < 3 || month > 10 ) { // month 1, 2, 11, 12 |
bonchenko | 0:c3a652eff606 | 33 | return false; // -> Winter |
bonchenko | 0:c3a652eff606 | 34 | } |
bonchenko | 0:c3a652eff606 | 35 | |
bonchenko | 0:c3a652eff606 | 36 | wday = t->wday; |
bonchenko | 0:c3a652eff606 | 37 | |
bonchenko | 0:c3a652eff606 | 38 | if( t->mday - wday >= 25 && (wday || t->hour >= 2) ) { // after last Sunday 2:00 |
bonchenko | 0:c3a652eff606 | 39 | if( month == 10 ) { // October -> Winter |
bonchenko | 0:c3a652eff606 | 40 | return false; |
bonchenko | 0:c3a652eff606 | 41 | } |
bonchenko | 0:c3a652eff606 | 42 | } else { // before last Sunday 2:00 |
bonchenko | 0:c3a652eff606 | 43 | if( month == 3 ) { // March -> Winter |
bonchenko | 0:c3a652eff606 | 44 | return false; |
bonchenko | 0:c3a652eff606 | 45 | } |
bonchenko | 0:c3a652eff606 | 46 | } |
bonchenko | 0:c3a652eff606 | 47 | |
bonchenko | 0:c3a652eff606 | 48 | return true; |
bonchenko | 0:c3a652eff606 | 49 | } |
bonchenko | 0:c3a652eff606 | 50 | |
bonchenko | 0:c3a652eff606 | 51 | /******************************************************************************* |
bonchenko | 0:c3a652eff606 | 52 | * Function Name : adjustDST |
bonchenko | 0:c3a652eff606 | 53 | * Description : adjusts time to DST if needed |
bonchenko | 0:c3a652eff606 | 54 | * Input : non DST time-struct, must be fully populated including weekday |
bonchenko | 0:c3a652eff606 | 55 | * Output : time-stuct gets modified |
bonchenko | 0:c3a652eff606 | 56 | * Return : false: no DST ("winter"), true: in DST ("summer") |
bonchenko | 0:c3a652eff606 | 57 | * DST according to German standard |
bonchenko | 0:c3a652eff606 | 58 | * Based on code from Peter Dannegger found in the microcontroller.net forum. |
bonchenko | 0:c3a652eff606 | 59 | *******************************************************************************/ |
bonchenko | 0:c3a652eff606 | 60 | static bool adjustDST( RTC_t *t ) |
bonchenko | 0:c3a652eff606 | 61 | { |
bonchenko | 0:c3a652eff606 | 62 | uint8_t hour, day, wday, month; // locals for faster access |
bonchenko | 0:c3a652eff606 | 63 | |
bonchenko | 0:c3a652eff606 | 64 | hour = t->hour; |
bonchenko | 0:c3a652eff606 | 65 | day = t->mday; |
bonchenko | 0:c3a652eff606 | 66 | wday = t->wday; |
bonchenko | 0:c3a652eff606 | 67 | month = t->month; |
bonchenko | 0:c3a652eff606 | 68 | |
bonchenko | 0:c3a652eff606 | 69 | if ( isDST(t) ) { |
bonchenko | 0:c3a652eff606 | 70 | t->dst = 1; |
bonchenko | 0:c3a652eff606 | 71 | hour++; // add one hour |
bonchenko | 0:c3a652eff606 | 72 | if( hour == 24 ){ // next day |
bonchenko | 0:c3a652eff606 | 73 | hour = 0; |
bonchenko | 0:c3a652eff606 | 74 | wday++; // next weekday |
bonchenko | 0:c3a652eff606 | 75 | if( wday == 7 ) { |
bonchenko | 0:c3a652eff606 | 76 | wday = 0; |
bonchenko | 0:c3a652eff606 | 77 | } |
bonchenko | 0:c3a652eff606 | 78 | if( day == DaysInMonth[month-1] ) { // next month |
bonchenko | 0:c3a652eff606 | 79 | day = 0; |
bonchenko | 0:c3a652eff606 | 80 | month++; |
bonchenko | 0:c3a652eff606 | 81 | } |
bonchenko | 0:c3a652eff606 | 82 | day++; |
bonchenko | 0:c3a652eff606 | 83 | } |
bonchenko | 0:c3a652eff606 | 84 | t->month = month; |
bonchenko | 0:c3a652eff606 | 85 | t->hour = hour; |
bonchenko | 0:c3a652eff606 | 86 | t->mday = day; |
bonchenko | 0:c3a652eff606 | 87 | t->wday = wday; |
bonchenko | 0:c3a652eff606 | 88 | return true; |
bonchenko | 0:c3a652eff606 | 89 | } else { |
bonchenko | 0:c3a652eff606 | 90 | t->dst = 0; |
bonchenko | 0:c3a652eff606 | 91 | return false; |
bonchenko | 0:c3a652eff606 | 92 | } |
bonchenko | 0:c3a652eff606 | 93 | } |
bonchenko | 0:c3a652eff606 | 94 | |
bonchenko | 0:c3a652eff606 | 95 | /******************************************************************************* |
bonchenko | 0:c3a652eff606 | 96 | * Function Name : counter_to_struct |
bonchenko | 0:c3a652eff606 | 97 | * Description : populates time-struct based on counter-value |
bonchenko | 0:c3a652eff606 | 98 | * Input : - counter-value (unit seconds, 0 -> 1.1.2000 00:00:00), |
bonchenko | 0:c3a652eff606 | 99 | * - Pointer to time-struct |
bonchenko | 0:c3a652eff606 | 100 | * Output : time-struct gets populated, DST not taken into account here |
bonchenko | 0:c3a652eff606 | 101 | * Return : none |
bonchenko | 0:c3a652eff606 | 102 | * Based on code from Peter Dannegger found in the microcontroller.net forum. |
bonchenko | 0:c3a652eff606 | 103 | *******************************************************************************/ |
bonchenko | 0:c3a652eff606 | 104 | static void counter_to_struct( uint32_t sec, RTC_t *t ) |
bonchenko | 0:c3a652eff606 | 105 | { |
bonchenko | 0:c3a652eff606 | 106 | uint16_t day; |
bonchenko | 0:c3a652eff606 | 107 | uint8_t year; |
bonchenko | 0:c3a652eff606 | 108 | uint16_t dayofyear; |
bonchenko | 0:c3a652eff606 | 109 | uint8_t leap400; |
bonchenko | 0:c3a652eff606 | 110 | uint8_t month; |
bonchenko | 0:c3a652eff606 | 111 | |
bonchenko | 0:c3a652eff606 | 112 | t->sec = sec % 60; |
bonchenko | 0:c3a652eff606 | 113 | sec /= 60; |
bonchenko | 0:c3a652eff606 | 114 | t->min = sec % 60; |
bonchenko | 0:c3a652eff606 | 115 | sec /= 60; |
bonchenko | 0:c3a652eff606 | 116 | t->hour = sec % 24; |
bonchenko | 0:c3a652eff606 | 117 | day = (uint16_t)(sec / 24); |
bonchenko | 0:c3a652eff606 | 118 | |
bonchenko | 0:c3a652eff606 | 119 | t->wday = (day + FIRSTDAY) % 7; // weekday |
bonchenko | 0:c3a652eff606 | 120 | |
bonchenko | 0:c3a652eff606 | 121 | year = FIRSTYEAR % 100; // 0..99 |
bonchenko | 0:c3a652eff606 | 122 | leap400 = 4 - ((FIRSTYEAR - 1) / 100 & 3); // 4, 3, 2, 1 |
bonchenko | 0:c3a652eff606 | 123 | |
bonchenko | 0:c3a652eff606 | 124 | for(;;) { |
bonchenko | 0:c3a652eff606 | 125 | dayofyear = 365; |
bonchenko | 0:c3a652eff606 | 126 | if( (year & 3) == 0 ) { |
bonchenko | 0:c3a652eff606 | 127 | dayofyear = 366; // leap year |
bonchenko | 0:c3a652eff606 | 128 | if( year == 0 || year == 100 || year == 200 ) { // 100 year exception |
bonchenko | 0:c3a652eff606 | 129 | if( --leap400 ) { // 400 year exception |
bonchenko | 0:c3a652eff606 | 130 | dayofyear = 365; |
bonchenko | 0:c3a652eff606 | 131 | } |
bonchenko | 0:c3a652eff606 | 132 | } |
bonchenko | 0:c3a652eff606 | 133 | } |
bonchenko | 0:c3a652eff606 | 134 | if( day < dayofyear ) { |
bonchenko | 0:c3a652eff606 | 135 | break; |
bonchenko | 0:c3a652eff606 | 136 | } |
bonchenko | 0:c3a652eff606 | 137 | day -= dayofyear; |
bonchenko | 0:c3a652eff606 | 138 | year++; // 00..136 / 99..235 |
bonchenko | 0:c3a652eff606 | 139 | } |
bonchenko | 0:c3a652eff606 | 140 | t->year = year + FIRSTYEAR / 100 * 100; // + century |
bonchenko | 0:c3a652eff606 | 141 | |
bonchenko | 0:c3a652eff606 | 142 | if( dayofyear & 1 && day > 58 ) { // no leap year and after 28.2. |
bonchenko | 0:c3a652eff606 | 143 | day++; // skip 29.2. |
bonchenko | 0:c3a652eff606 | 144 | } |
bonchenko | 0:c3a652eff606 | 145 | |
bonchenko | 0:c3a652eff606 | 146 | for( month = 1; day >= DaysInMonth[month-1]; month++ ) { |
bonchenko | 0:c3a652eff606 | 147 | day -= DaysInMonth[month-1]; |
bonchenko | 0:c3a652eff606 | 148 | } |
bonchenko | 0:c3a652eff606 | 149 | |
bonchenko | 0:c3a652eff606 | 150 | t->month = month; // 1..12 |
bonchenko | 0:c3a652eff606 | 151 | t->mday = day + 1; // 1..31 |
bonchenko | 0:c3a652eff606 | 152 | } |
bonchenko | 0:c3a652eff606 | 153 | |
bonchenko | 0:c3a652eff606 | 154 | /******************************************************************************* |
bonchenko | 0:c3a652eff606 | 155 | * Function Name : struct_to_counter |
bonchenko | 0:c3a652eff606 | 156 | * Description : calculates second-counter from populated time-struct |
bonchenko | 0:c3a652eff606 | 157 | * Input : Pointer to time-struct |
bonchenko | 0:c3a652eff606 | 158 | * Output : none |
bonchenko | 0:c3a652eff606 | 159 | * Return : counter-value (unit seconds, 0 -> 1.1.2000 00:00:00), |
bonchenko | 0:c3a652eff606 | 160 | * Based on code from "LalaDumm" found in the microcontroller.net forum. |
bonchenko | 0:c3a652eff606 | 161 | *******************************************************************************/ |
bonchenko | 0:c3a652eff606 | 162 | static uint32_t struct_to_counter( const RTC_t *t ) |
bonchenko | 0:c3a652eff606 | 163 | { |
bonchenko | 0:c3a652eff606 | 164 | uint8_t i; |
bonchenko | 0:c3a652eff606 | 165 | uint32_t result = 0; |
bonchenko | 0:c3a652eff606 | 166 | uint16_t idx, year; |
bonchenko | 0:c3a652eff606 | 167 | |
bonchenko | 0:c3a652eff606 | 168 | year = t->year; |
bonchenko | 0:c3a652eff606 | 169 | |
bonchenko | 0:c3a652eff606 | 170 | /* Calculate days of years before */ |
bonchenko | 0:c3a652eff606 | 171 | result = (uint32_t)year * 365; |
bonchenko | 0:c3a652eff606 | 172 | if (t->year >= 1) { |
bonchenko | 0:c3a652eff606 | 173 | result += (year + 3) / 4; |
bonchenko | 0:c3a652eff606 | 174 | result -= (year - 1) / 100; |
bonchenko | 0:c3a652eff606 | 175 | result += (year - 1) / 400; |
bonchenko | 0:c3a652eff606 | 176 | } |
bonchenko | 0:c3a652eff606 | 177 | |
bonchenko | 0:c3a652eff606 | 178 | /* Start with 2000 a.d. */ |
bonchenko | 0:c3a652eff606 | 179 | result -= 730485UL; |
bonchenko | 0:c3a652eff606 | 180 | |
bonchenko | 0:c3a652eff606 | 181 | /* Make month an array index */ |
bonchenko | 0:c3a652eff606 | 182 | idx = t->month - 1; |
bonchenko | 0:c3a652eff606 | 183 | |
bonchenko | 0:c3a652eff606 | 184 | /* Loop thru each month, adding the days */ |
bonchenko | 0:c3a652eff606 | 185 | for (i = 0; i < idx; i++) { |
bonchenko | 0:c3a652eff606 | 186 | result += DaysInMonth[i]; |
bonchenko | 0:c3a652eff606 | 187 | } |
bonchenko | 0:c3a652eff606 | 188 | |
bonchenko | 0:c3a652eff606 | 189 | /* Leap year? adjust February */ |
bonchenko | 0:c3a652eff606 | 190 | if (year%400 == 0 || (year%4 == 0 && year%100 !=0)) { |
bonchenko | 0:c3a652eff606 | 191 | ; |
bonchenko | 0:c3a652eff606 | 192 | } else { |
bonchenko | 0:c3a652eff606 | 193 | if (t->month > 1) { |
bonchenko | 0:c3a652eff606 | 194 | result--; |
bonchenko | 0:c3a652eff606 | 195 | } |
bonchenko | 0:c3a652eff606 | 196 | } |
bonchenko | 0:c3a652eff606 | 197 | |
bonchenko | 0:c3a652eff606 | 198 | /* Add remaining days */ |
bonchenko | 0:c3a652eff606 | 199 | result += t->mday; |
bonchenko | 0:c3a652eff606 | 200 | |
bonchenko | 0:c3a652eff606 | 201 | /* Convert to seconds, add all the other stuff */ |
bonchenko | 0:c3a652eff606 | 202 | result = (result-1) * 86400L + (uint32_t)t->hour * 3600 + |
bonchenko | 0:c3a652eff606 | 203 | (uint32_t)t->min * 60 + t->sec; |
bonchenko | 0:c3a652eff606 | 204 | |
bonchenko | 0:c3a652eff606 | 205 | return result; |
bonchenko | 0:c3a652eff606 | 206 | } |
bonchenko | 0:c3a652eff606 | 207 | |
bonchenko | 0:c3a652eff606 | 208 | /******************************************************************************* |
bonchenko | 0:c3a652eff606 | 209 | * Function Name : rtc_gettime |
bonchenko | 0:c3a652eff606 | 210 | * Description : populates structure from HW-RTC, takes DST into account |
bonchenko | 0:c3a652eff606 | 211 | * Input : None |
bonchenko | 0:c3a652eff606 | 212 | * Output : time-struct gets modified |
bonchenko | 0:c3a652eff606 | 213 | * Return : always true/not used |
bonchenko | 0:c3a652eff606 | 214 | *******************************************************************************/ |
bonchenko | 0:c3a652eff606 | 215 | bool rtc_gettime (RTC_t *rtc) |
bonchenko | 0:c3a652eff606 | 216 | { |
bonchenko | 0:c3a652eff606 | 217 | uint32_t t; |
bonchenko | 0:c3a652eff606 | 218 | |
bonchenko | 0:c3a652eff606 | 219 | while ( ( t = RTC_GetCounter() ) != RTC_GetCounter() ) { ; } |
bonchenko | 0:c3a652eff606 | 220 | counter_to_struct( t, rtc ); // get non DST time |
bonchenko | 0:c3a652eff606 | 221 | adjustDST( rtc ); |
bonchenko | 0:c3a652eff606 | 222 | |
bonchenko | 0:c3a652eff606 | 223 | return true; |
bonchenko | 0:c3a652eff606 | 224 | } |
bonchenko | 0:c3a652eff606 | 225 | |
bonchenko | 0:c3a652eff606 | 226 | /******************************************************************************* |
bonchenko | 0:c3a652eff606 | 227 | * Function Name : my_RTC_SetCounter |
bonchenko | 0:c3a652eff606 | 228 | * Description : sets the hardware-counter |
bonchenko | 0:c3a652eff606 | 229 | * Input : new counter-value |
bonchenko | 0:c3a652eff606 | 230 | * Output : None |
bonchenko | 0:c3a652eff606 | 231 | * Return : None |
bonchenko | 0:c3a652eff606 | 232 | *******************************************************************************/ |
bonchenko | 0:c3a652eff606 | 233 | static void my_RTC_SetCounter(uint32_t cnt) |
bonchenko | 0:c3a652eff606 | 234 | { |
bonchenko | 0:c3a652eff606 | 235 | /* Wait until last write operation on RTC registers has finished */ |
bonchenko | 0:c3a652eff606 | 236 | RTC_WaitForLastTask(); |
bonchenko | 0:c3a652eff606 | 237 | /* Change the current time */ |
bonchenko | 0:c3a652eff606 | 238 | RTC_SetCounter(cnt); |
bonchenko | 0:c3a652eff606 | 239 | /* Wait until last write operation on RTC registers has finished */ |
bonchenko | 0:c3a652eff606 | 240 | RTC_WaitForLastTask(); |
bonchenko | 0:c3a652eff606 | 241 | } |
bonchenko | 0:c3a652eff606 | 242 | |
bonchenko | 0:c3a652eff606 | 243 | /******************************************************************************* |
bonchenko | 0:c3a652eff606 | 244 | * Function Name : rtc_settime |
bonchenko | 0:c3a652eff606 | 245 | * Description : sets HW-RTC with values from time-struct, takes DST into |
bonchenko | 0:c3a652eff606 | 246 | * account, HW-RTC always running in non-DST time |
bonchenko | 0:c3a652eff606 | 247 | * Input : None |
bonchenko | 0:c3a652eff606 | 248 | * Output : None |
bonchenko | 0:c3a652eff606 | 249 | * Return : not used |
bonchenko | 0:c3a652eff606 | 250 | *******************************************************************************/ |
bonchenko | 0:c3a652eff606 | 251 | bool rtc_settime (const RTC_t *rtc) |
bonchenko | 0:c3a652eff606 | 252 | { |
bonchenko | 0:c3a652eff606 | 253 | uint32_t cnt; |
bonchenko | 0:c3a652eff606 | 254 | RTC_t ts; |
bonchenko | 0:c3a652eff606 | 255 | |
bonchenko | 0:c3a652eff606 | 256 | cnt = struct_to_counter( rtc ); // non-DST counter-value |
bonchenko | 0:c3a652eff606 | 257 | counter_to_struct( cnt, &ts ); // normalize struct (for weekday) |
bonchenko | 0:c3a652eff606 | 258 | if ( isDST( &ts ) ) { |
bonchenko | 0:c3a652eff606 | 259 | cnt -= 60*60; // Subtract one hour |
bonchenko | 0:c3a652eff606 | 260 | } |
bonchenko | 0:c3a652eff606 | 261 | PWR_BackupAccessCmd(ENABLE); |
bonchenko | 0:c3a652eff606 | 262 | my_RTC_SetCounter( cnt ); |
bonchenko | 0:c3a652eff606 | 263 | PWR_BackupAccessCmd(DISABLE); |
bonchenko | 0:c3a652eff606 | 264 | |
bonchenko | 0:c3a652eff606 | 265 | return true; |
bonchenko | 0:c3a652eff606 | 266 | } |
bonchenko | 0:c3a652eff606 | 267 | |
bonchenko | 0:c3a652eff606 | 268 | /******************************************************************************* |
bonchenko | 0:c3a652eff606 | 269 | * Function Name : rtc_init |
bonchenko | 0:c3a652eff606 | 270 | * Description : initializes HW RTC, |
bonchenko | 0:c3a652eff606 | 271 | * sets default time-stamp if RTC has not been initialized before |
bonchenko | 0:c3a652eff606 | 272 | * Input : None |
bonchenko | 0:c3a652eff606 | 273 | * Output : None |
bonchenko | 0:c3a652eff606 | 274 | * Return : not used |
bonchenko | 0:c3a652eff606 | 275 | * Based on code from a STM RTC example in the StdPeriph-Library package |
bonchenko | 0:c3a652eff606 | 276 | *******************************************************************************/ |
bonchenko | 0:c3a652eff606 | 277 | int rtc_init(void) |
bonchenko | 0:c3a652eff606 | 278 | { |
bonchenko | 0:c3a652eff606 | 279 | volatile uint16_t i; |
bonchenko | 0:c3a652eff606 | 280 | |
bonchenko | 0:c3a652eff606 | 281 | /* Enable PWR and BKP clocks */ |
bonchenko | 0:c3a652eff606 | 282 | RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE); |
bonchenko | 0:c3a652eff606 | 283 | |
bonchenko | 0:c3a652eff606 | 284 | /* LSI clock stabilization time */ |
bonchenko | 0:c3a652eff606 | 285 | for(i=0;i<5000;i++) { ; } |
bonchenko | 0:c3a652eff606 | 286 | |
bonchenko | 0:c3a652eff606 | 287 | if (BKP_ReadBackupRegister(BKP_DR1) != 0xA5A5) { |
bonchenko | 0:c3a652eff606 | 288 | /* Backup data register value is not correct or not yet programmed (when |
bonchenko | 0:c3a652eff606 | 289 | the first time the program is executed) */ |
bonchenko | 0:c3a652eff606 | 290 | |
bonchenko | 0:c3a652eff606 | 291 | /* Allow access to BKP Domain */ |
bonchenko | 0:c3a652eff606 | 292 | PWR_BackupAccessCmd(ENABLE); |
bonchenko | 0:c3a652eff606 | 293 | |
bonchenko | 0:c3a652eff606 | 294 | /* Reset Backup Domain */ |
bonchenko | 0:c3a652eff606 | 295 | BKP_DeInit(); |
bonchenko | 0:c3a652eff606 | 296 | |
bonchenko | 0:c3a652eff606 | 297 | /* Enable LSE */ |
bonchenko | 0:c3a652eff606 | 298 | RCC_LSEConfig(RCC_LSE_ON); |
bonchenko | 0:c3a652eff606 | 299 | |
bonchenko | 0:c3a652eff606 | 300 | /* Wait till LSE is ready */ |
bonchenko | 0:c3a652eff606 | 301 | while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET) { ; } |
bonchenko | 0:c3a652eff606 | 302 | |
bonchenko | 0:c3a652eff606 | 303 | /* Select LSE as RTC Clock Source */ |
bonchenko | 0:c3a652eff606 | 304 | RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE); |
bonchenko | 0:c3a652eff606 | 305 | |
bonchenko | 0:c3a652eff606 | 306 | /* Enable RTC Clock */ |
bonchenko | 0:c3a652eff606 | 307 | RCC_RTCCLKCmd(ENABLE); |
bonchenko | 0:c3a652eff606 | 308 | |
bonchenko | 0:c3a652eff606 | 309 | /* Wait for RTC registers synchronization */ |
bonchenko | 0:c3a652eff606 | 310 | RTC_WaitForSynchro(); |
bonchenko | 0:c3a652eff606 | 311 | |
bonchenko | 0:c3a652eff606 | 312 | /* Wait until last write operation on RTC registers has finished */ |
bonchenko | 0:c3a652eff606 | 313 | RTC_WaitForLastTask(); |
bonchenko | 0:c3a652eff606 | 314 | |
bonchenko | 0:c3a652eff606 | 315 | /* Set RTC prescaler: set RTC period to 1sec */ |
bonchenko | 0:c3a652eff606 | 316 | RTC_SetPrescaler(32767); /* RTC period = RTCCLK/RTC_PR = (32.768 KHz)/(32767+1) */ |
bonchenko | 0:c3a652eff606 | 317 | |
bonchenko | 0:c3a652eff606 | 318 | /* Wait until last write operation on RTC registers has finished */ |
bonchenko | 0:c3a652eff606 | 319 | RTC_WaitForLastTask(); |
bonchenko | 0:c3a652eff606 | 320 | |
bonchenko | 0:c3a652eff606 | 321 | /* Set initial value */ |
bonchenko | 0:c3a652eff606 | 322 | RTC_SetCounter( (uint32_t)((11*60+55)*60) ); // here: 1st January 2000 11:55:00 |
bonchenko | 0:c3a652eff606 | 323 | |
bonchenko | 0:c3a652eff606 | 324 | /* Wait until last write operation on RTC registers has finished */ |
bonchenko | 0:c3a652eff606 | 325 | RTC_WaitForLastTask(); |
bonchenko | 0:c3a652eff606 | 326 | |
bonchenko | 0:c3a652eff606 | 327 | BKP_WriteBackupRegister(BKP_DR1, 0xA5A5); |
bonchenko | 0:c3a652eff606 | 328 | |
bonchenko | 0:c3a652eff606 | 329 | /* Lock access to BKP Domain */ |
bonchenko | 0:c3a652eff606 | 330 | PWR_BackupAccessCmd(DISABLE); |
bonchenko | 0:c3a652eff606 | 331 | |
bonchenko | 0:c3a652eff606 | 332 | } else { |
bonchenko | 0:c3a652eff606 | 333 | |
bonchenko | 0:c3a652eff606 | 334 | /* Wait for RTC registers synchronization */ |
bonchenko | 0:c3a652eff606 | 335 | RTC_WaitForSynchro(); |
bonchenko | 0:c3a652eff606 | 336 | |
bonchenko | 0:c3a652eff606 | 337 | } |
bonchenko | 0:c3a652eff606 | 338 | |
bonchenko | 0:c3a652eff606 | 339 | return 0; |
bonchenko | 0:c3a652eff606 | 340 | } |
bonchenko | 0:c3a652eff606 | 341 | |
bonchenko | 0:c3a652eff606 | 342 | |
bonchenko | 0:c3a652eff606 | 343 |