mirror of
https://github.com/ArteryTek/AT32F413_Firmware_Library.git
synced 2026-05-21 09:22:02 +00:00
upload version v2.0.0
This commit is contained in:
333
middlewares/usbd_drivers/src/usbd_int.c
Normal file
333
middlewares/usbd_drivers/src/usbd_int.c
Normal file
@@ -0,0 +1,333 @@
|
||||
/**
|
||||
**************************************************************************
|
||||
* @file usbd_int.c
|
||||
* @version v2.0.0
|
||||
* @date 2021-11-26
|
||||
* @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"
|
||||
|
||||
/** @addtogroup AT32F413_middlewares_usbd_drivers
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @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 */
|
||||
usbx->intsts_bit.rst = 0;
|
||||
|
||||
/* reset interrupt handler */
|
||||
usbd_reset_handler(udev);
|
||||
}
|
||||
|
||||
if((sts_val & USB_SOF_FLAG) &&
|
||||
(sts_ien & USB_SOF_INT))
|
||||
{
|
||||
/* clear sof flag */
|
||||
usbx->intsts_bit.sof = 0;
|
||||
|
||||
/* sof interrupt handler */
|
||||
usbd_sof_handler(udev);
|
||||
}
|
||||
|
||||
if((sts_val & USB_LSOF_FLAG) &&
|
||||
(sts_ien & USB_LSOF_INT))
|
||||
{
|
||||
/* clear lsof flag */
|
||||
usbx->intsts_bit.lsof = 0;
|
||||
}
|
||||
|
||||
if((sts_val & USB_SP_FLAG) &&
|
||||
(sts_ien & USB_SP_INT))
|
||||
{
|
||||
/* clear suspend flag */
|
||||
usbx->intsts_bit.sp = 0;
|
||||
|
||||
/* 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 */
|
||||
usbx->intsts_bit.wk = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @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_core_in_handler(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);
|
||||
}
|
||||
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_core_out_handler(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 */
|
||||
if(udev->class_handler->event_handler)
|
||||
udev->class_handler->event_handler(udev, USBD_RESET_EVENT);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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);
|
||||
|
||||
/* user define suspend event */
|
||||
if(udev->class_handler->event_handler)
|
||||
udev->class_handler->event_handler(udev, USBD_SUSPEND_EVENT);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 */
|
||||
if(udev->class_handler->event_handler)
|
||||
udev->class_handler->event_handler(udev, USBD_WAKEUP_EVENT);
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
Reference in New Issue
Block a user