Уточнення при переривці, викликаному переносом DMA в STM32


0

Я намагаюся дізнатися про DMA та його використання в платформі STM32L4S9VI. Мене бентежить одне, що пов'язує передачу DMA до будь-якого конкретного переривання? У наведеному нижче прикладі мені цікаво, який UART переривання запускає передачу наступного байта в регістр даних передачі, а також те, як DMA визначає, яке переривання з UART викликалося. Як я розумію, насправді існує лише одна загальна лінія переривання USART2, яка переходить до DMA, тож як DMA насправді знає, що переривання - це те, що сигналізує про те, що він готовий мати ще один байт, поміщений в реєстр даних передачі? Чи

HAL_UART_IRQHandler(&huart2);

подбати про це?


Приклад:

/* Private variables ---------------------------------------------------------*/
extern UART_HandleTypeDef huart2;
DMA_HandleTypeDef hdma_usart2_tx;
char *msg = "Hello STM32 Lovers! This message is transferred in DMA Mode.\r\n";


/* USER CODE BEGIN PV */
/* Private variables ---------------------------------------------------------*/

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void DMATransferComplete(DMA_HandleTypeDef *hdma);

/* USER CODE BEGIN PFP */
/* Private function prototypes -----------------------------------------------*/

/* USER CODE END PFP */

/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

int main(void) {
  HAL_Init();

  Nucleo_BSP_Init();

  hdma_usart2_tx.Instance = DMA1_Channel7;
  hdma_usart2_tx.Init.Request = DMA_REQUEST_2;
  hdma_usart2_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
  hdma_usart2_tx.Init.PeriphInc = DMA_PINC_DISABLE;
  hdma_usart2_tx.Init.MemInc = DMA_MINC_ENABLE;
  hdma_usart2_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
  hdma_usart2_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
  hdma_usart2_tx.Init.Mode = DMA_NORMAL;
  hdma_usart2_tx.Init.Priority = DMA_PRIORITY_LOW;
  hdma_usart2_tx.XferCpltCallback = &DMATransferComplete;
  HAL_DMA_Init(&hdma_usart2_tx);

  /* DMA interrupt init */
  HAL_NVIC_SetPriority(DMA1_Channel7_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(DMA1_Channel7_IRQn);

  HAL_DMA_Start_IT(&hdma_usart2_tx,  (uint32_t)msg,  (uint32_t)&huart2.Instance->TDR, strlen(msg));
  //Enable UART in DMA mode
  huart2.Instance->CR3 |= USART_CR3_DMAT;

  /* Infinite loop */
  while (1);
}

void DMATransferComplete(DMA_HandleTypeDef *hdma) {
  if(hdma->Instance == DMA1_Channel7) {
    //Disable UART DMA mode
    huart2.Instance->CR3 &= ~USART_CR3_DMAT;
    //Turn LD2 ON
    HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, GPIO_PIN_SET);
  }
}

Передача DMA спричинить лише специфічні переривання периферійного пристрою (наприклад, отриманий байт та перервані перешкоди передачі байтів). Не кожен перерив із тієї периферійної волі. Непорозуміння на кшталт цього трапляються, коли ти не озираєшся за попередньо написаними бібліотеками. Прочитайте посібник для STM32 DMA та USART. Подивіться, що насправді роблять регістри.
DKNguyen

@DKNguyen Чи десь я можу знайти, які периферійні переривання перенаправлені до DMA? Я оглянув посібник з посиланнями і нічого не можу знайти, за винятком частини DMAMUX, яка дає мені загальний огляд, а не важкі цифри.
колькотон

Який MCU ви використовуєте?
DKNguyen

Лист даних про це ще менше поглиблений, я дійсно заглибився у посібник з посилань, оскільки він фактично перелічує регістри, але все одно насправді не скаже мені, як щось пов’язано, що дуже засмучує.
колькотон

Вибачте, я помилився з приводу даних аркуша. Це все у довідковому посібнику. Наприклад, для STM32F303 це в таблицях 78 та 79. Який MCU ви використовуєте?
DKNguyen

Відповіді:


1

У STM32L4 є і DMA, і DMA мультиплексор.

У більш простому мікросхемі на зразок STM32F3 є лише базовий DMA з прямими лініями до кожної DMA-периферії. Але я думаю, що в STM32L4 є багато інших периферійних пристроїв, і навряд чи багато з них буде використовуватися з DMA в будь-якому одному додатку. У поєднанні з недоцільністю запуску прямих ліній DMA до кожної периферії вони вирішили додати DMA mux між периферійними пристроями та DMA, щоб серед численних доступних для DMA периферійних пристроїв можна було вибрати лише декілька, які потрібні будь-коли. повинні бути перенаправлені до DMA, таким чином зберігаючи лінії до DMA невеликими.

Кожен висновок mux DMA (ви можете думати про це як паралельні одновивідні мукс-файли, які мають загальні входи, але кожен вихід йде в інший рядок у DMA) має реєстр, який дозволяє виводити, а також вибирає, який вхід (тобто периферійний) для підключення.

Звідти ви б налаштували свою DMA так, щоб вона поводилась належним чином для цієї периферії, одночасно посилаючись на цей вивід mux (скоріше безпосередньо посилаючись на периферійний, як у базовій DMA, де периферія має лінію безпосередньо до DMA).

Як я розумію, насправді існує лише одна загальна лінія переривання USART2, яка переходить до DMA, тож як DMA насправді знає, що переривання - це те, що сигналізує про те, що він готовий мати ще один байт, поміщений в реєстр даних передачі?

Не кожне переривання від DMA-периферійного пристрою викликає передачу DMA. Це не має сенсу у використанні. Кожна периферія розроблена таким чином, що лише певні переривання викликають передачу DMA.

Наприклад, для USART має сенс запускати передачу DMA лише тоді, коли байт отриманий або коли байт закінчив передачу, тому це єдині переривання, які запускають передачу DMA, і кожен має окремий біт включення (UART RX і TX мають різні тригерні лінії DMA).

Який конкретний перерив для периферійного пристрою буде викликати DMA, буде знаходитися в конкретному периферійному розділі довідкового посібника.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.