rtc_timestamp_struct rtc_timestamp;
rtc_tamper_struct rtc_tamper;
rtc_parameter_struct rtc_initpara;
__IO uint32_t prescaler_a = 0, prescaler_s = 0;
void rtc_pre_config(void);
void RTC_init(void)
{
#if 0
nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2);
rcu_periph_clock_enable(RCU_GPIOC);
rcu_periph_clock_enable(RCU_SYSCFG);
gpio_mode_set(GPIOC, GPIO_MODE_INPUT, GPIO_PUPD_NONE, GPIO_PIN_13);
#endif
// enable access to RTC registers in backup domain
rcu_periph_clock_enable(RCU_PMU);
pmu_backup_write_enable();
rtc_pre_config();
// rtc_tamper_disable(RTC_TAMPER0);
/* check if RTC has aready been configured */
if (BKP_VALUE != RTC_BKP0)
{
rtc_time_set(0x22, RTC_MAY, 0x17, 0x00, 0x00, 0x00);
}
else
{
/* detect the reset source */
if (RESET != rcu_flag_get(RCU_FLAG_PORRST))
{
// printf("power on reset occurred....\n\r");
}
else if (RESET != rcu_flag_get(RCU_FLAG_EPRST))
{
// printf("external reset occurred....\n\r");
}
// printf("no need to configure RTC....\n\r");
// rtc_show_time();
}
rcu_all_reset_flag_clear();
#if 0
exti_flag_clear(EXTI_21);
exti_init(EXTI_21, EXTI_INTERRUPT, EXTI_TRIG_RISING);
nvic_irq_enable(TAMPER_STAMP_IRQn, 0, 0);
/* RTC tamper configuration */
rtc_tamper.tamper_filter = RTC_FLT_EDGE;
rtc_tamper.tamper_source = RTC_TAMPER0;
rtc_tamper.tamper_trigger = RTC_TAMPER_TRIGGER_EDGE_FALLING;
rtc_tamper.tamper_with_timestamp = ENABLE;
rtc_tamper_enable(&rtc_tamper);
rtc_interrupt_enable(RTC_INT_TAMP);
rtc_flag_clear(RTC_FLAG_TS | RTC_FLAG_TSOVR | RTC_FLAG_TP0);
/* rtc_timestamp_enable(RTC_TIMESTAMP_FALLING_EDGE);
rtc_interrupt_enable(RTC_INT_TIMESTAMP);
rtc_flag_clear(RTC_FLAG_TS | RTC_FLAG_TSOVR); */
#endif
}
void rtc_pre_config(void)
{
#if defined(RTC_CLOCK_SOURCE_IRC32K)
rcu_osci_on(RCU_IRC32K);
rcu_osci_stab_wait(RCU_IRC32K);
rcu_rtc_clock_config(RCU_RTCSRC_IRC32K);
prescaler_a = 0x63; // 0x63 ck_apre频率 = RTC_CLOCK / (prescaler_a+1) = 32000 / (99+1)=320HZ
prescaler_s = 0x118; // 0x13F ck_spre频率 = ck_apre / (prescaler_s+1) = 320 / (319+1)=1HZ
#elif defined(RTC_CLOCK_SOURCE_LXTAL)
rcu_osci_on(RCU_LXTAL);
rcu_osci_stab_wait(RCU_LXTAL);
rcu_rtc_clock_config(RCU_RTCSRC_LXTAL);
prescaler_a = 0x7F; // ck_apre频率 = RTC_CLOCK/(prescaler_a+1) = 32768/(127+1)=256HZ
prescaler_s = 0xFF; // ck_spre频率 = ck_apre/(prescaler_s+1) = 256/(255+1)=1HZ
#else
#error RTC clock source should be defined.
#endif /* RTC_CLOCK_SOURCE_IRC32K */
// rtc_smooth_calibration_config(RTC_CALIBRATION_WINDOW_32S, RTC_CALIBRATION_PLUS_SET, 0x1F);
// rtc_coarse_calibration_config(CALIB_INCREASE, 0x1F);
// rtc_coarse_calibration_config(CALIB_DECREASE, 0x1D); //对晶振进行粗校准
rcu_periph_clock_enable(RCU_RTC);
rtc_register_sync_wait();
}
ErrStatus rtc_time_set(uint16_t year, uint8_t month, uint8_t day, uint8_t hh, uint8_t mm, uint8_t ss)
{
rtc_initpara.factor_asyn = prescaler_a;
rtc_initpara.factor_syn = prescaler_s;
rtc_initpara.year = year & 0x00FF;
rtc_initpara.day_of_week = RTC_SATURDAY;
rtc_initpara.month = month;
rtc_initpara.date = day;
rtc_initpara.display_format = RTC_24HOUR;
rtc_initpara.am_pm = RTC_AM;
// current time input
// =======Configure RTC Time========
rtc_initpara.hour = hh;
rtc_initpara.minute = mm;
rtc_initpara.second = ss;
/* RTC current time configuration */
if (ERROR == rtc_init(&rtc_initpara))
{
return ERROR;
}
else
{
RTC_BKP0 = BKP_VALUE;
return SUCCESS;
}
}
ErrStatus rtc_time_update(uint16_t year, uint8_t month, uint8_t day, uint8_t hh, uint8_t mm, uint8_t ss)
{
uint32_t reg_time = 0U, reg_date = 0U;
ErrStatus error_status = ERROR;
reg_date = (DATE_YR(year) |
DATE_DOW(RTC_SATURDAY) |
DATE_MON(month) |
DATE_DAY(day));
reg_time = (RTC_AM |
TIME_HR(hh) |
TIME_MN(mm) |
TIME_SC(ss));
/* 1st: disable the write protection */
RTC_WPK = RTC_UNLOCK_KEY1;
RTC_WPK = RTC_UNLOCK_KEY2;
error_status = rtc_init_mode_enter();
if (ERROR != error_status)
{
RTC_TIME = (uint32_t)reg_time;
RTC_DATE = (uint32_t)reg_date;
rtc_init_mode_exit();
error_status = rtc_register_sync_wait();
}
RTC_WPK = RTC_LOCK_KEY;
return error_status;
}
void rtc_alart_set(uint8_t hh, uint8_t mm, uint8_t ss)
{
rtc_alarm_struct rtc_alarm;
rtc_alarm_disable(RTC_ALARM0);
rtc_alarm.alarm_mask = RTC_ALARM_DATE_MASK | RTC_ALARM_HOUR_MASK | RTC_ALARM_MINUTE_MASK;
rtc_alarm.weekday_or_date = RTC_ALARM_DATE_SELECTED;
rtc_alarm.alarm_day = 0x31;
rtc_alarm.am_pm = RTC_AM;
rtc_alarm.alarm_hour = hh;
rtc_alarm.alarm_minute = mm;
rtc_alarm.alarm_second = ss;
rtc_alarm_config(RTC_ALARM0, &rtc_alarm);
rtc_alarm_enable(RTC_ALARM0);
}
/**
* [url=home.php?mod=space&uid=247401]@brief[/url] timestamp time
*
*/
void rtc_show_timestamp(void)
{
char buf[128] = {0};
uint32_t ts_subsecond = 0;
uint8_t ts_subsecond_ss, ts_subsecond_ts, ts_subsecond_hs;
rtc_timestamp_get(&rtc_timestamp);
/* get the subsecond value of timestamp time, and convert it into fractional format */
ts_subsecond = rtc_timestamp_subsecond_get();
ts_subsecond_ss = (1000 - (ts_subsecond * 1000 + 1000) / 400) / 100;
ts_subsecond_ts = (1000 - (ts_subsecond * 1000 + 1000) / 400) % 100 / 10;
ts_subsecond_hs = (1000 - (ts_subsecond * 1000 + 1000) / 400) % 10;
sprintf(buf, "timestamp: %0.2x:%0.2x:%0.2x.%d%d%d \n\r",
rtc_timestamp.timestamp_hour, rtc_timestamp.timestamp_minute, rtc_timestamp.timestamp_second,
ts_subsecond_ss, ts_subsecond_ts, ts_subsecond_hs);
RS485_sendData(UART4, (uint8_t *)buf, strlen(buf));
}
/**
* [url=home.php?mod=space&uid=247401]@brief[/url] current time
*
*/
void rtc_show_time(void)
{
uint32_t time_subsecond = 0;
char buf[128] = {0};
uint8_t subsecond_ss = 0, subsecond_ts = 0, subsecond_hs = 0;
rtc_current_time_get(&rtc_initpara);
/* get the subsecond value of current time, and convert it into fractional format */
time_subsecond = rtc_subsecond_get();
subsecond_ss = (1000 - (time_subsecond * 1000 + 1000) / 400) / 100;
subsecond_ts = (1000 - (time_subsecond * 1000 + 1000) / 400) % 100 / 10;
subsecond_hs = (1000 - (time_subsecond * 1000 + 1000) / 400) % 10;
sprintf(buf, "CurTime: %0.2x:%0.2x:%0.2x.%d%d%d \n\r",
rtc_initpara.hour, rtc_initpara.minute, rtc_initpara.second,
subsecond_ss, subsecond_ts, subsecond_hs);
RS485_sendData(UART4, (uint8_t *)buf, strlen(buf));
Uart5_Send_Data((uint8_t *)buf, strlen(buf));
}
void RTC_WKUP_IRQHandler(void)
{
if (RESET != rtc_flag_get(RTC_FLAG_WT))
{
exti_flag_clear(EXTI_22);
// gd_eval_led_toggle(LED1);
// rtc_show_time();
rtc_flag_clear(RTC_FLAG_WT);
}
}
/*!
\brief this function handles RTC interrupt request
\param[in] none
\param[out] none
\retval none
*/
void RTC_Alarm_IRQHandler(void)
{
if (RESET != rtc_flag_get(RTC_FLAG_ALRM0))
{
rtc_flag_clear(RTC_FLAG_ALRM0);
exti_flag_clear(EXTI_17);
// gd_eval_led_toggle(LED2);
}
}
/*!
\brief this function handles RTC interrupt request
\param[in] none
\param[out] none
\retval none
*/
void TAMPER_STAMP_IRQHandler(void)
{
if (RESET != rtc_flag_get(RTC_FLAG_TP0))
// if (RESET != rtc_flag_get(RTC_FLAG_TS))
{
exti_flag_clear(EXTI_21);
// gd_eval_led_toggle(LED1);
/* if tamper0 event occurs, check if the BKP0 register has been reset or not */
/* if(BKP_VALUE != RTC_BKP0)
gd_eval_led_toggle(LED2);
else
gd_eval_led_toggle(LED3); */
rtc_show_timestamp();
rtc_flag_clear(RTC_FLAG_TS | RTC_FLAG_TSOVR | RTC_FLAG_TP0);
// rtc_flag_clear(RTC_FLAG_TS | RTC_FLAG_TSOVR);
}
}