Skip to content

Commit

Permalink
cpu/esp32: add SDMMC support
Browse files Browse the repository at this point in the history
  • Loading branch information
gschorcht committed Jan 5, 2024
1 parent 866f2a0 commit 92657f5
Show file tree
Hide file tree
Showing 18 changed files with 866 additions and 38 deletions.
3 changes: 3 additions & 0 deletions cpu/esp32/Kconfig.esp32
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ config CPU_FAM_ESP32
select HAS_ESP_BLE
select HAS_ESP_BLE_ESP32
select HAS_PUF_SRAM
select HAS_PERIPH_SDMMC_AUTO_CLK
select HAS_PERIPH_SDMMC_AUTO_CMD12
select HAS_PERIPH_SDMMC_MMC

config CPU_FAM
default "esp32" if CPU_FAM_ESP32
Expand Down
4 changes: 4 additions & 0 deletions cpu/esp32/Kconfig.esp32s3
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ config CPU_FAM_ESP32S3
select HAS_BLE_PHY_2MBIT
select HAS_ESP_BLE
select HAS_ESP_BLE_ESP32C3
select HAS_PERIPH_SDMMC_AUTO_CLK
select HAS_PERIPH_SDMMC_AUTO_CMD12
select HAS_PERIPH_SDMMC_HS
select HAS_PERIPH_SDMMC_MMC
select MODULE_USBDEV_SYNOPSYS_DWC2 if MODULE_PERIPH_USBDEV
select MODULE_USB_BOARD_RESET if MODULE_USBUS_CDC_ACM || MODULE_TINYUSB_CLASS_CDC

Expand Down
1 change: 1 addition & 0 deletions cpu/esp32/Kconfig.esp32x
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ config CPU_COMMON_ESP32X

select PACKAGE_ESP32_SDK if TEST_KCONFIG

select MODULE_PERIPH_GPIO_IRQ if MODULE_PERIPH_SDMMC
select MODULE_PERIPH_RTT if HAS_PERIPH_RTT && MODULE_PM_LAYERED
select MODULE_PS if MODULE_SHELL
select MODULE_PTHREAD if MODULE_CPP
Expand Down
5 changes: 5 additions & 0 deletions cpu/esp32/Makefile.dep
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,11 @@ ifneq (,$(filter periph_i2c,$(USEMODULE)))
endif
endif

ifneq (,$(filter periph_sdmmc,$(USEMODULE)))
USEMODULE += esp_idf_sdmmc
USEMODULE += periph_gpio_irq
endif

ifneq (,$(filter esp_spi_ram,$(USEMODULE)))
FEATURES_REQUIRED += esp_spi_ram
FEATURES_OPTIONAL += esp_spi_oct
Expand Down
9 changes: 9 additions & 0 deletions cpu/esp32/Makefile.features
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,15 @@ else ifneq (,$(filter esp32c3 esp32s3,$(CPU_FAM)))
FEATURES_PROVIDED += esp_ble_esp32c3
endif

ifneq (,$(filter esp32 esp32s3,$(CPU_FAM)))
FEATURES_PROVIDED += periph_sdmmc_auto_clk
FEATURES_PROVIDED += periph_sdmmc_auto_cmd12
FEATURES_PROVIDED += periph_sdmmc_mmc
ifeq (esp32s3,$(CPU_FAM))
FEATURES_PROVIDED += periph_sdmmc_hs
endif
endif

ifneq (,$(filter esp32-wrover% esp32s2%r2 esp32s3%r2 esp32s3%r8 esp32s3%r8v,$(CPU_MODEL)))
FEATURES_PROVIDED += esp_spi_ram
ifneq (,$(filter esp32s3%r8 esp32s3%r8v,$(CPU_MODEL)))
Expand Down
129 changes: 94 additions & 35 deletions cpu/esp32/doc.txt
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,14 @@ This document describes the RIOT implementation for supported variants
3. [DAC Channels](#esp32_dac_channels)
4. [I2C Interfaces](#esp32_i2c_interfaces)
5. [PWM Channels](#esp32_pwm_channels)
6. [SPI Interfaces](#esp32_spi_interfaces)
7. [Timers](#esp32_timers)
8. [RTT Implementation](#esp32_rtt_counter)
9. [UART Interfaces](#esp32_uart_interfaces)
10. [CAN Interfaces](#esp32_can_interfaces)
11. [Power Management](#esp32_power_management)
12. [Other Peripherals](#esp32_other_peripherals)
6. [SDMMC Interfaces](#esp32_sdmmc_interfaces)
8. [SPI Interfaces](#esp32_spi_interfaces)
9. [Timers](#esp32_timers)
10. [RTT Implementation](#esp32_rtt_counter)
12. [UART Interfaces](#esp32_uart_interfaces)
13. [CAN Interfaces](#esp32_can_interfaces)
14. [Power Management](#esp32_power_management)
15. [Other Peripherals](#esp32_other_peripherals)
7. [Special On-board Peripherals](#esp32_special_on_board_peripherals)
1. [SPI RAM Modules](#esp32_spi_ram)
2. [SPIFFS Device](#esp32_spiffs_device)
Expand Down Expand Up @@ -212,13 +213,14 @@ The key features of ESP32 are:
| Flash | 512 KiB ... 16 MiB | yes |
| Frequency | 240 MHz, 160 MHz, 80 MHz | yes |
| Power Consumption | 68 mA @ 240 MHz <br> 44 mA @ 160 MHz (34 mA @ 160 MHz single core) <br> 31 mA @ 80 MHz (25 mA @ 80 MHz single core) <br> 800 uA in light sleep mode <br> 10 uA in deep sleep mode | yes <br> yes <br> yes <br> yes <br> yes |
| Timers | 4 x 64 bit | yes |
| ADCs | 2 x SAR-ADC with up to 18 x 12 bit channels total | yes |
| DACs | 2 x DAC with 8 bit | yes |
| GPIOs | 34 (6 are only inputs, 18 are RTC GPIOs) | yes |
| I2Cs | 2 | yes |
| SPIs | 4 | yes (2) |
| UARTs | 3 | yes |
| Timer | 4 x 64 bit | yes |
| ADC | 2 x SAR-ADC with up to 18 x 12 bit channels total | yes |
| DAC | 2 x DAC with 8 bit | yes |
| GPIO | 34 (6 are only inputs, 18 are RTC GPIOs) | yes |
| I2C | 2 | yes |
| SDMMC | 2 | yes |
| SPI | 4 | yes (2) |
| UART | 3 | yes |
| WiFi | IEEE 802.11 b/g/n built in | yes |
| Bluetooth | v4.2 BR/EDR and BLE | yes |
| Ethernet | MAC interface with dedicated DMA and IEEE 1588 support | yes |
Expand Down Expand Up @@ -248,13 +250,13 @@ The key features of ESP32-C3 are:
| Flash | 8 MiB | yes |
| Frequency | 160 MHz, 80 MHz | yes |
| Power Consumption | 20 mA @ 240 MHz <br> 15 mA @ 80 MHz <br> 130 uA in light sleep mode <br> 5 uA in deep sleep mode | yes <br> yes <br> yes <br> yes |
| Timers | 2 x 54 bit | yes |
| ADCs | 2 x SAR-ADC with up to 6 x 12 bit channels total | yes |
| DACs | - | - |
| GPIOs | 22 | yes |
| I2Cs | 1 | yes |
| SPIs | 3 | yes (1) |
| UARTs | 2 | yes |
| Timer | 2 x 54 bit | yes |
| ADC | 2 x SAR-ADC with up to 6 x 12 bit channels total | yes |
| DAC | - | - |
| GPIO | 22 | yes |
| I2C | 1 | yes |
| SPI | 3 | yes (1) |
| UART | 2 | yes |
| WiFi | IEEE 802.11 b/g/n built in | yes |
| Bluetooth | Bluetooth 5 (LE) | yes |
| Ethernet | - | - |
Expand Down Expand Up @@ -284,13 +286,13 @@ The key features of ESP32-S2 are:
| Flash | 512 KiB ... 32 MiB Dual/Quad/Octal SPI (external or internal) | yes |
| Frequency | 240 MHz, 160 MHz, 80 MHz | yes |
| Power Consumption | 66 mA @ 240 MHz <br> 50 mA @ 160 MHz (40 mA @ 160 MHz single core) <br> 33 mA @ 80 MHz (28 mA @ 80 MHz single core) <br> 19 mA @ 40 MHz (16 mA @ 40 MHz single core) <br>240 uA in light sleep mode <br> 8 uA in deep sleep mode | yes <br> yes <br> yes <br> yes <br> yes <br> yes |
| Timers | 4 x 54 bit | yes |
| ADCs | 2 x SAR-ADC with up to 20 x 13 bit channels total | yes |
| DACs | 2 x DAC with 8 bit | - |
| GPIOs | 43 (22 are RTC GPIOs) | yes |
| I2Cs | 2 | yes |
| SPIs | 4 | yes (2) |
| UARTs | 2 | yes |
| Timer | 4 x 54 bit | yes |
| ADC | 2 x SAR-ADC with up to 20 x 13 bit channels total | yes |
| DAC | 2 x DAC with 8 bit | - |
| GPIO | 43 (22 are RTC GPIOs) | yes |
| I2C | 2 | yes |
| SPI | 4 | yes (2) |
| UART | 2 | yes |
| WiFi | IEEE 802.11 b/g/n built in | yes |
| Bluetooth | - | - |
| Ethernet | - | - |
Expand Down Expand Up @@ -320,13 +322,14 @@ The key features of ESP32-S3 are:
| Flash | 512 KiB ... 32 MiB Dual/Quad/Octal SPI (external or internal) | yes |
| Frequency | 240 MHz, 160 MHz, 80 MHz | yes |
| Power Consumption | 66 mA @ 240 MHz <br> 50 mA @ 160 MHz (40 mA @ 160 MHz single core) <br> 33 mA @ 80 MHz (28 mA @ 80 MHz single core) <br> 19 mA @ 40 MHz (16 mA @ 40 MHz single core) <br>240 uA in light sleep mode <br> 8 uA in deep sleep mode | yes <br> yes <br> yes <br> yes <br> yes <br> yes |
| Timers | 4 x 54 bit | yes |
| ADCs | 2 x SAR-ADC with up to 20 x 12 bit channels total | yes |
| DACs | - | - |
| GPIOs | 45 (22 are RTC GPIOs) | yes |
| I2Cs | 2 | yes |
| SPIs | 4 | yes (2) |
| UARTs | 3 | yes |
| Timer | 4 x 54 bit | yes |
| ADC | 2 x SAR-ADC with up to 20 x 12 bit channels total | yes |
| DAC | - | - |
| GPIO | 45 (22 are RTC GPIOs) | yes |
| I2C | 2 | yes |
| SDMMC | 2 | yes |
| SPI | 4 | yes (2) |
| UART | 3 | yes |
| WiFi | IEEE 802.11 b/g/n built in | yes |
| Bluetooth | Bluetooth 5 (LE) | yes |
| Ethernet | - | - |
Expand Down Expand Up @@ -1012,6 +1015,62 @@ definition of `PWM0_GPIOS`, `PWM1_GPIOS`, `PWM2_GPIOS` and `PWM3_GPIOS`.

[Back to table of contents](#esp32_toc)

## SDMMC Interfaces {#esp32_sdmmc_interfaces}

ESP32 and ESP32-S3 variants integrate a SD/MMC host controller which supports
two slots for

- SD Memory Cards,
- SDIO Cards and
- MMC/eMMCs.

The SD/MMC host controller on the ESP32 variant

- supports 1-bit, 4-bit and 8-bit data bus width for slot 0 (@ref SDMMC_SLOT_0),
- supports 1-bit and 4-bit data bus width for slot 1 (@ref SDMMC_SLOT_1),
- uses direct I/O for SD/MMC signals so that the GPIOs used for the slots are
therefore fixed.

The SD/MMC host controller on the ESP32-S3 variant
- supports 1-, 4- and 8-bit data bus width for both slots
- uses the GPIO matrix to connect the SD/MMC signals to the GPIOs so that
all pins are configurable.

@note Since the GPIOs are fixed on the ESP32 variant and the same GPIOs are
used for slot 0 and the flash, slot 0 cannot be used on ESP32 variant.

The board-specific configuration is realized by defining the array
@ref sdmmc_config
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.c}
static const sdmmc_conf_t sdmmc_config[] = {
{
.slot = SDMMC_SLOT_1,
.cd = GPIO_UNDEF,
.wp = GPIO_UNDEF,
...
},
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
and the macro `SDMMC_NUMOF`
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.c}
#define SDMMC_NUMOF 1
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

where the value of @ref SDMMC_NUMOF must correspond to the number of elements
in @ref sdmmc_config.

While for the ESP32 variant it is sufficient to define the data bus width, used
GPIOs have to be defined in the configuration for the ESP32-S3 variant instead.
For details of ESP32x variant specific configuration, see:

- \ref esp32_sdmmc_interfaces_esp32 "ESP32"
- \ref esp32_sdmmc_interfaces_esp32s3 "ESP32-S3"

If the board supports a Card Detect pin or a Write Protect pin, the
corresponding GPIOs have to be defined in @ref sdmmc_conf_t::cd and
@ref sdmmc_conf_t::wp. Otherwise they have to be set to undefined
(@ref GPIO_UNDEF).

## SPI Interfaces {#esp32_spi_interfaces}

ESP32x SoCs have up to four SPI controllers dependent on the specific ESP32x
Expand Down
46 changes: 46 additions & 0 deletions cpu/esp32/doc_esp32.txt
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,52 @@ I2C_DEV(0) | SDA | GPIO21 | `#I2C0_SDA` | -
The ESP32 LEDC module has 2 channel groups with 8 channels each. Each of
these channels can be clocked by one of the 4 timers.

## SDMMC Interfaces {#esp32_sdmmc_interfaces_esp32}

The ESP32 variant uses the direct I/O (i.e. `SOC_SDMMC_USE_IOMUX` is defined in
the SoC capabilities file). The GPIOs used for SDMMC signals are therefore fixed
for each slot. Since the GPIOs used for slot 0 are the same as those used
for the Flash, slot 0 cannot be used. Therefore, only slot 1 can be used.

The GPIOs used by ESP32 for slot 1 are:

<center>
| Signal | GPIO Slot 1 |
|:------ |:------------|
| CLK | GPIO14 |
| CMD | GPIO15 |
| DAT0 | GPIO2 |
| DAT1 | GPIO4 |
| DAT2 | GPIO12 |
| DAT3 | GPIO13 |
</center>

The board-specific configuration is realized by defining the @ref sdmmc_config
array, for example:

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.c}
static const sdmmc_conf_t sdmmc_config[] = {
{
.slot = SDMMC_SLOT_1,
.cd = GPIO21,
.wp = GPIO_UNDEF,
.bus_width = 1,
},
};

#define SDMMC_NUMOF 1
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Used data bus width has to be defined in sdmmc_conf_t::bus_width in addition
to the slot, where 1 and 4 are valid values.

@note The slot must be @ref SDMMC_SLOT_1 for ESP32.

If the board supports a Card Detect pin or a Write Protect
pin, the corresponding GPIOs have to be defined in @ref sdmmc_conf_t::cd and
@ref sdmmc_conf_t::wp. Otherwise they have to be set to undefined
(@ref GPIO_UNDEF).

## SPI Interfaces {#esp32_spi_interfaces_esp32}

ESP32 has four SPI controllers where SPI0 and SPI1 share the same bus and
Expand Down
48 changes: 48 additions & 0 deletions cpu/esp32/doc_esp32s3.txt
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,54 @@ I2C_DEV(0) | SDA | GPIO8 | `#I2C0_SDA` | -
The ESP32-S3 LEDC module has 1 channel group with 8 channels. Each of
these channels can be clocked by one of the 4 timers.

## SDMMC Interfaces {#esp32_sdmmc_interfaces_esp32s3}

The ESP32-S3 variant uses the GPIO matrix (i.e. `SOC_SDMMC_USE_GPIO_MATRIX`
is defined in the SoC Capabilities file) to route the SDMMC signals to
arbitrary pins. The GPIOs used for the SDMMC signals are therefore
configurable and have to be defined in the board-specific configuration in
array @ref sdmmc_config in addition to the used slot.

The width of the data bus used is determined by the GPIOs defined for the
DAT lines. To use a 1-bit data bus, only DAT0 (@ref sdmmc_conf_t::dat0)
must be defined. All other GPIOs for the DAT lines must be set undefined
(@ref GPIO_UNDEF). For a 4-bit data bus, the GPIOs for pins DAT1 to DAT3
(@ref sdmmc_conf_t::dat1 ... @ref sdmmc_conf_t::dat3) must also be defined.
An 8-bit data bus width requires the definition of DAT4 to DAT7
(@ref sdmmc_conf_t::dat4 ... @ref sdmmc_conf_t::dat7) and the enabling
of the `periph_sdmmc_8bit` module.

The following example shows a configuration with 4-bit or 8-bit data
bus width dependent on whether the `periph_sdmmc_8bit` module is enabled.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.c}
static const sdmmc_conf_t sdmmc_config[] = {
{
.slot = SDMMC_SLOT_0,
.cd = GPIO16,
.wp = GPIO_UNDEF,
.clk = GPIO14,
.cmd = GPIO15,
.dat0 = GPIO2,
.dat1 = GPIO4,
.dat2 = GPIO12,
.dat3 = GPIO13,
#if IS_USED(MODULE_PERIPH_SMMC_8BIT)
.dat4 = GPIO33,
.dat5 = GPIO33,
.dat6 = GPIO33,
.dat7 = GPIO33,
#endif
},
};

#define SDMMC_NUMOF 1
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

If the board supports a Card Detect pin or a Write Protect pin, the
corresponding GPIOs have to be defined in @ref sdmmc_conf_t::cd and
@ref sdmmc_conf_t::wp. Otherwise they have to be set to undefined
(@ref GPIO_UNDEF).

## SPI Interfaces {#esp32_spi_interfaces_esp32s3}

ESP32-S3 has four SPI controllers where SPI0 and SPI1 share the same bus
Expand Down
1 change: 1 addition & 0 deletions cpu/esp32/esp-idf/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ rsource "heap/Kconfig"
rsource "lcd/Kconfig"
rsource "nvs_flash/Kconfig"
rsource "rmt/Kconfig"
rsource "sdmmc/Kconfig"
rsource "spi_flash/Kconfig"
rsource "spi_ram/Kconfig"
rsource "usb/Kconfig"
Expand Down
4 changes: 4 additions & 0 deletions cpu/esp32/esp-idf/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ ifneq (,$(filter esp_idf_rmt,$(USEMODULE)))
DIRS += rmt
endif

ifneq (,$(filter esp_idf_sdmmc,$(USEMODULE)))
DIRS += sdmmc
endif

ifneq (,$(filter esp_idf_spi_flash,$(USEMODULE)))
DIRS += spi_flash
endif
Expand Down
17 changes: 17 additions & 0 deletions cpu/esp32/esp-idf/sdmmc/Kconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Copyright (c) 2021 HAW Hamburg
# 2022 Gunar Schorcht
#
# This file is subject to the terms and conditions of the GNU Lesser
# General Public License v2.1. See the file LICENSE in the top level
# directory for more details.
#

config MODULE_ESP_IDF_SDMMC
bool
depends on TEST_KCONFIG
depends on MODULE_ESP_IDF
default y if MODULE_PERIPH_SDMMC
select PACKAGE_TLSF
help
ESP-IDF heap library. This library is required if external SPI RAM
or the WiFi interface is used.
18 changes: 18 additions & 0 deletions cpu/esp32/esp-idf/sdmmc/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
MODULE = esp_idf_sdmmc

# source files to be compiled for this module
ESP32_SDK_SRC = \
components/driver/sdmmc_host.c \
components/driver/sdmmc_transaction.c \
components/soc/$(CPU_FAM)/sdmmc_periph.c \
#

# additional include pathes required by this module
# INCLUDES += -I$(ESP32_SDK_DIR)/components/driver/include

include $(RIOTBASE)/Makefile.base

ESP32_SDK_BIN = $(BINDIR)/$(MODULE)

include ../esp_idf.mk
include ../esp_idf_cflags.mk
1 change: 1 addition & 0 deletions cpu/esp32/include/irq_arch.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ extern "C" {
#define CPU_INUM_FRC2 20 /**< Level interrupt with medium priority 2 */
#define CPU_INUM_SYSTIMER 20 /**< Level interrupt with medium priority 2 */
#define CPU_INUM_BLE 21 /**< Level interrupt with medium priority 2 */
#define CPU_INUM_SDMMC 23 /**< Level interrupt with medium priority 2 */
#define CPU_INUM_CACHEERR 25 /**< Level interrupt with high priority 4 */
/** @} */

Expand Down
Loading

0 comments on commit 92657f5

Please sign in to comment.