@@ -33,6 +33,21 @@
#define NVMC_ERASEPCR0 0x510
#define NVMC_ERASEUICR 0x514
+#define GPIO_BASE 0x50000000
+#define GPIO_OUT 0x504
+#define GPIO_OUTSET 0x508
+#define GPIO_OUTCLR 0x50C
+#define GPIO_IN 0x510
+#define GPIO_DIR 0x514
+#define GPIO_DIRSET 0x518
+#define GPIO_DIRCLR 0x51C
+#define GPIO_CNF_START 0x700
+#define GPIO_CNF_END 0x77F
+#define GPIO_PINS 32
+
+#define GPIO_PULLDOWN 1
+#define GPIO_PULLUP 3
+
static void fill_and_erase(hwaddr base, hwaddr size, uint32_t address_reg)
{
@@ -109,6 +124,86 @@ static void test_nrf51_nvmc(void)
}
}
+static void test_nrf51_gpio(void)
+{
+ size_t i;
+ uint32_t actual, expected;
+
+ struct {
+ hwaddr addr;
+ uint32_t expected;
+ } reset_state[] = {
+ {GPIO_OUT, 0x00000000}, {GPIO_OUTSET, 0x00000000},
+ {GPIO_OUTCLR, 0x00000000}, {GPIO_IN, 0x00000000},
+ {GPIO_DIR, 0x00000000}, {GPIO_DIRSET, 0x00000000},
+ {GPIO_DIRCLR, 0x00000000}
+ };
+
+ /** Check reset state **/
+ for (i = 0; i < ARRAY_SIZE(reset_state); i++) {
+ expected = reset_state[i].expected;
+ actual = readl(GPIO_BASE + reset_state[i].addr);
+ g_assert_cmpuint(actual, ==, expected);
+ }
+
+ for (i = 0; i < GPIO_PINS; i++) {
+ expected = 0x00000002;
+ actual = readl(GPIO_BASE + GPIO_CNF_START + i * 4);
+ g_assert_cmpuint(actual, ==, expected);
+ }
+
+ /** Check dir bit consistency between dir and cnf **/
+ /* Check set via DIRSET */
+ expected = 0x80000001;
+ writel(GPIO_BASE + GPIO_DIRSET, expected);
+ actual = readl(GPIO_BASE + GPIO_DIR);
+ g_assert_cmpuint(actual, ==, expected);
+ actual = readl(GPIO_BASE + GPIO_CNF_START) & 0x01;
+ g_assert_cmpuint(actual, ==, 0x01);
+ actual = readl(GPIO_BASE + GPIO_CNF_END) & 0x01;
+ g_assert_cmpuint(actual, ==, 0x01);
+
+ /* Check clear via DIRCLR */
+ writel(GPIO_BASE + GPIO_DIRCLR, 0x80000001);
+ actual = readl(GPIO_BASE + GPIO_DIR);
+ g_assert_cmpuint(actual, ==, 0x00000000);
+ actual = readl(GPIO_BASE + GPIO_CNF_START) & 0x01;
+ g_assert_cmpuint(actual, ==, 0x00);
+ actual = readl(GPIO_BASE + GPIO_CNF_END) & 0x01;
+ g_assert_cmpuint(actual, ==, 0x00);
+
+ /* Check set via DIR */
+ expected = 0x80000001;
+ writel(GPIO_BASE + GPIO_DIR, expected);
+ actual = readl(GPIO_BASE + GPIO_DIR);
+ g_assert_cmpuint(actual, ==, expected);
+ actual = readl(GPIO_BASE + GPIO_CNF_START) & 0x01;
+ g_assert_cmpuint(actual, ==, 0x01);
+ actual = readl(GPIO_BASE + GPIO_CNF_END) & 0x01;
+ g_assert_cmpuint(actual, ==, 0x01);
+
+ /* Reset DIR */
+ writel(GPIO_BASE + GPIO_DIR, 0x00000000);
+
+ /* Check Input propagates */
+ g_assert_false(true);
+
+ /* Check pull-up working */
+ g_assert_false(true);
+
+ /* Check pull-down working */
+ g_assert_false(true);
+
+ /* Check Output propagates */
+ g_assert_false(true);
+
+ /* Check self-stimulation */
+ g_assert_false(true);
+
+ /* Check short-circuit */
+ g_assert_false(true);
+}
+
int main(int argc, char **argv)
{
int ret;
@@ -118,6 +213,7 @@ int main(int argc, char **argv)
global_qtest = qtest_startf("-machine microbit");
qtest_add_func("/microbit/nrf51/nvmc", test_nrf51_nvmc);
+ qtest_add_func("/microbit/nrf51/gpio", test_nrf51_gpio);
ret = g_test_run();
The test suite for the nRF51 GPIO peripheral for now only tests initial state. Additionally a set of tests testing an implementation detail of the model are included. Signed-off-by: Steffen Görtz <contrib@steffen-goertz.de> --- tests/microbit-test.c | 96 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+)