2014-06-14 06:30 AM
I don't know whether this is related to the STM32CubeF4 package or the STM32F407 so I'll post here.
I'm using the STM32F4 discovery board and the onboard USB FS port.I wrote a VCP interface that lets me send a buffer of any length (basically just expanded the CDC example), but when I try to send a buffer with a length which is a multiple of the FS max packet size (64 bytes) the data is not transferred immediately but only on the next call to USBD_LL_Transmit (which in turn calls HAL_PCD_EP_Transmit).I tested this with 64 and 128 byte buffers.Am I doing something wrong here, is this a known bug or a new bug?And is it more likely related to the STM32CubeF4 or the chip itself?What I already did is look through the HAL firmware code but as far as I can see there's no rounding errors or similar that would cause such an issue...2014-06-18 01:09 AM
Hi,
Change ''if(((CDC_Handle->RxDataLength - length) > 0) && (length > CDC_Handle->DataItf.InEpSize))'' by ''if(((CDC_Handle->RxDataLength - length) >= 0) && (length >= CDC_Handle->DataItf.InEpSize))''2014-06-18 01:37 AM
Hi, I don't think that's anywhere in my code...
I did grep forRxDataLength
but didn't find anything.
2014-07-11 08:19 AM
Bump, I still have this problem with the new 1.3.0 HAL version.
I scanned the source code quite thoroughly but didn't find anything obvious (to me) that could cause this.Any ideas?2014-07-11 01:26 PM
I'm struggling with the same problem. The solution is to send an additional
ZLP (zero length packet) but I don't figured it out at the moment how to manage this.Btw.: how did you realize your VCP receive function ?2014-07-11 04:29 PM
ZLP, that's the info I needed.
I got it working now by sending a ZLP in theDataIn
callback of the VCP (former CDC, I renamed everything) class if the transfer size is a multiple of the packet size. Like so:PCD_HandleTypeDef *hpcd = pdev->pData;
PCD_EPTypeDef *ep = &hpcd->IN_ep[epnum];
// For transfers exactly a multiple of the packet size, we need to send a zero length packet to complete
if
(ep->xfer_len && (ep->xfer_len / ep->maxpacket) * ep->maxpacket == ep->xfer_len)
{
ep->xfer_len = 0;
USB_EPStartXfer(hpcd->Instance, ep, 0);
}
The proper place to do this would probably be
HAL_PCD_IRQHandler
, but that calls theDataIn
callback anyway. Regarding the receive function, I don't really know what you mean. I just use the Receive function from the template and piece together a command line from received characters. Or do you mean the transmit function?2014-07-14 02:18 AM
Hello Peter,
where can I find the DataIn function you mentioned ?Could you explain why my approach doesn't work:uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len){ uint8_t result = USBD_OK; /* USER CODE BEGIN 8 */ USBD_CDC_SetTxBuffer(hUsbDevice_0, Buf, Len); result = USBD_CDC_TransmitPacket(hUsbDevice_0); if ((Len%64==0) && (result==USBD_OK)) { USBD_CDC_SetTxBuffer(hUsbDevice_0, Buf, 0); result = USBD_CDC_TransmitPacket(hUsbDevice_0); } /* USER CODE END 8 */ return result;}Which library version do you use ?2014-07-14 03:36 AM
It's actually called
USBD_CDC_DataIn
in the CDC class fileusbd_cdc.c
It's the function that is called when an IN transfer is complete.I guess the transfer isn't finished when you callUSBD_CDC_TransmitPacket
the second time, do you getUSBD_OK
orUSBD_BUSY
returned?I use 1.3.02014-07-14 04:00 AM
I get ''USBD_OK''
2014-07-14 04:25 AM
Try to send more data than the TX FIFO holds, maybe you get
USBD_BUSY
then.Other than that, I have no idea. Just use the callback like I do, seems more logical to do it this way and it works.