Explorar el Código

fatfs: Implementation of disk_status nad disk_initialize for SD/MMC card

FATFS provides a disk status and disk initialize callback which were not
implemented. Implementation has very low impact on SD/MMC speed and
fixes issues, when trying to open file when SD card was removed from
slot and not deinited.

If disk_status returns STA_NOINIT, it will always continue with
disk_initialize. If that returns 0, it will continue like everything is
working normally. So there has to be the same check as in disk_status.
Return of disk_initialize is always checked like this for STA_NOINIT or
STA_PROTECT so if command fails, we return the STA_NOINIT.

stat = disk_initialize(pdrv);
if (stat & STA_NOINIT) return FR_NOT_READY;
if (stat & STA_PROTECT) return FR_WRITE_PROTECTED;

Closes IDF-4125
Jan Procházka hace 4 años
padre
commit
fb22c1f182

+ 25 - 15
components/fatfs/diskio/diskio_sdmmc.c

@@ -1,16 +1,8 @@
-// Copyright 2015-2017 Espressif Systems (Shanghai) PTE LTD
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
+/*
+ * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
 
 #include "diskio_impl.h"
 #include "ffconf.h"
@@ -23,14 +15,32 @@ static sdmmc_card_t* s_cards[FF_VOLUMES] = { NULL };
 
 static const char* TAG = "diskio_sdmmc";
 
-DSTATUS ff_sdmmc_initialize (BYTE pdrv)
+//Check if SD/MMC card is present
+static DSTATUS ff_sdmmc_card_available(BYTE pdrv)
 {
+    sdmmc_card_t* card = s_cards[pdrv];
+    assert(card);
+    esp_err_t err = sdmmc_get_status(card);
+    if (unlikely(err != ESP_OK)) {
+        ESP_LOGE(TAG, "Check status failed (0x%x)", err);
+        return STA_NOINIT;
+    }
     return 0;
 }
 
+/**
+*   ff_sdmmc_status() and ff_sdmmc_initialize() return STA_NOINIT when sdmmc_get_status()
+*   fails. This error value is checked throughout the FATFS code.
+*   Both functions return 0 on success.
+*/
+DSTATUS ff_sdmmc_initialize (BYTE pdrv)
+{
+    return ff_sdmmc_card_available(pdrv);
+}
+
 DSTATUS ff_sdmmc_status (BYTE pdrv)
 {
-    return 0;
+    return ff_sdmmc_card_available(pdrv);
 }
 
 DRESULT ff_sdmmc_read (BYTE pdrv, BYTE* buff, DWORD sector, UINT count)

+ 16 - 13
components/sdmmc/include/sdmmc_cmd.h

@@ -1,16 +1,8 @@
-// Copyright 2015-2018 Espressif Systems (Shanghai) PTE LTD
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
+/*
+ * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
 
 #pragma once
 
@@ -45,6 +37,17 @@ esp_err_t sdmmc_card_init(const sdmmc_host_t* host,
  */
 void sdmmc_card_print_info(FILE* stream, const sdmmc_card_t* card);
 
+/**
+ * Get status of SD/MMC card
+ *
+ * @param card  pointer to card information structure previously initialized
+ *              using sdmmc_card_init
+ * @return
+ *      - ESP_OK on success
+ *      - One of the error codes from SDMMC host controller
+ */
+esp_err_t sdmmc_get_status(sdmmc_card_t* card);
+
 /**
  * Write given number of sectors to SD/MMC card
  *

+ 8 - 13
components/sdmmc/sdmmc_cmd.c

@@ -1,18 +1,7 @@
 /*
- * Copyright (c) 2006 Uwe Stuehler <uwe@openbsd.org>
- * Adaptations to ESP-IDF Copyright (c) 2016-2018 Espressif Systems (Shanghai) PTE LTD
+ * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
  *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ * SPDX-License-Identifier: Apache-2.0
  */
 
 #include "sdmmc_common.h"
@@ -511,3 +500,9 @@ esp_err_t sdmmc_read_sectors_dma(sdmmc_card_t* card, void* dst,
     }
     return ESP_OK;
 }
+
+esp_err_t sdmmc_get_status(sdmmc_card_t* card)
+{
+    uint32_t stat;
+    return sdmmc_send_cmd_send_status(card, &stat);
+}

+ 0 - 3
tools/ci/check_copyright_ignore.txt

@@ -1068,7 +1068,6 @@ components/fatfs/diskio/diskio.c
 components/fatfs/diskio/diskio_impl.h
 components/fatfs/diskio/diskio_rawflash.c
 components/fatfs/diskio/diskio_rawflash.h
-components/fatfs/diskio/diskio_sdmmc.c
 components/fatfs/diskio/diskio_sdmmc.h
 components/fatfs/diskio/diskio_wl.h
 components/fatfs/port/freertos/ffsystem.c
@@ -1863,8 +1862,6 @@ components/riscv/include/riscv/riscv_interrupts.h
 components/riscv/include/riscv/rvruntime-frames.h
 components/riscv/instruction_decode.c
 components/riscv/interrupt.c
-components/sdmmc/include/sdmmc_cmd.h
-components/sdmmc/sdmmc_cmd.c
 components/sdmmc/sdmmc_common.c
 components/sdmmc/sdmmc_common.h
 components/sdmmc/sdmmc_init.c