From 4af26e7e98b6d4b2e1c94a54ad7ca02d55bb04cc Mon Sep 17 00:00:00 2001 From: Maurus Cuelenaere Date: Wed, 5 Nov 2008 00:24:46 +0000 Subject: Onda VX747: * Commit (premature) SD, USB & audio drivers * Fix ramdisk.c mistake * Add battery readout git-svn-id: svn://svn.rockbox.org/rockbox/trunk@19011 a1c6a512-1295-4272-9138-f99709370657 --- firmware/target/mips/ingenic_jz47xx/usb-jz4740.c | 1635 +++++++++++++--------- 1 file changed, 988 insertions(+), 647 deletions(-) (limited to 'firmware/target/mips/ingenic_jz47xx/usb-jz4740.c') diff --git a/firmware/target/mips/ingenic_jz47xx/usb-jz4740.c b/firmware/target/mips/ingenic_jz47xx/usb-jz4740.c index 2121d3e4b0..7cefdadbe3 100644 --- a/firmware/target/mips/ingenic_jz47xx/usb-jz4740.c +++ b/firmware/target/mips/ingenic_jz47xx/usb-jz4740.c @@ -20,6 +20,7 @@ ****************************************************************************/ #include "config.h" +#include "string.h" #include "system.h" #include "usb_ch9.h" #include "usb_drv.h" @@ -27,7 +28,7 @@ #include "jz4740.h" #include "thread.h" -#if 0 +#if 1 #define EP1_INTR_BIT 2 #define EP_FIFO_NOEMPTY 2 @@ -38,14 +39,327 @@ #define IS_CACHE(x) (x < 0xa0000000) +#define USB_EP0_IDLE 0 +#define USB_EP0_RX 1 +#define USB_EP0_TX 2 + +enum ep_type +{ + ep_control, ep_bulk, ep_interrupt +}; + +struct usb_endpoint +{ + void *buf; + unsigned int length; + void *ptr; + + const enum ep_type type; + const bool use_dma; + const bool in; + + const void *fifo_addr; + unsigned short fifo_size; +}; + +static unsigned char ep0_rx_buf[64]; +static unsigned char ep0_tx_buf[64]; +static unsigned char ep0state = USB_EP0_IDLE; +static struct usb_endpoint endpoints[] = +{ + /* buf length ptr type use_dma in fifo_addr fifo_size */ + {&ep0_rx_buf, 0, &ep0_rx_buf, ep_control, false, true, (void*)USB_FIFO_EP0, 64 }, + {&ep0_tx_buf, 0, &ep0_tx_buf, ep_control, false, false, (void*)USB_FIFO_EP0, 64 }, + {NULL, 0, NULL, ep_bulk, true, true, (void*)USB_FIFO_EP1, 512}, + {NULL, 0, NULL, ep_bulk, true, false, (void*)USB_FIFO_EP1, 512}, + {NULL, 0, NULL, ep_interrupt, false, true, (void*)USB_FIFO_EP2, 64 } +}; + +static inline void select_endpoint(int ep) +{ + REG_USB_REG_INDEX = ep; +} + +static void readFIFO(struct usb_endpoint *ep, unsigned int size) +{ + unsigned int *d = (unsigned int *)ep->ptr; + unsigned int s; + s = (size + 3) >> 2; + while (s--) + *d++ = REG32(ep->fifo_addr); +} + +static void writeFIFO(struct usb_endpoint *ep, unsigned int size) +{ + unsigned int *d = (unsigned int *)ep->ptr; + unsigned char *c; + int s, q; + + if (size > 0) + { + s = size >> 2; + while (s--) + REG32(ep->fifo_addr) = *d++; + + q = size & 3; + if (q) + { + c = (unsigned char *)d; + while (q--) + REG8(ep->fifo_addr) = *c++; + } + } +} + +static void sendPKT(int ep_nr, const unsigned char* ptr, unsigned int size) +{ + struct usb_endpoint *ep = &endpoints[ep_nr]; + + if (ep_nr != 0) + { + ep->buf = (void*)ptr; + ep->ptr = (void*)ptr; + ep->length = size; + select_endpoint(ep_nr); + if (size <= ep->fifo_size) + { + writeFIFO(ep, size); + REG_USB_REG_INCSR |= USB_INCSR_INPKTRDY; + ep->ptr = ep->buf + size; + } + else + { + writeFIFO(ep, ep->fifo_size); + REG_USB_REG_INCSR |= USB_INCSR_INPKTRDY; + ep->ptr += ep->fifo_size; + } + } + else /* EP0 */ + { + ep->length = size; + ep->ptr = ep->buf; + memcpy(ep->buf, ptr, size); + ep0state = USB_EP0_TX; + } +} + +static void getPKT(int ep_nr, const unsigned char *ptr, unsigned int size) +{ + struct usb_endpoint *ep = &endpoints[ep_nr]; + + memcpy((void*)ptr, ep->ptr, size); + if (ep->length > size) + ep->length -= size; + else + { + size = ep->length; + ep->length = 0; + } + + ep->ptr += size; +} + +static void EP0_handler(void) +{ + unsigned char csr0; + + /* Read CSR0 */ + select_endpoint(0); + csr0 = REG_USB_REG_CSR0; + + /* Check for SentStall + if sentstall is set, clear the sentstall bit + */ + if (csr0 & USB_CSR0_SENTSTALL) + { + REG_USB_REG_CSR0 = csr0 & ~USB_CSR0_SENTSTALL; + ep0state = USB_EP0_IDLE; + return; + } + + /* Check for SetupEnd */ + if (csr0 & USB_CSR0_SETUPEND) + { + REG_USB_REG_CSR0 |= USB_CSR0_SVDSETUPEND; + ep0state = USB_EP0_IDLE; + return; + } + + /* Call relevant routines for endpoint 0 state */ + if (ep0state == USB_EP0_IDLE) + { + if (csr0 & USB_CSR0_OUTPKTRDY) /* There is data in the fifo */ + { + readFIFO(&endpoints[0], 8); + REG_USB_REG_CSR0 |= USB_CSR0_SVDOUTPKTRDY; /* clear OUTRD bit */ + usb_core_control_request((struct usb_ctrlrequest*)endpoints[0].buf); + } + endpoints[0].length = 0; + endpoints[0].ptr = endpoints[0].buf; + } + + if (ep0state == USB_EP0_TX) + { + if ((&endpoints[1].ptr - &endpoints[1].buf) <= endpoints[1].fifo_size) + { + writeFIFO(&endpoints[1], (&endpoints[1].ptr - &endpoints[1].buf)); + endpoints[1].ptr = &endpoints[1].buf + endpoints[1].length; + REG_USB_REG_CSR0 |= (USB_CSR0_INPKTRDY | USB_CSR0_DATAEND); /* Set data end! */ + ep0state = USB_EP0_IDLE; + } + else + { + writeFIFO(&endpoints[1], endpoints[1].fifo_size); + REG_USB_REG_CSR0 |= USB_CSR0_INPKTRDY; + endpoints[1].ptr += endpoints[1].fifo_size; + } + } +} + +static void setup_endpoint(struct usb_endpoint *ep) +{ + ep->ptr = ep->buf; + ep->length = 0; + + if(ep->in) + { + if(ep->type == ep_bulk) + { + register int size; + + if((REG_USB_REG_POWER & USB_POWER_HSMODE) == 0) + size = 64; + else + size = 512; + + REG_USB_REG_INMAXP = size; + ep->fifo_size = size; + } + else + REG_USB_REG_INMAXP = ep->fifo_size; + + REG_USB_REG_INCSR = 0x2048; + } + else + { + REG_USB_REG_OUTMAXP = ep->fifo_size; + REG_USB_REG_OUTCSR = 0x0090; + } +} + +static void udc_reset(void) +{ + register int i; + + /* data init */ + ep0state = USB_EP0_IDLE; + + /* Disable interrupts */ + REG_USB_REG_INTRINE = 0; + REG_USB_REG_INTROUTE = 0; + REG_USB_REG_INTRUSBE = 0; + + REG_USB_REG_FADDR = 0; + REG_USB_REG_POWER = 0x60; /* High speed */ + + select_endpoint(0); + REG_USB_REG_CSR0 = 0xC0; + + for(i=1; i<3; i++) + { + select_endpoint(i); + setup_endpoint(&endpoints[i]); + } + + /* enable intr */ + REG_USB_REG_INTRINE = 0x3; + REG_USB_REG_INTROUTE = 0x2; + REG_USB_REG_INTRUSBE = 0x4; +} + +/* Interrupt handler */ +void UDC(void) +{ + /* Read interrupt registers */ + unsigned char intrUSB = REG_USB_REG_INTRUSB & 0x07; /* Mask SOF */ + unsigned short intrIn = REG_USB_REG_INTRIN; + unsigned short intrOut = REG_USB_REG_INTROUT; + unsigned char intrDMA = REG_USB_REG_INTR; + + if(intrUSB == 0 && intrIn == 0 && intrOut == 0 && intrDMA == 0) + return; + + /* EPIN & EPOUT are all handled in DMA */ + if(intrIn & USB_INTR_EP0) + EP0_handler(); + if(intrUSB & USB_INTR_RESET) + udc_reset(); + if(intrUSB & USB_INTR_SUSPEND); + if(intrUSB & USB_INTR_RESUME); + if(intrDMA & USB_INTR_DMA_BULKIN) + { + usb_core_transfer_complete(((REG_USB_REG_CNTL1 >> 4) & 0xF) | USB_DIR_IN, USB_DIR_IN, 0, 0); + } + if(intrDMA & USB_INTR_DMA_BULKOUT) + { + usb_core_transfer_complete(((REG_USB_REG_CNTL2 >> 4) & 0xF) | USB_DIR_OUT, USB_DIR_OUT, 0, 0); + } +} + +bool usb_drv_stalled(int endpoint, bool in) +{ + select_endpoint(endpoint); + + if(endpoint == 0) + return (REG_USB_REG_CSR0 & USB_CSR0_SENDSTALL) != 0; + else + { + if(in) + return (REG_USB_REG_INCSR & USB_INCSR_SENDSTALL) != 0; + else + return (REG_USB_REG_OUTCSR & USB_OUTCSR_SENDSTALL) != 0; + } +} + +void usb_drv_stall(int endpoint, bool stall, bool in) +{ + select_endpoint(endpoint); + + if(endpoint == 0) + { + if(stall) + REG_USB_REG_CSR0 |= USB_CSR0_SENDSTALL; + else + REG_USB_REG_CSR0 &= ~USB_CSR0_SENDSTALL; + } + else + { + if(in) + { + if(stall) + REG_USB_REG_INCSR |= USB_INCSR_SENDSTALL; + else + REG_USB_REG_INCSR &= ~USB_INCSR_SENDSTALL; + } + else + { + if(stall) + REG_USB_REG_OUTCSR |= USB_OUTCSR_SENDSTALL; + else + REG_USB_REG_OUTCSR &= ~USB_OUTCSR_SENDSTALL; + } + } +} + + bool usb_drv_connected(void) { - return (__gpio_get_pin(GPIO_UDC_DETE)==1); + return __gpio_get_pin(GPIO_UDC_DETE) == 1; } int usb_detect(void) { - if(__gpio_get_pin(GPIO_UDC_DETE)==1) + if(__gpio_get_pin(GPIO_UDC_DETE) == 1) return USB_INSERTED; else return USB_EXTRACTED; @@ -68,49 +382,51 @@ void usb_enable(bool on) void usb_drv_init(void) { - /* Set this bit to allow the UDC entering low-power mode when - * there are no actions on the USB bus. - * UDC still works during this bit was set. - */ - //__cpm_stop_udc(); + /* Set this bit to allow the UDC entering low-power mode when + * there are no actions on the USB bus. + * UDC still works during this bit was set. + */ + //__cpm_stop_udc(); __cpm_start_udc(); - /* Enable the USB PHY */ - REG_CPM_SCR |= CPM_SCR_USBPHY_ENABLE; + /* Enable the USB PHY */ + REG_CPM_SCR |= CPM_SCR_USBPHY_ENABLE; - /* Disable interrupts */ - REG_USB_REG_INTRINE = 0; - REG_USB_REG_INTROUTE = 0; - REG_USB_REG_INTRUSBE = 0; + /* Disable interrupts */ + REG_USB_REG_INTRINE = 0; + REG_USB_REG_INTROUTE = 0; + REG_USB_REG_INTRUSBE = 0; - /* Enable interrupts */ - REG_USB_REG_INTRINE |= USB_INTR_EP0; - REG_USB_REG_INTRUSBE |= USB_INTR_RESET; + /* Enable interrupts */ + REG_USB_REG_INTRINE |= USB_INTR_EP0; + REG_USB_REG_INTRUSBE |= USB_INTR_RESET; - /* Enable SUSPEND */ - /* usb_setb(USB_REG_POWER, USB_POWER_SUSPENDM); */ + /* Enable SUSPEND */ + /* usb_setb(USB_REG_POWER, USB_POWER_SUSPENDM); */ - /* Enable HS Mode */ + /* Enable HS Mode */ REG_USB_REG_POWER |= USB_POWER_HSENAB; - /* Let host detect UDC: - * Software must write a 1 to the PMR:USB_POWER_SOFTCONN bit to turn this - * transistor on and pull the USBDP pin HIGH. - */ - REG_USB_REG_POWER |= USB_POWER_SOFTCONN; + /* Let host detect UDC: + * Software must write a 1 to the PMR:USB_POWER_SOFTCONN bit to turn this + * transistor on and pull the USBDP pin HIGH. + */ + REG_USB_REG_POWER |= USB_POWER_SOFTCONN; + + udc_reset(); } void usb_drv_exit(void) { - /* Disable interrupts */ - REG_USB_REG_INTRINE = 0; - REG_USB_REG_INTROUTE = 0; - REG_USB_REG_INTRUSBE = 0; - - /* Disable DMA */ - REG_USB_REG_CNTL1 = 0; - REG_USB_REG_CNTL2 = 0; + /* Disable interrupts */ + REG_USB_REG_INTRINE = 0; + REG_USB_REG_INTROUTE = 0; + REG_USB_REG_INTRUSBE = 0; + + /* Disable DMA */ + REG_USB_REG_CNTL1 = 0; + REG_USB_REG_CNTL2 = 0; /* Disconnect from usb */ REG_USB_REG_POWER &= ~USB_POWER_SOFTCONN; @@ -126,253 +442,248 @@ void usb_drv_set_address(int address) REG_USB_REG_FADDR = address; } -/* Interrupt handler */ -void UDC(void) -{ - -} #else //------------------------------------------ #ifndef u8 -#define u8 unsigned char +#define u8 unsigned char #endif #ifndef u16 -#define u16 unsigned short +#define u16 unsigned short #endif #ifndef u32 -#define u32 unsigned int +#define u32 unsigned int #endif #ifndef s8 -#define s8 char +#define s8 char #endif #ifndef s16 -#define s16 short +#define s16 short #endif #ifndef s32 -#define s32 int +#define s32 int #endif extern int usbdebug; enum USB_ENDPOINT_TYPE { - ENDPOINT_TYPE_CONTROL, - /* Typically used to configure a device when attached to the host. - * It may also be used for other device specific purposes, including - * control of other pipes on the device. - */ - ENDPOINT_TYPE_ISOCHRONOUS, - /* Typically used for applications which need guaranteed speed. - * Isochronous transfer is fast but with possible data loss. A typical - * use is audio data which requires a constant data rate. - */ - ENDPOINT_TYPE_BULK, - /* Typically used by devices that generate or consume data in relatively - * large and bursty quantities. Bulk transfer has wide dynamic latitude - * in transmission constraints. It can use all remaining available bandwidth, - * but with no guarantees on bandwidth or latency. Since the USB bus is - * normally not very busy, there is typically 90% or more of the bandwidth - * available for USB transfers. - */ - ENDPOINT_TYPE_INTERRUPT - /* Typically used by devices that need guaranteed quick responses - * (bounded latency). - */ + ENDPOINT_TYPE_CONTROL, + /* Typically used to configure a device when attached to the host. + * It may also be used for other device specific purposes, including + * control of other pipes on the device. + */ + ENDPOINT_TYPE_ISOCHRONOUS, + /* Typically used for applications which need guaranteed speed. + * Isochronous transfer is fast but with possible data loss. A typical + * use is audio data which requires a constant data rate. + */ + ENDPOINT_TYPE_BULK, + /* Typically used by devices that generate or consume data in relatively + * large and bursty quantities. Bulk transfer has wide dynamic latitude + * in transmission constraints. It can use all remaining available bandwidth, + * but with no guarantees on bandwidth or latency. Since the USB bus is + * normally not very busy, there is typically 90% or more of the bandwidth + * available for USB transfers. + */ + ENDPOINT_TYPE_INTERRUPT + /* Typically used by devices that need guaranteed quick responses + * (bounded latency). + */ }; enum USB_STANDARD_REQUEST_CODE { - GET_STATUS, - CLEAR_FEATURE, - SET_FEATURE = 3, - SET_ADDRESS = 5, - GET_DESCRIPTOR, - SET_DESCRIPTOR, - GET_CONFIGURATION, - SET_CONFIGURATION, - GET_INTERFACE, - SET_INTERFACE, - SYNCH_FRAME + GET_STATUS, + CLEAR_FEATURE, + SET_FEATURE = 3, + SET_ADDRESS = 5, + GET_DESCRIPTOR, + SET_DESCRIPTOR, + GET_CONFIGURATION, + SET_CONFIGURATION, + GET_INTERFACE, + SET_INTERFACE, + SYNCH_FRAME }; enum USB_DESCRIPTOR_TYPE { - DEVICE_DESCRIPTOR = 1, - CONFIGURATION_DESCRIPTOR, - STRING_DESCRIPTOR, - INTERFACE_DESCRIPTOR, - ENDPOINT_DESCRIPTOR, - DEVICE_QUALIFIER_DESCRIPTOR, - OTHER_SPEED_CONFIGURATION_DESCRIPTOR, - INTERFACE_POWER1_DESCRIPTOR + DEVICE_DESCRIPTOR = 1, + CONFIGURATION_DESCRIPTOR, + STRING_DESCRIPTOR, + INTERFACE_DESCRIPTOR, + ENDPOINT_DESCRIPTOR, + DEVICE_QUALIFIER_DESCRIPTOR, + OTHER_SPEED_CONFIGURATION_DESCRIPTOR, + INTERFACE_POWER1_DESCRIPTOR }; enum USB_FEATURE_SELECTOR { - ENDPOINT_HALT, - DEVICE_REMOTE_WAKEUP, - TEST_MODE + ENDPOINT_HALT, + DEVICE_REMOTE_WAKEUP, + TEST_MODE }; enum USB_CLASS_CODE { - CLASS_DEVICE, - CLASS_AUDIO, - CLASS_COMM_AND_CDC_CONTROL, - CLASS_HID, - CLASS_PHYSICAL = 0x05, - CLASS_STILL_IMAGING, - CLASS_PRINTER, - CLASS_MASS_STORAGE, - CLASS_HUB, - CLASS_CDC_DATA, - CLASS_SMART_CARD, - CLASS_CONTENT_SECURITY = 0x0d, - CLASS_VIDEO, - CLASS_DIAGNOSTIC_DEVICE = 0xdc, - CLASS_WIRELESS_CONTROLLER = 0xe0, - CLASS_MISCELLANEOUS = 0xef, - CLASS_APP_SPECIFIC = 0xfe, - CLASS_VENDOR_SPECIFIC = 0xff + CLASS_DEVICE, + CLASS_AUDIO, + CLASS_COMM_AND_CDC_CONTROL, + CLASS_HID, + CLASS_PHYSICAL = 0x05, + CLASS_STILL_IMAGING, + CLASS_PRINTER, + CLASS_MASS_STORAGE, + CLASS_HUB, + CLASS_CDC_DATA, + CLASS_SMART_CARD, + CLASS_CONTENT_SECURITY = 0x0d, + CLASS_VIDEO, + CLASS_DIAGNOSTIC_DEVICE = 0xdc, + CLASS_WIRELESS_CONTROLLER = 0xe0, + CLASS_MISCELLANEOUS = 0xef, + CLASS_APP_SPECIFIC = 0xfe, + CLASS_VENDOR_SPECIFIC = 0xff }; typedef struct { - u8 bmRequestType; - u8 bRequest; - u16 wValue; - u16 wIndex; - u16 wLength; + u8 bmRequestType; + u8 bRequest; + u16 wValue; + u16 wIndex; + u16 wLength; } __attribute__ ((packed)) USB_DeviceRequest; typedef struct { - u8 bLength; - u8 bDescriptorType; - u16 bcdUSB; - u8 bDeviceClass; - u8 bDeviceSubClass; - u8 bDeviceProtocol; - u8 bMaxPacketSize0; - u16 idVendor; - u16 idProduct; - u16 bcdDevice; - u8 iManufacturer; - u8 iProduct; - u8 iSerialNumber; - u8 bNumConfigurations; + u8 bLength; + u8 bDescriptorType; + u16 bcdUSB; + u8 bDeviceClass; + u8 bDeviceSubClass; + u8 bDeviceProtocol; + u8 bMaxPacketSize0; + u16 idVendor; + u16 idProduct; + u16 bcdDevice; + u8 iManufacturer; + u8 iProduct; + u8 iSerialNumber; + u8 bNumConfigurations; } __attribute__ ((packed)) USB_DeviceDescriptor; typedef struct { - u8 bLength; - u8 bDescriptorType; - u16 bcdUSB; - u8 bDeviceClass; - u8 bDeviceSubClass; - u8 bDeviceProtocol; - u8 bMaxPacketSize0; - u8 bNumConfigurations; - u8 bReserved; + u8 bLength; + u8 bDescriptorType; + u16 bcdUSB; + u8 bDeviceClass; + u8 bDeviceSubClass; + u8 bDeviceProtocol; + u8 bMaxPacketSize0; + u8 bNumConfigurations; + u8 bReserved; } __attribute__ ((packed)) USB_DeviceQualifierDescriptor; typedef struct { - u8 bLength; - u8 bDescriptorType; - u16 wTotalLength; - u8 bNumInterfaces; - u8 bConfigurationValue; - u8 iConfiguration; - u8 bmAttributes; - u8 MaxPower; + u8 bLength; + u8 bDescriptorType; + u16 wTotalLength; + u8 bNumInterfaces; + u8 bConfigurationValue; + u8 iConfiguration; + u8 bmAttributes; + u8 MaxPower; } __attribute__ ((packed)) USB_ConfigDescriptor; typedef struct { - u8 bLength; - u8 bDescriptorType; - u16 wTotalLength; - u8 bNumInterfaces; - u8 bConfigurationValue; - u8 iConfiguration; - u8 bmAttributes; - u8 bMaxPower; + u8 bLength; + u8 bDescriptorType; + u16 wTotalLength; + u8 bNumInterfaces; + u8 bConfigurationValue; + u8 iConfiguration; + u8 bmAttributes; + u8 bMaxPower; } __attribute__ ((packed)) USB_OtherSpeedConfigDescriptor; typedef struct { - u8 bLength; - u8 bDescriptorType; - u8 bInterfaceNumber; - u8 bAlternateSetting; - u8 bNumEndpoints; - u8 bInterfaceClass; - u8 bInterfaceSubClass; - u8 bInterfaceProtocol; - u8 iInterface; + u8 bLength; + u8 bDescriptorType; + u8 bInterfaceNumber; + u8 bAlternateSetting; + u8 bNumEndpoints; + u8 bInterfaceClass; + u8 bInterfaceSubClass; + u8 bInterfaceProtocol; + u8 iInterface; } __attribute__ ((packed)) USB_InterfaceDescriptor; typedef struct { - u8 bLegth; - u8 bDescriptorType; - u8 bEndpointAddress; - u8 bmAttributes; - u16 wMaxPacketSize; - u8 bInterval; + u8 bLegth; + u8 bDescriptorType; + u8 bEndpointAddress; + u8 bmAttributes; + u16 wMaxPacketSize; + u8 bInterval; } __attribute__ ((packed)) USB_EndPointDescriptor; typedef struct { - u8 bLength; - u8 bDescriptorType; - u16 SomeDesriptor[1]; + u8 bLength; + u8 bDescriptorType; + u16 SomeDesriptor[1]; } __attribute__ ((packed)) USB_StringDescriptor; //------------------------------------------ -#define MAX_EP0_SIZE 64 -#define MAX_EP1_SIZE 512 +#define MAX_EP0_SIZE 64 +#define MAX_EP1_SIZE 512 #define USB_HS 0 #define USB_FS 1 #define USB_LS 2 //definitions of EP0 -#define USB_EP0_IDLE 0 -#define USB_EP0_RX 1 -#define USB_EP0_TX 2 +#define USB_EP0_IDLE 0 +#define USB_EP0_RX 1 +#define USB_EP0_TX 2 /* Define maximum packet size for endpoint 0 */ -#define M_EP0_MAXP 64 +#define M_EP0_MAXP 64 /* Endpoint 0 status structure */ static __inline__ void usb_setb(u32 port, u8 val) { - volatile u8 *ioport = (volatile u8 *)(port); - *ioport = (*ioport) | val; + volatile u8 *ioport = (volatile u8 *)(port); + *ioport = (*ioport) | val; } static __inline__ void usb_clearb(u32 port, u8 val) { - volatile u8 *ioport = (volatile u8 *)(port); - *ioport = (*ioport) & ~val; + volatile u8 *ioport = (volatile u8 *)(port); + *ioport = (*ioport) & ~val; } static __inline__ void usb_setw(u32 port, u16 val) { - volatile u16 *ioport = (volatile u16 *)(port); - *ioport = (*ioport) | val; + volatile u16 *ioport = (volatile u16 *)(port); + *ioport = (*ioport) | val; } static __inline__ void usb_clearw(u32 port, u16 val) { - volatile u16 *ioport = (volatile u16 *)(port); - *ioport = (*ioport) & ~val; + volatile u16 *ioport = (volatile u16 *)(port); + *ioport = (*ioport) & ~val; } //--------------------------------- #define BULK_OUT_BUF_SIZE 0x20000 //buffer size : @@ -380,118 +691,118 @@ static __inline__ void usb_clearw(u32 port, u16 val) enum UDC_STATE { - IDLE, - BULK_IN, - BULK_OUT + IDLE, + BULK_IN, + BULK_OUT }; enum USB_JZ4740_REQUEST //add for USB_BOOT { - VR_GET_CUP_INFO = 0, - VR_SET_DATA_ADDERSS, - VR_SET_DATA_LENGTH, - VR_FLUSH_CACHES, - VR_PROGRAM_START1, - VR_PROGRAM_START2, - VR_NOR_OPS, - VR_NAND_OPS, - VR_SDRAM_OPS, - VR_CONFIGRATION + VR_GET_CUP_INFO = 0, + VR_SET_DATA_ADDERSS, + VR_SET_DATA_LENGTH, + VR_FLUSH_CACHES, + VR_PROGRAM_START1, + VR_PROGRAM_START2, + VR_NOR_OPS, + VR_NAND_OPS, + VR_SDRAM_OPS, + VR_CONFIGRATION }; enum NOR_OPS_TYPE { - NOR_INIT = 0, - NOR_QUERY, - NOR_WRITE, - NOR_ERASE_CHIP, - NOR_ERASE_SECTOR + NOR_INIT = 0, + NOR_QUERY, + NOR_WRITE, + NOR_ERASE_CHIP, + NOR_ERASE_SECTOR }; enum NOR_FLASH_TYPE { - NOR_AM29 = 0, - NOR_SST28, - NOR_SST39x16, - NOR_SST39x8 + NOR_AM29 = 0, + NOR_SST28, + NOR_SST39x16, + NOR_SST39x8 }; enum NAND_OPS_TYPE { - NAND_QUERY = 0, - NAND_INIT, - NAND_MARK_BAD, - NAND_READ_OOB, - NAND_READ_RAW, - NAND_ERASE, - NAND_READ, - NAND_PROGRAM, - NAND_READ_TO_RAM + NAND_QUERY = 0, + NAND_INIT, + NAND_MARK_BAD, + NAND_READ_OOB, + NAND_READ_RAW, + NAND_ERASE, + NAND_READ, + NAND_PROGRAM, + NAND_READ_TO_RAM }; enum SDRAM_OPS_TYPE { - SDRAM_LOAD, + SDRAM_LOAD, }; enum DATA_STRUCTURE_OB { - DS_flash_info , - DS_hand + DS_flash_info , + DS_hand }; /*typedef enum _USB_BOOT_STATUS { - USB_NO_ERR =0 , - GET_CPU_INFO_ERR, - SET_DATA_ADDRESS_ERR, - SET_DATA_LENGTH_ERR, - FLUSH_CAHCES_ERR, - PROGRAM_START1_ERR, - PROGRAM_START2_ERR, - NOR_OPS_ERR, - NAND_OPS_ERR, - NOR_FLASHTYPE_ERR, - OPS_NOTSUPPORT_ERR + USB_NO_ERR =0 , + GET_CPU_INFO_ERR, + SET_DATA_ADDRESS_ERR, + SET_DATA_LENGTH_ERR, + FLUSH_CAHCES_ERR, + PROGRAM_START1_ERR, + PROGRAM_START2_ERR, + NOR_OPS_ERR, + NAND_OPS_ERR, + NOR_FLASHTYPE_ERR, + OPS_NOTSUPPORT_ERR }USB_BOOT_STATUS;*/ enum OPTION { - OOB_ECC, - OOB_NO_ECC, - NO_OOB, + OOB_ECC, + OOB_NO_ECC, + NO_OOB, }; //------------------------- static inline void jz_writeb(u32 address, u8 value) { - *((volatile u8 *)address) = value; + *((volatile u8 *)address) = value; } static inline void jz_writew(u32 address, u16 value) { - *((volatile u16 *)address) = value; + *((volatile u16 *)address) = value; } static inline void jz_writel(u32 address, u32 value) { - *((volatile u32 *)address) = value; + *((volatile u32 *)address) = value; } static inline u8 jz_readb(u32 address) { - return *((volatile u8 *)address); + return *((volatile u8 *)address); } static inline u16 jz_readw(u32 address) { - return *((volatile u16 *)address); + return *((volatile u16 *)address); } static inline u32 jz_readl(u32 address) { - return *((volatile u32 *)address); + return *((volatile u32 *)address); } //--------------------------- @@ -510,530 +821,560 @@ static u8 ep0state,USB_Version; static u32 fifoaddr[] = { - TXFIFOEP0, TXFIFOEP0+4 ,TXFIFOEP0+8 + TXFIFOEP0, TXFIFOEP0+4 ,TXFIFOEP0+8 }; static u32 fifosize[] = { - MAX_EP0_SIZE, MAX_EP1_SIZE + MAX_EP0_SIZE, MAX_EP1_SIZE }; static void udcReadFifo(u8 *ptr, int size) { - u32 *d = (u32 *)ptr; - int s; - s = (size + 3) >> 2; - while (s--) - *d++ = REG32(fifo); + u32 *d = (u32 *)ptr; + int s; + s = (size + 3) >> 2; + while (s--) + *d++ = REG32(fifo); } static void udcWriteFifo(u8 *ptr, int size) { - u32 *d = (u32 *)ptr; - u8 *c; - int s, q; - - if (size > 0) { - s = size >> 2; - while (s--) - REG32(fifo) = *d++; - q = size & 3; - if (q) { - c = (u8 *)d; - while (q--) - REG8(fifo) = *c++; - } - } + u32 *d = (u32 *)ptr; + u8 *c; + int s, q; + + if (size > 0) { + s = size >> 2; + while (s--) + REG32(fifo) = *d++; + q = size & 3; + if (q) { + c = (u8 *)d; + while (q--) + REG8(fifo) = *c++; + } + } } void HW_SendPKT(int ep, const u8 *buf, int size) { - fifo = fifoaddr[ep]; - - if (ep!=0) - { - Bulk_in_size = size; - Bulk_in_finish = 0; - jz_writeb(USB_REG_INDEX, ep); - if (Bulk_in_size - Bulk_in_finish <= fifosize[ep]) - { - udcWriteFifo((u8 *)((u32)buf+Bulk_in_finish), - Bulk_in_size - Bulk_in_finish); - usb_setb(USB_REG_INCSR, USB_INCSR_INPKTRDY); - Bulk_in_finish = Bulk_in_size; - } + fifo = fifoaddr[ep]; + + if (ep!=0) + { + Bulk_in_size = size; + Bulk_in_finish = 0; + jz_writeb(USB_REG_INDEX, ep); + if (Bulk_in_size - Bulk_in_finish <= fifosize[ep]) + { + udcWriteFifo((u8 *)((u32)buf+Bulk_in_finish), + Bulk_in_size - Bulk_in_finish); + usb_setb(USB_REG_INCSR, USB_INCSR_INPKTRDY); + Bulk_in_finish = Bulk_in_size; + } else - { - udcWriteFifo((u8 *)((u32)buf+Bulk_in_finish), - fifosize[ep]); - usb_setb(USB_REG_INCSR, USB_INCSR_INPKTRDY); - Bulk_in_finish += fifosize[ep]; + { + udcWriteFifo((u8 *)((u32)buf+Bulk_in_finish), + fifosize[ep]); + usb_setb(USB_REG_INCSR, USB_INCSR_INPKTRDY); + Bulk_in_finish += fifosize[ep]; Bulk_in_buf = (u8*)buf; - } - } - else //EP0 - { - tx_size = size; - finished = 0; - memcpy((void *)tx_buf, buf, size); - ep0state = USB_EP0_TX; - } + } + } + else //EP0 + { + tx_size = size; + finished = 0; + memcpy((void *)tx_buf, buf, size); + ep0state = USB_EP0_TX; + } +} + +void HW_GetPKT(int ep, const u8 *buf, unsigned int size) +{ + memcpy((void *)buf, (u8 *)rx_buf, size); + fifo = fifoaddr[ep]; + if (rx_size > size) + rx_size -= size; + else + { + size = rx_size; + rx_size = 0; + } + memcpy((u8 *)rx_buf, (u8 *)((u32)rx_buf+size), rx_size); +} + +void Enable_DMA(u8* buf, u32 length) +{ + dma_cache_wback_inv((u32)buf, length); + jz_writeb(USB_REG_INDEX, 1); + usb_setw(USB_REG_INCSR, 0x9400); + usb_clearw(USB_REG_INTRINE, 0x2); //disable OUT intr + jz_writel(USB_REG_ADDR1, (u32)buf); + jz_writel(USB_REG_COUNT1, length); + jz_writel(USB_REG_CNTL1, 0x001f); } -void HW_GetPKT(int ep, const u8 *buf, int size) -{ - memcpy((void *)buf, (u8 *)rx_buf, size); - fifo = fifoaddr[ep]; - if (rx_size > size) - rx_size -= size; - else { - size = rx_size; - rx_size = 0; - } - memcpy((u8 *)rx_buf, (u8 *)((u32)rx_buf+size), rx_size); +void Disable_DMA(void) +{ + jz_writeb(USB_REG_INDEX, 1); + usb_clearw(USB_REG_INCSR, 0x9400); + usb_setw(USB_REG_INTRINE, 0x2); //Enable OUT intr } static USB_DeviceDescriptor devDesc = { - sizeof(USB_DeviceDescriptor), - DEVICE_DESCRIPTOR, //1 - 0x0200, //Version 2.0 - 0xff, //Vendor spec class - 0xff, - 0xff, - 64, /* Ep0 FIFO size */ - 0x601a, //vendor ID - 0xDEAD, //Product ID - 0xffff, - 0x00, - 0x00, - 0x00, - 0x01 + sizeof(USB_DeviceDescriptor), + DEVICE_DESCRIPTOR, //1 + 0x0200, //Version 2.0 + 0xff, //Vendor spec class + 0xff, + 0xff, + 64, /* Ep0 FIFO size */ + 0x601a, //vendor ID + 0xDEAD, //Product ID + 0xffff, + 0x00, + 0x00, + 0x00, + 0x01 }; -#define CONFIG_DESCRIPTOR_LEN (sizeof(USB_ConfigDescriptor) + \ - sizeof(USB_InterfaceDescriptor) + \ - sizeof(USB_EndPointDescriptor) * 2) +#define CONFIG_DESCRIPTOR_LEN (sizeof(USB_ConfigDescriptor) + \ + sizeof(USB_InterfaceDescriptor) + \ + sizeof(USB_EndPointDescriptor) * 2) static struct { - USB_ConfigDescriptor configuration_descriptor; - USB_InterfaceDescriptor interface_descritor; - USB_EndPointDescriptor endpoint_descriptor[2]; + USB_ConfigDescriptor configuration_descriptor; + USB_InterfaceDescriptor interface_descritor; + USB_EndPointDescriptor endpoint_descriptor[2]; } __attribute__ ((packed)) confDesc = { - { - sizeof(USB_ConfigDescriptor), - CONFIGURATION_DESCRIPTOR, - CONFIG_DESCRIPTOR_LEN, - 0x01, - 0x01, - 0x00, - 0xc0, // Self Powered, no remote wakeup - 0x64 // Maximum power consumption 2000 mA - }, - { - sizeof(USB_InterfaceDescriptor), - INTERFACE_DESCRIPTOR, - 0x00, - 0x00, - 0x02, /* ep number */ - 0xff, - 0xff, - 0xff, - 0x00 - }, - { - { - sizeof(USB_EndPointDescriptor), - ENDPOINT_DESCRIPTOR, - (1 << 7) | 1,// endpoint 2 is IN endpoint - 2, /* bulk */ - 512, - 0 - }, - { - sizeof(USB_EndPointDescriptor), - ENDPOINT_DESCRIPTOR, - (0 << 7) | 1,// endpoint 5 is OUT endpoint - 2, /* bulk */ - 512, /* OUT EP FIFO size */ - 0 - } - } + { + sizeof(USB_ConfigDescriptor), + CONFIGURATION_DESCRIPTOR, + CONFIG_DESCRIPTOR_LEN, + 0x01, + 0x01, + 0x00, + 0xc0, // Self Powered, no remote wakeup + 0x64 // Maximum power consumption 2000 mA + }, + { + sizeof(USB_InterfaceDescriptor), + INTERFACE_DESCRIPTOR, + 0x00, + 0x00, + 0x02, /* ep number */ + 0xff, + 0xff, + 0xff, + 0x00 + }, + { + { + sizeof(USB_EndPointDescriptor), + ENDPOINT_DESCRIPTOR, + (1 << 7) | 1,// endpoint 2 is IN endpoint + 2, /* bulk */ + 512, + 0 + }, + { + sizeof(USB_EndPointDescriptor), + ENDPOINT_DESCRIPTOR, + (0 << 7) | 1,// endpoint 5 is OUT endpoint + 2, /* bulk */ + 512, /* OUT EP FIFO size */ + 0 + } + } }; void sendDevDescString(int size) { - u16 str_ret[13] = { - 0x031a,//0x1a=26 byte - 0x0041, - 0x0030, - 0x0030, - 0x0041, - 0x0030, - 0x0030, - 0x0041, - 0x0030, - 0x0030, - 0x0041, - 0x0030, - 0x0030 - }; - if(size >= 26) - size = 26; - str_ret[0] = (0x0300 | size); - HW_SendPKT(0, (u8 *)str_ret,size); + u16 str_ret[13] = { + 0x031a,//0x1a=26 byte + 0x0041, + 0x0030, + 0x0030, + 0x0041, + 0x0030, + 0x0030, + 0x0041, + 0x0030, + 0x0030, + 0x0041, + 0x0030, + 0x0030 + }; + if(size >= 26) + size = 26; + str_ret[0] = (0x0300 | size); + HW_SendPKT(0, (u8 *)str_ret,size); } void sendDevDesc(int size) { switch (size) { - case 18: - HW_SendPKT(0, (u8 *)&devDesc, sizeof(devDesc)); - break; - default: - HW_SendPKT(0, (u8 *)&devDesc, 8); - break; - } + case 18: + HW_SendPKT(0, (u8 *)&devDesc, sizeof(devDesc)); + break; + default: + HW_SendPKT(0, (u8 *)&devDesc, 8); + break; + } } void sendConfDesc(int size) { - switch (size) { - case 9: - HW_SendPKT(0, (u8 *)&confDesc, 9); - break; - case 8: - HW_SendPKT(0, (u8 *)&confDesc, 8); - break; - default: - HW_SendPKT(0, (u8 *)&confDesc, sizeof(confDesc)); - break; - } + switch (size) { + case 9: + HW_SendPKT(0, (u8 *)&confDesc, 9); + break; + case 8: + HW_SendPKT(0, (u8 *)&confDesc, 8); + break; + default: + HW_SendPKT(0, (u8 *)&confDesc, sizeof(confDesc)); + break; + } } void EP0_init(u32 out, u32 out_size, u32 in, u32 in_size) { - confDesc.endpoint_descriptor[0].bEndpointAddress = (1<<7) | in; - confDesc.endpoint_descriptor[0].wMaxPacketSize = in_size; - confDesc.endpoint_descriptor[1].bEndpointAddress = (0<<7) | out; - confDesc.endpoint_descriptor[1].wMaxPacketSize = out_size; + confDesc.endpoint_descriptor[0].bEndpointAddress = (1<<7) | in; + confDesc.endpoint_descriptor[0].wMaxPacketSize = in_size; + confDesc.endpoint_descriptor[1].bEndpointAddress = (0<<7) | out; + confDesc.endpoint_descriptor[1].wMaxPacketSize = out_size; } static void udc_reset(void) { - //data init - ep0state = USB_EP0_IDLE; - Bulk_in_size = 0; - Bulk_in_finish = 0; - Bulk_out_size = 0; - udc_state = IDLE; - tx_size = 0; - rx_size = 0; - finished = 0; - /* Enable the USB PHY */ -// REG_CPM_SCR |= CPM_SCR_USBPHY_ENABLE; - /* Disable interrupts */ - jz_writew(USB_REG_INTRINE, 0); - jz_writew(USB_REG_INTROUTE, 0); - jz_writeb(USB_REG_INTRUSBE, 0); - jz_writeb(USB_REG_FADDR,0); - jz_writeb(USB_REG_POWER,0x60); //High speed - jz_writeb(USB_REG_INDEX,0); - jz_writeb(USB_REG_CSR0,0xc0); - jz_writeb(USB_REG_INDEX,1); - jz_writew(USB_REG_INMAXP,512); - jz_writew(USB_REG_INCSR,0x2048); - jz_writeb(USB_REG_INDEX,1); - jz_writew(USB_REG_OUTMAXP,512); - jz_writew(USB_REG_OUTCSR,0x0090); - jz_writew(USB_REG_INTRINE,0x3); //enable intr - jz_writew(USB_REG_INTROUTE,0x2); - jz_writeb(USB_REG_INTRUSBE,0x4); - - if ((jz_readb(USB_REG_POWER)&0x10)==0) - { - jz_writeb(USB_REG_INDEX,1); - jz_writew(USB_REG_INMAXP,64); - jz_writew(USB_REG_INCSR,0x2048); - jz_writeb(USB_REG_INDEX,1); - jz_writew(USB_REG_OUTMAXP,64); - jz_writew(USB_REG_OUTCSR,0x0090); - USB_Version=USB_FS; - fifosize[1]=64; - EP0_init(1,64,1,64); - } - else - { - jz_writeb(USB_REG_INDEX,1); - jz_writew(USB_REG_INMAXP,512); - jz_writew(USB_REG_INCSR,0x2048); - jz_writeb(USB_REG_INDEX,1); - jz_writew(USB_REG_OUTMAXP,512); - jz_writew(USB_REG_OUTCSR,0x0090); - USB_Version=USB_HS; - fifosize[1]=512; - EP0_init(1,512,1,512); - } + //data init + ep0state = USB_EP0_IDLE; + Bulk_in_size = 0; + Bulk_in_finish = 0; + Bulk_out_size = 0; + udc_state = IDLE; + tx_size = 0; + rx_size = 0; + finished = 0; + /* Enable the USB PHY */ +// REG_CPM_SCR |= CPM_SCR_USBPHY_ENABLE; + /* Disable interrupts */ + jz_writew(USB_REG_INTRINE, 0); + jz_writew(USB_REG_INTROUTE, 0); + jz_writeb(USB_REG_INTRUSBE, 0); + jz_writeb(USB_REG_FADDR,0); + jz_writeb(USB_REG_POWER,0x60); //High speed + jz_writeb(USB_REG_INDEX,0); + jz_writeb(USB_REG_CSR0,0xc0); + jz_writeb(USB_REG_INDEX,1); + jz_writew(USB_REG_INMAXP,512); + jz_writew(USB_REG_INCSR,0x2048); + jz_writeb(USB_REG_INDEX,1); + jz_writew(USB_REG_OUTMAXP,512); + jz_writew(USB_REG_OUTCSR,0x0090); + jz_writew(USB_REG_INTRINE,0x3); //enable intr + jz_writew(USB_REG_INTROUTE,0x2); + jz_writeb(USB_REG_INTRUSBE,0x4); + + if ((jz_readb(USB_REG_POWER)&0x10)==0) + { + jz_writeb(USB_REG_INDEX,1); + jz_writew(USB_REG_INMAXP,64); + jz_writew(USB_REG_INCSR,0x2048); + jz_writeb(USB_REG_INDEX,1); + jz_writew(USB_REG_OUTMAXP,64); + jz_writew(USB_REG_OUTCSR,0x0090); + USB_Version=USB_FS; + fifosize[1]=64; + EP0_init(1,64,1,64); + } + else + { + jz_writeb(USB_REG_INDEX,1); + jz_writew(USB_REG_INMAXP,512); + jz_writew(USB_REG_INCSR,0x2048); + jz_writeb(USB_REG_INDEX,1); + jz_writew(USB_REG_OUTMAXP,512); + jz_writew(USB_REG_OUTCSR,0x0090); + USB_Version=USB_HS; + fifosize[1]=512; + EP0_init(1,512,1,512); + } } void usbHandleStandDevReq(u8 *buf) { - USB_DeviceRequest *dreq = (USB_DeviceRequest *)buf; - switch (dreq->bRequest) { - case GET_DESCRIPTOR: - if (dreq->bmRequestType == 0x80) /* Dev2Host */ - switch(dreq->wValue >> 8) - { - case DEVICE_DESCRIPTOR: - sendDevDesc(dreq->wLength); - break; - case CONFIGURATION_DESCRIPTOR: - sendConfDesc(dreq->wLength); - break; - case STRING_DESCRIPTOR: - if (dreq->wLength == 0x02) - HW_SendPKT(0, "\x04\x03", 2); - else - sendDevDescString(dreq->wLength); - //HW_SendPKT(0, "\x04\x03\x09\x04", 2); - break; - } - ep0state=USB_EP0_TX; - - break; - case SET_ADDRESS: - jz_writeb(USB_REG_FADDR,dreq->wValue); - break; - case GET_STATUS: - switch (dreq->bmRequestType) { - case 80: /* device */ - HW_SendPKT(0, "\x01\x00", 2); - break; - case 81: /* interface */ - case 82: /* ep */ - HW_SendPKT(0, "\x00\x00", 2); - break; - } - ep0state=USB_EP0_TX; - break; - case CLEAR_FEATURE: - case SET_CONFIGURATION: - case SET_INTERFACE: - case SET_FEATURE: - break; - } + USB_DeviceRequest *dreq = (USB_DeviceRequest *)buf; + switch (dreq->bRequest) { + case GET_DESCRIPTOR: + if (dreq->bmRequestType == 0x80) /* Dev2Host */ + switch(dreq->wValue >> 8) + { + case DEVICE_DESCRIPTOR: + sendDevDesc(dreq->wLength); + break; + case CONFIGURATION_DESCRIPTOR: + sendConfDesc(dreq->wLength); + break; + case STRING_DESCRIPTOR: + if (dreq->wLength == 0x02) + HW_SendPKT(0, "\x04\x03", 2); + else + sendDevDescString(dreq->wLength); + //HW_SendPKT(0, "\x04\x03\x09\x04", 2); + break; + } + ep0state=USB_EP0_TX; + + break; + case SET_ADDRESS: + jz_writeb(USB_REG_FADDR,dreq->wValue); + break; + case GET_STATUS: + switch (dreq->bmRequestType) { + case 80: /* device */ + HW_SendPKT(0, "\x01\x00", 2); + break; + case 81: /* interface */ + case 82: /* ep */ + HW_SendPKT(0, "\x00\x00", 2); + break; + } + ep0state=USB_EP0_TX; + break; + case CLEAR_FEATURE: + case SET_CONFIGURATION: + case SET_INTERFACE: + case SET_FEATURE: + break; + } } unsigned char nandbuffer[4096]; +extern void jz_nand_read(int block, int page, unsigned char *buf); void usbHandleVendorReq(u8 *buf) { - USB_DeviceRequest *dreq = (USB_DeviceRequest *)buf; - switch (dreq->bRequest) + USB_DeviceRequest *dreq = (USB_DeviceRequest *)buf; + switch (dreq->bRequest) { case 0xB0: memset(&nandbuffer, 0, 4096); - jz_nand_read(dreq->wValue, dreq->wIndex, &nandbuffer); + jz_nand_read(dreq->wValue, dreq->wIndex, nandbuffer); //printf("Read block %d page %d", dreq->wValue, dreq->wIndex); udc_state = IDLE; break; - case 0xAB: - HW_SendPKT(1, nandbuffer, 4096); + case 0xAB: + Enable_DMA(nandbuffer, 4096); + //HW_SendPKT(1, nandbuffer, 4096); //printf("Send data"); - //udc_state = BULK_OUT; - break; + //udc_state = BULK_OUT; + break; case 0x12: - HW_SendPKT(0, "TEST", 4); + HW_SendPKT(0, "TEST", 4); //printf("Send test"); - udc_state = IDLE; + udc_state = IDLE; break; - } + } } void Handshake_PKT(void) { - if (udc_state!=IDLE) - { - HW_SendPKT(1,(u8 *)handshake_PKT,sizeof(handshake_PKT)); - udc_state = IDLE; - } + if (udc_state!=IDLE) + { + HW_SendPKT(1,(u8 *)handshake_PKT,sizeof(handshake_PKT)); + udc_state = IDLE; + } } void usbHandleDevReq(u8 *buf) { - switch ((buf[0] & (3 << 5)) >> 5) { - case 0: /* Standard request */ - usbHandleStandDevReq(buf); - break; - case 1: /* Class request */ - break; - case 2: /* Vendor request */ - usbHandleVendorReq(buf); - break; - } + switch ((buf[0] & (3 << 5)) >> 5) { + case 0: /* Standard request */ + usbHandleStandDevReq(buf); + break; + case 1: /* Class request */ + break; + case 2: /* Vendor request */ + usbHandleVendorReq(buf); + break; + } } void EP0_Handler (void) { - u8 byCSR0; + u8 byCSR0; /* Read CSR0 */ - jz_writeb(USB_REG_INDEX, 0); - byCSR0 = jz_readb(USB_REG_CSR0); + jz_writeb(USB_REG_INDEX, 0); + byCSR0 = jz_readb(USB_REG_CSR0); /* Check for SentStall if sendstall is set ,clear the sendstall bit*/ - if (byCSR0 & USB_CSR0_SENTSTALL) - { - jz_writeb(USB_REG_CSR0, (byCSR0 & ~USB_CSR0_SENDSTALL)); - ep0state = USB_EP0_IDLE; - return; - } + if (byCSR0 & USB_CSR0_SENTSTALL) + { + jz_writeb(USB_REG_CSR0, (byCSR0 & ~USB_CSR0_SENDSTALL)); + ep0state = USB_EP0_IDLE; + return; + } /* Check for SetupEnd */ - if (byCSR0 & USB_CSR0_SETUPEND) - { - jz_writeb(USB_REG_CSR0, (byCSR0 | USB_CSR0_SVDSETUPEND)); - ep0state = USB_EP0_IDLE; - return; - } + if (byCSR0 & USB_CSR0_SETUPEND) + { + jz_writeb(USB_REG_CSR0, (byCSR0 | USB_CSR0_SVDSETUPEND)); + ep0state = USB_EP0_IDLE; + return; + } /* Call relevant routines for endpoint 0 state */ - if (ep0state == USB_EP0_IDLE) - { - if (byCSR0 & USB_CSR0_OUTPKTRDY) //There are datas in fifo - { - USB_DeviceRequest *dreq; - fifo=fifoaddr[0]; - udcReadFifo((u8 *)rx_buf, sizeof(USB_DeviceRequest)); - usb_setb(USB_REG_CSR0, 0x48);//clear OUTRD bit - dreq = (USB_DeviceRequest *)rx_buf; - usbHandleDevReq((u8 *)rx_buf); - } - rx_size = 0; - } - - if (ep0state == USB_EP0_TX) - { - fifo=fifoaddr[0]; - if (tx_size - finished <= 64) - { - udcWriteFifo((u8 *)((u32)tx_buf+finished), - tx_size - finished); - finished = tx_size; - usb_setb(USB_REG_CSR0, USB_CSR0_INPKTRDY); - usb_setb(USB_REG_CSR0, USB_CSR0_DATAEND); //Set dataend! - ep0state=USB_EP0_IDLE; - } else - { - udcWriteFifo((u8 *)((u32)tx_buf+finished), 64); - usb_setb(USB_REG_CSR0, USB_CSR0_INPKTRDY); - finished += 64; - } - } - return; + if (ep0state == USB_EP0_IDLE) + { + if (byCSR0 & USB_CSR0_OUTPKTRDY) //There are datas in fifo + { + USB_DeviceRequest *dreq; + fifo=fifoaddr[0]; + udcReadFifo((u8 *)rx_buf, sizeof(USB_DeviceRequest)); + usb_setb(USB_REG_CSR0, 0x48);//clear OUTRD bit + dreq = (USB_DeviceRequest *)rx_buf; + usbHandleDevReq((u8 *)rx_buf); + } + rx_size = 0; + } + + if (ep0state == USB_EP0_TX) + { + fifo=fifoaddr[0]; + if (tx_size - finished <= 64) + { + udcWriteFifo((u8 *)((u32)tx_buf+finished), + tx_size - finished); + finished = tx_size; + usb_setb(USB_REG_CSR0, USB_CSR0_INPKTRDY); + usb_setb(USB_REG_CSR0, USB_CSR0_DATAEND); //Set dataend! + ep0state=USB_EP0_IDLE; + } else + { + udcWriteFifo((u8 *)((u32)tx_buf+finished), 64); + usb_setb(USB_REG_CSR0, USB_CSR0_INPKTRDY); + finished += 64; + } + } + return; } void EPIN_Handler(u8 EP) { - jz_writeb(USB_REG_INDEX, EP); - fifo = fifoaddr[EP]; - - if (Bulk_in_size-Bulk_in_finish==0) - { - Handshake_PKT(); - return; - } - - if (Bulk_in_size - Bulk_in_finish <= fifosize[EP]) - { - udcWriteFifo((u8 *)((u32)Bulk_in_buf+Bulk_in_finish), - Bulk_in_size - Bulk_in_finish); - usb_setw(USB_REG_INCSR, USB_INCSR_INPKTRDY); - Bulk_in_finish = Bulk_in_size; - } + jz_writeb(USB_REG_INDEX, EP); + fifo = fifoaddr[EP]; + + if (Bulk_in_size-Bulk_in_finish==0) + { + Handshake_PKT(); + return; + } + + if (Bulk_in_size - Bulk_in_finish <= fifosize[EP]) + { + udcWriteFifo((u8 *)((u32)Bulk_in_buf+Bulk_in_finish), + Bulk_in_size - Bulk_in_finish); + usb_setw(USB_REG_INCSR, USB_INCSR_INPKTRDY); + Bulk_in_finish = Bulk_in_size; + } else - { - udcWriteFifo((u8 *)((u32)Bulk_in_buf+Bulk_in_finish), - fifosize[EP]); - usb_setw(USB_REG_INCSR, USB_INCSR_INPKTRDY); - Bulk_in_finish += fifosize[EP]; - } + { + udcWriteFifo((u8 *)((u32)Bulk_in_buf+Bulk_in_finish), + fifosize[EP]); + usb_setw(USB_REG_INCSR, USB_INCSR_INPKTRDY); + Bulk_in_finish += fifosize[EP]; + } } void EPOUT_Handler(u8 EP) { - u32 size; - jz_writeb(USB_REG_INDEX, EP); - size = jz_readw(USB_REG_OUTCOUNT); - fifo = fifoaddr[EP]; - udcReadFifo((u8 *)((u32)Bulk_out_buf+Bulk_out_size), size); - usb_clearb(USB_REG_OUTCSR,USB_OUTCSR_OUTPKTRDY); - Bulk_out_size += size; + u32 size; + jz_writeb(USB_REG_INDEX, EP); + size = jz_readw(USB_REG_OUTCOUNT); + fifo = fifoaddr[EP]; + udcReadFifo((u8 *)((u32)Bulk_out_buf+Bulk_out_size), size); + usb_clearb(USB_REG_OUTCSR,USB_OUTCSR_OUTPKTRDY); + Bulk_out_size += size; } void UDC(void) { - u8 IntrUSB; - u16 IntrIn; - u16 IntrOut; + u8 IntrUSB; + u16 IntrIn; + u16 IntrOut; + u16 IntrDMA; /* Read interrupt registers */ - IntrUSB = jz_readb(USB_REG_INTRUSB); - IntrIn = jz_readw(USB_REG_INTRIN); - IntrOut = jz_readw(USB_REG_INTROUT); - - if ( IntrUSB == 0 && IntrIn == 0 && IntrOut == 0) - return; - - if (IntrIn & 2) - { - EPIN_Handler(1); - } - if (IntrOut & 2) - { - EPOUT_Handler(1); - } - if (IntrUSB & USB_INTR_RESET) - { - udc_reset(); - } + IntrUSB = jz_readb(USB_REG_INTRUSB); + IntrIn = jz_readw(USB_REG_INTRIN); + IntrOut = jz_readw(USB_REG_INTROUT); + IntrDMA = jz_readb(USB_REG_INTR); + + if ( IntrUSB == 0 && IntrIn == 0 && IntrOut == 0) + return; + + if (IntrIn & 2) + { + EPIN_Handler(1); + } + if (IntrOut & 2) + { + EPOUT_Handler(1); + } + if (IntrUSB & USB_INTR_RESET) + { + udc_reset(); + } /* Check for endpoint 0 interrupt */ - if (IntrIn & USB_INTR_EP0) - { - EP0_Handler(); - } + if (IntrIn & USB_INTR_EP0) + { + EP0_Handler(); + } - IntrIn = jz_readw(USB_REG_INTRIN); - return; + if (IntrDMA & 0x1) //channel 1 :OUT + { + if (tx_size > 0 && tx_size % fifosize[1] != 0) + { + jz_writeb(USB_REG_INDEX, 1); + usb_clearb(USB_REG_INCSR, USB_INCSR_INPKTRDY); + } + Disable_DMA(); + } } void __udc_start(void) { udc_reset(); - ep0state = USB_EP0_IDLE; - Bulk_in_size = 0; - Bulk_in_finish = 0; - Bulk_out_size = 0; - udc_state = IDLE; - tx_size = 0; - rx_size = 0; - finished = 0; - - if ((jz_readb(USB_REG_POWER)&0x10)==0) - { - USB_Version=USB_FS; - fifosize[1]=64; - EP0_init(1,64,1,64); - } - else - { - USB_Version=USB_HS; - fifosize[1]=512; - EP0_init(1,512,1,512); - } - - USB_Version=USB_HS; + ep0state = USB_EP0_IDLE; + Bulk_in_size = 0; + Bulk_in_finish = 0; + Bulk_out_size = 0; + udc_state = IDLE; + tx_size = 0; + rx_size = 0; + finished = 0; + + if ((jz_readb(USB_REG_POWER)&0x10)==0) + { + USB_Version=USB_FS; + fifosize[1]=64; + EP0_init(1,64,1,64); + } + else + { + USB_Version=USB_HS; + fifosize[1]=512; + EP0_init(1,512,1,512); + } + + USB_Version=USB_HS; system_enable_irq(IRQ_UDC); } -- cgit v1.2.3