# include "llusb_declarations.h"
USB_OTG_GlobalTypeDef * USBx = USB_OTG_HS ;
static void OTG_HS_IRQ_Handler ( void ) {
NVIC_DisableIRQ ( OTG_HS_IRQn ) ;
usb_irqhandler ( ) ;
NVIC_EnableIRQ ( OTG_HS_IRQn ) ;
}
void usb_init ( void ) {
REGISTER_INTERRUPT ( OTG_HS_IRQn , OTG_HS_IRQ_Handler , 1500000U , FAULT_INTERRUPT_RATE_USB ) // TODO: Find out a better rate limit for USB. Now it's the 1.5MB/s rate
// Disable global interrupt
USBx - > GAHBCFG & = ~ ( USB_OTG_GAHBCFG_GINT ) ;
// Select FS Embedded PHY
USBx - > GUSBCFG | = USB_OTG_GUSBCFG_PHYSEL ;
// Force device mode
USBx - > GUSBCFG & = ~ ( USB_OTG_GUSBCFG_FHMOD | USB_OTG_GUSBCFG_FDMOD ) ;
USBx - > GUSBCFG | = USB_OTG_GUSBCFG_FDMOD ;
delay ( 250000 ) ; // Wait for about 25ms (explicitly stated in H7 ref manual)
// Wait for AHB master IDLE state.
while ( ( USBx - > GRSTCTL & USB_OTG_GRSTCTL_AHBIDL ) = = 0U ) ;
// Core Soft Reset
USBx - > GRSTCTL | = USB_OTG_GRSTCTL_CSRST ;
while ( ( USBx - > GRSTCTL & USB_OTG_GRSTCTL_CSRST ) = = USB_OTG_GRSTCTL_CSRST ) ;
// Activate the USB Transceiver
USBx - > GCCFG | = USB_OTG_GCCFG_PWRDWN ;
for ( uint8_t i = 0U ; i < 15U ; i + + ) {
USBx - > DIEPTXF [ i ] = 0U ;
}
// VBUS Sensing setup
USBx_DEVICE - > DCTL | = USB_OTG_DCTL_SDIS ;
// Deactivate VBUS Sensing B
USBx - > GCCFG & = ~ ( USB_OTG_GCCFG_VBDEN ) ;
// B-peripheral session valid override enable
USBx - > GOTGCTL | = USB_OTG_GOTGCTL_BVALOEN ;
USBx - > GOTGCTL | = USB_OTG_GOTGCTL_BVALOVAL ;
// Restart the Phy Clock
USBx_PCGCCTL = 0U ;
// Device mode configuration
USBx_DEVICE - > DCFG | = DCFG_FRAME_INTERVAL_80 ;
USBx_DEVICE - > DCFG | = USB_OTG_SPEED_FULL | USB_OTG_DCFG_NZLSOHSK ;
// Flush FIFOs
USBx - > GRSTCTL = ( USB_OTG_GRSTCTL_TXFFLSH | ( 0x10U < < 6 ) ) ;
while ( ( USBx - > GRSTCTL & USB_OTG_GRSTCTL_TXFFLSH ) = = USB_OTG_GRSTCTL_TXFFLSH ) ;
USBx - > GRSTCTL = USB_OTG_GRSTCTL_RXFFLSH ;
while ( ( USBx - > GRSTCTL & USB_OTG_GRSTCTL_RXFFLSH ) = = USB_OTG_GRSTCTL_RXFFLSH ) ;
// Clear all pending Device Interrupts
USBx_DEVICE - > DIEPMSK = 0U ;
USBx_DEVICE - > DOEPMSK = 0U ;
USBx_DEVICE - > DAINTMSK = 0U ;
USBx_DEVICE - > DIEPMSK & = ~ ( USB_OTG_DIEPMSK_TXFURM ) ;
// Disable all interrupts.
USBx - > GINTMSK = 0U ;
// Clear any pending interrupts
USBx - > GINTSTS = 0xBFFFFFFFU ;
// Enable interrupts matching to the Device mode ONLY
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_CIDSCHGM | USB_OTG_GINTMSK_SRQIM | USB_OTG_GINTMSK_MMISM ;
// Set USB Turnaround time
USBx - > GUSBCFG | = ( ( USBD_FS_TRDT_VALUE < < 10 ) & USB_OTG_GUSBCFG_TRDT ) ;
// Enables the controller's Global Int in the AHB Config reg
USBx - > GAHBCFG | = USB_OTG_GAHBCFG_GINT ;
// Soft disconnect disable:
USBx_DEVICE - > DCTL & = ~ ( USB_OTG_DCTL_SDIS ) ;
// enable the IRQ
NVIC_EnableIRQ ( OTG_HS_IRQn ) ;
}