7575
7676#define SLAVE_MODE_TRANSMIT 0
7777#define SLAVE_MODE_RECEIVE 1
78+ #define SLAVE_MODE_LISTEN 2
79+
7880
7981/**
8082 * @}
@@ -288,6 +290,9 @@ void i2c_custom_init(i2c_t *obj, i2c_timing_e timing, uint32_t addressingMode, u
288290 HAL_I2C_Init (handle );
289291
290292 obj -> isMaster = master ;
293+ /* Initialize default values */
294+ obj -> slaveRxNbData = 0 ;
295+ obj -> slaveMode = SLAVE_MODE_LISTEN ;
291296}
292297
293298/**
@@ -411,9 +416,10 @@ i2c_status_e i2c_slave_write_IT(i2c_t *obj, uint8_t *data, uint16_t size)
411416 // Check the communication status
412417 for (i = 0 ; i < size ; i ++ ) {
413418 obj -> i2cTxRxBuffer [i ] = * (data + i );
414- obj -> i2cTxRxBufferSize ++ ;
415419 }
416420
421+ obj -> i2cTxRxBufferSize = size ;
422+
417423 return I2C_OK ;
418424}
419425
@@ -536,8 +542,6 @@ void HAL_I2C_AddrCallback(I2C_HandleTypeDef *hi2c, uint8_t TransferDirection, ui
536542
537543 if (AddrMatchCode == hi2c -> Init .OwnAddress1 ) {
538544 if (TransferDirection == I2C_DIRECTION_RECEIVE ) {
539-
540- obj -> i2cTxRxBufferSize = 0 ;
541545 obj -> slaveMode = SLAVE_MODE_TRANSMIT ;
542546
543547 if (obj -> i2c_onSlaveTransmit != NULL ) {
@@ -546,9 +550,12 @@ void HAL_I2C_AddrCallback(I2C_HandleTypeDef *hi2c, uint8_t TransferDirection, ui
546550 HAL_I2C_Slave_Sequential_Transmit_IT (hi2c , obj -> i2cTxRxBuffer ,
547551 obj -> i2cTxRxBufferSize , I2C_LAST_FRAME );
548552 } else {
553+ obj -> slaveRxNbData = 0 ;
549554 obj -> slaveMode = SLAVE_MODE_RECEIVE ;
550- HAL_I2C_Slave_Sequential_Receive_IT (hi2c , obj -> i2cTxRxBuffer ,
551- I2C_TXRX_BUFFER_SIZE , I2C_LAST_FRAME );
555+ /* We don't know in advance how many bytes will be sent by master so
556+ * we'll fetch one by one until master ends the sequence */
557+ HAL_I2C_Slave_Sequential_Receive_IT (hi2c , & (obj -> i2cTxRxBuffer [obj -> slaveRxNbData ]),
558+ 1 , I2C_NEXT_FRAME );
552559 }
553560 }
554561}
@@ -561,19 +568,56 @@ void HAL_I2C_AddrCallback(I2C_HandleTypeDef *hi2c, uint8_t TransferDirection, ui
561568 */
562569void HAL_I2C_ListenCpltCallback (I2C_HandleTypeDef * hi2c )
563570{
564- uint8_t nbData = 0 ;
565571 i2c_t * obj = get_i2c_obj (hi2c );
566572
573+ /* Previous master transaction now ended, so inform upper layer if needed
574+ * then prepare for listening to next request */
567575 if ((obj -> i2c_onSlaveReceive != NULL ) &&
568576 (obj -> slaveMode == SLAVE_MODE_RECEIVE )) {
569- nbData = I2C_TXRX_BUFFER_SIZE - obj -> handle .XferSize ;
570- if (nbData != 0 ) {
571- obj -> i2c_onSlaveReceive (obj -> i2cTxRxBuffer , nbData );
577+ if (obj -> slaveRxNbData != 0 ) {
578+ obj -> i2c_onSlaveReceive (obj -> i2cTxRxBuffer , obj -> slaveRxNbData );
572579 }
573580 }
581+ obj -> slaveMode = SLAVE_MODE_LISTEN ;
582+ obj -> slaveRxNbData = 0 ;
574583 HAL_I2C_EnableListen_IT (hi2c );
575584}
576585
586+ /**
587+ * @brief Slave RX complete callback
588+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
589+ * the configuration information for the specified I2C.
590+ * @retval None
591+ */
592+ void HAL_I2C_SlaveRxCpltCallback (I2C_HandleTypeDef * hi2c )
593+ {
594+ i2c_t * obj = get_i2c_obj (hi2c );
595+ /* One more byte was received, store it then prepare next */
596+ if (obj -> slaveRxNbData < I2C_TXRX_BUFFER_SIZE ) {
597+ obj -> slaveRxNbData ++ ;
598+ } else {
599+ printf ("ERROR: I2C Slave RX overflow\n" );
600+ }
601+ /* Restart interrupt mode for next Byte */
602+ if (obj -> slaveMode == SLAVE_MODE_RECEIVE ) {
603+ HAL_I2C_Slave_Sequential_Receive_IT (hi2c , & (obj -> i2cTxRxBuffer [obj -> slaveRxNbData ]),
604+ 1 , I2C_NEXT_FRAME );
605+ }
606+ }
607+
608+ /**
609+ * @brief Slave TX complete callback
610+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
611+ * the configuration information for the specified I2C.
612+ * @retval None
613+ */
614+ void HAL_I2C_SlaveTxCpltCallback (I2C_HandleTypeDef * hi2c )
615+ {
616+ i2c_t * obj = get_i2c_obj (hi2c );
617+ /* Reset transmit buffer size */
618+ obj -> i2cTxRxBufferSize = 0 ;
619+ }
620+
577621/**
578622 * @brief I2C error callback.
579623 * @note In master mode, the callback is not used because the error is reported
0 commit comments