Skip to content

Commit 31277ee

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 9738b27 commit 31277ee

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
@@ -86,6 +86,10 @@ static I2C_HandleTypeDef *i2c_handles[I2C_NUM];
8686
#define FLAG_TIMEOUT ((int)0x1000)
8787
#endif
8888

89+
#define SLAVE_MODE_RECEIVE 1
90+
#define SLAVE_MODE_LISTEN 2
91+
#define DEFAULT_SLAVE_MODE SLAVE_MODE_LISTEN
92+
8993
/* Declare i2c_init_internal to be used in this file */
9094
void i2c_init_internal(i2c_t *obj, const i2c_pinmap_t *pinmap);
9195

@@ -1084,7 +1088,7 @@ void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *hi2c)
10841088
#if DEVICE_I2CSLAVE
10851089
/* restore slave address */
10861090
if (address != 0) {
1087-
obj_s->slave = 1;
1091+
obj_s->slave = DEFAULT_SLAVE_MODE;
10881092
i2c_slave_address(obj, 0, address, 0);
10891093
}
10901094
#endif
@@ -1136,7 +1140,7 @@ void i2c_slave_mode(i2c_t *obj, int enable_slave)
11361140
I2C_HandleTypeDef *handle = &(obj_s->handle);
11371141

11381142
if (enable_slave) {
1139-
obj_s->slave = 1;
1143+
obj_s->slave = DEFAULT_SLAVE_MODE;
11401144
HAL_I2C_EnableListen_IT(handle);
11411145
} else {
11421146
obj_s->slave = 0;
@@ -1180,11 +1184,28 @@ void HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef *I2cHandle)
11801184
/* Get object ptr based on handler ptr */
11811185
i2c_t *obj = get_i2c_obj(I2cHandle);
11821186
struct i2c_s *obj_s = I2C_S(obj);
1183-
obj_s->pending_slave_rx_maxter_tx = 0;
1187+
1188+
if(obj_s->slave == SLAVE_MODE_LISTEN) {
1189+
obj_s->slave_rx_count++;
1190+
if(obj_s->slave_rx_count < obj_s->slave_rx_buffer_size){
1191+
HAL_I2C_Slave_Seq_Receive_IT(I2cHandle, &(obj_s->slave_rx_buffer[obj_s->slave_rx_count]), 1, I2C_NEXT_FRAME);
1192+
} else {
1193+
obj_s->pending_slave_rx_maxter_tx = 0;
1194+
}
1195+
} else {
1196+
obj_s->pending_slave_rx_maxter_tx = 0;
1197+
}
11841198
}
11851199

11861200
void HAL_I2C_ListenCpltCallback(I2C_HandleTypeDef *hi2c)
11871201
{
1202+
i2c_t *obj = get_i2c_obj(hi2c);
1203+
struct i2c_s *obj_s = I2C_S(obj);
1204+
1205+
if (obj_s->slave == SLAVE_MODE_LISTEN) {
1206+
obj_s->pending_slave_rx_maxter_tx = 0;
1207+
}
1208+
11881209
/* restart listening for master requests */
11891210
HAL_I2C_EnableListen_IT(hi2c);
11901211
}
@@ -1213,18 +1234,34 @@ int i2c_slave_read(i2c_t *obj, char *data, int length)
12131234
int count = 0;
12141235
int ret = 0;
12151236
uint32_t timeout = 0;
1237+
int _length = 0;
1238+
1239+
if (obj_s->slave == SLAVE_MODE_LISTEN) {
1240+
/* We don't know in advance how many bytes will be sent by master so
1241+
* we'll fetch one by one until master ends the sequence */
1242+
_length = 1;
1243+
obj_s->slave_rx_buffer_size = length;
1244+
obj_s->slave_rx_count = 0;
1245+
obj_s->slave_rx_buffer = (uint8_t*)data;
1246+
} else {
1247+
_length = length;
1248+
}
12161249

12171250
/* Always use I2C_NEXT_FRAME as slave will just adapt to master requests */
1218-
ret = HAL_I2C_Slave_Seq_Receive_IT(handle, (uint8_t *) data, length, I2C_NEXT_FRAME);
1251+
ret = HAL_I2C_Slave_Seq_Receive_IT(handle, (uint8_t *) data, _length, I2C_NEXT_FRAME);
12191252

12201253
if (ret == HAL_OK) {
1221-
timeout = BYTE_TIMEOUT_US * (length + 1);
1254+
timeout = BYTE_TIMEOUT_US * (_length + 1);
12221255
while (obj_s->pending_slave_rx_maxter_tx && (--timeout != 0)) {
12231256
wait_us(1);
12241257
}
12251258

12261259
if (timeout != 0) {
1227-
count = length;
1260+
if(obj_s->slave == SLAVE_MODE_LISTEN) {
1261+
count = obj_s->slave_rx_count;
1262+
} else {
1263+
count = _length;
1264+
}
12281265
} else {
12291266
DEBUG_PRINTF("TIMEOUT or error in i2c_slave_read\r\n");
12301267
}

0 commit comments

Comments
 (0)