cancel
Showing results for 
Search instead for 
Did you mean: 

USB CDC Bug in CubeMX firmware

richard239955
Associate II
Posted on April 11, 2014 at 10:07

Hey everybody,

in order to initialize a working Virtual Com Port with CubeMX on the STM32F4 Discovery, I had to change

   pdev->pClassData = USBD_malloc(sizeof (USBD_CDC_HandleTypeDef));

to

   pdev->pClassData = (void *) USBD_malloc(sizeof (USBD_CDC_HandleTypeDef));

Without the type cast pClassData would always be null, which will make the parent function (USBD_CDC_Init in usbd_cdc.c) return before initializing the interface.

Btw I used firmware 1.1.0.

EDIT: Sorry, that was too fast. This line was actually not the root cause, it was the following line in USB_CDC.h

   &sharpdefine CDC_DATA_HS_MAX_PACKET_SIZE        512

Changing that value to 256 made it work for me now. In case anyone is interested, here's a small code example for a vcp mirror. Add this code to CDC_Receive in usb_cdc_if.c

    static uint8_t buff_RX[256];

    static uint8_t buff_TX[256];

    

    int i = 0;

    

    for (i = 0; i < *Len; i++)

        buff_TX[i] = buff_RX[i];

    

    USBD_CDC_SetTxBuffer(&hUsbDeviceFS, &buff_TX[0], *Len);

    USBD_CDC_TransmitPacket(&hUsbDeviceFS);

    

    USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &buff_RX[0]);

    USBD_CDC_ReceivePacket(&hUsbDeviceFS);

Also you will have to add

    extern USBD_HandleTypeDef hUsbDeviceFS;

to this file.

 

#usb #cdc #cdc #cdc #cdc_receive_fs #full-echo #usb-cdc #vcp #vcp
49 REPLIES 49
derun_a
Associate II
Posted on May 13, 2014 at 10:50

Hi Ramdas,

I have generated the basis for the project by CubeMX

In my case the function  CDC_Init(void) is also empty.

It works in spite of this.

But you can add your code if you need.

ayyaramdas
Associate II
Posted on May 14, 2014 at 06:24

hi Andrii,

thanks for the reply. currently the PC is detecting the device but if i see in the device manager there is yellow exclamatory saying the following message ''This device cannot start. (Code 10)''  seems like the code which i flashed is not handling the SOF correctly.

please could you share me your STM32CubeMX and the keil project. i am using a Win7 PC.

Thanks in advance.

Ramdas

derun_a
Associate II
Posted on May 14, 2014 at 13:29

Hi Ramdas,

I didn't have the problem such as yours.

But I have seen the forum discussion where people have the same problem.

The advice was: disable the verification of the digital signature for the driver.

But I don't know if it helps.

I use the OlimexSTM32-E407 development board and Eclipse withGNU Tools for ARM Embedded toolchains. Windows 7 x64 platform.

There is the Cube configuration file in the attachment.

________________

Attachments :

led_key_usb_cube.ioc : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006HzMF&d=%2Fa%2F0X0000000bL8%2FGk.Y4gQ3S2Hs_0b1QnS2f.e7bU2nW2MbVQ59HHaan78&asPdf=false
arnaljl
Associate III
Posted on May 15, 2014 at 02:05

I'm dealing with the same problem here: the CDC_Receive(..) method from usbd_cdc_if.c is called once when I first send some ''hello world'' through the host's serial terminal, and always stalls on subsequent sends.

As far as I known, even the USBD_CDC_DataOut method from USBD_CDC.c isn't called when I send a second packet to the VCP.

I'm using a ''raw'' STM32CubeMX custom project made from the built-in STM32F429I Disco template (since it's the board I'm working with), along with ST's VCP x64 drivers, ver 1.3.1 .

My STM32CubeMX project file is attached here, btw. (nb : easy to guess what I'm try to port on the CM4 architecture 😉 )

The device successfully goes through every config steps with flying colors.

Only added a global variable byte to monitor my small serial RX packets, making the green led (LD3) blink. The red one always blinks to monitor any infinite loop or unexpected fault ISR, but this case hasn't happened yet. No infinite loop for me, just the CDC reception stalling.

here's my main.c 's main()

 
/* Private function prototypes -----------------------------------------------*/
static
void
SystemClock_Config(
void
);
uint8_t cdc_activity;
 
int
main(
void
)
{
 
/* USER CODE BEGIN 1 */
cdc_activity = 0;
/* USER CODE END 1 */
 
/* MCU Configuration----------------------------------------------------------*/
 
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
 
/* Configure the system clock */
SystemClock_Config();
 
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA_Init();
// MX_ADC3_Init();
MX_CRC_Init();
// MX_DAC_Init();
MX_FMC_Init();
MX_RNG_Init();
// MX_SDIO_SD_Init();
// MX_SPI4_Init();
// MX_TIM6_Init();
// MX_USART1_UART_Init();
MX_USB_DEVICE_Init();
 
/* USER CODE BEGIN 2 */
 
/* USER CODE END 2 */
 
/*## FatFS: Link the SD disk I/O driver ###############################*/
// SD_DriverNum = FATFS_LinkDriver(&SD_Driver, SD_Path);
 
/* USER CODE BEGIN 3 */
/* Infinite loop */
while
(1)
{
Led_Red_Toggle();
HAL_Delay(125);  
if
( cdc_activity )
{
cdc_activity--;
Led_Green_Toggle();
}
}
/* USER CODE END 3 */
 
}

Notice I disabled any unused (for the time being) peripherals. I'm not planning to use the LCD for my tests but this is another story.

and the ''modified'' CDC_Receive()

 
extern
uint8_t cdc_activity;
static
int8_t CDC_Receive (uint8_t* Buf, uint32_t *Len)<br>
{
/* USER CODE BEGIN 7 */
cdc_activity = (uint8_t)*Len;
return
(USBD_OK);
/* USER CODE END 7 */
}
 

I haven't found the problem yet. It's late, I'm tired, and calling it a night.

Best luck tomorrow, maybe.

Also, I noticed something strange in the CDC_Init() method :

static
int8_t CDC_Init(
void
)
{
hUsbDevice_0 = &hUsbDeviceHS;
/* USER CODE BEGIN 4 */
/* Set Application Buffers */
USBD_CDC_SetTxBuffer(hUsbDevice_0, UserTxBuffer, 0); 
// <-- shouldn't this receive APP_TX_DATA_SIZE as its last argument ?
USBD_CDC_SetRxBuffer(hUsbDevice_0, UserRxBuffer);
return
(USBD_OK);
/* USER CODE END 4 */
}

Shouldn't the USBD_CDC_SetTxBuffer() method be called with APP_TX_DATA_SIZE as its last argument ?

________________

Attachments :

Repetier429I.ioc : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006HzOT&d=%2Fa%2F0X0000000bL7%2Fs0P1zgKv_wXg3uvZchnDQjLJYY1jUVEFnMU1hmtWoUI&asPdf=false
ayyaramdas
Associate II
Posted on May 15, 2014 at 04:48

hi Andril,

i now solved the issue with richard's solution. so to bother you all. 

now it communicates once, let me test it fully and then come share my experience.

thanks to all ,

Ramdas

arnaljl
Associate III
Posted on May 15, 2014 at 14:12

Okay, so, another day, another step, I stumbled bs's post #13 on this

https://my.st.com/public/STe2ecommunities/mcu/Lists/STM32Java/Flat.aspx?RootFolder=https%3a//my.st.com/public/STe2ecommunities/mcu/Lists/STM32Java/USB%20middleware%20issue%20with%20CDCVCP%20only%20x%20packets%20receivable%20%28HAL%1.0%20and%20Host-Device_Lib%1.0%29&FolderCTID=0x01200200770978C69A114...

, which might indicate a lack of subsequent preparation on the CDC data endpoint.

'might have to take a deeper look at this, since trying his solution gives good results.

Edit : From host to device, that is. The TX isn't working properly.

With a simple loopback test, I get a bunch of '\0' (zeros) on the host. Still searching the problem on the IN endpoint, since tracing the USB frames on the host proves the content is really a bunch of zeros, so at least the Win7 x64 drivers/serial terminal combo isn't at fault here.

shorai
Associate III
Posted on May 16, 2014 at 10:36

Hi jla

Check your clocks very carefully. In another post (Windows 7 CDC) I solved a clock related issue.

The divisors I used were 

        8MHz HSE,   Divide 8, PLL 336, divide 7     this works

                             Divide 8, PLL 192, divide 4 does not work even though it generates 48MHz

Also check VBUS and SOF are correct for your hardware

If you have an ST board, tru use cube to generate a project and run it, then compare to what is not working

Chris

arnaljl
Associate III
Posted on May 16, 2014 at 13:46 Thank, but naaaah. I don't think the host could get the device/class/interface descriptors and their strings right with a wrong USB clock btw. As far as I remember, I never could, even in USB low speed on a PIC18 platform. The clock has to be relatively precise, and in my case, it is. Fact is I was sending the wrong buffer to USBD_CDC_SetTxBuffer(). silly me. It's almost working like a charm now. I'm using

/public/STe2ecommunities/mcu/Lists/STM32Java/Flat.aspx?RootFolder=https://my.st.com/public/STe2ecommunities/mcu/Lists/STM32Java/USB%20middleware%20issue%20with%20CDCVCP%20only%20x%20packets%20receivable%20%28HAL%1.0%20and%20Host-Device_Lib%1.0%29&FolderCTID=0x01200200770978C69A1141439FE559EB459D758000F9A0E3A95BA69146A17C2E80209ADC21&currentviews=162

to set/reset the pdev->pClassData->TxState flag after each IN (host-wise) packet now : 1) Added his implementation of USB_EpTxCount(..) o stm32f4xx_ll_usb.c 2) Added his implementation of HAL_PCD_EP_GetTxCount(..) to stm32f4xx_hal_pcd.c 3) Added his implementation of USBD_LL_GetTxCount(..) to usbd_conf.h 4) Modified USBD_CDC_TransmitPacked(..) from usbd_cdc.c like so :


uint8_t USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev)

{ 

USBD_CDC_HandleTypeDef *hcdc = pdev->pClassData;


if
(pdev->pClassData != NULL)

{


if
(hcdc->TxState == 0)

{


/* Transmit next packet */

USBD_LL_Transmit(pdev,

CDC_IN_EP,

hcdc->TxBuffer,

hcdc->TxLength);


/* Tx Transfer in progress */

hcdc->TxState = 1;

return
USBD_OK;

}

else

{

return
USBD_BUSY;

}

}

else

{

return
USBD_FAIL;

}

}

becomes :


extern
uint32_t USBD_LL_GetTxCount (USBD_HandleTypeDef *pdev, uint8_t ep_addr);

uint8_t USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev)

{ 

USBD_CDC_HandleTypeDef *hcdc = pdev->pClassData;


if
(pdev->pClassData != NULL)

{


if
(hcdc->TxState == 0)

{


/* Transmit next packet */

USBD_LL_Transmit(pdev,

CDC_IN_EP,

hcdc->TxBuffer,

hcdc->TxLength);


/* Tx Transfer in progress */

hcdc->TxState = USBD_LL_GetTxCount(pdev,CDC_IN_EP) ? 1 : 0;

return
USBD_OK;

}

else

{

return
USBD_BUSY;

}

}

else

{

return
USBD_FAIL;

}

}

Works (almost) like a charm now : The loopback is still getting some bytes stuck in the device-side transmit buffer, so I'll look into it as soon as I have time for it. I did not look at his code hard enough to detect any flaw, but again, I'm pretty busy with other things right now. Still, one step further is a good one.
ayyaramdas
Associate II
Posted on May 29, 2014 at 06:03

hi Jla,

here is my code which works fine.

static int8_t CDC_Init(void)

{

  /* USER CODE BEGIN 3 */ 

USBD_CDC_SetTxBuffer(&hUsbDeviceFS, &buff_TX[0],256);

USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &buff_RX[0]);

  return (0);

  /* USER CODE END 3 */ 

}

static int8_t CDC_Receive (uint8_t* Buf, uint32_t *Len)

{

  /* USER CODE BEGIN 6 */ 

  if(pack_processed==0)

{

pak_len = *Len;

USBD_CDC_ReceivePacket(&hUsbDeviceFS);

pack_received=1;

}

return (0);

  /* USER CODE END 6 */ 

}

 and then in the mail just for testing , i was using the following code.

 /* USER CODE BEGIN 3 */

  /* Infinite loop */

  while (1)

  {

if(pack_received == 1)

{

if(pak_len == 4)

{

if((buff_RX[0]=='1')&&(buff_RX[1]=='2')&&(buff_RX[2]=='3')&&(buff_RX[3]=='4'))

{

strcpy((char *)buff_TX,''Received1234\n\r>'');

USBD_CDC_SetTxBuffer(&hUsbDeviceFS, &buff_TX[0], strlen(''Received1234\n\r>'')-1); // it is important to send the ''/n/r>'' otherwise the driver will hang.

USBD_CDC_TransmitPacket(&hUsbDeviceFS);

}

}

pack_processed=0;

pack_received=0;

}

  }

  /* USER CODE END 3 */

i hope it helps you, and one more thing please do not forget to do the change that Richard was saying the earlier post 

in the file make sure the macro is 256 otherwise the class is not getting created. may because of heap size or stack size. i think there is a information on the same in this post.

#define CDC_DATA_HS_MAX_PACKET_SIZE        256  /* Endpoint IN & OUT Packet size */

good luck,

Ramdas

joe
Associate II
Posted on June 13, 2014 at 14:39

When trying to implement the Virtual Com using CubeMX I was getting an problem on the PC side which was reported in the Device Manager as ''The device cannot start (code 10)'' for STMicroelectronics Virtual COM Port. Increasing the Heap from 0x200 to 0x400 has fixed it. Cheers simon