Skip to content

Commit 3d19b35

Browse files
authored
Major RCC refactor (#89) and DMA cleanup (#30) (#102)
* Major RCC refactor (#89) and DMA cleanup (#30) * use QEMU_BUILD_BUG_MSG instead of static_assert
1 parent ba79cf3 commit 3d19b35

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+2944
-3017
lines changed

hw/arm/prusa/meson.build

+1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ else
2222
message('OpenGL libraries not found. Install development packages for freeglut, glew, and mesa and re-run configure.')
2323
endif
2424

25+
subdir('stm32_common')
2526
subdir('stm32f407')
2627

2728
arm_ss.add(when: 'CONFIG_BUDDYBOARD', if_true: files(

hw/arm/prusa/parts/tmc2209.c

+8-8
Original file line numberDiff line numberDiff line change
@@ -407,14 +407,14 @@ static void tmc2209_init(Object *obj){
407407
s->regs.defs.SG_RESULT.sg_result = 250;
408408
s->regs.defs.DRV_STATUS.stst = 1;
409409

410-
qdev_init_gpio_in_named( DEVICE(obj),tmc2209_dir, "tmc2209-dir",1);
411-
qdev_init_gpio_in_named( DEVICE(obj),tmc2209_step, "tmc2209-step",1);
412-
qdev_init_gpio_in_named( DEVICE(obj),tmc2209_enable, "tmc2209-enable",1);
413-
qdev_init_gpio_out_named(DEVICE(obj),&s->irq_diag, "tmc2209-diag", 1);
414-
qdev_init_gpio_out_named(DEVICE(obj),&s->hard_out, "tmc2209-hard", 1);
415-
qdev_init_gpio_in_named( DEVICE(obj),tmc2209_receive, "tmc2209-byte-in",1);
416-
qdev_init_gpio_out_named(DEVICE(obj),&s->byte_out, "tmc2209-byte-out", 1);
417-
qdev_init_gpio_out_named(DEVICE(obj),&s->position_out, "tmc2209-step-out", 1);
410+
qdev_init_gpio_in_named( DEVICE(obj),tmc2209_dir, "dir",1);
411+
qdev_init_gpio_in_named( DEVICE(obj),tmc2209_step, "step",1);
412+
qdev_init_gpio_in_named( DEVICE(obj),tmc2209_enable, "enable",1);
413+
qdev_init_gpio_out_named(DEVICE(obj),&s->irq_diag, "diag", 1);
414+
qdev_init_gpio_out_named(DEVICE(obj),&s->hard_out, "hard", 1);
415+
qdev_init_gpio_in_named( DEVICE(obj),tmc2209_receive, "byte-in",1);
416+
qdev_init_gpio_out_named(DEVICE(obj),&s->byte_out, "byte-out", 1);
417+
qdev_init_gpio_out_named(DEVICE(obj),&s->position_out, "step-out", 1);
418418
qemu_set_irq(s->irq_diag,0);
419419
qemu_set_irq(s->hard_out,0);
420420

hw/arm/prusa/prusa-mini.c

+45-47
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
* Prusa Buddy board machine model
3-
*
3+
*
44
* Copyright 2020 VintagePC <github.com/vintagepc>
55
*
66
* Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -42,21 +42,22 @@ static void prusa_mini_init(MachineState *machine)
4242
{
4343
DeviceState *dev;
4444

45-
dev = qdev_new(TYPE_STM32F407_SOC);
45+
dev = qdev_new(TYPE_STM32F407xG_SOC);
4646
qdev_prop_set_string(dev, "cpu-type", ARM_CPU_TYPE_NAME("cortex-m4"));
4747
qdev_prop_set_uint32(dev,"sram-size", machine->ram_size);
4848
sysbus_realize(SYS_BUS_DEVICE(dev), &error_fatal);
49-
STM32F407State *SOC = STM32F407_SOC(dev);
50-
// We (ab)use the kernel command line to piggyback custom arguments into QEMU.
51-
// Parse those now.
49+
STM32F4xxState *SOC = STM32F4XX_BASE(dev);
50+
DeviceState* dev_soc = dev;
51+
// We (ab)use the kernel command line to piggyback custom arguments into QEMU.
52+
// Parse those now.
5253
arghelper_setargs(machine->kernel_cmdline);
53-
int default_flash_size = FLASH_SIZE;
54+
int default_flash_size = stm32_soc_get_flash_size(dev);
5455
if (arghelper_is_arg("4x_flash"))
5556
{
5657
default_flash_size <<=2; // quadruple the flash size for debug code.
5758
}
5859
if (arghelper_is_arg("appendix")) {
59-
SOC->gpio[GPIO_A].idr_mask |= 0x2000;
60+
SOC->gpios[0].idr_mask |= 0x2000;
6061
}
6162
int kernel_len = strlen(machine->kernel_filename);
6263
if (kernel_len >3)
@@ -77,7 +78,7 @@ static void prusa_mini_init(MachineState *machine)
7778
armv7m_load_kernel(ARM_CPU(first_cpu),
7879
BOOTLOADER_IMAGE,
7980
default_flash_size);
80-
}
81+
}
8182
else // Raw bin or ELF file, load directly.
8283
{
8384
armv7m_load_kernel(ARM_CPU(first_cpu),
@@ -93,41 +94,38 @@ static void prusa_mini_init(MachineState *machine)
9394

9495
void *bus;
9596
{
96-
bus = qdev_get_child_bus(DEVICE(&SOC->spi[1]), "ssi");
97+
bus = qdev_get_child_bus(DEVICE(&SOC->spis[1]), "ssi");
9798

9899
DeviceState *lcd_dev = ssi_create_peripheral(bus, "st7789v");
99100
qemu_irq lcd_cs = qdev_get_gpio_in_named(lcd_dev, SSI_GPIO_CS, 0);
100101

101102
/* Make sure the select pin is high. */
102103
qemu_irq_raise(lcd_cs);
103-
void *gpio = DEVICE(&SOC->gpio[GPIO_C]);
104-
qdev_connect_gpio_out(gpio,9,lcd_cs);
104+
qdev_connect_gpio_out(stm32_soc_get_periph(dev_soc, STM32_P_GPIOC),9,lcd_cs);
105105

106106
qemu_irq lcd_cd = qdev_get_gpio_in(lcd_dev,0);
107-
gpio = DEVICE(&SOC->gpio[GPIO_D]);
108-
qdev_connect_gpio_out(gpio,11, lcd_cd);
107+
qdev_connect_gpio_out(stm32_soc_get_periph(dev_soc, STM32_P_GPIOD),11, lcd_cd);
109108
}
110109
DriveInfo *dinfo = NULL;
111110
{
112-
bus = qdev_get_child_bus(DEVICE(&SOC->spi[2]), "ssi");
111+
bus = qdev_get_child_bus(DEVICE(&SOC->spis[2]), "ssi");
113112
dev = qdev_new("w25q64jv");
114113
dinfo = drive_get_next(IF_MTD);
115114
if (dinfo) {
116115
qdev_prop_set_drive(dev, "drive",
117116
blk_by_legacy_dinfo(dinfo));
118117
}
119118
qdev_realize_and_unref(dev, bus, &error_fatal);
120-
//DeviceState *flash_dev = ssi_create_slave(bus, "w25q64jv");
119+
//DeviceState *flash_dev = ssi_create_slave(bus, "w25q64jv");
121120
qemu_irq flash_cs = qdev_get_gpio_in_named(dev, SSI_GPIO_CS, 0);
122121
qemu_irq_raise(flash_cs);
123-
void* gpio = DEVICE(&SOC->gpio[GPIO_D]);
124-
qdev_connect_gpio_out(gpio, 7, flash_cs);
122+
qdev_connect_gpio_out(stm32_soc_get_periph(dev_soc, STM32_P_GPIOD), 7, flash_cs);
123+
124+
125125

126-
127-
128126
}
129127
{
130-
bus = qdev_get_child_bus(DEVICE(&SOC->i2c[0]),"i2c");
128+
bus = qdev_get_child_bus(DEVICE(&SOC->i2cs[0]),"i2c");
131129
dev = qdev_new("at24c-eeprom");
132130
qdev_prop_set_uint8(dev, "address", 0x53);
133131
qdev_prop_set_uint32(dev, "rom-size", 64*KiB);
@@ -139,7 +137,7 @@ static void prusa_mini_init(MachineState *machine)
139137
qdev_realize(dev, bus, &error_fatal);
140138
// The QEMU I2CBus doesn't support devices with multiple addresses, so fake it
141139
// with a second instance at the SYSTEM address.
142-
// bus = qdev_get_child_bus(DEVICE(&SOC->i2c[0]),"i2c");
140+
// bus = qdev_get_child_bus(DEVICE(&SOC->i2cs[0]),"i2c");
143141
dev = qdev_new("at24c-eeprom");
144142
qdev_prop_set_uint8(dev, "address", 0x57);
145143
qdev_prop_set_uint32(dev, "rom-size", 64*KiB);
@@ -159,9 +157,9 @@ static void prusa_mini_init(MachineState *machine)
159157
#ifdef BUDDY_HAS_GL
160158
DeviceState *gl_db = qdev_new("gl-dashboard");
161159
if (arghelper_is_arg("gfx-full")) {
162-
qdev_prop_set_uint8(gl_db, "dashboard_type", DB_MINI_FULL);
160+
qdev_prop_set_uint8(gl_db, "dashboard_type", DB_MINI_FULL);
163161
} else if (arghelper_is_arg("gfx-lite")) {
164-
qdev_prop_set_uint8(gl_db, "dashboard_type", DB_MINI_LITE);
162+
qdev_prop_set_uint8(gl_db, "dashboard_type", DB_MINI_LITE);
165163
}
166164
sysbus_realize(SYS_BUS_DEVICE(gl_db), &error_fatal);
167165
#else
@@ -182,7 +180,7 @@ static void prusa_mini_init(MachineState *machine)
182180
static const uint8_t dir_pins[4] = {0, 12, 15, 8};
183181
static const uint8_t en_pins[4] = {3, 14, 2, 10};
184182
static const uint8_t diag_pins[4] = {2, 1, 3, 15};
185-
static const uint8_t diag_ports[4] = {GPIO_E, GPIO_E, GPIO_E, GPIO_A};
183+
static const uint8_t diag_ports[4] = {STM32_P_GPIOE, STM32_P_GPIOE, STM32_P_GPIOE, STM32_P_GPIOA};
186184
static const uint8_t is_inverted[4] = {1,1,0,0};
187185
static const int32_t ends[4] = { 100*16*182, 100*16*183, 400*16*185,0 };
188186
static const int32_t stepsize[4] = { 100*16, 100*16, 400*16, 320*16 };
@@ -192,11 +190,11 @@ static void prusa_mini_init(MachineState *machine)
192190
DeviceState* split_out = qdev_new("split-irq");
193191
qdev_prop_set_uint16(split_out, "num-lines", 4);
194192
qdev_realize_and_unref(DEVICE(split_out),NULL, &error_fatal);
195-
qdev_connect_gpio_out_named(DEVICE(&SOC->usart[1]),"uart-byte-out", 0, qdev_get_gpio_in(split_out,0));
193+
qdev_connect_gpio_out_named(DEVICE(&SOC->usarts[1]),"uart-byte-out", 0, qdev_get_gpio_in(split_out,0));
196194
DeviceState* split_zmin = qdev_new("split-irq");
197195
qdev_prop_set_uint16(split_zmin, "num-lines", 3);
198196
qdev_realize_and_unref(DEVICE(split_zmin),NULL, &error_fatal);
199-
qdev_connect_gpio_out(split_zmin, 0, qdev_get_gpio_in(DEVICE(&SOC->gpio[GPIO_A]),8));
197+
qdev_connect_gpio_out(split_zmin, 0, qdev_get_gpio_in(stm32_soc_get_periph(dev_soc, STM32_P_GPIOA),8));
200198
qdev_connect_gpio_out(split_zmin, 1, qdev_get_gpio_in_named(db2,"led-digital",0));
201199
#ifdef BUDDY_HAS_GL
202200
qdev_connect_gpio_out(split_zmin, 2, qdev_get_gpio_in_named(gl_db,"indicator-analog",DB_IND_ZPROBE));
@@ -211,28 +209,26 @@ static void prusa_mini_init(MachineState *machine)
211209
qdev_prop_set_int32(dev, "max_step", ends[i]);
212210
qdev_prop_set_int32(dev, "fullstepspermm", stepsize[i]);
213211
sysbus_realize(SYS_BUS_DEVICE(dev), &error_fatal);
214-
qdev_connect_gpio_out_named(dev,"tmc2209-byte-out", 0, qdev_get_gpio_in_named(DEVICE(&SOC->usart[1]),"uart-byte-in",0));
215-
qdev_connect_gpio_out(split_out,i, qdev_get_gpio_in_named(dev,"tmc2209-byte-in",0));
216-
qdev_connect_gpio_out(DEVICE(&SOC->gpio[GPIO_D]), step_pins[i], qdev_get_gpio_in_named(dev,"tmc2209-step",0));
217-
qdev_connect_gpio_out(DEVICE(&SOC->gpio[GPIO_D]), dir_pins[i], qdev_get_gpio_in_named(dev,"tmc2209-dir",0));
212+
qdev_connect_gpio_out_named(dev,"byte-out", 0, qdev_get_gpio_in_named(DEVICE(&SOC->usarts[1]),"uart-byte-in",0));
213+
qdev_connect_gpio_out(split_out,i, qdev_get_gpio_in_named(dev,"byte-in",0));
214+
qdev_connect_gpio_out(stm32_soc_get_periph(dev_soc, STM32_P_GPIOD), step_pins[i], qdev_get_gpio_in_named(dev,"step",0));
215+
qdev_connect_gpio_out(stm32_soc_get_periph(dev_soc, STM32_P_GPIOD), dir_pins[i], qdev_get_gpio_in_named(dev,"dir",0));
218216
object_property_set_link(OBJECT(db2), links[i], OBJECT(dev), &error_fatal);
219-
qdev_connect_gpio_out_named(dev,"tmc2209-diag", 0, qdev_get_gpio_in(DEVICE(&SOC->gpio[diag_ports[i]]),diag_pins[i]));
220-
qdev_connect_gpio_out(DEVICE(&SOC->gpio[GPIO_D]), en_pins[i],qdev_get_gpio_in_named(dev,"tmc2209-enable",0));
221-
222-
217+
qdev_connect_gpio_out_named(dev,"diag", 0, qdev_get_gpio_in(stm32_soc_get_periph(dev_soc, diag_ports[i]),diag_pins[i]));
218+
qdev_connect_gpio_out(stm32_soc_get_periph(dev_soc, STM32_P_GPIOD), en_pins[i],qdev_get_gpio_in_named(dev,"enable",0));
223219
#ifdef BUDDY_HAS_GL
224220
if (i<3) {
225221
qemu_irq split_step = qemu_irq_split(
226-
qdev_get_gpio_in_named(pinda,"position_xyz",i),
222+
qdev_get_gpio_in_named(pinda,"position_xyz",i),
227223
qdev_get_gpio_in_named(gl_db,"motor-step",DB_MOTOR_X+i)
228224
);
229-
qdev_connect_gpio_out_named(dev,"tmc2209-step-out", 0,split_step);
225+
qdev_connect_gpio_out_named(dev,"step-out", 0,split_step);
230226
} else {
231-
qdev_connect_gpio_out_named(dev,"tmc2209-step-out", 0, qdev_get_gpio_in_named(gl_db,"motor-step",DB_MOTOR_X+i));
227+
qdev_connect_gpio_out_named(dev,"step-out", 0, qdev_get_gpio_in_named(gl_db,"motor-step",DB_MOTOR_X+i));
232228
}
233229
#else
234230
if (i<3) {
235-
qdev_connect_gpio_out_named(dev,"tmc2209-step-out", 0, qdev_get_gpio_in_named(pinda,"position_xyz",i));
231+
qdev_connect_gpio_out_named(dev,"step-out", 0, qdev_get_gpio_in_named(pinda,"position_xyz",i));
236232
}
237233
#endif
238234
}
@@ -254,8 +250,8 @@ static void prusa_mini_init(MachineState *machine)
254250
qdev_prop_set_uint16(dev, "table_no", tables[i]);
255251
qdev_prop_set_uint8(dev, "index", i);
256252
sysbus_realize(SYS_BUS_DEVICE(dev), &error_fatal);
257-
qdev_connect_gpio_out_named(DEVICE(&SOC->adc[0]),"adc_read", channels[i], qdev_get_gpio_in_named(dev, "thermistor_read_request",0));
258-
qdev_connect_gpio_out_named(dev, "thermistor_value",0, qdev_get_gpio_in_named(DEVICE(&SOC->adc[0]),"adc_data_in",channels[i]));
253+
qdev_connect_gpio_out_named(DEVICE(&SOC->adcs[0]),"adc_read", channels[i], qdev_get_gpio_in_named(dev, "thermistor_read_request",0));
254+
qdev_connect_gpio_out_named(dev, "thermistor_value",0, qdev_get_gpio_in_named(DEVICE(&SOC->adcs[0]),"adc_data_in",channels[i]));
259255
qdev_connect_gpio_out_named(dev, "temp_out_256x", 0, qdev_get_gpio_in_named(db2,"therm-temp",i));
260256

261257
}
@@ -267,6 +263,7 @@ static void prusa_mini_init(MachineState *machine)
267263
sysbus_realize(SYS_BUS_DEVICE(dev), &error_fatal);
268264
qdev_connect_gpio_out_named(DEVICE(&SOC->timers[2]),"pwm_ratio_changed",3,qdev_get_gpio_in_named(dev, "pwm_in",0));
269265
qdev_connect_gpio_out_named(dev, "temp_out",0, qdev_get_gpio_in_named(hotend, "thermistor_set_temperature",0));
266+
qdev_connect_gpio_out_named(dev, "pwm-out", 0, qdev_get_gpio_in_named(db2,"therm-pwm",0));
270267
#ifdef BUDDY_HAS_GL
271268
qemu_irq split_htr = qemu_irq_split(qdev_get_gpio_in_named(db2,"therm-pwm",0),qdev_get_gpio_in_named(gl_db,"indicator-analog",DB_IND_HTR));
272269
qdev_connect_gpio_out_named(dev, "pwm-out", 0, split_htr);
@@ -281,6 +278,7 @@ static void prusa_mini_init(MachineState *machine)
281278
sysbus_realize(SYS_BUS_DEVICE(dev), &error_fatal);
282279
qdev_connect_gpio_out_named(DEVICE(&SOC->timers[2]),"pwm_ratio_changed",2,qdev_get_gpio_in_named(dev, "pwm_in",0));
283280
qdev_connect_gpio_out_named(dev, "temp_out",0, qdev_get_gpio_in_named(bed, "thermistor_set_temperature",0));
281+
qdev_connect_gpio_out_named(dev, "pwm-out", 0, qdev_get_gpio_in_named(db2,"therm-pwm",1));
284282
#ifdef BUDDY_HAS_GL
285283
qemu_irq split_bed = qemu_irq_split(qdev_get_gpio_in_named(db2,"therm-pwm",1),qdev_get_gpio_in_named(gl_db,"indicator-analog",DB_IND_BED));
286284
qdev_connect_gpio_out_named(dev, "pwm-out", 0, split_bed);
@@ -291,7 +289,7 @@ static void prusa_mini_init(MachineState *machine)
291289

292290
dev = qdev_new("ir-sensor");
293291
sysbus_realize(SYS_BUS_DEVICE(dev), &error_fatal);
294-
qemu_irq split_fsensor = qemu_irq_split( qdev_get_gpio_in(DEVICE(&SOC->gpio[GPIO_B]),4),qemu_irq_invert(qdev_get_gpio_in_named(db2,"led-digital",1)));
292+
qemu_irq split_fsensor = qemu_irq_split( qdev_get_gpio_in(stm32_soc_get_periph(dev_soc, STM32_P_GPIOB),4),qemu_irq_invert(qdev_get_gpio_in_named(db2,"led-digital",1)));
295293
qdev_connect_gpio_out(dev, 0, split_fsensor);
296294

297295
// hotend = fan1
@@ -307,8 +305,8 @@ static void prusa_mini_init(MachineState *machine)
307305
qdev_prop_set_uint32(dev, "max_rpm",fan_max_rpms[i]);
308306
qdev_prop_set_bit(dev, "is_nonlinear", i); // E is nonlinear.
309307
sysbus_realize(SYS_BUS_DEVICE(dev), &error_fatal);
310-
qdev_connect_gpio_out_named(dev, "tach-out",0,qdev_get_gpio_in(DEVICE(&SOC->gpio[GPIO_E]),fan_tach_pins[i]));
311-
qdev_connect_gpio_out(DEVICE(&SOC->gpio[GPIO_E]),fan_pwm_pins[i],qdev_get_gpio_in_named(dev, "pwm-in-soft",0));
308+
qdev_connect_gpio_out_named(dev, "tach-out",0,qdev_get_gpio_in(stm32_soc_get_periph(dev_soc, STM32_P_GPIOE),fan_tach_pins[i]));
309+
qdev_connect_gpio_out(stm32_soc_get_periph(dev_soc, STM32_P_GPIOE),fan_pwm_pins[i],qdev_get_gpio_in_named(dev, "pwm-in-soft",0));
312310
qdev_connect_gpio_out_named(dev, "rpm-out", 0, qdev_get_gpio_in_named(db2,"fan-rpm",i));
313311
#ifdef BUDDY_HAS_GL
314312
qemu_irq split_fan = qemu_irq_split(qdev_get_gpio_in_named(db2,"fan-pwm",i),qdev_get_gpio_in_named(gl_db,"indicator-analog",DB_IND_PFAN+i));
@@ -320,9 +318,9 @@ static void prusa_mini_init(MachineState *machine)
320318

321319
dev = qdev_new("encoder-input");
322320
sysbus_realize(SYS_BUS_DEVICE(dev), &error_fatal);
323-
qdev_connect_gpio_out_named(dev, "encoder-button",0, qdev_get_gpio_in(DEVICE(&SOC->gpio[GPIO_E]),12));
324-
qdev_connect_gpio_out_named(dev, "encoder-a",0, qdev_get_gpio_in(DEVICE(&SOC->gpio[GPIO_E]),15));
325-
qdev_connect_gpio_out_named(dev, "encoder-b",0, qdev_get_gpio_in(DEVICE(&SOC->gpio[GPIO_E]),13));
321+
qdev_connect_gpio_out_named(dev, "encoder-button", 0, qdev_get_gpio_in(stm32_soc_get_periph(dev_soc, STM32_P_GPIOE),12));
322+
qdev_connect_gpio_out_named(dev, "encoder-a", 0, qdev_get_gpio_in(stm32_soc_get_periph(dev_soc, STM32_P_GPIOE),15));
323+
qdev_connect_gpio_out_named(dev, "encoder-b", 0, qdev_get_gpio_in(stm32_soc_get_periph(dev_soc, STM32_P_GPIOE),13));
326324

327325
// Needs to come last because it has the scripting engine setup.
328326
dev = qdev_new("p404-scriptcon");
@@ -342,7 +340,7 @@ static void prusa_mini_machine_init(MachineClass *mc)
342340
{
343341
mc->desc = "Prusa Mini";
344342
mc->init = prusa_mini_init;
345-
mc->default_ram_size = F407_SRAM_SIZE;
343+
mc->default_ram_size = 0; // 0 = use default RAM from chip.
346344
mc->no_parallel = 1;
347345
mc->no_serial = 1;
348346
}

0 commit comments

Comments
 (0)