[LUFA] Virtual serial and keyboard

Go To Last Post
11 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi,

I am trying to have a device recognized as a virtual serial port and a keyboard by the computer with the LUFA library. I am using an atmega32u4 clocked at 8MHz.

I managed to send and receive data with the serial port and to send keystrokes with the keyboard. However I can't have the device receive a led report when it is enumareted as a composite device. But I get a report when the device is configured only as a keyboard.

I do not understand why the behavior is different in both cases. I searched in the demos but I only found a virtual serial and mouse device.

Maybe the descriptor is bad constructed when I enable the serial port and the keyboard ?

 

Do you see anything wrong with the code ? I attached a minimal example to the post. If there are not enough comments in the code or whatever, I will try to correct it as soon as possible.

 

Thanks,
Thomas

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Maybe the descriptor can be useful :

const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
{
	.Config =
		{
			.Header                 = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration},

			.TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t),
			#if defined(KEYBOARD_ENABLE) && defined(SERIAL_ENABLE)
			.TotalInterfaces        = 3,
			#elif defined(SERIAL_ENABLE)
			.TotalInterfaces		= 2,
			#elif defined(KEYBOARD_ENABLE)
			.TotalInterfaces		= 1,
			#endif

			.ConfigurationNumber    = 1,
			.ConfigurationStrIndex  = NO_DESCRIPTOR,

			.ConfigAttributes       = (USB_CONFIG_ATTR_RESERVED),

			.MaxPowerConsumption    = USB_CONFIG_POWER_MA(30)
		},
#if defined(SERIAL_ENABLE) && defined(KEYBOARD_ENABLE)
		.CDC_IAD =
		{
			.Header                 = {.Size = sizeof(USB_Descriptor_Interface_Association_t), .Type = DTYPE_InterfaceAssociation},

			.FirstInterfaceIndex    = INTERFACE_ID_CDC_CCI,
			.TotalInterfaces        = 2,

			.Class                  = CDC_CSCP_CDCClass,
			.SubClass               = CDC_CSCP_ACMSubclass,
			.Protocol               = CDC_CSCP_ATCommandProtocol,

			.IADStrIndex            = NO_DESCRIPTOR
		},
#endif

#if defined(SERIAL_ENABLE)
	.CDC_CCI_Interface =
		{
			.Header                 = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},

			.InterfaceNumber        = INTERFACE_ID_CDC_CCI,
			.AlternateSetting       = 0,

			.TotalEndpoints         = 1,

			.Class                  = CDC_CSCP_CDCClass,
			.SubClass               = CDC_CSCP_ACMSubclass,
			.Protocol               = CDC_CSCP_ATCommandProtocol,

			.InterfaceStrIndex      = NO_DESCRIPTOR
		},

	.CDC_Functional_Header =
		{
			.Header                 = {.Size = sizeof(USB_CDC_Descriptor_FunctionalHeader_t), .Type = DTYPE_CSInterface},
			.Subtype                = CDC_DSUBTYPE_CSInterface_Header,

			.CDCSpecification       = VERSION_BCD(1,1,0),
		},

	.CDC_Functional_ACM =
		{
			.Header                 = {.Size = sizeof(USB_CDC_Descriptor_FunctionalACM_t), .Type = DTYPE_CSInterface},
			.Subtype                = CDC_DSUBTYPE_CSInterface_ACM,

			.Capabilities           = 0x06,
		},

	.CDC_Functional_Union =
		{
			.Header                 = {.Size = sizeof(USB_CDC_Descriptor_FunctionalUnion_t), .Type = DTYPE_CSInterface},
			.Subtype                = CDC_DSUBTYPE_CSInterface_Union,

			.MasterInterfaceNumber  = INTERFACE_ID_CDC_CCI,
			.SlaveInterfaceNumber   = INTERFACE_ID_CDC_DCI,
		},

	.CDC_NotificationEndpoint =
		{
			.Header                 = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},

			.EndpointAddress        = CDC_NOTIFICATION_EPADDR,
			.Attributes             = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
			.EndpointSize           = CDC_NOTIFICATION_EPSIZE,
			.PollingIntervalMS      = 0xFF
		},

	.CDC_DCI_Interface =
		{
			.Header                 = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},

			.InterfaceNumber        = INTERFACE_ID_CDC_DCI,
			.AlternateSetting       = 0,

			.TotalEndpoints         = 2,

			.Class                  = CDC_CSCP_CDCDataClass,
			.SubClass               = CDC_CSCP_NoDataSubclass,
			.Protocol               = CDC_CSCP_NoDataProtocol,

			.InterfaceStrIndex      = NO_DESCRIPTOR
		},

	.CDC_DataOutEndpoint =
		{
			.Header                 = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},

			.EndpointAddress        = CDC_RX_EPADDR,
			.Attributes             = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
			.EndpointSize           = CDC_TXRX_EPSIZE,
			.PollingIntervalMS      = 0x05
		},

	.CDC_DataInEndpoint =
		{
			.Header                 = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},

			.EndpointAddress        = CDC_TX_EPADDR,
			.Attributes             = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
			.EndpointSize           = CDC_TXRX_EPSIZE,
			.PollingIntervalMS      = 0x05
		},
#endif
#if defined(KEYBOARD_ENABLE)
		.HID_Interface =
		{
			.Header                 = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},

			.InterfaceNumber        = INTERFACE_ID_Keyboard,
			.AlternateSetting       = 0x00,

			.TotalEndpoints         = 2,

			.Class                  = HID_CSCP_HIDClass,
			.SubClass               = HID_CSCP_BootSubclass,
			.Protocol               = HID_CSCP_KeyboardBootProtocol,

			.InterfaceStrIndex      = NO_DESCRIPTOR
		},

	.HID_KeyboardHID =
		{
			.Header                 = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID},

			.HIDSpec                = VERSION_BCD(1,1,1),
			.CountryCode            = 0x00,
			.TotalReportDescriptors = 1,
			.HIDReportType          = HID_DTYPE_Report,
			.HIDReportLength        = sizeof(KeyboardReport)
		},

	.HID_ReportINEndpoint =
		{
			.Header                 = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},

			.EndpointAddress        = KEYBOARD_IN_EPADDR,
			.Attributes             = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
			.EndpointSize           = KEYBOARD_EPSIZE,
			.PollingIntervalMS      = 0x05
		},

	.HID_ReportOUTEndpoint =
		{
			.Header                 = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},

			.EndpointAddress        = KEYBOARD_OUT_EPADDR,
			.Attributes             = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
			.EndpointSize           = KEYBOARD_EPSIZE,
			.PollingIntervalMS      = 0x05
		}
#endif
};

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You mean you succesfully solved your problem with that descriptor?
.
MG

I don't know why I'm still doing this hobby

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

And what was it, specifically, about that descriptor that made it work - as opposed to what you'd tried before?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Sorry I have expressed myself badly. I meant the descriptor can be useful to resolve the problem. It was just to make it more visible to people who don't download the attachment.

I am still stuck with this problem and I have not yet found solutions to it.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

May I ask you what you want to build by combining keyboard and serial interface?
Maybe there's a more simple way.
.
MG

I don't know why I'm still doing this hobby

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I want to create a device which can send keystroke to the computer (for typing a password), and the serial port is here to provide interface with the system's memory (32Kb).  All of this work but I can't manage to receive the led report.

I have tested the device (with the exact same code) by connecting it to the bios of my computer and I received the led report successfuly, the led was on when caps lock or num lock were on, but it still doesn't work when connecting it to a normal os.

 

 

Last Edited: Tue. Aug 15, 2017 - 07:47 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

thomas29 wrote:
I have tested the device (with the exact same code) by connecting it to the bios of my computer and I received the led report successfuly ... but it still doesn't work when connecting it to a normal os.

I don't understand that: how can you "connect to the BIOS" other than through the OS ?

 

Please clarify ...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ok first sorry for the bad english, and so my explication, this is not my native language. Thanks for your patience.

I mean I boot the pc, press the f12 key, enter the bios setup and try to write something with the device. And when I connected the device the led light up according to the state of the caps lock and the num lock.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

thomas29 wrote:
I mean I boot the pc, press the f12 key, enter the bios setup
The BIOS is a small program in the ROM of the PC. It has just enough of a USB supporting stack to support a keyboard (and perhaps a mouse). So don't expect it to be able to enumerate and support a multi class device.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ok so this is why it supports only the keyboard and that I receive the led report. The problem is still the same : I am unable to receive a led report when the computer enumerate my device as a composite device.