Skip to content

Commit cdceaf2

Browse files
Add handling of a partial write by the master
1 parent c92c78e commit cdceaf2

File tree

2 files changed

+17
-8
lines changed

2 files changed

+17
-8
lines changed

hal/include/hal/i2c_api.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,7 @@ int i2c_slave_receive(i2c_t *obj);
323323
* @param obj The I2C object
324324
* @param data The buffer for receiving
325325
* @param length Number of bytes to read
326-
* @return non-zero if a value is available, or zero on error
326+
* @return Number of bytes read, or zero on error
327327
*/
328328
int i2c_slave_read(i2c_t *obj, char *data, int length);
329329

targets/TARGET_STM/i2c_api.c

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1512,15 +1512,16 @@ void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *hi2c)
15121512
uint32_t event_code = 0;
15131513

15141514
#if DEVICE_I2CSLAVE
1515-
uint32_t address = 0;
1516-
/* Store address to handle it after reset */
1517-
if (obj_s->slave) {
1518-
address = handle->Init.OwnAddress1;
1515+
if(obj_s->slave_rx_transfer_in_progress && handle->ErrorCode == HAL_I2C_ERROR_AF)
1516+
{
1517+
// We get here if the master NACKed a write operation after fewer than expected
1518+
// bytes. Just mark the slave transfer as done and return.
1519+
obj_s->slave_rx_transfer_in_progress = 0;
1520+
return;
15191521
}
15201522
#endif
15211523

1522-
1523-
if ((handle->ErrorCode & HAL_I2C_ERROR_AF) == HAL_I2C_ERROR_AF) {
1524+
if (handle->ErrorCode & HAL_I2C_ERROR_AF) {
15241525
/* Keep Set event flag */
15251526
event_code = (I2C_EVENT_TRANSFER_EARLY_NACK) | (I2C_EVENT_ERROR_NO_SLAVE);
15261527
}
@@ -1535,6 +1536,14 @@ void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *hi2c)
15351536

15361537
DEBUG_PRINTF("HAL_I2C_ErrorCallback:%d, index=%d\r\n", (int) hi2c->ErrorCode, obj_s->index);
15371538

1539+
#if DEVICE_I2CSLAVE
1540+
uint32_t address = 0;
1541+
/* Store address to handle it after reset */
1542+
if (obj_s->slave) {
1543+
address = handle->Init.OwnAddress1;
1544+
}
1545+
#endif
1546+
15381547
/* re-init IP to try and get back in a working state */
15391548
i2c_init_internal(obj, NULL);
15401549

@@ -1717,7 +1726,7 @@ int i2c_slave_read(i2c_t *obj, char *data, int length)
17171726
if (obj_s->slave == SLAVE_MODE_LISTEN) {
17181727
count = obj_s->slave_rx_count;
17191728
} else {
1720-
count = _length;
1729+
count = length - handle->XferCount;
17211730
}
17221731
} else {
17231732
DEBUG_PRINTF("TIMEOUT or error in i2c_slave_read\r\n");

0 commit comments

Comments
 (0)