Files
zTC1/mico-os/platform/MCU/MX1101/FileSystem/presearch.c

410 lines
9.9 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/////////////////////////////////////////////////////////////////////////
// Mountain View Silicon Tech. Inc.
// Copyright 2012, Mountain View Silicon Tech. Inc.,ShangHai,China
// All rights reserved
// Filename:presearch.c
/////////////////////////////////////////////////////////////////////////
//#include "app_config.h"
#include "dev_detect_driver.h"
#include "fs_config.h"
#include "folder.h"
#include "fat_file.h"
#include "fsinfo.h"
#include "dir.h"
#include "fsmount_buffermanager.h"
#include "fs_mount.h"
#include "fs_sync.h"
#include "fs_filesort.h"
#include "partition.h"
#include "breakpoint.h"
#include "Debug.h"
#define INDEPEND_FREERTOS
#ifndef INDEPEND_FREERTOS
#include "os.h"
#endif
#define FUNC_SPI_UPDATE_EN
#ifdef FUNC_SPI_UPDATE_EN
uint8_t UpgradeFileFound = 0xFF;
#endif// FUNC_SPI_UPDATE_EN
static bool fs_inited_flag = 0;
#ifndef INDEPEND_FREERTOS
SEMAPHORE Sync; // Identifier of sync object
#endif
#define FS_DBG(M, ...)
uint8_t FsSyncInit(void* FsContext)
{
#ifndef INDEPEND_FREERTOS
if(FsContext)
{
SEMA_INIT(Sync, 1)
return 1;
}
#endif
return 0;
}
void FsLock(void* FsContext)
{
#ifndef INDEPEND_FREERTOS
if(FsContext)
{
OSDOWN(Sync);
}
#endif
}
void FsUnLock(void* FsContext)
{
#ifndef INDEPEND_FREERTOS
if(FsContext)
{
OSUP(Sync);
}
#endif
}
////////////////////////////////////////////////////////////////
//
//寻找有特定扩展名的文件
//
void FindSpecialFileCallBack(FS_CONTEXT* FsContext)
{
#ifdef FUNC_SPI_UPDATE_EN //注:升级文件相关,勿改
//检查是否为SPI FLASH升级文件*.MVA
//只检查根目录
if((FsContext->gFsInfo.FolderSum == 1) && (UpgradeFileFound != 1)) //只搜索根目录是否有升级文件,注释这句则全盘搜索
{
if(memcmp(FsContext->gCurrentEntry->ExtName, "MVA", 3) == 0)
{
UpgradeFileFound = 1;
}
}
#endif
//以下为demo,可改。搜索到每个文件都会Call一次
#if 0 //demo
// 如果想获取特点文件Handle 则需定义全局变量如FAT_FILE SpecialFile
if(FsContext->gFsInfo.FolderSum == 1) //只搜索根目录是否有特定扩展名的文件,注释这句则全盘搜索
{
if(memcmp(FsContext->gCurrentEntry->ExtName, "XYZ", 3) == 0)
{
FileGetInfo(&SpecialFile); //找到特定文件获取到了SpecialFile信息。
}
}
#endif
}
////////////////////////////////////////////////////////////////
//判断文件的类型,由文件系统底层调用
uint8_t FileGetType(FS_CONTEXT* FsContext)
{
uint8_t ExtFileName[3];
ExtFileName[0] = FsContext->gCurrentEntry->ExtName[0];
ExtFileName[1] = FsContext->gCurrentEntry->ExtName[1];
ExtFileName[2] = FsContext->gCurrentEntry->ExtName[2];
if((ExtFileName[0] == 'M') && (ExtFileName[1] == 'P') && (ExtFileName[2] == '3' || ExtFileName[2] == '2'))
{
return FILE_TYPE_MP3;
}
else if((ExtFileName[0] == 'W') && (ExtFileName[1] == 'M') && (ExtFileName[2] == 'A'))
{
return FILE_TYPE_WMA;
}
else if((ExtFileName[0] == 'A') && (ExtFileName[1] == 'S') && (ExtFileName[2] == 'F'))
{
return FILE_TYPE_WMA;
}
else if((ExtFileName[0] == 'W') && (ExtFileName[1] == 'M') && (ExtFileName[2] == 'V'))
{
return FILE_TYPE_WMA;
}
else if((ExtFileName[0] == 'A') && (ExtFileName[1] == 'S') && (ExtFileName[2] == 'X'))
{
return FILE_TYPE_WMA;
}
else if((ExtFileName[0] == 'W') && (ExtFileName[1] == 'A') && (ExtFileName[2] == 'V'))
{
return FILE_TYPE_WAV;
}
else if((ExtFileName[0] == 'S') && (ExtFileName[1] == 'B') && (ExtFileName[2] == 'C'))
{
return FILE_TYPE_SBC;
}
else if((ExtFileName[0] == 'F') && (ExtFileName[1] == 'L') && (ExtFileName[2] == 'A'))
{
return FILE_TYPE_FLAC;
}
else if(((ExtFileName[0] == 'A') && (ExtFileName[1] == 'A') && ExtFileName[2] == 'C')
|| ((ExtFileName[0] == 'M') && (ExtFileName[1] == 'P') && ExtFileName[2] == '4')
|| ((ExtFileName[0] == 'M') && (ExtFileName[1] == '4') && ExtFileName[2] == 'A'))
{
return FILE_TYPE_AAC;
}
else if((ExtFileName[0] == 'A') && (ExtFileName[1] == 'I') && (ExtFileName[2] == 'F'))
{
return FILE_TYPE_AIF;
}
else
{
return FILE_TYPE_UNKNOWN;
}
}
// 获取FS扫描后与播放模式断点信息相匹配的文件、文件夹ID号
#ifdef FUNC_MATCH_PLAYER_BP
static PLAYER_BP_RET sPlayerBPRet = {-1, 1, 1};
// 获取播放断点匹配信息应该在FS初始化成功后调用
PLAYER_BP_RET* GetMatchPlayerBPRet(void)
{
return &sPlayerBPRet;
}
void SetMatchPlayerBPRet(int8_t BPIndex, uint16_t FileId, uint16_t FolderId)
{
sPlayerBPRet.BPIndex = BPIndex;
sPlayerBPRet.FileId = FileId;
sPlayerBPRet.FolderId = FolderId;
}
#endif
//
//统计文件和文件夹总数
//
bool PreSearch(FS_CONTEXT* FsContext)
{
ENTRY_TYPE EntryType;
#ifdef FUNC_MATCH_PLAYER_BP
sPlayerBPRet.BPIndex = -1;
#endif
FS_DBG("PreSearch start!\n");
#ifdef FUNC_SPI_UPDATE_EN
UpgradeFileFound = 0;
#endif
DirSetStartEntry(FsContext, FsContext->gFsInfo.RootStart, 0, TRUE);
FSINFO_Init(FsContext);
FsContext->gFolderDirStart = FsContext->gFsInfo.RootStart;
while(1)
{
EntryType = (ENTRY_TYPE)DirGetNextEntry(FsContext);
//FS_DBG("fcount:%d\n",++fcount);
if(FsContext->gEntryOffset == 0)
{
FSINFO_SaveFdi(FsContext);
}
switch(EntryType)
{
case ENTRY_FILE: //是歌曲
//FS_DBG("fcount:%d\n",++fcount);
if(FileGetType(FsContext) != FILE_TYPE_UNKNOWN)
{
//FS_DBG("找到歌曲:%-.8s%-.3s\n", &FsContext->gCurrentEntry->FileName[0], &FsContext->gCurrentEntry->FileName[8]);
if(FsContext->gFsInfo.FileSum >= 65535)
{
return TRUE;
}
FsContext->gFsInfo.FileSum++;
FsContext->gFsInfo.FileSumInFolder++;
//FS_DBG("Find a audio file:%d!\n", fcount);
#if FS_FILE_SORT_EN == 1
FileSortSearchNewFile(FsContext);
#endif
}
FindSpecialFileCallBack(FsContext);
break;
case ENTRY_FOLDER: //是文件夹,下次循环不会进入这个文件夹内
FsContext->gFsInfo.FolderNumInFolder++;
//FS_DBG("ENTRY_FOLDER: %d\n", FsContext->gFsInfo.FolderNumInFolder);
break;
case ENTRY_END: //返回上一级文件夹,调整之前记录的部分节点
FSINFO_ChangeFileNum(FsContext);
//记录根文件夹中的文件个数
if(FsContext->gFsInfo.FolderSum == 1)
{
FsContext->gFsInfo.RootFileSum = FsContext->gFsInfo.FileSum;
}
//回到当前文件夹的开头位置
//FS_DBG("开始查找下一个文件夹的位置!\n");
RewindFolderStart(FsContext);
//从当前位置,在整个文件系统中寻找下一个文件夹
if(!FindNextFolder(FsContext))
{
//FS_DBG("PreSearch end! %d ms \n", (uint16_t)PastTimeGet(&Timer));
#if FS_FILE_SORT_EN == 1
FileSortSearchEnd(FsContext);
#endif
return TRUE;
}
else //进入下一个文件夹成功
{
//FS_DBG("Into Next Folder%8s\n", &FsContext->gCurrentEntry->FileName[0]);
if(FsContext->gFsInfo.FolderSum >= 65535)
{
#if FS_FILE_SORT_EN == 1
FileSortSearchEnd(FsContext);
#endif
return TRUE;
}
FsContext->gFsInfo.FolderSum++;
FsContext->gFsInfo.FolderNumInFolder = 0;
FsContext->gFsInfo.FileSumInFolder = 0;
if(!DirEnterSonFolder(FsContext))
{
//FS_DBG("进入子文件夹失败!\n");
FsContext->gFsInfo.FolderSum--;
}
//FS_DBG("进入子文件夹成功!\n");
}
break;
default:
break;
}
}
}
//
//文件系统初始化,分析分区表,预搜索统计文件系统有关信息.
//
bool FSInit(uint8_t DeviceID)
{
//get fs memory
FS_CONTEXT* Fs_Context;
Fs_Context = gFSContextBufferManager.pfnAllocFSContextBuffer(&gFSContextBufferManager.FSContextBuffer, DeviceID);
if(Fs_Context == NULL)
{
return FALSE;
}
ENTER_FAT(Fs_Context);
if(!CheckAllDiskLinkFlag())
{
FS_DBG("disk not ready!\n");
LEAVE_FAT(Fs_Context, FALSE);
}
if(Fs_Context->gPreSearchStatus != PRESEARCH_STATUS_NONE)
{
FS_DBG("Mount Already\n");
LEAVE_FAT(Fs_Context, TRUE);
}
Fs_Context->gPreSearchStatus = PRESEARCH_STATUS_SEARCHING;
if(Fs_Context == 0 || FsGetAvailableLogicId() < 0)
{
LEAVE_FAT(Fs_Context, FALSE);
}
//mount fs
FsMount(FsGetAvailableLogicId(), Fs_Context);
FsGetCurContext()->gFsInfo.DevID = (DEV_ID)DeviceID;
FsGetCurContext()->gFsInfo.CurrFATSecNum = -1;
//FsGetCurContext()->gFsInfo.CurrDirSecNum = -1;
FsGetCurContext()->gCurFreeClusNum = 2;
if(!PartitionLoad(FsGetCurContext(), 0))
{
FS_DBG("PartitionLoad() error!\n");
//return FALSE;
FsMount(FsGetLogicIdByDeviceType(DeviceID), 0);
gFSContextBufferManager.pfnFreeFSContextBuffer(&gFSContextBufferManager.FSContextBuffer, DeviceID);
Fs_Context->gPreSearchStatus = PRESEARCH_STATUS_NONE;
LEAVE_FAT(Fs_Context, FALSE);
}
FS_DBG("PartitionLoad() OK!\n");
// {
// if(!PreSearch(FsGetCurContext()))
// {
// FS_DBG("PreSearch() error!\n");
// //return FALSE;
// LEAVE_FAT(Fs_Context, FALSE);
// }
// //end = OSSysTickGet();
// //FS_DBG("PreSearch() End:%d\n", end - begin);
// }
// Fs_Context->gPreSearchStatus = PRESEARCH_STATUS_SEARCHED;
// FS_DBG("PreSearch() OK\n");
// FS_DBG("Song sum in disk: %d\n", FsGetCurContext()->gFsInfo.FileSum);
// FS_DBG("Folder sum in disk: %d\n", FsGetCurContext()->gFsInfo.FolderSum);
// FS_DBG("Valid folder sum in disk: %d\n", FsGetCurContext()->gFsInfo.ValidFolderSum);
// FS_DBG("***********************************************\n");
// FS_DBG("\n");
//return TRUE;
LEAVE_FAT(Fs_Context, TRUE);
// fs_inited_flag = TRUE;
}
//
//文件系统去初始化
//
bool FSDeInit(uint8_t DeviceID)
{
bool res = FALSE;
int8_t LogicId = FsGetLogicIdByDeviceType(DeviceID);
FS_CONTEXT* Fs_Context = FsGetContextByDeviceType(DeviceID);
#ifdef FUNC_MATCH_PLAYER_BP
// sPlayerBPRet.BPIndex = -1;
#endif
ENTER_FAT(Fs_Context);
if(LogicId >= 0)
{
FsMount(LogicId, 0);
res = gFSContextBufferManager.pfnFreeFSContextBuffer(&gFSContextBufferManager.FSContextBuffer, DeviceID);
}
//return res;
LEAVE_FAT(Fs_Context, res);
// fs_inited_flag = FALSE;
}
bool IsFsInited(void)
{
return fs_inited_flag;
}