/platform/mcu/mx1101/sdk/O18B_SDK_GCC/MVs_new/MVs18_SDK/src/fm_driver/i2c.c

https://github.com/alibaba/AliOS-Things · C · 458 lines · 294 code · 57 blank · 107 comment · 28 complexity · 9fb137cb944b3a4471c91a23c2aad51a MD5 · raw file

  1. /**
  2. *************************************************************************************
  3. * @file i2c.c
  4. * @author Yancy
  5. * @version v1.0.0
  6. * @date 2013/05/29
  7. * @brief software I2C driver
  8. * @ maintainer: YunWang
  9. * Copyright (C) Shanghai Mountain View Silicon Technology Co.,Ltd. All rights reserved.
  10. *************************************************************************************
  11. */
  12. #include <string.h>
  13. #include "type.h"
  14. #include "app_config.h"
  15. #include "aos/hal/gpio.h"
  16. #include "aos/hal/i2c.h"
  17. #define MAX_I2C_MASTER 2
  18. typedef struct
  19. {
  20. uint32_t SdaMask;
  21. uint32_t SclMask;
  22. uint8_t SdaPortIndex;
  23. uint8_t SclPortIndex;
  24. bool IsUsed;
  25. } I2C_INFO, *I2C_HANDLE;
  26. I2C_INFO I2cInfo[MAX_I2C_MASTER];
  27. /**
  28. * I2C Read/Write Flag
  29. */
  30. #define IIC_READ 0x01 /*!< Read flag in I2C slave address. */
  31. #define IIC_WRITE 0x00 /*!< Write flag in I2C slave address. */
  32. #define I2C_Delay() __udelay(5) /**< SCL/SDA hold time*/
  33. /**
  34. * SCL Manipulation
  35. */
  36. void SetOutputSCL(void* I2cMasterHandle)
  37. {
  38. I2C_HANDLE I2cHandle = (I2C_HANDLE)I2cMasterHandle;
  39. GpioSetRegOneBit(I2cHandle->SclPortIndex + 3, I2cHandle->SclMask);
  40. }
  41. void SetSCL(void* I2cMasterHandle)
  42. {
  43. I2C_HANDLE I2cHandle = (I2C_HANDLE)I2cMasterHandle;
  44. GpioSetRegOneBit(I2cHandle->SclPortIndex + 1, I2cHandle->SclMask);
  45. I2C_Delay();
  46. }
  47. void ClrSCL(void* I2cMasterHandle)
  48. {
  49. I2C_HANDLE I2cHandle = (I2C_HANDLE)I2cMasterHandle;
  50. GpioClrRegOneBit(I2cHandle->SclPortIndex + 1, I2cHandle->SclMask);
  51. I2C_Delay();
  52. }
  53. /**
  54. * SDA Manipulation
  55. */
  56. void SetOutputSDA(void* I2cMasterHandle)
  57. {
  58. I2C_HANDLE I2cHandle = (I2C_HANDLE)I2cMasterHandle;
  59. GpioSetRegOneBit(I2cHandle->SdaPortIndex + 3, I2cHandle->SdaMask);
  60. }
  61. void SetSDA(void* I2cMasterHandle)
  62. {
  63. I2C_HANDLE I2cHandle = (I2C_HANDLE)I2cMasterHandle;
  64. GpioSetRegOneBit(I2cHandle->SdaPortIndex + 1, I2cHandle->SdaMask);
  65. I2C_Delay();
  66. }
  67. void ClrSDA(void* I2cMasterHandle)
  68. {
  69. I2C_HANDLE I2cHandle = (I2C_HANDLE)I2cMasterHandle;
  70. GpioClrRegOneBit(I2cHandle->SdaPortIndex + 1, I2cHandle->SdaMask);
  71. I2C_Delay();
  72. }
  73. void SetInputSDA(void* I2cMasterHandle)
  74. {
  75. I2C_HANDLE I2cHandle = (I2C_HANDLE)I2cMasterHandle;
  76. GpioClrRegOneBit(I2cHandle->SdaPortIndex + 3, I2cHandle->SdaMask);
  77. }
  78. uint8_t GetSDA(void* I2cMasterHandle)
  79. {
  80. I2C_HANDLE I2cHandle = (I2C_HANDLE)I2cMasterHandle;
  81. uint32_t Val = GpioGetReg(I2cHandle->SdaPortIndex);
  82. if(Val & I2cHandle->SdaMask)
  83. {
  84. return 1;
  85. }
  86. else
  87. {
  88. return 0;
  89. }
  90. }
  91. static I2cInfoInit(void)
  92. {
  93. static uint8_t I2cInfoInitFlag = FALSE;
  94. if(!I2cInfoInitFlag)
  95. {
  96. memset(I2cInfo, 0, sizeof(I2cInfo));
  97. I2cInfoInitFlag = TRUE;
  98. }
  99. }
  100. /**
  101. * @brief This function create an I2C object.
  102. * @param None
  103. * @return None
  104. */
  105. void* I2cMasterCreate(PORT_SEL SclPortSel, uint8_t SclIndex, PORT_SEL SdaPortSel, uint8_t SdaIndex)
  106. {
  107. uint8_t i;
  108. I2cInfoInit();
  109. for(i = 0; i < MAX_I2C_MASTER; i++)
  110. {
  111. if(I2cInfo[i].IsUsed == FALSE)
  112. {
  113. switch(SdaPortSel)
  114. {
  115. case PORT_A:
  116. I2cInfo[i].SdaPortIndex = GPIO_A_IN;
  117. break;
  118. case PORT_B:
  119. I2cInfo[i].SdaPortIndex = GPIO_B_IN;
  120. break;
  121. case PORT_C:
  122. I2cInfo[i].SdaPortIndex = GPIO_C_IN;
  123. break;
  124. default:
  125. return NULL;
  126. }
  127. switch(SclPortSel)
  128. {
  129. case PORT_A:
  130. I2cInfo[i].SclPortIndex = GPIO_A_IN;
  131. break;
  132. case PORT_B:
  133. I2cInfo[i].SclPortIndex = GPIO_B_IN;
  134. break;
  135. case PORT_C:
  136. I2cInfo[i].SclPortIndex = GPIO_C_IN;
  137. break;
  138. default:
  139. return NULL;
  140. }
  141. I2cInfo[i].SdaMask = 1 << SdaIndex;
  142. I2cInfo[i].SclMask = 1 << SclIndex;
  143. I2cInfo[i].IsUsed = TRUE;
  144. return (void*)&I2cInfo[i];
  145. }
  146. }
  147. return NULL;
  148. }
  149. /**
  150. * @brief This function validate an I2C object.
  151. * @param None
  152. * @return None
  153. */
  154. bool ValidateI2cHandle(void* I2cMasterHandle)
  155. {
  156. uint8_t i;
  157. for(i = 0; i < MAX_I2C_MASTER; i++)
  158. {
  159. void* h = (void*)&I2cInfo[i];
  160. if(h == I2cMasterHandle)
  161. {
  162. return TRUE;
  163. }
  164. }
  165. return FALSE;
  166. }
  167. /**
  168. * @brief This function generates I2C start timing.
  169. * @param None
  170. * @return None
  171. */
  172. void I2cStart(void* I2cMasterHandle)
  173. {
  174. SetSDA(I2cMasterHandle);
  175. SetSCL(I2cMasterHandle);
  176. SetOutputSCL(I2cMasterHandle);
  177. SetOutputSDA(I2cMasterHandle);
  178. ClrSDA(I2cMasterHandle);
  179. ClrSCL(I2cMasterHandle);
  180. }
  181. /**
  182. * @brief This function generates I2C stop timing.
  183. * @param None
  184. * @return None
  185. */
  186. void I2cStop(void* I2cMasterHandle)
  187. {
  188. SetOutputSCL(I2cMasterHandle);
  189. SetOutputSDA(I2cMasterHandle);
  190. ClrSDA(I2cMasterHandle);
  191. SetSCL(I2cMasterHandle);
  192. SetSDA(I2cMasterHandle);
  193. SetInputSDA(I2cMasterHandle);
  194. }
  195. /**
  196. * @brief This function send ACK to I2C slave.
  197. * @param None
  198. * @return None
  199. */
  200. void I2cSendAck(void* I2cMasterHandle)
  201. {
  202. ClrSDA(I2cMasterHandle);
  203. SetSCL(I2cMasterHandle);
  204. ClrSCL(I2cMasterHandle);
  205. }
  206. /**
  207. * @brief This function send NACK to I2C slave.
  208. * @param None
  209. * @return None
  210. */
  211. void I2cSendNoAck(void* I2cMasterHandle)
  212. {
  213. SetSDA(I2cMasterHandle);
  214. SetSCL(I2cMasterHandle);
  215. ClrSCL(I2cMasterHandle);
  216. }
  217. /**
  218. * @brief This function checks ACK/NACK from I2C slave.
  219. * @param None
  220. * @return None
  221. */
  222. bool I2cChkAck(void* I2cMasterHandle)
  223. {
  224. bool Ack;
  225. SetInputSDA(I2cMasterHandle);//Allow slave to send ACK
  226. ClrSCL(I2cMasterHandle);//slave send ACK
  227. SetSCL(I2cMasterHandle);
  228. Ack = !GetSDA(I2cMasterHandle);//Get ACK from slave
  229. ClrSCL(I2cMasterHandle);
  230. return Ack;
  231. }
  232. /**
  233. * @brief This function send one byte to I2C slave.
  234. * @param Val: data to be sent
  235. * @return
  236. * @arg True: Receive ACK from I2C slave
  237. * @arg False: Not receive ACK from I2C slave
  238. */
  239. bool I2cWriteByte(void* I2cMasterHandle, uint8_t Val)
  240. {
  241. uint8_t i = 8;
  242. SetOutputSDA(I2cMasterHandle);
  243. ClrSCL(I2cMasterHandle);
  244. while(i--)
  245. {
  246. if(Val & 0x80) /* MSB output first */
  247. {
  248. SetSDA(I2cMasterHandle);
  249. }
  250. else
  251. {
  252. ClrSDA(I2cMasterHandle);
  253. }
  254. Val <<= 1;
  255. SetSCL(I2cMasterHandle);
  256. ClrSCL(I2cMasterHandle);
  257. }
  258. return I2cChkAck(I2cMasterHandle);
  259. }
  260. /**
  261. * @brief This function recieve one byte from I2C slave.
  262. * @param none
  263. * @return Data received from I2C slave
  264. */
  265. uint8_t I2cReadByte(void* I2cMasterHandle)
  266. {
  267. uint8_t i = 8;
  268. uint8_t Dat = 0;
  269. SetInputSDA(I2cMasterHandle);
  270. while(i--)
  271. {
  272. SetSCL(I2cMasterHandle);
  273. Dat <<= 1;
  274. if(GetSDA(I2cMasterHandle))
  275. {
  276. Dat |= 0x01;
  277. }
  278. ClrSCL(I2cMasterHandle);
  279. }
  280. SetOutputSDA(I2cMasterHandle);
  281. return Dat;
  282. }
  283. /**
  284. * @brief This function send multiple bytes to I2C slave.
  285. * @param Buf: Buffer pointer to the data to be send
  286. * @param Len: Data Length to be send in byte uint
  287. * @return
  288. * @arg TRUE: success
  289. * @arg FALSE: fail
  290. */
  291. bool I2cWriteBytes(void* I2cMasterHandle, uint8_t* Buf, uint8_t Len)
  292. {
  293. while(Len--)
  294. {
  295. if(!I2cWriteByte(I2cMasterHandle, *(Buf++)))
  296. {
  297. DBG("write data err\n");
  298. return FALSE;
  299. }
  300. }
  301. return TRUE;
  302. }
  303. /**
  304. * @brief This function receive multiple bytes to I2C slave.
  305. * @param Buf: Buffer pointer to hold the received data.
  306. * @param Len: Data Length to be received
  307. * @return None
  308. */
  309. void I2cReadBytes(void* I2cMasterHandle, uint8_t* Buf, uint8_t Len)
  310. {
  311. while(Len--)
  312. {
  313. *(Buf++) = I2cReadByte(I2cMasterHandle);
  314. if(Len == 0)
  315. {
  316. I2cSendNoAck(I2cMasterHandle);
  317. }
  318. else
  319. {
  320. I2cSendAck(I2cMasterHandle);
  321. }
  322. }
  323. }
  324. /**
  325. * @brief This function send device address and register address to I2C slave.
  326. * @param DeviceAddr: I2C slave address
  327. * @param RegAddr: slave device's register address, usually before read/write slave device's register,
  328. * i2c master should first send it.
  329. * @return
  330. * @arg TRUE: success
  331. * @arg FALSE:fail
  332. */
  333. bool I2cSendAddr(void* I2cMasterHandle, uint8_t SlaveAddr, uint8_t RegAddr, uint8_t RwFlag)
  334. {
  335. I2cStart(I2cMasterHandle);
  336. if(!I2cWriteByte(I2cMasterHandle, SlaveAddr))
  337. {
  338. /* Retry */
  339. I2cStart(I2cMasterHandle);
  340. if(!I2cWriteByte(I2cMasterHandle, SlaveAddr))
  341. {
  342. I2cStop(I2cMasterHandle);
  343. return FALSE;
  344. }
  345. }
  346. if(!I2cWriteByte(I2cMasterHandle, RegAddr))
  347. {
  348. I2cStop(I2cMasterHandle);
  349. return FALSE;
  350. }
  351. if(RwFlag == IIC_READ)
  352. {
  353. I2cStart(I2cMasterHandle);
  354. if(!I2cWriteByte(I2cMasterHandle, SlaveAddr | IIC_READ))
  355. {
  356. I2cStop(I2cMasterHandle);
  357. return FALSE;
  358. }
  359. }
  360. return TRUE;
  361. }
  362. /**
  363. * @brief This function send multiple bytes to I2C slave with address
  364. * @param Buf: Buffer pointer to the data to be send
  365. * @param Len: Data Length to be send in byte uint
  366. * @return
  367. * @arg TRUE: success
  368. * @arg FALSE:fail
  369. */
  370. bool I2cWriteNByte(void* I2cMasterHandle, uint8_t SlaveAddr, uint8_t RegAddr, uint8_t* Buf, uint8_t Len)
  371. {
  372. if(I2cSendAddr(I2cMasterHandle, SlaveAddr, RegAddr, IIC_WRITE))
  373. {
  374. if(I2cWriteBytes(I2cMasterHandle, Buf, Len))
  375. {
  376. I2cStop(I2cMasterHandle);
  377. return TRUE;
  378. }
  379. }
  380. I2cStop(I2cMasterHandle);
  381. return FALSE;
  382. }
  383. /**
  384. * @brief This function read multiple bytes to I2C slave with address
  385. * @param Buf: Buffer pointer to the data to be send
  386. * @param Len: Data Length to be send in byte uint
  387. * @return
  388. * @arg TRUE: success
  389. * @arg FALSE: fail
  390. */
  391. bool I2cReadNByte(void* I2cMasterHandle, uint8_t SlaveAddr, uint8_t RegAddr, uint8_t* Buf, uint8_t Len)
  392. {
  393. if(I2cSendAddr(I2cMasterHandle, SlaveAddr, RegAddr, IIC_READ))
  394. {
  395. I2cReadBytes(I2cMasterHandle, Buf, Len);
  396. I2cStop(I2cMasterHandle);
  397. return TRUE;
  398. }
  399. I2cStop(I2cMasterHandle);
  400. return FALSE;
  401. }