From 5cb1325c6a94dc76ab36db9940f6fdf6b323a8b7 Mon Sep 17 00:00:00 2001 From: Advaith Menon Date: Mon, 24 Nov 2025 19:59:46 -0500 Subject: [PATCH] Add basic SD Card Support * Support reading from an SD card * Check for the presence of readme.txt file --- main/CMakeLists.txt | 6 ++- main/hello_world_main.c | 2 + main/pins.h | 9 ++++ main/sdcardspi.c | 110 ++++++++++++++++++++++++++++++++++++++++ main/sdcardspi.h | 18 +++++++ main/task_lcd.c | 2 +- 6 files changed, 145 insertions(+), 2 deletions(-) create mode 100644 main/sdcardspi.c create mode 100644 main/sdcardspi.h diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index 80ac656..492e8c4 100644 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -2,6 +2,10 @@ idf_component_register(SRCS "hello_world_main.c" "goldeloxSerial.c" "task_lcd.c" "task_button.c" + "sdcardspi.c" INCLUDE_DIRS "." PRIV_REQUIRES esp_driver_gpio - esp_driver_uart) + esp_driver_uart + esp_driver_spi + esp_driver_sdspi + fatfs) diff --git a/main/hello_world_main.c b/main/hello_world_main.c index eb152a4..17725db 100644 --- a/main/hello_world_main.c +++ b/main/hello_world_main.c @@ -14,6 +14,7 @@ #include "pins.h" #include "task_lcd.h" #include "task_button.h" +#include "sdcardspi.h" @@ -51,6 +52,7 @@ void app_main(void) /* initialize the buttons */ gt_btn_setup(); + task_sdcard(); /* start the main gui thread which starts all else */ lcd_task(); diff --git a/main/pins.h b/main/pins.h index 04623f4..c3f1046 100644 --- a/main/pins.h +++ b/main/pins.h @@ -11,8 +11,17 @@ #define PIN_BUTTON_BLUE 18 #define PIN_BUTTON_RED 15 #define PIN_VIBRATOR 20 + #define PIN_ULCD_TX 23 #define PIN_ULCD_RX 22 #define PIN_ULCD_RESET 19 +#define PIN_SD_CS 7 +#define PIN_SD_CD 6 +#define PIN_SD_MOSI 9 +#define PIN_SD_MISO 1 +#define PIN_SD_SCK 21 +#define SD_MOUNT_PATH "/mnt/sdcard0" +#define SD_MAX_FILE_HANDLES 5 + #endif diff --git a/main/sdcardspi.c b/main/sdcardspi.c new file mode 100644 index 0000000..9284f72 --- /dev/null +++ b/main/sdcardspi.c @@ -0,0 +1,110 @@ +#include +#include + +#include "esp_vfs_fat.h" +#include "sdmmc_cmd.h" +#include "esp_system.h" +#include "esp_err.h" +#include "esp_log.h" +#include "hal/spi_types.h" + +#include "sdcardspi.h" +#include "pins.h" + +#define SPI_UNUSED -1 +#define SPI_MAX_TRANSFER_BYTES 4000 + +/* code largely adapted from ESP-IDF examples: sd_card/sdspi */ + +/* constants */ +const char *TAG = "sdcardspi"; +/* the sdcard handle itself */ +sdmmc_card_t *sdmmc; +/* the sd card mount path */ +const char *mntpath = SD_MOUNT_PATH; +sdmmc_host_t host = SDSPI_HOST_DEFAULT(); + + +uint8_t check_valid_swos_fhs(void); + + +uint8_t task_sdcard() { + esp_err_t nzec; + + /* set up mount config */ + esp_vfs_fat_sdmmc_mount_config_t mount_cfg = { + .format_if_mount_failed = false, + .max_files = SD_MAX_FILE_HANDLES + }; + + const spi_bus_config_t spi_bus_cfg = { + .mosi_io_num = PIN_SD_MOSI, + .miso_io_num = PIN_SD_MISO, + .sclk_io_num = PIN_SD_SCK, + .quadwp_io_num = SPI_UNUSED, + .quadhd_io_num = SPI_UNUSED, + .max_transfer_sz = SPI_MAX_TRANSFER_BYTES + }; + + sdspi_device_config_t slot_cfg = SDSPI_DEVICE_CONFIG_DEFAULT(); + slot_cfg.gpio_cs = PIN_SD_CS; + slot_cfg.host_id = host.slot; + + ESP_LOGI(TAG, "Initializing card with mount point: %s", mntpath); + if (spi_bus_initialize(host.slot, &spi_bus_cfg, + SDSPI_DEFAULT_DMA) != ESP_OK) { + ESP_LOGE(TAG, "SPI bus initialization failed!"); + return 0; + } + + + + nzec = esp_vfs_fat_sdspi_mount(mntpath, &host, &slot_cfg, &mount_cfg, + &sdmmc); + + if (nzec != ESP_OK) { + if (nzec == ESP_FAIL) { + ESP_LOGE(TAG, "Failed to mount filesystem. Run a disk repair " + "tool to correct errors."); + } else { + ESP_LOGE(TAG, "Failed to initialize SD card (%s).", + esp_err_to_name(nzec)); + } + return 0; + } + + ESP_LOGI(TAG, "SD FATfs mounted successfully."); + sdmmc_card_print_info(stdout, sdmmc); + + if (check_valid_swos_fhs()) { + esp_vfs_fat_sdcard_unmount(mntpath, sdmmc); + ESP_LOGI(TAG, "Card unmounted since this isn't a valid SWOS system"); + + //deinitialize the bus after all devices are removed + spi_bus_free(host.slot); + } + return 1; +} + + +uint8_t check_valid_swos_fhs() { + char txtdata[128]; + size_t x; + FILE *fp = fopen(SD_PATH("README.txt"), "rb"); + + if (!fp) { + ESP_LOGE(TAG, "The file %s is missing!", SD_PATH("README.txt")); + return 1; + } + + ESP_LOGI(TAG, "Found README.txt"); + while ((x = fread(txtdata, sizeof(char), 127, fp))) { + txtdata[x + 1] = '\0'; + printf(txtdata); + } + fflush(stdout); + + fclose(fp); + return 0; +} + diff --git a/main/sdcardspi.h b/main/sdcardspi.h new file mode 100644 index 0000000..63de4b9 --- /dev/null +++ b/main/sdcardspi.h @@ -0,0 +1,18 @@ +/** + * @file sdcardspi.h + * @brief SD Card Mounter + */ +#pragma once + +#ifndef __SDCARDSPI_H__ +#define __SDCARDSPI_H__ +#include + +#define SD_PATH(x) SD_MOUNT_PATH "/" x +/** + * @brief Set up SD Card Communication. + * @return Return a bool indicating if the SD card can be used. + */ +uint8_t task_sdcard(void); + +#endif diff --git a/main/task_lcd.c b/main/task_lcd.c index ac6b746..97de30d 100644 --- a/main/task_lcd.c +++ b/main/task_lcd.c @@ -35,7 +35,7 @@ struct app_t applist[NUM_APPS] = { .icon.width = 0, .icon.height = 0, .icon.data = NULL, - .name = "SWOS Flash" + .name = "About SWOS" } }; -- 2.47.3