USBD_HAL.c
Go to the documentation of this file.
1 /* ---------------------------------------------------------------------------- */
2 /* Atmel Microcontroller Software Support */
3 /* SAM Software Package License */
4 /* ---------------------------------------------------------------------------- */
5 /* Copyright (c) 2015, Atmel Corporation */
6 /* */
7 /* All rights reserved. */
8 /* */
9 /* Redistribution and use in source and binary forms, with or without */
10 /* modification, are permitted provided that the following condition is met: */
11 /* */
12 /* - Redistributions of source code must retain the above copyright notice, */
13 /* this list of conditions and the disclaimer below. */
14 /* */
15 /* Atmel's name may not be used to endorse or promote products derived from */
16 /* this software without specific prior written permission. */
17 /* */
18 /* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR */
19 /* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF */
20 /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE */
21 /* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, */
22 /* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */
23 /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, */
24 /* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF */
25 /* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING */
26 /* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, */
27 /* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
28 /* ---------------------------------------------------------------------------- */
29 
42 /*---------------------------------------------------------------------------
43  * Headers
44  *---------------------------------------------------------------------------*/
45 
46 #include "../../libchip/libchip_compiler.h"
47 #include "../../libchip/include/usbhs.h"
48 #include "USBD_HAL.h"
49 #include "USBLib_Trace.h"
50 
51 #include <stdbool.h>
52 #include <stdint.h>
53 #include <stdio.h>
54 #include <string.h>
55 
56 /*---------------------------------------------------------------------------
57  * Definitions
58  *---------------------------------------------------------------------------*/
59 
60 #define DMA
61 
62 
64 #define SHIFT_INTERUPT 12
65 
82 #define UDPHS_ENDPOINT_DISABLED 0
83 
84 #define UDPHS_ENDPOINT_HALTED 1
85 
86 #define UDPHS_ENDPOINT_IDLE 2
87 
88 #define UDPHS_ENDPOINT_SENDING 3
89 
90 #define UDPHS_ENDPOINT_RECEIVING 4
91 
92 #define UDPHS_ENDPOINT_SENDINGM 5
93 
94 #define UDPHS_ENDPOINT_RECEIVINGM 6
95 
96 
102 #define MBL_NbBuffer(i, o, size) (((i)>(o))?((i)-(o)):((i)+(size)-(o)))
103 
105 #define MBL_FULL 1
106 
107 #define MBL_NULL 2
108 
109 /*---------------------------------------------------------------------------
110  * Types
111  *---------------------------------------------------------------------------*/
112 
114 typedef struct {
116  void *fCallback;
118  void *pArgument;
120  uint8_t transType;
121  /* Reserved to 32-b aligned */
122  uint8_t reserved[3];
124 
126 typedef struct {
127 
131  void *pArgument;
133  uint8_t transType;
134  uint8_t reserved[3];
137  int32_t buffered;
139  uint8_t *pData;
141  int32_t transferred;
143  int32_t remaining;
144 } Transfer;
145 
147 typedef struct {
151  void *pArgument;
153  uint8_t transType;
155  uint8_t listState;
157  uint16_t listSize;
161  uint16_t offsetSize;
163  uint16_t outCurr;
165  uint16_t outLast;
167  uint16_t inCurr;
168 } MblTransfer;
169 
173 typedef struct {
174  /* CSR */
176  volatile uint8_t state;
178  volatile uint8_t bank;
180  volatile uint16_t size;
183  union {
187  } transfer;
189  uint32_t sendZLP;
190 } Endpoint;
191 
195 typedef struct {
196  void *pNxtDesc;
197  void *pAddr;
198  uint32_t dwCtrl;
199  uint32_t dw;
201 
202 /*---------------------------------------------------------------------------
203  * Internal variables
204  *---------------------------------------------------------------------------*/
205 
208 
211 static const char test_packet_buffer[] = {
212  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // JKJKJKJK * 9
213  0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, // JJKKJJKK * 8
214  0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, // JJJJKKKK * 8
215  0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // JJJJJJJKKKKKKK * 8
216  0x7F, 0xBF, 0xDF, 0xEF, 0xF7, 0xFB, 0xFD, // JJJJJJJK * 8
217  0xFC, 0x7E, 0xBF, 0xDF, 0xEF, 0xF7, 0xFB, 0xFD, 0x7E // {JKKKKKKK * 10}, JK
218 };
219 
222 COMPILER_ALIGNED(16) static UdphsDmaDescriptor *pDmaLL;
223 
224 /*---------------------------------------------------------------------------
225  * Internal Functions
226  *---------------------------------------------------------------------------*/
227 
234 static void UDPHS_EndOfTransfer(uint8_t bEndpoint, uint8_t bStatus)
235 {
236  Endpoint *pEp = &(endpoints[bEndpoint]);
237 
238  /* Check that endpoint was sending or receiving data */
239  if ((pEp->state == UDPHS_ENDPOINT_RECEIVING) ||
240  (pEp->state == UDPHS_ENDPOINT_SENDING)) {
241  Transfer *pXfr = (Transfer *)&(pEp->transfer);
242 
243  uint32_t transferred = pXfr->transferred;
244  uint32_t remaining = pXfr->remaining + pXfr->buffered;
245 
246  TRACE_DEBUG_WP("EoT ");
247 
248  if (pEp->state == UDPHS_ENDPOINT_SENDING)
249  pEp->sendZLP = 0;
250 
251  pEp->state = UDPHS_ENDPOINT_IDLE;
252  pXfr->pData = 0;
253  pXfr->transferred = -1;
254  pXfr->buffered = -1;
255  pXfr->remaining = -1;
256 
257  /* Invoke callback */
258  if (pXfr->fCallback) {
259  pXfr->fCallback(pXfr->pArgument, bStatus, transferred, remaining);
260  }
261  else {
262  TRACE_DEBUG_WP("NoCB ");
263  }
264  } else if ((pEp->state == UDPHS_ENDPOINT_RECEIVINGM)
265  || (pEp->state == UDPHS_ENDPOINT_SENDINGM)) {
266  MblTransfer *pXfr = (MblTransfer *) & (pEp->transfer);
267  TRACE_DEBUG_WP("EoMT ");
268 
269  pEp->state = UDPHS_ENDPOINT_IDLE;
270  pXfr->listState = 0;
271  pXfr->outCurr = pXfr->inCurr = pXfr->outLast = 0;
272 
273  /* Invoke callback */
274  if (pXfr->fCallback) {
275  pXfr->fCallback(pXfr->pArgument, bStatus);
276  }
277  else {
278  TRACE_DEBUG_WP("NoCB ");
279  }
280  }
281 }
282 
290 static uint8_t UDPHS_MblUpdate(MblTransfer *pTransfer,
291  USBDTransferBuffer *pBi,
292  uint16_t size,
293  uint8_t forceEnd)
294 {
295  /* Update transfer descriptor */
296  pBi->remaining -= size;
297 
298  /* Check if list NULL */
299  if (pTransfer->listState == MBL_NULL)
300  return 1;
301 
302  /* Check if current buffer ended */
303  if (pBi->remaining == 0 || forceEnd || size == 0) {
304  /* Process to next buffer */
305  if ((++ pTransfer->outCurr) == pTransfer->listSize)
306  pTransfer->outCurr = 0;
307 
308  /* Check buffer NULL case */
309  if (pTransfer->outCurr == pTransfer->inCurr)
310  pTransfer->listState = MBL_NULL;
311  else {
312  pTransfer->listState = 0;
313  /* Continue transfer, prepare for next operation */
314  pBi = &pTransfer->pMbl[pTransfer->outCurr];
315  pBi->buffered = 0;
316  pBi->transferred = 0;
317  pBi->remaining = pBi->size;
318  }
319 
320  return 1;
321  }
322 
323  return 0;
324 }
325 
331 static uint8_t UDPHS_MblWriteFifo(uint8_t bEndpoint)
332 {
333  Endpoint *pEndpoint = &(endpoints[bEndpoint]);
334  MblTransfer *pTransfer = (MblTransfer *)&(pEndpoint->transfer);
335  USBDTransferBuffer *pBi = &(pTransfer->pMbl[pTransfer->outCurr]);
336  uint8_t *pFifo;
337  int32_t size;
338 
339  volatile uint8_t *pBytes;
340  volatile uint8_t bufferEnd = 1;
341 
342  /* Get the number of bytes to send */
343  size = pEndpoint->size;
344 
345  if (size > pBi->remaining) size = pBi->remaining;
346 
347  TRACE_DEBUG_WP("w%d.%d ", pTransfer->outCurr, size);
348 
349  /* Record last accessed buffer */
350  pTransfer->outLast = pTransfer->outCurr;
351 
352  pBytes = &(pBi->pBuffer[pBi->transferred + pBi->buffered]);
353  pBi->buffered += size;
354  bufferEnd = UDPHS_MblUpdate(pTransfer, pBi, size, 0);
355 
356  /* Write packet in the FIFO buffer */
357  pFifo = (uint8_t *)((uint32_t *)USBHS_RAM_ADDR + (EPT_VIRTUAL_SIZE *
358  bEndpoint));
359  memory_sync();
360 
361  if (size) {
362  int32_t c8 = size >> 3;
363  int32_t c1 = size & 0x7;
364 
365  for (; c8; c8 --) {
366  *(pFifo++) = *(pBytes ++);
367  *(pFifo++) = *(pBytes ++);
368  *(pFifo++) = *(pBytes ++);
369  *(pFifo++) = *(pBytes ++);
370 
371  *(pFifo++) = *(pBytes ++);
372  *(pFifo++) = *(pBytes ++);
373  *(pFifo++) = *(pBytes ++);
374  *(pFifo++) = *(pBytes ++);
375  }
376 
377  for (; c1; c1 --)
378  *(pFifo++) = *(pBytes ++);
379  }
380 
381  return bufferEnd;
382 }
383 
389 static void UDPHS_WritePayload(uint8_t bEndpoint, int32_t size)
390 {
391  Endpoint *pEndpoint = &(endpoints[bEndpoint]);
392  Transfer *pTransfer = (Transfer *)&(pEndpoint->transfer);
393  uint8_t *pFifo;
394 
395  /* Get the number of bytes to send */
396  if (size > pTransfer->remaining)
397  size = pTransfer->remaining;
398 
399  /* Update transfer descriptor information */
400  pTransfer->buffered += size;
401  pTransfer->remaining -= size;
402 
403  /* Write packet in the FIFO buffer */
404  pFifo = (uint8_t *)((uint32_t *)USBHS_RAM_ADDR + (EPT_VIRTUAL_SIZE *
405  bEndpoint));
406  memory_sync();
407 
408  for (; size; size --)
409  *(pFifo ++) = *(pTransfer->pData ++);
410 
411  memory_sync();
412 
413 }
414 
420 static void UDPHS_ReadPayload(uint8_t bEndpoint, int32_t wPacketSize)
421 {
422  Endpoint *pEndpoint = &(endpoints[bEndpoint]);
423  Transfer *pTransfer = (Transfer *)&(pEndpoint->transfer);
424  uint8_t *pFifo;
425 
426  /* Check that the requested size is not bigger than the remaining transfer */
427  if (wPacketSize > pTransfer->remaining) {
428  pTransfer->buffered += wPacketSize - pTransfer->remaining;
429  wPacketSize = pTransfer->remaining;
430  }
431 
432  /* Update transfer descriptor information */
433  pTransfer->remaining -= wPacketSize;
434  pTransfer->transferred += wPacketSize;
435 
436  /* Retrieve packet */
437  pFifo = (uint8_t *)((uint32_t *)USBHS_RAM_ADDR
438  + (EPT_VIRTUAL_SIZE * bEndpoint));
439 
440  while (wPacketSize > 0) {
441  *(pTransfer->pData++) = *(pFifo++);
442  memory_sync();
443  wPacketSize--;
444  }
445 }
446 
451 static void UDPHS_ReadRequest(USBGenericRequest *pRequest)
452 {
453  uint32_t *pData = (uint32_t *)(void *)pRequest;
454  volatile uint32_t *pFifo;
455 
456  pFifo = (volatile uint32_t *)USBHS_RAM_ADDR;
457  *pData++ = *pFifo;
458  memory_sync();
459  pFifo = (volatile uint32_t *)USBHS_RAM_ADDR;
460  *pData = *pFifo;
461  memory_sync();
462 }
463 
464 
470 static void UDPHS_EndpointHandler(uint8_t bEndpoint)
471 {
472  Usbhs *pUdp = USBHS;
473  Endpoint *pEp = &(endpoints[bEndpoint]);
474  Transfer *pXfr = (Transfer *) & (pEp->transfer);
475 
476  uint32_t status = USBHS_ReadEPStatus(pUdp, bEndpoint, 0xFFFFFFFF);
477  uint32_t type = USBHS_GetEpType(pUdp, bEndpoint);
478  uint32_t reqBuf[2];
479  USBGenericRequest *pReq = (USBGenericRequest *)reqBuf;
480  uint16_t wPktSize;
481 
482  TRACE_DEBUG_WP("Ep%d ", bEndpoint);
483 
484  /* IN packet sent */
485  /* When the bank is empty, USBHS_DEVEPTISRx.TXINI and USBHS_DEVEPTIMRx.FIFOCON
486  are set, which triggers a PEP_x interrupt if USBHS_DEVEPTIMRx.TXINE = 1.*/
487  if ((status & USBHS_DEVEPTISR_TXINI)
488  && USBHS_IsEpIntEnable(pUdp, bEndpoint, USBHS_DEVEPTIMR_TXINE)) {
489  TRACE_DEBUG_WP("Wr ");
490 
491  /* Multi-buffer-list transfer state */
492  if (pEp->state == UDPHS_ENDPOINT_SENDINGM) {
493  } else if (pEp->state == UDPHS_ENDPOINT_SENDING) {
494  /* Sending state */
495  if (pXfr->buffered) {
496  pXfr->transferred += pXfr->buffered;
497  pXfr->buffered = 0;
498  }
499 
500  /* Force ZLP transmission in total length is a
501  multiple of endpoint size */
502  if (((pXfr->transferred % pEp->size) == 0)
503  && (pXfr->remaining == 0)
504  && (pXfr->transferred > 0)
505  && (pEp->sendZLP == 0))
506  pEp->sendZLP = 1;
507 
508 
509  if (pXfr->buffered == 0
510  && pXfr->transferred == 0
511  && pXfr->remaining == 0
512  && pEp->sendZLP == 0)
513  pEp->sendZLP = 1;
514 
515  /* End of Xfr ? */
516  if (pXfr->remaining || pEp->sendZLP == 1) {
517  if (pEp->sendZLP == 1)
518  /* A null packet will be send, keep trace of it :
519  Change this value only if ZLP will be send!!! */
520  pEp->sendZLP = 2;
521 
522  /* Transfer remaining */
523  TRACE_DEBUG_WP("%d ", pEp->size);
524 
525  /* The user writes the data into the current bank by using
526  the USB Pipe/Endpoint nFIFO Data */
527  UDPHS_WritePayload(bEndpoint, pEp->size);
528 
529  /*Acknowledges the interrupt by clearing TXINIC.*/
531 
533  /* Send the bank and switch to the next bank (if any) by clearing FIFOCON. */
535  } else {
536  /* Transfer done */
537  TRACE_DEBUG_WP("l%d ", pXfr->transferred);
538 
539  /* Disable interrupt on non-control EP */
541  USBHS_DisableIntEP(pUdp, bEndpoint);
542 
544  UDPHS_EndOfTransfer(bEndpoint, USBD_STATUS_SUCCESS);
545  pEp->sendZLP = 0;
546  }
547  } else {
548  /* Clear interrupt when the state of endpoint0 is not SENDING. */
549  if (bEndpoint == 0)
551 
552  TRACE_DEBUG("Err Wr %d\n\r", pEp->sendZLP);
553  }
554  }
555 
556  /* OUT packet received */
557  if (USBHS_DEVEPTISR_RXOUTI & status) {
558  TRACE_DEBUG_WP("Rd ");
559 
560  /* NOT in receiving state */
561  if (pEp->state != UDPHS_ENDPOINT_RECEIVING) {
562  /* Check if ACK received on a Control EP */
564  && (0 == (status & USBHS_DEVEPTISR_BYCT_Msk))) {
565  TRACE_INFO_WP("Ack ");
567  UDPHS_EndOfTransfer(bEndpoint, USBD_STATUS_SUCCESS);
568  }
569  /* data has been STALLed */
570  else if (USBHS_DEVEPTISR_STALLEDI & status) {
571  TRACE_INFO_WP("Discard ");
573  }
574  /* NAK the data */
575  else {
576  TRACE_INFO_WP("Nak ");
578  }
579  }
580  /* In read state */
581  else {
582  TRACE_DEBUG_WP("%d ", wPktSize);
583 
584  /*Acknowledge Received OUT Data Interrupt*/
586 
587  wPktSize = USBHS_ByteCount(pUdp, bEndpoint);
588  UDPHS_ReadPayload(bEndpoint, wPktSize);
589 
590  /*Free the current bank and to switch to the next bank (If any).*/
593 
594  /* Check if transfer is finished */
595  if (pXfr->remaining == 0 || wPktSize < pEp->size) {
597 
598  /* Disable interrupt if not control EP */
600  USBHS_DisableIntEP(pUdp, bEndpoint);
601 
602  UDPHS_EndOfTransfer(bEndpoint, USBD_STATUS_SUCCESS);
605  }
606  }
607  }
608 
609  /* STALL sent */
610  if (USBHS_DEVEPTISR_STALLEDI & status) {
611  /* Acknowledge */
613 
614  /* ISO error */
616  TRACE_WARNING("IsoE[%d]\n\r", bEndpoint);
617  UDPHS_EndOfTransfer(bEndpoint, USBD_STATUS_ABORTED);
618  /* If EP is not halted, clear STALL */
619  } else {
620  TRACE_WARNING("Stall[%d]\n\r", bEndpoint);
621 
622  if (pEp->state != UDPHS_ENDPOINT_HALTED)
624  }
625  }
626 
627  /* SETUP packet received */
628  if (USBHS_DEVEPTISR_RXSTPI & status) {
629  /* If a transfer was pending, complete it
630  Handles the case where during the status phase of a control write
631  transfer, the host receives the device ZLP and ack it, but the ack
632  is not received by the device */
633  if (pEp->state == UDPHS_ENDPOINT_RECEIVING
635  || pEp->state == UDPHS_ENDPOINT_SENDING
636  || pEp->state == UDPHS_ENDPOINT_SENDINGM)
637  UDPHS_EndOfTransfer(bEndpoint, USBD_STATUS_SUCCESS);
638 
639  /* ISO Err Flow */
641  TRACE_WARNING("IsoFE[%d]\n\r", bEndpoint);
642  /* Acknowledge setup packet */
644  } else {
645  TRACE_DEBUG_WP("Stup ");
646  /* Copy setup */
647  UDPHS_ReadRequest(pReq);
648  /* Acknowledge setup packet */
650 
651  /* Handler */
652  USBD_RequestHandler(bEndpoint, pReq);
653  }
654  }
655 }
656 #ifdef DMA
657 
663 static inline void UDPHS_DmaSingle(uint8_t bEndpoint, Transfer *pXfr,
664  uint32_t dwCfg)
665 {
666  Usbhs *pUdp = USBHS;
667  UsbhsDevdma *pUsbDma = &pUdp->USBHS_DEVDMA[bEndpoint];
668 
669  /* Single transfer */
670  USBHS_SetDmaBuffAdd(pUsbDma, (uint32_t)&pXfr->pData[pXfr->transferred]);
671  USBHS_GetDmaStatus(pUsbDma);
672 
673  TRACE_DEBUG_WP("Dma[B%d:T%d] ", pXfr->buffered, pXfr->transferred);
674  /* DMA Configure */
675  USBHS_ConfigureDma(pUsbDma, 0);
676  USBHS_ConfigureDma(pUsbDma,
677  (USBHS_DEVDMACONTROL_BUFF_LENGTH(pXfr->buffered) | dwCfg));
678 
679  /* Interrupt enable */
680  USBHS_EnableDMAIntEP(pUdp, bEndpoint);
681 }
687 static void UDPHS_DmaHandler(uint8_t bEndpoint)
688 {
689  Usbhs *pUdp = USBHS;
690  uint8_t bDmaEndpoint = bEndpoint - 1;
691 
692  Endpoint *pEp = &(endpoints[bEndpoint]);
693  Transfer *pXfr = (Transfer *)&(pEp->transfer);
694 
695  uint32_t dwDmaSr;
696  int32_t iRemain, iXfred;
697  uint8_t iRead = 0;
698  uint8_t bRc = USBD_STATUS_SUCCESS;
699  UsbhsDevdma *pUsbDma = &pUdp->USBHS_DEVDMA[bDmaEndpoint];
700 
701  dwDmaSr = USBHS_GetDmaStatus(pUsbDma);
702  TRACE_DEBUG_WP("iDma%d,%x ", bDmaEndpoint, dwDmaSr);
703 
704  /* Mbl transfer */
705  if (pEp->state == UDPHS_ENDPOINT_SENDINGM)
706  /* Not implemented */
707  return;
708  else if (pEp->state == UDPHS_ENDPOINT_RECEIVINGM)
709  /* Not implemented */
710  return;
711 
712  if ((pUdp->USBHS_DEVDMA[bDmaEndpoint].USBHS_DEVDMACONTROL
713  & USBHS_DEVDMACONTROL_END_TR_EN) == USBHS_DEVDMACONTROL_END_TR_EN)
714  iRead = 1;
715 
716  /* Disable DMA interrupt to avoid receiving 2 (B_EN and TR_EN) */
717  pUdp->USBHS_DEVDMA[bDmaEndpoint].USBHS_DEVDMACONTROL &= ~
718  (USBHS_DEVDMACONTROL_END_TR_EN
720 
721  if (USBHS_DEVDMASTATUS_END_BF_ST & dwDmaSr) {
722  TRACE_DEBUG_WP("EoDmaB ");
723  /* BUFF_COUNT holds the number of untransmitted bytes.
724  BUFF_COUNT is equal to zero in case of good transfer */
725  iRemain = (dwDmaSr & USBHS_DEVDMASTATUS_BUFF_COUNT_Msk)
727  TRACE_DEBUG_WP("C%d ", iRemain);
728  iXfred = pXfr->buffered - iRemain;
729 
730  pXfr->transferred += iXfred;
731  pXfr->buffered = iRemain;
732  pXfr->remaining -= iXfred;
733  TRACE_DEBUG_WP("[B%d:T%d:R%d] ", pXfr->buffered, pXfr->transferred,
734  pXfr->remaining);
735 
736  /* There is still data */
737  if (pXfr->remaining + pXfr->buffered > 0) {
738  if (pXfr->remaining > DMA_MAX_FIFO_SIZE)
739  pXfr->buffered = DMA_MAX_FIFO_SIZE;
740  else
741  pXfr->buffered = pXfr->remaining;
742 
743  /* Single transfer again */
744  UDPHS_DmaSingle(bDmaEndpoint, pXfr, USBHS_DEVDMACONTROL_END_TR_EN
749  }
750  } else if (USBHS_DEVDMASTATUS_END_TR_ST & dwDmaSr) {
751  TRACE_DEBUG_WP("EoDmaT ");
752  pXfr->transferred = pXfr->buffered -
755  pXfr->remaining = 0;
756 
757  TRACE_DEBUG_WP("[B%d:T%d] ", pXfr->buffered, pXfr->transferred);
758  } else {
759  TRACE_ERROR("UDPHS_DmaHandler: ST 0x%X\n\r", (unsigned int)dwDmaSr);
760  bRc = USBD_STATUS_ABORTED;
761  }
762 
763  /* Callback */
764  if (pXfr->remaining == 0) {
765  if (iRead)
766  SCB_InvalidateDCache_by_Addr((uint32_t *)pXfr->pData, pXfr->transferred);
767 
768  UDPHS_EndOfTransfer(bEndpoint, bRc);
769  }
770 }
771 #endif
772 
790 static inline uint8_t UDPHS_Write(uint8_t bEndpoint,
791  const void *pData,
792  uint32_t dLength)
793 {
794  Usbhs *pUdp = USBHS;
795  uint8_t bDmaEndpoint = bEndpoint - 1;
796 
797  Endpoint *pEp = &(endpoints[bEndpoint]);
798  Transfer *pXfr = (Transfer *)&(pEp->transfer);
799 
800  /* Return if busy */
801  if (pEp->state != UDPHS_ENDPOINT_IDLE)
802  return USBD_STATUS_LOCKED;
803 
804  /* Sending state */
806  TRACE_DEBUG_WP("Wr%d(%d) ", bEndpoint, dLength);
807  pEp->sendZLP = 0;
808  /* Setup transfer descriptor */
809  pXfr->pData = (void *) pData;
810  pXfr->remaining = dLength;
811  pXfr->buffered = 0;
812  pXfr->transferred = 0;
813 
814 #ifdef DMA
815 
816  /* 1. DMA supported, 2. Not ZLP */
817  if (CHIP_USB_ENDPOINTS_DMA(bEndpoint)
818  && pXfr->remaining > 0) {
819  /* Enable automatic bank switch for DMA*/
820  USBHS_AutoSwitchBankEnable(pUdp, bEndpoint, true);
821 
822  if (pXfr->remaining > DMA_MAX_FIFO_SIZE)
823  /* Transfer the max */
824  pXfr->buffered = DMA_MAX_FIFO_SIZE;
825  else
826  /* Good size */
827  pXfr->buffered = pXfr->remaining;
828 
829  /* Single transfer */
830  SCB_CleanDCache_by_Addr((uint32_t *) pData, dLength);
834  return USBD_STATUS_SUCCESS;
835  }
836 
837  /* Wait for the bank to be free in order to transfer data without DMA correctly
838  * when the last is done with DMA */
839  if (bEndpoint)
840  while (USBHS_IsBankFree(pUdp, bEndpoint) == false);
841 
842 #endif
843  /* Disable automatic bank switch*/
844  USBHS_AutoSwitchBankEnable(pUdp, bEndpoint, false);
845  /* Enable IT */
846  USBHS_EnableIntEP(pUdp, bEndpoint);
848  return USBD_STATUS_SUCCESS;
849 }
850 
869 static inline uint8_t UDPHS_AddWr(uint8_t bEndpoint,
870  const void *pData,
871  uint32_t dLength)
872 {
873  Usbhs *pUdp = USBHS;
874 
875  Endpoint *pEp = &(endpoints[bEndpoint]);
876  MblTransfer *pMbl = (MblTransfer *)&(pEp->transfer);
877  USBDTransferBuffer *pTx;
878 
879  /* Check parameter */
880  if (dLength >= 0x10000)
882 
883  /* Data in process */
884  if (pEp->state > UDPHS_ENDPOINT_IDLE) {
885  /* MBL transfer */
886  if (pMbl->transType) {
887  if (pMbl->listState == MBL_FULL)
888  return USBD_STATUS_LOCKED;
889  } else
890  return USBD_STATUS_LOCKED;
891  }
892 
893  TRACE_DEBUG_WP("AddW%d(%d) ", bEndpoint, dLength);
894  /* Add buffer to buffer list and update index */
895  pTx = &(pMbl->pMbl[pMbl->inCurr]);
896  pTx->pBuffer = (uint8_t *)pData;
897  pTx->size = pTx->remaining = dLength;
898  pTx->transferred = pTx->buffered = 0;
899 
900  /* Update input index */
901  if (pMbl->inCurr >= (pMbl->listSize - 1))
902  pMbl->inCurr = 0;
903  else
904  pMbl->inCurr ++;
905 
906  if (pMbl->inCurr == pMbl->outCurr)
907  pMbl->listState = MBL_FULL;
908  else
909  pMbl->listState = 0;
910 
911  /* Start sending when offset achieved */
912  if (MBL_NbBuffer(pMbl->inCurr, pMbl->outCurr, pMbl->listSize)
913  >= pMbl->offsetSize
914  && pEp->state == UDPHS_ENDPOINT_IDLE) {
915  uint8_t nbBanks = CHIP_USB_ENDPOINTS_BANKS(bEndpoint);
916 
917  /* Change state */
919  TRACE_DEBUG_WP("StartM ");
920 
921  /* Fill data into FIFO */
922  for (; nbBanks && pMbl->pMbl[pMbl->inCurr].remaining; nbBanks --) {
923  UDPHS_MblWriteFifo(bEndpoint);
924  USBHS_RaiseEPInt(pUdp, bEndpoint, USBHS_DEVEPTIFR_TXINIS);
925  }
926 
927  /* Enable interrupt */
928  USBHS_EnableIntEP(pUdp, bEndpoint);
930  }
931 
932  return USBD_STATUS_SUCCESS;
933 }
934 
949 static inline uint8_t UDPHS_Read(uint8_t bEndpoint,
950  void *pData,
951  uint32_t dLength)
952 {
953  Usbhs *pUdp = USBHS;
954  uint8_t bDmaEndpoint = (bEndpoint - 1);
955  Endpoint *pEp = &(endpoints[bEndpoint]);
956  Transfer *pXfr = (Transfer *)&(pEp->transfer);
957 
958  /* Return if busy */
959  if (pEp->state != UDPHS_ENDPOINT_IDLE)
960  return USBD_STATUS_LOCKED;
961 
962  /* Receiving state */
964 
965  TRACE_DEBUG_WP("Rd%d(%d) ", bEndpoint, dLength);
966  /* Setup transfer descriptor */
967  pXfr->pData = (void *)pData;
968  pXfr->remaining = dLength;
969  pXfr->buffered = 0;
970  pXfr->transferred = 0;
971 
972 #ifdef DMA
973 
974  /* If: 1. DMA supported, 2. Has data */
975  if (CHIP_USB_ENDPOINTS_DMA(bEndpoint) && pXfr->remaining > 0) {
976  /* DMA XFR size adjust */
977  if (pXfr->remaining > DMA_MAX_FIFO_SIZE)
978  pXfr->buffered = DMA_MAX_FIFO_SIZE;
979  else
980  pXfr->buffered = pXfr->remaining;
981 
982  /* Single transfer */
988  return USBD_STATUS_SUCCESS;
989  }
990 
991 #endif
992 
993  /* Enable IT */
994  USBHS_EnableIntEP(pUdp, bEndpoint);
996 
997  return USBD_STATUS_SUCCESS;
998 }
999 
1000 /*---------------------------------------------------------------------------
1001  * Exported functions
1002  *---------------------------------------------------------------------------*/
1008 void USBHS_Handler(void)
1009 {
1010  Usbhs *pUdp = USBHS;
1011 
1012  uint32_t status;
1013  uint8_t numIt;
1014 
1015  status = USBHS_ReadIntStatus(pUdp, 0xFFFFFFFF);
1016  status &= USBHS_IsIntEnable(pUdp, 0xFFFFFFFF);
1017 
1018  /* Handle all USBHS interrupts */
1019  TRACE_DEBUG_WP("\n\r%c ", USBD_HAL_IsHighSpeed() ? 'H' : 'F');
1020 
1021  while (status) {
1022  /* SOF */
1023  if (status & USBHS_DEVISR_SOF) {
1024  TRACE_DEBUG_WP("SOF ");
1025  /* SOF handler */
1026  /* Acknowledge interrupt */
1028  } else if (status & USBHS_DEVISR_MSOF) {
1029  /* MOSF */
1030  TRACE_DEBUG_WP("Mosf ");
1031  /* Acknowledge interrupt */
1033  } else if (status & USBHS_DEVISR_SUSP) {
1034  /* Suspend, treated last */
1035  TRACE_WARNING_WP("Susp ");
1039 
1040  /* Enable wakeup */
1042  USBHS_FreezeClock(pUdp);
1045  } else if (status & USBHS_DEVISR_WAKEUP) {
1046  /* Resume */
1047  TRACE_INFO_WP("Rsm ");
1051  /* Acknowledge interrupt */
1052 
1055  } else if (status & USBHS_DEVISR_EORSM) {
1056  /* Bus reset */
1059  } else if (status & USBHS_DEVISR_EORST) {
1060  TRACE_DEBUG_WP("EoB ");
1061  /* Acknowledge interrupt */
1063  /* Flush and enable the suspend interrupt */
1066 
1067  /* Reset handler */
1071  } else if (status & USBHS_DEVISR_UPRSM) {
1072  /* Upstream resume */
1073  TRACE_DEBUG_WP("ExtRes ");
1074  /* Acknowledge interrupt */
1077  } else {
1078  /* Endpoints */
1079  for (numIt = 0; numIt < CHIP_USB_NUMENDPOINTS; numIt++) {
1080 #ifdef DMA
1081 
1082  if ((CHIP_USB_ENDPOINTS_DMA(numIt))
1083  && USBHS_ReadDmaIntStatus(pUdp, numIt - 1))
1084  UDPHS_DmaHandler(numIt);
1085  else
1086 #endif
1087  if (USBHS_ReadEpIntStatus(pUdp, numIt))
1088  UDPHS_EndpointHandler(numIt);
1089  }
1090  }
1091 
1092  /* Update interrupt status */
1093  status = USBHS_ReadIntStatus(pUdp, 0xFFFFFFFF);
1094  status &= USBHS_IsIntEnable(pUdp, 0xFFFFFFFF);
1095 
1096  TRACE_DEBUG_WP("\n\r");
1097 
1098  if (status) {
1099  TRACE_DEBUG_WP(" - ");
1100  }
1101  }
1102 
1103  NVIC_ClearPendingIRQ(USBHS_IRQn); // clear l'IRQ
1104  memory_sync();
1105 
1106 }
1107 
1119 void USBD_HAL_ResetEPs(uint32_t bmEPs, uint8_t bStatus, uint8_t bKeepCfg)
1120 {
1121  Usbhs *pUdp = USBHS;
1122 
1123  Endpoint *pEndpoint;
1124  uint32_t tmp = bmEPs & ((1 << CHIP_USB_NUMENDPOINTS) - 1);
1125  uint8_t ep;
1126  uint32_t epBit, epCfg;
1127 
1128  for (ep = 0, epBit = 1; ep < CHIP_USB_NUMENDPOINTS; ep ++) {
1129  if (tmp & epBit) {
1130  /* Disable ISR */
1131  pUdp->USBHS_DEVIDR |= (epBit << SHIFT_INTERUPT);
1132  /* Reset transfer information */
1133  pEndpoint = &(endpoints[ep]);
1134  /* Reset endpoint state */
1135  pEndpoint->bank = 0;
1136  /* Endpoint configure */
1137  epCfg = pUdp->USBHS_DEVEPTCFG[ep];
1138  /* Reset endpoint */
1139  USBHS_ResetEP(pUdp, ep);
1140 
1141  /* Restore configure */
1142  if (bKeepCfg)
1143  pUdp->USBHS_DEVEPTCFG[ep] = epCfg;
1144  else
1145  pEndpoint->state = UDPHS_ENDPOINT_DISABLED;
1146 
1147  /*Clear data toggle sequence*/
1149 
1150  /* Terminate transfer on this EP */
1151  UDPHS_EndOfTransfer(ep, bStatus);
1152  }
1153 
1154  epBit <<= 1;
1155  }
1156 }
1157 
1163 void USBD_HAL_CancelIo(uint32_t bmEPs)
1164 {
1165  Usbhs *pUdp = USBHS;
1166 
1167  uint32_t tmp = bmEPs & ((1 << CHIP_USB_NUMENDPOINTS) - 1);
1168  uint8_t ep;
1169  uint32_t epBit;
1170 
1171  for (ep = 0, epBit = 1; ep < CHIP_USB_NUMENDPOINTS; ep ++) {
1172  if (tmp & epBit) {
1173  /* Disable ISR */
1174  pUdp->USBHS_DEVIDR |= (epBit << SHIFT_INTERUPT);
1175  /* Terminate transfer on this EP */
1176  UDPHS_EndOfTransfer(ep, USBD_STATUS_CANCELED);
1177  }
1178 
1179  epBit <<= 1;
1180  }
1181 }
1182 
1188 uint8_t USBD_HAL_ConfigureEP(const USBEndpointDescriptor *pDescriptor)
1189 {
1190  Usbhs *pUdp = USBHS;
1191 
1192  Endpoint *pEndpoint;
1193  uint8_t bEndpoint;
1194  uint8_t bType;
1195  uint8_t bEndpointDir;
1196  uint8_t bNbTrans = 1;
1197  uint8_t bSizeEpt = 0;
1198  uint8_t bHs = ((USBHS_GetUsbSpeed(pUdp) == USBHS_SR_SPEED_HIGH_SPEED) ? true :
1199  false);
1200 
1201  /* NULL descriptor -> Control endpoint 0 */
1202  if (pDescriptor == 0) {
1203 
1204  bEndpoint = 0;
1205  pEndpoint = &(endpoints[bEndpoint]);
1207  bEndpointDir = 0;
1208  pEndpoint->size = CHIP_USB_ENDPOINTS_MAXPACKETSIZE(0);
1209  pEndpoint->bank = CHIP_USB_ENDPOINTS_BANKS(0);
1210  }
1211  /* Device descriptor -> Control endpoint 0 */
1212  else if (pDescriptor->bDescriptorType == USBGenericDescriptor_DEVICE) {
1213  USBDeviceDescriptor *pDevDesc = (USBDeviceDescriptor *)pDescriptor;
1214  bEndpoint = 0;
1215  pEndpoint = &(endpoints[bEndpoint]);
1217  bEndpointDir = 0;
1218  pEndpoint->size = pDevDesc->bMaxPacketSize0;
1219  pEndpoint->bank = CHIP_USB_ENDPOINTS_BANKS(0);
1220  /* Endpoint descriptor */
1221  } else {
1222  /* The endpoint number */
1223  bEndpoint = USBEndpointDescriptor_GetNumber(pDescriptor);
1224  pEndpoint = &(endpoints[bEndpoint]);
1225  /* Transfer type: Control, Isochronous, Bulk, Interrupt */
1226  bType = USBEndpointDescriptor_GetType(pDescriptor);
1227  /* Direction, ignored for control endpoints */
1228  bEndpointDir = USBEndpointDescriptor_GetDirection(pDescriptor);
1229  pEndpoint->size = USBEndpointDescriptor_GetMaxPacketSize(pDescriptor);
1230  pEndpoint->bank = CHIP_USB_ENDPOINTS_BANKS(bEndpoint);
1231 
1232  /* Convert descriptor value to EP configuration */
1233  /* HS Interval, *125us */
1234  if (bHs) {
1235  /* MPS: Bit12,11 specify NB_TRANS, as USB 2.0 Spec. */
1236  bNbTrans = ((pEndpoint->size >> 11) & 0x3);
1237 
1238  if (CHIP_USB_ENDPOINTS_HBW(bEndpoint)) {
1239  if (bNbTrans == 3)
1240  bNbTrans = 1;
1241  else
1242  bNbTrans ++;
1243  } else
1244  bNbTrans = 0;
1245 
1246  /* Mask, bit 10..0 is the size */
1247  pEndpoint->size &= 0x7FF;
1248  }
1249  }
1250 
1251  TRACE_DEBUG_WP("CfgE%d ", bEndpoint);
1252 
1253  /* Abort the current transfer is the endpoint was configured and in
1254  Write or Read state */
1255  if ((pEndpoint->state == UDPHS_ENDPOINT_RECEIVING)
1256  || (pEndpoint->state == UDPHS_ENDPOINT_SENDING)
1257  || (pEndpoint->state == UDPHS_ENDPOINT_RECEIVINGM)
1258  || (pEndpoint->state == UDPHS_ENDPOINT_SENDINGM))
1259 
1260  UDPHS_EndOfTransfer(bEndpoint, USBD_STATUS_RESET);
1261 
1262  pEndpoint->state = UDPHS_ENDPOINT_IDLE;
1263 
1264 
1265  /* Configure endpoint size */
1266  if (pEndpoint->size <= 8)
1267  bSizeEpt = 0;
1268  else if (pEndpoint->size <= 16)
1269  bSizeEpt = 1;
1270  else if (pEndpoint->size <= 32)
1271  bSizeEpt = 2;
1272  else if (pEndpoint->size <= 64)
1273  bSizeEpt = 3;
1274  else if (pEndpoint->size <= 128)
1275  bSizeEpt = 4;
1276  else if (pEndpoint->size <= 256)
1277  bSizeEpt = 5;
1278  else if (pEndpoint->size <= 512)
1279  bSizeEpt = 6;
1280  else if (pEndpoint->size <= 1024)
1281  bSizeEpt = 7;
1282 
1283  /* Configure endpoint */
1284  if (bType == USBEndpointDescriptor_CONTROL)
1285  USBHS_EnableIntEP(pUdp, bEndpoint);
1286 
1287  USBHS_ConfigureEPs(pUdp, bEndpoint, bType, bEndpointDir, bSizeEpt,
1288  ((pEndpoint->bank) - 1));
1289 
1290  USBHS_AllocateMemory(pUdp, bEndpoint);
1291 
1292  while ((USBHS_DEVEPTISR_CFGOK & pUdp->USBHS_DEVEPTISR[bEndpoint]) == 0) {
1293 
1294  /* resolved by clearing the reset IT in good place */
1295  TRACE_ERROR("PB bEndpoint: 0x%X\n\r", bEndpoint);
1296  TRACE_ERROR("PB bSizeEpt: 0x%X\n\r", bSizeEpt);
1297  TRACE_ERROR("PB bEndpointDir: 0x%X\n\r", bEndpointDir);
1298  TRACE_ERROR("PB bType: 0x%X\n\r", bType);
1299  TRACE_ERROR("PB pEndpoint->bank: 0x%X\n\r", pEndpoint->bank);
1300  TRACE_ERROR("PB UDPHS_EPTCFG: 0x%X\n\r",
1301  (unsigned int)pUdp->USBHS_DEVEPTCFG[bEndpoint]);
1302 
1303  for (;;);
1304  }
1305 
1306  if (bType == USBEndpointDescriptor_CONTROL) {
1307  // enable Endpoint
1308  USBHS_EnableEP(pUdp, bEndpoint, true);
1309  // Enable Ep interrupt type
1310  USBHS_EnableEPIntType(pUdp, bEndpoint,
1312  // enable endpoint interrupt
1313  USBHS_EnableIntEP(pUdp, bEndpoint);
1314  } else {
1315 #ifndef DMA
1316  USBHS_EnableEP(pUdp, bEndpoint, true);
1317 #else
1318  USBHS_EnableEP(pUdp, bEndpoint, true);
1319 
1320  if (bType == USBEndpointDescriptor_ISOCHRONOUS)
1321  USBHS_SetIsoTrans(pUdp, bEndpoint, bNbTrans);
1322 
1323  USBHS_AutoSwitchBankEnable(pUdp, bEndpoint, true);
1324 #endif
1325  }
1326 
1327  //TRACE_DEBUG_WP("<%x,%x,%x> ", pEpt->UDPHS_EPTCFG, pEpt->UDPHS_EPTCTL, pEpt->UDPHS_EPTSTA);
1328  return bEndpoint;
1329 }
1330 
1340 uint8_t USBD_HAL_SetTransferCallback(uint8_t bEP,
1341  TransferCallback fCallback,
1342  void *pCbData)
1343 {
1344  Endpoint *pEndpoint = &(endpoints[bEP]);
1345  TransferHeader *pTransfer = (TransferHeader *) & (pEndpoint->transfer);
1346 
1347  /* Check that the endpoint is not transferring */
1348  if (pEndpoint->state > UDPHS_ENDPOINT_IDLE)
1349  return USBD_STATUS_LOCKED;
1350 
1351  TRACE_DEBUG_WP("sXfrCb ");
1352  /* Setup the transfer callback and extension data */
1353  pTransfer->fCallback = (void *)fCallback;
1354  pTransfer->pArgument = pCbData;
1355  return USBD_STATUS_SUCCESS;
1356 }
1357 
1365 uint8_t USBD_HAL_SetupMblTransfer(uint8_t bEndpoint,
1366  USBDTransferBuffer *pMbList,
1367  uint16_t mblSize,
1368  uint16_t startOffset)
1369 {
1370  Endpoint *pEndpoint = &(endpoints[bEndpoint]);
1371  MblTransfer *pXfr = (MblTransfer *)&(pEndpoint->transfer);
1372  uint16_t i;
1373 
1374  /* Check that the endpoint is not transferring */
1375  if (pEndpoint->state > UDPHS_ENDPOINT_IDLE)
1376  return USBD_STATUS_LOCKED;
1377 
1378  TRACE_DEBUG_WP("sMblXfr ");
1379 
1380  /* Enable Multi-Buffer Transfer List */
1381  if (pMbList) {
1382  /* Reset list items */
1383  for (i = 0; i < mblSize; i --) {
1384  pMbList[i].pBuffer = NULL;
1385  pMbList[i].size = 0;
1386  pMbList[i].transferred = 0;
1387  pMbList[i].buffered = 0;
1388  pMbList[i].remaining = 0;
1389  }
1390 
1391  /* Setup transfer */
1392  pXfr->transType = 1;
1393  pXfr->listState = 0; /* OK */
1394  pXfr->listSize = mblSize;
1395  pXfr->pMbl = pMbList;
1396  pXfr->outCurr = pXfr->outLast = 0;
1397  pXfr->inCurr = 0;
1398  pXfr->offsetSize = startOffset;
1399  }
1400  /* Disable Multi-Buffer Transfer */
1401  else {
1402  pXfr->transType = 0;
1403  pXfr->pMbl = NULL;
1404  pXfr->listSize = 0;
1405  pXfr->offsetSize = 1;
1406  }
1407 
1408  return USBD_STATUS_SUCCESS;
1409 }
1410 
1429 uint8_t USBD_HAL_Write(uint8_t bEndpoint,
1430  const void *pData,
1431  uint32_t dLength)
1432 {
1433  if (endpoints[bEndpoint].transfer.transHdr.transType)
1434  return UDPHS_AddWr(bEndpoint, pData, dLength);
1435  else
1436  return UDPHS_Write(bEndpoint, pData, dLength);
1437 }
1438 
1458 uint8_t USBD_HAL_WrWithHdr(uint8_t bEndpoint,
1459  const void *pHdr, uint8_t bHdrLen,
1460  const void *pData, uint32_t dLength)
1461 {
1462  Usbhs *pUdp = USBHS;
1463 
1464  Endpoint *pEp = &(endpoints[bEndpoint]);
1465  uint8_t bDmaEndpoint = (bEndpoint - 1);
1466  Transfer *pXfr = (Transfer *)&(pEp->transfer);
1467 
1468  /* Return if DMA is not supported */
1469  if (!CHIP_USB_ENDPOINTS_DMA(bEndpoint))
1471 
1472 #ifdef DMA
1473 
1474  /* Return if busy */
1475  if (pEp->state != UDPHS_ENDPOINT_IDLE)
1476  return USBD_STATUS_LOCKED;
1477 
1478  /* Sending state */
1480  TRACE_DEBUG_WP("Wr%d(%d+%d) ", bEndpoint, bHdrLen, dLength);
1481 
1482  pEp->sendZLP = 0;
1483 
1484  /* Setup transfer descriptor */
1485  pXfr->pData = (void *) pData;
1486  pXfr->remaining = bHdrLen + dLength;
1487  pXfr->buffered = 0;
1488  pXfr->transferred = 0;
1489 
1490  SCB_CleanDCache_by_Addr((uint32_t *)pHdr, bHdrLen);
1491  SCB_CleanDCache_by_Addr((uint32_t *)pData, dLength);
1492 
1493  /* 1. DMA supported always, 2. Not ZLP */
1494  if (bHdrLen + dLength > 0) {
1495  uint8_t bNbTrans = (USBHS_GetConfigureEPs(pUdp, bEndpoint,
1498 
1499  if (pXfr->remaining > DMA_MAX_FIFO_SIZE)
1500  /* Transfer the max */
1501  pXfr->buffered = DMA_MAX_FIFO_SIZE;
1502  else
1503  /* Good size, total size */
1504  pXfr->buffered = pXfr->remaining;
1505 
1506  /* LD1: header - load to fifo without interrupt */
1507  /* Header discarded if exceed the DMA FIFO length */
1508  //if (bHdrLen > DMA_MAX_FIFO_SIZE) bHdrLen = DMA_MAX_FIFO_SIZE;
1509  pDmaLL[0].pNxtDesc = (void *)&pDmaLL[1];
1510  pDmaLL[0].pAddr = (void *)pHdr;
1511  pDmaLL[0].dwCtrl = USBHS_DEVDMACONTROL_CHANN_ENB
1514 
1515  /* High bandwidth ISO EP, max size n*ep_size */
1516  if (bNbTrans > 1) {
1517  uint8_t *pU8 = (uint8_t *)pData;
1518  uint32_t maxSize = bNbTrans * pEp->size;
1519  dLength = pXfr->buffered - bHdrLen;
1520 
1521  if (dLength > maxSize) dLength = maxSize;
1522 
1523  uint32_t pktLen, ndxData = 0;
1524  /* LD2: data - bank 0 */
1525  pktLen = pEp->size - bHdrLen;
1526 
1527  /* It's the last DMA LLI */
1528  if (pktLen >= dLength) {
1529  pDmaLL[1].pNxtDesc = (void *)NULL;
1530  pDmaLL[1].pAddr = (void *)pU8;
1531  pDmaLL[1].dwCtrl = USBHS_DEVDMACONTROL_CHANN_ENB
1535  } else {
1536  pDmaLL[1].pNxtDesc = (void *)&pDmaLL[2];
1537  pDmaLL[1].pAddr = (void *)pU8;
1538  pDmaLL[1].dwCtrl = USBHS_DEVDMACONTROL_CHANN_ENB
1542 
1543  dLength -= pktLen;
1544  ndxData += pktLen;
1545  /* LD3: data - bank 1 */
1546  pktLen = pEp->size;
1547 
1548  if (pktLen >= dLength) { /* It's the last */
1549  pDmaLL[1].pNxtDesc = (void *) NULL;
1550  pDmaLL[1].pAddr = (void *)&pU8[ndxData];
1551  pDmaLL[1].dwCtrl = USBHS_DEVDMACONTROL_CHANN_ENB
1555  } else {
1556  pDmaLL[2].pNxtDesc = (void *)&pDmaLL[3];
1557  pDmaLL[2].pAddr = (void *)&pU8[ndxData];
1558  pDmaLL[2].dwCtrl = USBHS_DEVDMACONTROL_CHANN_ENB
1562  dLength -= pktLen; ndxData += pktLen;
1563  /* LD4: data - bank 2 */
1564  pDmaLL[3].pNxtDesc = (void *) NULL;
1565  pDmaLL[3].pAddr = (void *)&pU8[ndxData];
1566  pDmaLL[3].dwCtrl = USBHS_DEVDMACONTROL_CHANN_ENB
1570  }
1571  }
1572 
1573  /* Normal, fill all data */
1574  } else {
1575  /* LD2: data - load to fifo with interrupt */
1576  dLength = pXfr->buffered - bHdrLen;
1577  pDmaLL[1].pNxtDesc = (void *)NULL;
1578  pDmaLL[1].pAddr = (void *)pData;
1579  pDmaLL[1].dwCtrl = USBHS_DEVDMACONTROL_CHANN_ENB
1583  }
1584 
1585  SCB_CleanDCache_by_Addr((uint32_t *)dmaLL, sizeof(dmaLL));
1586  /* Interrupt enable */
1587  USBHS_EnableDMAIntEP(pUdp, bDmaEndpoint);
1588  /* Start transfer with LLI */
1589  pUdp->USBHS_DEVDMA[bDmaEndpoint].USBHS_DEVDMANXTDSC = (uint32_t)pDmaLL;
1590  pUdp->USBHS_DEVDMA[bDmaEndpoint].USBHS_DEVDMACONTROL = 0;
1591  pUdp->USBHS_DEVDMA[bDmaEndpoint].USBHS_DEVDMACONTROL =
1593  return USBD_STATUS_SUCCESS;
1594  }
1595 
1596 #endif
1597 
1598  /* Enable IT */
1599  USBHS_EnableIntEP(pUdp, bEndpoint);
1601  return USBD_STATUS_SUCCESS;
1602 }
1603 
1618 uint8_t USBD_HAL_Read(uint8_t bEndpoint,
1619  void *pData,
1620  uint32_t dLength)
1621 {
1622  if (endpoints[bEndpoint].transfer.transHdr.transType)
1624  else
1625  return UDPHS_Read(bEndpoint, pData, dLength);
1626 }
1627 
1636 {
1637  uint32_t Interrupt;
1638 
1639  // At startup the USB bus state is unknown,
1640  // therefore the state is considered IDLE to not miss any USB event
1641 
1643 
1644  // Authorize attach
1645  USBHS_DetachUsb(USBHS, false);
1646 
1647  // (RESET_AND_WAKEUP)
1648  // After the attach and the first USB suspend, the following USB Reset time can be inferior to CPU restart clock time.
1649  // Thus, the USB Reset state is not detected and endpoint control is not allocated
1650  // In this case, a Reset is do automatically after attach.
1652 
1653  // Enable USB line events
1656 
1657 #ifdef USB_DEVICE_HS_SUPPORT
1658  Interrupt |= USBHS_DEVIER_MSOFES;
1659 #endif
1660 
1661  USBHS_EnableInt(USBHS, Interrupt);
1662 
1663  // Reset following interrupts flag
1666  USBHS_AckInt(USBHS, Interrupt);
1667 
1668 
1669  // The first suspend interrupt is not detected else raise it
1671 
1673 
1675 }
1676 
1685 {
1687  // Detach device from the bus
1688  USBHS_DetachUsb(USBHS, true);
1689 }
1690 
1695 {
1696  Usbhs *pUdp = USBHS;
1697  TRACE_INFO_WP("RWUp ");
1698 
1699  /* Activates a remote wakeup (edge on ESR), then clear ESR */
1700  USBHS_SetRemoteWakeUp(pUdp);
1701 
1702  while (pUdp->USBHS_DEVCTRL & USBHS_DEVCTRL_RMWKUP);
1703 
1704  TRACE_DEBUG_WP("w");
1705 }
1706 
1711 void USBD_HAL_SetAddress(uint8_t address)
1712 {
1713  Usbhs *pUdp = USBHS;
1714 
1715  if (address)
1716  USBHS_SetAddress(pUdp, address);
1717  else
1718  USBHS_EnableAddress(pUdp, false);
1719 }
1720 
1725 void USBD_HAL_SetConfiguration(uint8_t cfgnum)
1726 {
1727  /* Nothing to do now */
1728  cfgnum = cfgnum;
1729 }
1730 
1734 void USBD_HAL_Init(void)
1735 {
1736 
1737 #ifdef DMA
1738 
1739  /* DMA Link list should be 16-bytes aligned */
1740  if ((uint32_t)dmaLL & 0xFFFFFFF0)
1741  pDmaLL = (UdphsDmaDescriptor *)((uint32_t)&dmaLL[1] & 0xFFFFFFF0);
1742  else
1743  pDmaLL = (UdphsDmaDescriptor *)((uint32_t)&dmaLL[0]);
1744 
1745 #endif
1746 
1747  USBHS_UsbEnable(USBHS, false);
1748 
1750 
1752  USBHS_UsbEnable(USBHS, true);
1753 
1755 
1756  if (ForceFS)
1757  USBHS_EnableHighSpeed(USBHS, false);
1758  else
1760 
1761  /* Check USB clock */
1762  while (!USBHS_ISUsableClock(USBHS));
1763 
1765 
1766  /* Clear IRQ */
1768  /* IRQ */
1770 
1771 }
1772 
1779 uint8_t USBD_HAL_Stall(uint8_t bEP)
1780 {
1781  Usbhs *pUdp = USBHS;
1782 
1783  Endpoint *pEndpoint = &(endpoints[bEP]);
1784 
1785  /* Check that endpoint is in Idle state */
1786  if (pEndpoint->state != UDPHS_ENDPOINT_IDLE) {
1787  TRACE_WARNING("UDP_Stall: EP%d locked\n\r", bEP);
1788  return USBD_STATUS_LOCKED;
1789  }
1790 
1791  /* STALL endpoint */
1793 
1794  TRACE_INFO_WP("Stall%d ", bEP);
1795  return USBD_STATUS_SUCCESS;
1796 }
1797 
1809 uint8_t USBD_HAL_Halt(uint8_t bEndpoint, uint8_t ctl)
1810 {
1811  Usbhs *pUdp = USBHS;
1812 
1813  Endpoint *pEndpoint = &(endpoints[bEndpoint]);
1814  uint8_t bDmaEndpoint = (bEndpoint - 1);
1815  uint8_t status = 0;
1816 
1817  /* SET Halt */
1818  if (ctl == 1) {
1819  /* Check that endpoint is enabled and not already in Halt state */
1820  if ((pEndpoint->state != UDPHS_ENDPOINT_DISABLED)
1821  && (pEndpoint->state != UDPHS_ENDPOINT_HALTED)) {
1822 
1823  TRACE_INFO_WP("Halt%d ", bEndpoint);
1824 
1825  /* Abort the current transfer if necessary */
1826  UDPHS_EndOfTransfer(bEndpoint, USBD_STATUS_ABORTED);
1827 
1828  /* Put endpoint into Halt state */
1829  pEndpoint->state = UDPHS_ENDPOINT_HALTED;
1830  memory_sync();
1831 
1832  while (!USBHS_IsBankFree(pUdp, bEndpoint)) {
1833  USBHS_KillBank(pUdp, bEndpoint);
1834 
1835  while (USBHS_IsBankKilled(pUdp, bEndpoint));
1836  }
1837 
1838  if (USBHS_IsBankFree(pUdp, bEndpoint)) {
1839  USBHS_AutoSwitchBankEnable(pUdp, bEndpoint, false);
1840  USBHS_EnableEPIntType(pUdp, bEndpoint,
1842  } else {
1844 #ifdef DMA
1845 
1846  if (CHIP_USB_ENDPOINTS_DMA(bDmaEndpoint)) {
1847  /* Enable the endpoint DMA interrupt */
1848  USBHS_EnableDMAIntEP(pUdp, bDmaEndpoint);
1849  } else {
1850  /* Enable the endpoint interrupt */
1851  USBHS_EnableIntEP(pUdp, bEndpoint);
1852  }
1853 
1854 #else
1855  /* Enable the endpoint interrupt */
1856  USBHS_EnableIntEP(pUdp, bEndpoint);
1857 #endif
1858  }
1859  }
1860 
1861  /* CLEAR Halt */
1862  } else if (ctl == 0) {
1863  /* Check if the endpoint is halted */
1864  if ((pEndpoint->state == UDPHS_ENDPOINT_HALTED)
1865  || (USBHS_IsEpIntEnable(pUdp, bEndpoint, USBHS_DEVEPTIMR_STALLRQ))) {
1866  TRACE_INFO_WP("Unhalt%d ", bEndpoint);
1867  /* Return endpoint to Idle state */
1868  pEndpoint->state = UDPHS_ENDPOINT_IDLE;
1869 
1870  /* Clear FORCESTALL flag */
1872  USBHS_AutoSwitchBankEnable(pUdp, bEndpoint, true);
1873  }
1874  }
1875 
1876  /* Return Halt status */
1877  if (pEndpoint->state == UDPHS_ENDPOINT_HALTED)
1878  status = 1;
1879 
1880  return (status);
1881 }
1882 
1887 void USBD_HAL_WaitReadData(uint8_t bEndpoint)
1888 {
1889  Usbhs *pUdp = USBHS;
1890 
1891  while (USBHS_ByteCount(pUdp, bEndpoint) == 0);
1892 }
1893 
1899 {
1900  return USBHS_IsUsbHighSpeed(USBHS);
1901 }
1902 
1911 {
1912  /* The device enters the Suspended state */
1914 }
1915 
1923 {
1925 }
1926 
1928 {
1929  //** Disable USB hardware
1930  USBHS_UsbEnable(USBHS, false);
1931 
1932  /* Clear IRQ */
1934  /* IRQ */
1936 }
1937 
1938 
1943 void USBD_HAL_Test(uint8_t bIndex)
1944 {
1945  Usbhs *pUdp = USBHS;
1946  uint8_t *pFifo;
1947  uint32_t i;
1948 
1949  /* remove suspend for TEST */
1951  /* force High Speed (remove suspend) */
1953 
1955 
1956  switch (bIndex) {
1958  TRACE_DEBUG_WP("TEST_PACKET ");
1959 
1960  pUdp->USBHS_DEVDMA[1].USBHS_DEVDMACONTROL = 0;
1961  pUdp->USBHS_DEVDMA[2].USBHS_DEVDMACONTROL = 0;
1962 
1963  /* Configure endpoint 2, 64 bytes, direction IN, type BULK, 1 bank */
1968  USBHS_AllocateMemory(pUdp, 2);
1969 
1970  while ((USBHS_DEVEPTISR_CFGOK & pUdp->USBHS_DEVEPTISR[2]) !=
1972 
1973  USBHS_EnableEP(pUdp, 2, true);
1974 
1975  /* Write FIFO */
1976  pFifo = (uint8_t *)((uint32_t *)(USBHS_RAM_ADDR) + (EPT_VIRTUAL_SIZE * 2));
1977 
1978  for (i = 0; i < sizeof(test_packet_buffer); i++)
1979  pFifo[i] = test_packet_buffer[i];
1980 
1981  /* Tst PACKET */
1983  /* Send packet */
1985  break;
1986 
1988  TRACE_DEBUG_WP("TEST_J ");
1990  break;
1991 
1993  TRACE_DEBUG_WP("TEST_K ");
1995  break;
1996 
1998  TRACE_DEBUG_WP("TEST_SEO_NAK ");
1999  USBHS_DisableInt(pUdp, 0xFFFFFFFF); // for test
2000  break;
2001 
2004  TRACE_DEBUG_WP("SEND_ZLP ");
2005  break;
2006  }
2007 
2008  TRACE_DEBUG_WP("\n\r");
2009 }
2010 
int32_t transferred
Definition: USBD_HAL.c:141
#define USBHS_DEVISR_SOF
(USBHS_DEVISR) Start of Frame Interrupt
#define USBD_STATUS_INVALID_PARAMETER
Definition: USBD.h:112
#define CHIP_USB_NUMENDPOINTS
#define USBHS_DEVEPTCFG_NBTRANS_Msk
(USBHS_DEVEPTCFG[10]) Number of transactions per microframe for isochronous endpoint ...
Buffer struct used for multi-buffer-listed transfer.
Definition: USBD.h:155
__STATIC_INLINE void SCB_InvalidateDCache_by_Addr(uint32_t *addr, int32_t dsize)
D-Cache Invalidate by address.
Definition: core_cm7_4p30.h:16
__STATIC_INLINE void SCB_CleanDCache_by_Addr(uint32_t *addr, int32_t dsize)
D-Cache Clean by address.
Definition: core_cm7_4p30.h:47
uint8_t USBD_HAL_Read(uint8_t bEndpoint, void *pData, uint32_t dLength)
Definition: USBD_HAL.c:1618
#define EPT_VIRTUAL_SIZE
uint8_t transType
Definition: USBD_HAL.c:133
volatile uint8_t bank
Definition: USBD_HAL.c:178
#define USBFeatureRequest_TESTSE0NAK
Definition: USBRequests.h:242
uint8_t USBD_HAL_Write(uint8_t bEndpoint, const void *pData, uint32_t dLength)
Definition: USBD_HAL.c:1429
uint8_t listState
Definition: USBD_HAL.c:155
#define USBHS_DEVCTRL_SPDCONF_HIGH_SPEED
(USBHS_DEVCTRL) Forced high speed.
#define USBHS_DEVEPTIMR_TXINE
(USBHS_DEVEPTIMR[10]) Transmitted IN Data Interrupt
COMPILER_ALIGNED(16)
Definition: USBD_HAL.c:221
static uint8_t UDPHS_Read(uint8_t bEndpoint, void *pData, uint32_t dLength)
Definition: USBD_HAL.c:949
void USBD_HAL_Init(void)
Definition: USBD_HAL.c:1734
#define USBHS_DEVDMACONTROL_CHANN_ENB
(USBHS_DEVDMACONTROL) Channel Enable Command
#define USBD_STATUS_RESET
Definition: USBD.h:108
void USBD_HAL_Disconnect(void)
Disable Pull-up, disconnect.
Definition: USBD_HAL.c:1684
__I uint32_t USBHS_DEVEPTISR[10]
(Usbhs Offset: 0x130) Device Endpoint Status Register (n = 0)
#define USBHS_DEVCTRL_TSTJ
(USBHS_DEVCTRL) Test mode J
#define UDPHS_ENDPOINT_IDLE
Definition: USBD_HAL.c:86
#define USBHS_DEVDMACONTROL_END_TR_EN
(USBHS_DEVDMACONTROL) End of Transfer Enable Control (OUT transfers only)
uint8_t USBD_HAL_IsHighSpeed(void)
Definition: USBD_HAL.c:1898
#define USBHS_DEVDMACONTROL_END_B_EN
(USBHS_DEVDMACONTROL) End of Buffer Enable Control
#define USBHS_RAM_ADDR
Definition: usbhs_device.h:52
#define USBHS_DEVEPTISR_RXSTPI
(USBHS_DEVEPTISR[10]) Received SETUP Interrupt
#define USBHS_DEVEPTIER_TXINES
(USBHS_DEVEPTIER[10]) Transmitted IN Data Interrupt Enable
__STATIC_INLINE uint32_t USBHS_ReadDmaIntStatus(Usbhs *pUsbhs, uint8_t DmaNum)
Read status for a DMA Endpoint.
__STATIC_INLINE void USBHS_EnableEPIntType(Usbhs *pUsbhs, uint8_t Ep, uint32_t EpInt)
__STATIC_INLINE uint32_t USBHS_ReadIntStatus(Usbhs *pUsbhs, uint32_t IntType)
Read status for an interrupt.
__O uint32_t USBHS_DEVIDR
(Usbhs Offset: 0x0014) Device Global Interrupt Disable Register
#define USBHS_DEVEPTIDR_STALLRQC
(USBHS_DEVEPTIDR[10]) STALL Request Clear
#define USBFeatureRequest_TESTSENDZLP
Definition: USBRequests.h:248
__STATIC_INLINE void USBHS_RaiseInt(Usbhs *pUsbhs, uint32_t IntType)
Raise interrupt for endpoint.
#define USBHS_DEVDMACONTROL_END_TR_IT
(USBHS_DEVDMACONTROL) End of Transfer Interrupt Enable
#define USBHS_DEVEPTIDR_FIFOCONC
(USBHS_DEVEPTIDR[10]) FIFO Control Clear
#define USBHS_DEVCTRL_OPMODE2
(USBHS_DEVCTRL) Specific Operational mode
void USBD_HAL_Test(uint8_t bIndex)
Definition: USBD_HAL.c:1943
__STATIC_INLINE void USBHS_EnableAddress(Usbhs *pUsbhs, uint8_t Enable)
Enable or disable USB address.
#define USBHS_DEVCTRL_TSTK
(USBHS_DEVCTRL) Test mode K
#define USBGenericDescriptor_DEVICE
#define USBHS_DEVEPTCFG_EPBK_1_BANK
(USBHS_DEVEPTCFG[10]) Single-bank endpoint
#define USBHS_DEVICR_SOFC
(USBHS_DEVICR) Start of Frame Interrupt Clear
#define USBHS_DEVCTRL_TSTPCKT
(USBHS_DEVCTRL) Test packet mode
__STATIC_INLINE void USBHS_ConfigureEPs(Usbhs *pUsbhs, const uint8_t Ep, const uint8_t Type, const uint8_t Dir, const uint8_t Size, const uint8_t Bank)
static void UDPHS_EndpointHandler(uint8_t bEndpoint)
Definition: USBD_HAL.c:470
__STATIC_INLINE uint32_t USBHS_GetUsbSpeed(Usbhs *pUsbhs)
Enable or disable USB address.
#define USBHS_DEVICR_UPRSMC
(USBHS_DEVICR) Upstream Resume Interrupt Clear
uint16_t offsetSize
Definition: USBD_HAL.c:161
__STATIC_INLINE void USBHS_ResetEP(Usbhs *pUsbhs, uint8_t Ep)
Rests Endpoint.
#define USBEndpointDescriptor_ISOCHRONOUS
if(udd_ctrl_interrupt())
Definition: usbhs_device.c:688
USBDTransferBuffer * pMbl
Definition: USBD_HAL.c:159
uint8_t USBD_HAL_ConfigureEP(const USBEndpointDescriptor *pDescriptor)
Definition: USBD_HAL.c:1188
uint16_t listSize
Definition: USBD_HAL.c:157
void USBD_HAL_Connect(void)
Enable Pull-up, connect.
Definition: USBD_HAL.c:1635
#define CHIP_USB_ENDPOINTS_DMA(ep)
TransferHeader transHdr
Definition: USBD_HAL.c:184
void * pArgument
Definition: USBD_HAL.c:118
#define USBHS_DEVEPTISR_RXOUTI
(USBHS_DEVEPTISR[10]) Received OUT Data Interrupt
static void UDPHS_DmaSingle(uint8_t bEndpoint, Transfer *pXfr, uint32_t dwCfg)
Definition: USBD_HAL.c:663
#define NULL
Definition: nm_bsp.h:52
int32_t buffered
Definition: USBD_HAL.c:137
void USBD_ResetHandler()
Definition: USBD.c:126
__STATIC_INLINE void USBHS_KillBank(Usbhs *pUsbhs, uint8_t Ep)
__STATIC_INLINE void USBHS_FreezeClock(Usbhs *pUsbhs)
Freeze or unfreeze USB clock.
#define USBHS_DEVEPTIER_RXOUTES
(USBHS_DEVEPTIER[10]) Received OUT Data Interrupt Enable
__STATIC_INLINE uint8_t USBHS_GetEpType(Usbhs *pUsbhs, uint8_t Ep)
volatile uint8_t state
Definition: USBD_HAL.c:176
int32_t remaining
Definition: USBD_HAL.c:143
#define USBHS_DEVEPTCFG_EPSIZE_64_BYTE
(USBHS_DEVEPTCFG[10]) 64 bytes
static void UDPHS_DmaHandler(uint8_t bEndpoint)
Definition: USBD_HAL.c:687
static Endpoint endpoints[CHIP_USB_NUMENDPOINTS]
Definition: USBD_HAL.c:207
uint8_t USBD_HAL_SetTransferCallback(uint8_t bEP, TransferCallback fCallback, void *pCbData)
Definition: USBD_HAL.c:1340
#define USBEndpointDescriptor_CONTROL
void USBD_HAL_RemoteWakeUp(void)
Definition: USBD_HAL.c:1694
__STATIC_INLINE void USBHS_EnableEP(Usbhs *pUsbhs, uint8_t Ep, uint8_t Enable)
Enables or disables endpoint.
#define USBHS_DEVEPTISR_TXINI
(USBHS_DEVEPTISR[10]) Transmitted IN Data Interrupt
uint8_t * pBuffer
Definition: USBD.h:157
#define USBHS_DEVDMASTATUS_END_BF_ST
(USBHS_DEVDMASTATUS) End of Channel Buffer Status
__STATIC_INLINE void USBHS_SetDmaBuffAdd(UsbhsDevdma *pUsbDma, uint32_t Addr)
Sets USBHS&#39;s DMA Buffer addresse.
#define USBHS_DEVISR_WAKEUP
(USBHS_DEVISR) Wake-Up Interrupt
#define USBD_STATUS_ABORTED
Definition: USBD.h:104
MblTransfer mblTransfer
Definition: USBD_HAL.c:186
__STATIC_INLINE uint32_t USBHS_ReadEPStatus(Usbhs *pUsbhs, uint8_t Ep, uint32_t EpInt)
#define USBHS_DEVIER_EORSTES
(USBHS_DEVIER) End of Reset Interrupt Enable
__STATIC_INLINE void USBHS_EnableDMAIntEP(Usbhs *pUsbhs, uint32_t DmaEp)
Enables DMA interrupt for a given endpoint.
#define UDPHS_ENDPOINT_SENDING
Definition: USBD_HAL.c:88
#define SHIFT_INTERUPT
Definition: USBD_HAL.c:64
#define USBHS_DEVISR_EORSM
(USBHS_DEVISR) End of Resume Interrupt
__STATIC_INLINE void USBHS_SetAddress(Usbhs *pUsbhs, uint8_t Addr)
Configure USB address and enable or disable it.
__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)
Disable External Interrupt.
Definition: core_cm7.h:1696
void USBD_RequestHandler(uint8_t bEndpoint, const USBGenericRequest *pRequest)
Definition: USBD.c:147
#define USBD_STATUS_LOCKED
Definition: USBD.h:102
#define USBHS_DEVEPTIER_RXSTPES
(USBHS_DEVEPTIER[10]) Received SETUP Interrupt Enable
__STATIC_INLINE void USBHS_AutoSwitchBankEnable(Usbhs *pUsbhs, uint8_t Ep, uint8_t Enable)
#define USBHS
(USBHS ) Base Address
Definition: same70j19.h:508
uint8_t ForceFS
Definition: USBD.c:65
#define USBHS_DEVIER_SOFES
(USBHS_DEVIER) Start of Frame Interrupt Enable
__STATIC_INLINE uint32_t USBHS_IsIntEnable(Usbhs *pUsbhs, uint32_t IntType)
check for interrupt of endpoint.
uint8_t USBEndpointDescriptor_GetNumber(const USBEndpointDescriptor *endpoint)
#define USBFeatureRequest_TESTJ
Definition: USBRequests.h:237
uint16_t USBEndpointDescriptor_GetMaxPacketSize(const USBEndpointDescriptor *endpoint)
__STATIC_INLINE void USBHS_DisableIntEP(Usbhs *pUsbhs, uint8_t Ep)
Disables interrupt for endpoint.
#define UDPHS_ENDPOINT_RECEIVING
Definition: USBD_HAL.c:90
__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
Enable External Interrupt.
Definition: core_cm7.h:1683
__STATIC_INLINE void USBHS_EnableHighSpeed(Usbhs *pUsbhs, uint8_t Enable)
Disable/Enables High Speed mode.
#define USBD_STATUS_CANCELED
Definition: USBD.h:106
static uint8_t UDPHS_MblUpdate(MblTransfer *pTransfer, USBDTransferBuffer *pBi, uint16_t size, uint8_t forceEnd)
Definition: USBD_HAL.c:290
void USBD_ResumeHandler(void)
Definition: USBD.c:105
uint8_t USBEndpointDescriptor_GetType(const USBEndpointDescriptor *endpoint)
#define USBHS_DEVEPTIER_RSTDTS
(USBHS_DEVEPTIER[10]) Reset Data Toggle Enable
#define USBHS_DEVISR_UPRSM
(USBHS_DEVISR) Upstream Resume Interrupt
static void UDPHS_ReadPayload(uint8_t bEndpoint, int32_t wPacketSize)
Definition: USBD_HAL.c:420
void * pArgument
Definition: USBD_HAL.c:131
#define USBHS_DEVEPTCFG_EPTYPE_CTRL
(USBHS_DEVEPTCFG[10]) Control
#define UDPHS_ENDPOINT_SENDINGM
Definition: USBD_HAL.c:92
__STATIC_INLINE bool USBHS_IsUsbHighSpeed(Usbhs *pUsbhs)
Enable or disable USB address.
void USBD_HAL_ResetEPs(uint32_t bmEPs, uint8_t bStatus, uint8_t bKeepCfg)
Reset endpoints and disable them.Terminate transfer if there is any, with given status;Reset the endp...
Definition: USBD_HAL.c:1119
#define USBD_STATUS_HW_NOT_SUPPORTED
Definition: USBD.h:118
#define USBFeatureRequest_TESTK
Definition: USBRequests.h:239
__STATIC_INLINE void USBHS_DisableInt(Usbhs *pUsbhs, uint32_t IntType)
Disables interrupt for endpoint.
uint8_t transType
Definition: USBD_HAL.c:153
#define USBHS_DEVISR_MSOF
(USBHS_DEVISR) Micro Start of Frame Interrupt
__STATIC_INLINE void USBHS_AckInt(Usbhs *pUsbhs, uint32_t IntType)
Acknowledge interrupt for endpoint.
void * fCallback
Definition: USBD_HAL.c:116
#define MBL_NbBuffer(i, o, size)
Definition: USBD_HAL.c:102
#define USBHS_DEVIDR_SUSPEC
(USBHS_DEVIDR) Suspend Interrupt Disable
#define USBHS_DEVISR_SUSP
(USBHS_DEVISR) Suspend Interrupt
#define USBHS_DEVEPTIDR_RXOUTEC
(USBHS_DEVEPTIDR[10]) Received OUT Data Interrupt Clear
static const char test_packet_buffer[]
Definition: USBD_HAL.c:211
uint8_t * pData
Definition: USBD_HAL.c:139
#define USBHS_DEVEPTICR_RXOUTIC
(USBHS_DEVEPTICR[10]) Received OUT Data Interrupt Clear
#define UDPHS_ENDPOINT_DISABLED
Definition: USBD_HAL.c:82
__STATIC_INLINE void USBHS_ConfigureDma(UsbhsDevdma *pUsbDma, uint32_t Cfg)
Setup the USBHS DMA.
uint16_t buffered
Definition: USBD.h:163
void USBD_SuspendHandler(void)
Definition: USBD.c:83
#define USBHS_DEVEPTICR_NAKINIC
(USBHS_DEVEPTICR[10]) NAKed IN Interrupt Clear
#define USBHS_DEVDMASTATUS_END_TR_ST
(USBHS_DEVDMASTATUS) End of Channel Transfer Status
static uint8_t UDPHS_MblWriteFifo(uint8_t bEndpoint)
Definition: USBD_HAL.c:331
__STATIC_INLINE void USBHS_AllocateMemory(Usbhs *pUsbhs, uint8_t Ep)
#define CHIP_USB_ENDPOINTS_HBW(ep)
#define TRACE_ERROR(...)
Definition: USBLib_Trace.h:182
#define MBL_FULL
Definition: USBD_HAL.c:105
__STATIC_INLINE void USBHS_SetIsoTrans(Usbhs *pUsbhs, uint8_t Ep, uint8_t nbTrans)
#define USBHS_DEVEPTIMR_STALLRQ
(USBHS_DEVEPTIMR[10]) STALL Request
__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
Clear Pending Interrupt.
Definition: core_cm7.h:1736
#define USBHS_DEVEPTIER_NBUSYBKES
(USBHS_DEVEPTIER[10]) Number of Busy Banks Interrupt Enable
void USBD_HAL_Suspend(void)
Definition: USBD_HAL.c:1910
uint8_t USBD_HAL_SetupMblTransfer(uint8_t bEndpoint, USBDTransferBuffer *pMbList, uint16_t mblSize, uint16_t startOffset)
Definition: USBD_HAL.c:1365
void * pArgument
Definition: USBD_HAL.c:151
__STATIC_INLINE void USBHS_EnableInt(Usbhs *pUsbhs, uint32_t IntType)
Enables Interrupt.
__STATIC_INLINE void USBHS_UnFreezeClock(Usbhs *pUsbhs)
Freeze or unfreeze USB clock.
void(* TransferCallback)(void *pArg, uint8_t status, uint32_t transferred, uint32_t remaining)
Definition: USBD.h:200
#define USBHS_DEVIER_MSOFES
(USBHS_DEVIER) Micro Start of Frame Interrupt Enable
#define DMA_MAX_FIFO_SIZE
#define USBHS_DEVCTRL_RMWKUP
(USBHS_DEVCTRL) Remote Wake-Up
void USBD_HAL_WaitReadData(uint8_t bEndpoint)
Definition: USBD_HAL.c:1887
#define USBHS_DEVIER_EORSMES
(USBHS_DEVIER) End of Resume Interrupt Enable
#define USBHS_DEVDMACONTROL_END_BUFFIT
(USBHS_DEVDMACONTROL) End of Buffer Interrupt Enable
uint8_t USBD_HAL_Halt(uint8_t bEndpoint, uint8_t ctl)
Definition: USBD_HAL.c:1809
__STATIC_INLINE uint32_t USBHS_IsBankKilled(Usbhs *pUsbhs, uint8_t Ep)
uint16_t reserved
#define USBHS_DEVEPTICR_TXINIC
(USBHS_DEVEPTICR[10]) Transmitted IN Data Interrupt Clear
#define USBHS_DEVICR_EORSMC
(USBHS_DEVICR) End of Resume Interrupt Clear
#define USBD_STATUS_SW_NOT_SUPPORTED
Definition: USBD.h:116
void USBD_HAL_CancelIo(uint32_t bmEPs)
Definition: USBD_HAL.c:1163
void USBD_HAL_SetAddress(uint8_t address)
Definition: USBD_HAL.c:1711
#define USBHS_DEVEPTISR_STALLEDI
(USBHS_DEVEPTISR[10]) STALLed Interrupt
Transfer singleTransfer
Definition: USBD_HAL.c:185
__IO uint32_t USBHS_DEVDMANXTDSC
(UsbhsDevdma Offset: 0x0) Device DMA Channel Next Descriptor Address Register
uint16_t outLast
Definition: USBD_HAL.c:165
#define TRACE_WARNING(...)
Definition: USBLib_Trace.h:174
#define USBHS_DEVIER_WAKEUPES
(USBHS_DEVIER) Wake-Up Interrupt Enable
#define USBHS_DEVEPTIDR_TXINEC
(USBHS_DEVEPTIDR[10]) Transmitted IN Interrupt Clear
void USBD_HAL_Disable(void)
Definition: USBD_HAL.c:1927
static void UDPHS_ReadRequest(USBGenericRequest *pRequest)
Definition: USBD_HAL.c:451
#define CHIP_USB_ENDPOINTS_MAXPACKETSIZE(ep)
#define UDPHS_ENDPOINT_RECEIVINGM
Definition: USBD_HAL.c:94
#define MBL_NULL
Definition: USBD_HAL.c:107
#define USBHS_SR_SPEED_HIGH_SPEED
(USBHS_SR) High-Speed mode
volatile uint16_t size
Definition: USBD_HAL.c:180
uint16_t remaining
Definition: USBD.h:165
uint8_t USBD_HAL_Stall(uint8_t bEP)
Definition: USBD_HAL.c:1779
__IO uint32_t USBHS_DEVEPTCFG[10]
(Usbhs Offset: 0x100) Device Endpoint Configuration Register (n = 0)
__STATIC_INLINE void USBHS_UsbEnable(Usbhs *pUsbhs, uint8_t Enable)
Enables or disables USB.
#define USBHS_DEVIDR_EORSMEC
(USBHS_DEVIDR) End of Resume Interrupt Disable
__STATIC_INLINE void USBHS_DetachUsb(Usbhs *pUsbhs, uint8_t Enable)
Attach or detach USB.
#define USBHS_DEVEPTISR_CFGOK
(USBHS_DEVEPTISR[10]) Configuration OK Status
uint32_t dwCtrl
Definition: USBD_HAL.c:198
#define USBHS_DEVEPTCFG_EPTYPE_ISO
(USBHS_DEVEPTCFG[10]) Isochronous
uint8_t transType
Definition: USBD_HAL.c:120
#define USBHS_DEVEPTCFG_EPTYPE_BLK
(USBHS_DEVEPTCFG[10]) Bulk
#define USBHS_DEVIER_SUSPES
(USBHS_DEVIER) Suspend Interrupt Enable
#define USBHS_DEVEPTIER_STALLRQS
(USBHS_DEVEPTIER[10]) STALL Request Enable
#define USBHS_DEVDMACONTROL_LDNXT_DSC
(USBHS_DEVDMACONTROL) Load Next Channel Transfer Descriptor Enable Command
uint16_t transferred
Definition: USBD.h:161
uint8_t USBEndpointDescriptor_GetDirection(const USBEndpointDescriptor *endpoint)
__STATIC_INLINE void USBHS_UsbMode(Usbhs *pUsbhs, USB_Mode_t Mode)
Device or Host Mode.
__STATIC_INLINE uint8_t USBHS_ISUsableClock(Usbhs *pUsbhs)
Check if clock is usable or not.
#define USBHS_DEVIFR_SUSPS
(USBHS_DEVIFR) Suspend Interrupt Set
#define USBHS_DEVEPTCFG_EPDIR
(USBHS_DEVEPTCFG[10]) Endpoint Direction
#define USBFeatureRequest_TESTPACKET
Definition: USBRequests.h:244
__STATIC_INLINE uint16_t USBHS_ByteCount(Usbhs *pUsbhs, uint8_t Ep)
void USBD_HAL_Activate(void)
Definition: USBD_HAL.c:1922
#define USBHS_DEVICR_WAKEUPC
(USBHS_DEVICR) Wake-Up Interrupt Clear
uint32_t sendZLP
Definition: USBD_HAL.c:189
__STATIC_INLINE uint32_t USBHS_IsEpIntEnable(Usbhs *pUsbhs, uint8_t Ep, uint32_t EpIntType)
__STATIC_INLINE void USBHS_AckEpInterrupt(Usbhs *pUsbhs, uint8_t Ep, uint32_t EpInt)
void(* MblTransferCallback)(void *pArg, uint8_t status)
Definition: USBD.h:211
#define USBHS_DEVIDR_WAKEUPEC
(USBHS_DEVIDR) Wake-Up Interrupt Disable
#define USBHS_DEVICR_MSOFC
(USBHS_DEVICR) Micro Start of Frame Interrupt Clear
uint16_t outCurr
Definition: USBD_HAL.c:163
#define CHIP_USB_ENDPOINTS_BANKS(ep)
#define USBHS_DEVICR_EORSTC
(USBHS_DEVICR) End of Reset Interrupt Clear
static uint8_t UDPHS_Write(uint8_t bEndpoint, const void *pData, uint32_t dLength)
Definition: USBD_HAL.c:790
#define USBHS_DEVEPTICR_STALLEDIC
(USBHS_DEVEPTICR[10]) STALLed Interrupt Clear
#define USBHS_DEVDMASTATUS_BUFF_COUNT_Msk
(USBHS_DEVDMASTATUS) Buffer Byte Count
__STATIC_INLINE void USBHS_SetRemoteWakeUp(Usbhs *pUsbhs)
Set Remote WakeUp mode.
union Endpoint::@33 transfer
static void UDPHS_WritePayload(uint8_t bEndpoint, int32_t size)
Definition: USBD_HAL.c:389
__IO uint32_t USBHS_DEVCTRL
(Usbhs Offset: 0x0000) Device General Control Register
__STATIC_INLINE uint32_t USBHS_GetDmaStatus(UsbhsDevdma *pUsbDma)
Get Dma Status.
uint16_t size
Definition: USBD.h:159
TransferCallback fCallback
Definition: USBD_HAL.c:129
#define TRACE_DEBUG(...)
Definition: USBLib_Trace.h:161
#define TRACE_WARNING_WP(...)
Definition: USBLib_Trace.h:175
__STATIC_INLINE uint32_t USBHS_ReadEpIntStatus(Usbhs *pUsbhs, uint8_t EpNum)
Read status for an Endpoint.
#define USBHS_DEVICR_SUSPC
(USBHS_DEVICR) Suspend Interrupt Clear
__STATIC_INLINE uint8_t USBHS_IsBankFree(Usbhs *pUsbhs, uint8_t Ep)
#define USBHS_DEVISR_EORST
(USBHS_DEVISR) End of Reset Interrupt
static uint8_t UDPHS_AddWr(uint8_t bEndpoint, const void *pData, uint32_t dLength)
Definition: USBD_HAL.c:869
UsbhsDevdma USBHS_DEVDMA[USBHSDEVDMA_NUMBER]
(Usbhs Offset: 0x310) n = 1 .. 7
#define USBD_STATUS_SUCCESS
Definition: USBD.h:100
MblTransferCallback fCallback
Definition: USBD_HAL.c:149
void USBHS_Handler(void)
Definition: USBD_HAL.c:1008
#define USBHS_DEVEPTIFR_TXINIS
(USBHS_DEVEPTIFR[10]) Transmitted IN Data Interrupt Set
#define UDPHS_ENDPOINT_HALTED
Definition: USBD_HAL.c:84
#define TRACE_DEBUG_WP(...)
Definition: USBLib_Trace.h:162
#define TRACE_INFO_WP(...)
Definition: USBLib_Trace.h:167
#define USBHS_DEVEPTISR_BYCT_Msk
(USBHS_DEVEPTISR[10]) Byte Count
__IO uint32_t USBHS_DEVDMACONTROL
(UsbhsDevdma Offset: 0x8) Device DMA Channel Control Register
__STATIC_INLINE uint32_t USBHS_GetConfigureEPs(Usbhs *pUsbhs, uint8_t Ep, uint32_t IntType)
void USBD_HAL_SetConfiguration(uint8_t cfgnum)
Definition: USBD_HAL.c:1725
#define USBHS_DEVEPTICR_RXSTPIC
(USBHS_DEVEPTICR[10]) Received SETUP Interrupt Clear
#define USBHS_DEVIER_UPRSMES
(USBHS_DEVIER) Upstream Resume Interrupt Enable
__STATIC_INLINE void USBHS_EnableIntEP(Usbhs *pUsbhs, uint8_t EpNum)
Enables interrupt for a given endpoint.
uint16_t inCurr
Definition: USBD_HAL.c:167
__STATIC_INLINE void USBHS_DisableEPIntType(Usbhs *pUsbhs, uint8_t Ep, uint32_t EpInt)
uint8_t USBD_HAL_WrWithHdr(uint8_t bEndpoint, const void *pHdr, uint8_t bHdrLen, const void *pData, uint32_t dLength)
Definition: USBD_HAL.c:1458
__STATIC_INLINE void USBHS_EnableTestMode(Usbhs *pUsbhs, uint32_t mode)
Disable/Enables Test mode.
__STATIC_INLINE void USBHS_RaiseEPInt(Usbhs *pUsbhs, uint8_t Ep, uint32_t EpInt)


inertial_sense_ros
Author(s):
autogenerated on Sun Feb 28 2021 03:17:58