drv_i2c.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. /*
  2. * Copyright (c) 2019 Winner Microelectronics Co., Ltd.
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2018-11-9 fanwenl 1st version
  9. */
  10. #include <rtdevice.h>
  11. #include <rtthread.h>
  12. #include "board.h"
  13. #include "wm_i2c.h"
  14. #include "wm_io.h"
  15. #include "wm_gpio_afsel.h"
  16. #include "pin_map.h"
  17. #include "drv_i2c.h"
  18. #ifdef BSP_USING_I2C
  19. struct wm_i2c_bus
  20. {
  21. struct rt_i2c_bus_device parent;
  22. struct rt_i2c_msg *msg;
  23. rt_uint32_t msg_cnt;
  24. volatile rt_uint32_t msg_ptr;
  25. volatile rt_uint32_t dptr;
  26. };
  27. static struct wm_i2c_bus wm_i2c;
  28. static rt_size_t wm_i2c_mst_xfer(struct rt_i2c_bus_device *bus,
  29. struct rt_i2c_msg msgs[],
  30. rt_uint32_t num);
  31. static rt_size_t wm_i2c_slv_xfer(struct rt_i2c_bus_device *bus,
  32. struct rt_i2c_msg msgs[],
  33. rt_uint32_t num);
  34. static rt_err_t wm_i2c_bus_control(struct rt_i2c_bus_device *bus,
  35. rt_uint32_t,
  36. rt_uint32_t);
  37. static const struct rt_i2c_bus_device_ops wm_i2c_ops =
  38. {
  39. wm_i2c_mst_xfer,
  40. wm_i2c_slv_xfer,
  41. wm_i2c_bus_control,
  42. };
  43. static rt_err_t wm_i2c_send_address(struct rt_i2c_bus_device *bus,
  44. struct rt_i2c_msg *msg)
  45. {
  46. uint8_t addr_msb, addr_lsb;
  47. if (msg->flags & RT_I2C_ADDR_10BIT)
  48. {
  49. addr_msb = 0xf0 | ((msg->addr >> 7) & 0x06);
  50. addr_lsb = msg->addr & 0xff;
  51. if (msg->flags & RT_I2C_RD)
  52. {
  53. addr_msb |= 0x01;
  54. }
  55. tls_i2c_write_byte(addr_msb, 1);
  56. tls_i2c_wait_ack();
  57. tls_i2c_write_byte(addr_lsb, 0);
  58. tls_i2c_wait_ack();
  59. }
  60. else
  61. {
  62. tls_i2c_write_byte((msg->addr << 1) | msg->flags, 1);
  63. tls_i2c_wait_ack();
  64. }
  65. return RT_EOK;
  66. }
  67. static rt_size_t wm_i2c_mst_xfer(struct rt_i2c_bus_device *bus,
  68. struct rt_i2c_msg msgs[],
  69. rt_uint32_t num)
  70. {
  71. struct wm_i2c_bus *wm_i2c;
  72. rt_size_t i;
  73. RT_ASSERT(bus != RT_NULL);
  74. wm_i2c = (struct wm_i2c_bus *)bus;
  75. wm_i2c->msg = msgs;
  76. wm_i2c->msg_ptr = 0;
  77. wm_i2c->msg_cnt = num;
  78. wm_i2c->dptr = 0;
  79. for (i = 0; i < wm_i2c->msg_cnt; i++)
  80. {
  81. if (!(wm_i2c->msg[i].flags & RT_I2C_NO_START))
  82. {
  83. wm_i2c_send_address(bus, &(wm_i2c->msg[i]));
  84. }
  85. if (wm_i2c->msg[i].flags & RT_I2C_RD)
  86. {
  87. while (wm_i2c->msg[i].len > 1)
  88. {
  89. *wm_i2c->msg[i].buf++ = tls_i2c_read_byte(1, 0);
  90. wm_i2c->msg[i].len--;
  91. }
  92. *wm_i2c->msg[i].buf = tls_i2c_read_byte(0, 0);
  93. }
  94. else
  95. {
  96. while (wm_i2c->msg[i].len > 0)
  97. {
  98. tls_i2c_write_byte(*wm_i2c->msg[i].buf, 0);
  99. tls_i2c_wait_ack();
  100. wm_i2c->msg[i].len--;
  101. wm_i2c->msg[i].buf++;
  102. }
  103. }
  104. }
  105. wm_i2c->msg = RT_NULL;
  106. wm_i2c->msg_ptr = 0;
  107. wm_i2c->msg_cnt = 0;
  108. wm_i2c->dptr = 0;
  109. tls_i2c_stop();
  110. for (int j = 0; j < 3000; j++);
  111. return i;
  112. }
  113. static rt_size_t wm_i2c_slv_xfer(struct rt_i2c_bus_device *bus,
  114. struct rt_i2c_msg msgs[],
  115. rt_uint32_t num)
  116. {
  117. return 0;
  118. }
  119. static rt_err_t wm_i2c_bus_control(struct rt_i2c_bus_device *bus,
  120. rt_uint32_t cmd,
  121. rt_uint32_t arg)
  122. {
  123. return RT_ERROR;
  124. }
  125. void WM_I2C_IRQHandler(void)
  126. {
  127. extern void I2C_IRQHandler(void);
  128. /* enter interrupt */
  129. rt_interrupt_enter();
  130. I2C_IRQHandler();
  131. /* leave interrupt */
  132. rt_interrupt_leave();
  133. }
  134. int wm_hw_i2c_init(void)
  135. {
  136. rt_int16_t gpio_pin;
  137. gpio_pin = wm_get_pin(WM_I2C_SCL_PIN);
  138. if (gpio_pin >= 0)
  139. {
  140. wm_i2c_scl_config((enum tls_io_name)gpio_pin);
  141. }
  142. gpio_pin = wm_get_pin(WM_I2C_DAT_PIN);
  143. if (gpio_pin >= 0)
  144. {
  145. wm_i2c_sda_config((enum tls_io_name)gpio_pin);
  146. }
  147. tls_i2c_init(WM_HW_I2C_FREQ);
  148. wm_i2c.parent.ops = &wm_i2c_ops;
  149. #ifdef WM_I2C_BUS_NAME
  150. rt_i2c_bus_device_register(&wm_i2c.parent, WM_I2C_BUS_NAME);
  151. #else
  152. rt_i2c_bus_device_register(&wm_i2c.parent, "i2c");
  153. #endif
  154. return 0;
  155. }
  156. INIT_DEVICE_EXPORT(wm_hw_i2c_init);
  157. #endif /* BSP_USING_I2C */