|
@@ -3,7 +3,7 @@
|
|
|
// // \ V/ @Brief
|
|
|
// // | "") @Author lijinwen, ghz005@uni-trend.com.cn
|
|
|
// // / | @Creation 2024-05-17
|
|
|
-// // / \\ @Modified 2024-05-30
|
|
|
+// // / \\ @Modified 2024-06-05
|
|
|
// // *(__\_\
|
|
|
// // ******************************************************************
|
|
|
|
|
@@ -18,416 +18,427 @@
|
|
|
|
|
|
namespace Protocol
|
|
|
{
|
|
|
- std::vector<std::string> USBDecoder::EventInfoTitles()
|
|
|
- {
|
|
|
- return {"Index", "Start Time", "Sync", "PID", "Data", "Addr", "FNUM", "CRC5", "CRC16", "EOP", "Error"};
|
|
|
- }
|
|
|
-
|
|
|
- //主解码函数入口
|
|
|
- bool USBDecoder::DecodeUSB(const UsbDecodeOptions& option, const EdgePulseDataTwoLevels& edge_pulses_dp,
|
|
|
- const EdgePulseDataTwoLevels& edge_pulses_dm, UsbDecodeResult& result)
|
|
|
- {
|
|
|
- std::vector<Protocol::TwoLevelEdgePulse> edge_pulses2 =
|
|
|
- CommonHelper::ConvertPointerArrayToVector<Protocol::TwoLevelEdgePulse>(
|
|
|
- edge_pulses_dm.GetDataAddrPtr(), edge_pulses_dm.EdgePulsesCount);
|
|
|
- std::vector<Protocol::TwoLevelEdgePulse> edge_pulses1 =
|
|
|
- CommonHelper::ConvertPointerArrayToVector<Protocol::TwoLevelEdgePulse>(
|
|
|
- edge_pulses_dp.GetDataAddrPtr(), edge_pulses_dp.EdgePulsesCount);
|
|
|
- differenceEopIndexs = {};
|
|
|
- double set_bit_time_span = 0;
|
|
|
- //////参数判断
|
|
|
- if (!CheckOptions(option, edge_pulses1, edge_pulses2, set_bit_time_span))
|
|
|
- {
|
|
|
- return false;
|
|
|
- }
|
|
|
- resultCells = {};
|
|
|
- usbDiffUnalignedFramesIndex = {};
|
|
|
-
|
|
|
- //////处理差分逻辑
|
|
|
- if (option.SignType == SignType::Diff)
|
|
|
- {
|
|
|
- if (!ParseDiffSignalData(edge_pulses1, edge_pulses2))
|
|
|
- {
|
|
|
- return false;
|
|
|
- }
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- if (edge_pulses1.size() < edge_pulses2.size())
|
|
|
- {
|
|
|
- signEdgePulse = std::move(edge_pulses2);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- signEdgePulse = std::move(edge_pulses1);
|
|
|
- }
|
|
|
- }
|
|
|
- waveMaxTimeIndexLen = signEdgePulse[signEdgePulse.size() - 1].EndIndex;
|
|
|
- //////处理单端逻辑
|
|
|
- if (option.AutoClock) set_bit_time_span = -1;
|
|
|
- if (ParseSingleData(set_bit_time_span))
|
|
|
- {
|
|
|
- result = {};
|
|
|
- result.DecodeEventsPtr = resultEvents.data();
|
|
|
- result.DecodeResultCellsPtr = resultCells.data();
|
|
|
- result.DecodeEventCount = resultEvents.size();
|
|
|
- result.DecodeResultCount = resultCells.size();
|
|
|
- result.DecodeResultNeedUpdate = !resultCells.empty();
|
|
|
- result.DecodeEventNeedUpdate = !resultEvents.empty();
|
|
|
-
|
|
|
- // WriteLog(LogLevel::LevelDebug, "Offset 1: %d" , offsetof(UsbDecodeEvent, PacketTitle));
|
|
|
- // WriteLog(LogLevel::LevelDebug, "Offset 2: %d" , offsetof(UsbDecodeEvent, FrameId));
|
|
|
- // WriteLog(LogLevel::LevelDebug, "Offset 2.5: %d" , offsetof(UsbDecodeEvent, EndPoint));
|
|
|
- // WriteLog(LogLevel::LevelDebug, "Offset 3: %d" , offsetof(UsbDecodeEvent, CrcSignNum));
|
|
|
- // WriteLog(LogLevel::LevelDebug, "Offset 3.5: %d" , offsetof(UsbDecodeEvent, CrcData));
|
|
|
- // WriteLog(LogLevel::LevelDebug, "Offset 4: %d" , offsetof(UsbDecodeEvent, DataCount));
|
|
|
- // WriteLog(LogLevel::LevelDebug, "Offset 5: %d" , offsetof(UsbDecodeEvent, DecodeDatasPtr));
|
|
|
- return true;
|
|
|
- }
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
- bool USBDecoder::ParseSingleData(double set_bit_time_span)
|
|
|
- {
|
|
|
- if (signEdgePulse.empty()) return false;
|
|
|
- WriteLog(LogLevel::Level2, "ParseSingleData start");
|
|
|
-
|
|
|
- // 检查是否取消
|
|
|
- if (canceled)
|
|
|
- {
|
|
|
- WriteLog(LogLevel::Level2, "AsyncFunction canceled");
|
|
|
- return false;
|
|
|
- }
|
|
|
- int32_t left_data_size = static_cast<int32_t>(signEdgePulse.size());
|
|
|
- //找数据包
|
|
|
- if (FindPackets(left_data_size, usbPackets, set_bit_time_span))
|
|
|
- {
|
|
|
- if (usbPackets.empty())
|
|
|
- {
|
|
|
- WriteLog(LogLevel::Level2, "ParseSingleData false - usbPackets is empty");
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
- for (auto&& element : usbPackets)
|
|
|
- {
|
|
|
- //resultData.Add(new UsbDecodeResultCell(element));
|
|
|
- resultEvents.emplace_back(element);
|
|
|
- resultEvents[resultEvents.size() - 1].EventIndex = static_cast<int64_t>(resultEvents.size());
|
|
|
- }
|
|
|
- }
|
|
|
- WriteLog(LogLevel::Level2, "ParseSingleData done");
|
|
|
- return true;
|
|
|
- }
|
|
|
-
|
|
|
- bool USBDecoder::CheckTimeDifferenceWithinThreshold(const double* array, int32_t size, double threshold)
|
|
|
- {
|
|
|
- //threshold = 0.15;
|
|
|
- for (int i = 2; i < size; i++)
|
|
|
- {
|
|
|
- double difference = std::abs(array[i] - array[i - 1]);
|
|
|
- double percentage_difference = difference / array[i - 1];
|
|
|
- if (difference < 50)
|
|
|
- {
|
|
|
- threshold = USB_TIME_DIFFERENCE_THRESHOLD;
|
|
|
- }
|
|
|
- if (percentage_difference > threshold)
|
|
|
- {
|
|
|
- return false; // 如果差异大于阈值,则返回 false
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- return true; // 所有元素之间的差异都小于阈值
|
|
|
- }
|
|
|
-
|
|
|
- void USBDecoder::ClearEdgeArray(Protocol::Edge* edges, int32_t size)
|
|
|
- {
|
|
|
- for (int i = 0; i < size; ++i)
|
|
|
- {
|
|
|
- edges[i] = Protocol::Edge::None;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- //检查同步域边沿
|
|
|
- bool USBDecoder::CheckSyncEdges(Protocol::Edge start_edge, const Protocol::Edge* edges)
|
|
|
- {
|
|
|
- return edges[0] != edges[1] && edges[0] == start_edge && edges[0] == edges[6];
|
|
|
- }
|
|
|
-
|
|
|
- //检查同步域在时域间隔
|
|
|
- bool USBDecoder::CheckSyncSpans(const Protocol::TwoLevelEdgePulse* node, const int32_t count, int32_t& avg_spans)
|
|
|
- {
|
|
|
- if (count < 1)
|
|
|
- {
|
|
|
- return false;
|
|
|
- }
|
|
|
- auto start_indexs = new int32_t[count + 1];
|
|
|
- avg_spans = 0;
|
|
|
- if ((node - 1) != nullptr)
|
|
|
- {
|
|
|
- node--;
|
|
|
- }
|
|
|
-
|
|
|
- for (int i = count - 1; i >= 0; i--)
|
|
|
- {
|
|
|
- node--;
|
|
|
- if (node == nullptr)
|
|
|
- {
|
|
|
- return false;
|
|
|
- }
|
|
|
- start_indexs[i] = node->StartIndex;
|
|
|
- }
|
|
|
- return CheckSyncSpansByArray(start_indexs, count, avg_spans);
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- bool USBDecoder::CheckSyncSpansByArray(const int32_t* start_indexs, const int32_t count,
|
|
|
- int32_t& avg_spans)
|
|
|
- {
|
|
|
- if (count < 1)
|
|
|
- {
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
- auto tmp_spans = new double[count - 1];
|
|
|
- for (int i = 1; i < count; i++)
|
|
|
- {
|
|
|
- tmp_spans[i - 1] = static_cast<double>(start_indexs[i] - start_indexs[i - 1]);
|
|
|
- }
|
|
|
-
|
|
|
- double total_spans = 0;
|
|
|
- for (int i = 0; i < count - 1; i++)
|
|
|
- {
|
|
|
- total_spans += std::abs(tmp_spans[2 + (i / 2)]);
|
|
|
- }
|
|
|
- avg_spans = static_cast<int>(total_spans / (count - 1));
|
|
|
- return CheckTimeDifferenceWithinThreshold(tmp_spans, count - 1);
|
|
|
- }
|
|
|
-
|
|
|
- bool USBDecoder::FindAllSyncs(Protocol::TwoLevelEdgePulse* node, std::vector<SYNC>& all_sync
|
|
|
- , double set_bit_time_span, bool polarity)
|
|
|
- {
|
|
|
- all_sync.clear();
|
|
|
- int first_avg_span = 0;
|
|
|
-
|
|
|
- if (node == nullptr || node - 1 == nullptr)
|
|
|
- {
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
- constexpr int sync_bit_len = 8;
|
|
|
- Edge next_edge = polarity ? Protocol::Edge::Rise : Protocol::Edge::Falling;
|
|
|
- Edge start_edge = next_edge;
|
|
|
-
|
|
|
- TwoLevelEdgePulse* start_info_node = nullptr;
|
|
|
- Edge tmp_edges[sync_bit_len];
|
|
|
- TwoLevelEdgePulse* tmp_edges_ptr[sync_bit_len];
|
|
|
- int32_t tmp_edges_len[sync_bit_len];
|
|
|
- ClearEdgeArray(tmp_edges, sync_bit_len);
|
|
|
-
|
|
|
- int tmp_edge_count = 0;
|
|
|
- Protocol::TwoLevelEdgePulse* tmp_node = node;
|
|
|
-
|
|
|
- while (tmp_node != nullptr)
|
|
|
- {
|
|
|
- if (canceled)
|
|
|
- {
|
|
|
- WriteLog(LogLevel::Level2, "AsyncFunction canceled");
|
|
|
- return false;
|
|
|
- }
|
|
|
- if (tmp_node->StartIndex < 0 || tmp_node->EndIndex < 0
|
|
|
- || tmp_node->StartIndex > tmp_node->EndIndex || tmp_node->LevelCount() <= 0)
|
|
|
- {
|
|
|
- WriteLog(LogLevel::Level2, "FindAllSyncs break,SYNC count:%d", all_sync.size());
|
|
|
- break;
|
|
|
- }
|
|
|
- //可能找到目标头
|
|
|
- if (first_avg_span != 0 && tmp_node->GetLength() > first_avg_span * 8)
|
|
|
- {
|
|
|
- tmp_edge_count = 0;
|
|
|
- }
|
|
|
-
|
|
|
- if (tmp_edge_count <= 7)
|
|
|
- {
|
|
|
- if (tmp_edge_count == 0)
|
|
|
- {
|
|
|
- start_info_node = tmp_node;
|
|
|
- }
|
|
|
-
|
|
|
- tmp_edges[tmp_edge_count] = tmp_node->Edge;
|
|
|
- tmp_edges_ptr[tmp_edge_count] = tmp_node;
|
|
|
- tmp_edges_len[tmp_edge_count] = tmp_node->GetLength();
|
|
|
- tmp_edge_count++;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- if (CheckSyncEdges(start_edge, tmp_edges))
|
|
|
- {
|
|
|
- int avg_spans;
|
|
|
- if (CheckSyncSpans(tmp_node, sync_bit_len - 1, avg_spans))
|
|
|
- {
|
|
|
- if (all_sync.empty())
|
|
|
- {
|
|
|
- int32_t set_bit_span = static_cast<int>(set_bit_time_span);
|
|
|
-
|
|
|
- first_avg_span = set_bit_span >= 0 ? set_bit_span : avg_spans;
|
|
|
- all_sync.emplace_back(start_info_node, (tmp_node - 2)->StartIndex + first_avg_span,
|
|
|
- first_avg_span);
|
|
|
- }
|
|
|
- else if (start_info_node != nullptr && (start_info_node - 1) != nullptr && (start_info_node - 1)->
|
|
|
- GetLength() > first_avg_span * 8)
|
|
|
- {
|
|
|
- int32_t set_bit_span = static_cast<int>(set_bit_time_span);
|
|
|
- avg_spans = set_bit_span >= 0 ? set_bit_span : avg_spans;
|
|
|
- all_sync.emplace_back(start_info_node, (tmp_node - 2)->StartIndex + avg_spans,
|
|
|
- avg_spans);
|
|
|
- }
|
|
|
-
|
|
|
- ClearEdgeArray(tmp_edges, sync_bit_len);
|
|
|
- tmp_edge_count = 0;
|
|
|
- tmp_node++;
|
|
|
- //left_over_size--;
|
|
|
- continue;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- for (int i = 0; i < sync_bit_len - 1; i++)
|
|
|
- {
|
|
|
- tmp_edges[i] = tmp_edges[i + 1];
|
|
|
- tmp_edges_ptr[i] = tmp_edges_ptr[i + 1];
|
|
|
- tmp_edges_len[i] = tmp_edges_len[i + 1];
|
|
|
- }
|
|
|
-
|
|
|
- tmp_edges[sync_bit_len - 1] = tmp_node->Edge;
|
|
|
- tmp_edges_ptr[sync_bit_len - 1] = tmp_node;
|
|
|
- tmp_edges_len[sync_bit_len - 1] = tmp_node->GetLength();
|
|
|
- start_info_node++;
|
|
|
- }
|
|
|
-
|
|
|
- tmp_node++;
|
|
|
- //left_over_size--;
|
|
|
- }
|
|
|
-
|
|
|
- return !all_sync.empty();
|
|
|
- }
|
|
|
-
|
|
|
- bool USBDecoder::FindPackets(int32_t& left_over_size,
|
|
|
- std::vector<USBPacket>& all_packet, double set_bit_time_span,
|
|
|
- bool polarity)
|
|
|
- {
|
|
|
- Protocol::TwoLevelEdgePulse* node = signEdgePulse.data();
|
|
|
- all_packet.clear();
|
|
|
- std::vector<SYNC> all_sync;
|
|
|
- //找的全部同步帧
|
|
|
- if (!FindAllSyncs(node, all_sync, set_bit_time_span, polarity) || all_sync.empty())
|
|
|
- {
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
- for (const auto& sync : all_sync)
|
|
|
- {
|
|
|
- if (sync.NodePtr == nullptr)
|
|
|
- {
|
|
|
- continue;
|
|
|
- }
|
|
|
- if (canceled)
|
|
|
- {
|
|
|
- WriteLog(LogLevel::Level2, "AsyncFunction canceled");
|
|
|
- return false;
|
|
|
- }
|
|
|
- Protocol::TwoLevelEdgePulse* tmp_node = sync.NodePtr;
|
|
|
-
|
|
|
- int32_t eop_index = -1;
|
|
|
- //有差分Eop情况
|
|
|
- if (!differenceEopIndexs.empty() && differenceEopIndexs.size() > all_packet.size())
|
|
|
- {
|
|
|
- eop_index = differenceEopIndexs[all_packet.size()];
|
|
|
- }
|
|
|
- if (eop_index <= 0)
|
|
|
- {
|
|
|
- //如果存在后续同步帧,用下个同步帧头-1的起始做可能结束
|
|
|
- if (static_cast<int32_t>(all_sync.size()) > (all_packet.size() + 2))
|
|
|
- {
|
|
|
- eop_index = (all_sync[all_packet.size() + 2].NodePtr - 1)->StartIndex;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- eop_index = waveMaxTimeIndexLen;
|
|
|
- }
|
|
|
- }
|
|
|
- int32_t packetMaxTimeLen = eop_index - sync.NodePtr->StartIndex;
|
|
|
- if (packetMaxTimeLen <= 0)
|
|
|
- {
|
|
|
- WriteLog(LogLevel::Level2, "FindPackets Warning: packetMaxTimeLen <= 0");
|
|
|
- }
|
|
|
- USBPacket packet(tmp_node, left_over_size, sync, polarity, packetMaxTimeLen);
|
|
|
- if (packet.IsValid())
|
|
|
- {
|
|
|
- all_packet.push_back(packet);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- return true;
|
|
|
- }
|
|
|
- bool USBDecoder::CheckOptions(UsbDecodeOptions option, const std::vector<Protocol::TwoLevelEdgePulse>& edge_pulses_dp,
|
|
|
- const std::vector<Protocol::TwoLevelEdgePulse>& edge_pulses_dm, double& set_bit_time_span)
|
|
|
- {
|
|
|
- double usb_speed = 0;
|
|
|
- switch (option.USBSpeed)
|
|
|
- {
|
|
|
- case USBEnums::USBSpeed::LOW_SPEED:
|
|
|
- usb_speed = USB_LOW_SPEED_MHZ;
|
|
|
- break;
|
|
|
- case USBEnums::USBSpeed::FULL_SPEED:
|
|
|
- usb_speed = USB_FULL_SPEED_MHZ;
|
|
|
- break;
|
|
|
- case USBEnums::USBSpeed::HIGH_SPEED:
|
|
|
- usb_speed = USB_HIGH_SPEED_MHZ;
|
|
|
- break;
|
|
|
- default:
|
|
|
- WriteLog(LogLevel::Level2, "CheckOptions Failed, usbSpeed error");
|
|
|
- return false;
|
|
|
- }
|
|
|
- if (!option.AutoClock && option.SamplingFrequency < usb_speed * 2)
|
|
|
- {
|
|
|
- WriteLog(LogLevel::Level2, "CheckOptions Failed, samplingFrequency error");
|
|
|
- return false;
|
|
|
- }
|
|
|
- if (option.SignType == SignType::SingleEnded)
|
|
|
- {
|
|
|
- WriteLog(LogLevel::Level2, "CheckOptions SignType:%d", static_cast<int>(option.SignType));
|
|
|
- if (edge_pulses_dp.size() < USB_MINIMUM_SEQUENCE_LENGTH && edge_pulses_dm.size() < USB_MINIMUM_SEQUENCE_LENGTH)
|
|
|
- {
|
|
|
- WriteLog(LogLevel::Level2, "CheckOptions Failed, edgePulses.size too short");
|
|
|
- return false;
|
|
|
- }
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- auto edgePulsesSize1 = static_cast<double>(edge_pulses_dp.size());
|
|
|
- auto edgePulsesSize2 = static_cast<double>(edge_pulses_dm.size());
|
|
|
- //// 差分长度判断
|
|
|
- if (!DataCheckHelper::CheckDoubleIsEqual(edgePulsesSize1, edgePulsesSize2)
|
|
|
- && ((USB_DIFF_LEN_DIFFERENCE_THRESHOLD * edgePulsesSize1) > edgePulsesSize2
|
|
|
- || (USB_DIFF_LEN_DIFFERENCE_THRESHOLD * edgePulsesSize2) > edgePulsesSize1))
|
|
|
- {
|
|
|
- WriteLog(LogLevel::Level2, "CheckOptions Failed,diff edgePulses size is not equal");
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
- if (edge_pulses_dp.size() < USB_MINIMUM_SEQUENCE_LENGTH)
|
|
|
- {
|
|
|
- WriteLog(LogLevel::Level2, "CheckOptions Failed, edgePulses size too short");
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
- usbDiffSignalRealEdgesCount = static_cast<int32_t>(edge_pulses_dp.size() > edge_pulses_dm.size()
|
|
|
- ? edge_pulses_dm.size()
|
|
|
- : edge_pulses_dp.size());
|
|
|
- }
|
|
|
- set_bit_time_span = option.SamplingFrequency / usb_speed;
|
|
|
- return true;
|
|
|
- }
|
|
|
+ std::vector<std::string> USBDecoder::EventInfoTitles()
|
|
|
+ {
|
|
|
+ return { "Index", "Start Time", "Sync", "PID", "Data", "Addr", "FNUM", "CRC5", "CRC16", "EOP", "Error" };
|
|
|
+ }
|
|
|
+
|
|
|
+ //主解码函数入口
|
|
|
+ bool USBDecoder::DecodeUSB(const UsbDecodeOptions& option, const EdgePulseDataTwoLevels& edge_pulses_dp,
|
|
|
+ const EdgePulseDataTwoLevels& edge_pulses_dm, UsbDecodeResult& result)
|
|
|
+ {
|
|
|
+ std::vector<Protocol::TwoLevelEdgePulse> edge_pulses1 = {};
|
|
|
+
|
|
|
+ if (&edge_pulses_dp != NULL && edge_pulses_dp.WaveformDataCount > 0)
|
|
|
+ {
|
|
|
+ edge_pulses1 =
|
|
|
+ CommonHelper::ConvertPointerArrayToVector<Protocol::TwoLevelEdgePulse>(
|
|
|
+ edge_pulses_dp.GetDataAddrPtr(), edge_pulses_dp.EdgePulsesCount);
|
|
|
+ }
|
|
|
+ std::vector<Protocol::TwoLevelEdgePulse> edge_pulses2 = {};
|
|
|
+ if (&edge_pulses_dm != NULL && edge_pulses_dm.WaveformDataCount > 0)
|
|
|
+ {
|
|
|
+ edge_pulses2 = CommonHelper::ConvertPointerArrayToVector<Protocol::TwoLevelEdgePulse>(
|
|
|
+ edge_pulses_dm.GetDataAddrPtr(), edge_pulses_dm.EdgePulsesCount);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ differenceEopIndexs = {};
|
|
|
+ double set_bit_time_span = 0;
|
|
|
+ //////参数判断
|
|
|
+ if (!CheckOptions(option, edge_pulses1, edge_pulses2, set_bit_time_span))
|
|
|
+ {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ resultCells = {};
|
|
|
+ resultEvents = {};
|
|
|
+ usbDiffUnalignedFramesIndex = {};
|
|
|
+
|
|
|
+ //////处理差分逻辑
|
|
|
+ if (option.SignType == SignType::Diff)
|
|
|
+ {
|
|
|
+ if (!ParseDiffSignalData(edge_pulses1, edge_pulses2))
|
|
|
+ {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ if (edge_pulses1.size() < edge_pulses2.size())
|
|
|
+ {
|
|
|
+ signEdgePulse = std::move(edge_pulses2);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ signEdgePulse = std::move(edge_pulses1);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ waveMaxTimeIndexLen = signEdgePulse[signEdgePulse.size() - 1].EndIndex;
|
|
|
+ //////处理单端逻辑
|
|
|
+ if (option.AutoClock) set_bit_time_span = -1;
|
|
|
+ if (ParseSingleData(set_bit_time_span))
|
|
|
+ {
|
|
|
+ result = {};
|
|
|
+ result.DecodeEventsPtr = resultEvents.data();
|
|
|
+ result.DecodeResultCellsPtr = resultCells.data();
|
|
|
+ result.DecodeEventCount = resultEvents.size();
|
|
|
+ result.DecodeResultCount = resultCells.size();
|
|
|
+ result.DecodeResultNeedUpdate = !resultCells.empty();
|
|
|
+ result.DecodeEventNeedUpdate = !resultEvents.empty();
|
|
|
+
|
|
|
+ // WriteLog(LogLevel::LevelDebug, "Offset 1: %d" , offsetof(UsbDecodeEvent, PacketTitle));
|
|
|
+ // WriteLog(LogLevel::LevelDebug, "Offset 2: %d" , offsetof(UsbDecodeEvent, FrameId));
|
|
|
+ // WriteLog(LogLevel::LevelDebug, "Offset 2.5: %d" , offsetof(UsbDecodeEvent, EndPoint));
|
|
|
+ // WriteLog(LogLevel::LevelDebug, "Offset 3: %d" , offsetof(UsbDecodeEvent, CrcSignNum));
|
|
|
+ // WriteLog(LogLevel::LevelDebug, "Offset 3.5: %d" , offsetof(UsbDecodeEvent, CrcData));
|
|
|
+ // WriteLog(LogLevel::LevelDebug, "Offset 4: %d" , offsetof(UsbDecodeEvent, DataCount));
|
|
|
+ // WriteLog(LogLevel::LevelDebug, "Offset 5: %d" , offsetof(UsbDecodeEvent, DecodeDatasPtr));
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ bool USBDecoder::ParseSingleData(double set_bit_time_span)
|
|
|
+ {
|
|
|
+ if (signEdgePulse.empty()) return false;
|
|
|
+ WriteLog(LogLevel::Level2, "ParseSingleData start");
|
|
|
+
|
|
|
+ // 检查是否取消
|
|
|
+ if (canceled)
|
|
|
+ {
|
|
|
+ WriteLog(LogLevel::Level2, "AsyncFunction canceled");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ int32_t left_data_size = static_cast<int32_t>(signEdgePulse.size());
|
|
|
+ //找数据包
|
|
|
+ if (FindPackets(left_data_size, usbPackets, set_bit_time_span))
|
|
|
+ {
|
|
|
+ if (usbPackets.empty())
|
|
|
+ {
|
|
|
+ WriteLog(LogLevel::Level2, "ParseSingleData false - usbPackets is empty");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ for (auto&& element : usbPackets)
|
|
|
+ {
|
|
|
+ //resultData.Add(new UsbDecodeResultCell(element));
|
|
|
+ resultEvents.emplace_back(element);
|
|
|
+ resultEvents[resultEvents.size() - 1].EventIndex = static_cast<int64_t>(resultEvents.size());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ WriteLog(LogLevel::Level2, "ParseSingleData done");
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ bool USBDecoder::CheckTimeDifferenceWithinThreshold(const double* array, int32_t size, double threshold)
|
|
|
+ {
|
|
|
+ //threshold = 0.15;
|
|
|
+ for (int i = 2; i < size; i++)
|
|
|
+ {
|
|
|
+ double difference = std::abs(array[i] - array[i - 1]);
|
|
|
+ double percentage_difference = difference / array[i - 1];
|
|
|
+ if (difference < 50)
|
|
|
+ {
|
|
|
+ threshold = USB_TIME_DIFFERENCE_THRESHOLD;
|
|
|
+ }
|
|
|
+ if (percentage_difference > threshold)
|
|
|
+ {
|
|
|
+ return false; // 如果差异大于阈值,则返回 false
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return true; // 所有元素之间的差异都小于阈值
|
|
|
+ }
|
|
|
+
|
|
|
+ void USBDecoder::ClearEdgeArray(Protocol::Edge* edges, int32_t size)
|
|
|
+ {
|
|
|
+ for (int i = 0; i < size; ++i)
|
|
|
+ {
|
|
|
+ edges[i] = Protocol::Edge::None;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //检查同步域边沿
|
|
|
+ bool USBDecoder::CheckSyncEdges(Protocol::Edge start_edge, const Protocol::Edge* edges)
|
|
|
+ {
|
|
|
+ return edges[0] != edges[1] && edges[0] == start_edge && edges[0] == edges[6];
|
|
|
+ }
|
|
|
+
|
|
|
+ //检查同步域在时域间隔
|
|
|
+ bool USBDecoder::CheckSyncSpans(const Protocol::TwoLevelEdgePulse* node, const int32_t count, int32_t& avg_spans)
|
|
|
+ {
|
|
|
+ if (count < 1)
|
|
|
+ {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ auto start_indexs = new int32_t[count + 1];
|
|
|
+ avg_spans = 0;
|
|
|
+ if ((node - 1) != nullptr)
|
|
|
+ {
|
|
|
+ node--;
|
|
|
+ }
|
|
|
+
|
|
|
+ for (int i = count - 1; i >= 0; i--)
|
|
|
+ {
|
|
|
+ node--;
|
|
|
+ if (node == nullptr)
|
|
|
+ {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ start_indexs[i] = node->StartIndex;
|
|
|
+ }
|
|
|
+ return CheckSyncSpansByArray(start_indexs, count, avg_spans);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ bool USBDecoder::CheckSyncSpansByArray(const int32_t* start_indexs, const int32_t count,
|
|
|
+ int32_t& avg_spans)
|
|
|
+ {
|
|
|
+ if (count < 1)
|
|
|
+ {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ auto tmp_spans = new double[count - 1];
|
|
|
+ for (int i = 1; i < count; i++)
|
|
|
+ {
|
|
|
+ tmp_spans[i - 1] = static_cast<double>(start_indexs[i] - start_indexs[i - 1]);
|
|
|
+ }
|
|
|
+
|
|
|
+ double total_spans = 0;
|
|
|
+ for (int i = 0; i < count - 1; i++)
|
|
|
+ {
|
|
|
+ total_spans += std::abs(tmp_spans[2 + (i / 2)]);
|
|
|
+ }
|
|
|
+ avg_spans = static_cast<int>(total_spans / (count - 1));
|
|
|
+ return CheckTimeDifferenceWithinThreshold(tmp_spans, count - 1);
|
|
|
+ }
|
|
|
+
|
|
|
+ bool USBDecoder::FindAllSyncs(Protocol::TwoLevelEdgePulse* node, std::vector<SYNC>& all_sync
|
|
|
+ , double set_bit_time_span, bool polarity)
|
|
|
+ {
|
|
|
+ all_sync.clear();
|
|
|
+ int first_avg_span = 0;
|
|
|
+
|
|
|
+ if (node == nullptr || node - 1 == nullptr)
|
|
|
+ {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ constexpr int sync_bit_len = 8;
|
|
|
+ Edge next_edge = polarity ? Protocol::Edge::Rise : Protocol::Edge::Falling;
|
|
|
+ Edge start_edge = next_edge;
|
|
|
+
|
|
|
+ TwoLevelEdgePulse* start_info_node = nullptr;
|
|
|
+ Edge tmp_edges[sync_bit_len];
|
|
|
+ TwoLevelEdgePulse* tmp_edges_ptr[sync_bit_len];
|
|
|
+ int32_t tmp_edges_len[sync_bit_len];
|
|
|
+ ClearEdgeArray(tmp_edges, sync_bit_len);
|
|
|
+
|
|
|
+ int tmp_edge_count = 0;
|
|
|
+ Protocol::TwoLevelEdgePulse* tmp_node = node;
|
|
|
+
|
|
|
+ while (tmp_node != nullptr)
|
|
|
+ {
|
|
|
+ if (canceled)
|
|
|
+ {
|
|
|
+ WriteLog(LogLevel::Level2, "AsyncFunction canceled");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if (tmp_node->StartIndex < 0 || tmp_node->EndIndex < 0
|
|
|
+ || tmp_node->StartIndex > tmp_node->EndIndex || tmp_node->LevelCount() <= 0)
|
|
|
+ {
|
|
|
+ WriteLog(LogLevel::Level2, "FindAllSyncs break,SYNC count:%d", all_sync.size());
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ //可能找到目标头
|
|
|
+ if (first_avg_span != 0 && tmp_node->GetLength() > first_avg_span * 8)
|
|
|
+ {
|
|
|
+ tmp_edge_count = 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (tmp_edge_count <= 7)
|
|
|
+ {
|
|
|
+ if (tmp_edge_count == 0)
|
|
|
+ {
|
|
|
+ start_info_node = tmp_node;
|
|
|
+ }
|
|
|
+
|
|
|
+ tmp_edges[tmp_edge_count] = tmp_node->Edge;
|
|
|
+ tmp_edges_ptr[tmp_edge_count] = tmp_node;
|
|
|
+ tmp_edges_len[tmp_edge_count] = tmp_node->GetLength();
|
|
|
+ tmp_edge_count++;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ if (CheckSyncEdges(start_edge, tmp_edges))
|
|
|
+ {
|
|
|
+ int avg_spans;
|
|
|
+ if (CheckSyncSpans(tmp_node, sync_bit_len - 1, avg_spans))
|
|
|
+ {
|
|
|
+ if (all_sync.empty())
|
|
|
+ {
|
|
|
+ int32_t set_bit_span = static_cast<int>(set_bit_time_span);
|
|
|
+
|
|
|
+ first_avg_span = set_bit_span >= 0 ? set_bit_span : avg_spans;
|
|
|
+ all_sync.emplace_back(start_info_node, (tmp_node - 2)->StartIndex + first_avg_span,
|
|
|
+ first_avg_span);
|
|
|
+ }
|
|
|
+ else if (start_info_node != nullptr && (start_info_node - 1) != nullptr && (start_info_node - 1)->
|
|
|
+ GetLength() > first_avg_span * 8)
|
|
|
+ {
|
|
|
+ int32_t set_bit_span = static_cast<int>(set_bit_time_span);
|
|
|
+ avg_spans = set_bit_span >= 0 ? set_bit_span : avg_spans;
|
|
|
+ all_sync.emplace_back(start_info_node, (tmp_node - 2)->StartIndex + avg_spans,
|
|
|
+ avg_spans);
|
|
|
+ }
|
|
|
+
|
|
|
+ ClearEdgeArray(tmp_edges, sync_bit_len);
|
|
|
+ tmp_edge_count = 0;
|
|
|
+ tmp_node++;
|
|
|
+ //left_over_size--;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ for (int i = 0; i < sync_bit_len - 1; i++)
|
|
|
+ {
|
|
|
+ tmp_edges[i] = tmp_edges[i + 1];
|
|
|
+ tmp_edges_ptr[i] = tmp_edges_ptr[i + 1];
|
|
|
+ tmp_edges_len[i] = tmp_edges_len[i + 1];
|
|
|
+ }
|
|
|
+
|
|
|
+ tmp_edges[sync_bit_len - 1] = tmp_node->Edge;
|
|
|
+ tmp_edges_ptr[sync_bit_len - 1] = tmp_node;
|
|
|
+ tmp_edges_len[sync_bit_len - 1] = tmp_node->GetLength();
|
|
|
+ start_info_node++;
|
|
|
+ }
|
|
|
+
|
|
|
+ tmp_node++;
|
|
|
+ //left_over_size--;
|
|
|
+ }
|
|
|
+
|
|
|
+ return !all_sync.empty();
|
|
|
+ }
|
|
|
+
|
|
|
+ bool USBDecoder::FindPackets(int32_t& left_over_size,
|
|
|
+ std::vector<USBPacket>& all_packet, double set_bit_time_span,
|
|
|
+ bool polarity)
|
|
|
+ {
|
|
|
+ Protocol::TwoLevelEdgePulse* node = signEdgePulse.data();
|
|
|
+ all_packet.clear();
|
|
|
+ std::vector<SYNC> all_sync;
|
|
|
+ //找的全部同步帧
|
|
|
+ if (!FindAllSyncs(node, all_sync, set_bit_time_span, polarity) || all_sync.empty())
|
|
|
+ {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ for (const auto& sync : all_sync)
|
|
|
+ {
|
|
|
+ if (sync.NodePtr == nullptr)
|
|
|
+ {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ if (canceled)
|
|
|
+ {
|
|
|
+ WriteLog(LogLevel::Level2, "AsyncFunction canceled");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ Protocol::TwoLevelEdgePulse* tmp_node = sync.NodePtr;
|
|
|
+
|
|
|
+ int32_t eop_index = -1;
|
|
|
+ //有差分Eop情况
|
|
|
+ if (!differenceEopIndexs.empty() && differenceEopIndexs.size() > all_packet.size())
|
|
|
+ {
|
|
|
+ eop_index = differenceEopIndexs[all_packet.size()];
|
|
|
+ }
|
|
|
+ if (eop_index <= 0)
|
|
|
+ {
|
|
|
+ //如果存在后续同步帧,用下个同步帧头-1的起始做可能结束
|
|
|
+ if (static_cast<int32_t>(all_sync.size()) > (all_packet.size() + 2))
|
|
|
+ {
|
|
|
+ eop_index = (all_sync[all_packet.size() + 2].NodePtr - 1)->StartIndex;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ eop_index = waveMaxTimeIndexLen;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ int32_t packetMaxTimeLen = eop_index - sync.NodePtr->StartIndex;
|
|
|
+ if (packetMaxTimeLen <= 0)
|
|
|
+ {
|
|
|
+ WriteLog(LogLevel::Level2, "FindPackets Warning: packetMaxTimeLen <= 0");
|
|
|
+ }
|
|
|
+ USBPacket packet(tmp_node, left_over_size, sync, polarity, packetMaxTimeLen);
|
|
|
+ if (packet.IsValid())
|
|
|
+ {
|
|
|
+ all_packet.push_back(packet);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ bool USBDecoder::CheckOptions(UsbDecodeOptions option, const std::vector<Protocol::TwoLevelEdgePulse>& edge_pulses_dp,
|
|
|
+ const std::vector<Protocol::TwoLevelEdgePulse>& edge_pulses_dm, double& set_bit_time_span)
|
|
|
+ {
|
|
|
+ double usb_speed = 0;
|
|
|
+ switch (option.USBSpeed)
|
|
|
+ {
|
|
|
+ case USBEnums::USBSpeed::LOW_SPEED:
|
|
|
+ usb_speed = USB_LOW_SPEED_MHZ;
|
|
|
+ break;
|
|
|
+ case USBEnums::USBSpeed::FULL_SPEED:
|
|
|
+ usb_speed = USB_FULL_SPEED_MHZ;
|
|
|
+ break;
|
|
|
+ case USBEnums::USBSpeed::HIGH_SPEED:
|
|
|
+ usb_speed = USB_HIGH_SPEED_MHZ;
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ WriteLog(LogLevel::Level2, "CheckOptions Failed, usbSpeed error");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if (!option.AutoClock && option.SamplingFrequency < usb_speed * 2)
|
|
|
+ {
|
|
|
+ WriteLog(LogLevel::Level2, "CheckOptions Failed, samplingFrequency error");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if (option.SignType == SignType::SingleEnded)
|
|
|
+ {
|
|
|
+ WriteLog(LogLevel::Level2, "CheckOptions SignType:%d", static_cast<int>(option.SignType));
|
|
|
+ if (edge_pulses_dp.size() < USB_MINIMUM_SEQUENCE_LENGTH && edge_pulses_dm.size() < USB_MINIMUM_SEQUENCE_LENGTH)
|
|
|
+ {
|
|
|
+ WriteLog(LogLevel::Level2, "CheckOptions Failed, edgePulses.size too short");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ auto edgePulsesSize1 = static_cast<double>(edge_pulses_dp.size());
|
|
|
+ auto edgePulsesSize2 = static_cast<double>(edge_pulses_dm.size());
|
|
|
+ //// 差分长度判断
|
|
|
+ if (!DataCheckHelper::CheckDoubleIsEqual(edgePulsesSize1, edgePulsesSize2)
|
|
|
+ && ((USB_DIFF_LEN_DIFFERENCE_THRESHOLD * edgePulsesSize1) > edgePulsesSize2
|
|
|
+ || (USB_DIFF_LEN_DIFFERENCE_THRESHOLD * edgePulsesSize2) > edgePulsesSize1))
|
|
|
+ {
|
|
|
+ WriteLog(LogLevel::Level2, "CheckOptions Failed,diff edgePulses size is not equal");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (edge_pulses_dp.size() < USB_MINIMUM_SEQUENCE_LENGTH)
|
|
|
+ {
|
|
|
+ WriteLog(LogLevel::Level2, "CheckOptions Failed, edgePulses size too short");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ usbDiffSignalRealEdgesCount = static_cast<int32_t>(edge_pulses_dp.size() > edge_pulses_dm.size()
|
|
|
+ ? edge_pulses_dm.size()
|
|
|
+ : edge_pulses_dp.size());
|
|
|
+ }
|
|
|
+ set_bit_time_span = option.SamplingFrequency / usb_speed;
|
|
|
+ return true;
|
|
|
+ }
|
|
|
}
|