Commit 5251bc6e authored by Dean Camera's avatar Dean Camera
Browse files

Add new MouseHost Class Driver demo, unfinished, to allow for better testing...

Add new MouseHost Class Driver demo, unfinished, to allow for better testing of the new prototype Host Mode Class Driver framework. Flesh out start of a HID class Host mode class driver.
parent 05fa6e0c
......@@ -76,6 +76,8 @@ int main(void)
if (CDC_Host_ConfigurePipes(&VirtualSerial_CDC_Interface, 512) != CDC_ENUMERROR_NoError)
{
printf("Attached device is not a valid CDC device.\r\n");
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
break;
......@@ -83,11 +85,14 @@ int main(void)
if (USB_Host_SetDeviceConfiguration(1) != HOST_SENDCONTROL_Successful)
{
printf("Error Setting Device Configuration.\r\n");
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
break;
}
printf("CDC Device Enumerated.\r\n");
USB_HostState = HOST_STATE_Configured;
break;
case HOST_STATE_Configured:
......
/** \file
*
* This file contains special DoxyGen information for the generation of the main page and other special
* documentation pages. It is not a project source file.
*/
/** \mainpage CDC Host Demo
*
* \section SSec_Compat Demo Compatibility:
*
* The following table indicates what microcontrollers are compatible with this demo.
*
* - AT90USB1287
* - AT90USB1286
*
* \section SSec_Info USB Information:
*
* The following table gives a rundown of the USB utilization of this demo.
*
* <table>
* <tr>
* <td><b>USB Mode:</b></td>
* <td>Host</td>
* </tr>
* <tr>
* <td><b>USB Class:</b></td>
* <td>Communications Device Class (CDC)</td>
* </tr>
* <tr>
* <td><b>USB Subclass:</b></td>
* <td>Abstract Control Model (ACM)</td>
* </tr>
* <tr>
* <td><b>Relevant Standards:</b></td>
* <td>USBIF CDC Class Standard</td>
* </tr>
* <tr>
* <td><b>Usable Speeds:</b></td>
* <td>Full Speed Mode</td>
* </tr>
* </table>
*
* \section SSec_Description Project Description:
*
* CDC host demonstration application. This gives a simple reference application
* for implementing a USB CDC host, for CDC devices using the standard ACM profile.
*
* This demo prints out received CDC data through the serial port.
*
* Note that this demo is only compatible with devices which report the correct CDC
* and ACM class, subclass and protocol values. Most USB-Serial cables have vendor
* specific features, thus use vendor-specific class/subclass/protocol codes to force
* the user to use specialized drivers. This demo is not compatible with such devices.
*
* \section SSec_Options Project Options
*
* The following defines can be found in this demo, which can control the demo behaviour when defined, or changed in value.
*
* <table>
* <tr>
* <td>
* None
* </td>
* </tr>
* </table>
*/
This diff is collapsed.
/*
LUFA Library
Copyright (C) Dean Camera, 2009.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, and distribute this software
and its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of
this software.
*/
/** \file
*
* Main source file for the MouseHost demo. This file contains the main tasks of
* the demo and is responsible for the initial application hardware configuration.
*/
#include "MouseHost.h"
/** LUFA HID Class driver interface configuration and state information. This structure is
* passed to all HID Class driver functions, so that multiple instances of the same class
* within a device can be differentiated from one another.
*/
USB_ClassInfo_HID_Host_t Mouse_HID_Interface =
{
.Config =
{
.DataINPipeNumber = 1,
.DataOUTPipeNumber = 2,
.MatchInterfaceProtocol = true,
.HIDInterfaceProtocol = 0x02,
},
.State =
{
// Leave all state values to their defaults
}
};
/** Main program entry point. This routine configures the hardware required by the application, then
* starts the scheduler to run the application tasks.
*/
int main(void)
{
SetupHardware();
puts_P(PSTR(ESC_FG_CYAN "Mouse Host Demo running.\r\n" ESC_FG_WHITE));
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
for (;;)
{
switch (USB_HostState)
{
case HOST_STATE_Addressed:
LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
if (HID_Host_ConfigurePipes(&Mouse_HID_Interface, 512) != HID_ENUMERROR_NoError)
{
printf("Attached device is not a valid Mouse.\r\n");
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
break;
}
if (USB_Host_SetDeviceConfiguration(1) != HOST_SENDCONTROL_Successful)
{
printf("Error Setting Device Configuration.\r\n");
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
break;
}
printf("Mouse Enumerated.\r\n");
USB_HostState = HOST_STATE_Configured;
break;
case HOST_STATE_Configured:
break;
}
HID_Host_USBTask(&Mouse_HID_Interface);
USB_USBTask();
}
}
/** Configures the board hardware and chip peripherals for the demo's functionality. */
void SetupHardware(void)
{
/* Disable watchdog if enabled by bootloader/fuses */
MCUSR &= ~(1 << WDRF);
wdt_disable();
/* Disable clock division */
clock_prescale_set(clock_div_1);
/* Hardware Initialization */
SerialStream_Init(9600, false);
LEDs_Init();
USB_Init();
}
/** Event handler for the USB_DeviceAttached event. This indicates that a device has been attached to the host, and
* starts the library USB task to begin the enumeration and USB management process.
*/
void EVENT_USB_DeviceAttached(void)
{
puts_P(PSTR("Device Attached.\r\n"));
LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
}
/** Event handler for the USB_DeviceUnattached event. This indicates that a device has been removed from the host, and
* stops the library USB task management process.
*/
void EVENT_USB_DeviceUnattached(void)
{
puts_P(PSTR("\r\nDevice Unattached.\r\n"));
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
}
/** Event handler for the USB_DeviceEnumerationComplete event. This indicates that a device has been successfully
* enumerated by the host and is now ready to be used by the application.
*/
void EVENT_USB_DeviceEnumerationComplete(void)
{
LEDs_SetAllLEDs(LEDMASK_USB_READY);
}
/** Event handler for the USB_HostError event. This indicates that a hardware error occurred while in host mode. */
void EVENT_USB_HostError(const uint8_t ErrorCode)
{
USB_ShutDown();
puts_P(PSTR(ESC_FG_RED "Host Mode Error\r\n"));
printf_P(PSTR(" -- Error Code %d\r\n" ESC_FG_WHITE), ErrorCode);
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
for(;;);
}
/** Event handler for the USB_DeviceEnumerationFailed event. This indicates that a problem occurred while
* enumerating an attached USB device.
*/
void EVENT_USB_DeviceEnumerationFailed(const uint8_t ErrorCode, const uint8_t SubErrorCode)
{
puts_P(PSTR(ESC_FG_RED "Dev Enum Error\r\n"));
printf_P(PSTR(" -- Error Code %d\r\n"), ErrorCode);
printf_P(PSTR(" -- Sub Error Code %d\r\n"), SubErrorCode);
printf_P(PSTR(" -- In State %d\r\n" ESC_FG_WHITE), USB_HostState);
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
}
/*
LUFA Library
Copyright (C) Dean Camera, 2009.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, and distribute this software
and its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of
this software.
*/
/** \file
*
* Header file for MouseHost.c.
*/
#ifndef _MOUSE_HOST_H_
#define _MOUSE_HOST_H_
/* Includes: */
#include <avr/io.h>
#include <avr/wdt.h>
#include <avr/pgmspace.h>
#include <avr/power.h>
#include <stdio.h>
#include <LUFA/Version.h>
#include <LUFA/Drivers/Misc/TerminalCodes.h>
#include <LUFA/Drivers/Peripheral/SerialStream.h>
#include <LUFA/Drivers/Board/LEDs.h>
#include <LUFA/Drivers/USB/USB.h>
#include <LUFA/Drivers/USB/Class/Host/HID.h>
/* Macros: */
/** LED mask for the library LED driver, to indicate that the USB interface is not ready. */
#define LEDMASK_USB_NOTREADY LEDS_LED1
/** LED mask for the library LED driver, to indicate that the USB interface is enumerating. */
#define LEDMASK_USB_ENUMERATING (LEDS_LED2 | LEDS_LED3)
/** LED mask for the library LED driver, to indicate that the USB interface is ready. */
#define LEDMASK_USB_READY (LEDS_LED2 | LEDS_LED4)
/** LED mask for the library LED driver, to indicate that an error has occurred in the USB interface. */
#define LEDMASK_USB_ERROR (LEDS_LED1 | LEDS_LED3)
/* Function Prototypes: */
void SetupHardware(void);
void EVENT_USB_HostError(const uint8_t ErrorCode);
void EVENT_USB_DeviceAttached(void);
void EVENT_USB_DeviceUnattached(void);
void EVENT_USB_DeviceEnumerationFailed(const uint8_t ErrorCode, const uint8_t SubErrorCode);
void EVENT_USB_DeviceEnumerationComplete(void);
#endif
This diff is collapsed.
This diff is collapsed.
......@@ -93,7 +93,7 @@ uint8_t CDC_Host_ConfigurePipes(USB_ClassInfo_CDC_Host_t* CDCInterfaceInfo, uint
if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
DComp_CDC_Host_NextInterfaceCDCDataEndpoint) != DESCRIPTOR_SEARCH_COMP_Found)
{
return CDC_ENUMERROR_NoEndpointFound;
return CDC_ENUMERROR_EndpointsNotFound;
}
}
......
......@@ -71,8 +71,6 @@
*/
struct
{
uint8_t ControlInterfaceNumber; /**< Interface number of the CDC control interface within the device */
uint16_t DataINPipeSize; /**< Size in bytes of the CDC interface's IN data pipe */
uint16_t DataOUTPipeSize; /**< Size in bytes of the CDC interface's OUT data pipe */
uint16_t NotificationPipeSize; /**< Size in bytes of the CDC interface's IN notification endpoint, if used */
......@@ -114,11 +112,22 @@
CDC_ENUMERROR_DescriptorTooLarge = 2, /**< The device's Configuration Descriptor is too large to process */
CDC_ENUMERROR_InvalidConfigDataReturned = 3, /**< The device returned an invalid Configuration Descriptor */
CDC_ENUMERROR_NoCDCInterfaceFound = 4, /**< A compatible CDC interface was not found in the device's Configuration Descriptor */
CDC_ENUMERROR_NoEndpointFound = 5, /**< Compatible CDC endpoints were not found in the device's CDC interface */
CDC_ENUMERROR_EndpointsNotFound = 5, /**< Compatible CDC endpoints were not found in the device's CDC interface */
} CDCHost_EnumerationFailure_ErrorCodes_t;
/* Function Prototypes: */
void CDC_Host_USBTask(USB_ClassInfo_CDC_Host_t* CDCInterfaceInfo);
uint8_t CDC_Host_ConfigurePipes(USB_ClassInfo_CDC_Host_t* CDCInterfaceInfo, uint16_t MaxConfigBufferSize);
void EVENT_CDC_Host_ControLineStateChanged(USB_ClassInfo_CDC_Host_t* CDCInterfaceInfo);
uint8_t CDC_Host_SetLineEncoding(USB_ClassInfo_CDC_Host_t* CDCInterfaceInfo);
uint8_t CDC_Host_SendControlLineStateChange(USB_ClassInfo_CDC_Host_t* CDCInterfaceInfo);
void CDC_Host_SendString(USB_ClassInfo_CDC_Host_t* CDCInterfaceInfo, char* Data, uint16_t Length);
void CDC_Host_SendByte(USB_ClassInfo_CDC_Host_t* CDCInterfaceInfo, uint8_t Data);
uint16_t CDC_Host_BytesReceived(USB_ClassInfo_CDC_Host_t* CDCInterfaceInfo);
uint8_t CDC_Host_ReceiveByte(USB_ClassInfo_CDC_Host_t* CDCInterfaceInfo);
/* Private Interface - For use in library only: */
#if !defined(__DOXYGEN__)
......@@ -139,21 +148,7 @@
static uint8_t DComp_CDC_Host_NextCDCControlInterface(void* CurrentDescriptor);
static uint8_t DComp_CDC_Host_NextCDCDataInterface(void* CurrentDescriptor);
static uint8_t DComp_CDC_Host_NextInterfaceCDCDataEndpoint(void* CurrentDescriptor);
#endif
uint8_t CDC_Host_ConfigurePipes(USB_ClassInfo_CDC_Host_t* CDCInterfaceInfo, uint16_t MaxConfigBufferSize);
void CDC_Host_USBTask(USB_ClassInfo_CDC_Host_t* CDCInterfaceInfo);
void EVENT_CDC_Host_ControLineStateChanged(USB_ClassInfo_CDC_Host_t* CDCInterfaceInfo);
uint8_t CDC_Host_SetLineEncoding(USB_ClassInfo_CDC_Host_t* CDCInterfaceInfo);
uint8_t CDC_Host_SendControlLineStateChange(USB_ClassInfo_CDC_Host_t* CDCInterfaceInfo);
void CDC_Host_SendString(USB_ClassInfo_CDC_Host_t* CDCInterfaceInfo, char* Data, uint16_t Length);
void CDC_Host_SendByte(USB_ClassInfo_CDC_Host_t* CDCInterfaceInfo, uint8_t Data);
uint16_t CDC_Host_BytesReceived(USB_ClassInfo_CDC_Host_t* CDCInterfaceInfo);
uint8_t CDC_Host_ReceiveByte(USB_ClassInfo_CDC_Host_t* CDCInterfaceInfo);
#endif
#endif
/* Disable C linkage for C++ Compilers: */
......
......@@ -31,6 +31,106 @@
#include "../../HighLevel/USBMode.h"
#if defined(USB_CAN_BE_HOST)
#define INCLUDE_FROM_HID_CLASS_HOST_C
#include "HID.h"
uint8_t HID_Host_ConfigurePipes(USB_ClassInfo_HID_Host_t* HIDInterfaceInfo, uint16_t MaxConfigBufferSize)
{
uint8_t* ConfigDescriptorData;
uint16_t ConfigDescriptorSize;
uint8_t FoundEndpoints = 0;
if (USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, NULL) != HOST_SENDCONTROL_Successful)
return HID_ENUMERROR_ControlError;
if (ConfigDescriptorSize > MaxConfigBufferSize)
return HID_ENUMERROR_DescriptorTooLarge;
ConfigDescriptorData = alloca(ConfigDescriptorSize);
USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData);
if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration)
return HID_ENUMERROR_InvalidConfigDataReturned;
do
{
if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
DComp_HID_Host_NextHIDInterface) != DESCRIPTOR_SEARCH_COMP_Found)
{
return HID_ENUMERROR_NoHIDInterfaceFound;
}
} while (HIDInterfaceInfo->Config.MatchInterfaceProtocol &&
DESCRIPTOR_PCAST(ConfigDescriptorData,
USB_Descriptor_Interface_t)->HIDInterfaceProtocol != HIDInterfaceInfo->Config.Protocol);
while (FoundEndpoints != ((1 << HID_FOUND_DATAPIPE_IN) | (1 << HID_FOUND_DATAPIPE_OUT)))
{
if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
DComp_HID_Host_NextInterfaceHIDDataEndpoint) != DESCRIPTOR_SEARCH_COMP_Found)
{
if (FoundEndpoints == (1 << HID_FOUND_DATAPIPE_IN))
break;
return HID_ENUMERROR_EndpointsNotFound;
}
USB_Descriptor_Endpoint_t* EndpointData = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Endpoint_t);
if (EndpointData->EndpointAddress & ENDPOINT_DESCRIPTOR_DIR_IN)
{
Pipe_ConfigurePipe(HIDInterfaceInfo->Config.DataINPipeNumber, EP_TYPE_INTERRUPT, PIPE_TOKEN_IN,
EndpointData->EndpointAddress, EndpointData->EndpointSize, PIPE_BANK_SINGLE);
FoundEndpoints |= (1 << HID_FOUND_DATAPIPE_IN);
}
else
{
Pipe_ConfigurePipe(HIDInterfaceInfo->Config.DataOUTPipeNumber, EP_TYPE_INTERRUPT, PIPE_TOKEN_OUT,
EndpointData->EndpointAddress, EndpointData->EndpointSize, PIPE_BANK_SINGLE);
FoundEndpoints |= (1 << HID_FOUND_DATAPIPE_OUT);
}
}
return HID_ENUMERROR_NoError;
}
static uint8_t DComp_HID_Host_NextHIDInterface(void* CurrentDescriptor)
{
if (DESCRIPTOR_TYPE(CurrentDescriptor) == DTYPE_Interface)
{
USB_Descriptor_Interface_t* CurrentInterface = DESCRIPTOR_PCAST(CurrentDescriptor,
USB_Descriptor_Interface_t);
if (CurrentInterface->Class == HID_INTERFACE_CLASS)
return DESCRIPTOR_SEARCH_Found;
}
return DESCRIPTOR_SEARCH_NotFound;
}
static uint8_t DComp_HID_Host_NextInterfaceHIDDataEndpoint(void* CurrentDescriptor)
{
if (DESCRIPTOR_TYPE(CurrentDescriptor) == DTYPE_Endpoint)
{
USB_Descriptor_Endpoint_t* CurrentEndpoint = DESCRIPTOR_PCAST(CurrentDescriptor,
USB_Descriptor_Endpoint_t);
if (!(Pipe_IsEndpointBound(CurrentEndpoint->EndpointAddress)))
return DESCRIPTOR_SEARCH_Found;
}
else if (DESCRIPTOR_TYPE(CurrentDescriptor) == DTYPE_Interface)
{
return DESCRIPTOR_SEARCH_Fail;
}
return DESCRIPTOR_SEARCH_NotFound;
}
void HID_Host_USBTask(USB_ClassInfo_HID_Host_t* HIDInterfaceInfo)
{
}
#endif
......@@ -54,8 +54,63 @@
#endif
/* Public Interface - May be used in end-application: */
/* Type Defines: */
/** Class state structure. An instance of this structure should be made within the user application,
* and passed to each of the HID class driver functions as the HIDInterfaceInfo parameter. This
* stores each HID interface's configuration and state information.
*/
typedef struct
{
const struct
{
uint8_t DataINPipeNumber; /**< Pipe number of the HID interface's IN data pipe */
uint8_t DataOUTPipeNumber; /**< Pipe number of the HID interface's OUT data pipe */
bool MatchInterfaceProtocol;
uint8_t HIDInterfaceProtocol;
} Config; /**< Config data for the USB class interface within the device. All elements in this section
* <b>must</b> be set or the interface will fail to enumerate and operate correctly.
*/
struct
{
uint16_t DataINPipeSize; /**< Size in bytes of the HID interface's IN data pipe */
uint16_t DataOUTPipeSize; /**< Size in bytes of the HID interface's OUT data pipe */
} State; /**< State data for the USB class interface within the device. All elements in this section
* <b>may</b> be set to initial values, but may also be ignored to default to sane values when
* the interface is enumerated.
*/
} USB_ClassInfo_HID_Host_t;
/* Enums: */
enum
{
HID_ENUMERROR_NoError = 0, /**< Configuration Descriptor was processed successfully */
HID_ENUMERROR_ControlError = 1, /**< A control request to the device failed to complete successfully */
HID_ENUMERROR_DescriptorTooLarge = 2, /**< The device's Configuration Descriptor is too large to process */
HID_ENUMERROR_InvalidConfigDataReturned = 3, /**< The device returned an invalid Configuration Descriptor */
HID_ENUMERROR_NoHIDInterfaceFound = 4, /**< A compatible HID interface was not found in the device's Configuration Descriptor */
HID_ENUMERROR_EndpointsNotFound = 5, /**< Compatible HID endpoints were not found in the device's CDC interface */
} CDCHost_EnumerationFailure_ErrorCodes_t;
/* Function Prototypes: */
void HID_Host_USBTask(USB_ClassInfo_HID_Host_t* HIDInterfaceInfo);
uint8_t HID_Host_ConfigurePipes(USB_ClassInfo_HID_Host_t* HIDInterfaceInfo, uint16_t MaxConfigBufferSize);
/* Private Interface - For use in library only: */
#if !defined(__DOXYGEN__)
/* Macros: */
#define HID_INTERFACE_CLASS 0x03
#define HID_FOUND_DATAPIPE_IN (1 << 0)
#define HID_FOUND_DATAPIPE_OUT (1 << 1)
/* Function Prototypes: */
#if defined(INCLUDE_FROM_HID_CLASS_HOST_C)
static uint8_t DComp_HID_Host_NextHIDInterface(void* CurrentDescriptor);
static uint8_t DComp_HID_Host_NextInterfaceHIDDataEndpoint(void* CurrentDescriptor);
#endif
#endif
/* Disable C linkage for C++ Compilers: */
#if defined(__cplusplus)
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment