]>
Commit | Line | Data |
---|---|---|
17ff8e18 SG |
1 | /* |
2 | * QTest testcase for Microbit board using the Nordic Semiconductor nRF51 SoC. | |
3 | * | |
4 | * nRF51: | |
5 | * Reference Manual: http://infocenter.nordicsemi.com/pdf/nRF51_RM_v3.0.pdf | |
6 | * Product Spec: http://infocenter.nordicsemi.com/pdf/nRF51822_PS_v3.1.pdf | |
7 | * | |
8 | * Microbit Board: http://microbit.org/ | |
9 | * | |
10 | * Copyright 2018 Steffen Görtz <contrib@steffen-goertz.de> | |
11 | * | |
12 | * This code is licensed under the GPL version 2 or later. See | |
13 | * the COPYING file in the top-level directory. | |
14 | */ | |
15 | ||
16 | ||
17 | #include "qemu/osdep.h" | |
18 | #include "exec/hwaddr.h" | |
19 | #include "libqtest.h" | |
20 | ||
21 | #include "hw/arm/nrf51.h" | |
46a6603b | 22 | #include "hw/char/nrf51_uart.h" |
17ff8e18 | 23 | #include "hw/gpio/nrf51_gpio.h" |
7ec543e4 | 24 | #include "hw/timer/nrf51_timer.h" |
b36356f6 SH |
25 | #include "hw/i2c/microbit_i2c.h" |
26 | ||
46a6603b JS |
27 | static bool uart_wait_for_event(QTestState *qts, uint32_t event_addr) |
28 | { | |
29 | time_t now, start = time(NULL); | |
30 | ||
31 | while (true) { | |
32 | if (qtest_readl(qts, event_addr) == 1) { | |
33 | qtest_writel(qts, event_addr, 0x00); | |
34 | return true; | |
35 | } | |
36 | ||
37 | /* Wait at most 10 minutes */ | |
38 | now = time(NULL); | |
39 | if (now - start > 600) { | |
40 | break; | |
41 | } | |
42 | g_usleep(10000); | |
43 | } | |
44 | ||
45 | return false; | |
46 | } | |
47 | ||
48 | static void uart_rw_to_rxd(QTestState *qts, int sock_fd, const char *in, | |
49 | char *out) | |
50 | { | |
51 | int i, in_len = strlen(in); | |
52 | ||
53 | g_assert_true(write(sock_fd, in, in_len) == in_len); | |
54 | for (i = 0; i < in_len; i++) { | |
55 | g_assert_true(uart_wait_for_event(qts, NRF51_UART_BASE + | |
56 | A_UART_RXDRDY)); | |
57 | out[i] = qtest_readl(qts, NRF51_UART_BASE + A_UART_RXD); | |
58 | } | |
59 | out[i] = '\0'; | |
60 | } | |
61 | ||
62 | static void uart_w_to_txd(QTestState *qts, const char *in) | |
63 | { | |
64 | int i, in_len = strlen(in); | |
65 | ||
66 | for (i = 0; i < in_len; i++) { | |
67 | qtest_writel(qts, NRF51_UART_BASE + A_UART_TXD, in[i]); | |
68 | g_assert_true(uart_wait_for_event(qts, NRF51_UART_BASE + | |
69 | A_UART_TXDRDY)); | |
70 | } | |
71 | } | |
72 | ||
73 | static void test_nrf51_uart(void) | |
74 | { | |
75 | int sock_fd; | |
76 | char s[10]; | |
77 | QTestState *qts = qtest_init_with_serial("-M microbit", &sock_fd); | |
78 | ||
79 | g_assert_true(write(sock_fd, "c", 1) == 1); | |
80 | g_assert_cmphex(qtest_readl(qts, NRF51_UART_BASE + A_UART_RXD), ==, 0x00); | |
81 | ||
82 | qtest_writel(qts, NRF51_UART_BASE + A_UART_ENABLE, 0x04); | |
83 | qtest_writel(qts, NRF51_UART_BASE + A_UART_STARTRX, 0x01); | |
84 | ||
85 | g_assert_true(uart_wait_for_event(qts, NRF51_UART_BASE + A_UART_RXDRDY)); | |
86 | qtest_writel(qts, NRF51_UART_BASE + A_UART_RXDRDY, 0x00); | |
87 | g_assert_cmphex(qtest_readl(qts, NRF51_UART_BASE + A_UART_RXD), ==, 'c'); | |
88 | ||
89 | qtest_writel(qts, NRF51_UART_BASE + A_UART_INTENSET, 0x04); | |
90 | g_assert_cmphex(qtest_readl(qts, NRF51_UART_BASE + A_UART_INTEN), ==, 0x04); | |
91 | qtest_writel(qts, NRF51_UART_BASE + A_UART_INTENCLR, 0x04); | |
92 | g_assert_cmphex(qtest_readl(qts, NRF51_UART_BASE + A_UART_INTEN), ==, 0x00); | |
93 | ||
94 | uart_rw_to_rxd(qts, sock_fd, "hello", s); | |
95 | g_assert_true(memcmp(s, "hello", 5) == 0); | |
96 | ||
97 | qtest_writel(qts, NRF51_UART_BASE + A_UART_STARTTX, 0x01); | |
98 | uart_w_to_txd(qts, "d"); | |
99 | g_assert_true(read(sock_fd, s, 10) == 1); | |
100 | g_assert_cmphex(s[0], ==, 'd'); | |
101 | ||
102 | qtest_writel(qts, NRF51_UART_BASE + A_UART_SUSPEND, 0x01); | |
103 | qtest_writel(qts, NRF51_UART_BASE + A_UART_TXD, 'h'); | |
104 | qtest_writel(qts, NRF51_UART_BASE + A_UART_STARTTX, 0x01); | |
105 | uart_w_to_txd(qts, "world"); | |
106 | g_assert_true(read(sock_fd, s, 10) == 5); | |
107 | g_assert_true(memcmp(s, "world", 5) == 0); | |
108 | ||
109 | close(sock_fd); | |
110 | ||
111 | qtest_quit(qts); | |
112 | } | |
113 | ||
b36356f6 | 114 | /* Read a byte from I2C device at @addr from register @reg */ |
7cf19e73 | 115 | static uint32_t i2c_read_byte(QTestState *qts, uint32_t addr, uint32_t reg) |
b36356f6 SH |
116 | { |
117 | uint32_t val; | |
118 | ||
7cf19e73 JS |
119 | qtest_writel(qts, NRF51_TWI_BASE + NRF51_TWI_REG_ADDRESS, addr); |
120 | qtest_writel(qts, NRF51_TWI_BASE + NRF51_TWI_TASK_STARTTX, 1); | |
121 | qtest_writel(qts, NRF51_TWI_BASE + NRF51_TWI_REG_TXD, reg); | |
122 | val = qtest_readl(qts, NRF51_TWI_BASE + NRF51_TWI_EVENT_TXDSENT); | |
b36356f6 | 123 | g_assert_cmpuint(val, ==, 1); |
7cf19e73 | 124 | qtest_writel(qts, NRF51_TWI_BASE + NRF51_TWI_TASK_STOP, 1); |
b36356f6 | 125 | |
7cf19e73 JS |
126 | qtest_writel(qts, NRF51_TWI_BASE + NRF51_TWI_TASK_STARTRX, 1); |
127 | val = qtest_readl(qts, NRF51_TWI_BASE + NRF51_TWI_EVENT_RXDREADY); | |
b36356f6 | 128 | g_assert_cmpuint(val, ==, 1); |
7cf19e73 JS |
129 | val = qtest_readl(qts, NRF51_TWI_BASE + NRF51_TWI_REG_RXD); |
130 | qtest_writel(qts, NRF51_TWI_BASE + NRF51_TWI_TASK_STOP, 1); | |
b36356f6 SH |
131 | |
132 | return val; | |
133 | } | |
134 | ||
135 | static void test_microbit_i2c(void) | |
136 | { | |
137 | uint32_t val; | |
7cf19e73 | 138 | QTestState *qts = qtest_init("-M microbit"); |
b36356f6 SH |
139 | |
140 | /* We don't program pins/irqs but at least enable the device */ | |
7cf19e73 | 141 | qtest_writel(qts, NRF51_TWI_BASE + NRF51_TWI_REG_ENABLE, 5); |
b36356f6 SH |
142 | |
143 | /* MMA8653 magnetometer detection */ | |
7cf19e73 | 144 | val = i2c_read_byte(qts, 0x3A, 0x0D); |
b36356f6 SH |
145 | g_assert_cmpuint(val, ==, 0x5A); |
146 | ||
7cf19e73 | 147 | val = i2c_read_byte(qts, 0x3A, 0x0D); |
b36356f6 SH |
148 | g_assert_cmpuint(val, ==, 0x5A); |
149 | ||
150 | /* LSM303 accelerometer detection */ | |
7cf19e73 | 151 | val = i2c_read_byte(qts, 0x3C, 0x4F); |
b36356f6 SH |
152 | g_assert_cmpuint(val, ==, 0x40); |
153 | ||
7cf19e73 JS |
154 | qtest_writel(qts, NRF51_TWI_BASE + NRF51_TWI_REG_ENABLE, 0); |
155 | ||
156 | qtest_quit(qts); | |
b36356f6 | 157 | } |
17ff8e18 SG |
158 | |
159 | static void test_nrf51_gpio(void) | |
160 | { | |
161 | size_t i; | |
162 | uint32_t actual, expected; | |
163 | ||
164 | struct { | |
165 | hwaddr addr; | |
166 | uint32_t expected; | |
167 | } const reset_state[] = { | |
168 | {NRF51_GPIO_REG_OUT, 0x00000000}, {NRF51_GPIO_REG_OUTSET, 0x00000000}, | |
169 | {NRF51_GPIO_REG_OUTCLR, 0x00000000}, {NRF51_GPIO_REG_IN, 0x00000000}, | |
170 | {NRF51_GPIO_REG_DIR, 0x00000000}, {NRF51_GPIO_REG_DIRSET, 0x00000000}, | |
171 | {NRF51_GPIO_REG_DIRCLR, 0x00000000} | |
172 | }; | |
173 | ||
7cf19e73 JS |
174 | QTestState *qts = qtest_init("-M microbit"); |
175 | ||
17ff8e18 SG |
176 | /* Check reset state */ |
177 | for (i = 0; i < ARRAY_SIZE(reset_state); i++) { | |
178 | expected = reset_state[i].expected; | |
7cf19e73 | 179 | actual = qtest_readl(qts, NRF51_GPIO_BASE + reset_state[i].addr); |
17ff8e18 SG |
180 | g_assert_cmpuint(actual, ==, expected); |
181 | } | |
182 | ||
183 | for (i = 0; i < NRF51_GPIO_PINS; i++) { | |
184 | expected = 0x00000002; | |
7cf19e73 JS |
185 | actual = qtest_readl(qts, NRF51_GPIO_BASE + |
186 | NRF51_GPIO_REG_CNF_START + i * 4); | |
17ff8e18 SG |
187 | g_assert_cmpuint(actual, ==, expected); |
188 | } | |
189 | ||
190 | /* Check dir bit consistency between dir and cnf */ | |
191 | /* Check set via DIRSET */ | |
192 | expected = 0x80000001; | |
7cf19e73 JS |
193 | qtest_writel(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_DIRSET, expected); |
194 | actual = qtest_readl(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_DIR); | |
17ff8e18 | 195 | g_assert_cmpuint(actual, ==, expected); |
7cf19e73 JS |
196 | actual = qtest_readl(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_CNF_START) |
197 | & 0x01; | |
17ff8e18 | 198 | g_assert_cmpuint(actual, ==, 0x01); |
7cf19e73 | 199 | actual = qtest_readl(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_CNF_END) & 0x01; |
17ff8e18 SG |
200 | g_assert_cmpuint(actual, ==, 0x01); |
201 | ||
202 | /* Check clear via DIRCLR */ | |
7cf19e73 JS |
203 | qtest_writel(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_DIRCLR, 0x80000001); |
204 | actual = qtest_readl(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_DIR); | |
17ff8e18 | 205 | g_assert_cmpuint(actual, ==, 0x00000000); |
7cf19e73 JS |
206 | actual = qtest_readl(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_CNF_START) |
207 | & 0x01; | |
17ff8e18 | 208 | g_assert_cmpuint(actual, ==, 0x00); |
7cf19e73 | 209 | actual = qtest_readl(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_CNF_END) & 0x01; |
17ff8e18 SG |
210 | g_assert_cmpuint(actual, ==, 0x00); |
211 | ||
212 | /* Check set via DIR */ | |
213 | expected = 0x80000001; | |
7cf19e73 JS |
214 | qtest_writel(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_DIR, expected); |
215 | actual = qtest_readl(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_DIR); | |
17ff8e18 | 216 | g_assert_cmpuint(actual, ==, expected); |
7cf19e73 JS |
217 | actual = qtest_readl(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_CNF_START) |
218 | & 0x01; | |
17ff8e18 | 219 | g_assert_cmpuint(actual, ==, 0x01); |
7cf19e73 | 220 | actual = qtest_readl(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_CNF_END) & 0x01; |
17ff8e18 SG |
221 | g_assert_cmpuint(actual, ==, 0x01); |
222 | ||
223 | /* Reset DIR */ | |
7cf19e73 | 224 | qtest_writel(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_DIR, 0x00000000); |
17ff8e18 SG |
225 | |
226 | /* Check Input propagates */ | |
7cf19e73 JS |
227 | qtest_writel(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_CNF_START, 0x00); |
228 | qtest_set_irq_in(qts, "/machine/nrf51", "unnamed-gpio-in", 0, 0); | |
229 | actual = qtest_readl(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_IN) & 0x01; | |
17ff8e18 | 230 | g_assert_cmpuint(actual, ==, 0x00); |
7cf19e73 JS |
231 | qtest_set_irq_in(qts, "/machine/nrf51", "unnamed-gpio-in", 0, 1); |
232 | actual = qtest_readl(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_IN) & 0x01; | |
17ff8e18 | 233 | g_assert_cmpuint(actual, ==, 0x01); |
7cf19e73 JS |
234 | qtest_set_irq_in(qts, "/machine/nrf51", "unnamed-gpio-in", 0, -1); |
235 | actual = qtest_readl(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_IN) & 0x01; | |
17ff8e18 | 236 | g_assert_cmpuint(actual, ==, 0x01); |
7cf19e73 | 237 | qtest_writel(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_CNF_START, 0x02); |
17ff8e18 SG |
238 | |
239 | /* Check pull-up working */ | |
7cf19e73 JS |
240 | qtest_set_irq_in(qts, "/machine/nrf51", "unnamed-gpio-in", 0, 0); |
241 | qtest_writel(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_CNF_START, 0b0000); | |
242 | actual = qtest_readl(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_IN) & 0x01; | |
17ff8e18 | 243 | g_assert_cmpuint(actual, ==, 0x00); |
7cf19e73 JS |
244 | qtest_writel(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_CNF_START, 0b1110); |
245 | actual = qtest_readl(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_IN) & 0x01; | |
17ff8e18 | 246 | g_assert_cmpuint(actual, ==, 0x01); |
7cf19e73 | 247 | qtest_writel(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_CNF_START, 0x02); |
17ff8e18 SG |
248 | |
249 | /* Check pull-down working */ | |
7cf19e73 JS |
250 | qtest_set_irq_in(qts, "/machine/nrf51", "unnamed-gpio-in", 0, 1); |
251 | qtest_writel(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_CNF_START, 0b0000); | |
252 | actual = qtest_readl(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_IN) & 0x01; | |
17ff8e18 | 253 | g_assert_cmpuint(actual, ==, 0x01); |
7cf19e73 JS |
254 | qtest_writel(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_CNF_START, 0b0110); |
255 | actual = qtest_readl(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_IN) & 0x01; | |
17ff8e18 | 256 | g_assert_cmpuint(actual, ==, 0x00); |
7cf19e73 JS |
257 | qtest_writel(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_CNF_START, 0x02); |
258 | qtest_set_irq_in(qts, "/machine/nrf51", "unnamed-gpio-in", 0, -1); | |
17ff8e18 SG |
259 | |
260 | /* Check Output propagates */ | |
7cf19e73 JS |
261 | qtest_irq_intercept_out(qts, "/machine/nrf51"); |
262 | qtest_writel(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_CNF_START, 0b0011); | |
263 | qtest_writel(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_OUTSET, 0x01); | |
264 | g_assert_true(qtest_get_irq(qts, 0)); | |
265 | qtest_writel(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_OUTCLR, 0x01); | |
266 | g_assert_false(qtest_get_irq(qts, 0)); | |
17ff8e18 SG |
267 | |
268 | /* Check self-stimulation */ | |
7cf19e73 JS |
269 | qtest_writel(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_CNF_START, 0b01); |
270 | qtest_writel(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_OUTSET, 0x01); | |
271 | actual = qtest_readl(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_IN) & 0x01; | |
17ff8e18 SG |
272 | g_assert_cmpuint(actual, ==, 0x01); |
273 | ||
7cf19e73 JS |
274 | qtest_writel(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_OUTCLR, 0x01); |
275 | actual = qtest_readl(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_IN) & 0x01; | |
17ff8e18 SG |
276 | g_assert_cmpuint(actual, ==, 0x00); |
277 | ||
278 | /* | |
279 | * Check short-circuit - generates an guest_error which must be checked | |
280 | * manually as long as qtest can not scan qemu_log messages | |
281 | */ | |
7cf19e73 JS |
282 | qtest_writel(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_CNF_START, 0b01); |
283 | qtest_writel(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_OUTSET, 0x01); | |
284 | qtest_set_irq_in(qts, "/machine/nrf51", "unnamed-gpio-in", 0, 0); | |
285 | ||
286 | qtest_quit(qts); | |
17ff8e18 SG |
287 | } |
288 | ||
7cf19e73 | 289 | static void timer_task(QTestState *qts, hwaddr task) |
7ec543e4 | 290 | { |
7cf19e73 | 291 | qtest_writel(qts, NRF51_TIMER_BASE + task, NRF51_TRIGGER_TASK); |
7ec543e4 SG |
292 | } |
293 | ||
7cf19e73 | 294 | static void timer_clear_event(QTestState *qts, hwaddr event) |
7ec543e4 | 295 | { |
7cf19e73 | 296 | qtest_writel(qts, NRF51_TIMER_BASE + event, NRF51_EVENT_CLEAR); |
7ec543e4 SG |
297 | } |
298 | ||
7cf19e73 | 299 | static void timer_set_bitmode(QTestState *qts, uint8_t mode) |
7ec543e4 | 300 | { |
7cf19e73 | 301 | qtest_writel(qts, NRF51_TIMER_BASE + NRF51_TIMER_REG_BITMODE, mode); |
7ec543e4 SG |
302 | } |
303 | ||
7cf19e73 | 304 | static void timer_set_prescaler(QTestState *qts, uint8_t prescaler) |
7ec543e4 | 305 | { |
7cf19e73 | 306 | qtest_writel(qts, NRF51_TIMER_BASE + NRF51_TIMER_REG_PRESCALER, prescaler); |
7ec543e4 SG |
307 | } |
308 | ||
7cf19e73 | 309 | static void timer_set_cc(QTestState *qts, size_t idx, uint32_t value) |
7ec543e4 | 310 | { |
7cf19e73 | 311 | qtest_writel(qts, NRF51_TIMER_BASE + NRF51_TIMER_REG_CC0 + idx * 4, value); |
7ec543e4 SG |
312 | } |
313 | ||
7cf19e73 JS |
314 | static void timer_assert_events(QTestState *qts, uint32_t ev0, uint32_t ev1, |
315 | uint32_t ev2, uint32_t ev3) | |
7ec543e4 | 316 | { |
7cf19e73 JS |
317 | g_assert(qtest_readl(qts, NRF51_TIMER_BASE + NRF51_TIMER_EVENT_COMPARE_0) |
318 | == ev0); | |
319 | g_assert(qtest_readl(qts, NRF51_TIMER_BASE + NRF51_TIMER_EVENT_COMPARE_1) | |
320 | == ev1); | |
321 | g_assert(qtest_readl(qts, NRF51_TIMER_BASE + NRF51_TIMER_EVENT_COMPARE_2) | |
322 | == ev2); | |
323 | g_assert(qtest_readl(qts, NRF51_TIMER_BASE + NRF51_TIMER_EVENT_COMPARE_3) | |
324 | == ev3); | |
7ec543e4 SG |
325 | } |
326 | ||
327 | static void test_nrf51_timer(void) | |
328 | { | |
329 | uint32_t steps_to_overflow = 408; | |
7cf19e73 | 330 | QTestState *qts = qtest_init("-M microbit"); |
7ec543e4 SG |
331 | |
332 | /* Compare Match */ | |
7cf19e73 JS |
333 | timer_task(qts, NRF51_TIMER_TASK_STOP); |
334 | timer_task(qts, NRF51_TIMER_TASK_CLEAR); | |
7ec543e4 | 335 | |
7cf19e73 JS |
336 | timer_clear_event(qts, NRF51_TIMER_EVENT_COMPARE_0); |
337 | timer_clear_event(qts, NRF51_TIMER_EVENT_COMPARE_1); | |
338 | timer_clear_event(qts, NRF51_TIMER_EVENT_COMPARE_2); | |
339 | timer_clear_event(qts, NRF51_TIMER_EVENT_COMPARE_3); | |
7ec543e4 | 340 | |
7cf19e73 JS |
341 | timer_set_bitmode(qts, NRF51_TIMER_WIDTH_16); /* 16 MHz Timer */ |
342 | timer_set_prescaler(qts, 0); | |
7ec543e4 | 343 | /* Swept over in first step */ |
7cf19e73 | 344 | timer_set_cc(qts, 0, 2); |
7ec543e4 | 345 | /* Barely miss on first step */ |
7cf19e73 | 346 | timer_set_cc(qts, 1, 162); |
7ec543e4 | 347 | /* Spot on on third step */ |
7cf19e73 | 348 | timer_set_cc(qts, 2, 480); |
7ec543e4 | 349 | |
7cf19e73 | 350 | timer_assert_events(qts, 0, 0, 0, 0); |
7ec543e4 | 351 | |
7cf19e73 JS |
352 | timer_task(qts, NRF51_TIMER_TASK_START); |
353 | qtest_clock_step(qts, 10000); | |
354 | timer_assert_events(qts, 1, 0, 0, 0); | |
7ec543e4 SG |
355 | |
356 | /* Swept over on first overflow */ | |
7cf19e73 | 357 | timer_set_cc(qts, 3, 114); |
7ec543e4 | 358 | |
7cf19e73 JS |
359 | qtest_clock_step(qts, 10000); |
360 | timer_assert_events(qts, 1, 1, 0, 0); | |
7ec543e4 | 361 | |
7cf19e73 JS |
362 | qtest_clock_step(qts, 10000); |
363 | timer_assert_events(qts, 1, 1, 1, 0); | |
7ec543e4 SG |
364 | |
365 | /* Wrap time until internal counter overflows */ | |
366 | while (steps_to_overflow--) { | |
7cf19e73 JS |
367 | timer_assert_events(qts, 1, 1, 1, 0); |
368 | qtest_clock_step(qts, 10000); | |
7ec543e4 SG |
369 | } |
370 | ||
7cf19e73 | 371 | timer_assert_events(qts, 1, 1, 1, 1); |
7ec543e4 | 372 | |
7cf19e73 JS |
373 | timer_clear_event(qts, NRF51_TIMER_EVENT_COMPARE_0); |
374 | timer_clear_event(qts, NRF51_TIMER_EVENT_COMPARE_1); | |
375 | timer_clear_event(qts, NRF51_TIMER_EVENT_COMPARE_2); | |
376 | timer_clear_event(qts, NRF51_TIMER_EVENT_COMPARE_3); | |
377 | timer_assert_events(qts, 0, 0, 0, 0); | |
7ec543e4 | 378 | |
7cf19e73 | 379 | timer_task(qts, NRF51_TIMER_TASK_STOP); |
7ec543e4 SG |
380 | |
381 | /* Test Proposal: Stop/Shutdown */ | |
382 | /* Test Proposal: Shortcut Compare -> Clear */ | |
383 | /* Test Proposal: Shortcut Compare -> Stop */ | |
384 | /* Test Proposal: Counter Mode */ | |
7cf19e73 JS |
385 | |
386 | qtest_quit(qts); | |
7ec543e4 SG |
387 | } |
388 | ||
17ff8e18 SG |
389 | int main(int argc, char **argv) |
390 | { | |
17ff8e18 SG |
391 | g_test_init(&argc, &argv, NULL); |
392 | ||
46a6603b | 393 | qtest_add_func("/microbit/nrf51/uart", test_nrf51_uart); |
17ff8e18 | 394 | qtest_add_func("/microbit/nrf51/gpio", test_nrf51_gpio); |
7ec543e4 | 395 | qtest_add_func("/microbit/nrf51/timer", test_nrf51_timer); |
b36356f6 | 396 | qtest_add_func("/microbit/microbit/i2c", test_microbit_i2c); |
17ff8e18 | 397 | |
7cf19e73 | 398 | return g_test_run(); |
17ff8e18 | 399 | } |