?? chap_9.c
字號:
#include <stdio.h>
#include <string.h>
#include "config.h"
#include "d12ci.h"
#include "mainloop.h"
#include "usb100.h"
#include "chap_9.h"
#define NUM_ENDPOINTS 4
#define CONFIG_DESCRIPTOR_LENGTH sizeof(USB_CONFIGURATION_DESCRIPTOR) \
+ sizeof(USB_INTERFACE_DESCRIPTOR) \
+ (NUM_ENDPOINTS * sizeof(USB_ENDPOINT_DESCRIPTOR))
//extern CONTROL_XFER ControlData;
CONTROL_XFER ControlData;
//extern IO_REQUEST idata ioRequest;
extern EPPFLAGS bEPPflags;
extern code void (*VendorDeviceRequest[])(void);
//設備描述符
code USB_DEVICE_DESCRIPTOR DeviceDescr =
{
sizeof(USB_DEVICE_DESCRIPTOR),
USB_DEVICE_DESCRIPTOR_TYPE,
SWAP(0x0110),
USB_CLASS_CODE_TEST_CLASS_DEVICE,
0, 0,
EP0_PACKET_SIZE,
SWAP(0x0471),
SWAP(0x0666),
SWAP(0x0100),
0, 0, 0,
1
};
//配置描述符
code USB_CONFIGURATION_DESCRIPTOR ConfigDescr =
{
sizeof(USB_CONFIGURATION_DESCRIPTOR),
USB_CONFIGURATION_DESCRIPTOR_TYPE,
SWAP(CONFIG_DESCRIPTOR_LENGTH),
1,
1,
0,
0xa0,
0x1
};
//接口描述符
code USB_INTERFACE_DESCRIPTOR InterfaceDescr =
{
sizeof(USB_INTERFACE_DESCRIPTOR),
USB_INTERFACE_DESCRIPTOR_TYPE,
0,
0,
NUM_ENDPOINTS,
USB_CLASS_CODE_TEST_CLASS_DEVICE,
USB_SUBCLASS_CODE_TEST_CLASS_D12,
USB_PROTOCOL_CODE_TEST_CLASS_D12,
0
};
//端點描述符
code USB_ENDPOINT_DESCRIPTOR EP1_TXDescr =
{
sizeof(USB_ENDPOINT_DESCRIPTOR),
USB_ENDPOINT_DESCRIPTOR_TYPE,
0x81,
USB_ENDPOINT_TYPE_INTERRUPT,
SWAP(EP1_PACKET_SIZE),
1
};
code USB_ENDPOINT_DESCRIPTOR EP1_RXDescr =
{
sizeof(USB_ENDPOINT_DESCRIPTOR),
USB_ENDPOINT_DESCRIPTOR_TYPE,
0x1,
USB_ENDPOINT_TYPE_INTERRUPT,
SWAP(EP1_PACKET_SIZE),
1
};
code USB_ENDPOINT_DESCRIPTOR EP2_TXDescr =
{
sizeof(USB_ENDPOINT_DESCRIPTOR),
USB_ENDPOINT_DESCRIPTOR_TYPE,
0x82,
// USB_ENDPOINT_TYPE_BULK,
USB_ENDPOINT_TYPE_INTERRUPT,
SWAP(EP2_PACKET_SIZE),
10
};
code USB_ENDPOINT_DESCRIPTOR EP2_RXDescr =
{
sizeof(USB_ENDPOINT_DESCRIPTOR),
USB_ENDPOINT_DESCRIPTOR_TYPE,
0x2,
// USB_ENDPOINT_TYPE_BULK,
USB_ENDPOINT_TYPE_INTERRUPT,
SWAP(EP2_PACKET_SIZE),
10
};
//USB標準請求
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
};
/*
//*************************************************************************
// USB Protocol Layer
//*************************************************************************
*/
void reserved(void)
{
stall_ep0();
}
/*
//*************************************************************************
// USB standard device requests
//*************************************************************************
*/
//獲取設備狀態(tài)
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)//獲取遠程喚醒狀態(tài)
txdat[0] = 3;
else
txdat[0] = 1;
txdat[1]=0;
single_transmit(txdat, 2);
} else if (bRecipient == USB_RECIPIENT_INTERFACE) {//獲取接口狀態(tài)
txdat[0]=0;
txdat[1]=0;
single_transmit(txdat, 2);
} else if (bRecipient == USB_RECIPIENT_ENDPOINT) {//獲取端點狀態(tài)
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();
}
//特性清除
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) {//清除遠程喚醒功能
DISABLE;
bEPPflags.bits.remote_wakeup = 0;
ENABLE;
single_transmit(0, 0);
}
else if (bRecipient == USB_RECIPIENT_ENDPOINT
&& ControlData.DeviceRequest.wValue == USB_FEATURE_ENDPOINT_STALL) {//清除端點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);
else
/* clear RX stall for OUT on EPn. */
D12_SetEndpointStatus(endp*2, 0);
single_transmit(0, 0);
} else
stall_ep0();
}
//特性設置
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) {//設置遠程喚醒功能
DISABLE;
bEPPflags.bits.remote_wakeup = 1;
ENABLE;
single_transmit(0, 0);
}
else if (bRecipient == USB_RECIPIENT_ENDPOINT
&& ControlData.DeviceRequest.wValue == USB_FEATURE_ENDPOINT_STALL) {//設置端點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
/* clear RX stall for OUT on EPn. */
D12_SetEndpointStatus(endp*2, 1);
single_transmit(0, 0);
} else
stall_ep0();
}
//設置地址
void set_address(void)
{
D12_SetAddressEnable((unsigned char)(ControlData.DeviceRequest.wValue &
DEVICE_ADDRESS_MASK), 1);
single_transmit(0, 0);
}
//獲取描述符
void get_descriptor(void)
{
switch (MSB(ControlData.DeviceRequest.wValue))
{
case USB_DEVICE_DESCRIPTOR_TYPE:
code_transmit((unsigned char code *)&DeviceDescr, sizeof(USB_DEVICE_DESCRIPTOR));
break;
case USB_CONFIGURATION_DESCRIPTOR_TYPE:
code_transmit((unsigned char code *)&ConfigDescr, CONFIG_DESCRIPTOR_LENGTH);
break;
default:
stall_ep0();
break;
}
}
//獲取配置狀態(tài)
void get_configuration(void)
{
unsigned char c = bEPPflags.bits.configuration;
single_transmit(&c, 1);
}
//設置配置狀態(tài)
void set_configuration(void)
{
if (ControlData.DeviceRequest.wValue == 0) {
//設備進入未配置狀態(tài)
single_transmit(0, 0);
DISABLE;
bEPPflags.bits.configuration = 0;
ENABLE;
init_unconfig();
} else if (ControlData.DeviceRequest.wValue == 1) {
//配置設備
single_transmit(0, 0);
init_unconfig();
init_config();
DISABLE;
bEPPflags.bits.configuration = 1;
ENABLE;
} else
stall_ep0();
}
//獲取接口狀態(tài)
void get_interface(void)
{
unsigned char txdat = 0; /* Only/Current interface = 0 */
single_transmit(&txdat, 1);
}
//設置接口狀態(tài)
void set_interface(void)
{
if (ControlData.DeviceRequest.wValue == 0 && ControlData.DeviceRequest.wIndex == 0)
single_transmit(0, 0);
else
stall_ep0();
}
//*****************************************************************************************
//返回stall應答
void stall_ep0(void)
{
D12_SetEndpointStatus(0, 1);
D12_SetEndpointStatus(1, 1);
}
//斷開USB總線
void disconnect_USB(void)
{
// Initialize D12 configuration
D12_SetMode(D12_NOLAZYCLOCK, D12_SETTOONE | D12_CLOCK_12M);
}
//連接USB總線
void connect_USB(void)
{
// reset event flags
DISABLE;
bEPPflags.value = 0;//清除所有狀態(tài)
ENABLE;
// V2.1 enable normal+sof interrupt
D12_SetDMA(D12_ENDP4INTENABLE | D12_ENDP5INTENABLE);
// Initialize D12 configuration
D12_SetMode(D12_NOLAZYCLOCK|D12_SOFTCONNECT, D12_SETTOONE | D12_CLOCK_12M);
}
//重新連接到USB總線
void reconnect_USB(void)
{
// unsigned long clk_cnt;
// D12SUSPD = 0;
disconnect_USB();
connect_USB();
}
//恢復到未配置狀態(tài)
void init_unconfig(void)
{
// unsigned char i;
D12_SetEndpointEnable(0); /* Disable all endpoints but EPP0. */
}
//設置配置狀態(tài)
void init_config(void)
{
D12_SetEndpointEnable(1); /* Enable generic/iso endpoints. */
}
//從端點號1發(fā)送數(shù)據(jù)
void single_transmit(unsigned char * buf, unsigned char len)
{
if( len <= EP0_PACKET_SIZE) {
D12_WriteEndpoint(1, len, buf);
}
}
//發(fā)送端點號1建立代碼
void code_transmit(unsigned char code * 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);//發(fā)送16字節(jié)數(shù)據(jù)
ControlData.wCount += EP0_PACKET_SIZE;
DISABLE;
bEPPflags.bits.control_state = USB_TRANSMIT;
ENABLE;
}
else {
D12_WriteEndpoint(1, ControlData.wLength, pRomData);//發(fā)送16字節(jié)內(nèi)數(shù)據(jù)
ControlData.wCount += ControlData.wLength;
DISABLE;
bEPPflags.bits.control_state = USB_IDLE;
ENABLE;
}
}
//請求處理子程序
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)
(*StandardDeviceRequest[req])();//調(diào)用標準請求
else if (type == USB_VENDOR_REQUEST)
(*VendorDeviceRequest[req])();//調(diào)用廠商請求
else
stall_ep0();
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -