DMA

Pages List
List view
Home
Portfolio
HW
FW
SW
FPGA / Adaptive SoC
Daily
Photo
Etc
 
STM32 Peripheral

DMA


notion image

DMA Exercises : GPIO Polling and Interrupt


notion image
DMA를 사용하기 위한 절차는 다음과 같다.
  1. 당신의 어플리케이션에 알맞은 DMA Controller를 찾아야 한다. (DMA1 or DMA2)
  1. DMA 초기화를 수행한다.
  1. DMA를 trigger한다. (Automatic trigger or Manual trigger) Automatic trigger는 ARM이 아닌 다른 Peripheral이 DMA를 trigger할 수 있다.
    Manual trigger는 사용자의 요청에 따라 ARM이 DMA를 trigger하는 방식이다. (비효율적임)
  1. Transmission complete (Polling 방식 : Bad)를 기다리거나 DMA driver (interrupt 방식 : Good)로부터 Callback을 받는다.
 

① Polling mode

Polling Mode에서는
  1. 어플리케이션에 알맞은 DMA를 Initialization한다.
  1. DMA를 Start (Trigger) 한다.
  1. Data Transfer가 완료되었다는 Flag가 Set될 때까지 대기한다. (while loop)

② Interrupt mode

Interrupt mode에서는
  1. Application에 알맞은 DMA를 Initialization한다.
  1. DMA를 Start (Trigger) 한다.
  1. Data Transfer가 완료되면, Interrupt가 걸리고 ARM이 ISR에 진입한다. Interrupt가 걸릴 때까지 ARM은 다른 작업을 수행할 수 있다.
 
 

LED Toggling using DMA

다음은 Bus matrix 그림이다.
notion image
LED를 Toggling 하는 것은 결국 GPIO port의 Output data register의 값을 0 또는 1로 설정하는 것이다. 그래서 DMA를 사용해서 SRAM의 data를 GPIO port의 Output data register에 write하면, LED를 On/Off 할 수 있다. (ARM과는 무관하게)
그런데 DMA1의 경우에는 SRAM1으로부터 data를 읽을 수 있지만 AHB1과 연결되어 있지 않아서 AHB1에 달린 GPIO 레지스터에 접근할 수 없다.
그래서 DMA2를 사용해야 한다.
 
notion image
 
 

UART to SRAM Data Transfer using DMA (Interrupt mode)

  1. PC에서 송신한 data가 UART의 DR (Data Register)에 도착하면, UART는 ARM 또는 DMA Controller에게 Interrupt 요청을 보낸다. (단, USART_CR3의 DMAT or DMAR이 Enable되어 있을 때만, UART가 Data를 받거나 보낼 때 DMA Controller에게 Interrupt 요청을 보낸다.)
  1. Interrupt 요청을 받은 DMA Controller는 UART_DR의 data를 SRAM으로 transfer 시킨다. (물론 Data Transfer 하기 전에 Source Address와 Destination Address를 설정해야 한다.)
  1. UART_DR에서 SRAM으로의 Data transfer가 완료되면, DMA Controller는 ARM에게 Transfer Complete Interrupt를 요청한다.
  1. 그러면 ARM은 DMA_IRQHandler에서 Transfer Complete Callback을 호출하고, 해당 Callback function의 code를 수행한다.
 
 

DMA Functional Block Diagram

Master and Slave Ports of DMA

notion image
DMA Controller는 AMBA Advanced High-performance Bus (AHB) Master Module이다.
DMA Controller는 3개의 AHB port를 가지는데, 1개는 DMA Controller를 programming (Configuring) 하기 위한 Slave port이고, 나머지 2개는 Master port이다. (위 그림에서 Memory port, Peripheral port가 Master port이고, Programming port가 Slave port이다.)
DMA를 사용해 SPI peripheral에서 SRAM1으로 Data Transfer를 수행한다고 가정해보자. (Source : SPI peripheral / Destination : SRAM1)
SPI peripheral의 Data는 DMA의 Peripheral port로 입력되어 DMA stream을 지나 Memory port를 통해 SRAM으로 이동한다.
이번에는 DMA를 사용해 SRAM1에서 UART로 Data Transfer를 수행한다고 가정해보자. (Source : SRAM1 / Destination : UART)
SRAM1의 Data는 DMA의 Memory port로 입력되어 DMA stream을 지나 Peripheral port를 통해 UART의 Data Register로 이동한다.
 
 

DMA Streams

  • 각 DMA Controller는 8개의 Stream을 가지고, 이 Stream들은 Source와 Destination 사이의 unidirectional transfer link를 제공한다.
  • 각 Stream은 다음과 같은 방식으로 설정될 수 있다.
  • Memory to Peripherals Transfer (M2P)
  • Peripherals to Memory Transfer (P2M)
  • Memory to Memory Transfer (M2M)
  • DMA의 Stream은 오로지 한번에 1개만 Active될 수 있고, 여러 개의 Stream이 동시에 Active될 수는 없다.
 
위에서 ‘Memory to Peripherals Transfer’과 ‘Peripherals to Memory Transfer’을 살펴보았다. 이번에는 ‘Memory to Memory Transfer’를 살펴보자.
예를 들어, DMA를 사용해 SRAM1에서 SRAM2으로 Data Transfer를 수행한다고 가정한다. (Source : SRAM1 / Destination : SRAM2)
‘Memory to Memory Transfer’는 ‘Peripherals to Memory Transfer’의 Special case이기 때문에, 이 경우에는 Memory가 Peripheral이 될 뿐이다. (단, Bus matrix에서 DMA Controller의 Peripheral port가 해당 SRAM에 연결되어 있는지 확인해야 한다.)
 
 

DMA Channel Mapping

notion image
각 Stream은 다양한 Peripheral들로부터 DMA Request를 받을 수 있는데, 8개의 Channel (request)중 1개만 Stream을 점유할 수 있다.
어떤 Channel이 Stream을 점유할 것인지는 DMA_SxCR의 CHSEL[2:0]에서 설정할 수 있고, Channel과 연결된 Peripheral의 종류는 device에 따라 다르므로 해당 device의 datasheet를 참조해야 한다.
 
다음은 STM32F407xx의 DMAx Request mapping Table이다.
notion image
notion image
에를 들어, STM32F407xx의 DMA1 Stream0의 Channel0에는 SPI3_RX가 연결되어 있다. 그래서 SPI3 peripheral이 Data를 받을 때마다 DMA1의 Stream0의 Channel0에 요청을 보낸다.
(참고로 DMA의 Stream의 Channel은 Memory가 아닌 Peripheral들을 위한 것이다.)
 
 

DMA Channel Mapping Case Study1 : P2M

SPI2 peripheral에서 수신한 Data를 SRAM1에 Transfer하고 싶다고 가정하자.
SPI2가 외부에서 data를 받을 때마다 어떤 Channel을 통해 DMA로 Reqeust를 보내고, 어떤 Stream이 Data Transfer에 사용될까?
  1. 목적에 부합하는 DMA Controller를 골라야 한다. (Bus matrix의 연결 확인)
  1. Channel number와 Stream number를 찾아야 한다.
 
notion image
SPI2_RX는 Stream3의 Channel0에 Mapping 되어 있기 때문에, SPI2 peripheral이 외부로부터 1Byte를 수신할 때마다 Stream3의 Channel0를 통해 DMA에 Request를 전달한다.
그리고 Stream3에 대한 SPI2 peripheral의 Request를 받은 DMA Arbiter는 Stream3를 Activate한다.
그러면 SPI2 peripheral의 Data는 Peripheral port로 들어가서, Stream3를 통해 Memory port로 빠져나가 SRAM1에 전달된다.
 
 

DMA Channel Mapping Case Study2 : M2P, M2M

① Memory to Peripherals Transfer (M2P)

SRAM1의 Data를 UART2의 DR에 Transfer하고 싶다고 가정하자.
UART2가 외부로 data를 보내려고 할 때마다 어떤 Channel을 통해 DMA로 Request를 보내고, 어떤 Stream이 Data Transfer에 사용될까?
  1. 목적에 부합하는 DMA Controller
  1. Channel number와 Stream number를 찾아야 한다.
 
notion image
UART2_TX는 Stream6의 Channel4에 Mapping 되어 있기 때문에, UART2 peripheral이 SRAM1의 Data를 외부로 보내려고 할 때마다 Stream6의 Channel4를 통해 DMA에 Request를 전달한다.
그리고 Stream6에 대한 UART2 peripheral의 Request를 받은 DMA Arbiter는 Stream6를 Activate한다.
그러면 SRAM1의 Data는 Memory port로 들어가서, Stream6를 통해 Peripheral port로 빠져나가 UART2_DR에 전달된다.
 

② Memory to Memory Transfer (M2M)

DMA Request를 위한 Stream의 Channel은 오직 SPI, I2C 등의 Peripheral에서만 사용되고, Memory에서는 사용되지 않는다.
그러면 Memory to Memory Transfer (M2M)는 어떻게 해야할까?
M2M에서는 사용자가 원하는 Stream을 마음대로 골라서 사용할 수 있다.
  1. DMA Controller에서 Source Address와 Destination Address 그리고 사용하고 싶은 Stream을 Enable 한다.
  1. 그러면 해당 Stream에서 Data Transfer가 이루어 질 것이다.
 
 

DMA Arbiter and Stream Priority


notion image
DMA Arbiter는 DMA Stream에 대한 다양한 Peripheral들의 Request를 처리한다.(Like Traffic Control)
DMA Arbiter는 8개의 Stream에 대한 요청을 받을 수 있는데, 각 Request의 Priority를 기반으로 한 번에 하나씩만 Request를 허용한다. (다시 말해서 특정 시점에서 Active되는 Stream은 단 1개이다.)
두 Peripheral의 DMA Requset가 DMA Arbiter로 전달되는 경우를 생각해보자.
만약 동시에 DMA Aribter로 들어온 Stream0 Request의 Priority가 Stream7 Request 보다 높다면, Stream0의 Request가 먼저 허용된다.
Priority는 다음의 두 개의 Priority로 나뉘어 관리된다.
  1. Software Priority : Stream Priority는 DMA_SxCR에서 설정될 수 있고, 4가지의 Level이 존재한다.
      • Very high priority
      • High priority
      • Medium priority
      • Low priority
  1. Hardware Priority : 만약 두 Request가 동일한 Software Priority Level을 갖는다면, 더 낮은 번호의 Stream이 먼저 허용된다. (예를 들어, 동일한 Software Priority를 가지는 Stream2가 Stream4보다 우선권을 가진다.)
 
 

DMA Transfer Modes and FIFO mode


notion image
각 Stream은 4Byte 크기의 FIFO를 가지고 있다. (1Word → AHB Bus의 크기)
 
 

Peripheral to Memory Data Transfer (P2M)


notion image
Peripheral이 DMA Request를 보낼 때마다 Data item은 Peripheral의 Data Register에서 Memory로 이동하는데, 거기에는 두 가지 방식이 존재한다.
  1. Direct mode (FIFO is used without threshold)
  1. FIFO mode (FIFO is used with threshold)
 
Direct mode에서는 FIFO의 Threshold level이 사용되지 않는다. Peripheral에서 FIFO로 Data가 Transfer되면, 해당 Data는 그 즉시 빠져나와 Destination에 저장된다.
반면에 FIFO mode에서는 FIFO의 Threshold level에 도달하면. FIFO에 저장되어 있던 Data가 빠져나와 Destination에 저장된다.
 
FIFO의 Threshold는 DMA_SxFCR에서 설정할 수 있다.
notion image
Peripheral로부터 받은 Data bytes는 FIFO Threshold에 도달할 때까지 FIFO에 저장된다.
예를 들어, Threshold를 1/2 full FIFO로 설정하면, FIFO의 Data 크기가 2Byte가 될 때마다 2Byte의 Data는 FIFO를 빠져나와 Destination에 저장된다.
 
FIFO 사용의 장점은 다음과 같다.
  1. Memory port에 Access하는 빈도가 감소해서, 다른 DMA Requests가 Memory port에 Access 할 수 있게 된다.
  1. 다른 Bus master들이 Memory에 Access할 수 있기 때문에, 다른 Master들의 대기 시간이 감소한다.
 
 

Memory to Peripheral Data Transfer

notion image
Peripheral이 DMA Request를 보낼 때마다 Data item은 Memory에서 Peripheral의 Data Register로 이동하는데, 거기에는 두 가지 방식이 존재한다.
  1. Direct mode (FIFO is used without threshold)
  1. FIFO mode (FIFO is used with threshold)
 
Direct mode에서는 FIFO의 Threshold level이 사용되지 않는다. Stream이 Enable되면, DMA는 첫번째 Data를 Preload해서 내부 FIFO에 Transfer한다. M2P Data Transfer의 Direct Mode의 특징인 이 과정은 Peripheral이 Request를 보냈는지 보내지 않았는지와는 상관없이 Stream을 Enable할 때마다 이루어진다.
그리고 Peripheral이 Data Transfer를 요청하는 즉시 DMA는 Preload된 Data를 Destination에 Transfer한다. 그러면 다시 비어있는 내부 FIFO를 다음에 Transfer할 Data로 reload한다.
FIFO mode에서는 Stream이 Enable될 때마다 FIFO를 Transfer할 Memory의 Data로 가득 채운다. 그리고 Peripheral이 DMA Request를 보낼 때마다 FIFO의 Data가 빠져나와 Destination에 Transfer된다. FIFO의 Level이 사전에 설정된 FIFO Threshold Level 보다 낮거나 동일하다면, FIFO는 다시 FIFO를 Transfer할 Memory의 Data로 가득 채운다.