/**
* @brief USB interrupt processing function
* @pre None
* @param[in] None
* @retval None
*/
__attribute__((interrupt("WCH-Interrupt-fast")))
__attribute__((section(".highcode"))) void
USBD_IRQHandler(void)
{
volatile uint8_t intflag = 0;
intflag = CH58x_USBFS_DEV->USB_INT_FG;
if (intflag & RB_UIF_TRANSFER) {
printf("RB_UIF_TRANSFER: %x\r\n", CH58x_USBFS_DEV->USB_INT_ST);
if ((CH58x_USBFS_DEV->USB_INT_ST & MASK_UIS_TOKEN) != MASK_UIS_TOKEN) {
printf("RB_UIF_TRANSFER: %x\r\n", CH58x_USBFS_DEV->USB_INT_ST);
uint8_t epid = ((CH58x_USBFS_DEV->USB_INT_ST & (MASK_UIS_TOKEN | MASK_UIS_ENDP)) & 0x0f);
printf("epid: 0x%x\r\n", epid);
printf("UIS_TOKEN %x\r\n", (CH58x_USBFS_DEV->USB_INT_ST & (MASK_UIS_TOKEN | MASK_UIS_ENDP)) & 0xf0);
switch ((CH58x_USBFS_DEV->USB_INT_ST & (MASK_UIS_TOKEN | MASK_UIS_ENDP)) & 0xf0) {
case UIS_TOKEN_IN:
if (epid == 0) {
/**
* IN The host takes away the data that has been stored in FIFO
*/
printf("FIFO: 0x%x\r\n", usb_dc_cfg.setup.bmRequestType >> USB_REQUEST_DIR_SHIFT);
switch (usb_dc_cfg.setup.bmRequestType >> USB_REQUEST_DIR_SHIFT) {
case 1:
/*!< Get */
CH58x_USBFS_DEV->UEP0_CTRL ^= RB_UEP_T_TOG;
/**
* Here is to take away the last data, and the IN interrupt will be triggered only after it is successfully taken away.
* Therefore, the status of the in endpoint is set to NAK here. If there is data transmission,
* the endpoint status will be set to ack again in the in handler of EP0.
*/
EPn_SET_TX_NAK(0);
/*!< IN */
if (usb_dc_cfg.ep_in[0].xfer_len > usb_dc_cfg.ep_in[0].mps) {
usb_dc_cfg.ep_in[0].xfer_len -= usb_dc_cfg.ep_in[0].mps;
usb_dc_cfg.ep_in[0].actual_xfer_len += usb_dc_cfg.ep_in[0].mps;
usbd_event_ep_in_complete_handler(0, 0 | 0x80, usb_dc_cfg.ep_in[0].actual_xfer_len);
} else {
usb_dc_cfg.ep_in[0].actual_xfer_len += usb_dc_cfg.ep_in[0].xfer_len;
usb_dc_cfg.ep_in[0].xfer_len = 0;
usbd_event_ep_in_complete_handler(0, 0 | 0x80, usb_dc_cfg.ep_in[0].actual_xfer_len);
}
break;
case 0:
/*!< Set */
switch (usb_dc_cfg.setup.bRequest) {
case USB_REQUEST_SET_ADDRESS:
/*!< Fill in the equipment address */
CH58x_USBFS_DEV->USB_DEV_AD = (CH58x_USBFS_DEV->USB_DEV_AD & RB_UDA_GP_BIT) | usb_dc_cfg.address;
/**
* In the state phase after setting the address, the host has sent an in token packet of data1 to take the packet of 0 length,
* Ch58x USB IP needs to manually set the status of the in endpoint to NAK
*/
EPn_SET_TX_NAK(0);
EPn_SET_RX_VALID(0);
break;
default:
/*!< Normal out state phase */
/**
* The host has sent an in token packet of data1 and taken the packet of 0 length.
* Here, you only need to set the status of the in endpoint to NAK and out endpoint ACK
*/
EPn_SET_TX_NAK(0);
EPn_SET_RX_VALID(0);
break;
}
break;
}
} else {
if (epid == 4) {
CH58x_USBFS_DEV->UEP4_CTRL ^= RB_UEP_T_TOG;
}
EPn_SET_TX_NAK(epid);
if (usb_dc_cfg.ep_in[epid].xfer_len > usb_dc_cfg.ep_in[epid].mps) {
/*!< Need start in again */
usb_dc_cfg.ep_in[epid].xfer_buf += usb_dc_cfg.ep_in[epid].mps;
usb_dc_cfg.ep_in[epid].xfer_len -= usb_dc_cfg.ep_in[epid].mps;
usb_dc_cfg.ep_in[epid].actual_xfer_len += usb_dc_cfg.ep_in[epid].mps;
if (usb_dc_cfg.ep_in[epid].xfer_len > usb_dc_cfg.ep_in[epid].mps) {
memcpy(usb_dc_cfg.ep_in[epid].ep_ram_addr, usb_dc_cfg.ep_in[epid].xfer_buf, usb_dc_cfg.ep_in[epid].mps);
} else {
memcpy(usb_dc_cfg.ep_in[epid].ep_ram_addr, usb_dc_cfg.ep_in[epid].xfer_buf, usb_dc_cfg.ep_in[epid].xfer_len);
}
if (usb_dc_cfg.ep_in[epid].eptype != USB_ENDPOINT_TYPE_ISOCHRONOUS) {
EPn_SET_TX_VALID(epid);
} else {
EPn_SET_TX_ISO_VALID(epid);
}
} else {
usb_dc_cfg.ep_in[epid].actual_xfer_len += usb_dc_cfg.ep_in[epid].xfer_len;
usb_dc_cfg.ep_in[epid].xfer_len = 0;
usbd_event_ep_in_complete_handler(0, epid | 0x80, usb_dc_cfg.ep_in[epid].actual_xfer_len);
}
}
break;
case UIS_TOKEN_OUT:
EPn_SET_RX_NAK(epid);
if (epid == 0) {
/*!< ep0 out */
CH58x_USBFS_DEV->UEP0_CTRL ^= RB_UEP_R_TOG;
uint32_t read_count = EPn_GET_RX_LEN(0);
memcpy(usb_dc_cfg.ep_out[epid].xfer_buf, usb_dc_cfg.ep_out[epid].ep_ram_addr, read_count);
usb_dc_cfg.ep_out[0].actual_xfer_len += read_count;
usb_dc_cfg.ep_out[0].xfer_len -= read_count;
usbd_event_ep_out_complete_handler(0, 0x00, usb_dc_cfg.ep_out[0].actual_xfer_len);
if (read_count == 0) {
/*!< Out status, start reading setup */
EPn_SET_RX_VALID(0);
}
} else {
if ((CH58x_USBFS_DEV->USB_INT_ST) & RB_UIS_TOG_OK) {
if (epid == 4) {
CH58x_USBFS_DEV->UEP4_CTRL ^= RB_UEP_R_TOG;
}
uint32_t read_count = EPn_GET_RX_LEN(epid);
memcpy(usb_dc_cfg.ep_out[epid].xfer_buf, usb_dc_cfg.ep_out[epid].ep_ram_addr, read_count);
usb_dc_cfg.ep_out[epid].xfer_buf += read_count;
usb_dc_cfg.ep_out[epid].actual_xfer_len += read_count;
usb_dc_cfg.ep_out[epid].xfer_len -= read_count;
if ((read_count < usb_dc_cfg.ep_out[epid].mps) || (usb_dc_cfg.ep_out[epid].xfer_len == 0)) {
usbd_event_ep_out_complete_handler(0, ((epid)&0x7f), usb_dc_cfg.ep_out[epid].actual_xfer_len);
} else {
if (usb_dc_cfg.ep_out[epid].eptype != USB_ENDPOINT_TYPE_ISOCHRONOUS) {
EPn_SET_RX_VALID(epid);
} else {
EPn_SET_RX_ISO_VALID(epid);
}
}
}
}
break;
default:
break;
}
CH58x_USBFS_DEV->USB_INT_FG = RB_UIF_TRANSFER;
}
if (CH58x_USBFS_DEV->USB_INT_ST & RB_UIS_SETUP_ACT) {
printf("RB_UIS_SETUP_ACT: %x\r\n", CH58x_USBFS_DEV->USB_INT_ST);
/*!< Setup */
/**
* Setup the device must respond with ACK, and the next data phase is DATA1
* If it is sent, the data1 packet will be sent.
* If it is received, the data1 packet is expected to be received.
* If it is in, the host will send the data1 out packet to complete the status phase after the in completes.
* If it is out, the host will send the data1 in packet to complete the status phase after the out completes.
*/
CH58x_USBFS_DEV->UEP0_CTRL = RB_UEP_R_TOG | RB_UEP_T_TOG | UEP_T_RES_NAK;
/*!< get setup packet */
usb_dc_cfg.setup = GET_SETUP_PACKET(usb_dc_cfg.ep_out[0].ep_ram_addr);
if (usb_dc_cfg.setup.bmRequestType >> USB_REQUEST_DIR_SHIFT == 0) {
/**
* Ep0 The next in must be the status stage.
* The device must reply to the host data 0 length packet.
* Here, set the transmission length to 0 and the transmission status to ACK,
* and wait for the host to send the in token to retrieve
*/
EPn_SET_TX_LEN(0, 0);
EPn_SET_TX_VALID(0);
}
EPn_SET_RX_NAK(0);
usbd_event_ep0_setup_complete_handler(0, (uint8_t *)&(usb_dc_cfg.setup));
CH58x_USBFS_DEV->USB_INT_FG = RB_UIF_TRANSFER;
}
} else if (intflag & RB_UIF_BUS_RST) {
/*!< Reset */
CH58x_USBFS_DEV->USB_DEV_AD = 0;
usbd_event_reset_handler(0);
/*!< Set ep0 rx vaild to start receive setup packet */
EPn_SET_RX_VALID(0);
CH58x_USBFS_DEV->USB_INT_FG = RB_UIF_BUS_RST;
} else if (intflag & RB_UIF_SUSPEND) {
if (CH58x_USBFS_DEV->USB_MIS_ST & RB_UMS_SUSPEND) {
/*!< Suspend */
} else {
/*!< Wake up */
}
CH58x_USBFS_DEV->USB_INT_FG = RB_UIF_SUSPEND;
} else {
CH58x_USBFS_DEV->USB_INT_FG = intflag;
}
}
硬件是否正常,是否使用杜邦线连接,如果正常,请说明正常原因
USB 中断,时钟,引脚,寄存器地址是否正确,截图
是否能进 USB 中断
芯片是否带有 cache功能,是否做了 no cache 处理,截图
打开 CONFGI_USBDEV_SETUP_LOG_PRINT,并提供 log
是否流片并销售
是
其他