Direct Memory Access (DMA)
Circle supports Direct Memory Access (DMA) using the platform DMA controller of the Raspberry Pi. This is implemented in the class CDMAChannel.
CDMAChannel
#include <circle/dmachannel.h>
-
class CDMAChannel
-
CDMAChannel::CDMAChannel(unsigned nChannel, CInterruptSystem *pInterruptSystem = 0)
Creates an instance of
CDMAChanneland allocates a channel of the platform DMA controller.nChannelmust beDMA_CHANNEL_NORMAL(normal DMA engine),DMA_CHANNEL_LITE(lite (or normal) DMA engine),DMA_CHANNEL_EXTENDED(“large address” DMA4 engine, on Raspberry Pi 4 only) or an explicit channel number (0-15).pInterruptSystemis a pointer to the instance ofCInterruptSystemand is only needed for interrupt operation.
-
void CDMAChannel::SetupMemCopy(void *pDestination, const void *pSource, size_t nLength, unsigned nBurstLength = 0, boolean bCached = TRUE)
Setup a DMA memory copy transfer from
pSourcetopDestinationwith lengthnLength.nBurstLength> 0 increases the speed, but may congest the system bus.bCacheddetermines, if the source and destination address ranges are in cached memory.
-
void CDMAChannel::SetupIORead(void *pDestination, u32 nIOAddress, size_t nLength, TDREQ DREQ)
Setup a DMA read transfer from the I/O port
nIOAddresstopDestinationwith lengthnLength.DREQpaces the transfer from these devices:
DREQSourceNone (no wait)
DREQSourceEMMC
DREQSourcePCMRX
DREQSourceSMI
DREQSourceSPIRX
DREQSourceUARTRX
-
void CDMAChannel::SetupIOWrite(u32 nIOAddress, const void *pSource, size_t nLength, TDREQ DREQ)
Setup a DMA write transfer to the I/O port
nIOAddressfrompSourcewith lengthnLength.DREQpaces the transfer to these devices:
DREQSourceNone (no wait)
DREQSourceEMMC
DREQSourcePCMTX
DREQSourcePWM
DREQSourcePWM1 (on Raspberry Pi 4 only)
DREQSourceSMI
DREQSourceSPITX
DREQSourceUARTTX
-
void CDMAChannel::SetupMemCopy2D(void *pDestination, const void *pSource, size_t nBlockLength, unsigned nBlockCount, size_t nBlockStride, unsigned nBurstLength = 0)
Setup a 2D DMA memory copy transfer of
nBlockCountblocks ofnBlockLengthlength frompSourcetopDestination. SkipnBlockStridebytes after each block on destination. Source is continuous. The destination cache, if any, is not touched.nBurstLength> 0 increases speed, but may congest the system bus. This method can be used to copy data to the framebuffer and is not supported withDMA_CHANNEL_LITE.
-
void CDMAChannel::SetCompletionRoutine(TDMACompletionRoutine *pRoutine, void *pParam)
Sets a DMA completion routine for interrupt operation.
pRoutineis called, when the transfer is completed.pParamis a user parameter, which is handed over to the completion routine.TDMACompletionRoutinehas the following prototype:
void TDMACompletionRoutine (unsigned nChannel, boolean bStatus, void *pParam);
nChannel is the channel number. bStatus is TRUE, if the transfer completed successfully.
-
void CDMAChannel::Start(void)
Starts the DMA transfer, which has been setup before.
-
boolean CDMAChannel::Wait(void)
Waits for the completion of the DMA transfer (for synchronous non-interrupt operation without completion routine). Returns
TRUE, if the transfer was successful.
-
boolean CDMAChannel::GetStatus(void)
Returns
TRUE, if the last completed transfer was successful.
DMA buffers
#include <circle/synchronize.h>
-
DMA_BUFFER(type, name, num)
Defines a buffer with
nameandnumelements oftypeto be used for DMA transfers.See doc/dma-buffer-requirements.txt for more information on DMA buffers.
Cache maintenance
#include <circle/synchronize.h>
-
void CleanAndInvalidateDataCacheRange(uintptr nAddress, size_t nLength)
Cleans and invalidates a memory range in the data cache.