455 lines
12 KiB
C
455 lines
12 KiB
C
/******************** (C) COPYRIGHT 2010 STMicroelectronics ********************
|
|
* File Name : otgd_fs_pcd.c
|
|
* Author : MCD Application Team
|
|
* Version : V3.1.1
|
|
* Date : 04/07/2010
|
|
* Description : Peripheral Device Interface low layer.
|
|
********************************************************************************
|
|
* THE PRESENT SOFTWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
|
|
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
|
|
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
|
|
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
|
|
* CONTENT OF SUCH SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
|
|
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
|
|
*******************************************************************************/
|
|
|
|
#ifdef STM32F10X_CL
|
|
|
|
#include "usb_lib.h"
|
|
#include "otgd_fs_cal.h"
|
|
#include "otgd_fs_pcd.h"
|
|
|
|
USB_OTG_PCD_DEV USB_OTG_PCD_dev;
|
|
|
|
extern USB_OTG_CORE_REGS core_regs;
|
|
/*******************************************************************************
|
|
* Function Name : OTGD_FS_PCD_Init
|
|
* Description : Initialize the USB Device portion of the driver.
|
|
* Input : None
|
|
* Output : None
|
|
* Return : None
|
|
*******************************************************************************/
|
|
void OTGD_FS_PCD_Init(void)
|
|
{
|
|
uint32_t i = 0;
|
|
USB_OTG_EP *ep;
|
|
|
|
ep = &USB_OTG_PCD_dev.ep0;
|
|
USB_OTG_PCD_dev.ep0state = 0;
|
|
|
|
/* Init ep structure */
|
|
ep->num = 0;
|
|
ep->tx_fifo_num = 0;
|
|
|
|
/* Control until ep is actvated */
|
|
ep->type = EP_TYPE_CTRL;
|
|
ep->maxpacket = MAX_PACKET_SIZE;
|
|
|
|
ep->xfer_buff = 0;
|
|
ep->xfer_len = 0;
|
|
|
|
for (i = 1; i < MAX_TX_FIFOS ; i++)
|
|
{
|
|
ep = &USB_OTG_PCD_dev.in_ep[i-1];
|
|
|
|
/* Init ep structure */
|
|
ep->is_in = 1;
|
|
ep->num = i;
|
|
ep->tx_fifo_num = i;
|
|
|
|
/* Control until ep is actvated */
|
|
ep->type = EP_TYPE_CTRL;
|
|
ep->maxpacket = MAX_PACKET_SIZE;
|
|
ep->xfer_buff = 0;
|
|
ep->xfer_len = 0;
|
|
}
|
|
|
|
for (i = 1; i < MAX_TX_FIFOS; i++)
|
|
{
|
|
ep = &USB_OTG_PCD_dev.out_ep[i-1];
|
|
|
|
/* Init ep structure */
|
|
ep->is_in = 0;
|
|
ep->num = i;
|
|
ep->tx_fifo_num = i;
|
|
|
|
/* Control until ep is activated */
|
|
ep->type = EP_TYPE_CTRL;
|
|
ep->maxpacket = MAX_PACKET_SIZE;
|
|
ep->xfer_buff = 0;
|
|
ep->xfer_len = 0;
|
|
}
|
|
|
|
USB_OTG_PCD_dev.ep0.maxpacket = MAX_EP0_SIZE;
|
|
USB_OTG_PCD_dev.ep0.type = EP_TYPE_CTRL;
|
|
|
|
}
|
|
|
|
/*******************************************************************************
|
|
* Function Name : OTGD_FS_PCD_EP_Open
|
|
* Description : Configure an Endpoint
|
|
* Input : None
|
|
* Output : None
|
|
* Return : status
|
|
*******************************************************************************/
|
|
uint32_t OTGD_FS_PCD_EP_Open(EP_DESCRIPTOR *epdesc)
|
|
{
|
|
USB_OTG_EP *ep;
|
|
|
|
|
|
if ((0x80 & epdesc->bEndpointAddress) != 0)
|
|
{
|
|
ep = OTGD_FS_PCD_GetInEP(epdesc->bEndpointAddress & 0x7F);
|
|
ep->is_in = 1;
|
|
}
|
|
else
|
|
{
|
|
ep = OTGD_FS_PCD_GetOutEP(epdesc->bEndpointAddress & 0x7F);
|
|
ep->is_in = 0;
|
|
}
|
|
|
|
ep->num = epdesc->bEndpointAddress & 0x7F;
|
|
ep->maxpacket = epdesc->wMaxPacketSize;
|
|
ep->type = epdesc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
|
|
|
|
if (ep->is_in)
|
|
{
|
|
/* Assign a Tx FIFO */
|
|
ep->tx_fifo_num = ep->num;
|
|
}
|
|
|
|
/* Set initial data PID. */
|
|
if ((epdesc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK )
|
|
{
|
|
ep->data_pid_start = 0;
|
|
}
|
|
|
|
OTGD_FS_EPActivate(ep );
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*******************************************************************************
|
|
* Function Name : OTGD_FS_PCD_EP_Close
|
|
* Description : Called when an EP is disabled
|
|
* Input : Endpoint address.
|
|
* Output : None
|
|
* Return : status
|
|
*******************************************************************************/
|
|
uint32_t OTGD_FS_PCD_EP_Close(uint8_t ep_addr)
|
|
{
|
|
|
|
USB_OTG_EP *ep;
|
|
|
|
if ((0x80 & ep_addr) != 0)
|
|
{
|
|
ep = OTGD_FS_PCD_GetInEP(ep_addr & 0x7F);
|
|
}
|
|
else
|
|
{
|
|
ep = OTGD_FS_PCD_GetOutEP(ep_addr & 0x7F);
|
|
}
|
|
|
|
ep->num = ep_addr & 0x7F;
|
|
ep->is_in = (0x80 & ep_addr) != 0;
|
|
|
|
OTGD_FS_EPDeactivate(ep );
|
|
return 0;
|
|
}
|
|
|
|
/*******************************************************************************
|
|
* Function Name : OTGD_FS_PCD_EP_Read
|
|
* Description : Read data from Fifo
|
|
* Input : Endpoint address.
|
|
* Output : None
|
|
* Return : status
|
|
*******************************************************************************/
|
|
uint32_t OTGD_FS_PCD_EP_Read (uint8_t ep_addr, uint8_t *pbuf, uint32_t buf_len)
|
|
{
|
|
USB_OTG_EP *ep;
|
|
uint32_t i = 0;
|
|
|
|
ep = OTGD_FS_PCD_GetOutEP(ep_addr & 0x7F);
|
|
|
|
/* copy received data into application buffer */
|
|
for (i = 0 ; i < buf_len ; i++)
|
|
{
|
|
pbuf[i] = ep->xfer_buff[i];
|
|
}
|
|
|
|
/*setup and start the Xfer */
|
|
ep->xfer_buff = pbuf;
|
|
ep->xfer_len = buf_len;
|
|
ep->xfer_count = 0;
|
|
ep->is_in = 0;
|
|
ep->num = ep_addr & 0x7F;
|
|
|
|
if ( ep->num == 0 )
|
|
{
|
|
OTGD_FS_EP0StartXfer(ep);
|
|
}
|
|
else if (USB_OTG_PCD_dev.ep0state == 0)
|
|
{
|
|
OTGD_FS_EPStartXfer( ep );
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*******************************************************************************
|
|
* Function Name : USBF_EP_Write
|
|
* Description : Read data from Fifo
|
|
* Input : ep
|
|
* Output : None
|
|
* Return : status
|
|
*******************************************************************************/
|
|
uint32_t OTGD_FS_PCD_EP_Write (uint8_t ep_addr, uint8_t *pbuf, uint32_t buf_len)
|
|
{
|
|
USB_OTG_EP *ep;
|
|
|
|
ep = OTGD_FS_PCD_GetInEP(ep_addr & 0x7f);
|
|
|
|
/* assign data to EP structure buffer */
|
|
ep->xfer_buff = pbuf;
|
|
|
|
/* Setup and start the Transfer */
|
|
ep->xfer_count = 0;
|
|
ep->xfer_len = buf_len;
|
|
ep->is_in = 1;
|
|
ep->num = ep_addr & 0x7F;
|
|
|
|
if ( ep->num == 0 )
|
|
{
|
|
OTGD_FS_EP0StartXfer(ep);
|
|
}
|
|
else if (USB_OTG_PCD_dev.ep0state == 0)
|
|
{
|
|
OTGD_FS_EPStartXfer( ep );
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*******************************************************************************
|
|
* Function Name : OTGD_FS_PCD_EP_Stall
|
|
* Description : Stall an endpoint.
|
|
* Input : Endpoint Address.
|
|
* Output : None
|
|
* Return : status
|
|
*******************************************************************************/
|
|
uint32_t OTGD_FS_PCD_EP_Stall (uint8_t ep_addr)
|
|
{
|
|
USB_OTG_EP *ep;
|
|
|
|
if ((0x80 & ep_addr) != 0)
|
|
{
|
|
ep = OTGD_FS_PCD_GetInEP(ep_addr & 0x7F);
|
|
}
|
|
else
|
|
{
|
|
ep = OTGD_FS_PCD_GetOutEP(ep_addr & 0x7F);
|
|
}
|
|
|
|
ep->num = ep_addr & 0x7F;
|
|
ep->is_in = ((ep_addr & 0x80) == 0x80) ? 1 : 0;
|
|
|
|
OTGD_FS_EPSetStall(ep);
|
|
return (0);
|
|
}
|
|
/*******************************************************************************
|
|
* Function Name : OTGD_FS_PCD_EP_ClrStall
|
|
* Description : Clear stall condition on endpoints.
|
|
* Input : Endpoint Address.
|
|
* Output : None
|
|
* Return : status
|
|
*******************************************************************************/
|
|
uint32_t OTGD_FS_PCD_EP_ClrStall (uint8_t ep_addr)
|
|
{
|
|
|
|
USB_OTG_EP *ep;
|
|
|
|
if ((0x80 & ep_addr) != 0)
|
|
{
|
|
ep = OTGD_FS_PCD_GetInEP(ep_addr & 0x7F);
|
|
}
|
|
else
|
|
{
|
|
ep = OTGD_FS_PCD_GetOutEP(ep_addr & 0x7F);
|
|
}
|
|
|
|
ep->num = ep_addr & 0x7F;
|
|
ep->is_in = ((ep_addr & 0x80) == 0x80) ? 1 : 0;
|
|
|
|
OTGD_FS_EPClearStall(ep);
|
|
|
|
return (0);
|
|
}
|
|
|
|
/*******************************************************************************
|
|
* Function Name : USBF_FCD_EP_Flush()
|
|
* Description : This Function flushes the buffer.
|
|
* Input : Endpoint Address.
|
|
* Output : None
|
|
* Return : status
|
|
*******************************************************************************/
|
|
uint32_t OTGD_FS_PCD_EP_Flush (uint8_t ep_addr)
|
|
{
|
|
|
|
uint8_t is_out = 0;
|
|
uint8_t ep_nbr = 0;
|
|
|
|
ep_nbr = ep_addr & 0x7F;
|
|
is_out = ((ep_addr & 0x80) == 0x80) ? 0 : 1;
|
|
|
|
if (is_out == 0)
|
|
{
|
|
OTGD_FS_FlushTxFifo(ep_nbr);
|
|
}
|
|
else
|
|
{
|
|
OTGD_FS_FlushRxFifo();
|
|
}
|
|
OTGD_FS_PCD_EP_ClrStall(ep_addr);
|
|
return (0);
|
|
}
|
|
|
|
/*******************************************************************************
|
|
* Function Name : OTGD_FS_PCD_EP_SetAddress
|
|
* Description : This Function set USB device address
|
|
* Input : The new device Address to be set.
|
|
* Output : None
|
|
* Return : status
|
|
*******************************************************************************/
|
|
void OTGD_FS_PCD_EP_SetAddress (uint8_t address)
|
|
{
|
|
|
|
USB_OTG_dev_cfg_data dcfg;
|
|
|
|
dcfg.d32 = 0;
|
|
|
|
dcfg.b.devaddr = address;
|
|
MODIFY_REG32( &core_regs.dev_regs->dev_cfg, 0, dcfg.d32);
|
|
}
|
|
|
|
|
|
/*******************************************************************************
|
|
* Function Name : OTGD_FS_PCD_GetInEP
|
|
* Description : This function returns pointer to IN EP struct with number ep_num
|
|
* Input : Endpoint Number.
|
|
* Output : None
|
|
* Return : status
|
|
*******************************************************************************/
|
|
USB_OTG_EP* OTGD_FS_PCD_GetInEP(uint32_t ep_num)
|
|
{
|
|
uint32_t i = 0;
|
|
|
|
if (ep_num == 0)
|
|
{
|
|
return &USB_OTG_PCD_dev.ep0;
|
|
}
|
|
else
|
|
{
|
|
for (i = 0; i < MAX_TX_FIFOS; ++i)
|
|
{
|
|
if (USB_OTG_PCD_dev.in_ep[i].num == ep_num)
|
|
return &USB_OTG_PCD_dev.in_ep[i];
|
|
}
|
|
return 0;
|
|
}
|
|
}
|
|
/*******************************************************************************
|
|
* Function Name : USBF_GetOutEP
|
|
* Description : returns pointer to OUT EP struct with number ep_num
|
|
* Input : Endpoint Number.
|
|
* Output : None
|
|
* Return : USBF_EP
|
|
*******************************************************************************/
|
|
USB_OTG_EP* OTGD_FS_PCD_GetOutEP(uint32_t ep_num)
|
|
{
|
|
uint32_t i = 0;
|
|
|
|
if (ep_num == 0)
|
|
{
|
|
return &USB_OTG_PCD_dev.ep0;
|
|
}
|
|
else
|
|
{
|
|
for (i = 0; i < MAX_TX_FIFOS; ++i)
|
|
{
|
|
if (USB_OTG_PCD_dev.out_ep[i].num == ep_num)
|
|
return &USB_OTG_PCD_dev.out_ep[i];
|
|
}
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
/*******************************************************************************
|
|
* Function Name : OTGD_FS_PCD_DevConnect
|
|
* Description : Connect device
|
|
* Input : None
|
|
* Output : None
|
|
* Return : status
|
|
*******************************************************************************/
|
|
void OTGD_FS_PCD_DevConnect(void)
|
|
{
|
|
|
|
USB_OTG_dev_ctl_data dctl;
|
|
|
|
dctl.d32 = 0;
|
|
|
|
dctl.d32 = READ_REG32(&core_regs.dev_regs->dev_ctl);
|
|
|
|
/* Connect device */
|
|
dctl.b.sftdiscon = 0;
|
|
WRITE_REG32(&core_regs.dev_regs->dev_ctl, dctl.d32);
|
|
mDELAY(25);
|
|
}
|
|
|
|
/*******************************************************************************
|
|
* Function Name : OTGD_FS_PCD_DevDisconnect
|
|
* Description : Disconnect device
|
|
* Input : None
|
|
* Output : None
|
|
* Return : status
|
|
*******************************************************************************/
|
|
void OTGD_FS_PCD_DevDisconnect (void)
|
|
{
|
|
|
|
USB_OTG_dev_ctl_data dctl;
|
|
|
|
dctl.d32 = 0;
|
|
|
|
dctl.d32 = READ_REG32(&core_regs.dev_regs->dev_ctl);
|
|
|
|
/* Disconnect device for 20ms */
|
|
dctl.b.sftdiscon = 1;
|
|
WRITE_REG32(&core_regs.dev_regs->dev_ctl, dctl.d32);
|
|
mDELAY(25);
|
|
}
|
|
|
|
/*******************************************************************************
|
|
* Function Name : OTGD_FS_PCD_EP0_OutStart
|
|
* Description : Configures EPO to receive SETUP packets.
|
|
* Input : None
|
|
* Output : None
|
|
* Return : None
|
|
*******************************************************************************/
|
|
void OTGD_FS_PCD_EP0_OutStart(void)
|
|
{
|
|
|
|
USB_OTG_dev_ep_txfer_size0_data doeptsize0;
|
|
doeptsize0.d32 = 0;
|
|
|
|
|
|
doeptsize0.b.supcnt = 3;
|
|
doeptsize0.b.pktcnt = 1;
|
|
doeptsize0.b.xfersize = 8 * 3;
|
|
|
|
WRITE_REG32( &core_regs.outep_regs[0]->dev_out_ep_txfer_siz, doeptsize0.d32 );
|
|
|
|
}
|
|
|
|
#endif /* STM32F10X_CL */
|
|
/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/
|
|
|