MCUXpresso_MIMXRT1021xxxxx/boards/evkmimxrt1020/sdmmc_examples/sdcard_fatfs/sdcard_fatfs.c
2022-08-23 23:00:33 +08:00

278 lines
7.8 KiB
C

/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright 2016-2017 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <stdio.h>
#include <string.h>
#include "fsl_sd.h"
#include "fsl_debug_console.h"
#include "ff.h"
#include "diskio.h"
#include "fsl_sd_disk.h"
#include "pin_mux.h"
#include "clock_config.h"
#include "board.h"
#include "sdmmc_config.h"
#include "fsl_common.h"
/*******************************************************************************
* Definitions
******************************************************************************/
/* buffer size (in byte) for read/write operations */
#define BUFFER_SIZE (513U)
/*******************************************************************************
* Prototypes
******************************************************************************/
/*!
* @brief wait card insert function.
*/
static status_t sdcardWaitCardInsert(void);
/*******************************************************************************
* Variables
******************************************************************************/
static FATFS g_fileSystem; /* File system object */
static FIL g_fileObject; /* File object */
/* @brief decription about the read/write buffer
* The size of the read/write buffer should be a multiple of 512, since SDHC/SDXC card uses 512-byte fixed
* block length and this driver example is enabled with a SDHC/SDXC card.If you are using a SDSC card, you
* can define the block length by yourself if the card supports partial access.
* The address of the read/write buffer should align to the specific DMA data buffer address align value if
* DMA transfer is used, otherwise the buffer address is not important.
* At the same time buffer address/size should be aligned to the cache line size if cache is supported.
*/
/*! @brief Data written to the card */
SDK_ALIGN(uint8_t g_bufferWrite[BUFFER_SIZE], BOARD_SDMMC_DATA_BUFFER_ALIGN_SIZE);
/*! @brief Data read from the card */
SDK_ALIGN(uint8_t g_bufferRead[BUFFER_SIZE], BOARD_SDMMC_DATA_BUFFER_ALIGN_SIZE);
/*******************************************************************************
* Code
******************************************************************************/
/*!
* @brief Main function
*/
int main(void)
{
FRESULT error;
DIR directory; /* Directory object */
FILINFO fileInformation;
UINT bytesWritten;
UINT bytesRead;
const TCHAR driverNumberBuffer[3U] = {SDDISK + '0', ':', '/'};
volatile bool failedFlag = false;
char ch = '0';
BYTE work[FF_MAX_SS];
BOARD_ConfigMPU();
BOARD_InitPins();
BOARD_BootClockRUN();
BOARD_InitDebugConsole();
PRINTF("\r\nFATFS example to demonstrate how to use FATFS with SD card.\r\n");
PRINTF("\r\nPlease insert a card into board.\r\n");
if (sdcardWaitCardInsert() != kStatus_Success)
{
return -1;
}
if (f_mount(&g_fileSystem, driverNumberBuffer, 0U))
{
PRINTF("Mount volume failed.\r\n");
return -1;
}
#if (FF_FS_RPATH >= 2U)
error = f_chdrive((char const *)&driverNumberBuffer[0U]);
if (error)
{
PRINTF("Change drive failed.\r\n");
return -1;
}
#endif
#if FF_USE_MKFS
PRINTF("\r\nMake file system......The time may be long if the card capacity is big.\r\n");
if (f_mkfs(driverNumberBuffer, 0, work, sizeof work))
{
PRINTF("Make file system failed.\r\n");
return -1;
}
#endif /* FF_USE_MKFS */
PRINTF("\r\nCreate directory......\r\n");
error = f_mkdir(_T("/dir_1"));
if (error)
{
if (error == FR_EXIST)
{
PRINTF("Directory exists.\r\n");
}
else
{
PRINTF("Make directory failed.\r\n");
return -1;
}
}
PRINTF("\r\nCreate a file in that directory......\r\n");
error = f_open(&g_fileObject, _T("/dir_1/f_1.dat"), (FA_WRITE | FA_READ | FA_CREATE_ALWAYS));
if (error)
{
if (error == FR_EXIST)
{
PRINTF("File exists.\r\n");
}
else
{
PRINTF("Open file failed.\r\n");
return -1;
}
}
PRINTF("\r\nCreate a directory in that directory......\r\n");
error = f_mkdir(_T("/dir_1/dir_2"));
if (error)
{
if (error == FR_EXIST)
{
PRINTF("Directory exists.\r\n");
}
else
{
PRINTF("Directory creation failed.\r\n");
return -1;
}
}
PRINTF("\r\nList the file in that directory......\r\n");
if (f_opendir(&directory, "/dir_1"))
{
PRINTF("Open directory failed.\r\n");
return -1;
}
for (;;)
{
error = f_readdir(&directory, &fileInformation);
/* To the end. */
if ((error != FR_OK) || (fileInformation.fname[0U] == 0U))
{
break;
}
if (fileInformation.fname[0] == '.')
{
continue;
}
if (fileInformation.fattrib & AM_DIR)
{
PRINTF("Directory file : %s.\r\n", fileInformation.fname);
}
else
{
PRINTF("General file : %s.\r\n", fileInformation.fname);
}
}
memset(g_bufferWrite, 'a', sizeof(g_bufferWrite));
g_bufferWrite[BUFFER_SIZE - 2U] = '\r';
g_bufferWrite[BUFFER_SIZE - 1U] = '\n';
PRINTF("\r\nWrite/read file until encounters error......\r\n");
while (true)
{
if (failedFlag || (ch == 'q'))
{
break;
}
PRINTF("\r\nWrite to above created file.\r\n");
error = f_write(&g_fileObject, g_bufferWrite, sizeof(g_bufferWrite), &bytesWritten);
if ((error) || (bytesWritten != sizeof(g_bufferWrite)))
{
PRINTF("Write file failed. \r\n");
failedFlag = true;
continue;
}
/* Move the file pointer */
if (f_lseek(&g_fileObject, 0U))
{
PRINTF("Set file pointer position failed. \r\n");
failedFlag = true;
continue;
}
PRINTF("Read from above created file.\r\n");
memset(g_bufferRead, 0U, sizeof(g_bufferRead));
error = f_read(&g_fileObject, g_bufferRead, sizeof(g_bufferRead), &bytesRead);
if ((error) || (bytesRead != sizeof(g_bufferRead)))
{
PRINTF("Read file failed. \r\n");
failedFlag = true;
continue;
}
PRINTF("Compare the read/write content......\r\n");
if (memcmp(g_bufferWrite, g_bufferRead, sizeof(g_bufferWrite)))
{
PRINTF("Compare read/write content isn't consistent.\r\n");
failedFlag = true;
continue;
}
PRINTF("The read/write content is consistent.\r\n");
PRINTF("\r\nInput 'q' to quit read/write.\r\nInput other char to read/write file again.\r\n");
ch = GETCHAR();
PUTCHAR(ch);
}
PRINTF("\r\nThe example will not read/write file again.\r\n");
if (f_close(&g_fileObject))
{
PRINTF("\r\nClose file failed.\r\n");
return -1;
}
while (true)
{
}
}
static status_t sdcardWaitCardInsert(void)
{
BOARD_SD_Config(&g_sd, NULL, BOARD_SDMMC_SD_HOST_IRQ_PRIORITY, NULL);
/* SD host init function */
if (SD_HostInit(&g_sd) != kStatus_Success)
{
PRINTF("\r\nSD host init fail\r\n");
return kStatus_Fail;
}
/* wait card insert */
if (SD_PollingCardInsert(&g_sd, kSD_Inserted) == kStatus_Success)
{
PRINTF("\r\nCard inserted.\r\n");
/* power off card */
SD_SetCardPower(&g_sd, false);
/* power on the card */
SD_SetCardPower(&g_sd, true);
}
else
{
PRINTF("\r\nCard detect fail.\r\n");
return kStatus_Fail;
}
return kStatus_Success;
}