📄 d12.c
字号:
#include "d12.h"
#include "alt_types.h"
#include <io.h>
/**************************************/
#define D12_DELAY Delay(20)
//#define USB_DEBUG
/*******************************************/
alt_u8 mDevice_Descriptor[] = {
0x12, //设备描述符长度
0x01, //设备描述符类型
0x10, 0x01, //USB协议版本
0xDC, //测试设备类型
0x00, //设备子类
0x00, //设备协议
EP0_PK_LEN, //端点0最大数据包大小
0x71, 0x04, //厂商ID
0x8a, 0x88, //产品ID
0x00, 0x01, //设备系列号
0x00, //索引
0x00,
0x00,
0x01 }; //可能配置数
alt_u8 mAll_Descriptor[] = {
/********配置描述符*************/
0x09, //配置描述符长度
0x02, //配置描述符类型
0x2e, 0x00, //描述符总长度
0x01, //仅支持一个接口
0x01, //配置值
0x00, //无字符串描述符指针
0xa0, //总线供电,支持远程唤醒
0x00, //最大消耗200mA电流
/********接口描述符*************/
0x09, //接口描述符长度
0x04, //接口描述符类型
0x00, //只有一个接口
0x00, //可选配置只有一个
0x04, //端点数目(除端点0外)
0xdc, //测试设备类型
0xa0, //子类代码
0xb0, //协议代码
0x00, //字符串描述符索引
/*********端点描述符************/
/*********端点1:IN*************/
0x07, //端点描述符长度
0x05, //端点描述符类型
0x81, //端点1:IN
0x03, //中断传输
16, 0, //最大数据包大小
0x0a, //传输间隔时间
/*********端点1:OUT*************/
0x07, //端点描述符长度
0x05, //端点描述符类型
0x01, //端点1:OUT
0x03, //中断传输
16, 0, //最大数据包大小
0x0a, //传输间隔时间
/*********端点2:IN*************/
0x07, //端点描述符长度
0x05, //端点描述符类型
0x82, //端点1:IN
0x02, //批量传输
64, 0, //最大数据包大小
0x01, //传输间隔时间
/*********端点2:OUT*************/
0x07, //端点描述符长度
0x05, //端点描述符类型
0x02, //端点2:OUT
0x02, //批量传输
64, 0, //最大数据包大小
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); //设置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) //设置地址
{
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) //设置端点使能
{
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) //读中断标志
{
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) //读最后处理状态寄存器
{
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) //选择端点
{
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) //读缓冲区
{
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) //如果缓冲区为空,则返回
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) //写缓冲区
{
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包应答
{
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) //设置端点状态
{
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) //获取端点状态
{
D12_DELAY;
IOWR_8DIRECT(D12_BASE, USB_CMD, 0x40 | mEndPoint);
D12_DELAY;
return IORD_8DIRECT(D12_BASE, USB_DAT);
}
void USB_Stall(void) //设备停止
{
USB_SetEndPoint_Status(ENDPOINT0_OUT,1);
USB_SetEndPoint_Status(ENDPOINT0_IN,1);
}
/********************标准设备请求*********************************/
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); //设置端点状态
}
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: //获取设备描述符
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) //端点0 IN 中断服务子程序
{
alt_u8 m_Status;
m_Status=USB_Read_LastStatus(ENDPOINT0_IN);
if(UsbSendDescFlag)
UsbSendDesc();
}
void USB_EndPoint0_OUT(void) //端点0 OUT中断服务子程序
{
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) //读取数据到USB_Buff
{
USB_EndPoint_Setup_Ack(0); //应答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();
}
//端点1 IN中断服务子程序
void USB_EndPoint1_IN(void)
{
alt_u16 m_Status;
m_Status=USB_Read_LastStatus(ENDPOINT1_IN);
}
//端点1 OUT中断服务子程序
void USB_EndPoint1_OUT(void)
{
alt_u16 m_Status;
m_Status=USB_Read_LastStatus(ENDPOINT1_OUT);
}
//端点02 IN中断服务子程序
void USB_EndPoint2_IN(void)
{
alt_u16 m_Status;
m_Status=USB_Read_LastStatus(ENDPOINT2_IN);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -