diff --git a/components/esp_hw_support/CMakeLists.txt b/components/esp_hw_support/CMakeLists.txt index 7b8994d950..733618e76f 100644 --- a/components/esp_hw_support/CMakeLists.txt +++ b/components/esp_hw_support/CMakeLists.txt @@ -7,7 +7,8 @@ endif() set(srcs "compare_set.c" "cpu_util.c") if(NOT BOOTLOADER_BUILD) - list(APPEND srcs "clk_ctrl_os.c") + list(APPEND srcs "clk_ctrl_os.c" + "regi2c_ctrl.c") endif() idf_component_register(SRCS ${srcs} diff --git a/components/esp_hw_support/component.mk b/components/esp_hw_support/component.mk index 867056fdc0..d975901a51 100644 --- a/components/esp_hw_support/component.mk +++ b/components/esp_hw_support/component.mk @@ -1,9 +1,9 @@ COMPONENT_SRCDIRS := . port/$(IDF_TARGET) -COMPONENT_ADD_INCLUDEDIRS := . include port/$(IDF_TARGET)/private_include +COMPONENT_ADD_INCLUDEDIRS := . include include/soc port/$(IDF_TARGET)/ port/$(IDF_TARGET)/private_include COMPONENT_ADD_LDFRAGMENTS := linker.lf port/$(IDF_TARGET)/rtc_clk.o: CFLAGS += -fno-jump-tables -fno-tree-switch-conversion ifdef IS_BOOTLOADER_BUILD -COMPONENT_OBJEXCLUDE += clk_ctrl_os.o +COMPONENT_OBJEXCLUDE += clk_ctrl_os.o regi2c_ctrl.o endif diff --git a/components/esp_hw_support/port/esp32/regi2c_ctrl.h b/components/esp_hw_support/port/esp32/regi2c_ctrl.h index d896cb2b88..69f2919207 100644 --- a/components/esp_hw_support/port/esp32/regi2c_ctrl.h +++ b/components/esp_hw_support/port/esp32/regi2c_ctrl.h @@ -37,20 +37,45 @@ uint8_t rom_i2c_readReg_Mask(uint8_t block, uint8_t host_id, uint8_t reg_add, ui void rom_i2c_writeReg(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t data); void rom_i2c_writeReg_Mask(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t msb, uint8_t lsb, uint8_t data); +#ifdef BOOTLOADER_BUILD + +/** + * If compiling for the bootloader, ROM functions can be called directly, + * without the need of a lock. + */ +#define regi2c_ctrl_read_reg rom_i2c_readReg +#define regi2c_ctrl_read_reg_mask rom_i2c_readReg_Mask +#define regi2c_ctrl_write_reg rom_i2c_writeReg +#define regi2c_ctrl_write_reg_mask rom_i2c_writeReg_Mask + +#else + +#define i2c_read_reg_raw rom_i2c_readReg +#define i2c_read_reg_mask_raw rom_i2c_readReg_Mask +#define i2c_write_reg_raw rom_i2c_writeReg +#define i2c_write_reg_mask_raw rom_i2c_writeReg_Mask + +uint8_t regi2c_ctrl_read_reg(uint8_t block, uint8_t host_id, uint8_t reg_add); +uint8_t regi2c_ctrl_read_reg_mask(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t msb, uint8_t lsb); +void regi2c_ctrl_write_reg(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t data); +void regi2c_ctrl_write_reg_mask(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t msb, uint8_t lsb, uint8_t data); + +#endif // BOOTLOADER_BUILD + /* Convenience macros for the above functions, these use register definitions * from regi2c_apll.h/regi2c_bbpll.h header files. */ #define REGI2C_WRITE_MASK(block, reg_add, indata) \ - rom_i2c_writeReg_Mask(block, block##_HOSTID, reg_add, reg_add##_MSB, reg_add##_LSB, indata) + regi2c_ctrl_write_reg_mask(block, block##_HOSTID, reg_add, reg_add##_MSB, reg_add##_LSB, indata) #define REGI2C_READ_MASK(block, reg_add) \ - rom_i2c_readReg_Mask(block, block##_HOSTID, reg_add, reg_add##_MSB, reg_add##_LSB) + regi2c_ctrl_read_reg_mask(block, block##_HOSTID, reg_add, reg_add##_MSB, reg_add##_LSB) #define REGI2C_WRITE(block, reg_add, indata) \ - rom_i2c_writeReg(block, block##_HOSTID, reg_add, indata) + regi2c_ctrl_write_reg(block, block##_HOSTID, reg_add, indata) #define REGI2C_READ(block, reg_add) \ - rom_i2c_readReg(block, block##_HOSTID, reg_add) + regi2c_ctrl_read_reg(block, block##_HOSTID, reg_add) #ifdef __cplusplus diff --git a/components/esp_hw_support/port/esp32c3/regi2c_ctrl.h b/components/esp_hw_support/port/esp32c3/regi2c_ctrl.h index dbca47e01f..95f2626656 100644 --- a/components/esp_hw_support/port/esp32c3/regi2c_ctrl.h +++ b/components/esp_hw_support/port/esp32c3/regi2c_ctrl.h @@ -64,20 +64,45 @@ uint8_t rom_i2c_readReg_Mask(uint8_t block, uint8_t host_id, uint8_t reg_add, ui void rom_i2c_writeReg(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t data); void rom_i2c_writeReg_Mask(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t msb, uint8_t lsb, uint8_t data); +#ifdef BOOTLOADER_BUILD + +/** + * If compiling for the bootloader, ROM functions can be called directly, + * without the need of a lock. + */ +#define regi2c_ctrl_read_reg rom_i2c_readReg +#define regi2c_ctrl_read_reg_mask rom_i2c_readReg_Mask +#define regi2c_ctrl_write_reg rom_i2c_writeReg +#define regi2c_ctrl_write_reg_mask rom_i2c_writeReg_Mask + +#else + +#define i2c_read_reg_raw rom_i2c_readReg +#define i2c_read_reg_mask_raw rom_i2c_readReg_Mask +#define i2c_write_reg_raw rom_i2c_writeReg +#define i2c_write_reg_mask_raw rom_i2c_writeReg_Mask + +uint8_t regi2c_ctrl_read_reg(uint8_t block, uint8_t host_id, uint8_t reg_add); +uint8_t regi2c_ctrl_read_reg_mask(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t msb, uint8_t lsb); +void regi2c_ctrl_write_reg(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t data); +void regi2c_ctrl_write_reg_mask(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t msb, uint8_t lsb, uint8_t data); + +#endif // BOOTLOADER_BUILD + /* Convenience macros for the above functions, these use register definitions * from regi2c_bbpll.h/regi2c_dig_reg.h/regi2c_lp_bias.h/regi2c_bias.h header files. */ #define REGI2C_WRITE_MASK(block, reg_add, indata) \ - rom_i2c_writeReg_Mask(block, block##_HOSTID, reg_add, reg_add##_MSB, reg_add##_LSB, indata) + regi2c_ctrl_write_reg_mask(block, block##_HOSTID, reg_add, reg_add##_MSB, reg_add##_LSB, indata) #define REGI2C_READ_MASK(block, reg_add) \ - rom_i2c_readReg_Mask(block, block##_HOSTID, reg_add, reg_add##_MSB, reg_add##_LSB) + regi2c_ctrl_read_reg_mask(block, block##_HOSTID, reg_add, reg_add##_MSB, reg_add##_LSB) #define REGI2C_WRITE(block, reg_add, indata) \ - rom_i2c_writeReg(block, block##_HOSTID, reg_add, indata) + regi2c_ctrl_write_reg(block, block##_HOSTID, reg_add, indata) #define REGI2C_READ(block, reg_add) \ - rom_i2c_readReg(block, block##_HOSTID, reg_add) + regi2c_ctrl_read_reg(block, block##_HOSTID, reg_add) #ifdef __cplusplus } diff --git a/components/esp_hw_support/port/esp32s2/regi2c_ctrl.h b/components/esp_hw_support/port/esp32s2/regi2c_ctrl.h index 16d63340af..51a0a22dcb 100644 --- a/components/esp_hw_support/port/esp32s2/regi2c_ctrl.h +++ b/components/esp_hw_support/port/esp32s2/regi2c_ctrl.h @@ -45,20 +45,45 @@ void i2c_rtc_write_reg(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t void i2c_rtc_write_reg_mask(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t msb, uint8_t lsb, uint8_t data); void i2c_rtc_init(void); +#ifdef BOOTLOADER_BUILD + +/** + * If compiling for the bootloader, internal functions can be called directly, + * without the need of a lock. + */ +#define regi2c_ctrl_read_reg i2c_rtc_read_reg +#define regi2c_ctrl_read_reg_mask i2c_rtc_read_reg_mask +#define regi2c_ctrl_write_reg i2c_rtc_write_reg +#define regi2c_ctrl_write_reg_mask i2c_rtc_write_reg_mask + +#else + +#define i2c_read_reg_raw i2c_rtc_read_reg +#define i2c_read_reg_mask_raw i2c_rtc_read_reg_mask +#define i2c_write_reg_raw i2c_rtc_write_reg +#define i2c_write_reg_mask_raw i2c_rtc_write_reg_mask + +uint8_t regi2c_ctrl_read_reg(uint8_t block, uint8_t host_id, uint8_t reg_add); +uint8_t regi2c_ctrl_read_reg_mask(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t msb, uint8_t lsb); +void regi2c_ctrl_write_reg(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t data); +void regi2c_ctrl_write_reg_mask(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t msb, uint8_t lsb, uint8_t data); + +#endif // BOOTLOADER_BUILD + /* Convenience macros for the above functions, these use register definitions * from regi2c_apll.h/regi2c_bbpll.h header files. */ #define REGI2C_WRITE_MASK(block, reg_add, indata) \ - i2c_rtc_write_reg_mask(block, block##_HOSTID, reg_add, reg_add##_MSB, reg_add##_LSB, indata) + regi2c_ctrl_write_reg_mask(block, block##_HOSTID, reg_add, reg_add##_MSB, reg_add##_LSB, indata) #define REGI2C_READ_MASK(block, reg_add) \ - i2c_rtc_read_reg_mask(block, block##_HOSTID, reg_add, reg_add##_MSB, reg_add##_LSB) + regi2c_ctrl_read_reg_mask(block, block##_HOSTID, reg_add, reg_add##_MSB, reg_add##_LSB) #define REGI2C_WRITE(block, reg_add, indata) \ - i2c_rtc_write_reg(block, block##_HOSTID, reg_add, indata) + regi2c_ctrl_write_reg(block, block##_HOSTID, reg_add, indata) #define REGI2C_READ(block, reg_add) \ - i2c_rtc_read_reg(block, block##_HOSTID, reg_add) + regi2c_ctrl_read_reg(block, block##_HOSTID, reg_add) #ifdef __cplusplus } diff --git a/components/esp_hw_support/port/esp32s3/regi2c_ctrl.h b/components/esp_hw_support/port/esp32s3/regi2c_ctrl.h index 11f6c1fc95..b8507917a7 100644 --- a/components/esp_hw_support/port/esp32s3/regi2c_ctrl.h +++ b/components/esp_hw_support/port/esp32s3/regi2c_ctrl.h @@ -38,17 +38,42 @@ uint8_t rom_i2c_readReg_Mask(uint8_t block, uint8_t host_id, uint8_t reg_add, ui void rom_i2c_writeReg(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t data); void rom_i2c_writeReg_Mask(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t msb, uint8_t lsb, uint8_t data); +#ifdef BOOTLOADER_BUILD + +/** + * If compiling for the bootloader, ROM functions can be called directly, + * without the need of a lock. + */ +#define regi2c_ctrl_read_reg rom_i2c_readReg +#define regi2c_ctrl_read_reg_mask rom_i2c_readReg_Mask +#define regi2c_ctrl_write_reg rom_i2c_writeReg +#define regi2c_ctrl_write_reg_mask rom_i2c_writeReg_Mask + +#else + +#define i2c_read_reg_raw rom_i2c_readReg +#define i2c_read_reg_mask_raw rom_i2c_readReg_Mask +#define i2c_write_reg_raw rom_i2c_writeReg +#define i2c_write_reg_mask_raw rom_i2c_writeReg_Mask + +uint8_t regi2c_ctrl_read_reg(uint8_t block, uint8_t host_id, uint8_t reg_add); +uint8_t regi2c_ctrl_read_reg_mask(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t msb, uint8_t lsb); +void regi2c_ctrl_write_reg(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t data); +void regi2c_ctrl_write_reg_mask(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t msb, uint8_t lsb, uint8_t data); + +#endif // BOOTLOADER_BUILD + /* Convenience macros for the above functions, these use register definitions * from regi2c_bbpll.h/regi2c_dig_reg.h/regi2c_ulp.h header files. */ #define REGI2C_WRITE_MASK(block, reg_add, indata) \ - rom_i2c_writeReg_Mask(block, block##_HOSTID, reg_add, reg_add##_MSB, reg_add##_LSB, indata) + regi2c_ctrl_write_reg_mask(block, block##_HOSTID, reg_add, reg_add##_MSB, reg_add##_LSB, indata) #define REGI2C_READ_MASK(block, reg_add) \ - rom_i2c_readReg_Mask(block, block##_HOSTID, reg_add, reg_add##_MSB, reg_add##_LSB) + regi2c_ctrl_read_reg_mask(block, block##_HOSTID, reg_add, reg_add##_MSB, reg_add##_LSB) #define REGI2C_WRITE(block, reg_add, indata) \ - rom_i2c_writeReg(block, block##_HOSTID, reg_add, indata) + regi2c_ctrl_write_reg(block, block##_HOSTID, reg_add, indata) #define REGI2C_READ(block, reg_add) \ - rom_i2c_readReg(block, block##_HOSTID, reg_add) + regi2c_ctrl_read_reg(block, block##_HOSTID, reg_add) diff --git a/components/esp_hw_support/regi2c_ctrl.c b/components/esp_hw_support/regi2c_ctrl.c new file mode 100644 index 0000000000..77a22ae662 --- /dev/null +++ b/components/esp_hw_support/regi2c_ctrl.c @@ -0,0 +1,50 @@ +// Copyright 2020 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "regi2c_ctrl.h" +#include +#include +#include + +static portMUX_TYPE mux = portMUX_INITIALIZER_UNLOCKED; + +uint8_t IRAM_ATTR regi2c_ctrl_read_reg(uint8_t block, uint8_t host_id, uint8_t reg_add) +{ + portENTER_CRITICAL_ISR(&mux); + uint8_t value = i2c_read_reg_raw(block, host_id, reg_add); + portEXIT_CRITICAL_ISR(&mux); + return value; +} + +uint8_t IRAM_ATTR regi2c_ctrl_read_reg_mask(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t msb, uint8_t lsb) +{ + portENTER_CRITICAL_ISR(&mux); + uint8_t value = i2c_read_reg_mask_raw(block, host_id, reg_add, msb, lsb); + portEXIT_CRITICAL_ISR(&mux); + return value; +} + +void IRAM_ATTR regi2c_ctrl_write_reg(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t data) +{ + portENTER_CRITICAL_ISR(&mux); + i2c_write_reg_raw(block, host_id, reg_add, data); + portEXIT_CRITICAL_ISR(&mux); +} + +void IRAM_ATTR regi2c_ctrl_write_reg_mask(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t msb, uint8_t lsb, uint8_t data) +{ + portENTER_CRITICAL_ISR(&mux); + i2c_write_reg_mask_raw(block, host_id, reg_add, msb, lsb, data); + portEXIT_CRITICAL_ISR(&mux); +}