278 lines
7.8 KiB
C
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;
|
|
}
|