Initial import
Signed-off-by: Bernardo Carvalho <bernardo.carvalho@tecnico.ulisboa.pt>
This commit is contained in:
47
Analysis/getMdsData.py
Normal file
47
Analysis/getMdsData.py
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
Extract data from MDSplus and plot
|
||||||
|
"""
|
||||||
|
import sys
|
||||||
|
import numpy as np
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
from MDSplus import Tree
|
||||||
|
|
||||||
|
mdsTreeName = 'rtappisttok'
|
||||||
|
|
||||||
|
if len(sys.argv) > 1:
|
||||||
|
mdsPulseNumber = int(sys.argv[1])
|
||||||
|
else:
|
||||||
|
mdsPulseNumber = 1
|
||||||
|
#treename = ''
|
||||||
|
|
||||||
|
try:
|
||||||
|
tree = Tree(mdsTreeName, mdsPulseNumber)
|
||||||
|
except:
|
||||||
|
print(f'Failed opening {mdsTreeName} for pulse number {mdsPulseNumber:d}')
|
||||||
|
exit()
|
||||||
|
"""
|
||||||
|
Available Channels
|
||||||
|
|
||||||
|
ATCAIOP1.ADC0RAW
|
||||||
|
ATCAIOP1.ADC1RAW
|
||||||
|
ATCAIOP1.ADC2RAW
|
||||||
|
ATCAIOP1.ADC3RAW
|
||||||
|
ATCAIOP1.ADC4RAW
|
||||||
|
ATCAIOP1.ADC5RAW
|
||||||
|
ATCAIOP1.ADC6RAW
|
||||||
|
ATCAIOP1.ADC7RAW
|
||||||
|
|
||||||
|
ATCAIOP1.ADC0INT
|
||||||
|
ATCAIOP1.ADC1INT
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
mdsNode = tree.getNode("ATCAIOP1.ADC0RAW")
|
||||||
|
mdsNode = tree.getNode("ATCAIOP1.ADC1INT")
|
||||||
|
dataAdc = mdsNode.getData().data()
|
||||||
|
timeData = mdsNode.getDimensionAt(0).data()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
99
Analysis/pyqtPlotMds.py
Normal file
99
Analysis/pyqtPlotMds.py
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
"""
|
||||||
|
This example demonstrates many of the 2D plotting capabilities
|
||||||
|
in pyqtgraph. All of the plots may be panned/scaled by dragging with
|
||||||
|
the left/right mouse buttons. Right click on any plot to show a context menu.
|
||||||
|
"""
|
||||||
|
|
||||||
|
#import sys
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
import pyqtgraph as pg
|
||||||
|
from pyqtgraph.Qt import QtCore
|
||||||
|
from MDSplus import Tree
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
app = pg.mkQApp("Plotting MARTe2 Data")
|
||||||
|
#mw = QtWidgets.QMainWindow()
|
||||||
|
#mw.resize(800,800)
|
||||||
|
|
||||||
|
MAX_SAMPLES = 50000
|
||||||
|
ADC_CHANNELS = 4
|
||||||
|
DECIM_RATE = 200
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser(description = 'Script to support the QA activities')
|
||||||
|
|
||||||
|
#parser.add_argument('-l','--list', nargs='+', help='<Required> Set flag', required=True)
|
||||||
|
#parser.add_argument('-l','--list', nargs='+')
|
||||||
|
parser.add_argument('-c', '--crange', nargs='+',type=int, help='Channel lines (0 4 )',default=[0, 4])
|
||||||
|
parser.add_argument('-i', '--irange', nargs='+',type=int,default=[0, 4])
|
||||||
|
#parser.add_argument('pulse','-', nargs='+', help='<Required> Set flag', required=True)
|
||||||
|
parser.add_argument('-s', '--shot', type=int, help='Mds+ pulse Number ([0, ...])', default=100)
|
||||||
|
parser.add_argument('-m', '--maxsamples', type=int, help='Max samples to plot', default=50000)
|
||||||
|
parser.add_argument('-z', '--zero', action='store_true',help='Zero integral Lines') #, default='')
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
mdsPulseNumber = args.shot
|
||||||
|
|
||||||
|
#if len(sys.argv) > 1:
|
||||||
|
# mdsPulseNumber = int(sys.argv[1])
|
||||||
|
#else:
|
||||||
|
# mdsPulseNumber = 1
|
||||||
|
# #treename = ''
|
||||||
|
|
||||||
|
mdsTreeName = 'rtappisttok'
|
||||||
|
|
||||||
|
try:
|
||||||
|
tree = Tree(mdsTreeName, mdsPulseNumber)
|
||||||
|
except:
|
||||||
|
print(f'Failed opening {mdsTreeName} for pulse number {mdsPulseNumber:d}')
|
||||||
|
exit()
|
||||||
|
|
||||||
|
#time = dataCsv['#Time (uint32)[1]']
|
||||||
|
#timeRel = time - time[0]
|
||||||
|
#x = DECIM_RATE * np.arange(len(vals))
|
||||||
|
|
||||||
|
win = pg.GraphicsLayoutWidget(show=True, title="Basic plotting examples")
|
||||||
|
win.resize(1000,600)
|
||||||
|
win.setWindowTitle('pyqtgraph example: Plotting')
|
||||||
|
|
||||||
|
# Enable antialiasing for prettier plots
|
||||||
|
pg.setConfigOptions(antialias=True)
|
||||||
|
|
||||||
|
p1 = win.addPlot(title="ATCA ADC raw decim")
|
||||||
|
# add plt.addLegend() BEFORE you create the curves.
|
||||||
|
mdsNode = tree.getNode("ATCAIOP1.ADC0RAW")
|
||||||
|
dataAdc = mdsNode.getData().data()
|
||||||
|
timeData = mdsNode.getDimensionAt(0).data()
|
||||||
|
p1.addLegend()
|
||||||
|
for i in range(args.crange[0], args.crange[1]):
|
||||||
|
mdsNode = tree.getNode(f"ATCAIOP1.ADC{i}RAW")
|
||||||
|
dataAdc = mdsNode.getData().data()
|
||||||
|
timeData = mdsNode.getDimensionAt(0).data()
|
||||||
|
#y = dataAdc[ :args.maxsamples, 0]
|
||||||
|
y = dataAdc[ :MAX_SAMPLES, 0]
|
||||||
|
x = DECIM_RATE * np.arange(len(y)) / 2.0e6
|
||||||
|
p1.plot(x,y, pen=pg.mkPen(i, width=2), name=f"Ch {i}")
|
||||||
|
#p1.setLabel('bottom', "Y Axis", units='s')
|
||||||
|
|
||||||
|
win.nextRow()
|
||||||
|
p4 = win.addPlot(title="ATCA Integral Channels")
|
||||||
|
p4.addLegend()
|
||||||
|
#for i in range(8,12):
|
||||||
|
for i in range(args.irange[0], args.irange[1]):
|
||||||
|
mdsNode = tree.getNode(f"ATCAIOP1.ADC{i}INT")
|
||||||
|
dataAdcInt = mdsNode.getData().data()
|
||||||
|
timeData = mdsNode.getDimensionAt(0).data()
|
||||||
|
y = dataAdcInt[ :args.maxsamples, 0]
|
||||||
|
if(args.zero):
|
||||||
|
y = y - dataAdcInt[0, 0]
|
||||||
|
#x = DECIM_RATE * np.arange(len(y))
|
||||||
|
x = DECIM_RATE * np.arange(len(y)) / 2.0e6
|
||||||
|
p4.plot(x,y, pen=pg.mkPen(i, width=2), name=f"Ch {i}")
|
||||||
|
|
||||||
|
p4.setLabel('bottom', "Time", units='s')
|
||||||
|
|
||||||
|
#updatePlot()
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
pg.exec()
|
||||||
|
# vim: syntax=python ts=4 sw=4 sts=4 sr et
|
||||||
56
Configurations/EPICS-isttok.db
Normal file
56
Configurations/EPICS-isttok.db
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
#record( longin, "ISTTOK:marte2:STATUS")
|
||||||
|
#{
|
||||||
|
# field(DTYP, "Soft Channel")
|
||||||
|
#}
|
||||||
|
|
||||||
|
#record( longin, "ISTTOK:marte2:COMMAND")
|
||||||
|
#{
|
||||||
|
# field(DTYP, "Soft Channel")
|
||||||
|
#}
|
||||||
|
|
||||||
|
#record( longin, "ISTTOK:marte2:RESET")
|
||||||
|
#{
|
||||||
|
# field(DTYP, "Soft Channel")
|
||||||
|
#}
|
||||||
|
|
||||||
|
#record( ai, "ISTTOK:marte2:MEASUREMENT0")
|
||||||
|
#{
|
||||||
|
# field(DTYP, "Soft Channel")
|
||||||
|
#}
|
||||||
|
|
||||||
|
record( waveform, "ISTTOK:marte2:HIST-IDLE-CT")
|
||||||
|
{
|
||||||
|
field(DTYP, "Soft Channel")
|
||||||
|
field(NELM, 10)
|
||||||
|
field(FTVL, "LONG")
|
||||||
|
}
|
||||||
|
record( waveform, "ISTTOK:marte2:HIST-RUN-CT")
|
||||||
|
{
|
||||||
|
field(DTYP, "Soft Channel")
|
||||||
|
field(NELM, 10)
|
||||||
|
field(FTVL, "LONG")
|
||||||
|
}
|
||||||
|
|
||||||
|
record( longin, "ISTTOK:marte2:TIME")
|
||||||
|
{
|
||||||
|
field(DTYP, "Soft Channel")
|
||||||
|
}
|
||||||
|
|
||||||
|
record( longin, "ISTTOK:marte2:COUNTER")
|
||||||
|
{
|
||||||
|
field(DTYP, "Soft Channel")
|
||||||
|
}
|
||||||
|
|
||||||
|
record( ai, "ISTTOK:marte2:ADC0S")
|
||||||
|
{
|
||||||
|
field(DTYP, "Soft Channel")
|
||||||
|
}
|
||||||
|
record( ai, "ISTTOK:marte2:Adc0-Decim")
|
||||||
|
{
|
||||||
|
field(DTYP, "Soft Channel")
|
||||||
|
}
|
||||||
|
record( ai, "ISTTOK:marte2:Adc1-Decim")
|
||||||
|
{
|
||||||
|
field(DTYP, "Soft Channel")
|
||||||
|
}
|
||||||
|
|
||||||
1531
Configurations/RTApp-AtcaIop.cfg
Normal file
1531
Configurations/RTApp-AtcaIop.cfg
Normal file
File diff suppressed because it is too large
Load Diff
734
DataSources/AtcaIop/AtcaIopADC.cpp
Normal file
734
DataSources/AtcaIop/AtcaIopADC.cpp
Normal file
@@ -0,0 +1,734 @@
|
|||||||
|
/**
|
||||||
|
* @file AtcaIopADC.cpp
|
||||||
|
* @brief Source file for class AtcaIopADC
|
||||||
|
* @date 19/09/2020
|
||||||
|
* @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 AtcaIopADC (public, protected, and private). Be aware that some
|
||||||
|
* methods, such as those inline could be defined on the header file, instead.
|
||||||
|
*/
|
||||||
|
|
||||||
|
//#define DLL_API
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/* Standard header includes */
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
//#include <math.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/mman.h> // For mmap()
|
||||||
|
|
||||||
|
#include <unistd.h> // for close()
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/* Project header includes */
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
#include "AdvancedErrorManagement.h"
|
||||||
|
#include "MemoryMapSynchronisedInputBroker.h"
|
||||||
|
#include "AtcaIopADC.h"
|
||||||
|
#include "atca-v6-iop-ioctl.h"
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/* Static definitions */
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
namespace MARTe {
|
||||||
|
|
||||||
|
//const float64 ADC_SIMULATOR_PI = 3.14159265359;
|
||||||
|
const uint32 IOP_ADC_OFFSET = 2u; // in DMA Data packet in 32b. First 2 are counter.
|
||||||
|
const uint32 IOP_ADC_INTEG_OFFSET = 16u; // in 64 bit words
|
||||||
|
|
||||||
|
const uint32 RT_PCKT_SIZE = 1024u;
|
||||||
|
const uint32 RT_PCKT64_SIZE = 512u; // In 64 bit words
|
||||||
|
|
||||||
|
/* 256 + 3840 = 4096 B (PAGE_SIZE) data packet*/
|
||||||
|
typedef struct _DMA_CH1_PCKT {
|
||||||
|
uint32 head_time_cnt;
|
||||||
|
uint32 header; // h5431BACD
|
||||||
|
int32 channel[60]; // 24 56
|
||||||
|
uint32 foot_time_cnt;
|
||||||
|
uint32 footer; // h9876ABDC
|
||||||
|
uint8 page_fill[3840];
|
||||||
|
} DMA_CH1_PCKT;
|
||||||
|
|
||||||
|
struct atca_eo_config {
|
||||||
|
int32_t offset[ATCA_IOP_MAX_CHANNELS];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct atca_wo_config {
|
||||||
|
int32_t offset[ATCA_IOP_MAX_CHANNELS];
|
||||||
|
};
|
||||||
|
|
||||||
|
//}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/* Method definitions */
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
AtcaIopADC::AtcaIopADC() :
|
||||||
|
DataSourceI(), MessageI(), EmbeddedServiceMethodBinderI(), executor(*this) {
|
||||||
|
//boardId = 2u;
|
||||||
|
deviceName = "";
|
||||||
|
deviceDmaName = "";
|
||||||
|
boardFileDescriptor = -1;
|
||||||
|
boardDmaDescriptor = -1;
|
||||||
|
mappedDmaBase = NULL;
|
||||||
|
mappedDmaSize = 0u;
|
||||||
|
isMaster = 0u;
|
||||||
|
oldestBufferIdx = 0u;
|
||||||
|
lastTimeTicks = 0u;
|
||||||
|
sleepTimeTicks = 0u;
|
||||||
|
timerPeriodUsecTime = 0u;
|
||||||
|
counterAndTimer[0] = 0u;
|
||||||
|
counterAndTimer[1] = 0u;
|
||||||
|
sleepNature = Busy;
|
||||||
|
sleepPercentage = 0u;
|
||||||
|
adcPeriod = 0.;
|
||||||
|
uint32 k;
|
||||||
|
for (k=0u; k<ATCA_IOP_N_ADCs; k++) {
|
||||||
|
adcValues[k] = 0u;
|
||||||
|
electricalOffsets[k] = 0u;
|
||||||
|
wiringOffsets[k] = 0.0;
|
||||||
|
}
|
||||||
|
for (k=0u; k<ATCA_IOP_N_INTEGRALS; k++) {
|
||||||
|
adcIntegralValues[k] = 0u;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!synchSem.Create()) {
|
||||||
|
REPORT_ERROR(ErrorManagement::FatalError, "Could not create EventSem.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*lint -e{1551} the destructor must guarantee that the Timer SingleThreadService is stopped.*/
|
||||||
|
AtcaIopADC::~AtcaIopADC() {
|
||||||
|
if (boardFileDescriptor != -1) {
|
||||||
|
// Synchronize DMA before accessing board registers
|
||||||
|
oldestBufferIdx = GetOldestBufferIdx();
|
||||||
|
PollDma(HighResolutionTimer::Counter() + 2000000); // wait max 2ms
|
||||||
|
ioctl(boardFileDescriptor, ATCA_PCIE_IOPT_STREAM_DISABLE);
|
||||||
|
ioctl(boardFileDescriptor, ATCA_PCIE_IOPT_DMA_DISABLE);
|
||||||
|
uint32 statusReg = 0;
|
||||||
|
ioctl(boardFileDescriptor, ATCA_PCIE_IOPG_STATUS, &statusReg);
|
||||||
|
//rc = ioctl(boardFileDescriptor, ATCA_PCIE_IOPT_DMA_RESET);
|
||||||
|
close(boardFileDescriptor);
|
||||||
|
REPORT_ERROR(ErrorManagement::Information, "Close device %d OK. Status Reg 0x%x,", boardFileDescriptor, statusReg);
|
||||||
|
}
|
||||||
|
if (!synchSem.Post()) {
|
||||||
|
REPORT_ERROR(ErrorManagement::Warning, "Could not post EventSem.");
|
||||||
|
}
|
||||||
|
if (!executor.Stop()) {
|
||||||
|
if (!executor.Stop()) {
|
||||||
|
REPORT_ERROR(ErrorManagement::Warning, "Could not stop SingleThreadService.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// some waiting..
|
||||||
|
//float32 sleepTime = static_cast<float32>(static_cast<float64>(1000) * HighResolutionTimer::Period());
|
||||||
|
//Sleep::NoMore(sleepTime);
|
||||||
|
if (boardDmaDescriptor != -1) {
|
||||||
|
close(boardDmaDescriptor);
|
||||||
|
REPORT_ERROR(ErrorManagement::Information, "Close device %d OK", boardDmaDescriptor);
|
||||||
|
}
|
||||||
|
uint32 k;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AtcaIopADC::AllocateMemory() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AtcaIopADC::Initialise(StructuredDataI& data) {
|
||||||
|
bool ok = DataSourceI::Initialise(data);
|
||||||
|
if (ok) {
|
||||||
|
ok = data.Read("DeviceName", deviceName);
|
||||||
|
if (!ok) {
|
||||||
|
REPORT_ERROR(ErrorManagement::ParametersError, "The DeviceName shall be specified");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ok) {
|
||||||
|
ok = data.Read("DeviceDmaName", deviceDmaName);
|
||||||
|
if (!ok) {
|
||||||
|
REPORT_ERROR(ErrorManagement::ParametersError, "The DeviceDmaName shall be specified");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ok) {
|
||||||
|
ok = data.Read("NumberOfChannels", numberOfChannels);
|
||||||
|
if (!ok) {
|
||||||
|
REPORT_ERROR(ErrorManagement::ParametersError, "The NumberOfChannels shall be specified");
|
||||||
|
}
|
||||||
|
if (numberOfChannels > ATCA_IOP_MAX_CHANNELS ) {
|
||||||
|
numberOfChannels = ATCA_IOP_MAX_CHANNELS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ok) {
|
||||||
|
ok = data.Read("RTDecimation", rtDecimation);
|
||||||
|
if (!ok) {
|
||||||
|
REPORT_ERROR(ErrorManagement::ParametersError, "The RTDecimation shall be specified");
|
||||||
|
}
|
||||||
|
if (rtDecimation > 2000000u) {
|
||||||
|
rtDecimation = 2000000u;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
StreamString sleepNatureStr;
|
||||||
|
if (!data.Read("SleepNature", sleepNatureStr)) {
|
||||||
|
REPORT_ERROR(ErrorManagement::Information, "SleepNature was not set. Using Default.");
|
||||||
|
sleepNatureStr = "Default";
|
||||||
|
}
|
||||||
|
if (sleepNatureStr == "Default") {
|
||||||
|
sleepNature = Default;
|
||||||
|
}
|
||||||
|
else if (sleepNatureStr == "Busy") {
|
||||||
|
sleepNature = Busy;
|
||||||
|
if (!data.Read("SleepPercentage", sleepPercentage)) {
|
||||||
|
sleepPercentage = 0u;
|
||||||
|
REPORT_ERROR(ErrorManagement::Information, "SleepPercentage was not set. Using Default %d.", sleepPercentage);
|
||||||
|
}
|
||||||
|
if (sleepPercentage > 100u) {
|
||||||
|
sleepPercentage = 100u;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
REPORT_ERROR(ErrorManagement::ParametersError, "Unsupported SleepNature.");
|
||||||
|
ok = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
AnyType arrayDescription = data.GetType("ElectricalOffsets");
|
||||||
|
uint32 numberOfElements = 0u;
|
||||||
|
if (ok) {
|
||||||
|
ok = arrayDescription.GetDataPointer() != NULL_PTR(void *);
|
||||||
|
}
|
||||||
|
if (ok) {
|
||||||
|
numberOfElements = arrayDescription.GetNumberOfElements(0u);
|
||||||
|
ok = (numberOfElements == ATCA_IOP_N_ADCs);
|
||||||
|
if (!ok) {
|
||||||
|
REPORT_ERROR(ErrorManagement::ParametersError, "Exactly %d elements shall be defined in the array ElectricalOffsets", ATCA_IOP_N_ADCs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ok) {
|
||||||
|
Vector<int32> readVector(&electricalOffsets[0u], numberOfElements);
|
||||||
|
ok = data.Read("ElectricalOffsets", readVector);
|
||||||
|
}
|
||||||
|
|
||||||
|
arrayDescription = data.GetType("WiringOffsets");
|
||||||
|
numberOfElements = 0u;
|
||||||
|
if (ok) {
|
||||||
|
ok = arrayDescription.GetDataPointer() != NULL_PTR(void *);
|
||||||
|
}
|
||||||
|
if (ok) {
|
||||||
|
numberOfElements = arrayDescription.GetNumberOfElements(0u);
|
||||||
|
ok = (numberOfElements == ATCA_IOP_N_ADCs);
|
||||||
|
if (!ok) {
|
||||||
|
REPORT_ERROR(ErrorManagement::ParametersError, "Exactly %d elements shall be defined in the array WiringOffsets", ATCA_IOP_N_ADCs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ok) {
|
||||||
|
Vector<float32> readVector(&wiringOffsets[0u], numberOfElements);
|
||||||
|
ok = data.Read("WiringOffsets", readVector);
|
||||||
|
}
|
||||||
|
|
||||||
|
chopperPeriod = 1000;
|
||||||
|
if (!data.Read("ChopperPeriod", chopperPeriod)) {
|
||||||
|
REPORT_ERROR(ErrorManagement::Warning, "ChopperPeriod not specified. Using default: %d", chopperPeriod);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!data.Read("IsMaster", isMaster)) {
|
||||||
|
REPORT_ERROR(ErrorManagement::Warning, "IsMaster not specified. Using default: %d", isMaster);
|
||||||
|
}
|
||||||
|
|
||||||
|
adcFrequency = 2e5;
|
||||||
|
if (!data.Read("ADCFrequency", adcFrequency)) {
|
||||||
|
REPORT_ERROR(ErrorManagement::Warning, "ADCFrequency not specified. Using default: %d", adcFrequency);
|
||||||
|
}
|
||||||
|
adcPeriod = 1./adcFrequency;
|
||||||
|
|
||||||
|
if (ok) {
|
||||||
|
uint32 cpuMaskIn;
|
||||||
|
if (!data.Read("CPUMask", cpuMaskIn)) {
|
||||||
|
cpuMaskIn = 0xFFu;
|
||||||
|
REPORT_ERROR(ErrorManagement::Warning, "CPUMask not specified using: %d", cpuMaskIn);
|
||||||
|
}
|
||||||
|
cpuMask = cpuMaskIn;
|
||||||
|
}
|
||||||
|
if (ok) {
|
||||||
|
if (!data.Read("StackSize", stackSize)) {
|
||||||
|
stackSize = THREADS_DEFAULT_STACKSIZE;
|
||||||
|
REPORT_ERROR(ErrorManagement::Warning, "StackSize not specified using: %d", stackSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ok) {
|
||||||
|
ok = (stackSize > 0u);
|
||||||
|
|
||||||
|
if (!ok) {
|
||||||
|
REPORT_ERROR(ErrorManagement::ParametersError, "StackSize shall be > 0u");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ok) {
|
||||||
|
executor.SetCPUMask(cpuMask);
|
||||||
|
executor.SetStackSize(stackSize);
|
||||||
|
}
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AtcaIopADC::SetConfiguredDatabase(StructuredDataI& data) {
|
||||||
|
bool ok = DataSourceI::SetConfiguredDatabase(data);
|
||||||
|
struct atca_eo_config eo_conf;
|
||||||
|
struct atca_wo_config wo_conf;
|
||||||
|
//The DataSource shall have N signals.
|
||||||
|
//The first two are uint32 (counter and time) a
|
||||||
|
//
|
||||||
|
if (ok) {
|
||||||
|
ok = (GetNumberOfSignals() == ATCA_IOP_N_SIGNALS);
|
||||||
|
}
|
||||||
|
if (!ok) {
|
||||||
|
REPORT_ERROR(ErrorManagement::ParametersError, "Exactly %d signals shall be configured", ATCA_IOP_N_SIGNALS);
|
||||||
|
}
|
||||||
|
uint32 i, startPos, endPos;
|
||||||
|
startPos = 0u;
|
||||||
|
endPos = ATCA_IOP_N_TIMCNT;
|
||||||
|
for (i=startPos; (i < endPos) && (ok); i++) {
|
||||||
|
ok = (GetSignalType(i).type == UnsignedInteger);
|
||||||
|
if (!ok) {
|
||||||
|
REPORT_ERROR(ErrorManagement::ParametersError, "The signal %d shall be of type UnsignedInteger", i);
|
||||||
|
}
|
||||||
|
ok = (GetSignalType(i).numberOfBits == 32u);
|
||||||
|
if (!ok) {
|
||||||
|
REPORT_ERROR(ErrorManagement::ParametersError, "The signal in position %d shall have 32 bits and %d were specified", i, uint16(GetSignalType(i).numberOfBits));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
startPos = endPos;
|
||||||
|
endPos = startPos + ATCA_IOP_N_ADCs;
|
||||||
|
for (i=startPos; (i < endPos) && (ok); i++) {
|
||||||
|
ok = (GetSignalType(i).type == SignedInteger);
|
||||||
|
if (!ok) {
|
||||||
|
REPORT_ERROR(ErrorManagement::ParametersError, "The signal %d shall be of type SignedInteger", i);
|
||||||
|
}
|
||||||
|
ok = (GetSignalType(i).numberOfBits == 32u);
|
||||||
|
if (!ok) {
|
||||||
|
REPORT_ERROR(ErrorManagement::ParametersError, "The signal in position %d shall have 32 bits and %d were specified", i, uint16(GetSignalType(i).numberOfBits));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
startPos = endPos;
|
||||||
|
endPos = startPos + ATCA_IOP_N_INTEGRALS;
|
||||||
|
for (i=startPos; (i < endPos) && (ok); i++) {
|
||||||
|
ok = (GetSignalType(i).type == SignedInteger);
|
||||||
|
if (!ok) {
|
||||||
|
REPORT_ERROR(ErrorManagement::ParametersError, "The signal %d shall be of type SignedInteger", i);
|
||||||
|
}
|
||||||
|
ok = (GetSignalType(i).numberOfBits == 64u);
|
||||||
|
if (!ok) {
|
||||||
|
REPORT_ERROR(ErrorManagement::ParametersError, "The signal in position %d shall have 64 bits and %d were specified", i, uint16(GetSignalType(i).numberOfBits));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
startPos = endPos;
|
||||||
|
endPos = ATCA_IOP_N_SIGNALS;
|
||||||
|
for (i=startPos; (i < endPos) && (ok); i++) {
|
||||||
|
ok = (GetSignalType(i).type == SignedInteger);
|
||||||
|
if (!ok) {
|
||||||
|
REPORT_ERROR(ErrorManagement::ParametersError, "The signal %d shall be of type SignedInteger", i);
|
||||||
|
}
|
||||||
|
ok = (GetSignalType(i).numberOfBits == 32u);
|
||||||
|
if (!ok) {
|
||||||
|
REPORT_ERROR(ErrorManagement::ParametersError, "The signal in position %d shall have 32 bits and %d were specified", i, uint16(GetSignalType(i).numberOfBits));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
StreamString fullDeviceName;
|
||||||
|
//Configure the board
|
||||||
|
if (ok) {
|
||||||
|
ok = fullDeviceName.Printf("%s", deviceName.Buffer());
|
||||||
|
}
|
||||||
|
if (ok) {
|
||||||
|
ok = fullDeviceName.Seek(0LLU);
|
||||||
|
}
|
||||||
|
if (ok) {
|
||||||
|
boardFileDescriptor = open(fullDeviceName.Buffer(), O_RDWR);
|
||||||
|
ok = (boardFileDescriptor > -1);
|
||||||
|
if (!ok) {
|
||||||
|
REPORT_ERROR_PARAMETERS(ErrorManagement::ParametersError, "Could not open device %s", fullDeviceName);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
REPORT_ERROR(ErrorManagement::Information, "Open device %s OK", fullDeviceName);
|
||||||
|
}
|
||||||
|
ok = fullDeviceName.Seek(0LLU);
|
||||||
|
if (ok) {
|
||||||
|
ok = fullDeviceName.Printf("%s", deviceDmaName.Buffer());
|
||||||
|
}
|
||||||
|
if (ok) {
|
||||||
|
ok = fullDeviceName.Seek(0LLU);
|
||||||
|
}
|
||||||
|
if (ok) {
|
||||||
|
boardDmaDescriptor = open(fullDeviceName.Buffer(), O_RDWR);
|
||||||
|
ok = (boardDmaDescriptor > -1);
|
||||||
|
if (!ok) {
|
||||||
|
REPORT_ERROR_PARAMETERS(ErrorManagement::ParametersError, "Could not open DMA device %s", fullDeviceName);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
REPORT_ERROR(ErrorManagement::Information, "Open DMA device %s OK", fullDeviceName);
|
||||||
|
}
|
||||||
|
|
||||||
|
//mappedDmaBase = (int32 *) mmap(0, getpagesize() * NUMBER_OF_BUFFERS,
|
||||||
|
mappedDmaBase = (int32 *) mmap(0, 4096u * NUMBER_OF_BUFFERS,
|
||||||
|
PROT_READ, MAP_SHARED, boardDmaDescriptor, 0);
|
||||||
|
if (mappedDmaBase == MAP_FAILED){
|
||||||
|
ok = false;
|
||||||
|
REPORT_ERROR(ErrorManagement::FatalError, "Error Mapping DMA Memory Device %s", fullDeviceName);
|
||||||
|
}
|
||||||
|
mappedDmaSize = getpagesize();
|
||||||
|
|
||||||
|
uint32 statusReg = 0;
|
||||||
|
int rc = ioctl(boardFileDescriptor, ATCA_PCIE_IOPT_DMA_RESET);
|
||||||
|
//rc = ioctl(boardFileDescriptor, ATCA_PCIE_IOPT_STREAM_DISABLE);
|
||||||
|
if (chopperPeriod > 0)
|
||||||
|
{
|
||||||
|
uint32 chopCounter = (chopperPeriod) << 16;
|
||||||
|
chopCounter &= 0xFFFF0000;
|
||||||
|
chopCounter |= chopperPeriod / 2;
|
||||||
|
|
||||||
|
rc = ioctl(boardFileDescriptor, ATCA_PCIE_IOPS_CHOP_COUNTERS, &chopCounter);
|
||||||
|
//read chopper
|
||||||
|
chopCounter = 0;
|
||||||
|
rc = ioctl(boardFileDescriptor, ATCA_PCIE_IOPG_CHOP_COUNTERS, &chopCounter);
|
||||||
|
|
||||||
|
rc = ioctl(boardFileDescriptor, ATCA_PCIE_IOPT_CHOP_ON);
|
||||||
|
REPORT_ERROR(ErrorManagement::Information, "Chop ON 0x%x", chopCounter);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
rc = ioctl(boardFileDescriptor, ATCA_PCIE_IOPT_CHOP_OFF);
|
||||||
|
|
||||||
|
for (i=0u; i < ATCA_IOP_MAX_CHANNELS ; i++) {
|
||||||
|
eo_conf.offset[i] = 0u;
|
||||||
|
wo_conf.offset[i] = 0.0;
|
||||||
|
}
|
||||||
|
for (i=0u; i < ATCA_IOP_N_ADCs ; i++) {
|
||||||
|
eo_conf.offset[i] = electricalOffsets[i];
|
||||||
|
wo_conf.offset[i] = wiringOffsets[i];
|
||||||
|
}
|
||||||
|
rc = ioctl(boardFileDescriptor, ATCA_PCIE_IOPS_EO_OFFSETS, &eo_conf);
|
||||||
|
rc = ioctl(boardFileDescriptor, ATCA_PCIE_IOPS_WO_OFFSETS, &wo_conf);
|
||||||
|
|
||||||
|
rc = ioctl(boardFileDescriptor, ATCA_PCIE_IOPG_STATUS, &statusReg);
|
||||||
|
if (rc) {
|
||||||
|
ok = false;
|
||||||
|
REPORT_ERROR(ErrorManagement::FatalError, "Device Status Reg %d, 0x%x", rc, statusReg);
|
||||||
|
}
|
||||||
|
rc = ioctl(boardFileDescriptor, ATCA_PCIE_IOPT_ACQ_ENABLE);
|
||||||
|
//rc = ioctl(boardFileDescriptor, ATCA_PCIE_IOPT_DMA_DISABLE);
|
||||||
|
Sleep::Busy(0.001); // in Sec
|
||||||
|
rc = ioctl(boardFileDescriptor, ATCA_PCIE_IOPT_ACQ_DISABLE);
|
||||||
|
|
||||||
|
rc = ioctl(boardFileDescriptor, ATCA_PCIE_IOPT_IRQ_DISABLE);
|
||||||
|
rc = ioctl(boardFileDescriptor, ATCA_PCIE_IOPT_STREAM_ENABLE);
|
||||||
|
//rc = ioctl(boardFileDescriptor, ATCA_PCIE_IOPG_STATUS, &statusReg);
|
||||||
|
Sleep::Busy(0.0011); // in Sec
|
||||||
|
int32 currentDMA = 0u;// = CurrentBufferIndex(200);
|
||||||
|
for (i = 0u; i < 1; i++) {
|
||||||
|
oldestBufferIdx = GetOldestBufferIdx();
|
||||||
|
currentDMA = PollDma(HighResolutionTimer::Counter() + 2000000u); // wait max 2ms
|
||||||
|
REPORT_ERROR(ErrorManagement::Information, "AtcaIopADC::CurrentBufferIndex: %d, Idx: %d", currentDMA, oldestBufferIdx);
|
||||||
|
}
|
||||||
|
REPORT_ERROR(ErrorManagement::Information, "AtcaIopADC::CurrentBufferIndex: %d", currentDMA);
|
||||||
|
//REPORT_ERROR(ErrorManagement::Warning, "SleepTime %d, count:0x%x", sleepTime, pdma[3].head_time_cnt);
|
||||||
|
uint32 nOfFunctions = GetNumberOfFunctions();
|
||||||
|
float32 cycleFrequency = -1.0F;
|
||||||
|
bool frequencyFound = false;
|
||||||
|
uint32 functionIdx;
|
||||||
|
|
||||||
|
//How many GAMs (functions) are interacting with this DataSource?
|
||||||
|
for (functionIdx = 0u; (functionIdx < nOfFunctions) && (ok); functionIdx++) {
|
||||||
|
uint32 nOfSignals = 0u;
|
||||||
|
ok = GetFunctionNumberOfSignals(InputSignals, functionIdx, nOfSignals);
|
||||||
|
uint32 i;
|
||||||
|
for (i = 0u; (i < nOfSignals) && (ok); i++) {
|
||||||
|
if (!frequencyFound) {
|
||||||
|
ok = GetFunctionSignalReadFrequency(InputSignals, functionIdx, i, cycleFrequency);
|
||||||
|
//Found a GAM that wants to synchronise on this DataSourceI. We need to have one and exactly one GAM asking to synchronise in this DataSource.
|
||||||
|
frequencyFound = (cycleFrequency > 0.F);
|
||||||
|
}
|
||||||
|
bool isCounter = false;
|
||||||
|
bool isTime = false;
|
||||||
|
bool isAdc = false;
|
||||||
|
// bool isAdcDecim = false;
|
||||||
|
//bool isAdcSim = false;
|
||||||
|
uint32 signalIdx = 0u;
|
||||||
|
uint32 nSamples = 0u;
|
||||||
|
uint32 nElements = 0u;
|
||||||
|
|
||||||
|
ok = GetFunctionSignalSamples(InputSignals, functionIdx, i, nSamples);
|
||||||
|
|
||||||
|
//Is the counter or the time signal?
|
||||||
|
StreamString signalAlias;
|
||||||
|
if (ok) {
|
||||||
|
ok = GetFunctionSignalAlias(InputSignals, functionIdx, i, signalAlias);
|
||||||
|
}
|
||||||
|
if (ok) {
|
||||||
|
ok = GetSignalIndex(signalIdx, signalAlias.Buffer());
|
||||||
|
}
|
||||||
|
if (ok) {
|
||||||
|
isCounter = (signalIdx == 0u);
|
||||||
|
isTime = (signalIdx == 1u);
|
||||||
|
//isAdcDecim = (signalIdx == 2u);
|
||||||
|
isAdc= (signalIdx < ATCA_IOP_N_TIMCNT + ATCA_IOP_N_ADCs + ATCA_IOP_N_INTEGRALS);
|
||||||
|
//isAdcSim = (signalIdx < ATCA_IOP_N_SIGNALS);
|
||||||
|
if (isCounter) {
|
||||||
|
if (nSamples > 1u) {
|
||||||
|
ok = false;
|
||||||
|
REPORT_ERROR(ErrorManagement::ParametersError, "The first signal (counter) shall have one and only one sample");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (isTime) {
|
||||||
|
if (nSamples > 1u) {
|
||||||
|
ok = false;
|
||||||
|
REPORT_ERROR(ErrorManagement::ParametersError, "The second signal (time) shall have one and only one sample");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
else if (isAdcDecim) {
|
||||||
|
ok = GetSignalNumberOfElements(signalIdx, nElements);
|
||||||
|
REPORT_ERROR(ErrorManagement::Information, "The ADC decim Signal Elements %d", nElements);
|
||||||
|
// if (nSamples > 1u) {
|
||||||
|
// ok = false;
|
||||||
|
// REPORT_ERROR(ErrorManagement::ParametersError, "The second signal (time) shall have one and only one sample");
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
else if (isAdc) {
|
||||||
|
if (nSamples > 1u) {
|
||||||
|
ok = false;
|
||||||
|
REPORT_ERROR(ErrorManagement::ParametersError, "The ATCA-IOP signals shall have one and only one sample");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
else if (isAdcSim) {
|
||||||
|
//How many samples to read for each cycle?
|
||||||
|
if (adcSamplesPerCycle == 0u) {
|
||||||
|
adcSamplesPerCycle = nSamples;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (adcSamplesPerCycle != nSamples) {
|
||||||
|
ok = false;
|
||||||
|
REPORT_ERROR(ErrorManagement::ParametersError, "All the ADC signals shall have the same number of samples");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
else {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ok) {
|
||||||
|
ok = frequencyFound;
|
||||||
|
if (!ok) {
|
||||||
|
REPORT_ERROR(ErrorManagement::ParametersError, "No frequency > 0 was set (i.e. no signal synchronises on this AtcaIopADC).");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ok) {
|
||||||
|
REPORT_ERROR(ErrorManagement::Information, "The timer will be set using a cycle frequency of %f Hz", cycleFrequency);
|
||||||
|
|
||||||
|
float64 periodUsec = (1e6 / cycleFrequency);
|
||||||
|
timerPeriodUsecTime = static_cast<uint32>(periodUsec);
|
||||||
|
float64 sleepTimeT = (static_cast<float64>(HighResolutionTimer::Frequency()) / cycleFrequency);
|
||||||
|
sleepTimeTicks = static_cast<uint64>(sleepTimeT);
|
||||||
|
REPORT_ERROR(ErrorManagement::Information,
|
||||||
|
"The timer will be set using a sleepTimeTicks of %d (ns)", sleepTimeTicks);
|
||||||
|
}
|
||||||
|
if (ok) {
|
||||||
|
//float32 totalNumberOfSamplesPerSecond = (static_cast<float32>(adcSamplesPerCycle) * cycleFrequency);
|
||||||
|
float32 totalNumberOfSamplesPerSecond = (static_cast<float32>(rtDecimation) * cycleFrequency);
|
||||||
|
ok = (adcFrequency == static_cast<uint32>(totalNumberOfSamplesPerSecond));
|
||||||
|
if (!ok) {
|
||||||
|
REPORT_ERROR(ErrorManagement::ParametersError,
|
||||||
|
"The adcSamplesPerCycle * cycleFrequency (%u) shall be equal to the ADCs acquisition frequency (%u)",
|
||||||
|
totalNumberOfSamplesPerSecond, adcFrequency);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 AtcaIopADC::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 AtcaIopADC::GetSignalMemoryBuffer(const uint32 signalIdx, const uint32 bufferIdx, void*& signalAddress) {
|
||||||
|
bool ok = true;
|
||||||
|
if (signalIdx == 0u) {
|
||||||
|
signalAddress = &counterAndTimer[0];
|
||||||
|
}
|
||||||
|
else if (signalIdx == 1u) {
|
||||||
|
signalAddress = &counterAndTimer[1];
|
||||||
|
}
|
||||||
|
else if (signalIdx < ATCA_IOP_N_TIMCNT + ATCA_IOP_N_ADCs ) {
|
||||||
|
signalAddress = &adcValues[signalIdx - ATCA_IOP_N_TIMCNT];
|
||||||
|
}
|
||||||
|
else if (signalIdx < ATCA_IOP_N_TIMCNT + ATCA_IOP_N_ADCs + ATCA_IOP_N_INTEGRALS) {
|
||||||
|
signalAddress = &adcIntegralValues[signalIdx -
|
||||||
|
(ATCA_IOP_N_TIMCNT + ATCA_IOP_N_ADCs)];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ok = false;
|
||||||
|
}
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char8* AtcaIopADC::GetBrokerName(StructuredDataI& data, const SignalDirection direction) {
|
||||||
|
const char8 *brokerName = NULL_PTR(const char8 *);
|
||||||
|
if (direction == InputSignals) {
|
||||||
|
float32 frequency = 0.F;
|
||||||
|
if (!data.Read("Frequency", frequency)) {
|
||||||
|
frequency = -1.F;
|
||||||
|
}
|
||||||
|
if (frequency > 0.F) {
|
||||||
|
brokerName = "MemoryMapSynchronisedInputBroker";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
brokerName = "MemoryMapInputBroker";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
REPORT_ERROR(ErrorManagement::ParametersError, "DataSource not compatible with OutputSignals");
|
||||||
|
}
|
||||||
|
return brokerName;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AtcaIopADC::Synchronise() {
|
||||||
|
ErrorManagement::ErrorType err;
|
||||||
|
err = synchSem.ResetWait(TTInfiniteWait);
|
||||||
|
return err.ErrorsCleared();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*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 AtcaIopADC::PrepareNextState(const char8* const currentStateName, const char8* const nextStateName) {
|
||||||
|
bool ok = true;
|
||||||
|
if (executor.GetStatus() == EmbeddedThreadI::OffState) {
|
||||||
|
ok = executor.Start();
|
||||||
|
REPORT_ERROR(ErrorManagement::Information, "Executor Start");
|
||||||
|
}
|
||||||
|
counterAndTimer[0] = 0u;
|
||||||
|
//counterAndTimer[1] = 0u;
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*lint -e{715} [MISRA C++ Rule 0-1-11], [MISRA C++ Rule 0-1-12]. Justification: the method sleeps for the given period irrespectively of the input info.*/
|
||||||
|
ErrorManagement::ErrorType AtcaIopADC::Execute(ExecutionInfo& info) {
|
||||||
|
if (lastTimeTicks == 0u) {
|
||||||
|
lastTimeTicks = HighResolutionTimer::Counter();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64 startTicks = HighResolutionTimer::Counter();
|
||||||
|
//If we lose cycle, rephase to a multiple of the period.
|
||||||
|
uint32 nCycles = 0u;
|
||||||
|
while (lastTimeTicks < startTicks) {
|
||||||
|
lastTimeTicks += sleepTimeTicks;
|
||||||
|
nCycles++;
|
||||||
|
}
|
||||||
|
lastTimeTicks -= sleepTimeTicks;
|
||||||
|
|
||||||
|
//Sleep until the next period. Cannot be < 0 due to while(lastTimeTicks < startTicks) above
|
||||||
|
uint64 sleepTicksCorrection = (startTicks - lastTimeTicks);
|
||||||
|
uint64 deltaTicks = sleepTimeTicks - sleepTicksCorrection;
|
||||||
|
//volatile int32 currentDMA = 0u;
|
||||||
|
oldestBufferIdx = GetOldestBufferIdx();
|
||||||
|
if (sleepNature == Busy) {
|
||||||
|
if (sleepPercentage == 0u) {
|
||||||
|
//currentDMA =
|
||||||
|
PollDma(startTicks + deltaTicks + 100000u); // TODO check max wait
|
||||||
|
//while ((HighResolutionTimer::Counter() - startTicks) < deltaTicks) {
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
float32 totalSleepTime = static_cast<float32>(static_cast<float64>(deltaTicks) * HighResolutionTimer::Period());
|
||||||
|
uint32 busyPercentage = (100u - sleepPercentage);
|
||||||
|
float32 busyTime = totalSleepTime * (static_cast<float32>(busyPercentage) / 100.F);
|
||||||
|
Sleep::SemiBusy(totalSleepTime, busyTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
float32 sleepTime = static_cast<float32>(static_cast<float64>(deltaTicks) * HighResolutionTimer::Period());
|
||||||
|
Sleep::NoMore(sleepTime);
|
||||||
|
}
|
||||||
|
lastTimeTicks = HighResolutionTimer::Counter();
|
||||||
|
|
||||||
|
ErrorManagement::ErrorType err = synchSem.Post();
|
||||||
|
counterAndTimer[0] += nCycles;
|
||||||
|
//counterAndTimer[1] = counterAndTimer[0] * timerPeriodUsecTime;
|
||||||
|
counterAndTimer[1] = mappedDmaBase[oldestBufferIdx * RT_PCKT_SIZE] * timerPeriodUsecTime;
|
||||||
|
// Get adc data from DMA packet
|
||||||
|
uint32 k;
|
||||||
|
uint32 s;
|
||||||
|
for (k=0u; k < ATCA_IOP_N_ADCs ; k++) {
|
||||||
|
adcValues[k] = (mappedDmaBase[oldestBufferIdx * RT_PCKT_SIZE +
|
||||||
|
IOP_ADC_OFFSET + k] ) / (1<<14);
|
||||||
|
}
|
||||||
|
int64 * mappedDmaBase64 = (int64 *) mappedDmaBase;
|
||||||
|
for (k=0u; k < ATCA_IOP_N_INTEGRALS ; k++) {
|
||||||
|
adcIntegralValues[k] = mappedDmaBase64[oldestBufferIdx * RT_PCKT64_SIZE + IOP_ADC_INTEG_OFFSET + k];
|
||||||
|
}
|
||||||
|
|
||||||
|
float64 t = counterAndTimer[1];
|
||||||
|
t /= 1e6;
|
||||||
|
// Compute simulated Sinus Signals
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ProcessorType& AtcaIopADC::GetCPUMask() const {
|
||||||
|
return cpuMask;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 AtcaIopADC::GetStackSize() const {
|
||||||
|
return stackSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 AtcaIopADC::GetSleepPercentage() const {
|
||||||
|
return sleepPercentage;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32 AtcaIopADC::PollDma(uint64 waitLimitTicks) const {
|
||||||
|
uint32 buffIdx = oldestBufferIdx;
|
||||||
|
uint32 oldBufferFooter = mappedDmaBase[buffIdx * RT_PCKT_SIZE + 62];
|
||||||
|
uint32 freshBufferFooter = oldBufferFooter;
|
||||||
|
uint64 actualTime = HighResolutionTimer::Counter();
|
||||||
|
while (freshBufferFooter == oldBufferFooter) {
|
||||||
|
if(actualTime > waitLimitTicks) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
actualTime = HighResolutionTimer::Counter();
|
||||||
|
freshBufferFooter = mappedDmaBase[buffIdx * RT_PCKT_SIZE + 62];
|
||||||
|
}
|
||||||
|
uint32 headTimeMark = mappedDmaBase[buffIdx * RT_PCKT_SIZE];
|
||||||
|
if(headTimeMark != freshBufferFooter)
|
||||||
|
{
|
||||||
|
//currentBufferIdx = buffIdx;
|
||||||
|
//currentMasterHeader = pdma[currentBufferIdx].head_time_cnt;
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
return buffIdx;
|
||||||
|
}
|
||||||
|
uint32 AtcaIopADC::GetOldestBufferIdx() const {
|
||||||
|
volatile uint32 oldestBufferHeader = mappedDmaBase[0];
|
||||||
|
uint32 buffIdx = 0u;
|
||||||
|
|
||||||
|
volatile uint32 header = mappedDmaBase[0];
|
||||||
|
for (uint32 dmaIndex = 1u; dmaIndex < NUMBER_OF_BUFFERS; dmaIndex++) {
|
||||||
|
header = mappedDmaBase[dmaIndex * RT_PCKT_SIZE];
|
||||||
|
if (header < oldestBufferHeader) {
|
||||||
|
oldestBufferHeader = header;
|
||||||
|
buffIdx = dmaIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return buffIdx;
|
||||||
|
}
|
||||||
|
|
||||||
|
CLASS_REGISTER(AtcaIopADC, "1.0")
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// vim: syntax=cpp ts=4 sw=4 sts=4 sr et
|
||||||
435
DataSources/AtcaIop/AtcaIopADC.h
Normal file
435
DataSources/AtcaIop/AtcaIopADC.h
Normal file
@@ -0,0 +1,435 @@
|
|||||||
|
/**
|
||||||
|
* @file AtcaIopADC.h
|
||||||
|
* @brief Header file for class AtcaIopADC
|
||||||
|
* @date 19/10/2023
|
||||||
|
* @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 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ATCA_IOP_ADC_H
|
||||||
|
#define ATCA_IOP_ADC_H
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/* Standard header includes */
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/* Project header includes */
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
#include "DataSourceI.h"
|
||||||
|
#include "EventSem.h"
|
||||||
|
#include "EmbeddedServiceMethodBinderI.h"
|
||||||
|
#include "SingleThreadService.h"
|
||||||
|
#include "MessageI.h"
|
||||||
|
#include "RegisteredMethodsMessageFilter.h"
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/* Class declaration */
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
namespace MARTe {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The number of signals (2 time signals + ).
|
||||||
|
*/
|
||||||
|
const uint32 ATCA_IOP_MAX_CHANNELS = 32u;
|
||||||
|
|
||||||
|
const uint32 ATCA_IOP_N_TIMCNT = 2u;
|
||||||
|
const uint32 ATCA_IOP_N_ADCs = 12u;
|
||||||
|
const uint32 ATCA_IOP_N_INTEGRALS = ATCA_IOP_N_ADCs ; //12u;
|
||||||
|
//const uint32 ADC_SIMULATOR_N_ADCs = 2u;
|
||||||
|
const uint32 ATCA_IOP_N_SIGNALS = (ATCA_IOP_N_TIMCNT + 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
|
||||||
|
* <pre>
|
||||||
|
* +ADCSim = {
|
||||||
|
* Class = ADCSimulator
|
||||||
|
* DeviceName = "/dev/atca_v6" //Mandatory
|
||||||
|
* BoardId = 0 // Mandatory
|
||||||
|
* ChopperPeriod = 2000
|
||||||
|
* ElectricalOffsets = {1, 10, 20, -30, 1, 1, -10, 10}
|
||||||
|
* WiringOffsets = {1, 10, 20, -30, 1, 1, -10, 10}
|
||||||
|
* ADCFrequency = 2000000
|
||||||
|
* Signals = {
|
||||||
|
* Counter = {
|
||||||
|
* Type = uint32 //int32 also supported
|
||||||
|
* }
|
||||||
|
* Time = {
|
||||||
|
* Type = uint32 //int32 also supported
|
||||||
|
* Frequency = 1000
|
||||||
|
* }
|
||||||
|
* ADC0 = {
|
||||||
|
* Type = uint32
|
||||||
|
* }
|
||||||
|
* ADC1 = {
|
||||||
|
* Type = uint32
|
||||||
|
* }
|
||||||
|
* ADC2 = {
|
||||||
|
* Type = uint32
|
||||||
|
* }
|
||||||
|
* ADC3 = {
|
||||||
|
* Type = uint32
|
||||||
|
* }
|
||||||
|
* ADC0Decim = {
|
||||||
|
* Type = uint32
|
||||||
|
* }
|
||||||
|
* ADC1Decim = {
|
||||||
|
* Type = uint32
|
||||||
|
* }
|
||||||
|
* ADC2Decim = {
|
||||||
|
* Type = uint32
|
||||||
|
* }
|
||||||
|
* ...
|
||||||
|
* ADC7Decim = {
|
||||||
|
* Type = uint32
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* </pre>
|
||||||
|
*/
|
||||||
|
class AtcaIopADC: public DataSourceI, public MessageI, public EmbeddedServiceMethodBinderI {
|
||||||
|
public:
|
||||||
|
CLASS_REGISTER_DECLARATION()
|
||||||
|
/**
|
||||||
|
* @brief Default constructor
|
||||||
|
* @post
|
||||||
|
* Counter = 0
|
||||||
|
* Time = 0
|
||||||
|
*/
|
||||||
|
AtcaIopADC ();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Destructor. Stops the EmbeddedThread.
|
||||||
|
*/
|
||||||
|
virtual ~AtcaIopADC();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief See DataSourceI::AllocateMemory.
|
||||||
|
*/
|
||||||
|
virtual bool AllocateMemory();
|
||||||
|
|
||||||
|
/**
|
||||||
|
gg* @brief See DataSourceI::GetNumberOfMemoryBuffers.
|
||||||
|
* @return 1.
|
||||||
|
*/
|
||||||
|
virtual uint32 GetNumberOfMemoryBuffers();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief See DataSourceI::GetNumberOfMemoryBuffers.
|
||||||
|
*/
|
||||||
|
virtual bool GetSignalMemoryBuffer(const uint32 signalIdx,
|
||||||
|
const uint32 bufferIdx,
|
||||||
|
void *&signalAddress);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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 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();
|
||||||
|
|
||||||
|
/**
|
||||||
|
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 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 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 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 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 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 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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find the currentDMABufferIndex and synchronize on data arrival
|
||||||
|
*/
|
||||||
|
// int32 CurrentBufferIndex(uint64 waitLimitUs) 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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The board Dma descriptor
|
||||||
|
*/
|
||||||
|
int32 boardDmaDescriptor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The two supported sleep natures.
|
||||||
|
*/
|
||||||
|
enum AtcaIopADCSleepNature {
|
||||||
|
Default = 0,
|
||||||
|
Busy = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The non-busy sleep percentage. Valid if
|
||||||
|
* AtcaIopADCSleepNature == Busy
|
||||||
|
*/
|
||||||
|
uint32 sleepPercentage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The selected sleep nature.
|
||||||
|
*/
|
||||||
|
AtcaIopADCSleepNature sleepNature;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Current counter and timer
|
||||||
|
*/
|
||||||
|
uint32 counterAndTimer[2];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ADC values
|
||||||
|
*/
|
||||||
|
int32 adcValues[ATCA_IOP_MAX_CHANNELS];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ADC Integral values
|
||||||
|
*/
|
||||||
|
int64 adcIntegralValues[ATCA_IOP_MAX_CHANNELS];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Number of samples to read on each cycle
|
||||||
|
*/
|
||||||
|
uint32 adcSamplesPerCycle;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The semaphore for the synchronisation between the EmbeddedThread and the Synchronise method.
|
||||||
|
*/
|
||||||
|
EventSem synchSem;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The EmbeddedThread where the Execute method waits for the period to elapse.
|
||||||
|
*/
|
||||||
|
SingleThreadService executor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HighResolutionTimer::Counter() value after the last Sleep.
|
||||||
|
*/
|
||||||
|
uint64 lastTimeTicks;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sleeping period in units of ticks.
|
||||||
|
*/
|
||||||
|
uint64 sleepTimeTicks;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sleeping period.
|
||||||
|
*/
|
||||||
|
uint32 timerPeriodUsecTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Index of the function which has the signal that synchronises on this DataSourceI.
|
||||||
|
*/
|
||||||
|
uint32 synchronisingFunctionIdx;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The affinity of the thread that asynchronously generates the time.
|
||||||
|
*/
|
||||||
|
ProcessorType cpuMask;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The size of the stack of the thread that asynchronously generates the time.
|
||||||
|
*/
|
||||||
|
uint32 stackSize;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The simulated signals frequencies.
|
||||||
|
*/
|
||||||
|
//float32 signalsFrequencies[4];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The simulated signals gains.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Electrical Offset Parameters.
|
||||||
|
*/
|
||||||
|
int32 electricalOffsets[ATCA_IOP_MAX_CHANNELS];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Wiring Offset Parameters.
|
||||||
|
*/
|
||||||
|
float32 wiringOffsets[ATCA_IOP_MAX_CHANNELS];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The ADC chopping period in samples
|
||||||
|
*/
|
||||||
|
uint16 chopperPeriod;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The simulated ADC frequency
|
||||||
|
*/
|
||||||
|
uint32 adcFrequency;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The simulated ADC period
|
||||||
|
*/
|
||||||
|
float64 adcPeriod;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For the ATCA Master board
|
||||||
|
*/
|
||||||
|
uint32 isMaster;
|
||||||
|
/**
|
||||||
|
* Pointer to mapped memory
|
||||||
|
*/
|
||||||
|
int32 * mappedDmaBase;
|
||||||
|
uint32 mappedDmaSize;
|
||||||
|
/**
|
||||||
|
* The last written buffer
|
||||||
|
*/
|
||||||
|
uint8 currentBufferIdx;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 PollDma(uint64 waitLimitTicks) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* filter to receive the RPC which ...
|
||||||
|
*/
|
||||||
|
ReferenceT<RegisteredMethodsMessageFilter> filter;
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/* Inline method definitions */
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#endif /* ATCA_IOP_ADC_H */
|
||||||
|
|
||||||
|
// vim: syntax=cpp ts=4 sw=4 sts=4 sr et
|
||||||
374
DataSources/AtcaIop/AtcaIopDAC.cpp
Normal file
374
DataSources/AtcaIop/AtcaIopDAC.cpp
Normal file
@@ -0,0 +1,374 @@
|
|||||||
|
/**
|
||||||
|
* @file AtcaIopDAC.cpp
|
||||||
|
* @brief Source file for class AtcaIopDAC
|
||||||
|
* @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 AtcaIopDAC (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 <unistd.h> // for close()
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/* Project header includes */
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
#include "AdvancedErrorManagement.h"
|
||||||
|
#include "MemoryMapSynchronisedOutputBroker.h"
|
||||||
|
#include "AtcaIopDAC.h"
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/* Static definitions */
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/* Method definitions */
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
namespace MARTe {
|
||||||
|
const float32 DAC_RANGE = 20.0;
|
||||||
|
const float32 ATCA_IOP_MAX_DAC_RANGE = 20.0;
|
||||||
|
AtcaIopDAC::AtcaIopDAC() :
|
||||||
|
DataSourceI(),
|
||||||
|
MessageI() {
|
||||||
|
boardFileDescriptor = -1;
|
||||||
|
numberOfDACsEnabled = 0u;
|
||||||
|
//isMaster = 0u;
|
||||||
|
deviceName = "";
|
||||||
|
triggerSet = false;
|
||||||
|
uint32 n;
|
||||||
|
for (n = 0u; n < ATCA_IOP_MAX_DAC_CHANNELS; n++) {
|
||||||
|
//dacEnabled[n] = false;
|
||||||
|
outputRange[n] = ATCA_IOP_MAX_DAC_RANGE;
|
||||||
|
}
|
||||||
|
|
||||||
|
channelsMemory = NULL_PTR(float32 *);
|
||||||
|
|
||||||
|
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.*/
|
||||||
|
AtcaIopDAC::~AtcaIopDAC() {
|
||||||
|
if (boardFileDescriptor != -1) {
|
||||||
|
uint32 statusReg = 0;
|
||||||
|
//REPORT_ERROR(ErrorManagement::Information, " Close Device Status Reg %d, 0x%x", rc, statusReg);
|
||||||
|
close(boardFileDescriptor);
|
||||||
|
REPORT_ERROR(ErrorManagement::Information, "Close device %d OK. Status Reg 0x%x,", boardFileDescriptor, statusReg);
|
||||||
|
}
|
||||||
|
if (channelsMemory != NULL_PTR(float32 *)) {
|
||||||
|
delete[] channelsMemory;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AtcaIopDAC::AllocateMemory() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 AtcaIopDAC::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 AtcaIopDAC::GetSignalMemoryBuffer(const uint32 signalIdx, const uint32 bufferIdx, void*& signalAddress) {
|
||||||
|
bool ok = (signalIdx < (ATCA_IOP_MAX_DAC_CHANNELS));
|
||||||
|
if (ok) {
|
||||||
|
if (channelsMemory != NULL_PTR(float32 *)) {
|
||||||
|
signalAddress = &(channelsMemory[signalIdx]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char8* AtcaIopDAC::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 AtcaIopDAC::GetInputBrokers(ReferenceContainer& inputBrokers, const char8* const functionName, void* const gamMemPtr) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AtcaIopDAC::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 AtcaIopDAC::PrepareNextState(const char8* const currentStateName, const char8* const nextStateName) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AtcaIopDAC::Initialise(StructuredDataI& data) {
|
||||||
|
bool ok = DataSourceI::Initialise(data);
|
||||||
|
if (ok) {
|
||||||
|
ok = data.Read("DeviceName", deviceName);
|
||||||
|
if (!ok) {
|
||||||
|
REPORT_ERROR(ErrorManagement::ParametersError, "The DeviceName shall be specified");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//if (!data.Read("IsMaster", isMaster)) {
|
||||||
|
// REPORT_ERROR(ErrorManagement::Warning, "IsMaster not specified. Using default: %d", isMaster);
|
||||||
|
//}
|
||||||
|
|
||||||
|
//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(i))) {
|
||||||
|
//uint32 channelId;
|
||||||
|
float32 range;
|
||||||
|
ok = data.Read("OutputRange", range);
|
||||||
|
if (ok) {
|
||||||
|
//if (data.Read("OutputRange", range)) {
|
||||||
|
ok = (range > 0.0) && (range <= ATCA_IOP_MAX_DAC_RANGE);
|
||||||
|
if (!ok) {
|
||||||
|
REPORT_ERROR(ErrorManagement::ParametersError, "Invalid OutputRange specified.");
|
||||||
|
}
|
||||||
|
if (ok) {
|
||||||
|
outputRange[i] = range;
|
||||||
|
REPORT_ERROR(ErrorManagement::Information, " Parameter DAC %d Output Range %f", i, range);
|
||||||
|
//dacEnabled[i] = true;
|
||||||
|
numberOfDACsEnabled++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
REPORT_ERROR(ErrorManagement::ParametersError, "The OutputRange shall be specified.");
|
||||||
|
}
|
||||||
|
if (ok) {
|
||||||
|
ok = data.MoveToAncestor(1u);
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ok) {
|
||||||
|
ok = data.MoveToAncestor(1u);
|
||||||
|
if (!ok) {
|
||||||
|
REPORT_ERROR(ErrorManagement::ParametersError, "Could not move to the parent section");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
REPORT_ERROR(ErrorManagement::Information, "numberOfDACsEnabled %d", numberOfDACsEnabled);
|
||||||
|
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AtcaIopDAC::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(i) == 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");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StreamString fullDeviceName;
|
||||||
|
//Configure the board
|
||||||
|
if (ok) {
|
||||||
|
ok = fullDeviceName.Printf("%s", deviceName.Buffer());
|
||||||
|
}
|
||||||
|
if (ok) {
|
||||||
|
ok = fullDeviceName.Seek(0LLU);
|
||||||
|
}
|
||||||
|
if (ok) {
|
||||||
|
boardFileDescriptor = open(fullDeviceName.Buffer(), O_RDWR);
|
||||||
|
ok = (boardFileDescriptor > -1);
|
||||||
|
if (!ok) {
|
||||||
|
REPORT_ERROR_PARAMETERS(ErrorManagement::ParametersError, "Could not open device %s", fullDeviceName);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
REPORT_ERROR(ErrorManagement::Information, "Open device %s OK", fullDeviceName);
|
||||||
|
}
|
||||||
|
if (ok) {
|
||||||
|
//Allocate memory
|
||||||
|
channelsMemory = new float32[ATCA_IOP_MAX_DAC_CHANNELS];
|
||||||
|
}
|
||||||
|
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool AtcaIopDAC::Synchronise() {
|
||||||
|
uint32 i;
|
||||||
|
int32 w;
|
||||||
|
bool ok = true;
|
||||||
|
if (channelsMemory != NULL_PTR(float32 *)) {
|
||||||
|
|
||||||
|
// value = channelsMemory[0] / DAC_RANGE;
|
||||||
|
for (i = 0u; (i < 2u) && (ok); i++) {
|
||||||
|
//for (i = 0u; (i < numberOfDACsEnabled ) && (ok); i++) {
|
||||||
|
float32 value = channelsMemory[i] / outputRange[i];
|
||||||
|
w = SetDacReg(i, value);
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32 AtcaIopDAC::SetDacReg(uint32 channel, float32 val) const {
|
||||||
|
if (val > 1.0)
|
||||||
|
val = 1.0;
|
||||||
|
if (val < -1.0)
|
||||||
|
val = -1.0;
|
||||||
|
int32 dacReg = static_cast<int32>(val * pow(2,17));
|
||||||
|
if (dacReg > 0x1FFFF) // 131071
|
||||||
|
dacReg = 0x1FFFF;
|
||||||
|
if (dacReg < -131072) // -0x20000
|
||||||
|
dacReg = -131072;
|
||||||
|
dacReg &= 0x0003FFFF; // keep 18 lsb
|
||||||
|
dacReg |= (0xF & channel) << 28;
|
||||||
|
return dacReg;
|
||||||
|
}
|
||||||
|
|
||||||
|
CLASS_REGISTER(AtcaIopDAC, "1.0")
|
||||||
|
}
|
||||||
|
// vim: syntax=cpp ts=4 sw=4 sts=4 sr et
|
||||||
236
DataSources/AtcaIop/AtcaIopDAC.h
Normal file
236
DataSources/AtcaIop/AtcaIopDAC.h
Normal file
@@ -0,0 +1,236 @@
|
|||||||
|
/**
|
||||||
|
* @file AtcaIopDAC.h
|
||||||
|
* @brief Header file for class AtcaIopDAC
|
||||||
|
* @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 AtcaIopDAC
|
||||||
|
* 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 ATCA_IOP_DAC_H
|
||||||
|
#define ATCA_IOP_DAC_H
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/* Standard header includes */
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/* Project header includes */
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
#include "DataSourceI.h"
|
||||||
|
#include "EventSem.h"
|
||||||
|
#include "EmbeddedServiceMethodBinderI.h"
|
||||||
|
#include "SingleThreadService.h"
|
||||||
|
#include "MessageI.h"
|
||||||
|
#include "RegisteredMethodsMessageFilter.h"
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/* Class declaration */
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
namespace MARTe {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The number of signals
|
||||||
|
*/
|
||||||
|
|
||||||
|
const uint32 ATCA_IOP_N_DACs = 2u;
|
||||||
|
const uint32 ATCA_IOP_MAX_DAC_CHANNELS = 16u;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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_0_DAC = {
|
||||||
|
* Class = AtcaIop::AtcaIopDAC
|
||||||
|
* DeviceName = "/dev/atca_v6_dac_2" //Mandatory
|
||||||
|
* Signals = {
|
||||||
|
* DAC0_0 = {
|
||||||
|
* 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.
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* </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 AtcaIopDAC: public DataSourceI, public MessageI {
|
||||||
|
public:
|
||||||
|
CLASS_REGISTER_DECLARATION()
|
||||||
|
/**
|
||||||
|
* @brief Default constructor
|
||||||
|
* @post
|
||||||
|
* Counter = 0
|
||||||
|
* Time = 0
|
||||||
|
*/
|
||||||
|
AtcaIopDAC ();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Destructor. Stops the EmbeddedThread.
|
||||||
|
*/
|
||||||
|
virtual ~AtcaIopDAC();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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 deviceName;
|
||||||
|
/**
|
||||||
|
* The board file descriptor
|
||||||
|
*/
|
||||||
|
int32 boardFileDescriptor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DAC values
|
||||||
|
*/
|
||||||
|
int32 dacValues[ATCA_IOP_N_DACs];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The signal memory
|
||||||
|
*/
|
||||||
|
float32 *channelsMemory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The DACs that are enabled
|
||||||
|
*/
|
||||||
|
// bool dacEnabled[ATCA_IOP_MAX_DAC_CHANNELS];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The board individual channel output ranges
|
||||||
|
*/
|
||||||
|
float32 outputRange[ATCA_IOP_MAX_DAC_CHANNELS];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/* Inline method definitions */
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#endif /* ATCA_IOP_DAC_H */
|
||||||
|
|
||||||
|
// vim: syntax=cpp ts=4 sw=4 sts=4 sr et
|
||||||
28
DataSources/AtcaIop/Makefile.cov
Normal file
28
DataSources/AtcaIop/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/AtcaIop/Makefile.gcc
Normal file
27
DataSources/AtcaIop/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
|
||||||
|
|
||||||
54
DataSources/AtcaIop/Makefile.inc
Normal file
54
DataSources/AtcaIop/Makefile.inc
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
#############################################################
|
||||||
|
#
|
||||||
|
# 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=AtcaIopDAC.x AtcaIopADC.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
|
||||||
|
|
||||||
|
all: $(OBJS) \
|
||||||
|
$(BUILD_DIR)/AtcaIop$(LIBEXT) \
|
||||||
|
$(BUILD_DIR)/AtcaIop$(DLLEXT)
|
||||||
|
echo $(OBJS)
|
||||||
|
|
||||||
|
include depends.$(TARGET)
|
||||||
|
|
||||||
|
include $(MAKEDEFAULTDIR)/MakeStdLibRules.$(TARGET)
|
||||||
|
|
||||||
93
DataSources/AtcaIop/include/atca-v6-iop-ioctl.h
Normal file
93
DataSources/AtcaIop/include/atca-v6-iop-ioctl.h
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
/**
|
||||||
|
* IOCTL Definitions for the Linux Device Driver
|
||||||
|
* Should be synchronized with:
|
||||||
|
* https://github.com/bernardocarvalho/atca-iop-stream/blob/master/linux-software/include/atca-v6-pcie-ioctl.h
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _ATCA_IOP_IOPTL_H_
|
||||||
|
#define _ATCA_IOP_IOPTL_H_
|
||||||
|
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
|
||||||
|
#define ADC_CHANNELS 16
|
||||||
|
#define DMA_BUFFS 8 // Number of DMA ch0 buffs
|
||||||
|
|
||||||
|
/* 256 + 3840 = 4096 B (PAGE_SIZE) data packet
|
||||||
|
typedef struct _DMA_CH1_PCKT {
|
||||||
|
volatile uint32_t head_time_cnt;
|
||||||
|
volatile uint32_t header; // h5431BACD
|
||||||
|
volatile int32_t channel[60]; // 24 56
|
||||||
|
volatile uint32_t foot_time_cnt;
|
||||||
|
volatile uint32_t footer; // h5431BACD
|
||||||
|
uint8_t page_fill[3840];
|
||||||
|
} DMA_CH1_PCKT;
|
||||||
|
*/
|
||||||
|
struct atca_eo_config {
|
||||||
|
int32_t offset[ADC_CHANNELS];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct atca_wo_config {
|
||||||
|
int32_t offset[ADC_CHANNELS];
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* IOCTL definitions
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Please use a different 8-bit number in your code */
|
||||||
|
/*See /Documentation/ioctl-number.txt*/
|
||||||
|
#define ATCA_PCIE_IOP_MAGIC 'k'
|
||||||
|
/* S means "Set": thru a pointer
|
||||||
|
* T means "Tell": directly with the argument value
|
||||||
|
* G menas "Get": reply by setting thru a pointer
|
||||||
|
* Q means "Qry": response is on the return value
|
||||||
|
* X means "eXchange": G and S atomically
|
||||||
|
* H means "sHift": T and Q atomically
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**********************************************************************
|
||||||
|
* IOCTL FUNCTIONS *
|
||||||
|
*********************************************************************/
|
||||||
|
#define ATCA_PCIE_IOPT_IRQ_ENABLE _IO(ATCA_PCIE_IOP_MAGIC, 1)
|
||||||
|
#define ATCA_PCIE_IOPT_IRQ_DISABLE _IO(ATCA_PCIE_IOP_MAGIC, 2)
|
||||||
|
#define ATCA_PCIE_IOPT_ACQ_ENABLE _IO(ATCA_PCIE_IOP_MAGIC, 3)
|
||||||
|
#define ATCA_PCIE_IOPT_ACQ_DISABLE _IO(ATCA_PCIE_IOP_MAGIC, 4)
|
||||||
|
#define ATCA_PCIE_IOPT_DMA_ENABLE _IO(ATCA_PCIE_IOP_MAGIC, 5)
|
||||||
|
#define ATCA_PCIE_IOPT_DMA_DISABLE _IO(ATCA_PCIE_IOP_MAGIC, 6)
|
||||||
|
#define ATCA_PCIE_IOPT_SOFT_TRIG _IO(ATCA_PCIE_IOP_MAGIC, 7)
|
||||||
|
#define ATCA_PCIE_IOPG_STATUS _IOR(ATCA_PCIE_IOP_MAGIC, 8, u_int32_t)
|
||||||
|
#define ATCA_PCIE_IOPS_RDTMOUT _IOW(ATCA_PCIE_IOP_MAGIC, 9, u_int32_t)
|
||||||
|
#define ATCA_PCIE_IOPS_DMA_SIZE _IOW(ATCA_PCIE_IOP_MAGIC, 10, u_int32_t)
|
||||||
|
#define ATCA_PCIE_IOPG_DMA_SIZE _IOR(ATCA_PCIE_IOP_MAGIC, 11, u_int32_t)
|
||||||
|
#define ATCA_PCIE_IOPT_DMA_RESET _IO(ATCA_PCIE_IOP_MAGIC, 12)
|
||||||
|
#define ATCA_PCIE_IOPT_STREAM_ENABLE _IO(ATCA_PCIE_IOP_MAGIC, 13)
|
||||||
|
#define ATCA_PCIE_IOPT_STREAM_DISABLE _IO(ATCA_PCIE_IOP_MAGIC, 14)
|
||||||
|
#define ATCA_PCIE_IOPT_CHOP_ON _IO(ATCA_PCIE_IOP_MAGIC, 15)
|
||||||
|
#define ATCA_PCIE_IOPT_CHOP_OFF _IO(ATCA_PCIE_IOP_MAGIC, 16)
|
||||||
|
#define ATCA_PCIE_IOPT_CHOP_DEFAULT_1 _IO(ATCA_PCIE_IOP_MAGIC, 17)
|
||||||
|
#define ATCA_PCIE_IOPT_CHOP_DEFAULT_0 _IO(ATCA_PCIE_IOP_MAGIC, 18)
|
||||||
|
#define ATCA_PCIE_IOPS_CHOP_COUNTERS _IOW(ATCA_PCIE_IOP_MAGIC, 19, u_int32_t)
|
||||||
|
#define ATCA_PCIE_IOPG_CHOP_COUNTERS _IOR(ATCA_PCIE_IOP_MAGIC, 20, u_int32_t)
|
||||||
|
#define ATCA_PCIE_IOPS_EO_OFFSETS \
|
||||||
|
_IOW(ATCA_PCIE_IOP_MAGIC, 21, struct atca_eo_config)
|
||||||
|
#define ATCA_PCIE_IOPS_WO_OFFSETS \
|
||||||
|
_IOW(ATCA_PCIE_IOP_MAGIC, 22, struct atca_wo_config)
|
||||||
|
#define ATCA_PCIE_IOPG_EO_OFFSETS \
|
||||||
|
_IOR(ATCA_PCIE_IOP_MAGIC, 23, struct atca_eo_config)
|
||||||
|
#define ATCA_PCIE_IOPG_WO_OFFSETS \
|
||||||
|
_IOR(ATCA_PCIE_IOP_MAGIC, 24, struct atca_wo_config)
|
||||||
|
|
||||||
|
#define ATCA_PCIE_IOPS_CONTROL _IOW(ATCA_PCIE_IOP_MAGIC, 25, u_int32_t)
|
||||||
|
#define ATCA_PCIE_IOPG_CONTROL _IOR(ATCA_PCIE_IOP_MAGIC, 26, u_int32_t)
|
||||||
|
|
||||||
|
#define ATCA_PCIE_IOPS_CHOP_DISABLE _IOW(ATCA_PCIE_IOP_MAGIC, 27, u_int32_t)
|
||||||
|
#define ATCA_PCIE_IOPG_CHOP_DISABLE _IOR(ATCA_PCIE_IOP_MAGIC, 28, u_int32_t)
|
||||||
|
|
||||||
|
#define ATCA_PCIE_IOPG_DACS_REG _IOR(ATCA_PCIE_IOP_MAGIC, 29, u_int32_t)
|
||||||
|
|
||||||
|
#define ATCA_PCIE_IOP_MAXNR 29
|
||||||
|
|
||||||
|
#endif /* _ATCA_IOP_IOPTL_H_ */
|
||||||
|
|
||||||
|
// vim: syntax=cpp ts=4 sw=4 sts=4 sr et
|
||||||
78
Startup/AtcaIop.sh
Executable file
78
Startup/AtcaIop.sh
Executable file
@@ -0,0 +1,78 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
#Arguments -f FILENAME -m MESSAGE | -s STATE [-d cgdb|strace]
|
||||||
|
# Must set MARTe2 instalation folders
|
||||||
|
#MARTe2_HOME=
|
||||||
|
#
|
||||||
|
#MARTe2_DIR=$MARTe2_HOME/MARTe2
|
||||||
|
#MARTe2_Components_DIR=$MARTe2_HOME/MARTe2-components
|
||||||
|
#MARTe2_Demos_DIR=$MARTe2_HOME/MARTe2-demos-padova
|
||||||
|
#EPICS_BASE=
|
||||||
|
|
||||||
|
MDS=0
|
||||||
|
DEBUG=""
|
||||||
|
INPUT_ARGS=$*
|
||||||
|
while test $# -gt 0
|
||||||
|
do
|
||||||
|
case "$1" in
|
||||||
|
-d|--debug)
|
||||||
|
DEBUG="$2"
|
||||||
|
;;
|
||||||
|
-mds)
|
||||||
|
MDS=1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
|
||||||
|
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$MARTe2_DIR/Build/x86-linux/Core/
|
||||||
|
|
||||||
|
#LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$MARTe2_Demos_DIR/Build/x86-linux/Components/DataSources/AtcaIop/
|
||||||
|
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:../Build/x86-linux/Components/DataSources/AtcaIop/
|
||||||
|
|
||||||
|
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$MARTe2_Components_DIR/Build/x86-linux/Components/DataSources/EPICSCA/
|
||||||
|
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$MARTe2_Components_DIR/Build/x86-linux/Components/DataSources/EPICSPVA/
|
||||||
|
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$MARTe2_Components_DIR/Build/x86-linux/Components/DataSources/LinuxTimer/
|
||||||
|
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$MARTe2_Components_DIR/Build/x86-linux/Components/DataSources/LoggerDataSource/
|
||||||
|
#LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$MARTe2_Components_DIR/Build/x86-linux/Components/DataSources/DAN/
|
||||||
|
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$MARTe2_Components_DIR/Build/x86-linux/Components/DataSources/FileDataSource/
|
||||||
|
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$MARTe2_Components_DIR/Build/x86-linux/Components/DataSources/LinkDataSource/
|
||||||
|
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$MARTe2_Components_DIR/Build/x86-linux/Components/DataSources/UDP/
|
||||||
|
#LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$MARTe2_Components_DIR/Build/x86-linux/Components/DataSources/MDSReader/
|
||||||
|
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$MARTe2_Components_DIR/Build/x86-linux/Components/DataSources/MDSWriter/
|
||||||
|
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$MARTe2_Components_DIR/Build/x86-linux/Components/DataSources/RealTimeThreadSynchronisation/
|
||||||
|
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$MARTe2_Components_DIR/Build/x86-linux/Components/DataSources/RealTimeThreadAsyncBridge/
|
||||||
|
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$MARTe2_Components_DIR/Build/x86-linux/Components/GAMs/ConstantGAM/
|
||||||
|
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$MARTe2_Components_DIR/Build/x86-linux/Components/GAMs/ConversionGAM/
|
||||||
|
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$MARTe2_Components_DIR/Build/x86-linux/Components/GAMs/IOGAM/
|
||||||
|
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$MARTe2_Components_DIR/Build/x86-linux/Components/GAMs/FilterGAM/
|
||||||
|
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$MARTe2_Components_DIR/Build/x86-linux/Components/GAMs/HistogramGAM/
|
||||||
|
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$MARTe2_Components_DIR/Build/x86-linux/Components/GAMs/SSMGAM/
|
||||||
|
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$MARTe2_Components_DIR/Build/x86-linux/Components/GAMs/TriggerOnChangeGAM/
|
||||||
|
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$MARTe2_Components_DIR/Build/x86-linux/Components/GAMs/WaveformGAM/
|
||||||
|
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$MARTe2_Components_DIR/Build/x86-linux/Components/Interfaces/BaseLib2Wrapper/
|
||||||
|
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$MARTe2_Components_DIR/Build/x86-linux/Components/Interfaces/EPICS/
|
||||||
|
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$MARTe2_Components_DIR/Build/x86-linux/Components/Interfaces/EPICSPVA/
|
||||||
|
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$MARTe2_Components_DIR/Build/x86-linux/Components/Interfaces/MemoryGate/
|
||||||
|
#LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$MARTe2_Components_DIR/Build/x86-linux/Components/Interfaces/NI9157Device/
|
||||||
|
#LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$MARTe2_Components_DIR/Build/x86-linux/Components/Interfaces/OPCUA/
|
||||||
|
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$MARTe2_Components_DIR/Build/x86-linux/Components/Interfaces/SysLogger/
|
||||||
|
|
||||||
|
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$EPICS_BASE/lib/$EPICS_HOST_ARCH
|
||||||
|
|
||||||
|
echo $LD_LIBRARY_PATH
|
||||||
|
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH
|
||||||
|
|
||||||
|
#if [ ${MDS} == 1 ]; then
|
||||||
|
#export rtappwriter_path=../Trees
|
||||||
|
#export rtappreader_path=../Trees
|
||||||
|
#export rtappdemo_path=../Trees
|
||||||
|
#mdstcl < CreateMDSTrees.tcl
|
||||||
|
#fi
|
||||||
|
|
||||||
|
if [ "$DEBUG" = "cgdb" ]
|
||||||
|
then
|
||||||
|
cgdb --args $MARTe2_DIR/Build/x86-linux/App/MARTeApp.ex $INPUT_ARGS
|
||||||
|
else
|
||||||
|
$MARTe2_DIR/Build/x86-linux/App/MARTeApp.ex $INPUT_ARGS
|
||||||
|
fi
|
||||||
|
|
||||||
4
Startup/ClearIsttokMDSTree.tcl
Normal file
4
Startup/ClearIsttokMDSTree.tcl
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
set tree rtappisttok
|
||||||
|
create pulse 1
|
||||||
|
exit
|
||||||
|
|
||||||
111
Startup/CreateIsttokMDSplusTree.tcl
Normal file
111
Startup/CreateIsttokMDSplusTree.tcl
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
edit rtappisttok/new
|
||||||
|
|
||||||
|
add node .ATCAIOP1
|
||||||
|
add node .INP
|
||||||
|
add node .REFS
|
||||||
|
add node .ERRORS
|
||||||
|
add node .CONTROLS
|
||||||
|
add node .STATES
|
||||||
|
add node .PERF
|
||||||
|
add node TIME/usage=signal
|
||||||
|
add node TIMED/usage=signal
|
||||||
|
|
||||||
|
set def \RTAPPISTTOK::TOP.ATCAIOP1
|
||||||
|
add node ADC0RAW/usage=signal
|
||||||
|
add node ADC0RAWD/usage=signal
|
||||||
|
add node ADC1RAW/usage=signal
|
||||||
|
add node ADC1RAWD/usage=signal
|
||||||
|
add node ADC2RAW/usage=signal
|
||||||
|
add node ADC2RAWD/usage=signal
|
||||||
|
add node ADC3RAW/usage=signal
|
||||||
|
add node ADC3RAWD/usage=signal
|
||||||
|
add node ADC4RAW/usage=signal
|
||||||
|
add node ADC4RAWD/usage=signal
|
||||||
|
add node ADC5RAW/usage=signal
|
||||||
|
add node ADC5RAWD/usage=signal
|
||||||
|
add node ADC6RAW/usage=signal
|
||||||
|
add node ADC6RAWD/usage=signal
|
||||||
|
add node ADC7RAW/usage=signal
|
||||||
|
add node ADC7RAWD/usage=signal
|
||||||
|
add node ADC8RAW/usage=signal
|
||||||
|
add node ADC8RAWD/usage=signal
|
||||||
|
add node ADC9RAW/usage=signal
|
||||||
|
add node ADC9RAWD/usage=signal
|
||||||
|
add node ADC10RAW/usage=signal
|
||||||
|
add node ADC10RAWD/usage=signal
|
||||||
|
add node ADC11RAW/usage=signal
|
||||||
|
add node ADC11RAWD/usage=signal
|
||||||
|
|
||||||
|
add node ADC0INT/usage=signal
|
||||||
|
add node ADC0INTD/usage=signal
|
||||||
|
add node ADC1INT/usage=signal
|
||||||
|
add node ADC1INTD/usage=signal
|
||||||
|
add node ADC2INT/usage=signal
|
||||||
|
add node ADC2INTD/usage=signal
|
||||||
|
add node ADC3INT/usage=signal
|
||||||
|
add node ADC3INTD/usage=signal
|
||||||
|
add node ADC4INT/usage=signal
|
||||||
|
add node ADC4INTD/usage=signal
|
||||||
|
add node ADC5INT/usage=signal
|
||||||
|
add node ADC5INTD/usage=signal
|
||||||
|
add node ADC6INT/usage=signal
|
||||||
|
add node ADC6INTD/usage=signal
|
||||||
|
add node ADC7INT/usage=signal
|
||||||
|
add node ADC7INTD/usage=signal
|
||||||
|
add node ADC8INT/usage=signal
|
||||||
|
add node ADC8INTD/usage=signal
|
||||||
|
add node ADC9INT/usage=signal
|
||||||
|
add node ADC9INTD/usage=signal
|
||||||
|
add node ADC10INT/usage=signal
|
||||||
|
add node ADC10INTD/usage=signal
|
||||||
|
add node ADC11INT/usage=signal
|
||||||
|
add node ADC11INTD/usage=signal
|
||||||
|
|
||||||
|
set def \RTAPPISTTOK::TOP.INP
|
||||||
|
add node MEAS0D/usage=signal
|
||||||
|
add node MEAS0/usage=signal
|
||||||
|
add node MEAS0D/usage=signal
|
||||||
|
add node MEAS0F/usage=signal
|
||||||
|
add node MEAS0FD/usage=signal
|
||||||
|
add node MEAS1/usage=signal
|
||||||
|
add node MEAS1D/usage=signal
|
||||||
|
add node MEAS1F/usage=signal
|
||||||
|
add node MEAS1FD/usage=signal
|
||||||
|
|
||||||
|
set def \RTAPPISTTOK::TOP.REFS
|
||||||
|
add node REF0/usage=signal
|
||||||
|
add node REF0D/usage=signal
|
||||||
|
add node REF1/usage=signal
|
||||||
|
add node REF1D/usage=signal
|
||||||
|
|
||||||
|
set def \RTAPPISTTOK::TOP.ERRORS
|
||||||
|
add node ERROR0/usage=signal
|
||||||
|
add node ERROR0D/usage=signal
|
||||||
|
add node ERROR1/usage=signal
|
||||||
|
add node ERROR1D/usage=signal
|
||||||
|
|
||||||
|
set def \RTAPPISTTOK::TOP.CONTROLS
|
||||||
|
add node CONTROL0/usage=signal
|
||||||
|
add node CONTROL0D/usage=signal
|
||||||
|
add node CONTROL1/usage=signal
|
||||||
|
add node CONTROL1D/usage=signal
|
||||||
|
|
||||||
|
set def \RTAPPISTTOK::TOP.STATES
|
||||||
|
add node STATE0/usage=signal
|
||||||
|
add node STATE0D/usage=signal
|
||||||
|
add node STATE1/usage=signal
|
||||||
|
add node STATE1D/usage=signal
|
||||||
|
add node STATE2/usage=signal
|
||||||
|
add node STATE2D/usage=signal
|
||||||
|
add node STATE3/usage=signal
|
||||||
|
add node STATE3D/usage=signal
|
||||||
|
|
||||||
|
set def \RTAPPISTTOK::TOP.PERF
|
||||||
|
add node CYCLET/usage=signal
|
||||||
|
add node CYCLETD/usage=signal
|
||||||
|
|
||||||
|
write
|
||||||
|
close
|
||||||
|
set tree rtappisttok
|
||||||
|
create pulse 1
|
||||||
|
exit
|
||||||
Reference in New Issue
Block a user