diff options
Diffstat (limited to 'lib/chibios-contrib/testhal/MSP430X/EXP430FR5969/DMA/main.c')
-rw-r--r-- | lib/chibios-contrib/testhal/MSP430X/EXP430FR5969/DMA/main.c | 351 |
1 files changed, 351 insertions, 0 deletions
diff --git a/lib/chibios-contrib/testhal/MSP430X/EXP430FR5969/DMA/main.c b/lib/chibios-contrib/testhal/MSP430X/EXP430FR5969/DMA/main.c new file mode 100644 index 000000000..f65d55019 --- /dev/null +++ b/lib/chibios-contrib/testhal/MSP430X/EXP430FR5969/DMA/main.c | |||
@@ -0,0 +1,351 @@ | |||
1 | /* | ||
2 | ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio | ||
3 | |||
4 | Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | you may not use this file except in compliance with the License. | ||
6 | You may obtain a copy of the License at | ||
7 | |||
8 | http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | |||
10 | Unless required by applicable law or agreed to in writing, software | ||
11 | distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | See the License for the specific language governing permissions and | ||
14 | limitations under the License. | ||
15 | */ | ||
16 | |||
17 | #include "ch.h" | ||
18 | #include "hal.h" | ||
19 | #include "hal_dma_lld.h" | ||
20 | #include "string.h" | ||
21 | |||
22 | const char * start_msg = "\r\n\r\nExecuting DMA test suite...\r\n"; | ||
23 | const char * test_1_msg = | ||
24 | "TEST 1: Word-to-word memcpy with DMA engine, no callbacks\r\n"; | ||
25 | const char * test_2_msg = | ||
26 | "TEST 2: Byte-to-byte memcpy with DMA engine, no callbacks\r\n"; | ||
27 | const char * test_3_msg = | ||
28 | "TEST 3: Byte-to-byte memset with DMA engine, no callbacks\r\n"; | ||
29 | const char * test_4_msg = | ||
30 | "TEST 4: Word-to-word memcpy with DMA engine, with callback\r\n"; | ||
31 | const char * test_5_msg = | ||
32 | "TEST 5: Claim DMA channel 0, perform a Word-to-word memcpy\r\n"; | ||
33 | const char * test_6_msg = "TEST 6: Attempt to claim already claimed DMA " | ||
34 | "channel, fail. Release it, try to claim it again, " | ||
35 | "and succeed.\r\n"; | ||
36 | const char * test_7_msg = "TEST 7: Claim DMA channel 1, perform a Word-to-word " | ||
37 | "memcpy, and release it\r\n"; | ||
38 | const char * test_8_msg = "TEST 8: Claim all three DMA channels, try to issue dmaRequest, " | ||
39 | "fail\r\n"; | ||
40 | |||
41 | const char * succeed_string = "SUCCESS\r\n\r\n"; | ||
42 | const char * fail_string = "FAILURE\r\n\r\n"; | ||
43 | |||
44 | char instring[256]; | ||
45 | char outstring[256]; | ||
46 | msp430x_dma_req_t * request; | ||
47 | uint8_t cb_arg = 1; | ||
48 | bool result; | ||
49 | int result_i; | ||
50 | |||
51 | void dma_callback_test(void * args) { | ||
52 | |||
53 | *((uint8_t *)args) = 0; | ||
54 | } | ||
55 | |||
56 | msp430x_dma_req_t test_1_req = { | ||
57 | instring, /* source address */ | ||
58 | outstring, /* destination address */ | ||
59 | 9, /* number of words */ | ||
60 | MSP430X_DMA_SRCINCR | MSP430X_DMA_DSTINCR, /* address mode - dual increment */ | ||
61 | MSP430X_DMA_SRCWORD | MSP430X_DMA_DSTWORD, /* word transfer */ | ||
62 | MSP430X_DMA_BLOCK, /* block (and blocking) transfer */ | ||
63 | DMA_TRIGGER_MNEM(DMAREQ), /* software-requested trigger */ | ||
64 | { | ||
65 | NULL, /* no callback */ | ||
66 | NULL /* no arguments */ | ||
67 | } | ||
68 | }; | ||
69 | |||
70 | msp430x_dma_req_t test_2_req = { | ||
71 | instring, /* source address */ | ||
72 | outstring, /* destination address */ | ||
73 | 18, /* number of bytes */ | ||
74 | MSP430X_DMA_SRCINCR | MSP430X_DMA_DSTINCR, /* address mode - dual increment */ | ||
75 | MSP430X_DMA_SRCBYTE | MSP430X_DMA_DSTBYTE, /* byte transfer */ | ||
76 | MSP430X_DMA_BLOCK, /* block (and blocking) transfer */ | ||
77 | DMA_TRIGGER_MNEM(DMAREQ), /* software-requested trigger */ | ||
78 | { | ||
79 | NULL, /* no callback */ | ||
80 | NULL /* no arguments */ | ||
81 | } | ||
82 | }; | ||
83 | |||
84 | msp430x_dma_req_t test_3_req = { | ||
85 | instring, /* source address */ | ||
86 | outstring, /* destination address */ | ||
87 | 16, /* number of words */ | ||
88 | MSP430X_DMA_DSTINCR, /* address mode - dest increment only */ | ||
89 | MSP430X_DMA_SRCBYTE | MSP430X_DMA_DSTBYTE, /* word transfer */ | ||
90 | MSP430X_DMA_BLOCK, /* block (and blocking) transfer */ | ||
91 | DMA_TRIGGER_MNEM(DMAREQ), /* software-requested trigger */ | ||
92 | { | ||
93 | NULL, /* no callback */ | ||
94 | NULL /* no arguments */ | ||
95 | } | ||
96 | }; | ||
97 | |||
98 | msp430x_dma_req_t test_4_req = { | ||
99 | instring, /* source address */ | ||
100 | outstring, /* destination address */ | ||
101 | 9, /* number of words */ | ||
102 | MSP430X_DMA_SRCINCR | MSP430X_DMA_DSTINCR, /* address mode - dual increment */ | ||
103 | MSP430X_DMA_SRCWORD | MSP430X_DMA_DSTWORD, /* word transfer */ | ||
104 | MSP430X_DMA_BLOCK, /* block (and blocking) transfer */ | ||
105 | DMA_TRIGGER_MNEM(DMAREQ), /* software-requested trigger */ | ||
106 | { | ||
107 | &dma_callback_test, /* test callback */ | ||
108 | &cb_arg /* test arguments */ | ||
109 | } | ||
110 | }; | ||
111 | |||
112 | msp430x_dma_req_t test_5_req = { | ||
113 | instring, /* source address */ | ||
114 | outstring, /* destination address */ | ||
115 | 9, /* number of words */ | ||
116 | MSP430X_DMA_SRCINCR | MSP430X_DMA_DSTINCR, /* address mode - dual increment */ | ||
117 | MSP430X_DMA_SRCWORD | MSP430X_DMA_DSTWORD, /* word transfer */ | ||
118 | MSP430X_DMA_BLOCK, /* block (and blocking) transfer */ | ||
119 | DMA_TRIGGER_MNEM(DMAREQ), /* software-requested trigger */ | ||
120 | { | ||
121 | NULL, /* no callback */ | ||
122 | NULL /* no arguments */ | ||
123 | } | ||
124 | }; | ||
125 | |||
126 | msp430x_dma_ch_t ch = { NULL, 0, NULL }; | ||
127 | msp430x_dma_ch_t ch1 = { NULL, 0, NULL }; | ||
128 | msp430x_dma_ch_t ch2 = { NULL, 0, NULL }; | ||
129 | |||
130 | /* | ||
131 | * Thread 2. | ||
132 | */ | ||
133 | THD_WORKING_AREA(waThread1, 2048); | ||
134 | THD_FUNCTION(Thread1, arg) { | ||
135 | |||
136 | (void)arg; | ||
137 | |||
138 | /* | ||
139 | * Activate the serial driver 0 using the driver default configuration. | ||
140 | */ | ||
141 | sdStart(&SD0, NULL); | ||
142 | |||
143 | while (chnGetTimeout(&SD0, TIME_INFINITE)) { | ||
144 | chnWrite(&SD0, (const uint8_t *)start_msg, strlen(start_msg)); | ||
145 | chThdSleepMilliseconds(2000); | ||
146 | |||
147 | /* Test 1 - use DMA engine to execute a word-wise memory-to-memory copy. */ | ||
148 | chnWrite(&SD0, (const uint8_t *)test_1_msg, strlen(test_1_msg)); | ||
149 | strcpy(instring, "After DMA test \r\n"); | ||
150 | strcpy(outstring, "Before DMA test \r\n"); | ||
151 | if (strcmp("Before DMA test \r\n", outstring)) { | ||
152 | chnWrite(&SD0, (const uint8_t *)fail_string, strlen(fail_string)); | ||
153 | } | ||
154 | request = &test_1_req; | ||
155 | chSysLock(); | ||
156 | dmaRequestS(request, TIME_INFINITE); | ||
157 | chSysUnlock(); | ||
158 | if (strcmp("After DMA test \r\n", outstring)) { | ||
159 | chnWrite(&SD0, (const uint8_t *)fail_string, strlen(fail_string)); | ||
160 | } | ||
161 | else { | ||
162 | chnWrite(&SD0, (const uint8_t *)succeed_string, strlen(succeed_string)); | ||
163 | } | ||
164 | |||
165 | /* Test 2 - use DMA engine to execute a byte-wise memory-to-memory copy. */ | ||
166 | chnWrite(&SD0, (const uint8_t *)test_2_msg, strlen(test_2_msg)); | ||
167 | strcpy(instring, "After DMA test \r\n"); | ||
168 | strcpy(outstring, "Before DMA test \r\n"); | ||
169 | if (strcmp("Before DMA test \r\n", outstring)) { | ||
170 | chnWrite(&SD0, (const uint8_t *)fail_string, strlen(fail_string)); | ||
171 | } | ||
172 | request = &test_2_req; | ||
173 | chSysLock(); | ||
174 | dmaRequestS(request, TIME_INFINITE); | ||
175 | chSysUnlock(); | ||
176 | if (strcmp("After DMA test \r\n", outstring)) { | ||
177 | chnWrite(&SD0, (const uint8_t *)fail_string, strlen(fail_string)); | ||
178 | } | ||
179 | else { | ||
180 | chnWrite(&SD0, (const uint8_t *)succeed_string, strlen(succeed_string)); | ||
181 | } | ||
182 | |||
183 | /* Test 3 - use DMA engine to execute a word-wise memory-to-memory set. */ | ||
184 | chnWrite(&SD0, (const uint8_t *)test_3_msg, strlen(test_3_msg)); | ||
185 | strcpy(instring, "After DMA test \r\n"); | ||
186 | strcpy(outstring, "Before DMA test \r\n"); | ||
187 | if (strcmp("Before DMA test \r\n", outstring)) { | ||
188 | chnWrite(&SD0, (const uint8_t *)fail_string, strlen(fail_string)); | ||
189 | } | ||
190 | request = &test_3_req; | ||
191 | chSysLock(); | ||
192 | dmaRequestS(request, TIME_INFINITE); | ||
193 | chSysUnlock(); | ||
194 | if (strcmp("AAAAAAAAAAAAAAAA\r\n", outstring)) { | ||
195 | chnWrite(&SD0, (const uint8_t *)fail_string, strlen(fail_string)); | ||
196 | } | ||
197 | else { | ||
198 | chnWrite(&SD0, (const uint8_t *)succeed_string, strlen(succeed_string)); | ||
199 | } | ||
200 | |||
201 | /* Test 4 - use DMA engine to execute a word-wise memory-to-memory copy, | ||
202 | * then call a callback. */ | ||
203 | chnWrite(&SD0, (const uint8_t *)test_4_msg, strlen(test_4_msg)); | ||
204 | strcpy(instring, "After DMA test \r\n"); | ||
205 | strcpy(outstring, "Before DMA test \r\n"); | ||
206 | cb_arg = 1; | ||
207 | if (strcmp("Before DMA test \r\n", outstring) || (cb_arg != 1)) { | ||
208 | chnWrite(&SD0, (const uint8_t *)fail_string, strlen(fail_string)); | ||
209 | } | ||
210 | request = &test_4_req; | ||
211 | chSysLock(); | ||
212 | dmaRequestS(request, TIME_INFINITE); | ||
213 | chSysUnlock(); | ||
214 | if (strcmp("After DMA test \r\n", outstring) || cb_arg) { | ||
215 | chnWrite(&SD0, (const uint8_t *)fail_string, strlen(fail_string)); | ||
216 | } | ||
217 | else { | ||
218 | chnWrite(&SD0, (const uint8_t *)succeed_string, strlen(succeed_string)); | ||
219 | } | ||
220 | |||
221 | /* Test 5 - use exclusive DMA channel 0 to execute a word-wise | ||
222 | * memory-to-memory copy. */ | ||
223 | chnWrite(&SD0, (const uint8_t *)test_5_msg, strlen(test_5_msg)); | ||
224 | strcpy(instring, "After DMA test \r\n"); | ||
225 | strcpy(outstring, "Before DMA test \r\n"); | ||
226 | if (strcmp("Before DMA test \r\n", outstring)) { | ||
227 | chnWrite(&SD0, (const uint8_t *)fail_string, strlen(fail_string)); | ||
228 | } | ||
229 | request = &test_5_req; | ||
230 | chSysLock(); | ||
231 | dmaAcquireI(&ch, 0); | ||
232 | chSysUnlock(); | ||
233 | dmaTransfer(&ch, request); | ||
234 | if (strcmp("After DMA test \r\n", outstring)) { | ||
235 | chnWrite(&SD0, (const uint8_t *)fail_string, strlen(fail_string)); | ||
236 | } | ||
237 | else { | ||
238 | chnWrite(&SD0, (const uint8_t *)succeed_string, strlen(succeed_string)); | ||
239 | } | ||
240 | |||
241 | /* Test 6 - Attempt to claim DMA channel 0, fail, release it, attempt to | ||
242 | * claim it again */ | ||
243 | chnWrite(&SD0, (const uint8_t *)test_6_msg, strlen(test_6_msg)); | ||
244 | chSysLock(); | ||
245 | result = dmaAcquireI(&ch, 0); | ||
246 | chSysUnlock(); | ||
247 | if (!result) { | ||
248 | chnWrite(&SD0, (const uint8_t *)fail_string, strlen(fail_string)); | ||
249 | } | ||
250 | dmaRelease(&ch); | ||
251 | chSysLock(); | ||
252 | result = dmaAcquireI(&ch, 0); | ||
253 | chSysUnlock(); | ||
254 | if (result) { | ||
255 | chnWrite(&SD0, (const uint8_t *)fail_string, strlen(fail_string)); | ||
256 | } | ||
257 | else { | ||
258 | chnWrite(&SD0, (const uint8_t *)succeed_string, strlen(succeed_string)); | ||
259 | } | ||
260 | dmaRelease(&ch); | ||
261 | |||
262 | /* Test 7 - use exclusive DMA channel 1 to execute a word-wise | ||
263 | * memory-to-memory copy. */ | ||
264 | chnWrite(&SD0, (const uint8_t *)test_7_msg, strlen(test_7_msg)); | ||
265 | strcpy(instring, "After DMA test \r\n"); | ||
266 | strcpy(outstring, "Before DMA test \r\n"); | ||
267 | if (strcmp("Before DMA test \r\n", outstring)) { | ||
268 | chnWrite(&SD0, (const uint8_t *)fail_string, strlen(fail_string)); | ||
269 | } | ||
270 | request = &test_5_req; | ||
271 | chSysLock(); | ||
272 | dmaAcquireI(&ch, 1); | ||
273 | chSysUnlock(); | ||
274 | dmaTransfer(&ch, request); | ||
275 | if (strcmp("After DMA test \r\n", outstring)) { | ||
276 | chnWrite(&SD0, (const uint8_t *)fail_string, strlen(fail_string)); | ||
277 | } | ||
278 | else { | ||
279 | chnWrite(&SD0, (const uint8_t *)succeed_string, strlen(succeed_string)); | ||
280 | } | ||
281 | dmaRelease(&ch); | ||
282 | |||
283 | /* Test 8 - Claim all 3 DMA channels, attempt dmaRequest, fail */ | ||
284 | chnWrite(&SD0, (const uint8_t *)test_8_msg, strlen(test_8_msg)); | ||
285 | chSysLock(); | ||
286 | result = dmaAcquireI(&ch, 0); | ||
287 | chSysUnlock(); | ||
288 | if (result) { | ||
289 | chnWrite(&SD0, (const uint8_t *)fail_string, strlen(fail_string)); | ||
290 | } | ||
291 | chSysLock(); | ||
292 | result = dmaAcquireI(&ch1, 1); | ||
293 | chSysUnlock(); | ||
294 | if (result) { | ||
295 | chnWrite(&SD0, (const uint8_t *)fail_string, strlen(fail_string)); | ||
296 | } | ||
297 | chSysLock(); | ||
298 | result = dmaAcquireI(&ch2, 2); | ||
299 | chSysUnlock(); | ||
300 | if (result) { | ||
301 | chnWrite(&SD0, (const uint8_t *)fail_string, strlen(fail_string)); | ||
302 | } | ||
303 | chSysLock(); | ||
304 | result_i = dmaRequestS(request, TIME_IMMEDIATE); | ||
305 | chSysUnlock(); | ||
306 | if (result_i > 0) { | ||
307 | chnWrite(&SD0, (const uint8_t *)fail_string, strlen(fail_string)); | ||
308 | } | ||
309 | else { | ||
310 | chnWrite(&SD0, (const uint8_t *)succeed_string, strlen(succeed_string)); | ||
311 | } | ||
312 | dmaRelease(&ch); | ||
313 | dmaRelease(&ch1); | ||
314 | dmaRelease(&ch2); | ||
315 | |||
316 | } | ||
317 | } | ||
318 | |||
319 | /* | ||
320 | * Threads static table, one entry per thread. The number of entries must | ||
321 | * match NIL_CFG_NUM_THREADS. | ||
322 | */ | ||
323 | THD_TABLE_BEGIN | ||
324 | THD_TABLE_ENTRY(waThread1, "dma_test", Thread1, NULL) | ||
325 | THD_TABLE_END | ||
326 | |||
327 | /* | ||
328 | * Application entry point. | ||
329 | */ | ||
330 | int main(void) { | ||
331 | |||
332 | /* | ||
333 | * System initializations. | ||
334 | * - HAL initialization, this also initializes the configured device drivers | ||
335 | * and performs the board-specific initializations. | ||
336 | * - Kernel initialization, the main() function becomes a thread and the | ||
337 | * RTOS is active. | ||
338 | */ | ||
339 | WDTCTL = WDTPW | WDTHOLD; | ||
340 | |||
341 | halInit(); | ||
342 | chSysInit(); | ||
343 | dmaInit(); | ||
344 | |||
345 | /* This is now the idle thread loop, you may perform here a low priority | ||
346 | task but you must never try to sleep or wait in this loop. Note that | ||
347 | this tasks runs at the lowest priority level so any instruction added | ||
348 | here will be executed after all other tasks have been started.*/ | ||
349 | while (true) { | ||
350 | } | ||
351 | } | ||