root/Examples_CP-JR_ARM7_LPC2368/ETT_LPC2368_Examples/USB_DEMO/USBMem/usbhw.c

Revision 8, 20.7 kB (checked in by phil, 15 years ago)

Added Examples etc. from CD

Line 
1 /*----------------------------------------------------------------------------
2  *      U S B  -  K e r n e l
3  *----------------------------------------------------------------------------
4  *      Name:    USBHW.C
5  *      Purpose: USB Hardware Layer Module for Philips LPC214x/LPC318x/23xx/24xx
6  *      Version: V1.10
7  *----------------------------------------------------------------------------
8  *      This file is part of the uVision/ARM development tools.
9  *      This software may only be used under the terms of a valid, current,
10  *      end user licence from KEIL for a compatible version of KEIL software
11  *      development tools. Nothing else gives you the right to use it.
12  *
13  *      Copyright (c) 2005-2007 Keil Software.
14  *---------------------------------------------------------------------------*/
15
16 #include <LPC23xx.H>                        /* LPC23xx definitions */
17
18 #include "type.h"
19
20 #include "usb.h"
21 #include "usbcfg.h"
22 #include "usbreg.h"
23 #include "usbhw.h"
24 #include "usbcore.h"
25 #include "usbuser.h"
26
27
28 #pragma diag_suppress 1441
29
30
31 #define EP_MSK_CTRL 0x0001      /* Control Endpoint Logical Address Mask */
32 #define EP_MSK_BULK 0xC924      /* Bulk Endpoint Logical Address Mask */
33 #define EP_MSK_INT  0x4492      /* Interrupt Endpoint Logical Address Mask */
34 #define EP_MSK_ISO  0x1248      /* Isochronous Endpoint Logical Address Mask */
35
36
37 #if USB_DMA
38
39 #pragma arm section zidata = "USB_RAM"
40 DWORD UDCA[USB_EP_NUM];                     /* UDCA in USB RAM */
41 DWORD DD_NISO_Mem[4*DD_NISO_CNT];           /* Non-Iso DMA Descriptor Memory */
42 DWORD DD_ISO_Mem [5*DD_ISO_CNT];            /* Iso DMA Descriptor Memory */
43 #pragma arm section zidata
44 DWORD udca[USB_EP_NUM];                     /* UDCA saved values */
45
46 DWORD DDMemMap[2];                          /* DMA Descriptor Memory Usage */
47
48 #endif
49
50
51 /*
52  *  Get Endpoint Physical Address
53  *    Parameters:      EPNum: Endpoint Number
54  *                       EPNum.0..3: Address
55  *                       EPNum.7:    Dir
56  *    Return Value:    Endpoint Physical Address
57  */
58
59 DWORD EPAdr (DWORD EPNum) {
60   DWORD val;
61
62   val = (EPNum & 0x0F) << 1;
63   if (EPNum & 0x80) {
64     val += 1;
65   }
66   return (val);
67 }
68
69
70 /*
71  *  Write Command
72  *    Parameters:      cmd:   Command
73  *    Return Value:    None
74  */
75
76 void WrCmd (DWORD cmd) {
77
78   DEV_INT_CLR = CCEMTY_INT;
79   CMD_CODE = cmd;
80   while ((DEV_INT_STAT & CCEMTY_INT) == 0);
81 }
82
83
84 /*
85  *  Write Command Data
86  *    Parameters:      cmd:   Command
87  *                     val:   Data
88  *    Return Value:    None
89  */
90
91 void WrCmdDat (DWORD cmd, DWORD val) {
92
93   DEV_INT_CLR = CCEMTY_INT;
94   CMD_CODE = cmd;
95   while ((DEV_INT_STAT & CCEMTY_INT) == 0);
96   DEV_INT_CLR = CCEMTY_INT;
97   CMD_CODE = val;
98   while ((DEV_INT_STAT & CCEMTY_INT) == 0);
99 }
100
101
102 /*
103  *  Read Command Data
104  *    Parameters:      cmd:   Command
105  *    Return Value:    Data Value
106  */
107
108 DWORD RdCmdDat (DWORD cmd) {
109
110   DEV_INT_CLR = CCEMTY_INT | CDFULL_INT;
111   CMD_CODE = cmd;
112   while ((DEV_INT_STAT & CDFULL_INT) == 0);
113   return (CMD_DATA);
114 }
115
116
117 /*
118  *  USB Initialize Function
119  *   Called by the User to initialize USB
120  *    Return Value:    None
121  */
122
123 void USB_Init (void) {
124
125   PINSEL1 &= ~0x3C000000;                 /* P0.29 USB1_D+, P0.30 USB1_D- */
126   PINSEL1 |=  0x14000000;                 /* PINSEL1 26.27, 28.29         */
127
128   PINSEL3 &= ~0x30000030;                 /* P1.18 GoodLink, P1.30 VBus   */
129   PINSEL3 |=  0x20000010;                 /* PINSEL3 4.5, 28.29           */
130
131   /* The SoftConnect pin for LPC2300 on USB_U1 doesn't work for now,
132      make it GPIO and make it low to turn on pull-up on D+.
133          Once it's fixed, make #if 1 and set it as SoftConn Pin. */
134 #if 0
135   PINSEL4 &= ~0x000C0000;                 /* P2.9 USB1 SoftConnect        */
136   PINSEL4 |= 0x000040000;                 /* PINSEl4 18.19                */
137 #else
138   PINSEL4 &= ~0x000C0000;
139   FIO2DIR |= (1 << 9);
140   FIO2CLR  = (1 << 9);
141 #endif
142        
143   PCONP |= 0x80000000;                    /* USB PCLK -> enable USB Per.  */
144
145   OTG_CLK_CTRL = 0x12;                    /* Dev clock, AHB clock enable  */
146   while ((OTG_CLK_STAT & 0x12) != 0x12);
147  
148   VICVectAddr22 = (unsigned long)USB_ISR; /* USB Interrupt -> Vector 22   */
149   VICVectCntl22 = 0x01;                   /* USB Interrupt -> Priority  1   */
150   VICIntEnable = 1 << 22;                 /* Enable USB Interrupt         */
151
152 //  DEV_INT_EN = DEV_STAT_INT;              /* Enable Device Status Interrupt */
153
154 #if 1 /* Partial Manual Reset since Automatic Bus Reset is not working */
155   USB_Reset();
156   USB_SetAddress(0);
157 #endif
158 }
159
160
161 /*
162  *  USB Connect Function
163  *   Called by the User to Connect/Disconnect USB
164  *    Parameters:      con:   Connect/Disconnect
165  *    Return Value:    None
166  */
167
168 void USB_Connect (BOOL con) {
169   WrCmdDat(CMD_SET_DEV_STAT, DAT_WR_BYTE(con ? DEV_CON : 0));
170 }
171
172
173 /*
174  *  USB Reset Function
175  *   Called automatically on USB Reset
176  *    Return Value:    None
177  */
178
179 void USB_Reset (void) {
180 #if USB_DMA
181   DWORD n;
182 #endif
183
184   EP_INDEX = 0;
185   MAXPACKET_SIZE = USB_MAX_PACKET0;
186   EP_INDEX = 1;
187   MAXPACKET_SIZE = USB_MAX_PACKET0;
188   while ((DEV_INT_STAT & EP_RLZED_INT) == 0);
189
190   EP_INT_CLR  = 0xFFFFFFFF;
191   EP_INT_EN   = 0xFFFFFFFF ^ USB_DMA_EP;
192   DEV_INT_CLR = 0xFFFFFFFF;
193   DEV_INT_EN  = DEV_STAT_INT    | EP_SLOW_INT    |
194                (USB_SOF_EVENT   ? FRAME_INT : 0) |
195                (USB_ERROR_EVENT ? ERR_INT   : 0);
196
197 #if USB_DMA
198   UDCA_HEAD   = USB_RAM_ADR;
199   DMA_REQ_CLR = 0xFFFFFFFF;
200   EP_DMA_DIS  = 0xFFFFFFFF;
201   EP_DMA_EN   = USB_DMA_EP;
202   EOT_INT_CLR = 0xFFFFFFFF;
203   NDD_REQ_INT_CLR = 0xFFFFFFFF;
204   SYS_ERR_INT_CLR = 0xFFFFFFFF;
205   DMA_INT_EN  = 0x00000007;
206   DDMemMap[0] = 0x00000000;
207   DDMemMap[1] = 0x00000000;
208   for (n = 0; n < USB_EP_NUM; n++) {
209     udca[n] = 0;
210     UDCA[n] = 0;
211   }
212 #endif
213 }
214
215
216 /*
217  *  USB Suspend Function
218  *   Called automatically on USB Suspend
219  *    Return Value:    None
220  */
221
222 void USB_Suspend (void) {
223   /* Performed by Hardware */
224 }
225
226
227 /*
228  *  USB Resume Function
229  *   Called automatically on USB Resume
230  *    Return Value:    None
231  */
232
233 void USB_Resume (void) {
234   /* Performed by Hardware */
235 }
236
237
238 /*
239  *  USB Remote Wakeup Function
240  *   Called automatically on USB Remote Wakeup
241  *    Return Value:    None
242  */
243
244 void USB_WakeUp (void) {
245
246   if (USB_DeviceStatus & USB_GETSTATUS_REMOTE_WAKEUP) {
247     WrCmdDat(CMD_SET_DEV_STAT, DAT_WR_BYTE(DEV_CON));
248   }
249 }
250
251
252 /*
253  *  USB Remote Wakeup Configuration Function
254  *    Parameters:      cfg:   Enable/Disable
255  *    Return Value:    None
256  */
257
258 void USB_WakeUpCfg (BOOL cfg) {
259   /* Not needed */
260 }
261
262
263 /*
264  *  USB Set Address Function
265  *    Parameters:      adr:   USB Address
266  *    Return Value:    None
267  */
268
269 void USB_SetAddress (DWORD adr) {
270   WrCmdDat(CMD_SET_ADDR, DAT_WR_BYTE(DEV_EN | adr)); /* Don't wait for next */
271   WrCmdDat(CMD_SET_ADDR, DAT_WR_BYTE(DEV_EN | adr)); /*  Setup Status Phase */
272 }
273
274
275 /*
276  *  USB Configure Function
277  *    Parameters:      cfg:   Configure/Deconfigure
278  *    Return Value:    None
279  */
280
281 void USB_Configure (BOOL cfg) {
282
283   WrCmdDat(CMD_CFG_DEV, DAT_WR_BYTE(cfg ? CONF_DVICE : 0));
284
285   REALIZE_EP = 0x00000003;
286   while ((DEV_INT_STAT & EP_RLZED_INT) == 0);
287   DEV_INT_CLR = EP_RLZED_INT;
288 }
289
290
291 /*
292  *  Configure USB Endpoint according to Descriptor
293  *    Parameters:      pEPD:  Pointer to Endpoint Descriptor
294  *    Return Value:    None
295  */
296
297 void USB_ConfigEP (USB_ENDPOINT_DESCRIPTOR *pEPD) {
298   DWORD num;
299
300   num = EPAdr(pEPD->bEndpointAddress);
301   REALIZE_EP |= (1 << num);
302   EP_INDEX = num;
303   MAXPACKET_SIZE = pEPD->wMaxPacketSize;
304   while ((DEV_INT_STAT & EP_RLZED_INT) == 0);
305   DEV_INT_CLR = EP_RLZED_INT;
306 }
307
308
309 /*
310  *  Set Direction for USB Control Endpoint
311  *    Parameters:      dir:   Out (dir == 0), In (dir <> 0)
312  *    Return Value:    None
313  */
314
315 void USB_DirCtrlEP (DWORD dir) {
316   /* Not needed */
317 }
318
319
320 /*
321  *  Enable USB Endpoint
322  *    Parameters:      EPNum: Endpoint Number
323  *                       EPNum.0..3: Address
324  *                       EPNum.7:    Dir
325  *    Return Value:    None
326  */
327
328 void USB_EnableEP (DWORD EPNum) {
329   WrCmdDat(CMD_SET_EP_STAT(EPAdr(EPNum)), DAT_WR_BYTE(0));
330 }
331
332
333 /*
334  *  Disable USB Endpoint
335  *    Parameters:      EPNum: Endpoint Number
336  *                       EPNum.0..3: Address
337  *                       EPNum.7:    Dir
338  *    Return Value:    None
339  */
340
341 void USB_DisableEP (DWORD EPNum) {
342   WrCmdDat(CMD_SET_EP_STAT(EPAdr(EPNum)), DAT_WR_BYTE(EP_STAT_DA));
343 }
344
345
346 /*
347  *  Reset USB Endpoint
348  *    Parameters:      EPNum: Endpoint Number
349  *                       EPNum.0..3: Address
350  *                       EPNum.7:    Dir
351  *    Return Value:    None
352  */
353
354 void USB_ResetEP (DWORD EPNum) {
355   WrCmdDat(CMD_SET_EP_STAT(EPAdr(EPNum)), DAT_WR_BYTE(0));
356 }
357
358
359 /*
360  *  Set Stall for USB Endpoint
361  *    Parameters:      EPNum: Endpoint Number
362  *                       EPNum.0..3: Address
363  *                       EPNum.7:    Dir
364  *    Return Value:    None
365  */
366
367 void USB_SetStallEP (DWORD EPNum) {
368   WrCmdDat(CMD_SET_EP_STAT(EPAdr(EPNum)), DAT_WR_BYTE(EP_STAT_ST));
369 }
370
371
372 /*
373  *  Clear Stall for USB Endpoint
374  *    Parameters:      EPNum: Endpoint Number
375  *                       EPNum.0..3: Address
376  *                       EPNum.7:    Dir
377  *    Return Value:    None
378  */
379
380 void USB_ClrStallEP (DWORD EPNum) {
381   WrCmdDat(CMD_SET_EP_STAT(EPAdr(EPNum)), DAT_WR_BYTE(0));
382 }
383
384
385 /*
386  *  Read USB Endpoint Data
387  *    Parameters:      EPNum: Endpoint Number
388  *                       EPNum.0..3: Address
389  *                       EPNum.7:    Dir
390  *                     pData: Pointer to Data Buffer
391  *    Return Value:    Number of bytes read
392  */
393
394 DWORD USB_ReadEP (DWORD EPNum, BYTE *pData) {
395   DWORD cnt, n;
396
397   USB_CTRL = ((EPNum & 0x0F) << 2) | CTRL_RD_EN;
398
399   do {
400     cnt = RX_PLENGTH;
401   } while ((cnt & PKT_RDY) == 0);
402   cnt &= PKT_LNGTH_MASK;
403
404   for (n = 0; n < (cnt + 3) / 4; n++) {
405     *((__packed DWORD *)pData) = RX_DATA;
406     pData += 4;
407   }
408
409   USB_CTRL = 0;
410
411   if (((EP_MSK_ISO >> EPNum) & 1) == 0) {   /* Non-Isochronous Endpoint */
412     WrCmd(CMD_SEL_EP(EPAdr(EPNum)));
413     WrCmd(CMD_CLR_BUF);
414   }
415
416   return (cnt);
417 }
418
419
420 /*
421  *  Write USB Endpoint Data
422  *    Parameters:      EPNum: Endpoint Number
423  *                       EPNum.0..3: Address
424  *                       EPNum.7:    Dir
425  *                     pData: Pointer to Data Buffer
426  *                     cnt:   Number of bytes to write
427  *    Return Value:    Number of bytes written
428  */
429
430 DWORD USB_WriteEP (DWORD EPNum, BYTE *pData, DWORD cnt) {
431   DWORD n;
432
433   USB_CTRL = ((EPNum & 0x0F) << 2) | CTRL_WR_EN;
434
435   TX_PLENGTH = cnt;
436
437   for (n = 0; n < (cnt + 3) / 4; n++) {
438     TX_DATA = *((__packed DWORD *)pData);
439     pData += 4;
440   }
441
442   USB_CTRL = 0;
443
444   WrCmd(CMD_SEL_EP(EPAdr(EPNum)));
445   WrCmd(CMD_VALID_BUF);
446
447   return (cnt);
448 }
449
450
451 #if USB_DMA
452
453
454 /* DMA Descriptor Memory Layout */
455 const DWORD DDAdr[2] = { DD_NISO_ADR, DD_ISO_ADR };
456 const DWORD DDSz [2] = { 16,          20         };
457
458
459 /*
460  *  Setup USB DMA Transfer for selected Endpoint
461  *    Parameters:      EPNum: Endpoint Number
462  *                     pDD: Pointer to DMA Descriptor
463  *    Return Value:    TRUE - Success, FALSE - Error
464  */
465
466 BOOL USB_DMA_Setup(DWORD EPNum, USB_DMA_DESCRIPTOR *pDD) {
467   DWORD num, ptr, nxt, iso, n;
468
469   iso = pDD->Cfg.Type.IsoEP;                /* Iso or Non-Iso Descriptor */
470   num = EPAdr(EPNum);                       /* Endpoint's Physical Address */
471
472   ptr = 0;                                  /* Current Descriptor */
473   nxt = udca[num];                          /* Initial Descriptor */
474   while (nxt) {                             /* Go through Descriptor List */
475     ptr = nxt;                              /* Current Descriptor */
476     if (!pDD->Cfg.Type.Link) {              /* Check for Linked Descriptors */
477       n = (ptr - DDAdr[iso]) / DDSz[iso];   /* Descriptor Index */
478       DDMemMap[iso] &= ~(1 << n);           /* Unmark Memory Usage */
479     }
480     nxt = *((DWORD *)ptr);                  /* Next Descriptor */
481   }
482
483   for (n = 0; n < 32; n++) {                /* Search for available Memory */
484     if ((DDMemMap[iso] & (1 << n)) == 0) {
485       break;                                /* Memory found */
486     }
487   }
488   if (n == 32) return (FALSE);              /* Memory not available */
489
490   DDMemMap[iso] |= 1 << n;                  /* Mark Memory Usage */
491   nxt = DDAdr[iso] + n * DDSz[iso];         /* Next Descriptor */
492
493   if (ptr && pDD->Cfg.Type.Link) {
494     *((DWORD *)(ptr + 0))  = nxt;           /* Link in new Descriptor */
495     *((DWORD *)(ptr + 4)) |= 0x00000004;    /* Next DD is Valid */
496   } else {
497     udca[num] = nxt;                        /* Save new Descriptor */
498     UDCA[num] = nxt;                        /* Update UDCA in USB */
499   }
500
501   /* Fill in DMA Descriptor */
502   *(((DWORD *)nxt)++) =  0;                 /* Next DD Pointer */
503   *(((DWORD *)nxt)++) =  pDD->Cfg.Type.ATLE |
504                        (pDD->Cfg.Type.IsoEP << 4) |
505                        (pDD->MaxSize <<  5) |
506                        (pDD->BufLen  << 16);
507   *(((DWORD *)nxt)++) =  pDD->BufAdr;
508   *(((DWORD *)nxt)++) =  pDD->Cfg.Type.LenPos << 8;
509   if (iso) {
510     *((DWORD *)nxt) =  pDD->InfoAdr;
511   }
512
513   return (TRUE); /* Success */
514 }
515
516
517 /*
518  *  Enable USB DMA Endpoint
519  *    Parameters:      EPNum: Endpoint Number
520  *                       EPNum.0..3: Address
521  *                       EPNum.7:    Dir
522  *    Return Value:    None
523  */
524
525 void USB_DMA_Enable (DWORD EPNum) {
526   EP_DMA_EN = 1 << EPAdr(EPNum);
527 }
528
529
530 /*
531  *  Disable USB DMA Endpoint
532  *    Parameters:      EPNum: Endpoint Number
533  *                       EPNum.0..3: Address
534  *                       EPNum.7:    Dir
535  *    Return Value:    None
536  */
537
538 void USB_DMA_Disable (DWORD EPNum) {
539   EP_DMA_DIS = 1 << EPAdr(EPNum);
540 }
541
542
543 /*
544  *  Get USB DMA Endpoint Status
545  *    Parameters:      EPNum: Endpoint Number
546  *                       EPNum.0..3: Address
547  *                       EPNum.7:    Dir
548  *    Return Value:    DMA Status
549  */
550
551 DWORD USB_DMA_Status (DWORD EPNum) {
552   DWORD ptr, val;
553
554   ptr = UDCA[EPAdr(EPNum)];                 /* Current Descriptor */
555   if (ptr == 0) return (USB_DMA_INVALID);
556
557   val = *((DWORD *)(ptr + 3*4));            /* Status Information */
558   switch ((val >> 1) & 0x0F) {
559     case 0x00:                              /* Not serviced */
560       return (USB_DMA_IDLE);
561     case 0x01:                              /* Being serviced */
562       return (USB_DMA_BUSY);
563     case 0x02:                              /* Normal Completition */
564       return (USB_DMA_DONE);
565     case 0x03:                              /* Data Under Run */
566       return (USB_DMA_UNDER_RUN);
567     case 0x08:                              /* Data Over Run */
568       return (USB_DMA_OVER_RUN);
569     case 0x09:                              /* System Error */
570       return (USB_DMA_ERROR);
571   }
572
573   return (USB_DMA_UNKNOWN);
574 }
575
576
577 /*
578  *  Get USB DMA Endpoint Current Buffer Address
579  *    Parameters:      EPNum: Endpoint Number
580  *                       EPNum.0..3: Address
581  *                       EPNum.7:    Dir
582  *    Return Value:    DMA Address (or -1 when DMA is Invalid)
583  */
584
585 DWORD USB_DMA_BufAdr (DWORD EPNum) {
586   DWORD ptr, val;
587
588   ptr = UDCA[EPAdr(EPNum)];                 /* Current Descriptor */
589   if (ptr == 0) return ((DWORD)(-1));                /* DMA Invalid */
590
591   val = *((DWORD *)(ptr + 2*4));            /* Buffer Address */
592
593   return (val);                             /* Current Address */
594 }
595
596
597 /*
598  *  Get USB DMA Endpoint Current Buffer Count
599  *   Number of transfered Bytes or Iso Packets
600  *    Parameters:      EPNum: Endpoint Number
601  *                       EPNum.0..3: Address
602  *                       EPNum.7:    Dir
603  *    Return Value:    DMA Count (or -1 when DMA is Invalid)
604  */
605
606 DWORD USB_DMA_BufCnt (DWORD EPNum) {
607   DWORD ptr, val;
608
609   ptr = UDCA[EPAdr(EPNum)];                 /* Current Descriptor */
610   if (ptr == 0) return ((DWORD)(-1));       /* DMA Invalid */
611
612   val = *((DWORD *)(ptr + 3*4));            /* Status Information */
613
614   return (val >> 16);                       /* Current Count */
615 }
616
617
618 #endif /* USB_DMA */
619
620
621 /*
622  *  Get USB Last Frame Number
623  *    Parameters:      None
624  *    Return Value:    Frame Number
625  */
626
627 DWORD USB_GetFrame (void) {
628   DWORD val;
629
630   WrCmd(CMD_RD_FRAME);
631   val = RdCmdDat(DAT_RD_FRAME);
632   val = val | (RdCmdDat(DAT_RD_FRAME) << 8);
633
634   return (val);
635 }
636
637
638 /*
639  *  USB Interrupt Service Routine
640  */
641
642 void USB_ISR (void) __irq {
643   DWORD disr, val, n, m;
644
645   disr = DEV_INT_STAT;                      /* Device Interrupt Status */
646   DEV_INT_CLR = disr;                       /* A known issue on LPC214x */
647
648   /* Device Status Interrupt (Reset, Connect change, Suspend/Resume) */
649   if (disr & DEV_STAT_INT) {
650     WrCmd(CMD_GET_DEV_STAT);
651     val = RdCmdDat(DAT_GET_DEV_STAT);       /* Device Status */
652     if (val & DEV_RST) {                    /* Reset */
653       USB_Reset();
654 #if   USB_RESET_EVENT
655       USB_Reset_Event();
656 #endif
657       goto isr_end;
658     }
659     if (val & DEV_CON_CH) {                 /* Connect change */
660 #if   USB_POWER_EVENT
661       USB_Power_Event(val & DEV_CON);
662 #endif
663       goto isr_end;
664     }
665     if (val & DEV_SUS_CH) {                 /* Suspend/Resume */
666       if (val & DEV_SUS) {                  /* Suspend */
667         USB_Suspend();
668 #if     USB_SUSPEND_EVENT
669         USB_Suspend_Event();
670 #endif
671       } else {                              /* Resume */
672         USB_Resume();
673 #if     USB_RESUME_EVENT
674         USB_Resume_Event();
675 #endif
676       }
677       goto isr_end;
678     }
679   }
680
681 #if USB_SOF_EVENT
682   /* Start of Frame Interrupt */
683   if (disr & FRAME_INT) {
684     USB_SOF_Event();
685   }
686 #endif
687
688 #if USB_ERROR_EVENT
689   /* Error Interrupt */
690   if (disr & ERR_INT) {
691     WrCmd(CMD_RD_ERR_STAT);
692     val = RdCmdDat(DAT_RD_ERR_STAT);
693     USB_Error_Event(val);
694   }
695 #endif
696
697   /* Endpoint's Slow Interrupt */
698   if (disr & EP_SLOW_INT) {
699
700     while (EP_INT_STAT) {                   /* Endpoint Interrupt Status */
701
702       for (n = 0; n < USB_EP_NUM; n++) {    /* Check All Endpoints */
703         if (EP_INT_STAT & (1 << n)) {
704           m = n >> 1;
705
706           EP_INT_CLR = 1 << n;
707           while ((DEV_INT_STAT & CDFULL_INT) == 0);
708           val = CMD_DATA;
709
710           if ((n & 1) == 0) {               /* OUT Endpoint */
711             if (n == 0) {                   /* Control OUT Endpoint */
712               if (val & EP_SEL_STP) {       /* Setup Packet */
713                 if (USB_P_EP[0]) {
714                   USB_P_EP[0](USB_EVT_SETUP);
715                   continue;
716                 }
717               }
718             }
719             if (USB_P_EP[m]) {
720               USB_P_EP[m](USB_EVT_OUT);
721             }
722           } else {                          /* IN Endpoint */
723             if (USB_P_EP[m]) {
724               USB_P_EP[m](USB_EVT_IN);
725             }
726           }
727         }
728       }
729     }
730   }
731
732 #if USB_DMA
733
734   if (DMA_INT_STAT & 0x00000001) {          /* End of Transfer Interrupt */
735     val = EOT_INT_STAT;
736     for (n = 2; n < USB_EP_NUM; n++) {      /* Check All Endpoints */
737       if (val & (1 << n)) {
738         m = n >> 1;
739         if ((n & 1) == 0) {                 /* OUT Endpoint */
740           if (USB_P_EP[m]) {
741             USB_P_EP[m](USB_EVT_OUT_DMA_EOT);
742           }
743         } else {                            /* IN Endpoint */
744           if (USB_P_EP[m]) {
745             USB_P_EP[m](USB_EVT_IN_DMA_EOT);
746           }
747         }
748       }
749     }
750     EOT_INT_CLR = val;
751   }
752
753   if (DMA_INT_STAT & 0x00000002) {          /* New DD Request Interrupt */
754     val = NDD_REQ_INT_STAT;
755     for (n = 2; n < USB_EP_NUM; n++) {      /* Check All Endpoints */
756       if (val & (1 << n)) {
757         m = n >> 1;
758         if ((n & 1) == 0) {                 /* OUT Endpoint */
759           if (USB_P_EP[m]) {
760             USB_P_EP[m](USB_EVT_OUT_DMA_NDR);
761           }
762         } else {                            /* IN Endpoint */
763           if (USB_P_EP[m]) {
764             USB_P_EP[m](USB_EVT_IN_DMA_NDR);
765           }
766         }
767       }
768     }
769     NDD_REQ_INT_CLR = val;
770   }
771
772   if (DMA_INT_STAT & 0x00000004) {          /* System Error Interrupt */
773     val = SYS_ERR_INT_STAT;
774     for (n = 2; n < USB_EP_NUM; n++) {      /* Check All Endpoints */
775       if (val & (1 << n)) {
776         m = n >> 1;
777         if ((n & 1) == 0) {                 /* OUT Endpoint */
778           if (USB_P_EP[m]) {
779             USB_P_EP[m](USB_EVT_OUT_DMA_ERR);
780           }
781         } else {                            /* IN Endpoint */
782           if (USB_P_EP[m]) {
783             USB_P_EP[m](USB_EVT_IN_DMA_ERR);
784           }
785         }
786       }
787     }
788     SYS_ERR_INT_CLR = val;
789   }
790
791 #endif /* USB_DMA */
792
793 isr_end:
794 //  DEV_INT_CLR = disr;
795   VICVectAddr = 0;                          /* Acknowledge Interrupt */
796 }
Note: See TracBrowser for help on using the browser.