00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00033 #include "type.h"
00034 #include "debug.h"
00035
00036 #ifdef LPC214x
00037 #include "lpc214x.h"
00038 #endif
00039 #ifdef LPC23xx
00040 #include "lpc23xx.h"
00041 #endif
00042 #include "usbhw_lpc.h"
00043 #include "usbapi.h"
00044
00045
00046 #ifdef DEBUG
00047
00048
00049
00050 #endif
00051
00052 #ifdef DEBUG_LED
00053 #ifdef LPC214x
00054 #define DEBUG_LED_ON(x) IOCLR0 = (1 << x);
00055 #define DEBUG_LED_OFF(x) IOSET0 = (1 << x);
00056 #define DEBUG_LED_INIT(x) PINSEL0 &= ~(0x3 << (2*x)); IODIR0 |= (1 << x); DEBUG_LED_OFF(x);
00057 #else
00058 #define DEBUG_LED_ON(x) FIO2SET = (1 << (x-8));
00059 #define DEBUG_LED_OFF(x) FIO2CLR = (1 << (x-8));
00060 #define DEBUG_LED_INIT(x) SCS |= 1; PINSEL10 = 0; FIO2DIR |= (1 << (x-8)); DEBUG_LED_OFF(x);
00061 #endif
00062 #else
00063 #define DEBUG_LED_INIT(x)
00064 #define DEBUG_LED_ON(x)
00065 #define DEBUG_LED_OFF(x)
00066 #endif
00067
00069 static TFnDevIntHandler *_pfnDevIntHandler = NULL;
00071 static TFnEPIntHandler *_apfnEPIntHandlers[16];
00073 static TFnFrameHandler *_pfnFrameHandler = NULL;
00074
00076 #define EP2IDX(bEP) ((((bEP)&0xF)<<1)|(((bEP)&0x80)>>7))
00077
00078 #define IDX2EP(idx) ((((idx)<<7)&0x80)|(((idx)>>1)&0xF))
00079
00080
00081
00087 static void Wait4DevInt(U32 dwIntr)
00088 {
00089
00090 while ((USBDevIntSt & dwIntr) != dwIntr);
00091
00092 USBDevIntClr = dwIntr;
00093 }
00094
00095
00101 static void USBHwCmd(U8 bCmd)
00102 {
00103
00104 USBDevIntClr = CDFULL | CCEMTY;
00105
00106 USBCmdCode = 0x00000500 | (bCmd << 16);
00107 Wait4DevInt(CCEMTY);
00108 }
00109
00110
00117 static void USBHwCmdWrite(U8 bCmd, U16 bData)
00118 {
00119
00120 USBHwCmd(bCmd);
00121
00122
00123 USBCmdCode = 0x00000100 | (bData << 16);
00124 Wait4DevInt(CCEMTY);
00125 }
00126
00127
00135 static U8 USBHwCmdRead(U8 bCmd)
00136 {
00137
00138 USBHwCmd(bCmd);
00139
00140
00141 USBCmdCode = 0x00000200 | (bCmd << 16);
00142 Wait4DevInt(CDFULL);
00143 return USBCmdData;
00144 }
00145
00146
00158 static void USBHwEPRealize(int idx, U16 wMaxPSize)
00159 {
00160 USBReEp |= (1 << idx);
00161 USBEpInd = idx;
00162 USBMaxPSize = wMaxPSize;
00163 Wait4DevInt(EP_RLZED);
00164 }
00165
00166
00173 static void USBHwEPEnable(int idx, BOOL fEnable)
00174 {
00175 USBHwCmdWrite(CMD_EP_SET_STATUS | idx, fEnable ? 0 : EP_DA);
00176 }
00177
00178
00185 void USBHwEPConfig(U8 bEP, U16 wMaxPacketSize)
00186 {
00187 int idx;
00188
00189 idx = EP2IDX(bEP);
00190
00191
00192 USBHwEPRealize(idx, wMaxPacketSize);
00193
00194
00195 USBHwEPEnable(idx, TRUE);
00196 }
00197
00198
00205 void USBHwRegisterEPIntHandler(U8 bEP, TFnEPIntHandler *pfnHandler)
00206 {
00207 int idx;
00208
00209 idx = EP2IDX(bEP);
00210
00211 ASSERT(idx<32);
00212
00213
00214 _apfnEPIntHandlers[idx / 2] = pfnHandler;
00215
00216
00217 USBEpIntEn |= (1 << idx);
00218 USBDevIntEn |= EP_SLOW;
00219
00220 DBG("Registered handler for EP 0x%x\n", bEP);
00221 }
00222
00223
00229 void USBHwRegisterDevIntHandler(TFnDevIntHandler *pfnHandler)
00230 {
00231 _pfnDevIntHandler = pfnHandler;
00232
00233
00234 USBDevIntEn |= DEV_STAT;
00235
00236 DBG("Registered handler for device status\n");
00237 }
00238
00239
00245 void USBHwRegisterFrameHandler(TFnFrameHandler *pfnHandler)
00246 {
00247 _pfnFrameHandler = pfnHandler;
00248
00249
00250 USBDevIntEn |= FRAME;
00251
00252 DBG("Registered handler for frame\n");
00253 }
00254
00255
00261 void USBHwSetAddress(U8 bAddr)
00262 {
00263 USBHwCmdWrite(CMD_DEV_SET_ADDRESS, DEV_EN | bAddr);
00264 }
00265
00266
00272 void USBHwConnect(BOOL fConnect)
00273 {
00274 #ifdef LPC23xx
00275 #ifndef LPC2378_PORTB
00276 if(fConnect)
00277 FIO2CLR = (1<<9);
00278 else
00279 FIO2SET = (1<<9);
00280 #else
00281 if(fConnect)
00282 FIO0CLR = (1<<14);
00283 else
00284 FIO0SET = (1<<14);
00285 #endif
00286 #endif
00287 USBHwCmdWrite(CMD_DEV_STATUS, fConnect ? CON : 0);
00288 }
00289
00290
00304 void USBHwNakIntEnable(U8 bIntBits)
00305 {
00306 USBHwCmdWrite(CMD_DEV_SET_MODE, bIntBits);
00307 }
00308
00309
00316 U8 USBHwEPGetStatus(U8 bEP)
00317 {
00318 int idx = EP2IDX(bEP);
00319
00320 return USBHwCmdRead(CMD_EP_SELECT | idx);
00321 }
00322
00323
00330 void USBHwEPStall(U8 bEP, BOOL fStall)
00331 {
00332 int idx = EP2IDX(bEP);
00333
00334 USBHwCmdWrite(CMD_EP_SET_STATUS | idx, fStall ? EP_ST : 0);
00335 }
00336
00337
00347 int USBHwEPWrite(U8 bEP, U8 *pbBuf, int iLen)
00348 {
00349 int idx;
00350
00351 idx = EP2IDX(bEP);
00352
00353
00354 USBCtrl = WR_EN | ((bEP & 0xF) << 2);
00355
00356
00357 USBTxPLen = iLen;
00358
00359
00360 while (USBCtrl & WR_EN) {
00361 USBTxData = (pbBuf[3] << 24) | (pbBuf[2] << 16) | (pbBuf[1] << 8) | pbBuf[0];
00362 pbBuf += 4;
00363 }
00364
00365 USBCtrl = 0;
00366
00367
00368 USBHwCmd(CMD_EP_SELECT | idx);
00369 USBHwCmd(CMD_EP_VALIDATE_BUFFER);
00370
00371 return iLen;
00372 }
00373
00374
00385 int USBHwEPRead(U8 bEP, U8 *pbBuf, int iMaxLen)
00386 {
00387 int i, idx;
00388 U32 dwData, dwLen;
00389
00390 idx = EP2IDX(bEP);
00391
00392
00393 USBCtrl = RD_EN | ((bEP & 0xF) << 2);
00394
00395
00396 do {
00397 dwLen = USBRxPLen;
00398 } while ((dwLen & PKT_RDY) == 0);
00399
00400
00401 if ((dwLen & DV) == 0) {
00402 return -1;
00403 }
00404
00405
00406 dwLen &= PKT_LNGTH_MASK;
00407
00408
00409 dwData = 0;
00410 for (i = 0; i < dwLen; i++) {
00411 if ((i % 4) == 0) {
00412 dwData = USBRxData;
00413 }
00414 if ((pbBuf != NULL) && (i < iMaxLen)) {
00415 pbBuf[i] = dwData & 0xFF;
00416 }
00417 dwData >>= 8;
00418 }
00419
00420
00421 USBCtrl = 0;
00422
00423
00424 USBHwCmd(CMD_EP_SELECT | idx);
00425 USBHwCmd(CMD_EP_CLEAR_BUFFER);
00426
00427 return dwLen;
00428 }
00429
00430
00431
00432
00433 int USBHwISOCEPRead(const U8 bEP, U8 *pbBuf, const int iMaxLen)
00434 {
00435
00436 int i, idx;
00437 U32 dwData, dwLen;
00438
00439 idx = EP2IDX(bEP);
00440
00441
00442 USBCtrl = RD_EN | ((bEP & 0xF) << 2);
00443
00444
00445
00446
00447 asm volatile("nop\n");
00448
00449
00450 dwLen = USBRxPLen;
00451 if( (dwLen & PKT_RDY) == 0 ) {
00452 USBCtrl = 0;
00453 return(-1);
00454 }
00455
00456
00457 if ((dwLen & DV) == 0) {
00458 USBCtrl = 0;
00459 return -1;
00460 }
00461
00462
00463 dwLen &= PKT_LNGTH_MASK;
00464
00465
00466 dwData = 0;
00467 for (i = 0; i < dwLen; i++) {
00468 if ((i % 4) == 0) {
00469 dwData = USBRxData;
00470 }
00471 if ((pbBuf != NULL) && (i < iMaxLen)) {
00472 pbBuf[i] = dwData & 0xFF;
00473 }
00474 dwData >>= 8;
00475 }
00476
00477
00478 USBCtrl = 0;
00479
00480
00481 USBHwCmd(CMD_EP_SELECT | idx);
00482 USBHwCmd(CMD_EP_CLEAR_BUFFER);
00483
00484 return dwLen;
00485 }
00486
00487
00496 void USBHwConfigDevice(BOOL fConfigured)
00497 {
00498
00499 USBHwCmdWrite(CMD_DEV_CONFIG, fConfigured ? CONF_DEVICE : 0);
00500 }
00501
00502
00510 void USBHwISR(void)
00511 {
00512 U32 dwStatus;
00513 U32 dwIntBit;
00514 U8 bEPStat, bDevStat, bStat;
00515 int i;
00516 U16 wFrame;
00517
00518
00519 DEBUG_LED_ON(9);
00520
00521
00522 dwStatus = USBDevIntSt;
00523
00524
00525 if (dwStatus & FRAME) {
00526
00527 USBDevIntClr = FRAME;
00528
00529 if (_pfnFrameHandler != NULL) {
00530 wFrame = USBHwCmdRead(CMD_DEV_READ_CUR_FRAME_NR);
00531 _pfnFrameHandler(wFrame);
00532 }
00533 }
00534
00535
00536 if (dwStatus & DEV_STAT) {
00537
00538
00539
00540
00541 USBDevIntClr = DEV_STAT;
00542 bDevStat = USBHwCmdRead(CMD_DEV_STATUS);
00543 if (bDevStat & (CON_CH | SUS_CH | RST)) {
00544
00545 bStat = ((bDevStat & CON) ? DEV_STATUS_CONNECT : 0) |
00546 ((bDevStat & SUS) ? DEV_STATUS_SUSPEND : 0) |
00547 ((bDevStat & RST) ? DEV_STATUS_RESET : 0);
00548
00549 if (_pfnDevIntHandler != NULL) {
00550 DEBUG_LED_ON(8);
00551 _pfnDevIntHandler(bStat);
00552 DEBUG_LED_OFF(8);
00553 }
00554 }
00555 }
00556
00557
00558 if (dwStatus & EP_SLOW) {
00559
00560 USBDevIntClr = EP_SLOW;
00561
00562 for (i = 0; i < 32; i++) {
00563 dwIntBit = (1 << i);
00564 if (USBEpIntSt & dwIntBit) {
00565
00566 USBEpIntClr = dwIntBit;
00567 Wait4DevInt(CDFULL);
00568 bEPStat = USBCmdData;
00569
00570 bStat = ((bEPStat & EPSTAT_FE) ? EP_STATUS_DATA : 0) |
00571 ((bEPStat & EPSTAT_ST) ? EP_STATUS_STALLED : 0) |
00572 ((bEPStat & EPSTAT_STP) ? EP_STATUS_SETUP : 0) |
00573 ((bEPStat & EPSTAT_EPN) ? EP_STATUS_NACKED : 0) |
00574 ((bEPStat & EPSTAT_PO) ? EP_STATUS_ERROR : 0);
00575
00576 if (_apfnEPIntHandlers[i / 2] != NULL) {
00577 DEBUG_LED_ON(10);
00578 _apfnEPIntHandlers[i / 2](IDX2EP(i), bStat);
00579 DEBUG_LED_OFF(10);
00580 }
00581 }
00582 }
00583 }
00584
00585 DEBUG_LED_OFF(9);
00586 }
00587
00588
00589
00603 BOOL USBHwInit(void)
00604 {
00605 #ifdef LPC214x
00606
00607
00608 PINSEL1 = (PINSEL1 & ~(3 << 14)) | (1 << 14);
00609
00610 PINSEL1 = (PINSEL1 & ~(3 << 30)) | (2 << 30);
00611
00612
00613 PCONP |= (1 << 31);
00614
00615
00616 PLL1CON = 1;
00617 PLL1CFG = (1 << 5) | 3;
00618 PLL1FEED = 0xAA;
00619 PLL1FEED = 0x55;
00620 while ((PLL1STAT & (1 << 10)) == 0);
00621
00622 PLL1CON = 3;
00623 PLL1FEED = 0xAA;
00624 PLL1FEED = 0x55;
00625
00626 #endif
00627
00628 #ifdef LPC23xx
00629 #ifdef LPC2378_PORTB
00630 PINSEL1 = (PINSEL1 & ~(3 << 30)) | (1 << 30);
00631 PINSEL3 = (PINSEL3 & ~(3 << 28)) | (2 << 28);
00632
00633
00634
00635
00636 PINSEL0 = (PINSEL0 & ~((3 << 26) | (3 << 28))) | (1 << 26);
00637 FIO0DIR |= (1<<14);
00638 FIO0SET = (1<<14);
00639
00640 #else
00641 PINSEL1 = (PINSEL1 & ~((3 << 26) | (3 << 28))) | (1 << 26) | (1 << 28);
00642 PINSEL3 = (PINSEL3 & ~((3 << 4) | (3 << 28))) | (1 << 4) | (2 << 28);
00643
00644
00645
00646
00647 PINSEL4 = (PINSEL4 & ~(3 << 18));
00648 FIO2DIR |= (1<<9);
00649 FIO2SET = (1<<9);
00650 #endif
00651
00652
00653 PCONP |= (1 << 31);
00654
00655
00656
00657
00658 USBCLKCFG = 5;
00659
00660 #ifdef LPC2378_PORTB
00661 USBClkCtrl = (1 << 1) | (1 << 3) | (1 << 4);
00662 while (!(USBClkSt & ((1 << 1) | (1 << 3) | (1 << 4))));
00663 USBPortSel = 0x3;
00664 #else
00665 USBClkCtrl = (1 << 1) | (1 << 4);
00666 while (!(USBClkSt & ((1 << 1) | (1 << 4))));
00667 #endif
00668
00669 #endif
00670
00671
00672 USBDevIntEn = 0;
00673 USBDevIntClr = 0xFFFFFFFF;
00674 USBDevIntPri = 0;
00675
00676 USBEpIntEn = 0;
00677 USBEpIntClr = 0xFFFFFFFF;
00678 USBEpIntPri = 0;
00679
00680
00681 USBHwNakIntEnable(0);
00682
00683
00684 DEBUG_LED_INIT(8);
00685 DEBUG_LED_INIT(9);
00686 DEBUG_LED_INIT(10);
00687
00688 return TRUE;
00689 }
00690
00691
00692
00693
00694
00695
00696
00712 void USBSetupDMADescriptor(
00713 volatile U32 dmaDescriptor[],
00714 volatile U32 nextDdPtr[],
00715 const U8 isIsocFlag,
00716 const U16 maxPacketSize,
00717 const U16 dmaLengthIsocNumFrames,
00718 void *dmaBufferStartAddress,
00719 U32 *isocPacketSizeMemoryAddress )
00720 {
00721 dmaDescriptor[1] = 0;
00722 dmaDescriptor[0] = (U32) nextDdPtr;
00723 dmaDescriptor[1] |= ((maxPacketSize & 0x3FF) << 5);
00724 dmaDescriptor[1] |= (dmaLengthIsocNumFrames << 16);
00725 if( isIsocFlag ) {
00726 dmaDescriptor[1] |= (1<<4);
00727 }
00728 if( nextDdPtr != NULL ) {
00729 dmaDescriptor[1] |= (1<<2);
00730 }
00731 dmaDescriptor[2] = (U32) dmaBufferStartAddress;
00732
00733 if( isIsocFlag && isocPacketSizeMemoryAddress != NULL ) {
00734 dmaDescriptor[4] = (U32) isocPacketSizeMemoryAddress;
00735 }
00736 dmaDescriptor[3] = 0;
00737 }
00738
00746 void USBDisableDMAForEndpoint(const U8 bEndpointNumber) {
00747 int idx = EP2IDX(bEndpointNumber);
00748 USBEpDMADis = (1<<idx);
00749 }
00750
00758 void USBEnableDMAForEndpoint(const U8 bEndpointNumber) {
00759 int idx = EP2IDX(bEndpointNumber);
00760 USBEpDMAEn = (1<<idx);
00761 }
00762
00773 void USBInitializeISOCFrameArray(U32 isocFrameArr[], const U32 numElements, const U16 startFrameNumber, const U16 defaultFrameLength) {
00774 U16 i;
00775 U16 frameNumber = startFrameNumber;
00776
00777 for(i = 0; i < numElements; i++ ) {
00778 isocFrameArr[i] = (frameNumber<<16) | (1<<15) | (defaultFrameLength & 0x3FF);
00779 frameNumber++;
00780 }
00781 }
00782
00792 void USBSetHeadDDForDMA(const U8 bEp, volatile U32* udcaHeadArray[32], volatile const U32 *dmaDescriptorPtr) {
00793 udcaHeadArray[EP2IDX(bEp)] = (U32) dmaDescriptorPtr;
00794 }
00795
00803 void USBInitializeUSBDMA(volatile U32* udcaHeadArray[32]) {
00804
00805 int i;
00806 for(i = 0; i < 32; i++ ) {
00807 udcaHeadArray[i] = NULL;
00808 }
00809 USBUDCAH = (U32) udcaHeadArray;
00810 }
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820