AnsweredAssumed Answered

USART1 Rx DMA

Question asked by bjorke.jake on May 5, 2014
Latest reply on May 6, 2014 by Clive One
Hello All,


I have not been able to get the USART1 DMA Rx TC interrupt to be raised.  In the code below the TX TC interrupt fires without a problem however @ no point does DMA2_Stream5_IRQHandler get raised.  Also Is there a routine that would allow for a level of abstraction as far as waiting for TC bit to clear in the TX ISR?


Thanks for any help,
Jake


int waitForTransmission = 0;


int main()
{
     NvicConfig();
     UartInit();


     //Enable DMA2 clock
     RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);


     //Send Data
     ConfigTxDma()


     while(waitForTransmission == 0){}
     
     //wait for data to come in...
     while(1){}


}


//This never fires....
//Rx interrupt--transmission complete (from UART to memory via DMA)
void DMA2_Stream5_IRQHandler()
{
     rxCounter++;
     
     //Clear the interrupt
     DMA_ClearITPendingBit(DMA2_Stream5, DMA_FLAG_TCIF5);
     
     //Indicate to the Anybus that data is ready.....
     DataReadyFlag = 1;
}


//Tx interrupt--transmission complete
void DMA2_Stream7_IRQHandler()
{
     waitForTransmission = 1;
     
     //Clear the interrupt
     DMA_ClearITPendingBit(DMA2_Stream7, DMA_FLAG_TCIF7);
     
     //Wait for the data to complete sending...
     while( (USART1->SR & USART_FLAG_TC ) == 0  )
     {
          //Loop
     }
     
     //Enable the RX DMA Transfer..
     ConfigRxDma(localAnybusPtr);
}


void ConfigRxDma( )
{
     DMA_InitTypeDef initStruct;
     
     //Set up the RX DMA
     DMA_DeInit(DMA2_Stream5);
     
     //Disable the stream.
     DMA_Cmd(DMA2_Stream5, DISABLE);
     
     //Wait for the stream to actually disbale
     while( DMA_GetCmdStatus(DMA2_Stream5) != DISABLE )
     {
          //loop
     }
     
     //Set the channel
     initStruct.DMA_Channel = DMA_Channel_4;
     
     //Set the direction
     initStruct.DMA_DIR = DMA_DIR_PeripheralToMemory;
     
     //set the address of the first element of the rx buffer as the memory address
     initStruct.DMA_Memory0BaseAddr = (uint32_t)&rxBuffer[0];
     
     //Set the dma buffer size....this may have to be changed when we exit setup mode
     //  on the anybus module.
     initStruct.DMA_BufferSize = (uint32_t)rxBufferSize;
     
     //set the peripheral base address
     initStruct.DMA_PeripheralBaseAddr = (uint32_t)(&(USART1->DR));
     
     //Disable incrementing the peripheral address
     initStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
     
     //Set the DMA so that the memory address inscrements.
     initStruct.DMA_MemoryInc = DMA_MemoryInc_Enable;
     
     //Set the peripheral/memory data size to a byte.
     initStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
     initStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
     
     //Use the circular buffer mode as we keep reloading the tx buffer.
     initStruct.DMA_Mode = DMA_Mode_Normal;//is this right??
     
     //Set High priority
     initStruct.DMA_Priority = DMA_Priority_High;
     
     //Enable the FIFO/Set the max threshold.
     initStruct.DMA_FIFOMode = DMA_FIFOMode_Disable;//DMA_FIFOMode_Enable;
     initStruct.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;//Should this be 1/4 full like example?
     
     //Set single burst transmission
     initStruct.DMA_MemoryBurst = DMA_MemoryBurst_Single;
     initStruct.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
     
     DMA_Init(DMA2_Stream5, &initStruct);
     
     //Enable the USART Rx DMA request.
     USART_DMACmd(USART1, USART_DMAReq_Rx, ENABLE);
     
     //Enable the DMA stream transfer complete interrupt
     DMA_ITConfig(DMA2_Stream5,DMA_IT_TC, ENABLE);
     
     //Enable the DMA RX Stream
     DMA_Cmd(DMA2_Stream5, ENABLE);
     
     //Make sure that the stream enables.
     while( DMA_GetCmdStatus(DMA2_Stream5) != ENABLE )
     {
          
     }
}


void ConfigTxDma( )
{
     DMA_InitTypeDef initStruct;
     
     //Set up the TX DMA
     DMA_DeInit(DMA2_Stream7);
     
     //Wait for the stream to actually disbale
     while( DMA_GetCmdStatus(DMA2_Stream7) != DISABLE )
     {
          //loop
     }
     
     //Set the channel
     initStruct.DMA_Channel = DMA_Channel_4;
     
     //Set the direction.
     initStruct.DMA_DIR = DMA_DIR_MemoryToPeripheral;
     
     initStruct.DMA_Memory0BaseAddr =  &txBuffer[0];
          
     //Set the size of the dma buffer--this may cause an issue as this changes and
     //  is not set up as a volatile value.
     initStruct.DMA_BufferSize = txBufferSize;
     
     
     //Set the USART1 Data register as the the peripheral base address (point where data is written)
     initStruct.DMA_PeripheralBaseAddr = (uint32_t)(&(USART1->DR));
     
     //Disable incrementing the peripheral address
     initStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
     
     //Set the DMA so that the memory address inscrements.
     initStruct.DMA_MemoryInc = DMA_MemoryInc_Enable;
     
     //Set the peripheral/memory data size to a byte.
     initStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
     initStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
     
     //Use the circular buffer mode as we keep reloading the tx buffer.
     initStruct.DMA_Mode = DMA_Mode_Normal;
     
     //Set High priority
     initStruct.DMA_Priority = DMA_Priority_High;
     
     //Enable the FIFO/Set the max threshold.
     initStruct.DMA_FIFOMode = DMA_FIFOMode_Disable;//DMA_FIFOMode_Enable;
     initStruct.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;//Should this be 1/4 full like example?
     
     //Set single burst transmission
     initStruct.DMA_MemoryBurst = DMA_MemoryBurst_Single;
     initStruct.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
     
     //Actually set up the DMA Registers.
     DMA_Init( DMA2_Stream7, &initStruct );
     
     //Enable the USART tx DMA request.
     USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE);//This actually sends the data..
     
     //Enable the DMA stream transfer complete interrupt
     DMA_ITConfig(DMA2_Stream7,DMA_IT_TC, ENABLE);
     
     //Enable the DMA TX Stream
     DMA_Cmd(DMA2_Stream7, ENABLE);
     
     //Make sure that the stream enables.
     while( DMA_GetCmdStatus(DMA2_Stream7) != ENABLE )
     {
          
     }
}
void UartInit()
{
     //Enable periph clocks for port a and UART1
     RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
     
     RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
     
     /*
          We are going to have to init the GPIO which
          will be used for the UART port.
     */
     ConfigUartGpio();
     
     /*
          Configure the actual port
     */
     ConfigPort();
}//Uart init


void ConfigUartGpio()
{
     GPIO_InitTypeDef initStruct;
     
     //set up the GPIO pins
     initStruct.GPIO_Pin = GPIO_Pin_9;// | GPIO_Pin_10;//PA 9 and PA 10 are used for USART-1
     
     //Set the GPIO mode to be used
     initStruct.GPIO_Mode = GPIO_Mode_AF;//Set to "Alternate Function"
     
     //Set the GPIO Output Type
     initStruct.GPIO_OType = GPIO_OType_PP;//Set to "Push/Pull (open drain)"
     
     //Set the pull-up/pull-down resistors
     initStruct.GPIO_PuPd = GPIO_PuPd_UP;//Enable pull up resistors.
     
     //Set the GPIO speed
     initStruct.GPIO_Speed = GPIO_Speed_100MHz;
     
     //Call the routine to actually init the GPIO functionality
     //init pin 9
     GPIO_Init(GPIOA, &initStruct);
     
     //set up the GPIO pins (pin 10)
     initStruct.GPIO_Pin = GPIO_Pin_10;
     GPIO_Init(GPIOA, &initStruct);
     
     //Connect USART pins to the Alternate function of the GPIO
     GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_USART1);
     GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_USART1);
     
}//Config Uart Gpio


void ConfigPort()
{
     USART_InitTypeDef initStruct;
     
     /*
          In order to test the Anybus CompactCom
          we will set up this device with the below
          parameters
          
          --8 Data Bits
          --No pairity
          --1 stop bit
          --115200 baud     
          --No flow control
          --Rx and Tx mode enabled.
     */
     initStruct.USART_WordLength = USART_WordLength_8b;
     initStruct.USART_Parity = USART_Parity_No;
     initStruct.USART_StopBits = USART_StopBits_1;
     initStruct.USART_BaudRate = 115200;
     initStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
     initStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
     
     //Initialize the hardware
     USART_Init(USART1, &initStruct);
     //Enable the hardware
     USART_Cmd(USART1,ENABLE);
}


void NvicConfig()
{
     NVIC_InitTypeDef initStruct;
     
     //Set the priority group to 2 bits
     NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
     
     //Tx DMA intertupt
     initStruct.NVIC_IRQChannel = DMA2_Stream7_IRQn;
     initStruct.NVIC_IRQChannelPreemptionPriority = 0;
     initStruct.NVIC_IRQChannelSubPriority = 0;
     initStruct.NVIC_IRQChannelCmd = ENABLE;
     NVIC_Init(&initStruct);     
     
     //Rx DMA interrupt
     initStruct.NVIC_IRQChannel = DMA2_Stream5_IRQn;
     initStruct.NVIC_IRQChannelPreemptionPriority = 0;
     NVIC_Init(&initStruct);     
}

Outcomes