19
19
/* Timeout of each I2C communication */
20
20
#define I2C_TIMEOUT_MS (10 )
21
21
22
- #define IO_COUNT (8 )
22
+ #define IO_COUNT (12 )
23
23
24
24
/* Register address */
25
- #define CH422G_REG_IN (0x26 )
26
- #define CH422G_REG_OUT (0x38 )
25
+ #define CH422G_REG_WR_SET (0x48 )
26
+ #define CH422G_REG_WR_OC (0x46 )
27
+ #define CH422G_REG_WR_IO (0x70 )
28
+ #define CH422G_REG_RD_IO (0x4D )
27
29
28
30
/* Default register value on power-up */
29
- #define DIR_REG_DEFAULT_VAL (0xff )
30
- #define OUT_REG_DEFAULT_VAL (0xdf )
31
+ // *INDENT-OFF*
32
+ #define REG_WR_SET_DEFAULT_VAL (0x00UL ) // Bit: | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
33
+ // |---------|---|---|---------|---|----------|---|---------|
34
+ // Value: | [SLEEP] | 0 | 0 | [OD_EN] | 0 | [A_SCAN] | 0 | [IO_OE] |
35
+ // |---------|---|---|---------|---|----------|---|---------|
36
+ // Default: | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
37
+ // *INDENT-OFF*
38
+ #define REG_WR_OC_DEFAULT_VAL (0x00UL )
39
+ #define REG_WR_IO_DEFAULT_VAL (0x00UL )
40
+ #define REG_OUT_DEFAULT_VAL (REG_WR_OC_DEFAULT_VAL << 8 | REG_WR_IO_DEFAULT_VAL)
41
+
42
+ #define REG_WR_SET_BIT_IO_OE (1 << 0 )
43
+ #define REG_WR_SET_BIT_OD_EN (1 << 4 )
31
44
32
45
/* *
33
46
* @brief Device Structure Type
@@ -38,8 +51,9 @@ typedef struct {
38
51
i2c_port_t i2c_num;
39
52
uint32_t i2c_address;
40
53
struct {
41
- uint8_t direction;
42
- uint8_t output;
54
+ uint8_t wr_set;
55
+ uint8_t wr_oc;
56
+ uint8_t wr_io;
43
57
} regs;
44
58
} esp_io_expander_ch422g_t ;
45
59
@@ -62,6 +76,32 @@ void ESP_IOExpander_CH422G::begin(void)
62
76
CHECK_ERROR_RETURN (esp_io_expander_new_i2c_ch422g (i2c_id, i2c_address, &handle));
63
77
}
64
78
79
+ void ESP_IOExpander_CH422G::enableOC_OpenDrain (void )
80
+ {
81
+ esp_io_expander_ch422g_t *ch422g = (esp_io_expander_ch422g_t *)__containerof (handle, esp_io_expander_ch422g_t , base);
82
+
83
+ uint8_t data[2 ] = {CH422G_REG_WR_SET, (uint8_t )(ch422g->regs .wr_set | REG_WR_SET_BIT_OD_EN)};
84
+
85
+ // WR-SET
86
+ CHECK_ERROR_RETURN (
87
+ i2c_master_write_to_device (ch422g->i2c_num , ch422g->i2c_address , data, sizeof (data), pdMS_TO_TICKS (I2C_TIMEOUT_MS))
88
+ );
89
+ ch422g->regs .wr_set = data[1 ];
90
+ }
91
+
92
+ void ESP_IOExpander_CH422G::enableOC_PushPull (void )
93
+ {
94
+ esp_io_expander_ch422g_t *ch422g = (esp_io_expander_ch422g_t *)__containerof (handle, esp_io_expander_ch422g_t , base);
95
+
96
+ uint8_t data[2 ] = {CH422G_REG_WR_SET, (uint8_t )(ch422g->regs .wr_set & ~REG_WR_SET_BIT_OD_EN)};
97
+
98
+ // WR-SET
99
+ CHECK_ERROR_RETURN (
100
+ i2c_master_write_to_device (ch422g->i2c_num , ch422g->i2c_address , data, sizeof (data), pdMS_TO_TICKS (I2C_TIMEOUT_MS))
101
+ );
102
+ ch422g->regs .wr_set = data[1 ];
103
+ }
104
+
65
105
static esp_err_t read_input_reg (esp_io_expander_handle_t handle, uint32_t *value);
66
106
static esp_err_t write_output_reg (esp_io_expander_handle_t handle, uint32_t value);
67
107
static esp_err_t read_output_reg (esp_io_expander_handle_t handle, uint32_t *value);
@@ -82,7 +122,9 @@ static esp_err_t esp_io_expander_new_i2c_ch422g(i2c_port_t i2c_num, uint32_t i2c
82
122
ch422g->base .config .flags .dir_out_bit_zero = 1 ;
83
123
ch422g->i2c_num = i2c_num;
84
124
ch422g->i2c_address = i2c_address;
85
- ch422g->regs .output = OUT_REG_DEFAULT_VAL;
125
+ ch422g->regs .wr_set = REG_WR_SET_DEFAULT_VAL;
126
+ ch422g->regs .wr_oc = REG_WR_OC_DEFAULT_VAL;
127
+ ch422g->regs .wr_io = REG_WR_IO_DEFAULT_VAL;
86
128
ch422g->base .read_input_reg = read_input_reg;
87
129
ch422g->base .write_output_reg = write_output_reg;
88
130
ch422g->base .read_output_reg = read_output_reg;
@@ -107,65 +149,99 @@ static esp_err_t read_input_reg(esp_io_expander_handle_t handle, uint32_t *value
107
149
esp_io_expander_ch422g_t *ch422g = (esp_io_expander_ch422g_t *)__containerof (handle, esp_io_expander_ch422g_t , base);
108
150
109
151
uint8_t temp = 0 ;
152
+ uint8_t reg = CH422G_REG_RD_IO;
110
153
111
154
ESP_RETURN_ON_ERROR (
112
- i2c_master_read_from_device (ch422g->i2c_num , ch422g->i2c_address , &temp, 1 , pdMS_TO_TICKS (I2C_TIMEOUT_MS)),
113
- TAG, " Read input reg failed" );
114
-
115
- // *INDENT-OFF*
116
- ESP_RETURN_ON_ERROR (
117
- i2c_master_read_from_device (ch422g->i2c_num , CH422G_REG_IN, &temp, 1 , pdMS_TO_TICKS (I2C_TIMEOUT_MS)),
118
- TAG, " Read input reg failed" );
119
- // *INDENT-ON*
155
+ i2c_master_write_read_device (ch422g->i2c_num , ch422g->i2c_address , ®, 1 , &temp, 1 , pdMS_TO_TICKS (I2C_TIMEOUT_MS)),
156
+ TAG, " Read RD-IO reg failed"
157
+ );
120
158
*value = temp;
159
+
121
160
return ESP_OK;
122
161
}
123
162
124
163
static esp_err_t write_output_reg (esp_io_expander_handle_t handle, uint32_t value)
125
164
{
126
165
esp_io_expander_ch422g_t *ch422g = (esp_io_expander_ch422g_t *)__containerof (handle, esp_io_expander_ch422g_t , base);
127
- value &= 0xff ;
128
166
129
- uint8_t out_temp = 0x01 ;
130
- ESP_RETURN_ON_ERROR (
131
- i2c_master_write_to_device (ch422g->i2c_num , ch422g->i2c_address , &out_temp, 1 , pdMS_TO_TICKS (I2C_TIMEOUT_MS)),
132
- TAG, " Write output reg failed" );
167
+ uint8_t wr_oc_data = (value & 0xf00 ) >> 8 ;
168
+ uint8_t wr_io_data = value & 0xff ;
169
+ uint8_t data[2 ] = {};
170
+
171
+ // WR-OC
172
+ if (wr_oc_data) {
173
+ data[0 ] = CH422G_REG_WR_OC;
174
+ data[1 ] = wr_oc_data;
175
+ ESP_RETURN_ON_ERROR (
176
+ i2c_master_write_to_device (ch422g->i2c_num , ch422g->i2c_address , data, sizeof (data), pdMS_TO_TICKS (I2C_TIMEOUT_MS)),
177
+ TAG, " Write WR-OC reg failed"
178
+ );
179
+ ch422g->regs .wr_oc = wr_oc_data;
180
+ }
181
+
182
+ // WR-IO
183
+ if (wr_io_data) {
184
+ data[0 ] = CH422G_REG_WR_IO;
185
+ data[1 ] = wr_io_data;
186
+ ESP_RETURN_ON_ERROR (
187
+ i2c_master_write_to_device (ch422g->i2c_num , ch422g->i2c_address , data, sizeof (data), pdMS_TO_TICKS (I2C_TIMEOUT_MS)),
188
+ TAG, " Write WR-IO reg failed"
189
+ );
190
+ ch422g->regs .wr_io = wr_io_data;
191
+ }
133
192
134
- uint8_t data = (uint8_t )value;
135
- ESP_RETURN_ON_ERROR (
136
- i2c_master_write_to_device (ch422g->i2c_num , CH422G_REG_OUT, &data, 1 , pdMS_TO_TICKS (I2C_TIMEOUT_MS)),
137
- TAG, " Write output reg failed" );
138
- ch422g->regs .output = value;
139
193
return ESP_OK;
140
194
}
141
195
142
196
static esp_err_t read_output_reg (esp_io_expander_handle_t handle, uint32_t *value)
143
197
{
144
198
esp_io_expander_ch422g_t *ch422g = (esp_io_expander_ch422g_t *)__containerof (handle, esp_io_expander_ch422g_t , base);
145
199
146
- *value = ch422g->regs .output ;
200
+ *value = ch422g->regs .wr_io | (((uint32_t )ch422g->regs .wr_oc ) << 8 );
201
+
147
202
return ESP_OK;
148
203
}
149
204
150
205
static esp_err_t write_direction_reg (esp_io_expander_handle_t handle, uint32_t value)
151
206
{
152
207
esp_io_expander_ch422g_t *ch422g = (esp_io_expander_ch422g_t *)__containerof (handle, esp_io_expander_ch422g_t , base);
153
208
value &= 0xff ;
154
- ch422g->regs .direction = value;
209
+
210
+ uint8_t data[2 ] = {CH422G_REG_WR_SET, ch422g->regs .wr_set };
211
+
212
+ if (value > 0 ) {
213
+ data[1 ] |= REG_WR_SET_BIT_IO_OE;
214
+ } else {
215
+ data[1 ] &= ~REG_WR_SET_BIT_IO_OE;
216
+ }
217
+
218
+ // WR-SET
219
+ ESP_RETURN_ON_ERROR (
220
+ i2c_master_write_to_device (ch422g->i2c_num , ch422g->i2c_address , data, sizeof (data), pdMS_TO_TICKS (I2C_TIMEOUT_MS)),
221
+ TAG, " Write WR_SET reg failed"
222
+ );
223
+ ch422g->regs .wr_set = data[1 ];
224
+
155
225
return ESP_OK;
156
226
}
157
227
228
+ #define DIR_OUT_VALUE (0xFFF )
229
+ #define DIR_IN_VALUE (0xF00 )
230
+
158
231
static esp_err_t read_direction_reg (esp_io_expander_handle_t handle, uint32_t *value)
159
232
{
160
233
esp_io_expander_ch422g_t *ch422g = (esp_io_expander_ch422g_t *)__containerof (handle, esp_io_expander_ch422g_t , base);
161
234
162
- *value = ch422g->regs .direction ;
235
+ *value = (ch422g->regs .wr_set & REG_WR_SET_BIT_IO_OE) ? DIR_OUT_VALUE : DIR_IN_VALUE;
236
+
163
237
return ESP_OK;
164
238
}
165
239
166
240
static esp_err_t reset (esp_io_expander_t *handle)
167
241
{
168
- ESP_RETURN_ON_ERROR (write_output_reg (handle, OUT_REG_DEFAULT_VAL), TAG, " Write output reg failed" );
242
+ ESP_RETURN_ON_ERROR (write_direction_reg (handle, REG_WR_SET_DEFAULT_VAL), TAG, " Write direction reg (WR_SET) failed" );
243
+ ESP_RETURN_ON_ERROR (write_output_reg (handle, REG_OUT_DEFAULT_VAL), TAG, " Write output reg (WR_OC & WR_IO) failed" );
244
+
169
245
return ESP_OK;
170
246
}
171
247
@@ -174,5 +250,6 @@ static esp_err_t del(esp_io_expander_t *handle)
174
250
esp_io_expander_ch422g_t *ch422g = (esp_io_expander_ch422g_t *)__containerof (handle, esp_io_expander_ch422g_t , base);
175
251
176
252
free (ch422g);
253
+
177
254
return ESP_OK;
178
255
}
0 commit comments