STM DMA no transmitirá continuamente en la línea UART

Estoy usando una placa STM32L4R5 y estoy tratando de configurar el DMA en la línea UART2. Logré que la línea RX funcione como quiero, pero cuando sigo "Transmisión usando DMA" en la sección 44.5.19 del "Manual de referencia RM0432", solo se transmite un byte y nada más. Este byte solo se envía cuando escribo explícitamente un byte en el registro TDR. Luego, puedo ver que el indicador TC se borra y el primer byte de mi registro DMA se ve afectado. ¿Cómo hago para que el DMA envíe continuamente los datos al TDR para su transmisión?

Nota: este problema parece ser similar a una pregunta sin respuesta aquí

Los pasos mencionados en la hoja de datos son los que se muestran:

  1. Escriba la dirección del registro USART_TDR en el registro de control DMA para configurarlo como destino de la transferencia. Los datos se mueven a esta dirección desde la memoria después de cada evento TXE (o TXFNF si el modo FIFO está habilitado).
  2. Escriba la dirección de memoria en el registro de control DMA para configurarlo como la fuente de la transferencia. Los datos se cargan en el registro USART_TDR desde esta área de memoria después de cada evento TXE (o TXFNF si el modo FIFO está habilitado).
  3. Configure el número total de bytes que se transferirán al registro de control DMA.
  4. Configurar la prioridad del canal en el registro DMA
  5. Configure la generación de interrupciones de DMA después de la mitad/transferencia completa según lo requiera la aplicación.
  6. Borre la bandera TC en el registro USART_ISR configurando el bit TCCF en el registro USART_ICR.
  7. Activar el canal en el registro DMA.

Mi código está aquí:

    //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);
¿ Por qué no usas HAL_USART_Transmit_DMA()?
@Codo Creo que la función se llama HAL_UART_Transmit_DMA()
La mezcla a medio camino entre el acceso directo al registro y las llamadas a la biblioteca aquí es un poco sospechosa. ¿No hay ejemplos de DMA UART para su placa? En términos generales, las funciones xxx_IT de HAL son particularmente notorias por hacer algo diferente a lo que sus nombres o la perspectiva de las necesidades típicas de la aplicación implicarían que deberían hacer, por lo que muchas personas terminan intentando usarlas de formas que no harán lo que se desea.
@Codo Originalmente tenía la impresión de que la función puede hacer un pend indeseable, pero ahora, al observar las entrañas de la función, veo que ese no es el caso. voy a probar eso

Respuestas (1)

Había dos partes de por qué esto no funcionaba como debería.

  1. Según el comentario de Codo, el simple uso de esta función funcionó para configurar y transmitir el UART DMA en la línea UART
  2. Mi UART está configurado con control de flujo RTS/CTS y mi línea de recepción no estaba lista, lo que impedía que se enviaran más caracteres.

gracias codo