Bootload from SD card to sector 0, and jump to sector 24 where new firmware resides
Fork of Panel-Controller-Bootloader by
rtc.c@2:0fa89ba8f6fe, 2015-04-22 (annotated)
- Committer:
- bonchenko
- Date:
- Wed Apr 22 10:18:55 2015 +0000
- Revision:
- 2:0fa89ba8f6fe
- Parent:
- 0:c3a652eff606
Bootloader from SD card works perfectly. Compiled with offset in EmBlocks, ADE cannot print readings - but its happened without bootloader too. The problem is Emblocks compiler settings
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 |