📄 usbd12.c
字号:
if (len!=0)
USB_FLAG.ep2_rxdone = 1;
}
/*******************************************
函数名称: Control_handler
功 能: 控制传输
参 数: 无
返回值 : 无
/********************************************/
void Control_handler(void)
{
uchar type,req;
type=ControlData.DeviceRequest.bmRequestType&USB_REQUEST_TYPE_MASK;
//读取请求代码
req=ControlData.DeviceRequest.bRequest&USB_REQUEST_MASK;
if(type==USB_STANDARD_REQUEST)
(*StandardDeviceRequest[req])(); //标准请求处理
else
Stall_ep0(); //无效请求,返回STALL
}
/*******************************************
函数名称: Reserved
功 能: 保留子程序
参 数: 无
返回值 : 无
/********************************************/
void Reserved(void)
{
Stall_ep0(); //返回STALL
}
/*******************************************
函数名称: Init_unconfig
功 能: 进入地址状态,禁止0除外的所有端点
参 数: 无
返回值 : 无
/********************************************/
void Init_unconfig(void)
{
Set_EPen(0); //禁止0除外的所有端点
}
/*******************************************
函数名称: Init_config
功 能: 配置处理,允许端点收发
参 数: 无
返回值 : 无
/********************************************/
void Init_config(void)
{
Set_EPen(1); //使能普通/同步端点使能
}
/*******************************************
函数名称: Get_status
功 能: 主机要求获取状态,设备返回16位的状态描述给主机
参 数: 无
返回值 : 无
/********************************************/
void Get_status(void)
{
uchar endp,txdat[2],c;
uchar bRecipient=ControlData.DeviceRequest.bmRequestType&USB_RECIPIENT;
//取得设备请求类型
if (bRecipient==USB_RECIPIENT_DEVICE)
{ //对设备请求
if(USB_FLAG.remote_wakeup==1)
{
txdat[0]=3; //支持远程唤醒、自供电
}
else
{
txdat[0]=1; //不支持远程唤醒、自供电
}
txdat[1]=0; //高8位为0
S_trans(txdat,2); //发送16位的状态到主机
}
else if (bRecipient == USB_RECIPIENT_INTERFACE)
{ //对接口请求
txdat[0]=0;
txdat[1]=0;
S_trans(txdat, 2);
//发送16位的状态到主机
}
else if (bRecipient == USB_RECIPIENT_ENDPOINT)
{ //对端点请求
endp = (uchar)(ControlData.DeviceRequest.wIndex & MAX_ENDPOINTS);
if (ControlData.DeviceRequest.wIndex & (uchar)USB_ENDPOINT_DIRECTION_MASK)
{
c = Sel_EP(endp*2+1); //读取输入端点状态
}
else
{
c = Sel_EP(endp*2); //读取输出端点状态
}
if(c & STALL)//----------------
{
txdat[0] = 1; //端点禁止
}
else
{
txdat[0] = 0; //端点有效
}
txdat[1] = 0;
S_trans(txdat, 2); //发送16位的状态到主机
}
else
{
Stall_ep0(); //非标准请求,发STALL
}
}
/*******************************************
函数名称: Clr_feature
功 能: 清除特性
参 数: 无
返回值 : 无
/********************************************/
void Clr_feature(void)
{
uchar endp; //读取请求类型中的接收方
uchar bRecipient = ControlData.DeviceRequest.bmRequestType & USB_RECIPIENT;
//读取请求类型
if (bRecipient == USB_RECIPIENT_DEVICE //对设备请求
&&ControlData.DeviceRequest.wValue==USB_FEATURE_REMOTE_WAKEUP) //清除远程唤醒特性
{
UEN_GINT();
USB_FLAG.remote_wakeup = 0; //清0远程唤醒标志
EN_GINT();
S_trans(0,0); //返回一个空的数据表示执行完毕
}
else if (bRecipient == USB_RECIPIENT_ENDPOINT //对端点请求
&& ControlData.DeviceRequest.wValue == USB_FEATURE_ENDPOINT_STALL) //清除端点禁止特性,恢复其使用
{
endp = (uchar)(ControlData.DeviceRequest.wIndex & MAX_ENDPOINTS);
if (ControlData.DeviceRequest.wIndex & (uchar)USB_ENDPOINT_DIRECTION_MASK)
{
Set_EPsta(endp*2 + 1, 0); //清除控制输入端点STALL特性
}
else
{
Set_EPsta(endp*2, 0); //清除控制输出端点STALL特性
}
S_trans(0, 0); //返回一个空的数据表示执行完毕
}
else
{
Stall_ep0(); //没有该请求,返回STALL
}
}
/*******************************************
函数名称: Set_feature
功 能: 设置特性
参 数: 无
返回值 : 无
/********************************************/
void Set_feature(void)
{
uchar endp; //读取请求类型中的接收方
uchar bRecipient = ControlData.DeviceRequest.bmRequestType & USB_RECIPIENT;
//读取请求类型
if (bRecipient == USB_RECIPIENT_DEVICE //对设备请求
&& ControlData.DeviceRequest.wValue == USB_FEATURE_REMOTE_WAKEUP) //设置远程唤醒特性
{
UEN_GINT();
USB_FLAG.remote_wakeup = 1; //置1远程唤醒标志
EN_GINT();
S_trans(0, 0); //返回一个空的数据表示执行完毕
}
else if (bRecipient == USB_RECIPIENT_ENDPOINT //对端点请求
&& ControlData.DeviceRequest.wValue == USB_FEATURE_ENDPOINT_STALL) //禁止端点
{
endp = (uchar)(ControlData.DeviceRequest.wIndex & MAX_ENDPOINTS);
if (ControlData.DeviceRequest.wIndex & (uchar)USB_ENDPOINT_DIRECTION_MASK)
{
Set_EPsta(endp*2 + 1, 1); //设置输入端点禁止
}
else
{
Set_EPsta(endp*2, 1); //设置输出端点禁止
}
S_trans(0, 0); //返回一个空的数据表示执行完毕
}
else
{
Stall_ep0(); //没有该请求,返回STALL
}
}
/*******************************************
函数名称: Set_addr
功 能: 设置地址
参 数: 无
返回值 : 无
/********************************************/
void Set_addr(void)
{
Set_addren((uchar)(ControlData.DeviceRequest.wValue&DEVICE_ADDRESS_MASK), 1);
S_trans(0, 0); //发送一个空的数据响应
}
/*******************************************
函数名称: Get_descriptor
功 能: 获取描述符
参 数: 无
返回值 : 无
/********************************************/
void Get_descriptor(void)
{
uchar bDescriptor = MSB(ControlData.DeviceRequest.wValue); //读取请求的描述符类型
if (bDescriptor == USB_DEVICE_DESCRIPTOR_TYPE)//获取设备描述符
{
Code_trans((uchar *)&DeviceDescr, sizeof(USB_DEVICE_DESCRIPTOR));
}
else if (bDescriptor == USB_CONFIGURATION_DESCRIPTOR_TYPE) //获取其它描述符
{
if (ControlData.DeviceRequest.wLength > CONFIG_DESCRIPTOR_LENGTH)
{
ControlData.DeviceRequest.wLength = CONFIG_DESCRIPTOR_LENGTH;
}
Code_trans((uchar *)&(usb_descr.ConfigDescr), ControlData.DeviceRequest.wLength);
//发送描述符内容
}
else
{
Stall_ep0(); //没有该请求,返回STALL
}
}
/*******************************************
函数名称: Get_config
功 能: 获取配置
参 数: 无
返回值 : 无
/********************************************/
void Get_config(void)
{
uchar c = USB_FLAG.configuration; //取出配置值
S_trans(&c, 1); //发送配置值
}
/*******************************************
函数名称: Set_config
功 能: 设置配置
参 数: 无
返回值 : 无
/********************************************/
void Set_config(void)
{
if (ControlData.DeviceRequest.wValue == 0)
{ //配置值不对,设备进入未配置状态
S_trans(0, 0); //发向一个空包响应
UEN_GINT();
USB_FLAG.configuration = 0; //标记未配置
EN_GINT();
Init_unconfig(); //进入地址状态,禁止0除外的所有端点
}
else if (ControlData.DeviceRequest.wValue == 1)
{ //配置设备
S_trans(0, 0); //发向一个空包响应
Init_unconfig(); //进入地址状态,禁止0除外的所有端点
Init_config(); //配置处理,允许端点收发
UEN_GINT();
USB_FLAG.configuration = 1; //标志已配置
EN_GINT();
}
else
{
Stall_ep0(); //没有该请求,返回STALL
}
}
/*******************************************
函数名称: Get_interface
功 能: 获取接口信息
参 数: 无
返回值 : 无
/********************************************/
void Get_interface(void)
{
uchar txdat = 0; //本设备只有一个接口
S_trans(&txdat, 1); //发送一个字节
}
/*******************************************
函数名称: Set_interface
功 能: 设置接口信息
参 数: 无
返回值 : 无
/********************************************/
void Set_interface(void)
{
if (ControlData.DeviceRequest.wValue == 0 && ControlData.DeviceRequest.wIndex == 0)
{
S_trans(0, 0); //发送一个空的数据表示执行完毕
}
else
{
Stall_ep0(); //没有该请求,返回STALL
}
}
/*******************************************
函数名称: USB_connect
功 能: 连接USB总线
参 数: 无
返回值 : 无
/********************************************/
void USB_connect(void)
{
// Initialize D12 configuration
Set_DMA(0x00);
Set_mode(NOLAZYCLOCK|SOFTCONNECT, SETTOONE | CLOCK_12M);
} //SoftConnect 连接上,并设置为无LazyClock,模式为非同步模式
/*******************************************
函数名称: Set_interface
功 能: 设置接口信息
参 数: 无
返回值 : 无
/********************************************/
void USB_disconnect(void)
{
// Initialize D12 configuration
Set_mode(NOLAZYCLOCK, SETTOONE | CLOCK_12M);
} //SoftConnect 断开
/*******************************************
函数名称: USB_reconnect
功 能: 重新连接USB总线
参 数: 无
返回值 : 无
/********************************************/
void USB_reconnect(void)
{
uint clk_cnt;
USB_disconnect(); //断开芯片与USB总线连接
Delayms(200);
//for (clk_cnt = 0;clk_cnt<= 0x10000;clk_cnt++); //延时处理
Set_addren(0,1);
Set_EPen(1);
USB_connect(); //连接到USB总线
}
uint Read_chipID(void)
{
uint i,j;
if(USB_FLAG.in_isr == 0)
UEN_GINT();
OutB(CMD, 0xFD);
i=InB( );
j=InB( );
i += (j<<8);
if(USB_FLAG.in_isr == 0)
EN_GINT();
return i;
}
/*******************************************
函数名称: Uart_init
功 能: 异步串口初始化
参 数: baud--设置的波特率
返回值 : 无
/********************************************/
/*void Uart_init(uint baud)
{
baud=MCLK/16/baud-1; //波特率最大为65K
UCSRB=0x00;
UCSRA=0x00; //控制寄存器清零
UCSRC=(1<<URSEL)|(0<<UPM0)|(3<<UCSZ0); //选择UCSRC,异步模式,禁止校验,1位停止位,8位数据位
UBRRL=baud;
UBRRH=baud>>8; //设置波特率
UCSRB=(1<<TXEN)|(1<<RXEN)|(1<<RXCIE); //接收、发送使能,接收中断使能
SREG=(1<<7); //全局中断开放
DDRD|=0X02; //配置TX为输出(很重要)
}
/*******************************************
函数名称: Uart_sendB
功 能: 异步串口发送一个字节
参 数: sendB--发送的字节数据
返回值 : 无
/********************************************/
/*void Uart_sendB(uchar sendB)
{
while(!(UCSRA&(1<<UDRE))); //等待发送缓冲区为空
UDR=sendB; //发送数据
while(!(UCSRA&(1<<TXC))); //等待发送完毕
UCSRA|=1<<TXC; //清除发送完毕状态位
}*/
/*******************************************
函数名称: main
功 能: 主函数文件
参 数: 无
返回值 : 无
/********************************************/
void main(void)
{
uchar a,b;//,i;
uint c;
Board_init( ); //初始化开发板
//Uart_init(9600);
D12_init();
//Set_addren(0x80,0x01);
//Set_EPen(0x01);
//c=Read_chipID();
USB_reconnect();
while(1)
{
if (USB_FLAG.setup_packet)
{ //Setup包处理
UEN_GINT();
USB_FLAG.setup_packet = 0;
Control_handler(); //调用请求处理子程序
EN_GINT();
}
if(USB_FLAG.ep1_rxdone == 1) //标志接收到数据
{
UEN_GINT();
USB_FLAG.ep1_rxdone=0;
All_led(FALSE);
One_led(GenEpBuf[0],GenEpBuf[1]);
EN_GINT();
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -