/platform/vendor_bsp/nxp/CH-K-Lib/drivers/KL/src/i2c.c

https://github.com/Tencent/TencentOS-tiny · C · 393 lines · 267 code · 56 blank · 70 comment · 15 complexity · 9161e377fd445a45f016fa259547169f MD5 · raw file

  1. /**
  2. ******************************************************************************
  3. * @file i2c.c
  4. * @author YANDLD
  5. * @version V2.6
  6. * @date 2015.06.21
  7. * @brief www.beyondcore.net http://upcmcu.taobao.com
  8. ******************************************************************************
  9. */
  10. #include "i2c.h"
  11. #include "gpio.h"
  12. #include "common.h"
  13. typedef struct
  14. {
  15. uint32_t instace;
  16. uint32_t sda;
  17. uint32_t scl;
  18. }i2c_gpio;
  19. static i2c_gpio i2c;
  20. #define SDA_DDR_OUT() GPIO_SetPinDir(i2c.instace, i2c.sda, 1)
  21. #define SDA_DDR_IN() GPIO_SetPinDir(i2c.instace, i2c.sda, 0)
  22. #define SDA_H() GPIO_PinWrite(i2c.instace, i2c.sda, 1)
  23. #define SDA_L() GPIO_PinWrite(i2c.instace, i2c.sda, 0)
  24. #define SCL_H() GPIO_PinWrite(i2c.instace, i2c.scl, 1)
  25. #define SCL_L() GPIO_PinWrite(i2c.instace, i2c.scl, 0)
  26. #define SDA_IN() GPIO_PinRead(i2c.instace, i2c.sda)
  27. #define I2C_DELAY() __NOP();
  28. uint8_t I2C_Init(uint32_t MAP, uint32_t baudrate)
  29. {
  30. uint8_t i;
  31. map_t * pq = (map_t*)&(MAP);
  32. /* open drain and pull up */
  33. for(i = 0; i < pq->pin_count; i++)
  34. {
  35. GPIO_Init(pq->io, pq->pin_start + i, kGPIO_Mode_OPP);
  36. GPIO_Init(pq->io, pq->pin_start + i, kGPIO_Mode_OPP);
  37. GPIO_PinWrite(pq->io, pq->pin_start + i, 1);
  38. SetPinPull(pq->io, pq->pin_start + i, 1);
  39. }
  40. /* i2c_gpio struct setup */
  41. i2c.instace = pq->io;
  42. switch(MAP)
  43. {
  44. case I2C1_SCL_PE01_SDA_PE00:
  45. i2c.scl = 1;i2c.sda = 0;
  46. break;
  47. case I2C0_SCL_PE19_SDA_PE18:
  48. i2c.scl = 19;i2c.sda = 18;
  49. break;
  50. case I2C0_SCL_PF22_SDA_PF23:
  51. i2c.scl = 22;i2c.sda = 23;
  52. break;
  53. case I2C0_SCL_PB00_SDA_PB01:
  54. i2c.scl = 0;i2c.sda = 1;
  55. break;
  56. case I2C0_SCL_PB02_SDA_PB03:
  57. i2c.scl = 2;i2c.sda = 3;
  58. break;
  59. case I2C1_SCL_PC10_SDA_PC11:
  60. i2c.scl = 10;i2c.sda = 11;
  61. break;
  62. case I2C0_SCL_PD08_SDA_PD09:
  63. i2c.scl = 8;i2c.sda = 9;
  64. break;
  65. case I2C0_SCL_PE24_SDA_PE25:
  66. i2c.scl = 24;i2c.sda = 25;
  67. break;
  68. case I2C1_SCL_PC01_SDA_PC02:
  69. i2c.scl = 1;i2c.sda = 2;
  70. break;
  71. default:
  72. LIB_TRACE("no PINMAP found\r\n");
  73. break;
  74. }
  75. return pq->ip;
  76. }
  77. static bool I2C_Start(void)
  78. {
  79. SDA_DDR_OUT();
  80. SDA_H();
  81. SCL_H();
  82. I2C_DELAY();
  83. SDA_L();
  84. I2C_DELAY();
  85. SCL_L();
  86. return true;
  87. }
  88. static void I2C_Stop(void)
  89. {
  90. SCL_L();
  91. SDA_L();
  92. I2C_DELAY();
  93. SCL_H();
  94. SDA_H();
  95. I2C_DELAY();
  96. }
  97. static void I2C_Ack(void)
  98. {
  99. SCL_L();
  100. SDA_L();
  101. I2C_DELAY();
  102. SCL_H();
  103. I2C_DELAY();
  104. SCL_L();
  105. I2C_DELAY();
  106. }
  107. static void I2C_NAck(void)
  108. {
  109. SCL_L();
  110. I2C_DELAY();
  111. SDA_H();
  112. I2C_DELAY();
  113. SCL_H();
  114. I2C_DELAY();
  115. SCL_L();
  116. I2C_DELAY();
  117. }
  118. static bool I2C_WaitAck(void)
  119. {
  120. uint8_t ack;
  121. SDA_DDR_IN();
  122. SCL_L();
  123. I2C_DELAY();
  124. SCL_H();
  125. I2C_DELAY();
  126. ack = SDA_IN();
  127. SCL_L();
  128. SDA_DDR_OUT();
  129. return ack;
  130. }
  131. static void I2C_SendByte(uint8_t data)
  132. {
  133. volatile uint8_t i;
  134. i = 8;
  135. while(i--)
  136. {
  137. if(data & 0x80) SDA_H();
  138. else SDA_L();
  139. data <<= 1;
  140. I2C_DELAY();
  141. SCL_H();
  142. I2C_DELAY();
  143. SCL_L();
  144. }
  145. }
  146. static uint8_t I2C_GetByte(void)
  147. {
  148. uint8_t i,byte;
  149. i = 8;
  150. byte = 0;
  151. SDA_DDR_IN();
  152. while(i--)
  153. {
  154. SCL_L();
  155. I2C_DELAY();
  156. SCL_H();
  157. I2C_DELAY();
  158. byte = (byte<<1)|(SDA_IN() & 1);
  159. }
  160. SCL_L();
  161. SDA_DDR_OUT();
  162. return byte;
  163. }
  164. /**
  165. * @brief I2C write mutiple data
  166. * @param instance: instance of i2c moudle
  167. * @arg chipAddr : i2c slave addr
  168. * @arg addr : i2c slave register offset
  169. * @arg addrLen : len of slave register addr(in byte)
  170. * @arg buf : data buf
  171. * @arg buf : read len
  172. * @note
  173. */
  174. uint8_t I2C_BurstWrite(uint32_t instance ,uint8_t chipAddr, uint32_t addr, uint32_t addrLen, uint8_t *buf, uint32_t len)
  175. {
  176. uint8_t *p;
  177. uint8_t err;
  178. p = (uint8_t*)&addr;
  179. err = 0;
  180. chipAddr <<= 1;
  181. I2C_Start();
  182. I2C_SendByte(chipAddr);
  183. err += I2C_WaitAck();
  184. while(addrLen--)
  185. {
  186. I2C_SendByte(*p++);
  187. err += I2C_WaitAck();
  188. }
  189. while(len--)
  190. {
  191. I2C_SendByte(*buf++);
  192. err += I2C_WaitAck();
  193. }
  194. I2C_Stop();
  195. return err;
  196. }
  197. /**
  198. * @brief write single register value
  199. * @param instance: instance of i2c moudle
  200. * @arg chipAddr : i2c slave addr
  201. * @arg addr : i2c slave register offset
  202. * @arg buf : data pointer
  203. * @note usually used on i2c sensor devices
  204. */
  205. uint8_t I2C_WriteSingleRegister(uint32_t instance, uint8_t chipAddr, uint8_t addr, uint8_t data)
  206. {
  207. return I2C_BurstWrite(instance, chipAddr, addr, 1, &data, 1);
  208. }
  209. /**
  210. * @brief I2C read mutiple data
  211. * @param instance: instance of i2c moudle
  212. * @arg chipAddr : i2c slave addr
  213. * @arg addr : i2c slave register offset
  214. * @arg addrLen : len of slave register addr(in byte)
  215. * @arg buf : data buf
  216. * @arg buf : read len
  217. * @note
  218. */
  219. int32_t I2C_BurstRead(uint32_t instance ,uint8_t chipAddr, uint32_t addr, uint32_t addrLen, uint8_t *buf, uint32_t len)
  220. {
  221. uint8_t *p;
  222. uint8_t err;
  223. p = (uint8_t*)&addr;
  224. err = 0;
  225. chipAddr <<= 1;
  226. I2C_Start();
  227. I2C_SendByte(chipAddr);
  228. err += I2C_WaitAck();
  229. while(addrLen--)
  230. {
  231. I2C_SendByte(*p++);
  232. err += I2C_WaitAck();
  233. }
  234. I2C_Start();
  235. I2C_SendByte(chipAddr+1);
  236. err += I2C_WaitAck();
  237. while(len--)
  238. {
  239. *buf++ = I2C_GetByte();
  240. if(len)
  241. {
  242. I2C_Ack();
  243. }
  244. }
  245. I2C_NAck();
  246. I2C_Stop();
  247. return err;
  248. }
  249. /**
  250. * @brief proble i2c bus
  251. * @param instance: instance of i2c moudle
  252. * @arg chipAddr : i2c slave addr
  253. * @note see if it's available i2c slave on the bus
  254. */
  255. uint8_t I2C_Probe(uint32_t instance, uint8_t chipAddr)
  256. {
  257. uint8_t err;
  258. err = 0;
  259. chipAddr <<= 1;
  260. I2C_Start();
  261. I2C_SendByte(chipAddr);
  262. err = I2C_WaitAck();
  263. I2C_Stop();
  264. return err;
  265. }
  266. /**
  267. * @brief read single register value
  268. * @param instance: instance of i2c moudle
  269. * @arg chipAddr : i2c slave addr
  270. * @arg addr : i2c slave register offset
  271. * @arg buf : data pointer
  272. * @note usually used on i2c sensor devices
  273. */
  274. uint8_t I2C_ReadSingleRegister(uint32_t instance, uint8_t chipAddr, uint8_t addr, uint8_t* buf)
  275. {
  276. return I2C_BurstRead(instance, chipAddr, addr, 1, buf, 1);
  277. }
  278. /**
  279. * @brief read single register value(SCCB)
  280. * @param instance: instance of i2c moudle
  281. * @arg chipAddr : i2c slave addr
  282. * @arg addr : i2c slave register offset
  283. * @arg buf : data pointer
  284. * @note usually used on i2c sensor devices
  285. */
  286. int SCCB_ReadSingleRegister(uint32_t instance, uint8_t chipAddr, uint8_t addr, uint8_t* buf)
  287. {
  288. uint8_t err;
  289. uint8_t retry;
  290. retry = 10;
  291. chipAddr <<= 1;
  292. while(retry--)
  293. {
  294. err = 0;
  295. I2C_Start();
  296. I2C_SendByte(chipAddr);
  297. err += I2C_WaitAck();
  298. I2C_SendByte(addr);
  299. err += I2C_WaitAck();
  300. I2C_Stop();
  301. I2C_Start();
  302. I2C_SendByte(chipAddr+1);
  303. err += I2C_WaitAck();
  304. *buf = I2C_GetByte();
  305. // err += I2C_WaitAck();
  306. I2C_NAck();
  307. I2C_Stop();
  308. if(!err)
  309. {
  310. break;
  311. }
  312. }
  313. return err;
  314. }
  315. /**
  316. * @brief write single register value(SCCB)
  317. * @param instance: instance of i2c moudle
  318. * @arg chipAddr : i2c slave addr
  319. * @arg addr : i2c slave register offset
  320. * @arg buf : data pointer
  321. * @note usually used on i2c sensor devices
  322. */
  323. int SCCB_WriteSingleRegister(uint32_t instance, uint8_t chipAddr, uint8_t addr, uint8_t data)
  324. {
  325. uint8_t err;
  326. uint8_t retry;
  327. retry = 10;
  328. while(retry--)
  329. {
  330. err = I2C_WriteSingleRegister(instance, chipAddr, addr, data);
  331. if(!err)
  332. {
  333. break;
  334. }
  335. }
  336. return err;
  337. }