Dma
The Dma component handles the configuration and control of the Direct Memory Access (DMA). It is used to transfer data from the hardware design to the memory.
Additional information
The Dma component works only with the Dma implementation of AMD/Xilinx [1].
When creating a Dma object the corresponding DMA is configured using a memory map to access the DMA registers and a descriptor control to access the descriptor control registers. A Uio device is used to wait for Dma interrupts. On each interrupt it is checked if the interrupt was caused by the measurement stop. If this happened the DMA waits for the last transfer to finish and then the DMA is stopped.
Classes
DMA Class
-
class Dma
DMA class to handle the AXI DMA device.
This class is used to control the DMA device.
Objects of this class are supposed to run in a separate thread. Also another thread is created to handle the interrupts.
Subclassed by nexmess::components::dma::DmaCount
Public Functions
-
Dma(uint8_t id, uint8_t dmaInterruptId, uint8_t index, int mem, uint32_t registerBase, const char *dmaDevice, const char *uioDevice, uint32_t descriptorOffset, uint32_t descriptorPerDma, uint32_t packageSize, uint32_t dmaRamStartAddress)
Only constructor for the DMA class.
- Parameters:
id – The DMA ID. The ID should be the index of the corresponding DMA device within the DMAS array.
dmaInterruptId – The DMA interrupt ID.
index – The index of the DMA device.
mem – The memory identifier.
registerBase – The address of the DMA device register.
dmaDevice – The name of the DMA device to handle the memory.
uioDevice – The name of the UIO device to handle the interrupts.
descriptorOffset – The offset of the DMA descriptor memory.
descriptorPerDma – The amount of DMA descriptors per DMA device.
packageSize – The size of a package in DEFAULT_DATA_SIZE byte words.
dmaRamStartAddress – The start address of the DMA RAM (e.g. DMA_RAW_START_ADDRESS).
-
virtual ~Dma()
Destructor for the DMA class.
This destructor makes sure the DMA is disabled and the thread is joined.
-
Dma() = delete
-
bool empty()
Checks if the DMA is empty.
- Returns:
true if the DMA is empty, false otherwise.
-
bool full()
Checks if the DMA is full.
It is also true if the RAM is full.
- Returns:
true if the DMA is full, false otherwise.
-
void setFifoFullHandled()
Sets the flag indicating that the FIFO is full and has been handled.
This is set by the controller once the FIFO full interrupt has been handled.
-
bool fifoFullHandled() const
Checks if the FIFO full interrupt has been handled.
- Returns:
true if the FIFO full interrupt has been handled, false otherwise.
-
inline uint8_t getID() const
Get the ID of the DMA.
-
inline uint8_t getIndex() const
Get the index of the DMA.
-
inline uint32_t getDmaDescriptorCount() const
Get the amount of descriptors for the DMA.
-
void reset()
Sets the bit in the DMA control register to reset the DMA.
-
void enableInterrupt()
Enables the DMA interrupts as well as the UIO interrupts.
-
InterruptStatus waitForData()
Waits for interrupts and checks for available data.
This function handles the interrupts and re-enables them. It updates the descriptor pointers. It also checks if there is data available and sets the FIFO full flag if the FIFO is full. When the measurement is finished it handles it as well.
- Returns:
The interrupt status.
-
void enable()
Enables the DMA operation.
It spawns the thread to handle the DMA operations.
-
void disable()
Disables the DMA operation.
It stops the thread to handle the DMA operations ans disables the DMA in hardware.
-
void setStartDescriptorAddress(uint32_t address)
Sets the start descriptor address.
-
void setTailDescriptorAddress(uint32_t address)
Sets the tail descriptor address.
Writing to this register starts the actual DMA operation in hardware. From this point on the DMA will read the descriptors and write the data to the RAM when data is available.
-
uint32_t getDataLength()
Gets the length of the data.
Usually it should be the same as DEFAULT_RAW_PACKAGE_SIZE_BYTES. When the measurement was stopped the last package might (most probably) be smaller.
- Returns:
The length of the data as a uint32_t.
-
uint32_t getStatus()
Get the status of the DMA.
The status is read from the status register of the DMA.
- Returns:
The status of the DMA as a 32-bit unsigned integer.
-
bool hasStatusError()
Checks if there is a status error.
Is the same as hasStatusError(uint32_t status) but reads the status register first.
- Returns:
true if there is a status error, false otherwise.
-
bool hasStatusError(uint32_t status)
Checks if there is a status error.
- Parameters:
status – The value if the status register.
- Returns:
true if there is a status error, false otherwise.
-
bool hasError() const
Checks if there is an error in the DMA component.
- Returns:
true if there is an error, false otherwise.
-
bool isRunning() const
Checks if the DMA is currently running.
- Returns:
true if the DMA is running, false otherwise.
-
bool isStopped() const
Checks if the DMA is stopped.
- Returns:
true if the DMA is stopped, false otherwise.
-
uint64_t *memoryMap() const
Returns a pointer to the memory map.
This function returns a pointer to the memory map used by the DMA component. The memory map is a uint64_t pointer that represents the starting address of the memory map.
- Returns:
A pointer to the memory map.
-
uint32_t writeSize()
Returns the size of data which is received and can be handled.
The returned write size is never bigger than one portion of memory described by one DMA descriptor. This makes sure that we don’t read data after the last descriptor (wrap around).
This function reduces the amount of available data for the next call.
This function must be called for continuous operation.
- Returns:
The size of the write operation in bytes.
-
void decreaseReadDifference()
Decreases the read difference.
This function is responsible for decreasing the read difference. It should be called after the received data of one descriptor has been handled.
This function must be called for continuous operation.
-
uint32_t currentReadDescriptor()
Returns the current read descriptor.
This function returns the current read descriptor used by the DMA module. This also updated the read descriptor pointer to read the next descriptor the next time.
This function must be called for continuous operation.
- Returns:
The current read descriptor.
-
uint32_t packageSize() const
Returns the package size.
-
virtual bool isCountDma() const
Returns false if the DMA is not a count DMA.
- Returns:
true if the DMA is a count DMA, false otherwise.
Private Functions
-
void registerEnable()
Sets the DMAs register so that it is ready to receive data.
-
void registerDisable()
Sets the DMAs register so that it is not ready to receive data.
Private Members
-
const uint8_t ID
The DMA ID.
The ID is supposed to be the index of the corresponding DMA device within the DMAS array.
-
const uint8_t DMA_INTERRUPT_ID
The DMA interrupt ID.
-
const uint8_t INDEX
The index of the DMA device.
-
const uint32_t REGISTER_BASE
The address of the DMA device register.
-
const char *DMA_DEVICE
The name of he DMA device to handle the memory.
-
const char *UIO_DEVICE
The name of the UIO device to handle the DMA interrupts.
-
const uint32_t DESCRIPTOR_OFFSET
The offset of the DMA descriptor memory.
-
const uint32_t DESCRIPTOR_PER_DMA
The amount of DMA descriptors per DMA device.
-
const uint32_t PACKAGE_SIZE
The size of a package in DEFAULT_DATA_SIZE byte words.
-
const uint32_t PACKAGE_SIZE_BYTES
The size of a package in bytes.
-
uint32_t mCurrentDescriptor = 0
The current write descriptor.
-
uint32_t mCurrentReadDescriptor = 0
The current read descriptor.
-
std::atomic<uint32_t> mReadDifference = {0}
The difference between the current read and write descriptor. RAM full depends on this value.
-
std::atomic<uint32_t> mReceivedDataPackets = {0}
The number of received data packets.
-
dma::DescriptorControl mDescriptorControl
The descriptor control object used to control the DMA descriptors.
-
std::atomic<bool> mEnabled = {false}
Indicates whether the DMA is enabled.
-
std::atomic<bool> mRunning = {false}
Indicates whether the DMA is running.
-
std::atomic<bool> mStopped = {false}
Indicates whether the DMA is finished its operation.
-
std::chrono::time_point<std::chrono::steady_clock> mStopTime = {}
The time when the DMA was stopped.
-
std::unique_ptr<std::thread> mThread = nullptr
The thread used to handle the DMA operations. It contains a loop which runs until the DMA is stopped.
-
std::atomic<bool> mExit = false
Indicates whether the DMA thread should exit.
-
std::atomic<bool> mFifoFull = {false}
Indicates whether the FIFO is full.
-
std::atomic<bool> mFifoFullHandled = {false}
Indicates whether the FIFO full interrupt was handled. It is used for communication with the controller object.
-
bool mHasError = false
Indicates whether there is an error.
-
Dma(uint8_t id, uint8_t dmaInterruptId, uint8_t index, int mem, uint32_t registerBase, const char *dmaDevice, const char *uioDevice, uint32_t descriptorOffset, uint32_t descriptorPerDma, uint32_t packageSize, uint32_t dmaRamStartAddress)
DescriptorControl Class
-
class DescriptorControl
Controls the descriptors for DMA operations.
The DescriptorControl class provides functionality to control the descriptors used for DMA operations. It manages the DMA ID, register base address, and memory size. It also provides methods to check for errors, retrieve the number of received data words, and write descriptors.
Public Functions
-
DescriptorControl(uint32_t id, uint32_t registerBase, int mem, uint32_t descriptorOffset, uint32_t descriptorPerDma, uint32_t packageSizeBytes, uint32_t dmaRamStartAddress)
Constructor for DescriptorControl.
- Parameters:
id – DMA ID.
registerBase – Register base address.
mem – Memory size.
descriptorOffset – Descriptor offset.
descriptorPerDma – Number of descriptors per DMA.
packageSizeBytes – Package size in bytes.
dmaRamStartAddress – Start address of the DMA RAM (e.g. DMA_RAW_START_ADDRESS).
-
~DescriptorControl() = default
Destructor for DescriptorControl.
-
DescriptorControl() = delete
-
DescriptorControl(const DescriptorControl&) = delete
-
void operator=(const DescriptorControl&) = delete
-
bool hasError() const
Checks if there is an error.
- Returns:
True if there is an error, false otherwise.
-
uint32_t getReceivedDataWordLength(uint32_t descriptorNumber)
Gets the number of received 32 bit words (yes not 64 bit).
The number of received 32 bit words is the number of bytes received divided by 4.
- Parameters:
descriptorNumber – Descriptor number.
- Returns:
The received data.
-
void writeDescriptors()
Writes the descriptors.
The DMA is set into circular mode, so the last descriptor points to the first one.
Private Functions
-
DescriptorControl(DescriptorControl&&) = delete
-
DescriptorControl &operator=(DescriptorControl&&) = delete
Private Members
-
const uint32_t DMA_ID
The DMA ID.
-
const uint32_t REGISTER_BASE
The register base address.
-
const uint32_t REGISTER_SIZE
The register size.
-
const uint32_t DESCRIPTOR_OFFSET
The offset of the first descriptor from the base.
-
const uint32_t DESCRIPTOR_PER_DMA
The number of descriptors per DMA.
-
const uint32_t PACKAGE_SIZE_BYTES
The package size in bytes.
-
const uint32_t DMA_RAM_START_ADDRESS
The start address of the DMA RAM.
-
DescriptorControl(uint32_t id, uint32_t registerBase, int mem, uint32_t descriptorOffset, uint32_t descriptorPerDma, uint32_t packageSizeBytes, uint32_t dmaRamStartAddress)