/** * @brief USB low level reset routine. * * @param[in] usbp pointer to the @p USBDriver object * * @notapi */ void usb_lld_reset(USBDriver *usbp) { unsigned i; stm32_otg_t *otgp = usbp->otg; /* Flush the Tx FIFO.*/ otg_txfifo_flush(usbp, 0); /* All endpoints in NAK mode, interrupts cleared.*/ for (i = 0; i <= usbp->otgparams->num_endpoints; i++) { otgp->ie[i].DIEPCTL = DIEPCTL_SNAK; otgp->oe[i].DOEPCTL = DOEPCTL_SNAK; otgp->ie[i].DIEPINT = 0xFF; otgp->oe[i].DOEPINT = 0xFF; } /* Endpoint interrupts all disabled and cleared.*/ otgp->DAINT = 0xFFFFFFFF; otgp->DAINTMSK = DAINTMSK_OEPM(0) | DAINTMSK_IEPM(0); /* Resets the FIFO memory allocator.*/ otg_ram_reset(usbp); /* Receive FIFO size initialization, the address is always zero.*/ otgp->GRXFSIZ = usbp->otgparams->rx_fifo_size; otg_rxfifo_flush(usbp); /* Resets the device address to zero.*/ otgp->DCFG = (otgp->DCFG & ~DCFG_DAD_MASK) | DCFG_DAD(0); /* Enables also EP-related interrupt sources.*/ otgp->GINTMSK |= GINTMSK_RXFLVLM | GINTMSK_OEPM | GINTMSK_IEPM; otgp->DIEPMSK = DIEPMSK_TOCM | DIEPMSK_XFRCM; otgp->DOEPMSK = DOEPMSK_STUPM | DOEPMSK_XFRCM; /* EP0 initialization, it is a special case.*/ usbp->epc[0] = &ep0config; otgp->oe[0].DOEPTSIZ = 0; otgp->oe[0].DOEPCTL = DOEPCTL_SD0PID | DOEPCTL_USBAEP | DOEPCTL_EPTYP_CTRL | DOEPCTL_MPSIZ(ep0config.out_maxsize); otgp->ie[0].DIEPTSIZ = 0; otgp->ie[0].DIEPCTL = DIEPCTL_SD0PID | DIEPCTL_USBAEP | DIEPCTL_EPTYP_CTRL | DIEPCTL_TXFNUM(0) | DIEPCTL_MPSIZ(ep0config.in_maxsize); otgp->DIEPTXF0 = DIEPTXF_INEPTXFD(ep0config.in_maxsize / 4) | DIEPTXF_INEPTXSA(otg_ram_alloc(usbp, ep0config.in_maxsize / 4)); }
void Usb_t::IReset() { Uart.Printf("========= Rst =========\r\n"); TxFifoFlush(); // Set all EPs in NAK mode and clear Irqs for(uint8_t i=0; i < USB_EP_CNT; i++) { OTG_FS->ie[i].DIEPCTL = DIEPCTL_SNAK; OTG_FS->oe[i].DOEPCTL = DOEPCTL_SNAK; OTG_FS->ie[i].DIEPINT = 0xFF; OTG_FS->oe[i].DOEPINT = 0xFF; Ep[i].IsReceiving = false; Ep[i].IsTransmitting = false; Ep[i].IsTxPending = false; } // Disable and clear all EP irqs OTG_FS->DAINT = 0xFFFFFFFF; OTG_FS->DAINTMSK = DAINTMSK_OEPM(0) | DAINTMSK_IEPM(0); OTG_FS->DIEPEMPMSK &= 0xFFFF0000; MemAllocator.Reset(); // RX FIFO init, the address is always zero OTG_FS->GRXFSIZ = RX_FIFO_SZW; RxFifoFlush(); // Reset device address to zero OTG_FS->DCFG = (OTG_FS->DCFG & ~DCFG_DAD_MASK) | DCFG_DAD(0); // Enable EP-related irqs OTG_FS->GINTMSK |= GINTMSK_RXFLVLM | GINTMSK_OEPM | GINTMSK_IEPM; OTG_FS->DIEPMSK = DIEPMSK_XFRCM; OTG_FS->DOEPMSK = DOEPMSK_STUPM | DOEPMSK_XFRCM | DOEPMSK_OTEPDM; // Init EP0 OTG_FS->ie[0].DIEPINT |= 0x5B; // } OTG_FS->oe[0].DOEPINT |= 0x5B; // } Clear interrupts OTG_FS->oe[0].DOEPTSIZ = DOEPTSIZ_STUPCNT(3) | DOEPTSIZ_XFRSIZ(Ep[0].OutMaxSz); OTG_FS->oe[0].DOEPCTL = 0; // EP size is 64 bytes OTG_FS->ie[0].DIEPTSIZ = 0; OTG_FS->ie[0].DIEPCTL = DIEPCTL_TXFNUM(0); OTG_FS->DIEPTXF0 = DIEPTXF_INEPTXFD(TX0_FIFO_SZW) | DIEPTXF_INEPTXSA(RX_FIFO_SZW); // OTG_FS->DIEPTXF0 = DIEPTXF_INEPTXFD(EP0_SZ / 4) | DIEPTXF_INEPTXSA(MemAllocator.Alloc(EP0_SZ / 4)); Ep0State = esWaitingSetup; Ep[0].Rx.Ptr = Ep0RxBuf; }
/** * @brief Sets the USB address. * * @param[in] usbp pointer to the @p USBDriver object * * @notapi */ void usb_lld_set_address(USBDriver *usbp) { stm32_otg_t *otgp = usbp->otg; otgp->DCFG = (otgp->DCFG & ~DCFG_DAD_MASK) | DCFG_DAD(usbp->address); }