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

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

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

See merge request espressif/esp-idf!13716
Zim Kalinowski 4 лет назад
Родитель
Сommit
eec2482ecf

+ 6 - 2
components/soc/CMakeLists.txt

@@ -5,11 +5,11 @@ if(EXISTS "${COMPONENT_DIR}/${soc_name}")
 
     spaces2list(SOC_SRCS)
     add_prefix(srcs "${soc_name}/" ${SOC_SRCS})
-    set(include_dirs ${soc_name}/include)
+    set(include_dirs ${soc_name} ${soc_name}/include)
 endif()
 
 list(APPEND include_dirs include)
-list(APPEND srcs 
+list(APPEND srcs
     "src/memory_layout_utils.c"
     "src/lldesc.c"
     "src/hal/spi_hal.c"
@@ -21,6 +21,10 @@ list(APPEND srcs
     "src/hal/spi_flash_hal_iram.c"
     )
 
+if (NOT(BOOTLOADER_BUILD))
+    list(APPEND srcs "src/regi2c_ctrl.c")
+endif()
+
 idf_component_register(SRCS "${srcs}"
                     INCLUDE_DIRS "${include_dirs}"
                     LDFRAGMENTS linker.lf)

+ 5 - 1
components/soc/component.mk

@@ -2,7 +2,11 @@ SOC_NAME := $(IDF_TARGET)
 
 COMPONENT_SRCDIRS := $(SOC_NAME) src src/hal
 
-COMPONENT_ADD_INCLUDEDIRS := $(SOC_NAME)/include include
+COMPONENT_ADD_INCLUDEDIRS := $(SOC_NAME) $(SOC_NAME)/include include
 
 -include $(COMPONENT_PATH)/$(SOC_NAME)/component.mk
 COMPONENT_ADD_LDFRAGMENTS += linker.lf
+
+ifdef IS_BOOTLOADER_BUILD
+	COMPONENT_OBJEXCLUDE += src/regi2c_ctrl.o
+endif

+ 34 - 4
components/soc/esp32/i2c_rtc_clk.h

@@ -16,6 +16,7 @@
 
 #include "i2c_apll.h"
 #include "i2c_bbpll.h"
+#include <stdint.h>
 
 /* Analog function control register */
 #define ANA_CONFIG_REG  0x6000E044
@@ -32,17 +33,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_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 i2c_apll.h/i2c_bbpll.h header files.
  */
 #define I2C_WRITEREG_MASK_RTC(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 I2C_READREG_MASK_RTC(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 I2C_WRITEREG_RTC(block, reg_add, indata) \
-      rom_i2c_writeReg(block, block##_HOSTID,  reg_add, indata)
+      regi2c_ctrl_write_reg(block, block##_HOSTID,  reg_add, indata)
 
 #define I2C_READREG_RTC(block, reg_add) \
-      rom_i2c_readReg(block, block##_HOSTID,  reg_add)
+      regi2c_ctrl_read_reg(block, block##_HOSTID,  reg_add)
+
+#ifdef __cplusplus
+}
+#endif

+ 49 - 0
components/soc/src/regi2c_ctrl.c

@@ -0,0 +1,49 @@
+// 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 "i2c_rtc_clk.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);
+}