F4.DMA Режим передачи ПАМЯТЬ-ПАМЯТЬ


Для передачи из памяти в память используется DMA2 контроллер. DMA1 не может использоваться потому что периферийный порт не подключен к шинной матрице AHB (мануал RM0090 страница 305).

Включаем тактирование DMA2:
RCC->AHB1ENR  |= RCC_AHB1ENR_DMA2EN;

Теперь нужно настроить поток для передачи. Любой свободный из 8 можно использовать. Выберем DMA2_Stream6 и настроим конфигурационный регистр DMA2_Stream6->CR

Задаем размерность памяти 16 бит для приема и передачи (поле MSIZE и PSIZE) и направление передачи (поле DIR)
DMA2_Stream6->CR |= DMA_SxCR_MSIZE_0 | DMA_SxCR_PSIZE_0 | DMA_SxCR_DIR_1;

Теперь укажем адрес откуда брать данные (поле PAR) у нас это 16 битная переменная COLOR
uint16_t COLOR = 0x00FF;
DMA2_Stream6->PAR = (uint32_t) &COLOR;

Теперь укажем адрес куда передавать данные (поле M0AR) у нас это адрес LCD_BASE_RAM 0x60000000 | (1 << 17). Это подключенный дисплей в адресное пространство МК через FSMC контроллер. Т.е. фактически мы будет отправлять пикселы на дисплей через DMA.
#define LCD_BASE 0x60000000
#define LCD_BASE_RAM (LCD_BASE | (1 << 17))
DMA2_Stream6->M0AR = (uint32_t)(LCD_BASE_RAM);

С конфигурационным регистром все. DMA готов к запуску.

Установим количество транзакций для передачи в регистр NDTR
DMA2_Stream6->NDTR = 2019;

И собственно запускаем передачу включив поле EN в регистре CR
DMA2_Stream6->CR |= DMA_SxCR_EN;

Ждем флаг окончания передачи и сбрасываем его.
while((DMA2->HISR & DMA_HIFCR_CTCIF6) == 0){};
DMA2->HIFCR = DMA_HIFCR_CTCIF6;

Запускаем еще раз
DMA2_Stream6->NDTR = 2019;
DMA2_Stream6->CR |= DMA_SxCR_EN;
while((DMA2->HISR & DMA_HIFCR_CTCIF6) == 0){};
DMA2->HIFCR = DMA_HIFCR_CTCIF6;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
uint16_t COLOR = 0x00FF;
#define LCD_BASE 0x60000000
#define LCD_BASE_RAM (LCD_BASE | (1 << 17))
 
void DMA_SETUP(void)
{
RCC->AHB1ENR |= RCC_AHB1ENR_DMA2EN;
 
DMA2_Stream6->CR |= DMA_SxCR_MSIZE_0 | DMA_SxCR_PSIZE_0 | DMA_SxCR_DIR_1;
DMA2_Stream6->M0AR = (uint32_t)(LCD_BASE_RAM);
DMA2_Stream6->PAR = (uint32_t)&COLOR;
 
DMA2_Stream6->NDTR = 2019;
DMA2_Stream6->CR |= DMA_SxCR_EN;
 
//WAIT DMA TRANSFER COMPLETE
while((DMA2->HISR & DMA_HIFCR_CTCIF6) == 0){};
DMA2->HIFCR = DMA_HIFCR_CTCIF6;
 
DMA2_Stream6->NDTR = 2019;
DMA2_Stream6->CR |= DMA_SxCR_EN;
 
//WAIT DMA TRANSFER COMPLETE
while((DMA2->HISR & DMA_HIFCR_CTCIF6) == 0){};
DMA2->HIFCR = DMA_HIFCR_CTCIF6;
}

Оставить ответ