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 )
27
-
28
- /* Default register value on power-up */
29
- #define DIR_REG_DEFAULT_VAL (0xff )
30
- #define OUT_REG_DEFAULT_VAL (0xdf )
25
+ #define CH422G_REG_WR_SET (0x48 >> 1 )
26
+ #define CH422G_REG_WR_OC (0x46 >> 1 )
27
+ #define CH422G_REG_WR_IO (0x70 >> 1 )
28
+ #define CH422G_REG_RD_IO (0x4D >> 1 )
29
+
30
+ /* Default register value when reset */
31
+ // *INDENT-OFF*
32
+ #define REG_WR_SET_DEFAULT_VAL (0x01UL ) // 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 | 1 |
37
+ // *INDENT-OFF*
38
+ #define REG_WR_OC_DEFAULT_VAL (0x0FUL )
39
+ #define REG_WR_IO_DEFAULT_VAL (0xFFUL )
40
+ #define REG_OUT_DEFAULT_VAL ((REG_WR_OC_DEFAULT_VAL << 8 ) | REG_WR_IO_DEFAULT_VAL)
41
+ #define REG_DIR_DEFAULT_VAL (0xFFUL )
42
+
43
+ #define REG_WR_SET_BIT_IO_OE (1 << 0 )
44
+ #define REG_WR_SET_BIT_OD_EN (1 << 4 )
31
45
32
46
/* *
33
47
* @brief Device Structure Type
@@ -38,14 +52,22 @@ typedef struct {
38
52
i2c_port_t i2c_num;
39
53
uint32_t i2c_address;
40
54
struct {
41
- uint8_t direction;
42
- uint8_t output;
55
+ uint8_t wr_set;
56
+ uint8_t wr_oc;
57
+ uint8_t wr_io;
43
58
} regs;
44
59
} esp_io_expander_ch422g_t ;
45
60
46
61
static const char *TAG = " ch422g" ;
47
62
48
63
static esp_err_t esp_io_expander_new_i2c_ch422g (i2c_port_t i2c_num, uint32_t i2c_address, esp_io_expander_handle_t *handle);
64
+ static esp_err_t read_input_reg (esp_io_expander_handle_t handle, uint32_t *value);
65
+ static esp_err_t write_output_reg (esp_io_expander_handle_t handle, uint32_t value);
66
+ static esp_err_t read_output_reg (esp_io_expander_handle_t handle, uint32_t *value);
67
+ static esp_err_t write_direction_reg (esp_io_expander_handle_t handle, uint32_t value);
68
+ static esp_err_t read_direction_reg (esp_io_expander_handle_t handle, uint32_t *value);
69
+ static esp_err_t reset (esp_io_expander_t *handle);
70
+ static esp_err_t del (esp_io_expander_t *handle);
49
71
50
72
ESP_IOExpander_CH422G::~ESP_IOExpander_CH422G ()
51
73
{
@@ -62,13 +84,29 @@ void ESP_IOExpander_CH422G::begin(void)
62
84
CHECK_ERROR_RETURN (esp_io_expander_new_i2c_ch422g (i2c_id, i2c_address, &handle));
63
85
}
64
86
65
- static esp_err_t read_input_reg (esp_io_expander_handle_t handle, uint32_t *value);
66
- static esp_err_t write_output_reg (esp_io_expander_handle_t handle, uint32_t value);
67
- static esp_err_t read_output_reg (esp_io_expander_handle_t handle, uint32_t *value);
68
- static esp_err_t write_direction_reg (esp_io_expander_handle_t handle, uint32_t value);
69
- static esp_err_t read_direction_reg (esp_io_expander_handle_t handle, uint32_t *value);
70
- static esp_err_t reset (esp_io_expander_t *handle);
71
- static esp_err_t del (esp_io_expander_t *handle);
87
+ void ESP_IOExpander_CH422G::enableOC_OpenDrain (void )
88
+ {
89
+ esp_io_expander_ch422g_t *ch422g = (esp_io_expander_ch422g_t *)__containerof (handle, esp_io_expander_ch422g_t , base);
90
+ uint8_t data = (uint8_t )(ch422g->regs .wr_set | REG_WR_SET_BIT_OD_EN);
91
+
92
+ // WR-SET
93
+ CHECK_ERROR_RETURN (
94
+ i2c_master_write_to_device (ch422g->i2c_num , CH422G_REG_WR_SET, &data, sizeof (data), pdMS_TO_TICKS (I2C_TIMEOUT_MS))
95
+ );
96
+ ch422g->regs .wr_set = data;
97
+ }
98
+
99
+ void ESP_IOExpander_CH422G::enableOC_PushPull (void )
100
+ {
101
+ esp_io_expander_ch422g_t *ch422g = (esp_io_expander_ch422g_t *)__containerof (handle, esp_io_expander_ch422g_t , base);
102
+ uint8_t data = (uint8_t )(ch422g->regs .wr_set & ~REG_WR_SET_BIT_OD_EN);
103
+
104
+ // WR-SET
105
+ CHECK_ERROR_RETURN (
106
+ i2c_master_write_to_device (ch422g->i2c_num , CH422G_REG_WR_SET, &data, sizeof (data), pdMS_TO_TICKS (I2C_TIMEOUT_MS))
107
+ );
108
+ ch422g->regs .wr_set = data;
109
+ }
72
110
73
111
static esp_err_t esp_io_expander_new_i2c_ch422g (i2c_port_t i2c_num, uint32_t i2c_address, esp_io_expander_handle_t *handle)
74
112
{
@@ -82,7 +120,9 @@ static esp_err_t esp_io_expander_new_i2c_ch422g(i2c_port_t i2c_num, uint32_t i2c
82
120
ch422g->base .config .flags .dir_out_bit_zero = 1 ;
83
121
ch422g->i2c_num = i2c_num;
84
122
ch422g->i2c_address = i2c_address;
85
- ch422g->regs .output = OUT_REG_DEFAULT_VAL;
123
+ ch422g->regs .wr_set = REG_WR_SET_DEFAULT_VAL;
124
+ ch422g->regs .wr_oc = REG_WR_OC_DEFAULT_VAL;
125
+ ch422g->regs .wr_io = REG_WR_IO_DEFAULT_VAL;
86
126
ch422g->base .read_input_reg = read_input_reg;
87
127
ch422g->base .write_output_reg = write_output_reg;
88
128
ch422g->base .read_output_reg = read_output_reg;
@@ -105,67 +145,93 @@ static esp_err_t esp_io_expander_new_i2c_ch422g(i2c_port_t i2c_num, uint32_t i2c
105
145
static esp_err_t read_input_reg (esp_io_expander_handle_t handle, uint32_t *value)
106
146
{
107
147
esp_io_expander_ch422g_t *ch422g = (esp_io_expander_ch422g_t *)__containerof (handle, esp_io_expander_ch422g_t , base);
108
-
109
148
uint8_t temp = 0 ;
110
149
111
150
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*
151
+ i2c_master_read_from_device (ch422g->i2c_num , CH422G_REG_RD_IO, &temp, 1 , pdMS_TO_TICKS (I2C_TIMEOUT_MS)),
152
+ TAG, " Read RD-IO reg failed"
153
+ );
120
154
*value = temp;
155
+
121
156
return ESP_OK;
122
157
}
123
158
124
159
static esp_err_t write_output_reg (esp_io_expander_handle_t handle, uint32_t value)
125
160
{
126
161
esp_io_expander_ch422g_t *ch422g = (esp_io_expander_ch422g_t *)__containerof (handle, esp_io_expander_ch422g_t , base);
127
- value &= 0xff ;
128
162
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" );
163
+ uint8_t wr_oc_data = (value & 0xF00 ) >> 8 ;
164
+ uint8_t wr_io_data = value & 0xFF ;
165
+
166
+ // WR-OC
167
+ if (wr_oc_data) {
168
+ ESP_RETURN_ON_ERROR (
169
+ i2c_master_write_to_device (ch422g->i2c_num , CH422G_REG_WR_OC, &wr_oc_data, sizeof (wr_oc_data), pdMS_TO_TICKS (I2C_TIMEOUT_MS)),
170
+ TAG, " Write WR-OC reg failed"
171
+ );
172
+ ch422g->regs .wr_oc = wr_oc_data;
173
+ }
174
+
175
+ // WR-IO
176
+ if (wr_io_data) {
177
+ ESP_RETURN_ON_ERROR (
178
+ i2c_master_write_to_device (ch422g->i2c_num , CH422G_REG_WR_IO, &wr_io_data, sizeof (wr_io_data), pdMS_TO_TICKS (I2C_TIMEOUT_MS)),
179
+ TAG, " Write WR-IO reg failed"
180
+ );
181
+ ch422g->regs .wr_io = wr_io_data;
182
+ }
133
183
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
184
return ESP_OK;
140
185
}
141
186
142
187
static esp_err_t read_output_reg (esp_io_expander_handle_t handle, uint32_t *value)
143
188
{
144
189
esp_io_expander_ch422g_t *ch422g = (esp_io_expander_ch422g_t *)__containerof (handle, esp_io_expander_ch422g_t , base);
145
190
146
- *value = ch422g->regs .output ;
191
+ *value = ch422g->regs .wr_io | (((uint32_t )ch422g->regs .wr_oc ) << 8 );
192
+
147
193
return ESP_OK;
148
194
}
149
195
150
196
static esp_err_t write_direction_reg (esp_io_expander_handle_t handle, uint32_t value)
151
197
{
152
198
esp_io_expander_ch422g_t *ch422g = (esp_io_expander_ch422g_t *)__containerof (handle, esp_io_expander_ch422g_t , base);
153
- value &= 0xff ;
154
- ch422g->regs .direction = value;
199
+ uint8_t data = ch422g->regs .wr_set ;
200
+
201
+ value &= 0xFF ;
202
+ if (value > 0 ) {
203
+ data |= REG_WR_SET_BIT_IO_OE;
204
+ } else {
205
+ data &= ~REG_WR_SET_BIT_IO_OE;
206
+ }
207
+
208
+ // WR-SET
209
+ ESP_RETURN_ON_ERROR (
210
+ i2c_master_write_to_device (ch422g->i2c_num , CH422G_REG_WR_SET, &data, sizeof (data), pdMS_TO_TICKS (I2C_TIMEOUT_MS)),
211
+ TAG, " Write WR_SET reg failed"
212
+ );
213
+ ch422g->regs .wr_set = data;
214
+
155
215
return ESP_OK;
156
216
}
157
217
218
+ #define DIR_OUT_VALUE (0xFFF )
219
+ #define DIR_IN_VALUE (0xF00 )
220
+
158
221
static esp_err_t read_direction_reg (esp_io_expander_handle_t handle, uint32_t *value)
159
222
{
160
223
esp_io_expander_ch422g_t *ch422g = (esp_io_expander_ch422g_t *)__containerof (handle, esp_io_expander_ch422g_t , base);
161
224
162
- *value = ch422g->regs .direction ;
225
+ *value = (ch422g->regs .wr_set & REG_WR_SET_BIT_IO_OE) ? DIR_OUT_VALUE : DIR_IN_VALUE;
226
+
163
227
return ESP_OK;
164
228
}
165
229
166
230
static esp_err_t reset (esp_io_expander_t *handle)
167
231
{
168
- ESP_RETURN_ON_ERROR (write_output_reg (handle, OUT_REG_DEFAULT_VAL), TAG, " Write output reg failed" );
232
+ ESP_RETURN_ON_ERROR (write_direction_reg (handle, REG_DIR_DEFAULT_VAL), TAG, " Write direction reg (WR_SET) failed" );
233
+ ESP_RETURN_ON_ERROR (write_output_reg (handle, REG_OUT_DEFAULT_VAL), TAG, " Write output reg (WR_OC & WR_IO) failed" );
234
+
169
235
return ESP_OK;
170
236
}
171
237
@@ -174,5 +240,6 @@ static esp_err_t del(esp_io_expander_t *handle)
174
240
esp_io_expander_ch422g_t *ch422g = (esp_io_expander_ch422g_t *)__containerof (handle, esp_io_expander_ch422g_t , base);
175
241
176
242
free (ch422g);
243
+
177
244
return ESP_OK;
178
245
}
0 commit comments