⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usbhost_fat.c

📁 LPC1788的USBHOST的FATFS移植
💻 C
📖 第 1 页 / 共 3 页
字号:
        cnt++;
    }
    cnt = 0;
    while (cnt < 3) {                  /* Get 3 charecters from there                                       */
        *ext_ptr = *entry;
        ext_ptr++;
        entry++;
        cnt++;
    }
    *ext_ptr = 0;
    ext_ptr--;
    while (*ext_ptr == ' ') {          /* If any spaces exist after the file extension, replace them with 0 */
        *ext_ptr = 0;
        ext_ptr--;
    }
}

/*
**************************************************************************************************************
*                                       CASE INSENSITIVE COMPARISION OF STRINGS
*
* Description: This function compares two strings case insensitively
*
* Arguments  : str1               Pointer to the first string
*              str2               Pointer to the second string
*
* Returns    : MATCH_FOUND        if both the strings are same
*              NATCH_NOT_FOUND    if both the strings are different
*
**************************************************************************************************************
*/

int32_t  FAT_StrCaseCmp (uint8_t  *str1,
                            uint8_t  *str2)
{
    while (*str1 && *str2) {
        if (*str1 == *str2 || *str1 == (*str2 + 32) || *str1 == (*str2 - 32)) {
            str1++;
            str2++;
            continue;
        } else {
            return (MATCH_NOT_FOUND);
        }
    }
    if (*str1 == 0 && *str2 == 0) {
        return (MATCH_FOUND);
    } else {
        return (MATCH_NOT_FOUND);
    }
}

/*
**************************************************************************************************************
*                                       CHECK TYPE OF THE ENTRY
*
* Description: This function checks the type of file entry.
*
* Arguments  : ent           Pointer to the buffer containing the entry
*
* Returns    : LAST_ENTRY    if the entry is last entry
*              FREE_ENTRY    if the entry is free entry
*              LFN_ENTRY     if the entry is long file name entry
*              SFN_ENTRY     if the entry is short file name entry
*
**************************************************************************************************************
*/

uint32_t  FAT_ChkEntType (volatile  uint8_t  *ent)
{
    if (ent[0] == 0x00) {                              /* First byte is 0 means it is the last entry        */
        return (LAST_ENTRY);
    }

    if (ent[0] == 0xE5) {                              /* First byte is 0xE5 means it is the free entry     */
        return (FREE_ENTRY);
    }

    if (0x0F == ent[11]) {                             /* If 11th byte of an entry is 0x0F, it is LFN       */
        return (LFN_ENTRY);

    } else {
        return (SFN_ENTRY);                            /* Else it is the SFN                                */
    }
}

/*
**************************************************************************************************************
*                                       READ DATA REQUESTED BY THE USER
*
* Description: This function reads data requested by the application from the file pointed by file descriptor.
*
* Arguments  : fd                  file descriptor that points to a file
*              buffer              buffer into which the data is to be read
*              num_bytes           number of bytes requested by the application
*
* Returns    : total_bytes_read    Total bytes actually read.
*
**************************************************************************************************************
*/

uint32_t  FILE_Read (          int32_t  fd,
                       volatile  uint8_t  *buffer,
                                 uint32_t   num_bytes)
{
    uint32_t   total_bytes_to_read;            /* Total bytes requested by the application                */
    uint32_t   total_bytes_read;               /* Total bytes read                                        */
    uint32_t   bytes_read;                     /* Bytes read from one cluster                             */
    uint32_t   bytes_to_read;                  /* Bytes to be read in one cluster                         */
    FILE_ENTRY  *entry;                          /* Entry that contains the file attribute information      */
    uint16_t   next_clus;                     /* Next cluster of the current cluster in the cluster chain */

    entry = &FAT_FileEntry[fd-1];                /* Get file entry from file descriptor                     */
    total_bytes_read = 0;

    if (entry->FileSize == 0) {
        return (0);
    }
    if (num_bytes < entry->FileSize) {
        total_bytes_to_read = num_bytes;
    } else {
        total_bytes_to_read = entry->FileSize;
    }
    do {
        next_clus = FAT_GetNextClus(entry->CurrClus);     /* Get next cluster                               */
        if (next_clus == 0) {                             /* If the current cluster is the last cluster     */
                                                          /* If the offset is at the end of the file        */
            if (entry->CurrClusOffset == (entry->FileSize % FAT_BootSec.BytsPerClus)) {
                return (0);                               /* No more bytes to read                          */
            }                               /* If requested number is > remaining bytes in the last cluster */
            if (total_bytes_to_read > ((entry->FileSize % FAT_BootSec.BytsPerClus) - entry->CurrClusOffset)) {
                total_bytes_to_read = (entry->FileSize % FAT_BootSec.BytsPerClus) - entry->CurrClusOffset;
            }
            bytes_to_read = total_bytes_to_read;
                                         /* If requested number is > remaining bytes in the current cluster */
        } else if (total_bytes_to_read > (FAT_BootSec.BytsPerClus - entry->CurrClusOffset)) {
            bytes_to_read = FAT_BootSec.BytsPerClus - entry->CurrClusOffset;
        } else {
            bytes_to_read = total_bytes_to_read;
        }
        bytes_read = FAT_ClusRead(entry->CurrClus,       /* Read bytes from a single cluster                */
                                  entry->CurrClusOffset,
                                  buffer,
                                  bytes_to_read);
        buffer              += bytes_read;
        total_bytes_read    += bytes_read;
        total_bytes_to_read -= bytes_read;
                                             /* If the cluster offset reaches end of the cluster, make it 0 */
        if (entry->CurrClusOffset + bytes_read == FAT_BootSec.BytsPerClus) {
            entry->CurrClusOffset = 0;
        } else {
            entry->CurrClusOffset += bytes_read;        /* Else increment the cluster offset                */
        }
        if (entry->CurrClusOffset == 0) {
            entry->CurrClus = (next_clus > 0) ? next_clus : entry->CurrClus;
        }
    } while (total_bytes_to_read);
    return (total_bytes_read);
}

/*
**************************************************************************************************************
*                                                 READ FROM ONE CLUSTER
*
* Description: This function reads the data from a single cluster.
*
* Arguments  : curr_clus         Current cluster from which the data has to read
*              clus_offset       Position in the current cluster from which the data has to read
*              buffer            Buffer into which the data has to read
*              num_bytes         Number of bytes to read
*
* Returns    : tot_bytes_read    Total bytes read from the current cluster
*
**************************************************************************************************************
*/

uint32_t  FAT_ClusRead (          uint16_t   curr_clus,
                                    uint32_t   clus_offset,
                          volatile  uint8_t  *buffer,
                                    uint32_t   num_bytes)
{
    uint32_t  tot_bytes_read;                              /* total bytes read in the current cluster     */
    uint32_t  n_bytes;                                     /* Bytes to read in the current sector         */
    uint32_t  start_sec;                                   /* Starting sector of the current cluster      */
    uint32_t  sec_num;                                     /*Current sector number                        */
    uint16_t  num_sec;                                     /* Number of sectors to be read                */
    uint32_t  sec_offset;                                  /* Offset in the current sector                */
    uint32_t  cnt;


    tot_bytes_read = 0;
    start_sec  = ((curr_clus - 2) * FAT_BootSec.SecPerClus) + FAT_BootSec.FirstDataSec;
    sec_num    = start_sec + (clus_offset / FAT_BootSec.BytsPerSec);
    num_sec    = num_bytes / FAT_BootSec.BytsPerSec;
    sec_offset = clus_offset % FAT_BootSec.BytsPerSec;

    if (sec_offset) {                                 /* If the sector offset is at the middle of a sector  */
        MS_BulkRecv(sec_num, 1, FATBuffer);           /* Read the first sector                              */
        n_bytes = (FAT_BootSec.BytsPerSec - sec_offset <= num_bytes) ?
                  (FAT_BootSec.BytsPerSec - sec_offset) : num_bytes;
        for (cnt = sec_offset; cnt < sec_offset + n_bytes; cnt++) {
            *buffer = FATBuffer[cnt];                 /* Copy the required bytes to user buffer             */
             buffer++;
        }
        tot_bytes_read += n_bytes;
        clus_offset    += n_bytes;
        num_bytes      -= n_bytes;
        sec_num++;
    }

    if (num_bytes / FAT_BootSec.BytsPerSec) {         /* Read all the remaining full sectors                */

        num_sec = num_bytes / FAT_BootSec.BytsPerSec;
        MS_BulkRecv(sec_num, num_sec, buffer);
        buffer         += (num_sec * FAT_BootSec.BytsPerSec);
        tot_bytes_read += (num_sec * FAT_BootSec.BytsPerSec);
        clus_offset    += (num_sec * FAT_BootSec.BytsPerSec);
        num_bytes      -= (num_sec * FAT_BootSec.BytsPerSec);
        sec_num        += num_sec;
    }

    if (num_bytes) {                                  /* Read the last sector for the remaining bytes       */
        MS_BulkRecv(sec_num, 1, FATBuffer);
        for (cnt = 0; cnt < num_bytes; cnt++) {
            *buffer = FATBuffer[cnt];                 /* Copy the required bytes to user buffer             */
             buffer++;
        }
        tot_bytes_read += num_bytes;
    }

    return (tot_bytes_read);
}

/*
**************************************************************************************************************
*                                       WRITE THE DATA REQUESTED BY THE USER
*
* Description: This function writes data requested by the application to the file pointed by file descriptor
*
* Arguments  : fd                     file descriptor that points to a file
*              buffer                 buffer from which the data is to be written
*              num_bytes              number of bytes requested by the application
*
* Returns    : total_bytes_written    Total bytes actually written
*
**************************************************************************************************************
*/

uint32_t  FILE_Write (          int32_t  fd,
                        volatile  uint8_t  *buffer,
                                  uint32_t   num_bytes)
{
    uint32_t   total_bytes_to_write;                      /* Total bytes requested by application         */
    uint32_t   total_bytes_written;                       /* Total bytes written                          */
    uint32_t   bytes_written;                             /* Bytes written in a single cluster            */
    uint32_t   bytes_to_write;                            /* Bytes to write in a single cluster           */
    FILE_ENTRY  *entry;                               /* Entry that contains the file attribute information */
    uint16_t   free_clus;                                 /* Free cluster available in the disk           */


    entry = &FAT_FileEntry[fd-1];                           /* Get file entry from file descriptor                     */
    total_bytes_written  = 0;
    total_bytes_to_write = num_bytes;

    if (num_bytes) {
        if (entry->FileSize == 0) {
            free_clus = FAT_GetFreeClus();
            FAT_UpdateFAT(free_clus, 0xFFFF);
            entry->CurrClus  = free_clus;
            MS_BulkRecv(entry->EntrySec, 1, FATBuffer);
            WriteLE16U(&FATBuffer[(entry->EntrySecOffset) + 26], free_clus);
            MS_BulkSend(entry->EntrySec, 1, FATBuffer);
        }
    } else {
        return (0);
    }
    entry->CurrClus = FAT_GetEndClus(entry->CurrClus);           /* Make the current cluster as end cluster */
    entry->CurrClusOffset = entry->FileSize % FAT_BootSec.BytsPerClus;   /* Move cluster offset to file end */
    do {
        if (total_bytes_to_write > FAT_BootSec.BytsPerClus - entry->CurrClusOffset) {
            bytes_to_write = FAT_BootSec.BytsPerClus - entry->CurrClusOffset;
        } else {
            bytes_to_write = total_bytes_to_write;
        }
        bytes_written = FAT_ClusWrite(entry->CurrClus,
                                      entry->CurrClusOffset,
                                      buffer,
                                      bytes_to_write);
        buffer               += bytes_written;
        total_bytes_written  += bytes_written;
        total_bytes_to_write -= bytes_written;
        entry->FileSize      += bytes_written;
        if (entry->CurrClusOffset + bytes_written == FAT_BootSec.BytsPerClus) {
            entry->CurrClusOffset = 0;
        } else {
            entry->CurrClusOffset += bytes_written;
        }
        if (entry->CurrClusOffset == 0) {
            free_clus = FAT_GetFreeClus();
            if (free_clus == 0) {
                return (total_bytes_written);
            }
            FAT_UpdateFAT(entry->CurrClus, free_clus);
            FAT_UpdateFAT(free_clus, 0xFFFF);
            entry->CurrClus = free_clus;
        }
    } while (total_bytes_to_write);
    return (total_bytes_written);
}

/*
**************************************************************************************************************
*                                               WRITE TO ONE CLUSTER
*
* Description: This function writes the data to a single cluster.
*
* Arguments  : curr_clus         Current cluster into which the data has to write
*              clus_offset       Position in the current cluster from which the data has to write
*              buffer            Buffer from which the data has to write
*              num_bytes         Number of bytes to write
*
* Returns    : tot_bytes_read    Total bytes written into the current cluster
*
**************************************************************************************************************
*/

uint32_t  FAT_ClusWrite (          uint16_t   curr_clus,
                                     uint32_t   clus_offset,
                           volatile  uint8_t  *buffer,
                                     uint32_t   num_bytes)
{
    uint32_t  tot_bytes_written;
	uint32_t  n_bytes;
	uint32_t  start_sec;
	uint32_t  sec_num;
	uint16_t  num_sec;
	uint32_t  sec_offset;
	uint32_t  cnt;


	tot_bytes_written = 0;
	start_sec  = ((curr_clus - 2) * FAT_BootSec.SecPerClus) + FAT_BootSec.FirstDataSec;
	sec_num    = start_sec + (clus_offset / FAT_BootSec.BytsPerSec);
	num_sec    = num_bytes / FAT_BootSec.BytsPerSec;
	sec_offset = clus_offset % FAT_BootSec.BytsPerSec;

	if (sec_offset) {
        MS_BulkRecv(sec_num, 1, FATBuffer);
		n_bytes = (FAT_BootSec.BytsPerSec - sec_offset <= num_bytes) ?

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -