You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

487 lines
20 KiB

3 years ago
  1. // Copyright 2020-2021 Espressif Systems (Shanghai) PTE LTD
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. // http://www.apache.org/licenses/LICENSE-2.0
  7. //
  8. // Unless required by applicable law or agreed to in writing, software
  9. // distributed under the License is distributed on an "AS IS" BASIS,
  10. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  11. // See the License for the specific language governing permissions and
  12. // limitations under the License.
  13. #include <stdio.h>
  14. #include <string.h>
  15. #include "freertos/FreeRTOS.h"
  16. #include "freertos/semphr.h"
  17. #include "esp_log.h"
  18. #include "i2c_bus.h"
  19. #define I2C_ACK_CHECK_EN 0x1 /*!< I2C master will check ack from slave*/
  20. #define I2C_ACK_CHECK_DIS 0x0 /*!< I2C master will not check ack from slave */
  21. #define I2C_BUS_FLG_DEFAULT (0)
  22. #define I2C_BUS_MASTER_BUF_LEN (0)
  23. #define I2C_BUS_MS_TO_WAIT CONFIG_I2C_MS_TO_WAIT
  24. #define I2C_BUS_TICKS_TO_WAIT (I2C_BUS_MS_TO_WAIT/portTICK_RATE_MS)
  25. #define I2C_BUS_MUTEX_TICKS_TO_WAIT (I2C_BUS_MS_TO_WAIT/portTICK_RATE_MS)
  26. typedef struct {
  27. i2c_port_t i2c_port; /*!<I2C port number */
  28. bool is_init; /*if bus is initialized*/
  29. i2c_config_t conf_active; /*!<I2C active configuration */
  30. SemaphoreHandle_t mutex; /* mutex to achive thread-safe*/
  31. int32_t ref_counter; /*reference count*/
  32. } i2c_bus_t;
  33. typedef struct {
  34. uint8_t dev_addr; /*device address*/
  35. i2c_config_t conf; /*!<I2C active configuration */
  36. i2c_bus_t *i2c_bus; /*!<I2C bus*/
  37. } i2c_bus_device_t;
  38. static const char *TAG = "i2c_bus";
  39. static i2c_bus_t s_i2c_bus[I2C_NUM_MAX];
  40. #define I2C_BUS_CHECK(a, str, ret) if(!(a)) { \
  41. ESP_LOGE(TAG,"%s:%d (%s):%s", __FILE__, __LINE__, __FUNCTION__, str); \
  42. return (ret); \
  43. }
  44. #define I2C_BUS_CHECK_GOTO(a, str, lable) if(!(a)) { \
  45. ESP_LOGE(TAG,"%s:%d (%s):%s", __FILE__, __LINE__, __FUNCTION__, str); \
  46. goto lable; \
  47. }
  48. #define I2C_BUS_INIT_CHECK(is_init, ret) if(!is_init) { \
  49. ESP_LOGE(TAG,"%s:%d (%s):i2c_bus has not inited", __FILE__, __LINE__, __FUNCTION__); \
  50. return (ret); \
  51. }
  52. #define I2C_BUS_MUTEX_TAKE(mutex, ret) if (!xSemaphoreTake(mutex, I2C_BUS_MUTEX_TICKS_TO_WAIT)) { \
  53. ESP_LOGE(TAG, "i2c_bus take mutex timeout, max wait = %d ms", I2C_BUS_MUTEX_TICKS_TO_WAIT); \
  54. return (ret); \
  55. }
  56. #define I2C_BUS_MUTEX_TAKE_MAX_DELAY(mutex, ret) if (!xSemaphoreTake(mutex, portMAX_DELAY)) { \
  57. ESP_LOGE(TAG, "i2c_bus take mutex timeout, max wait = %d ms", portMAX_DELAY); \
  58. return (ret); \
  59. }
  60. #define I2C_BUS_MUTEX_GIVE(mutex, ret) if (!xSemaphoreGive(mutex)) { \
  61. ESP_LOGE(TAG, "i2c_bus give mutex failed"); \
  62. return (ret); \
  63. }
  64. static esp_err_t i2c_driver_reinit(i2c_port_t port, const i2c_config_t *conf);
  65. static esp_err_t i2c_driver_deinit(i2c_port_t port);
  66. static esp_err_t i2c_bus_write_reg8(i2c_bus_device_handle_t dev_handle, uint8_t mem_address, size_t data_len, const uint8_t *data);
  67. static esp_err_t i2c_bus_read_reg8(i2c_bus_device_handle_t dev_handle, uint8_t mem_address, size_t data_len, uint8_t *data);
  68. inline static bool i2c_config_compare(i2c_port_t port, const i2c_config_t *conf);
  69. /**************************************** Public Functions (Application level)*********************************************/
  70. i2c_bus_handle_t i2c_bus_create(i2c_port_t port, const i2c_config_t *conf)
  71. {
  72. I2C_BUS_CHECK(port < I2C_NUM_MAX, "I2C port error", NULL);
  73. I2C_BUS_CHECK(conf != NULL, "pointer = NULL error", NULL);
  74. I2C_BUS_CHECK(conf->mode == I2C_MODE_MASTER, "i2c_bus only supports master mode", NULL);
  75. if (s_i2c_bus[port].is_init) {
  76. /**if i2c_bus has been inited and configs not changed, return the handle directly**/
  77. if (i2c_config_compare(port, conf)) {
  78. ESP_LOGW(TAG, "i2c%d has been inited, return handle directly, ref_counter=%d", port, s_i2c_bus[port].ref_counter);
  79. return (i2c_bus_handle_t)&s_i2c_bus[port];
  80. }
  81. } else {
  82. s_i2c_bus[port].mutex = xSemaphoreCreateMutex();
  83. I2C_BUS_CHECK(s_i2c_bus[port].mutex != NULL, "i2c_bus xSemaphoreCreateMutex failed", NULL);
  84. s_i2c_bus[port].ref_counter = 0;
  85. }
  86. esp_err_t ret = i2c_driver_reinit(port, conf);
  87. I2C_BUS_CHECK(ret == ESP_OK, "init error", NULL);
  88. s_i2c_bus[port].conf_active = *conf;
  89. s_i2c_bus[port].i2c_port = port;
  90. return (i2c_bus_handle_t)&s_i2c_bus[port];
  91. }
  92. esp_err_t i2c_bus_delete(i2c_bus_handle_t *p_bus)
  93. {
  94. I2C_BUS_CHECK(p_bus != NULL && *p_bus != NULL, "pointer = NULL error", ESP_ERR_INVALID_ARG);
  95. i2c_bus_t *i2c_bus = (i2c_bus_t *)(*p_bus);
  96. I2C_BUS_INIT_CHECK(i2c_bus->is_init, ESP_FAIL);
  97. I2C_BUS_MUTEX_TAKE_MAX_DELAY(i2c_bus->mutex, ESP_ERR_TIMEOUT);
  98. /** if ref_counter == 0, de-init the bus**/
  99. if ((i2c_bus->ref_counter) > 0) {
  100. ESP_LOGW(TAG, "i2c%d is also handled by others ref_counter=%u, won't be de-inited", i2c_bus->i2c_port, i2c_bus->ref_counter);
  101. return ESP_OK;
  102. }
  103. esp_err_t ret = i2c_driver_deinit(i2c_bus->i2c_port);
  104. I2C_BUS_CHECK(ret == ESP_OK, "deinit error", ret);
  105. vSemaphoreDelete(i2c_bus->mutex);
  106. *p_bus = NULL;
  107. return ESP_OK;
  108. }
  109. uint8_t i2c_bus_scan(i2c_bus_handle_t bus_handle, uint8_t *buf, uint8_t num)
  110. {
  111. I2C_BUS_CHECK(bus_handle != NULL, "Handle error", 0);
  112. i2c_bus_t *i2c_bus = (i2c_bus_t *)bus_handle;
  113. I2C_BUS_INIT_CHECK(i2c_bus->is_init, 0);
  114. uint8_t device_count = 0;
  115. I2C_BUS_MUTEX_TAKE_MAX_DELAY(i2c_bus->mutex, 0);
  116. for (uint8_t dev_address = 1; dev_address < 127; dev_address++) {
  117. i2c_cmd_handle_t cmd = i2c_cmd_link_create();
  118. i2c_master_start(cmd);
  119. i2c_master_write_byte(cmd, (dev_address << 1) | I2C_MASTER_WRITE, I2C_ACK_CHECK_EN);
  120. i2c_master_stop(cmd);
  121. esp_err_t ret = i2c_master_cmd_begin(i2c_bus->i2c_port, cmd, I2C_BUS_TICKS_TO_WAIT);
  122. if (ret == ESP_OK) {
  123. ESP_LOGI(TAG, "found i2c device address = 0x%02x", dev_address);
  124. if (buf != NULL && device_count < num) {
  125. *(buf + device_count) = dev_address;
  126. }
  127. device_count++;
  128. }
  129. i2c_cmd_link_delete(cmd);
  130. }
  131. I2C_BUS_MUTEX_GIVE(i2c_bus->mutex, 0);
  132. return device_count;
  133. }
  134. uint32_t i2c_bus_get_current_clk_speed(i2c_bus_handle_t bus_handle)
  135. {
  136. I2C_BUS_CHECK(bus_handle != NULL, "Null Bus Handle", 0);
  137. i2c_bus_t *i2c_bus = (i2c_bus_t *)bus_handle;
  138. I2C_BUS_INIT_CHECK(i2c_bus->is_init, 0);
  139. return i2c_bus->conf_active.master.clk_speed;
  140. }
  141. uint8_t i2c_bus_get_created_device_num(i2c_bus_handle_t bus_handle)
  142. {
  143. I2C_BUS_CHECK(bus_handle != NULL, "Null Bus Handle", 0);
  144. i2c_bus_t *i2c_bus = (i2c_bus_t *)bus_handle;
  145. I2C_BUS_INIT_CHECK(i2c_bus->is_init, 0);
  146. return i2c_bus->ref_counter;
  147. }
  148. i2c_bus_device_handle_t i2c_bus_device_create(i2c_bus_handle_t bus_handle, uint8_t dev_addr, uint32_t clk_speed)
  149. {
  150. I2C_BUS_CHECK(bus_handle != NULL, "Null Bus Handle", NULL);
  151. I2C_BUS_CHECK(clk_speed <= 400000, "clk_speed must <= 400000", NULL);
  152. i2c_bus_t *i2c_bus = (i2c_bus_t *)bus_handle;
  153. I2C_BUS_INIT_CHECK(i2c_bus->is_init, NULL);
  154. i2c_bus_device_t *i2c_device = calloc(1, sizeof(i2c_bus_device_t));
  155. I2C_BUS_CHECK(i2c_device != NULL, "calloc memory failed", NULL);
  156. I2C_BUS_MUTEX_TAKE_MAX_DELAY(i2c_bus->mutex, NULL);
  157. i2c_device->dev_addr = dev_addr;
  158. i2c_device->conf = i2c_bus->conf_active;
  159. /*if clk_speed == 0, current active clock speed will be used, else set a specified value*/
  160. if (clk_speed != 0) {
  161. i2c_device->conf.master.clk_speed = clk_speed;
  162. }
  163. i2c_device->i2c_bus = i2c_bus;
  164. i2c_bus->ref_counter++;
  165. I2C_BUS_MUTEX_GIVE(i2c_bus->mutex, NULL);
  166. return (i2c_bus_device_handle_t)i2c_device;
  167. }
  168. esp_err_t i2c_bus_device_delete(i2c_bus_device_handle_t *p_dev_handle)
  169. {
  170. I2C_BUS_CHECK(p_dev_handle != NULL && *p_dev_handle != NULL, "Null Device Handle", ESP_ERR_INVALID_ARG);
  171. i2c_bus_device_t *i2c_device = (i2c_bus_device_t *)(*p_dev_handle);
  172. I2C_BUS_MUTEX_TAKE_MAX_DELAY(i2c_device->i2c_bus->mutex, ESP_ERR_TIMEOUT);
  173. i2c_device->i2c_bus->ref_counter--;
  174. I2C_BUS_MUTEX_GIVE(i2c_device->i2c_bus->mutex, ESP_FAIL);
  175. free(i2c_device);
  176. *p_dev_handle = NULL;
  177. return ESP_OK;
  178. }
  179. uint8_t i2c_bus_device_get_address(i2c_bus_device_handle_t dev_handle)
  180. {
  181. I2C_BUS_CHECK(dev_handle != NULL, "device handle error", NULL_I2C_DEV_ADDR);
  182. i2c_bus_device_t *i2c_device = (i2c_bus_device_t *)dev_handle;
  183. return i2c_device->dev_addr;
  184. }
  185. esp_err_t i2c_bus_read_bytes(i2c_bus_device_handle_t dev_handle, uint8_t mem_address, size_t data_len, uint8_t *data)
  186. {
  187. return i2c_bus_read_reg8(dev_handle, mem_address, data_len, data);
  188. }
  189. esp_err_t i2c_bus_read_byte(i2c_bus_device_handle_t dev_handle, uint8_t mem_address, uint8_t *data)
  190. {
  191. return i2c_bus_read_reg8(dev_handle, mem_address, 1, data);
  192. }
  193. esp_err_t i2c_bus_read_bit(i2c_bus_device_handle_t dev_handle, uint8_t mem_address, uint8_t bit_num, uint8_t *data)
  194. {
  195. uint8_t byte = 0;
  196. esp_err_t ret = i2c_bus_read_reg8(dev_handle, mem_address, 1, &byte);
  197. *data = byte & (1 << bit_num);
  198. *data = (*data != 0) ? 1 : 0;
  199. return ret;
  200. }
  201. esp_err_t i2c_bus_read_bits(i2c_bus_device_handle_t dev_handle, uint8_t mem_address, uint8_t bit_start, uint8_t length, uint8_t *data)
  202. {
  203. uint8_t byte = 0;
  204. esp_err_t ret = i2c_bus_read_byte(dev_handle, mem_address, &byte);
  205. if (ret != ESP_OK) {
  206. return ret;
  207. }
  208. uint8_t mask = ((1 << length) - 1) << (bit_start - length + 1);
  209. byte &= mask;
  210. byte >>= (bit_start - length + 1);
  211. *data = byte;
  212. return ret;
  213. }
  214. esp_err_t i2c_bus_write_byte(i2c_bus_device_handle_t dev_handle, uint8_t mem_address, uint8_t data)
  215. {
  216. return i2c_bus_write_reg8(dev_handle, mem_address, 1, &data);
  217. }
  218. esp_err_t i2c_bus_write_bytes(i2c_bus_device_handle_t dev_handle, uint8_t mem_address, size_t data_len, const uint8_t *data)
  219. {
  220. return i2c_bus_write_reg8(dev_handle, mem_address, data_len, data);
  221. }
  222. esp_err_t i2c_bus_write_bit(i2c_bus_device_handle_t dev_handle, uint8_t mem_address, uint8_t bit_num, uint8_t data)
  223. {
  224. uint8_t byte = 0;
  225. esp_err_t ret = i2c_bus_read_byte(dev_handle, mem_address, &byte);
  226. if (ret != ESP_OK) {
  227. return ret;
  228. }
  229. byte = (data != 0) ? (byte | (1 << bit_num)) : (byte & ~(1 << bit_num));
  230. return i2c_bus_write_byte(dev_handle, mem_address, byte);
  231. }
  232. esp_err_t i2c_bus_write_bits(i2c_bus_device_handle_t dev_handle, uint8_t mem_address, uint8_t bit_start, uint8_t length, uint8_t data)
  233. {
  234. uint8_t byte = 0;
  235. esp_err_t ret = i2c_bus_read_byte(dev_handle, mem_address, &byte);
  236. if (ret != ESP_OK) {
  237. return ret;
  238. }
  239. uint8_t mask = ((1 << length) - 1) << (bit_start - length + 1);
  240. data <<= (bit_start - length + 1); // shift data into correct position
  241. data &= mask; // zero all non-important bits in data
  242. byte &= ~(mask); // zero all important bits in existing byte
  243. byte |= data; // combine data with existing byte
  244. return i2c_bus_write_byte(dev_handle, mem_address, byte);
  245. }
  246. /**
  247. * @brief I2C master send queued commands.
  248. * This function will trigger sending all queued commands.
  249. * The task will be blocked until all the commands have been sent out.
  250. * If I2C_BUS_DYNAMIC_CONFIG enable, i2c_bus will dynamically check configs and re-install i2c driver before each transfer,
  251. * hence multiple devices with different configs on a single bus can be supported.
  252. * @note
  253. * Only call this function in I2C master mode
  254. *
  255. * @param i2c_num I2C port number
  256. * @param cmd_handle I2C command handler
  257. * @param ticks_to_wait maximum wait ticks.
  258. * @param conf pointer to I2C parameter settings
  259. * @return esp_err_t
  260. */
  261. inline static esp_err_t i2c_master_cmd_begin_with_conf(i2c_port_t i2c_num, i2c_cmd_handle_t cmd_handle, TickType_t ticks_to_wait, const i2c_config_t *conf)
  262. {
  263. esp_err_t ret;
  264. #ifdef CONFIG_I2C_BUS_DYNAMIC_CONFIG
  265. /*if configs changed, i2c driver will reinit with new configuration*/
  266. if (conf != NULL && false == i2c_config_compare(i2c_num, conf)) {
  267. ret = i2c_driver_reinit(i2c_num, conf);
  268. I2C_BUS_CHECK(ret == ESP_OK, "reinit error", ret);
  269. s_i2c_bus[i2c_num].conf_active = *conf;
  270. }
  271. #endif
  272. ret = i2c_master_cmd_begin(i2c_num, cmd_handle, ticks_to_wait);
  273. return ret;
  274. }
  275. /**************************************** Public Functions (Low level)*********************************************/
  276. esp_err_t i2c_bus_cmd_begin(i2c_bus_device_handle_t dev_handle, i2c_cmd_handle_t cmd)
  277. {
  278. I2C_BUS_CHECK(dev_handle != NULL, "device handle error", ESP_ERR_INVALID_ARG);
  279. I2C_BUS_CHECK(cmd != NULL, "I2C command error", ESP_ERR_INVALID_ARG);
  280. i2c_bus_device_t *i2c_device = (i2c_bus_device_t *)dev_handle;
  281. I2C_BUS_INIT_CHECK(i2c_device->i2c_bus->is_init, ESP_ERR_INVALID_STATE);
  282. I2C_BUS_MUTEX_TAKE(i2c_device->i2c_bus->mutex, ESP_ERR_TIMEOUT);
  283. esp_err_t ret = i2c_master_cmd_begin_with_conf(i2c_device->i2c_bus->i2c_port, cmd, I2C_BUS_TICKS_TO_WAIT, &i2c_device->conf);
  284. I2C_BUS_MUTEX_GIVE(i2c_device->i2c_bus->mutex, ESP_FAIL);
  285. return ret;
  286. }
  287. static esp_err_t i2c_bus_read_reg8(i2c_bus_device_handle_t dev_handle, uint8_t mem_address, size_t data_len, uint8_t *data)
  288. {
  289. I2C_BUS_CHECK(dev_handle != NULL, "device handle error", ESP_ERR_INVALID_ARG);
  290. I2C_BUS_CHECK(data != NULL, "data pointer error", ESP_ERR_INVALID_ARG);
  291. i2c_bus_device_t *i2c_device = (i2c_bus_device_t *)dev_handle;
  292. I2C_BUS_INIT_CHECK(i2c_device->i2c_bus->is_init, ESP_ERR_INVALID_STATE);
  293. I2C_BUS_MUTEX_TAKE(i2c_device->i2c_bus->mutex, ESP_ERR_TIMEOUT);
  294. i2c_cmd_handle_t cmd = i2c_cmd_link_create();
  295. if (mem_address != NULL_I2C_MEM_ADDR) {
  296. i2c_master_start(cmd);
  297. i2c_master_write_byte(cmd, (i2c_device->dev_addr << 1) | I2C_MASTER_WRITE, I2C_ACK_CHECK_EN);
  298. i2c_master_write_byte(cmd, mem_address, I2C_ACK_CHECK_EN);
  299. }
  300. i2c_master_start(cmd);
  301. i2c_master_write_byte(cmd, (i2c_device->dev_addr << 1) | I2C_MASTER_READ, I2C_ACK_CHECK_EN);
  302. i2c_master_read(cmd, data, data_len, I2C_MASTER_LAST_NACK);
  303. i2c_master_stop(cmd);
  304. esp_err_t ret = i2c_master_cmd_begin_with_conf(i2c_device->i2c_bus->i2c_port, cmd, I2C_BUS_TICKS_TO_WAIT, &i2c_device->conf);
  305. i2c_cmd_link_delete(cmd);
  306. I2C_BUS_MUTEX_GIVE(i2c_device->i2c_bus->mutex, ESP_FAIL);
  307. return ret;
  308. }
  309. esp_err_t i2c_bus_read_reg16(i2c_bus_device_handle_t dev_handle, uint16_t mem_address, size_t data_len, uint8_t *data)
  310. {
  311. I2C_BUS_CHECK(dev_handle != NULL, "device handle error", ESP_ERR_INVALID_ARG);
  312. I2C_BUS_CHECK(data != NULL, "data pointer error", ESP_ERR_INVALID_ARG);
  313. i2c_bus_device_t *i2c_device = (i2c_bus_device_t *)dev_handle;
  314. I2C_BUS_INIT_CHECK(i2c_device->i2c_bus->is_init, ESP_ERR_INVALID_STATE);
  315. uint8_t memAddress8[2];
  316. memAddress8[0] = (uint8_t)((mem_address >> 8) & 0x00FF);
  317. memAddress8[1] = (uint8_t)(mem_address & 0x00FF);
  318. I2C_BUS_MUTEX_TAKE(i2c_device->i2c_bus->mutex, ESP_ERR_TIMEOUT);
  319. i2c_cmd_handle_t cmd = i2c_cmd_link_create();
  320. if (mem_address != NULL_I2C_MEM_ADDR) {
  321. i2c_master_start(cmd);
  322. i2c_master_write_byte(cmd, (i2c_device->dev_addr << 1) | I2C_MASTER_WRITE, I2C_ACK_CHECK_EN);
  323. i2c_master_write(cmd, memAddress8, 2, I2C_ACK_CHECK_EN);
  324. }
  325. i2c_master_start(cmd);
  326. i2c_master_write_byte(cmd, (i2c_device->dev_addr << 1) | I2C_MASTER_READ, I2C_ACK_CHECK_EN);
  327. i2c_master_read(cmd, data, data_len, I2C_MASTER_LAST_NACK);
  328. i2c_master_stop(cmd);
  329. esp_err_t ret = i2c_master_cmd_begin_with_conf(i2c_device->i2c_bus->i2c_port, cmd, I2C_BUS_TICKS_TO_WAIT, &i2c_device->conf);
  330. i2c_cmd_link_delete(cmd);
  331. I2C_BUS_MUTEX_GIVE(i2c_device->i2c_bus->mutex, ESP_FAIL);
  332. return ret;
  333. }
  334. static esp_err_t i2c_bus_write_reg8(i2c_bus_device_handle_t dev_handle, uint8_t mem_address, size_t data_len, const uint8_t *data)
  335. {
  336. I2C_BUS_CHECK(dev_handle != NULL, "device handle error", ESP_ERR_INVALID_ARG);
  337. I2C_BUS_CHECK(data != NULL, "data pointer error", ESP_ERR_INVALID_ARG);
  338. i2c_bus_device_t *i2c_device = (i2c_bus_device_t *)dev_handle;
  339. I2C_BUS_INIT_CHECK(i2c_device->i2c_bus->is_init, ESP_ERR_INVALID_STATE);
  340. I2C_BUS_MUTEX_TAKE(i2c_device->i2c_bus->mutex, ESP_ERR_TIMEOUT);
  341. i2c_cmd_handle_t cmd = i2c_cmd_link_create();
  342. i2c_master_start(cmd);
  343. i2c_master_write_byte(cmd, (i2c_device->dev_addr << 1) | I2C_MASTER_WRITE, I2C_ACK_CHECK_EN);
  344. if (mem_address != NULL_I2C_MEM_ADDR) {
  345. i2c_master_write_byte(cmd, mem_address, I2C_ACK_CHECK_EN);
  346. }
  347. i2c_master_write(cmd, (uint8_t *)data, data_len, I2C_ACK_CHECK_EN);
  348. i2c_master_stop(cmd);
  349. esp_err_t ret = i2c_master_cmd_begin_with_conf(i2c_device->i2c_bus->i2c_port, cmd, I2C_BUS_TICKS_TO_WAIT, &i2c_device->conf);
  350. i2c_cmd_link_delete(cmd);
  351. I2C_BUS_MUTEX_GIVE(i2c_device->i2c_bus->mutex, ESP_FAIL);
  352. return ret;
  353. }
  354. esp_err_t i2c_bus_write_reg16(i2c_bus_device_handle_t dev_handle, uint16_t mem_address, size_t data_len, const uint8_t *data)
  355. {
  356. I2C_BUS_CHECK(dev_handle != NULL, "device handle error", ESP_ERR_INVALID_ARG);
  357. I2C_BUS_CHECK(data != NULL, "data pointer error", ESP_ERR_INVALID_ARG);
  358. i2c_bus_device_t *i2c_device = (i2c_bus_device_t *)dev_handle;
  359. I2C_BUS_INIT_CHECK(i2c_device->i2c_bus->is_init, ESP_ERR_INVALID_STATE);
  360. uint8_t memAddress8[2];
  361. memAddress8[0] = (uint8_t)((mem_address >> 8) & 0x00FF);
  362. memAddress8[1] = (uint8_t)(mem_address & 0x00FF);
  363. I2C_BUS_MUTEX_TAKE(i2c_device->i2c_bus->mutex, ESP_ERR_TIMEOUT);
  364. i2c_cmd_handle_t cmd = i2c_cmd_link_create();
  365. i2c_master_start(cmd);
  366. i2c_master_write_byte(cmd, (i2c_device->dev_addr << 1) | I2C_MASTER_WRITE, I2C_ACK_CHECK_EN);
  367. if (mem_address != NULL_I2C_MEM_ADDR) {
  368. i2c_master_write(cmd, memAddress8, 2, I2C_ACK_CHECK_EN);
  369. }
  370. i2c_master_write(cmd, (uint8_t *)data, data_len, I2C_ACK_CHECK_EN);
  371. i2c_master_stop(cmd);
  372. esp_err_t ret = i2c_master_cmd_begin_with_conf(i2c_device->i2c_bus->i2c_port, cmd, I2C_BUS_TICKS_TO_WAIT, &i2c_device->conf);
  373. i2c_cmd_link_delete(cmd);
  374. I2C_BUS_MUTEX_GIVE(i2c_device->i2c_bus->mutex, ESP_FAIL);
  375. return ret;
  376. }
  377. /**************************************** Private Functions*********************************************/
  378. static esp_err_t i2c_driver_reinit(i2c_port_t port, const i2c_config_t *conf)
  379. {
  380. I2C_BUS_CHECK(port < I2C_NUM_MAX, "i2c port error", ESP_ERR_INVALID_ARG);
  381. I2C_BUS_CHECK(conf != NULL, "pointer = NULL error", ESP_ERR_INVALID_ARG);
  382. if (s_i2c_bus[port].is_init) {
  383. i2c_driver_delete(port);
  384. s_i2c_bus[port].is_init = false;
  385. ESP_LOGI(TAG, "i2c%d bus deinited", port);
  386. }
  387. esp_err_t ret = i2c_param_config(port, conf);
  388. I2C_BUS_CHECK(ret == ESP_OK, "i2c param config failed", ret);
  389. ret = i2c_driver_install(port, conf->mode, I2C_BUS_MASTER_BUF_LEN, I2C_BUS_MASTER_BUF_LEN, I2C_BUS_FLG_DEFAULT);
  390. I2C_BUS_CHECK(ret == ESP_OK, "i2c driver install failed", ret);
  391. s_i2c_bus[port].is_init = true;
  392. ESP_LOGI(TAG, "i2c%d bus inited", port);
  393. return ESP_OK;
  394. }
  395. static esp_err_t i2c_driver_deinit(i2c_port_t port)
  396. {
  397. I2C_BUS_CHECK(port < I2C_NUM_MAX, "i2c port error", ESP_ERR_INVALID_ARG);
  398. I2C_BUS_CHECK(s_i2c_bus[port].is_init == true, "i2c not inited", ESP_ERR_INVALID_STATE);
  399. i2c_driver_delete(port); //always return ESP_OK
  400. s_i2c_bus[port].is_init = false;
  401. ESP_LOGI(TAG,"i2c%d bus deinited",port);
  402. return ESP_OK;
  403. }
  404. /**
  405. * @brief compare with active i2c_bus configuration
  406. *
  407. * @param port choose which i2c_port's configuration will be compared
  408. * @param conf new configuration
  409. * @return true new configuration is equal to active configuration
  410. * @return false new configuration is not equal to active configuration
  411. */
  412. inline static bool i2c_config_compare(i2c_port_t port, const i2c_config_t *conf)
  413. {
  414. if (s_i2c_bus[port].conf_active.master.clk_speed == conf->master.clk_speed
  415. && s_i2c_bus[port].conf_active.sda_io_num == conf->sda_io_num
  416. && s_i2c_bus[port].conf_active.scl_io_num == conf->scl_io_num
  417. && s_i2c_bus[port].conf_active.scl_pullup_en == conf->scl_pullup_en
  418. && s_i2c_bus[port].conf_active.sda_pullup_en == conf->sda_pullup_en) {
  419. return true;
  420. }
  421. return false;
  422. }