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:
2014-10-25
Revision:
1:eaa3c3f36c03
Parent:
0:bad75bd13618
Child:
2:8b6a8cfa173a

File content as of revision 1:eaa3c3f36c03:

/*
 * mbed Application program
 *      RTC Clock test
 *
 *  Copyright (c) 2010-2014 Kenji Arai / JH1PJL
 *  http://www.page.sannet.ne.jp/kenjia/index.html
 *  http://mbed.org/users/kenjiArai/
 *      Created:  October   24th, 2014
 *      Revised:  October   25th, 2014
 *
 * 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 "rtc_api.h"

//  Definition ------------------------------------------------------------------------------------
#define STANDARD_FUNCTION // Use standard library prepared by STMicroelectronics
//#define SPECIAL_FUNCTION  // Use special function. Time out is much longer than standard function

#define BAUD(x)         pc.baud(x)
#define GETC(x)         pc.getc(x)
#define PUTC(x)         pc.putc(x)
#define PRINTF(...)     pc.printf(__VA_ARGS__)
#define READABLE(x)     pc.readable(x)

#define TIMEOUT         ((uint32_t)5000)

//  Object ----------------------------------------------------------------------------------------
Serial pc(USBTX, USBRX);
DigitalOut myled(LED1);
Timer t;

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

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

//  Function prototypes ---------------------------------------------------------------------------
uint32_t Set_RTC_LSI(void);
void rtc_external_osc_init(void);
uint32_t Set_RTC_LSE(void);

//-------------------------------------------------------------------------------------------------
//  Control Program
//-------------------------------------------------------------------------------------------------
int main()
{
    while(true)
    {
        PRINTF("Select RTC clock source\r\n");
        t.reset();
        t.start();
    #if defined(STANDARD_FUNCTION)
        rtc_init();
        t.stop();
        PRINTF("Use standard function by STM\r\n");
        PRINTF("The time taken was %f sec. (Time-out setting:%f sec.)\r\n",
                t.read(), (float)LSE_TIMEOUT_VALUE/1000);
    #elif defined(SPECIAL_FUNCTION)
        rtc_external_osc_init();
        t.stop();
        PRINTF("Use special function (extend time-out)\r\n");
        PRINTF("The time taken was %f sec. (Time-out setting:%f sec.)\r\n",
                t.read(), (float)(float)TIMEOUT/1000);
    #endif
        switch ((RCC->BDCR >> 8) & 0x03) {
            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");
        Set_RTC_LSI();
        if (((RCC->BDCR >> 8) & 0x03) != 2) {
            PRINTF("Please remove USB then re-plug again");
        } else {
            PRINTF("Use LSI again", (float)TIMEOUT/1000);
        }
        PRINTF("\r\nRepeat again? [y/n]\r\n");
        PRINTF(" If yes, please pusch [RESET] buttom.\r\n If no, please hit any key.\r\n");
        if (GETC()){
            break;
        }
    }
    PRINTF("next\r\n");
#if defined(STANDARD_FUNCTION)
    rtc_init();
#elif defined(SPECIAL_FUNCTION)
    rtc_external_osc_init();
#endif 
}

uint32_t Set_RTC_LSE(void)
{
    uint32_t timeout = 0;   
 
    //---------------------------- LSE Configuration ------------------------- 
    // Enable Power Clock
    __PWR_CLK_ENABLE();
    // Enable write access to Backup domain 
    PWR->CR |= PWR_CR_DBP;
    // Wait for Backup domain Write protection disable 
    timeout = HAL_GetTick() + DBP_TIMEOUT_VALUE;
    while((PWR->CR & PWR_CR_DBP) == RESET){
        if(HAL_GetTick() >= timeout){
            return 0;
        }      
    }
    // Reset LSEON and LSEBYP bits before configuring the LSE ----------------
    __HAL_RCC_LSE_CONFIG(RCC_LSE_OFF);
    // Get timeout 
    timeout = HAL_GetTick() + ((uint32_t)5000);
    // Wait till LSE is ready   
    while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) != RESET){
        if(HAL_GetTick() >= timeout) {
            return 0;
        }      
    } 
    // Set the new LSE configuration -----------------------------------------
    __HAL_RCC_LSE_CONFIG(RCC_LSE_ON);
    // Get timeout 
    timeout = HAL_GetTick() + ((uint32_t)5000);
    // Wait till LSE is ready   
    while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET){
        if(HAL_GetTick() >= timeout){
            return 0;
        }      
    }
    return 1;
}

void rtc_external_osc_init(void)
{
    // Enable Power clock
    __PWR_CLK_ENABLE();
    // Enable access to Backup domain
    HAL_PWR_EnableBkUpAccess();
    // Reset Backup domain
    __HAL_RCC_BACKUPRESET_FORCE();
    __HAL_RCC_BACKUPRESET_RELEASE();
    // Enable LSE Oscillator
    if (Set_RTC_LSE()) {
        // Connect LSE to RTC
        __HAL_RCC_RTC_CLKPRESCALER(RCC_RTCCLKSOURCE_LSE);
        __HAL_RCC_RTC_CONFIG(RCC_RTCCLKSOURCE_LSE);
    }
}

uint32_t Set_RTC_LSI(void)
{
    uint32_t timeout = 0;

    // Enable Power clock
    __PWR_CLK_ENABLE();
    // Enable access to Backup domain
    HAL_PWR_EnableBkUpAccess();
    // Reset Backup domain
    __HAL_RCC_BACKUPRESET_FORCE();
    __HAL_RCC_BACKUPRESET_RELEASE();
    // Enable Power Clock
    __PWR_CLK_ENABLE();
    // Enable write access to Backup domain
    PWR->CR |= PWR_CR_DBP;
    // Wait for Backup domain Write protection disable
    timeout = HAL_GetTick() + DBP_TIMEOUT_VALUE;
    while((PWR->CR & PWR_CR_DBP) == RESET) {
        if(HAL_GetTick() >= timeout) {
            return 0;
        }
    }
    __HAL_RCC_LSE_CONFIG(RCC_LSE_OFF);
    // Enable LSI 
    __HAL_RCC_LSI_ENABLE();
    timeout = HAL_GetTick() + TIMEOUT;
    // Wait till LSI is ready
    while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSIRDY) == RESET) {
        if(HAL_GetTick() >= timeout) {
            return 0;
        }
    }
    // Connect LSI to RTC
    __HAL_RCC_RTC_CLKPRESCALER(RCC_RTCCLKSOURCE_LSI);
    __HAL_RCC_RTC_CONFIG(RCC_RTCCLKSOURCE_LSI);    
    return 1;
}