예제 #1
0
/* Don't make this function static to avoid inlining.
 * The entire function would become too large and exceed the range of
 * relative jumps.
 * 2006-02-25: Either gcc 3.4.3 is better than the gcc used when the comment
 * above was written, or other parts of the code have changed. We now get
 * better results with an inlined function. Test condition: PowerSwitch code.
 */
static void usbProcessRx(uchar *data, uchar len)
{
usbRequest_t    *rq = (void *)data;
uchar           replyLen = 0, flags = USB_FLG_USE_DEFAULT_RW;
/* We use if() cascades because the compare is done byte-wise while switch()
 * is int-based. The if() cascades are therefore more efficient.
 */
    DBG2(0x10 + ((usbRxToken >> 6) & 3), data, len);
#if USB_CFG_IMPLEMENT_FN_WRITEOUT
    if(usbRxToken & 0x80){
        usbFunctionWriteOut(data, len);
        return; /* no reply expected, hence no usbMsgPtr, usbMsgFlags, usbMsgLen set */
    }
    if(usbRxToken == (uchar)(USBPID_SETUP & 0x7f)){ /* MSb contains endpoint (== 0) */
#else
    if(usbRxToken == (uchar)USBPID_SETUP){
#endif
        if(len == 8){   /* Setup size must be always 8 bytes. Ignore otherwise. */
            uchar type = rq->bmRequestType & USBRQ_TYPE_MASK;
            if(type == USBRQ_TYPE_STANDARD){
                #define SET_REPLY_LEN(len)  replyLen = (len); usbMsgPtr = replyData
                /* This macro ensures that replyLen and usbMsgPtr are always set in the same way.
                 * That allows optimization of common code in if() branches */
                uchar *replyData = usbTxBuf + 9; /* there is 3 bytes free space at the end of the buffer */
                replyData[0] = 0;   /* common to USBRQ_GET_STATUS and USBRQ_GET_INTERFACE */
                if(rq->bRequest == USBRQ_GET_STATUS){           /* 0 */
                    uchar __attribute__((__unused__)) recipient = rq->bmRequestType & USBRQ_RCPT_MASK;  /* assign arith ops to variables to enforce byte size */
#if USB_CFG_IS_SELF_POWERED
                    if(recipient == USBRQ_RCPT_DEVICE)
                        replyData[0] =  USB_CFG_IS_SELF_POWERED;
#endif
#if USB_CFG_HAVE_INTRIN_ENDPOINT && USB_CFG_IMPLEMENT_HALT
                    if(recipient == USBRQ_RCPT_ENDPOINT && rq->wIndex.bytes[0] == 0x81)   /* request status for endpoint 1 */
                        replyData[0] = usbTxLen1 == USBPID_STALL;
#endif
                    replyData[1] = 0;
                    SET_REPLY_LEN(2);
                }else if(rq->bRequest == USBRQ_SET_ADDRESS){    /* 5 */
                    usbNewDeviceAddr = rq->wValue.bytes[0];
                }else if(rq->bRequest == USBRQ_GET_DESCRIPTOR){ /* 6 */
                    flags = USB_FLG_MSGPTR_IS_ROM | USB_FLG_USE_DEFAULT_RW;
                    if(rq->wValue.bytes[1] == USBDESCR_DEVICE){ /* 1 */
                        GET_DESCRIPTOR(USB_CFG_DESCR_PROPS_DEVICE, usbDescriptorDevice)
                    }else if(rq->wValue.bytes[1] == USBDESCR_CONFIG){   /* 2 */
                        GET_DESCRIPTOR(USB_CFG_DESCR_PROPS_CONFIGURATION, usbDescriptorConfiguration)
                    }else if(rq->wValue.bytes[1] == USBDESCR_STRING){   /* 3 */
#if USB_CFG_DESCR_PROPS_STRINGS & USB_PROP_IS_DYNAMIC
                        if(USB_CFG_DESCR_PROPS_STRINGS & USB_PROP_IS_RAM)
                            flags &= ~USB_FLG_MSGPTR_IS_ROM;
                        replyLen = usbFunctionDescriptor(rq);
#else   /* USB_CFG_DESCR_PROPS_STRINGS & USB_PROP_IS_DYNAMIC */
                        if(rq->wValue.bytes[0] == 0){   /* descriptor index */
                            GET_DESCRIPTOR(USB_CFG_DESCR_PROPS_STRING_0, usbDescriptorString0)
                        }else if(rq->wValue.bytes[0] == 1){
                            GET_DESCRIPTOR(USB_CFG_DESCR_PROPS_STRING_VENDOR, usbDescriptorStringVendor)
                        }else if(rq->wValue.bytes[0] == 2){
                            GET_DESCRIPTOR(USB_CFG_DESCR_PROPS_STRING_DEVICE, usbDescriptorStringDevice)
                        }else if(rq->wValue.bytes[0] == 3){
                            GET_DESCRIPTOR(USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER, usbDescriptorStringSerialNumber)
                        }else if(USB_CFG_DESCR_PROPS_UNKNOWN & USB_PROP_IS_DYNAMIC){
                            replyLen = usbFunctionDescriptor(rq);
                        }
#endif  /* USB_CFG_DESCR_PROPS_STRINGS & USB_PROP_IS_DYNAMIC */
                    }else if(rq->wValue.bytes[1] == USBDESCR_HID){          /* 0x21 */
                        GET_DESCRIPTOR(USB_CFG_DESCR_PROPS_HID, usbDescriptorConfiguration + 18)
                    }else if(rq->wValue.bytes[1] == USBDESCR_HID_REPORT){   /* 0x22 */
                        GET_DESCRIPTOR(USB_CFG_DESCR_PROPS_HID_REPORT, usbDescriptorHidReport)
                    }else if(USB_CFG_DESCR_PROPS_UNKNOWN & USB_PROP_IS_DYNAMIC){
                        replyLen = usbFunctionDescriptor(rq);
                    }
                }else if(rq->bRequest == USBRQ_GET_CONFIGURATION){  /* 8 */
예제 #2
0
파일: usbdrv.c 프로젝트: hepri101/pixel-kit
                        }else if(rq->wValue.bytes[0] == 2){
                            GET_DESCRIPTOR(USB_CFG_DESCR_PROPS_STRING_PRODUCT, usbDescriptorStringDevice)
                        }else if(rq->wValue.bytes[0] == 3){
                            GET_DESCRIPTOR(USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER, usbDescriptorStringSerialNumber)
                        }else if(USB_CFG_DESCR_PROPS_UNKNOWN & USB_PROP_IS_DYNAMIC){
                            replyLen = usbFunctionDescriptor(rq);
                        }
#endif  /* USB_CFG_DESCR_PROPS_STRINGS & USB_PROP_IS_DYNAMIC */
#if USB_CFG_DESCR_PROPS_HID_REPORT  /* only support HID descriptors if enabled */
                    }else if(rq->wValue.bytes[1] == USBDESCR_HID){          /* 0x21 */
                        GET_DESCRIPTOR(USB_CFG_DESCR_PROPS_HID, usbDescriptorConfiguration + 18)
                    }else if(rq->wValue.bytes[1] == USBDESCR_HID_REPORT){   /* 0x22 */
                        GET_DESCRIPTOR(USB_CFG_DESCR_PROPS_HID_REPORT, usbDescriptorHidReport)
#endif  /* USB_CFG_DESCR_PROPS_HID_REPORT */
                    }else if(USB_CFG_DESCR_PROPS_UNKNOWN & USB_PROP_IS_DYNAMIC){
                        replyLen = usbFunctionDescriptor(rq);
                    }
                }else if(rq->bRequest == USBRQ_GET_CONFIGURATION){  /* 8 */
                    replyData = &usbConfiguration;  /* send current configuration value */
                    SET_REPLY_LEN(1);
                }else if(rq->bRequest == USBRQ_SET_CONFIGURATION){  /* 9 */
                    usbConfiguration = rq->wValue.bytes[0];
#if USB_CFG_IMPLEMENT_HALT
                    usbTxLen1 = USBPID_NAK;
#endif
                }else if(rq->bRequest == USBRQ_GET_INTERFACE){      /* 10 */
                    SET_REPLY_LEN(1);
#if USB_CFG_HAVE_INTRIN_ENDPOINT
                }else if(rq->bRequest == USBRQ_SET_INTERFACE){      /* 11 */
                    USB_SET_DATATOKEN1(USB_INITIAL_DATATOKEN);  /* reset data toggling for interrupt endpoint */
#   if USB_CFG_HAVE_INTRIN_ENDPOINT3