2026-05-04 2:56 AM - last edited on 2026-05-05 8:51 AM by FBL
Split from this thread
My firmware is based on this ccid usbd driver https://github.com/STMicroelectronics/stm32-mw-usb-device/blob/master/Class/CCID/Src/usbd_ccid.c .
The issue that I face, the PC finishes receiving data immediately after receiving 256 bytes (10 bytes of header + 246 bytes of data). when I want to send to pc 253 bytes of data + 10 bytes of header (263 bytes in total) by splitting (64 bytes by 64 bytes) the PC finishes receiving data immediately after receiving the fourth chunk which is 256 bytes (10 bytes of header and 243 bytes of data), It doesn't wait for the fifth chunk, which carries the remaining 7 bytes of my data which arrives in an unknown message despite the fact that I define the size of the data to be sent as 253 bytes. Images 1 and 2 show these details captured by wireshark software.1
2
this is my code used to send data by chunks :
uint8_t SC_Itf_XferBlock(uint8_t *ptrBlock, uint32_t blockLen, uint16_t expectedLen,
USBD_CCID_BulkIn_DataTypeDef *CCID_BulkIn_Data)
{
uint8_t ErrorCode = SLOT_NO_ERROR;
UNUSED(CCID_BulkIn_Data);
UNUSED(expectedLen);
UNUSED(blockLen);
UNUSED(ptrBlock);
if (ProtocolNUM_OUT == 0x00U)
{
/* Add your code here */
}
if (ProtocolNUM_OUT == 0x01U)
{
/* Add your code here */
data_to_send_size = 253;
CCID_BulkIn_Data->dwLength = data_to_send_size;
memcpy(CCID_BulkIn_Data->abData, data_to_send, data_to_send_size);
if (data_to_send_size > 54U)
{
tx_remaining_ptr = &data_to_send[54];
tx_remaining_len = data_to_send_size - 54;
tx_in_progress = 1;
}
else
{
tx_remaining_ptr = NULL;
tx_remaining_len = 0;
tx_in_progress = 0;
}
}
if (ErrorCode != SLOT_NO_ERROR)
{
return ErrorCode;
}
return ErrorCode;
}
static uint8_t USBD_CCID_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum)
{
USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
#ifdef USE_USBD_COMPOSITE
/* Get the Endpoints addresses allocated for this class instance */
CCIDInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
CCIDCmdEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_INTR, (uint8_t)pdev->classId);
#endif /* USE_USBD_COMPOSITE */
if (epnum == (CCIDInEpAdd & 0x7FU))
{
/* Filter the epnum by masking with 0x7f (mask of IN Direction) */
/*************** Handle Bulk Transfer IN data completion *****************/
switch (hccid->blkt_state)
{
case CCID_STATE_SEND_RESP:
/* won't wait ack to avoid missing a command */
if(tx_in_progress && tx_remaining_len > 0)
{
uint8_t chunk = (tx_remaining_len > 64) ? 64 : tx_remaining_len;
USBD_LL_Transmit(pdev, CCIDInEpAdd, (uint8_t *)tx_remaining_ptr, chunk);
tx_remaining_ptr += chunk;
tx_remaining_len -= chunk;
}
else
{
tx_in_progress = 0;
hccid->blkt_state = CCID_STATE_IDLE;
/* Prepare EP to Receive Cmd */
(void)USBD_LL_PrepareReceive(pdev, CCID_OUT_EP,
hccid->data, hccid->MaxPcktLen);
}
break;
default:
break;
}
}
else if (epnum == (CCIDCmdEpAdd & 0x7FU))
{
/* Filter the epnum by masking with 0x7f (mask of IN Direction) */
/*************** Handle Interrupt Transfer IN data completion *****************/
(void)USBD_CCID_IntMessage(pdev);
}
else
{
return (uint8_t)USBD_FAIL;
}
return (uint8_t)USBD_OK;
}