mirror of https://github.com/openXC7/prjxray.git
lib: xc7series: record header type in configuration packets
Type 2 packets are used for when the amount of data required exceeds the word count field in a Type 1 header. ConfigurationPacket mostly hides this detail from the user but occasionally it is handy for debugging. Signed-off-by: Rick Altherr <kc8apf@kc8apf.net> Signed-off-by: Tim 'mithro' Ansell <mithro@mithis.com>
This commit is contained in:
parent
78546b275d
commit
4a80475db9
|
|
@ -24,9 +24,11 @@ class ConfigurationPacket {
|
|||
/* reserved = 3 */
|
||||
};
|
||||
|
||||
ConfigurationPacket(Opcode opcode, ConfigurationRegister address,
|
||||
ConfigurationPacket(unsigned int header_type, Opcode opcode,
|
||||
ConfigurationRegister address,
|
||||
const absl::Span<uint32_t> &data)
|
||||
: opcode_(opcode), address_(address), data_(std::move(data)) {}
|
||||
: header_type_(header_type), opcode_(opcode),
|
||||
address_(address), data_(std::move(data)) {}
|
||||
|
||||
// Attempt to read a configuration packet from a sequence of
|
||||
// 32-bit, big-endian words. If successful, returns the packet read and
|
||||
|
|
@ -39,11 +41,13 @@ class ConfigurationPacket {
|
|||
absl::Span<uint32_t> words,
|
||||
const ConfigurationPacket *previous_packet = nullptr);
|
||||
|
||||
unsigned int header_type() const { return header_type_; }
|
||||
const Opcode opcode() const { return opcode_; }
|
||||
const ConfigurationRegister address() const { return address_; }
|
||||
const absl::Span<uint32_t> &data() const { return data_; }
|
||||
|
||||
private:
|
||||
unsigned int header_type_;
|
||||
Opcode opcode_;
|
||||
ConfigurationRegister address_;
|
||||
absl::Span<uint32_t> data_;
|
||||
|
|
|
|||
|
|
@ -32,7 +32,8 @@ ConfigurationPacket::InitWithWords(absl::Span<uint32_t> words,
|
|||
}
|
||||
|
||||
return {words.subspan(data_word_count+1),
|
||||
{{opcode, address, words.subspan(1, data_word_count)}}};
|
||||
{{header_type, opcode, address,
|
||||
words.subspan(1, data_word_count)}}};
|
||||
}
|
||||
case 0b010: {
|
||||
absl::optional<ConfigurationPacket> packet;
|
||||
|
|
@ -48,7 +49,8 @@ ConfigurationPacket::InitWithWords(absl::Span<uint32_t> words,
|
|||
|
||||
if (previous_packet) {
|
||||
packet = ConfigurationPacket(
|
||||
opcode, previous_packet->address(),
|
||||
header_type, opcode,
|
||||
previous_packet->address(),
|
||||
words.subspan(1, data_word_count));
|
||||
}
|
||||
|
||||
|
|
@ -62,26 +64,48 @@ ConfigurationPacket::InitWithWords(absl::Span<uint32_t> words,
|
|||
std::ostream& operator<<(std::ostream& o, const ConfigurationPacket &packet) {
|
||||
switch (packet.opcode()) {
|
||||
case ConfigurationPacket::Opcode::NOP:
|
||||
return o << "[NOP]" << std::endl;
|
||||
o << "[NOP]" << std::endl;
|
||||
break;
|
||||
case ConfigurationPacket::Opcode::Read:
|
||||
return o << "[Read Address="
|
||||
<< std::setw(2)
|
||||
<< static_cast<int>(packet.address())
|
||||
<< " Length="
|
||||
<< std::setw(10) << packet.data().size()
|
||||
<< " Reg=\"" << packet.address() << "\""
|
||||
<< "]" << std::endl;
|
||||
o << "[Read Type=";
|
||||
o << packet.header_type();
|
||||
o << " Address=";
|
||||
o << std::setw(2) << std::hex;
|
||||
o << static_cast<int>(packet.address());
|
||||
o << " Length=";
|
||||
o << std::setw(10) << std::dec << packet.data().size();
|
||||
o << " Reg=\"" << packet.address() << "\"";
|
||||
o << "]" << std::endl;
|
||||
break;
|
||||
case ConfigurationPacket::Opcode::Write:
|
||||
return o << "[Write Address="
|
||||
<< std::setw(2)
|
||||
<< static_cast<int>(packet.address())
|
||||
<< " Length="
|
||||
<< std::setw(10) << packet.data().size()
|
||||
<< " Reg=\"" << packet.address() << "\""
|
||||
<< "]" << std::endl;
|
||||
o << "[Write Type=";
|
||||
o << packet.header_type();
|
||||
o << " Address=";
|
||||
o << std::setw(2) << std::hex;
|
||||
o << static_cast<int>(packet.address());
|
||||
o << " Length=";
|
||||
o << std::setw(10) << std::dec << packet.data().size();
|
||||
o << " Reg=\"" << packet.address() << "\"";
|
||||
o << "]" << std::endl;
|
||||
o << "Data in hex:" << std::endl;
|
||||
|
||||
for (size_t ii = 0; ii < packet.data().size(); ++ii) {
|
||||
o << std::setw(8) << std::hex;
|
||||
o << packet.data()[ii] << " ";
|
||||
|
||||
if ((ii+1) % 4 == 0) {
|
||||
o << std::endl;
|
||||
}
|
||||
}
|
||||
if (packet.data().size() % 4 != 0) {
|
||||
o << std::endl;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return o << "[Invalid Opcode]" << std::endl;
|
||||
o << "[Invalid Opcode]" << std::endl;
|
||||
}
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
} // namespace xc7series
|
||||
|
|
|
|||
|
|
@ -86,6 +86,7 @@ TEST(ConfigPacket, InitWithType2WithoutPreviousPacketFails) {
|
|||
|
||||
TEST(ConfigPacket, InitWithType2WithPreviousPacket) {
|
||||
xc7series::ConfigurationPacket previous_packet(
|
||||
static_cast<unsigned int>(0x1),
|
||||
xc7series::ConfigurationPacket::Opcode::Read,
|
||||
xc7series::ConfigurationRegister::MFWR,
|
||||
absl::Span<uint32_t>());
|
||||
|
|
|
|||
Loading…
Reference in New Issue