• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 HPMicro
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  *
6  */
7 
8 #ifndef HPM_USB_DEVICE_H
9 #define HPM_USB_DEVICE_H
10 
11 /*---------------------------------------------------------------------
12  * Includes
13  *---------------------------------------------------------------------
14  */
15 #include "hpm_usb_drv.h"
16 #include "hpm_soc_feature.h"
17 /*---------------------------------------------------------------------
18  *  Macro Constant Declarations
19  *---------------------------------------------------------------------
20  */
21 
22 /*---------------------------------------------------------------------
23  * Macro Typedef Declaration
24  *---------------------------------------------------------------------
25  */
26 
27 /* Queue Transfer Descriptor */
28 typedef struct {
29     /* Word 0: Next QTD Pointer */
30     volatile uint32_t next; /* Next link pointer This field contains the physical memory address of the next dTD to be processed */
31 
32     /* Word 1: qTQ Token */
33     volatile uint32_t                      : 3;
34     volatile uint32_t xact_err             : 1;
35     volatile uint32_t                      : 1;
36     volatile uint32_t buffer_err           : 1;
37     volatile uint32_t halted               : 1;
38     volatile uint32_t active               : 1;
39     volatile uint32_t                      : 2;
40     volatile uint32_t iso_mult_override    : 2  ; /* This field can be used for transmit ISOs to override the MULT field in the dQH. This field must be zero for all packet types that are not transmit-ISO. */
41     volatile uint32_t                      : 3;
42     volatile uint32_t int_on_complete      : 1;
43     volatile uint32_t total_bytes          : 15;
44     volatile uint32_t                      : 0;
45 
46     /* Word 2-6: Buffer Page Pointer List, Each element in the list is a 4K page aligned, physical memory address. The lower 12 bits in each pointer are reserved (except for the first one) as each memory pointer must reference the start of a 4K page */
47     volatile uint32_t buffer[USB_SOC_DCD_QHD_BUFFER_COUNT];
48 
49     /*------------- DCD Area -------------*/
50     volatile uint16_t expected_bytes;
51     volatile uint8_t reserved[2];
52 } dcd_qtd_t;
53 
54 /* Queue Head */
55 typedef struct {
56     /* Word 0: Capabilities and Characteristics */
57 
58     volatile uint32_t                         : 15 ; /* Number of packets executed per transaction descriptor 00 - Execute N transactions as demonstrated by the USB variable length protocol where N is computed using Max_packet_length and the Total_bytes field in the dTD. 01 - Execute one transaction 10 - Execute two transactions 11 - Execute three transactions Remark: Non-isochronous endpoints must set MULT = 00. Remark: Isochronous endpoints must set MULT = 01, 10, or 11 as needed. */
59     volatile uint32_t int_on_setup            : 1  ; /* Interrupt on setup This bit is used on control type endpoints to indicate if USBINT is set in response to a setup being received. */
60     volatile uint32_t max_packet_size         : 11 ; /* This directly corresponds to the maximum packet size of the associated endpoint (wMaxPacketSize) */
61     volatile uint32_t                         : 2;
62     volatile uint32_t zero_length_termination : 1  ; /* This bit is used for non-isochronous endpoints to indicate when a zero-length packet is received to terminate transfers in case the total transfer length is “multiple”. 0 - Enable zero-length packet to terminate transfers equal to a multiple of Max_packet_length (default). 1 - Disable zero-length packet on transfers that are equal in length to a multiple Max_packet_length. */
63     volatile uint32_t iso_mult                : 2;
64     volatile uint32_t                         : 0;
65 
66     /* Word 1: Current qTD Pointer */
67     volatile uint32_t qtd_addr;
68 
69     /* Word 2-9: Transfer Overlay */
70     volatile dcd_qtd_t qtd_overlay;
71 
72     /* Word 10-11: Setup request (control OUT only) */
73     volatile usb_control_request_t setup_request;
74 
75     /*--------------------------------------------------------------------
76      * Due to the fact QHD is 64 bytes aligned but occupies only 48 bytes
77      * thus there are 16 bytes padding free that we can make use of.
78      *--------------------------------------------------------------------
79      */
80     volatile uint8_t reserved[16];
81 } dcd_qhd_t;
82 
83 typedef struct {
84     dcd_qhd_t qhd[USB_SOS_DCD_MAX_QHD_COUNT];
85     dcd_qtd_t qtd[USB_SOC_DCD_MAX_QTD_COUNT];
86 } dcd_data_t;
87 
88 typedef struct {
89     USB_Type     *regs;
90     dcd_data_t   *dcd_data;
91 } usb_device_handle_t;
92 
93 #if defined(__cplusplus)
94 extern "C" {
95 #endif /* __cplusplus */
96 
97 /*---------------------------------------------------------------------
98  *   Exported Function Declarations
99  *---------------------------------------------------------------------
100  */
101 /* Get a qhd of the specifed endpoint */
102 dcd_qhd_t *usb_device_qhd_get(usb_device_handle_t *handle, uint8_t ep_idx);
103 
104 /* Get a qtd of the specifed endpoint */
105 dcd_qtd_t *usb_device_qtd_get(usb_device_handle_t *handle, uint8_t ep_idx);
106 
107 /* USB bus reset */
108 void usb_device_bus_reset(usb_device_handle_t *handle, uint16_t ep0_max_packet_size);
109 
110 /* Initialize controller to device mode */
111 bool usb_device_init(usb_device_handle_t *handle, uint32_t int_mask);
112 
113 /* De-initialize controller */
114 void usb_device_deinit(usb_device_handle_t *handle);
115 
116 /* Set Address request */
117 void usb_device_set_address(usb_device_handle_t *handle, uint8_t dev_addr);
118 
119 /* Get device address */
120 uint8_t usb_device_get_address(usb_device_handle_t *handle);
121 
122 /* Wake up host */
123 void usb_device_remote_wakeup(usb_device_handle_t *handle);
124 
125 /* Connect by enabling internal pull-up resistor on D+/D- */
126 void usb_device_connect(usb_device_handle_t *handle);
127 
128 /* Disconnect by disabling internal pull-up resistor on D+/D- */
129 void usb_device_disconnect(usb_device_handle_t *handle);
130 
131 /* Configure an endpoint */
132 bool usb_device_edpt_open(usb_device_handle_t *handle, usb_endpoint_config_t *config);
133 
134 /* Submit a transfe */
135 bool usb_device_edpt_xfer(usb_device_handle_t *handle, uint8_t ep_addr, uint8_t *buffer, uint32_t total_bytes);
136 
137 /* Stall endpoint */
138 void usb_device_edpt_stall(usb_device_handle_t *handle, uint8_t ep_addr);
139 
140 /* clear stall */
141 void usb_device_edpt_clear_stall(usb_device_handle_t *handle, uint8_t ep_addr);
142 
143 /* check stall */
144 bool usb_device_edpt_check_stall(usb_device_handle_t *handle, uint8_t ep_addr);
145 
146 /* close a specified endpoint */
147 void usb_device_edpt_close(usb_device_handle_t *handle, uint8_t ep_addr);
148 
149 void usb_device_edpt_close_all(usb_device_handle_t *handle);
150 
151 uint32_t usb_device_status_flags(usb_device_handle_t *handle);
152 
153 void usb_device_clear_status_flags(usb_device_handle_t *handle, uint32_t mask);
154 
155 uint32_t usb_device_interrupts(usb_device_handle_t *handle);
156 
157 uint8_t usb_device_get_port_speed(usb_device_handle_t *handle);
158 
159 uint8_t usb_device_get_suspend_status(usb_device_handle_t *handle);
160 
161 bool usb_device_get_port_ccs(usb_device_handle_t *handle);
162 
163 bool usb_device_get_port_reset_status(usb_device_handle_t *handle);
164 
165 uint32_t usb_device_get_edpt_complete_status(usb_device_handle_t *handle);
166 
167 void usb_device_clear_edpt_complete_status(usb_device_handle_t *handle, uint32_t mask);
168 
169 uint32_t usb_device_get_setup_status(usb_device_handle_t *handle);
170 
171 void usb_device_clear_setup_status(usb_device_handle_t *handle, uint32_t mask);
172 
173 #if defined(__cplusplus)
174 }
175 #endif /* __cplusplus */
176 #endif /* HPM_USB_DEVICE_H */
177