nrf51_gpio.c 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329
  1. /*
  2. * nRF51 System-on-Chip general purpose input/output register definition
  3. *
  4. * Reference Manual: http://infocenter.nordicsemi.com/pdf/nRF51_RM_v3.0.pdf
  5. * Product Spec: http://infocenter.nordicsemi.com/pdf/nRF51822_PS_v3.1.pdf
  6. *
  7. * Copyright 2018 Steffen Görtz <contrib@steffen-goertz.de>
  8. *
  9. * This code is licensed under the GPL version 2 or later. See
  10. * the COPYING file in the top-level directory.
  11. */
  12. #include "qemu/osdep.h"
  13. #include "qemu/log.h"
  14. #include "qemu/module.h"
  15. #include "hw/gpio/nrf51_gpio.h"
  16. #include "hw/irq.h"
  17. #include "migration/vmstate.h"
  18. #include "trace.h"
  19. /*
  20. * Check if the output driver is connected to the direction switch
  21. * given the current configuration and logic level.
  22. * It is not differentiated between standard and "high"(-power) drive modes.
  23. */
  24. static bool is_connected(uint32_t config, uint32_t level)
  25. {
  26. bool state;
  27. uint32_t drive_config = extract32(config, 8, 3);
  28. switch (drive_config) {
  29. case 0 ... 3:
  30. state = true;
  31. break;
  32. case 4 ... 5:
  33. state = level != 0;
  34. break;
  35. case 6 ... 7:
  36. state = level == 0;
  37. break;
  38. default:
  39. g_assert_not_reached();
  40. }
  41. return state;
  42. }
  43. static int pull_value(uint32_t config)
  44. {
  45. int pull = extract32(config, 2, 2);
  46. if (pull == NRF51_GPIO_PULLDOWN) {
  47. return 0;
  48. } else if (pull == NRF51_GPIO_PULLUP) {
  49. return 1;
  50. }
  51. return -1;
  52. }
  53. static void update_output_irq(NRF51GPIOState *s, size_t i,
  54. bool connected, bool level)
  55. {
  56. int64_t irq_level = connected ? level : -1;
  57. bool old_connected = extract32(s->old_out_connected, i, 1);
  58. bool old_level = extract32(s->old_out, i, 1);
  59. if ((old_connected != connected) || (old_level != level)) {
  60. qemu_set_irq(s->output[i], irq_level);
  61. trace_nrf51_gpio_update_output_irq(i, irq_level);
  62. }
  63. s->old_out = deposit32(s->old_out, i, 1, level);
  64. s->old_out_connected = deposit32(s->old_out_connected, i, 1, connected);
  65. }
  66. static void update_state(NRF51GPIOState *s)
  67. {
  68. int pull;
  69. size_t i;
  70. bool connected_out, dir, connected_in, out, in, input;
  71. bool assert_detect = false;
  72. for (i = 0; i < NRF51_GPIO_PINS; i++) {
  73. pull = pull_value(s->cnf[i]);
  74. dir = extract32(s->cnf[i], 0, 1);
  75. connected_in = extract32(s->in_mask, i, 1);
  76. out = extract32(s->out, i, 1);
  77. in = extract32(s->in, i, 1);
  78. input = !extract32(s->cnf[i], 1, 1);
  79. connected_out = is_connected(s->cnf[i], out) && dir;
  80. if (!input) {
  81. if (pull >= 0) {
  82. /* Input buffer disconnected from external drives */
  83. s->in = deposit32(s->in, i, 1, pull);
  84. }
  85. } else {
  86. if (connected_out && connected_in && out != in) {
  87. /* Pin both driven externally and internally */
  88. qemu_log_mask(LOG_GUEST_ERROR,
  89. "GPIO pin %zu short circuited\n", i);
  90. }
  91. if (connected_in) {
  92. uint32_t detect_config = extract32(s->cnf[i], 16, 2);
  93. if ((detect_config == 2) && (in == 1)) {
  94. assert_detect = true;
  95. }
  96. if ((detect_config == 3) && (in == 0)) {
  97. assert_detect = true;
  98. }
  99. } else {
  100. /*
  101. * Floating input: the output stimulates IN if connected,
  102. * otherwise pull-up/pull-down resistors put a value on both
  103. * IN and OUT.
  104. */
  105. if (pull >= 0 && !connected_out) {
  106. connected_out = true;
  107. out = pull;
  108. }
  109. if (connected_out) {
  110. s->in = deposit32(s->in, i, 1, out);
  111. }
  112. }
  113. }
  114. update_output_irq(s, i, connected_out, out);
  115. }
  116. qemu_set_irq(s->detect, assert_detect);
  117. }
  118. /*
  119. * Direction is exposed in both the DIR register and the DIR bit
  120. * of each PINs CNF configuration register. Reflect bits for pins in DIR
  121. * to individual pin configuration registers.
  122. */
  123. static void reflect_dir_bit_in_cnf(NRF51GPIOState *s)
  124. {
  125. size_t i;
  126. uint32_t value = s->dir;
  127. for (i = 0; i < NRF51_GPIO_PINS; i++) {
  128. s->cnf[i] = (s->cnf[i] & ~(1UL)) | ((value >> i) & 0x01);
  129. }
  130. }
  131. static uint64_t nrf51_gpio_read(void *opaque, hwaddr offset, unsigned int size)
  132. {
  133. NRF51GPIOState *s = NRF51_GPIO(opaque);
  134. uint64_t r = 0;
  135. size_t idx;
  136. switch (offset) {
  137. case NRF51_GPIO_REG_OUT ... NRF51_GPIO_REG_OUTCLR:
  138. r = s->out;
  139. break;
  140. case NRF51_GPIO_REG_IN:
  141. r = s->in;
  142. break;
  143. case NRF51_GPIO_REG_DIR ... NRF51_GPIO_REG_DIRCLR:
  144. r = s->dir;
  145. break;
  146. case NRF51_GPIO_REG_CNF_START ... NRF51_GPIO_REG_CNF_END:
  147. idx = (offset - NRF51_GPIO_REG_CNF_START) / 4;
  148. r = s->cnf[idx];
  149. break;
  150. default:
  151. qemu_log_mask(LOG_GUEST_ERROR,
  152. "%s: bad read offset 0x%" HWADDR_PRIx "\n",
  153. __func__, offset);
  154. }
  155. trace_nrf51_gpio_read(offset, r);
  156. return r;
  157. }
  158. static void nrf51_gpio_write(void *opaque, hwaddr offset,
  159. uint64_t value, unsigned int size)
  160. {
  161. NRF51GPIOState *s = NRF51_GPIO(opaque);
  162. size_t idx;
  163. trace_nrf51_gpio_write(offset, value);
  164. switch (offset) {
  165. case NRF51_GPIO_REG_OUT:
  166. s->out = value;
  167. break;
  168. case NRF51_GPIO_REG_OUTSET:
  169. s->out |= value;
  170. break;
  171. case NRF51_GPIO_REG_OUTCLR:
  172. s->out &= ~value;
  173. break;
  174. case NRF51_GPIO_REG_DIR:
  175. s->dir = value;
  176. reflect_dir_bit_in_cnf(s);
  177. break;
  178. case NRF51_GPIO_REG_DIRSET:
  179. s->dir |= value;
  180. reflect_dir_bit_in_cnf(s);
  181. break;
  182. case NRF51_GPIO_REG_DIRCLR:
  183. s->dir &= ~value;
  184. reflect_dir_bit_in_cnf(s);
  185. break;
  186. case NRF51_GPIO_REG_CNF_START ... NRF51_GPIO_REG_CNF_END:
  187. idx = (offset - NRF51_GPIO_REG_CNF_START) / 4;
  188. s->cnf[idx] = value;
  189. /*
  190. * direction is exposed in both the DIR register and the DIR bit
  191. * of each PINs CNF configuration register.
  192. */
  193. s->dir = (s->dir & ~(1UL << idx)) | ((value & 0x01) << idx);
  194. break;
  195. default:
  196. qemu_log_mask(LOG_GUEST_ERROR,
  197. "%s: bad write offset 0x%" HWADDR_PRIx "\n",
  198. __func__, offset);
  199. }
  200. update_state(s);
  201. }
  202. static const MemoryRegionOps gpio_ops = {
  203. .read = nrf51_gpio_read,
  204. .write = nrf51_gpio_write,
  205. .endianness = DEVICE_LITTLE_ENDIAN,
  206. .impl.min_access_size = 4,
  207. .impl.max_access_size = 4,
  208. };
  209. static void nrf51_gpio_set(void *opaque, int line, int value)
  210. {
  211. NRF51GPIOState *s = NRF51_GPIO(opaque);
  212. trace_nrf51_gpio_set(line, value);
  213. assert(line >= 0 && line < NRF51_GPIO_PINS);
  214. s->in_mask = deposit32(s->in_mask, line, 1, value >= 0);
  215. if (value >= 0) {
  216. s->in = deposit32(s->in, line, 1, value != 0);
  217. }
  218. update_state(s);
  219. }
  220. static void nrf51_gpio_reset(DeviceState *dev)
  221. {
  222. NRF51GPIOState *s = NRF51_GPIO(dev);
  223. size_t i;
  224. s->out = 0;
  225. s->old_out = 0;
  226. s->old_out_connected = 0;
  227. s->in = 0;
  228. s->in_mask = 0;
  229. s->dir = 0;
  230. for (i = 0; i < NRF51_GPIO_PINS; i++) {
  231. s->cnf[i] = 0x00000002;
  232. }
  233. }
  234. static const VMStateDescription vmstate_nrf51_gpio = {
  235. .name = TYPE_NRF51_GPIO,
  236. .version_id = 1,
  237. .minimum_version_id = 1,
  238. .fields = (const VMStateField[]) {
  239. VMSTATE_UINT32(out, NRF51GPIOState),
  240. VMSTATE_UINT32(in, NRF51GPIOState),
  241. VMSTATE_UINT32(in_mask, NRF51GPIOState),
  242. VMSTATE_UINT32(dir, NRF51GPIOState),
  243. VMSTATE_UINT32_ARRAY(cnf, NRF51GPIOState, NRF51_GPIO_PINS),
  244. VMSTATE_UINT32(old_out, NRF51GPIOState),
  245. VMSTATE_UINT32(old_out_connected, NRF51GPIOState),
  246. VMSTATE_END_OF_LIST()
  247. }
  248. };
  249. static void nrf51_gpio_init(Object *obj)
  250. {
  251. NRF51GPIOState *s = NRF51_GPIO(obj);
  252. memory_region_init_io(&s->mmio, obj, &gpio_ops, s,
  253. TYPE_NRF51_GPIO, NRF51_GPIO_SIZE);
  254. sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio);
  255. qdev_init_gpio_in(DEVICE(s), nrf51_gpio_set, NRF51_GPIO_PINS);
  256. qdev_init_gpio_out(DEVICE(s), s->output, NRF51_GPIO_PINS);
  257. qdev_init_gpio_out_named(DEVICE(s), &s->detect, "detect", 1);
  258. }
  259. static void nrf51_gpio_class_init(ObjectClass *klass, void *data)
  260. {
  261. DeviceClass *dc = DEVICE_CLASS(klass);
  262. dc->vmsd = &vmstate_nrf51_gpio;
  263. device_class_set_legacy_reset(dc, nrf51_gpio_reset);
  264. dc->desc = "nRF51 GPIO";
  265. }
  266. static const TypeInfo nrf51_gpio_info = {
  267. .name = TYPE_NRF51_GPIO,
  268. .parent = TYPE_SYS_BUS_DEVICE,
  269. .instance_size = sizeof(NRF51GPIOState),
  270. .instance_init = nrf51_gpio_init,
  271. .class_init = nrf51_gpio_class_init
  272. };
  273. static void nrf51_gpio_register_types(void)
  274. {
  275. type_register_static(&nrf51_gpio_info);
  276. }
  277. type_init(nrf51_gpio_register_types)