Browse Source

Merge branch 'bugfix/spi_bus_unify_defualt_mosi_level' into 'master'

spi: unify default mosi level on all targets

Closes IDF-7683

See merge request espressif/esp-idf!24591
Wan Lei 2 years ago
parent
commit
f5e26a595d

+ 7 - 6
components/hal/esp32/include/hal/spi_ll.h

@@ -1,5 +1,5 @@
 /*
- * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -41,6 +41,7 @@ extern "C" {
 
 #define SPI_LL_DMA_MAX_BIT_LEN    (1 << 24)    //reg len: 24 bits
 #define SPI_LL_CPU_MAX_BIT_LEN    (16 * 32)    //Fifo len: 16 words
+#define SPI_LL_MOSI_FREE_LEVEL    0            //Default level after bus initialized
 
 /**
  * The data structure holding calculated clock configuration. Since the
@@ -123,21 +124,21 @@ static inline bool spi_ll_usr_is_done(spi_dev_t *hw)
 }
 
 /**
- * Trigger start of user-defined transaction for master.
+ * Apply the register configurations and wait until it's done
  *
  * @param hw Beginning address of the peripheral registers.
  */
-static inline void spi_ll_master_user_start(spi_dev_t *hw)
+static inline void spi_ll_apply_config(spi_dev_t *hw)
 {
-    hw->cmd.usr = 1;
+    // 32 don't need this option
 }
 
 /**
- * Trigger start of user-defined transaction for slave.
+ * Trigger start of user-defined transaction.
  *
  * @param hw Beginning address of the peripheral registers.
  */
-static inline void spi_ll_slave_user_start(spi_dev_t *hw)
+static inline void spi_ll_user_start(spi_dev_t *hw)
 {
     hw->cmd.usr = 1;
 }

+ 22 - 13
components/hal/esp32c2/include/hal/spi_ll.h

@@ -1,5 +1,5 @@
 /*
- * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -40,6 +40,7 @@ extern "C" {
 
 #define SPI_LL_DMA_MAX_BIT_LEN    (1 << 18)    //reg len: 18 bits
 #define SPI_LL_CPU_MAX_BIT_LEN    (16 * 32)    //Fifo len: 16 words
+#define SPI_LL_MOSI_FREE_LEVEL    1            //Default level after bus initialized
 
 /**
  * The data structure holding calculated clock configuration. Since the
@@ -186,36 +187,44 @@ static inline void spi_ll_slave_hd_init(spi_dev_t *hw)
 }
 
 /**
- * Check whether user-defined transaction is done.
+ * Determine and unify the default level of mosi line when bus free
  *
  * @param hw Beginning address of the peripheral registers.
- *
- * @return   True if transaction is done, otherwise false.
  */
-static inline bool spi_ll_usr_is_done(spi_dev_t *hw)
+static inline void spi_ll_set_mosi_free_level(spi_dev_t *hw, bool level)
 {
-    return hw->dma_int_raw.trans_done;
+    hw->ctrl.d_pol = level;     //set default level for MOSI only on IDLE state
 }
 
 /**
- * Trigger start of user-defined transaction for master.
- * The synchronization between two clock domains is required in ESP32-S3
+ * Apply the register configurations and wait until it's done
  *
  * @param hw Beginning address of the peripheral registers.
  */
-static inline void spi_ll_master_user_start(spi_dev_t *hw)
+static inline void spi_ll_apply_config(spi_dev_t *hw)
 {
     hw->cmd.update = 1;
-    while (hw->cmd.update);
-    hw->cmd.usr = 1;
+    while (hw->cmd.update);    //waiting config applied
+}
+
+/**
+ * Check whether user-defined transaction is done.
+ *
+ * @param hw Beginning address of the peripheral registers.
+ *
+ * @return   True if transaction is done, otherwise false.
+ */
+static inline bool spi_ll_usr_is_done(spi_dev_t *hw)
+{
+    return hw->dma_int_raw.trans_done;
 }
 
 /**
- * Trigger start of user-defined transaction for slave.
+ * Trigger start of user-defined transaction.
  *
  * @param hw Beginning address of the peripheral registers.
  */
-static inline void spi_ll_slave_user_start(spi_dev_t *hw)
+static inline void spi_ll_user_start(spi_dev_t *hw)
 {
     hw->cmd.usr = 1;
 }

+ 22 - 13
components/hal/esp32c3/include/hal/spi_ll.h

@@ -1,5 +1,5 @@
 /*
- * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -40,6 +40,7 @@ extern "C" {
 
 #define SPI_LL_DMA_MAX_BIT_LEN    (1 << 18)    //reg len: 18 bits
 #define SPI_LL_CPU_MAX_BIT_LEN    (16 * 32)    //Fifo len: 16 words
+#define SPI_LL_MOSI_FREE_LEVEL    1            //Default level after bus initialized
 
 /**
  * The data structure holding calculated clock configuration. Since the
@@ -186,36 +187,44 @@ static inline void spi_ll_slave_hd_init(spi_dev_t *hw)
 }
 
 /**
- * Check whether user-defined transaction is done.
+ * Determine and unify the default level of mosi line when bus free
  *
  * @param hw Beginning address of the peripheral registers.
- *
- * @return   True if transaction is done, otherwise false.
  */
-static inline bool spi_ll_usr_is_done(spi_dev_t *hw)
+static inline void spi_ll_set_mosi_free_level(spi_dev_t *hw, bool level)
 {
-    return hw->dma_int_raw.trans_done;
+    hw->ctrl.d_pol = level;     //set default level for MOSI only on IDLE state
 }
 
 /**
- * Trigger start of user-defined transaction for master.
- * The synchronization between two clock domains is required in ESP32-S3
+ * Apply the register configurations and wait until it's done
  *
  * @param hw Beginning address of the peripheral registers.
  */
-static inline void spi_ll_master_user_start(spi_dev_t *hw)
+static inline void spi_ll_apply_config(spi_dev_t *hw)
 {
     hw->cmd.update = 1;
-    while (hw->cmd.update);
-    hw->cmd.usr = 1;
+    while (hw->cmd.update);    //waiting config applied
+}
+
+/**
+ * Check whether user-defined transaction is done.
+ *
+ * @param hw Beginning address of the peripheral registers.
+ *
+ * @return   True if transaction is done, otherwise false.
+ */
+static inline bool spi_ll_usr_is_done(spi_dev_t *hw)
+{
+    return hw->dma_int_raw.trans_done;
 }
 
 /**
- * Trigger start of user-defined transaction for slave.
+ * Trigger start of user-defined transaction.
  *
  * @param hw Beginning address of the peripheral registers.
  */
-static inline void spi_ll_slave_user_start(spi_dev_t *hw)
+static inline void spi_ll_user_start(spi_dev_t *hw)
 {
     hw->cmd.usr = 1;
 }

+ 21 - 12
components/hal/esp32c6/include/hal/spi_ll.h

@@ -41,6 +41,7 @@ extern "C" {
 
 #define SPI_LL_DMA_MAX_BIT_LEN    (1 << 18)    //reg len: 18 bits
 #define SPI_LL_CPU_MAX_BIT_LEN    (16 * 32)    //Fifo len: 16 words
+#define SPI_LL_MOSI_FREE_LEVEL    1            //Default level after bus initialized
 
 /**
  * The data structure holding calculated clock configuration. Since the
@@ -190,36 +191,44 @@ static inline void spi_ll_slave_hd_init(spi_dev_t *hw)
 }
 
 /**
- * Check whether user-defined transaction is done.
+ * Determine and unify the default level of mosi line when bus free
  *
  * @param hw Beginning address of the peripheral registers.
- *
- * @return   True if transaction is done, otherwise false.
  */
-static inline bool spi_ll_usr_is_done(spi_dev_t *hw)
+static inline void spi_ll_set_mosi_free_level(spi_dev_t *hw, bool level)
 {
-    return hw->dma_int_raw.trans_done;
+    hw->ctrl.d_pol = level;     //set default level for MOSI only on IDLE state
 }
 
 /**
- * Trigger start of user-defined transaction for master.
- * The synchronization between two clock domains is required in ESP32-S3
+ * Apply the register configurations and wait until it's done
  *
  * @param hw Beginning address of the peripheral registers.
  */
-static inline void spi_ll_master_user_start(spi_dev_t *hw)
+static inline void spi_ll_apply_config(spi_dev_t *hw)
 {
     hw->cmd.update = 1;
-    while (hw->cmd.update);
-    hw->cmd.usr = 1;
+    while (hw->cmd.update);    //waiting config applied
+}
+
+/**
+ * Check whether user-defined transaction is done.
+ *
+ * @param hw Beginning address of the peripheral registers.
+ *
+ * @return   True if transaction is done, otherwise false.
+ */
+static inline bool spi_ll_usr_is_done(spi_dev_t *hw)
+{
+    return hw->dma_int_raw.trans_done;
 }
 
 /**
- * Trigger start of user-defined transaction for slave.
+ * Trigger start of user-defined transaction.
  *
  * @param hw Beginning address of the peripheral registers.
  */
-static inline void spi_ll_slave_user_start(spi_dev_t *hw)
+static inline void spi_ll_user_start(spi_dev_t *hw)
 {
     hw->cmd.usr = 1;
 }

+ 21 - 12
components/hal/esp32h2/include/hal/spi_ll.h

@@ -43,6 +43,7 @@ extern "C" {
 
 #define SPI_LL_DMA_MAX_BIT_LEN    (1 << 18)    //reg len: 18 bits
 #define SPI_LL_CPU_MAX_BIT_LEN    (16 * 32)    //Fifo len: 16 words
+#define SPI_LL_MOSI_FREE_LEVEL    1            //Default level after bus initialized
 
 /**
  * The data structure holding calculated clock configuration. Since the
@@ -192,36 +193,44 @@ static inline void spi_ll_slave_hd_init(spi_dev_t *hw)
 }
 
 /**
- * Check whether user-defined transaction is done.
+ * Determine and unify the default level of mosi line when bus free
  *
  * @param hw Beginning address of the peripheral registers.
- *
- * @return   True if transaction is done, otherwise false.
  */
-static inline bool spi_ll_usr_is_done(spi_dev_t *hw)
+static inline void spi_ll_set_mosi_free_level(spi_dev_t *hw, bool level)
 {
-    return hw->dma_int_raw.trans_done_int_raw;
+    hw->ctrl.d_pol = level;     //set default level for MOSI only on IDLE state
 }
 
 /**
- * Trigger start of user-defined transaction for master.
- * The synchronization between two clock domains is required in ESP32-S3
+ * Apply the register configurations and wait until it's done
  *
  * @param hw Beginning address of the peripheral registers.
  */
-static inline void spi_ll_master_user_start(spi_dev_t *hw)
+static inline void spi_ll_apply_config(spi_dev_t *hw)
 {
     hw->cmd.update = 1;
-    while (hw->cmd.update);
-    hw->cmd.usr = 1;
+    while (hw->cmd.update);    //waiting config applied
+}
+
+/**
+ * Check whether user-defined transaction is done.
+ *
+ * @param hw Beginning address of the peripheral registers.
+ *
+ * @return   True if transaction is done, otherwise false.
+ */
+static inline bool spi_ll_usr_is_done(spi_dev_t *hw)
+{
+    return hw->dma_int_raw.trans_done_int_raw;
 }
 
 /**
- * Trigger start of user-defined transaction for slave.
+ * Trigger start of user-defined transaction.
  *
  * @param hw Beginning address of the peripheral registers.
  */
-static inline void spi_ll_slave_user_start(spi_dev_t *hw)
+static inline void spi_ll_user_start(spi_dev_t *hw)
 {
     hw->cmd.usr = 1;
 }

+ 21 - 10
components/hal/esp32s2/include/hal/spi_ll.h

@@ -1,5 +1,5 @@
 /*
- * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -43,6 +43,7 @@ extern "C" {
 
 #define SPI_LL_DMA_MAX_BIT_LEN    (1 << 23)    //reg len: 23 bits
 #define SPI_LL_CPU_MAX_BIT_LEN    (18 * 32)    //Fifo len: 18 words
+#define SPI_LL_MOSI_FREE_LEVEL    1            //Default level after bus initialized
 
 /**
  * The data structure holding calculated clock configuration. Since the
@@ -176,33 +177,43 @@ static inline void spi_ll_slave_hd_init(spi_dev_t *hw)
 }
 
 /**
- * Check whether user-defined transaction is done.
+ * Determine and unify the default level of mosi line when bus free
  *
  * @param hw Beginning address of the peripheral registers.
+ */
+static inline void spi_ll_set_mosi_free_level(spi_dev_t *hw, bool level)
+{
+    hw->ctrl.d_pol = level;     //set default level for MOSI only on IDLE state
+}
+
+/**
+ * Apply the register configurations and wait until it's done
  *
- * @return true if transaction is done, otherwise false.
+ * @param hw Beginning address of the peripheral registers.
  */
-static inline bool spi_ll_usr_is_done(spi_dev_t *hw)
+static inline void spi_ll_apply_config(spi_dev_t *hw)
 {
-    return hw->slave.trans_done;
+    // S2 don't need this option
 }
 
 /**
- * Trigger start of user-defined transaction for master.
+ * Check whether user-defined transaction is done.
  *
  * @param hw Beginning address of the peripheral registers.
+ *
+ * @return true if transaction is done, otherwise false.
  */
-static inline void spi_ll_master_user_start(spi_dev_t *hw)
+static inline bool spi_ll_usr_is_done(spi_dev_t *hw)
 {
-    hw->cmd.usr = 1;
+    return hw->slave.trans_done;
 }
 
 /**
- * Trigger start of user-defined transaction for slave.
+ * Trigger start of user-defined transaction.
  *
  * @param hw Beginning address of the peripheral registers.
  */
-static inline void spi_ll_slave_user_start(spi_dev_t *hw)
+static inline void spi_ll_user_start(spi_dev_t *hw)
 {
     hw->cmd.usr = 1;
 }

+ 22 - 13
components/hal/esp32s3/include/hal/spi_ll.h

@@ -1,5 +1,5 @@
 /*
- * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -42,6 +42,7 @@ extern "C" {
 
 #define SPI_LL_DMA_MAX_BIT_LEN    (1 << 18)    //reg len: 18 bits
 #define SPI_LL_CPU_MAX_BIT_LEN    (16 * 32)    //Fifo len: 16 words
+#define SPI_LL_MOSI_FREE_LEVEL    1            //Default level after bus initialized
 
 /**
  * The data structure holding calculated clock configuration. Since the
@@ -188,36 +189,44 @@ static inline void spi_ll_slave_hd_init(spi_dev_t *hw)
 }
 
 /**
- * Check whether user-defined transaction is done.
+ * Determine and unify the default level of mosi line when bus free
  *
  * @param hw Beginning address of the peripheral registers.
- *
- * @return   True if transaction is done, otherwise false.
  */
-static inline bool spi_ll_usr_is_done(spi_dev_t *hw)
+static inline void spi_ll_set_mosi_free_level(spi_dev_t *hw, bool level)
 {
-    return hw->dma_int_raw.trans_done;
+    hw->ctrl.d_pol = level;     //set default level for MOSI only on IDLE state
 }
 
 /**
- * Trigger start of user-defined transaction for master.
- * The synchronization between two clock domains is required in ESP32-S3
+ * Apply the register configurations and wait until it's done
  *
  * @param hw Beginning address of the peripheral registers.
  */
-static inline void spi_ll_master_user_start(spi_dev_t *hw)
+static inline void spi_ll_apply_config(spi_dev_t *hw)
 {
     hw->cmd.update = 1;
-    while (hw->cmd.update);
-    hw->cmd.usr = 1;
+    while (hw->cmd.update);    //waiting config applied
+}
+
+/**
+ * Check whether user-defined transaction is done.
+ *
+ * @param hw Beginning address of the peripheral registers.
+ *
+ * @return   True if transaction is done, otherwise false.
+ */
+static inline bool spi_ll_usr_is_done(spi_dev_t *hw)
+{
+    return hw->dma_int_raw.trans_done;
 }
 
 /**
- * Trigger start of user-defined transaction for slave.
+ * Trigger start of user-defined transaction.
  *
  * @param hw Beginning address of the peripheral registers.
  */
-static inline void spi_ll_slave_user_start(spi_dev_t *hw)
+static inline void spi_ll_user_start(spi_dev_t *hw)
 {
     hw->cmd.usr = 1;
 }

+ 5 - 0
components/hal/spi_hal.c

@@ -56,6 +56,10 @@ void spi_hal_init(spi_hal_context_t *hal, uint32_t host_id, const spi_hal_config
     hal->rx_dma_chan = config->rx_dma_chan;
     hal->dmadesc_n = config->dmadesc_n;
 
+#if SPI_LL_MOSI_FREE_LEVEL
+    // Change default data line level to low which same as esp32
+    spi_ll_set_mosi_free_level(hw, 0);
+#endif
     spi_ll_master_init(hw);
     s_spi_hal_dma_init_config(hal);
 
@@ -66,6 +70,7 @@ void spi_hal_init(spi_hal_context_t *hal, uint32_t host_id, const spi_hal_config
     spi_ll_enable_int(hw);
     spi_ll_set_int_stat(hw);
     spi_ll_set_mosi_delay(hw, 0, 0);
+    spi_ll_apply_config(hw);
 }
 
 void spi_hal_deinit(spi_hal_context_t *hal)

+ 3 - 2
components/hal/spi_hal_iram.c

@@ -1,5 +1,5 @@
 /*
- * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -186,7 +186,8 @@ void spi_hal_prepare_data(spi_hal_context_t *hal, const spi_hal_dev_config_t *de
 
 void spi_hal_user_start(const spi_hal_context_t *hal)
 {
-    spi_ll_master_user_start(hal->hw);
+    spi_ll_apply_config(hal->hw);
+    spi_ll_user_start(hal->hw);
 }
 
 bool spi_hal_usr_is_done(const spi_hal_context_t *hal)

+ 1 - 1
components/hal/spi_slave_hal_iram.c

@@ -27,7 +27,7 @@ bool spi_slave_hal_usr_is_done(spi_slave_hal_context_t* hal)
 void spi_slave_hal_user_start(const spi_slave_hal_context_t *hal)
 {
     spi_ll_clear_int_stat(hal->hw); //clear int bit
-    spi_ll_slave_user_start(hal->hw);
+    spi_ll_user_start(hal->hw);
 }
 
 void spi_slave_hal_prepare_data(const spi_slave_hal_context_t *hal)