rtc_isr.c 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  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. {
  74. rr->flag_1s = 1;
  75. rr->second = BcdToOct(M0P_RTC->SEC);
  76. }
  77. if (rr->minute != BcdToOct(M0P_RTC->MIN))
  78. {
  79. rr->flag_1m = 1;
  80. rr->minute = BcdToOct(M0P_RTC->MIN);
  81. }
  82. rr->hour = BcdToOct(M0P_RTC->HOUR);
  83. rr->day = BcdToOct(M0P_RTC->DAY);
  84. rr->month = BcdToOct(M0P_RTC->MON);
  85. rr->year = BcdToOct(M0P_RTC->YEAR);
  86. rr->week = BcdToOct(M0P_RTC->WEEK);
  87. }
  88. void set_rtc_date(uint8_t year, uint8_t month, uint8_t day)
  89. {
  90. M0P_RTC->YEAR = year;
  91. M0P_RTC->MON = month;
  92. M0P_RTC->DAY = day;
  93. }
  94. void get_rtc_date(uint8_t *year, uint8_t *month, uint8_t *day)
  95. {
  96. *year = M0P_RTC->YEAR;
  97. *month = M0P_RTC->MON;
  98. *day = M0P_RTC->DAY;
  99. }
  100. void set_rtc_time(uint8_t hour, uint8_t min, uint8_t sec)
  101. {
  102. M0P_RTC->HOUR = hour;
  103. M0P_RTC->MIN = min;
  104. M0P_RTC->SEC = sec;
  105. }
  106. void get_rtc_time(uint8_t *hour, uint8_t *min, uint8_t *sec)
  107. {
  108. *hour = M0P_RTC->HOUR;
  109. *min = M0P_RTC->MIN;
  110. *sec = M0P_RTC->SEC;
  111. }
  112. uint32_t RTC_CntInt;
  113. uint32_t get_rtc_cnt_int(void)
  114. {
  115. return RTC_CntInt;
  116. }
  117. void set_rtc_cnt_int(uint32_t cnt_int)
  118. {
  119. RTC_CntInt = cnt_int;
  120. }
  121. static uint32_t TdcRwErrCnt = 0;
  122. uint32_t get_tdc_rw_err_cnt(void)
  123. {
  124. return TdcRwErrCnt;
  125. }
  126. uint32_t GetChIdx(uint32_t cnt)
  127. {
  128. if (pTdcItf->ch_num == 1)
  129. {
  130. return 0;
  131. }
  132. else if (pTdcItf->ch_num == 2)
  133. {
  134. return (cnt & 0x00000001);
  135. }
  136. else if (pTdcItf->ch_num == 4)
  137. {
  138. return (cnt & 0x00000003);
  139. }
  140. return 0;
  141. }
  142. static uint32_t MUX_SwitchInt = 0;
  143. void RTC_IRQHandler(void)
  144. {
  145. uint32_t ISR;
  146. ISR = M0P_RTC->CR1;
  147. M0P_RTC->CR1 = ISR & (~0x18u);
  148. // if(NB_RUN_UPDATE_FLAG == 1)return; //2026-4-8 wuxiaolin
  149. // add by yuewei 20260309 to deal hongwai long data
  150. if (HONGWAI_LONG_RX_FLAG == 1)
  151. return;
  152. extern uint8_t finsh_txing_flag;
  153. if (finsh_txing_flag == 1)
  154. return;
  155. // LOG("---------------------------------0\n");
  156. // extern uint8_t finsh_txing_flag; //modify by HBR 20260914 ,防止在红外通信时卡死ms1031
  157. // if(finsh_txing_flag==1) return;
  158. // return;
  159. // us_delay(2000);//!!!!!do not modify!!!!!
  160. // rt_thread_delay(5);//!!!!!do not modify!!!!!
  161. // get_internal_time();
  162. if (ISR & 0x08u)
  163. {
  164. rt_sem_release(&rtc_isr_sem);
  165. }
  166. }
  167. void rtc_interrupt_deal_tdc(void)
  168. {
  169. uint32_t Tu32;
  170. update_rtc_run();
  171. if (tof_state & (TOF_ST_METER | TOF_ST_CALIB | TOF_ST_VOID))
  172. {
  173. if (pTdcItf->mux_switch && ((RTC_CntInt & 0x00000001u) == 0) && pTdcItf->ch_num > 1)
  174. {
  175. uint32_t idx = GetChIdx(MUX_SwitchInt);
  176. set_mux_ch(pTdcItf->mux_ch_no[idx]);
  177. MUX_SwitchInt++;
  178. us_delay(50);
  179. }
  180. // LOG("---------------------------------1\n");
  181. RTC_CntInt++;
  182. }
  183. if (pTdcItf->blank_flag == pTdcItf->ch_bit_map)
  184. {
  185. if (tof_state & TOF_ST_METER)
  186. {
  187. tof_state = TOF_ST_VOID;
  188. }
  189. }
  190. else
  191. {
  192. if (tof_state & TOF_ST_VOID)
  193. {
  194. tof_state = TOF_ST_METER;
  195. }
  196. }
  197. if ((tof_state & (TOF_ST_METER | TOF_ST_CALIB)) || (tof_state & TOF_ST_VOID))
  198. {
  199. tof_flag &= ~TOF_FLAG_BLANK_PIPE;
  200. if (TdcIntStep != 0xFFu)
  201. {
  202. tof_flag |= TOF_FLAG_TDC_FAULT;
  203. }
  204. // 空管状态会关闭MS1031的高频时钟,先打开MS1031的高频时钟才能进行后续操作
  205. if (alarm_status(ERR_BLANK_PIPE))
  206. {
  207. tdc_turn_on_off_high_clk(1);
  208. }
  209. // 根据RTC_CntInt设置校准、采集温度,读取飞行时间
  210. if ((RTC_CntInt & RTC_CNTMSK_CAL) == 0x0u)
  211. {
  212. // 间隔8秒进行一次校准
  213. tdc_start_cal(TDC_CFG_DO_CKENA | TDC_CFG_DO_CKDIS | TDC_CFG_DO_WREG);
  214. if (tof_flag & TOF_FLAG_UNALGND_CHOP)
  215. {
  216. TdcIntStep = 0x01u;
  217. }
  218. else
  219. {
  220. TdcIntStep = 0x00u;
  221. }
  222. }
  223. else if ((RTC_CntInt & RTC_CNTMSK_TEMP) == 0x4u)
  224. {
  225. // 间隔4秒采集一次温度
  226. tdc_start_temp(TDC_CFG_DO_CKENA | TDC_CFG_DO_CKDIS | TDC_CFG_DO_WREG);
  227. TdcIntStep = 0x02u;
  228. }
  229. else
  230. {
  231. // 每次采集飞行时间
  232. tdc_start_tof(TDC_CFG_DO_CKENA | TDC_CFG_DO_CKDIS | TDC_CFG_DO_WREG);
  233. TdcIntStep = 0x03u;
  234. }
  235. }
  236. }