|
|
@@ -1,283 +1,97 @@
|
|
|
-#include <stdio.h>
|
|
|
-#include <time.h>
|
|
|
#include <string.h>
|
|
|
-
|
|
|
-//#include "gd32e10x.h"
|
|
|
-//#include "gd32e103v_eval.h"
|
|
|
-#include "Gd32f30x_rtc.h"
|
|
|
-#include "Gd32f30x_bkp.h"
|
|
|
-#include "qws_status.h"
|
|
|
-
|
|
|
+#include "gd32f3x0_rtc.h"
|
|
|
#include "shark_rtc.h"
|
|
|
-#include "FreeRTOS.h"
|
|
|
-#include "task.h"
|
|
|
-#include "shark_bkp.h"
|
|
|
-#define IS_LEAP_YEAR(year) ((year % 4 == 0) && ( year % 100 != 0) || (year % 400 == 0))
|
|
|
-
|
|
|
-static uint32_t time_ticks = 0;
|
|
|
-#define POWER_FIRSTFLAG_REG BKP_DATA_0
|
|
|
-#define POWER_FIRSTFLAG_VALUE 0x5AA5
|
|
|
-
|
|
|
-unsigned char check_rtc_time()
|
|
|
-{
|
|
|
- int rtcTime = rtc_counter_get();
|
|
|
|
|
|
- if(rtcTime > YEAR_20171201_UTS && rtcTime < YEAR_20571201_UTS)
|
|
|
- return 1;
|
|
|
+void shark_rtc_init(void){
|
|
|
+ /* enable PMU and BKPI clocks */
|
|
|
+ rcu_periph_clock_enable(RCU_PMU);
|
|
|
+ /* allow access to BKP domain */
|
|
|
+ pmu_backup_write_enable();
|
|
|
|
|
|
- start_uptade_local_time();
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
-uint32_t app_getcurrtime_utc(void)
|
|
|
-{
|
|
|
- if(check_rtc_time() == 1)
|
|
|
- return shark_rtc_get_timestamp();
|
|
|
- else
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
-/* get the utc readable time */
|
|
|
-void shark_rtc_get_local_time(uint32_t second, time_val *out){
|
|
|
- struct tm *tm;
|
|
|
- tm = localtime((time_t *)&second);
|
|
|
-
|
|
|
- out->year = tm->tm_year + 1900;
|
|
|
- out->month = tm->tm_mon + 1;
|
|
|
- out->day = tm->tm_mday;
|
|
|
- out->hour = tm->tm_hour;
|
|
|
- out->minute = tm->tm_min;
|
|
|
- out->second = tm->tm_sec;
|
|
|
-}
|
|
|
-
|
|
|
-/* get utc timestamp --> second */
|
|
|
-uint32_t shark_rtc_get_timestamp(void){
|
|
|
- return rtc_counter_get();
|
|
|
-}
|
|
|
-
|
|
|
-/*tz quarter-hour ,15min ,-48~+48*/
|
|
|
-uint32_t shark_rtc_get_timestamp_with_time_zone(int8_t tz){
|
|
|
- return (rtc_counter_get()+ tz*15*60);
|
|
|
+ rcu_osci_on(RCU_IRC40K);
|
|
|
+ rcu_osci_stab_wait(RCU_IRC40K);
|
|
|
|
|
|
-}
|
|
|
-
|
|
|
-void shark_rtc_getcurrtime_loca_time(time_val*ltc)
|
|
|
-{
|
|
|
- if(ltc==NULL) return;
|
|
|
- shark_rtc_get_local_time(shark_rtc_get_timestamp_with_time_zone(qws_status_get()->bike.qws_TZ ),ltc);
|
|
|
-
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-/* get utc timestamp --> macro second */
|
|
|
-uint64_t shark_rtc_get_timestamp_ms(void){
|
|
|
- return (uint64_t)rtc_counter_get() * 1000 + ((xTaskGetTickCount() - time_ticks) / portTICK_RATE_MS)%(1000/portTICK_RATE_MS);
|
|
|
-}
|
|
|
-
|
|
|
-/* set rtc time, used utc timestamp, can not include time zone*/
|
|
|
-uint32_t calendar_to_utc(time_val *time){
|
|
|
-
|
|
|
- struct tm utc_time;
|
|
|
- struct tm my_time;
|
|
|
- memset(&utc_time, 0, sizeof (struct tm));
|
|
|
- memset(&my_time, 0, sizeof (struct tm));
|
|
|
+ /* select RCU_RTCSRC_IRC40K as RTC clock source */
|
|
|
+ rcu_rtc_clock_config(RCU_RTCSRC_IRC40K);
|
|
|
+ /* enable RTC Clock */
|
|
|
+ rcu_periph_clock_enable(RCU_RTC);
|
|
|
|
|
|
- my_time.tm_mday = time->day;
|
|
|
- my_time.tm_mon = time->month- 1;
|
|
|
- my_time.tm_year = time->year - 1900;
|
|
|
- my_time.tm_hour = time->hour;
|
|
|
- my_time.tm_min = time->minute;
|
|
|
- my_time.tm_sec = time->second;
|
|
|
-
|
|
|
- utc_time.tm_mday = 1;
|
|
|
- utc_time.tm_mon = 1 - 1;
|
|
|
- utc_time.tm_year = 1970 - 1900;
|
|
|
- utc_time.tm_hour = 0;
|
|
|
- utc_time.tm_min = 0;
|
|
|
- utc_time.tm_sec = 0;
|
|
|
+ rtc_register_sync_wait();
|
|
|
|
|
|
- return mktime(&my_time) - mktime(&utc_time);
|
|
|
+ rtc_parameter_struct rtc_initpara;
|
|
|
+ memset(&rtc_initpara, 0, sizeof(rtc_initpara));
|
|
|
+ rtc_initpara.rtc_factor_asyn = 99;
|
|
|
+ rtc_initpara.rtc_factor_syn = 399;
|
|
|
+ rtc_initpara.rtc_display_format = RTC_24HOUR;
|
|
|
+ rtc_initpara.rtc_am_pm = RTC_AM;
|
|
|
+ rtc_initpara.rtc_date = 1;
|
|
|
+ rtc_init(&rtc_initpara);
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-void shark_rtc_set_time(time_val *time){
|
|
|
- uint32_t second = calendar_to_utc(time);
|
|
|
- /* wait until last write operation on RTC registers has finished */
|
|
|
- rtc_lwoff_wait();
|
|
|
- /* change the current time */
|
|
|
- rtc_counter_set(second);
|
|
|
- rtc_lwoff_wait();
|
|
|
+uint8_t _bcd_to_int(uint8_t bcd){
|
|
|
+ return (((bcd>>4)&0xF) *10) + (bcd&0xF);
|
|
|
}
|
|
|
|
|
|
-void shark_rtc_set_time_with_utc_second(uint32_t utc_s){
|
|
|
- /* wait until last write operation on RTC registers has finished */
|
|
|
- rtc_lwoff_wait();
|
|
|
- /* change the current time */
|
|
|
- rtc_counter_set(utc_s);
|
|
|
- rtc_lwoff_wait();
|
|
|
+uint8_t _int_to_bcd(uint8_t data){
|
|
|
+ return ((((data/10) << 4)&0xF0) | ((data%10) & 0xF));
|
|
|
}
|
|
|
|
|
|
-static void shark_rtc_first_init(void){
|
|
|
- //keep rtc running and inited while chip reset
|
|
|
- if (shark_bkp_first_startup()){
|
|
|
-
|
|
|
-
|
|
|
- /* enable PMU and BKPI clocks */
|
|
|
- rcu_periph_clock_enable(RCU_BKPI);
|
|
|
- rcu_periph_clock_enable(RCU_PMU);
|
|
|
- /* allow access to BKP domain */
|
|
|
- pmu_backup_write_enable();
|
|
|
-
|
|
|
- /* reset backup domain */
|
|
|
- bkp_deinit();
|
|
|
- rcu_osci_on(RCU_IRC40K);
|
|
|
- rcu_osci_stab_wait(RCU_IRC40K);
|
|
|
-
|
|
|
- /* select RCU_RTCSRC_IRC40K as RTC clock source */
|
|
|
- rcu_rtc_clock_config(RCU_RTCSRC_IRC40K);
|
|
|
-
|
|
|
- /* enable RTC Clock */
|
|
|
- rcu_periph_clock_enable(RCU_RTC);
|
|
|
-
|
|
|
- /* wait for RTC registers synchronization */
|
|
|
- rtc_register_sync_wait();
|
|
|
-
|
|
|
- /* wait until last write operation on RTC registers has finished */
|
|
|
- rtc_lwoff_wait();
|
|
|
-
|
|
|
- rtc_interrupt_enable(RTC_INT_SECOND);
|
|
|
- /* wait until last write operation on RTC registers has finished */
|
|
|
- rtc_lwoff_wait();
|
|
|
-
|
|
|
- //set 1s a tick
|
|
|
- rtc_prescaler_set(40000-1);
|
|
|
-
|
|
|
- /* wait until last write operation on RTC registers has finished */
|
|
|
- rtc_lwoff_wait();
|
|
|
-
|
|
|
- bkp_write_data(POWER_FIRSTFLAG_REG, POWER_FIRSTFLAG_VALUE);
|
|
|
-
|
|
|
- }else{
|
|
|
- /* allow access to BKP domain */
|
|
|
- rcu_periph_clock_enable(RCU_PMU);
|
|
|
- pmu_backup_write_enable();
|
|
|
-
|
|
|
- rcu_osci_on(RCU_IRC40K);
|
|
|
- rcu_osci_stab_wait(RCU_IRC40K);
|
|
|
-
|
|
|
- /* select RCU_RTCSRC_IRC40K as RTC clock source */
|
|
|
- rcu_rtc_clock_config(RCU_RTCSRC_IRC40K);
|
|
|
-
|
|
|
- /* enable RTC Clock */
|
|
|
- rcu_periph_clock_enable(RCU_RTC);
|
|
|
-
|
|
|
- /* wait for RTC registers synchronization */
|
|
|
- rtc_register_sync_wait();
|
|
|
- rtc_lwoff_wait();
|
|
|
- /* enable the RTC second and alarm interrupt*/
|
|
|
- rtc_interrupt_enable(RTC_INT_SECOND);
|
|
|
- rtc_lwoff_wait();
|
|
|
- }
|
|
|
+int shark_rtc_get_second(void){
|
|
|
+ rtc_parameter_struct rtc_time;
|
|
|
+ rtc_current_time_get(&rtc_time);
|
|
|
+ return _bcd_to_int(rtc_time.rtc_second);
|
|
|
}
|
|
|
|
|
|
-static void shark_rtc_enable_second_irq(int enable){
|
|
|
- if (enable){
|
|
|
- nvic_irq_enable(RTC_IRQn, 2U, 0U);
|
|
|
- }else{
|
|
|
- nvic_irq_disable(RTC_IRQn);
|
|
|
+/* sencod must less than 59 */
|
|
|
+static int set_rtc_alarm(uint32_t sencod){
|
|
|
+ rtc_parameter_struct rtc_initpara;
|
|
|
+
|
|
|
+ rtc_current_time_get(&rtc_initpara);
|
|
|
+
|
|
|
+ rtc_alarm_struct rtc_alarm;
|
|
|
+ memset(&rtc_alarm, 0, sizeof(rtc_alarm));
|
|
|
+ rtc_alarm.rtc_am_pm = rtc_initpara.rtc_am_pm;
|
|
|
+ rtc_alarm.rtc_alarm_mask = RTC_ALARM_DATE_MASK | RTC_ALARM_HOUR_MASK | RTC_ALARM_MINUTE_MASK;
|
|
|
+ rtc_alarm.rtc_alarm_day = rtc_initpara.rtc_date;
|
|
|
+ rtc_alarm.rtc_alarm_hour = rtc_initpara.rtc_hour;
|
|
|
+ rtc_alarm.rtc_alarm_minute = rtc_initpara.rtc_minute;
|
|
|
+ rtc_alarm.rtc_weekday_or_date = rtc_initpara.rtc_day_of_week;
|
|
|
+ uint8_t rtc_second = _bcd_to_int(rtc_initpara.rtc_second) + sencod;
|
|
|
+ if (rtc_second >= 60){
|
|
|
+ rtc_second -= 60;
|
|
|
}
|
|
|
-}
|
|
|
-
|
|
|
-void shark_rtc_init(void){
|
|
|
- shark_rtc_first_init();
|
|
|
- nvic_irq_enable(RTC_Alarm_IRQn , 2U, 0U);
|
|
|
- exti_init(EXTI_17, EXTI_INTERRUPT, EXTI_TRIG_RISING);
|
|
|
-
|
|
|
- exti_flag_clear(EXTI_17);
|
|
|
- exti_interrupt_enable(EXTI_17);
|
|
|
-
|
|
|
- shark_rtc_enable_second_irq(1);
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-int rtc_lwoff_wait_timeout(void)
|
|
|
-{
|
|
|
- int wait_count = 0xffff;
|
|
|
- /* loop until LWOFF flag is set */
|
|
|
- while(RESET == (RTC_CTL & RTC_CTL_LWOFF)){
|
|
|
- if (wait_count -- <= 0){
|
|
|
- return -1;
|
|
|
- }
|
|
|
- }
|
|
|
+ rtc_alarm.rtc_alarm_second = _int_to_bcd(rtc_second);
|
|
|
+ rtc_alarm_config(&rtc_alarm);
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
|
|
|
-static int set_rtc_alarm(uint32_t sencod){
|
|
|
- uint32_t current_count=0;
|
|
|
- current_count = rtc_counter_get();
|
|
|
- //rtc_lwoff_wait();
|
|
|
- rtc_alarm_config(current_count + sencod);
|
|
|
- return rtc_lwoff_wait_timeout();
|
|
|
-}
|
|
|
-
|
|
|
int shark_rtc_start_alarm(uint32_t second){
|
|
|
- rtc_lwoff_wait();
|
|
|
- rtc_interrupt_enable(RTC_INT_ALARM);// second means a shot here
|
|
|
- rtc_lwoff_wait();
|
|
|
- rtc_flag_clear(RTC_INT_SECOND ); //RTC_INT_FLAG_SECOND
|
|
|
- rtc_lwoff_wait();
|
|
|
- rtc_interrupt_disable(RTC_INT_SECOND);
|
|
|
- rtc_lwoff_wait();
|
|
|
- return set_rtc_alarm(second);
|
|
|
+ rtc_alarm_disable();
|
|
|
+ set_rtc_alarm(second);
|
|
|
+ rtc_interrupt_enable(RTC_INT_ALARM);
|
|
|
+ rtc_alarm_enable();
|
|
|
+ exti_init(EXTI_17,EXTI_INTERRUPT,EXTI_TRIG_RISING);
|
|
|
+ nvic_irq_enable(RTC_IRQn,4,0);
|
|
|
+ return 0;
|
|
|
}
|
|
|
|
|
|
|
|
|
void shark_rtc_stop_alarm(void){
|
|
|
- rtc_lwoff_wait();
|
|
|
+ rtc_alarm_disable();
|
|
|
+ rtc_flag_clear(RTC_STAT_ALRM0F);
|
|
|
rtc_interrupt_disable(RTC_INT_ALARM);
|
|
|
- rtc_lwoff_wait();
|
|
|
- rtc_interrupt_enable(RTC_INT_SECOND);
|
|
|
- rtc_lwoff_wait();
|
|
|
}
|
|
|
void shark_rtc_update_alarm(uint32_t sencod){
|
|
|
+ rtc_alarm_disable();
|
|
|
set_rtc_alarm(sencod);
|
|
|
-}
|
|
|
-
|
|
|
-uint32_t qws_rtc_irq_times = 0;
|
|
|
-static alarm_handler s_handler = NULL;
|
|
|
-
|
|
|
-void shark_rtc_set_alarm_handler(alarm_handler handler){
|
|
|
- s_handler = handler;
|
|
|
-}
|
|
|
-void RTC_Alarm_IRQHandler(void)
|
|
|
-{
|
|
|
- if (rtc_flag_get(RTC_INT_ALARM) != RESET)
|
|
|
- {
|
|
|
- /* clear the RTC second interrupt flag*/
|
|
|
- rtc_flag_clear(RTC_INT_ALARM);
|
|
|
- if (s_handler != NULL){
|
|
|
- s_handler();
|
|
|
- }
|
|
|
- qws_rtc_irq_times++;
|
|
|
- }
|
|
|
-
|
|
|
- exti_interrupt_flag_clear(EXTI_17);
|
|
|
+ rtc_alarm_enable();
|
|
|
}
|
|
|
|
|
|
|
|
|
void RTC_IRQHandler(void){
|
|
|
- if (rtc_flag_get(RTC_INT_OVERFLOW /*RTC_INT_FLAG_OVERFLOW*/) != RESET)
|
|
|
- {
|
|
|
- /* clear the RTC overflow interrupt flag*/
|
|
|
- rtc_flag_clear(RTC_INT_OVERFLOW);
|
|
|
- }
|
|
|
-
|
|
|
- if (rtc_flag_get(RTC_INT_SECOND) != RESET)
|
|
|
- {
|
|
|
- time_ticks = xTaskGetTickCount();
|
|
|
- /* clear the RTC second interrupt flag*/
|
|
|
- rtc_flag_clear(RTC_INT_SECOND);
|
|
|
- }
|
|
|
+ if(RESET != rtc_flag_get(RTC_STAT_ALRM0F)){
|
|
|
+ rtc_flag_clear(RTC_STAT_ALRM0F);
|
|
|
+ exti_flag_clear(EXTI_17);
|
|
|
+ }
|
|
|
}
|