SAMV71-Xult Composite: Now can switch between two different composite configurations dynamically.
This commit is contained in:
parent
815257743d
commit
e4d262436c
@ -86,145 +86,149 @@ FAR void *board_composite_connect(int port, int configid)
|
|||||||
/* Here we are composing the configuration of the usb composite device.
|
/* Here we are composing the configuration of the usb composite device.
|
||||||
*
|
*
|
||||||
* The standard is to use one CDC/ACM and one USB mass storage device.
|
* The standard is to use one CDC/ACM and one USB mass storage device.
|
||||||
*
|
|
||||||
* You will also find an example below which generates three CDC/ACM
|
|
||||||
* devices. This example can be used on samv71-xult.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if 1
|
if (configid == 0)
|
||||||
struct composite_devdesc_s dev[2];
|
|
||||||
int ifnobase = 0;
|
|
||||||
int strbase = COMPOSITE_NSTRIDS;
|
|
||||||
|
|
||||||
/* Configure the CDC/ACM device */
|
|
||||||
|
|
||||||
/* Ask the cdcacm driver to fill in the constants we didn't
|
|
||||||
* know here.
|
|
||||||
*/
|
|
||||||
|
|
||||||
cdcacm_get_composite_devdesc(&dev[0]);
|
|
||||||
|
|
||||||
/* Overwrite and correct some values... */
|
|
||||||
/* The callback functions for the CDC/ACM class */
|
|
||||||
|
|
||||||
dev[0].classobject = board_cdcclassobject;
|
|
||||||
dev[0].uninitialize = board_cdcuninitialize;
|
|
||||||
|
|
||||||
/* Interfaces */
|
|
||||||
|
|
||||||
dev[0].devdesc.ifnobase = ifnobase; /* Offset to Interface-IDs */
|
|
||||||
dev[0].minor = CONFIG_SYSTEM_COMPOSITE_TTYUSB; /* The minor interface number */
|
|
||||||
|
|
||||||
/* Strings */
|
|
||||||
|
|
||||||
dev[0].devdesc.strbase = strbase; /* Offset to String Numbers */
|
|
||||||
|
|
||||||
/* Endpoints */
|
|
||||||
|
|
||||||
dev[0].devdesc.epno[CDCACM_EP_INTIN_IDX] = 3;
|
|
||||||
dev[0].devdesc.epno[CDCACM_EP_BULKIN_IDX] = 4;
|
|
||||||
dev[0].devdesc.epno[CDCACM_EP_BULKOUT_IDX] = 5;
|
|
||||||
|
|
||||||
/* Count up the base numbers */
|
|
||||||
|
|
||||||
ifnobase += dev[0].devdesc.ninterfaces;
|
|
||||||
strbase += dev[0].devdesc.nstrings;
|
|
||||||
|
|
||||||
/* Configure the mass storage device device */
|
|
||||||
/* Ask the usbmsc driver to fill in the constants we didn't
|
|
||||||
* know here.
|
|
||||||
*/
|
|
||||||
|
|
||||||
usbmsc_get_composite_devdesc(&dev[1]);
|
|
||||||
|
|
||||||
/* Overwrite and correct some values... */
|
|
||||||
/* The callback functions for the USBMSC class */
|
|
||||||
|
|
||||||
dev[1].classobject = board_mscclassobject;
|
|
||||||
dev[1].uninitialize = board_mscuninitialize;
|
|
||||||
|
|
||||||
/* Interfaces */
|
|
||||||
|
|
||||||
dev[1].devdesc.ifnobase = ifnobase; /* Offset to Interface-IDs */
|
|
||||||
dev[1].minor = CONFIG_SYSTEM_COMPOSITE_DEVMINOR1; /* The minor interface number */
|
|
||||||
|
|
||||||
/* Strings */
|
|
||||||
|
|
||||||
dev[1].devdesc.strbase = strbase; /* Offset to String Numbers */
|
|
||||||
|
|
||||||
/* Endpoints */
|
|
||||||
|
|
||||||
dev[1].devdesc.epno[USBMSC_EP_BULKIN_IDX] = 1;
|
|
||||||
dev[1].devdesc.epno[USBMSC_EP_BULKOUT_IDX] = 2;
|
|
||||||
|
|
||||||
/* Count up the base numbers */
|
|
||||||
|
|
||||||
ifnobase += dev[1].devdesc.ninterfaces;
|
|
||||||
strbase += dev[1].devdesc.nstrings;
|
|
||||||
|
|
||||||
return composite_initialize(2, dev);
|
|
||||||
#else
|
|
||||||
/* Example with three CDC/ACMs
|
|
||||||
*
|
|
||||||
* This Example can be used e.g. on a samv71-xult. The samv71 has
|
|
||||||
* 10 Endpoints (EPs). The EPs 0 up to 7 are DMA aware. The EPs 8
|
|
||||||
* and 9 are not.
|
|
||||||
*
|
|
||||||
* In a composite device we need the EP0 as an control Endpoint.
|
|
||||||
* Each CDC/ACM needs one Interrupt driven and two bulk Endpoints.
|
|
||||||
* This is why we configure the EPs 7, 8 and 9 to be the IRQ-EPs
|
|
||||||
* and the EP-Pairs 1/2, 3/4, 5/6 to be the bulk EPs for each
|
|
||||||
* device.
|
|
||||||
*
|
|
||||||
* This means, that
|
|
||||||
*
|
|
||||||
* - the Composite device uses EP0 as the control-Endpoint,
|
|
||||||
* - the CDC/ACM 0 uses EP7, EP1 and EP2,
|
|
||||||
* - the CDC/ACM 1 uses EP8, EP3 and EP4,
|
|
||||||
* - the CDC/ACM 2 uses EP9, EP5 and EP6
|
|
||||||
*
|
|
||||||
* as its EP-Configuration.
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct composite_devdesc_struct dev[3];
|
|
||||||
int strbase = COMPOSITE_NSTRIDS;
|
|
||||||
int ifnobase = 0;
|
|
||||||
int ia;
|
|
||||||
|
|
||||||
for (ia = 0; ia < 3; ia++)
|
|
||||||
{
|
{
|
||||||
/* Ask the cdcacm driver to fill in the constants we didn't know here */
|
struct composite_devdesc_s dev[2];
|
||||||
|
int ifnobase = 0;
|
||||||
|
int strbase = COMPOSITE_NSTRIDS;
|
||||||
|
|
||||||
cdcacm_get_composite_devdesc(&dev[ia]);
|
/* Configure the CDC/ACM device */
|
||||||
|
|
||||||
|
/* Ask the cdcacm driver to fill in the constants we didn't
|
||||||
|
* know here.
|
||||||
|
*/
|
||||||
|
|
||||||
|
cdcacm_get_composite_devdesc(&dev[0]);
|
||||||
|
|
||||||
/* Overwrite and correct some values... */
|
/* Overwrite and correct some values... */
|
||||||
/* The callback functions for the CDC/ACM class */
|
/* The callback functions for the CDC/ACM class */
|
||||||
|
|
||||||
dev[ia].classobject = cdcacm_classobject;
|
dev[0].classobject = board_cdcclassobject;
|
||||||
dev[ia].uninitialize = cdcacm_uninitialize;
|
dev[0].uninitialize = board_cdcuninitialize;
|
||||||
|
|
||||||
dev[ia].minor = ia; /* The minor interface number */
|
|
||||||
|
|
||||||
/* Interfaces */
|
/* Interfaces */
|
||||||
|
|
||||||
dev[ia].devdesc.ifnobase = ifnobase; /* Offset to Interface-IDs */
|
dev[0].devdesc.ifnobase = ifnobase; /* Offset to Interface-IDs */
|
||||||
|
dev[0].minor = CONFIG_SYSTEM_COMPOSITE_TTYUSB; /* The minor interface number */
|
||||||
|
|
||||||
/* Strings */
|
/* Strings */
|
||||||
|
|
||||||
dev[ia].devdesc.strbase = strbase; /* Offset to String Numbers */
|
dev[0].devdesc.strbase = strbase; /* Offset to String Numbers */
|
||||||
|
|
||||||
/* Endpoints */
|
/* Endpoints */
|
||||||
|
|
||||||
dev[ia].devdesc.epno[CDCACM_EP_INTIN_IDX] = 7 + ia;
|
dev[0].devdesc.epno[CDCACM_EP_INTIN_IDX] = 3;
|
||||||
dev[ia].devdesc.epno[CDCACM_EP_BULKIN_IDX] = 1 + ia * 2;
|
dev[0].devdesc.epno[CDCACM_EP_BULKIN_IDX] = 4;
|
||||||
dev[ia].devdesc.epno[CDCACM_EP_BULKOUT_IDX] = 2 + ia * 2;
|
dev[0].devdesc.epno[CDCACM_EP_BULKOUT_IDX] = 5;
|
||||||
|
|
||||||
ifnobase += dev[ia].devdesc.ninterfaces;
|
/* Count up the base numbers */
|
||||||
strbase += dev[ia].devdesc.nstrings;
|
|
||||||
|
ifnobase += dev[0].devdesc.ninterfaces;
|
||||||
|
strbase += dev[0].devdesc.nstrings;
|
||||||
|
|
||||||
|
/* Configure the mass storage device device */
|
||||||
|
/* Ask the usbmsc driver to fill in the constants we didn't
|
||||||
|
* know here.
|
||||||
|
*/
|
||||||
|
|
||||||
|
usbmsc_get_composite_devdesc(&dev[1]);
|
||||||
|
|
||||||
|
/* Overwrite and correct some values... */
|
||||||
|
/* The callback functions for the USBMSC class */
|
||||||
|
|
||||||
|
dev[1].classobject = board_mscclassobject;
|
||||||
|
dev[1].uninitialize = board_mscuninitialize;
|
||||||
|
|
||||||
|
/* Interfaces */
|
||||||
|
|
||||||
|
dev[1].devdesc.ifnobase = ifnobase; /* Offset to Interface-IDs */
|
||||||
|
dev[1].minor = CONFIG_SYSTEM_COMPOSITE_DEVMINOR1; /* The minor interface number */
|
||||||
|
|
||||||
|
/* Strings */
|
||||||
|
|
||||||
|
dev[1].devdesc.strbase = strbase; /* Offset to String Numbers */
|
||||||
|
|
||||||
|
/* Endpoints */
|
||||||
|
|
||||||
|
dev[1].devdesc.epno[USBMSC_EP_BULKIN_IDX] = 1;
|
||||||
|
dev[1].devdesc.epno[USBMSC_EP_BULKOUT_IDX] = 2;
|
||||||
|
|
||||||
|
/* Count up the base numbers */
|
||||||
|
|
||||||
|
ifnobase += dev[1].devdesc.ninterfaces;
|
||||||
|
strbase += dev[1].devdesc.nstrings;
|
||||||
|
|
||||||
|
return composite_initialize(2, dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
return composite_initialize(3, dev);
|
/* Configuration with three CDC/ACMs
|
||||||
#endif
|
*
|
||||||
|
* This configuration can be used e.g. on a samv71-xult. The samv71 has
|
||||||
|
* 10 Endpoints (EPs). The EPs 0 up to 7 are DMA aware. The EPs 8 and 9
|
||||||
|
* are not.
|
||||||
|
*
|
||||||
|
* In a composite device we need the EP0 as an control Endpoint. Each
|
||||||
|
* CDC/ACM needs one Interrupt driven and two bulk Endpoints. This is
|
||||||
|
* why we configure the EPs 7, 8 and 9 to be the IRQ-EPs and the
|
||||||
|
* EP-Pairs 1/2, 3/4, 5/6 to be the bulk EPs for each device.
|
||||||
|
*
|
||||||
|
* This means, that
|
||||||
|
*
|
||||||
|
* - the Composite device uses EP0 as the control-Endpoint,
|
||||||
|
* - the CDC/ACM 0 uses EP7, EP1 and EP2,
|
||||||
|
* - the CDC/ACM 1 uses EP8, EP3 and EP4,
|
||||||
|
* - the CDC/ACM 2 uses EP9, EP5 and EP6
|
||||||
|
*
|
||||||
|
* as its EP-Configuration.
|
||||||
|
*/
|
||||||
|
|
||||||
|
else if (configid == 1)
|
||||||
|
{
|
||||||
|
struct composite_devdesc_s dev[3];
|
||||||
|
int strbase = COMPOSITE_NSTRIDS;
|
||||||
|
int ifnobase = 0;
|
||||||
|
int ia;
|
||||||
|
|
||||||
|
for (ia = 0; ia < 3; ia++)
|
||||||
|
{
|
||||||
|
/* Ask the cdcacm driver to fill in the constants we didn't know here */
|
||||||
|
|
||||||
|
cdcacm_get_composite_devdesc(&dev[ia]);
|
||||||
|
|
||||||
|
/* Overwrite and correct some values... */
|
||||||
|
/* The callback functions for the CDC/ACM class */
|
||||||
|
|
||||||
|
dev[ia].classobject = cdcacm_classobject;
|
||||||
|
dev[ia].uninitialize = cdcacm_uninitialize;
|
||||||
|
|
||||||
|
dev[ia].minor = ia; /* The minor interface number */
|
||||||
|
|
||||||
|
/* Interfaces */
|
||||||
|
|
||||||
|
dev[ia].devdesc.ifnobase = ifnobase; /* Offset to Interface-IDs */
|
||||||
|
|
||||||
|
/* Strings */
|
||||||
|
|
||||||
|
dev[ia].devdesc.strbase = strbase; /* Offset to String Numbers */
|
||||||
|
|
||||||
|
/* Endpoints */
|
||||||
|
|
||||||
|
dev[ia].devdesc.epno[CDCACM_EP_INTIN_IDX] = 7 + ia;
|
||||||
|
dev[ia].devdesc.epno[CDCACM_EP_BULKIN_IDX] = 1 + ia * 2;
|
||||||
|
dev[ia].devdesc.epno[CDCACM_EP_BULKOUT_IDX] = 2 + ia * 2;
|
||||||
|
|
||||||
|
ifnobase += dev[ia].devdesc.ninterfaces;
|
||||||
|
strbase += dev[ia].devdesc.nstrings;
|
||||||
|
}
|
||||||
|
|
||||||
|
return composite_initialize(3, dev);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_BOARDCTL_USBDEVCTRL && CONFIG_USBDEV_COMPOSITE */
|
#endif /* CONFIG_BOARDCTL_USBDEVCTRL && CONFIG_USBDEV_COMPOSITE */
|
||||||
|
Loading…
Reference in New Issue
Block a user