iic_decoder.cc 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531
  1. // // ******************************************************************
  2. // // /\ /| @File iic_decoder.cc
  3. // // \ V/ @Brief
  4. // // | "") @Author lijinwen, ghz005@uni-trend.com.cn
  5. // // / | @Creation 2024-07-19
  6. // // / \\ @Modified 2024-07-25
  7. // // *(__\_\
  8. // // ******************************************************************
  9. #include "iic_decoder.h"
  10. #include "constants.h"
  11. namespace Protocol
  12. {
  13. bool IicDecoder::DecodeIic(const IicDecodeOptions& option, const EdgePulseDataTwoLevels& edge_pulses_clk,
  14. const EdgePulseDataTwoLevels& edge_pulses_data, IicDecodeResult& result)
  15. {
  16. result = {};
  17. result.decoder_ptr = reinterpret_cast<intptr_t>(this);
  18. is_cancel_ptr_ = option.is_cancel;
  19. wave_data_len_ = static_cast<int32_t>(
  20. std::min(edge_pulses_clk.waveform_data_count, edge_pulses_data.waveform_data_count));
  21. bit_width_ = option.data_bit_width;
  22. const int32_t addr_len = bit_width_ == IicEnums::DataBitWidth::DATA_BIT_WIDTH_7_BIT ? 7 : 10;
  23. int32_t start_index = 0;
  24. packet_infos_.clear();
  25. packet_info_datas_.clear();
  26. TwoLevelEdgePulse* edge_pulses_data_ptr = edge_pulses_data.GetDataAddrPtr();
  27. TwoLevelEdgePulse* edge_pulses_clk_ptr = edge_pulses_clk.GetDataAddrPtr();
  28. /*auto t1 = offsetof(IicDataInfo, data);
  29. auto t2 = offsetof(IicDataInfo, ack);
  30. auto t3 = offsetof(IicDataInfo, ack_index);
  31. auto t4 = offsetof(IicDataInfo, ack_length);
  32. auto t5 = offsetof(IicDataInfo, success_ack);
  33. auto t6 = offsetof(IicDataInfo, has_ack);*/
  34. while (true)
  35. {
  36. // 检查是否取消
  37. if (is_cancel_ptr_ != nullptr && *is_cancel_ptr_)
  38. {
  39. WriteLog(LogLevel::Level2, "AsyncFunction canceled");
  40. return false;
  41. }
  42. while (start_index > 0 && edge_pulses_clk_ptr->start_index > start_index)
  43. {
  44. edge_pulses_clk_ptr--;
  45. }
  46. // find start index
  47. if (!FindStartNode(start_index, edge_pulses_data_ptr, edge_pulses_clk_ptr))
  48. {
  49. break;
  50. }
  51. //start_index = edge_pulses_data_ptr->start_index;
  52. int32_t data_len = wave_data_len_;
  53. IicEvent info = {};
  54. info.has_start = true;
  55. info.start_index = start_index;
  56. info.start_len = 1;
  57. //start_index = edge_pulses_clk_ptr++->start_index;
  58. if (!CommonHelper::FindNextNode(start_index, edge_pulses_clk_ptr) || edge_pulses_clk_ptr->start_index <= 0)
  59. {
  60. start_index = data_len;
  61. packet_infos_.push_back(info);
  62. break;
  63. }
  64. start_index = edge_pulses_clk_ptr->start_index;
  65. //if (start_index <= 0) break;
  66. //start_index = edge_pulses_clk_ptr++->start_index;
  67. if (!CommonHelper::FindNextNode(start_index, edge_pulses_clk_ptr) || edge_pulses_clk_ptr->start_index <= 0)
  68. {
  69. start_index = data_len;
  70. packet_infos_.push_back(info);
  71. break;
  72. }
  73. start_index = edge_pulses_clk_ptr->start_index;
  74. //if (start_index <= 0) break;
  75. info.addr_index = start_index;
  76. for (int index = 0; index < addr_len; ++index)
  77. {
  78. if (start_index >= data_len)
  79. {
  80. start_index = data_len;
  81. break;
  82. }
  83. if (!CommonHelper::GetNodeByIndex(start_index, edge_pulses_data_ptr))
  84. {
  85. start_index = data_len;
  86. break;
  87. }
  88. const bool bit = edge_pulses_data_ptr->current_level == TwoLevelEdgePulseStatusType::High;
  89. info.addr_data = static_cast<uint16_t>(info.addr_data << 1 | (bit ? 1 : 0));
  90. if (!CommonHelper::FindNextNode(start_index, edge_pulses_clk_ptr) || edge_pulses_clk_ptr->start_index <= 0)
  91. {
  92. start_index = data_len;
  93. break;
  94. }
  95. start_index = edge_pulses_clk_ptr->start_index;
  96. if (!CommonHelper::FindNextNode(start_index, edge_pulses_clk_ptr) || edge_pulses_clk_ptr->start_index <= 0)
  97. {
  98. start_index = data_len;
  99. break;
  100. }
  101. start_index = edge_pulses_clk_ptr->start_index;
  102. }
  103. info.addr_len = start_index - info.addr_index;
  104. // 解析RW标识位
  105. info.rw_index = start_index;
  106. if (!CommonHelper::GetNodeByIndex(start_index, edge_pulses_data_ptr))
  107. {
  108. start_index = data_len;
  109. packet_infos_.push_back(info);
  110. break;
  111. }
  112. info.rw = edge_pulses_data_ptr->current_level == TwoLevelEdgePulseStatusType::High ? 1 : 0;//get level
  113. start_index = edge_pulses_clk_ptr->start_index;
  114. if (start_index <= 0 || (is_cancel_ptr_ != nullptr && *is_cancel_ptr_))
  115. {
  116. start_index = data_len;
  117. packet_infos_.push_back(info);
  118. break;
  119. }
  120. if (!CommonHelper::FindNextNode(start_index, edge_pulses_clk_ptr) || edge_pulses_clk_ptr->start_index <= 0)
  121. {
  122. start_index = data_len;
  123. packet_infos_.push_back(info);
  124. break;
  125. }
  126. start_index = edge_pulses_clk_ptr->start_index;
  127. if (!CommonHelper::FindNextNode(start_index, edge_pulses_clk_ptr) || edge_pulses_clk_ptr->start_index <= 0)
  128. {
  129. start_index = data_len;
  130. packet_infos_.push_back(info);
  131. break;
  132. }
  133. start_index = edge_pulses_clk_ptr->start_index;
  134. info.rw_len = start_index - info.rw_index;
  135. //解析Addr后的ACK信号
  136. info.addr_ack_index = start_index;
  137. info.success_addr_ack = false;
  138. if (start_index >= data_len)
  139. {
  140. packet_infos_.push_back(info);
  141. break;
  142. }
  143. if (!CommonHelper::GetNodeByIndex(start_index, edge_pulses_data_ptr))
  144. {
  145. start_index = data_len;
  146. packet_infos_.push_back(info);
  147. break;
  148. }
  149. info.addr_ack = edge_pulses_data_ptr->current_level == TwoLevelEdgePulseStatusType::High; //get level
  150. if (!CommonHelper::FindNextNode(start_index, edge_pulses_clk_ptr) || edge_pulses_clk_ptr->start_index <= 0)
  151. {
  152. start_index = data_len;
  153. packet_infos_.push_back(info);
  154. break;
  155. }
  156. start_index = edge_pulses_clk_ptr->start_index;
  157. info.addr_ack_len = start_index - info.addr_ack_index;
  158. if (!CommonHelper::FindNextNode(start_index, edge_pulses_clk_ptr) || edge_pulses_clk_ptr->start_index <= 0)
  159. {
  160. start_index = data_len;
  161. packet_infos_.push_back(info);
  162. break;
  163. }
  164. start_index = edge_pulses_clk_ptr->start_index;
  165. if (start_index <= 0 || (is_cancel_ptr_ != nullptr && *is_cancel_ptr_))
  166. {
  167. start_index = data_len;
  168. packet_infos_.push_back(info);
  169. break;
  170. }
  171. std::vector<IicDataInfo> temp_infos;
  172. //开始解析数据
  173. while (true)
  174. {
  175. int32_t stop_index = 0;
  176. if (info.end_index > 0)
  177. {
  178. stop_index = info.end_index;
  179. }
  180. else if (FindStopNode(start_index, edge_pulses_data_ptr, edge_pulses_clk_ptr, stop_index))
  181. {
  182. //stop_index = edge_pulses_data_ptr->start_index;
  183. if (stop_index > 0)
  184. {
  185. info.has_end = true;
  186. info.end_index = stop_index;
  187. info.end_len = 1;
  188. if (start_index >= stop_index)
  189. {
  190. start_index = stop_index + 1;
  191. break;
  192. }
  193. }
  194. //break;
  195. }
  196. //下一帧 查找下一段启动信号
  197. if (start_index > edge_pulses_clk_ptr->start_index)
  198. {
  199. start_index = edge_pulses_clk_ptr->start_index;
  200. }
  201. int32_t next_start_index = start_index;
  202. if (FindStartNode(next_start_index, edge_pulses_data_ptr, edge_pulses_clk_ptr) || (is_cancel_ptr_ != nullptr && *
  203. is_cancel_ptr_))
  204. {
  205. }
  206. else
  207. {
  208. next_start_index = -1;
  209. }
  210. if (start_index >= next_start_index && next_start_index != -1)
  211. {
  212. start_index = next_start_index - 1;
  213. break;
  214. }
  215. IicDataInfo data_info = {};
  216. data_info.index = start_index;
  217. //解析数据
  218. for (int32_t index = 0; index < 8; index++)
  219. {
  220. if (start_index >= data_len)
  221. {
  222. start_index = data_len;
  223. break;
  224. }
  225. if (start_index >= stop_index && stop_index > 0)
  226. {
  227. start_index = stop_index + 1;
  228. break;
  229. }
  230. if (start_index >= next_start_index && next_start_index > 0)
  231. {
  232. start_index = next_start_index - 1;
  233. break;
  234. }
  235. data_info.data <<= 1;
  236. if (!CommonHelper::GetNodeByIndex(start_index, edge_pulses_data_ptr))
  237. {
  238. start_index = data_len;
  239. break;
  240. }
  241. bool bit = edge_pulses_data_ptr->current_level == TwoLevelEdgePulseStatusType::High;
  242. data_info.data |= static_cast<uint8_t>(bit ? 1 : 0);
  243. if (!CommonHelper::FindNextNode(start_index, edge_pulses_clk_ptr) || edge_pulses_clk_ptr->start_index <= 0)
  244. {
  245. start_index = data_len;
  246. break;
  247. }
  248. start_index = edge_pulses_clk_ptr->start_index;
  249. if (start_index <= 0 || (is_cancel_ptr_ != nullptr && *is_cancel_ptr_))
  250. {
  251. start_index = data_len;
  252. break;
  253. }
  254. if (!CommonHelper::FindNextNode(start_index, edge_pulses_clk_ptr) || edge_pulses_clk_ptr->start_index <= 0)
  255. {
  256. start_index = data_len;
  257. break;
  258. }
  259. start_index = edge_pulses_clk_ptr->start_index;
  260. if (start_index <= 0 || (is_cancel_ptr_ != nullptr && *is_cancel_ptr_))
  261. {
  262. start_index = data_len;
  263. break;
  264. }
  265. }
  266. if (start_index >= data_len) break;
  267. if (start_index >= stop_index && stop_index > 0)
  268. {
  269. start_index = stop_index + 1;
  270. break;
  271. }
  272. if (start_index >= next_start_index && next_start_index != -1)
  273. {
  274. start_index = next_start_index - 1;
  275. break;
  276. }
  277. //计算长度
  278. //data_info.length = stop_index - start_index;
  279. data_info.length = start_index - data_info.index;
  280. //解析数据包后的ACK信号
  281. data_info.ack_index = start_index;
  282. if (!CommonHelper::GetNodeByIndex(start_index, edge_pulses_data_ptr))
  283. {
  284. start_index = data_len;
  285. break;
  286. }
  287. data_info.ack = edge_pulses_data_ptr->current_level == TwoLevelEdgePulseStatusType::High ? 1 : 0;
  288. if (!CommonHelper::FindNextNode(start_index, edge_pulses_clk_ptr) || edge_pulses_clk_ptr->start_index <= 0)
  289. {
  290. start_index = data_len;
  291. break;
  292. }
  293. start_index = edge_pulses_clk_ptr->start_index;
  294. if (start_index <= 0 /*|| token.IsCancellationRequested || needclear*/)
  295. {
  296. start_index = data_len;
  297. break;
  298. }
  299. data_info.ack_length = start_index - data_info.ack_index;
  300. data_info.success_ack = 0;
  301. if (start_index >= stop_index && stop_index > 0)
  302. {
  303. start_index = stop_index + 1;
  304. break;
  305. }
  306. if (start_index >= next_start_index && next_start_index != -1)
  307. {
  308. start_index = next_start_index - 1;
  309. break;
  310. }
  311. temp_infos.push_back(data_info);
  312. if (!CommonHelper::FindNextNode(start_index, edge_pulses_clk_ptr) || edge_pulses_clk_ptr->start_index <= 0)
  313. {
  314. start_index = data_len;
  315. break;
  316. }
  317. start_index = edge_pulses_clk_ptr->start_index;
  318. if (start_index <= 0 || (is_cancel_ptr_ != nullptr && *is_cancel_ptr_))
  319. {
  320. start_index = data_len;
  321. break;
  322. }
  323. }
  324. //info.data_infos = temp_infos;
  325. //最后一个数据包的ACK信号为NACK
  326. if (!temp_infos.empty())
  327. {
  328. info.data_infos_index = static_cast<int32_t>(packet_info_datas_.size() + 1);
  329. //int32_t old_data_len = static_cast<int32_t>(packet_info_datas_.size());
  330. info.data_infos_count = static_cast<int32_t>(temp_infos.size());
  331. // 使用std::move将temp_infos的内容移动到packet_info_datas_的末尾
  332. packet_info_datas_.insert(packet_info_datas_.end(),
  333. std::make_move_iterator(temp_infos.begin()),
  334. std::make_move_iterator(temp_infos.end()));
  335. //info.data_infos_ptr = reinterpret_cast<intptr_t> (packet_info_datas_.data() + old_data_len - 1);
  336. info.has_end = true;
  337. //info.end_index = start_index;
  338. info.end_len = 1;
  339. //info.success_addr_ack = true;
  340. }
  341. packet_infos_.push_back(info);
  342. }
  343. if (!packet_infos_.empty())
  344. {
  345. result.decode_event_need_update = true;
  346. }
  347. result.decode_event_count = packet_infos_.size();
  348. result.decode_events_ptr = packet_infos_.data();
  349. result.decode_data_cell_ptr = packet_info_datas_.data();
  350. return true;
  351. }
  352. bool IicDecoder::FindStopNode(int32_t start_index, TwoLevelEdgePulse* node_sda,
  353. TwoLevelEdgePulse* node_scl, int32_t& stop_index)
  354. {
  355. if (start_index < 0)
  356. {
  357. return false;
  358. }
  359. TwoLevelEdgePulse* node_sda_tmp = node_sda;
  360. TwoLevelEdgePulse* node_scl_tmp = node_scl;
  361. const auto start_time = std::chrono::steady_clock::now();
  362. while (CommonHelper::CheckTwoLevelEdgePulseValid(node_sda_tmp))
  363. {
  364. // 找到SDA上升沿
  365. // 寻找SCL高
  366. /*if (node_sda_tmp->start_index > start_index || node_sda_tmp->current_level != TwoLevelEdgePulseStatusType::High)
  367. {
  368. node_sda_tmp++;
  369. continue;
  370. }*/
  371. while (node_sda_tmp->start_index < start_index || node_sda_tmp->current_level != TwoLevelEdgePulseStatusType::High)
  372. {
  373. node_sda_tmp++;
  374. if (!CommonHelper::CheckTwoLevelEdgePulseValid(node_sda_tmp))
  375. {
  376. return false;
  377. }
  378. }
  379. if (!CommonHelper::FindNextNode(node_sda_tmp->start_index, node_scl_tmp))
  380. {
  381. return false;
  382. }
  383. while (node_sda_tmp->start_index > node_scl_tmp->start_index)
  384. {
  385. node_scl_tmp++;
  386. if (!CommonHelper::CheckTwoLevelEdgePulseValid(node_scl))
  387. {
  388. return false;
  389. }
  390. }
  391. //sda高
  392. // 确认下一个SCL为低电平
  393. if (node_scl_tmp->current_level == TwoLevelEdgePulseStatusType::Low)
  394. {
  395. if (node_sda_tmp->start_index < node_scl_tmp->start_index)
  396. {
  397. // 找到目标停止条件
  398. stop_index = node_sda_tmp->start_index;
  399. return true;
  400. }
  401. }
  402. node_scl_tmp++;
  403. start_index = node_scl_tmp->end_index;
  404. //start_index = node_scl_tmp->end_index + 1;
  405. /* auto end_time = std::chrono::steady_clock::now();
  406. auto tmp = std::chrono::duration_cast<std::chrono::seconds>(
  407. end_time - start_time).count();*/
  408. if (auto end_time = std::chrono::steady_clock::now(); std::chrono::duration_cast<std::chrono::seconds>(
  409. end_time - start_time).count() >
  410. DECODE_OUT_TIME_BY_SEC)
  411. {
  412. WriteLog(LogLevel::Level2, "IIC FindStopNode TimeOut");
  413. return false;
  414. }
  415. }
  416. return CommonHelper::CheckTwoLevelEdgePulseValid(node_sda_tmp);
  417. }
  418. bool IicDecoder::FindStartNode(int32_t& start_index, TwoLevelEdgePulse* node_sda,
  419. TwoLevelEdgePulse* node_scl)
  420. {
  421. if (start_index < 0)
  422. {
  423. return false;
  424. }
  425. const auto start_time = std::chrono::steady_clock::now();
  426. while (CommonHelper::CheckTwoLevelEdgePulseValid(node_sda))
  427. {
  428. // 找到SDA下降沿
  429. // 寻找SCL高
  430. /* if (node_sda->start_index < start_index)
  431. {
  432. node_sda += 1;
  433. }
  434. if (!CommonHelper::CheckTwoLevelEdgePulseValid(node_sda))
  435. {
  436. return false;
  437. }
  438. if (node_sda->current_level != TwoLevelEdgePulseStatusType::Low)
  439. {
  440. node_sda += 1;
  441. }*/
  442. while (node_sda->start_index < start_index || node_sda->current_level != TwoLevelEdgePulseStatusType::Low)
  443. {
  444. node_sda++;
  445. if (!CommonHelper::CheckTwoLevelEdgePulseValid(node_sda))
  446. {
  447. return false;
  448. }
  449. }
  450. while (node_scl->start_index < start_index)
  451. {
  452. node_scl++;
  453. if (!CommonHelper::CheckTwoLevelEdgePulseValid(node_scl))
  454. {
  455. return false;
  456. }
  457. }
  458. //sda 低
  459. if (node_sda->start_index > node_scl->start_index)
  460. {
  461. node_scl += 1;
  462. }
  463. if (!CommonHelper::CheckTwoLevelEdgePulseValid(node_scl))
  464. {
  465. return false;
  466. }
  467. //找到SCL下降沿
  468. if (node_scl->current_level == TwoLevelEdgePulseStatusType::Low)
  469. {
  470. if (node_sda->start_index < node_scl->start_index)
  471. {
  472. //找到目标头
  473. start_index = node_sda->start_index;
  474. return true;
  475. }
  476. }
  477. if (node_sda->end_index < start_index)
  478. {
  479. node_sda++;
  480. }
  481. start_index = node_sda->end_index + 1;
  482. /*auto end_time = std::chrono::steady_clock::now();
  483. auto tmp = std::chrono::duration_cast<std::chrono::seconds>(
  484. end_time - start_time).count();*/
  485. if (auto end_time = std::chrono::steady_clock::now(); std::chrono::duration_cast<std::chrono::seconds>(
  486. end_time - start_time).count() >
  487. DECODE_OUT_TIME_BY_SEC)
  488. {
  489. WriteLog(LogLevel::Level2, "IIC FindStartNode TimeOut");
  490. return false;
  491. }
  492. }
  493. return CommonHelper::CheckTwoLevelEdgePulseValid(node_sda);
  494. }
  495. }