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

📄 usbhost_fat.c

📁 LPC1788的USBHOST的FATFS移植
💻 C
📖 第 1 页 / 共 3 页
字号:
                  (FAT_BootSec.BytsPerSec - sec_offset) : num_bytes;
		for (cnt = sec_offset; cnt < (sec_offset + n_bytes); cnt++) {
            FATBuffer[cnt] = *buffer;
			buffer++;
		}
        MS_BulkSend(sec_num, 1, FATBuffer);
		tot_bytes_written += n_bytes;
		clus_offset       += n_bytes;
        num_bytes         -= n_bytes;
		sec_num++;
	}
	if (num_bytes / FAT_BootSec.BytsPerSec) {
		num_sec = num_bytes / FAT_BootSec.BytsPerSec;
		MS_BulkSend(sec_num, num_sec, buffer);
		buffer            += (num_sec * FAT_BootSec.BytsPerSec);
		tot_bytes_written += (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) {
        MS_BulkRecv(sec_num, 1, FATBuffer);

		for (cnt = 0; cnt < num_bytes; cnt++) {
			FATBuffer[cnt] = *buffer;
			buffer++;
		}
        MS_BulkSend(sec_num, 1, FATBuffer);
		tot_bytes_written += num_bytes;
	}
	return (tot_bytes_written);
}

/*
**************************************************************************************************************
*                                              GET NEXT CLUSTER
*
* Description: This function returns next cluster of the current cluster in the cluster chain. If the current
*              cluster is the last cluster then this function returns 0
*
* Arguments  : clus_no    The cluster number for which the next cluster to be found
*
* Returns    : next_clus  if the current cluster is not the last cluster
*              0          if the current cluster is the last cluster
*                         Note: In practical cluster number 0 doesn't exist
*
**************************************************************************************************************
*/

uint16_t  FAT_GetNextClus (uint16_t  clus_no)
{
    uint32_t  sec_num;
    uint32_t  ent_offset;
    uint16_t  next_clus;

                                          /* Get the sector number in the FAT that contains current cluster */
    sec_num = FAT_BootSec.RsvdSecCnt + ((clus_no * 2) / FAT_BootSec.BytsPerSec);
                                   /* Get the sector offset in the FAT where the current cluster is located */
    ent_offset = (clus_no * 2) % FAT_BootSec.BytsPerSec; 
    MS_BulkRecv(sec_num, 1, FATBuffer);                          /* Read that sector                        */
    next_clus = ReadLE16U(&FATBuffer[ent_offset]);               /* Read the next cluster                   */
    if (next_clus >= 0xFFF8 && next_clus <= 0xFFFF) {      /* If that value is in between 0xFFF8 and 0xFFFF */ 
        next_clus = 0;                                     /* Current cluster is the end cluster            */
    }
    return (next_clus);

}

/*
**************************************************************************************************************
*                                               GET FREE CLUSTER
*
* Description: This function returns the free cluster if available
*
* Arguments  : None
*
* Returns    : free_clus    if available
*              0            if not available(means the disk is full)
*
**************************************************************************************************************
*/

uint16_t  FAT_GetFreeClus (void)
{
    uint32_t  num_sec;
    uint32_t  cnt;
    uint32_t  sec_num;
    uint16_t  free_clus;


    sec_num = FAT_BootSec.RsvdSecCnt;
    num_sec = FAT_BootSec.FATSz16;
    while (sec_num < (FAT_BootSec.RsvdSecCnt + num_sec)) {
        MS_BulkRecv(sec_num, 1, FATBuffer);
        for (cnt = 0; cnt < FAT_BootSec.BytsPerSec; cnt += 2) {
            if (ReadLE16U(&FATBuffer[cnt]) == 0) {
                free_clus = (((sec_num - FAT_BootSec.RsvdSecCnt) * FAT_BootSec.BytsPerSec) + cnt) / 2;
                return (free_clus);
            }
        }
        sec_num++;
    }
    return (0);
}

/*
**************************************************************************************************************
*                                       UPDATE FILE ALLOCATION TABLE
*
* Description: This function updates the file allocation table
*
* Arguments  : curr_clus    Offset of the current cluster number in the file allocation table
*              value        Value with which this offset to be updated
*
* Returns    : None
*
**************************************************************************************************************
*/

void  FAT_UpdateFAT (uint16_t  curr_clus,
                     uint16_t  value)
{
    uint32_t  sec_num;
    uint32_t  sec_offset;
    
    sec_num = FAT_BootSec.RsvdSecCnt + (curr_clus * 2) / FAT_BootSec.BytsPerSec;
    sec_offset = (curr_clus * 2) % FAT_BootSec.BytsPerSec;
    
    MS_BulkRecv(sec_num, 1, FATBuffer);
    WriteLE16U(&FATBuffer[sec_offset], value);
    MS_BulkSend(sec_num, 1, FATBuffer);
}

/*
**************************************************************************************************************
*                                              UPDATE THE FILE ENTRY
*
* Description: This function updates the file entry that is located in the root directory
*
* Arguments  : entry    Pointer to the FILE ENTRY structure which contains the information about the file
*
* Returns    : None
*
**************************************************************************************************************
*/

void  FAT_UpdateEntry (FILE_ENTRY  *entry)
{
    uint32_t  sec_num;
    uint32_t  offset;
    
    sec_num = entry->EntrySec;
    offset  = entry->EntrySecOffset;
    MS_BulkRecv(sec_num, 1, FATBuffer);
    WriteLE32U(&FATBuffer[offset + 28], entry->FileSize);
    MS_BulkSend(sec_num, 1, FATBuffer);
}

/*
**************************************************************************************************************
*                                              CREATING AN ENTRY
*
* Description: This function creates a file entry in the root directory if the file does not exist
*
* Arguments  : ent_name_given    The file name with which the entry is to be created
*              entry             Pointer to FILE ENTRY structure
*
* Returns    : OK                If the entry already exists or successfully created if it doesn't exists
*              ERROR             If failed to create the entry
*
**************************************************************************************************************
*/

int32_t  FAT_CreateEntry (uint8_t  *ent_name_given,
                             FILE_ENTRY  *entry)
{
    int32_t  rc;


    rc = FAT_FindEntry(ent_name_given, entry);        /* Find for the given file name in the root directory */
    if (rc == MATCH_FOUND) {                          /* If match found, return                             */
        return (rc);
    } else {
        rc = FAT_GetFreeEntry(entry);                 /* Else get a free entry from the root directory      */
        if (rc != OK) {
            return (rc);
        } else {
            FAT_PutSFN(ent_name_given, entry);        /* Store the given short file name in that entry      */
            return (rc);
        }
    }
}

/*
**************************************************************************************************************
*                                                GET GREE ENTRY
*
* Description: This function searches for a free entry in the root directory. If a free entry is found, the
*              sector number and sector offset where the entry is located will be stored
*
* Arguments  : entry    Pointer to FILE_ENTRY structure
*
* Returns    : OK       If a free entry is found
*              ERROR    If no free entry is found
*
**************************************************************************************************************
*/

int32_t  FAT_GetFreeEntry (FILE_ENTRY  *entry)
{
              uint32_t   sec_num;
    volatile  uint8_t  *buf;
              uint8_t   ent_type;


    for (sec_num = FAT_BootSec.RootDirStartSec; 
         sec_num < (FAT_BootSec.RootDirStartSec + FAT_BootSec.RootDirSec);
         sec_num++) {

        MS_BulkRecv(sec_num, 1, FATBuffer);
        buf = FATBuffer;
        while (buf < (FATBuffer + FAT_BootSec.BytsPerSec)) {
            ent_type = FAT_ChkEntType(buf);
            if (ent_type == FREE_ENTRY) {
                entry->EntrySec       = sec_num;
                entry->EntrySecOffset = buf - FATBuffer;
                return (OK);
            }
            if (ent_type == LAST_ENTRY) {
                return (ERR_ROOT_DIR_FULL);
            } else {
                buf += 32;
            }
        }
    }
    return (ERR_ROOT_DIR_FULL);
}

/*
**************************************************************************************************************
*                                              PUT SHORT FILE NAME
*
* Description: This function fills the file entry with the short file name given by the user
*
* Arguments  : ent_name_given    File name given by the user
*              entry             Pointer to the FILE_ENTRY structure
*
* Returns    : None
*
**************************************************************************************************************
*/

void  FAT_PutSFN (uint8_t  *ent_name_given,
                  FILE_ENTRY  *entry)
{
    uint32_t  idx;

                                           /* Read the sector from root directory containing the free entry */
    MS_BulkRecv(entry->EntrySec, 1, FATBuffer);
    for (idx = 0; idx < 8; idx++) {        /* Fill the first eight charecters of the entry with file name   */
        if (*ent_name_given == '.') {
            while (idx < 8) {
                FATBuffer[entry->EntrySecOffset + idx] = 0x20;
                idx++;
            }
            ent_name_given++;
        } else {
            FATBuffer[entry->EntrySecOffset + idx] = *ent_name_given;
            ent_name_given++;
        }
    }

    for (idx = 8; idx < 11; idx++) {                      /* Fill the next 3 charecters with file extension */
        if (*ent_name_given == '.') {
            while (idx < 11) {
                FATBuffer[entry->EntrySecOffset + idx] = 0x20;
                idx++;
            }
        } else {
            FATBuffer[entry->EntrySecOffset + idx] = *ent_name_given;
            ent_name_given++;
        }
    }
    FATBuffer[entry->EntrySecOffset + idx] = 0x20;
    for (idx = 12; idx < 32; idx++) {                           /* Fill all the remaining bytes with 0's    */
        FATBuffer[entry->EntrySecOffset + idx] = 0;
    }
    MS_BulkSend(entry->EntrySec, 1, FATBuffer);                 /* Write the sector into the root directory */
}

/*
**************************************************************************************************************
*                                                  FILE CLOSE
*
* Description: This function closes the opened file by making all the elements of FILE_ENTRY structure to 0
*
* Arguments  : fd    File descriptor which points to the file to be closed
*
* Returns    : None
*
**************************************************************************************************************
*/

void  FILE_Close (int32_t  fd)
{
    FILE_ENTRY  *entry;


    entry = &FAT_FileEntry[fd-1];
    MS_BulkRecv(entry->EntrySec, 1, FATBuffer);
    WriteLE32U(&FATBuffer[entry->EntrySecOffset + 28], entry->FileSize);    /* Update the file size         */
    MS_BulkSend(entry->EntrySec, 1, FATBuffer);
    entry->CurrClus       = 0;
    entry->CurrClusOffset = 0;
    entry->FileSize       = 0;
    entry->EntrySec       = 0;
    entry->EntrySecOffset = 0;
    entry->FileStatus     = 0;
}

/*
**************************************************************************************************************
*                                               GET END CLUSTER
*
* Description: This function end cluster in the cluster chain of a cluster
*
* Arguments  : clus_no    Starting cluster of the cluster chain in which end cluster to be found
*
* Returns    : End cluster in the cluster chain
*
**************************************************************************************************************
*/

uint16_t  FAT_GetEndClus (uint16_t  clus_no)
{
    uint16_t  next_clus;


    next_clus = clus_no;
    while (next_clus) {
        next_clus = FAT_GetNextClus(clus_no);
        if (next_clus) {
            clus_no = next_clus;
        }
    }
    return (clus_no);
}

⌨️ 快捷键说明

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