📄 usbhost_fat.c
字号:
/*
**************************************************************************************************************
* NXP USB Host Stack
*
* (c) Copyright 2008, NXP SemiConductors
* (c) Copyright 2008, OnChip Technologies LLC
* All Rights Reserved
*
* www.nxp.com
* www.onchiptech.com
*
* File : usbhost_fat.c
* Programmer(s) : Ravikanth.P
* Version :
*
**************************************************************************************************************
*/
/*
**************************************************************************************************************
* INCLUDE HEADER FILES
**************************************************************************************************************
*/
#include "usbhost_fat.h"
/*
**************************************************************************************************************
* GLOBAL VARIABLES
**************************************************************************************************************
*/
#define MAX_FILE_DESCRIPTORS 2
static BOOT_SEC FAT_BootSec;
static FILE_ENTRY FAT_FileEntry[MAX_FILE_DESCRIPTORS];
/*
**************************************************************************************************************
* INITIALIZE THE FILE SYSTEM
*
* Description: This function initializes the FAT16 file system
*
* Arguments : None
*
* Returns : OK if Success
* ERR_INVALID_BOOTSIG if Failed
*
**************************************************************************************************************
*/
int32_t FAT_Init (void)
{
uint16_t boot_sig;
int32_t rc, i;
FILE_ENTRY *entry;
for (i=0;i<MAX_FILE_DESCRIPTORS;i++) {
entry = &FAT_FileEntry[i];
entry->CurrClus = 0;
entry->CurrClusOffset = 0;
entry->FileSize = 0;
entry->EntrySec = 0;
entry->EntrySecOffset = 0;
entry->FileStatus = 0;
}
MS_BulkRecv(0, 1, FATBuffer);
boot_sig = ReadLE16U(&FATBuffer[510]);
if (boot_sig != 0xAA55) {
rc = ERR_INVALID_BOOT_SIG;
} else {
if (FATBuffer[0] != 0xEB && FATBuffer[0] != 0xE9) {
FAT_BootSec.BootSecOffset = ReadLE32U(&FATBuffer[454]);
MS_BulkRecv(FAT_BootSec.BootSecOffset, 1, FATBuffer);
}
FAT_BootSec.BytsPerSec = ReadLE16U(&FATBuffer[11]); /* Bytes per cluster */
FAT_BootSec.SecPerClus = FATBuffer[13]; /* Sectors per cluster */
/* Reserved sector count */
FAT_BootSec.RsvdSecCnt = ReadLE16U(&FATBuffer[14]) + FAT_BootSec.BootSecOffset;
FAT_BootSec.NumFATs = FATBuffer[16]; /* Number of FAT copies */
FAT_BootSec.RootEntCnt = ReadLE16U(&FATBuffer[17]); /* Root entry count */
FAT_BootSec.TotSec16 = ReadLE16U(&FATBuffer[19]); /* Total FAT16 sectors */
FAT_BootSec.TotSec32 = ReadLE32U(&FATBuffer[32]); /* Total FAT32 sectors */
FAT_BootSec.FATSz16 = ReadLE16U(&FATBuffer[22]); /* Size of the FAT table */
/* Bytes per cluster */
FAT_BootSec.BytsPerClus = (FAT_BootSec.BytsPerSec * FAT_BootSec.SecPerClus);
/* Root directory starting sector */
FAT_BootSec.RootDirStartSec = FAT_BootSec.RsvdSecCnt + (FAT_BootSec.FATSz16 * FAT_BootSec.NumFATs);
/* Sectors occupied by root directory */
FAT_BootSec.RootDirSec = ((FAT_BootSec.RootEntCnt * 32) + (FAT_BootSec.BytsPerSec - 1)) /
(FAT_BootSec.BytsPerSec);
/* First data sector */
FAT_BootSec.FirstDataSec = FAT_BootSec.RootDirStartSec + FAT_BootSec.RootDirSec;
FAT_BootSec.FATType = FAT_GetFATType(); /* Type of FAT */
if (FAT_BootSec.FATType == FAT_16) {
rc = OK;
} else {
rc = ERR_FAT_NOT_SUPPORTED;
PRINT_Err(rc);
}
}
return (rc);
}
/*
**************************************************************************************************************
* GET FILE SYSTEM TYPE
*
* Description: This function returns the file system type with which the disk is formatted
*
* Arguments : None
*
* Returns : FAT16 On Success
* ERR_FAT_TYPE On Failure
*
**************************************************************************************************************
*/
uint8_t FAT_GetFATType (void)
{
uint8_t fat_type;
uint32_t tot_sec;
uint32_t tot_data_clus;
if (FAT_BootSec.TotSec16 != 0) { /* Get total sectors in the disk */
tot_sec = FAT_BootSec.TotSec16;
} else {
tot_sec = FAT_BootSec.TotSec32;
}
tot_data_clus = tot_sec / (FAT_BootSec.SecPerClus); /* Get total data clusters in the disk */
/* If total data clusters >= 4085 and */
/* < 65525, then it is FAT16 file system */
if (tot_data_clus >= 4085 && tot_data_clus < 65525) {
fat_type = FAT_16;
} else {
fat_type = 0;
}
return (fat_type);
}
/*
**************************************************************************************************************
* OPENING A FILE
*
* Description: This function stores the attributes of a file, such as starting cluster, file size,
* sector where the file entry is stored and offset of the entry in that sector
*
* Arguments : file_name Name of the file. The file must be in root directory.
*
* Returns : pointer to the entry On Success
* NULL On Failure
*
* Modifed 6/9/08 WCB returns a file descriptor which is the INDEX+1 to the entry.
* returning the entry address itself could be interpreted as a negative number --
* and thus an error -- for memory locations of 0x80000000 and above. We return
* INDEX+1 instead of just the index to avoid returning a file descriptor of zero,
* which could be potentially confused with an error.
*
**************************************************************************************************************
*/
int32_t FILE_Open (uint8_t *file_name,
uint8_t flags)
{
int32_t rc;
FILE_ENTRY *entry = 0;
int32_t fd = -1;
do {
if (FAT_FileEntry[++fd].FileStatus == 0)
entry = &FAT_FileEntry[fd];
} while ((entry == 0) && (fd < MAX_FILE_DESCRIPTORS-1));
if (entry == 0) {
return (ERR_OPEN_LIMIT_REACHED);
}
if (flags == RDONLY) { /* Search for a file. If it doesn't exist, don't create it */
rc = FAT_FindEntry(file_name, entry);
if (rc == MATCH_FOUND) {
entry->FileStatus = 1;
rc = fd+1;
}
} else { /* Search for a file. If it doesn't exist, create it */
rc = FAT_CreateEntry(file_name, entry);
if (rc == MATCH_FOUND) {
entry->FileStatus = 1;
rc = fd+1;
}
}
return (rc);
}
/*
**************************************************************************************************************
* FINDING AN ENTRY
*
* Description: This function searches for a file name in the root directory
*
* Arguments : ent_name_given Pointer to the file name to be searched.
* entry Pointer to the entry structure. The attributes of the file are stored in this
* structure if the file was found in the root directory.
*
* Returns : MATCH_FOUND if the file was found in the root directory.
* MATCH_NOT_FOUND if the file was not found in the root directory.
*
**************************************************************************************************************
*/
int32_t FAT_FindEntry (uint8_t *ent_name_given,
FILE_ENTRY *entry)
{
uint32_t sec_num;
volatile uint8_t *buf;
uint8_t ent_type;
uint8_t ent_name_read[13];
for (sec_num = FAT_BootSec.RootDirStartSec; /* For all the sectors in root directory */
sec_num < (FAT_BootSec.RootDirStartSec + FAT_BootSec.RootDirSec);
sec_num++) {
MS_BulkRecv(sec_num, 1, FATBuffer); /* Read one sector */
buf = FATBuffer;
while (buf < (FATBuffer + FAT_BootSec.BytsPerSec)) {
ent_type = FAT_ChkEntType(buf); /* Check for the entry type */
if (ent_type == SFN_ENTRY) { /* If it is short entry get short file name */
FAT_GetSFN(buf, ent_name_read);
/* Compare given name with this name case insensitively */
if (FAT_StrCaseCmp(ent_name_given, ent_name_read) == MATCH_FOUND) {
entry->CurrClus = ReadLE16U(&buf[26]); /* If they are same, get starting cluster */
entry->FileSize = ReadLE32U(&buf[28]); /* Get file size */
entry->EntrySec = sec_num; /* Get sector number where the filename is located */
/* Get offset in this sector where the filename is located */
entry->EntrySecOffset = buf - FATBuffer;
return (MATCH_FOUND);
}
}
if (ent_type == LAST_ENTRY) { /* If it is the last entry, no more entries will exist. Return */
return (MATCH_NOT_FOUND);
}
buf = buf + 32; /* Move to the next entry */
}
}
return (MATCH_NOT_FOUND);
}
/*
**************************************************************************************************************
* GET SHORT FILE NAME AND EXTENSION OF A FILE
*
* Description: This function reads the short file name and extension corresponding to a file
*
* Arguments : ent_buf buffer which contains the 32 byte entry of a file
* name buffer to store the file name and extension of a file
*
* Returns : None
*
**************************************************************************************************************
*/
void FAT_GetSFN (volatile uint8_t *entry,
uint8_t *name)
{
uint8_t ext[4]; /* Buffer to store the extension of a file */
uint8_t *ext_ptr;
ext_ptr = ext;
FAT_GetSfnName(entry, name); /* Get file name into "name" buffer */
FAT_GetSfnExt(entry, ext_ptr); /* Get extension into "ext" buffer */
while (*name) { /* Goto the end of the filename */
name++;
}
if (*ext_ptr) { /* If the extension exists, put a '.' charecter */
*name = '.';
name++;
}
while (*ext_ptr) { /* Append the extension to the file name */
*name = *ext_ptr;
name++;
ext_ptr++;
}
*name = '\0';
}
/*
**************************************************************************************************************
* GET SHORT FILE NAME OF A FILE
*
* Description: This function reads the short file name of a file
*
* Arguments : ent_buf buffer which contains the 32 byte entry of a file
* name buffer to store the short file name of a file
*
* Returns : None
*
**************************************************************************************************************
*/
void FAT_GetSfnName (volatile uint8_t *entry,
uint8_t *name)
{
uint32_t cnt;
cnt = 0;
while (cnt < 8) {
*name = *entry; /* Get first 8 charecters of an SFN entry */
name++;
entry++;
cnt++;
}
*name = 0;
name--;
while (*name == 0x20) { /* If any spaces exist after the file name, replace them with 0 */
*name = 0;
name--;
}
}
/*
**************************************************************************************************************
* GET EXTENSION OF A FILE
*
* Description: This function reads the extension of a file
*
* Arguments : ent_buf buffer which contains the 32 byte entry of a file
* ext_ptr buffer to store the extension of a file
*
* Returns : None
*
**************************************************************************************************************
*/
void FAT_GetSfnExt (volatile uint8_t *entry,
uint8_t *ext_ptr)
{
uint32_t cnt;
cnt = 0;
while (cnt < 8) { /* Goto the beginning of the file extension */
entry++;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -