lpcware

why UART received data is not correct through GPDMA  mode in FREERTOS?

Discussion created by lpcware Employee on Jun 15, 2016
Latest reply on Jun 15, 2016 by lpcware
Content originally posted in LPCWare by hilbertdavid on Sat Jan 03 05:57:13 MST 2015
my os is freertos 8.1.2.  i want to receive serial data through uart2 in dma mode,its priority is 16, and there is also an lwip task which prio is 9, and the lwip work correctly,while the uart2 received data is not correct, can anybody help me?
the schematic is listed here,the peri include a 7"lcd and 32M SDRAM.
the dma interrupt can intriggered normally,it's listed here:

#include "dma.h"
#include <LPC177x_8x.H>
#include <FREERTOS.h>
#include <lpc177x_8x_gpio.h>
#include "lpc177x_8x_pinsel.h"
#include "lpc177x_8x_uart.h"
#include "lpc177x_8x_gpdma.h"
#include "bsp.h"
#include <stdio.h>
#include "string.h"
#include "lpc177x_8x_clkpwr.h"
#include "lpc_debug.h"
#include "BUTTON.h"
#include "task.h"
extern __IO uint8_t rx_buff[256];
extern xSemaphoreHandle disp_sem,d2r_sem,rx485_sem;
uint32_t tmp = 0;
void DMA_IRQHandler (void)
{
//  portENTER_CRITICAL();

  static portBASE_TYPE xHigherPriorityTaskWoken;
  xHigherPriorityTaskWoken = pdFALSE;
    /* Scan interrupt pending */
  for (tmp = 0; tmp < 3; tmp++)
  {
    if (GPDMA_IntGetStatus(GPDMA_STAT_INT, tmp))
    {
      /* Check counter terminal status */
      if (GPDMA_IntGetStatus(GPDMA_STAT_INTTC, tmp))
      {
        /* Clear terminate counter Interrupt pending */
        GPDMA_ClearIntPending (GPDMA_STATCLR_INTTC, tmp);

        switch (tmp)
        {
          case 0:
            GPDMA_ChannelCmd(0, DISABLE);           
            break;
           
          case 1:
            GPDMA_ChannelCmd(1, DISABLE);
            xSemaphoreGiveFromISR(rx485_sem,&xHigherPriorityTaskWoken);
            break;
           
          case 2:
            GPDMA_ChannelCmd(2, DISABLE);           
            break;
           
          default:
            break;
        }
      }
      /* Check error terminal status */
      if (GPDMA_IntGetStatus(GPDMA_STAT_INTERR, tmp))
      {
        /* Clear error counter Interrupt pending */
        GPDMA_ClearIntPending (GPDMA_STATCLR_INTERR, tmp);
        switch (tmp)
        {
          case 0:
            GPDMA_ChannelCmd(0, DISABLE);
            break;
           
          case 1:
            GPDMA_ChannelCmd(1, DISABLE);
            break;
           
          case 2:
            GPDMA_ChannelCmd(2, DISABLE);
            break;
           
          default:
            break;
        }
      }
    }
  }
//  portEXIT_CRITICAL();
  portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );
}



void channel1setup(uint32_t DMARXSize,uint32_t rx_buf)
{
  GPDMA_Channel_CFG_Type GPDMACfg;
  /* Setup GPDMA channel --------------------------------*/
  /* channel 0 */
  GPDMACfg.ChannelNum = 1;
  /* Source memory - don't care */
  GPDMACfg.SrcMemAddr = 0;
  /* Destination memory */
  GPDMACfg.DstMemAddr = rx_buf;
  /* Transfer size */
  GPDMACfg.TransferSize = DMARXSize;
  /* Transfer width - don't care */
  GPDMACfg.TransferWidth = 0;
  /* Transfer type */
  GPDMACfg.TransferType = GPDMA_TRANSFERTYPE_P2M;
  /* Source connection */
  GPDMACfg.SrcConn = GPDMA_CONN_UART0_Rx;
  /* Destination connection - don't care */
  GPDMACfg.DstConn = 0;
  /* Linker List Item - unused */
  GPDMACfg.DMALLI = 0;
  GPDMA_Setup(&GPDMACfg); 
}


int pos=0;
void data_recv_task(void)
{
  UBaseType_t x;
  UART_CFG_Type UARTConfigStruct;
  UART_FIFO_CFG_Type UARTFIFOConfigStruct;
 
  PINSEL_ConfigPin(0,2,1);
  PINSEL_ConfigPin(0,3,1);
//  PINSEL_ConfigPin(0,10,1);
//  PINSEL_ConfigPin(0,11,1);
//  PINSEL_ConfigPin(1,19,0);
//  GPIO_SetDir(1, (1<<19), GPIO_DIRECTION_OUTPUT);
//  GPIO_OutputValue(1,(1<<19), 0);
  UARTConfigStruct.Databits = UART_DATABIT_8;
  UARTConfigStruct.Parity = UART_PARITY_NONE;
  UARTConfigStruct.Stopbits = UART_STOPBIT_1;
  UARTConfigStruct.Baud_rate=230400;
  UART_Init(LPC_UART0, &UARTConfigStruct);
   
  UARTFIFOConfigStruct.FIFO_Level = UART_FIFO_TRGLEV0;
  UARTFIFOConfigStruct.FIFO_ResetRxBuf = ENABLE;
  UARTFIFOConfigStruct.FIFO_ResetTxBuf = ENABLE;
  UARTFIFOConfigStruct.FIFO_DMAMode = ENABLE;
  UART_FIFOConfig(LPC_UART0, &UARTFIFOConfigStruct);
   
  GPDMA_Init();  
  NVIC_DisableIRQ (DMA_IRQn);
  NVIC_SetPriority(DMA_IRQn,(0x01<<4)|0x00);
  NVIC_EnableIRQ (DMA_IRQn);

while(1)
{  
   channel1setup(201,(uint32_t)&rx_buff[0]); 
   GPDMA_ChannelCmd(1, ENABLE);
  
   xSemaphoreTake(rx485_sem,portMAX_DELAY);
   for(pos=0;pos<134;pos++)
     if((rx_buff[pos]==0xE7)&&(rx_buff[pos+1]==0x7E))
     {
       LPC_DEBUGF(LPC_DEBUG,("+++++++++++++"));
       xSemaphoreGive(disp_sem);
       xSemaphoreTake(d2r_sem,portMAX_DELAY);
       break;
     }
   else LPC_DEBUGF(LPC_DEBUG,("%d-%x\n",pos,rx_buff[pos]));
//   LPC_DEBUGF(LPC_DEBUG,("%d***%x***\n",pos,rx_buff[pos]));
   x=uxTaskGetStackHighWaterMark((xTaskHandle *)NULL);
   LPC_DEBUGF(LPC_DEBUG,("RECVDATA=%d;",x));
}  
}


/*********************************************************************************************************
**                            End Of File
*********************************************************************************************************/








Done!
i found it's the reason of the compiler ,when i changed the compiler from iar to keil.,it works correctly!!!!!!!!

Outcomes