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

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