123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458 |
- // // ******************************************************************
- // // /\ /| @File spi_decoder.cc
- // // \ V/ @Brief
- // // | "") @Author lijinwen, ghz005@uni-trend.com.cn
- // // / | @Creation 2024-07-19
- // // / \\ @Modified 2024-07-23
- // // *(__\_\
- // // ******************************************************************
- #include "spi_decoder.h"
- #include "../BaseHelper/common_helper.h"
- #include "../BaseHelper/constants.h"
- namespace Protocol
- {
- 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)
- {
- is_cancel_ptr_ = options.is_cancel;
- decode_result = {};
- decode_result.decoder_ptr = reinterpret_cast<intptr_t>(this);
- need_decode_data_ = true;
- 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;
- /*miso_data.clear();
- mosi_data.clear();*/
- data_packet_info_.clear();
- packet_infos_.clear();
- return false;
- }
- try
- {
- if (need_decode_data_)
- {
- /* miso_data.clear();
- mosi_data.clear();*/
- data_packet_info_.clear();
- packet_infos_.clear();
- need_decode_data_ = false;
- need_update_view_info_ = true;
- try
- {
- int32_t packet_index = 0, last_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;
- }
- 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");
- break;
- }
- if (packet_index < 0) break;
- SpiPacket packet_info = {};
- packet_info.start_index = cs_start_index;
- packet_info.start_len = 1;
- packet_info.has_start = cs_start_index >= 0 ? 1 : 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 (is_cancel_ptr_ != nullptr && *is_cancel_ptr_)
- {
- WriteLog(LogLevel::Level2, "AsyncFunction canceled");
- return false;
- }
- if (bool need_clear = false; need_clear) break;
- if (cs_end_index > packet_index)
- {
- packet_info.has_end = 1;
- packet_info.end_len = 1;
- packet_info.end_index = cs_end_index;
- }
- std::vector<DataPacketInfo> temp_data_packets;
- //数据解码
- while (true)
- {
- DataPacketInfo temp_data_packet = {};
- //std::vector<uint8_t> temp_miso_datas = {}, temp_mosi_datas = {};
- temp_data_packet.bit_count = frame_count_;
- temp_data_packet.index = packet_index;
- int32_t temp_miso_data = 0, temp_mosi_data = 0;
- bool get_miso_data = false, get_mosi_data = false;
- 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))
- {
- get_miso_data = false;
- break;
- }
- miso_bit = edge_pulse_data_miso_ptr->current_level == TwoLevelEdgePulseStatusType::High;
- if (options.miso_polarity == Polarity::NEG)
- {
- miso_bit = !miso_bit;
- }
- get_miso_data = true;
- }
- if (decode_mosi)
- {
- if (!CommonHelper::GetNodeByIndex(packet_index, edge_pulse_data_mosi_ptr))
- {
- get_miso_data = false;
- break;
- }
- mosi_bit = edge_pulse_data_mosi_ptr->current_level == TwoLevelEdgePulseStatusType::High;
- if (options.mosi_polarity == Polarity::NEG)
- {
- mosi_bit = !mosi_bit;
- }
- get_mosi_data = true;
- }
- 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;
- }
- temp_data_packet.real_bit_count = bit_index + 1;
- 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 = 1;
- break;
- }
- }
- 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 (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 (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);
- //end
- if (temp_data_packet.real_bit_count > 0)
- {
- //miso
- if (decode_miso)
- {
- temp_data_packet.miso_data_count = get_miso_data ? 1 : 0;
- if (temp_data_packet.miso_data_count > 0)
- {
- /* int32_t last_data_count = miso_data.size();
- miso_data.push_back(temp_miso_data);
- temp_data_packet.miso_data_ptr = miso_data.data() + last_data_count; */
- temp_data_packet.miso_data = static_cast<uint8_t>(temp_miso_data);
- }
- }
- //mosi
- if (decode_mosi)
- {
- temp_data_packet.mosi_data_count = get_mosi_data ? 1 : 0;
- if (temp_data_packet.mosi_data_count > 0)
- {
- /*int32_t last_data_count = mosi_data.size();
-
- mosi_data.push_back(temp_mosi_data);
- temp_data_packet.mosi_data_ptr = mosi_data.data() + last_data_count;*/
- temp_data_packet.mosi_data = static_cast<uint8_t>(temp_mosi_data);
- }
- }
- temp_data_packets.push_back(temp_data_packet);
- }
- if (temp_data_packet.is_last == 1 || packet_index >= data_len_) break;
- if (last_packet_index == packet_index)
- {
- break;
- }
- last_packet_index = packet_index;
- }
- //packet
- packet_info.data_count = static_cast<int32_t>(temp_data_packets.size());
- if (packet_info.data_count > 0)
- {
- int32_t last_data_count = static_cast<int32_t>(data_packet_info_.size());
- // 复制到末尾
- data_packet_info_.insert(data_packet_info_.end(),
- std::make_move_iterator(temp_data_packets.begin()),
- std::make_move_iterator(temp_data_packets.end()));
- packet_info.data_ptr = reinterpret_cast<intptr_t>(data_packet_info_.data() + last_data_count - 1);
- packet_info.data_info = temp_data_packets[0];
- }
- packet_infos_.push_back(packet_info);
- if (decode_miso && packet_index >= static_cast<int32_t>(miso_len))
- {
- break;
- }
- if (decode_mosi && packet_index >= static_cast<int32_t>(mosi_len))
- {
- break;
- }
- if (packet_index < 0)
- {
- break;
- }
- }
- }
- catch (const std::exception& ex)
- {
- std::string error_message = "DecodeSpi Error: " + std::string(ex.what());
- WriteLog(LogLevel::Level2, error_message.c_str());
- }
- }
- }
- 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_)
- {
- need_update_view_info_ = false;
- 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 (!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;
- }
- }
|