📄 usb.c
字号:
while(!(UEPSTAX&TXCMP)) ;
UEPSTAX&=(~(TXCMP)); //清除TXCMP
UEPINT = 0;
}
void main_txdone() //数据发送完毕给出回复
{
UEPSTAX&=(~(TXCMP)); //清除TXCMP
TransmitCSW();
}
//////////////////////////////////有关输出端点的调用//////////////////////////////////////////////
#define Inquiry 0x12
#define Mode_Sense 0x1A
#define Read10 0x28
#define Read_Capacity 0x25
#define Read_Format_Capacities 0x23
#define Test_Unit_Ready 0x00
#define Verify 0x2F
#define Write10 0x2A
#define Medium_Removal 0x1E
#define SCSI_MSPGCD_TPP 0x1C
#define SCSI_MSPGCD_RETALL 0x3F
//SCSI-Inquiry命令的返回数据
code unsigned char B_InquiryData[] = {
0x00, //Direct Access Device
0x80, //RMB
0x00, //ISO/ECMA/ANSI
0x01, //Response Data Format
0x1f, //Additional Length
0x00, //Reserved
0x00, //Reserved
0x00, //Reserved
'K', 'T', '-', 'T', 'E', 'C', 'H', ' ', //Vendor Information
'M', 'P', '3', ' ', 'P', 'l', 'a', 'y', 'e', 'r', ' ', 'V', '1', '.', '0', '0',//Product Identification
0, 0, 0, 0}; //Product Revision Level n.nn
//SCSI-Read_Format_capacities命令的返回数据
code unsigned char B_Read_Format_capacities[] = {0x00, 0x00, 0x00, 0x10, //capacity list header
0x00, 0x00, 0x07, 0xf5, 0x01, 0x00, 0x02, 0x00, //capacity descriptor
//Number of Blocks =2037,unformatted media,blocklength = 512Bytes
0x00, 0x00, 0x07, 0xfd, 0x00, 0x00, 0x02, 0x00 //Formattable Capacity Descriptors
};
//SCSI-Read_Capacity命令的返回数据
code unsigned char B_Read_Capacity[] = {
0x00, 0x00, 0xfe, 0xa0, //Last Logical Block Address for 32MB
0x00, 0x00, 0x02, 0x00 //block length in bytes
};
//SCSI-Mode_Sense命令的返回数据
code unsigned char B_Mode_Sense_ALL[] = {0x0b, 0x00, //Mode Data Length
0x00, 0x08, 0x00, 0x00,
0x7d, 0, 0, 0, 0x02, 0x00
};
//SCSI-Mode_Sense命令的返回数据
code unsigned char B_Mode_Sense_TPP[] = {0xf0, 0x00, //Mode Data Length
05, 00, 00, 00, 00, 0x0b, 00, 00, 00, 00, 0x24, 00, 00, 00, 00, 00
};
//SCSI-Mode_Sense命令的返回数据
code unsigned char B_Mode_Sense_ZERO[] = {0x00, 0x06, //Mode Data Length
0x00, //Medium Type Code
0, //write enabled
0, 0, 0, 0 //reserved
};
void SCSI_Mode_Sense()
{
if(bulk_CBW.CBWCB[2] == SCSI_MSPGCD_TPP) //Page Code=Timer and Potect Page
{WriteEpBulk(1, sizeof(B_Mode_Sense_TPP), B_Mode_Sense_TPP);}
else if(bulk_CBW.CBWCB[2] == SCSI_MSPGCD_RETALL) //Page Code=All
{WriteEpBulk(1, sizeof(B_Mode_Sense_ALL), B_Mode_Sense_ALL);}
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);
}
extern void ReadFlash();
extern void WriteFlash();
void SCSI_Read10()
{
unsigned char data i;
union
{
unsigned long Block;
unsigned char Addr[4];
}data BLK;
unsigned char length; //传输的簇数
//将起始地址变换为K9F5608适合的模式;
// BLK.Addr[0] = bulk_CBW.CBWCB[2];
// BLK.Addr[1] = bulk_CBW.CBWCB[3];
BLK.Addr[2] = bulk_CBW.CBWCB[4];
BLK.Addr[3] = bulk_CBW.CBWCB[5];
//将扇区数填入计数变量每循环一次读出一扇区的值;
// PG.Addr[0] = bulk_CBW.CBWCB[7];
// PG.Addr[1] = bulk_CBW.CBWCB[8];
length = bulk_CBW.CBWCB[8];
while(length>0)
{
K9F_FUN = COMMAND; //读出一个page
*((unsigned char xdata *)K9F5608) = 0x00;
K9F_FUN = ADDRESS;
*((unsigned char xdata *)K9F5608) = 0; //A0-A7
*((unsigned char xdata *)K9F5608) = BLK.Addr[3]; //A9-A16
*((unsigned char xdata *)K9F5608) = BLK.Addr[2]; //A17-A24
K9F_FUN = D_DATA;
UEPNUM=0x01; //指向端点
UEPSTAX|=DIR; //传输方向
while(!(K9F_FUN & RB));
for(i=0;i<8;i++) //读出512个字节的数据发送到usb
{
ReadFlash();
UEPSTAX|=TXRDY;
while(!(UEPSTAX&TXCMP)); //等待发送完成
UEPSTAX&=(~(TXCMP)); //清中断标志clear TXCMP
UEPINT=0;
}
*((unsigned char xdata *)K9F5608) = INACTIVE;
length--; //传输的簇数减1
BLK.Block ++; //flash的页地址加1
}
TransmitCSW(); //返回CSW
}
void delay() //延时20us
{
unsigned char data i=10;
while(i-->0);
}
#define BuffBlock (0xc0) //缓冲区为从偶数块开始的连续两个Block 这里定为2046和2047两个Block
//BuffBlock只代表块号的低字节
void SCSI_Write10() //之所以选用两个Block作为缓冲区,与Flash的Copy - Back功能的特性相关,
{ //清仔细阅读Flash 的datasheet
unsigned char Page_Buf[512];
unsigned int j;
union
{
unsigned long page;
unsigned char addr[4];
}data PG;
unsigned char data i=0,length=0,nBeginPage=0;
//所有写入都要缓冲,所以先清除缓冲区
K9F_FUN = COMMAND;
*((unsigned char xdata *)K9F5608) = 0x60; //擦除第2046个Block作为缓冲区
K9F_FUN = ADDRESS;
*((unsigned char xdata *)K9F5608) = BuffBlock; //A9-A16
*((unsigned char xdata *)K9F5608) = 0xff; //A17-A24
K9F_FUN = COMMAND;
*((unsigned char xdata *)K9F5608) = 0xd0;
K9F_FUN = D_DATA;
delay();
// printuf(" %x",PG.addr[0]);printuf(" %x",PG.addr[1]);printuf(" %x",PG.addr[2]);printuf(" %x",PG.addr[3]);
// printuf(" %x",length); printuf(" %x",nBeginPage);
while(!(K9F_FUN & RB)); //等待擦除操作的完成
K9F_FUN = COMMAND;
*((unsigned char xdata *)K9F5608) = 0x60; //擦除第2047个Block作为缓冲区
K9F_FUN = ADDRESS;
*((unsigned char xdata *)K9F5608) = BuffBlock|0x20; //A9-A16
*((unsigned char xdata *)K9F5608) = 0xff; //A17-A24
K9F_FUN = COMMAND;
*((unsigned char xdata *)K9F5608) = 0xd0;
K9F_FUN = D_DATA;
delay();
while(!(K9F_FUN & RB));
//从SCSI命令中分离出逻辑地址
// PG.addr[0] = bulk_CBW.CBWCB[2];
// PG.addr[1] = bulk_CBW.CBWCB[3];
PG.addr[2] = bulk_CBW.CBWCB[4]; //PG为前面定义的结构体
PG.addr[3] = bulk_CBW.CBWCB[5];
length = bulk_CBW.CBWCB[8]; //windows 系统每次写入的最大长度为0x80个扇区取一字节已够用
nBeginPage = PG.addr[3]&0x1f; //计算出要写入块内的要写入的起始扇区号
UEPNUM = 0x02; //指向Bulk端点2
delay();
while(!(K9F_FUN & RB)); //等待擦除操作的完成
if(nBeginPage>0) //如果起始写入page与flash的Block未对齐,则将当前Block中的前nBeginPage页
{ //拷贝到缓冲区的相同位置
for(i=0;i<nBeginPage;i++)
{
/*COPY BACK命令 001*************************
K9F_FUN = COMMAND;
*((unsigned char xdata *)K9F5608) = 0x00; //命令的第一个字节
K9F_FUN = ADDRESS;
*((unsigned char xdata *)K9F5608) = 0; //A0-A7
*((unsigned char xdata *)K9F5608) = (PG.addr[3]&0xe0)|i; //A9-A16
*((unsigned char xdata *)K9F5608) = PG.addr[2]; //A17-A24
K9F_FUN = D_DATA;
delay();
while(!(K9F_FUN & RB)); //等待操作的完成
K9F_FUN = COMMAND;
*((unsigned char xdata *)K9F5608) = 0x8a; //命令的第二个字节
K9F_FUN = ADDRESS;
*((unsigned char xdata *)K9F5608) = 0; //A0-A7
*((unsigned char xdata *)K9F5608) = BuffBlock|(PG.addr[3]&0x20)|i; //A9-A16
*((unsigned char xdata *)K9F5608) = 0xff; //A17-A24
K9F_FUN = D_DATA;
delay();
while(!(K9F_FUN & RB)); //等待操作的完成
END OF COPY BACK命令 001**************************/
//void ReadPage(unsigned int block, unsigned int page, unsigned char *pPage)
//unsigned int blockPage = (block << 5) | page;
K9F_FUN = COMMAND;
*((unsigned char xdata *)K9F5608) = 0x00;
K9F_FUN = ADDRESS;
*((unsigned char xdata *)K9F5608) = 0; //A0-A7
*((unsigned char xdata *)K9F5608) = (PG.addr[3]&0xe0)|i; //A9-A16
*((unsigned char xdata *)K9F5608) = PG.addr[2]; //A17-A24
K9F_FUN = D_DATA;
while(!(K9F_FUN & RB)); //等待操作的完成
for(j=0;j<512;j++)
{
Page_Buf[j]= *((unsigned char xdata *)K9F5608);
}
//int WritePage(unsigned int block, unsigned int page, unsigned char *pPage)
//{
//j = 512;
//unsigned int blockPage = (block << 5) + page;
K9F_FUN = COMMAND;
*((unsigned char xdata *)K9F5608) = 0x80;
K9F_FUN = ADDRESS;
*((unsigned char xdata *)K9F5608) = 0;
*((unsigned char xdata *)K9F5608) = BuffBlock|(PG.addr[3]&0x20)|i;
*((unsigned char xdata *)K9F5608) =0xff;
K9F_FUN = D_DATA;
for(j=0;j<512;j++)
{
*((unsigned char xdata *)K9F5608)= Page_Buf[j];
}
K9F_FUN = COMMAND;
*((unsigned char xdata *)K9F5608) = 0x10;
delay();
while(!(K9F_FUN & RB)); //等待操作的完
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -