void Endpoint_t::PrepareTransmit(uint8_t *Ptr, uint32_t Len) { if(IsTransmitting) return; // do not start if transmitting already //Uart.Printf("TX: %A\r\n", Ptr, Len, ' '); Uart.Printf("PrepTX L=%u\r\n", Len); Tx.Ptr = Ptr; Tx.Sz = Len; Tx.Cnt = 0; uint32_t Dieptsiz = OTG_FS->ie[SelfN].DIEPTSIZ; Dieptsiz &= ~((3<<19) | 0x7F); uint32_t DieptCtl = OTG_FS->ie[SelfN].DIEPCTL; // Prepare transmission if(Len == 0) { // Send zero pkt //OTG_FS->ie[SelfN].DIEPTSIZ = DIEPTSIZ_PKTCNT(1) | DIEPTSIZ_XFRSIZ(0); Dieptsiz |= DIEPTSIZ_PKTCNT(1) | DIEPTSIZ_XFRSIZ(0); } else { uint32_t Cnt = (Len + InMaxSz - 1) / InMaxSz; //OTG_FS->ie[SelfN].DIEPTSIZ = DIEPTSIZ_PKTCNT(Cnt) | DIEPTSIZ_XFRSIZ(Len); //Uart.Printf("Cnt: %u\r\n", Cnt); Dieptsiz |= DIEPTSIZ_PKTCNT(Cnt) | DIEPTSIZ_XFRSIZ(Len); } //Uart.Printf("Dieptsiz: %X\r\n", Dieptsiz); DieptCtl |= DIEPCTL_EPENA | DIEPCTL_CNAK; // Start transfer chSysLockFromIsr(); IsTransmitting = true; OTG_FS->ie[SelfN].DIEPTSIZ = Dieptsiz; OTG_FS->ie[SelfN].DIEPCTL = DieptCtl; EnableInFifoEmptyIRQ(); chSysUnlockFromIsr(); }
/** * @brief Prepares for a transmit operation. * * @param[in] usbp pointer to the @p USBDriver object * @param[in] ep endpoint number * * @notapi */ void usb_lld_prepare_transmit(USBDriver *usbp, usbep_t ep) { USBInEndpointState *isp = usbp->epc[ep]->in_state; /* Transfer initialization.*/ if (isp->txsize == 0) { /* Special case, sending zero size packet.*/ usbp->otg->ie[ep].DIEPTSIZ = DIEPTSIZ_PKTCNT(1) | DIEPTSIZ_XFRSIZ(0); } else { /* Normal case.*/ uint32_t pcnt = (isp->txsize + usbp->epc[ep]->in_maxsize - 1) / usbp->epc[ep]->in_maxsize; usbp->otg->ie[ep].DIEPTSIZ = DIEPTSIZ_PKTCNT(pcnt) | DIEPTSIZ_XFRSIZ(usbp->epc[ep]->in_state->txsize); } }