Add svn:eol-style property to source files, so that the line endings are correctly converted to the target system's native end of line style.

This commit is contained in:
Dean Camera 2010-05-08 03:12:14 +00:00
parent e331b531c6
commit 071e02c6b6
839 changed files with 274562 additions and 274562 deletions

File diff suppressed because it is too large Load diff

View file

@ -1,130 +1,130 @@
/* /*
LUFA Library LUFA Library
Copyright (C) Dean Camera, 2010. Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com www.fourwalledcubicle.com
*/ */
/* /*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com) Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the advertising or publicity pertaining to distribution of the
software without specific, written prior permission. software without specific, written prior permission.
The author disclaim all warranties with regard to this The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action, in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of arising out of or in connection with the use or performance of
this software. this software.
*/ */
/** \file /** \file
* *
* Header file for BootloaderCDC.c. * Header file for BootloaderCDC.c.
*/ */
#ifndef _CDC_H_ #ifndef _CDC_H_
#define _CDC_H_ #define _CDC_H_
/* Includes: */ /* Includes: */
#include <avr/io.h> #include <avr/io.h>
#include <avr/wdt.h> #include <avr/wdt.h>
#include <avr/boot.h> #include <avr/boot.h>
#include <avr/eeprom.h> #include <avr/eeprom.h>
#include <avr/power.h> #include <avr/power.h>
#include <avr/interrupt.h> #include <avr/interrupt.h>
#include <stdbool.h> #include <stdbool.h>
#include "Descriptors.h" #include "Descriptors.h"
#include <LUFA/Drivers/USB/USB.h> #include <LUFA/Drivers/USB/USB.h>
/* Macros: */ /* Macros: */
/** CDC Class Specific request to get the line encoding on a CDC-ACM virtual serial port, including the /** CDC Class Specific request to get the line encoding on a CDC-ACM virtual serial port, including the
* baud rate, parity, stop bits and data bits. * baud rate, parity, stop bits and data bits.
*/ */
#define REQ_GetLineEncoding 0x21 #define REQ_GetLineEncoding 0x21
/** CDC Class Specific request to set the line encoding on a CDC-ACM virtual serial port, including the /** CDC Class Specific request to set the line encoding on a CDC-ACM virtual serial port, including the
* baud rate, parity, stop bits and data bits. * baud rate, parity, stop bits and data bits.
*/ */
#define REQ_SetLineEncoding 0x20 #define REQ_SetLineEncoding 0x20
/** CDC Class Specific request to set the state of the serial handshake lines (such as DCD and RTS) on /** CDC Class Specific request to set the state of the serial handshake lines (such as DCD and RTS) on
* a CDC-ACM virtual serial port. * a CDC-ACM virtual serial port.
*/ */
#define REQ_SetControlLineState 0x22 #define REQ_SetControlLineState 0x22
/** Version major of the CDC bootloader. */ /** Version major of the CDC bootloader. */
#define BOOTLOADER_VERSION_MAJOR 0x01 #define BOOTLOADER_VERSION_MAJOR 0x01
/** Version minor of the CDC bootloader. */ /** Version minor of the CDC bootloader. */
#define BOOTLOADER_VERSION_MINOR 0x00 #define BOOTLOADER_VERSION_MINOR 0x00
/** Hardware version major of the CDC bootloader. */ /** Hardware version major of the CDC bootloader. */
#define BOOTLOADER_HWVERSION_MAJOR 0x01 #define BOOTLOADER_HWVERSION_MAJOR 0x01
/** Hardware version minor of the CDC bootloader. */ /** Hardware version minor of the CDC bootloader. */
#define BOOTLOADER_HWVERSION_MINOR 0x00 #define BOOTLOADER_HWVERSION_MINOR 0x00
/** Eight character bootloader firmware identifier reported to the host when requested */ /** Eight character bootloader firmware identifier reported to the host when requested */
#define SOFTWARE_IDENTIFIER "LUFACDC" #define SOFTWARE_IDENTIFIER "LUFACDC"
/* Type Defines: */ /* Type Defines: */
/** Type define for a non-returning pointer to the start of the loaded application in flash memory. */ /** Type define for a non-returning pointer to the start of the loaded application in flash memory. */
typedef void (*AppPtr_t)(void) ATTR_NO_RETURN; typedef void (*AppPtr_t)(void) ATTR_NO_RETURN;
/** Type define for the CDC-ACM virtual serial port line encoding options, including baud rate, format, parity /** Type define for the CDC-ACM virtual serial port line encoding options, including baud rate, format, parity
* and size of each data chunk in bits. * and size of each data chunk in bits.
*/ */
typedef struct typedef struct
{ {
uint32_t BaudRateBPS; /**< Baud rate in BPS */ uint32_t BaudRateBPS; /**< Baud rate in BPS */
uint8_t CharFormat; /**< Character format, an entry from the BootloaderCDC_CDC_LineCodingFormats_t enum */ uint8_t CharFormat; /**< Character format, an entry from the BootloaderCDC_CDC_LineCodingFormats_t enum */
uint8_t ParityType; /**< Parity mode, an entry from the BootloaderCDC_CDC_LineCodeingParity_t enum */ uint8_t ParityType; /**< Parity mode, an entry from the BootloaderCDC_CDC_LineCodeingParity_t enum */
uint8_t DataBits; /**< Size of each data chunk, in bits */ uint8_t DataBits; /**< Size of each data chunk, in bits */
} CDC_Line_Coding_t; } CDC_Line_Coding_t;
/* Enums: */ /* Enums: */
/** Enum for the possible line encoding formats on a CDC-ACM virtual serial port */ /** Enum for the possible line encoding formats on a CDC-ACM virtual serial port */
enum BootloaderCDC_CDC_LineCodingFormats_t enum BootloaderCDC_CDC_LineCodingFormats_t
{ {
OneStopBit = 0, /**< Single stop bit */ OneStopBit = 0, /**< Single stop bit */
OneAndAHalfStopBits = 1, /**< 1.5 stop bits */ OneAndAHalfStopBits = 1, /**< 1.5 stop bits */
TwoStopBits = 2, /**< Two stop bits */ TwoStopBits = 2, /**< Two stop bits */
}; };
/** Enum for the possible parity modes on a CDC-ACM virtual serial port */ /** Enum for the possible parity modes on a CDC-ACM virtual serial port */
enum BootloaderCDC_CDC_LineCodingParity_t enum BootloaderCDC_CDC_LineCodingParity_t
{ {
Parity_None = 0, /**< No data parity checking */ Parity_None = 0, /**< No data parity checking */
Parity_Odd = 1, /**< Odd data parity checking */ Parity_Odd = 1, /**< Odd data parity checking */
Parity_Even = 2, /**< Even data parity checking */ Parity_Even = 2, /**< Even data parity checking */
Parity_Mark = 3, /**< Mark data parity checking */ Parity_Mark = 3, /**< Mark data parity checking */
Parity_Space = 4, /**< Space data parity checking */ Parity_Space = 4, /**< Space data parity checking */
}; };
/* Function Prototypes: */ /* Function Prototypes: */
void CDC_Task(void); void CDC_Task(void);
void SetupHardware(void); void SetupHardware(void);
void EVENT_USB_Device_ConfigurationChanged(void); void EVENT_USB_Device_ConfigurationChanged(void);
void EVENT_USB_Device_UnhandledControlRequest(void); void EVENT_USB_Device_UnhandledControlRequest(void);
#if defined(INCLUDE_FROM_BOOTLOADERCDC_C) || defined(__DOXYGEN__) #if defined(INCLUDE_FROM_BOOTLOADERCDC_C) || defined(__DOXYGEN__)
static void ReadWriteMemoryBlock(const uint8_t Command); static void ReadWriteMemoryBlock(const uint8_t Command);
static uint8_t FetchNextCommandByte(void); static uint8_t FetchNextCommandByte(void);
static void WriteNextResponseByte(const uint8_t Response); static void WriteNextResponseByte(const uint8_t Response);
#endif #endif
#endif #endif

View file

@ -1,72 +1,72 @@
/** \file /** \file
* *
* This file contains special DoxyGen information for the generation of the main page and other special * 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. * documentation pages. It is not a project source file.
*/ */
/** \mainpage CDC Class USB AVR Bootloader /** \mainpage CDC Class USB AVR Bootloader
* *
* \section SSec_Compat Demo Compatibility: * \section SSec_Compat Demo Compatibility:
* *
* The following list indicates what microcontrollers are compatible with this demo. * The following list indicates what microcontrollers are compatible with this demo.
* *
* - Series 7 USB AVRs * - Series 7 USB AVRs
* - Series 6 USB AVRs * - Series 6 USB AVRs
* - Series 4 USB AVRs * - Series 4 USB AVRs
* - Series 2 USB AVRs * - Series 2 USB AVRs
* *
* \section SSec_Info USB Information: * \section SSec_Info USB Information:
* *
* The following table gives a rundown of the USB utilization of this demo. * The following table gives a rundown of the USB utilization of this demo.
* *
* <table> * <table>
* <tr> * <tr>
* <td><b>USB Mode:</b></td> * <td><b>USB Mode:</b></td>
* <td>Device</td> * <td>Device</td>
* </tr> * </tr>
* <tr> * <tr>
* <td><b>USB Class:</b></td> * <td><b>USB Class:</b></td>
* <td>Communications Device Class (CDC)</td> * <td>Communications Device Class (CDC)</td>
* </tr> * </tr>
* <tr> * <tr>
* <td><b>USB Subclass:</b></td> * <td><b>USB Subclass:</b></td>
* <td>Abstract Control Model (ACM)</td> * <td>Abstract Control Model (ACM)</td>
* </tr> * </tr>
* <tr> * <tr>
* <td><b>Relevant Standards:</b></td> * <td><b>Relevant Standards:</b></td>
* <td>USBIF CDC Class Standard</td> * <td>USBIF CDC Class Standard</td>
* </tr> * </tr>
* <tr> * <tr>
* <td><b>Usable Speeds:</b></td> * <td><b>Usable Speeds:</b></td>
* <td>Full Speed Mode</td> * <td>Full Speed Mode</td>
* </tr> * </tr>
* </table> * </table>
* *
* \section SSec_Description Project Description: * \section SSec_Description Project Description:
* *
* This bootloader enumerates to the host as a CDC Class device (virtual serial port), allowing for AVR109 * This bootloader enumerates to the host as a CDC Class device (virtual serial port), allowing for AVR109
* protocol compatible programming software to load firmware onto the AVR. * protocol compatible programming software to load firmware onto the AVR.
* *
* Out of the box this bootloader builds for the USB1287, and will fit into 4KB of bootloader space. If * Out of the box this bootloader builds for the USB1287, and will fit into 4KB of bootloader space. If
* you wish to enlarge this space and/or change the AVR model, you will need to edit the BOOT_START and MCU * you wish to enlarge this space and/or change the AVR model, you will need to edit the BOOT_START and MCU
* values in the accompanying makefile. * values in the accompanying makefile.
* *
* This bootloader is compatible with the open source application AVRDUDE, or Atmel's AVRPROG. * This bootloader is compatible with the open source application AVRDUDE, or Atmel's AVRPROG.
* *
* After running this bootloader for the first time on a new computer, you will need to supply the .INF * After running this bootloader for the first time on a new computer, you will need to supply the .INF
* file located in this bootloader project's directory as the device's driver when running under Windows. * file located in this bootloader project's directory as the device's driver when running under Windows.
* This will enable Windows to use its inbuilt CDC drivers, negating the need for custom drivers for the * This will enable Windows to use its inbuilt CDC drivers, negating the need for custom drivers for the
* device. Other Operating Systems should automatically use their own inbuilt CDC-ACM drivers. * device. Other Operating Systems should automatically use their own inbuilt CDC-ACM drivers.
* *
* \section SSec_Options Project Options * \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. * The following defines can be found in this demo, which can control the demo behaviour when defined, or changed in value.
* *
* <table> * <table>
* <tr> * <tr>
* <td> * <td>
* None * None
* </td> * </td>
* </tr> * </tr>
* </table> * </table>
*/ */

View file

@ -1,239 +1,239 @@
/* /*
LUFA Library LUFA Library
Copyright (C) Dean Camera, 2010. Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com www.fourwalledcubicle.com
*/ */
/* /*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com) Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the advertising or publicity pertaining to distribution of the
software without specific, written prior permission. software without specific, written prior permission.
The author disclaim all warranties with regard to this The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action, in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of arising out of or in connection with the use or performance of
this software. this software.
*/ */
/** \file /** \file
* *
* USB Device Descriptors, for library use when in USB device mode. Descriptors are special * USB Device Descriptors, for library use when in USB device mode. Descriptors are special
* computer-readable structures which the host requests upon device enumeration, to determine * computer-readable structures which the host requests upon device enumeration, to determine
* the device's capabilities and functions. * the device's capabilities and functions.
*/ */
#include "Descriptors.h" #include "Descriptors.h"
/** Device descriptor structure. This descriptor, located in SRAM memory, describes the overall /** Device descriptor structure. This descriptor, located in SRAM memory, describes the overall
* device characteristics, including the supported USB version, control endpoint size and the * device characteristics, including the supported USB version, control endpoint size and the
* number of device configurations. The descriptor is read out by the USB host when the enumeration * number of device configurations. The descriptor is read out by the USB host when the enumeration
* process begins. * process begins.
*/ */
USB_Descriptor_Device_t DeviceDescriptor = USB_Descriptor_Device_t DeviceDescriptor =
{ {
.Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device}, .Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device},
.USBSpecification = VERSION_BCD(01.10), .USBSpecification = VERSION_BCD(01.10),
.Class = 0x02, .Class = 0x02,
.SubClass = 0x00, .SubClass = 0x00,
.Protocol = 0x00, .Protocol = 0x00,
.Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE, .Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE,
.VendorID = 0x03EB, .VendorID = 0x03EB,
.ProductID = 0x204A, .ProductID = 0x204A,
.ReleaseNumber = 0x0000, .ReleaseNumber = 0x0000,
.ManufacturerStrIndex = NO_DESCRIPTOR, .ManufacturerStrIndex = NO_DESCRIPTOR,
.ProductStrIndex = 0x01, .ProductStrIndex = 0x01,
.SerialNumStrIndex = NO_DESCRIPTOR, .SerialNumStrIndex = NO_DESCRIPTOR,
.NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS .NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS
}; };
/** Configuration descriptor structure. This descriptor, located in SRAM memory, describes the usage /** Configuration descriptor structure. This descriptor, located in SRAM memory, describes the usage
* of the device in one of its supported configurations, including information about any device interfaces * of the device in one of its supported configurations, including information about any device interfaces
* and endpoints. The descriptor is read out by the USB host during the enumeration process when selecting * and endpoints. The descriptor is read out by the USB host during the enumeration process when selecting
* a configuration so that the host may correctly communicate with the USB device. * a configuration so that the host may correctly communicate with the USB device.
*/ */
USB_Descriptor_Configuration_t ConfigurationDescriptor = USB_Descriptor_Configuration_t ConfigurationDescriptor =
{ {
.Config = .Config =
{ {
.Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration}, .Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration},
.TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t), .TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t),
.TotalInterfaces = 2, .TotalInterfaces = 2,
.ConfigurationNumber = 1, .ConfigurationNumber = 1,
.ConfigurationStrIndex = NO_DESCRIPTOR, .ConfigurationStrIndex = NO_DESCRIPTOR,
.ConfigAttributes = USB_CONFIG_ATTR_BUSPOWERED, .ConfigAttributes = USB_CONFIG_ATTR_BUSPOWERED,
.MaxPowerConsumption = USB_CONFIG_POWER_MA(100) .MaxPowerConsumption = USB_CONFIG_POWER_MA(100)
}, },
.CDC_CCI_Interface = .CDC_CCI_Interface =
{ {
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface}, .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
.InterfaceNumber = 0, .InterfaceNumber = 0,
.AlternateSetting = 0, .AlternateSetting = 0,
.TotalEndpoints = 1, .TotalEndpoints = 1,
.Class = 0x02, .Class = 0x02,
.SubClass = 0x02, .SubClass = 0x02,
.Protocol = 0x01, .Protocol = 0x01,
.InterfaceStrIndex = NO_DESCRIPTOR .InterfaceStrIndex = NO_DESCRIPTOR
}, },
.CDC_Functional_IntHeader = .CDC_Functional_IntHeader =
{ {
.Header = {.Size = sizeof(CDC_FUNCTIONAL_DESCRIPTOR(2)), .Type = 0x24}, .Header = {.Size = sizeof(CDC_FUNCTIONAL_DESCRIPTOR(2)), .Type = 0x24},
.SubType = 0x00, .SubType = 0x00,
.Data = {0x10, 0x01} .Data = {0x10, 0x01}
}, },
.CDC_Functional_AbstractControlManagement = .CDC_Functional_AbstractControlManagement =
{ {
.Header = {.Size = sizeof(CDC_FUNCTIONAL_DESCRIPTOR(1)), .Type = 0x24}, .Header = {.Size = sizeof(CDC_FUNCTIONAL_DESCRIPTOR(1)), .Type = 0x24},
.SubType = 0x02, .SubType = 0x02,
.Data = {0x06} .Data = {0x06}
}, },
.CDC_Functional_Union = .CDC_Functional_Union =
{ {
.Header = {.Size = sizeof(CDC_FUNCTIONAL_DESCRIPTOR(2)), .Type = 0x24}, .Header = {.Size = sizeof(CDC_FUNCTIONAL_DESCRIPTOR(2)), .Type = 0x24},
.SubType = 0x06, .SubType = 0x06,
.Data = {0x00, 0x01} .Data = {0x00, 0x01}
}, },
.CDC_ManagementEndpoint = .CDC_ManagementEndpoint =
{ {
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint}, .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
.EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_IN | CDC_NOTIFICATION_EPNUM), .EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_IN | CDC_NOTIFICATION_EPNUM),
.Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
.EndpointSize = CDC_NOTIFICATION_EPSIZE, .EndpointSize = CDC_NOTIFICATION_EPSIZE,
.PollingIntervalMS = 0x02 .PollingIntervalMS = 0x02
}, },
.CDC_DCI_Interface = .CDC_DCI_Interface =
{ {
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface}, .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
.InterfaceNumber = 1, .InterfaceNumber = 1,
.AlternateSetting = 0, .AlternateSetting = 0,
.TotalEndpoints = 2, .TotalEndpoints = 2,
.Class = 0x0A, .Class = 0x0A,
.SubClass = 0x00, .SubClass = 0x00,
.Protocol = 0x00, .Protocol = 0x00,
.InterfaceStrIndex = NO_DESCRIPTOR .InterfaceStrIndex = NO_DESCRIPTOR
}, },
.CDC_DataOutEndpoint = .CDC_DataOutEndpoint =
{ {
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint}, .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
.EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_OUT | CDC_RX_EPNUM), .EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_OUT | CDC_RX_EPNUM),
.Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), .Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
.EndpointSize = CDC_TXRX_EPSIZE, .EndpointSize = CDC_TXRX_EPSIZE,
.PollingIntervalMS = 0x00 .PollingIntervalMS = 0x00
}, },
.CDC_DataInEndpoint = .CDC_DataInEndpoint =
{ {
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint}, .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
.EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_IN | CDC_TX_EPNUM), .EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_IN | CDC_TX_EPNUM),
.Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), .Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
.EndpointSize = CDC_TXRX_EPSIZE, .EndpointSize = CDC_TXRX_EPSIZE,
.PollingIntervalMS = 0x00 .PollingIntervalMS = 0x00
} }
}; };
/** Language descriptor structure. This descriptor, located in SRAM memory, is returned when the host requests /** Language descriptor structure. This descriptor, located in SRAM memory, is returned when the host requests
* the string descriptor with index 0 (the first index). It is actually an array of 16-bit integers, which indicate * the string descriptor with index 0 (the first index). It is actually an array of 16-bit integers, which indicate
* via the language ID table available at USB.org what languages the device supports for its string descriptors. * via the language ID table available at USB.org what languages the device supports for its string descriptors.
*/ */
USB_Descriptor_String_t LanguageString = USB_Descriptor_String_t LanguageString =
{ {
.Header = {.Size = USB_STRING_LEN(1), .Type = DTYPE_String}, .Header = {.Size = USB_STRING_LEN(1), .Type = DTYPE_String},
.UnicodeString = {LANGUAGE_ID_ENG} .UnicodeString = {LANGUAGE_ID_ENG}
}; };
/** Product descriptor string. This is a Unicode string containing the product's details in human readable form, /** Product descriptor string. This is a Unicode string containing the product's details in human readable form,
* and is read out upon request by the host when the appropriate string ID is requested, listed in the Device * and is read out upon request by the host when the appropriate string ID is requested, listed in the Device
* Descriptor. * Descriptor.
*/ */
USB_Descriptor_String_t ProductString = USB_Descriptor_String_t ProductString =
{ {
.Header = {.Size = USB_STRING_LEN(18), .Type = DTYPE_String}, .Header = {.Size = USB_STRING_LEN(18), .Type = DTYPE_String},
.UnicodeString = L"AVR CDC Bootloader" .UnicodeString = L"AVR CDC Bootloader"
}; };
/** This function is called by the library when in device mode, and must be overridden (see LUFA library "USB Descriptors" /** This function is called by the library when in device mode, and must be overridden (see LUFA library "USB Descriptors"
* documentation) by the application code so that the address and size of a requested descriptor can be given * documentation) by the application code so that the address and size of a requested descriptor can be given
* to the USB library. When the device receives a Get Descriptor request on the control endpoint, this function * to the USB library. When the device receives a Get Descriptor request on the control endpoint, this function
* is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the * is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the
* USB host. * USB host.
*/ */
uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, void** const DescriptorAddress) uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, void** const DescriptorAddress)
{ {
const uint8_t DescriptorType = (wValue >> 8); const uint8_t DescriptorType = (wValue >> 8);
const uint8_t DescriptorNumber = (wValue & 0xFF); const uint8_t DescriptorNumber = (wValue & 0xFF);
void* Address = NULL; void* Address = NULL;
uint16_t Size = NO_DESCRIPTOR; uint16_t Size = NO_DESCRIPTOR;
switch (DescriptorType) switch (DescriptorType)
{ {
case DTYPE_Device: case DTYPE_Device:
Address = (void*)&DeviceDescriptor; Address = (void*)&DeviceDescriptor;
Size = sizeof(USB_Descriptor_Device_t); Size = sizeof(USB_Descriptor_Device_t);
break; break;
case DTYPE_Configuration: case DTYPE_Configuration:
Address = (void*)&ConfigurationDescriptor; Address = (void*)&ConfigurationDescriptor;
Size = sizeof(USB_Descriptor_Configuration_t); Size = sizeof(USB_Descriptor_Configuration_t);
break; break;
case DTYPE_String: case DTYPE_String:
if (!(DescriptorNumber)) if (!(DescriptorNumber))
{ {
Address = (void*)&LanguageString; Address = (void*)&LanguageString;
Size = LanguageString.Header.Size; Size = LanguageString.Header.Size;
} }
else else
{ {
Address = (void*)&ProductString; Address = (void*)&ProductString;
Size = ProductString.Header.Size; Size = ProductString.Header.Size;
} }
break; break;
} }
*DescriptorAddress = Address; *DescriptorAddress = Address;
return Size; return Size;
} }

View file

@ -1,146 +1,146 @@
/* /*
LUFA Library LUFA Library
Copyright (C) Dean Camera, 2010. Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com www.fourwalledcubicle.com
*/ */
/* /*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com) Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the advertising or publicity pertaining to distribution of the
software without specific, written prior permission. software without specific, written prior permission.
The author disclaim all warranties with regard to this The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action, in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of arising out of or in connection with the use or performance of
this software. this software.
*/ */
/** \file /** \file
* *
* Header file for Descriptors.c. * Header file for Descriptors.c.
*/ */
#ifndef _DESCRIPTORS_H_ #ifndef _DESCRIPTORS_H_
#define _DESCRIPTORS_H_ #define _DESCRIPTORS_H_
/* Includes: */ /* Includes: */
#include <LUFA/Drivers/USB/USB.h> #include <LUFA/Drivers/USB/USB.h>
/* Macros: */ /* Macros: */
#if defined(__AVR_AT90USB1287__) #if defined(__AVR_AT90USB1287__)
#define AVR_SIGNATURE_1 0x1E #define AVR_SIGNATURE_1 0x1E
#define AVR_SIGNATURE_2 0x97 #define AVR_SIGNATURE_2 0x97
#define AVR_SIGNATURE_3 0x82 #define AVR_SIGNATURE_3 0x82
#elif defined(__AVR_AT90USB647__) #elif defined(__AVR_AT90USB647__)
#define AVR_SIGNATURE_1 0x1E #define AVR_SIGNATURE_1 0x1E
#define AVR_SIGNATURE_2 0x96 #define AVR_SIGNATURE_2 0x96
#define AVR_SIGNATURE_3 0x82 #define AVR_SIGNATURE_3 0x82
#elif defined(__AVR_AT90USB1286__) #elif defined(__AVR_AT90USB1286__)
#define AVR_SIGNATURE_1 0x1E #define AVR_SIGNATURE_1 0x1E
#define AVR_SIGNATURE_2 0x97 #define AVR_SIGNATURE_2 0x97
#define AVR_SIGNATURE_3 0x82 #define AVR_SIGNATURE_3 0x82
#elif defined(__AVR_AT90USB646__) #elif defined(__AVR_AT90USB646__)
#define AVR_SIGNATURE_1 0x1E #define AVR_SIGNATURE_1 0x1E
#define AVR_SIGNATURE_2 0x96 #define AVR_SIGNATURE_2 0x96
#define AVR_SIGNATURE_3 0x82 #define AVR_SIGNATURE_3 0x82
#elif defined(__AVR_ATmega32U6__) #elif defined(__AVR_ATmega32U6__)
#define AVR_SIGNATURE_1 0x1E #define AVR_SIGNATURE_1 0x1E
#define AVR_SIGNATURE_2 0x95 #define AVR_SIGNATURE_2 0x95
#define AVR_SIGNATURE_3 0x88 #define AVR_SIGNATURE_3 0x88
#elif defined(__AVR_ATmega32U4__) #elif defined(__AVR_ATmega32U4__)
#define AVR_SIGNATURE_1 0x1E #define AVR_SIGNATURE_1 0x1E
#define AVR_SIGNATURE_2 0x95 #define AVR_SIGNATURE_2 0x95
#define AVR_SIGNATURE_3 0x87 #define AVR_SIGNATURE_3 0x87
#elif defined(__AVR_ATmega16U4__) #elif defined(__AVR_ATmega16U4__)
#define AVR_SIGNATURE_1 0x1E #define AVR_SIGNATURE_1 0x1E
#define AVR_SIGNATURE_2 0x94 #define AVR_SIGNATURE_2 0x94
#define AVR_SIGNATURE_3 0x88 #define AVR_SIGNATURE_3 0x88
#elif defined(__AVR_ATmega32U2__) #elif defined(__AVR_ATmega32U2__)
#define AVR_SIGNATURE_1 0x1E #define AVR_SIGNATURE_1 0x1E
#define AVR_SIGNATURE_2 0x94 #define AVR_SIGNATURE_2 0x94
#define AVR_SIGNATURE_3 0x82 #define AVR_SIGNATURE_3 0x82
#elif defined(__AVR_ATmega16U2__) #elif defined(__AVR_ATmega16U2__)
#define AVR_SIGNATURE_1 0x1E #define AVR_SIGNATURE_1 0x1E
#define AVR_SIGNATURE_2 0x94 #define AVR_SIGNATURE_2 0x94
#define AVR_SIGNATURE_3 0x89 #define AVR_SIGNATURE_3 0x89
#elif defined(__AVR_AT90USB162__) #elif defined(__AVR_AT90USB162__)
#define AVR_SIGNATURE_1 0x1E #define AVR_SIGNATURE_1 0x1E
#define AVR_SIGNATURE_2 0x94 #define AVR_SIGNATURE_2 0x94
#define AVR_SIGNATURE_3 0x82 #define AVR_SIGNATURE_3 0x82
#elif defined(__AVR_ATmega8U2__) #elif defined(__AVR_ATmega8U2__)
#define AVR_SIGNATURE_1 0x1E #define AVR_SIGNATURE_1 0x1E
#define AVR_SIGNATURE_2 0x93 #define AVR_SIGNATURE_2 0x93
#define AVR_SIGNATURE_3 0x82 #define AVR_SIGNATURE_3 0x82
#elif defined(__AVR_AT90USB82__) #elif defined(__AVR_AT90USB82__)
#define AVR_SIGNATURE_1 0x1E #define AVR_SIGNATURE_1 0x1E
#define AVR_SIGNATURE_2 0x93 #define AVR_SIGNATURE_2 0x93
#define AVR_SIGNATURE_3 0x89 #define AVR_SIGNATURE_3 0x89
#else #else
#error The selected AVR part is not currently supported by this bootloader. #error The selected AVR part is not currently supported by this bootloader.
#endif #endif
/** Structure for a CDC class Functional descriptor, with a given data size. This is used instead of a /** Structure for a CDC class Functional descriptor, with a given data size. This is used instead of a
* type define so that the same macro can be used for functional descriptors of varying data lengths, * type define so that the same macro can be used for functional descriptors of varying data lengths,
* while allowing the sizeof() operator to return correct results. * while allowing the sizeof() operator to return correct results.
* *
* \param[in] DataSize Size of the functional descriptor's data payload, in bytes * \param[in] DataSize Size of the functional descriptor's data payload, in bytes
*/ */
#define CDC_FUNCTIONAL_DESCRIPTOR(DataSize) \ #define CDC_FUNCTIONAL_DESCRIPTOR(DataSize) \
struct \ struct \
{ \ { \
USB_Descriptor_Header_t Header; \ USB_Descriptor_Header_t Header; \
uint8_t SubType; \ uint8_t SubType; \
uint8_t Data[DataSize]; \ uint8_t Data[DataSize]; \
} }
/** Endpoint number for the CDC control interface event notification endpoint. */ /** Endpoint number for the CDC control interface event notification endpoint. */
#define CDC_NOTIFICATION_EPNUM 3 #define CDC_NOTIFICATION_EPNUM 3
/** Size of the CDC control interface notification endpoint bank, in bytes */ /** Size of the CDC control interface notification endpoint bank, in bytes */
#define CDC_NOTIFICATION_EPSIZE 8 #define CDC_NOTIFICATION_EPSIZE 8
/** Endpoint number for the CDC data interface TX (data IN) endpoint */ /** Endpoint number for the CDC data interface TX (data IN) endpoint */
#define CDC_TX_EPNUM 1 #define CDC_TX_EPNUM 1
/** Endpoint number for the CDC data interface RX (data OUT) endpoint */ /** Endpoint number for the CDC data interface RX (data OUT) endpoint */
#define CDC_RX_EPNUM 2 #define CDC_RX_EPNUM 2
/** Size of the CDC data interface TX and RX data endpoint banks, in bytes */ /** Size of the CDC data interface TX and RX data endpoint banks, in bytes */
#define CDC_TXRX_EPSIZE 16 #define CDC_TXRX_EPSIZE 16
/* Type Defines: */ /* Type Defines: */
/** Type define for the device configuration descriptor structure. This must be defined in the /** Type define for the device configuration descriptor structure. This must be defined in the
* application code, as the configuration descriptor contains several sub-descriptors which * application code, as the configuration descriptor contains several sub-descriptors which
* vary between devices, and which describe the device's usage to the host. * vary between devices, and which describe the device's usage to the host.
*/ */
typedef struct typedef struct
{ {
USB_Descriptor_Configuration_Header_t Config; USB_Descriptor_Configuration_Header_t Config;
USB_Descriptor_Interface_t CDC_CCI_Interface; USB_Descriptor_Interface_t CDC_CCI_Interface;
CDC_FUNCTIONAL_DESCRIPTOR(2) CDC_Functional_IntHeader; CDC_FUNCTIONAL_DESCRIPTOR(2) CDC_Functional_IntHeader;
CDC_FUNCTIONAL_DESCRIPTOR(1) CDC_Functional_AbstractControlManagement; CDC_FUNCTIONAL_DESCRIPTOR(1) CDC_Functional_AbstractControlManagement;
CDC_FUNCTIONAL_DESCRIPTOR(2) CDC_Functional_Union; CDC_FUNCTIONAL_DESCRIPTOR(2) CDC_Functional_Union;
USB_Descriptor_Endpoint_t CDC_ManagementEndpoint; USB_Descriptor_Endpoint_t CDC_ManagementEndpoint;
USB_Descriptor_Interface_t CDC_DCI_Interface; USB_Descriptor_Interface_t CDC_DCI_Interface;
USB_Descriptor_Endpoint_t CDC_DataOutEndpoint; USB_Descriptor_Endpoint_t CDC_DataOutEndpoint;
USB_Descriptor_Endpoint_t CDC_DataInEndpoint; USB_Descriptor_Endpoint_t CDC_DataInEndpoint;
} USB_Descriptor_Configuration_t; } USB_Descriptor_Configuration_t;
/* Function Prototypes: */ /* Function Prototypes: */
uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, void** const DescriptorAddress) uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, void** const DescriptorAddress)
ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3); ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3);
#endif #endif

File diff suppressed because it is too large Load diff

View file

@ -1,106 +1,106 @@
;************************************************************ ;************************************************************
; Windows USB CDC ACM Setup File ; Windows USB CDC ACM Setup File
; Copyright (c) 2000 Microsoft Corporation ; Copyright (c) 2000 Microsoft Corporation
[Version] [Version]
Signature="$Windows NT$" Signature="$Windows NT$"
Class=Ports Class=Ports
ClassGuid={4D36E978-E325-11CE-BFC1-08002BE10318} ClassGuid={4D36E978-E325-11CE-BFC1-08002BE10318}
Provider=%MFGNAME% Provider=%MFGNAME%
LayoutFile=layout.inf LayoutFile=layout.inf
CatalogFile=%MFGFILENAME%.cat CatalogFile=%MFGFILENAME%.cat
DriverVer=11/15/2007,5.1.2600.0 DriverVer=11/15/2007,5.1.2600.0
[Manufacturer] [Manufacturer]
%MFGNAME%=DeviceList, NTamd64 %MFGNAME%=DeviceList, NTamd64
[DestinationDirs] [DestinationDirs]
DefaultDestDir=12 DefaultDestDir=12
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
; Windows 2000/XP/Vista-32bit Sections ; Windows 2000/XP/Vista-32bit Sections
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
[DriverInstall.nt] [DriverInstall.nt]
include=mdmcpq.inf include=mdmcpq.inf
CopyFiles=DriverCopyFiles.nt CopyFiles=DriverCopyFiles.nt
AddReg=DriverInstall.nt.AddReg AddReg=DriverInstall.nt.AddReg
[DriverCopyFiles.nt] [DriverCopyFiles.nt]
usbser.sys,,,0x20 usbser.sys,,,0x20
[DriverInstall.nt.AddReg] [DriverInstall.nt.AddReg]
HKR,,DevLoader,,*ntkern HKR,,DevLoader,,*ntkern
HKR,,NTMPDriver,,%DRIVERFILENAME%.sys HKR,,NTMPDriver,,%DRIVERFILENAME%.sys
HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider" HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider"
[DriverInstall.nt.Services] [DriverInstall.nt.Services]
AddService=usbser, 0x00000002, DriverService.nt AddService=usbser, 0x00000002, DriverService.nt
[DriverService.nt] [DriverService.nt]
DisplayName=%SERVICE% DisplayName=%SERVICE%
ServiceType=1 ServiceType=1
StartType=3 StartType=3
ErrorControl=1 ErrorControl=1
ServiceBinary=%12%\%DRIVERFILENAME%.sys ServiceBinary=%12%\%DRIVERFILENAME%.sys
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
; Vista-64bit Sections ; Vista-64bit Sections
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
[DriverInstall.NTamd64] [DriverInstall.NTamd64]
include=mdmcpq.inf include=mdmcpq.inf
CopyFiles=DriverCopyFiles.NTamd64 CopyFiles=DriverCopyFiles.NTamd64
AddReg=DriverInstall.NTamd64.AddReg AddReg=DriverInstall.NTamd64.AddReg
[DriverCopyFiles.NTamd64] [DriverCopyFiles.NTamd64]
%DRIVERFILENAME%.sys,,,0x20 %DRIVERFILENAME%.sys,,,0x20
[DriverInstall.NTamd64.AddReg] [DriverInstall.NTamd64.AddReg]
HKR,,DevLoader,,*ntkern HKR,,DevLoader,,*ntkern
HKR,,NTMPDriver,,%DRIVERFILENAME%.sys HKR,,NTMPDriver,,%DRIVERFILENAME%.sys
HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider" HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider"
[DriverInstall.NTamd64.Services] [DriverInstall.NTamd64.Services]
AddService=usbser, 0x00000002, DriverService.NTamd64 AddService=usbser, 0x00000002, DriverService.NTamd64
[DriverService.NTamd64] [DriverService.NTamd64]
DisplayName=%SERVICE% DisplayName=%SERVICE%
ServiceType=1 ServiceType=1
StartType=3 StartType=3
ErrorControl=1 ErrorControl=1
ServiceBinary=%12%\%DRIVERFILENAME%.sys ServiceBinary=%12%\%DRIVERFILENAME%.sys
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
; Vendor and Product ID Definitions ; Vendor and Product ID Definitions
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
; When developing your USB device, the VID and PID used in the PC side ; When developing your USB device, the VID and PID used in the PC side
; application program and the firmware on the microcontroller must match. ; application program and the firmware on the microcontroller must match.
; Modify the below line to use your VID and PID. Use the format as shown below. ; Modify the below line to use your VID and PID. Use the format as shown below.
; Note: One INF file can be used for multiple devices with different VID and PIDs. ; Note: One INF file can be used for multiple devices with different VID and PIDs.
; For each supported device, append ",USB\VID_xxxx&PID_yyyy" to the end of the line. ; For each supported device, append ",USB\VID_xxxx&PID_yyyy" to the end of the line.
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
[SourceDisksFiles] [SourceDisksFiles]
[SourceDisksNames] [SourceDisksNames]
[DeviceList] [DeviceList]
%DESCRIPTION%=DriverInstall, USB\VID_03EB&PID_204A %DESCRIPTION%=DriverInstall, USB\VID_03EB&PID_204A
[DeviceList.NTamd64] [DeviceList.NTamd64]
%DESCRIPTION%=DriverInstall, USB\VID_03EB&PID_204A %DESCRIPTION%=DriverInstall, USB\VID_03EB&PID_204A
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
; String Definitions ; String Definitions
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
;Modify these strings to customize your device ;Modify these strings to customize your device
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
[Strings] [Strings]
MFGFILENAME="CDC_vista" MFGFILENAME="CDC_vista"
DRIVERFILENAME ="usbser" DRIVERFILENAME ="usbser"
MFGNAME="http://www.fourwalledcubicle.com" MFGNAME="http://www.fourwalledcubicle.com"
INSTDISK="LUFA CDC Bootloader Driver Installer" INSTDISK="LUFA CDC Bootloader Driver Installer"
DESCRIPTION="Communications Port" DESCRIPTION="Communications Port"
SERVICE="USB RS-232 Emulation Driver" SERVICE="USB RS-232 Emulation Driver"

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,207 +1,207 @@
/* /*
LUFA Library LUFA Library
Copyright (C) Dean Camera, 2010. Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com www.fourwalledcubicle.com
*/ */
/* /*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com) Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the advertising or publicity pertaining to distribution of the
software without specific, written prior permission. software without specific, written prior permission.
The author disclaim all warranties with regard to this The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action, in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of arising out of or in connection with the use or performance of
this software. this software.
*/ */
/** \file /** \file
* *
* Header file for BootloaderDFU.c. * Header file for BootloaderDFU.c.
*/ */
#ifndef _BOOTLOADER_H_ #ifndef _BOOTLOADER_H_
#define _BOOTLOADER_H_ #define _BOOTLOADER_H_
/* Includes: */ /* Includes: */
#include <avr/io.h> #include <avr/io.h>
#include <avr/wdt.h> #include <avr/wdt.h>
#include <avr/boot.h> #include <avr/boot.h>
#include <avr/pgmspace.h> #include <avr/pgmspace.h>
#include <avr/eeprom.h> #include <avr/eeprom.h>
#include <avr/power.h> #include <avr/power.h>
#include <avr/interrupt.h> #include <avr/interrupt.h>
#include <stdbool.h> #include <stdbool.h>
#include "Descriptors.h" #include "Descriptors.h"
#include <LUFA/Drivers/USB/USB.h> #include <LUFA/Drivers/USB/USB.h>
/* Macros: */ /* Macros: */
/** Configuration define. Define this token to true to case the bootloader to reject all memory commands /** Configuration define. Define this token to true to case the bootloader to reject all memory commands
* until a memory erase has been performed. When used in conjunction with the lockbits of the AVR, this * until a memory erase has been performed. When used in conjunction with the lockbits of the AVR, this
* can protect the AVR's firmware from being dumped from a secured AVR. When false, memory operations are * can protect the AVR's firmware from being dumped from a secured AVR. When false, memory operations are
* allowed at any time. * allowed at any time.
*/ */
#define SECURE_MODE false #define SECURE_MODE false
/** Major bootloader version number. */ /** Major bootloader version number. */
#define BOOTLOADER_VERSION_MINOR 2 #define BOOTLOADER_VERSION_MINOR 2
/** Minor bootloader version number. */ /** Minor bootloader version number. */
#define BOOTLOADER_VERSION_REV 0 #define BOOTLOADER_VERSION_REV 0
/** Complete bootloader version number expressed as a packed byte, constructed from the /** Complete bootloader version number expressed as a packed byte, constructed from the
* two individual bootloader version macros. * two individual bootloader version macros.
*/ */
#define BOOTLOADER_VERSION ((BOOTLOADER_VERSION_MINOR << 4) | BOOTLOADER_VERSION_REV) #define BOOTLOADER_VERSION ((BOOTLOADER_VERSION_MINOR << 4) | BOOTLOADER_VERSION_REV)
/** First byte of the bootloader identification bytes, used to identify a device's bootloader. */ /** First byte of the bootloader identification bytes, used to identify a device's bootloader. */
#define BOOTLOADER_ID_BYTE1 0xDC #define BOOTLOADER_ID_BYTE1 0xDC
/** Second byte of the bootloader identification bytes, used to identify a device's bootloader. */ /** Second byte of the bootloader identification bytes, used to identify a device's bootloader. */
#define BOOTLOADER_ID_BYTE2 0xFB #define BOOTLOADER_ID_BYTE2 0xFB
/** Convenience macro, used to determine if the issued command is the given one-byte long command. /** Convenience macro, used to determine if the issued command is the given one-byte long command.
* *
* \param[in] dataarr Command byte array to check against * \param[in] dataarr Command byte array to check against
* \param[in] cb1 First command byte to check * \param[in] cb1 First command byte to check
*/ */
#define IS_ONEBYTE_COMMAND(dataarr, cb1) (dataarr[0] == (cb1)) #define IS_ONEBYTE_COMMAND(dataarr, cb1) (dataarr[0] == (cb1))
/** Convenience macro, used to determine if the issued command is the given two-byte long command. /** Convenience macro, used to determine if the issued command is the given two-byte long command.
* *
* \param[in] dataarr Command byte array to check against * \param[in] dataarr Command byte array to check against
* \param[in] cb1 First command byte to check * \param[in] cb1 First command byte to check
* \param[in] cb2 Second command byte to check * \param[in] cb2 Second command byte to check
*/ */
#define IS_TWOBYTE_COMMAND(dataarr, cb1, cb2) ((dataarr[0] == (cb1)) && (dataarr[1] == (cb2))) #define IS_TWOBYTE_COMMAND(dataarr, cb1, cb2) ((dataarr[0] == (cb1)) && (dataarr[1] == (cb2)))
/** Length of the DFU file suffix block, appended to the end of each complete memory write command. /** Length of the DFU file suffix block, appended to the end of each complete memory write command.
* The DFU file suffix is currently unused (but is designed to give extra file information, such as * The DFU file suffix is currently unused (but is designed to give extra file information, such as
* a CRC of the complete firmware for error checking) and so is discarded. * a CRC of the complete firmware for error checking) and so is discarded.
*/ */
#define DFU_FILE_SUFFIX_SIZE 16 #define DFU_FILE_SUFFIX_SIZE 16
/** Length of the DFU file filler block, appended to the start of each complete memory write command. /** Length of the DFU file filler block, appended to the start of each complete memory write command.
* Filler bytes are added to the start of each complete memory write command, and must be discarded. * Filler bytes are added to the start of each complete memory write command, and must be discarded.
*/ */
#define DFU_FILLER_BYTES_SIZE 26 #define DFU_FILLER_BYTES_SIZE 26
/** DFU class command request to detach from the host. */ /** DFU class command request to detach from the host. */
#define DFU_DETATCH 0x00 #define DFU_DETATCH 0x00
/** DFU class command request to send data from the host to the bootloader. */ /** DFU class command request to send data from the host to the bootloader. */
#define DFU_DNLOAD 0x01 #define DFU_DNLOAD 0x01
/** DFU class command request to send data from the bootloader to the host. */ /** DFU class command request to send data from the bootloader to the host. */
#define DFU_UPLOAD 0x02 #define DFU_UPLOAD 0x02
/** DFU class command request to get the current DFU status and state from the bootloader. */ /** DFU class command request to get the current DFU status and state from the bootloader. */
#define DFU_GETSTATUS 0x03 #define DFU_GETSTATUS 0x03
/** DFU class command request to reset the current DFU status and state variables to their defaults. */ /** DFU class command request to reset the current DFU status and state variables to their defaults. */
#define DFU_CLRSTATUS 0x04 #define DFU_CLRSTATUS 0x04
/** DFU class command request to get the current DFU state of the bootloader. */ /** DFU class command request to get the current DFU state of the bootloader. */
#define DFU_GETSTATE 0x05 #define DFU_GETSTATE 0x05
/** DFU class command request to abort the current multi-request transfer and return to the dfuIDLE state. */ /** DFU class command request to abort the current multi-request transfer and return to the dfuIDLE state. */
#define DFU_ABORT 0x06 #define DFU_ABORT 0x06
/** DFU command to begin programming the device's memory. */ /** DFU command to begin programming the device's memory. */
#define COMMAND_PROG_START 0x01 #define COMMAND_PROG_START 0x01
/** DFU command to begin reading the device's memory. */ /** DFU command to begin reading the device's memory. */
#define COMMAND_DISP_DATA 0x03 #define COMMAND_DISP_DATA 0x03
/** DFU command to issue a write command. */ /** DFU command to issue a write command. */
#define COMMAND_WRITE 0x04 #define COMMAND_WRITE 0x04
/** DFU command to issue a read command. */ /** DFU command to issue a read command. */
#define COMMAND_READ 0x05 #define COMMAND_READ 0x05
/** DFU command to issue a memory base address change command, to set the current 64KB flash page /** DFU command to issue a memory base address change command, to set the current 64KB flash page
* that subsequent flash operations should use. */ * that subsequent flash operations should use. */
#define COMMAND_CHANGE_BASE_ADDR 0x06 #define COMMAND_CHANGE_BASE_ADDR 0x06
/* Type Defines: */ /* Type Defines: */
/** Type define for a non-returning function pointer to the loaded application. */ /** Type define for a non-returning function pointer to the loaded application. */
typedef void (*AppPtr_t)(void) ATTR_NO_RETURN; typedef void (*AppPtr_t)(void) ATTR_NO_RETURN;
/** Type define for a structure containing a complete DFU command issued by the host. */ /** Type define for a structure containing a complete DFU command issued by the host. */
typedef struct typedef struct
{ {
uint8_t Command; /**< Single byte command to perform, one of the COMMAND_* macro values */ uint8_t Command; /**< Single byte command to perform, one of the COMMAND_* macro values */
uint8_t Data[5]; /**< Command parameters */ uint8_t Data[5]; /**< Command parameters */
uint16_t DataSize; /**< Size of the command parameters */ uint16_t DataSize; /**< Size of the command parameters */
} DFU_Command_t; } DFU_Command_t;
/* Enums: */ /* Enums: */
/** DFU bootloader states. Refer to the DFU class specification for information on each state. */ /** DFU bootloader states. Refer to the DFU class specification for information on each state. */
enum DFU_State_t enum DFU_State_t
{ {
appIDLE = 0, appIDLE = 0,
appDETACH = 1, appDETACH = 1,
dfuIDLE = 2, dfuIDLE = 2,
dfuDNLOAD_SYNC = 3, dfuDNLOAD_SYNC = 3,
dfuDNBUSY = 4, dfuDNBUSY = 4,
dfuDNLOAD_IDLE = 5, dfuDNLOAD_IDLE = 5,
dfuMANIFEST_SYNC = 6, dfuMANIFEST_SYNC = 6,
dfuMANIFEST = 7, dfuMANIFEST = 7,
dfuMANIFEST_WAIT_RESET = 8, dfuMANIFEST_WAIT_RESET = 8,
dfuUPLOAD_IDLE = 9, dfuUPLOAD_IDLE = 9,
dfuERROR = 10 dfuERROR = 10
}; };
/** DFU command status error codes. Refer to the DFU class specification for information on each error code. */ /** DFU command status error codes. Refer to the DFU class specification for information on each error code. */
enum DFU_Status_t enum DFU_Status_t
{ {
OK = 0, OK = 0,
errTARGET = 1, errTARGET = 1,
errFILE = 2, errFILE = 2,
errWRITE = 3, errWRITE = 3,
errERASE = 4, errERASE = 4,
errCHECK_ERASED = 5, errCHECK_ERASED = 5,
errPROG = 6, errPROG = 6,
errVERIFY = 7, errVERIFY = 7,
errADDRESS = 8, errADDRESS = 8,
errNOTDONE = 9, errNOTDONE = 9,
errFIRMWARE = 10, errFIRMWARE = 10,
errVENDOR = 11, errVENDOR = 11,
errUSBR = 12, errUSBR = 12,
errPOR = 13, errPOR = 13,
errUNKNOWN = 14, errUNKNOWN = 14,
errSTALLEDPKT = 15 errSTALLEDPKT = 15
}; };
/* Function Prototypes: */ /* Function Prototypes: */
void SetupHardware(void); void SetupHardware(void);
void ResetHardware(void); void ResetHardware(void);
void EVENT_USB_Device_UnhandledControlRequest(void); void EVENT_USB_Device_UnhandledControlRequest(void);
#if defined(INCLUDE_FROM_BOOTLOADER_C) #if defined(INCLUDE_FROM_BOOTLOADER_C)
static void DiscardFillerBytes(uint8_t NumberOfBytes); static void DiscardFillerBytes(uint8_t NumberOfBytes);
static void ProcessBootloaderCommand(void); static void ProcessBootloaderCommand(void);
static void LoadStartEndAddresses(void); static void LoadStartEndAddresses(void);
static void ProcessMemProgCommand(void); static void ProcessMemProgCommand(void);
static void ProcessMemReadCommand(void); static void ProcessMemReadCommand(void);
static void ProcessWriteCommand(void); static void ProcessWriteCommand(void);
static void ProcessReadCommand(void); static void ProcessReadCommand(void);
#endif #endif
#endif #endif

View file

@ -1,90 +1,90 @@
/** \file /** \file
* *
* This file contains special DoxyGen information for the generation of the main page and other special * 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. * documentation pages. It is not a project source file.
*/ */
/** \mainpage DFU Class USB AVR Bootloader /** \mainpage DFU Class USB AVR Bootloader
* *
* \section SSec_Compat Demo Compatibility: * \section SSec_Compat Demo Compatibility:
* *
* The following list indicates what microcontrollers are compatible with this demo. * The following list indicates what microcontrollers are compatible with this demo.
* *
* - Series 7 USB AVRs * - Series 7 USB AVRs
* - Series 6 USB AVRs * - Series 6 USB AVRs
* - Series 4 USB AVRs * - Series 4 USB AVRs
* - Series 2 USB AVRs (Excluding the 8KB FLASH variants) * - Series 2 USB AVRs (Excluding the 8KB FLASH variants)
* *
* \section SSec_Info USB Information: * \section SSec_Info USB Information:
* *
* The following table gives a rundown of the USB utilization of this demo. * The following table gives a rundown of the USB utilization of this demo.
* *
* <table> * <table>
* <tr> * <tr>
* <td><b>USB Mode:</b></td> * <td><b>USB Mode:</b></td>
* <td>Device</td> * <td>Device</td>
* </tr> * </tr>
* <tr> * <tr>
* <td><b>USB Class:</b></td> * <td><b>USB Class:</b></td>
* <td>Device Firmware Update Class (DFU)</td> * <td>Device Firmware Update Class (DFU)</td>
* </tr> * </tr>
* <tr> * <tr>
* <td><b>USB Subclass:</b></td> * <td><b>USB Subclass:</b></td>
* <td>None</td> * <td>None</td>
* </tr> * </tr>
* <tr> * <tr>
* <td><b>Relevant Standards:</b></td> * <td><b>Relevant Standards:</b></td>
* <td>USBIF DFU Class Standard, Atmel USB Bootloader Datasheet</td> * <td>USBIF DFU Class Standard, Atmel USB Bootloader Datasheet</td>
* </tr> * </tr>
* <tr> * <tr>
* <td><b>Usable Speeds:</b></td> * <td><b>Usable Speeds:</b></td>
* <td>Full Speed Mode</td> * <td>Full Speed Mode</td>
* </tr> * </tr>
* </table> * </table>
* *
* \section SSec_Description Project Description: * \section SSec_Description Project Description:
* *
* This bootloader enumerates to the host as a DFU Class device, allowing for DFU-compatible programming * This bootloader enumerates to the host as a DFU Class device, allowing for DFU-compatible programming
* software to load firmware onto the AVR. * software to load firmware onto the AVR.
* *
* This bootloader is compatible with Atmel's FLIP application. However, it requires the use of Atmel's * This bootloader is compatible with Atmel's FLIP application. However, it requires the use of Atmel's
* DFU drivers. You will need to install Atmel's DFU drivers prior to using this bootloader. If you are * DFU drivers. You will need to install Atmel's DFU drivers prior to using this bootloader. If you are
* using a 64 bit Windows OS, you will need to either disable the driver signing requirement (see online * using a 64 bit Windows OS, you will need to either disable the driver signing requirement (see online
* tutorials for details) or use a digitally signed version of the official Atmel driver provided by a * tutorials for details) or use a digitally signed version of the official Atmel driver provided by a
* third party AVR user at * third party AVR user at
* <a>http://www.avrfreaks.net/index.php?module=Freaks%20Academy&func=viewItem&item_id=2196&item_type=project</a>. * <a>http://www.avrfreaks.net/index.php?module=Freaks%20Academy&func=viewItem&item_id=2196&item_type=project</a>.
* *
* As an open-source option, this bootloader is also compatible with the Linux Atmel USB DFU Programmer * As an open-source option, this bootloader is also compatible with the Linux Atmel USB DFU Programmer
* software, available for download at <a>http://sourceforge.net/projects/dfu-programmer/</a>. * software, available for download at <a>http://sourceforge.net/projects/dfu-programmer/</a>.
* *
* If SECURE_MODE is defined as true, upon start-up the bootloader will be locked, with only the chip erase * If SECURE_MODE is defined as true, upon start-up the bootloader will be locked, with only the chip erase
* function available (similar to Atmel's DFU bootloader). If SECURE_MODE is defined as false, all functions * function available (similar to Atmel's DFU bootloader). If SECURE_MODE is defined as false, all functions
* are usable on start-up without the prerequisite firmware erase. * are usable on start-up without the prerequisite firmware erase.
* *
* Out of the box this bootloader builds for the USB1287, and should fit into 4KB of bootloader space. If * Out of the box this bootloader builds for the USB1287, and should fit into 4KB of bootloader space. If
* you wish to enlarge this space and/or change the AVR model, you will need to edit the BOOT_START and MCU * you wish to enlarge this space and/or change the AVR model, you will need to edit the BOOT_START and MCU
* values in the accompanying makefile. * values in the accompanying makefile.
* *
* <b>NOTE:</b> This device spoofs Atmel's DFU Bootloader USB VID and PID so that the Atmel DFU bootloader * <b>NOTE:</b> This device spoofs Atmel's DFU Bootloader USB VID and PID so that the Atmel DFU bootloader
* drivers included with FLIP will work. If you do not wish to use Atmel's ID codes, please * drivers included with FLIP will work. If you do not wish to use Atmel's ID codes, please
* manually change them in Descriptors.c and alter your driver's INF file accordingly. * manually change them in Descriptors.c and alter your driver's INF file accordingly.
* *
* \section SSec_Options Project Options * \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. * The following defines can be found in this demo, which can control the demo behaviour when defined, or changed in value.
* *
* <table> * <table>
* <tr> * <tr>
* <td><b>Define Name:</b></td> * <td><b>Define Name:</b></td>
* <td><b>Location:</b></td> * <td><b>Location:</b></td>
* <td><b>Description:</b></td> * <td><b>Description:</b></td>
* </tr> * </tr>
* <tr> * <tr>
* <td>SECURE_MODE</td> * <td>SECURE_MODE</td>
* <td>BootloaderDFU.h</td> * <td>BootloaderDFU.h</td>
* <td>If defined to true, the bootloader will not accept any memory commands other than a chip erase on start-up, until an * <td>If defined to true, the bootloader will not accept any memory commands other than a chip erase on start-up, until an
* erase has been performed. This can be used in conjunction with the AVR's lockbits to prevent the AVRs firmware from * erase has been performed. This can be used in conjunction with the AVR's lockbits to prevent the AVRs firmware from
* being dumped by unauthorized persons.</td> * being dumped by unauthorized persons.</td>
* </tr> * </tr>
* </table> * </table>
*/ */

View file

@ -1,181 +1,181 @@
/* /*
LUFA Library LUFA Library
Copyright (C) Dean Camera, 2010. Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com www.fourwalledcubicle.com
*/ */
/* /*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com) Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the advertising or publicity pertaining to distribution of the
software without specific, written prior permission. software without specific, written prior permission.
The author disclaim all warranties with regard to this The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action, in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of arising out of or in connection with the use or performance of
this software. this software.
*/ */
/** \file /** \file
* *
* USB Device Descriptors, for library use when in USB device mode. Descriptors are special * USB Device Descriptors, for library use when in USB device mode. Descriptors are special
* computer-readable structures which the host requests upon device enumeration, to determine * computer-readable structures which the host requests upon device enumeration, to determine
* the device's capabilities and functions. * the device's capabilities and functions.
*/ */
#include "Descriptors.h" #include "Descriptors.h"
/** Device descriptor structure. This descriptor, located in FLASH memory, describes the overall /** Device descriptor structure. This descriptor, located in FLASH memory, describes the overall
* device characteristics, including the supported USB version, control endpoint size and the * device characteristics, including the supported USB version, control endpoint size and the
* number of device configurations. The descriptor is read out by the USB host when the enumeration * number of device configurations. The descriptor is read out by the USB host when the enumeration
* process begins. * process begins.
*/ */
USB_Descriptor_Device_t DeviceDescriptor = USB_Descriptor_Device_t DeviceDescriptor =
{ {
.Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device}, .Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device},
.USBSpecification = VERSION_BCD(01.10), .USBSpecification = VERSION_BCD(01.10),
.Class = 0x00, .Class = 0x00,
.SubClass = 0x00, .SubClass = 0x00,
.Protocol = 0x00, .Protocol = 0x00,
.Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE, .Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE,
.VendorID = 0x03EB, .VendorID = 0x03EB,
.ProductID = PRODUCT_ID_CODE, .ProductID = PRODUCT_ID_CODE,
.ReleaseNumber = 0x0000, .ReleaseNumber = 0x0000,
.ManufacturerStrIndex = NO_DESCRIPTOR, .ManufacturerStrIndex = NO_DESCRIPTOR,
.ProductStrIndex = 0x01, .ProductStrIndex = 0x01,
.SerialNumStrIndex = NO_DESCRIPTOR, .SerialNumStrIndex = NO_DESCRIPTOR,
.NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS .NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS
}; };
/** Configuration descriptor structure. This descriptor, located in FLASH memory, describes the usage /** Configuration descriptor structure. This descriptor, located in FLASH memory, describes the usage
* of the device in one of its supported configurations, including information about any device interfaces * of the device in one of its supported configurations, including information about any device interfaces
* and endpoints. The descriptor is read out by the USB host during the enumeration process when selecting * and endpoints. The descriptor is read out by the USB host during the enumeration process when selecting
* a configuration so that the host may correctly communicate with the USB device. * a configuration so that the host may correctly communicate with the USB device.
*/ */
USB_Descriptor_Configuration_t ConfigurationDescriptor = USB_Descriptor_Configuration_t ConfigurationDescriptor =
{ {
.Config = .Config =
{ {
.Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration}, .Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration},
.TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t), .TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t),
.TotalInterfaces = 1, .TotalInterfaces = 1,
.ConfigurationNumber = 1, .ConfigurationNumber = 1,
.ConfigurationStrIndex = NO_DESCRIPTOR, .ConfigurationStrIndex = NO_DESCRIPTOR,
.ConfigAttributes = USB_CONFIG_ATTR_BUSPOWERED, .ConfigAttributes = USB_CONFIG_ATTR_BUSPOWERED,
.MaxPowerConsumption = USB_CONFIG_POWER_MA(100) .MaxPowerConsumption = USB_CONFIG_POWER_MA(100)
}, },
.DFU_Interface = .DFU_Interface =
{ {
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface}, .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
.InterfaceNumber = 0, .InterfaceNumber = 0,
.AlternateSetting = 0, .AlternateSetting = 0,
.TotalEndpoints = 0, .TotalEndpoints = 0,
.Class = 0xFE, .Class = 0xFE,
.SubClass = 0x01, .SubClass = 0x01,
.Protocol = 0x02, .Protocol = 0x02,
.InterfaceStrIndex = NO_DESCRIPTOR .InterfaceStrIndex = NO_DESCRIPTOR
}, },
.DFU_Functional = .DFU_Functional =
{ {
.Header = {.Size = sizeof(USB_DFU_Functional_Descriptor_t), .Type = DTYPE_DFUFunctional}, .Header = {.Size = sizeof(USB_DFU_Functional_Descriptor_t), .Type = DTYPE_DFUFunctional},
.Attributes = (ATTR_CAN_UPLOAD | ATTR_CAN_DOWNLOAD), .Attributes = (ATTR_CAN_UPLOAD | ATTR_CAN_DOWNLOAD),
.DetachTimeout = 0x0000, .DetachTimeout = 0x0000,
.TransferSize = 0x0c00, .TransferSize = 0x0c00,
.DFUSpecification = VERSION_BCD(01.01) .DFUSpecification = VERSION_BCD(01.01)
} }
}; };
/** Language descriptor structure. This descriptor, located in FLASH memory, is returned when the host requests /** Language descriptor structure. This descriptor, located in FLASH memory, is returned when the host requests
* the string descriptor with index 0 (the first index). It is actually an array of 16-bit integers, which indicate * the string descriptor with index 0 (the first index). It is actually an array of 16-bit integers, which indicate
* via the language ID table available at USB.org what languages the device supports for its string descriptors. * via the language ID table available at USB.org what languages the device supports for its string descriptors.
*/ */
USB_Descriptor_String_t LanguageString = USB_Descriptor_String_t LanguageString =
{ {
.Header = {.Size = USB_STRING_LEN(1), .Type = DTYPE_String}, .Header = {.Size = USB_STRING_LEN(1), .Type = DTYPE_String},
.UnicodeString = {LANGUAGE_ID_ENG} .UnicodeString = {LANGUAGE_ID_ENG}
}; };
/** Product descriptor string. This is a Unicode string containing the product's details in human readable form, /** Product descriptor string. This is a Unicode string containing the product's details in human readable form,
* and is read out upon request by the host when the appropriate string ID is requested, listed in the Device * and is read out upon request by the host when the appropriate string ID is requested, listed in the Device
* Descriptor. * Descriptor.
*/ */
USB_Descriptor_String_t ProductString = USB_Descriptor_String_t ProductString =
{ {
.Header = {.Size = USB_STRING_LEN(18), .Type = DTYPE_String}, .Header = {.Size = USB_STRING_LEN(18), .Type = DTYPE_String},
.UnicodeString = L"AVR DFU Bootloader" .UnicodeString = L"AVR DFU Bootloader"
}; };
/** This function is called by the library when in device mode, and must be overridden (see library "USB Descriptors" /** This function is called by the library when in device mode, and must be overridden (see library "USB Descriptors"
* documentation) by the application code so that the address and size of a requested descriptor can be given * documentation) by the application code so that the address and size of a requested descriptor can be given
* to the USB library. When the device receives a Get Descriptor request on the control endpoint, this function * to the USB library. When the device receives a Get Descriptor request on the control endpoint, this function
* is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the * is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the
* USB host. * USB host.
*/ */
uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, void** const DescriptorAddress) uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, void** const DescriptorAddress)
{ {
const uint8_t DescriptorType = (wValue >> 8); const uint8_t DescriptorType = (wValue >> 8);
const uint8_t DescriptorNumber = (wValue & 0xFF); const uint8_t DescriptorNumber = (wValue & 0xFF);
void* Address = NULL; void* Address = NULL;
uint16_t Size = NO_DESCRIPTOR; uint16_t Size = NO_DESCRIPTOR;
switch (DescriptorType) switch (DescriptorType)
{ {
case DTYPE_Device: case DTYPE_Device:
Address = &DeviceDescriptor; Address = &DeviceDescriptor;
Size = sizeof(USB_Descriptor_Device_t); Size = sizeof(USB_Descriptor_Device_t);
break; break;
case DTYPE_Configuration: case DTYPE_Configuration:
Address = &ConfigurationDescriptor; Address = &ConfigurationDescriptor;
Size = sizeof(USB_Descriptor_Configuration_t); Size = sizeof(USB_Descriptor_Configuration_t);
break; break;
case DTYPE_String: case DTYPE_String:
if (!(DescriptorNumber)) if (!(DescriptorNumber))
{ {
Address = &LanguageString; Address = &LanguageString;
Size = LanguageString.Header.Size; Size = LanguageString.Header.Size;
} }
else else
{ {
Address = &ProductString; Address = &ProductString;
Size = ProductString.Header.Size; Size = ProductString.Header.Size;
} }
break; break;
} }
*DescriptorAddress = Address; *DescriptorAddress = Address;
return Size; return Size;
} }

View file

@ -1,172 +1,172 @@
/* /*
LUFA Library LUFA Library
Copyright (C) Dean Camera, 2010. Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com www.fourwalledcubicle.com
*/ */
/* /*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com) Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the advertising or publicity pertaining to distribution of the
software without specific, written prior permission. software without specific, written prior permission.
The author disclaim all warranties with regard to this The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action, in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of arising out of or in connection with the use or performance of
this software. this software.
*/ */
/** \file /** \file
* *
* Header file for Descriptors.c. * Header file for Descriptors.c.
*/ */
#ifndef _DESCRIPTORS_H_ #ifndef _DESCRIPTORS_H_
#define _DESCRIPTORS_H_ #define _DESCRIPTORS_H_
/* Includes: */ /* Includes: */
#include <LUFA/Drivers/USB/USB.h> #include <LUFA/Drivers/USB/USB.h>
/* Macros: */ /* Macros: */
/** Descriptor type value for a DFU class functional descriptor. */ /** Descriptor type value for a DFU class functional descriptor. */
#define DTYPE_DFUFunctional 0x21 #define DTYPE_DFUFunctional 0x21
/** DFU attribute mask, indicating that the DFU device will detach and re-attach when a DFU_DETACH /** DFU attribute mask, indicating that the DFU device will detach and re-attach when a DFU_DETACH
* command is issued, rather than the host issuing a USB Reset. * command is issued, rather than the host issuing a USB Reset.
*/ */
#define ATTR_WILL_DETATCH (1 << 3) #define ATTR_WILL_DETATCH (1 << 3)
/** DFU attribute mask, indicating that the DFU device can communicate during the manifestation phase /** DFU attribute mask, indicating that the DFU device can communicate during the manifestation phase
* (memory programming phase). * (memory programming phase).
*/ */
#define ATTR_MANEFESTATION_TOLLERANT (1 << 2) #define ATTR_MANEFESTATION_TOLLERANT (1 << 2)
/** DFU attribute mask, indicating that the DFU device can accept DFU_UPLOAD requests to send data from /** DFU attribute mask, indicating that the DFU device can accept DFU_UPLOAD requests to send data from
* the device to the host. * the device to the host.
*/ */
#define ATTR_CAN_UPLOAD (1 << 1) #define ATTR_CAN_UPLOAD (1 << 1)
/** DFU attribute mask, indicating that the DFU device can accept DFU_DNLOAD requests to send data from /** DFU attribute mask, indicating that the DFU device can accept DFU_DNLOAD requests to send data from
* the host to the device. * the host to the device.
*/ */
#define ATTR_CAN_DOWNLOAD (1 << 0) #define ATTR_CAN_DOWNLOAD (1 << 0)
#if defined(__AVR_AT90USB1287__) #if defined(__AVR_AT90USB1287__)
#define PRODUCT_ID_CODE 0x2FFB #define PRODUCT_ID_CODE 0x2FFB
#define AVR_SIGNATURE_1 0x1E #define AVR_SIGNATURE_1 0x1E
#define AVR_SIGNATURE_2 0x97 #define AVR_SIGNATURE_2 0x97
#define AVR_SIGNATURE_3 0x82 #define AVR_SIGNATURE_3 0x82
#elif defined(__AVR_AT90USB647__) #elif defined(__AVR_AT90USB647__)
#define PRODUCT_ID_CODE 0x2FF9 #define PRODUCT_ID_CODE 0x2FF9
#define AVR_SIGNATURE_1 0x1E #define AVR_SIGNATURE_1 0x1E
#define AVR_SIGNATURE_2 0x96 #define AVR_SIGNATURE_2 0x96
#define AVR_SIGNATURE_3 0x82 #define AVR_SIGNATURE_3 0x82
#elif defined(__AVR_AT90USB1286__) #elif defined(__AVR_AT90USB1286__)
#define PRODUCT_ID_CODE 0x2FFB #define PRODUCT_ID_CODE 0x2FFB
#define AVR_SIGNATURE_1 0x1E #define AVR_SIGNATURE_1 0x1E
#define AVR_SIGNATURE_2 0x97 #define AVR_SIGNATURE_2 0x97
#define AVR_SIGNATURE_3 0x82 #define AVR_SIGNATURE_3 0x82
#elif defined(__AVR_AT90USB646__) #elif defined(__AVR_AT90USB646__)
#define PRODUCT_ID_CODE 0x2FF9 #define PRODUCT_ID_CODE 0x2FF9
#define AVR_SIGNATURE_1 0x1E #define AVR_SIGNATURE_1 0x1E
#define AVR_SIGNATURE_2 0x96 #define AVR_SIGNATURE_2 0x96
#define AVR_SIGNATURE_3 0x82 #define AVR_SIGNATURE_3 0x82
#elif defined(__AVR_ATmega32U6__) #elif defined(__AVR_ATmega32U6__)
#define PRODUCT_ID_CODE 0x2FFB #define PRODUCT_ID_CODE 0x2FFB
#define AVR_SIGNATURE_1 0x1E #define AVR_SIGNATURE_1 0x1E
#define AVR_SIGNATURE_2 0x95 #define AVR_SIGNATURE_2 0x95
#define AVR_SIGNATURE_3 0x88 #define AVR_SIGNATURE_3 0x88
#elif defined(__AVR_ATmega32U4__) #elif defined(__AVR_ATmega32U4__)
#define PRODUCT_ID_CODE 0x2FF4 #define PRODUCT_ID_CODE 0x2FF4
#define AVR_SIGNATURE_1 0x1E #define AVR_SIGNATURE_1 0x1E
#define AVR_SIGNATURE_2 0x95 #define AVR_SIGNATURE_2 0x95
#define AVR_SIGNATURE_3 0x87 #define AVR_SIGNATURE_3 0x87
#elif defined(__AVR_ATmega16U4__) #elif defined(__AVR_ATmega16U4__)
#define PRODUCT_ID_CODE 0x2FF3 #define PRODUCT_ID_CODE 0x2FF3
#define AVR_SIGNATURE_1 0x1E #define AVR_SIGNATURE_1 0x1E
#define AVR_SIGNATURE_2 0x94 #define AVR_SIGNATURE_2 0x94
#define AVR_SIGNATURE_3 0x88 #define AVR_SIGNATURE_3 0x88
#elif defined(__AVR_ATmega32U2__) #elif defined(__AVR_ATmega32U2__)
#define PRODUCT_ID_CODE 0x2FF0 #define PRODUCT_ID_CODE 0x2FF0
#define AVR_SIGNATURE_1 0x1E #define AVR_SIGNATURE_1 0x1E
#define AVR_SIGNATURE_2 0x94 #define AVR_SIGNATURE_2 0x94
#define AVR_SIGNATURE_3 0x82 #define AVR_SIGNATURE_3 0x82
#elif defined(__AVR_ATmega16U2__) #elif defined(__AVR_ATmega16U2__)
#define PRODUCT_ID_CODE 0x2FEF #define PRODUCT_ID_CODE 0x2FEF
#define AVR_SIGNATURE_1 0x1E #define AVR_SIGNATURE_1 0x1E
#define AVR_SIGNATURE_2 0x94 #define AVR_SIGNATURE_2 0x94
#define AVR_SIGNATURE_3 0x89 #define AVR_SIGNATURE_3 0x89
#elif defined(__AVR_AT90USB162__) #elif defined(__AVR_AT90USB162__)
#define PRODUCT_ID_CODE 0x2FFA #define PRODUCT_ID_CODE 0x2FFA
#define AVR_SIGNATURE_1 0x1E #define AVR_SIGNATURE_1 0x1E
#define AVR_SIGNATURE_2 0x94 #define AVR_SIGNATURE_2 0x94
#define AVR_SIGNATURE_3 0x82 #define AVR_SIGNATURE_3 0x82
#elif defined(__AVR_ATmega8U2__) #elif defined(__AVR_ATmega8U2__)
#define PRODUCT_ID_CODE 0x2FF7 #define PRODUCT_ID_CODE 0x2FF7
#define AVR_SIGNATURE_1 0x1E #define AVR_SIGNATURE_1 0x1E
#define AVR_SIGNATURE_2 0x93 #define AVR_SIGNATURE_2 0x93
#define AVR_SIGNATURE_3 0x82 #define AVR_SIGNATURE_3 0x82
#elif defined(__AVR_AT90USB82__) #elif defined(__AVR_AT90USB82__)
#define PRODUCT_ID_CODE 0x2FEE #define PRODUCT_ID_CODE 0x2FEE
#define AVR_SIGNATURE_1 0x1E #define AVR_SIGNATURE_1 0x1E
#define AVR_SIGNATURE_2 0x93 #define AVR_SIGNATURE_2 0x93
#define AVR_SIGNATURE_3 0x89 #define AVR_SIGNATURE_3 0x89
#else #else
#error The selected AVR part is not currently supported by this bootloader. #error The selected AVR part is not currently supported by this bootloader.
#endif #endif
#if !defined(PRODUCT_ID_CODE) #if !defined(PRODUCT_ID_CODE)
#error Current AVR model is not supported by this bootloader. #error Current AVR model is not supported by this bootloader.
#endif #endif
/* Type Defines: */ /* Type Defines: */
/** Type define for a DFU class function descriptor. This descriptor gives DFU class information /** Type define for a DFU class function descriptor. This descriptor gives DFU class information
* to the host when read, indicating the DFU device's capabilities. * to the host when read, indicating the DFU device's capabilities.
*/ */
typedef struct typedef struct
{ {
USB_Descriptor_Header_t Header; /**< Standard descriptor header structure */ USB_Descriptor_Header_t Header; /**< Standard descriptor header structure */
uint8_t Attributes; /**< DFU device attributes, a mask comprising of the uint8_t Attributes; /**< DFU device attributes, a mask comprising of the
* ATTR_* macros listed in this source file * ATTR_* macros listed in this source file
*/ */
uint16_t DetachTimeout; /**< Timeout in milliseconds between a USB_DETACH uint16_t DetachTimeout; /**< Timeout in milliseconds between a USB_DETACH
* command being issued and the device detaching * command being issued and the device detaching
* from the USB bus * from the USB bus
*/ */
uint16_t TransferSize; /**< Maximum number of bytes the DFU device can accept uint16_t TransferSize; /**< Maximum number of bytes the DFU device can accept
* from the host in a transaction * from the host in a transaction
*/ */
uint16_t DFUSpecification; /**< BCD packed DFU specification number this DFU uint16_t DFUSpecification; /**< BCD packed DFU specification number this DFU
* device complies with * device complies with
*/ */
} USB_DFU_Functional_Descriptor_t; } USB_DFU_Functional_Descriptor_t;
/** Type define for the device configuration descriptor structure. This must be defined in the /** Type define for the device configuration descriptor structure. This must be defined in the
* application code, as the configuration descriptor contains several sub-descriptors which * application code, as the configuration descriptor contains several sub-descriptors which
* vary between devices, and which describe the device's usage to the host. * vary between devices, and which describe the device's usage to the host.
*/ */
typedef struct typedef struct
{ {
USB_Descriptor_Configuration_Header_t Config; USB_Descriptor_Configuration_Header_t Config;
USB_Descriptor_Interface_t DFU_Interface; USB_Descriptor_Interface_t DFU_Interface;
USB_DFU_Functional_Descriptor_t DFU_Functional; USB_DFU_Functional_Descriptor_t DFU_Functional;
} USB_Descriptor_Configuration_t; } USB_Descriptor_Configuration_t;
/* Function Prototypes: */ /* Function Prototypes: */
uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, void** const DescriptorAddress) uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, void** const DescriptorAddress)
ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3); ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3);
#endif #endif

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,189 +1,189 @@
/* /*
LUFA Library LUFA Library
Copyright (C) Dean Camera, 2010. Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com www.fourwalledcubicle.com
*/ */
/* /*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com) Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the advertising or publicity pertaining to distribution of the
software without specific, written prior permission. software without specific, written prior permission.
The author disclaim all warranties with regard to this The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action, in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of arising out of or in connection with the use or performance of
this software. this software.
*/ */
/** \file /** \file
* *
* USB Device Descriptors, for library use when in USB device mode. Descriptors are special * USB Device Descriptors, for library use when in USB device mode. Descriptors are special
* computer-readable structures which the host requests upon device enumeration, to determine * computer-readable structures which the host requests upon device enumeration, to determine
* the device's capabilities and functions. * the device's capabilities and functions.
*/ */
#include "Descriptors.h" #include "Descriptors.h"
/** HID class report descriptor. This is a special descriptor constructed with values from the /** HID class report descriptor. This is a special descriptor constructed with values from the
* USBIF HID class specification to describe the reports and capabilities of the HID device. This * USBIF HID class specification to describe the reports and capabilities of the HID device. This
* descriptor is parsed by the host and its contents used to determine what data (and in what encoding) * descriptor is parsed by the host and its contents used to determine what data (and in what encoding)
* the device will send, and what it may be sent back from the host. Refer to the HID specification for * the device will send, and what it may be sent back from the host. Refer to the HID specification for
* more details on HID report descriptors. * more details on HID report descriptors.
*/ */
USB_Descriptor_HIDReport_Datatype_t HIDReport[] = USB_Descriptor_HIDReport_Datatype_t HIDReport[] =
{ {
0x06, 0x9c, 0xff, /* Usage Page (Vendor Defined) */ 0x06, 0x9c, 0xff, /* Usage Page (Vendor Defined) */
0x09, TEENSY_USAGEPAGE, /* Usage (Vendor Defined) */ 0x09, TEENSY_USAGEPAGE, /* Usage (Vendor Defined) */
0xa1, 0x01, /* Collection (Vendor Defined) */ 0xa1, 0x01, /* Collection (Vendor Defined) */
0x0a, 0x19, 0x00, /* Usage (Vendor Defined) */ 0x0a, 0x19, 0x00, /* Usage (Vendor Defined) */
0x75, 0x08, /* Report Size (8) */ 0x75, 0x08, /* Report Size (8) */
#if (SPM_PAGESIZE == 128) /* Report Count (SPM_PAGESIZE + 2) */ #if (SPM_PAGESIZE == 128) /* Report Count (SPM_PAGESIZE + 2) */
0x95, (SPM_PAGESIZE + 2), 0x95, (SPM_PAGESIZE + 2),
#else #else
0x96, ((SPM_PAGESIZE + 2) & 0xFF), ((SPM_PAGESIZE + 2) >> 8), 0x96, ((SPM_PAGESIZE + 2) & 0xFF), ((SPM_PAGESIZE + 2) >> 8),
#endif #endif
0x15, 0x00, /* Logical Minimum (0) */ 0x15, 0x00, /* Logical Minimum (0) */
0x25, 0xff, /* Logical Maximum (255) */ 0x25, 0xff, /* Logical Maximum (255) */
0x91, 0x02, /* Output (Data, Variable, Absolute) */ 0x91, 0x02, /* Output (Data, Variable, Absolute) */
0xc0 /* End Collection */ 0xc0 /* End Collection */
}; };
/** Device descriptor structure. This descriptor, located in FLASH memory, describes the overall /** Device descriptor structure. This descriptor, located in FLASH memory, describes the overall
* device characteristics, including the supported USB version, control endpoint size and the * device characteristics, including the supported USB version, control endpoint size and the
* number of device configurations. The descriptor is read out by the USB host when the enumeration * number of device configurations. The descriptor is read out by the USB host when the enumeration
* process begins. * process begins.
*/ */
USB_Descriptor_Device_t DeviceDescriptor = USB_Descriptor_Device_t DeviceDescriptor =
{ {
.Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device}, .Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device},
.USBSpecification = VERSION_BCD(01.10), .USBSpecification = VERSION_BCD(01.10),
.Class = 0x00, .Class = 0x00,
.SubClass = 0x00, .SubClass = 0x00,
.Protocol = 0x00, .Protocol = 0x00,
.Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE, .Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE,
.VendorID = 0x16C0, .VendorID = 0x16C0,
.ProductID = 0x0478, .ProductID = 0x0478,
.ReleaseNumber = 0x0120, .ReleaseNumber = 0x0120,
.ManufacturerStrIndex = NO_DESCRIPTOR, .ManufacturerStrIndex = NO_DESCRIPTOR,
.ProductStrIndex = NO_DESCRIPTOR, .ProductStrIndex = NO_DESCRIPTOR,
.SerialNumStrIndex = NO_DESCRIPTOR, .SerialNumStrIndex = NO_DESCRIPTOR,
.NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS .NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS
}; };
/** Configuration descriptor structure. This descriptor, located in FLASH memory, describes the usage /** Configuration descriptor structure. This descriptor, located in FLASH memory, describes the usage
* of the device in one of its supported configurations, including information about any device interfaces * of the device in one of its supported configurations, including information about any device interfaces
* and endpoints. The descriptor is read out by the USB host during the enumeration process when selecting * and endpoints. The descriptor is read out by the USB host during the enumeration process when selecting
* a configuration so that the host may correctly communicate with the USB device. * a configuration so that the host may correctly communicate with the USB device.
*/ */
USB_Descriptor_Configuration_t ConfigurationDescriptor = USB_Descriptor_Configuration_t ConfigurationDescriptor =
{ {
.Config = .Config =
{ {
.Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration}, .Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration},
.TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t), .TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t),
.TotalInterfaces = 1, .TotalInterfaces = 1,
.ConfigurationNumber = 1, .ConfigurationNumber = 1,
.ConfigurationStrIndex = NO_DESCRIPTOR, .ConfigurationStrIndex = NO_DESCRIPTOR,
.ConfigAttributes = USB_CONFIG_ATTR_BUSPOWERED, .ConfigAttributes = USB_CONFIG_ATTR_BUSPOWERED,
.MaxPowerConsumption = USB_CONFIG_POWER_MA(100) .MaxPowerConsumption = USB_CONFIG_POWER_MA(100)
}, },
.HID_Interface = .HID_Interface =
{ {
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface}, .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
.InterfaceNumber = 0x00, .InterfaceNumber = 0x00,
.AlternateSetting = 0x00, .AlternateSetting = 0x00,
.TotalEndpoints = 1, .TotalEndpoints = 1,
.Class = 0x03, .Class = 0x03,
.SubClass = 0x00, .SubClass = 0x00,
.Protocol = 0x00, .Protocol = 0x00,
.InterfaceStrIndex = NO_DESCRIPTOR .InterfaceStrIndex = NO_DESCRIPTOR
}, },
.HID_VendorHID = .HID_VendorHID =
{ {
.Header = {.Size = sizeof(USB_Descriptor_HID_t), .Type = DTYPE_HID}, .Header = {.Size = sizeof(USB_Descriptor_HID_t), .Type = DTYPE_HID},
.HIDSpec = VERSION_BCD(01.11), .HIDSpec = VERSION_BCD(01.11),
.CountryCode = 0x00, .CountryCode = 0x00,
.TotalHIDDescriptors = 1, .TotalHIDDescriptors = 1,
.HIDReportType = DTYPE_Report, .HIDReportType = DTYPE_Report,
.HIDReportLength = sizeof(HIDReport) .HIDReportLength = sizeof(HIDReport)
}, },
.HID_ReportINEndpoint = .HID_ReportINEndpoint =
{ {
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint}, .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
.EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_IN | HID_EPNUM), .EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_IN | HID_EPNUM),
.Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
.EndpointSize = HID_EPSIZE, .EndpointSize = HID_EPSIZE,
.PollingIntervalMS = 0x40 .PollingIntervalMS = 0x40
}, },
}; };
/** This function is called by the library when in device mode, and must be overridden (see library "USB Descriptors" /** This function is called by the library when in device mode, and must be overridden (see library "USB Descriptors"
* documentation) by the application code so that the address and size of a requested descriptor can be given * documentation) by the application code so that the address and size of a requested descriptor can be given
* to the USB library. When the device receives a Get Descriptor request on the control endpoint, this function * to the USB library. When the device receives a Get Descriptor request on the control endpoint, this function
* is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the * is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the
* USB host. * USB host.
*/ */
uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, void** const DescriptorAddress) uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, void** const DescriptorAddress)
{ {
const uint8_t DescriptorType = (wValue >> 8); const uint8_t DescriptorType = (wValue >> 8);
void* Address = NULL; void* Address = NULL;
uint16_t Size = NO_DESCRIPTOR; uint16_t Size = NO_DESCRIPTOR;
/* If/Else If chain compiles slightly smaller than a switch case */ /* If/Else If chain compiles slightly smaller than a switch case */
if (DescriptorType == DTYPE_Device) if (DescriptorType == DTYPE_Device)
{ {
Address = (void*)&DeviceDescriptor; Address = (void*)&DeviceDescriptor;
Size = sizeof(USB_Descriptor_Device_t); Size = sizeof(USB_Descriptor_Device_t);
} }
else if (DescriptorType == DTYPE_Configuration) else if (DescriptorType == DTYPE_Configuration)
{ {
Address = (void*)&ConfigurationDescriptor; Address = (void*)&ConfigurationDescriptor;
Size = sizeof(USB_Descriptor_Configuration_t); Size = sizeof(USB_Descriptor_Configuration_t);
} }
else if (DescriptorType == DTYPE_HID) else if (DescriptorType == DTYPE_HID)
{ {
Address = (void*)&ConfigurationDescriptor.HID_VendorHID; Address = (void*)&ConfigurationDescriptor.HID_VendorHID;
Size = sizeof(USB_Descriptor_HID_t); Size = sizeof(USB_Descriptor_HID_t);
} }
else else
{ {
Address = (void*)&HIDReport; Address = (void*)&HIDReport;
Size = sizeof(HIDReport); Size = sizeof(HIDReport);
} }
*DescriptorAddress = Address; *DescriptorAddress = Address;
return Size; return Size;
} }

View file

@ -1,115 +1,115 @@
/* /*
LUFA Library LUFA Library
Copyright (C) Dean Camera, 2010. Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com www.fourwalledcubicle.com
*/ */
/* /*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com) Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the advertising or publicity pertaining to distribution of the
software without specific, written prior permission. software without specific, written prior permission.
The author disclaim all warranties with regard to this The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action, in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of arising out of or in connection with the use or performance of
this software. this software.
*/ */
/** \file /** \file
* *
* Header file for Descriptors.c. * Header file for Descriptors.c.
*/ */
#ifndef _DESCRIPTORS_H_ #ifndef _DESCRIPTORS_H_
#define _DESCRIPTORS_H_ #define _DESCRIPTORS_H_
/* Includes: */ /* Includes: */
#include <LUFA/Drivers/USB/USB.h> #include <LUFA/Drivers/USB/USB.h>
/* Type Defines: */ /* Type Defines: */
/** Type define for the HID class specific HID descriptor, to describe the HID device's specifications. Refer to the HID /** Type define for the HID class specific HID descriptor, to describe the HID device's specifications. Refer to the HID
* specification for details on the structure elements. * specification for details on the structure elements.
*/ */
typedef struct typedef struct
{ {
USB_Descriptor_Header_t Header; USB_Descriptor_Header_t Header;
uint16_t HIDSpec; uint16_t HIDSpec;
uint8_t CountryCode; uint8_t CountryCode;
uint8_t TotalHIDDescriptors; uint8_t TotalHIDDescriptors;
uint8_t HIDReportType; uint8_t HIDReportType;
uint16_t HIDReportLength; uint16_t HIDReportLength;
} USB_Descriptor_HID_t; } USB_Descriptor_HID_t;
/** Type define for the data type used to store HID report descriptor elements. */ /** Type define for the data type used to store HID report descriptor elements. */
typedef uint8_t USB_Descriptor_HIDReport_Datatype_t; typedef uint8_t USB_Descriptor_HIDReport_Datatype_t;
/** Type define for the device configuration descriptor structure. This must be defined in the /** Type define for the device configuration descriptor structure. This must be defined in the
* application code, as the configuration descriptor contains several sub-descriptors which * application code, as the configuration descriptor contains several sub-descriptors which
* vary between devices, and which describe the device's usage to the host. * vary between devices, and which describe the device's usage to the host.
*/ */
typedef struct typedef struct
{ {
USB_Descriptor_Configuration_Header_t Config; USB_Descriptor_Configuration_Header_t Config;
USB_Descriptor_Interface_t HID_Interface; USB_Descriptor_Interface_t HID_Interface;
USB_Descriptor_HID_t HID_VendorHID; USB_Descriptor_HID_t HID_VendorHID;
USB_Descriptor_Endpoint_t HID_ReportINEndpoint; USB_Descriptor_Endpoint_t HID_ReportINEndpoint;
} USB_Descriptor_Configuration_t; } USB_Descriptor_Configuration_t;
/* Macros: */ /* Macros: */
/** Endpoint number of the HID data IN endpoint. */ /** Endpoint number of the HID data IN endpoint. */
#define HID_EPNUM 1 #define HID_EPNUM 1
/** Size in bytes of the HID reporting IN endpoint. */ /** Size in bytes of the HID reporting IN endpoint. */
#define HID_EPSIZE 64 #define HID_EPSIZE 64
/** Descriptor header type value, to indicate a HID class HID descriptor. */ /** Descriptor header type value, to indicate a HID class HID descriptor. */
#define DTYPE_HID 0x21 #define DTYPE_HID 0x21
/** Descriptor header type value, to indicate a HID class HID report descriptor. */ /** Descriptor header type value, to indicate a HID class HID report descriptor. */
#define DTYPE_Report 0x22 #define DTYPE_Report 0x22
/** Vendor usage page for the Teensy 1.0 board */ /** Vendor usage page for the Teensy 1.0 board */
#define TEENSY_USAGEPAGE_10 0x19 #define TEENSY_USAGEPAGE_10 0x19
/** Vendor usage page for the Teensy++ 1.0 board */ /** Vendor usage page for the Teensy++ 1.0 board */
#define TEENSY_USAGEPAGE_10PP 0x1A #define TEENSY_USAGEPAGE_10PP 0x1A
/** Vendor usage page for the Teensy 2.0 board */ /** Vendor usage page for the Teensy 2.0 board */
#define TEENSY_USAGEPAGE_20 0x1B #define TEENSY_USAGEPAGE_20 0x1B
/** Vendor usage page for the Teensy++ 2.0 board */ /** Vendor usage page for the Teensy++ 2.0 board */
#define TEENSY_USAGEPAGE_20PP 0x1C #define TEENSY_USAGEPAGE_20PP 0x1C
#if (defined(__AVR_AT90USB162__) || defined(__AVR_ATmega16U2__)) #if (defined(__AVR_AT90USB162__) || defined(__AVR_ATmega16U2__))
#define TEENSY_USAGEPAGE TEENSY_USAGEPAGE_10 #define TEENSY_USAGEPAGE TEENSY_USAGEPAGE_10
#elif defined(__AVR_ATmega32U4__) #elif defined(__AVR_ATmega32U4__)
#define TEENSY_USAGEPAGE TEENSY_USAGEPAGE_20 #define TEENSY_USAGEPAGE TEENSY_USAGEPAGE_20
#elif (defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB647__)) #elif (defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB647__))
#define TEENSY_USAGEPAGE TEENSY_USAGEPAGE_10PP #define TEENSY_USAGEPAGE TEENSY_USAGEPAGE_10PP
#elif (defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__)) #elif (defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__))
#define TEENSY_USAGEPAGE TEENSY_USAGEPAGE_20PP #define TEENSY_USAGEPAGE TEENSY_USAGEPAGE_20PP
#else #else
#error The selected AVR model is not currently supported by the TeensyHID bootloader. #error The selected AVR model is not currently supported by the TeensyHID bootloader.
#endif #endif
/* Function Prototypes: */ /* Function Prototypes: */
uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, void** const DescriptorAddress) uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, void** const DescriptorAddress)
ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3); ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3);
#endif #endif

File diff suppressed because it is too large Load diff

View file

@ -1,157 +1,157 @@
/* /*
LUFA Library LUFA Library
Copyright (C) Dean Camera, 2010. Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com www.fourwalledcubicle.com
*/ */
/* /*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com) Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the advertising or publicity pertaining to distribution of the
software without specific, written prior permission. software without specific, written prior permission.
The author disclaim all warranties with regard to this The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action, in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of arising out of or in connection with the use or performance of
this software. this software.
*/ */
/** \file /** \file
* *
* Main source file for the TeensyHID bootloader. This file contains the complete bootloader logic. * Main source file for the TeensyHID bootloader. This file contains the complete bootloader logic.
*/ */
#include "TeensyHID.h" #include "TeensyHID.h"
/** Flag to indicate if the bootloader should be running, or should exit and allow the application code to run /** Flag to indicate if the bootloader should be running, or should exit and allow the application code to run
* via a soft reset. When cleared, the bootloader will abort, the USB interface will shut down and the application * via a soft reset. When cleared, the bootloader will abort, the USB interface will shut down and the application
* started via a forced watchdog reset. * started via a forced watchdog reset.
*/ */
bool RunBootloader = true; bool RunBootloader = true;
/** Main program entry point. This routine configures the hardware required by the bootloader, then continuously /** Main program entry point. This routine configures the hardware required by the bootloader, then continuously
* runs the bootloader processing routine until instructed to soft-exit. * runs the bootloader processing routine until instructed to soft-exit.
*/ */
int main(void) int main(void)
{ {
/* Setup hardware required for the bootloader */ /* Setup hardware required for the bootloader */
SetupHardware(); SetupHardware();
/* Enable global interrupts so that the USB stack can function */ /* Enable global interrupts so that the USB stack can function */
sei(); sei();
while (RunBootloader) while (RunBootloader)
USB_USBTask(); USB_USBTask();
/* Disconnect from the host - USB interface will be reset later along with the AVR */ /* Disconnect from the host - USB interface will be reset later along with the AVR */
USB_Detach(); USB_Detach();
/* Enable the watchdog and force a timeout to reset the AVR */ /* Enable the watchdog and force a timeout to reset the AVR */
wdt_enable(WDTO_250MS); wdt_enable(WDTO_250MS);
for (;;); for (;;);
} }
/** Configures all hardware required for the bootloader. */ /** Configures all hardware required for the bootloader. */
void SetupHardware(void) void SetupHardware(void)
{ {
/* Disable watchdog if enabled by bootloader/fuses */ /* Disable watchdog if enabled by bootloader/fuses */
MCUSR &= ~(1 << WDRF); MCUSR &= ~(1 << WDRF);
wdt_disable(); wdt_disable();
/* Relocate the interrupt vector table to the bootloader section */ /* Relocate the interrupt vector table to the bootloader section */
MCUCR = (1 << IVCE); MCUCR = (1 << IVCE);
MCUCR = (1 << IVSEL); MCUCR = (1 << IVSEL);
/* Initialize USB subsystem */ /* Initialize USB subsystem */
USB_Init(); USB_Init();
} }
/** Event handler for the USB_ConfigurationChanged event. This configures the device's endpoints ready /** Event handler for the USB_ConfigurationChanged event. This configures the device's endpoints ready
* to relay data to and from the attached USB host. * to relay data to and from the attached USB host.
*/ */
void EVENT_USB_Device_ConfigurationChanged(void) void EVENT_USB_Device_ConfigurationChanged(void)
{ {
/* Setup HID Report Endpoint */ /* Setup HID Report Endpoint */
Endpoint_ConfigureEndpoint(HID_EPNUM, EP_TYPE_INTERRUPT, Endpoint_ConfigureEndpoint(HID_EPNUM, EP_TYPE_INTERRUPT,
ENDPOINT_DIR_IN, HID_EPSIZE, ENDPOINT_DIR_IN, HID_EPSIZE,
ENDPOINT_BANK_SINGLE); ENDPOINT_BANK_SINGLE);
} }
/** Event handler for the USB_UnhandledControlRequest event. This is used to catch standard and class specific /** Event handler for the USB_UnhandledControlRequest event. This is used to catch standard and class specific
* control requests that are not handled internally by the USB library (including the HID commands, which are * control requests that are not handled internally by the USB library (including the HID commands, which are
* all issued via the control endpoint), so that they can be handled appropriately for the application. * all issued via the control endpoint), so that they can be handled appropriately for the application.
*/ */
void EVENT_USB_Device_UnhandledControlRequest(void) void EVENT_USB_Device_UnhandledControlRequest(void)
{ {
/* Handle HID Class specific requests */ /* Handle HID Class specific requests */
switch (USB_ControlRequest.bRequest) switch (USB_ControlRequest.bRequest)
{ {
case REQ_SetReport: case REQ_SetReport:
Endpoint_ClearSETUP(); Endpoint_ClearSETUP();
/* Wait until the command has been sent by the host */ /* Wait until the command has been sent by the host */
while (!(Endpoint_IsOUTReceived())); while (!(Endpoint_IsOUTReceived()));
/* Read in the write destination index */ /* Read in the write destination index */
uint16_t PageIndex = Endpoint_Read_Word_LE(); uint16_t PageIndex = Endpoint_Read_Word_LE();
/* Check if the command is a program page command, or a start application command */ /* Check if the command is a program page command, or a start application command */
if (PageIndex == TEENSY_STARTAPPLICATION) if (PageIndex == TEENSY_STARTAPPLICATION)
{ {
RunBootloader = false; RunBootloader = false;
} }
else else
{ {
#if (FLASHEND > 0xFFFF) #if (FLASHEND > 0xFFFF)
uint32_t PageByteAddress = ((uint32_t)PageIndex << 8); uint32_t PageByteAddress = ((uint32_t)PageIndex << 8);
#else #else
uint16_t PageByteAddress = PageIndex; uint16_t PageByteAddress = PageIndex;
#endif #endif
/* Erase the given FLASH page, ready to be programmed */ /* Erase the given FLASH page, ready to be programmed */
boot_page_erase(PageByteAddress); boot_page_erase(PageByteAddress);
boot_spm_busy_wait(); boot_spm_busy_wait();
/* Write each of the FLASH page's bytes in sequence */ /* Write each of the FLASH page's bytes in sequence */
#if (SPM_PAGESIZE == 128) #if (SPM_PAGESIZE == 128)
for (uint8_t PageByte = 0; PageByte < SPM_PAGESIZE; PageByte += 2) for (uint8_t PageByte = 0; PageByte < SPM_PAGESIZE; PageByte += 2)
#else #else
for (uint16_t PageByte = 0; PageByte < SPM_PAGESIZE; PageByte += 2) for (uint16_t PageByte = 0; PageByte < SPM_PAGESIZE; PageByte += 2)
#endif #endif
{ {
/* Check if endpoint is empty - if so clear it and wait until ready for next packet */ /* Check if endpoint is empty - if so clear it and wait until ready for next packet */
if (!(Endpoint_BytesInEndpoint())) if (!(Endpoint_BytesInEndpoint()))
{ {
Endpoint_ClearOUT(); Endpoint_ClearOUT();
while (!(Endpoint_IsOUTReceived())); while (!(Endpoint_IsOUTReceived()));
} }
/* Write the next data word to the FLASH page */ /* Write the next data word to the FLASH page */
boot_page_fill(PageByteAddress + PageByte, Endpoint_Read_Word_LE()); boot_page_fill(PageByteAddress + PageByte, Endpoint_Read_Word_LE());
} }
/* Write the filled FLASH page to memory */ /* Write the filled FLASH page to memory */
boot_page_write(PageByteAddress); boot_page_write(PageByteAddress);
boot_spm_busy_wait(); boot_spm_busy_wait();
} }
Endpoint_ClearOUT(); Endpoint_ClearOUT();
Endpoint_ClearStatusStage(); Endpoint_ClearStatusStage();
break; break;
} }
} }

View file

@ -1,64 +1,64 @@
/* /*
LUFA Library LUFA Library
Copyright (C) Dean Camera, 2010. Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com www.fourwalledcubicle.com
*/ */
/* /*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com) Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the advertising or publicity pertaining to distribution of the
software without specific, written prior permission. software without specific, written prior permission.
The author disclaim all warranties with regard to this The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action, in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of arising out of or in connection with the use or performance of
this software. this software.
*/ */
/** \file /** \file
* *
* Header file for TeensyHID.c. * Header file for TeensyHID.c.
*/ */
#ifndef _TEENSYHID_H_ #ifndef _TEENSYHID_H_
#define _TEENSYHID_H_ #define _TEENSYHID_H_
/* Includes: */ /* Includes: */
#include <avr/io.h> #include <avr/io.h>
#include <avr/wdt.h> #include <avr/wdt.h>
#include <avr/boot.h> #include <avr/boot.h>
#include <avr/power.h> #include <avr/power.h>
#include <avr/interrupt.h> #include <avr/interrupt.h>
#include <stdbool.h> #include <stdbool.h>
#include "Descriptors.h" #include "Descriptors.h"
#include <LUFA/Drivers/USB/USB.h> #include <LUFA/Drivers/USB/USB.h>
/* Macros: */ /* Macros: */
/** HID Class specific request to send the next HID report to the device. */ /** HID Class specific request to send the next HID report to the device. */
#define REQ_SetReport 0x09 #define REQ_SetReport 0x09
/** Teensy Bootloader special address to start the user application */ /** Teensy Bootloader special address to start the user application */
#define TEENSY_STARTAPPLICATION 0xFFFF #define TEENSY_STARTAPPLICATION 0xFFFF
/* Function Prototypes: */ /* Function Prototypes: */
void SetupHardware(void); void SetupHardware(void);
void EVENT_USB_Device_ConfigurationChanged(void); void EVENT_USB_Device_ConfigurationChanged(void);
void EVENT_USB_Device_UnhandledControlRequest(void); void EVENT_USB_Device_UnhandledControlRequest(void);
#endif #endif

View file

@ -1,72 +1,72 @@
/** \file /** \file
* *
* This file contains special DoxyGen information for the generation of the main page and other special * 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. * documentation pages. It is not a project source file.
*/ */
/** \mainpage Teensy HID Class USB AVR Bootloader /** \mainpage Teensy HID Class USB AVR Bootloader
* *
* \section SSec_Compat Demo Compatibility: * \section SSec_Compat Demo Compatibility:
* *
* The following list indicates what microcontrollers are compatible with this demo. * The following list indicates what microcontrollers are compatible with this demo.
* *
* - AT90USB162 (Teensy 1.0) * - AT90USB162 (Teensy 1.0)
* - AT90USB646 (Teensy++ 1.0) * - AT90USB646 (Teensy++ 1.0)
* - ATMEGA32U4 (Teensy 2.0) * - ATMEGA32U4 (Teensy 2.0)
* - AT90USB1286 (Teensy++ 2.0) * - AT90USB1286 (Teensy++ 2.0)
* *
* \section SSec_Info USB Information: * \section SSec_Info USB Information:
* *
* The following table gives a rundown of the USB utilization of this demo. * The following table gives a rundown of the USB utilization of this demo.
* *
* <table> * <table>
* <tr> * <tr>
* <td><b>USB Mode:</b></td> * <td><b>USB Mode:</b></td>
* <td>Device</td> * <td>Device</td>
* </tr> * </tr>
* <tr> * <tr>
* <td><b>USB Class:</b></td> * <td><b>USB Class:</b></td>
* <td>Human Interface Device Class (HID)</td> * <td>Human Interface Device Class (HID)</td>
* </tr> * </tr>
* <tr> * <tr>
* <td><b>USB Subclass:</b></td> * <td><b>USB Subclass:</b></td>
* <td>N/A</td> * <td>N/A</td>
* </tr> * </tr>
* <tr> * <tr>
* <td><b>Relevant Standards:</b></td> * <td><b>Relevant Standards:</b></td>
* <td>USBIF HID Class Standard \n * <td>USBIF HID Class Standard \n
* Teensy Programming Protocol Specification</td> * Teensy Programming Protocol Specification</td>
* </tr> * </tr>
* <tr> * <tr>
* <td><b>Usable Speeds:</b></td> * <td><b>Usable Speeds:</b></td>
* <td>Low Speed Mode \n * <td>Low Speed Mode \n
* Full Speed Mode</td> * Full Speed Mode</td>
* </tr> * </tr>
* </table> * </table>
* *
* \section SSec_Description Project Description: * \section SSec_Description Project Description:
* *
* This bootloader enumerates to the host as a HID Class device, allowing for Teensy compatible programming * This bootloader enumerates to the host as a HID Class device, allowing for Teensy compatible programming
* software to load firmware onto the AVR, such as the official software at <a>http://www.pjrc.com/teensy/</a>. * software to load firmware onto the AVR, such as the official software at <a>http://www.pjrc.com/teensy/</a>.
* *
* Out of the box this bootloader builds for the ATMEGA32U4, and will fit into 2-4KB of bootloader space. For other * Out of the box this bootloader builds for the ATMEGA32U4, and will fit into 2-4KB of bootloader space. For other
* devices, the makefile will need to be updated to reflect the altered MCU model and bootloader start address. When * devices, the makefile will need to be updated to reflect the altered MCU model and bootloader start address. When
* calculating the bootloader start address, use (TARGET_FLASH_SIZE_BYTES - 4096) for targets where the bootloader * calculating the bootloader start address, use (TARGET_FLASH_SIZE_BYTES - 4096) for targets where the bootloader
* compiles larger than 2KB, or (TARGET_FLASH_SIZE_BYTES - 2048) for smaller targets where the bootloader compiles * compiles larger than 2KB, or (TARGET_FLASH_SIZE_BYTES - 2048) for smaller targets where the bootloader compiles
* under 2KB. * under 2KB.
* *
* This spoofs (with permission) the official Teensy bootloader's VID and PID, so that the software remains * This spoofs (with permission) the official Teensy bootloader's VID and PID, so that the software remains
* compatible with no changes. * compatible with no changes.
* *
* \section SSec_Options Project Options * \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. * The following defines can be found in this demo, which can control the demo behaviour when defined, or changed in value.
* *
* <table> * <table>
* <tr> * <tr>
* <td> * <td>
* None * None
* </td> * </td>
* </tr> * </tr>
* </table> * </table>
*/ */

File diff suppressed because it is too large Load diff

View file

@ -1,29 +1,29 @@
# #
# LUFA Library # LUFA Library
# Copyright (C) Dean Camera, 2010. # Copyright (C) Dean Camera, 2010.
# #
# dean [at] fourwalledcubicle [dot] com # dean [at] fourwalledcubicle [dot] com
# www.fourwalledcubicle.com # www.fourwalledcubicle.com
# #
# Makefile to build all the LUFA USB Bootloaders. Call with "make all" to # Makefile to build all the LUFA USB Bootloaders. Call with "make all" to
# rebuild all bootloaders. # rebuild all bootloaders.
# Bootloaders are pre-cleaned before each one is built, to ensure any # Bootloaders are pre-cleaned before each one is built, to ensure any
# custom LUFA library build options are reflected in the compiled # custom LUFA library build options are reflected in the compiled
# code. # code.
all: all:
$(MAKE) -C DFU clean $(MAKE) -C DFU clean
$(MAKE) -C DFU all $(MAKE) -C DFU all
$(MAKE) -C CDC clean $(MAKE) -C CDC clean
$(MAKE) -C CDC all $(MAKE) -C CDC all
$(MAKE) -C TeensyHID clean $(MAKE) -C TeensyHID clean
$(MAKE) -C TeensyHID all $(MAKE) -C TeensyHID all
%: %:
$(MAKE) -C DFU $@ $(MAKE) -C DFU $@
$(MAKE) -C CDC $@ $(MAKE) -C CDC $@
$(MAKE) -C TeensyHID $@ $(MAKE) -C TeensyHID $@

View file

@ -1,148 +1,148 @@
/* /*
LUFA Library LUFA Library
Copyright (C) Dean Camera, 2010. Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com www.fourwalledcubicle.com
*/ */
/* /*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com) Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the advertising or publicity pertaining to distribution of the
software without specific, written prior permission. software without specific, written prior permission.
The author disclaim all warranties with regard to this The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action, in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of arising out of or in connection with the use or performance of
this software. this software.
*/ */
/** \file /** \file
* *
* Main source file for the AudioInput demo. This file contains the main tasks of * Main source file for the AudioInput demo. This file contains the main tasks of
* the demo and is responsible for the initial application hardware configuration. * the demo and is responsible for the initial application hardware configuration.
*/ */
#include "AudioInput.h" #include "AudioInput.h"
/** LUFA Audio Class driver interface configuration and state information. This structure is /** LUFA Audio Class driver interface configuration and state information. This structure is
* passed to all Audio Class driver functions, so that multiple instances of the same class * passed to all Audio Class driver functions, so that multiple instances of the same class
* within a device can be differentiated from one another. * within a device can be differentiated from one another.
*/ */
USB_ClassInfo_Audio_Device_t Microphone_Audio_Interface = USB_ClassInfo_Audio_Device_t Microphone_Audio_Interface =
{ {
.Config = .Config =
{ {
.StreamingInterfaceNumber = 1, .StreamingInterfaceNumber = 1,
.DataINEndpointNumber = AUDIO_STREAM_EPNUM, .DataINEndpointNumber = AUDIO_STREAM_EPNUM,
.DataINEndpointSize = AUDIO_STREAM_EPSIZE, .DataINEndpointSize = AUDIO_STREAM_EPSIZE,
}, },
}; };
/** Main program entry point. This routine contains the overall program flow, including initial /** Main program entry point. This routine contains the overall program flow, including initial
* setup of all components and the main program loop. * setup of all components and the main program loop.
*/ */
int main(void) int main(void)
{ {
SetupHardware(); SetupHardware();
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY); LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
sei(); sei();
for (;;) for (;;)
{ {
ProcessNextSample(); ProcessNextSample();
Audio_Device_USBTask(&Microphone_Audio_Interface); Audio_Device_USBTask(&Microphone_Audio_Interface);
USB_USBTask(); USB_USBTask();
} }
} }
/** Configures the board hardware and chip peripherals for the demo's functionality. */ /** Configures the board hardware and chip peripherals for the demo's functionality. */
void SetupHardware(void) void SetupHardware(void)
{ {
/* Disable watchdog if enabled by bootloader/fuses */ /* Disable watchdog if enabled by bootloader/fuses */
MCUSR &= ~(1 << WDRF); MCUSR &= ~(1 << WDRF);
wdt_disable(); wdt_disable();
/* Disable clock division */ /* Disable clock division */
clock_prescale_set(clock_div_1); clock_prescale_set(clock_div_1);
/* Hardware Initialization */ /* Hardware Initialization */
LEDs_Init(); LEDs_Init();
USB_Init(); USB_Init();
ADC_Init(ADC_FREE_RUNNING | ADC_PRESCALE_32); ADC_Init(ADC_FREE_RUNNING | ADC_PRESCALE_32);
ADC_SetupChannel(MIC_IN_ADC_CHANNEL); ADC_SetupChannel(MIC_IN_ADC_CHANNEL);
/* Start the ADC conversion in free running mode */ /* Start the ADC conversion in free running mode */
ADC_StartReading(ADC_REFERENCE_AVCC | ADC_RIGHT_ADJUSTED | MIC_IN_ADC_MUX_MASK); ADC_StartReading(ADC_REFERENCE_AVCC | ADC_RIGHT_ADJUSTED | MIC_IN_ADC_MUX_MASK);
} }
/** Processes the next audio sample by reading the last ADC conversion and writing it to the audio /** Processes the next audio sample by reading the last ADC conversion and writing it to the audio
* interface, each time the sample reload timer period elapses to give a constant sample rate. * interface, each time the sample reload timer period elapses to give a constant sample rate.
*/ */
void ProcessNextSample(void) void ProcessNextSample(void)
{ {
/* Check if the sample reload timer period has elapsed, and that the USB bus is ready for a new sample */ /* Check if the sample reload timer period has elapsed, and that the USB bus is ready for a new sample */
if ((TIFR0 & (1 << OCF0A)) && Audio_Device_IsReadyForNextSample(&Microphone_Audio_Interface)) if ((TIFR0 & (1 << OCF0A)) && Audio_Device_IsReadyForNextSample(&Microphone_Audio_Interface))
{ {
TIFR0 |= (1 << OCF0A); TIFR0 |= (1 << OCF0A);
/* Audio sample is ADC value scaled to fit the entire range */ /* Audio sample is ADC value scaled to fit the entire range */
int16_t AudioSample = ((SAMPLE_MAX_RANGE / ADC_MAX_RANGE) * ADC_GetResult()); int16_t AudioSample = ((SAMPLE_MAX_RANGE / ADC_MAX_RANGE) * ADC_GetResult());
#if defined(MICROPHONE_BIASED_TO_HALF_RAIL) #if defined(MICROPHONE_BIASED_TO_HALF_RAIL)
/* Microphone is biased to half rail voltage, subtract the bias from the sample value */ /* Microphone is biased to half rail voltage, subtract the bias from the sample value */
AudioSample -= (SAMPLE_MAX_RANGE / 2); AudioSample -= (SAMPLE_MAX_RANGE / 2);
#endif #endif
Audio_Device_WriteSample16(&Microphone_Audio_Interface, AudioSample); Audio_Device_WriteSample16(&Microphone_Audio_Interface, AudioSample);
} }
} }
/** Event handler for the library USB Connection event. */ /** Event handler for the library USB Connection event. */
void EVENT_USB_Device_Connect(void) void EVENT_USB_Device_Connect(void)
{ {
LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING); LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
/* Sample reload timer initialization */ /* Sample reload timer initialization */
OCR0A = (F_CPU / 8 / AUDIO_SAMPLE_FREQUENCY) - 1; OCR0A = (F_CPU / 8 / AUDIO_SAMPLE_FREQUENCY) - 1;
TCCR0A = (1 << WGM01); // CTC mode TCCR0A = (1 << WGM01); // CTC mode
TCCR0B = (1 << CS01); // Fcpu/8 speed TCCR0B = (1 << CS01); // Fcpu/8 speed
} }
/** Event handler for the library USB Disconnection event. */ /** Event handler for the library USB Disconnection event. */
void EVENT_USB_Device_Disconnect(void) void EVENT_USB_Device_Disconnect(void)
{ {
/* Stop the sample reload timer */ /* Stop the sample reload timer */
TCCR0B = 0; TCCR0B = 0;
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY); LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
} }
/** Event handler for the library USB Configuration Changed event. */ /** Event handler for the library USB Configuration Changed event. */
void EVENT_USB_Device_ConfigurationChanged(void) void EVENT_USB_Device_ConfigurationChanged(void)
{ {
LEDs_SetAllLEDs(LEDMASK_USB_READY); LEDs_SetAllLEDs(LEDMASK_USB_READY);
if (!(Audio_Device_ConfigureEndpoints(&Microphone_Audio_Interface))) if (!(Audio_Device_ConfigureEndpoints(&Microphone_Audio_Interface)))
LEDs_SetAllLEDs(LEDMASK_USB_ERROR); LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
} }
/** Event handler for the library USB Unhandled Control Request event. */ /** Event handler for the library USB Unhandled Control Request event. */
void EVENT_USB_Device_UnhandledControlRequest(void) void EVENT_USB_Device_UnhandledControlRequest(void)
{ {
Audio_Device_ProcessControlRequest(&Microphone_Audio_Interface); Audio_Device_ProcessControlRequest(&Microphone_Audio_Interface);
} }

View file

@ -1,87 +1,87 @@
/* /*
LUFA Library LUFA Library
Copyright (C) Dean Camera, 2010. Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com www.fourwalledcubicle.com
*/ */
/* /*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com) Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the advertising or publicity pertaining to distribution of the
software without specific, written prior permission. software without specific, written prior permission.
The author disclaim all warranties with regard to this The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action, in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of arising out of or in connection with the use or performance of
this software. this software.
*/ */
/** \file /** \file
* *
* Header file for AudioInput.c. * Header file for AudioInput.c.
*/ */
#ifndef _AUDIO_INPUT_H_ #ifndef _AUDIO_INPUT_H_
#define _AUDIO_INPUT_H_ #define _AUDIO_INPUT_H_
/* Includes: */ /* Includes: */
#include <avr/io.h> #include <avr/io.h>
#include <avr/wdt.h> #include <avr/wdt.h>
#include <avr/power.h> #include <avr/power.h>
#include <avr/interrupt.h> #include <avr/interrupt.h>
#include <LUFA/Version.h> #include <LUFA/Version.h>
#include <LUFA/Drivers/Board/LEDs.h> #include <LUFA/Drivers/Board/LEDs.h>
#include <LUFA/Drivers/Peripheral/ADC.h> #include <LUFA/Drivers/Peripheral/ADC.h>
#include <LUFA/Drivers/USB/USB.h> #include <LUFA/Drivers/USB/USB.h>
#include <LUFA/Drivers/USB/Class/Audio.h> #include <LUFA/Drivers/USB/Class/Audio.h>
#include "Descriptors.h" #include "Descriptors.h"
/* Macros: */ /* Macros: */
/** ADC channel number for the microphone input. */ /** ADC channel number for the microphone input. */
#define MIC_IN_ADC_CHANNEL 2 #define MIC_IN_ADC_CHANNEL 2
/** ADC channel MUX mask for the microphone input. */ /** ADC channel MUX mask for the microphone input. */
#define MIC_IN_ADC_MUX_MASK ADC_CHANNEL2 #define MIC_IN_ADC_MUX_MASK ADC_CHANNEL2
/** Maximum ADC sample value for the microphone input. */ /** Maximum ADC sample value for the microphone input. */
#define SAMPLE_MAX_RANGE 0xFFFF #define SAMPLE_MAX_RANGE 0xFFFF
/** Maximum ADC range for the microphone input. */ /** Maximum ADC range for the microphone input. */
#define ADC_MAX_RANGE 0x3FF #define ADC_MAX_RANGE 0x3FF
/** LED mask for the library LED driver, to indicate that the USB interface is not ready. */ /** LED mask for the library LED driver, to indicate that the USB interface is not ready. */
#define LEDMASK_USB_NOTREADY LEDS_LED1 #define LEDMASK_USB_NOTREADY LEDS_LED1
/** LED mask for the library LED driver, to indicate that the USB interface is enumerating. */ /** LED mask for the library LED driver, to indicate that the USB interface is enumerating. */
#define LEDMASK_USB_ENUMERATING (LEDS_LED2 | LEDS_LED3) #define LEDMASK_USB_ENUMERATING (LEDS_LED2 | LEDS_LED3)
/** LED mask for the library LED driver, to indicate that the USB interface is ready. */ /** LED mask for the library LED driver, to indicate that the USB interface is ready. */
#define LEDMASK_USB_READY (LEDS_LED2 | LEDS_LED4) #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. */ /** 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) #define LEDMASK_USB_ERROR (LEDS_LED1 | LEDS_LED3)
/* Function Prototypes: */ /* Function Prototypes: */
void SetupHardware(void); void SetupHardware(void);
void ProcessNextSample(void); void ProcessNextSample(void);
void EVENT_USB_Device_Connect(void); void EVENT_USB_Device_Connect(void);
void EVENT_USB_Device_Disconnect(void); void EVENT_USB_Device_Disconnect(void);
void EVENT_USB_Device_ConfigurationChanged(void); void EVENT_USB_Device_ConfigurationChanged(void);
void EVENT_USB_Device_UnhandledControlRequest(void); void EVENT_USB_Device_UnhandledControlRequest(void);
#endif #endif

View file

@ -1,83 +1,83 @@
/** \file /** \file
* *
* This file contains special DoxyGen information for the generation of the main page and other special * 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. * documentation pages. It is not a project source file.
*/ */
/** \mainpage Audio Input Device Demo /** \mainpage Audio Input Device Demo
* *
* \section SSec_Compat Demo Compatibility: * \section SSec_Compat Demo Compatibility:
* *
* The following list indicates what microcontrollers are compatible with this demo. * The following list indicates what microcontrollers are compatible with this demo.
* *
* - Series 7 USB AVRs * - Series 7 USB AVRs
* - Series 6 USB AVRs * - Series 6 USB AVRs
* - Series 4 USB AVRs * - Series 4 USB AVRs
* *
* \section SSec_Info USB Information: * \section SSec_Info USB Information:
* *
* The following table gives a rundown of the USB utilization of this demo. * The following table gives a rundown of the USB utilization of this demo.
* *
* <table> * <table>
* <tr> * <tr>
* <td><b>USB Mode:</b></td> * <td><b>USB Mode:</b></td>
* <td>Device</td> * <td>Device</td>
* </tr> * </tr>
* <tr> * <tr>
* <td><b>USB Class:</b></td> * <td><b>USB Class:</b></td>
* <td>Audio Class</td> * <td>Audio Class</td>
* </tr> * </tr>
* <tr> * <tr>
* <td><b>USB Subclass:</b></td> * <td><b>USB Subclass:</b></td>
* <td>Standard Audio Device</td> * <td>Standard Audio Device</td>
* </tr> * </tr>
* <tr> * <tr>
* <td><b>Relevant Standards:</b></td> * <td><b>Relevant Standards:</b></td>
* <td>USBIF Audio Class Specification \n * <td>USBIF Audio Class Specification \n
* USBIF Audio Class Terminal Types Specification \n * USBIF Audio Class Terminal Types Specification \n
* USBIF Audio Data Formats Specification</td> * USBIF Audio Data Formats Specification</td>
* </tr> * </tr>
* <tr> * <tr>
* <td><b>Usable Speeds:</b></td> * <td><b>Usable Speeds:</b></td>
* <td>Full Speed Mode</td> * <td>Full Speed Mode</td>
* </tr> * </tr>
* </table> * </table>
* *
* \section SSec_Description Project Description: * \section SSec_Description Project Description:
* *
* Audio demonstration application. This gives a simple reference * Audio demonstration application. This gives a simple reference
* application for implementing a USB Audio Input device using the * application for implementing a USB Audio Input device using the
* basic USB Audio drivers in all modern OSes (i.e. no special drivers * basic USB Audio drivers in all modern OSes (i.e. no special drivers
* required). * required).
* *
* On start-up the system will automatically enumerate and function * On start-up the system will automatically enumerate and function
* as a USB microphone. Incoming audio from the ADC channel 1 will * as a USB microphone. Incoming audio from the ADC channel 1 will
* be sampled and sent to the host computer. * be sampled and sent to the host computer.
* *
* To use, connect a microphone to the ADC channel 1. * To use, connect a microphone to the ADC channel 1.
* *
* Under Windows, if a driver request dialogue pops up, select the option * Under Windows, if a driver request dialogue pops up, select the option
* to automatically install the appropriate drivers. * to automatically install the appropriate drivers.
* *
* \section SSec_Options Project Options * \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. * The following defines can be found in this demo, which can control the demo behaviour when defined, or changed in value.
* *
* <table> * <table>
* <tr> * <tr>
* <td><b>Define Name:</b></td> * <td><b>Define Name:</b></td>
* <td><b>Location:</b></td> * <td><b>Location:</b></td>
* <td><b>Description:</b></td> * <td><b>Description:</b></td>
* </tr> * </tr>
* <tr> * <tr>
* <td>MICROPHONE_BIASED_TO_HALF_RAIL</td> * <td>MICROPHONE_BIASED_TO_HALF_RAIL</td>
* <td>Makefile CDEFS</td> * <td>Makefile CDEFS</td>
* <td>When defined, this alters the demo so that the half VCC bias of the microphone input is subtracted.</td> * <td>When defined, this alters the demo so that the half VCC bias of the microphone input is subtracted.</td>
* </tr> * </tr>
* <tr> * <tr>
* <td>AUDIO_SAMPLE_FREQUENCY</td> * <td>AUDIO_SAMPLE_FREQUENCY</td>
* <td>Descriptors.h</td> * <td>Descriptors.h</td>
* <td>Gives the audio sample rate per channel for the audio stream, in Hz.</td> * <td>Gives the audio sample rate per channel for the audio stream, in Hz.</td>
* </tr> * </tr>
* </table> * </table>
*/ */

View file

@ -1,314 +1,314 @@
/* /*
LUFA Library LUFA Library
Copyright (C) Dean Camera, 2010. Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com www.fourwalledcubicle.com
*/ */
/* /*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com) Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the advertising or publicity pertaining to distribution of the
software without specific, written prior permission. software without specific, written prior permission.
The author disclaim all warranties with regard to this The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action, in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of arising out of or in connection with the use or performance of
this software. this software.
*/ */
/** \file /** \file
* *
* USB Device Descriptors, for library use when in USB device mode. Descriptors are special * USB Device Descriptors, for library use when in USB device mode. Descriptors are special
* computer-readable structures which the host requests upon device enumeration, to determine * computer-readable structures which the host requests upon device enumeration, to determine
* the device's capabilities and functions. * the device's capabilities and functions.
*/ */
#include "Descriptors.h" #include "Descriptors.h"
/** Device descriptor structure. This descriptor, located in FLASH memory, describes the overall /** Device descriptor structure. This descriptor, located in FLASH memory, describes the overall
* device characteristics, including the supported USB version, control endpoint size and the * device characteristics, including the supported USB version, control endpoint size and the
* number of device configurations. The descriptor is read out by the USB host when the enumeration * number of device configurations. The descriptor is read out by the USB host when the enumeration
* process begins. * process begins.
*/ */
USB_Descriptor_Device_t PROGMEM DeviceDescriptor = USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
{ {
.Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device}, .Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device},
.USBSpecification = VERSION_BCD(02.00), .USBSpecification = VERSION_BCD(02.00),
.Class = 0x00, .Class = 0x00,
.SubClass = 0x00, .SubClass = 0x00,
.Protocol = 0x00, .Protocol = 0x00,
.Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE, .Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE,
.VendorID = 0x03EB, .VendorID = 0x03EB,
.ProductID = 0x2047, .ProductID = 0x2047,
.ReleaseNumber = 0x0000, .ReleaseNumber = 0x0000,
.ManufacturerStrIndex = 0x01, .ManufacturerStrIndex = 0x01,
.ProductStrIndex = 0x02, .ProductStrIndex = 0x02,
.SerialNumStrIndex = NO_DESCRIPTOR, .SerialNumStrIndex = NO_DESCRIPTOR,
.NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS .NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS
}; };
/** Configuration descriptor structure. This descriptor, located in FLASH memory, describes the usage /** Configuration descriptor structure. This descriptor, located in FLASH memory, describes the usage
* of the device in one of its supported configurations, including information about any device interfaces * of the device in one of its supported configurations, including information about any device interfaces
* and endpoints. The descriptor is read out by the USB host during the enumeration process when selecting * and endpoints. The descriptor is read out by the USB host during the enumeration process when selecting
* a configuration so that the host may correctly communicate with the USB device. * a configuration so that the host may correctly communicate with the USB device.
*/ */
USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor = USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
{ {
.Config = .Config =
{ {
.Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration}, .Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration},
.TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t), .TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t),
.TotalInterfaces = 2, .TotalInterfaces = 2,
.ConfigurationNumber = 1, .ConfigurationNumber = 1,
.ConfigurationStrIndex = NO_DESCRIPTOR, .ConfigurationStrIndex = NO_DESCRIPTOR,
.ConfigAttributes = (USB_CONFIG_ATTR_BUSPOWERED | USB_CONFIG_ATTR_SELFPOWERED), .ConfigAttributes = (USB_CONFIG_ATTR_BUSPOWERED | USB_CONFIG_ATTR_SELFPOWERED),
.MaxPowerConsumption = USB_CONFIG_POWER_MA(100) .MaxPowerConsumption = USB_CONFIG_POWER_MA(100)
}, },
.Audio_ControlInterface = .Audio_ControlInterface =
{ {
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface}, .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
.InterfaceNumber = 0, .InterfaceNumber = 0,
.AlternateSetting = 0, .AlternateSetting = 0,
.TotalEndpoints = 0, .TotalEndpoints = 0,
.Class = 0x01, .Class = 0x01,
.SubClass = 0x01, .SubClass = 0x01,
.Protocol = 0x00, .Protocol = 0x00,
.InterfaceStrIndex = NO_DESCRIPTOR .InterfaceStrIndex = NO_DESCRIPTOR
}, },
.Audio_ControlInterface_SPC = .Audio_ControlInterface_SPC =
{ {
.Header = {.Size = sizeof(USB_Audio_Interface_AC_t), .Type = DTYPE_AudioInterface}, .Header = {.Size = sizeof(USB_Audio_Interface_AC_t), .Type = DTYPE_AudioInterface},
.Subtype = DSUBTYPE_Header, .Subtype = DSUBTYPE_Header,
.ACSpecification = VERSION_BCD(01.00), .ACSpecification = VERSION_BCD(01.00),
.TotalLength = (sizeof(USB_Audio_Interface_AC_t) + .TotalLength = (sizeof(USB_Audio_Interface_AC_t) +
sizeof(USB_Audio_InputTerminal_t) + sizeof(USB_Audio_InputTerminal_t) +
sizeof(USB_Audio_OutputTerminal_t)), sizeof(USB_Audio_OutputTerminal_t)),
.InCollection = 1, .InCollection = 1,
.InterfaceNumbers = {1}, .InterfaceNumbers = {1},
}, },
.Audio_InputTerminal = .Audio_InputTerminal =
{ {
.Header = {.Size = sizeof(USB_Audio_InputTerminal_t), .Type = DTYPE_AudioInterface}, .Header = {.Size = sizeof(USB_Audio_InputTerminal_t), .Type = DTYPE_AudioInterface},
.Subtype = DSUBTYPE_InputTerminal, .Subtype = DSUBTYPE_InputTerminal,
.TerminalID = 0x01, .TerminalID = 0x01,
.TerminalType = TERMINAL_IN_MIC, .TerminalType = TERMINAL_IN_MIC,
.AssociatedOutputTerminal = 0x00, .AssociatedOutputTerminal = 0x00,
.TotalChannels = 1, .TotalChannels = 1,
.ChannelConfig = 0, .ChannelConfig = 0,
.ChannelStrIndex = NO_DESCRIPTOR, .ChannelStrIndex = NO_DESCRIPTOR,
.TerminalStrIndex = NO_DESCRIPTOR .TerminalStrIndex = NO_DESCRIPTOR
}, },
.Audio_OutputTerminal = .Audio_OutputTerminal =
{ {
.Header = {.Size = sizeof(USB_Audio_OutputTerminal_t), .Type = DTYPE_AudioInterface}, .Header = {.Size = sizeof(USB_Audio_OutputTerminal_t), .Type = DTYPE_AudioInterface},
.Subtype = DSUBTYPE_OutputTerminal, .Subtype = DSUBTYPE_OutputTerminal,
.TerminalID = 0x02, .TerminalID = 0x02,
.TerminalType = TERMINAL_STREAMING, .TerminalType = TERMINAL_STREAMING,
.AssociatedInputTerminal = 0x00, .AssociatedInputTerminal = 0x00,
.SourceID = 0x01, .SourceID = 0x01,
.TerminalStrIndex = NO_DESCRIPTOR .TerminalStrIndex = NO_DESCRIPTOR
}, },
.Audio_StreamInterface_Alt0 = .Audio_StreamInterface_Alt0 =
{ {
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface}, .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
.InterfaceNumber = 1, .InterfaceNumber = 1,
.AlternateSetting = 0, .AlternateSetting = 0,
.TotalEndpoints = 0, .TotalEndpoints = 0,
.Class = 0x01, .Class = 0x01,
.SubClass = 0x02, .SubClass = 0x02,
.Protocol = 0x00, .Protocol = 0x00,
.InterfaceStrIndex = NO_DESCRIPTOR .InterfaceStrIndex = NO_DESCRIPTOR
}, },
.Audio_StreamInterface_Alt1 = .Audio_StreamInterface_Alt1 =
{ {
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface}, .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
.InterfaceNumber = 1, .InterfaceNumber = 1,
.AlternateSetting = 1, .AlternateSetting = 1,
.TotalEndpoints = 1, .TotalEndpoints = 1,
.Class = 0x01, .Class = 0x01,
.SubClass = 0x02, .SubClass = 0x02,
.Protocol = 0x00, .Protocol = 0x00,
.InterfaceStrIndex = NO_DESCRIPTOR .InterfaceStrIndex = NO_DESCRIPTOR
}, },
.Audio_StreamInterface_SPC = .Audio_StreamInterface_SPC =
{ {
.Header = {.Size = sizeof(USB_Audio_Interface_AS_t), .Type = DTYPE_AudioInterface}, .Header = {.Size = sizeof(USB_Audio_Interface_AS_t), .Type = DTYPE_AudioInterface},
.Subtype = DSUBTYPE_General, .Subtype = DSUBTYPE_General,
.TerminalLink = 0x02, .TerminalLink = 0x02,
.FrameDelay = 1, .FrameDelay = 1,
.AudioFormat = 0x0001 .AudioFormat = 0x0001
}, },
.Audio_AudioFormat = .Audio_AudioFormat =
{ {
.Header = {.Size = sizeof(USB_Audio_Format_t), .Type = DTYPE_AudioInterface}, .Header = {.Size = sizeof(USB_Audio_Format_t), .Type = DTYPE_AudioInterface},
.Subtype = DSUBTYPE_Format, .Subtype = DSUBTYPE_Format,
.FormatType = 0x01, .FormatType = 0x01,
.Channels = 0x01, .Channels = 0x01,
.SubFrameSize = 0x02, .SubFrameSize = 0x02,
.BitResolution = 16, .BitResolution = 16,
.SampleFrequencyType = AUDIO_TOTAL_SAMPLE_RATES, .SampleFrequencyType = AUDIO_TOTAL_SAMPLE_RATES,
.SampleFrequencies = {AUDIO_SAMPLE_FREQ(AUDIO_SAMPLE_FREQUENCY)} .SampleFrequencies = {AUDIO_SAMPLE_FREQ(AUDIO_SAMPLE_FREQUENCY)}
}, },
.Audio_StreamEndpoint = .Audio_StreamEndpoint =
{ {
.Endpoint = .Endpoint =
{ {
.Header = {.Size = sizeof(USB_Audio_StreamEndpoint_Std_t), .Type = DTYPE_Endpoint}, .Header = {.Size = sizeof(USB_Audio_StreamEndpoint_Std_t), .Type = DTYPE_Endpoint},
.EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_IN | AUDIO_STREAM_EPNUM), .EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_IN | AUDIO_STREAM_EPNUM),
.Attributes = (EP_TYPE_ISOCHRONOUS | ENDPOINT_ATTR_SYNC | ENDPOINT_USAGE_DATA), .Attributes = (EP_TYPE_ISOCHRONOUS | ENDPOINT_ATTR_SYNC | ENDPOINT_USAGE_DATA),
.EndpointSize = AUDIO_STREAM_EPSIZE, .EndpointSize = AUDIO_STREAM_EPSIZE,
.PollingIntervalMS = 1 .PollingIntervalMS = 1
}, },
.Refresh = 0, .Refresh = 0,
.SyncEndpointNumber = 0 .SyncEndpointNumber = 0
}, },
.Audio_StreamEndpoint_SPC = .Audio_StreamEndpoint_SPC =
{ {
.Header = {.Size = sizeof(USB_Audio_StreamEndpoint_Spc_t), .Type = DTYPE_AudioEndpoint}, .Header = {.Size = sizeof(USB_Audio_StreamEndpoint_Spc_t), .Type = DTYPE_AudioEndpoint},
.Subtype = DSUBTYPE_General, .Subtype = DSUBTYPE_General,
.Attributes = 0x00, .Attributes = 0x00,
.LockDelayUnits = 0x00, .LockDelayUnits = 0x00,
.LockDelay = 0x0000 .LockDelay = 0x0000
} }
}; };
/** Language descriptor structure. This descriptor, located in FLASH memory, is returned when the host requests /** Language descriptor structure. This descriptor, located in FLASH memory, is returned when the host requests
* the string descriptor with index 0 (the first index). It is actually an array of 16-bit integers, which indicate * the string descriptor with index 0 (the first index). It is actually an array of 16-bit integers, which indicate
* via the language ID table available at USB.org what languages the device supports for its string descriptors. * via the language ID table available at USB.org what languages the device supports for its string descriptors.
*/ */
USB_Descriptor_String_t PROGMEM LanguageString = USB_Descriptor_String_t PROGMEM LanguageString =
{ {
.Header = {.Size = USB_STRING_LEN(1), .Type = DTYPE_String}, .Header = {.Size = USB_STRING_LEN(1), .Type = DTYPE_String},
.UnicodeString = {LANGUAGE_ID_ENG} .UnicodeString = {LANGUAGE_ID_ENG}
}; };
/** Manufacturer descriptor string. This is a Unicode string containing the manufacturer's details in human readable /** Manufacturer descriptor string. This is a Unicode string containing the manufacturer's details in human readable
* form, and is read out upon request by the host when the appropriate string ID is requested, listed in the Device * form, and is read out upon request by the host when the appropriate string ID is requested, listed in the Device
* Descriptor. * Descriptor.
*/ */
USB_Descriptor_String_t PROGMEM ManufacturerString = USB_Descriptor_String_t PROGMEM ManufacturerString =
{ {
.Header = {.Size = USB_STRING_LEN(11), .Type = DTYPE_String}, .Header = {.Size = USB_STRING_LEN(11), .Type = DTYPE_String},
.UnicodeString = L"Dean Camera" .UnicodeString = L"Dean Camera"
}; };
/** Product descriptor string. This is a Unicode string containing the product's details in human readable form, /** Product descriptor string. This is a Unicode string containing the product's details in human readable form,
* and is read out upon request by the host when the appropriate string ID is requested, listed in the Device * and is read out upon request by the host when the appropriate string ID is requested, listed in the Device
* Descriptor. * Descriptor.
*/ */
USB_Descriptor_String_t PROGMEM ProductString = USB_Descriptor_String_t PROGMEM ProductString =
{ {
.Header = {.Size = USB_STRING_LEN(18), .Type = DTYPE_String}, .Header = {.Size = USB_STRING_LEN(18), .Type = DTYPE_String},
.UnicodeString = L"LUFA Audio In Demo" .UnicodeString = L"LUFA Audio In Demo"
}; };
/** This function is called by the library when in device mode, and must be overridden (see library "USB Descriptors" /** This function is called by the library when in device mode, and must be overridden (see library "USB Descriptors"
* documentation) by the application code so that the address and size of a requested descriptor can be given * documentation) by the application code so that the address and size of a requested descriptor can be given
* to the USB library. When the device receives a Get Descriptor request on the control endpoint, this function * to the USB library. When the device receives a Get Descriptor request on the control endpoint, this function
* is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the * is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the
* USB host. * USB host.
*/ */
uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, void** const DescriptorAddress) uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, void** const DescriptorAddress)
{ {
const uint8_t DescriptorType = (wValue >> 8); const uint8_t DescriptorType = (wValue >> 8);
const uint8_t DescriptorNumber = (wValue & 0xFF); const uint8_t DescriptorNumber = (wValue & 0xFF);
void* Address = NULL; void* Address = NULL;
uint16_t Size = NO_DESCRIPTOR; uint16_t Size = NO_DESCRIPTOR;
switch (DescriptorType) switch (DescriptorType)
{ {
case DTYPE_Device: case DTYPE_Device:
Address = (void*)&DeviceDescriptor; Address = (void*)&DeviceDescriptor;
Size = sizeof(USB_Descriptor_Device_t); Size = sizeof(USB_Descriptor_Device_t);
break; break;
case DTYPE_Configuration: case DTYPE_Configuration:
Address = (void*)&ConfigurationDescriptor; Address = (void*)&ConfigurationDescriptor;
Size = sizeof(USB_Descriptor_Configuration_t); Size = sizeof(USB_Descriptor_Configuration_t);
break; break;
case DTYPE_String: case DTYPE_String:
switch (DescriptorNumber) switch (DescriptorNumber)
{ {
case 0x00: case 0x00:
Address = (void*)&LanguageString; Address = (void*)&LanguageString;
Size = pgm_read_byte(&LanguageString.Header.Size); Size = pgm_read_byte(&LanguageString.Header.Size);
break; break;
case 0x01: case 0x01:
Address = (void*)&ManufacturerString; Address = (void*)&ManufacturerString;
Size = pgm_read_byte(&ManufacturerString.Header.Size); Size = pgm_read_byte(&ManufacturerString.Header.Size);
break; break;
case 0x02: case 0x02:
Address = (void*)&ProductString; Address = (void*)&ProductString;
Size = pgm_read_byte(&ProductString.Header.Size); Size = pgm_read_byte(&ProductString.Header.Size);
break; break;
} }
break; break;
} }
*DescriptorAddress = Address; *DescriptorAddress = Address;
return Size; return Size;
} }

View file

@ -1,82 +1,82 @@
/* /*
LUFA Library LUFA Library
Copyright (C) Dean Camera, 2010. Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com www.fourwalledcubicle.com
*/ */
/* /*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com) Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the advertising or publicity pertaining to distribution of the
software without specific, written prior permission. software without specific, written prior permission.
The author disclaim all warranties with regard to this The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action, in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of arising out of or in connection with the use or performance of
this software. this software.
*/ */
/** \file /** \file
* *
* Header file for Descriptors.c. * Header file for Descriptors.c.
*/ */
#ifndef _DESCRIPTORS_H_ #ifndef _DESCRIPTORS_H_
#define _DESCRIPTORS_H_ #define _DESCRIPTORS_H_
/* Includes: */ /* Includes: */
#include <LUFA/Drivers/USB/USB.h> #include <LUFA/Drivers/USB/USB.h>
#include <LUFA/Drivers/USB/Class/Audio.h> #include <LUFA/Drivers/USB/Class/Audio.h>
#include <avr/pgmspace.h> #include <avr/pgmspace.h>
/* Macros: */ /* Macros: */
/** Endpoint number of the Audio isochronous streaming data endpoint. */ /** Endpoint number of the Audio isochronous streaming data endpoint. */
#define AUDIO_STREAM_EPNUM 1 #define AUDIO_STREAM_EPNUM 1
/** Endpoint size in bytes of the Audio isochronous streaming data endpoint. The Windows audio stack requires /** Endpoint size in bytes of the Audio isochronous streaming data endpoint. The Windows audio stack requires
* at least 192 bytes for correct output, thus the smaller 128 byte maximum endpoint size on some of the smaller * at least 192 bytes for correct output, thus the smaller 128 byte maximum endpoint size on some of the smaller
* USB AVR models will result in unavoidable distorted output. * USB AVR models will result in unavoidable distorted output.
*/ */
#define AUDIO_STREAM_EPSIZE ENDPOINT_MAX_SIZE(AUDIO_STREAM_EPNUM) #define AUDIO_STREAM_EPSIZE ENDPOINT_MAX_SIZE(AUDIO_STREAM_EPNUM)
/** Sample frequency of the data being transmitted through the streaming endpoint. */ /** Sample frequency of the data being transmitted through the streaming endpoint. */
#define AUDIO_SAMPLE_FREQUENCY 48000 #define AUDIO_SAMPLE_FREQUENCY 48000
/* Type Defines: */ /* Type Defines: */
/** Type define for the device configuration descriptor structure. This must be defined in the /** Type define for the device configuration descriptor structure. This must be defined in the
* application code, as the configuration descriptor contains several sub-descriptors which * application code, as the configuration descriptor contains several sub-descriptors which
* vary between devices, and which describe the device's usage to the host. * vary between devices, and which describe the device's usage to the host.
*/ */
typedef struct typedef struct
{ {
USB_Descriptor_Configuration_Header_t Config; USB_Descriptor_Configuration_Header_t Config;
USB_Descriptor_Interface_t Audio_ControlInterface; USB_Descriptor_Interface_t Audio_ControlInterface;
USB_Audio_Interface_AC_t Audio_ControlInterface_SPC; USB_Audio_Interface_AC_t Audio_ControlInterface_SPC;
USB_Audio_InputTerminal_t Audio_InputTerminal; USB_Audio_InputTerminal_t Audio_InputTerminal;
USB_Audio_OutputTerminal_t Audio_OutputTerminal; USB_Audio_OutputTerminal_t Audio_OutputTerminal;
USB_Descriptor_Interface_t Audio_StreamInterface_Alt0; USB_Descriptor_Interface_t Audio_StreamInterface_Alt0;
USB_Descriptor_Interface_t Audio_StreamInterface_Alt1; USB_Descriptor_Interface_t Audio_StreamInterface_Alt1;
USB_Audio_Interface_AS_t Audio_StreamInterface_SPC; USB_Audio_Interface_AS_t Audio_StreamInterface_SPC;
USB_Audio_Format_t Audio_AudioFormat; USB_Audio_Format_t Audio_AudioFormat;
USB_Audio_StreamEndpoint_Std_t Audio_StreamEndpoint; USB_Audio_StreamEndpoint_Std_t Audio_StreamEndpoint;
USB_Audio_StreamEndpoint_Spc_t Audio_StreamEndpoint_SPC; USB_Audio_StreamEndpoint_Spc_t Audio_StreamEndpoint_SPC;
} USB_Descriptor_Configuration_t; } USB_Descriptor_Configuration_t;
/* Function Prototypes: */ /* Function Prototypes: */
uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, void** const DescriptorAddress) uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, void** const DescriptorAddress)
ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3); ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3);
#endif #endif

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,201 +1,201 @@
/* /*
LUFA Library LUFA Library
Copyright (C) Dean Camera, 2010. Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com www.fourwalledcubicle.com
*/ */
/* /*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com) Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the advertising or publicity pertaining to distribution of the
software without specific, written prior permission. software without specific, written prior permission.
The author disclaim all warranties with regard to this The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action, in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of arising out of or in connection with the use or performance of
this software. this software.
*/ */
/** \file /** \file
* *
* Main source file for the AudioOutput demo. This file contains the main tasks of * Main source file for the AudioOutput demo. This file contains the main tasks of
* the demo and is responsible for the initial application hardware configuration. * the demo and is responsible for the initial application hardware configuration.
*/ */
#include "AudioOutput.h" #include "AudioOutput.h"
/** LUFA Audio Class driver interface configuration and state information. This structure is /** LUFA Audio Class driver interface configuration and state information. This structure is
* passed to all Audio Class driver functions, so that multiple instances of the same class * passed to all Audio Class driver functions, so that multiple instances of the same class
* within a device can be differentiated from one another. * within a device can be differentiated from one another.
*/ */
USB_ClassInfo_Audio_Device_t Speaker_Audio_Interface = USB_ClassInfo_Audio_Device_t Speaker_Audio_Interface =
{ {
.Config = .Config =
{ {
.StreamingInterfaceNumber = 1, .StreamingInterfaceNumber = 1,
.DataOUTEndpointNumber = AUDIO_STREAM_EPNUM, .DataOUTEndpointNumber = AUDIO_STREAM_EPNUM,
.DataOUTEndpointSize = AUDIO_STREAM_EPSIZE, .DataOUTEndpointSize = AUDIO_STREAM_EPSIZE,
}, },
}; };
/** Main program entry point. This routine contains the overall program flow, including initial /** Main program entry point. This routine contains the overall program flow, including initial
* setup of all components and the main program loop. * setup of all components and the main program loop.
*/ */
int main(void) int main(void)
{ {
SetupHardware(); SetupHardware();
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY); LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
sei(); sei();
for (;;) for (;;)
{ {
ProcessNextSample(); ProcessNextSample();
Audio_Device_USBTask(&Speaker_Audio_Interface); Audio_Device_USBTask(&Speaker_Audio_Interface);
USB_USBTask(); USB_USBTask();
} }
} }
/** Configures the board hardware and chip peripherals for the demo's functionality. */ /** Configures the board hardware and chip peripherals for the demo's functionality. */
void SetupHardware(void) void SetupHardware(void)
{ {
/* Disable watchdog if enabled by bootloader/fuses */ /* Disable watchdog if enabled by bootloader/fuses */
MCUSR &= ~(1 << WDRF); MCUSR &= ~(1 << WDRF);
wdt_disable(); wdt_disable();
/* Disable clock division */ /* Disable clock division */
clock_prescale_set(clock_div_1); clock_prescale_set(clock_div_1);
/* Hardware Initialization */ /* Hardware Initialization */
LEDs_Init(); LEDs_Init();
USB_Init(); USB_Init();
} }
/** Processes the next audio sample by reading the last ADC conversion and writing it to the audio /** Processes the next audio sample by reading the last ADC conversion and writing it to the audio
* interface, each time the sample reload timer period elapses to give a constant sample rate. * interface, each time the sample reload timer period elapses to give a constant sample rate.
*/ */
void ProcessNextSample(void) void ProcessNextSample(void)
{ {
/* Check if the sample reload timer period has elapsed, and that the USB bus is ready for a new sample */ /* Check if the sample reload timer period has elapsed, and that the USB bus is ready for a new sample */
if ((TIFR0 & (1 << OCF0A)) && Audio_Device_IsSampleReceived(&Speaker_Audio_Interface)) if ((TIFR0 & (1 << OCF0A)) && Audio_Device_IsSampleReceived(&Speaker_Audio_Interface))
{ {
/* Clear the sample reload timer */ /* Clear the sample reload timer */
TIFR0 |= (1 << OCF0A); TIFR0 |= (1 << OCF0A);
/* Retrieve the signed 16-bit left and right audio samples, convert to 8-bit */ /* Retrieve the signed 16-bit left and right audio samples, convert to 8-bit */
int8_t LeftSample_8Bit = (Audio_Device_ReadSample16(&Speaker_Audio_Interface) >> 8); int8_t LeftSample_8Bit = (Audio_Device_ReadSample16(&Speaker_Audio_Interface) >> 8);
int8_t RightSample_8Bit = (Audio_Device_ReadSample16(&Speaker_Audio_Interface) >> 8); int8_t RightSample_8Bit = (Audio_Device_ReadSample16(&Speaker_Audio_Interface) >> 8);
/* Mix the two channels together to produce a mono, 8-bit sample */ /* Mix the two channels together to produce a mono, 8-bit sample */
int8_t MixedSample_8Bit = (((int16_t)LeftSample_8Bit + (int16_t)RightSample_8Bit) >> 1); int8_t MixedSample_8Bit = (((int16_t)LeftSample_8Bit + (int16_t)RightSample_8Bit) >> 1);
#if defined(AUDIO_OUT_MONO) #if defined(AUDIO_OUT_MONO)
/* Load the sample into the PWM timer channel */ /* Load the sample into the PWM timer channel */
OCR3A = (MixedSample_8Bit ^ (1 << 7)); OCR3A = (MixedSample_8Bit ^ (1 << 7));
#elif defined(AUDIO_OUT_STEREO) #elif defined(AUDIO_OUT_STEREO)
/* Load the dual 8-bit samples into the PWM timer channels */ /* Load the dual 8-bit samples into the PWM timer channels */
OCR3A = (LeftSample_8Bit ^ (1 << 7)); OCR3A = (LeftSample_8Bit ^ (1 << 7));
OCR3B = (RightSample_8Bit ^ (1 << 7)); OCR3B = (RightSample_8Bit ^ (1 << 7));
#elif defined(AUDIO_OUT_PORTC) #elif defined(AUDIO_OUT_PORTC)
/* Load the 8-bit mixed sample into PORTC */ /* Load the 8-bit mixed sample into PORTC */
PORTC = MixedSample_8Bit; PORTC = MixedSample_8Bit;
#endif #endif
uint8_t LEDMask = LEDS_NO_LEDS; uint8_t LEDMask = LEDS_NO_LEDS;
/* Turn on LEDs as the sample amplitude increases */ /* Turn on LEDs as the sample amplitude increases */
if (MixedSample_8Bit > 16) if (MixedSample_8Bit > 16)
LEDMask = (LEDS_LED1 | LEDS_LED2 | LEDS_LED3 | LEDS_LED4); LEDMask = (LEDS_LED1 | LEDS_LED2 | LEDS_LED3 | LEDS_LED4);
else if (MixedSample_8Bit > 8) else if (MixedSample_8Bit > 8)
LEDMask = (LEDS_LED1 | LEDS_LED2 | LEDS_LED3); LEDMask = (LEDS_LED1 | LEDS_LED2 | LEDS_LED3);
else if (MixedSample_8Bit > 4) else if (MixedSample_8Bit > 4)
LEDMask = (LEDS_LED1 | LEDS_LED2); LEDMask = (LEDS_LED1 | LEDS_LED2);
else if (MixedSample_8Bit > 2) else if (MixedSample_8Bit > 2)
LEDMask = (LEDS_LED1); LEDMask = (LEDS_LED1);
LEDs_SetAllLEDs(LEDMask); LEDs_SetAllLEDs(LEDMask);
} }
} }
/** Event handler for the library USB Connection event. */ /** Event handler for the library USB Connection event. */
void EVENT_USB_Device_Connect(void) void EVENT_USB_Device_Connect(void)
{ {
LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING); LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
/* Sample reload timer initialization */ /* Sample reload timer initialization */
OCR0A = (F_CPU / 8 / AUDIO_SAMPLE_FREQUENCY) - 1; OCR0A = (F_CPU / 8 / AUDIO_SAMPLE_FREQUENCY) - 1;
TCCR0A = (1 << WGM01); // CTC mode TCCR0A = (1 << WGM01); // CTC mode
TCCR0B = (1 << CS01); // Fcpu/8 speed TCCR0B = (1 << CS01); // Fcpu/8 speed
#if defined(AUDIO_OUT_MONO) #if defined(AUDIO_OUT_MONO)
/* Set speaker as output */ /* Set speaker as output */
DDRC |= (1 << 6); DDRC |= (1 << 6);
#elif defined(AUDIO_OUT_STEREO) #elif defined(AUDIO_OUT_STEREO)
/* Set speakers as outputs */ /* Set speakers as outputs */
DDRC |= ((1 << 6) | (1 << 5)); DDRC |= ((1 << 6) | (1 << 5));
#elif defined(AUDIO_OUT_PORTC) #elif defined(AUDIO_OUT_PORTC)
/* Set PORTC as outputs */ /* Set PORTC as outputs */
DDRC |= 0xFF; DDRC |= 0xFF;
#endif #endif
#if (defined(AUDIO_OUT_MONO) || defined(AUDIO_OUT_STEREO)) #if (defined(AUDIO_OUT_MONO) || defined(AUDIO_OUT_STEREO))
/* PWM speaker timer initialization */ /* PWM speaker timer initialization */
TCCR3A = ((1 << WGM30) | (1 << COM3A1) | (1 << COM3A0) TCCR3A = ((1 << WGM30) | (1 << COM3A1) | (1 << COM3A0)
| (1 << COM3B1) | (1 << COM3B0)); // Set on match, clear on TOP | (1 << COM3B1) | (1 << COM3B0)); // Set on match, clear on TOP
TCCR3B = ((1 << WGM32) | (1 << CS30)); // Fast 8-Bit PWM, Fcpu speed TCCR3B = ((1 << WGM32) | (1 << CS30)); // Fast 8-Bit PWM, Fcpu speed
#endif #endif
} }
/** Event handler for the library USB Disconnection event. */ /** Event handler for the library USB Disconnection event. */
void EVENT_USB_Device_Disconnect(void) void EVENT_USB_Device_Disconnect(void)
{ {
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY); LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
/* Stop the sample reload timer */ /* Stop the sample reload timer */
TCCR0B = 0; TCCR0B = 0;
#if (defined(AUDIO_OUT_MONO) || defined(AUDIO_OUT_STEREO)) #if (defined(AUDIO_OUT_MONO) || defined(AUDIO_OUT_STEREO))
/* Stop the PWM generation timer */ /* Stop the PWM generation timer */
TCCR3B = 0; TCCR3B = 0;
#endif #endif
#if defined(AUDIO_OUT_MONO) #if defined(AUDIO_OUT_MONO)
/* Set speaker as input to reduce current draw */ /* Set speaker as input to reduce current draw */
DDRC &= ~(1 << 6); DDRC &= ~(1 << 6);
#elif defined(AUDIO_OUT_STEREO) #elif defined(AUDIO_OUT_STEREO)
/* Set speakers as inputs to reduce current draw */ /* Set speakers as inputs to reduce current draw */
DDRC &= ~((1 << 6) | (1 << 5)); DDRC &= ~((1 << 6) | (1 << 5));
#elif defined(AUDIO_OUT_PORTC) #elif defined(AUDIO_OUT_PORTC)
/* Set PORTC low */ /* Set PORTC low */
PORTC = 0x00; PORTC = 0x00;
#endif #endif
} }
/** Event handler for the library USB Configuration Changed event. */ /** Event handler for the library USB Configuration Changed event. */
void EVENT_USB_Device_ConfigurationChanged(void) void EVENT_USB_Device_ConfigurationChanged(void)
{ {
LEDs_SetAllLEDs(LEDMASK_USB_READY); LEDs_SetAllLEDs(LEDMASK_USB_READY);
if (!(Audio_Device_ConfigureEndpoints(&Speaker_Audio_Interface))) if (!(Audio_Device_ConfigureEndpoints(&Speaker_Audio_Interface)))
LEDs_SetAllLEDs(LEDMASK_USB_ERROR); LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
} }
/** Event handler for the library USB Unhandled Control Request event. */ /** Event handler for the library USB Unhandled Control Request event. */
void EVENT_USB_Device_UnhandledControlRequest(void) void EVENT_USB_Device_UnhandledControlRequest(void)
{ {
Audio_Device_ProcessControlRequest(&Speaker_Audio_Interface); Audio_Device_ProcessControlRequest(&Speaker_Audio_Interface);
} }

View file

@ -1,75 +1,75 @@
/* /*
LUFA Library LUFA Library
Copyright (C) Dean Camera, 2010. Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com www.fourwalledcubicle.com
*/ */
/* /*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com) Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the advertising or publicity pertaining to distribution of the
software without specific, written prior permission. software without specific, written prior permission.
The author disclaim all warranties with regard to this The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action, in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of arising out of or in connection with the use or performance of
this software. this software.
*/ */
/** \file /** \file
* *
* Header file for AudioOutput.c. * Header file for AudioOutput.c.
*/ */
#ifndef _AUDIO_OUTPUT_H_ #ifndef _AUDIO_OUTPUT_H_
#define _AUDIO_OUTPUT_H_ #define _AUDIO_OUTPUT_H_
/* Includes: */ /* Includes: */
#include <avr/io.h> #include <avr/io.h>
#include <avr/wdt.h> #include <avr/wdt.h>
#include <avr/power.h> #include <avr/power.h>
#include <avr/interrupt.h> #include <avr/interrupt.h>
#include <stdlib.h> #include <stdlib.h>
#include "Descriptors.h" #include "Descriptors.h"
#include <LUFA/Version.h> #include <LUFA/Version.h>
#include <LUFA/Drivers/Board/LEDs.h> #include <LUFA/Drivers/Board/LEDs.h>
#include <LUFA/Drivers/USB/USB.h> #include <LUFA/Drivers/USB/USB.h>
#include <LUFA/Drivers/USB/Class/Audio.h> #include <LUFA/Drivers/USB/Class/Audio.h>
/* Macros: */ /* Macros: */
/** LED mask for the library LED driver, to indicate that the USB interface is not ready. */ /** LED mask for the library LED driver, to indicate that the USB interface is not ready. */
#define LEDMASK_USB_NOTREADY LEDS_LED1 #define LEDMASK_USB_NOTREADY LEDS_LED1
/** LED mask for the library LED driver, to indicate that the USB interface is enumerating. */ /** LED mask for the library LED driver, to indicate that the USB interface is enumerating. */
#define LEDMASK_USB_ENUMERATING (LEDS_LED2 | LEDS_LED3) #define LEDMASK_USB_ENUMERATING (LEDS_LED2 | LEDS_LED3)
/** LED mask for the library LED driver, to indicate that the USB interface is ready. */ /** LED mask for the library LED driver, to indicate that the USB interface is ready. */
#define LEDMASK_USB_READY (LEDS_LED2 | LEDS_LED4) #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. */ /** 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) #define LEDMASK_USB_ERROR (LEDS_LED1 | LEDS_LED3)
/* Function Prototypes: */ /* Function Prototypes: */
void SetupHardware(void); void SetupHardware(void);
void ProcessNextSample(void); void ProcessNextSample(void);
void EVENT_USB_Device_Connect(void); void EVENT_USB_Device_Connect(void);
void EVENT_USB_Device_Disconnect(void); void EVENT_USB_Device_Disconnect(void);
void EVENT_USB_Device_ConfigurationChanged(void); void EVENT_USB_Device_ConfigurationChanged(void);
void EVENT_USB_Device_UnhandledControlRequest(void); void EVENT_USB_Device_UnhandledControlRequest(void);
#endif #endif

View file

@ -1,96 +1,96 @@
/** \file /** \file
* *
* This file contains special DoxyGen information for the generation of the main page and other special * 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. * documentation pages. It is not a project source file.
*/ */
/** \mainpage Audio Output Device Demo /** \mainpage Audio Output Device Demo
* *
* \section SSec_Compat Demo Compatibility: * \section SSec_Compat Demo Compatibility:
* *
* The following list indicates what microcontrollers are compatible with this demo. * The following list indicates what microcontrollers are compatible with this demo.
* *
* - Series 7 USB AVRs * - Series 7 USB AVRs
* - Series 6 USB AVRs * - Series 6 USB AVRs
* - Series 4 USB AVRs * - Series 4 USB AVRs
* *
* \section SSec_Info USB Information: * \section SSec_Info USB Information:
* *
* The following table gives a rundown of the USB utilization of this demo. * The following table gives a rundown of the USB utilization of this demo.
* *
* <table> * <table>
* <tr> * <tr>
* <td><b>USB Mode:</b></td> * <td><b>USB Mode:</b></td>
* <td>Device</td> * <td>Device</td>
* </tr> * </tr>
* <tr> * <tr>
* <td><b>USB Class:</b></td> * <td><b>USB Class:</b></td>
* <td>Audio Class</td> * <td>Audio Class</td>
* </tr> * </tr>
* <tr> * <tr>
* <td><b>USB Subclass:</b></td> * <td><b>USB Subclass:</b></td>
* <td>Standard Audio Device</td> * <td>Standard Audio Device</td>
* </tr> * </tr>
* <tr> * <tr>
* <td><b>Relevant Standards:</b></td> * <td><b>Relevant Standards:</b></td>
* <td>USBIF Audio Class Specification \n * <td>USBIF Audio Class Specification \n
* USBIF Audio Class Terminal Types Specification \n * USBIF Audio Class Terminal Types Specification \n
* USBIF Audio Data Formats Specification</td> * USBIF Audio Data Formats Specification</td>
* </tr> * </tr>
* <tr> * <tr>
* <td><b>Usable Speeds:</b></td> * <td><b>Usable Speeds:</b></td>
* <td>Full Speed Mode</td> * <td>Full Speed Mode</td>
* </tr> * </tr>
* </table> * </table>
* *
* \section SSec_Description Project Description: * \section SSec_Description Project Description:
* *
* Audio demonstration application. This gives a simple reference * Audio demonstration application. This gives a simple reference
* application for implementing a USB Audio Output device using the * application for implementing a USB Audio Output device using the
* basic USB Audio drivers in all modern OSes (i.e. no special drivers * basic USB Audio drivers in all modern OSes (i.e. no special drivers
* required). * required).
* *
* On start-up the system will automatically enumerate and function * On start-up the system will automatically enumerate and function
* as a USB speaker. Outgoing audio will output in 8-bit PWM onto * as a USB speaker. Outgoing audio will output in 8-bit PWM onto
* the timer 3 output compare channel A for AUDIO_OUT_MONO mode, on * the timer 3 output compare channel A for AUDIO_OUT_MONO mode, on
* timer 3 channels A and B for AUDIO_OUT_STEREO and on PORTC as a signed * timer 3 channels A and B for AUDIO_OUT_STEREO and on PORTC as a signed
* mono sample for AUDIO_OUT_PORTC. Audio output will also be indicated on * mono sample for AUDIO_OUT_PORTC. Audio output will also be indicated on
* the board LEDs in all modes. Decouple audio outputs with a capacitor and * the board LEDs in all modes. Decouple audio outputs with a capacitor and
* attach to a speaker to hear the audio. * attach to a speaker to hear the audio.
* *
* Under Windows, if a driver request dialogue pops up, select the option * Under Windows, if a driver request dialogue pops up, select the option
* to automatically install the appropriate drivers. * to automatically install the appropriate drivers.
* *
* \section SSec_Options Project Options * \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. * The following defines can be found in this demo, which can control the demo behaviour when defined, or changed in value.
* *
* <table> * <table>
* <tr> * <tr>
* <td><b>Define Name:</b></td> * <td><b>Define Name:</b></td>
* <td><b>Location:</b></td> * <td><b>Location:</b></td>
* <td><b>Description:</b></td> * <td><b>Description:</b></td>
* </tr> * </tr>
* <tr> * <tr>
* <td>AUDIO_OUT_STEREO</td> * <td>AUDIO_OUT_STEREO</td>
* <td>Makefile CDEFS</td> * <td>Makefile CDEFS</td>
* <td>When defined, this outputs the audio samples in stereo to the timer output pins of the microcontroller.</td> * <td>When defined, this outputs the audio samples in stereo to the timer output pins of the microcontroller.</td>
* </tr> * </tr>
* <tr> * <tr>
* <td>AUDIO_OUT_MONO</td> * <td>AUDIO_OUT_MONO</td>
* <td>Makefile CDEFS</td> * <td>Makefile CDEFS</td>
* <td>When defined, this outputs the audio samples in mono to the timer output pin of the microcontroller.</td> * <td>When defined, this outputs the audio samples in mono to the timer output pin of the microcontroller.</td>
* </tr> * </tr>
* <tr> * <tr>
* <td>AUDIO_OUT_PORTC</td> * <td>AUDIO_OUT_PORTC</td>
* <td>Makefile CDEFS</td> * <td>Makefile CDEFS</td>
* <td>When defined, this outputs the audio samples in mono to port C of the microcontroller, for connection to an * <td>When defined, this outputs the audio samples in mono to port C of the microcontroller, for connection to an
* external DAC.</td> * external DAC.</td>
* </tr> * </tr>
* <tr> * <tr>
* <td>AUDIO_SAMPLE_FREQUENCY</td> * <td>AUDIO_SAMPLE_FREQUENCY</td>
* <td>Descriptors.h</td> * <td>Descriptors.h</td>
* <td>Gives the audio sample rate per channel for the audio stream, in Hz.</td> * <td>Gives the audio sample rate per channel for the audio stream, in Hz.</td>
* </tr> * </tr>
* </table> * </table>
*/ */

View file

@ -1,314 +1,314 @@
/* /*
LUFA Library LUFA Library
Copyright (C) Dean Camera, 2010. Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com www.fourwalledcubicle.com
*/ */
/* /*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com) Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the advertising or publicity pertaining to distribution of the
software without specific, written prior permission. software without specific, written prior permission.
The author disclaim all warranties with regard to this The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action, in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of arising out of or in connection with the use or performance of
this software. this software.
*/ */
/** \file /** \file
* *
* USB Device Descriptors, for library use when in USB device mode. Descriptors are special * USB Device Descriptors, for library use when in USB device mode. Descriptors are special
* computer-readable structures which the host requests upon device enumeration, to determine * computer-readable structures which the host requests upon device enumeration, to determine
* the device's capabilities and functions. * the device's capabilities and functions.
*/ */
#include "Descriptors.h" #include "Descriptors.h"
/** Device descriptor structure. This descriptor, located in FLASH memory, describes the overall /** Device descriptor structure. This descriptor, located in FLASH memory, describes the overall
* device characteristics, including the supported USB version, control endpoint size and the * device characteristics, including the supported USB version, control endpoint size and the
* number of device configurations. The descriptor is read out by the USB host when the enumeration * number of device configurations. The descriptor is read out by the USB host when the enumeration
* process begins. * process begins.
*/ */
USB_Descriptor_Device_t PROGMEM DeviceDescriptor = USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
{ {
.Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device}, .Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device},
.USBSpecification = VERSION_BCD(02.00), .USBSpecification = VERSION_BCD(02.00),
.Class = 0x00, .Class = 0x00,
.SubClass = 0x00, .SubClass = 0x00,
.Protocol = 0x00, .Protocol = 0x00,
.Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE, .Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE,
.VendorID = 0x03EB, .VendorID = 0x03EB,
.ProductID = 0x2046, .ProductID = 0x2046,
.ReleaseNumber = 0x0000, .ReleaseNumber = 0x0000,
.ManufacturerStrIndex = 0x01, .ManufacturerStrIndex = 0x01,
.ProductStrIndex = 0x02, .ProductStrIndex = 0x02,
.SerialNumStrIndex = NO_DESCRIPTOR, .SerialNumStrIndex = NO_DESCRIPTOR,
.NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS .NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS
}; };
/** Configuration descriptor structure. This descriptor, located in FLASH memory, describes the usage /** Configuration descriptor structure. This descriptor, located in FLASH memory, describes the usage
* of the device in one of its supported configurations, including information about any device interfaces * of the device in one of its supported configurations, including information about any device interfaces
* and endpoints. The descriptor is read out by the USB host during the enumeration process when selecting * and endpoints. The descriptor is read out by the USB host during the enumeration process when selecting
* a configuration so that the host may correctly communicate with the USB device. * a configuration so that the host may correctly communicate with the USB device.
*/ */
USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor = USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
{ {
.Config = .Config =
{ {
.Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration}, .Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration},
.TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t), .TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t),
.TotalInterfaces = 2, .TotalInterfaces = 2,
.ConfigurationNumber = 1, .ConfigurationNumber = 1,
.ConfigurationStrIndex = NO_DESCRIPTOR, .ConfigurationStrIndex = NO_DESCRIPTOR,
.ConfigAttributes = (USB_CONFIG_ATTR_BUSPOWERED | USB_CONFIG_ATTR_SELFPOWERED), .ConfigAttributes = (USB_CONFIG_ATTR_BUSPOWERED | USB_CONFIG_ATTR_SELFPOWERED),
.MaxPowerConsumption = USB_CONFIG_POWER_MA(100) .MaxPowerConsumption = USB_CONFIG_POWER_MA(100)
}, },
.Audio_ControlInterface = .Audio_ControlInterface =
{ {
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface}, .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
.InterfaceNumber = 0, .InterfaceNumber = 0,
.AlternateSetting = 0, .AlternateSetting = 0,
.TotalEndpoints = 0, .TotalEndpoints = 0,
.Class = 0x01, .Class = 0x01,
.SubClass = 0x01, .SubClass = 0x01,
.Protocol = 0x00, .Protocol = 0x00,
.InterfaceStrIndex = NO_DESCRIPTOR .InterfaceStrIndex = NO_DESCRIPTOR
}, },
.Audio_ControlInterface_SPC = .Audio_ControlInterface_SPC =
{ {
.Header = {.Size = sizeof(USB_Audio_Interface_AC_t), .Type = DTYPE_AudioInterface}, .Header = {.Size = sizeof(USB_Audio_Interface_AC_t), .Type = DTYPE_AudioInterface},
.Subtype = DSUBTYPE_Header, .Subtype = DSUBTYPE_Header,
.ACSpecification = VERSION_BCD(01.00), .ACSpecification = VERSION_BCD(01.00),
.TotalLength = (sizeof(USB_Audio_Interface_AC_t) + .TotalLength = (sizeof(USB_Audio_Interface_AC_t) +
sizeof(USB_Audio_InputTerminal_t) + sizeof(USB_Audio_InputTerminal_t) +
sizeof(USB_Audio_OutputTerminal_t)), sizeof(USB_Audio_OutputTerminal_t)),
.InCollection = 1, .InCollection = 1,
.InterfaceNumbers = {1}, .InterfaceNumbers = {1},
}, },
.Audio_InputTerminal = .Audio_InputTerminal =
{ {
.Header = {.Size = sizeof(USB_Audio_InputTerminal_t), .Type = DTYPE_AudioInterface}, .Header = {.Size = sizeof(USB_Audio_InputTerminal_t), .Type = DTYPE_AudioInterface},
.Subtype = DSUBTYPE_InputTerminal, .Subtype = DSUBTYPE_InputTerminal,
.TerminalID = 0x01, .TerminalID = 0x01,
.TerminalType = TERMINAL_STREAMING, .TerminalType = TERMINAL_STREAMING,
.AssociatedOutputTerminal = 0x00, .AssociatedOutputTerminal = 0x00,
.TotalChannels = 2, .TotalChannels = 2,
.ChannelConfig = (CHANNEL_LEFT_FRONT | CHANNEL_RIGHT_FRONT), .ChannelConfig = (CHANNEL_LEFT_FRONT | CHANNEL_RIGHT_FRONT),
.ChannelStrIndex = NO_DESCRIPTOR, .ChannelStrIndex = NO_DESCRIPTOR,
.TerminalStrIndex = NO_DESCRIPTOR .TerminalStrIndex = NO_DESCRIPTOR
}, },
.Audio_OutputTerminal = .Audio_OutputTerminal =
{ {
.Header = {.Size = sizeof(USB_Audio_OutputTerminal_t), .Type = DTYPE_AudioInterface}, .Header = {.Size = sizeof(USB_Audio_OutputTerminal_t), .Type = DTYPE_AudioInterface},
.Subtype = DSUBTYPE_OutputTerminal, .Subtype = DSUBTYPE_OutputTerminal,
.TerminalID = 0x02, .TerminalID = 0x02,
.TerminalType = TERMINAL_OUT_SPEAKER, .TerminalType = TERMINAL_OUT_SPEAKER,
.AssociatedInputTerminal = 0x00, .AssociatedInputTerminal = 0x00,
.SourceID = 0x01, .SourceID = 0x01,
.TerminalStrIndex = NO_DESCRIPTOR .TerminalStrIndex = NO_DESCRIPTOR
}, },
.Audio_StreamInterface_Alt0 = .Audio_StreamInterface_Alt0 =
{ {
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface}, .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
.InterfaceNumber = 1, .InterfaceNumber = 1,
.AlternateSetting = 0, .AlternateSetting = 0,
.TotalEndpoints = 0, .TotalEndpoints = 0,
.Class = 0x01, .Class = 0x01,
.SubClass = 0x02, .SubClass = 0x02,
.Protocol = 0x00, .Protocol = 0x00,
.InterfaceStrIndex = NO_DESCRIPTOR .InterfaceStrIndex = NO_DESCRIPTOR
}, },
.Audio_StreamInterface_Alt1 = .Audio_StreamInterface_Alt1 =
{ {
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface}, .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
.InterfaceNumber = 1, .InterfaceNumber = 1,
.AlternateSetting = 1, .AlternateSetting = 1,
.TotalEndpoints = 1, .TotalEndpoints = 1,
.Class = 0x01, .Class = 0x01,
.SubClass = 0x02, .SubClass = 0x02,
.Protocol = 0x00, .Protocol = 0x00,
.InterfaceStrIndex = NO_DESCRIPTOR .InterfaceStrIndex = NO_DESCRIPTOR
}, },
.Audio_StreamInterface_SPC = .Audio_StreamInterface_SPC =
{ {
.Header = {.Size = sizeof(USB_Audio_Interface_AS_t), .Type = DTYPE_AudioInterface}, .Header = {.Size = sizeof(USB_Audio_Interface_AS_t), .Type = DTYPE_AudioInterface},
.Subtype = DSUBTYPE_General, .Subtype = DSUBTYPE_General,
.TerminalLink = 0x01, .TerminalLink = 0x01,
.FrameDelay = 1, .FrameDelay = 1,
.AudioFormat = 0x0001 .AudioFormat = 0x0001
}, },
.Audio_AudioFormat = .Audio_AudioFormat =
{ {
.Header = {.Size = sizeof(USB_Audio_Format_t), .Type = DTYPE_AudioInterface}, .Header = {.Size = sizeof(USB_Audio_Format_t), .Type = DTYPE_AudioInterface},
.Subtype = DSUBTYPE_Format, .Subtype = DSUBTYPE_Format,
.FormatType = 0x01, .FormatType = 0x01,
.Channels = 0x02, .Channels = 0x02,
.SubFrameSize = 0x02, .SubFrameSize = 0x02,
.BitResolution = 16, .BitResolution = 16,
.SampleFrequencyType = AUDIO_TOTAL_SAMPLE_RATES, .SampleFrequencyType = AUDIO_TOTAL_SAMPLE_RATES,
.SampleFrequencies = {AUDIO_SAMPLE_FREQ(AUDIO_SAMPLE_FREQUENCY)} .SampleFrequencies = {AUDIO_SAMPLE_FREQ(AUDIO_SAMPLE_FREQUENCY)}
}, },
.Audio_StreamEndpoint = .Audio_StreamEndpoint =
{ {
.Endpoint = .Endpoint =
{ {
.Header = {.Size = sizeof(USB_Audio_StreamEndpoint_Std_t), .Type = DTYPE_Endpoint}, .Header = {.Size = sizeof(USB_Audio_StreamEndpoint_Std_t), .Type = DTYPE_Endpoint},
.EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_OUT | AUDIO_STREAM_EPNUM), .EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_OUT | AUDIO_STREAM_EPNUM),
.Attributes = (EP_TYPE_ISOCHRONOUS | ENDPOINT_ATTR_SYNC | ENDPOINT_USAGE_DATA), .Attributes = (EP_TYPE_ISOCHRONOUS | ENDPOINT_ATTR_SYNC | ENDPOINT_USAGE_DATA),
.EndpointSize = AUDIO_STREAM_EPSIZE, .EndpointSize = AUDIO_STREAM_EPSIZE,
.PollingIntervalMS = 1 .PollingIntervalMS = 1
}, },
.Refresh = 0, .Refresh = 0,
.SyncEndpointNumber = 0 .SyncEndpointNumber = 0
}, },
.Audio_StreamEndpoint_SPC = .Audio_StreamEndpoint_SPC =
{ {
.Header = {.Size = sizeof(USB_Audio_StreamEndpoint_Spc_t), .Type = DTYPE_AudioEndpoint}, .Header = {.Size = sizeof(USB_Audio_StreamEndpoint_Spc_t), .Type = DTYPE_AudioEndpoint},
.Subtype = DSUBTYPE_General, .Subtype = DSUBTYPE_General,
.Attributes = EP_ACCEPTS_SMALL_PACKETS, .Attributes = EP_ACCEPTS_SMALL_PACKETS,
.LockDelayUnits = 0x00, .LockDelayUnits = 0x00,
.LockDelay = 0x0000 .LockDelay = 0x0000
} }
}; };
/** Language descriptor structure. This descriptor, located in FLASH memory, is returned when the host requests /** Language descriptor structure. This descriptor, located in FLASH memory, is returned when the host requests
* the string descriptor with index 0 (the first index). It is actually an array of 16-bit integers, which indicate * the string descriptor with index 0 (the first index). It is actually an array of 16-bit integers, which indicate
* via the language ID table available at USB.org what languages the device supports for its string descriptors. * via the language ID table available at USB.org what languages the device supports for its string descriptors.
*/ */
USB_Descriptor_String_t PROGMEM LanguageString = USB_Descriptor_String_t PROGMEM LanguageString =
{ {
.Header = {.Size = USB_STRING_LEN(1), .Type = DTYPE_String}, .Header = {.Size = USB_STRING_LEN(1), .Type = DTYPE_String},
.UnicodeString = {LANGUAGE_ID_ENG} .UnicodeString = {LANGUAGE_ID_ENG}
}; };
/** Manufacturer descriptor string. This is a Unicode string containing the manufacturer's details in human readable /** Manufacturer descriptor string. This is a Unicode string containing the manufacturer's details in human readable
* form, and is read out upon request by the host when the appropriate string ID is requested, listed in the Device * form, and is read out upon request by the host when the appropriate string ID is requested, listed in the Device
* Descriptor. * Descriptor.
*/ */
USB_Descriptor_String_t PROGMEM ManufacturerString = USB_Descriptor_String_t PROGMEM ManufacturerString =
{ {
.Header = {.Size = USB_STRING_LEN(11), .Type = DTYPE_String}, .Header = {.Size = USB_STRING_LEN(11), .Type = DTYPE_String},
.UnicodeString = L"Dean Camera" .UnicodeString = L"Dean Camera"
}; };
/** Product descriptor string. This is a Unicode string containing the product's details in human readable form, /** Product descriptor string. This is a Unicode string containing the product's details in human readable form,
* and is read out upon request by the host when the appropriate string ID is requested, listed in the Device * and is read out upon request by the host when the appropriate string ID is requested, listed in the Device
* Descriptor. * Descriptor.
*/ */
USB_Descriptor_String_t PROGMEM ProductString = USB_Descriptor_String_t PROGMEM ProductString =
{ {
.Header = {.Size = USB_STRING_LEN(19), .Type = DTYPE_String}, .Header = {.Size = USB_STRING_LEN(19), .Type = DTYPE_String},
.UnicodeString = L"LUFA Audio Out Demo" .UnicodeString = L"LUFA Audio Out Demo"
}; };
/** This function is called by the library when in device mode, and must be overridden (see library "USB Descriptors" /** This function is called by the library when in device mode, and must be overridden (see library "USB Descriptors"
* documentation) by the application code so that the address and size of a requested descriptor can be given * documentation) by the application code so that the address and size of a requested descriptor can be given
* to the USB library. When the device receives a Get Descriptor request on the control endpoint, this function * to the USB library. When the device receives a Get Descriptor request on the control endpoint, this function
* is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the * is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the
* USB host. * USB host.
*/ */
uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, void** const DescriptorAddress) uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, void** const DescriptorAddress)
{ {
const uint8_t DescriptorType = (wValue >> 8); const uint8_t DescriptorType = (wValue >> 8);
const uint8_t DescriptorNumber = (wValue & 0xFF); const uint8_t DescriptorNumber = (wValue & 0xFF);
void* Address = NULL; void* Address = NULL;
uint16_t Size = NO_DESCRIPTOR; uint16_t Size = NO_DESCRIPTOR;
switch (DescriptorType) switch (DescriptorType)
{ {
case DTYPE_Device: case DTYPE_Device:
Address = (void*)&DeviceDescriptor; Address = (void*)&DeviceDescriptor;
Size = sizeof(USB_Descriptor_Device_t); Size = sizeof(USB_Descriptor_Device_t);
break; break;
case DTYPE_Configuration: case DTYPE_Configuration:
Address = (void*)&ConfigurationDescriptor; Address = (void*)&ConfigurationDescriptor;
Size = sizeof(USB_Descriptor_Configuration_t); Size = sizeof(USB_Descriptor_Configuration_t);
break; break;
case DTYPE_String: case DTYPE_String:
switch (DescriptorNumber) switch (DescriptorNumber)
{ {
case 0x00: case 0x00:
Address = (void*)&LanguageString; Address = (void*)&LanguageString;
Size = pgm_read_byte(&LanguageString.Header.Size); Size = pgm_read_byte(&LanguageString.Header.Size);
break; break;
case 0x01: case 0x01:
Address = (void*)&ManufacturerString; Address = (void*)&ManufacturerString;
Size = pgm_read_byte(&ManufacturerString.Header.Size); Size = pgm_read_byte(&ManufacturerString.Header.Size);
break; break;
case 0x02: case 0x02:
Address = (void*)&ProductString; Address = (void*)&ProductString;
Size = pgm_read_byte(&ProductString.Header.Size); Size = pgm_read_byte(&ProductString.Header.Size);
break; break;
} }
break; break;
} }
*DescriptorAddress = Address; *DescriptorAddress = Address;
return Size; return Size;
} }

View file

@ -1,82 +1,82 @@
/* /*
LUFA Library LUFA Library
Copyright (C) Dean Camera, 2010. Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com www.fourwalledcubicle.com
*/ */
/* /*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com) Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the advertising or publicity pertaining to distribution of the
software without specific, written prior permission. software without specific, written prior permission.
The author disclaim all warranties with regard to this The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action, in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of arising out of or in connection with the use or performance of
this software. this software.
*/ */
/** \file /** \file
* *
* Header file for Descriptors.c. * Header file for Descriptors.c.
*/ */
#ifndef _DESCRIPTORS_H_ #ifndef _DESCRIPTORS_H_
#define _DESCRIPTORS_H_ #define _DESCRIPTORS_H_
/* Includes: */ /* Includes: */
#include <LUFA/Drivers/USB/USB.h> #include <LUFA/Drivers/USB/USB.h>
#include <LUFA/Drivers/USB/Class/Audio.h> #include <LUFA/Drivers/USB/Class/Audio.h>
#include <avr/pgmspace.h> #include <avr/pgmspace.h>
/* Macros: */ /* Macros: */
/** Endpoint number of the Audio isochronous streaming data endpoint. */ /** Endpoint number of the Audio isochronous streaming data endpoint. */
#define AUDIO_STREAM_EPNUM 1 #define AUDIO_STREAM_EPNUM 1
/** Endpoint size in bytes of the Audio isochronous streaming data endpoint. The Windows audio stack requires /** Endpoint size in bytes of the Audio isochronous streaming data endpoint. The Windows audio stack requires
* at least 192 bytes for correct output, thus the smaller 128 byte maximum endpoint size on some of the smaller * at least 192 bytes for correct output, thus the smaller 128 byte maximum endpoint size on some of the smaller
* USB AVR models will result in unavoidable distorted output. * USB AVR models will result in unavoidable distorted output.
*/ */
#define AUDIO_STREAM_EPSIZE ENDPOINT_MAX_SIZE(AUDIO_STREAM_EPNUM) #define AUDIO_STREAM_EPSIZE ENDPOINT_MAX_SIZE(AUDIO_STREAM_EPNUM)
/** Sample frequency of the data being transmitted through the streaming endpoint. */ /** Sample frequency of the data being transmitted through the streaming endpoint. */
#define AUDIO_SAMPLE_FREQUENCY 48000 #define AUDIO_SAMPLE_FREQUENCY 48000
/* Type Defines: */ /* Type Defines: */
/** Type define for the device configuration descriptor structure. This must be defined in the /** Type define for the device configuration descriptor structure. This must be defined in the
* application code, as the configuration descriptor contains several sub-descriptors which * application code, as the configuration descriptor contains several sub-descriptors which
* vary between devices, and which describe the device's usage to the host. * vary between devices, and which describe the device's usage to the host.
*/ */
typedef struct typedef struct
{ {
USB_Descriptor_Configuration_Header_t Config; USB_Descriptor_Configuration_Header_t Config;
USB_Descriptor_Interface_t Audio_ControlInterface; USB_Descriptor_Interface_t Audio_ControlInterface;
USB_Audio_Interface_AC_t Audio_ControlInterface_SPC; USB_Audio_Interface_AC_t Audio_ControlInterface_SPC;
USB_Audio_InputTerminal_t Audio_InputTerminal; USB_Audio_InputTerminal_t Audio_InputTerminal;
USB_Audio_OutputTerminal_t Audio_OutputTerminal; USB_Audio_OutputTerminal_t Audio_OutputTerminal;
USB_Descriptor_Interface_t Audio_StreamInterface_Alt0; USB_Descriptor_Interface_t Audio_StreamInterface_Alt0;
USB_Descriptor_Interface_t Audio_StreamInterface_Alt1; USB_Descriptor_Interface_t Audio_StreamInterface_Alt1;
USB_Audio_Interface_AS_t Audio_StreamInterface_SPC; USB_Audio_Interface_AS_t Audio_StreamInterface_SPC;
USB_Audio_Format_t Audio_AudioFormat; USB_Audio_Format_t Audio_AudioFormat;
USB_Audio_StreamEndpoint_Std_t Audio_StreamEndpoint; USB_Audio_StreamEndpoint_Std_t Audio_StreamEndpoint;
USB_Audio_StreamEndpoint_Spc_t Audio_StreamEndpoint_SPC; USB_Audio_StreamEndpoint_Spc_t Audio_StreamEndpoint_SPC;
} USB_Descriptor_Configuration_t; } USB_Descriptor_Configuration_t;
/* Function Prototypes: */ /* Function Prototypes: */
uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, void** const DescriptorAddress) uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, void** const DescriptorAddress)
ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3); ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3);
#endif #endif

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,381 +1,381 @@
/* /*
LUFA Library LUFA Library
Copyright (C) Dean Camera, 2010. Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com www.fourwalledcubicle.com
*/ */
/* /*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com) Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the advertising or publicity pertaining to distribution of the
software without specific, written prior permission. software without specific, written prior permission.
The author disclaim all warranties with regard to this The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action, in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of arising out of or in connection with the use or performance of
this software. this software.
*/ */
/** \file /** \file
* *
* USB Device Descriptors, for library use when in USB device mode. Descriptors are special * USB Device Descriptors, for library use when in USB device mode. Descriptors are special
* computer-readable structures which the host requests upon device enumeration, to determine * computer-readable structures which the host requests upon device enumeration, to determine
* the device's capabilities and functions. * the device's capabilities and functions.
*/ */
#include "Descriptors.h" #include "Descriptors.h"
/* On some devices, there is a factory set internal serial number which can be automatically sent to the host as /* On some devices, there is a factory set internal serial number which can be automatically sent to the host as
* the device's serial number when the Device Descriptor's .SerialNumStrIndex entry is set to USE_INTERNAL_SERIAL. * the device's serial number when the Device Descriptor's .SerialNumStrIndex entry is set to USE_INTERNAL_SERIAL.
* This allows the host to track a device across insertions on different ports, allowing them to retain allocated * This allows the host to track a device across insertions on different ports, allowing them to retain allocated
* resources like COM port numbers and drivers. On demos using this feature, give a warning on unsupported devices * resources like COM port numbers and drivers. On demos using this feature, give a warning on unsupported devices
* so that the user can supply their own serial number descriptor instead or remove the USE_INTERNAL_SERIAL value * so that the user can supply their own serial number descriptor instead or remove the USE_INTERNAL_SERIAL value
* from the Device Descriptor (forcing the host to generate a serial number for each device from the VID, PID and * from the Device Descriptor (forcing the host to generate a serial number for each device from the VID, PID and
* port location). * port location).
*/ */
#if (USE_INTERNAL_SERIAL == NO_DESCRIPTOR) #if (USE_INTERNAL_SERIAL == NO_DESCRIPTOR)
#warning USE_INTERNAL_SERIAL is not available on this AVR - please manually construct a device serial descriptor. #warning USE_INTERNAL_SERIAL is not available on this AVR - please manually construct a device serial descriptor.
#endif #endif
/** Device descriptor structure. This descriptor, located in FLASH memory, describes the overall /** Device descriptor structure. This descriptor, located in FLASH memory, describes the overall
* device characteristics, including the supported USB version, control endpoint size and the * device characteristics, including the supported USB version, control endpoint size and the
* number of device configurations. The descriptor is read out by the USB host when the enumeration * number of device configurations. The descriptor is read out by the USB host when the enumeration
* process begins. * process begins.
*/ */
USB_Descriptor_Device_t PROGMEM DeviceDescriptor = USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
{ {
.Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device}, .Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device},
.USBSpecification = VERSION_BCD(01.10), .USBSpecification = VERSION_BCD(01.10),
.Class = 0xEF, .Class = 0xEF,
.SubClass = 0x02, .SubClass = 0x02,
.Protocol = 0x01, .Protocol = 0x01,
.Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE, .Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE,
.VendorID = 0x03EB, .VendorID = 0x03EB,
.ProductID = 0x204E, .ProductID = 0x204E,
.ReleaseNumber = 0x0000, .ReleaseNumber = 0x0000,
.ManufacturerStrIndex = 0x01, .ManufacturerStrIndex = 0x01,
.ProductStrIndex = 0x02, .ProductStrIndex = 0x02,
.SerialNumStrIndex = USE_INTERNAL_SERIAL, .SerialNumStrIndex = USE_INTERNAL_SERIAL,
.NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS .NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS
}; };
/** Configuration descriptor structure. This descriptor, located in FLASH memory, describes the usage /** Configuration descriptor structure. This descriptor, located in FLASH memory, describes the usage
* of the device in one of its supported configurations, including information about any device interfaces * of the device in one of its supported configurations, including information about any device interfaces
* and endpoints. The descriptor is read out by the USB host during the enumeration process when selecting * and endpoints. The descriptor is read out by the USB host during the enumeration process when selecting
* a configuration so that the host may correctly communicate with the USB device. * a configuration so that the host may correctly communicate with the USB device.
*/ */
USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor = USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
{ {
.Config = .Config =
{ {
.Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration}, .Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration},
.TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t), .TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t),
.TotalInterfaces = 4, .TotalInterfaces = 4,
.ConfigurationNumber = 1, .ConfigurationNumber = 1,
.ConfigurationStrIndex = NO_DESCRIPTOR, .ConfigurationStrIndex = NO_DESCRIPTOR,
.ConfigAttributes = (USB_CONFIG_ATTR_BUSPOWERED | USB_CONFIG_ATTR_SELFPOWERED), .ConfigAttributes = (USB_CONFIG_ATTR_BUSPOWERED | USB_CONFIG_ATTR_SELFPOWERED),
.MaxPowerConsumption = USB_CONFIG_POWER_MA(100) .MaxPowerConsumption = USB_CONFIG_POWER_MA(100)
}, },
.CDC1_IAD = .CDC1_IAD =
{ {
.Header = {.Size = sizeof(USB_Descriptor_Interface_Association_t), .Type = DTYPE_InterfaceAssociation}, .Header = {.Size = sizeof(USB_Descriptor_Interface_Association_t), .Type = DTYPE_InterfaceAssociation},
.FirstInterfaceIndex = 0, .FirstInterfaceIndex = 0,
.TotalInterfaces = 2, .TotalInterfaces = 2,
.Class = 0x02, .Class = 0x02,
.SubClass = 0x02, .SubClass = 0x02,
.Protocol = 0x01, .Protocol = 0x01,
.IADStrIndex = NO_DESCRIPTOR .IADStrIndex = NO_DESCRIPTOR
}, },
.CDC1_CCI_Interface = .CDC1_CCI_Interface =
{ {
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface}, .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
.InterfaceNumber = 0, .InterfaceNumber = 0,
.AlternateSetting = 0, .AlternateSetting = 0,
.TotalEndpoints = 1, .TotalEndpoints = 1,
.Class = 0x02, .Class = 0x02,
.SubClass = 0x02, .SubClass = 0x02,
.Protocol = 0x01, .Protocol = 0x01,
.InterfaceStrIndex = NO_DESCRIPTOR .InterfaceStrIndex = NO_DESCRIPTOR
}, },
.CDC1_Functional_IntHeader = .CDC1_Functional_IntHeader =
{ {
.Header = {.Size = sizeof(CDC_FUNCTIONAL_DESCRIPTOR(2)), .Type = 0x24}, .Header = {.Size = sizeof(CDC_FUNCTIONAL_DESCRIPTOR(2)), .Type = 0x24},
.SubType = 0x00, .SubType = 0x00,
.Data = {0x01, 0x10} .Data = {0x01, 0x10}
}, },
.CDC1_Functional_AbstractControlManagement = .CDC1_Functional_AbstractControlManagement =
{ {
.Header = {.Size = sizeof(CDC_FUNCTIONAL_DESCRIPTOR(1)), .Type = 0x24}, .Header = {.Size = sizeof(CDC_FUNCTIONAL_DESCRIPTOR(1)), .Type = 0x24},
.SubType = 0x02, .SubType = 0x02,
.Data = {0x06} .Data = {0x06}
}, },
.CDC1_Functional_Union = .CDC1_Functional_Union =
{ {
.Header = {.Size = sizeof(CDC_FUNCTIONAL_DESCRIPTOR(2)), .Type = 0x24}, .Header = {.Size = sizeof(CDC_FUNCTIONAL_DESCRIPTOR(2)), .Type = 0x24},
.SubType = 0x06, .SubType = 0x06,
.Data = {0x00, 0x01} .Data = {0x00, 0x01}
}, },
.CDC1_ManagementEndpoint = .CDC1_ManagementEndpoint =
{ {
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint}, .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
.EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_IN | CDC1_NOTIFICATION_EPNUM), .EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_IN | CDC1_NOTIFICATION_EPNUM),
.Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
.EndpointSize = CDC_NOTIFICATION_EPSIZE, .EndpointSize = CDC_NOTIFICATION_EPSIZE,
.PollingIntervalMS = 0xFF .PollingIntervalMS = 0xFF
}, },
.CDC1_DCI_Interface = .CDC1_DCI_Interface =
{ {
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface}, .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
.InterfaceNumber = 1, .InterfaceNumber = 1,
.AlternateSetting = 0, .AlternateSetting = 0,
.TotalEndpoints = 2, .TotalEndpoints = 2,
.Class = 0x0A, .Class = 0x0A,
.SubClass = 0x00, .SubClass = 0x00,
.Protocol = 0x00, .Protocol = 0x00,
.InterfaceStrIndex = NO_DESCRIPTOR .InterfaceStrIndex = NO_DESCRIPTOR
}, },
.CDC1_DataOutEndpoint = .CDC1_DataOutEndpoint =
{ {
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint}, .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
.EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_OUT | CDC1_RX_EPNUM), .EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_OUT | CDC1_RX_EPNUM),
.Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), .Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
.EndpointSize = CDC_TXRX_EPSIZE, .EndpointSize = CDC_TXRX_EPSIZE,
.PollingIntervalMS = 0x00 .PollingIntervalMS = 0x00
}, },
.CDC1_DataInEndpoint = .CDC1_DataInEndpoint =
{ {
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint}, .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
.EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_IN | CDC1_TX_EPNUM), .EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_IN | CDC1_TX_EPNUM),
.Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), .Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
.EndpointSize = CDC_TXRX_EPSIZE, .EndpointSize = CDC_TXRX_EPSIZE,
.PollingIntervalMS = 0x00 .PollingIntervalMS = 0x00
}, },
.CDC2_IAD = .CDC2_IAD =
{ {
.Header = {.Size = sizeof(USB_Descriptor_Interface_Association_t), .Type = DTYPE_InterfaceAssociation}, .Header = {.Size = sizeof(USB_Descriptor_Interface_Association_t), .Type = DTYPE_InterfaceAssociation},
.FirstInterfaceIndex = 2, .FirstInterfaceIndex = 2,
.TotalInterfaces = 2, .TotalInterfaces = 2,
.Class = 0x02, .Class = 0x02,
.SubClass = 0x02, .SubClass = 0x02,
.Protocol = 0x01, .Protocol = 0x01,
.IADStrIndex = NO_DESCRIPTOR .IADStrIndex = NO_DESCRIPTOR
}, },
.CDC2_CCI_Interface = .CDC2_CCI_Interface =
{ {
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface}, .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
.InterfaceNumber = 2, .InterfaceNumber = 2,
.AlternateSetting = 0, .AlternateSetting = 0,
.TotalEndpoints = 1, .TotalEndpoints = 1,
.Class = 0x02, .Class = 0x02,
.SubClass = 0x02, .SubClass = 0x02,
.Protocol = 0x01, .Protocol = 0x01,
.InterfaceStrIndex = NO_DESCRIPTOR .InterfaceStrIndex = NO_DESCRIPTOR
}, },
.CDC2_Functional_IntHeader = .CDC2_Functional_IntHeader =
{ {
.Header = {.Size = sizeof(CDC_FUNCTIONAL_DESCRIPTOR(2)), .Type = 0x24}, .Header = {.Size = sizeof(CDC_FUNCTIONAL_DESCRIPTOR(2)), .Type = 0x24},
.SubType = 0x00, .SubType = 0x00,
.Data = {0x01, 0x10} .Data = {0x01, 0x10}
}, },
.CDC2_Functional_AbstractControlManagement = .CDC2_Functional_AbstractControlManagement =
{ {
.Header = {.Size = sizeof(CDC_FUNCTIONAL_DESCRIPTOR(1)), .Type = 0x24}, .Header = {.Size = sizeof(CDC_FUNCTIONAL_DESCRIPTOR(1)), .Type = 0x24},
.SubType = 0x02, .SubType = 0x02,
.Data = {0x06} .Data = {0x06}
}, },
.CDC2_Functional_Union = .CDC2_Functional_Union =
{ {
.Header = {.Size = sizeof(CDC_FUNCTIONAL_DESCRIPTOR(2)), .Type = 0x24}, .Header = {.Size = sizeof(CDC_FUNCTIONAL_DESCRIPTOR(2)), .Type = 0x24},
.SubType = 0x06, .SubType = 0x06,
.Data = {0x02, 0x03} .Data = {0x02, 0x03}
}, },
.CDC2_ManagementEndpoint = .CDC2_ManagementEndpoint =
{ {
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint}, .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
.EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_IN | CDC2_NOTIFICATION_EPNUM), .EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_IN | CDC2_NOTIFICATION_EPNUM),
.Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
.EndpointSize = CDC_NOTIFICATION_EPSIZE, .EndpointSize = CDC_NOTIFICATION_EPSIZE,
.PollingIntervalMS = 0xFF .PollingIntervalMS = 0xFF
}, },
.CDC2_DCI_Interface = .CDC2_DCI_Interface =
{ {
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface}, .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
.InterfaceNumber = 3, .InterfaceNumber = 3,
.AlternateSetting = 0, .AlternateSetting = 0,
.TotalEndpoints = 2, .TotalEndpoints = 2,
.Class = 0x0A, .Class = 0x0A,
.SubClass = 0x00, .SubClass = 0x00,
.Protocol = 0x00, .Protocol = 0x00,
.InterfaceStrIndex = NO_DESCRIPTOR .InterfaceStrIndex = NO_DESCRIPTOR
}, },
.CDC2_DataOutEndpoint = .CDC2_DataOutEndpoint =
{ {
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint}, .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
.EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_OUT | CDC2_RX_EPNUM), .EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_OUT | CDC2_RX_EPNUM),
.Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), .Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
.EndpointSize = CDC_TXRX_EPSIZE, .EndpointSize = CDC_TXRX_EPSIZE,
.PollingIntervalMS = 0x00 .PollingIntervalMS = 0x00
}, },
.CDC2_DataInEndpoint = .CDC2_DataInEndpoint =
{ {
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint}, .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
.EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_IN | CDC2_TX_EPNUM), .EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_IN | CDC2_TX_EPNUM),
.Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), .Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
.EndpointSize = CDC_TXRX_EPSIZE, .EndpointSize = CDC_TXRX_EPSIZE,
.PollingIntervalMS = 0x00 .PollingIntervalMS = 0x00
} }
}; };
/** Language descriptor structure. This descriptor, located in FLASH memory, is returned when the host requests /** Language descriptor structure. This descriptor, located in FLASH memory, is returned when the host requests
* the string descriptor with index 0 (the first index). It is actually an array of 16-bit integers, which indicate * the string descriptor with index 0 (the first index). It is actually an array of 16-bit integers, which indicate
* via the language ID table available at USB.org what languages the device supports for its string descriptors. * via the language ID table available at USB.org what languages the device supports for its string descriptors.
*/ */
USB_Descriptor_String_t PROGMEM LanguageString = USB_Descriptor_String_t PROGMEM LanguageString =
{ {
.Header = {.Size = USB_STRING_LEN(1), .Type = DTYPE_String}, .Header = {.Size = USB_STRING_LEN(1), .Type = DTYPE_String},
.UnicodeString = {LANGUAGE_ID_ENG} .UnicodeString = {LANGUAGE_ID_ENG}
}; };
/** Manufacturer descriptor string. This is a Unicode string containing the manufacturer's details in human readable /** Manufacturer descriptor string. This is a Unicode string containing the manufacturer's details in human readable
* form, and is read out upon request by the host when the appropriate string ID is requested, listed in the Device * form, and is read out upon request by the host when the appropriate string ID is requested, listed in the Device
* Descriptor. * Descriptor.
*/ */
USB_Descriptor_String_t PROGMEM ManufacturerString = USB_Descriptor_String_t PROGMEM ManufacturerString =
{ {
.Header = {.Size = USB_STRING_LEN(11), .Type = DTYPE_String}, .Header = {.Size = USB_STRING_LEN(11), .Type = DTYPE_String},
.UnicodeString = L"Dean Camera" .UnicodeString = L"Dean Camera"
}; };
/** Product descriptor string. This is a Unicode string containing the product's details in human readable form, /** Product descriptor string. This is a Unicode string containing the product's details in human readable form,
* and is read out upon request by the host when the appropriate string ID is requested, listed in the Device * and is read out upon request by the host when the appropriate string ID is requested, listed in the Device
* Descriptor. * Descriptor.
*/ */
USB_Descriptor_String_t PROGMEM ProductString = USB_Descriptor_String_t PROGMEM ProductString =
{ {
.Header = {.Size = USB_STRING_LEN(13), .Type = DTYPE_String}, .Header = {.Size = USB_STRING_LEN(13), .Type = DTYPE_String},
.UnicodeString = L"LUFA Dual CDC Demo" .UnicodeString = L"LUFA Dual CDC Demo"
}; };
/** This function is called by the library when in device mode, and must be overridden (see library "USB Descriptors" /** This function is called by the library when in device mode, and must be overridden (see library "USB Descriptors"
* documentation) by the application code so that the address and size of a requested descriptor can be given * documentation) by the application code so that the address and size of a requested descriptor can be given
* to the USB library. When the device receives a Get Descriptor request on the control endpoint, this function * to the USB library. When the device receives a Get Descriptor request on the control endpoint, this function
* is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the * is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the
* USB host. * USB host.
*/ */
uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, void** const DescriptorAddress) uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, void** const DescriptorAddress)
{ {
const uint8_t DescriptorType = (wValue >> 8); const uint8_t DescriptorType = (wValue >> 8);
const uint8_t DescriptorNumber = (wValue & 0xFF); const uint8_t DescriptorNumber = (wValue & 0xFF);
void* Address = NULL; void* Address = NULL;
uint16_t Size = NO_DESCRIPTOR; uint16_t Size = NO_DESCRIPTOR;
switch (DescriptorType) switch (DescriptorType)
{ {
case DTYPE_Device: case DTYPE_Device:
Address = (void*)&DeviceDescriptor; Address = (void*)&DeviceDescriptor;
Size = sizeof(USB_Descriptor_Device_t); Size = sizeof(USB_Descriptor_Device_t);
break; break;
case DTYPE_Configuration: case DTYPE_Configuration:
Address = (void*)&ConfigurationDescriptor; Address = (void*)&ConfigurationDescriptor;
Size = sizeof(USB_Descriptor_Configuration_t); Size = sizeof(USB_Descriptor_Configuration_t);
break; break;
case DTYPE_String: case DTYPE_String:
switch (DescriptorNumber) switch (DescriptorNumber)
{ {
case 0x00: case 0x00:
Address = (void*)&LanguageString; Address = (void*)&LanguageString;
Size = pgm_read_byte(&LanguageString.Header.Size); Size = pgm_read_byte(&LanguageString.Header.Size);
break; break;
case 0x01: case 0x01:
Address = (void*)&ManufacturerString; Address = (void*)&ManufacturerString;
Size = pgm_read_byte(&ManufacturerString.Header.Size); Size = pgm_read_byte(&ManufacturerString.Header.Size);
break; break;
case 0x02: case 0x02:
Address = (void*)&ProductString; Address = (void*)&ProductString;
Size = pgm_read_byte(&ProductString.Header.Size); Size = pgm_read_byte(&ProductString.Header.Size);
break; break;
} }
break; break;
} }
*DescriptorAddress = Address; *DescriptorAddress = Address;
return Size; return Size;
} }

View file

@ -1,102 +1,102 @@
/* /*
LUFA Library LUFA Library
Copyright (C) Dean Camera, 2010. Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com www.fourwalledcubicle.com
*/ */
/* /*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com) Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the advertising or publicity pertaining to distribution of the
software without specific, written prior permission. software without specific, written prior permission.
The author disclaim all warranties with regard to this The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action, in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of arising out of or in connection with the use or performance of
this software. this software.
*/ */
/** \file /** \file
* *
* Header file for Descriptors.c. * Header file for Descriptors.c.
*/ */
#ifndef _DESCRIPTORS_H_ #ifndef _DESCRIPTORS_H_
#define _DESCRIPTORS_H_ #define _DESCRIPTORS_H_
/* Includes: */ /* Includes: */
#include <avr/pgmspace.h> #include <avr/pgmspace.h>
#include <LUFA/Drivers/USB/USB.h> #include <LUFA/Drivers/USB/USB.h>
#include <LUFA/Drivers/USB/Class/CDC.h> #include <LUFA/Drivers/USB/Class/CDC.h>
/* Macros: */ /* Macros: */
/** Endpoint number of the first CDC interface's device-to-host notification IN endpoint. */ /** Endpoint number of the first CDC interface's device-to-host notification IN endpoint. */
#define CDC1_NOTIFICATION_EPNUM 3 #define CDC1_NOTIFICATION_EPNUM 3
/** Endpoint number of the first CDC interface's device-to-host data IN endpoint. */ /** Endpoint number of the first CDC interface's device-to-host data IN endpoint. */
#define CDC1_TX_EPNUM 1 #define CDC1_TX_EPNUM 1
/** Endpoint number of the first CDC interface's host-to-device data OUT endpoint. */ /** Endpoint number of the first CDC interface's host-to-device data OUT endpoint. */
#define CDC1_RX_EPNUM 2 #define CDC1_RX_EPNUM 2
/** Endpoint number of the second CDC interface's device-to-host notification IN endpoint. */ /** Endpoint number of the second CDC interface's device-to-host notification IN endpoint. */
#define CDC2_NOTIFICATION_EPNUM 4 #define CDC2_NOTIFICATION_EPNUM 4
/** Endpoint number of the second CDC interface's device-to-host data IN endpoint. */ /** Endpoint number of the second CDC interface's device-to-host data IN endpoint. */
#define CDC2_TX_EPNUM 5 #define CDC2_TX_EPNUM 5
/** Endpoint number of the second CDC interface's host-to-device data OUT endpoint. */ /** Endpoint number of the second CDC interface's host-to-device data OUT endpoint. */
#define CDC2_RX_EPNUM 6 #define CDC2_RX_EPNUM 6
/** Size in bytes of the CDC device-to-host notification IN endpoints. */ /** Size in bytes of the CDC device-to-host notification IN endpoints. */
#define CDC_NOTIFICATION_EPSIZE 8 #define CDC_NOTIFICATION_EPSIZE 8
/** Size in bytes of the CDC data IN and OUT endpoints. */ /** Size in bytes of the CDC data IN and OUT endpoints. */
#define CDC_TXRX_EPSIZE 16 #define CDC_TXRX_EPSIZE 16
/* Type Defines: */ /* Type Defines: */
/** Type define for the device configuration descriptor structure. This must be defined in the /** Type define for the device configuration descriptor structure. This must be defined in the
* application code, as the configuration descriptor contains several sub-descriptors which * application code, as the configuration descriptor contains several sub-descriptors which
* vary between devices, and which describe the device's usage to the host. * vary between devices, and which describe the device's usage to the host.
*/ */
typedef struct typedef struct
{ {
USB_Descriptor_Configuration_Header_t Config; USB_Descriptor_Configuration_Header_t Config;
USB_Descriptor_Interface_Association_t CDC1_IAD; USB_Descriptor_Interface_Association_t CDC1_IAD;
USB_Descriptor_Interface_t CDC1_CCI_Interface; USB_Descriptor_Interface_t CDC1_CCI_Interface;
CDC_FUNCTIONAL_DESCRIPTOR(2) CDC1_Functional_IntHeader; CDC_FUNCTIONAL_DESCRIPTOR(2) CDC1_Functional_IntHeader;
CDC_FUNCTIONAL_DESCRIPTOR(1) CDC1_Functional_AbstractControlManagement; CDC_FUNCTIONAL_DESCRIPTOR(1) CDC1_Functional_AbstractControlManagement;
CDC_FUNCTIONAL_DESCRIPTOR(2) CDC1_Functional_Union; CDC_FUNCTIONAL_DESCRIPTOR(2) CDC1_Functional_Union;
USB_Descriptor_Endpoint_t CDC1_ManagementEndpoint; USB_Descriptor_Endpoint_t CDC1_ManagementEndpoint;
USB_Descriptor_Interface_t CDC1_DCI_Interface; USB_Descriptor_Interface_t CDC1_DCI_Interface;
USB_Descriptor_Endpoint_t CDC1_DataOutEndpoint; USB_Descriptor_Endpoint_t CDC1_DataOutEndpoint;
USB_Descriptor_Endpoint_t CDC1_DataInEndpoint; USB_Descriptor_Endpoint_t CDC1_DataInEndpoint;
USB_Descriptor_Interface_Association_t CDC2_IAD; USB_Descriptor_Interface_Association_t CDC2_IAD;
USB_Descriptor_Interface_t CDC2_CCI_Interface; USB_Descriptor_Interface_t CDC2_CCI_Interface;
CDC_FUNCTIONAL_DESCRIPTOR(2) CDC2_Functional_IntHeader; CDC_FUNCTIONAL_DESCRIPTOR(2) CDC2_Functional_IntHeader;
CDC_FUNCTIONAL_DESCRIPTOR(1) CDC2_Functional_AbstractControlManagement; CDC_FUNCTIONAL_DESCRIPTOR(1) CDC2_Functional_AbstractControlManagement;
CDC_FUNCTIONAL_DESCRIPTOR(2) CDC2_Functional_Union; CDC_FUNCTIONAL_DESCRIPTOR(2) CDC2_Functional_Union;
USB_Descriptor_Endpoint_t CDC2_ManagementEndpoint; USB_Descriptor_Endpoint_t CDC2_ManagementEndpoint;
USB_Descriptor_Interface_t CDC2_DCI_Interface; USB_Descriptor_Interface_t CDC2_DCI_Interface;
USB_Descriptor_Endpoint_t CDC2_DataOutEndpoint; USB_Descriptor_Endpoint_t CDC2_DataOutEndpoint;
USB_Descriptor_Endpoint_t CDC2_DataInEndpoint; USB_Descriptor_Endpoint_t CDC2_DataInEndpoint;
} USB_Descriptor_Configuration_t; } USB_Descriptor_Configuration_t;
/* Function Prototypes: */ /* Function Prototypes: */
uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, void** const DescriptorAddress) uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, void** const DescriptorAddress)
ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3); ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3);
#endif #endif

File diff suppressed because it is too large Load diff

View file

@ -1,192 +1,192 @@
/* /*
LUFA Library LUFA Library
Copyright (C) Dean Camera, 2010. Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com www.fourwalledcubicle.com
*/ */
/* /*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com) Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the advertising or publicity pertaining to distribution of the
software without specific, written prior permission. software without specific, written prior permission.
The author disclaim all warranties with regard to this The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action, in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of arising out of or in connection with the use or performance of
this software. this software.
*/ */
/** \file /** \file
* *
* Main source file for the DualVirtualSerial demo. This file contains the main tasks of * Main source file for the DualVirtualSerial demo. This file contains the main tasks of
* the demo and is responsible for the initial application hardware configuration. * the demo and is responsible for the initial application hardware configuration.
*/ */
#include "DualVirtualSerial.h" #include "DualVirtualSerial.h"
/** LUFA CDC Class driver interface configuration and state information. This structure is /** LUFA CDC Class driver interface configuration and state information. This structure is
* passed to all CDC Class driver functions, so that multiple instances of the same class * passed to all CDC Class driver functions, so that multiple instances of the same class
* within a device can be differentiated from one another. This is for the first CDC interface, * within a device can be differentiated from one another. This is for the first CDC interface,
* which sends strings to the host for each joystick movement. * which sends strings to the host for each joystick movement.
*/ */
USB_ClassInfo_CDC_Device_t VirtualSerial1_CDC_Interface = USB_ClassInfo_CDC_Device_t VirtualSerial1_CDC_Interface =
{ {
.Config = .Config =
{ {
.ControlInterfaceNumber = 0, .ControlInterfaceNumber = 0,
.DataINEndpointNumber = CDC1_TX_EPNUM, .DataINEndpointNumber = CDC1_TX_EPNUM,
.DataINEndpointSize = CDC_TXRX_EPSIZE, .DataINEndpointSize = CDC_TXRX_EPSIZE,
.DataINEndpointDoubleBank = false, .DataINEndpointDoubleBank = false,
.DataOUTEndpointNumber = CDC1_RX_EPNUM, .DataOUTEndpointNumber = CDC1_RX_EPNUM,
.DataOUTEndpointSize = CDC_TXRX_EPSIZE, .DataOUTEndpointSize = CDC_TXRX_EPSIZE,
.DataOUTEndpointDoubleBank = false, .DataOUTEndpointDoubleBank = false,
.NotificationEndpointNumber = CDC1_NOTIFICATION_EPNUM, .NotificationEndpointNumber = CDC1_NOTIFICATION_EPNUM,
.NotificationEndpointSize = CDC_NOTIFICATION_EPSIZE, .NotificationEndpointSize = CDC_NOTIFICATION_EPSIZE,
.NotificationEndpointDoubleBank = false, .NotificationEndpointDoubleBank = false,
}, },
}; };
/** LUFA CDC Class driver interface configuration and state information. This structure is /** LUFA CDC Class driver interface configuration and state information. This structure is
* passed to all CDC Class driver functions, so that multiple instances of the same class * passed to all CDC Class driver functions, so that multiple instances of the same class
* within a device can be differentiated from one another. This is for the second CDC interface, * within a device can be differentiated from one another. This is for the second CDC interface,
* which echos back all received data from the host. * which echos back all received data from the host.
*/ */
USB_ClassInfo_CDC_Device_t VirtualSerial2_CDC_Interface = USB_ClassInfo_CDC_Device_t VirtualSerial2_CDC_Interface =
{ {
.Config = .Config =
{ {
.ControlInterfaceNumber = 2, .ControlInterfaceNumber = 2,
.DataINEndpointNumber = CDC2_TX_EPNUM, .DataINEndpointNumber = CDC2_TX_EPNUM,
.DataINEndpointSize = CDC_TXRX_EPSIZE, .DataINEndpointSize = CDC_TXRX_EPSIZE,
.DataINEndpointDoubleBank = false, .DataINEndpointDoubleBank = false,
.DataOUTEndpointNumber = CDC2_RX_EPNUM, .DataOUTEndpointNumber = CDC2_RX_EPNUM,
.DataOUTEndpointSize = CDC_TXRX_EPSIZE, .DataOUTEndpointSize = CDC_TXRX_EPSIZE,
.DataOUTEndpointDoubleBank = false, .DataOUTEndpointDoubleBank = false,
.NotificationEndpointNumber = CDC2_NOTIFICATION_EPNUM, .NotificationEndpointNumber = CDC2_NOTIFICATION_EPNUM,
.NotificationEndpointSize = CDC_NOTIFICATION_EPSIZE, .NotificationEndpointSize = CDC_NOTIFICATION_EPSIZE,
.NotificationEndpointDoubleBank = false, .NotificationEndpointDoubleBank = false,
}, },
}; };
/** Main program entry point. This routine contains the overall program flow, including initial /** Main program entry point. This routine contains the overall program flow, including initial
* setup of all components and the main program loop. * setup of all components and the main program loop.
*/ */
int main(void) int main(void)
{ {
SetupHardware(); SetupHardware();
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY); LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
sei(); sei();
for (;;) for (;;)
{ {
CheckJoystickMovement(); CheckJoystickMovement();
/* Discard all received data on the first CDC interface */ /* Discard all received data on the first CDC interface */
while (CDC_Device_BytesReceived(&VirtualSerial1_CDC_Interface)) while (CDC_Device_BytesReceived(&VirtualSerial1_CDC_Interface))
CDC_Device_ReceiveByte(&VirtualSerial1_CDC_Interface); CDC_Device_ReceiveByte(&VirtualSerial1_CDC_Interface);
/* Echo all received data on the second CDC interface */ /* Echo all received data on the second CDC interface */
while (CDC_Device_BytesReceived(&VirtualSerial2_CDC_Interface)) while (CDC_Device_BytesReceived(&VirtualSerial2_CDC_Interface))
CDC_Device_SendByte(&VirtualSerial2_CDC_Interface, CDC_Device_ReceiveByte(&VirtualSerial2_CDC_Interface)); CDC_Device_SendByte(&VirtualSerial2_CDC_Interface, CDC_Device_ReceiveByte(&VirtualSerial2_CDC_Interface));
CDC_Device_USBTask(&VirtualSerial1_CDC_Interface); CDC_Device_USBTask(&VirtualSerial1_CDC_Interface);
CDC_Device_USBTask(&VirtualSerial2_CDC_Interface); CDC_Device_USBTask(&VirtualSerial2_CDC_Interface);
USB_USBTask(); USB_USBTask();
} }
} }
/** Configures the board hardware and chip peripherals for the demo's functionality. */ /** Configures the board hardware and chip peripherals for the demo's functionality. */
void SetupHardware(void) void SetupHardware(void)
{ {
/* Disable watchdog if enabled by bootloader/fuses */ /* Disable watchdog if enabled by bootloader/fuses */
MCUSR &= ~(1 << WDRF); MCUSR &= ~(1 << WDRF);
wdt_disable(); wdt_disable();
/* Disable clock division */ /* Disable clock division */
clock_prescale_set(clock_div_1); clock_prescale_set(clock_div_1);
/* Hardware Initialization */ /* Hardware Initialization */
Joystick_Init(); Joystick_Init();
LEDs_Init(); LEDs_Init();
USB_Init(); USB_Init();
} }
/** Checks for changes in the position of the board joystick, sending strings to the host upon each change /** Checks for changes in the position of the board joystick, sending strings to the host upon each change
* through the first of the CDC interfaces. * through the first of the CDC interfaces.
*/ */
void CheckJoystickMovement(void) void CheckJoystickMovement(void)
{ {
uint8_t JoyStatus_LCL = Joystick_GetStatus(); uint8_t JoyStatus_LCL = Joystick_GetStatus();
char* ReportString = NULL; char* ReportString = NULL;
static bool ActionSent = false; static bool ActionSent = false;
if (JoyStatus_LCL & JOY_UP) if (JoyStatus_LCL & JOY_UP)
ReportString = "Joystick Up\r\n"; ReportString = "Joystick Up\r\n";
else if (JoyStatus_LCL & JOY_DOWN) else if (JoyStatus_LCL & JOY_DOWN)
ReportString = "Joystick Down\r\n"; ReportString = "Joystick Down\r\n";
else if (JoyStatus_LCL & JOY_LEFT) else if (JoyStatus_LCL & JOY_LEFT)
ReportString = "Joystick Left\r\n"; ReportString = "Joystick Left\r\n";
else if (JoyStatus_LCL & JOY_RIGHT) else if (JoyStatus_LCL & JOY_RIGHT)
ReportString = "Joystick Right\r\n"; ReportString = "Joystick Right\r\n";
else if (JoyStatus_LCL & JOY_PRESS) else if (JoyStatus_LCL & JOY_PRESS)
ReportString = "Joystick Pressed\r\n"; ReportString = "Joystick Pressed\r\n";
else else
ActionSent = false; ActionSent = false;
if ((ReportString != NULL) && (ActionSent == false)) if ((ReportString != NULL) && (ActionSent == false))
{ {
ActionSent = true; ActionSent = true;
CDC_Device_SendString(&VirtualSerial1_CDC_Interface, ReportString, strlen(ReportString)); CDC_Device_SendString(&VirtualSerial1_CDC_Interface, ReportString, strlen(ReportString));
} }
} }
/** Event handler for the library USB Connection event. */ /** Event handler for the library USB Connection event. */
void EVENT_USB_Device_Connect(void) void EVENT_USB_Device_Connect(void)
{ {
LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING); LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
} }
/** Event handler for the library USB Disconnection event. */ /** Event handler for the library USB Disconnection event. */
void EVENT_USB_Device_Disconnect(void) void EVENT_USB_Device_Disconnect(void)
{ {
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY); LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
} }
/** Event handler for the library USB Configuration Changed event. */ /** Event handler for the library USB Configuration Changed event. */
void EVENT_USB_Device_ConfigurationChanged(void) void EVENT_USB_Device_ConfigurationChanged(void)
{ {
LEDs_SetAllLEDs(LEDMASK_USB_READY); LEDs_SetAllLEDs(LEDMASK_USB_READY);
if (!(CDC_Device_ConfigureEndpoints(&VirtualSerial1_CDC_Interface))) if (!(CDC_Device_ConfigureEndpoints(&VirtualSerial1_CDC_Interface)))
LEDs_SetAllLEDs(LEDMASK_USB_ERROR); LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
if (!(CDC_Device_ConfigureEndpoints(&VirtualSerial2_CDC_Interface))) if (!(CDC_Device_ConfigureEndpoints(&VirtualSerial2_CDC_Interface)))
LEDs_SetAllLEDs(LEDMASK_USB_ERROR); LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
} }
/** Event handler for the library USB Unhandled Control Request event. */ /** Event handler for the library USB Unhandled Control Request event. */
void EVENT_USB_Device_UnhandledControlRequest(void) void EVENT_USB_Device_UnhandledControlRequest(void)
{ {
CDC_Device_ProcessControlRequest(&VirtualSerial1_CDC_Interface); CDC_Device_ProcessControlRequest(&VirtualSerial1_CDC_Interface);
CDC_Device_ProcessControlRequest(&VirtualSerial2_CDC_Interface); CDC_Device_ProcessControlRequest(&VirtualSerial2_CDC_Interface);
} }

View file

@ -1,76 +1,76 @@
/* /*
LUFA Library LUFA Library
Copyright (C) Dean Camera, 2010. Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com www.fourwalledcubicle.com
*/ */
/* /*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com) Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the advertising or publicity pertaining to distribution of the
software without specific, written prior permission. software without specific, written prior permission.
The author disclaim all warranties with regard to this The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action, in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of arising out of or in connection with the use or performance of
this software. this software.
*/ */
/** \file /** \file
* *
* Header file for DualVirtualSerial.c. * Header file for DualVirtualSerial.c.
*/ */
#ifndef _DUAL_VIRTUALSERIAL_H_ #ifndef _DUAL_VIRTUALSERIAL_H_
#define _DUAL_VIRTUALSERIAL_H_ #define _DUAL_VIRTUALSERIAL_H_
/* Includes: */ /* Includes: */
#include <avr/io.h> #include <avr/io.h>
#include <avr/wdt.h> #include <avr/wdt.h>
#include <avr/power.h> #include <avr/power.h>
#include <avr/interrupt.h> #include <avr/interrupt.h>
#include <string.h> #include <string.h>
#include "Descriptors.h" #include "Descriptors.h"
#include <LUFA/Version.h> #include <LUFA/Version.h>
#include <LUFA/Drivers/Board/LEDs.h> #include <LUFA/Drivers/Board/LEDs.h>
#include <LUFA/Drivers/Board/Joystick.h> #include <LUFA/Drivers/Board/Joystick.h>
#include <LUFA/Drivers/USB/USB.h> #include <LUFA/Drivers/USB/USB.h>
#include <LUFA/Drivers/USB/Class/CDC.h> #include <LUFA/Drivers/USB/Class/CDC.h>
/* Macros: */ /* Macros: */
/** LED mask for the library LED driver, to indicate that the USB interface is not ready. */ /** LED mask for the library LED driver, to indicate that the USB interface is not ready. */
#define LEDMASK_USB_NOTREADY LEDS_LED1 #define LEDMASK_USB_NOTREADY LEDS_LED1
/** LED mask for the library LED driver, to indicate that the USB interface is enumerating. */ /** LED mask for the library LED driver, to indicate that the USB interface is enumerating. */
#define LEDMASK_USB_ENUMERATING (LEDS_LED2 | LEDS_LED3) #define LEDMASK_USB_ENUMERATING (LEDS_LED2 | LEDS_LED3)
/** LED mask for the library LED driver, to indicate that the USB interface is ready. */ /** LED mask for the library LED driver, to indicate that the USB interface is ready. */
#define LEDMASK_USB_READY (LEDS_LED2 | LEDS_LED4) #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. */ /** 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) #define LEDMASK_USB_ERROR (LEDS_LED1 | LEDS_LED3)
/* Function Prototypes: */ /* Function Prototypes: */
void SetupHardware(void); void SetupHardware(void);
void CheckJoystickMovement(void); void CheckJoystickMovement(void);
void EVENT_USB_Device_Connect(void); void EVENT_USB_Device_Connect(void);
void EVENT_USB_Device_Disconnect(void); void EVENT_USB_Device_Disconnect(void);
void EVENT_USB_Device_ConfigurationChanged(void); void EVENT_USB_Device_ConfigurationChanged(void);
void EVENT_USB_Device_UnhandledControlRequest(void); void EVENT_USB_Device_UnhandledControlRequest(void);
#endif #endif

View file

@ -1,85 +1,85 @@
/** \file /** \file
* *
* This file contains special DoxyGen information for the generation of the main page and other special * 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. * documentation pages. It is not a project source file.
*/ */
/** \mainpage Dual Communications Device Class (Dual Virtual Serial Port) Device /** \mainpage Dual Communications Device Class (Dual Virtual Serial Port) Device
* *
* \section SSec_Compat Demo Compatibility: * \section SSec_Compat Demo Compatibility:
* *
* The following list indicates what microcontrollers are compatible with this demo. * The following list indicates what microcontrollers are compatible with this demo.
* *
* - Series 7 USB AVRs * - Series 7 USB AVRs
* - Series 6 USB AVRs * - Series 6 USB AVRs
* - Series 4 USB AVRs * - Series 4 USB AVRs
* *
* \section SSec_Info USB Information: * \section SSec_Info USB Information:
* *
* The following table gives a rundown of the USB utilization of this demo. * The following table gives a rundown of the USB utilization of this demo.
* *
* <table> * <table>
* <tr> * <tr>
* <td><b>USB Mode:</b></td> * <td><b>USB Mode:</b></td>
* <td>Device</td> * <td>Device</td>
* </tr> * </tr>
* <tr> * <tr>
* <td><b>USB Class:</b></td> * <td><b>USB Class:</b></td>
* <td>Communications Device Class (CDC)</td> * <td>Communications Device Class (CDC)</td>
* </tr> * </tr>
* <tr> * <tr>
* <td><b>USB Subclass:</b></td> * <td><b>USB Subclass:</b></td>
* <td>Abstract Control Model (ACM)</td> * <td>Abstract Control Model (ACM)</td>
* </tr> * </tr>
* <tr> * <tr>
* <td><b>Relevant Standards:</b></td> * <td><b>Relevant Standards:</b></td>
* <td>USBIF CDC Class Standard</td> * <td>USBIF CDC Class Standard</td>
* </tr> * </tr>
* <tr> * <tr>
* <td><b>Relevant Standards:</b></td> * <td><b>Relevant Standards:</b></td>
* <td>USBIF Interface Association Descriptor ECN \n * <td>USBIF Interface Association Descriptor ECN \n
* USBIF CDC Class Standard</td> * USBIF CDC Class Standard</td>
* </tr> * </tr>
* <tr> * <tr>
* <td><b>Usable Speeds:</b></td> * <td><b>Usable Speeds:</b></td>
* <td>Full Speed Mode</td> * <td>Full Speed Mode</td>
* </tr> * </tr>
* </table> * </table>
* *
* \section SSec_Description Project Description: * \section SSec_Description Project Description:
* *
* Dual Communications Device Class demonstration application. * Dual Communications Device Class demonstration application.
* This gives a simple reference application for implementing * This gives a simple reference application for implementing
* a compound device with dual CDC functions acting as a pair * a compound device with dual CDC functions acting as a pair
* of virtual serial ports. This demo uses Interface Association * of virtual serial ports. This demo uses Interface Association
* Descriptors to link together the pair of related CDC * Descriptors to link together the pair of related CDC
* descriptors for each virtual serial port, which may not be * descriptors for each virtual serial port, which may not be
* supported in all OSes - Windows Vista is supported, as is * supported in all OSes - Windows Vista is supported, as is
* XP (although the latter may need a hotfix to function). * XP (although the latter may need a hotfix to function).
* *
* Joystick actions are transmitted to the host as strings * Joystick actions are transmitted to the host as strings
* through the first serial port. The device does not respond to * through the first serial port. The device does not respond to
* serial data sent from the host in the first serial port. * serial data sent from the host in the first serial port.
* *
* The second serial port echoes back data sent from the host. * The second serial port echoes back data sent from the host.
* *
* After running this demo for the first time on a new computer, * After running this demo for the first time on a new computer,
* you will need to supply the .INF file located in this demo * you will need to supply the .INF file located in this demo
* project's directory as the device's driver when running under * project's directory as the device's driver when running under
* Windows. This will enable Windows to use its inbuilt CDC drivers, * Windows. This will enable Windows to use its inbuilt CDC drivers,
* negating the need for custom drivers for the device. Other * negating the need for custom drivers for the device. Other
* Operating Systems should automatically use their own inbuilt * Operating Systems should automatically use their own inbuilt
* CDC-ACM drivers. * CDC-ACM drivers.
* *
* \section SSec_Options Project Options * \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. * The following defines can be found in this demo, which can control the demo behaviour when defined, or changed in value.
* *
* <table> * <table>
* <tr> * <tr>
* <td> * <td>
* None * None
* </td> * </td>
* </tr> * </tr>
* </table> * </table>
*/ */

View file

@ -1,106 +1,106 @@
;************************************************************ ;************************************************************
; Windows USB CDC ACM Setup File ; Windows USB CDC ACM Setup File
; Copyright (c) 2000 Microsoft Corporation ; Copyright (c) 2000 Microsoft Corporation
[Version] [Version]
Signature="$Windows NT$" Signature="$Windows NT$"
Class=Ports Class=Ports
ClassGuid={4D36E978-E325-11CE-BFC1-08002BE10318} ClassGuid={4D36E978-E325-11CE-BFC1-08002BE10318}
Provider=%MFGNAME% Provider=%MFGNAME%
LayoutFile=layout.inf LayoutFile=layout.inf
CatalogFile=%MFGFILENAME%.cat CatalogFile=%MFGFILENAME%.cat
DriverVer=11/15/2007,5.1.2600.0 DriverVer=11/15/2007,5.1.2600.0
[Manufacturer] [Manufacturer]
%MFGNAME%=DeviceList, NTamd64 %MFGNAME%=DeviceList, NTamd64
[DestinationDirs] [DestinationDirs]
DefaultDestDir=12 DefaultDestDir=12
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
; Windows 2000/XP/Vista-32bit Sections ; Windows 2000/XP/Vista-32bit Sections
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
[DriverInstall.nt] [DriverInstall.nt]
include=mdmcpq.inf include=mdmcpq.inf
CopyFiles=DriverCopyFiles.nt CopyFiles=DriverCopyFiles.nt
AddReg=DriverInstall.nt.AddReg AddReg=DriverInstall.nt.AddReg
[DriverCopyFiles.nt] [DriverCopyFiles.nt]
usbser.sys,,,0x20 usbser.sys,,,0x20
[DriverInstall.nt.AddReg] [DriverInstall.nt.AddReg]
HKR,,DevLoader,,*ntkern HKR,,DevLoader,,*ntkern
HKR,,NTMPDriver,,%DRIVERFILENAME%.sys HKR,,NTMPDriver,,%DRIVERFILENAME%.sys
HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider" HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider"
[DriverInstall.nt.Services] [DriverInstall.nt.Services]
AddService=usbser, 0x00000002, DriverService.nt AddService=usbser, 0x00000002, DriverService.nt
[DriverService.nt] [DriverService.nt]
DisplayName=%SERVICE% DisplayName=%SERVICE%
ServiceType=1 ServiceType=1
StartType=3 StartType=3
ErrorControl=1 ErrorControl=1
ServiceBinary=%12%\%DRIVERFILENAME%.sys ServiceBinary=%12%\%DRIVERFILENAME%.sys
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
; Vista-64bit Sections ; Vista-64bit Sections
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
[DriverInstall.NTamd64] [DriverInstall.NTamd64]
include=mdmcpq.inf include=mdmcpq.inf
CopyFiles=DriverCopyFiles.NTamd64 CopyFiles=DriverCopyFiles.NTamd64
AddReg=DriverInstall.NTamd64.AddReg AddReg=DriverInstall.NTamd64.AddReg
[DriverCopyFiles.NTamd64] [DriverCopyFiles.NTamd64]
%DRIVERFILENAME%.sys,,,0x20 %DRIVERFILENAME%.sys,,,0x20
[DriverInstall.NTamd64.AddReg] [DriverInstall.NTamd64.AddReg]
HKR,,DevLoader,,*ntkern HKR,,DevLoader,,*ntkern
HKR,,NTMPDriver,,%DRIVERFILENAME%.sys HKR,,NTMPDriver,,%DRIVERFILENAME%.sys
HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider" HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider"
[DriverInstall.NTamd64.Services] [DriverInstall.NTamd64.Services]
AddService=usbser, 0x00000002, DriverService.NTamd64 AddService=usbser, 0x00000002, DriverService.NTamd64
[DriverService.NTamd64] [DriverService.NTamd64]
DisplayName=%SERVICE% DisplayName=%SERVICE%
ServiceType=1 ServiceType=1
StartType=3 StartType=3
ErrorControl=1 ErrorControl=1
ServiceBinary=%12%\%DRIVERFILENAME%.sys ServiceBinary=%12%\%DRIVERFILENAME%.sys
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
; Vendor and Product ID Definitions ; Vendor and Product ID Definitions
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
; When developing your USB device, the VID and PID used in the PC side ; When developing your USB device, the VID and PID used in the PC side
; application program and the firmware on the microcontroller must match. ; application program and the firmware on the microcontroller must match.
; Modify the below line to use your VID and PID. Use the format as shown below. ; Modify the below line to use your VID and PID. Use the format as shown below.
; Note: One INF file can be used for multiple devices with different VID and PIDs. ; Note: One INF file can be used for multiple devices with different VID and PIDs.
; For each supported device, append ",USB\VID_xxxx&PID_yyyy" to the end of the line. ; For each supported device, append ",USB\VID_xxxx&PID_yyyy" to the end of the line.
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
[SourceDisksFiles] [SourceDisksFiles]
[SourceDisksNames] [SourceDisksNames]
[DeviceList] [DeviceList]
%DESCRIPTION%=DriverInstall, USB\VID_03EB&PID_204E&MI_00, USB\VID_03EB&PID_204E&MI_02 %DESCRIPTION%=DriverInstall, USB\VID_03EB&PID_204E&MI_00, USB\VID_03EB&PID_204E&MI_02
[DeviceList.NTamd64] [DeviceList.NTamd64]
%DESCRIPTION%=DriverInstall, USB\VID_03EB&PID_204E&MI_00, USB\VID_03EB&PID_204E&MI_02 %DESCRIPTION%=DriverInstall, USB\VID_03EB&PID_204E&MI_00, USB\VID_03EB&PID_204E&MI_02
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
; String Definitions ; String Definitions
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
;Modify these strings to customize your device ;Modify these strings to customize your device
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
[Strings] [Strings]
MFGFILENAME="CDC_vista" MFGFILENAME="CDC_vista"
DRIVERFILENAME ="usbser" DRIVERFILENAME ="usbser"
MFGNAME="http://www.fourwalledcubicle.com" MFGNAME="http://www.fourwalledcubicle.com"
INSTDISK="LUFA Dual CDC Driver Installer" INSTDISK="LUFA Dual CDC Driver Installer"
DESCRIPTION="Communications Port" DESCRIPTION="Communications Port"
SERVICE="USB RS-232 Emulation Driver" SERVICE="USB RS-232 Emulation Driver"

File diff suppressed because it is too large Load diff

View file

@ -1,240 +1,240 @@
/* /*
LUFA Library LUFA Library
Copyright (C) Dean Camera, 2010. Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com www.fourwalledcubicle.com
*/ */
/* /*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com) Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the advertising or publicity pertaining to distribution of the
software without specific, written prior permission. software without specific, written prior permission.
The author disclaim all warranties with regard to this The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action, in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of arising out of or in connection with the use or performance of
this software. this software.
*/ */
/** \file /** \file
* *
* USB Device Descriptors, for library use when in USB device mode. Descriptors are special * USB Device Descriptors, for library use when in USB device mode. Descriptors are special
* computer-readable structures which the host requests upon device enumeration, to determine * computer-readable structures which the host requests upon device enumeration, to determine
* the device's capabilities and functions. * the device's capabilities and functions.
*/ */
#include "Descriptors.h" #include "Descriptors.h"
/** HID class report descriptor. This is a special descriptor constructed with values from the /** HID class report descriptor. This is a special descriptor constructed with values from the
* USBIF HID class specification to describe the reports and capabilities of the HID device. This * USBIF HID class specification to describe the reports and capabilities of the HID device. This
* descriptor is parsed by the host and its contents used to determine what data (and in what encoding) * descriptor is parsed by the host and its contents used to determine what data (and in what encoding)
* the device will send, and what it may be sent back from the host. Refer to the HID specification for * the device will send, and what it may be sent back from the host. Refer to the HID specification for
* more details on HID report descriptors. * more details on HID report descriptors.
*/ */
USB_Descriptor_HIDReport_Datatype_t PROGMEM GenericReport[] = USB_Descriptor_HIDReport_Datatype_t PROGMEM GenericReport[] =
{ {
0x06, 0x9c, 0xff, /* Usage Page (Vendor Defined) */ 0x06, 0x9c, 0xff, /* Usage Page (Vendor Defined) */
0x09, 0x01, /* Usage (Vendor Defined) */ 0x09, 0x01, /* Usage (Vendor Defined) */
0xa1, 0x01, /* Collection (Vendor Defined) */ 0xa1, 0x01, /* Collection (Vendor Defined) */
0x09, 0x02, /* Usage (Vendor Defined) */ 0x09, 0x02, /* Usage (Vendor Defined) */
0x75, 0x08, /* Report Size (8) */ 0x75, 0x08, /* Report Size (8) */
0x95, GENERIC_REPORT_SIZE, /* Report Count (GENERIC_REPORT_SIZE) */ 0x95, GENERIC_REPORT_SIZE, /* Report Count (GENERIC_REPORT_SIZE) */
0x15, 0x80, /* Logical Minimum (-128) */ 0x15, 0x80, /* Logical Minimum (-128) */
0x25, 0x7F, /* Logical Maximum (127) */ 0x25, 0x7F, /* Logical Maximum (127) */
0x81, 0x02, /* Input (Data, Variable, Absolute) */ 0x81, 0x02, /* Input (Data, Variable, Absolute) */
0x09, 0x03, /* Usage (Vendor Defined) */ 0x09, 0x03, /* Usage (Vendor Defined) */
0x75, 0x08, /* Report Size (8) */ 0x75, 0x08, /* Report Size (8) */
0x95, GENERIC_REPORT_SIZE, /* Report Count (GENERIC_REPORT_SIZE) */ 0x95, GENERIC_REPORT_SIZE, /* Report Count (GENERIC_REPORT_SIZE) */
0x15, 0x00, /* Logical Minimum (0) */ 0x15, 0x00, /* Logical Minimum (0) */
0x25, 0xff, /* Logical Maximum (255) */ 0x25, 0xff, /* Logical Maximum (255) */
0x91, 0x02, /* Output (Data, Variable, Absolute) */ 0x91, 0x02, /* Output (Data, Variable, Absolute) */
0xc0 /* End Collection */ 0xc0 /* End Collection */
}; };
/** Device descriptor structure. This descriptor, located in FLASH memory, describes the overall /** Device descriptor structure. This descriptor, located in FLASH memory, describes the overall
* device characteristics, including the supported USB version, control endpoint size and the * device characteristics, including the supported USB version, control endpoint size and the
* number of device configurations. The descriptor is read out by the USB host when the enumeration * number of device configurations. The descriptor is read out by the USB host when the enumeration
* process begins. * process begins.
*/ */
USB_Descriptor_Device_t PROGMEM DeviceDescriptor = USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
{ {
.Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device}, .Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device},
.USBSpecification = VERSION_BCD(01.10), .USBSpecification = VERSION_BCD(01.10),
.Class = 0x00, .Class = 0x00,
.SubClass = 0x00, .SubClass = 0x00,
.Protocol = 0x00, .Protocol = 0x00,
.Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE, .Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE,
.VendorID = 0x03EB, .VendorID = 0x03EB,
.ProductID = 0x204F, .ProductID = 0x204F,
.ReleaseNumber = 0x0000, .ReleaseNumber = 0x0000,
.ManufacturerStrIndex = 0x01, .ManufacturerStrIndex = 0x01,
.ProductStrIndex = 0x02, .ProductStrIndex = 0x02,
.SerialNumStrIndex = NO_DESCRIPTOR, .SerialNumStrIndex = NO_DESCRIPTOR,
.NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS .NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS
}; };
/** Configuration descriptor structure. This descriptor, located in FLASH memory, describes the usage /** Configuration descriptor structure. This descriptor, located in FLASH memory, describes the usage
* of the device in one of its supported configurations, including information about any device interfaces * of the device in one of its supported configurations, including information about any device interfaces
* and endpoints. The descriptor is read out by the USB host during the enumeration process when selecting * and endpoints. The descriptor is read out by the USB host during the enumeration process when selecting
* a configuration so that the host may correctly communicate with the USB device. * a configuration so that the host may correctly communicate with the USB device.
*/ */
USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor = USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
{ {
.Config = .Config =
{ {
.Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration}, .Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration},
.TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t), .TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t),
.TotalInterfaces = 1, .TotalInterfaces = 1,
.ConfigurationNumber = 1, .ConfigurationNumber = 1,
.ConfigurationStrIndex = NO_DESCRIPTOR, .ConfigurationStrIndex = NO_DESCRIPTOR,
.ConfigAttributes = (USB_CONFIG_ATTR_BUSPOWERED | USB_CONFIG_ATTR_SELFPOWERED), .ConfigAttributes = (USB_CONFIG_ATTR_BUSPOWERED | USB_CONFIG_ATTR_SELFPOWERED),
.MaxPowerConsumption = USB_CONFIG_POWER_MA(100) .MaxPowerConsumption = USB_CONFIG_POWER_MA(100)
}, },
.HID_Interface = .HID_Interface =
{ {
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface}, .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
.InterfaceNumber = 0x00, .InterfaceNumber = 0x00,
.AlternateSetting = 0x00, .AlternateSetting = 0x00,
.TotalEndpoints = 1, .TotalEndpoints = 1,
.Class = 0x03, .Class = 0x03,
.SubClass = 0x00, .SubClass = 0x00,
.Protocol = HID_NON_BOOT_PROTOCOL, .Protocol = HID_NON_BOOT_PROTOCOL,
.InterfaceStrIndex = NO_DESCRIPTOR .InterfaceStrIndex = NO_DESCRIPTOR
}, },
.HID_GenericHID = .HID_GenericHID =
{ {
.Header = {.Size = sizeof(USB_HID_Descriptor_t), .Type = DTYPE_HID}, .Header = {.Size = sizeof(USB_HID_Descriptor_t), .Type = DTYPE_HID},
.HIDSpec = VERSION_BCD(01.11), .HIDSpec = VERSION_BCD(01.11),
.CountryCode = 0x00, .CountryCode = 0x00,
.TotalReportDescriptors = 1, .TotalReportDescriptors = 1,
.HIDReportType = DTYPE_Report, .HIDReportType = DTYPE_Report,
.HIDReportLength = sizeof(GenericReport) .HIDReportLength = sizeof(GenericReport)
}, },
.HID_ReportINEndpoint = .HID_ReportINEndpoint =
{ {
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint}, .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
.EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_IN | GENERIC_IN_EPNUM), .EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_IN | GENERIC_IN_EPNUM),
.Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
.EndpointSize = GENERIC_EPSIZE, .EndpointSize = GENERIC_EPSIZE,
.PollingIntervalMS = 0x0A .PollingIntervalMS = 0x0A
}, },
}; };
/** Language descriptor structure. This descriptor, located in FLASH memory, is returned when the host requests /** Language descriptor structure. This descriptor, located in FLASH memory, is returned when the host requests
* the string descriptor with index 0 (the first index). It is actually an array of 16-bit integers, which indicate * the string descriptor with index 0 (the first index). It is actually an array of 16-bit integers, which indicate
* via the language ID table available at USB.org what languages the device supports for its string descriptors. * via the language ID table available at USB.org what languages the device supports for its string descriptors.
*/ */
USB_Descriptor_String_t PROGMEM LanguageString = USB_Descriptor_String_t PROGMEM LanguageString =
{ {
.Header = {.Size = USB_STRING_LEN(1), .Type = DTYPE_String}, .Header = {.Size = USB_STRING_LEN(1), .Type = DTYPE_String},
.UnicodeString = {LANGUAGE_ID_ENG} .UnicodeString = {LANGUAGE_ID_ENG}
}; };
/** Manufacturer descriptor string. This is a Unicode string containing the manufacturer's details in human readable /** Manufacturer descriptor string. This is a Unicode string containing the manufacturer's details in human readable
* form, and is read out upon request by the host when the appropriate string ID is requested, listed in the Device * form, and is read out upon request by the host when the appropriate string ID is requested, listed in the Device
* Descriptor. * Descriptor.
*/ */
USB_Descriptor_String_t PROGMEM ManufacturerString = USB_Descriptor_String_t PROGMEM ManufacturerString =
{ {
.Header = {.Size = USB_STRING_LEN(11), .Type = DTYPE_String}, .Header = {.Size = USB_STRING_LEN(11), .Type = DTYPE_String},
.UnicodeString = L"Dean Camera" .UnicodeString = L"Dean Camera"
}; };
/** Product descriptor string. This is a Unicode string containing the product's details in human readable form, /** Product descriptor string. This is a Unicode string containing the product's details in human readable form,
* and is read out upon request by the host when the appropriate string ID is requested, listed in the Device * and is read out upon request by the host when the appropriate string ID is requested, listed in the Device
* Descriptor. * Descriptor.
*/ */
USB_Descriptor_String_t PROGMEM ProductString = USB_Descriptor_String_t PROGMEM ProductString =
{ {
.Header = {.Size = USB_STRING_LEN(21), .Type = DTYPE_String}, .Header = {.Size = USB_STRING_LEN(21), .Type = DTYPE_String},
.UnicodeString = L"LUFA Generic HID Demo" .UnicodeString = L"LUFA Generic HID Demo"
}; };
/** This function is called by the library when in device mode, and must be overridden (see library "USB Descriptors" /** This function is called by the library when in device mode, and must be overridden (see library "USB Descriptors"
* documentation) by the application code so that the address and size of a requested descriptor can be given * documentation) by the application code so that the address and size of a requested descriptor can be given
* to the USB library. When the device receives a Get Descriptor request on the control endpoint, this function * to the USB library. When the device receives a Get Descriptor request on the control endpoint, this function
* is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the * is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the
* USB host. * USB host.
*/ */
uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, void** const DescriptorAddress) uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, void** const DescriptorAddress)
{ {
const uint8_t DescriptorType = (wValue >> 8); const uint8_t DescriptorType = (wValue >> 8);
const uint8_t DescriptorNumber = (wValue & 0xFF); const uint8_t DescriptorNumber = (wValue & 0xFF);
void* Address = NULL; void* Address = NULL;
uint16_t Size = NO_DESCRIPTOR; uint16_t Size = NO_DESCRIPTOR;
switch (DescriptorType) switch (DescriptorType)
{ {
case DTYPE_Device: case DTYPE_Device:
Address = (void*)&DeviceDescriptor; Address = (void*)&DeviceDescriptor;
Size = sizeof(USB_Descriptor_Device_t); Size = sizeof(USB_Descriptor_Device_t);
break; break;
case DTYPE_Configuration: case DTYPE_Configuration:
Address = (void*)&ConfigurationDescriptor; Address = (void*)&ConfigurationDescriptor;
Size = sizeof(USB_Descriptor_Configuration_t); Size = sizeof(USB_Descriptor_Configuration_t);
break; break;
case DTYPE_String: case DTYPE_String:
switch (DescriptorNumber) switch (DescriptorNumber)
{ {
case 0x00: case 0x00:
Address = (void*)&LanguageString; Address = (void*)&LanguageString;
Size = pgm_read_byte(&LanguageString.Header.Size); Size = pgm_read_byte(&LanguageString.Header.Size);
break; break;
case 0x01: case 0x01:
Address = (void*)&ManufacturerString; Address = (void*)&ManufacturerString;
Size = pgm_read_byte(&ManufacturerString.Header.Size); Size = pgm_read_byte(&ManufacturerString.Header.Size);
break; break;
case 0x02: case 0x02:
Address = (void*)&ProductString; Address = (void*)&ProductString;
Size = pgm_read_byte(&ProductString.Header.Size); Size = pgm_read_byte(&ProductString.Header.Size);
break; break;
} }
break; break;
case DTYPE_HID: case DTYPE_HID:
Address = (void*)&ConfigurationDescriptor.HID_GenericHID; Address = (void*)&ConfigurationDescriptor.HID_GenericHID;
Size = sizeof(USB_HID_Descriptor_t); Size = sizeof(USB_HID_Descriptor_t);
break; break;
case DTYPE_Report: case DTYPE_Report:
Address = (void*)&GenericReport; Address = (void*)&GenericReport;
Size = sizeof(GenericReport); Size = sizeof(GenericReport);
break; break;
} }
*DescriptorAddress = Address; *DescriptorAddress = Address;
return Size; return Size;
} }

View file

@ -1,72 +1,72 @@
/* /*
LUFA Library LUFA Library
Copyright (C) Dean Camera, 2010. Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com www.fourwalledcubicle.com
*/ */
/* /*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com) Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the advertising or publicity pertaining to distribution of the
software without specific, written prior permission. software without specific, written prior permission.
The author disclaim all warranties with regard to this The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action, in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of arising out of or in connection with the use or performance of
this software. this software.
*/ */
/** \file /** \file
* *
* Header file for Descriptors.c. * Header file for Descriptors.c.
*/ */
#ifndef _DESCRIPTORS_H_ #ifndef _DESCRIPTORS_H_
#define _DESCRIPTORS_H_ #define _DESCRIPTORS_H_
/* Includes: */ /* Includes: */
#include <avr/pgmspace.h> #include <avr/pgmspace.h>
#include <LUFA/Drivers/USB/USB.h> #include <LUFA/Drivers/USB/USB.h>
#include <LUFA/Drivers/USB/Class/HID.h> #include <LUFA/Drivers/USB/Class/HID.h>
/* Type Defines: */ /* Type Defines: */
/** Type define for the device configuration descriptor structure. This must be defined in the /** Type define for the device configuration descriptor structure. This must be defined in the
* application code, as the configuration descriptor contains several sub-descriptors which * application code, as the configuration descriptor contains several sub-descriptors which
* vary between devices, and which describe the device's usage to the host. * vary between devices, and which describe the device's usage to the host.
*/ */
typedef struct typedef struct
{ {
USB_Descriptor_Configuration_Header_t Config; USB_Descriptor_Configuration_Header_t Config;
USB_Descriptor_Interface_t HID_Interface; USB_Descriptor_Interface_t HID_Interface;
USB_HID_Descriptor_t HID_GenericHID; USB_HID_Descriptor_t HID_GenericHID;
USB_Descriptor_Endpoint_t HID_ReportINEndpoint; USB_Descriptor_Endpoint_t HID_ReportINEndpoint;
} USB_Descriptor_Configuration_t; } USB_Descriptor_Configuration_t;
/* Macros: */ /* Macros: */
/** Endpoint number of the Generic HID reporting IN endpoint. */ /** Endpoint number of the Generic HID reporting IN endpoint. */
#define GENERIC_IN_EPNUM 1 #define GENERIC_IN_EPNUM 1
/** Size in bytes of the Generic HID reporting endpoint. */ /** Size in bytes of the Generic HID reporting endpoint. */
#define GENERIC_EPSIZE 8 #define GENERIC_EPSIZE 8
/** Size in bytes of the Generic HID reports (including report ID byte). */ /** Size in bytes of the Generic HID reports (including report ID byte). */
#define GENERIC_REPORT_SIZE 8 #define GENERIC_REPORT_SIZE 8
/* Function Prototypes: */ /* Function Prototypes: */
uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, void** const DescriptorAddress) uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, void** const DescriptorAddress)
ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3); ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3);
#endif #endif

File diff suppressed because it is too large Load diff

View file

@ -1,171 +1,171 @@
/* /*
LUFA Library LUFA Library
Copyright (C) Dean Camera, 2010. Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com www.fourwalledcubicle.com
*/ */
/* /*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com) Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the advertising or publicity pertaining to distribution of the
software without specific, written prior permission. software without specific, written prior permission.
The author disclaim all warranties with regard to this The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action, in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of arising out of or in connection with the use or performance of
this software. this software.
*/ */
/** \file /** \file
* *
* Main source file for the GenericHID demo. This file contains the main tasks of * Main source file for the GenericHID demo. This file contains the main tasks of
* the demo and is responsible for the initial application hardware configuration. * the demo and is responsible for the initial application hardware configuration.
*/ */
#include "GenericHID.h" #include "GenericHID.h"
/** Buffer to hold the previously generated HID report, for comparison purposes inside the HID class driver. */ /** Buffer to hold the previously generated HID report, for comparison purposes inside the HID class driver. */
uint8_t PrevHIDReportBuffer[GENERIC_REPORT_SIZE]; uint8_t PrevHIDReportBuffer[GENERIC_REPORT_SIZE];
/** Structure to contain reports from the host, so that they can be echoed back upon request */ /** Structure to contain reports from the host, so that they can be echoed back upon request */
struct struct
{ {
uint8_t ReportID; uint8_t ReportID;
uint16_t ReportSize; uint16_t ReportSize;
uint8_t ReportData[GENERIC_REPORT_SIZE]; uint8_t ReportData[GENERIC_REPORT_SIZE];
} HIDReportEcho; } HIDReportEcho;
/** LUFA HID Class driver interface configuration and state information. This structure is /** 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 * passed to all HID Class driver functions, so that multiple instances of the same class
* within a device can be differentiated from one another. * within a device can be differentiated from one another.
*/ */
USB_ClassInfo_HID_Device_t Generic_HID_Interface = USB_ClassInfo_HID_Device_t Generic_HID_Interface =
{ {
.Config = .Config =
{ {
.InterfaceNumber = 0, .InterfaceNumber = 0,
.ReportINEndpointNumber = GENERIC_IN_EPNUM, .ReportINEndpointNumber = GENERIC_IN_EPNUM,
.ReportINEndpointSize = GENERIC_EPSIZE, .ReportINEndpointSize = GENERIC_EPSIZE,
.ReportINEndpointDoubleBank = false, .ReportINEndpointDoubleBank = false,
.PrevReportINBuffer = PrevHIDReportBuffer, .PrevReportINBuffer = PrevHIDReportBuffer,
.PrevReportINBufferSize = sizeof(PrevHIDReportBuffer), .PrevReportINBufferSize = sizeof(PrevHIDReportBuffer),
}, },
}; };
/** Main program entry point. This routine contains the overall program flow, including initial /** Main program entry point. This routine contains the overall program flow, including initial
* setup of all components and the main program loop. * setup of all components and the main program loop.
*/ */
int main(void) int main(void)
{ {
SetupHardware(); SetupHardware();
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY); LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
sei(); sei();
for (;;) for (;;)
{ {
HID_Device_USBTask(&Generic_HID_Interface); HID_Device_USBTask(&Generic_HID_Interface);
USB_USBTask(); USB_USBTask();
} }
} }
/** Configures the board hardware and chip peripherals for the demo's functionality. */ /** Configures the board hardware and chip peripherals for the demo's functionality. */
void SetupHardware(void) void SetupHardware(void)
{ {
/* Disable watchdog if enabled by bootloader/fuses */ /* Disable watchdog if enabled by bootloader/fuses */
MCUSR &= ~(1 << WDRF); MCUSR &= ~(1 << WDRF);
wdt_disable(); wdt_disable();
/* Disable clock division */ /* Disable clock division */
clock_prescale_set(clock_div_1); clock_prescale_set(clock_div_1);
/* Hardware Initialization */ /* Hardware Initialization */
LEDs_Init(); LEDs_Init();
USB_Init(); USB_Init();
} }
/** Event handler for the library USB Connection event. */ /** Event handler for the library USB Connection event. */
void EVENT_USB_Device_Connect(void) void EVENT_USB_Device_Connect(void)
{ {
LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING); LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
} }
/** Event handler for the library USB Disconnection event. */ /** Event handler for the library USB Disconnection event. */
void EVENT_USB_Device_Disconnect(void) void EVENT_USB_Device_Disconnect(void)
{ {
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY); LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
} }
/** Event handler for the library USB Configuration Changed event. */ /** Event handler for the library USB Configuration Changed event. */
void EVENT_USB_Device_ConfigurationChanged(void) void EVENT_USB_Device_ConfigurationChanged(void)
{ {
LEDs_SetAllLEDs(LEDMASK_USB_READY); LEDs_SetAllLEDs(LEDMASK_USB_READY);
if (!(HID_Device_ConfigureEndpoints(&Generic_HID_Interface))) if (!(HID_Device_ConfigureEndpoints(&Generic_HID_Interface)))
LEDs_SetAllLEDs(LEDMASK_USB_ERROR); LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
USB_Device_EnableSOFEvents(); USB_Device_EnableSOFEvents();
} }
/** Event handler for the library USB Unhandled Control Request event. */ /** Event handler for the library USB Unhandled Control Request event. */
void EVENT_USB_Device_UnhandledControlRequest(void) void EVENT_USB_Device_UnhandledControlRequest(void)
{ {
HID_Device_ProcessControlRequest(&Generic_HID_Interface); HID_Device_ProcessControlRequest(&Generic_HID_Interface);
} }
/** Event handler for the USB device Start Of Frame event. */ /** Event handler for the USB device Start Of Frame event. */
void EVENT_USB_Device_StartOfFrame(void) void EVENT_USB_Device_StartOfFrame(void)
{ {
HID_Device_MillisecondElapsed(&Generic_HID_Interface); HID_Device_MillisecondElapsed(&Generic_HID_Interface);
} }
/** HID class driver callback function for the creation of HID reports to the host. /** HID class driver callback function for the creation of HID reports to the host.
* *
* \param[in] HIDInterfaceInfo Pointer to the HID class interface configuration structure being referenced * \param[in] HIDInterfaceInfo Pointer to the HID class interface configuration structure being referenced
* \param[in,out] ReportID Report ID requested by the host if non-zero, otherwise callback should set to the generated report ID * \param[in,out] ReportID Report ID requested by the host if non-zero, otherwise callback should set to the generated report ID
* \param[in] ReportType Type of the report to create, either REPORT_ITEM_TYPE_In or REPORT_ITEM_TYPE_Feature * \param[in] ReportType Type of the report to create, either REPORT_ITEM_TYPE_In or REPORT_ITEM_TYPE_Feature
* \param[out] ReportData Pointer to a buffer where the created report should be stored * \param[out] ReportData Pointer to a buffer where the created report should be stored
* \param[out] ReportSize Number of bytes written in the report (or zero if no report is to be sent * \param[out] ReportSize Number of bytes written in the report (or zero if no report is to be sent
* *
* \return Boolean true to force the sending of the report, false to let the library determine if it needs to be sent * \return Boolean true to force the sending of the report, false to let the library determine if it needs to be sent
*/ */
bool CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, uint8_t* const ReportID, bool CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, uint8_t* const ReportID,
const uint8_t ReportType, void* ReportData, uint16_t* ReportSize) const uint8_t ReportType, void* ReportData, uint16_t* ReportSize)
{ {
if (HIDReportEcho.ReportID) if (HIDReportEcho.ReportID)
*ReportID = HIDReportEcho.ReportID; *ReportID = HIDReportEcho.ReportID;
memcpy(ReportData, HIDReportEcho.ReportData, HIDReportEcho.ReportSize); memcpy(ReportData, HIDReportEcho.ReportData, HIDReportEcho.ReportSize);
*ReportSize = HIDReportEcho.ReportSize; *ReportSize = HIDReportEcho.ReportSize;
return true; return true;
} }
/** HID class driver callback function for the processing of HID reports from the host. /** HID class driver callback function for the processing of HID reports from the host.
* *
* \param[in] HIDInterfaceInfo Pointer to the HID class interface configuration structure being referenced * \param[in] HIDInterfaceInfo Pointer to the HID class interface configuration structure being referenced
* \param[in] ReportID Report ID of the received report from the host * \param[in] ReportID Report ID of the received report from the host
* \param[in] ReportData Pointer to a buffer where the created report has been stored * \param[in] ReportData Pointer to a buffer where the created report has been stored
* \param[in] ReportSize Size in bytes of the received HID report * \param[in] ReportSize Size in bytes of the received HID report
*/ */
void CALLBACK_HID_Device_ProcessHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, const uint8_t ReportID, void CALLBACK_HID_Device_ProcessHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, const uint8_t ReportID,
const void* ReportData, const uint16_t ReportSize) const void* ReportData, const uint16_t ReportSize)
{ {
HIDReportEcho.ReportID = ReportID; HIDReportEcho.ReportID = ReportID;
HIDReportEcho.ReportSize = ReportSize; HIDReportEcho.ReportSize = ReportSize;
memcpy(HIDReportEcho.ReportData, ReportData, ReportSize); memcpy(HIDReportEcho.ReportData, ReportData, ReportSize);
} }

View file

@ -1,80 +1,80 @@
/* /*
LUFA Library LUFA Library
Copyright (C) Dean Camera, 2010. Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com www.fourwalledcubicle.com
*/ */
/* /*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com) Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the advertising or publicity pertaining to distribution of the
software without specific, written prior permission. software without specific, written prior permission.
The author disclaim all warranties with regard to this The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action, in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of arising out of or in connection with the use or performance of
this software. this software.
*/ */
/** \file /** \file
* *
* Header file for GenericHID.c. * Header file for GenericHID.c.
*/ */
#ifndef _GENERICHID_H_ #ifndef _GENERICHID_H_
#define _GENERICHID_H_ #define _GENERICHID_H_
/* Includes: */ /* Includes: */
#include <avr/io.h> #include <avr/io.h>
#include <avr/wdt.h> #include <avr/wdt.h>
#include <avr/power.h> #include <avr/power.h>
#include <avr/interrupt.h> #include <avr/interrupt.h>
#include <string.h> #include <string.h>
#include "Descriptors.h" #include "Descriptors.h"
#include <LUFA/Version.h> #include <LUFA/Version.h>
#include <LUFA/Drivers/Board/LEDs.h> #include <LUFA/Drivers/Board/LEDs.h>
#include <LUFA/Drivers/USB/USB.h> #include <LUFA/Drivers/USB/USB.h>
#include <LUFA/Drivers/USB/Class/HID.h> #include <LUFA/Drivers/USB/Class/HID.h>
/* Macros: */ /* Macros: */
/** LED mask for the library LED driver, to indicate that the USB interface is not ready. */ /** LED mask for the library LED driver, to indicate that the USB interface is not ready. */
#define LEDMASK_USB_NOTREADY LEDS_LED1 #define LEDMASK_USB_NOTREADY LEDS_LED1
/** LED mask for the library LED driver, to indicate that the USB interface is enumerating. */ /** LED mask for the library LED driver, to indicate that the USB interface is enumerating. */
#define LEDMASK_USB_ENUMERATING (LEDS_LED2 | LEDS_LED3) #define LEDMASK_USB_ENUMERATING (LEDS_LED2 | LEDS_LED3)
/** LED mask for the library LED driver, to indicate that the USB interface is ready. */ /** LED mask for the library LED driver, to indicate that the USB interface is ready. */
#define LEDMASK_USB_READY (LEDS_LED2 | LEDS_LED4) #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. */ /** 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) #define LEDMASK_USB_ERROR (LEDS_LED1 | LEDS_LED3)
/* Function Prototypes: */ /* Function Prototypes: */
void SetupHardware(void); void SetupHardware(void);
void EVENT_USB_Device_Connect(void); void EVENT_USB_Device_Connect(void);
void EVENT_USB_Device_Disconnect(void); void EVENT_USB_Device_Disconnect(void);
void EVENT_USB_Device_ConfigurationChanged(void); void EVENT_USB_Device_ConfigurationChanged(void);
void EVENT_USB_Device_UnhandledControlRequest(void); void EVENT_USB_Device_UnhandledControlRequest(void);
void EVENT_USB_Device_StartOfFrame(void); void EVENT_USB_Device_StartOfFrame(void);
bool CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, uint8_t* const ReportID, bool CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, uint8_t* const ReportID,
const uint8_t ReportType, void* ReportData, uint16_t* ReportSize); const uint8_t ReportType, void* ReportData, uint16_t* ReportSize);
void CALLBACK_HID_Device_ProcessHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, const uint8_t ReportID, void CALLBACK_HID_Device_ProcessHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, const uint8_t ReportID,
const void* ReportData, const uint16_t ReportSize); const void* ReportData, const uint16_t ReportSize);
#endif #endif

View file

@ -1,75 +1,75 @@
/** \file /** \file
* *
* This file contains special DoxyGen information for the generation of the main page and other special * 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. * documentation pages. It is not a project source file.
*/ */
/** \mainpage Generic HID Device /** \mainpage Generic HID Device
* *
* \section SSec_Compat Demo Compatibility: * \section SSec_Compat Demo Compatibility:
* *
* The following list indicates what microcontrollers are compatible with this demo. * The following list indicates what microcontrollers are compatible with this demo.
* *
* - Series 7 USB AVRs * - Series 7 USB AVRs
* - Series 6 USB AVRs * - Series 6 USB AVRs
* - Series 4 USB AVRs * - Series 4 USB AVRs
* - Series 2 USB AVRs * - Series 2 USB AVRs
* *
* \section SSec_Info USB Information: * \section SSec_Info USB Information:
* *
* The following table gives a rundown of the USB utilization of this demo. * The following table gives a rundown of the USB utilization of this demo.
* *
* <table> * <table>
* <tr> * <tr>
* <td><b>USB Mode:</b></td> * <td><b>USB Mode:</b></td>
* <td>Device</td> * <td>Device</td>
* </tr> * </tr>
* <tr> * <tr>
* <td><b>USB Class:</b></td> * <td><b>USB Class:</b></td>
* <td>Human Interface Device (HID)</td> * <td>Human Interface Device (HID)</td>
* </tr> * </tr>
* <tr> * <tr>
* <td><b>USB Subclass:</b></td> * <td><b>USB Subclass:</b></td>
* <td>N/A</td> * <td>N/A</td>
* </tr> * </tr>
* <tr> * <tr>
* <td><b>Relevant Standards:</b></td> * <td><b>Relevant Standards:</b></td>
* <td>USBIF HID Specification \n * <td>USBIF HID Specification \n
* USBIF HID Usage Tables</td> * USBIF HID Usage Tables</td>
* </tr> * </tr>
* <tr> * <tr>
* <td><b>Usable Speeds:</b></td> * <td><b>Usable Speeds:</b></td>
* <td>Low Speed Mode \n * <td>Low Speed Mode \n
* Full Speed Mode</td> * Full Speed Mode</td>
* </tr> * </tr>
* </table> * </table>
* *
* \section SSec_Description Project Description: * \section SSec_Description Project Description:
* *
* Generic HID device demonstration application. This gives a simple reference application * Generic HID device demonstration application. This gives a simple reference application
* for implementing a generic HID device, using the basic USB HID drivers in all modern * for implementing a generic HID device, using the basic USB HID drivers in all modern
* OSes (i.e. no special drivers required). By default it accepts and sends up to 8 byte reports * OSes (i.e. no special drivers required). By default it accepts and sends up to 8 byte reports
* to and from a USB Host, and transmits the last sent report back to the host. * to and from a USB Host, and transmits the last sent report back to the host.
* *
* On start-up the system will automatically enumerate and function as a vendor HID device. * On start-up the system will automatically enumerate and function as a vendor HID device.
* When controlled by a custom HID class application, reports can be sent and received by * When controlled by a custom HID class application, reports can be sent and received by
* both the standard data endpoint and control request methods defined in the HID specification. * both the standard data endpoint and control request methods defined in the HID specification.
* *
* \section SSec_Options Project Options * \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. * The following defines can be found in this demo, which can control the demo behaviour when defined, or changed in value.
* *
* <table> * <table>
* <tr> * <tr>
* <td><b>Define Name:</b></td> * <td><b>Define Name:</b></td>
* <td><b>Location:</b></td> * <td><b>Location:</b></td>
* <td><b>Description:</b></td> * <td><b>Description:</b></td>
* </tr> * </tr>
* <tr> * <tr>
* <td>GENERIC_REPORT_SIZE</td> * <td>GENERIC_REPORT_SIZE</td>
* <td>Descriptors.h</td> * <td>Descriptors.h</td>
* <td>This token defines the size of the device reports, both sent and received. The value must be an * <td>This token defines the size of the device reports, both sent and received. The value must be an
* integer ranging from 1 to 255.</td> * integer ranging from 1 to 255.</td>
* </tr> * </tr>
* </table> * </table>
*/ */

File diff suppressed because it is too large Load diff

View file

@ -1,250 +1,250 @@
/* /*
LUFA Library LUFA Library
Copyright (C) Dean Camera, 2010. Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com www.fourwalledcubicle.com
*/ */
/* /*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com) Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the advertising or publicity pertaining to distribution of the
software without specific, written prior permission. software without specific, written prior permission.
The author disclaim all warranties with regard to this The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action, in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of arising out of or in connection with the use or performance of
this software. this software.
*/ */
/** \file /** \file
* *
* USB Device Descriptors, for library use when in USB device mode. Descriptors are special * USB Device Descriptors, for library use when in USB device mode. Descriptors are special
* computer-readable structures which the host requests upon device enumeration, to determine * computer-readable structures which the host requests upon device enumeration, to determine
* the device's capabilities and functions. * the device's capabilities and functions.
*/ */
#include "Descriptors.h" #include "Descriptors.h"
/** HID class report descriptor. This is a special descriptor constructed with values from the /** HID class report descriptor. This is a special descriptor constructed with values from the
* USBIF HID class specification to describe the reports and capabilities of the HID device. This * USBIF HID class specification to describe the reports and capabilities of the HID device. This
* descriptor is parsed by the host and its contents used to determine what data (and in what encoding) * descriptor is parsed by the host and its contents used to determine what data (and in what encoding)
* the device will send, and what it may be sent back from the host. Refer to the HID specification for * the device will send, and what it may be sent back from the host. Refer to the HID specification for
* more details on HID report descriptors. * more details on HID report descriptors.
*/ */
USB_Descriptor_HIDReport_Datatype_t PROGMEM JoystickReport[] = USB_Descriptor_HIDReport_Datatype_t PROGMEM JoystickReport[] =
{ {
0x05, 0x01, /* Usage Page (Generic Desktop) */ 0x05, 0x01, /* Usage Page (Generic Desktop) */
0x09, 0x04, /* Usage (Joystick) */ 0x09, 0x04, /* Usage (Joystick) */
0xa1, 0x01, /* Collection (Application) */ 0xa1, 0x01, /* Collection (Application) */
0x09, 0x01, /* Usage (Pointer) */ 0x09, 0x01, /* Usage (Pointer) */
0xa1, 0x00, /* Collection (Physical) */ 0xa1, 0x00, /* Collection (Physical) */
0x05, 0x01, /* Usage Page (Generic Desktop) */ 0x05, 0x01, /* Usage Page (Generic Desktop) */
0x09, 0x30, /* Usage (X) */ 0x09, 0x30, /* Usage (X) */
0x09, 0x31, /* Usage (Y) */ 0x09, 0x31, /* Usage (Y) */
0x15, 0x9c, /* Logical Minimum (-100) */ 0x15, 0x9c, /* Logical Minimum (-100) */
0x25, 0x64, /* Logical Maximum (100) */ 0x25, 0x64, /* Logical Maximum (100) */
0x75, 0x08, /* Report Size (8) */ 0x75, 0x08, /* Report Size (8) */
0x95, 0x02, /* Report Count (2) */ 0x95, 0x02, /* Report Count (2) */
0x81, 0x82, /* Input (Data, Variable, Absolute, Volatile) */ 0x81, 0x82, /* Input (Data, Variable, Absolute, Volatile) */
0xc0, /* End Collection */ 0xc0, /* End Collection */
0x05, 0x09, /* Usage Page (Button) */ 0x05, 0x09, /* Usage Page (Button) */
0x09, 0x02, /* Usage (Button 2) */ 0x09, 0x02, /* Usage (Button 2) */
0x09, 0x01, /* Usage (Button 1) */ 0x09, 0x01, /* Usage (Button 1) */
0x15, 0x00, /* Logical Minimum (0) */ 0x15, 0x00, /* Logical Minimum (0) */
0x25, 0x01, /* Logical Maximum (1) */ 0x25, 0x01, /* Logical Maximum (1) */
0x75, 0x01, /* Report Size (1) */ 0x75, 0x01, /* Report Size (1) */
0x95, 0x02, /* Report Count (2) */ 0x95, 0x02, /* Report Count (2) */
0x81, 0x02, /* Input (Data, Variable, Absolute) */ 0x81, 0x02, /* Input (Data, Variable, Absolute) */
0x75, 0x06, /* Report Size (6) */ 0x75, 0x06, /* Report Size (6) */
0x95, 0x01, /* Report Count (1) */ 0x95, 0x01, /* Report Count (1) */
0x81, 0x01, /* Input (Constant) */ 0x81, 0x01, /* Input (Constant) */
0xc0 /* End Collection */ 0xc0 /* End Collection */
}; };
/** Device descriptor structure. This descriptor, located in FLASH memory, describes the overall /** Device descriptor structure. This descriptor, located in FLASH memory, describes the overall
* device characteristics, including the supported USB version, control endpoint size and the * device characteristics, including the supported USB version, control endpoint size and the
* number of device configurations. The descriptor is read out by the USB host when the enumeration * number of device configurations. The descriptor is read out by the USB host when the enumeration
* process begins. * process begins.
*/ */
USB_Descriptor_Device_t PROGMEM DeviceDescriptor = USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
{ {
.Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device}, .Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device},
.USBSpecification = VERSION_BCD(01.10), .USBSpecification = VERSION_BCD(01.10),
.Class = 0x00, .Class = 0x00,
.SubClass = 0x00, .SubClass = 0x00,
.Protocol = 0x00, .Protocol = 0x00,
.Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE, .Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE,
.VendorID = 0x03EB, .VendorID = 0x03EB,
.ProductID = 0x2043, .ProductID = 0x2043,
.ReleaseNumber = 0x0000, .ReleaseNumber = 0x0000,
.ManufacturerStrIndex = 0x01, .ManufacturerStrIndex = 0x01,
.ProductStrIndex = 0x02, .ProductStrIndex = 0x02,
.SerialNumStrIndex = NO_DESCRIPTOR, .SerialNumStrIndex = NO_DESCRIPTOR,
.NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS .NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS
}; };
/** Configuration descriptor structure. This descriptor, located in FLASH memory, describes the usage /** Configuration descriptor structure. This descriptor, located in FLASH memory, describes the usage
* of the device in one of its supported configurations, including information about any device interfaces * of the device in one of its supported configurations, including information about any device interfaces
* and endpoints. The descriptor is read out by the USB host during the enumeration process when selecting * and endpoints. The descriptor is read out by the USB host during the enumeration process when selecting
* a configuration so that the host may correctly communicate with the USB device. * a configuration so that the host may correctly communicate with the USB device.
*/ */
USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor = USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
{ {
.Config = .Config =
{ {
.Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration}, .Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration},
.TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t), .TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t),
.TotalInterfaces = 1, .TotalInterfaces = 1,
.ConfigurationNumber = 1, .ConfigurationNumber = 1,
.ConfigurationStrIndex = NO_DESCRIPTOR, .ConfigurationStrIndex = NO_DESCRIPTOR,
.ConfigAttributes = (USB_CONFIG_ATTR_BUSPOWERED | USB_CONFIG_ATTR_SELFPOWERED), .ConfigAttributes = (USB_CONFIG_ATTR_BUSPOWERED | USB_CONFIG_ATTR_SELFPOWERED),
.MaxPowerConsumption = USB_CONFIG_POWER_MA(100) .MaxPowerConsumption = USB_CONFIG_POWER_MA(100)
}, },
.HID_Interface = .HID_Interface =
{ {
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface}, .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
.InterfaceNumber = 0x00, .InterfaceNumber = 0x00,
.AlternateSetting = 0x00, .AlternateSetting = 0x00,
.TotalEndpoints = 1, .TotalEndpoints = 1,
.Class = 0x03, .Class = 0x03,
.SubClass = 0x00, .SubClass = 0x00,
.Protocol = HID_NON_BOOT_PROTOCOL, .Protocol = HID_NON_BOOT_PROTOCOL,
.InterfaceStrIndex = NO_DESCRIPTOR .InterfaceStrIndex = NO_DESCRIPTOR
}, },
.HID_JoystickHID = .HID_JoystickHID =
{ {
.Header = {.Size = sizeof(USB_HID_Descriptor_t), .Type = DTYPE_HID}, .Header = {.Size = sizeof(USB_HID_Descriptor_t), .Type = DTYPE_HID},
.HIDSpec = VERSION_BCD(01.11), .HIDSpec = VERSION_BCD(01.11),
.CountryCode = 0x00, .CountryCode = 0x00,
.TotalReportDescriptors = 1, .TotalReportDescriptors = 1,
.HIDReportType = DTYPE_Report, .HIDReportType = DTYPE_Report,
.HIDReportLength = sizeof(JoystickReport) .HIDReportLength = sizeof(JoystickReport)
}, },
.HID_ReportINEndpoint = .HID_ReportINEndpoint =
{ {
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint}, .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
.EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_IN | JOYSTICK_EPNUM), .EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_IN | JOYSTICK_EPNUM),
.Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
.EndpointSize = JOYSTICK_EPSIZE, .EndpointSize = JOYSTICK_EPSIZE,
.PollingIntervalMS = 0x0A .PollingIntervalMS = 0x0A
} }
}; };
/** Language descriptor structure. This descriptor, located in FLASH memory, is returned when the host requests /** Language descriptor structure. This descriptor, located in FLASH memory, is returned when the host requests
* the string descriptor with index 0 (the first index). It is actually an array of 16-bit integers, which indicate * the string descriptor with index 0 (the first index). It is actually an array of 16-bit integers, which indicate
* via the language ID table available at USB.org what languages the device supports for its string descriptors. * via the language ID table available at USB.org what languages the device supports for its string descriptors.
*/ */
USB_Descriptor_String_t PROGMEM LanguageString = USB_Descriptor_String_t PROGMEM LanguageString =
{ {
.Header = {.Size = USB_STRING_LEN(1), .Type = DTYPE_String}, .Header = {.Size = USB_STRING_LEN(1), .Type = DTYPE_String},
.UnicodeString = {LANGUAGE_ID_ENG} .UnicodeString = {LANGUAGE_ID_ENG}
}; };
/** Manufacturer descriptor string. This is a Unicode string containing the manufacturer's details in human readable /** Manufacturer descriptor string. This is a Unicode string containing the manufacturer's details in human readable
* form, and is read out upon request by the host when the appropriate string ID is requested, listed in the Device * form, and is read out upon request by the host when the appropriate string ID is requested, listed in the Device
* Descriptor. * Descriptor.
*/ */
USB_Descriptor_String_t PROGMEM ManufacturerString = USB_Descriptor_String_t PROGMEM ManufacturerString =
{ {
.Header = {.Size = USB_STRING_LEN(11), .Type = DTYPE_String}, .Header = {.Size = USB_STRING_LEN(11), .Type = DTYPE_String},
.UnicodeString = L"Dean Camera" .UnicodeString = L"Dean Camera"
}; };
/** Product descriptor string. This is a Unicode string containing the product's details in human readable form, /** Product descriptor string. This is a Unicode string containing the product's details in human readable form,
* and is read out upon request by the host when the appropriate string ID is requested, listed in the Device * and is read out upon request by the host when the appropriate string ID is requested, listed in the Device
* Descriptor. * Descriptor.
*/ */
USB_Descriptor_String_t PROGMEM ProductString = USB_Descriptor_String_t PROGMEM ProductString =
{ {
.Header = {.Size = USB_STRING_LEN(18), .Type = DTYPE_String}, .Header = {.Size = USB_STRING_LEN(18), .Type = DTYPE_String},
.UnicodeString = L"LUFA Joystick Demo" .UnicodeString = L"LUFA Joystick Demo"
}; };
/** This function is called by the library when in device mode, and must be overridden (see library "USB Descriptors" /** This function is called by the library when in device mode, and must be overridden (see library "USB Descriptors"
* documentation) by the application code so that the address and size of a requested descriptor can be given * documentation) by the application code so that the address and size of a requested descriptor can be given
* to the USB library. When the device receives a Get Descriptor request on the control endpoint, this function * to the USB library. When the device receives a Get Descriptor request on the control endpoint, this function
* is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the * is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the
* USB host. * USB host.
*/ */
uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, void** const DescriptorAddress) uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, void** const DescriptorAddress)
{ {
const uint8_t DescriptorType = (wValue >> 8); const uint8_t DescriptorType = (wValue >> 8);
const uint8_t DescriptorNumber = (wValue & 0xFF); const uint8_t DescriptorNumber = (wValue & 0xFF);
void* Address = NULL; void* Address = NULL;
uint16_t Size = NO_DESCRIPTOR; uint16_t Size = NO_DESCRIPTOR;
switch (DescriptorType) switch (DescriptorType)
{ {
case DTYPE_Device: case DTYPE_Device:
Address = (void*)&DeviceDescriptor; Address = (void*)&DeviceDescriptor;
Size = sizeof(USB_Descriptor_Device_t); Size = sizeof(USB_Descriptor_Device_t);
break; break;
case DTYPE_Configuration: case DTYPE_Configuration:
Address = (void*)&ConfigurationDescriptor; Address = (void*)&ConfigurationDescriptor;
Size = sizeof(USB_Descriptor_Configuration_t); Size = sizeof(USB_Descriptor_Configuration_t);
break; break;
case DTYPE_String: case DTYPE_String:
switch (DescriptorNumber) switch (DescriptorNumber)
{ {
case 0x00: case 0x00:
Address = (void*)&LanguageString; Address = (void*)&LanguageString;
Size = pgm_read_byte(&LanguageString.Header.Size); Size = pgm_read_byte(&LanguageString.Header.Size);
break; break;
case 0x01: case 0x01:
Address = (void*)&ManufacturerString; Address = (void*)&ManufacturerString;
Size = pgm_read_byte(&ManufacturerString.Header.Size); Size = pgm_read_byte(&ManufacturerString.Header.Size);
break; break;
case 0x02: case 0x02:
Address = (void*)&ProductString; Address = (void*)&ProductString;
Size = pgm_read_byte(&ProductString.Header.Size); Size = pgm_read_byte(&ProductString.Header.Size);
break; break;
} }
break; break;
case DTYPE_HID: case DTYPE_HID:
Address = (void*)&ConfigurationDescriptor.HID_JoystickHID; Address = (void*)&ConfigurationDescriptor.HID_JoystickHID;
Size = sizeof(USB_HID_Descriptor_t); Size = sizeof(USB_HID_Descriptor_t);
break; break;
case DTYPE_Report: case DTYPE_Report:
Address = (void*)&JoystickReport; Address = (void*)&JoystickReport;
Size = sizeof(JoystickReport); Size = sizeof(JoystickReport);
break; break;
} }
*DescriptorAddress = Address; *DescriptorAddress = Address;
return Size; return Size;
} }

View file

@ -1,69 +1,69 @@
/* /*
LUFA Library LUFA Library
Copyright (C) Dean Camera, 2010. Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com www.fourwalledcubicle.com
*/ */
/* /*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com) Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the advertising or publicity pertaining to distribution of the
software without specific, written prior permission. software without specific, written prior permission.
The author disclaim all warranties with regard to this The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action, in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of arising out of or in connection with the use or performance of
this software. this software.
*/ */
/** \file /** \file
* *
* Header file for Descriptors.c. * Header file for Descriptors.c.
*/ */
#ifndef _DESCRIPTORS_H_ #ifndef _DESCRIPTORS_H_
#define _DESCRIPTORS_H_ #define _DESCRIPTORS_H_
/* Includes: */ /* Includes: */
#include <avr/pgmspace.h> #include <avr/pgmspace.h>
#include <LUFA/Drivers/USB/USB.h> #include <LUFA/Drivers/USB/USB.h>
#include <LUFA/Drivers/USB/Class/HID.h> #include <LUFA/Drivers/USB/Class/HID.h>
/* Type Defines: */ /* Type Defines: */
/** Type define for the device configuration descriptor structure. This must be defined in the /** Type define for the device configuration descriptor structure. This must be defined in the
* application code, as the configuration descriptor contains several sub-descriptors which * application code, as the configuration descriptor contains several sub-descriptors which
* vary between devices, and which describe the device's usage to the host. * vary between devices, and which describe the device's usage to the host.
*/ */
typedef struct typedef struct
{ {
USB_Descriptor_Configuration_Header_t Config; USB_Descriptor_Configuration_Header_t Config;
USB_Descriptor_Interface_t HID_Interface; USB_Descriptor_Interface_t HID_Interface;
USB_HID_Descriptor_t HID_JoystickHID; USB_HID_Descriptor_t HID_JoystickHID;
USB_Descriptor_Endpoint_t HID_ReportINEndpoint; USB_Descriptor_Endpoint_t HID_ReportINEndpoint;
} USB_Descriptor_Configuration_t; } USB_Descriptor_Configuration_t;
/* Macros: */ /* Macros: */
/** Endpoint number of the Joystick HID reporting IN endpoint. */ /** Endpoint number of the Joystick HID reporting IN endpoint. */
#define JOYSTICK_EPNUM 1 #define JOYSTICK_EPNUM 1
/** Size in bytes of the Joystick HID reporting IN endpoint. */ /** Size in bytes of the Joystick HID reporting IN endpoint. */
#define JOYSTICK_EPSIZE 8 #define JOYSTICK_EPSIZE 8
/* Function Prototypes: */ /* Function Prototypes: */
uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, void** const DescriptorAddress) uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, void** const DescriptorAddress)
ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3); ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3);
#endif #endif

File diff suppressed because it is too large Load diff

View file

@ -1,179 +1,179 @@
/* /*
LUFA Library LUFA Library
Copyright (C) Dean Camera, 2010. Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com www.fourwalledcubicle.com
*/ */
/* /*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com) Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the advertising or publicity pertaining to distribution of the
software without specific, written prior permission. software without specific, written prior permission.
The author disclaim all warranties with regard to this The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action, in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of arising out of or in connection with the use or performance of
this software. this software.
*/ */
/** \file /** \file
* *
* Main source file for the Joystick demo. This file contains the main tasks of * Main source file for the Joystick demo. This file contains the main tasks of
* the demo and is responsible for the initial application hardware configuration. * the demo and is responsible for the initial application hardware configuration.
*/ */
#include "Joystick.h" #include "Joystick.h"
/** Buffer to hold the previously generated HID report, for comparison purposes inside the HID class driver. */ /** Buffer to hold the previously generated HID report, for comparison purposes inside the HID class driver. */
uint8_t PrevJoystickHIDReportBuffer[sizeof(USB_JoystickReport_Data_t)]; uint8_t PrevJoystickHIDReportBuffer[sizeof(USB_JoystickReport_Data_t)];
/** LUFA HID Class driver interface configuration and state information. This structure is /** 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 * passed to all HID Class driver functions, so that multiple instances of the same class
* within a device can be differentiated from one another. * within a device can be differentiated from one another.
*/ */
USB_ClassInfo_HID_Device_t Joystick_HID_Interface = USB_ClassInfo_HID_Device_t Joystick_HID_Interface =
{ {
.Config = .Config =
{ {
.InterfaceNumber = 0, .InterfaceNumber = 0,
.ReportINEndpointNumber = JOYSTICK_EPNUM, .ReportINEndpointNumber = JOYSTICK_EPNUM,
.ReportINEndpointSize = JOYSTICK_EPSIZE, .ReportINEndpointSize = JOYSTICK_EPSIZE,
.ReportINEndpointDoubleBank = false, .ReportINEndpointDoubleBank = false,
.PrevReportINBuffer = PrevJoystickHIDReportBuffer, .PrevReportINBuffer = PrevJoystickHIDReportBuffer,
.PrevReportINBufferSize = sizeof(PrevJoystickHIDReportBuffer), .PrevReportINBufferSize = sizeof(PrevJoystickHIDReportBuffer),
}, },
}; };
/** Main program entry point. This routine contains the overall program flow, including initial /** Main program entry point. This routine contains the overall program flow, including initial
* setup of all components and the main program loop. * setup of all components and the main program loop.
*/ */
int main(void) int main(void)
{ {
SetupHardware(); SetupHardware();
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY); LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
sei(); sei();
for (;;) for (;;)
{ {
HID_Device_USBTask(&Joystick_HID_Interface); HID_Device_USBTask(&Joystick_HID_Interface);
USB_USBTask(); USB_USBTask();
} }
} }
/** Configures the board hardware and chip peripherals for the demo's functionality. */ /** Configures the board hardware and chip peripherals for the demo's functionality. */
void SetupHardware(void) void SetupHardware(void)
{ {
/* Disable watchdog if enabled by bootloader/fuses */ /* Disable watchdog if enabled by bootloader/fuses */
MCUSR &= ~(1 << WDRF); MCUSR &= ~(1 << WDRF);
wdt_disable(); wdt_disable();
/* Disable clock division */ /* Disable clock division */
clock_prescale_set(clock_div_1); clock_prescale_set(clock_div_1);
/* Hardware Initialization */ /* Hardware Initialization */
Joystick_Init(); Joystick_Init();
LEDs_Init(); LEDs_Init();
Buttons_Init(); Buttons_Init();
USB_Init(); USB_Init();
} }
/** Event handler for the library USB Connection event. */ /** Event handler for the library USB Connection event. */
void EVENT_USB_Device_Connect(void) void EVENT_USB_Device_Connect(void)
{ {
LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING); LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
} }
/** Event handler for the library USB Disconnection event. */ /** Event handler for the library USB Disconnection event. */
void EVENT_USB_Device_Disconnect(void) void EVENT_USB_Device_Disconnect(void)
{ {
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY); LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
} }
/** Event handler for the library USB Configuration Changed event. */ /** Event handler for the library USB Configuration Changed event. */
void EVENT_USB_Device_ConfigurationChanged(void) void EVENT_USB_Device_ConfigurationChanged(void)
{ {
LEDs_SetAllLEDs(LEDMASK_USB_READY); LEDs_SetAllLEDs(LEDMASK_USB_READY);
if (!(HID_Device_ConfigureEndpoints(&Joystick_HID_Interface))) if (!(HID_Device_ConfigureEndpoints(&Joystick_HID_Interface)))
LEDs_SetAllLEDs(LEDMASK_USB_ERROR); LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
USB_Device_EnableSOFEvents(); USB_Device_EnableSOFEvents();
} }
/** Event handler for the library USB Unhandled Control Request event. */ /** Event handler for the library USB Unhandled Control Request event. */
void EVENT_USB_Device_UnhandledControlRequest(void) void EVENT_USB_Device_UnhandledControlRequest(void)
{ {
HID_Device_ProcessControlRequest(&Joystick_HID_Interface); HID_Device_ProcessControlRequest(&Joystick_HID_Interface);
} }
/** Event handler for the USB device Start Of Frame event. */ /** Event handler for the USB device Start Of Frame event. */
void EVENT_USB_Device_StartOfFrame(void) void EVENT_USB_Device_StartOfFrame(void)
{ {
HID_Device_MillisecondElapsed(&Joystick_HID_Interface); HID_Device_MillisecondElapsed(&Joystick_HID_Interface);
} }
/** HID class driver callback function for the creation of HID reports to the host. /** HID class driver callback function for the creation of HID reports to the host.
* *
* \param[in] HIDInterfaceInfo Pointer to the HID class interface configuration structure being referenced * \param[in] HIDInterfaceInfo Pointer to the HID class interface configuration structure being referenced
* \param[in,out] ReportID Report ID requested by the host if non-zero, otherwise callback should set to the generated report ID * \param[in,out] ReportID Report ID requested by the host if non-zero, otherwise callback should set to the generated report ID
* \param[in] ReportType Type of the report to create, either REPORT_ITEM_TYPE_In or REPORT_ITEM_TYPE_Feature * \param[in] ReportType Type of the report to create, either REPORT_ITEM_TYPE_In or REPORT_ITEM_TYPE_Feature
* \param[out] ReportData Pointer to a buffer where the created report should be stored * \param[out] ReportData Pointer to a buffer where the created report should be stored
* \param[out] ReportSize Number of bytes written in the report (or zero if no report is to be sent * \param[out] ReportSize Number of bytes written in the report (or zero if no report is to be sent
* *
* \return Boolean true to force the sending of the report, false to let the library determine if it needs to be sent * \return Boolean true to force the sending of the report, false to let the library determine if it needs to be sent
*/ */
bool CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, uint8_t* const ReportID, bool CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, uint8_t* const ReportID,
const uint8_t ReportType, void* ReportData, uint16_t* ReportSize) const uint8_t ReportType, void* ReportData, uint16_t* ReportSize)
{ {
USB_JoystickReport_Data_t* JoystickReport = (USB_JoystickReport_Data_t*)ReportData; USB_JoystickReport_Data_t* JoystickReport = (USB_JoystickReport_Data_t*)ReportData;
uint8_t JoyStatus_LCL = Joystick_GetStatus(); uint8_t JoyStatus_LCL = Joystick_GetStatus();
uint8_t ButtonStatus_LCL = Buttons_GetStatus(); uint8_t ButtonStatus_LCL = Buttons_GetStatus();
if (JoyStatus_LCL & JOY_UP) if (JoyStatus_LCL & JOY_UP)
JoystickReport->Y = -100; JoystickReport->Y = -100;
else if (JoyStatus_LCL & JOY_DOWN) else if (JoyStatus_LCL & JOY_DOWN)
JoystickReport->Y = 100; JoystickReport->Y = 100;
if (JoyStatus_LCL & JOY_LEFT) if (JoyStatus_LCL & JOY_LEFT)
JoystickReport->X = -100; JoystickReport->X = -100;
else if (JoyStatus_LCL & JOY_RIGHT) else if (JoyStatus_LCL & JOY_RIGHT)
JoystickReport->X = 100; JoystickReport->X = 100;
if (JoyStatus_LCL & JOY_PRESS) if (JoyStatus_LCL & JOY_PRESS)
JoystickReport->Button = (1 << 1); JoystickReport->Button = (1 << 1);
if (ButtonStatus_LCL & BUTTONS_BUTTON1) if (ButtonStatus_LCL & BUTTONS_BUTTON1)
JoystickReport->Button |= (1 << 0); JoystickReport->Button |= (1 << 0);
*ReportSize = sizeof(USB_JoystickReport_Data_t); *ReportSize = sizeof(USB_JoystickReport_Data_t);
return false; return false;
} }
/** HID class driver callback function for the processing of HID reports from the host. /** HID class driver callback function for the processing of HID reports from the host.
* *
* \param[in] HIDInterfaceInfo Pointer to the HID class interface configuration structure being referenced * \param[in] HIDInterfaceInfo Pointer to the HID class interface configuration structure being referenced
* \param[in] ReportID Report ID of the received report from the host * \param[in] ReportID Report ID of the received report from the host
* \param[in] ReportData Pointer to a buffer where the created report has been stored * \param[in] ReportData Pointer to a buffer where the created report has been stored
* \param[in] ReportSize Size in bytes of the received HID report * \param[in] ReportSize Size in bytes of the received HID report
*/ */
void CALLBACK_HID_Device_ProcessHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, const uint8_t ReportID, void CALLBACK_HID_Device_ProcessHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, const uint8_t ReportID,
const void* ReportData, const uint16_t ReportSize) const void* ReportData, const uint16_t ReportSize)
{ {
// Unused (but mandatory for the HID class driver) in this demo, since there are no Host->Device reports // Unused (but mandatory for the HID class driver) in this demo, since there are no Host->Device reports
} }

View file

@ -1,93 +1,93 @@
/* /*
LUFA Library LUFA Library
Copyright (C) Dean Camera, 2010. Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com www.fourwalledcubicle.com
*/ */
/* /*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com) Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the advertising or publicity pertaining to distribution of the
software without specific, written prior permission. software without specific, written prior permission.
The author disclaim all warranties with regard to this The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action, in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of arising out of or in connection with the use or performance of
this software. this software.
*/ */
/** \file /** \file
* *
* Header file for Joystick.c. * Header file for Joystick.c.
*/ */
#ifndef _JOYSTICK_H_ #ifndef _JOYSTICK_H_
#define _JOYSTICK_H_ #define _JOYSTICK_H_
/* Includes: */ /* Includes: */
#include <avr/io.h> #include <avr/io.h>
#include <avr/wdt.h> #include <avr/wdt.h>
#include <avr/power.h> #include <avr/power.h>
#include <avr/interrupt.h> #include <avr/interrupt.h>
#include <string.h> #include <string.h>
#include "Descriptors.h" #include "Descriptors.h"
#include <LUFA/Version.h> #include <LUFA/Version.h>
#include <LUFA/Drivers/Board/Joystick.h> #include <LUFA/Drivers/Board/Joystick.h>
#include <LUFA/Drivers/Board/LEDs.h> #include <LUFA/Drivers/Board/LEDs.h>
#include <LUFA/Drivers/Board/Buttons.h> #include <LUFA/Drivers/Board/Buttons.h>
#include <LUFA/Drivers/USB/USB.h> #include <LUFA/Drivers/USB/USB.h>
#include <LUFA/Drivers/USB/Class/HID.h> #include <LUFA/Drivers/USB/Class/HID.h>
/* Type Defines: */ /* Type Defines: */
/** Type define for the joystick HID report structure, for creating and sending HID reports to the host PC. /** Type define for the joystick HID report structure, for creating and sending HID reports to the host PC.
* This mirrors the layout described to the host in the HID report descriptor, in Descriptors.c. * This mirrors the layout described to the host in the HID report descriptor, in Descriptors.c.
*/ */
typedef struct typedef struct
{ {
int8_t X; /**< Current absolute joystick X position, as a signed 8-bit integer */ int8_t X; /**< Current absolute joystick X position, as a signed 8-bit integer */
int8_t Y; /**< Current absolute joystick Y position, as a signed 8-bit integer */ int8_t Y; /**< Current absolute joystick Y position, as a signed 8-bit integer */
uint8_t Button; /**< Bit mask of the currently pressed joystick buttons */ uint8_t Button; /**< Bit mask of the currently pressed joystick buttons */
} USB_JoystickReport_Data_t; } USB_JoystickReport_Data_t;
/* Macros: */ /* Macros: */
/** LED mask for the library LED driver, to indicate that the USB interface is not ready. */ /** LED mask for the library LED driver, to indicate that the USB interface is not ready. */
#define LEDMASK_USB_NOTREADY LEDS_LED1 #define LEDMASK_USB_NOTREADY LEDS_LED1
/** LED mask for the library LED driver, to indicate that the USB interface is enumerating. */ /** LED mask for the library LED driver, to indicate that the USB interface is enumerating. */
#define LEDMASK_USB_ENUMERATING (LEDS_LED2 | LEDS_LED3) #define LEDMASK_USB_ENUMERATING (LEDS_LED2 | LEDS_LED3)
/** LED mask for the library LED driver, to indicate that the USB interface is ready. */ /** LED mask for the library LED driver, to indicate that the USB interface is ready. */
#define LEDMASK_USB_READY (LEDS_LED2 | LEDS_LED4) #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. */ /** 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) #define LEDMASK_USB_ERROR (LEDS_LED1 | LEDS_LED3)
/* Function Prototypes: */ /* Function Prototypes: */
void SetupHardware(void); void SetupHardware(void);
void EVENT_USB_Device_Connect(void); void EVENT_USB_Device_Connect(void);
void EVENT_USB_Device_Disconnect(void); void EVENT_USB_Device_Disconnect(void);
void EVENT_USB_Device_ConfigurationChanged(void); void EVENT_USB_Device_ConfigurationChanged(void);
void EVENT_USB_Device_UnhandledControlRequest(void); void EVENT_USB_Device_UnhandledControlRequest(void);
void EVENT_USB_Device_StartOfFrame(void); void EVENT_USB_Device_StartOfFrame(void);
bool CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, uint8_t* const ReportID, bool CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, uint8_t* const ReportID,
const uint8_t ReportType, void* ReportData, uint16_t* ReportSize); const uint8_t ReportType, void* ReportData, uint16_t* ReportSize);
void CALLBACK_HID_Device_ProcessHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, const uint8_t ReportID, void CALLBACK_HID_Device_ProcessHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, const uint8_t ReportID,
const void* ReportData, const uint16_t ReportSize); const void* ReportData, const uint16_t ReportSize);
#endif #endif

View file

@ -1,73 +1,73 @@
/** \file /** \file
* *
* This file contains special DoxyGen information for the generation of the main page and other special * 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. * documentation pages. It is not a project source file.
*/ */
/** \mainpage Joystick Device Demo /** \mainpage Joystick Device Demo
* *
* \section SSec_Compat Demo Compatibility: * \section SSec_Compat Demo Compatibility:
* *
* The following list indicates what microcontrollers are compatible with this demo. * The following list indicates what microcontrollers are compatible with this demo.
* *
* - Series 7 USB AVRs * - Series 7 USB AVRs
* - Series 6 USB AVRs * - Series 6 USB AVRs
* - Series 4 USB AVRs * - Series 4 USB AVRs
* - Series 2 USB AVRs * - Series 2 USB AVRs
* *
* \section SSec_Info USB Information: * \section SSec_Info USB Information:
* *
* The following table gives a rundown of the USB utilization of this demo. * The following table gives a rundown of the USB utilization of this demo.
* *
* <table> * <table>
* <tr> * <tr>
* <td><b>USB Mode:</b></td> * <td><b>USB Mode:</b></td>
* <td>Device</td> * <td>Device</td>
* </tr> * </tr>
* <tr> * <tr>
* <td><b>USB Class:</b></td> * <td><b>USB Class:</b></td>
* <td>Human Interface Device (HID)</td> * <td>Human Interface Device (HID)</td>
* </tr> * </tr>
* <tr> * <tr>
* <td><b>USB Subclass:</b></td> * <td><b>USB Subclass:</b></td>
* <td>N/A</td> * <td>N/A</td>
* </tr> * </tr>
* <tr> * <tr>
* <td><b>Relevant Standards:</b></td> * <td><b>Relevant Standards:</b></td>
* <td>USBIF HID Specification \n * <td>USBIF HID Specification \n
* USBIF HID Usage Tables</td> * USBIF HID Usage Tables</td>
* </tr> * </tr>
* <tr> * <tr>
* <td><b>Usable Speeds:</b></td> * <td><b>Usable Speeds:</b></td>
* <td>Low Speed Mode \n * <td>Low Speed Mode \n
* Full Speed Mode</td> * Full Speed Mode</td>
* </tr> * </tr>
* </table> * </table>
* *
* \section SSec_Description Project Description: * \section SSec_Description Project Description:
* *
* Joystick demonstration application. This gives a simple reference * Joystick demonstration application. This gives a simple reference
* application for implementing a USB Keyboard device, for USB Joysticks * application for implementing a USB Keyboard device, for USB Joysticks
* using the standard Keyboard HID profile. * using the standard Keyboard HID profile.
* *
* This device will show up as a generic joystick device, with two buttons. * This device will show up as a generic joystick device, with two buttons.
* Pressing the joystick inwards is the first button, and the HWB button * Pressing the joystick inwards is the first button, and the HWB button
* is the second. * is the second.
* *
* Moving the joystick on the selected board moves the joystick location on * Moving the joystick on the selected board moves the joystick location on
* the host computer. * the host computer.
* *
* Currently only single interface joysticks are supported. * Currently only single interface joysticks are supported.
* *
* \section SSec_Options Project Options * \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. * The following defines can be found in this demo, which can control the demo behaviour when defined, or changed in value.
* *
* <table> * <table>
* <tr> * <tr>
* <td> * <td>
* None * None
* </td> * </td>
* </tr> * </tr>
* </table> * </table>
*/ */

File diff suppressed because it is too large Load diff

View file

@ -1,257 +1,257 @@
/* /*
LUFA Library LUFA Library
Copyright (C) Dean Camera, 2010. Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com www.fourwalledcubicle.com
*/ */
/* /*
Copyright 2010 Denver Gingerich (denver [at] ossguy [dot] com) Copyright 2010 Denver Gingerich (denver [at] ossguy [dot] com)
Based on code by Dean Camera (dean [at] fourwalledcubicle [dot] com) Based on code by Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the advertising or publicity pertaining to distribution of the
software without specific, written prior permission. software without specific, written prior permission.
The author disclaim all warranties with regard to this The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action, in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of arising out of or in connection with the use or performance of
this software. this software.
*/ */
/** \file /** \file
* *
* USB Device Descriptors, for library use when in USB device mode. Descriptors are special * USB Device Descriptors, for library use when in USB device mode. Descriptors are special
* computer-readable structures which the host requests upon device enumeration, to determine * computer-readable structures which the host requests upon device enumeration, to determine
* the device's capabilities and functions. * the device's capabilities and functions.
*/ */
#include "Descriptors.h" #include "Descriptors.h"
/** HID class report descriptor. This is a special descriptor constructed with values from the /** HID class report descriptor. This is a special descriptor constructed with values from the
* USBIF HID class specification to describe the reports and capabilities of the HID device. This * USBIF HID class specification to describe the reports and capabilities of the HID device. This
* descriptor is parsed by the host and its contents used to determine what data (and in what encoding) * descriptor is parsed by the host and its contents used to determine what data (and in what encoding)
* the device will send, and what it may be sent back from the host. Refer to the HID specification for * the device will send, and what it may be sent back from the host. Refer to the HID specification for
* more details on HID report descriptors. * more details on HID report descriptors.
*/ */
USB_Descriptor_HIDReport_Datatype_t PROGMEM KeyboardReport[] = USB_Descriptor_HIDReport_Datatype_t PROGMEM KeyboardReport[] =
{ {
0x05, 0x01, /* Usage Page (Generic Desktop) */ 0x05, 0x01, /* Usage Page (Generic Desktop) */
0x09, 0x06, /* Usage (Keyboard) */ 0x09, 0x06, /* Usage (Keyboard) */
0xa1, 0x01, /* Collection (Application) */ 0xa1, 0x01, /* Collection (Application) */
0x75, 0x01, /* Report Size (1) */ 0x75, 0x01, /* Report Size (1) */
0x95, 0x08, /* Report Count (8) */ 0x95, 0x08, /* Report Count (8) */
0x05, 0x07, /* Usage Page (Key Codes) */ 0x05, 0x07, /* Usage Page (Key Codes) */
0x19, 0xe0, /* Usage Minimum (Keyboard LeftControl) */ 0x19, 0xe0, /* Usage Minimum (Keyboard LeftControl) */
0x29, 0xe7, /* Usage Maximum (Keyboard Right GUI) */ 0x29, 0xe7, /* Usage Maximum (Keyboard Right GUI) */
0x15, 0x00, /* Logical Minimum (0) */ 0x15, 0x00, /* Logical Minimum (0) */
0x25, 0x01, /* Logical Maximum (1) */ 0x25, 0x01, /* Logical Maximum (1) */
0x81, 0x02, /* Input (Data, Variable, Absolute) */ 0x81, 0x02, /* Input (Data, Variable, Absolute) */
0x95, 0x01, /* Report Count (1) */ 0x95, 0x01, /* Report Count (1) */
0x75, 0x08, /* Report Size (8) */ 0x75, 0x08, /* Report Size (8) */
0x81, 0x03, /* Input (Const, Variable, Absolute) */ 0x81, 0x03, /* Input (Const, Variable, Absolute) */
0x95, 0x05, /* Report Count (5) */ 0x95, 0x05, /* Report Count (5) */
0x75, 0x01, /* Report Size (1) */ 0x75, 0x01, /* Report Size (1) */
0x05, 0x08, /* Usage Page (LEDs) */ 0x05, 0x08, /* Usage Page (LEDs) */
0x19, 0x01, /* Usage Minimum (Num Lock) */ 0x19, 0x01, /* Usage Minimum (Num Lock) */
0x29, 0x05, /* Usage Maximum (Kana) */ 0x29, 0x05, /* Usage Maximum (Kana) */
0x91, 0x02, /* Output (Data, Variable, Absolute) */ 0x91, 0x02, /* Output (Data, Variable, Absolute) */
0x95, 0x01, /* Report Count (1) */ 0x95, 0x01, /* Report Count (1) */
0x75, 0x03, /* Report Size (3) */ 0x75, 0x03, /* Report Size (3) */
0x91, 0x03, /* Output (Const, Variable, Absolute) */ 0x91, 0x03, /* Output (Const, Variable, Absolute) */
0x95, 0x06, /* Report Count (6) */ 0x95, 0x06, /* Report Count (6) */
0x75, 0x08, /* Report Size (8) */ 0x75, 0x08, /* Report Size (8) */
0x15, 0x00, /* Logical Minimum (0) */ 0x15, 0x00, /* Logical Minimum (0) */
0x25, 0x65, /* Logical Maximum (101) */ 0x25, 0x65, /* Logical Maximum (101) */
0x05, 0x07, /* Usage Page (Keyboard) */ 0x05, 0x07, /* Usage Page (Keyboard) */
0x19, 0x00, /* Usage Minimum (Reserved (no event indicated)) */ 0x19, 0x00, /* Usage Minimum (Reserved (no event indicated)) */
0x29, 0x65, /* Usage Maximum (Keyboard Application) */ 0x29, 0x65, /* Usage Maximum (Keyboard Application) */
0x81, 0x00, /* Input (Data, Array, Absolute) */ 0x81, 0x00, /* Input (Data, Array, Absolute) */
0xc0 /* End Collection */ 0xc0 /* End Collection */
}; };
/** Device descriptor structure. This descriptor, located in FLASH memory, describes the overall /** Device descriptor structure. This descriptor, located in FLASH memory, describes the overall
* device characteristics, including the supported USB version, control endpoint size and the * device characteristics, including the supported USB version, control endpoint size and the
* number of device configurations. The descriptor is read out by the USB host when the enumeration * number of device configurations. The descriptor is read out by the USB host when the enumeration
* process begins. * process begins.
*/ */
USB_Descriptor_Device_t PROGMEM DeviceDescriptor = USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
{ {
.Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device}, .Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device},
.USBSpecification = VERSION_BCD(01.10), .USBSpecification = VERSION_BCD(01.10),
.Class = 0x00, .Class = 0x00,
.SubClass = 0x00, .SubClass = 0x00,
.Protocol = 0x00, .Protocol = 0x00,
.Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE, .Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE,
.VendorID = 0x03EB, .VendorID = 0x03EB,
.ProductID = 0x2042, .ProductID = 0x2042,
.ReleaseNumber = 0x0000, .ReleaseNumber = 0x0000,
.ManufacturerStrIndex = 0x01, .ManufacturerStrIndex = 0x01,
.ProductStrIndex = 0x02, .ProductStrIndex = 0x02,
.SerialNumStrIndex = NO_DESCRIPTOR, .SerialNumStrIndex = NO_DESCRIPTOR,
.NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS .NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS
}; };
/** Configuration descriptor structure. This descriptor, located in FLASH memory, describes the usage /** Configuration descriptor structure. This descriptor, located in FLASH memory, describes the usage
* of the device in one of its supported configurations, including information about any device interfaces * of the device in one of its supported configurations, including information about any device interfaces
* and endpoints. The descriptor is read out by the USB host during the enumeration process when selecting * and endpoints. The descriptor is read out by the USB host during the enumeration process when selecting
* a configuration so that the host may correctly communicate with the USB device. * a configuration so that the host may correctly communicate with the USB device.
*/ */
USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor = USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
{ {
.Config = .Config =
{ {
.Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration}, .Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration},
.TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t), .TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t),
.TotalInterfaces = 1, .TotalInterfaces = 1,
.ConfigurationNumber = 1, .ConfigurationNumber = 1,
.ConfigurationStrIndex = NO_DESCRIPTOR, .ConfigurationStrIndex = NO_DESCRIPTOR,
.ConfigAttributes = (USB_CONFIG_ATTR_BUSPOWERED | USB_CONFIG_ATTR_SELFPOWERED), .ConfigAttributes = (USB_CONFIG_ATTR_BUSPOWERED | USB_CONFIG_ATTR_SELFPOWERED),
.MaxPowerConsumption = USB_CONFIG_POWER_MA(100) .MaxPowerConsumption = USB_CONFIG_POWER_MA(100)
}, },
.HID_Interface = .HID_Interface =
{ {
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface}, .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
.InterfaceNumber = 0x00, .InterfaceNumber = 0x00,
.AlternateSetting = 0x00, .AlternateSetting = 0x00,
.TotalEndpoints = 1, .TotalEndpoints = 1,
.Class = 0x03, .Class = 0x03,
.SubClass = 0x01, .SubClass = 0x01,
.Protocol = HID_BOOT_KEYBOARD_PROTOCOL, .Protocol = HID_BOOT_KEYBOARD_PROTOCOL,
.InterfaceStrIndex = NO_DESCRIPTOR .InterfaceStrIndex = NO_DESCRIPTOR
}, },
.HID_KeyboardHID = .HID_KeyboardHID =
{ {
.Header = {.Size = sizeof(USB_HID_Descriptor_t), .Type = DTYPE_HID}, .Header = {.Size = sizeof(USB_HID_Descriptor_t), .Type = DTYPE_HID},
.HIDSpec = VERSION_BCD(01.11), .HIDSpec = VERSION_BCD(01.11),
.CountryCode = 0x00, .CountryCode = 0x00,
.TotalReportDescriptors = 1, .TotalReportDescriptors = 1,
.HIDReportType = DTYPE_Report, .HIDReportType = DTYPE_Report,
.HIDReportLength = sizeof(KeyboardReport) .HIDReportLength = sizeof(KeyboardReport)
}, },
.HID_ReportINEndpoint = .HID_ReportINEndpoint =
{ {
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint}, .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
.EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_IN | KEYBOARD_EPNUM), .EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_IN | KEYBOARD_EPNUM),
.Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
.EndpointSize = KEYBOARD_EPSIZE, .EndpointSize = KEYBOARD_EPSIZE,
.PollingIntervalMS = 0x0A .PollingIntervalMS = 0x0A
}, },
}; };
/** Language descriptor structure. This descriptor, located in FLASH memory, is returned when the host requests /** Language descriptor structure. This descriptor, located in FLASH memory, is returned when the host requests
* the string descriptor with index 0 (the first index). It is actually an array of 16-bit integers, which indicate * the string descriptor with index 0 (the first index). It is actually an array of 16-bit integers, which indicate
* via the language ID table available at USB.org what languages the device supports for its string descriptors. * via the language ID table available at USB.org what languages the device supports for its string descriptors.
*/ */
USB_Descriptor_String_t PROGMEM LanguageString = USB_Descriptor_String_t PROGMEM LanguageString =
{ {
.Header = {.Size = USB_STRING_LEN(1), .Type = DTYPE_String}, .Header = {.Size = USB_STRING_LEN(1), .Type = DTYPE_String},
.UnicodeString = {LANGUAGE_ID_ENG} .UnicodeString = {LANGUAGE_ID_ENG}
}; };
/** Manufacturer descriptor string. This is a Unicode string containing the manufacturer's details in human readable /** Manufacturer descriptor string. This is a Unicode string containing the manufacturer's details in human readable
* form, and is read out upon request by the host when the appropriate string ID is requested, listed in the Device * form, and is read out upon request by the host when the appropriate string ID is requested, listed in the Device
* Descriptor. * Descriptor.
*/ */
USB_Descriptor_String_t PROGMEM ManufacturerString = USB_Descriptor_String_t PROGMEM ManufacturerString =
{ {
.Header = {.Size = USB_STRING_LEN(16), .Type = DTYPE_String}, .Header = {.Size = USB_STRING_LEN(16), .Type = DTYPE_String},
.UnicodeString = L"Denver Gingerich" .UnicodeString = L"Denver Gingerich"
}; };
/** Product descriptor string. This is a Unicode string containing the product's details in human readable form, /** Product descriptor string. This is a Unicode string containing the product's details in human readable form,
* and is read out upon request by the host when the appropriate string ID is requested, listed in the Device * and is read out upon request by the host when the appropriate string ID is requested, listed in the Device
* Descriptor. * Descriptor.
*/ */
USB_Descriptor_String_t PROGMEM ProductString = USB_Descriptor_String_t PROGMEM ProductString =
{ {
.Header = {.Size = USB_STRING_LEN(18), .Type = DTYPE_String}, .Header = {.Size = USB_STRING_LEN(18), .Type = DTYPE_String},
.UnicodeString = L"LUFA Keyboard Demo" .UnicodeString = L"LUFA Keyboard Demo"
}; };
/** This function is called by the library when in device mode, and must be overridden (see library "USB Descriptors" /** This function is called by the library when in device mode, and must be overridden (see library "USB Descriptors"
* documentation) by the application code so that the address and size of a requested descriptor can be given * documentation) by the application code so that the address and size of a requested descriptor can be given
* to the USB library. When the device receives a Get Descriptor request on the control endpoint, this function * to the USB library. When the device receives a Get Descriptor request on the control endpoint, this function
* is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the * is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the
* USB host. * USB host.
*/ */
uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, void** const DescriptorAddress) uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, void** const DescriptorAddress)
{ {
const uint8_t DescriptorType = (wValue >> 8); const uint8_t DescriptorType = (wValue >> 8);
const uint8_t DescriptorNumber = (wValue & 0xFF); const uint8_t DescriptorNumber = (wValue & 0xFF);
void* Address = NULL; void* Address = NULL;
uint16_t Size = NO_DESCRIPTOR; uint16_t Size = NO_DESCRIPTOR;
switch (DescriptorType) switch (DescriptorType)
{ {
case DTYPE_Device: case DTYPE_Device:
Address = (void*)&DeviceDescriptor; Address = (void*)&DeviceDescriptor;
Size = sizeof(USB_Descriptor_Device_t); Size = sizeof(USB_Descriptor_Device_t);
break; break;
case DTYPE_Configuration: case DTYPE_Configuration:
Address = (void*)&ConfigurationDescriptor; Address = (void*)&ConfigurationDescriptor;
Size = sizeof(USB_Descriptor_Configuration_t); Size = sizeof(USB_Descriptor_Configuration_t);
break; break;
case DTYPE_String: case DTYPE_String:
switch (DescriptorNumber) switch (DescriptorNumber)
{ {
case 0x00: case 0x00:
Address = (void*)&LanguageString; Address = (void*)&LanguageString;
Size = pgm_read_byte(&LanguageString.Header.Size); Size = pgm_read_byte(&LanguageString.Header.Size);
break; break;
case 0x01: case 0x01:
Address = (void*)&ManufacturerString; Address = (void*)&ManufacturerString;
Size = pgm_read_byte(&ManufacturerString.Header.Size); Size = pgm_read_byte(&ManufacturerString.Header.Size);
break; break;
case 0x02: case 0x02:
Address = (void*)&ProductString; Address = (void*)&ProductString;
Size = pgm_read_byte(&ProductString.Header.Size); Size = pgm_read_byte(&ProductString.Header.Size);
break; break;
} }
break; break;
case DTYPE_HID: case DTYPE_HID:
Address = (void*)&ConfigurationDescriptor.HID_KeyboardHID; Address = (void*)&ConfigurationDescriptor.HID_KeyboardHID;
Size = sizeof(USB_HID_Descriptor_t); Size = sizeof(USB_HID_Descriptor_t);
break; break;
case DTYPE_Report: case DTYPE_Report:
Address = (void*)&KeyboardReport; Address = (void*)&KeyboardReport;
Size = sizeof(KeyboardReport); Size = sizeof(KeyboardReport);
break; break;
} }
*DescriptorAddress = Address; *DescriptorAddress = Address;
return Size; return Size;
} }

View file

@ -1,70 +1,70 @@
/* /*
LUFA Library LUFA Library
Copyright (C) Dean Camera, 2010. Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com www.fourwalledcubicle.com
*/ */
/* /*
Copyright 2010 Denver Gingerich (denver [at] ossguy [dot] com) Copyright 2010 Denver Gingerich (denver [at] ossguy [dot] com)
Based on code by Dean Camera (dean [at] fourwalledcubicle [dot] com) Based on code by Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the advertising or publicity pertaining to distribution of the
software without specific, written prior permission. software without specific, written prior permission.
The author disclaim all warranties with regard to this The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action, in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of arising out of or in connection with the use or performance of
this software. this software.
*/ */
/** \file /** \file
* *
* Header file for Descriptors.c. * Header file for Descriptors.c.
*/ */
#ifndef _DESCRIPTORS_H_ #ifndef _DESCRIPTORS_H_
#define _DESCRIPTORS_H_ #define _DESCRIPTORS_H_
/* Includes: */ /* Includes: */
#include <avr/pgmspace.h> #include <avr/pgmspace.h>
#include <LUFA/Drivers/USB/USB.h> #include <LUFA/Drivers/USB/USB.h>
#include <LUFA/Drivers/USB/Class/HID.h> #include <LUFA/Drivers/USB/Class/HID.h>
/* Type Defines: */ /* Type Defines: */
/** Type define for the device configuration descriptor structure. This must be defined in the /** Type define for the device configuration descriptor structure. This must be defined in the
* application code, as the configuration descriptor contains several sub-descriptors which * application code, as the configuration descriptor contains several sub-descriptors which
* vary between devices, and which describe the device's usage to the host. * vary between devices, and which describe the device's usage to the host.
*/ */
typedef struct typedef struct
{ {
USB_Descriptor_Configuration_Header_t Config; USB_Descriptor_Configuration_Header_t Config;
USB_Descriptor_Interface_t HID_Interface; USB_Descriptor_Interface_t HID_Interface;
USB_HID_Descriptor_t HID_KeyboardHID; USB_HID_Descriptor_t HID_KeyboardHID;
USB_Descriptor_Endpoint_t HID_ReportINEndpoint; USB_Descriptor_Endpoint_t HID_ReportINEndpoint;
} USB_Descriptor_Configuration_t; } USB_Descriptor_Configuration_t;
/* Macros: */ /* Macros: */
/** Endpoint number of the Keyboard HID reporting IN endpoint. */ /** Endpoint number of the Keyboard HID reporting IN endpoint. */
#define KEYBOARD_EPNUM 1 #define KEYBOARD_EPNUM 1
/** Size in bytes of the Keyboard HID reporting IN and OUT endpoints. */ /** Size in bytes of the Keyboard HID reporting IN and OUT endpoints. */
#define KEYBOARD_EPSIZE 8 #define KEYBOARD_EPSIZE 8
/* Function Prototypes: */ /* Function Prototypes: */
uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, void** const DescriptorAddress) uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, void** const DescriptorAddress)
ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3); ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3);
#endif #endif

File diff suppressed because it is too large Load diff

View file

@ -1,196 +1,196 @@
/* /*
LUFA Library LUFA Library
Copyright (C) Dean Camera, 2010. Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com www.fourwalledcubicle.com
*/ */
/* /*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com) Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the advertising or publicity pertaining to distribution of the
software without specific, written prior permission. software without specific, written prior permission.
The author disclaim all warranties with regard to this The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action, in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of arising out of or in connection with the use or performance of
this software. this software.
*/ */
/** \file /** \file
* *
* Main source file for the Keyboard demo. This file contains the main tasks of * Main source file for the Keyboard demo. This file contains the main tasks of
* the demo and is responsible for the initial application hardware configuration. * the demo and is responsible for the initial application hardware configuration.
*/ */
#include "Keyboard.h" #include "Keyboard.h"
/** Buffer to hold the previously generated Keyboard HID report, for comparison purposes inside the HID class driver. */ /** Buffer to hold the previously generated Keyboard HID report, for comparison purposes inside the HID class driver. */
uint8_t PrevKeyboardHIDReportBuffer[sizeof(USB_KeyboardReport_Data_t)]; uint8_t PrevKeyboardHIDReportBuffer[sizeof(USB_KeyboardReport_Data_t)];
/** LUFA HID Class driver interface configuration and state information. This structure is /** 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 * passed to all HID Class driver functions, so that multiple instances of the same class
* within a device can be differentiated from one another. * within a device can be differentiated from one another.
*/ */
USB_ClassInfo_HID_Device_t Keyboard_HID_Interface = USB_ClassInfo_HID_Device_t Keyboard_HID_Interface =
{ {
.Config = .Config =
{ {
.InterfaceNumber = 0, .InterfaceNumber = 0,
.ReportINEndpointNumber = KEYBOARD_EPNUM, .ReportINEndpointNumber = KEYBOARD_EPNUM,
.ReportINEndpointSize = KEYBOARD_EPSIZE, .ReportINEndpointSize = KEYBOARD_EPSIZE,
.ReportINEndpointDoubleBank = false, .ReportINEndpointDoubleBank = false,
.PrevReportINBuffer = PrevKeyboardHIDReportBuffer, .PrevReportINBuffer = PrevKeyboardHIDReportBuffer,
.PrevReportINBufferSize = sizeof(PrevKeyboardHIDReportBuffer), .PrevReportINBufferSize = sizeof(PrevKeyboardHIDReportBuffer),
}, },
}; };
/** Main program entry point. This routine contains the overall program flow, including initial /** Main program entry point. This routine contains the overall program flow, including initial
* setup of all components and the main program loop. * setup of all components and the main program loop.
*/ */
int main(void) int main(void)
{ {
SetupHardware(); SetupHardware();
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY); LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
sei(); sei();
for (;;) for (;;)
{ {
HID_Device_USBTask(&Keyboard_HID_Interface); HID_Device_USBTask(&Keyboard_HID_Interface);
USB_USBTask(); USB_USBTask();
} }
} }
/** Configures the board hardware and chip peripherals for the demo's functionality. */ /** Configures the board hardware and chip peripherals for the demo's functionality. */
void SetupHardware() void SetupHardware()
{ {
/* Disable watchdog if enabled by bootloader/fuses */ /* Disable watchdog if enabled by bootloader/fuses */
MCUSR &= ~(1 << WDRF); MCUSR &= ~(1 << WDRF);
wdt_disable(); wdt_disable();
/* Disable clock division */ /* Disable clock division */
clock_prescale_set(clock_div_1); clock_prescale_set(clock_div_1);
/* Hardware Initialization */ /* Hardware Initialization */
Joystick_Init(); Joystick_Init();
LEDs_Init(); LEDs_Init();
Buttons_Init(); Buttons_Init();
USB_Init(); USB_Init();
} }
/** Event handler for the library USB Connection event. */ /** Event handler for the library USB Connection event. */
void EVENT_USB_Device_Connect(void) void EVENT_USB_Device_Connect(void)
{ {
LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING); LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
} }
/** Event handler for the library USB Disconnection event. */ /** Event handler for the library USB Disconnection event. */
void EVENT_USB_Device_Disconnect(void) void EVENT_USB_Device_Disconnect(void)
{ {
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY); LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
} }
/** Event handler for the library USB Configuration Changed event. */ /** Event handler for the library USB Configuration Changed event. */
void EVENT_USB_Device_ConfigurationChanged(void) void EVENT_USB_Device_ConfigurationChanged(void)
{ {
LEDs_SetAllLEDs(LEDMASK_USB_READY); LEDs_SetAllLEDs(LEDMASK_USB_READY);
if (!(HID_Device_ConfigureEndpoints(&Keyboard_HID_Interface))) if (!(HID_Device_ConfigureEndpoints(&Keyboard_HID_Interface)))
LEDs_SetAllLEDs(LEDMASK_USB_ERROR); LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
USB_Device_EnableSOFEvents(); USB_Device_EnableSOFEvents();
} }
/** Event handler for the library USB Unhandled Control Request event. */ /** Event handler for the library USB Unhandled Control Request event. */
void EVENT_USB_Device_UnhandledControlRequest(void) void EVENT_USB_Device_UnhandledControlRequest(void)
{ {
HID_Device_ProcessControlRequest(&Keyboard_HID_Interface); HID_Device_ProcessControlRequest(&Keyboard_HID_Interface);
} }
/** Event handler for the USB device Start Of Frame event. */ /** Event handler for the USB device Start Of Frame event. */
void EVENT_USB_Device_StartOfFrame(void) void EVENT_USB_Device_StartOfFrame(void)
{ {
HID_Device_MillisecondElapsed(&Keyboard_HID_Interface); HID_Device_MillisecondElapsed(&Keyboard_HID_Interface);
} }
/** HID class driver callback function for the creation of HID reports to the host. /** HID class driver callback function for the creation of HID reports to the host.
* *
* \param[in] HIDInterfaceInfo Pointer to the HID class interface configuration structure being referenced * \param[in] HIDInterfaceInfo Pointer to the HID class interface configuration structure being referenced
* \param[in,out] ReportID Report ID requested by the host if non-zero, otherwise callback should set to the generated report ID * \param[in,out] ReportID Report ID requested by the host if non-zero, otherwise callback should set to the generated report ID
* \param[in] ReportType Type of the report to create, either REPORT_ITEM_TYPE_In or REPORT_ITEM_TYPE_Feature * \param[in] ReportType Type of the report to create, either REPORT_ITEM_TYPE_In or REPORT_ITEM_TYPE_Feature
* \param[out] ReportData Pointer to a buffer where the created report should be stored * \param[out] ReportData Pointer to a buffer where the created report should be stored
* \param[out] ReportSize Number of bytes written in the report (or zero if no report is to be sent * \param[out] ReportSize Number of bytes written in the report (or zero if no report is to be sent
* *
* \return Boolean true to force the sending of the report, false to let the library determine if it needs to be sent * \return Boolean true to force the sending of the report, false to let the library determine if it needs to be sent
*/ */
bool CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, uint8_t* const ReportID, bool CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, uint8_t* const ReportID,
const uint8_t ReportType, void* ReportData, uint16_t* ReportSize) const uint8_t ReportType, void* ReportData, uint16_t* ReportSize)
{ {
USB_KeyboardReport_Data_t* KeyboardReport = (USB_KeyboardReport_Data_t*)ReportData; USB_KeyboardReport_Data_t* KeyboardReport = (USB_KeyboardReport_Data_t*)ReportData;
uint8_t JoyStatus_LCL = Joystick_GetStatus(); uint8_t JoyStatus_LCL = Joystick_GetStatus();
uint8_t ButtonStatus_LCL = Buttons_GetStatus(); uint8_t ButtonStatus_LCL = Buttons_GetStatus();
uint8_t UsedKeyCodes = 0; uint8_t UsedKeyCodes = 0;
if (JoyStatus_LCL & JOY_UP) if (JoyStatus_LCL & JOY_UP)
KeyboardReport->KeyCode[UsedKeyCodes++] = 0x04; // A KeyboardReport->KeyCode[UsedKeyCodes++] = 0x04; // A
else if (JoyStatus_LCL & JOY_DOWN) else if (JoyStatus_LCL & JOY_DOWN)
KeyboardReport->KeyCode[UsedKeyCodes++] = 0x05; // B KeyboardReport->KeyCode[UsedKeyCodes++] = 0x05; // B
if (JoyStatus_LCL & JOY_LEFT) if (JoyStatus_LCL & JOY_LEFT)
KeyboardReport->KeyCode[UsedKeyCodes++] = 0x06; // C KeyboardReport->KeyCode[UsedKeyCodes++] = 0x06; // C
else if (JoyStatus_LCL & JOY_RIGHT) else if (JoyStatus_LCL & JOY_RIGHT)
KeyboardReport->KeyCode[UsedKeyCodes++] = 0x07; // D KeyboardReport->KeyCode[UsedKeyCodes++] = 0x07; // D
if (JoyStatus_LCL & JOY_PRESS) if (JoyStatus_LCL & JOY_PRESS)
KeyboardReport->KeyCode[UsedKeyCodes++] = 0x08; // E KeyboardReport->KeyCode[UsedKeyCodes++] = 0x08; // E
if (ButtonStatus_LCL & BUTTONS_BUTTON1) if (ButtonStatus_LCL & BUTTONS_BUTTON1)
KeyboardReport->KeyCode[UsedKeyCodes++] = 0x09; // F KeyboardReport->KeyCode[UsedKeyCodes++] = 0x09; // F
if (UsedKeyCodes) if (UsedKeyCodes)
KeyboardReport->Modifier = HID_KEYBOARD_MODIFER_LEFTSHIFT; KeyboardReport->Modifier = HID_KEYBOARD_MODIFER_LEFTSHIFT;
*ReportSize = sizeof(USB_KeyboardReport_Data_t); *ReportSize = sizeof(USB_KeyboardReport_Data_t);
return false; return false;
} }
/** HID class driver callback function for the processing of HID reports from the host. /** HID class driver callback function for the processing of HID reports from the host.
* *
* \param[in] HIDInterfaceInfo Pointer to the HID class interface configuration structure being referenced * \param[in] HIDInterfaceInfo Pointer to the HID class interface configuration structure being referenced
* \param[in] ReportID Report ID of the received report from the host * \param[in] ReportID Report ID of the received report from the host
* \param[in] ReportData Pointer to a buffer where the created report has been stored * \param[in] ReportData Pointer to a buffer where the created report has been stored
* \param[in] ReportSize Size in bytes of the received HID report * \param[in] ReportSize Size in bytes of the received HID report
*/ */
void CALLBACK_HID_Device_ProcessHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, const uint8_t ReportID, void CALLBACK_HID_Device_ProcessHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, const uint8_t ReportID,
const void* ReportData, const uint16_t ReportSize) const void* ReportData, const uint16_t ReportSize)
{ {
uint8_t LEDMask = LEDS_NO_LEDS; uint8_t LEDMask = LEDS_NO_LEDS;
uint8_t* LEDReport = (uint8_t*)ReportData; uint8_t* LEDReport = (uint8_t*)ReportData;
if (*LEDReport & HID_KEYBOARD_LED_NUMLOCK) if (*LEDReport & HID_KEYBOARD_LED_NUMLOCK)
LEDMask |= LEDS_LED1; LEDMask |= LEDS_LED1;
if (*LEDReport & HID_KEYBOARD_LED_CAPSLOCK) if (*LEDReport & HID_KEYBOARD_LED_CAPSLOCK)
LEDMask |= LEDS_LED3; LEDMask |= LEDS_LED3;
if (*LEDReport & HID_KEYBOARD_LED_SCROLLLOCK) if (*LEDReport & HID_KEYBOARD_LED_SCROLLLOCK)
LEDMask |= LEDS_LED4; LEDMask |= LEDS_LED4;
LEDs_SetAllLEDs(LEDMask); LEDs_SetAllLEDs(LEDMask);
} }

View file

@ -1,84 +1,84 @@
/* /*
LUFA Library LUFA Library
Copyright (C) Dean Camera, 2010. Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com www.fourwalledcubicle.com
*/ */
/* /*
Copyright 2010 Denver Gingerich (denver [at] ossguy [dot] com) Copyright 2010 Denver Gingerich (denver [at] ossguy [dot] com)
Based on code by Dean Camera (dean [at] fourwalledcubicle [dot] com) Based on code by Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the advertising or publicity pertaining to distribution of the
software without specific, written prior permission. software without specific, written prior permission.
The author disclaim all warranties with regard to this The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action, in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of arising out of or in connection with the use or performance of
this software. this software.
*/ */
/** \file /** \file
* *
* Header file for Keyboard.c. * Header file for Keyboard.c.
*/ */
#ifndef _KEYBOARD_H_ #ifndef _KEYBOARD_H_
#define _KEYBOARD_H_ #define _KEYBOARD_H_
/* Includes: */ /* Includes: */
#include <avr/io.h> #include <avr/io.h>
#include <avr/wdt.h> #include <avr/wdt.h>
#include <avr/power.h> #include <avr/power.h>
#include <avr/interrupt.h> #include <avr/interrupt.h>
#include <stdbool.h> #include <stdbool.h>
#include <string.h> #include <string.h>
#include "Descriptors.h" #include "Descriptors.h"
#include <LUFA/Version.h> #include <LUFA/Version.h>
#include <LUFA/Drivers/Board/Joystick.h> #include <LUFA/Drivers/Board/Joystick.h>
#include <LUFA/Drivers/Board/LEDs.h> #include <LUFA/Drivers/Board/LEDs.h>
#include <LUFA/Drivers/Board/Buttons.h> #include <LUFA/Drivers/Board/Buttons.h>
#include <LUFA/Drivers/USB/USB.h> #include <LUFA/Drivers/USB/USB.h>
#include <LUFA/Drivers/USB/Class/HID.h> #include <LUFA/Drivers/USB/Class/HID.h>
/* Macros: */ /* Macros: */
/** LED mask for the library LED driver, to indicate that the USB interface is not ready. */ /** LED mask for the library LED driver, to indicate that the USB interface is not ready. */
#define LEDMASK_USB_NOTREADY LEDS_LED1 #define LEDMASK_USB_NOTREADY LEDS_LED1
/** LED mask for the library LED driver, to indicate that the USB interface is enumerating. */ /** LED mask for the library LED driver, to indicate that the USB interface is enumerating. */
#define LEDMASK_USB_ENUMERATING (LEDS_LED2 | LEDS_LED3) #define LEDMASK_USB_ENUMERATING (LEDS_LED2 | LEDS_LED3)
/** LED mask for the library LED driver, to indicate that the USB interface is ready. */ /** LED mask for the library LED driver, to indicate that the USB interface is ready. */
#define LEDMASK_USB_READY (LEDS_LED2 | LEDS_LED4) #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. */ /** 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) #define LEDMASK_USB_ERROR (LEDS_LED1 | LEDS_LED3)
/* Function Prototypes: */ /* Function Prototypes: */
void SetupHardware(void); void SetupHardware(void);
void EVENT_USB_Device_Connect(void); void EVENT_USB_Device_Connect(void);
void EVENT_USB_Device_Disconnect(void); void EVENT_USB_Device_Disconnect(void);
void EVENT_USB_Device_ConfigurationChanged(void); void EVENT_USB_Device_ConfigurationChanged(void);
void EVENT_USB_Device_UnhandledControlRequest(void); void EVENT_USB_Device_UnhandledControlRequest(void);
void EVENT_USB_Device_StartOfFrame(void); void EVENT_USB_Device_StartOfFrame(void);
bool CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, uint8_t* const ReportID, bool CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, uint8_t* const ReportID,
const uint8_t ReportType, void* ReportData, uint16_t* ReportSize); const uint8_t ReportType, void* ReportData, uint16_t* ReportSize);
void CALLBACK_HID_Device_ProcessHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, const uint8_t ReportID, void CALLBACK_HID_Device_ProcessHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, const uint8_t ReportID,
const void* ReportData, const uint16_t ReportSize); const void* ReportData, const uint16_t ReportSize);
#endif #endif

View file

@ -1,72 +1,72 @@
/** \file /** \file
* *
* This file contains special DoxyGen information for the generation of the main page and other special * 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. * documentation pages. It is not a project source file.
*/ */
/** \mainpage Keyboard Device Demo /** \mainpage Keyboard Device Demo
* *
* \section SSec_Compat Demo Compatibility: * \section SSec_Compat Demo Compatibility:
* *
* The following list indicates what microcontrollers are compatible with this demo. * The following list indicates what microcontrollers are compatible with this demo.
* *
* - Series 7 USB AVRs * - Series 7 USB AVRs
* - Series 6 USB AVRs * - Series 6 USB AVRs
* - Series 4 USB AVRs * - Series 4 USB AVRs
* - Series 2 USB AVRs * - Series 2 USB AVRs
* *
* \section SSec_Info USB Information: * \section SSec_Info USB Information:
* *
* The following table gives a rundown of the USB utilization of this demo. * The following table gives a rundown of the USB utilization of this demo.
* *
* <table> * <table>
* <tr> * <tr>
* <td><b>USB Mode:</b></td> * <td><b>USB Mode:</b></td>
* <td>Device</td> * <td>Device</td>
* </tr> * </tr>
* <tr> * <tr>
* <td><b>USB Class:</b></td> * <td><b>USB Class:</b></td>
* <td>Human Interface Device (HID)</td> * <td>Human Interface Device (HID)</td>
* </tr> * </tr>
* <tr> * <tr>
* <td><b>USB Subclass:</b></td> * <td><b>USB Subclass:</b></td>
* <td>Keyboard Subclass</td> * <td>Keyboard Subclass</td>
* </tr> * </tr>
* <tr> * <tr>
* <td><b>Relevant Standards:</b></td> * <td><b>Relevant Standards:</b></td>
* <td>USBIF HID Specification \n * <td>USBIF HID Specification \n
* USBIF HID Usage Tables</td> * USBIF HID Usage Tables</td>
* </tr> * </tr>
* <tr> * <tr>
* <td><b>Usable Speeds:</b></td> * <td><b>Usable Speeds:</b></td>
* <td>Low Speed Mode \n * <td>Low Speed Mode \n
* Full Speed Mode</td> * Full Speed Mode</td>
* </tr> * </tr>
* </table> * </table>
* *
* \section SSec_Description Project Description: * \section SSec_Description Project Description:
* *
* Keyboard demonstration application. This gives a simple reference application * Keyboard demonstration application. This gives a simple reference application
* for implementing a USB Keyboard using the basic USB HID drivers in all modern * for implementing a USB Keyboard using the basic USB HID drivers in all modern
* OSes (i.e. no special drivers required). It is boot protocol compatible, and thus * OSes (i.e. no special drivers required). It is boot protocol compatible, and thus
* works under compatible BIOS as if it was a native keyboard (e.g. PS/2). * works under compatible BIOS as if it was a native keyboard (e.g. PS/2).
* *
* On start-up the system will automatically enumerate and function as a keyboard * On start-up the system will automatically enumerate and function as a keyboard
* when the USB connection to a host is present. To use the keyboard example, * when the USB connection to a host is present. To use the keyboard example,
* manipulate the joystick to send the letters a, b, c, d and e. See the USB HID * manipulate the joystick to send the letters a, b, c, d and e. See the USB HID
* documentation for more information on sending keyboard event and key presses. Unlike * documentation for more information on sending keyboard event and key presses. Unlike
* other LUFA Keyboard demos, this example shows explicitly how to send multiple keypresses * other LUFA Keyboard demos, this example shows explicitly how to send multiple keypresses
* inside the same report to the host. * inside the same report to the host.
* *
* \section SSec_Options Project Options * \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. * The following defines can be found in this demo, which can control the demo behaviour when defined, or changed in value.
* *
* <table> * <table>
* <tr> * <tr>
* <td> * <td>
* None * None
* </td> * </td>
* </tr> * </tr>
* </table> * </table>
*/ */

File diff suppressed because it is too large Load diff

View file

@ -1,344 +1,344 @@
/* /*
LUFA Library LUFA Library
Copyright (C) Dean Camera, 2010. Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com www.fourwalledcubicle.com
*/ */
/* /*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com) Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Copyright 2010 Denver Gingerich (denver [at] ossguy [dot] com) Copyright 2010 Denver Gingerich (denver [at] ossguy [dot] com)
Permission to use, copy, modify, distribute, and sell this Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the advertising or publicity pertaining to distribution of the
software without specific, written prior permission. software without specific, written prior permission.
The author disclaim all warranties with regard to this The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action, in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of arising out of or in connection with the use or performance of
this software. this software.
*/ */
/** \file /** \file
* *
* USB Device Descriptors, for library use when in USB device mode. Descriptors are special * USB Device Descriptors, for library use when in USB device mode. Descriptors are special
* computer-readable structures which the host requests upon device enumeration, to determine * computer-readable structures which the host requests upon device enumeration, to determine
* the device's capabilities and functions. * the device's capabilities and functions.
*/ */
#include "Descriptors.h" #include "Descriptors.h"
/** HID class report descriptor. This is a special descriptor constructed with values from the /** HID class report descriptor. This is a special descriptor constructed with values from the
* USBIF HID class specification to describe the reports and capabilities of the HID device. This * USBIF HID class specification to describe the reports and capabilities of the HID device. This
* descriptor is parsed by the host and its contents used to determine what data (and in what encoding) * descriptor is parsed by the host and its contents used to determine what data (and in what encoding)
* the device will send, and what it may be sent back from the host. Refer to the HID specification for * the device will send, and what it may be sent back from the host. Refer to the HID specification for
* more details on HID report descriptors. * more details on HID report descriptors.
* *
* This descriptor describes the mouse HID interface's report structure. * This descriptor describes the mouse HID interface's report structure.
*/ */
USB_Descriptor_HIDReport_Datatype_t PROGMEM MouseReport[] = USB_Descriptor_HIDReport_Datatype_t PROGMEM MouseReport[] =
{ {
0x05, 0x01, /* Usage Page (Generic Desktop) */ 0x05, 0x01, /* Usage Page (Generic Desktop) */
0x09, 0x02, /* Usage (Mouse) */ 0x09, 0x02, /* Usage (Mouse) */
0xA1, 0x01, /* Collection (Application) */ 0xA1, 0x01, /* Collection (Application) */
0x09, 0x01, /* Usage (Pointer) */ 0x09, 0x01, /* Usage (Pointer) */
0xA1, 0x00, /* Collection (Physical) */ 0xA1, 0x00, /* Collection (Physical) */
0x95, 0x03, /* Report Count (3) */ 0x95, 0x03, /* Report Count (3) */
0x75, 0x01, /* Report Size (1) */ 0x75, 0x01, /* Report Size (1) */
0x05, 0x09, /* Usage Page (Button) */ 0x05, 0x09, /* Usage Page (Button) */
0x19, 0x01, /* Usage Minimum (Button 1) */ 0x19, 0x01, /* Usage Minimum (Button 1) */
0x29, 0x03, /* Usage Maximum (Button 3) */ 0x29, 0x03, /* Usage Maximum (Button 3) */
0x15, 0x00, /* Logical Minimum (0) */ 0x15, 0x00, /* Logical Minimum (0) */
0x25, 0x01, /* Logical Maximum (1) */ 0x25, 0x01, /* Logical Maximum (1) */
0x81, 0x02, /* Input (Data, Variable, Absolute) */ 0x81, 0x02, /* Input (Data, Variable, Absolute) */
0x95, 0x01, /* Report Count (1) */ 0x95, 0x01, /* Report Count (1) */
0x75, 0x05, /* Report Size (5) */ 0x75, 0x05, /* Report Size (5) */
0x81, 0x01, /* Input (Constant) */ 0x81, 0x01, /* Input (Constant) */
0x75, 0x08, /* Report Size (8) */ 0x75, 0x08, /* Report Size (8) */
0x95, 0x02, /* Report Count (2) */ 0x95, 0x02, /* Report Count (2) */
0x05, 0x01, /* Usage Page (Generic Desktop Control) */ 0x05, 0x01, /* Usage Page (Generic Desktop Control) */
0x09, 0x30, /* Usage X */ 0x09, 0x30, /* Usage X */
0x09, 0x31, /* Usage Y */ 0x09, 0x31, /* Usage Y */
0x15, 0x81, /* Logical Minimum (-127) */ 0x15, 0x81, /* Logical Minimum (-127) */
0x25, 0x7F, /* Logical Maximum (127) */ 0x25, 0x7F, /* Logical Maximum (127) */
0x81, 0x06, /* Input (Data, Variable, Relative) */ 0x81, 0x06, /* Input (Data, Variable, Relative) */
0xC0, /* End Collection */ 0xC0, /* End Collection */
0xC0, /* End Collection */ 0xC0, /* End Collection */
}; };
/** Same as the MouseReport structure, but defines the keyboard HID interface's report structure. */ /** Same as the MouseReport structure, but defines the keyboard HID interface's report structure. */
USB_Descriptor_HIDReport_Datatype_t PROGMEM KeyboardReport[] = USB_Descriptor_HIDReport_Datatype_t PROGMEM KeyboardReport[] =
{ {
0x05, 0x01, /* Usage Page (Generic Desktop) */ 0x05, 0x01, /* Usage Page (Generic Desktop) */
0x09, 0x06, /* Usage (Keyboard) */ 0x09, 0x06, /* Usage (Keyboard) */
0xa1, 0x01, /* Collection (Application) */ 0xa1, 0x01, /* Collection (Application) */
0x75, 0x01, /* Report Size (1) */ 0x75, 0x01, /* Report Size (1) */
0x95, 0x08, /* Report Count (8) */ 0x95, 0x08, /* Report Count (8) */
0x05, 0x07, /* Usage Page (Key Codes) */ 0x05, 0x07, /* Usage Page (Key Codes) */
0x19, 0xe0, /* Usage Minimum (Keyboard LeftControl) */ 0x19, 0xe0, /* Usage Minimum (Keyboard LeftControl) */
0x29, 0xe7, /* Usage Maximum (Keyboard Right GUI) */ 0x29, 0xe7, /* Usage Maximum (Keyboard Right GUI) */
0x15, 0x00, /* Logical Minimum (0) */ 0x15, 0x00, /* Logical Minimum (0) */
0x25, 0x01, /* Logical Maximum (1) */ 0x25, 0x01, /* Logical Maximum (1) */
0x81, 0x02, /* Input (Data, Variable, Absolute) */ 0x81, 0x02, /* Input (Data, Variable, Absolute) */
0x95, 0x01, /* Report Count (1) */ 0x95, 0x01, /* Report Count (1) */
0x75, 0x08, /* Report Size (8) */ 0x75, 0x08, /* Report Size (8) */
0x81, 0x03, /* Input (Const, Variable, Absolute) */ 0x81, 0x03, /* Input (Const, Variable, Absolute) */
0x95, 0x05, /* Report Count (5) */ 0x95, 0x05, /* Report Count (5) */
0x75, 0x01, /* Report Size (1) */ 0x75, 0x01, /* Report Size (1) */
0x05, 0x08, /* Usage Page (LEDs) */ 0x05, 0x08, /* Usage Page (LEDs) */
0x19, 0x01, /* Usage Minimum (Num Lock) */ 0x19, 0x01, /* Usage Minimum (Num Lock) */
0x29, 0x05, /* Usage Maximum (Kana) */ 0x29, 0x05, /* Usage Maximum (Kana) */
0x91, 0x02, /* Output (Data, Variable, Absolute) */ 0x91, 0x02, /* Output (Data, Variable, Absolute) */
0x95, 0x01, /* Report Count (1) */ 0x95, 0x01, /* Report Count (1) */
0x75, 0x03, /* Report Size (3) */ 0x75, 0x03, /* Report Size (3) */
0x91, 0x03, /* Output (Const, Variable, Absolute) */ 0x91, 0x03, /* Output (Const, Variable, Absolute) */
0x95, 0x06, /* Report Count (6) */ 0x95, 0x06, /* Report Count (6) */
0x75, 0x08, /* Report Size (8) */ 0x75, 0x08, /* Report Size (8) */
0x15, 0x00, /* Logical Minimum (0) */ 0x15, 0x00, /* Logical Minimum (0) */
0x25, 0x65, /* Logical Maximum (101) */ 0x25, 0x65, /* Logical Maximum (101) */
0x05, 0x07, /* Usage Page (Keyboard) */ 0x05, 0x07, /* Usage Page (Keyboard) */
0x19, 0x00, /* Usage Minimum (Reserved (no event indicated)) */ 0x19, 0x00, /* Usage Minimum (Reserved (no event indicated)) */
0x29, 0x65, /* Usage Maximum (Keyboard Application) */ 0x29, 0x65, /* Usage Maximum (Keyboard Application) */
0x81, 0x00, /* Input (Data, Array, Absolute) */ 0x81, 0x00, /* Input (Data, Array, Absolute) */
0xC0 /* End Collection */ 0xC0 /* End Collection */
}; };
/** Device descriptor structure. This descriptor, located in FLASH memory, describes the overall /** Device descriptor structure. This descriptor, located in FLASH memory, describes the overall
* device characteristics, including the supported USB version, control endpoint size and the * device characteristics, including the supported USB version, control endpoint size and the
* number of device configurations. The descriptor is read out by the USB host when the enumeration * number of device configurations. The descriptor is read out by the USB host when the enumeration
* process begins. * process begins.
*/ */
USB_Descriptor_Device_t PROGMEM DeviceDescriptor = USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
{ {
.Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device}, .Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device},
.USBSpecification = VERSION_BCD(01.10), .USBSpecification = VERSION_BCD(01.10),
.Class = 0x00, .Class = 0x00,
.SubClass = 0x00, .SubClass = 0x00,
.Protocol = 0x00, .Protocol = 0x00,
.Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE, .Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE,
.VendorID = 0x03EB, .VendorID = 0x03EB,
.ProductID = 0x204D, .ProductID = 0x204D,
.ReleaseNumber = 0x0000, .ReleaseNumber = 0x0000,
.ManufacturerStrIndex = 0x01, .ManufacturerStrIndex = 0x01,
.ProductStrIndex = 0x02, .ProductStrIndex = 0x02,
.SerialNumStrIndex = NO_DESCRIPTOR, .SerialNumStrIndex = NO_DESCRIPTOR,
.NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS .NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS
}; };
/** Configuration descriptor structure. This descriptor, located in FLASH memory, describes the usage /** Configuration descriptor structure. This descriptor, located in FLASH memory, describes the usage
* of the device in one of its supported configurations, including information about any device interfaces * of the device in one of its supported configurations, including information about any device interfaces
* and endpoints. The descriptor is read out by the USB host during the enumeration process when selecting * and endpoints. The descriptor is read out by the USB host during the enumeration process when selecting
* a configuration so that the host may correctly communicate with the USB device. * a configuration so that the host may correctly communicate with the USB device.
*/ */
USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor = USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
{ {
.Config = .Config =
{ {
.Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration}, .Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration},
.TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t), .TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t),
.TotalInterfaces = 2, .TotalInterfaces = 2,
.ConfigurationNumber = 1, .ConfigurationNumber = 1,
.ConfigurationStrIndex = NO_DESCRIPTOR, .ConfigurationStrIndex = NO_DESCRIPTOR,
.ConfigAttributes = (USB_CONFIG_ATTR_BUSPOWERED | USB_CONFIG_ATTR_SELFPOWERED), .ConfigAttributes = (USB_CONFIG_ATTR_BUSPOWERED | USB_CONFIG_ATTR_SELFPOWERED),
.MaxPowerConsumption = USB_CONFIG_POWER_MA(100) .MaxPowerConsumption = USB_CONFIG_POWER_MA(100)
}, },
.HID1_KeyboardInterface = .HID1_KeyboardInterface =
{ {
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface}, .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
.InterfaceNumber = 0x00, .InterfaceNumber = 0x00,
.AlternateSetting = 0x00, .AlternateSetting = 0x00,
.TotalEndpoints = 1, .TotalEndpoints = 1,
.Class = 0x03, .Class = 0x03,
.SubClass = 0x01, .SubClass = 0x01,
.Protocol = HID_BOOT_KEYBOARD_PROTOCOL, .Protocol = HID_BOOT_KEYBOARD_PROTOCOL,
.InterfaceStrIndex = NO_DESCRIPTOR .InterfaceStrIndex = NO_DESCRIPTOR
}, },
.HID1_KeyboardHID = .HID1_KeyboardHID =
{ {
.Header = {.Size = sizeof(USB_HID_Descriptor_t), .Type = DTYPE_HID}, .Header = {.Size = sizeof(USB_HID_Descriptor_t), .Type = DTYPE_HID},
.HIDSpec = VERSION_BCD(01.11), .HIDSpec = VERSION_BCD(01.11),
.CountryCode = 0x00, .CountryCode = 0x00,
.TotalReportDescriptors = 1, .TotalReportDescriptors = 1,
.HIDReportType = DTYPE_Report, .HIDReportType = DTYPE_Report,
.HIDReportLength = sizeof(KeyboardReport) .HIDReportLength = sizeof(KeyboardReport)
}, },
.HID1_ReportINEndpoint = .HID1_ReportINEndpoint =
{ {
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint}, .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
.EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_IN | KEYBOARD_IN_EPNUM), .EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_IN | KEYBOARD_IN_EPNUM),
.Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
.EndpointSize = HID_EPSIZE, .EndpointSize = HID_EPSIZE,
.PollingIntervalMS = 0x0A .PollingIntervalMS = 0x0A
}, },
.HID2_MouseInterface = .HID2_MouseInterface =
{ {
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface}, .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
.InterfaceNumber = 0x01, .InterfaceNumber = 0x01,
.AlternateSetting = 0x00, .AlternateSetting = 0x00,
.TotalEndpoints = 1, .TotalEndpoints = 1,
.Class = 0x03, .Class = 0x03,
.SubClass = 0x01, .SubClass = 0x01,
.Protocol = HID_BOOT_MOUSE_PROTOCOL, .Protocol = HID_BOOT_MOUSE_PROTOCOL,
.InterfaceStrIndex = NO_DESCRIPTOR .InterfaceStrIndex = NO_DESCRIPTOR
}, },
.HID2_MouseHID = .HID2_MouseHID =
{ {
.Header = {.Size = sizeof(USB_HID_Descriptor_t), .Type = DTYPE_HID}, .Header = {.Size = sizeof(USB_HID_Descriptor_t), .Type = DTYPE_HID},
.HIDSpec = VERSION_BCD(01.11), .HIDSpec = VERSION_BCD(01.11),
.CountryCode = 0x00, .CountryCode = 0x00,
.TotalReportDescriptors = 1, .TotalReportDescriptors = 1,
.HIDReportType = DTYPE_Report, .HIDReportType = DTYPE_Report,
.HIDReportLength = sizeof(MouseReport) .HIDReportLength = sizeof(MouseReport)
}, },
.HID2_ReportINEndpoint = .HID2_ReportINEndpoint =
{ {
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint}, .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
.EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_IN | MOUSE_IN_EPNUM), .EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_IN | MOUSE_IN_EPNUM),
.Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
.EndpointSize = HID_EPSIZE, .EndpointSize = HID_EPSIZE,
.PollingIntervalMS = 0x0A .PollingIntervalMS = 0x0A
} }
}; };
/** Language descriptor structure. This descriptor, located in FLASH memory, is returned when the host requests /** Language descriptor structure. This descriptor, located in FLASH memory, is returned when the host requests
* the string descriptor with index 0 (the first index). It is actually an array of 16-bit integers, which indicate * the string descriptor with index 0 (the first index). It is actually an array of 16-bit integers, which indicate
* via the language ID table available at USB.org what languages the device supports for its string descriptors. * via the language ID table available at USB.org what languages the device supports for its string descriptors.
*/ */
USB_Descriptor_String_t PROGMEM LanguageString = USB_Descriptor_String_t PROGMEM LanguageString =
{ {
.Header = {.Size = USB_STRING_LEN(1), .Type = DTYPE_String}, .Header = {.Size = USB_STRING_LEN(1), .Type = DTYPE_String},
.UnicodeString = {LANGUAGE_ID_ENG} .UnicodeString = {LANGUAGE_ID_ENG}
}; };
/** Manufacturer descriptor string. This is a Unicode string containing the manufacturer's details in human readable /** Manufacturer descriptor string. This is a Unicode string containing the manufacturer's details in human readable
* form, and is read out upon request by the host when the appropriate string ID is requested, listed in the Device * form, and is read out upon request by the host when the appropriate string ID is requested, listed in the Device
* Descriptor. * Descriptor.
*/ */
USB_Descriptor_String_t PROGMEM ManufacturerString = USB_Descriptor_String_t PROGMEM ManufacturerString =
{ {
.Header = {.Size = USB_STRING_LEN(11), .Type = DTYPE_String}, .Header = {.Size = USB_STRING_LEN(11), .Type = DTYPE_String},
.UnicodeString = L"Dean Camera" .UnicodeString = L"Dean Camera"
}; };
/** Product descriptor string. This is a Unicode string containing the product's details in human readable form, /** Product descriptor string. This is a Unicode string containing the product's details in human readable form,
* and is read out upon request by the host when the appropriate string ID is requested, listed in the Device * and is read out upon request by the host when the appropriate string ID is requested, listed in the Device
* Descriptor. * Descriptor.
*/ */
USB_Descriptor_String_t PROGMEM ProductString = USB_Descriptor_String_t PROGMEM ProductString =
{ {
.Header = {.Size = USB_STRING_LEN(28), .Type = DTYPE_String}, .Header = {.Size = USB_STRING_LEN(28), .Type = DTYPE_String},
.UnicodeString = L"LUFA Mouse and Keyboard Demo" .UnicodeString = L"LUFA Mouse and Keyboard Demo"
}; };
/** This function is called by the library when in device mode, and must be overridden (see library "USB Descriptors" /** This function is called by the library when in device mode, and must be overridden (see library "USB Descriptors"
* documentation) by the application code so that the address and size of a requested descriptor can be given * documentation) by the application code so that the address and size of a requested descriptor can be given
* to the USB library. When the device receives a Get Descriptor request on the control endpoint, this function * to the USB library. When the device receives a Get Descriptor request on the control endpoint, this function
* is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the * is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the
* USB host. * USB host.
*/ */
uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, void** const DescriptorAddress) uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, void** const DescriptorAddress)
{ {
const uint8_t DescriptorType = (wValue >> 8); const uint8_t DescriptorType = (wValue >> 8);
const uint8_t DescriptorNumber = (wValue & 0xFF); const uint8_t DescriptorNumber = (wValue & 0xFF);
void* Address = NULL; void* Address = NULL;
uint16_t Size = NO_DESCRIPTOR; uint16_t Size = NO_DESCRIPTOR;
switch (DescriptorType) switch (DescriptorType)
{ {
case DTYPE_Device: case DTYPE_Device:
Address = (void*)&DeviceDescriptor; Address = (void*)&DeviceDescriptor;
Size = sizeof(USB_Descriptor_Device_t); Size = sizeof(USB_Descriptor_Device_t);
break; break;
case DTYPE_Configuration: case DTYPE_Configuration:
Address = (void*)&ConfigurationDescriptor; Address = (void*)&ConfigurationDescriptor;
Size = sizeof(USB_Descriptor_Configuration_t); Size = sizeof(USB_Descriptor_Configuration_t);
break; break;
case DTYPE_String: case DTYPE_String:
switch (DescriptorNumber) switch (DescriptorNumber)
{ {
case 0x00: case 0x00:
Address = (void*)&LanguageString; Address = (void*)&LanguageString;
Size = pgm_read_byte(&LanguageString.Header.Size); Size = pgm_read_byte(&LanguageString.Header.Size);
break; break;
case 0x01: case 0x01:
Address = (void*)&ManufacturerString; Address = (void*)&ManufacturerString;
Size = pgm_read_byte(&ManufacturerString.Header.Size); Size = pgm_read_byte(&ManufacturerString.Header.Size);
break; break;
case 0x02: case 0x02:
Address = (void*)&ProductString; Address = (void*)&ProductString;
Size = pgm_read_byte(&ProductString.Header.Size); Size = pgm_read_byte(&ProductString.Header.Size);
break; break;
} }
break; break;
case DTYPE_HID: case DTYPE_HID:
if (!(wIndex)) if (!(wIndex))
{ {
Address = (void*)&ConfigurationDescriptor.HID1_KeyboardHID; Address = (void*)&ConfigurationDescriptor.HID1_KeyboardHID;
Size = sizeof(USB_HID_Descriptor_t); Size = sizeof(USB_HID_Descriptor_t);
} }
else else
{ {
Address = (void*)&ConfigurationDescriptor.HID2_MouseHID; Address = (void*)&ConfigurationDescriptor.HID2_MouseHID;
Size = sizeof(USB_HID_Descriptor_t); Size = sizeof(USB_HID_Descriptor_t);
} }
break; break;
case DTYPE_Report: case DTYPE_Report:
if (!(wIndex)) if (!(wIndex))
{ {
Address = (void*)&KeyboardReport; Address = (void*)&KeyboardReport;
Size = sizeof(KeyboardReport); Size = sizeof(KeyboardReport);
} }
else else
{ {
Address = (void*)&MouseReport; Address = (void*)&MouseReport;
Size = sizeof(MouseReport); Size = sizeof(MouseReport);
} }
break; break;
} }
*DescriptorAddress = Address; *DescriptorAddress = Address;
return Size; return Size;
} }

View file

@ -1,76 +1,76 @@
/* /*
LUFA Library LUFA Library
Copyright (C) Dean Camera, 2010. Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com www.fourwalledcubicle.com
*/ */
/* /*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com) Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Copyright 2010 Denver Gingerich (denver [at] ossguy [dot] com) Copyright 2010 Denver Gingerich (denver [at] ossguy [dot] com)
Permission to use, copy, modify, distribute, and sell this Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the advertising or publicity pertaining to distribution of the
software without specific, written prior permission. software without specific, written prior permission.
The author disclaim all warranties with regard to this The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action, in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of arising out of or in connection with the use or performance of
this software. this software.
*/ */
/** \file /** \file
* *
* Header file for Descriptors.c. * Header file for Descriptors.c.
*/ */
#ifndef _DESCRIPTORS_H_ #ifndef _DESCRIPTORS_H_
#define _DESCRIPTORS_H_ #define _DESCRIPTORS_H_
/* Includes: */ /* Includes: */
#include <avr/pgmspace.h> #include <avr/pgmspace.h>
#include <LUFA/Drivers/USB/USB.h> #include <LUFA/Drivers/USB/USB.h>
#include <LUFA/Drivers/USB/Class/HID.h> #include <LUFA/Drivers/USB/Class/HID.h>
/* Type Defines: */ /* Type Defines: */
/** Type define for the device configuration descriptor structure. This must be defined in the /** Type define for the device configuration descriptor structure. This must be defined in the
* application code, as the configuration descriptor contains several sub-descriptors which * application code, as the configuration descriptor contains several sub-descriptors which
* vary between devices, and which describe the device's usage to the host. * vary between devices, and which describe the device's usage to the host.
*/ */
typedef struct typedef struct
{ {
USB_Descriptor_Configuration_Header_t Config; USB_Descriptor_Configuration_Header_t Config;
USB_Descriptor_Interface_t HID1_KeyboardInterface; USB_Descriptor_Interface_t HID1_KeyboardInterface;
USB_HID_Descriptor_t HID1_KeyboardHID; USB_HID_Descriptor_t HID1_KeyboardHID;
USB_Descriptor_Endpoint_t HID1_ReportINEndpoint; USB_Descriptor_Endpoint_t HID1_ReportINEndpoint;
USB_Descriptor_Interface_t HID2_MouseInterface; USB_Descriptor_Interface_t HID2_MouseInterface;
USB_HID_Descriptor_t HID2_MouseHID; USB_HID_Descriptor_t HID2_MouseHID;
USB_Descriptor_Endpoint_t HID2_ReportINEndpoint; USB_Descriptor_Endpoint_t HID2_ReportINEndpoint;
} USB_Descriptor_Configuration_t; } USB_Descriptor_Configuration_t;
/* Macros: */ /* Macros: */
/** Endpoint number of the Keyboard HID reporting IN endpoint. */ /** Endpoint number of the Keyboard HID reporting IN endpoint. */
#define KEYBOARD_IN_EPNUM 1 #define KEYBOARD_IN_EPNUM 1
/** Endpoint number of the Mouse HID reporting IN endpoint. */ /** Endpoint number of the Mouse HID reporting IN endpoint. */
#define MOUSE_IN_EPNUM 3 #define MOUSE_IN_EPNUM 3
/** Size in bytes of each of the HID reporting IN and OUT endpoints. */ /** Size in bytes of each of the HID reporting IN and OUT endpoints. */
#define HID_EPSIZE 8 #define HID_EPSIZE 8
/* Function Prototypes: */ /* Function Prototypes: */
uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, void** const DescriptorAddress) uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, void** const DescriptorAddress)
ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3); ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3);
#endif #endif

File diff suppressed because it is too large Load diff

View file

@ -1,253 +1,253 @@
/* /*
LUFA Library LUFA Library
Copyright (C) Dean Camera, 2010. Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com www.fourwalledcubicle.com
*/ */
/* /*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com) Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the advertising or publicity pertaining to distribution of the
software without specific, written prior permission. software without specific, written prior permission.
The author disclaim all warranties with regard to this The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action, in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of arising out of or in connection with the use or performance of
this software. this software.
*/ */
/** \file /** \file
* *
* Main source file for the KeyboardMouse demo. This file contains the main tasks of * Main source file for the KeyboardMouse demo. This file contains the main tasks of
* the demo and is responsible for the initial application hardware configuration. * the demo and is responsible for the initial application hardware configuration.
*/ */
#include "KeyboardMouse.h" #include "KeyboardMouse.h"
/** Buffer to hold the previously generated Keyboard HID report, for comparison purposes inside the HID class driver. */ /** Buffer to hold the previously generated Keyboard HID report, for comparison purposes inside the HID class driver. */
uint8_t PrevKeyboardHIDReportBuffer[sizeof(USB_KeyboardReport_Data_t)]; uint8_t PrevKeyboardHIDReportBuffer[sizeof(USB_KeyboardReport_Data_t)];
/** Buffer to hold the previously generated Mouse HID report, for comparison purposes inside the HID class driver. */ /** Buffer to hold the previously generated Mouse HID report, for comparison purposes inside the HID class driver. */
uint8_t PrevMouseHIDReportBuffer[sizeof(USB_MouseReport_Data_t)]; uint8_t PrevMouseHIDReportBuffer[sizeof(USB_MouseReport_Data_t)];
/** LUFA HID Class driver interface configuration and state information. This structure is /** 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 * passed to all HID Class driver functions, so that multiple instances of the same class
* within a device can be differentiated from one another. This is for the keyboard HID * within a device can be differentiated from one another. This is for the keyboard HID
* interface within the device. * interface within the device.
*/ */
USB_ClassInfo_HID_Device_t Keyboard_HID_Interface = USB_ClassInfo_HID_Device_t Keyboard_HID_Interface =
{ {
.Config = .Config =
{ {
.InterfaceNumber = 0, .InterfaceNumber = 0,
.ReportINEndpointNumber = KEYBOARD_IN_EPNUM, .ReportINEndpointNumber = KEYBOARD_IN_EPNUM,
.ReportINEndpointSize = HID_EPSIZE, .ReportINEndpointSize = HID_EPSIZE,
.ReportINEndpointDoubleBank = false, .ReportINEndpointDoubleBank = false,
.PrevReportINBuffer = PrevKeyboardHIDReportBuffer, .PrevReportINBuffer = PrevKeyboardHIDReportBuffer,
.PrevReportINBufferSize = sizeof(PrevKeyboardHIDReportBuffer), .PrevReportINBufferSize = sizeof(PrevKeyboardHIDReportBuffer),
}, },
}; };
/** LUFA HID Class driver interface configuration and state information. This structure is /** 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 * passed to all HID Class driver functions, so that multiple instances of the same class
* within a device can be differentiated from one another. This is for the mouse HID * within a device can be differentiated from one another. This is for the mouse HID
* interface within the device. * interface within the device.
*/ */
USB_ClassInfo_HID_Device_t Mouse_HID_Interface = USB_ClassInfo_HID_Device_t Mouse_HID_Interface =
{ {
.Config = .Config =
{ {
.InterfaceNumber = 1, .InterfaceNumber = 1,
.ReportINEndpointNumber = MOUSE_IN_EPNUM, .ReportINEndpointNumber = MOUSE_IN_EPNUM,
.ReportINEndpointSize = HID_EPSIZE, .ReportINEndpointSize = HID_EPSIZE,
.PrevReportINBuffer = PrevMouseHIDReportBuffer, .PrevReportINBuffer = PrevMouseHIDReportBuffer,
.PrevReportINBufferSize = sizeof(PrevMouseHIDReportBuffer), .PrevReportINBufferSize = sizeof(PrevMouseHIDReportBuffer),
}, },
}; };
/** Main program entry point. This routine contains the overall program flow, including initial /** Main program entry point. This routine contains the overall program flow, including initial
* setup of all components and the main program loop. * setup of all components and the main program loop.
*/ */
int main(void) int main(void)
{ {
SetupHardware(); SetupHardware();
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY); LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
sei(); sei();
for (;;) for (;;)
{ {
HID_Device_USBTask(&Keyboard_HID_Interface); HID_Device_USBTask(&Keyboard_HID_Interface);
HID_Device_USBTask(&Mouse_HID_Interface); HID_Device_USBTask(&Mouse_HID_Interface);
USB_USBTask(); USB_USBTask();
} }
} }
/** Configures the board hardware and chip peripherals for the demo's functionality. */ /** Configures the board hardware and chip peripherals for the demo's functionality. */
void SetupHardware() void SetupHardware()
{ {
/* Disable watchdog if enabled by bootloader/fuses */ /* Disable watchdog if enabled by bootloader/fuses */
MCUSR &= ~(1 << WDRF); MCUSR &= ~(1 << WDRF);
wdt_disable(); wdt_disable();
/* Disable clock division */ /* Disable clock division */
clock_prescale_set(clock_div_1); clock_prescale_set(clock_div_1);
/* Hardware Initialization */ /* Hardware Initialization */
Joystick_Init(); Joystick_Init();
LEDs_Init(); LEDs_Init();
USB_Init(); USB_Init();
} }
/** Event handler for the library USB Connection event. */ /** Event handler for the library USB Connection event. */
void EVENT_USB_Device_Connect(void) void EVENT_USB_Device_Connect(void)
{ {
LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING); LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
} }
/** Event handler for the library USB Disconnection event. */ /** Event handler for the library USB Disconnection event. */
void EVENT_USB_Device_Disconnect(void) void EVENT_USB_Device_Disconnect(void)
{ {
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY); LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
} }
/** Event handler for the library USB Configuration Changed event. */ /** Event handler for the library USB Configuration Changed event. */
void EVENT_USB_Device_ConfigurationChanged(void) void EVENT_USB_Device_ConfigurationChanged(void)
{ {
LEDs_SetAllLEDs(LEDMASK_USB_READY); LEDs_SetAllLEDs(LEDMASK_USB_READY);
if (!(HID_Device_ConfigureEndpoints(&Keyboard_HID_Interface))) if (!(HID_Device_ConfigureEndpoints(&Keyboard_HID_Interface)))
LEDs_SetAllLEDs(LEDMASK_USB_ERROR); LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
if (!(HID_Device_ConfigureEndpoints(&Mouse_HID_Interface))) if (!(HID_Device_ConfigureEndpoints(&Mouse_HID_Interface)))
LEDs_SetAllLEDs(LEDMASK_USB_ERROR); LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
USB_Device_EnableSOFEvents(); USB_Device_EnableSOFEvents();
} }
/** Event handler for the library USB Unhandled Control Request event. */ /** Event handler for the library USB Unhandled Control Request event. */
void EVENT_USB_Device_UnhandledControlRequest(void) void EVENT_USB_Device_UnhandledControlRequest(void)
{ {
HID_Device_ProcessControlRequest(&Keyboard_HID_Interface); HID_Device_ProcessControlRequest(&Keyboard_HID_Interface);
HID_Device_ProcessControlRequest(&Mouse_HID_Interface); HID_Device_ProcessControlRequest(&Mouse_HID_Interface);
} }
/** Event handler for the USB device Start Of Frame event. */ /** Event handler for the USB device Start Of Frame event. */
void EVENT_USB_Device_StartOfFrame(void) void EVENT_USB_Device_StartOfFrame(void)
{ {
HID_Device_MillisecondElapsed(&Keyboard_HID_Interface); HID_Device_MillisecondElapsed(&Keyboard_HID_Interface);
HID_Device_MillisecondElapsed(&Mouse_HID_Interface); HID_Device_MillisecondElapsed(&Mouse_HID_Interface);
} }
/** HID class driver callback function for the creation of HID reports to the host. /** HID class driver callback function for the creation of HID reports to the host.
* *
* \param[in] HIDInterfaceInfo Pointer to the HID class interface configuration structure being referenced * \param[in] HIDInterfaceInfo Pointer to the HID class interface configuration structure being referenced
* \param[in,out] ReportID Report ID requested by the host if non-zero, otherwise callback should set to the generated report ID * \param[in,out] ReportID Report ID requested by the host if non-zero, otherwise callback should set to the generated report ID
* \param[in] ReportType Type of the report to create, either REPORT_ITEM_TYPE_In or REPORT_ITEM_TYPE_Feature * \param[in] ReportType Type of the report to create, either REPORT_ITEM_TYPE_In or REPORT_ITEM_TYPE_Feature
* \param[out] ReportData Pointer to a buffer where the created report should be stored * \param[out] ReportData Pointer to a buffer where the created report should be stored
* \param[out] ReportSize Number of bytes written in the report (or zero if no report is to be sent * \param[out] ReportSize Number of bytes written in the report (or zero if no report is to be sent
* *
* \return Boolean true to force the sending of the report, false to let the library determine if it needs to be sent * \return Boolean true to force the sending of the report, false to let the library determine if it needs to be sent
*/ */
bool CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, uint8_t* const ReportID, bool CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, uint8_t* const ReportID,
const uint8_t ReportType, void* ReportData, uint16_t* ReportSize) const uint8_t ReportType, void* ReportData, uint16_t* ReportSize)
{ {
uint8_t JoyStatus_LCL = Joystick_GetStatus(); uint8_t JoyStatus_LCL = Joystick_GetStatus();
uint8_t ButtonStatus_LCL = Buttons_GetStatus(); uint8_t ButtonStatus_LCL = Buttons_GetStatus();
/* Determine which interface must have its report generated */ /* Determine which interface must have its report generated */
if (HIDInterfaceInfo == &Keyboard_HID_Interface) if (HIDInterfaceInfo == &Keyboard_HID_Interface)
{ {
USB_KeyboardReport_Data_t* KeyboardReport = (USB_KeyboardReport_Data_t*)ReportData; USB_KeyboardReport_Data_t* KeyboardReport = (USB_KeyboardReport_Data_t*)ReportData;
/* If first board button not being held down, no keyboard report */ /* If first board button not being held down, no keyboard report */
if (!(ButtonStatus_LCL & BUTTONS_BUTTON1)) if (!(ButtonStatus_LCL & BUTTONS_BUTTON1))
return 0; return 0;
KeyboardReport->Modifier = HID_KEYBOARD_MODIFER_LEFTSHIFT; KeyboardReport->Modifier = HID_KEYBOARD_MODIFER_LEFTSHIFT;
if (JoyStatus_LCL & JOY_UP) if (JoyStatus_LCL & JOY_UP)
KeyboardReport->KeyCode[0] = 0x04; // A KeyboardReport->KeyCode[0] = 0x04; // A
else if (JoyStatus_LCL & JOY_DOWN) else if (JoyStatus_LCL & JOY_DOWN)
KeyboardReport->KeyCode[0] = 0x05; // B KeyboardReport->KeyCode[0] = 0x05; // B
if (JoyStatus_LCL & JOY_LEFT) if (JoyStatus_LCL & JOY_LEFT)
KeyboardReport->KeyCode[0] = 0x06; // C KeyboardReport->KeyCode[0] = 0x06; // C
else if (JoyStatus_LCL & JOY_RIGHT) else if (JoyStatus_LCL & JOY_RIGHT)
KeyboardReport->KeyCode[0] = 0x07; // D KeyboardReport->KeyCode[0] = 0x07; // D
if (JoyStatus_LCL & JOY_PRESS) if (JoyStatus_LCL & JOY_PRESS)
KeyboardReport->KeyCode[0] = 0x08; // E KeyboardReport->KeyCode[0] = 0x08; // E
*ReportSize = sizeof(USB_KeyboardReport_Data_t); *ReportSize = sizeof(USB_KeyboardReport_Data_t);
return false; return false;
} }
else else
{ {
USB_MouseReport_Data_t* MouseReport = (USB_MouseReport_Data_t*)ReportData; USB_MouseReport_Data_t* MouseReport = (USB_MouseReport_Data_t*)ReportData;
/* If first board button being held down, no mouse report */ /* If first board button being held down, no mouse report */
if (ButtonStatus_LCL & BUTTONS_BUTTON1) if (ButtonStatus_LCL & BUTTONS_BUTTON1)
return 0; return 0;
if (JoyStatus_LCL & JOY_UP) if (JoyStatus_LCL & JOY_UP)
MouseReport->Y = -1; MouseReport->Y = -1;
else if (JoyStatus_LCL & JOY_DOWN) else if (JoyStatus_LCL & JOY_DOWN)
MouseReport->Y = 1; MouseReport->Y = 1;
if (JoyStatus_LCL & JOY_LEFT) if (JoyStatus_LCL & JOY_LEFT)
MouseReport->X = -1; MouseReport->X = -1;
else if (JoyStatus_LCL & JOY_RIGHT) else if (JoyStatus_LCL & JOY_RIGHT)
MouseReport->X = 1; MouseReport->X = 1;
if (JoyStatus_LCL & JOY_PRESS) if (JoyStatus_LCL & JOY_PRESS)
MouseReport->Button |= (1 << 0); MouseReport->Button |= (1 << 0);
*ReportSize = sizeof(USB_MouseReport_Data_t); *ReportSize = sizeof(USB_MouseReport_Data_t);
return true; return true;
} }
} }
/** HID class driver callback function for the processing of HID reports from the host. /** HID class driver callback function for the processing of HID reports from the host.
* *
* \param[in] HIDInterfaceInfo Pointer to the HID class interface configuration structure being referenced * \param[in] HIDInterfaceInfo Pointer to the HID class interface configuration structure being referenced
* \param[in] ReportID Report ID of the received report from the host * \param[in] ReportID Report ID of the received report from the host
* \param[in] ReportData Pointer to a buffer where the created report has been stored * \param[in] ReportData Pointer to a buffer where the created report has been stored
* \param[in] ReportSize Size in bytes of the received HID report * \param[in] ReportSize Size in bytes of the received HID report
*/ */
void CALLBACK_HID_Device_ProcessHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, const uint8_t ReportID, void CALLBACK_HID_Device_ProcessHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, const uint8_t ReportID,
const void* ReportData, const uint16_t ReportSize) const void* ReportData, const uint16_t ReportSize)
{ {
if (HIDInterfaceInfo == &Keyboard_HID_Interface) if (HIDInterfaceInfo == &Keyboard_HID_Interface)
{ {
uint8_t LEDMask = LEDS_NO_LEDS; uint8_t LEDMask = LEDS_NO_LEDS;
uint8_t* LEDReport = (uint8_t*)ReportData; uint8_t* LEDReport = (uint8_t*)ReportData;
if (*LEDReport & HID_KEYBOARD_LED_NUMLOCK) if (*LEDReport & HID_KEYBOARD_LED_NUMLOCK)
LEDMask |= LEDS_LED1; LEDMask |= LEDS_LED1;
if (*LEDReport & HID_KEYBOARD_LED_CAPSLOCK) if (*LEDReport & HID_KEYBOARD_LED_CAPSLOCK)
LEDMask |= LEDS_LED3; LEDMask |= LEDS_LED3;
if (*LEDReport & HID_KEYBOARD_LED_SCROLLLOCK) if (*LEDReport & HID_KEYBOARD_LED_SCROLLLOCK)
LEDMask |= LEDS_LED4; LEDMask |= LEDS_LED4;
LEDs_SetAllLEDs(LEDMask); LEDs_SetAllLEDs(LEDMask);
} }
} }

View file

@ -1,79 +1,79 @@
/* /*
LUFA Library LUFA Library
Copyright (C) Dean Camera, 2010. Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com www.fourwalledcubicle.com
*/ */
/* /*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com) Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Copyright 2010 Denver Gingerich (denver [at] ossguy [dot] com) Copyright 2010 Denver Gingerich (denver [at] ossguy [dot] com)
Permission to use, copy, modify, distribute, and sell this Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the advertising or publicity pertaining to distribution of the
software without specific, written prior permission. software without specific, written prior permission.
The author disclaim all warranties with regard to this The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action, in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of arising out of or in connection with the use or performance of
this software. this software.
*/ */
#ifndef _KEYBOARD_MOUSE_H_ #ifndef _KEYBOARD_MOUSE_H_
#define _KEYBOARD_MOUSE_H_ #define _KEYBOARD_MOUSE_H_
/* Includes: */ /* Includes: */
#include <avr/io.h> #include <avr/io.h>
#include <avr/wdt.h> #include <avr/wdt.h>
#include <avr/power.h> #include <avr/power.h>
#include <avr/interrupt.h> #include <avr/interrupt.h>
#include <stdbool.h> #include <stdbool.h>
#include <string.h> #include <string.h>
#include "Descriptors.h" #include "Descriptors.h"
#include <LUFA/Version.h> #include <LUFA/Version.h>
#include <LUFA/Drivers/Board/Joystick.h> #include <LUFA/Drivers/Board/Joystick.h>
#include <LUFA/Drivers/Board/LEDs.h> #include <LUFA/Drivers/Board/LEDs.h>
#include <LUFA/Drivers/Board/Buttons.h> #include <LUFA/Drivers/Board/Buttons.h>
#include <LUFA/Drivers/USB/USB.h> #include <LUFA/Drivers/USB/USB.h>
#include <LUFA/Drivers/USB/Class/HID.h> #include <LUFA/Drivers/USB/Class/HID.h>
/* Macros: */ /* Macros: */
/** LED mask for the library LED driver, to indicate that the USB interface is not ready. */ /** LED mask for the library LED driver, to indicate that the USB interface is not ready. */
#define LEDMASK_USB_NOTREADY LEDS_LED1 #define LEDMASK_USB_NOTREADY LEDS_LED1
/** LED mask for the library LED driver, to indicate that the USB interface is enumerating. */ /** LED mask for the library LED driver, to indicate that the USB interface is enumerating. */
#define LEDMASK_USB_ENUMERATING (LEDS_LED2 | LEDS_LED3) #define LEDMASK_USB_ENUMERATING (LEDS_LED2 | LEDS_LED3)
/** LED mask for the library LED driver, to indicate that the USB interface is ready. */ /** LED mask for the library LED driver, to indicate that the USB interface is ready. */
#define LEDMASK_USB_READY (LEDS_LED2 | LEDS_LED4) #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. */ /** 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) #define LEDMASK_USB_ERROR (LEDS_LED1 | LEDS_LED3)
/* Function Prototypes: */ /* Function Prototypes: */
void SetupHardware(void); void SetupHardware(void);
void EVENT_USB_Device_Connect(void); void EVENT_USB_Device_Connect(void);
void EVENT_USB_Device_Disconnect(void); void EVENT_USB_Device_Disconnect(void);
void EVENT_USB_Device_ConfigurationChanged(void); void EVENT_USB_Device_ConfigurationChanged(void);
void EVENT_USB_Device_UnhandledControlRequest(void); void EVENT_USB_Device_UnhandledControlRequest(void);
void EVENT_USB_Device_StartOfFrame(void); void EVENT_USB_Device_StartOfFrame(void);
bool CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, uint8_t* const ReportID, bool CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, uint8_t* const ReportID,
const uint8_t ReportType, void* ReportData, uint16_t* ReportSize); const uint8_t ReportType, void* ReportData, uint16_t* ReportSize);
void CALLBACK_HID_Device_ProcessHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, const uint8_t ReportID, void CALLBACK_HID_Device_ProcessHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, const uint8_t ReportID,
const void* ReportData, const uint16_t ReportSize); const void* ReportData, const uint16_t ReportSize);
#endif #endif

View file

@ -1,77 +1,77 @@
/** \file /** \file
* *
* This file contains special DoxyGen information for the generation of the main page and other special * 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. * documentation pages. It is not a project source file.
*/ */
/** \mainpage Dual HID Keyboard and Mouse Device Demo /** \mainpage Dual HID Keyboard and Mouse Device Demo
* *
* \section SSec_Compat Demo Compatibility: * \section SSec_Compat Demo Compatibility:
* *
* The following list indicates what microcontrollers are compatible with this demo. * The following list indicates what microcontrollers are compatible with this demo.
* *
* - Series 7 USB AVRs * - Series 7 USB AVRs
* - Series 6 USB AVRs * - Series 6 USB AVRs
* - Series 4 USB AVRs * - Series 4 USB AVRs
* - Series 2 USB AVRs * - Series 2 USB AVRs
* *
* \section SSec_Info USB Information: * \section SSec_Info USB Information:
* *
* The following table gives a rundown of the USB utilization of this demo. * The following table gives a rundown of the USB utilization of this demo.
* *
* <table> * <table>
* <tr> * <tr>
* <td><b>USB Mode:</b></td> * <td><b>USB Mode:</b></td>
* <td>Device</td> * <td>Device</td>
* </tr> * </tr>
* <tr> * <tr>
* <td><b>USB Class:</b></td> * <td><b>USB Class:</b></td>
* <td>Human Interface Device (HID)</td> * <td>Human Interface Device (HID)</td>
* </tr> * </tr>
* <tr> * <tr>
* <td><b>USB Subclass:</b></td> * <td><b>USB Subclass:</b></td>
* <td>N/A</td> * <td>N/A</td>
* </tr> * </tr>
* <tr> * <tr>
* <td><b>Relevant Standards:</b></td> * <td><b>Relevant Standards:</b></td>
* <td>USBIF HID Specification \n * <td>USBIF HID Specification \n
* USBIF HID Usage Tables</td> * USBIF HID Usage Tables</td>
* </tr> * </tr>
* <tr> * <tr>
* <td><b>Usable Speeds:</b></td> * <td><b>Usable Speeds:</b></td>
* <td>Low Speed Mode \n * <td>Low Speed Mode \n
* Full Speed Mode</td> * Full Speed Mode</td>
* </tr> * </tr>
* </table> * </table>
* *
* \section SSec_Description Project Description: * \section SSec_Description Project Description:
* *
* Keyboard/Mouse demonstration application. This gives a simple reference * Keyboard/Mouse demonstration application. This gives a simple reference
* application for implementing a composite device containing both USB Keyboard * application for implementing a composite device containing both USB Keyboard
* and USB Mouse functionality using the basic USB HID drivers in all modern OSes * and USB Mouse functionality using the basic USB HID drivers in all modern OSes
* (i.e. no special drivers required). This example uses two separate HID * (i.e. no special drivers required). This example uses two separate HID
* interfaces for each function. It is boot protocol compatible, and thus works under * interfaces for each function. It is boot protocol compatible, and thus works under
* compatible BIOS as if it was a native keyboard and mouse (e.g. PS/2). * compatible BIOS as if it was a native keyboard and mouse (e.g. PS/2).
* *
* On start-up the system will automatically enumerate and function * On start-up the system will automatically enumerate and function
* as a keyboard when the USB connection to a host is present and the HWB is not * as a keyboard when the USB connection to a host is present and the HWB is not
* pressed. When enabled, manipulate the joystick to send the letters * pressed. When enabled, manipulate the joystick to send the letters
* a, b, c, d and e. See the USB HID documentation for more information * a, b, c, d and e. See the USB HID documentation for more information
* on sending keyboard event and key presses. * on sending keyboard event and key presses.
* *
* When the HWB is pressed, the mouse mode is enabled. When enabled, move the * When the HWB is pressed, the mouse mode is enabled. When enabled, move the
* joystick to move the pointer, and push the joystick inwards to simulate a * joystick to move the pointer, and push the joystick inwards to simulate a
* left-button click. * left-button click.
* *
* \section SSec_Options Project Options * \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. * The following defines can be found in this demo, which can control the demo behaviour when defined, or changed in value.
* *
* <table> * <table>
* <tr> * <tr>
* <td> * <td>
* None * None
* </td> * </td>
* </tr> * </tr>
* </table> * </table>
*/ */

File diff suppressed because it is too large Load diff

View file

@ -1,326 +1,326 @@
/* /*
LUFA Library LUFA Library
Copyright (C) Dean Camera, 2010. Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com www.fourwalledcubicle.com
*/ */
/* /*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com) Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the advertising or publicity pertaining to distribution of the
software without specific, written prior permission. software without specific, written prior permission.
The author disclaim all warranties with regard to this The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action, in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of arising out of or in connection with the use or performance of
this software. this software.
*/ */
/** \file /** \file
* *
* USB Device Descriptors, for library use when in USB device mode. Descriptors are special * USB Device Descriptors, for library use when in USB device mode. Descriptors are special
* computer-readable structures which the host requests upon device enumeration, to determine * computer-readable structures which the host requests upon device enumeration, to determine
* the device's capabilities and functions. * the device's capabilities and functions.
*/ */
#include "Descriptors.h" #include "Descriptors.h"
/** Device descriptor structure. This descriptor, located in FLASH memory, describes the overall /** Device descriptor structure. This descriptor, located in FLASH memory, describes the overall
* device characteristics, including the supported USB version, control endpoint size and the * device characteristics, including the supported USB version, control endpoint size and the
* number of device configurations. The descriptor is read out by the USB host when the enumeration * number of device configurations. The descriptor is read out by the USB host when the enumeration
* process begins. * process begins.
*/ */
USB_Descriptor_Device_t PROGMEM DeviceDescriptor = USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
{ {
.Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device}, .Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device},
.USBSpecification = VERSION_BCD(01.10), .USBSpecification = VERSION_BCD(01.10),
.Class = 0x00, .Class = 0x00,
.SubClass = 0x00, .SubClass = 0x00,
.Protocol = 0x00, .Protocol = 0x00,
.Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE, .Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE,
.VendorID = 0x03EB, .VendorID = 0x03EB,
.ProductID = 0x2048, .ProductID = 0x2048,
.ReleaseNumber = 0x0000, .ReleaseNumber = 0x0000,
.ManufacturerStrIndex = 0x01, .ManufacturerStrIndex = 0x01,
.ProductStrIndex = 0x02, .ProductStrIndex = 0x02,
.SerialNumStrIndex = NO_DESCRIPTOR, .SerialNumStrIndex = NO_DESCRIPTOR,
.NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS .NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS
}; };
/** Configuration descriptor structure. This descriptor, located in FLASH memory, describes the usage /** Configuration descriptor structure. This descriptor, located in FLASH memory, describes the usage
* of the device in one of its supported configurations, including information about any device interfaces * of the device in one of its supported configurations, including information about any device interfaces
* and endpoints. The descriptor is read out by the USB host during the enumeration process when selecting * and endpoints. The descriptor is read out by the USB host during the enumeration process when selecting
* a configuration so that the host may correctly communicate with the USB device. * a configuration so that the host may correctly communicate with the USB device.
*/ */
USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor = USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
{ {
.Config = .Config =
{ {
.Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration}, .Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration},
.TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t), .TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t),
.TotalInterfaces = 2, .TotalInterfaces = 2,
.ConfigurationNumber = 1, .ConfigurationNumber = 1,
.ConfigurationStrIndex = NO_DESCRIPTOR, .ConfigurationStrIndex = NO_DESCRIPTOR,
.ConfigAttributes = (USB_CONFIG_ATTR_BUSPOWERED | USB_CONFIG_ATTR_SELFPOWERED), .ConfigAttributes = (USB_CONFIG_ATTR_BUSPOWERED | USB_CONFIG_ATTR_SELFPOWERED),
.MaxPowerConsumption = USB_CONFIG_POWER_MA(100) .MaxPowerConsumption = USB_CONFIG_POWER_MA(100)
}, },
.Audio_ControlInterface = .Audio_ControlInterface =
{ {
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface}, .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
.InterfaceNumber = 0, .InterfaceNumber = 0,
.AlternateSetting = 0, .AlternateSetting = 0,
.TotalEndpoints = 0, .TotalEndpoints = 0,
.Class = 0x01, .Class = 0x01,
.SubClass = 0x01, .SubClass = 0x01,
.Protocol = 0x00, .Protocol = 0x00,
.InterfaceStrIndex = NO_DESCRIPTOR .InterfaceStrIndex = NO_DESCRIPTOR
}, },
.Audio_ControlInterface_SPC = .Audio_ControlInterface_SPC =
{ {
.Header = {.Size = sizeof(USB_Audio_Interface_AC_t), .Type = DTYPE_AudioInterface}, .Header = {.Size = sizeof(USB_Audio_Interface_AC_t), .Type = DTYPE_AudioInterface},
.Subtype = DSUBTYPE_Header, .Subtype = DSUBTYPE_Header,
.ACSpecification = VERSION_BCD(01.00), .ACSpecification = VERSION_BCD(01.00),
.TotalLength = sizeof(USB_Audio_Interface_AC_t), .TotalLength = sizeof(USB_Audio_Interface_AC_t),
.InCollection = 1, .InCollection = 1,
.InterfaceNumbers = {1}, .InterfaceNumbers = {1},
}, },
.Audio_StreamInterface = .Audio_StreamInterface =
{ {
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface}, .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
.InterfaceNumber = 1, .InterfaceNumber = 1,
.AlternateSetting = 0, .AlternateSetting = 0,
.TotalEndpoints = 2, .TotalEndpoints = 2,
.Class = 0x01, .Class = 0x01,
.SubClass = 0x03, .SubClass = 0x03,
.Protocol = 0x00, .Protocol = 0x00,
.InterfaceStrIndex = NO_DESCRIPTOR .InterfaceStrIndex = NO_DESCRIPTOR
}, },
.Audio_StreamInterface_SPC = .Audio_StreamInterface_SPC =
{ {
.Header = {.Size = sizeof(USB_MIDI_AudioInterface_AS_t), .Type = DTYPE_AudioInterface}, .Header = {.Size = sizeof(USB_MIDI_AudioInterface_AS_t), .Type = DTYPE_AudioInterface},
.Subtype = DSUBTYPE_General, .Subtype = DSUBTYPE_General,
.AudioSpecification = VERSION_BCD(01.00), .AudioSpecification = VERSION_BCD(01.00),
.TotalLength = (sizeof(USB_Descriptor_Configuration_t) - .TotalLength = (sizeof(USB_Descriptor_Configuration_t) -
offsetof(USB_Descriptor_Configuration_t, Audio_StreamInterface_SPC)) offsetof(USB_Descriptor_Configuration_t, Audio_StreamInterface_SPC))
}, },
.MIDI_In_Jack_Emb = .MIDI_In_Jack_Emb =
{ {
.Header = {.Size = sizeof(USB_MIDI_In_Jack_t), .Type = DTYPE_AudioInterface}, .Header = {.Size = sizeof(USB_MIDI_In_Jack_t), .Type = DTYPE_AudioInterface},
.Subtype = DSUBTYPE_InputJack, .Subtype = DSUBTYPE_InputJack,
.JackType = MIDI_JACKTYPE_EMBEDDED, .JackType = MIDI_JACKTYPE_EMBEDDED,
.JackID = 0x01, .JackID = 0x01,
.JackStrIndex = NO_DESCRIPTOR .JackStrIndex = NO_DESCRIPTOR
}, },
.MIDI_In_Jack_Ext = .MIDI_In_Jack_Ext =
{ {
.Header = {.Size = sizeof(USB_MIDI_In_Jack_t), .Type = DTYPE_AudioInterface}, .Header = {.Size = sizeof(USB_MIDI_In_Jack_t), .Type = DTYPE_AudioInterface},
.Subtype = DSUBTYPE_InputJack, .Subtype = DSUBTYPE_InputJack,
.JackType = MIDI_JACKTYPE_EXTERNAL, .JackType = MIDI_JACKTYPE_EXTERNAL,
.JackID = 0x02, .JackID = 0x02,
.JackStrIndex = NO_DESCRIPTOR .JackStrIndex = NO_DESCRIPTOR
}, },
.MIDI_Out_Jack_Emb = .MIDI_Out_Jack_Emb =
{ {
.Header = {.Size = sizeof(USB_MIDI_Out_Jack_t), .Type = DTYPE_AudioInterface}, .Header = {.Size = sizeof(USB_MIDI_Out_Jack_t), .Type = DTYPE_AudioInterface},
.Subtype = DSUBTYPE_OutputJack, .Subtype = DSUBTYPE_OutputJack,
.JackType = MIDI_JACKTYPE_EMBEDDED, .JackType = MIDI_JACKTYPE_EMBEDDED,
.JackID = 0x03, .JackID = 0x03,
.NumberOfPins = 1, .NumberOfPins = 1,
.SourceJackID = {0x02}, .SourceJackID = {0x02},
.SourcePinID = {0x01}, .SourcePinID = {0x01},
.JackStrIndex = NO_DESCRIPTOR .JackStrIndex = NO_DESCRIPTOR
}, },
.MIDI_Out_Jack_Ext = .MIDI_Out_Jack_Ext =
{ {
.Header = {.Size = sizeof(USB_MIDI_Out_Jack_t), .Type = DTYPE_AudioInterface}, .Header = {.Size = sizeof(USB_MIDI_Out_Jack_t), .Type = DTYPE_AudioInterface},
.Subtype = DSUBTYPE_OutputJack, .Subtype = DSUBTYPE_OutputJack,
.JackType = MIDI_JACKTYPE_EXTERNAL, .JackType = MIDI_JACKTYPE_EXTERNAL,
.JackID = 0x04, .JackID = 0x04,
.NumberOfPins = 1, .NumberOfPins = 1,
.SourceJackID = {0x01}, .SourceJackID = {0x01},
.SourcePinID = {0x01}, .SourcePinID = {0x01},
.JackStrIndex = NO_DESCRIPTOR .JackStrIndex = NO_DESCRIPTOR
}, },
.MIDI_In_Jack_Endpoint = .MIDI_In_Jack_Endpoint =
{ {
.Endpoint = .Endpoint =
{ {
.Header = {.Size = sizeof(USB_Audio_StreamEndpoint_Std_t), .Type = DTYPE_Endpoint}, .Header = {.Size = sizeof(USB_Audio_StreamEndpoint_Std_t), .Type = DTYPE_Endpoint},
.EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_OUT | MIDI_STREAM_OUT_EPNUM), .EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_OUT | MIDI_STREAM_OUT_EPNUM),
.Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), .Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
.EndpointSize = MIDI_STREAM_EPSIZE, .EndpointSize = MIDI_STREAM_EPSIZE,
.PollingIntervalMS = 0 .PollingIntervalMS = 0
}, },
.Refresh = 0, .Refresh = 0,
.SyncEndpointNumber = 0 .SyncEndpointNumber = 0
}, },
.MIDI_In_Jack_Endpoint_SPC = .MIDI_In_Jack_Endpoint_SPC =
{ {
.Header = {.Size = sizeof(USB_MIDI_Jack_Endpoint_t), .Type = DTYPE_AudioEndpoint}, .Header = {.Size = sizeof(USB_MIDI_Jack_Endpoint_t), .Type = DTYPE_AudioEndpoint},
.Subtype = DSUBTYPE_General, .Subtype = DSUBTYPE_General,
.TotalEmbeddedJacks = 0x01, .TotalEmbeddedJacks = 0x01,
.AssociatedJackID = {0x01} .AssociatedJackID = {0x01}
}, },
.MIDI_Out_Jack_Endpoint = .MIDI_Out_Jack_Endpoint =
{ {
.Endpoint = .Endpoint =
{ {
.Header = {.Size = sizeof(USB_Audio_StreamEndpoint_Std_t), .Type = DTYPE_Endpoint}, .Header = {.Size = sizeof(USB_Audio_StreamEndpoint_Std_t), .Type = DTYPE_Endpoint},
.EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_IN | MIDI_STREAM_IN_EPNUM), .EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_IN | MIDI_STREAM_IN_EPNUM),
.Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), .Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
.EndpointSize = MIDI_STREAM_EPSIZE, .EndpointSize = MIDI_STREAM_EPSIZE,
.PollingIntervalMS = 0 .PollingIntervalMS = 0
}, },
.Refresh = 0, .Refresh = 0,
.SyncEndpointNumber = 0 .SyncEndpointNumber = 0
}, },
.MIDI_Out_Jack_Endpoint_SPC = .MIDI_Out_Jack_Endpoint_SPC =
{ {
.Header = {.Size = sizeof(USB_MIDI_Jack_Endpoint_t), .Type = DTYPE_AudioEndpoint}, .Header = {.Size = sizeof(USB_MIDI_Jack_Endpoint_t), .Type = DTYPE_AudioEndpoint},
.Subtype = DSUBTYPE_General, .Subtype = DSUBTYPE_General,
.TotalEmbeddedJacks = 0x01, .TotalEmbeddedJacks = 0x01,
.AssociatedJackID = {0x03} .AssociatedJackID = {0x03}
} }
}; };
/** Language descriptor structure. This descriptor, located in FLASH memory, is returned when the host requests /** Language descriptor structure. This descriptor, located in FLASH memory, is returned when the host requests
* the string descriptor with index 0 (the first index). It is actually an array of 16-bit integers, which indicate * the string descriptor with index 0 (the first index). It is actually an array of 16-bit integers, which indicate
* via the language ID table available at USB.org what languages the device supports for its string descriptors. * via the language ID table available at USB.org what languages the device supports for its string descriptors.
*/ */
USB_Descriptor_String_t PROGMEM LanguageString = USB_Descriptor_String_t PROGMEM LanguageString =
{ {
.Header = {.Size = USB_STRING_LEN(1), .Type = DTYPE_String}, .Header = {.Size = USB_STRING_LEN(1), .Type = DTYPE_String},
.UnicodeString = {LANGUAGE_ID_ENG} .UnicodeString = {LANGUAGE_ID_ENG}
}; };
/** Manufacturer descriptor string. This is a Unicode string containing the manufacturer's details in human readable /** Manufacturer descriptor string. This is a Unicode string containing the manufacturer's details in human readable
* form, and is read out upon request by the host when the appropriate string ID is requested, listed in the Device * form, and is read out upon request by the host when the appropriate string ID is requested, listed in the Device
* Descriptor. * Descriptor.
*/ */
USB_Descriptor_String_t PROGMEM ManufacturerString = USB_Descriptor_String_t PROGMEM ManufacturerString =
{ {
.Header = {.Size = USB_STRING_LEN(11), .Type = DTYPE_String}, .Header = {.Size = USB_STRING_LEN(11), .Type = DTYPE_String},
.UnicodeString = L"Dean Camera" .UnicodeString = L"Dean Camera"
}; };
/** Product descriptor string. This is a Unicode string containing the product's details in human readable form, /** Product descriptor string. This is a Unicode string containing the product's details in human readable form,
* and is read out upon request by the host when the appropriate string ID is requested, listed in the Device * and is read out upon request by the host when the appropriate string ID is requested, listed in the Device
* Descriptor. * Descriptor.
*/ */
USB_Descriptor_String_t PROGMEM ProductString = USB_Descriptor_String_t PROGMEM ProductString =
{ {
.Header = {.Size = USB_STRING_LEN(14), .Type = DTYPE_String}, .Header = {.Size = USB_STRING_LEN(14), .Type = DTYPE_String},
.UnicodeString = L"LUFA MIDI Demo" .UnicodeString = L"LUFA MIDI Demo"
}; };
/** This function is called by the library when in device mode, and must be overridden (see library "USB Descriptors" /** This function is called by the library when in device mode, and must be overridden (see library "USB Descriptors"
* documentation) by the application code so that the address and size of a requested descriptor can be given * documentation) by the application code so that the address and size of a requested descriptor can be given
* to the USB library. When the device receives a Get Descriptor request on the control endpoint, this function * to the USB library. When the device receives a Get Descriptor request on the control endpoint, this function
* is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the * is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the
* USB host. * USB host.
*/ */
uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, void** const DescriptorAddress) uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, void** const DescriptorAddress)
{ {
const uint8_t DescriptorType = (wValue >> 8); const uint8_t DescriptorType = (wValue >> 8);
const uint8_t DescriptorNumber = (wValue & 0xFF); const uint8_t DescriptorNumber = (wValue & 0xFF);
void* Address = NULL; void* Address = NULL;
uint16_t Size = NO_DESCRIPTOR; uint16_t Size = NO_DESCRIPTOR;
switch (DescriptorType) switch (DescriptorType)
{ {
case DTYPE_Device: case DTYPE_Device:
Address = (void*)&DeviceDescriptor; Address = (void*)&DeviceDescriptor;
Size = sizeof(USB_Descriptor_Device_t); Size = sizeof(USB_Descriptor_Device_t);
break; break;
case DTYPE_Configuration: case DTYPE_Configuration:
Address = (void*)&ConfigurationDescriptor; Address = (void*)&ConfigurationDescriptor;
Size = sizeof(USB_Descriptor_Configuration_t); Size = sizeof(USB_Descriptor_Configuration_t);
break; break;
case DTYPE_String: case DTYPE_String:
switch (DescriptorNumber) switch (DescriptorNumber)
{ {
case 0x00: case 0x00:
Address = (void*)&LanguageString; Address = (void*)&LanguageString;
Size = pgm_read_byte(&LanguageString.Header.Size); Size = pgm_read_byte(&LanguageString.Header.Size);
break; break;
case 0x01: case 0x01:
Address = (void*)&ManufacturerString; Address = (void*)&ManufacturerString;
Size = pgm_read_byte(&ManufacturerString.Header.Size); Size = pgm_read_byte(&ManufacturerString.Header.Size);
break; break;
case 0x02: case 0x02:
Address = (void*)&ProductString; Address = (void*)&ProductString;
Size = pgm_read_byte(&ProductString.Header.Size); Size = pgm_read_byte(&ProductString.Header.Size);
break; break;
} }
break; break;
} }
*DescriptorAddress = Address; *DescriptorAddress = Address;
return Size; return Size;
} }

View file

@ -1,81 +1,81 @@
/* /*
LUFA Library LUFA Library
Copyright (C) Dean Camera, 2010. Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com www.fourwalledcubicle.com
*/ */
/* /*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com) Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the advertising or publicity pertaining to distribution of the
software without specific, written prior permission. software without specific, written prior permission.
The author disclaim all warranties with regard to this The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action, in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of arising out of or in connection with the use or performance of
this software. this software.
*/ */
/** \file /** \file
* *
* Header file for Descriptors.c. * Header file for Descriptors.c.
*/ */
#ifndef _DESCRIPTORS_H_ #ifndef _DESCRIPTORS_H_
#define _DESCRIPTORS_H_ #define _DESCRIPTORS_H_
/* Includes: */ /* Includes: */
#include <LUFA/Drivers/USB/USB.h> #include <LUFA/Drivers/USB/USB.h>
#include <LUFA/Drivers/USB/Class/MIDI.h> #include <LUFA/Drivers/USB/Class/MIDI.h>
#include <avr/pgmspace.h> #include <avr/pgmspace.h>
/* Macros: */ /* Macros: */
/** Endpoint number of the MIDI streaming data IN endpoint, for device-to-host data transfers. */ /** Endpoint number of the MIDI streaming data IN endpoint, for device-to-host data transfers. */
#define MIDI_STREAM_IN_EPNUM 2 #define MIDI_STREAM_IN_EPNUM 2
/** Endpoint number of the MIDI streaming data OUT endpoint, for host-to-device data transfers. */ /** Endpoint number of the MIDI streaming data OUT endpoint, for host-to-device data transfers. */
#define MIDI_STREAM_OUT_EPNUM 1 #define MIDI_STREAM_OUT_EPNUM 1
/** Endpoint size in bytes of the Audio isochronous streaming data IN and OUT endpoints. */ /** Endpoint size in bytes of the Audio isochronous streaming data IN and OUT endpoints. */
#define MIDI_STREAM_EPSIZE 64 #define MIDI_STREAM_EPSIZE 64
/* Type Defines: */ /* Type Defines: */
/** Type define for the device configuration descriptor structure. This must be defined in the /** Type define for the device configuration descriptor structure. This must be defined in the
* application code, as the configuration descriptor contains several sub-descriptors which * application code, as the configuration descriptor contains several sub-descriptors which
* vary between devices, and which describe the device's usage to the host. * vary between devices, and which describe the device's usage to the host.
*/ */
typedef struct typedef struct
{ {
USB_Descriptor_Configuration_Header_t Config; USB_Descriptor_Configuration_Header_t Config;
USB_Descriptor_Interface_t Audio_ControlInterface; USB_Descriptor_Interface_t Audio_ControlInterface;
USB_Audio_Interface_AC_t Audio_ControlInterface_SPC; USB_Audio_Interface_AC_t Audio_ControlInterface_SPC;
USB_Descriptor_Interface_t Audio_StreamInterface; USB_Descriptor_Interface_t Audio_StreamInterface;
USB_MIDI_AudioInterface_AS_t Audio_StreamInterface_SPC; USB_MIDI_AudioInterface_AS_t Audio_StreamInterface_SPC;
USB_MIDI_In_Jack_t MIDI_In_Jack_Emb; USB_MIDI_In_Jack_t MIDI_In_Jack_Emb;
USB_MIDI_In_Jack_t MIDI_In_Jack_Ext; USB_MIDI_In_Jack_t MIDI_In_Jack_Ext;
USB_MIDI_Out_Jack_t MIDI_Out_Jack_Emb; USB_MIDI_Out_Jack_t MIDI_Out_Jack_Emb;
USB_MIDI_Out_Jack_t MIDI_Out_Jack_Ext; USB_MIDI_Out_Jack_t MIDI_Out_Jack_Ext;
USB_Audio_StreamEndpoint_Std_t MIDI_In_Jack_Endpoint; USB_Audio_StreamEndpoint_Std_t MIDI_In_Jack_Endpoint;
USB_MIDI_Jack_Endpoint_t MIDI_In_Jack_Endpoint_SPC; USB_MIDI_Jack_Endpoint_t MIDI_In_Jack_Endpoint_SPC;
USB_Audio_StreamEndpoint_Std_t MIDI_Out_Jack_Endpoint; USB_Audio_StreamEndpoint_Std_t MIDI_Out_Jack_Endpoint;
USB_MIDI_Jack_Endpoint_t MIDI_Out_Jack_Endpoint_SPC; USB_MIDI_Jack_Endpoint_t MIDI_Out_Jack_Endpoint_SPC;
} USB_Descriptor_Configuration_t; } USB_Descriptor_Configuration_t;
/* Function Prototypes: */ /* Function Prototypes: */
uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, void** const DescriptorAddress) uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, void** const DescriptorAddress)
ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3); ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3);
#endif #endif

File diff suppressed because it is too large Load diff

View file

@ -1,193 +1,193 @@
/* /*
LUFA Library LUFA Library
Copyright (C) Dean Camera, 2010. Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com www.fourwalledcubicle.com
*/ */
/* /*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com) Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the advertising or publicity pertaining to distribution of the
software without specific, written prior permission. software without specific, written prior permission.
The author disclaim all warranties with regard to this The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action, in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of arising out of or in connection with the use or performance of
this software. this software.
*/ */
/** \file /** \file
* *
* Main source file for the MIDI demo. This file contains the main tasks of * Main source file for the MIDI demo. This file contains the main tasks of
* the demo and is responsible for the initial application hardware configuration. * the demo and is responsible for the initial application hardware configuration.
*/ */
#include "MIDI.h" #include "MIDI.h"
/** LUFA MIDI Class driver interface configuration and state information. This structure is /** LUFA MIDI Class driver interface configuration and state information. This structure is
* passed to all MIDI Class driver functions, so that multiple instances of the same class * passed to all MIDI Class driver functions, so that multiple instances of the same class
* within a device can be differentiated from one another. * within a device can be differentiated from one another.
*/ */
USB_ClassInfo_MIDI_Device_t Keyboard_MIDI_Interface = USB_ClassInfo_MIDI_Device_t Keyboard_MIDI_Interface =
{ {
.Config = .Config =
{ {
.StreamingInterfaceNumber = 1, .StreamingInterfaceNumber = 1,
.DataINEndpointNumber = MIDI_STREAM_IN_EPNUM, .DataINEndpointNumber = MIDI_STREAM_IN_EPNUM,
.DataINEndpointSize = MIDI_STREAM_EPSIZE, .DataINEndpointSize = MIDI_STREAM_EPSIZE,
.DataINEndpointDoubleBank = false, .DataINEndpointDoubleBank = false,
.DataOUTEndpointNumber = MIDI_STREAM_OUT_EPNUM, .DataOUTEndpointNumber = MIDI_STREAM_OUT_EPNUM,
.DataOUTEndpointSize = MIDI_STREAM_EPSIZE, .DataOUTEndpointSize = MIDI_STREAM_EPSIZE,
.DataOUTEndpointDoubleBank = false, .DataOUTEndpointDoubleBank = false,
}, },
}; };
/** Main program entry point. This routine contains the overall program flow, including initial /** Main program entry point. This routine contains the overall program flow, including initial
* setup of all components and the main program loop. * setup of all components and the main program loop.
*/ */
int main(void) int main(void)
{ {
SetupHardware(); SetupHardware();
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY); LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
sei(); sei();
for (;;) for (;;)
{ {
CheckJoystickMovement(); CheckJoystickMovement();
MIDI_EventPacket_t ReceivedMIDIEvent; MIDI_EventPacket_t ReceivedMIDIEvent;
if (MIDI_Device_ReceiveEventPacket(&Keyboard_MIDI_Interface, &ReceivedMIDIEvent)) if (MIDI_Device_ReceiveEventPacket(&Keyboard_MIDI_Interface, &ReceivedMIDIEvent))
{ {
if ((ReceivedMIDIEvent.Command == (MIDI_COMMAND_NOTE_ON >> 4)) && (ReceivedMIDIEvent.Data3 > 0)) if ((ReceivedMIDIEvent.Command == (MIDI_COMMAND_NOTE_ON >> 4)) && (ReceivedMIDIEvent.Data3 > 0))
LEDs_SetAllLEDs(ReceivedMIDIEvent.Data2 > 64 ? LEDS_LED1 : LEDS_LED2); LEDs_SetAllLEDs(ReceivedMIDIEvent.Data2 > 64 ? LEDS_LED1 : LEDS_LED2);
else else
LEDs_SetAllLEDs(LEDS_NO_LEDS); LEDs_SetAllLEDs(LEDS_NO_LEDS);
} }
MIDI_Device_USBTask(&Keyboard_MIDI_Interface); MIDI_Device_USBTask(&Keyboard_MIDI_Interface);
USB_USBTask(); USB_USBTask();
} }
} }
/** Configures the board hardware and chip peripherals for the demo's functionality. */ /** Configures the board hardware and chip peripherals for the demo's functionality. */
void SetupHardware(void) void SetupHardware(void)
{ {
/* Disable watchdog if enabled by bootloader/fuses */ /* Disable watchdog if enabled by bootloader/fuses */
MCUSR &= ~(1 << WDRF); MCUSR &= ~(1 << WDRF);
wdt_disable(); wdt_disable();
/* Disable clock division */ /* Disable clock division */
clock_prescale_set(clock_div_1); clock_prescale_set(clock_div_1);
/* Hardware Initialization */ /* Hardware Initialization */
Joystick_Init(); Joystick_Init();
LEDs_Init(); LEDs_Init();
Buttons_Init(); Buttons_Init();
USB_Init(); USB_Init();
} }
/** Checks for changes in the position of the board joystick, sending MIDI events to the host upon each change. */ /** Checks for changes in the position of the board joystick, sending MIDI events to the host upon each change. */
void CheckJoystickMovement(void) void CheckJoystickMovement(void)
{ {
static uint8_t PrevJoystickStatus; static uint8_t PrevJoystickStatus;
uint8_t MIDICommand = 0; uint8_t MIDICommand = 0;
uint8_t MIDIPitch; uint8_t MIDIPitch;
/* Get current joystick mask, XOR with previous to detect joystick changes */ /* Get current joystick mask, XOR with previous to detect joystick changes */
uint8_t JoystickStatus = Joystick_GetStatus(); uint8_t JoystickStatus = Joystick_GetStatus();
uint8_t JoystickChanges = (JoystickStatus ^ PrevJoystickStatus); uint8_t JoystickChanges = (JoystickStatus ^ PrevJoystickStatus);
/* Get board button status - if pressed use channel 10 (percussion), otherwise use channel 1 */ /* Get board button status - if pressed use channel 10 (percussion), otherwise use channel 1 */
uint8_t Channel = ((Buttons_GetStatus() & BUTTONS_BUTTON1) ? MIDI_CHANNEL(10) : MIDI_CHANNEL(1)); uint8_t Channel = ((Buttons_GetStatus() & BUTTONS_BUTTON1) ? MIDI_CHANNEL(10) : MIDI_CHANNEL(1));
if (JoystickChanges & JOY_LEFT) if (JoystickChanges & JOY_LEFT)
{ {
MIDICommand = ((JoystickStatus & JOY_LEFT)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF); MIDICommand = ((JoystickStatus & JOY_LEFT)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF);
MIDIPitch = 0x3C; MIDIPitch = 0x3C;
} }
if (JoystickChanges & JOY_UP) if (JoystickChanges & JOY_UP)
{ {
MIDICommand = ((JoystickStatus & JOY_UP)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF); MIDICommand = ((JoystickStatus & JOY_UP)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF);
MIDIPitch = 0x3D; MIDIPitch = 0x3D;
} }
if (JoystickChanges & JOY_RIGHT) if (JoystickChanges & JOY_RIGHT)
{ {
MIDICommand = ((JoystickStatus & JOY_RIGHT)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF); MIDICommand = ((JoystickStatus & JOY_RIGHT)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF);
MIDIPitch = 0x3E; MIDIPitch = 0x3E;
} }
if (JoystickChanges & JOY_DOWN) if (JoystickChanges & JOY_DOWN)
{ {
MIDICommand = ((JoystickStatus & JOY_DOWN)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF); MIDICommand = ((JoystickStatus & JOY_DOWN)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF);
MIDIPitch = 0x3F; MIDIPitch = 0x3F;
} }
if (JoystickChanges & JOY_PRESS) if (JoystickChanges & JOY_PRESS)
{ {
MIDICommand = ((JoystickStatus & JOY_PRESS)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF); MIDICommand = ((JoystickStatus & JOY_PRESS)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF);
MIDIPitch = 0x3B; MIDIPitch = 0x3B;
} }
if (MIDICommand) if (MIDICommand)
{ {
MIDI_EventPacket_t MIDIEvent = (MIDI_EventPacket_t) MIDI_EventPacket_t MIDIEvent = (MIDI_EventPacket_t)
{ {
.CableNumber = 0, .CableNumber = 0,
.Command = (MIDICommand >> 4), .Command = (MIDICommand >> 4),
.Data1 = MIDICommand | Channel, .Data1 = MIDICommand | Channel,
.Data2 = MIDIPitch, .Data2 = MIDIPitch,
.Data3 = MIDI_STANDARD_VELOCITY, .Data3 = MIDI_STANDARD_VELOCITY,
}; };
MIDI_Device_SendEventPacket(&Keyboard_MIDI_Interface, &MIDIEvent); MIDI_Device_SendEventPacket(&Keyboard_MIDI_Interface, &MIDIEvent);
MIDI_Device_Flush(&Keyboard_MIDI_Interface); MIDI_Device_Flush(&Keyboard_MIDI_Interface);
} }
PrevJoystickStatus = JoystickStatus; PrevJoystickStatus = JoystickStatus;
} }
/** Event handler for the library USB Connection event. */ /** Event handler for the library USB Connection event. */
void EVENT_USB_Device_Connect(void) void EVENT_USB_Device_Connect(void)
{ {
LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING); LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
} }
/** Event handler for the library USB Disconnection event. */ /** Event handler for the library USB Disconnection event. */
void EVENT_USB_Device_Disconnect(void) void EVENT_USB_Device_Disconnect(void)
{ {
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY); LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
} }
/** Event handler for the library USB Configuration Changed event. */ /** Event handler for the library USB Configuration Changed event. */
void EVENT_USB_Device_ConfigurationChanged(void) void EVENT_USB_Device_ConfigurationChanged(void)
{ {
LEDs_SetAllLEDs(LEDMASK_USB_READY); LEDs_SetAllLEDs(LEDMASK_USB_READY);
if (!(MIDI_Device_ConfigureEndpoints(&Keyboard_MIDI_Interface))) if (!(MIDI_Device_ConfigureEndpoints(&Keyboard_MIDI_Interface)))
LEDs_SetAllLEDs(LEDMASK_USB_ERROR); LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
} }
/** Event handler for the library USB Unhandled Control Request event. */ /** Event handler for the library USB Unhandled Control Request event. */
void EVENT_USB_Device_UnhandledControlRequest(void) void EVENT_USB_Device_UnhandledControlRequest(void)
{ {
MIDI_Device_ProcessControlRequest(&Keyboard_MIDI_Interface); MIDI_Device_ProcessControlRequest(&Keyboard_MIDI_Interface);
} }

View file

@ -1,79 +1,79 @@
/* /*
LUFA Library LUFA Library
Copyright (C) Dean Camera, 2010. Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com www.fourwalledcubicle.com
*/ */
/* /*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com) Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the advertising or publicity pertaining to distribution of the
software without specific, written prior permission. software without specific, written prior permission.
The author disclaim all warranties with regard to this The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action, in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of arising out of or in connection with the use or performance of
this software. this software.
*/ */
/** \file /** \file
* *
* Header file for AudioOutput.c. * Header file for AudioOutput.c.
*/ */
#ifndef _AUDIO_OUTPUT_H_ #ifndef _AUDIO_OUTPUT_H_
#define _AUDIO_OUTPUT_H_ #define _AUDIO_OUTPUT_H_
/* Includes: */ /* Includes: */
#include <avr/io.h> #include <avr/io.h>
#include <avr/wdt.h> #include <avr/wdt.h>
#include <avr/power.h> #include <avr/power.h>
#include <avr/interrupt.h> #include <avr/interrupt.h>
#include <stdbool.h> #include <stdbool.h>
#include <string.h> #include <string.h>
#include "Descriptors.h" #include "Descriptors.h"
#include <LUFA/Version.h> #include <LUFA/Version.h>
#include <LUFA/Drivers/Board/LEDs.h> #include <LUFA/Drivers/Board/LEDs.h>
#include <LUFA/Drivers/Board/Joystick.h> #include <LUFA/Drivers/Board/Joystick.h>
#include <LUFA/Drivers/Board/Buttons.h> #include <LUFA/Drivers/Board/Buttons.h>
#include <LUFA/Drivers/Peripheral/ADC.h> #include <LUFA/Drivers/Peripheral/ADC.h>
#include <LUFA/Drivers/USB/USB.h> #include <LUFA/Drivers/USB/USB.h>
#include <LUFA/Drivers/USB/Class/MIDI.h> #include <LUFA/Drivers/USB/Class/MIDI.h>
/* Macros: */ /* Macros: */
/** LED mask for the library LED driver, to indicate that the USB interface is not ready. */ /** LED mask for the library LED driver, to indicate that the USB interface is not ready. */
#define LEDMASK_USB_NOTREADY LEDS_LED1 #define LEDMASK_USB_NOTREADY LEDS_LED1
/** LED mask for the library LED driver, to indicate that the USB interface is enumerating. */ /** LED mask for the library LED driver, to indicate that the USB interface is enumerating. */
#define LEDMASK_USB_ENUMERATING (LEDS_LED2 | LEDS_LED3) #define LEDMASK_USB_ENUMERATING (LEDS_LED2 | LEDS_LED3)
/** LED mask for the library LED driver, to indicate that the USB interface is ready. */ /** LED mask for the library LED driver, to indicate that the USB interface is ready. */
#define LEDMASK_USB_READY (LEDS_LED2 | LEDS_LED4) #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. */ /** 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) #define LEDMASK_USB_ERROR (LEDS_LED1 | LEDS_LED3)
/* Function Prototypes: */ /* Function Prototypes: */
void SetupHardware(void); void SetupHardware(void);
void CheckJoystickMovement(void); void CheckJoystickMovement(void);
void EVENT_USB_Device_Connect(void); void EVENT_USB_Device_Connect(void);
void EVENT_USB_Device_Disconnect(void); void EVENT_USB_Device_Disconnect(void);
void EVENT_USB_Device_ConfigurationChanged(void); void EVENT_USB_Device_ConfigurationChanged(void);
void EVENT_USB_Device_UnhandledControlRequest(void); void EVENT_USB_Device_UnhandledControlRequest(void);
#endif #endif

View file

@ -1,74 +1,74 @@
/** \file /** \file
* *
* This file contains special DoxyGen information for the generation of the main page and other special * 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. * documentation pages. It is not a project source file.
*/ */
/** \mainpage MIDI Input Device Demo /** \mainpage MIDI Input Device Demo
* *
* \section SSec_Compat Demo Compatibility: * \section SSec_Compat Demo Compatibility:
* *
* The following list indicates what microcontrollers are compatible with this demo. * The following list indicates what microcontrollers are compatible with this demo.
* *
* - Series 7 USB AVRs * - Series 7 USB AVRs
* - Series 6 USB AVRs * - Series 6 USB AVRs
* - Series 4 USB AVRs * - Series 4 USB AVRs
* - Series 2 USB AVRs * - Series 2 USB AVRs
* *
* \section SSec_Info USB Information: * \section SSec_Info USB Information:
* *
* The following table gives a rundown of the USB utilization of this demo. * The following table gives a rundown of the USB utilization of this demo.
* *
* <table> * <table>
* <tr> * <tr>
* <td><b>USB Mode:</b></td> * <td><b>USB Mode:</b></td>
* <td>Device</td> * <td>Device</td>
* </tr> * </tr>
* <tr> * <tr>
* <td><b>USB Class:</b></td> * <td><b>USB Class:</b></td>
* <td>Audio Class</td> * <td>Audio Class</td>
* </tr> * </tr>
* <tr> * <tr>
* <td><b>USB Subclass:</b></td> * <td><b>USB Subclass:</b></td>
* <td>Standard Audio Device</td> * <td>Standard Audio Device</td>
* </tr> * </tr>
* <tr> * <tr>
* <td><b>Relevant Standards:</b></td> * <td><b>Relevant Standards:</b></td>
* <td>USBIF Audio Class Specification \n * <td>USBIF Audio Class Specification \n
* USB-MIDI Audio Class Extension Specification \n * USB-MIDI Audio Class Extension Specification \n
* General MIDI Specification</td> * General MIDI Specification</td>
* </tr> * </tr>
* <tr> * <tr>
* <td><b>Usable Speeds:</b></td> * <td><b>Usable Speeds:</b></td>
* <td>Full Speed Mode</td> * <td>Full Speed Mode</td>
* </tr> * </tr>
* </table> * </table>
* *
* \section SSec_Description Project Description: * \section SSec_Description Project Description:
* *
* MIDI demonstration application. This gives a simple reference * MIDI demonstration application. This gives a simple reference
* application for implementing the USB-MIDI class in USB devices. * application for implementing the USB-MIDI class in USB devices.
* It is built upon the USB Audio class. * It is built upon the USB Audio class.
* *
* Joystick movements are translated into note on/off messages and * Joystick movements are translated into note on/off messages and
* are sent to the host PC as MIDI streams which can be read by any * are sent to the host PC as MIDI streams which can be read by any
* MIDI program supporting MIDI IN devices. * MIDI program supporting MIDI IN devices.
* *
* If the HWB is not pressed, channel 1 (default piano) is used. If * If the HWB is not pressed, channel 1 (default piano) is used. If
* the HWB is set, then channel 10 (default percussion) is selected. * the HWB is set, then channel 10 (default percussion) is selected.
* *
* This device implements MIDI-THRU mode, with the IN MIDI data being * This device implements MIDI-THRU mode, with the IN MIDI data being
* generated by the device itself. OUT MIDI data is discarded. * generated by the device itself. OUT MIDI data is discarded.
* *
* \section SSec_Options Project Options * \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. * The following defines can be found in this demo, which can control the demo behaviour when defined, or changed in value.
* *
* <table> * <table>
* <tr> * <tr>
* <td> * <td>
* None * None
* </td> * </td>
* </tr> * </tr>
* </table> * </table>
*/ */

File diff suppressed because it is too large Load diff

View file

@ -1,217 +1,217 @@
/* /*
LUFA Library LUFA Library
Copyright (C) Dean Camera, 2010. Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com www.fourwalledcubicle.com
*/ */
/* /*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com) Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the advertising or publicity pertaining to distribution of the
software without specific, written prior permission. software without specific, written prior permission.
The author disclaim all warranties with regard to this The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action, in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of arising out of or in connection with the use or performance of
this software. this software.
*/ */
/** \file /** \file
* *
* USB Device Descriptors, for library use when in USB device mode. Descriptors are special * USB Device Descriptors, for library use when in USB device mode. Descriptors are special
* computer-readable structures which the host requests upon device enumeration, to determine * computer-readable structures which the host requests upon device enumeration, to determine
* the device's capabilities and functions. * the device's capabilities and functions.
*/ */
#include "Descriptors.h" #include "Descriptors.h"
/* On some devices, there is a factory set internal serial number which can be automatically sent to the host as /* On some devices, there is a factory set internal serial number which can be automatically sent to the host as
* the device's serial number when the Device Descriptor's .SerialNumStrIndex entry is set to USE_INTERNAL_SERIAL. * the device's serial number when the Device Descriptor's .SerialNumStrIndex entry is set to USE_INTERNAL_SERIAL.
* This allows the host to track a device across insertions on different ports, allowing them to retain allocated * This allows the host to track a device across insertions on different ports, allowing them to retain allocated
* resources like COM port numbers and drivers. On demos using this feature, give a warning on unsupported devices * resources like COM port numbers and drivers. On demos using this feature, give a warning on unsupported devices
* so that the user can supply their own serial number descriptor instead or remove the USE_INTERNAL_SERIAL value * so that the user can supply their own serial number descriptor instead or remove the USE_INTERNAL_SERIAL value
* from the Device Descriptor (forcing the host to generate a serial number for each device from the VID, PID and * from the Device Descriptor (forcing the host to generate a serial number for each device from the VID, PID and
* port location). * port location).
*/ */
#if (USE_INTERNAL_SERIAL == NO_DESCRIPTOR) #if (USE_INTERNAL_SERIAL == NO_DESCRIPTOR)
#warning USE_INTERNAL_SERIAL is not available on this AVR - please manually construct a device serial descriptor. #warning USE_INTERNAL_SERIAL is not available on this AVR - please manually construct a device serial descriptor.
#endif #endif
/** Device descriptor structure. This descriptor, located in FLASH memory, describes the overall /** Device descriptor structure. This descriptor, located in FLASH memory, describes the overall
* device characteristics, including the supported USB version, control endpoint size and the * device characteristics, including the supported USB version, control endpoint size and the
* number of device configurations. The descriptor is read out by the USB host when the enumeration * number of device configurations. The descriptor is read out by the USB host when the enumeration
* process begins. * process begins.
*/ */
USB_Descriptor_Device_t PROGMEM DeviceDescriptor = USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
{ {
.Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device}, .Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device},
.USBSpecification = VERSION_BCD(01.10), .USBSpecification = VERSION_BCD(01.10),
.Class = 0x00, .Class = 0x00,
.SubClass = 0x00, .SubClass = 0x00,
.Protocol = 0x00, .Protocol = 0x00,
.Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE, .Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE,
.VendorID = 0x03EB, .VendorID = 0x03EB,
.ProductID = 0x2045, .ProductID = 0x2045,
.ReleaseNumber = 0x0000, .ReleaseNumber = 0x0000,
.ManufacturerStrIndex = 0x01, .ManufacturerStrIndex = 0x01,
.ProductStrIndex = 0x02, .ProductStrIndex = 0x02,
.SerialNumStrIndex = USE_INTERNAL_SERIAL, .SerialNumStrIndex = USE_INTERNAL_SERIAL,
.NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS .NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS
}; };
/** Configuration descriptor structure. This descriptor, located in FLASH memory, describes the usage /** Configuration descriptor structure. This descriptor, located in FLASH memory, describes the usage
* of the device in one of its supported configurations, including information about any device interfaces * of the device in one of its supported configurations, including information about any device interfaces
* and endpoints. The descriptor is read out by the USB host during the enumeration process when selecting * and endpoints. The descriptor is read out by the USB host during the enumeration process when selecting
* a configuration so that the host may correctly communicate with the USB device. * a configuration so that the host may correctly communicate with the USB device.
*/ */
USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor = USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
{ {
.Config = .Config =
{ {
.Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration}, .Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration},
.TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t), .TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t),
.TotalInterfaces = 1, .TotalInterfaces = 1,
.ConfigurationNumber = 1, .ConfigurationNumber = 1,
.ConfigurationStrIndex = NO_DESCRIPTOR, .ConfigurationStrIndex = NO_DESCRIPTOR,
.ConfigAttributes = USB_CONFIG_ATTR_BUSPOWERED, .ConfigAttributes = USB_CONFIG_ATTR_BUSPOWERED,
.MaxPowerConsumption = USB_CONFIG_POWER_MA(100) .MaxPowerConsumption = USB_CONFIG_POWER_MA(100)
}, },
.MS_Interface = .MS_Interface =
{ {
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface}, .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
.InterfaceNumber = 0, .InterfaceNumber = 0,
.AlternateSetting = 0, .AlternateSetting = 0,
.TotalEndpoints = 2, .TotalEndpoints = 2,
.Class = 0x08, .Class = 0x08,
.SubClass = 0x06, .SubClass = 0x06,
.Protocol = 0x50, .Protocol = 0x50,
.InterfaceStrIndex = NO_DESCRIPTOR .InterfaceStrIndex = NO_DESCRIPTOR
}, },
.MS_DataInEndpoint = .MS_DataInEndpoint =
{ {
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint}, .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
.EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_IN | MASS_STORAGE_IN_EPNUM), .EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_IN | MASS_STORAGE_IN_EPNUM),
.Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), .Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
.EndpointSize = MASS_STORAGE_IO_EPSIZE, .EndpointSize = MASS_STORAGE_IO_EPSIZE,
.PollingIntervalMS = 0x00 .PollingIntervalMS = 0x00
}, },
.MS_DataOutEndpoint = .MS_DataOutEndpoint =
{ {
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint}, .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
.EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_OUT | MASS_STORAGE_OUT_EPNUM), .EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_OUT | MASS_STORAGE_OUT_EPNUM),
.Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), .Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
.EndpointSize = MASS_STORAGE_IO_EPSIZE, .EndpointSize = MASS_STORAGE_IO_EPSIZE,
.PollingIntervalMS = 0x00 .PollingIntervalMS = 0x00
} }
}; };
/** Language descriptor structure. This descriptor, located in FLASH memory, is returned when the host requests /** Language descriptor structure. This descriptor, located in FLASH memory, is returned when the host requests
* the string descriptor with index 0 (the first index). It is actually an array of 16-bit integers, which indicate * the string descriptor with index 0 (the first index). It is actually an array of 16-bit integers, which indicate
* via the language ID table available at USB.org what languages the device supports for its string descriptors. * via the language ID table available at USB.org what languages the device supports for its string descriptors.
*/ */
USB_Descriptor_String_t PROGMEM LanguageString = USB_Descriptor_String_t PROGMEM LanguageString =
{ {
.Header = {.Size = USB_STRING_LEN(1), .Type = DTYPE_String}, .Header = {.Size = USB_STRING_LEN(1), .Type = DTYPE_String},
.UnicodeString = {LANGUAGE_ID_ENG} .UnicodeString = {LANGUAGE_ID_ENG}
}; };
/** Manufacturer descriptor string. This is a Unicode string containing the manufacturer's details in human readable /** Manufacturer descriptor string. This is a Unicode string containing the manufacturer's details in human readable
* form, and is read out upon request by the host when the appropriate string ID is requested, listed in the Device * form, and is read out upon request by the host when the appropriate string ID is requested, listed in the Device
* Descriptor. * Descriptor.
*/ */
USB_Descriptor_String_t PROGMEM ManufacturerString = USB_Descriptor_String_t PROGMEM ManufacturerString =
{ {
.Header = {.Size = USB_STRING_LEN(11), .Type = DTYPE_String}, .Header = {.Size = USB_STRING_LEN(11), .Type = DTYPE_String},
.UnicodeString = L"Dean Camera" .UnicodeString = L"Dean Camera"
}; };
/** Product descriptor string. This is a Unicode string containing the product's details in human readable form, /** Product descriptor string. This is a Unicode string containing the product's details in human readable form,
* and is read out upon request by the host when the appropriate string ID is requested, listed in the Device * and is read out upon request by the host when the appropriate string ID is requested, listed in the Device
* Descriptor. * Descriptor.
*/ */
USB_Descriptor_String_t PROGMEM ProductString = USB_Descriptor_String_t PROGMEM ProductString =
{ {
.Header = {.Size = USB_STRING_LEN(22), .Type = DTYPE_String}, .Header = {.Size = USB_STRING_LEN(22), .Type = DTYPE_String},
.UnicodeString = L"LUFA Mass Storage Demo" .UnicodeString = L"LUFA Mass Storage Demo"
}; };
/** This function is called by the library when in device mode, and must be overridden (see library "USB Descriptors" /** This function is called by the library when in device mode, and must be overridden (see library "USB Descriptors"
* documentation) by the application code so that the address and size of a requested descriptor can be given * documentation) by the application code so that the address and size of a requested descriptor can be given
* to the USB library. When the device receives a Get Descriptor request on the control endpoint, this function * to the USB library. When the device receives a Get Descriptor request on the control endpoint, this function
* is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the * is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the
* USB host. * USB host.
*/ */
uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, void** const DescriptorAddress) uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, void** const DescriptorAddress)
{ {
const uint8_t DescriptorType = (wValue >> 8); const uint8_t DescriptorType = (wValue >> 8);
const uint8_t DescriptorNumber = (wValue & 0xFF); const uint8_t DescriptorNumber = (wValue & 0xFF);
void* Address = NULL; void* Address = NULL;
uint16_t Size = NO_DESCRIPTOR; uint16_t Size = NO_DESCRIPTOR;
switch (DescriptorType) switch (DescriptorType)
{ {
case DTYPE_Device: case DTYPE_Device:
Address = (void*)&DeviceDescriptor; Address = (void*)&DeviceDescriptor;
Size = sizeof(USB_Descriptor_Device_t); Size = sizeof(USB_Descriptor_Device_t);
break; break;
case DTYPE_Configuration: case DTYPE_Configuration:
Address = (void*)&ConfigurationDescriptor; Address = (void*)&ConfigurationDescriptor;
Size = sizeof(USB_Descriptor_Configuration_t); Size = sizeof(USB_Descriptor_Configuration_t);
break; break;
case DTYPE_String: case DTYPE_String:
switch (DescriptorNumber) switch (DescriptorNumber)
{ {
case 0x00: case 0x00:
Address = (void*)&LanguageString; Address = (void*)&LanguageString;
Size = pgm_read_byte(&LanguageString.Header.Size); Size = pgm_read_byte(&LanguageString.Header.Size);
break; break;
case 0x01: case 0x01:
Address = (void*)&ManufacturerString; Address = (void*)&ManufacturerString;
Size = pgm_read_byte(&ManufacturerString.Header.Size); Size = pgm_read_byte(&ManufacturerString.Header.Size);
break; break;
case 0x02: case 0x02:
Address = (void*)&ProductString; Address = (void*)&ProductString;
Size = pgm_read_byte(&ProductString.Header.Size); Size = pgm_read_byte(&ProductString.Header.Size);
break; break;
} }
break; break;
} }
*DescriptorAddress = Address; *DescriptorAddress = Address;
return Size; return Size;
} }

View file

@ -1,72 +1,72 @@
/* /*
LUFA Library LUFA Library
Copyright (C) Dean Camera, 2010. Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com www.fourwalledcubicle.com
*/ */
/* /*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com) Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the advertising or publicity pertaining to distribution of the
software without specific, written prior permission. software without specific, written prior permission.
The author disclaim all warranties with regard to this The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action, in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of arising out of or in connection with the use or performance of
this software. this software.
*/ */
/** \file /** \file
* *
* Header file for Descriptors.c. * Header file for Descriptors.c.
*/ */
#ifndef _DESCRIPTORS_H_ #ifndef _DESCRIPTORS_H_
#define _DESCRIPTORS_H_ #define _DESCRIPTORS_H_
/* Includes: */ /* Includes: */
#include <avr/pgmspace.h> #include <avr/pgmspace.h>
#include <LUFA/Drivers/USB/USB.h> #include <LUFA/Drivers/USB/USB.h>
#include <LUFA/Drivers/USB/Class/MassStorage.h> #include <LUFA/Drivers/USB/Class/MassStorage.h>
/* Macros: */ /* Macros: */
/** Endpoint number of the Mass Storage device-to-host data IN endpoint. */ /** Endpoint number of the Mass Storage device-to-host data IN endpoint. */
#define MASS_STORAGE_IN_EPNUM 3 #define MASS_STORAGE_IN_EPNUM 3
/** Endpoint number of the Mass Storage host-to-device data OUT endpoint. */ /** Endpoint number of the Mass Storage host-to-device data OUT endpoint. */
#define MASS_STORAGE_OUT_EPNUM 4 #define MASS_STORAGE_OUT_EPNUM 4
/** Size in bytes of the Mass Storage data endpoints. */ /** Size in bytes of the Mass Storage data endpoints. */
#define MASS_STORAGE_IO_EPSIZE 64 #define MASS_STORAGE_IO_EPSIZE 64
/* Type Defines: */ /* Type Defines: */
/** Type define for the device configuration descriptor structure. This must be defined in the /** Type define for the device configuration descriptor structure. This must be defined in the
* application code, as the configuration descriptor contains several sub-descriptors which * application code, as the configuration descriptor contains several sub-descriptors which
* vary between devices, and which describe the device's usage to the host. * vary between devices, and which describe the device's usage to the host.
*/ */
typedef struct typedef struct
{ {
USB_Descriptor_Configuration_Header_t Config; USB_Descriptor_Configuration_Header_t Config;
USB_Descriptor_Interface_t MS_Interface; USB_Descriptor_Interface_t MS_Interface;
USB_Descriptor_Endpoint_t MS_DataInEndpoint; USB_Descriptor_Endpoint_t MS_DataInEndpoint;
USB_Descriptor_Endpoint_t MS_DataOutEndpoint; USB_Descriptor_Endpoint_t MS_DataOutEndpoint;
} USB_Descriptor_Configuration_t; } USB_Descriptor_Configuration_t;
/* Function Prototypes: */ /* Function Prototypes: */
uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, void** const DescriptorAddress) uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, void** const DescriptorAddress)
ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3); ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3);
#endif #endif

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,81 +1,81 @@
/* /*
LUFA Library LUFA Library
Copyright (C) Dean Camera, 2010. Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com www.fourwalledcubicle.com
*/ */
/* /*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com) Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the advertising or publicity pertaining to distribution of the
software without specific, written prior permission. software without specific, written prior permission.
The author disclaim all warranties with regard to this The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action, in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of arising out of or in connection with the use or performance of
this software. this software.
*/ */
/** \file /** \file
* *
* Header file for DataflashManager.c. * Header file for DataflashManager.c.
*/ */
#ifndef _DATAFLASH_MANAGER_H_ #ifndef _DATAFLASH_MANAGER_H_
#define _DATAFLASH_MANAGER_H_ #define _DATAFLASH_MANAGER_H_
/* Includes: */ /* Includes: */
#include <avr/io.h> #include <avr/io.h>
#include "MassStorage.h" #include "MassStorage.h"
#include "Descriptors.h" #include "Descriptors.h"
#include <LUFA/Common/Common.h> #include <LUFA/Common/Common.h>
#include <LUFA/Drivers/USB/USB.h> #include <LUFA/Drivers/USB/USB.h>
#include <LUFA/Drivers/USB/Class/MassStorage.h> #include <LUFA/Drivers/USB/Class/MassStorage.h>
#include <LUFA/Drivers/Board/Dataflash.h> #include <LUFA/Drivers/Board/Dataflash.h>
/* Preprocessor Checks: */ /* Preprocessor Checks: */
#if (DATAFLASH_PAGE_SIZE % 16) #if (DATAFLASH_PAGE_SIZE % 16)
#error Dataflash page size must be a multiple of 16 bytes. #error Dataflash page size must be a multiple of 16 bytes.
#endif #endif
/* Defines: */ /* Defines: */
/** Total number of bytes of the storage medium, comprised of one or more dataflash ICs. */ /** Total number of bytes of the storage medium, comprised of one or more dataflash ICs. */
#define VIRTUAL_MEMORY_BYTES ((uint32_t)DATAFLASH_PAGES * DATAFLASH_PAGE_SIZE * DATAFLASH_TOTALCHIPS) #define VIRTUAL_MEMORY_BYTES ((uint32_t)DATAFLASH_PAGES * DATAFLASH_PAGE_SIZE * DATAFLASH_TOTALCHIPS)
/** Block size of the device. This is kept at 512 to remain compatible with the OS despite the underlying /** Block size of the device. This is kept at 512 to remain compatible with the OS despite the underlying
* storage media (Dataflash) using a different native block size. Do not change this value. * storage media (Dataflash) using a different native block size. Do not change this value.
*/ */
#define VIRTUAL_MEMORY_BLOCK_SIZE 512 #define VIRTUAL_MEMORY_BLOCK_SIZE 512
/** Total number of blocks of the virtual memory for reporting to the host as the device's total capacity. Do not /** Total number of blocks of the virtual memory for reporting to the host as the device's total capacity. Do not
* change this value; change VIRTUAL_MEMORY_BYTES instead to alter the media size. * change this value; change VIRTUAL_MEMORY_BYTES instead to alter the media size.
*/ */
#define VIRTUAL_MEMORY_BLOCKS (VIRTUAL_MEMORY_BYTES / VIRTUAL_MEMORY_BLOCK_SIZE) #define VIRTUAL_MEMORY_BLOCKS (VIRTUAL_MEMORY_BYTES / VIRTUAL_MEMORY_BLOCK_SIZE)
/* Function Prototypes: */ /* Function Prototypes: */
void DataflashManager_WriteBlocks(USB_ClassInfo_MS_Device_t* MSInterfaceInfo, const uint32_t BlockAddress, void DataflashManager_WriteBlocks(USB_ClassInfo_MS_Device_t* MSInterfaceInfo, const uint32_t BlockAddress,
uint16_t TotalBlocks); uint16_t TotalBlocks);
void DataflashManager_ReadBlocks(USB_ClassInfo_MS_Device_t* MSInterfaceInfo, const uint32_t BlockAddress, void DataflashManager_ReadBlocks(USB_ClassInfo_MS_Device_t* MSInterfaceInfo, const uint32_t BlockAddress,
uint16_t TotalBlocks); uint16_t TotalBlocks);
void DataflashManager_WriteBlocks_RAM(const uint32_t BlockAddress, uint16_t TotalBlocks, void DataflashManager_WriteBlocks_RAM(const uint32_t BlockAddress, uint16_t TotalBlocks,
uint8_t* BufferPtr) ATTR_NON_NULL_PTR_ARG(3); uint8_t* BufferPtr) ATTR_NON_NULL_PTR_ARG(3);
void DataflashManager_ReadBlocks_RAM(const uint32_t BlockAddress, uint16_t TotalBlocks, void DataflashManager_ReadBlocks_RAM(const uint32_t BlockAddress, uint16_t TotalBlocks,
uint8_t* BufferPtr) ATTR_NON_NULL_PTR_ARG(3); uint8_t* BufferPtr) ATTR_NON_NULL_PTR_ARG(3);
void DataflashManager_ResetDataflashProtections(void); void DataflashManager_ResetDataflashProtections(void);
bool DataflashManager_CheckDataflashOperation(void); bool DataflashManager_CheckDataflashOperation(void);
#endif #endif

View file

@ -1,286 +1,286 @@
/* /*
LUFA Library LUFA Library
Copyright (C) Dean Camera, 2010. Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com www.fourwalledcubicle.com
*/ */
/* /*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com) Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the advertising or publicity pertaining to distribution of the
software without specific, written prior permission. software without specific, written prior permission.
The author disclaim all warranties with regard to this The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action, in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of arising out of or in connection with the use or performance of
this software. this software.
*/ */
/** \file /** \file
* *
* SCSI command processing routines, for SCSI commands issued by the host. Mass Storage * SCSI command processing routines, for SCSI commands issued by the host. Mass Storage
* devices use a thin "Bulk-Only Transport" protocol for issuing commands and status information, * devices use a thin "Bulk-Only Transport" protocol for issuing commands and status information,
* which wrap around standard SCSI device commands for controlling the actual storage medium. * which wrap around standard SCSI device commands for controlling the actual storage medium.
*/ */
#define INCLUDE_FROM_SCSI_C #define INCLUDE_FROM_SCSI_C
#include "SCSI.h" #include "SCSI.h"
/** Structure to hold the SCSI response data to a SCSI INQUIRY command. This gives information about the device's /** Structure to hold the SCSI response data to a SCSI INQUIRY command. This gives information about the device's
* features and capabilities. * features and capabilities.
*/ */
SCSI_Inquiry_Response_t InquiryData = SCSI_Inquiry_Response_t InquiryData =
{ {
.DeviceType = DEVICE_TYPE_BLOCK, .DeviceType = DEVICE_TYPE_BLOCK,
.PeripheralQualifier = 0, .PeripheralQualifier = 0,
.Removable = true, .Removable = true,
.Version = 0, .Version = 0,
.ResponseDataFormat = 2, .ResponseDataFormat = 2,
.NormACA = false, .NormACA = false,
.TrmTsk = false, .TrmTsk = false,
.AERC = false, .AERC = false,
.AdditionalLength = 0x1F, .AdditionalLength = 0x1F,
.SoftReset = false, .SoftReset = false,
.CmdQue = false, .CmdQue = false,
.Linked = false, .Linked = false,
.Sync = false, .Sync = false,
.WideBus16Bit = false, .WideBus16Bit = false,
.WideBus32Bit = false, .WideBus32Bit = false,
.RelAddr = false, .RelAddr = false,
.VendorID = "LUFA", .VendorID = "LUFA",
.ProductID = "Dataflash Disk", .ProductID = "Dataflash Disk",
.RevisionID = {'0','.','0','0'}, .RevisionID = {'0','.','0','0'},
}; };
/** Structure to hold the sense data for the last issued SCSI command, which is returned to the host after a SCSI REQUEST SENSE /** Structure to hold the sense data for the last issued SCSI command, which is returned to the host after a SCSI REQUEST SENSE
* command is issued. This gives information on exactly why the last command failed to complete. * command is issued. This gives information on exactly why the last command failed to complete.
*/ */
SCSI_Request_Sense_Response_t SenseData = SCSI_Request_Sense_Response_t SenseData =
{ {
.ResponseCode = 0x70, .ResponseCode = 0x70,
.AdditionalLength = 0x0A, .AdditionalLength = 0x0A,
}; };
/** Main routine to process the SCSI command located in the Command Block Wrapper read from the host. This dispatches /** Main routine to process the SCSI command located in the Command Block Wrapper read from the host. This dispatches
* to the appropriate SCSI command handling routine if the issued command is supported by the device, else it returns * to the appropriate SCSI command handling routine if the issued command is supported by the device, else it returns
* a command failure due to a ILLEGAL REQUEST. * a command failure due to a ILLEGAL REQUEST.
* *
* \param[in] MSInterfaceInfo Pointer to the Mass Storage class interface structure that the command is associated with * \param[in] MSInterfaceInfo Pointer to the Mass Storage class interface structure that the command is associated with
*/ */
bool SCSI_DecodeSCSICommand(USB_ClassInfo_MS_Device_t* MSInterfaceInfo) bool SCSI_DecodeSCSICommand(USB_ClassInfo_MS_Device_t* MSInterfaceInfo)
{ {
/* Set initial sense data, before the requested command is processed */ /* Set initial sense data, before the requested command is processed */
SCSI_SET_SENSE(SCSI_SENSE_KEY_GOOD, SCSI_SET_SENSE(SCSI_SENSE_KEY_GOOD,
SCSI_ASENSE_NO_ADDITIONAL_INFORMATION, SCSI_ASENSE_NO_ADDITIONAL_INFORMATION,
SCSI_ASENSEQ_NO_QUALIFIER); SCSI_ASENSEQ_NO_QUALIFIER);
/* Run the appropriate SCSI command hander function based on the passed command */ /* Run the appropriate SCSI command hander function based on the passed command */
switch (MSInterfaceInfo->State.CommandBlock.SCSICommandData[0]) switch (MSInterfaceInfo->State.CommandBlock.SCSICommandData[0])
{ {
case SCSI_CMD_INQUIRY: case SCSI_CMD_INQUIRY:
SCSI_Command_Inquiry(MSInterfaceInfo); SCSI_Command_Inquiry(MSInterfaceInfo);
break; break;
case SCSI_CMD_REQUEST_SENSE: case SCSI_CMD_REQUEST_SENSE:
SCSI_Command_Request_Sense(MSInterfaceInfo); SCSI_Command_Request_Sense(MSInterfaceInfo);
break; break;
case SCSI_CMD_READ_CAPACITY_10: case SCSI_CMD_READ_CAPACITY_10:
SCSI_Command_Read_Capacity_10(MSInterfaceInfo); SCSI_Command_Read_Capacity_10(MSInterfaceInfo);
break; break;
case SCSI_CMD_SEND_DIAGNOSTIC: case SCSI_CMD_SEND_DIAGNOSTIC:
SCSI_Command_Send_Diagnostic(MSInterfaceInfo); SCSI_Command_Send_Diagnostic(MSInterfaceInfo);
break; break;
case SCSI_CMD_WRITE_10: case SCSI_CMD_WRITE_10:
SCSI_Command_ReadWrite_10(MSInterfaceInfo, DATA_WRITE); SCSI_Command_ReadWrite_10(MSInterfaceInfo, DATA_WRITE);
break; break;
case SCSI_CMD_READ_10: case SCSI_CMD_READ_10:
SCSI_Command_ReadWrite_10(MSInterfaceInfo, DATA_READ); SCSI_Command_ReadWrite_10(MSInterfaceInfo, DATA_READ);
break; break;
case SCSI_CMD_TEST_UNIT_READY: case SCSI_CMD_TEST_UNIT_READY:
case SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL: case SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL:
case SCSI_CMD_VERIFY_10: case SCSI_CMD_VERIFY_10:
/* These commands should just succeed, no handling required */ /* These commands should just succeed, no handling required */
MSInterfaceInfo->State.CommandBlock.DataTransferLength = 0; MSInterfaceInfo->State.CommandBlock.DataTransferLength = 0;
break; break;
default: default:
/* Update the SENSE key to reflect the invalid command */ /* Update the SENSE key to reflect the invalid command */
SCSI_SET_SENSE(SCSI_SENSE_KEY_ILLEGAL_REQUEST, SCSI_SET_SENSE(SCSI_SENSE_KEY_ILLEGAL_REQUEST,
SCSI_ASENSE_INVALID_COMMAND, SCSI_ASENSE_INVALID_COMMAND,
SCSI_ASENSEQ_NO_QUALIFIER); SCSI_ASENSEQ_NO_QUALIFIER);
break; break;
} }
return (SenseData.SenseKey == SCSI_SENSE_KEY_GOOD); return (SenseData.SenseKey == SCSI_SENSE_KEY_GOOD);
} }
/** Command processing for an issued SCSI INQUIRY command. This command returns information about the device's features /** Command processing for an issued SCSI INQUIRY command. This command returns information about the device's features
* and capabilities to the host. * and capabilities to the host.
* *
* \param[in] MSInterfaceInfo Pointer to the Mass Storage class interface structure that the command is associated with * \param[in] MSInterfaceInfo Pointer to the Mass Storage class interface structure that the command is associated with
*/ */
static void SCSI_Command_Inquiry(USB_ClassInfo_MS_Device_t* MSInterfaceInfo) static void SCSI_Command_Inquiry(USB_ClassInfo_MS_Device_t* MSInterfaceInfo)
{ {
uint16_t AllocationLength = (((uint16_t)MSInterfaceInfo->State.CommandBlock.SCSICommandData[3] << 8) | uint16_t AllocationLength = (((uint16_t)MSInterfaceInfo->State.CommandBlock.SCSICommandData[3] << 8) |
MSInterfaceInfo->State.CommandBlock.SCSICommandData[4]); MSInterfaceInfo->State.CommandBlock.SCSICommandData[4]);
uint16_t BytesTransferred = (AllocationLength < sizeof(InquiryData))? AllocationLength : uint16_t BytesTransferred = (AllocationLength < sizeof(InquiryData))? AllocationLength :
sizeof(InquiryData); sizeof(InquiryData);
/* Only the standard INQUIRY data is supported, check if any optional INQUIRY bits set */ /* Only the standard INQUIRY data is supported, check if any optional INQUIRY bits set */
if ((MSInterfaceInfo->State.CommandBlock.SCSICommandData[1] & ((1 << 0) | (1 << 1))) || if ((MSInterfaceInfo->State.CommandBlock.SCSICommandData[1] & ((1 << 0) | (1 << 1))) ||
MSInterfaceInfo->State.CommandBlock.SCSICommandData[2]) MSInterfaceInfo->State.CommandBlock.SCSICommandData[2])
{ {
/* Optional but unsupported bits set - update the SENSE key and fail the request */ /* Optional but unsupported bits set - update the SENSE key and fail the request */
SCSI_SET_SENSE(SCSI_SENSE_KEY_ILLEGAL_REQUEST, SCSI_SET_SENSE(SCSI_SENSE_KEY_ILLEGAL_REQUEST,
SCSI_ASENSE_INVALID_FIELD_IN_CDB, SCSI_ASENSE_INVALID_FIELD_IN_CDB,
SCSI_ASENSEQ_NO_QUALIFIER); SCSI_ASENSEQ_NO_QUALIFIER);
return; return;
} }
Endpoint_Write_Stream_LE(&InquiryData, BytesTransferred, NO_STREAM_CALLBACK); Endpoint_Write_Stream_LE(&InquiryData, BytesTransferred, NO_STREAM_CALLBACK);
uint8_t PadBytes[AllocationLength - BytesTransferred]; uint8_t PadBytes[AllocationLength - BytesTransferred];
/* Pad out remaining bytes with 0x00 */ /* Pad out remaining bytes with 0x00 */
Endpoint_Write_Stream_LE(&PadBytes, (AllocationLength - BytesTransferred), NO_STREAM_CALLBACK); Endpoint_Write_Stream_LE(&PadBytes, (AllocationLength - BytesTransferred), NO_STREAM_CALLBACK);
/* Finalize the stream transfer to send the last packet */ /* Finalize the stream transfer to send the last packet */
Endpoint_ClearIN(); Endpoint_ClearIN();
/* Succeed the command and update the bytes transferred counter */ /* Succeed the command and update the bytes transferred counter */
MSInterfaceInfo->State.CommandBlock.DataTransferLength -= BytesTransferred; MSInterfaceInfo->State.CommandBlock.DataTransferLength -= BytesTransferred;
} }
/** Command processing for an issued SCSI REQUEST SENSE command. This command returns information about the last issued command, /** Command processing for an issued SCSI REQUEST SENSE command. This command returns information about the last issued command,
* including the error code and additional error information so that the host can determine why a command failed to complete. * including the error code and additional error information so that the host can determine why a command failed to complete.
* *
* \param[in] MSInterfaceInfo Pointer to the Mass Storage class interface structure that the command is associated with * \param[in] MSInterfaceInfo Pointer to the Mass Storage class interface structure that the command is associated with
*/ */
static void SCSI_Command_Request_Sense(USB_ClassInfo_MS_Device_t* MSInterfaceInfo) static void SCSI_Command_Request_Sense(USB_ClassInfo_MS_Device_t* MSInterfaceInfo)
{ {
uint8_t AllocationLength = MSInterfaceInfo->State.CommandBlock.SCSICommandData[4]; uint8_t AllocationLength = MSInterfaceInfo->State.CommandBlock.SCSICommandData[4];
uint8_t BytesTransferred = (AllocationLength < sizeof(SenseData))? AllocationLength : sizeof(SenseData); uint8_t BytesTransferred = (AllocationLength < sizeof(SenseData))? AllocationLength : sizeof(SenseData);
uint8_t PadBytes[AllocationLength - BytesTransferred]; uint8_t PadBytes[AllocationLength - BytesTransferred];
Endpoint_Write_Stream_LE(&SenseData, BytesTransferred, NO_STREAM_CALLBACK); Endpoint_Write_Stream_LE(&SenseData, BytesTransferred, NO_STREAM_CALLBACK);
Endpoint_Write_Stream_LE(&PadBytes, (AllocationLength - BytesTransferred), NO_STREAM_CALLBACK); Endpoint_Write_Stream_LE(&PadBytes, (AllocationLength - BytesTransferred), NO_STREAM_CALLBACK);
Endpoint_ClearIN(); Endpoint_ClearIN();
/* Succeed the command and update the bytes transferred counter */ /* Succeed the command and update the bytes transferred counter */
MSInterfaceInfo->State.CommandBlock.DataTransferLength -= BytesTransferred; MSInterfaceInfo->State.CommandBlock.DataTransferLength -= BytesTransferred;
} }
/** Command processing for an issued SCSI READ CAPACITY (10) command. This command returns information about the device's capacity /** Command processing for an issued SCSI READ CAPACITY (10) command. This command returns information about the device's capacity
* on the selected Logical Unit (drive), as a number of OS-sized blocks. * on the selected Logical Unit (drive), as a number of OS-sized blocks.
* *
* \param[in] MSInterfaceInfo Pointer to the Mass Storage class interface structure that the command is associated with * \param[in] MSInterfaceInfo Pointer to the Mass Storage class interface structure that the command is associated with
*/ */
static void SCSI_Command_Read_Capacity_10(USB_ClassInfo_MS_Device_t* MSInterfaceInfo) static void SCSI_Command_Read_Capacity_10(USB_ClassInfo_MS_Device_t* MSInterfaceInfo)
{ {
uint32_t LastBlockAddressInLUN = (LUN_MEDIA_BLOCKS - 1); uint32_t LastBlockAddressInLUN = (LUN_MEDIA_BLOCKS - 1);
uint32_t MediaBlockSize = VIRTUAL_MEMORY_BLOCK_SIZE; uint32_t MediaBlockSize = VIRTUAL_MEMORY_BLOCK_SIZE;
Endpoint_Write_Stream_BE(&LastBlockAddressInLUN, sizeof(LastBlockAddressInLUN), NO_STREAM_CALLBACK); Endpoint_Write_Stream_BE(&LastBlockAddressInLUN, sizeof(LastBlockAddressInLUN), NO_STREAM_CALLBACK);
Endpoint_Write_Stream_BE(&MediaBlockSize, sizeof(MediaBlockSize), NO_STREAM_CALLBACK); Endpoint_Write_Stream_BE(&MediaBlockSize, sizeof(MediaBlockSize), NO_STREAM_CALLBACK);
Endpoint_ClearIN(); Endpoint_ClearIN();
/* Succeed the command and update the bytes transferred counter */ /* Succeed the command and update the bytes transferred counter */
MSInterfaceInfo->State.CommandBlock.DataTransferLength -= 8; MSInterfaceInfo->State.CommandBlock.DataTransferLength -= 8;
} }
/** Command processing for an issued SCSI SEND DIAGNOSTIC command. This command performs a quick check of the Dataflash ICs on the /** Command processing for an issued SCSI SEND DIAGNOSTIC command. This command performs a quick check of the Dataflash ICs on the
* board, and indicates if they are present and functioning correctly. Only the Self-Test portion of the diagnostic command is * board, and indicates if they are present and functioning correctly. Only the Self-Test portion of the diagnostic command is
* supported. * supported.
* *
* \param[in] MSInterfaceInfo Pointer to the Mass Storage class interface structure that the command is associated with * \param[in] MSInterfaceInfo Pointer to the Mass Storage class interface structure that the command is associated with
*/ */
static void SCSI_Command_Send_Diagnostic(USB_ClassInfo_MS_Device_t* MSInterfaceInfo) static void SCSI_Command_Send_Diagnostic(USB_ClassInfo_MS_Device_t* MSInterfaceInfo)
{ {
/* Check to see if the SELF TEST bit is not set */ /* Check to see if the SELF TEST bit is not set */
if (!(MSInterfaceInfo->State.CommandBlock.SCSICommandData[1] & (1 << 2))) if (!(MSInterfaceInfo->State.CommandBlock.SCSICommandData[1] & (1 << 2)))
{ {
/* Only self-test supported - update SENSE key and fail the command */ /* Only self-test supported - update SENSE key and fail the command */
SCSI_SET_SENSE(SCSI_SENSE_KEY_ILLEGAL_REQUEST, SCSI_SET_SENSE(SCSI_SENSE_KEY_ILLEGAL_REQUEST,
SCSI_ASENSE_INVALID_FIELD_IN_CDB, SCSI_ASENSE_INVALID_FIELD_IN_CDB,
SCSI_ASENSEQ_NO_QUALIFIER); SCSI_ASENSEQ_NO_QUALIFIER);
return; return;
} }
/* Check to see if all attached Dataflash ICs are functional */ /* Check to see if all attached Dataflash ICs are functional */
if (!(DataflashManager_CheckDataflashOperation())) if (!(DataflashManager_CheckDataflashOperation()))
{ {
/* Update SENSE key with a hardware error condition and return command fail */ /* Update SENSE key with a hardware error condition and return command fail */
SCSI_SET_SENSE(SCSI_SENSE_KEY_HARDWARE_ERROR, SCSI_SET_SENSE(SCSI_SENSE_KEY_HARDWARE_ERROR,
SCSI_ASENSE_NO_ADDITIONAL_INFORMATION, SCSI_ASENSE_NO_ADDITIONAL_INFORMATION,
SCSI_ASENSEQ_NO_QUALIFIER); SCSI_ASENSEQ_NO_QUALIFIER);
return; return;
} }
/* Succeed the command and update the bytes transferred counter */ /* Succeed the command and update the bytes transferred counter */
MSInterfaceInfo->State.CommandBlock.DataTransferLength = 0; MSInterfaceInfo->State.CommandBlock.DataTransferLength = 0;
} }
/** Command processing for an issued SCSI READ (10) or WRITE (10) command. This command reads in the block start address /** Command processing for an issued SCSI READ (10) or WRITE (10) command. This command reads in the block start address
* and total number of blocks to process, then calls the appropriate low-level dataflash routine to handle the actual * and total number of blocks to process, then calls the appropriate low-level dataflash routine to handle the actual
* reading and writing of the data. * reading and writing of the data.
* *
* \param[in] MSInterfaceInfo Pointer to the Mass Storage class interface structure that the command is associated with * \param[in] MSInterfaceInfo Pointer to the Mass Storage class interface structure that the command is associated with
* \param[in] IsDataRead Indicates if the command is a READ (10) command or WRITE (10) command (DATA_READ or DATA_WRITE) * \param[in] IsDataRead Indicates if the command is a READ (10) command or WRITE (10) command (DATA_READ or DATA_WRITE)
*/ */
static void SCSI_Command_ReadWrite_10(USB_ClassInfo_MS_Device_t* MSInterfaceInfo, const bool IsDataRead) static void SCSI_Command_ReadWrite_10(USB_ClassInfo_MS_Device_t* MSInterfaceInfo, const bool IsDataRead)
{ {
uint32_t BlockAddress; uint32_t BlockAddress;
uint16_t TotalBlocks; uint16_t TotalBlocks;
/* Load in the 32-bit block address (SCSI uses big-endian, so have to reverse the byte order) */ /* Load in the 32-bit block address (SCSI uses big-endian, so have to reverse the byte order) */
BlockAddress = SwapEndian_32(*(uint32_t*)&MSInterfaceInfo->State.CommandBlock.SCSICommandData[2]); BlockAddress = SwapEndian_32(*(uint32_t*)&MSInterfaceInfo->State.CommandBlock.SCSICommandData[2]);
/* Load in the 16-bit total blocks (SCSI uses big-endian, so have to reverse the byte order) */ /* Load in the 16-bit total blocks (SCSI uses big-endian, so have to reverse the byte order) */
TotalBlocks = SwapEndian_16(*(uint32_t*)&MSInterfaceInfo->State.CommandBlock.SCSICommandData[7]); TotalBlocks = SwapEndian_16(*(uint32_t*)&MSInterfaceInfo->State.CommandBlock.SCSICommandData[7]);
/* Check if the block address is outside the maximum allowable value for the LUN */ /* Check if the block address is outside the maximum allowable value for the LUN */
if (BlockAddress >= LUN_MEDIA_BLOCKS) if (BlockAddress >= LUN_MEDIA_BLOCKS)
{ {
/* Block address is invalid, update SENSE key and return command fail */ /* Block address is invalid, update SENSE key and return command fail */
SCSI_SET_SENSE(SCSI_SENSE_KEY_ILLEGAL_REQUEST, SCSI_SET_SENSE(SCSI_SENSE_KEY_ILLEGAL_REQUEST,
SCSI_ASENSE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, SCSI_ASENSE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
SCSI_ASENSEQ_NO_QUALIFIER); SCSI_ASENSEQ_NO_QUALIFIER);
return; return;
} }
#if (TOTAL_LUNS > 1) #if (TOTAL_LUNS > 1)
/* Adjust the given block address to the real media address based on the selected LUN */ /* Adjust the given block address to the real media address based on the selected LUN */
BlockAddress += ((uint32_t)MSInterfaceInfo->State.CommandBlock.LUN * LUN_MEDIA_BLOCKS); BlockAddress += ((uint32_t)MSInterfaceInfo->State.CommandBlock.LUN * LUN_MEDIA_BLOCKS);
#endif #endif
/* Determine if the packet is a READ (10) or WRITE (10) command, call appropriate function */ /* Determine if the packet is a READ (10) or WRITE (10) command, call appropriate function */
if (IsDataRead == DATA_READ) if (IsDataRead == DATA_READ)
DataflashManager_ReadBlocks(MSInterfaceInfo, BlockAddress, TotalBlocks); DataflashManager_ReadBlocks(MSInterfaceInfo, BlockAddress, TotalBlocks);
else else
DataflashManager_WriteBlocks(MSInterfaceInfo, BlockAddress, TotalBlocks); DataflashManager_WriteBlocks(MSInterfaceInfo, BlockAddress, TotalBlocks);
/* Update the bytes transferred counter and succeed the command */ /* Update the bytes transferred counter and succeed the command */
MSInterfaceInfo->State.CommandBlock.DataTransferLength -= ((uint32_t)TotalBlocks * VIRTUAL_MEMORY_BLOCK_SIZE); MSInterfaceInfo->State.CommandBlock.DataTransferLength -= ((uint32_t)TotalBlocks * VIRTUAL_MEMORY_BLOCK_SIZE);
} }

View file

@ -1,86 +1,86 @@
/* /*
LUFA Library LUFA Library
Copyright (C) Dean Camera, 2010. Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com www.fourwalledcubicle.com
*/ */
/* /*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com) Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the advertising or publicity pertaining to distribution of the
software without specific, written prior permission. software without specific, written prior permission.
The author disclaim all warranties with regard to this The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action, in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of arising out of or in connection with the use or performance of
this software. this software.
*/ */
/** \file /** \file
* *
* Header file for SCSI.c. * Header file for SCSI.c.
*/ */
#ifndef _SCSI_H_ #ifndef _SCSI_H_
#define _SCSI_H_ #define _SCSI_H_
/* Includes: */ /* Includes: */
#include <avr/io.h> #include <avr/io.h>
#include <avr/pgmspace.h> #include <avr/pgmspace.h>
#include <LUFA/Drivers/USB/USB.h> #include <LUFA/Drivers/USB/USB.h>
#include <LUFA/Drivers/USB/Class/MassStorage.h> #include <LUFA/Drivers/USB/Class/MassStorage.h>
#include "MassStorage.h" #include "MassStorage.h"
#include "Descriptors.h" #include "Descriptors.h"
#include "DataflashManager.h" #include "DataflashManager.h"
/* Macros: */ /* Macros: */
/** Macro to set the current SCSI sense data to the given key, additional sense code and additional sense qualifier. This /** Macro to set the current SCSI sense data to the given key, additional sense code and additional sense qualifier. This
* is for convenience, as it allows for all three sense values (returned upon request to the host to give information about * is for convenience, as it allows for all three sense values (returned upon request to the host to give information about
* the last command failure) in a quick and easy manner. * the last command failure) in a quick and easy manner.
* *
* \param[in] key New SCSI sense key to set the sense code to * \param[in] key New SCSI sense key to set the sense code to
* \param[in] acode New SCSI additional sense key to set the additional sense code to * \param[in] acode New SCSI additional sense key to set the additional sense code to
* \param[in] aqual New SCSI additional sense key qualifier to set the additional sense qualifier code to * \param[in] aqual New SCSI additional sense key qualifier to set the additional sense qualifier code to
*/ */
#define SCSI_SET_SENSE(key, acode, aqual) MACROS{ SenseData.SenseKey = (key); \ #define SCSI_SET_SENSE(key, acode, aqual) MACROS{ SenseData.SenseKey = (key); \
SenseData.AdditionalSenseCode = (acode); \ SenseData.AdditionalSenseCode = (acode); \
SenseData.AdditionalSenseQualifier = (aqual); }MACROE SenseData.AdditionalSenseQualifier = (aqual); }MACROE
/** Macro for the SCSI_Command_ReadWrite_10() function, to indicate that data is to be read from the storage medium. */ /** Macro for the SCSI_Command_ReadWrite_10() function, to indicate that data is to be read from the storage medium. */
#define DATA_READ true #define DATA_READ true
/** Macro for the SCSI_Command_ReadWrite_10() function, to indicate that data is to be written to the storage medium. */ /** Macro for the SCSI_Command_ReadWrite_10() function, to indicate that data is to be written to the storage medium. */
#define DATA_WRITE false #define DATA_WRITE false
/** Value for the DeviceType entry in the SCSI_Inquiry_Response_t enum, indicating a Block Media device. */ /** Value for the DeviceType entry in the SCSI_Inquiry_Response_t enum, indicating a Block Media device. */
#define DEVICE_TYPE_BLOCK 0x00 #define DEVICE_TYPE_BLOCK 0x00
/** Value for the DeviceType entry in the SCSI_Inquiry_Response_t enum, indicating a CD-ROM device. */ /** Value for the DeviceType entry in the SCSI_Inquiry_Response_t enum, indicating a CD-ROM device. */
#define DEVICE_TYPE_CDROM 0x05 #define DEVICE_TYPE_CDROM 0x05
/* Function Prototypes: */ /* Function Prototypes: */
bool SCSI_DecodeSCSICommand(USB_ClassInfo_MS_Device_t* MSInterfaceInfo); bool SCSI_DecodeSCSICommand(USB_ClassInfo_MS_Device_t* MSInterfaceInfo);
#if defined(INCLUDE_FROM_SCSI_C) #if defined(INCLUDE_FROM_SCSI_C)
static void SCSI_Command_Inquiry(USB_ClassInfo_MS_Device_t* MSInterfaceInfo); static void SCSI_Command_Inquiry(USB_ClassInfo_MS_Device_t* MSInterfaceInfo);
static void SCSI_Command_Request_Sense(USB_ClassInfo_MS_Device_t* MSInterfaceInfo); static void SCSI_Command_Request_Sense(USB_ClassInfo_MS_Device_t* MSInterfaceInfo);
static void SCSI_Command_Read_Capacity_10(USB_ClassInfo_MS_Device_t* MSInterfaceInfo); static void SCSI_Command_Read_Capacity_10(USB_ClassInfo_MS_Device_t* MSInterfaceInfo);
static void SCSI_Command_Send_Diagnostic(USB_ClassInfo_MS_Device_t* MSInterfaceInfo); static void SCSI_Command_Send_Diagnostic(USB_ClassInfo_MS_Device_t* MSInterfaceInfo);
static void SCSI_Command_ReadWrite_10(USB_ClassInfo_MS_Device_t* MSInterfaceInfo, const bool IsDataRead); static void SCSI_Command_ReadWrite_10(USB_ClassInfo_MS_Device_t* MSInterfaceInfo, const bool IsDataRead);
#endif #endif
#endif #endif

View file

@ -1,138 +1,138 @@
/* /*
LUFA Library LUFA Library
Copyright (C) Dean Camera, 2010. Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com www.fourwalledcubicle.com
*/ */
/* /*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com) Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the advertising or publicity pertaining to distribution of the
software without specific, written prior permission. software without specific, written prior permission.
The author disclaim all warranties with regard to this The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action, in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of arising out of or in connection with the use or performance of
this software. this software.
*/ */
/** \file /** \file
* *
* Main source file for the MassStorage demo. This file contains the main tasks of * Main source file for the MassStorage demo. This file contains the main tasks of
* the demo and is responsible for the initial application hardware configuration. * the demo and is responsible for the initial application hardware configuration.
*/ */
#include "MassStorage.h" #include "MassStorage.h"
/** LUFA Mass Storage Class driver interface configuration and state information. This structure is /** LUFA Mass Storage Class driver interface configuration and state information. This structure is
* passed to all Mass Storage Class driver functions, so that multiple instances of the same class * passed to all Mass Storage Class driver functions, so that multiple instances of the same class
* within a device can be differentiated from one another. * within a device can be differentiated from one another.
*/ */
USB_ClassInfo_MS_Device_t Disk_MS_Interface = USB_ClassInfo_MS_Device_t Disk_MS_Interface =
{ {
.Config = .Config =
{ {
.InterfaceNumber = 0, .InterfaceNumber = 0,
.DataINEndpointNumber = MASS_STORAGE_IN_EPNUM, .DataINEndpointNumber = MASS_STORAGE_IN_EPNUM,
.DataINEndpointSize = MASS_STORAGE_IO_EPSIZE, .DataINEndpointSize = MASS_STORAGE_IO_EPSIZE,
.DataINEndpointDoubleBank = false, .DataINEndpointDoubleBank = false,
.DataOUTEndpointNumber = MASS_STORAGE_OUT_EPNUM, .DataOUTEndpointNumber = MASS_STORAGE_OUT_EPNUM,
.DataOUTEndpointSize = MASS_STORAGE_IO_EPSIZE, .DataOUTEndpointSize = MASS_STORAGE_IO_EPSIZE,
.DataOUTEndpointDoubleBank = false, .DataOUTEndpointDoubleBank = false,
.TotalLUNs = TOTAL_LUNS, .TotalLUNs = TOTAL_LUNS,
}, },
}; };
/** Main program entry point. This routine contains the overall program flow, including initial /** Main program entry point. This routine contains the overall program flow, including initial
* setup of all components and the main program loop. * setup of all components and the main program loop.
*/ */
int main(void) int main(void)
{ {
SetupHardware(); SetupHardware();
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY); LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
sei(); sei();
for (;;) for (;;)
{ {
MS_Device_USBTask(&Disk_MS_Interface); MS_Device_USBTask(&Disk_MS_Interface);
USB_USBTask(); USB_USBTask();
} }
} }
/** Configures the board hardware and chip peripherals for the demo's functionality. */ /** Configures the board hardware and chip peripherals for the demo's functionality. */
void SetupHardware(void) void SetupHardware(void)
{ {
/* Disable watchdog if enabled by bootloader/fuses */ /* Disable watchdog if enabled by bootloader/fuses */
MCUSR &= ~(1 << WDRF); MCUSR &= ~(1 << WDRF);
wdt_disable(); wdt_disable();
/* Disable clock division */ /* Disable clock division */
clock_prescale_set(clock_div_1); clock_prescale_set(clock_div_1);
/* Hardware Initialization */ /* Hardware Initialization */
LEDs_Init(); LEDs_Init();
SPI_Init(SPI_SPEED_FCPU_DIV_2 | SPI_SCK_LEAD_FALLING | SPI_SAMPLE_TRAILING | SPI_MODE_MASTER); SPI_Init(SPI_SPEED_FCPU_DIV_2 | SPI_SCK_LEAD_FALLING | SPI_SAMPLE_TRAILING | SPI_MODE_MASTER);
Dataflash_Init(); Dataflash_Init();
USB_Init(); USB_Init();
/* Clear Dataflash sector protections, if enabled */ /* Clear Dataflash sector protections, if enabled */
DataflashManager_ResetDataflashProtections(); DataflashManager_ResetDataflashProtections();
} }
/** Event handler for the library USB Connection event. */ /** Event handler for the library USB Connection event. */
void EVENT_USB_Device_Connect(void) void EVENT_USB_Device_Connect(void)
{ {
LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING); LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
} }
/** Event handler for the library USB Disconnection event. */ /** Event handler for the library USB Disconnection event. */
void EVENT_USB_Device_Disconnect(void) void EVENT_USB_Device_Disconnect(void)
{ {
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY); LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
} }
/** Event handler for the library USB Configuration Changed event. */ /** Event handler for the library USB Configuration Changed event. */
void EVENT_USB_Device_ConfigurationChanged(void) void EVENT_USB_Device_ConfigurationChanged(void)
{ {
LEDs_SetAllLEDs(LEDMASK_USB_READY); LEDs_SetAllLEDs(LEDMASK_USB_READY);
if (!(MS_Device_ConfigureEndpoints(&Disk_MS_Interface))) if (!(MS_Device_ConfigureEndpoints(&Disk_MS_Interface)))
LEDs_SetAllLEDs(LEDMASK_USB_ERROR); LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
} }
/** Event handler for the library USB Unhandled Control Request event. */ /** Event handler for the library USB Unhandled Control Request event. */
void EVENT_USB_Device_UnhandledControlRequest(void) void EVENT_USB_Device_UnhandledControlRequest(void)
{ {
MS_Device_ProcessControlRequest(&Disk_MS_Interface); MS_Device_ProcessControlRequest(&Disk_MS_Interface);
} }
/** Mass Storage class driver callback function the reception of SCSI commands from the host, which must be processed. /** Mass Storage class driver callback function the reception of SCSI commands from the host, which must be processed.
* *
* \param[in] MSInterfaceInfo Pointer to the Mass Storage class interface configuration structure being referenced * \param[in] MSInterfaceInfo Pointer to the Mass Storage class interface configuration structure being referenced
*/ */
bool CALLBACK_MS_Device_SCSICommandReceived(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) bool CALLBACK_MS_Device_SCSICommandReceived(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo)
{ {
bool CommandSuccess; bool CommandSuccess;
LEDs_SetAllLEDs(LEDMASK_USB_BUSY); LEDs_SetAllLEDs(LEDMASK_USB_BUSY);
CommandSuccess = SCSI_DecodeSCSICommand(MSInterfaceInfo); CommandSuccess = SCSI_DecodeSCSICommand(MSInterfaceInfo);
LEDs_SetAllLEDs(LEDMASK_USB_READY); LEDs_SetAllLEDs(LEDMASK_USB_READY);
return CommandSuccess; return CommandSuccess;
} }

View file

@ -1,88 +1,88 @@
/* /*
LUFA Library LUFA Library
Copyright (C) Dean Camera, 2010. Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com www.fourwalledcubicle.com
*/ */
/* /*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com) Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the advertising or publicity pertaining to distribution of the
software without specific, written prior permission. software without specific, written prior permission.
The author disclaim all warranties with regard to this The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action, in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of arising out of or in connection with the use or performance of
this software. this software.
*/ */
/** \file /** \file
* *
* Header file for MassStorage.c. * Header file for MassStorage.c.
*/ */
#ifndef _MASS_STORAGE_H_ #ifndef _MASS_STORAGE_H_
#define _MASS_STORAGE_H_ #define _MASS_STORAGE_H_
/* Includes: */ /* Includes: */
#include <avr/io.h> #include <avr/io.h>
#include <avr/wdt.h> #include <avr/wdt.h>
#include <avr/power.h> #include <avr/power.h>
#include <avr/interrupt.h> #include <avr/interrupt.h>
#include <string.h> #include <string.h>
#include "Descriptors.h" #include "Descriptors.h"
#include "Lib/SCSI.h" #include "Lib/SCSI.h"
#include "Lib/DataflashManager.h" #include "Lib/DataflashManager.h"
#include <LUFA/Version.h> #include <LUFA/Version.h>
#include <LUFA/Drivers/Board/LEDs.h> #include <LUFA/Drivers/Board/LEDs.h>
#include <LUFA/Drivers/USB/USB.h> #include <LUFA/Drivers/USB/USB.h>
#include <LUFA/Drivers/USB/Class/MassStorage.h> #include <LUFA/Drivers/USB/Class/MassStorage.h>
/* Macros: */ /* Macros: */
/** LED mask for the library LED driver, to indicate that the USB interface is not ready. */ /** LED mask for the library LED driver, to indicate that the USB interface is not ready. */
#define LEDMASK_USB_NOTREADY LEDS_LED1 #define LEDMASK_USB_NOTREADY LEDS_LED1
/** LED mask for the library LED driver, to indicate that the USB interface is enumerating. */ /** LED mask for the library LED driver, to indicate that the USB interface is enumerating. */
#define LEDMASK_USB_ENUMERATING (LEDS_LED2 | LEDS_LED3) #define LEDMASK_USB_ENUMERATING (LEDS_LED2 | LEDS_LED3)
/** LED mask for the library LED driver, to indicate that the USB interface is ready. */ /** LED mask for the library LED driver, to indicate that the USB interface is ready. */
#define LEDMASK_USB_READY (LEDS_LED2 | LEDS_LED4) #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. */ /** 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) #define LEDMASK_USB_ERROR (LEDS_LED1 | LEDS_LED3)
/** LED mask for the library LED driver, to indicate that the USB interface is busy. */ /** LED mask for the library LED driver, to indicate that the USB interface is busy. */
#define LEDMASK_USB_BUSY LEDS_LED2 #define LEDMASK_USB_BUSY LEDS_LED2
/** Total number of logical drives within the device - must be non-zero. */ /** Total number of logical drives within the device - must be non-zero. */
#define TOTAL_LUNS 1 #define TOTAL_LUNS 1
/** Blocks in each LUN, calculated from the total capacity divided by the total number of Logical Units in the device. */ /** Blocks in each LUN, calculated from the total capacity divided by the total number of Logical Units in the device. */
#define LUN_MEDIA_BLOCKS (VIRTUAL_MEMORY_BLOCKS / TOTAL_LUNS) #define LUN_MEDIA_BLOCKS (VIRTUAL_MEMORY_BLOCKS / TOTAL_LUNS)
/* Function Prototypes: */ /* Function Prototypes: */
void SetupHardware(void); void SetupHardware(void);
void EVENT_USB_Device_Connect(void); void EVENT_USB_Device_Connect(void);
void EVENT_USB_Device_Disconnect(void); void EVENT_USB_Device_Disconnect(void);
void EVENT_USB_Device_ConfigurationChanged(void); void EVENT_USB_Device_ConfigurationChanged(void);
void EVENT_USB_Device_UnhandledControlRequest(void); void EVENT_USB_Device_UnhandledControlRequest(void);
bool CALLBACK_MS_Device_SCSICommandReceived(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo); bool CALLBACK_MS_Device_SCSICommandReceived(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo);
#endif #endif

View file

@ -1,92 +1,92 @@
/** \file /** \file
* *
* This file contains special DoxyGen information for the generation of the main page and other special * 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. * documentation pages. It is not a project source file.
*/ */
/** \mainpage Mass Storage Device Demo /** \mainpage Mass Storage Device Demo
* *
* \section SSec_Compat Demo Compatibility: * \section SSec_Compat Demo Compatibility:
* *
* The following list indicates what microcontrollers are compatible with this demo. * The following list indicates what microcontrollers are compatible with this demo.
* *
* - Series 7 USB AVRs * - Series 7 USB AVRs
* - Series 6 USB AVRs * - Series 6 USB AVRs
* - Series 4 USB AVRs * - Series 4 USB AVRs
* - Series 2 USB AVRs * - Series 2 USB AVRs
* *
* \section SSec_Info USB Information: * \section SSec_Info USB Information:
* *
* The following table gives a rundown of the USB utilization of this demo. * The following table gives a rundown of the USB utilization of this demo.
* *
* <table> * <table>
* <tr> * <tr>
* <td><b>USB Mode:</b></td> * <td><b>USB Mode:</b></td>
* <td>Device</td> * <td>Device</td>
* </tr> * </tr>
* <tr> * <tr>
* <td><b>USB Class:</b></td> * <td><b>USB Class:</b></td>
* <td>Mass Storage Device</td> * <td>Mass Storage Device</td>
* </tr> * </tr>
* <tr> * <tr>
* <td><b>USB Subclass:</b></td> * <td><b>USB Subclass:</b></td>
* <td>Bulk-Only Transport</td> * <td>Bulk-Only Transport</td>
* </tr> * </tr>
* <tr> * <tr>
* <td><b>Relevant Standards:</b></td> * <td><b>Relevant Standards:</b></td>
* <td>USBIF Mass Storage Standard \n * <td>USBIF Mass Storage Standard \n
* USB Bulk-Only Transport Standard \n * USB Bulk-Only Transport Standard \n
* SCSI Primary Commands Specification \n * SCSI Primary Commands Specification \n
* SCSI Block Commands Specification</td> * SCSI Block Commands Specification</td>
* </tr> * </tr>
* <tr> * <tr>
* <td><b>Usable Speeds:</b></td> * <td><b>Usable Speeds:</b></td>
* <td>Full Speed Mode</td> * <td>Full Speed Mode</td>
* </tr> * </tr>
* </table> * </table>
* *
* \section SSec_Description Project Description: * \section SSec_Description Project Description:
* *
* Dual LUN Mass Storage demonstration application. This gives a simple * Dual LUN Mass Storage demonstration application. This gives a simple
* reference application for implementing a multiple LUN USB Mass Storage * reference application for implementing a multiple LUN USB Mass Storage
* device using the basic USB UFI drivers in all modern OSes (i.e. no * device using the basic USB UFI drivers in all modern OSes (i.e. no
* special drivers required). * special drivers required).
* *
* On start-up the system will automatically enumerate and function as an * On start-up the system will automatically enumerate and function as an
* external mass storage device with two LUNs (separate disks) which may * external mass storage device with two LUNs (separate disks) which may
* be formatted and used in the same manner as commercial USB Mass Storage * be formatted and used in the same manner as commercial USB Mass Storage
* devices. * devices.
* *
* You will need to format the mass storage drives upon first run of this * You will need to format the mass storage drives upon first run of this
* demonstration - as the device acts only as a data block transport between * demonstration - as the device acts only as a data block transport between
* the host and the storage media, it does not matter what file system is used, * the host and the storage media, it does not matter what file system is used,
* as the data interpretation is performed by the host and not the USB device. * as the data interpretation is performed by the host and not the USB device.
* *
* This demo is not restricted to only two LUNs; by changing the TOTAL_LUNS * This demo is not restricted to only two LUNs; by changing the TOTAL_LUNS
* value in MassStorageDualLUN.h, any number of LUNs can be used (from 1 to * value in MassStorageDualLUN.h, any number of LUNs can be used (from 1 to
* 255), with each LUN being allocated an equal portion of the available * 255), with each LUN being allocated an equal portion of the available
* Dataflash memory. * Dataflash memory.
* *
* The USB control endpoint is managed entirely by the library using endpoint * The USB control endpoint is managed entirely by the library using endpoint
* interrupts, as the INTERRUPT_CONTROL_ENDPOINT option is enabled. This allows for * interrupts, as the INTERRUPT_CONTROL_ENDPOINT option is enabled. This allows for
* the host to reset the Mass Storage device state during long transfers without * the host to reset the Mass Storage device state during long transfers without
* the need for complicated polling logic. * the need for complicated polling logic.
* *
* \section SSec_Options Project Options * \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. * The following defines can be found in this demo, which can control the demo behaviour when defined, or changed in value.
* *
* <table> * <table>
* <tr> * <tr>
* <td><b>Define Name:</b></td> * <td><b>Define Name:</b></td>
* <td><b>Location:</b></td> * <td><b>Location:</b></td>
* <td><b>Description:</b></td> * <td><b>Description:</b></td>
* </tr> * </tr>
* <tr> * <tr>
* <td>TOTAL_LUNS</td> * <td>TOTAL_LUNS</td>
* <td>MassStorage.h</td> * <td>MassStorage.h</td>
* <td>Total number of Logical Units (drives) in the device. The total device capacity is shared equally between each drive * <td>Total number of Logical Units (drives) in the device. The total device capacity is shared equally between each drive
* - this can be set to any positive non-zero amount.</td> * - this can be set to any positive non-zero amount.</td>
* </tr> * </tr>
* </table> * </table>
*/ */

File diff suppressed because it is too large Load diff

View file

@ -1,305 +1,305 @@
/* /*
LUFA Library LUFA Library
Copyright (C) Dean Camera, 2010. Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com www.fourwalledcubicle.com
*/ */
/* /*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com) Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Copyright 2010 Matthias Hullin (lufa [at] matthias [dot] hullin [dot] net) Copyright 2010 Matthias Hullin (lufa [at] matthias [dot] hullin [dot] net)
Permission to use, copy, modify, distribute, and sell this Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the advertising or publicity pertaining to distribution of the
software without specific, written prior permission. software without specific, written prior permission.
The author disclaim all warranties with regard to this The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action, in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of arising out of or in connection with the use or performance of
this software. this software.
*/ */
/** \file /** \file
* *
* USB Device Descriptors, for library use when in USB device mode. Descriptors are special * USB Device Descriptors, for library use when in USB device mode. Descriptors are special
* computer-readable structures which the host requests upon device enumeration, to determine * computer-readable structures which the host requests upon device enumeration, to determine
* the device's capabilities and functions. * the device's capabilities and functions.
*/ */
#include "Descriptors.h" #include "Descriptors.h"
/* On some devices, there is a factory set internal serial number which can be automatically sent to the host as /* On some devices, there is a factory set internal serial number which can be automatically sent to the host as
* the device's serial number when the Device Descriptor's .SerialNumStrIndex entry is set to USE_INTERNAL_SERIAL. * the device's serial number when the Device Descriptor's .SerialNumStrIndex entry is set to USE_INTERNAL_SERIAL.
* This allows the host to track a device across insertions on different ports, allowing them to retain allocated * This allows the host to track a device across insertions on different ports, allowing them to retain allocated
* resources like COM port numbers and drivers. On demos using this feature, give a warning on unsupported devices * resources like COM port numbers and drivers. On demos using this feature, give a warning on unsupported devices
* so that the user can supply their own serial number descriptor instead or remove the USE_INTERNAL_SERIAL value * so that the user can supply their own serial number descriptor instead or remove the USE_INTERNAL_SERIAL value
* from the Device Descriptor (forcing the host to generate a serial number for each device from the VID, PID and * from the Device Descriptor (forcing the host to generate a serial number for each device from the VID, PID and
* port location). * port location).
*/ */
#if (USE_INTERNAL_SERIAL == NO_DESCRIPTOR) #if (USE_INTERNAL_SERIAL == NO_DESCRIPTOR)
#warning USE_INTERNAL_SERIAL is not available on this AVR - please manually construct a device serial descriptor. #warning USE_INTERNAL_SERIAL is not available on this AVR - please manually construct a device serial descriptor.
#endif #endif
/** HID class report descriptor. This is a special descriptor constructed with values from the /** HID class report descriptor. This is a special descriptor constructed with values from the
* USBIF HID class specification to describe the reports and capabilities of the HID device. This * USBIF HID class specification to describe the reports and capabilities of the HID device. This
* descriptor is parsed by the host and its contents used to determine what data (and in what encoding) * descriptor is parsed by the host and its contents used to determine what data (and in what encoding)
* the device will send, and what it may be sent back from the host. Refer to the HID specification for * the device will send, and what it may be sent back from the host. Refer to the HID specification for
* more details on HID report descriptors. * more details on HID report descriptors.
*/ */
USB_Descriptor_HIDReport_Datatype_t PROGMEM KeyboardReport[] = USB_Descriptor_HIDReport_Datatype_t PROGMEM KeyboardReport[] =
{ {
0x05, 0x01, /* Usage Page (Generic Desktop) */ 0x05, 0x01, /* Usage Page (Generic Desktop) */
0x09, 0x06, /* Usage (Keyboard) */ 0x09, 0x06, /* Usage (Keyboard) */
0xa1, 0x01, /* Collection (Application) */ 0xa1, 0x01, /* Collection (Application) */
0x75, 0x01, /* Report Size (1) */ 0x75, 0x01, /* Report Size (1) */
0x95, 0x08, /* Report Count (8) */ 0x95, 0x08, /* Report Count (8) */
0x05, 0x07, /* Usage Page (Key Codes) */ 0x05, 0x07, /* Usage Page (Key Codes) */
0x19, 0xe0, /* Usage Minimum (Keyboard LeftControl) */ 0x19, 0xe0, /* Usage Minimum (Keyboard LeftControl) */
0x29, 0xe7, /* Usage Maximum (Keyboard Right GUI) */ 0x29, 0xe7, /* Usage Maximum (Keyboard Right GUI) */
0x15, 0x00, /* Logical Minimum (0) */ 0x15, 0x00, /* Logical Minimum (0) */
0x25, 0x01, /* Logical Maximum (1) */ 0x25, 0x01, /* Logical Maximum (1) */
0x81, 0x02, /* Input (Data, Variable, Absolute) */ 0x81, 0x02, /* Input (Data, Variable, Absolute) */
0x95, 0x01, /* Report Count (1) */ 0x95, 0x01, /* Report Count (1) */
0x75, 0x08, /* Report Size (8) */ 0x75, 0x08, /* Report Size (8) */
0x81, 0x03, /* Input (Const, Variable, Absolute) */ 0x81, 0x03, /* Input (Const, Variable, Absolute) */
0x95, 0x05, /* Report Count (5) */ 0x95, 0x05, /* Report Count (5) */
0x75, 0x01, /* Report Size (1) */ 0x75, 0x01, /* Report Size (1) */
0x05, 0x08, /* Usage Page (LEDs) */ 0x05, 0x08, /* Usage Page (LEDs) */
0x19, 0x01, /* Usage Minimum (Num Lock) */ 0x19, 0x01, /* Usage Minimum (Num Lock) */
0x29, 0x05, /* Usage Maximum (Kana) */ 0x29, 0x05, /* Usage Maximum (Kana) */
0x91, 0x02, /* Output (Data, Variable, Absolute) */ 0x91, 0x02, /* Output (Data, Variable, Absolute) */
0x95, 0x01, /* Report Count (1) */ 0x95, 0x01, /* Report Count (1) */
0x75, 0x03, /* Report Size (3) */ 0x75, 0x03, /* Report Size (3) */
0x91, 0x03, /* Output (Const, Variable, Absolute) */ 0x91, 0x03, /* Output (Const, Variable, Absolute) */
0x95, 0x06, /* Report Count (6) */ 0x95, 0x06, /* Report Count (6) */
0x75, 0x08, /* Report Size (8) */ 0x75, 0x08, /* Report Size (8) */
0x15, 0x00, /* Logical Minimum (0) */ 0x15, 0x00, /* Logical Minimum (0) */
0x25, 0x65, /* Logical Maximum (101) */ 0x25, 0x65, /* Logical Maximum (101) */
0x05, 0x07, /* Usage Page (Keyboard) */ 0x05, 0x07, /* Usage Page (Keyboard) */
0x19, 0x00, /* Usage Minimum (Reserved (no event indicated)) */ 0x19, 0x00, /* Usage Minimum (Reserved (no event indicated)) */
0x29, 0x65, /* Usage Maximum (Keyboard Application) */ 0x29, 0x65, /* Usage Maximum (Keyboard Application) */
0x81, 0x00, /* Input (Data, Array, Absolute) */ 0x81, 0x00, /* Input (Data, Array, Absolute) */
0xc0 /* End Collection */ 0xc0 /* End Collection */
}; };
/** Device descriptor structure. This descriptor, located in FLASH memory, describes the overall /** Device descriptor structure. This descriptor, located in FLASH memory, describes the overall
* device characteristics, including the supported USB version, control endpoint size and the * device characteristics, including the supported USB version, control endpoint size and the
* number of device configurations. The descriptor is read out by the USB host when the enumeration * number of device configurations. The descriptor is read out by the USB host when the enumeration
* process begins. * process begins.
*/ */
USB_Descriptor_Device_t PROGMEM DeviceDescriptor = USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
{ {
.Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device}, .Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device},
.USBSpecification = VERSION_BCD(01.10), .USBSpecification = VERSION_BCD(01.10),
.Class = 0x00, .Class = 0x00,
.SubClass = 0x00, .SubClass = 0x00,
.Protocol = 0x00, .Protocol = 0x00,
.Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE, .Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE,
.VendorID = 0x03EB, .VendorID = 0x03EB,
.ProductID = 0x2061, .ProductID = 0x2061,
.ReleaseNumber = 0x0000, .ReleaseNumber = 0x0000,
.ManufacturerStrIndex = 0x01, .ManufacturerStrIndex = 0x01,
.ProductStrIndex = 0x02, .ProductStrIndex = 0x02,
.SerialNumStrIndex = USE_INTERNAL_SERIAL, .SerialNumStrIndex = USE_INTERNAL_SERIAL,
.NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS .NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS
}; };
/** Configuration descriptor structure. This descriptor, located in FLASH memory, describes the usage /** Configuration descriptor structure. This descriptor, located in FLASH memory, describes the usage
* of the device in one of its supported configurations, including information about any device interfaces * of the device in one of its supported configurations, including information about any device interfaces
* and endpoints. The descriptor is read out by the USB host during the enumeration process when selecting * and endpoints. The descriptor is read out by the USB host during the enumeration process when selecting
* a configuration so that the host may correctly communicate with the USB device. * a configuration so that the host may correctly communicate with the USB device.
*/ */
USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor = USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
{ {
.Config = .Config =
{ {
.Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration}, .Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration},
.TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t), .TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t),
.TotalInterfaces = 2, .TotalInterfaces = 2,
.ConfigurationNumber = 1, .ConfigurationNumber = 1,
.ConfigurationStrIndex = NO_DESCRIPTOR, .ConfigurationStrIndex = NO_DESCRIPTOR,
.ConfigAttributes = USB_CONFIG_ATTR_BUSPOWERED, .ConfigAttributes = USB_CONFIG_ATTR_BUSPOWERED,
.MaxPowerConsumption = USB_CONFIG_POWER_MA(100) .MaxPowerConsumption = USB_CONFIG_POWER_MA(100)
}, },
.MS_Interface = .MS_Interface =
{ {
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface}, .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
.InterfaceNumber = 0, .InterfaceNumber = 0,
.AlternateSetting = 0, .AlternateSetting = 0,
.TotalEndpoints = 2, .TotalEndpoints = 2,
.Class = 0x08, .Class = 0x08,
.SubClass = 0x06, .SubClass = 0x06,
.Protocol = 0x50, .Protocol = 0x50,
.InterfaceStrIndex = NO_DESCRIPTOR .InterfaceStrIndex = NO_DESCRIPTOR
}, },
.MS_DataInEndpoint = .MS_DataInEndpoint =
{ {
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint}, .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
.EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_IN | MASS_STORAGE_IN_EPNUM), .EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_IN | MASS_STORAGE_IN_EPNUM),
.Attributes = EP_TYPE_BULK, .Attributes = EP_TYPE_BULK,
.EndpointSize = MASS_STORAGE_IO_EPSIZE, .EndpointSize = MASS_STORAGE_IO_EPSIZE,
.PollingIntervalMS = 0x00 .PollingIntervalMS = 0x00
}, },
.MS_DataOutEndpoint = .MS_DataOutEndpoint =
{ {
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint}, .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
.EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_OUT | MASS_STORAGE_OUT_EPNUM), .EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_OUT | MASS_STORAGE_OUT_EPNUM),
.Attributes = EP_TYPE_BULK, .Attributes = EP_TYPE_BULK,
.EndpointSize = MASS_STORAGE_IO_EPSIZE, .EndpointSize = MASS_STORAGE_IO_EPSIZE,
.PollingIntervalMS = 0x00 .PollingIntervalMS = 0x00
}, },
.HID_KeyboardInterface = .HID_KeyboardInterface =
{ {
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface}, .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
.InterfaceNumber = 1, .InterfaceNumber = 1,
.AlternateSetting = 0, .AlternateSetting = 0,
.TotalEndpoints = 1, .TotalEndpoints = 1,
.Class = 0x03, .Class = 0x03,
.SubClass = 0x01, .SubClass = 0x01,
.Protocol = 0x01, .Protocol = 0x01,
.InterfaceStrIndex = NO_DESCRIPTOR .InterfaceStrIndex = NO_DESCRIPTOR
}, },
.HID_KeyboardHID = .HID_KeyboardHID =
{ {
.Header = {.Size = sizeof(USB_HID_Descriptor_t), .Type = DTYPE_HID}, .Header = {.Size = sizeof(USB_HID_Descriptor_t), .Type = DTYPE_HID},
.HIDSpec = VERSION_BCD(01.11), .HIDSpec = VERSION_BCD(01.11),
.CountryCode = 0x00, .CountryCode = 0x00,
.TotalReportDescriptors = 1, .TotalReportDescriptors = 1,
.HIDReportType = DTYPE_Report, .HIDReportType = DTYPE_Report,
.HIDReportLength = sizeof(KeyboardReport) .HIDReportLength = sizeof(KeyboardReport)
}, },
.HID_ReportINEndpoint = .HID_ReportINEndpoint =
{ {
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint}, .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
.EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_IN | KEYBOARD_EPNUM), .EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_IN | KEYBOARD_EPNUM),
.Attributes = EP_TYPE_INTERRUPT, .Attributes = EP_TYPE_INTERRUPT,
.EndpointSize = KEYBOARD_EPSIZE, .EndpointSize = KEYBOARD_EPSIZE,
.PollingIntervalMS = 0x04 .PollingIntervalMS = 0x04
}, },
}; };
/** Language descriptor structure. This descriptor, located in FLASH memory, is returned when the host requests /** Language descriptor structure. This descriptor, located in FLASH memory, is returned when the host requests
* the string descriptor with index 0 (the first index). It is actually an array of 16-bit integers, which indicate * the string descriptor with index 0 (the first index). It is actually an array of 16-bit integers, which indicate
* via the language ID table available at USB.org what languages the device supports for its string descriptors. * via the language ID table available at USB.org what languages the device supports for its string descriptors.
*/ */
USB_Descriptor_String_t PROGMEM LanguageString = USB_Descriptor_String_t PROGMEM LanguageString =
{ {
.Header = {.Size = USB_STRING_LEN(1), .Type = DTYPE_String}, .Header = {.Size = USB_STRING_LEN(1), .Type = DTYPE_String},
.UnicodeString = {LANGUAGE_ID_ENG} .UnicodeString = {LANGUAGE_ID_ENG}
}; };
/** Manufacturer descriptor string. This is a Unicode string containing the manufacturer's details in human readable /** Manufacturer descriptor string. This is a Unicode string containing the manufacturer's details in human readable
* form, and is read out upon request by the host when the appropriate string ID is requested, listed in the Device * form, and is read out upon request by the host when the appropriate string ID is requested, listed in the Device
* Descriptor. * Descriptor.
*/ */
USB_Descriptor_String_t PROGMEM ManufacturerString = USB_Descriptor_String_t PROGMEM ManufacturerString =
{ {
.Header = {.Size = USB_STRING_LEN(11), .Type = DTYPE_String}, .Header = {.Size = USB_STRING_LEN(11), .Type = DTYPE_String},
.UnicodeString = L"Dean Camera" .UnicodeString = L"Dean Camera"
}; };
/** Product descriptor string. This is a Unicode string containing the product's details in human readable form, /** Product descriptor string. This is a Unicode string containing the product's details in human readable form,
* and is read out upon request by the host when the appropriate string ID is requested, listed in the Device * and is read out upon request by the host when the appropriate string ID is requested, listed in the Device
* Descriptor. * Descriptor.
*/ */
USB_Descriptor_String_t PROGMEM ProductString = USB_Descriptor_String_t PROGMEM ProductString =
{ {
.Header = {.Size = USB_STRING_LEN(35), .Type = DTYPE_String}, .Header = {.Size = USB_STRING_LEN(35), .Type = DTYPE_String},
.UnicodeString = L"LUFA Mass Storage and Keyboard Demo" .UnicodeString = L"LUFA Mass Storage and Keyboard Demo"
}; };
/** This function is called by the library when in device mode, and must be overridden (see library "USB Descriptors" /** This function is called by the library when in device mode, and must be overridden (see library "USB Descriptors"
* documentation) by the application code so that the address and size of a requested descriptor can be given * documentation) by the application code so that the address and size of a requested descriptor can be given
* to the USB library. When the device receives a Get Descriptor request on the control endpoint, this function * to the USB library. When the device receives a Get Descriptor request on the control endpoint, this function
* is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the * is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the
* USB host. * USB host.
*/ */
uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, void** const DescriptorAddress) uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, void** const DescriptorAddress)
{ {
const uint8_t DescriptorType = (wValue >> 8); const uint8_t DescriptorType = (wValue >> 8);
const uint8_t DescriptorNumber = (wValue & 0xFF); const uint8_t DescriptorNumber = (wValue & 0xFF);
void* Address = NULL; void* Address = NULL;
uint16_t Size = NO_DESCRIPTOR; uint16_t Size = NO_DESCRIPTOR;
switch (DescriptorType) switch (DescriptorType)
{ {
case DTYPE_Device: case DTYPE_Device:
Address = (void*)&DeviceDescriptor; Address = (void*)&DeviceDescriptor;
Size = sizeof(USB_Descriptor_Device_t); Size = sizeof(USB_Descriptor_Device_t);
break; break;
case DTYPE_Configuration: case DTYPE_Configuration:
Address = (void*)&ConfigurationDescriptor; Address = (void*)&ConfigurationDescriptor;
Size = sizeof(USB_Descriptor_Configuration_t); Size = sizeof(USB_Descriptor_Configuration_t);
break; break;
case DTYPE_String: case DTYPE_String:
switch (DescriptorNumber) switch (DescriptorNumber)
{ {
case 0x00: case 0x00:
Address = (void*)&LanguageString; Address = (void*)&LanguageString;
Size = pgm_read_byte(&LanguageString.Header.Size); Size = pgm_read_byte(&LanguageString.Header.Size);
break; break;
case 0x01: case 0x01:
Address = (void*)&ManufacturerString; Address = (void*)&ManufacturerString;
Size = pgm_read_byte(&ManufacturerString.Header.Size); Size = pgm_read_byte(&ManufacturerString.Header.Size);
break; break;
case 0x02: case 0x02:
Address = (void*)&ProductString; Address = (void*)&ProductString;
Size = pgm_read_byte(&ProductString.Header.Size); Size = pgm_read_byte(&ProductString.Header.Size);
break; break;
} }
break; break;
case DTYPE_HID: case DTYPE_HID:
Address = (void*)&ConfigurationDescriptor.HID_KeyboardHID; Address = (void*)&ConfigurationDescriptor.HID_KeyboardHID;
Size = sizeof(USB_HID_Descriptor_t); Size = sizeof(USB_HID_Descriptor_t);
break; break;
case DTYPE_Report: case DTYPE_Report:
Address = (void*)&KeyboardReport; Address = (void*)&KeyboardReport;
Size = sizeof(KeyboardReport); Size = sizeof(KeyboardReport);
break; break;
} }
*DescriptorAddress = Address; *DescriptorAddress = Address;
return Size; return Size;
} }

View file

@ -1,83 +1,83 @@
/* /*
LUFA Library LUFA Library
Copyright (C) Dean Camera, 2010. Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com www.fourwalledcubicle.com
*/ */
/* /*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com) Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Copyright 2010 Matthias Hullin (lufa [at] matthias [dot] hullin [dot] net) Copyright 2010 Matthias Hullin (lufa [at] matthias [dot] hullin [dot] net)
Permission to use, copy, modify, distribute, and sell this Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the advertising or publicity pertaining to distribution of the
software without specific, written prior permission. software without specific, written prior permission.
The author disclaim all warranties with regard to this The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action, in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of arising out of or in connection with the use or performance of
this software. this software.
*/ */
/** \file /** \file
* *
* Header file for Descriptors.c. * Header file for Descriptors.c.
*/ */
#ifndef _DESCRIPTORS_H_ #ifndef _DESCRIPTORS_H_
#define _DESCRIPTORS_H_ #define _DESCRIPTORS_H_
/* Includes: */ /* Includes: */
#include <avr/pgmspace.h> #include <avr/pgmspace.h>
#include <LUFA/Drivers/USB/USB.h> #include <LUFA/Drivers/USB/USB.h>
#include <LUFA/Drivers/USB/Class/MassStorage.h> #include <LUFA/Drivers/USB/Class/MassStorage.h>
#include <LUFA/Drivers/USB/Class/HID.h> #include <LUFA/Drivers/USB/Class/HID.h>
/* Macros: */ /* Macros: */
/** Endpoint number of the Keyboard HID reporting IN endpoint. */ /** Endpoint number of the Keyboard HID reporting IN endpoint. */
#define KEYBOARD_EPNUM 1 #define KEYBOARD_EPNUM 1
/** Size in bytes of the Keyboard HID reporting IN and OUT endpoints. */ /** Size in bytes of the Keyboard HID reporting IN and OUT endpoints. */
#define KEYBOARD_EPSIZE 8 #define KEYBOARD_EPSIZE 8
/** Endpoint number of the Mass Storage device-to-host data IN endpoint. */ /** Endpoint number of the Mass Storage device-to-host data IN endpoint. */
#define MASS_STORAGE_IN_EPNUM 3 #define MASS_STORAGE_IN_EPNUM 3
/** Endpoint number of the Mass Storage host-to-device data OUT endpoint. */ /** Endpoint number of the Mass Storage host-to-device data OUT endpoint. */
#define MASS_STORAGE_OUT_EPNUM 4 #define MASS_STORAGE_OUT_EPNUM 4
/** Size in bytes of the Mass Storage data endpoints. */ /** Size in bytes of the Mass Storage data endpoints. */
#define MASS_STORAGE_IO_EPSIZE 64 #define MASS_STORAGE_IO_EPSIZE 64
/* Type Defines: */ /* Type Defines: */
/** Type define for the device configuration descriptor structure. This must be defined in the /** Type define for the device configuration descriptor structure. This must be defined in the
* application code, as the configuration descriptor contains several sub-descriptors which * application code, as the configuration descriptor contains several sub-descriptors which
* vary between devices, and which describe the device's usage to the host. * vary between devices, and which describe the device's usage to the host.
*/ */
typedef struct typedef struct
{ {
USB_Descriptor_Configuration_Header_t Config; USB_Descriptor_Configuration_Header_t Config;
USB_Descriptor_Interface_t MS_Interface; USB_Descriptor_Interface_t MS_Interface;
USB_Descriptor_Endpoint_t MS_DataInEndpoint; USB_Descriptor_Endpoint_t MS_DataInEndpoint;
USB_Descriptor_Endpoint_t MS_DataOutEndpoint; USB_Descriptor_Endpoint_t MS_DataOutEndpoint;
USB_Descriptor_Interface_t HID_KeyboardInterface; USB_Descriptor_Interface_t HID_KeyboardInterface;
USB_HID_Descriptor_t HID_KeyboardHID; USB_HID_Descriptor_t HID_KeyboardHID;
USB_Descriptor_Endpoint_t HID_ReportINEndpoint; USB_Descriptor_Endpoint_t HID_ReportINEndpoint;
} USB_Descriptor_Configuration_t; } USB_Descriptor_Configuration_t;
/* Function Prototypes: */ /* Function Prototypes: */
uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, void** const DescriptorAddress) uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, void** const DescriptorAddress)
ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3); ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3);
#endif #endif

File diff suppressed because it is too large Load diff

View file

@ -1,492 +1,492 @@
/* /*
LUFA Library LUFA Library
Copyright (C) Dean Camera, 2010. Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com www.fourwalledcubicle.com
*/ */
/* /*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com) Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the advertising or publicity pertaining to distribution of the
software without specific, written prior permission. software without specific, written prior permission.
The author disclaim all warranties with regard to this The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action, in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of arising out of or in connection with the use or performance of
this software. this software.
*/ */
/** \file /** \file
* *
* Functions to manage the physical dataflash media, including reading and writing of * Functions to manage the physical dataflash media, including reading and writing of
* blocks of data. These functions are called by the SCSI layer when data must be stored * blocks of data. These functions are called by the SCSI layer when data must be stored
* or retrieved to/from the physical storage media. If a different media is used (such * or retrieved to/from the physical storage media. If a different media is used (such
* as a SD card or EEPROM), functions similar to these will need to be generated. * as a SD card or EEPROM), functions similar to these will need to be generated.
*/ */
#define INCLUDE_FROM_DATAFLASHMANAGER_C #define INCLUDE_FROM_DATAFLASHMANAGER_C
#include "DataflashManager.h" #include "DataflashManager.h"
/** Writes blocks (OS blocks, not Dataflash pages) to the storage medium, the board dataflash IC(s), from /** Writes blocks (OS blocks, not Dataflash pages) to the storage medium, the board dataflash IC(s), from
* the pre-selected data OUT endpoint. This routine reads in OS sized blocks from the endpoint and writes * the pre-selected data OUT endpoint. This routine reads in OS sized blocks from the endpoint and writes
* them to the dataflash in Dataflash page sized blocks. * them to the dataflash in Dataflash page sized blocks.
* *
* \param[in] MSInterfaceInfo Pointer to a structure containing a Mass Storage Class configuration and state * \param[in] MSInterfaceInfo Pointer to a structure containing a Mass Storage Class configuration and state
* \param[in] BlockAddress Data block starting address for the write sequence * \param[in] BlockAddress Data block starting address for the write sequence
* \param[in] TotalBlocks Number of blocks of data to write * \param[in] TotalBlocks Number of blocks of data to write
*/ */
void DataflashManager_WriteBlocks(USB_ClassInfo_MS_Device_t* MSInterfaceInfo, const uint32_t BlockAddress, uint16_t TotalBlocks) void DataflashManager_WriteBlocks(USB_ClassInfo_MS_Device_t* MSInterfaceInfo, const uint32_t BlockAddress, uint16_t TotalBlocks)
{ {
uint16_t CurrDFPage = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) / DATAFLASH_PAGE_SIZE); uint16_t CurrDFPage = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) / DATAFLASH_PAGE_SIZE);
uint16_t CurrDFPageByte = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) % DATAFLASH_PAGE_SIZE); uint16_t CurrDFPageByte = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) % DATAFLASH_PAGE_SIZE);
uint8_t CurrDFPageByteDiv16 = (CurrDFPageByte >> 4); uint8_t CurrDFPageByteDiv16 = (CurrDFPageByte >> 4);
bool UsingSecondBuffer = false; bool UsingSecondBuffer = false;
/* Select the correct starting Dataflash IC for the block requested */ /* Select the correct starting Dataflash IC for the block requested */
Dataflash_SelectChipFromPage(CurrDFPage); Dataflash_SelectChipFromPage(CurrDFPage);
#if (DATAFLASH_PAGE_SIZE > VIRTUAL_MEMORY_BLOCK_SIZE) #if (DATAFLASH_PAGE_SIZE > VIRTUAL_MEMORY_BLOCK_SIZE)
/* Copy selected dataflash's current page contents to the dataflash buffer */ /* Copy selected dataflash's current page contents to the dataflash buffer */
Dataflash_SendByte(DF_CMD_MAINMEMTOBUFF1); Dataflash_SendByte(DF_CMD_MAINMEMTOBUFF1);
Dataflash_SendAddressBytes(CurrDFPage, 0); Dataflash_SendAddressBytes(CurrDFPage, 0);
Dataflash_WaitWhileBusy(); Dataflash_WaitWhileBusy();
#endif #endif
/* Send the dataflash buffer write command */ /* Send the dataflash buffer write command */
Dataflash_SendByte(DF_CMD_BUFF1WRITE); Dataflash_SendByte(DF_CMD_BUFF1WRITE);
Dataflash_SendAddressBytes(0, CurrDFPageByte); Dataflash_SendAddressBytes(0, CurrDFPageByte);
/* Wait until endpoint is ready before continuing */ /* Wait until endpoint is ready before continuing */
if (Endpoint_WaitUntilReady()) if (Endpoint_WaitUntilReady())
return; return;
while (TotalBlocks) while (TotalBlocks)
{ {
uint8_t BytesInBlockDiv16 = 0; uint8_t BytesInBlockDiv16 = 0;
/* Write an endpoint packet sized data block to the dataflash */ /* Write an endpoint packet sized data block to the dataflash */
while (BytesInBlockDiv16 < (VIRTUAL_MEMORY_BLOCK_SIZE >> 4)) while (BytesInBlockDiv16 < (VIRTUAL_MEMORY_BLOCK_SIZE >> 4))
{ {
/* Check if the endpoint is currently empty */ /* Check if the endpoint is currently empty */
if (!(Endpoint_IsReadWriteAllowed())) if (!(Endpoint_IsReadWriteAllowed()))
{ {
/* Clear the current endpoint bank */ /* Clear the current endpoint bank */
Endpoint_ClearOUT(); Endpoint_ClearOUT();
/* Wait until the host has sent another packet */ /* Wait until the host has sent another packet */
if (Endpoint_WaitUntilReady()) if (Endpoint_WaitUntilReady())
return; return;
} }
/* Check if end of dataflash page reached */ /* Check if end of dataflash page reached */
if (CurrDFPageByteDiv16 == (DATAFLASH_PAGE_SIZE >> 4)) if (CurrDFPageByteDiv16 == (DATAFLASH_PAGE_SIZE >> 4))
{ {
/* Write the dataflash buffer contents back to the dataflash page */ /* Write the dataflash buffer contents back to the dataflash page */
Dataflash_WaitWhileBusy(); Dataflash_WaitWhileBusy();
Dataflash_SendByte(UsingSecondBuffer ? DF_CMD_BUFF2TOMAINMEMWITHERASE : DF_CMD_BUFF1TOMAINMEMWITHERASE); Dataflash_SendByte(UsingSecondBuffer ? DF_CMD_BUFF2TOMAINMEMWITHERASE : DF_CMD_BUFF1TOMAINMEMWITHERASE);
Dataflash_SendAddressBytes(CurrDFPage, 0); Dataflash_SendAddressBytes(CurrDFPage, 0);
/* Reset the dataflash buffer counter, increment the page counter */ /* Reset the dataflash buffer counter, increment the page counter */
CurrDFPageByteDiv16 = 0; CurrDFPageByteDiv16 = 0;
CurrDFPage++; CurrDFPage++;
/* Once all the dataflash ICs have had their first buffers filled, switch buffers to maintain throughput */ /* Once all the dataflash ICs have had their first buffers filled, switch buffers to maintain throughput */
if (Dataflash_GetSelectedChip() == DATAFLASH_CHIP_MASK(DATAFLASH_TOTALCHIPS)) if (Dataflash_GetSelectedChip() == DATAFLASH_CHIP_MASK(DATAFLASH_TOTALCHIPS))
UsingSecondBuffer = !(UsingSecondBuffer); UsingSecondBuffer = !(UsingSecondBuffer);
/* Select the next dataflash chip based on the new dataflash page index */ /* Select the next dataflash chip based on the new dataflash page index */
Dataflash_SelectChipFromPage(CurrDFPage); Dataflash_SelectChipFromPage(CurrDFPage);
#if (DATAFLASH_PAGE_SIZE > VIRTUAL_MEMORY_BLOCK_SIZE) #if (DATAFLASH_PAGE_SIZE > VIRTUAL_MEMORY_BLOCK_SIZE)
/* If less than one dataflash page remaining, copy over the existing page to preserve trailing data */ /* If less than one dataflash page remaining, copy over the existing page to preserve trailing data */
if ((TotalBlocks * (VIRTUAL_MEMORY_BLOCK_SIZE >> 4)) < (DATAFLASH_PAGE_SIZE >> 4)) if ((TotalBlocks * (VIRTUAL_MEMORY_BLOCK_SIZE >> 4)) < (DATAFLASH_PAGE_SIZE >> 4))
{ {
/* Copy selected dataflash's current page contents to the dataflash buffer */ /* Copy selected dataflash's current page contents to the dataflash buffer */
Dataflash_WaitWhileBusy(); Dataflash_WaitWhileBusy();
Dataflash_SendByte(UsingSecondBuffer ? DF_CMD_MAINMEMTOBUFF2 : DF_CMD_MAINMEMTOBUFF1); Dataflash_SendByte(UsingSecondBuffer ? DF_CMD_MAINMEMTOBUFF2 : DF_CMD_MAINMEMTOBUFF1);
Dataflash_SendAddressBytes(CurrDFPage, 0); Dataflash_SendAddressBytes(CurrDFPage, 0);
Dataflash_WaitWhileBusy(); Dataflash_WaitWhileBusy();
} }
#endif #endif
/* Send the dataflash buffer write command */ /* Send the dataflash buffer write command */
Dataflash_SendByte(UsingSecondBuffer ? DF_CMD_BUFF2WRITE : DF_CMD_BUFF1WRITE); Dataflash_SendByte(UsingSecondBuffer ? DF_CMD_BUFF2WRITE : DF_CMD_BUFF1WRITE);
Dataflash_SendAddressBytes(0, 0); Dataflash_SendAddressBytes(0, 0);
} }
/* Write one 16-byte chunk of data to the dataflash */ /* Write one 16-byte chunk of data to the dataflash */
Dataflash_SendByte(Endpoint_Read_Byte()); Dataflash_SendByte(Endpoint_Read_Byte());
Dataflash_SendByte(Endpoint_Read_Byte()); Dataflash_SendByte(Endpoint_Read_Byte());
Dataflash_SendByte(Endpoint_Read_Byte()); Dataflash_SendByte(Endpoint_Read_Byte());
Dataflash_SendByte(Endpoint_Read_Byte()); Dataflash_SendByte(Endpoint_Read_Byte());
Dataflash_SendByte(Endpoint_Read_Byte()); Dataflash_SendByte(Endpoint_Read_Byte());
Dataflash_SendByte(Endpoint_Read_Byte()); Dataflash_SendByte(Endpoint_Read_Byte());
Dataflash_SendByte(Endpoint_Read_Byte()); Dataflash_SendByte(Endpoint_Read_Byte());
Dataflash_SendByte(Endpoint_Read_Byte()); Dataflash_SendByte(Endpoint_Read_Byte());
Dataflash_SendByte(Endpoint_Read_Byte()); Dataflash_SendByte(Endpoint_Read_Byte());
Dataflash_SendByte(Endpoint_Read_Byte()); Dataflash_SendByte(Endpoint_Read_Byte());
Dataflash_SendByte(Endpoint_Read_Byte()); Dataflash_SendByte(Endpoint_Read_Byte());
Dataflash_SendByte(Endpoint_Read_Byte()); Dataflash_SendByte(Endpoint_Read_Byte());
Dataflash_SendByte(Endpoint_Read_Byte()); Dataflash_SendByte(Endpoint_Read_Byte());
Dataflash_SendByte(Endpoint_Read_Byte()); Dataflash_SendByte(Endpoint_Read_Byte());
Dataflash_SendByte(Endpoint_Read_Byte()); Dataflash_SendByte(Endpoint_Read_Byte());
Dataflash_SendByte(Endpoint_Read_Byte()); Dataflash_SendByte(Endpoint_Read_Byte());
/* Increment the dataflash page 16 byte block counter */ /* Increment the dataflash page 16 byte block counter */
CurrDFPageByteDiv16++; CurrDFPageByteDiv16++;
/* Increment the block 16 byte block counter */ /* Increment the block 16 byte block counter */
BytesInBlockDiv16++; BytesInBlockDiv16++;
/* Check if the current command is being aborted by the host */ /* Check if the current command is being aborted by the host */
if (MSInterfaceInfo->State.IsMassStoreReset) if (MSInterfaceInfo->State.IsMassStoreReset)
return; return;
} }
/* Decrement the blocks remaining counter and reset the sub block counter */ /* Decrement the blocks remaining counter and reset the sub block counter */
TotalBlocks--; TotalBlocks--;
} }
/* Write the dataflash buffer contents back to the dataflash page */ /* Write the dataflash buffer contents back to the dataflash page */
Dataflash_WaitWhileBusy(); Dataflash_WaitWhileBusy();
Dataflash_SendByte(UsingSecondBuffer ? DF_CMD_BUFF2TOMAINMEMWITHERASE : DF_CMD_BUFF1TOMAINMEMWITHERASE); Dataflash_SendByte(UsingSecondBuffer ? DF_CMD_BUFF2TOMAINMEMWITHERASE : DF_CMD_BUFF1TOMAINMEMWITHERASE);
Dataflash_SendAddressBytes(CurrDFPage, 0x00); Dataflash_SendAddressBytes(CurrDFPage, 0x00);
Dataflash_WaitWhileBusy(); Dataflash_WaitWhileBusy();
/* If the endpoint is empty, clear it ready for the next packet from the host */ /* If the endpoint is empty, clear it ready for the next packet from the host */
if (!(Endpoint_IsReadWriteAllowed())) if (!(Endpoint_IsReadWriteAllowed()))
Endpoint_ClearOUT(); Endpoint_ClearOUT();
/* Deselect all dataflash chips */ /* Deselect all dataflash chips */
Dataflash_DeselectChip(); Dataflash_DeselectChip();
} }
/** Reads blocks (OS blocks, not Dataflash pages) from the storage medium, the board dataflash IC(s), into /** Reads blocks (OS blocks, not Dataflash pages) from the storage medium, the board dataflash IC(s), into
* the pre-selected data IN endpoint. This routine reads in Dataflash page sized blocks from the Dataflash * the pre-selected data IN endpoint. This routine reads in Dataflash page sized blocks from the Dataflash
* and writes them in OS sized blocks to the endpoint. * and writes them in OS sized blocks to the endpoint.
* *
* \param[in] MSInterfaceInfo Pointer to a structure containing a Mass Storage Class configuration and state * \param[in] MSInterfaceInfo Pointer to a structure containing a Mass Storage Class configuration and state
* \param[in] BlockAddress Data block starting address for the read sequence * \param[in] BlockAddress Data block starting address for the read sequence
* \param[in] TotalBlocks Number of blocks of data to read * \param[in] TotalBlocks Number of blocks of data to read
*/ */
void DataflashManager_ReadBlocks(USB_ClassInfo_MS_Device_t* MSInterfaceInfo, const uint32_t BlockAddress, uint16_t TotalBlocks) void DataflashManager_ReadBlocks(USB_ClassInfo_MS_Device_t* MSInterfaceInfo, const uint32_t BlockAddress, uint16_t TotalBlocks)
{ {
uint16_t CurrDFPage = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) / DATAFLASH_PAGE_SIZE); uint16_t CurrDFPage = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) / DATAFLASH_PAGE_SIZE);
uint16_t CurrDFPageByte = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) % DATAFLASH_PAGE_SIZE); uint16_t CurrDFPageByte = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) % DATAFLASH_PAGE_SIZE);
uint8_t CurrDFPageByteDiv16 = (CurrDFPageByte >> 4); uint8_t CurrDFPageByteDiv16 = (CurrDFPageByte >> 4);
/* Select the correct starting Dataflash IC for the block requested */ /* Select the correct starting Dataflash IC for the block requested */
Dataflash_SelectChipFromPage(CurrDFPage); Dataflash_SelectChipFromPage(CurrDFPage);
/* Send the dataflash main memory page read command */ /* Send the dataflash main memory page read command */
Dataflash_SendByte(DF_CMD_MAINMEMPAGEREAD); Dataflash_SendByte(DF_CMD_MAINMEMPAGEREAD);
Dataflash_SendAddressBytes(CurrDFPage, CurrDFPageByte); Dataflash_SendAddressBytes(CurrDFPage, CurrDFPageByte);
Dataflash_SendByte(0x00); Dataflash_SendByte(0x00);
Dataflash_SendByte(0x00); Dataflash_SendByte(0x00);
Dataflash_SendByte(0x00); Dataflash_SendByte(0x00);
Dataflash_SendByte(0x00); Dataflash_SendByte(0x00);
/* Wait until endpoint is ready before continuing */ /* Wait until endpoint is ready before continuing */
if (Endpoint_WaitUntilReady()) if (Endpoint_WaitUntilReady())
return; return;
while (TotalBlocks) while (TotalBlocks)
{ {
uint8_t BytesInBlockDiv16 = 0; uint8_t BytesInBlockDiv16 = 0;
/* Write an endpoint packet sized data block to the dataflash */ /* Write an endpoint packet sized data block to the dataflash */
while (BytesInBlockDiv16 < (VIRTUAL_MEMORY_BLOCK_SIZE >> 4)) while (BytesInBlockDiv16 < (VIRTUAL_MEMORY_BLOCK_SIZE >> 4))
{ {
/* Check if the endpoint is currently full */ /* Check if the endpoint is currently full */
if (!(Endpoint_IsReadWriteAllowed())) if (!(Endpoint_IsReadWriteAllowed()))
{ {
/* Clear the endpoint bank to send its contents to the host */ /* Clear the endpoint bank to send its contents to the host */
Endpoint_ClearIN(); Endpoint_ClearIN();
/* Wait until the endpoint is ready for more data */ /* Wait until the endpoint is ready for more data */
if (Endpoint_WaitUntilReady()) if (Endpoint_WaitUntilReady())
return; return;
} }
/* Check if end of dataflash page reached */ /* Check if end of dataflash page reached */
if (CurrDFPageByteDiv16 == (DATAFLASH_PAGE_SIZE >> 4)) if (CurrDFPageByteDiv16 == (DATAFLASH_PAGE_SIZE >> 4))
{ {
/* Reset the dataflash buffer counter, increment the page counter */ /* Reset the dataflash buffer counter, increment the page counter */
CurrDFPageByteDiv16 = 0; CurrDFPageByteDiv16 = 0;
CurrDFPage++; CurrDFPage++;
/* Select the next dataflash chip based on the new dataflash page index */ /* Select the next dataflash chip based on the new dataflash page index */
Dataflash_SelectChipFromPage(CurrDFPage); Dataflash_SelectChipFromPage(CurrDFPage);
/* Send the dataflash main memory page read command */ /* Send the dataflash main memory page read command */
Dataflash_SendByte(DF_CMD_MAINMEMPAGEREAD); Dataflash_SendByte(DF_CMD_MAINMEMPAGEREAD);
Dataflash_SendAddressBytes(CurrDFPage, 0); Dataflash_SendAddressBytes(CurrDFPage, 0);
Dataflash_SendByte(0x00); Dataflash_SendByte(0x00);
Dataflash_SendByte(0x00); Dataflash_SendByte(0x00);
Dataflash_SendByte(0x00); Dataflash_SendByte(0x00);
Dataflash_SendByte(0x00); Dataflash_SendByte(0x00);
} }
/* Read one 16-byte chunk of data from the dataflash */ /* Read one 16-byte chunk of data from the dataflash */
Endpoint_Write_Byte(Dataflash_ReceiveByte()); Endpoint_Write_Byte(Dataflash_ReceiveByte());
Endpoint_Write_Byte(Dataflash_ReceiveByte()); Endpoint_Write_Byte(Dataflash_ReceiveByte());
Endpoint_Write_Byte(Dataflash_ReceiveByte()); Endpoint_Write_Byte(Dataflash_ReceiveByte());
Endpoint_Write_Byte(Dataflash_ReceiveByte()); Endpoint_Write_Byte(Dataflash_ReceiveByte());
Endpoint_Write_Byte(Dataflash_ReceiveByte()); Endpoint_Write_Byte(Dataflash_ReceiveByte());
Endpoint_Write_Byte(Dataflash_ReceiveByte()); Endpoint_Write_Byte(Dataflash_ReceiveByte());
Endpoint_Write_Byte(Dataflash_ReceiveByte()); Endpoint_Write_Byte(Dataflash_ReceiveByte());
Endpoint_Write_Byte(Dataflash_ReceiveByte()); Endpoint_Write_Byte(Dataflash_ReceiveByte());
Endpoint_Write_Byte(Dataflash_ReceiveByte()); Endpoint_Write_Byte(Dataflash_ReceiveByte());
Endpoint_Write_Byte(Dataflash_ReceiveByte()); Endpoint_Write_Byte(Dataflash_ReceiveByte());
Endpoint_Write_Byte(Dataflash_ReceiveByte()); Endpoint_Write_Byte(Dataflash_ReceiveByte());
Endpoint_Write_Byte(Dataflash_ReceiveByte()); Endpoint_Write_Byte(Dataflash_ReceiveByte());
Endpoint_Write_Byte(Dataflash_ReceiveByte()); Endpoint_Write_Byte(Dataflash_ReceiveByte());
Endpoint_Write_Byte(Dataflash_ReceiveByte()); Endpoint_Write_Byte(Dataflash_ReceiveByte());
Endpoint_Write_Byte(Dataflash_ReceiveByte()); Endpoint_Write_Byte(Dataflash_ReceiveByte());
Endpoint_Write_Byte(Dataflash_ReceiveByte()); Endpoint_Write_Byte(Dataflash_ReceiveByte());
/* Increment the dataflash page 16 byte block counter */ /* Increment the dataflash page 16 byte block counter */
CurrDFPageByteDiv16++; CurrDFPageByteDiv16++;
/* Increment the block 16 byte block counter */ /* Increment the block 16 byte block counter */
BytesInBlockDiv16++; BytesInBlockDiv16++;
/* Check if the current command is being aborted by the host */ /* Check if the current command is being aborted by the host */
if (MSInterfaceInfo->State.IsMassStoreReset) if (MSInterfaceInfo->State.IsMassStoreReset)
return; return;
} }
/* Decrement the blocks remaining counter */ /* Decrement the blocks remaining counter */
TotalBlocks--; TotalBlocks--;
} }
/* If the endpoint is full, send its contents to the host */ /* If the endpoint is full, send its contents to the host */
if (!(Endpoint_IsReadWriteAllowed())) if (!(Endpoint_IsReadWriteAllowed()))
Endpoint_ClearIN(); Endpoint_ClearIN();
/* Deselect all dataflash chips */ /* Deselect all dataflash chips */
Dataflash_DeselectChip(); Dataflash_DeselectChip();
} }
/** Writes blocks (OS blocks, not Dataflash pages) to the storage medium, the board dataflash IC(s), from /** Writes blocks (OS blocks, not Dataflash pages) to the storage medium, the board dataflash IC(s), from
* the a given RAM buffer. This routine reads in OS sized blocks from the buffer and writes them to the * the a given RAM buffer. This routine reads in OS sized blocks from the buffer and writes them to the
* dataflash in Dataflash page sized blocks. This can be linked to FAT libraries to write files to the * dataflash in Dataflash page sized blocks. This can be linked to FAT libraries to write files to the
* dataflash. * dataflash.
* *
* \param[in] BlockAddress Data block starting address for the write sequence * \param[in] BlockAddress Data block starting address for the write sequence
* \param[in] TotalBlocks Number of blocks of data to write * \param[in] TotalBlocks Number of blocks of data to write
* \param[in] BufferPtr Pointer to the data source RAM buffer * \param[in] BufferPtr Pointer to the data source RAM buffer
*/ */
void DataflashManager_WriteBlocks_RAM(const uint32_t BlockAddress, uint16_t TotalBlocks, uint8_t* BufferPtr) void DataflashManager_WriteBlocks_RAM(const uint32_t BlockAddress, uint16_t TotalBlocks, uint8_t* BufferPtr)
{ {
uint16_t CurrDFPage = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) / DATAFLASH_PAGE_SIZE); uint16_t CurrDFPage = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) / DATAFLASH_PAGE_SIZE);
uint16_t CurrDFPageByte = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) % DATAFLASH_PAGE_SIZE); uint16_t CurrDFPageByte = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) % DATAFLASH_PAGE_SIZE);
uint8_t CurrDFPageByteDiv16 = (CurrDFPageByte >> 4); uint8_t CurrDFPageByteDiv16 = (CurrDFPageByte >> 4);
bool UsingSecondBuffer = false; bool UsingSecondBuffer = false;
/* Select the correct starting Dataflash IC for the block requested */ /* Select the correct starting Dataflash IC for the block requested */
Dataflash_SelectChipFromPage(CurrDFPage); Dataflash_SelectChipFromPage(CurrDFPage);
#if (DATAFLASH_PAGE_SIZE > VIRTUAL_MEMORY_BLOCK_SIZE) #if (DATAFLASH_PAGE_SIZE > VIRTUAL_MEMORY_BLOCK_SIZE)
/* Copy selected dataflash's current page contents to the dataflash buffer */ /* Copy selected dataflash's current page contents to the dataflash buffer */
Dataflash_SendByte(DF_CMD_MAINMEMTOBUFF1); Dataflash_SendByte(DF_CMD_MAINMEMTOBUFF1);
Dataflash_SendAddressBytes(CurrDFPage, 0); Dataflash_SendAddressBytes(CurrDFPage, 0);
Dataflash_WaitWhileBusy(); Dataflash_WaitWhileBusy();
#endif #endif
/* Send the dataflash buffer write command */ /* Send the dataflash buffer write command */
Dataflash_SendByte(DF_CMD_BUFF1WRITE); Dataflash_SendByte(DF_CMD_BUFF1WRITE);
Dataflash_SendAddressBytes(0, CurrDFPageByte); Dataflash_SendAddressBytes(0, CurrDFPageByte);
while (TotalBlocks) while (TotalBlocks)
{ {
uint8_t BytesInBlockDiv16 = 0; uint8_t BytesInBlockDiv16 = 0;
/* Write an endpoint packet sized data block to the dataflash */ /* Write an endpoint packet sized data block to the dataflash */
while (BytesInBlockDiv16 < (VIRTUAL_MEMORY_BLOCK_SIZE >> 4)) while (BytesInBlockDiv16 < (VIRTUAL_MEMORY_BLOCK_SIZE >> 4))
{ {
/* Check if end of dataflash page reached */ /* Check if end of dataflash page reached */
if (CurrDFPageByteDiv16 == (DATAFLASH_PAGE_SIZE >> 4)) if (CurrDFPageByteDiv16 == (DATAFLASH_PAGE_SIZE >> 4))
{ {
/* Write the dataflash buffer contents back to the dataflash page */ /* Write the dataflash buffer contents back to the dataflash page */
Dataflash_WaitWhileBusy(); Dataflash_WaitWhileBusy();
Dataflash_SendByte(UsingSecondBuffer ? DF_CMD_BUFF2TOMAINMEMWITHERASE : DF_CMD_BUFF1TOMAINMEMWITHERASE); Dataflash_SendByte(UsingSecondBuffer ? DF_CMD_BUFF2TOMAINMEMWITHERASE : DF_CMD_BUFF1TOMAINMEMWITHERASE);
Dataflash_SendAddressBytes(CurrDFPage, 0); Dataflash_SendAddressBytes(CurrDFPage, 0);
/* Reset the dataflash buffer counter, increment the page counter */ /* Reset the dataflash buffer counter, increment the page counter */
CurrDFPageByteDiv16 = 0; CurrDFPageByteDiv16 = 0;
CurrDFPage++; CurrDFPage++;
/* Once all the dataflash ICs have had their first buffers filled, switch buffers to maintain throughput */ /* Once all the dataflash ICs have had their first buffers filled, switch buffers to maintain throughput */
if (Dataflash_GetSelectedChip() == DATAFLASH_CHIP_MASK(DATAFLASH_TOTALCHIPS)) if (Dataflash_GetSelectedChip() == DATAFLASH_CHIP_MASK(DATAFLASH_TOTALCHIPS))
UsingSecondBuffer = !(UsingSecondBuffer); UsingSecondBuffer = !(UsingSecondBuffer);
/* Select the next dataflash chip based on the new dataflash page index */ /* Select the next dataflash chip based on the new dataflash page index */
Dataflash_SelectChipFromPage(CurrDFPage); Dataflash_SelectChipFromPage(CurrDFPage);
#if (DATAFLASH_PAGE_SIZE > VIRTUAL_MEMORY_BLOCK_SIZE) #if (DATAFLASH_PAGE_SIZE > VIRTUAL_MEMORY_BLOCK_SIZE)
/* If less than one dataflash page remaining, copy over the existing page to preserve trailing data */ /* If less than one dataflash page remaining, copy over the existing page to preserve trailing data */
if ((TotalBlocks * (VIRTUAL_MEMORY_BLOCK_SIZE >> 4)) < (DATAFLASH_PAGE_SIZE >> 4)) if ((TotalBlocks * (VIRTUAL_MEMORY_BLOCK_SIZE >> 4)) < (DATAFLASH_PAGE_SIZE >> 4))
{ {
/* Copy selected dataflash's current page contents to the dataflash buffer */ /* Copy selected dataflash's current page contents to the dataflash buffer */
Dataflash_WaitWhileBusy(); Dataflash_WaitWhileBusy();
Dataflash_SendByte(UsingSecondBuffer ? DF_CMD_MAINMEMTOBUFF2 : DF_CMD_MAINMEMTOBUFF1); Dataflash_SendByte(UsingSecondBuffer ? DF_CMD_MAINMEMTOBUFF2 : DF_CMD_MAINMEMTOBUFF1);
Dataflash_SendAddressBytes(CurrDFPage, 0); Dataflash_SendAddressBytes(CurrDFPage, 0);
Dataflash_WaitWhileBusy(); Dataflash_WaitWhileBusy();
} }
#endif #endif
/* Send the dataflash buffer write command */ /* Send the dataflash buffer write command */
Dataflash_ToggleSelectedChipCS(); Dataflash_ToggleSelectedChipCS();
Dataflash_SendByte(DF_CMD_BUFF1WRITE); Dataflash_SendByte(DF_CMD_BUFF1WRITE);
Dataflash_SendAddressBytes(0, 0); Dataflash_SendAddressBytes(0, 0);
} }
/* Write one 16-byte chunk of data to the dataflash */ /* Write one 16-byte chunk of data to the dataflash */
for (uint8_t ByteNum = 0; ByteNum < 16; ByteNum++) for (uint8_t ByteNum = 0; ByteNum < 16; ByteNum++)
Dataflash_SendByte(*(BufferPtr++)); Dataflash_SendByte(*(BufferPtr++));
/* Increment the dataflash page 16 byte block counter */ /* Increment the dataflash page 16 byte block counter */
CurrDFPageByteDiv16++; CurrDFPageByteDiv16++;
/* Increment the block 16 byte block counter */ /* Increment the block 16 byte block counter */
BytesInBlockDiv16++; BytesInBlockDiv16++;
} }
/* Decrement the blocks remaining counter and reset the sub block counter */ /* Decrement the blocks remaining counter and reset the sub block counter */
TotalBlocks--; TotalBlocks--;
} }
/* Write the dataflash buffer contents back to the dataflash page */ /* Write the dataflash buffer contents back to the dataflash page */
Dataflash_WaitWhileBusy(); Dataflash_WaitWhileBusy();
Dataflash_SendByte(UsingSecondBuffer ? DF_CMD_BUFF2TOMAINMEMWITHERASE : DF_CMD_BUFF1TOMAINMEMWITHERASE); Dataflash_SendByte(UsingSecondBuffer ? DF_CMD_BUFF2TOMAINMEMWITHERASE : DF_CMD_BUFF1TOMAINMEMWITHERASE);
Dataflash_SendAddressBytes(CurrDFPage, 0x00); Dataflash_SendAddressBytes(CurrDFPage, 0x00);
Dataflash_WaitWhileBusy(); Dataflash_WaitWhileBusy();
/* Deselect all dataflash chips */ /* Deselect all dataflash chips */
Dataflash_DeselectChip(); Dataflash_DeselectChip();
} }
/** Reads blocks (OS blocks, not Dataflash pages) from the storage medium, the board dataflash IC(s), into /** Reads blocks (OS blocks, not Dataflash pages) from the storage medium, the board dataflash IC(s), into
* the a preallocated RAM buffer. This routine reads in Dataflash page sized blocks from the Dataflash * the a preallocated RAM buffer. This routine reads in Dataflash page sized blocks from the Dataflash
* and writes them in OS sized blocks to the given buffer. This can be linked to FAT libraries to read * and writes them in OS sized blocks to the given buffer. This can be linked to FAT libraries to read
* the files stored on the dataflash. * the files stored on the dataflash.
* *
* \param[in] BlockAddress Data block starting address for the read sequence * \param[in] BlockAddress Data block starting address for the read sequence
* \param[in] TotalBlocks Number of blocks of data to read * \param[in] TotalBlocks Number of blocks of data to read
* \param[out] BufferPtr Pointer to the data destination RAM buffer * \param[out] BufferPtr Pointer to the data destination RAM buffer
*/ */
void DataflashManager_ReadBlocks_RAM(const uint32_t BlockAddress, uint16_t TotalBlocks, uint8_t* BufferPtr) void DataflashManager_ReadBlocks_RAM(const uint32_t BlockAddress, uint16_t TotalBlocks, uint8_t* BufferPtr)
{ {
uint16_t CurrDFPage = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) / DATAFLASH_PAGE_SIZE); uint16_t CurrDFPage = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) / DATAFLASH_PAGE_SIZE);
uint16_t CurrDFPageByte = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) % DATAFLASH_PAGE_SIZE); uint16_t CurrDFPageByte = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) % DATAFLASH_PAGE_SIZE);
uint8_t CurrDFPageByteDiv16 = (CurrDFPageByte >> 4); uint8_t CurrDFPageByteDiv16 = (CurrDFPageByte >> 4);
/* Select the correct starting Dataflash IC for the block requested */ /* Select the correct starting Dataflash IC for the block requested */
Dataflash_SelectChipFromPage(CurrDFPage); Dataflash_SelectChipFromPage(CurrDFPage);
/* Send the dataflash main memory page read command */ /* Send the dataflash main memory page read command */
Dataflash_SendByte(DF_CMD_MAINMEMPAGEREAD); Dataflash_SendByte(DF_CMD_MAINMEMPAGEREAD);
Dataflash_SendAddressBytes(CurrDFPage, CurrDFPageByte); Dataflash_SendAddressBytes(CurrDFPage, CurrDFPageByte);
Dataflash_SendByte(0x00); Dataflash_SendByte(0x00);
Dataflash_SendByte(0x00); Dataflash_SendByte(0x00);
Dataflash_SendByte(0x00); Dataflash_SendByte(0x00);
Dataflash_SendByte(0x00); Dataflash_SendByte(0x00);
while (TotalBlocks) while (TotalBlocks)
{ {
uint8_t BytesInBlockDiv16 = 0; uint8_t BytesInBlockDiv16 = 0;
/* Write an endpoint packet sized data block to the dataflash */ /* Write an endpoint packet sized data block to the dataflash */
while (BytesInBlockDiv16 < (VIRTUAL_MEMORY_BLOCK_SIZE >> 4)) while (BytesInBlockDiv16 < (VIRTUAL_MEMORY_BLOCK_SIZE >> 4))
{ {
/* Check if end of dataflash page reached */ /* Check if end of dataflash page reached */
if (CurrDFPageByteDiv16 == (DATAFLASH_PAGE_SIZE >> 4)) if (CurrDFPageByteDiv16 == (DATAFLASH_PAGE_SIZE >> 4))
{ {
/* Reset the dataflash buffer counter, increment the page counter */ /* Reset the dataflash buffer counter, increment the page counter */
CurrDFPageByteDiv16 = 0; CurrDFPageByteDiv16 = 0;
CurrDFPage++; CurrDFPage++;
/* Select the next dataflash chip based on the new dataflash page index */ /* Select the next dataflash chip based on the new dataflash page index */
Dataflash_SelectChipFromPage(CurrDFPage); Dataflash_SelectChipFromPage(CurrDFPage);
/* Send the dataflash main memory page read command */ /* Send the dataflash main memory page read command */
Dataflash_SendByte(DF_CMD_MAINMEMPAGEREAD); Dataflash_SendByte(DF_CMD_MAINMEMPAGEREAD);
Dataflash_SendAddressBytes(CurrDFPage, 0); Dataflash_SendAddressBytes(CurrDFPage, 0);
Dataflash_SendByte(0x00); Dataflash_SendByte(0x00);
Dataflash_SendByte(0x00); Dataflash_SendByte(0x00);
Dataflash_SendByte(0x00); Dataflash_SendByte(0x00);
Dataflash_SendByte(0x00); Dataflash_SendByte(0x00);
} }
/* Read one 16-byte chunk of data from the dataflash */ /* Read one 16-byte chunk of data from the dataflash */
for (uint8_t ByteNum = 0; ByteNum < 16; ByteNum++) for (uint8_t ByteNum = 0; ByteNum < 16; ByteNum++)
*(BufferPtr++) = Dataflash_ReceiveByte(); *(BufferPtr++) = Dataflash_ReceiveByte();
/* Increment the dataflash page 16 byte block counter */ /* Increment the dataflash page 16 byte block counter */
CurrDFPageByteDiv16++; CurrDFPageByteDiv16++;
/* Increment the block 16 byte block counter */ /* Increment the block 16 byte block counter */
BytesInBlockDiv16++; BytesInBlockDiv16++;
} }
/* Decrement the blocks remaining counter */ /* Decrement the blocks remaining counter */
TotalBlocks--; TotalBlocks--;
} }
/* Deselect all dataflash chips */ /* Deselect all dataflash chips */
Dataflash_DeselectChip(); Dataflash_DeselectChip();
} }
/** Disables the dataflash memory write protection bits on the board Dataflash ICs, if enabled. */ /** Disables the dataflash memory write protection bits on the board Dataflash ICs, if enabled. */
void DataflashManager_ResetDataflashProtections(void) void DataflashManager_ResetDataflashProtections(void)
{ {
/* Select first dataflash chip, send the read status register command */ /* Select first dataflash chip, send the read status register command */
Dataflash_SelectChip(DATAFLASH_CHIP1); Dataflash_SelectChip(DATAFLASH_CHIP1);
Dataflash_SendByte(DF_CMD_GETSTATUS); Dataflash_SendByte(DF_CMD_GETSTATUS);
/* Check if sector protection is enabled */ /* Check if sector protection is enabled */
if (Dataflash_ReceiveByte() & DF_STATUS_SECTORPROTECTION_ON) if (Dataflash_ReceiveByte() & DF_STATUS_SECTORPROTECTION_ON)
{ {
Dataflash_ToggleSelectedChipCS(); Dataflash_ToggleSelectedChipCS();
/* Send the commands to disable sector protection */ /* Send the commands to disable sector protection */
Dataflash_SendByte(DF_CMD_SECTORPROTECTIONOFF[0]); Dataflash_SendByte(DF_CMD_SECTORPROTECTIONOFF[0]);
Dataflash_SendByte(DF_CMD_SECTORPROTECTIONOFF[1]); Dataflash_SendByte(DF_CMD_SECTORPROTECTIONOFF[1]);
Dataflash_SendByte(DF_CMD_SECTORPROTECTIONOFF[2]); Dataflash_SendByte(DF_CMD_SECTORPROTECTIONOFF[2]);
Dataflash_SendByte(DF_CMD_SECTORPROTECTIONOFF[3]); Dataflash_SendByte(DF_CMD_SECTORPROTECTIONOFF[3]);
} }
/* Select second dataflash chip (if present on selected board), send read status register command */ /* Select second dataflash chip (if present on selected board), send read status register command */
#if (DATAFLASH_TOTALCHIPS == 2) #if (DATAFLASH_TOTALCHIPS == 2)
Dataflash_SelectChip(DATAFLASH_CHIP2); Dataflash_SelectChip(DATAFLASH_CHIP2);
Dataflash_SendByte(DF_CMD_GETSTATUS); Dataflash_SendByte(DF_CMD_GETSTATUS);
/* Check if sector protection is enabled */ /* Check if sector protection is enabled */
if (Dataflash_ReceiveByte() & DF_STATUS_SECTORPROTECTION_ON) if (Dataflash_ReceiveByte() & DF_STATUS_SECTORPROTECTION_ON)
{ {
Dataflash_ToggleSelectedChipCS(); Dataflash_ToggleSelectedChipCS();
/* Send the commands to disable sector protection */ /* Send the commands to disable sector protection */
Dataflash_SendByte(DF_CMD_SECTORPROTECTIONOFF[0]); Dataflash_SendByte(DF_CMD_SECTORPROTECTIONOFF[0]);
Dataflash_SendByte(DF_CMD_SECTORPROTECTIONOFF[1]); Dataflash_SendByte(DF_CMD_SECTORPROTECTIONOFF[1]);
Dataflash_SendByte(DF_CMD_SECTORPROTECTIONOFF[2]); Dataflash_SendByte(DF_CMD_SECTORPROTECTIONOFF[2]);
Dataflash_SendByte(DF_CMD_SECTORPROTECTIONOFF[3]); Dataflash_SendByte(DF_CMD_SECTORPROTECTIONOFF[3]);
} }
#endif #endif
/* Deselect current dataflash chip */ /* Deselect current dataflash chip */
Dataflash_DeselectChip(); Dataflash_DeselectChip();
} }

View file

@ -1,77 +1,77 @@
/* /*
LUFA Library LUFA Library
Copyright (C) Dean Camera, 2010. Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com www.fourwalledcubicle.com
*/ */
/* /*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com) Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the advertising or publicity pertaining to distribution of the
software without specific, written prior permission. software without specific, written prior permission.
The author disclaim all warranties with regard to this The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action, in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of arising out of or in connection with the use or performance of
this software. this software.
*/ */
/** \file /** \file
* *
* Header file for DataflashManager.c. * Header file for DataflashManager.c.
*/ */
#ifndef _DATAFLASH_MANAGER_H_ #ifndef _DATAFLASH_MANAGER_H_
#define _DATAFLASH_MANAGER_H_ #define _DATAFLASH_MANAGER_H_
/* Includes: */ /* Includes: */
#include <avr/io.h> #include <avr/io.h>
#include "MassStorageKeyboard.h" #include "MassStorageKeyboard.h"
#include "Descriptors.h" #include "Descriptors.h"
#include <LUFA/Common/Common.h> #include <LUFA/Common/Common.h>
#include <LUFA/Drivers/USB/USB.h> #include <LUFA/Drivers/USB/USB.h>
#include <LUFA/Drivers/Board/Dataflash.h> #include <LUFA/Drivers/Board/Dataflash.h>
/* Preprocessor Checks: */ /* Preprocessor Checks: */
#if (DATAFLASH_PAGE_SIZE % 16) #if (DATAFLASH_PAGE_SIZE % 16)
#error Dataflash page size must be a multiple of 16 bytes. #error Dataflash page size must be a multiple of 16 bytes.
#endif #endif
/* Defines: */ /* Defines: */
/** Total number of bytes of the storage medium, comprised of one or more dataflash ICs. */ /** Total number of bytes of the storage medium, comprised of one or more dataflash ICs. */
#define VIRTUAL_MEMORY_BYTES ((uint32_t)DATAFLASH_PAGES * DATAFLASH_PAGE_SIZE * DATAFLASH_TOTALCHIPS) #define VIRTUAL_MEMORY_BYTES ((uint32_t)DATAFLASH_PAGES * DATAFLASH_PAGE_SIZE * DATAFLASH_TOTALCHIPS)
/** Block size of the device. This is kept at 512 to remain compatible with the OS despite the underlying /** Block size of the device. This is kept at 512 to remain compatible with the OS despite the underlying
* storage media (Dataflash) using a different native block size. * storage media (Dataflash) using a different native block size.
*/ */
#define VIRTUAL_MEMORY_BLOCK_SIZE 512 #define VIRTUAL_MEMORY_BLOCK_SIZE 512
/** Total number of blocks of the virtual memory for reporting to the host as the device's total capacity. */ /** Total number of blocks of the virtual memory for reporting to the host as the device's total capacity. */
#define VIRTUAL_MEMORY_BLOCKS (VIRTUAL_MEMORY_BYTES / VIRTUAL_MEMORY_BLOCK_SIZE) #define VIRTUAL_MEMORY_BLOCKS (VIRTUAL_MEMORY_BYTES / VIRTUAL_MEMORY_BLOCK_SIZE)
/* Function Prototypes: */ /* Function Prototypes: */
void DataflashManager_WriteBlocks(USB_ClassInfo_MS_Device_t* MSInterfaceInfo, const uint32_t BlockAddress, void DataflashManager_WriteBlocks(USB_ClassInfo_MS_Device_t* MSInterfaceInfo, const uint32_t BlockAddress,
uint16_t TotalBlocks); uint16_t TotalBlocks);
void DataflashManager_ReadBlocks(USB_ClassInfo_MS_Device_t* MSInterfaceInfo, const uint32_t BlockAddress, void DataflashManager_ReadBlocks(USB_ClassInfo_MS_Device_t* MSInterfaceInfo, const uint32_t BlockAddress,
uint16_t TotalBlocks); uint16_t TotalBlocks);
void DataflashManager_WriteBlocks_RAM(const uint32_t BlockAddress, uint16_t TotalBlocks, void DataflashManager_WriteBlocks_RAM(const uint32_t BlockAddress, uint16_t TotalBlocks,
uint8_t* BufferPtr) ATTR_NON_NULL_PTR_ARG(3); uint8_t* BufferPtr) ATTR_NON_NULL_PTR_ARG(3);
void DataflashManager_ReadBlocks_RAM(const uint32_t BlockAddress, uint16_t TotalBlocks, void DataflashManager_ReadBlocks_RAM(const uint32_t BlockAddress, uint16_t TotalBlocks,
uint8_t* BufferPtr) ATTR_NON_NULL_PTR_ARG(3); uint8_t* BufferPtr) ATTR_NON_NULL_PTR_ARG(3);
void DataflashManager_ResetDataflashProtections(void); void DataflashManager_ResetDataflashProtections(void);
#endif #endif

View file

@ -1,345 +1,345 @@
/* /*
LUFA Library LUFA Library
Copyright (C) Dean Camera, 2010. Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com www.fourwalledcubicle.com
*/ */
/* /*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com) Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the advertising or publicity pertaining to distribution of the
software without specific, written prior permission. software without specific, written prior permission.
The author disclaim all warranties with regard to this The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action, in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of arising out of or in connection with the use or performance of
this software. this software.
*/ */
/** \file /** \file
* *
* SCSI command processing routines, for SCSI commands issued by the host. Mass Storage * SCSI command processing routines, for SCSI commands issued by the host. Mass Storage
* devices use a thin "Bulk-Only Transport" protocol for issuing commands and status information, * devices use a thin "Bulk-Only Transport" protocol for issuing commands and status information,
* which wrap around standard SCSI device commands for controlling the actual storage medium. * which wrap around standard SCSI device commands for controlling the actual storage medium.
*/ */
#define INCLUDE_FROM_SCSI_C #define INCLUDE_FROM_SCSI_C
#include "SCSI.h" #include "SCSI.h"
/** Structure to hold the SCSI response data to a SCSI INQUIRY command. This gives information about the device's /** Structure to hold the SCSI response data to a SCSI INQUIRY command. This gives information about the device's
* features and capabilities. * features and capabilities.
*/ */
SCSI_Inquiry_Response_t InquiryData = SCSI_Inquiry_Response_t InquiryData =
{ {
.DeviceType = DEVICE_TYPE_BLOCK, .DeviceType = DEVICE_TYPE_BLOCK,
.PeripheralQualifier = 0, .PeripheralQualifier = 0,
.Removable = true, .Removable = true,
.Version = 0, .Version = 0,
.ResponseDataFormat = 2, .ResponseDataFormat = 2,
.NormACA = false, .NormACA = false,
.TrmTsk = false, .TrmTsk = false,
.AERC = false, .AERC = false,
.AdditionalLength = 0x1F, .AdditionalLength = 0x1F,
.SoftReset = false, .SoftReset = false,
.CmdQue = false, .CmdQue = false,
.Linked = false, .Linked = false,
.Sync = false, .Sync = false,
.WideBus16Bit = false, .WideBus16Bit = false,
.WideBus32Bit = false, .WideBus32Bit = false,
.RelAddr = false, .RelAddr = false,
.VendorID = "LUFA", .VendorID = "LUFA",
.ProductID = "Dataflash Disk", .ProductID = "Dataflash Disk",
.RevisionID = {'0','.','0','0'}, .RevisionID = {'0','.','0','0'},
}; };
/** Structure to hold the sense data for the last issued SCSI command, which is returned to the host after a SCSI REQUEST SENSE /** Structure to hold the sense data for the last issued SCSI command, which is returned to the host after a SCSI REQUEST SENSE
* command is issued. This gives information on exactly why the last command failed to complete. * command is issued. This gives information on exactly why the last command failed to complete.
*/ */
SCSI_Request_Sense_Response_t SenseData = SCSI_Request_Sense_Response_t SenseData =
{ {
.ResponseCode = 0x70, .ResponseCode = 0x70,
.AdditionalLength = 0x0A, .AdditionalLength = 0x0A,
}; };
/** Main routine to process the SCSI command located in the Command Block Wrapper read from the host. This dispatches /** Main routine to process the SCSI command located in the Command Block Wrapper read from the host. This dispatches
* to the appropriate SCSI command handling routine if the issued command is supported by the device, else it returns * to the appropriate SCSI command handling routine if the issued command is supported by the device, else it returns
* a command failure due to a ILLEGAL REQUEST. * a command failure due to a ILLEGAL REQUEST.
* *
* \param[in] MSInterfaceInfo Pointer to the Mass Storage class interface structure that the command is associated with * \param[in] MSInterfaceInfo Pointer to the Mass Storage class interface structure that the command is associated with
*/ */
bool SCSI_DecodeSCSICommand(USB_ClassInfo_MS_Device_t* MSInterfaceInfo) bool SCSI_DecodeSCSICommand(USB_ClassInfo_MS_Device_t* MSInterfaceInfo)
{ {
bool CommandSuccess = false; bool CommandSuccess = false;
/* Run the appropriate SCSI command hander function based on the passed command */ /* Run the appropriate SCSI command hander function based on the passed command */
switch (MSInterfaceInfo->State.CommandBlock.SCSICommandData[0]) switch (MSInterfaceInfo->State.CommandBlock.SCSICommandData[0])
{ {
case SCSI_CMD_INQUIRY: case SCSI_CMD_INQUIRY:
CommandSuccess = SCSI_Command_Inquiry(MSInterfaceInfo); CommandSuccess = SCSI_Command_Inquiry(MSInterfaceInfo);
break; break;
case SCSI_CMD_REQUEST_SENSE: case SCSI_CMD_REQUEST_SENSE:
CommandSuccess = SCSI_Command_Request_Sense(MSInterfaceInfo); CommandSuccess = SCSI_Command_Request_Sense(MSInterfaceInfo);
break; break;
case SCSI_CMD_READ_CAPACITY_10: case SCSI_CMD_READ_CAPACITY_10:
CommandSuccess = SCSI_Command_Read_Capacity_10(MSInterfaceInfo); CommandSuccess = SCSI_Command_Read_Capacity_10(MSInterfaceInfo);
break; break;
case SCSI_CMD_SEND_DIAGNOSTIC: case SCSI_CMD_SEND_DIAGNOSTIC:
CommandSuccess = SCSI_Command_Send_Diagnostic(MSInterfaceInfo); CommandSuccess = SCSI_Command_Send_Diagnostic(MSInterfaceInfo);
break; break;
case SCSI_CMD_WRITE_10: case SCSI_CMD_WRITE_10:
CommandSuccess = SCSI_Command_ReadWrite_10(MSInterfaceInfo, DATA_WRITE); CommandSuccess = SCSI_Command_ReadWrite_10(MSInterfaceInfo, DATA_WRITE);
break; break;
case SCSI_CMD_READ_10: case SCSI_CMD_READ_10:
CommandSuccess = SCSI_Command_ReadWrite_10(MSInterfaceInfo, DATA_READ); CommandSuccess = SCSI_Command_ReadWrite_10(MSInterfaceInfo, DATA_READ);
break; break;
case SCSI_CMD_TEST_UNIT_READY: case SCSI_CMD_TEST_UNIT_READY:
case SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL: case SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL:
case SCSI_CMD_VERIFY_10: case SCSI_CMD_VERIFY_10:
/* These commands should just succeed, no handling required */ /* These commands should just succeed, no handling required */
CommandSuccess = true; CommandSuccess = true;
MSInterfaceInfo->State.CommandBlock.DataTransferLength = 0; MSInterfaceInfo->State.CommandBlock.DataTransferLength = 0;
break; break;
default: default:
/* Update the SENSE key to reflect the invalid command */ /* Update the SENSE key to reflect the invalid command */
SCSI_SET_SENSE(SCSI_SENSE_KEY_ILLEGAL_REQUEST, SCSI_SET_SENSE(SCSI_SENSE_KEY_ILLEGAL_REQUEST,
SCSI_ASENSE_INVALID_COMMAND, SCSI_ASENSE_INVALID_COMMAND,
SCSI_ASENSEQ_NO_QUALIFIER); SCSI_ASENSEQ_NO_QUALIFIER);
break; break;
} }
/* Check if command was successfully processed */ /* Check if command was successfully processed */
if (CommandSuccess) if (CommandSuccess)
{ {
SCSI_SET_SENSE(SCSI_SENSE_KEY_GOOD, SCSI_SET_SENSE(SCSI_SENSE_KEY_GOOD,
SCSI_ASENSE_NO_ADDITIONAL_INFORMATION, SCSI_ASENSE_NO_ADDITIONAL_INFORMATION,
SCSI_ASENSEQ_NO_QUALIFIER); SCSI_ASENSEQ_NO_QUALIFIER);
return true; return true;
} }
return false; return false;
} }
/** Command processing for an issued SCSI INQUIRY command. This command returns information about the device's features /** Command processing for an issued SCSI INQUIRY command. This command returns information about the device's features
* and capabilities to the host. * and capabilities to the host.
* *
* \param[in] MSInterfaceInfo Pointer to the Mass Storage class interface structure that the command is associated with * \param[in] MSInterfaceInfo Pointer to the Mass Storage class interface structure that the command is associated with
* *
* \return Boolean true if the command completed successfully, false otherwise. * \return Boolean true if the command completed successfully, false otherwise.
*/ */
static bool SCSI_Command_Inquiry(USB_ClassInfo_MS_Device_t* MSInterfaceInfo) static bool SCSI_Command_Inquiry(USB_ClassInfo_MS_Device_t* MSInterfaceInfo)
{ {
uint16_t AllocationLength = (((uint16_t)MSInterfaceInfo->State.CommandBlock.SCSICommandData[3] << 8) | uint16_t AllocationLength = (((uint16_t)MSInterfaceInfo->State.CommandBlock.SCSICommandData[3] << 8) |
MSInterfaceInfo->State.CommandBlock.SCSICommandData[4]); MSInterfaceInfo->State.CommandBlock.SCSICommandData[4]);
uint16_t BytesTransferred = (AllocationLength < sizeof(InquiryData))? AllocationLength : uint16_t BytesTransferred = (AllocationLength < sizeof(InquiryData))? AllocationLength :
sizeof(InquiryData); sizeof(InquiryData);
/* Only the standard INQUIRY data is supported, check if any optional INQUIRY bits set */ /* Only the standard INQUIRY data is supported, check if any optional INQUIRY bits set */
if ((MSInterfaceInfo->State.CommandBlock.SCSICommandData[1] & ((1 << 0) | (1 << 1))) || if ((MSInterfaceInfo->State.CommandBlock.SCSICommandData[1] & ((1 << 0) | (1 << 1))) ||
MSInterfaceInfo->State.CommandBlock.SCSICommandData[2]) MSInterfaceInfo->State.CommandBlock.SCSICommandData[2])
{ {
/* Optional but unsupported bits set - update the SENSE key and fail the request */ /* Optional but unsupported bits set - update the SENSE key and fail the request */
SCSI_SET_SENSE(SCSI_SENSE_KEY_ILLEGAL_REQUEST, SCSI_SET_SENSE(SCSI_SENSE_KEY_ILLEGAL_REQUEST,
SCSI_ASENSE_INVALID_FIELD_IN_CDB, SCSI_ASENSE_INVALID_FIELD_IN_CDB,
SCSI_ASENSEQ_NO_QUALIFIER); SCSI_ASENSEQ_NO_QUALIFIER);
return false; return false;
} }
Endpoint_Write_Stream_LE(&InquiryData, BytesTransferred, NO_STREAM_CALLBACK); Endpoint_Write_Stream_LE(&InquiryData, BytesTransferred, NO_STREAM_CALLBACK);
uint8_t PadBytes[AllocationLength - BytesTransferred]; uint8_t PadBytes[AllocationLength - BytesTransferred];
/* Pad out remaining bytes with 0x00 */ /* Pad out remaining bytes with 0x00 */
Endpoint_Write_Stream_LE(&PadBytes, (AllocationLength - BytesTransferred), NO_STREAM_CALLBACK); Endpoint_Write_Stream_LE(&PadBytes, (AllocationLength - BytesTransferred), NO_STREAM_CALLBACK);
/* Finalize the stream transfer to send the last packet */ /* Finalize the stream transfer to send the last packet */
Endpoint_ClearIN(); Endpoint_ClearIN();
/* Succeed the command and update the bytes transferred counter */ /* Succeed the command and update the bytes transferred counter */
MSInterfaceInfo->State.CommandBlock.DataTransferLength -= BytesTransferred; MSInterfaceInfo->State.CommandBlock.DataTransferLength -= BytesTransferred;
return true; return true;
} }
/** Command processing for an issued SCSI REQUEST SENSE command. This command returns information about the last issued command, /** Command processing for an issued SCSI REQUEST SENSE command. This command returns information about the last issued command,
* including the error code and additional error information so that the host can determine why a command failed to complete. * including the error code and additional error information so that the host can determine why a command failed to complete.
* *
* \param[in] MSInterfaceInfo Pointer to the Mass Storage class interface structure that the command is associated with * \param[in] MSInterfaceInfo Pointer to the Mass Storage class interface structure that the command is associated with
* *
* \return Boolean true if the command completed successfully, false otherwise. * \return Boolean true if the command completed successfully, false otherwise.
*/ */
static bool SCSI_Command_Request_Sense(USB_ClassInfo_MS_Device_t* MSInterfaceInfo) static bool SCSI_Command_Request_Sense(USB_ClassInfo_MS_Device_t* MSInterfaceInfo)
{ {
uint8_t AllocationLength = MSInterfaceInfo->State.CommandBlock.SCSICommandData[4]; uint8_t AllocationLength = MSInterfaceInfo->State.CommandBlock.SCSICommandData[4];
uint8_t BytesTransferred = (AllocationLength < sizeof(SenseData))? AllocationLength : sizeof(SenseData); uint8_t BytesTransferred = (AllocationLength < sizeof(SenseData))? AllocationLength : sizeof(SenseData);
uint8_t PadBytes[AllocationLength - BytesTransferred]; uint8_t PadBytes[AllocationLength - BytesTransferred];
Endpoint_Write_Stream_LE(&SenseData, BytesTransferred, NO_STREAM_CALLBACK); Endpoint_Write_Stream_LE(&SenseData, BytesTransferred, NO_STREAM_CALLBACK);
Endpoint_Write_Stream_LE(&PadBytes, (AllocationLength - BytesTransferred), NO_STREAM_CALLBACK); Endpoint_Write_Stream_LE(&PadBytes, (AllocationLength - BytesTransferred), NO_STREAM_CALLBACK);
Endpoint_ClearIN(); Endpoint_ClearIN();
/* Succeed the command and update the bytes transferred counter */ /* Succeed the command and update the bytes transferred counter */
MSInterfaceInfo->State.CommandBlock.DataTransferLength -= BytesTransferred; MSInterfaceInfo->State.CommandBlock.DataTransferLength -= BytesTransferred;
return true; return true;
} }
/** Command processing for an issued SCSI READ CAPACITY (10) command. This command returns information about the device's capacity /** Command processing for an issued SCSI READ CAPACITY (10) command. This command returns information about the device's capacity
* on the selected Logical Unit (drive), as a number of OS-sized blocks. * on the selected Logical Unit (drive), as a number of OS-sized blocks.
* *
* \param[in] MSInterfaceInfo Pointer to the Mass Storage class interface structure that the command is associated with * \param[in] MSInterfaceInfo Pointer to the Mass Storage class interface structure that the command is associated with
* *
* \return Boolean true if the command completed successfully, false otherwise. * \return Boolean true if the command completed successfully, false otherwise.
*/ */
static bool SCSI_Command_Read_Capacity_10(USB_ClassInfo_MS_Device_t* MSInterfaceInfo) static bool SCSI_Command_Read_Capacity_10(USB_ClassInfo_MS_Device_t* MSInterfaceInfo)
{ {
uint32_t LastBlockAddressInLUN = (LUN_MEDIA_BLOCKS - 1); uint32_t LastBlockAddressInLUN = (LUN_MEDIA_BLOCKS - 1);
uint32_t MediaBlockSize = VIRTUAL_MEMORY_BLOCK_SIZE; uint32_t MediaBlockSize = VIRTUAL_MEMORY_BLOCK_SIZE;
Endpoint_Write_Stream_BE(&LastBlockAddressInLUN, sizeof(LastBlockAddressInLUN), NO_STREAM_CALLBACK); Endpoint_Write_Stream_BE(&LastBlockAddressInLUN, sizeof(LastBlockAddressInLUN), NO_STREAM_CALLBACK);
Endpoint_Write_Stream_BE(&MediaBlockSize, sizeof(MediaBlockSize), NO_STREAM_CALLBACK); Endpoint_Write_Stream_BE(&MediaBlockSize, sizeof(MediaBlockSize), NO_STREAM_CALLBACK);
Endpoint_ClearIN(); Endpoint_ClearIN();
/* Succeed the command and update the bytes transferred counter */ /* Succeed the command and update the bytes transferred counter */
MSInterfaceInfo->State.CommandBlock.DataTransferLength -= 8; MSInterfaceInfo->State.CommandBlock.DataTransferLength -= 8;
return true; return true;
} }
/** Command processing for an issued SCSI SEND DIAGNOSTIC command. This command performs a quick check of the Dataflash ICs on the /** Command processing for an issued SCSI SEND DIAGNOSTIC command. This command performs a quick check of the Dataflash ICs on the
* board, and indicates if they are present and functioning correctly. Only the Self-Test portion of the diagnostic command is * board, and indicates if they are present and functioning correctly. Only the Self-Test portion of the diagnostic command is
* supported. * supported.
* *
* \param[in] MSInterfaceInfo Pointer to the Mass Storage class interface structure that the command is associated with * \param[in] MSInterfaceInfo Pointer to the Mass Storage class interface structure that the command is associated with
* *
* \return Boolean true if the command completed successfully, false otherwise. * \return Boolean true if the command completed successfully, false otherwise.
*/ */
static bool SCSI_Command_Send_Diagnostic(USB_ClassInfo_MS_Device_t* MSInterfaceInfo) static bool SCSI_Command_Send_Diagnostic(USB_ClassInfo_MS_Device_t* MSInterfaceInfo)
{ {
uint8_t ReturnByte; uint8_t ReturnByte;
/* Check to see if the SELF TEST bit is not set */ /* Check to see if the SELF TEST bit is not set */
if (!(MSInterfaceInfo->State.CommandBlock.SCSICommandData[1] & (1 << 2))) if (!(MSInterfaceInfo->State.CommandBlock.SCSICommandData[1] & (1 << 2)))
{ {
/* Only self-test supported - update SENSE key and fail the command */ /* Only self-test supported - update SENSE key and fail the command */
SCSI_SET_SENSE(SCSI_SENSE_KEY_ILLEGAL_REQUEST, SCSI_SET_SENSE(SCSI_SENSE_KEY_ILLEGAL_REQUEST,
SCSI_ASENSE_INVALID_FIELD_IN_CDB, SCSI_ASENSE_INVALID_FIELD_IN_CDB,
SCSI_ASENSEQ_NO_QUALIFIER); SCSI_ASENSEQ_NO_QUALIFIER);
return false; return false;
} }
/* Test first Dataflash IC is present and responding to commands */ /* Test first Dataflash IC is present and responding to commands */
Dataflash_SelectChip(DATAFLASH_CHIP1); Dataflash_SelectChip(DATAFLASH_CHIP1);
Dataflash_SendByte(DF_CMD_READMANUFACTURERDEVICEINFO); Dataflash_SendByte(DF_CMD_READMANUFACTURERDEVICEINFO);
ReturnByte = Dataflash_ReceiveByte(); ReturnByte = Dataflash_ReceiveByte();
Dataflash_DeselectChip(); Dataflash_DeselectChip();
/* If returned data is invalid, fail the command */ /* If returned data is invalid, fail the command */
if (ReturnByte != DF_MANUFACTURER_ATMEL) if (ReturnByte != DF_MANUFACTURER_ATMEL)
{ {
/* Update SENSE key with a hardware error condition and return command fail */ /* Update SENSE key with a hardware error condition and return command fail */
SCSI_SET_SENSE(SCSI_SENSE_KEY_HARDWARE_ERROR, SCSI_SET_SENSE(SCSI_SENSE_KEY_HARDWARE_ERROR,
SCSI_ASENSE_NO_ADDITIONAL_INFORMATION, SCSI_ASENSE_NO_ADDITIONAL_INFORMATION,
SCSI_ASENSEQ_NO_QUALIFIER); SCSI_ASENSEQ_NO_QUALIFIER);
return false; return false;
} }
#if (DATAFLASH_TOTALCHIPS == 2) #if (DATAFLASH_TOTALCHIPS == 2)
/* Test second Dataflash IC is present and responding to commands */ /* Test second Dataflash IC is present and responding to commands */
Dataflash_SelectChip(DATAFLASH_CHIP2); Dataflash_SelectChip(DATAFLASH_CHIP2);
Dataflash_SendByte(DF_CMD_READMANUFACTURERDEVICEINFO); Dataflash_SendByte(DF_CMD_READMANUFACTURERDEVICEINFO);
ReturnByte = Dataflash_ReceiveByte(); ReturnByte = Dataflash_ReceiveByte();
Dataflash_DeselectChip(); Dataflash_DeselectChip();
/* If returned data is invalid, fail the command */ /* If returned data is invalid, fail the command */
if (ReturnByte != DF_MANUFACTURER_ATMEL) if (ReturnByte != DF_MANUFACTURER_ATMEL)
{ {
/* Update SENSE key with a hardware error condition and return command fail */ /* Update SENSE key with a hardware error condition and return command fail */
SCSI_SET_SENSE(SCSI_SENSE_KEY_HARDWARE_ERROR, SCSI_SET_SENSE(SCSI_SENSE_KEY_HARDWARE_ERROR,
SCSI_ASENSE_NO_ADDITIONAL_INFORMATION, SCSI_ASENSE_NO_ADDITIONAL_INFORMATION,
SCSI_ASENSEQ_NO_QUALIFIER); SCSI_ASENSEQ_NO_QUALIFIER);
return false; return false;
} }
#endif #endif
/* Succeed the command and update the bytes transferred counter */ /* Succeed the command and update the bytes transferred counter */
MSInterfaceInfo->State.CommandBlock.DataTransferLength = 0; MSInterfaceInfo->State.CommandBlock.DataTransferLength = 0;
return true; return true;
} }
/** Command processing for an issued SCSI READ (10) or WRITE (10) command. This command reads in the block start address /** Command processing for an issued SCSI READ (10) or WRITE (10) command. This command reads in the block start address
* and total number of blocks to process, then calls the appropriate low-level dataflash routine to handle the actual * and total number of blocks to process, then calls the appropriate low-level dataflash routine to handle the actual
* reading and writing of the data. * reading and writing of the data.
* *
* \param[in] MSInterfaceInfo Pointer to the Mass Storage class interface structure that the command is associated with * \param[in] MSInterfaceInfo Pointer to the Mass Storage class interface structure that the command is associated with
* \param[in] IsDataRead Indicates if the command is a READ (10) command or WRITE (10) command (DATA_READ or DATA_WRITE) * \param[in] IsDataRead Indicates if the command is a READ (10) command or WRITE (10) command (DATA_READ or DATA_WRITE)
* *
* \return Boolean true if the command completed successfully, false otherwise. * \return Boolean true if the command completed successfully, false otherwise.
*/ */
static bool SCSI_Command_ReadWrite_10(USB_ClassInfo_MS_Device_t* MSInterfaceInfo, const bool IsDataRead) static bool SCSI_Command_ReadWrite_10(USB_ClassInfo_MS_Device_t* MSInterfaceInfo, const bool IsDataRead)
{ {
uint32_t BlockAddress; uint32_t BlockAddress;
uint16_t TotalBlocks; uint16_t TotalBlocks;
/* Load in the 32-bit block address (SCSI uses big-endian, so have to do it byte-by-byte) */ /* Load in the 32-bit block address (SCSI uses big-endian, so have to do it byte-by-byte) */
((uint8_t*)&BlockAddress)[3] = MSInterfaceInfo->State.CommandBlock.SCSICommandData[2]; ((uint8_t*)&BlockAddress)[3] = MSInterfaceInfo->State.CommandBlock.SCSICommandData[2];
((uint8_t*)&BlockAddress)[2] = MSInterfaceInfo->State.CommandBlock.SCSICommandData[3]; ((uint8_t*)&BlockAddress)[2] = MSInterfaceInfo->State.CommandBlock.SCSICommandData[3];
((uint8_t*)&BlockAddress)[1] = MSInterfaceInfo->State.CommandBlock.SCSICommandData[4]; ((uint8_t*)&BlockAddress)[1] = MSInterfaceInfo->State.CommandBlock.SCSICommandData[4];
((uint8_t*)&BlockAddress)[0] = MSInterfaceInfo->State.CommandBlock.SCSICommandData[5]; ((uint8_t*)&BlockAddress)[0] = MSInterfaceInfo->State.CommandBlock.SCSICommandData[5];
/* Load in the 16-bit total blocks (SCSI uses big-endian, so have to do it byte-by-byte) */ /* Load in the 16-bit total blocks (SCSI uses big-endian, so have to do it byte-by-byte) */
((uint8_t*)&TotalBlocks)[1] = MSInterfaceInfo->State.CommandBlock.SCSICommandData[7]; ((uint8_t*)&TotalBlocks)[1] = MSInterfaceInfo->State.CommandBlock.SCSICommandData[7];
((uint8_t*)&TotalBlocks)[0] = MSInterfaceInfo->State.CommandBlock.SCSICommandData[8]; ((uint8_t*)&TotalBlocks)[0] = MSInterfaceInfo->State.CommandBlock.SCSICommandData[8];
/* Check if the block address is outside the maximum allowable value for the LUN */ /* Check if the block address is outside the maximum allowable value for the LUN */
if (BlockAddress >= LUN_MEDIA_BLOCKS) if (BlockAddress >= LUN_MEDIA_BLOCKS)
{ {
/* Block address is invalid, update SENSE key and return command fail */ /* Block address is invalid, update SENSE key and return command fail */
SCSI_SET_SENSE(SCSI_SENSE_KEY_ILLEGAL_REQUEST, SCSI_SET_SENSE(SCSI_SENSE_KEY_ILLEGAL_REQUEST,
SCSI_ASENSE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, SCSI_ASENSE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
SCSI_ASENSEQ_NO_QUALIFIER); SCSI_ASENSEQ_NO_QUALIFIER);
return false; return false;
} }
#if (TOTAL_LUNS > 1) #if (TOTAL_LUNS > 1)
/* Adjust the given block address to the real media address based on the selected LUN */ /* Adjust the given block address to the real media address based on the selected LUN */
BlockAddress += ((uint32_t)MSInterfaceInfo->State.CommandBlock.LUN * LUN_MEDIA_BLOCKS); BlockAddress += ((uint32_t)MSInterfaceInfo->State.CommandBlock.LUN * LUN_MEDIA_BLOCKS);
#endif #endif
/* Determine if the packet is a READ (10) or WRITE (10) command, call appropriate function */ /* Determine if the packet is a READ (10) or WRITE (10) command, call appropriate function */
if (IsDataRead == DATA_READ) if (IsDataRead == DATA_READ)
DataflashManager_ReadBlocks(MSInterfaceInfo, BlockAddress, TotalBlocks); DataflashManager_ReadBlocks(MSInterfaceInfo, BlockAddress, TotalBlocks);
else else
DataflashManager_WriteBlocks(MSInterfaceInfo, BlockAddress, TotalBlocks); DataflashManager_WriteBlocks(MSInterfaceInfo, BlockAddress, TotalBlocks);
/* Update the bytes transferred counter and succeed the command */ /* Update the bytes transferred counter and succeed the command */
MSInterfaceInfo->State.CommandBlock.DataTransferLength -= ((uint32_t)TotalBlocks * VIRTUAL_MEMORY_BLOCK_SIZE); MSInterfaceInfo->State.CommandBlock.DataTransferLength -= ((uint32_t)TotalBlocks * VIRTUAL_MEMORY_BLOCK_SIZE);
return true; return true;
} }

View file

@ -1,87 +1,87 @@
/* /*
LUFA Library LUFA Library
Copyright (C) Dean Camera, 2010. Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com www.fourwalledcubicle.com
*/ */
/* /*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com) Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the advertising or publicity pertaining to distribution of the
software without specific, written prior permission. software without specific, written prior permission.
The author disclaim all warranties with regard to this The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action, in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of arising out of or in connection with the use or performance of
this software. this software.
*/ */
/** \file /** \file
* *
* Header file for SCSI.c. * Header file for SCSI.c.
*/ */
#ifndef _SCSI_H_ #ifndef _SCSI_H_
#define _SCSI_H_ #define _SCSI_H_
/* Includes: */ /* Includes: */
#include <avr/io.h> #include <avr/io.h>
#include <avr/pgmspace.h> #include <avr/pgmspace.h>
#include <LUFA/Drivers/USB/USB.h> #include <LUFA/Drivers/USB/USB.h>
#include <LUFA/Drivers/USB/Class/MassStorage.h> #include <LUFA/Drivers/USB/Class/MassStorage.h>
#include "MassStorageKeyboard.h" #include "MassStorageKeyboard.h"
#include "Descriptors.h" #include "Descriptors.h"
#include "DataflashManager.h" #include "DataflashManager.h"
#include "SCSI_Codes.h" #include "SCSI_Codes.h"
/* Macros: */ /* Macros: */
/** Macro to set the current SCSI sense data to the given key, additional sense code and additional sense qualifier. This /** Macro to set the current SCSI sense data to the given key, additional sense code and additional sense qualifier. This
* is for convenience, as it allows for all three sense values (returned upon request to the host to give information about * is for convenience, as it allows for all three sense values (returned upon request to the host to give information about
* the last command failure) in a quick and easy manner. * the last command failure) in a quick and easy manner.
* *
* \param[in] key New SCSI sense key to set the sense code to * \param[in] key New SCSI sense key to set the sense code to
* \param[in] acode New SCSI additional sense key to set the additional sense code to * \param[in] acode New SCSI additional sense key to set the additional sense code to
* \param[in] aqual New SCSI additional sense key qualifier to set the additional sense qualifier code to * \param[in] aqual New SCSI additional sense key qualifier to set the additional sense qualifier code to
*/ */
#define SCSI_SET_SENSE(key, acode, aqual) MACROS{ SenseData.SenseKey = key; \ #define SCSI_SET_SENSE(key, acode, aqual) MACROS{ SenseData.SenseKey = key; \
SenseData.AdditionalSenseCode = acode; \ SenseData.AdditionalSenseCode = acode; \
SenseData.AdditionalSenseQualifier = aqual; }MACROE SenseData.AdditionalSenseQualifier = aqual; }MACROE
/** Macro for the SCSI_Command_ReadWrite_10() function, to indicate that data is to be read from the storage medium. */ /** Macro for the SCSI_Command_ReadWrite_10() function, to indicate that data is to be read from the storage medium. */
#define DATA_READ true #define DATA_READ true
/** Macro for the SCSI_Command_ReadWrite_10() function, to indicate that data is to be written to the storage medium. */ /** Macro for the SCSI_Command_ReadWrite_10() function, to indicate that data is to be written to the storage medium. */
#define DATA_WRITE false #define DATA_WRITE false
/** Value for the DeviceType entry in the SCSI_Inquiry_Response_t enum, indicating a Block Media device. */ /** Value for the DeviceType entry in the SCSI_Inquiry_Response_t enum, indicating a Block Media device. */
#define DEVICE_TYPE_BLOCK 0x00 #define DEVICE_TYPE_BLOCK 0x00
/** Value for the DeviceType entry in the SCSI_Inquiry_Response_t enum, indicating a CD-ROM device. */ /** Value for the DeviceType entry in the SCSI_Inquiry_Response_t enum, indicating a CD-ROM device. */
#define DEVICE_TYPE_CDROM 0x05 #define DEVICE_TYPE_CDROM 0x05
/* Function Prototypes: */ /* Function Prototypes: */
bool SCSI_DecodeSCSICommand(USB_ClassInfo_MS_Device_t* MSInterfaceInfo); bool SCSI_DecodeSCSICommand(USB_ClassInfo_MS_Device_t* MSInterfaceInfo);
#if defined(INCLUDE_FROM_SCSI_C) #if defined(INCLUDE_FROM_SCSI_C)
static bool SCSI_Command_Inquiry(USB_ClassInfo_MS_Device_t* MSInterfaceInfo); static bool SCSI_Command_Inquiry(USB_ClassInfo_MS_Device_t* MSInterfaceInfo);
static bool SCSI_Command_Request_Sense(USB_ClassInfo_MS_Device_t* MSInterfaceInfo); static bool SCSI_Command_Request_Sense(USB_ClassInfo_MS_Device_t* MSInterfaceInfo);
static bool SCSI_Command_Read_Capacity_10(USB_ClassInfo_MS_Device_t* MSInterfaceInfo); static bool SCSI_Command_Read_Capacity_10(USB_ClassInfo_MS_Device_t* MSInterfaceInfo);
static bool SCSI_Command_Send_Diagnostic(USB_ClassInfo_MS_Device_t* MSInterfaceInfo); static bool SCSI_Command_Send_Diagnostic(USB_ClassInfo_MS_Device_t* MSInterfaceInfo);
static bool SCSI_Command_ReadWrite_10(USB_ClassInfo_MS_Device_t* MSInterfaceInfo, const bool IsDataRead); static bool SCSI_Command_ReadWrite_10(USB_ClassInfo_MS_Device_t* MSInterfaceInfo, const bool IsDataRead);
#endif #endif
#endif #endif

View file

@ -1,85 +1,85 @@
/* /*
LUFA Library LUFA Library
Copyright (C) Dean Camera, 2010. Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com www.fourwalledcubicle.com
*/ */
/* /*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com) Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the advertising or publicity pertaining to distribution of the
software without specific, written prior permission. software without specific, written prior permission.
The author disclaim all warranties with regard to this The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action, in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of arising out of or in connection with the use or performance of
this software. this software.
*/ */
/** \file /** \file
* *
* Header containing macros for possible SCSI commands and SENSE data. Refer to * Header containing macros for possible SCSI commands and SENSE data. Refer to
* the SCSI standard documentation for more information on each SCSI command and * the SCSI standard documentation for more information on each SCSI command and
* the SENSE data. * the SENSE data.
*/ */
#ifndef _SCSI_CODES_H_ #ifndef _SCSI_CODES_H_
#define _SCSI_CODES_H_ #define _SCSI_CODES_H_
/* Macros: */ /* Macros: */
#define SCSI_CMD_INQUIRY 0x12 #define SCSI_CMD_INQUIRY 0x12
#define SCSI_CMD_REQUEST_SENSE 0x03 #define SCSI_CMD_REQUEST_SENSE 0x03
#define SCSI_CMD_TEST_UNIT_READY 0x00 #define SCSI_CMD_TEST_UNIT_READY 0x00
#define SCSI_CMD_READ_CAPACITY_10 0x25 #define SCSI_CMD_READ_CAPACITY_10 0x25
#define SCSI_CMD_SEND_DIAGNOSTIC 0x1D #define SCSI_CMD_SEND_DIAGNOSTIC 0x1D
#define SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL 0x1E #define SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL 0x1E
#define SCSI_CMD_WRITE_10 0x2A #define SCSI_CMD_WRITE_10 0x2A
#define SCSI_CMD_READ_10 0x28 #define SCSI_CMD_READ_10 0x28
#define SCSI_CMD_WRITE_6 0x0A #define SCSI_CMD_WRITE_6 0x0A
#define SCSI_CMD_READ_6 0x08 #define SCSI_CMD_READ_6 0x08
#define SCSI_CMD_VERIFY_10 0x2F #define SCSI_CMD_VERIFY_10 0x2F
#define SCSI_CMD_MODE_SENSE_6 0x1A #define SCSI_CMD_MODE_SENSE_6 0x1A
#define SCSI_CMD_MODE_SENSE_10 0x5A #define SCSI_CMD_MODE_SENSE_10 0x5A
#define SCSI_SENSE_KEY_GOOD 0x00 #define SCSI_SENSE_KEY_GOOD 0x00
#define SCSI_SENSE_KEY_RECOVERED_ERROR 0x01 #define SCSI_SENSE_KEY_RECOVERED_ERROR 0x01
#define SCSI_SENSE_KEY_NOT_READY 0x02 #define SCSI_SENSE_KEY_NOT_READY 0x02
#define SCSI_SENSE_KEY_MEDIUM_ERROR 0x03 #define SCSI_SENSE_KEY_MEDIUM_ERROR 0x03
#define SCSI_SENSE_KEY_HARDWARE_ERROR 0x04 #define SCSI_SENSE_KEY_HARDWARE_ERROR 0x04
#define SCSI_SENSE_KEY_ILLEGAL_REQUEST 0x05 #define SCSI_SENSE_KEY_ILLEGAL_REQUEST 0x05
#define SCSI_SENSE_KEY_UNIT_ATTENTION 0x06 #define SCSI_SENSE_KEY_UNIT_ATTENTION 0x06
#define SCSI_SENSE_KEY_DATA_PROTECT 0x07 #define SCSI_SENSE_KEY_DATA_PROTECT 0x07
#define SCSI_SENSE_KEY_BLANK_CHECK 0x08 #define SCSI_SENSE_KEY_BLANK_CHECK 0x08
#define SCSI_SENSE_KEY_VENDOR_SPECIFIC 0x09 #define SCSI_SENSE_KEY_VENDOR_SPECIFIC 0x09
#define SCSI_SENSE_KEY_COPY_ABORTED 0x0A #define SCSI_SENSE_KEY_COPY_ABORTED 0x0A
#define SCSI_SENSE_KEY_ABORTED_COMMAND 0x0B #define SCSI_SENSE_KEY_ABORTED_COMMAND 0x0B
#define SCSI_SENSE_KEY_VOLUME_OVERFLOW 0x0D #define SCSI_SENSE_KEY_VOLUME_OVERFLOW 0x0D
#define SCSI_SENSE_KEY_MISCOMPARE 0x0E #define SCSI_SENSE_KEY_MISCOMPARE 0x0E
#define SCSI_ASENSE_NO_ADDITIONAL_INFORMATION 0x00 #define SCSI_ASENSE_NO_ADDITIONAL_INFORMATION 0x00
#define SCSI_ASENSE_LOGICAL_UNIT_NOT_READY 0x04 #define SCSI_ASENSE_LOGICAL_UNIT_NOT_READY 0x04
#define SCSI_ASENSE_INVALID_FIELD_IN_CDB 0x24 #define SCSI_ASENSE_INVALID_FIELD_IN_CDB 0x24
#define SCSI_ASENSE_WRITE_PROTECTED 0x27 #define SCSI_ASENSE_WRITE_PROTECTED 0x27
#define SCSI_ASENSE_FORMAT_ERROR 0x31 #define SCSI_ASENSE_FORMAT_ERROR 0x31
#define SCSI_ASENSE_INVALID_COMMAND 0x20 #define SCSI_ASENSE_INVALID_COMMAND 0x20
#define SCSI_ASENSE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE 0x21 #define SCSI_ASENSE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE 0x21
#define SCSI_ASENSE_MEDIUM_NOT_PRESENT 0x3A #define SCSI_ASENSE_MEDIUM_NOT_PRESENT 0x3A
#define SCSI_ASENSEQ_NO_QUALIFIER 0x00 #define SCSI_ASENSEQ_NO_QUALIFIER 0x00
#define SCSI_ASENSEQ_FORMAT_COMMAND_FAILED 0x01 #define SCSI_ASENSEQ_FORMAT_COMMAND_FAILED 0x01
#define SCSI_ASENSEQ_INITIALIZING_COMMAND_REQUIRED 0x02 #define SCSI_ASENSEQ_INITIALIZING_COMMAND_REQUIRED 0x02
#define SCSI_ASENSEQ_OPERATION_IN_PROGRESS 0x07 #define SCSI_ASENSEQ_OPERATION_IN_PROGRESS 0x07
#endif #endif

View file

@ -1,242 +1,242 @@
/* /*
LUFA Library LUFA Library
Copyright (C) Dean Camera, 2010. Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com www.fourwalledcubicle.com
*/ */
/* /*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com) Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Copyright 2010 Matthias Hullin (lufa [at] matthias [dot] hullin [dot] net) Copyright 2010 Matthias Hullin (lufa [at] matthias [dot] hullin [dot] net)
Permission to use, copy, modify, distribute, and sell this Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the advertising or publicity pertaining to distribution of the
software without specific, written prior permission. software without specific, written prior permission.
The author disclaim all warranties with regard to this The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action, in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of arising out of or in connection with the use or performance of
this software. this software.
*/ */
/** \file /** \file
* *
* Main source file for the MassStorageKeyboard demo. This file contains the main tasks of * Main source file for the MassStorageKeyboard demo. This file contains the main tasks of
* the demo and is responsible for the initial application hardware configuration. * the demo and is responsible for the initial application hardware configuration.
*/ */
#include "MassStorageKeyboard.h" #include "MassStorageKeyboard.h"
/** LUFA Mass Storage Class driver interface configuration and state information. This structure is /** LUFA Mass Storage Class driver interface configuration and state information. This structure is
* passed to all Mass Storage Class driver functions, so that multiple instances of the same class * passed to all Mass Storage Class driver functions, so that multiple instances of the same class
* within a device can be differentiated from one another. * within a device can be differentiated from one another.
*/ */
USB_ClassInfo_MS_Device_t Disk_MS_Interface = USB_ClassInfo_MS_Device_t Disk_MS_Interface =
{ {
.Config = .Config =
{ {
.InterfaceNumber = 0, .InterfaceNumber = 0,
.DataINEndpointNumber = MASS_STORAGE_IN_EPNUM, .DataINEndpointNumber = MASS_STORAGE_IN_EPNUM,
.DataINEndpointSize = MASS_STORAGE_IO_EPSIZE, .DataINEndpointSize = MASS_STORAGE_IO_EPSIZE,
.DataINEndpointDoubleBank = false, .DataINEndpointDoubleBank = false,
.DataOUTEndpointNumber = MASS_STORAGE_OUT_EPNUM, .DataOUTEndpointNumber = MASS_STORAGE_OUT_EPNUM,
.DataOUTEndpointSize = MASS_STORAGE_IO_EPSIZE, .DataOUTEndpointSize = MASS_STORAGE_IO_EPSIZE,
.DataOUTEndpointDoubleBank = false, .DataOUTEndpointDoubleBank = false,
.TotalLUNs = TOTAL_LUNS, .TotalLUNs = TOTAL_LUNS,
}, },
}; };
/** Buffer to hold the previously generated Keyboard HID report, for comparison purposes inside the HID class driver. */ /** Buffer to hold the previously generated Keyboard HID report, for comparison purposes inside the HID class driver. */
uint8_t PrevKeyboardHIDReportBuffer[sizeof(USB_KeyboardReport_Data_t)]; uint8_t PrevKeyboardHIDReportBuffer[sizeof(USB_KeyboardReport_Data_t)];
/** LUFA HID Class driver interface configuration and state information. This structure is /** 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 * passed to all HID Class driver functions, so that multiple instances of the same class
* within a device can be differentiated from one another. * within a device can be differentiated from one another.
*/ */
USB_ClassInfo_HID_Device_t Keyboard_HID_Interface = USB_ClassInfo_HID_Device_t Keyboard_HID_Interface =
{ {
.Config = .Config =
{ {
.InterfaceNumber = 1, .InterfaceNumber = 1,
.ReportINEndpointNumber = KEYBOARD_EPNUM, .ReportINEndpointNumber = KEYBOARD_EPNUM,
.ReportINEndpointSize = KEYBOARD_EPSIZE, .ReportINEndpointSize = KEYBOARD_EPSIZE,
.ReportINEndpointDoubleBank = false, .ReportINEndpointDoubleBank = false,
.PrevReportINBuffer = PrevKeyboardHIDReportBuffer, .PrevReportINBuffer = PrevKeyboardHIDReportBuffer,
.PrevReportINBufferSize = sizeof(PrevKeyboardHIDReportBuffer), .PrevReportINBufferSize = sizeof(PrevKeyboardHIDReportBuffer),
}, },
}; };
/** Main program entry point. This routine contains the overall program flow, including initial /** Main program entry point. This routine contains the overall program flow, including initial
* setup of all components and the main program loop. * setup of all components and the main program loop.
*/ */
int main(void) int main(void)
{ {
SetupHardware(); SetupHardware();
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY); LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
sei(); sei();
for (;;) for (;;)
{ {
MS_Device_USBTask(&Disk_MS_Interface); MS_Device_USBTask(&Disk_MS_Interface);
HID_Device_USBTask(&Keyboard_HID_Interface); HID_Device_USBTask(&Keyboard_HID_Interface);
USB_USBTask(); USB_USBTask();
} }
} }
/** Configures the board hardware and chip peripherals for the demo's functionality. */ /** Configures the board hardware and chip peripherals for the demo's functionality. */
void SetupHardware(void) void SetupHardware(void)
{ {
/* Disable watchdog if enabled by bootloader/fuses */ /* Disable watchdog if enabled by bootloader/fuses */
MCUSR &= ~(1 << WDRF); MCUSR &= ~(1 << WDRF);
wdt_disable(); wdt_disable();
/* Disable clock division */ /* Disable clock division */
clock_prescale_set(clock_div_1); clock_prescale_set(clock_div_1);
/* Hardware Initialization */ /* Hardware Initialization */
LEDs_Init(); LEDs_Init();
Joystick_Init(); Joystick_Init();
Buttons_Init(); Buttons_Init();
SPI_Init(SPI_SPEED_FCPU_DIV_2 | SPI_SCK_LEAD_FALLING | SPI_SAMPLE_TRAILING | SPI_MODE_MASTER); SPI_Init(SPI_SPEED_FCPU_DIV_2 | SPI_SCK_LEAD_FALLING | SPI_SAMPLE_TRAILING | SPI_MODE_MASTER);
Dataflash_Init(); Dataflash_Init();
USB_Init(); USB_Init();
/* Clear Dataflash sector protections, if enabled */ /* Clear Dataflash sector protections, if enabled */
DataflashManager_ResetDataflashProtections(); DataflashManager_ResetDataflashProtections();
} }
/** Event handler for the library USB Connection event. */ /** Event handler for the library USB Connection event. */
void EVENT_USB_Device_Connect(void) void EVENT_USB_Device_Connect(void)
{ {
LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING); LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
} }
/** Event handler for the library USB Disconnection event. */ /** Event handler for the library USB Disconnection event. */
void EVENT_USB_Device_Disconnect(void) void EVENT_USB_Device_Disconnect(void)
{ {
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY); LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
} }
/** Event handler for the library USB Configuration Changed event. */ /** Event handler for the library USB Configuration Changed event. */
void EVENT_USB_Device_ConfigurationChanged(void) void EVENT_USB_Device_ConfigurationChanged(void)
{ {
LEDs_SetAllLEDs(LEDMASK_USB_READY); LEDs_SetAllLEDs(LEDMASK_USB_READY);
if (!(MS_Device_ConfigureEndpoints(&Disk_MS_Interface))) if (!(MS_Device_ConfigureEndpoints(&Disk_MS_Interface)))
LEDs_SetAllLEDs(LEDMASK_USB_ERROR); LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
if (!(HID_Device_ConfigureEndpoints(&Keyboard_HID_Interface))) if (!(HID_Device_ConfigureEndpoints(&Keyboard_HID_Interface)))
LEDs_SetAllLEDs(LEDMASK_USB_ERROR); LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
USB_Device_EnableSOFEvents(); USB_Device_EnableSOFEvents();
} }
/** Event handler for the library USB Unhandled Control Request event. */ /** Event handler for the library USB Unhandled Control Request event. */
void EVENT_USB_Device_UnhandledControlRequest(void) void EVENT_USB_Device_UnhandledControlRequest(void)
{ {
MS_Device_ProcessControlRequest(&Disk_MS_Interface); MS_Device_ProcessControlRequest(&Disk_MS_Interface);
HID_Device_ProcessControlRequest(&Keyboard_HID_Interface); HID_Device_ProcessControlRequest(&Keyboard_HID_Interface);
} }
/** Mass Storage class driver callback function the reception of SCSI commands from the host, which must be processed. /** Mass Storage class driver callback function the reception of SCSI commands from the host, which must be processed.
* *
* \param[in] MSInterfaceInfo Pointer to the Mass Storage class interface configuration structure being referenced * \param[in] MSInterfaceInfo Pointer to the Mass Storage class interface configuration structure being referenced
*/ */
bool CALLBACK_MS_Device_SCSICommandReceived(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) bool CALLBACK_MS_Device_SCSICommandReceived(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo)
{ {
bool CommandSuccess; bool CommandSuccess;
LEDs_SetAllLEDs(LEDMASK_USB_BUSY); LEDs_SetAllLEDs(LEDMASK_USB_BUSY);
CommandSuccess = SCSI_DecodeSCSICommand(MSInterfaceInfo); CommandSuccess = SCSI_DecodeSCSICommand(MSInterfaceInfo);
LEDs_SetAllLEDs(LEDMASK_USB_READY); LEDs_SetAllLEDs(LEDMASK_USB_READY);
return CommandSuccess; return CommandSuccess;
} }
/** Event handler for the USB device Start Of Frame event. */ /** Event handler for the USB device Start Of Frame event. */
void EVENT_USB_Device_StartOfFrame(void) void EVENT_USB_Device_StartOfFrame(void)
{ {
HID_Device_MillisecondElapsed(&Keyboard_HID_Interface); HID_Device_MillisecondElapsed(&Keyboard_HID_Interface);
} }
/** HID class driver callback function for the creation of HID reports to the host. /** HID class driver callback function for the creation of HID reports to the host.
* *
* \param[in] HIDInterfaceInfo Pointer to the HID class interface configuration structure being referenced * \param[in] HIDInterfaceInfo Pointer to the HID class interface configuration structure being referenced
* \param[in,out] ReportID Report ID requested by the host if non-zero, otherwise callback should set to the generated report ID * \param[in,out] ReportID Report ID requested by the host if non-zero, otherwise callback should set to the generated report ID
* \param[in] ReportType Type of the report to create, either REPORT_ITEM_TYPE_In or REPORT_ITEM_TYPE_Feature * \param[in] ReportType Type of the report to create, either REPORT_ITEM_TYPE_In or REPORT_ITEM_TYPE_Feature
* \param[out] ReportData Pointer to a buffer where the created report should be stored * \param[out] ReportData Pointer to a buffer where the created report should be stored
* \param[out] ReportSize Number of bytes written in the report (or zero if no report is to be sent * \param[out] ReportSize Number of bytes written in the report (or zero if no report is to be sent
* *
* \return Boolean true to force the sending of the report, false to let the library determine if it needs to be sent * \return Boolean true to force the sending of the report, false to let the library determine if it needs to be sent
*/ */
bool CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, uint8_t* const ReportID, bool CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, uint8_t* const ReportID,
const uint8_t ReportType, void* ReportData, uint16_t* ReportSize) const uint8_t ReportType, void* ReportData, uint16_t* ReportSize)
{ {
USB_KeyboardReport_Data_t* KeyboardReport = (USB_KeyboardReport_Data_t*)ReportData; USB_KeyboardReport_Data_t* KeyboardReport = (USB_KeyboardReport_Data_t*)ReportData;
uint8_t JoyStatus_LCL = Joystick_GetStatus(); uint8_t JoyStatus_LCL = Joystick_GetStatus();
uint8_t ButtonStatus_LCL = Buttons_GetStatus(); uint8_t ButtonStatus_LCL = Buttons_GetStatus();
KeyboardReport->Modifier = HID_KEYBOARD_MODIFER_LEFTSHIFT; KeyboardReport->Modifier = HID_KEYBOARD_MODIFER_LEFTSHIFT;
if (JoyStatus_LCL & JOY_UP) if (JoyStatus_LCL & JOY_UP)
KeyboardReport->KeyCode[0] = 0x04; // A KeyboardReport->KeyCode[0] = 0x04; // A
else if (JoyStatus_LCL & JOY_DOWN) else if (JoyStatus_LCL & JOY_DOWN)
KeyboardReport->KeyCode[0] = 0x05; // B KeyboardReport->KeyCode[0] = 0x05; // B
if (JoyStatus_LCL & JOY_LEFT) if (JoyStatus_LCL & JOY_LEFT)
KeyboardReport->KeyCode[0] = 0x06; // C KeyboardReport->KeyCode[0] = 0x06; // C
else if (JoyStatus_LCL & JOY_RIGHT) else if (JoyStatus_LCL & JOY_RIGHT)
KeyboardReport->KeyCode[0] = 0x07; // D KeyboardReport->KeyCode[0] = 0x07; // D
if (JoyStatus_LCL & JOY_PRESS) if (JoyStatus_LCL & JOY_PRESS)
KeyboardReport->KeyCode[0] = 0x08; // E KeyboardReport->KeyCode[0] = 0x08; // E
if (ButtonStatus_LCL & BUTTONS_BUTTON1) if (ButtonStatus_LCL & BUTTONS_BUTTON1)
KeyboardReport->KeyCode[0] = 0x09; // F KeyboardReport->KeyCode[0] = 0x09; // F
*ReportSize = sizeof(USB_KeyboardReport_Data_t); *ReportSize = sizeof(USB_KeyboardReport_Data_t);
return false; return false;
} }
/** HID class driver callback function for the processing of HID reports from the host. /** HID class driver callback function for the processing of HID reports from the host.
* *
* \param[in] HIDInterfaceInfo Pointer to the HID class interface configuration structure being referenced * \param[in] HIDInterfaceInfo Pointer to the HID class interface configuration structure being referenced
* \param[in] ReportID Report ID of the received report from the host * \param[in] ReportID Report ID of the received report from the host
* \param[in] ReportData Pointer to a buffer where the created report has been stored * \param[in] ReportData Pointer to a buffer where the created report has been stored
* \param[in] ReportSize Size in bytes of the received HID report * \param[in] ReportSize Size in bytes of the received HID report
*/ */
void CALLBACK_HID_Device_ProcessHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, const uint8_t ReportID, void CALLBACK_HID_Device_ProcessHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, const uint8_t ReportID,
const void* ReportData, const uint16_t ReportSize) const void* ReportData, const uint16_t ReportSize)
{ {
uint8_t LEDMask = LEDS_NO_LEDS; uint8_t LEDMask = LEDS_NO_LEDS;
uint8_t* LEDReport = (uint8_t*)ReportData; uint8_t* LEDReport = (uint8_t*)ReportData;
if (*LEDReport & HID_KEYBOARD_LED_NUMLOCK) if (*LEDReport & HID_KEYBOARD_LED_NUMLOCK)
LEDMask |= LEDS_LED1; LEDMask |= LEDS_LED1;
if (*LEDReport & HID_KEYBOARD_LED_CAPSLOCK) if (*LEDReport & HID_KEYBOARD_LED_CAPSLOCK)
LEDMask |= LEDS_LED3; LEDMask |= LEDS_LED3;
if (*LEDReport & HID_KEYBOARD_LED_SCROLLLOCK) if (*LEDReport & HID_KEYBOARD_LED_SCROLLLOCK)
LEDMask |= LEDS_LED4; LEDMask |= LEDS_LED4;
LEDs_SetAllLEDs(LEDMask); LEDs_SetAllLEDs(LEDMask);
} }

Some files were not shown because too many files have changed in this diff Show more