mirror of
https://github.com/apache/nuttx.git
synced 2026-09-13 22:20:24 +00:00
arch/arm/stm32h7/i2c: use per-instance RCC registers for clock and reset
stm32_i2c_init() and stm32_i2c_deinit() hardcoded APB1LENR/APB1LRSTR while taking the enable and reset bits from the per-instance config. That is correct for I2C1-3, but I2C4 is on APB4: its clk_bit and reset_bit are RCC_APB4ENR_I2C4EN and RCC_APB4RSTR_I2C4RST, both bit 7, and bit 7 of APB1LENR/APB1LRSTR is TIM13. So for I2C4 the driver enabled and pulsed the reset of TIM13 instead, and never reset the I2C4 peripheral at all. I2C4 still works because rcc_enableapb4() enables I2C4EN at boot, but the peripheral reset that stm32_i2c_reset() (CONFIG_I2C_RESET) relies on to clear a wedged I2C state machine never happens, and deinit gates TIM13 while leaving the I2C4 clock running. Store the clock enable and reset register addresses in struct stm32_i2c_config_s next to the bits, and use them in stm32_i2c_init() and stm32_i2c_deinit(). Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com>
This commit is contained in:
parent
ab9007c4e9
commit
659f47a824
1 changed files with 14 additions and 4 deletions
|
|
@ -374,7 +374,9 @@ struct stm32_trace_s
|
|||
struct stm32_i2c_config_s
|
||||
{
|
||||
uint32_t base; /* I2C base address */
|
||||
uint32_t clk_reg; /* Clock enable register */
|
||||
uint32_t clk_bit; /* Clock enable bit */
|
||||
uint32_t rst_reg; /* Peripheral reset register */
|
||||
uint32_t reset_bit; /* Reset bit */
|
||||
uint32_t scl_pin; /* GPIO configuration for SCL as SCL */
|
||||
uint32_t sda_pin; /* GPIO configuration for SDA as SDA */
|
||||
|
|
@ -492,7 +494,9 @@ static int stm32_i2c_pm_prepare(struct pm_callback_s *cb, int domain,
|
|||
static const struct stm32_i2c_config_s stm32_i2c1_config =
|
||||
{
|
||||
.base = STM32_I2C1_BASE,
|
||||
.clk_reg = STM32_RCC_APB1LENR,
|
||||
.clk_bit = RCC_APB1LENR_I2C1EN,
|
||||
.rst_reg = STM32_RCC_APB1LRSTR,
|
||||
.reset_bit = RCC_APB1LRSTR_I2C1RST,
|
||||
.scl_pin = GPIO_I2C1_SCL,
|
||||
.sda_pin = GPIO_I2C1_SDA,
|
||||
|
|
@ -528,7 +532,9 @@ static struct stm32_i2c_priv_s stm32_i2c1_priv =
|
|||
static const struct stm32_i2c_config_s stm32_i2c2_config =
|
||||
{
|
||||
.base = STM32_I2C2_BASE,
|
||||
.clk_reg = STM32_RCC_APB1LENR,
|
||||
.clk_bit = RCC_APB1LENR_I2C2EN,
|
||||
.rst_reg = STM32_RCC_APB1LRSTR,
|
||||
.reset_bit = RCC_APB1LRSTR_I2C2RST,
|
||||
.scl_pin = GPIO_I2C2_SCL,
|
||||
.sda_pin = GPIO_I2C2_SDA,
|
||||
|
|
@ -564,7 +570,9 @@ static struct stm32_i2c_priv_s stm32_i2c2_priv =
|
|||
static const struct stm32_i2c_config_s stm32_i2c3_config =
|
||||
{
|
||||
.base = STM32_I2C3_BASE,
|
||||
.clk_reg = STM32_RCC_APB1LENR,
|
||||
.clk_bit = RCC_APB1LENR_I2C3EN,
|
||||
.rst_reg = STM32_RCC_APB1LRSTR,
|
||||
.reset_bit = RCC_APB1LRSTR_I2C3RST,
|
||||
.scl_pin = GPIO_I2C3_SCL,
|
||||
.sda_pin = GPIO_I2C3_SDA,
|
||||
|
|
@ -600,7 +608,9 @@ static struct stm32_i2c_priv_s stm32_i2c3_priv =
|
|||
static const struct stm32_i2c_config_s stm32_i2c4_config =
|
||||
{
|
||||
.base = STM32_I2C4_BASE,
|
||||
.clk_reg = STM32_RCC_APB4ENR,
|
||||
.clk_bit = RCC_APB4ENR_I2C4EN,
|
||||
.rst_reg = STM32_RCC_APB4RSTR,
|
||||
.reset_bit = RCC_APB4RSTR_I2C4RST,
|
||||
.scl_pin = GPIO_I2C4_SCL,
|
||||
.sda_pin = GPIO_I2C4_SDA,
|
||||
|
|
@ -2143,9 +2153,9 @@ static int stm32_i2c_init(struct stm32_i2c_priv_s *priv)
|
|||
|
||||
/* Enable power and reset the peripheral */
|
||||
|
||||
modifyreg32(STM32_RCC_APB1LENR, 0, priv->config->clk_bit);
|
||||
modifyreg32(STM32_RCC_APB1LRSTR, 0, priv->config->reset_bit);
|
||||
modifyreg32(STM32_RCC_APB1LRSTR, priv->config->reset_bit, 0);
|
||||
modifyreg32(priv->config->clk_reg, 0, priv->config->clk_bit);
|
||||
modifyreg32(priv->config->rst_reg, 0, priv->config->reset_bit);
|
||||
modifyreg32(priv->config->rst_reg, priv->config->reset_bit, 0);
|
||||
|
||||
/* Configure pins */
|
||||
|
||||
|
|
@ -2213,7 +2223,7 @@ static int stm32_i2c_deinit(struct stm32_i2c_priv_s *priv)
|
|||
|
||||
/* Disable clocking */
|
||||
|
||||
modifyreg32(STM32_RCC_APB1LENR, priv->config->clk_bit, 0);
|
||||
modifyreg32(priv->config->clk_reg, priv->config->clk_bit, 0);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue