HW_I2C_ATY.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521
  1. /**
  2. * @file HW_I2C_ATY.c
  3. *
  4. * @param Project DEVICE_GENERAL_ATY_LIB
  5. *
  6. * @author ATY
  7. *
  8. * @copyright
  9. * - Copyright 2017 - 2023 MZ-ATY
  10. * - This code follows:
  11. * - MZ-ATY Various Contents Joint Statement -
  12. * <a href="https://mengze.top/MZ-ATY_VCJS">
  13. * https://mengze.top/MZ-ATY_VCJS</a>
  14. * - CC 4.0 BY-NC-SA -
  15. * <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/">
  16. * https://creativecommons.org/licenses/by-nc-sa/4.0/</a>
  17. * - Your use will be deemed to have accepted the terms of this statement.
  18. *
  19. * @brief Familiar functions of I2C for all embedded device
  20. *
  21. * @version
  22. * - 1_01_220602 > ATY
  23. * -# Preliminary version, first Release
  24. * - 1_02_220804 > ATY
  25. * -# Change delay flow
  26. * -# Change SDA set function
  27. * -# Add Read/Write function
  28. * -Undone: hardware not test
  29. ********************************************************************************
  30. */
  31. #ifndef __HW_I2C_ATY_C
  32. #define __HW_I2C_ATY_C
  33. #include "HW_I2C_ATY.h"
  34. /******************************* For user *************************************/
  35. /******************************************************************************/
  36. #ifndef __I2C_HARDWARE_ATY
  37. // 1: Out, 0: In, config default out
  38. uint8_t i2c_SdaDir = 1;
  39. /**
  40. * @brief Set SDA output
  41. */
  42. void I2C_SDA_SetOut(void)
  43. {
  44. if(i2c_SdaDir == 0)
  45. {
  46. i2c_SdaDir = 1;
  47. GPIO_SET_OUT(I2C_SDA_PORT, I2C_SDA_PIN);
  48. }
  49. }
  50. /**
  51. * @brief Set SDA input
  52. */
  53. void I2C_SDA_SetIn(void)
  54. {
  55. if(i2c_SdaDir == 1)
  56. {
  57. i2c_SdaDir = 0;
  58. GPIO_SET_IN(I2C_SDA_PORT, I2C_SDA_PIN);
  59. }
  60. }
  61. /**
  62. * @brief Star I2C bus
  63. * @note START:when CLK is high,DATA change form high to low
  64. */
  65. void I2C_Start(void)
  66. {
  67. I2C_SDA_SET_OUT;
  68. DelayUs(4);
  69. I2C_SDA_SET_H;
  70. I2C_SCL_SET_H;
  71. DelayUs(4);
  72. I2C_SDA_SET_L;
  73. DelayUs(4);
  74. I2C_SCL_SET_L;
  75. }
  76. /**
  77. * @brief Stop I2C bus
  78. * @note STOP:when CLK is high DATA change form low to high
  79. */
  80. void I2C_Stop(void)
  81. {
  82. I2C_SDA_SET_OUT;
  83. DelayUs(4);
  84. I2C_SCL_SET_L;
  85. I2C_SDA_SET_L;
  86. DelayUs(4);
  87. I2C_SCL_SET_H;
  88. DelayUs(4);
  89. I2C_SDA_SET_H;
  90. }
  91. /**
  92. * @brief I2C ack
  93. */
  94. void I2C_Ack(void)
  95. {
  96. I2C_SDA_SET_OUT;
  97. DelayUs(4);
  98. I2C_SCL_SET_L;
  99. I2C_SDA_SET_L;
  100. DelayUs(4);
  101. I2C_SCL_SET_H;
  102. DelayUs(4);
  103. I2C_SCL_SET_L;
  104. }
  105. /**
  106. * @brief I2C no ack
  107. */
  108. void I2C_NoAck(void)
  109. {
  110. I2C_SDA_SET_OUT;
  111. DelayUs(4);
  112. I2C_SCL_SET_L;
  113. I2C_SDA_SET_H;
  114. DelayUs(4);
  115. I2C_SCL_SET_H;
  116. DelayUs(4);
  117. I2C_SCL_SET_L;
  118. }
  119. /**
  120. * @brief Wait ack coming
  121. * @param maxErrTime max time to wait until fail
  122. * @return 0 success, !0: fail
  123. */
  124. uint8_t I2C_WaitAck(uint16_t maxErrTime)
  125. {
  126. uint16_t errTime = 0;
  127. I2C_SDA_SET_IN;
  128. DelayUs(4);
  129. I2C_SCL_SET_H;
  130. DelayUs(4);
  131. while(I2C_SDA_GET_H)
  132. {
  133. errTime++;
  134. DelayUs(2);
  135. if(errTime > maxErrTime)
  136. {
  137. I2C_Stop();
  138. return 1;
  139. }
  140. }
  141. I2C_SCL_SET_L;
  142. return 0;
  143. }
  144. /**
  145. * @brief I2C send one byte
  146. * @param byte data to send
  147. */
  148. void I2C_WriteByte(uint8_t byte)
  149. {
  150. uint8_t isb_i;
  151. I2C_SDA_SET_OUT;
  152. DelayUs(8);
  153. I2C_SCL_SET_L;
  154. for(isb_i = 0; isb_i < 8; isb_i++)
  155. {
  156. DelayUs(4);
  157. if((byte & 0x80) >> 7)
  158. I2C_SDA_SET_H;
  159. else
  160. I2C_SDA_SET_L;
  161. byte <<= 1;
  162. I2C_SCL_SET_H;
  163. DelayUs(4);
  164. I2C_SCL_SET_L;
  165. }
  166. }
  167. /**
  168. * @brief I2C read one byte
  169. * @param ack if send ACK or not
  170. * @return data to read
  171. */
  172. uint8_t I2C_ReadByte(uint8_t ack)
  173. {
  174. uint8_t irb_i, byte = 0;
  175. I2C_SDA_SET_IN;
  176. DelayUs(8);
  177. for(irb_i = 0; irb_i < 8; irb_i++)
  178. {
  179. I2C_SCL_SET_L;
  180. DelayUs(4);
  181. I2C_SCL_SET_H;
  182. DelayUs(4);
  183. byte <<= 1;
  184. if(I2C_SDA_GET_H) byte++;
  185. }
  186. I2C_SCL_SET_L;
  187. if(ack)
  188. I2C_Ack();
  189. else
  190. I2C_NoAck();
  191. return byte;
  192. }
  193. /**
  194. * @brief Write serial data to reg
  195. * @param addr slave machine address
  196. * @param data_t data to write(uint8)
  197. * @param len length of write data(uint8)
  198. * @return 0: success, !0: error
  199. */
  200. uint8_t I2C_Write(uint8_t addr, uint8_t* data_t, uint8_t len)
  201. {
  202. uint8_t i = 0;
  203. I2C_Start();
  204. I2C_WriteByte(addr << 1 | 0);
  205. if(I2C_WaitAck(I2C_WAIT_ACK_TIME))
  206. return 1;
  207. for(i = 0; i < len; i++)
  208. {
  209. I2C_WriteByte(data_t[i]);
  210. if(I2C_WaitAck(I2C_WAIT_ACK_TIME))
  211. return 1;
  212. }
  213. I2C_Stop();
  214. return 0;
  215. }
  216. /**
  217. * @brief Write serial data to reg
  218. * @param addr slave machine address
  219. * @param data_t data to write(uint8)
  220. * @param len length of write data(uint8)
  221. * @return 0: success, !0: error
  222. */
  223. uint8_t I2C_Write_NoStop(uint8_t addr, uint8_t* data_t, uint8_t len)
  224. {
  225. uint8_t i = 0;
  226. I2C_Start();
  227. I2C_WriteByte(addr << 1 | 0);
  228. if(I2C_WaitAck(I2C_WAIT_ACK_TIME))
  229. return 1;
  230. for(i = 0; i < len; i++)
  231. {
  232. I2C_WriteByte(data_t[i]);
  233. if(I2C_WaitAck(I2C_WAIT_ACK_TIME))
  234. return 1;
  235. }
  236. return 0;
  237. }
  238. /**
  239. * @brief Read serial data to reg
  240. * @param addr slave machine address
  241. * @param data_t data to read(uint8)
  242. * @param len length of read data(uint8)
  243. * @return 0: success, !0: error
  244. */
  245. uint8_t I2C_Read(uint8_t addr, uint8_t* data_t, uint8_t len)
  246. {
  247. I2C_Start();
  248. I2C_WriteByte(addr << 1 | 1);
  249. if(I2C_WaitAck(I2C_WAIT_ACK_TIME))
  250. return 1;
  251. while(len--)
  252. {
  253. if(len > 0)
  254. *data_t++ = I2C_ReadByte(1);
  255. else
  256. *data_t++ = I2C_ReadByte(0);
  257. }
  258. I2C_Stop();
  259. return 0;
  260. }
  261. /**
  262. * @brief Write serial data to reg
  263. * @param addr slave machine address
  264. * @param reg reg addr to write
  265. * @param data_t data to write(uint8)
  266. * @param len length of write data(uint8)
  267. * @return 0: success, !0: error
  268. */
  269. uint8_t I2C_WriteReg(uint8_t addr, uint8_t reg, uint8_t* data_t, uint8_t len)
  270. {
  271. uint8_t i = 0;
  272. I2C_Start();
  273. I2C_WriteByte(addr << 1 | 0);
  274. if(I2C_WaitAck(I2C_WAIT_ACK_TIME))
  275. {
  276. I2C_Stop();
  277. return 1;
  278. }
  279. if(reg != 0)
  280. {
  281. I2C_WriteByte(reg);
  282. I2C_WaitAck(I2C_WAIT_ACK_TIME);
  283. }
  284. for(i = 0; i < len; i++)
  285. {
  286. I2C_WriteByte(data_t[i]);
  287. if(I2C_WaitAck(I2C_WAIT_ACK_TIME))
  288. {
  289. I2C_Stop();
  290. return 1;
  291. }
  292. }
  293. I2C_Stop();
  294. return 0;
  295. }
  296. /**
  297. * @brief Read serial data to reg
  298. * @param addr slave machine address
  299. * @param reg reg addr to read
  300. * @param data_t data to read(uint8)
  301. * @param len length of read data(uint8)
  302. * @return 0: success, !0: error
  303. */
  304. uint8_t I2C_ReadReg(uint8_t addr, uint8_t reg, uint8_t* data_t, uint8_t len)
  305. {
  306. I2C_Start();
  307. I2C_WriteByte(addr << 1 | 0);
  308. if(I2C_WaitAck(I2C_WAIT_ACK_TIME))
  309. {
  310. I2C_Stop();
  311. return 1;
  312. }
  313. I2C_WriteByte(reg);
  314. I2C_WaitAck(I2C_WAIT_ACK_TIME);
  315. I2C_Stop();
  316. I2C_Start();
  317. I2C_WriteByte(addr << 1 | 1);
  318. I2C_WaitAck(I2C_WAIT_ACK_TIME);
  319. while(len)
  320. {
  321. if(len == 1)
  322. *data_t = I2C_ReadByte(0);
  323. else
  324. *data_t = I2C_ReadByte(1);
  325. len--;
  326. data_t++;
  327. }
  328. I2C_Stop();
  329. return 0;
  330. }
  331. #else
  332. #if defined(__STM32_HAL_ATY)
  333. #include "i2c.h"
  334. /**
  335. * @brief Eliminate HAL_I2C bug
  336. * @warning Put "__HAL_RCC_I2C1_CLK_ENABLE();" before GPIO init
  337. */
  338. //void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c)
  339. //{
  340. // GPIO_InitTypeDef GPIO_InitStruct = {0};
  341. // if(hi2c->Instance==I2C1)
  342. // {
  343. // /* USER CODE BEGIN I2C1_MspInit 0 */
  344. // __HAL_RCC_I2C1_CLK_ENABLE();
  345. // /* USER CODE END I2C1_MspInit 0 */
  346. //
  347. // __HAL_RCC_GPIOB_CLK_ENABLE();
  348. // /**I2C1 GPIO Configuration
  349. // PB6 ------> I2C1_SCL
  350. // PB7 ------> I2C1_SDA
  351. // */
  352. // GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
  353. // GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
  354. // GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  355. // HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
  356. //
  357. // /* Peripheral clock enable */
  358. // //__HAL_RCC_I2C1_CLK_ENABLE();
  359. // /* USER CODE BEGIN I2C1_MspInit 1 */
  360. //
  361. // /* USER CODE END I2C1_MspInit 1 */
  362. // }
  363. //
  364. //}
  365. /**
  366. * @brief Write serial data to reg
  367. * @param addr slave machine address
  368. * @param data_t data to write(uint8)
  369. * @param len length of write data(uint8)
  370. * @return 0: success, !0: error
  371. */
  372. uint8_t I2C_Write(uint8_t addr, uint8_t* data_t, uint8_t len)
  373. {
  374. uint8_t i = 3;
  375. while(i--)
  376. {
  377. if(HAL_I2C_Master_Transmit(&I2CH_N, addr << 1 | 0, data_t, len, 1000) == HAL_OK)
  378. return 0;
  379. }
  380. return 1;
  381. }
  382. /**
  383. * @brief Read serial data to reg
  384. * @param addr slave machine address
  385. * @param data_t data to read(uint8)
  386. * @param len length of read data(uint8)
  387. * @return 0: success, !0: error
  388. */
  389. uint8_t I2C_Read(uint8_t addr, uint8_t* data_t, uint8_t len)
  390. {
  391. uint8_t i = 3;
  392. while(i--)
  393. {
  394. if(HAL_I2C_Master_Receive(&I2CH_N, addr << 1 | 1, data_t, len, 1000) == HAL_OK)
  395. return 0;
  396. }
  397. return 1;
  398. }
  399. #elif defined(__ESP8266_RTOS_ATY)
  400. #include "driver/i2c.h"
  401. #define I2C_EXAMPLE_MASTER_SCL_IO 2 /*!< gpio number for I2C master clock */
  402. #define I2C_EXAMPLE_MASTER_SDA_IO 14 /*!< gpio number for I2C master data */
  403. #define I2C_EXAMPLE_MASTER_NUM I2C_NUM_0 /*!< I2C port number for master dev */
  404. #define I2C_EXAMPLE_MASTER_TX_BUF_DISABLE 0 /*!< I2C master do not need buffer */
  405. #define I2C_EXAMPLE_MASTER_RX_BUF_DISABLE 0 /*!< I2C master do not need buffer */
  406. /**
  407. * @brief i2c master initialization
  408. */
  409. static esp_err_t i2c_example_master_init()
  410. {
  411. int i2c_master_port = I2CH_N;
  412. i2c_config_t conf;
  413. conf.mode = I2C_MODE_MASTER;
  414. conf.sda_io_num = I2C_EXAMPLE_MASTER_SDA_IO;
  415. conf.sda_pullup_en = 1;
  416. conf.scl_io_num = I2C_EXAMPLE_MASTER_SCL_IO;
  417. conf.scl_pullup_en = 1;
  418. conf.clk_stretch_tick = 300; // 300 ticks, Clock stretch is about 210us, you can make changes according to the actual situation.
  419. ESP_ERROR_CHECK(i2c_driver_install(i2c_master_port, conf.mode));
  420. ESP_ERROR_CHECK(i2c_param_config(i2c_master_port, &conf));
  421. return ESP_OK;
  422. }
  423. /**
  424. * @brief Write serial data to reg
  425. * @param addr slave machine address
  426. * @param data_t data to write(uint8)
  427. * @param len length of write data(uint8)
  428. * @return 0: success, !0: error
  429. */
  430. uint8_t I2C_Write(uint8_t addr, uint8_t* data_t, uint8_t len)
  431. {
  432. int ret;
  433. i2c_cmd_handle_t cmd = i2c_cmd_link_create();
  434. i2c_master_start(cmd);
  435. i2c_master_write_byte(cmd, addr << 1 | 0, ACK_CHECK_EN);
  436. i2c_master_write(cmd, data_t, len, ACK_CHECK_EN);
  437. i2c_master_stop(cmd);
  438. ret = i2c_master_cmd_begin(I2CH_N, cmd, 1000 / portTICK_RATE_MS);
  439. i2c_cmd_link_delete(cmd);
  440. return ret;
  441. }
  442. /**
  443. * @brief Read serial data to reg
  444. * @param addr slave machine address
  445. * @param data_t data to read(uint8)
  446. * @param len length of read data(uint8)
  447. * @return 0: success, !0: error
  448. */
  449. uint8_t I2C_Read(uint8_t addr, uint8_t* data_t, uint8_t len)
  450. {
  451. int ret;
  452. i2c_cmd_handle_t cmd = i2c_cmd_link_create();
  453. i2c_master_start(cmd);
  454. i2c_master_write_byte(cmd, addr << 1 | 0, ACK_CHECK_EN);
  455. i2c_master_stop(cmd);
  456. ret = i2c_master_cmd_begin(I2CH_N, cmd, 1000 / portTICK_RATE_MS);
  457. i2c_cmd_link_delete(cmd);
  458. if(ret != ESP_OK) {
  459. return ret;
  460. }
  461. cmd = i2c_cmd_link_create();
  462. i2c_master_start(cmd);
  463. i2c_master_write_byte(cmd, addr << 1 | 1, ACK_CHECK_EN);
  464. i2c_master_read(cmd, data_t, len, LAST_NACK_VAL);
  465. i2c_master_stop(cmd);
  466. ret = i2c_master_cmd_begin(i2c_num, cmd, 1000 / portTICK_RATE_MS);
  467. i2c_cmd_link_delete(cmd);
  468. return ret;
  469. }
  470. #endif /* PLATFORM */
  471. #endif /* __I2C_HARDWARE_ATY */
  472. #endif /* __HW_I2C_ATY_C */
  473. /******************************** End Of File *********************************/