@@ -35,8 +35,9 @@ static const PinMap PinMap_I2C_SCL[] = {
35
35
#define I2C_SCLL (x , val ) (x->i2c->SCLL = val)
36
36
#define I2C_SCLH (x , val ) (x->i2c->SCLH = val)
37
37
38
- static const uint32_t I2C_addr_offset [4 ] = {
39
- 0x0C , 0x20 , 0x24 , 0x28
38
+ static const uint32_t I2C_addr_offset [2 ][4 ] = {
39
+ {0x0C , 0x20 , 0x24 , 0x28 },
40
+ {0x30 , 0x34 , 0x38 , 0x3C }
40
41
};
41
42
42
43
static inline void i2c_conclr (i2c_t * obj , int start , int stop , int interrupt , int acknowledge ) {
@@ -124,17 +125,18 @@ inline int i2c_start(i2c_t *obj) {
124
125
}
125
126
126
127
inline int i2c_stop (i2c_t * obj ) {
128
+ int timeout = 0 ;
129
+
127
130
// write the stop bit
128
- int timeout = 0 ;
129
131
i2c_conset (obj , 0 , 1 , 0 , 0 );
130
132
i2c_clear_SI (obj );
131
133
132
134
// wait for STO bit to reset
133
135
while (I2C_CONSET (obj ) & (1 << 4 )) {
134
- timeout ++ ;
135
- if (timeout > 100000 ) return 1 ;
136
- }
137
-
136
+ timeout ++ ;
137
+ if (timeout > 100000 ) return 1 ;
138
+ }
139
+
138
140
return 0 ;
139
141
}
140
142
@@ -201,13 +203,13 @@ int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) {
201
203
202
204
if ((status != 0x10 ) && (status != 0x08 )) {
203
205
i2c_stop (obj );
204
- return status ;
206
+ return I2C_ERROR_BUS_BUSY ;
205
207
}
206
208
207
209
status = i2c_do_write (obj , (address | 0x01 ), 1 );
208
210
if (status != 0x40 ) {
209
211
i2c_stop (obj );
210
- return status ;
212
+ return I2C_ERROR_NO_SLAVE ;
211
213
}
212
214
213
215
// Read in all except last byte
@@ -216,7 +218,7 @@ int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) {
216
218
status = i2c_status (obj );
217
219
if (status != 0x50 ) {
218
220
i2c_stop (obj );
219
- return status ;
221
+ return count ;
220
222
}
221
223
data [count ] = (char ) value ;
222
224
}
@@ -226,7 +228,7 @@ int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) {
226
228
status = i2c_status (obj );
227
229
if (status != 0x58 ) {
228
230
i2c_stop (obj );
229
- return status ;
231
+ return length - 1 ;
230
232
}
231
233
232
234
data [count ] = (char ) value ;
@@ -236,7 +238,7 @@ int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) {
236
238
i2c_stop (obj );
237
239
}
238
240
239
- return 0 ;
241
+ return length ;
240
242
}
241
243
242
244
int i2c_write (i2c_t * obj , int address , const char * data , int length , int stop ) {
@@ -246,31 +248,33 @@ int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) {
246
248
247
249
if ((status != 0x10 ) && (status != 0x08 )) {
248
250
i2c_stop (obj );
249
- return status ;
251
+ return I2C_ERROR_BUS_BUSY ;
250
252
}
251
253
252
254
status = i2c_do_write (obj , (address & 0xFE ), 1 );
253
255
if (status != 0x18 ) {
254
256
i2c_stop (obj );
255
- return status ;
257
+ return I2C_ERROR_NO_SLAVE ;
256
258
}
257
259
258
260
for (i = 0 ; i < length ; i ++ ) {
259
261
status = i2c_do_write (obj , data [i ], 0 );
260
262
if (status != 0x28 ) {
261
263
i2c_stop (obj );
262
- return status ;
264
+ return i ;
263
265
}
264
266
}
265
267
266
- i2c_clear_SI (obj );
268
+ // clearing the serial interrupt here might cause an unintended rewrite of the last byte
269
+ // see also issue report https://mbed.org/users/mbed_official/code/mbed/issues/1
270
+ // i2c_clear_SI(obj);
267
271
268
272
// If not repeated start, send stop.
269
273
if (stop ) {
270
274
i2c_stop (obj );
271
275
}
272
276
273
- return 0 ;
277
+ return length ;
274
278
}
275
279
276
280
void i2c_reset (i2c_t * obj ) {
@@ -348,7 +352,7 @@ int i2c_slave_read(i2c_t *obj, char *data, int length) {
348
352
349
353
i2c_clear_SI (obj );
350
354
351
- return ( count - 1 ) ;
355
+ return count ;
352
356
}
353
357
354
358
int i2c_slave_write (i2c_t * obj , const char * data , int length ) {
@@ -377,7 +381,7 @@ void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask) {
377
381
uint32_t addr ;
378
382
379
383
if ((idx >= 0 ) && (idx <= 3 )) {
380
- addr = ((uint32_t )obj -> i2c ) + I2C_addr_offset [idx ];
384
+ addr = ((uint32_t )obj -> i2c ) + I2C_addr_offset [0 ][ idx ];
381
385
* ((uint32_t * ) addr ) = address & 0xFF ;
382
386
}
383
387
}
0 commit comments