spi_decoder.cc 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458
  1. // // ******************************************************************
  2. // // /\ /| @File spi_decoder.cc
  3. // // \ V/ @Brief
  4. // // | "") @Author lijinwen, ghz005@uni-trend.com.cn
  5. // // / | @Creation 2024-07-19
  6. // // / \\ @Modified 2024-07-23
  7. // // *(__\_\
  8. // // ******************************************************************
  9. #include "spi_decoder.h"
  10. #include "../BaseHelper/common_helper.h"
  11. #include "../BaseHelper/constants.h"
  12. namespace Protocol
  13. {
  14. bool SpiDecoder::DecodeSpi(const SpiDecodeOptions& options, const EdgePulseDataTwoLevels& edge_pulse_data_clk,
  15. const EdgePulseDataTwoLevels& edge_pulse_data_cs,
  16. const EdgePulseDataTwoLevels& edge_pulse_data_mosi,
  17. const EdgePulseDataTwoLevels& edge_pulse_data_miso, SpiDecodeResult& decode_result)
  18. {
  19. is_cancel_ptr_ = options.is_cancel;
  20. decode_result = {};
  21. decode_result.decoder_ptr = reinterpret_cast<intptr_t>(this);
  22. need_decode_data_ = true;
  23. bool checked_params = true;
  24. if (edge_pulse_data_clk.waveform_data_count <= 0
  25. || edge_pulse_data_cs.waveform_data_count <= 0
  26. || edge_pulse_data_clk.sample_rate <= 0
  27. || edge_pulse_data_cs.sample_rate <= 0)
  28. {
  29. checked_params = false;
  30. }
  31. const bool decode_mosi = options.decode_channel == SpiEnums::DecodeChannel::MOMI || options.decode_channel ==
  32. SpiEnums::DecodeChannel::MOSI;
  33. const bool decode_miso = options.decode_channel == SpiEnums::DecodeChannel::MOMI || options.decode_channel ==
  34. SpiEnums::DecodeChannel::MISO;
  35. if (decode_mosi && (edge_pulse_data_mosi.waveform_data_count <= 0 || edge_pulse_data_mosi.sample_rate <= 0))
  36. {
  37. checked_params = false;
  38. }
  39. if (decode_miso && (edge_pulse_data_miso.waveform_data_count <= 0 || edge_pulse_data_miso.sample_rate <= 0))
  40. {
  41. checked_params = false;
  42. }
  43. if (!checked_params)
  44. {
  45. need_decode_data_ = false;
  46. need_update_view_info_ = true;
  47. /*miso_data.clear();
  48. mosi_data.clear();*/
  49. data_packet_info_.clear();
  50. packet_infos_.clear();
  51. return false;
  52. }
  53. try
  54. {
  55. if (need_decode_data_)
  56. {
  57. /* miso_data.clear();
  58. mosi_data.clear();*/
  59. data_packet_info_.clear();
  60. packet_infos_.clear();
  61. need_decode_data_ = false;
  62. need_update_view_info_ = true;
  63. try
  64. {
  65. int32_t packet_index = 0, last_packet_index = 0;
  66. uint64_t cs_len = edge_pulse_data_cs.waveform_data_count;
  67. uint64_t clk_len = edge_pulse_data_clk.waveform_data_count;
  68. uint64_t miso_len = 0;
  69. uint64_t mosi_len = 0;
  70. uint64_t min_data_len = std::min(cs_len, clk_len);
  71. TwoLevelEdgePulse* edge_pulse_data_cs_ptr = edge_pulse_data_cs.GetDataAddrPtr();
  72. TwoLevelEdgePulse* edge_pulse_data_clk_ptr = edge_pulse_data_clk.GetDataAddrPtr();
  73. TwoLevelEdgePulse* edge_pulse_data_miso_ptr = nullptr;
  74. TwoLevelEdgePulse* edge_pulse_data_mosi_ptr = nullptr;
  75. if (decode_miso)
  76. {
  77. miso_len = edge_pulse_data_miso.waveform_data_count;
  78. edge_pulse_data_miso_ptr = edge_pulse_data_miso.GetDataAddrPtr();
  79. min_data_len = std::min(min_data_len, miso_len);
  80. }
  81. if (decode_mosi)
  82. {
  83. mosi_len = edge_pulse_data_mosi.waveform_data_count;
  84. edge_pulse_data_mosi_ptr = edge_pulse_data_mosi.GetDataAddrPtr();
  85. min_data_len = std::min(min_data_len, mosi_len);
  86. }
  87. data_len_ = static_cast<int32_t>(min_data_len);
  88. if (data_len_ == 0)
  89. {
  90. WriteLog(LogLevel::Level2, "data_len == 0");
  91. return false;
  92. }
  93. int32_t cs_start_index = -1;
  94. const bool clk_state = options.clk_polarity == Polarity::POS;
  95. while (true)
  96. {
  97. // 检查是否取消
  98. if (is_cancel_ptr_ != nullptr && *is_cancel_ptr_)
  99. {
  100. WriteLog(LogLevel::Level2, "AsyncFunction canceled");
  101. return false;
  102. }
  103. if (!FindStartNode(packet_index, cs_start_index,
  104. edge_pulse_data_cs_ptr, edge_pulse_data_clk_ptr,
  105. options.cs_polarity, options.clk_polarity))
  106. {
  107. WriteLog(LogLevel::Level2, "Not find start node");
  108. break;
  109. }
  110. if (packet_index < 0) break;
  111. SpiPacket packet_info = {};
  112. packet_info.start_index = cs_start_index;
  113. packet_info.start_len = 1;
  114. packet_info.has_start = cs_start_index >= 0 ? 1 : 0;
  115. if (!GetCsBitNextIndex(options.cs_polarity == Polarity::POS,
  116. packet_index, edge_pulse_data_cs_ptr))
  117. {
  118. break;
  119. }
  120. const auto cs_end_index = edge_pulse_data_cs_ptr->start_index;
  121. if (is_cancel_ptr_ != nullptr && *is_cancel_ptr_)
  122. {
  123. WriteLog(LogLevel::Level2, "AsyncFunction canceled");
  124. return false;
  125. }
  126. if (bool need_clear = false; need_clear) break;
  127. if (cs_end_index > packet_index)
  128. {
  129. packet_info.has_end = 1;
  130. packet_info.end_len = 1;
  131. packet_info.end_index = cs_end_index;
  132. }
  133. std::vector<DataPacketInfo> temp_data_packets;
  134. //数据解码
  135. while (true)
  136. {
  137. DataPacketInfo temp_data_packet = {};
  138. //std::vector<uint8_t> temp_miso_datas = {}, temp_mosi_datas = {};
  139. temp_data_packet.bit_count = frame_count_;
  140. temp_data_packet.index = packet_index;
  141. int32_t temp_miso_data = 0, temp_mosi_data = 0;
  142. bool get_miso_data = false, get_mosi_data = false;
  143. for (int32_t bit_index = 0; bit_index < frame_count_; ++bit_index)
  144. {
  145. bool miso_bit = false;
  146. bool mosi_bit = false;
  147. if (decode_miso)
  148. {
  149. if (!CommonHelper::GetNodeByIndex(packet_index, edge_pulse_data_miso_ptr))
  150. {
  151. get_miso_data = false;
  152. break;
  153. }
  154. miso_bit = edge_pulse_data_miso_ptr->current_level == TwoLevelEdgePulseStatusType::High;
  155. if (options.miso_polarity == Polarity::NEG)
  156. {
  157. miso_bit = !miso_bit;
  158. }
  159. get_miso_data = true;
  160. }
  161. if (decode_mosi)
  162. {
  163. if (!CommonHelper::GetNodeByIndex(packet_index, edge_pulse_data_mosi_ptr))
  164. {
  165. get_miso_data = false;
  166. break;
  167. }
  168. mosi_bit = edge_pulse_data_mosi_ptr->current_level == TwoLevelEdgePulseStatusType::High;
  169. if (options.mosi_polarity == Polarity::NEG)
  170. {
  171. mosi_bit = !mosi_bit;
  172. }
  173. get_mosi_data = true;
  174. }
  175. if (options.msb_lsb == SpiEnums::Msblsb::MSB)
  176. {
  177. temp_miso_data <<= 1;
  178. temp_miso_data |= (miso_bit ? 1 : 0);
  179. temp_mosi_data <<= 1;
  180. temp_mosi_data |= (mosi_bit ? 1 : 0);
  181. }
  182. else
  183. {
  184. temp_miso_data |= (miso_bit ? 1 : 0) << bit_index;
  185. temp_mosi_data |= (mosi_bit ? 1 : 0) << bit_index;
  186. }
  187. temp_data_packet.real_bit_count = bit_index + 1;
  188. if (!GetClkEdge(!clk_state, packet_index, edge_pulse_data_clk_ptr))
  189. {
  190. break;
  191. }
  192. if ((packet_index > cs_end_index && cs_end_index >= 0) || packet_index == -1)
  193. {
  194. temp_data_packet.is_last = 1;
  195. break;
  196. }
  197. }
  198. if (packet_index > cs_end_index && cs_end_index != -1)
  199. {
  200. packet_index = cs_end_index;
  201. temp_data_packet.len = packet_index - temp_data_packet.index;
  202. }
  203. if (packet_index == -1)
  204. {
  205. if (cs_end_index != -1)
  206. {
  207. temp_data_packet.len = cs_end_index - temp_data_packet.index;
  208. }
  209. else
  210. {
  211. temp_data_packet.len = static_cast<int>(miso_len - temp_data_packet.index);
  212. }
  213. }
  214. else if (packet_index >= temp_data_packet.index && temp_data_packet.len == 0)
  215. {
  216. temp_data_packet.len = packet_index - temp_data_packet.index;
  217. }
  218. //if (temp_data_packet.real_bit_count > 0) temp_data_packets.push_back(temp_data_packet);
  219. //end
  220. if (temp_data_packet.real_bit_count > 0)
  221. {
  222. //miso
  223. if (decode_miso)
  224. {
  225. temp_data_packet.miso_data_count = get_miso_data ? 1 : 0;
  226. if (temp_data_packet.miso_data_count > 0)
  227. {
  228. /* int32_t last_data_count = miso_data.size();
  229. miso_data.push_back(temp_miso_data);
  230. temp_data_packet.miso_data_ptr = miso_data.data() + last_data_count; */
  231. temp_data_packet.miso_data = static_cast<uint8_t>(temp_miso_data);
  232. }
  233. }
  234. //mosi
  235. if (decode_mosi)
  236. {
  237. temp_data_packet.mosi_data_count = get_mosi_data ? 1 : 0;
  238. if (temp_data_packet.mosi_data_count > 0)
  239. {
  240. /*int32_t last_data_count = mosi_data.size();
  241. mosi_data.push_back(temp_mosi_data);
  242. temp_data_packet.mosi_data_ptr = mosi_data.data() + last_data_count;*/
  243. temp_data_packet.mosi_data = static_cast<uint8_t>(temp_mosi_data);
  244. }
  245. }
  246. temp_data_packets.push_back(temp_data_packet);
  247. }
  248. if (temp_data_packet.is_last == 1 || packet_index >= data_len_) break;
  249. if (last_packet_index == packet_index)
  250. {
  251. break;
  252. }
  253. last_packet_index = packet_index;
  254. }
  255. //packet
  256. packet_info.data_count = static_cast<int32_t>(temp_data_packets.size());
  257. if (packet_info.data_count > 0)
  258. {
  259. int32_t last_data_count = static_cast<int32_t>(data_packet_info_.size());
  260. // 复制到末尾
  261. data_packet_info_.insert(data_packet_info_.end(),
  262. std::make_move_iterator(temp_data_packets.begin()),
  263. std::make_move_iterator(temp_data_packets.end()));
  264. packet_info.data_ptr = reinterpret_cast<intptr_t>(data_packet_info_.data() + last_data_count - 1);
  265. packet_info.data_info = temp_data_packets[0];
  266. }
  267. packet_infos_.push_back(packet_info);
  268. if (decode_miso && packet_index >= static_cast<int32_t>(miso_len))
  269. {
  270. break;
  271. }
  272. if (decode_mosi && packet_index >= static_cast<int32_t>(mosi_len))
  273. {
  274. break;
  275. }
  276. if (packet_index < 0)
  277. {
  278. break;
  279. }
  280. }
  281. }
  282. catch (const std::exception& ex)
  283. {
  284. std::string error_message = "DecodeSpi Error: " + std::string(ex.what());
  285. WriteLog(LogLevel::Level2, error_message.c_str());
  286. }
  287. }
  288. }
  289. catch (const std::exception& ex)
  290. {
  291. std::string error_message = "DecodeSpi Error: " + std::string(ex.what());
  292. WriteLog(LogLevel::Level2, error_message.c_str());
  293. }
  294. if (need_update_view_info_)
  295. {
  296. need_update_view_info_ = false;
  297. if (packet_infos_.size() > 0)
  298. {
  299. decode_result.decode_events_ptr = packet_infos_.data();
  300. decode_result.decode_event_count = packet_infos_.size();
  301. }
  302. }
  303. return true;
  304. }
  305. bool SpiDecoder::GetClkEdge(const bool state, int32_t& start_index, TwoLevelEdgePulse*& node_clk)
  306. {
  307. if (!CommonHelper::GetNodeByIndex(start_index, node_clk))
  308. {
  309. return false;
  310. }
  311. if (node_clk->current_level == TwoLevelEdgePulseStatusType::High != state)
  312. {
  313. if (!CommonHelper::FindNextNode(start_index, node_clk))
  314. {
  315. return false;
  316. }
  317. start_index = node_clk->start_index;
  318. if (start_index < 0) return false;
  319. }
  320. if (start_index < 0) return false;
  321. if (!CommonHelper::FindNextNode(start_index, node_clk))
  322. {
  323. return false;
  324. }
  325. start_index = node_clk->start_index;
  326. if (start_index < 0) return false;
  327. return true;
  328. }
  329. bool SpiDecoder::FindStartNode(int32_t& start_index, int32_t& cs_start_index, TwoLevelEdgePulse*& node_cs,
  330. TwoLevelEdgePulse*& node_clk,
  331. const Polarity polarity_cs, const Polarity polarity_clk) const
  332. {
  333. cs_start_index = -1;
  334. if (start_index >= data_len_) return false;
  335. const bool state = polarity_cs == Polarity::POS;
  336. const bool clk_state = polarity_clk == Polarity::NEG;
  337. if (!CommonHelper::GetNodeByIndex(start_index, node_cs))
  338. {
  339. return false;
  340. }
  341. if (node_cs->current_level == TwoLevelEdgePulseStatusType::High != state)
  342. {
  343. if (!CommonHelper::FindNextNode(start_index, node_cs))
  344. {
  345. return false;
  346. }
  347. cs_start_index = node_cs->start_index;
  348. if (cs_start_index < 0) return false;
  349. }
  350. else
  351. {
  352. if (start_index > 0)
  353. {
  354. cs_start_index = start_index;
  355. }
  356. }
  357. if (cs_start_index >= 0)
  358. {
  359. start_index = cs_start_index;
  360. }
  361. const auto start_time = std::chrono::steady_clock::now();
  362. while (true)
  363. {
  364. if (!CommonHelper::GetNodeByIndex(start_index, node_clk))
  365. {
  366. return false;
  367. }
  368. if (node_clk->current_level == TwoLevelEdgePulseStatusType::High != clk_state)
  369. {
  370. if (!CommonHelper::FindNextNode(start_index, node_clk))
  371. {
  372. return false;
  373. }
  374. start_index = node_clk->start_index;
  375. }
  376. if (start_index <= 0) return false;
  377. if (!CommonHelper::FindNextNode(start_index, node_clk))
  378. {
  379. return false;
  380. }
  381. start_index = node_clk->start_index;
  382. if (start_index <= 0) return false;
  383. if (!CommonHelper::GetNodeByIndex(start_index, node_cs))
  384. {
  385. return false;
  386. }
  387. if (node_cs->current_level == TwoLevelEdgePulseStatusType::High == state) return node_cs->start_index;
  388. if (auto end_time = std::chrono::steady_clock::now(); std::chrono::duration_cast<std::chrono::nanoseconds>(
  389. end_time - start_time).count() >
  390. DECODE_OUT_TIME_BY_SEC)
  391. {
  392. WriteLog(LogLevel::Level2, "IIC FindStopNode TimeOut");
  393. return false;
  394. }
  395. }
  396. }
  397. bool SpiDecoder::GetCsBitNextIndex(const bool state, int32_t start_index, TwoLevelEdgePulse*& node_cs)
  398. {
  399. if (!CommonHelper::GetNodeByIndex(start_index, node_cs))
  400. {
  401. return false;
  402. }
  403. if (node_cs->current_level == TwoLevelEdgePulseStatusType::High != state)
  404. {
  405. if (!CommonHelper::FindNextNode(start_index, node_cs))
  406. {
  407. return false;
  408. }
  409. start_index = node_cs->start_index;
  410. }
  411. if (start_index == -1) return false;
  412. if (!CommonHelper::FindNextNode(start_index, node_cs))
  413. {
  414. return false;
  415. }
  416. //start_index = node_cs->start_index;
  417. return true;
  418. }
  419. }