99 * 2024-04-23 Zeidan fix bugs, test on STM32F429IGTx
1010 * 2024-12-10 zzk597 add support for STM32F1 series
1111 * 2024-06-23 wdfk-prog Add blocking modes and distinguish POLL,INT,DMA modes
12+ * 2024-06-23 wdfk-prog Distinguish STM32 I2C timing semantics by IP generation
1213 */
1314
1415#include "drv_hard_i2c.h"
1920#define LOG_TAG "drv.i2c.hw"
2021#include <drv_log.h>
2122
23+ /*
24+ * Default timing values follow the IP generation split declared in
25+ * drv_hard_i2c.h:
26+ * - legacy IP (F1/F4): timing is the bus speed in Hz
27+ * - TIMINGR IP (F7/H7): timing is the raw I2C_TIMINGR value
28+ */
29+ #if defined(STM32_I2C_TIMINGR_IP )
30+ #define DEFAULT_I2C_TIMING_VALUE 0x307075B1U // 100K
31+ #else
32+ #define DEFAULT_I2C_TIMING_VALUE (100*1000U) //HZ
33+ #endif
34+
2235/* only buffer length >= DMA_TRANS_MIN_LEN will use DMA mode */
2336#define DMA_TRANS_MIN_LEN 2
2437
@@ -56,6 +69,16 @@ static struct stm32_i2c_config i2c_config[] =
5669
5770static struct stm32_i2c i2c_objs [sizeof (i2c_config ) / sizeof (i2c_config [0 ])] = {0 };
5871
72+ static void stm32_i2c_apply_default_config (struct stm32_i2c_config * cfg )
73+ {
74+ RT_ASSERT (cfg != RT_NULL );
75+
76+ if (cfg -> timing == 0U )
77+ {
78+ cfg -> timing = DEFAULT_I2C_TIMING_VALUE ;
79+ }
80+ }
81+
5982static rt_err_t stm32_i2c_init (struct stm32_i2c * i2c_drv )
6083{
6184 RT_ASSERT (i2c_drv != RT_NULL );
@@ -64,14 +87,16 @@ static rt_err_t stm32_i2c_init(struct stm32_i2c *i2c_drv)
6487 struct stm32_i2c_config * cfg = i2c_drv -> config ;
6588
6689 rt_memset (i2c_handle , 0 , sizeof (I2C_HandleTypeDef ));
90+ stm32_i2c_apply_default_config (cfg );
91+
6792 i2c_handle -> Instance = cfg -> Instance ;
68- #if defined(SOC_SERIES_STM32H7 )
93+ #if defined(STM32_I2C_TIMINGR_IP )
6994 i2c_handle -> Init .Timing = cfg -> timing ;
7095 i2c_handle -> Init .OwnAddress2Masks = I2C_OA2_NOMASK ;
7196#else
72- i2c_handle -> Init .ClockSpeed = 100000 ;
97+ i2c_handle -> Init .ClockSpeed = cfg -> timing ;
7398 i2c_handle -> Init .DutyCycle = I2C_DUTYCYCLE_2 ;
74- #endif /* defined(SOC_SERIES_STM32H7 ) */
99+ #endif /* defined(STM32_I2C_TIMINGR_IP ) */
75100 i2c_handle -> Init .OwnAddress1 = 0 ;
76101 i2c_handle -> Init .AddressingMode = I2C_ADDRESSINGMODE_7BIT ;
77102 i2c_handle -> Init .DualAddressMode = I2C_DUALADDRESS_DISABLE ;
@@ -87,7 +112,7 @@ static rt_err_t stm32_i2c_init(struct stm32_i2c *i2c_drv)
87112 {
88113 return - RT_EFAULT ;
89114 }
90- #if defined(SOC_SERIES_STM32H7 )
115+ #if defined(STM32_I2C_TIMINGR_IP )
91116 /* Configure Analogue filter */
92117 if (HAL_I2CEx_ConfigAnalogFilter (i2c_handle , I2C_ANALOGFILTER_ENABLE ) != HAL_OK )
93118 {
@@ -99,7 +124,7 @@ static rt_err_t stm32_i2c_init(struct stm32_i2c *i2c_drv)
99124 {
100125 return - RT_EFAULT ;
101126 }
102- #endif /* defined(SOC_SERIES_STM32H7 ) */
127+ #endif /* defined(STM32_I2C_TIMINGR_IP ) */
103128#if defined(BSP_I2C_RX_USING_DMA )
104129 /* I2C2 DMA Init */
105130 if (i2c_drv -> i2c_dma_flag & RT_DEVICE_FLAG_DMA_RX )
@@ -325,6 +350,10 @@ static rt_ssize_t stm32_i2c_master_xfer(struct rt_i2c_bus_device *bus,
325350 struct rt_i2c_msg msgs [],
326351 rt_uint32_t num )
327352{
353+ /* timeout = data_time + dev_addr_time + reserve_time */
354+ #define TIMEOUT_FREQ_KHZ (freq ) (((freq) / 1000U) ? ((freq) / 1000U) : 1U)
355+ #define TIMEOUT_CALC (msg ) (((msg)->len * 8U) / TIMEOUT_FREQ_KHZ(bus->config.usage_freq) + 1U + 5U)
356+
328357 rt_uint32_t i = 0 ;
329358 rt_int32_t ret = 0 ;
330359 struct rt_i2c_msg * msg = RT_NULL ;
@@ -348,13 +377,6 @@ static rt_ssize_t stm32_i2c_master_xfer(struct rt_i2c_bus_device *bus,
348377 completion = & i2c_obj -> completion ;
349378#endif /* defined(BSP_I2C_USING_IRQ) */
350379 LOG_D ("xfer start %d megs" , num );
351-
352- rt_uint32_t freq_khz = bus -> config .usage_freq / 1000 ;
353- if (freq_khz == 0 )
354- {
355- freq_khz = 1 ;
356- }
357-
358380 for (i = 0 ; i < num ; i ++ )
359381 {
360382 rt_bool_t need_wait = RT_FALSE ;
@@ -363,10 +385,11 @@ static rt_ssize_t stm32_i2c_master_xfer(struct rt_i2c_bus_device *bus,
363385 next_msg = is_last ? RT_NULL : & msgs [i + 1 ];
364386 mode = stm32_i2c_get_xfer_mode (i , msg , next_msg , is_last );
365387 LOG_D ("xfer msgs[%d] addr=0x%2x buf=0x%x len= 0x%x flags= 0x%x" , i , msg -> addr , msg -> buf , msg -> len , msg -> flags );
366-
367- // timeout= data_time + dev_addr_time + reserve_time
368- timeout = (msg -> len * 8 ) / freq_khz + 1 + 5 ;
369-
388+ #if defined(STM32_I2C_TIMINGR_IP )
389+ timeout = bus -> timeout ? bus -> timeout : 100U ;
390+ #else
391+ timeout = TIMEOUT_CALC (msg );
392+ #endif
370393 if (msg -> flags & RT_I2C_RD )
371394 {
372395 LOG_D ("xfer rec msgs[%d] hal mode = %s" , i , stm32_i2c_mode_name (mode ));
@@ -421,38 +444,78 @@ static rt_ssize_t stm32_i2c_master_xfer(struct rt_i2c_bus_device *bus,
421444out :
422445 ret = i ;
423446 /*
424- * On STM32H7, STOPI only enables STOP-event interrupt handling.
447+ * On TIMINGR-based STM32 I2C IPs (currently F7/H7 in this driver),
448+ * STOPI only enables STOP-event interrupt handling.
425449 * It does not actively generate a STOP condition on the bus.
426450 *
427- * For non-H7 STM32 series , the legacy HAL error handler already
428- * generates a STOP condition on AF in master/memory modes, so
429- * this driver does not manually issue another STOP in the AF path.
451+ * For legacy STM32 I2C IPs , the HAL error handler already generates a
452+ * STOP condition on AF in master/memory modes, so this driver does not
453+ * manually issue another STOP in the AF path.
430454 */
431455 if (handle -> ErrorCode & HAL_I2C_ERROR_AF )
432456 {
433457 LOG_W ("I2C[%s] NACK Error" , bus -> parent .parent .name );
434- #if defined(SOC_SERIES_STM32H7 )
458+ #if defined(STM32_I2C_TIMINGR_IP )
435459 handle -> Instance -> CR1 |= I2C_IT_STOPI ;
436- #endif /* defined(SOC_SERIES_STM32H7 ) */
460+ #endif /* defined(STM32_I2C_TIMINGR_IP ) */
437461 }
438462 if (handle -> ErrorCode & HAL_I2C_ERROR_BERR )
439463 {
440464 LOG_W ("I2C[%s] BUS Error" , bus -> parent .parent .name );
441- #if defined(SOC_SERIES_STM32H7 )
465+ #if defined(STM32_I2C_TIMINGR_IP )
442466 handle -> Instance -> CR1 |= I2C_IT_STOPI ;
443467#else
444468 handle -> Instance -> CR1 |= I2C_CR1_STOP ;
445- #endif /* defined(SOC_SERIES_STM32H7 ) */
469+ #endif /* defined(STM32_I2C_TIMINGR_IP ) */
446470 }
447471
448472 return ret ;
473+ #undef TIMEOUT_FREQ_KHZ
474+ #undef TIMEOUT_CALC
475+ }
476+
477+ rt_err_t stm_i2c_bus_control (struct rt_i2c_bus_device * bus , int cmd , void * args )
478+ {
479+ struct stm32_i2c * i2c_obj ;
480+ RT_ASSERT (bus != RT_NULL );
481+
482+ i2c_obj = rt_container_of (bus , struct stm32_i2c , i2c_bus );
483+ RT_ASSERT (i2c_obj != RT_NULL );
484+
485+ switch (cmd )
486+ {
487+ case BSP_I2C_CTRL_SET_TIMING :
488+ {
489+ if (args == RT_NULL )
490+ {
491+ return - RT_EINVAL ;
492+ }
493+
494+ rt_uint32_t timing = * (rt_uint32_t * )args ;
495+ if (timing <= 0 )
496+ {
497+ return - RT_ERROR ;
498+ }
499+
500+ i2c_obj -> i2c_bus .config .usage_freq = i2c_obj -> config -> timing = timing ;
501+ return stm32_i2c_configure (& i2c_obj -> i2c_bus );
502+ break ;
503+ }
504+ default :
505+ {
506+ break ;
507+ }
508+ }
509+ return - RT_EINVAL ;
449510}
450511
451512static const struct rt_i2c_bus_device_ops stm32_i2c_ops =
452513{
453514 .master_xfer = stm32_i2c_master_xfer ,
454- RT_NULL ,
455- RT_NULL ,
515+ #if defined(STM32_I2C_LEGACY_IP )
516+ .i2c_bus_control = stm_i2c_bus_control ,
517+ #endif
518+ .slave_xfer = RT_NULL ,
456519};
457520
458521int RT_hw_i2c_bus_init (void )
@@ -465,6 +528,12 @@ int RT_hw_i2c_bus_init(void)
465528 i2c_objs [i ].i2c_bus .ops = & stm32_i2c_ops ;
466529 i2c_objs [i ].config = & i2c_config [i ];
467530 i2c_objs [i ].i2c_bus .timeout = i2c_config [i ].timeout ;
531+ stm32_i2c_apply_default_config (& i2c_config [i ]);
532+ #if defined(STM32_I2C_LEGACY_IP )
533+ i2c_objs [i ].i2c_bus .config .max_hz = i2c_config [i ].timing ;
534+ i2c_objs [i ].i2c_bus .config .usage_freq = i2c_config [i ].timing ;
535+ #endif
536+
468537#ifdef BSP_I2C_USING_DMA
469538 if ((i2c_objs [i ].i2c_dma_flag & RT_DEVICE_FLAG_DMA_RX ))
470539 {
@@ -525,7 +594,7 @@ int RT_hw_i2c_bus_init(void)
525594 i2c_objs [i ].dma .handle_tx .Init .MemDataAlignment = DMA_MDATAALIGN_BYTE ;
526595 i2c_objs [i ].dma .handle_tx .Init .Mode = DMA_NORMAL ;
527596 i2c_objs [i ].dma .handle_tx .Init .Priority = DMA_PRIORITY_LOW ;
528- #endif
597+ #endif /* SOC_SERIES_STM32U5 */
529598#if defined(SOC_SERIES_STM32F2 ) || defined(SOC_SERIES_STM32F4 ) || defined(SOC_SERIES_STM32F7 ) || defined(SOC_SERIES_STM32MP1 ) || defined(SOC_SERIES_STM32H7 )
530599
531600 i2c_objs [i ].dma .handle_tx .Init .FIFOMode = DMA_FIFOMODE_DISABLE ;
@@ -685,7 +754,7 @@ void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *hi2c)
685754#endif /* I2C4 */
686755 : "unknown" ,
687756 hi2c -> ErrorCode );
688- #if defined(SOC_SERIES_STM32H7 )
757+ #if defined(STM32_I2C_TIMINGR_IP )
689758 /* Send stop signal to prevent bus lock-up */
690759 if (hi2c -> ErrorCode == HAL_I2C_ERROR_AF )
691760 {
@@ -697,7 +766,7 @@ void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *hi2c)
697766 LOG_W ("I2C BUS Error now stoped" );
698767 hi2c -> Instance -> CR1 |= I2C_IT_STOPI ;
699768 }
700- #endif /* defined(SOC_SERIES_STM32H7 ) */
769+ #endif /* defined(STM32_I2C_TIMINGR_IP ) */
701770}
702771
703772#ifdef BSP_USING_HARD_I2C1
0 commit comments