@@ -86,6 +86,10 @@ static I2C_HandleTypeDef *i2c_handles[I2C_NUM];
86
86
#define FLAG_TIMEOUT ((int)0x1000)
87
87
#endif
88
88
89
+ #define SLAVE_MODE_RECEIVE 1
90
+ #define SLAVE_MODE_LISTEN 2
91
+ #define DEFAULT_SLAVE_MODE SLAVE_MODE_LISTEN
92
+
89
93
/* Declare i2c_init_internal to be used in this file */
90
94
void i2c_init_internal (i2c_t * obj , const i2c_pinmap_t * pinmap );
91
95
@@ -1084,7 +1088,7 @@ void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *hi2c)
1084
1088
#if DEVICE_I2CSLAVE
1085
1089
/* restore slave address */
1086
1090
if (address != 0 ) {
1087
- obj_s -> slave = 1 ;
1091
+ obj_s -> slave = DEFAULT_SLAVE_MODE ;
1088
1092
i2c_slave_address (obj , 0 , address , 0 );
1089
1093
}
1090
1094
#endif
@@ -1136,7 +1140,7 @@ void i2c_slave_mode(i2c_t *obj, int enable_slave)
1136
1140
I2C_HandleTypeDef * handle = & (obj_s -> handle );
1137
1141
1138
1142
if (enable_slave ) {
1139
- obj_s -> slave = 1 ;
1143
+ obj_s -> slave = DEFAULT_SLAVE_MODE ;
1140
1144
HAL_I2C_EnableListen_IT (handle );
1141
1145
} else {
1142
1146
obj_s -> slave = 0 ;
@@ -1180,11 +1184,28 @@ void HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef *I2cHandle)
1180
1184
/* Get object ptr based on handler ptr */
1181
1185
i2c_t * obj = get_i2c_obj (I2cHandle );
1182
1186
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
+ }
1184
1198
}
1185
1199
1186
1200
void HAL_I2C_ListenCpltCallback (I2C_HandleTypeDef * hi2c )
1187
1201
{
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
+
1188
1209
/* restart listening for master requests */
1189
1210
HAL_I2C_EnableListen_IT (hi2c );
1190
1211
}
@@ -1213,18 +1234,34 @@ int i2c_slave_read(i2c_t *obj, char *data, int length)
1213
1234
int count = 0 ;
1214
1235
int ret = 0 ;
1215
1236
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
+ }
1216
1249
1217
1250
/* 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 );
1219
1252
1220
1253
if (ret == HAL_OK ) {
1221
- timeout = BYTE_TIMEOUT_US * (length + 1 );
1254
+ timeout = BYTE_TIMEOUT_US * (_length + 1 );
1222
1255
while (obj_s -> pending_slave_rx_maxter_tx && (-- timeout != 0 )) {
1223
1256
wait_us (1 );
1224
1257
}
1225
1258
1226
1259
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
+ }
1228
1265
} else {
1229
1266
DEBUG_PRINTF ("TIMEOUT or error in i2c_slave_read\r\n" );
1230
1267
}
0 commit comments