Skip to content

Commit ae75c78

Browse files
committed
[NUCLEO_F401RE] add stop management in I2C
1 parent 03f7fcd commit ae75c78

File tree

1 file changed

+81
-9
lines changed
  • libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_F401RE

1 file changed

+81
-9
lines changed

libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_F401RE/i2c_api.c

Lines changed: 81 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -155,29 +155,101 @@ inline int i2c_stop(i2c_t *obj) {
155155
}
156156

157157
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+
158164
if (length == 0) return 0;
159165

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+
}
161195

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);
165200
}
166201

202+
// Read the last byte
203+
value = i2c_byte_read(obj, 1);
204+
data[count] = (char)value;
205+
167206
return length;
168207
}
169208

170209
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+
171215
if (length == 0) return 0;
216+
i2c_start(obj);
172217

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+
174229

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+
}
178245
}
179246

180-
return length;
247+
// If not repeated start, send stop.
248+
if (stop) {
249+
i2c_stop(obj);
250+
}
251+
252+
return count;
181253
}
182254

183255
int i2c_byte_read(i2c_t *obj, int last) {

0 commit comments

Comments
 (0)