Check RTC LSE(External Xtal, 32.768kHz) mode

Dependencies:   mbed CheckRTC

Please refer follow links.
My notebook
http://developer.mbed.org/users/kenjiArai/notebook/nucleo-series-clock-structure-and-xtal-oscillation/
Q&A for RTC Xtal
http://developer.mbed.org/questions/4531/RTC-External-Crystal-Nucleo/

main.cpp

Committer:
kenjiArai
Date:
2015-05-16
Revision:
4:56a0cbad89b0
Parent:
3:921a09e41147

File content as of revision 4:56a0cbad89b0:

/*
 * mbed Application program
 *
 *  Copyright (c) 2010-2015 Kenji Arai / JH1PJL
 *  http://www.page.sannet.ne.jp/kenjia/index.html
 *  http://mbed.org/users/kenjiArai/
 *      Created:  March     27th, 2010
 *      Revised:  May       16th, 2015
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
 * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
 * DAMAGES OR OTHER  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

//  Include ---------------------------------------------------------------------------------------
#include "mbed.h"
#include "CheckRTC.h"

//  Object ----------------------------------------------------------------------------------------
Serial pc(USBTX, USBRX);
DigitalOut myled1(LED1);                                // Assign LED1 output port
Timer t;

//  RAM -------------------------------------------------------------------------------------------

//  ROM / Constant data ---------------------------------------------------------------------------

//  Function prototypes ---------------------------------------------------------------------------
int set_time_and_check_time(void);
void msg_hlp (void);
void chk_and_set_time(char *ptr);
int xatoi (char **str, int32_t *res);
void get_line (char *buff, int len);

//  Definition ------------------------------------------------------------------------------------
#define BAUD(x)                 pc.baud(x)
#define GETC(x)                 pc.getc(x)
#define PUTC(x)                 pc.putc(x)
#define PUTS(x)                 pc.puts(x)
#define PRINTF(...)             pc.printf(__VA_ARGS__)
#define READABLE(x)             pc.readable(x)

#define STYLE1
//#define STYLE2
//#define STYLE_COM

//-------------------------------------------------------------------------------------------------
//  Control Program
//-------------------------------------------------------------------------------------------------
#if defined(TARGET_NUCLEO_F401RE) || defined(TARGET_NUCLEO_F411RE) || defined(TARGET_NUCLEO_L152RE)
int main()
{
    uint32_t state;

    while(true) {
        PUTS("\r\n\r\nCurrent Nucleo mbed Power-on sequence does NOT consider ");
        PUTS("External Xtal start-up.\r\n");
        PUTS("Setting time is 5 seconds (improved) ");
        PUTS("but sometimes External Xtal 32.768KHz (LSE) does NOT work!\r\n");
        PUTS("Current setting: ");
        state = get_RTCSEL();
        switch (state) {
            case 0: // no clock
                PUTS("No clock");
                break;
            case 1: // LSE
                PUTS("Use LSE(external Xtal)=32.768KHz");
                break;
            case 2: // LSI
                PUTS("Use LSI(internal RC/Low speed), RC = 17 to 47, typ.32KHz");
                break;
            case 3: // HSE
                PUTS("Use HSE(with prescaler)");
                break;
            default:    // Not come here
                PRINTF("No clock");
                break;
        }
        PUTS("\r\n\r\n");
        if (state == 1) {
            PUTS("LSE is using! No addtional effort but just in case please try follows.\r\n");
        } else {
            PUTS("Please hit any key to use RTC external clock.\r\n");
            while (!READABLE()) {
                wait(0.2);
            }
            PRINTF("\r\nStart measure\r\n");
            t.reset();
            t.start();
            CheckRTC();
            t.stop();
            PRINTF("Start-up time was %f sec. (Time-out setting:%f sec.)\r\n",
                   t.read(), (float)(float)TIMEOUT/1000);
            PUTS("\r\n");
            state = get_RTCSEL();
            switch (state) {
                case 0: // no clock
                    PRINTF("No clock");
                    break;
                case 1: // LSE
                    PRINTF("Use LSE");
                    break;
                case 2: // LSI
                    PRINTF("Use LSI");
                    break;
                case 3: // HSE
                    PRINTF("Use HSE");
                    break;
                default:    // Not come here
                    PRINTF("?");
                    break;
            }
            PRINTF("\r\n");
            CheckRTC();
            if (state == 1) {
                PUTS("Looks okay right now but always okay or not?!\r\n");
            }
        }
        PUTS("If you would like to masure again,");
        PUTS("Please remove JP6/IDO on the mbed board then re-plug it again!.\r\n\r\n");
        set_time_and_check_time();
    }
}

#else
#warning "Cannot use this function. Please comment out #define CHECK_RTC and use #define SET_RTC
#endif

int set_time_and_check_time()
{
    char *ptr;
    char linebuf[64];
    char buf[40];
    time_t seconds;

    if (READABLE()) {
        GETC();
    }
    seconds = time(NULL);
    PRINTF("Current time is ");
#ifdef STYLE_COM
    PRINTF("Time: %s\r\n", ctime(&seconds));
#else
    strftime(buf,40, "%I:%M:%S %p (%Y/%m/%d)", localtime(&seconds));
    PRINTF("Time: %s\r\n", buf);
#endif
    PRINTF("Is it correct time?\r\n");
    PRINTF("YES -> please enter '/'\r\n");
    PRINTF("NO -> please enter t yy mm dd hh mm ss <ret>   ");
    PRINTF("e.g. >t 15 5 17 10 5 15<ret>\r\n");
    for (;;) {
        PUTC('\r');
        PUTC('>');
        ptr = linebuf;
        get_line(ptr, sizeof(linebuf));
        switch (*ptr++) {
                //---------------------------------------------------------------------------------
                //  check and set RTC
                //---------------------------------------------------------------------------------
            case 't' :
                PUTC('\r');
                chk_and_set_time(ptr);
                break;
                //---------------------------------------------------------------------------------
                //  check and set RTC
                //---------------------------------------------------------------------------------
            case '/' :
                PUTC('\r');
                PRINTF("Current Time -> Plese see LCD also\r\n");
                while (1) {
                    if (READABLE()) {
                        break;
                    }
                    while ( seconds == time(NULL)) ;
                    seconds = time(NULL);
                    myled1 = !myled1;
#ifdef STYLE1
                    //                  17 May 2015 13:24:00
                    strftime(buf,40, "%x %X ", localtime(&seconds));
#endif
#ifdef STYLE2
                    //                 13:24:00 PM (2015/05/17)
                    strftime(buf,40, "%I:%M:%S %p (%Y/%m/%d)", localtime(&seconds));
#endif
#ifdef STYLE_COM
                    PRINTF("Time: %s\r\n", ctime(&seconds));
#else
                    PRINTF("Time: %s\r\n", buf);
#endif
                }
                break;
                //---------------------------------------------------------------------------------
                //  check and set RTC
                //---------------------------------------------------------------------------------
            case '?' :
            default :
                PUTC('\r');
                msg_hlp();
                break;
        }
    }
}

//  Help Massage
void msg_hlp (void)
{
    PUTS("t - Check and set RTC\r\n");
    PUTS("/ - Show time every second (Esc -> hit any key)\r\n");
    PUTS("? - Help\r\n");
}

//  Change string -> number
int xatoi (char **str, int32_t *res)
{
    unsigned long val;
    unsigned char 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
void get_line (char *buff, int len)
{
    char c;
    int idx = 0;

    for (;;) {
        c = GETC();
        if (c == '\r') {
            buff[idx++] = c;
            break;
        }
        if ((c == '\b') && idx) {
            idx--;
            PUTC(c);
            PUTC(' ');
            PUTC(c);
        }
        if (((uint8_t)c >= ' ') && (idx < len - 1)) {
            buff[idx++] = c;
            PUTC(c);
        }
    }
    buff[idx] = 0;
    PUTC('\n');
}

// RTC related subroutines
void chk_and_set_time(char *ptr)
{
    int32_t p1;
    struct tm t;
    time_t seconds;
    char buf[40];

    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);
    }
    seconds = time(NULL);
    strftime(buf, 40, "%B %d,'%y, %H:%M:%S", localtime(&seconds));
    PRINTF("Time: %s\r\n", buf);
}