📄 udisk.c
字号:
else {WriteEpBulk(1, sizeof(B_Mode_Sense_ZERO), B_Mode_Sense_ZERO);}
}
///////////////////////////////////////////////////////////////////////////
void SCSI_Read_Format_Capacities()
{
if(bulk_CBW.CBWCB[7]==0 && bulk_CBW.CBWCB[8]==0)return;
WriteEpBulk(1, sizeof(B_Read_Format_capacities), B_Read_Format_capacities);
}
/////////////////////////////////////////////////////////////////////////
void SCSI_Read10()//FLASH读处理函数
{
unsigned char data i;
unsigned char Addr[4];
unsigned char length;
/*读操作的起始地址*/
Addr[2] = bulk_CBW.CBWCB[4];
Addr[3] = bulk_CBW.CBWCB[5];
/*读操作的扇区长度*/
length = bulk_CBW.CBWCB[8];
while(length>0)
{
P5 = COMMAND;
io_port1 = 0x00;//FLASH读命令码
P5 = ADDRESS;
io_port1 = 0;
io_port1 = Addr[3];
io_port1 = Addr[2];
P5 = D_DATA;
UEPNUM=0x01;
UEPSTAX|=DIR;
while(!(P5 & RB));
/*读取一个扇区的数据*/
for(i=0;i<8;i++)
{
ReadFlash();
UEPSTAX|=TXRDY;
while(!(UEPSTAX&TXCMP));
UEPSTAX&=(~(TXCMP)); }
io_port1 = INACTIVE;
length--;
Addr[3]++;
if(Addr[3]==255)
{
Addr[3]=0;
Addr[2]++;
}
}
TransmitCSW();
}
/////////////////////////////////////////
void delay()
{
unsigned char data i=100;
while(i-->0);
}
/////////////////////////////////////////////
void SCSI_Write10() //FLASH写操作
{
unsigned char addr[4];
unsigned char data i=0,length=0,nBeginPage=0;
/*开辟一个数据缓冲区*/
P5 = COMMAND;
io_port1 = 0x60;
P5 = ADDRESS;
io_port1 = BuffBlock;
io_port1 = 0xff;
P5 = COMMAND;
io_port1 = 0xd0;
P5 = D_DATA;
delay();
while(!(P5 & RB));
/*得到写操作的参数--起始扇区号、扇区长度*/
addr[2] = bulk_CBW.CBWCB[4];
addr[3] = bulk_CBW.CBWCB[5];
length = bulk_CBW.CBWCB[8];
nBeginPage = addr[3]&0x1f;
/*把写操作扇区对应的块的数据COPY到缓冲区*/
UEPNUM = 0x02;
delay();
while(!(P5 & RB));
if(nBeginPage>0)
{
for(i=0;i<nBeginPage;i++)
{
P5 = COMMAND;
io_port1 = 0x00;
P5 = ADDRESS;
io_port1 = 0; //A0-A7
io_port1 = (addr[3]&0xe0)|i; //A9-A16
io_port1 = addr[2]; //A17-A24
P5 = D_DATA;
delay();
while(!(P5 & RB));
P5 = COMMAND;
io_port1 = 0x8a;
P5 = ADDRESS;
io_port1 = 0;
io_port1 = BuffBlock|i;
io_port1 = 0xff;
P5 = D_DATA;
delay();
while(!(P5 & RB));
}
nBeginPage=0;
}
/*数据先写到缓冲区*/
while(length>0)
{
P5 = COMMAND;
io_port1 = 0x80;//PAGE写操作码
P5 = ADDRESS;
io_port1 = 0; //A0-A7
io_port1 = (addr[3]&0x1f)|BuffBlock;
io_port1 = 0xff; //A17-A24
P5 = D_DATA;
for(i=0;i<8;i++)
{
while (!(UEPINT & EP2));
WriteFlash();
UEPSTAX &= 0xB9;
}
P5 = COMMAND;
io_port1 = 0x10;
P5 = D_DATA;
length--;
delay();
while(!(P5 & RB));
if(((addr[3]&0x1f)==0x1f)||(length==0))
{
/*保存数据到缓冲区*/
for(i=((addr[3]&0x1f)+1);i<32;i++)
{
P5 = COMMAND;
io_port1 = 0x00;
P5 = ADDRESS;
io_port1 = 0; //A0-A7
io_port1 = (addr[3]&0xe0)|i; //A9-A16
io_port1 = addr[2]; //A17-A24
P5 = D_DATA;
delay();
while(!(P5 & RB));
P5 = COMMAND;
io_port1 = 0x8a;
P5 = ADDRESS;
io_port1 = 0; //A0-A7
io_port1 = BuffBlock|i;
io_port1 = 0xff; //A17-A24
P5 = D_DATA;
delay();
while(!(P5 & RB));
}
/*擦除要写的数据块*/
P5 = COMMAND;
io_port1 = 0x60; //擦除当前block
P5 = ADDRESS;
io_port1 = addr[3]; //A9-A16
io_port1 = addr[2]; //A17-A24
P5 = COMMAND;
io_port1 = 0xd0;
P5 = D_DATA;
delay();
while(!(P5 & RB)); //等待操作完成
/*把缓冲区的数据COPY到指定写的扇区所在块*/
for(i=0;i<32;i++)
{
P5 = COMMAND;
io_port1 = 0x00;
P5 = ADDRESS;
io_port1 = 0; //A0-A7
io_port1 = BuffBlock|i;
io_port1 = 0xff; //A17-A24
P5 = D_DATA;
delay();
while(!(P5 & RB));
P5 = COMMAND;
io_port1 = 0x8a;
P5 = ADDRESS;
io_port1 = 0; //A0-A7
io_port1 = (addr[3]&0xe0)|i; //A9-A16
io_port1 = addr[2]; //A17-A24
P5 = D_DATA;
delay();
while(!(P5 & RB));
}
if(length>0)
{
P5 = COMMAND;
io_port1 = 0x60;
P5 = ADDRESS;
io_port1 = BuffBlock;
io_port1 = 0xff; //A17-A24
P5 = COMMAND;
io_port1 = 0xD0;
P5 = D_DATA;
delay();
while(!(P5 & RB));
}
}
addr[3]++;
if(addr[3]==255)
{
addr[2]++;
}
}
TransmitCSW();
}
//////////////////////////////////
void Ep2()//端口2中断处理函数
{
unsigned char data i;
unsigned char data Buf[64];
i = ReadEp(2,Buf);
bulk_CSW[4] = Buf[4]; bulk_CSW[5] = Buf[5]; bulk_CSW[6] = Buf[6]; bulk_CSW[7] = Buf[7];
for(i=0;i<12;i++) bulk_CBW.CBWCB[i] = Buf[i+15];
switch(bulk_CBW.CBWCB[0])
{
case Inquiry :WriteEpBulk(1,36,B_InquiryData);break;
case Mode_Sense :SCSI_Mode_Sense(); break;
case Read10 :SCSI_Read10(); break;
case Read_Capacity :WriteEpBulk(1, sizeof(B_Read_Capacity), B_Read_Capacity);break;
case Read_Format_Capacities :SCSI_Read_Format_Capacities(); break;
case Test_Unit_Ready :TransmitCSW(); break;
case Verify :TransmitCSW(); break;
case Write10 :SCSI_Write10(); break;
case Medium_Removal :TransmitCSW(); break;
}
}
/////////////////////////////////////
void Flash_Reset(void) //flash reset
{
unsigned int data i;
P5 = COMMAND;
io_port1 = 0xff; //reset command
for (i=0; i<3000; i++) ; //delay
}
////////////////////////////////////
void ReadFlash() //从FLASH读取32个字节数据并保存在端口缓存
{
int i;
for(i=0;i<32;i++)
{
UEPDATX=io_port1;
}
}
///////////////////////////////////
void WriteFlash() //从端口得到32个字节的数据写到FLASH
{
int i;
for(i=0;i<32;i++)
{
io_port1=UEPDATX;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -