AT32F435_437_Firmware_Library/libraries/drivers/src/at32f435_437_usb.c

1098 lines
30 KiB
C

/**
**************************************************************************
* @file at32f435_437_usb.c
* @version v2.0.9
* @date 2022-06-28
* @brief contains all the functions for the usb firmware library
**************************************************************************
* 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 "at32f435_437_conf.h"
/** @addtogroup AT32F435_437_periph_driver
* @{
*/
/** @defgroup USB
* @brief USB driver modules
* @{
*/
#ifdef USB_MODULE_ENABLED
/** @defgroup USB_private_functions
* @{
*/
#ifdef OTGFS_USB_GLOBAL
/**
* @brief usb global core soft reset
* @param usbx: to select the otgfs peripheral.
* this parameter can be one of the following values:
* - OTG1_GLOBAL
* - OTG2_GLOBAL
* @retval error status
*/
error_status usb_global_reset(otg_global_type *usbx)
{
uint32_t timeout = 0;
while(usbx->grstctl_bit.ahbidle == RESET)
{
if(timeout ++ > 200000)
{
break;
}
}
timeout = 0;
usbx->grstctl_bit.csftrst = TRUE;
while(usbx->grstctl_bit.csftrst == SET)
{
if(timeout ++ > 200000)
{
break;
}
}
return SUCCESS;
}
/**
* @brief usb global initialization
* @param usbx: to select the otgfs peripheral.
* this parameter can be one of the following values:
* - OTG1_GLOBAL
* - OTG2_GLOBAL
* @retval none
*/
void usb_global_init(otg_global_type *usbx)
{
/* reset otg moudle */
usb_global_reset(usbx);
/* exit power down mode */
usbx->gccfg_bit.pwrdown = TRUE;
}
/**
* @brief usb global select usb core (otg1 or otg2).
* @param usb_id: select otg1 or otg2
* this parameter can be one of the following values:
* - USB_OTG1_ID
* - USB_OTG2_ID
* @retval usb global register type pointer
*/
otg_global_type *usb_global_select_core(uint8_t usb_id)
{
if(usb_id == USB_OTG1_ID)
{
/* use otg1 */
return OTG1_GLOBAL;
}
else
{
/* use otg2 */
return OTG2_GLOBAL;
}
}
/**
* @brief flush tx fifo
* @param usbx: to select the otgfs peripheral.
* this parameter can be one of the following values:
* - OTG1_GLOBAL
* - OTG2_GLOBAL
* @param fifo_num: tx fifo num,when fifo_num=16,flush all tx fifo
* parameter as following values: 0-16
* @retval none
*/
void usb_flush_tx_fifo(otg_global_type *usbx, uint32_t fifo_num)
{
uint32_t timeout = 0;
/* set flush fifo number */
usbx->grstctl_bit.txfnum = fifo_num;
/* start flush fifo */
usbx->grstctl_bit.txfflsh = TRUE;
while(usbx->grstctl_bit.txfflsh == TRUE)
{
if(timeout ++ > 200000)
{
break;
}
}
}
/**
* @brief flush rx fifo
* @param usbx: to select the otgfs peripheral.
* this parameter can be one of the following values:
* - OTG1_GLOBAL
* - OTG2_GLOBAL
* @retval none
*/
void usb_flush_rx_fifo(otg_global_type *usbx)
{
uint32_t timeout = 0;
usbx->grstctl_bit.rxfflsh = TRUE;
while(usbx->grstctl_bit.rxfflsh == TRUE)
{
if(timeout ++ > 200000)
{
break;
}
}
}
/**
* @brief usb interrupt mask enable
* @param usbx: to select the otgfs peripheral.
* this parameter can be one of the following values:
* - OTG1_GLOBAL
* - OTG2_GLOBAL
* @param interrupt:
* this parameter can be any combination of the following values:
* - USB_OTG_MODEMIS_INT
* - USB_OTG_OTGINT_INT
* - USB_OTG_SOF_INT
* - USB_OTG_RXFLVL_INT
* - USB_OTG_NPTXFEMP_INT
* - USB_OTG_GINNAKEFF_INT
* - USB_OTG_GOUTNAKEFF_INT
* - USB_OTG_ERLYSUSP_INT
* - USB_OTG_USBSUSP_INT
* - USB_OTG_USBRST_INT
* - USB_OTG_ENUMDONE_INT
* - USB_OTG_ISOOUTDROP_INT
* - USB_OTG_IEPT_INT
* - USB_OTG_OEPT_INT
* - USB_OTG_INCOMISOIN_INT
* - USB_OTG_INCOMPIP_INCOMPISOOUT_INT
* - USB_OTG_PRT_INT
* - USB_OTG_HCH_INT
* - USB_OTG_PTXFEMP_INT
* - USB_OTG_CONIDSCHG_INT
* - USB_OTG_DISCON_INT
* - USB_OTG_WKUP_INT
* @param new_state: TRUE or FALSE
* @retval none
*/
void usb_global_interrupt_enable(otg_global_type *usbx, uint16_t interrupt, confirm_state new_state)
{
if(new_state == TRUE)
{
usbx->gintmsk |= interrupt;
}
else
{
usbx->gintmsk &= ~interrupt;
}
}
/**
* @brief get all global core interrupt flag
* @param usbx: to select the otgfs peripheral.
* this parameter can be one of the following values:
* - OTG1_GLOBAL
* - OTG2_GLOBAL
* @retval intterupt flag
*/
uint32_t usb_global_get_all_interrupt(otg_global_type *usbx)
{
uint32_t intsts = usbx->gintsts;
return intsts & usbx->gintmsk;
}
/**
* @brief clear the global interrupt flag
* @param usbx: to select the otgfs peripheral.
* this parameter can be one of the following values:
* - OTG1_GLOBAL
* - OTG2_GLOBAL
* @param flag: interrupt flag
* this parameter can be any combination of the following values:
* - USB_OTG_MODEMIS_FLAG
* - USB_OTG_OTGINT_FLAG
* - USB_OTG_SOF_FLAG
* - USB_OTG_RXFLVL_FLAG
* - USB_OTG_NPTXFEMP_FLAG
* - USB_OTG_GINNAKEFF_FLAG
* - USB_OTG_GOUTNAKEFF_FLAG
* - USB_OTG_ERLYSUSP_FLAG
* - USB_OTG_USBSUSP_FLAG
* - USB_OTG_USBRST_FLAG
* - USB_OTG_ENUMDONE_FLAG
* - USB_OTG_ISOOUTDROP_FLAG
* - USB_OTG_EOPF_FLAG
* - USB_OTG_IEPT_FLAG
* - USB_OTG_OEPT_FLAG
* - USB_OTG_INCOMISOIN_FLAG
* - USB_OTG_INCOMPIP_INCOMPISOOUT_FLAG
* - USB_OTG_PRT_FLAG
* - USB_OTG_HCH_FLAG
* - USB_OTG_PTXFEMP_FLAG
* - USB_OTG_CONIDSCHG_FLAG
* - USB_OTG_DISCON_FLAG
* - USB_OTG_WKUP_FLAG
* @retval none
*/
void usb_global_clear_interrupt(otg_global_type *usbx, uint32_t flag)
{
usbx->gintsts = flag;
}
/**
* @brief usb global interrupt enable
* @param usbx: to select the otgfs peripheral.
* this parameter can be one of the following values:
* OTG1_GLOBAL , OTG2_GLOBAL
* @retval none
*/
void usb_interrupt_enable(otg_global_type *usbx)
{
usbx->gahbcfg_bit.glbintmsk = TRUE;
}
/**
* @brief usb global interrupt disable
* @param usbx: to select the otgfs peripheral.
* this parameter can be one of the following values:
* - OTG1_GLOBAL
* - OTG2_GLOBAL
* @retval none
*/
void usb_interrupt_disable(otg_global_type *usbx)
{
usbx->gahbcfg_bit.glbintmsk = FALSE;
}
/**
* @brief usb set rx fifo size
* @param usbx: to select the otgfs peripheral.
* this parameter can be one of the following values:
* - OTG1_GLOBAL
* - OTG2_GLOBAL
* @param size: rx fifo size
* @retval none
*/
void usb_set_rx_fifo(otg_global_type *usbx, uint16_t size)
{
usbx->grxfsiz = size;
}
/**
* @brief usb set tx fifo size
* @param usbx: to select the otgfs peripheral.
* this parameter can be one of the following values:
* - OTG1_GLOBAL
* - OTG2_GLOBAL
* @param txfifo: the fifo number
* @param size: tx fifo size
* @retval none
*/
void usb_set_tx_fifo(otg_global_type *usbx, uint8_t txfifo, uint16_t size)
{
uint8_t i_index = 0;
uint32_t offset = 0;
offset = usbx->grxfsiz;
if(txfifo == 0)
{
usbx->gnptxfsiz_ept0tx = offset | (size << 16);
}
else
{
offset += usbx->gnptxfsiz_ept0tx_bit.nptxfdep;
for(i_index = 0; i_index < (txfifo - 1); i_index ++)
{
offset += usbx->dieptxfn_bit[i_index].ineptxfdep;
}
usbx->dieptxfn[txfifo - 1] = offset | (size << 16);
}
}
/**
* @brief set otg mode(device or host mode)
* @param usbx: to select the otgfs peripheral.
* this parameter can be one of the following values:
* - OTG1_GLOBAL
* - OTG2_GLOBAL
* @param mode:
this parameter can be one of the following values:
* - OTG_DEVICE_MODE
* - OTG_HOST_MODE
* - OTG_DRD_MODE
* @retval none
*/
void usb_global_set_mode(otg_global_type *usbx, uint32_t mode)
{
/* set otg to device mode */
if(mode == OTG_DEVICE_MODE)
{
usbx->gusbcfg_bit.fhstmode = FALSE;
usbx->gusbcfg_bit.fdevmode = TRUE;
}
/* set otg to host mode */
if(mode == OTG_HOST_MODE)
{
usbx->gusbcfg_bit.fdevmode = FALSE;
usbx->gusbcfg_bit.fhstmode = TRUE;
}
/* set otg to default mode */
if(mode == OTG_DRD_MODE)
{
usbx->gusbcfg_bit.fdevmode = FALSE;
usbx->gusbcfg_bit.fhstmode = FALSE;
}
}
/**
* @brief disable the transceiver power down mode
* @param usbx: to select the otgfs peripheral.
* this parameter can be one of the following values:
* - OTG1_GLOBAL
* - OTG2_GLOBAL
* @retval none
*/
void usb_global_power_on(otg_global_type *usbx)
{
/* core soft reset */
usbx->grstctl_bit.csftrst = TRUE;
while(usbx->grstctl_bit.csftrst);
/* disable power down mode */
usbx->gccfg_bit.pwrdown = TRUE;
}
/**
* @brief usb stop phy clock
* @param usbx: to select the otgfs peripheral.
* this parameter can be one of the following values:
* - OTG1_GLOBAL
* - OTG2_GLOBAL
* @retval none
*/
void usb_stop_phy_clk(otg_global_type *usbx)
{
OTG_PCGCCTL(usbx)->pcgcctl_bit.stoppclk = TRUE;
}
/**
* @brief usb open phy clock
* @param usbx: to select the otgfs peripheral.
* this parameter can be one of the following values:
* - OTG1_GLOBAL
* - OTG2_GLOBAL
* @retval none
*/
void usb_open_phy_clk(otg_global_type *usbx)
{
OTG_PCGCCTL(usbx)->pcgcctl_bit.stoppclk = FALSE;
}
/**
* @brief write data from user memory to usb buffer
* @param pusr_buf: point to user buffer
* @param offset_addr: endpoint tx offset address
* @param nbytes: number of bytes data write to usb buffer
* @retval none
*/
void usb_write_packet(otg_global_type *usbx, uint8_t *pusr_buf, uint16_t num, uint16_t nbytes)
{
uint32_t n_index;
uint32_t nhbytes = (nbytes + 3) / 4;
uint32_t *pbuf = (uint32_t *)pusr_buf;
for(n_index = 0; n_index < nhbytes; n_index ++)
{
#if defined (__ICCARM__) && (__VER__ < 7000000)
USB_FIFO(usbx, num) = *(__packed uint32_t *)pbuf;
#else
USB_FIFO(usbx, num) = __UNALIGNED_UINT32_READ(pbuf);
#endif
pbuf ++;
}
}
/**
* @brief read data from usb buffer to user buffer
* @param pusr_buf: point to user buffer
* @param offset_addr: endpoint rx offset address
* @param nbytes: number of bytes data write to usb buffer
* @retval none
*/
void usb_read_packet(otg_global_type *usbx, uint8_t *pusr_buf, uint16_t num, uint16_t nbytes)
{
uint32_t n_index;
uint32_t nhbytes = (nbytes + 3) / 4;
uint32_t *pbuf = (uint32_t *)pusr_buf;
for(n_index = 0; n_index < nhbytes; n_index ++)
{
#if defined (__ICCARM__) && (__VER__ < 7000000)
*(__packed uint32_t *)pbuf = USB_FIFO(usbx, 0);
#else
__UNALIGNED_UINT32_WRITE(pbuf, (USB_FIFO(usbx, 0)));
#endif
pbuf ++;
}
}
#endif
#ifdef OTGFS_USB_DEVICE
/**
* @brief open usb endpoint
* @param usbx: to select the otgfs peripheral.
* this parameter can be one of the following values:
* - OTG1_GLOBAL
* - OTG2_GLOBAL
* @param ept_info: endpoint information structure
* @retval none
*/
void usb_ept_open(otg_global_type *usbx, usb_ept_info *ept_info)
{
uint8_t mps = USB_EPT0_MPS_64;
if(ept_info->eptn == USB_EPT0)
{
if(ept_info->maxpacket == 0x40)
{
mps = USB_EPT0_MPS_64;
}
else if(ept_info->maxpacket == 0x20)
{
mps = USB_EPT0_MPS_32;
}
else if(ept_info->maxpacket == 0x10)
{
mps = USB_EPT0_MPS_16;
}
else if(ept_info->maxpacket == 0x08)
{
mps = USB_EPT0_MPS_8;
}
}
/* endpoint direction is in */
if(ept_info->inout == EPT_DIR_IN)
{
OTG_DEVICE(usbx)->daintmsk |= 1 << ept_info->eptn;
if(ept_info->eptn == USB_EPT0)
{
USB_INEPT(usbx, ept_info->eptn)->diepctl_bit.mps = mps;
}
else
{
USB_INEPT(usbx, ept_info->eptn)->diepctl_bit.mps = ept_info->maxpacket;
}
USB_INEPT(usbx, ept_info->eptn)->diepctl_bit.eptype = ept_info->trans_type;
USB_INEPT(usbx, ept_info->eptn)->diepctl_bit.txfnum = ept_info->eptn;
USB_INEPT(usbx, ept_info->eptn)->diepctl_bit.setd0pid = TRUE;
USB_INEPT(usbx, ept_info->eptn)->diepctl_bit.usbacept = TRUE;
}
/* endpoint direction is out */
else
{
OTG_DEVICE(usbx)->daintmsk |= (1 << ept_info->eptn) << 16;
if(ept_info->eptn == USB_EPT0)
{
USB_OUTEPT(usbx, ept_info->eptn)->doepctl_bit.mps = mps;
}
else
{
USB_OUTEPT(usbx, ept_info->eptn)->doepctl_bit.mps = ept_info->maxpacket;
}
USB_OUTEPT(usbx, ept_info->eptn)->doepctl_bit.eptype = ept_info->trans_type;
USB_OUTEPT(usbx, ept_info->eptn)->doepctl_bit.setd0pid = TRUE;
USB_OUTEPT(usbx, ept_info->eptn)->doepctl_bit.usbacept = TRUE;
}
}
/**
* @brief close usb endpoint
* @param usbx: to select the otgfs peripheral.
* this parameter can be one of the following values:
* - OTG1_GLOBAL
* - OTG2_GLOBAL
* @param ept_info: endpoint information structure
* @retval none
*/
void usb_ept_close(otg_global_type *usbx, usb_ept_info *ept_info)
{
if(ept_info->inout == EPT_DIR_IN)
{
OTG_DEVICE(usbx)->daintmsk &= ~(1 << ept_info->eptn);
USB_INEPT(usbx, ept_info->eptn)->diepctl_bit.usbacept = FALSE;
}
else
{
OTG_DEVICE(usbx)->daintmsk &= ~((1 << ept_info->eptn) << 16);
USB_OUTEPT(usbx, ept_info->eptn)->doepctl_bit.usbacept = FALSE;
}
}
/**
* @brief set endpoint tx or rx status to stall
* @param usbx: to select the otgfs peripheral.
* this parameter can be one of the following values:
* - OTG1_GLOBAL
* - OTG2_GLOBAL
* @param ept_info: endpoint information structure
* @retval none
*/
void usb_ept_stall(otg_global_type *usbx, usb_ept_info *ept_info)
{
if(ept_info->inout == EPT_DIR_IN)
{
if(USB_INEPT(usbx, ept_info->eptn)->diepctl_bit.eptena == RESET)
{
USB_INEPT(usbx, ept_info->eptn)->diepctl_bit.eptdis = FALSE;
}
USB_INEPT(usbx, ept_info->eptn)->diepctl_bit.stall = SET;
}
else
{
if(USB_OUTEPT(usbx, ept_info->eptn)->doepctl_bit.eptena == RESET)
{
USB_OUTEPT(usbx, ept_info->eptn)->doepctl_bit.eptdis = FALSE;
}
USB_OUTEPT(usbx, ept_info->eptn)->doepctl_bit.stall = TRUE;
}
}
/**
* @brief clear endpoint tx or rx status to stall
* @param usbx: to select the otgfs peripheral.
* this parameter can be one of the following values:
* - OTG1_GLOBAL
* - OTG2_GLOBAL
* @param ept_info: endpoint information structure
* @retval none
*/
void usb_ept_clear_stall(otg_global_type *usbx, usb_ept_info *ept_info)
{
if(ept_info->inout == EPT_DIR_IN)
{
USB_INEPT(usbx, ept_info->eptn)->diepctl_bit.stall = FALSE;
if(ept_info->trans_type == EPT_INT_TYPE || ept_info->trans_type == EPT_BULK_TYPE)
{
USB_INEPT(usbx, ept_info->eptn)->diepctl_bit.setd0pid = TRUE;
}
}
else
{
USB_OUTEPT(usbx, ept_info->eptn)->doepctl_bit.stall = FALSE;
if(ept_info->trans_type == EPT_INT_TYPE || ept_info->trans_type == EPT_BULK_TYPE)
{
USB_OUTEPT(usbx, ept_info->eptn)->doepctl_bit.setd0pid = TRUE;
}
}
}
/**
* @brief get all out endpoint interrupt bits
* @param usbx: to select the otgfs peripheral.
* this parameter can be one of the following values:
* - OTG1_GLOBAL
* - OTG2_GLOBAL
* @retval out endpoint interrupt bits
*/
uint32_t usb_get_all_out_interrupt(otg_global_type *usbx)
{
uint32_t intsts = OTG_DEVICE(usbx)->daint;
return ((intsts & (OTG_DEVICE(usbx)->daintmsk)) >> 16);
}
/**
* @brief get all in endpoint interrupt bits
* @param usbx: to select the otgfs peripheral.
* this parameter can be one of the following values:
* - OTG1_GLOBAL
* - OTG2_GLOBAL
* @retval in endpoint interrupt bits
*/
uint32_t usb_get_all_in_interrupt(otg_global_type *usbx)
{
uint32_t intsts = OTG_DEVICE(usbx)->daint;
return ((intsts & (OTG_DEVICE(usbx)->daintmsk)) & 0xFFFF);
}
/**
* @brief get out endpoint interrupt flag
* @param usbx: to select the otgfs peripheral.
* this parameter can be one of the following values:
* - OTG1_GLOBAL
* - OTG2_GLOBAL
* @param eptn: endpoint number
* @retval out endpoint interrupt flags
*/
uint32_t usb_ept_out_interrupt(otg_global_type *usbx, uint32_t eptn)
{
uint32_t intsts = USB_OUTEPT(usbx, eptn)->doepint;
return (intsts & (OTG_DEVICE(usbx)->doepmsk));
}
/**
* @brief get in endpoint interrupt flag
* @param usbx: to select the otgfs peripheral.
* this parameter can be one of the following values:
* - OTG1_GLOBAL
* - OTG2_GLOBAL
* @param eptn: endpoint number
* @retval in endpoint intterupt flags
*/
uint32_t usb_ept_in_interrupt(otg_global_type *usbx, uint32_t eptn)
{
uint32_t intsts, mask1, mask2;
mask1 = OTG_DEVICE(usbx)->diepmsk;
mask2 = OTG_DEVICE(usbx)->diepempmsk;
mask1 |= ((mask2 >> eptn) & 0x1) << 7;
intsts = USB_INEPT(usbx, eptn)->diepint & mask1;
return intsts;
}
/**
* @brief clear out endpoint interrupt flag
* @param usbx: to select the otgfs peripheral.
* this parameter can be one of the following values:
* - OTG1_GLOBAL
* - OTG2_GLOBAL
* @param eptn: endpoint number
* @retval flag: interrupt flag
* this parameter can be any combination of the following values:
* - USB_OTG_DOEPINT_XFERC_FLAG
* - USB_OTG_DOEPINT_EPTDISD_FLAG
* - USB_OTG_DOEPINT_SETUP_FLAG
* - USB_OTG_DOEPINT_OTEPDIS_FLAG
* - USB_OTG_DOEPINT_B2BSTUP_FLAG
*/
void usb_ept_out_clear(otg_global_type *usbx, uint32_t eptn, uint32_t flag)
{
USB_OUTEPT(usbx, eptn)->doepint = flag;
}
/**
* @brief clear in endpoint interrupt flag
* @param usbx: to select the otgfs peripheral.
* this parameter can be one of the following values:
* - OTG1_GLOBAL
* - OTG2_GLOBAL
* @param eptn: endpoint number
* @retval flag: interrupt flag
* this parameter can be any combination of the following values:
* - USB_OTG_DIEPINT_XFERC_FLAG
* - USB_OTG_DIEPINT_EPTDISD_FLAG
* - USB_OTG_DIEPINT_TMROC_FLAG
* - USB_OTG_DIEPINT_INTTXFE_FLAG
* - USB_OTG_DIEPINT_INEPNE_FLAG
* - USB_OTG_DIEPINT_TXFE_FLAG
*/
void usb_ept_in_clear(otg_global_type *usbx, uint32_t eptn, uint32_t flag)
{
USB_INEPT(usbx, eptn)->diepint = flag;
}
/**
* @brief set the host assignment address
* @param usbx: to select the otgfs peripheral.
* this parameter can be one of the following values:
* - OTG1_GLOBAL
* - OTG2_GLOBAL
* @param address: host assignment address
* @retval none
*/
void usb_set_address(otg_global_type *usbx, uint8_t address)
{
OTG_DEVICE(usbx)->dcfg_bit.devaddr = address;
}
/**
* @brief enable endpoint 0 out
* @param usbx: to select the otgfs peripheral.
* this parameter can be one of the following values:
* - OTG1_GLOBAL
* - OTG2_GLOBAL
* @retval none
*/
void usb_ept0_start(otg_global_type *usbx)
{
otg_eptout_type *usb_outept = USB_OUTEPT(usbx, 0);
usb_outept->doeptsiz = 0;
usb_outept->doeptsiz_bit.pktcnt = 1;
usb_outept->doeptsiz_bit.xfersize = 24;
usb_outept->doeptsiz_bit.rxdpid_setupcnt = 3;
}
/**
* @brief endpoint 0 start setup
* @param usbx: to select the otgfs peripheral.
* this parameter can be one of the following values:
* - OTG1_GLOBAL
* - OTG2_GLOBAL
* @retval none
*/
void usb_ept0_setup(otg_global_type *usbx)
{
USB_INEPT(usbx, 0)->diepctl_bit.mps = 0;
OTG_DEVICE(usbx)->dctl_bit.cgnpinak = FALSE;
}
/**
* @brief connect usb device by enable pull-up
* @param usbx: to select the otgfs peripheral.
* this parameter can be one of the following values:
* - OTG1_GLOBAL
* - OTG2_GLOBAL
* @retval none
*/
void usb_connect(otg_global_type *usbx)
{
/* D+ 1.5k pull-up enable */
OTG_DEVICE(usbx)->dctl_bit.sftdiscon = FALSE;
}
/**
* @brief disconnect usb device by disable pull-up
* @param usbx: to select the otgfs peripheral.
* this parameter can be one of the following values:
* - OTG1_GLOBAL
* - OTG2_GLOBAL
* @retval none
*/
void usb_disconnect(otg_global_type *usbx)
{
/* D+ 1.5k pull-up disable */
OTG_DEVICE(usbx)->dctl_bit.sftdiscon = TRUE;
}
/**
* @brief usb remote wakeup set
* @param usbx: to select the otgfs peripheral.
* this parameter can be one of the following values:
* - OTG1_GLOBAL
* - OTG2_GLOBAL
* @retval none
*/
void usb_remote_wkup_set(otg_global_type *usbx)
{
OTG_DEVICE(usbx)->dctl_bit.rwkupsig = TRUE;
}
/**
* @brief usb remote wakeup clear
* @param usbx: to select the otgfs peripheral.
* this parameter can be one of the following values:
* - OTG1_GLOBAL
* - OTG2_GLOBAL
* @retval none
*/
void usb_remote_wkup_clear(otg_global_type *usbx)
{
OTG_DEVICE(usbx)->dctl_bit.rwkupsig = FALSE;
}
/**
* @brief usb suspend status get
* @param usbx: to select the otgfs peripheral.
* this parameter can be one of the following values:
* - OTG1_GLOBAL
* - OTG2_GLOBAL
* @retval usb suspend status
*/
uint8_t usb_suspend_status_get(otg_global_type *usbx)
{
return OTG_DEVICE(usbx)->dsts_bit.suspsts;
}
#endif
#ifdef OTGFS_USB_HOST
/**
* @brief usb port power on
* @param usbx: to select the otgfs peripheral.
* this parameter can be one of the following values:
* - OTG1_GLOBAL
* - OTG2_GLOBAL
* @param state: state (TRUE or FALSE)
* @retval none
*/
void usb_port_power_on(otg_global_type *usbx, confirm_state state)
{
otg_host_type *usb_host = OTG_HOST(usbx);
uint32_t hprt_val = usb_host->hprt;
hprt_val &= ~(USB_OTG_HPRT_PRTENA | USB_OTG_HPRT_PRTENCHNG |
USB_OTG_HPRT_PRTOVRCACT | USB_OTG_HPRT_PRTCONDET);
if(state == TRUE)
{
usb_host->hprt = hprt_val | USB_OTG_HPRT_PRTPWR;
}
else
{
usb_host->hprt = hprt_val & (~USB_OTG_HPRT_PRTPWR);
}
}
/**
* @brief get current frame number
* @param usbx: to select the otgfs peripheral.
* this parameter can be one of the following values:
* - OTG1_GLOBAL
* - OTG2_GLOBAL
* @retval none
*/
uint32_t usbh_get_frame(otg_global_type *usbx)
{
otg_host_type *usb_host = OTG_HOST(usbx);
return usb_host->hfnum & 0xFFFF;
}
/**
* @brief enable one host channel
* @param usbx: to select the otgfs peripheral.
* this parameter can be one of the following values:
* - OTG1_GLOBAL
* - OTG2_GLOBAL
* @param chn: host channel number
* @param ept_num: devvice endpoint number
* @param dev_address: device address
* @param type: channel transfer type
* this parameter can be one of the following values:
* - EPT_CONTROL_TYPE
* - EPT_BULK_TYPE
* - EPT_INT_TYPE
* - EPT_ISO_TYPE
* @param maxpacket: support max packe size for this channel
* @param speed: device speed
* this parameter can be one of the following values:
* - USB_PRTSPD_FULL_SPEED
* - USB_PRTSPD_LOW_SPEED
* @retval none
*/
void usb_hc_enable(otg_global_type *usbx,
uint8_t chn,
uint8_t ept_num,
uint8_t dev_address,
uint8_t type,
uint16_t maxpacket,
uint8_t speed)
{
otg_hchannel_type *hch = USB_CHL(usbx, chn);
otg_host_type *usb_host = OTG_HOST(usbx);
switch(type)
{
case EPT_CONTROL_TYPE:
case EPT_BULK_TYPE:
hch->hcintmsk |= USB_OTG_HC_XFERCM_INT | USB_OTG_HC_STALLM_INT |
USB_OTG_HC_XACTERRM_INT | USB_OTG_HC_NAKM_INT |
USB_OTG_HC_DTGLERRM_INT;
if(ept_num & 0x80)
{
hch->hcintmsk_bit.bblerrmsk = TRUE;
}
break;
case EPT_INT_TYPE:
hch->hcintmsk |= USB_OTG_HC_XFERCM_INT | USB_OTG_HC_STALLM_INT |
USB_OTG_HC_XACTERRM_INT | USB_OTG_HC_NAKM_INT |
USB_OTG_HC_DTGLERRM_INT | USB_OTG_HC_FRMOVRRUN_INT;
break;
case EPT_ISO_TYPE:
hch->hcintmsk |= USB_OTG_HC_XFERCM_INT | USB_OTG_HC_ACKM_INT |
USB_OTG_HC_FRMOVRRUN_INT;
break;
}
usb_host->haintmsk |= 1 << chn;
usbx->gintmsk_bit.hchintmsk = TRUE;
hch->hcchar_bit.devaddr = dev_address;
hch->hcchar_bit.eptnum = ept_num & 0x7F;
hch->hcchar_bit.eptdir = (ept_num & 0x80)?1:0;
hch->hcchar_bit.lspddev = (speed == USB_PRTSPD_LOW_SPEED)?1:0;
hch->hcchar_bit.eptype = type;
hch->hcchar_bit.mps = maxpacket;
if(type == EPT_INT_TYPE)
{
hch->hcchar_bit.oddfrm = TRUE;
}
}
/**
* @brief host read channel interrupt
* @param usbx: to select the otgfs peripheral.
* this parameter can be one of the following values:
* - OTG1_GLOBAL
* - OTG2_GLOBAL
* @retval interrupt flag
*/
uint32_t usb_hch_read_interrupt(otg_global_type *usbx)
{
otg_host_type *usb_host = OTG_HOST(usbx);
return usb_host->haint & 0xFFFF;
}
/**
* @brief disable host
* @param usbx: to select the otgfs peripheral.
* this parameter can be one of the following values:
* - OTG1_GLOBAL
* - OTG2_GLOBAL
* @retval none
*/
void usb_host_disable(otg_global_type *usbx)
{
uint32_t i_index = 0, count = 0;
otg_hchannel_type *hch;
otg_host_type *usb_host = OTG_HOST(usbx);
usbx->gahbcfg_bit.glbintmsk = FALSE;
usb_flush_rx_fifo(usbx);
usb_flush_tx_fifo(usbx, 0x10);
for(i_index = 0; i_index < 16; i_index ++)
{
hch = USB_CHL(usbx, i_index);
hch->hcchar_bit.chdis = TRUE;
hch->hcchar_bit.chena = FALSE;
hch->hcchar_bit.eptdir = 0;
}
for(i_index = 0; i_index < 16; i_index ++)
{
hch = USB_CHL(usbx, i_index);
hch->hcchar_bit.chdis = TRUE;
hch->hcchar_bit.chena = TRUE;
hch->hcchar_bit.eptdir = 0;
do
{
if(count ++ > 1000)
break;
}while(hch->hcchar_bit.chena);
}
usb_host->haint = 0xFFFFFFFF;
usbx->gintsts = 0xFFFFFFFF;
usbx->gahbcfg_bit.glbintmsk = TRUE;
}
/**
* @brief halt channel
* @param usbx: to select the otgfs peripheral.
* this parameter can be one of the following values:
* - OTG1_GLOBAL
* - OTG2_GLOBAL
* @param chn: channel number
* @retval none
*/
void usb_hch_halt(otg_global_type *usbx, uint8_t chn)
{
uint32_t count = 0;
otg_hchannel_type *usb_chh = USB_CHL(usbx, chn);
otg_host_type *usb_host = OTG_HOST(usbx);
/* endpoint type is control or bulk */
if(usb_chh->hcchar_bit.eptype == EPT_CONTROL_TYPE ||
usb_chh->hcchar_bit.eptype == EPT_BULK_TYPE)
{
usb_chh->hcchar_bit.chdis = TRUE;
if((usbx->gnptxsts & 0xFFFF) == 0)
{
usb_chh->hcchar_bit.chena = FALSE;
usb_chh->hcchar_bit.chena = TRUE;
usb_chh->hcchar_bit.eptdir = 0;
do
{
if(count ++ > 1000)
break;
}while(usb_chh->hcchar_bit.chena == SET);
}
else
{
usb_chh->hcchar_bit.chena = TRUE;
}
}
else
{
usb_chh->hcchar_bit.chdis = TRUE;
if((usb_host->hptxsts & 0xFFFF) == 0)
{
usb_chh->hcchar_bit.chena = FALSE;
usb_chh->hcchar_bit.chena = TRUE;
usb_chh->hcchar_bit.eptdir = 0;
do
{
if(count ++ > 1000)
break;
}while(usb_chh->hcchar_bit.chena == SET);
}
else
{
usb_chh->hcchar_bit.chena = TRUE;
}
}
}
/**
* @brief select full or low speed clock
* @param usbx: to select the otgfs peripheral.
* this parameter can be one of the following values:
* - OTG1_GLOBAL
* - OTG2_GLOBAL
* @param clk: clock frequency
* @retval none
*/
void usbh_fsls_clksel(otg_global_type *usbx, uint8_t clk)
{
otg_host_type *usb_host = OTG_HOST(usbx);
usb_host->hcfg_bit.fslspclksel = clk;
if(clk == USB_HCFG_CLK_6M)
{
usb_host->hfir = 6000;
}
else
{
usb_host->hfir = 48000;
}
}
#endif
/**
* @}
*/
#endif
/**
* @}
*/
/**
* @}
*/