/* Write USB Device Endpoint Data Parameters: EPNum: Endpoint Number EPNum.0..3: Address EPNum.7: Dir pData: Pointer to Data Buffer cnt: Number of bytes to write Return Value: Number of bytes written  */
uint32_t USBD_WriteEP(uint32_t EPNum, uint8_t *pData, uint32_t cnt)
/* Write USB Device Endpoint Data Parameters: EPNum: Endpoint Number EPNum.0..3: Address EPNum.7: Dir pData: Pointer to Data Buffer cnt: Number of bytes to write Return Value: Number of bytes written  */
uint32_t USBD_WriteEP(uint32_t EPNum, uint8_t *pData, uint32_t cnt)
{
    uint32_t i;
    volatile uint32_t *ptr;
    uint32_t *dataptr;
    ptr = GetEpCmdStatPtr(EPNum);
    EPNum &= ~USB_IN_MASK;
    while (*ptr & EP_BUF_ACTIVE);
    uint32_t cmdstat = *ptr;
    cmdstat &= ~(EP_NBYTES_MASK | EP_BUF_OFFSET_MASK);
    cmdstat |=  BUF_ADDR(EPBufInfo[EP_IN_IDX(EPNum)].buf_ptr) | N_BYTES(cnt);
    *ptr = cmdstat;
    dataptr = (uint32_t *)EPBufInfo[EP_IN_IDX(EPNum)].buf_ptr;
    memcpy(dataptr, pData, cnt);
    if (EPNum && (*ptr & EP_STALL)) {
        return (0);
    }
    *ptr |= EP_BUF_ACTIVE;
    return (cnt);
}