2018-06-08 11:55 PM
Hi
I use DMA in Interrupt mode to receive data from UART Periph to memory. data is transfered (my destination memory is occupied correctly)but my DMAReceiptComplete() callback function is never called./*--------------------------------------------------------------------------main.c------------------------------------------------------------------------*/
/* Includes ------------------------------------------------------------------*/
&sharpinclude 'stm32f1xx_hal.h'&sharpinclude <myboard_hal_bsp.h>&sharpinclude 'string.h'/* Private variables ---------------------------------------------------------*/extern UART_HandleTypeDef huart2;extern UART_HandleTypeDef huart1;DMA_HandleTypeDef hdma_usart1_rx;DMA_HandleTypeDef hdma_usart2_tx;char *msg = 'HI Hello STM32 Lovers! This message is transferred in DMA Mode.\r\n';uint8_t buf[2] = '';void DMAReceiptComplete(DMA_HandleTypeDef *hdma);int main(void){
HAL_Init(); MyBoard_BSP_Init();//USART1
hdma_usart1_rx.Instance = DMA1_Channel5; hdma_usart1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY; hdma_usart1_rx.Init.PeriphInc = DMA_PINC_DISABLE; hdma_usart1_rx.Init.MemInc = DMA_MINC_ENABLE; hdma_usart1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; hdma_usart1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; hdma_usart1_rx.Init.Mode = DMA_CIRCULAR; hdma_usart1_rx.Init.Priority = DMA_PRIORITY_VERY_HIGH; hdma_usart1_rx.XferCpltCallback = &DMAReceiptComplete;HAL_DMA_Init(&hdma_usart1_rx);
/* DMA interrupt init */ HAL_NVIC_SetPriority(DMA1_Channel5_IRQn, 0, 0); HAL_NVIC_EnableIRQ(DMA1_Channel5_IRQn); HAL_DMA_Start_IT(&hdma_usart1_rx, (uint32_t)&huart1.Instance->DR, (uint32_t)buf, 2); //Enable UART in DMA mode huart1.Instance->CR3 |= USART_CR3_DMAR;//USART2
hdma_usart2_tx.Instance = DMA1_Channel7; hdma_usart2_tx.Init.Direction = DMA_MEMORY_TO_PERIPH; hdma_usart2_tx.Init.PeriphInc = DMA_PINC_DISABLE; hdma_usart2_tx.Init.MemInc = DMA_MINC_DISABLE; hdma_usart2_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD; hdma_usart2_tx.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD; hdma_usart2_tx.Init.Mode = DMA_NORMAL; hdma_usart2_tx.Init.Priority = DMA_PRIORITY_LOW; HAL_DMA_Init(&hdma_usart2_tx); __HAL_LINKDMA(&huart2, hdmatx, hdma_usart2_tx);/* DMA interrupt init */
HAL_NVIC_SetPriority(DMA1_Channel7_IRQn, 0, 0); HAL_NVIC_EnableIRQ(DMA1_Channel7_IRQn); /* Peripheral interrupt init */ HAL_NVIC_SetPriority(USART2_IRQn, 0, 0); HAL_NVIC_EnableIRQ(USART2_IRQn); //Enable UART in DMA mode ( receive or transmit DMAR DMAT) huart2.Instance->CR3 |= USART_CR3_DMAT; HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET);while(1);
return 0;}void DMAReceiptComplete(DMA_HandleTypeDef *hdma) {
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET); if (hdma->Instance == DMA1_Channel5){ //now we should enable usart2 i think HAL_UART_Transmit_DMA(&huart2, (uint8_t*)buf, 2);}
}void DMA1_Channel5_IRQHandler(void){
HAL_DMA_IRQHandler(&hdma_usart1_rx);}void USART1_IRQHandler (void){
HAL_UART_IRQHandler(&huart1);}void DMA1_Channel7_IRQHandler(void){
HAL_DMA_IRQHandler(&hdma_usart2_tx);}void USART2_IRQHandler (void){
HAL_UART_IRQHandler(&huart2);}void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart){ ;}Is it a bug or I made mistake somewhere?
#dma-uart #xfercpltcallback2018-06-10 04:10 PM
did you fix it ?
did you use the cube ?
I use the Uart DMA in Circular mode.
I just calculate the buffer size from the DMA counter.
2018-06-11 03:47 AM
no I haven't fixed it.
yes I used cube
the problem is with dmauart1_rx , I used it in circular mode too. but
what's the point?
2018-06-11 03:56 AM
why do you need DMAReceiptComplete() ?
I poll this function every mS, RxBufSize = readableU1(); // unread length
void initUart1RxDMABuffer(void) {
if (HAL_UART_Receive_DMA(&huart1, (uint8_t *)Usart1RxDMABuffer, U1RxBufSize) != HAL_OK) printf(string, 'initUart1RxDMABuffer Failed\n'); else printf(string, 'initUart1RxDMABuffer OK!\n');}char readableU1(void) {
U1RxBufferPtrIN = U1RxBufSize - huart1.hdmarx->Instance->CNDTR; return U1RxBufferPtrIN - U1RxBufferPtrOUT; // length of unread characters}char getc1(void) {
char Rxbyte = Usart1RxDMABuffer[U1RxBufferPtrOUT++]; if (U1RxBufferPtrOUT >= U1RxBufSize) U1RxBufferPtrOUT = 0; return Rxbyte;}