@@ -548,6 +548,17 @@ void i2c_init_internal(i2c_t *obj, const i2c_pinmap_t *pinmap)
548548 obj_s -> hz = 100000 ; // 100 kHz per default
549549 }
550550
551+ // Set remaining init parameters to defaults
552+ obj_s -> handle .Init .AddressingMode = I2C_ADDRESSINGMODE_7BIT ;
553+ obj_s -> handle .Init .DualAddressMode = I2C_DUALADDRESS_DISABLE ;
554+ obj_s -> handle .Init .GeneralCallMode = I2C_GENERALCALL_DISABLE ;
555+ obj_s -> handle .Init .NoStretchMode = I2C_NOSTRETCH_DISABLE ;
556+ obj_s -> handle .Init .OwnAddress1 = 0 ;
557+ obj_s -> handle .Init .OwnAddress2 = 0 ;
558+ #ifdef I2C_IP_VERSION_V2
559+ obj_s -> handle .Init .OwnAddress2Masks = I2C_OA2_NOMASK ;
560+ #endif
561+
551562 // Reset to clear pending flags if any
552563 i2c_hw_reset (obj );
553564 i2c_frequency (obj , obj_s -> hz );
@@ -784,19 +795,15 @@ void i2c_frequency(i2c_t *obj, int hz)
784795 /* hz value is stored for computing timing value next time */
785796 obj_s -> current_hz = hz ;
786797#endif // I2C_IP_VERSION_V2
787-
788- // I2C configuration
789- handle -> Init .AddressingMode = I2C_ADDRESSINGMODE_7BIT ;
790- handle -> Init .DualAddressMode = I2C_DUALADDRESS_DISABLE ;
791- handle -> Init .GeneralCallMode = I2C_GENERALCALL_DISABLE ;
792- handle -> Init .NoStretchMode = I2C_NOSTRETCH_DISABLE ;
793- handle -> Init .OwnAddress1 = 0 ;
794- handle -> Init .OwnAddress2 = 0 ;
795- #ifdef I2C_IP_VERSION_V2
796- handle -> Init .OwnAddress2Masks = I2C_OA2_NOMASK ;
797- #endif
798+
798799 HAL_I2C_Init (handle );
799800
801+ // In slave mode, reenable slave interrupts after calling init
802+ if (obj_s -> slave != 0 )
803+ {
804+ HAL_I2C_EnableListen_IT (& obj_s -> handle );
805+ }
806+
800807 /* store frequency for timeout computation */
801808 obj_s -> hz = hz ;
802809}
@@ -1120,11 +1127,11 @@ int i2c_byte_read(i2c_t *obj, int last)
11201127 if (last ) {
11211128 /* Disable Address Acknowledge */
11221129 tmpreg = tmpreg & (~I2C_CR2_RELOAD );
1123- tmpreg |= I2C_CR2_NACK | (I2C_CR2_NBYTES & ( 1 << 16 ) );
1130+ tmpreg |= I2C_CR2_NACK | (1 << I2C_CR2_NBYTES_Pos );
11241131 } else {
11251132 /* Enable reload mode as we don't know how many bytes will be sent */
11261133 /* and set transfer size to 1 */
1127- tmpreg |= I2C_CR2_RELOAD | (I2C_CR2_NBYTES & ( 1 << 16 ) );
1134+ tmpreg |= I2C_CR2_RELOAD | (1 << I2C_CR2_NBYTES_Pos );
11281135 }
11291136
11301137 /* Set the prepared configuration */
@@ -1505,15 +1512,15 @@ void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *hi2c)
15051512 uint32_t event_code = 0 ;
15061513
15071514#if DEVICE_I2CSLAVE
1508- uint32_t address = 0 ;
1509- /* Store address to handle it after reset */
1510- if (obj_s -> slave ) {
1511- address = handle -> Init .OwnAddress1 ;
1515+ if (obj_s -> slave_rx_transfer_in_progress && handle -> ErrorCode == HAL_I2C_ERROR_AF ) {
1516+ // We get here if the master ended a write operation after fewer than expected
1517+ // bytes. Just mark the slave transfer as done and return.
1518+ obj_s -> slave_rx_transfer_in_progress = 0 ;
1519+ return ;
15121520 }
15131521#endif
15141522
1515-
1516- if ((handle -> ErrorCode & HAL_I2C_ERROR_AF ) == HAL_I2C_ERROR_AF ) {
1523+ if (handle -> ErrorCode & HAL_I2C_ERROR_AF ) {
15171524 /* Keep Set event flag */
15181525 event_code = (I2C_EVENT_TRANSFER_EARLY_NACK ) | (I2C_EVENT_ERROR_NO_SLAVE );
15191526 }
@@ -1528,6 +1535,14 @@ void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *hi2c)
15281535
15291536 DEBUG_PRINTF ("HAL_I2C_ErrorCallback:%d, index=%d\r\n" , (int ) hi2c -> ErrorCode , obj_s -> index );
15301537
1538+ #if DEVICE_I2CSLAVE
1539+ uint32_t address = 0 ;
1540+ /* Store address to handle it after reset */
1541+ if (obj_s -> slave ) {
1542+ address = handle -> Init .OwnAddress1 ;
1543+ }
1544+ #endif
1545+
15311546 /* re-init IP to try and get back in a working state */
15321547 i2c_init_internal (obj , NULL );
15331548
@@ -1710,7 +1725,7 @@ int i2c_slave_read(i2c_t *obj, char *data, int length)
17101725 if (obj_s -> slave == SLAVE_MODE_LISTEN ) {
17111726 count = obj_s -> slave_rx_count ;
17121727 } else {
1713- count = _length ;
1728+ count = length - handle -> XferCount ;
17141729 }
17151730 } else {
17161731 DEBUG_PRINTF ("TIMEOUT or error in i2c_slave_read\r\n" );
0 commit comments