driver: SD protocol driver for SPI peripheral

This commit is contained in:
Dmitry Yakovlev
2017-07-04 13:58:36 +08:00
committed by Ivan Grokhotkov
parent 5f8785eaec
commit e5bb45f381
12 changed files with 1466 additions and 54 deletions

View File

@@ -18,19 +18,21 @@ This example demonstrates how to use an SD card with ESP32. Example does the fol
To run this example, ESP32 development board needs to be connected to SD card as follows:
ESP32 pin | SD card pin | Notes
--------------|-------------|------------
GPIO14 (MTMS) | CLK | 10k pullup
GPIO15 (MTDO) | CMD | 10k pullup
GPIO2 | D0 | 10k pullup, pull low to go into download mode
GPIO4 | D1 | 10k pullup; not used in 1-line mode
GPIO12 (MTDI) | D2 | otherwise 10k pullup (see note below!); not used in 1-line mode
GPIO13 (MTCK) | D3 | 10k pullup needed at card side, even in 1-line mode
N/C | CD |
N/C | WP |
ESP32 pin | SD card pin | SPI pin | Notes
--------------|-------------|---------|------------
GPIO14 (MTMS) | CLK | SCK | 10k pullup in SD mode
GPIO15 (MTDO) | CMD | MOSI | 10k pullup, both in SD and SPI modes
GPIO2 | D0 | MISO | 10k pullup in SD mode, pull low to go into download mode (see note below!)
GPIO4 | D1 | N/C | not used in 1-line SD mode; 10k pullup in 4-line SD mode
GPIO12 (MTDI) | D2 | N/C | not used in 1-line SD mode; 10k pullup in 4-line SD mode (see note below!)
GPIO13 (MTCK) | D3 | CS | not used in 1-line SD mode, but card's D3 pin must have a 10k pullup
N/C | CD | | optional, not used in the example
N/C | WP | | optional, not used in the example
This example doesn't utilize card detect (CD) and write protect (WP) signals from SD card slot.
With the given pinout for SPI mode, same connections between the SD card and ESP32 can be used to test both SD and SPI modes, provided that the appropriate pullups are in place. In SPI mode, pins can be customized. See the initialization of ``sdspi_slot_config_t`` structure in the example code.
### Note about GPIO2
GPIO2 pin is used as a bootstrapping pin, and should be low to enter UART download mode. One way to do this is to connect GPIO0 and GPIO2 using a jumper, and then the auto-reset circuit on most development boards will pull GPIO2 low along with GPIO0, when entering download mode.
@@ -63,9 +65,12 @@ By default, example code uses the following initializer for SDMMC host periphera
sdmmc_host_t host = SDMMC_HOST_DEFAULT();
```
Among other things, this sets `host.flags` to `SDMMC_HOST_FLAG_4BIT`, which means that SD/MMC driver will switch to 4-line mode when initializing the card (initial communication always happens in 1-line mode). If some of D1, D2, D3 pins are not connected to the card, set `host.flags` to `SDMMC_HOST_FLAG_1BIT` — then the SD/MMC driver will not attempt to switch to 4-line mode.
Note that even if D3 line is not connected to the ESP32, it still has to be pulled up at card side, otherwise the card will go into SPI protocol mode.
Among other things, this sets `host.flags` to `SDMMC_HOST_FLAG_4BIT`, which means that SD/MMC driver will switch to 4-line mode when initializing the card (initial communication always happens in 1-line mode). If some of the card's D1, D2, D3 pins are not connected to the ESP32, set `host.flags` to `SDMMC_HOST_FLAG_1BIT` — then the SD/MMC driver will not attempt to switch to 4-line mode.
Note that even if card's D3 line is not connected to the ESP32, it still has to be pulled up, otherwise the card will go into SPI protocol mode.
## SPI mode
By default, the example uses SDMMC Host peripheral to access SD card. To use SPI peripheral instead, uncomment ``#define USE_SPI_MODE`` in the example code.
## Example output

View File

@@ -14,15 +14,37 @@
#include "esp_log.h"
#include "esp_vfs_fat.h"
#include "driver/sdmmc_host.h"
#include "driver/sdmmc_defs.h"
#include "driver/sdspi_host.h"
#include "sdmmc_cmd.h"
static const char* TAG = "example";
static const char *TAG = "example";
// This example can use SDMMC and SPI peripherals to communicate with SD card.
// By default, SDMMC peripheral is used.
// To enable SPI mode, uncomment the following line:
// #define USE_SPI_MODE
// When testing SD and SPI modes, keep in mind that once the card has been
// initialized in SPI mode, it can not be reinitialized in SD mode without
// toggling power to the card.
#ifdef USE_SPI_MODE
// Pin mapping when using SPI mode.
// With this mapping, SD card can be used both in SPI and 1-line SD mode.
// Note that a pull-up on CS line is required in SD mode.
#define PIN_NUM_MISO 2
#define PIN_NUM_MOSI 15
#define PIN_NUM_CLK 14
#define PIN_NUM_CS 13
#endif //USE_SPI_MODE
void app_main(void)
{
ESP_LOGI(TAG, "Initializing SD card");
#ifndef USE_SPI_MODE
ESP_LOGI(TAG, "Using SDMMC peripheral");
sdmmc_host_t host = SDMMC_HOST_DEFAULT();
// To use 1-line SD mode, uncomment the following line:
@@ -32,9 +54,22 @@ void app_main(void)
// Modify slot_config.gpio_cd and slot_config.gpio_wp if your board has these signals.
sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT();
#else
ESP_LOGI(TAG, "Using SPI peripheral");
sdmmc_host_t host = SDSPI_HOST_DEFAULT();
sdspi_slot_config_t slot_config = SDSPI_SLOT_CONFIG_DEFAULT();
slot_config.gpio_miso = PIN_NUM_MISO;
slot_config.gpio_mosi = PIN_NUM_MOSI;
slot_config.gpio_sck = PIN_NUM_CLK;
slot_config.gpio_cs = PIN_NUM_CS;
// This initializes the slot without card detect (CD) and write protect (WP) signals.
// Modify slot_config.gpio_cd and slot_config.gpio_wp if your board has these signals.
#endif //USE_SPI_MODE
// Options for mounting the filesystem.
// If format_if_mount_failed is set to true, SD card will be partitioned and formatted
// in case when mounting fails.
// If format_if_mount_failed is set to true, SD card will be partitioned and
// formatted in case when mounting fails.
esp_vfs_fat_sdmmc_mount_config_t mount_config = {
.format_if_mount_failed = false,
.max_files = 5
@@ -46,11 +81,14 @@ void app_main(void)
// production applications.
sdmmc_card_t* card;
esp_err_t ret = esp_vfs_fat_sdmmc_mount("/sdcard", &host, &slot_config, &mount_config, &card);
if (ret != ESP_OK) {
if (ret == ESP_FAIL) {
ESP_LOGE(TAG, "Failed to mount filesystem. If you want the card to be formatted, set format_if_mount_failed = true.");
ESP_LOGE(TAG, "Failed to mount filesystem. "
"If you want the card to be formatted, set format_if_mount_failed = true.");
} else {
ESP_LOGE(TAG, "Failed to initialize the card (%d). Make sure SD card lines have pull-up resistors in place.", ret);
ESP_LOGE(TAG, "Failed to initialize the card (%d). "
"Make sure SD card lines have pull-up resistors in place.", ret);
}
return;
}
@@ -101,7 +139,7 @@ void app_main(void)
}
ESP_LOGI(TAG, "Read from file: '%s'", line);
// All done, unmount partition and disable SDMMC host peripheral
// All done, unmount partition and disable SDMMC or SPI peripheral
esp_vfs_fat_sdmmc_unmount();
ESP_LOGI(TAG, "Card unmounted");
}