drv_i2c.c 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. /*
  2. * Copyright (c) 2006-2024, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2024-01-20 wirano first version
  9. */
  10. #include <rtthread.h>
  11. #include <rtdevice.h>
  12. #include <rtdbg.h>
  13. #ifdef BSP_USING_I2C
  14. #if defined(BSP_USING_I2C0) || defined(BSP_USING_I2C1) || defined(BSP_USING_I2C2) || defined(BSP_USING_I2C3)
  15. #include "drv_i2c.h"
  16. #include "inc/hw_memmap.h"
  17. #include "i2c_config.h"
  18. enum {
  19. #ifdef BSP_USING_I2C0
  20. I2C0_INDEX,
  21. #endif
  22. #ifdef BSP_USING_I2C1
  23. I2C1_INDEX,
  24. #endif
  25. #ifdef BSP_USING_I2C2
  26. I2C2_INDEX,
  27. #endif
  28. #ifdef BSP_USING_I2C3
  29. I2C3_INDEX,
  30. #endif
  31. };
  32. static struct tm4c123_i2c tm4c123_i2cs[] =
  33. {
  34. #ifdef BSP_USING_I2C0
  35. I2C0_BUS_CONFIG,
  36. #endif
  37. #ifdef BSP_USING_I2C1
  38. I2C1_BUS_CONFIG,
  39. #endif
  40. #ifdef BSP_USING_I2C2
  41. I2C2_BUS_CONFIG,
  42. #endif
  43. #ifdef BSP_USING_I2C3
  44. I2C3_BUS_CONFIG,
  45. #endif
  46. };
  47. static rt_ssize_t tm4c123_i2c_xfer(struct rt_i2c_bus_device *bus, struct rt_i2c_msg msgs[], rt_uint32_t num);
  48. struct rt_i2c_bus_device_ops tm4c123_i2c_ops =
  49. {
  50. tm4c123_i2c_xfer,
  51. RT_NULL,
  52. RT_NULL
  53. };
  54. static rt_ssize_t tm4c123_i2c_xfer(struct rt_i2c_bus_device *bus, struct rt_i2c_msg msgs[], rt_uint32_t num) {
  55. RT_ASSERT(bus != RT_NULL);
  56. RT_ASSERT(msgs != RT_NULL);
  57. struct rt_i2c_msg *msg;
  58. struct tm4c123_i2c *i2c_info = (struct tm4c123_i2c *) bus;
  59. rt_err_t ret = -RT_ERROR;
  60. rt_uint32_t i;
  61. for (i = 0; i < num; i++) {
  62. msg = &msgs[i];
  63. if (msg->flags & RT_I2C_ADDR_10BIT) {
  64. LOG_E("does not support 10bits address!\n");
  65. }
  66. if (msg->flags & RT_I2C_RD) {
  67. rt_uint8_t *data = msg->buf;
  68. ROM_I2CMasterSlaveAddrSet(i2c_info->base, msg->addr, true);
  69. if (msg->flags & RT_I2C_NO_START) {
  70. ROM_I2CMasterControl(i2c_info->base, I2C_MASTER_CMD_BURST_RECEIVE_CONT);
  71. while (ROM_I2CMasterBusy(i2c_info->base));
  72. *data = ROM_I2CMasterDataGet(i2c_info->base);
  73. } else {
  74. ROM_I2CMasterControl(i2c_info->base, I2C_MASTER_CMD_BURST_RECEIVE_START);
  75. while (ROM_I2CMasterBusy(i2c_info->base));
  76. *data = ROM_I2CMasterDataGet(i2c_info->base);
  77. }
  78. if (msg->len > 1) {
  79. data++;
  80. for (int j = 1; j < msg->len - 1; ++j) {
  81. ROM_I2CMasterControl(i2c_info->base, I2C_MASTER_CMD_BURST_RECEIVE_CONT);
  82. while (ROM_I2CMasterBusy(i2c_info->base));
  83. *data = ROM_I2CMasterDataGet(i2c_info->base);
  84. data++;
  85. }
  86. if (msg->flags & RT_I2C_NO_STOP) {
  87. ROM_I2CMasterControl(i2c_info->base, I2C_MASTER_CMD_BURST_RECEIVE_CONT);
  88. while (ROM_I2CMasterBusy(i2c_info->base));
  89. *data = ROM_I2CMasterDataGet(i2c_info->base);
  90. } else {
  91. ROM_I2CMasterControl(i2c_info->base, I2C_MASTER_CMD_BURST_RECEIVE_FINISH);
  92. while (ROM_I2CMasterBusy(i2c_info->base));
  93. *data = ROM_I2CMasterDataGet(i2c_info->base);
  94. }
  95. }
  96. } else {
  97. rt_uint8_t *data = msg->buf;
  98. ROM_I2CMasterSlaveAddrSet(i2c_info->base, msg->addr, false);
  99. // use single send when data len = 1
  100. if (msg->len == 1) {
  101. if (msg->flags & RT_I2C_NO_START) {
  102. ROM_I2CMasterDataPut(i2c_info->base, *data);
  103. ROM_I2CMasterControl(i2c_info->base, I2C_MASTER_CMD_BURST_SEND_CONT);
  104. } else if (msg->flags & RT_I2C_NO_STOP) {
  105. ROM_I2CMasterDataPut(i2c_info->base, *data);
  106. ROM_I2CMasterControl(i2c_info->base, I2C_MASTER_CMD_BURST_SEND_CONT);
  107. } else {
  108. ROM_I2CMasterControl(i2c_info->base, I2C_MASTER_CMD_SINGLE_SEND);
  109. ROM_I2CMasterDataPut(i2c_info->base, *data);
  110. }
  111. while (ROM_I2CMasterBusy(i2c_info->base));
  112. // otherwise use burst send
  113. } else {
  114. if (msg->flags & RT_I2C_NO_START) {
  115. ROM_I2CMasterDataPut(i2c_info->base, *data);
  116. ROM_I2CMasterControl(i2c_info->base, I2C_MASTER_CMD_BURST_SEND_CONT);
  117. while (ROM_I2CMasterBusy(i2c_info->base));
  118. } else {
  119. ROM_I2CMasterDataPut(i2c_info->base, *data);
  120. ROM_I2CMasterControl(i2c_info->base, I2C_MASTER_CMD_BURST_SEND_START);
  121. while (ROM_I2CMasterBusy(i2c_info->base));
  122. }
  123. data++;
  124. for (int j = 1; j < msg->len - 1; ++j) {
  125. ROM_I2CMasterDataPut(i2c_info->base, *data);
  126. ROM_I2CMasterControl(i2c_info->base, I2C_MASTER_CMD_BURST_SEND_CONT);
  127. while (ROM_I2CMasterBusy(i2c_info->base));
  128. data++;
  129. }
  130. if (msg->flags & RT_I2C_NO_STOP) {
  131. ROM_I2CMasterDataPut(i2c_info->base, *data);
  132. ROM_I2CMasterControl(i2c_info->base, I2C_MASTER_CMD_BURST_SEND_CONT);
  133. } else {
  134. ROM_I2CMasterDataPut(i2c_info->base, *data);
  135. ROM_I2CMasterControl(i2c_info->base, I2C_MASTER_CMD_BURST_SEND_FINISH);
  136. }
  137. while (ROM_I2CMasterBusy(i2c_info->base));
  138. }
  139. }
  140. }
  141. ret = i;
  142. return ret;
  143. }
  144. int rt_hw_i2c_init(void) {
  145. rt_err_t ret = RT_EOK;
  146. i2c_hw_config();
  147. for (uint32_t i = 0; i < sizeof(tm4c123_i2cs) / sizeof(tm4c123_i2cs[0]); i++) {
  148. if (tm4c123_i2cs[i].clk_freq == 400000) {
  149. ROM_I2CMasterInitExpClk(tm4c123_i2cs[i].base, ROM_SysCtlClockGet(), RT_TRUE);
  150. } else {
  151. ROM_I2CMasterInitExpClk(tm4c123_i2cs[i].base, ROM_SysCtlClockGet(), RT_FALSE);
  152. }
  153. ROM_I2CMasterEnable(tm4c123_i2cs[i].base);
  154. tm4c123_i2cs[i].bus.ops = &tm4c123_i2c_ops;
  155. ret = rt_i2c_bus_device_register(&tm4c123_i2cs[i].bus, tm4c123_i2cs[i].bus_name);
  156. if (ret != RT_EOK) {
  157. LOG_E("rt i2c device %s register failed, status=%d\n", tm4c123_i2cs[i].bus_name, ret);
  158. }
  159. }
  160. return ret;
  161. }
  162. INIT_DEVICE_EXPORT(rt_hw_i2c_init);
  163. #endif /* BSP_USING_I2C1 || BSP_USING_I2C2 || BSP_USING_I2C3 || BSP_USING_I2C4 */
  164. #endif /* BSP_USING_I2C */