@@ -155,29 +155,101 @@ inline int i2c_stop(i2c_t *obj) {
155
155
}
156
156
157
157
int i2c_read (i2c_t * obj , int address , char * data , int length , int stop ) {
158
+ I2C_TypeDef * i2c = (I2C_TypeDef * )(obj -> i2c );
159
+ I2cHandle .Instance = (I2C_TypeDef * )(obj -> i2c );
160
+ int timeout ;
161
+ int count ;
162
+ int value ;
163
+
158
164
if (length == 0 ) return 0 ;
159
165
160
- I2cHandle .Instance = (I2C_TypeDef * )(obj -> i2c );
166
+ i2c_start (obj );
167
+
168
+ // Wait until SB flag is set
169
+ timeout = FLAG_TIMEOUT ;
170
+ while (__HAL_I2C_GET_FLAG (& I2cHandle , I2C_FLAG_SB ) == RESET ) {
171
+ timeout -- ;
172
+ if (timeout == 0 ) {
173
+ return 0 ;
174
+ }
175
+ }
176
+
177
+ i2c -> DR = __HAL_I2C_7BIT_ADD_READ (address );
178
+
179
+
180
+ // Wait address is acknowledged
181
+ timeout = FLAG_TIMEOUT ;
182
+ while (__HAL_I2C_GET_FLAG (& I2cHandle , I2C_FLAG_ADDR ) == RESET ) {
183
+ timeout -- ;
184
+ if (timeout == 0 ) {
185
+ return 0 ;
186
+ }
187
+ }
188
+ __HAL_I2C_CLEAR_ADDRFLAG (& I2cHandle );
189
+
190
+ // Read all bytes except last one
191
+ for (count = 0 ; count < (length - 1 ); count ++ ) {
192
+ value = i2c_byte_read (obj , 0 );
193
+ data [count ] = (char )value ;
194
+ }
161
195
162
- // Reception process with 5 seconds timeout
163
- if (HAL_I2C_Master_Receive (& I2cHandle , (uint16_t )address , (uint8_t * )data , length , 5000 ) != HAL_OK ) {
164
- return 0 ; // Error
196
+ // If not repeated start, send stop.
197
+ // Warning: must be done BEFORE the data is read.
198
+ if (stop ) {
199
+ i2c_stop (obj );
165
200
}
166
201
202
+ // Read the last byte
203
+ value = i2c_byte_read (obj , 1 );
204
+ data [count ] = (char )value ;
205
+
167
206
return length ;
168
207
}
169
208
170
209
int i2c_write (i2c_t * obj , int address , const char * data , int length , int stop ) {
210
+ I2C_TypeDef * i2c = (I2C_TypeDef * )(obj -> i2c );
211
+ I2cHandle .Instance = (I2C_TypeDef * )(obj -> i2c );
212
+ int timeout ;
213
+ int count ;
214
+
171
215
if (length == 0 ) return 0 ;
216
+ i2c_start (obj );
172
217
173
- I2cHandle .Instance = (I2C_TypeDef * )(obj -> i2c );
218
+ // Wait until SB flag is set
219
+ timeout = FLAG_TIMEOUT ;
220
+ while (__HAL_I2C_GET_FLAG (& I2cHandle , I2C_FLAG_SB ) == RESET ) {
221
+ timeout -- ;
222
+ if (timeout == 0 ) {
223
+ return 0 ;
224
+ }
225
+ }
226
+
227
+ i2c -> DR = __HAL_I2C_7BIT_ADD_WRITE (address );
228
+
174
229
175
- // Transmission process with 5 seconds timeout
176
- if (HAL_I2C_Master_Transmit (& I2cHandle , (uint16_t )address , (uint8_t * )data , length , 5000 ) != HAL_OK ) {
177
- return 0 ; // Error
230
+ // Wait address is acknowledged
231
+ timeout = FLAG_TIMEOUT ;
232
+ while (__HAL_I2C_GET_FLAG (& I2cHandle , I2C_FLAG_ADDR ) == RESET ) {
233
+ timeout -- ;
234
+ if (timeout == 0 ) {
235
+ return 0 ;
236
+ }
237
+ }
238
+ __HAL_I2C_CLEAR_ADDRFLAG (& I2cHandle );
239
+
240
+ for (count = 0 ; count < length ; count ++ ) {
241
+ if (i2c_byte_write (obj , data [count ]) != 1 ) {
242
+ i2c_stop (obj );
243
+ return 0 ;
244
+ }
178
245
}
179
246
180
- return length ;
247
+ // If not repeated start, send stop.
248
+ if (stop ) {
249
+ i2c_stop (obj );
250
+ }
251
+
252
+ return count ;
181
253
}
182
254
183
255
int i2c_byte_read (i2c_t * obj , int last ) {
0 commit comments