Instantiate the LED matrix and set board-level pull-up default values to buttons A and B. This is necessary to calm down the microsoft pxt javascript runtime available for the micro:bit.
Signed-off-by: Steffen Görtz <cont...@steffen-goertz.de> --- hw/arm/microbit.c | 52 ++++++++++++++++++++++++++++++++++----- include/hw/arm/microbit.h | 1 + 2 files changed, 47 insertions(+), 6 deletions(-) diff --git a/hw/arm/microbit.c b/hw/arm/microbit.c index bb6ddb6a79..6fad0de2cd 100644 --- a/hw/arm/microbit.c +++ b/hw/arm/microbit.c @@ -13,34 +13,74 @@ #include "qapi/error.h" #include "hw/boards.h" #include "hw/arm/arm.h" +#include "sysemu/qtest.h" #include "exec/address-spaces.h" #include "hw/arm/microbit.h" +#define BUTTON_A_PIN 17 +#define BUTTON_B_PIN 26 + static void microbit_init(MachineState *machine) { MicrobitMachineState *s = MICROBIT_MACHINE(machine); MemoryRegion *system_memory = get_system_memory(); - Object *soc; + DeviceState *soc, *matrix; object_initialize(&s->nrf51, sizeof(s->nrf51), TYPE_NRF51_SOC); - soc = OBJECT(&s->nrf51); - object_property_add_child(OBJECT(machine), "nrf51", soc, &error_fatal); - object_property_set_link(soc, OBJECT(system_memory), + soc = DEVICE(&s->nrf51); + object_property_add_child(OBJECT(machine), "nrf51", OBJECT(soc), + &error_fatal); + object_property_set_link(OBJECT(soc), OBJECT(system_memory), "memory", &error_abort); - qdev_prop_set_uint32(DEVICE(soc), "variant", NRF51_VARIANT_AA); + qdev_prop_set_uint32(soc, "variant", NRF51_VARIANT_AA); - object_property_set_bool(soc, true, "realized", &error_abort); + object_property_set_bool(OBJECT(soc), true, "realized", &error_abort); + + object_initialize(&s->matrix, sizeof(s->matrix), TYPE_LED_MATRIX); + matrix = DEVICE(&s->matrix); + qdev_prop_set_uint16(matrix, "rows", 3); + qdev_prop_set_uint16(matrix, "cols", 9); + object_property_set_bool(OBJECT(matrix), true, "realized", &error_fatal); + + qdev_connect_gpio_out(soc, 4, qdev_get_gpio_in_named(matrix, "col", 0)); + qdev_connect_gpio_out(soc, 5, qdev_get_gpio_in_named(matrix, "col", 1)); + qdev_connect_gpio_out(soc, 6, qdev_get_gpio_in_named(matrix, "col", 2)); + qdev_connect_gpio_out(soc, 7, qdev_get_gpio_in_named(matrix, "col", 3)); + qdev_connect_gpio_out(soc, 8, qdev_get_gpio_in_named(matrix, "col", 4)); + qdev_connect_gpio_out(soc, 9, qdev_get_gpio_in_named(matrix, "col", 5)); + qdev_connect_gpio_out(soc, 10, qdev_get_gpio_in_named(matrix, "col", 6)); + qdev_connect_gpio_out(soc, 11, qdev_get_gpio_in_named(matrix, "col", 7)); + qdev_connect_gpio_out(soc, 12, qdev_get_gpio_in_named(matrix, "col", 8)); + + qdev_connect_gpio_out(soc, 13, qdev_get_gpio_in_named(matrix, "row", 0)); + qdev_connect_gpio_out(soc, 14, qdev_get_gpio_in_named(matrix, "row", 1)); + qdev_connect_gpio_out(soc, 15, qdev_get_gpio_in_named(matrix, "row", 2)); armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename, 0x00); } +static void microbit_reset(void) +{ + MachineState *machine = MACHINE(qdev_get_machine()); + MicrobitMachineState *s = MICROBIT_MACHINE(machine); + + qemu_devices_reset(); + + /* Board level pull-up */ + if (!qtest_enabled()) { + qemu_set_irq(qdev_get_gpio_in(DEVICE(&s->nrf51), BUTTON_A_PIN), 1); + qemu_set_irq(qdev_get_gpio_in(DEVICE(&s->nrf51), BUTTON_B_PIN), 1); + } +} + static void microbit_machine_init(MachineClass *mc) { mc->desc = "BBC micro:bit"; mc->init = microbit_init; mc->max_cpus = 1; + mc->reset = microbit_reset; } static void microbit_machine_init_class_init(ObjectClass *oc, void *data) diff --git a/include/hw/arm/microbit.h b/include/hw/arm/microbit.h index 89f0c6bc07..094326b4ae 100644 --- a/include/hw/arm/microbit.h +++ b/include/hw/arm/microbit.h @@ -24,6 +24,7 @@ typedef struct MicrobitMachineState { MachineState parent_obj; NRF51State nrf51; + LEDMatrixState matrix; } MicrobitMachineState; #endif -- 2.18.0