📄 usb_disk.c
字号:
/* Copyright (C) 1996-2005 Brilliant Ideal Electronics. All rights reserved.
MP3_Player+USB_Disk V3.0 Edit by JMBIE STUDIO 2005.03
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "AT89C51SND1_REG.H"
#include "UDISK_DEF.H"
extern void ReadFlash(); //Defined in FLASH_RW.C
extern void WriteFlash();
code unsigned char Device_Descriptor[18] = {
0x12, //0x12
0x01, //DEVICE descriptor
0x10, 0x01, //spec rev level (BCD) 1.0
0x0, //device class
0x0, //device subclass
0x0, //device protocol
0x20, //max packet size
0x05, 0x82, //National's vendor ID
0x00, 0x11, //National's product ID
0x00, 0x00, //National's revision ID
0, //index of manuf. string
0, //index of prod. string
0, //index of ser. # string
0x01 //number of configs.
};
code unsigned char Configuration_Descriptor_All[32] = {
9, //Size of Descriptor in Bytes
2, //Configuration Descriptor (0x02)
0x20, //Total length in bytes of data returned LSB
0x00, //MSB
1, //Number of Interfaces
1, //Value to use as an argument to select this configuration
0, //Index of String Descriptor describing this configuration
0x80,
0xfa, //Maximum Power Consumption in 2mA units
9,
4,
0, //the index of the interface descriptor Number of Interface
0, //Value used to select alternative setting
2, //EndPoint Number Used in this Descriptor
8, //Class Code (Assigned by USB Org)
6, //interface subclass1=RBC,2=SFF,3=QIC,4=UFI,5=SFF,6=SCSI
0x50, //bulk 0nly Transport
0, //Index of String Descriptor Describing this interface
//Bulk-in Endpoint
0x07, //length of this desc.
0x05, //ENDPOINT descriptor TYPE
0x81, //address (IN) Endpoint 4 84
0x02, //attributes (BULK)
0x40, 0x00, //max packet size (64)
0x0, //Does not apply to Bulk endpoints
//Bulk-out Endpoint
0x07, //length of this desc.
0x05, //ENDPOINT descriptor TYPE
0x02, //address (OUT) Endpoint 5 05
0x02, //attributes (BULK)
0x40, 0x00, //max packet size (64)
0x0 //Does not apply to Bulk endpoints
};
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
'J', 'M', 'B', 'I', 'E', ' ', ' ', ' ', //Vendor Information
'U', 'S', 'B', '-', 'M', 'P', '3', ' ', 'V', '3', '.', '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
};
unsigned char data bulk_CSW[]={0x55,0x53,0x42,0x53, //bytes 4 dCSWSignature
0x00,0x00,0x00,0x00, //bytes 4 dCSWTag
0x00,0x00,0x00,0x00, //bytes 4 dDataResiduce
0x00}; //bCSWStatus 00=good state.
struct_CBW data bulk_CBW;
void AtmelUSBInit()
{
int data i;
PLLNDIV = 0x04;
PLLCON |= (0x3&Rdiv)<<6;
PLLRDIV = (0x3ff&Rdiv)>>2;
USBCLK=0;
PLLCON&=(~PLLRES);
PLLCON|=PLLEN;
USBCON&=(~USBE);
for(i=0;i<3000;i++);
USBCON|=USBE;
}
void EpEnable(void)
{
UEPNUM=0x00; UEPCONX=0x80;
UEPNUM=0x01; UEPCONX=0x86;
UEPNUM=0x02; UEPCONX=0x82;
UEPRST=0x07; UEPRST= 0x00;
UEPIEN=0x07; USBIEN|=EEOFINT;
USBADDR=FEN;
}
unsigned char ReadEp(unsigned char EpNum,unsigned char *Data)
{
unsigned char data i=0;
UEPNUM=EpNum;
while(i<UBYCTLX)
{
Data[i++]=UEPDATX;
}
UEPSTAX&=~(RXOUTB0|RXOUTB1|RXSETUP);
return(i);
}
void WriteEp(unsigned char EpNum,unsigned char nLength,unsigned char *Data)
{
unsigned char data i=0;
UEPNUM=EpNum;
UEPSTAX|=DIR;
while(nLength--) UEPDATX=Data[i++];
UEPSTAX|=TXRDY;
while(!(UEPSTAX&TXCMP)) ;
UEPSTAX&=(~(TXCMP));
}
void Set_Address(unsigned char EpNum)
{
WriteEp(0,0,0);
USBADDR|=EpNum;
USBADDR|=FEN;
USBCON|=FADDEN;
}
void Get_Descriptor(unsigned char DesType,unsigned char nLength)
{
if(DesType==0x01)
WriteEp(0,18,Device_Descriptor);
if((DesType==0x02)&&(nLength==0x09))
WriteEp(0,9,Configuration_Descriptor_All);
if((DesType==0x02)&&(nLength==0xff))
{
WriteEp(0,32,Configuration_Descriptor_All);
WriteEp(0,2,&Device_Descriptor[4]);
}
if((DesType==0x02)&&(nLength==0x20))
WriteEp(0,32,Configuration_Descriptor_All);
}
void Set_Configuration(unsigned char wValue)
{
if(wValue == 0)
{
UEPNUM=0x00; UEPCONX=0x80;
UEPNUM=0x01; UEPCONX=0x86;
UEPNUM=0x02; UEPCONX=0x82;
USBCON&=(~CONFG);
WriteEp(0,0,0);
}
else if(wValue == 1)
{
UEPNUM=0x00; UEPCONX=0x80;
UEPNUM=0x01; UEPCONX=0x86;
UEPNUM=0x02; UEPCONX=0x82;
USBCON|=CONFG;
WriteEp(0,0,0);
}
}
void Ep0()
{
unsigned char data DT[32]={0,};
unsigned char data i;
i = ReadEp(0,DT);
if (((DT[0] & 0x60)==0) && i)
{
switch (DT[1])
{
case set_address :Set_Address(DT[2]); break;
case get_descriptor :Get_Descriptor(DT[3],DT[6]); break;
case set_configuration :Set_Configuration(DT[2]); break;
default :; break;
}
}
else if(DT[0]==0xa1)
{
WriteEp(0,0,0);
}
}
void WriteEpBulk(unsigned char EpNum,unsigned char nLength,unsigned char *Data)
{
unsigned char data i;
UEPNUM=EpNum;
UEPSTAX|=DIR;
for(i=0;i<nLength;i++) UEPDATX=Data[i];
UEPSTAX|=TXRDY;
}
void TransmitCSW()
{
WriteEpBulk(1, sizeof(bulk_CSW), bulk_CSW);
while(!(UEPSTAX&TXCMP)) ;
UEPSTAX&=(~(TXCMP));
}
void main_txdone()
{
UEPSTAX&=(~(TXCMP));
TransmitCSW();
}
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);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -