This is a RTC additional function. This is only for Nucleo F401RE & F411RE mbed(Added L152RE, F334R8, L476RG & F746xx). If you connected battery backup circuit for internal RTC, you can make a power-off and reset condition. RTC still has proper time and date.

Dependents:   Nucleo_rtos_sample PB_Emma_Ethernet

Please refer following NOTE information.
/users/kenjiArai/notebook/nucleo-series-rtc-control-under-power-onoff-and-re/

Committer:
kenjiArai
Date:
Thu Feb 19 02:56:12 2015 +0000
Revision:
6:ef7d2c83034d
Parent:
5:1a8e7aed053d
Child:
7:fa32602e23ec
Child:
9:1af4e107ca7b
Bug fix when External Xtal is not avairable. In addtion change checking method for STM32xxx register status

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kenjiArai 0:e4c20fd769f1 1 /*
kenjiArai 0:e4c20fd769f1 2 * mbed Library program
kenjiArai 0:e4c20fd769f1 3 * Check & set RTC function and set proper clock if we can set
kenjiArai 0:e4c20fd769f1 4 * ONLY FOR "Nucleo Board"
kenjiArai 0:e4c20fd769f1 5 *
kenjiArai 0:e4c20fd769f1 6 * Copyright (c) 2014-2015 Kenji Arai / JH1PJL
kenjiArai 0:e4c20fd769f1 7 * http://www.page.sannet.ne.jp/kenjia/index.html
kenjiArai 0:e4c20fd769f1 8 * http://mbed.org/users/kenjiArai/
kenjiArai 0:e4c20fd769f1 9 * Created: October 24th, 2014
kenjiArai 6:ef7d2c83034d 10 * Revised: Feburary 19th, 2015
kenjiArai 0:e4c20fd769f1 11 *
kenjiArai 0:e4c20fd769f1 12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
kenjiArai 0:e4c20fd769f1 13 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
kenjiArai 0:e4c20fd769f1 14 * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
kenjiArai 0:e4c20fd769f1 15 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
kenjiArai 0:e4c20fd769f1 16 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
kenjiArai 0:e4c20fd769f1 17 */
kenjiArai 0:e4c20fd769f1 18
kenjiArai 0:e4c20fd769f1 19 #if defined(TARGET_NUCLEO_F401RE) || defined(TARGET_NUCLEO_F411RE) || defined(TARGET_NUCLEO_L152RE)
kenjiArai 0:e4c20fd769f1 20
kenjiArai 0:e4c20fd769f1 21 //#define DEBUG // use Communication with PC(UART)
kenjiArai 0:e4c20fd769f1 22
kenjiArai 0:e4c20fd769f1 23 // Include ---------------------------------------------------------------------------------------
kenjiArai 0:e4c20fd769f1 24 #include "mbed.h"
kenjiArai 0:e4c20fd769f1 25 #include "SetRTC.h"
kenjiArai 0:e4c20fd769f1 26
kenjiArai 0:e4c20fd769f1 27 // Definition ------------------------------------------------------------------------------------
kenjiArai 0:e4c20fd769f1 28 #ifdef DEBUG
kenjiArai 0:e4c20fd769f1 29 #define BAUD(x) pcr.baud(x)
kenjiArai 0:e4c20fd769f1 30 #define GETC(x) pcr.getc(x)
kenjiArai 0:e4c20fd769f1 31 #define PUTC(x) pcr.putc(x)
kenjiArai 0:e4c20fd769f1 32 #define PRINTF(...) pcr.printf(__VA_ARGS__)
kenjiArai 0:e4c20fd769f1 33 #define READABLE(x) pcr.readable(x)
kenjiArai 0:e4c20fd769f1 34 #else
kenjiArai 0:e4c20fd769f1 35 #define BAUD(x) {;}
kenjiArai 0:e4c20fd769f1 36 #define GETC(x) {;}
kenjiArai 0:e4c20fd769f1 37 #define PUTC(x) {;}
kenjiArai 0:e4c20fd769f1 38 #define PRINTF(...) {;}
kenjiArai 0:e4c20fd769f1 39 #define READABLE(x) {;}
kenjiArai 0:e4c20fd769f1 40 #endif
kenjiArai 0:e4c20fd769f1 41
kenjiArai 0:e4c20fd769f1 42 // Object ----------------------------------------------------------------------------------------
kenjiArai 0:e4c20fd769f1 43 Serial pcr(USBTX, USBRX);
kenjiArai 0:e4c20fd769f1 44
kenjiArai 0:e4c20fd769f1 45 // RAM -------------------------------------------------------------------------------------------
kenjiArai 0:e4c20fd769f1 46
kenjiArai 0:e4c20fd769f1 47 // ROM / Constant data ---------------------------------------------------------------------------
kenjiArai 0:e4c20fd769f1 48
kenjiArai 0:e4c20fd769f1 49 // Function prototypes ---------------------------------------------------------------------------
kenjiArai 0:e4c20fd769f1 50 static int32_t set_RTC_LSI(void);
kenjiArai 0:e4c20fd769f1 51 static int32_t set_RTC_LSE(void);
kenjiArai 0:e4c20fd769f1 52 static int32_t rtc_external_osc_init(void);
kenjiArai 0:e4c20fd769f1 53 static uint32_t read_RTC_reg(uint32_t RTC_BKP_DR);
kenjiArai 0:e4c20fd769f1 54 static uint32_t check_RTC_backup_reg( void );
kenjiArai 0:e4c20fd769f1 55 static int xatoi (char **str, unsigned long *res);
kenjiArai 0:e4c20fd769f1 56 static void get_line (char *buff, int len);
kenjiArai 2:765470eab2a6 57 static void set_5v_drop_detect(void);
kenjiArai 0:e4c20fd769f1 58
kenjiArai 0:e4c20fd769f1 59 //-------------------------------------------------------------------------------------------------
kenjiArai 0:e4c20fd769f1 60 // Control Program
kenjiArai 0:e4c20fd769f1 61 //-------------------------------------------------------------------------------------------------
kenjiArai 0:e4c20fd769f1 62 int32_t SetRTC()
kenjiArai 0:e4c20fd769f1 63 {
kenjiArai 6:ef7d2c83034d 64 if (rtc_external_osc_init() == 1) {
kenjiArai 2:765470eab2a6 65 set_5v_drop_detect();
kenjiArai 6:ef7d2c83034d 66 return 1;
kenjiArai 0:e4c20fd769f1 67 } else {
kenjiArai 6:ef7d2c83034d 68 return 0;
kenjiArai 0:e4c20fd769f1 69 }
kenjiArai 0:e4c20fd769f1 70 }
kenjiArai 0:e4c20fd769f1 71
kenjiArai 0:e4c20fd769f1 72 int32_t set_RTC_LSE(void)
kenjiArai 0:e4c20fd769f1 73 {
kenjiArai 0:e4c20fd769f1 74 uint32_t timeout = 0;
kenjiArai 0:e4c20fd769f1 75
kenjiArai 0:e4c20fd769f1 76 //---------------------------- LSE Configuration -------------------------
kenjiArai 0:e4c20fd769f1 77 // Enable Power Clock
kenjiArai 0:e4c20fd769f1 78 __PWR_CLK_ENABLE();
kenjiArai 0:e4c20fd769f1 79 // Enable write access to Backup domain
kenjiArai 0:e4c20fd769f1 80 PWR->CR |= PWR_CR_DBP;
kenjiArai 0:e4c20fd769f1 81 // Wait for Backup domain Write protection disable
kenjiArai 0:e4c20fd769f1 82 timeout = HAL_GetTick() + DBP_TIMEOUT_VALUE;
kenjiArai 6:ef7d2c83034d 83 PRINTF("Time-Out %d\r\n", timeout);
kenjiArai 0:e4c20fd769f1 84 while((PWR->CR & PWR_CR_DBP) == RESET) {
kenjiArai 0:e4c20fd769f1 85 if(HAL_GetTick() >= timeout) {
kenjiArai 0:e4c20fd769f1 86 PRINTF("Time-Out 1\r\n");
kenjiArai 6:ef7d2c83034d 87 return 0;
kenjiArai 6:ef7d2c83034d 88 } else {
kenjiArai 6:ef7d2c83034d 89 PRINTF("GetTick: %d\r\n",HAL_GetTick());
kenjiArai 0:e4c20fd769f1 90 }
kenjiArai 0:e4c20fd769f1 91 }
kenjiArai 0:e4c20fd769f1 92 // Reset LSEON and LSEBYP bits before configuring the LSE ----------------
kenjiArai 0:e4c20fd769f1 93 __HAL_RCC_LSE_CONFIG(RCC_LSE_OFF);
kenjiArai 0:e4c20fd769f1 94 // Get timeout
kenjiArai 0:e4c20fd769f1 95 timeout = HAL_GetTick() + TIMEOUT;
kenjiArai 6:ef7d2c83034d 96 PRINTF("Time-Out %d\r\n", timeout);
kenjiArai 0:e4c20fd769f1 97 // Wait till LSE is ready
kenjiArai 0:e4c20fd769f1 98 while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) != RESET) {
kenjiArai 0:e4c20fd769f1 99 if(HAL_GetTick() >= timeout) {
kenjiArai 0:e4c20fd769f1 100 PRINTF("Time-Out 2\r\n");
kenjiArai 6:ef7d2c83034d 101 return 0;
kenjiArai 6:ef7d2c83034d 102 } else {
kenjiArai 6:ef7d2c83034d 103 PRINTF("GetTick: %d\r\n",HAL_GetTick());
kenjiArai 0:e4c20fd769f1 104 }
kenjiArai 0:e4c20fd769f1 105 }
kenjiArai 0:e4c20fd769f1 106 // Set the new LSE configuration -----------------------------------------
kenjiArai 0:e4c20fd769f1 107 __HAL_RCC_LSE_CONFIG(RCC_LSE_ON);
kenjiArai 0:e4c20fd769f1 108 // Get timeout
kenjiArai 0:e4c20fd769f1 109 timeout = HAL_GetTick() + TIMEOUT;
kenjiArai 6:ef7d2c83034d 110 PRINTF("Time-Out %d\r\n", timeout);
kenjiArai 0:e4c20fd769f1 111 // Wait till LSE is ready
kenjiArai 6:ef7d2c83034d 112 #if defined(TARGET_NUCLEO_F401RE) || defined(TARGET_NUCLEO_F411RE)
kenjiArai 6:ef7d2c83034d 113 while((RCC->BDCR & 0x02) != 2){
kenjiArai 6:ef7d2c83034d 114 #else
kenjiArai 0:e4c20fd769f1 115 while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET) {
kenjiArai 6:ef7d2c83034d 116 #endif
kenjiArai 6:ef7d2c83034d 117 // while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET) {
kenjiArai 0:e4c20fd769f1 118 if(HAL_GetTick() >= timeout) {
kenjiArai 0:e4c20fd769f1 119 PRINTF("Time-Out 3\r\n");
kenjiArai 6:ef7d2c83034d 120 return 0;
kenjiArai 6:ef7d2c83034d 121 } else {
kenjiArai 6:ef7d2c83034d 122 PRINTF("GetTick: %d\r\n",HAL_GetTick());
kenjiArai 0:e4c20fd769f1 123 }
kenjiArai 0:e4c20fd769f1 124 }
kenjiArai 6:ef7d2c83034d 125 PRINTF("OK\r\n");
kenjiArai 6:ef7d2c83034d 126 return 1;
kenjiArai 0:e4c20fd769f1 127 }
kenjiArai 0:e4c20fd769f1 128
kenjiArai 0:e4c20fd769f1 129 int32_t set_RTC_LSI(void)
kenjiArai 0:e4c20fd769f1 130 {
kenjiArai 0:e4c20fd769f1 131 uint32_t timeout = 0;
kenjiArai 0:e4c20fd769f1 132
kenjiArai 0:e4c20fd769f1 133 // Enable Power clock
kenjiArai 0:e4c20fd769f1 134 __PWR_CLK_ENABLE();
kenjiArai 0:e4c20fd769f1 135 // Enable access to Backup domain
kenjiArai 0:e4c20fd769f1 136 HAL_PWR_EnableBkUpAccess();
kenjiArai 0:e4c20fd769f1 137 // Reset Backup domain
kenjiArai 0:e4c20fd769f1 138 __HAL_RCC_BACKUPRESET_FORCE();
kenjiArai 0:e4c20fd769f1 139 __HAL_RCC_BACKUPRESET_RELEASE();
kenjiArai 0:e4c20fd769f1 140 // Enable Power Clock
kenjiArai 0:e4c20fd769f1 141 __PWR_CLK_ENABLE();
kenjiArai 0:e4c20fd769f1 142 // Enable write access to Backup domain
kenjiArai 0:e4c20fd769f1 143 PWR->CR |= PWR_CR_DBP;
kenjiArai 0:e4c20fd769f1 144 // Wait for Backup domain Write protection disable
kenjiArai 0:e4c20fd769f1 145 timeout = HAL_GetTick() + DBP_TIMEOUT_VALUE;
kenjiArai 0:e4c20fd769f1 146 while((PWR->CR & PWR_CR_DBP) == RESET) {
kenjiArai 0:e4c20fd769f1 147 if(HAL_GetTick() >= timeout) {
kenjiArai 6:ef7d2c83034d 148 return 0;
kenjiArai 0:e4c20fd769f1 149 }
kenjiArai 0:e4c20fd769f1 150 }
kenjiArai 0:e4c20fd769f1 151 __HAL_RCC_LSE_CONFIG(RCC_LSE_OFF);
kenjiArai 0:e4c20fd769f1 152 // Enable LSI
kenjiArai 0:e4c20fd769f1 153 __HAL_RCC_LSI_ENABLE();
kenjiArai 0:e4c20fd769f1 154 timeout = HAL_GetTick() + TIMEOUT;
kenjiArai 0:e4c20fd769f1 155 // Wait till LSI is ready
kenjiArai 0:e4c20fd769f1 156 while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSIRDY) == RESET) {
kenjiArai 0:e4c20fd769f1 157 if(HAL_GetTick() >= timeout) {
kenjiArai 6:ef7d2c83034d 158 return 0;
kenjiArai 0:e4c20fd769f1 159 }
kenjiArai 0:e4c20fd769f1 160 }
kenjiArai 0:e4c20fd769f1 161 // Connect LSI to RTC
kenjiArai 0:e4c20fd769f1 162 __HAL_RCC_RTC_CLKPRESCALER(RCC_RTCCLKSOURCE_LSI);
kenjiArai 0:e4c20fd769f1 163 __HAL_RCC_RTC_CONFIG(RCC_RTCCLKSOURCE_LSI);
kenjiArai 6:ef7d2c83034d 164 return 1;
kenjiArai 0:e4c20fd769f1 165 }
kenjiArai 0:e4c20fd769f1 166
kenjiArai 0:e4c20fd769f1 167 int32_t rtc_external_osc_init(void)
kenjiArai 0:e4c20fd769f1 168 {
kenjiArai 6:ef7d2c83034d 169 uint32_t timeout = 0;
kenjiArai 6:ef7d2c83034d 170 time_t seconds;
kenjiArai 6:ef7d2c83034d 171 uint8_t external_ok = 1;
kenjiArai 6:ef7d2c83034d 172
kenjiArai 0:e4c20fd769f1 173 // Enable Power clock
kenjiArai 0:e4c20fd769f1 174 __PWR_CLK_ENABLE();
kenjiArai 0:e4c20fd769f1 175 // Enable access to Backup domain
kenjiArai 0:e4c20fd769f1 176 HAL_PWR_EnableBkUpAccess();
kenjiArai 0:e4c20fd769f1 177 // Check backup condition
kenjiArai 0:e4c20fd769f1 178 if ( check_RTC_backup_reg() ) {
kenjiArai 6:ef7d2c83034d 179 #if defined(TARGET_NUCLEO_F401RE) || defined(TARGET_NUCLEO_F411RE)
kenjiArai 6:ef7d2c83034d 180 if ((RCC->BDCR & 0x8307) == 0x8103){
kenjiArai 6:ef7d2c83034d 181 #else
kenjiArai 6:ef7d2c83034d 182 if ((RCC->CSR & 0x430703) == 0x410300) {
kenjiArai 6:ef7d2c83034d 183 #endif
kenjiArai 6:ef7d2c83034d 184 //if (__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) != RESET) {
kenjiArai 6:ef7d2c83034d 185 timeout = HAL_GetTick() + TIMEOUT / 5;
kenjiArai 6:ef7d2c83034d 186 seconds = time(NULL);
kenjiArai 6:ef7d2c83034d 187 while (seconds == time(NULL)){
kenjiArai 6:ef7d2c83034d 188 if(HAL_GetTick() >= timeout) {
kenjiArai 6:ef7d2c83034d 189 PRINTF("Not available External Xtal\r\n");
kenjiArai 6:ef7d2c83034d 190 external_ok = 0;
kenjiArai 6:ef7d2c83034d 191 break;
kenjiArai 6:ef7d2c83034d 192 }
kenjiArai 6:ef7d2c83034d 193 }
kenjiArai 6:ef7d2c83034d 194 if (external_ok){
kenjiArai 6:ef7d2c83034d 195 PRINTF("OK everything\r\n");
kenjiArai 6:ef7d2c83034d 196 return 1;
kenjiArai 6:ef7d2c83034d 197 }
kenjiArai 6:ef7d2c83034d 198 }
kenjiArai 6:ef7d2c83034d 199 }
kenjiArai 6:ef7d2c83034d 200 PRINTF("Reset RTC LSE config.\r\n");
kenjiArai 6:ef7d2c83034d 201 // Reset Backup domain
kenjiArai 6:ef7d2c83034d 202 __HAL_RCC_BACKUPRESET_FORCE();
kenjiArai 6:ef7d2c83034d 203 __HAL_RCC_BACKUPRESET_RELEASE();
kenjiArai 6:ef7d2c83034d 204 // Enable LSE Oscillator
kenjiArai 6:ef7d2c83034d 205 if (set_RTC_LSE() == 1) {
kenjiArai 6:ef7d2c83034d 206 // Connect LSE to RTC
kenjiArai 6:ef7d2c83034d 207 __HAL_RCC_RTC_CLKPRESCALER(RCC_RTCCLKSOURCE_LSE);
kenjiArai 6:ef7d2c83034d 208 __HAL_RCC_RTC_CONFIG(RCC_RTCCLKSOURCE_LSE);
kenjiArai 6:ef7d2c83034d 209 PRINTF("Set LSE/External\r\n");
kenjiArai 6:ef7d2c83034d 210 return 1;
kenjiArai 0:e4c20fd769f1 211 } else {
kenjiArai 6:ef7d2c83034d 212 set_RTC_LSI();
kenjiArai 6:ef7d2c83034d 213 PRINTF("Set LSI/Internal\r\n");
kenjiArai 6:ef7d2c83034d 214 return 0;
kenjiArai 0:e4c20fd769f1 215 }
kenjiArai 0:e4c20fd769f1 216 }
kenjiArai 0:e4c20fd769f1 217
kenjiArai 0:e4c20fd769f1 218 uint32_t read_RTC_reg(uint32_t RTC_BKP_DR)
kenjiArai 0:e4c20fd769f1 219 {
kenjiArai 0:e4c20fd769f1 220 __IO uint32_t tmp = 0;
kenjiArai 0:e4c20fd769f1 221
kenjiArai 0:e4c20fd769f1 222 // Check the parameters
kenjiArai 0:e4c20fd769f1 223 assert_param(IS_RTC_BKP(RTC_BKP_DR));
kenjiArai 0:e4c20fd769f1 224 tmp = RTC_BASE + 0x50;
kenjiArai 0:e4c20fd769f1 225 tmp += (RTC_BKP_DR * 4);
kenjiArai 0:e4c20fd769f1 226 // Read the specified register
kenjiArai 0:e4c20fd769f1 227 return (*(__IO uint32_t *)tmp);
kenjiArai 0:e4c20fd769f1 228 }
kenjiArai 0:e4c20fd769f1 229
kenjiArai 0:e4c20fd769f1 230 // Check RTC Backup registers contents
kenjiArai 0:e4c20fd769f1 231 uint32_t check_RTC_backup_reg( void )
kenjiArai 0:e4c20fd769f1 232 {
kenjiArai 0:e4c20fd769f1 233 if ( read_RTC_reg( RTC_BKP_DR0 ) == RTC_DAT0 ) {
kenjiArai 0:e4c20fd769f1 234 if ( read_RTC_reg( RTC_BKP_DR1 ) == RTC_DAT1 ) {
kenjiArai 0:e4c20fd769f1 235 return 1;
kenjiArai 0:e4c20fd769f1 236 }
kenjiArai 0:e4c20fd769f1 237 }
kenjiArai 0:e4c20fd769f1 238 return 0;
kenjiArai 0:e4c20fd769f1 239 }
kenjiArai 0:e4c20fd769f1 240
kenjiArai 0:e4c20fd769f1 241 void show_RTC_reg( void )
kenjiArai 0:e4c20fd769f1 242 {
kenjiArai 0:e4c20fd769f1 243 // Show registers
kenjiArai 6:ef7d2c83034d 244 pcr.printf( "\r\nShow RTC registers\r\n" );
kenjiArai 0:e4c20fd769f1 245 pcr.printf( " Reg0 =0x%08x, Reg1 =0x%08x\r\n",
kenjiArai 0:e4c20fd769f1 246 read_RTC_reg( RTC_BKP_DR0 ),
kenjiArai 0:e4c20fd769f1 247 read_RTC_reg( RTC_BKP_DR1 )
kenjiArai 0:e4c20fd769f1 248 );
kenjiArai 0:e4c20fd769f1 249 pcr.printf( " TR =0x..%06x, DR =0x..%06x, CR =0x..%06x\r\n",
kenjiArai 0:e4c20fd769f1 250 RTC->TR, RTC->DR, RTC->CR
kenjiArai 0:e4c20fd769f1 251 );
kenjiArai 0:e4c20fd769f1 252 pcr.printf( " ISR =0x...%05x, PRER =0x..%06x, WUTR =0x....%04x\r\n",
kenjiArai 0:e4c20fd769f1 253 RTC->ISR, RTC->PRER, RTC->WUTR
kenjiArai 0:e4c20fd769f1 254 );
kenjiArai 0:e4c20fd769f1 255 pcr.printf( " CALIBR=0x....%04x, ALRMAR=0x%08x, ALRMBR=0x%08x\r\n",
kenjiArai 0:e4c20fd769f1 256 RTC->CALIBR, RTC->ALRMAR, RTC->ALRMBR
kenjiArai 0:e4c20fd769f1 257 );
kenjiArai 0:e4c20fd769f1 258 pcr.printf(
kenjiArai 0:e4c20fd769f1 259 " WPR =0x......%02x, SSR =0x....%04x, SHIFTR=0x....%04x\r\n",
kenjiArai 0:e4c20fd769f1 260 RTC->WPR, RTC->SSR, RTC->SHIFTR
kenjiArai 0:e4c20fd769f1 261 );
kenjiArai 0:e4c20fd769f1 262 pcr.printf(
kenjiArai 6:ef7d2c83034d 263 " TSTR =0x..%06x, TSDR =0x....%04x, TSSSR =0x....%04x\r\n",
kenjiArai 0:e4c20fd769f1 264 RTC->TSTR, RTC->TSDR, RTC->TSSSR
kenjiArai 0:e4c20fd769f1 265 );
kenjiArai 6:ef7d2c83034d 266 pcr.printf( "Show RCC registers (only RTC Related reg.)\r\n" );
kenjiArai 6:ef7d2c83034d 267 #if defined(TARGET_NUCLEO_F401RE) || defined(TARGET_NUCLEO_F411RE)
kenjiArai 6:ef7d2c83034d 268 pcr.printf( " RCC_BDCR=0x...%05x\r\n", RCC->BDCR);
kenjiArai 6:ef7d2c83034d 269 #else
kenjiArai 6:ef7d2c83034d 270 pcr.printf( " RCC_CSR =0x%08x\r\n", RCC->CSR);
kenjiArai 6:ef7d2c83034d 271 #endif
kenjiArai 6:ef7d2c83034d 272 pcr.printf( "\r\n");
kenjiArai 0:e4c20fd769f1 273 }
kenjiArai 0:e4c20fd769f1 274
kenjiArai 0:e4c20fd769f1 275 // Change string -> integer
kenjiArai 0:e4c20fd769f1 276 int xatoi (char **str, unsigned long *res)
kenjiArai 0:e4c20fd769f1 277 {
kenjiArai 0:e4c20fd769f1 278 unsigned long val;
kenjiArai 0:e4c20fd769f1 279 unsigned char c, radix, s = 0;
kenjiArai 0:e4c20fd769f1 280
kenjiArai 0:e4c20fd769f1 281 while ((c = **str) == ' ') (*str)++;
kenjiArai 0:e4c20fd769f1 282 if (c == '-') {
kenjiArai 0:e4c20fd769f1 283 s = 1;
kenjiArai 0:e4c20fd769f1 284 c = *(++(*str));
kenjiArai 0:e4c20fd769f1 285 }
kenjiArai 0:e4c20fd769f1 286 if (c == '0') {
kenjiArai 0:e4c20fd769f1 287 c = *(++(*str));
kenjiArai 0:e4c20fd769f1 288 if (c <= ' ') {
kenjiArai 0:e4c20fd769f1 289 *res = 0;
kenjiArai 0:e4c20fd769f1 290 return 1;
kenjiArai 0:e4c20fd769f1 291 }
kenjiArai 0:e4c20fd769f1 292 if (c == 'x') {
kenjiArai 0:e4c20fd769f1 293 radix = 16;
kenjiArai 0:e4c20fd769f1 294 c = *(++(*str));
kenjiArai 0:e4c20fd769f1 295 } else {
kenjiArai 0:e4c20fd769f1 296 if (c == 'b') {
kenjiArai 0:e4c20fd769f1 297 radix = 2;
kenjiArai 0:e4c20fd769f1 298 c = *(++(*str));
kenjiArai 0:e4c20fd769f1 299 } else {
kenjiArai 0:e4c20fd769f1 300 if ((c >= '0')&&(c <= '9')) {
kenjiArai 0:e4c20fd769f1 301 radix = 8;
kenjiArai 0:e4c20fd769f1 302 } else {
kenjiArai 0:e4c20fd769f1 303 return 0;
kenjiArai 0:e4c20fd769f1 304 }
kenjiArai 0:e4c20fd769f1 305 }
kenjiArai 0:e4c20fd769f1 306 }
kenjiArai 0:e4c20fd769f1 307 } else {
kenjiArai 0:e4c20fd769f1 308 if ((c < '1')||(c > '9')) {
kenjiArai 0:e4c20fd769f1 309 return 0;
kenjiArai 0:e4c20fd769f1 310 }
kenjiArai 0:e4c20fd769f1 311 radix = 10;
kenjiArai 0:e4c20fd769f1 312 }
kenjiArai 0:e4c20fd769f1 313 val = 0;
kenjiArai 0:e4c20fd769f1 314 while (c > ' ') {
kenjiArai 0:e4c20fd769f1 315 if (c >= 'a') c -= 0x20;
kenjiArai 0:e4c20fd769f1 316 c -= '0';
kenjiArai 0:e4c20fd769f1 317 if (c >= 17) {
kenjiArai 0:e4c20fd769f1 318 c -= 7;
kenjiArai 0:e4c20fd769f1 319 if (c <= 9) return 0;
kenjiArai 0:e4c20fd769f1 320 }
kenjiArai 0:e4c20fd769f1 321 if (c >= radix) return 0;
kenjiArai 0:e4c20fd769f1 322 val = val * radix + c;
kenjiArai 0:e4c20fd769f1 323 c = *(++(*str));
kenjiArai 0:e4c20fd769f1 324 }
kenjiArai 0:e4c20fd769f1 325 if (s) val = -val;
kenjiArai 0:e4c20fd769f1 326 *res = val;
kenjiArai 0:e4c20fd769f1 327 return 1;
kenjiArai 0:e4c20fd769f1 328 }
kenjiArai 0:e4c20fd769f1 329
kenjiArai 0:e4c20fd769f1 330 // Get key input data
kenjiArai 0:e4c20fd769f1 331 void get_line (char *buff, int len)
kenjiArai 0:e4c20fd769f1 332 {
kenjiArai 0:e4c20fd769f1 333 char c;
kenjiArai 0:e4c20fd769f1 334 int idx = 0;
kenjiArai 0:e4c20fd769f1 335
kenjiArai 0:e4c20fd769f1 336 for (;;) {
kenjiArai 0:e4c20fd769f1 337 c = pcr.getc();
kenjiArai 0:e4c20fd769f1 338 if (c == '\r') {
kenjiArai 0:e4c20fd769f1 339 buff[idx++] = c;
kenjiArai 0:e4c20fd769f1 340 break;
kenjiArai 0:e4c20fd769f1 341 }
kenjiArai 0:e4c20fd769f1 342 if ((c == '\b') && idx) {
kenjiArai 0:e4c20fd769f1 343 idx--;
kenjiArai 0:e4c20fd769f1 344 pcr.putc(c);
kenjiArai 0:e4c20fd769f1 345 pcr.putc(' ');
kenjiArai 0:e4c20fd769f1 346 pcr.putc(c);
kenjiArai 0:e4c20fd769f1 347 }
kenjiArai 0:e4c20fd769f1 348 if (((uint8_t)c >= ' ') && (idx < len - 1)) {
kenjiArai 0:e4c20fd769f1 349 buff[idx++] = c;
kenjiArai 0:e4c20fd769f1 350 pcr.putc(c);
kenjiArai 0:e4c20fd769f1 351 }
kenjiArai 0:e4c20fd769f1 352 }
kenjiArai 0:e4c20fd769f1 353 buff[idx] = 0;
kenjiArai 0:e4c20fd769f1 354 pcr.putc('\n');
kenjiArai 0:e4c20fd769f1 355 }
kenjiArai 0:e4c20fd769f1 356
kenjiArai 0:e4c20fd769f1 357 // RTC related subroutines
kenjiArai 0:e4c20fd769f1 358 void chk_and_set_time(char *ptr)
kenjiArai 0:e4c20fd769f1 359 {
kenjiArai 0:e4c20fd769f1 360 unsigned long p1;
kenjiArai 0:e4c20fd769f1 361 struct tm t;
kenjiArai 0:e4c20fd769f1 362 time_t seconds;
kenjiArai 0:e4c20fd769f1 363
kenjiArai 0:e4c20fd769f1 364 if (xatoi(&ptr, &p1)) {
kenjiArai 0:e4c20fd769f1 365 t.tm_year = (uint8_t)p1 + 100;
kenjiArai 0:e4c20fd769f1 366 PRINTF("Year:%d ",p1);
kenjiArai 0:e4c20fd769f1 367 xatoi( &ptr, &p1 );
kenjiArai 0:e4c20fd769f1 368 t.tm_mon = (uint8_t)p1 - 1;
kenjiArai 0:e4c20fd769f1 369 PRINTF("Month:%d ",p1);
kenjiArai 0:e4c20fd769f1 370 xatoi( &ptr, &p1 );
kenjiArai 0:e4c20fd769f1 371 t.tm_mday = (uint8_t)p1;
kenjiArai 0:e4c20fd769f1 372 PRINTF("Day:%d ",p1);
kenjiArai 0:e4c20fd769f1 373 xatoi( &ptr, &p1 );
kenjiArai 0:e4c20fd769f1 374 t.tm_hour = (uint8_t)p1;
kenjiArai 0:e4c20fd769f1 375 PRINTF("Hour:%d ",p1);
kenjiArai 0:e4c20fd769f1 376 xatoi( &ptr, &p1 );
kenjiArai 0:e4c20fd769f1 377 t.tm_min = (uint8_t)p1;
kenjiArai 0:e4c20fd769f1 378 PRINTF("Min:%d ",p1);
kenjiArai 0:e4c20fd769f1 379 xatoi( &ptr, &p1 );
kenjiArai 0:e4c20fd769f1 380 t.tm_sec = (uint8_t)p1;
kenjiArai 0:e4c20fd769f1 381 PRINTF("Sec: %d \r\n",p1);
kenjiArai 0:e4c20fd769f1 382 } else {
kenjiArai 0:e4c20fd769f1 383 return;
kenjiArai 0:e4c20fd769f1 384 }
kenjiArai 0:e4c20fd769f1 385 seconds = mktime(&t);
kenjiArai 0:e4c20fd769f1 386 set_time(seconds);
kenjiArai 0:e4c20fd769f1 387 // Show Time with several example
kenjiArai 0:e4c20fd769f1 388 // ex.1
kenjiArai 0:e4c20fd769f1 389 pcr.printf("Date: %04d/%02d/%02d, %02d:%02d:%02d\r\n",
kenjiArai 2:765470eab2a6 390 t.tm_year + 1900, t.tm_mon + 1, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec);
kenjiArai 0:e4c20fd769f1 391 #if 0
kenjiArai 0:e4c20fd769f1 392 time_t seconds;
kenjiArai 0:e4c20fd769f1 393 char buf[40];
kenjiArai 0:e4c20fd769f1 394
kenjiArai 0:e4c20fd769f1 395 seconds = mktime(&t);
kenjiArai 0:e4c20fd769f1 396 // ex.2
kenjiArai 0:e4c20fd769f1 397 strftime(buf, 40, "%x %X", localtime(&seconds));
kenjiArai 0:e4c20fd769f1 398 pcr.printf("Date: %s\r\n", buf);
kenjiArai 0:e4c20fd769f1 399 // ex.3
kenjiArai 0:e4c20fd769f1 400 strftime(buf, 40, "%I:%M:%S %p (%Y/%m/%d)", localtime(&seconds));
kenjiArai 0:e4c20fd769f1 401 pcr.printf("Date: %s\r\n", buf);
kenjiArai 0:e4c20fd769f1 402 // ex.4
kenjiArai 0:e4c20fd769f1 403 strftime(buf, 40, "%B %d,'%y, %H:%M:%S", localtime(&seconds));
kenjiArai 0:e4c20fd769f1 404 pcr.printf("Date: %s\r\n", buf);
kenjiArai 0:e4c20fd769f1 405 #endif
kenjiArai 0:e4c20fd769f1 406 }
kenjiArai 0:e4c20fd769f1 407
kenjiArai 0:e4c20fd769f1 408 void time_enter_mode(void)
kenjiArai 0:e4c20fd769f1 409 {
kenjiArai 0:e4c20fd769f1 410 char *ptr;
kenjiArai 0:e4c20fd769f1 411 char linebuf[64];
kenjiArai 0:e4c20fd769f1 412
kenjiArai 0:e4c20fd769f1 413 pcr.printf("\r\nSet time into RTC\r\n");
kenjiArai 0:e4c20fd769f1 414 pcr.printf(" e.g. >15 2 7 10 11 12 -> Feb. 7th, '15, 10:11:12\r\n");
kenjiArai 0:e4c20fd769f1 415 pcr.printf(" If time is fine, just hit enter\r\n");
kenjiArai 0:e4c20fd769f1 416 pcr.putc('>');
kenjiArai 0:e4c20fd769f1 417 ptr = linebuf;
kenjiArai 0:e4c20fd769f1 418 get_line(ptr, sizeof(linebuf));
kenjiArai 0:e4c20fd769f1 419 pcr.printf("\r");
kenjiArai 0:e4c20fd769f1 420 chk_and_set_time(ptr);
kenjiArai 0:e4c20fd769f1 421 }
kenjiArai 0:e4c20fd769f1 422
kenjiArai 2:765470eab2a6 423 #if defined(TARGET_NUCLEO_L152RE)
kenjiArai 5:1a8e7aed053d 424 void goto_standby(void)
kenjiArai 2:765470eab2a6 425 {
kenjiArai 5:1a8e7aed053d 426 RCC->AHBENR |= (RCC_AHBENR_GPIOAEN | RCC_AHBENR_GPIOBEN | RCC_AHBENR_GPIOCEN |
kenjiArai 5:1a8e7aed053d 427 RCC_AHBENR_GPIODEN | RCC_AHBENR_GPIOHEN);
kenjiArai 5:1a8e7aed053d 428 #if 0
kenjiArai 2:765470eab2a6 429 GPIO_InitTypeDef GPIO_InitStruct;
kenjiArai 2:765470eab2a6 430 // All other ports are analog input mode
kenjiArai 2:765470eab2a6 431 GPIO_InitStruct.Pin = GPIO_PIN_All;
kenjiArai 2:765470eab2a6 432 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
kenjiArai 2:765470eab2a6 433 GPIO_InitStruct.Pull = GPIO_NOPULL;
kenjiArai 2:765470eab2a6 434 GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
kenjiArai 2:765470eab2a6 435 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
kenjiArai 2:765470eab2a6 436 HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
kenjiArai 2:765470eab2a6 437 HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
kenjiArai 2:765470eab2a6 438 HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
kenjiArai 2:765470eab2a6 439 HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
kenjiArai 2:765470eab2a6 440 HAL_GPIO_Init(GPIOH, &GPIO_InitStruct);
kenjiArai 5:1a8e7aed053d 441 #else
kenjiArai 5:1a8e7aed053d 442 GPIOA->MODER = 0xffffffff;
kenjiArai 5:1a8e7aed053d 443 GPIOB->MODER = 0xffffffff;
kenjiArai 5:1a8e7aed053d 444 GPIOC->MODER = 0xffffffff;
kenjiArai 5:1a8e7aed053d 445 GPIOD->MODER = 0xffffffff;
kenjiArai 5:1a8e7aed053d 446 GPIOE->MODER = 0xffffffff;
kenjiArai 5:1a8e7aed053d 447 GPIOH->MODER = 0xffffffff;
kenjiArai 5:1a8e7aed053d 448 #endif
kenjiArai 5:1a8e7aed053d 449 RCC->AHBENR &= ~(RCC_AHBENR_GPIOAEN | RCC_AHBENR_GPIOBEN |RCC_AHBENR_GPIOCEN |
kenjiArai 5:1a8e7aed053d 450 RCC_AHBENR_GPIODEN | RCC_AHBENR_GPIOHEN);
kenjiArai 2:765470eab2a6 451 while(1) {
kenjiArai 5:1a8e7aed053d 452 #if 0
kenjiArai 5:1a8e7aed053d 453 // Stop mode
kenjiArai 2:765470eab2a6 454 HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
kenjiArai 5:1a8e7aed053d 455 #else
kenjiArai 5:1a8e7aed053d 456 // Standby mode
kenjiArai 5:1a8e7aed053d 457 HAL_PWR_EnterSTANDBYMode();
kenjiArai 5:1a8e7aed053d 458 #endif
kenjiArai 2:765470eab2a6 459 }
kenjiArai 2:765470eab2a6 460 }
kenjiArai 0:e4c20fd769f1 461 #else
kenjiArai 5:1a8e7aed053d 462 void goto_standby(void)
kenjiArai 2:765470eab2a6 463 {
kenjiArai 5:1a8e7aed053d 464 deepsleep(); // Not Standby Mode but Deep Sleep Mode
kenjiArai 2:765470eab2a6 465 }
kenjiArai 2:765470eab2a6 466 #endif
kenjiArai 2:765470eab2a6 467
kenjiArai 2:765470eab2a6 468 #if defined(TARGET_NUCLEO_L152RE)
kenjiArai 2:765470eab2a6 469 #if defined(USE_IRQ_FOR_RTC_BKUP)
kenjiArai 2:765470eab2a6 470 // COMP2 Interrupt routine
kenjiArai 2:765470eab2a6 471 void irq_comp2_handler(void)
kenjiArai 2:765470eab2a6 472 {
kenjiArai 2:765470eab2a6 473 __disable_irq();
kenjiArai 5:1a8e7aed053d 474 goto_standby();
kenjiArai 2:765470eab2a6 475 }
kenjiArai 2:765470eab2a6 476
kenjiArai 2:765470eab2a6 477 COMP_HandleTypeDef COMP_HandleStruct;
kenjiArai 2:765470eab2a6 478 GPIO_InitTypeDef GPIO_InitStruct;
kenjiArai 2:765470eab2a6 479
kenjiArai 5:1a8e7aed053d 480 // Set BOR level3 (2.54 to 2.74V)
kenjiArai 5:1a8e7aed053d 481 void set_BOR_level3(void)
kenjiArai 2:765470eab2a6 482 {
kenjiArai 2:765470eab2a6 483 FLASH_OBProgramInitTypeDef my_flash;
kenjiArai 2:765470eab2a6 484
kenjiArai 2:765470eab2a6 485 HAL_FLASHEx_OBGetConfig(&my_flash); // read current configuration
kenjiArai 5:1a8e7aed053d 486 if (my_flash.BORLevel != OB_BOR_LEVEL3) {
kenjiArai 5:1a8e7aed053d 487 my_flash.BORLevel = OB_BOR_LEVEL3;
kenjiArai 2:765470eab2a6 488 HAL_FLASHEx_OBProgram(&my_flash);
kenjiArai 2:765470eab2a6 489 }
kenjiArai 2:765470eab2a6 490 }
kenjiArai 2:765470eab2a6 491
kenjiArai 2:765470eab2a6 492 void set_5v_drop_detect(void)
kenjiArai 2:765470eab2a6 493 {
kenjiArai 5:1a8e7aed053d 494 set_BOR_level3();
kenjiArai 2:765470eab2a6 495 // Set Analog voltage input (PB5 or PB6)
kenjiArai 2:765470eab2a6 496 #if defined(USE_PB5_FOR_COMP)
kenjiArai 2:765470eab2a6 497 GPIO_InitStruct.Pin = GPIO_PIN_5; // PB5 comp input
kenjiArai 2:765470eab2a6 498 #elif defined(USE_PB6_FOR_COMP)
kenjiArai 2:765470eab2a6 499 GPIO_InitStruct.Pin = GPIO_PIN_6; // PB6 comp input
kenjiArai 2:765470eab2a6 500 #else
kenjiArai 2:765470eab2a6 501 #error "Please define USE_PB5_FOR_COMP or USE_PB6_FOR_COMP in SetRTC.h"
kenjiArai 2:765470eab2a6 502 #endif
kenjiArai 2:765470eab2a6 503 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
kenjiArai 2:765470eab2a6 504 GPIO_InitStruct.Pull = GPIO_NOPULL;
kenjiArai 2:765470eab2a6 505 GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
kenjiArai 2:765470eab2a6 506 HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
kenjiArai 2:765470eab2a6 507 // COMP2 sets for low volatage detection
kenjiArai 2:765470eab2a6 508 __COMP_CLK_ENABLE();
kenjiArai 2:765470eab2a6 509 COMP_HandleStruct.Instance = COMP2;
kenjiArai 2:765470eab2a6 510 COMP_HandleStruct.Init.InvertingInput = COMP_INVERTINGINPUT_VREFINT;
kenjiArai 2:765470eab2a6 511 #if defined(USE_PB5_FOR_COMP)
kenjiArai 2:765470eab2a6 512 COMP_HandleStruct.Init.NonInvertingInput = COMP_NONINVERTINGINPUT_PB5;
kenjiArai 2:765470eab2a6 513 #elif defined(USE_PB6_FOR_COMP)
kenjiArai 2:765470eab2a6 514 COMP_HandleStruct.Init.NonInvertingInput = COMP_NONINVERTINGINPUT_PB6;
kenjiArai 2:765470eab2a6 515 #endif
kenjiArai 2:765470eab2a6 516 COMP_HandleStruct.Init.Output = COMP_OUTPUT_NONE;
kenjiArai 2:765470eab2a6 517 COMP_HandleStruct.Init.Mode = COMP_MODE_HIGHSPEED;
kenjiArai 2:765470eab2a6 518 COMP_HandleStruct.Init.WindowMode = COMP_WINDOWMODE_DISABLED;
kenjiArai 2:765470eab2a6 519 COMP_HandleStruct.Init.TriggerMode = COMP_TRIGGERMODE_IT_FALLING;
kenjiArai 2:765470eab2a6 520 HAL_COMP_Init(&COMP_HandleStruct);
kenjiArai 2:765470eab2a6 521 // Interrupt configuration
kenjiArai 2:765470eab2a6 522 NVIC_SetVector(COMP_IRQn, (uint32_t)irq_comp2_handler);
kenjiArai 2:765470eab2a6 523 HAL_NVIC_SetPriority(COMP_IRQn, 0, 0);
kenjiArai 2:765470eab2a6 524 HAL_NVIC_ClearPendingIRQ(COMP_IRQn);
kenjiArai 2:765470eab2a6 525 HAL_COMP_Start_IT(&COMP_HandleStruct);
kenjiArai 2:765470eab2a6 526 HAL_NVIC_EnableIRQ(COMP_IRQn);
kenjiArai 2:765470eab2a6 527 }
kenjiArai 2:765470eab2a6 528 #else // defined(USE_IRQ_FOR_RTC_BKUP)
kenjiArai 2:765470eab2a6 529 void set_5v_drop_detect(void)
kenjiArai 2:765470eab2a6 530 {
kenjiArai 2:765470eab2a6 531 ; // No implementation
kenjiArai 2:765470eab2a6 532 }
kenjiArai 2:765470eab2a6 533 #endif // defined(USE_IRQ_FOR_RTC_BKUP)
kenjiArai 2:765470eab2a6 534
kenjiArai 2:765470eab2a6 535 #else // defined(TARGET_NUCLEO_L152RE)
kenjiArai 2:765470eab2a6 536 void set_5v_drop_detect(void)
kenjiArai 2:765470eab2a6 537 {
kenjiArai 2:765470eab2a6 538 ; // No implementation
kenjiArai 2:765470eab2a6 539 }
kenjiArai 2:765470eab2a6 540 #endif // defined(TARGET_NUCLEO_L152RE)
kenjiArai 2:765470eab2a6 541
kenjiArai 2:765470eab2a6 542 #else // defined(TARGET_NUCLEO_F401RE,TARGET_NUCLEO_F411RE,TARGET_NUCLEO_L152RE)
kenjiArai 0:e4c20fd769f1 543 #error "No suport this mbed, only for Nucleo mbed"
kenjiArai 2:765470eab2a6 544 #endif // defined(TARGET_NUCLEO_F401RE,TARGET_NUCLEO_F411RE,TARGET_NUCLEO_L152RE)