qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

microbit-test.c (18397B)


      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"
     22 #include "hw/char/nrf51_uart.h"
     23 #include "hw/gpio/nrf51_gpio.h"
     24 #include "hw/nvram/nrf51_nvm.h"
     25 #include "hw/timer/nrf51_timer.h"
     26 #include "hw/i2c/microbit_i2c.h"
     27 
     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 
     54     g_assert_true(send(sock_fd, in, in_len, 0) == in_len);
     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 
     80     g_assert_true(send(sock_fd, "c", 1, 0) == 1);
     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");
    100     g_assert_true(recv(sock_fd, s, 10, 0) == 1);
    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");
    107     g_assert_true(recv(sock_fd, s, 10, 0) == 5);
    108     g_assert_true(memcmp(s, "world", 5) == 0);
    109 
    110     closesocket(sock_fd);
    111 
    112     qtest_quit(qts);
    113 }
    114 
    115 /* Read a byte from I2C device at @addr from register @reg */
    116 static uint32_t i2c_read_byte(QTestState *qts, uint32_t addr, uint32_t reg)
    117 {
    118     uint32_t val;
    119 
    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);
    124     g_assert_cmpuint(val, ==, 1);
    125     qtest_writel(qts, NRF51_TWI_BASE + NRF51_TWI_TASK_STOP, 1);
    126 
    127     qtest_writel(qts, NRF51_TWI_BASE + NRF51_TWI_TASK_STARTRX, 1);
    128     val = qtest_readl(qts, NRF51_TWI_BASE + NRF51_TWI_EVENT_RXDREADY);
    129     g_assert_cmpuint(val, ==, 1);
    130     val = qtest_readl(qts, NRF51_TWI_BASE + NRF51_TWI_REG_RXD);
    131     qtest_writel(qts, NRF51_TWI_BASE + NRF51_TWI_TASK_STOP, 1);
    132 
    133     return val;
    134 }
    135 
    136 static void test_microbit_i2c(void)
    137 {
    138     uint32_t val;
    139     QTestState *qts = qtest_init("-M microbit");
    140 
    141     /* We don't program pins/irqs but at least enable the device */
    142     qtest_writel(qts, NRF51_TWI_BASE + NRF51_TWI_REG_ENABLE, 5);
    143 
    144     /* MMA8653 magnetometer detection */
    145     val = i2c_read_byte(qts, 0x3A, 0x0D);
    146     g_assert_cmpuint(val, ==, 0x5A);
    147 
    148     val = i2c_read_byte(qts, 0x3A, 0x0D);
    149     g_assert_cmpuint(val, ==, 0x5A);
    150 
    151     /* LSM303 accelerometer detection */
    152     val = i2c_read_byte(qts, 0x3C, 0x4F);
    153     g_assert_cmpuint(val, ==, 0x40);
    154 
    155     qtest_writel(qts, NRF51_TWI_BASE + NRF51_TWI_REG_ENABLE, 0);
    156 
    157     qtest_quit(qts);
    158 }
    159 
    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 
    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 
    281     QTestState *qts = qtest_init("-M microbit");
    282 
    283     /* Check reset state */
    284     for (i = 0; i < ARRAY_SIZE(reset_state); i++) {
    285         expected = reset_state[i].expected;
    286         actual = qtest_readl(qts, NRF51_GPIO_BASE + reset_state[i].addr);
    287         g_assert_cmpuint(actual, ==, expected);
    288     }
    289 
    290     for (i = 0; i < NRF51_GPIO_PINS; i++) {
    291         expected = 0x00000002;
    292         actual = qtest_readl(qts, NRF51_GPIO_BASE +
    293                                   NRF51_GPIO_REG_CNF_START + i * 4);
    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;
    300     qtest_writel(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_DIRSET, expected);
    301     actual = qtest_readl(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_DIR);
    302     g_assert_cmpuint(actual, ==, expected);
    303     actual = qtest_readl(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_CNF_START)
    304              & 0x01;
    305     g_assert_cmpuint(actual, ==, 0x01);
    306     actual = qtest_readl(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_CNF_END) & 0x01;
    307     g_assert_cmpuint(actual, ==, 0x01);
    308 
    309     /* Check clear via DIRCLR */
    310     qtest_writel(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_DIRCLR, 0x80000001);
    311     actual = qtest_readl(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_DIR);
    312     g_assert_cmpuint(actual, ==, 0x00000000);
    313     actual = qtest_readl(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_CNF_START)
    314              & 0x01;
    315     g_assert_cmpuint(actual, ==, 0x00);
    316     actual = qtest_readl(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_CNF_END) & 0x01;
    317     g_assert_cmpuint(actual, ==, 0x00);
    318 
    319     /* Check set via DIR */
    320     expected = 0x80000001;
    321     qtest_writel(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_DIR, expected);
    322     actual = qtest_readl(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_DIR);
    323     g_assert_cmpuint(actual, ==, expected);
    324     actual = qtest_readl(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_CNF_START)
    325              & 0x01;
    326     g_assert_cmpuint(actual, ==, 0x01);
    327     actual = qtest_readl(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_CNF_END) & 0x01;
    328     g_assert_cmpuint(actual, ==, 0x01);
    329 
    330     /* Reset DIR */
    331     qtest_writel(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_DIR, 0x00000000);
    332 
    333     /* Check Input propagates */
    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;
    337     g_assert_cmpuint(actual, ==, 0x00);
    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;
    340     g_assert_cmpuint(actual, ==, 0x01);
    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;
    343     g_assert_cmpuint(actual, ==, 0x01);
    344     qtest_writel(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_CNF_START, 0x02);
    345 
    346     /* Check pull-up working */
    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;
    350     g_assert_cmpuint(actual, ==, 0x00);
    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;
    353     g_assert_cmpuint(actual, ==, 0x01);
    354     qtest_writel(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_CNF_START, 0x02);
    355 
    356     /* Check pull-down working */
    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;
    360     g_assert_cmpuint(actual, ==, 0x01);
    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;
    363     g_assert_cmpuint(actual, ==, 0x00);
    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);
    366 
    367     /* Check Output propagates */
    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));
    374 
    375     /* Check self-stimulation */
    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;
    379     g_assert_cmpuint(actual, ==, 0x01);
    380 
    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;
    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      */
    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);
    394 }
    395 
    396 static void timer_task(QTestState *qts, hwaddr task)
    397 {
    398     qtest_writel(qts, NRF51_TIMER_BASE + task, NRF51_TRIGGER_TASK);
    399 }
    400 
    401 static void timer_clear_event(QTestState *qts, hwaddr event)
    402 {
    403     qtest_writel(qts, NRF51_TIMER_BASE + event, NRF51_EVENT_CLEAR);
    404 }
    405 
    406 static void timer_set_bitmode(QTestState *qts, uint8_t mode)
    407 {
    408     qtest_writel(qts, NRF51_TIMER_BASE + NRF51_TIMER_REG_BITMODE, mode);
    409 }
    410 
    411 static void timer_set_prescaler(QTestState *qts, uint8_t prescaler)
    412 {
    413     qtest_writel(qts, NRF51_TIMER_BASE + NRF51_TIMER_REG_PRESCALER, prescaler);
    414 }
    415 
    416 static void timer_set_cc(QTestState *qts, size_t idx, uint32_t value)
    417 {
    418     qtest_writel(qts, NRF51_TIMER_BASE + NRF51_TIMER_REG_CC0 + idx * 4, value);
    419 }
    420 
    421 static void timer_assert_events(QTestState *qts, uint32_t ev0, uint32_t ev1,
    422                                 uint32_t ev2, uint32_t ev3)
    423 {
    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);
    432 }
    433 
    434 static void test_nrf51_timer(void)
    435 {
    436     uint32_t steps_to_overflow = 408;
    437     QTestState *qts = qtest_init("-M microbit");
    438 
    439     /* Compare Match */
    440     timer_task(qts, NRF51_TIMER_TASK_STOP);
    441     timer_task(qts, NRF51_TIMER_TASK_CLEAR);
    442 
    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);
    447 
    448     timer_set_bitmode(qts, NRF51_TIMER_WIDTH_16); /* 16 MHz Timer */
    449     timer_set_prescaler(qts, 0);
    450     /* Swept over, during the first step */
    451     timer_set_cc(qts, 0, 2);
    452     /* Barely miss, after the second step */
    453     timer_set_cc(qts, 1, 162);
    454     /* Spot on, after the third step */
    455     timer_set_cc(qts, 2, 480);
    456 
    457     timer_assert_events(qts, 0, 0, 0, 0);
    458 
    459     timer_task(qts, NRF51_TIMER_TASK_START);
    460     qtest_clock_step(qts, 10000);
    461     timer_assert_events(qts, 1, 0, 0, 0);
    462 
    463     /* Swept over on first overflow */
    464     timer_set_cc(qts, 3, 114);
    465 
    466     qtest_clock_step(qts, 10000);
    467     timer_assert_events(qts, 1, 1, 0, 0);
    468 
    469     qtest_clock_step(qts, 10000);
    470     timer_assert_events(qts, 1, 1, 1, 0);
    471 
    472     /* Wrap time until internal counter overflows */
    473     while (steps_to_overflow--) {
    474         timer_assert_events(qts, 1, 1, 1, 0);
    475         qtest_clock_step(qts, 10000);
    476     }
    477 
    478     timer_assert_events(qts, 1, 1, 1, 1);
    479 
    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);
    485 
    486     timer_task(qts, NRF51_TIMER_TASK_STOP);
    487 
    488     /* Test Proposal: Stop/Shutdown */
    489     /* Test Proposal: Shortcut Compare -> Clear */
    490     /* Test Proposal: Shortcut Compare -> Stop */
    491     /* Test Proposal: Counter Mode */
    492 
    493     qtest_quit(qts);
    494 }
    495 
    496 int main(int argc, char **argv)
    497 {
    498     g_test_init(&argc, &argv, NULL);
    499 
    500     qtest_add_func("/microbit/nrf51/uart", test_nrf51_uart);
    501     qtest_add_func("/microbit/nrf51/gpio", test_nrf51_gpio);
    502     qtest_add_func("/microbit/nrf51/nvmc", test_nrf51_nvmc);
    503     qtest_add_func("/microbit/nrf51/timer", test_nrf51_timer);
    504     qtest_add_func("/microbit/microbit/i2c", test_microbit_i2c);
    505 
    506     return g_test_run();
    507 }