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 "qemu/module.h"
23 #include "hw/i2c/microbit_i2c.h"
25 static const uint32_t twi_read_sequence
[] = {0x5A, 0x5A, 0x40};
27 static uint64_t microbit_i2c_read(void *opaque
, hwaddr addr
, unsigned int size
)
29 MicrobitI2CState
*s
= opaque
;
33 case NRF51_TWI_EVENT_STOPPED
:
36 case NRF51_TWI_EVENT_RXDREADY
:
39 case NRF51_TWI_EVENT_TXDSENT
:
42 case NRF51_TWI_REG_RXD
:
43 data
= twi_read_sequence
[s
->read_idx
];
44 if (s
->read_idx
< G_N_ELEMENTS(twi_read_sequence
)) {
49 data
= s
->regs
[addr
/ sizeof(s
->regs
[0])];
53 qemu_log_mask(LOG_UNIMP
, "%s: 0x%" HWADDR_PRIx
" [%u] = %" PRIx32
"\n",
54 __func__
, addr
, size
, (uint32_t)data
);
60 static void microbit_i2c_write(void *opaque
, hwaddr addr
, uint64_t data
,
63 MicrobitI2CState
*s
= opaque
;
65 qemu_log_mask(LOG_UNIMP
, "%s: 0x%" HWADDR_PRIx
" <- 0x%" PRIx64
" [%u]\n",
66 __func__
, addr
, data
, size
);
67 s
->regs
[addr
/ sizeof(s
->regs
[0])] = data
;
70 static const MemoryRegionOps microbit_i2c_ops
= {
71 .read
= microbit_i2c_read
,
72 .write
= microbit_i2c_write
,
73 .endianness
= DEVICE_LITTLE_ENDIAN
,
74 .impl
.min_access_size
= 4,
75 .impl
.max_access_size
= 4,
78 static const VMStateDescription microbit_i2c_vmstate
= {
79 .name
= TYPE_MICROBIT_I2C
,
81 .minimum_version_id
= 1,
82 .fields
= (VMStateField
[]) {
83 VMSTATE_UINT32_ARRAY(regs
, MicrobitI2CState
, MICROBIT_I2C_NREGS
),
84 VMSTATE_UINT32(read_idx
, MicrobitI2CState
),
88 static void microbit_i2c_reset(DeviceState
*dev
)
90 MicrobitI2CState
*s
= MICROBIT_I2C(dev
);
92 memset(s
->regs
, 0, sizeof(s
->regs
));
96 static void microbit_i2c_realize(DeviceState
*dev
, Error
**errp
)
98 SysBusDevice
*sbd
= SYS_BUS_DEVICE(dev
);
99 MicrobitI2CState
*s
= MICROBIT_I2C(dev
);
101 memory_region_init_io(&s
->iomem
, OBJECT(s
), µbit_i2c_ops
, s
,
102 "microbit.twi", NRF51_TWI_SIZE
);
103 sysbus_init_mmio(sbd
, &s
->iomem
);
106 static void microbit_i2c_class_init(ObjectClass
*klass
, void *data
)
108 DeviceClass
*dc
= DEVICE_CLASS(klass
);
110 dc
->vmsd
= µbit_i2c_vmstate
;
111 dc
->reset
= microbit_i2c_reset
;
112 dc
->realize
= microbit_i2c_realize
;
113 dc
->desc
= "Microbit I2C controller";
116 static const TypeInfo microbit_i2c_info
= {
117 .name
= TYPE_MICROBIT_I2C
,
118 .parent
= TYPE_SYS_BUS_DEVICE
,
119 .instance_size
= sizeof(MicrobitI2CState
),
120 .class_init
= microbit_i2c_class_init
,
123 static void microbit_i2c_register_types(void)
125 type_register_static(µbit_i2c_info
);
128 type_init(microbit_i2c_register_types
)