?? d12_int.c
字號:
#include "D12_INT.h"
#include "USB_MassStorage.h"
#include "MMC_SD.h"
CBW cbw;
CSW csw;
unsigned char DISK_INF[36]= //Disk infomation //磁盤信息
{
0x00,
0x00,//最高位表示是否是可移動設備 //MSB of this byte indicate that this is removable disk
0x00,
0x01,
0x1F,
0x00,0x00,0x00,
'*',0xd5,0xc2,0xc6,0xe4,0xb2,0xa8,'*',//這一段可以自己添加內容,但長度不可變,編碼為ascii 也可是gbk
//You can add infomation here, a ASCII string needed, but the length must be 8
0xd6,0xc6,0xd7,0xf7,0xb5,0xc4,0xbf,0xc9,0xd2,0xc6,0xb6,0xaf,0xb4,0xc5,0xc5,0xcc,//這一段可以自己添加內容,但長度不可變,編碼為ascii 也可是gbk
//You can add infomation here, a ASCII string needed, but the length must be 16
0x31,0x2E,0x30,0x31
};
//Dis capacity. The first four bytes is the max LBA address
//It will be reinitialized when SD card is ready
unsigned char DISK_CAPACITY[8]= //磁盤容量//在SD初始化后會修改
{
0x00,0x0F,0x1C,0xF0,
0x00,0x00,0x02,0x00
};
//the requied data of MODE SENSE
unsigned char SENSE[0x12]= //模式探測返回數據
{
0x70, 0x00, 0x05, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00
};
//返回CSW包
void Send_CSW(U32 DataResidue,U8 status)
{
csw.dCSWSignature = 0x53425355; //csw包標志
csw.dCSWTag=cbw.dCBWTag; //主機發過來的tag
csw.dCSWDataResidue=DataResidue;
csw.bCSWStatus=status;
while(D12_Select_Endpoint(5));
D12_Write_Endpoint(5, (U8 *)&csw, 13);//定長度 13字節
}
//SCSI讀操作
void read_10()
{
U32 Byte_Count;//總字節數
U32 LBA; //LBA地址
U8 j=0;
//得到LBA地址
LBA = 0;
LBA += cbw.CBWCB[2];
LBA <<= 8;
LBA += cbw.CBWCB[3];
LBA <<= 8;
LBA += cbw.CBWCB[4];
LBA <<= 8;
LBA += cbw.CBWCB[5];
//得到傳輸字節數
Byte_Count = 0;
Byte_Count+=cbw.CBWCB[7];
Byte_Count<<=8;
Byte_Count+=cbw.CBWCB[8];
Byte_Count<<=9;
//傳輸數據 //一個while循環為讀一個扇區
while(1)
{
//以下為SD讀一扇區的前導操作
if(MMC_SD_SendCommand(17, LBA<<9)!=0x00){return;}
SPI_CS_Assert();
while(SPI_WriteByte(0xff) != 0xfe);//等數據的開始 //wait to start recieve data
LBA++;
for(j=0;j<8;j++)
{
D12_Write_Endpoint_SD(5);//寫端點,與SD卡同時操作//每次64字節
Byte_Count-=64;
if(Byte_Count==0)
{
//讀一扇區結尾的偽crc
SPI_WriteByte(0xff);//偽crc
SPI_WriteByte(0xff);
SPI_CS_Deassert();
return;//結束返回
}
}
//讀一扇區結尾的偽crc
SPI_WriteByte(0xff);//偽crc
SPI_WriteByte(0xff);
SPI_CS_Deassert();
}
}
//SCSI寫操作
void write_10()
{
U32 Byte_Count;//寫字節數
U32 LBA; //寫LBA地址
U8 j=0;
U8 buffer[512]; //實踐證明寫SD卡操作不可像讀操作那樣操作,否則會出錯 所以用緩沖區來做 等收到512字節再寫
//LBA地址
LBA = 0;
LBA += cbw.CBWCB[2];
LBA <<= 8;
LBA += cbw.CBWCB[3];
LBA <<= 8;
LBA += cbw.CBWCB[4];
LBA <<= 8;
LBA += cbw.CBWCB[5];
//總字節數
Byte_Count = 0;
Byte_Count+=cbw.CBWCB[7];
Byte_Count<<=8;
Byte_Count+=cbw.CBWCB[8];
Byte_Count<<=9;
//寫操作 1個while循環寫1扇區
while(1)
{
D12_Read_Endpoint(4, &buffer[j*64], 64);//正常端點讀操作
j++;
Byte_Count-=64;
if(j==8)//計滿512字節后一起寫到sd卡內
{
j=0;
MMC_SD_WriteSingleBlock(LBA++, buffer);
}
if(Byte_Count==0)return;//結束返回
}
}
//標準請求的函數指針
U8 (*Stand_Device_Request[])(U8 *SetupPacket) =
{
Get_Status,
Clear_Feature,
Reserved,
Set_Feature,
Reserved,
Set_Address,
Get_Descriptor,
Reserved,
Get_Configuration,
Set_Configuration,
Get_Interface,
Set_Interface,
Reserved,
Reserved,
Reserved,
Reserved
};
/**************************************/
void USB_Delay(U16 Time)
{
while(Time--)asm("nop");
}
/*****************初始化USB********************/
U8 USB_Init()
{
// D12_PORT_INI();
USB_Delay(20000);
if(D12_Read_Chip_ID()!=0x1210 )
return 0;
D12_Set_DMA(MyD12DmaCfg);
if(D12_Get_DMA()!=MyD12DmaCfg)
return 0;
D12_Set_Mode(MyD12EpCfgOff, D12Pll24M);
USB_Delay(20000);
USB_Delay(20000);
D12_Set_Mode(MyD12EpCfgOn, D12Pll24M);
return 1;
}
/********************** D12 interrupt process ******************/
void D12Ep0IntProc()
{
U8 SetupPacket[8];
U8 i = 0;
Clear_Remain_Descriptor_Flag();
//printf("\nEndpoint0 Process!");
if(D12_Read_Last_Transaction_Status(0)&0x20)
{
if(D12_Read_Endpoint(0, SetupPacket, 8)==8)
{
D12_Ack_Endpoint(0);
D12_Ack_Endpoint(1);
//for(i=0; i<8; i++)
//printf("%x,", SetupPacket[i]);
if(SetupPacket[0] == 0xa1 && SetupPacket[1] == 0xfe)
{
D12_Write_Endpoint(1,&i,1);
}
if(!Stand_Device_Request[SetupPacket[1]&0xf](SetupPacket));//調用相應的標準請求響應函數
return;
}
}
D12_Set_Endpoint_Status(0, D12EpStall);
D12_Set_Endpoint_Status(1, D12EpStall);
}
void D12Ep1IntProc()
{
U8 i;
//printf("\nEndpoint1 Process!\n");
i = D12_Read_Last_Transaction_Status(1);
if(Remain_Descriptor_Flag())
Send_Descriptor();
}
void D12Ep2IntProc()
{
// printf("\nEndpoint2 Process!\n");
D12_Set_Endpoint_Status(2, D12EpStall);
}
void D12Ep3IntProc()
{
// printf("\nEndpoint3 Process!\n");
D12_Set_Endpoint_Status(3, D12EpStall);
}
void D12Ep4IntProc()
{
//printf("\nEndpoint4 Process!\n");
D12_Read_Last_Transaction_Status(4);
D12_Read_Endpoint(4, (U8 *)&cbw, Endpoint2_Packet_Size);
if(cbw.dCBWSignature != 0x43425355)return; //cbw包標志
if(cbw.bmCBWFlags&0x80) //寫操作
{
switch(cbw.CBWCB[0])
{
case Read_10: read_10();Send_CSW(0x00,SUCCESS);break;
case Inquiry: D12_Write_Endpoint(5,DISK_INF,36);Send_CSW(0x00,SUCCESS); break;
case Read_Capacity: D12_Write_Endpoint(5,DISK_CAPACITY,0x08);Send_CSW(0x00,SUCCESS);break;
case Read_Format_capacity: D12_Write_Endpoint(5,0x00,0x00);Send_CSW(cbw.dCBWDataTransgerLength,FAIL);break;
case Request_Sense: D12_Write_Endpoint(5,SENSE,0x12);Send_CSW(0x00,SUCCESS);break;
case 0x1a: D12_Write_Endpoint(5,0x00,0x00);Send_CSW(cbw.dCBWDataTransgerLength,FAIL);break;
default : D12_Write_Endpoint(5,0x00,0x00);Send_CSW(cbw.dCBWDataTransgerLength,FAIL);break;
}
}
else //讀操作
{
switch(cbw.CBWCB[0])
{
case Write_10: write_10();Send_CSW(0x00,SUCCESS);break;
case Test_Unit_Ready: Send_CSW(0x00,SUCCESS);break;
case Verify: Send_CSW(0x00,SUCCESS);break;
default : Send_CSW(cbw.dCBWDataTransgerLength,FAIL);break;
}
}
}
void D12Ep5IntProc()
{
//printf("\nEndpoint5 Process!\n");
D12_Read_Last_Transaction_Status(5);//所有的數據傳輸都已在ep4內完成,該程序沒有采用中斷機制
}
void D12BusRstProc()
{
//printf("\nBus Reset!");
D12_Clear_Buffer();
D12_Enable_Buffer();
D12_Set_Endpoint_Enable(1);
}
void D12SuspChgProc()
{
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -