diff --git a/DataSources/AtcaIop/AtcaIopADC.h b/DataSources/AtcaIop/AtcaIopADC.h index 062df6a..858d950 100644 --- a/DataSources/AtcaIop/AtcaIopADC.h +++ b/DataSources/AtcaIop/AtcaIopADC.h @@ -2,7 +2,8 @@ * @file AtcaIopADC.h * @brief Header file for class AtcaIopADC * @date 19/10/2023 - * @author Andre Neto / Bernardo Carvalho + * @author Andre Neto + * @author Bernardo Carvalho * * Based on Example: * https://vcis-gitlab.f4e.europa.eu/aneto/MARTe2-demos-padova/-/tree/master/DataSources/ADCSimulator @@ -15,7 +16,7 @@ * 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, + * @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. @@ -36,424 +37,439 @@ /* Project header includes */ /*---------------------------------------------------------------------------*/ #include "DataSourceI.h" -#include "EventSem.h" #include "EmbeddedServiceMethodBinderI.h" -#include "SingleThreadService.h" +#include "EventSem.h" #include "MessageI.h" #include "RegisteredMethodsMessageFilter.h" +#include "SingleThreadService.h" /*---------------------------------------------------------------------------*/ /* Class declaration */ /*---------------------------------------------------------------------------*/ namespace MARTe { - /** - * The number of signals (2 time signals + ). - */ +/** + * The number of signals (2 time signals + ). + */ // const uint32 ATCA_IOP_MAX_CHANNELS = 32u; - - const uint32 ATCA_IOP_N_TIMCNT = 4u; - const uint32 ATCA_IOP_N_ADCs = 16u; - const uint32 ATCA_IOP_N_INTEGRALS = ATCA_IOP_N_ADCs; - const uint32 ATCA_IOP_N_SIGNALS = (ATCA_IOP_N_TIMCNT + 2); //ATCA_IOP_N_ADCs + - //ATCA_IOP_N_INTEGRALS); - /** - * The number of buffers to synchronise with the DMA - */ - const uint32 NUMBER_OF_BUFFERS = 8u; - /** - * @brief A DataSource that simulates an ADC board - * TODO - *
-     * +AtcaIopADC = {
-     *    Class = "AtcaIop::AtcaIopADC"
-     * CPUMask = "0x040"
-     * StackSize = "1048576"
-     * DeviceName = "/dev/atca_v6"
-     * BoardId = 9
-     * DeviceDmaName = "/dev/atca_v6_dmart_2"
-     * NumberOfChannels = "12"
-     * IsMaster = "1"
-     * SleepNature = "Busy"
-     * SleepPercentage = "15"
-     * ADCFrequency = "2000000"
-     * RTDecimation = "200"
-     * ChopperPeriod = "2000"
-     * ElectricalOffsets = {"-151" "110" "-417" "-35" "-204" "0" "134" "-59" "-227" "-308" "-120" "-175" "0" "0" "0" "0"}
-     * WiringOffsets = {"0.0" "0.0" "0.0" "0.0" "0.0" "0.0" "0.0" "0.0" "0.0" "0.0" "0.0" "0.0" "0.0" "0.0" "0.0" "0.0"}
-     * //WiringOffsets = {0.354 0.288 -0.010 -0.083 0.347 0.228 0.088 0.186 -0.297 -0.101 0.025 -0.012 0.0 0.0 0.0 0.0}
-     * //WiringOffsets = {"0.271" "0.211" "0.098" "0.141" "0.312" "0.203" "0.212" "0.361" "-0.546" "-0.433" "-0.598" "1.362"}
-     * Signals = {
-     *   Counter = {
-     *     Type = "uint32"
-     *   }
-     *   Time = {
-     *     Type = "uint32"
-     *   }
-     *   TimeoutCount = {
-     *     Type = "uint32"
-     *   }
-     *   TimeoutMax = {
-     *     Type = "uint32"
-     *   }
-     *   ADCDecim = {
-     *     DataSource = "AtcaIopAdc_DS"
-     *     Type = "int32"
-     *     NumberOfElements = 16
-     *     NumberOfDimensions = 1
-     *   }
-     *   ADCInt = {
-     *     DataSource = "AtcaIopAdc_DS"
-     *     Type = "int64"
-     *     NumberOfElements = 16
-     *     NumberOfDimensions = 1
-     *   }
-     *   Idle_Thread1_CycleTime = {
-     *     DataSource = "Timings"
-     *     Alias = "Idle.Thread1_CycleTime"
-     *     Type = "uint32"
-     *   }
-     *   Run_Thread1_CycleTime = {
-     *     DataSource = "Timings"
-     *     Alias = "Online.Thread1_CycleTime"
-     *     Type = "uint32"
-     *   }
-     *     }
-     * }
-     * 
- */ - class AtcaIopADC: public DataSourceI, public MessageI, public EmbeddedServiceMethodBinderI { - public: - CLASS_REGISTER_DECLARATION() - /** - * @brief Default constructor - * @post - * Counter = 0 - * Time = 0 - */ - AtcaIopADC (); +const uint32 ATCA_IOP_N_TIMCNT = 4u; +const uint32 ATCA_IOP_N_ADCs = 16u; +const uint32 ATCA_IOP_N_INTEGRALS = ATCA_IOP_N_ADCs; +const uint32 ATCA_IOP_N_SIGNALS = + (ATCA_IOP_N_TIMCNT + 2); // ATCA_IOP_N_ADCs + + // ATCA_IOP_N_INTEGRALS); +/** + * The number of buffers to synchronise with the DMA + */ +const uint32 NUMBER_OF_BUFFERS = 8u; - /** - * @brief Destructor. Stops the EmbeddedThread. - */ - virtual ~AtcaIopADC(); +/** + * @brief A DataSource that simulates an ADC board + * TODO + *
+ * +AtcaIopADC = {
+ *    Class = "AtcaIop::AtcaIopADC"
+ * CPUMask = "0x040"
+ * StackSize = "1048576"
+ * DeviceName = "/dev/atca_v6"
+ * BoardId = 9
+ * DeviceDmaName = "/dev/atca_v6_dmart_2"
+ * NumberOfChannels = "12"
+ * IsMaster = "1"
+ * SleepNature = "Busy"
+ * SleepPercentage = "15"
+ * ADCFrequency = "2000000"
+ * RTDecimation = "200"
+ * ChopperPeriod = "2000"
+ * ElectricalOffsets = {"-151" "110" "-417" "-35" "-204" "0" "134" "-59" "-227"
+ * "-308" "-120" "-175" "0" "0" "0" "0"} WiringOffsets = {"0.0" "0.0" "0.0"
+ * "0.0" "0.0" "0.0" "0.0" "0.0" "0.0" "0.0" "0.0" "0.0" "0.0" "0.0" "0.0"
+ * "0.0"}
+ * //WiringOffsets = {0.354 0.288 -0.010 -0.083 0.347 0.228 0.088 0.186 -0.297
+ * -0.101 0.025 -0.012 0.0 0.0 0.0 0.0}
+ * //WiringOffsets = {"0.271" "0.211" "0.098" "0.141" "0.312" "0.203" "0.212"
+ * "0.361" "-0.546" "-0.433" "-0.598" "1.362"} Signals = { Counter = { Type =
+ * "uint32"
+ *   }
+ *   Time = {
+ *     Type = "uint32"
+ *   }
+ *   TimeoutCount = {
+ *     Type = "uint32"
+ *   }
+ *   TimeoutMax = {
+ *     Type = "uint32"
+ *   }
+ *   ADCDecim = {
+ *     DataSource = "AtcaIopAdc_DS"
+ *     Type = "int32"
+ *     NumberOfElements = 16
+ *     NumberOfDimensions = 1
+ *   }
+ *   ADCInt = {
+ *     DataSource = "AtcaIopAdc_DS"
+ *     Type = "int64"
+ *     NumberOfElements = 16
+ *     NumberOfDimensions = 1
+ *   }
+ *   Idle_Thread1_CycleTime = {
+ *     DataSource = "Timings"
+ *     Alias = "Idle.Thread1_CycleTime"
+ *     Type = "uint32"
+ *   }
+ *   Run_Thread1_CycleTime = {
+ *     DataSource = "Timings"
+ *     Alias = "Online.Thread1_CycleTime"
+ *     Type = "uint32"
+ *   }
+ *     }
+ * }
+ * 
+ */ +class AtcaIopADC : public DataSourceI, + public MessageI, + public EmbeddedServiceMethodBinderI { +public: + CLASS_REGISTER_DECLARATION() + /** + * @brief Default constructor + * @post + * Counter = 0 + * Time = 0 + */ + AtcaIopADC(); - /** - * @brief See DataSourceI::AllocateMemory. - */ - virtual bool AllocateMemory(); + /** + * @brief Destructor. Stops the EmbeddedThread. + */ + virtual ~AtcaIopADC(); - /** - gg* @brief See DataSourceI::GetNumberOfMemoryBuffers. - * @return 1. - */ - virtual uint32 GetNumberOfMemoryBuffers(); + /** + * @brief See DataSourceI::AllocateMemory. + */ + virtual bool AllocateMemory(); - /** - * @brief See DataSourceI::GetNumberOfMemoryBuffers. - */ - virtual bool GetSignalMemoryBuffer(const uint32 signalIdx, - const uint32 bufferIdx, - void *&signalAddress); + /** + gg* @brief See DataSourceI::GetNumberOfMemoryBuffers. + * @return 1. + */ + virtual uint32 GetNumberOfMemoryBuffers(); - /** - * @brief See DataSourceI::GetNumberOfMemoryBuffers. - * @details Only InputSignals are supported. - * @return MemoryMapSynchronisedInputBroker if frequency > 0, MemoryMapInputBroker otherwise. - */ - virtual const char8 *GetBrokerName(StructuredDataI &data, - const SignalDirection direction); + /** + * @brief See DataSourceI::GetNumberOfMemoryBuffers. + */ + virtual bool GetSignalMemoryBuffer(const uint32 signalIdx, + const uint32 bufferIdx, + void *&signalAddress); - /** - * @brief Waits on an EventSem for the period given by 1/Frequency to elapse on Execute. - * @return true if the semaphore is successfully posted. - */ - virtual bool Synchronise(); + /** + * @brief See DataSourceI::GetNumberOfMemoryBuffers. + * @details Only InputSignals are supported. + * @return MemoryMapSynchronisedInputBroker if frequency > 0, + * MemoryMapInputBroker otherwise. + */ + virtual const char8 *GetBrokerName(StructuredDataI &data, + const SignalDirection direction); - /** - if (boardFileDescriptor != -1) { - close(boardFileDescriptor); - } - * @brief Callback function for an EmbeddedThread. - * @details Sleeps (Busy or Default) for the period given by 1/Frequency and post an EventSem which is waiting on - * the Synchronise method. - * @param[in] info not used. - * @return NoError if the EventSem can be successfully posted. - */ - virtual ErrorManagement::ErrorType Execute(ExecutionInfo & info); + /** + * @brief Waits on an EventSem for the period given by 1/Frequency to elapse + * on Execute. + * @return true if the semaphore is successfully posted. + */ + virtual bool Synchronise(); - /** - * @brief Resets the counter and the timer to zero and starts the EmbeddedThread. - * @details See StatefulI::PrepareNextState. Starts the EmbeddedThread (if it was not already started) and loops - * on the ExecuteMethod. - * @return true if the EmbeddedThread can be successfully started. - */ - virtual bool PrepareNextState(const char8 * const currentStateName, - const char8 * const nextStateName); + /** + if (boardFileDescriptor != -1) { + close(boardFileDescriptor); + } + * @brief Callback function for an EmbeddedThread. + * @details Sleeps (Busy or Default) for the period given by 1/Frequency and + post an EventSem which is waiting on + * the Synchronise method. + * @param[in] info not used. + * @return NoError if the EventSem can be successfully posted. + */ + virtual ErrorManagement::ErrorType Execute(ExecutionInfo &info); - /** - * @brief Initialises the AtcaIopADC - * @param[in] data configuration in the form: - * +AtcaIopADC = { - * Class = AtcaIopADC - * Signals = { - * Counter = { - * Type = uint32 //int32 also supported - * } - * Time = { - * Type = uint32 //int32 also supported - * Frequency = 10000 - * } - * ADC0 = { - * Type = uint32 - * } - * ADC1 = { - * Type = uint32 - * } - * ADC2 = { - * Type = uint32 - * } - * ADC3 = { - * Type = uint32 - * } - * } - * } - * @return TODO - */ - virtual bool Initialise(StructuredDataI & data); + /** + * @brief Resets the counter and the timer to zero and starts the + * EmbeddedThread. + * @details See StatefulI::PrepareNextState. Starts the EmbeddedThread (if it + * was not already started) and loops on the ExecuteMethod. + * @return true if the EmbeddedThread can be successfully started. + */ + virtual bool PrepareNextState(const char8 *const currentStateName, + const char8 *const nextStateName); - /** - * @brief Verifies that two, and only two, signal are set with the correct type. - * @details Verifies that two, and only two, signal are set; that the signals are - * 32 bits in size with a SignedInteger or UnsignedInteger type and that a Frequency > 0 was set in one of the two signals. - * @param[in] data see DataSourceI::SetConfiguredDatabase - * @return true if the rules above are met. - */ - virtual bool SetConfiguredDatabase(StructuredDataI & data); + /** + * @brief Initialises the AtcaIopADC + * @param[in] data configuration in the form: + * +AtcaIopADC = { + * Class = AtcaIopADC + * Signals = { + * Counter = { + * Type = uint32 //int32 also supported + * } + * Time = { + * Type = uint32 //int32 also supported + * Frequency = 10000 + * } + * ADC0 = { + * Type = uint32 + * } + * ADC1 = { + * Type = uint32 + * } + * ADC2 = { + * Type = uint32 + * } + * ADC3 = { + * Type = uint32 + * } + * } + * } + * @return TODO + */ + virtual bool Initialise(StructuredDataI &data); - /** - * @brief Gets the affinity of the thread which is going to be used to asynchronously wait for the time to elapse. - * @return the affinity of the thread which is going to be used to asynchronously wait for the time to elapse. - */ - const ProcessorType& GetCPUMask() const; + /** + * @brief Verifies that two, and only two, signal are set with the correct + * type. + * @details Verifies that two, and only two, signal are set; that the signals + * are 32 bits in size with a SignedInteger or UnsignedInteger type and that a + * Frequency > 0 was set in one of the two signals. + * @param[in] data see DataSourceI::SetConfiguredDatabase + * @return true if the rules above are met. + */ + virtual bool SetConfiguredDatabase(StructuredDataI &data); - /** - * @brief Gets the stack size of the thread which is going to be used to asynchronously wait for the time to elapse. - * @return the stack size of the thread which is going to be used to asynchronously wait for the time to elapse. - */ - uint32 GetStackSize() const; + /** + * @brief Gets the affinity of the thread which is going to be used to + * asynchronously wait for the time to elapse. + * @return the affinity of the thread which is going to be used to + * asynchronously wait for the time to elapse. + */ + const ProcessorType &GetCPUMask() const; - /** - * @brief Gets the percentage of the time to sleep using the OS sleep (i.e. the non-busy Sleep). - * @return the percentage of the time to sleep using the OS sleep (i.e. the non-busy Sleep). - */ - uint32 GetSleepPercentage() const; + /** + * @brief Gets the stack size of the thread which is going to be used to + * asynchronously wait for the time to elapse. + * @return the stack size of the thread which is going to be used to + * asynchronously wait for the time to elapse. + */ + uint32 GetStackSize() const; - /** - * Find the currentDMABufferIndex and synchronize on data arrival - */ -// int32 CurrentBufferIndex(uint64 waitLimitUs) const; + /** + * @brief Gets the percentage of the time to sleep using the OS sleep (i.e. + * the non-busy Sleep). + * @return the percentage of the time to sleep using the OS sleep (i.e. the + * non-busy Sleep). + */ + uint32 GetSleepPercentage() const; - private: - /** - * The board identifier - */ - uint32 boardId; - /** - * The numberOfChannels - */ - uint32 numberOfChannels; - /** - * The FPGA ADC Decimation factor from 2MSPS - */ - uint32 rtDecimation; - /** - * The board device name - */ - StreamString deviceName; - /** - * The board device name - */ - //StreamString deviceDmaName; - /** - * The board file descriptor - */ - int32 boardFileDescriptor; + /** + * Find the currentDMABufferIndex and synchronize on data arrival + */ + // int32 CurrentBufferIndex(uint64 waitLimitUs) const; - /** - * The board Dma descriptor - */ - int32 boardDmaDescriptor; +private: + /** + * The board identifier + */ + uint32 boardId; + /** + * The numberOfChannels + */ + uint32 numberOfChannels; + /** + * The FPGA ADC Decimation factor from 2MSPS + */ + uint32 rtDecimation; + /** + * The board device name + */ + StreamString deviceName; + /** + * The board device name + */ + // StreamString deviceDmaName; + /** + * The board file descriptor + */ + int32 boardFileDescriptor; - /** - * The two supported sleep natures. - */ - enum AtcaIopADCSleepNature { - Default = 0, - Busy = 1 - }; + /** + * The board Dma descriptor + */ + int32 boardDmaDescriptor; - /** - * The non-busy sleep percentage. Valid if - * AtcaIopADCSleepNature == Busy - */ - uint32 sleepPercentage; + /** + * The two supported sleep natures. + */ + enum AtcaIopADCSleepNature { Default = 0, Busy = 1 }; - /** - * The selected sleep nature. - */ - AtcaIopADCSleepNature sleepNature; + /** + * The non-busy sleep percentage. Valid if + * AtcaIopADCSleepNature == Busy + */ + uint32 sleepPercentage; - /** - * Debugging - */ - //uint32 execCounter; - //uint32 pollTimout; + /** + * The selected sleep nature. + */ + AtcaIopADCSleepNature sleepNature; - /** - * Current counter and timer - */ - uint32 counterAndTimer[2]; + /** + * Debugging + */ + // uint32 execCounter; + // uint32 pollTimout; - /** - * Timeout counter - */ - uint32 timeoutCount; + /** + * Current counter and timer + */ + uint32 counterAndTimer[2]; - /** - * Timeout counter - */ - uint32 timeoutMax; + /** + * Timeout counter + */ + uint32 timeoutCount; - /** - * ADC values - */ - //int32 adcValues[ATCA_IOP_N_ADCs]; - int32 *adcValues; + /** + * Timeout counter + */ + uint32 timeoutMax; - /** - * ADC Integral values - */ - int64 adcIntegralValues[ATCA_IOP_N_ADCs]; + /** + * ADC values + */ + // int32 adcValues[ATCA_IOP_N_ADCs]; + int32 *adcValues; - /** - * Number of samples to read on each cycle - */ - uint32 adcSamplesPerCycle; - - /** - * The semaphore for the synchronisation between the EmbeddedThread and the Synchronise method. - */ - EventSem synchSem; + /** + * ADC Integral values + */ + int64 adcIntegralValues[ATCA_IOP_N_ADCs]; - /** - * The EmbeddedThread where the Execute method waits for the period to elapse. - */ - SingleThreadService executor; + /** + * Number of samples to read on each cycle + */ + uint32 adcSamplesPerCycle; - /** - * HighResolutionTimer::Counter() value after the last Sleep. - */ - uint64 lastTimeTicks; + /** + * The semaphore for the synchronisation between the EmbeddedThread and the + * Synchronise method. + */ + EventSem synchSem; - /** - * Sleeping period in units of ticks. - */ - uint64 sleepTimeTicks; + /** + * The EmbeddedThread where the Execute method waits for the period to elapse. + */ + SingleThreadService executor; - /** - * Sleeping period. - */ - uint32 timerPeriodUsecTime; + /** + * HighResolutionTimer::Counter() value after the last Sleep. + */ + uint64 lastTimeTicks; - /** - * Index of the function which has the signal that synchronises on this DataSourceI. - */ - uint32 synchronisingFunctionIdx; + /** + * Sleeping period in units of ticks. + */ + uint64 sleepTimeTicks; - /** - * The affinity of the thread that asynchronously generates the time. - */ - ProcessorType cpuMask; + /** + * Sleeping period. + */ + uint32 timerPeriodUsecTime; - /** - * The size of the stack of the thread that asynchronously generates the time. - */ - uint32 stackSize; + /** + * Index of the function which has the signal that synchronises on this + * DataSourceI. + */ + uint32 synchronisingFunctionIdx; - /** - * The simulated signals frequencies. - */ - //float32 signalsFrequencies[4]; + /** + * The affinity of the thread that asynchronously generates the time. + */ + ProcessorType cpuMask; - /** - * The simulated signals gains. - */ + /** + * The size of the stack of the thread that asynchronously generates the time. + */ + uint32 stackSize; - /** - * The Electrical Offset Parameters. - */ - int32 electricalOffsets[ATCA_IOP_N_ADCs]; + /** + * The simulated signals frequencies. + */ + // float32 signalsFrequencies[4]; - /** - * The Wiring Offset Parameters. - */ - float32 wiringOffsets[ATCA_IOP_N_ADCs]; + /** + * The simulated signals gains. + */ - /** - * The ADC chopping period in samples - */ - uint16 chopperPeriod; + /** + * The Electrical Offset Parameters. + */ + int32 electricalOffsets[ATCA_IOP_N_ADCs]; - /** - * The simulated ADC frequency - */ - uint32 adcFrequency; + /** + * The Wiring Offset Parameters. + */ + float32 wiringOffsets[ATCA_IOP_N_ADCs]; - /** - * The simulated ADC period - */ - float64 adcPeriod; + /** + * The ADC chopping period in samples + */ + uint16 chopperPeriod; - /** - * For the ATCA Master board - */ - uint32 isMaster; - /** - * Pointer to mapped memory - */ - //int32 * mappedDmaBase; - void * mappedDmaBase; - uint32 mappedDmaSize; - /** - * The last written buffer - */ - uint8 currentBufferIdx; + /** + * The simulated ADC frequency + */ + uint32 adcFrequency; - /** - * The oldest written DMA buffer index - */ - uint8 oldestBufferIdx; - /** - * The last read buffer index - */ - uint8 lastBufferIdx; + /** + * The simulated ADC period + */ + float64 adcPeriod; - /* - * Find the latest completed buffer without synchronization - */ - int32 GetLatestBufferIndex() const; - uint32 GetOldestBufferIdx() const; - int32 PollDmaBuff(uint64 maxWaitTicks) const; + /** + * For the ATCA Master board + */ + uint32 isMaster; + /** + * Pointer to mapped memory + */ + // int32 * mappedDmaBase; + void *mappedDmaBase; + uint32 mappedDmaSize; + /** + * The last written buffer + */ + uint8 currentBufferIdx; - /** - * filter to receive the RPC which ... - */ - ReferenceT filter; + /** + * The oldest written DMA buffer index + */ + uint8 oldestBufferIdx; + /** + * The last read buffer index + */ + uint8 lastBufferIdx; - }; -} + /* + * Find the latest completed buffer without synchronization + */ + int32 GetLatestBufferIndex() const; + uint32 GetOldestBufferIdx() const; + int32 PollDmaBuff(uint64 maxWaitTicks) const; + + /** + * filter to receive the RPC which ... + */ + ReferenceT filter; +}; +} // namespace MARTe /*---------------------------------------------------------------------------*/ /* Inline method definitions */ diff --git a/DataSources/PSUCommunicator/Makefile.cov b/DataSources/PSUCommunicator/Makefile.cov new file mode 100644 index 0000000..5e0ca6d --- /dev/null +++ b/DataSources/PSUCommunicator/Makefile.cov @@ -0,0 +1,28 @@ +############################################################# +# +# 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 +# +# 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 for the specific language governing +# permissions and limitations under the Licence. +# +############################################################# + +TARGET=cov + +include Makefile.inc + diff --git a/DataSources/PSUCommunicator/Makefile.gcc b/DataSources/PSUCommunicator/Makefile.gcc new file mode 100644 index 0000000..a9d0599 --- /dev/null +++ b/DataSources/PSUCommunicator/Makefile.gcc @@ -0,0 +1,27 @@ +############################################################# +# +# 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 +# +# 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 for the specific language governing +# permissions and limitations under the Licence. +# +############################################################# + + +include Makefile.inc + diff --git a/DataSources/PSUCommunicator/Makefile.inc b/DataSources/PSUCommunicator/Makefile.inc new file mode 100644 index 0000000..cc782a8 --- /dev/null +++ b/DataSources/PSUCommunicator/Makefile.inc @@ -0,0 +1,57 @@ +############################################################# +# +# 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 +# +# 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 for the specific language governing +# permissions and limitations under the Licence. +# +############################################################# + +OBJSX=PSUCommunicatorTX.x UARTConfig.x + +PACKAGE=Components/DataSources + +ROOT_DIR=../.. +MAKEDEFAULTDIR=$(MARTe2_DIR)/MakeDefaults +include $(MAKEDEFAULTDIR)/MakeStdLibDefs.$(TARGET) + +INCLUDES += -I. +INCLUDES += -I./include +INCLUDES += -I$(MARTe2_DIR)/Source/Core/BareMetal/L0Types +INCLUDES += -I$(MARTe2_DIR)/Source/Core/BareMetal/L1Portability +INCLUDES += -I$(MARTe2_DIR)/Source/Core/BareMetal/L2Objects +INCLUDES += -I$(MARTe2_DIR)/Source/Core/BareMetal/L3Streams +INCLUDES += -I$(MARTe2_DIR)/Source/Core/BareMetal/L4Messages +INCLUDES += -I$(MARTe2_DIR)/Source/Core/BareMetal/L4Configuration +INCLUDES += -I$(MARTe2_DIR)/Source/Core/BareMetal/L5GAMs +INCLUDES += -I$(MARTe2_DIR)/Source/Core/Scheduler/L1Portability +INCLUDES += -I$(MARTe2_DIR)/Source/Core/Scheduler/L3Services +INCLUDES += -I$(MARTe2_DIR)/Source/Core/Scheduler/L4Messages +INCLUDES += -I$(MARTe2_DIR)/Source/Core/FileSystem/L1Portability +//INCLUDES += -I$(MARTe2_DIR)/Source/Core/FileSystem/L3Streams + + +all: $(OBJS) \ + $(BUILD_DIR)/PSUCommunicator$(LIBEXT) \ + $(BUILD_DIR)/PSUCommunicator$(DLLEXT) + echo $(OBJS) + +include depends.$(TARGET) + +include $(MAKEDEFAULTDIR)/MakeStdLibRules.$(TARGET) + diff --git a/DataSources/PSUCommunicator/PSUCommunicatorTX.cpp b/DataSources/PSUCommunicator/PSUCommunicatorTX.cpp new file mode 100644 index 0000000..625a41e --- /dev/null +++ b/DataSources/PSUCommunicator/PSUCommunicatorTX.cpp @@ -0,0 +1,441 @@ +/** + * @file PSUCommunicatorTX.cpp + * @brief Source file for class PSUCommunicatorTX + * @date 19/01/2024 + * @author Andre Neto / Bernardo Carvalho + * + * @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. + + * @details This source file contains the definition of all the methods for + * the class PSUCommunicatorTX (public, protected, and private). Be aware + that some + * methods, such as those inline could be defined on the header file, instead. + * + * https://vcis-gitlab.f4e.europa.eu/aneto/MARTe2-components/-/blob/master/Source/Components/DataSources/NI6259/NI6259DAC.cpp + */ + +#define DLL_API + +/*---------------------------------------------------------------------------*/ +/* Standard header includes */ +/*---------------------------------------------------------------------------*/ +#include + +#include +#include // for close() + +/*---------------------------------------------------------------------------*/ +/* Project header includes */ +/*---------------------------------------------------------------------------*/ +#include "AdvancedErrorManagement.h" +#include "MemoryMapSynchronisedOutputBroker.h" +#include "PSUCommunicatorTX.h" +#include "PSUMessages.h" + +/*---------------------------------------------------------------------------*/ +/* Static definitions */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Method definitions */ +/*---------------------------------------------------------------------------*/ +namespace MARTe { +const float32 DAC_RANGE = 20.0; +// const float32 ATCA_IOP_MAX_DAC_RANGE = 20.0; +PSUCommunicatorTX::PSUCommunicatorTX() : DataSourceI(), MessageI() { + // boardFileDescriptor = -1; + // numberOfDACsEnabled = 0u; + // isMaster = 0u; + // deviceName = ""; + // boardId = 2u; + triggerSet = false; + uint32 n; + // for (n = 0u; n < ATCA_IOP_MAX_DAC_CHANNELS; n++) { + // dacEnabled[n] = false; + outputRange = DAC_RANGE; + //} + + // channelsMemory = NULL_PTR(float32 *); + channelValue = 0.0; // NULL_PTR(float32 *); + currentStep = 0.0; + pointOfZeroCurrent = 0.0; + + filter = ReferenceT( + GlobalObjectsDatabase::Instance()->GetStandardHeap()); + filter->SetDestination(this); + ErrorManagement::ErrorType ret = MessageI::InstallMessageFilter(filter); + if (!ret.ErrorsCleared()) { + REPORT_ERROR(ErrorManagement::FatalError, + "Failed to install message filters"); + } +} + +/*lint -e{1551} the destructor must guarantee that the Timer SingleThreadService + * is stopped.*/ +PSUCommunicatorTX::~PSUCommunicatorTX() { + // REPORT_ERROR(ErrorManagement::Information, " Close Device Status Reg %d, + // 0x%x", rc, statusReg); close(boardFileDescriptor); + serial.Close(); + REPORT_ERROR_PARAMETERS(ErrorManagement::Information, "Close %s OK.", + portName); + /* + if (channelsMemory != NULL_PTR(float32 *)) { + delete[] channelsMemory; + } + */ +} + +bool PSUCommunicatorTX::AllocateMemory() { return true; } + +uint32 PSUCommunicatorTX::GetNumberOfMemoryBuffers() { return 1u; } + +/*lint -e{715} [MISRA C++ Rule 0-1-11], [MISRA C++ Rule 0-1-12]. Justification: + * The memory buffer is independent of the bufferIdx.*/ +bool PSUCommunicatorTX::GetSignalMemoryBuffer(const uint32 signalIdx, + const uint32 bufferIdx, + void *&signalAddress) { + bool ok = (signalIdx < (UART_MAX_CHANNELS)); + if (ok) { + // if (channelsMemory != NULL_PTR(float32 *)) { + signalAddress = &channelValue; + //} + } + return ok; +} + +const char8 *PSUCommunicatorTX::GetBrokerName(StructuredDataI &data, + const SignalDirection direction) { + const char8 *brokerName = NULL_PTR(const char8 *); + if (direction == OutputSignals) { + uint32 trigger = 0u; + if (!data.Read("Trigger", trigger)) { + trigger = 0u; + } + + if (trigger == 1u) { + brokerName = "MemoryMapSynchronisedOutputBroker"; + triggerSet = true; + } else { + brokerName = "MemoryMapOutputBroker"; + } + } else { + REPORT_ERROR(ErrorManagement::ParametersError, + "DataSource not compatible with InputSignals"); + } + return brokerName; +} +bool PSUCommunicatorTX::GetInputBrokers(ReferenceContainer &inputBrokers, + const char8 *const functionName, + void *const gamMemPtr) { + return false; +} + +bool PSUCommunicatorTX::GetOutputBrokers(ReferenceContainer &outputBrokers, + const char8 *const functionName, + void *const gamMemPtr) { + // Check if there is a Trigger signal for this function. + uint32 functionIdx = 0u; + uint32 nOfFunctionSignals = 0u; + uint32 i; + bool triggerGAM = false; + bool ok = GetFunctionIndex(functionIdx, functionName); + + if (ok) { + ok = GetFunctionNumberOfSignals(OutputSignals, functionIdx, + nOfFunctionSignals); + } + uint32 trigger = 0u; + for (i = 0u; (i < nOfFunctionSignals) && (ok) && (!triggerGAM); i++) { + ok = GetFunctionSignalTrigger(OutputSignals, functionIdx, i, trigger); + triggerGAM = (trigger == 1u); + } + if ((ok) && (triggerGAM)) { + ReferenceT broker( + "MemoryMapSynchronisedOutputBroker"); + ok = broker.IsValid(); + + if (ok) { + ok = broker->Init(OutputSignals, *this, functionName, gamMemPtr); + } + if (ok) { + ok = outputBrokers.Insert(broker); + } + // Must also add the signals which are not triggering but that belong to the + // same GAM... + if (ok) { + if (nOfFunctionSignals > 1u) { + ReferenceT brokerNotSync( + "MemoryMapOutputBroker"); + ok = brokerNotSync.IsValid(); + if (ok) { + ok = brokerNotSync->Init(OutputSignals, *this, functionName, + gamMemPtr); + } + if (ok) { + ok = outputBrokers.Insert(brokerNotSync); + } + } + } + } else { + ReferenceT brokerNotSync("MemoryMapOutputBroker"); + ok = brokerNotSync.IsValid(); + if (ok) { + ok = brokerNotSync->Init(OutputSignals, *this, functionName, gamMemPtr); + } + if (ok) { + ok = outputBrokers.Insert(brokerNotSync); + } + } + return ok; +} + +/*lint -e{715} [MISRA C++ Rule 0-1-11], [MISRA C++ Rule 0-1-12]. Justification: + * the counter and the timer are always reset irrespectively of the states being + * changed.*/ +bool PSUCommunicatorTX::PrepareNextState(const char8 *const currentStateName, + const char8 *const nextStateName) { + return true; +} + +bool PSUCommunicatorTX::Initialise(StructuredDataI &data) { + bool ok = DataSourceI::Initialise(data); + // StreamString portName; + if (ok) { + ok = data.Read("PortName", portName); + if (ok) { + REPORT_ERROR_PARAMETERS(ErrorManagement::Information, + "The port name is set to %s", portName.Buffer()); + } else { + REPORT_ERROR(ErrorManagement::ParametersError, + "The port name property shall be set"); + } + } + uint32 baudRate = 0u; + if (ok) { + ok = data.Read("BaudRate", baudRate); + if (ok) { + REPORT_ERROR_PARAMETERS(ErrorManagement::Information, + "The baud rate is set to %d", baudRate); + } else { + REPORT_ERROR(ErrorManagement::ParametersError, + "The baud rate property shall be set"); + } + } + if (ok) { + ok = data.Read("CurrentStep", currentStep); + if (ok) { + REPORT_ERROR_PARAMETERS(ErrorManagement::Information, + "The CurrentStep is set to %.2f", currentStep); + } else { + REPORT_ERROR(ErrorManagement::ParametersError, + "The CurrentStep rate property shall be set"); + } + } + if (ok) { + ok = data.Read("PointOfZeroCurrent", pointOfZeroCurrent); + if (ok) { + REPORT_ERROR_PARAMETERS(ErrorManagement::Information, + "The PointOfZeroCurrent is set to %.2f", + currentStep); + } else { + REPORT_ERROR(ErrorManagement::ParametersError, + "The PointOfZeroCurrent rate property shall be set"); + } + } + if (ok) { + if (!data.Read("Timeout", timeout)) { + timeout = 1000u; + } + } + /* + if (ok) { + ok = data.Read("SerialTimeout", serialTimeout); + if (ok) { + REPORT_ERROR(ErrorManagement::Information, "The serial timeout is set to + %d", serialTimeout); + } + else { + REPORT_ERROR(ErrorManagement::ParametersError, "The serial timeout + property shall be set"); + } + } + */ + if (ok) { + ok = serial.SetSpeed(baudRate); + } + if (ok) { + ok = serial.Open(portName.Buffer()); + } + if (!ok) { + REPORT_ERROR_PARAMETERS(ErrorManagement::ParametersError, + "The port %s Not opened.", portName); + } + + // Get individual signal parameters + uint32 i = 0u; + if (ok) { + ok = data.MoveRelative("Signals"); + if (!ok) { + REPORT_ERROR(ErrorManagement::ParametersError, + "Could not move to the Signals section"); + } + // Do not allow to add signals in run-time + if (ok) { + ok = signalsDatabase.MoveRelative("Signals"); + } + if (ok) { + ok = signalsDatabase.Write("Locked", 1u); + } + if (ok) { + ok = signalsDatabase.MoveToAncestor(1u); + } + // while ((i < ATCA_IOP_MAX_DAC_CHANNELS) && (ok)) { + if (data.MoveRelative(data.GetChildName(0))) { + // uint32 channelId; + float64 range; + ok = data.Read("OutputRange", range); + if (ok) { + // if (data.Read("OutputRange", range)) { + ok = (range > 0.0) && (range <= DAC_RANGE); + if (!ok) { + REPORT_ERROR(ErrorManagement::ParametersError, + "Invalid OutputRange specified."); + } + if (ok) { + outputRange = range; + REPORT_ERROR_PARAMETERS(ErrorManagement::Information, + " Parameter DAC Output Range %f", range); + // dacEnabled[i] = true; + // numberOfDACsEnabled++; + } + } else { + REPORT_ERROR(ErrorManagement::ParametersError, + "The OutputRange shall be specified."); + } + if (ok) { + ok = data.MoveToAncestor(1u); + } + } + } + if (ok) { + ok = data.MoveToAncestor(1u); + if (!ok) { + REPORT_ERROR(ErrorManagement::ParametersError, + "Could not move to the parent section"); + } + } + + // REPORT_ERROR_PARAMETERS(ErrorManagement::Information, "numberOfDACsEnabled + // %d", numberOfDACsEnabled); + return ok; +} + +bool PSUCommunicatorTX::SetConfiguredDatabase(StructuredDataI &data) { + uint32 i; + bool ok = DataSourceI::SetConfiguredDatabase(data); + + if (ok) { + ok = triggerSet; + } + if (!ok) { + REPORT_ERROR(ErrorManagement::ParametersError, + "At least one Trigger signal shall be set."); + } + if (ok) { + // for (i = 0u; (i < numberOfDACsEnabled) && (ok); i++) { + ok = (GetSignalType(0u) == Float32Bit); + //} + if (!ok) { + REPORT_ERROR(ErrorManagement::ParametersError, + "All the DAC signals shall be of type Float32Bit"); + } + } + + uint32 nOfFunctions = GetNumberOfFunctions(); + uint32 functionIdx; + // Check that the number of samples for all the signals is one + for (functionIdx = 0u; (functionIdx < nOfFunctions) && (ok); functionIdx++) { + uint32 nOfSignals = 0u; + ok = GetFunctionNumberOfSignals(OutputSignals, functionIdx, nOfSignals); + + for (i = 0u; (i < nOfSignals) && (ok); i++) { + uint32 nSamples = 0u; + ok = GetFunctionSignalSamples(OutputSignals, functionIdx, i, nSamples); + if (ok) { + ok = (nSamples == 1u); + } + if (!ok) { + REPORT_ERROR(ErrorManagement::ParametersError, + "The number of samples shall be exactly one"); + } + } + } + + return ok; +} + +// Create/Decode current packet +bool PSUCommunicatorTX::CreateCurrentPacket(float32 current, char8 *packet) { + + // Calculate the point in the scale of the current + int16 pointOfCurrent = (int16)(pointOfZeroCurrent + current / currentStep); + + // Saturate current + if (pointOfCurrent < FA_SCALE_MIN) + pointOfCurrent = FA_SCALE_MIN; + if (pointOfCurrent > FA_SCALE_MAX) + pointOfCurrent = FA_SCALE_MAX; + + // Build packets + uint16 pc = (uint16)pointOfCurrent; + uint16 nc = ~pc; + packet[0] = (char8)(0x0000 | ((nc & 0x03C0) >> 5) | ((pc & 0x0007) << 5)); + packet[1] = (char8)(0x0001 | ((pc & 0x03F8) >> 2)); + + return true; +} + +bool PSUCommunicatorTX::Synchronise() { + uint32 i; + int32 w = 24; + bool ok = true; + char8 text[] = "ola"; + // if (channelsMemory != NULL_PTR(float32 *)) { + + // value = channelsMemory[0] / DAC_RANGE; + // for (i = 0u; (i < numberOfDACsEnabled ) && (ok); i++) { + int32 ser_value = channelValue / outputRange * 1000000.0; + REPORT_ERROR_PARAMETERS(ErrorManagement::Information, + "Synchronise called. value: %f, %d", channelValue, + ser_value); + // w = SetDacReg(i, value); + char8 *data = reinterpret_cast(&ser_value); + serial.Write(data, sizeof(int32)); + // serial.Write(text, 4); + // write(boardFileDescriptor, &w, 4); + // value = channelsMemory[1] / DAC_RANGE; + // value = channelsMemory[1] / DAC_RANGE * pow(2,17); + // w = SetDacReg(1, value); + // w = 0x000FFFFF & static_cast(value); + // write(boardFileDescriptor, &w, 4); + // REPORT_ERROR(ErrorManagement::Information, " Writing DAC 0 0x%x", w); + /* + + w = dacValues[i]; + } + */ + return ok; +} +CLASS_REGISTER(PSUCommunicatorTX, "1.0") +} // namespace MARTe + // vim: syntax=cpp ts=2 sw=2 sts=2 sr et diff --git a/DataSources/PSUCommunicator/PSUCommunicatorTX.h b/DataSources/PSUCommunicator/PSUCommunicatorTX.h new file mode 100644 index 0000000..d57bb74 --- /dev/null +++ b/DataSources/PSUCommunicator/PSUCommunicatorTX.h @@ -0,0 +1,273 @@ +/** + * @file PSUCommunicatorTX.h + * @brief Header file for class PSUCommunicatorTX + * @date 19/01/2024 + * @author Andre Neto / Bernardo Carvalho + * + * Based on Example: + * https://vcis-gitlab.f4e.europa.eu/aneto/MARTe2-demos-padova/-/tree/master/DataSources/ADCSimulator + * + * + * @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. + + * @details This header file contains the declaration of the class + PSUCommunicatorTX + * with all of its public, protected and private members. It may also include + * definitions for inline methods which need to be visible to the compiler. + */ + +#ifndef PSUCOMMUNICATOR_TX_H +#define PSUCOMMUNICATOR_TX_H + +/*---------------------------------------------------------------------------*/ +/* Standard header includes */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Project header includes */ +/*---------------------------------------------------------------------------*/ +#include "DataSourceI.h" +#include "EmbeddedServiceMethodBinderI.h" +#include "EventSem.h" +#include "MessageI.h" +#include "RegisteredMethodsMessageFilter.h" +#include "SingleThreadService.h" + +#include "UARTConfig.h" +/*---------------------------------------------------------------------------*/ +/* Class declaration */ +/*---------------------------------------------------------------------------*/ +namespace MARTe { + +/** + * The number of signals + */ + +const uint32 UART_MAX_CHANNELS = 1u; + +/** + * @brief A DataSource which provides an analogue output interface to the ATCA + IOP boards. + * @details The configuration syntax is (names are only given as an example): + * + *
+ * +AtcaIop_UartOut = {
+ *     Class = PSUCommunicator::PSUCommunicatorTX
+ *     PortName = "/dev/ttyUSB0" //Name of the UART port, Mandatory
+ *     BaudRate = 115200 //BAUD UART rate
+ *     //Timeout = 200000 //Maximum time to wait for data
+ *     CPUMask = 8 //Affinity of the CPU of where to read data from
+ *     CurrentStep =
+ *     PointOfZeroCurrent =
+ *     Signals = {
+ *         SerialOut = {
+ *             Type = float32//Mandatory. Only type that is supported.
+ *             OutputRange = 10.0 //Mandatory. The channel Module Output Range
+ in volt.
+ *             //OutputPolarity = Bipolar //Optional. Possible values: Bipolar,
+ Unipolar. Default value Unipolar.
+ *         }
+ *          Packet = { //Actual data to write
+ *         Type = uint8
+ *         NumberOfElements = 15
+ *       }
+
+ *     }
+ * }
+ * 
+ * Note that at least one of the GAMs writing to this DataSource must have set + one of the signals with Trigger=1 (which forces the writing of all the signals + to the DAC). + */ +class PSUCommunicatorTX : public DataSourceI, public MessageI { +public: + CLASS_REGISTER_DECLARATION() + /** + * @brief Default constructor + * @post + * Counter = 0 + * Time = 0 + */ + PSUCommunicatorTX(); + + /** + * @brief Destructor. Stops the EmbeddedThread. + */ + virtual ~PSUCommunicatorTX(); + + /** + * @brief See DataSourceI::AllocateMemory. + * * @return true. + */ + virtual bool AllocateMemory(); + + /** + gg* @brief See DataSourceI::GetNumberOfMemoryBuffers. + * @return 1. + */ + virtual uint32 GetNumberOfMemoryBuffers(); + + /** + * @brief See DataSourceI::GetSignalMemoryBuffer. + */ + virtual bool GetSignalMemoryBuffer(const uint32 signalIdx, + const uint32 bufferIdx, + void *&signalAddress); + + /** + * @brief See DataSourceI::GetNumberOfMemoryBuffers. + * @details Only OutputSignals are supported. + * @return MemoryMapSynchronisedOutputBroker if Trigger == 1 for any of the + * signals, MemoryMapOutputBroker otherwise. + */ + virtual const char8 *GetBrokerName(StructuredDataI &data, + const SignalDirection direction); + + /** + * @brief See DataSourceI::GetInputBrokers. + * @return false. + */ + virtual bool GetInputBrokers(ReferenceContainer &inputBrokers, + const char8 *const functionName, + void *const gamMemPtr); + + /** + * @brief See DataSourceI::GetOutputBrokers. + * @details If the functionName is one of the functions which requested a + * Trigger, it adds a MemoryMapSynchronisedOutputBroker instance to the + * outputBrokers, otherwise it adds a MemoryMapOutputBroker instance to the + * outputBrokers. + * @param[out] outputBrokers where the BrokerI instances have to be added to. + * @param[in] functionName name of the function being queried. + * @param[in] gamMemPtr the GAM memory where the signals will be read from. + * @return true if the outputBrokers can be successfully configured. + */ + virtual bool GetOutputBrokers(ReferenceContainer &outputBrokers, + const char8 *const functionName, + void *const gamMemPtr); + + /** + * @brief See StatefulI::PrepareNextState. + * @details NOOP. + * @return true. + */ + virtual bool PrepareNextState(const char8 *const currentStateName, + const char8 *const nextStateName); + + /** + * @brief Loads and verifies the configuration parameters detailed in the + * class description. + * @return true if all the mandatory parameters are correctly specified and if + * the specified optional parameters have valid values. + */ + + virtual bool Initialise(StructuredDataI &data); + + /** + * @brief Final verification of all the parameters and setup of the board + * configuration. + * @details This method verifies that all the parameters (e.g. number of + * samples) requested by the GAMs interacting with this DataSource are valid + * and consistent with the board parameters set during the initialisation + * phase. In particular the following conditions shall be met: + * - At least one triggering signal was requested by a GAM (with the property + * Trigger = 1) + * - All the DAC channels have type float32. + * - The number of samples of all the DAC channels is exactly one. + * @return true if all the parameters are valid and consistent with the board + * parameters and if the board can be successfully configured with these + * parameters. + */ + virtual bool SetConfiguredDatabase(StructuredDataI &data); + + /** + * @details Writes the value of all the DAC channels to the board. + * @return true if the writing of all the channels is successful. + */ + virtual bool Synchronise(); + +private: + /** + * The board device name + */ + StreamString portName; + /** + * The board identifier + */ + uint32 boardId; + /** + * The board file descriptor + */ + // int32 boardFileDescriptor; + /** + * The UART interface. + */ + UARTConfig serial; + + /** + * Timeout to wait for data to be available. + */ + // uint32 serialTimeout; + + /** + */ + uint32 timeout; + + /** + * DAC values + */ + // int32 dacValues[ATCA_IOP_N_DACs]; + + /** + * The signal memory + */ + float32 channelValue; + float32 currentStep; + float32 pointOfZeroCurrent; + /** + * The DACs that are enabled + */ + // bool dacEnabled[ATCA_IOP_MAX_DAC_CHANNELS]; + + /** + * The board individual channel output ranges + */ + float32 outputRange; + + /** + * The number of enabled DACs + */ + uint32 numberOfDACsEnabled; + + /** + * Filter to receive the RPC which allows to change the... + */ + ReferenceT filter; + + /** + * True if at least one trigger was set. + */ + bool triggerSet; + + // int32 SetDacReg(uint32 channel, float32 val) const; + bool CreateCurrentPacket(float32 current, char8 *packet); +}; +} // namespace MARTe + +/*---------------------------------------------------------------------------*/ +/* Inline method definitions */ +/*---------------------------------------------------------------------------*/ + +#endif /* PSUCOMMUNICATOR_TX_H */ + +// vim: syntax=cpp ts=2 sw=2 sts=2 sr et diff --git a/DataSources/PSUCommunicator/PSUMessages.h b/DataSources/PSUCommunicator/PSUMessages.h new file mode 100644 index 0000000..45814db --- /dev/null +++ b/DataSources/PSUCommunicator/PSUMessages.h @@ -0,0 +1,74 @@ +/** + * @file PSUMessages.h + * @brief Header file + * @date 25/10/2025 + * @author Bernardo Carvalho + * + * + * @copyright Copyright 2025 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. + + * @details This header file contains the declaration of the class AtcaIopADC + * with all of its public, protected and private members. It may also include + * definitions for inline methods which need to be visible to the compiler. + */ +#define FA_CHARGE_MESSAGE_1 0x6C +#define FA_CHARGE_MESSAGE_2 0x6D +#define FA_SHUTDOWN_MESSAGE_1 0x92 +#define FA_SHUTDOWN_MESSAGE_2 0x93 +#define FA_STARTOP_MESSAGE_1 0xFE +#define FA_STARTOP_MESSAGE_2 0xFF +#define FA_STOPOP_MESSAGE_1 0x00 +#define FA_STOPOP_MESSAGE_2 0x01 + +#define FA_STARTED_MESSAGE_1 0xFE +#define FA_STARTED_MESSAGE_2 0xFF +#define FA_STOPPED_MESSAGE_1 0x00 +#define FA_STOPPED_MESSAGE_2 0x01 +#define FA_STOP_ERROR_MESSAGE_1 0x24 +#define FA_STOP_ERROR_MESSAGE_2 0x25 +#define FA_COMM_ERROR_MESSAGE_1 0xDA +#define FA_COMM_ERROR_MESSAGE_2 0xDB + +#define FA_COMMUNICATION_MAX_PACKETS 4 +#define FA_FRAMING_BIT_MASK 0x01 + +#define FA_SCALE_MIN 0 +#define FA_SCALE_MAX 1023 + +#define LOG_CHARGE 1 +#define LOG_SHUTDOWN 2 +#define LOG_STARTOP 3 +#define LOG_STOPOP 4 +#define LOG_TEMPERATURE_FAULT 5 +#define LOG_24V_FAULT 6 +#define LOG_CHARGED 7 +#define LOG_NOT_CHARGED 8 +#define LOG_STARTED 9 +#define LOG_STOPPED 10 +#define LOG_STOP_FAULT 11 +#define LOG_COMMUNICATION_FAULT 12 +#define LOG_CURRENT_VALUE 13 + +// Logging #defines +// #define __FA_COM_LOG_RECEIVED_MESSAGES +// #define ___FA_COM_LOG_SENT_MESSAGES +#define __FA_COM_LOG_LEVEL InitialisationError + +// Communicator Online Stages +#define FA_COMMUNICATOR_ONLINE_IDLE 0 +#define FA_COMMUNICATOR_ONLINE_WAIT_CODAC_TRIGGER 1 +#define FA_COMMUNICATOR_ONLINE_DISCHARGE 2 +#define FA_COMMUNICATOR_ONLINE_STOP_OPERATION 3 +#define FA_COMMUNICATOR_ONLINE_ERROR 4 + +#define FA_COMMUNICATOR_MAXIMUM_ATTEMPTS 5 diff --git a/DataSources/PSUCommunicator/UARTConfig.cpp b/DataSources/PSUCommunicator/UARTConfig.cpp new file mode 100644 index 0000000..ef3f7d6 --- /dev/null +++ b/DataSources/PSUCommunicator/UARTConfig.cpp @@ -0,0 +1,375 @@ +/** + * @file UARTConfig.cpp + * @brief Source file for class UARTConfig. + * @date 07/08/2018 + * @author Andre Neto + * @author Pedro Lourenco + * + * @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. + * + * @details This source file contains the definition of all the methods for + * the class UARTConfig (public, protected, and private). Be aware that some + * methods, such as those inline could be defined on the header file, instead. + */ + +/*---------------------------------------------------------------------------*/ +/* Standard header includes */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Project header includes */ +/*---------------------------------------------------------------------------*/ +#include "UARTConfig.h" + +/*---------------------------------------------------------------------------*/ +/* Static definitions */ +/*---------------------------------------------------------------------------*/ +/*lint -e628 []. Justification: Argument 'errno' of 'strerror()' provided + via .*/ +/*lint -e10 []. Justification: '}' present.*/ + +/*lint -e{9141} [MISRA C++ Rule 7-3-1]. Justification: 'SpeedTable' declared " + "as global.*/ +struct SpeedTable { + MARTe::int32 code; + MARTe::uint32 speed; +}; + +/*lint -e{9141} [MISRA C++ Rule 7-3-1]. Justification: 'speedTable' declared " + "as global.*/ +const SpeedTable speedTable[] = {{B0, 0u}, + {B50, 50u}, + {B75, 75u}, + {B110, 110u}, + {B134, 134u}, + {B150, 150u}, + {B200, 200u}, + {B300, 300u}, + {B600, 600u}, + {B1200, 1200u}, + {B1800, 1800u}, + {B2400, 2400u}, + {B4800, 4800u}, + {B9600, 9600u}, + {B19200, 19200u}, + {B38400, 38400u}, + {B57600, 57600u}, + {B115200, 115200u}, + {B230400, 230400u}, + {B460800, 460800u}, + {B500000, 500000u}, + {B576000, 576000u}, + {B921600, 921600u}, + {B1000000, 1000000u}, + {B1152000, 1152000u}, + {B1500000, 1500000u}, + {B2000000, 2000000u}, + {B2500000, 2500000u}, + {B3000000, 3000000u}, + {B3500000, 3500000u}, + {B4000000, 4000000u}}; + +/*---------------------------------------------------------------------------*/ +/* Method definitions */ +/*---------------------------------------------------------------------------*/ +namespace MARTe { + +/*lint -e{1401} [MISRA C++ Rule 8-5-1]. Justification: FD_ZERO arguments + correctly initialised.*/ +UARTConfig::UARTConfig() { + + properties.fileDescriptor = -1; + properties.speedCode = B19200; + FD_ZERO(&properties.readFDS); + FD_ZERO(&properties.readFDS_done); + FD_ZERO(&properties.writeFDS); + FD_ZERO(&properties.writeFDS_done); +} + +UARTConfig::~UARTConfig() { + /*lint -e{1551} []. Justification: thrown exception non critical.*/ + Close(); +} + +bool UARTConfig::SetSpeed(const uint32 speed) { + + bool ok = (properties.fileDescriptor == -1); + if (ok) { + int32 ix = 0; + while ((speedTable[ix].code != __MAX_BAUD) && + (speed > speedTable[ix].speed)) { + ix++; + } + properties.speedCode = speedTable[ix].code; + ok = (speed == speedTable[ix].speed); + } + + return ok; +} +/*lint -e{952} [MISRA C++ Rule 7-1-1]. Justification: Parameter 'name' + kept as non const.*/ +bool UARTConfig::Open(const char8 *name) { + + // Info from termios.h: + // c_iflag - input modes; + // c_oflag - output modes; + // c_cflag - control modes; + // c_lflag - local modes; + // c_cc[NCCS] - special characters. + + bool ok = (properties.fileDescriptor == -1); + if (ok) { + ok = (name != NULL); + } + if (ok) { + /*lint -e{9130} [MISRA C++ Rule 5-0-21]. Justification: Known bitwise + operation over signed type.*/ + properties.fileDescriptor = open(name, O_RDWR | O_NOCTTY | O_NONBLOCK); + if (properties.fileDescriptor == -1) { + REPORT_ERROR_STATIC(ErrorManagement::OSError, + "UARTConfig::Open - " + "cannot open serial device %s.", + name); + ok = false; + } + FD_SET(properties.fileDescriptor, &properties.readFDS); + FD_SET(properties.fileDescriptor, &properties.writeFDS); + } + if (ok) { + struct termios newtio; + // Clean all settings + cfmakeraw(&newtio); + // Eight Data bits + // CSIZE - Character size mask. Values are CS5, CS6, CS7, or CS8. + /*lint -e{9130} [MISRA C++ Rule 5-0-21]. Justification: Known bitwise + operations over signed types.*/ + /*lint -e{9117} [MISRA C++ Rule 5-0-4]. Justification: Known signedness + change due to implicit conversion.*/ + /*lint -e{737} []. Justification: Known loss of signedness.*/ + newtio.c_cflag = (newtio.c_cflag & ~CSIZE) | CS8 | properties.speedCode; + // CLOCAL - Ignore modem control lines. + // CREAD - Enable receiver. + /*lint -e{9130} [MISRA C++ Rule 5-0-21]. Justification: Known bitwise + operations over signed types.*/ + /*lint -e{9117} [MISRA C++ Rule 5-0-4]. Justification: Known signedness + change due to implicit conversion.*/ + newtio.c_cflag |= (CLOCAL | CREAD); + // Parity Odd: + // PARENB - Enable parity generation on output and parity checking for + // input. + // PARODD - If set, then parity for input and output is odd; otherwise + // even parity is used. + /*lint -e{9130} [MISRA C++ Rule 5-0-21]. Justification: Known bitwise + operations over signed types.*/ + /*lint -e{9117} [MISRA C++ Rule 5-0-4]. Justification: Known signedness + change due to implicit conversion.*/ + newtio.c_cflag |= (PARENB | PARODD); + // No hardware handshake: + // CRTSCTS - Enable RTS/CTS (hardware) flow control. + /*lint -e{9130} [MISRA C++ Rule 5-0-21]. Justification: Known bitwise + operations over signed types.*/ + /*lint -e{9105} [MISRA C++ Rule 2-13-3]. Justification: Known U suffix + missing.*/ + newtio.c_cflag &= ~CRTSCTS; + // Two stopbit: + // CSTOPB - Set two stop bits, rather than one. + /*lint -e{9130} [MISRA C++ Rule 5-0-21]. Justification: Known bitwise + operations over signed types.*/ + /*lint -e{9117} [MISRA C++ Rule 5-0-4]. Justification: Known signedness + change due to implicit conversion.*/ + newtio.c_cflag |= CSTOPB; + // IGNBRK - Ignore BREAK condition on input. + // newtio.c_iflag = IGNBRK; + // Software handshake: + // IXON - Enable XON/XOFF flow control on output. + // IXANY - Typing any character will restart stopped output. + // IXOFF - Enable XON/XOFF flow control on input. + // newtio.c_iflag |= (IXON | IXOFF | IXANY); + /*lint -e{9130} [MISRA C++ Rule 5-0-21]. Justification: Known bitwise + operations over signed types.*/ + /*lint -e{9117} [MISRA C++ Rule 5-0-4]. Justification: Known signedness + change due to implicit conversion.*/ + newtio.c_iflag &= ~(IXON | IXOFF | IXANY); + // Non cannonical mode + // ICANON - Enable canonical mode. + // ECHO - Echo input characters. + // ECHOE - If ICANON is also set, the ERASE character erases the + // preceding input character, and WERASE erases the preceding word. + // ISIG - When any of the characters INTR, QUIT, SUSP, or DSUSP are + // received, generate the corresponding signal. + /*lint -e{9130} [MISRA C++ Rule 5-0-21]. Justification: Known bitwise + operations over signed types.*/ + /*lint -e{9117} [MISRA C++ Rule 5-0-4]. Justification: Known signedness + change due to implicit conversion.*/ + newtio.c_iflag &= ~(ICANON | ECHO | ECHOE | ISIG); + newtio.c_lflag = 0u; + newtio.c_oflag = 0u; + // VMIN - Minimum number of characters for noncanonical read (MIN). + newtio.c_cc[VMIN] = 1u; + // VTIME - Timeout in deciseconds for noncanonical read (TIME). + newtio.c_cc[VTIME] = 5u; + + ok = (cfsetspeed(&newtio, static_cast(properties.speedCode)) == 0); + ErrorManagement::ErrorType errorCode = + ok ? ErrorManagement::Information : ErrorManagement::OSError; + REPORT_ERROR_STATIC(errorCode, + "UARTConfig::Open - %s serial device %s " + "speed to %u.", + ok ? "successfully set" : "could not set", name, + properties.speedCode); + + if (ok) { + ok = (tcsetattr(properties.fileDescriptor, TCSANOW, &newtio) != -1); + errorCode = ok ? ErrorManagement::Information : ErrorManagement::OSError; + REPORT_ERROR_STATIC(errorCode, + "UARTConfig::Open - %s serial device " + "parameters.", + ok ? "successfully set" : "could not set"); + } + } + + return ok; +} + +void UARTConfig::Close() { + + if (properties.fileDescriptor != -1) { + int32 err = close(properties.fileDescriptor); + bool ok = (err == 0); + ErrorManagement::ErrorType errorCode = + ok ? ErrorManagement::Information : ErrorManagement::OSError; + REPORT_ERROR_STATIC(errorCode, + "UARTConfig::Close - %s serial " + "interface.", + ok ? "closed" : "failed to close"); + properties.fileDescriptor = -1; + } +} + +/*lint -e{952} [MISRA C++ Rule 7-1-1]. Justification: Parameter 'buffer' kept + as non const.*/ +/*lint -e{1762} [MISRA C++ Rule 9-3-3]. Justification: Member function :Read() + kept as non const.*/ +bool UARTConfig::Read(char8 *buffer, uint32 &size) { + + size_t readSize = static_cast(size); + ssize_t readBytes = read(properties.fileDescriptor, buffer, readSize); + size = static_cast(readBytes); + bool ok = (readBytes == static_cast(size)); + + // ErrorManagement::ErrorType errorCode = ok ? + // ErrorManagement::Information : + // ErrorManagement::OSError; + // REPORT_ERROR_STATIC(errorCode, "UARTConfig::Read - read %d bytes, " + // "requested %u.", static_cast(readBytes), + // static_cast(readSize)); + + return ok; +} + +/*lint -e{952} [MISRA C++ Rule 7-1-1]. Justification: Parameter 'buffer' kept + as non const.*/ +bool UARTConfig::Read(char8 *buffer, uint32 &size, const uint32 timeoutUsec) { + + bool ok = true; + size_t leftToRead = static_cast(size); + void *rbuffer = &buffer[0u]; + while ((leftToRead > 0u) && (ok)) { + ok = WaitRead(timeoutUsec); + if (ok) { + ssize_t readBytes = read(properties.fileDescriptor, rbuffer, leftToRead); + ok = (readBytes > 0); + if (ok) { + leftToRead -= static_cast(readBytes); + uint32 idx = size - static_cast(leftToRead); + rbuffer = &buffer[idx]; + } + ErrorManagement::ErrorType errorCode = + ok ? ErrorManagement::Information : ErrorManagement::OSError; + StreamString errorMessage; + /*lint -e{1055} [MISRA C++ Rule 14-8-2]. Justification: Symbol + 'strerror' declared.*/ + /*lint -e{746} []. Justification: Prototype not present in + MARTe::strerror().*/ + (void)errorMessage.Printf(" with error %s.", strerror(errno)); + // Error only verbosity, comment condition if needed. + if (!ok) { + /*lint -e{578} [MISRA C++ Rule 2-10-2]. Justification: Symbol + 'Buffer' has an identical name as a global + symbol 'buffer'.*/ + REPORT_ERROR_STATIC(errorCode, + "UARTConfig::Read - %s read %d " + "bytes%s", + ok ? "" : "failed to", + static_cast(readBytes), + ok ? "." : errorMessage.Buffer()); + } + } + } + size = (size - static_cast(leftToRead)); + + return ok; +} + +/*lint -e{952} [MISRA C++ Rule 7-1-1]. Justification: Parameter 'size' kept as + non const.*/ +/*lint -e{1762} [MISRA C++ Rule 9-3-3]. Justification: Member function :Read() + kept as non const.*/ +/*lint -e{818} [MISRA C++ Rule 7-1-1]. Justification: Parameter 'size' kept as + non const.*/ +bool UARTConfig::Write(char8 *buffer, uint32 size) { + + size_t writeSize = static_cast(size); + ssize_t writtenBytes = write(properties.fileDescriptor, buffer, writeSize); + bool ok = (writtenBytes == static_cast(writeSize)); + + // ErrorManagement::ErrorType errorCode = ok ? + // ErrorManagement::Information : + // ErrorManagement::OSError; + // REPORT_ERROR_STATIC(errorCode, "UARTConfig::Write - wrote %d bytes, " + // "requested %u.", static_cast(writtenBytes), size); + + return ok; +} + +bool UARTConfig::WaitRead(const uint32 timeoutUsec) { + + struct timeval timeWait; + uint32 tmp = timeoutUsec / 1000000u; + timeWait.tv_sec = static_cast(tmp); + tmp = timeoutUsec % 1000000u; + timeWait.tv_usec = static_cast(tmp); + properties.readFDS_done = properties.readFDS; + int32 readyCount = + select(properties.fileDescriptor + 1, &properties.readFDS_done, + NULL_PTR(fd_set *), NULL_PTR(fd_set *), &timeWait); + + return (readyCount > 0); +} + +bool UARTConfig::WaitWrite(const uint32 timeoutUsec) { + + struct timeval timeWait; + uint32 tmp = timeoutUsec / 1000000u; + timeWait.tv_sec = static_cast(tmp); + tmp = timeoutUsec % 1000000u; + timeWait.tv_usec = static_cast(tmp); + properties.writeFDS_done = properties.writeFDS; + int32 readyCount = + select(properties.fileDescriptor + 1, NULL_PTR(fd_set *), + &properties.writeFDS_done, NULL_PTR(fd_set *), &timeWait); + + return (readyCount > 0); +} + +} // namespace MARTe diff --git a/DataSources/PSUCommunicator/UARTConfig.h b/DataSources/PSUCommunicator/UARTConfig.h new file mode 100644 index 0000000..81446fd --- /dev/null +++ b/DataSources/PSUCommunicator/UARTConfig.h @@ -0,0 +1,164 @@ +/** + * @file UARTConfig.h + * @brief Header file for class UARTConfig. + * @date 16/08/2021 + * @author Filippo Sartori + * @author Pedro Lourenco + * + * @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. + * + * @details This header file contains the declaration of the class UARTConfig + * with all of its public, protected and private members. It may also include + * definitions for inline methods which need to be visible to the compiler. + */ + +#ifndef UARTCONFIG_H_ +#define UARTCONFIG_H_ + +/*---------------------------------------------------------------------------*/ +/* Standard header includes */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Project header includes */ +/*---------------------------------------------------------------------------*/ +#include "AdvancedErrorManagement.h" +#include "CompilerTypes.h" +#include "GeneralDefinitions.h" +#include "StreamString.h" +#include INCLUDE_FILE_ENVIRONMENT(FileSystem, L1Portability, ENVIRONMENT, BasicUARTProperties.h) + +/*---------------------------------------------------------------------------*/ +/* Class declaration */ +/*---------------------------------------------------------------------------*/ + +namespace MARTe { + +/** + * @brief UART implementation based on the Linux general terminal interface + * that is provided to control asynchronous communications ports. + * @details Some of termio parameters are hard-coded as follows: + * - eight data bits; + * - no parity bit; + * - one stop bit; + * - noncanonical input processing mode. + */ +class DLL_API UARTConfig { +public: + /** + * @brief Default constructor. + * @details FD_ZERO the file descriptors. + */ + UARTConfig(); + + /** + * @brief Destructor. + * @details Calls Close(). + */ + virtual ~UARTConfig(); + + /** + * @brief Sets the speed of the UART. Shall be called before the Open + * method. + * @param[in] serial the speed to set. + * @return true if the speed was successfully updated. + */ + bool SetSpeed(const uint32 speed); + + /** + * @brief Opens the UART described by the provided \a name. + * @details The UART is open in read/write mode. Many of the UART + * properties are hard-coded for the CRIO use-case. + * @param[in] name the UART file descriptor location. + * @pre + * SetSpeed + */ + bool Open(const char8 *name); + + /** + * @brief Closes the UART. + * @pre + * Open + */ + void Close(); + + /** + * @brief Reads \a size bytes into the \a buffer. + * @param[in] buffer the memory where to write the read bytes. + * @param[in,out] size the number of bytes to read and the number of bytes + * that were actually read. + * @return true if the Read operation completes successfully (and reads all + * the requested bytes). + * @pre + * Open + */ + bool Read(char8 *buffer, uint32 &size); + + /** + * @brief Reads \a size bytes into the \a buffer within \a timeoutUsec + * micro-seconds. + * @param[in] buffer the memory where to write the read bytes. + * @param[in,out] size the number of bytes to read and the number of bytes + * that were actually read. + * @param[in] timeoutUsec the maximum time to complete the read operation. + * @return true if the Read operation completes successfully within the + * timeout (and reads all the requested bytes). + * @pre + * Open + */ + bool Read(char8 *buffer, uint32 &size, const uint32 timeoutUsec); + + /** + * @brief Waits \a timeoutUsec micro-seconds for data to be available for + * reading in the UART. + * @param[in] timeoutUsec the maximum time to wait for data to be + * available. + * @return true if data is available to be read within the timeout. + */ + bool WaitRead(const uint32 timeoutUsec); + + /** + * @brief Writes \a size bytes from the \a buffer. + * @param[in] buffer the memory where to read the bytes to write. + * @param[in] size the number of bytes to write. + * @param[in] timeoutUsec the maximum time to complete the read operation. + * @return true if the Read operation completes successfully within the + * timeout (and reads all the requested bytes). + * @pre + * Open + */ + bool Write(char8 *buffer, uint32 size); + + /** + * @brief Waits \a timeoutUsec micro-seconds for the UART to be available + * for writing data. + * @param[in] timeoutUsec the maximum time to wait for the write to be + * available. + * @return true if the UART is available to write within the timeout. + */ + bool WaitWrite(const uint32 timeoutUsec); + +private: + /** + * Structure with variables/parameters for different Environments. + */ + BasicUARTProperties properties; +}; + +} // namespace MARTe + +/*---------------------------------------------------------------------------*/ +/* Inline method definitions */ +/*---------------------------------------------------------------------------*/ + +#endif /* UARTCONFIG_H_ */