|
@@ -8,123 +8,376 @@
|
|
|
// // ******************************************************************
|
|
|
|
|
|
#include "spi_decoder.h"
|
|
|
+
|
|
|
+#include "../BaseHelper/common_helper.h"
|
|
|
+#include "../BaseHelper/constants.h"
|
|
|
+
|
|
|
namespace Protocol
|
|
|
{
|
|
|
- bool SpiDecoder::DecodeSpi(const SpiDecodeOptions& options, const Protocol::TwoLevelEdgePulse& edge_pulse_data_clk,
|
|
|
- const Protocol::TwoLevelEdgePulse& edge_pulse_data_cs, const Protocol::TwoLevelEdgePulse& edge_pulse_data_mosi,
|
|
|
- const Protocol::TwoLevelEdgePulse& edge_pulse_data_miso, Protocol::SpiDecodeResult& decode_result)
|
|
|
+ bool SpiDecoder::DecodeSpi(const SpiDecodeOptions& options, const EdgePulseDataTwoLevels& edge_pulse_data_clk,
|
|
|
+ const EdgePulseDataTwoLevels& edge_pulse_data_cs,
|
|
|
+ const EdgePulseDataTwoLevels& edge_pulse_data_mosi,
|
|
|
+ const EdgePulseDataTwoLevels& edge_pulse_data_miso, SpiDecodeResult& decode_result)
|
|
|
{
|
|
|
-
|
|
|
- if (csindex == -1 || clkindex == -1 || mosiindex == -1 || misoindex == -1) {
|
|
|
+ is_cancel_ptr_ = options.is_cancel;
|
|
|
+ decode_result = {};
|
|
|
+ bool checked_params = true;
|
|
|
+ if (edge_pulse_data_clk.waveform_data_count <= 0
|
|
|
+ || edge_pulse_data_cs.waveform_data_count <= 0
|
|
|
+ || edge_pulse_data_clk.sample_rate <= 0
|
|
|
+ || edge_pulse_data_cs.sample_rate <= 0)
|
|
|
+ {
|
|
|
+ checked_params = false;
|
|
|
+ }
|
|
|
+ const bool decode_mosi = options.decode_channel == SpiEnums::DecodeChannel::MOMI || options.decode_channel ==
|
|
|
+ SpiEnums::DecodeChannel::MOSI;
|
|
|
+ const bool decode_miso = options.decode_channel == SpiEnums::DecodeChannel::MOMI || options.decode_channel ==
|
|
|
+ SpiEnums::DecodeChannel::MISO;
|
|
|
+ if (decode_mosi && (edge_pulse_data_mosi.waveform_data_count <= 0 || edge_pulse_data_mosi.sample_rate <= 0))
|
|
|
+ {
|
|
|
+ checked_params = false;
|
|
|
+ }
|
|
|
+ if (decode_miso && (edge_pulse_data_miso.waveform_data_count <= 0 || edge_pulse_data_miso.sample_rate <= 0))
|
|
|
+ {
|
|
|
+ checked_params = false;
|
|
|
+ }
|
|
|
+ if (!checked_params)
|
|
|
+ {
|
|
|
need_decode_data_ = false;
|
|
|
need_update_view_info_ = true;
|
|
|
packet_infos_.clear();
|
|
|
+ return false;
|
|
|
}
|
|
|
-
|
|
|
- bool needclear = false;
|
|
|
- try {
|
|
|
- if (need_decode_data_) {
|
|
|
+ try
|
|
|
+ {
|
|
|
+ if (need_decode_data_)
|
|
|
+ {
|
|
|
need_decode_data_ = false;
|
|
|
need_update_view_info_ = true;
|
|
|
packet_infos_.clear();
|
|
|
- try {
|
|
|
- int packetindex = 0;
|
|
|
- uint32_t cslen = 0, clklen = 0, misolen = 0, mosilen = 0;
|
|
|
- DecodeDataHelper::Instance.TryGetPerChannelDataLength(_CS, cslen);
|
|
|
- DecodeDataHelper::Instance.TryGetPerChannelDataLength(_CLK, clklen);
|
|
|
- DecodeDataHelper::Instance.TryGetPerChannelDataLength(_MISO, misolen);
|
|
|
- DecodeDataHelper::Instance.TryGetPerChannelDataLength(_MOSI, mosilen);
|
|
|
- int csstartindex = -1;
|
|
|
- bool clkstate = clkState_ == Edge::Rise;
|
|
|
-
|
|
|
- while (true) {
|
|
|
+ try
|
|
|
+ {
|
|
|
+ int32_t packet_index = 0;
|
|
|
+ uint64_t cs_len = edge_pulse_data_cs.waveform_data_count;
|
|
|
+ uint64_t clk_len = edge_pulse_data_clk.waveform_data_count;
|
|
|
+ uint64_t miso_len = 0;
|
|
|
+ uint64_t mosi_len = 0;
|
|
|
+ uint64_t min_data_len = std::min(cs_len, clk_len);
|
|
|
+ TwoLevelEdgePulse* edge_pulse_data_cs_ptr = edge_pulse_data_cs.GetDataAddrPtr();
|
|
|
+ TwoLevelEdgePulse* edge_pulse_data_clk_ptr = edge_pulse_data_clk.GetDataAddrPtr();
|
|
|
+ TwoLevelEdgePulse* edge_pulse_data_miso_ptr = nullptr;
|
|
|
+ TwoLevelEdgePulse* edge_pulse_data_mosi_ptr = nullptr;
|
|
|
+ if (decode_miso)
|
|
|
+ {
|
|
|
+ miso_len = edge_pulse_data_miso.waveform_data_count;
|
|
|
+ edge_pulse_data_miso_ptr = edge_pulse_data_miso.GetDataAddrPtr();
|
|
|
+ min_data_len = std::min(min_data_len, miso_len);
|
|
|
+ }
|
|
|
+ if (decode_mosi)
|
|
|
+ {
|
|
|
+ mosi_len = edge_pulse_data_mosi.waveform_data_count;
|
|
|
+ edge_pulse_data_mosi_ptr = edge_pulse_data_mosi.GetDataAddrPtr();
|
|
|
+ min_data_len = std::min(min_data_len, mosi_len);
|
|
|
+ }
|
|
|
+ data_len_ = static_cast<int32_t>(min_data_len);
|
|
|
+ if (data_len_ == 0)
|
|
|
+ {
|
|
|
+ WriteLog(LogLevel::Level2, "data_len == 0");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ int32_t cs_start_index = -1;
|
|
|
+ const bool clk_state = options.clk_polarity == Polarity::POS;
|
|
|
+
|
|
|
+ while (true)
|
|
|
+ {
|
|
|
// 检查是否取消
|
|
|
if (is_cancel_ptr_ != nullptr && *is_cancel_ptr_)
|
|
|
{
|
|
|
WriteLog(LogLevel::Level2, "AsyncFunction canceled");
|
|
|
return false;
|
|
|
}
|
|
|
- packetindex = FindStartIndex(packetindex, cslen, token, needclear, csstartindex);
|
|
|
- if (packetindex == -1 || token.load() || needclear) break;
|
|
|
-
|
|
|
- PacketInfo packetInfo = {};
|
|
|
- packetInfo.Datas = vector<DataPacketInfo>();
|
|
|
- packetInfo.StartIndex = csstartindex;
|
|
|
- packetInfo.StartLen = 1;
|
|
|
- packetInfo.HasStart = csstartindex >= 0;
|
|
|
-
|
|
|
- auto csendindex = GetCSBitNextIndex(csLevelState_ == LevelState::High, packetindex, token, needclear);
|
|
|
- if (token.load() || needclear) break;
|
|
|
-
|
|
|
- if (csendindex > packetindex) {
|
|
|
- packetInfo.HasEnd = true;
|
|
|
- packetInfo.EndLen = 1;
|
|
|
- packetInfo.EndIndex = csendindex;
|
|
|
+ if (!FindStartNode(packet_index, cs_start_index,
|
|
|
+ edge_pulse_data_cs_ptr, edge_pulse_data_clk_ptr,
|
|
|
+ options.cs_polarity, options.clk_polarity))
|
|
|
+ {
|
|
|
+ WriteLog(LogLevel::Level2, "Not find start node");
|
|
|
+ return false;
|
|
|
}
|
|
|
|
|
|
- vector<DataPacketInfo> tempdatapckets;
|
|
|
- while (true) {
|
|
|
- DataPacketInfo tempdatapacket = {};
|
|
|
- tempdatapacket.BitCount = frame_count_;
|
|
|
- tempdatapacket.Index = packetindex;
|
|
|
- int tempmisodata = 0, tempmosidata = 0;
|
|
|
-
|
|
|
- for (int bitindex = 0; bitindex < frame_count_; ++bitindex) {
|
|
|
- bool misobit = GetBit(_MISO, packetindex, _MISOThreshold, miso_polarity_ == Polarity::Negative);
|
|
|
- bool mosibit = GetBit(_MOSI, packetindex, _MOSIThreshold, mosi_polarity_ == Polarity::Negative);
|
|
|
-
|
|
|
- if (byte_order_ == MSB_LSB::MSB) {
|
|
|
- tempmisodata <<= 1;
|
|
|
- tempmisodata |= (misobit ? 1 : 0);
|
|
|
- tempmosidata <<= 1;
|
|
|
- tempmosidata |= (mosibit ? 1 : 0);
|
|
|
- } else {
|
|
|
- tempmisodata |= (misobit ? 1 : 0) << bitindex;
|
|
|
- tempmosidata |= (mosibit ? 1 : 0) << bitindex;
|
|
|
+ if (packet_index < 0 || *is_cancel_ptr_) break;
|
|
|
+
|
|
|
+ SpiPacket packet_info = {};
|
|
|
+ packet_info.data = std::vector<DataPacketInfo>();
|
|
|
+ packet_info.start_index = cs_start_index;
|
|
|
+ packet_info.start_len = 1;
|
|
|
+ packet_info.has_start = cs_start_index >= 0;
|
|
|
+
|
|
|
+ if (!GetCsBitNextIndex(options.cs_polarity == Polarity::POS,
|
|
|
+ packet_index, edge_pulse_data_cs_ptr))
|
|
|
+ {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ const auto cs_end_index = edge_pulse_data_cs_ptr->start_index;
|
|
|
+ if (bool need_clear = false; *is_cancel_ptr_ || need_clear) break;
|
|
|
+
|
|
|
+ if (cs_end_index > packet_index)
|
|
|
+ {
|
|
|
+ packet_info.has_end = true;
|
|
|
+ packet_info.end_len = 1;
|
|
|
+ packet_info.end_index = cs_end_index;
|
|
|
+ }
|
|
|
+
|
|
|
+ std::vector<DataPacketInfo> temp_data_packets;
|
|
|
+ //数据解码
|
|
|
+ while (true)
|
|
|
+ {
|
|
|
+ DataPacketInfo temp_data_packet = {};
|
|
|
+ temp_data_packet.bit_count = frame_count_;
|
|
|
+ temp_data_packet.index = packet_index;
|
|
|
+ int32_t temp_miso_data = 0, temp_mosi_data = 0;
|
|
|
+
|
|
|
+ for (int32_t bit_index = 0; bit_index < frame_count_; ++bit_index)
|
|
|
+ {
|
|
|
+ bool miso_bit = false;
|
|
|
+ bool mosi_bit = false;
|
|
|
+ if (decode_miso)
|
|
|
+ {
|
|
|
+ if (!CommonHelper::GetNodeByIndex(packet_index, edge_pulse_data_miso_ptr))
|
|
|
+ {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ miso_bit = edge_pulse_data_miso_ptr->current_level == TwoLevelEdgePulseStatusType::High;
|
|
|
+ if (options.miso_polarity == Polarity::NEG)
|
|
|
+ {
|
|
|
+ miso_bit = !miso_bit;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (decode_mosi)
|
|
|
+ {
|
|
|
+ if (!CommonHelper::GetNodeByIndex(packet_index, edge_pulse_data_mosi_ptr))
|
|
|
+ {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ mosi_bit = edge_pulse_data_mosi_ptr->current_level == TwoLevelEdgePulseStatusType::High;
|
|
|
+ if (options.mosi_polarity == Polarity::NEG)
|
|
|
+ {
|
|
|
+ mosi_bit = !mosi_bit;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (options.msb_lsb == SpiEnums::Msblsb::MSB)
|
|
|
+ {
|
|
|
+ temp_miso_data <<= 1;
|
|
|
+ temp_miso_data |= (miso_bit ? 1 : 0);
|
|
|
+ temp_mosi_data <<= 1;
|
|
|
+ temp_mosi_data |= (mosi_bit ? 1 : 0);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ temp_miso_data |= (miso_bit ? 1 : 0) << bit_index;
|
|
|
+ temp_mosi_data |= (mosi_bit ? 1 : 0) << bit_index;
|
|
|
}
|
|
|
|
|
|
- tempdatapacket.MISOData.push_back(tempmisodata);
|
|
|
- tempdatapacket.MOSIData.push_back(tempmosidata);
|
|
|
- tempdatapacket.RealBitCount = bitindex + 1;
|
|
|
- packetindex = GetCLKEdge(!clkstate, packetindex, token, needclear);
|
|
|
+ temp_data_packet.miso_data.push_back(static_cast<uint8_t>(temp_miso_data));
|
|
|
+ temp_data_packet.mosi_data.push_back(static_cast<uint8_t>(temp_mosi_data));
|
|
|
+ temp_data_packet.real_bit_count = bit_index + 1;
|
|
|
|
|
|
- if ((packetindex > csendindex && csendindex >= 0) || packetindex == -1) {
|
|
|
- tempdatapacket.IsLast = true;
|
|
|
+ if (!GetClkEdge(!clk_state, packet_index, edge_pulse_data_clk_ptr))
|
|
|
+ {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ if ((packet_index > cs_end_index && cs_end_index >= 0) || packet_index == -1)
|
|
|
+ {
|
|
|
+ temp_data_packet.is_last = true;
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- if (packetindex > csendindex && csendindex != -1) {
|
|
|
- packetindex = csendindex;
|
|
|
- tempdatapacket.Len = packetindex - tempdatapacket.Index;
|
|
|
+ if (packet_index > cs_end_index && cs_end_index != -1)
|
|
|
+ {
|
|
|
+ packet_index = cs_end_index;
|
|
|
+ temp_data_packet.len = packet_index - temp_data_packet.index;
|
|
|
}
|
|
|
- if (packetindex == -1) {
|
|
|
- if (csendindex != -1) {
|
|
|
- tempdatapacket.Len = static_cast<int>(csendindex - tempdatapacket.Index);
|
|
|
- } else {
|
|
|
- tempdatapacket.Len = static_cast<int>(misolen - tempdatapacket.Index);
|
|
|
+ if (packet_index == -1)
|
|
|
+ {
|
|
|
+ if (cs_end_index != -1)
|
|
|
+ {
|
|
|
+ temp_data_packet.len = cs_end_index - temp_data_packet.index;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ temp_data_packet.len = static_cast<int>(miso_len - temp_data_packet.index);
|
|
|
}
|
|
|
- } else if (packetindex >= tempdatapacket.Index && tempdatapacket.Len == 0) {
|
|
|
- tempdatapacket.Len = packetindex - tempdatapacket.Index;
|
|
|
}
|
|
|
- if (tempdatapacket.RealBitCount > 0) tempdatapckets.push_back(tempdatapacket);
|
|
|
- if (tempdatapacket.IsLast) break;
|
|
|
+ else if (packet_index >= temp_data_packet.index && temp_data_packet.len == 0)
|
|
|
+ {
|
|
|
+ temp_data_packet.len = packet_index - temp_data_packet.index;
|
|
|
+ }
|
|
|
+ if (temp_data_packet.real_bit_count > 0) temp_data_packets.push_back(temp_data_packet);
|
|
|
+ if (temp_data_packet.is_last) break;
|
|
|
}
|
|
|
|
|
|
- packetInfo.Datas = tempdatapckets;
|
|
|
- packet_infos_.push_back(packetInfo);
|
|
|
+ packet_info.data = temp_data_packets;
|
|
|
+ packet_infos_.push_back(packet_info);
|
|
|
|
|
|
- if (packetindex >= misolen || packetindex < 0) {
|
|
|
+ if (packet_index >= static_cast<int32_t>(miso_len) || packet_index < 0)
|
|
|
+ {
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
- } catch (...) {}
|
|
|
+ }
|
|
|
+ catch (const std::exception& ex)
|
|
|
+ {
|
|
|
+ std::string error_message = "DecodeSpi Error: " + std::string(ex.what());
|
|
|
+ WriteLog(LogLevel::Level2, error_message.c_str());
|
|
|
+ }
|
|
|
}
|
|
|
- } catch (...) {}
|
|
|
+ }
|
|
|
+ catch (const std::exception& ex)
|
|
|
+ {
|
|
|
+ std::string error_message = "DecodeSpi Error: " + std::string(ex.what());
|
|
|
+ WriteLog(LogLevel::Level2, error_message.c_str());
|
|
|
+ }
|
|
|
|
|
|
- if (need_update_view_info_) {
|
|
|
+ if (need_update_view_info_)
|
|
|
+ {
|
|
|
need_update_view_info_ = false;
|
|
|
- // Update view info logic here
|
|
|
+ if (packet_infos_.size() > 0)
|
|
|
+ {
|
|
|
+ decode_result.decode_events_ptr = packet_infos_.data();
|
|
|
+ decode_result.decode_event_count = packet_infos_.size();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ bool SpiDecoder::GetClkEdge(const bool state, int32_t& start_index, TwoLevelEdgePulse* node_clk)
|
|
|
+ {
|
|
|
+ if (!CommonHelper::GetNodeByIndex(start_index, node_clk))
|
|
|
+ {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if (node_clk->current_level == TwoLevelEdgePulseStatusType::High != state)
|
|
|
+ {
|
|
|
+ if (!CommonHelper::FindNextNode(start_index, node_clk))
|
|
|
+ {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ start_index = node_clk->start_index;
|
|
|
+ if (start_index < 0) return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (start_index < 0) return false;
|
|
|
+
|
|
|
+ if (!CommonHelper::FindNextNode(start_index, node_clk))
|
|
|
+ {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ start_index = node_clk->start_index;
|
|
|
+ if (start_index < 0) return false;
|
|
|
+
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ bool SpiDecoder::FindStartNode(int32_t& start_index, int32_t& cs_start_index, TwoLevelEdgePulse* node_cs,
|
|
|
+ TwoLevelEdgePulse* node_clk,
|
|
|
+ const Polarity polarity_cs, const Polarity polarity_clk) const
|
|
|
+ {
|
|
|
+ cs_start_index = -1;
|
|
|
+ if (start_index >= data_len_) return false;
|
|
|
+
|
|
|
+ const bool state = polarity_cs == Polarity::POS;
|
|
|
+ const bool clk_state = polarity_clk == Polarity::NEG;
|
|
|
+
|
|
|
+ if (!CommonHelper::GetNodeByIndex(start_index, node_cs))
|
|
|
+ {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if (node_cs->current_level == TwoLevelEdgePulseStatusType::High != state)
|
|
|
+ {
|
|
|
+ if (!CommonHelper::FindNextNode(start_index, node_cs))
|
|
|
+ {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ cs_start_index = node_cs->start_index;
|
|
|
+ if (cs_start_index < 0) return false;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ if (start_index > 0)
|
|
|
+ {
|
|
|
+ cs_start_index = start_index;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (cs_start_index >= 0)
|
|
|
+ {
|
|
|
+ start_index = cs_start_index;
|
|
|
+ }
|
|
|
+
|
|
|
+ const auto start_time = std::chrono::steady_clock::now();
|
|
|
+
|
|
|
+ while (true)
|
|
|
+ {
|
|
|
+ if (!CommonHelper::GetNodeByIndex(start_index, node_clk))
|
|
|
+ {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if (node_clk->current_level == TwoLevelEdgePulseStatusType::High != clk_state)
|
|
|
+ {
|
|
|
+ if (!CommonHelper::FindNextNode(start_index, node_clk))
|
|
|
+ {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ start_index = node_clk->start_index;
|
|
|
+ }
|
|
|
+ if (start_index <= 0) return false;
|
|
|
+ if (!CommonHelper::FindNextNode(start_index, node_clk))
|
|
|
+ {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ start_index = node_clk->start_index;
|
|
|
+ if (start_index <= 0) return false;
|
|
|
+ if (!CommonHelper::GetNodeByIndex(start_index, node_cs))
|
|
|
+ {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if (node_cs->current_level == TwoLevelEdgePulseStatusType::High == state) return node_cs->start_index;
|
|
|
+
|
|
|
+ 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;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ bool SpiDecoder::GetCsBitNextIndex(const bool state, int32_t& start_index, TwoLevelEdgePulse* node_cs)
|
|
|
+ {
|
|
|
+ if (!CommonHelper::GetNodeByIndex(start_index, node_cs))
|
|
|
+ {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if (node_cs->current_level == TwoLevelEdgePulseStatusType::High != state)
|
|
|
+ {
|
|
|
+ if (node_cs->current_level == TwoLevelEdgePulseStatusType::High != state)
|
|
|
+ {
|
|
|
+ if (!CommonHelper::FindNextNode(start_index, node_cs))
|
|
|
+ {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ start_index = node_cs->start_index;
|
|
|
+ }
|
|
|
+ if (start_index == -1) return false;
|
|
|
+
|
|
|
+ if (!CommonHelper::FindNextNode(start_index, node_cs))
|
|
|
+ {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ start_index = node_cs->start_index;
|
|
|
+ return true;
|
|
|
}
|
|
|
+ return false;
|
|
|
}
|
|
|
-}
|
|
|
+}
|