rtc_isr.c 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. #include "board.h"
  2. #include "tdc_tof.h"
  3. #include "alarm.h"
  4. static rtc_run_t *pRtcRun;
  5. void rtc_init(rtc_run_t *rtc_run)
  6. {
  7. PeriClk_MutEnable(PeriClk_Rtc);
  8. M0P_RTC->CR0 = (1<<14) | // 0:PRDS; 1:PRDX;
  9. #ifdef RTC_INTERRUPT_TIME_5_S//add by yuewei 20260306
  10. (9<< 8) | // PRDX, 0:0.5s; 1:1s; 2:1.5s .... 63:32S
  11. #else
  12. (1<< 8) | // PRDX, 0:0.5s; 1:1s; 2:1.5s .... 63:32S
  13. #endif
  14. (0<< 7) | // start, 0:stop; 1:start;
  15. (0<< 6) | // HZ1SEL, 0:normal; 1:high precision
  16. (0<< 5) | // HZ1OE, 0:disable output 1Hz; 1:enable
  17. (1<< 3) | // AMPM, 0:12-hour; 1:24-hour;
  18. (0<< 0); // PRDS, 0:disable; 1:0.5s; 2:1s; 3:1m; 4:1h; 5:1d; 6:1m;
  19. M0P_RTC->CR1 = (0<< 8) | // 0,1:XTL; 2,3:RCL; 4:XTH=4M; 5:XTH=8M; 6:XTH=16M; 7:XTH=32M;
  20. (0<< 7) | // ALMEN, 0:disable alarm function; 1:enable
  21. (0<< 6); // ALMIE, 0:disable alarm interrupt; 1:enable
  22. pRtcRun = rtc_run;
  23. M0P_RTC->SEC = OctToBcd(rtc_run->second); // BCD
  24. M0P_RTC->MIN = OctToBcd(rtc_run->minute); // BCD
  25. M0P_RTC->HOUR = OctToBcd(rtc_run->hour); // BCD
  26. M0P_RTC->DAY = OctToBcd(rtc_run->day); // BCD
  27. M0P_RTC->WEEK = OctToBcd(rtc_run->week); // DEC 0~6
  28. M0P_RTC->MON = OctToBcd(rtc_run->month); // BCD
  29. M0P_RTC->YEAR = OctToBcd(rtc_run->year); // BCD
  30. M0P_RTC->CR0_f.START = 1;
  31. // enable interrupt at NVIC side
  32. IRQMutEnable(RTC_IRQn, NVIC_PRIO_0);
  33. }
  34. //add by yuewei 20260519
  35. /**
  36. * @brief 设置RTC:多少秒钟进入一次中断
  37. * @param time:0.5s, 1.0s, 1.5s, 2.0s...
  38. * @retval 无
  39. */
  40. void set_rtc_interrupt_time(float time)
  41. {
  42. uint8_t prdx_val = (uint8_t)(time * 2 - 1); // 公式:cycle = (prdx_val + 1) * 0.5s
  43. M0P_RTC->CR0 = (1<<14) | // 0:PRDS; 1:PRDX;
  44. (prdx_val << 8) | // PRDX, 0:0.5s; 1:1s; 2:1.5s .... 63:32S
  45. (1<< 7) | // start, 0:stop; 1:start;
  46. (0<< 6) | // HZ1SEL, 0:normal; 1:high precision
  47. (0<< 5) | // HZ1OE, 0:disable output 1Hz; 1:enable
  48. (1<< 3) | // AMPM, 0:12-hour; 1:24-hour;
  49. (0<< 0); // PRDS, 0:disable; 1:0.5s; 2:1s; 3:1m; 4:1h; 5:1d; 6:1m;
  50. }
  51. /**********************************************************************
  52. * 函数名:RTC_GetIrqSeconds
  53. * 功能 :
  54. * 返回 :
  55. **********************************************************************/
  56. /**
  57. * @brief 从 RTC->CR0 读取 PRDX 值,返回中断间隔秒数
  58. * @param 无
  59. * @retval float 类型,多少秒产生一次中断
  60. */
  61. float get_rtc_interrupt_time(void)
  62. {
  63. // 从 CR0 寄存器取出 [13:8] 位的 PRDX 值
  64. uint8_t prdx_val = (M0P_RTC->CR0 >> 8) & 0x3F; // 0x3F = 6位掩码
  65. // 按规则计算秒数
  66. float seconds = (prdx_val + 1) * 0.5f;
  67. return seconds;
  68. }
  69. void update_rtc_run(void)
  70. {
  71. rtc_run_t *rr = pRtcRun;
  72. if (rr->second != BcdToOct(M0P_RTC->SEC)) {
  73. rr->flag_1s = 1;
  74. rr->second = BcdToOct(M0P_RTC->SEC);
  75. }
  76. if (rr->minute != BcdToOct(M0P_RTC->MIN)) {
  77. rr->flag_1m = 1;
  78. rr->minute = BcdToOct(M0P_RTC->MIN);
  79. }
  80. rr->hour = BcdToOct(M0P_RTC->HOUR);
  81. rr->day = BcdToOct(M0P_RTC->DAY);
  82. rr->month = BcdToOct(M0P_RTC->MON);
  83. rr->year = BcdToOct(M0P_RTC->YEAR);
  84. rr->week = BcdToOct(M0P_RTC->WEEK);
  85. }
  86. void set_rtc_date(uint8_t year, uint8_t month, uint8_t day) {
  87. M0P_RTC->YEAR = year;
  88. M0P_RTC->MON = month;
  89. M0P_RTC->DAY = day;
  90. }
  91. void get_rtc_date(uint8_t *year, uint8_t *month, uint8_t *day) {
  92. *year = M0P_RTC->YEAR;
  93. *month = M0P_RTC->MON;
  94. *day = M0P_RTC->DAY;
  95. }
  96. void set_rtc_time(uint8_t hour, uint8_t min, uint8_t sec) {
  97. M0P_RTC->HOUR = hour;
  98. M0P_RTC->MIN = min;
  99. M0P_RTC->SEC = sec;
  100. }
  101. void get_rtc_time(uint8_t *hour, uint8_t *min, uint8_t *sec) {
  102. *hour = M0P_RTC->HOUR;
  103. *min = M0P_RTC->MIN;
  104. *sec = M0P_RTC->SEC;
  105. }
  106. uint32_t RTC_CntInt;
  107. uint32_t get_rtc_cnt_int(void) {
  108. return RTC_CntInt;
  109. }
  110. void set_rtc_cnt_int(uint32_t cnt_int) {
  111. RTC_CntInt = cnt_int;
  112. }
  113. static uint32_t TdcRwErrCnt = 0;
  114. uint32_t get_tdc_rw_err_cnt(void) {
  115. return TdcRwErrCnt;
  116. }
  117. uint32_t GetChIdx(uint32_t cnt) {
  118. if (pTdcItf->ch_num == 1) {
  119. return 0;
  120. } else if (pTdcItf->ch_num == 2) {
  121. return (cnt & 0x00000001);
  122. } else if (pTdcItf->ch_num == 4) {
  123. return (cnt & 0x00000003);
  124. }
  125. return 0;
  126. }
  127. static uint32_t MUX_SwitchInt = 0;
  128. void RTC_IRQHandler(void)
  129. {
  130. uint32_t ISR;
  131. ISR = M0P_RTC->CR1;
  132. M0P_RTC->CR1 = ISR & (~0x18u);
  133. //if(NB_RUN_UPDATE_FLAG == 1)return; //2026-4-8 wuxiaolin
  134. //add by yuewei 20260309 to deal hongwai long data
  135. if(HONGWAI_LONG_RX_FLAG == 1)return;
  136. //LOG("---------------------------------0\n");
  137. //return;
  138. //us_delay(2000);//!!!!!do not modify!!!!!
  139. //rt_thread_delay(5);//!!!!!do not modify!!!!!
  140. // get_internal_time();
  141. if (ISR & 0x08u)
  142. {
  143. rt_sem_release(&rtc_isr_sem);
  144. }
  145. }
  146. void rtc_interrupt_deal_tdc(void)
  147. {
  148. uint32_t Tu32;
  149. update_rtc_run();
  150. if (tof_state&(TOF_ST_METER | TOF_ST_CALIB | TOF_ST_VOID))
  151. {
  152. if (pTdcItf->mux_switch && ((RTC_CntInt & 0x00000001u) == 0) && pTdcItf->ch_num > 1)
  153. {
  154. uint32_t idx = GetChIdx(MUX_SwitchInt);
  155. set_mux_ch(pTdcItf->mux_ch_no[idx]);
  156. MUX_SwitchInt++;
  157. us_delay(50);
  158. }
  159. //LOG("---------------------------------1\n");
  160. RTC_CntInt++;
  161. }
  162. if (pTdcItf->blank_flag == pTdcItf->ch_bit_map)
  163. {
  164. if (tof_state&TOF_ST_METER)
  165. {
  166. tof_state = TOF_ST_VOID;
  167. }
  168. }
  169. else
  170. {
  171. if (tof_state&TOF_ST_VOID)
  172. {
  173. tof_state = TOF_ST_METER;
  174. }
  175. }
  176. if ((tof_state&(TOF_ST_METER|TOF_ST_CALIB)) || (tof_state&TOF_ST_VOID))
  177. {
  178. tof_flag &= ~TOF_FLAG_BLANK_PIPE;
  179. if (TdcIntStep!=0xFFu)
  180. {
  181. tof_flag |= TOF_FLAG_TDC_FAULT;
  182. }
  183. //空管状态会关闭MS1031的高频时钟,先打开MS1031的高频时钟才能进行后续操作
  184. if(alarm_status(ERR_BLANK_PIPE))
  185. {
  186. tdc_turn_on_off_high_clk(1);
  187. }
  188. // 根据RTC_CntInt设置校准、采集温度,读取飞行时间
  189. if ((RTC_CntInt & RTC_CNTMSK_CAL) == 0x0u)
  190. {
  191. // 间隔8秒进行一次校准
  192. tdc_start_cal(TDC_CFG_DO_CKENA | TDC_CFG_DO_CKDIS | TDC_CFG_DO_WREG);
  193. if (tof_flag & TOF_FLAG_UNALGND_CHOP)
  194. {
  195. TdcIntStep = 0x01u;
  196. }
  197. else
  198. {
  199. TdcIntStep = 0x00u;
  200. }
  201. }
  202. else if ((RTC_CntInt & RTC_CNTMSK_TEMP) == 0x4u)
  203. {
  204. // 间隔4秒采集一次温度
  205. tdc_start_temp(TDC_CFG_DO_CKENA | TDC_CFG_DO_CKDIS | TDC_CFG_DO_WREG);
  206. TdcIntStep = 0x02u;
  207. }
  208. else
  209. {
  210. // 每次采集飞行时间
  211. tdc_start_tof(TDC_CFG_DO_CKENA | TDC_CFG_DO_CKDIS | TDC_CFG_DO_WREG);
  212. TdcIntStep = 0x03u;
  213. }
  214. }
  215. }