From daca7d7dff650b70a69058a1b0bdedf410b78bd1 Mon Sep 17 00:00:00 2001 From: VintagePC <53943260+vintagepc@users.noreply.github.com> Date: Sun, 3 Mar 2024 11:24:54 -0500 Subject: [PATCH] Fix bug in GPIO initialization sequence. Fixes #146 --- hw/arm/prusa/prusa-mk4.c | 20 ++++++++++++++++---- hw/arm/prusa/stm32_common/stm32_gpio.c | 6 +++++- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/hw/arm/prusa/prusa-mk4.c b/hw/arm/prusa/prusa-mk4.c index 5c19ce20dc..22ab7b944e 100644 --- a/hw/arm/prusa/prusa-mk4.c +++ b/hw/arm/prusa/prusa-mk4.c @@ -114,6 +114,7 @@ typedef struct mk4_cfg_t { temp_cfg_t temps; uint8_t motor; uint8_t e_t_mass; + bool e_loopback; char m_label[AXIS_MAX]; stm_pin m_step[AXIS_MAX]; stm_pin m_dir[AXIS_MAX]; @@ -258,6 +259,7 @@ static const mk4_cfg_t mk3v5_cfg = { .table = { [T_NOZ] = 2005, [T_BED] = 2004, [T_BRK] = 5, [T_BRD] = 2000, [T_CASE] = 2000 } }, .e_t_mass = 30, + .e_loopback = true, .motor = TMC2130, .m_label = {'X','Y','Z','E'}, .m_step = { STM_PIN(GPIOD,7), STM_PIN(GPIOD,5), STM_PIN(GPIOD,3), STM_PIN(GPIOD,1)}, @@ -341,6 +343,9 @@ static void mk4_init(MachineState *machine) qdev_prop_set_uint32(dev,"sram-size", machine->ram_size); uint64_t flash_size = stm32_soc_get_flash_size(dev); arghelper_setargs(machine->kernel_cmdline); + + // We (ab)use the kernel command line to piggyback custom arguments into QEMU. + // Parse those now. bool args_continue_running = arghelper_parseargs(); if (arghelper_is_arg("4x_flash")) { @@ -361,14 +366,21 @@ static void mk4_init(MachineState *machine) qdev_prop_set_uint32(otp,"otp-data[7]", otp_raw[7]); qdev_prop_set_uint32(otp,"otp-data[8]", otp_raw[8]); - sysbus_realize(SYS_BUS_DEVICE(dev), &error_fatal); DeviceState* dev_soc = dev; - // We (ab)use the kernel command line to piggyback custom arguments into QEMU. - // Parse those now. - // ugly hack... FIXME. if (arghelper_is_arg("appendix")) { qdev_prop_set_uint32(stm32_soc_get_periph(dev_soc, STM32_P_GPIOA),"idr-mask", 0x2000); } + if (cfg.e_loopback) { + qdev_prop_set_uint32(stm32_soc_get_periph(dev_soc, STM32_P_GPIOE),"idr-mask", 0x80); + } + + sysbus_realize(SYS_BUS_DEVICE(dev), &error_fatal); + + if(cfg.e_loopback) + { + qdev_connect_gpio_out(stm32_soc_get_periph(dev_soc, STM32_P_GPIOG), 1, qdev_get_gpio_in(stm32_soc_get_periph(dev_soc, STM32_P_GPIOE), 7)); + } + char* kfn = machine->kernel_filename; int kernel_len = kfn ? strlen(kfn) : 0; diff --git a/hw/arm/prusa/stm32_common/stm32_gpio.c b/hw/arm/prusa/stm32_common/stm32_gpio.c index 6b5b96d1ad..e429bf53cf 100644 --- a/hw/arm/prusa/stm32_common/stm32_gpio.c +++ b/hw/arm/prusa/stm32_common/stm32_gpio.c @@ -89,8 +89,8 @@ stm32_common_gpio_read(void *arg, hwaddr addr, unsigned int size) uint32_t r; addr >>= 2; - r = s->regs[addr]; CHECK_BOUNDS_R(addr, RI_END, s->reginfo[s->parent.periph - STM32_P_GPIOA], "STM32 GPIO"); + r = s->regs[addr]; //printf("GPIO unit %d reg %x return 0x%x\n", s->periph, (int)offset << 2, r); return r; } @@ -221,6 +221,10 @@ stm32_common_gpio_reset(DeviceState *dev) { s->regs[i] = s->reginfo[s->parent.periph - STM32_P_GPIOA][i].reset_val; } + for (int i=0; ipin[i], s->regs[RI_ODR] & (1<regs[RI_IDR] = 0x0000ffff & ~(s->idr_mask); }