lcd and sd card file listing works
This commit is contained in:
+207
@@ -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;
|
||||
}
|
||||
Reference in New Issue
Block a user