diff --git a/Software/PC_Application/LibreVNA-GUI/Device/firmwareupdatedialog.cpp b/Software/PC_Application/LibreVNA-GUI/Device/firmwareupdatedialog.cpp index f2e5283..3b16e8c 100644 --- a/Software/PC_Application/LibreVNA-GUI/Device/firmwareupdatedialog.cpp +++ b/Software/PC_Application/LibreVNA-GUI/Device/firmwareupdatedialog.cpp @@ -1,6 +1,7 @@ #include "firmwareupdatedialog.h" #include "ui_firmwareupdatedialog.h" +#include "../../VNA_embedded/Application/Communication/PacketConstants.h" #include #include @@ -49,7 +50,7 @@ void FirmwareUpdateDialog::on_bStart_clicked() } file->seek(0); addStatus("Evaluating file..."); - if(file->size() % Protocol::FirmwareChunkSize != 0) { + if(file->size() % PacketConstants::FW_CHUNK_SIZE != 0) { abortWithError("Invalid file size"); return; } @@ -132,7 +133,7 @@ void FirmwareUpdateDialog::receivedAck() timer.start(1000); break; case State::TransferringData: - transferredBytes += Protocol::FirmwareChunkSize; + transferredBytes += PacketConstants::FW_CHUNK_SIZE; ui->progress->setValue(100 * transferredBytes / file->size()); if(transferredBytes >= file->size()) { // complete file transferred @@ -175,6 +176,6 @@ void FirmwareUpdateDialog::sendNextFirmwareChunk() { Protocol::FirmwarePacket fw; fw.address = transferredBytes; - file->read((char*) &fw.data, Protocol::FirmwareChunkSize); + file->read((char*) &fw.data, PacketConstants::FW_CHUNK_SIZE); dev->SendFirmwareChunk(fw); } diff --git a/Software/PC_Application/LibreVNA-GUI/LibreVNA-GUI.pro b/Software/PC_Application/LibreVNA-GUI/LibreVNA-GUI.pro index 3639f44..2621729 100644 --- a/Software/PC_Application/LibreVNA-GUI/LibreVNA-GUI.pro +++ b/Software/PC_Application/LibreVNA-GUI/LibreVNA-GUI.pro @@ -1,5 +1,6 @@ HEADERS += \ ../../VNA_embedded/Application/Communication/Protocol.hpp \ + ../../VNA_embedded/Application/Communication/PacketConstants.h \ Calibration/LibreCAL/caldevice.h \ Calibration/LibreCAL/librecaldialog.h \ Calibration/LibreCAL/usbdevice.h \ diff --git a/Software/VNA_embedded/Application/Communication/PacketConstants.h b/Software/VNA_embedded/Application/Communication/PacketConstants.h new file mode 100644 index 0000000..1b35f79 --- /dev/null +++ b/Software/VNA_embedded/Application/Communication/PacketConstants.h @@ -0,0 +1,49 @@ +#pragma once + + +#include + + +namespace PacketConstants { + // USB protocol packet field constants + + static constexpr uint8_t PCKT_HEADER_DATA = 0x5A; + + + ///////////////////////////////////////////////////////////// + // General packet structure field sizes and offsets in bytes + static constexpr uint8_t PCKT_HEADER_OFFSET = 0; + static constexpr uint8_t PCKT_HEADER_LEN = 1; + static constexpr uint8_t PCKT_LENGTH_OFFSET = PCKT_HEADER_OFFSET + PCKT_HEADER_LEN; // offset one byte + static constexpr uint8_t PCKT_LENGTH_LEN = 2; + static constexpr uint8_t PCKT_TYPE_OFFSET = PCKT_LENGTH_OFFSET + PCKT_LENGTH_LEN; // offset three bytes + static constexpr uint8_t PCKT_TYPE_LEN = 1; + static constexpr uint8_t PCKT_PAYLOAD_OFFSET = PCKT_TYPE_OFFSET + PCKT_TYPE_LEN; // offset four bytes + static constexpr uint8_t PCKT_CRC_LEN = 4; + + static constexpr uint8_t PCKT_COMBINED_HEADER_LEN = PCKT_HEADER_LEN + PCKT_LENGTH_LEN + PCKT_TYPE_LEN; // combined length of fields preceding payload + static constexpr uint8_t PCKT_EXCL_PAYLOAD_LEN = PCKT_COMBINED_HEADER_LEN + PCKT_CRC_LEN; // combined length of all packet fields, excluding payload + + ///////////////////////////////////////////////////////////// + // Payload content + + // Firmware packets + static constexpr uint16_t FW_CHUNK_SIZE = 256; + + // VNADataPoint payload fields in bytes + static constexpr uint8_t DPNT_FREQ_LEN = 8; + static constexpr uint8_t DPNT_POW_LVL_LEN = 2; + static constexpr uint8_t DPNT_PNT_NUM_LEN = 2; + static constexpr uint8_t DPNT_REAL_PART_LEN = 4; + static constexpr uint8_t DPNT_IMAG_PART_LEN = 4; + static constexpr uint8_t DPNT_DESC_LEN = 1; + + // VNADataPoint configuration bitmask offsets in bits + static constexpr uint8_t DPNT_CONF_P1_OFFSET = 0; + static constexpr uint8_t DPNT_CONF_P2_OFFSET = 1; + static constexpr uint8_t DPNT_CONF_P3_OFFSET = 2; + static constexpr uint8_t DPNT_CONF_P4_OFFSET = 3; + static constexpr uint8_t DPNT_CONF_REF_OFFSET = 4; + static constexpr uint8_t DPNT_CONF_STAGE_OFFSET = 5; + +} diff --git a/Software/VNA_embedded/Application/Communication/Protocol.cpp b/Software/VNA_embedded/Application/Communication/Protocol.cpp index 9a478f5..793f8c1 100644 --- a/Software/VNA_embedded/Application/Communication/Protocol.cpp +++ b/Software/VNA_embedded/Application/Communication/Protocol.cpp @@ -1,19 +1,16 @@ #include "Protocol.hpp" - #include +#include "PacketConstants.h" /* * General packet format: * 1. 1 byte header * 2. 2 byte overall packet length (with header and checksum) - * 3. packet type - * 4. packet payload + * 3. 1 byte packet type + * 4. variable length packet payload * 5. 4 byte CRC32 (with header) */ -static constexpr uint8_t header = 0x5A; -static constexpr uint8_t header_size = 4; - #define CRC32_POLYGON 0xEDB88320 uint32_t Protocol::CRC32(uint32_t crc, const void *data, uint32_t len) { uint8_t *u8buf = (uint8_t*) data; @@ -35,7 +32,7 @@ uint16_t Protocol::DecodeBuffer(uint8_t *buf, uint16_t len, PacketInfo *info) { } uint8_t *data = buf; /* Remove any out-of-order bytes in front of the frame */ - while (*data != header) { + while (*data != PCKT_HEADER_DATA) { data++; if(--len == 0) { /* Reached end of data */ @@ -45,16 +42,16 @@ uint16_t Protocol::DecodeBuffer(uint8_t *buf, uint16_t len, PacketInfo *info) { } } /* At this point, data points to the beginning of the frame */ - if(len < header_size) { + if(len < PCKT_COMBINED_HEADER_LEN) { /* the frame header has not been completely received */ info->type = PacketType::None; return data - buf; } /* Evaluate frame size */ - uint16_t length = data[1] | ((uint16_t) data[2] << 8); + uint16_t length = data[PCKT_LENGTH_OFFSET] | ((uint16_t) data[2] << 8); - if(length > sizeof(PacketInfo) * 2 || length < 8) { + if(length > sizeof(PacketInfo) * 2 || length < PCKT_EXCL_PAYLOAD_LEN) { // larger than twice the maximum expected packet size or too small, probably an error, ignore info->type = PacketType::None; return 1; @@ -67,10 +64,10 @@ uint16_t Protocol::DecodeBuffer(uint8_t *buf, uint16_t len, PacketInfo *info) { } /* The complete frame has been received, check checksum */ - auto type = (PacketType) data[3]; + auto type = (PacketType) data[PCKT_TYPE_OFFSET]; uint32_t crc = (uint32_t) data[length-4] | ((uint32_t) data[length-3] << 8) | ((uint32_t) data[length-2] << 16) | ((uint32_t) data[length-1] << 24); if(type != PacketType::VNADatapoint) { - uint32_t compare = CRC32(0, data, length - 4); + uint32_t compare = CRC32(0, data, length - PCKT_CRC_LEN); if(crc != compare) { // CRC mismatch, remove header data += 1; @@ -78,7 +75,7 @@ uint16_t Protocol::DecodeBuffer(uint8_t *buf, uint16_t len, PacketInfo *info) { return data - buf; } // Valid packet, copy packet type and payload - memcpy(info, &data[3], length - 7); + memcpy(info, &data[PCKT_TYPE_OFFSET], length - 7); } else { // Datapoint has the CRC set to zero if(crc != 0x00000000) { @@ -87,9 +84,9 @@ uint16_t Protocol::DecodeBuffer(uint8_t *buf, uint16_t len, PacketInfo *info) { return data - buf; } // Create the datapoint - info->type = (PacketType) data[3]; + info->type = (PacketType) data[PCKT_TYPE_OFFSET]; info->VNAdatapoint = new VNADatapoint<32>; - info->VNAdatapoint->decode(&data[4], length - 8); + info->VNAdatapoint->decode(&data[PCKT_PAYLOAD_OFFSET], length - PCKT_EXCL_PAYLOAD_LEN); } return data - buf + length; @@ -132,29 +129,29 @@ uint16_t Protocol::EncodePacket(const PacketInfo &packet, uint8_t *dest, uint16_ case PacketType::None: break; } - if (payload_size < 0 || payload_size + 8 > destsize) { + if (payload_size < 0 || payload_size + PCKT_EXCL_PAYLOAD_LEN > destsize) { // encoding failed, buffer too small return 0; } // Write header - dest[0] = header; - uint16_t overall_size = payload_size + 8; - memcpy(&dest[1], &overall_size, 2); + dest[PCKT_HEADER_OFFSET] = PCKT_HEADER_DATA; + uint16_t overall_size = payload_size + PCKT_EXCL_PAYLOAD_LEN; + memcpy(&dest[PCKT_LENGTH_OFFSET], &overall_size, PCKT_LENGTH_LEN); // Further encoding uses a special case for VNADatapoint packettype uint32_t crc = 0x00000000; if(packet.type == PacketType::VNADatapoint) { // CRC calculation takes about 18us which is the bulk of the time required to encode and transmit a datapoint. // Skip CRC for data points to optimize throughput - dest[3] = (uint8_t) packet.type; - packet.VNAdatapoint->encode(&dest[4], destsize - 8); + dest[PCKT_TYPE_OFFSET] = (uint8_t) packet.type; + packet.VNAdatapoint->encode(&dest[PCKT_PAYLOAD_OFFSET], destsize - PCKT_EXCL_PAYLOAD_LEN); crc = 0x00000000; } else { // Copy rest of the packet - memcpy(&dest[3], &packet, payload_size + 1); // one additional byte for the packet type + memcpy(&dest[PCKT_TYPE_OFFSET], &packet, payload_size + PCKT_TYPE_LEN); // one additional byte for the packet type // Calculate the CRC - crc = CRC32(0, dest, overall_size - 4); + crc = CRC32(0, dest, overall_size - PCKT_CRC_LEN); } - memcpy(&dest[overall_size - 4], &crc, 4); + memcpy(&dest[overall_size - PCKT_CRC_LEN], &crc, PCKT_CRC_LEN); return overall_size; } diff --git a/Software/VNA_embedded/Application/Communication/Protocol.hpp b/Software/VNA_embedded/Application/Communication/Protocol.hpp index 637eba1..5a2a3bd 100644 --- a/Software/VNA_embedded/Application/Communication/Protocol.hpp +++ b/Software/VNA_embedded/Application/Communication/Protocol.hpp @@ -1,9 +1,13 @@ #pragma once + #include #include #include #include +#include "PacketConstants.h" + +using namespace PacketConstants; namespace Protocol { @@ -37,7 +41,7 @@ public: } real_values[num_values] = real; imag_values[num_values] = imag; - descr_values[num_values] = stage << 5 | sourceMask; + descr_values[num_values] = stage << DPNT_CONF_STAGE_OFFSET | sourceMask; num_values++; return true; } @@ -46,27 +50,32 @@ public: if(requiredBufferSize() > destSize) { return false; } - memcpy(dest, &frequency, 8); - memcpy(dest+8, &cdBm, 2); - memcpy(dest+10, &pointNum, 2); - dest += 12; - memcpy(dest, real_values, num_values * 4); - dest += num_values * 4; - memcpy(dest, imag_values, num_values * 4); - dest += num_values * 4; + memcpy(dest, &frequency, DPNT_FREQ_LEN); + dest += DPNT_FREQ_LEN; + memcpy(dest, &cdBm, DPNT_POW_LVL_LEN); + dest += DPNT_POW_LVL_LEN; + memcpy(dest, &pointNum, DPNT_PNT_NUM_LEN); + dest += DPNT_PNT_NUM_LEN; + memcpy(dest, real_values, num_values * DPNT_REAL_PART_LEN); + dest += num_values * DPNT_REAL_PART_LEN; + memcpy(dest, imag_values, num_values * DPNT_IMAG_PART_LEN); + dest += num_values * DPNT_IMAG_PART_LEN; memcpy(dest, descr_values, num_values); return true; } void decode(const uint8_t *buffer, uint16_t size) { - num_values = (size - (8+2+2)) / (1+4+4); - memcpy(&frequency, buffer, 8); - memcpy(&cdBm, buffer+8, 2); - memcpy(&pointNum, buffer+10, 2); - buffer += 12; - memcpy(real_values, buffer, num_values * 4); - buffer += num_values * 4; - memcpy(imag_values, buffer, num_values * 4); - buffer += num_values * 4; + num_values = (size - (DPNT_FREQ_LEN + DPNT_POW_LVL_LEN + DPNT_PNT_NUM_LEN)) / + (DPNT_REAL_PART_LEN + DPNT_IMAG_PART_LEN + DPNT_DESC_LEN); + memcpy(&frequency, buffer, DPNT_FREQ_LEN); + buffer += DPNT_FREQ_LEN; + memcpy(&cdBm, buffer, DPNT_POW_LVL_LEN); + buffer += DPNT_POW_LVL_LEN; + memcpy(&pointNum, buffer, DPNT_PNT_NUM_LEN); + buffer += DPNT_PNT_NUM_LEN; + memcpy(real_values, buffer, num_values * DPNT_REAL_PART_LEN); + buffer += num_values * DPNT_REAL_PART_LEN; + memcpy(imag_values, buffer, num_values * DPNT_IMAG_PART_LEN); + buffer += num_values * DPNT_IMAG_PART_LEN; memcpy(descr_values, buffer, num_values); } @@ -77,7 +86,7 @@ public: sourceMask |= (int) Source::Reference; } for(int i=0;i> 5 != stage) { + if(descr_values[i] >> DPNT_CONF_STAGE_OFFSET != stage) { continue; } if((descr_values[i] & sourceMask) != sourceMask) { @@ -108,7 +117,8 @@ public: } uint16_t requiredBufferSize() { - return 8+2+2+ num_values * (4+4+1); + return DPNT_FREQ_LEN + DPNT_POW_LVL_LEN + DPNT_PNT_NUM_LEN + + num_values * (DPNT_REAL_PART_LEN + DPNT_IMAG_PART_LEN + DPNT_DESC_LEN); } union { @@ -299,10 +309,10 @@ using SpectrumAnalyzerResult = struct _spectrumAnalyzerResult { uint16_t pointNum; }; -static constexpr uint16_t FirmwareChunkSize = 256; + using FirmwarePacket = struct _firmwarePacket { uint32_t address; - uint8_t data[FirmwareChunkSize]; + uint8_t data[FW_CHUNK_SIZE]; }; using AmplitudeCorrectionPoint = struct _amplitudecorrectionpoint {