You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When the endpoints max packet size equals the data to send size, usbx does not send a zlp, therefore the host does not recognize the transfer as complete.
Reproduce:
Ux_Device_CDC_ACM example
Change usbx_cdc_acm_write_thread_entry to something like this:
/* Get the device */
device = &_ux_system_slave->ux_system_slave_device;
/* Get the data interface */
data_interface = device->ux_slave_device_first_interface->ux_slave_interface_next_interface;
/* Get the cdc Instance */
cdc_acm = data_interface->ux_slave_interface_class_instance;
cdc_acm -> ux_slave_class_cdc_acm_transmission_status = UX_FALSE;
buffsize = 0;
for(int i = 0; i < testlength; i++)
{
UserTxBufferFS[i] = '1';
buffsize++;
}
/* Send data over the class cdc_acm_write */
ux_status = ux_device_class_cdc_acm_write(cdc_acm,
(UCHAR *)UserTxBufferFS,
buffsize, &actual_length);
/* Check if dataset is correctly transmitted */
if (ux_status)
{
tx_thread_sleep(100);
}
tx_thread_sleep(100);
Set testlength to endpoints max packet size
Host wont recognize data
Analysis:
After investigation i found several issues,
host_length != slave_length will be false even if zlp is needed
when removed the host_length != slave_length in issue one and use this code for HAL_PCD_DataInStageCallback its working:
void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
{
UX_SLAVE_DCD *dcd;
UX_DCD_STM32 *dcd_stm32;
UX_DCD_STM32_ED *ed;
UX_SLAVE_TRANSFER *transfer_request;
ULONG transfer_length;
UX_SLAVE_ENDPOINT *endpoint;
/* Get the pointer to the DCD. */
dcd = &_ux_system_slave -> ux_system_slave_dcd;
/* Get the pointer to the STM32 DCD. */
dcd_stm32 = (UX_DCD_STM32 *) dcd -> ux_slave_dcd_controller_hardware;
/* Fetch the address of the physical endpoint. */
ed = &dcd_stm32 -> ux_dcd_stm32_ed[epnum & 0xF];
/* Get the pointer to the transfer request. */
transfer_request = &(ed -> ux_dcd_stm32_ed_endpoint -> ux_slave_endpoint_transfer_request);
/* Endpoint 0 is different. */
if (epnum == 0U)
{
/* Get the pointer to the logical endpoint from the transfer request. */
endpoint = transfer_request -> ux_slave_transfer_request_endpoint;
/* Check if we need to send data again on control endpoint. */
if (ed -> ux_dcd_stm32_ed_state == UX_DCD_STM32_ED_STATE_DATA_TX)
{
/* Arm Status transfer. */
HAL_PCD_EP_Receive(hpcd, 0, 0, 0);
/* Are we done with this transfer ? */
if (transfer_request -> ux_slave_transfer_request_in_transfer_length <= endpoint -> ux_slave_endpoint_descriptor.wMaxPacketSize)
{
/* There is no data to send but we may need to send a Zero Length Packet. */
if (transfer_request -> ux_slave_transfer_request_force_zlp == UX_TRUE)
{
/* Arm a ZLP packet on IN. */
HAL_PCD_EP_Transmit(hpcd,
endpoint->ux_slave_endpoint_descriptor.bEndpointAddress, 0, 0);
/* Reset the ZLP condition. */
transfer_request -> ux_slave_transfer_request_force_zlp = UX_FALSE;
}
else
{
/* Set the completion code to no error. */
transfer_request -> ux_slave_transfer_request_completion_code = UX_SUCCESS;
/* The transfer is completed. */
transfer_request -> ux_slave_transfer_request_status = UX_TRANSFER_STATUS_COMPLETED;
/* We are using a Control endpoint, if there is a callback, invoke it. We are still under ISR. */
if (transfer_request -> ux_slave_transfer_request_completion_function)
transfer_request -> ux_slave_transfer_request_completion_function (transfer_request) ;
/* State is now STATUS RX. */
ed -> ux_dcd_stm32_ed_state = UX_DCD_STM32_ED_STATE_STATUS_RX;
}
}
else
{
/* Get the size of the transfer. */
transfer_length = transfer_request -> ux_slave_transfer_request_in_transfer_length - endpoint -> ux_slave_endpoint_descriptor.wMaxPacketSize;
/* Check if the endpoint size is bigger that data requested. */
if (transfer_length > endpoint -> ux_slave_endpoint_descriptor.wMaxPacketSize)
{
/* Adjust the transfer size. */
transfer_length = endpoint -> ux_slave_endpoint_descriptor.wMaxPacketSize;
}
/* Adjust the data pointer. */
transfer_request -> ux_slave_transfer_request_current_data_pointer += endpoint -> ux_slave_endpoint_descriptor.wMaxPacketSize;
/* Adjust the transfer length remaining. */
transfer_request -> ux_slave_transfer_request_in_transfer_length -= transfer_length;
/* Transmit data. */
HAL_PCD_EP_Transmit(hpcd,
endpoint->ux_slave_endpoint_descriptor.bEndpointAddress,
transfer_request->ux_slave_transfer_request_current_data_pointer,
transfer_length);
}
}
}
else
{
if (transfer_request -> ux_slave_transfer_request_force_zlp == UX_TRUE)
{
/* Get the pointer to the logical endpoint from the transfer request. */
endpoint = transfer_request -> ux_slave_transfer_request_endpoint;
/* Arm a ZLP packet on IN. */
HAL_PCD_EP_Transmit(hpcd,
endpoint->ux_slave_endpoint_descriptor.bEndpointAddress, 0, 0);
/* Reset the ZLP condition. */
transfer_request -> ux_slave_transfer_request_force_zlp = UX_FALSE;
}else{
/* Set the completion code to no error. */
transfer_request -> ux_slave_transfer_request_completion_code = UX_SUCCESS;
/* The transfer is completed. */
transfer_request -> ux_slave_transfer_request_status = UX_TRANSFER_STATUS_COMPLETED;
/* Non control endpoint operation, use semaphore. */
_ux_utility_semaphore_put(&transfer_request -> ux_slave_transfer_request_semaphore);
}
}
}
The text was updated successfully, but these errors were encountered:
I am having the same issue using PIMA class. The ZLP is not transmitted.
Using your modified callback function that send ZLP for other endpoint than 0 works for me.
Thank you!
Board: Nucleo F429zi
IDE: CubeIDE
When the endpoints max packet size equals the data to send size, usbx does not send a zlp, therefore the host does not recognize the transfer as complete.
Reproduce:
Ux_Device_CDC_ACM example
Change usbx_cdc_acm_write_thread_entry to something like this:
Set testlength to endpoints max packet size
Host wont recognize data
Analysis:
After investigation i found several issues,
host_length != slave_length will be false even if zlp is needed
x-cube-azrtos-h7/Middlewares/ST/usbx/common/core/src/ux_device_stack_transfer_request.c
Lines 150 to 168 in 84ed811
even if
transfer_request -> ux_slave_transfer_request_force_zlp gets set to UX_TRUE the zlp wont be sended because its exclusive to endpoint 0, see:
x-cube-azrtos-h7/Middlewares/ST/usbx/common/usbx_stm32_device_controllers/ux_dcd_stm32_callback.c
Lines 237 to 349 in 84ed811
when removed the host_length != slave_length in issue one and use this code for HAL_PCD_DataInStageCallback its working:
The text was updated successfully, but these errors were encountered: