mirror of
https://github.com/oopuuu/zTC1.git
synced 2025-12-17 23:48:13 +08:00
336 lines
9.9 KiB
C
336 lines
9.9 KiB
C
/**
|
|
******************************************************************************
|
|
* @file MicoDriverRtc.c
|
|
* @author William Xu
|
|
* @version V1.0.0
|
|
* @date 05-May-2014
|
|
* @brief This file provide RTC driver functions.
|
|
******************************************************************************
|
|
* UNPUBLISHED PROPRIETARY SOURCE CODE
|
|
* Copyright (c) 2016 MXCHIP Inc.
|
|
*
|
|
* The contents of this file may not be disclosed to third parties, copied or
|
|
* duplicated in any form, in whole or in part, without the prior written
|
|
* permission of MXCHIP Corporation.
|
|
******************************************************************************
|
|
*/
|
|
|
|
#include "mico_platform.h"
|
|
#include "mico_rtos.h"
|
|
|
|
#include "platform.h"
|
|
#include "platform_peripheral.h"
|
|
#include "chip.h" // rocky
|
|
#include "debug.h"
|
|
#include "StringUtils.h"
|
|
|
|
|
|
/******************************************************
|
|
* Macros
|
|
******************************************************/
|
|
|
|
#define MICO_VERIFY_TIME(time, valid) \
|
|
if( (time->sec > 60) || ( time->min > 60 ) || (time->hr > 24) || ( time->date > 31 ) || ( time->month > 12 )) \
|
|
{ \
|
|
valid= false; \
|
|
} \
|
|
else \
|
|
{ \
|
|
valid= true; \
|
|
}
|
|
|
|
#define LEAP_YEAR_OR_NOT(year)( ( year % 4 ) ? ( 0 ) : ( 1 ) )
|
|
|
|
/******************************************************
|
|
* Constants
|
|
******************************************************/
|
|
|
|
#define LEAP_YEAR_DAY_COUNT ( 366 )
|
|
#define NOT_LEAP_YEAR_DAY_COUNT ( 365 )
|
|
#define NUM_SECONDS_IN_MINUTE ( 60 )
|
|
#define NUM_SECONDS_IN_HOUR ( 3600 )
|
|
#define NUM_1P25MS_IN_SEC ( 800 )
|
|
#define BASE_YEAR ( 2000 )
|
|
|
|
/******************************************************
|
|
* Enumerations
|
|
******************************************************/
|
|
|
|
typedef enum
|
|
{
|
|
CLOCKING_EVERY_SEC,
|
|
CLOCKING_EVERY_1p25MSEC
|
|
}rtc_clock_state_t;
|
|
|
|
extern const platform_gpio_t platform_gpio_pins[];
|
|
/******************************************************
|
|
* Type Definitions
|
|
******************************************************/
|
|
|
|
/******************************************************
|
|
* Structures
|
|
******************************************************/
|
|
|
|
/******************************************************
|
|
* Static Function Declarations
|
|
******************************************************/
|
|
// static OSStatus stm32f2_rtc_change_clock ( rtc_clock_state_t* current, rtc_clock_state_t target );
|
|
//static uint32_t convert_rtc_calendar_values_to_units_passed( const platform_rtc_time_t* rtc_read_date_time );
|
|
//static void convert_units_passed_to_rtc_calendar_values( const uint32_t seconds , platform_rtc_time_t *rtc_get_date_time );
|
|
//static uint8_t CaculateWeekDay( const platform_rtc_time_t* rtc_calendar );
|
|
|
|
/******************************************************
|
|
* Variables Definitions
|
|
******************************************************/
|
|
mico_rtc_time_t default_rtc_time =
|
|
{
|
|
/* set it to 12:20:30 08/04/2013 monday */
|
|
.sec = 00,
|
|
.min = 03,
|
|
.hr = 19,
|
|
.weekday = 1,
|
|
.date = 12,
|
|
.month = 6,
|
|
.year = 15
|
|
};
|
|
//
|
|
//static const char not_leap_days[] =
|
|
//{
|
|
// 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
|
|
//};
|
|
//
|
|
//static const char leap_days[] =
|
|
//{
|
|
// 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
|
|
//};
|
|
|
|
//static const platform_rtc_time_t* saved_rtc_time;
|
|
//static rtc_clock_state_t current_clock_state = CLOCKING_EVERY_SEC;
|
|
|
|
/******************************************************
|
|
* Function Declarations
|
|
******************************************************/
|
|
#define rtc_log(M, ...) custom_log("RTC", M, ##__VA_ARGS__)
|
|
#define rtc_log_trace() custom_log_trace("RTC")
|
|
|
|
/******************************************************
|
|
* Function Definitions
|
|
******************************************************/
|
|
/* Wecan Modify platform_rtc_init 2015.06.10 */
|
|
OSStatus platform_rtc_init(void)
|
|
{
|
|
#ifdef MICO_ENABLE_MCU_RTC
|
|
/* CLKOUT = 32K_Osc */
|
|
Chip_IOCON_PinMuxSet(LPC_IOCON, platform_gpio_pins[CLKOUT].port , platform_gpio_pins[CLKOUT].pin_number, (IOCON_MODE_PULLUP | IOCON_FUNC1 | IOCON_DIGITAL_EN | IOCON_INPFILT_OFF));
|
|
Chip_Clock_SetCLKOUTSource(SYSCON_CLKOUTSRC_RTC, 1);
|
|
|
|
/* Turn on the RTC 32K Oscillator */
|
|
Chip_SYSCON_PowerUp(SYSCON_PDRUNCFG_PD_32K_OSC);
|
|
|
|
/* Enable the RTC oscillator, oscillator rate can be determined by calling Chip_Clock_GetRTCOscRate() */
|
|
Chip_Clock_EnableRTCOsc();
|
|
|
|
/* Initialize RTC driver (enables RTC clocking) */
|
|
Chip_RTC_Init(LPC_RTC);
|
|
|
|
/* Enable RTC as a peripheral wakeup event */
|
|
//Chip_SYSCON_EnsableWakeup(SYSCON_STARTER_RTC);
|
|
|
|
/* RTC reset */
|
|
Chip_RTC_Reset(LPC_RTC);
|
|
|
|
/* Start RTC at a count of 0 when RTC is disabled. If the RTC is enabled, you need to disable it before setting the initial RTC count. */
|
|
Chip_RTC_Disable(LPC_RTC);
|
|
platform_rtc_set_time(&default_rtc_time);
|
|
|
|
//Chip_RTC_SetCount(LPC_RTC, 0);
|
|
|
|
/* Set a long alarm time so the interrupt won't trigger */
|
|
//Chip_RTC_SetAlarm(LPC_RTC, (Chip_RTC_GetCount(LPC_RTC) + 5));
|
|
|
|
/* Enable RTC and high resolution timer - this can be done in a single call with Chip_RTC_EnableOptions(LPC_RTC, (RTC_CTRL_RTC1KHZ_EN | RTC_CTRL_RTC_EN)); */
|
|
//Chip_RTC_Enable1KHZ(LPC_RTC);
|
|
Chip_RTC_Enable(LPC_RTC);
|
|
|
|
/* Clear latched RTC interrupt statuses */
|
|
Chip_RTC_ClearStatus(LPC_RTC, (RTC_CTRL_OFD | RTC_CTRL_ALARM1HZ | RTC_CTRL_WAKE1KHZ));
|
|
|
|
|
|
return kNoErr;
|
|
#else
|
|
return kUnsupportedErr;
|
|
#endif
|
|
}
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/**
|
|
* This function will return the value of time read from the on board CPU real time clock. Time value must be given in the format of
|
|
* the structure mico_rtc_time_t
|
|
*
|
|
* @return kNoErr : on success.
|
|
*/
|
|
OSStatus platform_rtc_get_time( platform_rtc_time_t* time)
|
|
{
|
|
#ifdef MICO_ENABLE_MCU_RTC
|
|
bool valid = false;
|
|
|
|
if( time == 0 )
|
|
{
|
|
return kParamErr;
|
|
}
|
|
|
|
/* get current rtc time */
|
|
convert_units_passed_to_rtc_calendar_values( Chip_RTC_GetCount(LPC_RTC), time );
|
|
|
|
MICO_VERIFY_TIME(time, valid);
|
|
if( valid == false )
|
|
{
|
|
return kParamErr;
|
|
}
|
|
|
|
#if 0
|
|
rtc_log(" return convert_units_passed_to_rtc_calendar_values address = 0x%x ", temp_time);
|
|
rtc_log(" sec = %d ", temp_time->sec);
|
|
rtc_log(" min = %d ", temp_time->min);
|
|
rtc_log(" hr = %d ", temp_time->hr);
|
|
rtc_log(" weekday = %d ", temp_time->weekday);
|
|
rtc_log(" date = %d ", temp_time->date);
|
|
rtc_log(" month = %d ", temp_time->month);
|
|
rtc_log(" year = %d ", temp_time->year);
|
|
#endif
|
|
|
|
return kNoErr;
|
|
#else /* #ifdef MICO_ENABLE_MCU_RTC */
|
|
UNUSED_PARAMETER(time);
|
|
return kUnsupportedErr;
|
|
#endif /* #ifdef MICO_ENABLE_MCU_RTC */
|
|
}
|
|
|
|
/**
|
|
* This function will set MCU RTC time to a new value. Time value must be given in the format of
|
|
* the structure mico_rtc_time_t
|
|
*
|
|
* @return kNoErr : on success.
|
|
*/
|
|
OSStatus platform_rtc_set_time( const mico_rtc_time_t* time )
|
|
{
|
|
#ifdef MICO_ENABLE_MCU_RTC
|
|
bool valid = false;
|
|
|
|
MICO_VERIFY_TIME(time, valid);
|
|
if( valid == false )
|
|
{
|
|
return kParamErr;
|
|
}
|
|
|
|
Chip_RTC_SetCount(LPC_RTC, convert_rtc_calendar_values_to_units_passed( time ));
|
|
|
|
return kNoErr;
|
|
#else /* #ifdef MICO_ENABLE_MCU_RTC */
|
|
|
|
UNUSED_PARAMETER(time);
|
|
return kUnsupportedErr;
|
|
#endif /* #ifdef MICO_ENABLE_MCU_RTC */
|
|
}
|
|
|
|
//
|
|
//static void convert_units_passed_to_rtc_calendar_values( const uint32_t seconds , platform_rtc_time_t *rtc_get_date_time )
|
|
//{
|
|
// long int temp1=0;
|
|
// int temp=0;
|
|
// long int temp_days=0;
|
|
// bool MonthFound = false;
|
|
// bool YearFound = false;
|
|
//
|
|
// rtc_log_trace();
|
|
//
|
|
// /* Convert seconds passed to hours, seconds and minutes */
|
|
// rtc_get_date_time->sec = seconds % NUM_SECONDS_IN_MINUTE;
|
|
// rtc_get_date_time->min = ( seconds / NUM_SECONDS_IN_MINUTE )% NUM_SECONDS_IN_MINUTE;
|
|
// rtc_get_date_time->hr = ( seconds / NUM_SECONDS_IN_HOUR ) % 24;
|
|
//
|
|
// /* years */
|
|
// temp_days = ( seconds / NUM_SECONDS_IN_HOUR ) / 24;
|
|
// rtc_get_date_time->year = 0;
|
|
// while ( YearFound == false ) {
|
|
// temp1 = (LEAP_YEAR_OR_NOT(temp)) ? (LEAP_YEAR_DAY_COUNT): (NOT_LEAP_YEAR_DAY_COUNT);
|
|
// if ( temp_days >= temp1 ) {
|
|
// temp_days -= temp1;
|
|
// temp++;
|
|
// }
|
|
// else {
|
|
// YearFound = true;
|
|
// }
|
|
// }
|
|
// rtc_get_date_time->year = temp;
|
|
//
|
|
// /* Month */
|
|
// temp = 1;
|
|
// rtc_get_date_time->month = 1;
|
|
// /* Determine offset of months from days offset */
|
|
// while ( MonthFound == false ) {
|
|
// temp1 = LEAP_YEAR_OR_NOT(rtc_get_date_time->year )?(leap_days[temp]):(not_leap_days[temp]);
|
|
// if(( temp_days + 1 ) > temp1) {
|
|
// temp_days -= temp1;
|
|
// temp++;
|
|
// }
|
|
// else {
|
|
// MonthFound = true;
|
|
// }
|
|
// }
|
|
// rtc_get_date_time->month = temp;
|
|
//
|
|
// /* date */
|
|
// rtc_get_date_time->date = temp_days + 1;
|
|
//
|
|
// /* WeekDay */
|
|
// rtc_get_date_time->weekday = CaculateWeekDay( rtc_get_date_time ) + 1;
|
|
//
|
|
//#if 0
|
|
// rtc_log(" sec = %d ", rtc_get_date_time->sec);
|
|
// rtc_log(" min = %d ", rtc_get_date_time->min);
|
|
// rtc_log(" hr = %d ", rtc_get_date_time->hr);
|
|
// rtc_log(" weekday = %d ", rtc_get_date_time->weekday);
|
|
// rtc_log(" date = %d ", rtc_get_date_time->date);
|
|
// rtc_log(" month = %d ", rtc_get_date_time->month);
|
|
// rtc_log(" year = %d ", rtc_get_date_time->year);
|
|
// rtc_log(" rtc_get_date_time = 0x%x ", rtc_get_date_time);
|
|
//#endif
|
|
//}
|
|
//
|
|
//static uint8_t CaculateWeekDay( const platform_rtc_time_t* rtc_calendar )
|
|
//{
|
|
// uint16_t year;
|
|
// uint8_t month, date, weekday;
|
|
//
|
|
// year = rtc_calendar->year + BASE_YEAR;
|
|
// month = rtc_calendar->month;
|
|
// date = rtc_calendar->date;
|
|
// if ( month == 1 || month == 2 )
|
|
// {
|
|
// month+=12;
|
|
// year--;
|
|
// }
|
|
// weekday = ( date + 2 * month + 3 * ( month + 1 ) / 5 + year + year / 4 - year / 100 + year / 400) % 7;
|
|
// return weekday;
|
|
//}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|