/**
******************************************************************************
* @file usb_dc_py32.c
* @author MCU Application Team
* @brief CMSIS Cortex-M4 Device Peripheral Access Layer System Source File
******************************************************************************
* @attention
*
*
© Copyright (c) Puya Semiconductor Co.
* All rights reserved.
*
* This software component is licensed by ST under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
*/
#include "usb_py32_reg.h"
#include "usbd_core.h"
#define HWREG(x) \
(*((volatile uint32_t *)(x)))
#define HWREGH(x) \
(*((volatile uint16_t *)(x)))
#define HWREGB(x) \
(*((volatile uint8_t *)(x)))
#ifndef USB_BASE
#define USB_BASE (0x40005C00)
#endif
#ifndef USB_NUM_BIDIR_ENDPOINTS
#define USB_NUM_BIDIR_ENDPOINTS 8
#endif
typedef enum {
USB_EP0_STATE_SETUP = 0x0, /**< SETUP DATA */
USB_EP0_STATE_IN_DATA = 0x1, /**< IN DATA */
USB_EP0_STATE_OUT_DATA = 0x3, /**< OUT DATA */
USB_EP0_STATE_IN_STATUS = 0x4, /**< IN status */
USB_EP0_STATE_OUT_STATUS = 0x5, /**< OUT status */
USB_EP0_STATE_IN_ZLP = 0x6, /**< OUT status */
USB_EP0_STATE_STALL = 0x7, /**< STALL status */
} ep0_state_t;
/* Endpoint state */
struct pyusb_ep_state {
uint16_t ep_mps; /* Endpoint max packet size */
uint8_t ep_type; /* Endpoint type */
uint8_t ep_stalled; /* Endpoint stall flag */
uint8_t ep_enable; /* Endpoint enable */
uint8_t *xfer_buf; /* data buffer */
uint32_t xfer_len;
uint32_t actual_xfer_len;
};
/* Driver state */
struct pyusb_udc {
volatile uint8_t dev_addr;
volatile uint32_t fifo_size_offset;
__attribute__((aligned(32))) struct usb_setup_packet setup;
struct pyusb_ep_state in_ep[USB_NUM_BIDIR_ENDPOINTS]; /*!< IN endpoint parameters*/
struct pyusb_ep_state out_ep[USB_NUM_BIDIR_ENDPOINTS]; /*!< OUT endpoint parameters */
} g_pyusb_udc;
static volatile uint8_t usb_ep0_state = USB_EP0_STATE_SETUP;
volatile bool zlp_flag = 0;
void usbd_ep0_set_zlp_flag()
{
zlp_flag = TRUE;
}
void usbd_ep0_reset_zlp_flag()
{
zlp_flag = FALSE;
}
/* get current active ep */
static uint8_t pyusb_get_active_ep(void)
{
return (uint8_t)(USB->INDEX);
}
/* set the active ep */
static void pyusb_set_active_ep(uint8_t ep_index)
{
USB->INDEX = ep_index;
}
static void pyusb_write_packet(uint8_t ep_idx, uint8_t *buffer, uint16_t len)
{
uint8_t *nAddr;
uint8_t *tmp = (uint8_t *)buffer;
uint16_t count = len;
nAddr = &((uint8_t *)&USB->FIFO_EP0)[ep_idx<<2];
if(count)
{
while (count)
{
*nAddr = *tmp++;
count--;
}
}
}
static void pyusb_read_packet(uint8_t ep_idx, uint8_t *buffer, uint16_t len)
{
uint8_t *tmp = (uint8_t *)buffer;
uint8_t *nAddr;
uint16_t count = len;
nAddr = &((uint8_t *)&USB->FIFO_EP0)[ep_idx<<2];
if(count)
{
while (count)
{
*tmp++ = *nAddr;
count--;
}
}
}
static uint32_t pyusb_get_fifo_size(uint16_t mps, uint16_t *used)
{
uint32_t size;
for (uint8_t i = USB_TXFIFOSZ_SIZE_8; i <= USB_TXFIFOSZ_SIZE_64; i++) {
size = (i << 3);
if (mps <= size) {
*used = size;
return i;
}
}
*used = 0;
return USB_TXFIFOSZ_SIZE_8;
}
__WEAK void usb_dc_low_level_init(void)
{
}
__WEAK void usb_dc_low_level_deinit(void)
{
}
int usb_dc_init(void)
{
usb_dc_low_level_init();
pyusb_set_active_ep(0);
USB->ADDR = 0;
// USB->INT_USBE = USB_INTR_RESET;
USB->INT_USBE = USB_INTR_RESET | USB_INTR_SUSPEND | USB_INTR_RESUME;
USB->INT_IN1E = USB_INTR_EP0;
USB->INT_OUT1E = 0;
return 0;
}
int usb_dc_deinit(void)
{
return 0;
}
int usbd_set_address(const uint8_t addr)
{
if (addr == 0)
{
USB->ADDR = 0;
}
g_pyusb_udc.dev_addr = addr;
return 0;
}
int usbd_ep_open(const struct usbd_endpoint_cfg *ep_cfg)
{
uint16_t used = 0;
uint16_t fifo_size = 0;
uint8_t ep_idx = USB_EP_GET_IDX(ep_cfg->ep_addr);
uint8_t old_ep_idx;
uint32_t ui32Flags = 0;
uint16_t ui32Register = 0;
if (ep_idx == 0) {
g_pyusb_udc.out_ep[0].ep_mps = USB_CTRL_EP_MPS;
g_pyusb_udc.out_ep[0].ep_type = 0x00;
g_pyusb_udc.out_ep[0].ep_enable = true;
g_pyusb_udc.in_ep[0].ep_mps = USB_CTRL_EP_MPS;
g_pyusb_udc.in_ep[0].ep_type = 0x00;
g_pyusb_udc.in_ep[0].ep_enable = true;
return 0;
}
if (ep_idx > (USB_NUM_BIDIR_ENDPOINTS - 1)) {
USB_LOG_ERR("Ep addr %d overflow\r\n", ep_cfg->ep_addr);
return -1;
}
old_ep_idx = pyusb_get_active_ep();
pyusb_set_active_ep(ep_idx);
if (USB_EP_DIR_IS_OUT(ep_cfg->ep_addr)) /* OUT endpoint */
{
g_pyusb_udc.out_ep[ep_idx].ep_mps = ep_cfg->ep_mps;
g_pyusb_udc.out_ep[ep_idx].ep_type = ep_cfg->ep_type;
g_pyusb_udc.out_ep[ep_idx].ep_enable = true;
/* Allow auto clearing of RxPktRdy when packet of size max packet
has been unloaded from the FIFO. */
if (ui32Flags & USB_EP_AUTO_CLEAR)
{
ui32Register = USB_OUTCSR2_AutoClear;
}
/* Configure the DMA mode. */
if (ui32Flags & USB_EP_DMA_MODE_1)
{
ui32Register |= USB_OUTCSR2_DMAEnab | USB_OUTCSR2_DMAMode;
} else if (ui32Flags & USB_EP_DMA_MODE_0)
{
ui32Register |= USB_OUTCSR2_DMAEnab;
}
/* Enable isochronous mode if requested. */
if (ep_cfg->ep_type == 0x01)
{
ui32Register |= USB_OUTCSR2_ISO;
}
USB->OUT_CSR2 = ui32Register;
/* Reset the Data toggle to zero. */
if (USB->OUT_CSR1 & USB_OUTCSR_OPR)
{
USB->OUT_CSR1 = (USB_OUTCSR_FF | USB_OUTCSR_CDT);
} else
{
USB->OUT_CSR1 = USB_OUTCSR_CDT;
}
fifo_size = pyusb_get_fifo_size(ep_cfg->ep_mps, &used);
USB->MAX_PKT_OUT = fifo_size;
g_pyusb_udc.fifo_size_offset += used;
} else { /* IN endpoint */
g_pyusb_udc.in_ep[ep_idx].ep_mps = ep_cfg->ep_mps;
g_pyusb_udc.in_ep[ep_idx].ep_type = ep_cfg->ep_type;
g_pyusb_udc.in_ep[ep_idx].ep_enable = true;
USB->INT_IN1E |= (1 << ep_idx);
/* Allow auto setting of TxPktRdy when max packet size has been loaded
into the FIFO. */
if (ui32Flags & USB_EP_AUTO_SET) {
ui32Register |= USB_INCSR2_AUTOSET;
}
/* Configure the DMA mode. */
if (ui32Flags & (USB_EP_DMA_MODE_0 | USB_EP_DMA_MODE_1)) {
ui32Register |= USB_INCSR2_DMAEnab;
}
/* Enable isochronous mode if requested. */
if (ep_cfg->ep_type == 0x01) {
ui32Register |= USB_INCSR2_ISO;
}
ui32Register |= USB_INCSR2_MODE;
USB->IN_CSR2 = ui32Register;
/* Reset the Data toggle to zero. */
if (USB->IN_CSR1 & USB_INCSR_FifoNotEmpty)
{
USB->IN_CSR1 = (USB_INCSR_FF | USB_INCSR_CDT);
} else
{
USB->IN_CSR1 = USB_INCSR_CDT;
}
fifo_size = pyusb_get_fifo_size(ep_cfg->ep_mps, &used);
USB->MAX_PKT_IN = fifo_size;
g_pyusb_udc.fifo_size_offset += used;
}
pyusb_set_active_ep(old_ep_idx);
return 0;
}
int usbd_ep_close(const uint8_t ep)
{
return 0;
}
int usbd_ep_set_stall(const uint8_t ep)
{
uint8_t ep_idx = USB_EP_GET_IDX(ep);
uint8_t old_ep_idx;
old_ep_idx = pyusb_get_active_ep();
pyusb_set_active_ep(ep_idx);
if (USB_EP_DIR_IS_OUT(ep))
{
if (ep_idx == 0x00)
{
usb_ep0_state = USB_EP0_STATE_STALL;
USB->EP0_CSR |= (USB_CSR0_SENDSTALL | USB_CSR0_SVDOUTPKTRDY);
} else
{
USB->OUT_CSR1 |= USB_OUTCSR_SendStall;
}
} else
{
if (ep_idx == 0x00)
{
usb_ep0_state = USB_EP0_STATE_STALL;
USB->EP0_CSR |= (USB_CSR0_SENDSTALL | USB_CSR0_SVDOUTPKTRDY);
} else
{
USB->IN_CSR1 |= USB_INCSR_SendStall;
}
}
pyusb_set_active_ep(old_ep_idx);
return 0;
}
int usbd_ep_clear_stall(const uint8_t ep)
{
uint8_t ep_idx = USB_EP_GET_IDX(ep);
uint8_t old_ep_idx;
old_ep_idx = pyusb_get_active_ep();
pyusb_set_active_ep(ep_idx);
if (USB_EP_DIR_IS_OUT(ep))
{
if (ep_idx == 0x00)
{
USB->EP0_CSR &= ~USB_CSR0_SENTSTALL;
} else
{
/* Clear the stall on an OUT endpoint. */
USB->OUT_CSR1 &= ~(USB_OUTCSR_SendStall | USB_OUTCSR_SentStall);
/* Reset the data toggle. */
USB->OUT_CSR1 |= USB_OUTCSR_CDT;
}
} else
{
if (ep_idx == 0x00)
{
USB->EP0_CSR &= ~USB_CSR0_SENTSTALL;
} else {
/* Clear the stall on an IN endpoint. */
USB->IN_CSR1 &= ~(USB_INCSR_SendStall | USB_INCSR_SentStall);
/* Reset the data toggle. */
USB->IN_CSR1 |= USB_INCSR_CDT;
}
}
pyusb_set_active_ep(old_ep_idx);
return 0;
}
int usbd_ep_is_stalled(const uint8_t ep, uint8_t *stalled)
{
uint8_t ep_idx = USB_EP_GET_IDX(ep);
uint8_t old_ep_idx;
old_ep_idx = pyusb_get_active_ep();
pyusb_set_active_ep(ep_idx);
if (USB_EP_DIR_IS_OUT(ep))
{
if (ep_idx == 0x00)
{
*stalled = 0;
} else
{
*stalled = !!(USB->OUT_CSR1 & USB_OUTCSR_SendStall);
}
} else
{
if (ep_idx == 0x00)
{
*stalled = 0;
} else {
*stalled = !!(USB->IN_CSR1 & USB_INCSR_SendStall);
}
}
pyusb_set_active_ep(old_ep_idx);
return 0;
}
int usbd_ep_start_write(const uint8_t ep, const uint8_t *data, uint32_t data_len)
{
uint8_t ep_idx = USB_EP_GET_IDX(ep);
uint8_t old_ep_idx;
if (!data && data_len) {
return -1;
}
if (!g_pyusb_udc.in_ep[ep_idx].ep_enable) {
return -2;
}
old_ep_idx = pyusb_get_active_ep();
pyusb_set_active_ep(ep_idx);
if (USB->IN_CSR1 & USB_INCSR_IPR)
{
pyusb_set_active_ep(old_ep_idx);
return -3;
}
g_pyusb_udc.in_ep[ep_idx].xfer_buf = (uint8_t *)data;
g_pyusb_udc.in_ep[ep_idx].xfer_len = data_len;
g_pyusb_udc.in_ep[ep_idx].actual_xfer_len = 0;
if(ep_idx == 0)
{
switch(usb_ep0_state)
{
case USB_EP0_STATE_SETUP:
/* Zero data request */
if(data_len == 0)
{
USB->EP0_CSR = (USB_CSR0_SVDOUTPKTRDY | USB_CSR0_DATAEND);
usb_ep0_state = USB_EP0_STATE_IN_STATUS;
}
/* Enter IN data stage */
else
{
/* Clear OutPktRdy bit for the next setup packet receive */
USB->EP0_CSR = USB_CSR0_SVDOUTPKTRDY;
/* The length of the sent data is less than or equal to the maximum packet length and no additional 0 packets are required */
if(data_len <= g_pyusb_udc.in_ep[ep_idx].ep_mps && zlp_flag == FALSE)
{
pyusb_write_packet(ep_idx, (uint8_t *)data, data_len);
USB->EP0_CSR = (USB_CSR0_INPKTRDY | USB_CSR0_DATAEND);
}
/* If the packet length exceeds the maximum, only the data with the maximum packet length is sent */
else
{
pyusb_write_packet(ep_idx, (uint8_t *)data, g_pyusb_udc.in_ep[ep_idx].ep_mps);
USB->EP0_CSR = USB_CSR0_INPKTRDY;
}
usb_ep0_state = USB_EP0_STATE_IN_DATA;
}
break;
case USB_EP0_STATE_IN_DATA:
/* Zero length packet need to be sent */
if(data_len == 0)
{
/* clear zlp flag */
usbd_ep0_reset_zlp_flag();
USB->EP0_CSR = (USB_CSR0_INPKTRDY | USB_CSR0_DATAEND);
usb_ep0_state = USB_EP0_STATE_IN_ZLP;
}
/* Start sending the remain data */
else
{
/* The length of the sent data is less than or equal to the maximum packet length and no additional 0 packets are required */
if(data_len <= g_pyusb_udc.in_ep[ep_idx].ep_mps && zlp_flag == FALSE)
{
pyusb_write_packet(ep_idx, (uint8_t *)data, data_len);
USB->EP0_CSR = (USB_CSR0_INPKTRDY | USB_CSR0_DATAEND);
}
/* If the packet length exceeds the maximum, only the data with the maximum packet length is sent */
else
{
pyusb_write_packet(ep_idx, (uint8_t *)data, g_pyusb_udc.in_ep[ep_idx].ep_mps);
USB->EP0_CSR = USB_CSR0_INPKTRDY;
}
}
break;
case USB_EP0_STATE_OUT_DATA:
/* Received all data, enter status stage */
USB->EP0_CSR = (USB_CSR0_SVDOUTPKTRDY | USB_CSR0_DATAEND);
usb_ep0_state = USB_EP0_STATE_IN_STATUS;
break;
}
}
else
{
if(data_len != 0)
{
/* If the packet length exceeds the maximum, only the data with the maximum packet length is sent */
if(data_len > g_pyusb_udc.in_ep[ep_idx].ep_mps)
{
pyusb_write_packet(ep_idx, (uint8_t *)data, g_pyusb_udc.in_ep[ep_idx].ep_mps);
}
/* The remaining data can be sent in one package */
else
{
pyusb_write_packet(ep_idx, (uint8_t *)data, data_len);
}
}
USB->IN_CSR1 = USB_INCSR_IPR;
}
pyusb_set_active_ep(old_ep_idx);
return 0;
}
int usbd_ep_start_read(const uint8_t ep, uint8_t *data, uint32_t data_len)
{
uint8_t ep_idx = USB_EP_GET_IDX(ep);
uint8_t old_ep_idx;
if (!data && data_len)
{
return -1;
}
if (!g_pyusb_udc.out_ep[ep_idx].ep_enable)
{
return -2;
}
old_ep_idx = pyusb_get_active_ep();
pyusb_set_active_ep(ep_idx);
g_pyusb_udc.out_ep[ep_idx].xfer_buf = data;
g_pyusb_udc.out_ep[ep_idx].xfer_len = data_len;
g_pyusb_udc.out_ep[ep_idx].actual_xfer_len = 0;
if(ep_idx == 0)
{
switch(usb_ep0_state)
{
case USB_EP0_STATE_SETUP:
/* Enter data stage, start receive data */
USB->EP0_CSR |= USB_CSR0_SVDOUTPKTRDY;
usb_ep0_state = USB_EP0_STATE_OUT_DATA;
break;
case USB_EP0_STATE_IN_DATA:
case USB_EP0_STATE_IN_ZLP:
/* Enter status stage, nothing to do */
usb_ep0_state = USB_EP0_STATE_OUT_STATUS;
break;
}
}
else
{
/* Enable ep receive interrupt before clear OutPktRdy */
USB->INT_OUT1E |= (1 << ep_idx);
/* Clear OutPktRdy to receive data */
USB->OUT_CSR1 &= ~USB_OUTCSR_OPR;
}
pyusb_set_active_ep(old_ep_idx);
return 0;
}
static void handle_ep0(void)
{
uint8_t ep0_status = USB->EP0_CSR;
uint16_t read_count;
if (ep0_status & USB_CSR0_SENTSTALL)
{
USB->EP0_CSR &= ~USB_CSR0_SENTSTALL;
usb_ep0_state = USB_EP0_STATE_SETUP;
return;
}
if (ep0_status & USB_CSR0_SETUPEND)
{
USB->EP0_CSR = USB_CSR0_SVDSETUPEND;
usb_ep0_state = USB_EP0_STATE_SETUP;
}
if (g_pyusb_udc.dev_addr > 0)
{
USB->ADDR = g_pyusb_udc.dev_addr;
g_pyusb_udc.dev_addr = 0;
}
switch (usb_ep0_state) {
case USB_EP0_STATE_SETUP:
if (ep0_status & USB_CSR0_OUTPKTRDY)
{
read_count = USB->EP0_COUNT;
if (read_count != 8)
{
return;
}
pyusb_read_packet(0, (uint8_t *)&g_pyusb_udc.setup, 8);
usbd_event_ep0_setup_complete_handler((uint8_t *)&g_pyusb_udc.setup);
}
break;
case USB_EP0_STATE_IN_DATA:
if (g_pyusb_udc.in_ep[0].xfer_len > g_pyusb_udc.in_ep[0].ep_mps) {
g_pyusb_udc.in_ep[0].actual_xfer_len += g_pyusb_udc.in_ep[0].ep_mps;
g_pyusb_udc.in_ep[0].xfer_len -= g_pyusb_udc.in_ep[0].ep_mps;
} else {
g_pyusb_udc.in_ep[0].actual_xfer_len += g_pyusb_udc.in_ep[0].xfer_len;
g_pyusb_udc.in_ep[0].xfer_len = 0;
}
usbd_event_ep_in_complete_handler(0x80, g_pyusb_udc.in_ep[0].actual_xfer_len);
break;
case USB_EP0_STATE_OUT_DATA:
if (ep0_status & USB_CSR0_OUTPKTRDY)
{
read_count = USB->EP0_COUNT;
pyusb_read_packet(0, g_pyusb_udc.out_ep[0].xfer_buf, read_count);
g_pyusb_udc.out_ep[0].xfer_buf += read_count;
g_pyusb_udc.out_ep[0].actual_xfer_len += read_count;
/* End of transfer:
1.Current packet length less than the max packet length
2.The total transfer size reaches the preset size of setup packet
*/
if ((read_count < g_pyusb_udc.out_ep[0].ep_mps) || (g_pyusb_udc.out_ep[0].actual_xfer_len == g_pyusb_udc.out_ep[0].xfer_len))
{
usbd_event_ep_out_complete_handler(0x00, g_pyusb_udc.out_ep[0].actual_xfer_len);
} else
{
USB->EP0_CSR = USB_CSR0_SVDOUTPKTRDY;
}
}
break;
case USB_EP0_STATE_IN_ZLP:
usbd_event_ep_in_complete_handler(0x80, 0);
break;
case USB_EP0_STATE_IN_STATUS:
case USB_EP0_STATE_OUT_STATUS:
usb_ep0_state = USB_EP0_STATE_SETUP;
break;
}
}
void USBD_IRQHandler(void)
{
uint32_t is;
uint32_t txis;
uint32_t rxis;
uint8_t old_ep_idx;
uint8_t ep_idx;
uint16_t write_count, read_count;
is = USB->INT_USB;
txis = USB->INT_IN1;
rxis = USB->INT_OUT1;
old_ep_idx = pyusb_get_active_ep();
/* Receive a reset signal from the USB bus */
if (is & USB_INTR_RESET) {
memset(&g_pyusb_udc, 0, sizeof(struct pyusb_udc));
g_pyusb_udc.fifo_size_offset = USB_CTRL_EP_MPS;
usbd_event_reset_handler();
USB->POWER |= USB_POWER_SUSPENDENB;
USB->INT_IN1E = USB_INTR_EP0;
USB->INT_OUT1E = 0;
usb_ep0_state = USB_EP0_STATE_SETUP;
}
if (is & USB_INTR_SOF)
{
}
if (is & USB_INTR_RESUME)
{
usbd_event_resume_handler();
}
if (is & USB_INTR_SUSPEND)
{
usbd_event_suspend_handler();
}
txis &= USB->INT_IN1E;
/* Handle EP0 interrupt */
if (txis & USB_INTR_EP0)
{
pyusb_set_active_ep(0);
handle_ep0();
txis &= ~USB_INTR_EP0;
}
ep_idx = 1;
while (txis) {
if (txis & (1 << ep_idx))
{
pyusb_set_active_ep(ep_idx);
if (USB->IN_CSR1 & USB_INCSR_UnderRun)
{
USB->IN_CSR1 &= ~USB_INCSR_UnderRun;
}
if (g_pyusb_udc.in_ep[ep_idx].xfer_len > g_pyusb_udc.in_ep[ep_idx].ep_mps)
{
g_pyusb_udc.in_ep[ep_idx].xfer_buf += g_pyusb_udc.in_ep[ep_idx].ep_mps;
g_pyusb_udc.in_ep[ep_idx].actual_xfer_len += g_pyusb_udc.in_ep[ep_idx].ep_mps;
g_pyusb_udc.in_ep[ep_idx].xfer_len -= g_pyusb_udc.in_ep[ep_idx].ep_mps;
} else
{
g_pyusb_udc.in_ep[ep_idx].xfer_buf += g_pyusb_udc.in_ep[ep_idx].xfer_len;
g_pyusb_udc.in_ep[ep_idx].actual_xfer_len += g_pyusb_udc.in_ep[ep_idx].xfer_len;
g_pyusb_udc.in_ep[ep_idx].xfer_len = 0;
}
if (g_pyusb_udc.in_ep[ep_idx].xfer_len == 0)
{
usbd_event_ep_in_complete_handler(ep_idx | 0x80, g_pyusb_udc.in_ep[ep_idx].actual_xfer_len);
} else
{
write_count = MIN(g_pyusb_udc.in_ep[ep_idx].xfer_len, g_pyusb_udc.in_ep[ep_idx].ep_mps);
pyusb_write_packet(ep_idx, g_pyusb_udc.in_ep[ep_idx].xfer_buf, write_count);
USB->IN_CSR1 = USB_INCSR_IPR;
}
txis &= ~(1 << ep_idx);
}
ep_idx++;
}
rxis &= USB->INT_OUT1E;
ep_idx = 1;
while (rxis)
{
if (rxis & (1 << ep_idx))
{
pyusb_set_active_ep(ep_idx);
if (USB->OUT_CSR1 & USB_OUTCSR_OPR)
{
read_count = USB->OUT_COUNT;
pyusb_read_packet(ep_idx, g_pyusb_udc.out_ep[ep_idx].xfer_buf, read_count);
g_pyusb_udc.out_ep[ep_idx].xfer_buf += read_count;
g_pyusb_udc.out_ep[ep_idx].actual_xfer_len += read_count;
g_pyusb_udc.out_ep[ep_idx].xfer_len -= read_count;
if ((read_count < g_pyusb_udc.out_ep[ep_idx].ep_mps) || (g_pyusb_udc.out_ep[ep_idx].xfer_len == 0))
{
USB->INT_OUT1E &= ~(1 << ep_idx);
usbd_event_ep_out_complete_handler(ep_idx, g_pyusb_udc.out_ep[ep_idx].actual_xfer_len);
} else
{
USB->OUT_CSR1 &= ~USB_OUTCSR_OPR;
}
}
rxis &= ~(1 << ep_idx);
}
ep_idx++;
}
pyusb_set_active_ep(old_ep_idx);
}