cancel
Showing results for 
Search instead for 
Did you mean: 

stm32f207 usb only multiple of 64 bytes can be send

easylwl
Associate II
Posted on April 10, 2013 at 10:04

change by stm32 usb device VCP example:

my send function:

uint16_t VCP_DataTx (uint8_t* Buf, uint32_t Len)

{

 uint8_t i;

 for (i=0;i<64;i++)    //only multiple of 64 bytes can be send

  {

 APP_Rx_Buffer[APP_Rx_ptr_in] = g_ucaHeartbeat[i];

 APP_Rx_ptr_in++;

  

   /* To avoid buffer overflow */

   if(APP_Rx_ptr_in == APP_RX_DATA_SIZE)

   {

     APP_Rx_ptr_in = 0;

   } 

  }

return USBD_OK;

}

the  usbd_cdc_core.c function

DCD_EP_Tx (pdev,

               VL8461_IN_EP,

               (uint8_t*)&APP_Rx_Buffer[USB_Tx_ptr],

               USB_Tx_length);   

//the USB_Tx_length must be 64 ??

please help

#stm32f207-cdc-virtualcom-usb #duplicate-thread
7 REPLIES 7
Andrew Neil
Evangelist III
Posted on April 10, 2013 at 12:12

There's no need to repeat the same question in every section of the forum:

/44864166

tsuneo
Senior
Posted on April 10, 2013 at 17:20

You may send any size of transfer over single DCD_EP_Tx() call, even more than 64 bytes (for full-speed) or 512 bytes (for high-speed) (*1). The stack and the USB engine split a large-size transfer into full-size transactions.

When the transfer size is just the multiple of endpoint wMaxPacketSize (64 / 512), you'll need to call DCD_EP_Tx(buf_len=0) to terminate the transfer with ZLT (Zero-Length Transaction), by the requirement of the CDC bulk endpoint.

(*1) The upper limit comes from PKTCNT field (10bits) of OTG_FS_DIEPTSIZx and OTG_HS_DIEPTSIZx registers.

upper limit = wMaxPacketSize * (2^10 - 1)

wMaxPacketSize = 64 bytes (FS) or 512 bytes (HS)

Tsuneo

easylwl
Associate II
Posted on April 11, 2013 at 03:25

thank you.

but I found the DCD_EP_Tx() the buf_len must be multiple of 64,if I want to transfer  8 bytes,By setting the DCD_EP_Tx(buf_len=8),it  will be nothing receive from the PC software (BUSHOUND) ?  
easylwl
Associate II
Posted on April 11, 2013 at 03:30

and if I want to send 64 bytes ,by setting DCD_EP_TX(buf_len=64) ,it will be successful

.what wrong with me ?

easylwl
Associate II
Posted on April 15, 2013 at 11:17

I change the USB CDC device Configuration Descriptor like this

/*Configuration Descriptor*/

  0x09,   /* bLength: Configuration Descriptor size */

  USB_CONFIGURATION_DESCRIPTOR_TYPE,      /* bDescriptorType: Configuration */

  USB_CDC_CONFIG_DESC_SIZ,                /* wTotalLength:no of returned bytes */

  0x00,

  0x01,   /* bNumInterfaces: 1 interface */

  0x01,   /* bConfigurationValue: Configuration value */

  0x00,   /* iConfiguration: Index of string descriptor describing the configuration */

  0xC0,   /* bmAttributes: self powered */

  250,   /* MaxPower 2 mA */

  

  /*Data class interface descriptor*/

  0x09,   /* bLength: Endpoint Descriptor size */

  USB_INTERFACE_DESCRIPTOR_TYPE,  /* bDescriptorType: */

  0x00,   /* bInterfaceNumber: Number of Interface */

  0x00,   /* bAlternateSetting: Alternate setting */

  0x02,   /* bNumEndpoints: Two endpoints used */

  0xff,   /* bInterfaceClass: USER */

  0x00,   /* bInterfaceSubClass: */

  0x00,   /* bInterfaceProtocol: */

  0x00,   /* iInterface: */

 

  //18

 

  /*Endpoint OUT Descriptor*/

  0x07,   /* bLength: Endpoint Descriptor size */

  USB_ENDPOINT_DESCRIPTOR_TYPE,      /* bDescriptorType: Endpoint */

  0x03,                        /* bEndpointAddress */

  0x02,                              /* bmAttributes: Bulk */

  0x40,  /* wMaxPacketSize: */

  0,

  0,                              /* bInterval: ignore for Bulk transfer */

  //25

  /*Endpoint IN Descriptor*/

  0x07,   /* bLength: Endpoint Descriptor size */

  USB_ENDPOINT_DESCRIPTOR_TYPE,      /* bDescriptorType: Endpoint */

  0x82,                         /* bEndpointAddress */

  0x02,                              /* bmAttributes: Bulk */

  0x40,  /* wMaxPacketSize: */

  0,

  0                               /* bInterval: ignore for Bulk transfer */

  //32

and change device decriptor

__ALIGN_BEGIN uint8_t USBD_DeviceDesc[USB_SIZ_DEVICE_DESC] __ALIGN_END =

  {

    0x12,                       /*bLength */

    USB_DEVICE_DESCRIPTOR_TYPE, /*bDescriptorType*/

    LOBYTE(0x0200),                       /*bcdUSB 2.0*/

    HIBYTE(0x0200), 

    2,    //0xff,                       /*bDeviceClass*/

    0x00,                       /*bDeviceSubClass*/

    0x00,                       /*bDeviceProtocol*/

    USB_OTG_MAX_EP0_SIZE,      /*bMaxPacketSize*/

    LOBYTE(USBD_VID),           /*idVendor*/

    HIBYTE(USBD_VID),           /*idVendor*/

    LOBYTE(USBD_PID),           /*idVendor*/

    HIBYTE(USBD_PID),           /*idVendor*/

    0x00,                       /*bcdDevice rel. 2.00*/

    0x02,

    0,    //USBD_IDX_MFC_STR,           /*Index of manufacturer  string*/

    0,  //USBD_IDX_PRODUCT_STR,       /*Index of product string*/

    0,  //USBD_IDX_SERIAL_STR,        /*Index of serial number string*/

    USBD_CFG_MAX_NUM            /*bNumConfigurations*/

  } ; /* USB_DeviceDescriptor */

tsuneo
Senior
Posted on April 15, 2013 at 16:12

[i]> but I found the DCD_EP_Tx() the buf_len must be multiple of 64[/i]

Heh, how did you get to such a wrong finding?

You don't need to modify the descriptors at all.

Rather, to apply DCD_EP_Tx() to the bulk IN EP directly, copy usbd_cdc_core.c to your project folder, and modify it.

\STM32_USB-Host-Device_Lib_V2.1.0\Libraries\STM32_USB_Device_Library\Class\cdc\src\usbd_cdc_core.c

usbd_cdc_core.c calls DCD_EP_Tx() on the bulk IN endpoint, to keep transfer interval.

 - maybe, ST has tried to implement ''latency timer'', but their implementation is just a delay, not a ''latency timer''.

You have to delete this implementation.

This implementation is useful for USB-UART and printf() over VCP, but for direct buffer transfer using DCD_EP_Tx(), it disturbs operation. Modify these subroutines.

[code]

usbd_cdc_core.c

static uint8_t  usbd_cdc_SOF (void *pdev)

{      

/*

   Delete all of contents of this subroutine

*/

  return USBD_OK;

}

static uint8_t  usbd_cdc_DataIn (void *pdev, uint8_t epnum)

{

  // replace

  USB_Tx_State = 0;

  return USBD_OK;

}

[/code]

DCD_EP_Tx() is applied, for example, as follows.

[code]

extern uint8_t USB_Tx_State;

extern uint8_t APP_Rx_Buffer[APP_RX_DATA_SIZE];

int main(void)

{

  ...

  ...

  /* Main loop */

  while (1)

  {

    if (i++ == 0x100000)

    {

      STM_EVAL_LEDToggle(LED1);

      STM_EVAL_LEDToggle(LED2);

      STM_EVAL_LEDToggle(LED3);

      STM_EVAL_LEDToggle(LED4);

      i = 0;

      APP_Rx_Buffer[0] = 'x';

      if ( (USB_OTG_dev.dev.device_status == USB_OTG_CONFIGURED) && (USB_Tx_State == 0 ) ) {

        USB_Tx_State = 1;

        DCD_EP_Tx (&USB_OTG_dev, CDC_IN_EP, (uint8_t*)&APP_Rx_Buffer, 1);

      }

    }

  }

}

[/code]

Tsuneo

sergalyant
Associate
Posted on December 06, 2014 at 09:53

how to make it in the new library? DCD_EP_Tx() and usbd_cdc_core.c is missing