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

📄 driver_wr.c

📁 基于U(375)盘及SD(SPI模式)卡集成文件系统(包括底层驱动)
💻 C
字号:
#include "Driver_WR.h"
#include "sd_driver.h"
#include "sd_cmd.h"
#include "ch375_driver.h"
#include "ch375_cmd.h"

extern volatile DSTATUS Stat;
extern volatile unsigned char CardType;
UINT8 sd_u;

/********************************************************************************************************************
** 函数名称: UINT8   RBC_Read( UINT32 iLbaStart, UINT8 iSectorCount,UINT8 xdata *mBufferPoint )
** Name:	 UINT8   RBC_Read( UINT32 iLbaStart, UINT8 iSectorCount,UINT8 xdata *mBufferPoint )
** 功能描述: 读取物理扇区						          
** Function: Read physic sector in the disk
** 输   入: UINT32 iLbaStart  : 扇区开始地址
			 UINT8 iSectorCount  :扇区数目
			 UINT8 xdata *mBufferPoint :数据缓存	  
** Input:    UINT32 iLbaStart  : start address of reading
			 UINT8 iSectorCount  :reading sector number
			 UINT8 xdata *mBufferPoint :the reading buffer
** 输   出: 0:   正确    >0:   错误码		  		  
** Output:	  0:  right		>0:  error code
*********************************************************************************************************************/
UINT8   RBC_Read( UINT32 iLbaStart, UINT8 iSectorCount,UINT8 xdata *mBufferPoint )
{
if(!sd_u)            ////sd card
{	
	if(!iSectorCount) 
	{
		printf("Error: RBC_Read() Parameter error \n");
		return CH_ERROR;
	}
	if(Stat == STA_NOINIT) 
	{
		printf("Error: RBC_Read() Chip is not inited \n");
		return CH_ERROR;
	}
	if(!(CardType==8)) iLbaStart = iLbaStart*512;
	SPI_TransferByte(0xff);
	if(iSectorCount ==1)
	{
		if((Write_Command_MMC(CMD17,iLbaStart)<=1)&&rcvr_datablock(mBufferPoint,512))
			iSectorCount = 0;
	}
	else
	{
		if(Write_Command_MMC(CMD18,iLbaStart)==0)
		{
			do{
				if(!rcvr_datablock(mBufferPoint, 512)) 
					break;
				mBufferPoint =mBufferPoint + 512;
			}while(--iSectorCount);
			Write_Command_MMC(CMD12,0);
		}
	}
	SPI_TransferByte(0xff);
	if(iSectorCount)
	{
		printf("Error: RBC_Read() quit, write is not finished \n");
		return CH_ERROR;
	}
	else
	{
//		printf("Success: RBC_Read() success \n");
		return CH_OK;
	}
}



else
{
	UINT8 mIntStatus;
    UINT16  mBlockCount;
    UINT8 mLength;
    UINT8 i;
	for( i=0; i!=3; i++ )
    {
        CH375_CMD_PORT_d_out(CMD_DISK_READ);  /* 从USB存储器读数据块 */
        CH375_DAT_PORT_d_out((UINT8)iLbaStart);  /* LBA的最低8位 */
        CH375_DAT_PORT_d_out((UINT8)(iLbaStart >> 8 ));
        CH375_DAT_PORT_d_out((UINT8)(iLbaStart >> 16 ));
        CH375_DAT_PORT_d_out((UINT8)( iLbaStart >> 24 ));  /* LBA的最高8位 */
        CH375_DAT_PORT_d_out( iSectorCount);  /* 扇区数 */
        for ( mBlockCount = iSectorCount * CH375_BLK_PER_SEC; mBlockCount != 0; mBlockCount -- ) {  /* 数据块计数 */
            mIntStatus = mWaitInterrupt( );  /* 等待中断并获取状态 */
            if ( mIntStatus == USB_INT_DISK_READ ) {  /* USB存储器读数据块,请求数据读出 */
                CH375_CMD_PORT_d_out(CMD_RD_USB_DATA);  /* 从CH375缓冲区读取数据块 */
                mLength = CH375_DAT_PORT_d_in();  /* 后续数据的长度 */
                /* 通常数据长度是64,有些U盘要求单片机必须在2mS之内取走64字节数据,否则U盘可能数据丢失 */
                /* 建议优化下面的循环程序,确保单片机在1mS之内完成64字节的数据传输 */
                if ( mLength ) {  /* 根据长度读取数据 */
                    do {  // 对于C51,这个DO+WHILE结构效率高,速度快
                        *mBufferPoint = CH375_DAT_PORT_d_in();  /* 读出数据并保存 */
                        mBufferPoint ++;
                    } while ( -- mLength );
                }
                CH375_CMD_PORT_d_out( CMD_DISK_RD_GO);  /* 继续执行USB存储器的读操作 */
            }
            else
            {
            	printf("mIntStatus is not USB_INT_DISK_READ \n");   //0x1F 错误
                break;
            }
        }
        if ( mBlockCount == 0 ) 
        {
            mIntStatus = mWaitInterrupt( );  /* 等待中断并获取状态 */
            if ( mIntStatus == USB_INT_SUCCESS ) 
                return CH_OK;  /* 操作成功 */
            else if( mIntStatus == USB_INT_DISK_ERR )
            {
                DelayMs( 50 );
                CH375_CMD_PORT_d_out( 	CMD_DISK_R_SENSE ); /* 获取USB存储器的容量 */
                mIntStatus = mWaitInterrupt( );                 /* 等待中断并获取状态 */
                if ( mIntStatus != USB_INT_SUCCESS )            /* 出现错误 */
                {
                	printf("Error: read sector Error! position 1 \n");
                    return CH_ERROR;
                 }
            }
        }
    }
    //CSTR( "mIntStatus: ", 0 );
    //CHEX( &mIntStatus, 1, 1 );
    printf("Error: read sector Error! position 2 \n");
    return CH_ERROR;  /* 操作失败 */
}
	
}
/********************************************************************************************************************
** 函数名称: UINT8   RBC_Write( UINT32 iLbaStart, UINT8 iSectorCount,UINT8 xdata *mBufferPoint )
** Name:	 UINT8   RBC_Write( UINT32 iLbaStart, UINT8 iSectorCount,UINT8 xdata *mBufferPoint )
** 功能描述: 写物理扇区						          
** Function: Write physic sector in the disk
** 输   入: UINT32 iLbaStart  : 扇区开始地址
			 UINT8 iSectorCount  :扇区数目
			 UINT8 xdata *mBufferPoint :数据缓存	  
** Input:    UINT32 iLbaStart  : start address of reading
			 UINT8 iSectorCount  :sector number
			 UINT8 xdata *mBufferPoint :the Writting buffer
** 输   出: 0:   正确    >0:   错误码		  		  
** Output:	  0:  right		>0:  error code
*********************************************************************************************************************/

UINT8 RBC_Write(UINT32 iLbaStart, UINT8 iSectorCount,UINT8 xdata *mBufferPoint)
{
if(!sd_u)
{
	UINT8 temp;
	UINT16 write_wait = 65535;
	if(!iSectorCount) 
	{
		printf("Error: RBC_Write() Parameter error \n");
		return CH_ERROR;
	}
	if(Stat == STA_NOINIT) 
	{
		printf("Error: RBC_Write() Chip is not inited \n");
		return CH_ERROR;
	}
	if(Stat == STA_PROTECT) 
	{
		printf("Error: RBC_Write() Chip is protected \n");
		return CH_ERROR;
	}
	
	if(!(CardType & 8)) iLbaStart = iLbaStart * 512;
	SPI_TransferByte(0xff);
	SPI_TransferByte(0xff);  //wait at least 8 clock
	if(iSectorCount == 1)
	{
		if(Write_Command_MMC(CMD24, iLbaStart)==0x00)
		{
			if(xmit_datablock(mBufferPoint,0xFE))
				iSectorCount = 0;
			write_wait = 65535;
			do{
				temp = SPI_TransferByte(0xff);
				write_wait--;
			}while((temp!=0xff)&&write_wait);    //wait for write complete
			if(!write_wait)	
			{
				printf("Error: RBC_Write(), single sector write time out \n");
				return CH_ERROR;
			}
		}
				
	}
	else
	{
		if(CardType == 6) 
			Write_Command_MMC(ACMD23, iSectorCount);
		if(Write_Command_MMC(CMD25,iLbaStart)==0x00)
		{
			do{
				if(!xmit_datablock(mBufferPoint,0xFC)) break;
					mBufferPoint = mBufferPoint +512;
					write_wait = 65535;
					do{
						temp = SPI_TransferByte(0xff);
						write_wait--;
					}while((temp!=0xff)&&write_wait);
					if(!write_wait)	
					{
						printf("Error: RBC_Write(), multi sectors write time out \n");
						return CH_ERROR;
					}
			}while(--iSectorCount);
			xmit_datablock(0,0xFD);
			write_wait = 65535;
			do{
				temp = SPI_TransferByte(0xff);
				write_wait--;
			}while((temp!=0xff)&&write_wait);
			if(!write_wait)	
			{
				printf("Error: RBC_Write(), write return to ilde time out \n");
				return CH_ERROR;
			}
		}
	}
	if(iSectorCount)
	{
		printf("Error: RBC_Write() quit, write is not finished \n");
		return CH_ERROR;
	}
	else
	{
//		printf("Success: RBC_Write() success \n");
		return CH_OK;
	}
}

else
{
	UINT8 mIntStatus;
    UINT16  mBlockCount;
    UINT8 mLength;

    CH375_CMD_PORT_d_out( CMD_DISK_WRITE);  /* 向USB存储器写数据块 */
    CH375_DAT_PORT_d_out((UINT8)iLbaStart);  /* LBA的最低8位 */
    CH375_DAT_PORT_d_out((UINT8)( iLbaStart >> 8 ));
    CH375_DAT_PORT_d_out((UINT8)( iLbaStart >> 16 ));
    CH375_DAT_PORT_d_out((UINT8)( iLbaStart >> 24 ));  /* LBA的最高8位 */
    CH375_DAT_PORT_d_out(iSectorCount);  /* 扇区数 */
    //mBufferPoint = &DATA_BUFFER;  /* 指向缓冲区起始地址 */
    for ( mBlockCount = iSectorCount * CH375_BLK_PER_SEC; mBlockCount != 0; mBlockCount -- ) {  /* 数据块计数 */
        mIntStatus = mWaitInterrupt( );  /* 等待中断并获取状态 */
        if ( mIntStatus == USB_INT_DISK_WRITE ) {  /* USB存储器写数据块,请求数据写入 */
            CH375_CMD_PORT_d_out( CMD_WR_USB_DATA7);  /* 向CH375缓冲区写入数据块 */
            mLength = CH375_BLOCK_SIZE;
            CH375_DAT_PORT_d_out(mLength);  /* 后续数据的长度 */
            /* 通常数据长度是64,有些U盘要求单片机必须在2mS之内写入64字节数据,否则U盘可能数据丢失 */
            /* 建议优化下面的循环程序,确保单片机在1mS之内完成64字节的数据传输 */
            do {  // 对于C51,这个DO+WHILE结构效率高,速度快
                CH375_DAT_PORT_d_out(*mBufferPoint);  /* 将数据写入 */
                mBufferPoint ++;
            } while ( -- mLength );
            CH375_CMD_PORT_d_out( CMD_DISK_WR_GO);  /* 继续执行USB存储器的写操作 */
        }
        else break;  /* 返回错误状态 */
    }
    if ( mBlockCount == 0 ) {
        mIntStatus = mWaitInterrupt( );  /* 等待中断并获取状态 */
        if ( mIntStatus == USB_INT_SUCCESS ) return CH_OK;  /* 操作成功 */
    }
    printf("Error: Write sector Error!\n");
    return CH_ERROR;  /* 操作失败 */
}
}





⌨️ 快捷键说明

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