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
CDMAChannel
and allocates a channel of the platform DMA controller.nChannel
must 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).pInterruptSystem
is a pointer to the instance ofCInterruptSystem
and 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
pSource
topDestination
with lengthnLength
.nBurstLength
> 0 increases the speed, but may congest the system bus.bCached
determines, 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
nIOAddress
topDestination
with lengthnLength
.DREQ
paces 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
nIOAddress
frompSource
with lengthnLength
.DREQ
paces 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
nBlockCount
blocks ofnBlockLength
length frompSource
topDestination
. SkipnBlockStride
bytes 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.
pRoutine
is called, when the transfer is completed.pParam
is a user parameter, which is handed over to the completion routine.TDMACompletionRoutine
has 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
name
andnum
elements oftype
to 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.