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-27 09:18 AM
Hi All again...
Thank to your suggestion, I've completed the UART/DMA and it works perfectly.My actual problem is the following:I'm using the uart with dma to receive a fixed length (10 bytes) packet and it works correctly... I receive hundreds of correct packet with no problem but there is a condition where I need to reset the MCU...well, after the reset the usart gets only the first byte and then nothing else... it seems like that something disables the DMA (but nothing really does it).If instead I wait for about 2 seconds after the reset and then start to send packets, everything works correctly.I've checked insisde the reference manual and seeked in the forum but didn't find something similar... Does somebody know if there is any flag time to wait before start using the usart/dma after the core startup?Thanks and regardsMat