Skip to content

Commit d6760b1

Browse files
committed
fix(i2c): Fix that fsm reset cause i2c scl frequency changed on esp32s2,
Closes #15724
1 parent 6a740a9 commit d6760b1

File tree

16 files changed

+355
-233
lines changed

16 files changed

+355
-233
lines changed

components/esp_driver_i2c/i2c_master.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,10 @@ static esp_err_t s_i2c_hw_fsm_reset(i2c_master_bus_handle_t i2c_master)
130130
}
131131

132132
i2c_hal_master_init(hal);
133+
// Restore the clock source here.
134+
I2C_CLOCK_SRC_ATOMIC() {
135+
i2c_ll_set_source_clk(hal->dev, i2c_master->base->clk_src);
136+
}
133137
i2c_ll_enable_fifo_mode(hal->dev, true);
134138
i2c_ll_disable_intr_mask(hal->dev, I2C_LL_INTR_MASK);
135139
i2c_ll_clear_intr_mask(hal->dev, I2C_LL_INTR_MASK);

components/esp_driver_i2c/i2c_private.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -80,11 +80,6 @@ typedef struct i2c_bus_t *i2c_bus_handle_t;
8080
typedef struct i2c_master_dev_t i2c_master_dev_t;
8181
typedef struct i2c_slave_dev_t i2c_slave_dev_t;
8282

83-
typedef enum {
84-
I2C_BUS_MODE_MASTER = 0,
85-
I2C_BUS_MODE_SLAVE = 1,
86-
} i2c_bus_mode_t;
87-
8883
typedef enum {
8984
I2C_SLAVE_FIFO = 0,
9085
I2C_SLAVE_NONFIFO = 1,

components/hal/esp32/include/hal/i2c_ll.h

Lines changed: 36 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
2+
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
@@ -654,6 +654,20 @@ static inline bool i2c_ll_master_is_bus_clear_done(i2c_dev_t *hw)
654654
return false;
655655
}
656656

657+
/**
658+
* @brief Set the ACK level that the I2C master must send when the Rx FIFO count has reached the threshold value.
659+
* ack_level: 1 (NACK)
660+
* ack_level: 0 (ACK)
661+
*
662+
* @param hw Beginning address of the peripheral registers
663+
*
664+
* @return None
665+
*/
666+
static inline void i2c_ll_master_rx_full_ack_level(i2c_dev_t *hw, int ack_level)
667+
{
668+
// Not supported on esp32
669+
}
670+
657671
/**
658672
* @brief Set I2C source clock
659673
*
@@ -680,36 +694,37 @@ static inline void i2c_ll_enable_controller_clock(i2c_dev_t *hw, bool en)
680694
}
681695

682696
/**
683-
* @brief Init I2C master
697+
* @brief Set the I2C bus mode (Master or Slave)
684698
*
685-
* @param hw Beginning address of the peripheral registers
686-
*
687-
* @return None
699+
* @param hw Pointer to the I2C hardware register structure.
700+
* @param mode The desired I2C bus mode (Master or Slave).
688701
*/
689-
static inline void i2c_ll_master_init(i2c_dev_t *hw)
702+
static inline void i2c_ll_set_mode(i2c_dev_t *hw, i2c_bus_mode_t mode)
690703
{
691-
typeof(hw->ctr) ctrl_reg;
692-
ctrl_reg.val = 0;
693-
ctrl_reg.ms_mode = 1;
694-
ctrl_reg.sda_force_out = 1;
695-
ctrl_reg.scl_force_out = 1;
696-
hw->ctr.val = ctrl_reg.val;
704+
hw->ctr.ms_mode = (mode == I2C_BUS_MODE_MASTER) ? 1 : 0;
697705
}
698706

699707
/**
700-
* @brief Init I2C slave
708+
* @brief Enable or disable open-drain mode for I2C pins
701709
*
702-
* @param hw Beginning address of the peripheral registers
710+
* @param hw Pointer to the I2C hardware register structure.
711+
* @param enable_od Boolean flag to enable or disable open-drain mode:
712+
*/
713+
static inline void i2c_ll_enable_pins_open_drain(i2c_dev_t *hw, bool enable_od)
714+
{
715+
hw->ctr.sda_force_out = enable_od;
716+
hw->ctr.scl_force_out = enable_od;
717+
}
718+
719+
/**
720+
* @brief Enable or disable arbitration for I2C communication.
703721
*
704-
* @return None
722+
* @param hw Pointer to the I2C hardware instance.
723+
* @param enable_arbi Boolean flag to enable (true) or disable (false) arbitration.
705724
*/
706-
static inline void i2c_ll_slave_init(i2c_dev_t *hw)
725+
static inline void i2c_ll_enable_arbitration(i2c_dev_t *hw, bool enable_arbi)
707726
{
708-
typeof(hw->ctr) ctrl_reg;
709-
ctrl_reg.val = 0;
710-
ctrl_reg.sda_force_out = 1;
711-
ctrl_reg.scl_force_out = 1;
712-
hw->ctr.val = ctrl_reg.val;
727+
;// ESP32 do not support
713728
}
714729

715730
/**

components/hal/esp32c2/include/hal/i2c_ll.h

Lines changed: 42 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD
2+
* SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
@@ -695,6 +695,20 @@ static inline bool i2c_ll_master_is_bus_clear_done(i2c_dev_t *hw)
695695
return hw->scl_sp_conf.scl_rst_slv_en;
696696
}
697697

698+
/**
699+
* @brief Set the ACK level that the I2C master must send when the Rx FIFO count has reached the threshold value.
700+
* ack_level: 1 (NACK)
701+
* ack_level: 0 (ACK)
702+
*
703+
* @param hw Beginning address of the peripheral registers
704+
*
705+
* @return None
706+
*/
707+
static inline void i2c_ll_master_rx_full_ack_level(i2c_dev_t *hw, int ack_level)
708+
{
709+
hw->ctr.rx_full_ack_level = ack_level;
710+
}
711+
698712
/**
699713
* @brief Set I2C source clock
700714
*
@@ -721,21 +735,37 @@ static inline void i2c_ll_enable_controller_clock(i2c_dev_t *hw, bool en)
721735
}
722736

723737
/**
724-
* @brief Init I2C master
738+
* @brief Set the I2C bus mode (Master or Slave)
725739
*
726-
* @param hw Beginning address of the peripheral registers
740+
* @param hw Pointer to the I2C hardware register structure.
741+
* @param mode The desired I2C bus mode (Master or Slave).
742+
*/
743+
static inline void i2c_ll_set_mode(i2c_dev_t *hw, i2c_bus_mode_t mode)
744+
{
745+
hw->ctr.ms_mode = (mode == I2C_BUS_MODE_MASTER) ? 1 : 0;
746+
}
747+
748+
/**
749+
* @brief Enable or disable open-drain mode for I2C pins
727750
*
728-
* @return None
751+
* @param hw Pointer to the I2C hardware register structure.
752+
* @param enable_od Boolean flag to enable or disable open-drain mode:
753+
*/
754+
static inline void i2c_ll_enable_pins_open_drain(i2c_dev_t *hw, bool enable_od)
755+
{
756+
hw->ctr.sda_force_out = enable_od;
757+
hw->ctr.scl_force_out = enable_od;
758+
}
759+
760+
/**
761+
* @brief Enable or disable arbitration for I2C communication.
762+
*
763+
* @param hw Pointer to the I2C hardware instance.
764+
* @param enable_arbi Boolean flag to enable (true) or disable (false) arbitration.
729765
*/
730-
static inline void i2c_ll_master_init(i2c_dev_t *hw)
766+
static inline void i2c_ll_enable_arbitration(i2c_dev_t *hw, bool enable_arbi)
731767
{
732-
typeof(hw->ctr) ctrl_reg;
733-
ctrl_reg.val = 0;
734-
ctrl_reg.ms_mode = 1;
735-
ctrl_reg.clk_en = 1;
736-
ctrl_reg.sda_force_out = 1;
737-
ctrl_reg.scl_force_out = 1;
738-
hw->ctr.val = ctrl_reg.val;
768+
hw->ctr.arbitration_en = enable_arbi;
739769
}
740770

741771
/**

components/hal/esp32c3/include/hal/i2c_ll.h

Lines changed: 36 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD
2+
* SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
@@ -821,6 +821,20 @@ static inline bool i2c_ll_master_is_bus_clear_done(i2c_dev_t *hw)
821821
return hw->scl_sp_conf.scl_rst_slv_en;
822822
}
823823

824+
/**
825+
* @brief Set the ACK level that the I2C master must send when the Rx FIFO count has reached the threshold value.
826+
* ack_level: 1 (NACK)
827+
* ack_level: 0 (ACK)
828+
*
829+
* @param hw Beginning address of the peripheral registers
830+
*
831+
* @return None
832+
*/
833+
static inline void i2c_ll_master_rx_full_ack_level(i2c_dev_t *hw, int ack_level)
834+
{
835+
hw->ctr.rx_full_ack_level = ack_level;
836+
}
837+
824838
/**
825839
* @brief Set I2C source clock
826840
*
@@ -847,37 +861,37 @@ static inline void i2c_ll_enable_controller_clock(i2c_dev_t *hw, bool en)
847861
}
848862

849863
/**
850-
* @brief Init I2C master
864+
* @brief Set the I2C bus mode (Master or Slave)
851865
*
852-
* @param hw Beginning address of the peripheral registers
853-
*
854-
* @return None
866+
* @param hw Pointer to the I2C hardware register structure.
867+
* @param mode The desired I2C bus mode (Master or Slave).
855868
*/
856-
static inline void i2c_ll_master_init(i2c_dev_t *hw)
869+
static inline void i2c_ll_set_mode(i2c_dev_t *hw, i2c_bus_mode_t mode)
857870
{
858-
typeof(hw->ctr) ctrl_reg;
859-
ctrl_reg.val = 0;
860-
ctrl_reg.ms_mode = 1;
861-
ctrl_reg.clk_en = 1;
862-
ctrl_reg.sda_force_out = 1;
863-
ctrl_reg.scl_force_out = 1;
864-
hw->ctr.val = ctrl_reg.val;
871+
hw->ctr.ms_mode = (mode == I2C_BUS_MODE_MASTER) ? 1 : 0;
865872
}
866873

867874
/**
868-
* @brief Init I2C slave
875+
* @brief Enable or disable open-drain mode for I2C pins
869876
*
870-
* @param hw Beginning address of the peripheral registers
877+
* @param hw Pointer to the I2C hardware register structure.
878+
* @param enable_od Boolean flag to enable or disable open-drain mode:
879+
*/
880+
static inline void i2c_ll_enable_pins_open_drain(i2c_dev_t *hw, bool enable_od)
881+
{
882+
hw->ctr.sda_force_out = enable_od;
883+
hw->ctr.scl_force_out = enable_od;
884+
}
885+
886+
/**
887+
* @brief Enable or disable arbitration for I2C communication.
871888
*
872-
* @return None
889+
* @param hw Pointer to the I2C hardware instance.
890+
* @param enable_arbi Boolean flag to enable (true) or disable (false) arbitration.
873891
*/
874-
static inline void i2c_ll_slave_init(i2c_dev_t *hw)
892+
static inline void i2c_ll_enable_arbitration(i2c_dev_t *hw, bool enable_arbi)
875893
{
876-
typeof(hw->ctr) ctrl_reg;
877-
ctrl_reg.val = 0;
878-
ctrl_reg.sda_force_out = 1;
879-
ctrl_reg.scl_force_out = 1;
880-
hw->ctr.val = ctrl_reg.val;
894+
hw->ctr.arbitration_en = enable_arbi;
881895
}
882896

883897
/**

components/hal/esp32c5/include/hal/i2c_ll.h

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
2+
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
@@ -886,36 +886,37 @@ static inline void i2c_ll_enable_controller_clock(i2c_dev_t *hw, bool en)
886886
}
887887

888888
/**
889-
* @brief Init I2C master
889+
* @brief Set the I2C bus mode (Master or Slave)
890890
*
891-
* @param hw Beginning address of the peripheral registers
892-
*
893-
* @return None
891+
* @param hw Pointer to the I2C hardware register structure.
892+
* @param mode The desired I2C bus mode (Master or Slave).
894893
*/
895-
static inline void i2c_ll_master_init(i2c_dev_t *hw)
894+
static inline void i2c_ll_set_mode(i2c_dev_t *hw, i2c_bus_mode_t mode)
896895
{
897-
typeof(hw->ctr) ctrl_reg;
898-
ctrl_reg.val = 0;
899-
ctrl_reg.ms_mode = 1;
900-
ctrl_reg.sda_force_out = 0;
901-
ctrl_reg.scl_force_out = 0;
902-
hw->ctr.val = ctrl_reg.val;
896+
hw->ctr.ms_mode = (mode == I2C_BUS_MODE_MASTER) ? 1 : 0;
903897
}
904898

905899
/**
906-
* @brief Init I2C slave
900+
* @brief Enable or disable open-drain mode for I2C pins
907901
*
908-
* @param hw Beginning address of the peripheral registers
902+
* @param hw Pointer to the I2C hardware register structure.
903+
* @param enable_od Boolean flag to enable or disable open-drain mode:
904+
*/
905+
static inline void i2c_ll_enable_pins_open_drain(i2c_dev_t *hw, bool enable_od)
906+
{
907+
hw->ctr.sda_force_out = !enable_od;
908+
hw->ctr.scl_force_out = !enable_od;
909+
}
910+
911+
/**
912+
* @brief Enable or disable arbitration for I2C communication.
909913
*
910-
* @return None
914+
* @param hw Pointer to the I2C hardware instance.
915+
* @param enable_arbi Boolean flag to enable (true) or disable (false) arbitration.
911916
*/
912-
static inline void i2c_ll_slave_init(i2c_dev_t *hw)
917+
static inline void i2c_ll_enable_arbitration(i2c_dev_t *hw, bool enable_arbi)
913918
{
914-
typeof(hw->ctr) ctrl_reg;
915-
ctrl_reg.val = 0;
916-
ctrl_reg.sda_force_out = 0;
917-
ctrl_reg.scl_force_out = 0;
918-
hw->ctr.val = ctrl_reg.val;
919+
hw->ctr.arbitration_en = enable_arbi;
919920
}
920921

921922
/**

0 commit comments

Comments
 (0)