|
| 1 | +#include "odroid_sdcard.h" |
| 2 | + |
| 3 | +//#include "esp_err.h" |
| 4 | +#include "esp_log.h" |
| 5 | +#include "esp_vfs_fat.h" |
| 6 | +#include "driver/sdmmc_host.h" |
| 7 | +#include "driver/sdspi_host.h" |
| 8 | +#include "sdmmc_cmd.h" |
| 9 | +#include "esp_heap_caps.h" |
| 10 | +#include "esp_spiffs.h" |
| 11 | + |
| 12 | +#include <dirent.h> |
| 13 | +#include <string.h> |
| 14 | +#include <unistd.h> |
| 15 | +#include <ctype.h> |
| 16 | + |
| 17 | + |
| 18 | + |
| 19 | +#define SD_PIN_NUM_MISO 19 |
| 20 | +#define SD_PIN_NUM_MOSI 23 |
| 21 | +#define SD_PIN_NUM_CLK 18 |
| 22 | +#define SD_PIN_NUM_CS 22 |
| 23 | + |
| 24 | + |
| 25 | +static bool isOpen = false; |
| 26 | + |
| 27 | + |
| 28 | +esp_err_t odroid_sdcard_open(const char* base_path) |
| 29 | +{ |
| 30 | + esp_err_t ret; |
| 31 | + |
| 32 | + if (isOpen) |
| 33 | + { |
| 34 | + printf("odroid_sdcard_open: alread open.\n"); |
| 35 | + ret = ESP_FAIL; |
| 36 | + } |
| 37 | + else |
| 38 | + { |
| 39 | + sdmmc_host_t host = SDSPI_HOST_DEFAULT(); |
| 40 | + host.slot = HSPI_HOST; // HSPI_HOST; |
| 41 | + //host.max_freq_khz = SDMMC_FREQ_HIGHSPEED; //10000000; |
| 42 | + host.max_freq_khz = SDMMC_FREQ_DEFAULT; |
| 43 | + |
| 44 | + sdspi_slot_config_t slot_config = SDSPI_SLOT_CONFIG_DEFAULT(); |
| 45 | + slot_config.gpio_miso = (gpio_num_t)SD_PIN_NUM_MISO; |
| 46 | + slot_config.gpio_mosi = (gpio_num_t)SD_PIN_NUM_MOSI; |
| 47 | + slot_config.gpio_sck = (gpio_num_t)SD_PIN_NUM_CLK; |
| 48 | + slot_config.gpio_cs = (gpio_num_t)SD_PIN_NUM_CS; |
| 49 | + //slot_config.dma_channel = 2; |
| 50 | + |
| 51 | + // Options for mounting the filesystem. |
| 52 | + // If format_if_mount_failed is set to true, SD card will be partitioned and |
| 53 | + // formatted in case when mounting fails. |
| 54 | + esp_vfs_fat_sdmmc_mount_config_t mount_config; |
| 55 | + memset(&mount_config, 0, sizeof(mount_config)); |
| 56 | + |
| 57 | + mount_config.format_if_mount_failed = false; |
| 58 | + mount_config.max_files = 5; |
| 59 | + |
| 60 | + |
| 61 | + // Use settings defined above to initialize SD card and mount FAT filesystem. |
| 62 | + // Note: esp_vfs_fat_sdmmc_mount is an all-in-one convenience function. |
| 63 | + // Please check its source code and implement error recovery when developing |
| 64 | + // production applications. |
| 65 | + sdmmc_card_t* card; |
| 66 | + ret = esp_vfs_fat_sdmmc_mount(base_path, &host, &slot_config, &mount_config, &card); |
| 67 | + |
| 68 | + if (ret == ESP_OK) |
| 69 | + { |
| 70 | + isOpen = true; |
| 71 | + } |
| 72 | + else |
| 73 | + { |
| 74 | + printf("odroid_sdcard_open: esp_vfs_fat_sdmmc_mount failed (%d)\n", ret); |
| 75 | + } |
| 76 | + } |
| 77 | + |
| 78 | + return ret; |
| 79 | +} |
| 80 | + |
| 81 | + |
| 82 | +esp_err_t odroid_sdcard_close() |
| 83 | +{ |
| 84 | + esp_err_t ret; |
| 85 | + |
| 86 | + if (!isOpen) |
| 87 | + { |
| 88 | + printf("odroid_sdcard_close: not open.\n"); |
| 89 | + ret = ESP_FAIL; |
| 90 | + } |
| 91 | + else |
| 92 | + { |
| 93 | + ret = esp_vfs_fat_sdmmc_unmount(); |
| 94 | + |
| 95 | + if (ret != ESP_OK) |
| 96 | + { |
| 97 | + printf("odroid_sdcard_close: esp_vfs_fat_sdmmc_unmount failed (%d)\n", ret); |
| 98 | + } |
| 99 | + |
| 100 | + isOpen = false; |
| 101 | + } |
| 102 | + |
| 103 | + return ret; |
| 104 | +} |
| 105 | + |
| 106 | + |
| 107 | +size_t odroid_sdcard_get_filesize(const char* path) |
| 108 | +{ |
| 109 | + size_t ret = 0; |
| 110 | + |
| 111 | + if (!isOpen) |
| 112 | + { |
| 113 | + printf("odroid_sdcard_get_filesize: not open.\n"); |
| 114 | + } |
| 115 | + else |
| 116 | + { |
| 117 | + FILE* f = fopen(path, "rb"); |
| 118 | + if (f == NULL) |
| 119 | + { |
| 120 | + printf("odroid_sdcard_get_filesize: fopen failed.\n"); |
| 121 | + } |
| 122 | + else |
| 123 | + { |
| 124 | + // get the file size |
| 125 | + fseek(f, 0, SEEK_END); |
| 126 | + ret = ftell(f); |
| 127 | + fseek(f, 0, SEEK_SET); |
| 128 | + } |
| 129 | + } |
| 130 | + |
| 131 | + return ret; |
| 132 | +} |
| 133 | + |
| 134 | +size_t odroid_sdcard_copy_file_to_memory(const char* path, void* ptr) |
| 135 | +{ |
| 136 | + size_t ret = 0; |
| 137 | + |
| 138 | + if (!isOpen) |
| 139 | + { |
| 140 | + printf("odroid_sdcard_copy_file_to_memory: not open.\n"); |
| 141 | + } |
| 142 | + else |
| 143 | + { |
| 144 | + if (!ptr) |
| 145 | + { |
| 146 | + printf("odroid_sdcard_copy_file_to_memory: ptr is null.\n"); |
| 147 | + } |
| 148 | + else |
| 149 | + { |
| 150 | + FILE* f = fopen(path, "rb"); |
| 151 | + if (f == NULL) |
| 152 | + { |
| 153 | + printf("odroid_sdcard_copy_file_to_memory: fopen failed.\n"); |
| 154 | + } |
| 155 | + else |
| 156 | + { |
| 157 | + // copy |
| 158 | + const size_t BLOCK_SIZE = 512; |
| 159 | + while(true) |
| 160 | + { |
| 161 | + __asm__("memw"); |
| 162 | + size_t count = fread((uint8_t*)ptr + ret, 1, BLOCK_SIZE, f); |
| 163 | + __asm__("memw"); |
| 164 | + |
| 165 | + ret += count; |
| 166 | + |
| 167 | + if (count < BLOCK_SIZE) break; |
| 168 | + } |
| 169 | + } |
| 170 | + } |
| 171 | + } |
| 172 | + |
| 173 | + return ret; |
| 174 | +} |
| 175 | + |
| 176 | +char* odroid_sdcard_create_savefile_path(const char* base_path, const char* fileName) |
| 177 | +{ |
| 178 | + char* result = NULL; |
| 179 | + |
| 180 | + if (!base_path) abort(); |
| 181 | + if (!fileName) abort(); |
| 182 | + |
| 183 | + //printf("%s: base_path='%s', fileName='%s'\n", __func__, base_path, fileName); |
| 184 | + |
| 185 | + // Determine folder |
| 186 | + char* extension = fileName + strlen(fileName); // place at NULL terminator |
| 187 | + while (extension != fileName) |
| 188 | + { |
| 189 | + if (*extension == '.') |
| 190 | + { |
| 191 | + ++extension; |
| 192 | + break; |
| 193 | + } |
| 194 | + --extension; |
| 195 | + } |
| 196 | + |
| 197 | + if (extension == fileName) |
| 198 | + { |
| 199 | + printf("%s: File extention not found.\n", __func__); |
| 200 | + abort(); |
| 201 | + } |
| 202 | + |
| 203 | + extension = "lynx"; |
| 204 | + |
| 205 | + //printf("%s: extension='%s'\n", __func__, extension); |
| 206 | + |
| 207 | + const char* DATA_PATH = "/odroid/data/"; |
| 208 | + const char* SAVE_EXTENSION = ".sav"; |
| 209 | + |
| 210 | + size_t savePathLength = strlen(base_path) + strlen(DATA_PATH) + strlen(extension) + 1 + strlen(fileName) + strlen(SAVE_EXTENSION) + 1; |
| 211 | + char* savePath = malloc(savePathLength); |
| 212 | + if (savePath) |
| 213 | + { |
| 214 | + strcpy(savePath, base_path); |
| 215 | + strcat(savePath, DATA_PATH); |
| 216 | + strcat(savePath, extension); |
| 217 | + //strcat(savePath, "lynx"); |
| 218 | + strcat(savePath, "/"); |
| 219 | + strcat(savePath, fileName); |
| 220 | + strcat(savePath, SAVE_EXTENSION); |
| 221 | + |
| 222 | + printf("%s: savefile_path='%s'\n", __func__, savePath); |
| 223 | + |
| 224 | + result = savePath; |
| 225 | + } |
| 226 | + |
| 227 | + return result; |
| 228 | +} |
0 commit comments