реклама на сайте
подробности

 
 
> STM32H743 MDMA, Нет передачи в периферию
__inline__
сообщение Jul 18 2018, 14:38
Сообщение #1


Местный
***

Группа: Участник
Сообщений: 257
Регистрация: 5-09-17
Пользователь №: 99 126



Использую H743 на отладочной плате Nucleo.

Работал с DMA, DMA2D - всё чудесно и превосходно: с AXI RAM отправляю буфер в LCD-дисплей по шине FMC 8-бит (дисплей со своим контроллером и видеопамятью).

Но не хватает опции перестановки байтов, потому что LCD требует передавать старший, затем младший байт. Пока использую REV16 per pixel.

Хочу избавиться от REV16, применив MDMA в котором можно включить перестановку байтов (слов и полу-слов).

Проблема: MDMA не работает: инит сделал Кубом , вызов через HAL. Код стандартный и нет нужды его приводить здесь.

Буфер кадра в AXI SRAM, дисплей на FMC, кеширование портов дисплея отключено (адреса 0xC0000000...0xC0010000). Дисплей чёрный - ничего не отрисовывает.

Почему?

Волнует специфика - может ли MDMA отрабатывать транзакции AXI SRAM => FMC ? Читал мануал, прямого ответа там на мой вопрос нет.
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
__inline__
сообщение Jul 19 2018, 11:38
Сообщение #2


Местный
***

Группа: Участник
Сообщений: 257
Регистрация: 5-09-17
Пользователь №: 99 126



Теперь всё ясно. Всем спасибо.

Интересно, что когда программировал DMA звуковой карты на ПК, там не нужно было оперировать с кешем вообще. Хотя в CPU были включены кеши.

Немного огорчило, что максимальный блок для передачи MDMA - 64 кБ. Пришлось буфер LCD резать на кусочки. Сделал 3 куска (320x240x2 /3 <64kB). Всё работает.

Свопинг байтов тоже сделан, что и нужно было!

Код
u16 Buffer[240*320] __attribute__((aligned(32)));

int main(void)
{
SCB_EnableICache();
SCB_EnableDCache();

HAL_Init();

SystemClock_Config();

MX_GPIO_Init();
MX_FMC_Init();
MX_DMA_Init();

MX_MDMA_Init();

LED(RESET);

LCD_Reset();
LCD_Init();
LCD_Position(0,0,W-1,H-1);

for(u32 i=0;i<(240*320);i++)
{
  u32 c=i/(240*40);
  Buffer[i]=  (((c/4)*0x1F)<<11) | ((((c/2)&1)*0x3F)<<5) | ((c&1)*0x1F);
}

SCB_CleanDCache();

if(HAL_MDMA_Start(&hmdma_mdma_channel7_sw_0,(u32)Buffer,(u32)&LCD_DAT32,(240*320*2)/3,3)!=HAL_OK)while(1);

if(HAL_MDMA_PollForTransfer(&hmdma_mdma_channel7_sw_0,HAL_MDMA_FULL_TRANSFER,1000)!=HAL_OK)while(1);

// SCB_InvalidateDCache();

while(1)
{
LED(SET);
delay_ms(100);
LED(RESET);
delay_ms(100);
}


Инит МДМА:
Код
static void MX_MDMA_Init(void)
{
  /* MDMA controller clock enable */
  __HAL_RCC_MDMA_CLK_ENABLE();
  /* Local variables */

  /* Configure MDMA channel MDMA_Channel7 */
  /* Configure MDMA request hmdma_mdma_channel7_sw_0 on MDMA_Channel7 */
  hmdma_mdma_channel7_sw_0.Instance = MDMA_Channel7;
  hmdma_mdma_channel7_sw_0.Init.Request = MDMA_REQUEST_SW;
  hmdma_mdma_channel7_sw_0.Init.TransferTriggerMode = MDMA_FULL_TRANSFER;
  hmdma_mdma_channel7_sw_0.Init.Priority = MDMA_PRIORITY_LOW;

  hmdma_mdma_channel7_sw_0.Init.Endianness = MDMA_LITTLE_BYTE_ENDIANNESS_EXCHANGE; //Меняем местами байты (для LCD)

  hmdma_mdma_channel7_sw_0.Init.SourceInc      = MDMA_SRC_INC_HALFWORD;
  hmdma_mdma_channel7_sw_0.Init.DestinationInc = MDMA_DEST_INC_DISABLE;

  hmdma_mdma_channel7_sw_0.Init.SourceDataSize = MDMA_SRC_DATASIZE_HALFWORD;
  hmdma_mdma_channel7_sw_0.Init.DestDataSize = MDMA_DEST_DATASIZE_HALFWORD;

  hmdma_mdma_channel7_sw_0.Init.DataAlignment = MDMA_DATAALIGN_PACKENABLE;

  hmdma_mdma_channel7_sw_0.Init.BufferTransferLength = 2;                     //1 для BYTE, 2 для HALFWORD, 4 для WORD

  hmdma_mdma_channel7_sw_0.Init.SourceBurst = MDMA_SOURCE_BURST_SINGLE;
  hmdma_mdma_channel7_sw_0.Init.DestBurst = MDMA_DEST_BURST_SINGLE;
  hmdma_mdma_channel7_sw_0.Init.SourceBlockAddressOffset = 0;
  hmdma_mdma_channel7_sw_0.Init.DestBlockAddressOffset = 0;
  if (HAL_MDMA_Init(&hmdma_mdma_channel7_sw_0) != HAL_OK)
  {
    Error_Handler();
  }

}


А для чего бурсты в DMA ? Они ускорят обмен с LCD?
Go to the top of the page
 
+Quote Post
Arlleex
сообщение Jul 19 2018, 12:20
Сообщение #3


Местный
***

Группа: Участник
Сообщений: 492
Регистрация: 12-11-11
Пользователь №: 68 264



Цитата(__inline__ @ Jul 19 2018, 15:38) *
Интересно, что когда программировал DMA звуковой карты на ПК, там не нужно было оперировать с кешем вообще. Хотя в CPU были включены кеши.

Это называется система с полностью когерентным кэшем. Там перед стартом DMA сам аппаратно пинает контроллер кэша, чтобы тот слил данные из нужной области памяти. Либо обновил кэш при чтении.

Цитата(__inline__ @ Jul 19 2018, 15:38) *
Немного огорчило, что максимальный блок для передачи MDMA - 64 кБ. Пришлось буфер LCD резать на кусочки. Сделал 3 куска (320x240x2 /3 <64kB). Всё работает.

Ну да, так сделано во всех STM32.

Цитата(__inline__ @ Jul 19 2018, 15:38) *
А для чего бурсты в DMA ? Они ускорят обмен с LCD?

Burst-режим работы DMA - это режим, когда DMA безразрывно занимает шину, то есть транзакцию никакой мастер шины больше прервать не сможет. Например, если надо разом заполнить все регистры таймера.
Я могу ошибаться, но вроде отличие от одиночного режима в том, что в случае одиночных пересылок на каждую транзакцию контроллер DMA выделяет еще стадию адресации памяти:
ADDR1 | DATA1 | ADDR2 | DATA2 | CPU ADDR1 | CPU DATA1 | ADDR3 | DATA3 |... Как видно, при этом CPU может разорвать атомарность пересылки DMA.
В burst-режиме используется один цикл адресации с дальнейшей передачей всего пакета (beat):
| ADDR | DATA1 | DATA2 | DATA3 | DATA4 |...
Это из какой-то Интернет-байки статьи, не относительно к конкретной архитектуре.
Не забывайте только, что одна транзакция DMA Burst не должна пересекать границу 1кБ (вроде), это связано с физическими адресуемыми подчиненными шин. Как-то так rolleyes.gif
Go to the top of the page
 
+Quote Post
__inline__
сообщение Jul 19 2018, 12:38
Сообщение #4


Местный
***

Группа: Участник
Сообщений: 257
Регистрация: 5-09-17
Пользователь №: 99 126



Цитата(Arlleex @ Jul 19 2018, 13:20) *
Это называется система с полностью когерентным кэшем. Там перед стартом DMA сам аппаратно пинает контроллер кэша, чтобы тот слил данные из нужной области памяти. Либо обновил кэш при чтении.

...

Не забывайте только, что одна транзакция DMA Burst не должна пересекать границу 1кБ (вроде), это связано с физическими адресуемыми подчиненными шин. Как-то так rolleyes.gif


Спасибо за развёрнутый ответ! rolleyes.gif
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- __inline__   STM32H743 MDMA   Jul 18 2018, 14:38
- - __inline__   Написал тестовый пример, пересылка память-память ч...   Jul 19 2018, 09:41
|- - Arlleex   Цитата(__inline__ @ Jul 19 2018, 13:41) Ч...   Jul 19 2018, 10:22
|- - __inline__   Всё заработало, когда включил MPU. Протестил на ра...   Jul 19 2018, 10:49
- - Genadi Zawidowski   Инвалидэйт делать перед запуском дома на какую-то ...   Jul 19 2018, 11:01
- - Arlleex   Тут чисто из логики даже все следует. Есть D-Cache...   Jul 19 2018, 11:26
|- - esaulenka   Цитата(Arlleex @ Jul 19 2018, 15:20) Не з...   Jul 20 2018, 06:50
|- - Arlleex   Цитата(esaulenka @ Jul 20 2018, 10:50) Ка...   Jul 20 2018, 07:06
- - Genadi Zawidowski   ЦитатаПоэтому после выдачи события "транзакци...   Jul 19 2018, 14:54
|- - Arlleex   Цитата(Genadi Zawidowski @ Jul 19 2018, 17...   Jul 19 2018, 17:18
- - Genadi Zawidowski   Кодвообще не смог понять Вспомните, что в данном п...   Jul 19 2018, 21:20
|- - jcxz   Цитата(Genadi Zawidowski @ Jul 20 2018, 00...   Jul 19 2018, 22:28
- - Genadi Zawidowski   Дело в том, что пока процессор ожидает завершения ...   Jul 19 2018, 23:26
- - Arlleex   В общем, я лишь для общей картины добавлю официаль...   Jul 20 2018, 06:16
- - esaulenka   Да, неправ, это место просмотрел... Благо объемы у...   Jul 20 2018, 12:43
|- - Arlleex   Цитата(esaulenka @ Jul 20 2018, 16:43) Но...   Jul 20 2018, 14:23
- - Genadi Zawidowski   ЦитатаИ маленький буфер тоже по-хорошему выравнива...   Jul 20 2018, 13:26


Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 12th August 2025 - 17:38
Рейтинг@Mail.ru


Страница сгенерированна за 0.01459 секунд с 7
ELECTRONIX ©2004-2016