/* Copyright (c) 2017 European Organization for Nuclear Research (CERN). All rights reserved. This program and the accompanying materials are made available under the terms of the GNU Public License v3.0 which accompanies this distribution, and is available at http://www.gnu.org/licenses/gpl.html Contributors: .European Organization for Nuclear Research (CERN) - initial API and implementation .GSI Helmholtzzentrum für Schwerionenforschung (GSI) - features and bugfixes */ #include <silecs-communication/interface/core/SilecsService.h> #include <silecs-communication/interface/utility/XMLParser.h> #include <silecs-communication/interface/equipment/SilecsPLC.h> #include <silecs-communication/interface/equipment/SilecsBlock.h> #include <silecs-communication/interface/equipment/SilecsRegister.h> #include <silecs-communication/interface/core/SilecsAction.h> #include <silecs-communication/interface/utility/SilecsException.h> #include <silecs-communication/interface/utility/SilecsLog.h> #include <silecs-communication/interface/utility/StringUtilities.h> namespace Silecs { Block::Block(const ElementXML& blockNode, Connection& plcConnection) : plcConnection_(plcConnection), configuration_(false) { name_ = blockNode.getAttribute("name");; if(blockNode.getName() == "Configuration-Block") configuration_ = true; StringUtilities::fromString(size_, blockNode.getAttribute("size")); StringUtilities::fromString(memSize_, blockNode.getAttribute("mem-size")); StringUtilities::fromString(address_, blockNode.getAttribute("address")); if (blockNode.hasAttribute("ioType")) // only IO-Blocks have this attribute accessArea_ = Block::whichAccessArea(blockNode.getAttribute("ioType")); else accessArea_ = AccessArea::Memory; resetCustomAttributes(); //by default custom-size of the block is the maximum size accessType_ = whichAccessType(blockNode.getName()); } Block::~Block() { if (DEBUG & Log::topics_) LOG(ALLOC) << "Block (delete): " << name_; } AccessType Block::whichAccessType(const std::string& type) { if (type == "Acquisition-Block") return AccessType::Acquisition; else if (type == "Command-Block") return AccessType::Command; else if (type == "Configuration-Block") return AccessType::Setting; else if (type == "Setting-Block") return AccessType::Setting; else if (type == "Setting-IO-Block") return AccessType::Setting; else if (type == "Acquisition-IO-Block") return AccessType::Acquisition; else if (type == "Command-IO-Block") return AccessType::Command; else throw SilecsException(__FILE__, __LINE__, DATA_UNKNOWN_ACCESS_TYPE, type); } std::string Block::whichAccessType(AccessType type) { switch (type) { case AccessType::Command: return "WRITE-ONLY"; case AccessType::Acquisition: return "READ-ONLY"; case AccessType::Setting: return "READ-WRITE"; default: throw SilecsException(__FILE__, __LINE__, DATA_UNKNOWN_ACCESS_TYPE, StringUtilities::toString(static_cast<int>(type))); } } AccessArea Block::whichAccessArea(std::string area) { StringUtilities::toLower(area); if (area == "memory") return AccessArea::Memory; else if (area == "digital-io") return AccessArea::Digital; else if (area == "analog-io") return AccessArea::Analog; else throw SilecsException(__FILE__, __LINE__, DATA_UNKNOWN_ACCESS_AREA, area); } std::string Block::whichAccessArea(AccessArea area) { switch (area) { case AccessArea::Memory: return "MEMORY"; case AccessArea::Digital: return "DIGITAL-IO"; case AccessArea::Analog: return "ANALOG-IO"; default: throw SilecsException(__FILE__, __LINE__, DATA_UNKNOWN_ACCESS_AREA, StringUtilities::toString(static_cast<int>(area))); } } void Block::setCustomAttributes(const unsigned long customAddress, const unsigned long customOffset, const unsigned long customSize) { //user wants to limit the size of data to be sent/receive - check that it is lower than design allocation size if (customSize > memSize_) throw SilecsException(__FILE__, __LINE__, PARAM_EXCEEDED_BLOCK_SIZE, StringUtilities::toString(memSize_)); customAddress_ = customAddress; customOffset_ = customOffset; customSize_ = customSize; customAttributes_ = true; LOG(DEBUG) << "Set custom attributes of block: " << name_ << ", memSize: " << memSize_ << ", customSize: " << customSize << ", customAddress: " << customAddress << ", customOffset: " << customOffset; } void Block::resetCustomAttributes() { customAttributes_ = false; LOG(DEBUG) << "Reset custom attributes of block: " << name_; } void Block::importRegisters(void* pBuffer, timeval ts) { for (auto& reg : registers_) { if (reg->getFormat() == String) { reg->importString(pBuffer, ts); } else { reg->importValue(pBuffer, ts); } } } void Block::exportRegisters(void* pBuffer) { for (auto& reg : registers_) { if (reg->getFormat() == String) { reg->exportString(pBuffer); } else { reg->exportValue(pBuffer); } } } void Block::copyInToOut() { for (auto& reg : registers_) { if (reg->isReadable() && reg->isWritable()) { reg->copyValue(); } } } const std::vector<std::unique_ptr<Register>>& Block::getRegisters() const { return registers_; } } // namespace