2 **************************************************************************
4 * @brief usb host interrupt request
5 **************************************************************************
6 * Copyright notice & Disclaimer
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.
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.
22 **************************************************************************
30 /** @addtogroup AT32F435_437_middlewares_usbh_drivers
34 /** @defgroup USBH_drivers_interrupt
35 * @brief usb host interrupt
39 /** @defgroup USBH_int_private_functions
44 * @brief usb host interrupt handler
45 * @param otgdev: to the structure of otg_core_type
48 void usbh_irq_handler(otg_core_type
*otgdev
)
50 otg_global_type
*usbx
= otgdev
->usb_reg
;
51 usbh_core_type
*uhost
= &otgdev
->host
;
52 uint32_t intsts
= usb_global_get_all_interrupt(usbx
);
54 if(usbx
->gintsts_bit
.curmode
== 1)
56 if(intsts
& USB_OTG_HCH_FLAG
)
58 usbh_hch_handler(uhost
);
59 usb_global_clear_interrupt(usbx
, USB_OTG_HCH_FLAG
);
61 if(intsts
& USB_OTG_SOF_FLAG
)
63 usbh_sof_handler(uhost
);
64 usb_global_clear_interrupt(usbx
, USB_OTG_SOF_FLAG
);
66 if(intsts
& USB_OTG_MODEMIS_FLAG
)
68 usb_global_clear_interrupt(usbx
, USB_OTG_MODEMIS_FLAG
);
70 if(intsts
& USB_OTG_WKUP_FLAG
)
72 usbh_wakeup_handler(uhost
);
73 usb_global_clear_interrupt(usbx
, USB_OTG_WKUP_FLAG
);
75 while(usbx
->gintsts
& USB_OTG_RXFLVL_FLAG
)
77 usbh_rx_qlvl_handler(uhost
);
78 usb_global_clear_interrupt(usbx
, USB_OTG_RXFLVL_FLAG
);
80 if(intsts
& USB_OTG_DISCON_FLAG
)
82 usbh_disconnect_handler(uhost
);
83 usb_global_clear_interrupt(usbx
, USB_OTG_DISCON_FLAG
);
85 if(intsts
& USB_OTG_PRT_FLAG
)
87 usbh_port_handler(uhost
);
89 if(intsts
& USB_OTG_INCOMPIP_INCOMPISOOUT_FLAG
)
91 usb_global_clear_interrupt(usbx
, USB_OTG_INCOMPIP_INCOMPISOOUT_FLAG
);
93 if(intsts
& USB_OTG_INCOMISOIN_FLAG
)
95 usb_global_clear_interrupt(usbx
, USB_OTG_INCOMISOIN_FLAG
);
97 if(intsts
& USB_OTG_PTXFEMP_FLAG
)
99 usb_global_clear_interrupt(usbx
, USB_OTG_PTXFEMP_FLAG
);
101 if(intsts
& USB_OTG_ISOOUTDROP_FLAG
)
103 usb_global_clear_interrupt(usbx
, USB_OTG_INCOMISOIN_FLAG
);
110 * @brief usb host wakeup handler
111 * @param uhost: to the structure of usbh_core_type
114 void usbh_wakeup_handler(usbh_core_type
*uhost
)
116 uhost
->global_state
= USBH_WAKEUP
;
120 * @brief usb host sof handler
121 * @param uhost: to the structure of usbh_core_type
124 void usbh_sof_handler(usbh_core_type
*uhost
)
130 * @brief usb host disconnect handler
131 * @param uhost: to the structure of usbh_core_type
134 void usbh_disconnect_handler(usbh_core_type
*uhost
)
136 otg_global_type
*usbx
= uhost
->usb_reg
;
140 usb_host_disable(usbx
);
144 uhost
->global_state
= USBH_DISCONNECT
;
146 for(i_index
= 0; i_index
< USB_HOST_CHANNEL_NUM
; i_index
++)
148 usbh_free_channel(uhost
, i_index
);
150 usbh_fsls_clksel(usbx
, USB_HCFG_CLK_48M
);
154 * @brief usb host in transfer request handler
155 * @param uhost: to the structure of usbh_core_type
156 * @param chn: channel number
159 void usbh_hch_in_handler(usbh_core_type
*uhost
, uint8_t chn
)
161 otg_global_type
*usbx
= uhost
->usb_reg
;
162 otg_hchannel_type
*usb_chh
= USB_CHL(usbx
, chn
);
163 uint32_t hcint_value
= usb_chh
->hcint
& usb_chh
->hcintmsk
;
165 if( hcint_value
& USB_OTG_HC_ACK_FLAG
)
167 usb_chh
->hcint
= USB_OTG_HC_ACK_FLAG
;
169 else if(hcint_value
& USB_OTG_HC_STALL_FLAG
)
171 usb_chh
->hcintmsk_bit
.chhltdmsk
= TRUE
;
172 usb_chh
->hcint
= USB_OTG_HC_NAK_FLAG
| USB_OTG_HC_STALL_FLAG
;
173 uhost
->hch
[chn
].state
= HCH_STALL
;
174 usb_hch_halt(usbx
, chn
);
176 else if(hcint_value
& USB_OTG_HC_DTGLERR_FLAG
)
178 usb_chh
->hcintmsk_bit
.chhltdmsk
= TRUE
;
179 usb_hch_halt(usbx
, chn
);
180 usb_chh
->hcint
= USB_OTG_HC_DTGLERR_FLAG
| USB_OTG_HC_NAK_FLAG
;
181 uhost
->hch
[chn
].state
= HCH_DATATGLERR
;
184 else if(hcint_value
& USB_OTG_HC_FRMOVRRUN_FLAG
)
186 usb_chh
->hcintmsk_bit
.chhltdmsk
= TRUE
;
187 usb_hch_halt(usbx
, chn
);
188 usb_chh
->hcint
= USB_OTG_HC_FRMOVRRUN_FLAG
;
190 else if(hcint_value
& USB_OTG_HC_XFERC_FLAG
)
192 uhost
->hch
[chn
].state
= HCH_XFRC
;
193 usb_chh
->hcint
= USB_OTG_HC_XFERC_FLAG
;
195 if(usb_chh
->hcchar_bit
.eptype
== EPT_BULK_TYPE
|| usb_chh
->hcchar_bit
.eptype
== EPT_CONTROL_TYPE
)
197 usb_chh
->hcintmsk_bit
.chhltdmsk
= TRUE
;
198 usb_hch_halt(usbx
, chn
);
199 usb_chh
->hcint
= USB_OTG_HC_NAK_FLAG
;
201 else if(usb_chh
->hcchar_bit
.eptype
== EPT_INT_TYPE
)
203 usb_chh
->hcchar_bit
.oddfrm
= TRUE
;
204 uhost
->urb_state
[chn
] = URB_DONE
;
206 else if(usb_chh
->hcchar_bit
.eptype
== EPT_ISO_TYPE
)
208 uhost
->urb_state
[chn
] = URB_DONE
;
210 uhost
->hch
[chn
].toggle_in
^= 1;
212 else if(hcint_value
& USB_OTG_HC_CHHLTD_FLAG
)
214 usb_chh
->hcintmsk_bit
.chhltdmsk
= FALSE
;
215 if(uhost
->hch
[chn
].state
== HCH_XFRC
)
217 uhost
->urb_state
[chn
] = URB_DONE
;
219 else if(uhost
->hch
[chn
].state
== HCH_STALL
)
221 uhost
->urb_state
[chn
] = URB_STALL
;
223 else if(uhost
->hch
[chn
].state
== HCH_XACTERR
||
224 uhost
->hch
[chn
].state
== HCH_DATATGLERR
)
226 uhost
->err_cnt
[chn
] ++;
227 if(uhost
->err_cnt
[chn
] > 3)
229 uhost
->urb_state
[chn
] = URB_ERROR
;
230 uhost
->err_cnt
[chn
] = 0;
234 uhost
->urb_state
[chn
] = URB_NOTREADY
;
236 usb_chh
->hcchar_bit
.chdis
= FALSE
;
237 usb_chh
->hcchar_bit
.chena
= TRUE
;
239 else if(uhost
->hch
[chn
].state
== HCH_NAK
)
241 usb_chh
->hcchar_bit
.chdis
= FALSE
;
242 usb_chh
->hcchar_bit
.chena
= TRUE
;
243 uhost
->urb_state
[chn
] = URB_NOTREADY
;
245 usb_chh
->hcint
= USB_OTG_HC_CHHLTD_FLAG
;
247 else if(hcint_value
& USB_OTG_HC_XACTERR_FLAG
)
249 usb_chh
->hcintmsk_bit
.chhltdmsk
= TRUE
;
250 uhost
->hch
[chn
].state
= HCH_XACTERR
;
251 usb_hch_halt(usbx
, chn
);
252 uhost
->err_cnt
[chn
] ++;
253 usb_chh
->hcint
= USB_OTG_HC_XACTERR_FLAG
;
255 else if(hcint_value
& USB_OTG_HC_NAK_FLAG
)
257 if(usb_chh
->hcchar_bit
.eptype
== EPT_INT_TYPE
)
259 uhost
->err_cnt
[chn
] = 0;
260 usb_chh
->hcintmsk_bit
.chhltdmsk
= TRUE
;
261 usb_hch_halt(usbx
, chn
);
263 else if(usb_chh
->hcchar_bit
.eptype
== EPT_BULK_TYPE
||
264 usb_chh
->hcchar_bit
.eptype
== EPT_CONTROL_TYPE
)
266 uhost
->err_cnt
[chn
] = 0;
267 usb_chh
->hcintmsk_bit
.chhltdmsk
= TRUE
;
268 usb_hch_halt(usbx
, chn
);
270 uhost
->hch
[chn
].state
= HCH_NAK
;
271 usb_chh
->hcint
= USB_OTG_HC_NAK_FLAG
;
273 else if(hcint_value
& USB_OTG_HC_BBLERR_FLAG
)
275 usb_chh
->hcint
= USB_OTG_HC_BBLERR_FLAG
;
280 * @brief usb host out transfer request handler
281 * @param uhost: to the structure of usbh_core_type
282 * @param chn: channel number
285 void usbh_hch_out_handler(usbh_core_type
*uhost
, uint8_t chn
)
287 otg_global_type
*usbx
= uhost
->usb_reg
;
288 otg_hchannel_type
*usb_chh
= USB_CHL(usbx
, chn
);
289 uint32_t hcint_value
= usb_chh
->hcint
& usb_chh
->hcintmsk
;
291 if( hcint_value
& USB_OTG_HC_ACK_FLAG
)
293 usb_chh
->hcint
= USB_OTG_HC_ACK_FLAG
;
295 else if( hcint_value
& USB_OTG_HC_FRMOVRRUN_FLAG
)
297 usb_chh
->hcintmsk_bit
.chhltdmsk
= TRUE
;
298 usb_hch_halt(usbx
, chn
);
299 usb_chh
->hcint
= USB_OTG_HC_FRMOVRRUN_FLAG
;
301 else if( hcint_value
& USB_OTG_HC_XFERC_FLAG
)
303 usb_chh
->hcintmsk_bit
.chhltdmsk
= TRUE
;
304 usb_hch_halt(usbx
, chn
);
305 uhost
->hch
[chn
].state
= HCH_XFRC
;
306 usb_chh
->hcint
= USB_OTG_HC_XFERC_FLAG
;
308 else if( hcint_value
& USB_OTG_HC_STALL_FLAG
)
310 usb_chh
->hcintmsk_bit
.chhltdmsk
= TRUE
;
311 usb_chh
->hcint
= USB_OTG_HC_STALL_FLAG
;
312 uhost
->hch
[chn
].state
= HCH_STALL
;
313 usb_hch_halt(usbx
, chn
);
315 else if( hcint_value
& USB_OTG_HC_DTGLERR_FLAG
)
317 usb_chh
->hcintmsk_bit
.chhltdmsk
= TRUE
;
318 usb_hch_halt(usbx
, chn
);
319 usb_chh
->hcint
= USB_OTG_HC_DTGLERR_FLAG
| USB_OTG_HC_NAK_FLAG
;
320 uhost
->hch
[chn
].state
= HCH_DATATGLERR
;
322 else if( hcint_value
& USB_OTG_HC_CHHLTD_FLAG
)
324 usb_chh
->hcintmsk_bit
.chhltdmsk
= FALSE
;
325 if(uhost
->hch
[chn
].state
== HCH_XFRC
)
327 uhost
->urb_state
[chn
] = URB_DONE
;
328 if(uhost
->hch
[chn
].ept_type
== EPT_BULK_TYPE
||
329 uhost
->hch
[chn
].ept_type
== EPT_INT_TYPE
)
331 uhost
->hch
[chn
].toggle_out
^= 1;
334 else if(uhost
->hch
[chn
].state
== HCH_NAK
)
336 uhost
->urb_state
[chn
] = URB_NOTREADY
;
338 else if(uhost
->hch
[chn
].state
== HCH_STALL
)
340 uhost
->hch
[chn
].urb_sts
= URB_STALL
;
342 else if(uhost
->hch
[chn
].state
== HCH_XACTERR
||
343 uhost
->hch
[chn
].state
== HCH_DATATGLERR
)
345 uhost
->err_cnt
[chn
] ++;
346 if(uhost
->err_cnt
[chn
] > 3)
348 uhost
->urb_state
[chn
] = URB_ERROR
;
349 uhost
->err_cnt
[chn
] = 0;
353 uhost
->urb_state
[chn
] = URB_NOTREADY
;
356 usb_chh
->hcchar_bit
.chdis
= FALSE
;
357 usb_chh
->hcchar_bit
.chena
= TRUE
;
359 usb_chh
->hcint
= USB_OTG_HC_CHHLTD_FLAG
;
361 else if( hcint_value
& USB_OTG_HC_XACTERR_FLAG
)
363 usb_chh
->hcintmsk_bit
.chhltdmsk
= TRUE
;
364 uhost
->err_cnt
[chn
] ++;
365 uhost
->hch
[chn
].state
= HCH_XACTERR
;
366 usb_hch_halt(usbx
, chn
);
367 usb_chh
->hcint
= USB_OTG_HC_XACTERR_FLAG
| USB_OTG_HC_NAK_FLAG
;
369 else if( hcint_value
& USB_OTG_HC_NAK_FLAG
)
371 usb_chh
->hcintmsk_bit
.chhltdmsk
= TRUE
;
372 uhost
->err_cnt
[chn
] = 0;
373 usb_hch_halt(usbx
, chn
);
374 uhost
->hch
[chn
].state
= HCH_NAK
;
375 usb_chh
->hcint
= USB_OTG_HC_NAK_FLAG
;
380 * @brief usb host channel request handler
381 * @param uhost: to the structure of usbh_core_type
384 void usbh_hch_handler(usbh_core_type
*uhost
)
386 otg_global_type
*usbx
= uhost
->usb_reg
;
387 otg_host_type
*usb_host
= OTG_HOST(usbx
);
388 uint32_t intsts
, i_index
;
390 intsts
= usb_host
->haint
& 0xFFFF;
391 for(i_index
= 0; i_index
< 16; i_index
++)
393 if(intsts
& (1 << i_index
))
395 if(USB_CHL(usbx
, i_index
)->hcchar_bit
.eptdir
)
398 usbh_hch_in_handler(uhost
, i_index
);
403 usbh_hch_out_handler(uhost
, i_index
);
410 * @brief usb host rx buffer not empty request handler
411 * @param uhost: to the structure of usbh_core_type
414 void usbh_rx_qlvl_handler(usbh_core_type
*uhost
)
420 otg_hchannel_type
*ch
;
421 otg_global_type
*usbx
= uhost
->usb_reg
;
423 usbx
->gintmsk_bit
.rxflvlmsk
= 0;
427 pktsts
= (tmp
>> 17) & 0xF;
428 pktcnt
= (tmp
>> 4) & 0x7FF;
429 ch
= USB_CHL(usbx
, chn
);
432 case PKTSTS_IN_DATA_PACKET_RECV
:
433 if(pktcnt
> 0 && (uhost
->hch
[chn
].trans_buf
) != 0)
435 usb_read_packet(usbx
, uhost
->hch
[chn
].trans_buf
, chn
, pktcnt
);
436 uhost
->hch
[chn
].trans_buf
+= pktcnt
;
437 uhost
->hch
[chn
].trans_count
+= pktcnt
;
439 if(ch
->hctsiz_bit
.pktcnt
> 0)
441 ch
->hcchar_bit
.chdis
= FALSE
;
442 ch
->hcchar_bit
.chena
= TRUE
;
443 uhost
->hch
[chn
].toggle_in
^= 1;
447 case PKTSTS_IN_TRANSFER_COMPLETE
:
449 case PKTSTS_DATA_BIT_ERROR
:
451 case PKTSTS_CHANNEL_STOP
:
457 usbx
->gintmsk_bit
.rxflvlmsk
= 1;
461 * @brief usb host port request handler
462 * @param uhost: to the structure of usbh_core_type
465 void usbh_port_handler(usbh_core_type
*uhost
)
467 otg_global_type
*usbx
= uhost
->usb_reg
;
468 otg_host_type
*usb_host
= OTG_HOST(usbx
);
470 uint32_t prt
= 0, prt_0
;
472 prt
= usb_host
->hprt
;
475 prt_0
&= ~(USB_OTG_HPRT_PRTENA
| USB_OTG_HPRT_PRTENCHNG
|
476 USB_OTG_HPRT_PRTOVRCACT
| USB_OTG_HPRT_PRTCONDET
);
477 if(prt
& USB_OTG_HPRT_PRTCONDET
)
479 if(prt
& USB_OTG_HPRT_PRTCONSTS
)
481 /* connect callback */
484 prt_0
|= USB_OTG_HPRT_PRTCONDET
;
487 if(prt
& USB_OTG_HPRT_PRTENCHNG
)
489 prt_0
|= USB_OTG_HPRT_PRTENCHNG
;
491 if(prt
& USB_OTG_HPRT_PRTENA
)
493 if((prt
& USB_OTG_HPRT_PRTSPD
) == (USB_PRTSPD_LOW_SPEED
<< 17))
495 usbh_fsls_clksel(usbx
, USB_HCFG_CLK_6M
);
499 usbh_fsls_clksel(usbx
, USB_HCFG_CLK_48M
);
501 /* connect callback */
502 uhost
->port_enable
= 1;
507 uhost
->port_enable
= 0;
511 if(prt
& USB_OTG_HPRT_PRTOVRCACT
)
513 prt_0
|= USB_OTG_HPRT_PRTOVRCACT
;
516 usb_host
->hprt
= prt_0
;