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
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046 #include "chip.h"
00047 #include "USBD_HAL.h"
00048
00049 #include <stdbool.h>
00050 #include <stdint.h>
00051 #include <stdio.h>
00052 #include <string.h>
00053
00054
00055
00056
00057
00058 #define DMA
00059
00060
00061
00062 #define SHIFT_INTERUPT 12
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080 #define UDPHS_ENDPOINT_DISABLED 0
00081
00082 #define UDPHS_ENDPOINT_HALTED 1
00083
00084 #define UDPHS_ENDPOINT_IDLE 2
00085
00086 #define UDPHS_ENDPOINT_SENDING 3
00087
00088 #define UDPHS_ENDPOINT_RECEIVING 4
00089
00090 #define UDPHS_ENDPOINT_SENDINGM 5
00091
00092 #define UDPHS_ENDPOINT_RECEIVINGM 6
00093
00094
00095
00096
00097
00098
00099
00100 #define MBL_NbBuffer(i, o, size) (((i)>(o))?((i)-(o)):((i)+(size)-(o)))
00101
00102
00103 #define MBL_FULL 1
00104
00105 #define MBL_NULL 2
00106
00107
00108
00109
00110
00111
00112 typedef struct {
00113
00114 void *fCallback;
00115
00116 void *pArgument;
00117
00118 uint8_t transType;
00119
00120 uint8_t reserved[3];
00121 } TransferHeader;
00122
00123
00124 typedef struct {
00125
00126
00127 TransferCallback fCallback;
00128
00129 void *pArgument;
00130
00131 uint8_t transType;
00132 uint8_t reserved[3];
00133
00134
00135 int32_t buffered;
00136
00137 uint8_t *pData;
00138
00139 int32_t transferred;
00140
00141 int32_t remaining;
00142 } Transfer;
00143
00144
00145 typedef struct {
00146
00147 MblTransferCallback fCallback;
00148
00149 void *pArgument;
00150
00151 uint8_t transType;
00152
00153 uint8_t listState;
00154
00155 uint16_t listSize;
00156
00157 USBDTransferBuffer *pMbl;
00158
00159 uint16_t offsetSize;
00160
00161 uint16_t outCurr;
00162
00163 uint16_t outLast;
00164
00165 uint16_t inCurr;
00166 } MblTransfer;
00167
00168
00169
00170
00171 typedef struct {
00172
00173
00174 volatile uint8_t state;
00175
00176 volatile uint8_t bank;
00177
00178 volatile uint16_t size;
00179
00180
00181 union {
00182 TransferHeader transHdr;
00183 Transfer singleTransfer;
00184 MblTransfer mblTransfer;
00185 } transfer;
00186
00187 uint32_t sendZLP;
00188 } Endpoint;
00189
00190
00191
00192
00193 typedef struct {
00194 void *pNxtDesc;
00195 void *pAddr;
00196 uint32_t dwCtrl;
00197 uint32_t dw;
00198 } UdphsDmaDescriptor;
00199
00200
00201
00202
00203
00204
00205 static Endpoint endpoints[CHIP_USB_NUMENDPOINTS];
00206
00207
00208
00209 static const char test_packet_buffer[] = {
00210 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00211 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
00212 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE,
00213 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
00214 0x7F, 0xBF, 0xDF, 0xEF, 0xF7, 0xFB, 0xFD,
00215 0xFC, 0x7E, 0xBF, 0xDF, 0xEF, 0xF7, 0xFB, 0xFD, 0x7E
00216 };
00217
00218
00219 COMPILER_ALIGNED(16) static UdphsDmaDescriptor dmaLL[5];
00220 COMPILER_ALIGNED(16) static UdphsDmaDescriptor *pDmaLL;
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232 static void UDPHS_EndOfTransfer(uint8_t bEndpoint, uint8_t bStatus)
00233 {
00234 Endpoint *pEp = &(endpoints[bEndpoint]);
00235
00236
00237 if ((pEp->state == UDPHS_ENDPOINT_RECEIVING) ||
00238 (pEp->state == UDPHS_ENDPOINT_SENDING)) {
00239 Transfer *pXfr = (Transfer *)&(pEp->transfer);
00240
00241 uint32_t transferred = pXfr->transferred;
00242 uint32_t remaining = pXfr->remaining + pXfr->buffered;
00243
00244 TRACE_DEBUG_WP("EoT ");
00245
00246 if (pEp->state == UDPHS_ENDPOINT_SENDING)
00247 pEp->sendZLP = 0;
00248
00249 pEp->state = UDPHS_ENDPOINT_IDLE;
00250 pXfr->pData = 0;
00251 pXfr->transferred = -1;
00252 pXfr->buffered = -1;
00253 pXfr->remaining = -1;
00254
00255
00256 if (pXfr->fCallback) {
00257 pXfr->fCallback(pXfr->pArgument, bStatus, transferred, remaining);
00258 }
00259 else {
00260 TRACE_DEBUG_WP("NoCB ");
00261 }
00262 } else if ((pEp->state == UDPHS_ENDPOINT_RECEIVINGM)
00263 || (pEp->state == UDPHS_ENDPOINT_SENDINGM)) {
00264 MblTransfer *pXfr = (MblTransfer *) & (pEp->transfer);
00265 TRACE_DEBUG_WP("EoMT ");
00266
00267 pEp->state = UDPHS_ENDPOINT_IDLE;
00268 pXfr->listState = 0;
00269 pXfr->outCurr = pXfr->inCurr = pXfr->outLast = 0;
00270
00271
00272 if (pXfr->fCallback) {
00273 pXfr->fCallback(pXfr->pArgument, bStatus);
00274 }
00275 else {
00276 TRACE_DEBUG_WP("NoCB ");
00277 }
00278 }
00279 }
00280
00281
00282
00283
00284
00285
00286
00287
00288 static uint8_t UDPHS_MblUpdate(MblTransfer *pTransfer,
00289 USBDTransferBuffer *pBi,
00290 uint16_t size,
00291 uint8_t forceEnd)
00292 {
00293
00294 pBi->remaining -= size;
00295
00296
00297 if (pTransfer->listState == MBL_NULL)
00298 return 1;
00299
00300
00301 if (pBi->remaining == 0 || forceEnd || size == 0) {
00302
00303 if ((++ pTransfer->outCurr) == pTransfer->listSize)
00304 pTransfer->outCurr = 0;
00305
00306
00307 if (pTransfer->outCurr == pTransfer->inCurr)
00308 pTransfer->listState = MBL_NULL;
00309 else {
00310 pTransfer->listState = 0;
00311
00312 pBi = &pTransfer->pMbl[pTransfer->outCurr];
00313 pBi->buffered = 0;
00314 pBi->transferred = 0;
00315 pBi->remaining = pBi->size;
00316 }
00317
00318 return 1;
00319 }
00320
00321 return 0;
00322 }
00323
00324
00325
00326
00327
00328
00329 static uint8_t UDPHS_MblWriteFifo(uint8_t bEndpoint)
00330 {
00331 Endpoint *pEndpoint = &(endpoints[bEndpoint]);
00332 MblTransfer *pTransfer = (MblTransfer *)&(pEndpoint->transfer);
00333 USBDTransferBuffer *pBi = &(pTransfer->pMbl[pTransfer->outCurr]);
00334 uint8_t *pFifo;
00335 int32_t size;
00336
00337 volatile uint8_t *pBytes;
00338 volatile uint8_t bufferEnd = 1;
00339
00340
00341 size = pEndpoint->size;
00342
00343 if (size > pBi->remaining) size = pBi->remaining;
00344
00345 TRACE_DEBUG_WP("w%d.%d ", pTransfer->outCurr, size);
00346
00347
00348 pTransfer->outLast = pTransfer->outCurr;
00349
00350 pBytes = &(pBi->pBuffer[pBi->transferred + pBi->buffered]);
00351 pBi->buffered += size;
00352 bufferEnd = UDPHS_MblUpdate(pTransfer, pBi, size, 0);
00353
00354
00355 pFifo = (uint8_t *)((uint32_t *)USBHS_RAM_ADDR + (EPT_VIRTUAL_SIZE *
00356 bEndpoint));
00357 memory_sync();
00358
00359 if (size) {
00360 int32_t c8 = size >> 3;
00361 int32_t c1 = size & 0x7;
00362
00363 for (; c8; c8 --) {
00364 *(pFifo++) = *(pBytes ++);
00365 *(pFifo++) = *(pBytes ++);
00366 *(pFifo++) = *(pBytes ++);
00367 *(pFifo++) = *(pBytes ++);
00368
00369 *(pFifo++) = *(pBytes ++);
00370 *(pFifo++) = *(pBytes ++);
00371 *(pFifo++) = *(pBytes ++);
00372 *(pFifo++) = *(pBytes ++);
00373 }
00374
00375 for (; c1; c1 --)
00376 *(pFifo++) = *(pBytes ++);
00377 }
00378
00379 return bufferEnd;
00380 }
00381
00382
00383
00384
00385
00386
00387 static void UDPHS_WritePayload(uint8_t bEndpoint, int32_t size)
00388 {
00389 Endpoint *pEndpoint = &(endpoints[bEndpoint]);
00390 Transfer *pTransfer = (Transfer *)&(pEndpoint->transfer);
00391 uint8_t *pFifo;
00392
00393
00394 if (size > pTransfer->remaining)
00395 size = pTransfer->remaining;
00396
00397
00398 pTransfer->buffered += size;
00399 pTransfer->remaining -= size;
00400
00401
00402 pFifo = (uint8_t *)((uint32_t *)USBHS_RAM_ADDR + (EPT_VIRTUAL_SIZE *
00403 bEndpoint));
00404 memory_sync();
00405
00406 for (; size; size --)
00407 *(pFifo ++) = *(pTransfer->pData ++);
00408
00409 memory_sync();
00410
00411 }
00412
00413
00414
00415
00416
00417
00418 static void UDPHS_ReadPayload(uint8_t bEndpoint, int32_t wPacketSize)
00419 {
00420 Endpoint *pEndpoint = &(endpoints[bEndpoint]);
00421 Transfer *pTransfer = (Transfer *)&(pEndpoint->transfer);
00422 uint8_t *pFifo;
00423
00424
00425 if (wPacketSize > pTransfer->remaining) {
00426 pTransfer->buffered += wPacketSize - pTransfer->remaining;
00427 wPacketSize = pTransfer->remaining;
00428 }
00429
00430
00431 pTransfer->remaining -= wPacketSize;
00432 pTransfer->transferred += wPacketSize;
00433
00434
00435 pFifo = (uint8_t *)((uint32_t *)USBHS_RAM_ADDR
00436 + (EPT_VIRTUAL_SIZE * bEndpoint));
00437
00438 while (wPacketSize > 0) {
00439 *(pTransfer->pData++) = *(pFifo++);
00440 memory_sync();
00441 wPacketSize--;
00442 }
00443 }
00444
00445
00446
00447
00448
00449 static void UDPHS_ReadRequest(USBGenericRequest *pRequest)
00450 {
00451 uint32_t *pData = (uint32_t *)(void *)pRequest;
00452 volatile uint32_t *pFifo;
00453
00454 pFifo = (volatile uint32_t *)USBHS_RAM_ADDR;
00455 *pData++ = *pFifo;
00456 memory_sync();
00457 pFifo = (volatile uint32_t *)USBHS_RAM_ADDR;
00458 *pData = *pFifo;
00459 memory_sync();
00460 }
00461
00462
00463
00464
00465
00466
00467
00468 static void UDPHS_EndpointHandler(uint8_t bEndpoint)
00469 {
00470 Usbhs *pUdp = USBHS;
00471 Endpoint *pEp = &(endpoints[bEndpoint]);
00472 Transfer *pXfr = (Transfer *) & (pEp->transfer);
00473
00474 uint32_t status = USBHS_ReadEPStatus(pUdp, bEndpoint, 0xFFFFFFFF);
00475 uint32_t type = USBHS_GetEpType(pUdp, bEndpoint);
00476 uint32_t reqBuf[2];
00477 USBGenericRequest *pReq = (USBGenericRequest *)reqBuf;
00478 uint16_t wPktSize;
00479
00480 TRACE_DEBUG_WP("Ep%d ", bEndpoint);
00481
00482
00483
00484
00485 if ((status & USBHS_DEVEPTISR_TXINI)
00486 && USBHS_IsEpIntEnable(pUdp, bEndpoint, USBHS_DEVEPTIMR_TXINE)) {
00487 TRACE_DEBUG_WP("Wr ");
00488
00489
00490 if (pEp->state == UDPHS_ENDPOINT_SENDINGM) {
00491 } else if (pEp->state == UDPHS_ENDPOINT_SENDING) {
00492
00493 if (pXfr->buffered) {
00494 pXfr->transferred += pXfr->buffered;
00495 pXfr->buffered = 0;
00496 }
00497
00498
00499
00500 if (((pXfr->transferred % pEp->size) == 0)
00501 && (pXfr->remaining == 0)
00502 && (pXfr->transferred > 0)
00503 && (pEp->sendZLP == 0))
00504 pEp->sendZLP = 1;
00505
00506
00507 if (pXfr->buffered == 0
00508 && pXfr->transferred == 0
00509 && pXfr->remaining == 0
00510 && pEp->sendZLP == 0)
00511 pEp->sendZLP = 1;
00512
00513
00514 if (pXfr->remaining || pEp->sendZLP == 1) {
00515 if (pEp->sendZLP == 1)
00516
00517
00518 pEp->sendZLP = 2;
00519
00520
00521 TRACE_DEBUG_WP("%d ", pEp->size);
00522
00523
00524
00525 UDPHS_WritePayload(bEndpoint, pEp->size);
00526
00527
00528 USBHS_AckEpInterrupt(USBHS, bEndpoint, USBHS_DEVEPTICR_TXINIC);
00529
00530 if (type != USBHS_DEVEPTCFG_EPTYPE_CTRL >> USBHS_DEVEPTCFG_EPTYPE_Pos)
00531
00532 USBHS_DisableEPIntType(pUdp, bEndpoint, USBHS_DEVEPTIDR_FIFOCONC);
00533 } else {
00534
00535 TRACE_DEBUG_WP("l%d ", pXfr->transferred);
00536
00537
00538 if (type != USBHS_DEVEPTCFG_EPTYPE_CTRL >> USBHS_DEVEPTCFG_EPTYPE_Pos)
00539 USBHS_DisableIntEP(pUdp, bEndpoint);
00540
00541 USBHS_DisableEPIntType(pUdp, bEndpoint, USBHS_DEVEPTIDR_TXINEC);
00542 UDPHS_EndOfTransfer(bEndpoint, USBD_STATUS_SUCCESS);
00543 pEp->sendZLP = 0;
00544 }
00545 } else {
00546
00547 if (bEndpoint == 0)
00548 USBHS_AckEpInterrupt(USBHS, bEndpoint, USBHS_DEVEPTICR_TXINIC);
00549
00550 TRACE_DEBUG("Err Wr %d\n\r", pEp->sendZLP);
00551 }
00552 }
00553
00554
00555 if (USBHS_DEVEPTISR_RXOUTI & status) {
00556 TRACE_DEBUG_WP("Rd ");
00557
00558
00559 if (pEp->state != UDPHS_ENDPOINT_RECEIVING) {
00560
00561 if (((USBHS_DEVEPTCFG_EPTYPE_CTRL >> USBHS_DEVEPTCFG_EPTYPE_Pos) == type)
00562 && (0 == (status & USBHS_DEVEPTISR_BYCT_Msk))) {
00563 TRACE_INFO_WP("Ack ");
00564 USBHS_AckEpInterrupt(pUdp, bEndpoint, USBHS_DEVEPTICR_RXOUTIC);
00565 UDPHS_EndOfTransfer(bEndpoint, USBD_STATUS_SUCCESS);
00566 }
00567
00568 else if (USBHS_DEVEPTISR_STALLEDI & status) {
00569 TRACE_INFO_WP("Discard ");
00570 USBHS_AckEpInterrupt(pUdp, bEndpoint, USBHS_DEVEPTICR_RXOUTIC);
00571 }
00572
00573 else {
00574 TRACE_INFO_WP("Nak ");
00575 USBHS_AckEpInterrupt(pUdp, bEndpoint, USBHS_DEVEPTICR_RXOUTIC);
00576 }
00577 }
00578
00579 else {
00580 TRACE_DEBUG_WP("%d ", wPktSize);
00581
00582
00583 USBHS_AckEpInterrupt(pUdp, bEndpoint, USBHS_DEVEPTICR_RXOUTIC);
00584
00585 wPktSize = USBHS_ByteCount(pUdp, bEndpoint);
00586 UDPHS_ReadPayload(bEndpoint, wPktSize);
00587
00588
00589 if (type != USBHS_DEVEPTCFG_EPTYPE_CTRL >> USBHS_DEVEPTCFG_EPTYPE_Pos)
00590 USBHS_DisableEPIntType(pUdp, bEndpoint, USBHS_DEVEPTIDR_FIFOCONC);
00591
00592
00593 if (pXfr->remaining == 0 || wPktSize < pEp->size) {
00594 USBHS_DisableEPIntType(pUdp, bEndpoint, USBHS_DEVEPTIDR_RXOUTEC);
00595
00596
00597 if ((USBHS_DEVEPTCFG_EPTYPE_CTRL >> USBHS_DEVEPTCFG_EPTYPE_Pos) != type)
00598 USBHS_DisableIntEP(pUdp, bEndpoint);
00599
00600 UDPHS_EndOfTransfer(bEndpoint, USBD_STATUS_SUCCESS);
00601 USBHS_AckEpInterrupt(pUdp, bEndpoint, USBHS_DEVEPTICR_NAKINIC);
00602 USBHS_AckEpInterrupt(pUdp, bEndpoint, USBHS_DEVEPTICR_TXINIC);
00603 }
00604 }
00605 }
00606
00607
00608 if (USBHS_DEVEPTISR_STALLEDI & status) {
00609
00610 USBHS_AckEpInterrupt(pUdp, bEndpoint, USBHS_DEVEPTICR_STALLEDIC);
00611
00612
00613 if (type == (USBHS_DEVEPTCFG_EPTYPE_ISO >> USBHS_DEVEPTCFG_EPTYPE_Pos)) {
00614 TRACE_WARNING("IsoE[%d]\n\r", bEndpoint);
00615 UDPHS_EndOfTransfer(bEndpoint, USBD_STATUS_ABORTED);
00616
00617 } else {
00618 TRACE_WARNING("Stall[%d]\n\r", bEndpoint);
00619
00620 if (pEp->state != UDPHS_ENDPOINT_HALTED)
00621 USBHS_DisableEPIntType(pUdp, bEndpoint, USBHS_DEVEPTIDR_STALLRQC);
00622 }
00623 }
00624
00625
00626 if (USBHS_DEVEPTISR_RXSTPI & status) {
00627
00628
00629
00630
00631 if (pEp->state == UDPHS_ENDPOINT_RECEIVING
00632 || pEp->state == UDPHS_ENDPOINT_RECEIVINGM
00633 || pEp->state == UDPHS_ENDPOINT_SENDING
00634 || pEp->state == UDPHS_ENDPOINT_SENDINGM)
00635 UDPHS_EndOfTransfer(bEndpoint, USBD_STATUS_SUCCESS);
00636
00637
00638 if (type == (USBHS_DEVEPTCFG_EPTYPE_ISO >> USBHS_DEVEPTCFG_EPTYPE_Pos)) {
00639 TRACE_WARNING("IsoFE[%d]\n\r", bEndpoint);
00640
00641 USBHS_AckEpInterrupt(pUdp, bEndpoint, USBHS_DEVEPTICR_RXSTPIC);
00642 } else {
00643 TRACE_DEBUG_WP("Stup ");
00644
00645 UDPHS_ReadRequest(pReq);
00646
00647 USBHS_AckEpInterrupt(pUdp, bEndpoint, USBHS_DEVEPTICR_RXSTPIC);
00648
00649
00650 USBD_RequestHandler(bEndpoint, pReq);
00651 }
00652 }
00653 }
00654 #ifdef DMA
00655
00656
00657
00658
00659
00660
00661 static inline void UDPHS_DmaSingle(uint8_t bEndpoint, Transfer *pXfr,
00662 uint32_t dwCfg)
00663 {
00664 Usbhs *pUdp = USBHS;
00665 UsbhsDevdma *pUsbDma = &pUdp->USBHS_DEVDMA[bEndpoint];
00666
00667
00668 USBHS_SetDmaBuffAdd(pUsbDma, (uint32_t)&pXfr->pData[pXfr->transferred]);
00669 USBHS_GetDmaStatus(pUsbDma);
00670
00671 TRACE_DEBUG_WP("Dma[B%d:T%d] ", pXfr->buffered, pXfr->transferred);
00672
00673 USBHS_ConfigureDma(pUsbDma, 0);
00674 USBHS_ConfigureDma(pUsbDma,
00675 (USBHS_DEVDMACONTROL_BUFF_LENGTH(pXfr->buffered) | dwCfg));
00676
00677
00678 USBHS_EnableDMAIntEP(pUdp, bEndpoint);
00679 }
00680
00681
00682
00683
00684
00685 static void UDPHS_DmaHandler(uint8_t bEndpoint)
00686 {
00687 Usbhs *pUdp = USBHS;
00688 uint8_t bDmaEndpoint = bEndpoint - 1;
00689
00690 Endpoint *pEp = &(endpoints[bEndpoint]);
00691 Transfer *pXfr = (Transfer *)&(pEp->transfer);
00692
00693 uint32_t dwDmaSr;
00694 int32_t iRemain, iXfred;
00695 uint8_t iRead = 0;
00696 uint8_t bRc = USBD_STATUS_SUCCESS;
00697 UsbhsDevdma *pUsbDma = &pUdp->USBHS_DEVDMA[bDmaEndpoint];
00698
00699 dwDmaSr = USBHS_GetDmaStatus(pUsbDma);
00700 TRACE_DEBUG_WP("iDma%d,%x ", bDmaEndpoint, dwDmaSr);
00701
00702
00703 if (pEp->state == UDPHS_ENDPOINT_SENDINGM)
00704
00705 return;
00706 else if (pEp->state == UDPHS_ENDPOINT_RECEIVINGM)
00707
00708 return;
00709
00710 if ((pUdp->USBHS_DEVDMA[bDmaEndpoint].USBHS_DEVDMACONTROL
00711 & USBHS_DEVDMACONTROL_END_TR_EN) == USBHS_DEVDMACONTROL_END_TR_EN)
00712 iRead = 1;
00713
00714
00715 pUdp->USBHS_DEVDMA[bDmaEndpoint].USBHS_DEVDMACONTROL &= ~
00716 (USBHS_DEVDMACONTROL_END_TR_EN
00717 | USBHS_DEVDMACONTROL_END_B_EN);
00718
00719 if (USBHS_DEVDMASTATUS_END_BF_ST & dwDmaSr) {
00720 TRACE_DEBUG_WP("EoDmaB ");
00721
00722
00723 iRemain = (dwDmaSr & USBHS_DEVDMASTATUS_BUFF_COUNT_Msk)
00724 >> USBHS_DEVDMASTATUS_BUFF_COUNT_Pos;
00725 TRACE_DEBUG_WP("C%d ", iRemain);
00726 iXfred = pXfr->buffered - iRemain;
00727
00728 pXfr->transferred += iXfred;
00729 pXfr->buffered = iRemain;
00730 pXfr->remaining -= iXfred;
00731 TRACE_DEBUG_WP("[B%d:T%d:R%d] ", pXfr->buffered, pXfr->transferred,
00732 pXfr->remaining);
00733
00734
00735 if (pXfr->remaining + pXfr->buffered > 0) {
00736 if (pXfr->remaining > DMA_MAX_FIFO_SIZE)
00737 pXfr->buffered = DMA_MAX_FIFO_SIZE;
00738 else
00739 pXfr->buffered = pXfr->remaining;
00740
00741
00742 UDPHS_DmaSingle(bDmaEndpoint, pXfr, USBHS_DEVDMACONTROL_END_TR_EN
00743 | USBHS_DEVDMACONTROL_END_TR_IT
00744 | USBHS_DEVDMACONTROL_END_B_EN
00745 | USBHS_DEVDMACONTROL_END_BUFFIT
00746 | USBHS_DEVDMACONTROL_CHANN_ENB);
00747 }
00748 } else if (USBHS_DEVDMASTATUS_END_TR_ST & dwDmaSr) {
00749 TRACE_DEBUG_WP("EoDmaT ");
00750 pXfr->transferred = pXfr->buffered -
00751 ((dwDmaSr & USBHS_DEVDMASTATUS_BUFF_COUNT_Msk)
00752 >> USBHS_DEVDMASTATUS_BUFF_COUNT_Pos);
00753 pXfr->remaining = 0;
00754
00755 TRACE_DEBUG_WP("[B%d:T%d] ", pXfr->buffered, pXfr->transferred);
00756 } else {
00757 TRACE_ERROR("UDPHS_DmaHandler: ST 0x%X\n\r", (unsigned int)dwDmaSr);
00758 bRc = USBD_STATUS_ABORTED;
00759 }
00760
00761
00762 if (pXfr->remaining == 0) {
00763 if (iRead)
00764 SCB_InvalidateDCache_by_Addr((uint32_t *)pXfr->pData, pXfr->transferred);
00765
00766 UDPHS_EndOfTransfer(bEndpoint, bRc);
00767 }
00768 }
00769 #endif
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788 static inline uint8_t UDPHS_Write(uint8_t bEndpoint,
00789 const void *pData,
00790 uint32_t dLength)
00791 {
00792 Usbhs *pUdp = USBHS;
00793 uint8_t bDmaEndpoint = bEndpoint - 1;
00794
00795 Endpoint *pEp = &(endpoints[bEndpoint]);
00796 Transfer *pXfr = (Transfer *)&(pEp->transfer);
00797
00798
00799 if (pEp->state != UDPHS_ENDPOINT_IDLE)
00800 return USBD_STATUS_LOCKED;
00801
00802
00803 pEp->state = UDPHS_ENDPOINT_SENDING;
00804 TRACE_DEBUG_WP("Wr%d(%d) ", bEndpoint, dLength);
00805 pEp->sendZLP = 0;
00806
00807 pXfr->pData = (void *) pData;
00808 pXfr->remaining = dLength;
00809 pXfr->buffered = 0;
00810 pXfr->transferred = 0;
00811
00812 #ifdef DMA
00813
00814
00815 if (CHIP_USB_ENDPOINTS_DMA(bEndpoint)
00816 && pXfr->remaining > 0) {
00817
00818 USBHS_AutoSwitchBankEnable(pUdp, bEndpoint, true);
00819
00820 if (pXfr->remaining > DMA_MAX_FIFO_SIZE)
00821
00822 pXfr->buffered = DMA_MAX_FIFO_SIZE;
00823 else
00824
00825 pXfr->buffered = pXfr->remaining;
00826
00827
00828 SCB_CleanDCache_by_Addr((uint32_t *) pData, dLength);
00829 UDPHS_DmaSingle(bDmaEndpoint, pXfr, USBHS_DEVDMACONTROL_END_B_EN
00830 | USBHS_DEVDMACONTROL_END_BUFFIT
00831 | USBHS_DEVDMACONTROL_CHANN_ENB);
00832 return USBD_STATUS_SUCCESS;
00833 }
00834
00835
00836
00837 if (bEndpoint)
00838 while (USBHS_IsBankFree(pUdp, bEndpoint) == false);
00839
00840 #endif
00841
00842 USBHS_AutoSwitchBankEnable(pUdp, bEndpoint, false);
00843
00844 USBHS_EnableIntEP(pUdp, bEndpoint);
00845 USBHS_EnableEPIntType(pUdp, bEndpoint, USBHS_DEVEPTIER_TXINES);
00846 return USBD_STATUS_SUCCESS;
00847 }
00848
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867 static inline uint8_t UDPHS_AddWr(uint8_t bEndpoint,
00868 const void *pData,
00869 uint32_t dLength)
00870 {
00871 Usbhs *pUdp = USBHS;
00872
00873 Endpoint *pEp = &(endpoints[bEndpoint]);
00874 MblTransfer *pMbl = (MblTransfer *)&(pEp->transfer);
00875 USBDTransferBuffer *pTx;
00876
00877
00878 if (dLength >= 0x10000)
00879 return USBD_STATUS_INVALID_PARAMETER;
00880
00881
00882 if (pEp->state > UDPHS_ENDPOINT_IDLE) {
00883
00884 if (pMbl->transType) {
00885 if (pMbl->listState == MBL_FULL)
00886 return USBD_STATUS_LOCKED;
00887 } else
00888 return USBD_STATUS_LOCKED;
00889 }
00890
00891 TRACE_DEBUG_WP("AddW%d(%d) ", bEndpoint, dLength);
00892
00893 pTx = &(pMbl->pMbl[pMbl->inCurr]);
00894 pTx->pBuffer = (uint8_t *)pData;
00895 pTx->size = pTx->remaining = dLength;
00896 pTx->transferred = pTx->buffered = 0;
00897
00898
00899 if (pMbl->inCurr >= (pMbl->listSize - 1))
00900 pMbl->inCurr = 0;
00901 else
00902 pMbl->inCurr ++;
00903
00904 if (pMbl->inCurr == pMbl->outCurr)
00905 pMbl->listState = MBL_FULL;
00906 else
00907 pMbl->listState = 0;
00908
00909
00910 if (MBL_NbBuffer(pMbl->inCurr, pMbl->outCurr, pMbl->listSize)
00911 >= pMbl->offsetSize
00912 && pEp->state == UDPHS_ENDPOINT_IDLE) {
00913 uint8_t nbBanks = CHIP_USB_ENDPOINTS_BANKS(bEndpoint);
00914
00915
00916 pEp->state = UDPHS_ENDPOINT_SENDINGM;
00917 TRACE_DEBUG_WP("StartM ");
00918
00919
00920 for (; nbBanks && pMbl->pMbl[pMbl->inCurr].remaining; nbBanks --) {
00921 UDPHS_MblWriteFifo(bEndpoint);
00922 USBHS_RaiseEPInt(pUdp, bEndpoint, USBHS_DEVEPTIFR_TXINIS);
00923 }
00924
00925
00926 USBHS_EnableIntEP(pUdp, bEndpoint);
00927 USBHS_EnableEPIntType(pUdp, bEndpoint, USBHS_DEVEPTIER_TXINES);
00928 }
00929
00930 return USBD_STATUS_SUCCESS;
00931 }
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947 static inline uint8_t UDPHS_Read(uint8_t bEndpoint,
00948 void *pData,
00949 uint32_t dLength)
00950 {
00951 Usbhs *pUdp = USBHS;
00952 uint8_t bDmaEndpoint = (bEndpoint - 1);
00953 Endpoint *pEp = &(endpoints[bEndpoint]);
00954 Transfer *pXfr = (Transfer *)&(pEp->transfer);
00955
00956
00957 if (pEp->state != UDPHS_ENDPOINT_IDLE)
00958 return USBD_STATUS_LOCKED;
00959
00960
00961 pEp->state = UDPHS_ENDPOINT_RECEIVING;
00962
00963 TRACE_DEBUG_WP("Rd%d(%d) ", bEndpoint, dLength);
00964
00965 pXfr->pData = (void *)pData;
00966 pXfr->remaining = dLength;
00967 pXfr->buffered = 0;
00968 pXfr->transferred = 0;
00969
00970 #ifdef DMA
00971
00972
00973 if (CHIP_USB_ENDPOINTS_DMA(bEndpoint) && pXfr->remaining > 0) {
00974
00975 if (pXfr->remaining > DMA_MAX_FIFO_SIZE)
00976 pXfr->buffered = DMA_MAX_FIFO_SIZE;
00977 else
00978 pXfr->buffered = pXfr->remaining;
00979
00980
00981 UDPHS_DmaSingle(bDmaEndpoint, pXfr, USBHS_DEVDMACONTROL_END_TR_EN
00982 | USBHS_DEVDMACONTROL_END_TR_IT
00983 | USBHS_DEVDMACONTROL_END_B_EN
00984 | USBHS_DEVDMACONTROL_END_BUFFIT
00985 | USBHS_DEVDMACONTROL_CHANN_ENB);
00986 return USBD_STATUS_SUCCESS;
00987 }
00988
00989 #endif
00990
00991
00992 USBHS_EnableIntEP(pUdp, bEndpoint);
00993 USBHS_EnableEPIntType(pUdp, bEndpoint, USBHS_DEVEPTIER_RXOUTES);
00994
00995 return USBD_STATUS_SUCCESS;
00996 }
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006 void USBHS_Handler(void)
01007 {
01008 Usbhs *pUdp = USBHS;
01009
01010 uint32_t status;
01011 uint8_t numIt;
01012
01013 status = USBHS_ReadIntStatus(pUdp, 0xFFFFFFFF);
01014 status &= USBHS_IsIntEnable(pUdp, 0xFFFFFFFF);
01015
01016
01017 TRACE_DEBUG_WP("\n\r%c ", USBD_HAL_IsHighSpeed() ? 'H' : 'F');
01018
01019 while (status) {
01020
01021 if (status & USBHS_DEVISR_SOF) {
01022 TRACE_DEBUG_WP("SOF ");
01023
01024
01025 USBHS_AckInt(pUdp, USBHS_DEVICR_SOFC);
01026 } else if (status & USBHS_DEVISR_MSOF) {
01027
01028 TRACE_DEBUG_WP("Mosf ");
01029
01030 USBHS_AckInt(pUdp, USBHS_DEVICR_MSOFC);
01031 } else if (status & USBHS_DEVISR_SUSP) {
01032
01033 TRACE_WARNING_WP("Susp ");
01034 USBHS_UnFreezeClock(USBHS);
01035 USBHS_AckInt(pUdp, USBHS_DEVICR_SUSPC);
01036 USBHS_DisableInt(pUdp, USBHS_DEVIDR_SUSPEC);
01037
01038
01039 USBHS_EnableInt(pUdp, USBHS_DEVIER_WAKEUPES);
01040 USBHS_FreezeClock(pUdp);
01041 USBD_SuspendHandler();
01042 USBHS_EnableInt(pUdp, USBHS_DEVIER_UPRSMES);
01043 } else if (status & USBHS_DEVISR_WAKEUP) {
01044
01045 TRACE_INFO_WP("Rsm ");
01046 USBHS_UnFreezeClock(USBHS);
01047 USBHS_AckInt(pUdp, USBHS_DEVICR_WAKEUPC);
01048 USBHS_DisableInt(pUdp, USBHS_DEVIDR_WAKEUPEC);
01049
01050
01051 USBHS_EnableInt(pUdp, (USBHS_DEVIER_SUSPES | USBHS_DEVIER_EORSMES));
01052 USBD_ResumeHandler();
01053 } else if (status & USBHS_DEVISR_EORSM) {
01054
01055 USBHS_AckInt(pUdp, (USBHS_DEVICR_EORSMC));
01056 USBHS_DisableInt(pUdp, (USBHS_DEVIDR_EORSMEC));
01057 } else if (status & USBHS_DEVISR_EORST) {
01058 TRACE_DEBUG_WP("EoB ");
01059
01060 USBHS_AckInt(pUdp, USBHS_DEVICR_EORSTC);
01061
01062 USBHS_AckInt(pUdp, (USBHS_DEVICR_SUSPC | USBHS_DEVICR_WAKEUPC));
01063 USBHS_EnableInt(pUdp, USBHS_DEVIER_SUSPES);
01064
01065
01066 USBD_ResetHandler();
01067 USBHS_EnableInt(pUdp, USBHS_DEVIER_SUSPES |
01068 USBHS_DEVIER_SOFES | USBHS_DEVIER_MSOFES);
01069 } else if (status & USBHS_DEVISR_UPRSM) {
01070
01071 TRACE_DEBUG_WP("ExtRes ");
01072
01073 USBHS_AckInt(pUdp, USBHS_DEVICR_UPRSMC);
01074 USBHS_EnableInt(pUdp, (USBHS_DEVIER_EORSMES));
01075 } else {
01076
01077 for (numIt = 0; numIt < CHIP_USB_NUMENDPOINTS; numIt++) {
01078 #ifdef DMA
01079
01080 if ((CHIP_USB_ENDPOINTS_DMA(numIt))
01081 && USBHS_ReadDmaIntStatus(pUdp, numIt - 1))
01082 UDPHS_DmaHandler(numIt);
01083 else
01084 #endif
01085 if (USBHS_ReadEpIntStatus(pUdp, numIt))
01086 UDPHS_EndpointHandler(numIt);
01087 }
01088 }
01089
01090
01091 status = USBHS_ReadIntStatus(pUdp, 0xFFFFFFFF);
01092 status &= USBHS_IsIntEnable(pUdp, 0xFFFFFFFF);
01093
01094 TRACE_DEBUG_WP("\n\r");
01095
01096 if (status) {
01097 TRACE_DEBUG_WP(" - ");
01098 }
01099 }
01100
01101 NVIC_ClearPendingIRQ(USBHS_IRQn);
01102 memory_sync();
01103
01104 }
01105
01106
01107
01108
01109
01110
01111
01112
01113
01114
01115
01116
01117 void USBD_HAL_ResetEPs(uint32_t bmEPs, uint8_t bStatus, uint8_t bKeepCfg)
01118 {
01119 Usbhs *pUdp = USBHS;
01120
01121 Endpoint *pEndpoint;
01122 uint32_t tmp = bmEPs & ((1 << CHIP_USB_NUMENDPOINTS) - 1);
01123 uint8_t ep;
01124 uint32_t epBit, epCfg;
01125
01126 for (ep = 0, epBit = 1; ep < CHIP_USB_NUMENDPOINTS; ep ++) {
01127 if (tmp & epBit) {
01128
01129 pUdp->USBHS_DEVIDR |= (epBit << SHIFT_INTERUPT);
01130
01131 pEndpoint = &(endpoints[ep]);
01132
01133 pEndpoint->bank = 0;
01134
01135 epCfg = pUdp->USBHS_DEVEPTCFG[ep];
01136
01137 USBHS_ResetEP(pUdp, ep);
01138
01139
01140 if (bKeepCfg)
01141 pUdp->USBHS_DEVEPTCFG[ep] = epCfg;
01142 else
01143 pEndpoint->state = UDPHS_ENDPOINT_DISABLED;
01144
01145
01146 USBHS_EnableEPIntType(pUdp, ep, USBHS_DEVEPTIER_RSTDTS);
01147
01148
01149 UDPHS_EndOfTransfer(ep, bStatus);
01150 }
01151
01152 epBit <<= 1;
01153 }
01154 }
01155
01156
01157
01158
01159
01160
01161 void USBD_HAL_CancelIo(uint32_t bmEPs)
01162 {
01163 Usbhs *pUdp = USBHS;
01164
01165 uint32_t tmp = bmEPs & ((1 << CHIP_USB_NUMENDPOINTS) - 1);
01166 uint8_t ep;
01167 uint32_t epBit;
01168
01169 for (ep = 0, epBit = 1; ep < CHIP_USB_NUMENDPOINTS; ep ++) {
01170 if (tmp & epBit) {
01171
01172 pUdp->USBHS_DEVIDR |= (epBit << SHIFT_INTERUPT);
01173
01174 UDPHS_EndOfTransfer(ep, USBD_STATUS_CANCELED);
01175 }
01176
01177 epBit <<= 1;
01178 }
01179 }
01180
01181
01182
01183
01184
01185
01186 uint8_t USBD_HAL_ConfigureEP(const USBEndpointDescriptor *pDescriptor)
01187 {
01188 Usbhs *pUdp = USBHS;
01189
01190 Endpoint *pEndpoint;
01191 uint8_t bEndpoint;
01192 uint8_t bType;
01193 uint8_t bEndpointDir;
01194 uint8_t bNbTrans = 1;
01195 uint8_t bSizeEpt = 0;
01196 uint8_t bHs = ((USBHS_GetUsbSpeed(pUdp) == USBHS_SR_SPEED_HIGH_SPEED) ? true :
01197 false);
01198
01199
01200 if (pDescriptor == 0) {
01201
01202 bEndpoint = 0;
01203 pEndpoint = &(endpoints[bEndpoint]);
01204 bType = USBEndpointDescriptor_CONTROL;
01205 bEndpointDir = 0;
01206 pEndpoint->size = CHIP_USB_ENDPOINTS_MAXPACKETSIZE(0);
01207 pEndpoint->bank = CHIP_USB_ENDPOINTS_BANKS(0);
01208 }
01209
01210 else if (pDescriptor->bDescriptorType == USBGenericDescriptor_DEVICE) {
01211 USBDeviceDescriptor *pDevDesc = (USBDeviceDescriptor *)pDescriptor;
01212 bEndpoint = 0;
01213 pEndpoint = &(endpoints[bEndpoint]);
01214 bType = USBEndpointDescriptor_CONTROL;
01215 bEndpointDir = 0;
01216 pEndpoint->size = pDevDesc->bMaxPacketSize0;
01217 pEndpoint->bank = CHIP_USB_ENDPOINTS_BANKS(0);
01218
01219 } else {
01220
01221 bEndpoint = USBEndpointDescriptor_GetNumber(pDescriptor);
01222 pEndpoint = &(endpoints[bEndpoint]);
01223
01224 bType = USBEndpointDescriptor_GetType(pDescriptor);
01225
01226 bEndpointDir = USBEndpointDescriptor_GetDirection(pDescriptor);
01227 pEndpoint->size = USBEndpointDescriptor_GetMaxPacketSize(pDescriptor);
01228 pEndpoint->bank = CHIP_USB_ENDPOINTS_BANKS(bEndpoint);
01229
01230
01231
01232 if (bHs) {
01233
01234 bNbTrans = ((pEndpoint->size >> 11) & 0x3);
01235
01236 if (CHIP_USB_ENDPOINTS_HBW(bEndpoint)) {
01237 if (bNbTrans == 3)
01238 bNbTrans = 1;
01239 else
01240 bNbTrans ++;
01241 } else
01242 bNbTrans = 0;
01243
01244
01245 pEndpoint->size &= 0x7FF;
01246 }
01247 }
01248
01249 TRACE_DEBUG_WP("CfgE%d ", bEndpoint);
01250
01251
01252
01253 if ((pEndpoint->state == UDPHS_ENDPOINT_RECEIVING)
01254 || (pEndpoint->state == UDPHS_ENDPOINT_SENDING)
01255 || (pEndpoint->state == UDPHS_ENDPOINT_RECEIVINGM)
01256 || (pEndpoint->state == UDPHS_ENDPOINT_SENDINGM))
01257
01258 UDPHS_EndOfTransfer(bEndpoint, USBD_STATUS_RESET);
01259
01260 pEndpoint->state = UDPHS_ENDPOINT_IDLE;
01261
01262
01263
01264 if (pEndpoint->size <= 8)
01265 bSizeEpt = 0;
01266 else if (pEndpoint->size <= 16)
01267 bSizeEpt = 1;
01268 else if (pEndpoint->size <= 32)
01269 bSizeEpt = 2;
01270 else if (pEndpoint->size <= 64)
01271 bSizeEpt = 3;
01272 else if (pEndpoint->size <= 128)
01273 bSizeEpt = 4;
01274 else if (pEndpoint->size <= 256)
01275 bSizeEpt = 5;
01276 else if (pEndpoint->size <= 512)
01277 bSizeEpt = 6;
01278 else if (pEndpoint->size <= 1024)
01279 bSizeEpt = 7;
01280
01281
01282 if (bType == USBEndpointDescriptor_CONTROL)
01283 USBHS_EnableIntEP(pUdp, bEndpoint);
01284
01285 USBHS_ConfigureEPs(pUdp, bEndpoint, bType, bEndpointDir, bSizeEpt,
01286 ((pEndpoint->bank) - 1));
01287
01288 USBHS_AllocateMemory(pUdp, bEndpoint);
01289
01290 while ((USBHS_DEVEPTISR_CFGOK & pUdp->USBHS_DEVEPTISR[bEndpoint]) == 0) {
01291
01292
01293 TRACE_ERROR("PB bEndpoint: 0x%X\n\r", bEndpoint);
01294 TRACE_ERROR("PB bSizeEpt: 0x%X\n\r", bSizeEpt);
01295 TRACE_ERROR("PB bEndpointDir: 0x%X\n\r", bEndpointDir);
01296 TRACE_ERROR("PB bType: 0x%X\n\r", bType);
01297 TRACE_ERROR("PB pEndpoint->bank: 0x%X\n\r", pEndpoint->bank);
01298 TRACE_ERROR("PB UDPHS_EPTCFG: 0x%X\n\r",
01299 (unsigned int)pUdp->USBHS_DEVEPTCFG[bEndpoint]);
01300
01301 for (;;);
01302 }
01303
01304 if (bType == USBEndpointDescriptor_CONTROL) {
01305
01306 USBHS_EnableEP(pUdp, bEndpoint, true);
01307
01308 USBHS_EnableEPIntType(pUdp, bEndpoint,
01309 USBHS_DEVEPTIER_RXOUTES | USBHS_DEVEPTIER_RXSTPES);
01310
01311 USBHS_EnableIntEP(pUdp, bEndpoint);
01312 } else {
01313 #ifndef DMA
01314 USBHS_EnableEP(pUdp, bEndpoint, true);
01315 #else
01316 USBHS_EnableEP(pUdp, bEndpoint, true);
01317
01318 if (bType == USBEndpointDescriptor_ISOCHRONOUS)
01319 USBHS_SetIsoTrans(pUdp, bEndpoint, bNbTrans);
01320
01321 USBHS_AutoSwitchBankEnable(pUdp, bEndpoint, true);
01322 #endif
01323 }
01324
01325
01326 return bEndpoint;
01327 }
01328
01329
01330
01331
01332
01333
01334
01335
01336
01337
01338 uint8_t USBD_HAL_SetTransferCallback(uint8_t bEP,
01339 TransferCallback fCallback,
01340 void *pCbData)
01341 {
01342 Endpoint *pEndpoint = &(endpoints[bEP]);
01343 TransferHeader *pTransfer = (TransferHeader *) & (pEndpoint->transfer);
01344
01345
01346 if (pEndpoint->state > UDPHS_ENDPOINT_IDLE)
01347 return USBD_STATUS_LOCKED;
01348
01349 TRACE_DEBUG_WP("sXfrCb ");
01350
01351 pTransfer->fCallback = (void *)fCallback;
01352 pTransfer->pArgument = pCbData;
01353 return USBD_STATUS_SUCCESS;
01354 }
01355
01356
01357
01358
01359
01360
01361
01362
01363 uint8_t USBD_HAL_SetupMblTransfer(uint8_t bEndpoint,
01364 USBDTransferBuffer *pMbList,
01365 uint16_t mblSize,
01366 uint16_t startOffset)
01367 {
01368 Endpoint *pEndpoint = &(endpoints[bEndpoint]);
01369 MblTransfer *pXfr = (MblTransfer *)&(pEndpoint->transfer);
01370 uint16_t i;
01371
01372
01373 if (pEndpoint->state > UDPHS_ENDPOINT_IDLE)
01374 return USBD_STATUS_LOCKED;
01375
01376 TRACE_DEBUG_WP("sMblXfr ");
01377
01378
01379 if (pMbList) {
01380
01381 for (i = 0; i < mblSize; i --) {
01382 pMbList[i].pBuffer = NULL;
01383 pMbList[i].size = 0;
01384 pMbList[i].transferred = 0;
01385 pMbList[i].buffered = 0;
01386 pMbList[i].remaining = 0;
01387 }
01388
01389
01390 pXfr->transType = 1;
01391 pXfr->listState = 0;
01392 pXfr->listSize = mblSize;
01393 pXfr->pMbl = pMbList;
01394 pXfr->outCurr = pXfr->outLast = 0;
01395 pXfr->inCurr = 0;
01396 pXfr->offsetSize = startOffset;
01397 }
01398
01399 else {
01400 pXfr->transType = 0;
01401 pXfr->pMbl = NULL;
01402 pXfr->listSize = 0;
01403 pXfr->offsetSize = 1;
01404 }
01405
01406 return USBD_STATUS_SUCCESS;
01407 }
01408
01409
01410
01411
01412
01413
01414
01415
01416
01417
01418
01419
01420
01421
01422
01423
01424
01425
01426
01427 uint8_t USBD_HAL_Write(uint8_t bEndpoint,
01428 const void *pData,
01429 uint32_t dLength)
01430 {
01431 if (endpoints[bEndpoint].transfer.transHdr.transType)
01432 return UDPHS_AddWr(bEndpoint, pData, dLength);
01433 else
01434 return UDPHS_Write(bEndpoint, pData, dLength);
01435 }
01436
01437
01438
01439
01440
01441
01442
01443
01444
01445
01446
01447
01448
01449
01450
01451
01452
01453
01454
01455
01456 uint8_t USBD_HAL_WrWithHdr(uint8_t bEndpoint,
01457 const void *pHdr, uint8_t bHdrLen,
01458 const void *pData, uint32_t dLength)
01459 {
01460 Usbhs *pUdp = USBHS;
01461
01462 Endpoint *pEp = &(endpoints[bEndpoint]);
01463 uint8_t bDmaEndpoint = (bEndpoint - 1);
01464 Transfer *pXfr = (Transfer *)&(pEp->transfer);
01465
01466
01467 if (!CHIP_USB_ENDPOINTS_DMA(bEndpoint))
01468 return USBD_STATUS_HW_NOT_SUPPORTED;
01469
01470 #ifdef DMA
01471
01472
01473 if (pEp->state != UDPHS_ENDPOINT_IDLE)
01474 return USBD_STATUS_LOCKED;
01475
01476
01477 pEp->state = UDPHS_ENDPOINT_SENDING;
01478 TRACE_DEBUG_WP("Wr%d(%d+%d) ", bEndpoint, bHdrLen, dLength);
01479
01480 pEp->sendZLP = 0;
01481
01482
01483 pXfr->pData = (void *) pData;
01484 pXfr->remaining = bHdrLen + dLength;
01485 pXfr->buffered = 0;
01486 pXfr->transferred = 0;
01487
01488 SCB_CleanDCache_by_Addr((uint32_t *)pHdr, bHdrLen);
01489 SCB_CleanDCache_by_Addr((uint32_t *)pData, dLength);
01490
01491
01492 if (bHdrLen + dLength > 0) {
01493 uint8_t bNbTrans = (USBHS_GetConfigureEPs(pUdp, bEndpoint,
01494 USBHS_DEVEPTCFG_NBTRANS_Msk)
01495 >> USBHS_DEVEPTCFG_NBTRANS_Pos);
01496
01497 if (pXfr->remaining > DMA_MAX_FIFO_SIZE)
01498
01499 pXfr->buffered = DMA_MAX_FIFO_SIZE;
01500 else
01501
01502 pXfr->buffered = pXfr->remaining;
01503
01504
01505
01506
01507 pDmaLL[0].pNxtDesc = (void *)&pDmaLL[1];
01508 pDmaLL[0].pAddr = (void *)pHdr;
01509 pDmaLL[0].dwCtrl = USBHS_DEVDMACONTROL_CHANN_ENB
01510 | USBHS_DEVDMACONTROL_BUFF_LENGTH(bHdrLen)
01511 | USBHS_DEVDMACONTROL_LDNXT_DSC;
01512
01513
01514 if (bNbTrans > 1) {
01515 uint8_t *pU8 = (uint8_t *)pData;
01516 uint32_t maxSize = bNbTrans * pEp->size;
01517 dLength = pXfr->buffered - bHdrLen;
01518
01519 if (dLength > maxSize) dLength = maxSize;
01520
01521 uint32_t pktLen, ndxData = 0;
01522
01523 pktLen = pEp->size - bHdrLen;
01524
01525
01526 if (pktLen >= dLength) {
01527 pDmaLL[1].pNxtDesc = (void *)NULL;
01528 pDmaLL[1].pAddr = (void *)pU8;
01529 pDmaLL[1].dwCtrl = USBHS_DEVDMACONTROL_CHANN_ENB
01530 | USBHS_DEVDMACONTROL_BUFF_LENGTH(dLength)
01531 | USBHS_DEVDMACONTROL_END_B_EN
01532 | USBHS_DEVDMACONTROL_END_BUFFIT;
01533 } else {
01534 pDmaLL[1].pNxtDesc = (void *)&pDmaLL[2];
01535 pDmaLL[1].pAddr = (void *)pU8;
01536 pDmaLL[1].dwCtrl = USBHS_DEVDMACONTROL_CHANN_ENB
01537 | USBHS_DEVDMACONTROL_BUFF_LENGTH(pktLen)
01538 | USBHS_DEVDMACONTROL_END_B_EN
01539 | USBHS_DEVDMACONTROL_LDNXT_DSC;
01540
01541 dLength -= pktLen;
01542 ndxData += pktLen;
01543
01544 pktLen = pEp->size;
01545
01546 if (pktLen >= dLength) {
01547 pDmaLL[1].pNxtDesc = (void *) NULL;
01548 pDmaLL[1].pAddr = (void *)&pU8[ndxData];
01549 pDmaLL[1].dwCtrl = USBHS_DEVDMACONTROL_CHANN_ENB
01550 | USBHS_DEVDMACONTROL_BUFF_LENGTH(dLength)
01551 | USBHS_DEVDMACONTROL_END_B_EN
01552 | USBHS_DEVDMACONTROL_END_BUFFIT;
01553 } else {
01554 pDmaLL[2].pNxtDesc = (void *)&pDmaLL[3];
01555 pDmaLL[2].pAddr = (void *)&pU8[ndxData];
01556 pDmaLL[2].dwCtrl = USBHS_DEVDMACONTROL_CHANN_ENB
01557 | USBHS_DEVDMACONTROL_BUFF_LENGTH(pktLen)
01558 | USBHS_DEVDMACONTROL_END_B_EN
01559 | USBHS_DEVDMACONTROL_LDNXT_DSC;
01560 dLength -= pktLen; ndxData += pktLen;
01561
01562 pDmaLL[3].pNxtDesc = (void *) NULL;
01563 pDmaLL[3].pAddr = (void *)&pU8[ndxData];
01564 pDmaLL[3].dwCtrl = USBHS_DEVDMACONTROL_CHANN_ENB
01565 | USBHS_DEVDMACONTROL_BUFF_LENGTH(dLength)
01566 | USBHS_DEVDMACONTROL_END_B_EN
01567 | USBHS_DEVDMACONTROL_END_BUFFIT;
01568 }
01569 }
01570
01571
01572 } else {
01573
01574 dLength = pXfr->buffered - bHdrLen;
01575 pDmaLL[1].pNxtDesc = (void *)NULL;
01576 pDmaLL[1].pAddr = (void *)pData;
01577 pDmaLL[1].dwCtrl = USBHS_DEVDMACONTROL_CHANN_ENB
01578 | USBHS_DEVDMACONTROL_BUFF_LENGTH(dLength)
01579 | USBHS_DEVDMACONTROL_END_B_EN
01580 | USBHS_DEVDMACONTROL_END_BUFFIT;
01581 }
01582
01583 SCB_CleanDCache_by_Addr((uint32_t *)dmaLL, sizeof(dmaLL));
01584
01585 USBHS_EnableDMAIntEP(pUdp, bDmaEndpoint);
01586
01587 pUdp->USBHS_DEVDMA[bDmaEndpoint].USBHS_DEVDMANXTDSC = (uint32_t)pDmaLL;
01588 pUdp->USBHS_DEVDMA[bDmaEndpoint].USBHS_DEVDMACONTROL = 0;
01589 pUdp->USBHS_DEVDMA[bDmaEndpoint].USBHS_DEVDMACONTROL =
01590 USBHS_DEVDMACONTROL_LDNXT_DSC;
01591 return USBD_STATUS_SUCCESS;
01592 }
01593
01594 #endif
01595
01596
01597 USBHS_EnableIntEP(pUdp, bEndpoint);
01598 USBHS_EnableEPIntType(pUdp, bEndpoint, USBHS_DEVEPTIER_TXINES);
01599 return USBD_STATUS_SUCCESS;
01600 }
01601
01602
01603
01604
01605
01606
01607
01608
01609
01610
01611
01612
01613
01614
01615
01616 uint8_t USBD_HAL_Read(uint8_t bEndpoint,
01617 void *pData,
01618 uint32_t dLength)
01619 {
01620 if (endpoints[bEndpoint].transfer.transHdr.transType)
01621 return USBD_STATUS_SW_NOT_SUPPORTED;
01622 else
01623 return UDPHS_Read(bEndpoint, pData, dLength);
01624 }
01625
01626
01627
01628
01629
01630
01631
01632
01633 void USBD_HAL_Connect(void)
01634 {
01635 uint32_t Interrupt;
01636
01637
01638
01639
01640 USBHS_UnFreezeClock(USBHS);
01641
01642
01643 USBHS_DetachUsb(USBHS, false);
01644
01645
01646
01647
01648
01649 USBD_HAL_ConfigureEP(0);
01650
01651
01652 Interrupt = (USBHS_DEVIER_EORSTES | USBHS_DEVIER_WAKEUPES |
01653 USBHS_DEVIER_SUSPES);
01654
01655 #ifdef USB_DEVICE_HS_SUPPORT
01656 Interrupt |= USBHS_DEVIER_MSOFES;
01657 #endif
01658
01659 USBHS_EnableInt(USBHS, Interrupt);
01660
01661
01662 Interrupt = (USBHS_DEVICR_EORSTC | USBHS_DEVICR_SOFC | USBHS_DEVICR_MSOFC |
01663 USBHS_DEVICR_SUSPC);
01664 USBHS_AckInt(USBHS, Interrupt);
01665
01666
01667
01668 USBHS_RaiseInt(USBHS, USBHS_DEVIFR_SUSPS);
01669
01670 USBHS_AckInt(USBHS, USBHS_DEVICR_WAKEUPC);
01671
01672 USBHS_FreezeClock(USBHS);
01673 }
01674
01675
01676
01677
01678
01679
01680
01681
01682 void USBD_HAL_Disconnect(void)
01683 {
01684 USBHS_FreezeClock(USBHS);
01685
01686 USBHS_DetachUsb(USBHS, true);
01687 }
01688
01689
01690
01691
01692 void USBD_HAL_RemoteWakeUp(void)
01693 {
01694 Usbhs *pUdp = USBHS;
01695 TRACE_INFO_WP("RWUp ");
01696
01697
01698 USBHS_SetRemoteWakeUp(pUdp);
01699
01700 while (pUdp->USBHS_DEVCTRL & USBHS_DEVCTRL_RMWKUP);
01701
01702 TRACE_DEBUG_WP("w");
01703 }
01704
01705
01706
01707
01708
01709 void USBD_HAL_SetAddress(uint8_t address)
01710 {
01711 Usbhs *pUdp = USBHS;
01712
01713 if (address)
01714 USBHS_SetAddress(pUdp, address);
01715 else
01716 USBHS_EnableAddress(pUdp, false);
01717 }
01718
01719
01720
01721
01722
01723 void USBD_HAL_SetConfiguration(uint8_t cfgnum)
01724 {
01725
01726 cfgnum = cfgnum;
01727 }
01728
01729
01730
01731
01732 void USBD_HAL_Init(void)
01733 {
01734
01735 #ifdef DMA
01736
01737
01738 if ((uint32_t)dmaLL & 0xFFFFFFF0)
01739 pDmaLL = (UdphsDmaDescriptor *)((uint32_t)&dmaLL[1] & 0xFFFFFFF0);
01740 else
01741 pDmaLL = (UdphsDmaDescriptor *)((uint32_t)&dmaLL[0]);
01742
01743 #endif
01744
01745 USBHS_UsbEnable(USBHS, false);
01746
01747 USBHS_UsbMode(USBHS, DEVICE_MODE);
01748
01749
01750 USBHS_UsbEnable(USBHS, true);
01751
01752 USBHS_UnFreezeClock(USBHS);
01753
01754 if (ForceFS)
01755 USBHS_EnableHighSpeed(USBHS, false);
01756 else
01757 USBHS_EnableHighSpeed(USBHS, true);
01758
01759
01760 while (!USBHS_ISUsableClock(USBHS));
01761
01762 USBHS_FreezeClock(USBHS);
01763
01764
01765 NVIC_ClearPendingIRQ(USBHS_IRQn);
01766
01767 NVIC_EnableIRQ(USBHS_IRQn);
01768
01769 }
01770
01771
01772
01773
01774
01775
01776
01777 uint8_t USBD_HAL_Stall(uint8_t bEP)
01778 {
01779 Usbhs *pUdp = USBHS;
01780
01781 Endpoint *pEndpoint = &(endpoints[bEP]);
01782
01783
01784 if (pEndpoint->state != UDPHS_ENDPOINT_IDLE) {
01785 TRACE_WARNING("UDP_Stall: EP%d locked\n\r", bEP);
01786 return USBD_STATUS_LOCKED;
01787 }
01788
01789
01790 USBHS_EnableEPIntType(pUdp, bEP, USBHS_DEVEPTIER_STALLRQS);
01791
01792 TRACE_INFO_WP("Stall%d ", bEP);
01793 return USBD_STATUS_SUCCESS;
01794 }
01795
01796
01797
01798
01799
01800
01801
01802
01803
01804
01805
01806
01807 uint8_t USBD_HAL_Halt(uint8_t bEndpoint, uint8_t ctl)
01808 {
01809 Usbhs *pUdp = USBHS;
01810
01811 Endpoint *pEndpoint = &(endpoints[bEndpoint]);
01812 uint8_t bDmaEndpoint = (bEndpoint - 1);
01813 uint8_t status = 0;
01814
01815
01816 if (ctl == 1) {
01817
01818 if ((pEndpoint->state != UDPHS_ENDPOINT_DISABLED)
01819 && (pEndpoint->state != UDPHS_ENDPOINT_HALTED)) {
01820
01821 TRACE_INFO_WP("Halt%d ", bEndpoint);
01822
01823
01824 UDPHS_EndOfTransfer(bEndpoint, USBD_STATUS_ABORTED);
01825
01826
01827 pEndpoint->state = UDPHS_ENDPOINT_HALTED;
01828 memory_sync();
01829
01830 while (!USBHS_IsBankFree(pUdp, bEndpoint)) {
01831 USBHS_KillBank(pUdp, bEndpoint);
01832
01833 while (USBHS_IsBankKilled(pUdp, bEndpoint));
01834 }
01835
01836 if (USBHS_IsBankFree(pUdp, bEndpoint)) {
01837 USBHS_AutoSwitchBankEnable(pUdp, bEndpoint, false);
01838 USBHS_EnableEPIntType(pUdp, bEndpoint,
01839 (USBHS_DEVEPTIER_STALLRQS | USBHS_DEVEPTIER_RSTDTS));
01840 } else {
01841 USBHS_EnableEPIntType(pUdp, bEndpoint, USBHS_DEVEPTIER_NBUSYBKES);
01842 #ifdef DMA
01843
01844 if (CHIP_USB_ENDPOINTS_DMA(bDmaEndpoint)) {
01845
01846 USBHS_EnableDMAIntEP(pUdp, bDmaEndpoint);
01847 } else {
01848
01849 USBHS_EnableIntEP(pUdp, bEndpoint);
01850 }
01851
01852 #else
01853
01854 USBHS_EnableIntEP(pUdp, bEndpoint);
01855 #endif
01856 }
01857 }
01858
01859
01860 } else if (ctl == 0) {
01861
01862 if ((pEndpoint->state == UDPHS_ENDPOINT_HALTED)
01863 || (USBHS_IsEpIntEnable(pUdp, bEndpoint, USBHS_DEVEPTIMR_STALLRQ))) {
01864 TRACE_INFO_WP("Unhalt%d ", bEndpoint);
01865
01866 pEndpoint->state = UDPHS_ENDPOINT_IDLE;
01867
01868
01869 USBHS_DisableEPIntType(pUdp, bEndpoint, USBHS_DEVEPTIDR_STALLRQC);
01870 USBHS_AutoSwitchBankEnable(pUdp, bEndpoint, true);
01871 }
01872 }
01873
01874
01875 if (pEndpoint->state == UDPHS_ENDPOINT_HALTED)
01876 status = 1;
01877
01878 return (status);
01879 }
01880
01881
01882
01883
01884
01885 void USBD_HAL_WaitReadData(uint8_t bEndpoint)
01886 {
01887 Usbhs *pUdp = USBHS;
01888
01889 while (USBHS_ByteCount(pUdp, bEndpoint) == 0);
01890 }
01891
01892
01893
01894
01895
01896 uint8_t USBD_HAL_IsHighSpeed(void)
01897 {
01898 return USBHS_IsUsbHighSpeed(USBHS);
01899 }
01900
01901
01902
01903
01904
01905
01906
01907
01908 void USBD_HAL_Suspend(void)
01909 {
01910
01911 USBHS_FreezeClock(USBHS);
01912 }
01913
01914
01915
01916
01917
01918
01919
01920 void USBD_HAL_Activate(void)
01921 {
01922 USBHS_UnFreezeClock(USBHS);
01923 }
01924
01925 void USBD_HAL_Disable(void)
01926 {
01927
01928 USBHS_UsbEnable(USBHS, false);
01929
01930
01931 NVIC_ClearPendingIRQ(USBHS_IRQn);
01932
01933 NVIC_DisableIRQ(USBHS_IRQn);
01934 }
01935
01936
01937
01938
01939
01940
01941 void USBD_HAL_Test(uint8_t bIndex)
01942 {
01943 Usbhs *pUdp = USBHS;
01944 uint8_t *pFifo;
01945 uint32_t i;
01946
01947
01948 USBHS_DisableInt(pUdp, USBHS_DEVIDR_SUSPEC);
01949
01950 pUdp->USBHS_DEVCTRL |= USBHS_DEVCTRL_SPDCONF_HIGH_SPEED;
01951
01952 USBHS_EnableTestMode(pUdp, USBHS_DEVCTRL_OPMODE2);
01953
01954 switch (bIndex) {
01955 case USBFeatureRequest_TESTPACKET:
01956 TRACE_DEBUG_WP("TEST_PACKET ");
01957
01958 pUdp->USBHS_DEVDMA[1].USBHS_DEVDMACONTROL = 0;
01959 pUdp->USBHS_DEVDMA[2].USBHS_DEVDMACONTROL = 0;
01960
01961
01962 pUdp->USBHS_DEVEPTCFG[2] = USBHS_DEVEPTCFG_EPSIZE_64_BYTE
01963 | USBHS_DEVEPTCFG_EPDIR
01964 | USBHS_DEVEPTCFG_EPTYPE_BLK
01965 | USBHS_DEVEPTCFG_EPBK_1_BANK;
01966 USBHS_AllocateMemory(pUdp, 2);
01967
01968 while ((USBHS_DEVEPTISR_CFGOK & pUdp->USBHS_DEVEPTISR[2]) !=
01969 USBHS_DEVEPTISR_CFGOK);
01970
01971 USBHS_EnableEP(pUdp, 2, true);
01972
01973
01974 pFifo = (uint8_t *)((uint32_t *)(USBHS_RAM_ADDR) + (EPT_VIRTUAL_SIZE * 2));
01975
01976 for (i = 0; i < sizeof(test_packet_buffer); i++)
01977 pFifo[i] = test_packet_buffer[i];
01978
01979
01980 USBHS_EnableTestMode(pUdp, USBHS_DEVCTRL_TSTPCKT);
01981
01982 USBHS_RaiseEPInt(pUdp, 2, USBHS_DEVEPTIFR_TXINIS);
01983 break;
01984
01985 case USBFeatureRequest_TESTJ:
01986 TRACE_DEBUG_WP("TEST_J ");
01987 USBHS_EnableTestMode(pUdp, USBHS_DEVCTRL_TSTJ);
01988 break;
01989
01990 case USBFeatureRequest_TESTK:
01991 TRACE_DEBUG_WP("TEST_K ");
01992 USBHS_EnableTestMode(pUdp, USBHS_DEVCTRL_TSTK);
01993 break;
01994
01995 case USBFeatureRequest_TESTSE0NAK:
01996 TRACE_DEBUG_WP("TEST_SEO_NAK ");
01997 USBHS_DisableInt(pUdp, 0xFFFFFFFF);
01998 break;
01999
02000 case USBFeatureRequest_TESTSENDZLP:
02001 USBHS_RaiseEPInt(pUdp, 0, USBHS_DEVEPTIFR_TXINIS);
02002 TRACE_DEBUG_WP("SEND_ZLP ");
02003 break;
02004 }
02005
02006 TRACE_DEBUG_WP("\n\r");
02007 }
02008
02009
02010