2012-06-16 06:32 AM
hi
everyoneneed help regarding UART with DMA mode,i am using STM32F407 Discovery Board,i want to configure UART4 with DMA, and want it to generate interrupt when DMA completes filling the memory. so should i configure the UART4's interrupt initializations also or only DMA interrupt initializations. I've attached my code. any help will be appreciated a lot. #selective-cut-n-paste #uart-usart-dma-interrupt2013-09-24 02:19 PM
3.5.0 is for the F1 series parts, this thread was about the F4 series parts, as were most of the other examples referred to. Which part are you using?
Here's an example blind ported to the VL-Discovery board which uses the STM32F100// STM32 USART1 DMA TX/RX (Tx PA.09, Rx PA.10) VLDiscovery - sourcer32@gmail.com
#include ''stm32F10x.h''
#include ''STM32vldiscovery.h''
/**************************************************************************************/
void RCC_Configuration(void)
{
/* Enable DMA clock */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
/* Enable GPIO clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
/* Enable UART clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
}
/**************************************************************************************/
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* Configure USART Tx as alternate function push-pull */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; // PA.09 USART1.TX
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* Configure USART Rx as input floating */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; // PA.10 USART1.RX
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
/**************************************************************************************/
void USART_Configuration(void)
{
USART_InitTypeDef USART_InitStructure;
/* USART resources configuration (Clock, GPIO pins and USART registers) ----*/
/* USART 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 configuration */
USART_Init(USART1, &USART_InitStructure);
/* Enable the USART1 */
USART_Cmd(USART1, ENABLE);
}
/**************************************************************************************/
volatile char Buffer[] = ''The quick brown fox jumps over the lazy dog
'';
void DMA_Configuration(void)
{
DMA_InitTypeDef DMA_InitStructure;
/* USART1_TX DMA1 Channel 4 (See RM0008) */
DMA_DeInit(DMA1_Channel4);
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART1->DR;
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)Buffer;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
DMA_InitStructure.DMA_BufferSize = sizeof(Buffer) - 1;
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_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_Low;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel4, &DMA_InitStructure);
USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE);
/* Enable DMA Stream Transfer Complete interrupt */
DMA_ITConfig(DMA1_Channel4, DMA_IT_TC, ENABLE);
/* USART1_RX DMA1 Channel 5 (See RM0008) */
DMA_DeInit(DMA1_Channel5);
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART1->DR;
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)Buffer;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_BufferSize = sizeof(Buffer) - 1;
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_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_Low;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel5, &DMA_InitStructure);
USART_DMACmd(USART1, USART_DMAReq_Rx, ENABLE);
/* Enable DMA Stream Transfer Complete interrupt */
DMA_ITConfig(DMA1_Channel5, DMA_IT_TC, ENABLE);
DMA_Cmd(DMA1_Channel4, ENABLE);
DMA_Cmd(DMA1_Channel5, ENABLE);
}
/**************************************************************************************/
void DMA1_Channel4_IRQHandler(void) // USART1_TX
{
/* Test on DMA Transfer Complete interrupt */
if (DMA_GetITStatus(DMA1_IT_TC4))
{
/* Clear DMA Transfer Complete interrupt pending bit */
DMA_ClearITPendingBit(DMA1_IT_TC4);
/* ... */
}
}
/**************************************************************************************/
void DMA1_Channel5_IRQHandler(void) // USART1_RX
{
/* Test on DMA Transfer Complete interrupt */
if (DMA_GetITStatus(DMA1_IT_TC5))
{
/* Clear DMA Transfer Complete interrupt pending bit */
DMA_ClearITPendingBit(DMA1_IT_TC5);
/* ... */
}
}
/**************************************************************************************/
void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
/* Configure the Priority Group to 2 bits */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
/* Enable the USART1 TX DMA Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel4_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/* Enable the USART1 RX DMA Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel5_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();
USART_Configuration();
DMA_Configuration();
while(1);
}
2015-11-17 02:28 AM
Hello,
I try to make stm32f4 discovery communicate with a raspberry pi using USART1 and DMA2. I want to have a rx ring buffer storing the incoming messages from the RPI. For this purpose i configure the DMA2 Streem5 and USART1 as shown in the code below. When i send a byte from the RPi to the discovery it is received in the USART1->DR but a get nothing in my receive buffer and also no interrupt. Thank you for your help! Stefanstatic void init_RPI_usart(void) {
USART_InitTypeDef USART_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
/* Peripheral Clock Enable -------------------------------------------------*/
//Enable GPIO clock
RPI_USART_GPIO_CLK_INIT(RPI_USART_TX_GPIO_CLK | RPI_USART_RX_GPIO_CLK,
ENABLE);
//Enable USART clock
RPI_USART_CLK_INIT(RPI_USART_CLK, ENABLE);
/* RPI_USART GPIO configuration -----------------------------------------------*/
/* Connect USART pins to AF7 */
GPIO_PinAFConfig(RPI_USART_TX_GPIO_PORT, RPI_USART_TX_SOURCE,
RPI_USART_TX_AF);
GPIO_PinAFConfig(RPI_USART_RX_GPIO_PORT, RPI_USART_RX_SOURCE,
RPI_USART_RX_AF);
/* Configure USART Tx and Rx as alternate function push-pull */
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Pin = RPI_USART_TX_PIN;
GPIO_Init(RPI_USART_TX_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = RPI_USART_RX_PIN;
GPIO_Init(RPI_USART_RX_GPIO_PORT, &GPIO_InitStructure);
/* RPI_USART configuration ----------------------------------------------------*/
/* Enable the USART OverSampling by 8 */
USART_OverSampling8Cmd(RPI_USART, ENABLE);
/* RPI_USART configured as follow:
- BaudRate = 5250000 baud
- Maximum BaudRate that can be achieved when using the Oversampling by 8
is: (USART APB Clock / 8)
Example:
- (USART3 APB1 Clock / 8) = (42 MHz / 8) = 5250000 baud
- (USART1 APB2 Clock / 8) = (84 MHz / 8) = 10500000 baud
- Maximum BaudRate that can be achieved when using the Oversampling by 16
is: (USART APB Clock / 16)
Example: (USART3 APB1 Clock / 16) = (42 MHz / 16) = 2625000 baud
Example: (USART1 APB2 Clock / 16) = (84 MHz / 16) = 5250000 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;
/* When using Parity the word length must be configured to 9 bits */
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(RPI_USART, &USART_InitStructure);
/* Enable USART */
USART_Cmd(RPI_USART, ENABLE);
}
/**
*
*/
static void init_RPI_dma(void) {
DMA_InitTypeDef DMA_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
//Enable the DMA clock
RPI_DMA_CLK_INIT(RPI_USART_DMA_CLK, ENABLE);
/* Configure DMA controller to manage USART TX and RX DMA request ----------*/
DMA_InitStructure.DMA_Channel = RPI_USART_RX_DMA_CHANNEL;
DMA_InitStructure.DMA_PeripheralBaseAddr = RPI_USART_DR_ADDRESS;
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_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_InitStructure.DMA_BufferSize = (uint16_t) TX_RX_QUEUE_SIZE;
//TX configuration
// DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;
// DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t) tx_queue.buff;
//
// DMA_Init(RPI_USART_TX_DMA_STREAM, &DMA_InitStructure);
//RX configuration
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t) &rx_queue.buff[0];
DMA_Init(RPI_USART_RX_DMA_STREAM, &DMA_InitStructure);
//interrupt configuration-------------------------------------------------------------
NVIC_InitStructure.NVIC_IRQChannel = RPI_USART_DMA_TX_IRQn
| RPI_USART_DMA_RX_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
// /* Enable the USART DMA requests */
// USART_DMACmd(RPI_USART, USART_DMAReq_Tx, ENABLE);
//
// /* Clear the TC bit in the SR register by writing 0 to it */
// USART_ClearFlag(RPI_USART, USART_FLAG_TC);
//
// /* Enable the DMA TX Stream, USART will start sending */
// DMA_Cmd(USARTx_TX_DMA_STREAM, ENABLE);
/* Enable the USART Rx DMA request */
USART_DMACmd(RPI_USART, USART_DMAReq_Rx, ENABLE);
/* Enable DMA Stream Transfer Complete interrupt */
DMA_ITConfig(RPI_USART_RX_DMA_STREAM, DMA_IT_TC | DMA_IT_HT | DMA_IT_TE | DMA_IT_DME | DMA_IT_FE, ENABLE);
/* Enable the DMA RX Stream */
DMA_Cmd(RPI_USART_RX_DMA_STREAM, ENABLE);
}
//defines------------------------------------------------------------------------------
/* Definition for RPI_USART resources ********************************************/
#define RPI_USART USART1
#define RPI_USART_CLK RCC_APB2Periph_USART1
#define RPI_USART_CLK_INIT RCC_APB2PeriphClockCmd
#define RPI_USART_IRQHandler USART1_IRQHandler
#define RPI_USART_GPIO_CLK_INIT RCC_AHB1PeriphClockCmd
#define RPI_USART_TX_PIN GPIO_Pin_6
#define RPI_USART_TX_GPIO_PORT GPIOB
#define RPI_USART_TX_GPIO_CLK RCC_AHB1Periph_GPIOB
#define RPI_USART_TX_SOURCE GPIO_PinSource6
#define RPI_USART_TX_AF GPIO_AF_USART1
#define RPI_USART_RX_PIN GPIO_Pin_7
#define RPI_USART_RX_GPIO_PORT GPIOB
#define RPI_USART_RX_GPIO_CLK RCC_AHB1Periph_GPIOB
#define RPI_USART_RX_SOURCE GPIO_PinSource7
#define RPI_USART_RX_AF GPIO_AF_USART1
/* Definition for DMAx resources **********************************************/
#define RPI_USART_DR_ADDRESS ((uint32_t) &RPI_USART->DR)
#define RPI_USART_DMA DMA2
#define RPI_USART_DMA_CLK RCC_AHB1Periph_DMA2
#define RPI_DMA_CLK_INIT RCC_AHB1PeriphClockCmd
#define RPI_USART_TX_DMA_CHANNEL DMA_Channel_4
#define RPI_USART_TX_DMA_STREAM DMA2_Stream7
#define RPI_USART_TX_DMA_FLAG_FEIF DMA_FLAG_FEIF7
#define RPI_USART_TX_DMA_FLAG_DMEIF DMA_FLAG_DMEIF7
#define RPI_USART_TX_DMA_FLAG_TEIF DMA_FLAG_TEIF7
#define RPI_USART_TX_DMA_FLAG_HTIF DMA_FLAG_HTIF7
#define RPI_USART_TX_DMA_FLAG_TCIF DMA_FLAG_TCIF7
#define RPI_USART_RX_DMA_CHANNEL DMA_Channel_4
#define RPI_USART_RX_DMA_STREAM DMA2_Stream5
#define RPI_USART_RX_DMA_FLAG_FEIF DMA_FLAG_FEIF5
#define RPI_USART_RX_DMA_FLAG_DMEIF DMA_FLAG_DMEIF5
#define RPI_USART_RX_DMA_FLAG_TEIF DMA_FLAG_TEIF5
#define RPI_USART_RX_DMA_FLAG_HTIF DMA_FLAG_HTIF5
#define RPI_USART_RX_DMA_FLAG_TCIF DMA_FLAG_TCIF5
#define RPI_USART_DMA_TX_IRQn DMA2_Stream7_IRQn
#define RPI_USART_DMA_RX_IRQn DMA2_Stream5_IRQn
#define RPI_USART_DMA_TX_IRQHandler DMA2_Stream7_IRQHandler
#define RPI_USART_DMA_RX_IRQHandler DMA2_Stream5_IRQHandler
#define TX_RX_QUEUE_SIZE 5
//typedefs-----------------------------------------------------------------------------
typedef struct {
uint8_t buff[TX_RX_QUEUE_SIZE];
uint16_t ri;
uint16_t wi;
} queue_t;
2015-11-17 05:14 AM
You can't OR indexes together like this
NVIC_InitStructure.NVIC_IRQChannel = RPI_USART_DMA_TX_IRQn
| RPI_USART_DMA_RX_IRQn;
2015-11-17 05:31 AM
unfortunately still same behavior after removing
RPI_USART_DMA_TX_IRQn
2015-11-17 10:13 AM
Ok, but I can only skim over the code, I'm not writing a framework to test this. You'll need to provide a concise stand-alone example.
Perhaps you should watch the order you run these functions, or move the clock initialization up one level, so all of the them are running.2015-11-19 07:24 AM
2015-12-03 11:17 PM
Hi Clive,
I used your code and gave the buffer size to 10, but when I'm trnasferring 10 I'm not getting Transfer Complete every time. Is it because of the DMA_SxNDTR = Multiple of ((Mburst beat) × (Msize)/(Psize)) inconsistency When I checked MBURST, MSIZE, and PSIZE all are configured for byte, so it should give me DMA_TC on reception of every 10 byte . What am I missing?2015-12-27 05:11 AM
Is there any example how to implement UART transmit trough circular DMA with use of MxCube?
2016-06-19 07:20 AM
Hi everyone,
I try to communication with peripherals by USARTx with Keilc 5.13v and stm32f4 discovery. But I can't handle USARTx interrupt through HAL libraries. I don't know what happen? Therefore who can show me how to use HAL libraries to configurate for STM32f4 Discovery kit to get data from PC. Thanks!2016-06-19 10:18 AM
I'm not sure where the HAL/Cube protagonists go when people need their help..