| LPCOpen Platform v1.03 LPCOpen Platform for NXP LPC Microcontrollers

- Main Page
- Modules
- Data Structures
- Files
- Related Pages

- File List
- Globals

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;
77 static DMA_TransferDescriptor_t desc_array[DMA_DESCRIPTOR_COUNT];
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;
98 DMA_TransferDescriptor_t *desc;
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 {
112 Chip_DMA_PrepareDescriptor(LPC_GPDMA, &desc[i],
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),
116 GPDMA_TRANSFERTYPE_M2M_CONTROLLER_DMA,
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;
151 Chip_DMA_Interrupt(LPC_GPDMA, ch_no);
152 }
153
158 int main(void)
159 {
160 uint32_t start_time;
161 uint32_t end_time;
162 uint32_t *dst = (uint32_t *) TRANSFER_DST_ADDR;
163 uint32_t *src = (uint32_t *) TRANSFER_SRC_ADDR;
164
165 Board_Init();
166
167 /* Initialize the DMA */
168 Chip_GPDMA_Init(LPC_GPDMA);
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);
178 ch_no = Chip_DMA_GetFreeChannel(LPC_GPDMA, 0);
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);
184 Chip_DMA_SGTransfer(LPC_GPDMA, ch_no, &desc_array[0], GPDMA_TRANSFERTYPE_M2M_CONTROLLER_DMA);
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