tdc_ms1030.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465
  1. #include "board.h"
  2. #include "tdc_tof.h"
  3. #define ANZ_FIRE 24u //fire发送脉冲数
  4. #define DIV_FIRE 3u //内部时钟产生脉冲的分频
  5. #define DIV_CLKHS 0u //高速时钟分频
  6. #define START_CLKHS 2u //高速启动后测量前晶振启动间隔时间
  7. #define NEG_START 0u //start通道边缘
  8. #define NEG_STOP 0u //stop通道边缘
  9. #define HITIN 9u //stop预期脉冲数
  10. #define SEL_TIMO_MB 0u //暂未确定数值
  11. #define SEL_TSTO2 3u //32khz //和MS1030不同
  12. #define SEL_TSTO1 1u //start tdc输出 ,暂时
  13. #define DFLT_WREG0 ((ANZ_FIRE<<25) | \
  14. ( DIV_FIRE<<19) | \
  15. ( DIV_CLKHS<<17) | \
  16. ( START_CLKHS<<14) | \
  17. ( NEG_START<<13) | \
  18. ( NEG_STOP<<12) | \
  19. ( HITIN<< 8) | \
  20. ( SEL_TSTO2<< 2) | \
  21. ( SEL_TSTO1<< 0))
  22. #define EN_INT_TO 1 //TIMOUT中断触发位
  23. #define EN_INT_HIT 0 //END HITS中断触发位
  24. #define EN_INT_ALU 1 //alu中断触发位
  25. #define RFEDGE 0 //stop通道边沿敏感性
  26. #define UP_DELVAL1 0 //当EN_FIST_WAVE=1时,为第一波屏蔽窗口 BIT12~27 暂未设置
  27. #define OFFSET 0 //当en_hc=1时, 62~-64mV 暂未设置
  28. #define DFLT_WREG1 (( EN_INT_TO<<31) | \
  29. ( EN_INT_HIT<<30) | \
  30. ( EN_INT_ALU<<29) | \
  31. ( RFEDGE<<28) | \
  32. ( OFFSET<< 0))
  33. #define EN_FIRST_WAVE 0u //BIT31, 为1时后面的定义有效
  34. #define EDGE_FW 0u //第一波边缘敏感性
  35. #define DELREL1 6u //第1个stop接收第几个回波周期
  36. #define DELREL2 8u //第2个stop接收第几个回波周期
  37. #define DELREL3 10u //第3个stop接收第几个回波周期
  38. #define DELREL4 12u //第4个stop接收第几个回波周期
  39. #define DELREL5 14u //第5个stop接收第几个回波周期
  40. #define DFLT_WREG2 ((EDGE_FW<<30) | \
  41. (DELREL1<<24) | \
  42. (DELREL2<<18) | \
  43. (DELREL3<<12) | \
  44. (DELREL4<< 6) | \
  45. (DELREL5<< 0))
  46. #define DELREL6 16u //第3个stop接收第几个回波周期
  47. #define DELREL7 18u //第4个stop接收第几个回波周期
  48. #define DELREL8 20u //第5个stop接收第几个回波周期
  49. //后面几位和MS1030一致
  50. #define DFLT_WREG3 ((DELREL6<<26) | \
  51. (DELREL7<<20) | \
  52. (DELREL8<<14))
  53. #define CONF_FIRE 0 //暂时设置为0 bit29~31
  54. #define PHASE_FIREUP 0
  55. #define PHASE_FIREDOWN 0
  56. #define SEL_START_FIRE 1
  57. #define EN_ANALOG 1
  58. #define HZ60 0
  59. #define TCYCLE 1
  60. #define ANZ_FAKE 0
  61. #define SEL_ECLK_TMP 1
  62. #define TW2 3
  63. #define EN_PEAK 1 //峰值检波使能 1030不同
  64. #define EN_DISCHARGE 1 //检波放电使能1030不同
  65. #define CYCLE_TOF 3 //顺流逆流自动检测模式下,顺流逆流测量间隔时间,初步确定为3=20ms 1030不同
  66. #define EN_ERR_VAL 1
  67. #define EN_DC 1 //stop端口充电模式 这里设置为直流 1030不同
  68. #define FIRE0_DEF 1
  69. #define DOUBLE_RES 0
  70. #define QUAD_RES 0
  71. #define DFLT_WREG4 (( PHASE_FIREUP<<28) | \
  72. ( PHASE_FIREDOWN<<27) | \
  73. ( SEL_START_FIRE<<26) | \
  74. ( EN_ANALOG<<25) | \
  75. ( HZ60<<24) | \
  76. ( TCYCLE<<23) | \
  77. ( ANZ_FAKE<<22) | \
  78. ( SEL_ECLK_TMP<<21) | \
  79. ( TW2<<17) | \
  80. ( EN_PEAK<<16) | \
  81. ( EN_DISCHARGE<<15) | \
  82. ( CYCLE_TOF<<11) | \
  83. ( EN_ERR_VAL<<10) | \
  84. ( EN_DC<<9) | \
  85. ( FIRE0_DEF<<8) | \
  86. ( DOUBLE_RES<<7) | \
  87. ( QUAD_RES<<6))
  88. #define CYCLE_AUTOTOF (250<<20) //自动测量循环时间 500ms
  89. #define ANZ_AUTOTOF (1<<16) //循环次数 一直开启
  90. #define AUTOTOF_MODE (0<<15) //顺逆顺逆
  91. #define PHASE_FIRENUM (3<<6) //插入相位位置
  92. #define ANZ_PHASE (8) //插入周期数
  93. #define DFLT_WREG5 (CYCLE_AUTOTOF|ANZ_AUTOTOF|AUTOTOF_MODE|PHASE_FIRENUM|ANZ_PHASE)
  94. #define DOWN_DELVAL1 (0<<12)//第一波屏蔽窗口
  95. #define SEL_SRC_CLK (0<<7)//使用晶振产生时钟
  96. #define EN_HC (1<<6)
  97. #define CURR32K (0<<5)
  98. #define DIS_Vref (1<<4)
  99. #define ADJ_LDO_ROUGH (0<<3)
  100. #define ADJ_LDO_FINE (4<<0)
  101. #define DFLT_WREG6 (DOWN_DELVAL1|SEL_SRC_CLK|EN_HC|CURR32K|DIS_Vref|ADJ_LDO_ROUGH|ADJ_LDO_FINE)
  102. uint16_t tof_state = TOF_ST_INIT;
  103. uint32_t tof_flag;
  104. //uint16_t CntSync = 0;
  105. void tdc_tof_init(void)
  106. {
  107. //MUX ADDA : PA08; ADDB : PC09
  108. mux_init();
  109. // MS1030 RSTN : PD02
  110. GpioInit(PD02_AF0, GPIO_DIG_OUT_WEAK_PUSH_NONEUP_NONEDOWN);
  111. GpioClrPins(GpioPortD, GpioBitMsk2); // reset active low
  112. us_delay(10); // 10us > tPH(30ns)
  113. GpioSetPins(GpioPortD, GpioBitMsk2); // reset release
  114. us_delay(10); // 10us > tRFS(30ns)
  115. tdc_spi_init(); // peripheral init
  116. PeriClk_MutEnable(PeriClk_Spi1);
  117. DMA_ReqClkOn();
  118. // TDC POR
  119. tdc_spi_wr_code(0x50);
  120. us_delay(1000); // 1000us > specification(500us)
  121. tdc_spi_wr_d32(0x80, DFLT_WREG0);
  122. uint32_t reg0=tdc_spi_rd_d32(0xa0);
  123. if(reg0==0)return;
  124. tof_flag = TOF_FLAG_UNALGND_CHOP;
  125. if (tdc_spi_rd_d8(0xd3)!=(DFLT_WREG0&0xFFu)){
  126. tof_flag |= TOF_FLAG_TDC_FAULT;
  127. } else {
  128. // write_reg0
  129. tdc_spi_wr_d32(0x80, DFLT_WREG0 |
  130. ( 2u<< 4) // SEL_TIMO_MB, 0:64us; 1:128us; 2:256us; ~ 6:4096us;
  131. );
  132. // write_reg1
  133. tdc_spi_wr_d32(0x81, DFLT_WREG1 |
  134. (5760u<< 7) // DELVAL1=45us, format:16.5, time unit:Tref;
  135. );
  136. // write_reg2
  137. tdc_spi_wr_d32(0x82, DFLT_WREG2 |
  138. ( 0u<<31) // EN_FIRST_WAVE, 0:disable; 1:enable;
  139. );
  140. // write_reg3
  141. tdc_spi_wr_d32(0x83, DFLT_WREG3 |
  142. ( 1u<<13) // measure FW pulse width, 0:on; 1:off
  143. );
  144. // write_reg4
  145. tdc_spi_wr_d32(0x84, DFLT_WREG4);
  146. tdc_spi_wr_d32(0x85, DFLT_WREG5);
  147. tdc_spi_wr_d32(0x86, DFLT_WREG6);
  148. tdc_spi_wr_code(0x70);
  149. tdc_spi_wr_code(0x06);
  150. // not 'INTN' but 'us_delay' to avoid dead loop when INTN fault
  151. us_delay(2000); // > 480 + 600 + 16 + 70
  152. tdc_read_cal(0x0u);
  153. // tof_flag ^= TOF_FLAG_UNALGND_CHOP;
  154. // // start a single ToF to align MS1030 internal calibration order(1 CAL every 24 ToF)
  155. // // must be sure that CAL not in the middle of UP Tof and DOWN Tof
  156. // tdc_start_tof(TDC_CFG_DO_WREG | TDC_CFG_FIRE_UP);
  157. //
  158. // // not 'INTN' but 'us_delay' to avoid dead loop when INTN fault
  159. // us_delay(2000); // > 480 + 600 + 16 + 70
  160. //
  161. // tdc_read_tof(TDC_CFG_FIRE_UP); // read data and clear interrupt
  162. }
  163. DMA_ReqClkOff();
  164. PeriClk_MutDisable(PeriClk_Spi1);
  165. // MS1030 INTN : PD03 falling edge trigger
  166. GpioInit(PD03_AF0, GPIO_DIG_IN_PULLUP_NONEDOWN);
  167. GpioEventInit(PD03_AF0, GPIO_EVENT_FALL);
  168. // enable interrupt at NVIC side
  169. IRQMutEnable(PORTD_F_IRQn, NVIC_PRIO_1);
  170. }
  171. void tdc_start_tof(uint32_t cfg)
  172. {
  173. //rt_enter_critical();
  174. uint32_t u32tmp;
  175. if (cfg & TDC_CFG_DO_CKENA){
  176. PeriClk_MutEnable(PeriClk_Spi1);
  177. DMA_ReqClkOn();
  178. }
  179. if (cfg & TDC_CFG_DO_WREG){
  180. // write_reg0
  181. tdc_spi_wr_d32(0x80, DFLT_WREG0 |
  182. ( 3u<< 4) // SEL_TIMO_MB, 0:64us; 1:128us; 2:256us; ~ 6:4096us;
  183. //modified by yuewei 20260526 1->3, 128us -> 512us, for DN300 almost 240us
  184. );
  185. // write_reg1
  186. // DN15: L/C > (42+21+10*2)*1000/1555=53us
  187. tdc_spi_wr_d32(0x81, DFLT_WREG1 |
  188. (5760u<< 12) // DELVAL1=45us, format:16.5, time unit:Tref;//1031 从BIT12开始
  189. // (6400u<< 7) // DELVAL1=50us, format:16.5, time unit:Tref;
  190. // (7040u<< 7) // DELVAL1=55us, format:16.5, time unit:Tref;
  191. // (7680u<< 7) // DELVAL1=60us, format:16.5, time unit:Tref;
  192. // (8230u<< 7) // DELVAL1=65us, format:16.5, time unit:Tref;
  193. // (8960u<< 7) // DELVAL1=70us, format:16.5, time unit:Tref;
  194. );
  195. // write_reg2
  196. tdc_spi_wr_d32(0x82, DFLT_WREG2 |
  197. ( 1u<<31) // EN_FIRST_WAVE, 0:disable; 1:enable;
  198. );
  199. // write_reg3
  200. u32tmp = DFLT_WREG3 |
  201. ( 0u<<13) | // measure FW pulse width, 0:on; 1:off
  202. (TdcFwOfst<<6); // FW wave_offs, 0:0mv; 1~63:2~126mV; 64~127:-128~-2mV;
  203. if (tof_state&TOF_ST_VOID){
  204. u32tmp |= (1u<<13); // disable FW pulse width to save power
  205. }
  206. tdc_spi_wr_d32(0x83, u32tmp);
  207. }
  208. // write_reg4
  209. u32tmp = DFLT_WREG4;
  210. if (cfg & TDC_CFG_FIRE_UP){
  211. u32tmp |= (1u<<30); // FIRE_UP, 0:off; 1:on;
  212. } else {
  213. u32tmp |= (1u<<29); // FIRE_DOWN, 0:off; 1:on;
  214. }
  215. tdc_spi_wr_d32(0x84, u32tmp);
  216. // Initial TDC status regs
  217. tdc_spi_wr_code(0x70);
  218. // start single-direction measure
  219. tdc_spi_wr_code(0x01);
  220. if (cfg & TDC_CFG_DO_CKDIS){
  221. DMA_ReqClkOff();
  222. PeriClk_MutDisable(PeriClk_Spi1);
  223. }
  224. //rt_exit_critical();
  225. }
  226. uint16_t TdcStatus;
  227. uint16_t TdcUPwFw;
  228. uint16_t TdcUPwHw;
  229. uint32_t TdcUToF[9];
  230. uint16_t TdcDPwFw;
  231. uint16_t TdcDPwHw;
  232. uint32_t TdcDToF[9];
  233. uint32_t TdcCal;
  234. //float TdcScale = 250.0f/65536;
  235. float TdcScale = 0.00381147861f;
  236. uint32_t TdcPT[4];
  237. float TdcResist = 5000; // OhmX10
  238. //modified by yuewei 20260520
  239. //float WaterPrmt[2] = {25.0f, 1496.6f};
  240. float WaterPrmt[2] = {25.0f, 1497.1484f};
  241. void tdc_read_tof(uint32_t cfg)
  242. {
  243. // uint16_t i;
  244. if (cfg & TDC_CFG_DO_CKENA){
  245. PeriClk_MutEnable(PeriClk_Spi1);
  246. DMA_ReqClkOn();
  247. }
  248. TdcStatus = tdc_spi_rd_d16(0xd2); // status
  249. if ((TdcStatus&0x0600)==0x0000u){
  250. tof_flag ^= TOF_FLAG_UNALGND_CHOP;
  251. // if (CntSync>=240){
  252. // CntSync = 10;
  253. // } else {
  254. // CntSync += 10;
  255. // }
  256. }
  257. if ((TdcStatus&0x06F0)!=0x0090u){
  258. tof_flag |= TOF_FLAG_BLANK_PIPE;
  259. tdc_spi_wr_code(0x70);
  260. } else {
  261. if (cfg & TDC_CFG_FIRE_UP){
  262. TdcUPwFw = tdc_spi_rd_d16(0xd0); // First wave pulse width
  263. TdcUPwHw = tdc_spi_rd_d16(0xd1); // 1st Hit wave pulse width
  264. tdc_spi_wr_code(0x70);
  265. // TOF_UP_HITs
  266. TdcUToF[0] = tdc_spi_rd_d32(0xb8)*(1.0f/8); // average of all
  267. // for(i=0; i<8; i++){
  268. // TdcUToF[i+1] = tdc_spi_rd_d32(0xb0 + i);
  269. // };
  270. } else if (cfg & TDC_CFG_FIRE_DOWN){
  271. TdcDPwFw = tdc_spi_rd_d16(0xd0); // First wave pulse width
  272. TdcDPwHw = tdc_spi_rd_d16(0xd1); // 1st Hit wave pulse width
  273. tdc_spi_wr_code(0x70);
  274. // TOF_DOWN_HITs
  275. TdcDToF[0] = tdc_spi_rd_d32(0xb8)*(1.0f/8); // average of all
  276. // for(i=0; i<8; i++){
  277. // TdcDToF[i+1] = tdc_spi_rd_d32(0xb0 + i);
  278. // };
  279. }
  280. }
  281. if (cfg & TDC_CFG_DO_CKDIS){
  282. DMA_ReqClkOff();
  283. PeriClk_MutDisable(PeriClk_Spi1);
  284. }
  285. }
  286. void tdc_start_cal(uint32_t cfg)
  287. {
  288. //rt_enter_critical();
  289. if (cfg & TDC_CFG_DO_CKENA){
  290. PeriClk_MutEnable(PeriClk_Spi1);
  291. DMA_ReqClkOn();
  292. }
  293. // 8*T_32k = 244.140625us
  294. if (cfg & TDC_CFG_DO_WREG){
  295. // write_reg0
  296. tdc_spi_wr_d32(0x80, DFLT_WREG0 |
  297. ( 2u<< 4) // SEL_TIMO_MB, 0:64us; 1:128us; 2:256us; ~ 6:4096us;
  298. );
  299. // write_reg3
  300. tdc_spi_wr_d32(0x83, DFLT_WREG3 |
  301. ( 1u<<13) // measure FW pulse width, 0:on; 1:off
  302. );
  303. }
  304. tdc_spi_wr_code(0x70);
  305. tdc_spi_wr_code(0x06);
  306. if (cfg & TDC_CFG_DO_CKDIS){
  307. DMA_ReqClkOff();
  308. PeriClk_MutDisable(PeriClk_Spi1);
  309. }
  310. //rt_exit_critical();
  311. }
  312. void tdc_read_cal(uint32_t cfg)
  313. {
  314. //rt_enter_critical();
  315. if (cfg & TDC_CFG_DO_CKENA){
  316. PeriClk_MutEnable(PeriClk_Spi1);
  317. DMA_ReqClkOn();
  318. }
  319. TdcStatus = tdc_spi_rd_d16(0xd2); // status
  320. if ((TdcStatus&0x0600)==0x0000u){
  321. tof_flag ^= TOF_FLAG_UNALGND_CHOP;
  322. // if (CntSync>=240){
  323. // CntSync = 10;
  324. // } else {
  325. // CntSync += 10;
  326. // }
  327. tdc_spi_wr_code(0x70);
  328. TdcCal = tdc_spi_rd_d32(0xd4);
  329. // TdcScale = 244140.625f/TdcCal;
  330. TdcScale += (244140.625f/TdcCal - TdcScale)*(1.0f/2);
  331. //LOG("----------TdcScale=%.6f\n",TdcScale);
  332. } else {
  333. tdc_spi_wr_code(0x70);
  334. }
  335. if (cfg & TDC_CFG_DO_CKDIS){
  336. DMA_ReqClkOff();
  337. PeriClk_MutDisable(PeriClk_Spi1);
  338. }
  339. //rt_exit_critical();
  340. }
  341. void tdc_start_temp(uint32_t cfg)
  342. {
  343. //rt_enter_critical();
  344. if (cfg & TDC_CFG_DO_CKENA){
  345. PeriClk_MutEnable(PeriClk_Spi1);
  346. DMA_ReqClkOn();
  347. }
  348. if (cfg & TDC_CFG_DO_WREG){
  349. // write_reg0
  350. tdc_spi_wr_d32(0x80, DFLT_WREG0 |
  351. ( 3u<< 4) // SEL_TIMO_MB, 0:64us; 1:128us; 2:256us; 3:512us; ~ 6:4096us;
  352. );
  353. // write_reg1
  354. tdc_spi_wr_d32(0x81, DFLT_WREG1 |
  355. ( 0u<< 12) // DELVAL1=0us, format:16.5, time unit:Tref;
  356. );
  357. // write_reg3
  358. tdc_spi_wr_d32(0x83, DFLT_WREG3 |
  359. ( 1u<<13) // measure FW pulse width, 0:on; 1:off
  360. );
  361. }
  362. tdc_spi_wr_code(0x70);
  363. tdc_spi_wr_code(0x04);
  364. if (cfg & TDC_CFG_DO_CKDIS){
  365. DMA_ReqClkOff();
  366. PeriClk_MutDisable(PeriClk_Spi1);
  367. }
  368. //rt_exit_critical();
  369. }
  370. void tdc_read_temp(uint32_t cfg)
  371. {
  372. //rt_enter_critical();
  373. if (cfg & TDC_CFG_DO_CKENA){
  374. PeriClk_MutEnable(PeriClk_Spi1);
  375. DMA_ReqClkOn();
  376. }
  377. TdcStatus = tdc_spi_rd_d16(0xd2); // status
  378. tdc_spi_wr_code(0x70);
  379. TdcPT[0] = tdc_spi_rd_d32(0xc2); // REF 5K +/- 5
  380. TdcPT[1] = tdc_spi_rd_d32(0xc3); // U7
  381. //TdcPT[2] = tdc_spi_rd_d32(0xc4); // U8
  382. //TdcPT[3] = tdc_spi_rd_d32(0xc5); // REF 1.5K
  383. // if (TdcPT[0]>0x1000000u && TdcPT[0]<0x2000000u){
  384. // TdcResist = 5000.0f*TdcPT[1]/TdcPT[0];
  385. // Ohm2Dgr2USSpd(TdcResist, WaterPrmt); // [0]:Temperature; [1]:ultrasonic speed @Temp
  386. // }
  387. if (TdcPT[0]>0xB00000u && TdcPT[0]<0xE00000u){
  388. TdcResist = 2500.0f*TdcPT[1]/TdcPT[0]; // ohmX10
  389. Ohm2Dgr2USSpd(TdcResist, WaterPrmt); // [0]:Temperature; [1]:ultrasonic speed @Temp
  390. }
  391. //LOG("----------T=%.6f,C=%.6f\n",WaterPrmt[0],WaterPrmt[1]);
  392. if (cfg & TDC_CFG_DO_CKDIS){
  393. DMA_ReqClkOff();
  394. PeriClk_MutDisable(PeriClk_Spi1);
  395. }
  396. //rt_exit_critical();
  397. }