?? d12.c
字號(hào):
#include "d12.h"
#include "alt_types.h"
#include <io.h>
/**************************************/
#define D12_DELAY Delay(20)
//#define USB_DEBUG
/*******************************************/
alt_u8 mDevice_Descriptor[] = {
0x12, //設(shè)備描述符長度
0x01, //設(shè)備描述符類型
0x10, 0x01, //USB協(xié)議版本
0xDC, //測(cè)試設(shè)備類型
0x00, //設(shè)備子類
0x00, //設(shè)備協(xié)議
EP0_PK_LEN, //端點(diǎn)0最大數(shù)據(jù)包大小
0x71, 0x04, //廠商ID
0x8a, 0x88, //產(chǎn)品ID
0x00, 0x01, //設(shè)備系列號(hào)
0x00, //索引
0x00,
0x00,
0x01 }; //可能配置數(shù)
alt_u8 mAll_Descriptor[] = {
/********配置描述符*************/
0x09, //配置描述符長度
0x02, //配置描述符類型
0x2e, 0x00, //描述符總長度
0x01, //僅支持一個(gè)接口
0x01, //配置值
0x00, //無字符串描述符指針
0xa0, //總線供電,支持遠(yuǎn)程喚醒
0x00, //最大消耗200mA電流
/********接口描述符*************/
0x09, //接口描述符長度
0x04, //接口描述符類型
0x00, //只有一個(gè)接口
0x00, //可選配置只有一個(gè)
0x04, //端點(diǎn)數(shù)目(除端點(diǎn)0外)
0xdc, //測(cè)試設(shè)備類型
0xa0, //子類代碼
0xb0, //協(xié)議代碼
0x00, //字符串描述符索引
/*********端點(diǎn)描述符************/
/*********端點(diǎn)1:IN*************/
0x07, //端點(diǎn)描述符長度
0x05, //端點(diǎn)描述符類型
0x81, //端點(diǎn)1:IN
0x03, //中斷傳輸
16, 0, //最大數(shù)據(jù)包大小
0x0a, //傳輸間隔時(shí)間
/*********端點(diǎn)1:OUT*************/
0x07, //端點(diǎn)描述符長度
0x05, //端點(diǎn)描述符類型
0x01, //端點(diǎn)1:OUT
0x03, //中斷傳輸
16, 0, //最大數(shù)據(jù)包大小
0x0a, //傳輸間隔時(shí)間
/*********端點(diǎn)2:IN*************/
0x07, //端點(diǎn)描述符長度
0x05, //端點(diǎn)描述符類型
0x82, //端點(diǎn)1:IN
0x02, //批量傳輸
64, 0, //最大數(shù)據(jù)包大小
0x01, //傳輸間隔時(shí)間
/*********端點(diǎn)2:OUT*************/
0x07, //端點(diǎn)描述符長度
0x05, //端點(diǎn)描述符類型
0x02, //端點(diǎn)2:OUT
0x02, //批量傳輸
64, 0, //最大數(shù)據(jù)包大小
0x01
};
void Delay(alt_u32 delay)
{
while(delay--);
}
/***********D12初始化********************/
void USB_Port_Init(void)
{
if(D12RdChipId() != 0x1210)
{
printf("\nUSB Error: Not Found D12 Chip!");
return;
}
USB_SetDMA_Mode(0x00); //設(shè)置USB DMA
USB_Connect(0x02,0x4b); //斷開USB
Delay(100000);
USB_Connect(0x12,0x45); //重新連接USB
USB_Read_INT_Flag();
}
/**********D12操作程序*****************/
alt_u16 D12RdChipId(void) //讀取D12 ID
{
alt_u16 tmp;
D12_DELAY;
IOWR_8DIRECT(D12_BASE, USB_CMD, 0xfd);
D12_DELAY;
tmp = IORD_8DIRECT(D12_BASE, USB_DAT);
D12_DELAY;
tmp = (tmp<<8) | IORD_8DIRECT(D12_BASE, USB_DAT);
return tmp;
}
void USB_Connect(alt_u8 mMode,alt_u8 mClk)
{
D12_DELAY;
IOWR_8DIRECT(D12_BASE, USB_CMD, 0xf3);
D12_DELAY;
IOWR_8DIRECT(D12_BASE, USB_DAT, mMode);
D12_DELAY;
IOWR_8DIRECT(D12_BASE, USB_DAT, mClk);
}
void USB_SetAddr_Enable(alt_u8 mAddr,alt_u8 mEnable) //設(shè)置地址
{
D12_DELAY;
IOWR_8DIRECT(D12_BASE, USB_CMD, 0xd0);
D12_DELAY;
if(mEnable)
IOWR_8DIRECT(D12_BASE, USB_DAT, mAddr | 0x80);
else
IOWR_8DIRECT(D12_BASE, USB_DAT, mAddr);
}
void USB_SetEndPoint_Enable(alt_u8 mEnable) //設(shè)置端點(diǎn)使能
{
D12_DELAY;
IOWR_8DIRECT(D12_BASE, USB_CMD, 0xd8);
D12_DELAY;
IOWR_8DIRECT(D12_BASE, USB_DAT, mEnable & 0x01);
}
void USB_SetDMA_Mode(alt_u8 mMode)
{
D12_DELAY;
IOWR_8DIRECT(D12_BASE, USB_CMD, 0xfb);
D12_DELAY;
IOWR_8DIRECT(D12_BASE, USB_DAT, mMode);
}
alt_u16 USB_Read_INT_Flag(void) //讀中斷標(biāo)志
{
alt_u16 Temp1,Temp2;
D12_DELAY;
IOWR_8DIRECT(D12_BASE, USB_CMD, 0xf4);
D12_DELAY;
Temp2 = IORD_8DIRECT(D12_BASE, USB_DAT);
D12_DELAY;
Temp1 = IORD_8DIRECT(D12_BASE, USB_DAT);
D12_DELAY;
Temp1 <<= 8;
return Temp1 + Temp2;
}
alt_u8 USB_Read_LastStatus(alt_u8 mEndPoint) //讀最后處理狀態(tài)寄存器
{
D12_DELAY;
IOWR_8DIRECT(D12_BASE, USB_CMD, 0x40 | mEndPoint);
D12_DELAY;
return IORD_8DIRECT(D12_BASE, USB_DAT);;
}
alt_u8 USB_Select_EndPoint(alt_u8 mEndPoint) //選擇端點(diǎn)
{
D12_DELAY;
IOWR_8DIRECT(D12_BASE, USB_CMD, mEndPoint);
D12_DELAY;
return IORD_8DIRECT(D12_BASE, USB_DAT);;
}
alt_u8 USB_Read_EndPoint_Buff(alt_u8 mEndPoint,alt_u8 mLen,alt_u8 *mBuff) //讀緩沖區(qū)
{
alt_u8 len,i,Temp;
D12_DELAY;
IOWR_8DIRECT(D12_BASE, USB_CMD, mEndPoint);
D12_DELAY;
if((IORD_8DIRECT(D12_BASE, USB_DAT) & 0x01) == 0) //如果緩沖區(qū)為空,則返回
return 0;
else
{
D12_DELAY;
IOWR_8DIRECT(D12_BASE, USB_CMD, 0xf0);
D12_DELAY;
Temp = IORD_8DIRECT(D12_BASE, USB_DAT);
D12_DELAY;
len = IORD_8DIRECT(D12_BASE, USB_DAT);
D12_DELAY;
if(len > mLen)
len = mLen;
for(i=0;i<len;i++)
{
D12_DELAY;
mBuff[i] = IORD_8DIRECT(D12_BASE, USB_DAT);
}
D12_DELAY;
IOWR_8DIRECT(D12_BASE, USB_CMD, 0xf2);
return len;
}
}
void USB_Write_EndPoint_Buff(alt_u8 mEndPoint,alt_u8 mLen,alt_u8 *mBuff) //寫緩沖區(qū)
{
alt_u8 i;
D12_DELAY;
IOWR_8DIRECT(D12_BASE, USB_CMD, mEndPoint);
D12_DELAY;
IOWR_8DIRECT(D12_BASE, USB_CMD, 0xf0);
D12_DELAY;
IOWR_8DIRECT(D12_BASE, USB_DAT, 0);
D12_DELAY;
IOWR_8DIRECT(D12_BASE, USB_DAT, mLen);
D12_DELAY;
for(i=0; i<mLen; i++)
{
D12_DELAY;
IOWR_8DIRECT(D12_BASE, USB_DAT, mBuff[i]);
}
D12_DELAY;
IOWR_8DIRECT(D12_BASE, USB_CMD, 0xfa);
}
void USB_EndPoint_Setup_Ack(alt_u8 mEndPoint) //SetUp包應(yīng)答
{
D12_DELAY;
IOWR_8DIRECT(D12_BASE, USB_CMD, mEndPoint);
D12_DELAY;
IOWR_8DIRECT(D12_BASE, USB_CMD, 0xf1);
D12_DELAY;
if(!mEndPoint)
IOWR_8DIRECT(D12_BASE, USB_CMD, 0xf2);
}
void USB_SetEndPoint_Status(alt_u8 mEndPoint,alt_u8 mStall) //設(shè)置端點(diǎn)狀態(tài)
{
D12_DELAY;
IOWR_8DIRECT(D12_BASE, USB_CMD, 0x40 | mEndPoint);
D12_DELAY;
IOWR_8DIRECT(D12_BASE, USB_DAT, mStall);
}
alt_u8 USB_GetEndPoint_Status(alt_u8 mEndPoint) //獲取端點(diǎn)狀態(tài)
{
D12_DELAY;
IOWR_8DIRECT(D12_BASE, USB_CMD, 0x40 | mEndPoint);
D12_DELAY;
return IORD_8DIRECT(D12_BASE, USB_DAT);
}
void USB_Stall(void) //設(shè)備停止
{
USB_SetEndPoint_Status(ENDPOINT0_OUT,1);
USB_SetEndPoint_Status(ENDPOINT0_IN,1);
}
/********************標(biāo)準(zhǔn)設(shè)備請(qǐng)求*********************************/
DEVICE_REQUEST mDevice_Request;
alt_u8 RemoteWakeupState;
alt_u8 Config;
alt_u8 UsbSendDescFlag;
alt_u8 *pUSBSendDisc;
alt_u8 DiscSendRemainLen;
alt_u8 UsbGetStatus(alt_u8 *SetupPkt)
{
alt_u8 temp;
if(SetupPkt[2] | SetupPkt[3] | SetupPkt[5] | SetupPkt[7])
return STATUS_ERR;
if(SetupPkt[6] != 2)
return STATUS_ERR;
if(SetupPkt[0] == 0x80)
{
if(SetupPkt[4])
return STATUS_ERR;
SetupPkt[0] = RemoteWakeupState ? 1 : 0;
SetupPkt[1] = 0;
}
else
if(SetupPkt[0] == 0x81)
{
if(SetupPkt[4])
return STATUS_ERR;
SetupPkt[0] = 0;
SetupPkt[1] = 0;
}
else
if(SetupPkt[0] == 0x82)
{
temp = USB_Select_EndPoint((SetupPkt[4] << 1) | (SetupPkt[4] >> 7));
SetupPkt[1] = (temp & 2) ? 1 : 0;
SetupPkt[0] = 0;
}
else
return STATUS_ERR;
USB_Write_EndPoint_Buff(ENDPOINT0_IN, 2, SetupPkt);
return STATUS_OK;
}
alt_u8 UsbClrFeature(alt_u8 *SetupPkt)
{
if(SetupPkt[0] & 0x80)
return STATUS_ERR;
if(SetupPkt[3] | SetupPkt[5] | SetupPkt[6] | SetupPkt[7])
return STATUS_ERR;
if(SetupPkt[0] & 0x1f)
{
if((SetupPkt[0]&0x1f) != 2)
return STATUS_ERR;
USB_SetEndPoint_Status((SetupPkt[4] << 1) | (SetupPkt[4] >> 7), 0); //設(shè)置端點(diǎn)狀態(tài)
}
else
{
if(SetupPkt[4])
return STATUS_ERR;
RemoteWakeupState = 0;
}
USB_Write_EndPoint_Buff(ENDPOINT0_IN, 0, SetupPkt);
return STATUS_OK;
}
alt_u8 UsbSetFeature(alt_u8 *SetupPkt)
{
if(!(SetupPkt[0] & 0x80))
return STATUS_ERR;
if(SetupPkt[3] | SetupPkt[5] | SetupPkt[6] | SetupPkt[7])
return STATUS_ERR;
if(SetupPkt[0] & 0x1f)
{
if((SetupPkt[0] & 0x1f) != 2)
return STATUS_ERR;
USB_SetEndPoint_Status((SetupPkt[4] << 1) | (SetupPkt[4] >> 7), 1);
}
else
{
if(SetupPkt[4])
return STATUS_ERR;
RemoteWakeupState = 1;
}
USB_Write_EndPoint_Buff(ENDPOINT0_IN, 0, SetupPkt);
return STATUS_OK;
}
alt_u8 UsbSetAddress(alt_u8 *SetupPkt)
{
if(SetupPkt[0] | SetupPkt[3] | SetupPkt[4] | SetupPkt[5] | SetupPkt[6] | SetupPkt[7])
return STATUS_ERR;
USB_SetAddr_Enable(SetupPkt[2], 1);
USB_Write_EndPoint_Buff(ENDPOINT0_IN, 0, SetupPkt);
return STATUS_OK;
}
void UsbSendDesc()
{
alt_u8 len;
#ifdef USB_DEBUG
alt_u8 i;
#endif
UsbSendDescFlag = DiscSendRemainLen >= EP0_PK_LEN;
len = UsbSendDescFlag ? EP0_PK_LEN : DiscSendRemainLen;
USB_Write_EndPoint_Buff(ENDPOINT0_IN, len, pUSBSendDisc);
#ifdef USB_DEBUG
printf("@");
for(i=0; i<len; i++)
printf("%x,", pUSBSendDisc[i]);
printf("\n");
#endif
DiscSendRemainLen -= len;
pUSBSendDisc += len;
}
alt_u8 UsbGetDescriptor(alt_u8 *SetupPkt)
{
if(SetupPkt[0] != 0x80)
return STATUS_ERR;
switch(SetupPkt[3])
{
case 0x01: //獲取設(shè)備描述符
pUSBSendDisc = mDevice_Descriptor;
DiscSendRemainLen = mDevice_Descriptor[0];
break;
case 0x02: //獲取接口描述符
pUSBSendDisc = mAll_Descriptor;
DiscSendRemainLen = mAll_Descriptor[2];
break;
default:
return STATUS_ERR;
}
if(mDevice_Request.wLength < DiscSendRemainLen)
DiscSendRemainLen = mDevice_Request.wLength;
UsbSendDesc();
return STATUS_OK;
}
alt_u8 UsbGetConfiguration(alt_u8 *SetupPkt)
{
if(SetupPkt[0] != 0x80)
return STATUS_ERR;
if(SetupPkt[2] | SetupPkt[3] | SetupPkt[4] | SetupPkt[5] | SetupPkt[7])
return STATUS_ERR;
if(SetupPkt[6]!=1)
return STATUS_ERR;
SetupPkt[0] = Config ? 1 : 0;
USB_Write_EndPoint_Buff(ENDPOINT0_IN, 1, SetupPkt);
return STATUS_OK;
}
alt_u8 UsbSetConfiguration(alt_u8 *SetupPkt)
{
if(SetupPkt[0] | SetupPkt[3] | SetupPkt[4] | SetupPkt[5] | SetupPkt[6] | SetupPkt[7])
return STATUS_ERR;
if(SetupPkt[2]&0xfe)
return STATUS_ERR;
Config = SetupPkt[2] & 0x01;
USB_SetEndPoint_Enable(Config);
USB_SetEndPoint_Status(ENDPOINT1_OUT, Config^1);
USB_SetEndPoint_Status(ENDPOINT1_IN, Config^1);
USB_SetEndPoint_Status(ENDPOINT2_OUT, Config^1);
USB_SetEndPoint_Status(ENDPOINT2_IN, Config^1);
USB_Write_EndPoint_Buff(ENDPOINT0_IN, 0, SetupPkt);
return STATUS_OK;
}
alt_u8 UsbGetInterface(alt_u8 *SetupPkt)
{
if(SetupPkt[0]!=0x81)
return STATUS_ERR;
if(SetupPkt[2]|SetupPkt[3]|SetupPkt[4]|SetupPkt[5]|SetupPkt[7])
return STATUS_ERR;
if(SetupPkt[6]!=1)
return STATUS_ERR;
SetupPkt[0] = 0;
USB_Write_EndPoint_Buff(ENDPOINT0_IN, 1, SetupPkt);
return STATUS_OK;
}
alt_u8 UsbSetInterface(alt_u8 *SetupPkt)
{
return STATUS_ERR;
}
alt_u8 UsbReserved(alt_u8 *SetupPkt)
{
return STATUS_ERR;
}
alt_u8 (*StdUSBDevReq[])(alt_u8 *SetupPkt) = {
UsbGetStatus,
UsbClrFeature,
UsbReserved,
UsbSetFeature,
UsbReserved,
UsbSetAddress,
UsbGetDescriptor,
UsbReserved,
UsbGetConfiguration,
UsbSetConfiguration,
UsbGetInterface,
UsbSetInterface,
UsbReserved,
UsbReserved,
UsbReserved,
UsbReserved
};
/*****************************************************************/
void USB_EndPoint0_IN(void) //端點(diǎn)0 IN 中斷服務(wù)子程序
{
alt_u8 m_Status;
m_Status=USB_Read_LastStatus(ENDPOINT0_IN);
if(UsbSendDescFlag)
UsbSendDesc();
}
void USB_EndPoint0_OUT(void) //端點(diǎn)0 OUT中斷服務(wù)子程序
{
alt_u8 mStatus;
#ifdef USB_DEBUG
alt_u8 i;
alt_u8 *PakeData = (alt_u8 *)&mDevice_Request;
#endif
UsbSendDescFlag = FALSE;
mStatus = USB_Read_LastStatus(ENDPOINT0_OUT);
if(mStatus == USB_SETUPPACKET) //接收到正確的setup包
{
if(USB_Read_EndPoint_Buff(ENDPOINT0_OUT, 16, (alt_u8 *)&mDevice_Request) == 8) //讀取數(shù)據(jù)到USB_Buff
{
USB_EndPoint_Setup_Ack(0); //應(yīng)答Setup包
USB_EndPoint_Setup_Ack(1);
#ifdef USB_DEBUG
printf("$");
for(i=0; i<8; i++)
printf("0x%x,", PakeData[i]);
printf("\n");
#endif
if(!StdUSBDevReq[mDevice_Request.bRequest & 0xf]((alt_u8 *)&mDevice_Request));
return;
}
}
USB_Stall();
}
//端點(diǎn)1 IN中斷服務(wù)子程序
void USB_EndPoint1_IN(void)
{
alt_u16 m_Status;
m_Status=USB_Read_LastStatus(ENDPOINT1_IN);
}
//端點(diǎn)1 OUT中斷服務(wù)子程序
void USB_EndPoint1_OUT(void)
{
alt_u16 m_Status;
m_Status=USB_Read_LastStatus(ENDPOINT1_OUT);
}
//端點(diǎn)02 IN中斷服務(wù)子程序
void USB_EndPoint2_IN(void)
{
alt_u16 m_Status;
m_Status=USB_Read_LastStatus(ENDPOINT2_IN);
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -