aboutsummaryrefslogtreecommitdiff
path: root/libiot/vfs/fat.c
diff options
context:
space:
mode:
Diffstat (limited to 'libiot/vfs/fat.c')
-rw-r--r--libiot/vfs/fat.c453
1 files changed, 453 insertions, 0 deletions
diff --git a/libiot/vfs/fat.c b/libiot/vfs/fat.c
new file mode 100644
index 0000000..d612277
--- /dev/null
+++ b/libiot/vfs/fat.c
@@ -0,0 +1,453 @@
+/*
+ * Copyright (C) 2015 - 2018, IBEROXARXA SERVICIOS INTEGRALES, S.L.
+ * Copyright (C) 2015 - 2018, Jaume Olivé Petrus (jolive@whitecatboard.org)
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the <organization> nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ * * The WHITECAT logotype cannot be changed, you can remove it, but you
+ * cannot change it in any way. The WHITECAT logotype is:
+ *
+ * /\ /\
+ * / \_____/ \
+ * /_____________\
+ * W H I T E C A T
+ *
+ * * Redistributions in binary form must retain all copyright notices printed
+ * to any local or remote output device. This include any reference to
+ * Lua RTOS, whitecatboard.org, Lua, and other copyright notices that may
+ * appear in the future.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Lua RTOS fat vfs
+ *
+ */
+
+#include "sdkconfig.h"
+
+#if (CONFIG_SD_CARD_MMC || CONFIG_SD_CARD_SPI) && CONFIG_LUA_RTOS_USE_FAT
+
+#include <stdio.h>
+
+#include "esp_vfs.h"
+
+#include "esp_err.h"
+#include "esp_log.h"
+#include "esp_vfs_fat.h"
+#include "driver/sdmmc_host.h"
+#include "driver/sdspi_host.h"
+#include "sdmmc_cmd.h"
+#include "driver/sdmmc_defs.h"
+
+#include <drivers/gpio.h>
+#include <drivers/spi.h>
+#include <drivers/power_bus.h>
+
+#include <sys/driver.h>
+#include <sys/mount.h>
+#include <sys/syslog.h>
+
+#include <sys/vfs/vfs.h>
+
+int vfs_fat_mount(const char *target) {
+#if CONFIG_SD_CARD_SPI
+ spi_bus_t *spi_bus = get_spi_info();
+
+ #if CONFIG_LUA_RTOS_USE_HARDWARE_LOCKS
+ // Lock resources
+ if (spi_lock_bus_resources(CONFIG_LUA_RTOS_SD_SPI, DRIVER_ALL_FLAGS)) {
+ return -1;
+ }
+
+ if (driver_lock(SYSTEM_DRIVER, 0, GPIO_DRIVER, CONFIG_LUA_RTOS_SD_CS, DRIVER_ALL_FLAGS, "SD Card - CS")) {
+ return -1;
+ }
+ #endif // CONFIG_LUA_RTOS_USE_HARDWARE_LOCKS
+
+ sdmmc_host_t host = SDSPI_HOST_DEFAULT();
+ sdspi_slot_config_t slot_config = SDSPI_SLOT_CONFIG_DEFAULT();
+
+ #if (CONFIG_LUA_RTOS_SD_SPI == 2)
+ host.slot = HSPI_HOST;
+
+ slot_config.gpio_miso = CONFIG_LUA_RTOS_SPI2_MISO;
+ slot_config.gpio_mosi = CONFIG_LUA_RTOS_SPI2_MOSI;
+ slot_config.gpio_sck = CONFIG_LUA_RTOS_SPI2_CLK;
+ slot_config.gpio_cs = CONFIG_LUA_RTOS_SD_CS;
+ #endif // (CONFIG_LUA_RTOS_SD_SPI == 2)
+
+ #if (CONFIG_LUA_RTOS_SD_SPI == 3)
+ host.slot = VSPI_HOST;
+
+ slot_config.gpio_miso = CONFIG_LUA_RTOS_SPI3_MISO;
+ slot_config.gpio_mosi = CONFIG_LUA_RTOS_SPI3_MOSI;
+ slot_config.gpio_sck = CONFIG_LUA_RTOS_SPI3_CLK;
+ slot_config.gpio_cs = CONFIG_LUA_RTOS_SD_CS;
+ #endif // (CONFIG_LUA_RTOS_SD_SPI == 3)
+
+ spi_bus[spi_idx(CONFIG_LUA_RTOS_SD_SPI)].setup |= SPI_DMA_SETUP;
+#endif // CONFIG_SD_CARD_SPI
+
+#if CONFIG_SD_CARD_MMC
+ sdmmc_host_t host = SDMMC_HOST_DEFAULT();
+ sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT();
+
+ slot_config.gpio_cd = CONFIG_LUA_RTOS_MCC_CD;
+ slot_config.gpio_wp = CONFIG_LUA_RTOS_MCC_WP;
+
+ #if CONFIG_LUA_RTOS_USE_HARDWARE_LOCKS
+ // Lock resources
+ if (driver_lock(SYSTEM_DRIVER, 0, GPIO_DRIVER, 15, DRIVER_ALL_FLAGS, "SD Card - CMD")) {
+ return -1;
+ }
+
+ if (driver_lock(SYSTEM_DRIVER, 0, GPIO_DRIVER, 14, DRIVER_ALL_FLAGS, "SD Card - CLK")) {
+ return -1;
+ }
+
+ if (driver_lock(SYSTEM_DRIVER, 0, GPIO_DRIVER, 2, DRIVER_ALL_FLAGS, "SD Card - DAT0")) {
+ return -1;
+ }
+ #endif // CONFIG_LUA_RTOS_USE_HARDWARE_LOCKS
+
+ gpio_pin_pullup(2);
+ gpio_pin_pullup(14);
+ gpio_pin_pullup(15);
+
+ #if CONFIG_LUA_RTOS_MCC_1_LINE
+ host.flags = SDMMC_HOST_FLAG_1BIT;
+ slot_config.width = 1;
+ #endif // CONFIG_LUA_RTOS_MCC_1_LINE
+
+ #if CONFIG_LUA_RTOS_MCC_4_LINE
+ host.flags = SDMMC_HOST_FLAG_4BIT;
+ slot_config.width = 4;
+
+ gpio_pin_pullup(4);
+ gpio_pin_pullup(12);
+ gpio_pin_pullup(13);
+
+ #if CONFIG_LUA_RTOS_USE_HARDWARE_LOCKS
+ if (driver_lock(SYSTEM_DRIVER, 0, GPIO_DRIVER, 4, DRIVER_ALL_FLAGS, "SD Card - DAT1")) {
+ return -1;
+ }
+
+ if (driver_lock(SYSTEM_DRIVER, 0, GPIO_DRIVER, 12, DRIVER_ALL_FLAGS, "SD Card - DAT2")) {
+ return -1;
+ }
+
+ if (driver_lock(SYSTEM_DRIVER, 0, GPIO_DRIVER, 13, DRIVER_ALL_FLAGS, "SD Card - DAT3")) {
+ return -1;
+ }
+ #endif // CONFIG_LUA_RTOS_USE_HARDWARE_LOCKS
+ #endif // CONFIG_LUA_RTOS_MCC_4_LINE
+
+ #if CONFIG_LUA_RTOS_MCC_CD != -1
+ if (driver_lock(SYSTEM_DRIVER, 0, GPIO_DRIVER, CONFIG_LUA_RTOS_MCC_CD, DRIVER_ALL_FLAGS, "SD Card - CD")) {
+ return -1;
+ }
+ #endif // CONFIG_LUA_RTOS_MCC_CD
+
+ #if CONFIG_LUA_RTOS_MCC_WP != -1
+ if (driver_lock(SYSTEM_DRIVER, 0, GPIO_DRIVER, CONFIG_LUA_RTOS_MCC_WP, DRIVER_ALL_FLAGS, "SD Card - WP")) {
+ return -1;
+ }
+ #endif // CONFIG_LUA_RTOS_MCC_WP
+#endif // CONFIG_SD_CARD_MMC
+
+#if CONFIG_LUA_RTOS_SD_CONNECTED_TO_POWER_BUS
+ pwbus_on();
+#endif
+
+ esp_vfs_fat_sdmmc_mount_config_t mount_config = {
+ .format_if_mount_failed = false,
+ .max_files = 5
+ };
+
+ #if CONFIG_SD_CARD_SPI
+ syslog(LOG_INFO, "sd is at spi%d, cs=%s%d",
+ CONFIG_LUA_RTOS_SD_SPI,
+ gpio_portname(CONFIG_LUA_RTOS_SD_CS), gpio_name(CONFIG_LUA_RTOS_SD_CS)
+ );
+ #endif
+
+ #if CONFIG_SD_CARD_MMC
+ syslog(LOG_INFO, "sd is at mmc0");
+ #endif
+
+ sdmmc_card_t* card;
+ esp_err_t ret = esp_vfs_fat_sdmmc_mount("/fat", &host, &slot_config, &mount_config, &card);
+ if (ret != ESP_OK) {
+ syslog(LOG_INFO, "fat can't mounted (error %d)", ret);
+ vfs_fat_umount(target);
+ return -1;
+ }
+
+ syslog(LOG_INFO, "sd name %s", card->cid.name);
+ syslog(LOG_INFO, "sd type %s", (card->ocr & SD_OCR_SDHC_CAP)?"SDHC/SDXC":"SDSC");
+ syslog(LOG_INFO, "sd working at %s", (card->csd.tr_speed > 25000000)?"high speed":"default speed");
+ syslog(LOG_INFO, "sd size %.2f GB",
+ ((((double)card->csd.capacity) * ((double)card->csd.sector_size)) / 1073741824.0)
+ );
+
+ syslog(LOG_INFO, "sd CSD ver=%d, sector_size=%d, capacity=%d read_bl_len=%d",
+ card->csd.csd_ver,
+ card->csd.sector_size, card->csd.capacity, card->csd.read_block_len
+ );
+
+ syslog(LOG_INFO, "sd SCR sd_spec=%d, bus_width=%d", card->scr.sd_spec, card->scr.bus_width);
+
+ syslog(LOG_INFO, "fat mounted on %s", target);
+
+ return 0;
+}
+
+int vfs_fat_umount(const char *target) {
+ // Unmount
+ esp_vfs_fat_sdmmc_unmount();
+
+#if CONFIG_LUA_RTOS_USE_HARDWARE_LOCKS
+ #if CONFIG_SD_CARD_SPI
+ spi_bus_t *spi_bus = get_spi_info();
+
+ // Unlock resources
+ spi_unlock_bus_resources(CONFIG_LUA_RTOS_SD_SPI);
+ driver_unlock(SYSTEM_DRIVER, 0, GPIO_DRIVER, CONFIG_LUA_RTOS_SD_CS);
+ spi_bus[spi_idx(CONFIG_LUA_RTOS_SD_SPI)].setup &= ~SPI_DMA_SETUP;
+ #endif // CONFIG_SD_CARD_SPI
+
+ #if CONFIG_SD_CARD_MMC
+ // Unlock resources
+ driver_unlock(SYSTEM_DRIVER, 0, GPIO_DRIVER, 15);
+ driver_unlock(SYSTEM_DRIVER, 0, GPIO_DRIVER, 14);
+ driver_unlock(SYSTEM_DRIVER, 0, GPIO_DRIVER, 2);
+
+ #if CONFIG_LUA_RTOS_MCC_4_LINE
+ driver_unlock(SYSTEM_DRIVER, 0, GPIO_DRIVER, 14);
+ driver_unlock(SYSTEM_DRIVER, 0, GPIO_DRIVER, 12);
+ driver_unlock(SYSTEM_DRIVER, 0, GPIO_DRIVER, 13);
+ #endif
+
+ #if CONFIG_LUA_RTOS_MCC_CD != -1
+ driver_unlock(SYSTEM_DRIVER, 0, GPIO_DRIVER, CONFIG_LUA_RTOS_MCC_CD);
+ #endif
+
+ #if CONFIG_LUA_RTOS_MCC_WP != -1
+ driver_unlock(SYSTEM_DRIVER, 0, GPIO_DRIVER, CONFIG_LUA_RTOS_MCC_WP);
+ #endif
+ #endif // CONFIG_SD_CARD_MMC
+#endif // CONFIG_LUA_RTOS_USE_HARDWARE_LOCKS
+
+#if CONFIG_LUA_RTOS_SD_CONNECTED_TO_POWER_BUS
+ pwbus_off();
+#endif
+
+ syslog(LOG_INFO, "fat unmounted");
+
+ return 0;
+}
+
+int vfs_fat_format(const char *target) {
+ vfs_fat_umount(target);
+
+#if CONFIG_SD_CARD_SPI
+ spi_bus_t *spi_bus = get_spi_info();
+
+ #if CONFIG_LUA_RTOS_USE_HARDWARE_LOCKS
+ // Lock resources
+ if (spi_lock_bus_resources(CONFIG_LUA_RTOS_SD_SPI, DRIVER_ALL_FLAGS)) {
+ return -1;
+ }
+
+ if (driver_lock(SYSTEM_DRIVER, 0, GPIO_DRIVER, CONFIG_LUA_RTOS_SD_CS, DRIVER_ALL_FLAGS, "SD Card - CS")) {
+ return -1;
+ }
+ #endif // CONFIG_LUA_RTOS_USE_HARDWARE_LOCKS
+
+ sdmmc_host_t host = SDSPI_HOST_DEFAULT();
+ sdspi_slot_config_t slot_config = SDSPI_SLOT_CONFIG_DEFAULT();
+
+ #if (CONFIG_LUA_RTOS_SD_SPI == 2)
+ host.slot = HSPI_HOST;
+
+ slot_config.gpio_miso = CONFIG_LUA_RTOS_SPI2_MISO;
+ slot_config.gpio_mosi = CONFIG_LUA_RTOS_SPI2_MOSI;
+ slot_config.gpio_sck = CONFIG_LUA_RTOS_SPI2_CLK;
+ slot_config.gpio_cs = CONFIG_LUA_RTOS_SD_CS;
+ #endif // (CONFIG_LUA_RTOS_SD_SPI == 2)
+
+ #if (CONFIG_LUA_RTOS_SD_SPI == 3)
+ host.slot = VSPI_HOST;
+
+ slot_config.gpio_miso = CONFIG_LUA_RTOS_SPI3_MISO;
+ slot_config.gpio_mosi = CONFIG_LUA_RTOS_SPI3_MOSI;
+ slot_config.gpio_sck = CONFIG_LUA_RTOS_SPI3_CLK;
+ slot_config.gpio_cs = CONFIG_LUA_RTOS_SD_CS;
+ #endif // (CONFIG_LUA_RTOS_SD_SPI == 3)
+
+ spi_bus[spi_idx(CONFIG_LUA_RTOS_SD_SPI)].setup |= SPI_DMA_SETUP;
+#endif // CONFIG_SD_CARD_SPI
+
+#if CONFIG_SD_CARD_MMC
+ sdmmc_host_t host = SDMMC_HOST_DEFAULT();
+ sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT();
+
+ slot_config.gpio_cd = CONFIG_LUA_RTOS_MCC_CD;
+ slot_config.gpio_wp = CONFIG_LUA_RTOS_MCC_WP;
+
+ #if CONFIG_LUA_RTOS_USE_HARDWARE_LOCKS
+ // Lock resources
+ if (driver_lock(SYSTEM_DRIVER, 0, GPIO_DRIVER, 15, DRIVER_ALL_FLAGS, "SD Card - CMD")) {
+ return -1;
+ }
+
+ if (driver_lock(SYSTEM_DRIVER, 0, GPIO_DRIVER, 14, DRIVER_ALL_FLAGS, "SD Card - CLK")) {
+ return -1;
+ }
+
+ if (driver_lock(SYSTEM_DRIVER, 0, GPIO_DRIVER, 2, DRIVER_ALL_FLAGS, "SD Card - DAT0")) {
+ return -1;
+ }
+ #endif // CONFIG_LUA_RTOS_USE_HARDWARE_LOCKS
+
+ gpio_pin_pullup(2);
+ gpio_pin_pullup(14);
+ gpio_pin_pullup(15);
+
+ #if CONFIG_LUA_RTOS_MCC_1_LINE
+ host.flags = SDMMC_HOST_FLAG_1BIT;
+ slot_config.width = 1;
+ #endif // CONFIG_LUA_RTOS_MCC_1_LINE
+
+ #if CONFIG_LUA_RTOS_MCC_4_LINE
+ host.flags = SDMMC_HOST_FLAG_4BIT;
+ slot_config.width = 4;
+
+ gpio_pin_pullup(4);
+ gpio_pin_pullup(12);
+ gpio_pin_pullup(13);
+
+ #if CONFIG_LUA_RTOS_USE_HARDWARE_LOCKS
+ if (driver_lock(SYSTEM_DRIVER, 0, GPIO_DRIVER, 4, DRIVER_ALL_FLAGS, "SD Card - DAT1")) {
+ return -1;
+ }
+
+ if (driver_lock(SYSTEM_DRIVER, 0, GPIO_DRIVER, 12, DRIVER_ALL_FLAGS, "SD Card - DAT2")) {
+ return -1;
+ }
+
+ if (driver_lock(SYSTEM_DRIVER, 0, GPIO_DRIVER, 13, DRIVER_ALL_FLAGS, "SD Card - DAT3")) {
+ return -1;
+ }
+ #endif // CONFIG_LUA_RTOS_USE_HARDWARE_LOCKS
+ #endif // CONFIG_LUA_RTOS_MCC_4_LINE
+
+ #if CONFIG_LUA_RTOS_MCC_CD != -1
+ if (driver_lock(SYSTEM_DRIVER, 0, GPIO_DRIVER, CONFIG_LUA_RTOS_MCC_CD, DRIVER_ALL_FLAGS, "SD Card - CD")) {
+ return -1;
+ }
+ #endif // CONFIG_LUA_RTOS_MCC_CD
+
+ #if CONFIG_LUA_RTOS_MCC_WP != -1
+ if (driver_lock(SYSTEM_DRIVER, 0, GPIO_DRIVER, CONFIG_LUA_RTOS_MCC_WP, DRIVER_ALL_FLAGS, "SD Card - WP")) {
+ return -1;
+ }
+ #endif // CONFIG_LUA_RTOS_MCC_WP
+#endif // CONFIG_SD_CARD_MMC
+
+ esp_vfs_fat_sdmmc_mount_config_t mount_config = {
+ .format_if_mount_failed = false,
+ .max_files = 5
+ };
+
+ #if CONFIG_SD_CARD_SPI
+ syslog(LOG_INFO, "sd is at spi%d, cs=%s%d",
+ CONFIG_LUA_RTOS_SD_SPI,
+ gpio_portname(CONFIG_LUA_RTOS_SD_CS), gpio_name(CONFIG_LUA_RTOS_SD_CS)
+ );
+ #endif
+
+ #if CONFIG_SD_CARD_MMC
+ syslog(LOG_INFO, "sd is at mmc0");
+ #endif
+
+ sdmmc_card_t* card;
+ esp_err_t ret = esp_vfs_fat_sdmmc_format("/fat", &host, &slot_config, &mount_config, &card);
+ if (ret != ESP_OK) {
+ syslog(LOG_INFO, "fat can't mounted (error %d)", ret);
+ vfs_fat_umount(target);
+ return -1;
+ }
+
+ syslog(LOG_INFO, "sd name %s", card->cid.name);
+ syslog(LOG_INFO, "sd type %s", (card->ocr & SD_OCR_SDHC_CAP)?"SDHC/SDXC":"SDSC");
+ syslog(LOG_INFO, "sd working at %s", (card->csd.tr_speed > 25000000)?"high speed":"default speed");
+ syslog(LOG_INFO, "sd size %.2f GB",
+ ((((double)card->csd.capacity) * ((double)card->csd.sector_size)) / 1073741824.0)
+ );
+
+ syslog(LOG_INFO, "sd CSD ver=%d, sector_size=%d, capacity=%d read_bl_len=%d",
+ card->csd.csd_ver,
+ card->csd.sector_size, card->csd.capacity, card->csd.read_block_len
+ );
+
+ syslog(LOG_INFO, "sd SCR sd_spec=%d, bus_width=%d", card->scr.sd_spec, card->scr.bus_width);
+
+ syslog(LOG_INFO, "fat mounted on %s", target);
+
+ vfs_fat_umount(target);
+ vfs_fat_mount(target);
+
+ return 0;
+}
+
+int vfs_fat_fsstat(const char *target, u32_t *total, u32_t *used) {
+ DWORD nclst = 0;
+ FATFS* fs = NULL;
+ FRESULT err = f_getfree (target, &nclst, &fs);
+
+ if (err != FR_OK) {
+ syslog(LOG_ERR, "fat get fs info of '%s' (%i)", target, err);
+ return -1;
+ }
+
+ //fs->free_clst and nclst both are equal and give the number of free clusters
+ //fs->csize = Cluster size [sectors]
+ //fs->ssize = Sector size (512, 1024, 2048 or 4096)
+ //fs->fsize = Size of an FAT [sectors]
+ //fs->n_fatent = nclst + 2
+
+ DWORD tclst = fs->n_fatent - 2;
+
+ if (total) {
+ *total = tclst * fs->csize * fs->ssize;
+ }
+
+ if (used) {
+ *used = (tclst - nclst) * fs->csize * fs->ssize;
+ }
+
+ return 0;
+}
+
+#endif