Просмотр исходного кода

Merge branch 'feature/regi2c_add_lock_v4.2' into 'release/v4.2'

regi2c: add a spinlock for accessing (reg)I2C devices (backport v4.2)

See merge request espressif/esp-idf!13713
Michael (XIAO Xufeng) 4 лет назад
Родитель
Сommit
b2be91d98b

+ 41 - 35
components/soc/CMakeLists.txt

@@ -1,38 +1,44 @@
 idf_build_get_property(target IDF_TARGET)
 idf_build_get_property(target IDF_TARGET)
 
 
-idf_component_register(SRCS "src/cpu_util.c"
-                            "src/memory_layout_utils.c"
-                            "src/lldesc.c"
-                            "src/hal/cpu_hal.c"
-                            "src/hal/rmt_hal.c"
-                            "src/hal/rtc_io_hal.c"
-                            "src/hal/dac_hal.c"
-                            "src/hal/adc_hal.c"
-                            "src/hal/spi_hal.c"
-                            "src/hal/spi_hal_iram.c"
-                            "src/hal/spi_slave_hal.c"
-                            "src/hal/spi_slave_hal_iram.c"
-                            "src/hal/touch_sensor_hal.c"
-                            "src/soc_include_legacy_warn.c"
-                            "src/hal/pcnt_hal.c"
-                            "src/hal/i2s_hal.c"
-                            "src/hal/sigmadelta_hal.c"
-                            "src/hal/timer_hal.c"
-                            "src/hal/ledc_hal.c"
-                            "src/hal/ledc_hal_iram.c"
-                            "src/hal/i2c_hal.c"
-                            "src/hal/i2c_hal_iram.c"
-                            "src/hal/gpio_hal.c"
-                            "src/hal/uart_hal.c"
-                            "src/hal/uart_hal_iram.c"
-                            "src/hal/spi_flash_hal.c"
-                            "src/hal/spi_flash_hal_iram.c"
-                            "src/hal/mpu_hal.c"
-                            "src/hal/soc_hal.c"
-                            "src/hal/wdt_hal_iram.c"
-                            "src/compare_set.c"
-                            "src/hal/twai_hal.c"
-                            "src/hal/twai_hal_iram.c"
+set(srcs "src/cpu_util.c"
+          "src/memory_layout_utils.c"
+          "src/lldesc.c"
+          "src/hal/cpu_hal.c"
+          "src/hal/rmt_hal.c"
+          "src/hal/rtc_io_hal.c"
+          "src/hal/dac_hal.c"
+          "src/hal/adc_hal.c"
+          "src/hal/spi_hal.c"
+          "src/hal/spi_hal_iram.c"
+          "src/hal/spi_slave_hal.c"
+          "src/hal/spi_slave_hal_iram.c"
+          "src/hal/touch_sensor_hal.c"
+          "src/soc_include_legacy_warn.c"
+          "src/hal/pcnt_hal.c"
+          "src/hal/i2s_hal.c"
+          "src/hal/sigmadelta_hal.c"
+          "src/hal/timer_hal.c"
+          "src/hal/ledc_hal.c"
+          "src/hal/ledc_hal_iram.c"
+          "src/hal/i2c_hal.c"
+          "src/hal/i2c_hal_iram.c"
+          "src/hal/gpio_hal.c"
+          "src/hal/uart_hal.c"
+          "src/hal/uart_hal_iram.c"
+          "src/hal/spi_flash_hal.c"
+          "src/hal/spi_flash_hal_iram.c"
+          "src/hal/mpu_hal.c"
+          "src/hal/soc_hal.c"
+          "src/hal/wdt_hal_iram.c"
+          "src/compare_set.c"
+          "src/hal/twai_hal.c"
+          "src/hal/twai_hal_iram.c")
+
+if(NOT BOOTLOADER_BUILD)
+    list(APPEND srcs "src/regi2c_ctrl.c")
+endif()
+
+idf_component_register(SRCS ${srcs}
                        PRIV_REQUIRES ${target}
                        PRIV_REQUIRES ${target}
                        LDFRAGMENTS linker.lf)
                        LDFRAGMENTS linker.lf)
 
 
@@ -43,8 +49,8 @@ elseif(CONFIG_IDF_TARGET_ESP32S2)
     target_sources(${COMPONENT_LIB} PRIVATE "src/hal/spi_flash_hal_gpspi.c")
     target_sources(${COMPONENT_LIB} PRIVATE "src/hal/spi_flash_hal_gpspi.c")
 endif()
 endif()
 
 
-# Since there can be chip-specific HAL headers which can include the common 
-# HAL header via include_next, process the build scripts here first so that 
+# Since there can be chip-specific HAL headers which can include the common
+# HAL header via include_next, process the build scripts here first so that
 # include directories appear first in the compile command.
 # include directories appear first in the compile command.
 add_subdirectory(src/${target})
 add_subdirectory(src/${target})
 target_include_directories(${COMPONENT_LIB} PUBLIC include)
 target_include_directories(${COMPONENT_LIB} PUBLIC include)

+ 7 - 3
components/soc/component.mk

@@ -1,10 +1,10 @@
 SOC_NAME := $(IDF_TARGET)
 SOC_NAME := $(IDF_TARGET)
 
 
 COMPONENT_SRCDIRS := src src/hal
 COMPONENT_SRCDIRS := src src/hal
-COMPONENT_ADD_INCLUDEDIRS := 
+COMPONENT_ADD_INCLUDEDIRS :=
 
 
-# Since there can be chip-specific HAL headers which can include the common 
-# HAL header via include_next, process the build scripts here first so that 
+# Since there can be chip-specific HAL headers which can include the common
+# HAL header via include_next, process the build scripts here first so that
 # include directories appear first in the compile command.
 # include directories appear first in the compile command.
 -include $(COMPONENT_PATH)/src/$(SOC_NAME)/component.mk
 -include $(COMPONENT_PATH)/src/$(SOC_NAME)/component.mk
 COMPONENT_ADD_INCLUDEDIRS += include
 COMPONENT_ADD_INCLUDEDIRS += include
@@ -12,3 +12,7 @@ COMPONENT_ADD_INCLUDEDIRS += include
 -include $(COMPONENT_PATH)/soc/component.mk
 -include $(COMPONENT_PATH)/soc/component.mk
 
 
 COMPONENT_ADD_LDFRAGMENTS += linker.lf
 COMPONENT_ADD_LDFRAGMENTS += linker.lf
+
+ifdef IS_BOOTLOADER_BUILD
+	COMPONENT_OBJEXCLUDE += src/regi2c_ctrl.o
+endif

+ 30 - 6
components/soc/src/esp32/regi2c_ctrl.h

@@ -37,22 +37,46 @@ 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(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);
 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
 /* Convenience macros for the above functions, these use register definitions
  * from regi2c_apll.h/regi2c_bbpll.h header files.
  * from regi2c_apll.h/regi2c_bbpll.h header files.
  */
  */
 #define REGI2C_WRITE_MASK(block, reg_add, indata) \
 #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) \
 #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) \
 #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) \
 #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
 #ifdef __cplusplus
 }
 }
-#endif
+#endif

+ 30 - 5
components/soc/src/esp32s2/regi2c_ctrl.h

@@ -45,21 +45,46 @@ 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_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);
 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
 /* Convenience macros for the above functions, these use register definitions
  * from regi2c_apll.h/regi2c_bbpll.h header files.
  * from regi2c_apll.h/regi2c_bbpll.h header files.
  */
  */
 #define REGI2C_WRITE_MASK(block, reg_add, indata) \
 #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) \
 #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) \
 #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) \
 #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
 #ifdef __cplusplus
 }
 }
-#endif
+#endif

+ 50 - 0
components/soc/src/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 <stdint.h>
+#include <freertos/FreeRTOS.h>
+#include <freertos/semphr.h>
+
+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);
+}