📄 udc_ahb.c.orig
字号:
/******************************************************************************************************************* * Endpoint QUEUES * * Endpoint IN_0 * * +-+-+ * |H|T|---------------------------------------+ * +-+-+ | * | 32 bit 32 bit V 32 bit * -----> +-------+ +-> +-------+ +-> .... +-> +-------+ +--> NULL * | . | | | . | | | . | | * | . | | | . | | | . | | * +-------+ | +-------+ | +-------+ | * | Next |--+ | Next |--+ | Next |---+ * +-------+ +-------+ +-------+ * / DATA / / DATA / / DATA / * +-------+ +-------+ +-------+ * * * *******************************************************************************************************************/static DmaUsbBulkDescr *USBDMA_DescrEptHead[7] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};static DmaUsbBulkDescr *USBDMA_DescrEptTail[7] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};/* * Init the freelist of DMA descriptors. * Since we must know how big a USB max packet size is before calling this routine, it * is called when 'device enumeration complete' interrupt is received. */static voidUSB_InitDescrFreeList(){ DmaUsbBulkDescr *startp; int i; /* (TBD!!!!!) descriptor must be 16-byte aligned and non-cacheable area (0x18000000) */ startp = (DmaUsbBulkDescr *)(0x08000000 + (((int)DmaUsbBulkDescrArray + sizeof(DmaUsbBulkDescr) - 1) & 0xfffffff0)); for (i = 0; i < TOT_NUM_OF_DESCRIPTORS; i++) { if (i < TOT_NUM_OF_DESCRIPTORS - 1) startp[i].DmaUsb_Next = &(startp[i + 1]); else startp[i].DmaUsb_Next = 0x0; // (TBD!!!!!) startp[i].DmaUsb_Addr = (0x08000000 + ((int)USB_BufferList[i] + USB_BUFFER_SIZE - 1) & ~(USB_BUFFER_SIZE - 1) ); startp[i].DmaUsb_Status = DmaUsb_HostRdy; startp[i].DmaUsb_Reserved = 0xf0cacc1a; } USBDMA_DescrFreeList = startp;}/* * Returns a pointer to a list of 'num' free DMA descriptors. * If the number of items in freelist is less than the number requested then * NULL is returned. */void *USB_GetDescrFromFreeList(unsigned short num){ DmaUsbBulkDescr *frstp; DmaUsbBulkDescr *lastp; DmaUsbBulkDescr *freep; int i; intctlIntDisable(ITC_USBD_int); // Disable interrupts frstp = USBDMA_DescrFreeList; lastp = USBDMA_DescrFreeList; freep = USBDMA_DescrFreeList; for (i = 0; i < num; i++) { if ((lastp = freep) == 0x0) { /* less than 'num' items in freelist */ intctlIntEnable(ITC_USBD_int); // Enable interrupts return 0x0; } /* init the descriptor */ //freep->DmaUsb_Status = 0x0; //freep->DmaUsb_Reserved = 0x0; freep = freep->DmaUsb_Next; } /* * Init last item in chain to be returned. * The last item is marked as 'DMA last descriptor', so the DMA * will generate an interrupt when the chain is done even if the * USB transfer is not completed yet. */ lastp->DmaUsb_Next = 0x0; lastp->DmaUsb_Status = DmaUsb_LastDescr; USBDMA_DescrFreeList = freep; intctlIntEnable(ITC_USBD_int); // Enable interrupts return((void *)frstp);}/* * Put DMA descriptors into freelist. */intUSB_PutDescrIntoFreeList(DmaUsbBulkDescr *descp){ DmaUsbBulkDescr *freep = 0x0; DmaUsbBulkDescr *lastp = 0x0; intctlIntDisable(ITC_USBD_int); // Disable interrupts // finds the end of the chain. for (freep = descp; freep != 0x0; lastp = freep, freep = freep->DmaUsb_Next) freep->DmaUsb_Status = 0x0; lastp->DmaUsb_Next = USBDMA_DescrFreeList; USBDMA_DescrFreeList = descp; intctlIntEnable(ITC_USBD_int); // Enable interrupts return(0x0);}/* * Put descriptors chain into done queue for specified endpoint. */static intUSB_PutDescrIntoEpt(unsigned short endpt, DmaUsbBulkDescr *descp){ unsigned short numpck = 0; unsigned short DONE_List = 0; // Check argument if (endpt > MAX_NUM_OF_ENDPOINTS) return 0x0; intctlIntDisable(ITC_USBD_int); // Disable interrupts // Set DONE ptrs. if (USBDMA_DescrEptHead[endpt] == 0x0) USBDMA_DescrEptHead[endpt] = USBDMA_DescrEptTail[endpt] = descp; // First item else USBDMA_DescrEptTail[endpt]->DmaUsb_Next = descp; // Not first item // Set new tail pointer while (descp != 0x0 && DONE_List == 0) { numpck++; /* * If this is called after DMA completed (in IRQ handler routine) * then each descriptor must be adjusted to reflect the real size * of the buffer. */ if (descp->DmaUsb_Status & DmaUsb_DmaBsy) descp->DmaUsb_Status = DmaUsbMaxPacketSize; else if (descp->DmaUsb_Status & DmaUsb_DmaDone) { if (descp->DmaUsb_Status & DmaUsb_LastDescr) { descp->DmaUsb_Status = (descp->DmaUsb_Status & DmaUsb_Len_Mask) - ((numpck - 1) * DmaUsbMaxPacketSize); DONE_List = 1; } else descp->DmaUsb_Status = (descp->DmaUsb_Status & DmaUsb_Len_Mask); } else { // Should never get here! } USBDMA_DescrEptTail[endpt] = descp; descp = descp->DmaUsb_Next; } intctlIntEnable(ITC_USBD_int); // Enable interrupts /* Free possible remaining descriptors in list */ if (descp != 0x0) { USB_PutDescrIntoFreeList(descp); USBDMA_DescrEptTail[endpt]->DmaUsb_Next = 0x0; } return(0x0);}/* * GET descriptors chain from IN queue for specified endpoint. */static void *USB_GetDescrFromEpt(unsigned short endpt, unsigned short num){ DmaUsbBulkDescr *frstp; DmaUsbBulkDescr *lastp; DmaUsbBulkDescr *freep; int i; // Check argument if (endpt > MAX_NUM_OF_ENDPOINTS) return 0x0; intctlIntDisable(ITC_USBD_int); // Disable interrupts frstp = USBDMA_DescrEptHead[endpt]; lastp = USBDMA_DescrEptHead[endpt]; freep = USBDMA_DescrEptHead[endpt]; for (i = 0; i < num; i++) { if (freep == 0x0) { USBDMA_DescrEptTail[endpt] = 0x0; break; } freep->DmaUsb_Status &= DmaUsb_Len_Mask; lastp = freep; freep = freep->DmaUsb_Next; } // init last item in chain to be returned. if (lastp) { lastp->DmaUsb_Next = 0x0; lastp->DmaUsb_Status |= DmaUsb_LastDescr; } if (freep == 0x0) USBDMA_DescrEptTail[endpt] = 0x0; USBDMA_DescrEptHead[endpt] = freep; intctlIntEnable(ITC_USBD_int); // Enable interrupts return((void *)frstp);}/* * PUT descriptors chain into IN queue for specified endpoint. */static intUSB_PutBufToEpt(unsigned short endpt, char *bufp, unsigned int size){ DmaUsbBulkDescr *BulkIN_TMP; // Check argument if (endpt > MAX_NUM_OF_ENDPOINTS) return 0x0; BulkIN_TMP = USB_GetDescrFromFreeList(1); BulkIN_TMP->DmaUsb_Addr = bufp; // (TBD) ??? BulkIN_TMP->DmaUsb_Next = 0x0; BulkIN_TMP->DmaUsb_Status = DmaUsb_HostRdy | size; intctlIntDisable(ITC_USBD_int); // Disable interrupts /* Put the item in queue as last element */ if (USBDMA_DescrEptHead[endpt] == 0x0) USBDMA_DescrEptHead[endpt] = USBDMA_DescrEptTail[endpt] = BulkIN_TMP; // First item else { USBDMA_DescrEptTail[endpt]->DmaUsb_Next = BulkIN_TMP; USBDMA_DescrEptTail[endpt] = BulkIN_TMP; } intctlIntEnable(ITC_USBD_int); // Enable interrupts return(0x0);}#ifndef _USB_DMA/******************************************************************* * SLAVE MODE :: * Routines to acces RX/TX FIFOs directly. *******************************************************************/static voidUsbPutPckToFIFO(int epNum, DmaUsbBulkDescr *descp){ unsigned short i, nw, nb; unsigned int txf_base = 0; unsigned int *wrdp; unsigned char *bytp; char *data = descp->DmaUsb_Addr; int len = descp->DmaUsb_Status & DmaUsb_Len_Mask; switch(epNum) { case 0 : default: txf_base = 0; break; case 2: // txf_base += *VUINTP (Endp_BSorFN + In_Endp2); txf_base += USB_EP1_IN_BUSIZE; /* go through next case */ case 1: // txf_base += *VUINTP (Endp_BSorFN + In_Endp1); txf_base += USB_EP0__IN_BUSIZE; break; } nw = len / sizeof(int); nb = len % sizeof(int); wrdp = (unsigned int *)data; for (i = 0; i < nw; i++) { *VUINTP (USB_TX_FIFO + txf_base) = *wrdp++; } bytp = (unsigned char *)wrdp; for (i = 0; i < nb; i++) { *(volatile unsigned char *) (USB_TX_FIFO + txf_base) = *bytp++; } switch(epNum) { case 0 : default: *VUINTP USB_TX_FIFO_0_DONE = 0x0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -