@@ -36,7 +36,7 @@ tcal9539_write_shadow(tcal9539_t *tc, unsigned int line,
36
36
uint16_t shadow , int reg )
37
37
{
38
38
if (line < 8 ) {
39
- return i2c_write_u8 (tc -> i2c , tc -> address , reg , shadow && 0xff );
39
+ return i2c_write_u8 (tc -> i2c , tc -> address , reg , shadow & 0xff );
40
40
} else {
41
41
return i2c_write_u8 (tc -> i2c , tc -> address , reg + 1 , shadow >> 8 );
42
42
}
@@ -109,38 +109,44 @@ tcal9539_conf_input(indirect_gpio_t *ig, unsigned int line, gpio_pull_t pull)
109
109
110
110
111
111
static error_t
112
- tcal9539_conf_output (indirect_gpio_t * ig , unsigned int line ,
113
- gpio_output_type_t type , gpio_output_speed_t speed ,
114
- gpio_pull_t pull )
112
+ tcal9539_set_pin (indirect_gpio_t * ig , unsigned int line , int on )
115
113
{
116
114
tcal9539_t * tc = (tcal9539_t * )ig ;
117
115
118
116
if (line >= 16 )
119
117
return ERR_INVALID_ID ;
120
118
121
- error_t err = tcal9539_conf_pull (tc , line , pull );
122
- if (err )
123
- return err ;
119
+ if (on ) {
120
+ return tcal9539_set_bit_in_reg (tc , line , & tc -> output , TCAL9539_OUTPUT0 );
121
+ } else {
122
+ return tcal9539_clr_bit_in_reg (tc , line , & tc -> output , TCAL9539_OUTPUT0 );
123
+ }
124
124
125
- return tcal9539_clr_bit_in_reg ( tc , line , & tc -> direction , TCAL9539_CFG0 ) ;
125
+ return ERR_NOT_IMPLEMENTED ;
126
126
}
127
127
128
128
129
129
static error_t
130
- tcal9539_set_pin (indirect_gpio_t * ig , unsigned int line , int on )
130
+ tcal9539_conf_output (indirect_gpio_t * ig , unsigned int line ,
131
+ gpio_output_type_t type , gpio_output_speed_t speed ,
132
+ gpio_pull_t pull , int initial_value )
131
133
{
132
134
tcal9539_t * tc = (tcal9539_t * )ig ;
133
135
134
136
if (line >= 16 )
135
137
return ERR_INVALID_ID ;
136
138
137
- if (on ) {
138
- return tcal9539_set_bit_in_reg (tc , line , & tc -> output , TCAL9539_OUTPUT0 );
139
- } else {
140
- return tcal9539_clr_bit_in_reg (tc , line , & tc -> output , TCAL9539_OUTPUT0 );
139
+ error_t err = tcal9539_conf_pull (tc , line , pull );
140
+ if (err )
141
+ return err ;
142
+
143
+ if (initial_value != -1 ) {
144
+ err = tcal9539_set_pin (ig , line , initial_value );
145
+ if (err )
146
+ return err ;
141
147
}
142
148
143
- return ERR_NOT_IMPLEMENTED ;
149
+ return tcal9539_clr_bit_in_reg ( tc , line , & tc -> direction , TCAL9539_CFG0 ) ;
144
150
}
145
151
146
152
@@ -152,13 +158,20 @@ tcal9539_get_pin(indirect_gpio_t *ig, unsigned int line, int *status)
152
158
if (line >= 16 )
153
159
return ERR_INVALID_ID ;
154
160
155
- uint8_t val ;
156
- error_t err = i2c_read_u8 (tc -> i2c , tc -> address , line >> 3 , & val );
157
- if (err )
158
- return err ;
159
161
160
- int bit = line & 0x7 ;
161
- * status = !!(val & (1 << bit ));
162
+ if ((1 << line ) & tc -> direction ) {
163
+
164
+ uint8_t val ;
165
+ error_t err = i2c_read_u8 (tc -> i2c , tc -> address , line >> 3 , & val );
166
+ if (err )
167
+ return err ;
168
+
169
+ int bit = line & 0x7 ;
170
+ * status = !!(val & (1 << bit ));
171
+ } else {
172
+ * status = (tc -> output >> line ) & 1 ;
173
+ }
174
+
162
175
return 0 ;
163
176
}
164
177
@@ -179,13 +192,63 @@ tcal9539_get_port(indirect_gpio_t *ig, unsigned int port, uint32_t *status)
179
192
return 0 ;
180
193
}
181
194
195
+ static int
196
+ tcal9539_get_mode (indirect_gpio_t * ig , unsigned int line )
197
+ {
198
+ tcal9539_t * tc = (tcal9539_t * )ig ;
199
+ return (tc -> direction >> line ) & 1 ;
200
+ }
201
+
202
+
203
+
204
+
205
+
206
+ static error_t
207
+ tcal9539_read_u16 (tcal9539_t * tc , uint8_t reg , uint16_t * value )
208
+ {
209
+ uint8_t lo , hi ;
210
+ error_t err ;
211
+
212
+ err = i2c_read_u8 (tc -> i2c , tc -> address , reg , & lo );
213
+ if (err )
214
+ return err ;
215
+ err = i2c_read_u8 (tc -> i2c , tc -> address , reg + 1 , & hi );
216
+ if (err )
217
+ return err ;
218
+
219
+ * value = ((uint16_t )hi << 8 ) | lo ;
220
+ return 0 ;
221
+ }
222
+
223
+
224
+ static error_t
225
+ tcal9539_refresh_shadow (indirect_gpio_t * ig )
226
+ {
227
+ tcal9539_t * tc = (tcal9539_t * )ig ;
228
+ error_t err ;
229
+
230
+ err = tcal9539_read_u16 (tc , TCAL9539_OUTPUT0 , & tc -> output );
231
+ if (err )
232
+ return err ;
233
+ err = tcal9539_read_u16 (tc , TCAL9539_CFG0 , & tc -> direction );
234
+ if (err )
235
+ return err ;
236
+ err = tcal9539_read_u16 (tc , TCAL9539_PUD0 , & tc -> pull_direction );
237
+ if (err )
238
+ return err ;
239
+
240
+ return tcal9539_read_u16 (tc , TCAL9539_PE0 , & tc -> pull_enable );
241
+ }
242
+
182
243
183
244
static const gpio_vtable_t tcal9539_vtable = {
184
245
.conf_input = tcal9539_conf_input ,
185
246
.conf_output = tcal9539_conf_output ,
186
247
.set_pin = tcal9539_set_pin ,
187
248
.get_pin = tcal9539_get_pin ,
188
249
.get_port = tcal9539_get_port ,
250
+ .get_mode = tcal9539_get_mode ,
251
+ .refresh_shadow = tcal9539_refresh_shadow ,
189
252
};
190
253
191
254
0 commit comments