EasyDMA
EasyDMA is a module implemented by some peripherals as a bus manager for direct access to RAM. It cannot access non-volatile memory,
A peripheral can implement multiple EasyDMA instances to provide dedicated channels. For example, a channel can be dedicated for reading and writing data between the peripheral and RAM. This concept is illustrated in the following example figure, where READER is reading data from RAMc, while WRITER is writing data to RAMa and RAMb (each RAM being separate bus subordinates).
EasyDMA channel implementation
A typical EasyDMA channel is implemented in the following way.
READERBUFFER_SIZE 5
WRITERBUFFER_SIZE 6
uint8_t readerBuffer[READERBUFFER_SIZE] __at__ 0x20000000;
uint8_t writerBuffer[WRITERBUFFER_SIZE] __at__ 0x20000005;
// Configuring the READER channel
MYPERIPHERAL->READER.MAXCNT = READERBUFFER_SIZE;
MYPERIPHERAL->READER.PTR = &readerBuffer;
// Configure the WRITER channel
MYPERIPHERAL->WRITER.MAXCNT = WRITEERBUFFER_SIZE;
MYPERIPHERAL->WRITER.PTR = &writerBuffer;This example shows a peripheral called MYPERIPHERAL that implements two EasyDMA channels. One channel is for reading called READER, and one for writing called WRITER. When the peripheral starts, it performs the following tasks.
- Reads 5 B from the readerBuffer located in RAM at address 0x20000000.
- Processes the data.
- Writes up to 6 B back to the writerBuffer located in RAM at address 0x20000005.
The memory layout of these buffers is illustrated is shown in the following figure.
The specified size of the WRITER.MAXCNT register must not be larger than the actual size of the buffer (writerBuffer). This prevents the channel from overflowing the writerBuffer.
Once an EasyDMA transfer is complete, the CPU reads the AMOUNT register to see how many bytes were transferred. For example, the CPU can read the MYPERIPHERAL.WRITER.AMOUNT register to see how many bytes WRITER wrote to RAM.
EasyDMA error handling
Errors can occur during DMA handling.
If READER.PTR or WRITER.PTR is not pointing to a valid memory region, an EasyDMA transfer could HardFault or cause RAM corruption. See Memory for more information about the different memory regions.
An EasyDMA channel is an AHB bus Manager. If several AHB Managers try to access the same AHB Subordinate at the same time, AHB bus congestion can occur. Depending on the peripheral, the peripheral could either stall and wait for access to be granted, or lose data.
Array list
EasyDMA can operate in Array List mode.
The Array List mode is implemented in channels where the LIST register is available.
The array list is not able to specify where the next item in the list is located. Instead, it assumes that the list is organized as a linear array where items are located one after the other in RAM.
The EasyDMA array list is implemented with the data structure ArrayList_type. This is illustrated in the following code example using a READER EasyDMA channel as an example.
#define BUFFER_SIZE 4
typedef struct ArrayList
{
uint8_t buffer[BUFFER_SIZE];
} ArrayList_type;
ArrayList_type ReaderList[3] __at__ 0x20000000;
MYPERIPHERAL->READER.MAXCNT = BUFFER_SIZE;
MYPERIPHERAL->READER.PTR = &ReaderList;
MYPERIPHERAL->READER.LIST = MYPERIPHERAL_READER_LIST_ArrayList;The data structure includes a buffer that is equal in size to the READER.MAXCNT register. EasyDMA uses the READER.MAXCNT register to determine when the buffer is full.