fix(sdio_slave): improve sdio slave for high speed and 4 bit mode
This commit is contained in:
parent
823ebba0f0
commit
597eda5f0b
|
@ -47,10 +47,12 @@ typedef enum {
|
||||||
|
|
||||||
/// Timing of SDIO slave
|
/// Timing of SDIO slave
|
||||||
typedef enum {
|
typedef enum {
|
||||||
SDIO_SLAVE_TIMING_NSEND_PSAMPLE = 0,///< Send at negedge, and sample at posedge. Default value for SD protocol.
|
SDIO_SLAVE_TIMING_PSEND_PSAMPLE = 0,/**< Send at posedge, and sample at posedge. Default value for HS mode.
|
||||||
SDIO_SLAVE_TIMING_NSEND_NSAMPLE, ///< Send at negedge, and sample at negedge
|
* Normally there's no problem using this to work in DS mode.
|
||||||
SDIO_SLAVE_TIMING_PSEND_PSAMPLE, ///< Send at posedge, and sample at posedge
|
*/
|
||||||
|
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_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;
|
} sdio_slave_timing_t;
|
||||||
|
|
||||||
/// Configuration of SDIO slave mode
|
/// Configuration of SDIO slave mode
|
||||||
|
|
|
@ -472,9 +472,9 @@ static void configure_pin(int pin, uint32_t func, bool pullup)
|
||||||
PIN_INPUT_ENABLE(reg);
|
PIN_INPUT_ENABLE(reg);
|
||||||
PIN_FUNC_SELECT(reg, sdmmc_func);
|
PIN_FUNC_SELECT(reg, sdmmc_func);
|
||||||
PIN_SET_DRV(reg, drive_strength);
|
PIN_SET_DRV(reg, drive_strength);
|
||||||
|
gpio_pulldown_dis(pin);
|
||||||
if (pullup) {
|
if (pullup) {
|
||||||
gpio_pullup_en(pin);
|
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) {
|
switch(config->timing) {
|
||||||
case SDIO_SLAVE_TIMING_PSEND_PSAMPLE:
|
case SDIO_SLAVE_TIMING_PSEND_PSAMPLE:
|
||||||
HOST.conf.frc_sdio20 = 0xf;
|
HOST.conf.frc_sdio20 = 0x1f;
|
||||||
HOST.conf.frc_sdio11 = 0;
|
HOST.conf.frc_sdio11 = 0;
|
||||||
HOST.conf.frc_pos_samp = 0xf;
|
HOST.conf.frc_pos_samp = 0x1f;
|
||||||
HOST.conf.frc_neg_samp = 0;
|
HOST.conf.frc_neg_samp = 0;
|
||||||
break;
|
break;
|
||||||
case SDIO_SLAVE_TIMING_PSEND_NSAMPLE:
|
case SDIO_SLAVE_TIMING_PSEND_NSAMPLE:
|
||||||
HOST.conf.frc_sdio20 = 0xf;
|
HOST.conf.frc_sdio20 = 0x1f;
|
||||||
HOST.conf.frc_sdio11 = 0;
|
HOST.conf.frc_sdio11 = 0;
|
||||||
HOST.conf.frc_pos_samp = 0;
|
HOST.conf.frc_pos_samp = 0;
|
||||||
HOST.conf.frc_neg_samp = 0xf;
|
HOST.conf.frc_neg_samp = 0x1f;
|
||||||
break;
|
break;
|
||||||
case SDIO_SLAVE_TIMING_NSEND_PSAMPLE:
|
case SDIO_SLAVE_TIMING_NSEND_PSAMPLE:
|
||||||
HOST.conf.frc_sdio20 = 0;
|
HOST.conf.frc_sdio20 = 0;
|
||||||
HOST.conf.frc_sdio11 = 0xf;
|
HOST.conf.frc_sdio11 = 0x1f;
|
||||||
HOST.conf.frc_pos_samp = 0xf;
|
HOST.conf.frc_pos_samp = 0x1f;
|
||||||
HOST.conf.frc_neg_samp = 0;
|
HOST.conf.frc_neg_samp = 0;
|
||||||
break;
|
break;
|
||||||
case SDIO_SLAVE_TIMING_NSEND_NSAMPLE:
|
case SDIO_SLAVE_TIMING_NSEND_NSAMPLE:
|
||||||
HOST.conf.frc_sdio20 = 0;
|
HOST.conf.frc_sdio20 = 0;
|
||||||
HOST.conf.frc_sdio11 = 0xf;
|
HOST.conf.frc_sdio11 = 0x1f;
|
||||||
HOST.conf.frc_pos_samp = 0;
|
HOST.conf.frc_pos_samp = 0;
|
||||||
HOST.conf.frc_neg_samp = 0xf;
|
HOST.conf.frc_neg_samp = 0x1f;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -152,7 +152,7 @@ esp_err_t slave_init(esp_slave_context_t *context)
|
||||||
#ifdef CONFIG_SDIO_EXAMPLE_HIGHSPEED
|
#ifdef CONFIG_SDIO_EXAMPLE_HIGHSPEED
|
||||||
config.max_freq_khz = SDMMC_FREQ_HIGHSPEED;
|
config.max_freq_khz = SDMMC_FREQ_HIGHSPEED;
|
||||||
#else
|
#else
|
||||||
config.max_freq_khz = SDMMC_FREQ_PROBING;
|
config.max_freq_khz = SDMMC_FREQ_DEFAULT;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT();
|
sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT();
|
||||||
|
@ -209,14 +209,15 @@ void slave_power_on()
|
||||||
};
|
};
|
||||||
gpio_config(&cfg);
|
gpio_config(&cfg);
|
||||||
gpio_set_level(SLAVE_PWR_GPIO, 0); //low active
|
gpio_set_level(SLAVE_PWR_GPIO, 0); //low active
|
||||||
|
vTaskDelay(100);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DMA_ATTR uint8_t rcv_buffer[READ_BUFFER_LEN];
|
||||||
|
|
||||||
//try to get an interrupt from the slave and handle it, return if none.
|
//try to get an interrupt from the slave and handle it, return if none.
|
||||||
esp_err_t process_event(esp_slave_context_t *context)
|
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);
|
esp_err_t ret = esp_slave_wait_int(context, 0);
|
||||||
if (ret == ESP_ERR_TIMEOUT) {
|
if (ret == ESP_ERR_TIMEOUT) {
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -241,7 +242,7 @@ esp_err_t process_event(esp_slave_context_t *context)
|
||||||
ESP_LOGD(TAG, "new packet coming");
|
ESP_LOGD(TAG, "new packet coming");
|
||||||
while (1) {
|
while (1) {
|
||||||
size_t size_read = READ_BUFFER_LEN;
|
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) {
|
if (ret == ESP_ERR_NOT_FOUND) {
|
||||||
ESP_LOGE(TAG, "interrupt but no data can be read");
|
ESP_LOGE(TAG, "interrupt but no data can be read");
|
||||||
break;
|
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_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) {
|
if (ret == ESP_OK) {
|
||||||
break;
|
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
|
//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};
|
int packet_len[] = {3, 6, 12, 128, 511, 512, 513, 517};
|
||||||
//the sending buffer should be word aligned
|
//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)
|
//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 < 1024; i++) {
|
||||||
buffer[i] = 0x46 + i * 5;
|
send_buffer[i] = 0x46 + i * 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
esp_err_t ret;
|
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++) {
|
for (int i = 0; i < sizeof(packet_len) / sizeof(int); i++) {
|
||||||
const int wait_ms = 50;
|
const int wait_ms = 50;
|
||||||
int length = packet_len[i];
|
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) {
|
if (ret == ESP_ERR_TIMEOUT) {
|
||||||
ESP_LOGD(TAG, "several packets are expected to timeout.");
|
ESP_LOGD(TAG, "several packets are expected to timeout.");
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Reference in a new issue