feat(sd_card): add built-in checks for connections to the card and correct pullups

This commit is contained in:
sonika.rathi 2023-11-27 11:13:48 +01:00
parent 7be04869d2
commit 54647dbbd3
13 changed files with 602 additions and 4 deletions

View File

@ -3,4 +3,7 @@
cmake_minimum_required(VERSION 3.16)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
set(COMPONENTS main)
project(sd_card)

View File

@ -182,3 +182,72 @@ Connections between the card and the ESP32 are too long for the frequency used.
example: Failed to mount filesystem. If you want the card to be formatted, set the EXAMPLE_FORMAT_IF_MOUNT_FAILED menuconfig option.
```
The example will be able to mount only cards formatted using FAT32 filesystem. If the card is formatted as exFAT or some other filesystem, you have an option to format it in the example code. Enable the `EXAMPLE_FORMAT_IF_MOUNT_FAILED` menuconfig option, then build and flash the example.
### Debug SD connections and pullup strength
> If the initialization of the SD card fails, initially follow the above options. If the issue persists, confirm the connection of pullups to the SD pins. To do this, enable the` Debug sd pin connections and pullup strength` option from menuconfig and rerun the code. This will provide the following result:
```
**** PIN recovery time ****
PIN 14 CLK 10044 cycles
PIN 15 CMD 10034 cycles
PIN 2 D0 10034 cycles
PIN 4 D1 10034 cycles
PIN 12 D2 10034 cycles
PIN 13 D3 10034 cycles
**** PIN recovery time with weak pullup ****
PIN 14 CLK 100 cycles
PIN 15 CMD 100 cycles
PIN 2 D0 100 cycles
PIN 4 D1 100 cycles
PIN 12 D2 100 cycles
PIN 13 D3 100 cycles
**** PIN voltage levels ****
PIN 14 CLK 0.6V
PIN 15 CMD 0.3V
PIN 2 D0 0.8V
PIN 4 D1 0.6V
PIN 12 D2 0.4V
PIN 13 D3 0.8V
**** PIN voltage levels with weak pullup ****
PIN 14 CLK 1.0V
PIN 15 CMD 1.1V
PIN 2 D0 1.0V
PIN 4 D1 1.0V
PIN 12 D2 1.0V
PIN 13 D3 1.2V
**** PIN cross-talk ****
CLK CMD D0 D1 D2 D3
PIN 14 CLK -- 0.2V 0.1V 0.1V 0.1V 0.2V
PIN 15 CMD 0.1V -- 0.1V 0.1V 0.1V 0.1V
PIN 2 D0 0.1V 0.1V -- 0.2V 0.1V 0.1V
PIN 4 D1 0.1V 0.1V 0.3V -- 0.1V 0.1V
PIN 12 D2 0.1V 0.2V 0.2V 0.1V -- 0.1V
PIN 13 D3 0.1V 0.2V 0.1V 0.1V 0.1V --
**** PIN cross-talk with weak pullup ****
CLK CMD D0 D1 D2 D3
PIN 14 CLK -- 1.0V 1.0V 1.0V 1.0V 1.2V
PIN 15 CMD 0.9V -- 1.0V 1.0V 1.0V 1.2V
PIN 2 D0 0.9V 1.0V -- 1.0V 1.0V 1.2V
PIN 4 D1 0.9V 1.0V 1.2V -- 1.0V 1.2V
PIN 12 D2 0.9V 1.1V 1.2V 0.9V -- 1.2V
PIN 13 D3 0.9V 1.2V 1.1V 0.9V 0.9V --
I (845) main_task: Returned from app_main()
```
In the absence of connected pullups and having the weak pullups enabled, you can assess the pullup connections by comparing PIN recovery time measured in CPU cycles. To check pullup connections, configure the pin as open drain, set it to low state, and count the cpu cycles consumed before returning to high state. If a pullup is connected, the pin will get back to high state after reasonably small cycle count, typically around 50-300 cycles, depending on pullup strength. If no pullup is connected, the PIN stays low and the measurement times out after 10000 cycles.
It will also provide the voltage levels at the corresponding SD pins. By default, this information is provided for ESP32 chip only, and for other chipsets, verify the availability of ADC pins for the respective GPIO using [this](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/gpio.html#gpio-summary) and configure ADC mapped pins using menuconfig. Then test the voltage levels accordingly.
You can monitor the voltage levels of individual pins using `PIN voltage levels` and `PIN voltage levels with weak pullup`. However, if one pin being pulled low and experiencing interference with another pin, you can detect it through `PIN cross-talk` and `PIN cross-talk with weak pullup`. In the absence of pullups, voltage levels at each pin should range from 0 to 0.3V. With 10k pullups connected, the voltage will be between 3.1V to 3.3V, contingent on the connection between ADC pins and SD pins, and with weak pullups connected, it can fluctuate between 0.8V to 1.2V, depending on pullup strength.

View File

@ -0,0 +1,4 @@
idf_component_register(SRCS "sd_test_io.c"
INCLUDE_DIRS "."
REQUIRES fatfs esp_adc
WHOLE_ARCHIVE)

View File

@ -0,0 +1,231 @@
/*
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
#include <stdio.h>
#include <inttypes.h>
#include <unistd.h>
#include "esp_adc/adc_oneshot.h"
#include "driver/gpio.h"
#include "esp_cpu.h"
#include "esp_log.h"
#include "sd_test_io.h"
const static char *TAG = "SD_TEST";
#define ADC_ATTEN_DB ADC_ATTEN_DB_12
#define GPIO_INPUT_PIN_SEL(pin) (1ULL<<pin)
#if CONFIG_EXAMPLE_ENABLE_ADC_FEATURE
static bool adc_calibration_init(adc_unit_t unit, adc_channel_t channel, adc_atten_t atten, adc_cali_handle_t *out_handle)
{
adc_cali_handle_t handle = NULL;
esp_err_t ret = ESP_FAIL;
bool calibrated = false;
#if ADC_CALI_SCHEME_CURVE_FITTING_SUPPORTED
if (!calibrated) {
adc_cali_curve_fitting_config_t cali_config = {
.unit_id = unit,
.chan = channel,
.atten = atten,
.bitwidth = ADC_BITWIDTH_DEFAULT,
};
ret = adc_cali_create_scheme_curve_fitting(&cali_config, &handle);
if (ret == ESP_OK) {
calibrated = true;
}
}
#endif //ADC_CALI_SCHEME_CURVE_FITTING_SUPPORTED
#if ADC_CALI_SCHEME_LINE_FITTING_SUPPORTED
if (!calibrated) {
adc_cali_line_fitting_config_t cali_config = {
.unit_id = unit,
.atten = atten,
.bitwidth = ADC_BITWIDTH_DEFAULT,
};
ret = adc_cali_create_scheme_line_fitting(&cali_config, &handle);
if (ret == ESP_OK) {
calibrated = true;
}
}
#endif //ADC_CALI_SCHEME_LINE_FITTING_SUPPORTED
*out_handle = handle;
if (ret != ESP_OK) {
if (ret == ESP_ERR_NOT_SUPPORTED || !calibrated) {
ESP_LOGW(TAG, "eFuse not burnt, skip software calibration");
} else {
ESP_LOGE(TAG, "Invalid arg or no memory");
}
}
return calibrated;
}
static void example_adc_calibration_deinit(adc_cali_handle_t handle)
{
#if ADC_CALI_SCHEME_CURVE_FITTING_SUPPORTED
ESP_ERROR_CHECK(adc_cali_delete_scheme_curve_fitting(handle));
#elif ADC_CALI_SCHEME_LINE_FITTING_SUPPORTED
ESP_ERROR_CHECK(adc_cali_delete_scheme_line_fitting(handle));
#endif
}
static float get_pin_voltage(int i, adc_oneshot_unit_handle_t adc_handle, bool do_calibration, adc_cali_handle_t adc_cali_handle)
{
int voltage = 0;
int val;
adc_oneshot_chan_cfg_t config = {
.bitwidth = ADC_BITWIDTH_DEFAULT,
.atten = ADC_ATTEN_DB,
};
ESP_ERROR_CHECK(adc_oneshot_config_channel(adc_handle, i, &config));
ESP_ERROR_CHECK(adc_oneshot_read(adc_handle, i, &val));
if (do_calibration) {
ESP_ERROR_CHECK(adc_cali_raw_to_voltage(adc_cali_handle, val, &voltage));
}
return (float)voltage/1000;
}
#endif //CONFIG_EXAMPLE_ENABLE_ADC_FEATURE
static uint32_t get_cycles_until_pin_level(int i, int level, int timeout) {
uint32_t start = esp_cpu_get_cycle_count();
while(gpio_get_level(i) == !level && esp_cpu_get_cycle_count() - start < timeout) {
;
}
uint32_t end = esp_cpu_get_cycle_count();
return end - start;
}
void check_sd_card_pins(pin_configuration_t *config, const int pin_count)
{
ESP_LOGI(TAG, "Testing SD pin connections and pullup strength");
gpio_config_t io_conf = {};
for (int i = 0; i < pin_count; ++i) {
io_conf.intr_type = GPIO_INTR_DISABLE;
io_conf.mode = GPIO_MODE_INPUT_OUTPUT_OD;
io_conf.pin_bit_mask = GPIO_INPUT_PIN_SEL(config->pins[i]);
io_conf.pull_down_en = 0;
io_conf.pull_up_en = 0;
gpio_config(&io_conf);
}
printf("\n**** PIN recovery time ****\n\n");
for (int i = 0; i < pin_count; ++i) {
gpio_set_direction(config->pins[i], GPIO_MODE_INPUT_OUTPUT_OD);
gpio_set_level(config->pins[i], 0);
usleep(100);
gpio_set_level(config->pins[i], 1);
uint32_t cycles = get_cycles_until_pin_level(config->pins[i], 1, 10000);
printf("PIN %2d %3s %"PRIu32" cycles\n", config->pins[i], config->names[i], cycles);
}
printf("\n**** PIN recovery time with weak pullup ****\n\n");
for (int i = 0; i < pin_count; ++i) {
gpio_set_direction(config->pins[i], GPIO_MODE_INPUT_OUTPUT_OD);
gpio_pullup_en(config->pins[i]);
gpio_set_level(config->pins[i], 0);
usleep(100);
gpio_set_level(config->pins[i], 1);
uint32_t cycles = get_cycles_until_pin_level(config->pins[i], 1, 10000);
printf("PIN %2d %3s %"PRIu32" cycles\n", config->pins[i], config->names[i], cycles);
gpio_pullup_dis(config->pins[i]);
}
#if CONFIG_EXAMPLE_ENABLE_ADC_FEATURE
adc_oneshot_unit_handle_t adc_handle;
adc_oneshot_unit_init_cfg_t init_config = {
.unit_id = CONFIG_EXAMPLE_ADC_UNIT,
};
ESP_ERROR_CHECK(adc_oneshot_new_unit(&init_config, &adc_handle));
adc_cali_handle_t *adc_cali_handle = (adc_cali_handle_t *)malloc(sizeof(adc_cali_handle_t)*pin_count);
bool *do_calibration = (bool *)malloc(sizeof(bool)*pin_count);
for (int i = 0; i < pin_count; i++) {
do_calibration[i] = adc_calibration_init(CONFIG_EXAMPLE_ADC_UNIT, i, ADC_ATTEN_DB, &adc_cali_handle[i]);
}
printf("\n**** PIN voltage levels ****\n\n");
for (int i = 0; i < pin_count; ++i) {
float voltage = get_pin_voltage(config->adc_channels[i], adc_handle, do_calibration[i], adc_cali_handle[i]);
printf("PIN %2d %3s %.1fV\n", config->pins[i], config->names[i], voltage);
}
printf("\n**** PIN voltage levels with weak pullup ****\n\n");
for (int i = 0; i < pin_count; ++i) {
gpio_pullup_en(config->pins[i]);
usleep(100);
float voltage = get_pin_voltage(config->adc_channels[i], adc_handle, do_calibration[i], adc_cali_handle[i]);
printf("PIN %2d %3s %.1fV\n", config->pins[i], config->names[i], voltage);
gpio_pullup_dis(config->pins[i]);
}
printf("\n**** PIN cross-talk ****\n\n");
printf(" ");
for (int i = 0; i < pin_count; ++i) {
printf("%3s ", config->names[i]);
}
printf("\n");
for (int i = 0; i < pin_count; ++i) {
gpio_set_direction(config->pins[i], GPIO_MODE_INPUT_OUTPUT_OD);
gpio_set_level(config->pins[i], 0);
printf("PIN %2d %3s ", config->pins[i], config->names[i]);
for (int j = 0; j < pin_count; ++j) {
if (j == i) {
printf(" -- ");
continue;
}
usleep(100);
float voltage = get_pin_voltage(config->adc_channels[j], adc_handle, do_calibration[i], adc_cali_handle[i]);
printf("%1.1fV ", voltage);
}
printf("\n");
gpio_set_direction(config->pins[i], GPIO_MODE_INPUT);
}
printf("\n**** PIN cross-talk with weak pullup ****\n\n");
printf(" ");
for (int i = 0; i < pin_count; ++i) {
printf("%3s ", config->names[i]);
}
printf("\n");
for (int i = 0; i < pin_count; ++i) {
gpio_set_direction(config->pins[i], GPIO_MODE_INPUT_OUTPUT_OD);
gpio_set_level(config->pins[i], 0);
printf("PIN %2d %3s ", config->pins[i], config->names[i]);
for (int j = 0; j < pin_count; ++j) {
if (j == i) {
printf(" -- ");
continue;
}
gpio_pullup_en(config->pins[j]);
usleep(100);
float voltage = get_pin_voltage(config->adc_channels[j], adc_handle, do_calibration[i], adc_cali_handle[i]);
printf("%1.1fV ", voltage);
gpio_pullup_dis(config->pins[j]);
}
printf("\n");
gpio_set_direction(config->pins[i], GPIO_MODE_INPUT);
}
for (int i = 0; i < pin_count; ++i) {
if (do_calibration[i]) {
example_adc_calibration_deinit(adc_cali_handle[i]);
}
}
#endif //CONFIG_EXAMPLE_ENABLE_ADC_FEATURE
}

View File

@ -0,0 +1,28 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
#pragma once
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
const char** names;
const int* pins;
#if CONFIG_EXAMPLE_ENABLE_ADC_FEATURE
const int *adc_channels;
#endif
} pin_configuration_t;
void check_sd_card_pins(pin_configuration_t *config, const int pin_count);
#ifdef __cplusplus
}
#endif

View File

@ -1,6 +1,9 @@
idf_component_register(SRCS "sd_card_example_main.c"
INCLUDE_DIRS ".")
set(srcs "sd_card_example_main.c")
idf_component_register(SRCS ${srcs}
INCLUDE_DIRS "."
REQUIRES fatfs sd_card
WHOLE_ARCHIVE)
if(NOT CONFIG_SOC_SDMMC_HOST_SUPPORTED)
fail_at_build_time(sdmmc ""

View File

@ -60,4 +60,90 @@ menu "SD/MMC Example Configuration"
endif # SOC_SDMMC_USE_GPIO_MATRIX
config EXAMPLE_DEBUG_PIN_CONNECTIONS
bool "Debug sd pin connections and pullup strength"
default n
if !SOC_SDMMC_USE_GPIO_MATRIX
config EXAMPLE_PIN_CMD
depends on EXAMPLE_DEBUG_PIN_CONNECTIONS
default 15 if IDF_TARGET_ESP32
config EXAMPLE_PIN_CLK
depends on EXAMPLE_DEBUG_PIN_CONNECTIONS
default 14 if IDF_TARGET_ESP32
config EXAMPLE_PIN_D0
depends on EXAMPLE_DEBUG_PIN_CONNECTIONS
default 2 if IDF_TARGET_ESP32
if EXAMPLE_SDMMC_BUS_WIDTH_4
config EXAMPLE_PIN_D1
depends on EXAMPLE_DEBUG_PIN_CONNECTIONS
default 4 if IDF_TARGET_ESP32
config EXAMPLE_PIN_D2
depends on EXAMPLE_DEBUG_PIN_CONNECTIONS
default 12 if IDF_TARGET_ESP32
config EXAMPLE_PIN_D3
depends on EXAMPLE_DEBUG_PIN_CONNECTIONS
default 13 if IDF_TARGET_ESP32
endif # EXAMPLE_SDMMC_BUS_WIDTH_4
endif
config EXAMPLE_ENABLE_ADC_FEATURE
bool "Enable ADC feature"
depends on EXAMPLE_DEBUG_PIN_CONNECTIONS
default y if IDF_TARGET_ESP32
default n
config EXAMPLE_ADC_UNIT
int "ADC Unit"
depends on EXAMPLE_ENABLE_ADC_FEATURE
default 1 if IDF_TARGET_ESP32
default 1
config EXAMPLE_ADC_PIN_CLK
int "CLK mapped ADC pin"
depends on EXAMPLE_ENABLE_ADC_FEATURE
default 6 if IDF_TARGET_ESP32
default 1
config EXAMPLE_ADC_PIN_CMD
int "CMD mapped ADC pin"
depends on EXAMPLE_ENABLE_ADC_FEATURE
default 3 if IDF_TARGET_ESP32
default 1
config EXAMPLE_ADC_PIN_D0
int "D0 mapped ADC pin"
depends on EXAMPLE_ENABLE_ADC_FEATURE
default 2 if IDF_TARGET_ESP32
default 1
if EXAMPLE_SDMMC_BUS_WIDTH_4
config EXAMPLE_ADC_PIN_D1
int "D1 mapped ADC pin"
depends on EXAMPLE_ENABLE_ADC_FEATURE
default 0 if IDF_TARGET_ESP32
default 1
config EXAMPLE_ADC_PIN_D2
int "D2 mapped ADC pin"
depends on EXAMPLE_ENABLE_ADC_FEATURE
default 5 if IDF_TARGET_ESP32
default 1
config EXAMPLE_ADC_PIN_D3
int "D3 mapped ADC pin"
depends on EXAMPLE_ENABLE_ADC_FEATURE
default 4 if IDF_TARGET_ESP32
default 1
endif # EXAMPLE_SDMMC_BUS_WIDTH_4
endmenu

View File

@ -14,6 +14,7 @@
#include "esp_vfs_fat.h"
#include "sdmmc_cmd.h"
#include "driver/sdmmc_host.h"
#include "sd_test_io.h"
#define EXAMPLE_MAX_CHAR_SIZE 64
@ -21,6 +22,40 @@ static const char *TAG = "example";
#define MOUNT_POINT "/sdcard"
#ifdef CONFIG_EXAMPLE_DEBUG_PIN_CONNECTIONS
const char* names[] = {"CLK", "CMD", "D0", "D1", "D2", "D3"};
const int pins[] = {CONFIG_EXAMPLE_PIN_CLK,
CONFIG_EXAMPLE_PIN_CMD,
CONFIG_EXAMPLE_PIN_D0
#ifdef CONFIG_EXAMPLE_SDMMC_BUS_WIDTH_4
,CONFIG_EXAMPLE_PIN_D1,
CONFIG_EXAMPLE_PIN_D2,
CONFIG_EXAMPLE_PIN_D3
#endif
};
const int pin_count = sizeof(pins)/sizeof(pins[0]);
#if CONFIG_EXAMPLE_ENABLE_ADC_FEATURE
const int adc_channels[] = {CONFIG_EXAMPLE_ADC_PIN_CLK,
CONFIG_EXAMPLE_ADC_PIN_CMD,
CONFIG_EXAMPLE_ADC_PIN_D0
#ifdef CONFIG_EXAMPLE_SDMMC_BUS_WIDTH_4
,CONFIG_EXAMPLE_ADC_PIN_D1,
CONFIG_EXAMPLE_ADC_PIN_D2,
CONFIG_EXAMPLE_ADC_PIN_D3
#endif
};
#endif //CONFIG_EXAMPLE_ENABLE_ADC_FEATURE
pin_configuration_t config = {
.names = names,
.pins = pins,
#if CONFIG_EXAMPLE_ENABLE_ADC_FEATURE
.adc_channels = adc_channels,
#endif
};
#endif //CONFIG_EXAMPLE_DEBUG_PIN_CONNECTIONS
static esp_err_t s_example_write_file(const char *path, char *data)
{
@ -130,6 +165,9 @@ void app_main(void)
} else {
ESP_LOGE(TAG, "Failed to initialize the card (%s). "
"Make sure SD card lines have pull-up resistors in place.", esp_err_to_name(ret));
#ifdef CONFIG_EXAMPLE_DEBUG_PIN_CONNECTIONS
check_sd_card_pins(&config, pin_count);
#endif
}
return;
}

View File

@ -2,5 +2,8 @@
# in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.16)
list(APPEND EXTRA_COMPONENT_DIRS "$ENV{IDF_PATH}/examples/storage/sd_card/sdmmc/components/sd_card")
set(COMPONENTS main)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(sd_card)

View File

@ -155,3 +155,59 @@ Ensure that the board and SD card adapter you are using are powered using the ap
Attempt to reboot the board. This error may occur if you reset the ESP board or host controller without power-cycling it. In such cases, the card may remain in its previous state, causing it to potentially not respond to commands sent by the host controller.
Additionally, if the example works with certain SD cards but encounters issues with others, please confirm the read/write speed of the SD card. If the card is not compatible with the host frequency, consider lowering the host frequency and then attempting the operation again.
### Debug SD connections and pullup strength
> If the initialization of the SD card fails, initially follow the above options. If the issue persists, confirm the connection of pullups to the SD pins. To do this, enable the` Debug sd pin connections and pullup strength` option from menuconfig and rerun the code. This will provide the following result:
```
**** PIN recovery time ****
PIN 14 CLK 10049 cycles
PIN 15 MOSI 10034 cycles
PIN 2 MISO 10034 cycles
PIN 13 CS 10034 cycles
**** PIN recovery time with weak pullup ****
PIN 14 CLK 100 cycles
PIN 15 MOSI 100 cycles
PIN 2 MISO 100 cycles
PIN 13 CS 100 cycles
**** PIN voltage levels ****
PIN 14 CLK 0.6V
PIN 15 MOSI 0.4V
PIN 2 MISO 0.7V
PIN 13 CS 0.9V
**** PIN voltage levels with weak pullup ****
PIN 14 CLK 0.9V
PIN 15 MOSI 1.0V
PIN 2 MISO 1.0V
PIN 13 CS 1.2V
**** PIN cross-talk ****
CLK MOSI MISO CS
PIN 14 CLK -- 0.2V 0.2V 0.2V
PIN 15 MOSI 0.1V -- 0.1V 0.1V
PIN 2 MISO 0.1V 0.1V -- 0.1V
PIN 13 CS 0.1V 0.1V 0.1V --
**** PIN cross-talk with weak pullup ****
CLK MOSI MISO CS
PIN 14 CLK -- 1.0V 1.1V 1.2V
PIN 15 MOSI 0.9V -- 1.0V 1.2V
PIN 2 MISO 0.9V 1.0V -- 1.2V
PIN 13 CS 0.9V 1.1V 1.0V --
```
In the absence of connected pullups and having the weak pullups enabled, you can assess the pullup connections by comparing PIN recovery time measured in CPU cycles. To check pullup connections, configure the pin as open drain, set it to low state, and count the cpu cycles consumed before returning to high state. If a pullup is connected, the pin will get back to high state after reasonably small cycle count, typically around 50-300 cycles, depending on pullup strength. If no pullup is connected, the PIN stays low and the measurement times out after 10000 cycles.
It will also provide the voltage levels at the corresponding SD pins. By default, this information is provided for ESP32 chip only, and for other chipsets, verify the availability of ADC pins for the respective GPIO using [this](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/gpio.html#gpio-summary) and configure ADC mapped pins using menuconfig. Then test the voltage levels accordingly.
You can monitor the voltage levels of individual pins using `PIN voltage levels` and `PIN voltage levels with weak pullup`. However, if one pin being pulled low and experiencing interference with another pin, you can detect it through `PIN cross-talk` and `PIN cross-talk with weak pullup`. In the absence of pullups, voltage levels at each pin should range from 0 to 0.3V. With 10k pullups connected, the voltage will be between 3.1V to 3.3V, contingent on the connection between ADC pins and SD pins, and with weak pullups connected, it can fluctuate between 0.8V to 1.2V, depending on pullup strength.

View File

@ -1,2 +1,6 @@
idf_component_register(SRCS "sd_card_example_main.c"
INCLUDE_DIRS ".")
set(srcs "sd_card_example_main.c")
idf_component_register(SRCS ${srcs}
INCLUDE_DIRS "."
REQUIRES fatfs sd_card
WHOLE_ARCHIVE)

View File

@ -42,4 +42,49 @@ menu "SD SPI Example Configuration"
default 10 if IDF_TARGET_ESP32P4
default 1 # C3 and others
config EXAMPLE_DEBUG_PIN_CONNECTIONS
bool "Debug sd pin connections and pullup strength"
default n
config EXAMPLE_ENABLE_ADC_FEATURE
bool "Enable ADC feature"
depends on EXAMPLE_DEBUG_PIN_CONNECTIONS
default y if IDF_TARGET_ESP32
default n
config EXAMPLE_ADC_UNIT
int "ADC Unit"
depends on EXAMPLE_DEBUG_PIN_CONNECTIONS
default 1 if IDF_TARGET_ESP32
default 0 if IDF_TARGET_ESP32S3
default 1
config EXAMPLE_ADC_PIN_MOSI
int "MOSI mapped ADC pin"
depends on EXAMPLE_ENABLE_ADC_FEATURE
default 3 if IDF_TARGET_ESP32
default 7 if IDF_TARGET_ESP32S3
default 1
config EXAMPLE_ADC_PIN_MISO
int "MISO mapped ADC pin"
depends on EXAMPLE_ENABLE_ADC_FEATURE
default 2 if IDF_TARGET_ESP32
default 1 if IDF_TARGET_ESP32S3
default 1
config EXAMPLE_ADC_PIN_CLK
int "CLK mapped ADC pin"
depends on EXAMPLE_ENABLE_ADC_FEATURE
default 6 if IDF_TARGET_ESP32
default 0 if IDF_TARGET_ESP32S3
default 1
config EXAMPLE_ADC_PIN_CS
int "CS mapped ADC pin"
depends on EXAMPLE_ENABLE_ADC_FEATURE
default 4 if IDF_TARGET_ESP32
default 6 if IDF_TARGET_ESP32S3
default 1
endmenu

View File

@ -13,6 +13,7 @@
#include <sys/stat.h>
#include "esp_vfs_fat.h"
#include "sdmmc_cmd.h"
#include "sd_test_io.h"
#define EXAMPLE_MAX_CHAR_SIZE 64
@ -20,6 +21,30 @@ static const char *TAG = "example";
#define MOUNT_POINT "/sdcard"
#ifdef CONFIG_EXAMPLE_DEBUG_PIN_CONNECTIONS
const char* names[] = {"CLK ", "MOSI", "MISO", "CS "};
const int pins[] = {CONFIG_EXAMPLE_PIN_CLK,
CONFIG_EXAMPLE_PIN_MOSI,
CONFIG_EXAMPLE_PIN_MISO,
CONFIG_EXAMPLE_PIN_CS};
const int pin_count = sizeof(pins)/sizeof(pins[0]);
#if CONFIG_EXAMPLE_ENABLE_ADC_FEATURE
const int adc_channels[] = {CONFIG_EXAMPLE_ADC_PIN_CLK,
CONFIG_EXAMPLE_ADC_PIN_MOSI,
CONFIG_EXAMPLE_ADC_PIN_MISO,
CONFIG_EXAMPLE_ADC_PIN_CS};
#endif //CONFIG_EXAMPLE_ENABLE_ADC_FEATURE
pin_configuration_t config = {
.names = names,
.pins = pins,
#if CONFIG_EXAMPLE_ENABLE_ADC_FEATURE
.adc_channels = adc_channels,
#endif
};
#endif //CONFIG_EXAMPLE_DEBUG_PIN_CONNECTIONS
// Pin assignments can be set in menuconfig, see "SD SPI Example Configuration" menu.
// You can also change the pin assignments here by changing the following 4 lines.
#define PIN_NUM_MISO CONFIG_EXAMPLE_PIN_MISO
@ -125,6 +150,9 @@ void app_main(void)
} else {
ESP_LOGE(TAG, "Failed to initialize the card (%s). "
"Make sure SD card lines have pull-up resistors in place.", esp_err_to_name(ret));
#ifdef CONFIG_EXAMPLE_DEBUG_PIN_CONNECTIONS
check_sd_card_pins(&config, pin_count);
#endif
}
return;
}