Kenji Arai
/
Check_external_RTC
check program for EPSON RX-8025NB and STM M41T62 external RTC library
main.cpp
- Committer:
- kenjiArai
- Date:
- 2020-08-07
- Revision:
- 0:564965644ed2
- Child:
- 1:0fd657a82160
File content as of revision 0:564965644ed2:
/* * mbed Application program * External RTC test program * * Copyright (c) 2020 Kenji Arai / JH1PJL * http://www7b.biglobe.ne.jp/~kenjia/ * https://os.mbed.com/users/kenjiArai/ * Created: August 7th, 2020 * Revised: August 7th, 2020 */ // tested on Nucleo-L476RG board // Select target RTC ---------------------------------------------------------- //#define CHECK_RX8025 #define CHECK_M41T62 // Include -------------------------------------------------------------------- #include "mbed.h" #include "redirect_stdio.h" #if defined(CHECK_RX8025) # include "RX8025NB.h" # define RTC_NO 0 #elif defined(CHECK_M41T62) # include "m41t62_rtc.h" # define RTC_NO 1 #endif // Definition ----------------------------------------------------------------- #define PUSHED_SW 0 // Active low #define SLEEP_TIME 2 // 2 minuts(minimum setting) // Object --------------------------------------------------------------------- DigitalIn userSW(USER_BUTTON); DigitalOut myled(LED1); // Indicate the sampling period I2C i2c(D14, D15); #if defined(CHECK_RX8025) RX8025 ex_rtc(i2c); // EPSON RX-8025NB DigitalIn rtc_irq(A5, PullUp); // will change to InterruptIn #elif defined(CHECK_M41T62) M41T62 ex_rtc(i2c); // STMicro M41T62 DigitalIn rtc_irq(A4, PullUp); // will change to InterruptIn #endif // RAM ------------------------------------------------------------------------ // ROM / Constant data -------------------------------------------------------- const char *const msg0 = "Is a time correct? If no, please hit any key. "; const char *const msg1 = "<Push USER SW then enter the Deep Sleep mode> "; const char *const rtc_name[2] = {"RX-8025NB", "M41T62"}; // Function prototypes -------------------------------------------------------- static void w_check_rtc_time(void); static void time_enter_mode(void); static void chk_and_set_time(char *ptr); static int32_t xatoi(char **str, int32_t *res); static void get_line(char *buff, int32_t len); static void rtc_interrut(void); extern void print_revision(void); //------------------------------------------------------------------------------ // Control Program //------------------------------------------------------------------------------ int main() { char buf[64]; time_t seconds; uint8_t wait_counter = 0; puts("\r\n\r\nTest Nucleo RTC Function."); printf("External RTC is %s\r\n", rtc_name[RTC_NO]); print_revision(); myled = !myled; ThisThread::sleep_for(100ms); myled = !myled; ThisThread::sleep_for(100ms); // RTC related preparation //ex_rtc.set_sq_wave(RTC_SQW_NONE); ex_rtc.clear_IRQ(); w_check_rtc_time(); while(true) { seconds = time(NULL); strftime(buf, 50, " %B %d,'%y, %H:%M:%S\r\n", localtime(&seconds)); printf("[Time] %s", buf); printf("%s", msg0); printf("%s", msg1); puts("\r"); wait_counter = 0; while (seconds == time(NULL)) { if (readable() == 1) { // Enter time from PC console getc(); // dummy read time_enter_mode(); } if (userSW == PUSHED_SW) { // goto sleep and wake up by RTC timer while (userSW == PUSHED_SW) { ThisThread::sleep_for(10ms); } printf("Please wait %d minutes to wake-up(Reset).", SLEEP_TIME); puts(" Entered the deep sleep mode. "); ThisThread::sleep_for(1s); myled = 0; #if defined(CHECK_RX8025) InterruptIn rtc_irq(A5, PullUp); #elif defined(CHECK_M41T62) InterruptIn rtc_irq(A4, PullUp); #endif rtc_irq.fall(&rtc_interrut); ex_rtc.set_next_IRQ(SLEEP_TIME); ThisThread::sleep_for(1s); DigitalIn dmy0(LED1); DigitalIn dmy1(USBTX); DigitalIn dmy2(USBRX); ThisThread::sleep_for(10000s); // sleep long time } ThisThread::sleep_for(50ms); if (++wait_counter > (2000 / 50)) { break; } } // delete previous strings printf("\033[2A"); puts(""); // null uint8_t n = strlen(msg0) + strlen(msg1); memset(buf, ' ', 64); if (n > 64) { n -= 64; puts_wo_cr(buf, 64); } if (n > 64) { puts_wo_cr(buf, 64); } else { puts_wo_cr(buf, n); } printf("\033[G"); myled = !myled; } } // Check External RTC data static void w_check_rtc_time(void) { time_t seconds_1st, seconds_2nd, diff; struct tm t; for (uint32_t i = 0; i < 5; i++) { ex_rtc.read_rtc_std(&t); // read External RTC data printf("Year:%d ",t.tm_year); printf("Month:%d ",t.tm_mon); printf("Day:%d ",t.tm_mday); printf("Hour:%d ",t.tm_hour); printf("Min:%d ",t.tm_min); printf("Sec: %d \r\n",t.tm_sec); seconds_1st = mktime(&t); ex_rtc.read_rtc_std(&t); // read External RTC data again (make sure) seconds_2nd = mktime(&t); diff = seconds_2nd - seconds_1st; if ((diff == 0) || (diff == 1)) { break; } } set_time(seconds_2nd); } // Interrupt for wake up static void rtc_interrut(void) { system_reset(); // restart from RESET condition } // Time adjustment static void time_enter_mode(void) { char *ptr; char linebuf[64]; puts("Set time into RTC."); puts(" e.g. >20 8 1 12 34 56 -> August 01,'20, 12:34:56"); puts(" If time is fine, just hit enter key."); putc('>'); ptr = linebuf; get_line(ptr, sizeof(linebuf)); puts("\r"); chk_and_set_time(ptr); } // Change string -> integer static int32_t xatoi(char **str, int32_t *res) { uint32_t val; uint8_t c, radix, s = 0; while ((c = **str) == ' ') (*str)++; if (c == '-') { s = 1; c = *(++(*str)); } if (c == '0') { c = *(++(*str)); if (c <= ' ') { *res = 0; return 1; } if (c == 'x') { radix = 16; c = *(++(*str)); } else { if (c == 'b') { radix = 2; c = *(++(*str)); } else { if ((c >= '0')&&(c <= '9')) { radix = 8; } else { return 0; } } } } else { if ((c < '1')||(c > '9')) { return 0; } radix = 10; } val = 0; while (c > ' ') { if (c >= 'a') c -= 0x20; c -= '0'; if (c >= 17) { c -= 7; if (c <= 9) return 0; } if (c >= radix) return 0; val = val * radix + c; c = *(++(*str)); } if (s) val = -val; *res = val; return 1; } // Get key input data static void get_line(char *buff, int32_t len) { char c; int32_t idx = 0; for (;;) { c = getc(); //printf("0x%x \r\n", c); if ((c == '\r') || (c == '\n')) { buff[idx++] = '\r'; break; } if ((c == '\b') && idx) { idx--; const char bf_bs[] = {0x1b, '[', '1', 'D', ' ', 0x1b, '[', '1', 'D',0}; for(uint32_t i = 0; bf_bs[i] != 0; i++) { putc(bf_bs[i]); } } if (((uint8_t)c >= ' ') && (idx < len - 1)) { buff[idx++] = c; putc(c); } } buff[idx] = 0; putc('\n'); } // Check key input strings and set time static void chk_and_set_time(char *ptr) { int32_t p1; struct tm t; time_t seconds; if (xatoi(&ptr, &p1)) { t.tm_year = (uint8_t)p1 + 100; printf("Year:%d ",p1); xatoi( &ptr, &p1 ); t.tm_mon = (uint8_t)p1 - 1; printf("Month:%d ",p1); xatoi( &ptr, &p1 ); t.tm_mday = (uint8_t)p1; printf("Day:%d ",p1); xatoi( &ptr, &p1 ); t.tm_hour = (uint8_t)p1; printf("Hour:%d ",p1); xatoi( &ptr, &p1 ); t.tm_min = (uint8_t)p1; printf("Min:%d ",p1); xatoi( &ptr, &p1 ); t.tm_sec = (uint8_t)p1; printf("Sec: %d \r\n",p1); seconds = mktime(&t); set_time(seconds); } else { seconds = time(NULL); } seconds = time(NULL); struct tm *time_ajd = localtime(&seconds); ex_rtc.write_rtc_std(time_ajd); // Show Time with several example // ex.1 printf( "Date: %04d/%02d/%02d, %02d:%02d:%02d\r\n", t.tm_year + 1900, t.tm_mon + 1, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec ); char buf[64]; // ex.2 strftime(buf, 40, "%x %X", localtime(&seconds)); printf("Date: %s\r\n", buf); // ex.3 strftime(buf, 40, "%I:%M:%S %p (%Y/%m/%d)", localtime(&seconds)); printf("Date: %s\r\n", buf); // ex.4 strftime(buf, 40, "%B %d,'%y, %H:%M:%S", localtime(&seconds)); printf("Date: %s\r\n", buf); }