STM32F407VG UART DMA Not Working Properly
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2018-10-20 5:22 PM
Hello Guys;
I am trying to do Push Button Interrput UART+DMA application, but I have a problem about the UART DMA. When I configure the dma in normal mode it just make transmit once. I need to use dma every time I push the button. This is my code ;
#include "stm32f4xx.h" // Device header
#include "stm32f4xx_hal_conf.h" // Keil::Device:STM32Cube Framework:Classic
#include "stm32f4xx_hal.h" // Keil::Device:STM32Cube HAL:Common
#include "stdbool.h"
uint8_t btnWarn[] = "Button Push Interrupt\r\n";
UART_HandleTypeDef sUart4;
DMA_HandleTypeDef dmaHandler;
uint8_t counter=0;
int ret=0;
int ret2=0;
void SysTick_Handler(){
HAL_IncTick();
HAL_SYSTICK_IRQHandler();
if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0))
counter++;
else
counter=0;
}
void UART4_IRQHandler(void)
{
HAL_UART_IRQHandler(&sUart4);
}
void DMA1_Stream4_IRQHandler(void)
{
HAL_DMA_IRQHandler(&dmaHandler);
}
void EXTI0_IRQHandler(){
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);
}
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin){
if(counter >=100){
HAL_UART_Transmit_DMA(&sUart4,btnWarn,sizeof(btnWarn));
counter =0;
}
}
int main(){
HAL_Init();
__PWR_CLK_ENABLE();
__GPIOC_CLK_ENABLE();
//PC10 PC11 UART4 TX and RX
GPIO_InitTypeDef strIO;
strIO.Alternate = GPIO_AF8_UART4;
strIO.Mode = GPIO_MODE_AF_PP;
strIO.Pin = GPIO_PIN_10 | GPIO_PIN_11;
strIO.Pull = GPIO_NOPULL;
strIO.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOC,&strIO);
__GPIOA_CLK_ENABLE();
GPIO_InitTypeDef buttonIT;
buttonIT.Mode = GPIO_MODE_IT_FALLING;
buttonIT.Pin = GPIO_PIN_0;
buttonIT.Pull = GPIO_PULLDOWN;
buttonIT.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOA,&buttonIT);
HAL_NVIC_EnableIRQ(EXTI0_IRQn);
__HAL_RCC_DMA1_CLK_ENABLE();
DMA_HandleTypeDef dmaHandler;
dmaHandler.Instance = DMA1_Stream4;
dmaHandler.Init.Channel = DMA_CHANNEL_4;
dmaHandler.Init.Direction = DMA_MEMORY_TO_PERIPH;
dmaHandler.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
dmaHandler.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
dmaHandler.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
dmaHandler.Init.Mode = DMA_NORMAL;
dmaHandler.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
dmaHandler.Init.Priority = DMA_PRIORITY_VERY_HIGH;
dmaHandler.Init.MemInc = DMA_MINC_ENABLE;
dmaHandler.Init.MemBurst = DMA_MBURST_SINGLE;
dmaHandler.Init.PeriphBurst = DMA_PBURST_SINGLE;
dmaHandler.Init.PeriphInc = DMA_PINC_DISABLE;
__HAL_LINKDMA(&sUart4,hdmatx,dmaHandler);
HAL_DMA_Init(&dmaHandler);
HAL_NVIC_SetPriority(DMA1_Stream4_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Stream4_IRQn);
__UART4_CLK_ENABLE();
sUart4.Instance = UART4;
sUart4.Init.BaudRate = 115200;
sUart4.Init.Mode = UART_MODE_TX_RX;
sUart4.Init.Parity = UART_PARITY_NONE;
sUart4.Init.OverSampling = UART_OVERSAMPLING_16;
sUart4.Init.WordLength = UART_WORDLENGTH_8B;
sUart4.Init.StopBits = UART_STOPBITS_1;
sUart4.Init.HwFlowCtl = UART_HWCONTROL_NONE;
sUart4.hdmatx = &dmaHandler;
HAL_UART_Init(&sUart4);
HAL_NVIC_EnableIRQ(UART4_IRQn);
while(1){
HAL_UART_Transmit_DMA(&sUart4,btnWarn,sizeof(btnWarn));
}
}
I made research on Internet and I could not find the solutions. Maybe I am missing something small, I would be very appreciated I you help me about what am I doing wrong.
Best Regards
- Labels:
-
DMA
-
STM32F4 Series
-
UART-USART
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2018-10-21 12:35 AM
After you call DMA transmit, you have to wait for transmission to complete, before you can start a new one.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2018-10-21 1:35 AM
Tilen,
that's presumably the role of counter variable.
Mustfa,
What exactly are the symptoms? Isn't there any DMA error (I don't know how this demonstrates itself under Cube/HAL, normally I'd look at the relevant bits in DMAx_LISR/HISR).
Btw. you are not supposed to have both DMA and interrupts active for the UART.
JW
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2018-10-21 2:11 AM
is this where you send the Tx after you hit the button ?
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin){
if(counter >=100){
HAL_UART_Transmit_DMA(&sUart4,btnWarn,sizeof(btnWarn));
counter =0;
}
then you shouldn't be doing this:
while(1){
HAL_UART_Transmit_DMA(&sUart4,btnWarn,sizeof(btnWarn));
}
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2018-10-21 2:42 AM
Guys I found the problem,
To see whats going on at the DMA_HandleTypeDef struct, I add same handler in to the main function too. You can see at line 8 and line 75.
When I delete the line 75 DMA_HandleTypeDef, the issue is solved. I dont know why it act like that but I guess both are conflicting.
If you know why it is acting like that could you say the true answer for me to learn :)
Thank you all for your responses.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2018-10-21 3:46 PM
Local variable shadowing global, and pointer to it passed to functions which expect it to exist permanently... Yes C allows all this and finding it may be this tricky. Although some compiler at least issue a warning.
JW
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2018-10-21 4:51 PM
The local variable has limited and often transient scope, not really good for things that need to be globally visible and persistent. The variable in main() has limited scope, and replaces the global.
Jamming the DMA in the while loop probably is also ill-advised, you'd do much better with some kind of semaphore or flag indicating you have DMA busy doing something, which you clear when the IRQ handler sees the DMA transfer completed.
Up vote any posts that you find helpful, it shows what's working..
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2018-10-23 9:47 AM
What ever the correct working answer is, would you write it here on forum too, please. But isn't there UART DMA code both from CubeMX and in ...\STM32Cube\Repository\STM32Cube_FW_F4_V1.21.0\Projects\STM32F4-Discovery\Examples\UART\UART_TwoBoards_ComDMA examples.
