mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
Merge branch 'feature/sdio_slave_c6' into 'master'
sdio: c6 support Closes IDF-5809 See merge request espressif/esp-idf!21486
This commit is contained in:
commit
9f3fd2802f
@ -81,8 +81,10 @@ components/driver/test_apps/rs485:
|
||||
components/driver/test_apps/sdio:
|
||||
disable:
|
||||
- if: SOC_SDIO_SLAVE_SUPPORTED != 1
|
||||
disable_test:
|
||||
- if: IDF_TARGET == "esp32c6"
|
||||
temporary: true
|
||||
reason: Not supported.
|
||||
reason: lack of runners
|
||||
|
||||
components/driver/test_apps/spi/master:
|
||||
disable:
|
||||
|
@ -78,7 +78,6 @@ The driver of FIFOs works as below:
|
||||
#include <string.h>
|
||||
#include "driver/sdio_slave.h"
|
||||
#include "soc/sdio_slave_periph.h"
|
||||
#include "esp32/rom/lldesc.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_intr_alloc.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
@ -176,16 +175,16 @@ static inline void critical_exit_recv(void);
|
||||
|
||||
static void deinit_context(void);
|
||||
|
||||
static inline void show_ll(lldesc_t *item)
|
||||
static inline void show_ll(sdio_slave_ll_desc_t *item)
|
||||
{
|
||||
ESP_EARLY_LOGI(TAG, "=> %p: size: %d(%d), eof: %d, owner: %d", item, item->size, item->length, item->eof, item->owner);
|
||||
ESP_EARLY_LOGI(TAG, " buf: %p, stqe_next: %p", item->buf, item->qe.stqe_next);
|
||||
}
|
||||
|
||||
static void __attribute((unused)) dump_ll(lldesc_t *queue)
|
||||
static void __attribute((unused)) dump_ll(sdio_slave_ll_desc_t *queue)
|
||||
{
|
||||
int cnt = 0;
|
||||
lldesc_t *item = queue;
|
||||
sdio_slave_ll_desc_t *item = queue;
|
||||
while (item != NULL) {
|
||||
cnt++;
|
||||
show_ll(item);
|
||||
@ -294,7 +293,7 @@ static void configure_pin(int pin, uint32_t func, bool pullup)
|
||||
static inline esp_err_t sdio_slave_hw_init(sdio_slave_config_t *config)
|
||||
{
|
||||
//initialize pin
|
||||
const sdio_slave_slot_info_t *slot = &sdio_slave_slot_info[1];
|
||||
const sdio_slave_slot_info_t *slot = &sdio_slave_slot_info[0];
|
||||
|
||||
bool pullup = config->flags & SDIO_SLAVE_FLAG_INTERNAL_PULLUP;
|
||||
configure_pin(slot->clk_gpio, slot->func, false); //clk doesn't need a pullup
|
||||
@ -330,7 +329,7 @@ static void recover_pin(int pin, int sdio_func)
|
||||
|
||||
static void sdio_slave_hw_deinit(void)
|
||||
{
|
||||
const sdio_slave_slot_info_t *slot = &sdio_slave_slot_info[1];
|
||||
const sdio_slave_slot_info_t *slot = &sdio_slave_slot_info[0];
|
||||
recover_pin(slot->clk_gpio, slot->func);
|
||||
recover_pin(slot->cmd_gpio, slot->func);
|
||||
recover_pin(slot->d0_gpio, slot->func);
|
||||
|
@ -5,7 +5,7 @@ if(CONFIG_SOC_GPSPI_SUPPORTED)
|
||||
endif()
|
||||
|
||||
if(CONFIG_SOC_SDIO_SLAVE_SUPPORTED)
|
||||
list(APPEND srcs "essl_sdio.c")
|
||||
list(APPEND srcs "essl_sdio.c" "essl_sdio_defs.c")
|
||||
endif()
|
||||
|
||||
idf_component_register(
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -12,12 +12,24 @@
|
||||
#include "essl_internal.h"
|
||||
#include "essl_sdio.h"
|
||||
|
||||
#if SOC_SDIO_SLAVE_SUPPORTED
|
||||
#include "soc/host_reg.h"
|
||||
|
||||
static const char TAG[] = "essl_sdio";
|
||||
|
||||
#define HOST_SLCHOST_CONF_W_REG(pos) (HOST_SLCHOST_CONF_W0_REG+pos+(pos>23?4:0)+(pos>31?12:0))
|
||||
#ifndef DR_REG_SLCHOST_BASE
|
||||
#define DR_REG_SLCHOST_BASE 0 //The SDIO slave only check the least significant 10 bits, this doesn't matter
|
||||
#endif
|
||||
|
||||
//This should be consistent with the macro in soc/host_reg.h
|
||||
#define HOST_SLC0HOST_TOKEN_RDATA_REG (DR_REG_SLCHOST_BASE + 0x44)
|
||||
#define HOST_SLC0HOST_INT_RAW_REG (DR_REG_SLCHOST_BASE + 0x50)
|
||||
#define HOST_SLC0HOST_INT_ST_REG (DR_REG_SLCHOST_BASE + 0x58)
|
||||
#define HOST_SLCHOST_PKT_LEN_REG (DR_REG_SLCHOST_BASE + 0x60)
|
||||
#define HOST_SLCHOST_CONF_W0_REG (DR_REG_SLCHOST_BASE + 0x6C)
|
||||
#define HOST_SLCHOST_CONF_W7_REG (DR_REG_SLCHOST_BASE + 0x8C)
|
||||
#define HOST_SLC0HOST_INT_CLR_REG (DR_REG_SLCHOST_BASE + 0xD4)
|
||||
#define HOST_SLC0HOST_FUNC1_INT_ENA_REG (DR_REG_SLCHOST_BASE + 0xDC)
|
||||
|
||||
|
||||
#define HOST_SLCHOST_CONF_W_REG(pos) (HOST_SLCHOST_CONF_W0_REG+pos+(pos>23?4:0)+(pos>31?12:0))
|
||||
|
||||
#define ESSL_CMD53_END_ADDR 0x1f800
|
||||
|
||||
@ -495,5 +507,3 @@ void essl_sdio_reset_cnt(void *arg)
|
||||
ctx->rx_got_bytes = 0;
|
||||
ctx->tx_sent_buffers = 0;
|
||||
}
|
||||
|
||||
#endif // #if SOC_SDIO_SLAVE_SUPPORTED
|
||||
|
@ -0,0 +1,18 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
// Definitions of Espressif SDIO Slave hardware
|
||||
|
||||
|
||||
#include "essl_sdio.h"
|
||||
|
||||
essl_sdio_def_t ESSL_SDIO_DEF_ESP32 = {
|
||||
.new_packet_intr_mask = BIT(23),
|
||||
};
|
||||
|
||||
essl_sdio_def_t ESSL_SDIO_DEF_ESP32C6 = {
|
||||
.new_packet_intr_mask = BIT(23),
|
||||
};
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -267,9 +267,8 @@ static esp_err_t essl_spi_update_tx_buffer_num(void *arg, uint32_t wait_ms);
|
||||
esp_err_t essl_spi_init_dev(essl_handle_t *out_handle, const essl_spi_config_t *init_config)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(init_config->spi, ESP_ERR_INVALID_STATE, TAG, "Check SPI initialization first");
|
||||
// for esp32-s2 SOC_SPI_MAXIMUM_BUFFER_SIZE is 72, so compiler warns that comparisons of 'tx/rx_sync_reg' are always true
|
||||
ESP_RETURN_ON_FALSE((uint32_t)init_config->tx_sync_reg <= (SOC_SPI_MAXIMUM_BUFFER_SIZE - 1) * 4, ESP_ERR_INVALID_ARG, TAG, "GPSPI supports %d-byte-width internal registers", SOC_SPI_MAXIMUM_BUFFER_SIZE);
|
||||
ESP_RETURN_ON_FALSE((uint32_t)init_config->rx_sync_reg <= (SOC_SPI_MAXIMUM_BUFFER_SIZE - 1) * 4, ESP_ERR_INVALID_ARG, TAG, "GPSPI supports %d-byte-width internal registers", SOC_SPI_MAXIMUM_BUFFER_SIZE);
|
||||
ESP_RETURN_ON_FALSE(init_config->tx_sync_reg <= (SOC_SPI_MAXIMUM_BUFFER_SIZE - 1) * 4, ESP_ERR_INVALID_ARG, TAG, "GPSPI supports %d-byte-width internal registers", SOC_SPI_MAXIMUM_BUFFER_SIZE);
|
||||
ESP_RETURN_ON_FALSE(init_config->rx_sync_reg <= (SOC_SPI_MAXIMUM_BUFFER_SIZE - 1) * 4, ESP_ERR_INVALID_ARG, TAG, "GPSPI supports %d-byte-width internal registers", SOC_SPI_MAXIMUM_BUFFER_SIZE);
|
||||
ESP_RETURN_ON_FALSE(init_config->tx_sync_reg != init_config->rx_sync_reg, ESP_ERR_INVALID_ARG, TAG, "Should use different word of registers for synchronization");
|
||||
|
||||
essl_spi_context_t *context = calloc(1, sizeof(essl_spi_context_t));
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -9,9 +9,11 @@
|
||||
#pragma once
|
||||
|
||||
#include "esp_err.h"
|
||||
#include "driver/sdmmc_types.h"
|
||||
#include "driver/sdmmc_host.h"
|
||||
|
||||
#include "esp_serial_slave_link/essl.h"
|
||||
#include "essl_sdio_defs.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
/**
|
||||
* This file contains SDIO Slave hardware specific requirements
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
//interrupts
|
||||
uint32_t new_packet_intr_mask;
|
||||
} essl_sdio_def_t;
|
||||
|
||||
/// Definitions of ESP32 SDIO Slave hardware
|
||||
extern essl_sdio_def_t ESSL_SDIO_DEF_ESP32;
|
||||
/// Definitions of ESP32C6 SDIO Slave hardware
|
||||
extern essl_sdio_def_t ESSL_SDIO_DEF_ESP32C6;
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1,2 +1,2 @@
|
||||
| Supported Targets | ESP32 |
|
||||
| ----------------- | ----- |
|
||||
| Supported Targets | ESP32 | ESP32-C6 |
|
||||
| ----------------- | ----- | -------- |
|
@ -134,10 +134,12 @@ if(NOT BOOTLOADER_BUILD)
|
||||
list(APPEND srcs "spi_slave_hd_hal.c")
|
||||
endif()
|
||||
|
||||
if(CONFIG_SOC_SDIO_SLAVE_SUPPORTED)
|
||||
list(APPEND srcs "sdio_slave_hal.c")
|
||||
endif()
|
||||
|
||||
if(${target} STREQUAL "esp32")
|
||||
list(APPEND srcs
|
||||
"sdio_slave_hal.c"
|
||||
"touch_sensor_hal.c"
|
||||
"esp32/touch_sensor_hal.c"
|
||||
"esp32/gpio_hal_workaround.c")
|
||||
|
@ -1,16 +1,8 @@
|
||||
// Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
* NOTICE
|
||||
@ -40,6 +32,33 @@
|
||||
#define sdio_slave_ll_get_hinf(ID) (&HINF)
|
||||
|
||||
|
||||
/*
|
||||
* SLC2 DMA Desc struct, aka sdio_slave_ll_desc_t
|
||||
*
|
||||
* --------------------------------------------------------------
|
||||
* | own | EoF | sub_sof | 5'b0 | length [11:0] | size [11:0] |
|
||||
* --------------------------------------------------------------
|
||||
* | buf_ptr [31:0] |
|
||||
* --------------------------------------------------------------
|
||||
* | next_desc_ptr [31:0] |
|
||||
* --------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/* this bitfield is start from the LSB!!! */
|
||||
typedef struct sdio_slave_ll_desc_s {
|
||||
volatile uint32_t size : 12,
|
||||
length: 12,
|
||||
offset: 5, /* starting from bit24, h/w reserved 5bit, s/w use it as offset in buffer */
|
||||
sosf : 1, /* start of sub-frame */
|
||||
eof : 1, /* end of frame */
|
||||
owner : 1; /* hw or sw */
|
||||
volatile const uint8_t *buf; /* point to buffer data */
|
||||
union {
|
||||
volatile uint32_t empty;
|
||||
STAILQ_ENTRY(sdio_slave_ll_desc_s) qe; /* pointing to the next desc */
|
||||
};
|
||||
} sdio_slave_ll_desc_t;
|
||||
|
||||
/// Mask of general purpose interrupts sending from the host.
|
||||
typedef enum {
|
||||
SDIO_SLAVE_LL_SLVINT_0 = BIT(0), ///< General purpose interrupt bit 0.
|
||||
@ -109,6 +128,14 @@ static inline void sdio_slave_ll_set_timing(host_dev_t *host, sdio_slave_timing_
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the CCCR, SDIO and Physical Layer version
|
||||
*/
|
||||
static inline void sdio_slave_ll_init_version(hinf_dev_t *hinf)
|
||||
{
|
||||
hinf->cfg_data1.sdio_ver = 0x232;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the HS supported bit to be read by the host.
|
||||
*
|
||||
@ -118,8 +145,9 @@ static inline void sdio_slave_ll_set_timing(host_dev_t *host, sdio_slave_timing_
|
||||
static inline void sdio_slave_ll_enable_hs(hinf_dev_t *hinf, bool hs)
|
||||
{
|
||||
if (hs) {
|
||||
hinf->cfg_data1.sdio_ver = 0x232;
|
||||
hinf->cfg_data1.highspeed_enable = 1;
|
||||
} else {
|
||||
hinf->cfg_data1.highspeed_enable = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -155,7 +183,7 @@ static inline void sdio_slave_ll_send_reset(slc_dev_t *slc)
|
||||
* @param slc Address of the SLC registers
|
||||
* @param desc Descriptor to send
|
||||
*/
|
||||
static inline void sdio_slave_ll_send_start(slc_dev_t *slc, const lldesc_t *desc)
|
||||
static inline void sdio_slave_ll_send_start(slc_dev_t *slc, const sdio_slave_ll_desc_t *desc)
|
||||
{
|
||||
slc->slc0_rx_link.addr = (uint32_t)desc;
|
||||
slc->slc0_rx_link.start = 1;
|
||||
@ -289,7 +317,7 @@ static inline void sdio_slave_ll_recv_intr_ena(slc_dev_t *slc, bool ena)
|
||||
* @param slc Address of the SLC registers
|
||||
* @param desc Descriptor of the receiving buffer.
|
||||
*/
|
||||
static inline void sdio_slave_ll_recv_start(slc_dev_t *slc, lldesc_t *desc)
|
||||
static inline void sdio_slave_ll_recv_start(slc_dev_t *slc, sdio_slave_ll_desc_t *desc)
|
||||
{
|
||||
slc->slc0_tx_link.addr = (uint32_t)desc;
|
||||
slc->slc0_tx_link.start = 1;
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -72,6 +72,8 @@ static inline uint32_t periph_ll_get_clk_en_mask(periph_module_t periph)
|
||||
return PCR_DS_CLK_EN;
|
||||
case PERIPH_TEMPSENSOR_MODULE:
|
||||
return PCR_TSENS_CLK_EN;
|
||||
case PERIPH_SDIO_SLAVE_MODULE:
|
||||
return PCR_SDIO_SLAVE_CLK_EN;
|
||||
// case PERIPH_RNG_MODULE:
|
||||
// return PCR_WIFI_CLK_RNG_EN;
|
||||
// case PERIPH_WIFI_MODULE:
|
||||
@ -164,6 +166,8 @@ static inline uint32_t periph_ll_get_rst_en_mask(periph_module_t periph, bool en
|
||||
return PCR_HMAC_RST_EN;
|
||||
case PERIPH_DS_MODULE:
|
||||
return PCR_DS_RST_EN;
|
||||
case PERIPH_SDIO_SLAVE_MODULE:
|
||||
return PCR_SDIO_SLAVE_RST_EN;
|
||||
// case PERIPH_RNG_MODULE:
|
||||
// return PCR_WIFI_CLK_RNG_EN;
|
||||
// case PERIPH_WIFI_MODULE:
|
||||
@ -244,6 +248,8 @@ static uint32_t periph_ll_get_clk_en_reg(periph_module_t periph)
|
||||
return PCR_DS_CONF_REG;
|
||||
case PERIPH_TEMPSENSOR_MODULE:
|
||||
return PCR_TSENS_CLK_CONF_REG;
|
||||
case PERIPH_SDIO_SLAVE_MODULE:
|
||||
return PCR_SDIO_SLAVE_CONF_REG;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
@ -304,6 +310,8 @@ static uint32_t periph_ll_get_rst_en_reg(periph_module_t periph)
|
||||
return PCR_DS_CONF_REG;
|
||||
case PERIPH_TEMPSENSOR_MODULE:
|
||||
return PCR_TSENS_CLK_CONF_REG;
|
||||
case PERIPH_SDIO_SLAVE_MODULE:
|
||||
return PCR_SDIO_SLAVE_CONF_REG;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
509
components/hal/esp32c6/include/hal/sdio_slave_ll.h
Normal file
509
components/hal/esp32c6/include/hal/sdio_slave_ll.h
Normal file
@ -0,0 +1,509 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
* NOTICE
|
||||
* The hal is not public api, don't use in application code.
|
||||
* See readme.md in hal/include/hal/readme.md
|
||||
******************************************************************************/
|
||||
|
||||
// The LL layer for SDIO slave register operations
|
||||
// It's strange but `tx_*` regs for host->slave transfers while `rx_*` regs for slave->host transfers
|
||||
// To reduce ambiguity, we call (host->slave, tx) transfers receiving and (slave->host, rx) transfers receiving
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "hal/sdio_slave_hal.h"
|
||||
#include "soc/slc_struct.h"
|
||||
#include "soc/slc_reg.h"
|
||||
#include "soc/host_struct.h"
|
||||
#include "soc/host_reg.h"
|
||||
#include "soc/hinf_struct.h"
|
||||
#include "soc/lldesc.h"
|
||||
|
||||
/// Get address of the only SLC registers
|
||||
#define sdio_slave_ll_get_slc(ID) (&SLC)
|
||||
/// Get address of the only HOST registers
|
||||
#define sdio_slave_ll_get_host(ID) (&HOST)
|
||||
/// Get address of the only HINF registers
|
||||
#define sdio_slave_ll_get_hinf(ID) (&HINF)
|
||||
|
||||
|
||||
/*
|
||||
* SLC2 DMA Desc struct, aka sdio_slave_ll_desc_t
|
||||
*
|
||||
* --------------------------------------------------------------
|
||||
* | own | EoF | sub_sof | 1'b0 | length [13:0] | size [13:0] |
|
||||
* --------------------------------------------------------------
|
||||
* | buf_ptr [31:0] |
|
||||
* --------------------------------------------------------------
|
||||
* | next_desc_ptr [31:0] |
|
||||
* --------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/* this bitfield is start from the LSB!!! */
|
||||
typedef struct sdio_slave_ll_desc_s {
|
||||
volatile uint32_t size : 14,
|
||||
length: 14,
|
||||
offset: 1, /* starting from bit28, h/w reserved 1bit, s/w use it as offset in buffer */
|
||||
sosf : 1, /* start of sub-frame */
|
||||
eof : 1, /* end of frame */
|
||||
owner : 1; /* hw or sw */
|
||||
volatile const uint8_t *buf; /* point to buffer data */
|
||||
union {
|
||||
volatile uint32_t empty;
|
||||
STAILQ_ENTRY(sdio_slave_ll_desc_s) qe; /* pointing to the next desc */
|
||||
};
|
||||
} sdio_slave_ll_desc_t;
|
||||
|
||||
/// Mask of general purpose interrupts sending from the host.
|
||||
typedef enum {
|
||||
SDIO_SLAVE_LL_SLVINT_0 = BIT(0), ///< General purpose interrupt bit 0.
|
||||
SDIO_SLAVE_LL_SLVINT_1 = BIT(1),
|
||||
SDIO_SLAVE_LL_SLVINT_2 = BIT(2),
|
||||
SDIO_SLAVE_LL_SLVINT_3 = BIT(3),
|
||||
SDIO_SLAVE_LL_SLVINT_4 = BIT(4),
|
||||
SDIO_SLAVE_LL_SLVINT_5 = BIT(5),
|
||||
SDIO_SLAVE_LL_SLVINT_6 = BIT(6),
|
||||
SDIO_SLAVE_LL_SLVINT_7 = BIT(7),
|
||||
} sdio_slave_ll_slvint_t;
|
||||
|
||||
/**
|
||||
* Initialize the hardware.
|
||||
*
|
||||
* @param slc Address of the SLC registers
|
||||
*/
|
||||
static inline void sdio_slave_ll_init(slc_dev_t *slc)
|
||||
{
|
||||
slc->slc0int_ena.val = 0;
|
||||
|
||||
slc->slcconf0.slc0_rx_auto_wrback = 1;
|
||||
slc->slcconf0.slc0_token_auto_clr = 0;
|
||||
slc->slcconf0.slc0_rx_loop_test = 0;
|
||||
slc->slcconf0.slc0_tx_loop_test = 0;
|
||||
|
||||
slc->slcconf1.slc0_rx_stitch_en = 0;
|
||||
slc->slcconf1.slc0_tx_stitch_en = 0;
|
||||
slc->slcconf1.slc0_len_auto_clr = 0;
|
||||
|
||||
slc->slc_rx_dscr_conf.slc0_token_no_replace = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the timing for the communication
|
||||
*
|
||||
* @param host Address of the host registers
|
||||
* @param timing Timing configuration to set
|
||||
*/
|
||||
static inline void sdio_slave_ll_set_timing(host_dev_t *host, sdio_slave_timing_t timing)
|
||||
{
|
||||
switch(timing) {
|
||||
case SDIO_SLAVE_TIMING_PSEND_PSAMPLE:
|
||||
host->conf.frc_sdio20 = 0x1f;
|
||||
host->conf.frc_sdio11 = 0;
|
||||
host->conf.frc_pos_samp = 0x1f;
|
||||
host->conf.frc_neg_samp = 0;
|
||||
break;
|
||||
case SDIO_SLAVE_TIMING_PSEND_NSAMPLE:
|
||||
host->conf.frc_sdio20 = 0x1f;
|
||||
host->conf.frc_sdio11 = 0;
|
||||
host->conf.frc_pos_samp = 0;
|
||||
host->conf.frc_neg_samp = 0x1f;
|
||||
break;
|
||||
case SDIO_SLAVE_TIMING_NSEND_PSAMPLE:
|
||||
host->conf.frc_sdio20 = 0;
|
||||
host->conf.frc_sdio11 = 0x1f;
|
||||
host->conf.frc_pos_samp = 0x1f;
|
||||
host->conf.frc_neg_samp = 0;
|
||||
break;
|
||||
case SDIO_SLAVE_TIMING_NSEND_NSAMPLE:
|
||||
host->conf.frc_sdio20 = 0;
|
||||
host->conf.frc_sdio11 = 0x1f;
|
||||
host->conf.frc_pos_samp = 0;
|
||||
host->conf.frc_neg_samp = 0x1f;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the CCCR, SDIO and Physical Layer version
|
||||
*/
|
||||
static inline void sdio_slave_ll_init_version(hinf_dev_t *hinf)
|
||||
{
|
||||
hinf->cfg_data1.sdio_ver = 0x232;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the HS supported bit to be read by the host.
|
||||
*
|
||||
* @param hinf Address of the hinf registers
|
||||
* @param hs true if supported, otherwise false.
|
||||
*/
|
||||
static inline void sdio_slave_ll_enable_hs(hinf_dev_t *hinf, bool hs)
|
||||
{
|
||||
if (hs) {
|
||||
hinf->cfg_data1.highspeed_enable = 1;
|
||||
} else {
|
||||
hinf->cfg_data1.highspeed_enable = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the IO Ready bit to be read by the host.
|
||||
*
|
||||
* @param hinf Address of the hinf registers
|
||||
* @param ready true if ready, otherwise false.
|
||||
*/
|
||||
static inline void sdio_slave_ll_set_ioready(hinf_dev_t *hinf, bool ready)
|
||||
{
|
||||
hinf->cfg_data1.sdio_ioready1 = (ready ? 1 : 0); //set IO ready to 1 to stop host from using
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
* Send
|
||||
*--------------------------------------------------------------------------*/
|
||||
/**
|
||||
* Reset the sending DMA.
|
||||
*
|
||||
* @param slc Address of the SLC registers
|
||||
*/
|
||||
static inline void sdio_slave_ll_send_reset(slc_dev_t *slc)
|
||||
{
|
||||
//reset to flush previous packets
|
||||
slc->slcconf0.slc0_rx_rst = 1;
|
||||
slc->slcconf0.slc0_rx_rst = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Start the sending DMA with the given descriptor.
|
||||
*
|
||||
* @param slc Address of the SLC registers
|
||||
* @param desc Descriptor to send
|
||||
*/
|
||||
static inline void sdio_slave_ll_send_start(slc_dev_t *slc, const sdio_slave_ll_desc_t *desc)
|
||||
{
|
||||
slc->slc0rx_link_addr.slc0_rxlink_addr = (uint32_t)desc;
|
||||
slc->slc0rx_link.slc0_rxlink_start = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the PKT_LEN register to be written by the host to a certain value.
|
||||
*
|
||||
* @param slc Address of the SLC registers
|
||||
* @param len Length to write
|
||||
*/
|
||||
static inline void sdio_slave_ll_send_write_len(slc_dev_t *slc, uint32_t len)
|
||||
{
|
||||
slc->slc0_len_conf.val = FIELD_TO_VALUE2(SDIO_SLC0_LEN_WDATA, len) | FIELD_TO_VALUE2(SDIO_SLC0_LEN_WR, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the value of PKT_LEN register. The register may keep the same until read
|
||||
* by the host.
|
||||
*
|
||||
* @param host Address of the host registers
|
||||
* @return The value of PKT_LEN register.
|
||||
*/
|
||||
static inline uint32_t sdio_slave_ll_send_read_len(host_dev_t *host)
|
||||
{
|
||||
return host->pkt_len.hostslchost_slc0_len;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable the rx_done interrupt. (sending)
|
||||
*
|
||||
* @param slc Address of the SLC registers
|
||||
* @param ena true if enable, otherwise false.
|
||||
*/
|
||||
static inline void sdio_slave_ll_send_part_done_intr_ena(slc_dev_t *slc, bool ena)
|
||||
{
|
||||
slc->slc0int_ena.slc0_rx_done_int_ena = (ena ? 1 : 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the rx_done interrupt. (sending)
|
||||
*
|
||||
* @param slc Address of the SLC registers
|
||||
*/
|
||||
static inline void sdio_slave_ll_send_part_done_clear(slc_dev_t *slc)
|
||||
{
|
||||
slc->slc0int_clr.slc0_rx_done_int_clr = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the hardware is ready for the SW to use rx_done to invoke
|
||||
* the ISR.
|
||||
*
|
||||
* @param slc Address of the SLC registers
|
||||
* @return true if ready, otherwise false.
|
||||
*/
|
||||
static inline bool sdio_slave_ll_send_invoker_ready(slc_dev_t *slc)
|
||||
{
|
||||
return slc->slc0int_raw.slc0_rx_done_int_raw;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop the sending DMA.
|
||||
*
|
||||
* @param slc Address of the SLC registers
|
||||
*/
|
||||
static inline void sdio_slave_ll_send_stop(slc_dev_t *slc)
|
||||
{
|
||||
slc->slc0rx_link.slc0_rxlink_stop = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable the sending interrupt (rx_eof).
|
||||
*
|
||||
* @param slc Address of the SLC registers
|
||||
* @param ena true to enable, false to disable
|
||||
*/
|
||||
static inline void sdio_slave_ll_send_intr_ena(slc_dev_t *slc, bool ena)
|
||||
{
|
||||
slc->slc0int_ena.slc0_rx_eof_int_ena = (ena? 1: 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the sending interrupt (rx_eof).
|
||||
*
|
||||
* @param slc Address of the SLC registers
|
||||
*/
|
||||
static inline void sdio_slave_ll_send_intr_clr(slc_dev_t *slc)
|
||||
{
|
||||
slc->slc0int_clr.slc0_rx_eof_int_clr = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the sending is done.
|
||||
*
|
||||
* @param slc Address of the SLC registers
|
||||
* @return true if done, otherwise false
|
||||
*/
|
||||
static inline bool sdio_slave_ll_send_done(slc_dev_t *slc)
|
||||
{
|
||||
return slc->slc0int_st.slc0_rx_eof_int_st != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the host interrupt indicating the slave having packet to be read.
|
||||
*
|
||||
* @param host Address of the host registers
|
||||
*/
|
||||
static inline void sdio_slave_ll_send_hostint_clr(host_dev_t *host)
|
||||
{
|
||||
host->slc0host_int_clr.slc0_rx_new_packet_int_clr = 1;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
* Receive
|
||||
*--------------------------------------------------------------------------*/
|
||||
/**
|
||||
* Enable the receiving interrupt.
|
||||
*
|
||||
* @param slc Address of the SLC registers
|
||||
* @param ena
|
||||
*/
|
||||
static inline void sdio_slave_ll_recv_intr_ena(slc_dev_t *slc, bool ena)
|
||||
{
|
||||
slc->slc0int_ena.slc0_tx_done_int_ena = (ena ? 1 : 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Start receiving DMA with the given descriptor.
|
||||
*
|
||||
* @param slc Address of the SLC registers
|
||||
* @param desc Descriptor of the receiving buffer.
|
||||
*/
|
||||
static inline void sdio_slave_ll_recv_start(slc_dev_t *slc, sdio_slave_ll_desc_t *desc)
|
||||
{
|
||||
slc->slc0tx_link_addr.slc0_txlink_addr = (uint32_t)desc;
|
||||
slc->slc0tx_link.slc0_txlink_start = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Increase the receiving buffer counter by 1.
|
||||
*
|
||||
* @param slc Address of the SLC registers
|
||||
*/
|
||||
static inline void sdio_slave_ll_recv_size_inc(slc_dev_t *slc)
|
||||
{
|
||||
// fields wdata and inc_more should be written by the same instruction.
|
||||
slc->slc0token1.val = FIELD_TO_VALUE2(SDIO_SLC0_TOKEN1_WDATA, 1) | FIELD_TO_VALUE2(SDIO_SLC0_TOKEN1_INC_MORE, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the receiving buffer.
|
||||
*
|
||||
* @param slc Address of the SLC registers
|
||||
*/
|
||||
static inline void sdio_slave_ll_recv_size_reset(slc_dev_t *slc)
|
||||
{
|
||||
slc->slc0token1.val = FIELD_TO_VALUE2(SDIO_SLC0_TOKEN1_WDATA, 0) | FIELD_TO_VALUE2(SDIO_SLC0_TOKEN1_WR, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether there is a receiving finished event.
|
||||
*
|
||||
* @param slc Address of the SLC registers
|
||||
* @return
|
||||
*/
|
||||
static inline bool sdio_slave_ll_recv_done(slc_dev_t *slc)
|
||||
{
|
||||
return slc->slc0int_raw.slc0_tx_done_int_raw != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the receiving finished interrupt.
|
||||
*
|
||||
* @param slc Address of the SLC registers
|
||||
*/
|
||||
static inline void sdio_slave_ll_recv_done_clear(slc_dev_t *slc)
|
||||
{
|
||||
slc->slc0int_clr.slc0_tx_done_int_clr = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Restart the DMA. Call after you modified the next pointer of the tail descriptor to the appended
|
||||
* descriptor.
|
||||
*
|
||||
* @param slc Address of the SLC registers
|
||||
*/
|
||||
static inline void sdio_slave_ll_recv_restart(slc_dev_t *slc)
|
||||
{
|
||||
slc->slc0tx_link.slc0_txlink_restart = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the receiving DMA.
|
||||
*
|
||||
* @param slc Address of the SLC registers
|
||||
*/
|
||||
static inline void sdio_slave_ll_recv_reset(slc_dev_t *slc)
|
||||
{
|
||||
slc->slcconf0.slc0_tx_rst = 1;
|
||||
slc->slcconf0.slc0_tx_rst = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop the receiving DMA.
|
||||
*
|
||||
* @param slc Address of the SLC registers
|
||||
*/
|
||||
static inline void sdio_slave_ll_recv_stop(slc_dev_t *slc)
|
||||
{
|
||||
slc->slc0tx_link.slc0_txlink_stop = 1;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
* Host
|
||||
*--------------------------------------------------------------------------*/
|
||||
/**
|
||||
* Get the address of the shared general purpose register. Internal.
|
||||
*
|
||||
* @param host Address of the host registers
|
||||
* @param pos Position of the register, 0-63 except 24-27.
|
||||
* @return address of the register.
|
||||
*/
|
||||
static inline intptr_t sdio_slave_ll_host_get_w_reg(host_dev_t* host, int pos)
|
||||
{
|
||||
return (intptr_t )&(host->conf_w0) + pos + (pos>23?4:0) + (pos>31?12:0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of the shared general purpose register.
|
||||
*
|
||||
* @param host Address of the host registers
|
||||
* @param pos Position of the register, 0-63, except 24-27.
|
||||
* @return value of the register.
|
||||
*/
|
||||
static inline uint8_t sdio_slave_ll_host_get_reg(host_dev_t *host, int pos)
|
||||
{
|
||||
return *(uint8_t*)sdio_slave_ll_host_get_w_reg(host, pos);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value of the shared general purpose register.
|
||||
*
|
||||
* @param host Address of the host registers
|
||||
* @param pos Position of the register, 0-63, except 24-27.
|
||||
* @param reg Value to set.
|
||||
*/
|
||||
static inline void sdio_slave_ll_host_set_reg(host_dev_t* host, int pos, uint8_t reg)
|
||||
{
|
||||
uint32_t* addr = (uint32_t*)(sdio_slave_ll_host_get_w_reg(host, pos) & (~3));
|
||||
uint32_t shift = (pos % 4) * 8;
|
||||
*addr &= ~(0xff << shift);
|
||||
*addr |= ((uint32_t)reg << shift);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the interrupt enable bits for the host.
|
||||
*
|
||||
* @param host Address of the host registers
|
||||
* @return Enabled interrupts
|
||||
*/
|
||||
static inline sdio_slave_hostint_t sdio_slave_ll_host_get_intena(host_dev_t* host)
|
||||
{
|
||||
return host->slc0host_func1_int_ena.val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the interrupt enable bits for the host.
|
||||
*
|
||||
* @param host Address of the host registers
|
||||
* @param mask Mask of interrupts to enable
|
||||
*/
|
||||
static inline void sdio_slave_ll_host_set_intena(host_dev_t *host, const sdio_slave_hostint_t *mask)
|
||||
{
|
||||
host->slc0host_func1_int_ena.val = (*mask);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the interrupt bits for the host.
|
||||
* @param host Address of the host registers
|
||||
* @param mask Mask of interrupts to clear.
|
||||
*/
|
||||
static inline void sdio_slave_ll_host_intr_clear(host_dev_t* host, const sdio_slave_hostint_t *mask)
|
||||
{
|
||||
host->slc0host_int_clr.val = (*mask);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send general purpose interrupts to the host.
|
||||
* @param slc Address of the SLC registers
|
||||
* @param mask Mask of interrupts to seend to host
|
||||
*/
|
||||
static inline void sdio_slave_ll_host_send_int(slc_dev_t *slc, const sdio_slave_hostint_t *mask)
|
||||
{
|
||||
//use registers in SLC to trigger, rather than write HOST registers directly
|
||||
//other interrupts than tohost interrupts are not supported yet
|
||||
slc->slcintvec_tohost.slc0_tohost_intvec = (*mask);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable some of the slave interrups (send from host)
|
||||
*
|
||||
* @param slc Address of the SLC registers
|
||||
* @param mask Mask of interrupts to enable, all those set to 0 will be disabled.
|
||||
*/
|
||||
static inline void sdio_slave_ll_slvint_set_ena(slc_dev_t *slc, const sdio_slave_ll_slvint_t *mask)
|
||||
{
|
||||
//other interrupts are not enabled
|
||||
slc->slc0int_ena.val = (slc->slc0int_ena.val & (~0xff)) | ((*mask) & 0xff);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the slave interrupts (send from host) and clear them.
|
||||
*
|
||||
* @param slc Address of the SLC registers
|
||||
* @param out_slv_int Output of the slave interrupts fetched and cleared.
|
||||
*/
|
||||
static inline void sdio_slave_ll_slvint_fetch_clear(slc_dev_t *slc, sdio_slave_ll_slvint_t *out_slv_int)
|
||||
{
|
||||
sdio_slave_ll_slvint_t slv_int = slc->slc0int_st.val & 0xff;
|
||||
*out_slv_int = slv_int;
|
||||
slc->slc0int_clr.val = slv_int;
|
||||
}
|
@ -141,7 +141,6 @@ The HAL is used as below:
|
||||
|
||||
#pragma once
|
||||
#include <esp_err.h>
|
||||
#include "soc/lldesc.h"
|
||||
#include "hal/sdio_slave_types.h"
|
||||
#include "hal/sdio_slave_ll.h"
|
||||
|
||||
@ -172,15 +171,15 @@ typedef struct {
|
||||
|
||||
/// DMA descriptor with extra fields
|
||||
typedef struct sdio_slave_hal_send_desc_s {
|
||||
lldesc_t dma_desc; ///< Used by Hardware, has pointer linking to next desc
|
||||
sdio_slave_ll_desc_t dma_desc; ///< Used by Hardware, has pointer linking to next desc
|
||||
uint32_t pkt_len; ///< Accumulated length till this descriptor
|
||||
void* arg; ///< Holding arguments indicating this buffer */
|
||||
} sdio_slave_hal_send_desc_t;
|
||||
|
||||
/// Descriptor used by the receiving part, call `sdio_slave_hal_recv_init_desc`
|
||||
/// to initialize it before use.
|
||||
typedef lldesc_t sdio_slave_hal_recv_desc_t;
|
||||
#define sdio_slave_hal_recv_desc_s lldesc_s
|
||||
typedef sdio_slave_ll_desc_t sdio_slave_hal_recv_desc_t;
|
||||
#define sdio_slave_hal_recv_desc_s sdio_slave_ll_desc_s
|
||||
typedef STAILQ_HEAD(recv_stailq_head_s, sdio_slave_hal_recv_desc_s) sdio_slave_hal_recv_stailq_t;
|
||||
|
||||
|
||||
|
@ -46,7 +46,7 @@ static inline int sdio_ringbuf_return(sdio_ringbuf_t* buf, uint8_t *ptr);
|
||||
#define _SEND_DESC_NEXT(x) STAILQ_NEXT(&((sdio_slave_hal_send_desc_t*)x)->dma_desc, qe)
|
||||
#define SEND_DESC_NEXT(x) (sdio_slave_hal_send_desc_t*)_SEND_DESC_NEXT(x)
|
||||
#define SEND_DESC_NEXT_SET(x, target) do { \
|
||||
_SEND_DESC_NEXT(x)=(lldesc_t*)target; \
|
||||
_SEND_DESC_NEXT(x)=(sdio_slave_ll_desc_t*)target; \
|
||||
}while(0)
|
||||
|
||||
static esp_err_t link_desc_to_last(uint8_t* desc, void* arg)
|
||||
@ -259,7 +259,7 @@ static inline send_state_t send_get_state(sdio_slave_context_t* hal)
|
||||
return hal->send_state;
|
||||
}
|
||||
|
||||
DMA_ATTR static const lldesc_t start_desc = {
|
||||
DMA_ATTR static const sdio_slave_ll_desc_t start_desc = {
|
||||
.owner = 1,
|
||||
.buf = (void*)0x3ffbbbbb, //assign a dma-capable pointer other than NULL, which will not be used
|
||||
.size = 1,
|
||||
@ -319,7 +319,7 @@ static void send_new_packet(sdio_slave_context_t *hal)
|
||||
|
||||
sdio_slave_ll_send_stop(hal->slc);
|
||||
sdio_slave_ll_send_reset(hal->slc);
|
||||
sdio_slave_ll_send_start(hal->slc, (lldesc_t*)start_desc);
|
||||
sdio_slave_ll_send_start(hal->slc, (sdio_slave_ll_desc_t*)start_desc);
|
||||
|
||||
// update pkt_len register to allow host reading.
|
||||
sdio_slave_ll_send_write_len(hal->slc, end_desc->pkt_len);
|
||||
@ -552,10 +552,10 @@ esp_err_t sdio_slave_hal_send_queue(sdio_slave_context_t* hal, uint8_t *addr, si
|
||||
* Receive
|
||||
*--------------------------------------------------------------------------*/
|
||||
|
||||
static lldesc_t* recv_get_first_empty_buf(sdio_slave_context_t* hal)
|
||||
static sdio_slave_ll_desc_t* recv_get_first_empty_buf(sdio_slave_context_t* hal)
|
||||
{
|
||||
sdio_slave_hal_recv_stailq_t *const queue = &(hal->recv_link_list);
|
||||
lldesc_t *desc = STAILQ_FIRST(queue);
|
||||
sdio_slave_ll_desc_t *desc = STAILQ_FIRST(queue);
|
||||
while(desc && desc->owner == 0) {
|
||||
desc = STAILQ_NEXT(desc, qe);
|
||||
}
|
||||
@ -593,19 +593,19 @@ bool sdio_slave_hal_recv_done(sdio_slave_context_t *hal)
|
||||
return ret;
|
||||
}
|
||||
|
||||
lldesc_t *sdio_slave_hal_recv_unload_desc(sdio_slave_context_t *hal)
|
||||
sdio_slave_ll_desc_t *sdio_slave_hal_recv_unload_desc(sdio_slave_context_t *hal)
|
||||
{
|
||||
sdio_slave_hal_recv_stailq_t *const queue = &hal->recv_link_list;
|
||||
lldesc_t *desc = STAILQ_FIRST(queue);
|
||||
sdio_slave_ll_desc_t *desc = STAILQ_FIRST(queue);
|
||||
if (desc) {
|
||||
STAILQ_REMOVE_HEAD(queue, qe);
|
||||
}
|
||||
return desc;
|
||||
}
|
||||
|
||||
void sdio_slave_hal_recv_init_desc(sdio_slave_context_t* hal, lldesc_t *desc, uint8_t *start)
|
||||
void sdio_slave_hal_recv_init_desc(sdio_slave_context_t* hal, sdio_slave_ll_desc_t *desc, uint8_t *start)
|
||||
{
|
||||
*desc = (lldesc_t) {
|
||||
*desc = (sdio_slave_ll_desc_t) {
|
||||
.size = hal->recv_buffer_size,
|
||||
.buf = start,
|
||||
};
|
||||
@ -614,7 +614,7 @@ void sdio_slave_hal_recv_init_desc(sdio_slave_context_t* hal, lldesc_t *desc, ui
|
||||
void sdio_slave_hal_recv_start(sdio_slave_context_t *hal)
|
||||
{
|
||||
sdio_slave_ll_recv_reset(hal->slc);
|
||||
lldesc_t *desc = recv_get_first_empty_buf(hal);
|
||||
sdio_slave_ll_desc_t *desc = recv_get_first_empty_buf(hal);
|
||||
if (!desc) {
|
||||
HAL_LOGD(TAG, "recv: restart without desc");
|
||||
} else {
|
||||
@ -627,7 +627,7 @@ void sdio_slave_hal_recv_start(sdio_slave_context_t *hal)
|
||||
void sdio_slave_hal_recv_reset_counter(sdio_slave_context_t *hal)
|
||||
{
|
||||
sdio_slave_ll_recv_size_reset(hal->slc);
|
||||
lldesc_t *desc = recv_get_first_empty_buf(hal);
|
||||
sdio_slave_ll_desc_t *desc = recv_get_first_empty_buf(hal);
|
||||
while (desc != NULL) {
|
||||
sdio_slave_ll_recv_size_inc(hal->slc);
|
||||
desc = STAILQ_NEXT(desc, qe);
|
||||
@ -637,7 +637,7 @@ void sdio_slave_hal_recv_reset_counter(sdio_slave_context_t *hal)
|
||||
void sdio_slave_hal_recv_flush_one_buffer(sdio_slave_context_t *hal)
|
||||
{
|
||||
sdio_slave_hal_recv_stailq_t *const queue = &hal->recv_link_list;
|
||||
lldesc_t *desc = STAILQ_FIRST(queue);
|
||||
sdio_slave_ll_desc_t *desc = STAILQ_FIRST(queue);
|
||||
assert (desc != NULL && desc->owner == 0);
|
||||
STAILQ_REMOVE_HEAD(queue, qe);
|
||||
desc->owner = 1;
|
||||
@ -646,12 +646,12 @@ void sdio_slave_hal_recv_flush_one_buffer(sdio_slave_context_t *hal)
|
||||
//we only add it to the tail here, without start the DMA nor increase buffer num.
|
||||
}
|
||||
|
||||
void sdio_slave_hal_load_buf(sdio_slave_context_t *hal, lldesc_t *desc)
|
||||
void sdio_slave_hal_load_buf(sdio_slave_context_t *hal, sdio_slave_ll_desc_t *desc)
|
||||
{
|
||||
sdio_slave_hal_recv_stailq_t *const queue = &(hal->recv_link_list);
|
||||
desc->owner = 1;
|
||||
|
||||
lldesc_t *const tail = STAILQ_LAST(queue, lldesc_s, qe);
|
||||
sdio_slave_ll_desc_t *const tail = STAILQ_LAST(queue, sdio_slave_ll_desc_s, qe);
|
||||
|
||||
STAILQ_INSERT_TAIL(queue, desc, qe);
|
||||
if (hal->recv_cur_ret == NULL) {
|
||||
@ -671,7 +671,7 @@ void sdio_slave_hal_load_buf(sdio_slave_context_t *hal, lldesc_t *desc)
|
||||
sdio_slave_ll_recv_size_inc(hal->slc);
|
||||
}
|
||||
|
||||
static inline void show_queue_item(lldesc_t *item)
|
||||
static inline void show_queue_item(sdio_slave_ll_desc_t *item)
|
||||
{
|
||||
HAL_EARLY_LOGI(TAG, "=> %p: size: %d(%d), eof: %d, owner: %d", item, item->size, item->length, item->eof, item->owner);
|
||||
HAL_EARLY_LOGI(TAG, " buf: %p, stqe_next: %p", item->buf, item->qe.stqe_next);
|
||||
@ -680,7 +680,7 @@ static inline void show_queue_item(lldesc_t *item)
|
||||
static void __attribute((unused)) dump_queue(sdio_slave_hal_recv_stailq_t *queue)
|
||||
{
|
||||
int cnt = 0;
|
||||
lldesc_t *item = NULL;
|
||||
sdio_slave_ll_desc_t *item = NULL;
|
||||
HAL_EARLY_LOGI(TAG, ">>>>> first: %p, last: %p <<<<<", queue->stqh_first, queue->stqh_last);
|
||||
STAILQ_FOREACH(item, queue, qe) {
|
||||
cnt++;
|
||||
|
@ -1,19 +1,10 @@
|
||||
// Copyright 2015-2018 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef _SOC_SDIO_SLAVE_PINS_H_
|
||||
#define _SOC_SDIO_SLAVE_PINS_H_
|
||||
#pragma once
|
||||
|
||||
#define SDIO_SLAVE_SLOT0_IOMUX_PIN_NUM_CLK 6
|
||||
#define SDIO_SLAVE_SLOT0_IOMUX_PIN_NUM_CMD 11
|
||||
@ -30,5 +21,3 @@
|
||||
#define SDIO_SLAVE_SLOT1_IOMUX_PIN_NUM_D2 12
|
||||
#define SDIO_SLAVE_SLOT1_IOMUX_PIN_NUM_D3 13
|
||||
#define SDIO_SLAVE_SLOT1_FUNC 4
|
||||
|
||||
#endif /* _SOC_SDIO_SLAVE_PINS_H_ */
|
||||
|
@ -1,36 +1,23 @@
|
||||
// Copyright 2015-2018 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include "soc/sdio_slave_periph.h"
|
||||
#include "soc/gpio_periph.h"
|
||||
|
||||
// I/O slot of sdio slave:
|
||||
// 0: GPIO 6, 11, 7, 8, 9, 10,
|
||||
// 1: GPIO 14, 15, 2, 4, 12, 13 for CLK, CMD, D0, D1, D2, D3 respectively.
|
||||
// only one peripheral for SDIO and only one slot can work at the same time.
|
||||
// currently slot 0 is occupied by SPI for flash
|
||||
const sdio_slave_slot_info_t sdio_slave_slot_info[2] = {
|
||||
/**
|
||||
* I/O slot of sdio slave:
|
||||
* Slot 0: GPIO 6, 11, 7, 8, 9, 10.
|
||||
* Slot 1: GPIO 14, 15, 2, 4, 12, 13 for CLK, CMD, D0, D1, D2, D3 respectively.
|
||||
*
|
||||
* @note 1: Only one peripheral for SDIO and only one slot can work at the same time.
|
||||
* @note 2: Slot 0 is occupied by SPI for Flash, therefore we only use Slot 1
|
||||
*/
|
||||
const sdio_slave_slot_info_t sdio_slave_slot_info[1] = {
|
||||
{
|
||||
.clk_gpio = SDIO_SLAVE_SLOT0_IOMUX_PIN_NUM_CLK,
|
||||
.cmd_gpio = SDIO_SLAVE_SLOT0_IOMUX_PIN_NUM_CMD,
|
||||
.d0_gpio = SDIO_SLAVE_SLOT0_IOMUX_PIN_NUM_D0,
|
||||
.d1_gpio = SDIO_SLAVE_SLOT0_IOMUX_PIN_NUM_D1,
|
||||
.d2_gpio = SDIO_SLAVE_SLOT0_IOMUX_PIN_NUM_D2,
|
||||
.d3_gpio = SDIO_SLAVE_SLOT0_IOMUX_PIN_NUM_D3,
|
||||
.func = SDIO_SLAVE_SLOT0_FUNC,
|
||||
}, {
|
||||
.clk_gpio = SDIO_SLAVE_SLOT1_IOMUX_PIN_NUM_CLK,
|
||||
.cmd_gpio = SDIO_SLAVE_SLOT1_IOMUX_PIN_NUM_CMD,
|
||||
.d0_gpio = SDIO_SLAVE_SLOT1_IOMUX_PIN_NUM_D0,
|
||||
|
@ -16,7 +16,8 @@ set(srcs
|
||||
"uart_periph.c"
|
||||
"temperature_sensor_periph.c"
|
||||
"timer_periph.c"
|
||||
"twai_periph.c")
|
||||
"twai_periph.c"
|
||||
"sdio_slave_periph.c")
|
||||
|
||||
add_prefix(srcs "${CMAKE_CURRENT_LIST_DIR}/" "${srcs}")
|
||||
|
||||
|
@ -127,6 +127,10 @@ config SOC_SECURE_BOOT_SUPPORTED
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_SDIO_SLAVE_SUPPORTED
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_BOD_SUPPORTED
|
||||
bool
|
||||
default y
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -2654,7 +2654,7 @@ typedef union {
|
||||
} slchost_inf_st_reg_t;
|
||||
|
||||
|
||||
typedef struct slchost_dev_t {
|
||||
typedef struct host_dev_t {
|
||||
uint32_t reserved_000[4];
|
||||
volatile slchost_func2_0_reg_t func2_0;
|
||||
volatile slchost_func2_1_reg_t func2_1;
|
||||
@ -2725,12 +2725,12 @@ typedef struct slchost_dev_t {
|
||||
uint32_t reserved_180[28];
|
||||
volatile slchost_conf_reg_t conf;
|
||||
volatile slchost_inf_st_reg_t inf_st;
|
||||
} slchost_dev_t;
|
||||
} host_dev_t;
|
||||
|
||||
extern slchost_dev_t HOST;
|
||||
extern host_dev_t HOST;
|
||||
|
||||
#ifndef __cplusplus
|
||||
_Static_assert(sizeof(slchost_dev_t) == 0x1f8, "Invalid size of slchost_dev_t structure");
|
||||
_Static_assert(sizeof(host_dev_t) == 0x1f8, "Invalid size of host_dev_t structure");
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -33,6 +33,7 @@ typedef enum {
|
||||
PERIPH_ECC_MODULE,
|
||||
PERIPH_HMAC_MODULE,
|
||||
PERIPH_DS_MODULE,
|
||||
PERIPH_SDIO_SLAVE_MODULE,
|
||||
PERIPH_GDMA_MODULE,
|
||||
PERIPH_MCPWM0_MODULE,
|
||||
PERIPH_ETM_MODULE,
|
||||
|
14
components/soc/esp32c6/include/soc/sdio_slave_pins.h
Normal file
14
components/soc/esp32c6/include/soc/sdio_slave_pins.h
Normal file
@ -0,0 +1,14 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#define SDIO_SLAVE_SLOT0_IOMUX_PIN_NUM_CMD 18
|
||||
#define SDIO_SLAVE_SLOT0_IOMUX_PIN_NUM_CLK 19
|
||||
#define SDIO_SLAVE_SLOT0_IOMUX_PIN_NUM_D0 20
|
||||
#define SDIO_SLAVE_SLOT0_IOMUX_PIN_NUM_D1 21
|
||||
#define SDIO_SLAVE_SLOT0_IOMUX_PIN_NUM_D2 22
|
||||
#define SDIO_SLAVE_SLOT0_IOMUX_PIN_NUM_D3 23
|
||||
#define SDIO_SLAVE_SLOT0_FUNC 0
|
@ -60,6 +60,7 @@
|
||||
#define SOC_ECC_SUPPORTED 1
|
||||
#define SOC_FLASH_ENC_SUPPORTED 1
|
||||
#define SOC_SECURE_BOOT_SUPPORTED 1
|
||||
#define SOC_SDIO_SLAVE_SUPPORTED 1
|
||||
#define SOC_BOD_SUPPORTED 1
|
||||
#define SOC_APM_SUPPORTED 1
|
||||
|
||||
|
20
components/soc/esp32c6/sdio_slave_periph.c
Normal file
20
components/soc/esp32c6/sdio_slave_periph.c
Normal file
@ -0,0 +1,20 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <stdint.h>
|
||||
#include "soc/sdio_slave_periph.h"
|
||||
#include "soc/sdio_slave_pins.h"
|
||||
|
||||
const sdio_slave_slot_info_t sdio_slave_slot_info[1] = {
|
||||
{
|
||||
.clk_gpio = SDIO_SLAVE_SLOT0_IOMUX_PIN_NUM_CLK,
|
||||
.cmd_gpio = SDIO_SLAVE_SLOT0_IOMUX_PIN_NUM_CMD,
|
||||
.d0_gpio = SDIO_SLAVE_SLOT0_IOMUX_PIN_NUM_D0,
|
||||
.d1_gpio = SDIO_SLAVE_SLOT0_IOMUX_PIN_NUM_D1,
|
||||
.d2_gpio = SDIO_SLAVE_SLOT0_IOMUX_PIN_NUM_D2,
|
||||
.d3_gpio = SDIO_SLAVE_SLOT0_IOMUX_PIN_NUM_D3,
|
||||
.func = SDIO_SLAVE_SLOT0_FUNC,
|
||||
},
|
||||
};
|
@ -1,34 +0,0 @@
|
||||
// Copyright 2015-2018 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef _SOC_SDIO_SLAVE_PINS_H_
|
||||
#define _SOC_SDIO_SLAVE_PINS_H_
|
||||
|
||||
#define SDIO_SLAVE_SLOT0_IOMUX_PIN_NUM_CLK 12
|
||||
#define SDIO_SLAVE_SLOT0_IOMUX_PIN_NUM_CMD 11
|
||||
#define SDIO_SLAVE_SLOT0_IOMUX_PIN_NUM_D0 13
|
||||
#define SDIO_SLAVE_SLOT0_IOMUX_PIN_NUM_D1 14
|
||||
#define SDIO_SLAVE_SLOT0_IOMUX_PIN_NUM_D2 9
|
||||
#define SDIO_SLAVE_SLOT0_IOMUX_PIN_NUM_D3 10
|
||||
#define SDIO_SLAVE_SLOT0_FUNC 0
|
||||
|
||||
#define SDIO_SLAVE_SLOT1_IOMUX_PIN_NUM_CLK 36
|
||||
#define SDIO_SLAVE_SLOT1_IOMUX_PIN_NUM_CMD 35
|
||||
#define SDIO_SLAVE_SLOT1_IOMUX_PIN_NUM_D0 37
|
||||
#define SDIO_SLAVE_SLOT1_IOMUX_PIN_NUM_D1 38
|
||||
#define SDIO_SLAVE_SLOT1_IOMUX_PIN_NUM_D2 33
|
||||
#define SDIO_SLAVE_SLOT1_IOMUX_PIN_NUM_D3 34
|
||||
#define SDIO_SLAVE_SLOT1_FUNC 3
|
||||
|
||||
#endif /* _SOC_SDIO_SLAVE_PINS_H_ */
|
@ -13,7 +13,6 @@ set(srcs
|
||||
"pcnt_periph.c"
|
||||
"rmt_periph.c"
|
||||
"rtc_io_periph.c"
|
||||
"sdio_slave_periph.c"
|
||||
"sdmmc_periph.c"
|
||||
"spi_periph.c"
|
||||
"temperature_sensor_periph.c"
|
||||
|
@ -1,31 +0,0 @@
|
||||
// Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#pragma once
|
||||
|
||||
#define SDIO_SLAVE_SLOT0_IOMUX_PIN_NUM_CLK 6
|
||||
#define SDIO_SLAVE_SLOT0_IOMUX_PIN_NUM_CMD 11
|
||||
#define SDIO_SLAVE_SLOT0_IOMUX_PIN_NUM_D0 7
|
||||
#define SDIO_SLAVE_SLOT0_IOMUX_PIN_NUM_D1 8
|
||||
#define SDIO_SLAVE_SLOT0_IOMUX_PIN_NUM_D2 9
|
||||
#define SDIO_SLAVE_SLOT0_IOMUX_PIN_NUM_D3 10
|
||||
#define SDIO_SLAVE_SLOT0_FUNC 0
|
||||
|
||||
#define SDIO_SLAVE_SLOT1_IOMUX_PIN_NUM_CLK 14
|
||||
#define SDIO_SLAVE_SLOT1_IOMUX_PIN_NUM_CMD 15
|
||||
#define SDIO_SLAVE_SLOT1_IOMUX_PIN_NUM_D0 2
|
||||
#define SDIO_SLAVE_SLOT1_IOMUX_PIN_NUM_D1 4
|
||||
#define SDIO_SLAVE_SLOT1_IOMUX_PIN_NUM_D2 12
|
||||
#define SDIO_SLAVE_SLOT1_IOMUX_PIN_NUM_D3 13
|
||||
#define SDIO_SLAVE_SLOT1_FUNC 4
|
@ -15,6 +15,5 @@
|
||||
#include "soc/usb_pins.h"
|
||||
#include "soc/gpio_pins.h"
|
||||
#include "soc/spi_pins.h"
|
||||
#include "soc/sdio_slave_pins.h"
|
||||
#include "soc/sdmmc_pins.h"
|
||||
#include "soc/touch_sensor_pins.h"
|
||||
|
@ -1,42 +0,0 @@
|
||||
// Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <stdint.h>
|
||||
#include "soc/sdio_slave_periph.h"
|
||||
#include "soc/gpio_periph.h"
|
||||
|
||||
// I/O slot of sdio slave:
|
||||
// 0: GPIO 6, 11, 7, 8, 9, 10,
|
||||
// 1: GPIO 14, 15, 2, 4, 12, 13 for CLK, CMD, D0, D1, D2, D3 respectively.
|
||||
// only one peripheral for SDIO and only one slot can work at the same time.
|
||||
// currently slot 0 is occupied by SPI for flash
|
||||
const sdio_slave_slot_info_t sdio_slave_slot_info[2] = {
|
||||
{
|
||||
.clk_gpio = SDIO_SLAVE_SLOT0_IOMUX_PIN_NUM_CLK,
|
||||
.cmd_gpio = SDIO_SLAVE_SLOT0_IOMUX_PIN_NUM_CMD,
|
||||
.d0_gpio = SDIO_SLAVE_SLOT0_IOMUX_PIN_NUM_D0,
|
||||
.d1_gpio = SDIO_SLAVE_SLOT0_IOMUX_PIN_NUM_D1,
|
||||
.d2_gpio = SDIO_SLAVE_SLOT0_IOMUX_PIN_NUM_D2,
|
||||
.d3_gpio = SDIO_SLAVE_SLOT0_IOMUX_PIN_NUM_D3,
|
||||
.func = SDIO_SLAVE_SLOT0_FUNC,
|
||||
}, {
|
||||
.clk_gpio = SDIO_SLAVE_SLOT1_IOMUX_PIN_NUM_CLK,
|
||||
.cmd_gpio = SDIO_SLAVE_SLOT1_IOMUX_PIN_NUM_CMD,
|
||||
.d0_gpio = SDIO_SLAVE_SLOT1_IOMUX_PIN_NUM_D0,
|
||||
.d1_gpio = SDIO_SLAVE_SLOT1_IOMUX_PIN_NUM_D1,
|
||||
.d2_gpio = SDIO_SLAVE_SLOT1_IOMUX_PIN_NUM_D2,
|
||||
.d3_gpio = SDIO_SLAVE_SLOT1_IOMUX_PIN_NUM_D3,
|
||||
.func = SDIO_SLAVE_SLOT1_FUNC,
|
||||
},
|
||||
};
|
@ -65,8 +65,7 @@ WIFI_MESH_DOCS = ['api-guides/esp-wifi-mesh.rst',
|
||||
|
||||
COEXISTENCE_DOCS = ['api-guides/coexist.rst']
|
||||
|
||||
SDMMC_DOCS = ['api-reference/peripherals/sdmmc_host.rst',
|
||||
'api-reference/peripherals/sd_pullup_requirements.rst']
|
||||
SDMMC_DOCS = ['api-reference/peripherals/sdmmc_host.rst']
|
||||
|
||||
SDIO_SLAVE_DOCS = ['api-reference/peripherals/sdio_slave.rst',
|
||||
'api-reference/protocols/esp_sdio_slave_protocol.rst']
|
||||
@ -130,6 +129,7 @@ ESP32_DOCS = ['api-reference/system/himem.rst',
|
||||
'security/secure-boot-v1.rst',
|
||||
'api-reference/peripherals/secure_element.rst',
|
||||
'api-reference/peripherals/dac.rst',
|
||||
'api-reference/peripherals/sd_pullup_requirements.rst',
|
||||
'hw-reference/esp32/**',
|
||||
'api-guides/RF_calibration.rst'] + FTDI_JTAG_DOCS
|
||||
|
||||
@ -145,6 +145,7 @@ ESP32S2_DOCS = ['hw-reference/esp32s2/**',
|
||||
ESP32S3_DOCS = ['hw-reference/esp32s3/**',
|
||||
'api-reference/system/ipc.rst',
|
||||
'api-guides/flash_psram_config.rst',
|
||||
'api-reference/peripherals/sd_pullup_requirements.rst',
|
||||
'api-guides/RF_calibration.rst']
|
||||
|
||||
# No JTAG docs for this one as it gets gated on SOC_USB_SERIAL_JTAG_SUPPORTED down below.
|
||||
@ -153,7 +154,8 @@ ESP32C3_DOCS = ['hw-reference/esp32c3/**',
|
||||
|
||||
ESP32C2_DOCS = ['api-guides/RF_calibration.rst']
|
||||
|
||||
ESP32C6_DOCS = ['api-guides/RF_calibration.rst']
|
||||
ESP32C6_DOCS = ['api-guides/RF_calibration.rst',
|
||||
'api-reference/peripherals/sd_pullup_requirements.rst']
|
||||
|
||||
# format: {tag needed to include: documents to included}, tags are parsed from sdkconfig and peripheral_caps.h headers
|
||||
conditional_include_dict = {'SOC_BT_SUPPORTED':BT_DOCS,
|
||||
|
@ -96,7 +96,6 @@ api-reference/peripherals/sdio_slave
|
||||
api-reference/peripherals/touch_pad
|
||||
api-reference/peripherals/adc_calibration
|
||||
api-reference/peripherals/ds
|
||||
api-reference/peripherals/sd_pullup_requirements
|
||||
api-reference/peripherals/index
|
||||
api-reference/peripherals/sdmmc_host
|
||||
api-reference/kconfig
|
||||
@ -178,7 +177,6 @@ api-reference/error-codes
|
||||
api-reference/index
|
||||
api-reference/protocols
|
||||
api-reference/protocols/esp_serial_slave_link
|
||||
api-reference/protocols/esp_sdio_slave_protocol
|
||||
api-reference/protocols/esp_spi_slave_protocol
|
||||
api-reference/protocols/index
|
||||
security
|
||||
|
@ -24,7 +24,9 @@ Peripherals API
|
||||
:SOC_MCPWM_SUPPORTED: mcpwm
|
||||
:SOC_PCNT_SUPPORTED: pcnt
|
||||
:SOC_RMT_SUPPORTED: rmt
|
||||
:SOC_SDMMC_HOST_SUPPORTED: sd_pullup_requirements
|
||||
:esp32: sd_pullup_requirements
|
||||
:esp32s3: sd_pullup_requirements
|
||||
:esp32c6: sd_pullup_requirements
|
||||
:SOC_SDMMC_HOST_SUPPORTED: sdmmc_host
|
||||
sdspi_host
|
||||
:SOC_SDIO_SLAVE_SUPPORTED: sdio_slave
|
||||
|
@ -4,35 +4,57 @@ SDIO Card Slave Driver
|
||||
Overview
|
||||
--------
|
||||
|
||||
.. only:: esp32
|
||||
|
||||
The ESP32 SDIO Card peripherals (Host, Slave) shares two sets of pins as below table.
|
||||
The first set is usually occupied by SPI0 bus which is responsible for the SPI flash holding the code to run.
|
||||
This means SDIO slave driver can only runs on the second set of pins while SDIO host is not using it.
|
||||
|
||||
The SDIO slave can run under 3 modes: SPI, 1-bit SD and 4-bit SD modes, which
|
||||
is detected automatically by the hardware. According to the SDIO
|
||||
specification, CMD and DAT0-3 lines should be pulled up no matter in 1-bit,
|
||||
4-bit or SPI mode.
|
||||
The SDIO slave can run under 3 modes: SPI, 1-bit SD and 4-bit SD modes, which
|
||||
is detected automatically by the hardware. According to the SDIO
|
||||
specification, CMD and DAT0-3 lines should be pulled up no matter in 1-bit,
|
||||
4-bit or SPI mode.
|
||||
|
||||
Connections
|
||||
^^^^^^^^^^^
|
||||
|
||||
+----------+---------------+-------+-------+
|
||||
| Pin Name | Corresponding | Slot1 | Slot2 |
|
||||
+ + pins in SPI +-------+-------+
|
||||
| | mode | GPIO Number |
|
||||
+==========+===============+=======+=======+
|
||||
| CLK | SCLK | 6 | 14 |
|
||||
+----------+---------------+-------+-------+
|
||||
| CMD | MOSI | 11 | 15 |
|
||||
+----------+---------------+-------+-------+
|
||||
| DAT0 | MISO | 7 | 2 |
|
||||
+----------+---------------+-------+-------+
|
||||
| DAT1 | Interrupt | 8 | 4 |
|
||||
+----------+---------------+-------+-------+
|
||||
| DAT2 | N.C. (pullup) | 9 | 12 |
|
||||
+----------+---------------+-------+-------+
|
||||
| DAT3 | #CS | 10 | 13 |
|
||||
+----------+---------------+-------+-------+
|
||||
.. only:: esp32
|
||||
|
||||
+----------+---------------+-------+-------+
|
||||
| Pin Name | Corresponding | Slot1 | Slot2 |
|
||||
+ + pins in SPI +-------+-------+
|
||||
| | mode | GPIO Number |
|
||||
+==========+===============+=======+=======+
|
||||
| CLK | SCLK | 6 | 14 |
|
||||
+----------+---------------+-------+-------+
|
||||
| CMD | MOSI | 11 | 15 |
|
||||
+----------+---------------+-------+-------+
|
||||
| DAT0 | MISO | 7 | 2 |
|
||||
+----------+---------------+-------+-------+
|
||||
| DAT1 | Interrupt | 8 | 4 |
|
||||
+----------+---------------+-------+-------+
|
||||
| DAT2 | N.C. (pullup) | 9 | 12 |
|
||||
+----------+---------------+-------+-------+
|
||||
| DAT3 | #CS | 10 | 13 |
|
||||
+----------+---------------+-------+-------+
|
||||
|
||||
.. only:: esp32c6
|
||||
|
||||
+----------+--------------------------------+---------------+
|
||||
| Pin Name | Corresponding pins in SPI mode | GPIO Number |
|
||||
+==========+================================+===============+
|
||||
| CLK | SCLK | 19 |
|
||||
+----------+--------------------------------+---------------+
|
||||
| CMD | MOSI | 18 |
|
||||
+----------+--------------------------------+---------------+
|
||||
| DAT0 | MISO | 20 |
|
||||
+----------+--------------------------------+---------------+
|
||||
| DAT1 | Interrupt | 21 |
|
||||
+----------+--------------------------------+---------------+
|
||||
| DAT2 | N.C. (pullup) | 22 |
|
||||
+----------+--------------------------------+---------------+
|
||||
| DAT3 | #CS | 23 |
|
||||
+----------+--------------------------------+---------------+
|
||||
|
||||
- 1-bit SD mode: Connect CLK, CMD, DAT0, DAT1 pins and the ground.
|
||||
- 4-bit SD mode: Connect all pins and the ground.
|
||||
@ -45,23 +67,25 @@ Connections
|
||||
:ref:`compatibility_overview_espressif_hw_sdio` to see whether your
|
||||
development boards have such pullups.
|
||||
|
||||
.. note:: Most official modules have conflicts on strapping pins with the
|
||||
SDIO slave function. If you are using a ESP32 module with 3.3 V flash
|
||||
inside, you have to burn the EFUSE when you are developing on the module
|
||||
for the first time. See :ref:`compatibility_overview_espressif_hw_sdio` to
|
||||
see how to make your modules compatible with the SDIO.
|
||||
.. only:: esp32
|
||||
|
||||
Here is a list for modules/kits with 3.3 V flash:
|
||||
.. note:: Most official modules have conflicts on strapping pins with the
|
||||
SDIO slave function. If you are using a ESP32 module with 3.3 V flash
|
||||
inside, you have to burn the EFUSE when you are developing on the module
|
||||
for the first time. See :ref:`compatibility_overview_espressif_hw_sdio` to
|
||||
see how to make your modules compatible with the SDIO.
|
||||
|
||||
- Modules: ESP32-PICO-D4, ESP32-WROOM-32 series (including ESP32-SOLO-1),
|
||||
ESP32-WROVER-B and ESP32-WROVER-IB
|
||||
- Kits: ESP32-PICO-KIT, ESP32-DevKitC (till v4), ESP32-WROVER-KIT
|
||||
(v4.1 (also known as ESP32-WROVER-KIT-VB), v2, v1 (also known as DevKitJ
|
||||
v1))
|
||||
Here is a list for modules/kits with 3.3 V flash:
|
||||
|
||||
You can tell the version of your ESP23-WROVER-KIT version from the module
|
||||
on it: v4.1 are with ESP32-WROVER-B modules, v3 are with ESP32-WROVER
|
||||
modules, while v2 and v1 are with ESP32-WROOM-32 modules.
|
||||
- Modules: ESP32-PICO-D4, ESP32-WROOM-32 series (including ESP32-SOLO-1),
|
||||
ESP32-WROVER-B and ESP32-WROVER-IB
|
||||
- Kits: ESP32-PICO-KIT, ESP32-DevKitC (till v4), ESP32-WROVER-KIT
|
||||
(v4.1 (also known as ESP32-WROVER-KIT-VB), v2, v1 (also known as DevKitJ
|
||||
v1))
|
||||
|
||||
You can tell the version of your ESP23-WROVER-KIT version from the module
|
||||
on it: v4.1 are with ESP32-WROVER-B modules, v3 are with ESP32-WROVER
|
||||
modules, while v2 and v1 are with ESP32-WROOM-32 modules.
|
||||
|
||||
Refer to :doc:`sd_pullup_requirements` for more technical details of the pullups.
|
||||
|
||||
@ -90,7 +114,7 @@ Terminology
|
||||
The SDIO slave driver uses the following terms:
|
||||
|
||||
- Transfer: a transfer is always started by a command token from the host, and may contain a reply and several data
|
||||
blocks. ESP32 slave software is based on transfers.
|
||||
blocks. {IDF_TARGET_NAME} SDIO slave software is based on transfers.
|
||||
- Sending: slave to host transfers.
|
||||
- Receiving: host to slave transfers.
|
||||
|
||||
@ -109,29 +133,29 @@ The SDIO slave driver uses the following terms:
|
||||
- Requested length: The length requested in one transfer determined by the FIFO address.
|
||||
- Transfer length: The length requested in one transfer determined by the CMD53 byte/block count field.
|
||||
|
||||
.. note:: Requested length is different from the transfer length. ESP32 slave DMA base on the *requested length* rather
|
||||
.. note:: Requested length is different from the transfer length. {IDF_TARGET_NAME} SDIO slave DMA base on the *requested length* rather
|
||||
than the *transfer length*. The *transfer length* should be no shorter than the *requested length*, and the rest
|
||||
part will be filled with 0 (sending) or discard (receiving).
|
||||
|
||||
- Receiving buffer size: The buffer size is pre-defined between the host and the slave before communication starts.
|
||||
Slave application has to set the buffer size during initialization by the ``recv_buffer_size`` member of
|
||||
``sdio_slave_config_t``.
|
||||
- Interrupts: the esp32 slave support interrupts in two directions: from host to slave (called slave interrupts below)
|
||||
- Interrupts: the {IDF_TARGET_NAME} SDIO slave support interrupts in two directions: from host to slave (called slave interrupts below)
|
||||
and from slave to host (called host interrupts below). See more in :ref:`interrupts`.
|
||||
- Registers: specific address in Function 1 access by CMD52 or CMD53.
|
||||
|
||||
Communication with ESP SDIO Slave
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The host should initialize the ESP32 SDIO slave according to the standard
|
||||
The host should initialize the {IDF_TARGET_NAME} SDIO slave according to the standard
|
||||
SDIO initialization process (Sector 3.1.2 of `SDIO Simplified
|
||||
Specification <https://www.sdcard.org/downloads/pls/>`_), which is described
|
||||
briefly in :ref:`esp_slave_init`.
|
||||
|
||||
Furthermore, there's an ESP32-specific upper-level communication protocol upon the CMD52/CMD53 to
|
||||
Furthermore, there's an {IDF_TARGET_NAME}-specific upper-level communication protocol upon the CMD52/CMD53 to
|
||||
Func 1. Please refer to :ref:`esp_slave_protocol_layer`. There is also a component
|
||||
:doc:`ESP Serial Slave Link </api-reference/protocols/esp_serial_slave_link>`
|
||||
for ESP32 master to communicate with ESP32 SDIO slave, see example :example:`peripherals/sdio`
|
||||
for {IDF_TARGET_NAME} master to communicate with {IDF_TARGET_NAME} SDIO slave, see example :example:`peripherals/sdio`
|
||||
when programming your host.
|
||||
|
||||
|
||||
@ -222,7 +246,7 @@ following functions instead:
|
||||
If non-blocking call is needed, set ``wait=0``. If the ``wait`` is not ``portMAX_DELAY`` (wait until success),
|
||||
application has to check the result to know whether the data is put in to the queue or discard.
|
||||
|
||||
2. Call ``sdio_slave_send_get_finished`` to get and deal with a finished transfer. A buffer should be keep unmodified
|
||||
2. Call ``sdio_slave_send_get_finished`` to get and deal with a finished transfer. A buffer should be kept unmodified
|
||||
until returned from ``sdio_slave_send_get_finished``. This means the buffer is actually sent to the host, rather
|
||||
than just staying in the queue.
|
||||
|
||||
@ -281,5 +305,3 @@ API Reference
|
||||
|
||||
.. include-build-file:: inc/sdio_slave_types.inc
|
||||
.. include-build-file:: inc/sdio_slave.inc
|
||||
|
||||
|
||||
|
@ -39,7 +39,7 @@ The services provided by the SDIO Slave peripheral of the {IDF_TARGET_NAME} chip
|
||||
ESP SDIO Slave Initialization
|
||||
-----------------------------
|
||||
|
||||
The host should initialize the ESP32 SDIO slave according to the standard SDIO initialization process (Section 3.1.2 of `SDIO Simplified Specification <https://www.sdcard.org/downloads/pls/>`_). In this specification as well as below, the SDIO slave is called an (SD)IO card. Here is a brief example of an ESP SDIO Slave initialization process:
|
||||
The host should initialize the {IDF_TARGET_NAME} SDIO slave according to the standard SDIO initialization process (Section 3.1.2 of `SDIO Simplified Specification <https://www.sdcard.org/downloads/pls/>`_). In this specification as well as below, the SDIO slave is called an (SD)IO card. Here is a brief example of an ESP SDIO Slave initialization process:
|
||||
|
||||
1. SDIO reset
|
||||
CMD52 (Write 0x6=0x8)
|
||||
@ -171,7 +171,7 @@ Interrupts
|
||||
|
||||
SDIO interrupts are "level sensitive". For host interrupts, the slave sends an interrupt by pulling the DAT1 line down at a proper time. The host detects when the interrupt line is pulled down and reads the INT_ST register to determine the source of the interrupt. After that, the host can clear the interrupt bits by writing the INT_CLR register and process the interrupt. The host can also mask unneeded sources by clearing the bits in the INT_ENA register corresponding to the sources. If all the sources are cleared (or masked), the DAT1 line goes inactive.
|
||||
|
||||
On ESP32, the corresponding host_int bits are: bit 0 to bit 7.
|
||||
On {IDF_TARGET_NAME}, the corresponding host_int bits are: bit 0 to bit 7.
|
||||
|
||||
For slave interrupts, the host sends a transfer to write the SLAVE_INT register. Once a bit is set to 1, the slave hardware and the driver will detect it and inform the application.
|
||||
|
||||
@ -199,4 +199,3 @@ To read the slave's sending FIFO, the host should complete the following steps:
|
||||
3. **If new packets are ready, read the PKT_LEN register**. Before reading the packets, determine the length of data to be read. As the host keeps the length of data already read from the slave, subtract this value from PKT_LEN, the result will be the maximum length of data available for reading. If no data has been added to the sending FIFO yet, wait and poll until the slave is ready and update PKT_LEN.
|
||||
4. **Read from the FIFO using CMD53**. Note that the *requested length* should not be greater than calculated at Step 3, and the FIFO address is related to *requested length*.
|
||||
5. **Update the read length**.
|
||||
|
||||
|
@ -26,22 +26,28 @@ Please run wires between the slave and master to make the example function, and
|
||||
|
||||
### Slave
|
||||
|
||||
On ESP32, the pins of SDIO Slave are fixed:
|
||||
On ESP32 / ESP32C6, the pins of SDIO Slave are fixed:
|
||||
|
||||
| Signal | GPIO NUM |
|
||||
|--------|----------|
|
||||
| CLK | GPIO-14 |
|
||||
| CMD | GPIO-15 |
|
||||
| DAT0 | GPIO-2 |
|
||||
| DAT1 | GPIO-4 |
|
||||
| DAT2 | GPIO-12 |
|
||||
| DAT3 | GPIO-13 |
|
||||
| | ESP32 | ESP32C6 |
|
||||
|--------|----------|----------|
|
||||
| Signal | GPIO NUM | GPIO NUM |
|
||||
|--------|----------|----------|
|
||||
| CLK | GPIO-14 | GPIO-19 |
|
||||
| CMD | GPIO-15 | GPIO-18 |
|
||||
| DAT0 | GPIO-2 | GPIO-20 |
|
||||
| DAT1 | GPIO-4 | GPIO-21 |
|
||||
| DAT2 | GPIO-12 | GPIO-22 |
|
||||
| DAT3 | GPIO-13 | GPIO-23 |
|
||||
|
||||
#### Note
|
||||
|
||||
The SD peripheral works at a high frequency
|
||||
and uses native pins, there's no way to configure it to other pins through
|
||||
the GPIO matrix.
|
||||
|
||||
Be aware that these pins are normally reserved for JTAG on ESP32. If you're
|
||||
using a board with JTAG functions, please remember to remove jumpers
|
||||
connecting to the JTAG adapter. The SD peripheral works at a high frequency
|
||||
and uses native pins, there's no way to configure it to other pins through
|
||||
the GPIO matrix.
|
||||
connecting to the JTAG adapter. (ESP32 Only).
|
||||
|
||||
### Host
|
||||
|
||||
@ -72,11 +78,18 @@ please try:
|
||||
|
||||
## Board compatibility
|
||||
|
||||
1. If you're using a board (e.g. WroverKit v2 and before, PICO, DevKitC)
|
||||
Pull-up resistors is needed. As the SD specification and the eMMC datasheet clarify,
|
||||
minimum 10k pull-up resistors are required for the bus IOs to protect the IOs against bus floating issue.
|
||||
Note these pull-up resistors are needed, even if the pin is not used (For example,
|
||||
you use 1-line-mode, the pull-up resistor is still required for the D1 pin).
|
||||
|
||||
Some other notes:
|
||||
|
||||
1. (ESP32 Only) If you're using a board (e.g. WroverKit v2 and before, PICO, DevKitC)
|
||||
which is not able to drive GPIO2 low on downloading, please remember to
|
||||
disconnect GPIO2 between two boards when downloading the application.
|
||||
|
||||
2. It is suggested to use the official Wrover Kit as the slave. This is
|
||||
2. (ESP32 Only) It is suggested to use the official Wrover Kit as the slave. This is
|
||||
because Wrover Kits have pullups on CMD, DAT0 and DAT1. Otherwise you'll have
|
||||
to connect the pullups manually (or use the Wrover Kit as the host). However,
|
||||
due to a PCB issue, Wrover Kits v3 and earlier have pullup v.s. pulldown
|
||||
@ -92,7 +105,7 @@ please try:
|
||||
DAT0 and DAT1 and DAT3 lines. However please don't rely on internal weak
|
||||
pullups in your own design.
|
||||
|
||||
3. Moreover, if your slave devkit is using code flash of 3.3V, it is required
|
||||
3. (ESP32 Only) Moreover, if your slave devkit is using code flash of 3.3V, it is required
|
||||
to pull down DAT2 line to set proper flash voltage. This conflicts with SDIO
|
||||
pullup requirements. Currently devkits using PICO-D4 and Wroom-32 series
|
||||
modules have this problem. You can either:
|
||||
|
@ -1,4 +1,4 @@
|
||||
| Supported Targets | ESP32 |
|
||||
| ----------------- | ----- |
|
||||
| Supported Targets | ESP32 | ESP32-C6 |
|
||||
| ----------------- | ----- | -------- |
|
||||
|
||||
See README.md in the parent folder
|
||||
|
@ -863,7 +863,6 @@ components/soc/esp32/include/soc/rtc_cntl_struct.h
|
||||
components/soc/esp32/include/soc/rtc_i2c_reg.h
|
||||
components/soc/esp32/include/soc/rtc_io_reg.h
|
||||
components/soc/esp32/include/soc/rtc_io_struct.h
|
||||
components/soc/esp32/include/soc/sdio_slave_pins.h
|
||||
components/soc/esp32/include/soc/sdmmc_pins.h
|
||||
components/soc/esp32/include/soc/sdmmc_reg.h
|
||||
components/soc/esp32/include/soc/sens_reg.h
|
||||
@ -885,7 +884,6 @@ components/soc/esp32/include/soc/uhci_reg.h
|
||||
components/soc/esp32/include/soc/uhci_struct.h
|
||||
components/soc/esp32/include/soc/wdev_reg.h
|
||||
components/soc/esp32/ledc_periph.c
|
||||
components/soc/esp32/sdio_slave_periph.c
|
||||
components/soc/esp32/sdmmc_periph.c
|
||||
components/soc/esp32/spi_periph.c
|
||||
components/soc/esp32/uart_periph.c
|
||||
|
Loading…
Reference in New Issue
Block a user