From 1f43f335678f6ccb03af2789a43b24a85fb2e372 Mon Sep 17 00:00:00 2001 From: michael Date: Tue, 24 Dec 2019 15:57:44 +0800 Subject: [PATCH] sdio: update the host example to support working with a slave without DAT1 The interrupt line (DAT1) is an extra pin comparing to SD memory, allowing the slave to actively inform the host some events. It's possible for two ESP32 chips to communicate with each other in 1-bit mode or SPI mode without the DAT1 line by polling the slave's interrupt registers. But this will increase the CPU load of the host, and do harm to the response speed to slave events. --- .../sdio/host/main/Kconfig.projbuild | 11 ++++++++ .../peripherals/sdio/host/main/app_main.c | 28 +++++++++++++------ 2 files changed, 31 insertions(+), 8 deletions(-) diff --git a/examples/peripherals/sdio/host/main/Kconfig.projbuild b/examples/peripherals/sdio/host/main/Kconfig.projbuild index ad79d6587..bef0d1f83 100644 --- a/examples/peripherals/sdio/host/main/Kconfig.projbuild +++ b/examples/peripherals/sdio/host/main/Kconfig.projbuild @@ -32,6 +32,17 @@ menu "Example Configuration" If the example does not work, please try disabling the HS mode. + config EXAMPLE_NO_INTR_LINE + bool "The host is not connected to the interrupt line (DAT1) of slave" + default n + help + If this is set, the host example will not check the interrupt line but poll slave + registers to see whether the slave has interrupts for the host. + + Working without the interrupt line may increase the CPU load of the host, and do harm + to the response speed to slave events, though can save 1 GPIO for other purposes in + non-4-bit mode. + choice EXAMPLE_SLAVE prompt "GPIO to control slave EN in Espressif master-slave board." default EXAMPLE_SLAVE_NONE diff --git a/examples/peripherals/sdio/host/main/app_main.c b/examples/peripherals/sdio/host/main/app_main.c index c5eb08313..b3c13a675 100644 --- a/examples/peripherals/sdio/host/main/app_main.c +++ b/examples/peripherals/sdio/host/main/app_main.c @@ -284,22 +284,34 @@ void slave_power_on(void) DMA_ATTR uint8_t rcv_buffer[READ_BUFFER_LEN]; +static esp_err_t get_intr(essl_handle_t handle, uint32_t* out_raw, uint32_t* out_st) +{ + esp_err_t ret = ESP_OK; +#ifndef CONFIG_EXAMPLE_NO_INTR_LINE + ret = essl_wait_int(handle, 0); + if (ret != ESP_OK) { + return ret; + } +#endif + + ret = essl_get_intr(handle, out_raw, out_st, TIMEOUT_MAX); + if (ret != ESP_OK) return ret; + ret = essl_clear_intr(handle, *out_raw, TIMEOUT_MAX); + if (ret != ESP_OK) return ret; + ESP_LOGD(TAG, "intr: %08X", *out_raw); + return ESP_OK; +} + //try to get an interrupt from the slave and handle it, return if none. esp_err_t process_event(essl_handle_t handle) { - esp_err_t ret = essl_wait_int(handle, 0); + uint32_t intr_raw, intr_st; + esp_err_t ret = get_intr(handle, &intr_raw, &intr_st); if (ret == ESP_ERR_TIMEOUT) { return ret; } ESP_ERROR_CHECK(ret); - uint32_t intr_raw, intr_st; - ret = essl_get_intr(handle, &intr_raw, &intr_st, TIMEOUT_MAX); - ESP_ERROR_CHECK(ret); - ret = essl_clear_intr(handle, intr_raw, TIMEOUT_MAX); - ESP_ERROR_CHECK(ret); - ESP_LOGD(TAG, "intr: %08X", intr_raw); - for (int i = 0; i < 8; i++) { if (intr_raw & BIT(i)) { ESP_LOGI(TAG, "host int: %d", i);