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

📄 usbdrv.c

📁 AVR16源代码 ICC编译器 AVR16源代码 ICC编译器
💻 C
📖 第 1 页 / 共 2 页
字号:
 * 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. */#if DEBUG_LEVEL > 1    DBG2(0x10 + (usbRxToken == (uchar)USBPID_SETUP), data, len);#else    DBG1(0x10 + (usbRxToken == (uchar)USBPID_SETUP), data, 2);#endif    if(usbRxToken == (uchar)USBPID_SETUP){        if(len == 8){   /* Setup size must be always 8 bytes. Ignore otherwise. */            uchar type = rq->bmRequestType & USBRQ_TYPE_MASK;            if(type == USBRQ_TYPE_STANDARD){                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(usbHalted1 && recipient == USBRQ_RCPT_ENDPOINT && rq->wIndex.bytes[0] == 0x81)   /* request status for endpoint 1 */                        replyData[0] = 1;#endif                    replyData[1] = 0;                    replyLen = 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] == 1){   /* descriptor type requested */                        replyLen = sizeof(usbDescrDevice);                        replyData = (uchar *)usbDescrDevice;                    }else if(rq->wValue.bytes[1] == 2){                        replyLen = sizeof(usbDescrConfig);                        replyData = (uchar *)usbDescrConfig;                    }else if(rq->wValue.bytes[1] == 3){ /* string descriptor */                        if(rq->wValue.bytes[0] == 0){   /* descriptor index */                            replyLen = sizeof(usbDescrString0);                            replyData = (uchar *)usbDescrString0;#if USB_CFG_VENDOR_NAME_LEN                        }else if(rq->wValue.bytes[0] == 1){                            replyLen = sizeof(usbDescrString1);                            replyData = (uchar *)usbDescrString1;#endif#if USB_CFG_DEVICE_NAME_LEN                        }else if(rq->wValue.bytes[0] == 2){                            replyLen = sizeof(usbDescrString2);                            replyData = (uchar *)usbDescrString2;#endif#if USB_CFG_SERIAL_NUMBER_LENGTH                        }else if(rq->wValue.bytes[0] == 3){                            replyLen = 2 * USB_CFG_SERIAL_NUMBER_LENGTH + 2;                            replyData = (uchar *)usbCfgSerialNumberStringDescriptor;#endif                        }                    }#if USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH                    else if(rq->wValue.bytes[1] == USBDESCR_HID){           /* 0x21 */                        replyLen = 9;                        replyData = (uchar *)usbDescrConfig + 18;                    }else if(rq->wValue.bytes[1] == USBDESCR_HID_REPORT){   /* 0x22 */                        replyLen = USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH;                        replyData = (uchar *)usbHidReportDescriptor;                    }#endif                }else if(rq->bRequest == USBRQ_GET_CONFIGURATION){  /* 8 */                    replyLen = 1;                    replyData = &usbConfiguration;  /* send current configuration value */                }else if(rq->bRequest == USBRQ_SET_CONFIGURATION){  /* 9 */                    usbConfiguration = rq->wValue.bytes[0];#if USB_CFG_IMPLEMENT_HALT                    usbHalted1 = 0;#endif                }else if(rq->bRequest == USBRQ_GET_INTERFACE){      /* 10 */                    replyLen = 1;#if USB_CFG_HAVE_INTRIN_ENDPOINT#if USB_CFG_IMPLEMENT_HALT                }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 */                        usbHalted1 = rq->bRequest - 1;                        if(usbHalted1){                            usbTxBuf1[0] = USBPID_STALL;                            usbTxLen1 = 2;      /* length including sync byte */                        }                        usbTxPacketCnt1 = 0;    /* reset data toggling for interrupt endpoint */                    }#endif                }else if(rq->bRequest == USBRQ_SET_INTERFACE){      /* 11 */                    usbTxPacketCnt1 = 0;        /* reset data toggling for interrupt endpoint */#if USB_CFG_IMPLEMENT_HALT                    usbHalted1 = 0;#endif#endif                }else{                    /* the following requests can be ignored, send default reply */                    /* 1: CLEAR_FEATURE, 3: SET_FEATURE, 7: SET_DESCRIPTOR */                    /* 12: SYNCH_FRAME */                }                usbMsgPtr = replyData;                if(!rq->wLength.bytes[1] && replyLen > rq->wLength.bytes[0])  /* max length is in */                    replyLen = rq->wLength.bytes[0];            }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 = 0;  /* we have no valid msg, use user supplied read/write functions */                }#endif            }        }        /* 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 ACK [has been done by ASM module when OUT token arrived] */                usbTxBuf[0] = USBPID_STALL;                usbTxLen = 2;       /* length including sync byte */            }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 */        }#else        replyLen = 0;      /* send zero-sized block as ACK */#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{        token = USBPID_STALL;        txLen = 2;          /* length including sync byte */        usbMsgLen = 0xff;    }    usbTxBuf[0] = token;    usbTxLen = txLen;#if DEBUG_LEVEL > 1    DBG2(0x20, usbTxBuf, txLen-1);#else    DBG1(0x20, usbTxBuf + 1, 2);#endif}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);        }        usbRxLen = 0;   /* mark rx buffer as available */    }    if(usbMsgLen != 0xff){  /* transmit data pending? */        if(usbTxLen < 0)    /* 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            usbHalted1 = 0;#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 + -