diff --git a/examples/peripherals/sdio/host/components/esp_slave/esp_slave.c b/examples/peripherals/sdio/host/components/esp_slave/esp_slave.c index b7c8819df3..cbe3fe2660 100644 --- a/examples/peripherals/sdio/host/components/esp_slave/esp_slave.c +++ b/examples/peripherals/sdio/host/components/esp_slave/esp_slave.c @@ -68,6 +68,18 @@ esp_err_t esp_slave_init_io(esp_slave_context_t *context) if (err != ESP_OK) return err; ESP_LOGD(TAG, "IE: 0x%02x", ie); + // get bus width register + uint8_t bus_width; + err = sdmmc_io_read_byte(card, 0, SD_IO_CCCR_BUS_WIDTH, &bus_width); + if (err != ESP_OK) return err; + ESP_LOGD(TAG,"BUS_WIDTH: 0x%02x", bus_width); + + // enable continuous SPI interrupts + bus_width |= CCCR_BUS_WIDTH_ECSI; + err = sdmmc_io_write_byte(card, 0, SD_IO_CCCR_BUS_WIDTH, bus_width, &bus_width); + if (err != ESP_OK) return err; + ESP_LOGD(TAG, "BUS_WIDTH: 0x%02x", bus_width); + uint16_t bs = 512; const uint8_t* bs_u8 = (const uint8_t*) &bs; uint16_t bs_read = 0; diff --git a/examples/peripherals/sdio/host/components/esp_slave/include/esp_slave.h b/examples/peripherals/sdio/host/components/esp_slave/include/esp_slave.h index b24e61b5fa..56deab0f7d 100644 --- a/examples/peripherals/sdio/host/components/esp_slave/include/esp_slave.h +++ b/examples/peripherals/sdio/host/components/esp_slave/include/esp_slave.h @@ -13,11 +13,10 @@ // limitations under the License. #include "sdmmc_cmd.h" -#include "driver/sdmmc_host.h" #include "driver/sdmmc_defs.h" #include "soc/host_reg.h" -/* +/* * NOTE: This component is for example purpose only. Assertion fails if any of * the preconditions (connections, grounding, slave data preparation, etc.) is * not met. diff --git a/examples/peripherals/sdio/host/main/Kconfig.projbuild b/examples/peripherals/sdio/host/main/Kconfig.projbuild index 6e77578a48..586117ff10 100644 --- a/examples/peripherals/sdio/host/main/Kconfig.projbuild +++ b/examples/peripherals/sdio/host/main/Kconfig.projbuild @@ -1,8 +1,16 @@ menu "Example Configuration" + config SDIO_EXAMPLE_OVER_SPI + bool "Host use SPI bus to communicate with slave" + default n + help + If this is set, the host tries using SPI bus to communicate with slave. + Otherwise, the standarad SD bus is used. + config SDIO_EXAMPLE_4BIT bool "Host tries using 4-bit mode to communicate with slave" default n + depends on !SDIO_EXAMPLE_OVER_SPI help If this is set, the host tries using 4-bit mode to communicate with slave. If failed, the communication falls back to 1-bit mode. @@ -40,4 +48,11 @@ menu "Example Configuration" bool "Using slave B3" endchoice + config EXAMPLE_SLAVE_PWR_NEGTIVE_ACTIVE + bool "Slave power control pin is negtive active, otherwise postive active" + depends on !EXAMPLE_SLAVE_NONE + default y + help + Slave power control pin is negtive active, otherwise postive active + endmenu diff --git a/examples/peripherals/sdio/host/main/app_main.c b/examples/peripherals/sdio/host/main/app_main.c index 35d7c1bac6..cc4b1dcd9a 100644 --- a/examples/peripherals/sdio/host/main/app_main.c +++ b/examples/peripherals/sdio/host/main/app_main.c @@ -21,6 +21,9 @@ #include "esp_attr.h" #include "esp_slave.h" #include "sdkconfig.h" +#include "driver/sdmmc_host.h" +#include "driver/sdspi_host.h" +#include "soc/sdio_slave_pins.h" /* * For SDIO master-slave board, we have 3 pins controlling power of 3 different @@ -29,6 +32,7 @@ #define GPIO_B1 5 #define GPIO_B2 18 #define GPIO_B3 19 + #if CONFIG_EXAMPLE_SLAVE_B1 #define SLAVE_PWR_GPIO GPIO_B1 #elif CONFIG_EXAMPLE_SLAVE_B2 @@ -79,7 +83,7 @@ */ #define WRITE_BUFFER_LEN 4096 -#define READ_BUFFER_LEN 1024 +#define READ_BUFFER_LEN 4096 static const char TAG[] = "example_host"; @@ -117,14 +121,31 @@ esp_err_t slave_reset(esp_slave_context_t *context) return ret; } +#ifdef CONFIG_SDIO_EXAMPLE_OVER_SPI +static void gpio_d2_set_high() +{ + gpio_config_t d2_config = { + .pin_bit_mask = BIT(SDIO_SLAVE_SLOT1_IOMUX_PIN_NUM_D2), + .mode = GPIO_MODE_OUTPUT, + .pull_up_en = true, + }; + gpio_config(&d2_config); + gpio_set_level(SDIO_SLAVE_SLOT1_IOMUX_PIN_NUM_D2, 1); +} +#endif + //host use this to initialize the slave card as well as SDIO registers esp_err_t slave_init(esp_slave_context_t *context) { + esp_err_t err; /* Probe */ +#ifndef CONFIG_SDIO_EXAMPLE_OVER_SPI sdmmc_host_t config = SDMMC_HOST_DEFAULT(); #ifdef CONFIG_SDIO_EXAMPLE_4BIT + ESP_LOGI(TAG, "Probe using SD 4-bit...\n"); config.flags = SDMMC_HOST_FLAG_4BIT; #else + ESP_LOGI(TAG, "Probe using SD 1-bit...\n"); config.flags = SDMMC_HOST_FLAG_1BIT; #endif @@ -142,8 +163,33 @@ esp_err_t slave_init(esp_slave_context_t *context) real design. */ //slot_config.flags = SDMMC_SLOT_FLAG_INTERNAL_PULLUP; - sdmmc_host_init(); - sdmmc_host_init_slot(SDMMC_HOST_SLOT_1, &slot_config); + err = sdmmc_host_init(); + assert(err==ESP_OK); + + err = sdmmc_host_init_slot(SDMMC_HOST_SLOT_1, &slot_config); + assert(err==ESP_OK); +#else //over SPI + sdmmc_host_t config = SDSPI_HOST_DEFAULT(); + + sdspi_slot_config_t slot_config = SDSPI_SLOT_CONFIG_DEFAULT(); + slot_config.gpio_miso = SDIO_SLAVE_SLOT1_IOMUX_PIN_NUM_D0; + slot_config.gpio_mosi = SDIO_SLAVE_SLOT1_IOMUX_PIN_NUM_CMD; + slot_config.gpio_sck = SDIO_SLAVE_SLOT1_IOMUX_PIN_NUM_CLK; + slot_config.gpio_cs = SDIO_SLAVE_SLOT1_IOMUX_PIN_NUM_D3; + slot_config.gpio_int = SDIO_SLAVE_SLOT1_IOMUX_PIN_NUM_D1; + + err = gpio_install_isr_service(0); + assert(err == ESP_OK); + err = sdspi_host_init(); + assert(err==ESP_OK); + + err = sdspi_host_init_slot(HSPI_HOST, &slot_config); + assert(err==ESP_OK); + ESP_LOGI(TAG, "Probe using SPI...\n"); + + //we have to pull up all the slave pins even when the pin is not used + gpio_d2_set_high(); +#endif //over SPI sdmmc_card_t *card = (sdmmc_card_t *)malloc(sizeof(sdmmc_card_t)); if (card == NULL) { return ESP_ERR_NO_MEM; @@ -179,16 +225,28 @@ esp_err_t slave_init(esp_slave_context_t *context) void slave_power_on() { #ifdef SLAVE_PWR_GPIO + int level_active; +#ifdef CONFIG_EXAMPLE_SLAVE_PWR_NEGTIVE_ACTIVE + level_active = 0; +#else + level_active = 1; +#endif gpio_config_t cfg = { - .pin_bit_mask = BIT(SLAVE_PWR_GPIO), + .pin_bit_mask = BIT(GPIO_B1) | BIT(GPIO_B2) | BIT(GPIO_B3), .mode = GPIO_MODE_DEF_OUTPUT, .pull_up_en = false, .pull_down_en = false, .intr_type = GPIO_INTR_DISABLE, }; gpio_config(&cfg); - gpio_set_level(SLAVE_PWR_GPIO, 0); //low active + gpio_set_level(GPIO_B1, !level_active); + gpio_set_level(GPIO_B2, !level_active); + gpio_set_level(GPIO_B3, !level_active); + vTaskDelay(100); + gpio_set_level(SLAVE_PWR_GPIO, level_active); + vTaskDelay(100); + #endif } @@ -274,15 +332,16 @@ void job_write_reg(esp_slave_context_t *context, int value) ESP_LOG_BUFFER_HEXDUMP(TAG, reg_read, 64, ESP_LOG_INFO); } -//use 1+1+1+1+4+4=12 packets, 513 and 517 not sent -int packet_len[] = {3, 6, 12, 128, 511, 512, 513, 517}; +//the slave only load 16 buffers a time +//so first 5 packets (use 1+1+8+4+1=15 buffers) are sent, the others (513, 517) failed (timeout) +int packet_len[] = {6, 12, 1024, 512, 3, 513, 517}; //the sending buffer should be word aligned DMA_ATTR uint8_t send_buffer[READ_BUFFER_LEN]; //send packets to the slave (they will return and be handled by the interrupt handler) void job_fifo(esp_slave_context_t *context) { - for (int i = 0; i < 1024; i++) { + for (int i = 0; i < READ_BUFFER_LEN; i++) { send_buffer[i] = 0x46 + i * 5; } diff --git a/examples/peripherals/sdio/slave/main/app_main.c b/examples/peripherals/sdio/slave/main/app_main.c index 0c1d59fed2..410209bb24 100644 --- a/examples/peripherals/sdio/slave/main/app_main.c +++ b/examples/peripherals/sdio/slave/main/app_main.c @@ -60,7 +60,7 @@ #define SDIO_SLAVE_QUEUE_SIZE 11 #define BUFFER_SIZE 128 -#define BUFFER_NUM 12 +#define BUFFER_NUM 16 #define EV_STR(s) "================ "s" ================"