diff options
Diffstat (limited to 'firmware/target/mips/ingenic_jz47xx/usb-jz4740.c')
-rw-r--r-- | firmware/target/mips/ingenic_jz47xx/usb-jz4740.c | 1635 |
1 files changed, 988 insertions, 647 deletions
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 @@ | |||
20 | ****************************************************************************/ | 20 | ****************************************************************************/ |
21 | 21 | ||
22 | #include "config.h" | 22 | #include "config.h" |
23 | #include "string.h" | ||
23 | #include "system.h" | 24 | #include "system.h" |
24 | #include "usb_ch9.h" | 25 | #include "usb_ch9.h" |
25 | #include "usb_drv.h" | 26 | #include "usb_drv.h" |
@@ -27,7 +28,7 @@ | |||
27 | #include "jz4740.h" | 28 | #include "jz4740.h" |
28 | #include "thread.h" | 29 | #include "thread.h" |
29 | 30 | ||
30 | #if 0 | 31 | #if 1 |
31 | 32 | ||
32 | #define EP1_INTR_BIT 2 | 33 | #define EP1_INTR_BIT 2 |
33 | #define EP_FIFO_NOEMPTY 2 | 34 | #define EP_FIFO_NOEMPTY 2 |
@@ -38,14 +39,327 @@ | |||
38 | 39 | ||
39 | #define IS_CACHE(x) (x < 0xa0000000) | 40 | #define IS_CACHE(x) (x < 0xa0000000) |
40 | 41 | ||
42 | #define USB_EP0_IDLE 0 | ||
43 | #define USB_EP0_RX 1 | ||
44 | #define USB_EP0_TX 2 | ||
45 | |||
46 | enum ep_type | ||
47 | { | ||
48 | ep_control, ep_bulk, ep_interrupt | ||
49 | }; | ||
50 | |||
51 | struct usb_endpoint | ||
52 | { | ||
53 | void *buf; | ||
54 | unsigned int length; | ||
55 | void *ptr; | ||
56 | |||
57 | const enum ep_type type; | ||
58 | const bool use_dma; | ||
59 | const bool in; | ||
60 | |||
61 | const void *fifo_addr; | ||
62 | unsigned short fifo_size; | ||
63 | }; | ||
64 | |||
65 | static unsigned char ep0_rx_buf[64]; | ||
66 | static unsigned char ep0_tx_buf[64]; | ||
67 | static unsigned char ep0state = USB_EP0_IDLE; | ||
68 | static struct usb_endpoint endpoints[] = | ||
69 | { | ||
70 | /* buf length ptr type use_dma in fifo_addr fifo_size */ | ||
71 | {&ep0_rx_buf, 0, &ep0_rx_buf, ep_control, false, true, (void*)USB_FIFO_EP0, 64 }, | ||
72 | {&ep0_tx_buf, 0, &ep0_tx_buf, ep_control, false, false, (void*)USB_FIFO_EP0, 64 }, | ||
73 | {NULL, 0, NULL, ep_bulk, true, true, (void*)USB_FIFO_EP1, 512}, | ||
74 | {NULL, 0, NULL, ep_bulk, true, false, (void*)USB_FIFO_EP1, 512}, | ||
75 | {NULL, 0, NULL, ep_interrupt, false, true, (void*)USB_FIFO_EP2, 64 } | ||
76 | }; | ||
77 | |||
78 | static inline void select_endpoint(int ep) | ||
79 | { | ||
80 | REG_USB_REG_INDEX = ep; | ||
81 | } | ||
82 | |||
83 | static void readFIFO(struct usb_endpoint *ep, unsigned int size) | ||
84 | { | ||
85 | unsigned int *d = (unsigned int *)ep->ptr; | ||
86 | unsigned int s; | ||
87 | s = (size + 3) >> 2; | ||
88 | while (s--) | ||
89 | *d++ = REG32(ep->fifo_addr); | ||
90 | } | ||
91 | |||
92 | static void writeFIFO(struct usb_endpoint *ep, unsigned int size) | ||
93 | { | ||
94 | unsigned int *d = (unsigned int *)ep->ptr; | ||
95 | unsigned char *c; | ||
96 | int s, q; | ||
97 | |||
98 | if (size > 0) | ||
99 | { | ||
100 | s = size >> 2; | ||
101 | while (s--) | ||
102 | REG32(ep->fifo_addr) = *d++; | ||
103 | |||
104 | q = size & 3; | ||
105 | if (q) | ||
106 | { | ||
107 | c = (unsigned char *)d; | ||
108 | while (q--) | ||
109 | REG8(ep->fifo_addr) = *c++; | ||
110 | } | ||
111 | } | ||
112 | } | ||
113 | |||
114 | static void sendPKT(int ep_nr, const unsigned char* ptr, unsigned int size) | ||
115 | { | ||
116 | struct usb_endpoint *ep = &endpoints[ep_nr]; | ||
117 | |||
118 | if (ep_nr != 0) | ||
119 | { | ||
120 | ep->buf = (void*)ptr; | ||
121 | ep->ptr = (void*)ptr; | ||
122 | ep->length = size; | ||
123 | select_endpoint(ep_nr); | ||
124 | if (size <= ep->fifo_size) | ||
125 | { | ||
126 | writeFIFO(ep, size); | ||
127 | REG_USB_REG_INCSR |= USB_INCSR_INPKTRDY; | ||
128 | ep->ptr = ep->buf + size; | ||
129 | } | ||
130 | else | ||
131 | { | ||
132 | writeFIFO(ep, ep->fifo_size); | ||
133 | REG_USB_REG_INCSR |= USB_INCSR_INPKTRDY; | ||
134 | ep->ptr += ep->fifo_size; | ||
135 | } | ||
136 | } | ||
137 | else /* EP0 */ | ||
138 | { | ||
139 | ep->length = size; | ||
140 | ep->ptr = ep->buf; | ||
141 | memcpy(ep->buf, ptr, size); | ||
142 | ep0state = USB_EP0_TX; | ||
143 | } | ||
144 | } | ||
145 | |||
146 | static void getPKT(int ep_nr, const unsigned char *ptr, unsigned int size) | ||
147 | { | ||
148 | struct usb_endpoint *ep = &endpoints[ep_nr]; | ||
149 | |||
150 | memcpy((void*)ptr, ep->ptr, size); | ||
151 | if (ep->length > size) | ||
152 | ep->length -= size; | ||
153 | else | ||
154 | { | ||
155 | size = ep->length; | ||
156 | ep->length = 0; | ||
157 | } | ||
158 | |||
159 | ep->ptr += size; | ||
160 | } | ||
161 | |||
162 | static void EP0_handler(void) | ||
163 | { | ||
164 | unsigned char csr0; | ||
165 | |||
166 | /* Read CSR0 */ | ||
167 | select_endpoint(0); | ||
168 | csr0 = REG_USB_REG_CSR0; | ||
169 | |||
170 | /* Check for SentStall | ||
171 | if sentstall is set, clear the sentstall bit | ||
172 | */ | ||
173 | if (csr0 & USB_CSR0_SENTSTALL) | ||
174 | { | ||
175 | REG_USB_REG_CSR0 = csr0 & ~USB_CSR0_SENTSTALL; | ||
176 | ep0state = USB_EP0_IDLE; | ||
177 | return; | ||
178 | } | ||
179 | |||
180 | /* Check for SetupEnd */ | ||
181 | if (csr0 & USB_CSR0_SETUPEND) | ||
182 | { | ||
183 | REG_USB_REG_CSR0 |= USB_CSR0_SVDSETUPEND; | ||
184 | ep0state = USB_EP0_IDLE; | ||
185 | return; | ||
186 | } | ||
187 | |||
188 | /* Call relevant routines for endpoint 0 state */ | ||
189 | if (ep0state == USB_EP0_IDLE) | ||
190 | { | ||
191 | if (csr0 & USB_CSR0_OUTPKTRDY) /* There is data in the fifo */ | ||
192 | { | ||
193 | readFIFO(&endpoints[0], 8); | ||
194 | REG_USB_REG_CSR0 |= USB_CSR0_SVDOUTPKTRDY; /* clear OUTRD bit */ | ||
195 | usb_core_control_request((struct usb_ctrlrequest*)endpoints[0].buf); | ||
196 | } | ||
197 | endpoints[0].length = 0; | ||
198 | endpoints[0].ptr = endpoints[0].buf; | ||
199 | } | ||
200 | |||
201 | if (ep0state == USB_EP0_TX) | ||
202 | { | ||
203 | if ((&endpoints[1].ptr - &endpoints[1].buf) <= endpoints[1].fifo_size) | ||
204 | { | ||
205 | writeFIFO(&endpoints[1], (&endpoints[1].ptr - &endpoints[1].buf)); | ||
206 | endpoints[1].ptr = &endpoints[1].buf + endpoints[1].length; | ||
207 | REG_USB_REG_CSR0 |= (USB_CSR0_INPKTRDY | USB_CSR0_DATAEND); /* Set data end! */ | ||
208 | ep0state = USB_EP0_IDLE; | ||
209 | } | ||
210 | else | ||
211 | { | ||
212 | writeFIFO(&endpoints[1], endpoints[1].fifo_size); | ||
213 | REG_USB_REG_CSR0 |= USB_CSR0_INPKTRDY; | ||
214 | endpoints[1].ptr += endpoints[1].fifo_size; | ||
215 | } | ||
216 | } | ||
217 | } | ||
218 | |||
219 | static void setup_endpoint(struct usb_endpoint *ep) | ||
220 | { | ||
221 | ep->ptr = ep->buf; | ||
222 | ep->length = 0; | ||
223 | |||
224 | if(ep->in) | ||
225 | { | ||
226 | if(ep->type == ep_bulk) | ||
227 | { | ||
228 | register int size; | ||
229 | |||
230 | if((REG_USB_REG_POWER & USB_POWER_HSMODE) == 0) | ||
231 | size = 64; | ||
232 | else | ||
233 | size = 512; | ||
234 | |||
235 | REG_USB_REG_INMAXP = size; | ||
236 | ep->fifo_size = size; | ||
237 | } | ||
238 | else | ||
239 | REG_USB_REG_INMAXP = ep->fifo_size; | ||
240 | |||
241 | REG_USB_REG_INCSR = 0x2048; | ||
242 | } | ||
243 | else | ||
244 | { | ||
245 | REG_USB_REG_OUTMAXP = ep->fifo_size; | ||
246 | REG_USB_REG_OUTCSR = 0x0090; | ||
247 | } | ||
248 | } | ||
249 | |||
250 | static void udc_reset(void) | ||
251 | { | ||
252 | register int i; | ||
253 | |||
254 | /* data init */ | ||
255 | ep0state = USB_EP0_IDLE; | ||
256 | |||
257 | /* Disable interrupts */ | ||
258 | REG_USB_REG_INTRINE = 0; | ||
259 | REG_USB_REG_INTROUTE = 0; | ||
260 | REG_USB_REG_INTRUSBE = 0; | ||
261 | |||
262 | REG_USB_REG_FADDR = 0; | ||
263 | REG_USB_REG_POWER = 0x60; /* High speed */ | ||
264 | |||
265 | select_endpoint(0); | ||
266 | REG_USB_REG_CSR0 = 0xC0; | ||
267 | |||
268 | for(i=1; i<3; i++) | ||
269 | { | ||
270 | select_endpoint(i); | ||
271 | setup_endpoint(&endpoints[i]); | ||
272 | } | ||
273 | |||
274 | /* enable intr */ | ||
275 | REG_USB_REG_INTRINE = 0x3; | ||
276 | REG_USB_REG_INTROUTE = 0x2; | ||
277 | REG_USB_REG_INTRUSBE = 0x4; | ||
278 | } | ||
279 | |||
280 | /* Interrupt handler */ | ||
281 | void UDC(void) | ||
282 | { | ||
283 | /* Read interrupt registers */ | ||
284 | unsigned char intrUSB = REG_USB_REG_INTRUSB & 0x07; /* Mask SOF */ | ||
285 | unsigned short intrIn = REG_USB_REG_INTRIN; | ||
286 | unsigned short intrOut = REG_USB_REG_INTROUT; | ||
287 | unsigned char intrDMA = REG_USB_REG_INTR; | ||
288 | |||
289 | if(intrUSB == 0 && intrIn == 0 && intrOut == 0 && intrDMA == 0) | ||
290 | return; | ||
291 | |||
292 | /* EPIN & EPOUT are all handled in DMA */ | ||
293 | if(intrIn & USB_INTR_EP0) | ||
294 | EP0_handler(); | ||
295 | if(intrUSB & USB_INTR_RESET) | ||
296 | udc_reset(); | ||
297 | if(intrUSB & USB_INTR_SUSPEND); | ||
298 | if(intrUSB & USB_INTR_RESUME); | ||
299 | if(intrDMA & USB_INTR_DMA_BULKIN) | ||
300 | { | ||
301 | usb_core_transfer_complete(((REG_USB_REG_CNTL1 >> 4) & 0xF) | USB_DIR_IN, USB_DIR_IN, 0, 0); | ||
302 | } | ||
303 | if(intrDMA & USB_INTR_DMA_BULKOUT) | ||
304 | { | ||
305 | usb_core_transfer_complete(((REG_USB_REG_CNTL2 >> 4) & 0xF) | USB_DIR_OUT, USB_DIR_OUT, 0, 0); | ||
306 | } | ||
307 | } | ||
308 | |||
309 | bool usb_drv_stalled(int endpoint, bool in) | ||
310 | { | ||
311 | select_endpoint(endpoint); | ||
312 | |||
313 | if(endpoint == 0) | ||
314 | return (REG_USB_REG_CSR0 & USB_CSR0_SENDSTALL) != 0; | ||
315 | else | ||
316 | { | ||
317 | if(in) | ||
318 | return (REG_USB_REG_INCSR & USB_INCSR_SENDSTALL) != 0; | ||
319 | else | ||
320 | return (REG_USB_REG_OUTCSR & USB_OUTCSR_SENDSTALL) != 0; | ||
321 | } | ||
322 | } | ||
323 | |||
324 | void usb_drv_stall(int endpoint, bool stall, bool in) | ||
325 | { | ||
326 | select_endpoint(endpoint); | ||
327 | |||
328 | if(endpoint == 0) | ||
329 | { | ||
330 | if(stall) | ||
331 | REG_USB_REG_CSR0 |= USB_CSR0_SENDSTALL; | ||
332 | else | ||
333 | REG_USB_REG_CSR0 &= ~USB_CSR0_SENDSTALL; | ||
334 | } | ||
335 | else | ||
336 | { | ||
337 | if(in) | ||
338 | { | ||
339 | if(stall) | ||
340 | REG_USB_REG_INCSR |= USB_INCSR_SENDSTALL; | ||
341 | else | ||
342 | REG_USB_REG_INCSR &= ~USB_INCSR_SENDSTALL; | ||
343 | } | ||
344 | else | ||
345 | { | ||
346 | if(stall) | ||
347 | REG_USB_REG_OUTCSR |= USB_OUTCSR_SENDSTALL; | ||
348 | else | ||
349 | REG_USB_REG_OUTCSR &= ~USB_OUTCSR_SENDSTALL; | ||
350 | } | ||
351 | } | ||
352 | } | ||
353 | |||
354 | |||
41 | bool usb_drv_connected(void) | 355 | bool usb_drv_connected(void) |
42 | { | 356 | { |
43 | return (__gpio_get_pin(GPIO_UDC_DETE)==1); | 357 | return __gpio_get_pin(GPIO_UDC_DETE) == 1; |
44 | } | 358 | } |
45 | 359 | ||
46 | int usb_detect(void) | 360 | int usb_detect(void) |
47 | { | 361 | { |
48 | if(__gpio_get_pin(GPIO_UDC_DETE)==1) | 362 | if(__gpio_get_pin(GPIO_UDC_DETE) == 1) |
49 | return USB_INSERTED; | 363 | return USB_INSERTED; |
50 | else | 364 | else |
51 | return USB_EXTRACTED; | 365 | return USB_EXTRACTED; |
@@ -68,49 +382,51 @@ void usb_enable(bool on) | |||
68 | 382 | ||
69 | void usb_drv_init(void) | 383 | void usb_drv_init(void) |
70 | { | 384 | { |
71 | /* Set this bit to allow the UDC entering low-power mode when | 385 | /* Set this bit to allow the UDC entering low-power mode when |
72 | * there are no actions on the USB bus. | 386 | * there are no actions on the USB bus. |
73 | * UDC still works during this bit was set. | 387 | * UDC still works during this bit was set. |
74 | */ | 388 | */ |
75 | //__cpm_stop_udc(); | 389 | //__cpm_stop_udc(); |
76 | 390 | ||
77 | __cpm_start_udc(); | 391 | __cpm_start_udc(); |
78 | 392 | ||
79 | /* Enable the USB PHY */ | 393 | /* Enable the USB PHY */ |
80 | REG_CPM_SCR |= CPM_SCR_USBPHY_ENABLE; | 394 | REG_CPM_SCR |= CPM_SCR_USBPHY_ENABLE; |
81 | 395 | ||
82 | /* Disable interrupts */ | 396 | /* Disable interrupts */ |
83 | REG_USB_REG_INTRINE = 0; | 397 | REG_USB_REG_INTRINE = 0; |
84 | REG_USB_REG_INTROUTE = 0; | 398 | REG_USB_REG_INTROUTE = 0; |
85 | REG_USB_REG_INTRUSBE = 0; | 399 | REG_USB_REG_INTRUSBE = 0; |
86 | 400 | ||
87 | /* Enable interrupts */ | 401 | /* Enable interrupts */ |
88 | REG_USB_REG_INTRINE |= USB_INTR_EP0; | 402 | REG_USB_REG_INTRINE |= USB_INTR_EP0; |
89 | REG_USB_REG_INTRUSBE |= USB_INTR_RESET; | 403 | REG_USB_REG_INTRUSBE |= USB_INTR_RESET; |
90 | 404 | ||
91 | /* Enable SUSPEND */ | 405 | /* Enable SUSPEND */ |
92 | /* usb_setb(USB_REG_POWER, USB_POWER_SUSPENDM); */ | 406 | /* usb_setb(USB_REG_POWER, USB_POWER_SUSPENDM); */ |
93 | 407 | ||
94 | /* Enable HS Mode */ | 408 | /* Enable HS Mode */ |
95 | REG_USB_REG_POWER |= USB_POWER_HSENAB; | 409 | REG_USB_REG_POWER |= USB_POWER_HSENAB; |
96 | 410 | ||
97 | /* Let host detect UDC: | 411 | /* Let host detect UDC: |
98 | * Software must write a 1 to the PMR:USB_POWER_SOFTCONN bit to turn this | 412 | * Software must write a 1 to the PMR:USB_POWER_SOFTCONN bit to turn this |
99 | * transistor on and pull the USBDP pin HIGH. | 413 | * transistor on and pull the USBDP pin HIGH. |
100 | */ | 414 | */ |
101 | REG_USB_REG_POWER |= USB_POWER_SOFTCONN; | 415 | REG_USB_REG_POWER |= USB_POWER_SOFTCONN; |
416 | |||
417 | udc_reset(); | ||
102 | } | 418 | } |
103 | 419 | ||
104 | void usb_drv_exit(void) | 420 | void usb_drv_exit(void) |
105 | { | 421 | { |
106 | /* Disable interrupts */ | 422 | /* Disable interrupts */ |
107 | REG_USB_REG_INTRINE = 0; | 423 | REG_USB_REG_INTRINE = 0; |
108 | REG_USB_REG_INTROUTE = 0; | 424 | REG_USB_REG_INTROUTE = 0; |
109 | REG_USB_REG_INTRUSBE = 0; | 425 | REG_USB_REG_INTRUSBE = 0; |
110 | 426 | ||
111 | /* Disable DMA */ | 427 | /* Disable DMA */ |
112 | REG_USB_REG_CNTL1 = 0; | 428 | REG_USB_REG_CNTL1 = 0; |
113 | REG_USB_REG_CNTL2 = 0; | 429 | REG_USB_REG_CNTL2 = 0; |
114 | 430 | ||
115 | /* Disconnect from usb */ | 431 | /* Disconnect from usb */ |
116 | REG_USB_REG_POWER &= ~USB_POWER_SOFTCONN; | 432 | REG_USB_REG_POWER &= ~USB_POWER_SOFTCONN; |
@@ -126,253 +442,248 @@ void usb_drv_set_address(int address) | |||
126 | REG_USB_REG_FADDR = address; | 442 | REG_USB_REG_FADDR = address; |
127 | } | 443 | } |
128 | 444 | ||
129 | /* Interrupt handler */ | ||
130 | void UDC(void) | ||
131 | { | ||
132 | |||
133 | } | ||
134 | 445 | ||
135 | #else | 446 | #else |
136 | 447 | ||
137 | //------------------------------------------ | 448 | //------------------------------------------ |
138 | #ifndef u8 | 449 | #ifndef u8 |
139 | #define u8 unsigned char | 450 | #define u8 unsigned char |
140 | #endif | 451 | #endif |
141 | 452 | ||
142 | #ifndef u16 | 453 | #ifndef u16 |
143 | #define u16 unsigned short | 454 | #define u16 unsigned short |
144 | #endif | 455 | #endif |
145 | 456 | ||
146 | #ifndef u32 | 457 | #ifndef u32 |
147 | #define u32 unsigned int | 458 | #define u32 unsigned int |
148 | #endif | 459 | #endif |
149 | 460 | ||
150 | #ifndef s8 | 461 | #ifndef s8 |
151 | #define s8 char | 462 | #define s8 char |
152 | #endif | 463 | #endif |
153 | 464 | ||
154 | #ifndef s16 | 465 | #ifndef s16 |
155 | #define s16 short | 466 | #define s16 short |
156 | #endif | 467 | #endif |
157 | 468 | ||
158 | #ifndef s32 | 469 | #ifndef s32 |
159 | #define s32 int | 470 | #define s32 int |
160 | #endif | 471 | #endif |
161 | 472 | ||
162 | extern int usbdebug; | 473 | extern int usbdebug; |
163 | 474 | ||
164 | enum USB_ENDPOINT_TYPE | 475 | enum USB_ENDPOINT_TYPE |
165 | { | 476 | { |
166 | ENDPOINT_TYPE_CONTROL, | 477 | ENDPOINT_TYPE_CONTROL, |
167 | /* Typically used to configure a device when attached to the host. | 478 | /* Typically used to configure a device when attached to the host. |
168 | * It may also be used for other device specific purposes, including | 479 | * It may also be used for other device specific purposes, including |
169 | * control of other pipes on the device. | 480 | * control of other pipes on the device. |
170 | */ | 481 | */ |
171 | ENDPOINT_TYPE_ISOCHRONOUS, | 482 | ENDPOINT_TYPE_ISOCHRONOUS, |
172 | /* Typically used for applications which need guaranteed speed. | 483 | /* Typically used for applications which need guaranteed speed. |
173 | * Isochronous transfer is fast but with possible data loss. A typical | 484 | * Isochronous transfer is fast but with possible data loss. A typical |
174 | * use is audio data which requires a constant data rate. | 485 | * use is audio data which requires a constant data rate. |
175 | */ | 486 | */ |
176 | ENDPOINT_TYPE_BULK, | 487 | ENDPOINT_TYPE_BULK, |
177 | /* Typically used by devices that generate or consume data in relatively | 488 | /* Typically used by devices that generate or consume data in relatively |
178 | * large and bursty quantities. Bulk transfer has wide dynamic latitude | 489 | * large and bursty quantities. Bulk transfer has wide dynamic latitude |
179 | * in transmission constraints. It can use all remaining available bandwidth, | 490 | * in transmission constraints. It can use all remaining available bandwidth, |
180 | * but with no guarantees on bandwidth or latency. Since the USB bus is | 491 | * but with no guarantees on bandwidth or latency. Since the USB bus is |
181 | * normally not very busy, there is typically 90% or more of the bandwidth | 492 | * normally not very busy, there is typically 90% or more of the bandwidth |
182 | * available for USB transfers. | 493 | * available for USB transfers. |
183 | */ | 494 | */ |
184 | ENDPOINT_TYPE_INTERRUPT | 495 | ENDPOINT_TYPE_INTERRUPT |
185 | /* Typically used by devices that need guaranteed quick responses | 496 | /* Typically used by devices that need guaranteed quick responses |
186 | * (bounded latency). | 497 | * (bounded latency). |
187 | */ | 498 | */ |
188 | }; | 499 | }; |
189 | 500 | ||
190 | 501 | ||
191 | enum USB_STANDARD_REQUEST_CODE { | 502 | enum USB_STANDARD_REQUEST_CODE { |
192 | GET_STATUS, | 503 | GET_STATUS, |
193 | CLEAR_FEATURE, | 504 | CLEAR_FEATURE, |
194 | SET_FEATURE = 3, | 505 | SET_FEATURE = 3, |
195 | SET_ADDRESS = 5, | 506 | SET_ADDRESS = 5, |
196 | GET_DESCRIPTOR, | 507 | GET_DESCRIPTOR, |
197 | SET_DESCRIPTOR, | 508 | SET_DESCRIPTOR, |
198 | GET_CONFIGURATION, | 509 | GET_CONFIGURATION, |
199 | SET_CONFIGURATION, | 510 | SET_CONFIGURATION, |
200 | GET_INTERFACE, | 511 | GET_INTERFACE, |
201 | SET_INTERFACE, | 512 | SET_INTERFACE, |
202 | SYNCH_FRAME | 513 | SYNCH_FRAME |
203 | }; | 514 | }; |
204 | 515 | ||
205 | 516 | ||
206 | enum USB_DESCRIPTOR_TYPE { | 517 | enum USB_DESCRIPTOR_TYPE { |
207 | DEVICE_DESCRIPTOR = 1, | 518 | DEVICE_DESCRIPTOR = 1, |
208 | CONFIGURATION_DESCRIPTOR, | 519 | CONFIGURATION_DESCRIPTOR, |
209 | STRING_DESCRIPTOR, | 520 | STRING_DESCRIPTOR, |
210 | INTERFACE_DESCRIPTOR, | 521 | INTERFACE_DESCRIPTOR, |
211 | ENDPOINT_DESCRIPTOR, | 522 | ENDPOINT_DESCRIPTOR, |
212 | DEVICE_QUALIFIER_DESCRIPTOR, | 523 | DEVICE_QUALIFIER_DESCRIPTOR, |
213 | OTHER_SPEED_CONFIGURATION_DESCRIPTOR, | 524 | OTHER_SPEED_CONFIGURATION_DESCRIPTOR, |
214 | INTERFACE_POWER1_DESCRIPTOR | 525 | INTERFACE_POWER1_DESCRIPTOR |
215 | }; | 526 | }; |
216 | 527 | ||
217 | 528 | ||
218 | enum USB_FEATURE_SELECTOR { | 529 | enum USB_FEATURE_SELECTOR { |
219 | ENDPOINT_HALT, | 530 | ENDPOINT_HALT, |
220 | DEVICE_REMOTE_WAKEUP, | 531 | DEVICE_REMOTE_WAKEUP, |
221 | TEST_MODE | 532 | TEST_MODE |
222 | }; | 533 | }; |
223 | 534 | ||
224 | enum USB_CLASS_CODE { | 535 | enum USB_CLASS_CODE { |
225 | CLASS_DEVICE, | 536 | CLASS_DEVICE, |
226 | CLASS_AUDIO, | 537 | CLASS_AUDIO, |
227 | CLASS_COMM_AND_CDC_CONTROL, | 538 | CLASS_COMM_AND_CDC_CONTROL, |
228 | CLASS_HID, | 539 | CLASS_HID, |
229 | CLASS_PHYSICAL = 0x05, | 540 | CLASS_PHYSICAL = 0x05, |
230 | CLASS_STILL_IMAGING, | 541 | CLASS_STILL_IMAGING, |
231 | CLASS_PRINTER, | 542 | CLASS_PRINTER, |
232 | CLASS_MASS_STORAGE, | 543 | CLASS_MASS_STORAGE, |
233 | CLASS_HUB, | 544 | CLASS_HUB, |
234 | CLASS_CDC_DATA, | 545 | CLASS_CDC_DATA, |
235 | CLASS_SMART_CARD, | 546 | CLASS_SMART_CARD, |
236 | CLASS_CONTENT_SECURITY = 0x0d, | 547 | CLASS_CONTENT_SECURITY = 0x0d, |
237 | CLASS_VIDEO, | 548 | CLASS_VIDEO, |
238 | CLASS_DIAGNOSTIC_DEVICE = 0xdc, | 549 | CLASS_DIAGNOSTIC_DEVICE = 0xdc, |
239 | CLASS_WIRELESS_CONTROLLER = 0xe0, | 550 | CLASS_WIRELESS_CONTROLLER = 0xe0, |
240 | CLASS_MISCELLANEOUS = 0xef, | 551 | CLASS_MISCELLANEOUS = 0xef, |
241 | CLASS_APP_SPECIFIC = 0xfe, | 552 | CLASS_APP_SPECIFIC = 0xfe, |
242 | CLASS_VENDOR_SPECIFIC = 0xff | 553 | CLASS_VENDOR_SPECIFIC = 0xff |
243 | }; | 554 | }; |
244 | 555 | ||
245 | 556 | ||
246 | typedef struct { | 557 | typedef struct { |
247 | u8 bmRequestType; | 558 | u8 bmRequestType; |
248 | u8 bRequest; | 559 | u8 bRequest; |
249 | u16 wValue; | 560 | u16 wValue; |
250 | u16 wIndex; | 561 | u16 wIndex; |
251 | u16 wLength; | 562 | u16 wLength; |
252 | } __attribute__ ((packed)) USB_DeviceRequest; | 563 | } __attribute__ ((packed)) USB_DeviceRequest; |
253 | 564 | ||
254 | 565 | ||
255 | typedef struct { | 566 | typedef struct { |
256 | u8 bLength; | 567 | u8 bLength; |
257 | u8 bDescriptorType; | 568 | u8 bDescriptorType; |
258 | u16 bcdUSB; | 569 | u16 bcdUSB; |
259 | u8 bDeviceClass; | 570 | u8 bDeviceClass; |
260 | u8 bDeviceSubClass; | 571 | u8 bDeviceSubClass; |
261 | u8 bDeviceProtocol; | 572 | u8 bDeviceProtocol; |
262 | u8 bMaxPacketSize0; | 573 | u8 bMaxPacketSize0; |
263 | u16 idVendor; | 574 | u16 idVendor; |
264 | u16 idProduct; | 575 | u16 idProduct; |
265 | u16 bcdDevice; | 576 | u16 bcdDevice; |
266 | u8 iManufacturer; | 577 | u8 iManufacturer; |
267 | u8 iProduct; | 578 | u8 iProduct; |
268 | u8 iSerialNumber; | 579 | u8 iSerialNumber; |
269 | u8 bNumConfigurations; | 580 | u8 bNumConfigurations; |
270 | } __attribute__ ((packed)) USB_DeviceDescriptor; | 581 | } __attribute__ ((packed)) USB_DeviceDescriptor; |
271 | 582 | ||
272 | 583 | ||
273 | typedef struct { | 584 | typedef struct { |
274 | u8 bLength; | 585 | u8 bLength; |
275 | u8 bDescriptorType; | 586 | u8 bDescriptorType; |
276 | u16 bcdUSB; | 587 | u16 bcdUSB; |
277 | u8 bDeviceClass; | 588 | u8 bDeviceClass; |
278 | u8 bDeviceSubClass; | 589 | u8 bDeviceSubClass; |
279 | u8 bDeviceProtocol; | 590 | u8 bDeviceProtocol; |
280 | u8 bMaxPacketSize0; | 591 | u8 bMaxPacketSize0; |
281 | u8 bNumConfigurations; | 592 | u8 bNumConfigurations; |
282 | u8 bReserved; | 593 | u8 bReserved; |
283 | } __attribute__ ((packed)) USB_DeviceQualifierDescriptor; | 594 | } __attribute__ ((packed)) USB_DeviceQualifierDescriptor; |
284 | 595 | ||
285 | 596 | ||
286 | typedef struct { | 597 | typedef struct { |
287 | u8 bLength; | 598 | u8 bLength; |
288 | u8 bDescriptorType; | 599 | u8 bDescriptorType; |
289 | u16 wTotalLength; | 600 | u16 wTotalLength; |
290 | u8 bNumInterfaces; | 601 | u8 bNumInterfaces; |
291 | u8 bConfigurationValue; | 602 | u8 bConfigurationValue; |
292 | u8 iConfiguration; | 603 | u8 iConfiguration; |
293 | u8 bmAttributes; | 604 | u8 bmAttributes; |
294 | u8 MaxPower; | 605 | u8 MaxPower; |
295 | } __attribute__ ((packed)) USB_ConfigDescriptor; | 606 | } __attribute__ ((packed)) USB_ConfigDescriptor; |
296 | 607 | ||
297 | 608 | ||
298 | typedef struct { | 609 | typedef struct { |
299 | u8 bLength; | 610 | u8 bLength; |
300 | u8 bDescriptorType; | 611 | u8 bDescriptorType; |
301 | u16 wTotalLength; | 612 | u16 wTotalLength; |
302 | u8 bNumInterfaces; | 613 | u8 bNumInterfaces; |
303 | u8 bConfigurationValue; | 614 | u8 bConfigurationValue; |
304 | u8 iConfiguration; | 615 | u8 iConfiguration; |
305 | u8 bmAttributes; | 616 | u8 bmAttributes; |
306 | u8 bMaxPower; | 617 | u8 bMaxPower; |
307 | } __attribute__ ((packed)) USB_OtherSpeedConfigDescriptor; | 618 | } __attribute__ ((packed)) USB_OtherSpeedConfigDescriptor; |
308 | 619 | ||
309 | 620 | ||
310 | typedef struct { | 621 | typedef struct { |
311 | u8 bLength; | 622 | u8 bLength; |
312 | u8 bDescriptorType; | 623 | u8 bDescriptorType; |
313 | u8 bInterfaceNumber; | 624 | u8 bInterfaceNumber; |
314 | u8 bAlternateSetting; | 625 | u8 bAlternateSetting; |
315 | u8 bNumEndpoints; | 626 | u8 bNumEndpoints; |
316 | u8 bInterfaceClass; | 627 | u8 bInterfaceClass; |
317 | u8 bInterfaceSubClass; | 628 | u8 bInterfaceSubClass; |
318 | u8 bInterfaceProtocol; | 629 | u8 bInterfaceProtocol; |
319 | u8 iInterface; | 630 | u8 iInterface; |
320 | } __attribute__ ((packed)) USB_InterfaceDescriptor; | 631 | } __attribute__ ((packed)) USB_InterfaceDescriptor; |
321 | 632 | ||
322 | 633 | ||
323 | typedef struct { | 634 | typedef struct { |
324 | u8 bLegth; | 635 | u8 bLegth; |
325 | u8 bDescriptorType; | 636 | u8 bDescriptorType; |
326 | u8 bEndpointAddress; | 637 | u8 bEndpointAddress; |
327 | u8 bmAttributes; | 638 | u8 bmAttributes; |
328 | u16 wMaxPacketSize; | 639 | u16 wMaxPacketSize; |
329 | u8 bInterval; | 640 | u8 bInterval; |
330 | } __attribute__ ((packed)) USB_EndPointDescriptor; | 641 | } __attribute__ ((packed)) USB_EndPointDescriptor; |
331 | 642 | ||
332 | 643 | ||
333 | typedef struct { | 644 | typedef struct { |
334 | u8 bLength; | 645 | u8 bLength; |
335 | u8 bDescriptorType; | 646 | u8 bDescriptorType; |
336 | u16 SomeDesriptor[1]; | 647 | u16 SomeDesriptor[1]; |
337 | } __attribute__ ((packed)) USB_StringDescriptor; | 648 | } __attribute__ ((packed)) USB_StringDescriptor; |
338 | //------------------------------------------ | 649 | //------------------------------------------ |
339 | #define MAX_EP0_SIZE 64 | 650 | #define MAX_EP0_SIZE 64 |
340 | #define MAX_EP1_SIZE 512 | 651 | #define MAX_EP1_SIZE 512 |
341 | 652 | ||
342 | #define USB_HS 0 | 653 | #define USB_HS 0 |
343 | #define USB_FS 1 | 654 | #define USB_FS 1 |
344 | #define USB_LS 2 | 655 | #define USB_LS 2 |
345 | 656 | ||
346 | //definitions of EP0 | 657 | //definitions of EP0 |
347 | #define USB_EP0_IDLE 0 | 658 | #define USB_EP0_IDLE 0 |
348 | #define USB_EP0_RX 1 | 659 | #define USB_EP0_RX 1 |
349 | #define USB_EP0_TX 2 | 660 | #define USB_EP0_TX 2 |
350 | /* Define maximum packet size for endpoint 0 */ | 661 | /* Define maximum packet size for endpoint 0 */ |
351 | #define M_EP0_MAXP 64 | 662 | #define M_EP0_MAXP 64 |
352 | /* Endpoint 0 status structure */ | 663 | /* Endpoint 0 status structure */ |
353 | 664 | ||
354 | static __inline__ void usb_setb(u32 port, u8 val) | 665 | static __inline__ void usb_setb(u32 port, u8 val) |
355 | { | 666 | { |
356 | volatile u8 *ioport = (volatile u8 *)(port); | 667 | volatile u8 *ioport = (volatile u8 *)(port); |
357 | *ioport = (*ioport) | val; | 668 | *ioport = (*ioport) | val; |
358 | } | 669 | } |
359 | 670 | ||
360 | static __inline__ void usb_clearb(u32 port, u8 val) | 671 | static __inline__ void usb_clearb(u32 port, u8 val) |
361 | { | 672 | { |
362 | volatile u8 *ioport = (volatile u8 *)(port); | 673 | volatile u8 *ioport = (volatile u8 *)(port); |
363 | *ioport = (*ioport) & ~val; | 674 | *ioport = (*ioport) & ~val; |
364 | } | 675 | } |
365 | 676 | ||
366 | static __inline__ void usb_setw(u32 port, u16 val) | 677 | static __inline__ void usb_setw(u32 port, u16 val) |
367 | { | 678 | { |
368 | volatile u16 *ioport = (volatile u16 *)(port); | 679 | volatile u16 *ioport = (volatile u16 *)(port); |
369 | *ioport = (*ioport) | val; | 680 | *ioport = (*ioport) | val; |
370 | } | 681 | } |
371 | 682 | ||
372 | static __inline__ void usb_clearw(u32 port, u16 val) | 683 | static __inline__ void usb_clearw(u32 port, u16 val) |
373 | { | 684 | { |
374 | volatile u16 *ioport = (volatile u16 *)(port); | 685 | volatile u16 *ioport = (volatile u16 *)(port); |
375 | *ioport = (*ioport) & ~val; | 686 | *ioport = (*ioport) & ~val; |
376 | } | 687 | } |
377 | //--------------------------------- | 688 | //--------------------------------- |
378 | #define BULK_OUT_BUF_SIZE 0x20000 //buffer size : | 689 | #define BULK_OUT_BUF_SIZE 0x20000 //buffer size : |
@@ -380,118 +691,118 @@ static __inline__ void usb_clearw(u32 port, u16 val) | |||
380 | 691 | ||
381 | enum UDC_STATE | 692 | enum UDC_STATE |
382 | { | 693 | { |
383 | IDLE, | 694 | IDLE, |
384 | BULK_IN, | 695 | BULK_IN, |
385 | BULK_OUT | 696 | BULK_OUT |
386 | }; | 697 | }; |
387 | 698 | ||
388 | enum USB_JZ4740_REQUEST //add for USB_BOOT | 699 | enum USB_JZ4740_REQUEST //add for USB_BOOT |
389 | { | 700 | { |
390 | VR_GET_CUP_INFO = 0, | 701 | VR_GET_CUP_INFO = 0, |
391 | VR_SET_DATA_ADDERSS, | 702 | VR_SET_DATA_ADDERSS, |
392 | VR_SET_DATA_LENGTH, | 703 | VR_SET_DATA_LENGTH, |
393 | VR_FLUSH_CACHES, | 704 | VR_FLUSH_CACHES, |
394 | VR_PROGRAM_START1, | 705 | VR_PROGRAM_START1, |
395 | VR_PROGRAM_START2, | 706 | VR_PROGRAM_START2, |
396 | VR_NOR_OPS, | 707 | VR_NOR_OPS, |
397 | VR_NAND_OPS, | 708 | VR_NAND_OPS, |
398 | VR_SDRAM_OPS, | 709 | VR_SDRAM_OPS, |
399 | VR_CONFIGRATION | 710 | VR_CONFIGRATION |
400 | }; | 711 | }; |
401 | 712 | ||
402 | enum NOR_OPS_TYPE | 713 | enum NOR_OPS_TYPE |
403 | { | 714 | { |
404 | NOR_INIT = 0, | 715 | NOR_INIT = 0, |
405 | NOR_QUERY, | 716 | NOR_QUERY, |
406 | NOR_WRITE, | 717 | NOR_WRITE, |
407 | NOR_ERASE_CHIP, | 718 | NOR_ERASE_CHIP, |
408 | NOR_ERASE_SECTOR | 719 | NOR_ERASE_SECTOR |
409 | }; | 720 | }; |
410 | 721 | ||
411 | enum NOR_FLASH_TYPE | 722 | enum NOR_FLASH_TYPE |
412 | { | 723 | { |
413 | NOR_AM29 = 0, | 724 | NOR_AM29 = 0, |
414 | NOR_SST28, | 725 | NOR_SST28, |
415 | NOR_SST39x16, | 726 | NOR_SST39x16, |
416 | NOR_SST39x8 | 727 | NOR_SST39x8 |
417 | }; | 728 | }; |
418 | 729 | ||
419 | enum NAND_OPS_TYPE | 730 | enum NAND_OPS_TYPE |
420 | { | 731 | { |
421 | NAND_QUERY = 0, | 732 | NAND_QUERY = 0, |
422 | NAND_INIT, | 733 | NAND_INIT, |
423 | NAND_MARK_BAD, | 734 | NAND_MARK_BAD, |
424 | NAND_READ_OOB, | 735 | NAND_READ_OOB, |
425 | NAND_READ_RAW, | 736 | NAND_READ_RAW, |
426 | NAND_ERASE, | 737 | NAND_ERASE, |
427 | NAND_READ, | 738 | NAND_READ, |
428 | NAND_PROGRAM, | 739 | NAND_PROGRAM, |
429 | NAND_READ_TO_RAM | 740 | NAND_READ_TO_RAM |
430 | }; | 741 | }; |
431 | 742 | ||
432 | enum SDRAM_OPS_TYPE | 743 | enum SDRAM_OPS_TYPE |
433 | { | 744 | { |
434 | SDRAM_LOAD, | 745 | SDRAM_LOAD, |
435 | 746 | ||
436 | }; | 747 | }; |
437 | 748 | ||
438 | enum DATA_STRUCTURE_OB | 749 | enum DATA_STRUCTURE_OB |
439 | { | 750 | { |
440 | DS_flash_info , | 751 | DS_flash_info , |
441 | DS_hand | 752 | DS_hand |
442 | }; | 753 | }; |
443 | 754 | ||
444 | 755 | ||
445 | /*typedef enum _USB_BOOT_STATUS | 756 | /*typedef enum _USB_BOOT_STATUS |
446 | { | 757 | { |
447 | USB_NO_ERR =0 , | 758 | USB_NO_ERR =0 , |
448 | GET_CPU_INFO_ERR, | 759 | GET_CPU_INFO_ERR, |
449 | SET_DATA_ADDRESS_ERR, | 760 | SET_DATA_ADDRESS_ERR, |
450 | SET_DATA_LENGTH_ERR, | 761 | SET_DATA_LENGTH_ERR, |
451 | FLUSH_CAHCES_ERR, | 762 | FLUSH_CAHCES_ERR, |
452 | PROGRAM_START1_ERR, | 763 | PROGRAM_START1_ERR, |
453 | PROGRAM_START2_ERR, | 764 | PROGRAM_START2_ERR, |
454 | NOR_OPS_ERR, | 765 | NOR_OPS_ERR, |
455 | NAND_OPS_ERR, | 766 | NAND_OPS_ERR, |
456 | NOR_FLASHTYPE_ERR, | 767 | NOR_FLASHTYPE_ERR, |
457 | OPS_NOTSUPPORT_ERR | 768 | OPS_NOTSUPPORT_ERR |
458 | }USB_BOOT_STATUS;*/ | 769 | }USB_BOOT_STATUS;*/ |
459 | 770 | ||
460 | enum OPTION | 771 | enum OPTION |
461 | { | 772 | { |
462 | OOB_ECC, | 773 | OOB_ECC, |
463 | OOB_NO_ECC, | 774 | OOB_NO_ECC, |
464 | NO_OOB, | 775 | NO_OOB, |
465 | }; | 776 | }; |
466 | //------------------------- | 777 | //------------------------- |
467 | static inline void jz_writeb(u32 address, u8 value) | 778 | static inline void jz_writeb(u32 address, u8 value) |
468 | { | 779 | { |
469 | *((volatile u8 *)address) = value; | 780 | *((volatile u8 *)address) = value; |
470 | } | 781 | } |
471 | 782 | ||
472 | static inline void jz_writew(u32 address, u16 value) | 783 | static inline void jz_writew(u32 address, u16 value) |
473 | { | 784 | { |
474 | *((volatile u16 *)address) = value; | 785 | *((volatile u16 *)address) = value; |
475 | } | 786 | } |
476 | 787 | ||
477 | static inline void jz_writel(u32 address, u32 value) | 788 | static inline void jz_writel(u32 address, u32 value) |
478 | { | 789 | { |
479 | *((volatile u32 *)address) = value; | 790 | *((volatile u32 *)address) = value; |
480 | } | 791 | } |
481 | 792 | ||
482 | static inline u8 jz_readb(u32 address) | 793 | static inline u8 jz_readb(u32 address) |
483 | { | 794 | { |
484 | return *((volatile u8 *)address); | 795 | return *((volatile u8 *)address); |
485 | } | 796 | } |
486 | 797 | ||
487 | static inline u16 jz_readw(u32 address) | 798 | static inline u16 jz_readw(u32 address) |
488 | { | 799 | { |
489 | return *((volatile u16 *)address); | 800 | return *((volatile u16 *)address); |
490 | } | 801 | } |
491 | 802 | ||
492 | static inline u32 jz_readl(u32 address) | 803 | static inline u32 jz_readl(u32 address) |
493 | { | 804 | { |
494 | return *((volatile u32 *)address); | 805 | return *((volatile u32 *)address); |
495 | } | 806 | } |
496 | //--------------------------- | 807 | //--------------------------- |
497 | 808 | ||
@@ -510,530 +821,560 @@ static u8 ep0state,USB_Version; | |||
510 | 821 | ||
511 | static u32 fifoaddr[] = | 822 | static u32 fifoaddr[] = |
512 | { | 823 | { |
513 | TXFIFOEP0, TXFIFOEP0+4 ,TXFIFOEP0+8 | 824 | TXFIFOEP0, TXFIFOEP0+4 ,TXFIFOEP0+8 |
514 | }; | 825 | }; |
515 | 826 | ||
516 | static u32 fifosize[] = { | 827 | static u32 fifosize[] = { |
517 | MAX_EP0_SIZE, MAX_EP1_SIZE | 828 | MAX_EP0_SIZE, MAX_EP1_SIZE |
518 | }; | 829 | }; |
519 | 830 | ||
520 | static void udcReadFifo(u8 *ptr, int size) | 831 | static void udcReadFifo(u8 *ptr, int size) |
521 | { | 832 | { |
522 | u32 *d = (u32 *)ptr; | 833 | u32 *d = (u32 *)ptr; |
523 | int s; | 834 | int s; |
524 | s = (size + 3) >> 2; | 835 | s = (size + 3) >> 2; |
525 | while (s--) | 836 | while (s--) |
526 | *d++ = REG32(fifo); | 837 | *d++ = REG32(fifo); |
527 | } | 838 | } |
528 | 839 | ||
529 | static void udcWriteFifo(u8 *ptr, int size) | 840 | static void udcWriteFifo(u8 *ptr, int size) |
530 | { | 841 | { |
531 | u32 *d = (u32 *)ptr; | 842 | u32 *d = (u32 *)ptr; |
532 | u8 *c; | 843 | u8 *c; |
533 | int s, q; | 844 | int s, q; |
534 | 845 | ||
535 | if (size > 0) { | 846 | if (size > 0) { |
536 | s = size >> 2; | 847 | s = size >> 2; |
537 | while (s--) | 848 | while (s--) |
538 | REG32(fifo) = *d++; | 849 | REG32(fifo) = *d++; |
539 | q = size & 3; | 850 | q = size & 3; |
540 | if (q) { | 851 | if (q) { |
541 | c = (u8 *)d; | 852 | c = (u8 *)d; |
542 | while (q--) | 853 | while (q--) |
543 | REG8(fifo) = *c++; | 854 | REG8(fifo) = *c++; |
544 | } | 855 | } |
545 | } | 856 | } |
546 | } | 857 | } |
547 | 858 | ||
548 | void HW_SendPKT(int ep, const u8 *buf, int size) | 859 | void HW_SendPKT(int ep, const u8 *buf, int size) |
549 | { | 860 | { |
550 | fifo = fifoaddr[ep]; | 861 | fifo = fifoaddr[ep]; |
551 | 862 | ||
552 | if (ep!=0) | 863 | if (ep!=0) |
553 | { | 864 | { |
554 | Bulk_in_size = size; | 865 | Bulk_in_size = size; |
555 | Bulk_in_finish = 0; | 866 | Bulk_in_finish = 0; |
556 | jz_writeb(USB_REG_INDEX, ep); | 867 | jz_writeb(USB_REG_INDEX, ep); |
557 | if (Bulk_in_size - Bulk_in_finish <= fifosize[ep]) | 868 | if (Bulk_in_size - Bulk_in_finish <= fifosize[ep]) |
558 | { | 869 | { |
559 | udcWriteFifo((u8 *)((u32)buf+Bulk_in_finish), | 870 | udcWriteFifo((u8 *)((u32)buf+Bulk_in_finish), |
560 | Bulk_in_size - Bulk_in_finish); | 871 | Bulk_in_size - Bulk_in_finish); |
561 | usb_setb(USB_REG_INCSR, USB_INCSR_INPKTRDY); | 872 | usb_setb(USB_REG_INCSR, USB_INCSR_INPKTRDY); |
562 | Bulk_in_finish = Bulk_in_size; | 873 | Bulk_in_finish = Bulk_in_size; |
563 | } | 874 | } |
564 | else | 875 | else |
565 | { | 876 | { |
566 | udcWriteFifo((u8 *)((u32)buf+Bulk_in_finish), | 877 | udcWriteFifo((u8 *)((u32)buf+Bulk_in_finish), |
567 | fifosize[ep]); | 878 | fifosize[ep]); |
568 | usb_setb(USB_REG_INCSR, USB_INCSR_INPKTRDY); | 879 | usb_setb(USB_REG_INCSR, USB_INCSR_INPKTRDY); |
569 | Bulk_in_finish += fifosize[ep]; | 880 | Bulk_in_finish += fifosize[ep]; |
570 | Bulk_in_buf = (u8*)buf; | 881 | Bulk_in_buf = (u8*)buf; |
571 | } | 882 | } |
572 | } | 883 | } |
573 | else //EP0 | 884 | else //EP0 |
574 | { | 885 | { |
575 | tx_size = size; | 886 | tx_size = size; |
576 | finished = 0; | 887 | finished = 0; |
577 | memcpy((void *)tx_buf, buf, size); | 888 | memcpy((void *)tx_buf, buf, size); |
578 | ep0state = USB_EP0_TX; | 889 | ep0state = USB_EP0_TX; |
579 | } | 890 | } |
891 | } | ||
892 | |||
893 | void HW_GetPKT(int ep, const u8 *buf, unsigned int size) | ||
894 | { | ||
895 | memcpy((void *)buf, (u8 *)rx_buf, size); | ||
896 | fifo = fifoaddr[ep]; | ||
897 | if (rx_size > size) | ||
898 | rx_size -= size; | ||
899 | else | ||
900 | { | ||
901 | size = rx_size; | ||
902 | rx_size = 0; | ||
903 | } | ||
904 | memcpy((u8 *)rx_buf, (u8 *)((u32)rx_buf+size), rx_size); | ||
905 | } | ||
906 | |||
907 | void Enable_DMA(u8* buf, u32 length) | ||
908 | { | ||
909 | dma_cache_wback_inv((u32)buf, length); | ||
910 | jz_writeb(USB_REG_INDEX, 1); | ||
911 | usb_setw(USB_REG_INCSR, 0x9400); | ||
912 | usb_clearw(USB_REG_INTRINE, 0x2); //disable OUT intr | ||
913 | jz_writel(USB_REG_ADDR1, (u32)buf); | ||
914 | jz_writel(USB_REG_COUNT1, length); | ||
915 | jz_writel(USB_REG_CNTL1, 0x001f); | ||
580 | } | 916 | } |
581 | 917 | ||
582 | void HW_GetPKT(int ep, const u8 *buf, int size) | 918 | void Disable_DMA(void) |
583 | { | 919 | { |
584 | memcpy((void *)buf, (u8 *)rx_buf, size); | 920 | jz_writeb(USB_REG_INDEX, 1); |
585 | fifo = fifoaddr[ep]; | 921 | usb_clearw(USB_REG_INCSR, 0x9400); |
586 | if (rx_size > size) | 922 | usb_setw(USB_REG_INTRINE, 0x2); //Enable OUT intr |
587 | rx_size -= size; | ||
588 | else { | ||
589 | size = rx_size; | ||
590 | rx_size = 0; | ||
591 | } | ||
592 | memcpy((u8 *)rx_buf, (u8 *)((u32)rx_buf+size), rx_size); | ||
593 | } | 923 | } |
594 | 924 | ||
595 | static USB_DeviceDescriptor devDesc = | 925 | static USB_DeviceDescriptor devDesc = |
596 | { | 926 | { |
597 | sizeof(USB_DeviceDescriptor), | 927 | sizeof(USB_DeviceDescriptor), |
598 | DEVICE_DESCRIPTOR, //1 | 928 | DEVICE_DESCRIPTOR, //1 |
599 | 0x0200, //Version 2.0 | 929 | 0x0200, //Version 2.0 |
600 | 0xff, //Vendor spec class | 930 | 0xff, //Vendor spec class |
601 | 0xff, | 931 | 0xff, |
602 | 0xff, | 932 | 0xff, |
603 | 64, /* Ep0 FIFO size */ | 933 | 64, /* Ep0 FIFO size */ |
604 | 0x601a, //vendor ID | 934 | 0x601a, //vendor ID |
605 | 0xDEAD, //Product ID | 935 | 0xDEAD, //Product ID |
606 | 0xffff, | 936 | 0xffff, |
607 | 0x00, | 937 | 0x00, |
608 | 0x00, | 938 | 0x00, |
609 | 0x00, | 939 | 0x00, |
610 | 0x01 | 940 | 0x01 |
611 | }; | 941 | }; |
612 | 942 | ||
613 | #define CONFIG_DESCRIPTOR_LEN (sizeof(USB_ConfigDescriptor) + \ | 943 | #define CONFIG_DESCRIPTOR_LEN (sizeof(USB_ConfigDescriptor) + \ |
614 | sizeof(USB_InterfaceDescriptor) + \ | 944 | sizeof(USB_InterfaceDescriptor) + \ |
615 | sizeof(USB_EndPointDescriptor) * 2) | 945 | sizeof(USB_EndPointDescriptor) * 2) |
616 | 946 | ||
617 | static struct { | 947 | static struct { |
618 | USB_ConfigDescriptor configuration_descriptor; | 948 | USB_ConfigDescriptor configuration_descriptor; |
619 | USB_InterfaceDescriptor interface_descritor; | 949 | USB_InterfaceDescriptor interface_descritor; |
620 | USB_EndPointDescriptor endpoint_descriptor[2]; | 950 | USB_EndPointDescriptor endpoint_descriptor[2]; |
621 | } __attribute__ ((packed)) confDesc = { | 951 | } __attribute__ ((packed)) confDesc = { |
622 | { | 952 | { |
623 | sizeof(USB_ConfigDescriptor), | 953 | sizeof(USB_ConfigDescriptor), |
624 | CONFIGURATION_DESCRIPTOR, | 954 | CONFIGURATION_DESCRIPTOR, |
625 | CONFIG_DESCRIPTOR_LEN, | 955 | CONFIG_DESCRIPTOR_LEN, |
626 | 0x01, | 956 | 0x01, |
627 | 0x01, | 957 | 0x01, |
628 | 0x00, | 958 | 0x00, |
629 | 0xc0, // Self Powered, no remote wakeup | 959 | 0xc0, // Self Powered, no remote wakeup |
630 | 0x64 // Maximum power consumption 2000 mA | 960 | 0x64 // Maximum power consumption 2000 mA |
631 | }, | 961 | }, |
632 | { | 962 | { |
633 | sizeof(USB_InterfaceDescriptor), | 963 | sizeof(USB_InterfaceDescriptor), |
634 | INTERFACE_DESCRIPTOR, | 964 | INTERFACE_DESCRIPTOR, |
635 | 0x00, | 965 | 0x00, |
636 | 0x00, | 966 | 0x00, |
637 | 0x02, /* ep number */ | 967 | 0x02, /* ep number */ |
638 | 0xff, | 968 | 0xff, |
639 | 0xff, | 969 | 0xff, |
640 | 0xff, | 970 | 0xff, |
641 | 0x00 | 971 | 0x00 |
642 | }, | 972 | }, |
643 | { | 973 | { |
644 | { | 974 | { |
645 | sizeof(USB_EndPointDescriptor), | 975 | sizeof(USB_EndPointDescriptor), |
646 | ENDPOINT_DESCRIPTOR, | 976 | ENDPOINT_DESCRIPTOR, |
647 | (1 << 7) | 1,// endpoint 2 is IN endpoint | 977 | (1 << 7) | 1,// endpoint 2 is IN endpoint |
648 | 2, /* bulk */ | 978 | 2, /* bulk */ |
649 | 512, | 979 | 512, |
650 | 0 | 980 | 0 |
651 | }, | 981 | }, |
652 | { | 982 | { |
653 | sizeof(USB_EndPointDescriptor), | 983 | sizeof(USB_EndPointDescriptor), |
654 | ENDPOINT_DESCRIPTOR, | 984 | ENDPOINT_DESCRIPTOR, |
655 | (0 << 7) | 1,// endpoint 5 is OUT endpoint | 985 | (0 << 7) | 1,// endpoint 5 is OUT endpoint |
656 | 2, /* bulk */ | 986 | 2, /* bulk */ |
657 | 512, /* OUT EP FIFO size */ | 987 | 512, /* OUT EP FIFO size */ |
658 | 0 | 988 | 0 |
659 | } | 989 | } |
660 | } | 990 | } |
661 | }; | 991 | }; |
662 | 992 | ||
663 | void sendDevDescString(int size) | 993 | void sendDevDescString(int size) |
664 | { | 994 | { |
665 | u16 str_ret[13] = { | 995 | u16 str_ret[13] = { |
666 | 0x031a,//0x1a=26 byte | 996 | 0x031a,//0x1a=26 byte |
667 | 0x0041, | 997 | 0x0041, |
668 | 0x0030, | 998 | 0x0030, |
669 | 0x0030, | 999 | 0x0030, |
670 | 0x0041, | 1000 | 0x0041, |
671 | 0x0030, | 1001 | 0x0030, |
672 | 0x0030, | 1002 | 0x0030, |
673 | 0x0041, | 1003 | 0x0041, |
674 | 0x0030, | 1004 | 0x0030, |
675 | 0x0030, | 1005 | 0x0030, |
676 | 0x0041, | 1006 | 0x0041, |
677 | 0x0030, | 1007 | 0x0030, |
678 | 0x0030 | 1008 | 0x0030 |
679 | }; | 1009 | }; |
680 | if(size >= 26) | 1010 | if(size >= 26) |
681 | size = 26; | 1011 | size = 26; |
682 | str_ret[0] = (0x0300 | size); | 1012 | str_ret[0] = (0x0300 | size); |
683 | HW_SendPKT(0, (u8 *)str_ret,size); | 1013 | HW_SendPKT(0, (u8 *)str_ret,size); |
684 | } | 1014 | } |
685 | 1015 | ||
686 | void sendDevDesc(int size) | 1016 | void sendDevDesc(int size) |
687 | { | 1017 | { |
688 | switch (size) { | 1018 | switch (size) { |
689 | case 18: | 1019 | case 18: |
690 | HW_SendPKT(0, (u8 *)&devDesc, sizeof(devDesc)); | 1020 | HW_SendPKT(0, (u8 *)&devDesc, sizeof(devDesc)); |
691 | break; | 1021 | break; |
692 | default: | 1022 | default: |
693 | HW_SendPKT(0, (u8 *)&devDesc, 8); | 1023 | HW_SendPKT(0, (u8 *)&devDesc, 8); |
694 | break; | 1024 | break; |
695 | } | 1025 | } |
696 | } | 1026 | } |
697 | 1027 | ||
698 | void sendConfDesc(int size) | 1028 | void sendConfDesc(int size) |
699 | { | 1029 | { |
700 | switch (size) { | 1030 | switch (size) { |
701 | case 9: | 1031 | case 9: |
702 | HW_SendPKT(0, (u8 *)&confDesc, 9); | 1032 | HW_SendPKT(0, (u8 *)&confDesc, 9); |
703 | break; | 1033 | break; |
704 | case 8: | 1034 | case 8: |
705 | HW_SendPKT(0, (u8 *)&confDesc, 8); | 1035 | HW_SendPKT(0, (u8 *)&confDesc, 8); |
706 | break; | 1036 | break; |
707 | default: | 1037 | default: |
708 | HW_SendPKT(0, (u8 *)&confDesc, sizeof(confDesc)); | 1038 | HW_SendPKT(0, (u8 *)&confDesc, sizeof(confDesc)); |
709 | break; | 1039 | break; |
710 | } | 1040 | } |
711 | } | 1041 | } |
712 | 1042 | ||
713 | void EP0_init(u32 out, u32 out_size, u32 in, u32 in_size) | 1043 | void EP0_init(u32 out, u32 out_size, u32 in, u32 in_size) |
714 | { | 1044 | { |
715 | confDesc.endpoint_descriptor[0].bEndpointAddress = (1<<7) | in; | 1045 | confDesc.endpoint_descriptor[0].bEndpointAddress = (1<<7) | in; |
716 | confDesc.endpoint_descriptor[0].wMaxPacketSize = in_size; | 1046 | confDesc.endpoint_descriptor[0].wMaxPacketSize = in_size; |
717 | confDesc.endpoint_descriptor[1].bEndpointAddress = (0<<7) | out; | 1047 | confDesc.endpoint_descriptor[1].bEndpointAddress = (0<<7) | out; |
718 | confDesc.endpoint_descriptor[1].wMaxPacketSize = out_size; | 1048 | confDesc.endpoint_descriptor[1].wMaxPacketSize = out_size; |
719 | } | 1049 | } |
720 | 1050 | ||
721 | static void udc_reset(void) | 1051 | static void udc_reset(void) |
722 | { | 1052 | { |
723 | //data init | 1053 | //data init |
724 | ep0state = USB_EP0_IDLE; | 1054 | ep0state = USB_EP0_IDLE; |
725 | Bulk_in_size = 0; | 1055 | Bulk_in_size = 0; |
726 | Bulk_in_finish = 0; | 1056 | Bulk_in_finish = 0; |
727 | Bulk_out_size = 0; | 1057 | Bulk_out_size = 0; |
728 | udc_state = IDLE; | 1058 | udc_state = IDLE; |
729 | tx_size = 0; | 1059 | tx_size = 0; |
730 | rx_size = 0; | 1060 | rx_size = 0; |
731 | finished = 0; | 1061 | finished = 0; |
732 | /* Enable the USB PHY */ | 1062 | /* Enable the USB PHY */ |
733 | // REG_CPM_SCR |= CPM_SCR_USBPHY_ENABLE; | 1063 | // REG_CPM_SCR |= CPM_SCR_USBPHY_ENABLE; |
734 | /* Disable interrupts */ | 1064 | /* Disable interrupts */ |
735 | jz_writew(USB_REG_INTRINE, 0); | 1065 | jz_writew(USB_REG_INTRINE, 0); |
736 | jz_writew(USB_REG_INTROUTE, 0); | 1066 | jz_writew(USB_REG_INTROUTE, 0); |
737 | jz_writeb(USB_REG_INTRUSBE, 0); | 1067 | jz_writeb(USB_REG_INTRUSBE, 0); |
738 | jz_writeb(USB_REG_FADDR,0); | 1068 | jz_writeb(USB_REG_FADDR,0); |
739 | jz_writeb(USB_REG_POWER,0x60); //High speed | 1069 | jz_writeb(USB_REG_POWER,0x60); //High speed |
740 | jz_writeb(USB_REG_INDEX,0); | 1070 | jz_writeb(USB_REG_INDEX,0); |
741 | jz_writeb(USB_REG_CSR0,0xc0); | 1071 | jz_writeb(USB_REG_CSR0,0xc0); |
742 | jz_writeb(USB_REG_INDEX,1); | 1072 | jz_writeb(USB_REG_INDEX,1); |
743 | jz_writew(USB_REG_INMAXP,512); | 1073 | jz_writew(USB_REG_INMAXP,512); |
744 | jz_writew(USB_REG_INCSR,0x2048); | 1074 | jz_writew(USB_REG_INCSR,0x2048); |
745 | jz_writeb(USB_REG_INDEX,1); | 1075 | jz_writeb(USB_REG_INDEX,1); |
746 | jz_writew(USB_REG_OUTMAXP,512); | 1076 | jz_writew(USB_REG_OUTMAXP,512); |
747 | jz_writew(USB_REG_OUTCSR,0x0090); | 1077 | jz_writew(USB_REG_OUTCSR,0x0090); |
748 | jz_writew(USB_REG_INTRINE,0x3); //enable intr | 1078 | jz_writew(USB_REG_INTRINE,0x3); //enable intr |
749 | jz_writew(USB_REG_INTROUTE,0x2); | 1079 | jz_writew(USB_REG_INTROUTE,0x2); |
750 | jz_writeb(USB_REG_INTRUSBE,0x4); | 1080 | jz_writeb(USB_REG_INTRUSBE,0x4); |
751 | 1081 | ||
752 | if ((jz_readb(USB_REG_POWER)&0x10)==0) | 1082 | if ((jz_readb(USB_REG_POWER)&0x10)==0) |
753 | { | 1083 | { |
754 | jz_writeb(USB_REG_INDEX,1); | 1084 | jz_writeb(USB_REG_INDEX,1); |
755 | jz_writew(USB_REG_INMAXP,64); | 1085 | jz_writew(USB_REG_INMAXP,64); |
756 | jz_writew(USB_REG_INCSR,0x2048); | 1086 | jz_writew(USB_REG_INCSR,0x2048); |
757 | jz_writeb(USB_REG_INDEX,1); | 1087 | jz_writeb(USB_REG_INDEX,1); |
758 | jz_writew(USB_REG_OUTMAXP,64); | 1088 | jz_writew(USB_REG_OUTMAXP,64); |
759 | jz_writew(USB_REG_OUTCSR,0x0090); | 1089 | jz_writew(USB_REG_OUTCSR,0x0090); |
760 | USB_Version=USB_FS; | 1090 | USB_Version=USB_FS; |
761 | fifosize[1]=64; | 1091 | fifosize[1]=64; |
762 | EP0_init(1,64,1,64); | 1092 | EP0_init(1,64,1,64); |
763 | } | 1093 | } |
764 | else | 1094 | else |
765 | { | 1095 | { |
766 | jz_writeb(USB_REG_INDEX,1); | 1096 | jz_writeb(USB_REG_INDEX,1); |
767 | jz_writew(USB_REG_INMAXP,512); | 1097 | jz_writew(USB_REG_INMAXP,512); |
768 | jz_writew(USB_REG_INCSR,0x2048); | 1098 | jz_writew(USB_REG_INCSR,0x2048); |
769 | jz_writeb(USB_REG_INDEX,1); | 1099 | jz_writeb(USB_REG_INDEX,1); |
770 | jz_writew(USB_REG_OUTMAXP,512); | 1100 | jz_writew(USB_REG_OUTMAXP,512); |
771 | jz_writew(USB_REG_OUTCSR,0x0090); | 1101 | jz_writew(USB_REG_OUTCSR,0x0090); |
772 | USB_Version=USB_HS; | 1102 | USB_Version=USB_HS; |
773 | fifosize[1]=512; | 1103 | fifosize[1]=512; |
774 | EP0_init(1,512,1,512); | 1104 | EP0_init(1,512,1,512); |
775 | } | 1105 | } |
776 | 1106 | ||
777 | } | 1107 | } |
778 | 1108 | ||
779 | void usbHandleStandDevReq(u8 *buf) | 1109 | void usbHandleStandDevReq(u8 *buf) |
780 | { | 1110 | { |
781 | USB_DeviceRequest *dreq = (USB_DeviceRequest *)buf; | 1111 | USB_DeviceRequest *dreq = (USB_DeviceRequest *)buf; |
782 | switch (dreq->bRequest) { | 1112 | switch (dreq->bRequest) { |
783 | case GET_DESCRIPTOR: | 1113 | case GET_DESCRIPTOR: |
784 | if (dreq->bmRequestType == 0x80) /* Dev2Host */ | 1114 | if (dreq->bmRequestType == 0x80) /* Dev2Host */ |
785 | switch(dreq->wValue >> 8) | 1115 | switch(dreq->wValue >> 8) |
786 | { | 1116 | { |
787 | case DEVICE_DESCRIPTOR: | 1117 | case DEVICE_DESCRIPTOR: |
788 | sendDevDesc(dreq->wLength); | 1118 | sendDevDesc(dreq->wLength); |
789 | break; | 1119 | break; |
790 | case CONFIGURATION_DESCRIPTOR: | 1120 | case CONFIGURATION_DESCRIPTOR: |
791 | sendConfDesc(dreq->wLength); | 1121 | sendConfDesc(dreq->wLength); |
792 | break; | 1122 | break; |
793 | case STRING_DESCRIPTOR: | 1123 | case STRING_DESCRIPTOR: |
794 | if (dreq->wLength == 0x02) | 1124 | if (dreq->wLength == 0x02) |
795 | HW_SendPKT(0, "\x04\x03", 2); | 1125 | HW_SendPKT(0, "\x04\x03", 2); |
796 | else | 1126 | else |
797 | sendDevDescString(dreq->wLength); | 1127 | sendDevDescString(dreq->wLength); |
798 | //HW_SendPKT(0, "\x04\x03\x09\x04", 2); | 1128 | //HW_SendPKT(0, "\x04\x03\x09\x04", 2); |
799 | break; | 1129 | break; |
800 | } | 1130 | } |
801 | ep0state=USB_EP0_TX; | 1131 | ep0state=USB_EP0_TX; |
802 | 1132 | ||
803 | break; | 1133 | break; |
804 | case SET_ADDRESS: | 1134 | case SET_ADDRESS: |
805 | jz_writeb(USB_REG_FADDR,dreq->wValue); | 1135 | jz_writeb(USB_REG_FADDR,dreq->wValue); |
806 | break; | 1136 | break; |
807 | case GET_STATUS: | 1137 | case GET_STATUS: |
808 | switch (dreq->bmRequestType) { | 1138 | switch (dreq->bmRequestType) { |
809 | case 80: /* device */ | 1139 | case 80: /* device */ |
810 | HW_SendPKT(0, "\x01\x00", 2); | 1140 | HW_SendPKT(0, "\x01\x00", 2); |
811 | break; | 1141 | break; |
812 | case 81: /* interface */ | 1142 | case 81: /* interface */ |
813 | case 82: /* ep */ | 1143 | case 82: /* ep */ |
814 | HW_SendPKT(0, "\x00\x00", 2); | 1144 | HW_SendPKT(0, "\x00\x00", 2); |
815 | break; | 1145 | break; |
816 | } | 1146 | } |
817 | ep0state=USB_EP0_TX; | 1147 | ep0state=USB_EP0_TX; |
818 | break; | 1148 | break; |
819 | case CLEAR_FEATURE: | 1149 | case CLEAR_FEATURE: |
820 | case SET_CONFIGURATION: | 1150 | case SET_CONFIGURATION: |
821 | case SET_INTERFACE: | 1151 | case SET_INTERFACE: |
822 | case SET_FEATURE: | 1152 | case SET_FEATURE: |
823 | break; | 1153 | break; |
824 | } | 1154 | } |
825 | } | 1155 | } |
826 | 1156 | ||
827 | unsigned char nandbuffer[4096]; | 1157 | unsigned char nandbuffer[4096]; |
1158 | extern void jz_nand_read(int block, int page, unsigned char *buf); | ||
828 | 1159 | ||
829 | void usbHandleVendorReq(u8 *buf) | 1160 | void usbHandleVendorReq(u8 *buf) |
830 | { | 1161 | { |
831 | USB_DeviceRequest *dreq = (USB_DeviceRequest *)buf; | 1162 | USB_DeviceRequest *dreq = (USB_DeviceRequest *)buf; |
832 | switch (dreq->bRequest) | 1163 | switch (dreq->bRequest) |
833 | { | 1164 | { |
834 | case 0xB0: | 1165 | case 0xB0: |
835 | memset(&nandbuffer, 0, 4096); | 1166 | memset(&nandbuffer, 0, 4096); |
836 | jz_nand_read(dreq->wValue, dreq->wIndex, &nandbuffer); | 1167 | jz_nand_read(dreq->wValue, dreq->wIndex, nandbuffer); |
837 | //printf("Read block %d page %d", dreq->wValue, dreq->wIndex); | 1168 | //printf("Read block %d page %d", dreq->wValue, dreq->wIndex); |
838 | udc_state = IDLE; | 1169 | udc_state = IDLE; |
839 | break; | 1170 | break; |
840 | case 0xAB: | 1171 | case 0xAB: |
841 | HW_SendPKT(1, nandbuffer, 4096); | 1172 | Enable_DMA(nandbuffer, 4096); |
1173 | //HW_SendPKT(1, nandbuffer, 4096); | ||
842 | //printf("Send data"); | 1174 | //printf("Send data"); |
843 | //udc_state = BULK_OUT; | 1175 | //udc_state = BULK_OUT; |
844 | break; | 1176 | break; |
845 | case 0x12: | 1177 | case 0x12: |
846 | HW_SendPKT(0, "TEST", 4); | 1178 | HW_SendPKT(0, "TEST", 4); |
847 | //printf("Send test"); | 1179 | //printf("Send test"); |
848 | udc_state = IDLE; | 1180 | udc_state = IDLE; |
849 | break; | 1181 | break; |
850 | } | 1182 | } |
851 | } | 1183 | } |
852 | 1184 | ||
853 | void Handshake_PKT(void) | 1185 | void Handshake_PKT(void) |
854 | { | 1186 | { |
855 | if (udc_state!=IDLE) | 1187 | if (udc_state!=IDLE) |
856 | { | 1188 | { |
857 | HW_SendPKT(1,(u8 *)handshake_PKT,sizeof(handshake_PKT)); | 1189 | HW_SendPKT(1,(u8 *)handshake_PKT,sizeof(handshake_PKT)); |
858 | udc_state = IDLE; | 1190 | udc_state = IDLE; |
859 | } | 1191 | } |
860 | } | 1192 | } |
861 | 1193 | ||
862 | void usbHandleDevReq(u8 *buf) | 1194 | void usbHandleDevReq(u8 *buf) |
863 | { | 1195 | { |
864 | switch ((buf[0] & (3 << 5)) >> 5) { | 1196 | switch ((buf[0] & (3 << 5)) >> 5) { |
865 | case 0: /* Standard request */ | 1197 | case 0: /* Standard request */ |
866 | usbHandleStandDevReq(buf); | 1198 | usbHandleStandDevReq(buf); |
867 | break; | 1199 | break; |
868 | case 1: /* Class request */ | 1200 | case 1: /* Class request */ |
869 | break; | 1201 | break; |
870 | case 2: /* Vendor request */ | 1202 | case 2: /* Vendor request */ |
871 | usbHandleVendorReq(buf); | 1203 | usbHandleVendorReq(buf); |
872 | break; | 1204 | break; |
873 | } | 1205 | } |
874 | } | 1206 | } |
875 | 1207 | ||
876 | void EP0_Handler (void) | 1208 | void EP0_Handler (void) |
877 | { | 1209 | { |
878 | u8 byCSR0; | 1210 | u8 byCSR0; |
879 | 1211 | ||
880 | /* Read CSR0 */ | 1212 | /* Read CSR0 */ |
881 | jz_writeb(USB_REG_INDEX, 0); | 1213 | jz_writeb(USB_REG_INDEX, 0); |
882 | byCSR0 = jz_readb(USB_REG_CSR0); | 1214 | byCSR0 = jz_readb(USB_REG_CSR0); |
883 | 1215 | ||
884 | /* Check for SentStall | 1216 | /* Check for SentStall |
885 | if sendstall is set ,clear the sendstall bit*/ | 1217 | if sendstall is set ,clear the sendstall bit*/ |
886 | if (byCSR0 & USB_CSR0_SENTSTALL) | 1218 | if (byCSR0 & USB_CSR0_SENTSTALL) |
887 | { | 1219 | { |
888 | jz_writeb(USB_REG_CSR0, (byCSR0 & ~USB_CSR0_SENDSTALL)); | 1220 | jz_writeb(USB_REG_CSR0, (byCSR0 & ~USB_CSR0_SENDSTALL)); |
889 | ep0state = USB_EP0_IDLE; | 1221 | ep0state = USB_EP0_IDLE; |
890 | return; | 1222 | return; |
891 | } | 1223 | } |
892 | 1224 | ||
893 | /* Check for SetupEnd */ | 1225 | /* Check for SetupEnd */ |
894 | if (byCSR0 & USB_CSR0_SETUPEND) | 1226 | if (byCSR0 & USB_CSR0_SETUPEND) |
895 | { | 1227 | { |
896 | jz_writeb(USB_REG_CSR0, (byCSR0 | USB_CSR0_SVDSETUPEND)); | 1228 | jz_writeb(USB_REG_CSR0, (byCSR0 | USB_CSR0_SVDSETUPEND)); |
897 | ep0state = USB_EP0_IDLE; | 1229 | ep0state = USB_EP0_IDLE; |
898 | return; | 1230 | return; |
899 | } | 1231 | } |
900 | /* Call relevant routines for endpoint 0 state */ | 1232 | /* Call relevant routines for endpoint 0 state */ |
901 | if (ep0state == USB_EP0_IDLE) | 1233 | if (ep0state == USB_EP0_IDLE) |
902 | { | 1234 | { |
903 | if (byCSR0 & USB_CSR0_OUTPKTRDY) //There are datas in fifo | 1235 | if (byCSR0 & USB_CSR0_OUTPKTRDY) //There are datas in fifo |
904 | { | 1236 | { |
905 | USB_DeviceRequest *dreq; | 1237 | USB_DeviceRequest *dreq; |
906 | fifo=fifoaddr[0]; | 1238 | fifo=fifoaddr[0]; |
907 | udcReadFifo((u8 *)rx_buf, sizeof(USB_DeviceRequest)); | 1239 | udcReadFifo((u8 *)rx_buf, sizeof(USB_DeviceRequest)); |
908 | usb_setb(USB_REG_CSR0, 0x48);//clear OUTRD bit | 1240 | usb_setb(USB_REG_CSR0, 0x48);//clear OUTRD bit |
909 | dreq = (USB_DeviceRequest *)rx_buf; | 1241 | dreq = (USB_DeviceRequest *)rx_buf; |
910 | usbHandleDevReq((u8 *)rx_buf); | 1242 | usbHandleDevReq((u8 *)rx_buf); |
911 | } | 1243 | } |
912 | rx_size = 0; | 1244 | rx_size = 0; |
913 | } | 1245 | } |
914 | 1246 | ||
915 | if (ep0state == USB_EP0_TX) | 1247 | if (ep0state == USB_EP0_TX) |
916 | { | 1248 | { |
917 | fifo=fifoaddr[0]; | 1249 | fifo=fifoaddr[0]; |
918 | if (tx_size - finished <= 64) | 1250 | if (tx_size - finished <= 64) |
919 | { | 1251 | { |
920 | udcWriteFifo((u8 *)((u32)tx_buf+finished), | 1252 | udcWriteFifo((u8 *)((u32)tx_buf+finished), |
921 | tx_size - finished); | 1253 | tx_size - finished); |
922 | finished = tx_size; | 1254 | finished = tx_size; |
923 | usb_setb(USB_REG_CSR0, USB_CSR0_INPKTRDY); | 1255 | usb_setb(USB_REG_CSR0, USB_CSR0_INPKTRDY); |
924 | usb_setb(USB_REG_CSR0, USB_CSR0_DATAEND); //Set dataend! | 1256 | usb_setb(USB_REG_CSR0, USB_CSR0_DATAEND); //Set dataend! |
925 | ep0state=USB_EP0_IDLE; | 1257 | ep0state=USB_EP0_IDLE; |
926 | } else | 1258 | } else |
927 | { | 1259 | { |
928 | udcWriteFifo((u8 *)((u32)tx_buf+finished), 64); | 1260 | udcWriteFifo((u8 *)((u32)tx_buf+finished), 64); |
929 | usb_setb(USB_REG_CSR0, USB_CSR0_INPKTRDY); | 1261 | usb_setb(USB_REG_CSR0, USB_CSR0_INPKTRDY); |
930 | finished += 64; | 1262 | finished += 64; |
931 | } | 1263 | } |
932 | } | 1264 | } |
933 | return; | 1265 | return; |
934 | } | 1266 | } |
935 | 1267 | ||
936 | void EPIN_Handler(u8 EP) | 1268 | void EPIN_Handler(u8 EP) |
937 | { | 1269 | { |
938 | jz_writeb(USB_REG_INDEX, EP); | 1270 | jz_writeb(USB_REG_INDEX, EP); |
939 | fifo = fifoaddr[EP]; | 1271 | fifo = fifoaddr[EP]; |
940 | 1272 | ||
941 | if (Bulk_in_size-Bulk_in_finish==0) | 1273 | if (Bulk_in_size-Bulk_in_finish==0) |
942 | { | 1274 | { |
943 | Handshake_PKT(); | 1275 | Handshake_PKT(); |
944 | return; | 1276 | return; |
945 | } | 1277 | } |
946 | 1278 | ||
947 | if (Bulk_in_size - Bulk_in_finish <= fifosize[EP]) | 1279 | if (Bulk_in_size - Bulk_in_finish <= fifosize[EP]) |
948 | { | 1280 | { |
949 | udcWriteFifo((u8 *)((u32)Bulk_in_buf+Bulk_in_finish), | 1281 | udcWriteFifo((u8 *)((u32)Bulk_in_buf+Bulk_in_finish), |
950 | Bulk_in_size - Bulk_in_finish); | 1282 | Bulk_in_size - Bulk_in_finish); |
951 | usb_setw(USB_REG_INCSR, USB_INCSR_INPKTRDY); | 1283 | usb_setw(USB_REG_INCSR, USB_INCSR_INPKTRDY); |
952 | Bulk_in_finish = Bulk_in_size; | 1284 | Bulk_in_finish = Bulk_in_size; |
953 | } | 1285 | } |
954 | else | 1286 | else |
955 | { | 1287 | { |
956 | udcWriteFifo((u8 *)((u32)Bulk_in_buf+Bulk_in_finish), | 1288 | udcWriteFifo((u8 *)((u32)Bulk_in_buf+Bulk_in_finish), |
957 | fifosize[EP]); | 1289 | fifosize[EP]); |
958 | usb_setw(USB_REG_INCSR, USB_INCSR_INPKTRDY); | 1290 | usb_setw(USB_REG_INCSR, USB_INCSR_INPKTRDY); |
959 | Bulk_in_finish += fifosize[EP]; | 1291 | Bulk_in_finish += fifosize[EP]; |
960 | } | 1292 | } |
961 | } | 1293 | } |
962 | 1294 | ||
963 | void EPOUT_Handler(u8 EP) | 1295 | void EPOUT_Handler(u8 EP) |
964 | { | 1296 | { |
965 | u32 size; | 1297 | u32 size; |
966 | jz_writeb(USB_REG_INDEX, EP); | 1298 | jz_writeb(USB_REG_INDEX, EP); |
967 | size = jz_readw(USB_REG_OUTCOUNT); | 1299 | size = jz_readw(USB_REG_OUTCOUNT); |
968 | fifo = fifoaddr[EP]; | 1300 | fifo = fifoaddr[EP]; |
969 | udcReadFifo((u8 *)((u32)Bulk_out_buf+Bulk_out_size), size); | 1301 | udcReadFifo((u8 *)((u32)Bulk_out_buf+Bulk_out_size), size); |
970 | usb_clearb(USB_REG_OUTCSR,USB_OUTCSR_OUTPKTRDY); | 1302 | usb_clearb(USB_REG_OUTCSR,USB_OUTCSR_OUTPKTRDY); |
971 | Bulk_out_size += size; | 1303 | Bulk_out_size += size; |
972 | } | 1304 | } |
973 | 1305 | ||
974 | void UDC(void) | 1306 | void UDC(void) |
975 | { | 1307 | { |
976 | u8 IntrUSB; | 1308 | u8 IntrUSB; |
977 | u16 IntrIn; | 1309 | u16 IntrIn; |
978 | u16 IntrOut; | 1310 | u16 IntrOut; |
1311 | u16 IntrDMA; | ||
979 | /* Read interrupt registers */ | 1312 | /* Read interrupt registers */ |
980 | IntrUSB = jz_readb(USB_REG_INTRUSB); | 1313 | IntrUSB = jz_readb(USB_REG_INTRUSB); |
981 | IntrIn = jz_readw(USB_REG_INTRIN); | 1314 | IntrIn = jz_readw(USB_REG_INTRIN); |
982 | IntrOut = jz_readw(USB_REG_INTROUT); | 1315 | IntrOut = jz_readw(USB_REG_INTROUT); |
983 | 1316 | IntrDMA = jz_readb(USB_REG_INTR); | |
984 | if ( IntrUSB == 0 && IntrIn == 0 && IntrOut == 0) | 1317 | |
985 | return; | 1318 | if ( IntrUSB == 0 && IntrIn == 0 && IntrOut == 0) |
986 | 1319 | return; | |
987 | if (IntrIn & 2) | 1320 | |
988 | { | 1321 | if (IntrIn & 2) |
989 | EPIN_Handler(1); | 1322 | { |
990 | } | 1323 | EPIN_Handler(1); |
991 | if (IntrOut & 2) | 1324 | } |
992 | { | 1325 | if (IntrOut & 2) |
993 | EPOUT_Handler(1); | 1326 | { |
994 | } | 1327 | EPOUT_Handler(1); |
995 | if (IntrUSB & USB_INTR_RESET) | 1328 | } |
996 | { | 1329 | if (IntrUSB & USB_INTR_RESET) |
997 | udc_reset(); | 1330 | { |
998 | } | 1331 | udc_reset(); |
1332 | } | ||
999 | 1333 | ||
1000 | /* Check for endpoint 0 interrupt */ | 1334 | /* Check for endpoint 0 interrupt */ |
1001 | if (IntrIn & USB_INTR_EP0) | 1335 | if (IntrIn & USB_INTR_EP0) |
1002 | { | 1336 | { |
1003 | EP0_Handler(); | 1337 | EP0_Handler(); |
1004 | } | 1338 | } |
1005 | 1339 | ||
1006 | IntrIn = jz_readw(USB_REG_INTRIN); | 1340 | if (IntrDMA & 0x1) //channel 1 :OUT |
1007 | return; | 1341 | { |
1342 | if (tx_size > 0 && tx_size % fifosize[1] != 0) | ||
1343 | { | ||
1344 | jz_writeb(USB_REG_INDEX, 1); | ||
1345 | usb_clearb(USB_REG_INCSR, USB_INCSR_INPKTRDY); | ||
1346 | } | ||
1347 | Disable_DMA(); | ||
1348 | } | ||
1008 | } | 1349 | } |
1009 | 1350 | ||
1010 | void __udc_start(void) | 1351 | void __udc_start(void) |
1011 | { | 1352 | { |
1012 | udc_reset(); | 1353 | udc_reset(); |
1013 | 1354 | ||
1014 | ep0state = USB_EP0_IDLE; | 1355 | ep0state = USB_EP0_IDLE; |
1015 | Bulk_in_size = 0; | 1356 | Bulk_in_size = 0; |
1016 | Bulk_in_finish = 0; | 1357 | Bulk_in_finish = 0; |
1017 | Bulk_out_size = 0; | 1358 | Bulk_out_size = 0; |
1018 | udc_state = IDLE; | 1359 | udc_state = IDLE; |
1019 | tx_size = 0; | 1360 | tx_size = 0; |
1020 | rx_size = 0; | 1361 | rx_size = 0; |
1021 | finished = 0; | 1362 | finished = 0; |
1022 | 1363 | ||
1023 | if ((jz_readb(USB_REG_POWER)&0x10)==0) | 1364 | if ((jz_readb(USB_REG_POWER)&0x10)==0) |
1024 | { | 1365 | { |
1025 | USB_Version=USB_FS; | 1366 | USB_Version=USB_FS; |
1026 | fifosize[1]=64; | 1367 | fifosize[1]=64; |
1027 | EP0_init(1,64,1,64); | 1368 | EP0_init(1,64,1,64); |
1028 | } | 1369 | } |
1029 | else | 1370 | else |
1030 | { | 1371 | { |
1031 | USB_Version=USB_HS; | 1372 | USB_Version=USB_HS; |
1032 | fifosize[1]=512; | 1373 | fifosize[1]=512; |
1033 | EP0_init(1,512,1,512); | 1374 | EP0_init(1,512,1,512); |
1034 | } | 1375 | } |
1035 | 1376 | ||
1036 | USB_Version=USB_HS; | 1377 | USB_Version=USB_HS; |
1037 | system_enable_irq(IRQ_UDC); | 1378 | system_enable_irq(IRQ_UDC); |
1038 | } | 1379 | } |
1039 | 1380 | ||