.. _program_listing_file_encoder.cpp: Program Listing for File encoder.cpp ==================================== |exhale_lsh| :ref:`Return to documentation for file ` (``encoder.cpp``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: cpp #include "encoder.hpp" #include "log.hpp" void Encoder::set_data_format(int format) { #if REGMAP_VERSION < 0x0500 m_header_size = 2; m_block_bytes = 32; m_length_mask = TOFLX_LENGTH_MASK_RM4; m_elink_shift = TOFLX_ELINK_SHIFT_RM4; #else switch (format) { case FROMHOST_FORMAT_5BIT_LENGTH: m_header_size = 2; m_block_bytes = 32; m_length_mask = TOFLX_LENGTH_MASK; m_elink_shift = TOFLX_ELINK_SHIFT; break; case FROMHOST_FORMAT_HDR32_PACKET32: m_header_size = 4; m_block_bytes = 32; m_length_mask = TOFLX_LENGTH_MASK_HDR32; m_elink_shift = TOFLX_ELINK_SHIFT_HDR32; break; case FROMHOST_FORMAT_HDR32_PACKET64: m_block_bytes = 64; m_length_mask = TOFLX_LENGTH_MASK_HDR32; m_elink_shift = TOFLX_ELINK_SHIFT_HDR32; break; case FROMHOST_FORMAT_HDR32_PACKET32_8B: m_block_bytes = 32; break; case FROMHOST_FORMAT_HDR32_PACKET64_8B: m_block_bytes = 64; break; case FROMHOST_FORMAT_HDR32_PACKET128_8B: m_block_bytes = 128; break; default: LOG_ERR("Invalid FromHost data format %d. Assuming rm-5.1 for PCIe gen3.", format); break; } #endif m_payload_bytes = m_block_bytes - m_header_size; } void Encoder::set_destination_parameters(uint8_t* dest_start, uint32_t dest_size) { m_dest_start = dest_start; m_dest_size = dest_size; } size_t Encoder::compute_max_msg_occupancy(size_t size) const { return (compute_full_blocks(size) + 1) * m_block_bytes; } int Encoder::compute_full_blocks(size_t size) const { return ((size + m_payload_bytes - 1) / m_payload_bytes); } size_t Encoder::compute_final_bytes(size_t size) const { size_t blocks = (size + m_payload_bytes - 1) / m_payload_bytes; size_t final_bytes = size - (blocks - 1) * m_payload_bytes; return final_bytes; } uint64_t Encoder::encode_and_write_msg(uint64_t elink, const uint8_t *source, size_t size, uint32_t dest_offset) { if (m_dest_start == nullptr){ LOG_ERR("FromHost encoder not initialized. The message for 0x%lx will not be written.", elink); return 0; } uint32_t src_i(0); uint32_t dest_i(dest_offset); int blocks = compute_full_blocks(size); int final_bytes = size - (blocks - 1) * m_payload_bytes; #if REGMAP_VERSION < 0x0500 int hdr = ((elink << m_elink_shift) | ((m_payload_bytes / 2) << TOFLX_LENGTH_SHIFT_RM4)); int final_size = (final_bytes + 1) / 2; // Length in 2-byte units int final_hdr = hdr & ~m_length_mask; final_hdr |= ((final_size << TOFLX_LENGTH_SHIFT_RM4) | TOFLX_EOM_MASK_RM4); #else // Regmap 0x0500 and beyond, see FLX-1355, FLX-1601 and FLX-1886 if (m_length_mask == TOFLX_LENGTH_MASK_HDR32_8B and m_elink_shift == TOFLX_ELINK_SHIFT_HDR32_8B){ // Keeping the existing 4-byte header e-link numbering, // so map the e-link number to the '8-bit-fields' version uint64_t linknr = (elink & 0x07C0) >> 6; uint64_t eindex = (elink & 0x003F); elink = (linknr << 8) | eindex; } int hdr = ((elink << m_elink_shift) | m_length_mask); int final_hdr = hdr & ~m_length_mask; final_hdr |= final_bytes; // Length in bytes #endif // Fully-filled FromHost data packets for (int i = 0; i < blocks - 1; ++i) { // Invert payload byte order for (int j = m_payload_bytes - 1; j >= 0; --j, ++dest_i) { m_dest_start[dest_i] = source[src_i + j] & 0xFF; } src_i += m_payload_bytes; // Header for (int j = 0; j < m_header_size; ++j, ++dest_i) m_dest_start[dest_i] = (uint8_t)((hdr >> j * 8) & 0xFF); // Wrap-around ? if (dest_i >= m_dest_size) dest_i = 0; } // Final (likely not fully filled) FromHost data packet // Invert payload byte order for (int j = m_payload_bytes - 1; j >= final_bytes; --j, ++dest_i) { // destination[dest_i] = (char) 0xFF; // Remaining payload bytes: set to 0xFF m_dest_start[dest_i] = (uint8_t)0x00; // Remaining payload bytes: set to 0x00 } for (int j = final_bytes - 1; j >= 0; --j, ++dest_i) { m_dest_start[dest_i] = source[src_i + j] & 0xFF; // Final data bytes } // Header for (int j = 0; j < m_header_size; ++j, ++dest_i) m_dest_start[dest_i] = (uint8_t)((final_hdr >> j * 8) & 0xFF); // Wrap-around ? if (dest_i >= m_dest_size){ dest_i = 0; } return dest_i; }