mirror of https://github.com/commaai/panda.git
92 lines
3.6 KiB
C
92 lines
3.6 KiB
C
USB_OTG_GlobalTypeDef *USBx = USB_OTG_HS;
|
|
|
|
#define USBx_HOST ((USB_OTG_HostTypeDef *)((uint32_t)USBx + USB_OTG_HOST_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 6UL
|
|
#define USB_OTG_SPEED_FULL 3U
|
|
#define DCFG_FRAME_INTERVAL_80 0U
|
|
|
|
|
|
void usb_irqhandler(void);
|
|
|
|
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);
|
|
}
|