panda/board/stm32fx/llusb.h

103 lines
3.8 KiB
C

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);
print(" resetting PHY\n");*/
while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0);
//print("AHB idle\n");
// reset PHY here
USBx->GRSTCTL |= USB_OTG_GRSTCTL_CSRST;
while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_CSRST) == USB_OTG_GRSTCTL_CSRST);
//print("reset done\n");
// 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);
}