|
@@ -4,400 +4,452 @@
|
|
|
|
|
|
namespace Protocol
|
|
|
{
|
|
|
- bool IicDecoder::DecodeIic(const IicDecodeOptions& option, const EdgePulseDataTwoLevels& edge_pulses_clk,
|
|
|
- const EdgePulseDataTwoLevels& edge_pulses_data, IicDecodeResult& result)
|
|
|
- {
|
|
|
- result = {};
|
|
|
- is_cancel_ptr_ = option.is_cancel;
|
|
|
- wave_data_len_ = static_cast<int32_t>(
|
|
|
- std::min(edge_pulses_clk.waveform_data_count, edge_pulses_data.waveform_data_count));
|
|
|
- bit_width_ = option.data_bit_width;
|
|
|
- const int32_t addr_len = bit_width_ == IicEnums::DataBitWidth::DATA_BIT_WIDTH_7_BIT ? 7 : 10;
|
|
|
- int32_t start_index = 0;
|
|
|
-
|
|
|
- packet_infos_.clear();
|
|
|
- TwoLevelEdgePulse* edge_pulses_data_ptr = edge_pulses_data.GetDataAddrPtr();
|
|
|
- TwoLevelEdgePulse* edge_pulses_clk_ptr = edge_pulses_clk.GetDataAddrPtr();
|
|
|
-
|
|
|
- while (true)
|
|
|
- {
|
|
|
- // 检查是否取消
|
|
|
- if (is_cancel_ptr_ != nullptr && *is_cancel_ptr_)
|
|
|
- {
|
|
|
- WriteLog(LogLevel::Level2, "AsyncFunction canceled");
|
|
|
- return false;
|
|
|
- }
|
|
|
- // find start index
|
|
|
- if (!FindStartNode(start_index, edge_pulses_data_ptr, edge_pulses_clk_ptr))
|
|
|
- {
|
|
|
- break;
|
|
|
- }
|
|
|
- int32_t data_len = wave_data_len_;
|
|
|
- IicPacket info = {};
|
|
|
- info.has_start = true;
|
|
|
- info.start_index = start_index;
|
|
|
- info.start_len = 1;
|
|
|
- packet_infos_.push_back(info);
|
|
|
- start_index = edge_pulses_clk_ptr++->start_index;
|
|
|
- if (start_index <= 0) break;
|
|
|
- start_index = edge_pulses_clk_ptr++->start_index;
|
|
|
- if (start_index <= 0) break;
|
|
|
-
|
|
|
- info.addr_index = start_index;
|
|
|
- for (int index = 0; index < addr_len; ++index)
|
|
|
- {
|
|
|
- if (start_index >= data_len)
|
|
|
- {
|
|
|
- start_index = data_len;
|
|
|
- break;
|
|
|
- }
|
|
|
- if (!CommonHelper::GetNodeByIndex(index, edge_pulses_data_ptr))
|
|
|
- {
|
|
|
- start_index = data_len;
|
|
|
- break;
|
|
|
- }
|
|
|
- const bool bit = edge_pulses_data_ptr->current_level == TwoLevelEdgePulseStatusType::High;
|
|
|
- info.addr_data = static_cast<uint16_t>(info.addr_data << 1 | (bit ? 1 : 0));
|
|
|
- if (!CommonHelper::FindNextNode(start_index, edge_pulses_clk_ptr) || edge_pulses_clk_ptr->start_index <= 0)
|
|
|
- {
|
|
|
- start_index = data_len;
|
|
|
- break;
|
|
|
- }
|
|
|
- if (!CommonHelper::FindNextNode(start_index, edge_pulses_clk_ptr) || edge_pulses_clk_ptr->start_index <= 0)
|
|
|
- {
|
|
|
- start_index = data_len;
|
|
|
- break;
|
|
|
- }
|
|
|
- start_index = edge_pulses_clk_ptr->start_index;
|
|
|
- }
|
|
|
- info.addr_len = start_index - info.addr_index;
|
|
|
-
|
|
|
- // 解析RW标识位
|
|
|
- info.rw_index = start_index;
|
|
|
- if (!CommonHelper::GetNodeByIndex(start_index, edge_pulses_data_ptr))
|
|
|
- {
|
|
|
- start_index = data_len;
|
|
|
- break;
|
|
|
- }
|
|
|
- info.rw = edge_pulses_data_ptr->current_level == TwoLevelEdgePulseStatusType::High;
|
|
|
- start_index = edge_pulses_data_ptr->start_index;
|
|
|
- if (start_index <= 0 || *is_cancel_ptr_)
|
|
|
- {
|
|
|
- start_index = data_len;
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
- if (!CommonHelper::FindNextNode(start_index, edge_pulses_clk_ptr) || edge_pulses_clk_ptr->start_index <= 0)
|
|
|
- {
|
|
|
- start_index = data_len;
|
|
|
- break;
|
|
|
- }
|
|
|
- start_index = edge_pulses_clk_ptr->start_index;
|
|
|
-
|
|
|
- info.rw_len = start_index - info.rw_index;
|
|
|
- packet_infos_.push_back(info);
|
|
|
-
|
|
|
- //解析Addr后的ACK信号
|
|
|
- info.addr_ack_index = start_index;
|
|
|
- info.success_addr_ack = false;
|
|
|
- if (start_index >= data_len) break;
|
|
|
- if (!CommonHelper::GetNodeByIndex(start_index, edge_pulses_data_ptr))
|
|
|
- {
|
|
|
- start_index = data_len;
|
|
|
- break;
|
|
|
- }
|
|
|
- info.addr_ack = edge_pulses_data_ptr->current_level == TwoLevelEdgePulseStatusType::High; //get level
|
|
|
- if (!CommonHelper::FindNextNode(start_index, edge_pulses_data_ptr))
|
|
|
- {
|
|
|
- start_index = data_len;
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
- info.addr_ack_len = start_index - info.addr_ack_index;
|
|
|
- packet_infos_.push_back(info);
|
|
|
-
|
|
|
- if (!CommonHelper::FindNextNode(start_index, edge_pulses_clk_ptr) || edge_pulses_clk_ptr->start_index <= 0)
|
|
|
- {
|
|
|
- start_index = data_len;
|
|
|
- break;
|
|
|
- }
|
|
|
- start_index = edge_pulses_clk_ptr->start_index;
|
|
|
-
|
|
|
- if (start_index <= 0 || *is_cancel_ptr_)
|
|
|
- {
|
|
|
- start_index = data_len;
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
- std::vector<IicDataInfo> temp_infos;
|
|
|
- //开始解析数据
|
|
|
- while (true)
|
|
|
- {
|
|
|
- if (!FindStopNode(start_index, edge_pulses_data_ptr, edge_pulses_clk_ptr))
|
|
|
- {
|
|
|
- break;
|
|
|
- }
|
|
|
- int stop_index = edge_pulses_data_ptr->start_index;
|
|
|
- if (stop_index > 0)
|
|
|
- {
|
|
|
- info.has_end = true;
|
|
|
- info.end_index = stop_index;
|
|
|
- info.end_len = 1;
|
|
|
- if (start_index >= stop_index)
|
|
|
- {
|
|
|
- start_index = stop_index + 1;
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- //下一帧 查找下一段启动信号
|
|
|
-
|
|
|
- if (!FindStartNode(start_index, edge_pulses_data_ptr, edge_pulses_clk_ptr) || *is_cancel_ptr_)
|
|
|
- {
|
|
|
- break;
|
|
|
- }
|
|
|
- auto next_start_index = edge_pulses_clk_ptr->start_index;
|
|
|
- if (start_index >= next_start_index && next_start_index != -1)
|
|
|
- {
|
|
|
- start_index = next_start_index - 1;
|
|
|
- break;
|
|
|
- }
|
|
|
- IicDataInfo data_info = {};
|
|
|
- data_info.index = start_index;
|
|
|
-
|
|
|
- //解析数据
|
|
|
- for (int32_t index = 0; index < 8; index++)
|
|
|
- {
|
|
|
- if (start_index >= data_len)
|
|
|
- {
|
|
|
- start_index = data_len;
|
|
|
- break;
|
|
|
- }
|
|
|
- if (start_index >= stop_index && stop_index != -1)
|
|
|
- {
|
|
|
- start_index = stop_index + 1;
|
|
|
- break;
|
|
|
- }
|
|
|
- if (start_index >= next_start_index && next_start_index != -1)
|
|
|
- {
|
|
|
- start_index = next_start_index - 1;
|
|
|
- break;
|
|
|
- }
|
|
|
- data_info.data <<= 1;
|
|
|
- if (!CommonHelper::GetNodeByIndex(start_index, edge_pulses_data_ptr))
|
|
|
- {
|
|
|
- start_index = data_len;
|
|
|
- break;
|
|
|
- }
|
|
|
- bool bit = edge_pulses_data_ptr->current_level == TwoLevelEdgePulseStatusType::High;
|
|
|
- data_info.data |= static_cast<uint8_t>(bit ? 1 : 0);
|
|
|
-
|
|
|
- if (!CommonHelper::FindNextNode(start_index, edge_pulses_clk_ptr) || edge_pulses_clk_ptr->start_index <= 0)
|
|
|
- {
|
|
|
- start_index = data_len;
|
|
|
- break;
|
|
|
- }
|
|
|
- start_index = edge_pulses_clk_ptr->start_index;
|
|
|
- if (start_index <= 0 || *is_cancel_ptr_)
|
|
|
- {
|
|
|
- start_index = data_len;
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
- if (!CommonHelper::FindNextNode(start_index, edge_pulses_clk_ptr) || edge_pulses_clk_ptr->start_index <= 0)
|
|
|
- {
|
|
|
- start_index = data_len;
|
|
|
- break;
|
|
|
- }
|
|
|
- start_index = edge_pulses_clk_ptr->start_index;
|
|
|
- if (start_index <= 0 || *is_cancel_ptr_)
|
|
|
- {
|
|
|
- start_index = data_len;
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if (start_index >= data_len) break;
|
|
|
- if (start_index >= stop_index && stop_index != -1)
|
|
|
- {
|
|
|
- start_index = stop_index + 1;
|
|
|
- break;
|
|
|
- }
|
|
|
- if (start_index >= next_start_index && next_start_index != -1)
|
|
|
- {
|
|
|
- start_index = next_start_index - 1;
|
|
|
- break;
|
|
|
- }
|
|
|
- //计算长度
|
|
|
- data_info.length = stop_index - start_index;
|
|
|
- //解析数据包后的ACK信号
|
|
|
- data_info.ack_index = start_index;
|
|
|
- if (!CommonHelper::GetNodeByIndex(start_index, edge_pulses_data_ptr))
|
|
|
- {
|
|
|
- start_index = data_len;
|
|
|
- break;
|
|
|
- }
|
|
|
- data_info.ack = edge_pulses_data_ptr->current_level == TwoLevelEdgePulseStatusType::High;
|
|
|
-
|
|
|
- if (!CommonHelper::FindNextNode(start_index, edge_pulses_clk_ptr) || edge_pulses_clk_ptr->start_index <= 0)
|
|
|
- {
|
|
|
- start_index = data_len;
|
|
|
- break;
|
|
|
- }
|
|
|
- start_index = edge_pulses_clk_ptr->start_index;
|
|
|
-
|
|
|
- if (start_index <= 0 /*|| token.IsCancellationRequested || needclear*/)
|
|
|
- {
|
|
|
- start_index = data_len;
|
|
|
- break;
|
|
|
- }
|
|
|
- data_info.ack_length = start_index - data_info.ack_index;
|
|
|
- data_info.success_ack = false;
|
|
|
- if (start_index >= stop_index && stop_index != -1)
|
|
|
- {
|
|
|
- start_index = stop_index + 1;
|
|
|
- break;
|
|
|
- }
|
|
|
- if (start_index >= next_start_index && next_start_index != -1)
|
|
|
- {
|
|
|
- start_index = next_start_index - 1;
|
|
|
- break;
|
|
|
- }
|
|
|
- temp_infos.push_back(data_info);
|
|
|
-
|
|
|
- if (!CommonHelper::FindNextNode(start_index, edge_pulses_clk_ptr) || edge_pulses_clk_ptr->start_index <= 0)
|
|
|
- {
|
|
|
- start_index = data_len;
|
|
|
- break;
|
|
|
- }
|
|
|
- start_index = edge_pulses_clk_ptr->start_index;
|
|
|
-
|
|
|
- if (start_index <= 0 || *is_cancel_ptr_)
|
|
|
- {
|
|
|
- start_index = data_len;
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- info.data_infos = temp_infos;
|
|
|
- //最后一个数据包的ACK信号为NACK
|
|
|
- if (!temp_infos.empty())
|
|
|
- {
|
|
|
- info.data_infos = std::move(temp_infos);
|
|
|
- info.has_end = true;
|
|
|
- info.end_index = start_index;
|
|
|
- info.end_len = 1;
|
|
|
- packet_infos_.push_back(info);
|
|
|
- }
|
|
|
- }
|
|
|
- if (!packet_infos_.empty())
|
|
|
- {
|
|
|
- result.decode_event_need_update = true;
|
|
|
- }
|
|
|
- result.decode_event_count = packet_infos_.size();
|
|
|
- result.decode_events_ptr = packet_infos_.data();
|
|
|
-
|
|
|
- return true;
|
|
|
- }
|
|
|
- bool IicDecoder::FindStopNode(int32_t& start_index, TwoLevelEdgePulse* node_sda,
|
|
|
- TwoLevelEdgePulse* node_scl)
|
|
|
- {
|
|
|
- if (start_index < 0)
|
|
|
- {
|
|
|
- return false;
|
|
|
- }
|
|
|
- const auto start_time = std::chrono::steady_clock::now();
|
|
|
- while (CommonHelper::CheckTwoLevelEdgePulseValid(node_sda))
|
|
|
- {
|
|
|
- // 找到SDA上升沿
|
|
|
- // 寻找SCL高
|
|
|
- if (node_sda->start_index > start_index || node_sda->current_level != TwoLevelEdgePulseStatusType::High)
|
|
|
- {
|
|
|
- node_sda++;
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
- while (node_scl->start_index > start_index)
|
|
|
- {
|
|
|
- node_scl++;
|
|
|
- }
|
|
|
- if (node_sda->start_index > node_scl->start_index)
|
|
|
- {
|
|
|
- node_scl++;
|
|
|
- }
|
|
|
- if (!CommonHelper::CheckTwoLevelEdgePulseValid(node_scl))
|
|
|
- {
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
- // 确认SCL为高电平
|
|
|
- if (node_scl->current_level == TwoLevelEdgePulseStatusType::High)
|
|
|
- {
|
|
|
- if (node_sda->start_index <= node_scl->start_index)
|
|
|
- {
|
|
|
- // 找到目标停止条件
|
|
|
- return true;
|
|
|
- }
|
|
|
- }
|
|
|
- start_index = node_scl->end_index + 1;
|
|
|
- if (auto end_time = std::chrono::steady_clock::now(); std::chrono::duration_cast<std::chrono::nanoseconds>(
|
|
|
- end_time - start_time).count() >
|
|
|
- DECODE_OUT_TIME_BY_SEC)
|
|
|
- {
|
|
|
- WriteLog(LogLevel::Level2, "IIC FindStopNode TimeOut");
|
|
|
- return false;
|
|
|
- }
|
|
|
- }
|
|
|
- return CommonHelper::CheckTwoLevelEdgePulseValid(node_sda);
|
|
|
- }
|
|
|
-
|
|
|
- bool IicDecoder::FindStartNode(int32_t& start_index, TwoLevelEdgePulse* node_sda,
|
|
|
- TwoLevelEdgePulse* node_scl)
|
|
|
- {
|
|
|
- if (start_index < 0)
|
|
|
- {
|
|
|
- return false;
|
|
|
- }
|
|
|
- const auto start_time = std::chrono::steady_clock::now();
|
|
|
- while (CommonHelper::CheckTwoLevelEdgePulseValid(node_sda))
|
|
|
- {
|
|
|
- // 找到SDA下降沿
|
|
|
- // 寻找SCL高
|
|
|
- if (node_sda->start_index > start_index || node_sda->current_level != TwoLevelEdgePulseStatusType::Low)
|
|
|
- {
|
|
|
- node_sda += 1;
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
- while (node_scl->start_index > start_index)
|
|
|
- {
|
|
|
- node_scl++;
|
|
|
- }
|
|
|
- if (node_sda->start_index > node_scl->start_index)
|
|
|
- {
|
|
|
- node_scl += 1;
|
|
|
- }
|
|
|
- if (!CommonHelper::CheckTwoLevelEdgePulseValid(node_scl))
|
|
|
- {
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
- //找到SCL下降沿
|
|
|
- if (node_scl->current_level == TwoLevelEdgePulseStatusType::Low)
|
|
|
- {
|
|
|
- if (node_sda->start_index <= node_scl->start_index)
|
|
|
- {
|
|
|
- //找到目标头
|
|
|
- return true;
|
|
|
- }
|
|
|
- }
|
|
|
- start_index = node_scl->end_index + 1;
|
|
|
- if (auto end_time = std::chrono::steady_clock::now(); std::chrono::duration_cast<std::chrono::nanoseconds>(
|
|
|
- end_time - start_time).count() >
|
|
|
- DECODE_OUT_TIME_BY_SEC)
|
|
|
- {
|
|
|
- WriteLog(LogLevel::Level2, "IIC FindStartNode TimeOut");
|
|
|
- return false;
|
|
|
- }
|
|
|
- }
|
|
|
- return CommonHelper::CheckTwoLevelEdgePulseValid(node_sda);
|
|
|
- }
|
|
|
+ bool IicDecoder::DecodeIic(const IicDecodeOptions& option, const EdgePulseDataTwoLevels& edge_pulses_clk,
|
|
|
+ const EdgePulseDataTwoLevels& edge_pulses_data, IicDecodeResult& result)
|
|
|
+ {
|
|
|
+ result = {};
|
|
|
+ result.decoder_ptr = reinterpret_cast<intptr_t>(this);
|
|
|
+ is_cancel_ptr_ = option.is_cancel;
|
|
|
+ wave_data_len_ = static_cast<int32_t>(
|
|
|
+ std::min(edge_pulses_clk.waveform_data_count, edge_pulses_data.waveform_data_count));
|
|
|
+ bit_width_ = option.data_bit_width;
|
|
|
+ const int32_t addr_len = bit_width_ == IicEnums::DataBitWidth::DATA_BIT_WIDTH_7_BIT ? 7 : 10;
|
|
|
+ int32_t start_index = 0;
|
|
|
+
|
|
|
+ packet_infos_.clear();
|
|
|
+ packet_info_datas_.clear();
|
|
|
+ TwoLevelEdgePulse* edge_pulses_data_ptr = edge_pulses_data.GetDataAddrPtr();
|
|
|
+ TwoLevelEdgePulse* edge_pulses_clk_ptr = edge_pulses_clk.GetDataAddrPtr();
|
|
|
+
|
|
|
+ while (true)
|
|
|
+ {
|
|
|
+ // 检查是否取消
|
|
|
+ if (is_cancel_ptr_ != nullptr && *is_cancel_ptr_)
|
|
|
+ {
|
|
|
+ WriteLog(LogLevel::Level2, "AsyncFunction canceled");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ // find start index
|
|
|
+ if (!FindStartNode(start_index, edge_pulses_data_ptr, edge_pulses_clk_ptr))
|
|
|
+ {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ //start_index = edge_pulses_data_ptr->start_index;
|
|
|
+ int32_t data_len = wave_data_len_;
|
|
|
+ IicEvent info = {};
|
|
|
+ info.has_start = true;
|
|
|
+ info.start_index = start_index;
|
|
|
+ info.start_len = 1;
|
|
|
+
|
|
|
+ //start_index = edge_pulses_clk_ptr++->start_index;
|
|
|
+ if (!CommonHelper::FindNextNode(start_index, edge_pulses_clk_ptr) || edge_pulses_clk_ptr->start_index <= 0)
|
|
|
+ {
|
|
|
+ start_index = data_len;
|
|
|
+ packet_infos_.push_back(info);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ start_index = edge_pulses_clk_ptr->start_index;
|
|
|
+ //if (start_index <= 0) break;
|
|
|
+ //start_index = edge_pulses_clk_ptr++->start_index;
|
|
|
+ if (!CommonHelper::FindNextNode(start_index, edge_pulses_clk_ptr) || edge_pulses_clk_ptr->start_index <= 0)
|
|
|
+ {
|
|
|
+ start_index = data_len;
|
|
|
+ packet_infos_.push_back(info);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ start_index = edge_pulses_clk_ptr->start_index;
|
|
|
+ //if (start_index <= 0) break;
|
|
|
+
|
|
|
+ info.addr_index = start_index;
|
|
|
+ for (int index = 0; index < addr_len; ++index)
|
|
|
+ {
|
|
|
+ if (start_index >= data_len)
|
|
|
+ {
|
|
|
+ start_index = data_len;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ if (!CommonHelper::GetNodeByIndex(start_index, edge_pulses_data_ptr))
|
|
|
+ {
|
|
|
+ start_index = data_len;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ const bool bit = edge_pulses_data_ptr->current_level == TwoLevelEdgePulseStatusType::High;
|
|
|
+ info.addr_data = static_cast<uint16_t>(info.addr_data << 1 | (bit ? 1 : 0));
|
|
|
+ if (!CommonHelper::FindNextNode(start_index, edge_pulses_clk_ptr) || edge_pulses_clk_ptr->start_index <= 0)
|
|
|
+ {
|
|
|
+ start_index = data_len;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ start_index = edge_pulses_clk_ptr->start_index;
|
|
|
+ if (!CommonHelper::FindNextNode(start_index, edge_pulses_clk_ptr) || edge_pulses_clk_ptr->start_index <= 0)
|
|
|
+ {
|
|
|
+ start_index = data_len;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ start_index = edge_pulses_clk_ptr->start_index;
|
|
|
+ }
|
|
|
+ info.addr_len = start_index - info.addr_index;
|
|
|
+
|
|
|
+ // 解析RW标识位
|
|
|
+ info.rw_index = start_index;
|
|
|
+ if (!CommonHelper::GetNodeByIndex(start_index, edge_pulses_data_ptr))
|
|
|
+ {
|
|
|
+ start_index = data_len;
|
|
|
+ packet_infos_.push_back(info);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ info.rw = edge_pulses_data_ptr->current_level == TwoLevelEdgePulseStatusType::High ? 1 : 0;//get level
|
|
|
+ start_index = edge_pulses_clk_ptr->start_index;
|
|
|
+ if (start_index <= 0 || (is_cancel_ptr_ != nullptr && *is_cancel_ptr_))
|
|
|
+ {
|
|
|
+ start_index = data_len;
|
|
|
+ packet_infos_.push_back(info);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!CommonHelper::FindNextNode(start_index, edge_pulses_clk_ptr) || edge_pulses_clk_ptr->start_index <= 0)
|
|
|
+ {
|
|
|
+ start_index = data_len;
|
|
|
+ packet_infos_.push_back(info);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ start_index = edge_pulses_clk_ptr->start_index;
|
|
|
+ if (!CommonHelper::FindNextNode(start_index, edge_pulses_clk_ptr) || edge_pulses_clk_ptr->start_index <= 0)
|
|
|
+ {
|
|
|
+ start_index = data_len;
|
|
|
+ packet_infos_.push_back(info);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ start_index = edge_pulses_clk_ptr->start_index;
|
|
|
+
|
|
|
+ info.rw_len = start_index - info.rw_index;
|
|
|
+
|
|
|
+ //解析Addr后的ACK信号
|
|
|
+ info.addr_ack_index = start_index;
|
|
|
+ info.success_addr_ack = false;
|
|
|
+ if (start_index >= data_len) {
|
|
|
+ packet_infos_.push_back(info);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ if (!CommonHelper::GetNodeByIndex(start_index, edge_pulses_data_ptr))
|
|
|
+ {
|
|
|
+ start_index = data_len;
|
|
|
+ packet_infos_.push_back(info);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ info.addr_ack = edge_pulses_data_ptr->current_level == TwoLevelEdgePulseStatusType::High; //get level
|
|
|
+ if (!CommonHelper::FindNextNode(start_index, edge_pulses_clk_ptr) || edge_pulses_clk_ptr->start_index <= 0)
|
|
|
+ {
|
|
|
+ start_index = data_len;
|
|
|
+ packet_infos_.push_back(info);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ start_index = edge_pulses_clk_ptr->start_index;
|
|
|
+
|
|
|
+ info.addr_ack_len = start_index - info.addr_ack_index;
|
|
|
+
|
|
|
+
|
|
|
+ if (!CommonHelper::FindNextNode(start_index, edge_pulses_clk_ptr) || edge_pulses_clk_ptr->start_index <= 0)
|
|
|
+ {
|
|
|
+ start_index = data_len;
|
|
|
+ packet_infos_.push_back(info);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ start_index = edge_pulses_clk_ptr->start_index;
|
|
|
+
|
|
|
+ if (start_index <= 0 || (is_cancel_ptr_ != nullptr && *is_cancel_ptr_))
|
|
|
+ {
|
|
|
+ start_index = data_len;
|
|
|
+ packet_infos_.push_back(info);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ std::vector<IicDataInfo> temp_infos;
|
|
|
+ //开始解析数据
|
|
|
+ while (true)
|
|
|
+ {
|
|
|
+ int stop_index = 0;
|
|
|
+ if (FindStopNode(start_index, edge_pulses_data_ptr, edge_pulses_clk_ptr))
|
|
|
+ {
|
|
|
+ stop_index = edge_pulses_data_ptr->start_index;
|
|
|
+ if (stop_index > 0)
|
|
|
+ {
|
|
|
+ info.has_end = true;
|
|
|
+ info.end_index = stop_index;
|
|
|
+ info.end_len = 1;
|
|
|
+ if (start_index >= stop_index)
|
|
|
+ {
|
|
|
+ start_index = stop_index + 1;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ //下一帧 查找下一段启动信号
|
|
|
+ if (start_index > edge_pulses_clk_ptr->start_index)
|
|
|
+ {
|
|
|
+ start_index = edge_pulses_clk_ptr->start_index;
|
|
|
+ }
|
|
|
+ int32_t next_start_index = -1;
|
|
|
+ if (FindStartNode(start_index, edge_pulses_data_ptr, edge_pulses_clk_ptr) || (is_cancel_ptr_ != nullptr && *is_cancel_ptr_))
|
|
|
+ {
|
|
|
+ next_start_index = edge_pulses_data_ptr->start_index;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (start_index >= next_start_index && next_start_index != -1)
|
|
|
+ {
|
|
|
+ start_index = next_start_index - 1;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ IicDataInfo data_info = {};
|
|
|
+ data_info.index = start_index;
|
|
|
+
|
|
|
+ //解析数据
|
|
|
+ for (int32_t index = 0; index < 8; index++)
|
|
|
+ {
|
|
|
+ if (start_index >= data_len)
|
|
|
+ {
|
|
|
+ start_index = data_len;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ if (start_index >= stop_index && stop_index != -1)
|
|
|
+ {
|
|
|
+ start_index = stop_index + 1;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ if (start_index >= next_start_index && next_start_index != -1)
|
|
|
+ {
|
|
|
+ start_index = next_start_index - 1;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ data_info.data <<= 1;
|
|
|
+ if (!CommonHelper::GetNodeByIndex(start_index, edge_pulses_data_ptr))
|
|
|
+ {
|
|
|
+ start_index = data_len;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ bool bit = edge_pulses_data_ptr->current_level == TwoLevelEdgePulseStatusType::High;
|
|
|
+ data_info.data |= static_cast<uint8_t>(bit ? 1 : 0);
|
|
|
+
|
|
|
+ if (!CommonHelper::FindNextNode(start_index, edge_pulses_clk_ptr) || edge_pulses_clk_ptr->start_index <= 0)
|
|
|
+ {
|
|
|
+ start_index = data_len;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ start_index = edge_pulses_clk_ptr->start_index;
|
|
|
+ if (start_index <= 0 || (is_cancel_ptr_ != nullptr && *is_cancel_ptr_))
|
|
|
+ {
|
|
|
+ start_index = data_len;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!CommonHelper::FindNextNode(start_index, edge_pulses_clk_ptr) || edge_pulses_clk_ptr->start_index <= 0)
|
|
|
+ {
|
|
|
+ start_index = data_len;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ start_index = edge_pulses_clk_ptr->start_index;
|
|
|
+ if (start_index <= 0 || (is_cancel_ptr_ != nullptr && *is_cancel_ptr_))
|
|
|
+ {
|
|
|
+ start_index = data_len;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (start_index >= data_len) break;
|
|
|
+ if (start_index >= stop_index && stop_index != -1)
|
|
|
+ {
|
|
|
+ start_index = stop_index + 1;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ if (start_index >= next_start_index && next_start_index != -1)
|
|
|
+ {
|
|
|
+ start_index = next_start_index - 1;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ //计算长度
|
|
|
+ data_info.length = stop_index - start_index;
|
|
|
+ //解析数据包后的ACK信号
|
|
|
+ data_info.ack_index = start_index;
|
|
|
+ if (!CommonHelper::GetNodeByIndex(start_index, edge_pulses_data_ptr))
|
|
|
+ {
|
|
|
+ start_index = data_len;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ data_info.ack = edge_pulses_data_ptr->current_level == TwoLevelEdgePulseStatusType::High;
|
|
|
+
|
|
|
+ if (!CommonHelper::FindNextNode(start_index, edge_pulses_clk_ptr) || edge_pulses_clk_ptr->start_index <= 0)
|
|
|
+ {
|
|
|
+ start_index = data_len;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ start_index = edge_pulses_clk_ptr->start_index;
|
|
|
+
|
|
|
+ if (start_index <= 0 /*|| token.IsCancellationRequested || needclear*/)
|
|
|
+ {
|
|
|
+ start_index = data_len;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ data_info.ack_length = start_index - data_info.ack_index;
|
|
|
+ data_info.success_ack = false;
|
|
|
+ if (start_index >= stop_index && stop_index != -1)
|
|
|
+ {
|
|
|
+ start_index = stop_index + 1;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ if (start_index >= next_start_index && next_start_index != -1)
|
|
|
+ {
|
|
|
+ start_index = next_start_index - 1;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ temp_infos.push_back(data_info);
|
|
|
+
|
|
|
+ if (!CommonHelper::FindNextNode(start_index, edge_pulses_clk_ptr) || edge_pulses_clk_ptr->start_index <= 0)
|
|
|
+ {
|
|
|
+ start_index = data_len;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ start_index = edge_pulses_clk_ptr->start_index;
|
|
|
+
|
|
|
+ if (start_index <= 0 || (is_cancel_ptr_ != nullptr && *is_cancel_ptr_))
|
|
|
+ {
|
|
|
+ start_index = data_len;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //info.data_infos = temp_infos;
|
|
|
+ //最后一个数据包的ACK信号为NACK
|
|
|
+ if (!temp_infos.empty())
|
|
|
+ {
|
|
|
+ int32_t old_data_len = static_cast<int32_t>(packet_info_datas_.size());
|
|
|
+ info.data_infos_count = static_cast<int32_t>(temp_infos.size());
|
|
|
+ // 使用std::move将temp_infos的内容移动到packet_info_datas_的末尾
|
|
|
+ packet_info_datas_.insert(packet_info_datas_.end(),
|
|
|
+ std::make_move_iterator(temp_infos.begin()), std::make_move_iterator(temp_infos.end()));
|
|
|
+ info.data_infos_ptr = reinterpret_cast<intptr_t> (packet_info_datas_.data() + old_data_len - 1);
|
|
|
+
|
|
|
+ info.has_end = true;
|
|
|
+ info.end_index = start_index;
|
|
|
+ info.end_len = 1;
|
|
|
+
|
|
|
+ info.success_addr_ack = true;
|
|
|
+ }
|
|
|
+
|
|
|
+ packet_infos_.push_back(info);
|
|
|
+ }
|
|
|
+ if (!packet_infos_.empty())
|
|
|
+ {
|
|
|
+ result.decode_event_need_update = true;
|
|
|
+ }
|
|
|
+ result.decode_event_count = packet_infos_.size();
|
|
|
+ result.decode_events_ptr = packet_infos_.data();
|
|
|
+
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ bool IicDecoder::FindStopNode(int32_t& start_index, TwoLevelEdgePulse* node_sda,
|
|
|
+ TwoLevelEdgePulse* node_scl)
|
|
|
+ {
|
|
|
+ if (start_index < 0)
|
|
|
+ {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ const auto start_time = std::chrono::steady_clock::now();
|
|
|
+ while (CommonHelper::CheckTwoLevelEdgePulseValid(node_sda))
|
|
|
+ {
|
|
|
+ // 找到SDA上升沿
|
|
|
+ // 寻找SCL高
|
|
|
+ if (node_sda->start_index > start_index || node_sda->current_level != TwoLevelEdgePulseStatusType::High)
|
|
|
+ {
|
|
|
+ node_sda++;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!CommonHelper::FindNextNode(node_sda->start_index, node_scl))
|
|
|
+ {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (node_sda->start_index > node_scl->start_index)
|
|
|
+ {
|
|
|
+ node_scl++;
|
|
|
+ }
|
|
|
+ if (!CommonHelper::CheckTwoLevelEdgePulseValid(node_scl))
|
|
|
+ {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 确认下一个SCL为低电平
|
|
|
+ if (node_scl->current_level == TwoLevelEdgePulseStatusType::Low)
|
|
|
+ {
|
|
|
+ if (node_sda->start_index < node_scl->start_index)
|
|
|
+ {
|
|
|
+ // 找到目标停止条件
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ start_index = node_scl->end_index + 1;
|
|
|
+ if (auto end_time = std::chrono::steady_clock::now(); std::chrono::duration_cast<std::chrono::nanoseconds>(
|
|
|
+ end_time - start_time).count() >
|
|
|
+ DECODE_OUT_TIME_BY_SEC)
|
|
|
+ {
|
|
|
+ WriteLog(LogLevel::Level2, "IIC FindStopNode TimeOut");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return CommonHelper::CheckTwoLevelEdgePulseValid(node_sda);
|
|
|
+ }
|
|
|
+
|
|
|
+ bool IicDecoder::FindStartNode(int32_t& start_index, TwoLevelEdgePulse* node_sda,
|
|
|
+ TwoLevelEdgePulse* node_scl)
|
|
|
+ {
|
|
|
+ if (start_index < 0)
|
|
|
+ {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ const auto start_time = std::chrono::steady_clock::now();
|
|
|
+ while (CommonHelper::CheckTwoLevelEdgePulseValid(node_sda))
|
|
|
+ {
|
|
|
+ // 找到SDA下降沿
|
|
|
+ // 寻找SCL高
|
|
|
+ if (node_sda->start_index < start_index || node_sda->current_level != TwoLevelEdgePulseStatusType::Low)
|
|
|
+ {
|
|
|
+ node_sda += 1;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ while (node_scl->start_index < start_index)
|
|
|
+ {
|
|
|
+ node_scl++;
|
|
|
+ }
|
|
|
+ if (node_sda->start_index > node_scl->start_index)
|
|
|
+ {
|
|
|
+ node_scl += 1;
|
|
|
+ }
|
|
|
+ if (!CommonHelper::CheckTwoLevelEdgePulseValid(node_scl))
|
|
|
+ {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ //找到SCL下降沿
|
|
|
+ if (node_scl->current_level == TwoLevelEdgePulseStatusType::Low)
|
|
|
+ {
|
|
|
+ if (node_sda->start_index < node_scl->start_index)
|
|
|
+ {
|
|
|
+ //找到目标头
|
|
|
+ start_index = node_sda->start_index;
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ start_index = node_scl->end_index + 1;
|
|
|
+ if (auto end_time = std::chrono::steady_clock::now(); std::chrono::duration_cast<std::chrono::nanoseconds>(
|
|
|
+ end_time - start_time).count() >
|
|
|
+ DECODE_OUT_TIME_BY_SEC)
|
|
|
+ {
|
|
|
+ WriteLog(LogLevel::Level2, "IIC FindStartNode TimeOut");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return CommonHelper::CheckTwoLevelEdgePulseValid(node_sda);
|
|
|
+ }
|
|
|
}
|