#pragma once #include "UsbDeviceManager.h" #include "SetDataToEepromCommand.h" #include "EepromDataRecord.h" namespace Incart::DeviceComplexCommands { class MicroMonSetDataToEepromCommand final : public SetDataToEepromCommand { private: const uint16_t m_quant = 0x10; std::vector m_data; uint16_t m_startAddress; uint16_t m_currAddress; uint16_t m_endAddress; Usb::UsbDeviceManager* const m_usbDeviceManager; public: MicroMonSetDataToEepromCommand(uint32_t uid, const EepromDataRecord& data_, Usb::UsbDeviceManager* const usbDeviceManager) : SetDataToEepromCommand(uid) , m_data(data_.data) , m_startAddress(data_.address) , m_currAddress(m_startAddress) , m_endAddress(static_cast(m_startAddress + m_data.size())) , m_usbDeviceManager(usbDeviceManager) { } public: std::shared_ptr execute() override { return writeFirstDataPortion(); } private slots: void handleWriteToEepromAnswerIsReady(std::shared_ptr /*command_*/, std::vector answer_, int32_t status_) { Usb::DeviceCommand::EStatus status = static_cast(status_); if (status != Usb::DeviceCommand::EStatus::OK) { emit answerIsReady(this, Usb::DeviceCommandStatusCreator::create(answer_, status_)); return; } writeNextDataPortion(); } private: std::shared_ptr writeFirstDataPortion() { if (m_currAddress < m_endAddress) { uint16_t currCount = calculateQuant(m_currAddress, m_endAddress); std::vector commandBytes; Usb::DeviceCommand::EStatus status = createWriteCommandBytes(currCount, commandBytes); if (status != Usb::DeviceCommand::EStatus::OK) { return Usb::DeviceCommandStatusCreator::create({}, status); } sendWriteCommand(currCount, commandBytes); } return std::make_shared(Usb::DeviceCommand::EStatus::OK); } void writeNextDataPortion() { if (m_currAddress < m_endAddress) { uint16_t currCount = calculateQuant(m_currAddress, m_endAddress); std::vector commandBytes; Usb::DeviceCommand::EStatus status = createWriteCommandBytes(currCount, commandBytes); if (status != Usb::DeviceCommand::EStatus::OK) { emit answerIsReady(this, Usb::DeviceCommandStatusCreator::create({}, status)); } sendWriteCommand(currCount, commandBytes); } else { emit answerIsReady(this, std::make_shared(Usb::DeviceCommand::EStatus::OK)); } } Usb::DeviceCommand::EStatus createWriteCommandBytes(uint16_t currCount_, std::vector& commandBytes_) { uint16_t copyAddress = m_currAddress - m_startAddress; std::vector::const_iterator beginCopyIt = m_data.begin() + copyAddress; std::vector::const_iterator endCopyIt = m_data.begin() + copyAddress + currCount_; std::vector currData; Common::ByteArrayProvider::addWord(m_currAddress, currData); currData.push_back(0); currData.push_back(0x05); currData.insert(currData.end(), beginCopyIt, endCopyIt); return m_usbDeviceManager->getCommandSet()->createCommandBytes(std::make_shared("WriteToEeprom", m_usbDeviceManager->getCommandQueue()->generateUid(), currData), commandBytes_); } void sendWriteCommand(uint16_t currCount_, const std::vector& commandBytes_) { Usb::ByteCommandQueue* commandQueue = m_usbDeviceManager->getCommandQueue(); std::shared_ptr command = std::make_shared("WriteToEeprom", commandQueue->generateUid(), std::move(commandBytes_)); connect(command.get(), &Usb::ByteCommand::answerIsReady, this, &MicroMonSetDataToEepromCommand::handleWriteToEepromAnswerIsReady); m_currAddress += currCount_; commandQueue->enqueue(command); } uint16_t calculateQuant(uint16_t currAddress_, uint16_t maxAddress_) { uint16_t quant = static_cast(maxAddress_ - currAddress_); return std::min(quant, ((currAddress_) / m_quant + 1) * m_quant - currAddress_); } }; } // namespace Incart::DeviceComplexCommands