drivers: spi: esp32: Fix clock initialization
The clock should be initialised only once at the drivers init function. Check wether the subsys needs to be disabled in peripheral initialization according to reset reason in clock control. Signed-off-by: Lucas Tamborrino <lucas.tamborrino@espressif.com>
This commit is contained in:
parent
54cb89b8d7
commit
604ea9243a
@ -53,6 +53,284 @@
|
||||
#include <zephyr/logging/log.h>
|
||||
LOG_MODULE_REGISTER(clock_control, CONFIG_CLOCK_CONTROL_LOG_LEVEL);
|
||||
|
||||
static bool reset_reason_is_cpu_reset(void)
|
||||
{
|
||||
soc_reset_reason_t rst_reason = esp_rom_get_reset_reason(0);
|
||||
|
||||
if ((rst_reason == RESET_REASON_CPU0_MWDT0 || rst_reason == RESET_REASON_CPU0_SW ||
|
||||
rst_reason == RESET_REASON_CPU0_RTC_WDT
|
||||
#if !defined(CONFIG_SOC_SERIES_ESP32)
|
||||
|| rst_reason == RESET_REASON_CPU0_MWDT1
|
||||
#endif
|
||||
)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void esp32_clock_perip_init(void)
|
||||
{
|
||||
uint32_t common_perip_clk;
|
||||
uint32_t hwcrypto_perip_clk;
|
||||
uint32_t wifi_bt_sdio_clk;
|
||||
#if !defined(CONFIG_SOC_SERIES_ESP32)
|
||||
uint32_t common_perip_clk1;
|
||||
#endif
|
||||
|
||||
/* For reason that only reset CPU, do not disable the clocks
|
||||
* that have been enabled before reset.
|
||||
*/
|
||||
if (reset_reason_is_cpu_reset()) {
|
||||
#if (defined(CONFIG_SOC_SERIES_ESP32C3) || defined(CONFIG_SOC_SERIES_ESP32S3))
|
||||
common_perip_clk = ~READ_PERI_REG(SYSTEM_PERIP_CLK_EN0_REG);
|
||||
hwcrypto_perip_clk = ~READ_PERI_REG(SYSTEM_PERIP_CLK_EN1_REG);
|
||||
wifi_bt_sdio_clk = ~READ_PERI_REG(SYSTEM_WIFI_CLK_EN_REG);
|
||||
#else /* CONFIG_SOC_SERIES_ESP32 || CONFIG_SOC_SERIES_ESP32S2 */
|
||||
common_perip_clk = ~DPORT_READ_PERI_REG(DPORT_PERIP_CLK_EN_REG);
|
||||
hwcrypto_perip_clk = ~DPORT_READ_PERI_REG(DPORT_PERI_CLK_EN_REG);
|
||||
wifi_bt_sdio_clk = ~DPORT_READ_PERI_REG(DPORT_WIFI_CLK_EN_REG);
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_SOC_SERIES_ESP32S2)
|
||||
hwcrypto_perip_clk = ~DPORT_READ_PERI_REG(DPORT_PERIP_CLK_EN1_REG);
|
||||
#endif
|
||||
} else {
|
||||
common_perip_clk =
|
||||
#if (defined(CONFIG_SOC_SERIES_ESP32C3) || defined(CONFIG_SOC_SERIES_ESP32S3))
|
||||
SYSTEM_WDG_CLK_EN |
|
||||
SYSTEM_I2S0_CLK_EN |
|
||||
#if ESP_CONSOLE_UART_NUM != 0
|
||||
SYSTEM_UART_CLK_EN |
|
||||
#endif
|
||||
#if ESP_CONSOLE_UART_NUM != 1
|
||||
SYSTEM_UART1_CLK_EN |
|
||||
#endif
|
||||
#if defined(CONFIG_SOC_SERIES_ESP32S3)
|
||||
#if ESP_CONSOLE_UART_NUM != 2
|
||||
SYSTEM_UART2_CLK_EN |
|
||||
#endif
|
||||
SYSTEM_USB_CLK_EN |
|
||||
SYSTEM_PCNT_CLK_EN |
|
||||
SYSTEM_LEDC_CLK_EN |
|
||||
SYSTEM_PWM0_CLK_EN |
|
||||
SYSTEM_PWM1_CLK_EN |
|
||||
SYSTEM_PWM2_CLK_EN |
|
||||
SYSTEM_PWM3_CLK_EN |
|
||||
#endif /* CONFIG_SOC_SERIES_ESP32S3 */
|
||||
SYSTEM_SPI2_CLK_EN |
|
||||
SYSTEM_I2C_EXT0_CLK_EN |
|
||||
SYSTEM_UHCI0_CLK_EN |
|
||||
SYSTEM_RMT_CLK_EN |
|
||||
SYSTEM_LEDC_CLK_EN |
|
||||
SYSTEM_TIMERGROUP1_CLK_EN |
|
||||
SYSTEM_SPI3_CLK_EN |
|
||||
SYSTEM_SPI4_CLK_EN |
|
||||
SYSTEM_TWAI_CLK_EN |
|
||||
SYSTEM_I2S1_CLK_EN |
|
||||
SYSTEM_SPI2_DMA_CLK_EN |
|
||||
SYSTEM_SPI3_DMA_CLK_EN;
|
||||
#else /* CONFIG_SOC_SERIES_ESP32 || CONFIG_SOC_SERIES_ESP32S2 */
|
||||
DPORT_WDG_CLK_EN |
|
||||
DPORT_PCNT_CLK_EN |
|
||||
DPORT_LEDC_CLK_EN |
|
||||
DPORT_TIMERGROUP1_CLK_EN |
|
||||
DPORT_PWM0_CLK_EN |
|
||||
DPORT_TWAI_CLK_EN |
|
||||
DPORT_PWM1_CLK_EN |
|
||||
DPORT_PWM2_CLK_EN |
|
||||
#if defined(CONFIG_SOC_SERIES_ESP32S2)
|
||||
DPORT_I2S0_CLK_EN |
|
||||
DPORT_SPI2_CLK_EN |
|
||||
DPORT_I2C_EXT0_CLK_EN |
|
||||
DPORT_UHCI0_CLK_EN |
|
||||
DPORT_RMT_CLK_EN |
|
||||
DPORT_SPI3_CLK_EN |
|
||||
DPORT_I2S1_CLK_EN |
|
||||
DPORT_SPI2_DMA_CLK_EN |
|
||||
DPORT_SPI3_DMA_CLK_EN |
|
||||
#endif /* CONFIG_SOC_SERIES_ESP32S2 */
|
||||
DPORT_PWM3_CLK_EN;
|
||||
#endif /* CONFIG_SOC_SERIES_ESP32C3 || CONFIG_SOC_SERIES_ESP32S3 */
|
||||
|
||||
#if !defined(CONFIG_SOC_SERIES_ESP32)
|
||||
common_perip_clk1 = 0;
|
||||
#endif
|
||||
hwcrypto_perip_clk =
|
||||
#if defined(CONFIG_SOC_SERIES_ESP32)
|
||||
DPORT_PERI_EN_AES |
|
||||
DPORT_PERI_EN_SHA |
|
||||
DPORT_PERI_EN_RSA |
|
||||
DPORT_PERI_EN_SECUREBOOT;
|
||||
#endif /* CONFIG_SOC_SERIES_ESP32 */
|
||||
#if defined(CONFIG_SOC_SERIES_ESP32S2)
|
||||
DPORT_CRYPTO_AES_CLK_EN |
|
||||
DPORT_CRYPTO_SHA_CLK_EN |
|
||||
DPORT_CRYPTO_RSA_CLK_EN;
|
||||
#endif /* CONFIG_SOC_SERIES_ESP32S2 */
|
||||
#if (defined(CONFIG_SOC_SERIES_ESP32C3) || defined(CONFIG_SOC_SERIES_ESP32S3))
|
||||
SYSTEM_CRYPTO_AES_CLK_EN |
|
||||
SYSTEM_CRYPTO_SHA_CLK_EN |
|
||||
SYSTEM_CRYPTO_RSA_CLK_EN;
|
||||
#endif /* CONFIG_SOC_SERIES_ESP32C3 || CONFIG_SOC_SERIES_ESP32S3 */
|
||||
|
||||
wifi_bt_sdio_clk =
|
||||
#if (defined(CONFIG_SOC_SERIES_ESP32C3) || defined(CONFIG_SOC_SERIES_ESP32S3))
|
||||
SYSTEM_WIFI_CLK_WIFI_EN |
|
||||
SYSTEM_WIFI_CLK_BT_EN_M |
|
||||
SYSTEM_WIFI_CLK_I2C_CLK_EN |
|
||||
#if defined(CONFIG_SOC_SERIES_ESP32S3)
|
||||
SYSTEM_WIFI_CLK_SDIO_HOST_EN |
|
||||
#endif /* CONFIG_SOC_SERIES_ESP32S3 */
|
||||
SYSTEM_WIFI_CLK_UNUSED_BIT12;
|
||||
#else /* CONFIG_SOC_SERIES_ESP32 || CONFIG_SOC_SERIES_ESP32S2 */
|
||||
DPORT_WIFI_CLK_WIFI_EN |
|
||||
DPORT_WIFI_CLK_BT_EN_M |
|
||||
DPORT_WIFI_CLK_UNUSED_BIT5 |
|
||||
DPORT_WIFI_CLK_UNUSED_BIT12 |
|
||||
DPORT_WIFI_CLK_SDIOSLAVE_EN |
|
||||
DPORT_WIFI_CLK_SDIO_HOST_EN |
|
||||
DPORT_WIFI_CLK_EMAC_EN;
|
||||
#endif /* CONFIG_SOC_SERIES_ESP32C3 */
|
||||
}
|
||||
|
||||
/* Reset peripherals like I2C, SPI, UART, I2S and bring them to known state */
|
||||
common_perip_clk |=
|
||||
#if (defined(CONFIG_SOC_SERIES_ESP32C3) || defined(CONFIG_SOC_SERIES_ESP32S3))
|
||||
SYSTEM_I2S0_CLK_EN |
|
||||
#if ESP_CONSOLE_UART_NUM != 0
|
||||
SYSTEM_UART_CLK_EN |
|
||||
#endif
|
||||
#if ESP_CONSOLE_UART_NUM != 1
|
||||
SYSTEM_UART1_CLK_EN |
|
||||
#endif
|
||||
#if defined(CONFIG_SOC_SERIES_ESP32S3)
|
||||
#if ESP_CONSOLE_UART_NUM != 2
|
||||
SYSTEM_UART2_CLK_EN |
|
||||
#endif
|
||||
SYSTEM_USB_CLK_EN |
|
||||
#endif
|
||||
SYSTEM_SPI2_CLK_EN |
|
||||
SYSTEM_I2C_EXT0_CLK_EN |
|
||||
SYSTEM_UHCI0_CLK_EN |
|
||||
SYSTEM_RMT_CLK_EN |
|
||||
SYSTEM_UHCI1_CLK_EN |
|
||||
SYSTEM_SPI3_CLK_EN |
|
||||
SYSTEM_SPI4_CLK_EN |
|
||||
SYSTEM_I2C_EXT1_CLK_EN |
|
||||
SYSTEM_I2S1_CLK_EN |
|
||||
SYSTEM_SPI2_DMA_CLK_EN |
|
||||
SYSTEM_SPI3_DMA_CLK_EN;
|
||||
#else
|
||||
DPORT_I2S0_CLK_EN |
|
||||
DPORT_SPI2_CLK_EN |
|
||||
DPORT_I2C_EXT0_CLK_EN |
|
||||
DPORT_UHCI0_CLK_EN |
|
||||
DPORT_RMT_CLK_EN |
|
||||
DPORT_UHCI1_CLK_EN |
|
||||
DPORT_SPI3_CLK_EN |
|
||||
DPORT_I2C_EXT1_CLK_EN |
|
||||
#if ESP_CONSOLE_UART_NUM != 0
|
||||
DPORT_UART_CLK_EN |
|
||||
#endif
|
||||
#if ESP_CONSOLE_UART_NUM != 1
|
||||
DPORT_UART1_CLK_EN |
|
||||
#endif
|
||||
#if defined(CONFIG_SOC_SERIES_ESP32)
|
||||
DPORT_SPI_DMA_CLK_EN |
|
||||
#if ESP_CONSOLE_UART_NUM != 2
|
||||
DPORT_UART2_CLK_EN |
|
||||
#endif
|
||||
#endif /* CONFIG_SOC_SERIES_ESP32 */
|
||||
#if defined(CONFIG_SOC_SERIES_ESP32S2)
|
||||
DPORT_USB_CLK_EN |
|
||||
DPORT_SPI2_DMA_CLK_EN |
|
||||
DPORT_SPI3_DMA_CLK_EN |
|
||||
#endif /* CONFIG_SOC_SERIES_ESP32S2 */
|
||||
DPORT_I2S1_CLK_EN;
|
||||
#endif /* CONFIG_SOC_SERIES_ESP32C3 */
|
||||
|
||||
#if !defined(CONFIG_SOC_SERIES_ESP32)
|
||||
common_perip_clk1 = 0;
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_SOC_SERIES_ESP32)
|
||||
common_perip_clk &= ~DPORT_SPI01_CLK_EN;
|
||||
#if defined(CONFIG_SPIRAM_SPEED_80M)
|
||||
/*
|
||||
* 80MHz SPIRAM uses SPI2/SPI3 as well; it's initialized before this is called. Because it
|
||||
* is used in a weird mode where clock to the peripheral is disabled but reset is also
|
||||
* disabled, it 'hangs' in a state where it outputs a continuous 80MHz signal. Mask its bit
|
||||
* here because we should not modify that state, regardless of what we calculated earlier.
|
||||
*/
|
||||
common_perip_clk &= ~DPORT_SPI2_CLK_EN;
|
||||
common_perip_clk &= ~DPORT_SPI3_CLK_EN;
|
||||
#endif
|
||||
#endif /* CONFIG_SOC_SERIES_ESP32 */
|
||||
|
||||
/* Change I2S clock to audio PLL first. Because if I2S uses 160MHz clock,
|
||||
* the current is not reduced when disable I2S clock.
|
||||
*/
|
||||
#if defined(CONFIG_SOC_SERIES_ESP32)
|
||||
DPORT_SET_PERI_REG_MASK(I2S_CLKM_CONF_REG(0), I2S_CLKA_ENA);
|
||||
DPORT_SET_PERI_REG_MASK(I2S_CLKM_CONF_REG(1), I2S_CLKA_ENA);
|
||||
#endif /* CONFIG_SOC_SERIES_ESP32 */
|
||||
#if defined(CONFIG_SOC_SERIES_ESP32S2)
|
||||
REG_SET_FIELD(I2S_CLKM_CONF_REG(0), I2S_CLK_SEL, I2S_CLK_AUDIO_PLL);
|
||||
REG_SET_FIELD(I2S_CLKM_CONF_REG(1), I2S_CLK_SEL, I2S_CLK_AUDIO_PLL);
|
||||
#endif /* CONFIG_SOC_SERIES_ESP32S2 */
|
||||
|
||||
/* Disable some peripheral clocks. */
|
||||
#if (defined(CONFIG_SOC_SERIES_ESP32C3) || defined(CONFIG_SOC_SERIES_ESP32S3))
|
||||
CLEAR_PERI_REG_MASK(SYSTEM_PERIP_CLK_EN0_REG, common_perip_clk);
|
||||
SET_PERI_REG_MASK(SYSTEM_PERIP_RST_EN0_REG, common_perip_clk);
|
||||
|
||||
CLEAR_PERI_REG_MASK(SYSTEM_PERIP_CLK_EN1_REG, common_perip_clk1);
|
||||
SET_PERI_REG_MASK(SYSTEM_PERIP_RST_EN1_REG, common_perip_clk1);
|
||||
#else /* CONFIG_SOC_SERIES_ESP32 || CONFIG_SOC_SERIES_ESP32S2 */
|
||||
DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, common_perip_clk);
|
||||
DPORT_SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, common_perip_clk);
|
||||
#endif /* CONFIG_SOC_SERIES_ESP32C3 || CONFIG_SOC_SERIES_ESP32S3 */
|
||||
|
||||
/* Disable hardware crypto clocks. */
|
||||
#if (defined(CONFIG_SOC_SERIES_ESP32C3) || defined(CONFIG_SOC_SERIES_ESP32S3))
|
||||
CLEAR_PERI_REG_MASK(SYSTEM_PERIP_CLK_EN1_REG, hwcrypto_perip_clk);
|
||||
SET_PERI_REG_MASK(SYSTEM_PERIP_RST_EN1_REG, hwcrypto_perip_clk);
|
||||
#else /* CONFIG_SOC_SERIES_ESP32 || CONFIG_SOC_SERIES_ESP32S2 */
|
||||
DPORT_CLEAR_PERI_REG_MASK(DPORT_PERI_CLK_EN_REG, hwcrypto_perip_clk);
|
||||
DPORT_SET_PERI_REG_MASK(DPORT_PERI_RST_EN_REG, hwcrypto_perip_clk);
|
||||
#endif /* CONFIG_SOC_SERIES_ESP32C3 || CONFIG_SOC_SERIES_ESP32S3 */
|
||||
|
||||
#if defined(CONFIG_SOC_SERIES_ESP32S3)
|
||||
/* Force clear backup dma reset signal. This is a fix to the backup dma
|
||||
* implementation in the ROM, the reset signal was not cleared when the
|
||||
* backup dma was started, which caused the backup dma operation to fail.
|
||||
*/
|
||||
CLEAR_PERI_REG_MASK(SYSTEM_PERIP_RST_EN1_REG, SYSTEM_PERI_BACKUP_RST);
|
||||
#endif /* CONFIG_SOC_SERIES_ESP32S3 */
|
||||
|
||||
/* Disable WiFi/BT/SDIO clocks. */
|
||||
#if (defined(CONFIG_SOC_SERIES_ESP32C3) || defined(CONFIG_SOC_SERIES_ESP32S3))
|
||||
CLEAR_PERI_REG_MASK(SYSTEM_WIFI_CLK_EN_REG, wifi_bt_sdio_clk);
|
||||
SET_PERI_REG_MASK(SYSTEM_WIFI_CLK_EN_REG, SYSTEM_WIFI_CLK_EN);
|
||||
#else /* CONFIG_SOC_SERIES_ESP32 || CONFIG_SOC_SERIES_ESP32S2 */
|
||||
DPORT_CLEAR_PERI_REG_MASK(DPORT_WIFI_CLK_EN_REG, wifi_bt_sdio_clk);
|
||||
#endif /* CONFIG_SOC_SERIES_ESP32C3 || CONFIG_SOC_SERIES_ESP32S3 */
|
||||
|
||||
#if (defined(CONFIG_SOC_SERIES_ESP32C3) || defined(CONFIG_SOC_SERIES_ESP32S3))
|
||||
/* Set WiFi light sleep clock source to RTC slow clock */
|
||||
REG_SET_FIELD(SYSTEM_BT_LPCK_DIV_INT_REG, SYSTEM_BT_LPCK_DIV_NUM, 0);
|
||||
CLEAR_PERI_REG_MASK(SYSTEM_BT_LPCK_DIV_FRAC_REG, SYSTEM_LPCLK_SEL_8M);
|
||||
SET_PERI_REG_MASK(SYSTEM_BT_LPCK_DIV_FRAC_REG, SYSTEM_LPCLK_SEL_RTC_SLOW);
|
||||
#endif
|
||||
|
||||
/* Enable RNG clock. */
|
||||
periph_module_enable(PERIPH_RNG_MODULE);
|
||||
|
||||
#if (defined(CONFIG_SOC_SERIES_ESP32C3) || defined(CONFIG_SOC_SERIES_ESP32S3))
|
||||
periph_module_enable(PERIPH_TIMG0_MODULE);
|
||||
#endif
|
||||
}
|
||||
|
||||
static enum clock_control_status clock_control_esp32_get_status(const struct device *dev,
|
||||
clock_control_subsys_t sys)
|
||||
{
|
||||
@ -70,7 +348,7 @@ static int clock_control_esp32_on(const struct device *dev, clock_control_subsys
|
||||
{
|
||||
enum clock_control_status status = clock_control_esp32_get_status(dev, sys);
|
||||
|
||||
if (status == CLOCK_CONTROL_STATUS_ON) {
|
||||
if (status == CLOCK_CONTROL_STATUS_ON && !reset_reason_is_cpu_reset()) {
|
||||
return -EALREADY;
|
||||
}
|
||||
|
||||
@ -109,405 +387,6 @@ static int clock_control_esp32_get_rate(const struct device *dev, clock_control_
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_SOC_SERIES_ESP32)
|
||||
static void esp32_clock_perip_init(void)
|
||||
{
|
||||
uint32_t common_perip_clk;
|
||||
uint32_t hwcrypto_perip_clk;
|
||||
uint32_t wifi_bt_sdio_clk;
|
||||
|
||||
#if !CONFIG_SMP
|
||||
soc_reset_reason_t rst_reas[1];
|
||||
#else
|
||||
soc_reset_reason_t rst_reas[2];
|
||||
#endif
|
||||
|
||||
rst_reas[0] = esp_rom_get_reset_reason(0);
|
||||
#if CONFIG_SMP
|
||||
rst_reas[1] = esp_rom_get_reset_reason(1);
|
||||
#endif
|
||||
|
||||
/* For reason that only reset CPU, do not disable the clocks
|
||||
* that have been enabled before reset.
|
||||
*/
|
||||
if ((rst_reas[0] == RESET_REASON_CPU0_MWDT0 || rst_reas[0] == RESET_REASON_CPU0_SW ||
|
||||
rst_reas[0] == RESET_REASON_CPU0_RTC_WDT)
|
||||
#if CONFIG_SMP
|
||||
|| (rst_reas[1] == RESET_REASON_CPU1_MWDT1 || rst_reas[1] == RESET_REASON_CPU1_SW ||
|
||||
rst_reas[1] == RESET_REASON_CPU1_RTC_WDT)
|
||||
#endif
|
||||
) {
|
||||
common_perip_clk = ~DPORT_READ_PERI_REG(DPORT_PERIP_CLK_EN_REG);
|
||||
hwcrypto_perip_clk = ~DPORT_READ_PERI_REG(DPORT_PERI_CLK_EN_REG);
|
||||
wifi_bt_sdio_clk = ~DPORT_READ_PERI_REG(DPORT_WIFI_CLK_EN_REG);
|
||||
} else {
|
||||
common_perip_clk = DPORT_WDG_CLK_EN |
|
||||
DPORT_PCNT_CLK_EN |
|
||||
DPORT_LEDC_CLK_EN |
|
||||
DPORT_TIMERGROUP1_CLK_EN |
|
||||
DPORT_PWM0_CLK_EN |
|
||||
DPORT_TWAI_CLK_EN |
|
||||
DPORT_PWM1_CLK_EN |
|
||||
DPORT_PWM2_CLK_EN |
|
||||
DPORT_PWM3_CLK_EN;
|
||||
|
||||
hwcrypto_perip_clk = DPORT_PERI_EN_AES |
|
||||
DPORT_PERI_EN_SHA |
|
||||
DPORT_PERI_EN_RSA |
|
||||
DPORT_PERI_EN_SECUREBOOT;
|
||||
|
||||
wifi_bt_sdio_clk = DPORT_WIFI_CLK_WIFI_EN |
|
||||
DPORT_WIFI_CLK_BT_EN_M |
|
||||
DPORT_WIFI_CLK_UNUSED_BIT5 |
|
||||
DPORT_WIFI_CLK_UNUSED_BIT12 |
|
||||
DPORT_WIFI_CLK_SDIOSLAVE_EN |
|
||||
DPORT_WIFI_CLK_SDIO_HOST_EN |
|
||||
DPORT_WIFI_CLK_EMAC_EN;
|
||||
}
|
||||
|
||||
/* Reset peripherals like I2C, SPI, UART, I2S and bring them to known state */
|
||||
common_perip_clk |= DPORT_I2S0_CLK_EN |
|
||||
DPORT_UART_CLK_EN |
|
||||
DPORT_SPI2_CLK_EN |
|
||||
DPORT_I2C_EXT0_CLK_EN |
|
||||
DPORT_UHCI0_CLK_EN |
|
||||
DPORT_RMT_CLK_EN |
|
||||
DPORT_UHCI1_CLK_EN |
|
||||
DPORT_SPI3_CLK_EN |
|
||||
DPORT_I2C_EXT1_CLK_EN |
|
||||
DPORT_I2S1_CLK_EN |
|
||||
DPORT_SPI_DMA_CLK_EN;
|
||||
|
||||
common_perip_clk &= ~DPORT_SPI01_CLK_EN;
|
||||
common_perip_clk &= ~DPORT_SPI2_CLK_EN;
|
||||
common_perip_clk &= ~DPORT_SPI3_CLK_EN;
|
||||
|
||||
/* Change I2S clock to audio PLL first. Because if I2S uses 160MHz clock,
|
||||
* the current is not reduced when disable I2S clock.
|
||||
*/
|
||||
DPORT_SET_PERI_REG_MASK(I2S_CLKM_CONF_REG(0), I2S_CLKA_ENA);
|
||||
DPORT_SET_PERI_REG_MASK(I2S_CLKM_CONF_REG(1), I2S_CLKA_ENA);
|
||||
|
||||
/* Disable some peripheral clocks. */
|
||||
DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, common_perip_clk);
|
||||
DPORT_SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, common_perip_clk);
|
||||
|
||||
/* Disable hardware crypto clocks. */
|
||||
DPORT_CLEAR_PERI_REG_MASK(DPORT_PERI_CLK_EN_REG, hwcrypto_perip_clk);
|
||||
DPORT_SET_PERI_REG_MASK(DPORT_PERI_RST_EN_REG, hwcrypto_perip_clk);
|
||||
|
||||
/* Disable WiFi/BT/SDIO clocks. */
|
||||
DPORT_CLEAR_PERI_REG_MASK(DPORT_WIFI_CLK_EN_REG, wifi_bt_sdio_clk);
|
||||
|
||||
/* Enable RNG clock. */
|
||||
periph_module_enable(PERIPH_RNG_MODULE);
|
||||
}
|
||||
#endif /* CONFIG_SOC_SERIES_ESP32 */
|
||||
|
||||
#if defined(CONFIG_SOC_SERIES_ESP32S2)
|
||||
static void esp32_clock_perip_init(void)
|
||||
{
|
||||
uint32_t common_perip_clk;
|
||||
uint32_t hwcrypto_perip_clk;
|
||||
uint32_t wifi_bt_sdio_clk;
|
||||
uint32_t common_perip_clk1;
|
||||
|
||||
soc_reset_reason_t rst_reason = esp_rom_get_reset_reason(0);
|
||||
|
||||
/* For reason that only reset CPU, do not disable the clocks
|
||||
* that have been enabled before reset.
|
||||
*/
|
||||
if (rst_reason == RESET_REASON_CPU0_MWDT0 || rst_reason == RESET_REASON_CPU0_SW ||
|
||||
rst_reason == RESET_REASON_CPU0_RTC_WDT || rst_reason == RESET_REASON_CPU0_MWDT1) {
|
||||
common_perip_clk = ~DPORT_READ_PERI_REG(DPORT_PERIP_CLK_EN_REG);
|
||||
hwcrypto_perip_clk = ~DPORT_READ_PERI_REG(DPORT_PERIP_CLK_EN1_REG);
|
||||
wifi_bt_sdio_clk = ~DPORT_READ_PERI_REG(DPORT_WIFI_CLK_EN_REG);
|
||||
} else {
|
||||
common_perip_clk = DPORT_WDG_CLK_EN |
|
||||
DPORT_I2S0_CLK_EN |
|
||||
DPORT_UART1_CLK_EN |
|
||||
DPORT_SPI2_CLK_EN |
|
||||
DPORT_I2C_EXT0_CLK_EN |
|
||||
DPORT_UHCI0_CLK_EN |
|
||||
DPORT_RMT_CLK_EN |
|
||||
DPORT_PCNT_CLK_EN |
|
||||
DPORT_LEDC_CLK_EN |
|
||||
DPORT_TIMERGROUP1_CLK_EN |
|
||||
DPORT_SPI3_CLK_EN |
|
||||
DPORT_PWM0_CLK_EN |
|
||||
DPORT_TWAI_CLK_EN |
|
||||
DPORT_PWM1_CLK_EN |
|
||||
DPORT_I2S1_CLK_EN |
|
||||
DPORT_SPI2_DMA_CLK_EN |
|
||||
DPORT_SPI3_DMA_CLK_EN |
|
||||
DPORT_PWM2_CLK_EN |
|
||||
DPORT_PWM3_CLK_EN;
|
||||
|
||||
common_perip_clk1 = 0;
|
||||
|
||||
hwcrypto_perip_clk = DPORT_CRYPTO_AES_CLK_EN |
|
||||
DPORT_CRYPTO_SHA_CLK_EN |
|
||||
DPORT_CRYPTO_RSA_CLK_EN;
|
||||
|
||||
wifi_bt_sdio_clk = DPORT_WIFI_CLK_WIFI_EN |
|
||||
DPORT_WIFI_CLK_BT_EN_M |
|
||||
DPORT_WIFI_CLK_UNUSED_BIT5 |
|
||||
DPORT_WIFI_CLK_UNUSED_BIT12 |
|
||||
DPORT_WIFI_CLK_SDIOSLAVE_EN |
|
||||
DPORT_WIFI_CLK_SDIO_HOST_EN |
|
||||
DPORT_WIFI_CLK_EMAC_EN;
|
||||
}
|
||||
|
||||
/* Reset peripherals like I2C, SPI, UART, I2S and bring them to known state */
|
||||
common_perip_clk |= DPORT_I2S0_CLK_EN |
|
||||
DPORT_UART1_CLK_EN |
|
||||
DPORT_USB_CLK_EN |
|
||||
DPORT_SPI2_CLK_EN |
|
||||
DPORT_I2C_EXT0_CLK_EN |
|
||||
DPORT_UHCI0_CLK_EN |
|
||||
DPORT_RMT_CLK_EN |
|
||||
DPORT_UHCI1_CLK_EN |
|
||||
DPORT_SPI3_CLK_EN |
|
||||
DPORT_I2C_EXT1_CLK_EN |
|
||||
DPORT_I2S1_CLK_EN |
|
||||
DPORT_SPI2_DMA_CLK_EN |
|
||||
DPORT_SPI3_DMA_CLK_EN;
|
||||
|
||||
common_perip_clk1 = 0;
|
||||
|
||||
/* Change I2S clock to audio PLL first. Because if I2S uses 160MHz clock,
|
||||
* the current is not reduced when disable I2S clock.
|
||||
*/
|
||||
REG_SET_FIELD(I2S_CLKM_CONF_REG(0), I2S_CLK_SEL, I2S_CLK_AUDIO_PLL);
|
||||
REG_SET_FIELD(I2S_CLKM_CONF_REG(1), I2S_CLK_SEL, I2S_CLK_AUDIO_PLL);
|
||||
|
||||
/* Disable some peripheral clocks. */
|
||||
DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, common_perip_clk);
|
||||
DPORT_SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, common_perip_clk);
|
||||
|
||||
DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_CLK_EN1_REG, common_perip_clk1);
|
||||
DPORT_SET_PERI_REG_MASK(DPORT_PERIP_RST_EN1_REG, common_perip_clk1);
|
||||
|
||||
/* Disable hardware crypto clocks. */
|
||||
DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_CLK_EN1_REG, hwcrypto_perip_clk);
|
||||
DPORT_SET_PERI_REG_MASK(DPORT_PERIP_RST_EN1_REG, hwcrypto_perip_clk);
|
||||
|
||||
/* Disable WiFi/BT/SDIO clocks. */
|
||||
DPORT_CLEAR_PERI_REG_MASK(DPORT_WIFI_CLK_EN_REG, wifi_bt_sdio_clk);
|
||||
|
||||
/* Enable WiFi MAC and POWER clocks */
|
||||
DPORT_SET_PERI_REG_MASK(DPORT_WIFI_CLK_EN_REG, DPORT_WIFI_CLK_WIFI_EN);
|
||||
|
||||
/* Set WiFi light sleep clock source to RTC slow clock */
|
||||
DPORT_REG_SET_FIELD(DPORT_BT_LPCK_DIV_INT_REG, DPORT_BT_LPCK_DIV_NUM, 0);
|
||||
DPORT_CLEAR_PERI_REG_MASK(DPORT_BT_LPCK_DIV_FRAC_REG, DPORT_LPCLK_SEL_8M);
|
||||
DPORT_SET_PERI_REG_MASK(DPORT_BT_LPCK_DIV_FRAC_REG, DPORT_LPCLK_SEL_RTC_SLOW);
|
||||
|
||||
/* Enable RNG clock. */
|
||||
periph_module_enable(PERIPH_RNG_MODULE);
|
||||
}
|
||||
#endif /* CONFIG_SOC_SERIES_ESP32S2 */
|
||||
|
||||
#if defined(CONFIG_SOC_SERIES_ESP32S3)
|
||||
static void esp32_clock_perip_init(void)
|
||||
{
|
||||
#if defined(CONFIG_SOC_ESP32S3_APPCPU)
|
||||
/* skip APPCPU configuration */
|
||||
return;
|
||||
#endif
|
||||
|
||||
uint32_t common_perip_clk, hwcrypto_perip_clk, wifi_bt_sdio_clk = 0;
|
||||
uint32_t common_perip_clk1 = 0;
|
||||
|
||||
soc_reset_reason_t rst_reason = esp_rom_get_reset_reason(0);
|
||||
|
||||
/* For reason that only reset CPU, do not disable the clocks
|
||||
* that have been enabled before reset.
|
||||
*/
|
||||
if (rst_reason == RESET_REASON_CPU0_MWDT0 || rst_reason == RESET_REASON_CPU0_SW ||
|
||||
rst_reason == RESET_REASON_CPU0_RTC_WDT || rst_reason == RESET_REASON_CPU0_MWDT1) {
|
||||
common_perip_clk = ~READ_PERI_REG(SYSTEM_PERIP_CLK_EN0_REG);
|
||||
hwcrypto_perip_clk = ~READ_PERI_REG(SYSTEM_PERIP_CLK_EN1_REG);
|
||||
wifi_bt_sdio_clk = ~READ_PERI_REG(SYSTEM_WIFI_CLK_EN_REG);
|
||||
} else {
|
||||
common_perip_clk = SYSTEM_WDG_CLK_EN |
|
||||
SYSTEM_I2S0_CLK_EN |
|
||||
SYSTEM_UART1_CLK_EN |
|
||||
SYSTEM_UART2_CLK_EN |
|
||||
SYSTEM_USB_CLK_EN |
|
||||
SYSTEM_SPI2_CLK_EN |
|
||||
SYSTEM_I2C_EXT0_CLK_EN |
|
||||
SYSTEM_UHCI0_CLK_EN |
|
||||
SYSTEM_RMT_CLK_EN |
|
||||
SYSTEM_PCNT_CLK_EN |
|
||||
SYSTEM_LEDC_CLK_EN |
|
||||
SYSTEM_TIMERGROUP1_CLK_EN |
|
||||
SYSTEM_SPI3_CLK_EN |
|
||||
SYSTEM_SPI4_CLK_EN |
|
||||
SYSTEM_PWM0_CLK_EN |
|
||||
SYSTEM_TWAI_CLK_EN |
|
||||
SYSTEM_PWM1_CLK_EN |
|
||||
SYSTEM_I2S1_CLK_EN |
|
||||
SYSTEM_SPI2_DMA_CLK_EN |
|
||||
SYSTEM_SPI3_DMA_CLK_EN |
|
||||
SYSTEM_PWM2_CLK_EN |
|
||||
SYSTEM_PWM3_CLK_EN;
|
||||
|
||||
common_perip_clk1 = 0;
|
||||
|
||||
hwcrypto_perip_clk = SYSTEM_CRYPTO_AES_CLK_EN |
|
||||
SYSTEM_CRYPTO_SHA_CLK_EN |
|
||||
SYSTEM_CRYPTO_RSA_CLK_EN;
|
||||
|
||||
wifi_bt_sdio_clk = SYSTEM_WIFI_CLK_WIFI_EN |
|
||||
SYSTEM_WIFI_CLK_BT_EN_M |
|
||||
SYSTEM_WIFI_CLK_I2C_CLK_EN |
|
||||
SYSTEM_WIFI_CLK_UNUSED_BIT12 |
|
||||
SYSTEM_WIFI_CLK_SDIO_HOST_EN;
|
||||
}
|
||||
|
||||
/* Reset peripherals like I2C, SPI, UART, I2S and bring them to known state */
|
||||
common_perip_clk |= SYSTEM_I2S0_CLK_EN |
|
||||
SYSTEM_UART1_CLK_EN |
|
||||
SYSTEM_UART2_CLK_EN |
|
||||
SYSTEM_USB_CLK_EN |
|
||||
SYSTEM_SPI2_CLK_EN |
|
||||
SYSTEM_I2C_EXT0_CLK_EN |
|
||||
SYSTEM_UHCI0_CLK_EN |
|
||||
SYSTEM_RMT_CLK_EN |
|
||||
SYSTEM_UHCI1_CLK_EN |
|
||||
SYSTEM_SPI3_CLK_EN |
|
||||
SYSTEM_SPI4_CLK_EN |
|
||||
SYSTEM_I2C_EXT1_CLK_EN |
|
||||
SYSTEM_I2S1_CLK_EN |
|
||||
SYSTEM_SPI2_DMA_CLK_EN |
|
||||
SYSTEM_SPI3_DMA_CLK_EN;
|
||||
|
||||
common_perip_clk1 = 0;
|
||||
|
||||
/* Disable some peripheral clocks. */
|
||||
CLEAR_PERI_REG_MASK(SYSTEM_PERIP_CLK_EN0_REG, common_perip_clk);
|
||||
SET_PERI_REG_MASK(SYSTEM_PERIP_RST_EN0_REG, common_perip_clk);
|
||||
|
||||
CLEAR_PERI_REG_MASK(SYSTEM_PERIP_CLK_EN1_REG, common_perip_clk1);
|
||||
SET_PERI_REG_MASK(SYSTEM_PERIP_RST_EN1_REG, common_perip_clk1);
|
||||
|
||||
/* Disable hardware crypto clocks. */
|
||||
CLEAR_PERI_REG_MASK(SYSTEM_PERIP_CLK_EN1_REG, hwcrypto_perip_clk);
|
||||
SET_PERI_REG_MASK(SYSTEM_PERIP_RST_EN1_REG, hwcrypto_perip_clk);
|
||||
|
||||
/* Disable WiFi/BT/SDIO clocks. */
|
||||
CLEAR_PERI_REG_MASK(SYSTEM_WIFI_CLK_EN_REG, wifi_bt_sdio_clk);
|
||||
SET_PERI_REG_MASK(SYSTEM_WIFI_CLK_EN_REG, SYSTEM_WIFI_CLK_EN);
|
||||
|
||||
/* Set WiFi light sleep clock source to RTC slow clock */
|
||||
REG_SET_FIELD(SYSTEM_BT_LPCK_DIV_INT_REG, SYSTEM_BT_LPCK_DIV_NUM, 0);
|
||||
CLEAR_PERI_REG_MASK(SYSTEM_BT_LPCK_DIV_FRAC_REG, SYSTEM_LPCLK_SEL_8M);
|
||||
SET_PERI_REG_MASK(SYSTEM_BT_LPCK_DIV_FRAC_REG, SYSTEM_LPCLK_SEL_RTC_SLOW);
|
||||
|
||||
/* Enable RNG clock. */
|
||||
periph_module_enable(PERIPH_RNG_MODULE);
|
||||
|
||||
/* Enable TimerGroup 0 clock to ensure its reference counter will never
|
||||
* be decremented to 0 during normal operation and preventing it from
|
||||
* being disabled.
|
||||
* If the TimerGroup 0 clock is disabled and then reenabled, the watchdog
|
||||
* registers (Flashboot protection included) will be reenabled, and some
|
||||
* seconds later, will trigger an unintended reset.
|
||||
*/
|
||||
periph_module_enable(PERIPH_TIMG0_MODULE);
|
||||
}
|
||||
#endif /* CONFIG_SOC_SERIES_ESP32S3 */
|
||||
|
||||
#if defined(CONFIG_SOC_SERIES_ESP32C3)
|
||||
static void esp32_clock_perip_init(void)
|
||||
{
|
||||
uint32_t common_perip_clk;
|
||||
uint32_t hwcrypto_perip_clk;
|
||||
uint32_t wifi_bt_sdio_clk;
|
||||
uint32_t common_perip_clk1;
|
||||
|
||||
soc_reset_reason_t rst_reason = esp_rom_get_reset_reason(0);
|
||||
|
||||
/* For reason that only reset CPU, do not disable the clocks
|
||||
* that have been enabled before reset.
|
||||
*/
|
||||
if (rst_reason == RESET_REASON_CPU0_MWDT0 || rst_reason == RESET_REASON_CPU0_SW ||
|
||||
rst_reason == RESET_REASON_CPU0_RTC_WDT || rst_reason == RESET_REASON_CPU0_MWDT1) {
|
||||
common_perip_clk = ~READ_PERI_REG(SYSTEM_PERIP_CLK_EN0_REG);
|
||||
hwcrypto_perip_clk = ~READ_PERI_REG(SYSTEM_PERIP_CLK_EN1_REG);
|
||||
wifi_bt_sdio_clk = ~READ_PERI_REG(SYSTEM_WIFI_CLK_EN_REG);
|
||||
} else {
|
||||
common_perip_clk = SYSTEM_WDG_CLK_EN |
|
||||
SYSTEM_I2S0_CLK_EN |
|
||||
SYSTEM_UART1_CLK_EN |
|
||||
SYSTEM_SPI2_CLK_EN |
|
||||
SYSTEM_I2C_EXT0_CLK_EN |
|
||||
SYSTEM_UHCI0_CLK_EN |
|
||||
SYSTEM_RMT_CLK_EN |
|
||||
SYSTEM_LEDC_CLK_EN |
|
||||
SYSTEM_TIMERGROUP1_CLK_EN |
|
||||
SYSTEM_SPI3_CLK_EN |
|
||||
SYSTEM_SPI4_CLK_EN |
|
||||
SYSTEM_TWAI_CLK_EN |
|
||||
SYSTEM_I2S1_CLK_EN |
|
||||
SYSTEM_SPI2_DMA_CLK_EN |
|
||||
SYSTEM_SPI3_DMA_CLK_EN;
|
||||
|
||||
common_perip_clk1 = 0;
|
||||
|
||||
hwcrypto_perip_clk = SYSTEM_CRYPTO_AES_CLK_EN |
|
||||
SYSTEM_CRYPTO_SHA_CLK_EN |
|
||||
SYSTEM_CRYPTO_RSA_CLK_EN;
|
||||
|
||||
wifi_bt_sdio_clk = SYSTEM_WIFI_CLK_WIFI_EN |
|
||||
SYSTEM_WIFI_CLK_BT_EN_M |
|
||||
SYSTEM_WIFI_CLK_I2C_CLK_EN |
|
||||
SYSTEM_WIFI_CLK_UNUSED_BIT12;
|
||||
}
|
||||
|
||||
/* Reset peripherals like I2C, SPI, UART, I2S and bring them to known state */
|
||||
common_perip_clk |= SYSTEM_I2S0_CLK_EN |
|
||||
SYSTEM_UART1_CLK_EN |
|
||||
SYSTEM_SPI2_CLK_EN |
|
||||
SYSTEM_I2C_EXT0_CLK_EN |
|
||||
SYSTEM_UHCI0_CLK_EN |
|
||||
SYSTEM_RMT_CLK_EN |
|
||||
SYSTEM_UHCI1_CLK_EN |
|
||||
SYSTEM_SPI3_CLK_EN |
|
||||
SYSTEM_SPI4_CLK_EN |
|
||||
SYSTEM_I2C_EXT1_CLK_EN |
|
||||
SYSTEM_I2S1_CLK_EN |
|
||||
SYSTEM_SPI2_DMA_CLK_EN |
|
||||
SYSTEM_SPI3_DMA_CLK_EN;
|
||||
|
||||
common_perip_clk1 = 0;
|
||||
|
||||
/* Disable some peripheral clocks. */
|
||||
CLEAR_PERI_REG_MASK(SYSTEM_PERIP_CLK_EN0_REG, common_perip_clk);
|
||||
SET_PERI_REG_MASK(SYSTEM_PERIP_RST_EN0_REG, common_perip_clk);
|
||||
|
||||
CLEAR_PERI_REG_MASK(SYSTEM_PERIP_CLK_EN1_REG, common_perip_clk1);
|
||||
SET_PERI_REG_MASK(SYSTEM_PERIP_RST_EN1_REG, common_perip_clk1);
|
||||
|
||||
/* Disable hardware crypto clocks. */
|
||||
CLEAR_PERI_REG_MASK(SYSTEM_PERIP_CLK_EN1_REG, hwcrypto_perip_clk);
|
||||
SET_PERI_REG_MASK(SYSTEM_PERIP_RST_EN1_REG, hwcrypto_perip_clk);
|
||||
|
||||
/* Disable WiFi/BT/SDIO clocks. */
|
||||
CLEAR_PERI_REG_MASK(SYSTEM_WIFI_CLK_EN_REG, wifi_bt_sdio_clk);
|
||||
SET_PERI_REG_MASK(SYSTEM_WIFI_CLK_EN_REG, SYSTEM_WIFI_CLK_EN);
|
||||
|
||||
/* Set WiFi light sleep clock source to RTC slow clock */
|
||||
REG_SET_FIELD(SYSTEM_BT_LPCK_DIV_INT_REG, SYSTEM_BT_LPCK_DIV_NUM, 0);
|
||||
CLEAR_PERI_REG_MASK(SYSTEM_BT_LPCK_DIV_FRAC_REG, SYSTEM_LPCLK_SEL_8M);
|
||||
SET_PERI_REG_MASK(SYSTEM_BT_LPCK_DIV_FRAC_REG, SYSTEM_LPCLK_SEL_RTC_SLOW);
|
||||
|
||||
/* Enable RNG clock. */
|
||||
periph_module_enable(PERIPH_RNG_MODULE);
|
||||
}
|
||||
#endif /* CONFIG_SOC_SERIES_ESP32C3 */
|
||||
|
||||
static int esp32_select_rtc_slow_clk(uint8_t slow_clk)
|
||||
{
|
||||
soc_rtc_slow_clk_src_t rtc_slow_clk_src = slow_clk & RTC_CNTL_ANA_CLK_RTC_SEL_V;
|
||||
|
||||
@ -216,16 +216,34 @@ static int spi_esp32_init(const struct device *dev)
|
||||
int err;
|
||||
const struct spi_esp32_config *cfg = dev->config;
|
||||
struct spi_esp32_data *data = dev->data;
|
||||
spi_hal_context_t *hal = &data->hal;
|
||||
|
||||
if (!cfg->clock_dev) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!device_is_ready(cfg->clock_dev)) {
|
||||
LOG_ERR("clock control device not ready");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* Enables SPI peripheral */
|
||||
err = clock_control_on(cfg->clock_dev, cfg->clock_subsys);
|
||||
if (err < 0) {
|
||||
LOG_ERR("Error enabling SPI clock");
|
||||
return err;
|
||||
}
|
||||
|
||||
spi_ll_master_init(hal->hw);
|
||||
|
||||
if (cfg->dma_enabled) {
|
||||
spi_esp32_init_dma(dev);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SPI_ESP32_INTERRUPT
|
||||
spi_ll_disable_int(cfg->spi);
|
||||
spi_ll_clear_int_stat(cfg->spi);
|
||||
|
||||
data->irq_line = esp_intr_alloc(cfg->irq_source,
|
||||
0,
|
||||
(ISR_HANDLER)spi_esp32_isr,
|
||||
@ -285,19 +303,6 @@ static int IRAM_ATTR spi_esp32_configure(const struct device *dev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!device_is_ready(cfg->clock_dev)) {
|
||||
LOG_ERR("clock control device not ready");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* enables SPI peripheral */
|
||||
if (clock_control_on(cfg->clock_dev, cfg->clock_subsys)) {
|
||||
LOG_ERR("Could not enable SPI clock");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
spi_ll_master_init(hal->hw);
|
||||
|
||||
ctx->config = spi_cfg;
|
||||
|
||||
if (spi_cfg->operation & SPI_HALF_DUPLEX) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user