Skip to main content
Pilous Droip
Senior
January 30, 2018
Question

Restart DMA - STM32F767

  • January 30, 2018
  • 6 replies
  • 1126 views
Posted on January 30, 2018 at 11:35

Hello.

I have question. How to restart DMA?

I have this init function:

&sharpdefine DMA_RX_BUFF_SIZE            64         

uint8_t dma_rx_buff[DMA_RX_BUFF_SIZE];

void MX_UART5_Init(void)

{

/* Enable CLOCK for GPIO */

LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOC);

LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOD);

/* Enable Clock for UART5 */

LL_RCC_SetUARTClockSource(LL_RCC_UART5_CLKSOURCE_HSI);

/* Peripheral clock enable */

LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_UART5);

LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_DMA1);

/* create structure */

LL_USART_InitTypeDef USART_InitStruct;

LL_GPIO_InitTypeDef GPIO_InitStruct;

/**

* UART5 GPIO Configuration

* PC12 ------> UART5_TX

* PD2 ------> UART5_RX

*/

GPIO_InitStruct.Pin = LL_GPIO_PIN_12;

GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;

GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_VERY_HIGH;

GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;

GPIO_InitStruct.Pull = LL_GPIO_PULL_UP;

GPIO_InitStruct.Alternate = LL_GPIO_AF_8;

LL_GPIO_Init(GPIOC, &GPIO_InitStruct);

GPIO_InitStruct.Pin = LL_GPIO_PIN_2;

GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;

GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_VERY_HIGH;

GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;

GPIO_InitStruct.Pull = LL_GPIO_PULL_UP;

GPIO_InitStruct.Alternate = LL_GPIO_AF_8;

LL_GPIO_Init(GPIOD, &GPIO_InitStruct);

/* Init DMA */

/* For UART5 -> STREAM - 0, CHANNEL = 4 */

LL_DMA_SetChannelSelection(DMA1, LL_DMA_STREAM_0, LL_DMA_CHANNEL_4);

LL_DMA_SetDataTransferDirection(DMA1, LL_DMA_STREAM_0, LL_DMA_DIRECTION_PERIPH_TO_MEMORY);

LL_DMA_SetStreamPriorityLevel(DMA1, LL_DMA_STREAM_0, LL_DMA_PRIORITY_LOW);

LL_DMA_SetMode(DMA1, LL_DMA_STREAM_0, LL_DMA_MODE_NORMAL);

LL_DMA_SetPeriphIncMode(DMA1, LL_DMA_STREAM_0, LL_DMA_PERIPH_NOINCREMENT);

LL_DMA_SetMemoryIncMode(DMA1, LL_DMA_STREAM_0, LL_DMA_MEMORY_INCREMENT);

LL_DMA_SetPeriphSize(DMA1, LL_DMA_STREAM_0, LL_DMA_PDATAALIGN_BYTE);

LL_DMA_SetMemorySize(DMA1, LL_DMA_STREAM_0, LL_DMA_MDATAALIGN_BYTE);

LL_DMA_DisableFifoMode(DMA1, LL_DMA_STREAM_0);

LL_DMA_SetMemoryAddress(DMA1, LL_DMA_STREAM_0, (uint32_t)dma_rx_buff);

LL_DMA_SetDataLength(DMA1, LL_DMA_STREAM_0, sizeof(dma_rx_buff));

LL_DMA_SetPeriphAddress(DMA1, LL_DMA_STREAM_0, (uint32_t)&UART5->RDR);

//LL_DMA_EnableIT_HT(DMA1, LL_DMA_STREAM_0);

//LL_DMA_EnableIT_TC(DMA1, LL_DMA_STREAM_0);

LL_DMA_EnableStream(DMA1, LL_DMA_STREAM_0);

/* init for UART5 */

USART_InitStruct.BaudRate = 115200;

USART_InitStruct.DataWidth = LL_USART_DATAWIDTH_8B;

USART_InitStruct.StopBits = LL_USART_STOPBITS_1;

USART_InitStruct.Parity = LL_USART_PARITY_NONE;

USART_InitStruct.TransferDirection = LL_USART_DIRECTION_TX_RX;

USART_InitStruct.HardwareFlowControl = LL_USART_HWCONTROL_NONE;

USART_InitStruct.OverSampling = LL_USART_OVERSAMPLING_16;

LL_USART_Init(UART5, &USART_InitStruct);

LL_USART_Init(UART5, &USART_InitStruct);

LL_USART_ConfigAsyncMode(UART5);

LL_USART_EnableDMAReq_RX(UART5);

//LL_USART_EnableIT_IDLE(UART5);

LL_USART_EnableRxTimeout(UART5);

LL_USART_SetRxTimeout(UART5, 115);

LL_USART_EnableIT_RTO(UART5);

LL_USART_Enable(UART5);

NVIC_SetPriority(UART5_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 0, 0));

NVIC_EnableIRQ(UART5_IRQn);

}

And this funtion:

void UART5_IRQHandler(void) {

uint16_t pos;

/**

* Check for idle line detection on USART

*/

if (LL_USART_IsActiveFlag_RTO(UART5)) //kontrola, zda je preruseni od TIMER Rx uartu

{

LL_USART_ClearFlag_RTO(UART5); //smazu priznak

prijatych_znaku=DMA_RX_BUFF_SIZE-LL_DMA_GetDataLength(DMA1, LL_DMA_STREAM_0);

itoa(prijatych_znaku, buffer, 10);

process_usart_data(buffer, strlen(prijatych_znaku));

LL_DMA_DisableStream(DMA1, LL_DMA_STREAM_0);

LL_DMA_SetMemoryAddress(DMA1, LL_DMA_STREAM_0, (uint32_t)dma_rx_buff);

LL_DMA_SetDataLength(DMA1, LL_DMA_STREAM_0, sizeof(dma_rx_buff));

LL_DMA_EnableStream(DMA1, LL_DMA_STREAM_0);

}

}

And when I receive data I print lenght of receive data. And my receive data show as:

  • --> Send from PC
    • Hello\r\n
  • <-- Return to PC
    • 7
  • -->Send from PC
    • Hello\r\n
  • <-- Return to PC
    • 0

I would expect 7, not 0.

#uart-dma #stm32f767
This topic has been closed for replies.

6 replies

Pilous Droip
Senior
January 30, 2018
Posted on January 30, 2018 at 12:41

I modificate this function:

void UART5_IRQHandler(void)

{

if (LL_USART_IsActiveFlag_RTO(UART5)) //check RTO uart

{

LL_USART_ClearFlag_RTO(UART5); //delete flag

receive_char=DMA_RX_BUFF_SIZE-LL_DMA_GetDataLength(DMA1, LL_DMA_STREAM_0);

itoa(

receive_char

, buffer, 10);

usart_puts(buffer);

usart_puts(''\r\nNEW:'');

LL_DMA_DisableStream(DMA1, LL_DMA_STREAM_0);

LL_DMA_SetDataLength(DMA1, LL_DMA_STREAM_0, sizeof(dma_rx_buff));

LL_DMA_SetMemoryAddress(DMA1, LL_DMA_STREAM_0, (uint32_t)dma_rx_buff);

LL_DMA_EnableStream(DMA1, LL_DMA_STREAM_0);

}

}

And when I send first string, MCU return good value (7), but after this it is return only 0. And it is wrong value. Any idea, what is wrong?

Yellow: data from PC

Black: data from MCU

0690X00000604H1QAI.jpg
waclawek.jan
Super User
January 30, 2018
Posted on January 30, 2018 at 13:11

Read out and check/post the content of relevant DMA registers (including status) at the beginning of ISR.

JW

Pilous Droip
Senior
January 30, 2018
Posted on January 30, 2018 at 13:12

Sorry, but I don't understand. How do you think?