|
| 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