예제 #1
0
/**
  * @brief  Deactivate an endpoint
  * @param  hpcd: PCD handle
  * @param  ep_addr: endpoint address
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_PCD_EP_Close(PCD_HandleTypeDef * hpcd, uint8_t ep_addr)
{
	PCD_EPTypeDef *ep;

	if ((ep_addr & 0x80) == 0x80) {
		ep = &hpcd->IN_ep[ep_addr & 0x7F];
	} else {
		ep = &hpcd->OUT_ep[ep_addr & 0x7F];
	}
	ep->num = ep_addr & 0x7F;

	ep->is_in = (0x80 & ep_addr) != 0;

	__HAL_LOCK(hpcd);

	if (ep->doublebuffer == 0) {
		if (ep->is_in) {
			PCD_CLEAR_TX_DTOG(hpcd->Instance, ep->num);
			/* Configure DISABLE status for the Endpoint */
			PCD_SET_EP_TX_STATUS(hpcd->Instance, ep->num,
					     USB_EP_TX_DIS);
		} else {
			PCD_CLEAR_RX_DTOG(hpcd->Instance, ep->num);
			/* Configure DISABLE status for the Endpoint */
			PCD_SET_EP_RX_STATUS(hpcd->Instance, ep->num,
					     USB_EP_RX_DIS);
		}
	}
	/*Double Buffer */
	else {
		if (ep->is_in == 0) {
			/* Clear the data toggle bits for the endpoint IN/OUT */
			PCD_CLEAR_RX_DTOG(hpcd->Instance, ep->num);
			PCD_CLEAR_TX_DTOG(hpcd->Instance, ep->num);

			/* Reset value of the data toggle bits for the endpoint out */
			PCD_TX_DTOG(hpcd->Instance, ep->num);

			PCD_SET_EP_RX_STATUS(hpcd->Instance, ep->num,
					     USB_EP_RX_DIS);
			PCD_SET_EP_TX_STATUS(hpcd->Instance, ep->num,
					     USB_EP_TX_DIS);
		} else {
			/* Clear the data toggle bits for the endpoint IN/OUT */
			PCD_CLEAR_RX_DTOG(hpcd->Instance, ep->num);
			PCD_CLEAR_TX_DTOG(hpcd->Instance, ep->num);
			PCD_RX_DTOG(hpcd->Instance, ep->num);
			/* Configure DISABLE status for the Endpoint */
			PCD_SET_EP_TX_STATUS(hpcd->Instance, ep->num,
					     USB_EP_TX_DIS);
			PCD_SET_EP_RX_STATUS(hpcd->Instance, ep->num,
					     USB_EP_RX_DIS);
		}
	}

	__HAL_UNLOCK(hpcd);
	return HAL_OK;
}
예제 #2
0
/**
  * @brief  Clear a STALL condition over in an endpoint
  * @param  hpcd: PCD handle
  * @param  ep_addr: endpoint address
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_PCD_EP_ClrStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
{
  PCD_EPTypeDef *ep;
  
  if ((0x80 & ep_addr) == 0x80)
  {
    ep = &hpcd->IN_ep[ep_addr & 0x7F];
  }
  else
  {
    ep = &hpcd->OUT_ep[ep_addr];
  }
  
  ep->is_stall = 0;
  ep->num   = ep_addr & 0x7F;
  ep->is_in = ((ep_addr & 0x80) == 0x80);
  
  __HAL_LOCK(hpcd); 
  
  if (ep->is_in)
  {
    PCD_CLEAR_TX_DTOG(hpcd->Instance, ep->num);
    PCD_SET_EP_TX_STATUS(hpcd->Instance, ep->num, USB_EP_TX_VALID);
  }
  else
  {
    PCD_CLEAR_RX_DTOG(hpcd->Instance, ep->num);
    PCD_SET_EP_RX_STATUS(hpcd->Instance, ep->num, USB_EP_RX_VALID);
  }
  __HAL_UNLOCK(hpcd); 
    
  return HAL_OK;
}
예제 #3
0
/**
  * @brief  Open and configure an endpoint
  * @param  hpcd: PCD handle
  * @param  ep_addr: endpoint address
  * @param  ep_mps: endpoint max packert size
  * @param  ep_type: endpoint type   
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_PCD_EP_Open(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint16_t ep_mps, uint8_t ep_type)
{
  HAL_StatusTypeDef  ret = HAL_OK;
  PCD_EPTypeDef *ep;
  
  if ((ep_addr & 0x80) == 0x80)
  {
    ep = &hpcd->IN_ep[ep_addr & 0x7F];
  }
  else
  {
    ep = &hpcd->OUT_ep[ep_addr & 0x7F];
  }
  ep->num   = ep_addr & 0x7F;
  
  ep->is_in = (0x80 & ep_addr) != 0;
  ep->maxpacket = ep_mps;
  ep->type = ep_type;
  
  __HAL_LOCK(hpcd); 

/* initialize Endpoint */
  switch (ep->type)
  {
  case PCD_EP_TYPE_CTRL:
    PCD_SET_EPTYPE(hpcd->Instance, ep->num, USB_EP_CONTROL);
    break;
  case PCD_EP_TYPE_BULK:
    PCD_SET_EPTYPE(hpcd->Instance, ep->num, USB_EP_BULK);
    break;
  case PCD_EP_TYPE_INTR:
    PCD_SET_EPTYPE(hpcd->Instance, ep->num, USB_EP_INTERRUPT);
    break;
  case PCD_EP_TYPE_ISOC:
    PCD_SET_EPTYPE(hpcd->Instance, ep->num, USB_EP_ISOCHRONOUS);
    break;
  } 
  
  PCD_SET_EP_ADDRESS(hpcd->Instance, ep->num, ep->num);
  
  if (ep->doublebuffer == 0) 
  {
    if (ep->is_in)
    {
      /*Set the endpoint Transmit buffer address */
      PCD_SET_EP_TX_ADDRESS(hpcd->Instance, ep->num, ep->pmaadress);
      PCD_CLEAR_TX_DTOG(hpcd->Instance, ep->num);
      /* Configure NAK status for the Endpoint*/
      PCD_SET_EP_TX_STATUS(hpcd->Instance, ep->num, USB_EP_TX_NAK); 
    }
    else
    {
      /*Set the endpoint Receive buffer address */
      PCD_SET_EP_RX_ADDRESS(hpcd->Instance, ep->num, ep->pmaadress);
      /*Set the endpoint Receive buffer counter*/
      PCD_SET_EP_RX_CNT(hpcd->Instance, ep->num, ep->maxpacket);
      PCD_CLEAR_RX_DTOG(hpcd->Instance, ep->num);
      /* Configure VALID status for the Endpoint*/
      PCD_SET_EP_RX_STATUS(hpcd->Instance, ep->num, USB_EP_RX_VALID);
    }
  }
  /*Double Buffer*/
  else
  {
    /*Set the endpoint as double buffered*/
    PCD_SET_EP_DBUF(hpcd->Instance, ep->num);
    /*Set buffer address for double buffered mode*/
    PCD_SET_EP_DBUF_ADDR(hpcd->Instance, ep->num,ep->pmaaddr0, ep->pmaaddr1);
    
    if (ep->is_in==0)
    {
      /* Clear the data toggle bits for the endpoint IN/OUT*/
      PCD_CLEAR_RX_DTOG(hpcd->Instance, ep->num);
      PCD_CLEAR_TX_DTOG(hpcd->Instance, ep->num);
      
      /* Reset value of the data toggle bits for the endpoint out*/
      PCD_TX_DTOG(hpcd->Instance, ep->num);
      
      PCD_SET_EP_RX_STATUS(hpcd->Instance, ep->num, USB_EP_RX_VALID);
      PCD_SET_EP_TX_STATUS(hpcd->Instance, ep->num, USB_EP_TX_DIS);
    }
    else
    {
      /* Clear the data toggle bits for the endpoint IN/OUT*/
      PCD_CLEAR_RX_DTOG(hpcd->Instance, ep->num);
      PCD_CLEAR_TX_DTOG(hpcd->Instance, ep->num);
      PCD_RX_DTOG(hpcd->Instance, ep->num);
      /* Configure DISABLE status for the Endpoint*/
      PCD_SET_EP_TX_STATUS(hpcd->Instance, ep->num, USB_EP_TX_DIS);
      PCD_SET_EP_RX_STATUS(hpcd->Instance, ep->num, USB_EP_RX_DIS);
    }
  } 
  
  __HAL_UNLOCK(hpcd);   
  return ret;
}