Compare commits

...

10 Commits

Author SHA1 Message Date
a1ddaf871d Update code with for loop
Signed-off-by: Bernardo Carvalho <bernardo.carvalho@tecnico.ulisboa.pt>
2025-12-09 11:16:30 +00:00
cba72011a8 Update code with for loop
Signed-off-by: Bernardo Carvalho <bernardo.carvalho@tecnico.ulisboa.pt>
2025-12-09 11:14:06 +00:00
bfb45587ab Update code with for loop
Signed-off-by: Bernardo Carvalho <bernardo.carvalho@tecnico.ulisboa.pt>
2025-12-06 09:01:46 +00:00
c6cf6be3eb Update code with for loop
Signed-off-by: Bernardo Carvalho <bernardo.carvalho@tecnico.ulisboa.pt>
2025-12-06 08:23:03 +00:00
82dbcf868c Added test cpp Project
Signed-off-by: Bernardo Carvalho <bernardo.carvalho@tecnico.ulisboa.pt>
2025-12-05 13:20:11 +00:00
8850b75b15 updated files
Signed-off-by: Bernardo Carvalho <bernardo.carvalho@tecnico.ulisboa.pt>
2025-11-12 15:06:22 +00:00
1764a7b8da Added PSU DS messages
Signed-off-by: Bernardo Carvalho <bernardo.carvalho@tecnico.ulisboa.pt>
2025-10-28 18:19:07 +00:00
9bb3196a23 Added PSU DS messages
Signed-off-by: Bernardo Carvalho <bernardo.carvalho@tecnico.ulisboa.pt>
2025-10-28 17:17:54 +00:00
90591f504a Added PSU DS messages
Signed-off-by: Bernardo Carvalho <bernardo.carvalho@tecnico.ulisboa.pt>
2025-10-26 00:42:25 +01:00
cc8cab6d5f Added PSU DS
Signed-off-by: Bernardo Carvalho <bernardo.carvalho@tecnico.ulisboa.pt>
2025-10-25 23:47:18 +01:00
9 changed files with 610 additions and 173 deletions

View File

@@ -1,3 +1,9 @@
+TCPMessageProxy = {
Class = TCPSocketMessageProxyExample
Port = 24680
}
// echo -e "Destination=StateMachine\nFunction=GOTOSTATE2" | nc 127.0.0.1 24680
+StateMachine = {
Class = StateMachine
+INITIAL = {
@@ -54,6 +60,12 @@
Function = StartNextStateExecution
Mode = ExpectsReply
}
+TriggerPSUMsg = {
Class = Message
Destination = "TestApp.Data.UartOutDS"
Function = GoWaitTrigger
Mode = ExpectsReply
}
}
+ERROR = {
Class = StateMachineEvent
@@ -90,6 +102,12 @@
Function = StartNextStateExecution
Mode = ExpectsReply
}
+TriggerPSUMsg = {
Class = Message
Destination = "TestApp.Data.UartOutDS"
Function = TriggerPSU
Mode = ExpectsReply
}
}
+ERROR = {
Class = StateMachineEvent
@@ -126,6 +144,12 @@
Function = StartNextStateExecution
Mode = ExpectsReply
}
+TriggerPSUMsg = {
Class = Message
Destination = "TestApp.Data.UartOutDS"
Function = GoOnlineIdle
Mode = ExpectsReply
}
}
+ERROR = {
Class = StateMachineEvent
@@ -218,46 +242,12 @@ $TestApp = {
}
}
}
+GAMWF1 = {
Class = WaveformGAM::WaveformPointsDef
Points = {-1000 1000}
Times = {0 10000}
InputSignals = {
Time = {
DataSource = DDB1
Type = uint32
}
}
OutputSignals = {
Reference1 = {
DataSource = DDB1
Type = float32
}
}
}
+GAMWF2 = {
Class = WaveformGAM::WaveformPointsDef
Points = {1000 -1000}
Times = {0 10000}
InputSignals = {
Time = {
DataSource = DDB1
Type = uint32
}
}
OutputSignals = {
Reference1 = {
DataSource = DDB1
Type = float32
}
}
}
+GAMWF3 = {
+GAMWF = {
Class = WaveformGAM::WaveformSin
Amplitude = 10.0
Amplitude = 200.0
Frequency = 0.1
Phase = 0.0
Offset = 1.1
Offset = 200.1
InputSignals = {
Time = {
DataSource = "DDB1"
@@ -336,14 +326,17 @@ $TestApp = {
}
}
+UartOutDS = {
Class = UARTOutput
Class = PSUCommunicator::PSUCommunicatorTX
PortName = "/dev/ttyS0" //Name of the UART port, Mandatory
//PortName = "/dev/ttyLoopWr" //Name of the UART port, Mandatory
BaudRate = 9600 // 10.851 µs / Byte
//115200 //BAUD UART rate
BaudRate = 921600
//BaudRate = 115200 // 9600 10.851 µs / Byte
//115200 576000//BAUD UART rate
Timeout = 200000 //Maximum time to wait for data
CPUMask = 8 //Affinity of the CPU of where to read data from
SerialTimeout = 1000
PointOfZeroCurrent = 50.0 //5.100000e+02
CurrentStep = 1.0 //929700e+00
Signals = {
SerialOut = {
Type = float32 //Mandatory. Only type that is supported.
@@ -361,7 +354,7 @@ $TestApp = {
+Thread1 = {
Class = RealTimeThread
CPUs = 0x1
Functions = {GAMTimer GAMWF1 SerialOutGAM GAMDisplay}
Functions = {GAMTimer GAMWF SerialOutGAM GAMDisplay}
}
}
}
@@ -372,7 +365,7 @@ $TestApp = {
+Thread1 = {
Class = RealTimeThread
CPUs = 0x1
Functions = {GAMTimer GAMWF2 GAMDisplay}
Functions = {GAMTimer GAMWF SerialOutGAM GAMDisplay}
}
}
}
@@ -383,7 +376,7 @@ $TestApp = {
+Thread1 = {
Class = RealTimeThread
CPUs = 0x1
Functions = {GAMTimer GAMWF3 GAMDisplay}
Functions = {GAMTimer GAMWF SerialOutGAM GAMDisplay}
}
}
}

View File

@@ -54,19 +54,11 @@ 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;
//}
isTriggered = false;
communicatorOnlineStage = FA_COMMUNICATOR_ONLINE_IDLE;
// channelsMemory = NULL_PTR(float32 *);
channelValue = 0.0; // NULL_PTR(float32 *);
currentValue = 0.0; // NULL_PTR(float32 *);
currentStep = 0.0;
pointOfZeroCurrent = 0.0;
@@ -88,11 +80,6 @@ PSUCommunicatorTX::~PSUCommunicatorTX() {
serial.Close();
REPORT_ERROR_PARAMETERS(ErrorManagement::Information, "Close %s OK.",
portName);
/*
if (channelsMemory != NULL_PTR(float32 *)) {
delete[] channelsMemory;
}
*/
}
bool PSUCommunicatorTX::AllocateMemory() { return true; }
@@ -104,11 +91,9 @@ uint32 PSUCommunicatorTX::GetNumberOfMemoryBuffers() { return 1u; }
bool PSUCommunicatorTX::GetSignalMemoryBuffer(const uint32 signalIdx,
const uint32 bufferIdx,
void *&signalAddress) {
bool ok = (signalIdx < (UART_MAX_CHANNELS));
bool ok = (signalIdx < (PSU_MAX_CHANNELS));
if (ok) {
// if (channelsMemory != NULL_PTR(float32 *)) {
signalAddress = &channelValue;
//}
signalAddress = &currentValue;
}
return ok;
}
@@ -134,6 +119,7 @@ const char8 *PSUCommunicatorTX::GetBrokerName(StructuredDataI &data,
}
return brokerName;
}
bool PSUCommunicatorTX::GetInputBrokers(ReferenceContainer &inputBrokers,
const char8 *const functionName,
void *const gamMemPtr) {
@@ -281,62 +267,6 @@ bool PSUCommunicatorTX::Initialise(StructuredDataI &data) {
"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;
}
@@ -352,12 +282,11 @@ bool PSUCommunicatorTX::SetConfiguredDatabase(StructuredDataI &data) {
"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");
"The PSU current signal shall be of type Float32Bit");
}
}
@@ -385,10 +314,12 @@ bool PSUCommunicatorTX::SetConfiguredDatabase(StructuredDataI &data) {
}
// Create/Decode current packet
bool PSUCommunicatorTX::CreateCurrentPacket(float32 current, char8 *packet) {
bool PSUCommunicatorTX::CreateCurrentPacket() {
bool ok = true;
// Calculate the point in the scale of the current
int16 pointOfCurrent = (int16)(pointOfZeroCurrent + current / currentStep);
int16 pointOfCurrent =
(int16)(pointOfZeroCurrent + currentValue / currentStep);
// Saturate current
if (pointOfCurrent < FA_SCALE_MIN)
@@ -401,34 +332,112 @@ bool PSUCommunicatorTX::CreateCurrentPacket(float32 current, char8 *packet) {
uint16 nc = ~pc;
packet[0] = (char8)(0x0000 | ((nc & 0x03C0) >> 5) | ((pc & 0x0007) << 5));
packet[1] = (char8)(0x0001 | ((pc & 0x03F8) >> 2));
nc = (uint16)packet[1];
nc <<= 8;
nc &= 0xFF00;
nc |= packet[0];
REPORT_ERROR_PARAMETERS(ErrorManagement::Information, "CurrentPacket %d 0x%x",
pointOfCurrent, nc); // packet[0]);
// packet[1]);
return true;
return ok;
}
bool PSUCommunicatorTX::SendMessage() {
bool ok = true;
uint16 uval;
memcpy(&uval, packet, 2);
REPORT_ERROR_PARAMETERS(ErrorManagement::Information, "SendMessage 0x%",
uval);
// (uint16)packet[0], (uint16)packet[1]);
// packet[0], packet[1]);
serial.Write(packet, 2);
return ok;
}
bool PSUCommunicatorTX::CommunicatorOnline() {
bool ok = true;
switch (communicatorOnlineStage) {
case FA_COMMUNICATOR_ONLINE_IDLE:
// Log the entry on this stage
// if(this->communicatorOnlineIdleCount++ == 0)
// AssertErrorCondition(Information, "[FACom] COMMUNICATOR_ONLINE_IDLE");
isTriggered = false;
break;
// Wait for the CODAC trigger
case FA_COMMUNICATOR_ONLINE_WAIT_CODAC_TRIGGER:
// Log the entry on this stage
// if(this->communicatorOnlineWaitTriggerCount++ == 0)
// AssertErrorCondition(Information, "[FACom]
// COMMUNICATOR_ONLINE_WAIT_CODAC_TRIGGER");
if (isTriggered) {
// Send Start Operation message
// this->SendMessage(FA_STARTOP_MESSAGE_1, FA_STARTOP_MESSAGE_2);
packet[0] = FA_STARTOP_MESSAGE_1;
packet[1] = FA_STARTOP_MESSAGE_2;
SendMessage();
// Increase attempts counter
// this->communicatorOnlineStartOperationAttempts++;
// Change online state
communicatorOnlineStage = FA_COMMUNICATOR_ONLINE_DISCHARGE;
// this->communicatorOnlineWaitTriggerCount = 0;
}
break;
case FA_COMMUNICATOR_ONLINE_DISCHARGE:
/*
if(PlasmaEnded)
{
this->communicatorOnlineStage =
FA_COMMUNICATOR_ONLINE_STOP_OPERATION;
this->communicatorOnlineDischargeCount =
0; break;
}
*/
// CreateCurrentPacket(CurrentToSendCopy, packet1, packet2);
CreateCurrentPacket();
ok = SendMessage();
// communicatorOnlineStage = FA_COMMUNICATOR_ONLINE_STOP_OPERATION;
break;
case FA_COMMUNICATOR_ONLINE_STOP_OPERATION:
packet[0] = FA_STARTOP_MESSAGE_1;
packet[1] = FA_STARTOP_MESSAGE_2;
ok = SendMessage();
communicatorOnlineStage = FA_COMMUNICATOR_ONLINE_IDLE;
break;
case FA_COMMUNICATOR_ONLINE_ERROR:
// AssertErrorCondition(InitialisationError, "[FACom]::%s Power supplies
// timeout: after %d attemps, FA_COMMUNICATOR_ONLINE_ERROR, RETURN FALSE",
// this->Name(), this->communicatorOnlineStopOperationAttempts);
ok = false;
break;
default:
break;
}
return ok;
}
bool PSUCommunicatorTX::Synchronise() {
uint32 i;
int32 w = 24;
bool ok = true;
char8 text[] = "ola";
// if (channelsMemory != NULL_PTR(float32 *)) {
// 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));
CommunicatorOnline();
// REPORT_ERROR_PARAMETERS(ErrorManagement::Information,
// "Synchronise called. value: %f", currentValue);
// 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];
@@ -436,6 +445,38 @@ bool PSUCommunicatorTX::Synchronise() {
*/
return ok;
}
// Messages
ErrorManagement::ErrorType PSUCommunicatorTX::GoOnlineIdle() {
ErrorManagement::ErrorType err;
REPORT_ERROR(ErrorManagement::Information,
"PSUCommunicatorTX::GoOnlineIdle. Got Message!");
communicatorOnlineStage = FA_COMMUNICATOR_ONLINE_STOP_OPERATION;
// communicatorOnlineStage = FA_COMMUNICATOR_ONLINE_IDLE;
return err;
}
ErrorManagement::ErrorType PSUCommunicatorTX::GoWaitTrigger() {
ErrorManagement::ErrorType err;
REPORT_ERROR(ErrorManagement::Information,
"PSUCommunicatorTX::GoWaitTrigger. Got Message!");
communicatorOnlineStage = FA_COMMUNICATOR_ONLINE_WAIT_CODAC_TRIGGER;
return err;
}
ErrorManagement::ErrorType PSUCommunicatorTX::TriggerPSU() {
isTriggered = true;
ErrorManagement::ErrorType err;
REPORT_ERROR(ErrorManagement::Information,
"PSUCommunicatorTX::TriggerPSU. Got Message!");
// communicatorOnlineStage = FA_COMMUNICATOR_ONLINE_DISCHARGE;
return err;
}
CLASS_REGISTER(PSUCommunicatorTX, "1.0")
CLASS_METHOD_REGISTER(PSUCommunicatorTX, GoOnlineIdle)
CLASS_METHOD_REGISTER(PSUCommunicatorTX, GoWaitTrigger)
CLASS_METHOD_REGISTER(PSUCommunicatorTX, TriggerPSU)
} // namespace MARTe
// vim: syntax=cpp ts=2 sw=2 sts=2 sr et

View File

@@ -36,6 +36,7 @@
/*---------------------------------------------------------------------------*/
/* Project header includes */
/*---------------------------------------------------------------------------*/
#include "CLASSMETHODREGISTER.h"
#include "DataSourceI.h"
#include "EmbeddedServiceMethodBinderI.h"
#include "EventSem.h"
@@ -53,7 +54,7 @@ namespace MARTe {
* The number of signals
*/
const uint32 UART_MAX_CHANNELS = 1u;
const uint32 PSU_MAX_CHANNELS = 1u;
/**
* @brief A DataSource which provides an analogue output interface to the ATCA
@@ -70,7 +71,7 @@ const uint32 UART_MAX_CHANNELS = 1u;
* CurrentStep =
* PointOfZeroCurrent =
* Signals = {
* SerialOut = {
* CurrentSignal= {
* Type = float32//Mandatory. Only type that is supported.
* OutputRange = 10.0 //Mandatory. The channel Module Output Range
in volt.
@@ -92,6 +93,7 @@ const uint32 UART_MAX_CHANNELS = 1u;
class PSUCommunicatorTX : public DataSourceI, public MessageI {
public:
CLASS_REGISTER_DECLARATION()
// AtcaIopConfig ();
/**
* @brief Default constructor
* @post
@@ -191,24 +193,25 @@ public:
virtual bool SetConfiguredDatabase(StructuredDataI &data);
/**
* @details Writes the value of all the DAC channels to the board.
* @details Writes the packet to the PSU
* @return true if the writing of all the channels is successful.
*/
virtual bool Synchronise();
/**
* @brief
* @details This method
* It can be called within a
* MARTe message.
*/
ErrorManagement::ErrorType GoOnlineIdle();
ErrorManagement::ErrorType GoWaitTrigger();
ErrorManagement::ErrorType TriggerPSU();
private:
/**
* The board device name
*/
StreamString portName;
/**
* The board identifier
*/
uint32 boardId;
/**
* The board file descriptor
*/
// int32 boardFileDescriptor;
/**
* The UART interface.
*/
@@ -223,31 +226,15 @@ private:
*/
uint32 timeout;
/**
* DAC values
*/
// int32 dacValues[ATCA_IOP_N_DACs];
/**
* The signal memory
*/
float32 channelValue;
float32 currentValue;
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;
// Communicator online behaviour
uint32 communicatorOnlineStage;
bool isTriggered;
/**
* Filter to receive the RPC which allows to change the...
@@ -258,9 +245,12 @@ private:
* True if at least one trigger was set.
*/
bool triggerSet;
char8 packet[2];
// int32 SetDacReg(uint32 channel, float32 val) const;
bool CreateCurrentPacket(float32 current, char8 *packet);
bool SendMessage();
bool CommunicatorOnline();
bool CreateCurrentPacket(); // float32 current, char8 *packet);
};
} // namespace MARTe

View File

@@ -0,0 +1,5 @@
cmake_minimum_required(VERSION 3.25)
project(serial_psu)
add_executable(psuSendReceive psuSendReceive.cpp)

View 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

View File

@@ -0,0 +1,87 @@
// C library headers
// setserial /dev/ttyS0 spd_cust
// setserial /dev/ttyS0 divisor 16
// stty -F /dev/ttyS0 921600
#include <cstdint>
#include <cstdlib>
#include <stdio.h>
#include <string.h>
// Linux headers
#include <errno.h> // Error integer and strerror() function
#include <fcntl.h> // Contains file controls like O_RDWR
#include <iostream>
#include <termios.h> // Contains POSIX terminal control definitions
#include <unistd.h> // write(), read(), close()
int openSerialPort(const char *portname) {
int fd = open(portname, O_RDWR | O_NOCTTY | O_NDELAY);
if (fd < 0) {
std::cerr << "Error opening port: " << portname << std::endl;
return -1;
}
return fd;
}
bool configureSerialPort(int fd, int baudRate) {
// Create new termios struct, we call it 'tty' for convention
struct termios tty;
// Read in existing settings, and handle any error
if (tcgetattr(fd, &tty) != 0) {
printf("Error %i from tcgetattr: %s\n", errno, strerror(errno));
return false;
}
// tty.c_cflag &= ~PARENB; // Clear parity bit, disabling parity (most common)
tty.c_cflag |= PARENB;
tty.c_cflag |= PARODD;
tty.c_cflag |= CSTOPB;
// tty.c_cflag &= ~CSTOPB; // Clear stop field, only one stop bit used in
// communication (most common)
tty.c_cflag &= ~CSIZE; // Clear all bits that set the data size
tty.c_cflag |= CS8; // 8 bits per byte (most common)
tty.c_cflag &=
~CRTSCTS; // Disable RTS/CTS hardware flow control (most common)
tty.c_cflag |=
CREAD | CLOCAL; // Turn on READ & ignore ctrl lines (CLOCAL = 1)
// http://unixwiz.net/techtips/termios-vmin-vtime.html
// ICANON bit is turned off, a "raw mode" is selected
tty.c_lflag &= ~ICANON;
tty.c_lflag &= ~ECHO; // Disable echo
tty.c_lflag &= ~ECHOE; // Disable erasure
tty.c_lflag &= ~ECHONL; // Disable new-line echo
tty.c_lflag &= ~ISIG; // Disable interpretation of INTR, QUIT and SUSP
tty.c_iflag &= ~(IXON | IXOFF | IXANY); // Turn off s/w flow ctrl
tty.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR |
ICRNL); // Disable any special handling of received bytes
// write(fd, packet, sizeof(packet));
// printf("Sent : %lu bytes\n", sizeof(packet));
tty.c_oflag &= ~OPOST; // Prevent special interpretation of output bytes (e.g.
// newline chars)
tty.c_oflag &=
~ONLCR; // Prevent conversion of newline to carriage return/line feed
// tty.c_oflag &= ~OXTABS; // Prevent conversion of tabs to spaces (NOT
// PRESENT ON LINUX) tty.c_oflag &= ~ONOEOT; // Prevent removal of C-d chars
// (0x004) in output (NOT PRESENT ON LINUX)
tty.c_cc[VTIME] = 1; // Wait for up to 1s (10 deciseconds), returning as soon
// as any data is received.
tty.c_cc[VMIN] = 0;
// tty.c_cc[VMIN] = 2;
// Error reading: Resource temporarily unavailable%
// Set in/out baud rate
cfsetispeed(&tty, baudRate);
cfsetospeed(&tty, baudRate);
// Save tty settings, also checking for error
if (tcsetattr(fd, TCSANOW, &tty) != 0) {
printf("Error %i from tcsetattr: %s\n", errno, strerror(errno));
return false;
}
return true;
}

View File

@@ -0,0 +1,7 @@
// C library headers
// setserial /dev/ttyS0 spd_cust
// setserial /dev/ttyS0 divisor 16
// stty -F /dev/ttyS0 921600
int openSerialPort(const char *portname);
bool configureSerialPort(int fd, int baudRate);

View File

@@ -0,0 +1,190 @@
// C library headers
// setserial /dev/ttyS0 spd_cust
// setserial /dev/ttyS0 divisor 16
// stty -F /dev/ttyS0 921600
#include <cstdint>
#include <cstdlib>
#include <stdio.h>
#include <string.h>
// Linux headers
#include <errno.h> // Error integer and strerror() function
#include <fcntl.h> // Contains file controls like O_RDWR
#include <iostream>
#include <termios.h> // Contains POSIX terminal control definitions
#include <unistd.h> // write(), read(), close()
#include "PSUMessages.h"
#include "UartLib.hpp"
uint8_t packet[2];
uint8_t packetR[4];
// int sourceFd;
bool isStarted;
void InterpretMessage();
bool DecodeCurrentPacket() { // float &current, unsigned char packet1, unsigned
// char packet2){
// Validate packets
unsigned char validation = (packetR[1] & 0xF0) ^ ((packetR[0] & 0x1E) << 3);
if (validation != 0xF0) {
printf("WrongMessagesReceived\n");
return false;
}
short pointOfCurrent = (short)((((unsigned short)packetR[0] & 0x00E0) >> 5) |
(((unsigned short)packetR[1] & 0x00FE) << 2));
printf("pointOfCurrenti = %d\n", pointOfCurrent);
return true;
}
bool CreateCurrentPacket(unsigned int current) {
bool ok = true;
// Zero current 510
// Calculate the point in the scale of the current
int16_t pointOfCurrent = current;
// Saturate current
if (pointOfCurrent < FA_SCALE_MIN)
pointOfCurrent = FA_SCALE_MIN;
if (pointOfCurrent > FA_SCALE_MAX)
pointOfCurrent = FA_SCALE_MAX;
// Build packets
uint16_t pc = (uint16_t)pointOfCurrent;
uint16_t nc = ~pc;
packet[0] = (uint8_t)(0x0000 | ((nc & 0x03C0) >> 5) | ((pc & 0x0007) << 5));
packet[1] = (uint8_t)(0x0001 | ((pc & 0x03F8) >> 2));
/*
nc = (uint16_t)packet[1];
nc <<= 8;
nc &= 0xFF00;
nc |= packet[0];
*/
printf("Current: %d, Packet 0x%02X 0x%02X\n", current, packet[0], packet[1]);
return EXIT_SUCCESS;
}
int read_msg(int fd) {
// Allocate memory for read buffer, set size according to your needs
// char read_buf[4];
// Normally you wouldn't do this memset() call, but since we will just receive
// call printf() easily.
memset(&packetR, '\0', sizeof(packetR));
// wait 1 ms
usleep(1000);
// Read bytes. The behaviour of read() (e.g. does it block?,
// how long does it block for?) depends on the configuration
// settings above, specifically VMIN and VTIME
int num_bytes = read(fd, &packetR, sizeof(packetR));
// n is the number of bytes read. n may be 0 if no bytes were received, and
// can also be -1 to signal an error.
if (num_bytes < 0) {
printf("Error reading: %s", strerror(errno));
return EXIT_FAILURE;
}
// Here we assume we received ASCII data, but you might be sending raw bytes
// (in that case, don't try and print it to the screen like this!)
printf("Read %i bytes. \t", num_bytes);
for (int i = 0; i < num_bytes; i++) {
unsigned int val = packetR[i] & 0xFF;
printf("%i: 0x%02X \t", i, val);
// printf("%i: %u \n", i, val);
}
printf("\n");
if (num_bytes == 2)
InterpretMessage();
return EXIT_SUCCESS;
}
void InterpretMessage() {
// Operation Started message
if ((packetR[0] == FA_STARTED_MESSAGE_1) &&
(packetR[1] == FA_STARTED_MESSAGE_2)) {
printf("isStarted\n");
isStarted = true;
return;
}
// Operation Stopped message
if ((packetR[0] == FA_STOPPED_MESSAGE_1) &&
(packetR[1] == FA_STOPPED_MESSAGE_2)) {
printf("isStopped\n");
return;
}
// Stop Error message
if ((packetR[0] == FA_STOP_ERROR_MESSAGE_1) &&
(packetR[1] == FA_STOP_ERROR_MESSAGE_2)) {
printf("Stop Error message\n");
return;
}
// Communication Error message
if ((packetR[0] == FA_COMM_ERROR_MESSAGE_1) &&
(packetR[1] == FA_COMM_ERROR_MESSAGE_2)) {
printf("Communication Error message\n");
return;
}
// printf("Other message\n");
DecodeCurrentPacket();
}
int main() {
// Open the serial port. Change device path as needed (currently set to an
// standard FTDI USB-UART cable type device)
// sourceFd = open("/dev/ttyS2", O_RDWR);
int sourceFd = openSerialPort("/dev/ttyS2");
configureSerialPort(sourceFd, B921600);
// B115200; // B576000; // B460800; OK// B230400; // B9600;B921600;
// const speed_t baud_rate = B115200; // B9600;B921600;
// clear input port
read_msg(sourceFd);
isStarted = false;
// Write to serial port
// unsigned char msg[] = {FA_STARTOP_MESSAGE_1, 0xFF};
packet[0] = FA_STARTOP_MESSAGE_1;
packet[1] = FA_STARTOP_MESSAGE_2;
write(sourceFd, packet, sizeof(packet));
printf("Sent Start: %lu bytes\n", sizeof(packet));
read_msg(sourceFd);
if (isStarted) {
usleep(1000);
for (int i = 0; i < 10; i++) {
CreateCurrentPacket(500 + i);
write(sourceFd, packet, sizeof(packet));
usleep(10);
// printf("Sent : %lu bytes\n", sizeof(packet));
read_msg(sourceFd);
// Halting the execution for 100000 Microseconds (0.1 seconds)
usleep(10000);
}
}
packet[0] = FA_STOPOP_MESSAGE_1;
packet[1] = FA_STOPOP_MESSAGE_2;
write(sourceFd, packet, sizeof(packet));
printf("Sent Stop: %lu bytes\n", sizeof(packet));
// read_msg();
usleep(1000);
read_msg(sourceFd);
read_msg(sourceFd);
close(sourceFd);
return 0; // success
}
/**
void repeatData(int sourceFd, int destFd) {
char buffer[256];
while (true) {
int bytesRead = read(sourceFd, buffer, sizeof(buffer));
if (bytesRead > 0) {
write(destFd, buffer, bytesRead);
}
}
}
*/

View File

@@ -0,0 +1,50 @@
#include <csignal>
#include <cstdlib>
#include <fcntl.h>
#include <fstream>
#include <iostream>
#include <termios.h>
#include <unistd.h>
#include "UartLib.hpp"
// #include <pthread.h>
#include <thread>
bool run;
void repeatData(int sourceFd, int destFd, const std::string filename) {
char buffer[8];
std::ofstream outfile(filename); // Open file for writing
while (run) {
int bytesRead = read(sourceFd, buffer, sizeof(buffer));
if (bytesRead > 0) {
write(destFd, buffer, bytesRead);
outfile.write(buffer, bytesRead); // Write to file
}
}
outfile.close();
}
void signalHandler(int signum) {
std::cout << "Caught signal: " << signum << std::endl;
run = false;
// exit(signum);
}
int main() {
int fdMarte1 = openSerialPort("/dev/ttyS1");
configureSerialPort(fdMarte1, B921600);
int fdPSU = openSerialPort("/dev/ttyS2");
configureSerialPort(fdPSU, B921600);
run = true;
signal(SIGINT, signalHandler);
std::thread t1(repeatData, fdMarte1, fdPSU, "outS1.txt");
std::thread t2(repeatData, fdMarte1, fdPSU, "outS2.txt");
t1.join();
t2.join();
// pthread_join(thread1, nullptr);
// pthread_join(thread2, nullptr);
return 0;
}