/** * @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; }
/** * @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; }
/** * @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; }