⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usbdrv.c

📁 USBISP.rar
💻 C
📖 第 1 页 / 共 2 页
字号:
#if USB_CFG_IMPLEMENT_FN_READ    }else{        if(len != 0)    /* don't bother app with 0 sized reads */            return usbFunctionRead(data, len);        return 0;    }#endif}#define GET_DESCRIPTOR(cfgProp, staticName)         \    if(cfgProp){                                    \        if((cfgProp) & USB_PROP_IS_RAM)             \            flags &= ~USB_FLG_MSGPTR_IS_ROM;        \        if((cfgProp) & USB_PROP_IS_DYNAMIC){        \            replyLen = usbFunctionDescriptor(rq);   \        }else{                                      \            replyData = (uchar *)(staticName);      \            SET_REPLY_LEN((cfgProp) & 0xff);        \        }                                           \    }/* We use if() instead of #if in the macro above because #if can't be used * in macros and the compiler optimizes constant conditions anyway. *//* 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 */                    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 */                    usbTxPacketCnt1 = 0;        /* reset data toggling for interrupt endpoint */#   if USB_CFG_HAVE_INTRIN_ENDPOINT3                    usbTxPacketCnt3 = 0;        /* reset data toggling for interrupt endpoint */#   endif#   if USB_CFG_IMPLEMENT_HALT                    usbTxLen1 = USBPID_NAK;                }else if(rq->bRequest == USBRQ_CLEAR_FEATURE || rq->bRequest == USBRQ_SET_FEATURE){   /* 1|3 */                    if(rq->wValue.bytes[0] == 0 && rq->wIndex.bytes[0] == 0x81){   /* feature 0 == HALT for endpoint == 1 */                        usbTxLen1 = rq->bRequest == USBRQ_CLEAR_FEATURE ? USBPID_NAK : USBPID_STALL;                        usbTxPacketCnt1 = 0;    /* reset data toggling for interrupt endpoint */#       if USB_CFG_HAVE_INTRIN_ENDPOINT3                        usbTxPacketCnt3 = 0;    /* reset data toggling for interrupt endpoint */#       endif                    }#   endif#endif                }else{                    /* the following requests can be ignored, send default reply */                    /* 1: CLEAR_FEATURE, 3: SET_FEATURE, 7: SET_DESCRIPTOR */                    /* 12: SYNCH_FRAME */                }                #undef SET_REPLY_LEN            }else{  /* not a standard request -- must be vendor or class request */                replyLen = usbFunctionSetup(data);            }#if USB_CFG_IMPLEMENT_FN_READ || USB_CFG_IMPLEMENT_FN_WRITE            if(replyLen == 0xff){   /* use user-supplied read/write function */                if((rq->bmRequestType & USBRQ_DIR_MASK) == USBRQ_DIR_DEVICE_TO_HOST){                    replyLen = rq->wLength.bytes[0];    /* IN transfers only */                }                flags &= ~USB_FLG_USE_DEFAULT_RW;  /* we have no valid msg, use user supplied read/write functions */            }else   /* The 'else' prevents that we limit a replyLen of 0xff to the maximum transfer len. */#endif            if(!rq->wLength.bytes[1] && replyLen > rq->wLength.bytes[0])  /* limit length to max */                replyLen = rq->wLength.bytes[0];        }        /* make sure that data packets which are sent as ACK to an OUT transfer are always zero sized */    }else{  /* DATA packet from out request */#if USB_CFG_IMPLEMENT_FN_WRITE        if(!(usbMsgFlags & USB_FLG_USE_DEFAULT_RW)){            uchar rval = usbFunctionWrite(data, len);            replyLen = 0xff;            if(rval == 0xff){       /* an error occurred */                usbMsgLen = 0xff;   /* cancel potentially pending data packet for ACK */                usbTxLen = USBPID_STALL;            }else if(rval != 0){    /* This was the final package */                replyLen = 0;       /* answer with a zero-sized data packet */            }            flags = 0;    /* start with a DATA1 package, stay with user supplied write() function */        }#endif    }    usbMsgFlags = flags;    usbMsgLen = replyLen;}/* ------------------------------------------------------------------------- */static void usbBuildTxBlock(void){uchar       wantLen, len, txLen, token;    wantLen = usbMsgLen;    if(wantLen > 8)        wantLen = 8;    usbMsgLen -= wantLen;    token = USBPID_DATA1;    if(usbMsgFlags & USB_FLG_TX_PACKET)        token = USBPID_DATA0;    usbMsgFlags++;    len = usbRead(usbTxBuf + 1, wantLen);    if(len <= 8){           /* valid data packet */        usbCrc16Append(&usbTxBuf[1], len);        txLen = len + 4;    /* length including sync byte */        if(len < 8)         /* a partial package identifies end of message */            usbMsgLen = 0xff;    }else{        txLen = USBPID_STALL;   /* stall the endpoint */        usbMsgLen = 0xff;    }    usbTxBuf[0] = token;    usbTxLen = txLen;    DBG2(0x20, usbTxBuf, txLen-1);}static inline uchar isNotSE0(void){uchar   rval;/* We want to do *     return (USBIN & USBMASK); * here, but the compiler does int-expansion acrobatics. * We can avoid this by assigning to a char-sized variable. */    rval = USBIN & USBMASK;    return rval;}/* ------------------------------------------------------------------------- */void    usbPoll(void){uchar   len;    if((len = usbRxLen) > 0){/* We could check CRC16 here -- but ACK has already been sent anyway. If you * need data integrity checks with this driver, check the CRC in your app * code and report errors back to the host. Since the ACK was already sent, * retries must be handled on application level. * unsigned crc = usbCrc16((uchar *)(unsigned)(usbAppBuf + 1), usbRxLen - 3); */        len -= 3;       /* remove PID and CRC */        if(len < 128){  /* no overflow */            converter_t appBuf;            appBuf.ptr = (uchar *)usbRxBuf;            appBuf.bytes[0] = usbAppBuf;            appBuf.bytes[0]++;            usbProcessRx(appBuf.ptr, len);        }#if USB_CFG_HAVE_FLOWCONTROL        if(usbRxLen > 0)    /* only mark as available if not inactivated */            usbRxLen = 0;#else        usbRxLen = 0;   /* mark rx buffer as available */#endif    }    if(usbMsgLen != 0xff){  /* transmit data pending? */        if(usbTxLen & 0x10) /* transmit system idle */            usbBuildTxBlock();    }    if(isNotSE0()){ /* SE0 state */        usbIsReset = 0;    }else{        /* check whether SE0 lasts for more than 2.5us (3.75 bit times) */        if(!usbIsReset){            uchar i;            for(i=100;i;i--){                if(isNotSE0())                    goto notUsbReset;            }            usbIsReset = 1;            usbNewDeviceAddr = 0;            usbDeviceAddr = 0;#if USB_CFG_IMPLEMENT_HALT            usbTxLen1 = USBPID_NAK;#if USB_CFG_HAVE_INTRIN_ENDPOINT3            usbTxLen3 = USBPID_NAK;#endif#endif            DBG1(0xff, 0, 0);notUsbReset:;        }    }}/* ------------------------------------------------------------------------- */void    usbInit(void){    usbInputBuf = (uchar)usbRxBuf[0];    usbAppBuf = (uchar)usbRxBuf[1];#if USB_INTR_CFG_SET != 0    USB_INTR_CFG |= USB_INTR_CFG_SET;#endif#if USB_INTR_CFG_CLR != 0    USB_INTR_CFG &= ~(USB_INTR_CFG_CLR);#endif    USB_INTR_ENABLE |= (1 << USB_INTR_ENABLE_BIT);}/* ------------------------------------------------------------------------- */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -