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:
Sat May 23 21:07:12 2015 +0000
Revision:
9:1af4e107ca7b
Parent:
6:ef7d2c83034d
Child:
10:16ee1c956319
Added F334R8

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