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
This commit is contained in:
Jan Procházka
2021-10-12 15:30:13 +02:00
committed by bot
parent d9429ca7bc
commit 683da6b46d
3 changed files with 49 additions and 41 deletions

View File

@ -1,16 +1,8 @@
// Copyright 2015-2017 Espressif Systems (Shanghai) PTE LTD /*
// * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
// Licensed under the Apache License, Version 2.0 (the "License"); *
// you may not use this file except in compliance with the License. * SPDX-License-Identifier: Apache-2.0
// 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.
#include "diskio_impl.h" #include "diskio_impl.h"
#include "ffconf.h" #include "ffconf.h"
@ -23,14 +15,32 @@ static sdmmc_card_t* s_cards[FF_VOLUMES] = { NULL };
static const char* TAG = "diskio_sdmmc"; static const char* TAG = "diskio_sdmmc";
//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) DSTATUS ff_sdmmc_initialize (BYTE pdrv)
{ {
return 0; return ff_sdmmc_card_available(pdrv);
} }
DSTATUS ff_sdmmc_status (BYTE 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) DRESULT ff_sdmmc_read (BYTE pdrv, BYTE* buff, DWORD sector, UINT count)

View File

@ -1,16 +1,8 @@
// Copyright 2015-2018 Espressif Systems (Shanghai) PTE LTD /*
// * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
// Licensed under the Apache License, Version 2.0 (the "License"); *
// you may not use this file except in compliance with the License. * SPDX-License-Identifier: Apache-2.0
// 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.
#pragma once #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); 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 * Write given number of sectors to SD/MMC card
* *

View File

@ -1,18 +1,7 @@
/* /*
* Copyright (c) 2006 Uwe Stuehler <uwe@openbsd.org> * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
* Adaptations to ESP-IDF Copyright (c) 2016-2018 Espressif Systems (Shanghai) PTE LTD
* *
* Permission to use, copy, modify, and distribute this software for any * SPDX-License-Identifier: Apache-2.0
* 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.
*/ */
#include "sdmmc_common.h" #include "sdmmc_common.h"
@ -511,3 +500,9 @@ esp_err_t sdmmc_read_sectors_dma(sdmmc_card_t* card, void* dst,
} }
return ESP_OK; return ESP_OK;
} }
esp_err_t sdmmc_get_status(sdmmc_card_t* card)
{
uint32_t stat;
return sdmmc_send_cmd_send_status(card, &stat);
}