📄 mass_stg.c
字号:
/*******************************************************************************************
USB MASS STORAGE Source Code
Create By: Sen Xu
Date: 09/10/2007
Version: V1.0
Note: Only for Study and not for cometial use
*******************************************************************************************/
#include "c8051f320.h"
#include "intrins.h"
#include "USB.h"
#include "UFI.h"
#include "flash.c"
#define MaxSize 0x40
#define BIT0 0x01
#define BIT1 0x02
#define BIT2 0x04
#define BIT3 0x08
#define BIT4 0x10
#define BIT5 0x20
#define BIT6 0x40
#define BIT7 0x80
///////////////////////////////////////////////////////////////////////////////////////////
//Descriptors
#define DEVICE 0x01
#define CONFIG 0x02
#define STRING 0x03
#define INTERFACE 0x04
#define ENDPOINT 0x05
///////////////////////////////////////////////////////////////////////////////////////////
//Host Requst Report
#define Set_Addr 0x05
#define Get_Descriptor 0x06
#define Set_Config 0x09
#define Set_Interface 0x11
///////////////////////////////////////////////////////////////////////////////////////////
//Mass Storage class Specitial Requst
#define Get_Max_Lun 0xFE
#define Mass_Storage_Reset 0xFF
///////////////////////////////////////////////////////////////////////////////////////////
extern void Oscillator_Init(void);
extern void System_Config(void);
extern void USB_Config(void);
extern void SFR_WR(uchar,uchar);
extern uchar SFR_RD(uchar);
extern void Delay_uS(uint);
extern void Delay_mS(uchar);
extern void Analysis_Requst(Requst *);
extern uint Swap(uint);
extern void FIFO_WR(uchar *, uchar, uint) reentrant;
extern void FIFO_RD(uchar,uchar);
extern void CLR_Flags(void);
extern void Analysis_UFI(void);
extern void BulkOut_Process(void);
extern ulong exchange(ulong);
extern void Read_ID(void);
extern void write_cmd(uchar);
extern void write_addr(uchar);
extern void write_addr_2byte(uchar, uchar);
extern void write_addr_3byte(uchar, uchar, uchar);
extern uchar read_dat(void);
extern void write_dat(uchar);
extern uchar read_status(void);
extern uchar block_erase(uchar,uchar);
extern uchar page_program(uchar *,uchar, uchar, uchar, uint);
extern uchar copy_back(uchar ,uchar , uchar , uchar , uchar , uchar);
extern void page_read(uchar ,uchar , uchar) ;
extern void check_invalid(void);
extern void test_flash(void);
extern void fill_DBR(void);
extern void block_buffer(uint);
/*****************************************************************************************
Interrupt Flag Data Structure for Program jump
******************************************************************************************/
typedef struct Flag
{
uchar epin1;
uchar epout1;
}Flags;
/****************************************************************************************
UFI CBW DATA STRUCTURE
*****************************************************************************************/
code uchar Return_Inquiry[36] =
{
0x00, //Device Type
0x80, //Removable media
0x00,
0x01,
0x1F,
'x','u','s','e','n','C','H','F', //VID
0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,
0x38,0x39,0x30,0x31,0x32,0x33,0x34,0x35,
'V','1','.','0'
};
code uchar Return_Read_Format[20] =
{
0x00,0x00,0x00,0x10, //Capacity List Header
0x00,0x00,0xFA,0x00, //Block number
0x01,0x00,0x02,0x00, //sector length 512byte
0x00,0x00,0xFA,0x00,
0x00,0x00,0x02,0x00
};
code uchar Return_Read_Cap [8] =
{
0x00,0x00,0xFA,0x00, //Mediu Capacity
0x00,0x00,0x02,0x00
};
code uchar Sense[8] =
{
0x45, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00
};
code uchar DBR[512] =
{
0xeb, 0x58, 0x90,
0x4d, 0x53, 0x44, 0x4f, 0x53, 0x35, 0x2e, 0x30,
0x00, 0x02,
0x01,
0x01, 0x00,
0x02,
0xB0, 0x00,
0x00, 0xfa,
0xf8,
0xFA, 0x00,
0x3F, 0x00,
0xFF, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x80,
0x00,
0x029,
0xA8, 0x8B, 0x36, 0x52,
0x4E, 0x4F, 0x20, 0x4E, 0x41, 0x4D, 0x45, 0x20, 0x20, 0x20, 0x20,
0x46, 0x41, 0x54, 0x31, 0x36, 0x20, 0x20, 0x20,
0xf1, 0x7d,
0xfa, 0x33, 0xc9, 0x8e, 0xd1, 0xbc, 0xfc, 0x7b, 0x16, 0x07, 0xbd, 0x78, 0x00, 0xc5, 0x76, 0x00,
0x1e, 0x56, 0x16, 0x55, 0xbf, 0x22, 0x05, 0x89, 0x7e, 0x00, 0x89, 0x4e, 0x02, 0xb1, 0x0b, 0xfc,
0xf3, 0xa4, 0x06, 0x1f, 0xbd, 0x00, 0x7c, 0xc6, 0x45, 0xfe, 0x0f, 0x8b, 0x46, 0x18, 0x88, 0x45,
0xf9, 0xfb, 0x38, 0x66, 0x24, 0x7c, 0x04, 0xcd, 0x13, 0x72, 0x3c, 0x8a, 0x46, 0x10, 0x98, 0xf7,
0x66, 0x16, 0x03, 0x46, 0x1c, 0x13, 0x56, 0x1e, 0x03, 0x46, 0x0e, 0x13, 0xd1, 0x50, 0x52, 0x89,
0x46, 0xfc, 0x89, 0x56, 0xfe, 0xb8, 0x20, 0x00, 0x8b, 0x76, 0x11, 0xf7, 0xe6, 0x8b, 0x5e, 0x0b,
0x03, 0xc3, 0x48, 0xf7, 0xf3, 0x01, 0x46, 0xfc, 0x11, 0x4e, 0xfe, 0x5a, 0x58, 0xbb, 0x00, 0x07,
0x8b, 0xfb, 0xb1, 0x01, 0xe8, 0x94, 0x00, 0x72, 0x47, 0x38, 0x2d, 0x74, 0x19, 0xb1, 0x0b, 0x56,
0x8b, 0x76, 0x3e, 0xf3, 0xa6, 0x5e, 0x74, 0x4a, 0x4e, 0x74, 0x0b, 0x03, 0xf9, 0x83, 0xc7, 0x15,
0x3b, 0xfb, 0x72, 0xe5, 0xeb, 0xd7, 0x2b, 0xc9, 0xb8, 0xd8, 0x7d, 0x87, 0x46, 0x3e, 0x3c, 0xd8,
0x75, 0x99, 0xbe, 0x80, 0x7d, 0xac, 0x98, 0x03, 0xf0, 0xac, 0x84, 0xc0, 0x74, 0x17, 0x3c, 0xff,
0x74, 0x09, 0xb4, 0x0e, 0xbb, 0x07, 0x00, 0xcd, 0x10, 0xeb, 0xee, 0xbe, 0x83, 0x7d, 0xeb, 0xe5,
0xbe, 0x81, 0x7d, 0xeb, 0xe0, 0x33, 0xc0, 0xcd, 0x16, 0x5e, 0x1f, 0x8f, 0x04, 0x8f, 0x44, 0x02,
0xcd, 0x19, 0xbe, 0x82, 0x7d, 0x8b, 0x7d, 0x0f, 0x83, 0xff, 0x02, 0x72, 0xc8, 0x8b, 0xc7, 0x48,
0x48, 0x8a, 0x4e, 0x0d, 0xf7, 0xe1, 0x03, 0x46, 0xfc, 0x13, 0x56, 0xfe, 0xbb, 0x00, 0x07, 0x53,
0xb1, 0x04, 0xe8, 0x16, 0x00, 0x5b, 0x72, 0xc8, 0x81, 0x3f, 0x4d, 0x5a, 0x75, 0xa7, 0x81, 0xbf,
0x00, 0x02, 0x42, 0x4a, 0x75, 0x9f, 0xea, 0x00, 0x02, 0x70, 0x00, 0x50, 0x52, 0x51, 0x91, 0x92,
0x33, 0xd2, 0xf7, 0x76, 0x18, 0x91, 0xf7, 0x76, 0x18, 0x42, 0x87, 0xca, 0xf7, 0x76, 0x1a, 0x8a,
0xf2, 0x8a, 0x56, 0x24, 0x8a, 0xe8, 0xd0, 0xcc, 0xd0, 0xcc, 0x0a, 0xcc, 0xb8, 0x01, 0x02, 0xcd,
0x13, 0x59, 0x5a, 0x58, 0x72, 0x09, 0x40, 0x75, 0x01, 0x42, 0x03, 0x5e, 0x0b, 0xe2, 0xcc, 0xc3,
0x03, 0x18, 0x01, 0x27, 0x0d, 0x0a, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x73, 0x79,
0x73, 0x74, 0x65, 0x6d, 0x20, 0x64, 0x69, 0x73, 0x6b, 0xff, 0x0d, 0x0a, 0x44, 0x69, 0x73, 0x6b,
0x20, 0x49, 0x2f, 0x4f, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0xff, 0x0d, 0x0a, 0x52, 0x65, 0x70,
0x6c, 0x61, 0x63, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x64, 0x69, 0x73, 0x6b, 0x2c, 0x20, 0x61,
0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x70, 0x72, 0x65, 0x73, 0x73, 0x20, 0x61, 0x6e,
0x79, 0x20, 0x6b, 0x65, 0x79, 0x0d, 0x0a, 0x00, 0x49, 0x4f, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x53, 0x59, 0x53, 0x4d, 0x53, 0x44, 0x4f, 0x53, 0x20, 0x20, 0x20, 0x53, 0x59, 0x53, 0x80, 0x01,
0x00, 0x57, 0x49, 0x4e, 0x42, 0x4f, 0x4f, 0x54, 0x20, 0x53, 0x59, 0x53, 0x00, 0x00, 0x55, 0xaa
};
/****************************************************************************************
Descriptor Fullfill Blocks
*****************************************************************************************/
code Device_Descriptor device_descriptor =
{
0x12, //Descriptor Length
0x01, //Descriptor Type
0x0002, //bcdUSB USB2.0 Protocal
//0x1001,
0x00, //Device Class: Mass Storage
0x00, //Sub Device Class
0x00, //Device Protocal
0x40, //Max Packet size
0x1234, //ID Vendor
0x5678, //Product ID
0x0000, //BCD Device
0x00,
0x00,
0x00,
0x01 //Number of Configurations
} ;
//////////////////////////////////////////////////////////////////////////////////////////////
code Config_Descriptor config_descriptor =
{
0x09, //Descriptor Length
0x02, //Descriptor type
0x3C00, //config + interface + 6*endpoint
0x01, //Number of interface
0x01, //config value for Set_config and Get_config
0x00, //index of Config Descriptor
0x80, //Device is Self Powered, don't surpport Remote Wakeup
0xFA //Maximum Bus Current is 500mA
};
//////////////////////////////////////////////////////////////////////////////////////////////
code Interface_Descriptor interface_descriptor =
{
0x09, //Length
0x04, //Type
0x00, //interface Number
0x00, //default value
0x02, //Endpoint Number
0x08, //interface Class
0x06, //Interface Sub Class
0x50, //Use Mass Storage Bulk Only Transfer
0x00 //Index of the Descriptor
};
//////////////////////////////////////////////////////////////////////////////////////////////
code Endpoint_Descriptor endpointIN1_descriptor =
{
0x07, //Length
0x05, //Type
0x81, //Endpoint Address
0x02, //Endpoint Surpport Bulk Transfer
0x4000, //Max Packet Size
0x00 //not Related
};
///////////////////////////////////////////////////////////////////////////////////////////////
code Endpoint_Descriptor endpointOUT1_descriptor =
{
0x07, //Length
0x05, //Type
0x01, //Endpoint Address
0x02, //Endpoint Surpport Bulk Transfer
0x4000, //Max Packet Size
0x00 //not Related
};
//////////////////////////////////////////////////////////////////////////////////////////////
code Endpoint_Descriptor endpointIN2_descriptor =
{
0x07, //Length
0x05, //Type
0x82, //Endpoint Address
0x02, //Endpoint Surpport Bulk Transfer
0x4000, //Max Packet Size
0x00 //not Related
};
/////////////////////////////////////////////////////////////////////////////////////////////
code Endpoint_Descriptor endpointOUT2_descriptor =
{
0x07, //Length
0x05, //Type
0x02, //Endpoint Address
0x02, //Endpoint Surpport Bulk Transfer
0x4000, //Max Packet Size
0x00 //not Related
};
////////////////////////////////////////////////////////////////////////////////////////////
code Endpoint_Descriptor endpointIN3_descriptor =
{
0x07, //Length
0x05, //Type
0x83, //Endpoint Address
0x02, //Endpoint Surpport Bulk Transfer
0x4000, //Max Packet Size
0x00 //not Related
};
///////////////////////////////////////////////////////////////////////////////////////////
code Endpoint_Descriptor endpointOUT3_descriptor =
{
0x07, //Length
0x05, //Type
0x03, //Endpoint Address
0x02, //Endpoint Surpport Bulk Transfer
0x4000, //Max Packet Size
0x00 //not Related
};
/////////////////////////////////////////////////////////////////////////////////////////
code Config_Long config_long =
{
//Configure Descriptor
{
0x09, //Descriptor Length
0x02, //Descriptor type
0x2000, //config + interface + 6*endpoint
0x01, //Number of interface
0x01, //config value for Set_config and Get_config
0x00, //index of Config Descriptor
0x80, //Device is Self Powered, don't surpport Remote Wakeup
0xFA //Maximum Bus Current is 500mA
},
//Interface Descriptor
{
0x09, //Length
0x04, //Type
0x00, //interface Number
0x00, //default value
0x02, //Endpoint Number
0x08, //interface Class
0x06, //Interface Sub Class
0x50, //Use Mass Storage Bulk Only Transfer
0x00 //Index of the Descriptor
},
//Six Endpoint1-3 Descriptor
{
//Endpoint 1 IN description
{
0x07, //Length
0x05, //Type
0x81, //Endpoint Address
0x02, //Endpoint Surpport Bulk Transfer
0x4000, //Max Packet Size
0x00 //not Related
},
//Endpoint 1 OUT Description
{
0x07, //Length
0x05, //Type
0x01, //Endpoint Address
0x02, //Endpoint Surpport Bulk Transfer
0x4000, //Max Packet Size
0x00 //not Related
},
//Endpoint 2 IN Description
/* {
0x07, //Length
0x05, //Type
0x82, //Endpoint Address
0x02, //Endpoint Surpport Bulk Transfer
0x4000, //Max Packet Size
0x00 //not Related
},
//Endpoint 2 OUT Description
{
0x07, //Length
0x05, //Type
0x02, //Endpoint Address
0x02, //Endpoint Surpport Bulk Transfer
0x4000, //Max Packet Size
0x00 //not Related
},
//Endpoint 3 IN Description
{
0x07, //Length
0x05, //Type
0x81, //Endpoint Address
0x02, //Endpoint Surpport Bulk Transfer
0x4000, //Max Packet Size
0x00 //not Related
},
//Endpoint 3 OUT Description
{
0x07, //Length
0x05, //Type
0x01, //Endpoint Address
0x02, //Endpoint Surpport Bulk Transfer
0x4000, //Max Packet Size
0x00 //not Related
},*/
}
};
/*****************************************************************************************
Global Variables Define Area
******************************************************************************************/
xdata Flags flags; //Bulk in and Bulk out endPoint interrupt flags
CSW *pCS;
bit csw;
xdata uchar buf[512];
/****************************************************************************************
MAIN ROUTINE FOR USB TRANSFER
*****************************************************************************************/
void main(void)
{
//variables define area
Oscillator_Init();
System_Config();
CLR_Flags();
Read_ID();
//page_read(0,0, 0);
fill_DBR();
//block_buffer(0);
//check_invalid();
//test_flash();
USB_Config();
while(1)
{
if(flags.epin1 | flags.epout1)
Analysis_UFI();
}
}
/****************************************************************************************
name: USB_ISR
function: USB Interrupt Service Routine
pars: no
returns: no
******************************************************************************************/
void USB_ISR(void) interrupt 8
{
uchar CMINT_FLAG,IN_FLAG, OUT_FLAG; //Interrupt flags,IN,OUT and Common
xdata uchar RevBuf[8]; //Save the host Requst Command
Requst *pReq;
uchar cmd, number, i;
//read interrupt status
CMINT_FLAG = SFR_RD(CMINT); //save the Interrupt flags for
//Subroutine Entry
IN_FLAG = SFR_RD(IN1INT);
OUT_FLAG = SFR_RD(OUT1INT);
//interrupt subroutine process
if(CMINT_FLAG & BIT2) //Reset procedure
{
while(SFR_RD(POWER) & 0x08);
USB_Config();
}
else if(IN_FLAG & BIT0) //Endpoint 0 affairs procedure
{
SFR_WR(INDEX, 0x00);
cmd = SFR_RD(E0CSR);
if(cmd & BIT0)
{
number = SFR_RD(E0CNT);
for(i=0;i<number;i++) //Receive the host Requst
RevBuf[i] = SFR_RD(FIFO0);
cmd |= 0x48; //Clear the Receive Interrupt Flag
//and indicate Receive Data is END
SFR_WR(E0CSR, cmd);
pReq = (pRequst)RevBuf;
Analysis_Requst(pReq);
}
else if(cmd & BIT2) //Stall procedure
{
cmd &= ~BIT2;
SFR_WR(E0CSR, cmd);
//LED = 1;
}
}
if(IN_FLAG & BIT1)
flags.epin1 = 1;
if(OUT_FLAG & BIT1)
flags.epout1 = 1;
}
/*****************************************************************************************
Delay 1mS Subroutine
******************************************************************************************/
void Delay_mS(uchar t)
{
uint i;
uchar j;
for(j=0;j<t;j++)
for(i=0;i<20000;i++);
}
void Delay_uS(uint t)
{
do
{
_nop_();_nop_();
_nop_();_nop_();
_nop_();_nop_();
_nop_();_nop_();
}while(t--);
}
/*****************************************************************************************
name: Oscillator_Init
function: initial the system clock and 48MHz USB clock
pars: no
returns: no
******************************************************************************************/
void Oscillator_Init(void)
{
int i = 0;
CLKMUL = 0x80;
for (i = 0; i < 20; i++); // Wait 5us for initialization
CLKMUL |= 0xC0;
while ((CLKMUL & 0x20) == 0);
CLKSEL = 0x02;
OSCICN = 0x83;
}
/******************************************************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -