完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
看了提供的一些例程,在USBSetuPCB中厂商自定义命令处理业务中,有的例程在CyU3PUsbSendEP0Data或CyU3PUsbGetEP0Data调用后有跟着调用CyU3PUsbAckSetup,有的没有。这个到底需不需要调用呢?
在以下例程中,是有调用的 basic_examples/cyfxbulklpautoenum/cyfxbulklpautoenum.c /* Callback to handle the USB setup requests. */CyBool_tCyFxBulkLpApplnUSBSetupCB ( uint32_t setupdat0, /* SETUP Data 0 */ uint32_t setupdat1 /* SETUP Data 1 */ ){ CyBool_t isHandled = CyTrue; CyU3PReturnStatus_t status = CY_U3P_SUCCESS; uint8_t bRequest, bReqType; uint8_t bType, bTarget; uint16_t wValue, wIndex, wLength; /* Decode the fields from the setup request. */ bReqType = (setupdat0 CY_U3P_USB_REQUEST_TYPE_MASK); bType = (bReqType CY_U3P_USB_TYPE_MASK); bTarget = (bReqType CY_U3P_USB_TARGET_MASK); bRequest = ((setupdat0 CY_U3P_USB_REQUEST_MASK) >> CY_U3P_USB_REQUEST_POS); wValue = ((setupdat0 CY_U3P_USB_VALUE_MASK) >> CY_U3P_USB_VALUE_POS); wIndex = ((setupdat1 CY_U3P_USB_INDEX_MASK) >> CY_U3P_USB_INDEX_POS); wLength = ((setupdat1 CY_U3P_USB_LENGTH_MASK) >> CY_U3P_USB_LENGTH_POS); /* The only supported vendor command is to reset the FX3 device. */ if (bType == CY_U3P_USB_VENDOR_RQT) { if ((bRequest == 0xE0) (wLength == 0)) { glResetDevice = CyTrue; CyU3PUsbAckSetup (); return CyTrue; } return CyFalse; } /* Identify and handle setup request. */ switch (bRequest) { /* This is a get status request. The response depends on the target. * If this is for the device, then we need to return the status * of the device. If this is for the endpoint, then return the stall * status of the endpoint. */ case CY_U3P_USB_SC_GET_STATUS: CyU3PMemSet (glEp0Buffer, 0, sizeof(glEp0Buffer)); if (bTarget == CY_U3P_USB_TARGET_DEVICE) { glEp0Buffer[0] = glUsbDeviceStat; status = CyU3PUsbSendEP0Data (wLength, glEp0Buffer); } else if (bTarget == CY_U3P_USB_TARGET_INTF) { /* Just send zeros. */ status = CyU3PUsbSendEP0Data (wLength, glEp0Buffer); } else if (bTarget == CY_U3P_USB_TARGET_ENDPT) { CyBool_t isStall; status = CyU3PUsbGetEpCfg (wIndex, NULL, isStall); if (status == CY_U3P_SUCCESS) { glEp0Buffer[0] = isStall; status = CyU3PUsbSendEP0Data (wLength, glEp0Buffer); } } else { isHandled = CyFalse; } break; /* This feature behaves differently depending upon the target. * If the target is device then, this request is for remote-wakeup, * test mode, U1_ENABLE and U2_ENABLE. If this is for the endpoint * then this is for clearing the endpoint stall. */ case CY_U3P_USB_SC_CLEAR_FEATURE: isHandled = CyFxUsbHandleClearFeature (bTarget, wValue, wIndex); break; /* This feature behaves differently depending upon the target. * If the target is device then, this request is for remote-wakeup, * test mode, U1_ENABLE and U2_ENABLE. If this is for the endpoint * then this is for clearing the endpoint stall. */ case CY_U3P_USB_SC_SET_FEATURE: isHandled = CyFxUsbHandleSetFeature (bTarget, wValue, wIndex); break; /* Return the requested descriptor. */ case CY_U3P_USB_SC_GET_DESCRIPTOR: status = CyFxUsbSendDescriptor (wValue, wIndex, wLength); break; case CY_U3P_USB_SC_SET_DESCRIPTOR: /* ACK the request and do nothing. */ break; /* Return the current selected configuration. */ case CY_U3P_USB_SC_GET_CONFIGURATION: glEp0Buffer[0] = glUsbConfiguration; status = CyU3PUsbSendEP0Data (wLength, glEp0Buffer); break; /* Store the value for future use and start the application. */ case CY_U3P_USB_SC_SET_CONFIGURATION: if (wValue == 1) { /* Disable the low power entry to optimize USB throughput */ CyU3PUsbLPMDisable(); /* If the application is already active, then disable * it before re-enabling it. */ glUsbConfiguration = wValue; if (glIsApplnActive) { CyFxBulkLpApplnStop (); } /* Start the loop back function. */ CyFxBulkLpApplnStart (); } else { if (wValue == 0) { /* Stop the loop back function. */ glUsbConfiguration = wValue; if (glIsApplnActive) { CyFxBulkLpApplnStop (); } } else { /* Invalid configuration value. Fail the request. */ CyU3PUsbStall (0, CyTrue, CyFalse); } } break; /* Return the current selected interface. */ case CY_U3P_USB_SC_GET_INTERFACE: glEp0Buffer[0] = glUsbInterface; status = CyU3PUsbSendEP0Data (wLength, glEp0Buffer); break; /* Store the selected interface value. */ case CY_U3P_USB_SC_SET_INTERFACE: glUsbInterface = wValue; break; case CY_U3P_USB_SC_SET_SEL: { if ((CyU3PUsbGetSpeed () == CY_U3P_SUPER_SPEED) (wValue == 0) (wIndex == 0) (wLength == 6)) { status = CyU3PUsbGetEP0Data (32, glSelBuffer, 0); } else { isHandled = CyFalse; } } break; case CY_U3P_USB_SC_SET_ISOC_DELAY: { if ((CyU3PUsbGetSpeed () != CY_U3P_SUPER_SPEED) || (wIndex != 0) || (wLength != 0)) isHandled = CyFalse; } break; default: isHandled = CyFalse; break; } /* If there has been an error, stall EP0 to fail the transaction. */ if ((isHandled != CyTrue) || (status != CY_U3P_SUCCESS)) { /* This is an unhandled setup command. Stall the EP. */ CyU3PUsbStall (0, CyTrue, CyFalse); } else { CyU3PUsbAckSetup (); } return CyTrue;} 在以下例程中,没有 serialif_examples/cyfxusbi2cregmode/cyfxusbi2cregmode.c CyBool_tCyFxUSBSetupCB ( uint32_t setupdat0, uint32_t setupdat1){ /* Fast enumeration is used. Only requests addressed to the interface, class, * vendor and unknown control requests are received by this function. */ uint8_t i2cAddr; uint8_t bRequest, bReqType; uint8_t bType, bTarget; uint16_t wValue, wIndex, wLength; CyBool_t isHandled = CyFalse; CyU3PReturnStatus_t status = CY_U3P_SUCCESS; /* Decode the fields from the setup request. */ bReqType = (setupdat0 CY_U3P_USB_REQUEST_TYPE_MASK); bType = (bReqType CY_U3P_USB_TYPE_MASK); bTarget = (bReqType CY_U3P_USB_TARGET_MASK); bRequest = ((setupdat0 CY_U3P_USB_REQUEST_MASK) >> CY_U3P_USB_REQUEST_POS); wValue = ((setupdat0 CY_U3P_USB_VALUE_MASK) >> CY_U3P_USB_VALUE_POS); wIndex = ((setupdat1 CY_U3P_USB_INDEX_MASK) >> CY_U3P_USB_INDEX_POS); wLength = ((setupdat1 CY_U3P_USB_LENGTH_MASK) >> CY_U3P_USB_LENGTH_POS); if (bType == CY_U3P_USB_STANDARD_RQT) { /* Handle SET_FEATURE(FUNCTION_SUSPEND) and CLEAR_FEATURE(FUNCTION_SUSPEND) * requests here. It should be allowed to pass if the device is in configured * state and failed otherwise. */ if ((bTarget == CY_U3P_USB_TARGET_INTF) ((bRequest == CY_U3P_USB_SC_SET_FEATURE) || (bRequest == CY_U3P_USB_SC_CLEAR_FEATURE)) (wValue == 0)) { if (glIsApplnActive) CyU3PUsbAckSetup (); else CyU3PUsbStall (0, CyTrue, CyFalse); isHandled = CyTrue; } } /* Handle supported vendor requests. */ if (bType == CY_U3P_USB_VENDOR_RQT) { isHandled = CyTrue; switch (bRequest) { case CY_FX_RQT_ID_CHECK: CyU3PUsbSendEP0Data (8, (uint8_t *)glFirmwareID); break; case CY_FX_RQT_I2C_EEPROM_WRITE: i2cAddr = 0xA0 | ((wValue 0x0007) << 1); status = CyU3PUsbGetEP0Data(wLength, glEp0Buffer, NULL); if (status == CY_U3P_SUCCESS) { CyFxUsbI2cTransfer (wIndex, i2cAddr, wLength, glEp0Buffer, CyFalse); } break; case CY_FX_RQT_I2C_EEPROM_READ: i2cAddr = 0xA0 | ((wValue 0x0007) << 1); CyU3PMemSet (glEp0Buffer, 0, sizeof (glEp0Buffer)); status = CyFxUsbI2cTransfer (wIndex, i2cAddr, wLength, glEp0Buffer, CyTrue); if (status == CY_U3P_SUCCESS) { status = CyU3PUsbSendEP0Data(wLength, glEp0Buffer); } break; default: /* This is unknown request. */ isHandled = CyFalse; break; } /* If there was any error, return not handled so that the library will * stall the request. Alternatively EP0 can be stalled here and return * CyTrue. */ if (status != CY_U3P_SUCCESS) { isHandled = CyFalse; } } return isHandled;} |
|
相关推荐
1个回答
|
|
在USBSetupCB的最后,调用CyU3PUsbAckSetup是可选的。它用于向主机发送一个ACK响应,表示已成功处理了USB SETUP请求。如果处理USB SETUP请求后不调用CyU3PUsbAckSetup,主机可能会超时并重新发送请求。
在提供的例程中,有些例程可能没有显示调用CyU3PUsbAckSetup,而是间接地通过调用CyU3PUsbSendEP0Data或CyU3PUsbGetEP0Data来隐式地发送ACK响应。在这种情况下,主机会收到数据传输完成的信号,从而知道USB SETUP请求已被处理。 但是,为了遵循USB规范并确保与不同的主机设备正常通信,建议在USBSetupCB中完成处理后始终调用CyU3PUsbAckSetup。这样可以明确地告知主机请求已被处理,并避免潜在的通信错误。 |
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
5195 浏览 0 评论
9337 浏览 3 评论
【开源资料】基于机智云的智能感应灯(原理图+PCB+源程序)
46246 浏览 4 评论
3713 浏览 0 评论
4135 浏览 0 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-9 01:36 , Processed in 0.585151 second(s), Total 44, Slave 37 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号