1
1
/*
2
2
* Prusa Buddy board machine model
3
- *
3
+ *
4
4
* Copyright 2020 VintagePC <github.com/vintagepc>
5
5
*
6
6
* Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -42,21 +42,22 @@ static void prusa_mini_init(MachineState *machine)
42
42
{
43
43
DeviceState * dev ;
44
44
45
- dev = qdev_new (TYPE_STM32F407_SOC );
45
+ dev = qdev_new (TYPE_STM32F407xG_SOC );
46
46
qdev_prop_set_string (dev , "cpu-type" , ARM_CPU_TYPE_NAME ("cortex-m4" ));
47
47
qdev_prop_set_uint32 (dev ,"sram-size" , machine -> ram_size );
48
48
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.
52
53
arghelper_setargs (machine -> kernel_cmdline );
53
- int default_flash_size = FLASH_SIZE ;
54
+ int default_flash_size = stm32_soc_get_flash_size ( dev ) ;
54
55
if (arghelper_is_arg ("4x_flash" ))
55
56
{
56
57
default_flash_size <<=2 ; // quadruple the flash size for debug code.
57
58
}
58
59
if (arghelper_is_arg ("appendix" )) {
59
- SOC -> gpio [ GPIO_A ].idr_mask |= 0x2000 ;
60
+ SOC -> gpios [ 0 ].idr_mask |= 0x2000 ;
60
61
}
61
62
int kernel_len = strlen (machine -> kernel_filename );
62
63
if (kernel_len > 3 )
@@ -77,7 +78,7 @@ static void prusa_mini_init(MachineState *machine)
77
78
armv7m_load_kernel (ARM_CPU (first_cpu ),
78
79
BOOTLOADER_IMAGE ,
79
80
default_flash_size );
80
- }
81
+ }
81
82
else // Raw bin or ELF file, load directly.
82
83
{
83
84
armv7m_load_kernel (ARM_CPU (first_cpu ),
@@ -93,41 +94,38 @@ static void prusa_mini_init(MachineState *machine)
93
94
94
95
void * bus ;
95
96
{
96
- bus = qdev_get_child_bus (DEVICE (& SOC -> spi [1 ]), "ssi" );
97
+ bus = qdev_get_child_bus (DEVICE (& SOC -> spis [1 ]), "ssi" );
97
98
98
99
DeviceState * lcd_dev = ssi_create_peripheral (bus , "st7789v" );
99
100
qemu_irq lcd_cs = qdev_get_gpio_in_named (lcd_dev , SSI_GPIO_CS , 0 );
100
101
101
102
/* Make sure the select pin is high. */
102
103
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 );
105
105
106
106
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 );
109
108
}
110
109
DriveInfo * dinfo = NULL ;
111
110
{
112
- bus = qdev_get_child_bus (DEVICE (& SOC -> spi [2 ]), "ssi" );
111
+ bus = qdev_get_child_bus (DEVICE (& SOC -> spis [2 ]), "ssi" );
113
112
dev = qdev_new ("w25q64jv" );
114
113
dinfo = drive_get_next (IF_MTD );
115
114
if (dinfo ) {
116
115
qdev_prop_set_drive (dev , "drive" ,
117
116
blk_by_legacy_dinfo (dinfo ));
118
117
}
119
118
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");
121
120
qemu_irq flash_cs = qdev_get_gpio_in_named (dev , SSI_GPIO_CS , 0 );
122
121
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
+
125
125
126
-
127
-
128
126
}
129
127
{
130
- bus = qdev_get_child_bus (DEVICE (& SOC -> i2c [0 ]),"i2c" );
128
+ bus = qdev_get_child_bus (DEVICE (& SOC -> i2cs [0 ]),"i2c" );
131
129
dev = qdev_new ("at24c-eeprom" );
132
130
qdev_prop_set_uint8 (dev , "address" , 0x53 );
133
131
qdev_prop_set_uint32 (dev , "rom-size" , 64 * KiB );
@@ -139,7 +137,7 @@ static void prusa_mini_init(MachineState *machine)
139
137
qdev_realize (dev , bus , & error_fatal );
140
138
// The QEMU I2CBus doesn't support devices with multiple addresses, so fake it
141
139
// 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");
143
141
dev = qdev_new ("at24c-eeprom" );
144
142
qdev_prop_set_uint8 (dev , "address" , 0x57 );
145
143
qdev_prop_set_uint32 (dev , "rom-size" , 64 * KiB );
@@ -159,9 +157,9 @@ static void prusa_mini_init(MachineState *machine)
159
157
#ifdef BUDDY_HAS_GL
160
158
DeviceState * gl_db = qdev_new ("gl-dashboard" );
161
159
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 );
163
161
} 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 );
165
163
}
166
164
sysbus_realize (SYS_BUS_DEVICE (gl_db ), & error_fatal );
167
165
#else
@@ -182,7 +180,7 @@ static void prusa_mini_init(MachineState *machine)
182
180
static const uint8_t dir_pins [4 ] = {0 , 12 , 15 , 8 };
183
181
static const uint8_t en_pins [4 ] = {3 , 14 , 2 , 10 };
184
182
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 };
186
184
static const uint8_t is_inverted [4 ] = {1 ,1 ,0 ,0 };
187
185
static const int32_t ends [4 ] = { 100 * 16 * 182 , 100 * 16 * 183 , 400 * 16 * 185 ,0 };
188
186
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)
192
190
DeviceState * split_out = qdev_new ("split-irq" );
193
191
qdev_prop_set_uint16 (split_out , "num-lines" , 4 );
194
192
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 ));
196
194
DeviceState * split_zmin = qdev_new ("split-irq" );
197
195
qdev_prop_set_uint16 (split_zmin , "num-lines" , 3 );
198
196
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 ));
200
198
qdev_connect_gpio_out (split_zmin , 1 , qdev_get_gpio_in_named (db2 ,"led-digital" ,0 ));
201
199
#ifdef BUDDY_HAS_GL
202
200
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)
211
209
qdev_prop_set_int32 (dev , "max_step" , ends [i ]);
212
210
qdev_prop_set_int32 (dev , "fullstepspermm" , stepsize [i ]);
213
211
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 ));
218
216
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 ));
223
219
#ifdef BUDDY_HAS_GL
224
220
if (i < 3 ) {
225
221
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 ),
227
223
qdev_get_gpio_in_named (gl_db ,"motor-step" ,DB_MOTOR_X + i )
228
224
);
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 );
230
226
} 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 ));
232
228
}
233
229
#else
234
230
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 ));
236
232
}
237
233
#endif
238
234
}
@@ -254,8 +250,8 @@ static void prusa_mini_init(MachineState *machine)
254
250
qdev_prop_set_uint16 (dev , "table_no" , tables [i ]);
255
251
qdev_prop_set_uint8 (dev , "index" , i );
256
252
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 ]));
259
255
qdev_connect_gpio_out_named (dev , "temp_out_256x" , 0 , qdev_get_gpio_in_named (db2 ,"therm-temp" ,i ));
260
256
261
257
}
@@ -267,6 +263,7 @@ static void prusa_mini_init(MachineState *machine)
267
263
sysbus_realize (SYS_BUS_DEVICE (dev ), & error_fatal );
268
264
qdev_connect_gpio_out_named (DEVICE (& SOC -> timers [2 ]),"pwm_ratio_changed" ,3 ,qdev_get_gpio_in_named (dev , "pwm_in" ,0 ));
269
265
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 ));
270
267
#ifdef BUDDY_HAS_GL
271
268
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 ));
272
269
qdev_connect_gpio_out_named (dev , "pwm-out" , 0 , split_htr );
@@ -281,6 +278,7 @@ static void prusa_mini_init(MachineState *machine)
281
278
sysbus_realize (SYS_BUS_DEVICE (dev ), & error_fatal );
282
279
qdev_connect_gpio_out_named (DEVICE (& SOC -> timers [2 ]),"pwm_ratio_changed" ,2 ,qdev_get_gpio_in_named (dev , "pwm_in" ,0 ));
283
280
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 ));
284
282
#ifdef BUDDY_HAS_GL
285
283
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 ));
286
284
qdev_connect_gpio_out_named (dev , "pwm-out" , 0 , split_bed );
@@ -291,7 +289,7 @@ static void prusa_mini_init(MachineState *machine)
291
289
292
290
dev = qdev_new ("ir-sensor" );
293
291
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 )));
295
293
qdev_connect_gpio_out (dev , 0 , split_fsensor );
296
294
297
295
// hotend = fan1
@@ -307,8 +305,8 @@ static void prusa_mini_init(MachineState *machine)
307
305
qdev_prop_set_uint32 (dev , "max_rpm" ,fan_max_rpms [i ]);
308
306
qdev_prop_set_bit (dev , "is_nonlinear" , i ); // E is nonlinear.
309
307
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 ));
312
310
qdev_connect_gpio_out_named (dev , "rpm-out" , 0 , qdev_get_gpio_in_named (db2 ,"fan-rpm" ,i ));
313
311
#ifdef BUDDY_HAS_GL
314
312
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)
320
318
321
319
dev = qdev_new ("encoder-input" );
322
320
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 ));
326
324
327
325
// Needs to come last because it has the scripting engine setup.
328
326
dev = qdev_new ("p404-scriptcon" );
@@ -342,7 +340,7 @@ static void prusa_mini_machine_init(MachineClass *mc)
342
340
{
343
341
mc -> desc = "Prusa Mini" ;
344
342
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.
346
344
mc -> no_parallel = 1 ;
347
345
mc -> no_serial = 1 ;
348
346
}
0 commit comments