SensorLib 0.5.0
Multi-platform sensor driver library for Arduino, PlatformIO, and ESP-IDF
Loading...
Searching...
No Matches
esp_idf_sensor_hub/main/i2c_driver.cpp
Go to the documentation of this file.
1
30#include <cstring>
31#include "freertos/FreeRTOS.h"
32#include "freertos/task.h"
33#include "driver/gpio.h"
34#include "esp_log.h"
35#include "sdkconfig.h"
36#include "i2c_driver.h"
37
38#if CONFIG_I2C_COMMUNICATION_METHOD_BUILTIN_RW || CONFIG_I2C_COMMUNICATION_METHOD_CALLBACK_RW
39
40static const char *TAG = "I2C";
41
42#define I2C_MASTER_NUM (i2c_port_t)CONFIG_I2C_MASTER_PORT_NUM
43#define I2C_MASTER_SDA_IO (gpio_num_t)CONFIG_SENSOR_SDA
44#define I2C_MASTER_SCL_IO (gpio_num_t)CONFIG_SENSOR_SCL
45#define I2C_MASTER_FREQ_HZ CONFIG_I2C_MASTER_FREQUENCY
46#define I2C_MASTER_TX_BUF_DISABLE 0
47#define I2C_MASTER_RX_BUF_DISABLE 0
49#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)) && defined(CONFIG_SENSORLIB_ESP_IDF_NEW_API)
50#include "soc/clk_tree_defs.h"
51
52i2c_master_dev_handle_t i2c_device;
53
54// * Using the new API of esp-idf 5.x, you need to pass the I2C BUS handle,
55// * which is useful when the bus shares multiple devices.
56i2c_master_bus_handle_t bus_handle;
57#endif
58
59
60#if CONFIG_I2C_COMMUNICATION_METHOD_CALLBACK_RW
61
62
63
64bool i2c_wr_function(uint8_t addr, uint8_t reg, uint8_t *buf, size_t len, bool writeReg, bool isWrite)
65{
66 if (isWrite) {
67 esp_err_t ret;
68 if (buf == NULL) {
69 return false;
70 }
71
72#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)) && defined(CONFIG_SENSORLIB_ESP_IDF_NEW_API)
73
74 if (writeReg) {
75 uint8_t *write_buffer = (uint8_t *)malloc(sizeof(uint8_t) * (len + 1));
76 if (!write_buffer) {
77 return -1;
78 }
79 write_buffer[0] = reg;
80 memcpy(write_buffer + 1, buf, len);
81
82 ret = i2c_master_transmit(
83 i2c_device,
84 write_buffer,
85 len + 1,
86 -1);
87 free(write_buffer);
88 } else {
89 ret = i2c_master_transmit(i2c_device, buf, len, -1);
90 }
91
92#else
93
94 i2c_cmd_handle_t cmd = i2c_cmd_link_create();
95 i2c_master_start(cmd);
96 i2c_master_write_byte(cmd, (addr << 1) | I2C_MASTER_WRITE, true);
97 if (writeReg) {
98 i2c_master_write_byte(cmd, reg, true);
99 }
100 i2c_master_write(cmd, buf, len, true);
101 i2c_master_stop(cmd);
102 ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, pdTICKS_TO_MS(1000));
103 i2c_cmd_link_delete(cmd);
104 if (ret != ESP_OK) {
105 ESP_LOGE(TAG, "i2c_write_error.");
106 }
107
108#endif
109 return ret == ESP_OK ? true : false;
110
111 } else {
112 esp_err_t ret;
113 if (len == 0) {
114 return true;
115 }
116 if (buf == NULL) {
117 return false;
118 }
119
120#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)) && defined(CONFIG_SENSORLIB_ESP_IDF_NEW_API)
121
122 ret = i2c_master_transmit_receive(i2c_device, (const uint8_t *)&reg, 1, buf, len, -1);
123
124#else
125
126 i2c_cmd_handle_t cmd;
127 if (writeReg) {
128 cmd = i2c_cmd_link_create();
129 i2c_master_start(cmd);
130 i2c_master_write_byte(cmd, (addr << 1) | I2C_MASTER_WRITE, true);
131 i2c_master_write_byte(cmd, reg, true);
132 i2c_master_stop(cmd);
133 ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, pdTICKS_TO_MS(1000));
134 i2c_cmd_link_delete(cmd);
135 if (ret != ESP_OK) {
136 ESP_LOGE(TAG, "i2c_master_cmd_begin failed!");
137 return false;
138 }
139 }
140
141 cmd = i2c_cmd_link_create();
142 i2c_master_start(cmd);
143 i2c_master_write_byte(cmd, (addr << 1) | I2C_MASTER_READ, true);
144 if (len > 1) {
145 i2c_master_read(cmd, buf, len - 1, I2C_MASTER_ACK);
146 }
147 i2c_master_read_byte(cmd, &buf[len - 1], I2C_MASTER_NACK);
148 i2c_master_stop(cmd);
149 ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, pdTICKS_TO_MS(1000));
150 i2c_cmd_link_delete(cmd);
151 if (ret != ESP_OK) {
152 ESP_LOGE(TAG, "i2c_read_error.");
153 }
154#endif
155 return ret == ESP_OK ? true : false;
156
157 }
158}
159
163int i2c_read_callback(uint8_t devAddr, uint8_t regAddr, uint8_t *data, uint8_t len)
164{
165 esp_err_t ret;
166 if (len == 0) {
167 return ESP_OK;
168 }
169 if (data == NULL) {
170 return ESP_FAIL;
171 }
172
173#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)) && defined(CONFIG_SENSORLIB_ESP_IDF_NEW_API)
174
175 ret = i2c_master_transmit_receive(
176 i2c_device,
177 (const uint8_t *)&regAddr,
178 1,
179 data,
180 len,
181 -1);
182#else
183
184 i2c_cmd_handle_t cmd;
185
186 cmd = i2c_cmd_link_create();
187 i2c_master_start(cmd);
188 i2c_master_write_byte(cmd, (devAddr << 1) | I2C_MASTER_WRITE, true);
189 i2c_master_write_byte(cmd, regAddr, true);
190 i2c_master_stop(cmd);
191 ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, pdTICKS_TO_MS(1000));
192 i2c_cmd_link_delete(cmd);
193 if (ret != ESP_OK) {
194 ESP_LOGE(TAG, "i2c_master_cmd_begin failed!");
195 return ESP_FAIL;
196 }
197 cmd = i2c_cmd_link_create();
198 i2c_master_start(cmd);
199 i2c_master_write_byte(cmd, (devAddr << 1) | I2C_MASTER_READ, true);
200 if (len > 1) {
201 i2c_master_read(cmd, data, len - 1, I2C_MASTER_ACK);
202 }
203 i2c_master_read_byte(cmd, &data[len - 1], I2C_MASTER_NACK);
204 i2c_master_stop(cmd);
205 ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, pdTICKS_TO_MS(1000));
206 i2c_cmd_link_delete(cmd);
207 if (ret != ESP_OK) {
208 ESP_LOGE(TAG, "i2c_read_error.");
209 }
210#endif
211 return ret == ESP_OK ? 0 : -1;
212}
213
217int i2c_write_callback(uint8_t devAddr, uint8_t regAddr, uint8_t *data, uint8_t len)
218{
219 esp_err_t ret;
220 if (data == NULL) {
221 return ESP_FAIL;
222 }
223
224#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)) && defined(CONFIG_SENSORLIB_ESP_IDF_NEW_API)
225 uint8_t *write_buffer = (uint8_t *)malloc(sizeof(uint8_t) * (len + 1));
226 if (!write_buffer) {
227 return -1;
228 }
229 write_buffer[0] = regAddr;
230 memcpy(write_buffer + 1, data, len);
231
232 ret = i2c_master_transmit(
233 i2c_device,
234 write_buffer,
235 len + 1,
236 -1);
237 free(write_buffer);
238#else
239 i2c_cmd_handle_t cmd = i2c_cmd_link_create();
240 i2c_master_start(cmd);
241 i2c_master_write_byte(cmd, (devAddr << 1) | I2C_MASTER_WRITE, true);
242 i2c_master_write_byte(cmd, regAddr, true);
243 i2c_master_write(cmd, data, len, true);
244 i2c_master_stop(cmd);
245 ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, pdTICKS_TO_MS(1000));
246 i2c_cmd_link_delete(cmd);
247 if (ret != ESP_OK) {
248 ESP_LOGE(TAG, "i2c_write_error.");
249 }
250#endif
251 return ret == ESP_OK ? 0 : -1;
252}
253
254esp_err_t i2c_drv_device_init(uint8_t address)
255{
256#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)) && defined(CONFIG_SENSORLIB_ESP_IDF_NEW_API)
257 i2c_device_config_t i2c_dev_conf = {
258 .dev_addr_length = I2C_ADDR_BIT_LEN_7,
259 .device_address = address,
260 .scl_speed_hz = I2C_MASTER_FREQ_HZ,
261 };
262 return i2c_master_bus_add_device(bus_handle, &i2c_dev_conf, &i2c_device);
263#else
264 return ESP_OK;
265#endif
266}
267
268#endif //CONFIG_I2C_COMMUNICATION_METHOD_CALLBACK_RW
269
270
274esp_err_t i2c_drv_init(void)
275{
276#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)) && defined(CONFIG_SENSORLIB_ESP_IDF_NEW_API)
277
278 ESP_LOGI(TAG, "Implemented using read and write callback methods (Use higher version >= 5.0 API)");
279
280 i2c_master_bus_config_t i2c_bus_config;
281 memset(&i2c_bus_config, 0, sizeof(i2c_bus_config));
282 i2c_bus_config.clk_source = I2C_CLK_SRC_DEFAULT;
283 i2c_bus_config.i2c_port = I2C_MASTER_NUM;
284 i2c_bus_config.scl_io_num = (gpio_num_t)I2C_MASTER_SCL_IO;
285 i2c_bus_config.sda_io_num = (gpio_num_t)I2C_MASTER_SDA_IO;
286 i2c_bus_config.glitch_ignore_cnt = 7;
287 i2c_bus_config.flags.enable_internal_pullup = true;
288
289 ESP_ERROR_CHECK(i2c_new_master_bus(&i2c_bus_config, &bus_handle));
290
291 return ESP_OK;
292#else
293
294 ESP_LOGI(TAG, "Implemented using read and write callback methods (Use lower version < 5.0 API)");
295
296 i2c_config_t i2c_conf ;
297 memset(&i2c_conf, 0, sizeof(i2c_conf));
298 i2c_conf.mode = I2C_MODE_MASTER;
299 i2c_conf.sda_io_num = I2C_MASTER_SDA_IO;
300 i2c_conf.scl_io_num = I2C_MASTER_SCL_IO;
301 i2c_conf.sda_pullup_en = GPIO_PULLUP_ENABLE;
302 i2c_conf.scl_pullup_en = GPIO_PULLUP_ENABLE;
303 i2c_conf.master.clk_speed = I2C_MASTER_FREQ_HZ;
304 i2c_param_config(I2C_MASTER_NUM, &i2c_conf);
305 return i2c_driver_install(I2C_MASTER_NUM, i2c_conf.mode, I2C_MASTER_RX_BUF_DISABLE, I2C_MASTER_TX_BUF_DISABLE, 0);
306#endif
307}
308
309void i2c_drv_scan()
310{
311#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)) && defined(CONFIG_SENSORLIB_ESP_IDF_NEW_API)
312
313 esp_err_t err = ESP_OK;
314 uint8_t address = 0x00;
315 printf("Scan I2C Devices:\n");
316 printf(" 0 1 2 3 4 5 6 7 8 9 a b c d e f\r\n");
317 for (int i = 0; i < 128; i += 16) {
318 printf("%02x: ", i);
319 for (int j = 0; j < 16; j++) {
320 fflush(stdout);
321 address = i + j;
322 err = i2c_master_probe(bus_handle, address, 100);
323 if (err == ESP_OK) {
324 printf("%02x ", address);
325 } else if (err == ESP_ERR_TIMEOUT) {
326 printf("UU ");
327 } else {
328 printf("-- ");
329 }
330 }
331 printf("\r\n");
332 }
333 printf("\n\n\n");
334#else
335 uint8_t address;
336 printf("Scan I2C Devices:\n");
337 printf(" 0 1 2 3 4 5 6 7 8 9 a b c d e f\r\n");
338 for (int i = 0; i < 128; i += 16) {
339 printf("%02x: ", i);
340 for (int j = 0; j < 16; j++) {
341 fflush(stdout);
342 address = i + j;
343 i2c_cmd_handle_t cmd = i2c_cmd_link_create();
344 i2c_master_start(cmd);
345 i2c_master_write_byte(cmd, (address << 1) | I2C_MASTER_WRITE, true);
346 i2c_master_stop(cmd);
347 esp_err_t ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, 50 / portTICK_PERIOD_MS);
348 i2c_cmd_link_delete(cmd);
349 if (ret == ESP_OK) {
350 printf("%02x ", address);
351 } else if (ret == ESP_ERR_TIMEOUT) {
352 printf("UU ");
353 } else {
354 printf("-- ");
355 }
356 }
357 printf("\r\n");
358 }
359#endif
360}
361
362bool i2c_drv_probe(uint8_t devAddr)
363{
364#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)) && defined(CONFIG_SENSORLIB_ESP_IDF_NEW_API)
365 return ESP_OK == i2c_master_probe(bus_handle, devAddr, 1000);
366#else
367 i2c_cmd_handle_t cmd = i2c_cmd_link_create();
368 i2c_master_start(cmd);
369 i2c_master_write_byte(cmd, (devAddr << 1) | I2C_MASTER_WRITE, true);
370 i2c_master_stop(cmd);
371 esp_err_t ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, 50 / portTICK_PERIOD_MS);
372 i2c_cmd_link_delete(cmd);
373 return (ret == ESP_OK);
374#endif //ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)
375}
376
377
378#endif
bool i2c_wr_function(uint8_t addr, uint8_t reg, uint8_t *buf, size_t len, bool writeReg, bool isWrite)
#define I2C_MASTER_SCL_IO
esp_err_t i2c_drv_init(void)
i2c master initialization
#define I2C_MASTER_RX_BUF_DISABLE
bool i2c_drv_probe(uint8_t devAddr)
#define I2C_MASTER_FREQ_HZ
#define I2C_MASTER_TX_BUF_DISABLE
#define I2C_MASTER_SDA_IO
@license MIT License
int i2c_write_callback(uint8_t devAddr, uint8_t regAddr, uint8_t *data, uint8_t len)
int i2c_read_callback(uint8_t devAddr, uint8_t regAddr, uint8_t *data, uint8_t len)
uint8_t i
char buf[64]