blob: d5ec38ea3af32400a6f1f23ecbd8c9f2bdb8c081 [file] [log] [blame]
Christina Quast8be71e42014-12-02 13:06:01 +01001/* ----------------------------------------------------------------------------
2 * ATMEL Microcontroller Software Support
3 * ----------------------------------------------------------------------------
4 * Copyright (c) 2008, Atmel Corporation
5 *
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are met:
10 *
11 * - Redistributions of source code must retain the above copyright notice,
12 * this list of conditions and the disclaimer below.
13 *
14 * Atmel's name may not be used to endorse or promote products derived from
15 * this software without specific prior written permission.
16 *
17 * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
20 * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
23 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
24 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
25 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
26 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 * ----------------------------------------------------------------------------
28 */
29
30/**
31
32 \file
33
34 \section Purpose
35
36 Implementation of USB device functions on a UDP controller.
37
38 See \ref usbd_api_method USBD API Methods.
39*/
40
41/** \addtogroup usbd_hal
42 *@{*/
43
44/*---------------------------------------------------------------------------
45 * Headers
46 *---------------------------------------------------------------------------*/
47
48#include "chip.h"
49#include "USBD_HAL.h"
50
51#include <stdbool.h>
52#include <stdint.h>
53#include <stdio.h>
54
55/*---------------------------------------------------------------------------
56 * Definitions
57 *---------------------------------------------------------------------------*/
58
59/** Indicates chip has an UDP Full Speed. */
60#define CHIP_USB_UDP
61
62/** Indicates chip has an internal pull-up. */
63#define CHIP_USB_PULLUP_INTERNAL
64
65/** Number of USB endpoints */
66#define CHIP_USB_NUMENDPOINTS 8
67
68/** Endpoints max paxcket size */
69#define CHIP_USB_ENDPOINTS_MAXPACKETSIZE(i) \
70 ((i == 0) ? 64 : \
71 ((i == 1) ? 64 : \
72 ((i == 2) ? 64 : \
73 ((i == 3) ? 64 : \
74 ((i == 4) ? 512 : \
75 ((i == 5) ? 512 : \
76 ((i == 6) ? 64 : \
77 ((i == 7) ? 64 : 0 ))))))))
78
79/** Endpoints Number of Bank */
80#define CHIP_USB_ENDPOINTS_BANKS(i) \
81 ((i == 0) ? 1 : \
82 ((i == 1) ? 2 : \
83 ((i == 2) ? 2 : \
84 ((i == 3) ? 1 : \
85 ((i == 4) ? 2 : \
86 ((i == 5) ? 2 : \
87 ((i == 6) ? 2 : \
88 ((i == 7) ? 2 : 0 ))))))))
89
90/**
91 * \section UDP_registers_sec "UDP Register field values"
92 *
93 * This section lists the initialize values of UDP registers.
94 *
95 * \subsection Values
96 * - UDP_RXDATA
97 */
98/** Bit mask for both banks of the UDP_CSR register. */
99#define UDP_CSR_RXDATA_BK (UDP_CSR_RX_DATA_BK0 | UDP_CSR_RX_DATA_BK1)
100
101/**
102 * \section endpoint_states_sec "UDP Endpoint states"
103 *
104 * This page lists the endpoint states.
105 *
106 * \subsection States
107 * - UDP_ENDPOINT_DISABLED
108 * - UDP_ENDPOINT_HALTED
109 * - UDP_ENDPOINT_IDLE
110 * - UDP_ENDPOINT_SENDING
111 * - UDP_ENDPOINT_RECEIVING
112 * - UDP_ENDPOINT_SENDINGM
113 * - UDP_ENDPOINT_RECEIVINGM
114 */
115
116/** Endpoint states: Endpoint is disabled */
117#define UDP_ENDPOINT_DISABLED 0
118/** Endpoint states: Endpoint is halted (i.e. STALLs every request) */
119#define UDP_ENDPOINT_HALTED 1
120/** Endpoint states: Endpoint is idle (i.e. ready for transmission) */
121#define UDP_ENDPOINT_IDLE 2
122/** Endpoint states: Endpoint is sending data */
123#define UDP_ENDPOINT_SENDING 3
124/** Endpoint states: Endpoint is receiving data */
125#define UDP_ENDPOINT_RECEIVING 4
126/** Endpoint states: Endpoint is sending MBL */
127#define UDP_ENDPOINT_SENDINGM 5
128/** Endpoint states: Endpoint is receiving MBL */
129#define UDP_ENDPOINT_RECEIVINGM 6
130
131/**
132 * \section udp_csr_register_access_sec "UDP CSR register access"
133 *
134 * This page lists the macros to access UDP CSR register.
135 *
136 * \comment
137 * In a preemptive environment, set or clear the flag and wait for a time of
138 * 1 UDPCK clock cycle and 1 peripheral clock cycle. However, RX_DATA_BK0,
139 * TXPKTRDY, RX_DATA_BK1 require wait times of 3 UDPCK clock cycles and
140 * 5 peripheral clock cycles before accessing DPR.
141 * See datasheet
142 *
143 * !Macros
144 * - CLEAR_CSR
145 * - SET_CSR
146 */
147
148#if defined ( __CC_ARM )
149 #define nop() {volatile int h; for(h=0;h<10;h++){}}
150#elif defined ( __ICCARM__ )
151 #include <intrinsics.h>
152 #define nop() (__no_operation())
153#elif defined ( __GNUC__ )
154 #define nop() __asm__ __volatile__ ( "nop" )
155#endif
156
157
158/** Bitmap for all status bits in CSR. */
159#define REG_NO_EFFECT_1_ALL UDP_CSR_RX_DATA_BK0 | UDP_CSR_RX_DATA_BK1 \
160 |UDP_CSR_STALLSENTISOERROR | UDP_CSR_RXSETUP \
161 |UDP_CSR_TXCOMP
162
163/**
164 * Sets the specified bit(s) in the UDP_CSR register.
165 *
166 * \param endpoint The endpoint number of the CSR to process.
167 * \param flags The bitmap to set to 1.
168 */
169#define SET_CSR(endpoint, flags) \
170 { \
171 volatile uint32_t reg; \
172 int32_t nop_count ; \
173 reg = UDP->UDP_CSR[endpoint] ; \
174 reg |= REG_NO_EFFECT_1_ALL; \
175 reg |= (flags); \
176 UDP->UDP_CSR[endpoint] = reg; \
177 for( nop_count=0; nop_count<15; nop_count++ ) {\
178 nop();\
179 }\
180 }
181
182/**
183 * Clears the specified bit(s) in the UDP_CSR register.
184 *
185 * \param endpoint The endpoint number of the CSR to process.
186 * \param flags The bitmap to clear to 0.
187 */
188#define CLEAR_CSR(endpoint, flags) \
189{ \
190 volatile uint32_t reg; \
191 int32_t nop_count ; \
192 reg = UDP->UDP_CSR[endpoint]; \
193 reg |= REG_NO_EFFECT_1_ALL; \
194 reg &= ~((uint32_t)(flags)); \
195 UDP->UDP_CSR[endpoint] = reg; \
196 for( nop_count=0; nop_count<15; nop_count++ ) {\
197 nop();\
198 }\
199}
200
201
202/** Get Number of buffer in Multi-Buffer-List
203 * \param i input index
204 * \param o output index
205 * \param size list size
206 */
207#define MBL_NbBuffer(i, o, size) (((i)>(o))?((i)-(o)):((i)+(size)-(o)))
208
209/** Buffer list is full */
210#define MBL_FULL 1
211/** Buffer list is null */
212#define MBL_NULL 2
213
214/*---------------------------------------------------------------------------
215 * Types
216 *---------------------------------------------------------------------------*/
217
218/** Describes header for UDP endpoint transfer. */
219typedef struct {
220 /** Optional callback to invoke when the transfer completes. */
221 void* fCallback;
222 /** Optional argument to the callback function. */
223 void* pArgument;
224 /** Transfer type */
225 uint8_t transType;
226} TransferHeader;
227
228/** Describes a transfer on a UDP endpoint. */
229typedef struct {
230
231 /** Optional callback to invoke when the transfer completes. */
232 TransferCallback fCallback;
233 /** Optional argument to the callback function. */
234 void *pArgument;
235 /** Transfer type */
236 uint16_t transType;
237 /** Number of bytes which have been written into the UDP internal FIFO
238 * buffers. */
239 int16_t buffered;
240 /** Pointer to a data buffer used for emission/reception. */
241 uint8_t *pData;
242 /** Number of bytes which have been sent/received. */
243 int32_t transferred;
244 /** Number of bytes which have not been buffered/transferred yet. */
245 int32_t remaining;
246} Transfer;
247
248/** Describes Multi Buffer List transfer on a UDP endpoint. */
249typedef struct {
250 /** Optional callback to invoke when the transfer completes. */
251 MblTransferCallback fCallback;
252 /** Optional argument to the callback function. */
253 void *pArgument;
254 /** Transfer type */
255 volatile uint8_t transType;
256 /** List state (OK, FULL, NULL) (run time) */
257 uint8_t listState;
258 /** Multi-Buffer List size */
259 uint16_t listSize;
260 /** Pointer to multi-buffer list */
261 USBDTransferBuffer *pMbl;
262 /** Offset number of buffers to start transfer */
263 uint16_t offsetSize;
264 /** Current processing buffer index (run time) */
265 uint16_t outCurr;
266 /** Loast loaded buffer index (run time) */
267 uint16_t outLast;
268 /** Current buffer for input (run time) */
269 uint16_t inCurr;
270} MblTransfer;
271
272/**
273 * Describes the state of an endpoint of the UDP controller.
274 */
275typedef struct {
276
277 /* CSR */
278 //uint32_t CSR;
279 /** Current endpoint state. */
280 volatile uint8_t state;
281 /** Current reception bank (0 or 1). */
282 volatile uint8_t bank;
283 /** Maximum packet size for the endpoint. */
284 volatile uint16_t size;
285 /** Describes an ongoing transfer (if current state is either
286 * UDP_ENDPOINT_SENDING or UDP_ENDPOINT_RECEIVING) */
287 union {
288 TransferHeader transHdr;
289 Transfer singleTransfer;
290 MblTransfer mblTransfer;
291 } transfer;
292} Endpoint;
293
294/*---------------------------------------------------------------------------
295 * Internal variables
296 *---------------------------------------------------------------------------*/
297
298/** Holds the internal state for each endpoint of the UDP. */
299static Endpoint endpoints[CHIP_USB_NUMENDPOINTS];
300
301/*---------------------------------------------------------------------------
302 * Internal Functions
303 *---------------------------------------------------------------------------*/
304
305/**
306 * Enables the clock of the UDP peripheral.
307 * \return 1 if peripheral status changed.
308 */
309static uint8_t UDP_EnablePeripheralClock(void)
310{
311 if (!PMC_IsPeriphEnabled(ID_UDP)) {
312 PMC_EnablePeripheral(ID_UDP);
313 return 1;
314 }
315 return 0;
316}
317
318/**
319 * Disables the UDP peripheral clock.
320 */
321static inline void UDP_DisablePeripheralClock(void)
322{
323 PMC_DisablePeripheral(ID_UDP);
324}
325
326/**
327 * Enables the 48MHz USB clock.
328 */
329static inline void UDP_EnableUsbClock(void)
330{
331 REG_PMC_SCER = PMC_SCER_UDP;
332}
333
334/**
335 * Disables the 48MHz USB clock.
336 */
337static inline void UDP_DisableUsbClock(void)
338{
339 REG_PMC_SCDR = PMC_SCER_UDP;
340}
341
342/**
343 * Enables the UDP transceiver.
344 */
345static inline void UDP_EnableTransceiver(void)
346{
347 UDP->UDP_TXVC &= ~(uint32_t)UDP_TXVC_TXVDIS;
348}
349
350/**
351 * Disables the UDP transceiver.
352 */
353static inline void UDP_DisableTransceiver(void)
354{
355 UDP->UDP_TXVC |= UDP_TXVC_TXVDIS;
356}
357
358/**
359 * Handles a completed transfer on the given endpoint, invoking the
360 * configured callback if any.
361 * \param bEndpoint Number of the endpoint for which the transfer has completed.
362 * \param bStatus Status code returned by the transfer operation
363 */
364static void UDP_EndOfTransfer(uint8_t bEndpoint, uint8_t bStatus)
365{
366 Endpoint *pEndpoint = &(endpoints[bEndpoint]);
367
368 // Check that endpoint was sending or receiving data
369 if( (pEndpoint->state == UDP_ENDPOINT_RECEIVING)
370 || (pEndpoint->state == UDP_ENDPOINT_SENDING)) {
371
372 Transfer *pTransfer = (Transfer *)&(pEndpoint->transfer);
373 uint32_t transferred = pTransfer->transferred;
374 uint32_t remaining = pTransfer->remaining + pTransfer->buffered;
375
376 TRACE_DEBUG_WP("EoT ");
377
378 /* Endpoint returns in Idle state */
379 pEndpoint->state = UDP_ENDPOINT_IDLE;
380 /* Reset descriptor values */
381 pTransfer->pData = 0;
382 pTransfer->transferred = -1;
383 pTransfer->buffered = -1;
384 pTransfer->remaining = -1;
385
386 // Invoke callback is present
387 if (pTransfer->fCallback != 0) {
388
389 ((TransferCallback) pTransfer->fCallback)
390 (pTransfer->pArgument,
391 bStatus,
392 transferred,
393 remaining);
394 }
395 else {
396 TRACE_DEBUG_WP("NoCB ");
397 }
398 }
399 else if ( (pEndpoint->state == UDP_ENDPOINT_RECEIVINGM)
400 || (pEndpoint->state == UDP_ENDPOINT_SENDINGM) ) {
401
402 MblTransfer *pTransfer = (MblTransfer*)&(pEndpoint->transfer);
403
404 TRACE_DEBUG_WP("EoMT ");
405
406 /* Endpoint returns in Idle state */
407 pEndpoint->state = UDP_ENDPOINT_IDLE;
408 /* Reset transfer descriptor */
409 if (pTransfer->transType) {
410 MblTransfer *pMblt = (MblTransfer*)&(pEndpoint->transfer);
411 pMblt->listState = 0;
412 pMblt->outCurr = pMblt->inCurr = pMblt->outLast = 0;
413 }
414 /* Invoke callback */
415 if (pTransfer->fCallback != 0) {
416
417 ((MblTransferCallback) pTransfer->fCallback)
418 (pTransfer->pArgument,
419 bStatus);
420 }
421 else {
422 TRACE_DEBUG_WP("NoCB ");
423 }
424 }
425}
426
427/**
428 * Clears the correct reception flag (bank 0 or bank 1) of an endpoint
429 * \param bEndpoint Index of endpoint
430 */
431static void UDP_ClearRxFlag(uint8_t bEndpoint)
432{
433 Endpoint *pEndpoint = &(endpoints[bEndpoint]);
434
435 // Clear flag and change banks
436 if (pEndpoint->bank == 0) {
437
438 CLEAR_CSR(bEndpoint, UDP_CSR_RX_DATA_BK0);
439 // Swap bank if in dual-fifo mode
440 if (CHIP_USB_ENDPOINTS_BANKS(bEndpoint) > 1) {
441
442 pEndpoint->bank = 1;
443 }
444 }
445 else {
446
447 CLEAR_CSR(bEndpoint, UDP_CSR_RX_DATA_BK1);
448 pEndpoint->bank = 0;
449 }
450}
451
452/**
453 * Update multi-buffer-transfer descriptors.
454 * \param pTransfer Pointer to instance MblTransfer.
455 * \param size Size of bytes that processed.
456 * \param forceEnd Force the buffer END.
457 * \return 1 if current buffer ended.
458 */
459static uint8_t UDP_MblUpdate(MblTransfer *pTransfer,
460 USBDTransferBuffer * pBi,
461 uint16_t size,
462 uint8_t forceEnd)
463{
464 /* Update transfer descriptor */
465 pBi->remaining -= size;
466 /* Check if list NULL */
467 if (pTransfer->listState == MBL_NULL) {
468 return 1;
469 }
470 /* Check if current buffer ended */
471 if (pBi->remaining == 0 || forceEnd || size == 0) {
472
473 /* Process to next buffer */
474 if ((++ pTransfer->outCurr) == pTransfer->listSize)
475 pTransfer->outCurr = 0;
476 /* Check buffer NULL case */
477 if (pTransfer->outCurr == pTransfer->inCurr)
478 pTransfer->listState = MBL_NULL;
479 else {
480 pTransfer->listState = 0;
481 /* Continue transfer, prepare for next operation */
482 pBi = &pTransfer->pMbl[pTransfer->outCurr];
483 pBi->buffered = 0;
484 pBi->transferred = 0;
485 pBi->remaining = pBi->size;
486 }
487 return 1;
488 }
489 return 0;
490}
491
492/**
493 * Transfers a data payload from the current tranfer buffer to the endpoint
494 * FIFO
495 * \param bEndpoint Number of the endpoint which is sending data.
496 */
497static uint8_t UDP_MblWriteFifo(uint8_t bEndpoint)
498{
499 Endpoint *pEndpoint = &(endpoints[bEndpoint]);
500 MblTransfer *pTransfer = (MblTransfer*)&(pEndpoint->transfer);
501 USBDTransferBuffer *pBi = &(pTransfer->pMbl[pTransfer->outCurr]);
502 int32_t size;
503
504 volatile uint8_t * pBytes;
505 volatile uint8_t bufferEnd = 1;
506
507 /* Get the number of bytes to send */
508 size = pEndpoint->size;
509 if (size > pBi->remaining) size = pBi->remaining;
510
Christina Quast23c00132015-01-27 15:17:37 +0100511 TRACE_DEBUG_WP("w%d.%" PRId32 " ", pTransfer->outCurr, size);
Christina Quast8be71e42014-12-02 13:06:01 +0100512
513 /* Record last accessed buffer */
514 pTransfer->outLast = pTransfer->outCurr;
515
516 pBytes = &(pBi->pBuffer[pBi->transferred + pBi->buffered]);
517 pBi->buffered += size;
518 bufferEnd = UDP_MblUpdate(pTransfer, pBi, size, 0);
519
520 /* Write packet in the FIFO buffer */
521 if (size) {
522 int32_t c8 = size >> 3;
523 int32_t c1 = size & 0x7;
524 for (; c8; c8 --) {
525 UDP->UDP_FDR[bEndpoint] = *(pBytes ++);
526 UDP->UDP_FDR[bEndpoint] = *(pBytes ++);
527 UDP->UDP_FDR[bEndpoint] = *(pBytes ++);
528 UDP->UDP_FDR[bEndpoint] = *(pBytes ++);
529
530 UDP->UDP_FDR[bEndpoint] = *(pBytes ++);
531 UDP->UDP_FDR[bEndpoint] = *(pBytes ++);
532 UDP->UDP_FDR[bEndpoint] = *(pBytes ++);
533 UDP->UDP_FDR[bEndpoint] = *(pBytes ++);
534 }
535 for (; c1; c1 --) {
536 UDP->UDP_FDR[bEndpoint] = *(pBytes ++);
537 }
538 }
539 return bufferEnd;
540}
541
542/**
543 * Transfers a data payload from the current tranfer buffer to the endpoint
544 * FIFO
545 * \param bEndpoint Number of the endpoint which is sending data.
546 */
547static void UDP_WritePayload(uint8_t bEndpoint)
548{
549 Endpoint *pEndpoint = &(endpoints[bEndpoint]);
550 Transfer *pTransfer = (Transfer*)&(pEndpoint->transfer);
551 int32_t size;
552
553 // Get the number of bytes to send
554 size = pEndpoint->size;
555 if (size > pTransfer->remaining) {
556
557 size = pTransfer->remaining;
558 }
559
560 // Update transfer descriptor information
561 pTransfer->buffered += size;
562 pTransfer->remaining -= size;
563
564 // Write packet in the FIFO buffer
565 while (size > 0) {
566
567 UDP->UDP_FDR[bEndpoint] = *(pTransfer->pData);
568 pTransfer->pData++;
569 size--;
570 }
571}
572
573
574/**
575 * Transfers a data payload from an endpoint FIFO to the current transfer buffer
576 * \param bEndpoint Endpoint number.
577 * \param wPacketSize Size of received data packet
578 */
579static void UDP_ReadPayload(uint8_t bEndpoint, int32_t wPacketSize)
580{
581 Endpoint *pEndpoint = &(endpoints[bEndpoint]);
582 Transfer *pTransfer = (Transfer*)&(pEndpoint->transfer);
583
584 // Check that the requested size is not bigger than the remaining transfer
585 if (wPacketSize > pTransfer->remaining) {
586
587 pTransfer->buffered += wPacketSize - pTransfer->remaining;
588 wPacketSize = pTransfer->remaining;
589 }
590
591 // Update transfer descriptor information
592 pTransfer->remaining -= wPacketSize;
593 pTransfer->transferred += wPacketSize;
594
595 // Retrieve packet
596 while (wPacketSize > 0) {
597
598 *(pTransfer->pData) = (uint8_t) UDP->UDP_FDR[bEndpoint];
599 pTransfer->pData++;
600 wPacketSize--;
601 }
602}
603
604/**
605 * Received SETUP packet from endpoint 0 FIFO
606 * \param pRequest Generic USB SETUP request sent over Control endpoints
607 */
608static void UDP_ReadRequest(USBGenericRequest *pRequest)
609{
610 uint8_t *pData = (uint8_t *)pRequest;
611 uint32_t i;
612
613 // Copy packet
614 for (i = 0; i < 8; i++) {
615
616 *pData = (uint8_t) UDP->UDP_FDR[0];
617 pData++;
618 }
619}
620
621/**
622 * Checks if an ongoing transfer on an endpoint has been completed.
623 * \param bEndpoint Endpoint number.
624 * \return 1 if the current transfer on the given endpoint is complete;
625 * otherwise 0.
626 */
627static uint8_t UDP_IsTransferFinished(uint8_t bEndpoint)
628{
629 Endpoint *pEndpoint = &(endpoints[bEndpoint]);
630 Transfer *pTransfer = (Transfer*)&(pEndpoint->transfer);
631
632 // Check if it is a Control endpoint
633 // -> Control endpoint must always finish their transfer with a zero-length
634 // packet
635 if ((UDP->UDP_CSR[bEndpoint] & UDP_CSR_EPTYPE_Msk) == UDP_CSR_EPTYPE_CTRL) {
636
637 return (pTransfer->buffered < pEndpoint->size);
638 }
639 // Other endpoints only need to transfer all the data
640 else {
641
642 return (pTransfer->buffered <= pEndpoint->size)
643 && (pTransfer->remaining == 0);
644 }
645}
646
647/**
648 * Endpoint interrupt handler.
649 * Handle IN/OUT transfers, received SETUP packets and STALLing
650 * \param bEndpoint Index of endpoint
651 */
652static void UDP_EndpointHandler(uint8_t bEndpoint)
653{
654 Endpoint *pEndpoint = &(endpoints[bEndpoint]);
655 Transfer *pTransfer = (Transfer*)&(pEndpoint->transfer);
656 MblTransfer *pMblt = (MblTransfer*)&(pEndpoint->transfer);
657 uint32_t status = UDP->UDP_CSR[bEndpoint];
658 uint16_t wPacketSize;
659 USBGenericRequest request;
660
661 TRACE_DEBUG_WP("E%d ", bEndpoint);
Christina Quast23c00132015-01-27 15:17:37 +0100662 TRACE_DEBUG_WP("st:0x%" PRIX32 " ", status);
Christina Quast8be71e42014-12-02 13:06:01 +0100663
664 // Handle interrupts
665 // IN packet sent
666 if ((status & UDP_CSR_TXCOMP) != 0) {
667
668 TRACE_DEBUG_WP("Wr ");
669
670 // Check that endpoint was in MBL Sending state
671 if (pEndpoint->state == UDP_ENDPOINT_SENDINGM) {
672
673 USBDTransferBuffer * pMbli = &(pMblt->pMbl[pMblt->outLast]);
674 uint8_t bufferEnd = 0;
675
676 TRACE_DEBUG_WP("TxM%d.%d ", pMblt->listState, pMbli->buffered);
677
678 // End of transfer ?
679 if (pMblt->listState == MBL_NULL && pMbli->buffered == 0) {
680
681 pMbli->transferred += pMbli->buffered;
682 pMbli->buffered = 0;
683
684 // Disable interrupt
685 UDP->UDP_IDR = 1 << bEndpoint;
686 UDP_EndOfTransfer(bEndpoint, USBD_STATUS_SUCCESS);
687 CLEAR_CSR(bEndpoint, UDP_CSR_TXCOMP);
688 }
689 else {
690
691 // Transfer remaining data
692 TRACE_DEBUG_WP("%d ", pEndpoint->size);
693
694 if (pMbli->buffered > pEndpoint->size) {
695 pMbli->transferred += pEndpoint->size;
696 pMbli->buffered -= pEndpoint->size;
697 }
698 else {
699 pMbli->transferred += pMbli->buffered;
700 pMbli->buffered = 0;
701 }
702
703 // Send next packet
704 if (CHIP_USB_ENDPOINTS_BANKS(bEndpoint) == 1) {
705
706 // No double buffering
707 bufferEnd = UDP_MblWriteFifo(bEndpoint);
708 SET_CSR(bEndpoint, UDP_CSR_TXPKTRDY);
709 CLEAR_CSR(bEndpoint, UDP_CSR_TXCOMP);
710 }
711 else {
712 // Double buffering
713 SET_CSR(bEndpoint, UDP_CSR_TXPKTRDY);
714 CLEAR_CSR(bEndpoint, UDP_CSR_TXCOMP);
715 bufferEnd = UDP_MblWriteFifo(bEndpoint);
716 }
717
718 if (bufferEnd && pMblt->fCallback) {
719 ((MblTransferCallback) pTransfer->fCallback)
720 (pTransfer->pArgument,
721 USBD_STATUS_PARTIAL_DONE);
722 }
723 }
724 }
725 // Check that endpoint was in Sending state
726 else if (pEndpoint->state == UDP_ENDPOINT_SENDING) {
727
728 // End of transfer ?
729 if (UDP_IsTransferFinished(bEndpoint)) {
730
731 pTransfer->transferred += pTransfer->buffered;
732 pTransfer->buffered = 0;
733
734 // Disable interrupt if this is not a control endpoint
735 if ((status & UDP_CSR_EPTYPE_Msk) != UDP_CSR_EPTYPE_CTRL) {
736
737 UDP->UDP_IDR = 1 << bEndpoint;
738 }
739
740 UDP_EndOfTransfer(bEndpoint, USBD_STATUS_SUCCESS);
741 CLEAR_CSR(bEndpoint, UDP_CSR_TXCOMP);
742 }
743 else {
744
745 // Transfer remaining data
746 TRACE_DEBUG_WP(" %d ", pEndpoint->size);
747
748 pTransfer->transferred += pEndpoint->size;
749 pTransfer->buffered -= pEndpoint->size;
750
751 // Send next packet
752 if (CHIP_USB_ENDPOINTS_BANKS(bEndpoint) == 1) {
753
754 // No double buffering
755 UDP_WritePayload(bEndpoint);
756 SET_CSR(bEndpoint, UDP_CSR_TXPKTRDY);
757 CLEAR_CSR(bEndpoint, UDP_CSR_TXCOMP);
758 }
759 else {
760 // Double buffering
761 SET_CSR(bEndpoint, UDP_CSR_TXPKTRDY);
762 CLEAR_CSR(bEndpoint, UDP_CSR_TXCOMP);
763 UDP_WritePayload(bEndpoint);
764 }
765 }
766 }
767 else {
768 // Acknowledge interrupt
769 TRACE_ERROR("Error Wr%d, %x\n\r", bEndpoint, pEndpoint->state);
770 CLEAR_CSR(bEndpoint, UDP_CSR_TXCOMP);
771 }
772 }
773
774 // OUT packet received
775 if ((status & UDP_CSR_RXDATA_BK) != 0) {
776
777 TRACE_DEBUG_WP("Rd ");
778
779 // Check that the endpoint is in Receiving state
780 if (pEndpoint->state != UDP_ENDPOINT_RECEIVING) {
781
782 // Check if an ACK has been received on a Control endpoint
783 if (((status & UDP_CSR_EPTYPE_Msk) == UDP_CSR_EPTYPE_CTRL)
784 && ((status & UDP_CSR_RXBYTECNT_Msk) == 0)) {
785
786 // Acknowledge the data and finish the current transfer
787 UDP_ClearRxFlag(bEndpoint);
788 UDP_EndOfTransfer(bEndpoint, USBD_STATUS_SUCCESS);
789 }
790 // Check if the data has been STALLed
791 else if ((status & UDP_CSR_FORCESTALL) != 0) {
792
793 // Discard STALLed data
794 TRACE_DEBUG_WP("Discard ");
795 UDP_ClearRxFlag(bEndpoint);
796 }
797 // NAK the data
798 else {
799
800 TRACE_DEBUG_WP("Nak ");
801 UDP->UDP_IDR = 1 << bEndpoint;
802 }
803 }
804 // Endpoint is in Read state
805 else {
806
807 // Retrieve data and store it into the current transfer buffer
808 wPacketSize = (uint16_t) (status >> 16);
809 TRACE_DEBUG_WP("%d ", wPacketSize);
810 UDP_ReadPayload(bEndpoint, wPacketSize);
811 UDP_ClearRxFlag(bEndpoint);
812
813 // Check if the transfer is finished
814 if ((pTransfer->remaining == 0) || (wPacketSize < pEndpoint->size)) {
815
816 // Disable interrupt if this is not a control endpoint
817 if ((status & UDP_CSR_EPTYPE_Msk) != UDP_CSR_EPTYPE_CTRL) {
818
819 UDP->UDP_IDR = 1 << bEndpoint;
820 }
821 UDP_EndOfTransfer(bEndpoint, USBD_STATUS_SUCCESS);
822 }
823 }
824 }
825
826 // STALL sent
827 if ((status & UDP_CSR_STALLSENTISOERROR) != 0) {
828
829 CLEAR_CSR(bEndpoint, UDP_CSR_STALLSENTISOERROR);
830
831 if ( (status & UDP_CSR_EPTYPE_Msk) == UDP_CSR_EPTYPE_ISO_IN
832 || (status & UDP_CSR_EPTYPE_Msk) == UDP_CSR_EPTYPE_ISO_OUT ) {
833
834 TRACE_WARNING("Isoe [%d] ", bEndpoint);
835 UDP_EndOfTransfer(bEndpoint, USBD_STATUS_ABORTED);
836 }
837 else {
838
839 TRACE_WARNING("Sta 0x%X [%d] ", (int)status, bEndpoint);
840
841 if (pEndpoint->state != UDP_ENDPOINT_HALTED) {
842
843 TRACE_WARNING( "_ " );
844 // If the endpoint is not halted, clear the STALL condition
845 CLEAR_CSR(bEndpoint, UDP_CSR_FORCESTALL);
846 }
847 }
848 }
849
850 // SETUP packet received
851 if ((status & UDP_CSR_RXSETUP) != 0) {
852
853 TRACE_DEBUG_WP("Stp ");
854
855 // If a transfer was pending, complete it
856 // Handles the case where during the status phase of a control write
857 // transfer, the host receives the device ZLP and ack it, but the ack
858 // is not received by the device
859 if ((pEndpoint->state == UDP_ENDPOINT_RECEIVING)
860 || (pEndpoint->state == UDP_ENDPOINT_SENDING)) {
861
862 UDP_EndOfTransfer(bEndpoint, USBD_STATUS_SUCCESS);
863 }
864 // Copy the setup packet
865 UDP_ReadRequest(&request);
866
867 // Set the DIR bit before clearing RXSETUP in Control IN sequence
868 if (USBGenericRequest_GetDirection(&request) == USBGenericRequest_IN) {
869
870 SET_CSR(bEndpoint, UDP_CSR_DIR);
871 }
872 // Acknowledge setup packet
873 CLEAR_CSR(bEndpoint, UDP_CSR_RXSETUP);
874
875 // Forward the request to the upper layer
876 USBD_RequestHandler(0, &request);
877 }
878
879}
880
881/**
882 * Sends data through a USB endpoint. Sets up the transfer descriptor,
883 * writes one or two data payloads (depending on the number of FIFO bank
884 * for the endpoint) and then starts the actual transfer. The operation is
885 * complete when all the data has been sent.
886 *
887 * *If the size of the buffer is greater than the size of the endpoint
888 * (or twice the size if the endpoint has two FIFO banks), then the buffer
889 * must be kept allocated until the transfer is finished*. This means that
890 * it is not possible to declare it on the stack (i.e. as a local variable
891 * of a function which returns after starting a transfer).
892 *
893 * \param pEndpoint Pointer to Endpoint struct.
894 * \param pData Pointer to a buffer with the data to send.
895 * \param dLength Size of the data buffer.
896 * \return USBD_STATUS_SUCCESS if the transfer has been started;
897 * otherwise, the corresponding error status code.
898 */
899static inline uint8_t UDP_Write(uint8_t bEndpoint,
900 const void *pData,
901 uint32_t dLength)
902{
903 Endpoint *pEndpoint = &(endpoints[bEndpoint]);
904 Transfer *pTransfer = (Transfer*)&(pEndpoint->transfer);
905
906 /* Check that the endpoint is in Idle state */
907 if (pEndpoint->state != UDP_ENDPOINT_IDLE) {
908
909 return USBD_STATUS_LOCKED;
910 }
Christina Quast23c00132015-01-27 15:17:37 +0100911 TRACE_DEBUG_WP("Write%d(%" PRIu32 ") ", bEndpoint, dLength);
Christina Quast8be71e42014-12-02 13:06:01 +0100912
Christina Quastf51e0d22015-01-03 21:51:24 +0100913/* int i;
914 for (i = 0; i < dLength; i++) {
915 if (!(i%16)) {
916 printf("\n\r");
917 }
918 printf("0x%x ", ((uint8_t*)pData)[i]);
919 }
920 printf("\n\r");
921*/
922
Christina Quast8be71e42014-12-02 13:06:01 +0100923 /* Setup the transfer descriptor */
924 pTransfer->pData = (void *) pData;
925 pTransfer->remaining = dLength;
926 pTransfer->buffered = 0;
927 pTransfer->transferred = 0;
928
929 /* Send the first packet */
930 pEndpoint->state = UDP_ENDPOINT_SENDING;
931 while((UDP->UDP_CSR[bEndpoint]&UDP_CSR_TXPKTRDY)==UDP_CSR_TXPKTRDY);
932 UDP_WritePayload(bEndpoint);
933 SET_CSR(bEndpoint, UDP_CSR_TXPKTRDY);
934
935 /* If double buffering is enabled and there is data remaining,
936 prepare another packet */
937 if ((CHIP_USB_ENDPOINTS_BANKS(bEndpoint) > 1) && (pTransfer->remaining > 0)) {
938
939 UDP_WritePayload(bEndpoint);
940 }
941
942 /* Enable interrupt on endpoint */
943 UDP->UDP_IER = 1 << bEndpoint;
944
945 return USBD_STATUS_SUCCESS;
946}
947
948/**
949 * Sends data through a USB endpoint. Sets up the transfer descriptor list,
950 * writes one or two data payloads (depending on the number of FIFO bank
951 * for the endpoint) and then starts the actual transfer. The operation is
952 * complete when all the transfer buffer in the list has been sent.
953 *
954 * *If the size of the buffer is greater than the size of the endpoint
955 * (or twice the size if the endpoint has two FIFO banks), then the buffer
956 * must be kept allocated until the transfer is finished*. This means that
957 * it is not possible to declare it on the stack (i.e. as a local variable
958 * of a function which returns after starting a transfer).
959 *
960 * \param pEndpoint Pointer to Endpoint struct.
961 * \param pData Pointer to a buffer with the data to send.
962 * \param dLength Size of the data buffer.
963 * \return USBD_STATUS_SUCCESS if the transfer has been started;
964 * otherwise, the corresponding error status code.
965 */
966static inline uint8_t UDP_AddWr(uint8_t bEndpoint,
967 const void *pData,
968 uint32_t dLength)
969{
970 Endpoint *pEndpoint = &(endpoints[bEndpoint]);
971 MblTransfer *pMbl = (MblTransfer*)&(pEndpoint->transfer);
972 USBDTransferBuffer *pTx;
973
974 /* Check parameter */
975 if (dLength >= 0x10000)
976 return USBD_STATUS_INVALID_PARAMETER;
977
978 /* Data in progressing */
979 if (pEndpoint->state > UDP_ENDPOINT_IDLE) {
980 /* If list full */
981 if (pMbl->listState == MBL_FULL) {
982 return USBD_STATUS_LOCKED;
983 }
984 }
985
Christina Quast23c00132015-01-27 15:17:37 +0100986 TRACE_DEBUG_WP("AddW%d(%" PRIu32 ") ", bEndpoint, dLength);
Christina Quast8be71e42014-12-02 13:06:01 +0100987
988 /* Add buffer to buffer list and update index */
989 pTx = &(pMbl->pMbl[pMbl->inCurr]);
990 pTx->pBuffer = (uint8_t*)pData;
991 pTx->size = pTx->remaining = dLength;
992 pTx->transferred = pTx->buffered = 0;
993 /* Update input index */
994 if (pMbl->inCurr >= (pMbl->listSize-1)) pMbl->inCurr = 0;
995 else pMbl->inCurr ++;
996 if (pMbl->inCurr == pMbl->outCurr) pMbl->listState = MBL_FULL;
997 else pMbl->listState = 0;
998 /* Start sending when offset achieved */
999 if (MBL_NbBuffer(pMbl->inCurr, pMbl->outCurr, pMbl->listSize)
1000 >= pMbl->offsetSize
1001 && pEndpoint->state == UDP_ENDPOINT_IDLE) {
1002 TRACE_DEBUG_WP("StartT ");
1003 /* Change state */
1004 pEndpoint->state = UDP_ENDPOINT_SENDINGM;
1005 while((UDP->UDP_CSR[bEndpoint]&UDP_CSR_TXPKTRDY)==UDP_CSR_TXPKTRDY);
1006 /* Send first packet */
1007 UDP_MblWriteFifo(bEndpoint);
1008 SET_CSR(bEndpoint, UDP_CSR_TXPKTRDY);
1009 /* If double buffering is enabled and there is remaining, continue */
1010 if ((CHIP_USB_ENDPOINTS_BANKS(bEndpoint) > 1)
1011 && pMbl->pMbl[pMbl->outCurr].remaining) {
1012 UDP_MblWriteFifo(bEndpoint);
1013 }
1014 /* Enable interrupt on endpoint */
1015 UDP->UDP_IER = 1 << bEndpoint;
1016 }
1017
1018 return USBD_STATUS_SUCCESS;
1019}
1020
1021/**
1022 * Reads incoming data on an USB endpoint This methods sets the transfer
1023 * descriptor and activate the endpoint interrupt. The actual transfer is
1024 * then carried out by the endpoint interrupt handler. The Read operation
1025 * finishes either when the buffer is full, or a short packet (inferior to
1026 * endpoint maximum size) is received.
1027 *
1028 * *The buffer must be kept allocated until the transfer is finished*.
1029 * \param bEndpoint Endpoint number.
1030 * \param pData Pointer to a data buffer.
1031 * \param dLength Size of the data buffer in bytes.
1032 * \return USBD_STATUS_SUCCESS if the read operation has been started;
1033 * otherwise, the corresponding error code.
1034 */
1035static inline uint8_t UDP_Read(uint8_t bEndpoint,
1036 void *pData,
1037 uint32_t dLength)
1038{
1039 Endpoint *pEndpoint = &(endpoints[bEndpoint]);
1040 Transfer *pTransfer = (Transfer*)&(pEndpoint->transfer);
1041
1042 /* Return if the endpoint is not in IDLE state */
1043 if (pEndpoint->state != UDP_ENDPOINT_IDLE) {
1044
1045 return USBD_STATUS_LOCKED;
1046 }
1047
1048 /* Endpoint enters Receiving state */
1049 pEndpoint->state = UDP_ENDPOINT_RECEIVING;
Christina Quast23c00132015-01-27 15:17:37 +01001050 TRACE_DEBUG_WP("Read%d(%" PRIu32 ") ", bEndpoint, dLength);
Christina Quast8be71e42014-12-02 13:06:01 +01001051
Christina Quastf51e0d22015-01-03 21:51:24 +01001052/* int i;
1053 for (i = 0; i < dLength; i++) {
1054 if (!(i%16)) {
1055 printf("\n\r");
1056 }
1057 printf("0x%x ", ((uint8_t*)pData)[i]);
1058 }
1059 printf("\n\r");
1060*/
1061
Christina Quast8be71e42014-12-02 13:06:01 +01001062 /* Set the transfer descriptor */
1063 pTransfer->pData = pData;
1064 pTransfer->remaining = dLength;
1065 pTransfer->buffered = 0;
1066 pTransfer->transferred = 0;
1067
1068 /* Enable interrupt on endpoint */
1069 UDP->UDP_IER = 1 << bEndpoint;
1070
1071 return USBD_STATUS_SUCCESS;
1072}
1073
1074
1075/*---------------------------------------------------------------------------
1076 * Exported functions
1077 *---------------------------------------------------------------------------*/
1078
1079/**
1080 * USBD (UDP) interrupt handler
1081 * Manages device resume, suspend, end of bus reset.
1082 * Forwards endpoint events to the appropriate handler.
1083 */
1084void USBD_IrqHandler(void)
1085{
1086 uint32_t status;
1087 int32_t eptnum = 0;
1088
1089 /* Enable peripheral ? */
1090 //UDP_EnablePeripheralClock();
1091
1092 /* Get interrupt status
1093 Some interrupts may get masked depending on the device state */
1094 status = UDP->UDP_ISR;
1095 status &= UDP->UDP_IMR;
Christina Quastf51e0d22015-01-03 21:51:24 +01001096
Christina Quast23c00132015-01-27 15:17:37 +01001097 TRACE_DEBUG("status; 0x%" PRIx32 , status);
Christina Quast8be71e42014-12-02 13:06:01 +01001098
1099 if (USBD_GetState() < USBD_STATE_POWERED) {
1100
1101 status &= UDP_ICR_WAKEUP | UDP_ICR_RXRSM;
1102 UDP->UDP_ICR = ~status;
1103 }
1104
1105 /* Return immediately if there is no interrupt to service */
1106 if (status == 0) {
1107
1108 TRACE_DEBUG_WP(".\n\r");
1109 return;
1110 }
1111
1112 /* Toggle USB LED if the device is active */
1113 if (USBD_GetState() >= USBD_STATE_POWERED) {
1114
1115 //LED_Set(USBD_LEDUSB);
1116 }
1117
1118 /* Service interrupts */
1119
1120 /** / Start Of Frame (SOF) */
1121 //if (ISSET(dStatus, UDP_ISR_SOFINT)) {
1122 //
1123 // TRACE_DEBUG("SOF");
1124 //
1125 // // Invoke the SOF callback
1126 // USB_StartOfFrameCallback(pUsb);
1127 //
1128 // // Acknowledge interrupt
1129 // UDP->UDP_ICR = UDP_ICR_SOFINT;
1130 // dStatus &= ~UDP_ISR_SOFINT;
1131 //}
1132 /* Resume (Wakeup) */
1133 if ((status & (UDP_ISR_WAKEUP | UDP_ISR_RXRSM)) != 0) {
1134
1135 TRACE_INFO_WP("Res ");
1136 /* Clear and disable resume interrupts */
1137 UDP->UDP_ICR = UDP_ICR_WAKEUP | UDP_ICR_RXRSM | UDP_ICR_RXSUSP;
1138 UDP->UDP_IDR = UDP_IDR_WAKEUP | UDP_IDR_RXRSM;
1139 /* Do resome operations */
1140 USBD_ResumeHandler();
1141 }
1142
1143 /* Suspend
1144 This interrupt is always treated last (hence the '==') */
1145 if (status == UDP_ISR_RXSUSP) {
1146
1147 TRACE_INFO_WP("Susp ");
1148 /* Enable wakeup */
1149 UDP->UDP_IER = UDP_IER_WAKEUP | UDP_IER_RXRSM;
1150 /* Acknowledge interrupt */
1151 UDP->UDP_ICR = UDP_ICR_RXSUSP;
1152 /* Do suspend operations */
1153 USBD_SuspendHandler();
1154 }
1155 /* End of bus reset */
1156 else if ((status & UDP_ISR_ENDBUSRES) != 0) {
1157
1158 TRACE_INFO_WP("EoBRes ");
1159 /* Flush and enable the Suspend interrupt */
1160 UDP->UDP_ICR = UDP_ICR_WAKEUP | UDP_ICR_RXRSM | UDP_ICR_RXSUSP;
1161 UDP->UDP_IER = UDP_IER_RXSUSP;
1162
1163 /* Do RESET operations */
1164 USBD_ResetHandler();
1165
1166 /* Acknowledge end of bus reset interrupt */
1167 UDP->UDP_ICR = UDP_ICR_ENDBUSRES;
1168 }
1169 /* Endpoint interrupts */
1170 else {
1171
1172 status &= ((1 << CHIP_USB_NUMENDPOINTS) - 1);
1173 while (status != 0) {
1174
1175 /* Check if endpoint has a pending interrupt */
1176 if ((status & (1 << eptnum)) != 0) {
1177
1178 UDP_EndpointHandler(eptnum);
1179 status &= ~(1 << eptnum);
1180
1181 if (status != 0) {
1182
1183 TRACE_INFO_WP("\n\r - ");
1184 }
1185 }
1186 eptnum++;
1187 }
1188 }
1189
1190 /* Toggle LED back to its previous state */
1191 TRACE_DEBUG_WP("!");
1192 TRACE_INFO_WP("\n\r");
1193 if (USBD_GetState() >= USBD_STATE_POWERED) {
1194
1195 //LED_Clear(USBD_LEDUSB);
1196 }
1197}
1198
1199/**
1200 * \brief Reset endpoints and disable them.
1201 * -# Terminate transfer if there is any, with given status;
1202 * -# Reset the endpoint & disable it.
1203 * \param bmEPs Bitmap for endpoints to reset.
1204 * \param bStatus Status passed to terminate transfer on endpoint.
1205 * \param bKeepCfg 1 to keep old endpoint configuration.
1206 * \note Use USBD_HAL_ConfigureEP() to configure and enable endpoint
1207 if not keeping old configuration.
1208 * \sa USBD_HAL_ConfigureEP().
1209 */
1210void USBD_HAL_ResetEPs(uint32_t bmEPs, uint8_t bStatus, uint8_t bKeepCfg)
1211{
1212 Endpoint *pEndpoint;
1213 uint32_t tmp = bmEPs & ((1<<CHIP_USB_NUMENDPOINTS)-1);
1214 uint8_t ep;
1215 uint32_t epBit, epCfg;
1216 for (ep = 0, epBit = 1; ep < CHIP_USB_NUMENDPOINTS; ep ++) {
1217 if (tmp & epBit) {
1218
1219 /* Disable ISR */
1220 UDP->UDP_IDR = epBit;
1221 /* Kill pending TXPKTREADY */
1222 CLEAR_CSR(ep, UDP_CSR_TXPKTRDY);
1223
1224 /* Reset transfer information */
1225 pEndpoint = &(endpoints[ep]);
1226 /* Reset endpoint state */
1227 pEndpoint->bank = 0;
1228 /* Endpoint configure */
1229 epCfg = UDP->UDP_CSR[ep];
1230 /* Reset endpoint */
1231 UDP->UDP_RST_EP |= epBit;
1232 UDP->UDP_RST_EP &= ~epBit;
1233 /* Restore configure */
1234 if (bKeepCfg) {
1235 //SET_CSR(ep, pEndpoint->CSR);
1236 SET_CSR(ep, epCfg);
1237 }
1238 else {
1239 //pEndpoint->CSR = 0;
1240 pEndpoint->state = UDP_ENDPOINT_DISABLED;
1241 }
1242
1243 /* Terminate transfer on this EP */
1244 UDP_EndOfTransfer(ep, bStatus);
1245 }
1246 epBit <<= 1;
1247 }
1248 /* Reset EPs */
1249 // UDP->UDP_RST_EP |= bmEPs;
1250 // UDP->UDP_RST_EP &= ~bmEPs;
1251}
1252
1253/**
1254 * Cancel pending READ/WRITE
1255 * \param bmEPs Bitmap for endpoints to reset.
1256 * \note EP callback is invoked with USBD_STATUS_CANCELED.
1257 */
1258void USBD_HAL_CancelIo(uint32_t bmEPs)
1259{
1260 uint32_t tmp = bmEPs & ((1<<CHIP_USB_NUMENDPOINTS)-1);
1261 uint8_t ep;
1262 uint32_t epBit;
1263 for (ep = 0, epBit = 1; ep < CHIP_USB_NUMENDPOINTS; ep ++) {
1264 if (tmp & epBit) {
1265
1266 /* Disable ISR */
1267 UDP->UDP_IDR = epBit;
1268 /* Kill pending TXPKTREADY */
1269 CLEAR_CSR(ep, UDP_CSR_TXPKTRDY);
1270
1271 /* Terminate transfer on this EP */
1272 UDP_EndOfTransfer(ep, USBD_STATUS_CANCELED);
1273 }
1274 epBit <<= 1;
1275 }
1276}
1277
1278/**
1279 * Configures an endpoint according to its endpoint Descriptor.
1280 * \param pDescriptor Pointer to an endpoint descriptor.
1281 */
1282uint8_t USBD_HAL_ConfigureEP(const USBEndpointDescriptor *pDescriptor)
1283{
1284 Endpoint *pEndpoint;
1285 uint8_t bEndpoint;
1286 uint8_t bType;
1287 uint8_t bEndpointDir;
1288
1289 /* NULL descriptor -> Control endpoint 0 in default */
1290 if (pDescriptor == 0) {
1291 bEndpoint = 0;
1292 pEndpoint = &(endpoints[bEndpoint]);
1293 bType= USBEndpointDescriptor_CONTROL;
1294 bEndpointDir = 0;
1295 pEndpoint->size = CHIP_USB_ENDPOINTS_MAXPACKETSIZE(0);
1296 }
1297 /* Device descriptor -> Specific Control EP */
1298 else if (pDescriptor->bDescriptorType == USBGenericDescriptor_DEVICE) {
1299 bEndpoint = 0;
1300 pEndpoint = &(endpoints[bEndpoint]);
1301 bType = USBEndpointDescriptor_CONTROL;
1302 bEndpointDir = 0;
1303 pEndpoint->size = ((USBDeviceDescriptor *)pDescriptor)->bMaxPacketSize0;
1304 }
1305 /* Not endpoint descriptor, ERROR! */
1306 else if (pDescriptor->bDescriptorType != USBGenericDescriptor_ENDPOINT) {
1307 return 0xFF;
1308 }
1309 else {
1310 bEndpoint = USBEndpointDescriptor_GetNumber(pDescriptor);
1311 pEndpoint = &(endpoints[bEndpoint]);
1312 bType = USBEndpointDescriptor_GetType(pDescriptor);
1313 bEndpointDir = USBEndpointDescriptor_GetDirection(pDescriptor);
1314 pEndpoint->size = USBEndpointDescriptor_GetMaxPacketSize(pDescriptor);
1315 }
1316
1317 /* Abort the current transfer is the endpoint was configured and in
1318 Write or Read state */
1319 if ((pEndpoint->state == UDP_ENDPOINT_RECEIVING)
1320 || (pEndpoint->state == UDP_ENDPOINT_SENDING)
1321 || (pEndpoint->state == UDP_ENDPOINT_RECEIVINGM)
1322 || (pEndpoint->state == UDP_ENDPOINT_SENDINGM)) {
1323 UDP_EndOfTransfer(bEndpoint, USBD_STATUS_RESET);
1324 }
1325 pEndpoint->state = UDP_ENDPOINT_IDLE;
1326
1327 /* Reset Endpoint Fifos */
1328 UDP->UDP_RST_EP |= (1 << bEndpoint);
1329 UDP->UDP_RST_EP &= ~(1 << bEndpoint);
1330
1331 /* Configure endpoint */
1332 SET_CSR(bEndpoint, (uint32_t)UDP_CSR_EPEDS
1333 | (bType << 8) | (bEndpointDir << 10));
1334 if (bType != USBEndpointDescriptor_CONTROL) {
1335
1336 }
1337 else {
1338
1339 UDP->UDP_IER = (1 << bEndpoint);
1340 }
1341
1342 TRACE_INFO_WP("CfgEp%d ", bEndpoint);
1343 return bEndpoint;
1344}
1345
1346/**
1347 * Set callback for a USB endpoint for transfer (read/write).
1348 *
1349 * \param bEP Endpoint number.
1350 * \param fCallback Optional callback function to invoke when the transfer is
1351 * complete.
1352 * \param pCbData Optional pointer to data to the callback function.
1353 * \return USBD_STATUS_SUCCESS or USBD_STATUS_LOCKED if endpoint is busy.
1354 */
1355uint8_t USBD_HAL_SetTransferCallback(uint8_t bEP,
1356 TransferCallback fCallback,
1357 void *pCbData)
1358{
1359 Endpoint *pEndpoint = &(endpoints[bEP]);
1360 TransferHeader *pTransfer = (TransferHeader*)&(pEndpoint->transfer);
1361 /* Check that the endpoint is not transferring */
1362 if (pEndpoint->state > UDP_ENDPOINT_IDLE) {
1363 return USBD_STATUS_LOCKED;
1364 }
1365 TRACE_DEBUG_WP("sXfrCb ");
1366 /* Setup the transfer callback and extension data */
1367 pTransfer->fCallback = (void*)fCallback;
1368 pTransfer->pArgument = pCbData;
1369 return USBD_STATUS_SUCCESS;
1370}
1371
1372/**
1373 * Configure an endpoint to use multi-buffer-list transfer mode.
1374 * The buffers can be added by _Read/_Write function.
1375 * \param pMbList Pointer to a multi-buffer list used, NULL to disable MBL.
1376 * \param mblSize Multi-buffer list size (number of buffers can be queued)
1377 * \param startOffset When number of buffer achieve this offset transfer start
1378 */
1379uint8_t USBD_HAL_SetupMblTransfer( uint8_t bEndpoint,
1380 USBDTransferBuffer* pMbList,
1381 uint16_t mblSize,
1382 uint16_t startOffset)
1383{
1384 Endpoint *pEndpoint = &(endpoints[bEndpoint]);
1385 MblTransfer *pXfr = (MblTransfer*)&(pEndpoint->transfer);
1386 uint16_t i;
1387 /* Check that the endpoint is not transferring */
1388 if (pEndpoint->state > UDP_ENDPOINT_IDLE) {
1389 return USBD_STATUS_LOCKED;
1390 }
1391 TRACE_DEBUG_WP("sMblXfr ");
1392 /* Enable Multi-Buffer Transfer List */
1393 if (pMbList) {
1394 /* Reset list items */
1395 for (i = 0; i < mblSize; i --) {
1396 pMbList[i].pBuffer = NULL;
1397 pMbList[i].size = 0;
1398 pMbList[i].transferred = 0;
1399 pMbList[i].buffered = 0;
1400 pMbList[i].remaining = 0;
1401 }
1402 /* Setup transfer */
1403 pXfr->transType = 1;
1404 pXfr->listState = 0; /* OK */
1405 pXfr->listSize = mblSize;
1406 pXfr->pMbl = pMbList;
1407 pXfr->outCurr = pXfr->outLast = 0;
1408 pXfr->inCurr = 0;
1409 pXfr->offsetSize = startOffset;
1410 }
1411 /* Disable Multi-Buffer Transfer */
1412 else {
1413 pXfr->transType = 0;
1414 pXfr->pMbl = NULL;
1415 pXfr->listSize = 0;
1416 pXfr->offsetSize = 1;
1417 }
1418 return USBD_STATUS_SUCCESS;
1419}
1420
1421/**
1422 * Sends data through a USB endpoint. Sets up the transfer descriptor,
1423 * writes one or two data payloads (depending on the number of FIFO bank
1424 * for the endpoint) and then starts the actual transfer. The operation is
1425 * complete when all the data has been sent.
1426 *
1427 * *If the size of the buffer is greater than the size of the endpoint
1428 * (or twice the size if the endpoint has two FIFO banks), then the buffer
1429 * must be kept allocated until the transfer is finished*. This means that
1430 * it is not possible to declare it on the stack (i.e. as a local variable
1431 * of a function which returns after starting a transfer).
1432 *
1433 * \param bEndpoint Endpoint number.
1434 * \param pData Pointer to a buffer with the data to send.
1435 * \param dLength Size of the data buffer.
1436 * \return USBD_STATUS_SUCCESS if the transfer has been started;
1437 * otherwise, the corresponding error status code.
1438 */
1439uint8_t USBD_HAL_Write( uint8_t bEndpoint,
1440 const void *pData,
1441 uint32_t dLength)
1442{
1443 if (endpoints[bEndpoint].transfer.transHdr.transType)
1444 return UDP_AddWr(bEndpoint, pData, dLength);
1445 else
1446 return UDP_Write(bEndpoint, pData, dLength);
1447}
1448
1449/**
1450 * Reads incoming data on an USB endpoint This methods sets the transfer
1451 * descriptor and activate the endpoint interrupt. The actual transfer is
1452 * then carried out by the endpoint interrupt handler. The Read operation
1453 * finishes either when the buffer is full, or a short packet (inferior to
1454 * endpoint maximum size) is received.
1455 *
1456 * *The buffer must be kept allocated until the transfer is finished*.
1457 * \param bEndpoint Endpoint number.
1458 * \param pData Pointer to a data buffer.
1459 * \param dLength Size of the data buffer in bytes.
1460 * \return USBD_STATUS_SUCCESS if the read operation has been started;
1461 * otherwise, the corresponding error code.
1462 */
1463uint8_t USBD_HAL_Read(uint8_t bEndpoint,
1464 void *pData,
1465 uint32_t dLength)
1466{
1467 if (endpoints[bEndpoint].transfer.transHdr.transType)
1468 return USBD_STATUS_SW_NOT_SUPPORTED;
1469 else
1470 return UDP_Read(bEndpoint, pData, dLength);
1471}
1472
1473/**
1474 * \brief Enable Pull-up, connect.
1475 *
1476 * -# Enable HW access if needed
1477 * -# Enable Pull-Up
1478 * -# Disable HW access if needed
1479 */
1480void USBD_HAL_Connect(void)
1481{
1482 uint8_t dis = UDP_EnablePeripheralClock();
1483 UDP->UDP_TXVC |= UDP_TXVC_PUON;
1484 if (dis) UDP_DisablePeripheralClock();
1485}
1486
1487/**
1488 * \brief Disable Pull-up, disconnect.
1489 *
1490 * -# Enable HW access if needed
1491 * -# Disable PULL-Up
1492 * -# Disable HW access if needed
1493 */
1494void USBD_HAL_Disconnect(void)
1495{
1496 uint8_t dis = UDP_EnablePeripheralClock();
1497 UDP->UDP_TXVC &= ~(uint32_t)UDP_TXVC_PUON;
1498 if (dis) UDP_DisablePeripheralClock();
1499}
1500
1501/**
1502 * Starts a remote wake-up procedure.
1503 */
1504void USBD_HAL_RemoteWakeUp(void)
1505{
1506 UDP_EnablePeripheralClock();
1507 UDP_EnableUsbClock();
1508 UDP_EnableTransceiver();
1509
1510 TRACE_INFO_WP("RWUp ");
1511
1512 // Activates a remote wakeup (edge on ESR), then clear ESR
1513 UDP->UDP_GLB_STAT |= UDP_GLB_STAT_ESR;
1514 UDP->UDP_GLB_STAT &= ~(uint32_t)UDP_GLB_STAT_ESR;
1515}
1516
1517/**
1518 * Sets the device address to the given value.
1519 * \param address New device address.
1520 */
1521void USBD_HAL_SetAddress(uint8_t address)
1522{
1523 /* Set address */
1524 UDP->UDP_FADDR = UDP_FADDR_FEN | (address & UDP_FADDR_FADD_Msk);
1525 /* If the address is 0, the device returns to the Default state */
1526 if (address == 0) UDP->UDP_GLB_STAT = 0;
1527 /* If the address is non-zero, the device enters the Address state */
1528 else UDP->UDP_GLB_STAT = UDP_GLB_STAT_FADDEN;
1529}
1530
1531/**
1532 * Sets the current device configuration.
1533 * \param cfgnum - Configuration number to set.
1534 */
1535void USBD_HAL_SetConfiguration(uint8_t cfgnum)
1536{
1537 /* If the configuration number if non-zero, the device enters the
1538 Configured state */
1539 if (cfgnum != 0) UDP->UDP_GLB_STAT |= UDP_GLB_STAT_CONFG;
1540 /* If the configuration number is zero, the device goes back to the Address
1541 state */
1542 else {
1543 UDP->UDP_GLB_STAT = UDP_FADDR_FEN;
1544 }
1545}
1546
1547/**
1548 * Initializes the USB HW Access driver.
1549 */
1550void USBD_HAL_Init(void)
1551{
Christina Quastf51e0d22015-01-03 21:51:24 +01001552 TRACE_DEBUG("%s\n\r", "USBD_HAL_Init");
1553
Christina Quast8be71e42014-12-02 13:06:01 +01001554 /* Must before USB & TXVC access! */
1555 UDP_EnablePeripheralClock();
1556
1557 /* Reset & disable endpoints */
1558 USBD_HAL_ResetEPs(0xFFFFFFFF, USBD_STATUS_RESET, 0);
1559
1560 /* Configure the pull-up on D+ and disconnect it */
1561 UDP->UDP_TXVC &= ~(uint32_t)UDP_TXVC_PUON;
1562
1563 UDP_EnableUsbClock();
1564
1565 UDP->UDP_IDR = 0xFE;
1566 UDP->UDP_IER = UDP_IER_WAKEUP;
1567}
1568
1569/**
1570 * Causes the given endpoint to acknowledge the next packet it receives
1571 * with a STALL handshake except setup request.
1572 * \param bEP Endpoint number.
1573 * \return USBD_STATUS_SUCCESS or USBD_STATUS_LOCKED.
1574 */
1575uint8_t USBD_HAL_Stall(uint8_t bEP)
1576{
1577 Endpoint *pEndpoint = &(endpoints[bEP]);
1578
1579 /* Check that endpoint is in Idle state */
1580 if (pEndpoint->state != UDP_ENDPOINT_IDLE) {
1581 TRACE_WARNING("UDP_Stall: EP%d locked\n\r", bEP);
1582 return USBD_STATUS_LOCKED;
1583 }
1584 /* STALL endpoint */
1585 SET_CSR(bEP, UDP_CSR_FORCESTALL);
1586 TRACE_DEBUG_WP("Stall%d ", bEP);
1587 return USBD_STATUS_SUCCESS;
1588}
1589
1590/**
1591 * Sets/Clear/Get the HALT state on the endpoint.
1592 * In HALT state, the endpoint should keep stalling any packet.
1593 * \param bEndpoint Endpoint number.
1594 * \param ctl Control code CLR/HALT/READ.
1595 * 0: Clear HALT state;
1596 * 1: Set HALT state;
1597 * .: Return HALT status.
1598 * \return USBD_STATUS_INVALID_PARAMETER if endpoint not exist,
1599 * otherwise endpoint halt status.
1600 */
1601uint8_t USBD_HAL_Halt(uint8_t bEndpoint, uint8_t ctl)
1602{
1603 Endpoint *pEndpoint = &(endpoints[bEndpoint]);
1604 uint8_t status = 0;
1605
1606 /* SET Halt */
1607 if (ctl == 1) {
1608 /* Check that endpoint is enabled and not already in Halt state */
1609 if ((pEndpoint->state != UDP_ENDPOINT_DISABLED)
1610 && (pEndpoint->state != UDP_ENDPOINT_HALTED)) {
1611
1612 TRACE_DEBUG_WP("Halt%d ", bEndpoint);
1613
1614 /* Abort the current transfer if necessary */
1615 UDP_EndOfTransfer(bEndpoint, USBD_STATUS_ABORTED);
1616
1617 /* Put endpoint into Halt state */
1618 SET_CSR(bEndpoint, UDP_CSR_FORCESTALL);
1619 pEndpoint->state = UDP_ENDPOINT_HALTED;
1620
1621 /* Enable the endpoint interrupt */
1622 UDP->UDP_IER = 1 << bEndpoint;
1623 }
1624 }
1625 /* CLEAR Halt */
1626 else if (ctl == 0) {
1627 /* Check if the endpoint is halted */
1628 //if (pEndpoint->state != UDP_ENDPOINT_DISABLED) {
1629 if (pEndpoint->state == UDP_ENDPOINT_HALTED) {
1630
1631 TRACE_DEBUG_WP("Unhalt%d ", bEndpoint);
1632
1633 /* Return endpoint to Idle state */
1634 pEndpoint->state = UDP_ENDPOINT_IDLE;
1635
1636 /* Clear FORCESTALL flag */
1637 CLEAR_CSR(bEndpoint, UDP_CSR_FORCESTALL);
1638
1639 /* Reset Endpoint Fifos, beware this is a 2 steps operation */
1640 UDP->UDP_RST_EP |= 1 << bEndpoint;
1641 UDP->UDP_RST_EP &= ~(1 << bEndpoint);
1642 }
1643 }
1644
1645 /* Return Halt status */
1646 if (pEndpoint->state == UDP_ENDPOINT_HALTED) {
1647 status = 1;
1648 }
1649 return( status );
1650}
1651
1652/**
1653 * Indicates if the device is running in high or full-speed. Always returns 0
1654 * since UDP does not support high-speed mode.
1655 */
1656uint8_t USBD_HAL_IsHighSpeed(void)
1657{
1658 return 0;
1659}
1660
1661/**
1662 * Suspend USB Device HW Interface
1663 *
1664 * -# Disable transceiver
1665 * -# Disable USB Clock
1666 * -# Disable USB Peripheral
1667 */
1668void USBD_HAL_Suspend(void)
1669{
1670 /* The device enters the Suspended state */
1671 UDP_DisableTransceiver();
1672 UDP_DisableUsbClock();
1673 UDP_DisablePeripheralClock();
1674}
1675
1676/**
1677 * Activate USB Device HW Interface
1678 * -# Enable USB Peripheral
1679 * -# Enable USB Clock
1680 * -# Enable transceiver
1681 */
1682void USBD_HAL_Activate(void)
1683{
1684 UDP_EnablePeripheralClock();
1685 UDP_EnableUsbClock();
1686 UDP_EnableTransceiver();
1687}
1688
1689/**@}*/
1690