blob: 635950be66daa1b5e49306fad130c59498cb653a [file] [log] [blame]
Kévin Redon69b92d92019-01-24 16:39:20 +01001/**
2 * \file
3 *
4 * \brief SAM USB host HPL
5 *
6 * Copyright (c) 2016-2018 Microchip Technology Inc. and its subsidiaries.
7 *
8 * \asf_license_start
9 *
10 * \page License
11 *
12 * Subject to your compliance with these terms, you may use Microchip
13 * software and any derivatives exclusively with Microchip products.
14 * It is your responsibility to comply with third party license terms applicable
15 * to your use of third party software (including open source software) that
16 * may accompany Microchip software.
17 *
18 * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
19 * WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
20 * INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
21 * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
22 * LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
23 * LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
24 * SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
25 * POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
26 * ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
27 * RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
28 * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
29 *
30 * \asf_license_stop
31 *
32 */
33
34#ifndef _HPL_USB_HOST_H_INCLUDED
35#define _HPL_USB_HOST_H_INCLUDED
36
37#include <hpl_usb.h>
38#include <hpl_irq.h>
39#include "hpl_usb_config.h"
40
41#ifdef __cplusplus
42extern "C" {
43#endif
44
45/** Driver version */
46#define USB_H_VERSION 0x00000001
47
48/**
49 * @brief USB HCD callback types
50 */
51enum usb_h_cb_type {
52 /** SOF generated */
53 USB_H_CB_SOF,
54 /** Root Hub change detected */
55 USB_H_CB_ROOTHUB_CHANGE,
56 /** Number of USB HCD callback types */
57 USB_H_CB_N
58};
59
60/**
61 * @brief USB HCD resource strategy
62 */
63enum usb_h_rsc_strategy {
64 /** Normal resource allocation, e.g.,
65 * 1 bank for interrupt endpoint,
66 * 2 bank for bulk endpoint and normal iso endpoint,
67 * 3 bank for iso high bandwidth endpoint.
68 */
69 USB_H_RSC_NORMAL = false,
70 /** Minimal resource allocation, e.g., only 1 bank for bulk endpoints */
71 USB_H_RSC_MINIMAL = true
72};
73
74/**
75 * @brief USB HCD pipe states
76 */
77enum usb_h_pipe_state {
78 /** Pipe is free to allocate */
79 USB_H_PIPE_S_FREE = 0x00,
80 /** Pipe is in configuration */
81 USB_H_PIPE_S_CFG = 0x01,
82 /** Pipe is allocated and idle */
83 USB_H_PIPE_S_IDLE = 0x02,
84 /** Pipe in control setup stage */
85 USB_H_PIPE_S_SETUP = 0x03,
86 /** Pipe in data IN stage */
87 USB_H_PIPE_S_DATI = 0x05,
88 /** Pipe in data OUT stage */
89 USB_H_PIPE_S_DATO = 0x06,
90 /** Pipe in data IN ZLP stage */
91 USB_H_PIPE_S_ZLPI = 0x07,
92 /** Pipe in data OUT ZLP stage */
93 USB_H_PIPE_S_ZLPO = 0x08,
94 /** Pipe in control status IN stage */
95 USB_H_PIPE_S_STATI = 0x09,
96 /** Pipe in control status OUT stage */
97 USB_H_PIPE_S_STATO = 0x0A,
98 /** Taken by physical pipe (in process) */
99 USB_H_PIPE_S_TAKEN = 0x10
100};
101
102/**
103 * @brief USB HCD status code
104 */
105enum usb_h_status {
106 /** OK */
107 USB_H_OK = ERR_NONE,
108 /** Busy */
109 USB_H_BUSY = ERR_BUSY,
110 /** Denied */
111 USB_H_DENIED = ERR_DENIED,
112 /** Timeout */
113 USB_H_TIMEOUT = ERR_TIMEOUT,
114 /** Abort */
115 USB_H_ABORT = ERR_ABORTED,
116 /** Stall protocol */
117 USB_H_STALL = ERR_PROTOCOL,
118 /** Transfer reset by pipe re-configure */
119 USB_H_RESET = ERR_REQ_FLUSHED,
120 /** Argument error */
121 USB_H_ERR_ARG = ERR_INVALID_ARG,
122 /** Operation not supported */
123 USB_H_ERR_UNSP_OP = ERR_UNSUPPORTED_OP,
124 /** No resource */
125 USB_H_ERR_NO_RSC = ERR_NO_RESOURCE,
126 /** Not initialized */
127 USB_H_ERR_NOT_INIT = ERR_NOT_INITIALIZED,
128 /** Some general error */
129 USB_H_ERR = ERR_IO
130};
131
132/** Forward declare for pipe structure */
133struct usb_h_pipe;
134
135/** Forward declare for driver descriptor structure */
136struct usb_h_desc;
137
138/**
139 * \brief Prototyping USB HCD callback of SOF
140 */
141typedef void (*usb_h_cb_sof_t)(struct usb_h_desc *drv);
142
143/**
144 * \brief Prototyping USB HCD callback of root hub changing.
145 * According to the bitmap size, max port number is 31.
146 */
147typedef void (*usb_h_cb_roothub_t)(struct usb_h_desc *drv, uint8_t port, uint8_t ftr);
148
149/**
150 * Prototyping USB HCD callback of pipe transfer done.
151 * For control pipe, it's forced to call even if there is no transfer
152 * in progress, since the pipe size could be changed at run time.
153 */
154typedef void (*usb_h_pipe_cb_xfer_t)(struct usb_h_pipe *pipe);
155
156/** Access to max packet size of a pipe */
157#define usb_h_pipe_max_pkt_size(p) (p->max_pkt_size)
158
159/** Access to device address of a pipe */
160#define usb_h_pipe_dev_addr(p) (p->dev)
161
162/** Access to endpoint address of a pipe */
163#define usb_h_pipe_ep_addr(p) (p->ep)
164
165/** Access to state of a pipe */
166#define usb_h_pipe_state(p) (p->x.general.state)
167
168/** Access to status of a pipe */
169#define usb_h_pipe_status(p) (p->x.general.status)
170
171/**
172 * @brief USB Host Controller device structure
173 */
174struct usb_h_desc {
175 /** Pointer to hardware base */
176 void *hw;
177 /** Pointer to private data for Host Controller driver */
178 void *prvt;
179 /** Interrupt handling descriptor */
180 struct _irq_descriptor irq;
181 /** Callback of SOF */
182 usb_h_cb_sof_t sof_cb;
183 /** Callback of root hub change */
184 usb_h_cb_roothub_t rh_cb;
185#if CONF_USB_H_INST_OWNER_SP
186 /** Extension for the driver owner (upper layer user) */
187 void *owner;
188#endif
189};
190
191/**
192 * @brief Transfer descriptor for control transfer
193 *
194 * Timing in USB 2.0 spec.:
195 * - 9.2.6.1 : USB sets an upper limit of 5 seconds as the upper limit for any
196 * command to be processed.
197 * - 9.2.6.3 : if a device receives a SetAddress() request, the device must be
198 * able to complete processing of the request and be able to
199 * successfully complete the Status stage of the request within
200 * 50 ms.
201 * After successful completion of the Status stage, the device is
202 * allowed a SetAddress() recovery interval of 2 ms. At the end of
203 * this interval, the device must be able to accept Setup packets
204 * addressed to the new address.
205 * - 9.2.6.4 : For standard device requests that require no Data stage, a device
206 * must be able to complete the request and be able to successfully
207 * complete the Status stage of the request within 50 ms of receipt
208 * of the request. This limitation applies to requests to the
209 * device, interface, or endpoint.
210 * For standard device requests that require data stage transfer to
211 * the host, the device must be able to return the first data packet
212 * to the host within 500 ms of receipt of the request. For
213 * subsequent data packets, if any, the device must be able to
214 * return them within 500 ms of successful completion of the
215 * transmission of the previous packet. The device must then be
216 * able to successfully complete the status stage within 50 ms after
217 * returning the last data packet.
218 * For standard device requests that require a data stage transfer
219 * to the device, the 5-second limit applies.
220 * - 9.2.6.5 : Unless specifically exempted in the class document, all
221 * class-specific requests must meet the timing limitations for
222 * standard device requests.
223 *
224 * Conclusion:
225 * 1. Whole request with data: 5 seconds
226 * 2. Whole request without data: 50 ms
227 * 3. Data packets: 500 ms
228 */
229struct usb_h_ctrl_xfer {
230 /** Pointer to transfer data */
231 uint8_t *data;
232 /** Pointer to setup packet */
233 uint8_t *setup;
234 /** Expected transfer size */
235 uint16_t size;
236 /** Transfer count */
237 uint16_t count;
238 /** Timeout for request, -1 if disable timeout */
239 int16_t req_timeout;
240 /** Timeout between packets
241 * (500ms for data and 50ms for status), -1 if disabled */
242 int16_t pkt_timeout;
243 /** Packet size during transfer (<= allocate max packet size) */
244 uint16_t pkt_size;
245
246 /** Transfer state */
247 uint8_t state;
248 /** Last transfer status */
249 int8_t status;
250};
251
252/**
253 * @brief Transfer descriptor for bulk / interrupt / iso transfer
254 */
255struct usb_h_bulk_int_iso_xfer {
256 /** Expected transfer size */
257 uint32_t size;
258 /** Transfer count */
259 uint32_t count;
260 /** Pointer to transfer data */
261 uint8_t *data;
262 /** Reserved */
263 uint16_t reserved[3];
264
265 /** Transfer state */
266 uint8_t state;
267 /** Last transfer status */
268 int8_t status;
269};
270
271/**
272 * @brief Transfer descriptor for periodic high bandwidth transfer
273 */
274struct usb_h_high_bw_xfer {
275 /** Expected transfer size */
276 uint32_t size;
277 /** Transfer count */
278 uint32_t count;
279 /** Pointer to transfer data */
280 uint8_t *data;
281 /** Micro frame packet sizes */
282 uint16_t pkt_size[3];
283
284 /** Transfer state */
285 uint8_t state;
286 /** Last transfer status */
287 int8_t status;
288};
289
290/**
291 * @brief General transfer descriptor
292 */
293struct usb_h_xfer {
294 /** Reserved for different transfer */
295 union {
296 uint16_t u16[9];
297 uint8_t u8[18];
298 } reserved;
299 /** Transfer state */
300 uint8_t state;
301 /** Last transfer status */
302 int8_t status;
303};
304
305/**
306 * @brief USB Host Controller Driver Pipe structure
307 */
308struct usb_h_pipe {
309 /** Pointer to the USB Host Controller Driver */
310 struct usb_h_desc *hcd;
311 /** Pointer to the callback for transfer done */
312 usb_h_pipe_cb_xfer_t done;
313#if CONF_USB_H_INST_OWNER_SP
314 /** Pointer to the pipe owner */
315 void *owner;
316#endif
317
318 /** Endpoint max packet size (bits 10..0) */
319 uint16_t max_pkt_size;
320 /** Device address */
321 uint8_t dev;
322 /** Endpoint address */
323 uint8_t ep;
324
325 /** Endpoint interval */
326 uint8_t interval;
327 /** Endpoint type: Control, Isochronous, Bulk or Interrupt */
328 uint8_t type;
329 /** Current toggle (driver dependent) */
330 uint8_t toggle;
331 /** Endpoint number of banks (HW dependent) */
332 uint8_t bank : 2;
333 /** Transfer speed (HW dependent) */
334 uint8_t speed : 2;
335 /** High bandwidth periodic out */
336 uint8_t high_bw_out : 1;
337 /** Uses DMA (on transfer) */
338 uint8_t dma : 1;
339 /** Transfer ZLP support */
340 uint8_t zlp : 1;
341 /** Transfer periodic */
342 uint8_t periodic_start : 1;
343
344 /** Transfer status */
345 union {
346 /** General transfer info */
347 struct usb_h_xfer general;
348 /** Control transfer status */
349 struct usb_h_ctrl_xfer ctrl;
350 /** Bulk interrupt iso transfer status */
351 struct usb_h_bulk_int_iso_xfer bii;
352 /** Periodic high bandwidth transfer status */
353 struct usb_h_high_bw_xfer hbw;
354 } x;
355};
356
357/**
358 * @brief USB HCD Initialization
359 *
360 * @param drv Pointer to the HCD driver instance
361 * @param[in] hw Pointer to hardware base
362 * @param[in] prvt The private driver data (implement specific)
363 *
364 * @return Operation result status
365 * @retval ERR_DENIED Hardware has been enabled
366 * @retval ERR_NONE Operation done successfully
367 */
368int32_t _usb_h_init(struct usb_h_desc *drv, void *hw, void *prvt);
369
370/**
371 * @brief USB HCD de-initialization
372 *
373 * @param drv The driver
374 */
375void _usb_h_deinit(struct usb_h_desc *drv);
376
377/**
378 * @brief USB HCD enable
379 *
380 * @param drv The driver
381 */
382void _usb_h_enable(struct usb_h_desc *drv);
383
384/**
385 * @brief USB HCD disable
386 *
387 * @param drv The driver
388 */
389void _usb_h_disable(struct usb_h_desc *drv);
390
391/**
392 * @brief Register callbacks for USB HCD
393 *
394 * @param drv The driver
395 * @param[in] type The callback type
396 * @param[in] cb The callback function entry
397 *
398 * @return Operation result status
399 * @retval ERR_INVALID_ARG Argument error
400 * @retval ERR_NONE Operation done successfully
401 */
402int32_t _usb_h_register_callback(struct usb_h_desc *drv, enum usb_h_cb_type type, FUNC_PTR cb);
403
404/**
405 * @brief Return current frame number
406 *
407 * @param drv The driver
408 *
409 * @return current frame number
410 */
411uint16_t _usb_h_get_frame_n(struct usb_h_desc *drv);
412
413/**
414 * @brief Return current micro frame number
415 *
416 * @param drv The driver
417 *
418 * @return current micro frame number
419 */
420uint8_t _usb_h_get_microframe_n(struct usb_h_desc *drv);
421
422/**
423 * @brief Suspend the USB bus
424 *
425 * @param drv The driver
426 */
427void _usb_h_suspend(struct usb_h_desc *drv);
428
429/**
430 * @brief Resume the USB bus
431 *
432 * @param drv The driver
433 */
434void _usb_h_resume(struct usb_h_desc *drv);
435
436/* Root hub related APIs */
437
438/**
439 * \brief Reset the root hub port
440 *
441 * \param[in,out] drv Pointer to the USB HCD driver
442 * \param[in] port Root hub port, ignored if there is only one port
443 */
444void _usb_h_rh_reset(struct usb_h_desc *drv, uint8_t port);
445
446/**
447 * \brief Suspend the root hub port
448 *
449 * \param[in,out] drv Pointer to the USB HCD driver
450 * \param[in] port Root hub port, ignored if there is only one port
451 */
452void _usb_h_rh_suspend(struct usb_h_desc *drv, uint8_t port);
453
454/**
455 * \brief Resume the root hub port
456 *
457 * \param[in,out] drv Pointer to the USB HCD driver
458 * \param[in] port Root hub port, ignored if there is only one port
459 */
460void _usb_h_rh_resume(struct usb_h_desc *drv, uint8_t port);
461
462/**
463 * \brief Root hub or port feature status check
464 *
465 * Check USB Spec. for hub status and feature selectors.
466 *
467 * \param[in] drv Pointer to the USB HCD driver
468 * \param[in] port Set to 0 to get hub status, otherwise to get port status
469 * \param[in] ftr Hub feature/status selector
470 * (0: connection, 2: suspend, 4: reset, 9: LS, 10: HS)
471 *
472 * \return \c true if the status bit is 1
473 */
474bool _usb_h_rh_check_status(struct usb_h_desc *drv, uint8_t port, uint8_t ftr);
475
476/* Pipe transfer functions */
477
478/**
479 * @brief Allocate a pipe for USB host communication
480 *
481 * @param drv The USB HCD driver
482 * @param[in] dev The device address
483 * @param[in] ep The endpoint address
484 * @param[in] max_pkt_size The endpoint maximum packet size
485 * @param[in] attr The endpoint attribute
486 * @param[in] interval The endpoint interval
487 * (bInterval of USB Endpoint Descriptor)
488 * @param[in] speed The transfer speed of the endpoint
489 * @param[in] minimum_rsc Minimum the resource usage, \sa usb_h_rsc_strategy
490 *
491 * @return Pointer to allocated pipe structure instance
492 * @retval NULL allocation fail
493 */
494struct usb_h_pipe *_usb_h_pipe_allocate(struct usb_h_desc *drv, uint8_t dev, uint8_t ep, uint16_t max_pkt_size,
495 uint8_t attr, uint8_t interval, uint8_t speed, bool minimum_rsc);
496
497/**
498 * @brief Free an allocated pipe
499 *
500 * @param pipe The pipe
501 *
502 * @return Operation result status
503 * @retval ERR_BUSY Pipe is busy, use \ref _usb_h_pipe_abort to abort
504 * @retval ERR_NONE Operation done successfully
505 */
506int32_t _usb_h_pipe_free(struct usb_h_pipe *pipe);
507
508/**
509 * @brief Modify parameters of an allocated control pipe
510 *
511 * @param pipe The pipe
512 * @param[in] dev The device address
513 * @param[in] ep The endpoint address
514 * @param[in] max_pkt_size The maximum packet size, must be equal or
515 * less than allocated size
516 * @param[in] speed The working speed
517 *
518 * @return Operation result status
519 * @retval ERR_NOT_INITIALIZED Pipe is not allocated
520 * @retval ERR_BUSY Pipe is busy transferring
521 * @retval ERR_INVALID_ARG Argument error
522 * @retval ERR_UNSUPPORTED_OP Pipe is not control pipe
523 * @retval ERR_NONE Operation done successfully
524 */
525int32_t _usb_h_pipe_set_control_param(struct usb_h_pipe *pipe, uint8_t dev, uint8_t ep, uint16_t max_pkt_size,
526 uint8_t speed);
527
528/**
529 * @brief Register transfer callback on a pipe
530 *
531 * @param pipe The pipe
532 * @param[in] cb Transfer callback function
533 *
534 * @return Operation result status
535 * @retval ERR_INVALID_ARG Argument error
536 * @retval ERR_NONE Operation done successfully
537 */
538int32_t _usb_h_pipe_register_callback(struct usb_h_pipe *pipe, usb_h_pipe_cb_xfer_t cb);
539
540/**
541 * @brief Issue a control transfer (request) on a pipe
542 *
543 * \note When there is data stage, timeout between data packets is 500ms, the
544 * timeout between last data packet and the status packet is 50ms.
545 *
546 * @param pipe The pipe
547 * @param[in] setup Pointer to the setup packet
548 * @param[in,out] data Pointer to the data buffer
549 * @param[in] length The data length
550 * @param[in] timeout Timeout for whole request in ms
551 *
552 * @return Operation result status
553 * @retval ERR_NOT_INITIALIZED Pipe is not allocated
554 * @retval ERR_BUSY Pipe is busy transferring
555 * @retval ERR_INVALID_ARG Argument error
556 * @retval ERR_UNSUPPORTED_OP Pipe is not control pipe
557 * @retval ERR_NONE Operation done successfully
558 */
559int32_t _usb_h_control_xfer(struct usb_h_pipe *pipe, uint8_t *setup, uint8_t *data, uint16_t length, int16_t timeout);
560
561/**
562 * @brief Issue a bulk / interrupt / iso transfer on a pipe
563 *
564 * @param pipe The pipe
565 * @param[in,out] data Pointer to the data buffer
566 * @param[in] length The data length
567 * @param[in] auto_zlp Auto append ZLP for OUT
568 *
569 * @return Operation result status
570 * @retval ERR_NOT_INITIALIZED Pipe is not allocated
571 * @retval ERR_BUSY Pipe is busy transferring
572 * @retval ERR_INVALID_ARG Argument error
573 * @retval ERR_UNSUPPORTED_OP Pipe is control pipe
574 * @retval ERR_NONE Operation done successfully
575 */
576int32_t _usb_h_bulk_int_iso_xfer(struct usb_h_pipe *pipe, uint8_t *data, uint32_t length, bool auto_zlp);
577
578/**
579 * @brief Issue a periodic high bandwidth output on a pipe
580 *
581 * @param pipe The pipe
582 * @param[in,out] data Pointer to the data buffer
583 * @param[in] length The data length
584 * @param[in] trans_pkt_size The transaction packet sizes in a micro frame,
585 * 0 to use endpoint max packet size
586 *
587 * @return Operation result status
588 * @retval ERR_NOT_INITIALIZED Pipe is not allocated
589 * @retval ERR_BUSY Pipe is busy transferring
590 * @retval ERR_INVALID_ARG Argument error
591 * @retval ERR_UNSUPPORTED_OP Pipe is not high bandwidth periodic pipe, or
592 * DMA feature not enabled, or
593 * high bandwidth not enabled
594 * @retval ERR_NONE Operation done successfully
595 */
596int32_t _usb_h_high_bw_out(struct usb_h_pipe *pipe, uint8_t *data, uint32_t length, uint16_t trans_pkt_size[3]);
597
598/**
599 * @brief Check if pipe is busy transferring
600 *
601 * @param pipe The pipe
602 *
603 * @return \c true if pipe is busy
604 */
605bool _usb_h_pipe_is_busy(struct usb_h_pipe *pipe);
606
607/**
608 * @brief Abort pending transfer on a pipe
609 *
610 * @param pipe The pipe
611 */
612void _usb_h_pipe_abort(struct usb_h_pipe *pipe);
613
614#ifdef __cplusplus
615}
616#endif
617
618#endif /* _HPL_USB_HOST_H_INCLUDED */