@@ -199,6 +199,10 @@ static I2C_HandleTypeDef *i2c_handles[I2C_NUM];
199
199
#define I2C_STATE_NONE ((uint32_t)(HAL_I2C_MODE_NONE))
200
200
#endif
201
201
202
+ #define SLAVE_MODE_RECEIVE 1
203
+ #define SLAVE_MODE_LISTEN 2
204
+ #define DEFAULT_SLAVE_MODE SLAVE_MODE_LISTEN
205
+
202
206
/* Declare i2c_init_internal to be used in this file */
203
207
void i2c_init_internal (i2c_t * obj , const i2c_pinmap_t * pinmap );
204
208
@@ -1199,7 +1203,7 @@ void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *hi2c)
1199
1203
#if DEVICE_I2CSLAVE
1200
1204
/* restore slave address */
1201
1205
if (address != 0 ) {
1202
- obj_s -> slave = 1 ;
1206
+ obj_s -> slave = DEFAULT_SLAVE_MODE ;
1203
1207
i2c_slave_address (obj , 0 , address , 0 );
1204
1208
}
1205
1209
#endif
@@ -1251,7 +1255,7 @@ void i2c_slave_mode(i2c_t *obj, int enable_slave)
1251
1255
I2C_HandleTypeDef * handle = & (obj_s -> handle );
1252
1256
1253
1257
if (enable_slave ) {
1254
- obj_s -> slave = 1 ;
1258
+ obj_s -> slave = DEFAULT_SLAVE_MODE ;
1255
1259
HAL_I2C_EnableListen_IT (handle );
1256
1260
} else {
1257
1261
obj_s -> slave = 0 ;
@@ -1295,11 +1299,28 @@ void HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef *I2cHandle)
1295
1299
/* Get object ptr based on handler ptr */
1296
1300
i2c_t * obj = get_i2c_obj (I2cHandle );
1297
1301
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
+ }
1299
1313
}
1300
1314
1301
1315
void HAL_I2C_ListenCpltCallback (I2C_HandleTypeDef * hi2c )
1302
1316
{
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
+
1303
1324
/* restart listening for master requests */
1304
1325
HAL_I2C_EnableListen_IT (hi2c );
1305
1326
}
@@ -1328,18 +1349,34 @@ int i2c_slave_read(i2c_t *obj, char *data, int length)
1328
1349
int count = 0 ;
1329
1350
int ret = 0 ;
1330
1351
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
+ }
1331
1364
1332
1365
/* 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 );
1334
1367
1335
1368
if (ret == HAL_OK ) {
1336
- timeout = BYTE_TIMEOUT_US * (length + 1 );
1369
+ timeout = BYTE_TIMEOUT_US * (_length + 1 );
1337
1370
while (obj_s -> pending_slave_rx_maxter_tx && (-- timeout != 0 )) {
1338
1371
wait_us (1 );
1339
1372
}
1340
1373
1341
1374
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
+ }
1343
1380
} else {
1344
1381
DEBUG_PRINTF ("TIMEOUT or error in i2c_slave_read\r\n" );
1345
1382
}
0 commit comments