main.c 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. /*!
  2. \file main.c
  3. \brief RTC tamper with timestamp demo
  4. */
  5. /*
  6. Copyright (C) 2017 GigaDevice
  7. 2017-06-06, V1.0.0, firmware for GD32F3x0
  8. */
  9. #include "gd32f3x0.h"
  10. #include <stdio.h>
  11. #include "main.h"
  12. #include "gd32f3x0_eval.h"
  13. #define RTC_CLOCK_SOURCE_IRC40K
  14. rtc_timestamp_struct rtc_timestamp;
  15. rtc_tamper_struct rtc_tamper;
  16. rtc_parameter_struct rtc_initpara;
  17. __IO uint32_t prescaler_a = 0, prescaler_s = 0;
  18. void rtc_setup(void);
  19. void rtc_show_time(void);
  20. void rtc_show_timestamp(void);
  21. uint8_t usart_input_threshold(uint32_t value);
  22. void rtc_pre_config(void);
  23. /*!
  24. \brief main function
  25. \param[in] none
  26. \param[out] none
  27. \retval none
  28. */
  29. int main(void)
  30. {
  31. gd_eval_com_init(EVAL_COM1);
  32. nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2);
  33. printf("\n\r ************* RTC tamper with timestamp demo *************\n\r");
  34. /* enable access to RTC registers in backup domain */
  35. rcu_periph_clock_enable(RCU_PMU);
  36. pmu_backup_write_enable();
  37. rtc_pre_config();
  38. rtc_tamper_disable(RTC_TAMPER0);
  39. /* check if RTC has aready been configured */
  40. if (BKP_VALUE != RTC_BKP0){
  41. rtc_setup();
  42. }else{
  43. /* detect the reset source */
  44. if (RESET != rcu_flag_get(RCU_FLAG_PORRST)){
  45. printf("power on reset occurred....\n\r");
  46. }else if (RESET != rcu_flag_get(RCU_FLAG_EPRST)){
  47. printf("external reset occurred....\n\r");
  48. }
  49. printf("no need to configure RTC....\n\r");
  50. rtc_show_time();
  51. }
  52. rcu_all_reset_flag_clear();
  53. gd_eval_led_init(LED1);
  54. gd_eval_led_off(LED1);
  55. gd_eval_led_init(LED2);
  56. gd_eval_led_off(LED2);
  57. gd_eval_led_init(LED3);
  58. gd_eval_led_off(LED3);
  59. exti_flag_clear(EXTI_19);
  60. exti_init(EXTI_19,EXTI_INTERRUPT,EXTI_TRIG_FALLING);
  61. nvic_irq_enable(RTC_IRQn,0,0);
  62. /* RTC tamper configuration */
  63. rtc_tamper.rtc_tamper_filter = RTC_FLT_EDGE;
  64. rtc_tamper.rtc_tamper_source = RTC_TAMPER0;
  65. rtc_tamper.rtc_tamper_trigger = RTC_TAMPER_TRIGGER_EDGE_FALLING;
  66. rtc_tamper.rtc_tamper_with_timestamp = ENABLE;
  67. rtc_tamper_enable(&rtc_tamper);
  68. rtc_interrupt_enable(RTC_INT_TAMP);
  69. rtc_flag_clear(RTC_STAT_TSF|RTC_STAT_TSOVRF|RTC_STAT_TP0F);
  70. while (1);
  71. }
  72. /*!
  73. \brief RTC configuration function
  74. \param[in] none
  75. \param[out] none
  76. \retval none
  77. */
  78. void rtc_pre_config(void)
  79. {
  80. #if defined (RTC_CLOCK_SOURCE_IRC40K)
  81. rcu_osci_on(RCU_IRC40K);
  82. rcu_osci_stab_wait(RCU_IRC40K);
  83. rcu_rtc_clock_config(RCU_RTCSRC_IRC40K);
  84. prescaler_s = 0x18F;
  85. prescaler_a = 0x63;
  86. #elif defined (RTC_CLOCK_SOURCE_LXTAL)
  87. rcu_osci_on(RCU_LXTAL);
  88. rcu_osci_stab_wait(RCU_LXTAL);
  89. rcu_rtc_clock_config(RCU_RTC_LXTAL);
  90. prescaler_s = 0xFF;
  91. prescaler_a = 0x7F;
  92. #else
  93. #error RTC clock source should be defined.
  94. #endif /* RTC_CLOCK_SOURCE_IRC40K */
  95. rcu_periph_clock_enable(RCU_RTC);
  96. rtc_register_sync_wait();
  97. }
  98. /*!
  99. \brief use hyperterminal to setup RTC time and alarm
  100. \param[in] none
  101. \param[out] none
  102. \retval none
  103. */
  104. void rtc_setup(void)
  105. {
  106. /* setup RTC time value */
  107. uint32_t tmp_hh = 0xFF, tmp_mm = 0xFF, tmp_ss = 0xFF;
  108. rtc_initpara.rtc_factor_asyn = prescaler_a;
  109. rtc_initpara.rtc_factor_syn = prescaler_s;
  110. rtc_initpara.rtc_year = 0x16;
  111. rtc_initpara.rtc_day_of_week = RTC_SATURDAY;
  112. rtc_initpara.rtc_month = RTC_APR;
  113. rtc_initpara.rtc_date = 0x30;
  114. rtc_initpara.rtc_display_format = RTC_24HOUR;
  115. rtc_initpara.rtc_am_pm = RTC_AM;
  116. /* current time input */
  117. printf("=======Configure RTC Time========\n\r");
  118. printf(" please input hour:\n\r");
  119. while (tmp_hh == 0xFF){
  120. tmp_hh = usart_input_threshold(23);
  121. rtc_initpara.rtc_hour = tmp_hh;
  122. }
  123. printf(" %0.2x\n\r", tmp_hh);
  124. printf(" please input minute:\n\r");
  125. while (tmp_mm == 0xFF){
  126. tmp_mm = usart_input_threshold(59);
  127. rtc_initpara.rtc_minute = tmp_mm;
  128. }
  129. printf(" %0.2x\n\r", tmp_mm);
  130. printf(" please input second:\n\r");
  131. while (tmp_ss == 0xFF){
  132. tmp_ss = usart_input_threshold(59);
  133. rtc_initpara.rtc_second = tmp_ss;
  134. }
  135. printf(" %0.2x\n\r", tmp_ss);
  136. /* RTC current time configuration */
  137. if(ERROR == rtc_init(&rtc_initpara)){
  138. printf("** RTC time configuration failed! **\n\r");
  139. }else{
  140. printf("** RTC time configuration success! **\n\r");
  141. rtc_show_time();
  142. RTC_BKP0 = BKP_VALUE;
  143. }
  144. }
  145. /*!
  146. \brief display the timestamp time
  147. \param[in] none
  148. \param[out] none
  149. \retval none
  150. */
  151. void rtc_show_timestamp(void)
  152. {
  153. uint32_t ts_subsecond = 0;
  154. uint8_t ts_subsecond_ss,ts_subsecond_ts,ts_subsecond_hs ;
  155. rtc_timestamp_get(&rtc_timestamp);
  156. /* get the subsecond value of timestamp time, and convert it into fractional format */
  157. ts_subsecond = rtc_timestamp_subsecond_get();
  158. ts_subsecond_ss=(1000-(ts_subsecond*1000+1000)/400)/100;
  159. ts_subsecond_ts=(1000-(ts_subsecond*1000+1000)/400)%100/10;
  160. ts_subsecond_hs=(1000-(ts_subsecond*1000+1000)/400)%10;
  161. printf("Get the time-stamp time: %0.2x:%0.2x:%0.2x .%d%d%d \n\r", \
  162. rtc_timestamp.rtc_timestamp_hour, rtc_timestamp.rtc_timestamp_minute, rtc_timestamp.rtc_timestamp_second,\
  163. ts_subsecond_ss, ts_subsecond_ts, ts_subsecond_hs);
  164. }
  165. /*!
  166. \brief display the current time
  167. \param[in] none
  168. \param[out] none
  169. \retval none
  170. */
  171. void rtc_show_time(void)
  172. {
  173. uint32_t time_subsecond = 0;
  174. uint8_t subsecond_ss = 0,subsecond_ts = 0,subsecond_hs = 0;
  175. rtc_current_time_get(&rtc_initpara);
  176. /* get the subsecond value of current time, and convert it into fractional format */
  177. time_subsecond = rtc_subsecond_get();
  178. subsecond_ss=(1000-(time_subsecond*1000+1000)/400)/100;
  179. subsecond_ts=(1000-(time_subsecond*1000+1000)/400)%100/10;
  180. subsecond_hs=(1000-(time_subsecond*1000+1000)/400)%10;
  181. printf("Current time: %0.2x:%0.2x:%0.2x .%d%d%d \n\r", \
  182. rtc_initpara.rtc_hour, rtc_initpara.rtc_minute, rtc_initpara.rtc_second,\
  183. subsecond_ss, subsecond_ts, subsecond_hs);
  184. }
  185. /*!
  186. \brief get the input character string and check if it is valid
  187. \param[in] none
  188. \param[out] none
  189. \retval input value in BCD mode
  190. */
  191. uint8_t usart_input_threshold(uint32_t value)
  192. {
  193. uint32_t index = 0;
  194. uint32_t tmp[2] = {0, 0};
  195. while (index < 2){
  196. while (RESET == usart_flag_get(EVAL_COM1, USART_FLAG_RBNE));
  197. tmp[index++] = usart_data_receive(EVAL_COM1);
  198. if ((tmp[index - 1] < 0x30) || (tmp[index - 1] > 0x39)){
  199. printf("\n\r please input a valid number between 0 and 9 \n\r");
  200. index--;
  201. }
  202. }
  203. index = (tmp[1] - 0x30) + ((tmp[0] - 0x30) * 10);
  204. if (index > value){
  205. printf("\n\r please input a valid number between 0 and %d \n\r", value);
  206. return 0xFF;
  207. }
  208. index = (tmp[1] - 0x30) + ((tmp[0] - 0x30) <<4);
  209. return index;
  210. }
  211. /* retarget the C library printf function to the USART */
  212. int fputc(int ch, FILE *f)
  213. {
  214. usart_data_transmit(EVAL_COM1, (uint8_t) ch);
  215. while (RESET == usart_flag_get(EVAL_COM1,USART_FLAG_TC));
  216. return ch;
  217. }