lijinwen 4 mesiacov pred
rodič
commit
848fdd73f4

+ 13 - 3
ProtocolDecoder.vcxproj

@@ -316,6 +316,11 @@
         <ClCompile Include="ProtocolRS232\RS232DecodeEvent.cpp"/>
         <ClCompile Include="ProtocolRS232\RS232DecodeResult.cpp"/>
         <ClCompile Include="ProtocolRS232\RS232Packet.cpp"/>
+        <ClCompile Include="ProtocolUSB\Constants.cpp" />
+        <ClCompile Include="ProtocolUSB\UsbDecodeEvent.cpp" />
+        <ClCompile Include="ProtocolUSB\USBDecodeModel.cpp" />
+        <ClCompile Include="ProtocolUSB\UsbDecodeResult.cpp" />
+        <ClCompile Include="ProtocolUSB\USBPacket.cpp" />
         <ClCompile Include="QuantizeParams.cpp"/>
     </ItemGroup>
     <ItemGroup>
@@ -342,11 +347,16 @@
         <ClInclude Include="ProtocolRS232\RS232DecodeEvent.h"/>
         <ClInclude Include="ProtocolRS232\RS232DecodeResult.h"/>
         <ClInclude Include="ProtocolRS232\RS232Packet.h"/>
+        <ClInclude Include="ProtocolUSB\Constants.h" />
+        <ClInclude Include="ProtocolUSB\ProtocolUSBEnums.h" />
+        <ClInclude Include="ProtocolUSB\SYNC.h" />
+        <ClInclude Include="ProtocolUSB\UsbDecodeEvent.h" />
+        <ClInclude Include="ProtocolUSB\USBDecodeModel.h" />
+        <ClInclude Include="ProtocolUSB\UsbDecodeOptions.h" />
+        <ClInclude Include="ProtocolUSB\UsbDecodeResult.h" />
+        <ClInclude Include="ProtocolUSB\USBPacket.h" />
         <ClInclude Include="QuantizeParams.h"/>
     </ItemGroup>
-    <ItemGroup>
-        <Folder Include="ProtocolUSB\"/>
-    </ItemGroup>
     <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets"/>
     <ImportGroup Label="ExtensionTargets">
     </ImportGroup>

+ 14 - 0
ProtocolUSB/Constants.cpp

@@ -0,0 +1,14 @@
+// // ******************************************************************
+// //       /\ /|       @File         Constants.cpp
+// //       \ V/        @Brief
+// //       | "")       @Author        lijinwen, ghz005@uni-trend.com.cn
+// //       /  |        @Creation      2024-1-4
+// //      /  \\        @Modified      2024-1-15
+// //    *(__\_\
+// // ******************************************************************
+
+#include "Constants.h"
+
+namespace Protocol
+{
+}

+ 17 - 0
ProtocolUSB/Constants.h

@@ -0,0 +1,17 @@
+// // ******************************************************************
+// //       /\ /|       @File         Constants.h
+// //       \ V/        @Brief
+// //       | "")       @Author        lijinwen, ghz005@uni-trend.com.cn
+// //       /  |        @Creation      2024-1-4
+// //      /  \\        @Modified      2024-1-15
+// //    *(__\_\
+// // ******************************************************************
+
+#pragma once
+namespace Protocol
+{
+    class Constants
+    {
+    public:
+    };
+}

+ 114 - 0
ProtocolUSB/ProtocolUSBEnums.h

@@ -0,0 +1,114 @@
+// // ******************************************************************
+// //       /\ /|       @File         ProtocolUSBEnums.h
+// //       \ V/        @Brief
+// //       | "")       @Author        lijinwen, ghz005@uni-trend.com.cn
+// //       /  |        @Creation      2024-1-3
+// //      /  \\        @Modified      2024-1-15
+// //    *(__\_\
+// // ******************************************************************
+
+#pragma once
+#include <cstdint>
+
+namespace Protocol
+{
+    class Enums
+    {
+    public:
+        enum class USBFieldType
+        {
+            NoDefine = 0,
+            SOP,
+            SYNC,
+            PID,
+            ADDR,
+            FRAME,
+            DATA,
+            CRC
+        };
+
+        enum class USBPacketType
+        {
+            NoDefine = 0,
+            Token,
+            Data,
+            HandShake,
+            Special,
+        };
+
+        enum class Condition
+        {
+            Sync,
+            Reset,
+            Pause,
+            Resume,
+            PackageEnd,
+            TokenPackage,
+            HandshakePackage,
+            DataPackage,
+            // Sof,
+            Special,
+            Error,
+        };
+
+        enum class SignalRate
+        {
+            LowRate,
+            FullRate,
+            HighRate,
+        };
+
+        enum class TokenPackageType : uint8_t
+        {
+            Out = 0b0001,
+            SOF = 0b0101,
+            IN = 0b1001,
+            SETUP = 0b1101,
+        };
+
+        enum class SpecialPacketType : uint8_t
+        {
+            // Pre = 0b1100,
+            Err = 0b1100,
+            Split = 0b1000,
+            Ping = 0b0100,
+            Remain = 0b000,
+        };
+
+        enum class HandshakePackageType : uint8_t
+        {
+            ACK = 0b0010,
+            NAK = 0b1010,
+            STALL = 0b1110,
+            Nyet = 0b0110,
+        };
+
+        enum class DataPackageType : uint8_t
+        {
+            Data0 = 0b0011,
+            Data1 = 0b1011,
+            Data2 = 0b0111,
+            MData = 0b1111,
+        };
+
+        enum class ErrorPackageType
+        {
+            PIDCRC,
+            CRC5,
+            CRC16,
+            BitFill,
+        };
+
+        enum class DataRelation
+        {
+            Lt,
+            Gt,
+            Lteq,
+            Gteq,
+            Eq,
+            Neq,
+            In,
+            Out,
+        };
+    };
+}

+ 52 - 0
ProtocolUSB/SYNC.h

@@ -0,0 +1,52 @@
+// // ******************************************************************
+// //       /\ /|       @File         SYNC.h
+// //       \ V/        @Brief
+// //       | "")       @Author        lijinwen, ghz005@uni-trend.com.cn
+// //       /  |        @Creation      2024-1-3
+// //      /  \\        @Modified      2024-1-15
+// //    *(__\_\
+// // ******************************************************************
+
+#pragma once
+namespace Protocol
+{
+    class SYNC
+    {
+    public:
+        int StartIndex;
+        int EndIndex;
+        int SingleBitTimingLength;
+        int OneByteTimingLength;
+
+        int Length() const
+        {
+            return EndIndex - StartIndex;
+        }
+
+        int PacketEndIndex() const
+        {
+            return packetEndIndex;
+        }
+
+        void SetPacketEndIndex(int value)
+        {
+            packetEndIndex = value;
+        }
+
+        SYNC()
+        {
+        }
+
+        SYNC(int startIndex, int endIndex, int singleBitTimingLength) :
+            StartIndex(startIndex),
+            EndIndex(endIndex),
+            SingleBitTimingLength(singleBitTimingLength),
+            OneByteTimingLength(singleBitTimingLength * 8),
+            packetEndIndex(0)
+        {
+        }
+
+    private:
+        int packetEndIndex;
+    };
+}

+ 324 - 0
ProtocolUSB/USBDecodeModel.cpp

@@ -0,0 +1,324 @@
+// // ******************************************************************
+// //       /\ /|       @File         USBDecodeModel.cpp
+// //       \ V/        @Brief
+// //       | "")       @Author        lijinwen, ghz005@uni-trend.com.cn
+// //       /  |        @Creation      2024-1-4
+// //      /  \\        @Modified      2024-1-15
+// //    *(__\_\
+// // ******************************************************************
+
+#include "USBDecodeModel.h"
+
+namespace Protocol
+{
+    double USBDecodeModel::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> USBDecodeModel::EventInfoTitles() const
+    {
+        return {"Index", "Start Time", "Sync", "PID", "Data", "Addr", "FNUM", "CRC5", "CRC16", "EOP", "Error"};
+    }
+
+    Enums::SignalRate USBDecodeModel::SignalRate() const
+    {
+        return signalRate;
+    }
+
+    void USBDecodeModel::SetSignalRate(Enums::SignalRate value)
+    {
+        signalRate = value;
+    }
+
+    uint16_t USBDecodeModel::ByteCount() const
+    {
+        return byteCount;
+    }
+
+    void USBDecodeModel::SetByteCount(uint16_t value)
+    {
+        byteCount = value;
+    }
+
+    uint16_t USBDecodeModel::MaxByteCount()
+    {
+        return 1023;
+    }
+
+    uint16_t USBDecodeModel::MinByteCount()
+    {
+        return 0;
+    }
+
+    bool USBDecodeModel::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 USBDecodeModel::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 USBDecodeModel::ClearEdgeArray(Protocol::Edge* edges, int32_t size)
+    {
+        for (int i = 0; i < size; ++i)
+        {
+            edges[i] = Protocol::Edge::None;
+        }
+    }
+
+    bool USBDecodeModel::CheckSyncEdges(Protocol::Edge startEdge, Protocol::Edge* edges)
+    {
+        return edges[0] == edges[1] && edges[0] == startEdge && edges[0] == edges[6];
+    }
+
+    bool USBDecodeModel::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 USBDecodeModel::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 USBDecodeModel::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 USBDecodeModel::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;
+    }
+}

+ 80 - 0
ProtocolUSB/USBDecodeModel.h

@@ -0,0 +1,80 @@
+// // ******************************************************************
+// //       /\ /|       @File         USBDecodeModel.h
+// //       \ V/        @Brief
+// //       | "")       @Author        lijinwen, ghz005@uni-trend.com.cn
+// //       /  |        @Creation      2024-1-4
+// //      /  \\        @Modified      2024-1-15
+// //    *(__\_\
+// // ******************************************************************
+
+#pragma once
+#include <iostream>
+#include <future>
+#include <chrono>
+#include <thread>
+#include <cmath>
+
+ 
+#include "../EdgePulse.h"
+
+#include "SYNC.h"
+#include "ProtocolUSBEnums.h"
+#include "UsbDecodeResult.h"
+#include "USBPacket.h"
+
+namespace Protocol
+{
+    class USBDecodeModel
+    {
+    private:
+        UsbDecodeResult resultData;
+        Enums::SignalRate signalRate;
+
+        uint16_t byteCount;
+
+        std::vector<USBPacket> usbPackets;
+
+    public:
+        USBDecodeModel(): signalRate(), byteCount(0)
+        {
+        }
+
+        double GetBitRateByPs() const;
+
+        std::vector<std::string> EventInfoTitles() const;
+
+        Enums::SignalRate SignalRate() const;
+
+        void SetSignalRate(Enums::SignalRate value);
+
+        uint16_t ByteCount() const;
+
+        void SetByteCount(uint16_t value);
+
+        static uint16_t MaxByteCount();
+
+        static uint16_t MinByteCount();
+
+        bool Parse_USB(UsbDecodeOptions option,std::vector<Protocol::TwoLevelEdgePulse> edgePluses1,
+                         std::vector<Protocol::TwoLevelEdgePulse> edgePluses2,std::promise<void>& cancellationSignal);
+
+    private:
+        bool CheckDifferenceWithinThreshold(double* array, int32_t size, double threshold = 0.15);
+
+        void ClearEdgeArray(Protocol::Edge* edges, int32_t size);
+
+        bool CheckSyncEdges(Protocol::Edge startEdge, Protocol::Edge* edges);
+
+        bool CheckSyncSpans(Protocol::TwoLevelEdgePulse* node, int32_t& leftOverSize, int32_t count,
+                            int32_t& avgSpans);
+
+        bool CheckSyncSpansByArrary(int32_t* startIndexs, const int32_t count, int32_t& avgSpans);
+
+        bool FindAllSyncs(Protocol::TwoLevelEdgePulse* node, int32_t& leftOverSize,
+                          std::vector<SYNC>& allSYNC, std::promise<void>& cancellationSignal, bool polarity = false);
+
+        bool FindPackets(Protocol::TwoLevelEdgePulse* node, int32_t& leftOverSize,
+                         std::vector<USBPacket>& allPacket, std::promise<void>& cancellationSignal,
+                         bool polarity = false);
+    };
+}

+ 240 - 0
ProtocolUSB/USBPacket.cpp

@@ -0,0 +1,240 @@
+// // ******************************************************************
+// //       /\ /|       @File         USBPacket.cpp
+// //       \ V/        @Brief
+// //       | "")       @Author        lijinwen, ghz005@uni-trend.com.cn
+// //       /  |        @Creation      2024-1-3
+// //      /  \\        @Modified      2024-1-15
+// //    *(__\_\
+// // ******************************************************************
+
+#include "USBPacket.h"
+#include  "../BaseHelper/CommonHelper.h"
+namespace Protocol
+{
+    USBPacket::USBPacket(): pid(0), lastNRBZDataBit(false), polarity(false), endPoint(0), crc5(0), isValid(false),
+                            isCRCChecked(false)
+    {
+    }
+
+    USBPacket::USBPacket(Protocol::TwoLevelEdgePulse* pidNode, int32_t& leftOverSize, SYNC sync, bool polarity)
+    {
+        this->polarity = polarity;
+        this->packetSYNC = sync;
+        //this->pidType = nullptr;
+
+        if (!GetPID(pidNode, leftOverSize))
+        {
+            return;
+        }
+
+        isValid = true;
+
+        if (this->type == Enums::USBPacketType::NoDefine)
+        {
+            return;
+        }
+
+        DecodeFields(pidNode, leftOverSize, sync);
+    }
+
+    bool USBPacket::CheckNibblesInverse(uint8_t value)
+    {
+        uint8_t highNibble = static_cast<uint8_t>(value >> 4);
+        uint8_t lowNibble = static_cast<uint8_t>(value & 0x0F);
+        return highNibble == (~lowNibble & 0x0F);
+    }
+
+    bool USBPacket::GetPID(Protocol::TwoLevelEdgePulse* pidNode, int32_t& leftOverSize)
+    {
+        if (pidNode == nullptr || leftOverSize <= 0 || packetSYNC.SingleBitTimingLength <= 0)
+        {
+            return false;
+        }
+        lastNRBZDataBit = true;
+        uint8_t data;
+        if (!DecodeNextByte(pidNode, leftOverSize, data))
+        {
+            return false;
+        }
+        // if (pidNode != nullptr) {
+        //     pidEndIndex = pidNode.Parent().StartIndex();
+        // }
+
+        pid = data;
+
+        if (EnumIsDefined<Enums::TokenPackageType>(
+            static_cast<int>(RealPID())))
+        {
+            type = Enums::USBPacketType::Token;
+        }
+        else if (Protocol::EnumIsDefined<Enums::DataPackageType>(
+            static_cast<int>(RealPID())))
+        {
+            type = Enums::USBPacketType::Data;
+        }
+        else if (Protocol::EnumIsDefined<Enums::HandshakePackageType>(
+            static_cast<int>(RealPID())))
+        {
+            type = Enums::USBPacketType::HandShake;
+        }
+        else if (Protocol::EnumIsDefined<Enums::SpecialPacketType>(
+            static_cast<int>(RealPID())))
+        {
+            type = Enums::USBPacketType::Special;
+        }
+        else
+        {
+            return false;
+        }
+        return true;
+    }
+
+    bool USBPacket::DecodeNextByte(Protocol::TwoLevelEdgePulse* node, int32_t& leftOverSize, uint8_t& outData)
+    {
+        outData = 0;
+        const bool highPolarityEdge = polarity;
+        const double singleBitTimingLengthThreshold = packetSYNC.SingleBitTimingLength * 0.95;
+        int gotbitCount = 0;
+        std::vector<bool> nrzi_data(8, false);
+
+        while (gotbitCount < 8)
+        {
+            if (node == nullptr || leftOverSize <= 0 || (*node).Edge == CommonBase::Edge::None)
+            {
+                return false;
+            }
+
+            if ((*node).EndIndex - (*node).StartIndex >= singleBitTimingLengthThreshold)
+            {
+                const int bitsCount = static_cast<int>(((*node).EndIndex - (*node).StartIndex) /
+                    singleBitTimingLengthThreshold);
+
+                const int lastGotbitCount = gotbitCount;
+                for (int i = 0; i < bitsCount; i++)
+                {
+                    if (lastGotbitCount + i >= 8)
+                    {
+                        continue;
+                    }
+                    nrzi_data[lastGotbitCount + i] = highPolarityEdge == ((*node).Edge ==
+                        CommonBase::Edge::Rise);
+
+                    gotbitCount++;
+                }
+            }
+            leftOverSize--;
+            node++;
+        }
+
+        for (int i = 0; i < 8; i++)
+        {
+            if (lastNRBZDataBit != nrzi_data[i])
+            {
+                lastNRBZDataBit = nrzi_data[i];
+            }
+            else
+            {
+                outData |= (1 << i);
+            }
+        }
+
+        return true;
+    }
+
+    void USBPacket::DecodeFields(Protocol::TwoLevelEdgePulse* node, int32_t& leftOverSize, const SYNC& sync)
+    {
+        if (leftOverSize <= 0)
+        {
+            return;
+        }
+        switch (type)
+        {
+        case Enums::USBPacketType::Token:
+            DecodeFieldsByToken(node, leftOverSize, sync);
+            break;
+        case Enums::USBPacketType::Data:
+            DecodeFieldsByData(node, leftOverSize, sync);
+            break;
+        case Enums::USBPacketType::HandShake:
+            DecodeFieldsByHandShake(node, leftOverSize, sync);
+            break;
+        case Enums::USBPacketType::Special:
+            DecodeFieldsBySpecial(node, leftOverSize, sync);
+            break;
+        default:
+            break;
+        }
+    }
+
+    void USBPacket::DecodeFieldsByToken(Protocol::TwoLevelEdgePulse* node, int32_t& leftOverSize, const SYNC& sync)
+    {
+        if (type == Enums::USBPacketType::NoDefine)
+        {
+            return;
+        }
+
+        //todo
+        auto packageType = static_cast<
+            Enums::TokenPackageType>(RealPID());
+        switch (packageType)
+        {
+        case Enums::TokenPackageType::Out:
+            break;
+        case Enums::TokenPackageType::SOF:
+            break;
+        case Enums::TokenPackageType::IN:
+            break;
+        case Enums::TokenPackageType::SETUP:
+            break;
+        default:
+            break;
+        }
+    }
+
+    void USBPacket::DecodeFieldsByData(Protocol::TwoLevelEdgePulse* node, int32_t& leftOverSize, const SYNC sync)
+    {
+        if (type == Enums::USBPacketType::NoDefine)
+        {
+            return;
+        }
+        auto packageType = static_cast<Enums::DataPackageType>
+            (RealPID());
+        switch (packageType)
+        {
+        case Enums::DataPackageType::Data0:
+        case Enums::DataPackageType::Data1:
+            datas.clear();
+            while (node != nullptr && (*node).StartIndex < sync.PacketEndIndex())
+            {
+                uint8_t data;
+                DecodeNextByte(node, leftOverSize, data);
+                datas.push_back(data);
+            }
+            break;
+        case Enums::DataPackageType::Data2:
+            break;
+        case Enums::DataPackageType::MData:
+            break;
+        default:
+            break;
+        }
+    }
+
+    void USBPacket::DecodeFieldsByHandShake(Protocol::TwoLevelEdgePulse* node, int32_t& leftOverSize, SYNC sync)
+    {
+        //todo
+        if (type != Enums::USBPacketType::HandShake)
+        {
+            return;
+        }
+    }
+
+    void USBPacket::DecodeFieldsBySpecial(Protocol::TwoLevelEdgePulse* node, int32_t& leftOverSize, SYNC sync)
+    {
+        //todo
+        if (type != Enums::USBPacketType::Special)
+        {
+            return;
+        }
+    }
+}

+ 75 - 0
ProtocolUSB/USBPacket.h

@@ -0,0 +1,75 @@
+// // ******************************************************************
+// //       /\ /|       @File         USBPacket.h
+// //       \ V/        @Brief
+// //       | "")       @Author        lijinwen, ghz005@uni-trend.com.cn
+// //       /  |        @Creation      2024-1-3
+// //      /  \\        @Modified      2024-1-15
+// //    *(__\_\
+// // ******************************************************************
+
+#pragma once
+#include <typeinfo>
+#include <vector>
+
+#include "../../CommonBase/CommonHelper.h"
+#include "../../CommonBase/EnumTypeInfo.h"
+#include "../EdgePulse.h"
+
+#include "SYNC.h"
+#include "ProtocolUSBEnums.h"
+
+namespace Protocol
+{
+    class USBPacket
+    {
+    public:
+        USBPacket();
+        USBPacket(Protocol::TwoLevelEdgePulse* pidNode, int32_t& leftOverSize, SYNC sync, bool polarity);
+
+        Enums::USBPacketType Type() const { return type; }
+        uint8_t PID() const { return pid; }
+        void SetPID(uint8_t value) { pid = value; }
+        bool LastNRBZDataBit() const { return lastNRBZDataBit; }
+        uint8_t RealPID() const { return static_cast<uint8_t>(pid & 0xF); }
+        //const std::type_info& PIDType() const { return pidType; }
+        //int PIDEndIndex() const { return pidEndIndex; }
+        bool Polarity() const { return polarity; }
+        const SYNC PacketSYNC() const { return packetSYNC; }
+        const std::vector<uint8_t>& Address() const { return address; }
+        uint8_t EndPoint() const { return endPoint; }
+        const std::vector<uint8_t>& Datas() const { return datas; }
+        uint8_t CRC5() const { return crc5; }
+        bool IsValid() const { return isValid; }
+        bool IsCRCChecked() const { return isCRCChecked; }
+
+    private:
+        Enums::USBPacketType type = Enums::USBPacketType::NoDefine;
+        uint8_t pid;
+        bool lastNRBZDataBit;
+        //std::type_info& pidType;
+        //int pidEndIndex;
+        bool polarity;
+        SYNC packetSYNC;
+        std::vector<uint8_t> address;
+        uint8_t endPoint;
+        std::vector<uint8_t> datas;
+        uint8_t crc5;
+        bool isValid;
+        bool isCRCChecked;
+
+        bool CheckNibblesInverse(uint8_t value);
+
+        bool GetPID(ProtocolBase::TwoLevelEdgePulse* pidNode, int32_t& leftOverSize);
+
+        bool DecodeNextByte(ProtocolBase::TwoLevelEdgePulse* node, int32_t& leftOverSize, uint8_t& outData);
+
+        void DecodeFields(ProtocolBase::TwoLevelEdgePulse* node, int32_t& leftOverSize, const SYNC& sync);
+
+        void DecodeFieldsByToken(ProtocolBase::TwoLevelEdgePulse* node, int32_t& leftOverSize, const SYNC& sync);
+        void DecodeFieldsByData(ProtocolBase::TwoLevelEdgePulse* node, int32_t& leftOverSize, const SYNC sync);
+
+        void DecodeFieldsByHandShake(ProtocolBase::TwoLevelEdgePulse* node, int32_t& leftOverSize, SYNC sync);
+
+        void DecodeFieldsBySpecial(ProtocolBase::TwoLevelEdgePulse* node, int32_t& leftOverSize, SYNC sync);
+    };
+}

+ 14 - 0
ProtocolUSB/UsbDecodeEvent.cpp

@@ -0,0 +1,14 @@
+// // ******************************************************************
+// //       /\ /|       @File         UsbDecodeEvent.cpp
+// //       \ V/        @Brief
+// //       | "")       @Author        lijinwen, ghz005@uni-trend.com.cn
+// //       /  |        @Creation      2024-1-4
+// //      /  \\        @Modified      2024-1-15
+// //    *(__\_\
+// // ******************************************************************
+
+#include "UsbDecodeEvent.h"
+
+namespace Protocol
+{
+}

+ 19 - 0
ProtocolUSB/UsbDecodeEvent.h

@@ -0,0 +1,19 @@
+// // ******************************************************************
+// //       /\ /|       @File         UsbDecodeEvent.h
+// //       \ V/        @Brief
+// //       | "")       @Author        lijinwen, ghz005@uni-trend.com.cn
+// //       /  |        @Creation      2024-1-4
+// //      /  \\        @Modified      2024-1-15
+// //    *(__\_\
+// // ******************************************************************
+
+#pragma once
+#include "DecodeEvent.h"
+
+namespace Protocol
+{
+    struct UsbDecodeEvent : Protocol::DecodeBaseEvent
+    {
+    public:
+    };
+}

+ 19 - 0
ProtocolUSB/UsbDecodeOptions.h

@@ -0,0 +1,19 @@
+// // ******************************************************************
+// //       /\ /|       @File         UsbDecodeOptions.h
+// //       \ V/        @Brief
+// //       | "")       @Author        lijinwen, ghz005@uni-trend.com.cn
+// //       /  |        @Creation      2024-05-17
+// //      /  \\        @Modified      2024-05-17
+// //    *(__\_\
+// // ******************************************************************
+
+#pragma once
+
+namespace Protocol
+{
+
+    struct UsbDecodeOptions
+    {
+        SignType SignType; //信号类型 差分、单端
+    };
+}

+ 24 - 0
ProtocolUSB/UsbDecodeResult.cpp

@@ -0,0 +1,24 @@
+// // ******************************************************************
+// //       /\ /|       @File         UsbDecodeResult.cpp
+// //       \ V/        @Brief
+// //       | "")       @Author        lijinwen, ghz005@uni-trend.com.cn
+// //       /  |        @Creation      2024-1-4
+// //      /  \\        @Modified      2024-1-15
+// //    *(__\_\
+// // ******************************************************************
+
+#include "UsbDecodeResult.h"
+
+namespace Protocol
+{
+    void UsbDecodeResult::Add(const UsbDecodeResultUnit* unit)
+    {
+        DecodeResultUnits.push_back(*unit);
+    }
+
+    void UsbDecodeResult::ClearData()
+    {
+        DecodeResultUnits.clear();
+        ResultValid = false;
+    }
+}

+ 41 - 0
ProtocolUSB/UsbDecodeResult.h

@@ -0,0 +1,41 @@
+// // ******************************************************************
+// //       /\ /|       @File         UsbDecodeResult.h
+// //       \ V/        @Brief
+// //       | "")       @Author        lijinwen, ghz005@uni-trend.com.cn
+// //       /  |        @Creation      2024-1-4
+// //      /  \\        @Modified      2024-1-15
+// //    *(__\_\
+// // ******************************************************************
+
+#pragma once
+#include <utility>
+
+#include "ProtocolUSBEnums.h"
+#include "../DecodeResult.h"
+#include "USBPacket.h"
+#include "../DecodeEvent.h"
+
+namespace Protocol
+{
+    class UsbDecodeResultCell : Protocol::DecodeResultCell
+    {
+    public:
+        USBPacket GetUsbPacket() { return usbPacket; }
+
+        UsbDecodeResultCell(USBPacket packet)
+        {
+            usbPacket = std::move(packet);
+        }
+
+    private:
+        USBPacket usbPacket;
+    };
+
+    struct UsbDecodeResult : Protocol::DecodeResult
+    {
+        void Add(const UsbDecodeResultCell* cell);
+ 
+        std::vector<UsbDecodeResultCell> DecodeResultCells;
+        //std::vector<UsbDecodeEvent> DecodeEventCells; //TODO
+    };
+}