2018-01-30 02:35 AM
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 priznakprijatych_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:
I would expect 7, not 0.
#uart-dma #stm32f7672018-01-30 03:41 AM
I modificate this function:
void UART5_IRQHandler(void)
{if (LL_USART_IsActiveFlag_RTO(UART5)) //check RTO uart
{ LL_USART_ClearFlag_RTO(UART5); //delete flagreceive_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
2018-01-30 05:11 AM
Read out and check/post the content of relevant DMA registers (including status) at the beginning of ISR.
JW
2018-01-30 05:12 AM
Sorry, but I don't understand. How do you think?
2018-01-30 05:27 AM
The simplest way is to put a breakpoint at the beginning of the ISR and read out the registers using the registers view of debugger.
If you don't use a debugger, you can write code to do that at the beginning of ISR and then send the result to PC or visualize in any other way you prefer.
JW
2018-01-30 09:43 AM
Ok. So I look on register of DMA1 and I see one problem. Register:
DMA_SxCR_EN
isn't set to 1, when I restart my DMA. But I don't know why.void UART5_IRQHandler(void)
{if (LL_USART_IsActiveFlag_RTO(UART5))
LL_USART_ClearFlag_RTO(UART5);prijatych_znaku=DMA_RX_BUFF_SIZE-LL_DMA_GetDataLength(DMA1, LL_DMA_STREAM_0);
itoa(prijatych_znaku, buffer, 10); usart_puts(buffer); usart_puts(''\r\nNEW:'');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); // this setDMA_SxCR_EN (problem!!!?)
LL_GPIO_TogglePin(GPIOB, LL_GPIO_PIN_14);
asm(''NOP''); //only for debugging
}}But you can see in function, that I set this register.
2018-01-30 10:44 AM
Ok. Problem was solved.
Here is init:
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_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_ConfigAsyncMode(UART5);
LL_USART_EnableDMAReq_RX(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 interrupt is here.
void UART5_IRQHandler(void)
{if (LL_USART_IsActiveFlag_RTO(UART5)) //kontrola, zda je preruseni od TIMER Rx uartu
{ LL_USART_ClearFlag_RTO(UART5); //smazu priznakprijatych_znaku=DMA_RX_BUFF_SIZE-LL_DMA_GetDataLength(DMA1, LL_DMA_STREAM_0);
itoa(prijatych_znaku, buffer, 10); usart_puts(buffer); usart_puts('\r\nNEW:');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_ClearFlag_TE0(DMA1); LL_DMA_ClearFlag_TC0(DMA1); LL_DMA_EnableStream(DMA1, LL_DMA_STREAM_0);LL_GPIO_TogglePin(GPIOB, LL_GPIO_PIN_14);
asm('NOP');
}}And problem was:
It is ALL.
:)
:)
:)