-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathi2c_device_hal.c
121 lines (103 loc) · 3.61 KB
/
i2c_device_hal.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
#include <inttypes.h>
#include "i2c_device_hal.h"
#include "i2c_device.h"
// Return i2c handle for read and write, -1 mean error
int i2c_dev_init(int i2c_num, i2c_port_obj_t* port_obj) {
esp_err_t err = ESP_FAIL;
i2c_config_t conf = {
.mode = I2C_MODE_MASTER,
.sda_io_num = port_obj->sda,
.sda_pullup_en = GPIO_PULLUP_ENABLE,
.scl_io_num = port_obj->scl,
.scl_pullup_en = GPIO_PULLUP_ENABLE,
.master.clk_speed = port_obj->freq,
};
err = i2c_param_config(i2c_num, &conf);
err |= i2c_driver_install(i2c_num, I2C_MODE_MASTER, 0, 0, 0);
if (err == ESP_OK && port_obj->timeout > 0) {
i2c_set_timeout(i2c_num, port_obj->timeout);
}
return err == ESP_OK ? i2c_num : -1;
}
int i2c_dev_update_pins(int i2c_num, i2c_port_obj_t* select_port, i2c_port_obj_t* old_port) {
if (old_port) {
gpio_reset_pin(old_port->scl);
gpio_reset_pin(old_port->sda);
}
i2c_config_t conf = {
.mode = I2C_MODE_MASTER,
.sda_io_num = select_port->sda,
.sda_pullup_en = GPIO_PULLUP_ENABLE,
.scl_io_num = select_port->scl,
.scl_pullup_en = GPIO_PULLUP_ENABLE,
.master.clk_speed = select_port->freq,
};
if (i2c_param_config(i2c_num, &conf) != ESP_OK) {
return -1;
}
return select_port->port;
}
int i2c_dev_update_freq(int i2c_num, i2c_port_obj_t* port_obj) {
i2c_config_t conf = {
.mode = I2C_MODE_MASTER,
.sda_io_num = port_obj->sda,
.sda_pullup_en = GPIO_PULLUP_ENABLE,
.scl_io_num = port_obj->scl,
.scl_pullup_en = GPIO_PULLUP_ENABLE,
.master.clk_speed = port_obj->freq,
};
if (i2c_param_config(i2c_num, &conf) != ESP_OK) {
return -1;
}
return port_obj->port;
}
int i2c_dev_deinit(int i2c_port) {
// not support now
return -1;
}
// reg len (byte): 0, 1, 2
// data: NULL or data
// return:
int i2c_dev_write_bytes(int i2c_port, uint8_t device_addr, uint32_t reg_addr, uint8_t reg_len, const uint8_t *data, uint16_t length) {
if (i2c_port == I2C_PORT_NO_INIT || (length > 0 && data == NULL)) {
return I2C_FAIL;
}
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, (device_addr << 1) | I2C_MASTER_WRITE, 1);
if (reg_len) {
i2c_master_write(cmd, (uint8_t *)®_addr, reg_len, 1);
}
if (length) {
i2c_master_write(cmd, data, length, 1);
}
i2c_master_stop(cmd);
esp_err_t err = ESP_FAIL;
err = i2c_master_cmd_begin(i2c_port, cmd, pdMS_TO_TICKS(I2C_TIMEOUT_MS));
i2c_cmd_link_delete(cmd);
return err == ESP_OK ? I2C_OK : err;
}
int i2c_dev_read_bytes(int i2c_port, uint8_t device_addr, uint32_t reg_addr, uint8_t reg_len, uint8_t *data, uint16_t length) {
if (i2c_port == I2C_PORT_NO_INIT || (length > 0 && data == NULL)) {
return I2C_FAIL;
}
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
if (reg_len) {
i2c_master_start(cmd);
i2c_master_write_byte(cmd, (device_addr << 1) | I2C_MASTER_WRITE, 1);
i2c_master_write(cmd, (uint8_t *)®_addr, reg_len, 1);
}
i2c_master_start(cmd);
i2c_master_write_byte(cmd, (device_addr << 1) | I2C_MASTER_READ, 1);
if (length > 1) {
i2c_master_read(cmd, data, length - 1, I2C_MASTER_ACK);
}
if (length > 0) {
i2c_master_read_byte(cmd, &data[length-1], I2C_MASTER_NACK);
}
i2c_master_stop(cmd);
esp_err_t err = ESP_FAIL;
err = i2c_master_cmd_begin(i2c_port, cmd, pdMS_TO_TICKS(I2C_TIMEOUT_MS));
i2c_cmd_link_delete(cmd);
return err == ESP_OK ? I2C_OK : err;
}