1 /* 2 * STM32F405 SPI 3 * 4 * Copyright (c) 2014 Alistair Francis <alistair@alistair23.me> 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a copy 7 * of this software and associated documentation files (the "Software"), to deal 8 * in the Software without restriction, including without limitation the rights 9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 * copies of the Software, and to permit persons to whom the Software is 11 * furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included in 14 * all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 * THE SOFTWARE. 23 */ 24 25 #include "qemu/osdep.h" 26 #include "qemu/log.h" 27 #include "qemu/module.h" 28 #include "hw/ssi/stm32f2xx_spi.h" 29 #include "migration/vmstate.h" 30 31 #ifndef STM_SPI_ERR_DEBUG 32 #define STM_SPI_ERR_DEBUG 0 33 #endif 34 35 #define DB_PRINT_L(lvl, fmt, args...) do { \ 36 if (STM_SPI_ERR_DEBUG >= lvl) { \ 37 qemu_log("%s: " fmt, __func__, ## args); \ 38 } \ 39 } while (0) 40 41 #define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args) 42 43 static void stm32f2xx_spi_reset(DeviceState *dev) 44 { 45 STM32F2XXSPIState *s = STM32F2XX_SPI(dev); 46 47 s->spi_cr1 = 0x00000000; 48 s->spi_cr2 = 0x00000000; 49 s->spi_sr = 0x0000000A; 50 s->spi_dr = 0x0000000C; 51 s->spi_crcpr = 0x00000007; 52 s->spi_rxcrcr = 0x00000000; 53 s->spi_txcrcr = 0x00000000; 54 s->spi_i2scfgr = 0x00000000; 55 s->spi_i2spr = 0x00000002; 56 } 57 58 static void stm32f2xx_spi_transfer(STM32F2XXSPIState *s) 59 { 60 DB_PRINT("Data to send: 0x%x\n", s->spi_dr); 61 62 s->spi_dr = ssi_transfer(s->ssi, s->spi_dr); 63 s->spi_sr |= STM_SPI_SR_RXNE; 64 65 DB_PRINT("Data received: 0x%x\n", s->spi_dr); 66 } 67 68 static uint64_t stm32f2xx_spi_read(void *opaque, hwaddr addr, 69 unsigned int size) 70 { 71 STM32F2XXSPIState *s = opaque; 72 73 DB_PRINT("Address: 0x%" HWADDR_PRIx "\n", addr); 74 75 switch (addr) { 76 case STM_SPI_CR1: 77 return s->spi_cr1; 78 case STM_SPI_CR2: 79 qemu_log_mask(LOG_UNIMP, "%s: Interrupts and DMA are not implemented\n", 80 __func__); 81 return s->spi_cr2; 82 case STM_SPI_SR: 83 return s->spi_sr; 84 case STM_SPI_DR: 85 stm32f2xx_spi_transfer(s); 86 s->spi_sr &= ~STM_SPI_SR_RXNE; 87 return s->spi_dr; 88 case STM_SPI_CRCPR: 89 qemu_log_mask(LOG_UNIMP, "%s: CRC is not implemented, the registers " \ 90 "are included for compatibility\n", __func__); 91 return s->spi_crcpr; 92 case STM_SPI_RXCRCR: 93 qemu_log_mask(LOG_UNIMP, "%s: CRC is not implemented, the registers " \ 94 "are included for compatibility\n", __func__); 95 return s->spi_rxcrcr; 96 case STM_SPI_TXCRCR: 97 qemu_log_mask(LOG_UNIMP, "%s: CRC is not implemented, the registers " \ 98 "are included for compatibility\n", __func__); 99 return s->spi_txcrcr; 100 case STM_SPI_I2SCFGR: 101 qemu_log_mask(LOG_UNIMP, "%s: I2S is not implemented, the registers " \ 102 "are included for compatibility\n", __func__); 103 return s->spi_i2scfgr; 104 case STM_SPI_I2SPR: 105 qemu_log_mask(LOG_UNIMP, "%s: I2S is not implemented, the registers " \ 106 "are included for compatibility\n", __func__); 107 return s->spi_i2spr; 108 default: 109 qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%" HWADDR_PRIx "\n", 110 __func__, addr); 111 } 112 113 return 0; 114 } 115 116 static void stm32f2xx_spi_write(void *opaque, hwaddr addr, 117 uint64_t val64, unsigned int size) 118 { 119 STM32F2XXSPIState *s = opaque; 120 uint32_t value = val64; 121 122 DB_PRINT("Address: 0x%" HWADDR_PRIx ", Value: 0x%x\n", addr, value); 123 124 switch (addr) { 125 case STM_SPI_CR1: 126 s->spi_cr1 = value; 127 return; 128 case STM_SPI_CR2: 129 qemu_log_mask(LOG_UNIMP, "%s: " \ 130 "Interrupts and DMA are not implemented\n", __func__); 131 s->spi_cr2 = value; 132 return; 133 case STM_SPI_SR: 134 /* Read only register, except for clearing the CRCERR bit, which 135 * is not supported 136 */ 137 return; 138 case STM_SPI_DR: 139 s->spi_dr = value; 140 stm32f2xx_spi_transfer(s); 141 return; 142 case STM_SPI_CRCPR: 143 qemu_log_mask(LOG_UNIMP, "%s: CRC is not implemented\n", __func__); 144 return; 145 case STM_SPI_RXCRCR: 146 qemu_log_mask(LOG_GUEST_ERROR, "%s: Read only register: " \ 147 "0x%" HWADDR_PRIx "\n", __func__, addr); 148 return; 149 case STM_SPI_TXCRCR: 150 qemu_log_mask(LOG_GUEST_ERROR, "%s: Read only register: " \ 151 "0x%" HWADDR_PRIx "\n", __func__, addr); 152 return; 153 case STM_SPI_I2SCFGR: 154 qemu_log_mask(LOG_UNIMP, "%s: " \ 155 "I2S is not implemented\n", __func__); 156 return; 157 case STM_SPI_I2SPR: 158 qemu_log_mask(LOG_UNIMP, "%s: " \ 159 "I2S is not implemented\n", __func__); 160 return; 161 default: 162 qemu_log_mask(LOG_GUEST_ERROR, 163 "%s: Bad offset 0x%" HWADDR_PRIx "\n", __func__, addr); 164 } 165 } 166 167 static const MemoryRegionOps stm32f2xx_spi_ops = { 168 .read = stm32f2xx_spi_read, 169 .write = stm32f2xx_spi_write, 170 .endianness = DEVICE_NATIVE_ENDIAN, 171 }; 172 173 static const VMStateDescription vmstate_stm32f2xx_spi = { 174 .name = TYPE_STM32F2XX_SPI, 175 .version_id = 1, 176 .minimum_version_id = 1, 177 .fields = (const VMStateField[]) { 178 VMSTATE_UINT32(spi_cr1, STM32F2XXSPIState), 179 VMSTATE_UINT32(spi_cr2, STM32F2XXSPIState), 180 VMSTATE_UINT32(spi_sr, STM32F2XXSPIState), 181 VMSTATE_UINT32(spi_dr, STM32F2XXSPIState), 182 VMSTATE_UINT32(spi_crcpr, STM32F2XXSPIState), 183 VMSTATE_UINT32(spi_rxcrcr, STM32F2XXSPIState), 184 VMSTATE_UINT32(spi_txcrcr, STM32F2XXSPIState), 185 VMSTATE_UINT32(spi_i2scfgr, STM32F2XXSPIState), 186 VMSTATE_UINT32(spi_i2spr, STM32F2XXSPIState), 187 VMSTATE_END_OF_LIST() 188 } 189 }; 190 191 static void stm32f2xx_spi_init(Object *obj) 192 { 193 STM32F2XXSPIState *s = STM32F2XX_SPI(obj); 194 DeviceState *dev = DEVICE(obj); 195 196 memory_region_init_io(&s->mmio, obj, &stm32f2xx_spi_ops, s, 197 TYPE_STM32F2XX_SPI, 0x400); 198 sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio); 199 200 sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->irq); 201 202 s->ssi = ssi_create_bus(dev, "ssi"); 203 } 204 205 static void stm32f2xx_spi_class_init(ObjectClass *klass, void *data) 206 { 207 DeviceClass *dc = DEVICE_CLASS(klass); 208 209 device_class_set_legacy_reset(dc, stm32f2xx_spi_reset); 210 dc->vmsd = &vmstate_stm32f2xx_spi; 211 } 212 213 static const TypeInfo stm32f2xx_spi_info = { 214 .name = TYPE_STM32F2XX_SPI, 215 .parent = TYPE_SYS_BUS_DEVICE, 216 .instance_size = sizeof(STM32F2XXSPIState), 217 .instance_init = stm32f2xx_spi_init, 218 .class_init = stm32f2xx_spi_class_init, 219 }; 220 221 static void stm32f2xx_spi_register_types(void) 222 { 223 type_register_static(&stm32f2xx_spi_info); 224 } 225 226 type_init(stm32f2xx_spi_register_types) 227