i2c.c 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
  1. /**
  2. * @file i2c.c
  3. * @author chipsea
  4. * @brief
  5. * @version 0.1
  6. * @date 2020-11-30
  7. * @copyright Copyright (c) 2020, CHIPSEA Co., Ltd.
  8. * @note
  9. */
  10. /*******************************************************************************
  11. * @file i2c.c
  12. * @brief Contains all functions support for i2c driver
  13. * @version 0.0
  14. * @date 25. Oct. 2017
  15. * @author qing.han
  16. *
  17. *
  18. *******************************************************************************/
  19. /*******************************************************************************
  20. *@ Module : pre-compiler
  21. *@ Description : NULL
  22. *******************************************************************************/
  23. #define _I2C_CMD_
  24. /*******************************************************************************
  25. *@ Module : Includes
  26. *@ Description : None
  27. *******************************************************************************/
  28. #include "rom_sym_def.h"
  29. #include "types.h"
  30. #include "gpio.h"
  31. #include "i2c.h"
  32. #include "clock.h"
  33. #include "log.h"
  34. #include "error.h"
  35. #include "OSAL.h"
  36. #include "pwrmgr.h"
  37. #define I2C_OP_TIMEOUT 100 //100ms for an Byte operation
  38. extern uint32_t pclk;
  39. /**************************************************************************************
  40. * @fn hal_master_send_read_cmd
  41. *
  42. * @brief This function process for master send read command;It's vaild when the chip act as master
  43. *
  44. * input parameters
  45. *
  46. * @param uint8_t len: read length
  47. *
  48. * output parameters
  49. *
  50. * @param None.
  51. *
  52. * @return None.
  53. **************************************************************************************/
  54. static void hal_master_send_read_cmd(void* pi2c, uint8_t len){
  55. uint8_t i;
  56. AP_I2C_TypeDef * pi2cdev = (AP_I2C_TypeDef *)pi2c;
  57. for(i=0;i<len;i++){
  58. I2C_READ_CMD(pi2cdev);
  59. }
  60. }
  61. static void _hal_i2c_send_byte(void* pi2c, uint8_t data)
  62. {
  63. AP_I2C_TypeDef * pi2cdev = (AP_I2C_TypeDef *)pi2c;
  64. pi2cdev->IC_DATA_CMD = data; //data
  65. }
  66. /**************************************************************************************
  67. * @fn hal_i2c_send
  68. *
  69. * @brief This function process for send a serial(programe length) data by i2c interface
  70. *
  71. * input parameters
  72. *
  73. * @param unsigned char* str: send data(string)
  74. * uint32_t len: send length
  75. *
  76. * output parameters
  77. *
  78. * @param None.
  79. *
  80. * @return None.
  81. **************************************************************************************/
  82. int hal_i2c_send(void* pi2c, uint8_t* str,uint8_t len)
  83. {
  84. uint8_t i;
  85. AP_I2C_TypeDef * pi2cdev = (AP_I2C_TypeDef *)pi2c;
  86. if(pi2cdev != AP_I2C0 && pi2cdev != AP_I2C1){
  87. return ERR_INVALID_PARAM;
  88. }
  89. for(i=0;i<len;i++){
  90. _hal_i2c_send_byte(pi2c, str[i]);
  91. }
  92. return SUCCESS;
  93. }
  94. int hal_i2c_wait_tx_completed(void* pi2c)
  95. {
  96. int cnt = 0;
  97. //uint32 st0, st;
  98. AP_I2C_TypeDef * pi2cdev = (AP_I2C_TypeDef *)pi2c;
  99. I2C_INIT_TOUT(to);
  100. if(pi2cdev != AP_I2C0 && pi2cdev != AP_I2C1){
  101. return ERR_INVALID_PARAM;
  102. }
  103. //st0 = pi2cdev->IC_INTR_STAT;
  104. //st = pi2cdev->IC_RAW_INTR_STAT;
  105. while(1){
  106. cnt++;
  107. if(pi2cdev->IC_RAW_INTR_STAT&0x200)//check tx empty
  108. break;
  109. I2C_CHECK_TOUT(to, I2C_OP_TIMEOUT, "hal_i2c_wait_tx_completed TO\n");
  110. }
  111. //LOG("I2c Tx empty:%x, %x\n", st0,st);
  112. return SUCCESS;
  113. }
  114. void* hal_i2c_init(i2c_dev_t dev, I2C_CLOCK_e i2c_clock_rate)
  115. {
  116. int pclk = clk_get_pclk();
  117. AP_I2C_TypeDef * pi2cdev = NULL;
  118. if(dev == I2C_0){
  119. pi2cdev = AP_I2C0;
  120. hal_clk_gate_enable(MOD_I2C0);
  121. }
  122. else if(dev == I2C_1){
  123. pi2cdev = AP_I2C1;
  124. hal_clk_gate_enable(MOD_I2C1);
  125. }
  126. else{
  127. return NULL;
  128. }
  129. pi2cdev->IC_ENABLE=0;
  130. pi2cdev->IC_CON=0x61;
  131. if(i2c_clock_rate==I2C_CLOCK_100K){
  132. pi2cdev->IC_CON= ((pi2cdev->IC_CON) & 0xfffffff9)|(0x01 << 1);
  133. if(pclk==16000000){
  134. pi2cdev->IC_SS_SCL_HCNT=70; //16
  135. pi2cdev->IC_SS_SCL_LCNT=76; //32)
  136. }else if(pclk==32000000){
  137. pi2cdev->IC_SS_SCL_HCNT=148; //16
  138. pi2cdev->IC_SS_SCL_LCNT=154; //32)
  139. }else if(pclk==48000000){
  140. pi2cdev->IC_SS_SCL_HCNT=230; //16
  141. pi2cdev->IC_SS_SCL_LCNT=236; //32)
  142. }else if(pclk==64000000){
  143. pi2cdev->IC_SS_SCL_HCNT=307; //16
  144. pi2cdev->IC_SS_SCL_LCNT=320; //32)
  145. }else if(pclk==96000000){
  146. pi2cdev->IC_SS_SCL_HCNT=460; //16
  147. pi2cdev->IC_SS_SCL_LCNT=470; //32)
  148. }
  149. }else if(i2c_clock_rate==I2C_CLOCK_400K){
  150. pi2cdev->IC_CON= ((pi2cdev->IC_CON) & 0xfffffff9)|(0x02 << 1);
  151. if(pclk==16000000){
  152. pi2cdev->IC_FS_SCL_HCNT=10; //16
  153. pi2cdev->IC_FS_SCL_LCNT=17; //32)
  154. }else if(pclk==32000000){
  155. pi2cdev->IC_FS_SCL_HCNT=30; //16
  156. pi2cdev->IC_FS_SCL_LCNT=35; //32)
  157. }else if(pclk==48000000){
  158. pi2cdev->IC_FS_SCL_HCNT=48; //16
  159. pi2cdev->IC_FS_SCL_LCNT=54; //32)
  160. }else if(pclk==64000000){
  161. pi2cdev->IC_FS_SCL_HCNT=67; //16
  162. pi2cdev->IC_FS_SCL_LCNT=75; //32)
  163. }else if(pclk==96000000){
  164. pi2cdev->IC_FS_SCL_HCNT=105; //16
  165. pi2cdev->IC_FS_SCL_LCNT=113; //32)
  166. }
  167. }
  168. pi2cdev->IC_TAR = I2C_MASTER_ADDR_DEF;
  169. pi2cdev->IC_INTR_MASK=0;
  170. pi2cdev->IC_RX_TL=0x0;
  171. pi2cdev->IC_TX_TL=0x1;
  172. pi2cdev->IC_ENABLE=1;
  173. return (void*)pi2cdev;
  174. }
  175. int hal_i2c_deinit(void* pi2c){
  176. AP_I2C_TypeDef * pi2cdev = (AP_I2C_TypeDef *)pi2c;
  177. if(pi2cdev == AP_I2C0){
  178. pi2cdev->IC_ENABLE=0;
  179. hal_clk_gate_disable(MOD_I2C0);
  180. }
  181. else if(pi2cdev == AP_I2C1){
  182. pi2cdev->IC_ENABLE=0;
  183. hal_clk_gate_enable(MOD_I2C1);
  184. }
  185. else{
  186. return ERR_INVALID_PARAM;
  187. }
  188. return SUCCESS;
  189. }
  190. /**************************************************************************************
  191. * @fn hal_i2c_pin_init
  192. *
  193. * @brief This function process for i2c pin initial(2 lines);You can use two i2c,i2c0 and i2c1,should programe by USE_AP_I2CX
  194. *
  195. * input parameters
  196. *
  197. * @param GpioPin_t pin_sda: define sda_pin
  198. * GpioPin_t pin_clk: define clk_pin
  199. *
  200. * output parameters
  201. *
  202. * @param None.
  203. *
  204. * @return None.
  205. **************************************************************************************/
  206. int hal_i2c_pin_init(i2c_dev_t dev, GpioPin_t pin_sda, GpioPin_t pin_clk){
  207. if(dev == I2C_0){
  208. HalGpioFmuxConfig(pin_clk, FMUX_IIC0_SCL);
  209. HalGpioFmuxConfig(pin_sda, FMUX_IIC0_SDA);
  210. }
  211. else if(dev == I2C_1){
  212. HalGpioFmuxConfig(pin_clk, FMUX_IIC1_SCL);
  213. HalGpioFmuxConfig(pin_sda, FMUX_IIC1_SDA);
  214. }
  215. else{
  216. return ERR_INVALID_PARAM;
  217. }
  218. HalGpioPupdConfig(pin_sda,GPIO_PULL_UP_S);
  219. HalGpioPupdConfig(pin_clk,GPIO_PULL_UP_S);
  220. if(dev == I2C_0){
  221. hal_clk_gate_enable(MOD_I2C0);
  222. }
  223. else if(dev == I2C_1){
  224. hal_clk_gate_enable(MOD_I2C1);
  225. }
  226. return SUCCESS;
  227. }
  228. int hal_i2c_tx_start(void* pi2c)
  229. {
  230. AP_I2C_TypeDef * pi2cdev = (AP_I2C_TypeDef *)pi2c;
  231. if(pi2cdev != AP_I2C0 && pi2cdev != AP_I2C1){
  232. return ERR_INVALID_PARAM;
  233. }
  234. pi2cdev->IC_ENABLE=1;
  235. return SUCCESS;
  236. }
  237. /**************************************************************************************
  238. * @fn hal_i2c_addr_update
  239. *
  240. * @brief This function process for tar update
  241. *
  242. * input parameters
  243. *
  244. * @param uint8_t addr: address
  245. *
  246. * output parameters
  247. *
  248. * @param None.
  249. *
  250. * @return None.
  251. **************************************************************************************/
  252. int hal_i2c_addr_update(void* pi2c, uint8_t addr){
  253. AP_I2C_TypeDef * pi2cdev = (AP_I2C_TypeDef *)pi2c;
  254. if(pi2cdev != AP_I2C0 && pi2cdev != AP_I2C1){
  255. return ERR_INVALID_PARAM;
  256. }
  257. pi2cdev->IC_ENABLE=0;
  258. pi2cdev->IC_TAR = addr;
  259. pi2cdev->IC_ENABLE=0;
  260. return SUCCESS;
  261. }
  262. int _hal_i2c_read_s(void* pi2c, uint8_t slave_addr, uint8_t reg, uint8_t* data, uint8_t size)
  263. {
  264. I2C_INIT_TOUT(to);
  265. AP_I2C_TypeDef * pi2cdev = (AP_I2C_TypeDef *)pi2c;
  266. if(pi2cdev != AP_I2C0 && pi2cdev != AP_I2C1){
  267. return ERR_INVALID_PARAM;
  268. }
  269. hal_i2c_addr_update(pi2c, slave_addr);
  270. HAL_ENTER_CRITICAL_SECTION();
  271. hal_i2c_tx_start(pi2c);
  272. _hal_i2c_send_byte(pi2c, reg);
  273. hal_master_send_read_cmd(pi2c, size);
  274. HAL_EXIT_CRITICAL_SECTION();
  275. while(1){
  276. if(I2C_RX_FIFO_NOT_EMPTY(pi2cdev)){
  277. *data = (pi2cdev->IC_DATA_CMD&0xff);
  278. data++;
  279. size --;
  280. if(size == 0)
  281. break;
  282. }
  283. I2C_CHECK_TOUT(to, I2C_OP_TIMEOUT*size, "I2C RD TO\n");
  284. }
  285. return SUCCESS;
  286. }
  287. int hal_i2c_read(
  288. void* pi2c,
  289. uint8_t slave_addr,
  290. uint8_t reg,
  291. uint8_t* data,
  292. uint8_t size)
  293. {
  294. uint8_t cnt;
  295. int ret = SUCCESS;
  296. AP_I2C_TypeDef * pi2cdev = (AP_I2C_TypeDef *)pi2c;
  297. if(pi2cdev != AP_I2C0 && pi2cdev != AP_I2C1){
  298. return ERR_INVALID_PARAM;
  299. }
  300. while(size){
  301. cnt = (size >7) ? 7 : size;
  302. size -= cnt;
  303. ret = _hal_i2c_read_s(pi2c, slave_addr, reg, data , cnt);
  304. if(ret != SUCCESS)
  305. break;
  306. data += cnt;
  307. }
  308. return ret;
  309. }