CRpi
A library for rpi with intefaces to: gpio, pwm, dma
Macros | Functions
dma.cpp File Reference

Interface to the dma peripheral. More...

#include <memoryManagement/addressing.h>
#include <CCRCodingUtils/include/errorManagement.h>
#include <CCRCodingUtils/include/utils.h>
#include <memoryManagement/physMemoryManagement.h>
#include <memoryManagement/cacheCoherentMemoryProvider.h>
#include <string.h>
#include <stdlib.h>
#include <peripherals/dma.h>
#include <inttypes.h>
#include <errno.h>
#include <unistd.h>
#include <sys/mman.h>
#include <fcntl.h>

Macros

#define DMA_BASE_ADDR_PHYS   (peripheralsBaseAddressPhys + 0x7000)
 The base physical address of the dma peripheral.
 
#define CHANNEL_REGISTER_SET_OFFSET(ch)   (0x100*ch)
 Returns the offset from DMA_BASE_ADDR_PHYS of the register sets of the different channels.
 
#define DMA_AREA_LEN   0xf00
 The size of the memory area dedicated to the dma peripheral.
 
#define REG_CONTROL_STATUS_OFF   0
 Offset from the set base address of the Control and Status register.
 
#define REG_CONTROL_BLOCK_ADDR_OFF   0x4
 Offset from the set base address of the Control Block Address register (must be 32-byte aligned)
 
#define REG_TRANSFER_INFO_OFF   0x8
 Offset from the set base address of the Transefer Info register (writable only through control block)
 
#define REG_SOURCE_ADDR_OFF   0xC
 Offset from the set base address of the Source Address register (writable only through control block)
 
#define REG_DEST_ADDR_OFF   0x10
 Offset from the set base address of the Destination Address register (writable only through control block)
 
#define REG_TRANSFER_LENGTH_OFF   0x14
 Offset from the set base address of the Transfer Length register (writable only through control block)
 
#define REG_2D_STRIDE_MODE_OFF   0x18
 Offset from the set base address of the 2D Stride register (writable only through control block)
 
#define REG_NEXT_BLOCK_ADDR_OFF   0x1C
 Offset from the set base address of the Next Contorl Block Address register (writable only through control block)
 
#define REG_DEBUG_OFF   0x20
 Offset from the set base address of the Debug register (writable only through control block)
 
#define REG_GLOBAL_INT_STATUS_OFF   0xfe0
 Offset from the dma base address of the global interrupt status register.
 
#define REG_GLOBAL_ENABLE_OFF   0xff0
 Offset from the dma base address of the global enable register.
 
#define CNTRL_STTS_RESET_MASK   (1<<31)
 Write 1 to reset the channel.
 
#define CNTRL_STTS_ABORT_MASK   (1<<30)
 Write 1 to abort the current Control Block. Will continue from the next.
 
#define CNTRL_STTS_DISDEBUG_MASK   (1<<29)
 Set to 1 to disable stopping on debug pause signal.
 
#define CNTRL_STTS_WAIT_FOR_OUTSTANDING_WRITES_MASK   (1<<28)
 If set will wait for write responses.
 
#define CNTRL_STTS_ERROR_MASK   (1<8)
 Indicates if DMA detected an error, see more in the DEBUG register.
 
#define CNTRL_STTS_WAITING_FOR_OUTSTANDING_WRITES_MASK   (1<6)
 Indicates DMA is waiting for outstanding writes and isn't writing.
 
#define CNTRL_STTS_DREQ_STOPS_DMA_MASK   (1<5)
 Indicates DMA is stopped due to the DREQ being active.
 
#define CNTRL_STTS_PAUSED_MASK   (1<4)
 Indicates the DMA is paused and not transferring data.
 
#define CNTRL_STTS_DREQ_MASK   (1<3)
 Indicates Tte status of the DREQ signal selected by PERMAP in the transfer info.
 
#define CNTRL_STTS_INT_MASK   (1<2)
 Set when INTEN==1 and the transfer has ended, must be cleared (writing 1)
 
#define CNTRL_STTS_END_MASK   (1<1)
 Set when the transfer of the current control block is complete.
 
#define CNTRL_STTS_ACTIVE_MASK   (1)
 Activates or deactivates the DMA. Autmatically set to 0 when it loads 0 from nextcontrolblock.
 
#define DBG_LITE_MASK   (1<<28)
 Mask for the DMA Lite bit in the debug register.
 
#define DBG_VERSION_MASK   (7<<25)
 Mask for the DMA Version in the debug register.
 
#define DBG_DMA_STATE_MASK   (511<<16)
 Mask for the DMA State in the debug register.
 
#define DBG_DMA_ID_MASK   (255<<8)
 Mask for the DMA Axi id in the debug register.
 
#define DBG_OUTSTANDING_WRITES_MASK   (15<<4)
 Mask for the DMA outstanding writes counter in the debug register.
 
#define DBG_READ_ERROR_MASK   (1<<2)
 Mask for the DMA read error bit in the debug register.
 
#define DBG_FIFO_ERROR_MASK   (1<<1)
 Mask for the DMA FIFO error bit in the debug register.
 
#define DBG_READ_LAST_NOT_SET_ERROR_MASK   (0)
 Mask for the DMA read last not set error bit in the debug register.
 
#define INT_STTS_INT15_OFF   (1<<15)
 Offset of the interrupt status bit for channel 15 in the global interrupt status register.
 
#define INT_STTS_INT14_OFF   (1<<14)
 Offset of the interrupt status bit for channel 14 in the global interrupt status register.
 
#define INT_STTS_INT13_OFF   (1<<13)
 Offset of the interrupt status bit for channel 13 in the global interrupt status register.
 
#define INT_STTS_INT12_OFF   (1<<12)
 Offset of the interrupt status bit for channel 12 in the global interrupt status register.
 
#define INT_STTS_INT11_OFF   (1<<11)
 Offset of the interrupt status bit for channel 11 in the global interrupt status register.
 
#define INT_STTS_INT10_OFF   (1<<10)
 Offset of the interrupt status bit for channel 10 in the global interrupt status register.
 
#define INT_STTS_INT9_OFF   (1<<9)
 Offset of the interrupt status bit for channel 9 in the global interrupt status register.
 
#define INT_STTS_INT8_OFF   (1<<8)
 Offset of the interrupt status bit for channel 8 in the global interrupt status register.
 
#define INT_STTS_INT7_OFF   (1<<7)
 Offset of the interrupt status bit for channel 7 in the global interrupt status register.
 
#define INT_STTS_INT6_OFF   (1<<6)
 Offset of the interrupt status bit for channel 6 in the global interrupt status register.
 
#define INT_STTS_INT5_OFF   (1<<5)
 Offset of the interrupt status bit for channel 5 in the global interrupt status register.
 
#define INT_STTS_INT4_OFF   (1<<4)
 Offset of the interrupt status bit for channel 4 in the global interrupt status register.
 
#define INT_STTS_INT3_OFF   (1<<3)
 Offset of the interrupt status bit for channel 3 in the global interrupt status register.
 
#define INT_STTS_INT2_OFF   (1<<2)
 Offset of the interrupt status bit for channel 2 in the global interrupt status register.
 
#define INT_STTS_INT1_OFF   (1<<1)
 Offset of the interrupt status bit for channel 1 in the global interrupt status register.
 
#define INT_STTS_INT0_OFF   (1<<0)
 Offset of the interrupt status bit for channel 0 in the global interrupt status register.
 
#define INT_STTS_EN15_OFF   (1<<15)
 Offset of the enable bit for channel 15 in the global enable register.
 
#define INT_STTS_EN14_OFF   (1<<14)
 Offset of the enable bit for channel 14 in the global enable register.
 
#define INT_STTS_EN13_OFF   (1<<13)
 Offset of the enable bit for channel 13 in the global enable register.
 
#define INT_STTS_EN12_OFF   (1<<12)
 Offset of the enable bit for channel 12 in the global enable register.
 
#define INT_STTS_EN11_OFF   (1<<11)
 Offset of the enable bit for channel 11 in the global enable register.
 
#define INT_STTS_EN10_OFF   (1<<10)
 Offset of the enable bit for channel 10 in the global enable register.
 
#define INT_STTS_EN9_OFF   (1<<9)
 Offset of the enable bit for channel 9 in the global enable register.
 
#define INT_STTS_EN8_OFF   (1<<8)
 Offset of the enable bit for channel 8 in the global enable register.
 
#define INT_STTS_EN7_OFF   (1<<7)
 Offset of the enable bit for channel 7 in the global enable register.
 
#define INT_STTS_EN6_OFF   (1<<6)
 Offset of the enable bit for channel 6 in the global enable register.
 
#define INT_STTS_EN5_OFF   (1<<5)
 Offset of the enable bit for channel 5 in the global enable register.
 
#define INT_STTS_EN4_OFF   (1<<4)
 Offset of the enable bit for channel 4 in the global enable register.
 
#define INT_STTS_EN3_OFF   (1<<3)
 Offset of the enable bit for channel 3 in the global enable register.
 
#define INT_STTS_EN2_OFF   (1<<2)
 Offset of the enable bit for channel 2 in the global enable register.
 
#define INT_STTS_EN1_OFF   (1<<1)
 Offset of the enable bit for channel 1 in the global enable register.
 
#define INT_STTS_EN0_OFF   (1<<0)
 Offset of the enable bit for channel 0 in the global enable register.
 
#define CNTRL_STTS_PANIC_PRIORITY_OFF   (20)
 Sets the priority of panicking AXI bus transactions.
 
#define CNTRL_STTS_PANIC_PRIORITY_MASK   (0xf<<CNTRL_STTS_PANIC_PRIORITY_OFF)
 Sets the priority of panicking AXI bus transactions.
 
#define CNTRL_STTS_PRIORITY_OFF   (16)
 Sets the priority of normal AXI bus transactions.
 
#define CNTRL_STTS_PRIORITY_MASK   (0xf<<CNTRL_STTS_PRIORITY_OFF)
 Sets the priority of normal AXI bus transactions.
 

Functions

int dma_init ()
 Initializes the interface, to be called before any other function in this file. More...
 
int dma_isInit ()
 Says if dma_init has been called with success. More...
 
int dma_printRegisters (int channel)
 For debug purposes: prints the registers' contents to standard output. More...
 
int dma_printRegistersDense (int channel)
 For debug purposes: prints the registers' contents to standard output, in a single line. More...
 
int dma_dumpRegisters (int channel, char *s)
 For debug purposes: writes the register's contents on the provided string. More...
 
int dma_dumpRegistersDense (int channel, char *s)
 For debug purposes: writes the register's contents on the provided string, in a single line. More...
 
int dma_printControlBlock (ControlBlock *cb)
 For debug purposes: prints the control block's contents on standard output. More...
 
int dma_controlBlockToString (ControlBlock *cb, char *s)
 For debug purposes: writes the control block's contents on a string. More...
 
int dma_channelResetInitDefault (int channel)
 Resets the channel and sets it to default values. More...
 
int dma_setChannelGlobalEnable (int channel, int value)
 Set the global enable status for the specified channel. More...
 
int dma_setChannelActive (int channel, int value)
 Sets the channel active bit, this is automatically cleared at the end of each control block chain. More...
 
int dma_isChannelActive (int channel)
 Gets the channel active bit, this is automatically cleared at the end of each control block chain. More...
 
int dma_setControlBlockAddr (int channel, uint32_t controlBlockAddrPhys)
 Sets the address of the control block to be loaded in the dma engine, to start the transfer you then have to set the active bit. More...
 
int dma_writeControlBlock (ControlBlock *cb, uintptr_t srcAddrPhys, uintptr_t dstAddrPhys, size_t transferLength, uintptr_t nextControlBlockPhys, uint32_t transferInfo, uint32_t _2DStrideModeInfo, size_t _2DStrideTransferLenX, size_t _2DStrideTransferLenY)
 
int dma_allocControlBlockPhys (uintptr_t srcAddrPhys, uintptr_t dstAddrPhys, size_t transferLength, uintptr_t nextControlBlockPhys, uint32_t transferInfo, uint32_t _2DStrideModeInfo, size_t _2DStrideTransferLenX, size_t _2DStrideTransferLenY, Ccmb_desc *area)
 Builds a control block with the specified characteristics. More...
 
uint32_t dma_getUsableChannels ()
 Returns a bit mask indicating the usable channels with 1. More...
 

Detailed Description

Interface to the dma peripheral.

If you haven't already, see dma.h See documentation at "BCM2835 ARM peripherals" page 38

Function Documentation

int dma_allocControlBlockPhys ( uintptr_t  srcAddrPhys,
uintptr_t  dstAddrPhys,
size_t  transferLength,
uintptr_t  nextControlBlockPhys,
uint32_t  transferInfo,
uint32_t  _2DStrideModeInfo,
size_t  _2DStrideTransferLenX,
size_t  _2DStrideTransferLenY,
Ccmb_desc area 
)

Builds a control block with the specified characteristics.

Parameters
srcAddrPhysSource adddress
dstAddrPhysDestination address
transferLengthNumber of bytes to copy
nextControlBlockPhysThe next control block to process
transferInfoUse the TI_* macros
_2DStrideModeInfoSee bcm2835 datasheet
_2DStrideTransferLenXSee bcm2835 datasheet
_2DStrideTransferLenYSee bcm2835 datasheet
areaThe cacheCoherentMemoryProvider descriptor will be returned here, you'll have to free it using ccmp_free(area). You can get the bus and virtual address of the control block from here
Returns
negative in case of error
int dma_channelResetInitDefault ( int  channel)

Resets the channel and sets it to default values.

Parameters
channelThe channel
int dma_controlBlockToString ( ControlBlock cb,
char *  s 
)

For debug purposes: writes the control block's contents on a string.

Parameters
cbThe control block
sThe control block's will be written on this string (300 is an appropriate length)
int dma_dumpRegisters ( int  channel,
char *  s 
)

For debug purposes: writes the register's contents on the provided string.

Parameters
channelThe channel
sThe registers' contents will be written on this string (550 is an appropriate length)
int dma_dumpRegistersDense ( int  channel,
char *  s 
)

For debug purposes: writes the register's contents on the provided string, in a single line.

Parameters
channelThe channel
sThe registers' contents will be written on this string (550 is an appropriate length)
uint32_t dma_getUsableChannels ( )

Returns a bit mask indicating the usable channels with 1.

Returns
the bit mask, 0xf0000000 in case of error
int dma_init ( )

Initializes the interface, to be called before any other function in this file.

Returns
negative in case of error
int dma_isChannelActive ( int  channel)

Gets the channel active bit, this is automatically cleared at the end of each control block chain.

Parameters
channelThe channel
Returns
negative in case of error
int dma_isInit ( )

Says if dma_init has been called with success.

Returns
true if dma_init has been called with success
int dma_printControlBlock ( ControlBlock cb)

For debug purposes: prints the control block's contents on standard output.

Parameters
cbThe control block
int dma_printRegisters ( int  channel)

For debug purposes: prints the registers' contents to standard output.

Parameters
channelThe channel
Returns
negative in case of error
int dma_printRegistersDense ( int  channel)

For debug purposes: prints the registers' contents to standard output, in a single line.

Parameters
channelThe channel
Returns
negative in case of error
int dma_setChannelActive ( int  channel,
int  value 
)

Sets the channel active bit, this is automatically cleared at the end of each control block chain.

Parameters
channelThe affected channel
value0=disabled; anything else= enabled
Returns
negative in case of error
int dma_setChannelGlobalEnable ( int  channel,
int  value 
)

Set the global enable status for the specified channel.

Parameters
channelThe affected channel
value0=disabled; anything else= enabled
Returns
negative in case of error
int dma_setControlBlockAddr ( int  channel,
uint32_t  controlBlockAddrPhys 
)

Sets the address of the control block to be loaded in the dma engine, to start the transfer you then have to set the active bit.

Parameters
channelThe channel
controlBlockAddrPhysThe physical address of the control block
Returns
negative in case of error
int dma_writeControlBlock ( ControlBlock cb,
uintptr_t  srcAddrPhys,
uintptr_t  dstAddrPhys,
size_t  transferLength,
uintptr_t  nextControlBlockPhys,
uint32_t  transferInfo,
uint32_t  _2DStrideModeInfo,
size_t  _2DStrideTransferLenX,
size_t  _2DStrideTransferLenY 
)

Writes the provided values to the provided control block

Parameters
cbThe contorl block (virtual) address
srcAddrPhysSource adddress
dstAddrPhysDestination address
transferLengthNumber of bytes to copy
nextControlBlockPhysThe next control block to process
transferInfoUse the TI_* macros
_2DStrideModeInfoSee bcm2835 datasheet
_2DStrideTransferLenXSee bcm2835 datasheet
_2DStrideTransferLenYSee bcm2835 datasheet
Returns
Negative in case of error