drv_i2c.c 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  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-4-1 IceBear003 the first version
  9. */
  10. #include "board.h"
  11. #include "drv_i2c.h"
  12. #ifdef BSP_USING_HWI2C
  13. #define LOG_TAG "drv.hwi2c"
  14. #include "drv_log.h"
  15. #if !defined(BSP_USING_I2C1) && !defined(BSP_USING_I2C2)
  16. #error "Please define at least one BSP_USING_I2Cx"
  17. /* this driver can be disabled at menuconfig -> RT-Thread Components -> Device Drivers */
  18. #endif
  19. #define TIMEOUT 0xFF
  20. #ifdef BSP_USING_I2C1
  21. struct i2c_bus_device i2c_bus1;
  22. #endif
  23. #ifdef BSP_USING_I2C2
  24. struct i2c_bus_device i2c_bus2;
  25. #endif
  26. static int i2c_read(I2C_TypeDef *i2c_periph,
  27. rt_uint16_t addr,
  28. rt_uint8_t flags,
  29. rt_uint16_t len,
  30. rt_uint8_t *buf)
  31. {
  32. rt_uint16_t try = 0;
  33. while (I2C_GetFlagStatus(i2c_periph, I2C_FLAG_BUSY))
  34. if (try++ >= TIMEOUT) return -1;
  35. I2C_GenerateSTART(i2c_periph, ENABLE);
  36. try = 0;
  37. while (!I2C_CheckEvent(i2c_periph, I2C_EVENT_MASTER_MODE_SELECT)) //EVT5
  38. if (try++ >= TIMEOUT) return -1;
  39. if(flags & RT_I2C_ADDR_10BIT) //10-bit address mode
  40. {
  41. rt_uint8_t frame_head = 0xF0 + (addr >> 8) << 1; //11110XX0
  42. I2C_SendData(i2c_periph, frame_head); //FrameHead
  43. try = 0;
  44. while (!I2C_CheckEvent(i2c_periph, I2C_EVENT_MASTER_MODE_ADDRESS10)) //EVT9
  45. if (try++ >= TIMEOUT) return -1;
  46. I2C_SendData(i2c_periph,0xff & addr);
  47. try = 0;
  48. while (!I2C_CheckEvent(i2c_periph, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) //EVT6
  49. if (try++ >= TIMEOUT) return -1;
  50. I2C_GenerateSTART(i2c_periph, ENABLE); //Sr
  51. try = 0;
  52. while (!I2C_CheckEvent(i2c_periph, I2C_EVENT_MASTER_MODE_SELECT)) //EVT5
  53. if (try++ >= TIMEOUT) return -1;
  54. I2C_SendData(i2c_periph,frame_head); //Resend FrameHead
  55. }
  56. else
  57. {
  58. I2C_Send7bitAddress(i2c_periph, addr << 1, I2C_Direction_Receiver);
  59. }
  60. try = 0;
  61. while (!I2C_CheckEvent(i2c_periph, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)) //EVT6
  62. if (try++ >= TIMEOUT) return -1;
  63. while(len-- > 0)
  64. {
  65. try = 0;
  66. while (!I2C_GetFlagStatus(i2c_periph, I2C_FLAG_RXNE)) //Got ACK For the Last Byte
  67. if (try++ >= TIMEOUT) return -1;
  68. *(buf++)=I2C_ReceiveData(i2c_periph);
  69. }
  70. I2C_GenerateSTOP(i2c_periph, ENABLE);
  71. }
  72. static int i2c_write(I2C_TypeDef *i2c_periph,
  73. rt_uint16_t addr,
  74. rt_uint8_t flags,
  75. rt_uint8_t *buf,
  76. rt_uint16_t len)
  77. {
  78. rt_uint16_t try = 0;
  79. while (I2C_GetFlagStatus(i2c_periph, I2C_FLAG_BUSY))
  80. if (try++ >= TIMEOUT) return -1;
  81. I2C_GenerateSTART(i2c_periph, ENABLE);
  82. try = 0;
  83. while (!I2C_CheckEvent(i2c_periph, I2C_EVENT_MASTER_MODE_SELECT)) //EVT5
  84. if (try++ >= TIMEOUT) return -1;
  85. if(flags & RT_I2C_ADDR_10BIT) //10-bit address mode
  86. {
  87. I2C_SendData(i2c_periph,0xF0 + (addr >> 8) << 1); //FrameHead 11110XX0
  88. try = 0;
  89. while (!I2C_CheckEvent(i2c_periph, I2C_EVENT_MASTER_MODE_ADDRESS10)) //EVT9
  90. if (try++ >= TIMEOUT) return -1;
  91. I2C_SendData(i2c_periph,0xff & addr);
  92. }
  93. else //7-bit address mode
  94. {
  95. I2C_Send7bitAddress(i2c_periph, addr << 1, I2C_Direction_Transmitter);
  96. }
  97. try = 0;
  98. while (!I2C_CheckEvent(i2c_periph, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) //EVT6
  99. if (try++ >= TIMEOUT) return -1;
  100. //Missing Evt8_1 (No definition)
  101. while(len-- > 0)
  102. {
  103. try = 0;
  104. while (!I2C_GetFlagStatus(i2c_periph, I2C_FLAG_TXE)) //Got ACK For the Last Byte
  105. if (try++ >= TIMEOUT) return -1;
  106. I2C_SendData(i2c_periph,*(buf++));
  107. }
  108. try = 0;
  109. while(!I2C_CheckEvent(i2c_periph, I2C_EVENT_MASTER_BYTE_TRANSMITTING)) //Last byte sent successfully
  110. if (try++ >= TIMEOUT) return -1;
  111. I2C_GenerateSTOP(i2c_periph, ENABLE);
  112. }
  113. rt_size_t i2c_master_xfer(struct rt_i2c_bus_device *bus,
  114. struct rt_i2c_msg msgs[],
  115. rt_uint32_t num)
  116. {
  117. struct rt_i2c_msg *msg;
  118. struct i2c_bus_device *i2c_bus_dev;
  119. rt_uint32_t index;
  120. i2c_bus_dev = (struct i2c_bus_device *)bus;
  121. for (index = 0; index < num; index++)
  122. {
  123. msg = &msgs[index];
  124. if (msg->flags & RT_I2C_RD)
  125. {
  126. i2c_read(i2c_bus_dev->periph,
  127. msg->addr,
  128. msg->flags,
  129. msg->len,
  130. msg->buf);
  131. }
  132. else
  133. {
  134. i2c_write(i2c_bus_dev->periph,
  135. msg->addr,
  136. msg->flags,
  137. msg->buf,
  138. msg->len);
  139. }
  140. }
  141. return index;
  142. }
  143. static const struct rt_i2c_bus_device_ops ch32_i2c_ops =
  144. {
  145. .master_xfer = i2c_master_xfer,
  146. .slave_xfer = RT_NULL, //Not Used in i2c_core?
  147. .i2c_bus_control = RT_NULL
  148. };
  149. int rt_hw_i2c_init(struct i2c_config *config = &{5000, I2C_DutyCycle_2, 0, I2C_Ack_Disable, I2C_AcknowledgedAddress_7bit})
  150. {
  151. int result = RT_EOK;
  152. GPIO_InitTypeDef GPIO_InitStructure = {0};
  153. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  154. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
  155. I2C_InitTypeDef I2C_InitTSturcture = {0};
  156. I2C_StructInit(&I2C_InitTSturcture);
  157. I2C_InitTSturcture.I2C_ClockSpeed = config->clock_speed;
  158. I2C_InitTSturcture.I2C_DutyCycle = config->duty_cycle;
  159. I2C_InitTSturcture.I2C_OwnAddress1 = config->own_address;
  160. I2C_InitTSturcture.I2C_Ack = config->enable_ack ? I2C_Ack_Enable : I2C_Ack_Disable;
  161. I2C_InitTSturcture.I2C_AcknowledgedAddress = config->is_7_bit_address ? I2C_AcknowledgedAddress_7bit : I2C_AcknowledgedAddress_10bit;
  162. #ifdef BSP_USING_I2C1
  163. i2c_bus1.periph = I2C1;
  164. //Clock & IO Initialization
  165. RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
  166. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);
  167. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9;
  168. GPIO_Init(GPIOB, &GPIO_InitStructure);
  169. GPIO_PinRemapConfig(GPIO_Remap_I2C1, ENABLE);
  170. //I2C Initialization Config
  171. I2C_Init(I2C1, &I2C_InitTSturcture);
  172. I2C_Cmd(I2C1, ENABLE);
  173. //Hook to RT-Thread
  174. i2c_bus1.parent.ops = &ch32_i2c_ops;
  175. result += rt_i2c_bus_device_register(&i2c_bus1.parent, "i2c1");
  176. #endif
  177. #ifdef BSP_USING_I2C2
  178. i2c_bus2.periph = I2C2;
  179. //Clock & IO Initialization
  180. RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);
  181. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);
  182. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11;
  183. GPIO_Init(GPIOB, &GPIO_InitStructure);
  184. //I2C Initialization Config
  185. I2C_Init(I2C2, &I2C_InitTSturcture);
  186. I2C_Cmd(I2C2, ENABLE);
  187. //Hook to RT-Thread
  188. i2c_bus2.parent.ops = &ch32_i2c_ops;
  189. result += rt_i2c_bus_device_register(&i2c_bus2.parent, "i2c2");
  190. #endif
  191. return result;
  192. }
  193. #endif //BSP_USING_HWI2C