Skip to content

Commit d317dfc

Browse files
committed
make i2c_salve_read return the number of bytes read to let mbed-os read API return an error if less bytes are readed
1 parent 77927d0 commit d317dfc

File tree

2 files changed

+46
-6
lines changed

2 files changed

+46
-6
lines changed

targets/TARGET_STM/TARGET_STM32H7/objects.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,9 @@ struct i2c_s {
117117
uint8_t slave;
118118
volatile uint8_t pending_slave_tx_master_rx;
119119
volatile uint8_t pending_slave_rx_maxter_tx;
120+
uint8_t *slave_rx_buffer;
121+
volatile uint8_t slave_rx_buffer_size;
122+
volatile uint8_t slave_rx_count;
120123
#endif
121124
#if DEVICE_I2C_ASYNCH
122125
uint32_t address;

targets/TARGET_STM/i2c_api.c

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,10 @@ static I2C_HandleTypeDef *i2c_handles[I2C_NUM];
199199
#define I2C_STATE_NONE ((uint32_t)(HAL_I2C_MODE_NONE))
200200
#endif
201201

202+
#define SLAVE_MODE_RECEIVE 1
203+
#define SLAVE_MODE_LISTEN 2
204+
#define DEFAULT_SLAVE_MODE SLAVE_MODE_LISTEN
205+
202206
/* Declare i2c_init_internal to be used in this file */
203207
void i2c_init_internal(i2c_t *obj, const i2c_pinmap_t *pinmap);
204208

@@ -1199,7 +1203,7 @@ void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *hi2c)
11991203
#if DEVICE_I2CSLAVE
12001204
/* restore slave address */
12011205
if (address != 0) {
1202-
obj_s->slave = 1;
1206+
obj_s->slave = DEFAULT_SLAVE_MODE;
12031207
i2c_slave_address(obj, 0, address, 0);
12041208
}
12051209
#endif
@@ -1251,7 +1255,7 @@ void i2c_slave_mode(i2c_t *obj, int enable_slave)
12511255
I2C_HandleTypeDef *handle = &(obj_s->handle);
12521256

12531257
if (enable_slave) {
1254-
obj_s->slave = 1;
1258+
obj_s->slave = DEFAULT_SLAVE_MODE;
12551259
HAL_I2C_EnableListen_IT(handle);
12561260
} else {
12571261
obj_s->slave = 0;
@@ -1295,11 +1299,28 @@ void HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef *I2cHandle)
12951299
/* Get object ptr based on handler ptr */
12961300
i2c_t *obj = get_i2c_obj(I2cHandle);
12971301
struct i2c_s *obj_s = I2C_S(obj);
1298-
obj_s->pending_slave_rx_maxter_tx = 0;
1302+
1303+
if (obj_s->slave == SLAVE_MODE_LISTEN) {
1304+
obj_s->slave_rx_count++;
1305+
if (obj_s->slave_rx_count < obj_s->slave_rx_buffer_size){
1306+
HAL_I2C_Slave_Seq_Receive_IT(I2cHandle, &(obj_s->slave_rx_buffer[obj_s->slave_rx_count]), 1, I2C_NEXT_FRAME);
1307+
} else {
1308+
obj_s->pending_slave_rx_maxter_tx = 0;
1309+
}
1310+
} else {
1311+
obj_s->pending_slave_rx_maxter_tx = 0;
1312+
}
12991313
}
13001314

13011315
void HAL_I2C_ListenCpltCallback(I2C_HandleTypeDef *hi2c)
13021316
{
1317+
i2c_t *obj = get_i2c_obj(hi2c);
1318+
struct i2c_s *obj_s = I2C_S(obj);
1319+
1320+
if (obj_s->slave == SLAVE_MODE_LISTEN) {
1321+
obj_s->pending_slave_rx_maxter_tx = 0;
1322+
}
1323+
13031324
/* restart listening for master requests */
13041325
HAL_I2C_EnableListen_IT(hi2c);
13051326
}
@@ -1328,18 +1349,34 @@ int i2c_slave_read(i2c_t *obj, char *data, int length)
13281349
int count = 0;
13291350
int ret = 0;
13301351
uint32_t timeout = 0;
1352+
int _length = 0;
1353+
1354+
if (obj_s->slave == SLAVE_MODE_LISTEN) {
1355+
/* We don't know in advance how many bytes will be sent by master so
1356+
* we'll fetch one by one until master ends the sequence */
1357+
_length = 1;
1358+
obj_s->slave_rx_buffer_size = length;
1359+
obj_s->slave_rx_count = 0;
1360+
obj_s->slave_rx_buffer = (uint8_t*)data;
1361+
} else {
1362+
_length = length;
1363+
}
13311364

13321365
/* Always use I2C_NEXT_FRAME as slave will just adapt to master requests */
1333-
ret = HAL_I2C_Slave_Seq_Receive_IT(handle, (uint8_t *) data, length, I2C_NEXT_FRAME);
1366+
ret = HAL_I2C_Slave_Seq_Receive_IT(handle, (uint8_t *) data, _length, I2C_NEXT_FRAME);
13341367

13351368
if (ret == HAL_OK) {
1336-
timeout = BYTE_TIMEOUT_US * (length + 1);
1369+
timeout = BYTE_TIMEOUT_US * (_length + 1);
13371370
while (obj_s->pending_slave_rx_maxter_tx && (--timeout != 0)) {
13381371
wait_us(1);
13391372
}
13401373

13411374
if (timeout != 0) {
1342-
count = length;
1375+
if (obj_s->slave == SLAVE_MODE_LISTEN) {
1376+
count = obj_s->slave_rx_count;
1377+
} else {
1378+
count = _length;
1379+
}
13431380
} else {
13441381
DEBUG_PRINTF("TIMEOUT or error in i2c_slave_read\r\n");
13451382
}

0 commit comments

Comments
 (0)