1919/* Timeout of each I2C communication */
2020#define I2C_TIMEOUT_MS (10 )
2121
22- #define IO_COUNT (8 )
22+ #define IO_COUNT (12 )
2323
2424/* 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 )
3145
3246/* *
3347 * @brief Device Structure Type
@@ -38,14 +52,22 @@ typedef struct {
3852 i2c_port_t i2c_num;
3953 uint32_t i2c_address;
4054 struct {
41- uint8_t direction;
42- uint8_t output;
55+ uint8_t wr_set;
56+ uint8_t wr_oc;
57+ uint8_t wr_io;
4358 } regs;
4459} esp_io_expander_ch422g_t ;
4560
4661static const char *TAG = " ch422g" ;
4762
4863static 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);
4971
5072ESP_IOExpander_CH422G::~ESP_IOExpander_CH422G ()
5173{
@@ -62,13 +84,29 @@ void ESP_IOExpander_CH422G::begin(void)
6284 CHECK_ERROR_RETURN (esp_io_expander_new_i2c_ch422g (i2c_id, i2c_address, &handle));
6385}
6486
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+ }
72110
73111static esp_err_t esp_io_expander_new_i2c_ch422g (i2c_port_t i2c_num, uint32_t i2c_address, esp_io_expander_handle_t *handle)
74112{
@@ -82,7 +120,9 @@ static esp_err_t esp_io_expander_new_i2c_ch422g(i2c_port_t i2c_num, uint32_t i2c
82120 ch422g->base .config .flags .dir_out_bit_zero = 1 ;
83121 ch422g->i2c_num = i2c_num;
84122 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;
86126 ch422g->base .read_input_reg = read_input_reg;
87127 ch422g->base .write_output_reg = write_output_reg;
88128 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
105145static esp_err_t read_input_reg (esp_io_expander_handle_t handle, uint32_t *value)
106146{
107147 esp_io_expander_ch422g_t *ch422g = (esp_io_expander_ch422g_t *)__containerof (handle, esp_io_expander_ch422g_t , base);
108-
109148 uint8_t temp = 0 ;
110149
111150 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+ );
120154 *value = temp;
155+
121156 return ESP_OK;
122157}
123158
124159static esp_err_t write_output_reg (esp_io_expander_handle_t handle, uint32_t value)
125160{
126161 esp_io_expander_ch422g_t *ch422g = (esp_io_expander_ch422g_t *)__containerof (handle, esp_io_expander_ch422g_t , base);
127- value &= 0xff ;
128162
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+ }
133183
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;
139184 return ESP_OK;
140185}
141186
142187static esp_err_t read_output_reg (esp_io_expander_handle_t handle, uint32_t *value)
143188{
144189 esp_io_expander_ch422g_t *ch422g = (esp_io_expander_ch422g_t *)__containerof (handle, esp_io_expander_ch422g_t , base);
145190
146- *value = ch422g->regs .output ;
191+ *value = ch422g->regs .wr_io | (((uint32_t )ch422g->regs .wr_oc ) << 8 );
192+
147193 return ESP_OK;
148194}
149195
150196static esp_err_t write_direction_reg (esp_io_expander_handle_t handle, uint32_t value)
151197{
152198 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+
155215 return ESP_OK;
156216}
157217
218+ #define DIR_OUT_VALUE (0xFFF )
219+ #define DIR_IN_VALUE (0xF00 )
220+
158221static esp_err_t read_direction_reg (esp_io_expander_handle_t handle, uint32_t *value)
159222{
160223 esp_io_expander_ch422g_t *ch422g = (esp_io_expander_ch422g_t *)__containerof (handle, esp_io_expander_ch422g_t , base);
161224
162- *value = ch422g->regs .direction ;
225+ *value = (ch422g->regs .wr_set & REG_WR_SET_BIT_IO_OE) ? DIR_OUT_VALUE : DIR_IN_VALUE;
226+
163227 return ESP_OK;
164228}
165229
166230static esp_err_t reset (esp_io_expander_t *handle)
167231{
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+
169235 return ESP_OK;
170236}
171237
@@ -174,5 +240,6 @@ static esp_err_t del(esp_io_expander_t *handle)
174240 esp_io_expander_ch422g_t *ch422g = (esp_io_expander_ch422g_t *)__containerof (handle, esp_io_expander_ch422g_t , base);
175241
176242 free (ch422g);
243+
177244 return ESP_OK;
178245}
0 commit comments