2 * Microbit stub for Nordic Semiconductor nRF51 SoC Two-Wire Interface
3 * http://infocenter.nordicsemi.com/pdf/nRF51_RM_v3.0.1.pdf
5 * This is a microbit-specific stub for the TWI controller on the nRF51 SoC.
6 * We don't emulate I2C devices but the firmware probes the
7 * accelerometer/magnetometer on startup and panics if they are not found.
8 * Therefore we stub out the probing.
10 * In the future this file could evolve into a full nRF51 TWI controller
13 * Copyright 2018 Steffen Görtz <contrib@steffen-goertz.de>
14 * Copyright 2019 Red Hat, Inc.
16 * This code is licensed under the GPL version 2 or later. See
17 * the COPYING file in the top-level directory.
20 #include "qemu/osdep.h"
22 #include "hw/i2c/microbit_i2c.h"
24 static const uint32_t twi_read_sequence
[] = {0x5A, 0x5A, 0x40};
26 static uint64_t microbit_i2c_read(void *opaque
, hwaddr addr
, unsigned int size
)
28 MicrobitI2CState
*s
= opaque
;
32 case NRF51_TWI_EVENT_STOPPED
:
35 case NRF51_TWI_EVENT_RXDREADY
:
38 case NRF51_TWI_EVENT_TXDSENT
:
41 case NRF51_TWI_REG_RXD
:
42 data
= twi_read_sequence
[s
->read_idx
];
43 if (s
->read_idx
< G_N_ELEMENTS(twi_read_sequence
)) {
48 data
= s
->regs
[addr
/ sizeof(s
->regs
[0])];
52 qemu_log_mask(LOG_UNIMP
, "%s: 0x%" HWADDR_PRIx
" [%u] = %" PRIx32
"\n",
53 __func__
, addr
, size
, (uint32_t)data
);
59 static void microbit_i2c_write(void *opaque
, hwaddr addr
, uint64_t data
,
62 MicrobitI2CState
*s
= opaque
;
64 qemu_log_mask(LOG_UNIMP
, "%s: 0x%" HWADDR_PRIx
" <- 0x%" PRIx64
" [%u]\n",
65 __func__
, addr
, data
, size
);
66 s
->regs
[addr
/ sizeof(s
->regs
[0])] = data
;
69 static const MemoryRegionOps microbit_i2c_ops
= {
70 .read
= microbit_i2c_read
,
71 .write
= microbit_i2c_write
,
72 .endianness
= DEVICE_LITTLE_ENDIAN
,
73 .impl
.min_access_size
= 4,
74 .impl
.max_access_size
= 4,
77 static const VMStateDescription microbit_i2c_vmstate
= {
78 .name
= TYPE_MICROBIT_I2C
,
80 .minimum_version_id
= 1,
81 .fields
= (VMStateField
[]) {
82 VMSTATE_UINT32_ARRAY(regs
, MicrobitI2CState
, MICROBIT_I2C_NREGS
),
83 VMSTATE_UINT32(read_idx
, MicrobitI2CState
),
87 static void microbit_i2c_reset(DeviceState
*dev
)
89 MicrobitI2CState
*s
= MICROBIT_I2C(dev
);
91 memset(s
->regs
, 0, sizeof(s
->regs
));
95 static void microbit_i2c_realize(DeviceState
*dev
, Error
**errp
)
97 SysBusDevice
*sbd
= SYS_BUS_DEVICE(dev
);
98 MicrobitI2CState
*s
= MICROBIT_I2C(dev
);
100 memory_region_init_io(&s
->iomem
, OBJECT(s
), µbit_i2c_ops
, s
,
101 "microbit.twi", NRF51_TWI_SIZE
);
102 sysbus_init_mmio(sbd
, &s
->iomem
);
105 static void microbit_i2c_class_init(ObjectClass
*klass
, void *data
)
107 DeviceClass
*dc
= DEVICE_CLASS(klass
);
109 dc
->vmsd
= µbit_i2c_vmstate
;
110 dc
->reset
= microbit_i2c_reset
;
111 dc
->realize
= microbit_i2c_realize
;
112 dc
->desc
= "Microbit I2C controller";
115 static const TypeInfo microbit_i2c_info
= {
116 .name
= TYPE_MICROBIT_I2C
,
117 .parent
= TYPE_SYS_BUS_DEVICE
,
118 .instance_size
= sizeof(MicrobitI2CState
),
119 .class_init
= microbit_i2c_class_init
,
122 static void microbit_i2c_register_types(void)
124 type_register_static(µbit_i2c_info
);
127 type_init(microbit_i2c_register_types
)