📄 usbfunctions.c
字号:
功 能: 控制传输
参 数: 无
返回值 : 无
********************************************/
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)
{
//SoftConnect 连接上,并设置为无LazyClock,模式为非同步模式
Set_DMA(0x00);
Set_mode(NOLAZYCLOCK|SOFTCONNECT, SETTOONE | CLOCK_12M);
}
/*******************************************
函数名称: Set_interface
功 能: 设置接口信息
参 数: 无
返回值 : 无
********************************************/
void USB_disconnect(void)
{
//SoftConnect 断开
Set_mode(NOLAZYCLOCK, SETTOONE | CLOCK_12M);
}
/*******************************************
函数名称: USB_reconnect
功 能: 重新连接USB总线
参 数: 无
返回值 : 无
********************************************/
void USB_reconnect(void)
{
USB_disconnect(); //断开芯片与USB总线连接
Delayms(200);
Set_addren(0,1);
Set_EPen(1);
USB_connect(); //连接到USB总线
}
/*******************************************
函数名称: Read_chipID
功 能: 读取芯片的ID
参 数: 无
返回值 : 无
********************************************/
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;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -