481 lines
12 KiB
C++
481 lines
12 KiB
C++
/**
|
|
* @file AtcaIopADC.h
|
|
* @brief Header file for class AtcaIopADC
|
|
* @date 19/10/2023
|
|
* @author Andre Neto
|
|
* @author 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 "EmbeddedServiceMethodBinderI.h"
|
|
#include "EventSem.h"
|
|
#include "MessageI.h"
|
|
#include "RegisteredMethodsMessageFilter.h"
|
|
#include "SingleThreadService.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 = 4u;
|
|
const uint32 ATCA_IOP_N_ADCs = 16u;
|
|
const uint32 ATCA_IOP_N_INTEGRALS = ATCA_IOP_N_ADCs;
|
|
const uint32 ATCA_IOP_N_SIGNALS =
|
|
(ATCA_IOP_N_TIMCNT + 2); // ATCA_IOP_N_ADCs +
|
|
// ATCA_IOP_N_INTEGRALS);
|
|
/**
|
|
* The number of buffers to synchronise with the DMA
|
|
*/
|
|
const uint32 NUMBER_OF_BUFFERS = 8u;
|
|
|
|
/**
|
|
* @brief A DataSource that simulates an ADC board
|
|
* TODO
|
|
* <pre>
|
|
* +AtcaIopADC = {
|
|
* Class = "AtcaIop::AtcaIopADC"
|
|
* CPUMask = "0x040"
|
|
* StackSize = "1048576"
|
|
* DeviceName = "/dev/atca_v6"
|
|
* BoardId = 9
|
|
* DeviceDmaName = "/dev/atca_v6_dmart_2"
|
|
* NumberOfChannels = "12"
|
|
* IsMaster = "1"
|
|
* SleepNature = "Busy"
|
|
* SleepPercentage = "15"
|
|
* ADCFrequency = "2000000"
|
|
* RTDecimation = "200"
|
|
* ChopperPeriod = "2000"
|
|
* ElectricalOffsets = {"-151" "110" "-417" "-35" "-204" "0" "134" "-59" "-227"
|
|
* "-308" "-120" "-175" "0" "0" "0" "0"} WiringOffsets = {"0.0" "0.0" "0.0"
|
|
* "0.0" "0.0" "0.0" "0.0" "0.0" "0.0" "0.0" "0.0" "0.0" "0.0" "0.0" "0.0"
|
|
* "0.0"}
|
|
* //WiringOffsets = {0.354 0.288 -0.010 -0.083 0.347 0.228 0.088 0.186 -0.297
|
|
* -0.101 0.025 -0.012 0.0 0.0 0.0 0.0}
|
|
* //WiringOffsets = {"0.271" "0.211" "0.098" "0.141" "0.312" "0.203" "0.212"
|
|
* "0.361" "-0.546" "-0.433" "-0.598" "1.362"} Signals = { Counter = { Type =
|
|
* "uint32"
|
|
* }
|
|
* Time = {
|
|
* Type = "uint32"
|
|
* }
|
|
* TimeoutCount = {
|
|
* Type = "uint32"
|
|
* }
|
|
* TimeoutMax = {
|
|
* Type = "uint32"
|
|
* }
|
|
* ADCDecim = {
|
|
* DataSource = "AtcaIopAdc_DS"
|
|
* Type = "int32"
|
|
* NumberOfElements = 16
|
|
* NumberOfDimensions = 1
|
|
* }
|
|
* ADCInt = {
|
|
* DataSource = "AtcaIopAdc_DS"
|
|
* Type = "int64"
|
|
* NumberOfElements = 16
|
|
* NumberOfDimensions = 1
|
|
* }
|
|
* Idle_Thread1_CycleTime = {
|
|
* DataSource = "Timings"
|
|
* Alias = "Idle.Thread1_CycleTime"
|
|
* Type = "uint32"
|
|
* }
|
|
* Run_Thread1_CycleTime = {
|
|
* DataSource = "Timings"
|
|
* Alias = "Online.Thread1_CycleTime"
|
|
* Type = "uint32"
|
|
* }
|
|
* }
|
|
* }
|
|
* </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;
|
|
|
|
/**
|
|
* Debugging
|
|
*/
|
|
// uint32 execCounter;
|
|
// uint32 pollTimout;
|
|
|
|
/**
|
|
* Current counter and timer
|
|
*/
|
|
uint32 counterAndTimer[2];
|
|
|
|
/**
|
|
* Timeout counter
|
|
*/
|
|
uint32 timeoutCount;
|
|
|
|
/**
|
|
* Timeout counter
|
|
*/
|
|
uint32 timeoutMax;
|
|
|
|
/**
|
|
* ADC values
|
|
*/
|
|
// int32 adcValues[ATCA_IOP_N_ADCs];
|
|
int32 *adcValues;
|
|
|
|
/**
|
|
* ADC Integral values
|
|
*/
|
|
int64 adcIntegralValues[ATCA_IOP_N_ADCs];
|
|
|
|
/**
|
|
* 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_N_ADCs];
|
|
|
|
/**
|
|
* The Wiring Offset Parameters.
|
|
*/
|
|
float32 wiringOffsets[ATCA_IOP_N_ADCs];
|
|
|
|
/**
|
|
* 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;
|
|
void *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 PollDmaBuff(uint64 maxWaitTicks) const;
|
|
|
|
/**
|
|
* filter to receive the RPC which ...
|
|
*/
|
|
ReferenceT<RegisteredMethodsMessageFilter> filter;
|
|
};
|
|
} // namespace MARTe
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
/* Inline method definitions */
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
#endif /* ATCA_IOP_ADC_H */
|
|
|
|
// vim: syntax=cpp ts=4 sw=4 sts=4 sr et
|