|
@@ -0,0 +1,324 @@
|
|
|
+// // ******************************************************************
|
|
|
+// // /\ /| @File USBDecode.cpp
|
|
|
+// // \ V/ @Brief
|
|
|
+// // | "") @Author lijinwen, ghz005@uni-trend.com.cn
|
|
|
+// // / | @Creation 2024-1-4
|
|
|
+// // / \\ @Modified 2024-1-15
|
|
|
+// // *(__\_\
|
|
|
+// // ******************************************************************
|
|
|
+
|
|
|
+#include "USBDecode.h"
|
|
|
+
|
|
|
+namespace Protocol
|
|
|
+{
|
|
|
+ double USBDecode::GetBitRateByPs() const
|
|
|
+ {
|
|
|
+ double result = 1.0;
|
|
|
+ switch (signalRate)
|
|
|
+ {
|
|
|
+ case Enums::SignalRate::LowRate:
|
|
|
+ result /= 1.5E6;
|
|
|
+ break;
|
|
|
+ case Enums::SignalRate::FullRate:
|
|
|
+ result /= 12E6;
|
|
|
+ break;
|
|
|
+ case Enums::SignalRate::HighRate:
|
|
|
+ result /= 480E6;
|
|
|
+ break;
|
|
|
+ default: break;
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ std::vector<std::string> USBDecode::EventInfoTitles() const
|
|
|
+ {
|
|
|
+ return {"Index", "Start Time", "Sync", "PID", "Data", "Addr", "FNUM", "CRC5", "CRC16", "EOP", "Error"};
|
|
|
+ }
|
|
|
+
|
|
|
+ Enums::SignalRate USBDecode::SignalRate() const
|
|
|
+ {
|
|
|
+ return signalRate;
|
|
|
+ }
|
|
|
+
|
|
|
+ void USBDecode::SetSignalRate(Enums::SignalRate value)
|
|
|
+ {
|
|
|
+ signalRate = value;
|
|
|
+ }
|
|
|
+
|
|
|
+ uint16_t USBDecode::ByteCount() const
|
|
|
+ {
|
|
|
+ return byteCount;
|
|
|
+ }
|
|
|
+
|
|
|
+ void USBDecode::SetByteCount(uint16_t value)
|
|
|
+ {
|
|
|
+ byteCount = value;
|
|
|
+ }
|
|
|
+
|
|
|
+ uint16_t USBDecode::MaxByteCount()
|
|
|
+ {
|
|
|
+ return 1023;
|
|
|
+ }
|
|
|
+
|
|
|
+ uint16_t USBDecode::MinByteCount()
|
|
|
+ {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ bool USBDecode::ParseData(std::vector<Protocol::TwoLevelEdgePulse> edgePluses,
|
|
|
+ std::promise<void>& cancellationSignal)
|
|
|
+ {
|
|
|
+ if (edgePluses.empty()) return false;
|
|
|
+ // 使用 std::future 来检测取消请求
|
|
|
+ std::future<void> cancellationFuture = cancellationSignal.get_future();
|
|
|
+
|
|
|
+ // 检查是否取消
|
|
|
+ if (cancellationFuture.wait_for(std::chrono::milliseconds(0)) == std::future_status::ready)
|
|
|
+ {
|
|
|
+ std::cout << "AsyncFunction canceled." << '\n';
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ int32_t leftdataSize = static_cast<int32_t>(edgePluses.size());
|
|
|
+ if (FindPackets(edgePluses.data(), leftdataSize, usbPackets, cancellationSignal))
|
|
|
+ {
|
|
|
+ if (usbPackets.empty())
|
|
|
+ {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ //resultData.ClearData();
|
|
|
+
|
|
|
+ //todo 事件总线和绘图对象 下沉后在这里构建事件总线和绘图序列 这里只做简单逻辑暂时,细节未实现
|
|
|
+ for (auto&& element : usbPackets)
|
|
|
+ {
|
|
|
+ resultData.Add(new UsbDecodeResultCell(element));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ bool USBDecode::CheckDifferenceWithinThreshold(double* array, int32_t size, double threshold)
|
|
|
+ {
|
|
|
+ //threshold = 0.15;
|
|
|
+ for (int i = 1; i < size; i++)
|
|
|
+ {
|
|
|
+ double difference = std::abs(array[i] - array[i - 1]);
|
|
|
+ double percentageDifference = difference / array[i - 1];
|
|
|
+ if (difference < 50)
|
|
|
+ {
|
|
|
+ threshold = 0.28;
|
|
|
+ }
|
|
|
+ if (percentageDifference > threshold)
|
|
|
+ {
|
|
|
+ return false; // 如果差异大于阈值,则返回 false
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return true; // 所有元素之间的差异都小于阈值
|
|
|
+ }
|
|
|
+
|
|
|
+ void USBDecode::ClearEdgeArray(Protocol::Edge* edges, int32_t size)
|
|
|
+ {
|
|
|
+ for (int i = 0; i < size; ++i)
|
|
|
+ {
|
|
|
+ edges[i] = Protocol::Edge::None;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ bool USBDecode::CheckSyncEdges(Protocol::Edge startEdge, Protocol::Edge* edges)
|
|
|
+ {
|
|
|
+ return edges[0] == edges[1] && edges[0] == startEdge && edges[0] == edges[6];
|
|
|
+ }
|
|
|
+
|
|
|
+ bool USBDecode::CheckSyncSpans(Protocol::TwoLevelEdgePulse* node, int32_t& leftOverSize
|
|
|
+ , const int32_t count, int32_t& avgSpans)
|
|
|
+ {
|
|
|
+ if (count < 1)
|
|
|
+ {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ auto startIndexs = new int32_t[count + 1];
|
|
|
+ avgSpans = 0;
|
|
|
+ if ((node - 1) != nullptr)
|
|
|
+ {
|
|
|
+ node--;
|
|
|
+ }
|
|
|
+
|
|
|
+ for (int i = count; i >= 0; i--)
|
|
|
+ {
|
|
|
+ if (node == nullptr)
|
|
|
+ {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ startIndexs[i] = node->StartIndex;
|
|
|
+ node--;
|
|
|
+ }
|
|
|
+ return CheckSyncSpansByArrary(startIndexs, count, avgSpans);
|
|
|
+ }
|
|
|
+
|
|
|
+ bool USBDecode::CheckSyncSpansByArrary(int32_t* startIndexs, const int32_t count,
|
|
|
+ int32_t& avgSpans)
|
|
|
+ {
|
|
|
+ if (count < 1)
|
|
|
+ {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ auto tmpSpans = new double[count - 1];
|
|
|
+ for (int i = 1; i < count; i++)
|
|
|
+ {
|
|
|
+ tmpSpans[i - 1] = (double)(startIndexs[i] - startIndexs[i - 1]);
|
|
|
+ }
|
|
|
+ double totalSpans = 0;
|
|
|
+ for (int i = 0; i < count - 1; i++)
|
|
|
+ {
|
|
|
+ totalSpans += std::abs(tmpSpans[0]);
|
|
|
+ }
|
|
|
+ avgSpans = (int)(totalSpans / (count - 1));
|
|
|
+ return CheckDifferenceWithinThreshold(tmpSpans, count - 1);
|
|
|
+ }
|
|
|
+
|
|
|
+ bool USBDecode::FindAllSyncs(Protocol::TwoLevelEdgePulse* node, int32_t& leftOverSize,
|
|
|
+ std::vector<SYNC>& allSYNC, std::promise<void>& cancellationSignal,
|
|
|
+ bool polarity)
|
|
|
+ {
|
|
|
+ // 使用 std::future 来检测取消请求
|
|
|
+ std::future<void> cancellationFuture = cancellationSignal.get_future();
|
|
|
+ allSYNC.clear();
|
|
|
+ int firstAvgSpan = 0;
|
|
|
+
|
|
|
+ if (node == nullptr || node - 1 == nullptr)
|
|
|
+ {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ const int syncBitLen = 8;
|
|
|
+ Protocol::Edge nextEdge = polarity ? Protocol::Edge::Rise : Protocol::Edge::Falling;
|
|
|
+ Protocol::Edge startEdge = nextEdge;
|
|
|
+
|
|
|
+ Protocol::TwoLevelEdgePulse* startInfoNode = nullptr;
|
|
|
+ Protocol::Edge tmpEdges[syncBitLen];
|
|
|
+ ClearEdgeArray(tmpEdges, syncBitLen);
|
|
|
+
|
|
|
+ int tmpEdgeCount = 0;
|
|
|
+ Protocol::TwoLevelEdgePulse* tmpNode = node;
|
|
|
+
|
|
|
+ while (tmpNode != nullptr)
|
|
|
+ {
|
|
|
+ if (cancellationFuture.wait_for(std::chrono::milliseconds(0)) == std::future_status::ready)
|
|
|
+ {
|
|
|
+ std::cout << "AsyncFunction canceled." << '\n';
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if (tmpEdgeCount <= 7)
|
|
|
+ {
|
|
|
+ if (tmpEdgeCount == 0)
|
|
|
+ {
|
|
|
+ startInfoNode = tmpNode;
|
|
|
+ }
|
|
|
+
|
|
|
+ tmpEdges[tmpEdgeCount] = tmpNode->Edge;
|
|
|
+ tmpEdgeCount++;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ if (CheckSyncEdges(startEdge, tmpEdges))
|
|
|
+ {
|
|
|
+ int avgSpans;
|
|
|
+ if (CheckSyncSpans(tmpNode, leftOverSize, syncBitLen - 1, avgSpans))
|
|
|
+ {
|
|
|
+ if (allSYNC.empty())
|
|
|
+ {
|
|
|
+ firstAvgSpan = avgSpans;
|
|
|
+ allSYNC.emplace_back(startInfoNode->StartIndex, (tmpNode - 1)->StartIndex,
|
|
|
+ avgSpans);
|
|
|
+ }
|
|
|
+ else if (startInfoNode != nullptr && (startInfoNode - 1) != nullptr && (startInfoNode - 1)->
|
|
|
+ GetLength() > firstAvgSpan * 8)
|
|
|
+ {
|
|
|
+ allSYNC.emplace_back(startInfoNode->StartIndex, (tmpNode - 1)->StartIndex,
|
|
|
+ avgSpans);
|
|
|
+ }
|
|
|
+
|
|
|
+ ClearEdgeArray(tmpEdges, syncBitLen);
|
|
|
+ tmpEdgeCount = 0;
|
|
|
+ tmpNode++;
|
|
|
+ leftOverSize--;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ for (int i = 0; i < syncBitLen - 1; i++)
|
|
|
+ {
|
|
|
+ tmpEdges[i] = tmpEdges[i + 1];
|
|
|
+ }
|
|
|
+
|
|
|
+ tmpEdges[syncBitLen - 1] = tmpNode->Edge;
|
|
|
+ startInfoNode++;
|
|
|
+ }
|
|
|
+
|
|
|
+ tmpNode++;
|
|
|
+ leftOverSize--;
|
|
|
+ }
|
|
|
+
|
|
|
+ return !allSYNC.empty();
|
|
|
+ }
|
|
|
+
|
|
|
+ bool USBDecode::FindPackets(Protocol::TwoLevelEdgePulse* node, int32_t& leftOverSize,
|
|
|
+ std::vector<USBPacket>& allPacket, std::promise<void>& cancellationSignal,
|
|
|
+ bool polarity)
|
|
|
+ {
|
|
|
+ // 使用 std::future 来检测取消请求
|
|
|
+ const std::future<void> cancellationFuture = cancellationSignal.get_future();
|
|
|
+ allPacket.clear();
|
|
|
+ std::vector<SYNC> allSYNC;
|
|
|
+ if (!FindAllSyncs(node, leftOverSize, allSYNC, cancellationSignal, polarity) || allSYNC.empty())
|
|
|
+ {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ Protocol::TwoLevelEdgePulse* tmpNode = node;
|
|
|
+ for (const auto& sync : allSYNC)
|
|
|
+ {
|
|
|
+ while (tmpNode != nullptr && tmpNode->StartIndex < sync.StartIndex)
|
|
|
+ {
|
|
|
+ if (cancellationFuture.wait_for(std::chrono::milliseconds(0)) == std::future_status::ready)
|
|
|
+ {
|
|
|
+ std::cout << "AsyncFunction canceled." << '\n';
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ tmpNode--;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (tmpNode == nullptr || tmpNode - 1 == nullptr)
|
|
|
+ {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (sync.StartIndex != tmpNode->StartIndex)
|
|
|
+ {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ while (sync.EndIndex > tmpNode->StartIndex && tmpNode != nullptr)
|
|
|
+ {
|
|
|
+ tmpNode++;
|
|
|
+ if (cancellationFuture.wait_for(std::chrono::milliseconds(0)) == std::future_status::ready)
|
|
|
+ {
|
|
|
+ std::cout << "AsyncFunction canceled." << '\n';
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (tmpNode != nullptr)
|
|
|
+ {
|
|
|
+ USBPacket packet(tmpNode, leftOverSize, sync, polarity);
|
|
|
+ if (packet.IsValid())
|
|
|
+ {
|
|
|
+ allPacket.push_back(packet);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+}
|