FluxDC/components/FluxSD/FluxSD.c

217 lines
6.1 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* @file FluxSD.c
* @brief SD卡源文件
*
* 用于存储测试日志
*
* @author wang xiang en
* @date 2025-04-18
* @version 版本号
* @copyright 版权声明((C)2025, YUWELL MEDTECH Co.ltd
*/
#include "FluxSD.h"
/* SD卡配置 */
const static char *SD_TAG = "SD_TEST";
const char* names[] = {"CLK", "CMD", "D0", "D1", "D2", "D3"};
const int pins[] = {CONFIG_EXAMPLE_PIN_CLK,
CONFIG_EXAMPLE_PIN_CMD,
CONFIG_EXAMPLE_PIN_D0,
CONFIG_EXAMPLE_PIN_D1,
CONFIG_EXAMPLE_PIN_D2,
CONFIG_EXAMPLE_PIN_D3
};
const int pin_count = sizeof(pins)/sizeof(pins[0]);
pin_configuration_t config = {
.names = names,
.pins = pins,
};
/* 用于存储 SD 卡信息 */
uint64_t total_bytes = 0;
uint64_t free_bytes = 0;
float free_percent = 0;
/**
* @brief 等待SD引脚状态改变
*
* SD卡引脚检测子函数
*
* @param[in] i 序号值
* @param[in] level 检测的电平
* @param[in] timeout 超时时间
* @return 返回值说明
*/
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;
}
/**
* @brief SD卡引脚检测
*
* 测试SD卡引脚驱动能力及配置情况
*
* @param[in] config 配置情况
* @param[in] pin_count 引脚数目
*/
void check_sd_card_pins(pin_configuration_t *config, const int pin_count)
{
ESP_LOGI(SD_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]);
}
}
static esp_err_t s_example_write_file(const char *path, char *data)
{
ESP_LOGI(SD_TAG, "Opening file %s", path);
FILE *f = fopen(path, "a");
if (f == NULL) {
ESP_LOGE(SD_TAG, "Failed to open file for writing");
return ESP_FAIL;
}
fprintf(f, data);
fclose(f);
ESP_LOGI(SD_TAG, "File written");
return ESP_OK;
}
/*向SD卡中写入日志*/
esp_err_t s_example_write_log(char *data)
{
ESP_LOGI(SD_TAG, "Opening file %s", "/sdcard/log.txt");
FILE *f = fopen("/sdcard/log.txt", "a+");
if (f == NULL) {
ESP_LOGE(SD_TAG, "Failed to open file for writing");
return ESP_FAIL;
}
fprintf(f, data);
fclose(f);
ESP_LOGI(SD_TAG, "File written");
return ESP_OK;
}
static esp_err_t s_example_read_file(const char *path)
{
ESP_LOGI(SD_TAG, "Reading file %s", path);
FILE *f = fopen(path, "r");
if (f == NULL) {
ESP_LOGE(SD_TAG, "Failed to open file for reading");
return ESP_FAIL;
}
char line[EXAMPLE_MAX_CHAR_SIZE];
fgets(line, sizeof(line), f);
//fread(line, sizeof(line), f);
fclose(f);
// strip newline
char *pos = strchr(line, '\n');
if (pos) {
*pos = '\0';
}
ESP_LOGI(SD_TAG, "Read from file: '%s'", line);
return ESP_OK;
}
void flux_sd_init(void)
{
esp_err_t ret;
esp_vfs_fat_sdmmc_mount_config_t mount_config = {
.format_if_mount_failed = true,
.max_files = 5,
.allocation_unit_size = 16 * 1024
};
sdmmc_card_t *card;
const char mount_point[] = MOUNT_POINT;
ESP_LOGI(SD_TAG, "Initializing SD card");
ESP_LOGI(SD_TAG, "Using SDMMC peripheral");
sdmmc_host_t host = SDMMC_HOST_DEFAULT();
sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT();
slot_config.width = 4;
slot_config.clk = CONFIG_EXAMPLE_PIN_CLK;
slot_config.cmd = CONFIG_EXAMPLE_PIN_CMD;
slot_config.d0 = CONFIG_EXAMPLE_PIN_D0;
slot_config.d1 = CONFIG_EXAMPLE_PIN_D1;
slot_config.d2 = CONFIG_EXAMPLE_PIN_D2;
slot_config.d3 = CONFIG_EXAMPLE_PIN_D3;
slot_config.flags |= SDMMC_SLOT_FLAG_INTERNAL_PULLUP;
ESP_LOGI(SD_TAG, "Mounting filesystem");
ret = esp_vfs_fat_sdmmc_mount(mount_point, &host, &slot_config, &mount_config, &card);
if (ret != ESP_OK) {
if (ret == ESP_FAIL) {
ESP_LOGE(SD_TAG, "Failed to mount filesystem. "
"If you want the card to be formatted, set the EXAMPLE_FORMAT_IF_MOUNT_FAILED menuconfig option.");
} else {
ESP_LOGE(SD_TAG, "Failed to initialize the card (%s). "
"Make sure SD card lines have pull-up resistors in place.", esp_err_to_name(ret));
check_sd_card_pins(&config, pin_count);
}
return;
}
ESP_LOGI(SD_TAG, "Filesystem mounted");
sdmmc_card_print_info(stdout, card);
#ifdef CONFIG_WRITE_TEST
/* File write test example */
const char *file_hello = MOUNT_POINT"/hello.txt";
char data[EXAMPLE_MAX_CHAR_SIZE];
snprintf(data, EXAMPLE_MAX_CHAR_SIZE, "%s %s!\n", "Hello how are you", card->cid.name);
ret = s_example_write_file(file_hello, data);
if (ret != ESP_OK) {
return;
}
#endif
}