www.pudn.com > hf44b0_TEST.rar > usb.c
#include "..\inc\44b.h" #include "..\inc\44blib.h" #include "..\inc\def.h" #include "..\inc\option.h" #include "..\inc\usb.h" #include#include #include //static NU_HISR usb_comm_hisr; //static NU_TASK task_usbcomm; //NU_EVENT_GROUP eg_usbcomm; int usboperation=0; static U32 verbose = 0; static U8 usbbuffer0[256]; static U8 usbbuffer1[256]; static U8 usbbuffer2[256]; void USBISRPOLLING(int number); //**************************************************************************** // // This structure defines the setup packet received from the host via the // control out endpoint. This sturcture is padded at the end to the maximum // control endpoint transfer size. // //**************************************************************************** typedef struct { U8 bmRequestType; U8 bRequest; U16 wValue; U16 wIndex; U16 wLength; } ControlTransfer; //**************************************************************************** // // This is the configuration descriptor for the digital audio player. See the // USB specification for the definition of this descriptor. // //**************************************************************************** static const U8 ucDeviceDescriptor[] = { 0x12, // bLength 0x01, // bDescriptorType 0x00, 0x01, // bcdUSB 0x00, // bDeviceClass 0x00, // bDeviceSubClass 0x00, // bDeviceProtocol 0x10, // bMaxPacketSize0 0x71, 0x04, // idVendor 0x5e, 0x04, 0x22, 0x02, // idProduct 0x0a, 0x93, 0x00, 0x01, // bcdDevice 0x01, // iManufacturer 0x02, // iProduct 0x00, // iSerial Number 0x01 // bNumConfigurations }; static const U8 ucConfigurationDescriptor[] = { // // The configuration descriptor structure. // 0x09, // bLength 0x02, // bDescriptorType 0x20, // wTotalLength 0x00, // bCorrection 0x01, // bNumInterfaces 0x01, // bConfigurationValue 0x00, // iConfiguration 0x80, // bmAttributes 0x40 0x32, // MaxPower 0x00 // // The interface descriptor structure. // 0x09, // bLength 0x04, // bDescriptorType 0x00, // bInterfaceNumber 0x00, // bAlternateSetting 0x02, // bNumEndpoints 0x00, //00 // bInterfaceClass 0x00, // bInterfaceSubClass 0x00, //00 // bInterfaceProtocol 0x00, // iInterface // // The endpoint descriptor structure. // 0x07, // bLength 0x05, // bDescriptorType 0x82, // bEndpointAddress 0x02, // bmAttributes 0x40, 0x00, // wMaxPacketSize 0x00, // bInterval // // The endpoint descriptor structure. // 0x07, // bLength 0x05, // bDescriptorType 0x02, // bEndpointAddress 0x02, // bmAttributes 0x40, 0x00, // wMaxPacketSize 0x00 // bInterval }; //**************************************************************************** // // String descriptor 0 for the digital audio player. This defines the // languages supported by the string descriptors. See the USB specification // for the definition of this descriptor. // //**************************************************************************** static const U8 ucString0[] = { 0x04, // bLength 0x03, // bDescriptorType 0x09, 0x04 // wLANGID[0] -> US English }; //**************************************************************************** // // String descriptor 1 for the digital audio player. This defines the // manufacturer of the player. See the USB specification for the definition // of this descriptor. // //**************************************************************************** static const U8 ucString1[] = { 0x26, // bLength 0x03, // bDescriptorType 'S', 0x00, // wString[] 'W', 0x00, '4', 0x00, '4', 0x00, 'B', 0x00, '0', 0x00, ' ', 0x00, 'B', 0x00, 'O', 0x00, 'A', 0x00, 'R', 0x00, 'D', 0x00, ' ', 0x00, ' ', 0x00, ' ', 0x00, ' ', 0x00, ' ', 0x00, ' ', 0x00 }; //**************************************************************************** // // String descriptor 1 for the digital audio player. This defines the product // description of the player. See the USB specification for the definition of // this descriptor. // //**************************************************************************** static const U8 ucString2[] = { 0x52, // bLength 0x03, // bDescriptorType 'S', 0x00, // wString[] 'W', 0x00, '4', 0x00, '4', 0x00, 'B', 0x00, '0', 0x00, '-', 0x00, 'P', 0x00, 'D', 0x00, 'I', 0x00, 'U', 0x00, 'S', 0x00, 'B', 0x00, 'D', 0x00, '1', 0x00, '2', 0x00, ' ', 0x00, 'D', 0x00, 'E', 0x00, 'V', 0x00, 'I', 0x00, 'C', 0x00, 'E', 0x00, 'S', 0x00, ' ', 0x00 }; //**************************************************************************** // // An array of pointers to the USB standard device request handler Functions. // //**************************************************************************** void (* const USBStandardDeviceRequest[])(void) = { USBGetStatus, USBClearFeature, USBReserved, USBSetFeature, USBReserved, USBSetAddress, USBGetDescriptor, USBReserved, USBGetConfiguration, USBSetConfiguration, USBGetInterface, USBSetInterface, USBReserved }; //**************************************************************************** // // The following structure contains the persistent state of the USB interface. // //**************************************************************************** static struct { // The currently selected USB configuration. unsigned long ulConfiguration; // The buffer of data that is being sent to the control endpoint. const unsigned char *pucControlIn; // The number of bytes to be sent to the control endpoint. unsigned long ulControlInCount; // The buffer of data that is being received from the control endpoint. ControlTransfer sControlOut; // The buffer of data that is being sent to the bulk endpoint. const unsigned char *pucBulkIn; // The number of bytes to be sent to the bulk endpoint. unsigned long ulBulkInCount; // The buffer of data that is being received from the bulk endpoint. unsigned char *pucBulkOut; // The number of bytes still to be read from the bulk endpoint. unsigned long ulBulkOutCount; const unsigned char *pucACKIn; unsigned long ulACKInCount; unsigned char *pucCommandOut; unsigned long ulCommandOutCount; } sUSB; #define USB_STRUCT_INITED 0x55AAA55A U8 USBInitStruct(void) { if (sUSB.ulConfiguration == USB_STRUCT_INITED) return 0; memset(&sUSB, 0 , sizeof(sUSB)); sUSB.ulConfiguration = USB_STRUCT_INITED; sUSB.pucControlIn = usbbuffer0; sUSB.ulControlInCount = 0; sUSB.pucBulkIn = usbbuffer2; sUSB.ulBulkInCount = 0; sUSB.pucBulkOut = usbbuffer2; sUSB.ulBulkOutCount = 0; sUSB.pucACKIn = usbbuffer1; sUSB.ulACKInCount = 0; sUSB.pucCommandOut = usbbuffer1; sUSB.ulCommandOutCount = 0; return 0; } void USBEnable(void) { pISR_EINT0=(int)USBISR; rINTMSK =~(BIT_GLOBAL|BIT_EINT0); } void USBDisable(void) { rINTMSK =BIT_EINT0; } //**************************************************************************** // // USBWriteCommand will write the specified value to the command register of // the PDIUSBD12. // //**************************************************************************** void USBWriteCommand(U8 commandvalue) { U8 * volatile commandregister = (U8 *)(Usb_Base_Address + Usb_Command_Address); int delay; // Write the value to the command register. *commandregister = commandvalue; // Delay a bit to comply with the timing specification of the PDIUSBD12. for(delay = 0; delay < 24; delay++) { } } //**************************************************************************** // // USBWriteData will write the specified value to the data register of the // PDIUSBD12. // //**************************************************************************** void USBWriteData(U8 datavalue) { U8 * volatile dataregister = (U8 *)(Usb_Base_Address + Usb_Data_Address); int delay; // Write the value to the data register. *dataregister = datavalue; // Delay a bit to comply with the timing specification of the PDIUSBD12. for(delay = 0; delay < 24; delay++) { } } //**************************************************************************** // // USBInit configures the PDIUSBD12 device. // //**************************************************************************** void USBON(void) { int saveSyscfg; saveSyscfg=rSYSCFG; // rNCACHBE1=( (0x6000000>>12)<<16 )|(0x4000000>>12); // rSYSCFG=SYSCFG_8KBn; USBInitStruct(); USBWriteCommand(USB_COMMAND_SEND_RESUME); Delay(10000); USBWriteCommand(USB_COMMAND_SET_ADDRESS_ENABLE); USBWriteData(0); USBWriteCommand(USB_COMMAND_SET_ENDPOINT_ENABLE); USBWriteData(0); // // Enable the interrupts for the bulk endpoints. // USBWriteCommand(USB_COMMAND_SET_DMA); USBWriteData(USB_DMA_ENDP4_INT_ENABLE | USB_DMA_ENDP5_INT_ENABLE); // // Configure the PDIUSBD12 and enable the SoftConnect pull-up. // USBWriteCommand(USB_COMMAND_SET_MODE); USBWriteData(USB_CONFIG1_NO_LAZY_CLOCK | USB_CONFIG1_CLOCK_RUNNING | USB_CONFIG1_SOFT_CONNECT); USBWriteData(USB_CONFIG2_SET_TO_ONE | USB_CONFIG2_CLOCK_12M); Uart_Printf("USB ON\n"); Uart_Printf("Your PC will add the new USB\n"); Uart_Printf("Press any key ,close USB and exit\n"); USBEnable(); do{ USBISRPOLLING(0); } while(!Uart_GetKey()); USBOFF(); rSYSCFG=saveSyscfg; } void USBOFF(void) { USBWriteCommand(USB_COMMAND_SEND_RESUME); Delay(10000); USBWriteCommand(USB_COMMAND_SET_ADDRESS_ENABLE); USBWriteData(0); USBWriteCommand(USB_COMMAND_SET_ENDPOINT_ENABLE); USBWriteData(0); // // Enable the interrupts for the bulk endpoints. // USBWriteCommand(USB_COMMAND_SET_DMA); USBWriteData(USB_DMA_ENDP4_INT_ENABLE | USB_DMA_ENDP5_INT_ENABLE); USBWriteCommand(USB_COMMAND_SET_MODE); USBWriteData(0); USBWriteData(USB_CONFIG2_SET_TO_ONE | USB_CONFIG2_CLOCK_12M); } //**************************************************************************** // // USBISR is the interrupt handler routine for the USB. // //**************************************************************************** void __irq USBISR(void) { unsigned long ulIntStatus, ulTransactionStatus, ulLength,uSize; U8 *pucChar, ucChar; static int choosebool=0; // Read the PDIUSBD12 interrupt register. rI_ISPC=BIT_EINT0; //clear pending_bit USBWriteCommand(USB_COMMAND_READ_INTERRUPT); ulIntStatus = USBReadData(); ulIntStatus |= USBReadData() << 8; // Do nothing if there was a bus reset. if(ulIntStatus & USB_INT1_BUS_RESET) { return; } // Handle an interrupt on the bulk out endpoint. if(ulIntStatus & USB_INT1_ENDPOINT2_OUT) { //Uart_Printf("Occur USB_INT1_ENDPOINT2_OUT interrupt\n"); // Read the status of the last transaction on the bulk out endpoint. USBWriteCommand(USB_COMMAND_READ_LAST_XACTION_STATUS + USB_ENDPOINT_BULK_OUT); ulTransactionStatus = USBReadData(); //Uart_Printf("Status: %u\n",ulTransactionStatus); // Was a packet of data received successfully? if(ulTransactionStatus & USB_XACTION_STATUS_DATA_RX_TX_SUCCESS) { // If there is a buffer to read this data into, then read the data into that buffer. // Read the packet. uSize=USBReadEndpoint(USB_ENDPOINT_BULK_OUT, &sUSB.pucBulkOut, &sUSB.ulBulkOutCount); //Uart_Printf("Size: %u\n",uSize); Uart_Printf("usbbuffer0: %s\n",usbbuffer0); Uart_Printf("usbbuffer1: %s\n",usbbuffer1); Uart_Printf("usbbuffer2: %s\n",usbbuffer2); } } // Handle an interrupt on the control out endpoint. if(ulIntStatus & USB_INT1_CONTROL_OUT) { //Uart_Printf("Occur USB_INT1_CONTROL_OUT interrupt\n"); // Read the status of the last transaction on the control out endpoint. USBWriteCommand(USB_COMMAND_READ_LAST_XACTION_STATUS + USB_ENDPOINT_CONTROL_OUT); ulTransactionStatus = USBReadData(); // Was a setup packet received? if(ulTransactionStatus & USB_XACTION_STATUS_SETUP_PACKET) { // Read the packet. pucChar = (U8 *)&sUSB.sControlOut; ulLength = sizeof(ControlTransfer); if(USBReadEndpoint(USB_ENDPOINT_CONTROL_OUT, &pucChar, &ulLength) != sizeof(ControlTransfer)) { // The size of the setup packet is incorrect, so stall both of the control endpoints. USBStallEndpoint(USB_ENDPOINT_CONTROL_OUT, 1); USBStallEndpoint(USB_ENDPOINT_CONTROL_IN, 1); } else { // Acknowledge both the control in and control out endpoints, // and send a clear buffer command to the control out endpoint. USBWriteCommand(USB_COMMAND_SELECT_ENDPOINT + USB_ENDPOINT_CONTROL_OUT); USBWriteCommand(USB_COMMAND_ACKNOWLEDGE_ENDPOINT); USBWriteCommand(USB_COMMAND_CLEAR_BUFFER); USBWriteCommand(USB_COMMAND_SELECT_ENDPOINT + USB_ENDPOINT_CONTROL_IN); USBWriteCommand(USB_COMMAND_ACKNOWLEDGE_ENDPOINT); // Process the command in the setup packet. if(((sUSB.sControlOut.bmRequestType & USB_RT_TYPE_MASK) == USB_RT_TYPE_STANDARD) && (sUSB.sControlOut.bRequest < 16)) { // This is a standard request, so call the appropriate routine. (*USBStandardDeviceRequest[sUSB.sControlOut.bRequest])(); } else { // All other requests are treated as reserved requests. USBReserved(); } } } else { // The packet was not a setup packet, so ignore it. Send a clear // buffer command to the control out endpoint so it will receive new packets. // USBWriteCommand(USB_COMMAND_SELECT_ENDPOINT + USB_ENDPOINT_CONTROL_OUT); USBWriteCommand(USB_COMMAND_CLEAR_BUFFER); // Acknowledge both the control in and control out endpoints. USBWriteCommand(USB_COMMAND_ACKNOWLEDGE_ENDPOINT); USBWriteCommand(USB_COMMAND_SELECT_ENDPOINT + USB_ENDPOINT_CONTROL_IN); USBWriteCommand(USB_COMMAND_ACKNOWLEDGE_ENDPOINT); } } // Handle an interrupt on the control in endpoint. if(ulIntStatus & USB_INT1_CONTROL_IN) { //Uart_Printf("Occur USB_INT1_CONTROL_IN interrupt\n"); // Read the status of the last transaction on the control in endpoint. USBWriteCommand(USB_COMMAND_READ_LAST_XACTION_STATUS + USB_ENDPOINT_CONTROL_IN); USBReadData(); // Was this the last block of data to be sent back to the host? if(sUSB.ulControlInCount != 0) { // Send the next packet of data to the host. USBWriteEndpoint(USB_ENDPOINT_CONTROL_IN, &sUSB.pucControlIn,&sUSB.ulControlInCount); } else { // There is no more data to send, so send an empty packet. ulLength = 0; USBWriteEndpoint(USB_ENDPOINT_CONTROL_IN, 0, &ulLength); } } // Handle an interrupt on the bulk in endpoint. if(ulIntStatus & USB_INT1_ENDPOINT2_IN) { //Uart_Printf("Occur USB_INT1_ENDPOINT2_IN interrupt\n"); // Read the status of the last transaction on the bulk in endpoint. USBWriteCommand(USB_COMMAND_READ_LAST_XACTION_STATUS + USB_ENDPOINT_BULK_IN); USBReadData(); // Was this the last block of data to be sent back to the host? if(sUSB.ulBulkInCount != 0) {// Send the next packet of data to the host. USBWriteEndpoint(USB_ENDPOINT_BULK_IN, &sUSB.pucBulkIn, &sUSB.ulBulkInCount); } } } //**************************************************************************** // // USBReadData will read a value from the data register of the PDIUSBD12. // //**************************************************************************** unsigned char USBReadData(void) { unsigned char * volatile dataregister = (unsigned char*)(unsigned char *)(Usb_Base_Address + Usb_Data_Address); int delay; U8 datavalue; // Write the value to the data register. datavalue = * dataregister; for(delay = 0; delay < 24; delay++) { } return(datavalue); } //**************************************************************************** // // USBWriteEndpoint writes data to the specified endpoint. // //**************************************************************************** void USBWriteEndpoint(unsigned long ulEndpoint, const unsigned char **ppucData,unsigned long *pulLength) { U32 ulIdx, ulLength; // Determine the size of the packet to be sent based on the endpoint. if(ulEndpoint == USB_ENDPOINT_CONTROL_IN) { // The maximum packet size for the control endpoint is 16. ulLength = (*pulLength > 16) ? 16 : *pulLength; } else { // The maxmium packet size for the bulk endpoint is 64. ulLength = (*pulLength > 64) ? 64 : *pulLength; } // Select the appropriate endpoint. USBWriteCommand(USB_COMMAND_SELECT_ENDPOINT + ulEndpoint); // Send the write buffer command. USBWriteCommand(USB_COMMAND_WRITE_BUFFER); // Write the reserved byte to the buffer. USBWriteData(0); // Write the length of the data packet. USBWriteData(ulLength); // Write the data into the transmit buffer. for(ulIdx = 0; ulIdx < ulLength; ulIdx++) { USBWriteData(*(*ppucData)++); } // // Decrement the count of bytes to write. *pulLength -= ulLength; // Send the validate buffer command so that the endpoint will transmit the packet. USBWriteCommand(USB_COMMAND_VALIDATE_BUFFER); } //**************************************************************************** // // USBReadEndpoint reads data from the specified endpoint. // //**************************************************************************** unsigned long USBReadEndpoint(unsigned long ulEndpoint,unsigned char **ppucData,unsigned long *pulLength) { U32 ulIdx, ulLength; // Select the appropriate endpoint. USBWriteCommand(USB_COMMAND_SELECT_ENDPOINT + ulEndpoint); // Is there buffer space to fill with this data or should we throw the data away? if(*pulLength) { // Send the read buffer command. USBWriteCommand(USB_COMMAND_READ_BUFFER); // Throw away the reserved byte from the beginning of the buffer. USBReadData(); // Read the length of the data buffer. ulLength = USBReadData(); // Read the data into the receive buffer. for(ulIdx = 0; (ulIdx < ulLength) && (ulIdx < *pulLength); ulIdx++) { *(*ppucData)++ = USBReadData(); } // Decrement the count of bytes to read. *pulLength -= ulIdx; } // Send the clear buffer command so that the endpoint can receive another packet. USBWriteCommand(USB_COMMAND_CLEAR_BUFFER); // Return the size of the packet received. return(ulLength); } //**************************************************************************** // // USBSendACK transmits a block of data back to the host via the bulk // endpoint 1. // //**************************************************************************** unsigned long USBSendACK(const unsigned char *pucData, unsigned long ulLength) { // If a block is already being transmitted, then return a failure. if(sUSB.ulACKInCount) { return(0); } // Prepare to transmit this block back to the host. sUSB.pucACKIn = pucData; sUSB.ulACKInCount = ulLength; // Send the first packet of this block back to the host. USBWriteEndpoint(USB_ENDPOINT_ACK_IN, &sUSB.pucACKIn,&sUSB.ulACKInCount); return(1); } //**************************************************************************** // // USBReserved handles device requests which are not supported by this USB // device implementation. // //**************************************************************************** void USBReserved(void) { // Stall both control endpoints. USBStallEndpoint(USB_ENDPOINT_CONTROL_OUT, 1); USBStallEndpoint(USB_ENDPOINT_CONTROL_IN, 1); } //**************************************************************************** // // USBStallEndpoint stalls or un-stalls the specified endpoint. // //**************************************************************************** void USBStallEndpoint(unsigned long ulEndpoint, unsigned long bStall) { // // Send the appropriate set endpoint status command to the PDIUSBD12. // USBWriteCommand(USB_COMMAND_SET_ENDPOINT_STATUS + ulEndpoint); USBWriteData(bStall ? 1 : 0); } //**************************************************************************** // // USBGetStatus implements the USB Get_Status device request. // //**************************************************************************** void USBGetStatus(void) { U8 ucStatus[2]; U32 ulEndpoint; // Determine how to handle this request based on the recipient. switch(sUSB.sControlOut.bmRequestType & USB_RT_RECIPIENT_MASK) { // If the recipient is a device, return the state of the device's // remote wakeup and self powered states. case USB_RT_RECIPIENT_DEVICE: { // The player is self powered and does not support remote wakeup. ucStatus[0] = USB_DEVICE_STATUS_SELF_POWERED; ucStatus[1] = 0; // Send our response back to the host. USBSendControl(ucStatus, 2); // We're done handling this request. break; } // If the recipient is a device interface, return a value of // 0x00 as required by the USB spec. case USB_RT_RECIPIENT_INTERFACE: { // The USB spec. requires a GetStatus request for an interface return a pair of zero bytes. ucStatus[0] = 0; ucStatus[1] = 0; // Send our response back to the host. USBSendControl(ucStatus, 2); // We're done handling this request. break; } // // If the recipient is an endpoint, determine whether it is stalled or // not and return that information to the host. // case USB_RT_RECIPIENT_ENDPOINT: { // Find out which endpoint is the recipient of the request. ulEndpoint = sUSB.sControlOut.wIndex & USB_ENDPOINT_ADDRESS_MASK; // Determine whether the IN or the OUT endpoint is being addressed // in the device request. ulEndpoint *= 2; if(sUSB.sControlOut.wIndex & USB_ENDPOINT_DIRECTION_MASK) { ulEndpoint++; } // Read the endpoint status. USBWriteCommand(USB_COMMAND_SELECT_ENDPOINT); ulEndpoint = USBReadData(); // Send the endpoint's status to the host. if(ulEndpoint & USB_ENDPOINT_STALL) { ucStatus[0] = USB_ENDPOINT_STATUS_STALLED; } else { ucStatus[0] = 0; } ucStatus[1] = 0; // Send our response back to the host. USBSendControl(ucStatus, 2); // We're done handling this request. break; } // If an invalid request is received, stall the control endpoint. default: { // Stall the both control endpoints. USBStallEndpoint(USB_ENDPOINT_CONTROL_OUT, 1); USBStallEndpoint(USB_ENDPOINT_CONTROL_IN, 1); // We're done handling this request. break; } } } //**************************************************************************** // // USBSendControl transmits a block of data back to the host via the control // endpoint. // //**************************************************************************** unsigned long USBSendControl(const unsigned char *pucData, unsigned long ulLength) { // If a block is already being transmitted, then return a failure. if(sUSB.ulControlInCount) { return(0); } // Prepare to transmit this block back to the host. sUSB.pucControlIn = pucData; sUSB.ulControlInCount = ulLength; // Send the first packet of this block back to the host. USBWriteEndpoint(USB_ENDPOINT_CONTROL_IN, &sUSB.pucControlIn,&sUSB.ulControlInCount); return(1); } //**************************************************************************** // // USBClearFeature implements the USB Clear_Feature device request. // //**************************************************************************** void USBClearFeature(void) { U32 ulEndpoint; // The only feature we support is stall on an endpoint. if(((sUSB.sControlOut.bmRequestType & USB_RT_RECIPIENT_MASK) == USB_RT_RECIPIENT_ENDPOINT) && (sUSB.sControlOut.wValue == USB_FEATURE_ENDPOINT_STALL)) { // Compute the endpoint number. ulEndpoint = (sUSB.sControlOut.wIndex & USB_ENDPOINT_ADDRESS_MASK) * 2; if(sUSB.sControlOut.wIndex & USB_ENDPOINT_DIRECTION_MASK) { ulEndpoint++; } // Clear the stall condition on the specified endpoint. USBStallEndpoint(ulEndpoint, 0); } else { // An unknown feature was specified, so stall both control endpoints. USBStallEndpoint(USB_ENDPOINT_CONTROL_OUT, 1); USBStallEndpoint(USB_ENDPOINT_CONTROL_IN, 1); } } //**************************************************************************** // // USBSetFeature implements the USB Set_Feature device request. // //**************************************************************************** void USBSetFeature(void) { U32 ulEndpoint; // The only feature we support is stall on an endpoint. if(((sUSB.sControlOut.bmRequestType & USB_RT_RECIPIENT_MASK) == USB_RT_RECIPIENT_ENDPOINT) && (sUSB.sControlOut.wValue == USB_FEATURE_ENDPOINT_STALL)) { // Compute the endpoint number. ulEndpoint = (sUSB.sControlOut.wIndex & USB_ENDPOINT_ADDRESS_MASK) * 2; if(sUSB.sControlOut.wIndex & USB_ENDPOINT_DIRECTION_MASK) { ulEndpoint++; } // Set the stall condition on the specified endpoint. USBStallEndpoint(ulEndpoint, 1); } else { // An unknown feature was specified, so stall both control endpoints. USBStallEndpoint(USB_ENDPOINT_CONTROL_OUT, 1); USBStallEndpoint(USB_ENDPOINT_CONTROL_IN, 1); } } //**************************************************************************** // // USBSetAddress implements the USB Set_Address device request. // //**************************************************************************** void USBSetAddress(void) { // Configure our UBS controller for the USB address assigned by the host. USBWriteCommand(USB_COMMAND_SET_ADDRESS_ENABLE); USBWriteData(sUSB.sControlOut.wValue | 0x80); // Respond to the host with an empty packet. USBSendControl(0, 0); } //**************************************************************************** // // USBGetDescriptor implements the USB Get_Descriptor device request. // //**************************************************************************** void USBGetDescriptor(void) { const U8 *pucDescriptor; U32 ulLength; // Determine how to handle this request based on the requested descriptor. switch(sUSB.sControlOut.wValue & USB_DESCRIPTOR_TYPE_MASK) { // The device descriptor was requested. case USB_DESCRIPTOR_DEVICE: { // Prepare to return the device descriptor. pucDescriptor = ucDeviceDescriptor; ulLength = sizeof(ucDeviceDescriptor); // We're done handling this request. break; } // The configuration descriptor was requested. case USB_DESCRIPTOR_CONFIGURATION: { // Prepare to return the configuration descriptor. pucDescriptor = ucConfigurationDescriptor; ulLength = sizeof(ucConfigurationDescriptor); // We're done handling this request. break; } // A string descriptor was requested. case USB_DESCRIPTOR_STRING: { // Make sure that the language and string index requested are valid. if(((sUSB.sControlOut.wValue & USB_DESCRIPTOR_INDEX_MASK) != 0) && ((sUSB.sControlOut.wIndex != 0x0409) || ((sUSB.sControlOut.wValue & USB_DESCRIPTOR_INDEX_MASK) > 2))) { // Stall both of the control endpoints. USBStallEndpoint(USB_ENDPOINT_CONTROL_OUT, 1); USBStallEndpoint(USB_ENDPOINT_CONTROL_IN, 1); // We're done handling this request. return; } // Prepare to return the requested string. switch(sUSB.sControlOut.wValue & USB_DESCRIPTOR_INDEX_MASK) { // String index 0 is the language ID string. case 0x00: { pucDescriptor = ucString0; ulLength = sizeof(ucString0); break; } // String index 1 is the manufacturer name. case 0x01: { pucDescriptor = ucString1; ulLength = sizeof(ucString1); break; } // String index 2 is the product name. case 0x02: { pucDescriptor = ucString2; ulLength = sizeof(ucString2); break; } } // We're done handling this request. break; } // An invalid request is received, so stall both control endpoints. default: { // Stall both of the control endpoints. USBStallEndpoint(USB_ENDPOINT_CONTROL_OUT, 1); USBStallEndpoint(USB_ENDPOINT_CONTROL_IN, 1); // We're done handling this request. return; } } // If the requested length is less than the length of the descriptor to be // returned, then simply return the requested portion of the descriptor. if(sUSB.sControlOut.wLength < ulLength) { ulLength = sUSB.sControlOut.wLength; } // Send the descriptor back to the host. USBSendControl(pucDescriptor, ulLength); } //**************************************************************************** // // USBGetConfiguration implements the USB Get_Configuration device request. // //**************************************************************************** void USBGetConfiguration(void) { // Send the current configuration value back to the host. USBSendControl((U8 *)&sUSB.ulConfiguration, 1); } //**************************************************************************** // // USBSetConfiguration implements the USB Set_Configuration device request. // //**************************************************************************** void USBSetConfiguration(void) { // If the requested configuration is zero, then go into the unconfigured state. if(sUSB.sControlOut.wValue == 0) { // Clear the global configuration flag. sUSB.ulConfiguration = 0; // Disable the generic endpoints. USBWriteCommand(USB_COMMAND_SET_ENDPOINT_ENABLE); USBWriteData(0); // Respond to the host with an empty packet. USBSendControl(0, 0); } // If the requested configuration is one, then go into the configured state. else if(sUSB.sControlOut.wValue == 1) { // Set the global configuration flag. sUSB.ulConfiguration = 1; // Disable the generic endpoints. USBWriteCommand(USB_COMMAND_SET_ENDPOINT_ENABLE); USBWriteData(0); // Enable the generic endpoints. USBWriteCommand(USB_COMMAND_SET_ENDPOINT_ENABLE); USBWriteData(1); // Respond to the host with an empty packet. USBSendControl(0, 0); } // If the requested configuration is anything else, then stall both of the control endpoints. else { USBStallEndpoint(USB_ENDPOINT_CONTROL_OUT, 1); USBStallEndpoint(USB_ENDPOINT_CONTROL_IN, 1); } } //**************************************************************************** // // USBGetInterface implements the USB Get_Interface device request. // //**************************************************************************** void USBGetInterface(void) { U8 ucInterface = 0; // We only support a single interface, so the current interface is always // the first one. Send our response back to the host. USBSendControl(&ucInterface, 1); } //**************************************************************************** // // USBSetInterface implements the USB Set_Interface device request. // //**************************************************************************** void USBSetInterface(void) { // We only support a single interface. if((sUSB.sControlOut.wValue == 0) && (sUSB.sControlOut.wIndex == 0)) { // The first interface was requested, so do nothing. return; } else { // A non-existent interface was requested, so stall both control endpoints. USBStallEndpoint(USB_ENDPOINT_CONTROL_OUT, 1); USBStallEndpoint(USB_ENDPOINT_CONTROL_IN, 1); } } //**************************************************************************** // // USBReceiveBulk reads a block of data from the host via the bulk endpoint. // //**************************************************************************** unsigned long USBReceiveBulk(unsigned char *pucData, unsigned long ulLength) { // If a block is already being read, then return a failure. if(sUSB.ulBulkOutCount) { return(0); } // Prepare to read data from the host into this buffer. sUSB.pucBulkOut = pucData; sUSB.ulBulkOutCount = ulLength; return(1); } //**************************************************************************** // // USBReceiveBulkDone determines if the data receive from the bulk endpoint // has completed. // //**************************************************************************** unsigned long USBReceiveBulkDone(void) { // Is there more data to receive from the bulk endpoint? if(sUSB.ulBulkOutCount) { // There's more data to receive, so indicate that we're not done. return(0); } else { // We've received all the data, so indicate that we're done. return(1); } } //**************************************************************************** // // USBReceiveCommand reads a block of data from the host via the bulk endpoint 1. // //**************************************************************************** unsigned long USBReceiveCommand(unsigned char *pucData, unsigned long ulLength) { // If a block is already being read, then return a failure. if(sUSB.ulCommandOutCount) { return(0); } // Prepare to read data from the host into this buffer. sUSB.pucCommandOut = pucData; sUSB.ulCommandOutCount = ulLength; return(1); } //**************************************************************************** // // USBReceiveCommandDone determines if the data receive from the bulk endpoint // has completed. // //**************************************************************************** unsigned long USBReceiveCommandDone(void) { // Is there more data to receive from the bulk endpoint? if(sUSB.ulCommandOutCount) { // There's more data to receive, so indicate that we're not done. return(0); } else { // We've received all the data, so indicate that we're done. return(1); } } //**************************************************************************** // // USBSendACKDone determines if the data transmit to the bulk endpoint 2 has // completed. // //**************************************************************************** unsigned long USBSendACKDone(void) { // Is there more data to be sent to the bulk endpoint? if(sUSB.ulACKInCount != 0) { // There's more data to transmit, so indicate that we're not done. return(0); } else { // We've sent all the data, so indicate that we're done. return(1); } } //**************************************************************************** // // USBSendBulk transmits a block of data back to the host via the bulk // endpoint. // //**************************************************************************** unsigned long USBSendBulk(const unsigned char *pucData, unsigned long ulLength) { // If a block is already being transmitted, then return a failure. if(sUSB.ulBulkInCount) { return(0); } // Prepare to transmit this block back to the host. sUSB.pucBulkIn = pucData; sUSB.ulBulkInCount = ulLength; USBWriteEndpoint(USB_ENDPOINT_BULK_IN, &sUSB.pucBulkIn, &sUSB.ulBulkInCount); return(1); } //**************************************************************************** // // USBSendBulkDone determines if the data transmit to the bulk endpoint has // completed. // //**************************************************************************** unsigned long USBSendBulkDone(void) { // Is there more data to be sent to the bulk endpoint? if(sUSB.ulBulkInCount) { // There's more data to transmit, so indicate that we're not done. return(0); } else { // We've sent all the data, so indicate that we're done. return(1); } } //**************************************************************************** // // USBSendControlDone determines if the data transmit to the control endpoint // has completed. // //**************************************************************************** unsigned long USBSendControlDone(void) { // Is there more data to be sent to the control endpoint? if(sUSB.ulControlInCount) { // There's more data to transmit, so indicate that we're not done. return(0); } else { // We've sent all the data, so indicate that we're done. return(1); } } void USBISRPOLLING(int number) { unsigned long ulIntStatus, ulTransactionStatus, ulLength; unsigned char *pucChar, ucChar; static int choosebool=0; // // Read the PDIUSBD12 interrupt register. // USBWriteCommand(USB_COMMAND_READ_INTERRUPT); ulIntStatus = USBReadData(); ulIntStatus |= USBReadData() << 8; // // Do nothing if there was a bus reset. // if(ulIntStatus & USB_INT1_BUS_RESET) { if (verbose) printf("Host Send BUS-Reset Command.\n"); return; } // // Handle an interrupt on the bulk out endpoint. // if(ulIntStatus & USB_INT1_ENDPOINT2_OUT) { if (verbose) printf("Occur Main-Out-Endpoint Interrupt.\n"); // // Read the status of the last transaction on the bulk out endpoint. // USBWriteCommand(USB_COMMAND_READ_LAST_XACTION_STATUS + USB_ENDPOINT_BULK_OUT); ulTransactionStatus = USBReadData(); // // Was a packet of data received successfully? // if(ulTransactionStatus & USB_XACTION_STATUS_DATA_RX_TX_SUCCESS) { // // If there is a buffer to read this data into, then read the data // into that buffer. // // // Read the packet. // USBReadEndpoint(USB_ENDPOINT_BULK_OUT, &sUSB.pucBulkOut,&sUSB.ulBulkOutCount); } } // // Handle an interrupt on the control out endpoint. // if(ulIntStatus & USB_INT1_CONTROL_OUT) { if (verbose) printf("Occur Control-Out-Endpoint Interrupt.\n"); // // Read the status of the last transaction on the control out endpoint. // USBWriteCommand(USB_COMMAND_READ_LAST_XACTION_STATUS + USB_ENDPOINT_CONTROL_OUT); ulTransactionStatus = USBReadData(); // // Was a setup packet received? // if(ulTransactionStatus & USB_XACTION_STATUS_SETUP_PACKET) { // // Read the packet. // pucChar = (U8 *)&sUSB.sControlOut; ulLength = sizeof(ControlTransfer); if(USBReadEndpoint(USB_ENDPOINT_CONTROL_OUT, &pucChar,&ulLength) != sizeof(ControlTransfer)) { // // The size of the setup packet is incorrect, so stall both of // the control endpoints. // USBStallEndpoint(USB_ENDPOINT_CONTROL_OUT, 1); USBStallEndpoint(USB_ENDPOINT_CONTROL_IN, 1); } else { // // Acknowledge both the control in and control out endpoints, // and send a clear buffer command to the control out endpoint. // USBWriteCommand(USB_COMMAND_SELECT_ENDPOINT + USB_ENDPOINT_CONTROL_OUT); USBWriteCommand(USB_COMMAND_ACKNOWLEDGE_ENDPOINT); USBWriteCommand(USB_COMMAND_CLEAR_BUFFER); USBWriteCommand(USB_COMMAND_SELECT_ENDPOINT + USB_ENDPOINT_CONTROL_IN); USBWriteCommand(USB_COMMAND_ACKNOWLEDGE_ENDPOINT); // // // Process the command in the setup packet. // if(((sUSB.sControlOut.bmRequestType & USB_RT_TYPE_MASK) == USB_RT_TYPE_STANDARD) && (sUSB.sControlOut.bRequest < 16)) { // // This is a standard request, so call the appropriate // routine. // (*USBStandardDeviceRequest[sUSB.sControlOut.bRequest])(); } else { // // All other requests are treated as reserved requests. // USBReserved(); } } } else { // // The packet was not a setup packet, so ignore it. Send a clear // buffer command to the control out endpoint so it will receive // new packets. // USBWriteCommand(USB_COMMAND_SELECT_ENDPOINT + USB_ENDPOINT_CONTROL_OUT); USBWriteCommand(USB_COMMAND_CLEAR_BUFFER); // // Acknowledge both the control in and control out endpoints. // USBWriteCommand(USB_COMMAND_ACKNOWLEDGE_ENDPOINT); USBWriteCommand(USB_COMMAND_SELECT_ENDPOINT + USB_ENDPOINT_CONTROL_IN); USBWriteCommand(USB_COMMAND_ACKNOWLEDGE_ENDPOINT); } } // // Handle an interrupt on the control in endpoint. // if(ulIntStatus & USB_INT1_CONTROL_IN) { if (verbose) printf("Occur Control-In--Endpoint Interrupt.\n"); // // Read the status of the last transaction on the control in endpoint. // USBWriteCommand(USB_COMMAND_READ_LAST_XACTION_STATUS + USB_ENDPOINT_CONTROL_IN); USBReadData(); // // Was this the last block of data to be sent back to the host? // if(sUSB.ulControlInCount != 0) { // // Send the next packet of data to the host. // USBWriteEndpoint(USB_ENDPOINT_CONTROL_IN, &sUSB.pucControlIn, &sUSB.ulControlInCount); } else { // // There is no more data to send, so send an empty packet. // ulLength = 0; USBWriteEndpoint(USB_ENDPOINT_CONTROL_IN, 0, &ulLength); } } // // Handle an interrupt on the bulk in endpoint. // if(ulIntStatus & USB_INT1_ENDPOINT2_IN) { if (verbose) printf("Occur Main-In--Endpoint Interrupt.\n"); // // Read the status of the last transaction on the bulk in endpoint. // USBWriteCommand(USB_COMMAND_READ_LAST_XACTION_STATUS + USB_ENDPOINT_BULK_IN); USBReadData(); // // Was this the last block of data to be sent back to the host? // if(sUSB.ulBulkInCount != 0) { // // Send the next packet of data to the host. // USBWriteEndpoint(USB_ENDPOINT_BULK_IN, &sUSB.pucBulkIn, &sUSB.ulBulkInCount); } } }