soc: add esp32s3 sdmmc support

* sync the latest struct header file from ESP32
* add soc_caps.h macros to distinguish between IO MUX and GPIO Matrix
  support in SDMMC on different chips.
* store GPIO matrix signal numbers in sdmmc_slot_info_t
This commit is contained in:
Ivan Grokhotkov 2021-01-04 20:34:31 +01:00
parent bd3a6dda87
commit 17c65dad27
8 changed files with 150 additions and 90 deletions

View File

@ -28,6 +28,7 @@ PROVIDE ( GPSPI2 = 0x60024000 );
PROVIDE ( GPSPI3 = 0x60025000 );
PROVIDE ( SYSCON = 0x60026000 );
PROVIDE ( I2C1 = 0x60027000 );
PROVIDE ( SDMMC = 0x60028000 );
PROVIDE ( TWAI = 0x6002B000 );
PROVIDE ( GPSPI4 = 0x60037000 );
PROVIDE ( GDMA = 0x6003F000 );

View File

@ -282,3 +282,11 @@
# define CAN_BRP_DIV_SUPPORTED SOC_TWAI_BRP_DIV_SUPPORTED
# define CAN_BRP_DIV_THRESH SOC_TWAI_BRP_DIV_THRESH
#endif
/*-------------------------- SDMMC CAPS -----------------------------------------*/
/* On ESP32, clock/cmd/data pins use IO MUX.
* Card detect, write protect, interrupt use GPIO Matrix on all chips.
*/
#define SOC_SDMMC_USE_IOMUX 1
#define SOC_SDMMC_NUM_SLOTS 2

View File

@ -14,37 +14,44 @@
#include "soc/sdmmc_periph.h"
const sdmmc_slot_info_t sdmmc_slot_info[2] = {
const sdmmc_slot_info_t sdmmc_slot_info[SOC_SDMMC_NUM_SLOTS] = {
{
.clk_gpio = SDMMC_SLOT0_IOMUX_PIN_NUM_CLK,
.cmd_gpio = SDMMC_SLOT0_IOMUX_PIN_NUM_CMD,
.d0_gpio = SDMMC_SLOT0_IOMUX_PIN_NUM_D0,
.d1_gpio = SDMMC_SLOT0_IOMUX_PIN_NUM_D1,
.d2_gpio = SDMMC_SLOT0_IOMUX_PIN_NUM_D2,
.d3_gpio = SDMMC_SLOT0_IOMUX_PIN_NUM_D3,
.d4_gpio = SDMMC_SLOT0_IOMUX_PIN_NUM_D4,
.d5_gpio = SDMMC_SLOT0_IOMUX_PIN_NUM_D5,
.d6_gpio = SDMMC_SLOT0_IOMUX_PIN_NUM_D6,
.d7_gpio = SDMMC_SLOT0_IOMUX_PIN_NUM_D7,
.width = 8,
.card_detect = HOST_CARD_DETECT_N_1_IDX,
.write_protect = HOST_CARD_WRITE_PRT_1_IDX,
.card_int = HOST_CARD_INT_N_1_IDX,
.width = 8
},
{
.clk_gpio = SDMMC_SLOT1_IOMUX_PIN_NUM_CLK,
.cmd_gpio = SDMMC_SLOT1_IOMUX_PIN_NUM_CMD,
.d0_gpio = SDMMC_SLOT1_IOMUX_PIN_NUM_D0,
.d1_gpio = SDMMC_SLOT1_IOMUX_PIN_NUM_D1,
.d2_gpio = SDMMC_SLOT1_IOMUX_PIN_NUM_D2,
.d3_gpio = SDMMC_SLOT1_IOMUX_PIN_NUM_D3,
.d4_gpio = -1, //slot1 has no D4-7
.d5_gpio = -1,
.d6_gpio = -1,
.d7_gpio = -1,
.width = 4,
.card_detect = HOST_CARD_DETECT_N_2_IDX,
.write_protect = HOST_CARD_WRITE_PRT_2_IDX,
.card_int = HOST_CARD_INT_N_2_IDX,
.width = 4
}
};
const sdmmc_slot_io_info_t sdmmc_slot_gpio_num[SOC_SDMMC_NUM_SLOTS] = {
{
.clk = SDMMC_SLOT0_IOMUX_PIN_NUM_CLK,
.cmd = SDMMC_SLOT0_IOMUX_PIN_NUM_CMD,
.d0 = SDMMC_SLOT0_IOMUX_PIN_NUM_D0,
.d1 = SDMMC_SLOT0_IOMUX_PIN_NUM_D1,
.d2 = SDMMC_SLOT0_IOMUX_PIN_NUM_D2,
.d3 = SDMMC_SLOT0_IOMUX_PIN_NUM_D3,
.d4 = SDMMC_SLOT0_IOMUX_PIN_NUM_D4,
.d5 = SDMMC_SLOT0_IOMUX_PIN_NUM_D5,
.d6 = SDMMC_SLOT0_IOMUX_PIN_NUM_D6,
.d7 = SDMMC_SLOT0_IOMUX_PIN_NUM_D7,
},
{
.clk = SDMMC_SLOT1_IOMUX_PIN_NUM_CLK,
.cmd = SDMMC_SLOT1_IOMUX_PIN_NUM_CMD,
.d0 = SDMMC_SLOT1_IOMUX_PIN_NUM_D0,
.d1 = SDMMC_SLOT1_IOMUX_PIN_NUM_D1,
.d2 = SDMMC_SLOT1_IOMUX_PIN_NUM_D2,
.d3 = SDMMC_SLOT1_IOMUX_PIN_NUM_D3,
.d4 = -1, //slot1 has no D4-7
.d5 = -1,
.d6 = -1,
.d7 = -1,
}
};

View File

@ -14,22 +14,6 @@
#pragma once
#define SDMMC_SLOT0_IOMUX_PIN_NUM_CLK 6
#define SDMMC_SLOT0_IOMUX_PIN_NUM_CMD 11
#define SDMMC_SLOT0_IOMUX_PIN_NUM_D0 7
#define SDMMC_SLOT0_IOMUX_PIN_NUM_D1 8
#define SDMMC_SLOT0_IOMUX_PIN_NUM_D2 9
#define SDMMC_SLOT0_IOMUX_PIN_NUM_D3 10
#define SDMMC_SLOT0_IOMUX_PIN_NUM_D4 16
#define SDMMC_SLOT0_IOMUX_PIN_NUM_D5 17
#define SDMMC_SLOT0_IOMUX_PIN_NUM_D6 5
#define SDMMC_SLOT0_IOMUX_PIN_NUM_D7 18
#define SDMMC_SLOT0_FUNC 0
#define SDMMC_SLOT1_IOMUX_PIN_NUM_CLK 14
#define SDMMC_SLOT1_IOMUX_PIN_NUM_CMD 15
#define SDMMC_SLOT1_IOMUX_PIN_NUM_D0 2
#define SDMMC_SLOT1_IOMUX_PIN_NUM_D1 4
#define SDMMC_SLOT1_IOMUX_PIN_NUM_D2 12
#define SDMMC_SLOT1_IOMUX_PIN_NUM_D3 13
#define SDMMC_SLOT1_FUNC 4
/* SDMMC pins on ESP32-S3 are configurable through GPIO matrix.
* This file is kept for compatibility only.
*/

View File

@ -19,7 +19,7 @@
extern "C" {
#endif
typedef struct {
typedef struct sdmmc_desc_s {
uint32_t reserved1: 1;
uint32_t disable_int_on_completion: 1;
uint32_t last_descriptor: 1;
@ -32,10 +32,10 @@ typedef struct {
uint32_t buffer1_size: 13;
uint32_t buffer2_size: 13;
uint32_t reserved3: 6;
void *buffer1_ptr;
void* buffer1_ptr;
union {
void *buffer2_ptr;
void *next_desc_ptr;
void* buffer2_ptr;
void* next_desc_ptr;
};
} sdmmc_desc_t;
@ -44,7 +44,7 @@ typedef struct {
_Static_assert(sizeof(sdmmc_desc_t) == 16, "invalid size of sdmmc_desc_t structure");
typedef struct {
typedef struct sdmmc_hw_cmd_s {
uint32_t cmd_index: 6; ///< Command index
uint32_t response_expect: 1; ///< set if response is expected
uint32_t response_long: 1; ///< 0: short response expected, 1: long response expected
@ -73,7 +73,7 @@ typedef struct {
_Static_assert(sizeof(sdmmc_hw_cmd_t) == 4, "invalid size of sdmmc_cmd_t structure");
typedef volatile struct {
typedef volatile struct sdmmc_dev_s {
union {
struct {
uint32_t controller_reset: 1;
@ -282,7 +282,12 @@ typedef volatile struct {
uint32_t usrid; ///< user ID
uint32_t verid; ///< IP block version
uint32_t hcon; ///< compile-time IP configuration
uint32_t uhs; ///< TBD
union {
struct {
uint32_t voltage: 16; ///< voltage control for slots; no-op on ESP32.
uint32_t ddr: 16; ///< bit N enables DDR mode for card N
};
} uhs; ///< UHS related settings
union {
struct {
@ -306,7 +311,7 @@ typedef volatile struct {
} bmod;
uint32_t pldmnd; ///< set any bit to resume IDMAC FSM from suspended state
sdmmc_desc_t *dbaddr; ///< descriptor list base
sdmmc_desc_t* dbaddr; ///< descriptor list base
union {
struct {
@ -347,7 +352,16 @@ typedef volatile struct {
uint32_t bufaddrl; ///< unused
uint32_t bufaddru; ///< unused
uint32_t reserved_a8[22];
uint32_t cardthrctl;
union {
struct {
uint32_t read_thr_en : 1; ///< initiate transfer only if FIFO has more space than the read threshold
uint32_t busy_clr_int_en : 1; ///< enable generation of busy clear interrupts
uint32_t write_thr_en : 1; ///< equivalent of read_thr_en for writes
uint32_t reserved1 : 13;
uint32_t card_threshold : 12; ///< threshold value for reads/writes, in bytes
};
uint32_t val;
} cardthrctl;
uint32_t back_end_power;
uint32_t uhs_reg_ext;
uint32_t emmc_ddr_reg;
@ -361,6 +375,8 @@ typedef volatile struct {
uint32_t div_factor_p: 4; ///< controls clock period; it will be (div_factor_p + 1) / 160MHz
uint32_t div_factor_h: 4; ///< controls length of high pulse; it will be (div_factor_h + 1) / 160MHz
uint32_t div_factor_m: 4; ///< should be equal to div_factor_p
uint32_t reserved1 : 2;
uint32_t clk_sel : 1; ///< clock source select (0: XTAL, 1: 160 MHz from PLL)
};
uint32_t val;
} clock;

View File

@ -21,6 +21,7 @@
#define SOC_HMAC_SUPPORTED 1
#define SOC_ASYNC_MEMCPY_SUPPORTED 1
#define SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS 3
#define SOC_SDMMC_HOST_SUPPORTED 1
/*-------------------------- ADC CAPS ----------------------------------------*/
@ -214,3 +215,13 @@
#define SOC_SPI_MEM_SUPPORT_SW_SUSPEND (1)
/*-------------------------- COEXISTENCE HARDWARE PTI CAPS -------------------------------*/
#define SOC_COEX_HW_PTI (1)
/*-------------------------- SDMMC CAPS -----------------------------------------*/
/* Card detect, write protect, interrupt use GPIO Matrix on all chips.
* On ESP32-S3, clock/cmd/data pins use GPIO Matrix as well.
*/
#define SOC_SDMMC_USE_GPIO_MATRIX 1
#define SOC_SDMMC_NUM_SLOTS 2
/* Indicates that there is an option to use XTAL clock instead of PLL for SDMMC */
#define SOC_SDMMC_SUPPORT_XTAL_CLOCK 1

View File

@ -14,37 +14,44 @@
#include "soc/sdmmc_periph.h"
const sdmmc_slot_info_t sdmmc_slot_info[2] = {
const sdmmc_slot_info_t sdmmc_slot_info[SOC_SDMMC_NUM_SLOTS] = {
{
.clk_gpio = SDMMC_SLOT0_IOMUX_PIN_NUM_CLK,
.cmd_gpio = SDMMC_SLOT0_IOMUX_PIN_NUM_CMD,
.d0_gpio = SDMMC_SLOT0_IOMUX_PIN_NUM_D0,
.d1_gpio = SDMMC_SLOT0_IOMUX_PIN_NUM_D1,
.d2_gpio = SDMMC_SLOT0_IOMUX_PIN_NUM_D2,
.d3_gpio = SDMMC_SLOT0_IOMUX_PIN_NUM_D3,
.d4_gpio = SDMMC_SLOT0_IOMUX_PIN_NUM_D4,
.d5_gpio = SDMMC_SLOT0_IOMUX_PIN_NUM_D5,
.d6_gpio = SDMMC_SLOT0_IOMUX_PIN_NUM_D6,
.d7_gpio = SDMMC_SLOT0_IOMUX_PIN_NUM_D7,
.width = 8,
.card_detect = SDHOST_CARD_DETECT_N_1_IDX,
.write_protect = SDHOST_CARD_WRITE_PRT_1_IDX,
.card_int = SDHOST_CARD_INT_N_1_IDX,
.width = 8
},
{
.clk_gpio = SDMMC_SLOT1_IOMUX_PIN_NUM_CLK,
.cmd_gpio = SDMMC_SLOT1_IOMUX_PIN_NUM_CMD,
.d0_gpio = SDMMC_SLOT1_IOMUX_PIN_NUM_D0,
.d1_gpio = SDMMC_SLOT1_IOMUX_PIN_NUM_D1,
.d2_gpio = SDMMC_SLOT1_IOMUX_PIN_NUM_D2,
.d3_gpio = SDMMC_SLOT1_IOMUX_PIN_NUM_D3,
.d4_gpio = -1, //slot1 has no D4-7
.d5_gpio = -1,
.d6_gpio = -1,
.d7_gpio = -1,
.width = 8,
.card_detect = SDHOST_CARD_DETECT_N_2_IDX,
.write_protect = SDHOST_CARD_WRITE_PRT_2_IDX,
.card_int = SDHOST_CARD_INT_N_2_IDX,
.width = 4
}
};
const sdmmc_slot_io_info_t sdmmc_slot_gpio_sig[SOC_SDMMC_NUM_SLOTS] = {
{
.clk = SDHOST_CCLK_OUT_1_IDX,
.cmd = SDHOST_CCMD_OUT_1_IDX,
.d0 = SDHOST_CDATA_OUT_10_IDX,
.d1 = SDHOST_CDATA_OUT_11_IDX,
.d2 = SDHOST_CDATA_OUT_12_IDX,
.d3 = SDHOST_CDATA_OUT_13_IDX,
.d4 = SDHOST_CDATA_OUT_14_IDX,
.d5 = SDHOST_CDATA_OUT_15_IDX,
.d6 = SDHOST_CDATA_OUT_16_IDX,
.d7 = SDHOST_CDATA_OUT_17_IDX,
},
{
.clk = SDHOST_CCLK_OUT_2_IDX,
.cmd = SDHOST_CCMD_OUT_2_IDX,
.d0 = SDHOST_CDATA_OUT_20_IDX,
.d1 = SDHOST_CDATA_OUT_21_IDX,
.d2 = SDHOST_CDATA_OUT_22_IDX,
.d3 = SDHOST_CDATA_OUT_23_IDX,
.d4 = SDHOST_CDATA_OUT_24_IDX,
.d5 = SDHOST_CDATA_OUT_25_IDX,
.d6 = SDHOST_CDATA_OUT_26_IDX,
.d7 = SDHOST_CDATA_OUT_27_IDX,
}
};

View File

@ -15,6 +15,7 @@
#pragma once
#include <stdint.h>
//include soc related (generated) definitions
#include "soc/soc_caps.h"
#include "soc/soc_pins.h"
#include "soc/sdmmc_reg.h"
#include "soc/sdmmc_struct.h"
@ -24,25 +25,50 @@
extern "C" {
#endif
/**
* Common SDMMC slot info, doesn't depend on SOC_SDMMC_USE_{IOMUX,GPIO_MATRIX}
*/
typedef struct {
uint8_t clk_gpio;
uint8_t cmd_gpio;
uint8_t d0_gpio;
uint8_t d1_gpio;
uint8_t d2_gpio;
uint8_t d3_gpio;
uint8_t d4_gpio;
uint8_t d5_gpio;
uint8_t d6_gpio;
uint8_t d7_gpio;
uint8_t card_detect;
uint8_t write_protect;
uint8_t card_int;
uint8_t width;
uint8_t width; /*!< Maximum supported slot width (1, 4, 8) */
uint8_t card_detect; /*!< Card detect signal in GPIO Matrix */
uint8_t write_protect; /*!< Write protect signal in GPIO Matrix */
uint8_t card_int; /*!< Card interrupt signal in GPIO Matrix */
} sdmmc_slot_info_t;
/** pin and signal information of each slot */
extern const sdmmc_slot_info_t sdmmc_slot_info[];
/** Width and GPIO matrix signal numbers for auxillary SD host signals, one structure per slot */
extern const sdmmc_slot_info_t sdmmc_slot_info[SOC_SDMMC_NUM_SLOTS];
/**
* This structure lists pin numbers (if SOC_SDMMC_USE_IOMUX is set)
* or GPIO Matrix signal numbers (if SOC_SDMMC_USE_GPIO_MATRIX is set)
* for the SD bus signals. Field names match SD bus signal names.
*/
typedef struct {
uint8_t clk;
uint8_t cmd;
uint8_t d0;
uint8_t d1;
uint8_t d2;
uint8_t d3;
uint8_t d4;
uint8_t d5;
uint8_t d6;
uint8_t d7;
} sdmmc_slot_io_info_t;
/* Note: it is in theory possible to have both IOMUX and GPIO Matrix supported
* in the same SoC. However this is not used on any SoC at this point, and would
* complicate the driver. Hence only one of these options is supported at a time.
*/
#if SOC_SDMMC_USE_IOMUX
/** GPIO pin numbers of SD bus signals, one structure per slot */
extern const sdmmc_slot_io_info_t sdmmc_slot_gpio_num[SOC_SDMMC_NUM_SLOTS];
#elif SOC_SDMMC_USE_GPIO_MATRIX
/** GPIO matrix signal numbers of SD bus signals, one structure per slot */
extern const sdmmc_slot_io_info_t sdmmc_slot_gpio_sig[SOC_SDMMC_NUM_SLOTS];
#endif // SOC_SDMMC_USE_{IOMUX,GPIO_MATRIX}
#ifdef __cplusplus
}