Kenji Arai
/
Check_external_RTC
check program for EPSON RX-8025NB and STM M41T62 external RTC library
Diff: main.cpp
- Revision:
- 0:564965644ed2
- Child:
- 1:0fd657a82160
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Fri Aug 07 05:43:59 2020 +0000 @@ -0,0 +1,323 @@ +/* + * 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); +}