LPCOpen Platform  v1.03
LPCOpen Platform for NXP LPC Microcontrollers
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
gpdma_speed_test.c
Go to the documentation of this file.
1 /*
2  * @brief GPDMA Speed test example
3  *
4  * @note
5  * Copyright(C) NXP Semiconductors, 2012
6  * All rights reserved.
7  *
8  * @par
9  * Software that is described herein is for illustrative purposes only
10  * which provides customers with programming information regarding the
11  * LPC products. This software is supplied "AS IS" without any warranties of
12  * any kind, and NXP Semiconductors and its licensor disclaim any and
13  * all warranties, express or implied, including all implied warranties of
14  * merchantability, fitness for a particular purpose and non-infringement of
15  * intellectual property rights. NXP Semiconductors assumes no responsibility
16  * or liability for the use of the software, conveys no license or rights under any
17  * patent, copyright, mask work right, or any other intellectual property rights in
18  * or to any products. NXP Semiconductors reserves the right to make changes
19  * in the software without notification. NXP Semiconductors also makes no
20  * representation or warranty that such application will be suitable for the
21  * specified use without further testing or modification.
22  *
23  * @par
24  * Permission to use, copy, modify, and distribute this software and its
25  * documentation is hereby granted, under NXP Semiconductors' and its
26  * licensor's relevant copyrights in the software, without fee, provided that it
27  * is used in conjunction with NXP Semiconductors microcontrollers. This
28  * copyright, permission, and disclaimer notice must appear in all copies of
29  * this code.
30  */
31 
32 #include <stdlib.h>
33 #include <string.h>
34 #include "board.h"
35 
64 /*****************************************************************************
65  * Private types/enumerations/variables
66  ****************************************************************************/
67 
68 /* Data transfer information */
69 #define TRANSFER_DST_ADDR 0x28500000
70 #define TRANSFER_SRC_ADDR 0x28100000
71 #define TRANSFER_SIZE 0x200000
72 
73 #define TRANSFER_BLOCK_SZ (4 * 3 * 1024) /* 3K of data transfered per LLI */
74 #define DMA_DESCRIPTOR_COUNT 256
75 
76 static uint8_t ch_no;
78 static volatile int dma_xfer_complete;
79 /*****************************************************************************
80  * Public types/enumerations/variables
81  ****************************************************************************/
82 
83 /*****************************************************************************
84  * Private functions
85  ****************************************************************************/
86 static void prepare_src_data(uint32_t *src, int sz)
87 {
88  int i;
89  for (i = 0; i < sz; i++) {
90  src[i] = i | (~i << (16 - (i & 15))); /* Fill it with some pattern */
91  }
92 }
93 
94 /* Function to prepare memory to memory transfer descriptors */
95 static int prepare_dma_desc(uint32_t* dst, const uint32_t* src, uint32_t sz)
96 {
97  int i;
99  int num_desc = sz / TRANSFER_BLOCK_SZ;
100 
101  /* Add one more if size is not in 3K blocks */
102  num_desc += sz * TRANSFER_BLOCK_SZ != sz;
103  desc = &desc_array[0];
104  if (num_desc >= DMA_DESCRIPTOR_COUNT) {
105  DEBUGOUT("Transfer needs %d descriptors, but has "
106  "%d descriptors only\r\n", num_desc, DMA_DESCRIPTOR_COUNT);
107  return 0;
108  }
109 
110  for (i = 0; i < num_desc; i ++)
111  {
113  (uint32_t) src + (i * TRANSFER_BLOCK_SZ),
114  (uint32_t) dst + (i * TRANSFER_BLOCK_SZ),
115  (uint32_t) (sz < TRANSFER_BLOCK_SZ ? sz : TRANSFER_BLOCK_SZ),
117  (i + 1 == num_desc) ? NULL: &desc[i + 1]);
118  sz -= TRANSFER_BLOCK_SZ;
119  }
120  return num_desc;
121 }
122 
123 /* Print the result of a data transfer */
124 static void print_result(const void *dst, const void *src, int sz, uint32_t stime, uint32_t etime, const char *mode)
125 {
126  uint32_t clk = SystemCoreClock/1000000;
127  int invalid;
128  invalid = memcmp(dst, src, sz);
129  DEBUGOUT("\r\nData transfer results [MODE: %s]\r\n"
130  "=========================================\r\n", mode);
131  DEBUGOUT("SOURCE ADDR: 0x%08X\r\n", src);
132  DEBUGOUT("DESTN ADDR: 0x%08X\r\n", dst);
133  DEBUGOUT("XFER SIZE: %lu (Bytes)\r\n", sz);
134  DEBUGOUT("CPU SPEED: %lu.%lu (MHz)\r\n", clk, (SystemCoreClock / 10000) - (clk * 100));
135  DEBUGOUT("START TIME: %lu (ticks)\r\n", stime);
136  DEBUGOUT("END TIME: %lu (ticks)\r\n", etime);
137  DEBUGOUT("TIME TAKEN: %lu (uSec(s))\r\n", (etime - stime) / clk);
138  DEBUGOUT("SRC/DST COMP: %s\r\n", invalid ? "NOT MATCHING" : "MATCHING");
139 }
140 /*****************************************************************************
141  * Public functions
142  ****************************************************************************/
143 
148 void DMA_IRQHandler(void)
149 {
150  dma_xfer_complete = 1;
152 }
153 
158 int main(void)
159 {
160  uint32_t start_time;
161  uint32_t end_time;
164 
165  Board_Init();
166 
167  /* Initialize the DMA */
169 
170  /* Prepare the source buffer for transfer */
171  prepare_src_data(src, TRANSFER_SIZE/sizeof(*src));
172  DEBUGSTR("***** DATA TRANSFER TEST *******\r\n");
173  start_time = Chip_RIT_GetCounter(LPC_RITIMER);
174  memcpy(dst, src, TRANSFER_SIZE);
175  end_time = Chip_RIT_GetCounter(LPC_RITIMER);
176  print_result(dst, src, TRANSFER_SIZE, start_time, end_time, "CPU (memcpy)");
177  memset(dst, 0, TRANSFER_SIZE);
179  if (prepare_dma_desc(dst, src, TRANSFER_SIZE) <= 0) {
180  DEBUGSTR("Unable to create DMA Descriptors\r\n");
181  while (1) {}
182  }
183  start_time = Chip_RIT_GetCounter(LPC_RITIMER);
185  NVIC_EnableIRQ(DMA_IRQn);
186  while(!dma_xfer_complete); /* Set by ISR */
187  end_time = Chip_RIT_GetCounter(LPC_RITIMER);
188  print_result(dst, src, TRANSFER_SIZE, start_time, end_time, "DMA");
189  /* LED is toggled in interrupt handler */
190  while (1) {}
191 }
192