* [Qemu-devel] [PATCH v3 0/7] Update the Netduino 2 Machine
@ 2016-01-19 7:22 Alistair Francis
2016-01-19 7:23 ` [Qemu-devel] [PATCH v3 1/7] STM32F205: Remove the individual device variables Alistair Francis
` (5 more replies)
0 siblings, 6 replies; 14+ messages in thread
From: Alistair Francis @ 2016-01-19 7:22 UTC (permalink / raw)
To: qemu-devel, peter.crosthwaite; +Cc: peter.maydell, konstanty, alistair23
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.
V3:
- Rebase
V2:
- Update based on Peter C's coments
- Rebase
- Create an ADC folder for the ADC device
Alistair Francis (7):
STM32F205: Remove the individual device variables
STM32F2xx: Display PWM duty cycle from timer
STM32F2xx: Add the ADC device
STM32F2xx: Add the SPI device
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 | 283 ++++++++++++++++++++++++++++++++++++++++
hw/arm/stm32f205_soc.c | 76 ++++++++---
hw/ssi/Makefile.objs | 1 +
hw/ssi/stm32f2xx_spi.c | 205 +++++++++++++++++++++++++++++
hw/timer/stm32f2xx_timer.c | 9 ++
include/hw/adc/stm32f2xx_adc.h | 94 +++++++++++++
include/hw/arm/stm32f205_soc.h | 6 +
include/hw/ssi/stm32f2xx_spi.h | 72 ++++++++++
12 files changed, 748 insertions(+), 17 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
--
2.5.0
^ permalink raw reply [flat|nested] 14+ messages in thread
* [Qemu-devel] [PATCH v3 1/7] STM32F205: Remove the individual device variables
2016-01-19 7:22 [Qemu-devel] [PATCH v3 0/7] Update the Netduino 2 Machine Alistair Francis
@ 2016-01-19 7:23 ` Alistair Francis
2016-01-19 7:23 ` [Qemu-devel] [PATCH v3 2/7] STM32F2xx: Display PWM duty cycle from timer Alistair Francis
` (4 subsequent siblings)
5 siblings, 0 replies; 14+ messages in thread
From: Alistair Francis @ 2016-01-19 7:23 UTC (permalink / raw)
To: qemu-devel, peter.crosthwaite; +Cc: peter.maydell, konstanty, alistair23
Cleanup the individual DeviceState and SysBusDevice
variables to re-use the same variable for each
device.
Signed-off-by: Alistair Francis <alistair@alistair23.me>
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
---
hw/arm/stm32f205_soc.c | 32 +++++++++++++++-----------------
1 file changed, 15 insertions(+), 17 deletions(-)
diff --git a/hw/arm/stm32f205_soc.c b/hw/arm/stm32f205_soc.c
index 79bfe6d..a2bd970 100644
--- a/hw/arm/stm32f205_soc.c
+++ b/hw/arm/stm32f205_soc.c
@@ -60,8 +60,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;
@@ -92,43 +92,41 @@ 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]));
+ dev = DEVICE(&(s->usart[i]));
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]));
}
}
--
2.5.0
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [Qemu-devel] [PATCH v3 2/7] STM32F2xx: Display PWM duty cycle from timer
2016-01-19 7:22 [Qemu-devel] [PATCH v3 0/7] Update the Netduino 2 Machine Alistair Francis
2016-01-19 7:23 ` [Qemu-devel] [PATCH v3 1/7] STM32F205: Remove the individual device variables Alistair Francis
@ 2016-01-19 7:23 ` Alistair Francis
2016-01-19 7:23 ` [Qemu-devel] [PATCH v3 3/7] STM32F2xx: Add the ADC device Alistair Francis
` (3 subsequent siblings)
5 siblings, 0 replies; 14+ messages in thread
From: Alistair Francis @ 2016-01-19 7:23 UTC (permalink / raw)
To: qemu-devel, peter.crosthwaite; +Cc: peter.maydell, konstanty, alistair23
If correctly configured allow the STM32F2xx timer to print
out the PWM duty cycle information.
Signed-off-by: Alistair Francis <alistair@alistair23.me>
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
---
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(+)
diff --git a/hw/timer/stm32f2xx_timer.c b/hw/timer/stm32f2xx_timer.c
index ecadf9d..6e33a99 100644
--- a/hw/timer/stm32f2xx_timer.c
+++ b/hw/timer/stm32f2xx_timer.c
@@ -49,6 +49,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)
--
2.5.0
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [Qemu-devel] [PATCH v3 3/7] STM32F2xx: Add the ADC device
2016-01-19 7:22 [Qemu-devel] [PATCH v3 0/7] Update the Netduino 2 Machine Alistair Francis
2016-01-19 7:23 ` [Qemu-devel] [PATCH v3 1/7] STM32F205: Remove the individual device variables Alistair Francis
2016-01-19 7:23 ` [Qemu-devel] [PATCH v3 2/7] STM32F2xx: Display PWM duty cycle from timer Alistair Francis
@ 2016-01-19 7:23 ` Alistair Francis
2016-02-02 15:17 ` Peter Maydell
2016-01-19 7:23 ` [Qemu-devel] [PATCH v3 4/7] STM32F2xx: Add the SPI device Alistair Francis
` (2 subsequent siblings)
5 siblings, 1 reply; 14+ messages in thread
From: Alistair Francis @ 2016-01-19 7:23 UTC (permalink / raw)
To: qemu-devel, peter.crosthwaite; +Cc: peter.maydell, konstanty, alistair23
Add the STM32F2xx ADC device. This device randomly
generates values on each read.
This also includes creating a hw/adc directory.
Signed-off-by: Alistair Francis <alistair@alistair23.me>
---
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 | 283 ++++++++++++++++++++++++++++++++++++++++
include/hw/adc/stm32f2xx_adc.h | 94 +++++++++++++
5 files changed, 380 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
diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index d9b90a5..520b209 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -85,6 +85,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
diff --git a/hw/Makefile.objs b/hw/Makefile.objs
index 4a07ed4..0ffd281 100644
--- a/hw/Makefile.objs
+++ b/hw/Makefile.objs
@@ -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/
diff --git a/hw/adc/Makefile.objs b/hw/adc/Makefile.objs
new file mode 100644
index 0000000..3f6dfde
--- /dev/null
+++ b/hw/adc/Makefile.objs
@@ -0,0 +1 @@
+obj-$(CONFIG_STM32F2XX_ADC) += stm32f2xx_adc.o
diff --git a/hw/adc/stm32f2xx_adc.c b/hw/adc/stm32f2xx_adc.c
new file mode 100644
index 0000000..f7249b7
--- /dev/null
+++ b/hw/adc/stm32f2xx_adc.c
@@ -0,0 +1,283 @@
+/*
+ * STM32F2XX ADC
+ *
+ * Copyright (c) 2014 Alistair Francis <alistair@alistair23.me>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "hw/sysbus.h"
+#include "hw/hw.h"
+#include "hw/adc/stm32f2xx_adc.h"
+
+#ifndef STM_ADC_ERR_DEBUG
+#define STM_ADC_ERR_DEBUG 0
+#endif
+
+#define DB_PRINT_L(lvl, fmt, args...) do { \
+ if (STM_ADC_ERR_DEBUG >= lvl) { \
+ qemu_log("%s: " fmt, __func__, ## args); \
+ } \
+} while (0);
+
+#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)
+
+static void stm32f2xx_adc_reset(DeviceState *dev)
+{
+ STM32F2XXADCState *s = STM32F2XX_ADC(dev);
+
+ s->adc_sr = 0x00000000;
+ s->adc_cr1 = 0x00000000;
+ s->adc_cr2 = 0x00000000;
+ s->adc_smpr1 = 0x00000000;
+ s->adc_smpr2 = 0x00000000;
+ s->adc_jofr[0] = 0x00000000;
+ s->adc_jofr[1] = 0x00000000;
+ s->adc_jofr[2] = 0x00000000;
+ s->adc_jofr[3] = 0x00000000;
+ s->adc_htr = 0x00000FFF;
+ s->adc_ltr = 0x00000000;
+ s->adc_sqr1 = 0x00000000;
+ s->adc_sqr2 = 0x00000000;
+ s->adc_sqr3 = 0x00000000;
+ s->adc_jsqr = 0x00000000;
+ s->adc_jdr[0] = 0x00000000;
+ s->adc_jdr[1] = 0x00000000;
+ s->adc_jdr[2] = 0x00000000;
+ s->adc_jdr[3] = 0x00000000;
+ s->adc_dr = 0x00000000;
+}
+
+static uint32_t stm32f2xx_adc_generate_value(STM32F2XXADCState *s)
+{
+ /* Attempts to fake some ADC values */
+#ifdef RAND_AVALIABLE
+ s->adc_dr = s->adc_dr + rand();
+#else
+ s->adc_dr = s->adc_dr + 7;
+#endif
+
+ switch ((s->adc_cr1 & ADC_CR1_RES) >> 24) {
+ case 0:
+ /* 12-bit */
+ s->adc_dr &= 0xFFF;
+ break;
+ case 1:
+ /* 10-bit */
+ s->adc_dr &= 0x3FF;
+ break;
+ case 2:
+ /* 8-bit */
+ s->adc_dr &= 0xFF;
+ break;
+ default:
+ /* 6-bit */
+ s->adc_dr &= 0x3F;
+ }
+
+ if (s->adc_cr2 & ADC_CR2_ALIGN) {
+ return (s->adc_dr << 1) & 0xFFF0;
+ } else {
+ return s->adc_dr;
+ }
+}
+
+static uint64_t stm32f2xx_adc_read(void *opaque, hwaddr addr,
+ unsigned int size)
+{
+ STM32F2XXADCState *s = opaque;
+
+ DB_PRINT("Address: 0x%"HWADDR_PRIx"\n", addr);
+
+ if (addr >= ADC_COMMON_ADDRESS) {
+ qemu_log_mask(LOG_UNIMP,
+ "%s: ADC Common Register Unsupported\n", __func__);
+ }
+
+ switch (addr) {
+ case ADC_SR:
+ return s->adc_sr;
+ case ADC_CR1:
+ return s->adc_cr1;
+ case ADC_CR2:
+ return s->adc_cr2 & 0xFFFFFFF;
+ case ADC_SMPR1:
+ return s->adc_smpr1;
+ case ADC_SMPR2:
+ return s->adc_smpr2;
+ case ADC_JOFR1:
+ case ADC_JOFR2:
+ case ADC_JOFR3:
+ case ADC_JOFR4:
+ qemu_log_mask(LOG_UNIMP, "%s: " \
+ "Injection ADC is not implemented, the registers are " \
+ "included for compatability\n", __func__);
+ return s->adc_jofr[(addr - ADC_JOFR1) / 4];
+ case ADC_HTR:
+ return s->adc_htr;
+ case ADC_LTR:
+ return s->adc_ltr;
+ case ADC_SQR1:
+ return s->adc_sqr1;
+ case ADC_SQR2:
+ return s->adc_sqr2;
+ case ADC_SQR3:
+ return s->adc_sqr3;
+ case ADC_JSQR:
+ qemu_log_mask(LOG_UNIMP, "%s: " \
+ "Injection ADC is not implemented, the registers are " \
+ "included for compatability\n", __func__);
+ return s->adc_jsqr;
+ case ADC_JDR1:
+ case ADC_JDR2:
+ case ADC_JDR3:
+ case ADC_JDR4:
+ qemu_log_mask(LOG_UNIMP, "%s: " \
+ "Injection ADC is not implemented, the registers are " \
+ "included for compatability\n", __func__);
+ return s->adc_jdr[(addr - ADC_JDR1) / 4] -
+ s->adc_jofr[(addr - ADC_JDR1) / 4];
+ case ADC_DR:
+ if ((s->adc_cr2 & ADC_CR2_ADON) && (s->adc_cr2 & ADC_CR2_SWSTART)) {
+ s->adc_cr2 ^= ADC_CR2_SWSTART;
+ return stm32f2xx_adc_generate_value(s);
+ } else {
+ return 0x00000000;
+ }
+ default:
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: Bad offset 0x%"HWADDR_PRIx"\n", __func__, addr);
+ }
+
+ return 0;
+}
+
+static void stm32f2xx_adc_write(void *opaque, hwaddr addr,
+ uint64_t val64, unsigned int size)
+{
+ STM32F2XXADCState *s = opaque;
+ uint32_t value = (uint32_t) val64;
+
+ DB_PRINT("Address: 0x%"HWADDR_PRIx", Value: 0x%x\n",
+ addr, value);
+
+ if (addr >= 0x100) {
+ qemu_log_mask(LOG_UNIMP,
+ "%s: ADC Common Register Unsupported\n", __func__);
+ }
+
+ switch (addr) {
+ case ADC_SR:
+ s->adc_sr &= (value & 0x3F);
+ break;
+ case ADC_CR1:
+ s->adc_cr1 = value;
+ break;
+ case ADC_CR2:
+ s->adc_cr2 = value;
+ break;
+ case ADC_SMPR1:
+ s->adc_smpr1 = value;
+ break;
+ case ADC_SMPR2:
+ s->adc_smpr2 = value;
+ break;
+ case ADC_JOFR1:
+ case ADC_JOFR2:
+ case ADC_JOFR3:
+ case ADC_JOFR4:
+ s->adc_jofr[(addr - ADC_JOFR1) / 4] = (value & 0xFFF);
+ qemu_log_mask(LOG_UNIMP, "%s: " \
+ "Injection ADC is not implemented, the registers are " \
+ "included for compatability\n", __func__);
+ break;
+ case ADC_HTR:
+ s->adc_htr = value;
+ break;
+ case ADC_LTR:
+ s->adc_ltr = value;
+ break;
+ case ADC_SQR1:
+ s->adc_sqr1 = value;
+ break;
+ case ADC_SQR2:
+ s->adc_sqr2 = value;
+ break;
+ case ADC_SQR3:
+ s->adc_sqr3 = value;
+ break;
+ case ADC_JSQR:
+ s->adc_jsqr = value;
+ qemu_log_mask(LOG_UNIMP, "%s: " \
+ "Injection ADC is not implemented, the registers are " \
+ "included for compatability\n", __func__);
+ break;
+ case ADC_JDR1:
+ case ADC_JDR2:
+ case ADC_JDR3:
+ case ADC_JDR4:
+ s->adc_jdr[(addr - ADC_JDR1) / 4] = value;
+ qemu_log_mask(LOG_UNIMP, "%s: " \
+ "Injection ADC is not implemented, the registers are " \
+ "included for compatability\n", __func__);
+ break;
+ default:
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: Bad offset 0x%"HWADDR_PRIx"\n", __func__, addr);
+ }
+}
+
+static const MemoryRegionOps stm32f2xx_adc_ops = {
+ .read = stm32f2xx_adc_read,
+ .write = stm32f2xx_adc_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
+};
+
+static void stm32f2xx_adc_init(Object *obj)
+{
+ STM32F2XXADCState *s = STM32F2XX_ADC(obj);
+
+ sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->irq);
+
+ memory_region_init_io(&s->mmio, obj, &stm32f2xx_adc_ops, s,
+ TYPE_STM32F2XX_ADC, 0xFF);
+ sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio);
+}
+
+static void stm32f2xx_adc_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+
+ dc->reset = stm32f2xx_adc_reset;
+}
+
+static const TypeInfo stm32f2xx_adc_info = {
+ .name = TYPE_STM32F2XX_ADC,
+ .parent = TYPE_SYS_BUS_DEVICE,
+ .instance_size = sizeof(STM32F2XXADCState),
+ .instance_init = stm32f2xx_adc_init,
+ .class_init = stm32f2xx_adc_class_init,
+};
+
+static void stm32f2xx_adc_register_types(void)
+{
+ type_register_static(&stm32f2xx_adc_info);
+}
+
+type_init(stm32f2xx_adc_register_types)
diff --git a/include/hw/adc/stm32f2xx_adc.h b/include/hw/adc/stm32f2xx_adc.h
new file mode 100644
index 0000000..4095d9a
--- /dev/null
+++ b/include/hw/adc/stm32f2xx_adc.h
@@ -0,0 +1,94 @@
+/*
+ * STM32F2XX ADC
+ *
+ * Copyright (c) 2014 Alistair Francis <alistair@alistair23.me>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef HW_STM32F2XX_ADC_H
+#define HW_STM32F2XX_ADC_H
+
+#define ADC_SR 0x00
+#define ADC_CR1 0x04
+#define ADC_CR2 0x08
+#define ADC_SMPR1 0x0C
+#define ADC_SMPR2 0x10
+#define ADC_JOFR1 0x14
+#define ADC_JOFR2 0x18
+#define ADC_JOFR3 0x1C
+#define ADC_JOFR4 0x20
+#define ADC_HTR 0x24
+#define ADC_LTR 0x28
+#define ADC_SQR1 0x2C
+#define ADC_SQR2 0x30
+#define ADC_SQR3 0x34
+#define ADC_JSQR 0x38
+#define ADC_JDR1 0x3C
+#define ADC_JDR2 0x40
+#define ADC_JDR3 0x44
+#define ADC_JDR4 0x48
+#define ADC_DR 0x4C
+
+#define ADC_CR2_ADON 0x01
+#define ADC_CR2_CONT 0x02
+#define ADC_CR2_ALIGN 0x800
+#define ADC_CR2_SWSTART 0x40000000
+
+#define ADC_CR1_RES 0x3000000
+
+#define ADC_COMMON_ADDRESS 0x100
+
+#define TYPE_STM32F2XX_ADC "stm32f2xx-adc"
+#define STM32F2XX_ADC(obj) \
+ OBJECT_CHECK(STM32F2XXADCState, (obj), TYPE_STM32F2XX_ADC)
+
+#ifdef RAND_MAX
+/* The rand() function is avaliable */
+#define RAND_AVAILABLE
+#undef RAND_MAX
+#define RAND_MAX 0xFF
+#endif /* RAND_MAX */
+
+typedef struct {
+ /* <private> */
+ SysBusDevice parent_obj;
+
+ /* <public> */
+ MemoryRegion mmio;
+
+ uint32_t adc_sr;
+ uint32_t adc_cr1;
+ uint32_t adc_cr2;
+ uint32_t adc_smpr1;
+ uint32_t adc_smpr2;
+ uint32_t adc_jofr[4];
+ uint32_t adc_htr;
+ uint32_t adc_ltr;
+ uint32_t adc_sqr1;
+ uint32_t adc_sqr2;
+ uint32_t adc_sqr3;
+ uint32_t adc_jsqr;
+ uint32_t adc_jdr[4];
+ uint32_t adc_dr;
+
+ qemu_irq irq;
+} STM32F2XXADCState;
+
+#endif /* HW_STM32F2XX_ADC_H */
--
2.5.0
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [Qemu-devel] [PATCH v3 4/7] STM32F2xx: Add the SPI device
2016-01-19 7:22 [Qemu-devel] [PATCH v3 0/7] Update the Netduino 2 Machine Alistair Francis
` (2 preceding siblings ...)
2016-01-19 7:23 ` [Qemu-devel] [PATCH v3 3/7] STM32F2xx: Add the ADC device Alistair Francis
@ 2016-01-19 7:23 ` Alistair Francis
2016-02-02 15:30 ` Peter Maydell
2016-01-19 7:23 ` [Qemu-devel] [PATCH v3 5/7] STM32F205: Connect the ADC devices Alistair Francis
2016-01-19 7:23 ` [Qemu-devel] [PATCH v3 7/7] MAINTAINERS: Add Alistair to the maintainers list Alistair Francis
5 siblings, 1 reply; 14+ messages in thread
From: Alistair Francis @ 2016-01-19 7:23 UTC (permalink / raw)
To: qemu-devel, peter.crosthwaite; +Cc: peter.maydell, konstanty, alistair23
Add the STM32F2xx SPI device.
Signed-off-by: Alistair Francis <alistair@alistair23.me>
---
V2:
- Address Peter C's comments
default-configs/arm-softmmu.mak | 1 +
hw/ssi/Makefile.objs | 1 +
hw/ssi/stm32f2xx_spi.c | 205 ++++++++++++++++++++++++++++++++++++++++
include/hw/ssi/stm32f2xx_spi.h | 72 ++++++++++++++
4 files changed, 279 insertions(+)
create mode 100644 hw/ssi/stm32f2xx_spi.c
create mode 100644 include/hw/ssi/stm32f2xx_spi.h
diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index 520b209..af43eb1 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -86,6 +86,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
diff --git a/hw/ssi/Makefile.objs b/hw/ssi/Makefile.objs
index 9555825..c674247 100644
--- a/hw/ssi/Makefile.objs
+++ b/hw/ssi/Makefile.objs
@@ -2,5 +2,6 @@ common-obj-$(CONFIG_PL022) += pl022.o
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_STM32F2XX_SPI) += stm32f2xx_spi.o
obj-$(CONFIG_OMAP) += omap_spi.o
diff --git a/hw/ssi/stm32f2xx_spi.c b/hw/ssi/stm32f2xx_spi.c
new file mode 100644
index 0000000..1ae88d7
--- /dev/null
+++ b/hw/ssi/stm32f2xx_spi.c
@@ -0,0 +1,205 @@
+/*
+ * STM32F405 SPI
+ *
+ * Copyright (c) 2014 Alistair Francis <alistair@alistair23.me>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "hw/ssi/stm32f2xx_spi.h"
+
+#ifndef STM_SPI_ERR_DEBUG
+#define STM_SPI_ERR_DEBUG 0
+#endif
+
+#define DB_PRINT_L(lvl, fmt, args...) do { \
+ if (STM_SPI_ERR_DEBUG >= lvl) { \
+ qemu_log("%s: " fmt, __func__, ## args); \
+ } \
+} while (0);
+
+#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)
+
+static void stm32f2xx_spi_reset(DeviceState *dev)
+{
+ STM32F2XXSPIState *s = STM32F2XX_SPI(dev);
+
+ s->spi_cr1 = 0x00000000;
+ s->spi_cr2 = 0x00000000;
+ s->spi_sr = 0x0000000A;
+ s->spi_dr = 0x0000000C;
+ s->spi_crcpr = 0x00000007;
+ s->spi_rxcrcr = 0x00000000;
+ s->spi_txcrcr = 0x00000000;
+ s->spi_i2scfgr = 0x00000000;
+ s->spi_i2spr = 0x00000002;
+}
+
+static void stm32f2xx_spi_transfer(STM32F2XXSPIState *s)
+{
+ DB_PRINT("Data to send: 0x%x\n", s->spi_dr);
+
+ s->spi_dr = ssi_transfer(s->ssi, s->spi_dr);
+ s->spi_sr |= STM_SPI_SR_RXNE;
+
+ DB_PRINT("Data received: 0x%x\n", s->spi_dr);
+}
+
+static uint64_t stm32f2xx_spi_read(void *opaque, hwaddr addr,
+ unsigned int size)
+{
+ STM32F2XXSPIState *s = opaque;
+ uint32_t retval;
+
+ DB_PRINT("Address: 0x%"HWADDR_PRIx"\n", addr);
+
+ switch (addr) {
+ case STM_SPI_CR1:
+ return s->spi_cr1;
+ case STM_SPI_CR2:
+ qemu_log_mask(LOG_UNIMP, "%s: Interrupts and DMA are not implemented\n",
+ __func__);
+ return s->spi_cr2;
+ case STM_SPI_SR:
+ retval = s->spi_sr;
+ return retval;
+ case STM_SPI_DR:
+ stm32f2xx_spi_transfer(s);
+ s->spi_sr &= ~STM_SPI_SR_RXNE;
+ return s->spi_dr;
+ case STM_SPI_CRCPR:
+ qemu_log_mask(LOG_UNIMP, "%s: CRC is not implemented, the registers " \
+ "are included for compatability\n", __func__);
+ return s->spi_crcpr;
+ case STM_SPI_RXCRCR:
+ qemu_log_mask(LOG_UNIMP, "%s: CRC is not implemented, the registers " \
+ "are included for compatability\n", __func__);
+ return s->spi_rxcrcr;
+ case STM_SPI_TXCRCR:
+ qemu_log_mask(LOG_UNIMP, "%s: CRC is not implemented, the registers " \
+ "are included for compatability\n", __func__);
+ return s->spi_txcrcr;
+ case STM_SPI_I2SCFGR:
+ qemu_log_mask(LOG_UNIMP, "%s: I2S is not implemented, the registers " \
+ "are included for compatability\n", __func__);
+ return s->spi_i2scfgr;
+ case STM_SPI_I2SPR:
+ qemu_log_mask(LOG_UNIMP, "%s: I2S is not implemented, the registers " \
+ "are included for compatability\n", __func__);
+ return s->spi_i2spr;
+ default:
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%"HWADDR_PRIx"\n",
+ __func__, addr);
+ }
+
+ return 0;
+}
+
+static void stm32f2xx_spi_write(void *opaque, hwaddr addr,
+ uint64_t val64, unsigned int size)
+{
+ STM32F2XXSPIState *s = opaque;
+ uint32_t value = val64;
+
+ DB_PRINT("Address: 0x%"HWADDR_PRIx", Value: 0x%x\n", addr, value);
+
+ switch (addr) {
+ case STM_SPI_CR1:
+ s->spi_cr1 = value;
+ return;
+ case STM_SPI_CR2:
+ qemu_log_mask(LOG_UNIMP, "%s: " \
+ "Interrupts and DMA are not implemented\n", __func__);
+ s->spi_cr2 = value;
+ return;
+ case STM_SPI_SR:
+ /* Read only register, except for clearing the CRCERR bit, which
+ * is not supported
+ */
+ return;
+ case STM_SPI_DR:
+ s->spi_dr = value;
+ stm32f2xx_spi_transfer(s);
+ return;
+ case STM_SPI_CRCPR:
+ qemu_log_mask(LOG_UNIMP, "%s: CRC is not implemented\n", __func__);
+ return;
+ case STM_SPI_RXCRCR:
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Read only register: " \
+ "0x%"HWADDR_PRIx"\n", __func__, addr);
+ return;
+ case STM_SPI_TXCRCR:
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Read only register: " \
+ "0x%"HWADDR_PRIx"\n", __func__, addr);
+ return;
+ case STM_SPI_I2SCFGR:
+ qemu_log_mask(LOG_UNIMP, "%s: " \
+ "I2S is not implemented\n", __func__);
+ return;
+ case STM_SPI_I2SPR:
+ qemu_log_mask(LOG_UNIMP, "%s: " \
+ "I2S is not implemented\n", __func__);
+ return;
+ default:
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: Bad offset 0x%"HWADDR_PRIx"\n", __func__, addr);
+ }
+}
+
+static const MemoryRegionOps stm32f2xx_spi_ops = {
+ .read = stm32f2xx_spi_read,
+ .write = stm32f2xx_spi_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
+};
+
+static void stm32f2xx_spi_init(Object *obj)
+{
+ STM32F2XXSPIState *s = STM32F2XX_SPI(obj);
+ DeviceState *dev = DEVICE(obj);
+
+ memory_region_init_io(&s->mmio, obj, &stm32f2xx_spi_ops, s,
+ TYPE_STM32F2XX_SPI, 0x400);
+ sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio);
+
+ sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->irq);
+
+ s->ssi = ssi_create_bus(dev, "ssi");
+}
+
+static void stm32f2xx_spi_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+
+ dc->reset = stm32f2xx_spi_reset;
+}
+
+static const TypeInfo stm32f2xx_spi_info = {
+ .name = TYPE_STM32F2XX_SPI,
+ .parent = TYPE_SYS_BUS_DEVICE,
+ .instance_size = sizeof(STM32F2XXSPIState),
+ .instance_init = stm32f2xx_spi_init,
+ .class_init = stm32f2xx_spi_class_init,
+};
+
+static void stm32f2xx_spi_register_types(void)
+{
+ type_register_static(&stm32f2xx_spi_info);
+}
+
+type_init(stm32f2xx_spi_register_types)
diff --git a/include/hw/ssi/stm32f2xx_spi.h b/include/hw/ssi/stm32f2xx_spi.h
new file mode 100644
index 0000000..147ae8e
--- /dev/null
+++ b/include/hw/ssi/stm32f2xx_spi.h
@@ -0,0 +1,72 @@
+/*
+ * STM32F2XX SPI
+ *
+ * Copyright (c) 2014 Alistair Francis <alistair@alistair23.me>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef HW_STM32F2XX_SPI_H
+#define HW_STM32F2XX_SPI_H
+
+#include "hw/sysbus.h"
+#include "hw/hw.h"
+#include "hw/ssi.h"
+
+#define STM_SPI_CR1 0x00
+#define STM_SPI_CR2 0x04
+#define STM_SPI_SR 0x08
+#define STM_SPI_DR 0x0C
+#define STM_SPI_CRCPR 0x10
+#define STM_SPI_RXCRCR 0x14
+#define STM_SPI_TXCRCR 0x18
+#define STM_SPI_I2SCFGR 0x1C
+#define STM_SPI_I2SPR 0x20
+
+#define STM_SPI_CR1_SPE (1 << 6)
+#define STM_SPI_CR1_MSTR (1 << 2)
+
+#define STM_SPI_SR_RXNE 1
+
+#define TYPE_STM32F2XX_SPI "stm32f2xx-spi"
+#define STM32F2XX_SPI(obj) \
+ OBJECT_CHECK(STM32F2XXSPIState, (obj), TYPE_STM32F2XX_SPI)
+
+typedef struct {
+ /* <private> */
+ SysBusDevice parent_obj;
+
+ /* <public> */
+ MemoryRegion mmio;
+
+ uint32_t spi_cr1;
+ uint32_t spi_cr2;
+ uint32_t spi_sr;
+ uint32_t spi_dr;
+ uint32_t spi_crcpr;
+ uint32_t spi_rxcrcr;
+ uint32_t spi_txcrcr;
+ uint32_t spi_i2scfgr;
+ uint32_t spi_i2spr;
+
+ qemu_irq irq;
+ SSIBus *ssi;
+} STM32F2XXSPIState;
+
+#endif /* HW_STM32F2XX_SPI_H */
--
2.5.0
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [Qemu-devel] [PATCH v3 5/7] STM32F205: Connect the ADC devices
2016-01-19 7:22 [Qemu-devel] [PATCH v3 0/7] Update the Netduino 2 Machine Alistair Francis
` (3 preceding siblings ...)
2016-01-19 7:23 ` [Qemu-devel] [PATCH v3 4/7] STM32F2xx: Add the SPI device Alistair Francis
@ 2016-01-19 7:23 ` Alistair Francis
2016-02-02 15:27 ` Peter Maydell
2016-01-19 7:23 ` [Qemu-devel] [PATCH v3 7/7] MAINTAINERS: Add Alistair to the maintainers list Alistair Francis
5 siblings, 1 reply; 14+ messages in thread
From: Alistair Francis @ 2016-01-19 7:23 UTC (permalink / raw)
To: qemu-devel, peter.crosthwaite; +Cc: peter.maydell, konstanty, alistair23
Connect the ADC devices to the STM32F205 SoC.
Signed-off-by: Alistair Francis <alistair@alistair23.me>
---
V2:
- Fix up the device/devices commit message
hw/arm/stm32f205_soc.c | 22 ++++++++++++++++++++++
include/hw/arm/stm32f205_soc.h | 3 +++
2 files changed, 25 insertions(+)
diff --git a/hw/arm/stm32f205_soc.c b/hw/arm/stm32f205_soc.c
index a2bd970..28d4301 100644
--- a/hw/arm/stm32f205_soc.c
+++ b/hw/arm/stm32f205_soc.c
@@ -32,9 +32,12 @@ static const uint32_t timer_addr[STM_NUM_TIMERS] = { 0x40000000, 0x40000400,
0x40000800, 0x40000C00 };
static const uint32_t usart_addr[STM_NUM_USARTS] = { 0x40011000, 0x40004400,
0x40004800, 0x40004C00, 0x40005000, 0x40011400 };
+static const uint32_t adc_addr[STM_NUM_ADCS] = { 0x40012000, 0x40012100,
+ 0x40012200 };
static const int timer_irq[STM_NUM_TIMERS] = {28, 29, 30, 50};
static const int usart_irq[STM_NUM_USARTS] = {37, 38, 39, 52, 53, 71};
+#define ADC_IRQ 18
static void stm32f205_soc_initfn(Object *obj)
{
@@ -55,6 +58,12 @@ static void stm32f205_soc_initfn(Object *obj)
TYPE_STM32F2XX_TIMER);
qdev_set_parent_bus(DEVICE(&s->timer[i]), sysbus_get_default());
}
+
+ for (i = 0; i < STM_NUM_ADCS; i++) {
+ object_initialize(&s->adc[i], sizeof(s->adc[i]),
+ TYPE_STM32F2XX_ADC);
+ qdev_set_parent_bus(DEVICE(&s->adc[i]), sysbus_get_default());
+ }
}
static void stm32f205_soc_realize(DeviceState *dev_soc, Error **errp)
@@ -128,6 +137,19 @@ static void stm32f205_soc_realize(DeviceState *dev_soc, Error **errp)
sysbus_mmio_map(busdev, 0, timer_addr[i]);
sysbus_connect_irq(busdev, 0, qdev_get_gpio_in(nvic, timer_irq[i]));
}
+
+ /* ADC 1 to 3 */
+ for (i = 0; i < STM_NUM_ADCS; i++) {
+ dev = DEVICE(&(s->adc[i]));
+ object_property_set_bool(OBJECT(&s->adc[i]), true, "realized", &err);
+ if (err != NULL) {
+ error_propagate(errp, err);
+ return;
+ }
+ busdev = SYS_BUS_DEVICE(dev);
+ sysbus_mmio_map(busdev, 0, adc_addr[i]);
+ sysbus_connect_irq(busdev, 0, qdev_get_gpio_in(nvic, ADC_IRQ));
+ }
}
static Property stm32f205_soc_properties[] = {
diff --git a/include/hw/arm/stm32f205_soc.h b/include/hw/arm/stm32f205_soc.h
index 0390eff..091e4be 100644
--- a/include/hw/arm/stm32f205_soc.h
+++ b/include/hw/arm/stm32f205_soc.h
@@ -28,6 +28,7 @@
#include "hw/misc/stm32f2xx_syscfg.h"
#include "hw/timer/stm32f2xx_timer.h"
#include "hw/char/stm32f2xx_usart.h"
+#include "hw/adc/stm32f2xx_adc.h"
#define TYPE_STM32F205_SOC "stm32f205-soc"
#define STM32F205_SOC(obj) \
@@ -35,6 +36,7 @@
#define STM_NUM_USARTS 6
#define STM_NUM_TIMERS 4
+#define STM_NUM_ADCS 3
#define FLASH_BASE_ADDRESS 0x08000000
#define FLASH_SIZE (1024 * 1024)
@@ -52,6 +54,7 @@ typedef struct STM32F205State {
STM32F2XXSyscfgState syscfg;
STM32F2XXUsartState usart[STM_NUM_USARTS];
STM32F2XXTimerState timer[STM_NUM_TIMERS];
+ STM32F2XXADCState adc[STM_NUM_ADCS];
} STM32F205State;
#endif
--
2.5.0
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [Qemu-devel] [PATCH v3 7/7] MAINTAINERS: Add Alistair to the maintainers list
2016-01-19 7:22 [Qemu-devel] [PATCH v3 0/7] Update the Netduino 2 Machine Alistair Francis
` (4 preceding siblings ...)
2016-01-19 7:23 ` [Qemu-devel] [PATCH v3 5/7] STM32F205: Connect the ADC devices Alistair Francis
@ 2016-01-19 7:23 ` Alistair Francis
5 siblings, 0 replies; 14+ messages in thread
From: Alistair Francis @ 2016-01-19 7:23 UTC (permalink / raw)
To: qemu-devel, peter.crosthwaite; +Cc: peter.maydell, konstanty, alistair23
Add Alistair Francis as the maintainer for the Netduino 2
and SMM32F205 SoC.
Signed-off-by: Alistair Francis <alistair@alistair23.me>
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
---
MAINTAINERS | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index 4030e27..24aaef4 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -457,6 +457,21 @@ S: Maintained
F: hw/arm/virt-acpi-build.c
F: include/hw/arm/virt-acpi-build.h
+STM32F205
+M: Alistair Francis <alistair@alistair23.me>
+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 <alistair@alistair23.me>
+S: Maintained
+F: hw/arm/netduino2.c
+
CRIS Machines
-------------
Axis Dev88
--
2.5.0
^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [Qemu-devel] [PATCH v3 3/7] STM32F2xx: Add the ADC device
2016-01-19 7:23 ` [Qemu-devel] [PATCH v3 3/7] STM32F2xx: Add the ADC device Alistair Francis
@ 2016-02-02 15:17 ` Peter Maydell
2016-02-21 23:12 ` Alistair Francis
0 siblings, 1 reply; 14+ messages in thread
From: Peter Maydell @ 2016-02-02 15:17 UTC (permalink / raw)
To: Alistair Francis; +Cc: Peter Crosthwaite, QEMU Developers, Konstanty Bialkowski
On 19 January 2016 at 07:23, Alistair Francis <alistair23@gmail.com> wrote:
> Add the STM32F2xx ADC device. This device randomly
> generates values on each read.
>
> This also includes creating a hw/adc directory.
>
> Signed-off-by: Alistair Francis <alistair@alistair23.me>
> +static uint32_t stm32f2xx_adc_generate_value(STM32F2XXADCState *s)
> +{
> + /* Attempts to fake some ADC values */
> +#ifdef RAND_AVALIABLE
> + s->adc_dr = s->adc_dr + rand();
> +#else
> + s->adc_dr = s->adc_dr + 7;
> +#endif
We shouldn't be using rand() in devices I think. (Among other things
it means we won't be deterministic, which will break record-replay.)
In any case you've typoed your #ifdef constant name, which means
that code is never used :-)
> +static uint64_t stm32f2xx_adc_read(void *opaque, hwaddr addr,
> + unsigned int size)
> +{
> + STM32F2XXADCState *s = opaque;
> +
> + DB_PRINT("Address: 0x%"HWADDR_PRIx"\n", addr);
Spaces around the HWADDR_PRIx would be nice.
> +
> + if (addr >= ADC_COMMON_ADDRESS) {
> + qemu_log_mask(LOG_UNIMP,
> + "%s: ADC Common Register Unsupported\n", __func__);
> + }
> +
> + switch (addr) {
> + case ADC_SR:
> + return s->adc_sr;
> + case ADC_CR1:
> + return s->adc_cr1;
> + case ADC_CR2:
> + return s->adc_cr2 & 0xFFFFFFF;
> + case ADC_SMPR1:
> + return s->adc_smpr1;
> + case ADC_SMPR2:
> + return s->adc_smpr2;
> + case ADC_JOFR1:
> + case ADC_JOFR2:
> + case ADC_JOFR3:
> + case ADC_JOFR4:
> + qemu_log_mask(LOG_UNIMP, "%s: " \
> + "Injection ADC is not implemented, the registers are " \
> + "included for compatability\n", __func__);
"compatibility"
> + return s->adc_jofr[(addr - ADC_JOFR1) / 4];
> + case ADC_HTR:
> + return s->adc_htr;
> + case ADC_LTR:
> + return s->adc_ltr;
> + case ADC_SQR1:
> + return s->adc_sqr1;
> + case ADC_SQR2:
> + return s->adc_sqr2;
> + case ADC_SQR3:
> + return s->adc_sqr3;
> + case ADC_JSQR:
> + qemu_log_mask(LOG_UNIMP, "%s: " \
> + "Injection ADC is not implemented, the registers are " \
> + "included for compatability\n", __func__);
> + return s->adc_jsqr;
> + case ADC_JDR1:
> + case ADC_JDR2:
> + case ADC_JDR3:
> + case ADC_JDR4:
> + qemu_log_mask(LOG_UNIMP, "%s: " \
> + "Injection ADC is not implemented, the registers are " \
> + "included for compatability\n", __func__);
> + return s->adc_jdr[(addr - ADC_JDR1) / 4] -
> + s->adc_jofr[(addr - ADC_JDR1) / 4];
> + case ADC_DR:
> + if ((s->adc_cr2 & ADC_CR2_ADON) && (s->adc_cr2 & ADC_CR2_SWSTART)) {
> + s->adc_cr2 ^= ADC_CR2_SWSTART;
> + return stm32f2xx_adc_generate_value(s);
> + } else {
> + return 0x00000000;
Just "0" seems more readable to me.
> +#ifdef RAND_MAX
> +/* The rand() function is avaliable */
> +#define RAND_AVAILABLE
> +#undef RAND_MAX
> +#define RAND_MAX 0xFF
> +#endif /* RAND_MAX */
What platforms don't have rand()?
If we need an "exists everywhere" random number function
then there is one in glib.
(but as noted earlier I don't think we should be using rand() here)
> +
> +typedef struct {
> + /* <private> */
> + SysBusDevice parent_obj;
> +
> + /* <public> */
> + MemoryRegion mmio;
> +
> + uint32_t adc_sr;
> + uint32_t adc_cr1;
> + uint32_t adc_cr2;
> + uint32_t adc_smpr1;
> + uint32_t adc_smpr2;
> + uint32_t adc_jofr[4];
> + uint32_t adc_htr;
> + uint32_t adc_ltr;
> + uint32_t adc_sqr1;
> + uint32_t adc_sqr2;
> + uint32_t adc_sqr3;
> + uint32_t adc_jsqr;
> + uint32_t adc_jdr[4];
> + uint32_t adc_dr;
> +
> + qemu_irq irq;
> +} STM32F2XXADCState;
> +
> +#endif /* HW_STM32F2XX_ADC_H */
You need to implement the VMState structure for migration.
thanks
-- PMM
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [Qemu-devel] [PATCH v3 5/7] STM32F205: Connect the ADC devices
2016-01-19 7:23 ` [Qemu-devel] [PATCH v3 5/7] STM32F205: Connect the ADC devices Alistair Francis
@ 2016-02-02 15:27 ` Peter Maydell
2016-02-21 23:35 ` Alistair Francis
0 siblings, 1 reply; 14+ messages in thread
From: Peter Maydell @ 2016-02-02 15:27 UTC (permalink / raw)
To: Alistair Francis; +Cc: Peter Crosthwaite, QEMU Developers, Konstanty Bialkowski
On 19 January 2016 at 07:23, Alistair Francis <alistair23@gmail.com> wrote:
> Connect the ADC devices to the STM32F205 SoC.
>
> Signed-off-by: Alistair Francis <alistair@alistair23.me>
> ---
> V2:
> - Fix up the device/devices commit message
>
> hw/arm/stm32f205_soc.c | 22 ++++++++++++++++++++++
> include/hw/arm/stm32f205_soc.h | 3 +++
> 2 files changed, 25 insertions(+)
>
> diff --git a/hw/arm/stm32f205_soc.c b/hw/arm/stm32f205_soc.c
> index a2bd970..28d4301 100644
> --- a/hw/arm/stm32f205_soc.c
> +++ b/hw/arm/stm32f205_soc.c
> @@ -32,9 +32,12 @@ static const uint32_t timer_addr[STM_NUM_TIMERS] = { 0x40000000, 0x40000400,
> 0x40000800, 0x40000C00 };
> static const uint32_t usart_addr[STM_NUM_USARTS] = { 0x40011000, 0x40004400,
> 0x40004800, 0x40004C00, 0x40005000, 0x40011400 };
> +static const uint32_t adc_addr[STM_NUM_ADCS] = { 0x40012000, 0x40012100,
> + 0x40012200 };
>
> static const int timer_irq[STM_NUM_TIMERS] = {28, 29, 30, 50};
> static const int usart_irq[STM_NUM_USARTS] = {37, 38, 39, 52, 53, 71};
> +#define ADC_IRQ 18
Really three devices but only one IRQ ?
> + /* ADC 1 to 3 */
> + for (i = 0; i < STM_NUM_ADCS; i++) {
> + dev = DEVICE(&(s->adc[i]));
> + object_property_set_bool(OBJECT(&s->adc[i]), true, "realized", &err);
> + if (err != NULL) {
> + error_propagate(errp, err);
> + return;
> + }
> + busdev = SYS_BUS_DEVICE(dev);
> + sysbus_mmio_map(busdev, 0, adc_addr[i]);
> + sysbus_connect_irq(busdev, 0, qdev_get_gpio_in(nvic, ADC_IRQ));
You can't just wire multiple irq lines up like this; I think if
you do then if devices A and B both assert the IRQ and then A
deasserts it, then the receiving device will see an IRQ deassert
when it should not (since B still holds it high).
thanks
-- PMM
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [Qemu-devel] [PATCH v3 4/7] STM32F2xx: Add the SPI device
2016-01-19 7:23 ` [Qemu-devel] [PATCH v3 4/7] STM32F2xx: Add the SPI device Alistair Francis
@ 2016-02-02 15:30 ` Peter Maydell
2016-02-21 23:24 ` Alistair Francis
0 siblings, 1 reply; 14+ messages in thread
From: Peter Maydell @ 2016-02-02 15:30 UTC (permalink / raw)
To: Alistair Francis; +Cc: Peter Crosthwaite, QEMU Developers, Konstanty Bialkowski
On 19 January 2016 at 07:23, Alistair Francis <alistair23@gmail.com> wrote:
> Add the STM32F2xx SPI device.
>
> Signed-off-by: Alistair Francis <alistair@alistair23.me>
> ---
> V2:
> - Address Peter C's comments
>
> default-configs/arm-softmmu.mak | 1 +
> hw/ssi/Makefile.objs | 1 +
> hw/ssi/stm32f2xx_spi.c | 205 ++++++++++++++++++++++++++++++++++++++++
> include/hw/ssi/stm32f2xx_spi.h | 72 ++++++++++++++
> 4 files changed, 279 insertions(+)
> create mode 100644 hw/ssi/stm32f2xx_spi.c
> create mode 100644 include/hw/ssi/stm32f2xx_spi.h
> +static uint64_t stm32f2xx_spi_read(void *opaque, hwaddr addr,
> + unsigned int size)
> +{
> + STM32F2XXSPIState *s = opaque;
> + uint32_t retval;
> +
> + DB_PRINT("Address: 0x%"HWADDR_PRIx"\n", addr);
> +
> + switch (addr) {
> + case STM_SPI_CR1:
> + return s->spi_cr1;
> + case STM_SPI_CR2:
> + qemu_log_mask(LOG_UNIMP, "%s: Interrupts and DMA are not implemented\n",
> + __func__);
> + return s->spi_cr2;
> + case STM_SPI_SR:
> + retval = s->spi_sr;
> + return retval;
> + case STM_SPI_DR:
> + stm32f2xx_spi_transfer(s);
> + s->spi_sr &= ~STM_SPI_SR_RXNE;
> + return s->spi_dr;
> + case STM_SPI_CRCPR:
> + qemu_log_mask(LOG_UNIMP, "%s: CRC is not implemented, the registers " \
> + "are included for compatability\n", __func__);
"compatibility" again, here and below.
> + return s->spi_crcpr;
> + case STM_SPI_RXCRCR:
> + qemu_log_mask(LOG_UNIMP, "%s: CRC is not implemented, the registers " \
> + "are included for compatability\n", __func__);
> + return s->spi_rxcrcr;
> + case STM_SPI_TXCRCR:
> + qemu_log_mask(LOG_UNIMP, "%s: CRC is not implemented, the registers " \
> + "are included for compatability\n", __func__);
> + return s->spi_txcrcr;
> + case STM_SPI_I2SCFGR:
> + qemu_log_mask(LOG_UNIMP, "%s: I2S is not implemented, the registers " \
> + "are included for compatability\n", __func__);
> + return s->spi_i2scfgr;
> + case STM_SPI_I2SPR:
> + qemu_log_mask(LOG_UNIMP, "%s: I2S is not implemented, the registers " \
> + "are included for compatability\n", __func__);
> + return s->spi_i2spr;
> + default:
> + qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%"HWADDR_PRIx"\n",
Spaces, please.
> +static void stm32f2xx_spi_class_init(ObjectClass *klass, void *data)
> +{
> + DeviceClass *dc = DEVICE_CLASS(klass);
> +
> + dc->reset = stm32f2xx_spi_reset;
> +}
> +
> +static const TypeInfo stm32f2xx_spi_info = {
> + .name = TYPE_STM32F2XX_SPI,
> + .parent = TYPE_SYS_BUS_DEVICE,
> + .instance_size = sizeof(STM32F2XXSPIState),
> + .instance_init = stm32f2xx_spi_init,
> + .class_init = stm32f2xx_spi_class_init,
> +};
Can we have a VMState for migration, please?
> +
> +static void stm32f2xx_spi_register_types(void)
> +{
> + type_register_static(&stm32f2xx_spi_info);
> +}
> +typedef struct {
> + /* <private> */
> + SysBusDevice parent_obj;
> +
> + /* <public> */
> + MemoryRegion mmio;
> +
> + uint32_t spi_cr1;
> + uint32_t spi_cr2;
> + uint32_t spi_sr;
> + uint32_t spi_dr;
> + uint32_t spi_crcpr;
> + uint32_t spi_rxcrcr;
> + uint32_t spi_txcrcr;
> + uint32_t spi_i2scfgr;
> + uint32_t spi_i2spr;
> +
> + qemu_irq irq;
> + SSIBus *ssi;
> +} STM32F2XXSPIState;
Personally I like to order the struct fields of a device to put all
the not-migration data first (so here, mmio, irq, ssi), and then
the fields that correspond to real device state after that.
I don't feel very strongly about that though and of course a
lot of our devices don't do it.
thanks
-- PMM
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [Qemu-devel] [PATCH v3 3/7] STM32F2xx: Add the ADC device
2016-02-02 15:17 ` Peter Maydell
@ 2016-02-21 23:12 ` Alistair Francis
0 siblings, 0 replies; 14+ messages in thread
From: Alistair Francis @ 2016-02-21 23:12 UTC (permalink / raw)
To: Peter Maydell; +Cc: Peter Crosthwaite, QEMU Developers, Konstanty Bialkowski
On Tue, Feb 2, 2016 at 7:17 AM, Peter Maydell <peter.maydell@linaro.org> wrote:
> On 19 January 2016 at 07:23, Alistair Francis <alistair23@gmail.com> wrote:
>> Add the STM32F2xx ADC device. This device randomly
>> generates values on each read.
>>
>> This also includes creating a hw/adc directory.
>>
>> Signed-off-by: Alistair Francis <alistair@alistair23.me>
>
>> +static uint32_t stm32f2xx_adc_generate_value(STM32F2XXADCState *s)
>> +{
>> + /* Attempts to fake some ADC values */
>> +#ifdef RAND_AVALIABLE
>> + s->adc_dr = s->adc_dr + rand();
>> +#else
>> + s->adc_dr = s->adc_dr + 7;
>> +#endif
>
> We shouldn't be using rand() in devices I think. (Among other things
> it means we won't be deterministic, which will break record-replay.)
>
> In any case you've typoed your #ifdef constant name, which means
> that code is never used :-)
Woops, I didn't realise that. I'll take the rand() function out then.
I have made all of the other changes as well.
Thanks,
Alistair
>
>> +static uint64_t stm32f2xx_adc_read(void *opaque, hwaddr addr,
>> + unsigned int size)
>> +{
>> + STM32F2XXADCState *s = opaque;
>> +
>> + DB_PRINT("Address: 0x%"HWADDR_PRIx"\n", addr);
>
> Spaces around the HWADDR_PRIx would be nice.
>
>> +
>> + if (addr >= ADC_COMMON_ADDRESS) {
>> + qemu_log_mask(LOG_UNIMP,
>> + "%s: ADC Common Register Unsupported\n", __func__);
>> + }
>> +
>> + switch (addr) {
>> + case ADC_SR:
>> + return s->adc_sr;
>> + case ADC_CR1:
>> + return s->adc_cr1;
>> + case ADC_CR2:
>> + return s->adc_cr2 & 0xFFFFFFF;
>> + case ADC_SMPR1:
>> + return s->adc_smpr1;
>> + case ADC_SMPR2:
>> + return s->adc_smpr2;
>> + case ADC_JOFR1:
>> + case ADC_JOFR2:
>> + case ADC_JOFR3:
>> + case ADC_JOFR4:
>> + qemu_log_mask(LOG_UNIMP, "%s: " \
>> + "Injection ADC is not implemented, the registers are " \
>> + "included for compatability\n", __func__);
>
> "compatibility"
>
>> + return s->adc_jofr[(addr - ADC_JOFR1) / 4];
>> + case ADC_HTR:
>> + return s->adc_htr;
>> + case ADC_LTR:
>> + return s->adc_ltr;
>> + case ADC_SQR1:
>> + return s->adc_sqr1;
>> + case ADC_SQR2:
>> + return s->adc_sqr2;
>> + case ADC_SQR3:
>> + return s->adc_sqr3;
>> + case ADC_JSQR:
>> + qemu_log_mask(LOG_UNIMP, "%s: " \
>> + "Injection ADC is not implemented, the registers are " \
>> + "included for compatability\n", __func__);
>> + return s->adc_jsqr;
>> + case ADC_JDR1:
>> + case ADC_JDR2:
>> + case ADC_JDR3:
>> + case ADC_JDR4:
>> + qemu_log_mask(LOG_UNIMP, "%s: " \
>> + "Injection ADC is not implemented, the registers are " \
>> + "included for compatability\n", __func__);
>> + return s->adc_jdr[(addr - ADC_JDR1) / 4] -
>> + s->adc_jofr[(addr - ADC_JDR1) / 4];
>> + case ADC_DR:
>> + if ((s->adc_cr2 & ADC_CR2_ADON) && (s->adc_cr2 & ADC_CR2_SWSTART)) {
>> + s->adc_cr2 ^= ADC_CR2_SWSTART;
>> + return stm32f2xx_adc_generate_value(s);
>> + } else {
>> + return 0x00000000;
>
> Just "0" seems more readable to me.
>
>> +#ifdef RAND_MAX
>> +/* The rand() function is avaliable */
>> +#define RAND_AVAILABLE
>> +#undef RAND_MAX
>> +#define RAND_MAX 0xFF
>> +#endif /* RAND_MAX */
>
> What platforms don't have rand()?
> If we need an "exists everywhere" random number function
> then there is one in glib.
>
> (but as noted earlier I don't think we should be using rand() here)
>
>> +
>> +typedef struct {
>> + /* <private> */
>> + SysBusDevice parent_obj;
>> +
>> + /* <public> */
>> + MemoryRegion mmio;
>> +
>> + uint32_t adc_sr;
>> + uint32_t adc_cr1;
>> + uint32_t adc_cr2;
>> + uint32_t adc_smpr1;
>> + uint32_t adc_smpr2;
>> + uint32_t adc_jofr[4];
>> + uint32_t adc_htr;
>> + uint32_t adc_ltr;
>> + uint32_t adc_sqr1;
>> + uint32_t adc_sqr2;
>> + uint32_t adc_sqr3;
>> + uint32_t adc_jsqr;
>> + uint32_t adc_jdr[4];
>> + uint32_t adc_dr;
>> +
>> + qemu_irq irq;
>> +} STM32F2XXADCState;
>> +
>> +#endif /* HW_STM32F2XX_ADC_H */
>
> You need to implement the VMState structure for migration.
>
> thanks
> -- PMM
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [Qemu-devel] [PATCH v3 4/7] STM32F2xx: Add the SPI device
2016-02-02 15:30 ` Peter Maydell
@ 2016-02-21 23:24 ` Alistair Francis
0 siblings, 0 replies; 14+ messages in thread
From: Alistair Francis @ 2016-02-21 23:24 UTC (permalink / raw)
To: Peter Maydell; +Cc: Peter Crosthwaite, QEMU Developers, Konstanty Bialkowski
On Tue, Feb 2, 2016 at 7:30 AM, Peter Maydell <peter.maydell@linaro.org> wrote:
> On 19 January 2016 at 07:23, Alistair Francis <alistair23@gmail.com> wrote:
>> Add the STM32F2xx SPI device.
>>
>> Signed-off-by: Alistair Francis <alistair@alistair23.me>
>> ---
>> V2:
>> - Address Peter C's comments
>>
>> default-configs/arm-softmmu.mak | 1 +
>> hw/ssi/Makefile.objs | 1 +
>> hw/ssi/stm32f2xx_spi.c | 205 ++++++++++++++++++++++++++++++++++++++++
>> include/hw/ssi/stm32f2xx_spi.h | 72 ++++++++++++++
>> 4 files changed, 279 insertions(+)
>> create mode 100644 hw/ssi/stm32f2xx_spi.c
>> create mode 100644 include/hw/ssi/stm32f2xx_spi.h
>
>> +static uint64_t stm32f2xx_spi_read(void *opaque, hwaddr addr,
>> + unsigned int size)
>> +{
>> + STM32F2XXSPIState *s = opaque;
>> + uint32_t retval;
>> +
>> + DB_PRINT("Address: 0x%"HWADDR_PRIx"\n", addr);
>> +
>> + switch (addr) {
>> + case STM_SPI_CR1:
>> + return s->spi_cr1;
>> + case STM_SPI_CR2:
>> + qemu_log_mask(LOG_UNIMP, "%s: Interrupts and DMA are not implemented\n",
>> + __func__);
>> + return s->spi_cr2;
>> + case STM_SPI_SR:
>> + retval = s->spi_sr;
>> + return retval;
>> + case STM_SPI_DR:
>> + stm32f2xx_spi_transfer(s);
>> + s->spi_sr &= ~STM_SPI_SR_RXNE;
>> + return s->spi_dr;
>> + case STM_SPI_CRCPR:
>> + qemu_log_mask(LOG_UNIMP, "%s: CRC is not implemented, the registers " \
>> + "are included for compatability\n", __func__);
>
> "compatibility" again, here and below.
Fixed
>
>
>> + return s->spi_crcpr;
>> + case STM_SPI_RXCRCR:
>> + qemu_log_mask(LOG_UNIMP, "%s: CRC is not implemented, the registers " \
>> + "are included for compatability\n", __func__);
>> + return s->spi_rxcrcr;
>> + case STM_SPI_TXCRCR:
>> + qemu_log_mask(LOG_UNIMP, "%s: CRC is not implemented, the registers " \
>> + "are included for compatability\n", __func__);
>> + return s->spi_txcrcr;
>> + case STM_SPI_I2SCFGR:
>> + qemu_log_mask(LOG_UNIMP, "%s: I2S is not implemented, the registers " \
>> + "are included for compatability\n", __func__);
>> + return s->spi_i2scfgr;
>> + case STM_SPI_I2SPR:
>> + qemu_log_mask(LOG_UNIMP, "%s: I2S is not implemented, the registers " \
>> + "are included for compatability\n", __func__);
>> + return s->spi_i2spr;
>> + default:
>> + qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%"HWADDR_PRIx"\n",
>
> Spaces, please.
Fixed
>
>> +static void stm32f2xx_spi_class_init(ObjectClass *klass, void *data)
>> +{
>> + DeviceClass *dc = DEVICE_CLASS(klass);
>> +
>> + dc->reset = stm32f2xx_spi_reset;
>> +}
>> +
>> +static const TypeInfo stm32f2xx_spi_info = {
>> + .name = TYPE_STM32F2XX_SPI,
>> + .parent = TYPE_SYS_BUS_DEVICE,
>> + .instance_size = sizeof(STM32F2XXSPIState),
>> + .instance_init = stm32f2xx_spi_init,
>> + .class_init = stm32f2xx_spi_class_init,
>> +};
>
> Can we have a VMState for migration, please?
Yep, I added one.
>
>> +
>> +static void stm32f2xx_spi_register_types(void)
>> +{
>> + type_register_static(&stm32f2xx_spi_info);
>> +}
>
>> +typedef struct {
>> + /* <private> */
>> + SysBusDevice parent_obj;
>> +
>> + /* <public> */
>> + MemoryRegion mmio;
>> +
>> + uint32_t spi_cr1;
>> + uint32_t spi_cr2;
>> + uint32_t spi_sr;
>> + uint32_t spi_dr;
>> + uint32_t spi_crcpr;
>> + uint32_t spi_rxcrcr;
>> + uint32_t spi_txcrcr;
>> + uint32_t spi_i2scfgr;
>> + uint32_t spi_i2spr;
>> +
>> + qemu_irq irq;
>> + SSIBus *ssi;
>> +} STM32F2XXSPIState;
>
> Personally I like to order the struct fields of a device to put all
> the not-migration data first (so here, mmio, irq, ssi), and then
> the fields that correspond to real device state after that.
> I don't feel very strongly about that though and of course a
> lot of our devices don't do it.
So far I think all the STM devices are all like this, so I'm going to
keep it as is. I don't really mind which way it is either, but I think
they should all be consistent and at the moment this is the consistent
way :)
Thanks,
Alistair
>
> thanks
> -- PMM
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [Qemu-devel] [PATCH v3 5/7] STM32F205: Connect the ADC devices
2016-02-02 15:27 ` Peter Maydell
@ 2016-02-21 23:35 ` Alistair Francis
2016-02-22 0:29 ` Peter Maydell
0 siblings, 1 reply; 14+ messages in thread
From: Alistair Francis @ 2016-02-21 23:35 UTC (permalink / raw)
To: Peter Maydell; +Cc: Peter Crosthwaite, QEMU Developers, Konstanty Bialkowski
On Tue, Feb 2, 2016 at 7:27 AM, Peter Maydell <peter.maydell@linaro.org> wrote:
> On 19 January 2016 at 07:23, Alistair Francis <alistair23@gmail.com> wrote:
>> Connect the ADC devices to the STM32F205 SoC.
>>
>> Signed-off-by: Alistair Francis <alistair@alistair23.me>
>> ---
>> V2:
>> - Fix up the device/devices commit message
>>
>> hw/arm/stm32f205_soc.c | 22 ++++++++++++++++++++++
>> include/hw/arm/stm32f205_soc.h | 3 +++
>> 2 files changed, 25 insertions(+)
>>
>> diff --git a/hw/arm/stm32f205_soc.c b/hw/arm/stm32f205_soc.c
>> index a2bd970..28d4301 100644
>> --- a/hw/arm/stm32f205_soc.c
>> +++ b/hw/arm/stm32f205_soc.c
>> @@ -32,9 +32,12 @@ static const uint32_t timer_addr[STM_NUM_TIMERS] = { 0x40000000, 0x40000400,
>> 0x40000800, 0x40000C00 };
>> static const uint32_t usart_addr[STM_NUM_USARTS] = { 0x40011000, 0x40004400,
>> 0x40004800, 0x40004C00, 0x40005000, 0x40011400 };
>> +static const uint32_t adc_addr[STM_NUM_ADCS] = { 0x40012000, 0x40012100,
>> + 0x40012200 };
>>
>> static const int timer_irq[STM_NUM_TIMERS] = {28, 29, 30, 50};
>> static const int usart_irq[STM_NUM_USARTS] = {37, 38, 39, 52, 53, 71};
>> +#define ADC_IRQ 18
>
> Really three devices but only one IRQ ?
Yep, that's how HW does it. At least according to the reference manual.
>
>> + /* ADC 1 to 3 */
>> + for (i = 0; i < STM_NUM_ADCS; i++) {
>> + dev = DEVICE(&(s->adc[i]));
>> + object_property_set_bool(OBJECT(&s->adc[i]), true, "realized", &err);
>> + if (err != NULL) {
>> + error_propagate(errp, err);
>> + return;
>> + }
>> + busdev = SYS_BUS_DEVICE(dev);
>> + sysbus_mmio_map(busdev, 0, adc_addr[i]);
>> + sysbus_connect_irq(busdev, 0, qdev_get_gpio_in(nvic, ADC_IRQ));
>
> You can't just wire multiple irq lines up like this; I think if
> you do then if devices A and B both assert the IRQ and then A
> deasserts it, then the receiving device will see an IRQ deassert
> when it should not (since B still holds it high).
I can't figure out if that is how HW actually does it. I can't find
too much in the data sheet on how these interrupts behave.
In saying that, I am fine with what you described being the behaviour.
I don't know any better way to connect the 3 devices to one interrupt
line. Do you have any suggestions?
Thanks,
Alistair
>
> thanks
> -- PMM
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [Qemu-devel] [PATCH v3 5/7] STM32F205: Connect the ADC devices
2016-02-21 23:35 ` Alistair Francis
@ 2016-02-22 0:29 ` Peter Maydell
0 siblings, 0 replies; 14+ messages in thread
From: Peter Maydell @ 2016-02-22 0:29 UTC (permalink / raw)
To: Alistair Francis; +Cc: Peter Crosthwaite, QEMU Developers, Konstanty Bialkowski
On 21 February 2016 at 23:35, Alistair Francis <alistair23@gmail.com> wrote:
> On Tue, Feb 2, 2016 at 7:27 AM, Peter Maydell <peter.maydell@linaro.org> wrote:
>> On 19 January 2016 at 07:23, Alistair Francis <alistair23@gmail.com> wrote:
>> You can't just wire multiple irq lines up like this; I think if
>> you do then if devices A and B both assert the IRQ and then A
>> deasserts it, then the receiving device will see an IRQ deassert
>> when it should not (since B still holds it high).
>
> I can't figure out if that is how HW actually does it. I can't find
> too much in the data sheet on how these interrupts behave.
>
> In saying that, I am fine with what you described being the behaviour.
> I don't know any better way to connect the 3 devices to one interrupt
> line. Do you have any suggestions?
You're right that the data sheet is unclear, but I think the
only vaguely plausible setup is that the three lines are ORed
together. That way if any ADC asserts the line then the guest
presumably looks at all of them to find which one has asserted
it, and then writes to the register to acknowledge the interrupt.
So if two ADCs assert at the same time, the guest will still
(correctly) see an interrupt until it acks the second ADC.
Unfortunately we don't have a qemu_irq OR gate at the moment
I think, but it's a pretty simple thing to write.
thanks
-- PMM
^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2016-02-22 0:29 UTC | newest]
Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-01-19 7:22 [Qemu-devel] [PATCH v3 0/7] Update the Netduino 2 Machine Alistair Francis
2016-01-19 7:23 ` [Qemu-devel] [PATCH v3 1/7] STM32F205: Remove the individual device variables Alistair Francis
2016-01-19 7:23 ` [Qemu-devel] [PATCH v3 2/7] STM32F2xx: Display PWM duty cycle from timer Alistair Francis
2016-01-19 7:23 ` [Qemu-devel] [PATCH v3 3/7] STM32F2xx: Add the ADC device Alistair Francis
2016-02-02 15:17 ` Peter Maydell
2016-02-21 23:12 ` Alistair Francis
2016-01-19 7:23 ` [Qemu-devel] [PATCH v3 4/7] STM32F2xx: Add the SPI device Alistair Francis
2016-02-02 15:30 ` Peter Maydell
2016-02-21 23:24 ` Alistair Francis
2016-01-19 7:23 ` [Qemu-devel] [PATCH v3 5/7] STM32F205: Connect the ADC devices Alistair Francis
2016-02-02 15:27 ` Peter Maydell
2016-02-21 23:35 ` Alistair Francis
2016-02-22 0:29 ` Peter Maydell
2016-01-19 7:23 ` [Qemu-devel] [PATCH v3 7/7] MAINTAINERS: Add Alistair to the maintainers list Alistair Francis
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).