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

📄 file_sys.c

📁 基于CH376的U盘读写例子
💻 C
📖 第 1 页 / 共 3 页
字号:
{
	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 + -