7575
7676#define SLAVE_MODE_TRANSMIT 0
7777#define SLAVE_MODE_RECEIVE 1
78+ #define SLAVE_MODE_LISTEN 2
79+
7880
7981/**
8082 * @}
@@ -261,7 +263,12 @@ void i2c_custom_init(i2c_t *obj, i2c_timing_e timing, uint32_t addressingMode, u
261263 handle -> Init .Timing = timing ;
262264#else
263265 handle -> Init .ClockSpeed = timing ;
264- handle -> Init .DutyCycle = I2C_DUTYCYCLE_2 ;
266+ /* Standard mode (sm) is up to 100kHz, then it's Fast mode (fm) */
267+ /* In fast mode duty cyble bit must be set in CCR register */
268+ if (timing > 100000 )
269+ handle -> Init .DutyCycle = I2C_DUTYCYCLE_16_9 ;
270+ else
271+ handle -> Init .DutyCycle = I2C_DUTYCYCLE_2 ;
265272#endif
266273 handle -> Init .OwnAddress1 = ownAddress ;
267274 handle -> Init .OwnAddress2 = 0xFF ;
@@ -283,6 +290,9 @@ void i2c_custom_init(i2c_t *obj, i2c_timing_e timing, uint32_t addressingMode, u
283290 HAL_I2C_Init (handle );
284291
285292 obj -> isMaster = master ;
293+ /* Initialize default values */
294+ obj -> slaveRxNbData = 0 ;
295+ obj -> slaveMode = SLAVE_MODE_LISTEN ;
286296}
287297
288298/**
@@ -326,6 +336,12 @@ void i2c_setTiming(i2c_t *obj, uint32_t frequency)
326336 obj -> handle .Init .Timing = f ;
327337#else
328338 obj -> handle .Init .ClockSpeed = f ;
339+ /* Standard mode (sm) is up to 100kHz, then it's Fast mode (fm) */
340+ /* In fast mode duty cyble bit must be set in CCR register */
341+ if (frequency > 100000 )
342+ obj -> handle .Init .DutyCycle = I2C_DUTYCYCLE_16_9 ;
343+ else
344+ obj -> handle .Init .DutyCycle = I2C_DUTYCYCLE_2 ;
329345#endif
330346/*
331347 else if(frequency <= 600000)
@@ -355,6 +371,11 @@ i2c_status_e i2c_master_write(i2c_t *obj, uint8_t dev_address,
355371 uint32_t tickstart = HAL_GetTick ();
356372 uint32_t delta = 0 ;
357373
374+ /* When size is 0, this is usually an I2C scan / ping to check if device is there and ready */
375+ if (size == 0 ) {
376+ return i2c_IsDeviceReady (obj , dev_address , 1 );
377+ }
378+
358379 do {
359380 if (HAL_I2C_Master_Transmit_IT (& (obj -> handle ), dev_address , data , size ) == HAL_OK ){
360381 ret = I2C_OK ;
@@ -395,9 +416,10 @@ i2c_status_e i2c_slave_write_IT(i2c_t *obj, uint8_t *data, uint16_t size)
395416 // Check the communication status
396417 for (i = 0 ; i < size ; i ++ ) {
397418 obj -> i2cTxRxBuffer [i ] = * (data + i );
398- obj -> i2cTxRxBufferSize ++ ;
399419 }
400420
421+ obj -> i2cTxRxBufferSize = size ;
422+
401423 return I2C_OK ;
402424}
403425
@@ -447,8 +469,19 @@ i2c_status_e i2c_IsDeviceReady(i2c_t *obj, uint8_t devAddr, uint32_t trials)
447469{
448470 i2c_status_e ret = HAL_OK ;
449471
450- if (HAL_I2C_IsDeviceReady ( & (obj -> handle ), devAddr , trials , I2C_TIMEOUT_TICK ) != HAL_OK ) {
451- ret = I2C_BUSY ;
472+ switch (HAL_I2C_IsDeviceReady ( & (obj -> handle ), devAddr , trials , I2C_TIMEOUT_TICK )) {
473+ case HAL_OK :
474+ ret = HAL_OK ;
475+ break ;
476+ case HAL_TIMEOUT :
477+ ret = I2C_TIMEOUT ;
478+ break ;
479+ case HAL_BUSY :
480+ ret = I2C_BUSY ;
481+ break ;
482+ default :
483+ ret = I2C_TIMEOUT ;
484+ break ;
452485 }
453486
454487 return ret ;
@@ -509,8 +542,6 @@ void HAL_I2C_AddrCallback(I2C_HandleTypeDef *hi2c, uint8_t TransferDirection, ui
509542
510543 if (AddrMatchCode == hi2c -> Init .OwnAddress1 ) {
511544 if (TransferDirection == I2C_DIRECTION_RECEIVE ) {
512-
513- obj -> i2cTxRxBufferSize = 0 ;
514545 obj -> slaveMode = SLAVE_MODE_TRANSMIT ;
515546
516547 if (obj -> i2c_onSlaveTransmit != NULL ) {
@@ -519,9 +550,12 @@ void HAL_I2C_AddrCallback(I2C_HandleTypeDef *hi2c, uint8_t TransferDirection, ui
519550 HAL_I2C_Slave_Sequential_Transmit_IT (hi2c , obj -> i2cTxRxBuffer ,
520551 obj -> i2cTxRxBufferSize , I2C_LAST_FRAME );
521552 } else {
553+ obj -> slaveRxNbData = 0 ;
522554 obj -> slaveMode = SLAVE_MODE_RECEIVE ;
523- HAL_I2C_Slave_Sequential_Receive_IT (hi2c , obj -> i2cTxRxBuffer ,
524- 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 );
525559 }
526560 }
527561}
@@ -534,19 +568,56 @@ void HAL_I2C_AddrCallback(I2C_HandleTypeDef *hi2c, uint8_t TransferDirection, ui
534568 */
535569void HAL_I2C_ListenCpltCallback (I2C_HandleTypeDef * hi2c )
536570{
537- uint8_t nbData = 0 ;
538571 i2c_t * obj = get_i2c_obj (hi2c );
539572
573+ /* Previous master transaction now ended, so inform upper layer if needed
574+ * then prepare for listening to next request */
540575 if ((obj -> i2c_onSlaveReceive != NULL ) &&
541576 (obj -> slaveMode == SLAVE_MODE_RECEIVE )) {
542- nbData = I2C_TXRX_BUFFER_SIZE - obj -> handle .XferSize ;
543- if (nbData != 0 ) {
544- obj -> i2c_onSlaveReceive (obj -> i2cTxRxBuffer , nbData );
577+ if (obj -> slaveRxNbData != 0 ) {
578+ obj -> i2c_onSlaveReceive (obj -> i2cTxRxBuffer , obj -> slaveRxNbData );
545579 }
546580 }
581+ obj -> slaveMode = SLAVE_MODE_LISTEN ;
582+ obj -> slaveRxNbData = 0 ;
547583 HAL_I2C_EnableListen_IT (hi2c );
548584}
549585
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+
550621/**
551622 * @brief I2C error callback.
552623 * @note In master mode, the callback is not used because the error is reported
0 commit comments