75
75
76
76
#define SLAVE_MODE_TRANSMIT 0
77
77
#define SLAVE_MODE_RECEIVE 1
78
+ #define SLAVE_MODE_LISTEN 2
79
+
78
80
79
81
/**
80
82
* @}
@@ -288,6 +290,9 @@ void i2c_custom_init(i2c_t *obj, i2c_timing_e timing, uint32_t addressingMode, u
288
290
HAL_I2C_Init (handle );
289
291
290
292
obj -> isMaster = master ;
293
+ /* Initialize default values */
294
+ obj -> slaveRxNbData = 0 ;
295
+ obj -> slaveMode = SLAVE_MODE_LISTEN ;
291
296
}
292
297
293
298
/**
@@ -411,9 +416,10 @@ i2c_status_e i2c_slave_write_IT(i2c_t *obj, uint8_t *data, uint16_t size)
411
416
// Check the communication status
412
417
for (i = 0 ; i < size ; i ++ ) {
413
418
obj -> i2cTxRxBuffer [i ] = * (data + i );
414
- obj -> i2cTxRxBufferSize ++ ;
415
419
}
416
420
421
+ obj -> i2cTxRxBufferSize = size ;
422
+
417
423
return I2C_OK ;
418
424
}
419
425
@@ -536,8 +542,6 @@ void HAL_I2C_AddrCallback(I2C_HandleTypeDef *hi2c, uint8_t TransferDirection, ui
536
542
537
543
if (AddrMatchCode == hi2c -> Init .OwnAddress1 ) {
538
544
if (TransferDirection == I2C_DIRECTION_RECEIVE ) {
539
-
540
- obj -> i2cTxRxBufferSize = 0 ;
541
545
obj -> slaveMode = SLAVE_MODE_TRANSMIT ;
542
546
543
547
if (obj -> i2c_onSlaveTransmit != NULL ) {
@@ -546,9 +550,12 @@ void HAL_I2C_AddrCallback(I2C_HandleTypeDef *hi2c, uint8_t TransferDirection, ui
546
550
HAL_I2C_Slave_Sequential_Transmit_IT (hi2c , obj -> i2cTxRxBuffer ,
547
551
obj -> i2cTxRxBufferSize , I2C_LAST_FRAME );
548
552
} else {
553
+ obj -> slaveRxNbData = 0 ;
549
554
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 );
552
559
}
553
560
}
554
561
}
@@ -561,19 +568,56 @@ void HAL_I2C_AddrCallback(I2C_HandleTypeDef *hi2c, uint8_t TransferDirection, ui
561
568
*/
562
569
void HAL_I2C_ListenCpltCallback (I2C_HandleTypeDef * hi2c )
563
570
{
564
- uint8_t nbData = 0 ;
565
571
i2c_t * obj = get_i2c_obj (hi2c );
566
572
573
+ /* Previous master transaction now ended, so inform upper layer if needed
574
+ * then prepare for listening to next request */
567
575
if ((obj -> i2c_onSlaveReceive != NULL ) &&
568
576
(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 );
572
579
}
573
580
}
581
+ obj -> slaveMode = SLAVE_MODE_LISTEN ;
582
+ obj -> slaveRxNbData = 0 ;
574
583
HAL_I2C_EnableListen_IT (hi2c );
575
584
}
576
585
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
+
577
621
/**
578
622
* @brief I2C error callback.
579
623
* @note In master mode, the callback is not used because the error is reported
0 commit comments