Skip to contentSkip to conversation

Update the Netduino 2 Machine

PATCH Superseded Alistair Francis 2 participants 10 messages Jul 26, 2016 – Aug 1, 2016 Arm STM32

v5 of 8 Superseded Latest is v8 →

lore
Share & tools
lore
#0 lore raw

v5 cover Update the Netduino 2 Machine

This patchset continues with the Netduino 2 and STM32F205 SoC work.

This patch series makes a small change to the STM32F2xx SoC to tidy up the code.

Next a feature is added to the STM32F2xx timer to display the PWM duty cycle, when debugging is enabled.

Then the STM32F2xx SPI and ADC devices are added and connected to the STM32F205 SoC.

Finally the maintainers file is updated to add myself as the maintainer for the Netdunio 2 and STM32F2xx.

V5:
- Add a irq ORing function
V4:
- Add VMState to the new devices
- Remove rand() function
V3:
- Rebase
V2:
- Update based on Peter C's coments
- Rebase
- Create an ADC folder for the ADC device

Alistair Francis (8):
STM32F205: Remove the individual device variables
STM32F2xx: Display PWM duty cycle from timer
STM32F2xx: Add the ADC device
STM32F2xx: Add the SPI device
irq: Add a new irq device that allows the ORing of lines
STM32F205: Connect the ADC devices
STM32F205: Connect the SPI devices
MAINTAINERS: Add Alistair to the maintainers list

 MAINTAINERS                     |  15 ++
 default-configs/arm-softmmu.mak |   2 +
 hw/Makefile.objs                |   1 +
 hw/adc/Makefile.objs            |   1 +
 hw/adc/stm32f2xx_adc.c          | 306 ++++++++++++++++++++++++++++++++++++++++
 hw/arm/stm32f205_soc.c          |  82 ++++++++---
 hw/core/irq.c                   |  44 ++++++
 hw/ssi/Makefile.objs            |   1 +
 hw/ssi/stm32f2xx_spi.c          | 225 +++++++++++++++++++++++++++++
 hw/timer/stm32f2xx_timer.c      |   9 ++
 include/hw/adc/stm32f2xx_adc.h  |  87 ++++++++++++
 include/hw/arm/stm32f205_soc.h  |   6 +
 include/hw/irq.h                |  13 ++
 include/hw/ssi/stm32f2xx_spi.h  |  72 ++++++++++
 14 files changed, 846 insertions(+), 18 deletions(-)
 create mode 100644 hw/adc/Makefile.objs
 create mode 100644 hw/adc/stm32f2xx_adc.c
 create mode 100644 hw/ssi/stm32f2xx_spi.c
 create mode 100644 include/hw/adc/stm32f2xx_adc.h
 create mode 100644 include/hw/ssi/stm32f2xx_spi.h
Signature · 1 line
2.7.4
#1 lore raw

PATCH v5 1/8 STM32F205: Remove the individual device variables

Cleanup the individual DeviceState and SysBusDevice variables to re-use the same variable for each device.

---

 hw/arm/stm32f205_soc.c | 35 +++++++++++++++++------------------
 1 file changed, 17 insertions(+), 18 deletions(-)
hw/arm/stm32f205_soc.c +17 -18
index de26b8c..5b6fa3b 100644
@@ -62,8 +62,8 @@ static void stm32f205_soc_initfn(Object *obj)
 static void stm32f205_soc_realize(DeviceState *dev_soc, Error **errp)
 {
     STM32F205State *s = STM32F205_SOC(dev_soc);
-    DeviceState *syscfgdev, *usartdev, *timerdev, *nvic;
-    SysBusDevice *syscfgbusdev, *usartbusdev, *timerbusdev;
+    DeviceState *dev, *nvic;
+    SysBusDevice *busdev;
     Error *err = NULL;
     int i;
 
@@ -94,44 +94,43 @@ static void stm32f205_soc_realize(DeviceState *dev_soc, Error **errp)
                        s->kernel_filename, s->cpu_model);
 
     /* System configuration controller */
-    syscfgdev = DEVICE(&s->syscfg);
+    dev = DEVICE(&s->syscfg);
     object_property_set_bool(OBJECT(&s->syscfg), true, "realized", &err);
     if (err != NULL) {
         error_propagate(errp, err);
         return;
     }
-    syscfgbusdev = SYS_BUS_DEVICE(syscfgdev);
-    sysbus_mmio_map(syscfgbusdev, 0, 0x40013800);
-    sysbus_connect_irq(syscfgbusdev, 0, qdev_get_gpio_in(nvic, 71));
+    busdev = SYS_BUS_DEVICE(dev);
+    sysbus_mmio_map(busdev, 0, 0x40013800);
+    sysbus_connect_irq(busdev, 0, qdev_get_gpio_in(nvic, 71));
 
     /* Attach UART (uses USART registers) and USART controllers */
     for (i = 0; i < STM_NUM_USARTS; i++) {
-        usartdev = DEVICE(&(s->usart[i]));
-        qdev_prop_set_chr(usartdev, "chardev", i < MAX_SERIAL_PORTS ? serial_hds[i] : NULL);
+        dev = DEVICE(&(s->usart[i]));
+        qdev_prop_set_chr(dev, "chardev",
+                          i < MAX_SERIAL_PORTS ? serial_hds[i] : NULL);
         object_property_set_bool(OBJECT(&s->usart[i]), true, "realized", &err);
         if (err != NULL) {
             error_propagate(errp, err);
             return;
         }
-        usartbusdev = SYS_BUS_DEVICE(usartdev);
-        sysbus_mmio_map(usartbusdev, 0, usart_addr[i]);
-        sysbus_connect_irq(usartbusdev, 0,
-                           qdev_get_gpio_in(nvic, usart_irq[i]));
+        busdev = SYS_BUS_DEVICE(dev);
+        sysbus_mmio_map(busdev, 0, usart_addr[i]);
+        sysbus_connect_irq(busdev, 0, qdev_get_gpio_in(nvic, usart_irq[i]));
     }
 
     /* Timer 2 to 5 */
     for (i = 0; i < STM_NUM_TIMERS; i++) {
-        timerdev = DEVICE(&(s->timer[i]));
-        qdev_prop_set_uint64(timerdev, "clock-frequency", 1000000000);
+        dev = DEVICE(&(s->timer[i]));
+        qdev_prop_set_uint64(dev, "clock-frequency", 1000000000);
         object_property_set_bool(OBJECT(&s->timer[i]), true, "realized", &err);
         if (err != NULL) {
             error_propagate(errp, err);
             return;
         }
-        timerbusdev = SYS_BUS_DEVICE(timerdev);
-        sysbus_mmio_map(timerbusdev, 0, timer_addr[i]);
-        sysbus_connect_irq(timerbusdev, 0,
-                           qdev_get_gpio_in(nvic, timer_irq[i]));
+        busdev = SYS_BUS_DEVICE(dev);
+        sysbus_mmio_map(busdev, 0, timer_addr[i]);
+        sysbus_connect_irq(busdev, 0, qdev_get_gpio_in(nvic, timer_irq[i]));
     }
 }
 
Signature · 1 line
2.7.4
#2 lore raw

PATCH v5 2/8 STM32F2xx: Display PWM duty cycle from timer

In reply to Alistair Francis

If correctly configured allow the STM32F2xx timer to print out the PWM duty cycle information.

---
V3:
- Use OR instead of + for masking
- Improve clarity of print statement
V2:
- Fix up if statement braces
- Remove stm32f2xx_timer_set_alarm() call

 hw/timer/stm32f2xx_timer.c | 9 +++++++++
 1 file changed, 9 insertions(+)
hw/timer/stm32f2xx_timer.c +9 -0
index bf0fb28..8c4c1f9 100644
@@ -51,6 +51,15 @@ static void stm32f2xx_timer_interrupt(void *opaque)
         qemu_irq_pulse(s->irq);
         stm32f2xx_timer_set_alarm(s, s->hit_time);
     }
+
+    if (s->tim_ccmr1 & (TIM_CCMR1_OC2M2 | TIM_CCMR1_OC2M1) &&
+        !(s->tim_ccmr1 & TIM_CCMR1_OC2M0) &&
+        s->tim_ccmr1 & TIM_CCMR1_OC2PE &&
+        s->tim_ccer & TIM_CCER_CC2E) {
+        /* PWM 2 - Mode 1 */
+        DB_PRINT("PWM2 Duty Cycle: %d%%\n",
+                s->tim_ccr2 / (100 * (s->tim_psc + 1)));
+    }
 }
 
 static inline int64_t stm32f2xx_ns_to_ticks(STM32F2XXTimerState *s, int64_t t)
Signature · 1 line
2.7.4
#3 lore raw

PATCH v5 3/8 STM32F2xx: Add the ADC device

In reply to Alistair Francis

Add the STM32F2xx ADC device. This device randomly generates values on each read.

This also includes creating a hw/adc directory.

---
V4:
- Remove the rand() function
- Add VMState
- Small cleanups
V2:
- Address Peter C's comments
- Create a ADC folder and move the file in there
- Move some of the registers into arrays

 default-configs/arm-softmmu.mak |   1 +
 hw/Makefile.objs                |   1 +
 hw/adc/Makefile.objs            |   1 +
 hw/adc/stm32f2xx_adc.c          | 306 ++++++++++++++++++++++++++++++++++++++++
 include/hw/adc/stm32f2xx_adc.h  |  87 ++++++++++++
 5 files changed, 396 insertions(+)
 create mode 100644 hw/adc/Makefile.objs
 create mode 100644 hw/adc/stm32f2xx_adc.c
 create mode 100644 include/hw/adc/stm32f2xx_adc.h
default-configs/arm-softmmu.mak +1 -0
index 7a19863..5b1696d 100644
@@ -87,6 +87,7 @@ CONFIG_ZYNQ=y
 CONFIG_STM32F2XX_TIMER=y
 CONFIG_STM32F2XX_USART=y
 CONFIG_STM32F2XX_SYSCFG=y
+CONFIG_STM32F2XX_ADC=y
 CONFIG_STM32F205_SOC=y
 
 CONFIG_VERSATILE_PCI=y
hw/Makefile.objs +1 -0
index 4a07ed4..0ffd281 100644
@@ -1,5 +1,6 @@
 devices-dirs-$(call land, $(CONFIG_VIRTIO),$(call land,$(CONFIG_VIRTFS),$(CONFIG_PCI))) += 9pfs/
 devices-dirs-$(CONFIG_ACPI) += acpi/
+devices-dirs-$(CONFIG_SOFTMMU) += adc/
 devices-dirs-$(CONFIG_SOFTMMU) += audio/
 devices-dirs-$(CONFIG_SOFTMMU) += block/
 devices-dirs-$(CONFIG_SOFTMMU) += bt/
hw/adc/Makefile.objs new file +1 -0
new file mode 100644
index 0000000..3f6dfde
@@ -0,0 +1 @@
+obj-$(CONFIG_STM32F2XX_ADC) += stm32f2xx_adc.o
hw/adc/stm32f2xx_adc.c new file +306 -0

306 lines not on this page · raw message

include/hw/adc/stm32f2xx_adc.h new file +87 -0

87 lines not on this page · raw message

Signature · 1 line
2.7.4
#4 lore raw

PATCH v5 4/8 STM32F2xx: Add the SPI device

In reply to Alistair Francis

Add the STM32F2xx SPI device.

---
V4:
- Add VMState
- Small fixes
V2:
- Address Peter C's comments

 default-configs/arm-softmmu.mak |   1 +
 hw/ssi/Makefile.objs            |   1 +
 hw/ssi/stm32f2xx_spi.c          | 225 ++++++++++++++++++++++++++++++++++++++++
 include/hw/ssi/stm32f2xx_spi.h  |  72 +++++++++++++
 4 files changed, 299 insertions(+)
 create mode 100644 hw/ssi/stm32f2xx_spi.c
 create mode 100644 include/hw/ssi/stm32f2xx_spi.h
default-configs/arm-softmmu.mak +1 -0
index 5b1696d..e9e2de3 100644
@@ -88,6 +88,7 @@ CONFIG_STM32F2XX_TIMER=y
 CONFIG_STM32F2XX_USART=y
 CONFIG_STM32F2XX_SYSCFG=y
 CONFIG_STM32F2XX_ADC=y
+CONFIG_STM32F2XX_SPI=y
 CONFIG_STM32F205_SOC=y
 
 CONFIG_VERSATILE_PCI=y
hw/ssi/Makefile.objs +1 -0
index c79a8dc..487add2 100644
@@ -3,6 +3,7 @@ common-obj-$(CONFIG_SSI) += ssi.o
 common-obj-$(CONFIG_XILINX_SPI) += xilinx_spi.o
 common-obj-$(CONFIG_XILINX_SPIPS) += xilinx_spips.o
 common-obj-$(CONFIG_ASPEED_SOC) += aspeed_smc.o
+common-obj-$(CONFIG_STM32F2XX_SPI) += stm32f2xx_spi.o
 
 obj-$(CONFIG_OMAP) += omap_spi.o
 obj-$(CONFIG_IMX) += imx_spi.o
hw/ssi/stm32f2xx_spi.c new file +225 -0

225 lines not on this page · raw message

include/hw/ssi/stm32f2xx_spi.h new file +72 -0

72 lines not on this page · raw message

Signature · 1 line
2.7.4
#5 lore raw

PATCH v5 5/8 irq: Add a new irq device that allows the ORing of lines

In reply to Alistair Francis

---

 hw/core/irq.c    | 44 ++++++++++++++++++++++++++++++++++++++++++++
 include/hw/irq.h | 13 +++++++++++++
 2 files changed, 57 insertions(+)
hw/core/irq.c +44 -0
index 49ff2e6..73b18b4 100644
@@ -27,6 +27,7 @@
 #include "qom/object.h"
 
 #define IRQ(obj) OBJECT_CHECK(struct IRQState, (obj), TYPE_IRQ)
+#define OR_IRQ(obj) OBJECT_CHECK(struct OrIRQState, (obj), TYPE_OR_IRQ)
 
 struct IRQState {
     Object parent_obj;
@@ -36,6 +37,15 @@ struct IRQState {
     int n;
 };
 
+struct OrIRQState {
+    Object parent_obj;
+
+    qemu_irq in_irq;
+    qemu_irq *out_irqs;
+    int *levels;
+    int n;
+};
+
 void qemu_set_irq(qemu_irq irq, int level)
 {
     if (!irq)
@@ -77,6 +87,33 @@ qemu_irq qemu_allocate_irq(qemu_irq_handler handler, void *opaque, int n)
     return irq;
 }
 
+static void or_irq_handler(void *opaque, int n, int level)
+{
+    qemu_or_irq or_irq = (qemu_or_irq) opaque;
+    int or_level = 0;
+    int i;
+
+    or_irq->levels[n] = level;
+
+    for (i = 0; i < or_irq->n; i++) {
+        or_level |= or_irq->levels[i];
+    }
+
+    qemu_set_irq(or_irq->in_irq, or_level);
+}
+
+qemu_irq *qemu_allocate_or_irqs(qemu_irq in_irq, int n)
+{
+    qemu_or_irq or_irq = OR_IRQ(object_new(TYPE_OR_IRQ));
+
+    or_irq->out_irqs = qemu_allocate_irqs(or_irq_handler, or_irq, n);
+    or_irq->in_irq = in_irq;
+    or_irq->levels = g_new(int, n);
+    or_irq->n = n;
+
+    return or_irq->out_irqs;
+}
+
 void qemu_free_irqs(qemu_irq *s, int n)
 {
     int i;
@@ -151,9 +188,16 @@ static const TypeInfo irq_type_info = {
    .instance_size = sizeof(struct IRQState),
 };
 
+static const TypeInfo or_irq_type_info = {
+   .name = TYPE_OR_IRQ,
+   .parent = TYPE_OBJECT,
+   .instance_size = sizeof(struct OrIRQState),
+};
+
 static void irq_register_types(void)
 {
     type_register_static(&irq_type_info);
+    type_register_static(&or_irq_type_info);
 }
 
 type_init(irq_register_types)
include/hw/irq.h +13 -0
index 4c4c2ea..aeb7eb7 100644
@@ -4,8 +4,10 @@
 /* Generic IRQ/GPIO pin infrastructure.  */
 
 #define TYPE_IRQ "irq"
+#define TYPE_OR_IRQ "or-irq"
 
 typedef struct IRQState *qemu_irq;
+typedef struct OrIRQState *qemu_or_irq;
 
 typedef void (*qemu_irq_handler)(void *opaque, int n, int level);
 
@@ -38,6 +40,17 @@ qemu_irq *qemu_allocate_irqs(qemu_irq_handler handler, void *opaque, int n);
  */
 qemu_irq qemu_allocate_irq(qemu_irq_handler handler, void *opaque, int n);
 
+/*
+ * qemu_allocate_or_irqs
+ * @in_irq: An input IRQ. It will be the result of the @out_irqs ORed together
+ * @n: The number of interrupt lines that should be ORed together
+ *
+ * returns: An array of interrupts that should be ORed together
+ *
+ * OR all of the interrupts returned in the array into a single @in_irq.
+ */
+qemu_irq *qemu_allocate_or_irqs(qemu_irq in_irq, int n);
+
 /* Extends an Array of IRQs. Old IRQs have their handlers and opaque data
  * preserved. New IRQs are assigned the argument handler and opaque data.
  */
Signature · 1 line
2.7.4
#6 lore raw

Re: [Qemu-devel] [PATCH v5 5/8] irq: Add a new irq device that allows the ORing of lines

Quoted 20 lines · Alistair Francis

---

 hw/core/irq.c    | 44 ++++++++++++++++++++++++++++++++++++++++++++
 include/hw/irq.h | 13 +++++++++++++
 2 files changed, 57 insertions(+)
hw/core/irq.c +1 -0
index 49ff2e6..73b18b4 100644
@@ -27,6 +27,7 @@
 #include "qom/object.h"
 
 #define IRQ(obj) OBJECT_CHECK(struct IRQState, (obj), TYPE_IRQ)
+#define OR_IRQ(obj) OBJECT_CHECK(struct OrIRQState, (obj), TYPE_OR_IRQ)
 
 struct IRQState {
     Object parent_obj;

hw/core/irq.c struct IRQState { · line 45

Quoted 9 lines
hw/core/irq.c +6 -0
@@ -36,6 +37,15 @@ struct IRQState {
     int n;
 };
 
+struct OrIRQState {
+    Object parent_obj;
+
+    qemu_irq in_irq;
+    qemu_irq *out_irqs;
+    int *levels;

The data in the memory pointed to by 'levels' is state, and you need to migrate it somehow. (Otherwise you'll give the wrong results the next time an input changes following a migration.)

thanks
-- PMM

#7 lore raw

Re: [Qemu-devel] [PATCH v5 5/8] irq: Add a new irq device that allows the ORing of lines

Quoted 24 lines · Peter Maydell
Quoted 23 lines · Alistair Francis

---

 hw/core/irq.c    | 44 ++++++++++++++++++++++++++++++++++++++++++++
 include/hw/irq.h | 13 +++++++++++++
 2 files changed, 57 insertions(+)
hw/core/irq.c +1 -0
index 49ff2e6..73b18b4 100644
@@ -27,6 +27,7 @@
 #include "qom/object.h"
 
 #define IRQ(obj) OBJECT_CHECK(struct IRQState, (obj), TYPE_IRQ)
+#define OR_IRQ(obj) OBJECT_CHECK(struct OrIRQState, (obj), TYPE_OR_IRQ)
 
 struct IRQState {
     Object parent_obj;
@@ -36,6 +37,15 @@ struct IRQState {
     int n;
 };
 
Quoted 10 lines

hw/core/irq.c struct IRQState { · line 45

Quoted 6 lines
hw/core/irq.c +6 -0
+struct OrIRQState {
+    Object parent_obj;
+
+    qemu_irq in_irq;
+    qemu_irq *out_irqs;
+    int *levels;

The data in the memory pointed to by 'levels' is state, and you need to migrate it somehow. (Otherwise you'll give the wrong results the next time an input changes following a migration.)

A simple vmstate should be enough for that right?

Thanks,

Alistair

Quoted 4 lines

thanks
-- PMM

#8 lore raw

Re: [Qemu-devel] [PATCH v5 5/8] irq: Add a new irq device that allows the ORing of lines

Quoted 6 lines · Alistair Francis
Quoted 3 lines · Peter Maydell

The data in the memory pointed to by 'levels' is state, and you need to migrate it somehow. (Otherwise you'll give the wrong results the next time an input changes following a migration.)

A simple vmstate should be enough for that right?

Yes (but if you don't inherit from DeviceState you won't have anywhere convenient to hook it up).

thanks
-- PMM

#9 lore raw

PATCH v5 8/8 MAINTAINERS: Add Alistair to the maintainers list

In reply to Alistair Francis

Add Alistair Francis as the maintainer for the Netduino 2 and SMM32F205 SoC.

---

 MAINTAINERS | 15 +++++++++++++++
 1 file changed, 15 insertions(+)
MAINTAINERS +15 -0
index d1439a8..e55be55 100644
@@ -475,6 +475,21 @@ S: Maintained
 F: hw/arm/virt-acpi-build.c
 F: include/hw/arm/virt-acpi-build.h
 
+STM32F205
+M: Alistair Francis <[email protected]>
+S: Maintained
+F: hw/arm/stm32f205_soc.c
+F: hw/misc/stm32f2xx_syscfg.c
+F: hw/char/stm32f2xx_usart.c
+F: hw/timer/stm32f2xx_timer.c
+F: hw/adc/*
+F: hw/ssi/stm32f2xx_spi.c
+
+Netduino 2
+M: Alistair Francis <[email protected]>
+S: Maintained
+F: hw/arm/netduino2.c
+
 CRIS Machines
 -------------
 Axis Dev88
Signature · 1 line
2.7.4