STM DMA не будет непрерывно передавать по линии UART

Я использую плату STM32L4R5 и пытаюсь настроить DMA на линии UART2. Мне удалось заставить линию RX работать так, как я хочу, но когда я следую «Передача с использованием DMA» в разделе 44.5.19 «Справочного руководства RM0432», передается только один байт и ничего больше. Этот байт отправляется только тогда, когда я явно записываю байт в регистр TDR. После этого я вижу, что флаг TC очищен и затронут первый байт моего регистра DMA. Как заставить DMA постоянно отправлять данные в TDR для передачи?

Примечание: эта проблема похожа на вопрос без ответа здесь

Шаги, упомянутые в техническом описании, следующие:

  1. Запишите адрес регистра USART_TDR в регистр управления DMA, чтобы сконфигурировать его как место назначения передачи. Данные перемещаются по этому адресу из памяти после каждого события TXE (или TXFNF, если включен режим FIFO).
  2. Запишите адрес памяти в регистр управления DMA, чтобы настроить его как источник передачи. Данные загружаются в регистр USART_TDR из этой области памяти после каждого события TXE (или TXFNF, если включен режим FIFO).
  3. Настройте общее количество байтов, которые будут переданы в регистр управления DMA.
  4. Настройте приоритет канала в регистре DMA
  5. Настройте генерацию прерывания DMA после половинной/полной передачи в соответствии с требованиями приложения.
  6. Очистите флаг TC в регистре USART_ISR, установив бит TCCF в регистре USART_ICR.
  7. Активируйте канал в регистре DMA.

Мой код здесь:

    //filling in dummy info into my DMA TX buffer
    memset((void*)DMA_USB_TXbuf, 0x55, 16);

    //ensuring my UART is configured for DMA Transfer
    huart2.Instance->CR3 |= USART_CR3_DMAT;

    //steps 1-4 taken care of within this funciton
    HAL_DMA_Start_IT(&hdma_usart2_tx, (uint32_t)&huart2.Instance->TDR, (uint32_t)&DMA_USB_TXbuf[0], DMA_USB_TX_SIZE);

    //step 5 (just ensuring that we have the flags we want after the previous function)
    __HAL_DMA_DISABLE(&hdma_usart2_tx);
    __HAL_DMA_ENABLE_IT(&hdma_usart2_tx, DMA_IT_HT);
    __HAL_DMA_ENABLE_IT(&hdma_usart2_tx, DMA_IT_TC);

    //step 6
    __HAL_UART_CLEAR_FLAG(&huart2, UART_CLEAR_TCF);

    //step 7
    __HAL_DMA_ENABLE(&hdma_usart2_tx);

    //I shouldn't need to do this, but this seems to be the only way
    // I get even 1 trasmission from DMA register
    WRITE_REG(huart2.Instance->TDR, 0x55);
Почему не пользуетесь HAL_USART_Transmit_DMA()?
@Codo Я полагаю, что функция называется HAL_UART_Transmit_DMA()
Промежуточное сочетание между прямым доступом к регистру и вызовами библиотеки здесь немного подозрительно. Для вашей платы нет примеров DMA UART? В общих чертах функции xxx_IT HAL особенно печально известны тем, что делают что-то отличное от того, что их имена или перспектива типичных потребностей приложения подразумевают, что они должны, поэтому многие люди в конечном итоге пытаются использовать их способами, которые не будут делать то, что нужно.
@Codo Изначально у меня сложилось впечатление, что функция может выполнять нежелательную задержку, но теперь, глядя на суть функции, я вижу, что это не так. я попробую это

Ответы (1)

Было две части того, почему это не работало должным образом.

  1. Согласно комментарию Codo, простое использование этой функции работало для настройки и передачи UART DMA по линии UART.
  2. Мой UART настроен на управление потоком RTS/CTS, и моя принимающая линия не была готова, что не позволяло отправлять больше символов.

Спасибо, Кодо.