1 /**
2 **************************************************************************
3 * @file usbd_int.c
4 * @brief usb interrupt request
5 **************************************************************************
6 * Copyright notice & Disclaimer
7 *
8 * The software Board Support Package (BSP) that is made available to
9 * download from Artery official website is the copyrighted work of Artery.
10 * Artery authorizes customers to use, copy, and distribute the BSP
11 * software and its related documentation for the purpose of design and
12 * development in conjunction with Artery microcontrollers. Use of the
13 * software is governed by this copyright notice and the following disclaimer.
14 *
15 * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
16 * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
17 * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
18 * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
19 * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
21 *
22 **************************************************************************
23 */
24
25 #include "usbd_int.h"
26
27 /** @defgroup USBD_drivers_interrupt
28 * @brief usb device interrupt
29 * @{
30 */
31
32 /** @defgroup USBD_int_private_functions
33 * @{
34 */
35
36 #ifdef BSP_USING_USBD
37
38 /**
39 * @brief usb device interrput request handler.
40 * @param udev: to the structure of usbd_core_type
41 * @retval none
42 */
usbd_irq_handler(usbd_core_type * udev)43 void usbd_irq_handler(usbd_core_type *udev)
44 {
45 usbd_type *usbx = udev->usb_reg;
46 uint32_t sts_val = usbx->intsts;
47 uint32_t sts_ien = usbx->ctrl;
48
49 if(sts_val & USB_TC_FLAG)
50 {
51 /* endpoint tc interrupt handler */
52 usbd_ept_loop_handler(udev);
53 }
54
55 if(sts_val & USB_RST_FLAG)
56 {
57 /* clear reset flag */
58 usb_flag_clear(usbx, USB_RST_FLAG);
59
60 /* reset interrupt handler */
61 usbd_reset_handler(udev);
62 }
63
64 if((sts_val & USB_SOF_FLAG) &&
65 (sts_ien & USB_SOF_INT))
66 {
67 /* clear sof flag */
68 usb_flag_clear(usbx, USB_SOF_FLAG);
69
70 /* sof interrupt handler */
71 usbd_sof_callback(udev);
72 }
73
74 if((sts_val & USB_LSOF_FLAG) &&
75 (sts_ien & USB_LSOF_INT))
76 {
77 /* clear lsof flag */
78 usb_flag_clear(usbx, USB_LSOF_FLAG);
79 }
80
81 if((sts_val & USB_SP_FLAG) &&
82 (sts_ien & USB_SP_INT))
83 {
84 /* clear suspend flag */
85 usb_flag_clear(usbx, USB_SP_FLAG);
86
87 /* usb suspend interrupt handler */
88 usbd_suspend_handler(udev);
89 }
90
91 if((sts_val & USB_WK_FLAG) &&
92 (sts_ien & USB_WK_INT))
93 {
94 /* usb wakeup interrupt handler */
95 usbd_wakeup_handler(udev);
96
97 /* clear wakeup flag */
98 usb_flag_clear(usbx, USB_WK_FLAG);
99 }
100 }
101
102 /**
103 * @brief usb device endpoint request handler.
104 * @param udev: to the structure of usbd_core_type
105 * @param ept_num: endpoint number
106 * @retval none
107 */
usbd_eptn_handler(usbd_core_type * udev,usb_ept_number_type ept_num)108 void usbd_eptn_handler(usbd_core_type *udev, usb_ept_number_type ept_num)
109 {
110 usbd_type *usbx = udev->usb_reg;
111 usb_ept_info *ept_info;
112 uint32_t ept_val = usbx->ept[ept_num];
113 uint16_t length;
114
115 /* in interrupt request */
116 if(ept_val & USB_TXTC)
117 {
118 /* get endpoint register and in transfer info struct */
119 ept_info = &udev->ept_in[ept_num];
120
121 /* clear endpoint tc flag */
122 USB_CLEAR_TXTC(ept_num);
123
124 /* get endpoint tx length */
125 ept_info->trans_len = USB_GET_TX_LEN(ept_num);
126
127 /* offset the trans buffer */
128 ept_info->trans_buf += ept_info->trans_len;
129
130 if(ept_info->total_len == 0 || ept_num == USB_EPT0)
131 {
132 /* in transfer complete */
133 usbd_data_in_stage_callback(udev,ept_num);
134 }
135 else
136 {
137 /* endpoint continue send data */
138 usbd_ept_send(udev, ept_num, ept_info->trans_buf, ept_info->total_len);
139 }
140 /* set the host assignment address */
141 if(udev->conn_state == USB_CONN_STATE_ADDRESSED && udev->device_addr > 0)
142 {
143 usb_set_address(udev->usb_reg, udev->device_addr);
144 udev->device_addr = 0;
145 }
146 }
147 else
148 {
149 /* setup and out interrupt request */
150
151 /* get endpoint register and out transfer info struct */
152 ept_info = &udev->ept_out[ept_num];
153
154 if((ept_val & USB_SETUPTC) != 0)
155 {
156 /* endpoint setup interrupt request */
157
158 /* get endpoint received data length */
159 ept_info->trans_len = USB_GET_RX_LEN(ept_num);
160
161 /* read endpoint received data */
162 usb_read_packet(udev->setup_buffer, ept_info->rx_addr, ept_info->trans_len);
163
164 /* clear endpoint rx tc flag */
165 USB_CLEAR_RXTC(USB_EPT0);
166
167 /* endpoint setup complete handler */
168 usbd_core_setup_handler(udev, ept_num);
169 usbd_setup_phase_done_callback(udev);
170 }
171 else if(ept_val & USB_RXTC )
172 {
173 /* endpoint out interrupt request */
174 USB_CLEAR_RXTC(ept_num);
175
176 if(ept_info->is_double_buffer == 0)
177 {
178 /* get endpoint received data length */
179 length = USB_GET_RX_LEN(ept_num);
180
181 /* read endpoint received data */
182 usb_read_packet(ept_info->trans_buf, ept_info->rx_addr, length);
183 }
184 else
185 {
186 if( ept_val & USB_RXDTS)
187 {
188 length = USB_DBUF0_GET_LEN(ept_num);
189 usb_read_packet(ept_info->trans_buf, ept_info->tx_addr, length);
190 }
191 else
192 {
193 length = USB_DBUF1_GET_LEN(ept_num);
194 usb_read_packet(ept_info->trans_buf, ept_info->rx_addr, length);
195 }
196 USB_FREE_DB_USER_BUFFER(ept_num, DATA_TRANS_OUT);
197 }
198
199 /* set received data length */
200 ept_info->trans_len += length;
201 ept_info->trans_buf += length;
202
203 if(ept_info->total_len == 0 || length < ept_info->maxpacket || ept_num == USB_EPT0)
204 {
205 /* out transfer complete */
206 usbd_data_out_stage_callback(udev, ept_num);
207 }
208 else
209 {
210 /* endpoint continue receive data */
211 usbd_ept_recv(udev, ept_num, ept_info->trans_buf, ept_info->total_len);
212 }
213 }
214 }
215 }
216
217 /**
218 * @brief usb device endpoint loop handler.
219 * @param udev: to the structure of usbd_core_type
220 * @retval none
221 */
usbd_ept_loop_handler(usbd_core_type * udev)222 void usbd_ept_loop_handler(usbd_core_type *udev)
223 {
224 usbd_type *usbx = udev->usb_reg;
225 usb_ept_number_type ept_num = USB_EPT0;
226 uint32_t sts_val;
227
228 while((sts_val = usbx->intsts) & USB_TC_FLAG)
229 {
230 /* get the interrupt endpoint number */
231 ept_num = (usb_ept_number_type)(sts_val & USB_EPT_NUM_FLAG);
232
233 usbd_eptn_handler(udev, ept_num);
234 }
235 }
236
237 /**
238 * @brief usb device reset interrupt request handler.
239 * @param udev: to the structure of usbd_core_type
240 * @retval none
241 */
usbd_reset_handler(usbd_core_type * udev)242 void usbd_reset_handler(usbd_core_type *udev)
243 {
244 /* free usb buffer */
245 usb_buffer_free();
246
247 usbd_ept_defaut_init(udev);
248 #ifndef USB_EPT_AUTO_MALLOC_BUFFER
249 usbd_ept_buf_custom_define(udev, 0x80, EPT0_TX_ADDR);
250 usbd_ept_buf_custom_define(udev, 0x00, EPT0_RX_ADDR);
251 #endif
252
253 /* open endpoint 0 out */
254 usbd_ept_open(udev, 0x00, EPT_CONTROL_TYPE, 0x40);
255
256 /* open endpoint 0 in */
257 usbd_ept_open(udev, 0x80, EPT_CONTROL_TYPE, 0x40);
258
259 /* set device address to 0 */
260 usb_set_address(udev->usb_reg, 0);
261
262 /* usb connect state set to default */
263 udev->conn_state = USB_CONN_STATE_DEFAULT;
264
265 /* user define reset event */
266 usbd_reset_callback(udev);
267 }
268
269 /**
270 * @brief usb device sof interrupt request handler.
271 * @param udev: to the structure of usbd_core_type
272 * @retval none
273 */
usbd_sof_handler(usbd_core_type * udev)274 void usbd_sof_handler(usbd_core_type *udev)
275 {
276 /* user sof handler in class define*/
277 if(udev->class_handler->sof_handler)
278 udev->class_handler->sof_handler(udev);
279 }
280
281 /**
282 * @brief usb device suspend interrupt request handler.
283 * @param udev: to the structure of usbd_core_type
284 * @retval none
285 */
usbd_suspend_handler(usbd_core_type * udev)286 void usbd_suspend_handler(usbd_core_type *udev)
287 {
288 /* save connect state */
289 udev->old_conn_state = udev->conn_state;
290
291 /* set current state to suspend */
292 udev->conn_state = USB_CONN_STATE_SUSPENDED;
293
294 /* enter suspend mode */
295 usbd_enter_suspend(udev);
296 }
297
298 /**
299 * @brief usb device wakup interrupt request handler.
300 * @param udev: to the structure of usbd_core_type
301 * @retval none
302 */
usbd_wakeup_handler(usbd_core_type * udev)303 void usbd_wakeup_handler(usbd_core_type *udev)
304 {
305 /* exit suspend mode */
306 usb_exit_suspend(udev->usb_reg);
307
308 /* restore connect state */
309 udev->conn_state = udev->old_conn_state;
310
311 /* user define wakeup event */
312 }
313
usbd_reset_callback(usbd_core_type * udev)314 rt_weak void usbd_reset_callback(usbd_core_type *udev)
315 {
316 }
317
usbd_setup_phase_done_callback(usbd_core_type * udev)318 rt_weak void usbd_setup_phase_done_callback(usbd_core_type *udev)
319 {
320 }
321
usbd_data_in_stage_callback(usbd_core_type * udev,uint32_t ept_num)322 rt_weak void usbd_data_in_stage_callback(usbd_core_type *udev, uint32_t ept_num)
323 {
324 }
325
usbd_sof_callback(usbd_core_type * udev)326 rt_weak void usbd_sof_callback(usbd_core_type *udev)
327 {
328 }
329
usbd_data_out_stage_callback(usbd_core_type * udev,uint32_t ept_num)330 rt_weak void usbd_data_out_stage_callback(usbd_core_type *udev, uint32_t ept_num)
331 {
332 }
333
usbd_connectCallback(usbd_core_type * udev)334 rt_weak void usbd_connectCallback(usbd_core_type *udev)
335 {
336 }
337
usbd_disconnectCallback(usbd_core_type * udev)338 rt_weak void usbd_disconnectCallback(usbd_core_type *udev)
339 {
340 }
341
342 #endif
343
344 /**
345 * @}
346 */
347
348 /**
349 * @}
350 */
351
352