Skip to content

Commit da2a4cc

Browse files
committed
[EFM32] Add SPI test. Refactor SPI HAL, fix misc test failures.
Properly support the bit_width parameter for the async API. Fix issues with long DMA transfers (exceeding 1023 frames).
1 parent 746c485 commit da2a4cc

File tree

2 files changed

+647
-256
lines changed

2 files changed

+647
-256
lines changed
Lines changed: 378 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,378 @@
1+
/***************************************************************************//**
2+
* @file main.cpp
3+
*******************************************************************************
4+
* @section License
5+
* <b>(C) Copyright 2016 Silicon Labs, http://www.silabs.com</b>
6+
*******************************************************************************
7+
*
8+
* SPDX-License-Identifier: Apache-2.0
9+
*
10+
* Licensed under the Apache License, Version 2.0 (the "License"); you may
11+
* not use this file except in compliance with the License.
12+
* You may obtain a copy of the License at
13+
*
14+
* http://www.apache.org/licenses/LICENSE-2.0
15+
*
16+
* Unless required by applicable law or agreed to in writing, software
17+
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
18+
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19+
* See the License for the specific language governing permissions and
20+
* limitations under the License.
21+
*
22+
******************************************************************************/
23+
24+
#include "mbed.h"
25+
26+
#include "greentea-client/test_env.h"
27+
#include "unity/unity.h"
28+
#include "utest/utest.h"
29+
30+
#include "em_cmu.h"
31+
#include "em_gpio.h"
32+
#include "em_prs.h"
33+
#include "em_timer.h"
34+
35+
#define SHORT_TRANSFER_FRAMES 16
36+
#define LONG_TRANSFER_FRAMES 1842
37+
38+
#if defined(TARGET_EFM32GG_STK3700) || defined(TARGET_EFM32LG_STK3600) || defined(TARGET_EFM32WG_STK3800)
39+
40+
#define TEST 1
41+
42+
#define TEST_UART USART1
43+
#define MOSI_PIN PD0
44+
#define MISO_PIN PD1
45+
#define CLK_PIN PD2
46+
#define CS_PIN PD3
47+
48+
#define GPIO_PORT gpioPortD
49+
#define GPIO_PIN_TX 0
50+
#define GPIO_PIN_CLK 2
51+
#define GPIO_PRS_SRC_TX PRS_CH_CTRL_SOURCESEL_GPIOL
52+
#define GPIO_PRS_SIG_TX PRS_CH_CTRL_SIGSEL_GPIOPIN0
53+
#define GPIO_PRS_SRC_CLK PRS_CH_CTRL_SOURCESEL_GPIOL
54+
#define GPIO_PRS_SIG_CLK PRS_CH_CTRL_SIGSEL_GPIOPIN2
55+
56+
#define TEST_TIMER TIMER1
57+
#define TEST_TIMER_CLOCK cmuClock_TIMER1
58+
59+
#elif defined(TARGET_EFM32PG_STK3401)
60+
61+
#define TEST 1
62+
63+
#define TEST_UART USART1
64+
#define MOSI_PIN PC6
65+
#define MISO_PIN PC7
66+
#define CLK_PIN PC8
67+
#define CS_PIN PC9
68+
69+
#define GPIO_PORT gpioPortC
70+
#define GPIO_PIN_TX 6
71+
#define GPIO_PIN_CLK 8
72+
#define GPIO_PRS_SRC_TX PRS_CH_CTRL_SOURCESEL_GPIOL
73+
#define GPIO_PRS_SIG_TX PRS_CH_CTRL_SIGSEL_GPIOPIN6
74+
#define GPIO_PRS_SRC_CLK PRS_CH_CTRL_SOURCESEL_GPIOH
75+
#define GPIO_PRS_SIG_CLK PRS_CH_CTRL_SIGSEL_GPIOPIN8
76+
77+
#define TEST_TIMER TIMER1
78+
#define TEST_TIMER_CLOCK cmuClock_TIMER1
79+
80+
#else
81+
#define TEST 0
82+
#warning "Test config not defined; skipping test"
83+
#endif
84+
85+
using namespace utest::v1;
86+
87+
#if TEST
88+
DigitalOut cs(CS_PIN);
89+
static volatile bool complete;
90+
event_callback_t cb;
91+
92+
static uint8_t short_data_8[SHORT_TRANSFER_FRAMES];
93+
static uint16_t short_data_16[SHORT_TRANSFER_FRAMES];
94+
static uint32_t short_data_32[SHORT_TRANSFER_FRAMES];
95+
96+
static uint8_t short_data_8_rx[SHORT_TRANSFER_FRAMES];
97+
static uint16_t short_data_16_rx[SHORT_TRANSFER_FRAMES];
98+
static uint32_t short_data_32_rx[SHORT_TRANSFER_FRAMES];
99+
100+
static uint8_t long_data_8[LONG_TRANSFER_FRAMES];
101+
static uint16_t long_data_16[LONG_TRANSFER_FRAMES];
102+
103+
static uint8_t long_data_8_rx[LONG_TRANSFER_FRAMES];
104+
static uint16_t long_data_16_rx[LONG_TRANSFER_FRAMES];
105+
106+
void callbackFunction(int flags) {
107+
complete = true;
108+
}
109+
110+
void init_timer() {
111+
CMU_ClockEnable(cmuClock_PRS, true);
112+
CMU_ClockEnable(cmuClock_GPIO, true);
113+
CMU_ClockEnable(TEST_TIMER_CLOCK, true);
114+
115+
// Setup USART TX pin as PRS producer
116+
GPIO_IntConfig(GPIO_PORT, GPIO_PIN_TX, false, false, false);
117+
PRS_SourceSignalSet(0,
118+
GPIO_PRS_SRC_TX,
119+
GPIO_PRS_SIG_TX,
120+
prsEdgeOff);
121+
122+
// Setup USART CLK pin as PRS producer
123+
GPIO_IntConfig(GPIO_PORT, GPIO_PIN_CLK, false, false, false);
124+
PRS_SourceSignalSet(1,
125+
GPIO_PRS_SRC_CLK,
126+
GPIO_PRS_SIG_CLK,
127+
prsEdgeOff);
128+
129+
// Setup timer to count on PRS pulses
130+
TIMER_Init_TypeDef timInit = TIMER_INIT_DEFAULT;
131+
timInit.enable = false;
132+
timInit.clkSel = timerClkSelCC1;
133+
134+
TIMER_InitCC_TypeDef timInitCC = TIMER_INITCC_DEFAULT;
135+
timInitCC.prsInput = true;
136+
timInitCC.prsSel = timerPRSSELCh1;
137+
138+
TIMER_Init(TEST_TIMER, &timInit);
139+
TIMER_InitCC(TEST_TIMER, 1, &timInitCC);
140+
141+
TIMER_Enable(TEST_TIMER, true);
142+
}
143+
144+
template<typename T>
145+
void init_arrays(T * tx, T * rx, int len, uint32_t mask) {
146+
for (uint32_t i = 0; i < len; i++) {
147+
if (tx) {
148+
tx[i] = i & mask;
149+
}
150+
if (rx) {
151+
rx[i] = 0;
152+
}
153+
}
154+
}
155+
156+
template<typename T>
157+
void test_transfer(int bits, int polarity, int freq, DMAUsage dma, T * data_tx, T * data_rx, int len) {
158+
SPI spi(MOSI_PIN, MISO_PIN, CLK_PIN);
159+
160+
spi.format(bits, polarity);
161+
spi.frequency(freq);
162+
163+
spi.set_dma_usage(dma);
164+
165+
// Clear RX buffer, setup tx pattern
166+
init_arrays(data_tx, data_rx, len, (1 << bits) - 1);
167+
168+
// Set up PRS loopback of TX data to RX
169+
TEST_UART->INPUT = USART_INPUT_RXPRS | USART_INPUT_RXPRSSEL_PRSCH0;
170+
171+
complete = false;
172+
TIMER1->CNT = 0;
173+
cs = 0;
174+
spi.transfer(data_tx, len, data_rx, data_rx ? len : 0, cb);
175+
176+
while (!complete);
177+
178+
uint32_t xferred = TIMER1->CNT;
179+
cs = 1;
180+
181+
// Check that all bits were sent
182+
TEST_ASSERT_EQUAL(bits*len, xferred);
183+
184+
// Check that all data was received correctly
185+
if (data_rx) {
186+
for (int i = 0; i < len; i++) {
187+
TEST_ASSERT_EQUAL(data_tx[i], data_rx[i]);
188+
}
189+
}
190+
}
191+
192+
////////////////////////////////
193+
// Short single transfers
194+
195+
void test_5bit_8bit_0_1mhz_short_transfer() {
196+
test_transfer(5, 0, 1000000, DMA_USAGE_NEVER, short_data_8, short_data_8_rx, SHORT_TRANSFER_FRAMES);
197+
}
198+
199+
void test_5bit_8bit_0_1mhz_short_dma_transfer() {
200+
test_transfer(5, 0, 1000000, DMA_USAGE_OPPORTUNISTIC, short_data_8, short_data_8_rx, SHORT_TRANSFER_FRAMES);
201+
}
202+
203+
void test_5bit_16bit_0_1mhz_short_transfer() {
204+
test_transfer(5, 0, 1000000, DMA_USAGE_NEVER, short_data_16, short_data_16_rx, SHORT_TRANSFER_FRAMES);
205+
}
206+
207+
void test_5bit_16bit_0_1mhz_short_dma_transfer() {
208+
test_transfer(5, 0, 1000000, DMA_USAGE_OPPORTUNISTIC, short_data_16, short_data_16_rx, SHORT_TRANSFER_FRAMES);
209+
}
210+
211+
void test_8bit_8bit_0_1mhz_short_transfer() {
212+
test_transfer(8, 0, 1000000, DMA_USAGE_NEVER, short_data_8, short_data_8_rx, SHORT_TRANSFER_FRAMES);
213+
}
214+
215+
void test_8bit_8bit_0_1mhz_short_dma_transfer() {
216+
test_transfer(8, 0, 1000000, DMA_USAGE_OPPORTUNISTIC, short_data_8, short_data_8_rx, SHORT_TRANSFER_FRAMES);
217+
}
218+
219+
void test_8bit_16bit_0_1mhz_short_transfer() {
220+
test_transfer(8, 0, 1000000, DMA_USAGE_NEVER, short_data_16, short_data_16_rx, SHORT_TRANSFER_FRAMES);
221+
}
222+
223+
void test_8bit_16bit_0_1mhz_short_dma_transfer() {
224+
test_transfer(8, 0, 1000000, DMA_USAGE_OPPORTUNISTIC, short_data_16, short_data_16_rx, SHORT_TRANSFER_FRAMES);
225+
}
226+
227+
////////////////////////////////
228+
// Short extended/double transfers
229+
230+
void test_9bit_16bit_0_1mhz_short_transfer() {
231+
test_transfer(9, 0, 1000000, DMA_USAGE_NEVER, short_data_16, short_data_16_rx, SHORT_TRANSFER_FRAMES);
232+
}
233+
234+
void test_9bit_16bit_0_1mhz_short_dma_transfer() {
235+
test_transfer(9, 0, 1000000, DMA_USAGE_OPPORTUNISTIC, short_data_16, short_data_16_rx, SHORT_TRANSFER_FRAMES);
236+
}
237+
238+
void test_9bit_32bit_0_1mhz_short_transfer() {
239+
test_transfer(9, 0, 1000000, DMA_USAGE_NEVER, short_data_32, short_data_32_rx, SHORT_TRANSFER_FRAMES);
240+
}
241+
242+
void test_9bit_32bit_0_1mhz_short_dma_transfer() {
243+
test_transfer(9, 0, 1000000, DMA_USAGE_OPPORTUNISTIC, short_data_32, short_data_32_rx, SHORT_TRANSFER_FRAMES);
244+
}
245+
246+
void test_16bit_16bit_0_1mhz_short_transfer() {
247+
test_transfer(16, 0, 1000000, DMA_USAGE_NEVER, short_data_16, short_data_16_rx, SHORT_TRANSFER_FRAMES);
248+
}
249+
250+
void test_16bit_16bit_0_1mhz_short_dma_transfer() {
251+
test_transfer(16, 0, 1000000, DMA_USAGE_OPPORTUNISTIC, short_data_16, short_data_16_rx, SHORT_TRANSFER_FRAMES);
252+
}
253+
254+
void test_16bit_32bit_0_1mhz_short_transfer() {
255+
test_transfer(16, 0, 1000000, DMA_USAGE_NEVER, short_data_32, short_data_32_rx, SHORT_TRANSFER_FRAMES);
256+
}
257+
258+
void test_16bit_32bit_0_1mhz_short_dma_transfer() {
259+
test_transfer(16, 0, 1000000, DMA_USAGE_OPPORTUNISTIC, short_data_32, short_data_32_rx, SHORT_TRANSFER_FRAMES);
260+
}
261+
262+
////////////////////////////////
263+
// Long single transfers
264+
265+
void test_5bit_8bit_0_1mhz_long_transfer() {
266+
test_transfer(5, 0, 1000000, DMA_USAGE_NEVER, long_data_8, long_data_8_rx, LONG_TRANSFER_FRAMES);
267+
}
268+
269+
void test_5bit_8bit_0_1mhz_long_dma_transfer() {
270+
test_transfer(5, 0, 1000000, DMA_USAGE_OPPORTUNISTIC, long_data_8, long_data_8_rx, LONG_TRANSFER_FRAMES);
271+
}
272+
273+
void test_5bit_16bit_0_1mhz_long_transfer() {
274+
test_transfer(5, 0, 1000000, DMA_USAGE_NEVER, long_data_16, long_data_16_rx, LONG_TRANSFER_FRAMES);
275+
}
276+
277+
void test_5bit_16bit_0_1mhz_long_dma_transfer() {
278+
test_transfer(5, 0, 1000000, DMA_USAGE_OPPORTUNISTIC, long_data_16, long_data_16_rx, LONG_TRANSFER_FRAMES);
279+
}
280+
281+
void test_8bit_8bit_0_1mhz_long_transfer() {
282+
test_transfer(8, 0, 1000000, DMA_USAGE_NEVER, long_data_8, long_data_8_rx, LONG_TRANSFER_FRAMES);
283+
}
284+
285+
void test_8bit_8bit_0_1mhz_long_dma_transfer() {
286+
test_transfer(8, 0, 1000000, DMA_USAGE_OPPORTUNISTIC, long_data_8, long_data_8_rx, LONG_TRANSFER_FRAMES);
287+
}
288+
289+
void test_8bit_16bit_0_1mhz_long_transfer() {
290+
test_transfer(8, 0, 1000000, DMA_USAGE_NEVER, long_data_16, long_data_16_rx, LONG_TRANSFER_FRAMES);
291+
}
292+
293+
void test_8bit_16bit_0_1mhz_long_dma_transfer() {
294+
test_transfer(8, 0, 1000000, DMA_USAGE_OPPORTUNISTIC, long_data_16, long_data_16_rx, LONG_TRANSFER_FRAMES);
295+
}
296+
297+
////////////////////////////////
298+
// Long extended/double transfers
299+
300+
void test_9bit_16bit_0_1mhz_long_transfer() {
301+
test_transfer(9, 0, 1000000, DMA_USAGE_NEVER, long_data_16, long_data_16_rx, LONG_TRANSFER_FRAMES);
302+
}
303+
304+
void test_9bit_16bit_0_1mhz_long_dma_transfer() {
305+
test_transfer(9, 0, 1000000, DMA_USAGE_OPPORTUNISTIC, long_data_16, long_data_16_rx, LONG_TRANSFER_FRAMES);
306+
}
307+
308+
void test_16bit_16bit_0_1mhz_long_transfer() {
309+
test_transfer(16, 0, 1000000, DMA_USAGE_NEVER, long_data_16, long_data_16_rx, LONG_TRANSFER_FRAMES);
310+
}
311+
312+
void test_16bit_16bit_0_1mhz_long_dma_transfer() {
313+
test_transfer(16, 0, 1000000, DMA_USAGE_OPPORTUNISTIC, long_data_16, long_data_16_rx, LONG_TRANSFER_FRAMES);
314+
}
315+
316+
////////////////////////////////
317+
#else
318+
void test_dummy() {
319+
TEST_IGNORE_MESSAGE("This test is not compatible with this target.");
320+
}
321+
#endif
322+
323+
utest::v1::status_t greentea_failure_handler(const Case *const source, const failure_t reason) {
324+
greentea_case_failure_abort_handler(source, reason);
325+
return STATUS_CONTINUE;
326+
}
327+
328+
Case cases[] = {
329+
#if TEST
330+
Case("5-bit frames with 8-bit data, 1 MHz (short)", test_5bit_8bit_0_1mhz_short_transfer, greentea_failure_handler),
331+
Case("5-bit frames with 8-bit data, 1 MHz, DMA (short)", test_5bit_8bit_0_1mhz_short_dma_transfer, greentea_failure_handler),
332+
Case("5-bit frames with 16-bit data, 1 MHz (short)", test_5bit_16bit_0_1mhz_short_transfer, greentea_failure_handler),
333+
Case("5-bit frames with 16-bit data, 1 MHz, DMA (short)", test_5bit_16bit_0_1mhz_short_dma_transfer, greentea_failure_handler),
334+
Case("8-bit frames with 8-bit data, 1 MHz (short)", test_8bit_8bit_0_1mhz_short_transfer, greentea_failure_handler),
335+
Case("8-bit frames with 8-bit data, 1 MHz, DMA (short)", test_8bit_8bit_0_1mhz_short_dma_transfer, greentea_failure_handler),
336+
Case("8-bit frames with 16-bit data, 1 MHz (short)", test_8bit_16bit_0_1mhz_short_transfer, greentea_failure_handler),
337+
Case("8-bit frames with 16-bit data, 1 MHz, DMA (short)", test_8bit_16bit_0_1mhz_short_dma_transfer, greentea_failure_handler),
338+
Case("9-bit frames with 16-bit data, 1 MHz (short)", test_9bit_16bit_0_1mhz_short_transfer, greentea_failure_handler),
339+
Case("9-bit frames with 16-bit data, 1 MHz, DMA (short)", test_9bit_16bit_0_1mhz_short_dma_transfer, greentea_failure_handler),
340+
Case("9-bit frames with 32-bit data, 1 MHz (short)", test_9bit_32bit_0_1mhz_short_transfer, greentea_failure_handler),
341+
Case("9-bit frames with 32-bit data, 1 MHz, DMA (short)", test_9bit_32bit_0_1mhz_short_dma_transfer, greentea_failure_handler),
342+
Case("16-bit frames with 16-bit data, 1 MHz (short)", test_16bit_16bit_0_1mhz_short_transfer, greentea_failure_handler),
343+
Case("16-bit frames with 16-bit data, 1 MHz, DMA (short)", test_16bit_16bit_0_1mhz_short_dma_transfer, greentea_failure_handler),
344+
Case("16-bit frames with 32-bit data, 1 MHz (short)", test_16bit_32bit_0_1mhz_short_transfer, greentea_failure_handler),
345+
Case("16-bit frames with 32-bit data, 1 MHz, DMA (short)", test_16bit_32bit_0_1mhz_short_dma_transfer, greentea_failure_handler),
346+
347+
Case("5-bit frames with 8-bit data, 1 MHz (long)", test_5bit_8bit_0_1mhz_long_transfer, greentea_failure_handler),
348+
Case("5-bit frames with 8-bit data, 1 MHz, DMA (long)", test_5bit_8bit_0_1mhz_long_dma_transfer, greentea_failure_handler),
349+
Case("5-bit frames with 16-bit data, 1 MHz (long)", test_5bit_16bit_0_1mhz_long_transfer, greentea_failure_handler),
350+
Case("5-bit frames with 16-bit data, 1 MHz, DMA (long)", test_5bit_16bit_0_1mhz_long_dma_transfer, greentea_failure_handler),
351+
Case("8-bit frames with 8-bit data, 1 MHz (long)", test_8bit_8bit_0_1mhz_long_transfer, greentea_failure_handler),
352+
Case("8-bit frames with 8-bit data, 1 MHz, DMA (long)", test_8bit_8bit_0_1mhz_long_dma_transfer, greentea_failure_handler),
353+
Case("8-bit frames with 16-bit data, 1 MHz (long)", test_8bit_16bit_0_1mhz_long_transfer, greentea_failure_handler),
354+
Case("8-bit frames with 16-bit data, 1 MHz, DMA (long)", test_8bit_16bit_0_1mhz_long_dma_transfer, greentea_failure_handler),
355+
Case("9-bit frames with 16-bit data, 1 MHz (long)", test_9bit_16bit_0_1mhz_long_transfer, greentea_failure_handler),
356+
Case("9-bit frames with 16-bit data, 1 MHz, DMA (long)", test_9bit_16bit_0_1mhz_long_dma_transfer, greentea_failure_handler),
357+
Case("16-bit frames with 16-bit data, 1 MHz (long)", test_16bit_16bit_0_1mhz_long_transfer, greentea_failure_handler),
358+
Case("16-bit frames with 16-bit data, 1 MHz, DMA (long)", test_16bit_16bit_0_1mhz_long_dma_transfer, greentea_failure_handler),
359+
#else
360+
Case("Dummy case", test_dummy, greentea_failure_handler)
361+
#endif
362+
};
363+
364+
utest::v1::status_t greentea_test_setup(const size_t number_of_cases) {
365+
GREENTEA_SETUP(25, "default_auto");
366+
return greentea_test_setup_handler(number_of_cases);
367+
}
368+
369+
Specification specification(greentea_test_setup, cases, greentea_test_teardown_handler);
370+
371+
int main() {
372+
#if TEST
373+
cs = 1;
374+
cb.attach(callbackFunction);
375+
init_timer();
376+
#endif
377+
Harness::run(specification);
378+
}

0 commit comments

Comments
 (0)