Skip to content

Commit 74c36f7

Browse files
committed
Merge branch 'feature/esp32h4_regi2c_support' into 'master'
feat(regi2c): add regi2c support for esp32h4 Closes IDF-12315 See merge request espressif/esp-idf!39966
2 parents a08dff3 + cde716e commit 74c36f7

File tree

22 files changed

+534
-537
lines changed

22 files changed

+534
-537
lines changed

components/bootloader_support/src/esp32h4/bootloader_esp32h4.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@
2828
#include "bootloader_flash_config.h"
2929
#include "bootloader_mem.h"
3030
#include "esp_private/regi2c_ctrl.h"
31-
#include "soc/regi2c_lp_bias.h"
32-
#include "soc/regi2c_bias.h"
31+
// #include "soc/regi2c_lp_bias.h"
32+
// #include "soc/regi2c_bias.h"
3333
#include "soc/hp_system_reg.h"
3434
#include "bootloader_console.h"
3535
#include "bootloader_flash_priv.h"
@@ -110,12 +110,12 @@ void spi_flash_extra_dummy_set(uint8_t spi_num, uint8_t extra_dummy)
110110
*/
111111
static inline void bootloader_hardware_init(void)
112112
{
113+
// TODO: IDF-12285 RF disable?
113114

114-
// TODO: [ESP32H4] IDF-12315
115-
ESP_EARLY_LOGE(TAG, "Analog i2c mst clk enable skipped!\n");
116115
/* Enable analog i2c master clock */
117-
// SET_PERI_REG_MASK(MODEM_LPCON_CLK_CONF_REG, MODEM_LPCON_CLK_I2C_MST_EN);
118-
// SET_PERI_REG_MASK(MODEM_LPCON_I2C_MST_CLK_CONF_REG, MODEM_LPCON_CLK_I2C_MST_SEL_160M);
116+
_regi2c_ctrl_ll_master_enable_clock(true); // keep ana i2c mst clock always enabled in bootloader
117+
regi2c_ctrl_ll_master_force_enable_clock(true); // TODO: IDF-12285 Remove this?
118+
regi2c_ctrl_ll_master_configure_clock();
119119
}
120120

121121
static inline void bootloader_ana_reset_config(void)

components/esp_rom/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ else()
2727

2828
# Override regi2c implementation in ROM
2929
if(CONFIG_ESP_ROM_HAS_REGI2C_BUG OR CONFIG_ESP_ROM_WITHOUT_REGI2C)
30-
if(target STREQUAL "esp32c6" OR target STREQUAL "esp32c5" OR target STREQUAL "esp32h4")
30+
if(target STREQUAL "esp32c6" OR target STREQUAL "esp32c5")
3131
list(APPEND sources "patches/esp_rom_hp_regi2c_${target}.c")
3232
else()
3333
list(APPEND sources "patches/esp_rom_regi2c_${target}.c")

components/esp_rom/patches/esp_rom_hp_regi2c_esp32h4.c

Lines changed: 0 additions & 189 deletions
This file was deleted.
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
/*
2+
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
#include "esp_rom_sys.h"
7+
#include "esp_attr.h"
8+
#include "soc/i2c_ana_mst_reg.h"
9+
#include "hal/regi2c_ctrl_ll.h"
10+
11+
/* SLAVE */
12+
#define REGI2C_BBPLL (0x66)
13+
#define REGI2C_BBTOP (0x67)
14+
#define REGI2C_DCDC (0x6d)
15+
#define REGI2C_PERIF (0x69)
16+
#define REGI2C_PLL (0x62)
17+
#define REGI2C_SDM (0x63)
18+
#define REGI2C_ULP (0x61)
19+
/* SLAVE END */
20+
21+
uint8_t esp_rom_regi2c_read(uint8_t block, uint8_t host_id, uint8_t reg_add) __attribute__((alias("regi2c_read_impl")));
22+
uint8_t esp_rom_regi2c_read_mask(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t msb, uint8_t lsb) __attribute__((alias("regi2c_read_mask_impl")));
23+
void esp_rom_regi2c_write(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t data) __attribute__((alias("regi2c_write_impl")));
24+
void esp_rom_regi2c_write_mask(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t msb, uint8_t lsb, uint8_t data) __attribute__((alias("regi2c_write_mask_impl")));
25+
26+
static IRAM_ATTR uint8_t regi2c_enable_block(uint8_t block)
27+
{
28+
uint32_t i2c_sel = 0;
29+
assert(regi2c_ctrl_ll_master_is_clock_enabled());
30+
31+
/* Before config I2C register, enable corresponding slave. */
32+
switch (block) {
33+
case REGI2C_BBPLL:
34+
i2c_sel = REG_GET_BIT(I2C_ANA_MST_ANA_CONF2_REG, REGI2C_CONF2_BBPLL_SEL);
35+
REG_WRITE(I2C_ANA_MST_ANA_CONF1_REG, ~REGI2C_CONF1_BBPLL_SEL & I2C_ANA_MST_ANA_CONF1_M);
36+
break;
37+
case REGI2C_BBTOP:
38+
i2c_sel = REG_GET_BIT(I2C_ANA_MST_ANA_CONF2_REG, REGI2C_CONF2_BBTOP_SEL);
39+
REG_WRITE(I2C_ANA_MST_ANA_CONF1_REG, ~REGI2C_CONF1_BBTOP_SEL & I2C_ANA_MST_ANA_CONF1_M);
40+
break;
41+
case REGI2C_DCDC:
42+
i2c_sel = REG_GET_BIT(I2C_ANA_MST_ANA_CONF2_REG, REGI2C_CONF2_DCDC_SEL);
43+
REG_WRITE(I2C_ANA_MST_ANA_CONF1_REG, ~REGI2C_CONF1_DCDC_SEL & I2C_ANA_MST_ANA_CONF1_M);
44+
break;
45+
case REGI2C_PERIF:
46+
i2c_sel = REG_GET_BIT(I2C_ANA_MST_ANA_CONF2_REG, REGI2C_CONF2_PERIF_SEL);
47+
REG_WRITE(I2C_ANA_MST_ANA_CONF1_REG, ~REGI2C_CONF1_PERIF_SEL & I2C_ANA_MST_ANA_CONF1_M);
48+
break;
49+
case REGI2C_PLL:
50+
i2c_sel = REG_GET_BIT(I2C_ANA_MST_ANA_CONF2_REG, REGI2C_CONF2_PLL_SEL);
51+
REG_WRITE(I2C_ANA_MST_ANA_CONF1_REG, ~REGI2C_CONF1_PLL_SEL & I2C_ANA_MST_ANA_CONF1_M);
52+
break;
53+
case REGI2C_SDM:
54+
i2c_sel = REG_GET_BIT(I2C_ANA_MST_ANA_CONF2_REG, REGI2C_CONF2_SDM_SEL);
55+
REG_WRITE(I2C_ANA_MST_ANA_CONF1_REG, ~REGI2C_CONF1_SDM_SEL & I2C_ANA_MST_ANA_CONF1_M);
56+
break;
57+
case REGI2C_ULP:
58+
i2c_sel = REG_GET_BIT(I2C_ANA_MST_ANA_CONF2_REG, REGI2C_CONF2_ULP_SEL);
59+
REG_WRITE(I2C_ANA_MST_ANA_CONF1_REG, ~REGI2C_CONF1_ULP_SEL & I2C_ANA_MST_ANA_CONF1_M);
60+
break;
61+
}
62+
return (uint8_t)(i2c_sel ? 0 : 1);
63+
}
64+
65+
uint8_t IRAM_ATTR regi2c_read_impl(uint8_t block, uint8_t host_id, uint8_t reg_add)
66+
{
67+
(void)host_id;
68+
uint8_t i2c_sel = regi2c_enable_block(block);
69+
while (REG_GET_BIT(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), REGI2C_RTC_BUSY)); // wait i2c idle
70+
uint32_t temp = ((block & REGI2C_RTC_SLAVE_ID_V) << REGI2C_RTC_SLAVE_ID_S)
71+
| (reg_add & REGI2C_RTC_ADDR_V) << REGI2C_RTC_ADDR_S;
72+
REG_WRITE(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), temp);
73+
while (REG_GET_BIT(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), REGI2C_RTC_BUSY));
74+
uint8_t ret = REG_GET_FIELD(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), REGI2C_RTC_DATA);
75+
return ret;
76+
}
77+
78+
uint8_t IRAM_ATTR regi2c_read_mask_impl(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t msb, uint8_t lsb)
79+
{
80+
assert(msb - lsb < 8);
81+
uint8_t i2c_sel = regi2c_enable_block(block);
82+
(void)host_id;
83+
while (REG_GET_BIT(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), REGI2C_RTC_BUSY)); // wait i2c idle
84+
uint32_t temp = ((block & REGI2C_RTC_SLAVE_ID_V) << REGI2C_RTC_SLAVE_ID_S)
85+
| (reg_add & REGI2C_RTC_ADDR_V) << REGI2C_RTC_ADDR_S;
86+
REG_WRITE(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), temp);
87+
while (REG_GET_BIT(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), REGI2C_RTC_BUSY));
88+
uint32_t data = REG_GET_FIELD(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), REGI2C_RTC_DATA);
89+
uint8_t ret = (uint8_t)((data >> lsb) & (~(0xFFFFFFFF << (msb - lsb + 1))));
90+
return ret;
91+
}
92+
93+
void IRAM_ATTR regi2c_write_impl(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t data)
94+
{
95+
(void)host_id;
96+
uint8_t i2c_sel = regi2c_enable_block(block);
97+
while (REG_GET_BIT(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), REGI2C_RTC_BUSY)); // wait i2c idle
98+
uint32_t temp = ((block & REGI2C_RTC_SLAVE_ID_V) << REGI2C_RTC_SLAVE_ID_S)
99+
| ((reg_add & REGI2C_RTC_ADDR_V) << REGI2C_RTC_ADDR_S)
100+
| ((0x1 & REGI2C_RTC_WR_CNTL_V) << REGI2C_RTC_WR_CNTL_S) // 0: READ I2C register; 1: Write I2C register;
101+
| (((uint32_t)data & REGI2C_RTC_DATA_V) << REGI2C_RTC_DATA_S);
102+
REG_WRITE(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), temp);
103+
while (REG_GET_BIT(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), REGI2C_RTC_BUSY));
104+
}
105+
106+
void IRAM_ATTR regi2c_write_mask_impl(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t msb, uint8_t lsb, uint8_t data)
107+
{
108+
(void)host_id;
109+
assert(msb - lsb < 8);
110+
uint8_t i2c_sel = regi2c_enable_block(block);
111+
while (REG_GET_BIT(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), REGI2C_RTC_BUSY));
112+
/*Read the i2c bus register*/
113+
uint32_t temp = ((block & REGI2C_RTC_SLAVE_ID_V) << REGI2C_RTC_SLAVE_ID_S)
114+
| (reg_add & REGI2C_RTC_ADDR_V) << REGI2C_RTC_ADDR_S;
115+
REG_WRITE(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), temp);
116+
while (REG_GET_BIT(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), REGI2C_RTC_BUSY));
117+
temp = REG_GET_FIELD(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), REGI2C_RTC_DATA);
118+
/*Write the i2c bus register*/
119+
temp &= ((~(0xFFFFFFFF << lsb)) | (0xFFFFFFFF << (msb + 1)));
120+
temp = (((uint32_t)data & (~(0xFFFFFFFF << (msb - lsb + 1)))) << lsb) | temp;
121+
temp = ((block & REGI2C_RTC_SLAVE_ID_V) << REGI2C_RTC_SLAVE_ID_S)
122+
| ((reg_add & REGI2C_RTC_ADDR_V) << REGI2C_RTC_ADDR_S)
123+
| ((0x1 & REGI2C_RTC_WR_CNTL_V) << REGI2C_RTC_WR_CNTL_S)
124+
| ((temp & REGI2C_RTC_DATA_V) << REGI2C_RTC_DATA_S);
125+
REG_WRITE(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), temp);
126+
while (REG_GET_BIT(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), REGI2C_RTC_BUSY));
127+
}

0 commit comments

Comments
 (0)