void ClearEp3OutPktReady(void) { struct s3c24x0_usb_device * const usbdevregs = s3c24x0_get_base_usb_device(); U8 out_csr3; usbdevregs->INDEX_REG = 3; out_csr3 = usbdevregs->OUT_CSR1_REG; CLR_EP3_OUT_PKT_READY(); }
void Ep3Handler(void) { struct s3c24x0_interrupt *intregs = s3c24x0_get_base_interrupt(); struct s3c24x0_usb_device *const usbdevregs = s3c24x0_get_base_usb_device(); U8 out_csr3; int fifoCnt; usbdevregs->INDEX_REG = 3; out_csr3 = usbdevregs->OUT_CSR1_REG; DbgPrintf("<3:%x]",out_csr3); if(out_csr3 & EPO_OUT_PKT_READY) { fifoCnt = usbdevregs->OUT_FIFO_CNT1_REG; if (downloadFileSize == 0) { RdPktEp3((U8 *)downPt, 8); if(download_run == 0) { downloadAddress = tempDownloadAddress; } else { downloadAddress = *((U32 *)downPt); dwUSBBufReadPtr = downloadAddress; dwUSBBufWritePtr = downloadAddress; } downloadFileSize = *((U32 *)(downPt + 4)); DbgPrintf("[dwaddr = %x, dwsize = %x]\n", downloadAddress, downloadFileSize); checkSum = 0; downPt = (U8 *)downloadAddress; /* The first 8-bytes are deleted. */ RdPktEp3_CheckSum((U8 *)downPt, fifoCnt-8); downPt += fifoCnt - 8; #if USBDMA /* * 传输由中断发起(只接收头一个Pkg),由DMA完成. * 因此发生中断后就禁止USBD中断,在DMA传输完成 * 后再次开启. */ intregs->INTMSK |= BIT_USBD; return; #endif } else { RdPktEp3_CheckSum((U8 *)downPt, fifoCnt); downPt += fifoCnt; //fifoCnt = 64 } CLR_EP3_OUT_PKT_READY(); return; } if (out_csr3 & EPO_SENT_STALL) { DbgPrintf("[STALL]"); CLR_EP3_SENT_STALL(); return; } }
void RdPktEp3_CheckSum(U8 *buf,int num) { int i; struct s3c24x0_usb_device *const usbdevregs = s3c24x0_get_base_usb_device(); for(i = 0; i < num; i++) { buf[i] = (U8)usbdevregs->fifo[3].EP_FIFO_REG; checkSum += buf[i]; } }
void IsrDma2() { struct s3c24x0_interrupt *intregs = s3c24x0_get_base_interrupt(); struct s3c24x0_usb_device *usbdevregs = s3c24x0_get_base_usb_device(); U8 out_csr3; U32 dwEmptyCnt; U8 saveIndexReg = usbdevregs->INDEX_REG; usbdevregs->INDEX_REG = 3; out_csr3 = usbdevregs->OUT_CSR1_REG; ClearPending_my((int)BIT_DMA2); if (!totalDmaCount) totalDmaCount = dwWillDMACnt + EP3_PKT_SIZE; else totalDmaCount += dwWillDMACnt; dwUSBBufWritePtr = ((dwUSBBufWritePtr + dwWillDMACnt - dwUSBBufBase) % dwUSBBufSize) + dwUSBBufBase; if (totalDmaCount >= downloadFileSize) { /* last */ totalDmaCount = downloadFileSize; ConfigEp3IntMode(); if (out_csr3 & EPO_OUT_PKT_READY) CLR_EP3_OUT_PKT_READY(); /* 关闭DMA2中断并重新开启USBD中断 */ intregs->INTMSK |= BIT_DMA2; intregs->INTMSK &= ~(BIT_USBD); } else { if ((totalDmaCount + 0x80000) < downloadFileSize) dwWillDMACnt = 0x80000; else dwWillDMACnt = downloadFileSize - totalDmaCount; dwEmptyCnt = (dwUSBBufReadPtr - dwUSBBufWritePtr - 1 + dwUSBBufSize) % dwUSBBufSize; if (dwEmptyCnt >= dwWillDMACnt) ConfigEp3DmaMode(dwUSBBufWritePtr, dwWillDMACnt); } usbdevregs->INDEX_REG = saveIndexReg; }
void Ep0Handler(void) { static int ep0SubState; U8 ep0_csr; struct s3c24x0_usb_device * const usbdevregs = s3c24x0_get_base_usb_device(); writeb(0, &usbdevregs->INDEX_REG); ep0_csr = readb(&usbdevregs->EP0_CSR_IN_CSR1_REG); //DATAEND interrupt(ep0_csr==0x0) will be ignored //because ep0State==EP0_STATE_INIT when the DATAEND interrupt is issued. if(ep0_csr & EP0_SETUP_END) { // Host may end GET_DESCRIPTOR operation without completing the IN data stage. // If host does that, SETUP_END bit will be set. // OUT_PKT_RDY has to be also cleared because status stage sets OUT_PKT_RDY to 1. // DbgPrintf("[SETUPEND]"); CLR_EP0_SETUP_END(); if(ep0_csr & EP0_OUT_PKT_READY) { FLUSH_EP0_FIFO(); //(???) //I think this isn't needed because EP0 flush is done automatically. CLR_EP0_OUT_PKT_RDY(); } ep0State=EP0_STATE_INIT; return; } //I think that EP0_SENT_STALL will not be set to 1. if(ep0_csr & EP0_SENT_STALL) { // DbgPrintf("[STALL]"); CLR_EP0_SENT_STALL(); if(ep0_csr & EP0_OUT_PKT_READY) { CLR_EP0_OUT_PKT_RDY(); } ep0State=EP0_STATE_INIT; return; } if((ep0_csr & EP0_OUT_PKT_READY)) // && (ep0State==EP0_STATE_INIT)) { RdPktEp0((U8 *)&descSetup,EP0_PKT_SIZE); // PrintEp0Pkt((U8 *)(&descSetup)); //DEBUG switch(descSetup.bRequest) { case GET_DESCRIPTOR: switch(descSetup.bValueH) { case DEVICE_TYPE: // DbgPrintf("[GDD]"); CLR_EP0_OUT_PKT_RDY(); ep0State=EP0_STATE_GD_DEV_0; break; case CONFIGURATION_TYPE: // DbgPrintf("[GDC]"); CLR_EP0_OUT_PKT_RDY(); if((descSetup.bLengthL+(descSetup.bLengthH<<8))>0x9) //bLengthH should be used for bLength=0x209 at WIN2K. ep0State=EP0_STATE_GD_CFG_0; //for WIN98,WIN2K else ep0State=EP0_STATE_GD_CFG_ONLY_0; //for WIN2K break; case STRING_TYPE: // DbgPrintf("[GDS]"); CLR_EP0_OUT_PKT_RDY(); switch(descSetup.bValueL) { case 0: ep0State=EP0_STATE_GD_STR_I0; break; case 1: ep0State=EP0_STATE_GD_STR_I1; break; case 2: ep0State=EP0_STATE_GD_STR_I2; break; default: // DbgPrintf("[UE:STRI?]"); break; } ep0SubState=0; break; case INTERFACE_TYPE: // DbgPrintf("[GDI]"); CLR_EP0_OUT_PKT_RDY(); ep0State=EP0_STATE_GD_IF_ONLY_0; //for WIN98 break; case ENDPOINT_TYPE: // DbgPrintf("[GDE]"); CLR_EP0_OUT_PKT_RDY(); switch(descSetup.bValueL&0xf) { case 0: ep0State=EP0_STATE_GD_EP0_ONLY_0; break; case 1: ep0State=EP0_STATE_GD_EP1_ONLY_0; break; default: // DbgPrintf("[UE:GDE?]"); break; } break; default: // DbgPrintf("[UE:GD?]"); break; } break; case SET_ADDRESS: // DbgPrintf("[SA:%d]",descSetup.bValueL); writeb((descSetup.bValueL | 0x80), &usbdevregs->FUNC_ADDR_REG); CLR_EP0_OUTPKTRDY_DATAEND(); //Because of no data control transfers. ep0State=EP0_STATE_INIT; break; case SET_CONFIGURATION: // DbgPrintf("[SC]"); ConfigSet.ConfigurationValue=descSetup.bValueL; CLR_EP0_OUTPKTRDY_DATAEND(); //Because of no data control transfers. ep0State=EP0_STATE_INIT; isUsbdSetConfiguration=1; break; //////////////////////// For chapter 9 test //////////////////// case CLEAR_FEATURE: switch (descSetup.bmRequestType) { case DEVICE_RECIPIENT: if (descSetup.bValueL == 1) Rwuen = FALSE; break; case ENDPOINT_RECIPIENT: if (descSetup.bValueL == 0) { if((descSetup.bIndexL & 0x7f) == 0x00){ StatusGet.Endpoint0= 0; } if((descSetup.bIndexL & 0x8f) == 0x81){ // IN Endpoint 1 StatusGet.Endpoint1= 0; } if((descSetup.bIndexL & 0x8f) == 0x03){ // OUT Endpoint 3 StatusGet.Endpoint3= 0; } } break; default: break; } CLR_EP0_OUTPKTRDY_DATAEND(); ep0State=EP0_STATE_INIT; break; case GET_CONFIGURATION: CLR_EP0_OUT_PKT_RDY(); ep0State=EP0_CONFIG_SET; break; case GET_INTERFACE: CLR_EP0_OUT_PKT_RDY(); ep0State=EP0_INTERFACE_GET; break; case GET_STATUS: switch(descSetup.bmRequestType) { case (0x80): CLR_EP0_OUT_PKT_RDY(); StatusGet.Device=((U8)Rwuen<<1)|(U8)Selfpwr; ep0State=EP0_GET_STATUS0; break; case (0x81): CLR_EP0_OUT_PKT_RDY(); StatusGet.Interface=0; ep0State=EP0_GET_STATUS1; break; case (0x82): CLR_EP0_OUT_PKT_RDY(); if((descSetup.bIndexL & 0x7f) == 0x00){ ep0State=EP0_GET_STATUS2; } if((descSetup.bIndexL & 0x8f) == 0x81){ ep0State=EP0_GET_STATUS3; } if((descSetup.bIndexL & 0x8f) == 0x03){ ep0State=EP0_GET_STATUS4; } break; default: break; } break; case SET_DESCRIPTOR: CLR_EP0_OUTPKTRDY_DATAEND(); ep0State=EP0_STATE_INIT; break; case SET_FEATURE: switch (descSetup.bmRequestType) { case DEVICE_RECIPIENT: if (descSetup.bValueL == 1) Rwuen = TRUE; break; case ENDPOINT_RECIPIENT: if (descSetup.bValueL == 0) { if((descSetup.bIndexL & 0x7f) == 0x00){ StatusGet.Endpoint0= 1; } if((descSetup.bIndexL & 0x8f) == 0x81){ StatusGet.Endpoint1= 1; } if((descSetup.bIndexL & 0x8f) == 0x03){ StatusGet.Endpoint3= 1; } } break; default: break; } CLR_EP0_OUTPKTRDY_DATAEND(); ep0State=EP0_STATE_INIT; break; case SET_INTERFACE: InterfaceGet.AlternateSetting= descSetup.bValueL; CLR_EP0_OUTPKTRDY_DATAEND(); ep0State=EP0_STATE_INIT; break; case SYNCH_FRAME: ep0State=EP0_STATE_INIT; break; ////////////////////////////////////////////////////////////// default: // DbgPrintf("[UE:SETUP=%x]",descSetup.bRequest); CLR_EP0_OUTPKTRDY_DATAEND(); //Because of no data control transfers. ep0State=EP0_STATE_INIT; break; } } switch(ep0State) { case EP0_STATE_INIT: break; //=== GET_DESCRIPTOR:DEVICE === case EP0_STATE_GD_DEV_0: // DbgPrintf("[GDD0]"); WrPktEp0((U8 *)&descDev+0,8); //EP0_PKT_SIZE SET_EP0_IN_PKT_RDY(); ep0State=EP0_STATE_GD_DEV_1; break; case EP0_STATE_GD_DEV_1: // DbgPrintf("[GDD1]"); WrPktEp0((U8 *)&descDev+0x8,8); SET_EP0_IN_PKT_RDY(); ep0State=EP0_STATE_GD_DEV_2; break; case EP0_STATE_GD_DEV_2: // DbgPrintf("[GDD2]"); WrPktEp0((U8 *)&descDev+0x10,2); //8+8+2=0x12 SET_EP0_INPKTRDY_DATAEND(); ep0State=EP0_STATE_INIT; break; //=== GET_DESCRIPTOR:CONFIGURATION+INTERFACE+ENDPOINT0+ENDPOINT1 === //Windows98 gets these 4 descriptors all together by issuing only a request. //Windows2000 gets each descriptor seperately. case EP0_STATE_GD_CFG_0: // DbgPrintf("[GDC0]"); WrPktEp0((U8 *)&descConf+0,8); //EP0_PKT_SIZE SET_EP0_IN_PKT_RDY(); ep0State=EP0_STATE_GD_CFG_1; break; case EP0_STATE_GD_CFG_1: // DbgPrintf("[GDC1]"); WrPktEp0((U8 *)&descConf+8,1); WrPktEp0((U8 *)&descIf+0,7); SET_EP0_IN_PKT_RDY(); ep0State=EP0_STATE_GD_CFG_2; break; case EP0_STATE_GD_CFG_2: // DbgPrintf("[GDC2]"); WrPktEp0((U8 *)&descIf+7,2); WrPktEp0((U8 *)&descEndpt0+0,6); SET_EP0_IN_PKT_RDY(); ep0State=EP0_STATE_GD_CFG_3; break; case EP0_STATE_GD_CFG_3: // DbgPrintf("[GDC3]"); WrPktEp0((U8 *)&descEndpt0+6,1); WrPktEp0((U8 *)&descEndpt1+0,7); SET_EP0_IN_PKT_RDY(); ep0State=EP0_STATE_GD_CFG_4; break; case EP0_STATE_GD_CFG_4: // DbgPrintf("[GDC4]"); //zero length data packit SET_EP0_INPKTRDY_DATAEND(); ep0State=EP0_STATE_INIT; break; //=== GET_DESCRIPTOR:CONFIGURATION ONLY=== case EP0_STATE_GD_CFG_ONLY_0: // DbgPrintf("[GDCO0]"); WrPktEp0((U8 *)&descConf+0,8); //EP0_PKT_SIZE SET_EP0_IN_PKT_RDY(); ep0State=EP0_STATE_GD_CFG_ONLY_1; break; case EP0_STATE_GD_CFG_ONLY_1: // DbgPrintf("[GDCO1]"); WrPktEp0((U8 *)&descConf+8,1); SET_EP0_INPKTRDY_DATAEND(); ep0State=EP0_STATE_INIT; break; //=== GET_DESCRIPTOR:INTERFACE ONLY=== case EP0_STATE_GD_IF_ONLY_0: // DbgPrintf("[GDI0]"); WrPktEp0((U8 *)&descIf+0,8); SET_EP0_IN_PKT_RDY(); ep0State=EP0_STATE_GD_IF_ONLY_1; break; case EP0_STATE_GD_IF_ONLY_1: // DbgPrintf("[GDI1]"); WrPktEp0((U8 *)&descIf+8,1); SET_EP0_INPKTRDY_DATAEND(); ep0State=EP0_STATE_INIT; break; //=== GET_DESCRIPTOR:ENDPOINT 0 ONLY=== case EP0_STATE_GD_EP0_ONLY_0: // DbgPrintf("[GDE00]"); WrPktEp0((U8 *)&descEndpt0+0,7); SET_EP0_INPKTRDY_DATAEND(); ep0State=EP0_STATE_INIT; break; //=== GET_DESCRIPTOR:ENDPOINT 1 ONLY=== case EP0_STATE_GD_EP1_ONLY_0: // DbgPrintf("[GDE10]"); WrPktEp0((U8 *)&descEndpt1+0,7); SET_EP0_INPKTRDY_DATAEND(); ep0State=EP0_STATE_INIT; break; //////////////////////////////////////////// case EP0_INTERFACE_GET: WrPktEp0((U8 *)&InterfaceGet+0,1); SET_EP0_INPKTRDY_DATAEND(); ep0State=EP0_STATE_INIT; break; //=== GET_DESCRIPTOR:STRING === case EP0_STATE_GD_STR_I0: // DbgPrintf("[GDS0_0]"); WrPktEp0((U8 *)descStr0, 4 ); SET_EP0_INPKTRDY_DATAEND(); ep0State=EP0_STATE_INIT; ep0SubState=0; break; case EP0_STATE_GD_STR_I1: // DbgPrintf("[GDS1_%d]",ep0SubState); if( (ep0SubState*EP0_PKT_SIZE+EP0_PKT_SIZE)<sizeof(descStr1) ) { WrPktEp0((U8 *)descStr1+(ep0SubState*EP0_PKT_SIZE),EP0_PKT_SIZE); SET_EP0_IN_PKT_RDY(); ep0State=EP0_STATE_GD_STR_I1; ep0SubState++; } else { WrPktEp0((U8 *)descStr1+(ep0SubState*EP0_PKT_SIZE), sizeof(descStr1)-(ep0SubState*EP0_PKT_SIZE)); SET_EP0_INPKTRDY_DATAEND(); ep0State=EP0_STATE_INIT; ep0SubState=0; } break; case EP0_STATE_GD_STR_I2: // DbgPrintf("[GDS2_%d]",ep0SubState); if( (ep0SubState*EP0_PKT_SIZE+EP0_PKT_SIZE)<sizeof(descStr2) ) { WrPktEp0((U8 *)descStr2+(ep0SubState*EP0_PKT_SIZE),EP0_PKT_SIZE); SET_EP0_IN_PKT_RDY(); ep0State=EP0_STATE_GD_STR_I2; ep0SubState++; } else { // DbgPrintf("[E]"); WrPktEp0((U8 *)descStr2+(ep0SubState*EP0_PKT_SIZE), sizeof(descStr2)-(ep0SubState*EP0_PKT_SIZE)); SET_EP0_INPKTRDY_DATAEND(); ep0State=EP0_STATE_INIT; ep0SubState=0; } break; case EP0_CONFIG_SET: WrPktEp0((U8 *)&ConfigSet+0,1); SET_EP0_INPKTRDY_DATAEND(); ep0State=EP0_STATE_INIT; break; case EP0_GET_STATUS0: WrPktEp0((U8 *)&StatusGet+0,1); SET_EP0_INPKTRDY_DATAEND(); ep0State=EP0_STATE_INIT; break; case EP0_GET_STATUS1: WrPktEp0((U8 *)&StatusGet+1,1); SET_EP0_INPKTRDY_DATAEND(); ep0State=EP0_STATE_INIT; break; case EP0_GET_STATUS2: WrPktEp0((U8 *)&StatusGet+2,1); SET_EP0_INPKTRDY_DATAEND(); ep0State=EP0_STATE_INIT; break; case EP0_GET_STATUS3: WrPktEp0((U8 *)&StatusGet+3,1); SET_EP0_INPKTRDY_DATAEND(); ep0State=EP0_STATE_INIT; break; case EP0_GET_STATUS4: WrPktEp0((U8 *)&StatusGet+4,1); SET_EP0_INPKTRDY_DATAEND(); ep0State=EP0_STATE_INIT; break; default: // DbgPrintf("UE:G?D"); break; } }