/** * @file SlowControlGAM.cpp * @brief Source file for class SlowControlGAM * @date 29/08/2026 * @author Martino Ferrari * * @copyright Copyright 2015 F4E | European Joint Undertaking for ITER and * the Development of Fusion Energy ('Fusion for Energy'). * Licensed under the EUPL, Version 1.1 or - as soon they will be approved * by the European Commission - subsequent versions of the EUPL (the "Licence") * You may not use this work except in compliance with the Licence. * You may obtain a copy of the Licence at: http://ec.europa.eu/idabc/eupl * * @warning Unless required by applicable law or agreed to in writing, * software distributed under the Licence is distributed on an "AS IS" * basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express * or implied. See the Licence permissions and limitations under the Licence. */ #define DLL_API /*---------------------------------------------------------------------------*/ /* Standard header includes */ /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ /* Project header includes */ /*---------------------------------------------------------------------------*/ #include "AdvancedErrorManagement.h" #include "SlowControlGAM.h" /*---------------------------------------------------------------------------*/ /* Method definitions */ /*---------------------------------------------------------------------------*/ namespace MARTe { SlowControlGAM::SlowControlGAM() : GAM(), triggerPeriodMs(5000.0), triggerWidthMs(10.0), plateauMs(500.0), cycleFrequency(1000.0), cycleCount(0ull), triggerOut(NULL_PTR(float32 *)), plateauOut(NULL_PTR(float32 *)) { } SlowControlGAM::~SlowControlGAM() { } bool SlowControlGAM::Initialise(StructuredDataI &data) { bool ok = GAM::Initialise(data); if (ok && !data.Read("TriggerPeriodMs", triggerPeriodMs)) { triggerPeriodMs = 5000.0; } if (ok && !data.Read("TriggerWidthMs", triggerWidthMs)) { triggerWidthMs = 10.0; } if (ok && !data.Read("PlateauMs", plateauMs)) { plateauMs = 500.0; } if (ok && !data.Read("CycleFrequency", cycleFrequency)) { cycleFrequency = 1000.0; } if (ok && (triggerPeriodMs <= 0.0)) { REPORT_ERROR(ErrorManagement::InitialisationError, "SlowControlGAM: TriggerPeriodMs must be > 0."); ok = false; } if (ok && ((triggerWidthMs < 0.0) || (triggerWidthMs > triggerPeriodMs))) { REPORT_ERROR(ErrorManagement::InitialisationError, "SlowControlGAM: TriggerWidthMs must be in [0, TriggerPeriodMs]."); ok = false; } if (ok && (plateauMs < 0.0)) { REPORT_ERROR(ErrorManagement::InitialisationError, "SlowControlGAM: PlateauMs must be >= 0."); ok = false; } if (ok && (cycleFrequency <= 0.0)) { REPORT_ERROR(ErrorManagement::InitialisationError, "SlowControlGAM: CycleFrequency must be > 0."); ok = false; } return ok; } bool SlowControlGAM::Setup() { bool ok = (GetNumberOfOutputSignals() == 2u); if (!ok) { REPORT_ERROR(ErrorManagement::InitialisationError, "SlowControlGAM: exactly two output signals are required " "(Trigger, PlateauMs)."); return false; } triggerOut = reinterpret_cast(GetOutputSignalMemory(0u)); plateauOut = reinterpret_cast(GetOutputSignalMemory(1u)); ok = (triggerOut != NULL_PTR(float32 *)) && (plateauOut != NULL_PTR(float32 *)); if (!ok) { REPORT_ERROR(ErrorManagement::InitialisationError, "SlowControlGAM: failed to resolve output signal memory."); } return ok; } bool SlowControlGAM::Execute() { /* One Execute() is one RT cycle; convert the configured milliseconds to * cycle counts using the cycle rate. */ float64 msPerCycle = 1000.0 / cycleFrequency; uint64 period = static_cast(triggerPeriodMs / msPerCycle + 0.5); uint64 width = static_cast(triggerWidthMs / msPerCycle + 0.5); if (period == 0ull) { period = 1ull; } if (width > period) { width = period; } uint64 t = cycleCount % period; *triggerOut = (t < width) ? 1.0f : 0.0f; *plateauOut = static_cast(plateauMs); cycleCount++; return true; } CLASS_REGISTER(SlowControlGAM, "1.0") } /* namespace MARTe */