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