* [Qemu-devel] [PATCH v2 1/7] STM32F205: Remove the individual device variables
2015-05-30 5:45 [Qemu-devel] [PATCH v2 0/7] Update the Netduino 2 Machine Alistair Francis
@ 2015-05-30 5:45 ` Alistair Francis
2015-05-30 5:45 ` [Qemu-devel] [PATCH v2 2/7] STM32F2xx: Display PWM duty cycle from timer Alistair Francis
` (3 subsequent siblings)
4 siblings, 0 replies; 7+ messages in thread
From: Alistair Francis @ 2015-05-30 5:45 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 | 30 +++++++++++++++---------------
1 file changed, 15 insertions(+), 15 deletions(-)
diff --git a/hw/arm/stm32f205_soc.c b/hw/arm/stm32f205_soc.c
index 0f3bdc7..63893f3 100644
--- a/hw/arm/stm32f205_soc.c
+++ b/hw/arm/stm32f205_soc.c
@@ -59,8 +59,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;
- SysBusDevice *syscfgbusdev, *usartbusdev, *timerbusdev;
+ DeviceState *dev;
+ SysBusDevice *busdev;
qemu_irq *pic;
Error *err = NULL;
int i;
@@ -92,41 +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, pic[71]);
+ busdev = SYS_BUS_DEVICE(dev);
+ sysbus_mmio_map(busdev, 0, 0x40013800);
+ sysbus_connect_irq(busdev, 0, pic[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, pic[usart_irq[i]]);
+ busdev = SYS_BUS_DEVICE(dev);
+ sysbus_mmio_map(busdev, 0, usart_addr[i]);
+ sysbus_connect_irq(busdev, 0, pic[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, pic[timer_irq[i]]);
+ busdev = SYS_BUS_DEVICE(dev);
+ sysbus_mmio_map(busdev, 0, timer_addr[i]);
+ sysbus_connect_irq(busdev, 0, pic[timer_irq[i]]);
}
}
--
2.1.4
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [Qemu-devel] [PATCH v2 2/7] STM32F2xx: Display PWM duty cycle from timer
2015-05-30 5:45 [Qemu-devel] [PATCH v2 0/7] Update the Netduino 2 Machine Alistair Francis
2015-05-30 5:45 ` [Qemu-devel] [PATCH v2 1/7] STM32F205: Remove the individual device variables Alistair Francis
@ 2015-05-30 5:45 ` Alistair Francis
2015-05-30 6:42 ` Peter Crosthwaite
2015-05-30 5:45 ` [Qemu-devel] [PATCH v2 3/7] STM32F2xx: Add the ADC device Alistair Francis
` (2 subsequent siblings)
4 siblings, 1 reply; 7+ messages in thread
From: Alistair Francis @ 2015-05-30 5:45 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>
---
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..de4b8af 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("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.1.4
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [Qemu-devel] [PATCH v2 2/7] STM32F2xx: Display PWM duty cycle from timer
2015-05-30 5:45 ` [Qemu-devel] [PATCH v2 2/7] STM32F2xx: Display PWM duty cycle from timer Alistair Francis
@ 2015-05-30 6:42 ` Peter Crosthwaite
0 siblings, 0 replies; 7+ messages in thread
From: Peter Crosthwaite @ 2015-05-30 6:42 UTC (permalink / raw)
To: Alistair Francis
Cc: Peter Maydell, qemu-devel@nongnu.org Developers,
Konstanty Bialkowski
On Fri, May 29, 2015 at 10:45 PM, Alistair Francis <alistair23@gmail.com> wrote:
> If correctly configured allow the STM32F2xx timer to print
> out the PWM duty cycle information.
>
> Signed-off-by: Alistair Francis <alistair@alistair23.me>
> ---
> 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..de4b8af 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) &&
Use | to combine multiple masks together (to show you are doing bit
operations rather than arithmetic).
> + !(s->tim_ccmr1 & TIM_CCMR1_OC2M0) &&
> + s->tim_ccmr1 & TIM_CCMR1_OC2PE &&
> + s->tim_ccer & TIM_CCER_CC2E) {
> + /* PWM 2 - Mode 1 */
> + DB_PRINT("Duty Cycle: %d%%\n",
> + s->tim_ccr2 / (100 * (s->tim_psc + 1)));
You should be more descriptive and give more context to the print. Add
the timer name and "PWM" in there.
Otherwise:
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Regards,
Peter
> + }
> }
>
> static inline int64_t stm32f2xx_ns_to_ticks(STM32F2XXTimerState *s, int64_t t)
> --
> 2.1.4
>
>
^ permalink raw reply [flat|nested] 7+ messages in thread
* [Qemu-devel] [PATCH v2 3/7] STM32F2xx: Add the ADC device
2015-05-30 5:45 [Qemu-devel] [PATCH v2 0/7] Update the Netduino 2 Machine Alistair Francis
2015-05-30 5:45 ` [Qemu-devel] [PATCH v2 1/7] STM32F205: Remove the individual device variables Alistair Francis
2015-05-30 5:45 ` [Qemu-devel] [PATCH v2 2/7] STM32F2xx: Display PWM duty cycle from timer Alistair Francis
@ 2015-05-30 5:45 ` Alistair Francis
2015-05-30 5:45 ` [Qemu-devel] [PATCH v2 4/7] STM32F2xx: Add the SPI device Alistair Francis
2015-05-30 5:45 ` [Qemu-devel] [PATCH v2 7/7] MAINTAINERS: Add Alistair to the maintainers list Alistair Francis
4 siblings, 0 replies; 7+ messages in thread
From: Alistair Francis @ 2015-05-30 5:45 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 74f1db3..b172caf 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -84,6 +84,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 73afa41..96d9b77 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.1.4
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [Qemu-devel] [PATCH v2 4/7] STM32F2xx: Add the SPI device
2015-05-30 5:45 [Qemu-devel] [PATCH v2 0/7] Update the Netduino 2 Machine Alistair Francis
` (2 preceding siblings ...)
2015-05-30 5:45 ` [Qemu-devel] [PATCH v2 3/7] STM32F2xx: Add the ADC device Alistair Francis
@ 2015-05-30 5:45 ` Alistair Francis
2015-05-30 5:45 ` [Qemu-devel] [PATCH v2 7/7] MAINTAINERS: Add Alistair to the maintainers list Alistair Francis
4 siblings, 0 replies; 7+ messages in thread
From: Alistair Francis @ 2015-05-30 5:45 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 b172caf..18ef3b0 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -85,6 +85,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.1.4
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [Qemu-devel] [PATCH v2 7/7] MAINTAINERS: Add Alistair to the maintainers list
2015-05-30 5:45 [Qemu-devel] [PATCH v2 0/7] Update the Netduino 2 Machine Alistair Francis
` (3 preceding siblings ...)
2015-05-30 5:45 ` [Qemu-devel] [PATCH v2 4/7] STM32F2xx: Add the SPI device Alistair Francis
@ 2015-05-30 5:45 ` Alistair Francis
4 siblings, 0 replies; 7+ messages in thread
From: Alistair Francis @ 2015-05-30 5:45 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 0463696..4af3b24 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -356,6 +356,21 @@ F: hw/misc/zynq_slcr.c
F: hw/*/cadence_*
F: hw/ssi/xilinx_spips.c
+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.1.4
^ permalink raw reply related [flat|nested] 7+ messages in thread