summaryrefslogtreecommitdiff
path: root/bsp/at32/libraries/usbd_library/src/usbd_int.c
diff options
context:
space:
mode:
Diffstat (limited to 'bsp/at32/libraries/usbd_library/src/usbd_int.c')
-rw-r--r--bsp/at32/libraries/usbd_library/src/usbd_int.c347
1 files changed, 347 insertions, 0 deletions
diff --git a/bsp/at32/libraries/usbd_library/src/usbd_int.c b/bsp/at32/libraries/usbd_library/src/usbd_int.c
new file mode 100644
index 0000000000..4684d576ad
--- /dev/null
+++ b/bsp/at32/libraries/usbd_library/src/usbd_int.c
@@ -0,0 +1,347 @@
+/**
+ **************************************************************************
+ * @file usbd_int.c
+ * @brief usb interrupt request
+ **************************************************************************
+ * Copyright notice & Disclaimer
+ *
+ * The software Board Support Package (BSP) that is made available to
+ * download from Artery official website is the copyrighted work of Artery.
+ * Artery authorizes customers to use, copy, and distribute the BSP
+ * software and its related documentation for the purpose of design and
+ * development in conjunction with Artery microcontrollers. Use of the
+ * software is governed by this copyright notice and the following disclaimer.
+ *
+ * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
+ * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
+ * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
+ * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
+ * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
+ *
+ **************************************************************************
+ */
+
+#include "usbd_int.h"
+
+/** @defgroup USBD_drivers_interrupt
+ * @brief usb device interrupt
+ * @{
+ */
+
+/** @defgroup USBD_int_private_functions
+ * @{
+ */
+
+/**
+ * @brief usb device interrput request handler.
+ * @param udev: to the structure of usbd_core_type
+ * @retval none
+ */
+void usbd_irq_handler(usbd_core_type *udev)
+{
+ usbd_type *usbx = udev->usb_reg;
+ uint32_t sts_val = usbx->intsts;
+ uint32_t sts_ien = usbx->ctrl;
+
+ if(sts_val & USB_TC_FLAG)
+ {
+ /* endpoint tc interrupt handler */
+ usbd_ept_loop_handler(udev);
+ }
+
+ if(sts_val & USB_RST_FLAG)
+ {
+ /* clear reset flag */
+ usb_flag_clear(usbx, USB_RST_FLAG);
+
+ /* reset interrupt handler */
+ usbd_reset_handler(udev);
+ }
+
+ if((sts_val & USB_SOF_FLAG) &&
+ (sts_ien & USB_SOF_INT))
+ {
+ /* clear sof flag */
+ usb_flag_clear(usbx, USB_SOF_FLAG);
+
+ /* sof interrupt handler */
+ usbd_sof_callback(udev);
+ }
+
+ if((sts_val & USB_LSOF_FLAG) &&
+ (sts_ien & USB_LSOF_INT))
+ {
+ /* clear lsof flag */
+ usb_flag_clear(usbx, USB_LSOF_FLAG);
+ }
+
+ if((sts_val & USB_SP_FLAG) &&
+ (sts_ien & USB_SP_INT))
+ {
+ /* clear suspend flag */
+ usb_flag_clear(usbx, USB_SP_FLAG);
+
+ /* usb suspend interrupt handler */
+ usbd_suspend_handler(udev);
+ }
+
+ if((sts_val & USB_WK_FLAG) &&
+ (sts_ien & USB_WK_INT))
+ {
+ /* usb wakeup interrupt handler */
+ usbd_wakeup_handler(udev);
+
+ /* clear wakeup flag */
+ usb_flag_clear(usbx, USB_WK_FLAG);
+ }
+}
+
+/**
+ * @brief usb device endpoint request handler.
+ * @param udev: to the structure of usbd_core_type
+ * @param ept_num: endpoint number
+ * @retval none
+ */
+void usbd_eptn_handler(usbd_core_type *udev, usb_ept_number_type ept_num)
+{
+ usbd_type *usbx = udev->usb_reg;
+ usb_ept_info *ept_info;
+ uint32_t ept_val = usbx->ept[ept_num];
+ uint16_t length;
+
+ /* in interrupt request */
+ if(ept_val & USB_TXTC)
+ {
+ /* get endpoint register and in transfer info struct */
+ ept_info = &udev->ept_in[ept_num];
+
+ /* clear endpoint tc flag */
+ USB_CLEAR_TXTC(ept_num);
+
+ /* get endpoint tx length */
+ ept_info->trans_len = USB_GET_TX_LEN(ept_num);
+
+ /* offset the trans buffer */
+ ept_info->trans_buf += ept_info->trans_len;
+
+ if(ept_info->total_len == 0 || ept_num == USB_EPT0)
+ {
+ /* in transfer complete */
+ usbd_data_in_stage_callback(udev,ept_num);
+ }
+ else
+ {
+ /* endpoint continue send data */
+ usbd_ept_send(udev, ept_num, ept_info->trans_buf, ept_info->total_len);
+ }
+ /* set the host assignment address */
+ if(udev->conn_state == USB_CONN_STATE_ADDRESSED && udev->device_addr > 0)
+ {
+ usb_set_address(udev->usb_reg, udev->device_addr);
+ udev->device_addr = 0;
+ }
+ }
+ else
+ {
+ /* setup and out interrupt request */
+
+ /* get endpoint register and out transfer info struct */
+ ept_info = &udev->ept_out[ept_num];
+
+ if((ept_val & USB_SETUPTC) != 0)
+ {
+ /* endpoint setup interrupt request */
+
+ /* get endpoint received data length */
+ ept_info->trans_len = USB_GET_RX_LEN(ept_num);
+
+ /* read endpoint received data */
+ usb_read_packet(udev->setup_buffer, ept_info->rx_addr, ept_info->trans_len);
+
+ /* clear endpoint rx tc flag */
+ USB_CLEAR_RXTC(USB_EPT0);
+
+ /* endpoint setup complete handler */
+ usbd_core_setup_handler(udev, ept_num);
+ usbd_setup_phase_done_callback(udev);
+ }
+ else if(ept_val & USB_RXTC )
+ {
+ /* endpoint out interrupt request */
+ USB_CLEAR_RXTC(ept_num);
+
+ if(ept_info->is_double_buffer == 0)
+ {
+ /* get endpoint received data length */
+ length = USB_GET_RX_LEN(ept_num);
+
+ /* read endpoint received data */
+ usb_read_packet(ept_info->trans_buf, ept_info->rx_addr, length);
+ }
+ else
+ {
+ if( ept_val & USB_RXDTS)
+ {
+ length = USB_DBUF0_GET_LEN(ept_num);
+ usb_read_packet(ept_info->trans_buf, ept_info->tx_addr, length);
+ }
+ else
+ {
+ length = USB_DBUF1_GET_LEN(ept_num);
+ usb_read_packet(ept_info->trans_buf, ept_info->rx_addr, length);
+ }
+ USB_FREE_DB_USER_BUFFER(ept_num, DATA_TRANS_OUT);
+ }
+
+ /* set received data length */
+ ept_info->trans_len += length;
+ ept_info->trans_buf += length;
+
+ if(ept_info->total_len == 0 || length < ept_info->maxpacket || ept_num == USB_EPT0)
+ {
+ /* out transfer complete */
+ usbd_data_out_stage_callback(udev, ept_num);
+ }
+ else
+ {
+ /* endpoint continue receive data */
+ usbd_ept_recv(udev, ept_num, ept_info->trans_buf, ept_info->total_len);
+ }
+ }
+ }
+}
+
+/**
+ * @brief usb device endpoint loop handler.
+ * @param udev: to the structure of usbd_core_type
+ * @retval none
+ */
+void usbd_ept_loop_handler(usbd_core_type *udev)
+{
+ usbd_type *usbx = udev->usb_reg;
+ usb_ept_number_type ept_num = USB_EPT0;
+ uint32_t sts_val;
+
+ while((sts_val = usbx->intsts) & USB_TC_FLAG)
+ {
+ /* get the interrupt endpoint number */
+ ept_num = (usb_ept_number_type)(sts_val & USB_EPT_NUM_FLAG);
+
+ usbd_eptn_handler(udev, ept_num);
+ }
+}
+
+/**
+ * @brief usb device reset interrupt request handler.
+ * @param udev: to the structure of usbd_core_type
+ * @retval none
+ */
+void usbd_reset_handler(usbd_core_type *udev)
+{
+ /* free usb buffer */
+ usb_buffer_free();
+
+ usbd_ept_defaut_init(udev);
+#ifndef USB_EPT_AUTO_MALLOC_BUFFER
+ usbd_ept_buf_custom_define(udev, 0x80, EPT0_TX_ADDR);
+ usbd_ept_buf_custom_define(udev, 0x00, EPT0_RX_ADDR);
+#endif
+
+ /* open endpoint 0 out */
+ usbd_ept_open(udev, 0x00, EPT_CONTROL_TYPE, 0x40);
+
+ /* open endpoint 0 in */
+ usbd_ept_open(udev, 0x80, EPT_CONTROL_TYPE, 0x40);
+
+ /* set device address to 0 */
+ usb_set_address(udev->usb_reg, 0);
+
+ /* usb connect state set to default */
+ udev->conn_state = USB_CONN_STATE_DEFAULT;
+
+ /* user define reset event */
+ usbd_reset_callback(udev);
+}
+
+/**
+ * @brief usb device sof interrupt request handler.
+ * @param udev: to the structure of usbd_core_type
+ * @retval none
+ */
+void usbd_sof_handler(usbd_core_type *udev)
+{
+ /* user sof handler in class define*/
+ if(udev->class_handler->sof_handler)
+ udev->class_handler->sof_handler(udev);
+}
+
+/**
+ * @brief usb device suspend interrupt request handler.
+ * @param udev: to the structure of usbd_core_type
+ * @retval none
+ */
+void usbd_suspend_handler(usbd_core_type *udev)
+{
+ /* save connect state */
+ udev->old_conn_state = udev->conn_state;
+
+ /* set current state to suspend */
+ udev->conn_state = USB_CONN_STATE_SUSPENDED;
+
+ /* enter suspend mode */
+ usbd_enter_suspend(udev);
+}
+
+/**
+ * @brief usb device wakup interrupt request handler.
+ * @param udev: to the structure of usbd_core_type
+ * @retval none
+ */
+void usbd_wakeup_handler(usbd_core_type *udev)
+{
+ /* exit suspend mode */
+ usb_exit_suspend(udev->usb_reg);
+
+ /* restore connect state */
+ udev->conn_state = udev->old_conn_state;
+
+ /* user define wakeup event */
+}
+
+__weak void usbd_reset_callback(usbd_core_type *udev)
+{
+}
+
+__weak void usbd_setup_phase_done_callback(usbd_core_type *udev)
+{
+}
+
+__weak void usbd_data_in_stage_callback(usbd_core_type *udev, uint32_t ept_num)
+{
+}
+
+__weak void usbd_sof_callback(usbd_core_type *udev)
+{
+}
+
+__weak void usbd_data_out_stage_callback(usbd_core_type *udev, uint32_t ept_num)
+{
+}
+
+__weak void usbd_connectCallback(usbd_core_type *udev)
+{
+}
+
+__weak void usbd_disconnectCallback(usbd_core_type *udev)
+{
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+