STM32 Programming. Part 9: Description of DMA registers
Posted: 16 Oct 2023, 04:34
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 registers
DMA interrupt status register (DMA_ISR) - register of interrupt status from DMA channels.
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
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
MEM2MEM: memory-to-memory mode
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
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
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
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
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
- 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.
DMA registers
DMA interrupt status register (DMA_ISR) - register of interrupt status from DMA channels.
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
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
MEM2MEM: memory-to-memory mode
- 0 - MEM2MEM mode disabled
- 1 - MEM2MEM mode enabled
- 00: Low
- 01: Medium
- 10: High
- 11: Very high priority.
- 00: 8 bits
- 01: 16 bits
- 10: 32 bits
- 11: not used
- 00: 8 bits
- 01: 16 bits
- 10: 32 bits
- 11: not used
- 0 - memory increment mode disabled
- 1 - memory increment mode enabled
- 0 - peripheral increment mode disabled
- 1 - peripheral increment mode enabled
- 0 - Circular mode disabled
- 1 - circular mode enabled
- 0 - read from periphery (direction from periphery to memory)
- 1 - read from memory (direction from memory to peripheral)
- 0 - interrupt prohibited
- 1 - interrupt allowed
- 0 - interrupt prohibited
- 1 - interrupt allowed
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
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
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
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