cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F103 USART DMA issue

matteo239955
Associate III
Posted on February 26, 2014 at 15:29

Hi all,

I have a problem using the DMA with USART3 on an STM32F103 MCU:

I've configured the USART3 to transmit a buffer (fixed length) one shot using the DMA (just transmitting, not receiving) and then stop transmitting.

Once I've enabled the DMA and the uart starts to transmit bits, it never ends.... the behavior I see (using an oscilloscope) is the same I should get configuring the DMA in circular mode... but my DMA is in NormalMode...  so my code never gets into the DMA1_Channel2 TC interrupt.

Is there any other settings to do or any flag to clear in some interrupt handler?

I hope someone's able to help me... Tanks!

I've configured USART and DMA in the following way:

UartLayer_comLayerSetup(void) 

{

// USART Init Structures

GPIO_InitTypeDef GPIO_InitStructure;

USART_InitTypeDef USART_InitStructure;

NVIC_InitTypeDef NVIC_InitStructure;

// Enabling bus clocks

RCC_APB2PeriphClockCmd(HWCONF_USART_RCC_PORT | HWCONF_USART_BUS, ENABLE);

RCC_APB1PeriphClockCmd(HWCONF_USART_APB_USART, ENABLE);

// USART3 ---------------------------------------------------------------------------

// COnfigure Pins

GPIO_InitStructure.GPIO_Pin = HWCONF_USART_TX_PIN;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;

GPIO_Init(HWCONF_USART_PORT, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = HWCONF_USART_RX_PIN;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;

GPIO_Init(HWCONF_USART_PORT, &GPIO_InitStructure);

// Set USART Parameters

USART_InitStructure.USART_BaudRate = 115200;

USART_InitStructure.USART_WordLength = USART_WordLength_8b;

USART_InitStructure.USART_StopBits = USART_StopBits_1;

USART_InitStructure.USART_Parity = USART_Parity_No;

USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;

  // USART 3 INTERRUPT CONFIGUTATION -> used in receiving mode on the RXNE flag

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);

//Write USART parameters

USART_Init(HWCONF_USART_NUM, &USART_InitStructure);

// DMA Tx interrupt configuration

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel2_IRQn;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);

DMA_DeInit(DMA1_Channel2);

DMA_TX_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&(USART3)->DR; // Specifies the peripheral base address for DMAxChannely

  DMA_TX_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; // Specifies the DMA direction

  DMA_TX_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; // Specifies whether the peripheral address register should be incremented or not

  DMA_TX_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; // Specifies whether the memory address register should be incremented or not

  DMA_TX_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; // Specifies the peripheral data width

  DMA_TX_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; // Specifies the memory data width

  DMA_TX_InitStructure.DMA_Mode = DMA_Mode_Normal; // Specifies the operation mode of the DMAxChannely

  DMA_TX_InitStructure.DMA_Priority = DMA_Priority_High; // Specifies the software priority for the DMAxChannely

  DMA_TX_InitStructure.DMA_M2M = DMA_M2M_Disable; // Disable MemoryToMemory feature

USART_Cmd(HWCONF_USART_NUM, ENABLE);

}

void USART3_IRQHandler(void) 

{

// If a byte has been received

if (USART_GetITStatus(HWCONF_USART_NUM, USART_IT_RXNE) != RESET) 

{

//trace('c');

uint8_t TmpRecByte = USART_ReceiveData(HWCONF_USART_NUM); // Reading byte

USART_ClearITPendingBit(HWCONF_USART_NUM, USART_IT_RXNE); // Clearing Interrupt Flag

_ComInterface_processByte(COM_UART, TmpRecByte);

}

}

void _StartTxDMA(const uint8_t * dataBuffer, uint32_t dataSize)

{

// Setting the TX Pin in Output Pull'up

GPIO_InitTypeDef GPIO_InitStructure;

GPIO_InitStructure.GPIO_Pin = HWCONF_USART_TX_PIN;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;

GPIO_Init(HWCONF_USART_PORT, &GPIO_InitStructure);

// Preparing the DMA transaction from memory to USART

DMA_DeInit(DMA1_Channel2);

DMA_TX_InitStructure.DMA_MemoryBaseAddr = (uint32_t)dataBuffer;

DMA_TX_InitStructure.DMA_BufferSize = dataSize;

DMA_Init(DMA1_Channel2, &DMA_TX_InitStructure);

// Enable USART TX DMA request

USART_DMACmd(USART3, USART_DMAReq_Tx, ENABLE);

USART_ClearFlag(USART3, USART_FLAG_TC);

// Enable DMA Interrupts

DMA_ITConfig(DMA1_Channel2, DMA1_IT_TC2 | DMA1_IT_TE2, ENABLE);

// Enable DMA stream -> start transfert

DMA_Cmd(DMA1_Channel2, ENABLE);

}
10 REPLIES 10
Posted on February 26, 2014 at 15:58

The code is incomplete, lack defines, and won't compile

No DMA interrupt implemented

The USART RXNE interrupt is not enabled

DMA_ITConfig(DMA1_Channel2, DMA1_IT_TC2 | DMA1_IT_TE2, ENABLE); // No I don't think so!

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
matteo239955
Associate III
Posted on February 26, 2014 at 16:05

Yes I know Clive1 that many parts of the code are missing because it's quite distributed... I've just posted the USART/DMA configurations...

What do you mean with your comment '' // No I don't think so!'' ? 

I've missed any flag or used something inappropriate?

anhhuy0701
Associate II
Posted on February 26, 2014 at 16:12

Posted on February 26, 2014 at 16:15

> Yes I know Clive1 that many parts of the code are missing because it's quite distributed... I've just posted the USART/DMA configurations...

Prepare and post a minimal, but complete and compilable example, exhibiting your problem.

JW

Posted on February 26, 2014 at 16:24

> hello admin, how can I post a question on this forum?

0690X000006051FQAQ.png

Posted on February 26, 2014 at 16:33

What do you mean with your comment '' // No I don't think so!'' ?  I've missed any flag or used something inappropriate?

 

DMA_ITConfig(DMA1_Channel2, DMA_IT_TC | DMA_IT_TE, ENABLE)

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
matteo239955
Associate III
Posted on February 26, 2014 at 16:38

Thank you very mutch clive1... it was just that mistake... now works!

I'm sorry for the confusion I've created.... next time I will try to better describe the problem with a more complete code

Thanks again!

Mat

stm322399
Senior
Posted on February 26, 2014 at 16:40

DMA_TX_InitStructure is obviously global, are you sure it is not modified anywhere else ?

Posted on February 26, 2014 at 17:03

> DMA_ITConfig(DMA1_Channel2, DMA1_IT_TC2 | DMA1_IT_TE2, ENABLE); // No I don't think so!

> DMA_ITConfig(DMA1_Channel2, DMA_IT_TC | DMA_IT_TE, ENABLE)

I say, you deserved it, for using the ''library''... 😉

JW