forked from espressif/esp-idf
sdmmc_io: support to print CIS information
Currently only ESP slaves can be parsed correctly.
This commit is contained in:
@@ -458,15 +458,23 @@ static inline uint32_t MMC_RSP_BITS(uint32_t *src, int start, int len)
|
|||||||
#define SD_IO_CIS_SIZE 0x17000
|
#define SD_IO_CIS_SIZE 0x17000
|
||||||
|
|
||||||
/* CIS tuple codes (based on PC Card 16) */
|
/* CIS tuple codes (based on PC Card 16) */
|
||||||
#define SD_IO_CISTPL_NULL 0x00
|
#define CISTPL_CODE_NULL 0x00
|
||||||
#define SD_IO_CISTPL_VERS_1 0x15
|
#define CISTPL_CODE_DEVICE 0x01
|
||||||
#define SD_IO_CISTPL_MANFID 0x20
|
#define CISTPL_CODE_CHKSUM 0x10
|
||||||
#define SD_IO_CISTPL_FUNCID 0x21
|
#define CISTPL_CODE_VERS1 0x15
|
||||||
#define SD_IO_CISTPL_FUNCE 0x22
|
#define CISTPL_CODE_ALTSTR 0x16
|
||||||
#define SD_IO_CISTPL_END 0xff
|
#define CISTPL_CODE_CONFIG 0x1A
|
||||||
|
#define CISTPL_CODE_CFTABLE_ENTRY 0x1B
|
||||||
|
#define CISTPL_CODE_MANFID 0x20
|
||||||
|
#define CISTPL_CODE_FUNCID 0x21
|
||||||
|
#define TPLFID_FUNCTION_SDIO 0x0c
|
||||||
|
#define CISTPL_CODE_FUNCE 0x22
|
||||||
|
#define CISTPL_CODE_VENDER_BEGIN 0x80
|
||||||
|
#define CISTPL_CODE_VENDER_END 0x8F
|
||||||
|
#define CISTPL_CODE_SDIO_STD 0x91
|
||||||
|
#define CISTPL_CODE_SDIO_EXT 0x92
|
||||||
|
#define CISTPL_CODE_END 0xFF
|
||||||
|
|
||||||
/* CISTPL_FUNCID codes */
|
|
||||||
#define TPLFID_FUNCTION_SDIO 0x0c
|
|
||||||
|
|
||||||
/* Timing */
|
/* Timing */
|
||||||
#define SDMMC_TIMING_LEGACY 0
|
#define SDMMC_TIMING_LEGACY 0
|
||||||
|
@@ -220,6 +220,55 @@ esp_err_t sdmmc_io_enable_int(sdmmc_card_t* card);
|
|||||||
*/
|
*/
|
||||||
esp_err_t sdmmc_io_wait_int(sdmmc_card_t* card, TickType_t timeout_ticks);
|
esp_err_t sdmmc_io_wait_int(sdmmc_card_t* card, TickType_t timeout_ticks);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the data of CIS region of a SDIO card.
|
||||||
|
*
|
||||||
|
* You may provide a buffer not sufficient to store all the CIS data. In this
|
||||||
|
* case, this functions store as much data into your buffer as possible. Also,
|
||||||
|
* this function will try to get and return the size required for you.
|
||||||
|
*
|
||||||
|
* @param card pointer to card information structure previously initialized
|
||||||
|
* using sdmmc_card_init
|
||||||
|
* @param out_buffer Output buffer of the CIS data
|
||||||
|
* @param buffer_size Size of the buffer.
|
||||||
|
* @param inout_cis_size Mandatory, pointer to a size, input and output.
|
||||||
|
* - input: Limitation of maximum searching range, should be 0 or larger than
|
||||||
|
* buffer_size. The function searches for CIS_CODE_END until this range. Set to
|
||||||
|
* 0 to search infinitely.
|
||||||
|
* - output: The size required to store all the CIS data, if CIS_CODE_END is found.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* - ESP_OK: on success
|
||||||
|
* - ESP_ERR_INVALID_RESPONSE: if the card does not (correctly) support CIS.
|
||||||
|
* - ESP_ERR_INVALID_SIZE: CIS_CODE_END found, but buffer_size is less than
|
||||||
|
* required size, which is stored in the inout_cis_size then.
|
||||||
|
* - ESP_ERR_NOT_FOUND: if the CIS_CODE_END not found. Increase input value of
|
||||||
|
* inout_cis_size or set it to 0, if you still want to search for the end;
|
||||||
|
* output value of inout_cis_size is invalid in this case.
|
||||||
|
* - and other error code return from sdmmc_io_read_bytes
|
||||||
|
*/
|
||||||
|
esp_err_t sdmmc_io_get_cis_data(sdmmc_card_t* card, uint8_t* out_buffer, size_t buffer_size, size_t* inout_cis_size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse and print the CIS information of a SDIO card.
|
||||||
|
*
|
||||||
|
* @note Not all the CIS codes and all kinds of tuples are supported. If you
|
||||||
|
* see some unresolved code, you can add the parsing of these code in
|
||||||
|
* sdmmc_io.c and contribute to the IDF through the Github repository.
|
||||||
|
*
|
||||||
|
* using sdmmc_card_init
|
||||||
|
* @param buffer Buffer to parse
|
||||||
|
* @param buffer_size Size of the buffer.
|
||||||
|
* @param fp File pointer to print to, set to NULL to print to stdout.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* - ESP_OK: on success
|
||||||
|
* - ESP_ERR_NOT_SUPPORTED: if the value from the card is not supported to be parsed.
|
||||||
|
* - ESP_ERR_INVALID_SIZE: if the CIS size fields are not correct.
|
||||||
|
*/
|
||||||
|
esp_err_t sdmmc_io_print_cis_info(uint8_t* buffer, size_t buffer_size, FILE* fp);
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@@ -16,9 +16,50 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "sdmmc_common.h"
|
#include "sdmmc_common.h"
|
||||||
|
#include "esp_attr.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define CIS_TUPLE(NAME) (cis_tuple_t) {.code=CISTPL_CODE_##NAME, .name=#NAME, .func=&cis_tuple_func_default, }
|
||||||
|
#define CIS_TUPLE_WITH_FUNC(NAME, FUNC) (cis_tuple_t) {.code=CISTPL_CODE_##NAME, .name=#NAME, .func=&(FUNC), }
|
||||||
|
|
||||||
|
#define CIS_CHECK_SIZE(SIZE, MINIMAL) do {int store_size = (SIZE); if((store_size) < (MINIMAL)) return ESP_ERR_INVALID_SIZE;} while(0)
|
||||||
|
#define CIS_CHECK_UNSUPPORTED(COND) do {if(!(COND)) return ESP_ERR_NOT_SUPPORTED;} while(0)
|
||||||
|
#define CIS_GET_MINIMAL_SIZE 32
|
||||||
|
|
||||||
|
typedef esp_err_t (*cis_tuple_info_func_t)(const void* tuple_info, uint8_t* data, FILE* fp);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int code;
|
||||||
|
const char *name;
|
||||||
|
cis_tuple_info_func_t func;
|
||||||
|
} cis_tuple_t;
|
||||||
|
|
||||||
static const char* TAG = "sdmmc_io";
|
static const char* TAG = "sdmmc_io";
|
||||||
|
|
||||||
|
static esp_err_t cis_tuple_func_default(const void* p, uint8_t* data, FILE* fp);
|
||||||
|
static esp_err_t cis_tuple_func_manfid(const void* p, uint8_t* data, FILE* fp);
|
||||||
|
static esp_err_t cis_tuple_func_cftable_entry(const void* p, uint8_t* data, FILE* fp);
|
||||||
|
static esp_err_t cis_tuple_func_end(const void* p, uint8_t* data, FILE* fp);
|
||||||
|
|
||||||
|
static const cis_tuple_t cis_table[] = {
|
||||||
|
CIS_TUPLE(NULL),
|
||||||
|
CIS_TUPLE(DEVICE),
|
||||||
|
CIS_TUPLE(CHKSUM),
|
||||||
|
CIS_TUPLE(VERS1),
|
||||||
|
CIS_TUPLE(ALTSTR),
|
||||||
|
CIS_TUPLE(CONFIG),
|
||||||
|
CIS_TUPLE_WITH_FUNC(CFTABLE_ENTRY, cis_tuple_func_cftable_entry),
|
||||||
|
CIS_TUPLE_WITH_FUNC(MANFID, cis_tuple_func_manfid),
|
||||||
|
CIS_TUPLE(FUNCID),
|
||||||
|
CIS_TUPLE(FUNCE),
|
||||||
|
CIS_TUPLE(VENDER_BEGIN),
|
||||||
|
CIS_TUPLE(VENDER_END),
|
||||||
|
CIS_TUPLE(SDIO_STD),
|
||||||
|
CIS_TUPLE(SDIO_EXT),
|
||||||
|
CIS_TUPLE_WITH_FUNC(END, cis_tuple_func_end),
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
esp_err_t sdmmc_io_reset(sdmmc_card_t* card)
|
esp_err_t sdmmc_io_reset(sdmmc_card_t* card)
|
||||||
{
|
{
|
||||||
uint8_t sdio_reset = CCCR_CTL_RES;
|
uint8_t sdio_reset = CCCR_CTL_RES;
|
||||||
@@ -352,3 +393,240 @@ esp_err_t sdmmc_io_wait_int(sdmmc_card_t* card, TickType_t timeout_ticks)
|
|||||||
}
|
}
|
||||||
return (*card->host.io_int_wait)(card->host.slot, timeout_ticks);
|
return (*card->host.io_int_wait)(card->host.slot, timeout_ticks);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Print the CIS information of a CIS card, currently only ESP slave supported.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static esp_err_t cis_tuple_func_default(const void* p, uint8_t* data, FILE* fp)
|
||||||
|
{
|
||||||
|
const cis_tuple_t* tuple = (const cis_tuple_t*)p;
|
||||||
|
uint8_t code = *(data++);
|
||||||
|
int size = *(data++);
|
||||||
|
if (tuple) {
|
||||||
|
fprintf(fp, "TUPLE: %s, size: %d: ", tuple->name, size);
|
||||||
|
} else {
|
||||||
|
fprintf(fp, "TUPLE: unknown(%02X), size: %d: ", code, size);
|
||||||
|
}
|
||||||
|
for (int i = 0; i < size; i++) fprintf(fp, "%02X ", *(data++));
|
||||||
|
fprintf(fp, "\n");
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static esp_err_t cis_tuple_func_manfid(const void* p, uint8_t* data, FILE* fp)
|
||||||
|
{
|
||||||
|
const cis_tuple_t* tuple = (const cis_tuple_t*)p;
|
||||||
|
data++;
|
||||||
|
int size = *(data++);
|
||||||
|
fprintf(fp, "TUPLE: %s, size: %d\n", tuple->name, size);
|
||||||
|
CIS_CHECK_SIZE(size, 4);
|
||||||
|
fprintf(fp, " MANF: %04X, CARD: %04X\n", *(uint16_t*)(data), *(uint16_t*)(data+2));
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static esp_err_t cis_tuple_func_end(const void* p, uint8_t* data, FILE* fp)
|
||||||
|
{
|
||||||
|
const cis_tuple_t* tuple = (const cis_tuple_t*)p;
|
||||||
|
data++;
|
||||||
|
fprintf(fp, "TUPLE: %s\n", tuple->name);
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static esp_err_t cis_tuple_func_cftable_entry(const void* p, uint8_t* data, FILE* fp)
|
||||||
|
{
|
||||||
|
const cis_tuple_t* tuple = (const cis_tuple_t*)p;
|
||||||
|
data++;
|
||||||
|
int size = *(data++);
|
||||||
|
fprintf(fp, "TUPLE: %s, size: %d\n", tuple->name, size);
|
||||||
|
CIS_CHECK_SIZE(size, 2);
|
||||||
|
|
||||||
|
CIS_CHECK_SIZE(size--, 1);
|
||||||
|
bool interface = data[0] & BIT(7);
|
||||||
|
bool def = data[0] & BIT(6);
|
||||||
|
int conf_ent_num = data[0] & 0x3F;
|
||||||
|
fprintf(fp, " INDX: %02X, Intface: %d, Default: %d, Conf-Entry-Num: %d\n", *(data++), interface, def, conf_ent_num);
|
||||||
|
|
||||||
|
if (interface) {
|
||||||
|
CIS_CHECK_SIZE(size--, 1);
|
||||||
|
fprintf(fp, " IF: %02X\n", *(data++));
|
||||||
|
}
|
||||||
|
|
||||||
|
CIS_CHECK_SIZE(size--, 1);
|
||||||
|
bool misc = data[0] & BIT(7);
|
||||||
|
int mem_space = (data[0] >> 5 )&(0x3);
|
||||||
|
bool irq = data[0] & BIT(4);
|
||||||
|
bool io_sp = data[0] & BIT(3);
|
||||||
|
bool timing = data[0] & BIT(2);
|
||||||
|
int power = data[0] & 3;
|
||||||
|
fprintf(fp, " FS: %02X, misc: %d, mem_space: %d, irq: %d, io_space: %d, timing: %d, power: %d\n", *(data++), misc, mem_space, irq, io_sp, timing, power);
|
||||||
|
|
||||||
|
CIS_CHECK_UNSUPPORTED(power == 0); //power descriptor is not handled yet
|
||||||
|
CIS_CHECK_UNSUPPORTED(!timing); //timing descriptor is not handled yet
|
||||||
|
CIS_CHECK_UNSUPPORTED(!io_sp); //io space descriptor is not handled yet
|
||||||
|
|
||||||
|
if (irq) {
|
||||||
|
CIS_CHECK_SIZE(size--, 1);
|
||||||
|
bool mask = data[0] & BIT(4);
|
||||||
|
fprintf(fp, " IR: %02X, mask: %d, ",*(data++), mask);
|
||||||
|
if (mask) {
|
||||||
|
CIS_CHECK_SIZE(size, 2);
|
||||||
|
size-=2;
|
||||||
|
fprintf(fp, " IRQ: %02X %02X\n", data[0], data[1]);
|
||||||
|
data+=2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mem_space) {
|
||||||
|
CIS_CHECK_SIZE(size, 2);
|
||||||
|
size-=2;
|
||||||
|
CIS_CHECK_UNSUPPORTED(mem_space==1); //other cases not handled yet
|
||||||
|
int len = *(uint16_t*)data;
|
||||||
|
fprintf(fp, " LEN: %04X\n", len);
|
||||||
|
data+=2;
|
||||||
|
}
|
||||||
|
|
||||||
|
CIS_CHECK_UNSUPPORTED(misc==0); //misc descriptor is not handled yet
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const cis_tuple_t* get_tuple(uint8_t code)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < sizeof(cis_table)/sizeof(cis_tuple_t); i++) {
|
||||||
|
if (code == cis_table[i].code) return &cis_table[i];
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t sdmmc_io_print_cis_info(uint8_t* buffer, size_t buffer_size, FILE* fp)
|
||||||
|
{
|
||||||
|
ESP_LOG_BUFFER_HEXDUMP("CIS", buffer, buffer_size, ESP_LOG_DEBUG);
|
||||||
|
if (!fp) fp = stdout;
|
||||||
|
|
||||||
|
uint8_t* cis = buffer;
|
||||||
|
do {
|
||||||
|
const cis_tuple_t* tuple = get_tuple(cis[0]);
|
||||||
|
int size = cis[1];
|
||||||
|
esp_err_t ret = ESP_OK;
|
||||||
|
if (tuple) {
|
||||||
|
ret = tuple->func(tuple, cis, fp);
|
||||||
|
} else {
|
||||||
|
ret = cis_tuple_func_default(NULL, cis, fp);
|
||||||
|
}
|
||||||
|
if (ret != ESP_OK) return ret;
|
||||||
|
cis += 2 + size;
|
||||||
|
if (tuple && tuple->code == CISTPL_CODE_END) break;
|
||||||
|
} while (cis < buffer + buffer_size) ;
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check tuples in the buffer.
|
||||||
|
*
|
||||||
|
* @param buf Buffer to check
|
||||||
|
* @param buffer_size Size of the buffer
|
||||||
|
* @param inout_cis_offset
|
||||||
|
* - input: the last cis_offset, relative to the beginning of the buf. -1 if
|
||||||
|
* this buffer begin with the tuple length, otherwise should be no smaller than
|
||||||
|
* zero.
|
||||||
|
* - output: when the end tuple found, output offset of the CISTPL_CODE_END
|
||||||
|
* byte + 1 (relative to the beginning of the buffer; when not found, output
|
||||||
|
* the address of next tuple code.
|
||||||
|
*
|
||||||
|
* @return true if found, false if haven't.
|
||||||
|
*/
|
||||||
|
static bool check_tuples_in_buffer(uint8_t* buf, int buffer_size, int* inout_cis_offset)
|
||||||
|
{
|
||||||
|
int cis_offset = *inout_cis_offset;
|
||||||
|
if (cis_offset == -1) {
|
||||||
|
//the CIS code is checked in the last buffer, skip to next tuple
|
||||||
|
cis_offset += buf[0] + 2;
|
||||||
|
}
|
||||||
|
assert(cis_offset >= 0);
|
||||||
|
while (1) {
|
||||||
|
if (cis_offset < buffer_size) {
|
||||||
|
//A CIS code in the buffer, check it
|
||||||
|
if (buf[cis_offset] == CISTPL_CODE_END) {
|
||||||
|
*inout_cis_offset = cis_offset + 1;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (cis_offset + 1 < buffer_size) {
|
||||||
|
cis_offset += buf[cis_offset+1] + 2;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*inout_cis_offset = cis_offset;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t sdmmc_io_get_cis_data(sdmmc_card_t* card, uint8_t* out_buffer, size_t buffer_size, size_t* inout_cis_size)
|
||||||
|
{
|
||||||
|
esp_err_t ret = ESP_OK;
|
||||||
|
WORD_ALIGNED_ATTR uint8_t buf[CIS_GET_MINIMAL_SIZE];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CIS region exist in 0x1000~0x17FFF of FUNC 0, get the start address of it
|
||||||
|
* from CCCR register.
|
||||||
|
*/
|
||||||
|
uint32_t addr;
|
||||||
|
ret = sdmmc_io_read_bytes(card, 0, 9, &addr, 3);
|
||||||
|
if (ret != ESP_OK) return ret;
|
||||||
|
//the sdmmc_io driver reads 4 bytes, the most significant byte is not the address.
|
||||||
|
addr &= 0xffffff;
|
||||||
|
if (addr < 0x1000 || addr > 0x17FFF) {
|
||||||
|
return ESP_ERR_INVALID_RESPONSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* To avoid reading too long, take the input value as limitation if
|
||||||
|
* existing.
|
||||||
|
*/
|
||||||
|
size_t max_reading = UINT32_MAX;
|
||||||
|
if (inout_cis_size && *inout_cis_size != 0) {
|
||||||
|
max_reading = *inout_cis_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Parse the length while reading. If find the end tuple, or reaches the
|
||||||
|
* limitation, read no more and return both the data and the size already
|
||||||
|
* read.
|
||||||
|
*/
|
||||||
|
int buffer_offset = 0;
|
||||||
|
int cur_cis_offset = 0;
|
||||||
|
bool end_tuple_found = false;
|
||||||
|
do {
|
||||||
|
ret = sdmmc_io_read_bytes(card, 0, addr + buffer_offset, &buf, CIS_GET_MINIMAL_SIZE);
|
||||||
|
if (ret != ESP_OK) return ret;
|
||||||
|
|
||||||
|
//calculate relative to the beginning of the buffer
|
||||||
|
int offset = cur_cis_offset - buffer_offset;
|
||||||
|
bool finish = check_tuples_in_buffer(buf, CIS_GET_MINIMAL_SIZE, &offset);
|
||||||
|
|
||||||
|
int remain_size = buffer_size - buffer_offset;
|
||||||
|
int copy_len;
|
||||||
|
if (finish) {
|
||||||
|
copy_len = MIN(offset, remain_size);
|
||||||
|
end_tuple_found = true;
|
||||||
|
} else {
|
||||||
|
copy_len = MIN(CIS_GET_MINIMAL_SIZE, remain_size);
|
||||||
|
}
|
||||||
|
if (copy_len > 0) {
|
||||||
|
memcpy(out_buffer + buffer_offset, buf, copy_len);
|
||||||
|
}
|
||||||
|
cur_cis_offset = buffer_offset + offset;
|
||||||
|
buffer_offset += CIS_GET_MINIMAL_SIZE;
|
||||||
|
} while (!end_tuple_found && buffer_offset < max_reading);
|
||||||
|
|
||||||
|
if (end_tuple_found) {
|
||||||
|
*inout_cis_size = cur_cis_offset;
|
||||||
|
if (cur_cis_offset > buffer_size) {
|
||||||
|
return ESP_ERR_INVALID_SIZE;
|
||||||
|
} else {
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return ESP_ERR_NOT_FOUND;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -25,6 +25,7 @@
|
|||||||
#include "driver/sdmmc_host.h"
|
#include "driver/sdmmc_host.h"
|
||||||
#include "driver/sdspi_host.h"
|
#include "driver/sdspi_host.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
|
||||||
* slaves individially. We only enable one at a time.
|
* slaves individially. We only enable one at a time.
|
||||||
@@ -134,6 +135,36 @@ static void gpio_d2_set_high()
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static esp_err_t print_sdio_cis_information(sdmmc_card_t* card)
|
||||||
|
{
|
||||||
|
const size_t cis_buffer_size = 256;
|
||||||
|
uint8_t cis_buffer[cis_buffer_size];
|
||||||
|
size_t cis_data_len = 1024; //specify maximum searching range to avoid infinite loop
|
||||||
|
esp_err_t ret = ESP_OK;
|
||||||
|
|
||||||
|
ret = sdmmc_io_get_cis_data(card, cis_buffer, cis_buffer_size, &cis_data_len);
|
||||||
|
if (ret == ESP_ERR_INVALID_SIZE) {
|
||||||
|
int temp_buf_size = cis_data_len;
|
||||||
|
uint8_t* temp_buf = malloc(temp_buf_size);
|
||||||
|
assert(temp_buf);
|
||||||
|
|
||||||
|
ESP_LOGW(TAG, "CIS data longer than expected, temporary buffer allocated.");
|
||||||
|
ret = sdmmc_io_get_cis_data(card, temp_buf, temp_buf_size, &cis_data_len);
|
||||||
|
ESP_ERROR_CHECK(ret);
|
||||||
|
|
||||||
|
sdmmc_io_print_cis_info(temp_buf, cis_data_len, NULL);
|
||||||
|
|
||||||
|
free(temp_buf);
|
||||||
|
} else if (ret == ESP_OK) {
|
||||||
|
sdmmc_io_print_cis_info(cis_buffer, cis_data_len, NULL);
|
||||||
|
} else {
|
||||||
|
//including ESP_ERR_NOT_FOUND
|
||||||
|
ESP_LOGE(TAG, "failed to get the entire CIS data.");
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
//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)
|
||||||
{
|
{
|
||||||
@@ -164,10 +195,10 @@ esp_err_t slave_init(esp_slave_context_t *context)
|
|||||||
*/
|
*/
|
||||||
//slot_config.flags = SDMMC_SLOT_FLAG_INTERNAL_PULLUP;
|
//slot_config.flags = SDMMC_SLOT_FLAG_INTERNAL_PULLUP;
|
||||||
err = sdmmc_host_init();
|
err = sdmmc_host_init();
|
||||||
assert(err==ESP_OK);
|
ESP_ERROR_CHECK(err);
|
||||||
|
|
||||||
err = sdmmc_host_init_slot(SDMMC_HOST_SLOT_1, &slot_config);
|
err = sdmmc_host_init_slot(SDMMC_HOST_SLOT_1, &slot_config);
|
||||||
assert(err==ESP_OK);
|
ESP_ERROR_CHECK(err);
|
||||||
#else //over SPI
|
#else //over SPI
|
||||||
sdmmc_host_t config = SDSPI_HOST_DEFAULT();
|
sdmmc_host_t config = SDSPI_HOST_DEFAULT();
|
||||||
|
|
||||||
@@ -179,12 +210,12 @@ esp_err_t slave_init(esp_slave_context_t *context)
|
|||||||
slot_config.gpio_int = SDIO_SLAVE_SLOT1_IOMUX_PIN_NUM_D1;
|
slot_config.gpio_int = SDIO_SLAVE_SLOT1_IOMUX_PIN_NUM_D1;
|
||||||
|
|
||||||
err = gpio_install_isr_service(0);
|
err = gpio_install_isr_service(0);
|
||||||
assert(err == ESP_OK);
|
ESP_ERROR_CHECK(err);
|
||||||
err = sdspi_host_init();
|
err = sdspi_host_init();
|
||||||
assert(err==ESP_OK);
|
ESP_ERROR_CHECK(err);
|
||||||
|
|
||||||
err = sdspi_host_init_slot(HSPI_HOST, &slot_config);
|
err = sdspi_host_init_slot(HSPI_HOST, &slot_config);
|
||||||
assert(err==ESP_OK);
|
ESP_ERROR_CHECK(err);
|
||||||
ESP_LOGI(TAG, "Probe using SPI...\n");
|
ESP_LOGI(TAG, "Probe using SPI...\n");
|
||||||
|
|
||||||
//we have to pull up all the slave pins even when the pin is not used
|
//we have to pull up all the slave pins even when the pin is not used
|
||||||
@@ -218,10 +249,14 @@ esp_err_t slave_init(esp_slave_context_t *context)
|
|||||||
|
|
||||||
*context = ESP_SLAVE_DEFAULT_CONTEXT(card);
|
*context = ESP_SLAVE_DEFAULT_CONTEXT(card);
|
||||||
esp_err_t ret = esp_slave_init_io(context);
|
esp_err_t ret = esp_slave_init_io(context);
|
||||||
|
ESP_ERROR_CHECK(ret);
|
||||||
|
|
||||||
|
ret = print_sdio_cis_information(card);
|
||||||
|
ESP_ERROR_CHECK(ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void slave_power_on()
|
void slave_power_on()
|
||||||
{
|
{
|
||||||
#ifdef SLAVE_PWR_GPIO
|
#ifdef SLAVE_PWR_GPIO
|
||||||
|
Reference in New Issue
Block a user