lcd and sd card file listing works

This commit is contained in:
Timo Niemann
2026-06-30 15:32:18 +02:00
commit 229d828271
12 changed files with 4293 additions and 0 deletions
+207
View File
@@ -0,0 +1,207 @@
#include <string.h>
#include <dirent.h>
#include <stdlib.h>
#include <stdint.h>
#include <sys/unistd.h>
#include <sys/stat.h>
#include "sd/sd.h"
#include "esp_err.h"
#include "esp_log.h"
#include "esp_vfs_fat.h"
#include "sdmmc_cmd.h"
#include "driver/gpio.h"
#include "driver/sdspi_host.h"
#include "driver/spi_common.h"
#define MAX_CHAR_SIZE 64
#define MOUNT_POINT "/sdcard"
#define SD_PIN_MOSI (GPIO_NUM_11)
#define SD_PIN_MISO (GPIO_NUM_13)
#define SD_PIN_CLK (GPIO_NUM_12)
#define SD_PIN_CS (GPIO_NUM_10)
static sdmmc_card_t* card = NULL;
static const char *TAG = "sd";
static char** _file_list = NULL;
static size_t _current_file = 0;
static size_t _file_count = 0;
static esp_err_t get_top_level_files(void);
void sd_init(void){
if(card != NULL){
ESP_LOGW(TAG, "SD card already initialized");
return;
}
sdmmc_host_t host = SDSPI_HOST_DEFAULT();
host.unaligned_multi_block_rw_max_chunk_size = 8;
spi_bus_config_t bus_config = {
.mosi_io_num = SD_PIN_MOSI,
.miso_io_num = SD_PIN_MISO,
.sclk_io_num = SD_PIN_CLK,
.quadwp_io_num = GPIO_NUM_NC,
.quadhd_io_num = GPIO_NUM_NC,
.max_transfer_sz = 4000,
};
esp_err_t ret = spi_bus_initialize(host.slot, &bus_config, SDSPI_DEFAULT_DMA);
if(ret != ESP_OK){
ESP_LOGE(TAG, "Failed to initialize SD SPI bus (%s)", esp_err_to_name(ret));
return;
}
sdspi_device_config_t slot_config = SDSPI_DEVICE_CONFIG_DEFAULT();
slot_config.gpio_cs = SD_PIN_CS;
slot_config.host_id = host.slot;
esp_vfs_fat_sdmmc_mount_config_t mount_config = {
.format_if_mount_failed = false,
.max_files = MAX_SIMULTANEOUS_OPEN_FILES,
.allocation_unit_size = 16 * 1024
};
const char mount_point[] = MOUNT_POINT;
ret = esp_vfs_fat_sdspi_mount(mount_point, &host, &slot_config, &mount_config, &card);
if(ret != ESP_OK){
if(ret == ESP_FAIL) ESP_LOGE(TAG, "Failed to mount filesystem.");
else ESP_LOGE(TAG, "Failed to initialize the card (%s). ", esp_err_to_name(ret));
spi_bus_free(host.slot);
return;
}
ESP_LOGI(TAG, "SD card initialized");
if(get_top_level_files() == ESP_OK) ESP_LOGI(TAG, "Found %d files in root directory", _file_count);
else ESP_LOGW(TAG, "No files found in root directory");
}
void print_sd_card_info(void){
if(card == NULL) return;
sdmmc_card_print_info(stdout, card);
}
static inline void make_file_path(char* buffer, size_t buffer_size, const char* filename){
snprintf(buffer, buffer_size, "%s/%s", MOUNT_POINT, filename);
}
FILE* sd_open_read(const char* filename){
if(filename == NULL) return NULL;
char full_path[strlen(MOUNT_POINT) + strlen(filename) + 2];
make_file_path(full_path, sizeof(full_path), filename);
return fopen(full_path, "r");
}
FILE* sd_open_write(const char* filename){
if(filename == NULL) return NULL;
char full_path[strlen(MOUNT_POINT) + strlen(filename) + 2];
make_file_path(full_path, sizeof(full_path), filename);
return fopen(full_path, "w");
}
void sd_close_file(FILE* file){
if(file != NULL) fclose(file);
}
static esp_err_t get_top_level_files(void){
char** file_list = NULL;
size_t count = 0;
size_t capacity = 0;
DIR* dir = opendir(MOUNT_POINT);
if(dir == NULL){
ESP_LOGE(TAG, "Failed to open directory: %s", MOUNT_POINT);
return ESP_FAIL;
}
struct dirent* entry;
while((entry = readdir(dir)) != NULL){
if(entry->d_type == DT_REG){
ESP_LOGI(TAG, "Found file: %s", entry->d_name);
size_t name_length = strlen(entry->d_name);
if(name_length >= MAX_CHAR_SIZE){
ESP_LOGW(TAG, "File name too long: %s", entry->d_name);
continue;
}
if(count == capacity){
size_t new_capacity = capacity == 0 ? 8 : capacity * 2;
char** new_file_list = (char**)realloc(file_list, sizeof(char*) * new_capacity);
if(new_file_list == NULL){
ESP_LOGE(TAG, "Failed to allocate memory for file list");
for(size_t j = 0; j < count; j++) free(file_list[j]);
free(file_list);
closedir(dir);
return ESP_FAIL;
}
file_list = new_file_list;
capacity = new_capacity;
}
file_list[count] = (char*)malloc(sizeof(char) * (name_length + 1));
if(file_list[count] == NULL){
ESP_LOGE(TAG, "Failed to allocate memory for file name");
for(size_t j = 0; j < count; j++) free(file_list[j]);
free(file_list);
closedir(dir);
return ESP_FAIL;
}
memcpy(file_list[count], entry->d_name, name_length + 1);
count++;
}
}
closedir(dir);
if(count == 0){
ESP_LOGW(TAG, "No files found in directory: %s", MOUNT_POINT);
free(file_list);
_file_list = NULL;
_current_file = 0;
return ESP_FAIL;
}
_file_list = file_list;
_file_count = count;
return ESP_OK;
}
size_t sd_get_file_count(void){
return _file_count;
}
const char* sd_get_next_file(void){
if(_current_file >= _file_count) _current_file = 0;
return _file_list[_current_file++];
}
const char* sd_get_previous_file(void){
if(_current_file == 0) _current_file = _file_count;
return _file_list[--_current_file];
}
void sd_destroy(void){
if(card != NULL){
esp_vfs_fat_sdcard_unmount(MOUNT_POINT, card);
card = NULL;
ESP_LOGI(TAG, "SD card unmounted");
}
if(_file_list != NULL){
for(int i = 0; i < _file_count; i++) free((void*)_file_list[i]);
free((void*)_file_list);
_file_list = NULL;
}
_file_count = 0;
_current_file = 0;
}
+18
View File
@@ -0,0 +1,18 @@
#pragma once
#include <stdio.h>
#define MAX_SIMULTANEOUS_OPEN_FILES 2
void sd_init(void);
void sd_destroy(void);
void print_sd_card_info(void);
FILE* sd_open_read(const char* filename);
FILE* sd_open_write(const char* filename);
void sd_close_file(FILE* file);
size_t sd_get_file_count(void);
const char* sd_get_next_file(void);
const char* sd_get_previous_file(void);