New Datasource
This commit is contained in:
28
DataSources/PSUCommunicator/Makefile.cov
Normal file
28
DataSources/PSUCommunicator/Makefile.cov
Normal file
@@ -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
|
||||
|
||||
27
DataSources/PSUCommunicator/Makefile.gcc
Normal file
27
DataSources/PSUCommunicator/Makefile.gcc
Normal file
@@ -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
|
||||
|
||||
57
DataSources/PSUCommunicator/Makefile.inc
Normal file
57
DataSources/PSUCommunicator/Makefile.inc
Normal file
@@ -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)
|
||||
|
||||
441
DataSources/PSUCommunicator/PSUCommunicatorTX.cpp
Normal file
441
DataSources/PSUCommunicator/PSUCommunicatorTX.cpp
Normal file
@@ -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 <fcntl.h>
|
||||
|
||||
#include <math.h>
|
||||
#include <unistd.h> // 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<RegisteredMethodsMessageFilter>(
|
||||
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<MemoryMapSynchronisedOutputBroker> 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<MemoryMapOutputBroker> brokerNotSync(
|
||||
"MemoryMapOutputBroker");
|
||||
ok = brokerNotSync.IsValid();
|
||||
if (ok) {
|
||||
ok = brokerNotSync->Init(OutputSignals, *this, functionName,
|
||||
gamMemPtr);
|
||||
}
|
||||
if (ok) {
|
||||
ok = outputBrokers.Insert(brokerNotSync);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ReferenceT<MemoryMapOutputBroker> 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<char8 *>(&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<uint32>(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
|
||||
273
DataSources/PSUCommunicator/PSUCommunicatorTX.h
Normal file
273
DataSources/PSUCommunicator/PSUCommunicatorTX.h
Normal file
@@ -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):
|
||||
*
|
||||
* <pre>
|
||||
* +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
|
||||
* }
|
||||
|
||||
* }
|
||||
* }
|
||||
* </pre>
|
||||
* 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<RegisteredMethodsMessageFilter> 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
|
||||
74
DataSources/PSUCommunicator/PSUMessages.h
Normal file
74
DataSources/PSUCommunicator/PSUMessages.h
Normal file
@@ -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
|
||||
375
DataSources/PSUCommunicator/UARTConfig.cpp
Normal file
375
DataSources/PSUCommunicator/UARTConfig.cpp
Normal file
@@ -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 <errno.h>.*/
|
||||
/*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<uint32>(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_t>(size);
|
||||
ssize_t readBytes = read(properties.fileDescriptor, buffer, readSize);
|
||||
size = static_cast<uint32>(readBytes);
|
||||
bool ok = (readBytes == static_cast<ssize_t>(size));
|
||||
|
||||
// ErrorManagement::ErrorType errorCode = ok ?
|
||||
// ErrorManagement::Information :
|
||||
// ErrorManagement::OSError;
|
||||
// REPORT_ERROR_STATIC(errorCode, "UARTConfig::Read - read %d bytes, "
|
||||
// "requested %u.", static_cast<int32>(readBytes),
|
||||
// static_cast<uint32>(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_t>(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<size_t>(readBytes);
|
||||
uint32 idx = size - static_cast<uint32>(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<int32>(readBytes),
|
||||
ok ? "." : errorMessage.Buffer());
|
||||
}
|
||||
}
|
||||
}
|
||||
size = (size - static_cast<uint32>(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_t>(size);
|
||||
ssize_t writtenBytes = write(properties.fileDescriptor, buffer, writeSize);
|
||||
bool ok = (writtenBytes == static_cast<ssize_t>(writeSize));
|
||||
|
||||
// ErrorManagement::ErrorType errorCode = ok ?
|
||||
// ErrorManagement::Information :
|
||||
// ErrorManagement::OSError;
|
||||
// REPORT_ERROR_STATIC(errorCode, "UARTConfig::Write - wrote %d bytes, "
|
||||
// "requested %u.", static_cast<int32>(writtenBytes), size);
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool UARTConfig::WaitRead(const uint32 timeoutUsec) {
|
||||
|
||||
struct timeval timeWait;
|
||||
uint32 tmp = timeoutUsec / 1000000u;
|
||||
timeWait.tv_sec = static_cast<time_t>(tmp);
|
||||
tmp = timeoutUsec % 1000000u;
|
||||
timeWait.tv_usec = static_cast<suseconds_t>(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<time_t>(tmp);
|
||||
tmp = timeoutUsec % 1000000u;
|
||||
timeWait.tv_usec = static_cast<suseconds_t>(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
|
||||
164
DataSources/PSUCommunicator/UARTConfig.h
Normal file
164
DataSources/PSUCommunicator/UARTConfig.h
Normal file
@@ -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_ */
|
||||
Reference in New Issue
Block a user