cancel
Showing results for 
Search instead for 
Did you mean: 

UART receive DMA with ISR

anil23
Associate II
Posted on September 28, 2007 at 11:05

UART receive DMA with ISR

15 REPLIES 15
anil23
Associate II
Posted on May 17, 2011 at 09:34

Hello:

I’m having problems using the UART DMA in the interrupt mode. I’m avoiding the process of reading the UART byte in the RX channel as they arrive. Instead, the DMA has been set to trigger after 16 bytes so that the interrupt for every byte wouldn’t delay the processor.

I would like to know if there is a way to fire an interrupt on every DMA FIFO full. Please find the code attached and let me know of what I’m doing wrong. Also, I would like to know if there is a interrupt driven UART DMA example available.

Regards,

PS: the following code works...But I want it to be intterupt driven...

UART_InitStructure.UART_WordLength = UART_WordLength_8D;

UART_InitStructure.UART_StopBits = UART_StopBits_1;

UART_InitStructure.UART_Parity = UART_Parity_No ;

UART_InitStructure.UART_BaudRate = 19200;

UART_InitStructure.UART_HardwareFlowControl = UART_HardwareFlowControl_None;

UART_InitStructure.UART_Mode = UART_Mode_Tx_Rx;

UART_InitStructure.UART_FIFO = UART_FIFO_Disable;

UART_InitStructure.UART_TxFIFOLevel = UART_FIFOLevel_7_8; /* FIFO size 16 bytes, FIFO level 8 bytes */

UART_InitStructure.UART_RxFIFOLevel = UART_FIFOLevel_7_8; /* FIFO size 16 bytes, FIFO level 8 bytes */

UART_DeInit(UART1);

UART_Init(UART1, &UART_InitStructure);

/* Enable the UART1 */

UART_Cmd(UART1, ENABLE);

UART_LoopBackConfig(UART1, DISABLE);

UART_DMACmd(UART1, UART_DMAReq_Rx, ENABLE);

for(i=0;i

DesPtr = &(RxDMABuffer[0]);

DMA_DeInit();

DMA_Cmd(ENABLE);

DMA_SyncConfig(DMA_UART1_RX_Mask, ENABLE);

DMA_StructInit(&DMA_InitStruct);

DMA_InitStruct.DMA_Channel_LLstItm=5;

DMA_InitStruct.DMA_Channel_SrcAdd=(u32)(&(UART1->DR));

DMA_InitStruct.DMA_Channel_DesAdd=(u32)(DesPtr);

DMA_InitStruct.DMA_Channel_SrcWidth= DMA_SrcWidth_Byte;

DMA_InitStruct.DMA_Channel_DesWidth= DMA_DesWidth_Byte;

DMA_InitStruct.DMA_Channel_FlowCntrl= DMA_FlowCntrl_Perip2 ;

DMA_InitStruct.DMA_Channel_Src = DMA_SRC_UART1_RX;

DMA_InitStruct.DMA_Channel_TrsfSize = 16;

DMA_ChannelSRCIncConfig (DMA_Channel5, DISABLE);

DMA_ChannelDESIncConfig (DMA_Channel5, ENABLE);

DMA_ChannelBuffering(DMA_Channel5, ENABLE);

DMA_Init(DMA_Channel5,&DMA_InitStruct);

DMA_ChannelCmd (DMA_Channel5,ENABLE);

while (1){

while(DMA_GetChannelActiveStatus(DMA_Channel5)==RESET);

currentPack = ((DMA_Channel5->DES) - (u32)DesPtr)/16;

test = 1;

DMA_ChannelCmd (DMA_Channel5,DISABLE);//Enable the DMA channel

for(i=0;i

RxDMABuffer[i] = 0;

}

DMA_Channel5->DES = (u32)(&(RxDMABuffer[0]));

DMA_ChannelCmd (DMA_Channel5,ENABLE);//Enable the DMA channel

}

amira1
Associate II
Posted on May 17, 2011 at 09:34

Hi iamanil,

I've faced the same problem with UART_DMA_interrupt and after consulting st team I've learned that UART_DMA interface is not applied to support UART_IT_Receive and UART_DMAReq_Rx at the same time.

Best regards

mirou

anil23
Associate II
Posted on May 17, 2011 at 09:34

Hi mirou

Thank you for your comments on my DMA issue. If we can’t use the DMA for the UART receive, I would like to know if there is anyway to use the FIFO in the UART in the Rx mode.

I'm trying to avoid interrupts every time a byte is received....Any ideas???

Regards,

amira1
Associate II
Posted on May 17, 2011 at 09:34

Hi iamanil,

please find attached an example of UART_DMA using Rx mode with FIFO enabled which works well for me.

Best regads

mirou

[ This message was edited by: mirou on 11-12-2006 16:53 ]

anil23
Associate II
Posted on May 17, 2011 at 09:34

Thanks Mirou,

I will update you with my observations.

Regards,

[ This message was edited by: iamanil on 11-12-2006 17:52 ]

anil23
Associate II
Posted on May 17, 2011 at 09:34

Hello Mirou,

I took your reference project and created this project with DMA interrupt. I followed the terminal count interrupt description in the manual. The interrupt is being generated for the first packet received(16 bytes of information) on the UART-that’s good news. The bad news is that the interrupt is never fired after the first packet.

Any help in this regard would be appreciated.

Regards,

Posted on May 17, 2011 at 09:34

hi iamanil,

I think that when you reinitialize the DMA channel

you have to set the IRQ trigger writing 0x80000000

in the DMA_CCx register

anil23
Associate II
Posted on May 17, 2011 at 09:34

Hi Stevejamal,

I realized the transfer size is being reset after the interrupt is triggered. So, I re-enabled it in the ISR and it works now (DMA_Channelx->CC |= 0x80000010 for 16 bytes). Thanks for your support.

Regards,

nanuradha
Associate II
Posted on May 17, 2011 at 09:34

Hi Mirou,

i have modified my code according to u'r sugession. but no luck.

i got some junk values on hyper terminal.

is there any settings required for Hyperterminal?

have a glance of my code.

/******************** (C) COPYRIGHT 2006 STMicroelectronics ********************

* File Name : main.c

* Author : MCD Application Team

* Date First Issued : 05/18/2006 : Version 1.0

* Description : Main program body

********************************************************************************

* History:

* 05/24/2006 : Version 1.1

* 05/18/2006 : Version 1.0

********************************************************************************

* THE PRESENT SOFTWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS

* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.

* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,

* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE

* CONTENT OF SUCH SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING

* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.

*******************************************************************************/

/* Includes ---------------*/

#include ''91x_lib.h''

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

/* Private define ---------*/

#define TxBufferSize (countof(TxBuffer) - 1)

#define RxBufferSize 0xFF

/* Private macro ----------*/

#define countof(a) (sizeof(a) / sizeof(*(a)))

/* Private variables ------*/

UART_InitTypeDef UART_InitStructure;

u8 TxBuffer[] = ''UART Example: UART - Hyperterminal\n\r'';

u8 RxBuffer[RxBufferSize];

u8 NbrOfDataToTransfer = TxBufferSize;

u8 TxCounter = 0;

u8 RxCounter = 0;

// ****************************************************************

// Phase Lock Loop (PLL) setting

// ****************************************************************

#define PLL_M 25 // M (1 <= M <= 255) value for phase lock loop

#define PLL_N 192 // N (1 <= N <= 255) value for phase lock loop

#define PLL_P 3 // P (1 <= P <= 5) value for phase lock loop

// ****************************************************************

// clocks divisor setting

// ****************************************************************

#define RCLK_Divisor SCU_RCLK_Div1 // Reference clock divisor

#define HCLK_Divisor SCU_HCLK_Div1 // ARM high speed bus divisor

#define PCLK_Divisor SCU_PCLK_Div2 // ARM Peripheral bus divisor

#define FMICLK_Divisor SCU_FMICLK_Div1 // FMI divisor

/* Private function prototypes -------------*/

void SCU_Configuration(void);

void GPIO_Configuration(void);

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

/*******************************************************************************

* Function Name : main

* Description : Main program

* Input : None

* Output : None

* Return : None

*******************************************************************************/

int main()

{

u8 i;

#ifdef DEBUG

debug();

#endif

SCU_PLLFactorsConfig(192, 25, 3);

SCU_PLLCmd(ENABLE);

SCU_RCLKDivisorConfig(SCU_RCLK_Div1);

SCU_HCLKDivisorConfig(SCU_HCLK_Div1);

SCU_PCLKDivisorConfig(SCU_PCLK_Div2);

SCU_FMICLKDivisorConfig(SCU_FMICLK_Div1);

SCU_MCLKSourceConfig(SCU_MCLK_PLL);

/* Configure the system clocks */

SCU_Configuration();

/* Configure the GPIO ports */

GPIO_Configuration();

UART_InitStructure.UART_WordLength = UART_WordLength_8D;

UART_InitStructure.UART_StopBits = UART_StopBits_1;

UART_InitStructure.UART_Parity = UART_Parity_No ;

UART_InitStructure.UART_BaudRate = 115200;

UART_InitStructure.UART_HardwareFlowControl = UART_HardwareFlowControl_None;

UART_InitStructure.UART_Mode = UART_Mode_Tx;//_Rx;

UART_InitStructure.UART_FIFO = UART_FIFO_Enable;

UART_InitStructure.UART_TxFIFOLevel = UART_FIFOLevel_1_2; /* FIFO size 16 bytes, FIFO level 8 bytes */

UART_InitStructure.UART_RxFIFOLevel = UART_FIFOLevel_1_2; /* FIFO size 16 bytes, FIFO level 8 bytes */

UART_DeInit(UART1);

UART_Init(UART1, &UART_InitStructure);

/* Enable the UART1 */

UART_Cmd(UART1, ENABLE);

UART_LoopBackConfig(UART1, DISABLE);

TxCounter = 0;

UART_SendData(UART1, 0x00);

//while(1){

while(NbrOfDataToTransfer--)

{

UART_SendData(UART1, TxBuffer[TxCounter++]);

while(UART_GetFlagStatus(UART1, UART_FLAG_TxFIFOFull) != RESET);

}

for(i=0;i

NbrOfDataToTransfer = TxBufferSize;

TxCounter = 0;

//}

//do

//{

//if((UART_GetFlagStatus(UART1, UART_FLAG_RxFIFOEmpty) != SET)&&(RxCounter < RxBufferSize))

//{

//RxBuffer[RxCounter] = UART1->DR;

//UART_SendData(UART1, RxBuffer[RxCounter++]);

//}

//

//}while((RxBuffer[RxCounter - 1] != '\r')&&(RxCounter != RxBufferSize));

while (1);

}

/*******************************************************************************

* Function Name : SCU_Configuration

* Description : Configures the system clocks.

* Input : None

* Output : None

* Return : None

*******************************************************************************/

void SCU_Configuration(void)

{

/* Enable the UART1 Clock */

SCU_APBPeriphClockConfig(__UART1, ENABLE);

SCU_APBPeriphClockConfig(__GPIO3, ENABLE);

}

/*******************************************************************************

* Function Name : GPIO_Configuration

* Description : Configures the different GPIO ports.

* Input : None

* Output : None

* Return : None

*******************************************************************************/

void GPIO_Configuration(void)

{

GPIO_InitTypeDef GPIO_InitStructure;

//GPIO_DeInit(GPIO3);

///*Gonfigure UART1_Rx pin GPIO3.2*/

//GPIO_InitStructure.GPIO_Direction = GPIO_PinInput;

//GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;

//GPIO_InitStructure.GPIO_Type = GPIO_Type_PushPull ;

//GPIO_InitStructure.GPIO_IPConnected = GPIO_IPConnected_Enable;

//GPIO_InitStructure.GPIO_Alternate = GPIO_InputAlt1 ;

//GPIO_Init (GPIO3, &GPIO_InitStructure);

GPIO_DeInit(GPIO3);

/*Gonfigure UART1_Tx pin GPIO3.3*/

GPIO_InitStructure.GPIO_Direction = GPIO_PinOutput;

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;

GPIO_InitStructure.GPIO_Type = GPIO_Type_PushPull ;

GPIO_InitStructure.GPIO_IPConnected = GPIO_IPConnected_Enable;

GPIO_InitStructure.GPIO_Alternate = GPIO_OutputAlt2 ;

GPIO_Init (GPIO3, &GPIO_InitStructure);

}

/******************* (C) COPYRIGHT 2006 STMicroelectronics *****END OF FILE****/

thanks

raj.