📄 usb.c
字号:
{bEPPflags.bits.setup_packet=1;
bEPPflags.bits.control_state=USB_TRANSMIT; // get command 设置状态
}
else
{if(ControlData.DeviceRequest.wLength==0)//检查是为不带数据的要求
{bEPPflags.bits.setup_packet=1;
bEPPflags.bits.control_state=USB_IDLE; // set command 设置状态
}
else{if(ControlData.DeviceRequest.wLength>MAX_CONTROLDATA_SIZE) //数据长度出错,接收数据长度为0
{bEPPflags.bits.control_state=USB_IDLE;
D12_SetEndpointStatus(0,1);
D12_SetEndpointStatus(1,1);
}
else {bEPPflags.bits.control_state=USB_RECEIVE; // set command with OUT token
}
} // set command with data
} // else set command
} // if setup packet
else if(bEPPflags.bits.control_state==USB_RECEIVE) //接收数据
{i=D12_ReadEndpoint(0,ControlData.dataBuffer+ControlData.wCount,EP0_PACKET_SIZE);
ControlData.wCount+=i;
if(i!=EP0_PACKET_SIZE || ControlData.wCount>=ControlData.wLength)//数据接收完毕
{bEPPflags.bits.setup_packet=1;
bEPPflags.bits.control_state=USB_IDLE;
}
}
else {bEPPflags.bits.control_state=USB_IDLE; //进入等待状态
}
}
//程序处理的是一种动态的过程
//端点0 IN 处理
void ep0_txdone(void)
{short i=ControlData.wLength-ControlData.wCount;
D12_ReadLastTransactionStatus(1); // Clear interrupt flag清中断标志位
if(bEPPflags.bits.control_state!=USB_TRANSMIT)//非发送状态,返回
return;
if(i>=EP0_PACKET_SIZE)//剩下数据大于16B,发送16B
{D12_WriteEndpoint(1,EP0_PACKET_SIZE,ControlData.pData+ControlData.wCount);
ControlData.wCount+=EP0_PACKET_SIZE;
bEPPflags.bits.control_state=USB_TRANSMIT;
}
else {if(i!=0)//发送剩下数据
{D12_WriteEndpoint(1,i,ControlData.pData + ControlData.wCount);
ControlData.wCount+=i;
bEPPflags.bits.control_state=USB_IDLE;
}
else if(i==0)//发送完毕,发送0B
{D12_WriteEndpoint(1,0,0); // Send zero packet at the end ???
bEPPflags.bits.control_state=USB_IDLE;
}
}
}
//端点1 IN处理
void ep1_txdone(void)
{D12_ReadLastTransactionStatus(3); // Clear interrupt flag 清中断标志位
}
//端点1 OUT处理
void ep1_rxdone(void)
{unsigned char len;
D12_ReadLastTransactionStatus(2); // Clear interrupt flag 清中断标志位
len=D12_ReadEndpoint(2,sizeof(GenEpBuf),GenEpBuf);//读取数据
if(len!=0)
bEPPflags.bits.ep1_rxdone=1;//标志接收到数据
}
//主端点IN 控制
void main_txdone(void)
{D12_ReadLastTransactionStatus(5); // Clear interrupt flag 清中断标志位
}
//主端点OUT控制
void main_rxdone(void)
{unsigned char len,epstatus;
D12_ReadLastTransactionStatus(4); // Clear interrupt flag
epstatus=D12_ReadEndpointStatus(4);//读取缓冲区状态
epstatus&=0x60;//判断缓冲区0和1是否为满,若都为满,进行2次读取
//接收数据
len=D12_ReadEndpoint(4,64,EpBuf);
if(epstatus==0x60)
len=D12_ReadEndpoint(4,64,EpBuf); //读取双缓冲区数据
}
//协议层 CHAP-9,C
void control_handler()
{unsigned char type,req;
type=ControlData.DeviceRequest.bmRequestType & USB_REQUEST_TYPE_MASK;
req=ControlData.DeviceRequest.bRequest & USB_REQUEST_MASK;
if(type==USB_STANDARD_REQUEST)//标准的设备请求处理
{switch (req)
{case 0:get_status();
case 1:clear_feature();
case 2:reserved();
case 3:set_feature();
case 4:reserved();
case 5:set_address();
case 6:get_descriptor();
case 7:reserved();
case 8:get_configuration();
case 9:set_configuration();
case 10:get_interface();
case 11:set_interface();
case 12:reserved();
case 13:reserved();
case 14:reserved();
case 15:reserved();
}
}
//(*StandardDeviceRequest[req])();
else stall_ep0();
}
//标准设备请求处理
/*code void (*StandardDeviceRequest[])(void) =
{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 reserved(void)
{stall_ep0();//返回ATALL
}
//进入地址状态禁止0除外的所有端点
void init_unconfig(void)
{D12_SetEndpointEnable(0); /* Disable all endpoints but EPP0. */
}
//配置处理,允许端点收发
void init_config(void)
{D12_SetEndpointEnable(1); /* Enable generic/iso endpoints. */
}
//通过端点索引1发送数据(DATA型)
void single_transmit(unsigned char * buf, unsigned char len)
{if(len<=EP0_PACKET_SIZE)
{D12_WriteEndpoint(1,len,buf);
}
}
//通过端点索引1发送数据(CODE类型)
void code_transmit(unsigned char *pRomData, unsigned short len)
{ControlData.wCount=0;
if(ControlData.wLength>len)
ControlData.wLength=len;
ControlData.pData=pRomData;
if(ControlData.wLength>=EP0_PACKET_SIZE)
{D12_WriteEndpoint(1,EP0_PACKET_SIZE,ControlData.pData);
ControlData.wCount+=EP0_PACKET_SIZE;
DisableInterrupts;
bEPPflags.bits.control_state=USB_TRANSMIT;//标志发送状态
EnableInterrupts;
}
else {D12_WriteEndpoint(1,ControlData.wLength,pRomData);
ControlData.wCount+=ControlData.wLength;
DisableInterrupts;
bEPPflags.bits.control_state=USB_IDLE;
EnableInterrupts;
}
}
//USB标准请求服务程序
//获取状态
void get_status(void)
{unsigned char endp,txdat[2];
unsigned char bRecipient=ControlData.DeviceRequest.bmRequestType & USB_RECIPIENT;
unsigned char c;
if (bRecipient==USB_RECIPIENT_DEVICE)
{if(bEPPflags.bits.remote_wakeup==1) //返回设备状态
txdat[0]=3; //支持远程唤醒,自供电
else txdat[0]=1;
txdat[1]=0;
single_transmit(txdat,2);//发送数据
}
else if(bRecipient==USB_RECIPIENT_INTERFACE)//返回接口状态
{txdat[0]=0;
txdat[1]=0;
single_transmit(txdat,2);//发送数据
}
else if (bRecipient==USB_RECIPIENT_ENDPOINT)//返回端点状态
{endp=(unsigned char)(ControlData.DeviceRequest.wIndex & MAX_ENDPOINTS);
if (ControlData.DeviceRequest.wIndex & (unsigned char)USB_ENDPOINT_DIRECTION_MASK)
c=D12_SelectEndpoint(endp*2+1); // Control-in读取输入端点状态
else c=D12_SelectEndpoint(endp*2); // Control-out读取输出端点状态
if(c & D12_STALL)
txdat[0]=1; //端点禁止
else txdat[0]=0;//端点有效
txdat[1]=0;
single_transmit(txdat,2);//发送数据
}
else stall_ep0();//非标准请求,发STALL
}
//清除特性
void clear_feature(void)
{unsigned char endp; //读取请求类型中的接收方
unsigned char bRecipient=ControlData.DeviceRequest.bmRequestType & USB_RECIPIENT;
if (bRecipient==USB_RECIPIENT_DEVICE && ControlData.DeviceRequest.wValue==USB_FEATURE_REMOTE_WAKEUP)
{DisableInterrupts;//清除远程唤醒特性
bEPPflags.bits.remote_wakeup=0;
EnableInterrupts;
single_transmit(0,0); //返回应答
}
else if(bRecipient==USB_RECIPIENT_ENDPOINT && ControlData.DeviceRequest.wValue==USB_FEATURE_ENDPOINT_STALL)
{endp = (unsigned char)(ControlData.DeviceRequest.wIndex & MAX_ENDPOINTS);
if (ControlData.DeviceRequest.wIndex & (unsigned char)USB_ENDPOINT_DIRECTION_MASK)
// clear TX stall for IN on EPn 清除端点禁止特性,恢复其使用.
D12_SetEndpointStatus(endp*2+1,0);//清除输入端点STALL特性
else D12_SetEndpointStatus(endp*2,0);// clear RX stall for OUT on EPn.清除输出端点STALL特性
single_transmit(0,0);//发送应答
}
else stall_ep0();//没有该请求,返回STALL
}
//设置特性
void set_feature(void)
{unsigned char endp;//读取请求类型中的接收方
unsigned char bRecipient=ControlData.DeviceRequest.bmRequestType & USB_RECIPIENT;
if (bRecipient==USB_RECIPIENT_DEVICE && ControlData.DeviceRequest.wValue==USB_FEATURE_REMOTE_WAKEUP)
{DisableInterrupts;
bEPPflags.bits.remote_wakeup=1;//设置远程唤醒特性
EnableInterrupts;
single_transmit(0,0);//发送应答
}
else if(bRecipient==USB_RECIPIENT_ENDPOINT && ControlData.DeviceRequest.wValue==USB_FEATURE_ENDPOINT_STALL)
{endp=(unsigned char)(ControlData.DeviceRequest.wIndex & MAX_ENDPOINTS);
if(ControlData.DeviceRequest.wIndex & (unsigned char)USB_ENDPOINT_DIRECTION_MASK)
//clear TX stall for IN on EPn.
D12_SetEndpointStatus(endp*2+1,1);//设置输入端点禁止
else D12_SetEndpointStatus(endp*2,1); // clear RX stall for OUT on EPn设置输出端点禁止.
single_transmit(0,0);//发送应答
}
else stall_ep0();//没有该请求,返回STALL
}
//设置地址
void set_address(void)
{D12_SetAddressEnable((unsigned char)(ControlData.DeviceRequest.wValue & DEVICE_ADDRESS_MASK),1);
single_transmit(0,0);//发送应答
}
//获取描述符,此函数改动比较大,针对所用设备将设备和配置描述符进行固化
void get_descriptor(void)
{unsigned char bDescriptor=MSB(ControlData.DeviceRequest.wValue);//读取请求的描述符类型
if(bDescriptor==USB_DEVICE_DESCRIPTOR_TYPE)
{code_transmit((unsigned char*)&DeviceDescr,0x12);
}
else if(bDescriptor == USB_CONFIGURATION_DESCRIPTOR_TYPE)
{code_transmit((unsigned char*) & ConfigDescr, 0x2e);
}
else stall_ep0()//没有该请求,返回STALL
}
//获取配置
void get_configuration(void)
{unsigned char c=bEPPflags.bits.configuration;
single_transmit(&0c,1);//返回配置值
}
void init_unconfig(void)
{unsigned char i;
D12_SetEndpointEnable(0); /* Disable all endpoints but EPP0. */
}
void init_config(void)
{D12_SetEndpointEnable(1); /* Enable generic/iso endpoints. */
}
//设置配置
void set_configuration(void)
{if(ControlData.DeviceRequest.wValue==0)
// put device in unconfigured state 配置值不对,设备进入未配置状态
{single_transmit(0,0);//发送应答
DisableInterrupts;
bEPPflags.bits.configuration=0; //标志未配置
EnableInterrupts;
init_unconfig();//进入地址状态,禁止0除外的所有端点
}
else if(ControlData.DeviceRequest.wValue==1)
// Configure device 配置设备
{single_transmit(0,0); //发送应答
init_unconfig();//进入地址状态,禁止0除外的所有端点
init_config();//配置处理,允许端点收发
DisableInterrupts;
bEPPflags.bits.configuration=1; //标志已配置
EnableInterrupts;
}
else stall_ep0();//没有该请求,返回STALL
}
//获取接口信息
void get_interface(void)
{unsigned char txdat=0; // Only/Current interface = 0
single_transmit(&txdat,1);//设备只有一个接口
}
//设置接口
void set_interface(void)
{if(ControlData.DeviceRequest.wValue==0 && ControlData.DeviceRequest.wIndex==0)
single_transmit(0,0);//发送应答
else stall_ep0();//没有该请求,返回STALL
}
//主循环
void disconnect_USB(void)
{// Initialize D12 configuration 初始化PDIUSBD12工作状态,断开SoftConnect上拉电阻
D12_SetMode(D12_NOLAZYCLOCK,D12_SETTOONE | D12_CLOCK_12M);
}
void connect_USB(void)
{DisableInterrupts;
bEPPflags.value=0;//清除事件标志
EnableInterrupts;
//初始化PDIUSBD12工作状态,接通SoftConnect上拉电阻
D12_SetMode(D12_NOLAZYCLOCK | D12_SOFTCONNECT,D12_SETTOONE | D12_CLOCK_12M);
}
void main(void)
{reconnect_USB();
while(1)
{if(bEPPflags.bits.bus_reset)
{DisableInterrupts;
bEPPflags.bits.bus_reset = 0;
EnableInterrupts;
PORTK=0x8f;
} // if bus reset
if(bEPPflags.bits.suspend)
{DisableInterrupts;
bEPPflags.bits.suspend=0;
EnableInterrupts;
PORTK=0x8f;
}
if(bEPPflags.bits.setup_packet)
{DisableInterrupts;
bEPPflags.bits.setup_packet = 0;
EnableInterrupts;
control_handler();
PORTK=0x8f;
} // if setup_packet
}
}
void register_initial(void)
{PORTA=0x0ff;
PORTB=0x0ff;
DDRA=0x0ff;
DDRB=0x0ff;
PORTE=0x0ff;
DDRE=0x0ff;
PEAR=0x90;
MODE=0x90;
MODE=0x90;
PUCR=0x0f3;
RDRIV=0x0f3;
PORTP=0x0ff;
DDRP=0x0ff;
PORTT=0x0ff;
DDRT=0x0ff;
PORTS=0x0ff;
DDRS=0x0ff;
PORTIB=0x0ff;
DDRIB=0x0ff;
PORTK=0x8f;
DDRK=0x8f;
INTCR=0x60;
}
void reconnect_USB(void)
{unsigned long delay_cnt;
PORTK=0x87;//SUSPEND=0,唤醒PDIUSBD12
disconnect_USB();//断开芯片与USB总线的连接
for(delay_cnt=0;delay_cnt<50000;delay_cnt++);//延时处理
connect_USB();//连接到USB总线
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -