Steffen Görtz | 17ff8e1 | 2019-01-07 15:23:47 +0000 | [diff] [blame] | 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" |
Marc-André Lureau | 907b510 | 2022-03-30 13:39:05 +0400 | [diff] [blame] | 19 | #include "libqtest.h" |
Steffen Görtz | 17ff8e1 | 2019-01-07 15:23:47 +0000 | [diff] [blame] | 20 | |
| 21 | #include "hw/arm/nrf51.h" |
Julia Suvorova | 46a6603 | 2019-01-29 11:46:04 +0000 | [diff] [blame] | 22 | #include "hw/char/nrf51_uart.h" |
Steffen Görtz | 17ff8e1 | 2019-01-07 15:23:47 +0000 | [diff] [blame] | 23 | #include "hw/gpio/nrf51_gpio.h" |
Steffen Görtz | 7743b70 | 2019-02-01 10:33:57 +0800 | [diff] [blame] | 24 | #include "hw/nvram/nrf51_nvm.h" |
Steffen Görtz | 7ec543e | 2019-01-07 15:23:47 +0000 | [diff] [blame] | 25 | #include "hw/timer/nrf51_timer.h" |
Stefan Hajnoczi | b36356f | 2019-01-29 11:46:03 +0000 | [diff] [blame] | 26 | #include "hw/i2c/microbit_i2c.h" |
| 27 | |
Julia Suvorova | 46a6603 | 2019-01-29 11:46:04 +0000 | [diff] [blame] | 28 | static bool uart_wait_for_event(QTestState *qts, uint32_t event_addr) |
| 29 | { |
| 30 | time_t now, start = time(NULL); |
| 31 | |
| 32 | while (true) { |
| 33 | if (qtest_readl(qts, event_addr) == 1) { |
| 34 | qtest_writel(qts, event_addr, 0x00); |
| 35 | return true; |
| 36 | } |
| 37 | |
| 38 | /* Wait at most 10 minutes */ |
| 39 | now = time(NULL); |
| 40 | if (now - start > 600) { |
| 41 | break; |
| 42 | } |
| 43 | g_usleep(10000); |
| 44 | } |
| 45 | |
| 46 | return false; |
| 47 | } |
| 48 | |
| 49 | static void uart_rw_to_rxd(QTestState *qts, int sock_fd, const char *in, |
| 50 | char *out) |
| 51 | { |
| 52 | int i, in_len = strlen(in); |
| 53 | |
Bin Meng | e6f59e4 | 2022-09-25 19:30:22 +0800 | [diff] [blame] | 54 | g_assert_true(send(sock_fd, in, in_len, 0) == in_len); |
Julia Suvorova | 46a6603 | 2019-01-29 11:46:04 +0000 | [diff] [blame] | 55 | for (i = 0; i < in_len; i++) { |
| 56 | g_assert_true(uart_wait_for_event(qts, NRF51_UART_BASE + |
| 57 | A_UART_RXDRDY)); |
| 58 | out[i] = qtest_readl(qts, NRF51_UART_BASE + A_UART_RXD); |
| 59 | } |
| 60 | out[i] = '\0'; |
| 61 | } |
| 62 | |
| 63 | static void uart_w_to_txd(QTestState *qts, const char *in) |
| 64 | { |
| 65 | int i, in_len = strlen(in); |
| 66 | |
| 67 | for (i = 0; i < in_len; i++) { |
| 68 | qtest_writel(qts, NRF51_UART_BASE + A_UART_TXD, in[i]); |
| 69 | g_assert_true(uart_wait_for_event(qts, NRF51_UART_BASE + |
| 70 | A_UART_TXDRDY)); |
| 71 | } |
| 72 | } |
| 73 | |
| 74 | static void test_nrf51_uart(void) |
| 75 | { |
| 76 | int sock_fd; |
| 77 | char s[10]; |
| 78 | QTestState *qts = qtest_init_with_serial("-M microbit", &sock_fd); |
| 79 | |
Bin Meng | e6f59e4 | 2022-09-25 19:30:22 +0800 | [diff] [blame] | 80 | g_assert_true(send(sock_fd, "c", 1, 0) == 1); |
Julia Suvorova | 46a6603 | 2019-01-29 11:46:04 +0000 | [diff] [blame] | 81 | g_assert_cmphex(qtest_readl(qts, NRF51_UART_BASE + A_UART_RXD), ==, 0x00); |
| 82 | |
| 83 | qtest_writel(qts, NRF51_UART_BASE + A_UART_ENABLE, 0x04); |
| 84 | qtest_writel(qts, NRF51_UART_BASE + A_UART_STARTRX, 0x01); |
| 85 | |
| 86 | g_assert_true(uart_wait_for_event(qts, NRF51_UART_BASE + A_UART_RXDRDY)); |
| 87 | qtest_writel(qts, NRF51_UART_BASE + A_UART_RXDRDY, 0x00); |
| 88 | g_assert_cmphex(qtest_readl(qts, NRF51_UART_BASE + A_UART_RXD), ==, 'c'); |
| 89 | |
| 90 | qtest_writel(qts, NRF51_UART_BASE + A_UART_INTENSET, 0x04); |
| 91 | g_assert_cmphex(qtest_readl(qts, NRF51_UART_BASE + A_UART_INTEN), ==, 0x04); |
| 92 | qtest_writel(qts, NRF51_UART_BASE + A_UART_INTENCLR, 0x04); |
| 93 | g_assert_cmphex(qtest_readl(qts, NRF51_UART_BASE + A_UART_INTEN), ==, 0x00); |
| 94 | |
| 95 | uart_rw_to_rxd(qts, sock_fd, "hello", s); |
| 96 | g_assert_true(memcmp(s, "hello", 5) == 0); |
| 97 | |
| 98 | qtest_writel(qts, NRF51_UART_BASE + A_UART_STARTTX, 0x01); |
| 99 | uart_w_to_txd(qts, "d"); |
Bin Meng | e6f59e4 | 2022-09-25 19:30:22 +0800 | [diff] [blame] | 100 | g_assert_true(recv(sock_fd, s, 10, 0) == 1); |
Julia Suvorova | 46a6603 | 2019-01-29 11:46:04 +0000 | [diff] [blame] | 101 | g_assert_cmphex(s[0], ==, 'd'); |
| 102 | |
| 103 | qtest_writel(qts, NRF51_UART_BASE + A_UART_SUSPEND, 0x01); |
| 104 | qtest_writel(qts, NRF51_UART_BASE + A_UART_TXD, 'h'); |
| 105 | qtest_writel(qts, NRF51_UART_BASE + A_UART_STARTTX, 0x01); |
| 106 | uart_w_to_txd(qts, "world"); |
Bin Meng | e6f59e4 | 2022-09-25 19:30:22 +0800 | [diff] [blame] | 107 | g_assert_true(recv(sock_fd, s, 10, 0) == 5); |
Julia Suvorova | 46a6603 | 2019-01-29 11:46:04 +0000 | [diff] [blame] | 108 | g_assert_true(memcmp(s, "world", 5) == 0); |
| 109 | |
Bin Meng | e6f59e4 | 2022-09-25 19:30:22 +0800 | [diff] [blame] | 110 | closesocket(sock_fd); |
Julia Suvorova | 46a6603 | 2019-01-29 11:46:04 +0000 | [diff] [blame] | 111 | |
| 112 | qtest_quit(qts); |
| 113 | } |
| 114 | |
Stefan Hajnoczi | b36356f | 2019-01-29 11:46:03 +0000 | [diff] [blame] | 115 | /* Read a byte from I2C device at @addr from register @reg */ |
Julia Suvorova | 7cf19e7 | 2019-01-29 11:46:04 +0000 | [diff] [blame] | 116 | static uint32_t i2c_read_byte(QTestState *qts, uint32_t addr, uint32_t reg) |
Stefan Hajnoczi | b36356f | 2019-01-29 11:46:03 +0000 | [diff] [blame] | 117 | { |
| 118 | uint32_t val; |
| 119 | |
Julia Suvorova | 7cf19e7 | 2019-01-29 11:46:04 +0000 | [diff] [blame] | 120 | qtest_writel(qts, NRF51_TWI_BASE + NRF51_TWI_REG_ADDRESS, addr); |
| 121 | qtest_writel(qts, NRF51_TWI_BASE + NRF51_TWI_TASK_STARTTX, 1); |
| 122 | qtest_writel(qts, NRF51_TWI_BASE + NRF51_TWI_REG_TXD, reg); |
| 123 | val = qtest_readl(qts, NRF51_TWI_BASE + NRF51_TWI_EVENT_TXDSENT); |
Stefan Hajnoczi | b36356f | 2019-01-29 11:46:03 +0000 | [diff] [blame] | 124 | g_assert_cmpuint(val, ==, 1); |
Julia Suvorova | 7cf19e7 | 2019-01-29 11:46:04 +0000 | [diff] [blame] | 125 | qtest_writel(qts, NRF51_TWI_BASE + NRF51_TWI_TASK_STOP, 1); |
Stefan Hajnoczi | b36356f | 2019-01-29 11:46:03 +0000 | [diff] [blame] | 126 | |
Julia Suvorova | 7cf19e7 | 2019-01-29 11:46:04 +0000 | [diff] [blame] | 127 | qtest_writel(qts, NRF51_TWI_BASE + NRF51_TWI_TASK_STARTRX, 1); |
| 128 | val = qtest_readl(qts, NRF51_TWI_BASE + NRF51_TWI_EVENT_RXDREADY); |
Stefan Hajnoczi | b36356f | 2019-01-29 11:46:03 +0000 | [diff] [blame] | 129 | g_assert_cmpuint(val, ==, 1); |
Julia Suvorova | 7cf19e7 | 2019-01-29 11:46:04 +0000 | [diff] [blame] | 130 | val = qtest_readl(qts, NRF51_TWI_BASE + NRF51_TWI_REG_RXD); |
| 131 | qtest_writel(qts, NRF51_TWI_BASE + NRF51_TWI_TASK_STOP, 1); |
Stefan Hajnoczi | b36356f | 2019-01-29 11:46:03 +0000 | [diff] [blame] | 132 | |
| 133 | return val; |
| 134 | } |
| 135 | |
| 136 | static void test_microbit_i2c(void) |
| 137 | { |
| 138 | uint32_t val; |
Julia Suvorova | 7cf19e7 | 2019-01-29 11:46:04 +0000 | [diff] [blame] | 139 | QTestState *qts = qtest_init("-M microbit"); |
Stefan Hajnoczi | b36356f | 2019-01-29 11:46:03 +0000 | [diff] [blame] | 140 | |
| 141 | /* We don't program pins/irqs but at least enable the device */ |
Julia Suvorova | 7cf19e7 | 2019-01-29 11:46:04 +0000 | [diff] [blame] | 142 | qtest_writel(qts, NRF51_TWI_BASE + NRF51_TWI_REG_ENABLE, 5); |
Stefan Hajnoczi | b36356f | 2019-01-29 11:46:03 +0000 | [diff] [blame] | 143 | |
| 144 | /* MMA8653 magnetometer detection */ |
Julia Suvorova | 7cf19e7 | 2019-01-29 11:46:04 +0000 | [diff] [blame] | 145 | val = i2c_read_byte(qts, 0x3A, 0x0D); |
Stefan Hajnoczi | b36356f | 2019-01-29 11:46:03 +0000 | [diff] [blame] | 146 | g_assert_cmpuint(val, ==, 0x5A); |
| 147 | |
Julia Suvorova | 7cf19e7 | 2019-01-29 11:46:04 +0000 | [diff] [blame] | 148 | val = i2c_read_byte(qts, 0x3A, 0x0D); |
Stefan Hajnoczi | b36356f | 2019-01-29 11:46:03 +0000 | [diff] [blame] | 149 | g_assert_cmpuint(val, ==, 0x5A); |
| 150 | |
| 151 | /* LSM303 accelerometer detection */ |
Julia Suvorova | 7cf19e7 | 2019-01-29 11:46:04 +0000 | [diff] [blame] | 152 | val = i2c_read_byte(qts, 0x3C, 0x4F); |
Stefan Hajnoczi | b36356f | 2019-01-29 11:46:03 +0000 | [diff] [blame] | 153 | g_assert_cmpuint(val, ==, 0x40); |
| 154 | |
Julia Suvorova | 7cf19e7 | 2019-01-29 11:46:04 +0000 | [diff] [blame] | 155 | qtest_writel(qts, NRF51_TWI_BASE + NRF51_TWI_REG_ENABLE, 0); |
| 156 | |
| 157 | qtest_quit(qts); |
Stefan Hajnoczi | b36356f | 2019-01-29 11:46:03 +0000 | [diff] [blame] | 158 | } |
Steffen Görtz | 17ff8e1 | 2019-01-07 15:23:47 +0000 | [diff] [blame] | 159 | |
Steffen Görtz | 7743b70 | 2019-02-01 10:33:57 +0800 | [diff] [blame] | 160 | #define FLASH_SIZE (256 * NRF51_PAGE_SIZE) |
| 161 | |
| 162 | static void fill_and_erase(QTestState *qts, hwaddr base, hwaddr size, |
| 163 | uint32_t address_reg) |
| 164 | { |
| 165 | hwaddr i; |
| 166 | |
| 167 | /* Erase Page */ |
| 168 | qtest_writel(qts, NRF51_NVMC_BASE + NRF51_NVMC_CONFIG, 0x02); |
| 169 | qtest_writel(qts, NRF51_NVMC_BASE + address_reg, base); |
| 170 | qtest_writel(qts, NRF51_NVMC_BASE + NRF51_NVMC_CONFIG, 0x00); |
| 171 | |
| 172 | /* Check memory */ |
| 173 | for (i = 0; i < size / 4; i++) { |
| 174 | g_assert_cmpuint(qtest_readl(qts, base + i * 4), ==, 0xFFFFFFFF); |
| 175 | } |
| 176 | |
| 177 | /* Fill memory */ |
| 178 | qtest_writel(qts, NRF51_NVMC_BASE + NRF51_NVMC_CONFIG, 0x01); |
| 179 | for (i = 0; i < size / 4; i++) { |
| 180 | qtest_writel(qts, base + i * 4, i); |
| 181 | g_assert_cmpuint(qtest_readl(qts, base + i * 4), ==, i); |
| 182 | } |
| 183 | qtest_writel(qts, NRF51_NVMC_BASE + NRF51_NVMC_CONFIG, 0x00); |
| 184 | } |
| 185 | |
| 186 | static void test_nrf51_nvmc(void) |
| 187 | { |
| 188 | uint32_t value; |
| 189 | hwaddr i; |
| 190 | QTestState *qts = qtest_init("-M microbit"); |
| 191 | |
| 192 | /* Test always ready */ |
| 193 | value = qtest_readl(qts, NRF51_NVMC_BASE + NRF51_NVMC_READY); |
| 194 | g_assert_cmpuint(value & 0x01, ==, 0x01); |
| 195 | |
| 196 | /* Test write-read config register */ |
| 197 | qtest_writel(qts, NRF51_NVMC_BASE + NRF51_NVMC_CONFIG, 0x03); |
| 198 | g_assert_cmpuint(qtest_readl(qts, NRF51_NVMC_BASE + NRF51_NVMC_CONFIG), |
| 199 | ==, 0x03); |
| 200 | qtest_writel(qts, NRF51_NVMC_BASE + NRF51_NVMC_CONFIG, 0x00); |
| 201 | g_assert_cmpuint(qtest_readl(qts, NRF51_NVMC_BASE + NRF51_NVMC_CONFIG), |
| 202 | ==, 0x00); |
| 203 | |
| 204 | /* Test PCR0 */ |
| 205 | fill_and_erase(qts, NRF51_FLASH_BASE, NRF51_PAGE_SIZE, |
| 206 | NRF51_NVMC_ERASEPCR0); |
| 207 | fill_and_erase(qts, NRF51_FLASH_BASE + NRF51_PAGE_SIZE, |
| 208 | NRF51_PAGE_SIZE, NRF51_NVMC_ERASEPCR0); |
| 209 | |
| 210 | /* Test PCR1 */ |
| 211 | fill_and_erase(qts, NRF51_FLASH_BASE, NRF51_PAGE_SIZE, |
| 212 | NRF51_NVMC_ERASEPCR1); |
| 213 | fill_and_erase(qts, NRF51_FLASH_BASE + NRF51_PAGE_SIZE, |
| 214 | NRF51_PAGE_SIZE, NRF51_NVMC_ERASEPCR1); |
| 215 | |
| 216 | /* Erase all */ |
| 217 | qtest_writel(qts, NRF51_NVMC_BASE + NRF51_NVMC_CONFIG, 0x02); |
| 218 | qtest_writel(qts, NRF51_NVMC_BASE + NRF51_NVMC_ERASEALL, 0x01); |
| 219 | qtest_writel(qts, NRF51_NVMC_BASE + NRF51_NVMC_CONFIG, 0x00); |
| 220 | |
| 221 | qtest_writel(qts, NRF51_NVMC_BASE + NRF51_NVMC_CONFIG, 0x01); |
| 222 | for (i = 0; i < FLASH_SIZE / 4; i++) { |
| 223 | qtest_writel(qts, NRF51_FLASH_BASE + i * 4, i); |
| 224 | g_assert_cmpuint(qtest_readl(qts, NRF51_FLASH_BASE + i * 4), ==, i); |
| 225 | } |
| 226 | qtest_writel(qts, NRF51_NVMC_BASE + NRF51_NVMC_CONFIG, 0x00); |
| 227 | |
| 228 | qtest_writel(qts, NRF51_NVMC_BASE + NRF51_NVMC_CONFIG, 0x02); |
| 229 | qtest_writel(qts, NRF51_NVMC_BASE + NRF51_NVMC_ERASEALL, 0x01); |
| 230 | qtest_writel(qts, NRF51_NVMC_BASE + NRF51_NVMC_CONFIG, 0x00); |
| 231 | |
| 232 | for (i = 0; i < FLASH_SIZE / 4; i++) { |
| 233 | g_assert_cmpuint(qtest_readl(qts, NRF51_FLASH_BASE + i * 4), |
| 234 | ==, 0xFFFFFFFF); |
| 235 | } |
| 236 | |
| 237 | /* Erase UICR */ |
| 238 | qtest_writel(qts, NRF51_NVMC_BASE + NRF51_NVMC_CONFIG, 0x02); |
| 239 | qtest_writel(qts, NRF51_NVMC_BASE + NRF51_NVMC_ERASEUICR, 0x01); |
| 240 | qtest_writel(qts, NRF51_NVMC_BASE + NRF51_NVMC_CONFIG, 0x00); |
| 241 | |
| 242 | for (i = 0; i < NRF51_UICR_SIZE / 4; i++) { |
| 243 | g_assert_cmpuint(qtest_readl(qts, NRF51_UICR_BASE + i * 4), |
| 244 | ==, 0xFFFFFFFF); |
| 245 | } |
| 246 | |
| 247 | qtest_writel(qts, NRF51_NVMC_BASE + NRF51_NVMC_CONFIG, 0x01); |
| 248 | for (i = 0; i < NRF51_UICR_SIZE / 4; i++) { |
| 249 | qtest_writel(qts, NRF51_UICR_BASE + i * 4, i); |
| 250 | g_assert_cmpuint(qtest_readl(qts, NRF51_UICR_BASE + i * 4), ==, i); |
| 251 | } |
| 252 | qtest_writel(qts, NRF51_NVMC_BASE + NRF51_NVMC_CONFIG, 0x00); |
| 253 | |
| 254 | qtest_writel(qts, NRF51_NVMC_BASE + NRF51_NVMC_CONFIG, 0x02); |
| 255 | qtest_writel(qts, NRF51_NVMC_BASE + NRF51_NVMC_ERASEUICR, 0x01); |
| 256 | qtest_writel(qts, NRF51_NVMC_BASE + NRF51_NVMC_CONFIG, 0x00); |
| 257 | |
| 258 | for (i = 0; i < NRF51_UICR_SIZE / 4; i++) { |
| 259 | g_assert_cmpuint(qtest_readl(qts, NRF51_UICR_BASE + i * 4), |
| 260 | ==, 0xFFFFFFFF); |
| 261 | } |
| 262 | |
| 263 | qtest_quit(qts); |
| 264 | } |
| 265 | |
Steffen Görtz | 17ff8e1 | 2019-01-07 15:23:47 +0000 | [diff] [blame] | 266 | static void test_nrf51_gpio(void) |
| 267 | { |
| 268 | size_t i; |
| 269 | uint32_t actual, expected; |
| 270 | |
| 271 | struct { |
| 272 | hwaddr addr; |
| 273 | uint32_t expected; |
| 274 | } const reset_state[] = { |
| 275 | {NRF51_GPIO_REG_OUT, 0x00000000}, {NRF51_GPIO_REG_OUTSET, 0x00000000}, |
| 276 | {NRF51_GPIO_REG_OUTCLR, 0x00000000}, {NRF51_GPIO_REG_IN, 0x00000000}, |
| 277 | {NRF51_GPIO_REG_DIR, 0x00000000}, {NRF51_GPIO_REG_DIRSET, 0x00000000}, |
| 278 | {NRF51_GPIO_REG_DIRCLR, 0x00000000} |
| 279 | }; |
| 280 | |
Julia Suvorova | 7cf19e7 | 2019-01-29 11:46:04 +0000 | [diff] [blame] | 281 | QTestState *qts = qtest_init("-M microbit"); |
| 282 | |
Steffen Görtz | 17ff8e1 | 2019-01-07 15:23:47 +0000 | [diff] [blame] | 283 | /* Check reset state */ |
| 284 | for (i = 0; i < ARRAY_SIZE(reset_state); i++) { |
| 285 | expected = reset_state[i].expected; |
Julia Suvorova | 7cf19e7 | 2019-01-29 11:46:04 +0000 | [diff] [blame] | 286 | actual = qtest_readl(qts, NRF51_GPIO_BASE + reset_state[i].addr); |
Steffen Görtz | 17ff8e1 | 2019-01-07 15:23:47 +0000 | [diff] [blame] | 287 | g_assert_cmpuint(actual, ==, expected); |
| 288 | } |
| 289 | |
| 290 | for (i = 0; i < NRF51_GPIO_PINS; i++) { |
| 291 | expected = 0x00000002; |
Julia Suvorova | 7cf19e7 | 2019-01-29 11:46:04 +0000 | [diff] [blame] | 292 | actual = qtest_readl(qts, NRF51_GPIO_BASE + |
| 293 | NRF51_GPIO_REG_CNF_START + i * 4); |
Steffen Görtz | 17ff8e1 | 2019-01-07 15:23:47 +0000 | [diff] [blame] | 294 | g_assert_cmpuint(actual, ==, expected); |
| 295 | } |
| 296 | |
| 297 | /* Check dir bit consistency between dir and cnf */ |
| 298 | /* Check set via DIRSET */ |
| 299 | expected = 0x80000001; |
Julia Suvorova | 7cf19e7 | 2019-01-29 11:46:04 +0000 | [diff] [blame] | 300 | qtest_writel(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_DIRSET, expected); |
| 301 | actual = qtest_readl(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_DIR); |
Steffen Görtz | 17ff8e1 | 2019-01-07 15:23:47 +0000 | [diff] [blame] | 302 | g_assert_cmpuint(actual, ==, expected); |
Julia Suvorova | 7cf19e7 | 2019-01-29 11:46:04 +0000 | [diff] [blame] | 303 | actual = qtest_readl(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_CNF_START) |
| 304 | & 0x01; |
Steffen Görtz | 17ff8e1 | 2019-01-07 15:23:47 +0000 | [diff] [blame] | 305 | g_assert_cmpuint(actual, ==, 0x01); |
Julia Suvorova | 7cf19e7 | 2019-01-29 11:46:04 +0000 | [diff] [blame] | 306 | actual = qtest_readl(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_CNF_END) & 0x01; |
Steffen Görtz | 17ff8e1 | 2019-01-07 15:23:47 +0000 | [diff] [blame] | 307 | g_assert_cmpuint(actual, ==, 0x01); |
| 308 | |
| 309 | /* Check clear via DIRCLR */ |
Julia Suvorova | 7cf19e7 | 2019-01-29 11:46:04 +0000 | [diff] [blame] | 310 | qtest_writel(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_DIRCLR, 0x80000001); |
| 311 | actual = qtest_readl(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_DIR); |
Steffen Görtz | 17ff8e1 | 2019-01-07 15:23:47 +0000 | [diff] [blame] | 312 | g_assert_cmpuint(actual, ==, 0x00000000); |
Julia Suvorova | 7cf19e7 | 2019-01-29 11:46:04 +0000 | [diff] [blame] | 313 | actual = qtest_readl(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_CNF_START) |
| 314 | & 0x01; |
Steffen Görtz | 17ff8e1 | 2019-01-07 15:23:47 +0000 | [diff] [blame] | 315 | g_assert_cmpuint(actual, ==, 0x00); |
Julia Suvorova | 7cf19e7 | 2019-01-29 11:46:04 +0000 | [diff] [blame] | 316 | actual = qtest_readl(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_CNF_END) & 0x01; |
Steffen Görtz | 17ff8e1 | 2019-01-07 15:23:47 +0000 | [diff] [blame] | 317 | g_assert_cmpuint(actual, ==, 0x00); |
| 318 | |
| 319 | /* Check set via DIR */ |
| 320 | expected = 0x80000001; |
Julia Suvorova | 7cf19e7 | 2019-01-29 11:46:04 +0000 | [diff] [blame] | 321 | qtest_writel(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_DIR, expected); |
| 322 | actual = qtest_readl(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_DIR); |
Steffen Görtz | 17ff8e1 | 2019-01-07 15:23:47 +0000 | [diff] [blame] | 323 | g_assert_cmpuint(actual, ==, expected); |
Julia Suvorova | 7cf19e7 | 2019-01-29 11:46:04 +0000 | [diff] [blame] | 324 | actual = qtest_readl(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_CNF_START) |
| 325 | & 0x01; |
Steffen Görtz | 17ff8e1 | 2019-01-07 15:23:47 +0000 | [diff] [blame] | 326 | g_assert_cmpuint(actual, ==, 0x01); |
Julia Suvorova | 7cf19e7 | 2019-01-29 11:46:04 +0000 | [diff] [blame] | 327 | actual = qtest_readl(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_CNF_END) & 0x01; |
Steffen Görtz | 17ff8e1 | 2019-01-07 15:23:47 +0000 | [diff] [blame] | 328 | g_assert_cmpuint(actual, ==, 0x01); |
| 329 | |
| 330 | /* Reset DIR */ |
Julia Suvorova | 7cf19e7 | 2019-01-29 11:46:04 +0000 | [diff] [blame] | 331 | qtest_writel(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_DIR, 0x00000000); |
Steffen Görtz | 17ff8e1 | 2019-01-07 15:23:47 +0000 | [diff] [blame] | 332 | |
| 333 | /* Check Input propagates */ |
Julia Suvorova | 7cf19e7 | 2019-01-29 11:46:04 +0000 | [diff] [blame] | 334 | qtest_writel(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_CNF_START, 0x00); |
| 335 | qtest_set_irq_in(qts, "/machine/nrf51", "unnamed-gpio-in", 0, 0); |
| 336 | actual = qtest_readl(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_IN) & 0x01; |
Steffen Görtz | 17ff8e1 | 2019-01-07 15:23:47 +0000 | [diff] [blame] | 337 | g_assert_cmpuint(actual, ==, 0x00); |
Julia Suvorova | 7cf19e7 | 2019-01-29 11:46:04 +0000 | [diff] [blame] | 338 | qtest_set_irq_in(qts, "/machine/nrf51", "unnamed-gpio-in", 0, 1); |
| 339 | actual = qtest_readl(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_IN) & 0x01; |
Steffen Görtz | 17ff8e1 | 2019-01-07 15:23:47 +0000 | [diff] [blame] | 340 | g_assert_cmpuint(actual, ==, 0x01); |
Julia Suvorova | 7cf19e7 | 2019-01-29 11:46:04 +0000 | [diff] [blame] | 341 | qtest_set_irq_in(qts, "/machine/nrf51", "unnamed-gpio-in", 0, -1); |
| 342 | actual = qtest_readl(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_IN) & 0x01; |
Steffen Görtz | 17ff8e1 | 2019-01-07 15:23:47 +0000 | [diff] [blame] | 343 | g_assert_cmpuint(actual, ==, 0x01); |
Julia Suvorova | 7cf19e7 | 2019-01-29 11:46:04 +0000 | [diff] [blame] | 344 | qtest_writel(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_CNF_START, 0x02); |
Steffen Görtz | 17ff8e1 | 2019-01-07 15:23:47 +0000 | [diff] [blame] | 345 | |
| 346 | /* Check pull-up working */ |
Julia Suvorova | 7cf19e7 | 2019-01-29 11:46:04 +0000 | [diff] [blame] | 347 | qtest_set_irq_in(qts, "/machine/nrf51", "unnamed-gpio-in", 0, 0); |
| 348 | qtest_writel(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_CNF_START, 0b0000); |
| 349 | actual = qtest_readl(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_IN) & 0x01; |
Steffen Görtz | 17ff8e1 | 2019-01-07 15:23:47 +0000 | [diff] [blame] | 350 | g_assert_cmpuint(actual, ==, 0x00); |
Julia Suvorova | 7cf19e7 | 2019-01-29 11:46:04 +0000 | [diff] [blame] | 351 | qtest_writel(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_CNF_START, 0b1110); |
| 352 | actual = qtest_readl(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_IN) & 0x01; |
Steffen Görtz | 17ff8e1 | 2019-01-07 15:23:47 +0000 | [diff] [blame] | 353 | g_assert_cmpuint(actual, ==, 0x01); |
Julia Suvorova | 7cf19e7 | 2019-01-29 11:46:04 +0000 | [diff] [blame] | 354 | qtest_writel(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_CNF_START, 0x02); |
Steffen Görtz | 17ff8e1 | 2019-01-07 15:23:47 +0000 | [diff] [blame] | 355 | |
| 356 | /* Check pull-down working */ |
Julia Suvorova | 7cf19e7 | 2019-01-29 11:46:04 +0000 | [diff] [blame] | 357 | qtest_set_irq_in(qts, "/machine/nrf51", "unnamed-gpio-in", 0, 1); |
| 358 | qtest_writel(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_CNF_START, 0b0000); |
| 359 | actual = qtest_readl(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_IN) & 0x01; |
Steffen Görtz | 17ff8e1 | 2019-01-07 15:23:47 +0000 | [diff] [blame] | 360 | g_assert_cmpuint(actual, ==, 0x01); |
Julia Suvorova | 7cf19e7 | 2019-01-29 11:46:04 +0000 | [diff] [blame] | 361 | qtest_writel(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_CNF_START, 0b0110); |
| 362 | actual = qtest_readl(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_IN) & 0x01; |
Steffen Görtz | 17ff8e1 | 2019-01-07 15:23:47 +0000 | [diff] [blame] | 363 | g_assert_cmpuint(actual, ==, 0x00); |
Julia Suvorova | 7cf19e7 | 2019-01-29 11:46:04 +0000 | [diff] [blame] | 364 | qtest_writel(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_CNF_START, 0x02); |
| 365 | qtest_set_irq_in(qts, "/machine/nrf51", "unnamed-gpio-in", 0, -1); |
Steffen Görtz | 17ff8e1 | 2019-01-07 15:23:47 +0000 | [diff] [blame] | 366 | |
| 367 | /* Check Output propagates */ |
Julia Suvorova | 7cf19e7 | 2019-01-29 11:46:04 +0000 | [diff] [blame] | 368 | qtest_irq_intercept_out(qts, "/machine/nrf51"); |
| 369 | qtest_writel(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_CNF_START, 0b0011); |
| 370 | qtest_writel(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_OUTSET, 0x01); |
| 371 | g_assert_true(qtest_get_irq(qts, 0)); |
| 372 | qtest_writel(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_OUTCLR, 0x01); |
| 373 | g_assert_false(qtest_get_irq(qts, 0)); |
Steffen Görtz | 17ff8e1 | 2019-01-07 15:23:47 +0000 | [diff] [blame] | 374 | |
| 375 | /* Check self-stimulation */ |
Julia Suvorova | 7cf19e7 | 2019-01-29 11:46:04 +0000 | [diff] [blame] | 376 | qtest_writel(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_CNF_START, 0b01); |
| 377 | qtest_writel(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_OUTSET, 0x01); |
| 378 | actual = qtest_readl(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_IN) & 0x01; |
Steffen Görtz | 17ff8e1 | 2019-01-07 15:23:47 +0000 | [diff] [blame] | 379 | g_assert_cmpuint(actual, ==, 0x01); |
| 380 | |
Julia Suvorova | 7cf19e7 | 2019-01-29 11:46:04 +0000 | [diff] [blame] | 381 | qtest_writel(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_OUTCLR, 0x01); |
| 382 | actual = qtest_readl(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_IN) & 0x01; |
Steffen Görtz | 17ff8e1 | 2019-01-07 15:23:47 +0000 | [diff] [blame] | 383 | g_assert_cmpuint(actual, ==, 0x00); |
| 384 | |
| 385 | /* |
| 386 | * Check short-circuit - generates an guest_error which must be checked |
| 387 | * manually as long as qtest can not scan qemu_log messages |
| 388 | */ |
Julia Suvorova | 7cf19e7 | 2019-01-29 11:46:04 +0000 | [diff] [blame] | 389 | qtest_writel(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_CNF_START, 0b01); |
| 390 | qtest_writel(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_OUTSET, 0x01); |
| 391 | qtest_set_irq_in(qts, "/machine/nrf51", "unnamed-gpio-in", 0, 0); |
| 392 | |
| 393 | qtest_quit(qts); |
Steffen Görtz | 17ff8e1 | 2019-01-07 15:23:47 +0000 | [diff] [blame] | 394 | } |
| 395 | |
Julia Suvorova | 7cf19e7 | 2019-01-29 11:46:04 +0000 | [diff] [blame] | 396 | static void timer_task(QTestState *qts, hwaddr task) |
Steffen Görtz | 7ec543e | 2019-01-07 15:23:47 +0000 | [diff] [blame] | 397 | { |
Julia Suvorova | 7cf19e7 | 2019-01-29 11:46:04 +0000 | [diff] [blame] | 398 | qtest_writel(qts, NRF51_TIMER_BASE + task, NRF51_TRIGGER_TASK); |
Steffen Görtz | 7ec543e | 2019-01-07 15:23:47 +0000 | [diff] [blame] | 399 | } |
| 400 | |
Julia Suvorova | 7cf19e7 | 2019-01-29 11:46:04 +0000 | [diff] [blame] | 401 | static void timer_clear_event(QTestState *qts, hwaddr event) |
Steffen Görtz | 7ec543e | 2019-01-07 15:23:47 +0000 | [diff] [blame] | 402 | { |
Julia Suvorova | 7cf19e7 | 2019-01-29 11:46:04 +0000 | [diff] [blame] | 403 | qtest_writel(qts, NRF51_TIMER_BASE + event, NRF51_EVENT_CLEAR); |
Steffen Görtz | 7ec543e | 2019-01-07 15:23:47 +0000 | [diff] [blame] | 404 | } |
| 405 | |
Julia Suvorova | 7cf19e7 | 2019-01-29 11:46:04 +0000 | [diff] [blame] | 406 | static void timer_set_bitmode(QTestState *qts, uint8_t mode) |
Steffen Görtz | 7ec543e | 2019-01-07 15:23:47 +0000 | [diff] [blame] | 407 | { |
Julia Suvorova | 7cf19e7 | 2019-01-29 11:46:04 +0000 | [diff] [blame] | 408 | qtest_writel(qts, NRF51_TIMER_BASE + NRF51_TIMER_REG_BITMODE, mode); |
Steffen Görtz | 7ec543e | 2019-01-07 15:23:47 +0000 | [diff] [blame] | 409 | } |
| 410 | |
Julia Suvorova | 7cf19e7 | 2019-01-29 11:46:04 +0000 | [diff] [blame] | 411 | static void timer_set_prescaler(QTestState *qts, uint8_t prescaler) |
Steffen Görtz | 7ec543e | 2019-01-07 15:23:47 +0000 | [diff] [blame] | 412 | { |
Julia Suvorova | 7cf19e7 | 2019-01-29 11:46:04 +0000 | [diff] [blame] | 413 | qtest_writel(qts, NRF51_TIMER_BASE + NRF51_TIMER_REG_PRESCALER, prescaler); |
Steffen Görtz | 7ec543e | 2019-01-07 15:23:47 +0000 | [diff] [blame] | 414 | } |
| 415 | |
Julia Suvorova | 7cf19e7 | 2019-01-29 11:46:04 +0000 | [diff] [blame] | 416 | static void timer_set_cc(QTestState *qts, size_t idx, uint32_t value) |
Steffen Görtz | 7ec543e | 2019-01-07 15:23:47 +0000 | [diff] [blame] | 417 | { |
Julia Suvorova | 7cf19e7 | 2019-01-29 11:46:04 +0000 | [diff] [blame] | 418 | qtest_writel(qts, NRF51_TIMER_BASE + NRF51_TIMER_REG_CC0 + idx * 4, value); |
Steffen Görtz | 7ec543e | 2019-01-07 15:23:47 +0000 | [diff] [blame] | 419 | } |
| 420 | |
Julia Suvorova | 7cf19e7 | 2019-01-29 11:46:04 +0000 | [diff] [blame] | 421 | static void timer_assert_events(QTestState *qts, uint32_t ev0, uint32_t ev1, |
| 422 | uint32_t ev2, uint32_t ev3) |
Steffen Görtz | 7ec543e | 2019-01-07 15:23:47 +0000 | [diff] [blame] | 423 | { |
Julia Suvorova | 7cf19e7 | 2019-01-29 11:46:04 +0000 | [diff] [blame] | 424 | g_assert(qtest_readl(qts, NRF51_TIMER_BASE + NRF51_TIMER_EVENT_COMPARE_0) |
| 425 | == ev0); |
| 426 | g_assert(qtest_readl(qts, NRF51_TIMER_BASE + NRF51_TIMER_EVENT_COMPARE_1) |
| 427 | == ev1); |
| 428 | g_assert(qtest_readl(qts, NRF51_TIMER_BASE + NRF51_TIMER_EVENT_COMPARE_2) |
| 429 | == ev2); |
| 430 | g_assert(qtest_readl(qts, NRF51_TIMER_BASE + NRF51_TIMER_EVENT_COMPARE_3) |
| 431 | == ev3); |
Steffen Görtz | 7ec543e | 2019-01-07 15:23:47 +0000 | [diff] [blame] | 432 | } |
| 433 | |
| 434 | static void test_nrf51_timer(void) |
| 435 | { |
| 436 | uint32_t steps_to_overflow = 408; |
Julia Suvorova | 7cf19e7 | 2019-01-29 11:46:04 +0000 | [diff] [blame] | 437 | QTestState *qts = qtest_init("-M microbit"); |
Steffen Görtz | 7ec543e | 2019-01-07 15:23:47 +0000 | [diff] [blame] | 438 | |
| 439 | /* Compare Match */ |
Julia Suvorova | 7cf19e7 | 2019-01-29 11:46:04 +0000 | [diff] [blame] | 440 | timer_task(qts, NRF51_TIMER_TASK_STOP); |
| 441 | timer_task(qts, NRF51_TIMER_TASK_CLEAR); |
Steffen Görtz | 7ec543e | 2019-01-07 15:23:47 +0000 | [diff] [blame] | 442 | |
Julia Suvorova | 7cf19e7 | 2019-01-29 11:46:04 +0000 | [diff] [blame] | 443 | timer_clear_event(qts, NRF51_TIMER_EVENT_COMPARE_0); |
| 444 | timer_clear_event(qts, NRF51_TIMER_EVENT_COMPARE_1); |
| 445 | timer_clear_event(qts, NRF51_TIMER_EVENT_COMPARE_2); |
| 446 | timer_clear_event(qts, NRF51_TIMER_EVENT_COMPARE_3); |
Steffen Görtz | 7ec543e | 2019-01-07 15:23:47 +0000 | [diff] [blame] | 447 | |
Julia Suvorova | 7cf19e7 | 2019-01-29 11:46:04 +0000 | [diff] [blame] | 448 | timer_set_bitmode(qts, NRF51_TIMER_WIDTH_16); /* 16 MHz Timer */ |
| 449 | timer_set_prescaler(qts, 0); |
Daniel P. Berrangé | 7a21bee | 2022-07-07 17:37:15 +0100 | [diff] [blame] | 450 | /* Swept over, during the first step */ |
Julia Suvorova | 7cf19e7 | 2019-01-29 11:46:04 +0000 | [diff] [blame] | 451 | timer_set_cc(qts, 0, 2); |
Daniel P. Berrangé | 7a21bee | 2022-07-07 17:37:15 +0100 | [diff] [blame] | 452 | /* Barely miss, after the second step */ |
Julia Suvorova | 7cf19e7 | 2019-01-29 11:46:04 +0000 | [diff] [blame] | 453 | timer_set_cc(qts, 1, 162); |
Daniel P. Berrangé | 7a21bee | 2022-07-07 17:37:15 +0100 | [diff] [blame] | 454 | /* Spot on, after the third step */ |
Julia Suvorova | 7cf19e7 | 2019-01-29 11:46:04 +0000 | [diff] [blame] | 455 | timer_set_cc(qts, 2, 480); |
Steffen Görtz | 7ec543e | 2019-01-07 15:23:47 +0000 | [diff] [blame] | 456 | |
Julia Suvorova | 7cf19e7 | 2019-01-29 11:46:04 +0000 | [diff] [blame] | 457 | timer_assert_events(qts, 0, 0, 0, 0); |
Steffen Görtz | 7ec543e | 2019-01-07 15:23:47 +0000 | [diff] [blame] | 458 | |
Julia Suvorova | 7cf19e7 | 2019-01-29 11:46:04 +0000 | [diff] [blame] | 459 | timer_task(qts, NRF51_TIMER_TASK_START); |
| 460 | qtest_clock_step(qts, 10000); |
| 461 | timer_assert_events(qts, 1, 0, 0, 0); |
Steffen Görtz | 7ec543e | 2019-01-07 15:23:47 +0000 | [diff] [blame] | 462 | |
| 463 | /* Swept over on first overflow */ |
Julia Suvorova | 7cf19e7 | 2019-01-29 11:46:04 +0000 | [diff] [blame] | 464 | timer_set_cc(qts, 3, 114); |
Steffen Görtz | 7ec543e | 2019-01-07 15:23:47 +0000 | [diff] [blame] | 465 | |
Julia Suvorova | 7cf19e7 | 2019-01-29 11:46:04 +0000 | [diff] [blame] | 466 | qtest_clock_step(qts, 10000); |
| 467 | timer_assert_events(qts, 1, 1, 0, 0); |
Steffen Görtz | 7ec543e | 2019-01-07 15:23:47 +0000 | [diff] [blame] | 468 | |
Julia Suvorova | 7cf19e7 | 2019-01-29 11:46:04 +0000 | [diff] [blame] | 469 | qtest_clock_step(qts, 10000); |
| 470 | timer_assert_events(qts, 1, 1, 1, 0); |
Steffen Görtz | 7ec543e | 2019-01-07 15:23:47 +0000 | [diff] [blame] | 471 | |
| 472 | /* Wrap time until internal counter overflows */ |
| 473 | while (steps_to_overflow--) { |
Julia Suvorova | 7cf19e7 | 2019-01-29 11:46:04 +0000 | [diff] [blame] | 474 | timer_assert_events(qts, 1, 1, 1, 0); |
| 475 | qtest_clock_step(qts, 10000); |
Steffen Görtz | 7ec543e | 2019-01-07 15:23:47 +0000 | [diff] [blame] | 476 | } |
| 477 | |
Julia Suvorova | 7cf19e7 | 2019-01-29 11:46:04 +0000 | [diff] [blame] | 478 | timer_assert_events(qts, 1, 1, 1, 1); |
Steffen Görtz | 7ec543e | 2019-01-07 15:23:47 +0000 | [diff] [blame] | 479 | |
Julia Suvorova | 7cf19e7 | 2019-01-29 11:46:04 +0000 | [diff] [blame] | 480 | timer_clear_event(qts, NRF51_TIMER_EVENT_COMPARE_0); |
| 481 | timer_clear_event(qts, NRF51_TIMER_EVENT_COMPARE_1); |
| 482 | timer_clear_event(qts, NRF51_TIMER_EVENT_COMPARE_2); |
| 483 | timer_clear_event(qts, NRF51_TIMER_EVENT_COMPARE_3); |
| 484 | timer_assert_events(qts, 0, 0, 0, 0); |
Steffen Görtz | 7ec543e | 2019-01-07 15:23:47 +0000 | [diff] [blame] | 485 | |
Julia Suvorova | 7cf19e7 | 2019-01-29 11:46:04 +0000 | [diff] [blame] | 486 | timer_task(qts, NRF51_TIMER_TASK_STOP); |
Steffen Görtz | 7ec543e | 2019-01-07 15:23:47 +0000 | [diff] [blame] | 487 | |
| 488 | /* Test Proposal: Stop/Shutdown */ |
| 489 | /* Test Proposal: Shortcut Compare -> Clear */ |
| 490 | /* Test Proposal: Shortcut Compare -> Stop */ |
| 491 | /* Test Proposal: Counter Mode */ |
Julia Suvorova | 7cf19e7 | 2019-01-29 11:46:04 +0000 | [diff] [blame] | 492 | |
| 493 | qtest_quit(qts); |
Steffen Görtz | 7ec543e | 2019-01-07 15:23:47 +0000 | [diff] [blame] | 494 | } |
| 495 | |
Steffen Görtz | 17ff8e1 | 2019-01-07 15:23:47 +0000 | [diff] [blame] | 496 | int main(int argc, char **argv) |
| 497 | { |
Steffen Görtz | 17ff8e1 | 2019-01-07 15:23:47 +0000 | [diff] [blame] | 498 | g_test_init(&argc, &argv, NULL); |
| 499 | |
Julia Suvorova | 46a6603 | 2019-01-29 11:46:04 +0000 | [diff] [blame] | 500 | qtest_add_func("/microbit/nrf51/uart", test_nrf51_uart); |
Steffen Görtz | 17ff8e1 | 2019-01-07 15:23:47 +0000 | [diff] [blame] | 501 | qtest_add_func("/microbit/nrf51/gpio", test_nrf51_gpio); |
Steffen Görtz | 7743b70 | 2019-02-01 10:33:57 +0800 | [diff] [blame] | 502 | qtest_add_func("/microbit/nrf51/nvmc", test_nrf51_nvmc); |
Steffen Görtz | 7ec543e | 2019-01-07 15:23:47 +0000 | [diff] [blame] | 503 | qtest_add_func("/microbit/nrf51/timer", test_nrf51_timer); |
Stefan Hajnoczi | b36356f | 2019-01-29 11:46:03 +0000 | [diff] [blame] | 504 | qtest_add_func("/microbit/microbit/i2c", test_microbit_i2c); |
Steffen Görtz | 17ff8e1 | 2019-01-07 15:23:47 +0000 | [diff] [blame] | 505 | |
Julia Suvorova | 7cf19e7 | 2019-01-29 11:46:04 +0000 | [diff] [blame] | 506 | return g_test_run(); |
Steffen Görtz | 17ff8e1 | 2019-01-07 15:23:47 +0000 | [diff] [blame] | 507 | } |