Hi
I am trying to get multiple virtual COM ports on a single LPC11U35.
Windows detects the device, agrees that there are 2 COM ports (and a mouse, which is rudimentary from the example code). The COM port that came with the example works well. I modified the code to get the second one working, but it fails at configuration (opening the port). The example project I used was "nxp_lpcxpresso_11u14_usbd_lib_composite" from "lpcopen_v2_00a_lpcxpresso_nxp_lpcxpresso_11u14.zip"
Using breakpoints, I looked up the path what a working port should follow. I have determined that when opening the port, the working one goes all the way to its "VCOM_SetLineCode" function, however the failing one does not get past "USB_EndPoint0" ("USB_EvtOutHandler" never gets called). Here is a screenshot of the working chain:
Parts of code that may be of interest:
From main:
ret = USBD_API->hw->Init(&g_hUsb, &desc, &usb_param);
if (ret == LPC_OK) {
ret = Mouse_Init(g_hUsb, (USB_INTERFACE_DESCRIPTOR *) find_IntfDesc(desc.high_speed_desc, USB_DEVICE_CLASS_HUMAN_INTERFACE), &usb_param.mem_base, &usb_param.mem_size);
if (ret == LPC_OK) {
/* Init VCOM interface */
ret = vcom_init_multi(g_hUsb, &desc, &usb_param, &g_vCOM, USB_CDC_IN_EP, USB_CDC_OUT_EP);
if (ret == LPC_OK) {
ret = vcom_init_multi(g_hUsb, &desc, &usb_param, &g_vCOM2, USB_CDC2_IN_EP, USB_CDC2_OUT_EP);
if (ret == LPC_OK) {
/* enable USB interrrupts */
NVIC_EnableIRQ(USB0_IRQn);
/* now connect */
USBD_API->hw->Connect(g_hUsb, 1);
}
}
}
}
Initialization function:
ErrorCode_t vcom_init_multi(USBD_HANDLE_T hUsb, USB_CORE_DESCS_T *pDesc, USBD_API_INIT_PARAM_T *pUsbParam, VCOM_DATA_T *vCOMused, uint8_t ep_in, uint8_t ep_out){
int static comPortCounter = 0;
comPortCounter++;
DEBUGLED00_SETOUTPUT;
DEBUGLED00_OFF;
USBD_CDC_INIT_PARAM_T cdc_param;
ErrorCode_t ret = LPC_OK;
uint32_t ep_indx;
VCOM_DATA_T *localVCOM = vCOMused;
//g_vCOM.hUsb = hUsb; //example what was before for next line
localVCOM->hUsb = hUsb;
memset((void *) &cdc_param, 0, sizeof(USBD_CDC_INIT_PARAM_T));
cdc_param.mem_base = pUsbParam->mem_base;
cdc_param.mem_size = pUsbParam->mem_size;
cdc_param.cif_intf_desc = (uint8_t *) find_IntfDesc(pDesc->high_speed_desc, CDC_COMMUNICATION_INTERFACE_CLASS);
cdc_param.dif_intf_desc = (uint8_t *) find_IntfDesc(pDesc->high_speed_desc, CDC_DATA_INTERFACE_CLASS);
if(comPortCounter==1) cdc_param.SetLineCode = VCOM_SetLineCode;
else cdc_param.SetLineCode = VCOM_SetLineCode2;
ret = USBD_API->cdc->init(hUsb, &cdc_param, &(localVCOM->hCdc));
if (ret == LPC_OK) {
/* allocate transfer buffers */
localVCOM->rx_buff = (uint8_t *) cdc_param.mem_base;
cdc_param.mem_base += VCOM_RX_BUF_SZ;
cdc_param.mem_size -= VCOM_RX_BUF_SZ;
/* register endpoint interrupt handler */
ep_indx = (((ep_in & 0x0F) << 1) + 1);
if(comPortCounter==1) ret = USBD_API->core->RegisterEpHandler(hUsb, ep_indx, VCOM_bulk_in_hdlr, localVCOM);
else ret = USBD_API->core->RegisterEpHandler(hUsb, ep_indx, VCOM_bulk_in_hdlr2, localVCOM);
if (ret == LPC_OK) {
/* register endpoint interrupt handler */
ep_indx = ((ep_out & 0x0F) << 1);
if(comPortCounter==1) ret = USBD_API->core->RegisterEpHandler(hUsb, ep_indx, VCOM_bulk_out_hdlr, localVCOM);
else ret = USBD_API->core->RegisterEpHandler(hUsb, ep_indx, VCOM_bulk_out_hdlr2, localVCOM);
}
/* update mem_base and size variables for cascading calls. */
pUsbParam->mem_base = cdc_param.mem_base;
pUsbParam->mem_size = cdc_param.mem_size;
}
return ret;
}
SetLinecode functions:
/* Set line coding call back routine */
static ErrorCode_t VCOM_SetLineCode(USBD_HANDLE_T hCDC, CDC_LINE_CODING *line_coding)
{
//THIS FUNCTION GETS CALLED WHEN COMPORT OPENS
VCOM_DATA_T *pVcom = &g_vCOM;
DEBUGLED00_ON;
/* Called when baud rate is changed/set. Using it to know host connection state */
pVcom->tx_flags = VCOM_TX_CONNECTED; /* reset other flags */
return LPC_OK;
}
static ErrorCode_t VCOM_SetLineCode2(USBD_HANDLE_T hCDC, CDC_LINE_CODING *line_coding)
{
//This function does not get called when comport opens, for some reason!?
VCOM_DATA_T *pVcom = &g_vCOM2;
DEBUGLED00_ON;
/* Called when baud rate is changed/set. Using it to know host connection state */
pVcom->tx_flags = VCOM_TX_CONNECTED; /* reset other flags */
return LPC_OK;
}
A section from app_usbd_cfg.h
/* HID In/Out Endpoint Address */
#define HID_EP_IN 0x81
#define USB_HID_IF_NUM 0
/** Interval between mouse reports expressed in milliseconds for full-speed device. */
#define HID_MOUSE_REPORT_INTERVAL_MS 10
/* bInterval value used in descriptor. For HS this macro will differ from HID_MOUSE_REPORT_INTERVAL_MS macro. */
#define HID_MOUSE_REPORT_INTERVAL 10
/* Manifest constants defining interface numbers and endpoints used by a
CDC class interfaces in this application.
*/
#define USB_CDC_CIF_NUM 3
#define USB_CDC_DIF_NUM 4
#define USB_CDC_IN_EP 0x81 //0x81 is EP1_IN
#define USB_CDC_OUT_EP 0x01 //0x01 is EP1_OUT?
#define USB_CDC_INT_EP 0x82
//added to try to get second vcom
#define USB_CDC2_CIF_NUM 1
#define USB_CDC2_DIF_NUM 2
#define USB_CDC2_IN_EP 0x83
#define USB_CDC2_OUT_EP 0x03
#define USB_CDC2_INT_EP 0x84
(NB, I see that mouse and one CDC share the same EP_IN value, however this is the one that works. As I understand, they should not share the EP value)
Hopefully this is enough information. Please let me know if something else could be of assistance. I hope someone else has stumbled across this issue and can direct me forward.
Solved! Go to Solution.
Hi Jens Dender,
After dig deeper into the issue, I think the LPC11U35 can't achieve the application: HID +CDC+CDC, as the LCP11U35 has the limitation of the endpoint number (Fig 1).
So I'd highly recommend you to choose the LPC176x/5x instead of the LPC11U35 and LPC176x/5x can support 16 endpoints.
Fig 1
Hope this is clear.
Have a great day,
Ping
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
Hi Jens Dender,
Thank you for your interest in NXP Semiconductor products and for the opportunity to serve you.
I'm still a little confused, I was wondering if you can demonstrate the amendments you do in the list.
I'm looking forward to your reply.
Have a great day,
Ping
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
Hi
Thanks for reply.
I didn't exactly understand what do you mean by "amendments", but I have made available the entire modified workspace here: jdp.spacetechnology.net/lpc11u35-multiVCOM-broken.zip
Please let me know if there is any other information I can provide!
Hi Jens Dender,
Thanks for your reply, and let me clarify it.
I was wondering if you can exemplify what changes you did which involves the differ kinds of descriptors, code, etc.
I can't download the zip file, as some error messages jump out during open the link.
So I'd recommend you to upload the file to the community directly.
Have a great day,
Ping
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
Hi Ping
Thanks for letting me know you can't access the files. I uploaded the workspace here.
The changes I made in the "nxp_lpcxpresso_11u14_usbd_lib_composite" project summarized:
In inc/app_usbd_cfg.h
In inc/cdc_vcom.h
In src/cdc_vcom.c
In src/composite_desc.c
In src/composite_main.c
I hope I got all the changes summarized. Please let me know if I can provide any more information.
Hi Jens Dender,
After dig deeper into the issue, I think the LPC11U35 can't achieve the application: HID +CDC+CDC, as the LCP11U35 has the limitation of the endpoint number (Fig 1).
So I'd highly recommend you to choose the LPC176x/5x instead of the LPC11U35 and LPC176x/5x can support 16 endpoints.
Fig 1
Hope this is clear.
Have a great day,
Ping
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
Hi Jens Dender,
Thanks for your reply.
After review your demo, I have some suggestions for you.
1. You would see the CDC class should involve two interfaces and two endpoints at least, therefore the composite demo needs 5+1 endpoints to achieve the 2 CDC class + 1 HID class at least. For the composite demo, I'd like to exemplify the amended descriptor below.
/**
* USB FSConfiguration Descriptor
* All Descriptors (Configuration, Interface, Endpoint, Class, Vendor)
*/
ALIGNED(4) uint8_t USB_FsConfigDescriptor[] = {
/* Configuration 1 */
USB_CONFIGURATION_DESC_SIZE, /* bLength */
USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType */
WBVAL( /* wTotalLength */
USB_CONFIGURATION_DESC_SIZE +
/* HID class related descriptors */
USB_INTERFACE_DESC_SIZE +
HID_DESC_SIZE +
USB_ENDPOINT_DESC_SIZE +
/* CDC class related descriptors */
USB_INTERFACE_ASSOC_DESC_SIZE + /* interface association descriptor */
USB_INTERFACE_DESC_SIZE + /* communication control interface */
0x0013 + /* CDC functions */
1 * USB_ENDPOINT_DESC_SIZE + /* interrupt endpoint */
USB_INTERFACE_DESC_SIZE + /* communication data interface */
2 * USB_ENDPOINT_DESC_SIZE + /* bulk endpoints */
/* Second CDC class related descriptors */
USB_INTERFACE_ASSOC_DESC_SIZE + /* interface association descriptor */
USB_INTERFACE_DESC_SIZE + /* communication control interface */
0x0013 + /* CDC functions */
1 * USB_ENDPOINT_DESC_SIZE + /* interrupt endpoint */
USB_INTERFACE_DESC_SIZE + /* communication data interface */
2 * USB_ENDPOINT_DESC_SIZE + /* bulk endpoints */
0
),
0x03, /* bNumInterfaces */
0x01, /* bConfigurationValue */
0x00, /* iConfiguration */
USB_CONFIG_SELF_POWERED, /* bmAttributes */
USB_CONFIG_POWER_MA(2), /* bMaxPower */
/* Interface 0, Alternate Setting 0, HID Class */
USB_INTERFACE_DESC_SIZE, /* bLength */
USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
USB_HID_IF_NUM, /* bInterfaceNumber */
0x00, /* bAlternateSetting */
0x01, /* bNumEndpoints */
USB_DEVICE_CLASS_HUMAN_INTERFACE, /* bInterfaceClass */
HID_SUBCLASS_BOOT, /* bInterfaceSubClass */
HID_PROTOCOL_MOUSE, /* bInterfaceProtocol */
0x04, /* iInterface */
/* HID Class Descriptor */
/* HID_DESC_OFFSET = 0x0012 */
HID_DESC_SIZE, /* bLength */
HID_HID_DESCRIPTOR_TYPE, /* bDescriptorType */
WBVAL(0x0111), /* bcdHID : 1.11*/
0x00, /* bCountryCode */
0x01, /* bNumDescriptors */
HID_REPORT_DESCRIPTOR_TYPE, /* bDescriptorType */
WBVAL(sizeof(Mouse_ReportDescriptor)), /* wDescriptorLength */
/* Endpoint, HID Interrupt In */
USB_ENDPOINT_DESC_SIZE, /* bLength */
USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */
HID_EP_IN, /* bEndpointAddress */
USB_ENDPOINT_TYPE_INTERRUPT, /* bmAttributes */
WBVAL(0x0008), /* wMaxPacketSize */
HID_MOUSE_REPORT_INTERVAL, /* bInterval */
/* Interface association descriptor IAD*/
USB_INTERFACE_ASSOC_DESC_SIZE, /* bLength */
USB_INTERFACE_ASSOCIATION_DESCRIPTOR_TYPE, /* bDescriptorType */
USB_CDC_CIF_NUM, /* bFirstInterface */
0x02, /* bInterfaceCount */
CDC_COMMUNICATION_INTERFACE_CLASS, /* bFunctionClass */
CDC_ABSTRACT_CONTROL_MODEL, /* bFunctionSubClass */
0x00, /* bFunctionProtocol */
0x05, /* iFunction */
/* Interface 1, Alternate Setting 0, Communication class interface descriptor */
USB_INTERFACE_DESC_SIZE, /* bLength */
USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
USB_CDC_CIF_NUM, /* bInterfaceNumber: Number of Interface */
0x00, /* bAlternateSetting: Alternate setting */
0x01, /* bNumEndpoints: One endpoint used */
CDC_COMMUNICATION_INTERFACE_CLASS, /* bInterfaceClass: Communication Interface Class */
CDC_ABSTRACT_CONTROL_MODEL, /* bInterfaceSubClass: Abstract Control Model */
0x00, /* bInterfaceProtocol: no protocol used */
0x05, /* iInterface: */
/* Header Functional Descriptor*/
0x05, /* bLength: CDC header Descriptor size */
CDC_CS_INTERFACE, /* bDescriptorType: CS_INTERFACE */
CDC_HEADER, /* bDescriptorSubtype: Header Func Desc */
WBVAL(CDC_V1_10), /* bcdCDC 1.10 */
/* Call Management Functional Descriptor*/
0x05, /* bFunctionLength */
CDC_CS_INTERFACE, /* bDescriptorType: CS_INTERFACE */
CDC_CALL_MANAGEMENT, /* bDescriptorSubtype: Call Management Func Desc */
0x01, /* bmCapabilities: device handles call management */
USB_CDC_DIF_NUM, /* bDataInterface: CDC data IF ID */
/* Abstract Control Management Functional Descriptor*/
0x04, /* bFunctionLength */
CDC_CS_INTERFACE, /* bDescriptorType: CS_INTERFACE */
CDC_ABSTRACT_CONTROL_MANAGEMENT, /* bDescriptorSubtype: Abstract Control Management desc */
0x02, /* bmCapabilities: SET_LINE_CODING, GET_LINE_CODING, SET_CONTROL_LINE_STATE supported */
/* Union Functional Descriptor*/
0x05, /* bFunctionLength */
CDC_CS_INTERFACE, /* bDescriptorType: CS_INTERFACE */
CDC_UNION, /* bDescriptorSubtype: Union func desc */
USB_CDC_CIF_NUM, /* bMasterInterface: Communication class interface is master */
USB_CDC_DIF_NUM, /* bSlaveInterface0: Data class interface is slave 0 */
/* Endpoint 1 Descriptor*/
USB_ENDPOINT_DESC_SIZE, /* bLength */
USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */
USB_CDC_INT_EP, /* bEndpointAddress */
USB_ENDPOINT_TYPE_INTERRUPT, /* bmAttributes */
WBVAL(0x0010), /* wMaxPacketSize */
0x02, /* 2ms */ /* bInterval */
/* Interface 2, Alternate Setting 0, Data class interface descriptor*/
USB_INTERFACE_DESC_SIZE, /* bLength */
USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
USB_CDC_DIF_NUM, /* bInterfaceNumber: Number of Interface */
0x00, /* bAlternateSetting: no alternate setting */
0x02, /* bNumEndpoints: two endpoints used */
CDC_DATA_INTERFACE_CLASS, /* bInterfaceClass: Data Interface Class */
0x00, /* bInterfaceSubClass: no subclass available */
0x00, /* bInterfaceProtocol: no protocol used */
0x05, /* iInterface: */
/* Endpoint, EP Bulk Out */
USB_ENDPOINT_DESC_SIZE, /* bLength */
USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */
USB_CDC_OUT_EP, /* bEndpointAddress */
USB_ENDPOINT_TYPE_BULK, /* bmAttributes */
WBVAL(USB_FS_MAX_BULK_PACKET), /* wMaxPacketSize */
0x00, /* bInterval: ignore for Bulk transfer */
/* Endpoint, EP Bulk In */
USB_ENDPOINT_DESC_SIZE, /* bLength */
USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */
USB_CDC_IN_EP, /* bEndpointAddress */
USB_ENDPOINT_TYPE_BULK, /* bmAttributes */
WBVAL(64), /* wMaxPacketSize */
0x00, /* bInterval: ignore for Bulk transfer */
/* Interface association descriptor IAD for second CDC */
USB_INTERFACE_ASSOC_DESC_SIZE, /* bLength */
USB_INTERFACE_ASSOCIATION_DESCRIPTOR_TYPE, /* bDescriptorType */
Sec_USB_CDC_CIF_NUM, /* bFirstInterface */
0x02, /* bInterfaceCount */
CDC_COMMUNICATION_INTERFACE_CLASS, /* bFunctionClass */
CDC_ABSTRACT_CONTROL_MODEL, /* bFunctionSubClass */
0x00, /* bFunctionProtocol */
0x05, /* iFunction */
/* Interface 3, Alternate Setting 0, Communication class interface descriptor */
USB_INTERFACE_DESC_SIZE, /* bLength */
USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
Sec_USB_CDC_CIF_NUM, /* bInterfaceNumber: Number of Interface */
0x00, /* bAlternateSetting: Alternate setting */
0x01, /* bNumEndpoints: One endpoint used */
CDC_COMMUNICATION_INTERFACE_CLASS, /* bInterfaceClass: Communication Interface Class */
CDC_ABSTRACT_CONTROL_MODEL, /* bInterfaceSubClass: Abstract Control Model */
0x00, /* bInterfaceProtocol: no protocol used */
0x05, /* iInterface: */
/* Header Functional Descriptor*/
0x05, /* bLength: CDC header Descriptor size */
CDC_CS_INTERFACE, /* bDescriptorType: CS_INTERFACE */
CDC_HEADER, /* bDescriptorSubtype: Header Func Desc */
WBVAL(CDC_V1_10), /* bcdCDC 1.10 */
/* Call Management Functional Descriptor*/
0x05, /* bFunctionLength */
CDC_CS_INTERFACE, /* bDescriptorType: CS_INTERFACE */
CDC_CALL_MANAGEMENT, /* bDescriptorSubtype: Call Management Func Desc */
0x01, /* bmCapabilities: device handles call management */
Sec_USB_CDC_DIF_NUM, /* bDataInterface: CDC data IF ID */
/* Abstract Control Management Functional Descriptor*/
0x04, /* bFunctionLength */
CDC_CS_INTERFACE, /* bDescriptorType: CS_INTERFACE */
CDC_ABSTRACT_CONTROL_MANAGEMENT, /* bDescriptorSubtype: Abstract Control Management desc */
0x02, /* bmCapabilities: SET_LINE_CODING, GET_LINE_CODING, SET_CONTROL_LINE_STATE supported */
/* Union Functional Descriptor*/
0x05, /* bFunctionLength */
CDC_CS_INTERFACE, /* bDescriptorType: CS_INTERFACE */
CDC_UNION, /* bDescriptorSubtype: Union func desc */
Sec_USB_CDC_CIF_NUM, /* bMasterInterface: Communication class interface is master */
Sec_USB_CDC_DIF_NUM, /* bSlaveInterface0: Data class interface is slave 0 */
/* Endpoint 1 Descriptor*/
USB_ENDPOINT_DESC_SIZE, /* bLength */
USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */
Sec_USB_CDC_INT_EP, /* bEndpointAddress */
USB_ENDPOINT_TYPE_INTERRUPT, /* bmAttributes */
WBVAL(0x0010), /* wMaxPacketSize */
0x02, /* 2ms */ /* bInterval */
/* Interface 4, Alternate Setting 0, Data class interface descriptor*/
USB_INTERFACE_DESC_SIZE, /* bLength */
USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
Sec_USB_CDC_DIF_NUM, /* bInterfaceNumber: Number of Interface */
0x00, /* bAlternateSetting: no alternate setting */
0x02, /* bNumEndpoints: two endpoints used */
CDC_DATA_INTERFACE_CLASS, /* bInterfaceClass: Data Interface Class */
0x00, /* bInterfaceSubClass: no subclass available */
0x00, /* bInterfaceProtocol: no protocol used */
0x05, /* iInterface: */
/* Endpoint, EP Bulk Out */
USB_ENDPOINT_DESC_SIZE, /* bLength */
USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */
Sec_USB_CDC_OUT_EP, /* bEndpointAddress */
USB_ENDPOINT_TYPE_BULK, /* bmAttributes */
WBVAL(USB_FS_MAX_BULK_PACKET), /* wMaxPacketSize */
0x00, /* bInterval: ignore for Bulk transfer */
/* Endpoint, EP Bulk In */
USB_ENDPOINT_DESC_SIZE, /* bLength */
USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */
Sec_USB_CDC_IN_EP, /* bEndpointAddress */
USB_ENDPOINT_TYPE_BULK, /* bmAttributes */
WBVAL(64), /* wMaxPacketSize */
0x00, /* bInterval: ignore for Bulk transfer */
/* Terminator */
0 /* bLength */
};
/* HID In/Out Endpoint Address */
#define HID_EP_IN 0x81
#define USB_HID_IF_NUM 0
/** Interval between mouse reports expressed in milliseconds for full-speed device. */
#define HID_MOUSE_REPORT_INTERVAL_MS 10
/* bInterval value used in descriptor. For HS this macro will differ from HID_MOUSE_REPORT_INTERVAL_MS macro. */
#define HID_MOUSE_REPORT_INTERVAL 10
/* Manifest constants defining interface numbers and endpoints used by a
CDC class interfaces in this application.
*/
#define USB_CDC_CIF_NUM 1
#define USB_CDC_DIF_NUM 2
#define USB_CDC_IN_EP 0x82
#define USB_CDC_OUT_EP 0x01
#define USB_CDC_INT_EP 0x83
/* Manifest constants defining interface numbers and endpoints used by a
CDC class interfaces in this application.
*/
#define Sec_USB_CDC_CIF_NUM 3
#define Sec_USB_CDC_DIF_NUM 4
#define Sec_USB_CDC_IN_EP 0x85
#define Sec_USB_CDC_OUT_EP 0x04
#define Sec_USB_CDC_INT_EP 0x86
2. You need to consider the bug of the ROM driver as the errata demonstrates.
3. I think you need to get the idea of the process of window handles a composite device, I think you may need to modify the INF file to suit the new USB composite device and the attachment will help you a lot.
Have a great day,
Ping
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------