Page 1 of 1

STM32 Programming. Part 9: Description of DMA registers

Posted: 16 Oct 2023, 04:34
by Oleg
Since the previous article about DMA was quite large, I decided to put the description of registers in a separate article.

In the STM32F103C8 microcontroller, the DMA controller has 6 types of registers. They are organized as follows.

Registers that are common to all DMA channels:
  • DMA_ISR - interrupt status register
  • DMA_IFCR - interrupt flag clearing register
Registers that are individual for each DMA channel:
  • DMA_CCRx (x=1..7) - channel number x DMA configuration register
  • DMA_CNDTRx (x=1..7) - the register of the amount of transmitted data of the channel number x DMA
  • DMA_CPARx (x=1..7) - channel peripheral address register channel number x DMA
  • DMA_CMARx (x=1..7) - memory address register of the channel number x DMA.
The number of channels we have 7. Then the total number of DMA1 registers we have will be 7*4 + 2 = 30 pieces.

DMA registers
DMA interrupt status register (DMA_ISR) - register of interrupt status from DMA channels.

image.png
image.png (15.42 KiB)
Viewed 3569 times
Contains interrupt flags from all DMA channels.

TEIFx: DMA channel transfer error. Set by hardware. Reset by writing a 1 to the corresponding bit of the DMA_IFCR register.

HTIFx: flag transfer half of the data channel DMA channel. Set by hardware. Reset by writing 1 to the corresponding bit of the register DMA_IFCR.

TCIFx: flag of the end of transmission of the DMA channel. Set by hardware. Reset by writing 1 to the corresponding bit of the DMA_IFCR register.

GIFx: global DMA channel interrupt flag. Set to 1 when a TE, HT or TC event of this channel has occurred. Set by hardware. Reset by writing a 1 to the corresponding bit of the DMA_IFCR register.

DMA interrupt flag clear register (DMA_IFCR) - DMA channel interrupt flag clear register
image.png
image.png (18.58 KiB)
Viewed 3569 times
Setting any bit in the DMA_IFCR register to one clears the corresponding interrupt flag in the DMA_ISR register. Writing a zero to any bit has no effect.

CTEIFx: clear the DMA channel transmit error flag

CHTIFx: clear half data transfer flag

CTCIFx: clear transmission completion flag

CGIFx: clear global DMA interrupt flag

DMA channel x configuration register (DMA_CCRx) - DMA channel number x configuration register
image.png
image.png (11.44 KiB)
Viewed 3569 times
MEM2MEM: memory-to-memory mode
  • 0 - MEM2MEM mode disabled
  • 1 - MEM2MEM mode enabled
PL[1:0]: DMA channel priority level
  • 00: Low
  • 01: Medium
  • 10: High
  • 11: Very high priority.
MSIZE[1:0]: Memory data size
  • 00: 8 bits
  • 01: 16 bits
  • 10: 32 bits
  • 11: not used
PSIZE[1:0]: peripheral bit size
  • 00: 8 bits
  • 01: 16 bits
  • 10: 32 bits
  • 11: not used
MINC: memory increment mode
  • 0 - memory increment mode disabled
  • 1 - memory increment mode enabled
PINC: peripheral increment mode
  • 0 - peripheral increment mode disabled
  • 1 - peripheral increment mode enabled
CIRC: Circular mode DMA (Circular mode)
  • 0 - Circular mode disabled
  • 1 - circular mode enabled
DIR: direction of data transfer
  • 0 - read from periphery (direction from periphery to memory)
  • 1 - read from memory (direction from memory to peripheral)
TEIE: enable DMA transfer error interrupt
  • 0 - interrupt prohibited
  • 1 - interrupt allowed
HTIE: allow interrupt of buffer half transfer
  • 0 - interrupt prohibited
  • 1 - interrupt allowed
TCIE: allow end of transfer interrupt

0 - interrupt prohibited[/list]
1 - interrupt enabled[/list]

EN: enable DMA channel

0 - channel disabled[/list]
1 - channel enabled[/list]

DMA channel x number of data register (DMA_CNDTRx) - number of data to be transferred
image.png
image.png (7.71 KiB)
Viewed 3569 times
NDT[15:0]: the amount of data to transmit.

The amount of data to transfer can be from 0 to 65535. This register can only be written if this DMA channel is disabled (EN=0 in the DMA_CCRx register). When the DMA channel is enabled, this register is read-only and indicates how many DMA transactions are still remaining. This register is decremented by one after each DMA transaction. Once the transfer is complete, this register either remains at zero or is automatically reloaded with the value originally written to it if ring mode is enabled. If this register is zero, no DMA transaction can be performed, whether the channel is enabled or not.

DMA channel x memory address register (DMA_CMARx) - DMA channel memory address register
image.png
image.png (5.64 KiB)
Viewed 3569 times
This register cannot be written when this DMA channel is enabled

MA[31:0]: memory address.

The base address (pointer) of the memory area to be written/read. When MSIZE=01 (memory bit 16 bits), the MA[0] bit is ignored. The access is automatically aligned with the half-word address. When MSIZE=10 (memory bit size 32 bits), the MA[1:0] bits are ignored. The access is automatically aligned with the machine-word address.

Note. It turns out that when transferring an array of data over DMA by 16 or 32 bits, we must remember that the elements of the transferred array in memory must be aligned on the 16 or 32 bit boundary, respectively. If in C code the array to be transferred is declared as int16_t/uint16_t and this array is transferred by 16 bits, there should be no problems, because the compiler by default aligns the array data by the corresponding boundary (but it is not exact). The same is true for int32_t/uint32_t arrays and DMA data transfer by 32 bits. There should be no problem when transferring int32_t/uint32_t arrays 16 bits at a time. But if we have declared int8_t/uint8_t and want to transfer it somewhere by 16 or 32 bits at a time, there may be problems in this case. There are no such problems with registers of peripheral devices because they are all equalized on the 32-bit boundary.

DMA channel x peripheral address register (DMA_CPARx) - DMA channel peripheral address register
image.png
image.png (5.5 KiB)
Viewed 3569 times
This register cannot be written when this DMA channel is enabled

PA[31:0]: peripheral address

Base address (pointer) of the memory area to be written/read. When MSIZE=01 (memory bit 16 bits), the MA[0] bit is ignored. The access is automatically aligned with the half-word address. When MSIZE=10 (memory bit size 32 bits), the MA[1:0] bits are ignored. The access is automatically aligned with the machine-word address.

Conclusion
This completes the description of registers, in the next part we will move on to practice and learn how to quickly copy data from one memory area to another, as well as understand the exchange of data through the SPI interface via DMA.
See DMA_CMARx Register Note