cancel
Showing results for 
Search instead for 
Did you mean: 

Failing to set up USART DMA TX

lauris
Associate II
Posted on May 22, 2015 at 15:33

Hello,

Can anyone help in pinpointing where and what I'm doing wrong when seting up USART DMA TX transmission. Working with STM32L152RB (STM32L discovery) and trying to setup USART1_TX overDMA1_Channel4,USART2_TX overDMA1_Channel7 andUSART3_TX overDMA1_Channel2 - acording to UM it should be like that. Below is how I'm setting it up (only USART1 others are same just peripherals and DMA channels differ and in init function I already wrote data which I'm passing, what I can see when debugging):

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
USART_Init(0x40013800, { 115200,
USART_WordLength_8b,
USART_StopBits_1,
USART_Parity_No,
(USART_Mode_Rx | USART_Mode_Tx),
USART_HardwareFlowControl_None});
USART_Cmd(0x40013800, ENABLE);
DMA_ITConfig(DMA1_Channel4, DMA_IT_TC, ENABLE);
NVIC_Init({ NVIC_IRQChannel = DMA1_Channel4_IRQn, 
NVIC_IRQChannelPreemptionPriority = 0x0F, 
NVIC_IRQChannelSubPriority = 0x0F, 
NVIC_IRQChannelCmd = ENABLE});
GPIO_Init(GPIOA, { GPIO_Pin = (uint16_t)(1 << 
GPIO_PinSource10
), 
GPIO_Mode
= 
GPIO_Mode_AF
, 
GPIO_Speed
= 
GPIO_Speed_40MHz
, 
GPIO_OType
= 
GPIO_OType_PP
, 
GPIO_PuPd
= 
GPIO_PuPd_NOPULL
});
GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_USART1);
GPIO_Init(GPIOA, { GPIO_Pin = (uint16_t)(1 << GPIO_PinSource9), 
GPIO_Mode
= 
GPIO_Mode_AF
, 
GPIO_Speed
= 
GPIO_Speed_40MHz
, 
GPIO_OType
= 
GPIO_OType_PP
, 
GPIO_PuPd
= 
GPIO_PuPd_NOPULL
});
GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_USART1);
<<buffer setup>>
DMA_DeInit(DMA1_Channel4);
DMA_Init(DMA1_Channel4, { DMA_PeripheralBaseAddr = 0x40013804, 
DMA_MemoryBaseAddr = 0x20001344, 
DMA_DIR = DMA_DIR_PeripheralDST, 
DMA_BufferSize = 12, 
DMA_PeripheralInc = DMA_PeripheralInc_Disable, 
DMA_MemoryInc = DMA_MemoryInc_Enable, 
DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte, 
DMA_MemoryDataSize = DMA_MemoryDataSize_Byte, 
DMA_Mode = DMA_Mode_Normal, 
DMA_Priority = DMA_Priority_Low, 
DMA_M2M = DMA_M2M_Disable});
USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE);
USART_ClearFlag(USART1, USART_FLAG_TC);
DMA_Cmd(DMA1_Channel4, ENABLE);

all initialization passes without errors, but I am not getting anything on uart lines andDMA1_Channel4_IRQn never fires.
2 REPLIES 2
Posted on May 22, 2015 at 18:36

Here's what I have, and works for me..

// STM32 USART2 DMA TX MULTI (Tx PA.2, Rx PA.3) STM32L152RE NUCLEO - sourcer32@gmail.com
#include ''stm32l1xx.h''
#include <
string.h
>
/**************************************************************************************/
void RCC_Configuration(void)
{
/* --------------------------- System Clocks Configuration -----------------*/
/* USART2 clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
/* GPIOA and DMA1 clock enable */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA | RCC_AHBPeriph_DMA1, ENABLE);
}
/**************************************************************************************/
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/*-------------------------- GPIO Configuration ----------------------------*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3; // PA.2 USART2_TX, PA.3 USART2_RX
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* Connect USART pins to AF */
GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_USART2);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_USART2);
}
/**************************************************************************************/
void USART2_Configuration(void)
{
USART_InitTypeDef USART_InitStructure;
/* USARTx configuration ------------------------------------------------------*/
/* USARTx configured as follow:
- BaudRate = 115200 baud
- Word Length = 8 Bits
- One Stop Bit
- No parity
- Hardware flow control disabled (RTS and CTS signals)
- Receive and transmit enabled
*/
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_Rx | USART_Mode_Tx;
USART_Init(USART2, &USART_InitStructure);
USART_Cmd(USART2, ENABLE);
/* Enable the USART Tx DMA request */
USART_DMACmd(USART2, USART_DMAReq_Tx, ENABLE);
}
/**************************************************************************************/
// Output as a series of different length strings in a loop
char StringA[] = ''The quick brown fox jumps over the lazy dog

'';
char StringB[] = ''Danger Zombies Ahead

'';
char StringC[] = ''Do not cross the streams

'';
int StringIndex = 0;
char *StringList[] = { StringA, StringB, StringC, NULL };
void DMA_Configuration(void)
{
DMA_InitTypeDef DMA_InitStructure;
char *Buffer;
// USART2_TX DMA2 Channel 7
if (StringList[StringIndex] == NULL)
StringIndex = 0;
Buffer = StringList[StringIndex++];
DMA_DeInit(DMA1_Channel7);
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART2->DR;
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)Buffer;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; // Transmit
DMA_InitStructure.DMA_BufferSize = (uint16_t)strlen(Buffer);
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_High;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel7, &DMA_InitStructure);
/* Enable DMA Channel Transfer Complete interrupt */
DMA_ITConfig(DMA1_Channel7, DMA_IT_TC, ENABLE);
/* Enable the DMA TX Channel */
DMA_Cmd(DMA1_Channel7, ENABLE);
}
/**************************************************************************************/
void DMA1_Channel7_IRQHandler(void) // USART2_TX
{
/* Test on DMA Stream Transfer Complete interrupt */
if (DMA_GetITStatus(DMA1_IT_TC7))
{
/* Clear DMA Stream Transfer Complete interrupt pending bit */
DMA_ClearITPendingBit(DMA1_IT_TC7);
DMA_Configuration(); // Light off next string
}
}
/**************************************************************************************/
void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
/* Configure the Priority Group to 2 bits */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
/* Enable the USART2 TX DMA Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel7_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
/**************************************************************************************/
int main(void)
{
RCC_Configuration();
NVIC_Configuration();
GPIO_Configuration();
USART2_Configuration();
DMA_Configuration();
while(1); // Don't want to exit
}
/**************************************************************************************/
#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file: pointer to the source file name
* @param line: assert_param error line source number
* @retval None
*/
void assert_failed(uint8_t* file, uint32_t line)
{
/* User can add his own implementation to report the file name and line number,
ex: printf(''Wrong parameters value: file %s on line %d

'', file, line) */
while (1)
{}
}
#endif
/**************************************************************************************/

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
lauris
Associate II
Posted on May 25, 2015 at 21:22

Hello,

well it worked on STM32L152VC, but not on STM32L152R8, will need to check if I can make it working on R8 too, in some way.