main.c 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. /*!
  2. \file main.c
  3. \brief RTC calendar alarm 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 "gd32f3x0_eval.h"
  12. #define RTC_CLOCK_SOURCE_IRC40K
  13. #define BKP_VALUE 0x32F0
  14. rtc_parameter_struct rtc_initpara;
  15. rtc_alarm_struct rtc_alarm;
  16. __IO uint32_t prescaler_a = 0, prescaler_s = 0;
  17. void rtc_setup(void);
  18. void rtc_show_time(void);
  19. void rtc_show_alarm(void);
  20. uint8_t usart_input_threshold(uint32_t value);
  21. void rtc_pre_config(void);
  22. /*!
  23. \brief main function
  24. \param[in] none
  25. \param[out] none
  26. \retval none
  27. */
  28. int main(void)
  29. {
  30. gd_eval_com_init(EVAL_COM1);
  31. printf("\n\r ****************** RTC calendar alarm demo ******************\n\r");
  32. /* enable PMU clock */
  33. rcu_periph_clock_enable(RCU_PMU);
  34. /* enable the access of the RTC registers */
  35. pmu_backup_write_enable();
  36. rtc_pre_config();
  37. /* check if RTC has aready been configured */
  38. if (BKP_VALUE != RTC_BKP0){
  39. rtc_setup();
  40. }else{
  41. /* detect the reset source */
  42. if (RESET != rcu_flag_get(RCU_FLAG_PORRST)){
  43. printf("power on reset occurred....\n\r");
  44. }else if (RESET != rcu_flag_get(RCU_FLAG_EPRST)){
  45. printf("external reset occurred....\n\r");
  46. }
  47. printf("no need to configure RTC....\n\r");
  48. rtc_flag_clear(RTC_STAT_ALRM0F);
  49. exti_flag_clear(EXTI_17);
  50. rtc_show_time();
  51. rtc_show_alarm();
  52. }
  53. rcu_all_reset_flag_clear();
  54. /* configure the leds */
  55. gd_eval_led_init(LED1);
  56. gd_eval_led_on(LED1);
  57. gd_eval_led_init(LED2);
  58. gd_eval_led_on(LED2);
  59. /* RTC alarm interrupt configuration */
  60. exti_init(EXTI_17,EXTI_INTERRUPT,EXTI_TRIG_RISING);
  61. nvic_irq_enable(RTC_IRQn,0,0);
  62. while (1);
  63. }
  64. /*!
  65. \brief RTC configuration function
  66. \param[in] none
  67. \param[out] none
  68. \retval none
  69. */
  70. void rtc_pre_config(void)
  71. {
  72. #if defined (RTC_CLOCK_SOURCE_IRC40K)
  73. rcu_osci_on(RCU_IRC40K);
  74. rcu_osci_stab_wait(RCU_IRC40K);
  75. rcu_rtc_clock_config(RCU_RTCSRC_IRC40K);
  76. prescaler_s = 0x18F;
  77. prescaler_a = 0x63;
  78. #elif defined (RTC_CLOCK_SOURCE_LXTAL)
  79. rcu_osci_on(RCU_LXTAL);
  80. rcu_osci_stab_wait(RCU_LXTAL);
  81. rcu_rtc_clock_config(RCU_RTC_LXTAL);
  82. prescaler_s = 0xFF;
  83. prescaler_a = 0x7F;
  84. #else
  85. #error RTC clock source should be defined.
  86. #endif /* RTC_CLOCK_SOURCE_IRC40K */
  87. rcu_periph_clock_enable(RCU_RTC);
  88. rtc_register_sync_wait();
  89. }
  90. /*!
  91. \brief use hyperterminal to setup RTC time and alarm
  92. \param[in] none
  93. \param[out] none
  94. \retval none
  95. */
  96. void rtc_setup(void)
  97. {
  98. /* setup RTC time value */
  99. uint32_t tmp_hh = 0xFF, tmp_mm = 0xFF, tmp_ss = 0xFF;
  100. rtc_initpara.rtc_factor_asyn = prescaler_a;
  101. rtc_initpara.rtc_factor_syn = prescaler_s;
  102. rtc_initpara.rtc_year = 0x16;
  103. rtc_initpara.rtc_day_of_week = RTC_SATURDAY;
  104. rtc_initpara.rtc_month = RTC_APR;
  105. rtc_initpara.rtc_date = 0x30;
  106. rtc_initpara.rtc_display_format = RTC_24HOUR;
  107. rtc_initpara.rtc_am_pm = RTC_AM;
  108. /* current time input */
  109. printf("=======Configure RTC Time========\n\r");
  110. printf(" please input hour:\n\r");
  111. while (tmp_hh == 0xFF){
  112. tmp_hh = usart_input_threshold(23);
  113. rtc_initpara.rtc_hour = tmp_hh;
  114. }
  115. printf(" %0.2x\n\r", tmp_hh);
  116. printf(" please input minute:\n\r");
  117. while (tmp_mm == 0xFF){
  118. tmp_mm = usart_input_threshold(59);
  119. rtc_initpara.rtc_minute = tmp_mm;
  120. }
  121. printf(" %0.2x\n\r", tmp_mm);
  122. printf(" please input second:\n\r");
  123. while (tmp_ss == 0xFF){
  124. tmp_ss = usart_input_threshold(59);
  125. rtc_initpara.rtc_second = tmp_ss;
  126. }
  127. printf(" %0.2x\n\r", tmp_ss);
  128. /* RTC current time configuration */
  129. if(ERROR == rtc_init(&rtc_initpara)){
  130. printf("\n\r** RTC time configuration failed! **\n\r");
  131. }else{
  132. printf("\n\r** RTC time configuration success! **\n\r");
  133. rtc_show_time();
  134. RTC_BKP0 = BKP_VALUE;
  135. }
  136. /* setup RTC alarm */
  137. tmp_hh = 0xFF;
  138. tmp_mm = 0xFF;
  139. tmp_ss = 0xFF;
  140. rtc_alarm_disable();
  141. printf("=======Input Alarm Value=======\n\r");
  142. rtc_alarm.rtc_alarm_mask = RTC_ALARM_DATE_MASK|RTC_ALARM_HOUR_MASK|RTC_ALARM_MINUTE_MASK;
  143. rtc_alarm.rtc_weekday_or_date = RTC_ALARM_DATE_SELECTED;
  144. rtc_alarm.rtc_alarm_day = 0x31;
  145. rtc_alarm.rtc_am_pm = RTC_AM;
  146. /* RTC alarm input */
  147. printf(" please input Alarm Hour:\n\r");
  148. while (tmp_hh == 0xFF){
  149. tmp_hh = usart_input_threshold(23);
  150. rtc_alarm.rtc_alarm_hour = tmp_hh;
  151. }
  152. printf(" %0.2x\n\r", tmp_hh);
  153. printf(" Please Input Alarm Minute:\n\r");
  154. while (tmp_mm == 0xFF){
  155. tmp_mm = usart_input_threshold(59);
  156. rtc_alarm.rtc_alarm_minute = tmp_mm;
  157. }
  158. printf(" %0.2x\n\r", tmp_mm);
  159. printf(" Please Input Alarm Second:\n\r");
  160. while (tmp_ss == 0xFF){
  161. tmp_ss = usart_input_threshold(59);
  162. rtc_alarm.rtc_alarm_second = tmp_ss;
  163. }
  164. printf(" %0.2x", tmp_ss);
  165. /* RTC alarm configuration */
  166. rtc_alarm_config(&rtc_alarm);
  167. printf("\n\r** RTC Set Alarm Success! **\n\r");
  168. rtc_show_time();
  169. rtc_show_alarm();
  170. rtc_interrupt_enable(RTC_INT_ALARM);
  171. rtc_alarm_enable();
  172. }
  173. /*!
  174. \brief display the current time
  175. \param[in] none
  176. \param[out] none
  177. \retval none
  178. */
  179. void rtc_show_time(void)
  180. {
  181. uint32_t time_subsecond = 0;
  182. uint8_t subsecond_ss = 0,subsecond_ts = 0,subsecond_hs = 0;
  183. rtc_current_time_get(&rtc_initpara);
  184. /* get the subsecond value of current time, and convert it into fractional format */
  185. time_subsecond = rtc_subsecond_get();
  186. subsecond_ss=(1000-(time_subsecond*1000+1000)/400)/100;
  187. subsecond_ts=(1000-(time_subsecond*1000+1000)/400)%100/10;
  188. subsecond_hs=(1000-(time_subsecond*1000+1000)/400)%10;
  189. printf("Current time: %0.2x:%0.2x:%0.2x .%d%d%d \n\r", \
  190. rtc_initpara.rtc_hour, rtc_initpara.rtc_minute, rtc_initpara.rtc_second,\
  191. subsecond_ss, subsecond_ts, subsecond_hs);
  192. }
  193. /*!
  194. \brief display the alram value
  195. \param[in] none
  196. \param[out] none
  197. \retval none
  198. */
  199. void rtc_show_alarm(void)
  200. {
  201. rtc_alarm_get(&rtc_alarm);
  202. printf("The alarm: %0.2x:%0.2x:%0.2x \n\r", rtc_alarm.rtc_alarm_hour, rtc_alarm.rtc_alarm_minute,\
  203. rtc_alarm.rtc_alarm_second);
  204. }
  205. /*!
  206. \brief get the input character string and check if it is valid
  207. \param[in] none
  208. \param[out] none
  209. \retval input value in BCD mode
  210. */
  211. uint8_t usart_input_threshold(uint32_t value)
  212. {
  213. uint32_t index = 0;
  214. uint32_t tmp[2] = {0, 0};
  215. while (index < 2){
  216. while (RESET == usart_flag_get(EVAL_COM1, USART_FLAG_RBNE));
  217. tmp[index++] = usart_data_receive(EVAL_COM1);
  218. if ((tmp[index - 1] < 0x30) || (tmp[index - 1] > 0x39)){
  219. printf("\n\r please input a valid number between 0 and 9 \n\r");
  220. index--;
  221. }
  222. }
  223. index = (tmp[1] - 0x30) + ((tmp[0] - 0x30) * 10);
  224. if (index > value){
  225. printf("\n\r please input a valid number between 0 and %d \n\r", value);
  226. return 0xFF;
  227. }
  228. index = (tmp[1] - 0x30) + ((tmp[0] - 0x30) <<4);
  229. return index;
  230. }
  231. /* retarget the C library printf function to the USART */
  232. int fputc(int ch, FILE *f)
  233. {
  234. usart_data_transmit(EVAL_COM1, (uint8_t) ch);
  235. while (RESET == usart_flag_get(EVAL_COM1,USART_FLAG_TC));
  236. return ch;
  237. }