fix(sdio_slave): improve sdio slave for high speed and 4 bit mode

This commit is contained in:
michael 2018-07-04 20:37:30 +08:00
parent 823ebba0f0
commit 597eda5f0b
3 changed files with 23 additions and 20 deletions

View file

@ -47,10 +47,12 @@ typedef enum {
/// Timing of SDIO slave
typedef enum {
SDIO_SLAVE_TIMING_NSEND_PSAMPLE = 0,///< Send at negedge, and sample at posedge. Default value for SD protocol.
SDIO_SLAVE_TIMING_NSEND_NSAMPLE, ///< Send at negedge, and sample at negedge
SDIO_SLAVE_TIMING_PSEND_PSAMPLE, ///< Send at posedge, and sample at posedge
SDIO_SLAVE_TIMING_PSEND_PSAMPLE = 0,/**< Send at posedge, and sample at posedge. Default value for HS mode.
* Normally there's no problem using this to work in DS mode.
*/
SDIO_SLAVE_TIMING_NSEND_PSAMPLE ,///< Send at negedge, and sample at posedge. Default value for DS mode and below.
SDIO_SLAVE_TIMING_PSEND_NSAMPLE, ///< Send at posedge, and sample at negedge
SDIO_SLAVE_TIMING_NSEND_NSAMPLE, ///< Send at negedge, and sample at negedge
} sdio_slave_timing_t;
/// Configuration of SDIO slave mode

View file

@ -472,9 +472,9 @@ static void configure_pin(int pin, uint32_t func, bool pullup)
PIN_INPUT_ENABLE(reg);
PIN_FUNC_SELECT(reg, sdmmc_func);
PIN_SET_DRV(reg, drive_strength);
gpio_pulldown_dis(pin);
if (pullup) {
gpio_pullup_en(pin);
gpio_pulldown_dis(pin);
}
}
@ -516,28 +516,28 @@ static inline esp_err_t sdio_slave_hw_init(sdio_slave_config_t *config)
switch(config->timing) {
case SDIO_SLAVE_TIMING_PSEND_PSAMPLE:
HOST.conf.frc_sdio20 = 0xf;
HOST.conf.frc_sdio20 = 0x1f;
HOST.conf.frc_sdio11 = 0;
HOST.conf.frc_pos_samp = 0xf;
HOST.conf.frc_pos_samp = 0x1f;
HOST.conf.frc_neg_samp = 0;
break;
case SDIO_SLAVE_TIMING_PSEND_NSAMPLE:
HOST.conf.frc_sdio20 = 0xf;
HOST.conf.frc_sdio20 = 0x1f;
HOST.conf.frc_sdio11 = 0;
HOST.conf.frc_pos_samp = 0;
HOST.conf.frc_neg_samp = 0xf;
HOST.conf.frc_neg_samp = 0x1f;
break;
case SDIO_SLAVE_TIMING_NSEND_PSAMPLE:
HOST.conf.frc_sdio20 = 0;
HOST.conf.frc_sdio11 = 0xf;
HOST.conf.frc_pos_samp = 0xf;
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 = 0xf;
HOST.conf.frc_sdio11 = 0x1f;
HOST.conf.frc_pos_samp = 0;
HOST.conf.frc_neg_samp = 0xf;
HOST.conf.frc_neg_samp = 0x1f;
break;
}

View file

@ -152,7 +152,7 @@ esp_err_t slave_init(esp_slave_context_t *context)
#ifdef CONFIG_SDIO_EXAMPLE_HIGHSPEED
config.max_freq_khz = SDMMC_FREQ_HIGHSPEED;
#else
config.max_freq_khz = SDMMC_FREQ_PROBING;
config.max_freq_khz = SDMMC_FREQ_DEFAULT;
#endif
sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT();
@ -209,14 +209,15 @@ void slave_power_on()
};
gpio_config(&cfg);
gpio_set_level(SLAVE_PWR_GPIO, 0); //low active
vTaskDelay(100);
#endif
}
DMA_ATTR uint8_t rcv_buffer[READ_BUFFER_LEN];
//try to get an interrupt from the slave and handle it, return if none.
esp_err_t process_event(esp_slave_context_t *context)
{
uint8_t buffer[READ_BUFFER_LEN];
esp_err_t ret = esp_slave_wait_int(context, 0);
if (ret == ESP_ERR_TIMEOUT) {
return ret;
@ -241,7 +242,7 @@ esp_err_t process_event(esp_slave_context_t *context)
ESP_LOGD(TAG, "new packet coming");
while (1) {
size_t size_read = READ_BUFFER_LEN;
ret = esp_slave_get_packet(context, buffer, READ_BUFFER_LEN, &size_read, wait_ms);
ret = esp_slave_get_packet(context, rcv_buffer, READ_BUFFER_LEN, &size_read, wait_ms);
if (ret == ESP_ERR_NOT_FOUND) {
ESP_LOGE(TAG, "interrupt but no data can be read");
break;
@ -251,7 +252,7 @@ esp_err_t process_event(esp_slave_context_t *context)
}
ESP_LOGI(TAG, "receive data, size: %d", size_read);
ESP_LOG_BUFFER_HEXDUMP(TAG, buffer, size_read, ESP_LOG_INFO);
ESP_LOG_BUFFER_HEXDUMP(TAG, rcv_buffer, size_read, ESP_LOG_INFO);
if (ret == ESP_OK) {
break;
}
@ -297,13 +298,13 @@ void job_write_reg(esp_slave_context_t *context, int value)
//use 1+1+1+1+4+4=12 packets, 513 and 517 not sent
int packet_len[] = {3, 6, 12, 128, 511, 512, 513, 517};
//the sending buffer should be word aligned
DMA_ATTR uint8_t buffer[1024];
DMA_ATTR uint8_t send_buffer[READ_BUFFER_LEN];
//send packets to the slave (they will return and be handled by the interrupt handler)
void job_fifo(esp_slave_context_t *context)
{
for (int i = 0; i < 1024; i++) {
buffer[i] = 0x46 + i * 5;
send_buffer[i] = 0x46 + i * 5;
}
esp_err_t ret;
@ -318,7 +319,7 @@ void job_fifo(esp_slave_context_t *context)
for (int i = 0; i < sizeof(packet_len) / sizeof(int); i++) {
const int wait_ms = 50;
int length = packet_len[i];
ret = esp_slave_send_packet(context, buffer + pointer, length, wait_ms);
ret = esp_slave_send_packet(context, send_buffer + pointer, length, wait_ms);
if (ret == ESP_ERR_TIMEOUT) {
ESP_LOGD(TAG, "several packets are expected to timeout.");
} else {