?? combi.c
字號:
break;
}
return(byte_count1); //returns the number of bytes loaded
}
/*
**
** FUNCTION: SetConfiguration
**
** PURPOSE: Implements the Set Configuration Command
**
** PARAMETERS: none
**
** DESCRIPTION:
** This routine is entered Set Configuration request has been received from the host.
**
*/
void SetConfiguration(void)
{
if ( (ENDPOINT_A0_FIFO[USB_bmRequestType] == (HOST_TO_DEVICE | STANDARD | DEVICE)) &&
((ENDPOINT_A0_FIFO[USB_wValue] == UNCONFIGURED) || (ENDPOINT_A0_FIFO[USB_wValue] == CONFIGURED) ))
{
DeviceStatus.bConfiguration = ENDPOINT_A0_FIFO[USB_wValue]; //set the configuration
DeviceStatus.bEP1Stall = 0; //and clear EP1 stall
EP_A1_COUNTER &= ~DATATOGGLE; //clear EP1's data toggle
if(DeviceStatus.bConfiguration == UNCONFIGURED)
EP_A1_MODE = USB_MODE_DISABLE; //not configured -- disable EP1 from responding
else
EP_A1_MODE = USB_MODE_NAK_IN; //configured -- NAK traffic on EP1
SET_EP0_MODE(USB_MODE_STATUS_ONLY);
}
else
//something was awry with the command, stall
SET_EP0_MODE(USB_MODE_STALL_IN_OUT);
}
/*
**
** FUNCTION: SetAddress
**
** PURPOSE: Implements Set Address command
**
** PARAMETERS: none
**
** DESCRIPTION:
** This routine is entered whenever a SETUP request to set the address has been received.
** The address change cannot actually take place until the ensuing status-in is received
** from the host -- so we just save the address and set a flag to indicate that a new
** address was just received. The code that handles INs will recognize this and set the address
** properly.
**
**
*/
void SetAddress(void)
{
if (ENDPOINT_A0_FIFO[USB_bmRequestType] != HOST_TO_DEVICE | STANDARD | DEVICE)
{
SET_EP0_MODE(USB_MODE_STALL_IN_OUT);
}
else
{
DeviceStatus.bAddress = 0x80 | ENDPOINT_A0_FIFO[USB_wValue]; //save address away, we can't actually use it yet
SET_EP0_MODE(USB_MODE_STATUS_ONLY);
}
}
/*
**
** FUNCTION: ClearFeature
**
** PURPOSE: Handles Clear Feature requests
**
** PARAMETERS: none
**
** DESCRIPTION:
** This routine checks for either a clear-remote-wakeup request,
** or a clear-endpoint-stall request on endpoint 1 -- the only two valid clear
** feature requests for this device.
**
*/
void ClearFeature(void)
{
if ((ENDPOINT_A0_FIFO[USB_bmRequestType] ==(HOST_TO_DEVICE | STANDARD | DEVICE))
&& (ENDPOINT_A0_FIFO[USB_wValue] == USB_DEVICE_REMOTE_WAKEUP ) &&
( !ENDPOINT_A0_FIFO[USB_wValueHi]))
{
DeviceStatus.bRemoteWakeup = DISABLE_REMOTE_WAKEUP; /* disable remote wakeup */
SET_EP0_MODE(USB_MODE_STATUS_ONLY);
return;
}
if ((ENDPOINT_A0_FIFO[USB_bmRequestType] == (HOST_TO_DEVICE | STANDARD | ENDPOINT)) &&
(DeviceStatus.bConfiguration == CONFIGURED) &&
(!ENDPOINT_A0_FIFO[USB_wValueHi]) &&
(ENDPOINT_A0_FIFO[USB_wIndex] == 0x81)&&
(ENDPOINT_A0_FIFO[USB_wValue] == USB_ENDPOINT_STALL))
{ /*ep1 stall request*/
DeviceStatus.bEP1Stall = 0; /* not stalled */
EP_A1_COUNTER &= ~DATATOGGLE; /* clear data 0/1 bit */
EP_A1_MODE = USB_MODE_NAK_IN_OUT; //nak anything on endpoint 1 until ready
SET_EP0_MODE(USB_MODE_STATUS_ONLY);
return;
}
SET_EP0_MODE(USB_MODE_STALL_IN_OUT);
return;
}
/*
**
** FUNCTION: SetFeature
**
**
**
** PURPOSE: Handles Set Feature requests
**
** PARAMETERS: none
**
** DESCRIPTION:
** This routine checks for either a set-remote-wakeup request,
** or a set-endpoint-stall request on endpoint 1 -- the only two valid set
** feature requests for this device.
**
*/
void SetFeature(void)
{
if ( (ENDPOINT_A0_FIFO[USB_bmRequestType] == (HOST_TO_DEVICE | STANDARD | DEVICE)) &&
( ENDPOINT_A0_FIFO[USB_wValue] == USB_DEVICE_REMOTE_WAKEUP ) &&
( !ENDPOINT_A0_FIFO[USB_wValueHi]))
{
DeviceStatus.bRemoteWakeup = ENABLE_REMOTE_WAKEUP; /* set remote wakeup */
SET_EP0_MODE(USB_MODE_STATUS_ONLY);
return;
}
if ( (ENDPOINT_A0_FIFO[USB_bmRequestType] == (HOST_TO_DEVICE | STANDARD | ENDPOINT)) &&
(DeviceStatus.bConfiguration == CONFIGURED) &&
(!ENDPOINT_A0_FIFO[USB_wValueHi]) &&
(ENDPOINT_A0_FIFO[USB_wIndex] == 0x81) &&
(ENDPOINT_A0_FIFO[USB_wValue] == USB_ENDPOINT_STALL))
{
DeviceStatus.bEP1Stall = 1; //mark endpoint as stalled
EP_A1_MODE = USB_MODE_STALL_IN_OUT; //stall traffic on endpoint 1
SET_EP0_MODE(USB_MODE_STATUS_ONLY);
return;
}
//command not valid
SET_EP0_MODE(USB_MODE_STALL_IN_OUT);
return;
}
/*
**
** FUNCTION: GetDescriptor
**
** PURPOSE: Gets the requested descriptor
**
** PARAMETERS: none
**
** DESCRIPTION:
** This routine is entered when a Get Descriptor request is received.
** It decodes the descriptor request and initializes XmtBuff to the
** proper descriptor, then initiates the transfer by calling USB_control_read
**
**
*/
void GetDescriptor(void)
{
if ( (ENDPOINT_A0_FIFO[USB_bmRequestType] != (DEVICE_TO_HOST | STANDARD | DEVICE)) &&
(ENDPOINT_A0_FIFO[USB_bmRequestType] != (DEVICE_TO_HOST | STANDARD | INTERFACE)) &&
(ENDPOINT_A0_FIFO[USB_bmRequestType] != (DEVICE_TO_HOST | STANDARD | ENDPOINT)))
{
SET_EP0_MODE(USB_MODE_STALL_IN_OUT);
return;
}
switch (ENDPOINT_A0_FIFO[USB_wValueHi])
{
//decode descriptor request
case USB_DEVICE :
XmtBuff.bLength = device_desc_table[0];
XmtBuff.p = device_desc_table;
break;
case USB_CONFIGURATION :
XmtBuff.bLength = sizeof(config_desc_table) +
sizeof(Interface_Descriptor) +
sizeof(Class_Descriptor) +
sizeof(Endpoint_Descriptor);
XmtBuff.p=config_desc_table;
break;
case USB_STRING :
switch(ENDPOINT_A0_FIFO[USB_wValue])
{
case 0x00 :
XmtBuff.bLength = sizeof(USBStringLanguageDescription);
XmtBuff.p=USBStringLanguageDescription;
break;
case 0x01 :
XmtBuff.bLength = sizeof(USBStringDescription1);
XmtBuff.p=USBStringDescription1;
break;
case 0x02 :
XmtBuff.bLength = sizeof(USBStringDescription2);
XmtBuff.p=USBStringDescription2;
break;
case 0x03 :
XmtBuff.bLength = sizeof(USBStringDescription3);
XmtBuff.p=USBStringDescription3;
break;
case 0x04 :
XmtBuff.bLength = sizeof(USBStringDescription4);
XmtBuff.p=USBStringDescription4;
break;
case 0x05 :
XmtBuff.bLength = sizeof(USBStringDescription5);
XmtBuff.p=USBStringDescription5;
break;
default :
SET_EP0_MODE(USB_MODE_STALL_IN_OUT);
return;
}
break;
case USB_HID :
XmtBuff.bLength = sizeof(Class_Descriptor);
XmtBuff.p=Class_Descriptor;
break;
case USB_REPORT :
XmtBuff.bLength = sizeof(hid_report_desc_table);
XmtBuff.p=hid_report_desc_table;
break;
default :
//not a recognizable request, stall
SET_EP0_MODE(USB_MODE_STALL_IN_OUT);
return;
}
//initiate the transfer
USB_control_read();
}
/*
**
** FUNCTION: GetStatus
**
** PURPOSE: Implements a Get Status request
**
** PARAMETERS: none
**
** DESCRIPTION: This routine checks for either a request to get the device
** status, the interface status, or the endpoint status,
** sets up XmtBuff to point to the appropriate status, and
** calls USB_control_read to initiate the transfer.
**
**
**
*/
void GetStatus(void)
{
switch (ENDPOINT_A0_FIFO[USB_bmRequestType])
{
case (DEVICE_TO_HOST | STANDARD | DEVICE):
XmtBuff.bLength = 2; //send 2 bytes
XmtBuff.p = &DeviceStatus.bRemoteWakeup; //point at remote wakeup status
break;
case (DEVICE_TO_HOST | STANDARD | INTERFACE):
XmtBuff.bLength = sizeof(get_interface_status_table); //point at interface status
XmtBuff.p=get_interface_status_table;
break;
case (DEVICE_TO_HOST | STANDARD | ENDPOINT):
XmtBuff.bLength = 2; //send two bytes
XmtBuff.p = &DeviceStatus.bEP1Stall; //point at endpoint stall status
break;
default:
SET_EP0_MODE(USB_MODE_STALL_IN_OUT); //bogus request, complain
return;
}
USB_control_read(); //initiate transfer
}
/*
**
** FUNCTION: SetIdle
**
** PURPOSE: implements a request to set the idle period
**
** PARAMETERS: none
**
** DESCRIPTION:
** This routine is entered whenever a Set Idle request is received.
** See the HID spec for the rules on setting idle periods.
*/
void SetIdle(void)
{
if ( ((ENDPOINT_A0_FIFO[USB_bmRequestType] != (HOST_TO_DEVICE | CLASS | INTERFACE)) &&
(ENDPOINT_A0_FIFO[USB_bmRequestType] != (HOST_TO_DEVICE | CLASS | ENDPOINT))) ||
(ENDPOINT_A0_FIFO[USB_wIndex]) || (ENDPOINT_A0_FIFO[USB_wIndexHi]))
{
//request not valid, stall
SET_EP0_MODE(USB_MODE_STALL_IN_OUT);
return;
}
if (!MouseStatus.bIdlePeriod)
{
//current idle setting is off. set both the new period and the counter
MouseStatus.bIdlePeriod = ENDPOINT_A0_FIFO[USB_wValueHi];
MouseStatus.bIdleCounter = MouseStatus.bIdlePeriod;
SET_EP0_MODE(USB_MODE_STATUS_ONLY);
return;
}
if (MouseStatus.bIdleCounter <= 2)
{
// counter for current idle period is nearly expiring. leave it alone,
//but set new idle period
MouseStatus.bIdlePeriod = ENDPOINT_A0_FIFO[USB_wValueHi];
SET_EP0_MODE(USB_MODE_STATUS_ONLY);
return;
}
if ( ENDPOINT_A0_FIFO[USB_wValueHi] > MouseStatus.bIdleCounter)
{
//new period is shorter than the old one. Force current idle period to expire soon,
//and set new idle period
MouseStatus.bIdlePeriod = ENDPOINT_A0_FIFO[USB_wValueHi];
MouseStatus.bIdleCounter = 1;
}
else
{
//new period is longer than old one. set new idle period, and adjust current period
//to be equal to the new period, minus the counts that have already expired for the old one
MouseStatus.bIdlePeriod = ENDPOINT_A0_FIFO[USB_wValueHi];
MouseStatus.bIdleCounter = ENDPOINT_A0_FIFO[USB_wValueHi] - MouseStatus.bIdlePeriod;
}
SET_EP0_MODE(USB_MODE_STATUS_ONLY);
return;
}
/*
**
** FUNCTION: SetProtocol
**
** PURPOSE: Implements the set-protocol request
**
** PARAMETERS: none
**
** DESCRIPTION:
** This routine is entered whenever an Set Protocol request is received
**
*/
void SetProtocol(void)
{
if (((ENDPOINT_A0_FIFO[USB_bmRequestType] != (HOST_TO_DEVICE | CLASS | INTERFACE)) &&
(ENDPOINT_A0_FIFO[USB_bmRequestType] != (HOST_TO_DEVICE | CLASS | ENDPOINT))) ||
(ENDPOINT_A0_FIFO[USB_wIndex]) ||
(ENDPOINT_A0_FIFO[USB_wIndexHi]) ||
(ENDPOINT_A0_FIFO[USB_wValue] > REPORT_PROTOCOL))
//invalid request, stall
SET_EP0_MODE(USB_MODE_STALL_IN_OUT);
else
{
DeviceStatus.bProtocol = ENDPOINT_A0_FIFO[USB_wValue]; //set the new protocol
SET_EP0_MODE(USB_MODE_STATUS_ONLY); //acknowledge
}
}
/*
**
** FUNCTION: GetReport
**
** PURPOSE: Implements the GetReport request
**
** PARAMETERS: none
**
** DESCRIPTION:
** This routine is entered whenever a request to get a report is received.
** The most recent mouse data report is in the EP1 fifo.
**
*/
void GetReport(void)
{
if (ENDPOINT_A0_FIFO[USB_bmRequestType] != (DEVICE_TO_HOST | CLASS | INTERFACE))
{
SET_EP0_MODE(USB_MODE_STALL_IN_OUT);
return;
}
//depending upon the current protocol, either send a 3 or 4-byte mouse packet
//
XmtBuff.bLength = (DeviceStatus.bProtocol == REPORT_PROTOCOL ? 4 : 3);
XmtBuff.p = &Mouse.bButtons;
USB_control_read();
}
/*
**
** FUNCTION: GetIdle
**
** PURPOSE: Implements the Get Idle Request
**
** PARAMETERS: none
**
** DESCRIPTION:
** This routine is entered whenever a Get Idle request is received.
**
**
*/
void GetIdle(void)
{
if (ENDPOINT_A0_FIFO[USB_bmRequestType] != (DEVICE_TO_HOST | CLASS | INTERFACE))
{
SET_EP0_MODE(USB_MODE_STALL_IN_OUT);
return;
}
XmtBuff.bLength = 1; //idle is 1-byte long
XmtBuff.p=&MouseStatus.bIdlePeriod; //point at it
USB_control_read(); //initiate transfer
}
/*
**
** FUNCTION: GetProtocol
**
** PURPOSE: Implements the Get Protocol Request
**
** PARAMETERS: none
**
** DESCRIPTION:
** This routine is entered whenever a Get Protocol request is received
**
*/
void GetProtocol(void)
{
if (ENDPOINT_A0_FIFO[USB_bmRequestType] != (DEVICE_TO_HOST | CLASS | INTERFACE))
{
SET_EP0_MODE(USB_MODE_STALL_IN_OUT);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -