/** * @brief USB_EPClearStall : Clear a stall condition over an EP * @param USBx : Selected device * @param ep: pointer to endpoint structure * @retval HAL status */ HAL_StatusTypeDef USB_EPClearStall(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep) { if (ep->is_in == 1) { USBx_INEP(ep->num)->DIEPCTL &= ~USB_OTG_DIEPCTL_STALL; if (ep->type == EP_TYPE_INTR || ep->type == EP_TYPE_BULK) { USBx_INEP(ep->num)->DIEPCTL |= USB_OTG_DIEPCTL_SD0PID_SEVNFRM; /* DATA0 */ } } else { USBx_OUTEP(ep->num)->DOEPCTL &= ~USB_OTG_DOEPCTL_STALL; if (ep->type == EP_TYPE_INTR || ep->type == EP_TYPE_BULK) { USBx_OUTEP(ep->num)->DOEPCTL |= USB_OTG_DOEPCTL_SD0PID_SEVNFRM; /* DATA0 */ } } return HAL_OK; }
/** * @brief USB_EPSetStall : set a stall condition over an EP * @param USBx : Selected device * @param ep: pointer to endpoint structure * @retval HAL status */ HAL_StatusTypeDef USB_EPSetStall(USB_OTG_GlobalTypeDef *USBx , USB_OTG_EPTypeDef *ep) { if (ep->is_in == 1) { if (((USBx_INEP(ep->num)->DIEPCTL) & USB_OTG_DIEPCTL_EPENA) == 0) { USBx_INEP(ep->num)->DIEPCTL &= ~(USB_OTG_DIEPCTL_EPDIS); } USBx_INEP(ep->num)->DIEPCTL |= USB_OTG_DIEPCTL_STALL; } else { if (((USBx_OUTEP(ep->num)->DOEPCTL) & USB_OTG_DOEPCTL_EPENA) == 0) { USBx_OUTEP(ep->num)->DOEPCTL &= ~(USB_OTG_DOEPCTL_EPDIS); } USBx_OUTEP(ep->num)->DOEPCTL |= USB_OTG_DOEPCTL_STALL; } return HAL_OK; }
/** * @brief Activate and configure a dedicated endpoint * @param USBx : Selected device * @param ep: pointer to endpoint structure * @retval HAL status */ HAL_StatusTypeDef USB_ActivateDedicatedEndpoint(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep) { static __IO uint32_t debug = 0; /* Read DEPCTLn register */ if (ep->is_in == 1) { if (((USBx_INEP(ep->num)->DIEPCTL) & USB_OTG_DIEPCTL_USBAEP) == 0) { USBx_INEP(ep->num)->DIEPCTL |= ((ep->maxpacket & USB_OTG_DIEPCTL_MPSIZ ) | (ep->type << 18 ) |\ ((ep->num) << 22 ) | (USB_OTG_DIEPCTL_SD0PID_SEVNFRM) | (USB_OTG_DIEPCTL_USBAEP)); } debug |= ((ep->maxpacket & USB_OTG_DIEPCTL_MPSIZ ) | (ep->type << 18 ) |\ ((ep->num) << 22 ) | (USB_OTG_DIEPCTL_SD0PID_SEVNFRM) | (USB_OTG_DIEPCTL_USBAEP)); USBx_DEVICE->DEACHMSK |= USB_OTG_DAINTMSK_IEPM & ((1 << (ep->num))); } else { if (((USBx_OUTEP(ep->num)->DOEPCTL) & USB_OTG_DOEPCTL_USBAEP) == 0) { USBx_OUTEP(ep->num)->DOEPCTL |= ((ep->maxpacket & USB_OTG_DOEPCTL_MPSIZ ) | (ep->type << 18 ) |\ ((ep->num) << 22 ) | (USB_OTG_DOEPCTL_USBAEP)); debug = (uint32_t)(((uint32_t )USBx) + USB_OTG_OUT_ENDPOINT_BASE + (0)*USB_OTG_EP_REG_SIZE); debug = (uint32_t )&USBx_OUTEP(ep->num)->DOEPCTL; debug |= ((ep->maxpacket & USB_OTG_DOEPCTL_MPSIZ ) | (ep->type << 18 ) |\ ((ep->num) << 22 ) | (USB_OTG_DOEPCTL_USBAEP)); } USBx_DEVICE->DEACHMSK |= USB_OTG_DAINTMSK_OEPM & ((1 << (ep->num)) << 16); } return HAL_OK; }
/** * @brief De-activate and de-initialize a dedicated endpoint * @param USBx : Selected device * @param ep: pointer to endpoint structure * @retval HAL status */ HAL_StatusTypeDef USB_DeactivateDedicatedEndpoint(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep) { /* Read DEPCTLn register */ if (ep->is_in == 1) { USBx_INEP(ep->num)->DIEPCTL &= ~ USB_OTG_DIEPCTL_USBAEP; USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_IEPM & ((1 << (ep->num)))); } else { USBx_OUTEP(ep->num)->DOEPCTL &= ~USB_OTG_DOEPCTL_USBAEP; USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_OEPM & ((1 << (ep->num)) << 16)); } return HAL_OK; }
/** * @brief Activate and configure an endpoint * @param USBx : Selected device * @param ep: pointer to endpoint structure * @retval HAL status */ HAL_StatusTypeDef USB_ActivateEndpoint(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep) { if (ep->is_in == 1) { USBx_DEVICE->DAINTMSK |= USB_OTG_DAINTMSK_IEPM & ((1 << (ep->num))); if (((USBx_INEP(ep->num)->DIEPCTL) & USB_OTG_DIEPCTL_USBAEP) == 0) { USBx_INEP(ep->num)->DIEPCTL |= ((ep->maxpacket & USB_OTG_DIEPCTL_MPSIZ ) | (ep->type << 18 ) |\ ((ep->num) << 22 ) | (USB_OTG_DIEPCTL_SD0PID_SEVNFRM) | (USB_OTG_DIEPCTL_USBAEP)); } } else { USBx_DEVICE->DAINTMSK |= USB_OTG_DAINTMSK_OEPM & ((1 << (ep->num)) << 16); if (((USBx_OUTEP(ep->num)->DOEPCTL) & USB_OTG_DOEPCTL_USBAEP) == 0) { USBx_OUTEP(ep->num)->DOEPCTL |= ((ep->maxpacket & USB_OTG_DOEPCTL_MPSIZ ) | (ep->type << 18 ) |\ (USB_OTG_DIEPCTL_SD0PID_SEVNFRM)| (USB_OTG_DOEPCTL_USBAEP)); } } return HAL_OK; }
/** * @brief USB_StopDevice : Stop the usb device mode * @param USBx : Selected device * @retval HAL status */ HAL_StatusTypeDef USB_StopDevice(USB_OTG_GlobalTypeDef *USBx) { uint32_t i; /* Clear Pending interrupt */ for (i = 0; i < 15 ; i++) { USBx_INEP(i)->DIEPINT = 0xFF; USBx_OUTEP(i)->DOEPINT = 0xFF; } USBx_DEVICE->DAINT = 0xFFFFFFFF; /* Clear interrupt masks */ USBx_DEVICE->DIEPMSK = 0; USBx_DEVICE->DOEPMSK = 0; USBx_DEVICE->DAINTMSK = 0; /* Flush the FIFO */ USB_FlushRxFifo(USBx); USB_FlushTxFifo(USBx , 0x10 ); return HAL_OK; }
/** * @brief USB_EP0StartXfer : setup and starts a transfer over the EP 0 * @param USBx : Selected device * @param ep: pointer to endpoint structure * @param dma: USB dma enabled or disabled * This parameter can be one of the these values: * 0 : DMA feature not used * 1 : DMA feature used * @retval HAL status */ HAL_StatusTypeDef USB_EP0StartXfer(USB_OTG_GlobalTypeDef *USBx , USB_OTG_EPTypeDef *ep, uint8_t dma) { /* IN endpoint */ if (ep->is_in == 1) { /* Zero Length Packet? */ if (ep->xfer_len == 0) { USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT); USBx_INEP(ep->num)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (1 << 19)) ; USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ); } else { /* Program the transfer size and packet count * as follows: xfersize = N * maxpacket + * short_packet pktcnt = N + (short_packet * exist ? 1 : 0) */ USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ); USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT); if(ep->xfer_len > ep->maxpacket) { ep->xfer_len = ep->maxpacket; } USBx_INEP(ep->num)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (1 << 19)) ; USBx_INEP(ep->num)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_XFRSIZ & ep->xfer_len); } if (dma == 1) { USBx_INEP(ep->num)->DIEPDMA = (uint32_t)(ep->dma_addr); } else { /* Enable the Tx FIFO Empty Interrupt for this EP */ if (ep->xfer_len > 0) { USBx_DEVICE->DIEPEMPMSK |= 1 << (ep->num); } } /* EP enable, IN data in FIFO */ USBx_INEP(ep->num)->DIEPCTL |= (USB_OTG_DIEPCTL_CNAK | USB_OTG_DIEPCTL_EPENA); } else /* OUT endpoint */ { /* Program the transfer size and packet count as follows: * pktcnt = N * xfersize = N * maxpacket */ USBx_OUTEP(ep->num)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_XFRSIZ); USBx_OUTEP(ep->num)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_PKTCNT); if (ep->xfer_len > 0) { ep->xfer_len = ep->maxpacket; } USBx_OUTEP(ep->num)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1 << 19)); USBx_OUTEP(ep->num)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_XFRSIZ & (ep->maxpacket)); if (dma == 1) { USBx_OUTEP(ep->num)->DOEPDMA = (uint32_t)(ep->xfer_buff); } /* EP enable */ USBx_OUTEP(ep->num)->DOEPCTL |= (USB_OTG_DOEPCTL_CNAK | USB_OTG_DOEPCTL_EPENA); } return HAL_OK; }
/** * @brief USB_EPStartXfer : setup and starts a transfer over an EP * @param USBx : Selected device * @param ep: pointer to endpoint structure * @param dma: USB dma enabled or disabled * This parameter can be one of the these values: * 0 : DMA feature not used * 1 : DMA feature used * @retval HAL status */ HAL_StatusTypeDef USB_EPStartXfer(USB_OTG_GlobalTypeDef *USBx , USB_OTG_EPTypeDef *ep, uint8_t dma) { uint16_t pktcnt = 0; /* IN endpoint */ if (ep->is_in == 1) { /* Zero Length Packet? */ if (ep->xfer_len == 0) { USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT); USBx_INEP(ep->num)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (1 << 19)) ; USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ); } else { /* Program the transfer size and packet count * as follows: xfersize = N * maxpacket + * short_packet pktcnt = N + (short_packet * exist ? 1 : 0) */ USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ); USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT); USBx_INEP(ep->num)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (((ep->xfer_len + ep->maxpacket -1)/ ep->maxpacket) << 19)) ; USBx_INEP(ep->num)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_XFRSIZ & ep->xfer_len); if (ep->type == EP_TYPE_ISOC) { USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_MULCNT); USBx_INEP(ep->num)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_MULCNT & (1 << 29)); } } if (dma == 1) { USBx_INEP(ep->num)->DIEPDMA = (uint32_t)(ep->dma_addr); } else { if (ep->type != EP_TYPE_ISOC) { /* Enable the Tx FIFO Empty Interrupt for this EP */ if (ep->xfer_len > 0) { USBx_DEVICE->DIEPEMPMSK |= 1 << ep->num; } } } if (ep->type == EP_TYPE_ISOC) { if ((USBx_DEVICE->DSTS & ( 1 << 8 )) == 0) { USBx_INEP(ep->num)->DIEPCTL |= USB_OTG_DIEPCTL_SODDFRM; } else { USBx_INEP(ep->num)->DIEPCTL |= USB_OTG_DIEPCTL_SD0PID_SEVNFRM; } } /* EP enable, IN data in FIFO */ USBx_INEP(ep->num)->DIEPCTL |= (USB_OTG_DIEPCTL_CNAK | USB_OTG_DIEPCTL_EPENA); if (ep->type == EP_TYPE_ISOC) { USB_WritePacket(USBx, ep->xfer_buff, ep->num, ep->xfer_len, dma); } } else /* OUT endpoint */ { /* Program the transfer size and packet count as follows: * pktcnt = N * xfersize = N * maxpacket */ USBx_OUTEP(ep->num)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_XFRSIZ); USBx_OUTEP(ep->num)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_PKTCNT); if (ep->xfer_len == 0) { USBx_OUTEP(ep->num)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_XFRSIZ & ep->maxpacket); USBx_OUTEP(ep->num)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1 << 19)) ; } else { pktcnt = (ep->xfer_len + ep->maxpacket -1)/ ep->maxpacket; USBx_OUTEP(ep->num)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (pktcnt << 19)); ; USBx_OUTEP(ep->num)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_XFRSIZ & (ep->maxpacket * pktcnt)); } if (dma == 1) { USBx_OUTEP(ep->num)->DOEPDMA = (uint32_t)ep->xfer_buff; } if (ep->type == EP_TYPE_ISOC) { if ((USBx_DEVICE->DSTS & ( 1 << 8 )) == 0) { USBx_OUTEP(ep->num)->DOEPCTL |= USB_OTG_DOEPCTL_SODDFRM; } else { USBx_OUTEP(ep->num)->DOEPCTL |= USB_OTG_DOEPCTL_SD0PID_SEVNFRM; } } /* EP enable */ USBx_OUTEP(ep->num)->DOEPCTL |= (USB_OTG_DOEPCTL_CNAK | USB_OTG_DOEPCTL_EPENA); } return HAL_OK; }
/** * @brief USB_DevInit : Initializes the USB_OTG controller registers * for device mode * @param USBx : Selected device * @param cfg : pointer to a USB_OTG_CfgTypeDef structure that contains * the configuration information for the specified USBx peripheral. * @retval HAL status */ HAL_StatusTypeDef USB_DevInit (USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg) { uint32_t i = 0; /*Activate VBUS Sensing B */ USBx->GCCFG |= USB_OTG_GCCFG_VBUSBSEN; if (cfg.vbus_sensing_enable == 0) { USBx->GCCFG |= USB_OTG_GCCFG_NOVBUSSENS; } /* Restart the Phy Clock */ USBx_PCGCCTL = 0; /* Device mode configuration */ USBx_DEVICE->DCFG |= DCFG_FRAME_INTERVAL_80; if(cfg.phy_itface == USB_OTG_ULPI_PHY) { if(cfg.speed == USB_OTG_SPEED_HIGH) { /* Set High speed phy */ USB_SetDevSpeed (USBx , USB_OTG_SPEED_HIGH); } else { /* set High speed phy in Full speed mode */ USB_SetDevSpeed (USBx , USB_OTG_SPEED_HIGH_IN_FULL); } } else { /* Set Full speed phy */ USB_SetDevSpeed (USBx , USB_OTG_SPEED_FULL); } /* Flush the FIFOs */ USB_FlushTxFifo(USBx , 0x10); /* all Tx FIFOs */ USB_FlushRxFifo(USBx); /* Clear all pending Device Interrupts */ USBx_DEVICE->DIEPMSK = 0; USBx_DEVICE->DOEPMSK = 0; USBx_DEVICE->DAINT = 0xFFFFFFFF; USBx_DEVICE->DAINTMSK = 0; for (i = 0; i < cfg.dev_endpoints; i++) { if ((USBx_INEP(i)->DIEPCTL & USB_OTG_DIEPCTL_EPENA) == USB_OTG_DIEPCTL_EPENA) { USBx_INEP(i)->DIEPCTL = (USB_OTG_DIEPCTL_EPDIS | USB_OTG_DIEPCTL_SNAK); } else { USBx_INEP(i)->DIEPCTL = 0; } USBx_INEP(i)->DIEPTSIZ = 0; USBx_INEP(i)->DIEPINT = 0xFF; } for (i = 0; i < cfg.dev_endpoints; i++) { if ((USBx_OUTEP(i)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA) { USBx_OUTEP(i)->DOEPCTL = (USB_OTG_DOEPCTL_EPDIS | USB_OTG_DOEPCTL_SNAK); } else { USBx_OUTEP(i)->DOEPCTL = 0; } USBx_OUTEP(i)->DOEPTSIZ = 0; USBx_OUTEP(i)->DOEPINT = 0xFF; } USBx_DEVICE->DIEPMSK &= ~(USB_OTG_DIEPMSK_TXFURM); if (cfg.dma_enable == 1) { /*Set threshold parameters */ USBx_DEVICE->DTHRCTL = (USB_OTG_DTHRCTL_TXTHRLEN_6 | USB_OTG_DTHRCTL_RXTHRLEN_6); USBx_DEVICE->DTHRCTL |= (USB_OTG_DTHRCTL_RXTHREN | USB_OTG_DTHRCTL_ISOTHREN | USB_OTG_DTHRCTL_NONISOTHREN); i= USBx_DEVICE->DTHRCTL; } /* Disable all interrupts. */ USBx->GINTMSK = 0; /* Clear any pending interrupts */ USBx->GINTSTS = 0xBFFFFFFF; /* Enable the common interrupts */ if (cfg.dma_enable == DISABLE) { USBx->GINTMSK |= USB_OTG_GINTMSK_RXFLVLM; } /* Enable interrupts matching to the Device mode ONLY */ USBx->GINTMSK |= (USB_OTG_GINTMSK_USBSUSPM | USB_OTG_GINTMSK_USBRST |\ USB_OTG_GINTMSK_ENUMDNEM | USB_OTG_GINTMSK_IEPINT |\ USB_OTG_GINTMSK_OEPINT | USB_OTG_GINTMSK_IISOIXFRM|\ USB_OTG_GINTMSK_PXFRM_IISOOXFRM | USB_OTG_GINTMSK_WUIM); if(cfg.Sof_enable) { USBx->GINTMSK |= USB_OTG_GINTMSK_SOFM; } if (cfg.vbus_sensing_enable == ENABLE) { USBx->GINTMSK |= (USB_OTG_GINTMSK_SRQIM | USB_OTG_GINTMSK_OTGINT); } return HAL_OK; }