2021-07-03 09:25:35 +08:00
typedef struct
{
__IO uint32_t HPRT ;
}
USB_OTG_HostPortTypeDef ;
USB_OTG_GlobalTypeDef * USBx = USB_OTG_FS ;
# define USBx_HOST ((USB_OTG_HostTypeDef *)((uint32_t)USBx + USB_OTG_HOST_BASE))
# define USBx_HOST_PORT ((USB_OTG_HostPortTypeDef *)((uint32_t)USBx + USB_OTG_HOST_PORT_BASE))
# define USBx_DEVICE ((USB_OTG_DeviceTypeDef *)((uint32_t)USBx + USB_OTG_DEVICE_BASE))
# define USBx_INEP(i) ((USB_OTG_INEndpointTypeDef *)((uint32_t)USBx + USB_OTG_IN_ENDPOINT_BASE + ((i) * USB_OTG_EP_REG_SIZE)))
# define USBx_OUTEP(i) ((USB_OTG_OUTEndpointTypeDef *)((uint32_t)USBx + USB_OTG_OUT_ENDPOINT_BASE + ((i) * USB_OTG_EP_REG_SIZE)))
# define USBx_DFIFO(i) *(__IO uint32_t *)((uint32_t)USBx + USB_OTG_FIFO_BASE + ((i) * USB_OTG_FIFO_SIZE))
# define USBx_PCGCCTL *(__IO uint32_t *)((uint32_t)USBx + USB_OTG_PCGCCTL_BASE)
# define USBD_FS_TRDT_VALUE 5U
# define USB_OTG_SPEED_FULL 3
void usb_irqhandler ( void ) ;
void OTG_FS_IRQ_Handler ( void ) {
NVIC_DisableIRQ ( OTG_FS_IRQn ) ;
//__disable_irq();
usb_irqhandler ( ) ;
//__enable_irq();
NVIC_EnableIRQ ( OTG_FS_IRQn ) ;
}
void usb_init ( void ) {
REGISTER_INTERRUPT ( OTG_FS_IRQn , OTG_FS_IRQ_Handler , 1500000U , FAULT_INTERRUPT_RATE_USB ) //TODO: Find out a better rate limit for USB. Now it's the 1.5MB/s rate
// full speed PHY, do reset and remove power down
/*puth(USBx->GRSTCTL);
2022-11-30 14:55:10 +08:00
print ( " resetting PHY \n " ) ; */
2021-07-03 09:25:35 +08:00
while ( ( USBx - > GRSTCTL & USB_OTG_GRSTCTL_AHBIDL ) = = 0 ) ;
2022-11-30 14:55:10 +08:00
//print("AHB idle\n");
2021-07-03 09:25:35 +08:00
// reset PHY here
USBx - > GRSTCTL | = USB_OTG_GRSTCTL_CSRST ;
while ( ( USBx - > GRSTCTL & USB_OTG_GRSTCTL_CSRST ) = = USB_OTG_GRSTCTL_CSRST ) ;
2022-11-30 14:55:10 +08:00
//print("reset done\n");
2021-07-03 09:25:35 +08:00
// internal PHY, force device mode
USBx - > GUSBCFG = USB_OTG_GUSBCFG_PHYSEL | USB_OTG_GUSBCFG_FDMOD ;
// slowest timings
USBx - > GUSBCFG | = ( ( USBD_FS_TRDT_VALUE < < 10 ) & USB_OTG_GUSBCFG_TRDT ) ;
// power up the PHY
# ifdef STM32F4
USBx - > GCCFG = USB_OTG_GCCFG_PWRDWN ;
//USBx->GCCFG |= USB_OTG_GCCFG_VBDEN | USB_OTG_GCCFG_SDEN |USB_OTG_GCCFG_PDEN | USB_OTG_GCCFG_DCDEN;
/* B-peripheral session valid override enable*/
USBx - > GOTGCTL | = USB_OTG_GOTGCTL_BVALOVAL ;
USBx - > GOTGCTL | = USB_OTG_GOTGCTL_BVALOEN ;
# else
USBx - > GCCFG = USB_OTG_GCCFG_PWRDWN | USB_OTG_GCCFG_NOVBUSSENS ;
# endif
// be a device, slowest timings
//USBx->GUSBCFG = USB_OTG_GUSBCFG_FDMOD | USB_OTG_GUSBCFG_PHYSEL | USB_OTG_GUSBCFG_TRDT | USB_OTG_GUSBCFG_TOCAL;
//USBx->GUSBCFG |= (uint32_t)((USBD_FS_TRDT_VALUE << 10) & USB_OTG_GUSBCFG_TRDT);
//USBx->GUSBCFG = USB_OTG_GUSBCFG_PHYSEL | USB_OTG_GUSBCFG_TRDT | USB_OTG_GUSBCFG_TOCAL;
// **** for debugging, doesn't seem to work ****
//USBx->GUSBCFG |= USB_OTG_GUSBCFG_CTXPKT;
// reset PHY clock
USBx_PCGCCTL = 0 ;
// enable the fancy OTG things
// DCFG_FRAME_INTERVAL_80 is 0
//USBx->GUSBCFG |= USB_OTG_GUSBCFG_HNPCAP | USB_OTG_GUSBCFG_SRPCAP;
USBx_DEVICE - > DCFG | = USB_OTG_SPEED_FULL | USB_OTG_DCFG_NZLSOHSK ;
//USBx_DEVICE->DCFG = USB_OTG_DCFG_NZLSOHSK | USB_OTG_DCFG_DSPD;
//USBx_DEVICE->DCFG = USB_OTG_DCFG_DSPD;
// clear pending interrupts
USBx - > GINTSTS = 0xBFFFFFFFU ;
// setup USB interrupts
// all interrupts except TXFIFO EMPTY
//USBx->GINTMSK = 0xFFFFFFFF & ~(USB_OTG_GINTMSK_NPTXFEM | USB_OTG_GINTMSK_PTXFEM | USB_OTG_GINTSTS_SOF | USB_OTG_GINTSTS_EOPF);
//USBx->GINTMSK = 0xFFFFFFFF & ~(USB_OTG_GINTMSK_NPTXFEM | USB_OTG_GINTMSK_PTXFEM);
USBx - > GINTMSK = USB_OTG_GINTMSK_USBRST | USB_OTG_GINTMSK_ENUMDNEM | USB_OTG_GINTMSK_OTGINT |
USB_OTG_GINTMSK_RXFLVLM | USB_OTG_GINTMSK_GONAKEFFM | USB_OTG_GINTMSK_GINAKEFFM |
USB_OTG_GINTMSK_OEPINT | USB_OTG_GINTMSK_IEPINT | USB_OTG_GINTMSK_USBSUSPM |
USB_OTG_GINTMSK_CIDSCHGM | USB_OTG_GINTMSK_SRQIM | USB_OTG_GINTMSK_MMISM | USB_OTG_GINTMSK_EOPFM ;
USBx - > GAHBCFG = USB_OTG_GAHBCFG_GINT ;
// DCTL startup value is 2 on new chip, 0 on old chip
USBx_DEVICE - > DCTL = 0 ;
// enable the IRQ
NVIC_EnableIRQ ( OTG_FS_IRQn ) ;
}