2014-02-26 06:29 AM
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);}2014-02-26 06:58 AM
The code is incomplete, lack defines, and won't compile
No DMA interrupt implemented The USART RXNE interrupt is not enabledDMA_ITConfig(DMA1_Channel2, DMA1_IT_TC2 | DMA1_IT_TE2, ENABLE); // No I don't think so!2014-02-26 07:05 AM
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?2014-02-26 07:12 AM
2014-02-26 07:15 AM
> 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. JW2014-02-26 07:24 AM
> hello admin, how can I post a question on this forum?
2014-02-26 07:33 AM
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)
2014-02-26 07:38 AM
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 codeThanks again!Mat2014-02-26 07:40 AM
DMA_TX_InitStructure is obviously global, are you sure it is not modified anywhere else ?
2014-02-26 08:03 AM
> 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