Fast Data Transfer from Parallel GPIO Input to SRAM using GPDMA

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Fast Data Transfer from Parallel GPIO Input to SRAM using GPDMA

374 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by whatisain on Tue May 01 22:40:36 MST 2012
Hi everyone

(please understand for my poor English)
I'm trying to transfer 8bit parallel data input from GPIO pins to SRAM using GPDMA.

The base platform is LPC1769 operating at 120mhz CCLK,
and DMA request is made by counter match (matches every rising edge of 27mhz data clock).

But it seems that there are some loss during data transfer
I think GPDMA transfer can not catch up the 27mhz clock,
(it works fine up to about 7mhz)

does anyone have idea about
how many cycles needed to transfer single data from GPIO to SRAM using GPDMA?
or any way of speed up the GPDMA?

below is part of my GPDMA configuration.


LPC_SC->DMAREQSEL |= 1;                //Select REQ source Timer0, Mat0.0

LPC_SC->PCONP |= (1 << 29);//Power up GPDMA
LPC_GPDMA->DMACConfig |= 1;//Enable GPDMA Controller

LPC_TIM0->IR = 0x0f;                //clear mr, cr

LPC_GPDMACH0->DMACCSrcAddr= (uint32_t) &(LPC_GPIO2->FIOPIN);
LPC_GPDMACH0->DMACCDestAddr= (uint32_t) &dest[0];
LPC_GPDMACH0->DMACCLLI= 0;
LPC_GPDMACH0->DMACCControl= SAMPLE_NUM
| (0 << 12)//source burst size - 1
| (0 << 15)//destination burst size - 1
| (0 << 18)//source width - 8bit
| (0 << 21)//dest width - 8bit
| (0 << 24)
| (0 << 25)
| (0 << 26)//source increment - do not inc
| (1 << 27)//destination increment - inc
| (0 << 28)
| (0 << 29)
| (0 << 30)
| (1 << 31);//terminal count interrupt - enabled

LPC_GPDMA->DMACIntTCClear |= 1;                //Clear CH0 TC Int. flag
NVIC_EnableIRQ(DMA_IRQn);

LPC_GPDMACH0->DMACCConfig = 1                //Channel Enabled
| ((8 & 0x1f) << 1)//source peripheral - MAT0.0
| (0 << 6)//dest request peripheral - none
| (2 << 11)//flow control - peripheral to memory
| (1 << 14)//(14) - mask out error interrupt
| (1 << 15)//(15) - mask out terminal count interrupt
| (0 << 16)//(16) - no locked transfers
| (0 << 18);//(27) - no HALT



Thanks in advance.
0 Kudos
Reply
2 Replies

290 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by whatisain on Fri May 04 00:42:35 MST 2012
Hi researchinnovation,

Thanks for your reply,
I'll test the code you suggested below and refer to the link.

Thanks!
0 Kudos
Reply

290 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by researchinnovation on Wed May 02 04:14:20 MST 2012
@Whatisain.....Hi...!!!


Please go through the following link....

http://knowledgebase.nxp.com/showthread.php?t=2627

and Try This code and modify accordingly:-
/*---------------Include-------------------------------------------------------*/
#include "lpc17xx_uart.h"
#include "lpc17xx_gpdma.h"
#include "lpc_types.h"
#include "lpc17xx_libcfg_default.h"
#include "lpc17xx_nvic.h"
#include "lpc17xx_pinsel.h" /*---------------Macro Define--------------------------------------------------*/
#define DMA_SIZE   16
/*---------------Private Variable----------------------------------------------*/
uint8_t welcomeMenu[] =
"********************************************************************************\n\r"
"This example used to test GPDMA function by transferring data from Flash \n\r"
"to RAM memory!\n\r"
"********************************************************************************\n\r";
uint8_t endMenu[] = "Demo terminated! \n\r";
uint8_t errMenu[] = "Buffer Check fail!";
uint8_t completeMenu[] = "Buffer Check success!\n\r";
uint8_t startMenu[] = "Start transferring!\n\r";
/* DMAScr_Buffer will be burn into flash when compile */
const uint32_t DMASrc_Buffer[DMA_SIZE] =
{
0x01020304,0x05060708,0x090A0B0C,0x0D0E0F10,
0x21222324,0x25262728,0x292A2B2C,0x2D2E2F30,
0x11121314,0x15161718,0x191A1B1C,0x1D1E1F20,
0x31323334,0x35363738,0x393A3B3C,0x3D3E3F40
};
/* DMADest_Buffer will be loaded into RAM memory */
uint32_t DMADest_Buffer[DMA_SIZE];
/* Terminal Counter flag for Channel 0 */
volatile uint32_t Channel0_TC;
/* Error Counter flag for Channel 0 */
volatile uint32_t Channel0_Err;
/*---------------Private Function Prototypes----------------------------------------*/
void PrintMenu(void);
void DMA_IRQHandler(void);
void Buffer_Verify(void);
void Error_Loop(void);
void UARTInit(void);
/*---------------Private Functioins-------------------------------------------------*/
/*
* @brief    Test the GPDMA function by transferring data from flash to ram memory.
* @param    None.
* @return   None.
*/
void GPDMA_M2MExample(void)
{
GPDMA_Channel_CFG_Type GPDMACfg;
  /* Initialize the system clock */
SystemInit();
/* Configure the UART1 */
UARTInit();
  PrintMenu();
  /* GPDMA block section -------------------------------------------- */
    /* Disable GPDMA interrupt */
    NVIC_DisableIRQ(DMA_IRQn);
    /* preemption = 1, sub-priority = 1 */
    NVIC_SetPriority(DMA_IRQn, ((0x01<<3)|0x01));
     /* Initialize GPDMA controller */
GPDMA_Init();
  /* Setup GPDMA channel --------------------------------*/
/* channel 0 */
GPDMACfg.ChannelNum = 0;
/* Source memory */
GPDMACfg.SrcMemAddr = (uint32_t)DMASrc_Buffer;
/* Destination memory */
GPDMACfg.DstMemAddr = (uint32_t)DMADest_Buffer;
/* Transfer size */
GPDMACfg.TransferSize = DMA_SIZE;
/* Transfer width */
GPDMACfg.TransferWidth = GPDMA_WIDTH_WORD;
/* Transfer type */
GPDMACfg.TransferType = GPDMA_TRANSFERTYPE_M2M;
/* Source connection - unused */
GPDMACfg.SrcConn = 0;
/* Destination connection - unused */
GPDMACfg.DstConn = 0;
/* Linker List Item - unused */
GPDMACfg.DMALLI = 0;
/* Setup channel with given parameter */
GPDMA_Setup(&GPDMACfg);
  /* Reset terminal counter */
Channel0_TC = 0;
/* Reset Error counter */
Channel0_Err = 0;
  UART_Send((LPC_UART_TypeDef *)LPC_UART1, &startMenu[0], sizeof(startMenu), BLOCKING);
  /* Enable GPDMA channel 0 */
GPDMA_ChannelCmd(0, ENABLE);
  /* Enable GPDMA interrupt */
NVIC_EnableIRQ(DMA_IRQn);
  /* Wait for GPDMA processing complete */
while ((Channel0_TC == 0) && (Channel0_Err == 0));
  /* Verify buffer */
Buffer_Verify();
  UART_Send((LPC_UART_TypeDef *)LPC_UART1, &completeMenu[0], sizeof(completeMenu), BLOCKING);
}
/*
* @brief    DMA interrupt service routine , clear corresponding interrupt.
* @param    None.
* @return   None.
*/
void DMA_IRQHandler(void)
{
if(GPDMA_IntGetStatus(GPDMA_STAT_INT, 0) == SET)
{
  if(GPDMA_IntGetStatus(GPDMA_STAT_INTTC, 0) == SET)
  {
   Channel0_TC++;
   GPDMA_ClearIntPending(GPDMA_STATCLR_INTTC, 0);
  }
  if(GPDMA_IntGetStatus(GPDMA_STAT_INTERR, 0) == SET)
  {
   Channel0_Err++;
   GPDMA_ClearIntPending(GPDMA_STATCLR_INTERR, 0);
  }
}
}
/*
* @brief    Print the menu.
* @param    None.
* @return   None.
*/
void PrintMenu(void)
{
UART_Send((LPC_UART_TypeDef *)LPC_UART1, &welcomeMenu[0], sizeof(welcomeMenu), BLOCKING);
}
/*
* @brief    Simply verify the buffer area.
* @param    None.
* @return   None.
*/
void Buffer_Verify(void)
{
uint8_t i;
uint32_t *src_addr = (uint32_t *)DMASrc_Buffer;
uint32_t *dest_addr = (uint32_t *)DMADest_Buffer;
  for(i = 0; i < DMA_SIZE; i++)
{
  if(*src_addr != *dest_addr)
  {
   UART_Send((LPC_UART_TypeDef *)LPC_UART1, &endMenu[0], sizeof(endMenu), BLOCKING);
   Error_Loop();
  }
  else
  {
   src_addr++;
   dest_addr++;
  }
}
}
/*
* @brief    Print error message and goto indefinite loop.
* @param    None.
* @return   None.
*/
void Error_Loop(void)
{
UART_Send((LPC_UART_TypeDef *)LPC_UART1, &errMenu[0], sizeof(errMenu), BLOCKING);
while(1);
}
/*
* @brief    Initialize the UART1 to communicate with the PC hyperterminal.
* @param    None.
* @return   None.
*/
void UARTInit(void)
{
UART_CFG_Type UARTCfg;
UART_FIFO_CFG_Type UARTFIFOCfg;
PINSEL_CFG_Type PinCfg;
  /* Initialize the UART1 pin connect */
PinCfg.Funcnum = 2;
PinCfg.OpenDrain = 0;
PinCfg.Pinmode = 0;
PinCfg.Pinnum = 0;
PinCfg.Portnum = 2;
PINSEL_ConfigPin(&PinCfg);
PinCfg.Pinnum = 1;
PINSEL_ConfigPin(&PinCfg);
  /* Initialize the UART1
  * Baud_rate = 115200
  * 8 data bit
  * 1 stop bit
  * None parity
  */
UART_ConfigStructInit(&UARTCfg);
UARTCfg.Baud_rate = 115200;
UART_Init((LPC_UART_TypeDef *)LPC_UART1, &UARTCfg);
  /*
  * Initialize the UART FIFO
  * FIFO_DMAMode = DISABLE
  * FIFO_LEVEL = UART_FIFO_TRGLEV0
  * FIFO_ResetRxBuf = ENABLE
  * FIFO_ResetTxBuf = ENABLE
  * FIFO_State = ENABLE
  */
UART_FIFOConfigStructInit(&UARTFIFOCfg);
UART_FIFOConfig((LPC_UART_TypeDef *)LPC_UART1, &UARTFIFOCfg);
  /* Enable UART1 transmission */
UART_TxCmd((LPC_UART_TypeDef *)LPC_UART1, ENABLE);
}
0 Kudos
Reply