2013-04-10 01:04 AM
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-thread2013-04-10 03:12 AM
There's no need to repeat the same question in every section of the forum:
/44864166
2013-04-10 08:20 AM
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) Tsuneo2013-04-10 06:25 PM
2013-04-10 06:30 PM
and if I want to send 64 bytes ,by setting DCD_EP_TX(buf_len=64) ,it will be successful
.what wrong with me ?2013-04-15 02:17 AM
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 */2013-04-15 07:12 AM
[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] Tsuneo2014-12-06 12:53 AM
how to make it in the new library? DCD_EP_Tx() and usbd_cdc_core.c is missing