📄 file_sys.c
字号:
{
return( CH376FileOpenDir( PathName, 0xFF ) );
}
UINT8 CH376FileCreatePath( PUINT8 PathName ) /* 新建多级目录下的文件,支持多级目录路径,支持路径分隔符,路径长度不超过255个字符 */
{
UINT8 s;
UINT8 Name;
Name = CH376SeparatePath( PathName ); /* 从路径中分离出最后一级文件名,返回最后一级文件名的偏移 */
if ( Name ) { /* 是多级目录 */
s = CH376FileOpenDir( PathName, Name ); /* 打开多级目录下的最后一级目录,即打开新建文件的上级目录 */
if ( s != ERR_OPEN_DIR ) { /* 因为是打开上级目录,所以,如果不是成功打开了目录,那么说明有问题 */
if ( s == USB_INT_SUCCESS ) return( ERR_FOUND_NAME ); /* 中间路径必须是目录名,如果是文件名则出错 */
else if ( s == ERR_MISS_FILE ) return( ERR_MISS_DIR ); /* 中间路径的某个子目录没有找到,可能是目录名称错误 */
else return( s ); /* 操作出错 */
}
}
return( CH376FileCreate( &PathName[Name] ) ); /* 在根目录或者当前目录下新建文件 */
}
#ifdef EN_DIR_CREATE
UINT8 CH376DirCreatePath( PUINT8 PathName ) /* 新建多级目录下的目录(文件夹)并打开,支持多级目录路径,支持路径分隔符,路径长度不超过255个字符 */
{
UINT8 s;
UINT8 Name;
UINT8 ClustBuf[4];
Name = CH376SeparatePath( PathName ); /* 从路径中分离出最后一级目录名,返回最后一级文件名的偏移 */
if ( Name ) { /* 是多级目录 */
s = CH376FileOpenDir( PathName, Name ); /* 打开多级目录下的最后一级目录,即打开新建目录的上级目录 */
if ( s != ERR_OPEN_DIR ) { /* 因为是打开上级目录,所以,如果不是成功打开了目录,那么说明有问题 */
if ( s == USB_INT_SUCCESS ) return( ERR_FOUND_NAME ); /* 中间路径必须是目录名,如果是文件名则出错 */
else if ( s == ERR_MISS_FILE ) return( ERR_MISS_DIR ); /* 中间路径的某个子目录没有找到,可能是目录名称错误 */
else return( s ); /* 操作出错 */
}
xWriteCH376Cmd( CMD14_READ_VAR32 );
xWriteCH376Data( VAR_START_CLUSTER ); /* 上级目录的起始簇号 */
for ( s = 0; s != 4; s ++ ) ClustBuf[ s ] = xReadCH376Data( );
xEndCH376Cmd( );
s = CH376DirCreate( &PathName[Name] ); /* 在当前目录下新建目录 */
if ( s != USB_INT_SUCCESS ) return( s );
s = CH376ByteLocate( sizeof(FAT_DIR_INFO) + STRUCT_OFFSET( FAT_DIR_INFO, DIR_FstClusHI ) ); /* 移动文件指针 */
if ( s != USB_INT_SUCCESS ) return( s );
s = CH376ByteWrite( &ClustBuf[2], 2, NULL ); /* 写入上级目录的起始簇号的高16位 */
if ( s != USB_INT_SUCCESS ) return( s );
s = CH376ByteLocate( sizeof(FAT_DIR_INFO) + STRUCT_OFFSET( FAT_DIR_INFO, DIR_FstClusLO ) ); /* 移动文件指针 */
if ( s != USB_INT_SUCCESS ) return( s );
s = CH376ByteWrite( ClustBuf, 2, NULL ); /* 写入上级目录的起始簇号的低16位 */
if ( s != USB_INT_SUCCESS ) return( s );
s = CH376ByteLocate( 0 ); /* 移动文件指针,恢复到目录头位置 */
if ( s != USB_INT_SUCCESS ) return( s );
}
else { /* 不是多级目录 */
if ( PathName[0] == DEF_SEPAR_CHAR1 || PathName[0] == DEF_SEPAR_CHAR2 ) return( CH376DirCreate( PathName ) ); /* 在根目录下新建目录 */
else return( ERR_MISS_DIR ); /* 必须提供完整路径才能实现在当前目录下新建目录 */
}
}
#endif
UINT8 CH376FileErase( PUINT8 PathName ) /* 删除文件,如果已经打开则直接删除,否则对于文件会先打开再删除,支持多级目录路径 */
{
UINT8 s;
if ( PathName ) { /* 文件尚未打开 */
for ( s = 1; PathName[s] != DEF_SEPAR_CHAR1 && PathName[s] != DEF_SEPAR_CHAR2 && PathName[s] != 0; ++ s ); /* 搜索下一个路径分隔符或者路径结束符 */
if ( PathName[s] ) { /* 有路径分隔符,是多级目录下的文件或者目录 */
s = CH376FileOpenPath( PathName ); /* 打开多级目录下的文件或者目录 */
if ( s != USB_INT_SUCCESS && s != ERR_OPEN_DIR ) return( s ); /* 操作出错 */
}
else CH376SetFileName( PathName ); /* 没有路径分隔符,是根目录或者当前目录下的文件或者目录,设置将要操作的文件的文件名 */
}
return( CH376SendCmdWaitInt( CMD0H_FILE_ERASE ) );
}
UINT8 CH376FileClose( UINT8 UpdateSz ) /* 关闭当前已经打开的文件或者目录(文件夹) */
{
return( CH376SendCmdDatWaitInt( CMD1H_FILE_CLOSE, UpdateSz ) );
}
UINT8 CH376DirInfoRead( void ) /* 读取当前文件的目录信息 */
{
return( CH376SendCmdDatWaitInt( CMD1H_DIR_INFO_READ, 0xFF ) );
}
UINT8 CH376DirInfoSave( void ) /* 保存文件的目录信息 */
{
return( CH376SendCmdWaitInt( CMD0H_DIR_INFO_SAVE ) );
}
UINT8 CH376ByteLocate( UINT32 offset ) /* 以字节为单位移动当前文件指针 */
{
xWriteCH376Cmd( CMD4H_BYTE_LOCATE );
xWriteCH376Data( (UINT8)offset );
xWriteCH376Data( (UINT8)((UINT16)offset>>8) );
xWriteCH376Data( (UINT8)(offset>>16) );
xWriteCH376Data( (UINT8)(offset>>24) );
xEndCH376Cmd( );
return( Wait376Interrupt( ) );
}
UINT8 CH376ByteRead( PUINT8 buf, UINT16 ReqCount, PUINT16 RealCount ) /* 以字节为单位从当前位置读取数据块 */
{
UINT8 s;
xWriteCH376Cmd( CMD2H_BYTE_READ );
xWriteCH376Data( (UINT8)ReqCount );
xWriteCH376Data( (UINT8)(ReqCount>>8) );
xEndCH376Cmd( );
if ( RealCount ) *RealCount = 0;
while ( 1 ) {
s = Wait376Interrupt( );
if ( s == USB_INT_DISK_READ ) {
s = CH376ReadBlock( buf ); /* 从当前主机端点的接收缓冲区读取数据块,返回长度 */
xWriteCH376Cmd( CMD0H_BYTE_RD_GO );
xEndCH376Cmd( );
buf += s;
if ( RealCount ) *RealCount += s;
}
/* else if ( s == USB_INT_SUCCESS ) return( s );*/ /* 结束 */
else return( s ); /* 错误 */
}
}
UINT8 CH376ByteWrite( PUINT8 buf, UINT16 ReqCount, PUINT16 RealCount ) /* 以字节为单位向当前位置写入数据块 */
{
UINT8 s;
xWriteCH376Cmd( CMD2H_BYTE_WRITE );
xWriteCH376Data( (UINT8)ReqCount );
xWriteCH376Data( (UINT8)(ReqCount>>8) );
xEndCH376Cmd( );
if ( RealCount ) *RealCount = 0;
while ( 1 ) {
s = Wait376Interrupt( );
if ( s == USB_INT_DISK_WRITE ) {
s = CH376WriteReqBlock( buf ); /* 向内部指定缓冲区写入请求的数据块,返回长度 */
xWriteCH376Cmd( CMD0H_BYTE_WR_GO );
xEndCH376Cmd( );
buf += s;
if ( RealCount ) *RealCount += s;
}
/* else if ( s == USB_INT_SUCCESS ) return( s );*/ /* 结束 */
else return( s ); /* 错误 */
}
}
#ifdef EN_DISK_QUERY
UINT8 CH376DiskCapacity( PUINT32 DiskCap ) /* 查询磁盘物理容量,扇区数 */
{
UINT8 s;
s = CH376SendCmdWaitInt( CMD0H_DISK_CAPACITY );
if ( s == USB_INT_SUCCESS ) { /* 参考CH376INC.H文件中CH376_CMD_DATA结构的DiskCapacity */
xWriteCH376Cmd( CMD01_RD_USB_DATA0 );
xReadCH376Data( ); /* 长度总是sizeof(CH376_CMD_DATA.DiskCapacity) */
*DiskCap = CH376Read32bitDat( ); /* CH376_CMD_DATA.DiskCapacity.mDiskSizeSec,从CH376芯片读取32位的数据并结束命令 */
}
else *DiskCap = 0;
return( s );
}
UINT8 CH376DiskQuery( PUINT32 DiskFre ) /* 查询磁盘剩余空间信息,扇区数 */
{
UINT8 s;
UINT8 c0, c1, c2, c3;
s = CH376SendCmdWaitInt( CMD0H_DISK_QUERY );
if ( s == USB_INT_SUCCESS ) { /* 参考CH376INC.H文件中CH376_CMD_DATA结构的DiskQuery */
xWriteCH376Cmd( CMD01_RD_USB_DATA0 );
xReadCH376Data( ); /* 长度总是sizeof(CH376_CMD_DATA.DiskQuery) */
xReadCH376Data( ); /* CH376_CMD_DATA.DiskQuery.mTotalSector */
xReadCH376Data( );
xReadCH376Data( );
xReadCH376Data( );
c0 = xReadCH376Data( ); /* CH376_CMD_DATA.DiskQuery.mFreeSector */
c1 = xReadCH376Data( );
c2 = xReadCH376Data( );
c3 = xReadCH376Data( );
*DiskFre = c0 | (UINT16)c1 << 8 | (UINT32)c2 << 16 | (UINT32)c3 << 24;
xReadCH376Data( ); /* CH376_CMD_DATA.DiskQuery.mDiskFat */
xEndCH376Cmd( );
}
else *DiskFre = 0;
return( s );
}
#endif
UINT8 CH376SecLocate( UINT32 offset ) /* 以扇区为单位移动当前文件指针 */
{
xWriteCH376Cmd( CMD4H_SEC_LOCATE );
xWriteCH376Data( (UINT8)offset );
xWriteCH376Data( (UINT8)((UINT16)offset>>8) );
xWriteCH376Data( (UINT8)(offset>>16) );
xWriteCH376Data( 0 ); /* 超出最大文件尺寸 */
xEndCH376Cmd( );
return( Wait376Interrupt( ) );
}
#ifdef EN_SECTOR_ACCESS
UINT8 CH376DiskReadSec( PUINT8 buf, UINT32 iLbaStart, UINT8 iSectorCount ) /* 从U盘读取多个扇区的数据块到缓冲区,不支持SD卡 */
/* iLbaStart 是准备读取的线性起始扇区号, iSectorCount 是准备读取的扇区数 */
{
UINT8 s, err;
UINT16 mBlockCount;
for ( err = 0; err != 3; ++ err ) { /* 出错重试 */
xWriteCH376Cmd( CMD5H_DISK_READ ); /* 从USB存储器读扇区 */
xWriteCH376Data( (UINT8)iLbaStart ); /* LBA的最低8位 */
xWriteCH376Data( (UINT8)( (UINT16)iLbaStart >> 8 ) );
xWriteCH376Data( (UINT8)( iLbaStart >> 16 ) );
xWriteCH376Data( (UINT8)( iLbaStart >> 24 ) ); /* LBA的最高8位 */
xWriteCH376Data( iSectorCount ); /* 扇区数 */
xEndCH376Cmd( );
for ( mBlockCount = iSectorCount * DEF_SECTOR_SIZE / CH376_DAT_BLOCK_LEN; mBlockCount != 0; -- mBlockCount ) { /* 数据块计数 */
s = Wait376Interrupt( ); /* 等待中断并获取状态 */
if ( s == USB_INT_DISK_READ ) { /* USB存储器读数据块,请求数据读出 */
s = CH376ReadBlock( buf ); /* 从当前主机端点的接收缓冲区读取数据块,返回长度 */
xWriteCH376Cmd( CMD0H_DISK_RD_GO ); /* 继续执行USB存储器的读操作 */
xEndCH376Cmd( );
buf += s;
}
else break; /* 返回错误状态 */
}
if ( mBlockCount == 0 ) {
s = Wait376Interrupt( ); /* 等待中断并获取状态 */
if ( s == USB_INT_SUCCESS ) return( USB_INT_SUCCESS ); /* 操作成功 */
}
if ( s == USB_INT_DISCONNECT ) return( s ); /* U盘被移除 */
CH376DiskReqSense( ); /* 检查USB存储器错误 */
}
return( s ); /* 操作失败 */
}
UINT8 CH376DiskWriteSec( PUINT8 buf, UINT32 iLbaStart, UINT8 iSectorCount ) /* 将缓冲区中的多个扇区的数据块写入U盘,不支持SD卡 */
/* iLbaStart 是写入的线起始性扇区号, iSectorCount 是写入的扇区数 */
{
UINT8 s, err;
UINT16 mBlockCount;
for ( err = 0; err != 3; ++ err ) { /* 出错重试 */
xWriteCH376Cmd( CMD5H_DISK_WRITE ); /* 向USB存储器写扇区 */
xWriteCH376Data( (UINT8)iLbaStart ); /* LBA的最低8位 */
xWriteCH376Data( (UINT8)( (UINT16)iLbaStart >> 8 ) );
xWriteCH376Data( (UINT8)( iLbaStart >> 16 ) );
xWriteCH376Data( (UINT8)( iLbaStart >> 24 ) ); /* LBA的最高8位 */
xWriteCH376Data( iSectorCount ); /* 扇区数 */
xEndCH376Cmd( );
for ( mBlockCount = iSectorCount * DEF_SECTOR_SIZE / CH376_DAT_BLOCK_LEN; mBlockCount != 0; -- mBlockCount ) { /* 数据块计数 */
s = Wait376Interrupt( ); /* 等待中断并获取状态 */
if ( s == USB_INT_DISK_WRITE ) { /* USB存储器写数据块,请求数据写入 */
CH376WriteHostBlock( buf, CH376_DAT_BLOCK_LEN ); /* 向USB主机端点的发送缓冲区写入数据块 */
xWriteCH376Cmd( CMD0H_DISK_WR_GO ); /* 继续执行USB存储器的写操作 */
xEndCH376Cmd( );
buf += CH376_DAT_BLOCK_LEN;
}
else break; /* 返回错误状态 */
}
if ( mBlockCount == 0 ) {
s = Wait376Interrupt( ); /* 等待中断并获取状态 */
if ( s == USB_INT_SUCCESS ) return( USB_INT_SUCCESS ); /* 操作成功 */
}
if ( s == USB_INT_DISCONNECT ) return( s ); /* U盘被移除 */
CH376DiskReqSense( ); /* 检查USB存储器错误 */
}
return( s ); /* 操作失败 */
}
UINT8 CH376SecRead( PUINT8 buf, UINT8 ReqCount, PUINT8 RealCount ) /* 以扇区为单位从当前位置读取数据块,不支持SD卡 */
{
UINT8 s;
UINT8 cnt;
UINT32 StaSec;
UINT32 fsz, fofs;
if ( RealCount ) *RealCount = 0;
do {
xWriteCH376Cmd( CMD01_GET_IC_VER );
cnt = xReadCH376Data( );
if ( cnt == 0x41 ) {
xWriteCH376Cmd( CMD14_READ_VAR32 );
xWriteCH376Data( VAR_FILE_SIZE );
xReadCH376Data( );
fsz = xReadCH376Data( );
fsz |= (UINT16)(xReadCH376Data( )) << 8;
cnt = xReadCH376Data( );
fsz |= (UINT32)cnt << 16;
xWriteCH376Cmd( CMD14_READ_VAR32 );
xWriteCH376Data( VAR_CURRENT_OFFSET );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -