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-07-28 11:31 AM
Hi Peter,
I've also been struggling trying to make the vcp work. Would you be able to share your code? Best, Luis2014-07-28 02:24 PM
As I said I pretty much use the template and piece together a command line from received characters, but that's rather application specific.
What kind of problems do you have?2014-10-15 02:58 AM
Hi Peter,
How do you handle USB transfer, are you using USBD_CDC_SetTxBuffer() and USBD_CDC_TransmitPacket()? I've tested your use case with two different buffers 64 and 128 bytes and it is working for me, as it follows:USBD_CDC_SetTxBuffer(&USBD_Device, (uint8_t*)StatUserTxBuffer, sizeof(StatUserTxBuffer));
if(USBD_CDC_TransmitPacket(&USBD_Device) == USBD_OK)
{
}
Regards,
Heisenberg.
2015-05-30 09:34 AM
Heisenberg, sorry for not getting back to you.
I don't know if this is still an issue with the newest HAL version, I have not updated yet (the project is on pause, that's why I've not been here).Anyway, I'll answer this now:Yes I'm usingSetTxBuffer()
andTransmitPacket()
, however I didn't test it with FS USB, only HS USB where the maximum packet size is 512 bytes.Also, I can't remember exactly, but from what I recall this was only a problem on Windows (I could be wrong though, it's been some time).2015-06-01 02:49 PM
2015-06-19 09:46 AM
The crux of the problem - if you trace it down to hardware - is that DMA is used to send the data. The high level routine ''USBD_CDC_TransmitPacket'' just ultimately sets up the DMA but after it does, it returns ok. If you go ahead and reuse your buffer after that hight level ok, then potentially the DMA will send what you put next into your buffer. So when you do a one of, it all works. But in a real system those buffers are moving around and getting used for other things. So using a buffer which is not really free is where the problem lies.
For instance if I make a call to USBD_CDC_TransmitPacket and I don't use that buffer for anything else until I see the data pop out the other end of the USB connection, then all is well. However if I zero that buffer right after the call, even tho I received a ''HAL is ok'' reply, then when the DMA gets to sending the buffer, it won't be what I wanted.The function USBD_CDC_DataIn seems to be called after the data has been sent, so using it as a call back makes sense. Unfortunately it has no user code space in it. It is not called directly either so finding the call chain is difficult. One could either drop a user piece of code into that call or perhaps replace it in the class callbacks data structure. Both options are not nice. With some of the other drivers, there is a weak callback function which can be replaced or there are user code areas that are respected by the code generator. This seems to be lacking.The callback to USBD_CDC_DataIn seems to just set the TxState to 0. So one could in theory poll that state by calling USBD_CDC_TransmitPacket with a zero length packet until it said ok but unfortunately that will set the state to non zero. Or perhaps one could keep the old buffer until the new one is accepted. Many ways of ugly.I should point out that there is a weak callback but that is used by the CDC code. There is no link back to user code to let the use know when to reuse the buffer. The chain starts from: HAL_PCD_IRQHandlerwhich calls: HAL_PCD_DataInStageCallback (this is the weak call back but gets defined in CDC code) which calls: USBD_LL_DataInStagewhich finally calls: USBD_CDC_DataIn and this is where it all ends.The user code is unaware of that chain of events.2015-06-19 12:35 PM
Well as it turns out life is even stranger than we can imagine. I thought I had my problem solved by tying into USBD_CDC_DataIn but that didn't help. It turns out that my buffer pool was the problem. I have a pool of buffers allocated at compile time and then divvied up at run time according to a calculated length. This results in buffers not starting on 4 byte address boundary. Even tho the buffers contain bytes, something - probably DMA - doesn't like to start on a non-aligned boundary. I found this out by printing the buffer addresses as they were being used and noticed that for the ok frames sent, it was on aligned buffer boundaries. So be warned, if you pass a non-aligned address to USBD_CDC_SetTxBuffer, you might not send what is in the buffer. There rightfully should be a note in the code about this or it should just accept it and work with it.
2016-02-18 01:37 AM
if you still have issues with this, look at my post