AnsweredAssumed Answered

STM32 USART2 per DMA Problem

Question asked by duris.robin.002 on Aug 30, 2012
Latest reply on Dec 22, 2013 by Clive One

I have a problem that maybe someone can help with. I've spend the last few days on this and I just don't understand why it's not working.

I have a STM32 where I want to send out a buffer over USART 2 using DMA to a RS485 chip that sends it to a Hyperterminal via FTDI cable. I had this working using USART without DMA... by just feeding the Register with the buffer one by one. So I know that the USART and the RS485 chip works. 

After inital problems i have gone to a simple example from ST Library and modified it but still can't get it to work. Here is my code.. I'm trying to continuosly send out data over USART2. 

The problem: It doesn't send at all... or only once.. and usually gets stuck here:
while (DMA_GetFlagStatus(DMA1_FLAG_TC7) == RESET)

Can anyone see what I'm doing wrong?

 

 

 

 

/* Includes ------------------------------------------------------------------*/
#include "stm32f10x.h"

/* Private typedef -----------------------------------------------------------*/

/* Private define ------------------------------------------------------------*/
#define TxBufferSize2   (countof(TxBuffer2) - 1)

/* Private macro -------------------------------------------------------------*/
#define countof(a)   (sizeof(a) / sizeof(*(a)))

/* Private variables ---------------------------------------------------------*/
USART_InitTypeDef USART_InitStructure;
uint8_t TxBuffer2[] = "USART DMA Test Buffer\n";
uint8_t RxBuffer1[TxBufferSize2];

/* Private function prototypes -----------------------------------------------*/
void RCC_Configuration(void);
void GPIO_Configuration(void);
void NVIC_Configuration(void);
void DMA_Configuration(void);

/* Private functions ---------------------------------------------------------*/

int main(void)
{
  /* System Clocks Configuration */
  RCC_Configuration();
      
  /* NVIC configuration */
  NVIC_Configuration();

  /* Configure the GPIO ports */
  GPIO_Configuration();

  /* Configure the DMA */
  DMA_Configuration();

 /* USART2 Initialization  */
  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_HardwareFlowControl = USART_HardwareFlowControl_None;
  USART_InitStructure.USART_Mode =  USART_Mode_Tx;
 
 /* Configure USART2 */
  USART_Init( USART2, &USART_InitStructure);

 /* Disable the DMA Interrupts
   I do want to use the interrupts later 
     (that's the whole point) but I want
   to get it working without them first. */
  DMA_ITConfig( DMA1_Channel7, DMA_IT_TC|DMA_IT_HT|DMA_IT_TE, DISABLE) ;

  /* Enable USARTy DMA TX request */
  USART_DMACmd(USART2, USART_DMAReq_Tx, ENABLE);
 
  /* Enable USART2 */
  USART_Cmd(USART2, ENABLE);

  while(1)
 {
  
  /* Do I need to clear these flags before sending? */
  DMA_ClearFlag(DMA1_FLAG_TC7);
  DMA_ClearFlag(DMA1_FLAG_HT7);
  DMA_ClearFlag(DMA1_FLAG_TE7);
  DMA_ClearITPendingBit( DMA1_IT_TC7);
  DMA_ClearITPendingBit( DMA1_IT_TE7);
  DMA_ClearITPendingBit( DMA1_IT_HT7);
  
  /* Enable USARTy DMA TX Channel
    Transmit should now start and usually 
    sends one time.   */
   DMA_Cmd(DMA1_Channel7, ENABLE);

   /* Wait until USARTy TX DMA1 Channel  Transfer Complete
     It gets stuck here. Why is the flag not set? */
   while (DMA_GetFlagStatus(DMA1_FLAG_TC7) == RESET)
   {
   }
 
  DMA_Cmd(DMA1_Channel7, DISABLE); //Do i need to this?
 }

}

 

void RCC_Configuration(void)
{   
  /* DMA clock enable */
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

  /* Enable GPIO clock */
  RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);

  /* Enable USART2 Clock */
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); 
}

 

void GPIO_Configuration(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;

  /* Enable the USART2 Pins Software Remapping */
  //GPIO_PinRemapConfig(GPIO_Remap_USART2, ENABLE); 
 
  /* Configure USART2 Tx as alternate function push-pull */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  /* UART  Direction */
  GPIO_InitStructure.GPIO_Pin     = GPIO_Pin_1;
  GPIO_InitStructure.GPIO_Speed   = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode    = GPIO_Mode_Out_PP;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
 
 GPIOA->BSRR = GPIO_Pin_1; //Set Pin High..TX
}

 

void NVIC_Configuration(void)
{
   NVIC_InitTypeDef NVIC_InitStructure;

  /* Enable the USARTz Interrupt */
  NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
}

 

void DMA_Configuration(void)
{
  DMA_InitTypeDef DMA_InitStructure;

 /* USARTy_Tx_DMA_Channel (triggered by USARTy Tx event) Config */
  DMA_DeInit(DMA1_Channel7);
  DMA_InitStructure.DMA_PeripheralBaseAddr = 0x40004404;
  DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)TxBuffer2;
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
  DMA_InitStructure.DMA_BufferSize = TxBufferSize2;
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
  DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
  DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
  DMA_Init(DMA1_Channel7, &DMA_InitStructure);
 

}

 




Outcomes