mirror of
https://github.com/qmk/qmk_firmware.git
synced 2025-06-04 15:32:45 +00:00
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:
parent
e331b531c6
commit
071e02c6b6
File diff suppressed because it is too large
Load Diff
@ -1,130 +1,130 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Header file for BootloaderCDC.c.
|
||||
*/
|
||||
|
||||
#ifndef _CDC_H_
|
||||
#define _CDC_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/io.h>
|
||||
#include <avr/wdt.h>
|
||||
#include <avr/boot.h>
|
||||
#include <avr/eeprom.h>
|
||||
#include <avr/power.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "Descriptors.h"
|
||||
|
||||
#include <LUFA/Drivers/USB/USB.h>
|
||||
|
||||
/* Macros: */
|
||||
/** 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.
|
||||
*/
|
||||
#define REQ_GetLineEncoding 0x21
|
||||
|
||||
/** 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.
|
||||
*/
|
||||
#define REQ_SetLineEncoding 0x20
|
||||
|
||||
/** 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.
|
||||
*/
|
||||
#define REQ_SetControlLineState 0x22
|
||||
|
||||
/** Version major of the CDC bootloader. */
|
||||
#define BOOTLOADER_VERSION_MAJOR 0x01
|
||||
|
||||
/** Version minor of the CDC bootloader. */
|
||||
#define BOOTLOADER_VERSION_MINOR 0x00
|
||||
|
||||
/** Hardware version major of the CDC bootloader. */
|
||||
#define BOOTLOADER_HWVERSION_MAJOR 0x01
|
||||
|
||||
/** Hardware version minor of the CDC bootloader. */
|
||||
#define BOOTLOADER_HWVERSION_MINOR 0x00
|
||||
|
||||
/** Eight character bootloader firmware identifier reported to the host when requested */
|
||||
#define SOFTWARE_IDENTIFIER "LUFACDC"
|
||||
|
||||
/* Type Defines: */
|
||||
/** 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;
|
||||
|
||||
/** 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.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t BaudRateBPS; /**< Baud rate in BPS */
|
||||
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 DataBits; /**< Size of each data chunk, in bits */
|
||||
} CDC_Line_Coding_t;
|
||||
|
||||
/* Enums: */
|
||||
/** Enum for the possible line encoding formats on a CDC-ACM virtual serial port */
|
||||
enum BootloaderCDC_CDC_LineCodingFormats_t
|
||||
{
|
||||
OneStopBit = 0, /**< Single stop bit */
|
||||
OneAndAHalfStopBits = 1, /**< 1.5 stop bits */
|
||||
TwoStopBits = 2, /**< Two stop bits */
|
||||
};
|
||||
|
||||
/** Enum for the possible parity modes on a CDC-ACM virtual serial port */
|
||||
enum BootloaderCDC_CDC_LineCodingParity_t
|
||||
{
|
||||
Parity_None = 0, /**< No data parity checking */
|
||||
Parity_Odd = 1, /**< Odd data parity checking */
|
||||
Parity_Even = 2, /**< Even data parity checking */
|
||||
Parity_Mark = 3, /**< Mark data parity checking */
|
||||
Parity_Space = 4, /**< Space data parity checking */
|
||||
};
|
||||
|
||||
/* Function Prototypes: */
|
||||
void CDC_Task(void);
|
||||
void SetupHardware(void);
|
||||
|
||||
void EVENT_USB_Device_ConfigurationChanged(void);
|
||||
void EVENT_USB_Device_UnhandledControlRequest(void);
|
||||
|
||||
#if defined(INCLUDE_FROM_BOOTLOADERCDC_C) || defined(__DOXYGEN__)
|
||||
static void ReadWriteMemoryBlock(const uint8_t Command);
|
||||
static uint8_t FetchNextCommandByte(void);
|
||||
static void WriteNextResponseByte(const uint8_t Response);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Header file for BootloaderCDC.c.
|
||||
*/
|
||||
|
||||
#ifndef _CDC_H_
|
||||
#define _CDC_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/io.h>
|
||||
#include <avr/wdt.h>
|
||||
#include <avr/boot.h>
|
||||
#include <avr/eeprom.h>
|
||||
#include <avr/power.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "Descriptors.h"
|
||||
|
||||
#include <LUFA/Drivers/USB/USB.h>
|
||||
|
||||
/* Macros: */
|
||||
/** 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.
|
||||
*/
|
||||
#define REQ_GetLineEncoding 0x21
|
||||
|
||||
/** 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.
|
||||
*/
|
||||
#define REQ_SetLineEncoding 0x20
|
||||
|
||||
/** 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.
|
||||
*/
|
||||
#define REQ_SetControlLineState 0x22
|
||||
|
||||
/** Version major of the CDC bootloader. */
|
||||
#define BOOTLOADER_VERSION_MAJOR 0x01
|
||||
|
||||
/** Version minor of the CDC bootloader. */
|
||||
#define BOOTLOADER_VERSION_MINOR 0x00
|
||||
|
||||
/** Hardware version major of the CDC bootloader. */
|
||||
#define BOOTLOADER_HWVERSION_MAJOR 0x01
|
||||
|
||||
/** Hardware version minor of the CDC bootloader. */
|
||||
#define BOOTLOADER_HWVERSION_MINOR 0x00
|
||||
|
||||
/** Eight character bootloader firmware identifier reported to the host when requested */
|
||||
#define SOFTWARE_IDENTIFIER "LUFACDC"
|
||||
|
||||
/* Type Defines: */
|
||||
/** 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;
|
||||
|
||||
/** 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.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t BaudRateBPS; /**< Baud rate in BPS */
|
||||
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 DataBits; /**< Size of each data chunk, in bits */
|
||||
} CDC_Line_Coding_t;
|
||||
|
||||
/* Enums: */
|
||||
/** Enum for the possible line encoding formats on a CDC-ACM virtual serial port */
|
||||
enum BootloaderCDC_CDC_LineCodingFormats_t
|
||||
{
|
||||
OneStopBit = 0, /**< Single stop bit */
|
||||
OneAndAHalfStopBits = 1, /**< 1.5 stop bits */
|
||||
TwoStopBits = 2, /**< Two stop bits */
|
||||
};
|
||||
|
||||
/** Enum for the possible parity modes on a CDC-ACM virtual serial port */
|
||||
enum BootloaderCDC_CDC_LineCodingParity_t
|
||||
{
|
||||
Parity_None = 0, /**< No data parity checking */
|
||||
Parity_Odd = 1, /**< Odd data parity checking */
|
||||
Parity_Even = 2, /**< Even data parity checking */
|
||||
Parity_Mark = 3, /**< Mark data parity checking */
|
||||
Parity_Space = 4, /**< Space data parity checking */
|
||||
};
|
||||
|
||||
/* Function Prototypes: */
|
||||
void CDC_Task(void);
|
||||
void SetupHardware(void);
|
||||
|
||||
void EVENT_USB_Device_ConfigurationChanged(void);
|
||||
void EVENT_USB_Device_UnhandledControlRequest(void);
|
||||
|
||||
#if defined(INCLUDE_FROM_BOOTLOADERCDC_C) || defined(__DOXYGEN__)
|
||||
static void ReadWriteMemoryBlock(const uint8_t Command);
|
||||
static uint8_t FetchNextCommandByte(void);
|
||||
static void WriteNextResponseByte(const uint8_t Response);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -1,72 +1,72 @@
|
||||
/** \file
|
||||
*
|
||||
* This file contains special DoxyGen information for the generation of the main page and other special
|
||||
* documentation pages. It is not a project source file.
|
||||
*/
|
||||
|
||||
/** \mainpage CDC Class USB AVR Bootloader
|
||||
*
|
||||
* \section SSec_Compat Demo Compatibility:
|
||||
*
|
||||
* The following list indicates what microcontrollers are compatible with this demo.
|
||||
*
|
||||
* - Series 7 USB AVRs
|
||||
* - Series 6 USB AVRs
|
||||
* - Series 4 USB AVRs
|
||||
* - Series 2 USB AVRs
|
||||
*
|
||||
* \section SSec_Info USB Information:
|
||||
*
|
||||
* The following table gives a rundown of the USB utilization of this demo.
|
||||
*
|
||||
* <table>
|
||||
* <tr>
|
||||
* <td><b>USB Mode:</b></td>
|
||||
* <td>Device</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>USB Class:</b></td>
|
||||
* <td>Communications Device Class (CDC)</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>USB Subclass:</b></td>
|
||||
* <td>Abstract Control Model (ACM)</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>Relevant Standards:</b></td>
|
||||
* <td>USBIF CDC Class Standard</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>Usable Speeds:</b></td>
|
||||
* <td>Full Speed Mode</td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*
|
||||
* \section SSec_Description Project Description:
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* 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
|
||||
* values in the accompanying makefile.
|
||||
*
|
||||
* 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
|
||||
* 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
|
||||
* device. Other Operating Systems should automatically use their own inbuilt CDC-ACM drivers.
|
||||
*
|
||||
* \section SSec_Options Project Options
|
||||
*
|
||||
* The following defines can be found in this demo, which can control the demo behaviour when defined, or changed in value.
|
||||
*
|
||||
* <table>
|
||||
* <tr>
|
||||
* <td>
|
||||
* None
|
||||
* </td>
|
||||
* </tr>
|
||||
* </table>
|
||||
/** \file
|
||||
*
|
||||
* This file contains special DoxyGen information for the generation of the main page and other special
|
||||
* documentation pages. It is not a project source file.
|
||||
*/
|
||||
|
||||
/** \mainpage CDC Class USB AVR Bootloader
|
||||
*
|
||||
* \section SSec_Compat Demo Compatibility:
|
||||
*
|
||||
* The following list indicates what microcontrollers are compatible with this demo.
|
||||
*
|
||||
* - Series 7 USB AVRs
|
||||
* - Series 6 USB AVRs
|
||||
* - Series 4 USB AVRs
|
||||
* - Series 2 USB AVRs
|
||||
*
|
||||
* \section SSec_Info USB Information:
|
||||
*
|
||||
* The following table gives a rundown of the USB utilization of this demo.
|
||||
*
|
||||
* <table>
|
||||
* <tr>
|
||||
* <td><b>USB Mode:</b></td>
|
||||
* <td>Device</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>USB Class:</b></td>
|
||||
* <td>Communications Device Class (CDC)</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>USB Subclass:</b></td>
|
||||
* <td>Abstract Control Model (ACM)</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>Relevant Standards:</b></td>
|
||||
* <td>USBIF CDC Class Standard</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>Usable Speeds:</b></td>
|
||||
* <td>Full Speed Mode</td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*
|
||||
* \section SSec_Description Project Description:
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* 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
|
||||
* values in the accompanying makefile.
|
||||
*
|
||||
* 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
|
||||
* 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
|
||||
* device. Other Operating Systems should automatically use their own inbuilt CDC-ACM drivers.
|
||||
*
|
||||
* \section SSec_Options Project Options
|
||||
*
|
||||
* The following defines can be found in this demo, which can control the demo behaviour when defined, or changed in value.
|
||||
*
|
||||
* <table>
|
||||
* <tr>
|
||||
* <td>
|
||||
* None
|
||||
* </td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*/
|
@ -1,239 +1,239 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* 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
|
||||
* the device's capabilities and functions.
|
||||
*/
|
||||
|
||||
#include "Descriptors.h"
|
||||
|
||||
/** Device descriptor structure. This descriptor, located in SRAM memory, describes the overall
|
||||
* 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
|
||||
* process begins.
|
||||
*/
|
||||
USB_Descriptor_Device_t DeviceDescriptor =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device},
|
||||
|
||||
.USBSpecification = VERSION_BCD(01.10),
|
||||
.Class = 0x02,
|
||||
.SubClass = 0x00,
|
||||
.Protocol = 0x00,
|
||||
|
||||
.Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE,
|
||||
|
||||
.VendorID = 0x03EB,
|
||||
.ProductID = 0x204A,
|
||||
.ReleaseNumber = 0x0000,
|
||||
|
||||
.ManufacturerStrIndex = NO_DESCRIPTOR,
|
||||
.ProductStrIndex = 0x01,
|
||||
.SerialNumStrIndex = NO_DESCRIPTOR,
|
||||
|
||||
.NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS
|
||||
};
|
||||
|
||||
/** 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
|
||||
* 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.
|
||||
*/
|
||||
USB_Descriptor_Configuration_t ConfigurationDescriptor =
|
||||
{
|
||||
.Config =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration},
|
||||
|
||||
.TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t),
|
||||
.TotalInterfaces = 2,
|
||||
|
||||
.ConfigurationNumber = 1,
|
||||
.ConfigurationStrIndex = NO_DESCRIPTOR,
|
||||
|
||||
.ConfigAttributes = USB_CONFIG_ATTR_BUSPOWERED,
|
||||
|
||||
.MaxPowerConsumption = USB_CONFIG_POWER_MA(100)
|
||||
},
|
||||
|
||||
.CDC_CCI_Interface =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
|
||||
|
||||
.InterfaceNumber = 0,
|
||||
.AlternateSetting = 0,
|
||||
|
||||
.TotalEndpoints = 1,
|
||||
|
||||
.Class = 0x02,
|
||||
.SubClass = 0x02,
|
||||
.Protocol = 0x01,
|
||||
|
||||
.InterfaceStrIndex = NO_DESCRIPTOR
|
||||
},
|
||||
|
||||
.CDC_Functional_IntHeader =
|
||||
{
|
||||
.Header = {.Size = sizeof(CDC_FUNCTIONAL_DESCRIPTOR(2)), .Type = 0x24},
|
||||
.SubType = 0x00,
|
||||
|
||||
.Data = {0x10, 0x01}
|
||||
},
|
||||
|
||||
.CDC_Functional_AbstractControlManagement =
|
||||
{
|
||||
.Header = {.Size = sizeof(CDC_FUNCTIONAL_DESCRIPTOR(1)), .Type = 0x24},
|
||||
.SubType = 0x02,
|
||||
|
||||
.Data = {0x06}
|
||||
},
|
||||
|
||||
.CDC_Functional_Union =
|
||||
{
|
||||
.Header = {.Size = sizeof(CDC_FUNCTIONAL_DESCRIPTOR(2)), .Type = 0x24},
|
||||
.SubType = 0x06,
|
||||
|
||||
.Data = {0x00, 0x01}
|
||||
},
|
||||
|
||||
.CDC_ManagementEndpoint =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
|
||||
|
||||
.EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_IN | CDC_NOTIFICATION_EPNUM),
|
||||
.Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
|
||||
.EndpointSize = CDC_NOTIFICATION_EPSIZE,
|
||||
.PollingIntervalMS = 0x02
|
||||
},
|
||||
|
||||
.CDC_DCI_Interface =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
|
||||
|
||||
.InterfaceNumber = 1,
|
||||
.AlternateSetting = 0,
|
||||
|
||||
.TotalEndpoints = 2,
|
||||
|
||||
.Class = 0x0A,
|
||||
.SubClass = 0x00,
|
||||
.Protocol = 0x00,
|
||||
|
||||
.InterfaceStrIndex = NO_DESCRIPTOR
|
||||
},
|
||||
|
||||
.CDC_DataOutEndpoint =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
|
||||
|
||||
.EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_OUT | CDC_RX_EPNUM),
|
||||
.Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
|
||||
.EndpointSize = CDC_TXRX_EPSIZE,
|
||||
.PollingIntervalMS = 0x00
|
||||
},
|
||||
|
||||
.CDC_DataInEndpoint =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
|
||||
|
||||
.EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_IN | CDC_TX_EPNUM),
|
||||
.Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
|
||||
.EndpointSize = CDC_TXRX_EPSIZE,
|
||||
.PollingIntervalMS = 0x00
|
||||
}
|
||||
};
|
||||
|
||||
/** 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
|
||||
* via the language ID table available at USB.org what languages the device supports for its string descriptors.
|
||||
*/
|
||||
USB_Descriptor_String_t LanguageString =
|
||||
{
|
||||
.Header = {.Size = USB_STRING_LEN(1), .Type = DTYPE_String},
|
||||
|
||||
.UnicodeString = {LANGUAGE_ID_ENG}
|
||||
};
|
||||
|
||||
/** 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
|
||||
* Descriptor.
|
||||
*/
|
||||
USB_Descriptor_String_t ProductString =
|
||||
{
|
||||
.Header = {.Size = USB_STRING_LEN(18), .Type = DTYPE_String},
|
||||
|
||||
.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"
|
||||
* 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
|
||||
* is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the
|
||||
* USB host.
|
||||
*/
|
||||
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 DescriptorNumber = (wValue & 0xFF);
|
||||
|
||||
void* Address = NULL;
|
||||
uint16_t Size = NO_DESCRIPTOR;
|
||||
|
||||
switch (DescriptorType)
|
||||
{
|
||||
case DTYPE_Device:
|
||||
Address = (void*)&DeviceDescriptor;
|
||||
Size = sizeof(USB_Descriptor_Device_t);
|
||||
break;
|
||||
case DTYPE_Configuration:
|
||||
Address = (void*)&ConfigurationDescriptor;
|
||||
Size = sizeof(USB_Descriptor_Configuration_t);
|
||||
break;
|
||||
case DTYPE_String:
|
||||
if (!(DescriptorNumber))
|
||||
{
|
||||
Address = (void*)&LanguageString;
|
||||
Size = LanguageString.Header.Size;
|
||||
}
|
||||
else
|
||||
{
|
||||
Address = (void*)&ProductString;
|
||||
Size = ProductString.Header.Size;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
*DescriptorAddress = Address;
|
||||
return Size;
|
||||
}
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* 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
|
||||
* the device's capabilities and functions.
|
||||
*/
|
||||
|
||||
#include "Descriptors.h"
|
||||
|
||||
/** Device descriptor structure. This descriptor, located in SRAM memory, describes the overall
|
||||
* 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
|
||||
* process begins.
|
||||
*/
|
||||
USB_Descriptor_Device_t DeviceDescriptor =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device},
|
||||
|
||||
.USBSpecification = VERSION_BCD(01.10),
|
||||
.Class = 0x02,
|
||||
.SubClass = 0x00,
|
||||
.Protocol = 0x00,
|
||||
|
||||
.Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE,
|
||||
|
||||
.VendorID = 0x03EB,
|
||||
.ProductID = 0x204A,
|
||||
.ReleaseNumber = 0x0000,
|
||||
|
||||
.ManufacturerStrIndex = NO_DESCRIPTOR,
|
||||
.ProductStrIndex = 0x01,
|
||||
.SerialNumStrIndex = NO_DESCRIPTOR,
|
||||
|
||||
.NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS
|
||||
};
|
||||
|
||||
/** 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
|
||||
* 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.
|
||||
*/
|
||||
USB_Descriptor_Configuration_t ConfigurationDescriptor =
|
||||
{
|
||||
.Config =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration},
|
||||
|
||||
.TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t),
|
||||
.TotalInterfaces = 2,
|
||||
|
||||
.ConfigurationNumber = 1,
|
||||
.ConfigurationStrIndex = NO_DESCRIPTOR,
|
||||
|
||||
.ConfigAttributes = USB_CONFIG_ATTR_BUSPOWERED,
|
||||
|
||||
.MaxPowerConsumption = USB_CONFIG_POWER_MA(100)
|
||||
},
|
||||
|
||||
.CDC_CCI_Interface =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
|
||||
|
||||
.InterfaceNumber = 0,
|
||||
.AlternateSetting = 0,
|
||||
|
||||
.TotalEndpoints = 1,
|
||||
|
||||
.Class = 0x02,
|
||||
.SubClass = 0x02,
|
||||
.Protocol = 0x01,
|
||||
|
||||
.InterfaceStrIndex = NO_DESCRIPTOR
|
||||
},
|
||||
|
||||
.CDC_Functional_IntHeader =
|
||||
{
|
||||
.Header = {.Size = sizeof(CDC_FUNCTIONAL_DESCRIPTOR(2)), .Type = 0x24},
|
||||
.SubType = 0x00,
|
||||
|
||||
.Data = {0x10, 0x01}
|
||||
},
|
||||
|
||||
.CDC_Functional_AbstractControlManagement =
|
||||
{
|
||||
.Header = {.Size = sizeof(CDC_FUNCTIONAL_DESCRIPTOR(1)), .Type = 0x24},
|
||||
.SubType = 0x02,
|
||||
|
||||
.Data = {0x06}
|
||||
},
|
||||
|
||||
.CDC_Functional_Union =
|
||||
{
|
||||
.Header = {.Size = sizeof(CDC_FUNCTIONAL_DESCRIPTOR(2)), .Type = 0x24},
|
||||
.SubType = 0x06,
|
||||
|
||||
.Data = {0x00, 0x01}
|
||||
},
|
||||
|
||||
.CDC_ManagementEndpoint =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
|
||||
|
||||
.EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_IN | CDC_NOTIFICATION_EPNUM),
|
||||
.Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
|
||||
.EndpointSize = CDC_NOTIFICATION_EPSIZE,
|
||||
.PollingIntervalMS = 0x02
|
||||
},
|
||||
|
||||
.CDC_DCI_Interface =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
|
||||
|
||||
.InterfaceNumber = 1,
|
||||
.AlternateSetting = 0,
|
||||
|
||||
.TotalEndpoints = 2,
|
||||
|
||||
.Class = 0x0A,
|
||||
.SubClass = 0x00,
|
||||
.Protocol = 0x00,
|
||||
|
||||
.InterfaceStrIndex = NO_DESCRIPTOR
|
||||
},
|
||||
|
||||
.CDC_DataOutEndpoint =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
|
||||
|
||||
.EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_OUT | CDC_RX_EPNUM),
|
||||
.Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
|
||||
.EndpointSize = CDC_TXRX_EPSIZE,
|
||||
.PollingIntervalMS = 0x00
|
||||
},
|
||||
|
||||
.CDC_DataInEndpoint =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
|
||||
|
||||
.EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_IN | CDC_TX_EPNUM),
|
||||
.Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
|
||||
.EndpointSize = CDC_TXRX_EPSIZE,
|
||||
.PollingIntervalMS = 0x00
|
||||
}
|
||||
};
|
||||
|
||||
/** 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
|
||||
* via the language ID table available at USB.org what languages the device supports for its string descriptors.
|
||||
*/
|
||||
USB_Descriptor_String_t LanguageString =
|
||||
{
|
||||
.Header = {.Size = USB_STRING_LEN(1), .Type = DTYPE_String},
|
||||
|
||||
.UnicodeString = {LANGUAGE_ID_ENG}
|
||||
};
|
||||
|
||||
/** 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
|
||||
* Descriptor.
|
||||
*/
|
||||
USB_Descriptor_String_t ProductString =
|
||||
{
|
||||
.Header = {.Size = USB_STRING_LEN(18), .Type = DTYPE_String},
|
||||
|
||||
.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"
|
||||
* 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
|
||||
* is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the
|
||||
* USB host.
|
||||
*/
|
||||
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 DescriptorNumber = (wValue & 0xFF);
|
||||
|
||||
void* Address = NULL;
|
||||
uint16_t Size = NO_DESCRIPTOR;
|
||||
|
||||
switch (DescriptorType)
|
||||
{
|
||||
case DTYPE_Device:
|
||||
Address = (void*)&DeviceDescriptor;
|
||||
Size = sizeof(USB_Descriptor_Device_t);
|
||||
break;
|
||||
case DTYPE_Configuration:
|
||||
Address = (void*)&ConfigurationDescriptor;
|
||||
Size = sizeof(USB_Descriptor_Configuration_t);
|
||||
break;
|
||||
case DTYPE_String:
|
||||
if (!(DescriptorNumber))
|
||||
{
|
||||
Address = (void*)&LanguageString;
|
||||
Size = LanguageString.Header.Size;
|
||||
}
|
||||
else
|
||||
{
|
||||
Address = (void*)&ProductString;
|
||||
Size = ProductString.Header.Size;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
*DescriptorAddress = Address;
|
||||
return Size;
|
||||
}
|
||||
|
@ -1,146 +1,146 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Header file for Descriptors.c.
|
||||
*/
|
||||
|
||||
#ifndef _DESCRIPTORS_H_
|
||||
#define _DESCRIPTORS_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <LUFA/Drivers/USB/USB.h>
|
||||
|
||||
/* Macros: */
|
||||
#if defined(__AVR_AT90USB1287__)
|
||||
#define AVR_SIGNATURE_1 0x1E
|
||||
#define AVR_SIGNATURE_2 0x97
|
||||
#define AVR_SIGNATURE_3 0x82
|
||||
#elif defined(__AVR_AT90USB647__)
|
||||
#define AVR_SIGNATURE_1 0x1E
|
||||
#define AVR_SIGNATURE_2 0x96
|
||||
#define AVR_SIGNATURE_3 0x82
|
||||
#elif defined(__AVR_AT90USB1286__)
|
||||
#define AVR_SIGNATURE_1 0x1E
|
||||
#define AVR_SIGNATURE_2 0x97
|
||||
#define AVR_SIGNATURE_3 0x82
|
||||
#elif defined(__AVR_AT90USB646__)
|
||||
#define AVR_SIGNATURE_1 0x1E
|
||||
#define AVR_SIGNATURE_2 0x96
|
||||
#define AVR_SIGNATURE_3 0x82
|
||||
#elif defined(__AVR_ATmega32U6__)
|
||||
#define AVR_SIGNATURE_1 0x1E
|
||||
#define AVR_SIGNATURE_2 0x95
|
||||
#define AVR_SIGNATURE_3 0x88
|
||||
#elif defined(__AVR_ATmega32U4__)
|
||||
#define AVR_SIGNATURE_1 0x1E
|
||||
#define AVR_SIGNATURE_2 0x95
|
||||
#define AVR_SIGNATURE_3 0x87
|
||||
#elif defined(__AVR_ATmega16U4__)
|
||||
#define AVR_SIGNATURE_1 0x1E
|
||||
#define AVR_SIGNATURE_2 0x94
|
||||
#define AVR_SIGNATURE_3 0x88
|
||||
#elif defined(__AVR_ATmega32U2__)
|
||||
#define AVR_SIGNATURE_1 0x1E
|
||||
#define AVR_SIGNATURE_2 0x94
|
||||
#define AVR_SIGNATURE_3 0x82
|
||||
#elif defined(__AVR_ATmega16U2__)
|
||||
#define AVR_SIGNATURE_1 0x1E
|
||||
#define AVR_SIGNATURE_2 0x94
|
||||
#define AVR_SIGNATURE_3 0x89
|
||||
#elif defined(__AVR_AT90USB162__)
|
||||
#define AVR_SIGNATURE_1 0x1E
|
||||
#define AVR_SIGNATURE_2 0x94
|
||||
#define AVR_SIGNATURE_3 0x82
|
||||
#elif defined(__AVR_ATmega8U2__)
|
||||
#define AVR_SIGNATURE_1 0x1E
|
||||
#define AVR_SIGNATURE_2 0x93
|
||||
#define AVR_SIGNATURE_3 0x82
|
||||
#elif defined(__AVR_AT90USB82__)
|
||||
#define AVR_SIGNATURE_1 0x1E
|
||||
#define AVR_SIGNATURE_2 0x93
|
||||
#define AVR_SIGNATURE_3 0x89
|
||||
#else
|
||||
#error The selected AVR part is not currently supported by this bootloader.
|
||||
#endif
|
||||
|
||||
/** 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,
|
||||
* while allowing the sizeof() operator to return correct results.
|
||||
*
|
||||
* \param[in] DataSize Size of the functional descriptor's data payload, in bytes
|
||||
*/
|
||||
#define CDC_FUNCTIONAL_DESCRIPTOR(DataSize) \
|
||||
struct \
|
||||
{ \
|
||||
USB_Descriptor_Header_t Header; \
|
||||
uint8_t SubType; \
|
||||
uint8_t Data[DataSize]; \
|
||||
}
|
||||
|
||||
/** Endpoint number for the CDC control interface event notification endpoint. */
|
||||
#define CDC_NOTIFICATION_EPNUM 3
|
||||
|
||||
/** Size of the CDC control interface notification endpoint bank, in bytes */
|
||||
#define CDC_NOTIFICATION_EPSIZE 8
|
||||
|
||||
/** Endpoint number for the CDC data interface TX (data IN) endpoint */
|
||||
#define CDC_TX_EPNUM 1
|
||||
|
||||
/** Endpoint number for the CDC data interface RX (data OUT) endpoint */
|
||||
#define CDC_RX_EPNUM 2
|
||||
|
||||
/** Size of the CDC data interface TX and RX data endpoint banks, in bytes */
|
||||
#define CDC_TXRX_EPSIZE 16
|
||||
|
||||
/* Type Defines: */
|
||||
/** 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
|
||||
* vary between devices, and which describe the device's usage to the host.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
USB_Descriptor_Configuration_Header_t Config;
|
||||
USB_Descriptor_Interface_t CDC_CCI_Interface;
|
||||
CDC_FUNCTIONAL_DESCRIPTOR(2) CDC_Functional_IntHeader;
|
||||
CDC_FUNCTIONAL_DESCRIPTOR(1) CDC_Functional_AbstractControlManagement;
|
||||
CDC_FUNCTIONAL_DESCRIPTOR(2) CDC_Functional_Union;
|
||||
USB_Descriptor_Endpoint_t CDC_ManagementEndpoint;
|
||||
USB_Descriptor_Interface_t CDC_DCI_Interface;
|
||||
USB_Descriptor_Endpoint_t CDC_DataOutEndpoint;
|
||||
USB_Descriptor_Endpoint_t CDC_DataInEndpoint;
|
||||
} USB_Descriptor_Configuration_t;
|
||||
|
||||
/* Function Prototypes: */
|
||||
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);
|
||||
|
||||
#endif
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Header file for Descriptors.c.
|
||||
*/
|
||||
|
||||
#ifndef _DESCRIPTORS_H_
|
||||
#define _DESCRIPTORS_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <LUFA/Drivers/USB/USB.h>
|
||||
|
||||
/* Macros: */
|
||||
#if defined(__AVR_AT90USB1287__)
|
||||
#define AVR_SIGNATURE_1 0x1E
|
||||
#define AVR_SIGNATURE_2 0x97
|
||||
#define AVR_SIGNATURE_3 0x82
|
||||
#elif defined(__AVR_AT90USB647__)
|
||||
#define AVR_SIGNATURE_1 0x1E
|
||||
#define AVR_SIGNATURE_2 0x96
|
||||
#define AVR_SIGNATURE_3 0x82
|
||||
#elif defined(__AVR_AT90USB1286__)
|
||||
#define AVR_SIGNATURE_1 0x1E
|
||||
#define AVR_SIGNATURE_2 0x97
|
||||
#define AVR_SIGNATURE_3 0x82
|
||||
#elif defined(__AVR_AT90USB646__)
|
||||
#define AVR_SIGNATURE_1 0x1E
|
||||
#define AVR_SIGNATURE_2 0x96
|
||||
#define AVR_SIGNATURE_3 0x82
|
||||
#elif defined(__AVR_ATmega32U6__)
|
||||
#define AVR_SIGNATURE_1 0x1E
|
||||
#define AVR_SIGNATURE_2 0x95
|
||||
#define AVR_SIGNATURE_3 0x88
|
||||
#elif defined(__AVR_ATmega32U4__)
|
||||
#define AVR_SIGNATURE_1 0x1E
|
||||
#define AVR_SIGNATURE_2 0x95
|
||||
#define AVR_SIGNATURE_3 0x87
|
||||
#elif defined(__AVR_ATmega16U4__)
|
||||
#define AVR_SIGNATURE_1 0x1E
|
||||
#define AVR_SIGNATURE_2 0x94
|
||||
#define AVR_SIGNATURE_3 0x88
|
||||
#elif defined(__AVR_ATmega32U2__)
|
||||
#define AVR_SIGNATURE_1 0x1E
|
||||
#define AVR_SIGNATURE_2 0x94
|
||||
#define AVR_SIGNATURE_3 0x82
|
||||
#elif defined(__AVR_ATmega16U2__)
|
||||
#define AVR_SIGNATURE_1 0x1E
|
||||
#define AVR_SIGNATURE_2 0x94
|
||||
#define AVR_SIGNATURE_3 0x89
|
||||
#elif defined(__AVR_AT90USB162__)
|
||||
#define AVR_SIGNATURE_1 0x1E
|
||||
#define AVR_SIGNATURE_2 0x94
|
||||
#define AVR_SIGNATURE_3 0x82
|
||||
#elif defined(__AVR_ATmega8U2__)
|
||||
#define AVR_SIGNATURE_1 0x1E
|
||||
#define AVR_SIGNATURE_2 0x93
|
||||
#define AVR_SIGNATURE_3 0x82
|
||||
#elif defined(__AVR_AT90USB82__)
|
||||
#define AVR_SIGNATURE_1 0x1E
|
||||
#define AVR_SIGNATURE_2 0x93
|
||||
#define AVR_SIGNATURE_3 0x89
|
||||
#else
|
||||
#error The selected AVR part is not currently supported by this bootloader.
|
||||
#endif
|
||||
|
||||
/** 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,
|
||||
* while allowing the sizeof() operator to return correct results.
|
||||
*
|
||||
* \param[in] DataSize Size of the functional descriptor's data payload, in bytes
|
||||
*/
|
||||
#define CDC_FUNCTIONAL_DESCRIPTOR(DataSize) \
|
||||
struct \
|
||||
{ \
|
||||
USB_Descriptor_Header_t Header; \
|
||||
uint8_t SubType; \
|
||||
uint8_t Data[DataSize]; \
|
||||
}
|
||||
|
||||
/** Endpoint number for the CDC control interface event notification endpoint. */
|
||||
#define CDC_NOTIFICATION_EPNUM 3
|
||||
|
||||
/** Size of the CDC control interface notification endpoint bank, in bytes */
|
||||
#define CDC_NOTIFICATION_EPSIZE 8
|
||||
|
||||
/** Endpoint number for the CDC data interface TX (data IN) endpoint */
|
||||
#define CDC_TX_EPNUM 1
|
||||
|
||||
/** Endpoint number for the CDC data interface RX (data OUT) endpoint */
|
||||
#define CDC_RX_EPNUM 2
|
||||
|
||||
/** Size of the CDC data interface TX and RX data endpoint banks, in bytes */
|
||||
#define CDC_TXRX_EPSIZE 16
|
||||
|
||||
/* Type Defines: */
|
||||
/** 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
|
||||
* vary between devices, and which describe the device's usage to the host.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
USB_Descriptor_Configuration_Header_t Config;
|
||||
USB_Descriptor_Interface_t CDC_CCI_Interface;
|
||||
CDC_FUNCTIONAL_DESCRIPTOR(2) CDC_Functional_IntHeader;
|
||||
CDC_FUNCTIONAL_DESCRIPTOR(1) CDC_Functional_AbstractControlManagement;
|
||||
CDC_FUNCTIONAL_DESCRIPTOR(2) CDC_Functional_Union;
|
||||
USB_Descriptor_Endpoint_t CDC_ManagementEndpoint;
|
||||
USB_Descriptor_Interface_t CDC_DCI_Interface;
|
||||
USB_Descriptor_Endpoint_t CDC_DataOutEndpoint;
|
||||
USB_Descriptor_Endpoint_t CDC_DataInEndpoint;
|
||||
} USB_Descriptor_Configuration_t;
|
||||
|
||||
/* Function Prototypes: */
|
||||
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);
|
||||
|
||||
#endif
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,106 +1,106 @@
|
||||
;************************************************************
|
||||
; Windows USB CDC ACM Setup File
|
||||
; Copyright (c) 2000 Microsoft Corporation
|
||||
|
||||
|
||||
[Version]
|
||||
Signature="$Windows NT$"
|
||||
Class=Ports
|
||||
ClassGuid={4D36E978-E325-11CE-BFC1-08002BE10318}
|
||||
Provider=%MFGNAME%
|
||||
LayoutFile=layout.inf
|
||||
CatalogFile=%MFGFILENAME%.cat
|
||||
DriverVer=11/15/2007,5.1.2600.0
|
||||
|
||||
[Manufacturer]
|
||||
%MFGNAME%=DeviceList, NTamd64
|
||||
|
||||
[DestinationDirs]
|
||||
DefaultDestDir=12
|
||||
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; Windows 2000/XP/Vista-32bit Sections
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
[DriverInstall.nt]
|
||||
include=mdmcpq.inf
|
||||
CopyFiles=DriverCopyFiles.nt
|
||||
AddReg=DriverInstall.nt.AddReg
|
||||
|
||||
[DriverCopyFiles.nt]
|
||||
usbser.sys,,,0x20
|
||||
|
||||
[DriverInstall.nt.AddReg]
|
||||
HKR,,DevLoader,,*ntkern
|
||||
HKR,,NTMPDriver,,%DRIVERFILENAME%.sys
|
||||
HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider"
|
||||
|
||||
[DriverInstall.nt.Services]
|
||||
AddService=usbser, 0x00000002, DriverService.nt
|
||||
|
||||
[DriverService.nt]
|
||||
DisplayName=%SERVICE%
|
||||
ServiceType=1
|
||||
StartType=3
|
||||
ErrorControl=1
|
||||
ServiceBinary=%12%\%DRIVERFILENAME%.sys
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; Vista-64bit Sections
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
[DriverInstall.NTamd64]
|
||||
include=mdmcpq.inf
|
||||
CopyFiles=DriverCopyFiles.NTamd64
|
||||
AddReg=DriverInstall.NTamd64.AddReg
|
||||
|
||||
[DriverCopyFiles.NTamd64]
|
||||
%DRIVERFILENAME%.sys,,,0x20
|
||||
|
||||
[DriverInstall.NTamd64.AddReg]
|
||||
HKR,,DevLoader,,*ntkern
|
||||
HKR,,NTMPDriver,,%DRIVERFILENAME%.sys
|
||||
HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider"
|
||||
|
||||
[DriverInstall.NTamd64.Services]
|
||||
AddService=usbser, 0x00000002, DriverService.NTamd64
|
||||
|
||||
[DriverService.NTamd64]
|
||||
DisplayName=%SERVICE%
|
||||
ServiceType=1
|
||||
StartType=3
|
||||
ErrorControl=1
|
||||
ServiceBinary=%12%\%DRIVERFILENAME%.sys
|
||||
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; Vendor and Product ID Definitions
|
||||
;------------------------------------------------------------------------------
|
||||
; When developing your USB device, the VID and PID used in the PC side
|
||||
; 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.
|
||||
; 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.
|
||||
;------------------------------------------------------------------------------
|
||||
[SourceDisksFiles]
|
||||
[SourceDisksNames]
|
||||
[DeviceList]
|
||||
%DESCRIPTION%=DriverInstall, USB\VID_03EB&PID_204A
|
||||
|
||||
[DeviceList.NTamd64]
|
||||
%DESCRIPTION%=DriverInstall, USB\VID_03EB&PID_204A
|
||||
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; String Definitions
|
||||
;------------------------------------------------------------------------------
|
||||
;Modify these strings to customize your device
|
||||
;------------------------------------------------------------------------------
|
||||
[Strings]
|
||||
MFGFILENAME="CDC_vista"
|
||||
DRIVERFILENAME ="usbser"
|
||||
MFGNAME="http://www.fourwalledcubicle.com"
|
||||
INSTDISK="LUFA CDC Bootloader Driver Installer"
|
||||
DESCRIPTION="Communications Port"
|
||||
;************************************************************
|
||||
; Windows USB CDC ACM Setup File
|
||||
; Copyright (c) 2000 Microsoft Corporation
|
||||
|
||||
|
||||
[Version]
|
||||
Signature="$Windows NT$"
|
||||
Class=Ports
|
||||
ClassGuid={4D36E978-E325-11CE-BFC1-08002BE10318}
|
||||
Provider=%MFGNAME%
|
||||
LayoutFile=layout.inf
|
||||
CatalogFile=%MFGFILENAME%.cat
|
||||
DriverVer=11/15/2007,5.1.2600.0
|
||||
|
||||
[Manufacturer]
|
||||
%MFGNAME%=DeviceList, NTamd64
|
||||
|
||||
[DestinationDirs]
|
||||
DefaultDestDir=12
|
||||
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; Windows 2000/XP/Vista-32bit Sections
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
[DriverInstall.nt]
|
||||
include=mdmcpq.inf
|
||||
CopyFiles=DriverCopyFiles.nt
|
||||
AddReg=DriverInstall.nt.AddReg
|
||||
|
||||
[DriverCopyFiles.nt]
|
||||
usbser.sys,,,0x20
|
||||
|
||||
[DriverInstall.nt.AddReg]
|
||||
HKR,,DevLoader,,*ntkern
|
||||
HKR,,NTMPDriver,,%DRIVERFILENAME%.sys
|
||||
HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider"
|
||||
|
||||
[DriverInstall.nt.Services]
|
||||
AddService=usbser, 0x00000002, DriverService.nt
|
||||
|
||||
[DriverService.nt]
|
||||
DisplayName=%SERVICE%
|
||||
ServiceType=1
|
||||
StartType=3
|
||||
ErrorControl=1
|
||||
ServiceBinary=%12%\%DRIVERFILENAME%.sys
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; Vista-64bit Sections
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
[DriverInstall.NTamd64]
|
||||
include=mdmcpq.inf
|
||||
CopyFiles=DriverCopyFiles.NTamd64
|
||||
AddReg=DriverInstall.NTamd64.AddReg
|
||||
|
||||
[DriverCopyFiles.NTamd64]
|
||||
%DRIVERFILENAME%.sys,,,0x20
|
||||
|
||||
[DriverInstall.NTamd64.AddReg]
|
||||
HKR,,DevLoader,,*ntkern
|
||||
HKR,,NTMPDriver,,%DRIVERFILENAME%.sys
|
||||
HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider"
|
||||
|
||||
[DriverInstall.NTamd64.Services]
|
||||
AddService=usbser, 0x00000002, DriverService.NTamd64
|
||||
|
||||
[DriverService.NTamd64]
|
||||
DisplayName=%SERVICE%
|
||||
ServiceType=1
|
||||
StartType=3
|
||||
ErrorControl=1
|
||||
ServiceBinary=%12%\%DRIVERFILENAME%.sys
|
||||
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; Vendor and Product ID Definitions
|
||||
;------------------------------------------------------------------------------
|
||||
; When developing your USB device, the VID and PID used in the PC side
|
||||
; 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.
|
||||
; 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.
|
||||
;------------------------------------------------------------------------------
|
||||
[SourceDisksFiles]
|
||||
[SourceDisksNames]
|
||||
[DeviceList]
|
||||
%DESCRIPTION%=DriverInstall, USB\VID_03EB&PID_204A
|
||||
|
||||
[DeviceList.NTamd64]
|
||||
%DESCRIPTION%=DriverInstall, USB\VID_03EB&PID_204A
|
||||
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; String Definitions
|
||||
;------------------------------------------------------------------------------
|
||||
;Modify these strings to customize your device
|
||||
;------------------------------------------------------------------------------
|
||||
[Strings]
|
||||
MFGFILENAME="CDC_vista"
|
||||
DRIVERFILENAME ="usbser"
|
||||
MFGNAME="http://www.fourwalledcubicle.com"
|
||||
INSTDISK="LUFA CDC Bootloader Driver Installer"
|
||||
DESCRIPTION="Communications Port"
|
||||
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
@ -1,207 +1,207 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Header file for BootloaderDFU.c.
|
||||
*/
|
||||
|
||||
#ifndef _BOOTLOADER_H_
|
||||
#define _BOOTLOADER_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/io.h>
|
||||
#include <avr/wdt.h>
|
||||
#include <avr/boot.h>
|
||||
#include <avr/pgmspace.h>
|
||||
#include <avr/eeprom.h>
|
||||
#include <avr/power.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "Descriptors.h"
|
||||
|
||||
#include <LUFA/Drivers/USB/USB.h>
|
||||
|
||||
/* Macros: */
|
||||
/** 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
|
||||
* can protect the AVR's firmware from being dumped from a secured AVR. When false, memory operations are
|
||||
* allowed at any time.
|
||||
*/
|
||||
#define SECURE_MODE false
|
||||
|
||||
/** Major bootloader version number. */
|
||||
#define BOOTLOADER_VERSION_MINOR 2
|
||||
|
||||
/** Minor bootloader version number. */
|
||||
#define BOOTLOADER_VERSION_REV 0
|
||||
|
||||
/** Complete bootloader version number expressed as a packed byte, constructed from the
|
||||
* two individual bootloader version macros.
|
||||
*/
|
||||
#define BOOTLOADER_VERSION ((BOOTLOADER_VERSION_MINOR << 4) | BOOTLOADER_VERSION_REV)
|
||||
|
||||
/** First byte of the bootloader identification bytes, used to identify a device's bootloader. */
|
||||
#define BOOTLOADER_ID_BYTE1 0xDC
|
||||
|
||||
/** Second byte of the bootloader identification bytes, used to identify a device's bootloader. */
|
||||
#define BOOTLOADER_ID_BYTE2 0xFB
|
||||
|
||||
/** 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] cb1 First command byte to check
|
||||
*/
|
||||
#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.
|
||||
*
|
||||
* \param[in] dataarr Command byte array to check against
|
||||
* \param[in] cb1 First 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)))
|
||||
|
||||
/** 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
|
||||
* a CRC of the complete firmware for error checking) and so is discarded.
|
||||
*/
|
||||
#define DFU_FILE_SUFFIX_SIZE 16
|
||||
|
||||
/** 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.
|
||||
*/
|
||||
#define DFU_FILLER_BYTES_SIZE 26
|
||||
|
||||
/** DFU class command request to detach from the host. */
|
||||
#define DFU_DETATCH 0x00
|
||||
|
||||
/** DFU class command request to send data from the host to the bootloader. */
|
||||
#define DFU_DNLOAD 0x01
|
||||
|
||||
/** DFU class command request to send data from the bootloader to the host. */
|
||||
#define DFU_UPLOAD 0x02
|
||||
|
||||
/** DFU class command request to get the current DFU status and state from the bootloader. */
|
||||
#define DFU_GETSTATUS 0x03
|
||||
|
||||
/** DFU class command request to reset the current DFU status and state variables to their defaults. */
|
||||
#define DFU_CLRSTATUS 0x04
|
||||
|
||||
/** DFU class command request to get the current DFU state of the bootloader. */
|
||||
#define DFU_GETSTATE 0x05
|
||||
|
||||
/** DFU class command request to abort the current multi-request transfer and return to the dfuIDLE state. */
|
||||
#define DFU_ABORT 0x06
|
||||
|
||||
/** DFU command to begin programming the device's memory. */
|
||||
#define COMMAND_PROG_START 0x01
|
||||
|
||||
/** DFU command to begin reading the device's memory. */
|
||||
#define COMMAND_DISP_DATA 0x03
|
||||
|
||||
/** DFU command to issue a write command. */
|
||||
#define COMMAND_WRITE 0x04
|
||||
|
||||
/** DFU command to issue a read command. */
|
||||
#define COMMAND_READ 0x05
|
||||
|
||||
/** DFU command to issue a memory base address change command, to set the current 64KB flash page
|
||||
* that subsequent flash operations should use. */
|
||||
#define COMMAND_CHANGE_BASE_ADDR 0x06
|
||||
|
||||
/* Type Defines: */
|
||||
/** Type define for a non-returning function pointer to the loaded application. */
|
||||
typedef void (*AppPtr_t)(void) ATTR_NO_RETURN;
|
||||
|
||||
/** Type define for a structure containing a complete DFU command issued by the host. */
|
||||
typedef struct
|
||||
{
|
||||
uint8_t Command; /**< Single byte command to perform, one of the COMMAND_* macro values */
|
||||
uint8_t Data[5]; /**< Command parameters */
|
||||
uint16_t DataSize; /**< Size of the command parameters */
|
||||
} DFU_Command_t;
|
||||
|
||||
/* Enums: */
|
||||
/** DFU bootloader states. Refer to the DFU class specification for information on each state. */
|
||||
enum DFU_State_t
|
||||
{
|
||||
appIDLE = 0,
|
||||
appDETACH = 1,
|
||||
dfuIDLE = 2,
|
||||
dfuDNLOAD_SYNC = 3,
|
||||
dfuDNBUSY = 4,
|
||||
dfuDNLOAD_IDLE = 5,
|
||||
dfuMANIFEST_SYNC = 6,
|
||||
dfuMANIFEST = 7,
|
||||
dfuMANIFEST_WAIT_RESET = 8,
|
||||
dfuUPLOAD_IDLE = 9,
|
||||
dfuERROR = 10
|
||||
};
|
||||
|
||||
/** DFU command status error codes. Refer to the DFU class specification for information on each error code. */
|
||||
enum DFU_Status_t
|
||||
{
|
||||
OK = 0,
|
||||
errTARGET = 1,
|
||||
errFILE = 2,
|
||||
errWRITE = 3,
|
||||
errERASE = 4,
|
||||
errCHECK_ERASED = 5,
|
||||
errPROG = 6,
|
||||
errVERIFY = 7,
|
||||
errADDRESS = 8,
|
||||
errNOTDONE = 9,
|
||||
errFIRMWARE = 10,
|
||||
errVENDOR = 11,
|
||||
errUSBR = 12,
|
||||
errPOR = 13,
|
||||
errUNKNOWN = 14,
|
||||
errSTALLEDPKT = 15
|
||||
};
|
||||
|
||||
/* Function Prototypes: */
|
||||
void SetupHardware(void);
|
||||
void ResetHardware(void);
|
||||
|
||||
void EVENT_USB_Device_UnhandledControlRequest(void);
|
||||
|
||||
#if defined(INCLUDE_FROM_BOOTLOADER_C)
|
||||
static void DiscardFillerBytes(uint8_t NumberOfBytes);
|
||||
static void ProcessBootloaderCommand(void);
|
||||
static void LoadStartEndAddresses(void);
|
||||
static void ProcessMemProgCommand(void);
|
||||
static void ProcessMemReadCommand(void);
|
||||
static void ProcessWriteCommand(void);
|
||||
static void ProcessReadCommand(void);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Header file for BootloaderDFU.c.
|
||||
*/
|
||||
|
||||
#ifndef _BOOTLOADER_H_
|
||||
#define _BOOTLOADER_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/io.h>
|
||||
#include <avr/wdt.h>
|
||||
#include <avr/boot.h>
|
||||
#include <avr/pgmspace.h>
|
||||
#include <avr/eeprom.h>
|
||||
#include <avr/power.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "Descriptors.h"
|
||||
|
||||
#include <LUFA/Drivers/USB/USB.h>
|
||||
|
||||
/* Macros: */
|
||||
/** 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
|
||||
* can protect the AVR's firmware from being dumped from a secured AVR. When false, memory operations are
|
||||
* allowed at any time.
|
||||
*/
|
||||
#define SECURE_MODE false
|
||||
|
||||
/** Major bootloader version number. */
|
||||
#define BOOTLOADER_VERSION_MINOR 2
|
||||
|
||||
/** Minor bootloader version number. */
|
||||
#define BOOTLOADER_VERSION_REV 0
|
||||
|
||||
/** Complete bootloader version number expressed as a packed byte, constructed from the
|
||||
* two individual bootloader version macros.
|
||||
*/
|
||||
#define BOOTLOADER_VERSION ((BOOTLOADER_VERSION_MINOR << 4) | BOOTLOADER_VERSION_REV)
|
||||
|
||||
/** First byte of the bootloader identification bytes, used to identify a device's bootloader. */
|
||||
#define BOOTLOADER_ID_BYTE1 0xDC
|
||||
|
||||
/** Second byte of the bootloader identification bytes, used to identify a device's bootloader. */
|
||||
#define BOOTLOADER_ID_BYTE2 0xFB
|
||||
|
||||
/** 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] cb1 First command byte to check
|
||||
*/
|
||||
#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.
|
||||
*
|
||||
* \param[in] dataarr Command byte array to check against
|
||||
* \param[in] cb1 First 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)))
|
||||
|
||||
/** 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
|
||||
* a CRC of the complete firmware for error checking) and so is discarded.
|
||||
*/
|
||||
#define DFU_FILE_SUFFIX_SIZE 16
|
||||
|
||||
/** 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.
|
||||
*/
|
||||
#define DFU_FILLER_BYTES_SIZE 26
|
||||
|
||||
/** DFU class command request to detach from the host. */
|
||||
#define DFU_DETATCH 0x00
|
||||
|
||||
/** DFU class command request to send data from the host to the bootloader. */
|
||||
#define DFU_DNLOAD 0x01
|
||||
|
||||
/** DFU class command request to send data from the bootloader to the host. */
|
||||
#define DFU_UPLOAD 0x02
|
||||
|
||||
/** DFU class command request to get the current DFU status and state from the bootloader. */
|
||||
#define DFU_GETSTATUS 0x03
|
||||
|
||||
/** DFU class command request to reset the current DFU status and state variables to their defaults. */
|
||||
#define DFU_CLRSTATUS 0x04
|
||||
|
||||
/** DFU class command request to get the current DFU state of the bootloader. */
|
||||
#define DFU_GETSTATE 0x05
|
||||
|
||||
/** DFU class command request to abort the current multi-request transfer and return to the dfuIDLE state. */
|
||||
#define DFU_ABORT 0x06
|
||||
|
||||
/** DFU command to begin programming the device's memory. */
|
||||
#define COMMAND_PROG_START 0x01
|
||||
|
||||
/** DFU command to begin reading the device's memory. */
|
||||
#define COMMAND_DISP_DATA 0x03
|
||||
|
||||
/** DFU command to issue a write command. */
|
||||
#define COMMAND_WRITE 0x04
|
||||
|
||||
/** DFU command to issue a read command. */
|
||||
#define COMMAND_READ 0x05
|
||||
|
||||
/** DFU command to issue a memory base address change command, to set the current 64KB flash page
|
||||
* that subsequent flash operations should use. */
|
||||
#define COMMAND_CHANGE_BASE_ADDR 0x06
|
||||
|
||||
/* Type Defines: */
|
||||
/** Type define for a non-returning function pointer to the loaded application. */
|
||||
typedef void (*AppPtr_t)(void) ATTR_NO_RETURN;
|
||||
|
||||
/** Type define for a structure containing a complete DFU command issued by the host. */
|
||||
typedef struct
|
||||
{
|
||||
uint8_t Command; /**< Single byte command to perform, one of the COMMAND_* macro values */
|
||||
uint8_t Data[5]; /**< Command parameters */
|
||||
uint16_t DataSize; /**< Size of the command parameters */
|
||||
} DFU_Command_t;
|
||||
|
||||
/* Enums: */
|
||||
/** DFU bootloader states. Refer to the DFU class specification for information on each state. */
|
||||
enum DFU_State_t
|
||||
{
|
||||
appIDLE = 0,
|
||||
appDETACH = 1,
|
||||
dfuIDLE = 2,
|
||||
dfuDNLOAD_SYNC = 3,
|
||||
dfuDNBUSY = 4,
|
||||
dfuDNLOAD_IDLE = 5,
|
||||
dfuMANIFEST_SYNC = 6,
|
||||
dfuMANIFEST = 7,
|
||||
dfuMANIFEST_WAIT_RESET = 8,
|
||||
dfuUPLOAD_IDLE = 9,
|
||||
dfuERROR = 10
|
||||
};
|
||||
|
||||
/** DFU command status error codes. Refer to the DFU class specification for information on each error code. */
|
||||
enum DFU_Status_t
|
||||
{
|
||||
OK = 0,
|
||||
errTARGET = 1,
|
||||
errFILE = 2,
|
||||
errWRITE = 3,
|
||||
errERASE = 4,
|
||||
errCHECK_ERASED = 5,
|
||||
errPROG = 6,
|
||||
errVERIFY = 7,
|
||||
errADDRESS = 8,
|
||||
errNOTDONE = 9,
|
||||
errFIRMWARE = 10,
|
||||
errVENDOR = 11,
|
||||
errUSBR = 12,
|
||||
errPOR = 13,
|
||||
errUNKNOWN = 14,
|
||||
errSTALLEDPKT = 15
|
||||
};
|
||||
|
||||
/* Function Prototypes: */
|
||||
void SetupHardware(void);
|
||||
void ResetHardware(void);
|
||||
|
||||
void EVENT_USB_Device_UnhandledControlRequest(void);
|
||||
|
||||
#if defined(INCLUDE_FROM_BOOTLOADER_C)
|
||||
static void DiscardFillerBytes(uint8_t NumberOfBytes);
|
||||
static void ProcessBootloaderCommand(void);
|
||||
static void LoadStartEndAddresses(void);
|
||||
static void ProcessMemProgCommand(void);
|
||||
static void ProcessMemReadCommand(void);
|
||||
static void ProcessWriteCommand(void);
|
||||
static void ProcessReadCommand(void);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -1,90 +1,90 @@
|
||||
/** \file
|
||||
*
|
||||
* This file contains special DoxyGen information for the generation of the main page and other special
|
||||
* documentation pages. It is not a project source file.
|
||||
*/
|
||||
|
||||
/** \mainpage DFU Class USB AVR Bootloader
|
||||
*
|
||||
* \section SSec_Compat Demo Compatibility:
|
||||
*
|
||||
* The following list indicates what microcontrollers are compatible with this demo.
|
||||
*
|
||||
* - Series 7 USB AVRs
|
||||
* - Series 6 USB AVRs
|
||||
* - Series 4 USB AVRs
|
||||
* - Series 2 USB AVRs (Excluding the 8KB FLASH variants)
|
||||
*
|
||||
* \section SSec_Info USB Information:
|
||||
*
|
||||
* The following table gives a rundown of the USB utilization of this demo.
|
||||
*
|
||||
* <table>
|
||||
* <tr>
|
||||
* <td><b>USB Mode:</b></td>
|
||||
* <td>Device</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>USB Class:</b></td>
|
||||
* <td>Device Firmware Update Class (DFU)</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>USB Subclass:</b></td>
|
||||
* <td>None</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>Relevant Standards:</b></td>
|
||||
* <td>USBIF DFU Class Standard, Atmel USB Bootloader Datasheet</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>Usable Speeds:</b></td>
|
||||
* <td>Full Speed Mode</td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*
|
||||
* \section SSec_Description Project Description:
|
||||
*
|
||||
* This bootloader enumerates to the host as a DFU Class device, allowing for DFU-compatible programming
|
||||
* software to load firmware onto the AVR.
|
||||
*
|
||||
* 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
|
||||
* 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
|
||||
* third party AVR user at
|
||||
* <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
|
||||
* 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
|
||||
* 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.
|
||||
*
|
||||
* 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
|
||||
* 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
|
||||
* 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.
|
||||
*
|
||||
* \section SSec_Options Project Options
|
||||
*
|
||||
* The following defines can be found in this demo, which can control the demo behaviour when defined, or changed in value.
|
||||
*
|
||||
* <table>
|
||||
* <tr>
|
||||
* <td><b>Define Name:</b></td>
|
||||
* <td><b>Location:</b></td>
|
||||
* <td><b>Description:</b></td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>SECURE_MODE</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
|
||||
* 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>
|
||||
* </tr>
|
||||
* </table>
|
||||
*/
|
||||
/** \file
|
||||
*
|
||||
* This file contains special DoxyGen information for the generation of the main page and other special
|
||||
* documentation pages. It is not a project source file.
|
||||
*/
|
||||
|
||||
/** \mainpage DFU Class USB AVR Bootloader
|
||||
*
|
||||
* \section SSec_Compat Demo Compatibility:
|
||||
*
|
||||
* The following list indicates what microcontrollers are compatible with this demo.
|
||||
*
|
||||
* - Series 7 USB AVRs
|
||||
* - Series 6 USB AVRs
|
||||
* - Series 4 USB AVRs
|
||||
* - Series 2 USB AVRs (Excluding the 8KB FLASH variants)
|
||||
*
|
||||
* \section SSec_Info USB Information:
|
||||
*
|
||||
* The following table gives a rundown of the USB utilization of this demo.
|
||||
*
|
||||
* <table>
|
||||
* <tr>
|
||||
* <td><b>USB Mode:</b></td>
|
||||
* <td>Device</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>USB Class:</b></td>
|
||||
* <td>Device Firmware Update Class (DFU)</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>USB Subclass:</b></td>
|
||||
* <td>None</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>Relevant Standards:</b></td>
|
||||
* <td>USBIF DFU Class Standard, Atmel USB Bootloader Datasheet</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>Usable Speeds:</b></td>
|
||||
* <td>Full Speed Mode</td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*
|
||||
* \section SSec_Description Project Description:
|
||||
*
|
||||
* This bootloader enumerates to the host as a DFU Class device, allowing for DFU-compatible programming
|
||||
* software to load firmware onto the AVR.
|
||||
*
|
||||
* 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
|
||||
* 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
|
||||
* third party AVR user at
|
||||
* <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
|
||||
* 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
|
||||
* 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.
|
||||
*
|
||||
* 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
|
||||
* 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
|
||||
* 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.
|
||||
*
|
||||
* \section SSec_Options Project Options
|
||||
*
|
||||
* The following defines can be found in this demo, which can control the demo behaviour when defined, or changed in value.
|
||||
*
|
||||
* <table>
|
||||
* <tr>
|
||||
* <td><b>Define Name:</b></td>
|
||||
* <td><b>Location:</b></td>
|
||||
* <td><b>Description:</b></td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>SECURE_MODE</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
|
||||
* 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>
|
||||
* </tr>
|
||||
* </table>
|
||||
*/
|
||||
|
@ -1,181 +1,181 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* 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
|
||||
* the device's capabilities and functions.
|
||||
*/
|
||||
|
||||
#include "Descriptors.h"
|
||||
|
||||
/** Device descriptor structure. This descriptor, located in FLASH memory, describes the overall
|
||||
* 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
|
||||
* process begins.
|
||||
*/
|
||||
USB_Descriptor_Device_t DeviceDescriptor =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device},
|
||||
|
||||
.USBSpecification = VERSION_BCD(01.10),
|
||||
.Class = 0x00,
|
||||
.SubClass = 0x00,
|
||||
.Protocol = 0x00,
|
||||
|
||||
.Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE,
|
||||
|
||||
.VendorID = 0x03EB,
|
||||
.ProductID = PRODUCT_ID_CODE,
|
||||
.ReleaseNumber = 0x0000,
|
||||
|
||||
.ManufacturerStrIndex = NO_DESCRIPTOR,
|
||||
.ProductStrIndex = 0x01,
|
||||
.SerialNumStrIndex = NO_DESCRIPTOR,
|
||||
|
||||
.NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS
|
||||
};
|
||||
|
||||
/** 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
|
||||
* 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.
|
||||
*/
|
||||
USB_Descriptor_Configuration_t ConfigurationDescriptor =
|
||||
{
|
||||
.Config =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration},
|
||||
|
||||
.TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t),
|
||||
.TotalInterfaces = 1,
|
||||
|
||||
.ConfigurationNumber = 1,
|
||||
.ConfigurationStrIndex = NO_DESCRIPTOR,
|
||||
|
||||
.ConfigAttributes = USB_CONFIG_ATTR_BUSPOWERED,
|
||||
|
||||
.MaxPowerConsumption = USB_CONFIG_POWER_MA(100)
|
||||
},
|
||||
|
||||
.DFU_Interface =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
|
||||
|
||||
.InterfaceNumber = 0,
|
||||
.AlternateSetting = 0,
|
||||
|
||||
.TotalEndpoints = 0,
|
||||
|
||||
.Class = 0xFE,
|
||||
.SubClass = 0x01,
|
||||
.Protocol = 0x02,
|
||||
|
||||
.InterfaceStrIndex = NO_DESCRIPTOR
|
||||
},
|
||||
|
||||
.DFU_Functional =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_DFU_Functional_Descriptor_t), .Type = DTYPE_DFUFunctional},
|
||||
|
||||
.Attributes = (ATTR_CAN_UPLOAD | ATTR_CAN_DOWNLOAD),
|
||||
|
||||
.DetachTimeout = 0x0000,
|
||||
.TransferSize = 0x0c00,
|
||||
|
||||
.DFUSpecification = VERSION_BCD(01.01)
|
||||
}
|
||||
};
|
||||
|
||||
/** 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
|
||||
* via the language ID table available at USB.org what languages the device supports for its string descriptors.
|
||||
*/
|
||||
USB_Descriptor_String_t LanguageString =
|
||||
{
|
||||
.Header = {.Size = USB_STRING_LEN(1), .Type = DTYPE_String},
|
||||
|
||||
.UnicodeString = {LANGUAGE_ID_ENG}
|
||||
};
|
||||
|
||||
/** 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
|
||||
* Descriptor.
|
||||
*/
|
||||
USB_Descriptor_String_t ProductString =
|
||||
{
|
||||
.Header = {.Size = USB_STRING_LEN(18), .Type = DTYPE_String},
|
||||
|
||||
.UnicodeString = L"AVR DFU Bootloader"
|
||||
};
|
||||
|
||||
/** 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
|
||||
* 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
|
||||
* USB host.
|
||||
*/
|
||||
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 DescriptorNumber = (wValue & 0xFF);
|
||||
|
||||
void* Address = NULL;
|
||||
uint16_t Size = NO_DESCRIPTOR;
|
||||
|
||||
switch (DescriptorType)
|
||||
{
|
||||
case DTYPE_Device:
|
||||
Address = &DeviceDescriptor;
|
||||
Size = sizeof(USB_Descriptor_Device_t);
|
||||
break;
|
||||
case DTYPE_Configuration:
|
||||
Address = &ConfigurationDescriptor;
|
||||
Size = sizeof(USB_Descriptor_Configuration_t);
|
||||
break;
|
||||
case DTYPE_String:
|
||||
if (!(DescriptorNumber))
|
||||
{
|
||||
Address = &LanguageString;
|
||||
Size = LanguageString.Header.Size;
|
||||
}
|
||||
else
|
||||
{
|
||||
Address = &ProductString;
|
||||
Size = ProductString.Header.Size;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
*DescriptorAddress = Address;
|
||||
return Size;
|
||||
}
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* 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
|
||||
* the device's capabilities and functions.
|
||||
*/
|
||||
|
||||
#include "Descriptors.h"
|
||||
|
||||
/** Device descriptor structure. This descriptor, located in FLASH memory, describes the overall
|
||||
* 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
|
||||
* process begins.
|
||||
*/
|
||||
USB_Descriptor_Device_t DeviceDescriptor =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device},
|
||||
|
||||
.USBSpecification = VERSION_BCD(01.10),
|
||||
.Class = 0x00,
|
||||
.SubClass = 0x00,
|
||||
.Protocol = 0x00,
|
||||
|
||||
.Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE,
|
||||
|
||||
.VendorID = 0x03EB,
|
||||
.ProductID = PRODUCT_ID_CODE,
|
||||
.ReleaseNumber = 0x0000,
|
||||
|
||||
.ManufacturerStrIndex = NO_DESCRIPTOR,
|
||||
.ProductStrIndex = 0x01,
|
||||
.SerialNumStrIndex = NO_DESCRIPTOR,
|
||||
|
||||
.NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS
|
||||
};
|
||||
|
||||
/** 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
|
||||
* 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.
|
||||
*/
|
||||
USB_Descriptor_Configuration_t ConfigurationDescriptor =
|
||||
{
|
||||
.Config =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration},
|
||||
|
||||
.TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t),
|
||||
.TotalInterfaces = 1,
|
||||
|
||||
.ConfigurationNumber = 1,
|
||||
.ConfigurationStrIndex = NO_DESCRIPTOR,
|
||||
|
||||
.ConfigAttributes = USB_CONFIG_ATTR_BUSPOWERED,
|
||||
|
||||
.MaxPowerConsumption = USB_CONFIG_POWER_MA(100)
|
||||
},
|
||||
|
||||
.DFU_Interface =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
|
||||
|
||||
.InterfaceNumber = 0,
|
||||
.AlternateSetting = 0,
|
||||
|
||||
.TotalEndpoints = 0,
|
||||
|
||||
.Class = 0xFE,
|
||||
.SubClass = 0x01,
|
||||
.Protocol = 0x02,
|
||||
|
||||
.InterfaceStrIndex = NO_DESCRIPTOR
|
||||
},
|
||||
|
||||
.DFU_Functional =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_DFU_Functional_Descriptor_t), .Type = DTYPE_DFUFunctional},
|
||||
|
||||
.Attributes = (ATTR_CAN_UPLOAD | ATTR_CAN_DOWNLOAD),
|
||||
|
||||
.DetachTimeout = 0x0000,
|
||||
.TransferSize = 0x0c00,
|
||||
|
||||
.DFUSpecification = VERSION_BCD(01.01)
|
||||
}
|
||||
};
|
||||
|
||||
/** 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
|
||||
* via the language ID table available at USB.org what languages the device supports for its string descriptors.
|
||||
*/
|
||||
USB_Descriptor_String_t LanguageString =
|
||||
{
|
||||
.Header = {.Size = USB_STRING_LEN(1), .Type = DTYPE_String},
|
||||
|
||||
.UnicodeString = {LANGUAGE_ID_ENG}
|
||||
};
|
||||
|
||||
/** 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
|
||||
* Descriptor.
|
||||
*/
|
||||
USB_Descriptor_String_t ProductString =
|
||||
{
|
||||
.Header = {.Size = USB_STRING_LEN(18), .Type = DTYPE_String},
|
||||
|
||||
.UnicodeString = L"AVR DFU Bootloader"
|
||||
};
|
||||
|
||||
/** 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
|
||||
* 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
|
||||
* USB host.
|
||||
*/
|
||||
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 DescriptorNumber = (wValue & 0xFF);
|
||||
|
||||
void* Address = NULL;
|
||||
uint16_t Size = NO_DESCRIPTOR;
|
||||
|
||||
switch (DescriptorType)
|
||||
{
|
||||
case DTYPE_Device:
|
||||
Address = &DeviceDescriptor;
|
||||
Size = sizeof(USB_Descriptor_Device_t);
|
||||
break;
|
||||
case DTYPE_Configuration:
|
||||
Address = &ConfigurationDescriptor;
|
||||
Size = sizeof(USB_Descriptor_Configuration_t);
|
||||
break;
|
||||
case DTYPE_String:
|
||||
if (!(DescriptorNumber))
|
||||
{
|
||||
Address = &LanguageString;
|
||||
Size = LanguageString.Header.Size;
|
||||
}
|
||||
else
|
||||
{
|
||||
Address = &ProductString;
|
||||
Size = ProductString.Header.Size;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
*DescriptorAddress = Address;
|
||||
return Size;
|
||||
}
|
||||
|
@ -1,172 +1,172 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Header file for Descriptors.c.
|
||||
*/
|
||||
|
||||
#ifndef _DESCRIPTORS_H_
|
||||
#define _DESCRIPTORS_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <LUFA/Drivers/USB/USB.h>
|
||||
|
||||
/* Macros: */
|
||||
/** Descriptor type value for a DFU class functional descriptor. */
|
||||
#define DTYPE_DFUFunctional 0x21
|
||||
|
||||
/** 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.
|
||||
*/
|
||||
#define ATTR_WILL_DETATCH (1 << 3)
|
||||
|
||||
/** DFU attribute mask, indicating that the DFU device can communicate during the manifestation phase
|
||||
* (memory programming phase).
|
||||
*/
|
||||
#define ATTR_MANEFESTATION_TOLLERANT (1 << 2)
|
||||
|
||||
/** DFU attribute mask, indicating that the DFU device can accept DFU_UPLOAD requests to send data from
|
||||
* the device to the host.
|
||||
*/
|
||||
#define ATTR_CAN_UPLOAD (1 << 1)
|
||||
|
||||
/** DFU attribute mask, indicating that the DFU device can accept DFU_DNLOAD requests to send data from
|
||||
* the host to the device.
|
||||
*/
|
||||
#define ATTR_CAN_DOWNLOAD (1 << 0)
|
||||
|
||||
#if defined(__AVR_AT90USB1287__)
|
||||
#define PRODUCT_ID_CODE 0x2FFB
|
||||
#define AVR_SIGNATURE_1 0x1E
|
||||
#define AVR_SIGNATURE_2 0x97
|
||||
#define AVR_SIGNATURE_3 0x82
|
||||
#elif defined(__AVR_AT90USB647__)
|
||||
#define PRODUCT_ID_CODE 0x2FF9
|
||||
#define AVR_SIGNATURE_1 0x1E
|
||||
#define AVR_SIGNATURE_2 0x96
|
||||
#define AVR_SIGNATURE_3 0x82
|
||||
#elif defined(__AVR_AT90USB1286__)
|
||||
#define PRODUCT_ID_CODE 0x2FFB
|
||||
#define AVR_SIGNATURE_1 0x1E
|
||||
#define AVR_SIGNATURE_2 0x97
|
||||
#define AVR_SIGNATURE_3 0x82
|
||||
#elif defined(__AVR_AT90USB646__)
|
||||
#define PRODUCT_ID_CODE 0x2FF9
|
||||
#define AVR_SIGNATURE_1 0x1E
|
||||
#define AVR_SIGNATURE_2 0x96
|
||||
#define AVR_SIGNATURE_3 0x82
|
||||
#elif defined(__AVR_ATmega32U6__)
|
||||
#define PRODUCT_ID_CODE 0x2FFB
|
||||
#define AVR_SIGNATURE_1 0x1E
|
||||
#define AVR_SIGNATURE_2 0x95
|
||||
#define AVR_SIGNATURE_3 0x88
|
||||
#elif defined(__AVR_ATmega32U4__)
|
||||
#define PRODUCT_ID_CODE 0x2FF4
|
||||
#define AVR_SIGNATURE_1 0x1E
|
||||
#define AVR_SIGNATURE_2 0x95
|
||||
#define AVR_SIGNATURE_3 0x87
|
||||
#elif defined(__AVR_ATmega16U4__)
|
||||
#define PRODUCT_ID_CODE 0x2FF3
|
||||
#define AVR_SIGNATURE_1 0x1E
|
||||
#define AVR_SIGNATURE_2 0x94
|
||||
#define AVR_SIGNATURE_3 0x88
|
||||
#elif defined(__AVR_ATmega32U2__)
|
||||
#define PRODUCT_ID_CODE 0x2FF0
|
||||
#define AVR_SIGNATURE_1 0x1E
|
||||
#define AVR_SIGNATURE_2 0x94
|
||||
#define AVR_SIGNATURE_3 0x82
|
||||
#elif defined(__AVR_ATmega16U2__)
|
||||
#define PRODUCT_ID_CODE 0x2FEF
|
||||
#define AVR_SIGNATURE_1 0x1E
|
||||
#define AVR_SIGNATURE_2 0x94
|
||||
#define AVR_SIGNATURE_3 0x89
|
||||
#elif defined(__AVR_AT90USB162__)
|
||||
#define PRODUCT_ID_CODE 0x2FFA
|
||||
#define AVR_SIGNATURE_1 0x1E
|
||||
#define AVR_SIGNATURE_2 0x94
|
||||
#define AVR_SIGNATURE_3 0x82
|
||||
#elif defined(__AVR_ATmega8U2__)
|
||||
#define PRODUCT_ID_CODE 0x2FF7
|
||||
#define AVR_SIGNATURE_1 0x1E
|
||||
#define AVR_SIGNATURE_2 0x93
|
||||
#define AVR_SIGNATURE_3 0x82
|
||||
#elif defined(__AVR_AT90USB82__)
|
||||
#define PRODUCT_ID_CODE 0x2FEE
|
||||
#define AVR_SIGNATURE_1 0x1E
|
||||
#define AVR_SIGNATURE_2 0x93
|
||||
#define AVR_SIGNATURE_3 0x89
|
||||
#else
|
||||
#error The selected AVR part is not currently supported by this bootloader.
|
||||
#endif
|
||||
|
||||
#if !defined(PRODUCT_ID_CODE)
|
||||
#error Current AVR model is not supported by this bootloader.
|
||||
#endif
|
||||
|
||||
/* Type Defines: */
|
||||
/** 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.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
USB_Descriptor_Header_t Header; /**< Standard descriptor header structure */
|
||||
|
||||
uint8_t Attributes; /**< DFU device attributes, a mask comprising of the
|
||||
* ATTR_* macros listed in this source file
|
||||
*/
|
||||
uint16_t DetachTimeout; /**< Timeout in milliseconds between a USB_DETACH
|
||||
* command being issued and the device detaching
|
||||
* from the USB bus
|
||||
*/
|
||||
uint16_t TransferSize; /**< Maximum number of bytes the DFU device can accept
|
||||
* from the host in a transaction
|
||||
*/
|
||||
uint16_t DFUSpecification; /**< BCD packed DFU specification number this DFU
|
||||
* device complies with
|
||||
*/
|
||||
} USB_DFU_Functional_Descriptor_t;
|
||||
|
||||
/** 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
|
||||
* vary between devices, and which describe the device's usage to the host.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
USB_Descriptor_Configuration_Header_t Config;
|
||||
USB_Descriptor_Interface_t DFU_Interface;
|
||||
USB_DFU_Functional_Descriptor_t DFU_Functional;
|
||||
} USB_Descriptor_Configuration_t;
|
||||
|
||||
/* Function Prototypes: */
|
||||
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);
|
||||
|
||||
#endif
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Header file for Descriptors.c.
|
||||
*/
|
||||
|
||||
#ifndef _DESCRIPTORS_H_
|
||||
#define _DESCRIPTORS_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <LUFA/Drivers/USB/USB.h>
|
||||
|
||||
/* Macros: */
|
||||
/** Descriptor type value for a DFU class functional descriptor. */
|
||||
#define DTYPE_DFUFunctional 0x21
|
||||
|
||||
/** 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.
|
||||
*/
|
||||
#define ATTR_WILL_DETATCH (1 << 3)
|
||||
|
||||
/** DFU attribute mask, indicating that the DFU device can communicate during the manifestation phase
|
||||
* (memory programming phase).
|
||||
*/
|
||||
#define ATTR_MANEFESTATION_TOLLERANT (1 << 2)
|
||||
|
||||
/** DFU attribute mask, indicating that the DFU device can accept DFU_UPLOAD requests to send data from
|
||||
* the device to the host.
|
||||
*/
|
||||
#define ATTR_CAN_UPLOAD (1 << 1)
|
||||
|
||||
/** DFU attribute mask, indicating that the DFU device can accept DFU_DNLOAD requests to send data from
|
||||
* the host to the device.
|
||||
*/
|
||||
#define ATTR_CAN_DOWNLOAD (1 << 0)
|
||||
|
||||
#if defined(__AVR_AT90USB1287__)
|
||||
#define PRODUCT_ID_CODE 0x2FFB
|
||||
#define AVR_SIGNATURE_1 0x1E
|
||||
#define AVR_SIGNATURE_2 0x97
|
||||
#define AVR_SIGNATURE_3 0x82
|
||||
#elif defined(__AVR_AT90USB647__)
|
||||
#define PRODUCT_ID_CODE 0x2FF9
|
||||
#define AVR_SIGNATURE_1 0x1E
|
||||
#define AVR_SIGNATURE_2 0x96
|
||||
#define AVR_SIGNATURE_3 0x82
|
||||
#elif defined(__AVR_AT90USB1286__)
|
||||
#define PRODUCT_ID_CODE 0x2FFB
|
||||
#define AVR_SIGNATURE_1 0x1E
|
||||
#define AVR_SIGNATURE_2 0x97
|
||||
#define AVR_SIGNATURE_3 0x82
|
||||
#elif defined(__AVR_AT90USB646__)
|
||||
#define PRODUCT_ID_CODE 0x2FF9
|
||||
#define AVR_SIGNATURE_1 0x1E
|
||||
#define AVR_SIGNATURE_2 0x96
|
||||
#define AVR_SIGNATURE_3 0x82
|
||||
#elif defined(__AVR_ATmega32U6__)
|
||||
#define PRODUCT_ID_CODE 0x2FFB
|
||||
#define AVR_SIGNATURE_1 0x1E
|
||||
#define AVR_SIGNATURE_2 0x95
|
||||
#define AVR_SIGNATURE_3 0x88
|
||||
#elif defined(__AVR_ATmega32U4__)
|
||||
#define PRODUCT_ID_CODE 0x2FF4
|
||||
#define AVR_SIGNATURE_1 0x1E
|
||||
#define AVR_SIGNATURE_2 0x95
|
||||
#define AVR_SIGNATURE_3 0x87
|
||||
#elif defined(__AVR_ATmega16U4__)
|
||||
#define PRODUCT_ID_CODE 0x2FF3
|
||||
#define AVR_SIGNATURE_1 0x1E
|
||||
#define AVR_SIGNATURE_2 0x94
|
||||
#define AVR_SIGNATURE_3 0x88
|
||||
#elif defined(__AVR_ATmega32U2__)
|
||||
#define PRODUCT_ID_CODE 0x2FF0
|
||||
#define AVR_SIGNATURE_1 0x1E
|
||||
#define AVR_SIGNATURE_2 0x94
|
||||
#define AVR_SIGNATURE_3 0x82
|
||||
#elif defined(__AVR_ATmega16U2__)
|
||||
#define PRODUCT_ID_CODE 0x2FEF
|
||||
#define AVR_SIGNATURE_1 0x1E
|
||||
#define AVR_SIGNATURE_2 0x94
|
||||
#define AVR_SIGNATURE_3 0x89
|
||||
#elif defined(__AVR_AT90USB162__)
|
||||
#define PRODUCT_ID_CODE 0x2FFA
|
||||
#define AVR_SIGNATURE_1 0x1E
|
||||
#define AVR_SIGNATURE_2 0x94
|
||||
#define AVR_SIGNATURE_3 0x82
|
||||
#elif defined(__AVR_ATmega8U2__)
|
||||
#define PRODUCT_ID_CODE 0x2FF7
|
||||
#define AVR_SIGNATURE_1 0x1E
|
||||
#define AVR_SIGNATURE_2 0x93
|
||||
#define AVR_SIGNATURE_3 0x82
|
||||
#elif defined(__AVR_AT90USB82__)
|
||||
#define PRODUCT_ID_CODE 0x2FEE
|
||||
#define AVR_SIGNATURE_1 0x1E
|
||||
#define AVR_SIGNATURE_2 0x93
|
||||
#define AVR_SIGNATURE_3 0x89
|
||||
#else
|
||||
#error The selected AVR part is not currently supported by this bootloader.
|
||||
#endif
|
||||
|
||||
#if !defined(PRODUCT_ID_CODE)
|
||||
#error Current AVR model is not supported by this bootloader.
|
||||
#endif
|
||||
|
||||
/* Type Defines: */
|
||||
/** 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.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
USB_Descriptor_Header_t Header; /**< Standard descriptor header structure */
|
||||
|
||||
uint8_t Attributes; /**< DFU device attributes, a mask comprising of the
|
||||
* ATTR_* macros listed in this source file
|
||||
*/
|
||||
uint16_t DetachTimeout; /**< Timeout in milliseconds between a USB_DETACH
|
||||
* command being issued and the device detaching
|
||||
* from the USB bus
|
||||
*/
|
||||
uint16_t TransferSize; /**< Maximum number of bytes the DFU device can accept
|
||||
* from the host in a transaction
|
||||
*/
|
||||
uint16_t DFUSpecification; /**< BCD packed DFU specification number this DFU
|
||||
* device complies with
|
||||
*/
|
||||
} USB_DFU_Functional_Descriptor_t;
|
||||
|
||||
/** 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
|
||||
* vary between devices, and which describe the device's usage to the host.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
USB_Descriptor_Configuration_Header_t Config;
|
||||
USB_Descriptor_Interface_t DFU_Interface;
|
||||
USB_DFU_Functional_Descriptor_t DFU_Functional;
|
||||
} USB_Descriptor_Configuration_t;
|
||||
|
||||
/* Function Prototypes: */
|
||||
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);
|
||||
|
||||
#endif
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,189 +1,189 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* 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
|
||||
* the device's capabilities and functions.
|
||||
*/
|
||||
|
||||
#include "Descriptors.h"
|
||||
|
||||
/** 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
|
||||
* 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
|
||||
* more details on HID report descriptors.
|
||||
*/
|
||||
USB_Descriptor_HIDReport_Datatype_t HIDReport[] =
|
||||
{
|
||||
0x06, 0x9c, 0xff, /* Usage Page (Vendor Defined) */
|
||||
0x09, TEENSY_USAGEPAGE, /* Usage (Vendor Defined) */
|
||||
0xa1, 0x01, /* Collection (Vendor Defined) */
|
||||
0x0a, 0x19, 0x00, /* Usage (Vendor Defined) */
|
||||
0x75, 0x08, /* Report Size (8) */
|
||||
#if (SPM_PAGESIZE == 128) /* Report Count (SPM_PAGESIZE + 2) */
|
||||
0x95, (SPM_PAGESIZE + 2),
|
||||
#else
|
||||
0x96, ((SPM_PAGESIZE + 2) & 0xFF), ((SPM_PAGESIZE + 2) >> 8),
|
||||
#endif
|
||||
0x15, 0x00, /* Logical Minimum (0) */
|
||||
0x25, 0xff, /* Logical Maximum (255) */
|
||||
0x91, 0x02, /* Output (Data, Variable, Absolute) */
|
||||
0xc0 /* End Collection */
|
||||
};
|
||||
|
||||
/** Device descriptor structure. This descriptor, located in FLASH memory, describes the overall
|
||||
* 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
|
||||
* process begins.
|
||||
*/
|
||||
USB_Descriptor_Device_t DeviceDescriptor =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device},
|
||||
|
||||
.USBSpecification = VERSION_BCD(01.10),
|
||||
.Class = 0x00,
|
||||
.SubClass = 0x00,
|
||||
.Protocol = 0x00,
|
||||
|
||||
.Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE,
|
||||
|
||||
.VendorID = 0x16C0,
|
||||
.ProductID = 0x0478,
|
||||
.ReleaseNumber = 0x0120,
|
||||
|
||||
.ManufacturerStrIndex = NO_DESCRIPTOR,
|
||||
.ProductStrIndex = NO_DESCRIPTOR,
|
||||
.SerialNumStrIndex = NO_DESCRIPTOR,
|
||||
|
||||
.NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS
|
||||
};
|
||||
|
||||
/** 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
|
||||
* 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.
|
||||
*/
|
||||
USB_Descriptor_Configuration_t ConfigurationDescriptor =
|
||||
{
|
||||
.Config =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration},
|
||||
|
||||
.TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t),
|
||||
.TotalInterfaces = 1,
|
||||
|
||||
.ConfigurationNumber = 1,
|
||||
.ConfigurationStrIndex = NO_DESCRIPTOR,
|
||||
|
||||
.ConfigAttributes = USB_CONFIG_ATTR_BUSPOWERED,
|
||||
|
||||
.MaxPowerConsumption = USB_CONFIG_POWER_MA(100)
|
||||
},
|
||||
|
||||
.HID_Interface =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
|
||||
|
||||
.InterfaceNumber = 0x00,
|
||||
.AlternateSetting = 0x00,
|
||||
|
||||
.TotalEndpoints = 1,
|
||||
|
||||
.Class = 0x03,
|
||||
.SubClass = 0x00,
|
||||
.Protocol = 0x00,
|
||||
|
||||
.InterfaceStrIndex = NO_DESCRIPTOR
|
||||
},
|
||||
|
||||
.HID_VendorHID =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_HID_t), .Type = DTYPE_HID},
|
||||
|
||||
.HIDSpec = VERSION_BCD(01.11),
|
||||
.CountryCode = 0x00,
|
||||
.TotalHIDDescriptors = 1,
|
||||
.HIDReportType = DTYPE_Report,
|
||||
.HIDReportLength = sizeof(HIDReport)
|
||||
},
|
||||
|
||||
.HID_ReportINEndpoint =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
|
||||
|
||||
.EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_IN | HID_EPNUM),
|
||||
.Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
|
||||
.EndpointSize = HID_EPSIZE,
|
||||
.PollingIntervalMS = 0x40
|
||||
},
|
||||
};
|
||||
|
||||
/** 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
|
||||
* 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
|
||||
* USB host.
|
||||
*/
|
||||
uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, void** const DescriptorAddress)
|
||||
{
|
||||
const uint8_t DescriptorType = (wValue >> 8);
|
||||
|
||||
void* Address = NULL;
|
||||
uint16_t Size = NO_DESCRIPTOR;
|
||||
|
||||
/* If/Else If chain compiles slightly smaller than a switch case */
|
||||
|
||||
if (DescriptorType == DTYPE_Device)
|
||||
{
|
||||
Address = (void*)&DeviceDescriptor;
|
||||
Size = sizeof(USB_Descriptor_Device_t);
|
||||
}
|
||||
else if (DescriptorType == DTYPE_Configuration)
|
||||
{
|
||||
Address = (void*)&ConfigurationDescriptor;
|
||||
Size = sizeof(USB_Descriptor_Configuration_t);
|
||||
}
|
||||
else if (DescriptorType == DTYPE_HID)
|
||||
{
|
||||
Address = (void*)&ConfigurationDescriptor.HID_VendorHID;
|
||||
Size = sizeof(USB_Descriptor_HID_t);
|
||||
}
|
||||
else
|
||||
{
|
||||
Address = (void*)&HIDReport;
|
||||
Size = sizeof(HIDReport);
|
||||
}
|
||||
|
||||
*DescriptorAddress = Address;
|
||||
return Size;
|
||||
}
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* 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
|
||||
* the device's capabilities and functions.
|
||||
*/
|
||||
|
||||
#include "Descriptors.h"
|
||||
|
||||
/** 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
|
||||
* 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
|
||||
* more details on HID report descriptors.
|
||||
*/
|
||||
USB_Descriptor_HIDReport_Datatype_t HIDReport[] =
|
||||
{
|
||||
0x06, 0x9c, 0xff, /* Usage Page (Vendor Defined) */
|
||||
0x09, TEENSY_USAGEPAGE, /* Usage (Vendor Defined) */
|
||||
0xa1, 0x01, /* Collection (Vendor Defined) */
|
||||
0x0a, 0x19, 0x00, /* Usage (Vendor Defined) */
|
||||
0x75, 0x08, /* Report Size (8) */
|
||||
#if (SPM_PAGESIZE == 128) /* Report Count (SPM_PAGESIZE + 2) */
|
||||
0x95, (SPM_PAGESIZE + 2),
|
||||
#else
|
||||
0x96, ((SPM_PAGESIZE + 2) & 0xFF), ((SPM_PAGESIZE + 2) >> 8),
|
||||
#endif
|
||||
0x15, 0x00, /* Logical Minimum (0) */
|
||||
0x25, 0xff, /* Logical Maximum (255) */
|
||||
0x91, 0x02, /* Output (Data, Variable, Absolute) */
|
||||
0xc0 /* End Collection */
|
||||
};
|
||||
|
||||
/** Device descriptor structure. This descriptor, located in FLASH memory, describes the overall
|
||||
* 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
|
||||
* process begins.
|
||||
*/
|
||||
USB_Descriptor_Device_t DeviceDescriptor =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device},
|
||||
|
||||
.USBSpecification = VERSION_BCD(01.10),
|
||||
.Class = 0x00,
|
||||
.SubClass = 0x00,
|
||||
.Protocol = 0x00,
|
||||
|
||||
.Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE,
|
||||
|
||||
.VendorID = 0x16C0,
|
||||
.ProductID = 0x0478,
|
||||
.ReleaseNumber = 0x0120,
|
||||
|
||||
.ManufacturerStrIndex = NO_DESCRIPTOR,
|
||||
.ProductStrIndex = NO_DESCRIPTOR,
|
||||
.SerialNumStrIndex = NO_DESCRIPTOR,
|
||||
|
||||
.NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS
|
||||
};
|
||||
|
||||
/** 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
|
||||
* 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.
|
||||
*/
|
||||
USB_Descriptor_Configuration_t ConfigurationDescriptor =
|
||||
{
|
||||
.Config =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration},
|
||||
|
||||
.TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t),
|
||||
.TotalInterfaces = 1,
|
||||
|
||||
.ConfigurationNumber = 1,
|
||||
.ConfigurationStrIndex = NO_DESCRIPTOR,
|
||||
|
||||
.ConfigAttributes = USB_CONFIG_ATTR_BUSPOWERED,
|
||||
|
||||
.MaxPowerConsumption = USB_CONFIG_POWER_MA(100)
|
||||
},
|
||||
|
||||
.HID_Interface =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
|
||||
|
||||
.InterfaceNumber = 0x00,
|
||||
.AlternateSetting = 0x00,
|
||||
|
||||
.TotalEndpoints = 1,
|
||||
|
||||
.Class = 0x03,
|
||||
.SubClass = 0x00,
|
||||
.Protocol = 0x00,
|
||||
|
||||
.InterfaceStrIndex = NO_DESCRIPTOR
|
||||
},
|
||||
|
||||
.HID_VendorHID =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_HID_t), .Type = DTYPE_HID},
|
||||
|
||||
.HIDSpec = VERSION_BCD(01.11),
|
||||
.CountryCode = 0x00,
|
||||
.TotalHIDDescriptors = 1,
|
||||
.HIDReportType = DTYPE_Report,
|
||||
.HIDReportLength = sizeof(HIDReport)
|
||||
},
|
||||
|
||||
.HID_ReportINEndpoint =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
|
||||
|
||||
.EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_IN | HID_EPNUM),
|
||||
.Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
|
||||
.EndpointSize = HID_EPSIZE,
|
||||
.PollingIntervalMS = 0x40
|
||||
},
|
||||
};
|
||||
|
||||
/** 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
|
||||
* 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
|
||||
* USB host.
|
||||
*/
|
||||
uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, void** const DescriptorAddress)
|
||||
{
|
||||
const uint8_t DescriptorType = (wValue >> 8);
|
||||
|
||||
void* Address = NULL;
|
||||
uint16_t Size = NO_DESCRIPTOR;
|
||||
|
||||
/* If/Else If chain compiles slightly smaller than a switch case */
|
||||
|
||||
if (DescriptorType == DTYPE_Device)
|
||||
{
|
||||
Address = (void*)&DeviceDescriptor;
|
||||
Size = sizeof(USB_Descriptor_Device_t);
|
||||
}
|
||||
else if (DescriptorType == DTYPE_Configuration)
|
||||
{
|
||||
Address = (void*)&ConfigurationDescriptor;
|
||||
Size = sizeof(USB_Descriptor_Configuration_t);
|
||||
}
|
||||
else if (DescriptorType == DTYPE_HID)
|
||||
{
|
||||
Address = (void*)&ConfigurationDescriptor.HID_VendorHID;
|
||||
Size = sizeof(USB_Descriptor_HID_t);
|
||||
}
|
||||
else
|
||||
{
|
||||
Address = (void*)&HIDReport;
|
||||
Size = sizeof(HIDReport);
|
||||
}
|
||||
|
||||
*DescriptorAddress = Address;
|
||||
return Size;
|
||||
}
|
||||
|
@ -1,115 +1,115 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Header file for Descriptors.c.
|
||||
*/
|
||||
|
||||
#ifndef _DESCRIPTORS_H_
|
||||
#define _DESCRIPTORS_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <LUFA/Drivers/USB/USB.h>
|
||||
|
||||
/* Type Defines: */
|
||||
/** 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.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
USB_Descriptor_Header_t Header;
|
||||
|
||||
uint16_t HIDSpec;
|
||||
uint8_t CountryCode;
|
||||
|
||||
uint8_t TotalHIDDescriptors;
|
||||
|
||||
uint8_t HIDReportType;
|
||||
uint16_t HIDReportLength;
|
||||
} USB_Descriptor_HID_t;
|
||||
|
||||
/** Type define for the data type used to store HID report descriptor elements. */
|
||||
typedef uint8_t USB_Descriptor_HIDReport_Datatype_t;
|
||||
|
||||
/** 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
|
||||
* vary between devices, and which describe the device's usage to the host.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
USB_Descriptor_Configuration_Header_t Config;
|
||||
USB_Descriptor_Interface_t HID_Interface;
|
||||
USB_Descriptor_HID_t HID_VendorHID;
|
||||
USB_Descriptor_Endpoint_t HID_ReportINEndpoint;
|
||||
} USB_Descriptor_Configuration_t;
|
||||
|
||||
/* Macros: */
|
||||
/** Endpoint number of the HID data IN endpoint. */
|
||||
#define HID_EPNUM 1
|
||||
|
||||
/** Size in bytes of the HID reporting IN endpoint. */
|
||||
#define HID_EPSIZE 64
|
||||
|
||||
/** Descriptor header type value, to indicate a HID class HID descriptor. */
|
||||
#define DTYPE_HID 0x21
|
||||
|
||||
/** Descriptor header type value, to indicate a HID class HID report descriptor. */
|
||||
#define DTYPE_Report 0x22
|
||||
|
||||
/** Vendor usage page for the Teensy 1.0 board */
|
||||
#define TEENSY_USAGEPAGE_10 0x19
|
||||
|
||||
/** Vendor usage page for the Teensy++ 1.0 board */
|
||||
#define TEENSY_USAGEPAGE_10PP 0x1A
|
||||
|
||||
/** Vendor usage page for the Teensy 2.0 board */
|
||||
#define TEENSY_USAGEPAGE_20 0x1B
|
||||
|
||||
/** Vendor usage page for the Teensy++ 2.0 board */
|
||||
#define TEENSY_USAGEPAGE_20PP 0x1C
|
||||
|
||||
#if (defined(__AVR_AT90USB162__) || defined(__AVR_ATmega16U2__))
|
||||
#define TEENSY_USAGEPAGE TEENSY_USAGEPAGE_10
|
||||
#elif defined(__AVR_ATmega32U4__)
|
||||
#define TEENSY_USAGEPAGE TEENSY_USAGEPAGE_20
|
||||
#elif (defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB647__))
|
||||
#define TEENSY_USAGEPAGE TEENSY_USAGEPAGE_10PP
|
||||
#elif (defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__))
|
||||
#define TEENSY_USAGEPAGE TEENSY_USAGEPAGE_20PP
|
||||
#else
|
||||
#error The selected AVR model is not currently supported by the TeensyHID bootloader.
|
||||
#endif
|
||||
|
||||
/* Function Prototypes: */
|
||||
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);
|
||||
|
||||
#endif
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Header file for Descriptors.c.
|
||||
*/
|
||||
|
||||
#ifndef _DESCRIPTORS_H_
|
||||
#define _DESCRIPTORS_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <LUFA/Drivers/USB/USB.h>
|
||||
|
||||
/* Type Defines: */
|
||||
/** 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.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
USB_Descriptor_Header_t Header;
|
||||
|
||||
uint16_t HIDSpec;
|
||||
uint8_t CountryCode;
|
||||
|
||||
uint8_t TotalHIDDescriptors;
|
||||
|
||||
uint8_t HIDReportType;
|
||||
uint16_t HIDReportLength;
|
||||
} USB_Descriptor_HID_t;
|
||||
|
||||
/** Type define for the data type used to store HID report descriptor elements. */
|
||||
typedef uint8_t USB_Descriptor_HIDReport_Datatype_t;
|
||||
|
||||
/** 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
|
||||
* vary between devices, and which describe the device's usage to the host.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
USB_Descriptor_Configuration_Header_t Config;
|
||||
USB_Descriptor_Interface_t HID_Interface;
|
||||
USB_Descriptor_HID_t HID_VendorHID;
|
||||
USB_Descriptor_Endpoint_t HID_ReportINEndpoint;
|
||||
} USB_Descriptor_Configuration_t;
|
||||
|
||||
/* Macros: */
|
||||
/** Endpoint number of the HID data IN endpoint. */
|
||||
#define HID_EPNUM 1
|
||||
|
||||
/** Size in bytes of the HID reporting IN endpoint. */
|
||||
#define HID_EPSIZE 64
|
||||
|
||||
/** Descriptor header type value, to indicate a HID class HID descriptor. */
|
||||
#define DTYPE_HID 0x21
|
||||
|
||||
/** Descriptor header type value, to indicate a HID class HID report descriptor. */
|
||||
#define DTYPE_Report 0x22
|
||||
|
||||
/** Vendor usage page for the Teensy 1.0 board */
|
||||
#define TEENSY_USAGEPAGE_10 0x19
|
||||
|
||||
/** Vendor usage page for the Teensy++ 1.0 board */
|
||||
#define TEENSY_USAGEPAGE_10PP 0x1A
|
||||
|
||||
/** Vendor usage page for the Teensy 2.0 board */
|
||||
#define TEENSY_USAGEPAGE_20 0x1B
|
||||
|
||||
/** Vendor usage page for the Teensy++ 2.0 board */
|
||||
#define TEENSY_USAGEPAGE_20PP 0x1C
|
||||
|
||||
#if (defined(__AVR_AT90USB162__) || defined(__AVR_ATmega16U2__))
|
||||
#define TEENSY_USAGEPAGE TEENSY_USAGEPAGE_10
|
||||
#elif defined(__AVR_ATmega32U4__)
|
||||
#define TEENSY_USAGEPAGE TEENSY_USAGEPAGE_20
|
||||
#elif (defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB647__))
|
||||
#define TEENSY_USAGEPAGE TEENSY_USAGEPAGE_10PP
|
||||
#elif (defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__))
|
||||
#define TEENSY_USAGEPAGE TEENSY_USAGEPAGE_20PP
|
||||
#else
|
||||
#error The selected AVR model is not currently supported by the TeensyHID bootloader.
|
||||
#endif
|
||||
|
||||
/* Function Prototypes: */
|
||||
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);
|
||||
|
||||
#endif
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,157 +1,157 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Main source file for the TeensyHID bootloader. This file contains the complete bootloader logic.
|
||||
*/
|
||||
|
||||
#include "TeensyHID.h"
|
||||
|
||||
/** 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
|
||||
* started via a forced watchdog reset.
|
||||
*/
|
||||
bool RunBootloader = true;
|
||||
|
||||
/** 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.
|
||||
*/
|
||||
int main(void)
|
||||
{
|
||||
/* Setup hardware required for the bootloader */
|
||||
SetupHardware();
|
||||
|
||||
/* Enable global interrupts so that the USB stack can function */
|
||||
sei();
|
||||
|
||||
while (RunBootloader)
|
||||
USB_USBTask();
|
||||
|
||||
/* Disconnect from the host - USB interface will be reset later along with the AVR */
|
||||
USB_Detach();
|
||||
|
||||
/* Enable the watchdog and force a timeout to reset the AVR */
|
||||
wdt_enable(WDTO_250MS);
|
||||
|
||||
for (;;);
|
||||
}
|
||||
|
||||
/** Configures all hardware required for the bootloader. */
|
||||
void SetupHardware(void)
|
||||
{
|
||||
/* Disable watchdog if enabled by bootloader/fuses */
|
||||
MCUSR &= ~(1 << WDRF);
|
||||
wdt_disable();
|
||||
|
||||
/* Relocate the interrupt vector table to the bootloader section */
|
||||
MCUCR = (1 << IVCE);
|
||||
MCUCR = (1 << IVSEL);
|
||||
|
||||
/* Initialize USB subsystem */
|
||||
USB_Init();
|
||||
}
|
||||
|
||||
/** Event handler for the USB_ConfigurationChanged event. This configures the device's endpoints ready
|
||||
* to relay data to and from the attached USB host.
|
||||
*/
|
||||
void EVENT_USB_Device_ConfigurationChanged(void)
|
||||
{
|
||||
/* Setup HID Report Endpoint */
|
||||
Endpoint_ConfigureEndpoint(HID_EPNUM, EP_TYPE_INTERRUPT,
|
||||
ENDPOINT_DIR_IN, HID_EPSIZE,
|
||||
ENDPOINT_BANK_SINGLE);
|
||||
}
|
||||
|
||||
/** 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
|
||||
* all issued via the control endpoint), so that they can be handled appropriately for the application.
|
||||
*/
|
||||
void EVENT_USB_Device_UnhandledControlRequest(void)
|
||||
{
|
||||
/* Handle HID Class specific requests */
|
||||
switch (USB_ControlRequest.bRequest)
|
||||
{
|
||||
case REQ_SetReport:
|
||||
Endpoint_ClearSETUP();
|
||||
|
||||
/* Wait until the command has been sent by the host */
|
||||
while (!(Endpoint_IsOUTReceived()));
|
||||
|
||||
/* Read in the write destination index */
|
||||
uint16_t PageIndex = Endpoint_Read_Word_LE();
|
||||
|
||||
/* Check if the command is a program page command, or a start application command */
|
||||
if (PageIndex == TEENSY_STARTAPPLICATION)
|
||||
{
|
||||
RunBootloader = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
#if (FLASHEND > 0xFFFF)
|
||||
uint32_t PageByteAddress = ((uint32_t)PageIndex << 8);
|
||||
#else
|
||||
uint16_t PageByteAddress = PageIndex;
|
||||
#endif
|
||||
|
||||
/* Erase the given FLASH page, ready to be programmed */
|
||||
boot_page_erase(PageByteAddress);
|
||||
boot_spm_busy_wait();
|
||||
|
||||
/* Write each of the FLASH page's bytes in sequence */
|
||||
#if (SPM_PAGESIZE == 128)
|
||||
for (uint8_t PageByte = 0; PageByte < SPM_PAGESIZE; PageByte += 2)
|
||||
#else
|
||||
for (uint16_t PageByte = 0; PageByte < SPM_PAGESIZE; PageByte += 2)
|
||||
#endif
|
||||
{
|
||||
/* Check if endpoint is empty - if so clear it and wait until ready for next packet */
|
||||
if (!(Endpoint_BytesInEndpoint()))
|
||||
{
|
||||
Endpoint_ClearOUT();
|
||||
while (!(Endpoint_IsOUTReceived()));
|
||||
}
|
||||
|
||||
/* Write the next data word to the FLASH page */
|
||||
boot_page_fill(PageByteAddress + PageByte, Endpoint_Read_Word_LE());
|
||||
}
|
||||
|
||||
/* Write the filled FLASH page to memory */
|
||||
boot_page_write(PageByteAddress);
|
||||
boot_spm_busy_wait();
|
||||
}
|
||||
|
||||
Endpoint_ClearOUT();
|
||||
|
||||
Endpoint_ClearStatusStage();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Main source file for the TeensyHID bootloader. This file contains the complete bootloader logic.
|
||||
*/
|
||||
|
||||
#include "TeensyHID.h"
|
||||
|
||||
/** 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
|
||||
* started via a forced watchdog reset.
|
||||
*/
|
||||
bool RunBootloader = true;
|
||||
|
||||
/** 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.
|
||||
*/
|
||||
int main(void)
|
||||
{
|
||||
/* Setup hardware required for the bootloader */
|
||||
SetupHardware();
|
||||
|
||||
/* Enable global interrupts so that the USB stack can function */
|
||||
sei();
|
||||
|
||||
while (RunBootloader)
|
||||
USB_USBTask();
|
||||
|
||||
/* Disconnect from the host - USB interface will be reset later along with the AVR */
|
||||
USB_Detach();
|
||||
|
||||
/* Enable the watchdog and force a timeout to reset the AVR */
|
||||
wdt_enable(WDTO_250MS);
|
||||
|
||||
for (;;);
|
||||
}
|
||||
|
||||
/** Configures all hardware required for the bootloader. */
|
||||
void SetupHardware(void)
|
||||
{
|
||||
/* Disable watchdog if enabled by bootloader/fuses */
|
||||
MCUSR &= ~(1 << WDRF);
|
||||
wdt_disable();
|
||||
|
||||
/* Relocate the interrupt vector table to the bootloader section */
|
||||
MCUCR = (1 << IVCE);
|
||||
MCUCR = (1 << IVSEL);
|
||||
|
||||
/* Initialize USB subsystem */
|
||||
USB_Init();
|
||||
}
|
||||
|
||||
/** Event handler for the USB_ConfigurationChanged event. This configures the device's endpoints ready
|
||||
* to relay data to and from the attached USB host.
|
||||
*/
|
||||
void EVENT_USB_Device_ConfigurationChanged(void)
|
||||
{
|
||||
/* Setup HID Report Endpoint */
|
||||
Endpoint_ConfigureEndpoint(HID_EPNUM, EP_TYPE_INTERRUPT,
|
||||
ENDPOINT_DIR_IN, HID_EPSIZE,
|
||||
ENDPOINT_BANK_SINGLE);
|
||||
}
|
||||
|
||||
/** 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
|
||||
* all issued via the control endpoint), so that they can be handled appropriately for the application.
|
||||
*/
|
||||
void EVENT_USB_Device_UnhandledControlRequest(void)
|
||||
{
|
||||
/* Handle HID Class specific requests */
|
||||
switch (USB_ControlRequest.bRequest)
|
||||
{
|
||||
case REQ_SetReport:
|
||||
Endpoint_ClearSETUP();
|
||||
|
||||
/* Wait until the command has been sent by the host */
|
||||
while (!(Endpoint_IsOUTReceived()));
|
||||
|
||||
/* Read in the write destination index */
|
||||
uint16_t PageIndex = Endpoint_Read_Word_LE();
|
||||
|
||||
/* Check if the command is a program page command, or a start application command */
|
||||
if (PageIndex == TEENSY_STARTAPPLICATION)
|
||||
{
|
||||
RunBootloader = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
#if (FLASHEND > 0xFFFF)
|
||||
uint32_t PageByteAddress = ((uint32_t)PageIndex << 8);
|
||||
#else
|
||||
uint16_t PageByteAddress = PageIndex;
|
||||
#endif
|
||||
|
||||
/* Erase the given FLASH page, ready to be programmed */
|
||||
boot_page_erase(PageByteAddress);
|
||||
boot_spm_busy_wait();
|
||||
|
||||
/* Write each of the FLASH page's bytes in sequence */
|
||||
#if (SPM_PAGESIZE == 128)
|
||||
for (uint8_t PageByte = 0; PageByte < SPM_PAGESIZE; PageByte += 2)
|
||||
#else
|
||||
for (uint16_t PageByte = 0; PageByte < SPM_PAGESIZE; PageByte += 2)
|
||||
#endif
|
||||
{
|
||||
/* Check if endpoint is empty - if so clear it and wait until ready for next packet */
|
||||
if (!(Endpoint_BytesInEndpoint()))
|
||||
{
|
||||
Endpoint_ClearOUT();
|
||||
while (!(Endpoint_IsOUTReceived()));
|
||||
}
|
||||
|
||||
/* Write the next data word to the FLASH page */
|
||||
boot_page_fill(PageByteAddress + PageByte, Endpoint_Read_Word_LE());
|
||||
}
|
||||
|
||||
/* Write the filled FLASH page to memory */
|
||||
boot_page_write(PageByteAddress);
|
||||
boot_spm_busy_wait();
|
||||
}
|
||||
|
||||
Endpoint_ClearOUT();
|
||||
|
||||
Endpoint_ClearStatusStage();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1,64 +1,64 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Header file for TeensyHID.c.
|
||||
*/
|
||||
|
||||
#ifndef _TEENSYHID_H_
|
||||
#define _TEENSYHID_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/io.h>
|
||||
#include <avr/wdt.h>
|
||||
#include <avr/boot.h>
|
||||
#include <avr/power.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "Descriptors.h"
|
||||
|
||||
#include <LUFA/Drivers/USB/USB.h>
|
||||
|
||||
/* Macros: */
|
||||
/** HID Class specific request to send the next HID report to the device. */
|
||||
#define REQ_SetReport 0x09
|
||||
|
||||
/** Teensy Bootloader special address to start the user application */
|
||||
#define TEENSY_STARTAPPLICATION 0xFFFF
|
||||
|
||||
/* Function Prototypes: */
|
||||
void SetupHardware(void);
|
||||
|
||||
void EVENT_USB_Device_ConfigurationChanged(void);
|
||||
void EVENT_USB_Device_UnhandledControlRequest(void);
|
||||
|
||||
#endif
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Header file for TeensyHID.c.
|
||||
*/
|
||||
|
||||
#ifndef _TEENSYHID_H_
|
||||
#define _TEENSYHID_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/io.h>
|
||||
#include <avr/wdt.h>
|
||||
#include <avr/boot.h>
|
||||
#include <avr/power.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "Descriptors.h"
|
||||
|
||||
#include <LUFA/Drivers/USB/USB.h>
|
||||
|
||||
/* Macros: */
|
||||
/** HID Class specific request to send the next HID report to the device. */
|
||||
#define REQ_SetReport 0x09
|
||||
|
||||
/** Teensy Bootloader special address to start the user application */
|
||||
#define TEENSY_STARTAPPLICATION 0xFFFF
|
||||
|
||||
/* Function Prototypes: */
|
||||
void SetupHardware(void);
|
||||
|
||||
void EVENT_USB_Device_ConfigurationChanged(void);
|
||||
void EVENT_USB_Device_UnhandledControlRequest(void);
|
||||
|
||||
#endif
|
||||
|
@ -1,72 +1,72 @@
|
||||
/** \file
|
||||
*
|
||||
* This file contains special DoxyGen information for the generation of the main page and other special
|
||||
* documentation pages. It is not a project source file.
|
||||
*/
|
||||
|
||||
/** \mainpage Teensy HID Class USB AVR Bootloader
|
||||
*
|
||||
* \section SSec_Compat Demo Compatibility:
|
||||
*
|
||||
* The following list indicates what microcontrollers are compatible with this demo.
|
||||
*
|
||||
* - AT90USB162 (Teensy 1.0)
|
||||
* - AT90USB646 (Teensy++ 1.0)
|
||||
* - ATMEGA32U4 (Teensy 2.0)
|
||||
* - AT90USB1286 (Teensy++ 2.0)
|
||||
*
|
||||
* \section SSec_Info USB Information:
|
||||
*
|
||||
* The following table gives a rundown of the USB utilization of this demo.
|
||||
*
|
||||
* <table>
|
||||
* <tr>
|
||||
* <td><b>USB Mode:</b></td>
|
||||
* <td>Device</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>USB Class:</b></td>
|
||||
* <td>Human Interface Device Class (HID)</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>USB Subclass:</b></td>
|
||||
* <td>N/A</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>Relevant Standards:</b></td>
|
||||
* <td>USBIF HID Class Standard \n
|
||||
* Teensy Programming Protocol Specification</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>Usable Speeds:</b></td>
|
||||
* <td>Low Speed Mode \n
|
||||
* Full Speed Mode</td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*
|
||||
* \section SSec_Description Project Description:
|
||||
*
|
||||
* 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>.
|
||||
*
|
||||
* 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
|
||||
* 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
|
||||
* under 2KB.
|
||||
*
|
||||
* This spoofs (with permission) the official Teensy bootloader's VID and PID, so that the software remains
|
||||
* compatible with no changes.
|
||||
*
|
||||
* \section SSec_Options Project Options
|
||||
*
|
||||
* The following defines can be found in this demo, which can control the demo behaviour when defined, or changed in value.
|
||||
*
|
||||
* <table>
|
||||
* <tr>
|
||||
* <td>
|
||||
* None
|
||||
* </td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*/
|
||||
/** \file
|
||||
*
|
||||
* This file contains special DoxyGen information for the generation of the main page and other special
|
||||
* documentation pages. It is not a project source file.
|
||||
*/
|
||||
|
||||
/** \mainpage Teensy HID Class USB AVR Bootloader
|
||||
*
|
||||
* \section SSec_Compat Demo Compatibility:
|
||||
*
|
||||
* The following list indicates what microcontrollers are compatible with this demo.
|
||||
*
|
||||
* - AT90USB162 (Teensy 1.0)
|
||||
* - AT90USB646 (Teensy++ 1.0)
|
||||
* - ATMEGA32U4 (Teensy 2.0)
|
||||
* - AT90USB1286 (Teensy++ 2.0)
|
||||
*
|
||||
* \section SSec_Info USB Information:
|
||||
*
|
||||
* The following table gives a rundown of the USB utilization of this demo.
|
||||
*
|
||||
* <table>
|
||||
* <tr>
|
||||
* <td><b>USB Mode:</b></td>
|
||||
* <td>Device</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>USB Class:</b></td>
|
||||
* <td>Human Interface Device Class (HID)</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>USB Subclass:</b></td>
|
||||
* <td>N/A</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>Relevant Standards:</b></td>
|
||||
* <td>USBIF HID Class Standard \n
|
||||
* Teensy Programming Protocol Specification</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>Usable Speeds:</b></td>
|
||||
* <td>Low Speed Mode \n
|
||||
* Full Speed Mode</td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*
|
||||
* \section SSec_Description Project Description:
|
||||
*
|
||||
* 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>.
|
||||
*
|
||||
* 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
|
||||
* 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
|
||||
* under 2KB.
|
||||
*
|
||||
* This spoofs (with permission) the official Teensy bootloader's VID and PID, so that the software remains
|
||||
* compatible with no changes.
|
||||
*
|
||||
* \section SSec_Options Project Options
|
||||
*
|
||||
* The following defines can be found in this demo, which can control the demo behaviour when defined, or changed in value.
|
||||
*
|
||||
* <table>
|
||||
* <tr>
|
||||
* <td>
|
||||
* None
|
||||
* </td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*/
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,29 +1,29 @@
|
||||
#
|
||||
# LUFA Library
|
||||
# Copyright (C) Dean Camera, 2010.
|
||||
#
|
||||
# dean [at] fourwalledcubicle [dot] com
|
||||
# www.fourwalledcubicle.com
|
||||
#
|
||||
|
||||
# Makefile to build all the LUFA USB Bootloaders. Call with "make all" to
|
||||
# rebuild all bootloaders.
|
||||
|
||||
# Bootloaders are pre-cleaned before each one is built, to ensure any
|
||||
# custom LUFA library build options are reflected in the compiled
|
||||
# code.
|
||||
|
||||
all:
|
||||
$(MAKE) -C DFU clean
|
||||
$(MAKE) -C DFU all
|
||||
|
||||
$(MAKE) -C CDC clean
|
||||
$(MAKE) -C CDC all
|
||||
|
||||
$(MAKE) -C TeensyHID clean
|
||||
$(MAKE) -C TeensyHID all
|
||||
|
||||
%:
|
||||
$(MAKE) -C DFU $@
|
||||
$(MAKE) -C CDC $@
|
||||
$(MAKE) -C TeensyHID $@
|
||||
#
|
||||
# LUFA Library
|
||||
# Copyright (C) Dean Camera, 2010.
|
||||
#
|
||||
# dean [at] fourwalledcubicle [dot] com
|
||||
# www.fourwalledcubicle.com
|
||||
#
|
||||
|
||||
# Makefile to build all the LUFA USB Bootloaders. Call with "make all" to
|
||||
# rebuild all bootloaders.
|
||||
|
||||
# Bootloaders are pre-cleaned before each one is built, to ensure any
|
||||
# custom LUFA library build options are reflected in the compiled
|
||||
# code.
|
||||
|
||||
all:
|
||||
$(MAKE) -C DFU clean
|
||||
$(MAKE) -C DFU all
|
||||
|
||||
$(MAKE) -C CDC clean
|
||||
$(MAKE) -C CDC all
|
||||
|
||||
$(MAKE) -C TeensyHID clean
|
||||
$(MAKE) -C TeensyHID all
|
||||
|
||||
%:
|
||||
$(MAKE) -C DFU $@
|
||||
$(MAKE) -C CDC $@
|
||||
$(MAKE) -C TeensyHID $@
|
||||
|
@ -1,148 +1,148 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Main source file for the AudioInput demo. This file contains the main tasks of
|
||||
* the demo and is responsible for the initial application hardware configuration.
|
||||
*/
|
||||
|
||||
#include "AudioInput.h"
|
||||
|
||||
/** 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
|
||||
* within a device can be differentiated from one another.
|
||||
*/
|
||||
USB_ClassInfo_Audio_Device_t Microphone_Audio_Interface =
|
||||
{
|
||||
.Config =
|
||||
{
|
||||
.StreamingInterfaceNumber = 1,
|
||||
|
||||
.DataINEndpointNumber = AUDIO_STREAM_EPNUM,
|
||||
.DataINEndpointSize = AUDIO_STREAM_EPSIZE,
|
||||
},
|
||||
};
|
||||
|
||||
/** Main program entry point. This routine contains the overall program flow, including initial
|
||||
* setup of all components and the main program loop.
|
||||
*/
|
||||
int main(void)
|
||||
{
|
||||
SetupHardware();
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
|
||||
sei();
|
||||
|
||||
for (;;)
|
||||
{
|
||||
ProcessNextSample();
|
||||
|
||||
Audio_Device_USBTask(&Microphone_Audio_Interface);
|
||||
USB_USBTask();
|
||||
}
|
||||
}
|
||||
|
||||
/** Configures the board hardware and chip peripherals for the demo's functionality. */
|
||||
void SetupHardware(void)
|
||||
{
|
||||
/* Disable watchdog if enabled by bootloader/fuses */
|
||||
MCUSR &= ~(1 << WDRF);
|
||||
wdt_disable();
|
||||
|
||||
/* Disable clock division */
|
||||
clock_prescale_set(clock_div_1);
|
||||
|
||||
/* Hardware Initialization */
|
||||
LEDs_Init();
|
||||
USB_Init();
|
||||
ADC_Init(ADC_FREE_RUNNING | ADC_PRESCALE_32);
|
||||
ADC_SetupChannel(MIC_IN_ADC_CHANNEL);
|
||||
|
||||
/* Start the ADC conversion in free running mode */
|
||||
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
|
||||
* interface, each time the sample reload timer period elapses to give a constant sample rate.
|
||||
*/
|
||||
void ProcessNextSample(void)
|
||||
{
|
||||
/* 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))
|
||||
{
|
||||
TIFR0 |= (1 << OCF0A);
|
||||
|
||||
/* Audio sample is ADC value scaled to fit the entire range */
|
||||
int16_t AudioSample = ((SAMPLE_MAX_RANGE / ADC_MAX_RANGE) * ADC_GetResult());
|
||||
|
||||
#if defined(MICROPHONE_BIASED_TO_HALF_RAIL)
|
||||
/* Microphone is biased to half rail voltage, subtract the bias from the sample value */
|
||||
AudioSample -= (SAMPLE_MAX_RANGE / 2);
|
||||
#endif
|
||||
|
||||
Audio_Device_WriteSample16(&Microphone_Audio_Interface, AudioSample);
|
||||
}
|
||||
}
|
||||
|
||||
/** Event handler for the library USB Connection event. */
|
||||
void EVENT_USB_Device_Connect(void)
|
||||
{
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
|
||||
|
||||
/* Sample reload timer initialization */
|
||||
OCR0A = (F_CPU / 8 / AUDIO_SAMPLE_FREQUENCY) - 1;
|
||||
TCCR0A = (1 << WGM01); // CTC mode
|
||||
TCCR0B = (1 << CS01); // Fcpu/8 speed
|
||||
}
|
||||
|
||||
/** Event handler for the library USB Disconnection event. */
|
||||
void EVENT_USB_Device_Disconnect(void)
|
||||
{
|
||||
/* Stop the sample reload timer */
|
||||
TCCR0B = 0;
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
|
||||
}
|
||||
|
||||
/** Event handler for the library USB Configuration Changed event. */
|
||||
void EVENT_USB_Device_ConfigurationChanged(void)
|
||||
{
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
|
||||
if (!(Audio_Device_ConfigureEndpoints(&Microphone_Audio_Interface)))
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
}
|
||||
|
||||
/** Event handler for the library USB Unhandled Control Request event. */
|
||||
void EVENT_USB_Device_UnhandledControlRequest(void)
|
||||
{
|
||||
Audio_Device_ProcessControlRequest(&Microphone_Audio_Interface);
|
||||
}
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Main source file for the AudioInput demo. This file contains the main tasks of
|
||||
* the demo and is responsible for the initial application hardware configuration.
|
||||
*/
|
||||
|
||||
#include "AudioInput.h"
|
||||
|
||||
/** 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
|
||||
* within a device can be differentiated from one another.
|
||||
*/
|
||||
USB_ClassInfo_Audio_Device_t Microphone_Audio_Interface =
|
||||
{
|
||||
.Config =
|
||||
{
|
||||
.StreamingInterfaceNumber = 1,
|
||||
|
||||
.DataINEndpointNumber = AUDIO_STREAM_EPNUM,
|
||||
.DataINEndpointSize = AUDIO_STREAM_EPSIZE,
|
||||
},
|
||||
};
|
||||
|
||||
/** Main program entry point. This routine contains the overall program flow, including initial
|
||||
* setup of all components and the main program loop.
|
||||
*/
|
||||
int main(void)
|
||||
{
|
||||
SetupHardware();
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
|
||||
sei();
|
||||
|
||||
for (;;)
|
||||
{
|
||||
ProcessNextSample();
|
||||
|
||||
Audio_Device_USBTask(&Microphone_Audio_Interface);
|
||||
USB_USBTask();
|
||||
}
|
||||
}
|
||||
|
||||
/** Configures the board hardware and chip peripherals for the demo's functionality. */
|
||||
void SetupHardware(void)
|
||||
{
|
||||
/* Disable watchdog if enabled by bootloader/fuses */
|
||||
MCUSR &= ~(1 << WDRF);
|
||||
wdt_disable();
|
||||
|
||||
/* Disable clock division */
|
||||
clock_prescale_set(clock_div_1);
|
||||
|
||||
/* Hardware Initialization */
|
||||
LEDs_Init();
|
||||
USB_Init();
|
||||
ADC_Init(ADC_FREE_RUNNING | ADC_PRESCALE_32);
|
||||
ADC_SetupChannel(MIC_IN_ADC_CHANNEL);
|
||||
|
||||
/* Start the ADC conversion in free running mode */
|
||||
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
|
||||
* interface, each time the sample reload timer period elapses to give a constant sample rate.
|
||||
*/
|
||||
void ProcessNextSample(void)
|
||||
{
|
||||
/* 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))
|
||||
{
|
||||
TIFR0 |= (1 << OCF0A);
|
||||
|
||||
/* Audio sample is ADC value scaled to fit the entire range */
|
||||
int16_t AudioSample = ((SAMPLE_MAX_RANGE / ADC_MAX_RANGE) * ADC_GetResult());
|
||||
|
||||
#if defined(MICROPHONE_BIASED_TO_HALF_RAIL)
|
||||
/* Microphone is biased to half rail voltage, subtract the bias from the sample value */
|
||||
AudioSample -= (SAMPLE_MAX_RANGE / 2);
|
||||
#endif
|
||||
|
||||
Audio_Device_WriteSample16(&Microphone_Audio_Interface, AudioSample);
|
||||
}
|
||||
}
|
||||
|
||||
/** Event handler for the library USB Connection event. */
|
||||
void EVENT_USB_Device_Connect(void)
|
||||
{
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
|
||||
|
||||
/* Sample reload timer initialization */
|
||||
OCR0A = (F_CPU / 8 / AUDIO_SAMPLE_FREQUENCY) - 1;
|
||||
TCCR0A = (1 << WGM01); // CTC mode
|
||||
TCCR0B = (1 << CS01); // Fcpu/8 speed
|
||||
}
|
||||
|
||||
/** Event handler for the library USB Disconnection event. */
|
||||
void EVENT_USB_Device_Disconnect(void)
|
||||
{
|
||||
/* Stop the sample reload timer */
|
||||
TCCR0B = 0;
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
|
||||
}
|
||||
|
||||
/** Event handler for the library USB Configuration Changed event. */
|
||||
void EVENT_USB_Device_ConfigurationChanged(void)
|
||||
{
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
|
||||
if (!(Audio_Device_ConfigureEndpoints(&Microphone_Audio_Interface)))
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
}
|
||||
|
||||
/** Event handler for the library USB Unhandled Control Request event. */
|
||||
void EVENT_USB_Device_UnhandledControlRequest(void)
|
||||
{
|
||||
Audio_Device_ProcessControlRequest(&Microphone_Audio_Interface);
|
||||
}
|
||||
|
@ -1,87 +1,87 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Header file for AudioInput.c.
|
||||
*/
|
||||
|
||||
#ifndef _AUDIO_INPUT_H_
|
||||
#define _AUDIO_INPUT_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/io.h>
|
||||
#include <avr/wdt.h>
|
||||
#include <avr/power.h>
|
||||
#include <avr/interrupt.h>
|
||||
|
||||
#include <LUFA/Version.h>
|
||||
#include <LUFA/Drivers/Board/LEDs.h>
|
||||
#include <LUFA/Drivers/Peripheral/ADC.h>
|
||||
#include <LUFA/Drivers/USB/USB.h>
|
||||
#include <LUFA/Drivers/USB/Class/Audio.h>
|
||||
|
||||
#include "Descriptors.h"
|
||||
|
||||
/* Macros: */
|
||||
/** ADC channel number for the microphone input. */
|
||||
#define MIC_IN_ADC_CHANNEL 2
|
||||
|
||||
/** ADC channel MUX mask for the microphone input. */
|
||||
#define MIC_IN_ADC_MUX_MASK ADC_CHANNEL2
|
||||
|
||||
/** Maximum ADC sample value for the microphone input. */
|
||||
#define SAMPLE_MAX_RANGE 0xFFFF
|
||||
|
||||
/** Maximum ADC range for the microphone input. */
|
||||
#define ADC_MAX_RANGE 0x3FF
|
||||
|
||||
/** LED mask for the library LED driver, to indicate that the USB interface is not ready. */
|
||||
#define LEDMASK_USB_NOTREADY LEDS_LED1
|
||||
|
||||
/** LED mask for the library LED driver, to indicate that the USB interface is enumerating. */
|
||||
#define LEDMASK_USB_ENUMERATING (LEDS_LED2 | LEDS_LED3)
|
||||
|
||||
/** LED mask for the library LED driver, to indicate that the USB interface is ready. */
|
||||
#define LEDMASK_USB_READY (LEDS_LED2 | LEDS_LED4)
|
||||
|
||||
/** LED mask for the library LED driver, to indicate that an error has occurred in the USB interface. */
|
||||
#define LEDMASK_USB_ERROR (LEDS_LED1 | LEDS_LED3)
|
||||
|
||||
/* Function Prototypes: */
|
||||
void SetupHardware(void);
|
||||
void ProcessNextSample(void);
|
||||
|
||||
void EVENT_USB_Device_Connect(void);
|
||||
void EVENT_USB_Device_Disconnect(void);
|
||||
void EVENT_USB_Device_ConfigurationChanged(void);
|
||||
void EVENT_USB_Device_UnhandledControlRequest(void);
|
||||
|
||||
#endif
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Header file for AudioInput.c.
|
||||
*/
|
||||
|
||||
#ifndef _AUDIO_INPUT_H_
|
||||
#define _AUDIO_INPUT_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/io.h>
|
||||
#include <avr/wdt.h>
|
||||
#include <avr/power.h>
|
||||
#include <avr/interrupt.h>
|
||||
|
||||
#include <LUFA/Version.h>
|
||||
#include <LUFA/Drivers/Board/LEDs.h>
|
||||
#include <LUFA/Drivers/Peripheral/ADC.h>
|
||||
#include <LUFA/Drivers/USB/USB.h>
|
||||
#include <LUFA/Drivers/USB/Class/Audio.h>
|
||||
|
||||
#include "Descriptors.h"
|
||||
|
||||
/* Macros: */
|
||||
/** ADC channel number for the microphone input. */
|
||||
#define MIC_IN_ADC_CHANNEL 2
|
||||
|
||||
/** ADC channel MUX mask for the microphone input. */
|
||||
#define MIC_IN_ADC_MUX_MASK ADC_CHANNEL2
|
||||
|
||||
/** Maximum ADC sample value for the microphone input. */
|
||||
#define SAMPLE_MAX_RANGE 0xFFFF
|
||||
|
||||
/** Maximum ADC range for the microphone input. */
|
||||
#define ADC_MAX_RANGE 0x3FF
|
||||
|
||||
/** LED mask for the library LED driver, to indicate that the USB interface is not ready. */
|
||||
#define LEDMASK_USB_NOTREADY LEDS_LED1
|
||||
|
||||
/** LED mask for the library LED driver, to indicate that the USB interface is enumerating. */
|
||||
#define LEDMASK_USB_ENUMERATING (LEDS_LED2 | LEDS_LED3)
|
||||
|
||||
/** LED mask for the library LED driver, to indicate that the USB interface is ready. */
|
||||
#define LEDMASK_USB_READY (LEDS_LED2 | LEDS_LED4)
|
||||
|
||||
/** LED mask for the library LED driver, to indicate that an error has occurred in the USB interface. */
|
||||
#define LEDMASK_USB_ERROR (LEDS_LED1 | LEDS_LED3)
|
||||
|
||||
/* Function Prototypes: */
|
||||
void SetupHardware(void);
|
||||
void ProcessNextSample(void);
|
||||
|
||||
void EVENT_USB_Device_Connect(void);
|
||||
void EVENT_USB_Device_Disconnect(void);
|
||||
void EVENT_USB_Device_ConfigurationChanged(void);
|
||||
void EVENT_USB_Device_UnhandledControlRequest(void);
|
||||
|
||||
#endif
|
||||
|
@ -1,83 +1,83 @@
|
||||
/** \file
|
||||
*
|
||||
* This file contains special DoxyGen information for the generation of the main page and other special
|
||||
* documentation pages. It is not a project source file.
|
||||
*/
|
||||
|
||||
/** \mainpage Audio Input Device Demo
|
||||
*
|
||||
* \section SSec_Compat Demo Compatibility:
|
||||
*
|
||||
* The following list indicates what microcontrollers are compatible with this demo.
|
||||
*
|
||||
* - Series 7 USB AVRs
|
||||
* - Series 6 USB AVRs
|
||||
* - Series 4 USB AVRs
|
||||
*
|
||||
* \section SSec_Info USB Information:
|
||||
*
|
||||
* The following table gives a rundown of the USB utilization of this demo.
|
||||
*
|
||||
* <table>
|
||||
* <tr>
|
||||
* <td><b>USB Mode:</b></td>
|
||||
* <td>Device</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>USB Class:</b></td>
|
||||
* <td>Audio Class</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>USB Subclass:</b></td>
|
||||
* <td>Standard Audio Device</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>Relevant Standards:</b></td>
|
||||
* <td>USBIF Audio Class Specification \n
|
||||
* USBIF Audio Class Terminal Types Specification \n
|
||||
* USBIF Audio Data Formats Specification</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>Usable Speeds:</b></td>
|
||||
* <td>Full Speed Mode</td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*
|
||||
* \section SSec_Description Project Description:
|
||||
*
|
||||
* Audio demonstration application. This gives a simple reference
|
||||
* application for implementing a USB Audio Input device using the
|
||||
* basic USB Audio drivers in all modern OSes (i.e. no special drivers
|
||||
* required).
|
||||
*
|
||||
* On start-up the system will automatically enumerate and function
|
||||
* as a USB microphone. Incoming audio from the ADC channel 1 will
|
||||
* be sampled and sent to the host computer.
|
||||
*
|
||||
* To use, connect a microphone to the ADC channel 1.
|
||||
*
|
||||
* Under Windows, if a driver request dialogue pops up, select the option
|
||||
* to automatically install the appropriate drivers.
|
||||
*
|
||||
* \section SSec_Options Project Options
|
||||
*
|
||||
* The following defines can be found in this demo, which can control the demo behaviour when defined, or changed in value.
|
||||
*
|
||||
* <table>
|
||||
* <tr>
|
||||
* <td><b>Define Name:</b></td>
|
||||
* <td><b>Location:</b></td>
|
||||
* <td><b>Description:</b></td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>MICROPHONE_BIASED_TO_HALF_RAIL</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>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>AUDIO_SAMPLE_FREQUENCY</td>
|
||||
* <td>Descriptors.h</td>
|
||||
* <td>Gives the audio sample rate per channel for the audio stream, in Hz.</td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*/
|
||||
/** \file
|
||||
*
|
||||
* This file contains special DoxyGen information for the generation of the main page and other special
|
||||
* documentation pages. It is not a project source file.
|
||||
*/
|
||||
|
||||
/** \mainpage Audio Input Device Demo
|
||||
*
|
||||
* \section SSec_Compat Demo Compatibility:
|
||||
*
|
||||
* The following list indicates what microcontrollers are compatible with this demo.
|
||||
*
|
||||
* - Series 7 USB AVRs
|
||||
* - Series 6 USB AVRs
|
||||
* - Series 4 USB AVRs
|
||||
*
|
||||
* \section SSec_Info USB Information:
|
||||
*
|
||||
* The following table gives a rundown of the USB utilization of this demo.
|
||||
*
|
||||
* <table>
|
||||
* <tr>
|
||||
* <td><b>USB Mode:</b></td>
|
||||
* <td>Device</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>USB Class:</b></td>
|
||||
* <td>Audio Class</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>USB Subclass:</b></td>
|
||||
* <td>Standard Audio Device</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>Relevant Standards:</b></td>
|
||||
* <td>USBIF Audio Class Specification \n
|
||||
* USBIF Audio Class Terminal Types Specification \n
|
||||
* USBIF Audio Data Formats Specification</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>Usable Speeds:</b></td>
|
||||
* <td>Full Speed Mode</td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*
|
||||
* \section SSec_Description Project Description:
|
||||
*
|
||||
* Audio demonstration application. This gives a simple reference
|
||||
* application for implementing a USB Audio Input device using the
|
||||
* basic USB Audio drivers in all modern OSes (i.e. no special drivers
|
||||
* required).
|
||||
*
|
||||
* On start-up the system will automatically enumerate and function
|
||||
* as a USB microphone. Incoming audio from the ADC channel 1 will
|
||||
* be sampled and sent to the host computer.
|
||||
*
|
||||
* To use, connect a microphone to the ADC channel 1.
|
||||
*
|
||||
* Under Windows, if a driver request dialogue pops up, select the option
|
||||
* to automatically install the appropriate drivers.
|
||||
*
|
||||
* \section SSec_Options Project Options
|
||||
*
|
||||
* The following defines can be found in this demo, which can control the demo behaviour when defined, or changed in value.
|
||||
*
|
||||
* <table>
|
||||
* <tr>
|
||||
* <td><b>Define Name:</b></td>
|
||||
* <td><b>Location:</b></td>
|
||||
* <td><b>Description:</b></td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>MICROPHONE_BIASED_TO_HALF_RAIL</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>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>AUDIO_SAMPLE_FREQUENCY</td>
|
||||
* <td>Descriptors.h</td>
|
||||
* <td>Gives the audio sample rate per channel for the audio stream, in Hz.</td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*/
|
||||
|
@ -1,314 +1,314 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* 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
|
||||
* the device's capabilities and functions.
|
||||
*/
|
||||
|
||||
#include "Descriptors.h"
|
||||
|
||||
/** Device descriptor structure. This descriptor, located in FLASH memory, describes the overall
|
||||
* 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
|
||||
* process begins.
|
||||
*/
|
||||
USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device},
|
||||
|
||||
.USBSpecification = VERSION_BCD(02.00),
|
||||
.Class = 0x00,
|
||||
.SubClass = 0x00,
|
||||
.Protocol = 0x00,
|
||||
|
||||
.Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE,
|
||||
|
||||
.VendorID = 0x03EB,
|
||||
.ProductID = 0x2047,
|
||||
.ReleaseNumber = 0x0000,
|
||||
|
||||
.ManufacturerStrIndex = 0x01,
|
||||
.ProductStrIndex = 0x02,
|
||||
.SerialNumStrIndex = NO_DESCRIPTOR,
|
||||
|
||||
.NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS
|
||||
};
|
||||
|
||||
/** 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
|
||||
* 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.
|
||||
*/
|
||||
USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
|
||||
{
|
||||
.Config =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration},
|
||||
|
||||
.TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t),
|
||||
.TotalInterfaces = 2,
|
||||
|
||||
.ConfigurationNumber = 1,
|
||||
.ConfigurationStrIndex = NO_DESCRIPTOR,
|
||||
|
||||
.ConfigAttributes = (USB_CONFIG_ATTR_BUSPOWERED | USB_CONFIG_ATTR_SELFPOWERED),
|
||||
|
||||
.MaxPowerConsumption = USB_CONFIG_POWER_MA(100)
|
||||
},
|
||||
|
||||
.Audio_ControlInterface =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
|
||||
|
||||
.InterfaceNumber = 0,
|
||||
.AlternateSetting = 0,
|
||||
|
||||
.TotalEndpoints = 0,
|
||||
|
||||
.Class = 0x01,
|
||||
.SubClass = 0x01,
|
||||
.Protocol = 0x00,
|
||||
|
||||
.InterfaceStrIndex = NO_DESCRIPTOR
|
||||
},
|
||||
|
||||
.Audio_ControlInterface_SPC =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Audio_Interface_AC_t), .Type = DTYPE_AudioInterface},
|
||||
.Subtype = DSUBTYPE_Header,
|
||||
|
||||
.ACSpecification = VERSION_BCD(01.00),
|
||||
.TotalLength = (sizeof(USB_Audio_Interface_AC_t) +
|
||||
sizeof(USB_Audio_InputTerminal_t) +
|
||||
sizeof(USB_Audio_OutputTerminal_t)),
|
||||
|
||||
.InCollection = 1,
|
||||
.InterfaceNumbers = {1},
|
||||
},
|
||||
|
||||
.Audio_InputTerminal =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Audio_InputTerminal_t), .Type = DTYPE_AudioInterface},
|
||||
.Subtype = DSUBTYPE_InputTerminal,
|
||||
|
||||
.TerminalID = 0x01,
|
||||
.TerminalType = TERMINAL_IN_MIC,
|
||||
.AssociatedOutputTerminal = 0x00,
|
||||
|
||||
.TotalChannels = 1,
|
||||
.ChannelConfig = 0,
|
||||
|
||||
.ChannelStrIndex = NO_DESCRIPTOR,
|
||||
.TerminalStrIndex = NO_DESCRIPTOR
|
||||
},
|
||||
|
||||
.Audio_OutputTerminal =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Audio_OutputTerminal_t), .Type = DTYPE_AudioInterface},
|
||||
.Subtype = DSUBTYPE_OutputTerminal,
|
||||
|
||||
.TerminalID = 0x02,
|
||||
.TerminalType = TERMINAL_STREAMING,
|
||||
.AssociatedInputTerminal = 0x00,
|
||||
|
||||
.SourceID = 0x01,
|
||||
|
||||
.TerminalStrIndex = NO_DESCRIPTOR
|
||||
},
|
||||
|
||||
.Audio_StreamInterface_Alt0 =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
|
||||
|
||||
.InterfaceNumber = 1,
|
||||
.AlternateSetting = 0,
|
||||
|
||||
.TotalEndpoints = 0,
|
||||
|
||||
.Class = 0x01,
|
||||
.SubClass = 0x02,
|
||||
.Protocol = 0x00,
|
||||
|
||||
.InterfaceStrIndex = NO_DESCRIPTOR
|
||||
},
|
||||
|
||||
.Audio_StreamInterface_Alt1 =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
|
||||
|
||||
.InterfaceNumber = 1,
|
||||
.AlternateSetting = 1,
|
||||
|
||||
.TotalEndpoints = 1,
|
||||
|
||||
.Class = 0x01,
|
||||
.SubClass = 0x02,
|
||||
.Protocol = 0x00,
|
||||
|
||||
.InterfaceStrIndex = NO_DESCRIPTOR
|
||||
},
|
||||
|
||||
.Audio_StreamInterface_SPC =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Audio_Interface_AS_t), .Type = DTYPE_AudioInterface},
|
||||
.Subtype = DSUBTYPE_General,
|
||||
|
||||
.TerminalLink = 0x02,
|
||||
|
||||
.FrameDelay = 1,
|
||||
.AudioFormat = 0x0001
|
||||
},
|
||||
|
||||
.Audio_AudioFormat =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Audio_Format_t), .Type = DTYPE_AudioInterface},
|
||||
.Subtype = DSUBTYPE_Format,
|
||||
|
||||
.FormatType = 0x01,
|
||||
.Channels = 0x01,
|
||||
|
||||
.SubFrameSize = 0x02,
|
||||
.BitResolution = 16,
|
||||
.SampleFrequencyType = AUDIO_TOTAL_SAMPLE_RATES,
|
||||
|
||||
.SampleFrequencies = {AUDIO_SAMPLE_FREQ(AUDIO_SAMPLE_FREQUENCY)}
|
||||
},
|
||||
|
||||
.Audio_StreamEndpoint =
|
||||
{
|
||||
.Endpoint =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Audio_StreamEndpoint_Std_t), .Type = DTYPE_Endpoint},
|
||||
|
||||
.EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_IN | AUDIO_STREAM_EPNUM),
|
||||
.Attributes = (EP_TYPE_ISOCHRONOUS | ENDPOINT_ATTR_SYNC | ENDPOINT_USAGE_DATA),
|
||||
.EndpointSize = AUDIO_STREAM_EPSIZE,
|
||||
.PollingIntervalMS = 1
|
||||
},
|
||||
|
||||
.Refresh = 0,
|
||||
.SyncEndpointNumber = 0
|
||||
},
|
||||
|
||||
.Audio_StreamEndpoint_SPC =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Audio_StreamEndpoint_Spc_t), .Type = DTYPE_AudioEndpoint},
|
||||
.Subtype = DSUBTYPE_General,
|
||||
|
||||
.Attributes = 0x00,
|
||||
|
||||
.LockDelayUnits = 0x00,
|
||||
.LockDelay = 0x0000
|
||||
}
|
||||
};
|
||||
|
||||
/** 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
|
||||
* via the language ID table available at USB.org what languages the device supports for its string descriptors.
|
||||
*/
|
||||
USB_Descriptor_String_t PROGMEM LanguageString =
|
||||
{
|
||||
.Header = {.Size = USB_STRING_LEN(1), .Type = DTYPE_String},
|
||||
|
||||
.UnicodeString = {LANGUAGE_ID_ENG}
|
||||
};
|
||||
|
||||
/** 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
|
||||
* Descriptor.
|
||||
*/
|
||||
USB_Descriptor_String_t PROGMEM ManufacturerString =
|
||||
{
|
||||
.Header = {.Size = USB_STRING_LEN(11), .Type = DTYPE_String},
|
||||
|
||||
.UnicodeString = L"Dean Camera"
|
||||
};
|
||||
|
||||
/** 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
|
||||
* Descriptor.
|
||||
*/
|
||||
USB_Descriptor_String_t PROGMEM ProductString =
|
||||
{
|
||||
.Header = {.Size = USB_STRING_LEN(18), .Type = DTYPE_String},
|
||||
|
||||
.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"
|
||||
* 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
|
||||
* is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the
|
||||
* USB host.
|
||||
*/
|
||||
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 DescriptorNumber = (wValue & 0xFF);
|
||||
|
||||
void* Address = NULL;
|
||||
uint16_t Size = NO_DESCRIPTOR;
|
||||
|
||||
switch (DescriptorType)
|
||||
{
|
||||
case DTYPE_Device:
|
||||
Address = (void*)&DeviceDescriptor;
|
||||
Size = sizeof(USB_Descriptor_Device_t);
|
||||
break;
|
||||
case DTYPE_Configuration:
|
||||
Address = (void*)&ConfigurationDescriptor;
|
||||
Size = sizeof(USB_Descriptor_Configuration_t);
|
||||
break;
|
||||
case DTYPE_String:
|
||||
switch (DescriptorNumber)
|
||||
{
|
||||
case 0x00:
|
||||
Address = (void*)&LanguageString;
|
||||
Size = pgm_read_byte(&LanguageString.Header.Size);
|
||||
break;
|
||||
case 0x01:
|
||||
Address = (void*)&ManufacturerString;
|
||||
Size = pgm_read_byte(&ManufacturerString.Header.Size);
|
||||
break;
|
||||
case 0x02:
|
||||
Address = (void*)&ProductString;
|
||||
Size = pgm_read_byte(&ProductString.Header.Size);
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
*DescriptorAddress = Address;
|
||||
return Size;
|
||||
}
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* 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
|
||||
* the device's capabilities and functions.
|
||||
*/
|
||||
|
||||
#include "Descriptors.h"
|
||||
|
||||
/** Device descriptor structure. This descriptor, located in FLASH memory, describes the overall
|
||||
* 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
|
||||
* process begins.
|
||||
*/
|
||||
USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device},
|
||||
|
||||
.USBSpecification = VERSION_BCD(02.00),
|
||||
.Class = 0x00,
|
||||
.SubClass = 0x00,
|
||||
.Protocol = 0x00,
|
||||
|
||||
.Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE,
|
||||
|
||||
.VendorID = 0x03EB,
|
||||
.ProductID = 0x2047,
|
||||
.ReleaseNumber = 0x0000,
|
||||
|
||||
.ManufacturerStrIndex = 0x01,
|
||||
.ProductStrIndex = 0x02,
|
||||
.SerialNumStrIndex = NO_DESCRIPTOR,
|
||||
|
||||
.NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS
|
||||
};
|
||||
|
||||
/** 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
|
||||
* 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.
|
||||
*/
|
||||
USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
|
||||
{
|
||||
.Config =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration},
|
||||
|
||||
.TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t),
|
||||
.TotalInterfaces = 2,
|
||||
|
||||
.ConfigurationNumber = 1,
|
||||
.ConfigurationStrIndex = NO_DESCRIPTOR,
|
||||
|
||||
.ConfigAttributes = (USB_CONFIG_ATTR_BUSPOWERED | USB_CONFIG_ATTR_SELFPOWERED),
|
||||
|
||||
.MaxPowerConsumption = USB_CONFIG_POWER_MA(100)
|
||||
},
|
||||
|
||||
.Audio_ControlInterface =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
|
||||
|
||||
.InterfaceNumber = 0,
|
||||
.AlternateSetting = 0,
|
||||
|
||||
.TotalEndpoints = 0,
|
||||
|
||||
.Class = 0x01,
|
||||
.SubClass = 0x01,
|
||||
.Protocol = 0x00,
|
||||
|
||||
.InterfaceStrIndex = NO_DESCRIPTOR
|
||||
},
|
||||
|
||||
.Audio_ControlInterface_SPC =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Audio_Interface_AC_t), .Type = DTYPE_AudioInterface},
|
||||
.Subtype = DSUBTYPE_Header,
|
||||
|
||||
.ACSpecification = VERSION_BCD(01.00),
|
||||
.TotalLength = (sizeof(USB_Audio_Interface_AC_t) +
|
||||
sizeof(USB_Audio_InputTerminal_t) +
|
||||
sizeof(USB_Audio_OutputTerminal_t)),
|
||||
|
||||
.InCollection = 1,
|
||||
.InterfaceNumbers = {1},
|
||||
},
|
||||
|
||||
.Audio_InputTerminal =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Audio_InputTerminal_t), .Type = DTYPE_AudioInterface},
|
||||
.Subtype = DSUBTYPE_InputTerminal,
|
||||
|
||||
.TerminalID = 0x01,
|
||||
.TerminalType = TERMINAL_IN_MIC,
|
||||
.AssociatedOutputTerminal = 0x00,
|
||||
|
||||
.TotalChannels = 1,
|
||||
.ChannelConfig = 0,
|
||||
|
||||
.ChannelStrIndex = NO_DESCRIPTOR,
|
||||
.TerminalStrIndex = NO_DESCRIPTOR
|
||||
},
|
||||
|
||||
.Audio_OutputTerminal =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Audio_OutputTerminal_t), .Type = DTYPE_AudioInterface},
|
||||
.Subtype = DSUBTYPE_OutputTerminal,
|
||||
|
||||
.TerminalID = 0x02,
|
||||
.TerminalType = TERMINAL_STREAMING,
|
||||
.AssociatedInputTerminal = 0x00,
|
||||
|
||||
.SourceID = 0x01,
|
||||
|
||||
.TerminalStrIndex = NO_DESCRIPTOR
|
||||
},
|
||||
|
||||
.Audio_StreamInterface_Alt0 =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
|
||||
|
||||
.InterfaceNumber = 1,
|
||||
.AlternateSetting = 0,
|
||||
|
||||
.TotalEndpoints = 0,
|
||||
|
||||
.Class = 0x01,
|
||||
.SubClass = 0x02,
|
||||
.Protocol = 0x00,
|
||||
|
||||
.InterfaceStrIndex = NO_DESCRIPTOR
|
||||
},
|
||||
|
||||
.Audio_StreamInterface_Alt1 =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
|
||||
|
||||
.InterfaceNumber = 1,
|
||||
.AlternateSetting = 1,
|
||||
|
||||
.TotalEndpoints = 1,
|
||||
|
||||
.Class = 0x01,
|
||||
.SubClass = 0x02,
|
||||
.Protocol = 0x00,
|
||||
|
||||
.InterfaceStrIndex = NO_DESCRIPTOR
|
||||
},
|
||||
|
||||
.Audio_StreamInterface_SPC =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Audio_Interface_AS_t), .Type = DTYPE_AudioInterface},
|
||||
.Subtype = DSUBTYPE_General,
|
||||
|
||||
.TerminalLink = 0x02,
|
||||
|
||||
.FrameDelay = 1,
|
||||
.AudioFormat = 0x0001
|
||||
},
|
||||
|
||||
.Audio_AudioFormat =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Audio_Format_t), .Type = DTYPE_AudioInterface},
|
||||
.Subtype = DSUBTYPE_Format,
|
||||
|
||||
.FormatType = 0x01,
|
||||
.Channels = 0x01,
|
||||
|
||||
.SubFrameSize = 0x02,
|
||||
.BitResolution = 16,
|
||||
.SampleFrequencyType = AUDIO_TOTAL_SAMPLE_RATES,
|
||||
|
||||
.SampleFrequencies = {AUDIO_SAMPLE_FREQ(AUDIO_SAMPLE_FREQUENCY)}
|
||||
},
|
||||
|
||||
.Audio_StreamEndpoint =
|
||||
{
|
||||
.Endpoint =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Audio_StreamEndpoint_Std_t), .Type = DTYPE_Endpoint},
|
||||
|
||||
.EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_IN | AUDIO_STREAM_EPNUM),
|
||||
.Attributes = (EP_TYPE_ISOCHRONOUS | ENDPOINT_ATTR_SYNC | ENDPOINT_USAGE_DATA),
|
||||
.EndpointSize = AUDIO_STREAM_EPSIZE,
|
||||
.PollingIntervalMS = 1
|
||||
},
|
||||
|
||||
.Refresh = 0,
|
||||
.SyncEndpointNumber = 0
|
||||
},
|
||||
|
||||
.Audio_StreamEndpoint_SPC =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Audio_StreamEndpoint_Spc_t), .Type = DTYPE_AudioEndpoint},
|
||||
.Subtype = DSUBTYPE_General,
|
||||
|
||||
.Attributes = 0x00,
|
||||
|
||||
.LockDelayUnits = 0x00,
|
||||
.LockDelay = 0x0000
|
||||
}
|
||||
};
|
||||
|
||||
/** 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
|
||||
* via the language ID table available at USB.org what languages the device supports for its string descriptors.
|
||||
*/
|
||||
USB_Descriptor_String_t PROGMEM LanguageString =
|
||||
{
|
||||
.Header = {.Size = USB_STRING_LEN(1), .Type = DTYPE_String},
|
||||
|
||||
.UnicodeString = {LANGUAGE_ID_ENG}
|
||||
};
|
||||
|
||||
/** 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
|
||||
* Descriptor.
|
||||
*/
|
||||
USB_Descriptor_String_t PROGMEM ManufacturerString =
|
||||
{
|
||||
.Header = {.Size = USB_STRING_LEN(11), .Type = DTYPE_String},
|
||||
|
||||
.UnicodeString = L"Dean Camera"
|
||||
};
|
||||
|
||||
/** 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
|
||||
* Descriptor.
|
||||
*/
|
||||
USB_Descriptor_String_t PROGMEM ProductString =
|
||||
{
|
||||
.Header = {.Size = USB_STRING_LEN(18), .Type = DTYPE_String},
|
||||
|
||||
.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"
|
||||
* 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
|
||||
* is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the
|
||||
* USB host.
|
||||
*/
|
||||
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 DescriptorNumber = (wValue & 0xFF);
|
||||
|
||||
void* Address = NULL;
|
||||
uint16_t Size = NO_DESCRIPTOR;
|
||||
|
||||
switch (DescriptorType)
|
||||
{
|
||||
case DTYPE_Device:
|
||||
Address = (void*)&DeviceDescriptor;
|
||||
Size = sizeof(USB_Descriptor_Device_t);
|
||||
break;
|
||||
case DTYPE_Configuration:
|
||||
Address = (void*)&ConfigurationDescriptor;
|
||||
Size = sizeof(USB_Descriptor_Configuration_t);
|
||||
break;
|
||||
case DTYPE_String:
|
||||
switch (DescriptorNumber)
|
||||
{
|
||||
case 0x00:
|
||||
Address = (void*)&LanguageString;
|
||||
Size = pgm_read_byte(&LanguageString.Header.Size);
|
||||
break;
|
||||
case 0x01:
|
||||
Address = (void*)&ManufacturerString;
|
||||
Size = pgm_read_byte(&ManufacturerString.Header.Size);
|
||||
break;
|
||||
case 0x02:
|
||||
Address = (void*)&ProductString;
|
||||
Size = pgm_read_byte(&ProductString.Header.Size);
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
*DescriptorAddress = Address;
|
||||
return Size;
|
||||
}
|
||||
|
@ -1,82 +1,82 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Header file for Descriptors.c.
|
||||
*/
|
||||
|
||||
#ifndef _DESCRIPTORS_H_
|
||||
#define _DESCRIPTORS_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <LUFA/Drivers/USB/USB.h>
|
||||
#include <LUFA/Drivers/USB/Class/Audio.h>
|
||||
|
||||
#include <avr/pgmspace.h>
|
||||
|
||||
/* Macros: */
|
||||
/** Endpoint number of the Audio isochronous streaming data endpoint. */
|
||||
#define AUDIO_STREAM_EPNUM 1
|
||||
|
||||
/** 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
|
||||
* USB AVR models will result in unavoidable distorted output.
|
||||
*/
|
||||
#define AUDIO_STREAM_EPSIZE ENDPOINT_MAX_SIZE(AUDIO_STREAM_EPNUM)
|
||||
|
||||
/** Sample frequency of the data being transmitted through the streaming endpoint. */
|
||||
#define AUDIO_SAMPLE_FREQUENCY 48000
|
||||
|
||||
/* Type Defines: */
|
||||
/** 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
|
||||
* vary between devices, and which describe the device's usage to the host.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
USB_Descriptor_Configuration_Header_t Config;
|
||||
USB_Descriptor_Interface_t Audio_ControlInterface;
|
||||
USB_Audio_Interface_AC_t Audio_ControlInterface_SPC;
|
||||
USB_Audio_InputTerminal_t Audio_InputTerminal;
|
||||
USB_Audio_OutputTerminal_t Audio_OutputTerminal;
|
||||
USB_Descriptor_Interface_t Audio_StreamInterface_Alt0;
|
||||
USB_Descriptor_Interface_t Audio_StreamInterface_Alt1;
|
||||
USB_Audio_Interface_AS_t Audio_StreamInterface_SPC;
|
||||
USB_Audio_Format_t Audio_AudioFormat;
|
||||
USB_Audio_StreamEndpoint_Std_t Audio_StreamEndpoint;
|
||||
USB_Audio_StreamEndpoint_Spc_t Audio_StreamEndpoint_SPC;
|
||||
} USB_Descriptor_Configuration_t;
|
||||
|
||||
/* Function Prototypes: */
|
||||
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);
|
||||
|
||||
#endif
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Header file for Descriptors.c.
|
||||
*/
|
||||
|
||||
#ifndef _DESCRIPTORS_H_
|
||||
#define _DESCRIPTORS_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <LUFA/Drivers/USB/USB.h>
|
||||
#include <LUFA/Drivers/USB/Class/Audio.h>
|
||||
|
||||
#include <avr/pgmspace.h>
|
||||
|
||||
/* Macros: */
|
||||
/** Endpoint number of the Audio isochronous streaming data endpoint. */
|
||||
#define AUDIO_STREAM_EPNUM 1
|
||||
|
||||
/** 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
|
||||
* USB AVR models will result in unavoidable distorted output.
|
||||
*/
|
||||
#define AUDIO_STREAM_EPSIZE ENDPOINT_MAX_SIZE(AUDIO_STREAM_EPNUM)
|
||||
|
||||
/** Sample frequency of the data being transmitted through the streaming endpoint. */
|
||||
#define AUDIO_SAMPLE_FREQUENCY 48000
|
||||
|
||||
/* Type Defines: */
|
||||
/** 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
|
||||
* vary between devices, and which describe the device's usage to the host.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
USB_Descriptor_Configuration_Header_t Config;
|
||||
USB_Descriptor_Interface_t Audio_ControlInterface;
|
||||
USB_Audio_Interface_AC_t Audio_ControlInterface_SPC;
|
||||
USB_Audio_InputTerminal_t Audio_InputTerminal;
|
||||
USB_Audio_OutputTerminal_t Audio_OutputTerminal;
|
||||
USB_Descriptor_Interface_t Audio_StreamInterface_Alt0;
|
||||
USB_Descriptor_Interface_t Audio_StreamInterface_Alt1;
|
||||
USB_Audio_Interface_AS_t Audio_StreamInterface_SPC;
|
||||
USB_Audio_Format_t Audio_AudioFormat;
|
||||
USB_Audio_StreamEndpoint_Std_t Audio_StreamEndpoint;
|
||||
USB_Audio_StreamEndpoint_Spc_t Audio_StreamEndpoint_SPC;
|
||||
} USB_Descriptor_Configuration_t;
|
||||
|
||||
/* Function Prototypes: */
|
||||
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);
|
||||
|
||||
#endif
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,201 +1,201 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Main source file for the AudioOutput demo. This file contains the main tasks of
|
||||
* the demo and is responsible for the initial application hardware configuration.
|
||||
*/
|
||||
|
||||
#include "AudioOutput.h"
|
||||
|
||||
/** 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
|
||||
* within a device can be differentiated from one another.
|
||||
*/
|
||||
USB_ClassInfo_Audio_Device_t Speaker_Audio_Interface =
|
||||
{
|
||||
.Config =
|
||||
{
|
||||
.StreamingInterfaceNumber = 1,
|
||||
|
||||
.DataOUTEndpointNumber = AUDIO_STREAM_EPNUM,
|
||||
.DataOUTEndpointSize = AUDIO_STREAM_EPSIZE,
|
||||
},
|
||||
};
|
||||
|
||||
/** Main program entry point. This routine contains the overall program flow, including initial
|
||||
* setup of all components and the main program loop.
|
||||
*/
|
||||
int main(void)
|
||||
{
|
||||
SetupHardware();
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
|
||||
sei();
|
||||
|
||||
for (;;)
|
||||
{
|
||||
ProcessNextSample();
|
||||
|
||||
Audio_Device_USBTask(&Speaker_Audio_Interface);
|
||||
USB_USBTask();
|
||||
}
|
||||
}
|
||||
|
||||
/** Configures the board hardware and chip peripherals for the demo's functionality. */
|
||||
void SetupHardware(void)
|
||||
{
|
||||
/* Disable watchdog if enabled by bootloader/fuses */
|
||||
MCUSR &= ~(1 << WDRF);
|
||||
wdt_disable();
|
||||
|
||||
/* Disable clock division */
|
||||
clock_prescale_set(clock_div_1);
|
||||
|
||||
/* Hardware Initialization */
|
||||
LEDs_Init();
|
||||
USB_Init();
|
||||
}
|
||||
|
||||
/** 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.
|
||||
*/
|
||||
void ProcessNextSample(void)
|
||||
{
|
||||
/* 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))
|
||||
{
|
||||
/* Clear the sample reload timer */
|
||||
TIFR0 |= (1 << OCF0A);
|
||||
|
||||
/* 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 RightSample_8Bit = (Audio_Device_ReadSample16(&Speaker_Audio_Interface) >> 8);
|
||||
|
||||
/* 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);
|
||||
|
||||
#if defined(AUDIO_OUT_MONO)
|
||||
/* Load the sample into the PWM timer channel */
|
||||
OCR3A = (MixedSample_8Bit ^ (1 << 7));
|
||||
#elif defined(AUDIO_OUT_STEREO)
|
||||
/* Load the dual 8-bit samples into the PWM timer channels */
|
||||
OCR3A = (LeftSample_8Bit ^ (1 << 7));
|
||||
OCR3B = (RightSample_8Bit ^ (1 << 7));
|
||||
#elif defined(AUDIO_OUT_PORTC)
|
||||
/* Load the 8-bit mixed sample into PORTC */
|
||||
PORTC = MixedSample_8Bit;
|
||||
#endif
|
||||
|
||||
uint8_t LEDMask = LEDS_NO_LEDS;
|
||||
|
||||
/* Turn on LEDs as the sample amplitude increases */
|
||||
if (MixedSample_8Bit > 16)
|
||||
LEDMask = (LEDS_LED1 | LEDS_LED2 | LEDS_LED3 | LEDS_LED4);
|
||||
else if (MixedSample_8Bit > 8)
|
||||
LEDMask = (LEDS_LED1 | LEDS_LED2 | LEDS_LED3);
|
||||
else if (MixedSample_8Bit > 4)
|
||||
LEDMask = (LEDS_LED1 | LEDS_LED2);
|
||||
else if (MixedSample_8Bit > 2)
|
||||
LEDMask = (LEDS_LED1);
|
||||
|
||||
LEDs_SetAllLEDs(LEDMask);
|
||||
}
|
||||
}
|
||||
|
||||
/** Event handler for the library USB Connection event. */
|
||||
void EVENT_USB_Device_Connect(void)
|
||||
{
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
|
||||
|
||||
/* Sample reload timer initialization */
|
||||
OCR0A = (F_CPU / 8 / AUDIO_SAMPLE_FREQUENCY) - 1;
|
||||
TCCR0A = (1 << WGM01); // CTC mode
|
||||
TCCR0B = (1 << CS01); // Fcpu/8 speed
|
||||
|
||||
#if defined(AUDIO_OUT_MONO)
|
||||
/* Set speaker as output */
|
||||
DDRC |= (1 << 6);
|
||||
#elif defined(AUDIO_OUT_STEREO)
|
||||
/* Set speakers as outputs */
|
||||
DDRC |= ((1 << 6) | (1 << 5));
|
||||
#elif defined(AUDIO_OUT_PORTC)
|
||||
/* Set PORTC as outputs */
|
||||
DDRC |= 0xFF;
|
||||
#endif
|
||||
|
||||
#if (defined(AUDIO_OUT_MONO) || defined(AUDIO_OUT_STEREO))
|
||||
/* PWM speaker timer initialization */
|
||||
TCCR3A = ((1 << WGM30) | (1 << COM3A1) | (1 << COM3A0)
|
||||
| (1 << COM3B1) | (1 << COM3B0)); // Set on match, clear on TOP
|
||||
TCCR3B = ((1 << WGM32) | (1 << CS30)); // Fast 8-Bit PWM, Fcpu speed
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Event handler for the library USB Disconnection event. */
|
||||
void EVENT_USB_Device_Disconnect(void)
|
||||
{
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
|
||||
|
||||
/* Stop the sample reload timer */
|
||||
TCCR0B = 0;
|
||||
|
||||
#if (defined(AUDIO_OUT_MONO) || defined(AUDIO_OUT_STEREO))
|
||||
/* Stop the PWM generation timer */
|
||||
TCCR3B = 0;
|
||||
#endif
|
||||
|
||||
#if defined(AUDIO_OUT_MONO)
|
||||
/* Set speaker as input to reduce current draw */
|
||||
DDRC &= ~(1 << 6);
|
||||
#elif defined(AUDIO_OUT_STEREO)
|
||||
/* Set speakers as inputs to reduce current draw */
|
||||
DDRC &= ~((1 << 6) | (1 << 5));
|
||||
#elif defined(AUDIO_OUT_PORTC)
|
||||
/* Set PORTC low */
|
||||
PORTC = 0x00;
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Event handler for the library USB Configuration Changed event. */
|
||||
void EVENT_USB_Device_ConfigurationChanged(void)
|
||||
{
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
|
||||
if (!(Audio_Device_ConfigureEndpoints(&Speaker_Audio_Interface)))
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
}
|
||||
|
||||
/** Event handler for the library USB Unhandled Control Request event. */
|
||||
void EVENT_USB_Device_UnhandledControlRequest(void)
|
||||
{
|
||||
Audio_Device_ProcessControlRequest(&Speaker_Audio_Interface);
|
||||
}
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Main source file for the AudioOutput demo. This file contains the main tasks of
|
||||
* the demo and is responsible for the initial application hardware configuration.
|
||||
*/
|
||||
|
||||
#include "AudioOutput.h"
|
||||
|
||||
/** 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
|
||||
* within a device can be differentiated from one another.
|
||||
*/
|
||||
USB_ClassInfo_Audio_Device_t Speaker_Audio_Interface =
|
||||
{
|
||||
.Config =
|
||||
{
|
||||
.StreamingInterfaceNumber = 1,
|
||||
|
||||
.DataOUTEndpointNumber = AUDIO_STREAM_EPNUM,
|
||||
.DataOUTEndpointSize = AUDIO_STREAM_EPSIZE,
|
||||
},
|
||||
};
|
||||
|
||||
/** Main program entry point. This routine contains the overall program flow, including initial
|
||||
* setup of all components and the main program loop.
|
||||
*/
|
||||
int main(void)
|
||||
{
|
||||
SetupHardware();
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
|
||||
sei();
|
||||
|
||||
for (;;)
|
||||
{
|
||||
ProcessNextSample();
|
||||
|
||||
Audio_Device_USBTask(&Speaker_Audio_Interface);
|
||||
USB_USBTask();
|
||||
}
|
||||
}
|
||||
|
||||
/** Configures the board hardware and chip peripherals for the demo's functionality. */
|
||||
void SetupHardware(void)
|
||||
{
|
||||
/* Disable watchdog if enabled by bootloader/fuses */
|
||||
MCUSR &= ~(1 << WDRF);
|
||||
wdt_disable();
|
||||
|
||||
/* Disable clock division */
|
||||
clock_prescale_set(clock_div_1);
|
||||
|
||||
/* Hardware Initialization */
|
||||
LEDs_Init();
|
||||
USB_Init();
|
||||
}
|
||||
|
||||
/** 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.
|
||||
*/
|
||||
void ProcessNextSample(void)
|
||||
{
|
||||
/* 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))
|
||||
{
|
||||
/* Clear the sample reload timer */
|
||||
TIFR0 |= (1 << OCF0A);
|
||||
|
||||
/* 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 RightSample_8Bit = (Audio_Device_ReadSample16(&Speaker_Audio_Interface) >> 8);
|
||||
|
||||
/* 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);
|
||||
|
||||
#if defined(AUDIO_OUT_MONO)
|
||||
/* Load the sample into the PWM timer channel */
|
||||
OCR3A = (MixedSample_8Bit ^ (1 << 7));
|
||||
#elif defined(AUDIO_OUT_STEREO)
|
||||
/* Load the dual 8-bit samples into the PWM timer channels */
|
||||
OCR3A = (LeftSample_8Bit ^ (1 << 7));
|
||||
OCR3B = (RightSample_8Bit ^ (1 << 7));
|
||||
#elif defined(AUDIO_OUT_PORTC)
|
||||
/* Load the 8-bit mixed sample into PORTC */
|
||||
PORTC = MixedSample_8Bit;
|
||||
#endif
|
||||
|
||||
uint8_t LEDMask = LEDS_NO_LEDS;
|
||||
|
||||
/* Turn on LEDs as the sample amplitude increases */
|
||||
if (MixedSample_8Bit > 16)
|
||||
LEDMask = (LEDS_LED1 | LEDS_LED2 | LEDS_LED3 | LEDS_LED4);
|
||||
else if (MixedSample_8Bit > 8)
|
||||
LEDMask = (LEDS_LED1 | LEDS_LED2 | LEDS_LED3);
|
||||
else if (MixedSample_8Bit > 4)
|
||||
LEDMask = (LEDS_LED1 | LEDS_LED2);
|
||||
else if (MixedSample_8Bit > 2)
|
||||
LEDMask = (LEDS_LED1);
|
||||
|
||||
LEDs_SetAllLEDs(LEDMask);
|
||||
}
|
||||
}
|
||||
|
||||
/** Event handler for the library USB Connection event. */
|
||||
void EVENT_USB_Device_Connect(void)
|
||||
{
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
|
||||
|
||||
/* Sample reload timer initialization */
|
||||
OCR0A = (F_CPU / 8 / AUDIO_SAMPLE_FREQUENCY) - 1;
|
||||
TCCR0A = (1 << WGM01); // CTC mode
|
||||
TCCR0B = (1 << CS01); // Fcpu/8 speed
|
||||
|
||||
#if defined(AUDIO_OUT_MONO)
|
||||
/* Set speaker as output */
|
||||
DDRC |= (1 << 6);
|
||||
#elif defined(AUDIO_OUT_STEREO)
|
||||
/* Set speakers as outputs */
|
||||
DDRC |= ((1 << 6) | (1 << 5));
|
||||
#elif defined(AUDIO_OUT_PORTC)
|
||||
/* Set PORTC as outputs */
|
||||
DDRC |= 0xFF;
|
||||
#endif
|
||||
|
||||
#if (defined(AUDIO_OUT_MONO) || defined(AUDIO_OUT_STEREO))
|
||||
/* PWM speaker timer initialization */
|
||||
TCCR3A = ((1 << WGM30) | (1 << COM3A1) | (1 << COM3A0)
|
||||
| (1 << COM3B1) | (1 << COM3B0)); // Set on match, clear on TOP
|
||||
TCCR3B = ((1 << WGM32) | (1 << CS30)); // Fast 8-Bit PWM, Fcpu speed
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Event handler for the library USB Disconnection event. */
|
||||
void EVENT_USB_Device_Disconnect(void)
|
||||
{
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
|
||||
|
||||
/* Stop the sample reload timer */
|
||||
TCCR0B = 0;
|
||||
|
||||
#if (defined(AUDIO_OUT_MONO) || defined(AUDIO_OUT_STEREO))
|
||||
/* Stop the PWM generation timer */
|
||||
TCCR3B = 0;
|
||||
#endif
|
||||
|
||||
#if defined(AUDIO_OUT_MONO)
|
||||
/* Set speaker as input to reduce current draw */
|
||||
DDRC &= ~(1 << 6);
|
||||
#elif defined(AUDIO_OUT_STEREO)
|
||||
/* Set speakers as inputs to reduce current draw */
|
||||
DDRC &= ~((1 << 6) | (1 << 5));
|
||||
#elif defined(AUDIO_OUT_PORTC)
|
||||
/* Set PORTC low */
|
||||
PORTC = 0x00;
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Event handler for the library USB Configuration Changed event. */
|
||||
void EVENT_USB_Device_ConfigurationChanged(void)
|
||||
{
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
|
||||
if (!(Audio_Device_ConfigureEndpoints(&Speaker_Audio_Interface)))
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
}
|
||||
|
||||
/** Event handler for the library USB Unhandled Control Request event. */
|
||||
void EVENT_USB_Device_UnhandledControlRequest(void)
|
||||
{
|
||||
Audio_Device_ProcessControlRequest(&Speaker_Audio_Interface);
|
||||
}
|
||||
|
@ -1,75 +1,75 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Header file for AudioOutput.c.
|
||||
*/
|
||||
|
||||
#ifndef _AUDIO_OUTPUT_H_
|
||||
#define _AUDIO_OUTPUT_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/io.h>
|
||||
#include <avr/wdt.h>
|
||||
#include <avr/power.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "Descriptors.h"
|
||||
|
||||
#include <LUFA/Version.h>
|
||||
#include <LUFA/Drivers/Board/LEDs.h>
|
||||
#include <LUFA/Drivers/USB/USB.h>
|
||||
#include <LUFA/Drivers/USB/Class/Audio.h>
|
||||
|
||||
/* Macros: */
|
||||
/** LED mask for the library LED driver, to indicate that the USB interface is not ready. */
|
||||
#define LEDMASK_USB_NOTREADY LEDS_LED1
|
||||
|
||||
/** LED mask for the library LED driver, to indicate that the USB interface is enumerating. */
|
||||
#define LEDMASK_USB_ENUMERATING (LEDS_LED2 | LEDS_LED3)
|
||||
|
||||
/** LED mask for the library LED driver, to indicate that the USB interface is ready. */
|
||||
#define LEDMASK_USB_READY (LEDS_LED2 | LEDS_LED4)
|
||||
|
||||
/** LED mask for the library LED driver, to indicate that an error has occurred in the USB interface. */
|
||||
#define LEDMASK_USB_ERROR (LEDS_LED1 | LEDS_LED3)
|
||||
|
||||
/* Function Prototypes: */
|
||||
void SetupHardware(void);
|
||||
void ProcessNextSample(void);
|
||||
|
||||
void EVENT_USB_Device_Connect(void);
|
||||
void EVENT_USB_Device_Disconnect(void);
|
||||
void EVENT_USB_Device_ConfigurationChanged(void);
|
||||
void EVENT_USB_Device_UnhandledControlRequest(void);
|
||||
|
||||
#endif
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Header file for AudioOutput.c.
|
||||
*/
|
||||
|
||||
#ifndef _AUDIO_OUTPUT_H_
|
||||
#define _AUDIO_OUTPUT_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/io.h>
|
||||
#include <avr/wdt.h>
|
||||
#include <avr/power.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "Descriptors.h"
|
||||
|
||||
#include <LUFA/Version.h>
|
||||
#include <LUFA/Drivers/Board/LEDs.h>
|
||||
#include <LUFA/Drivers/USB/USB.h>
|
||||
#include <LUFA/Drivers/USB/Class/Audio.h>
|
||||
|
||||
/* Macros: */
|
||||
/** LED mask for the library LED driver, to indicate that the USB interface is not ready. */
|
||||
#define LEDMASK_USB_NOTREADY LEDS_LED1
|
||||
|
||||
/** LED mask for the library LED driver, to indicate that the USB interface is enumerating. */
|
||||
#define LEDMASK_USB_ENUMERATING (LEDS_LED2 | LEDS_LED3)
|
||||
|
||||
/** LED mask for the library LED driver, to indicate that the USB interface is ready. */
|
||||
#define LEDMASK_USB_READY (LEDS_LED2 | LEDS_LED4)
|
||||
|
||||
/** LED mask for the library LED driver, to indicate that an error has occurred in the USB interface. */
|
||||
#define LEDMASK_USB_ERROR (LEDS_LED1 | LEDS_LED3)
|
||||
|
||||
/* Function Prototypes: */
|
||||
void SetupHardware(void);
|
||||
void ProcessNextSample(void);
|
||||
|
||||
void EVENT_USB_Device_Connect(void);
|
||||
void EVENT_USB_Device_Disconnect(void);
|
||||
void EVENT_USB_Device_ConfigurationChanged(void);
|
||||
void EVENT_USB_Device_UnhandledControlRequest(void);
|
||||
|
||||
#endif
|
||||
|
@ -1,96 +1,96 @@
|
||||
/** \file
|
||||
*
|
||||
* This file contains special DoxyGen information for the generation of the main page and other special
|
||||
* documentation pages. It is not a project source file.
|
||||
*/
|
||||
|
||||
/** \mainpage Audio Output Device Demo
|
||||
*
|
||||
* \section SSec_Compat Demo Compatibility:
|
||||
*
|
||||
* The following list indicates what microcontrollers are compatible with this demo.
|
||||
*
|
||||
* - Series 7 USB AVRs
|
||||
* - Series 6 USB AVRs
|
||||
* - Series 4 USB AVRs
|
||||
*
|
||||
* \section SSec_Info USB Information:
|
||||
*
|
||||
* The following table gives a rundown of the USB utilization of this demo.
|
||||
*
|
||||
* <table>
|
||||
* <tr>
|
||||
* <td><b>USB Mode:</b></td>
|
||||
* <td>Device</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>USB Class:</b></td>
|
||||
* <td>Audio Class</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>USB Subclass:</b></td>
|
||||
* <td>Standard Audio Device</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>Relevant Standards:</b></td>
|
||||
* <td>USBIF Audio Class Specification \n
|
||||
* USBIF Audio Class Terminal Types Specification \n
|
||||
* USBIF Audio Data Formats Specification</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>Usable Speeds:</b></td>
|
||||
* <td>Full Speed Mode</td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*
|
||||
* \section SSec_Description Project Description:
|
||||
*
|
||||
* Audio demonstration application. This gives a simple reference
|
||||
* application for implementing a USB Audio Output device using the
|
||||
* basic USB Audio drivers in all modern OSes (i.e. no special drivers
|
||||
* required).
|
||||
*
|
||||
* On start-up the system will automatically enumerate and function
|
||||
* 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
|
||||
* 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
|
||||
* the board LEDs in all modes. Decouple audio outputs with a capacitor and
|
||||
* attach to a speaker to hear the audio.
|
||||
*
|
||||
* Under Windows, if a driver request dialogue pops up, select the option
|
||||
* to automatically install the appropriate drivers.
|
||||
*
|
||||
* \section SSec_Options Project Options
|
||||
*
|
||||
* The following defines can be found in this demo, which can control the demo behaviour when defined, or changed in value.
|
||||
*
|
||||
* <table>
|
||||
* <tr>
|
||||
* <td><b>Define Name:</b></td>
|
||||
* <td><b>Location:</b></td>
|
||||
* <td><b>Description:</b></td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>AUDIO_OUT_STEREO</td>
|
||||
* <td>Makefile CDEFS</td>
|
||||
* <td>When defined, this outputs the audio samples in stereo to the timer output pins of the microcontroller.</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>AUDIO_OUT_MONO</td>
|
||||
* <td>Makefile CDEFS</td>
|
||||
* <td>When defined, this outputs the audio samples in mono to the timer output pin of the microcontroller.</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>AUDIO_OUT_PORTC</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
|
||||
* external DAC.</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>AUDIO_SAMPLE_FREQUENCY</td>
|
||||
* <td>Descriptors.h</td>
|
||||
* <td>Gives the audio sample rate per channel for the audio stream, in Hz.</td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*/
|
||||
/** \file
|
||||
*
|
||||
* This file contains special DoxyGen information for the generation of the main page and other special
|
||||
* documentation pages. It is not a project source file.
|
||||
*/
|
||||
|
||||
/** \mainpage Audio Output Device Demo
|
||||
*
|
||||
* \section SSec_Compat Demo Compatibility:
|
||||
*
|
||||
* The following list indicates what microcontrollers are compatible with this demo.
|
||||
*
|
||||
* - Series 7 USB AVRs
|
||||
* - Series 6 USB AVRs
|
||||
* - Series 4 USB AVRs
|
||||
*
|
||||
* \section SSec_Info USB Information:
|
||||
*
|
||||
* The following table gives a rundown of the USB utilization of this demo.
|
||||
*
|
||||
* <table>
|
||||
* <tr>
|
||||
* <td><b>USB Mode:</b></td>
|
||||
* <td>Device</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>USB Class:</b></td>
|
||||
* <td>Audio Class</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>USB Subclass:</b></td>
|
||||
* <td>Standard Audio Device</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>Relevant Standards:</b></td>
|
||||
* <td>USBIF Audio Class Specification \n
|
||||
* USBIF Audio Class Terminal Types Specification \n
|
||||
* USBIF Audio Data Formats Specification</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>Usable Speeds:</b></td>
|
||||
* <td>Full Speed Mode</td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*
|
||||
* \section SSec_Description Project Description:
|
||||
*
|
||||
* Audio demonstration application. This gives a simple reference
|
||||
* application for implementing a USB Audio Output device using the
|
||||
* basic USB Audio drivers in all modern OSes (i.e. no special drivers
|
||||
* required).
|
||||
*
|
||||
* On start-up the system will automatically enumerate and function
|
||||
* 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
|
||||
* 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
|
||||
* the board LEDs in all modes. Decouple audio outputs with a capacitor and
|
||||
* attach to a speaker to hear the audio.
|
||||
*
|
||||
* Under Windows, if a driver request dialogue pops up, select the option
|
||||
* to automatically install the appropriate drivers.
|
||||
*
|
||||
* \section SSec_Options Project Options
|
||||
*
|
||||
* The following defines can be found in this demo, which can control the demo behaviour when defined, or changed in value.
|
||||
*
|
||||
* <table>
|
||||
* <tr>
|
||||
* <td><b>Define Name:</b></td>
|
||||
* <td><b>Location:</b></td>
|
||||
* <td><b>Description:</b></td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>AUDIO_OUT_STEREO</td>
|
||||
* <td>Makefile CDEFS</td>
|
||||
* <td>When defined, this outputs the audio samples in stereo to the timer output pins of the microcontroller.</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>AUDIO_OUT_MONO</td>
|
||||
* <td>Makefile CDEFS</td>
|
||||
* <td>When defined, this outputs the audio samples in mono to the timer output pin of the microcontroller.</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>AUDIO_OUT_PORTC</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
|
||||
* external DAC.</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>AUDIO_SAMPLE_FREQUENCY</td>
|
||||
* <td>Descriptors.h</td>
|
||||
* <td>Gives the audio sample rate per channel for the audio stream, in Hz.</td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*/
|
||||
|
@ -1,314 +1,314 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* 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
|
||||
* the device's capabilities and functions.
|
||||
*/
|
||||
|
||||
#include "Descriptors.h"
|
||||
|
||||
/** Device descriptor structure. This descriptor, located in FLASH memory, describes the overall
|
||||
* 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
|
||||
* process begins.
|
||||
*/
|
||||
USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device},
|
||||
|
||||
.USBSpecification = VERSION_BCD(02.00),
|
||||
.Class = 0x00,
|
||||
.SubClass = 0x00,
|
||||
.Protocol = 0x00,
|
||||
|
||||
.Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE,
|
||||
|
||||
.VendorID = 0x03EB,
|
||||
.ProductID = 0x2046,
|
||||
.ReleaseNumber = 0x0000,
|
||||
|
||||
.ManufacturerStrIndex = 0x01,
|
||||
.ProductStrIndex = 0x02,
|
||||
.SerialNumStrIndex = NO_DESCRIPTOR,
|
||||
|
||||
.NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS
|
||||
};
|
||||
|
||||
/** 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
|
||||
* 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.
|
||||
*/
|
||||
USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
|
||||
{
|
||||
.Config =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration},
|
||||
|
||||
.TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t),
|
||||
.TotalInterfaces = 2,
|
||||
|
||||
.ConfigurationNumber = 1,
|
||||
.ConfigurationStrIndex = NO_DESCRIPTOR,
|
||||
|
||||
.ConfigAttributes = (USB_CONFIG_ATTR_BUSPOWERED | USB_CONFIG_ATTR_SELFPOWERED),
|
||||
|
||||
.MaxPowerConsumption = USB_CONFIG_POWER_MA(100)
|
||||
},
|
||||
|
||||
.Audio_ControlInterface =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
|
||||
|
||||
.InterfaceNumber = 0,
|
||||
.AlternateSetting = 0,
|
||||
|
||||
.TotalEndpoints = 0,
|
||||
|
||||
.Class = 0x01,
|
||||
.SubClass = 0x01,
|
||||
.Protocol = 0x00,
|
||||
|
||||
.InterfaceStrIndex = NO_DESCRIPTOR
|
||||
},
|
||||
|
||||
.Audio_ControlInterface_SPC =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Audio_Interface_AC_t), .Type = DTYPE_AudioInterface},
|
||||
.Subtype = DSUBTYPE_Header,
|
||||
|
||||
.ACSpecification = VERSION_BCD(01.00),
|
||||
.TotalLength = (sizeof(USB_Audio_Interface_AC_t) +
|
||||
sizeof(USB_Audio_InputTerminal_t) +
|
||||
sizeof(USB_Audio_OutputTerminal_t)),
|
||||
|
||||
.InCollection = 1,
|
||||
.InterfaceNumbers = {1},
|
||||
},
|
||||
|
||||
.Audio_InputTerminal =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Audio_InputTerminal_t), .Type = DTYPE_AudioInterface},
|
||||
.Subtype = DSUBTYPE_InputTerminal,
|
||||
|
||||
.TerminalID = 0x01,
|
||||
.TerminalType = TERMINAL_STREAMING,
|
||||
.AssociatedOutputTerminal = 0x00,
|
||||
|
||||
.TotalChannels = 2,
|
||||
.ChannelConfig = (CHANNEL_LEFT_FRONT | CHANNEL_RIGHT_FRONT),
|
||||
|
||||
.ChannelStrIndex = NO_DESCRIPTOR,
|
||||
.TerminalStrIndex = NO_DESCRIPTOR
|
||||
},
|
||||
|
||||
.Audio_OutputTerminal =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Audio_OutputTerminal_t), .Type = DTYPE_AudioInterface},
|
||||
.Subtype = DSUBTYPE_OutputTerminal,
|
||||
|
||||
.TerminalID = 0x02,
|
||||
.TerminalType = TERMINAL_OUT_SPEAKER,
|
||||
.AssociatedInputTerminal = 0x00,
|
||||
|
||||
.SourceID = 0x01,
|
||||
|
||||
.TerminalStrIndex = NO_DESCRIPTOR
|
||||
},
|
||||
|
||||
.Audio_StreamInterface_Alt0 =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
|
||||
|
||||
.InterfaceNumber = 1,
|
||||
.AlternateSetting = 0,
|
||||
|
||||
.TotalEndpoints = 0,
|
||||
|
||||
.Class = 0x01,
|
||||
.SubClass = 0x02,
|
||||
.Protocol = 0x00,
|
||||
|
||||
.InterfaceStrIndex = NO_DESCRIPTOR
|
||||
},
|
||||
|
||||
.Audio_StreamInterface_Alt1 =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
|
||||
|
||||
.InterfaceNumber = 1,
|
||||
.AlternateSetting = 1,
|
||||
|
||||
.TotalEndpoints = 1,
|
||||
|
||||
.Class = 0x01,
|
||||
.SubClass = 0x02,
|
||||
.Protocol = 0x00,
|
||||
|
||||
.InterfaceStrIndex = NO_DESCRIPTOR
|
||||
},
|
||||
|
||||
.Audio_StreamInterface_SPC =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Audio_Interface_AS_t), .Type = DTYPE_AudioInterface},
|
||||
.Subtype = DSUBTYPE_General,
|
||||
|
||||
.TerminalLink = 0x01,
|
||||
|
||||
.FrameDelay = 1,
|
||||
.AudioFormat = 0x0001
|
||||
},
|
||||
|
||||
.Audio_AudioFormat =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Audio_Format_t), .Type = DTYPE_AudioInterface},
|
||||
.Subtype = DSUBTYPE_Format,
|
||||
|
||||
.FormatType = 0x01,
|
||||
.Channels = 0x02,
|
||||
|
||||
.SubFrameSize = 0x02,
|
||||
.BitResolution = 16,
|
||||
|
||||
.SampleFrequencyType = AUDIO_TOTAL_SAMPLE_RATES,
|
||||
.SampleFrequencies = {AUDIO_SAMPLE_FREQ(AUDIO_SAMPLE_FREQUENCY)}
|
||||
},
|
||||
|
||||
.Audio_StreamEndpoint =
|
||||
{
|
||||
.Endpoint =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Audio_StreamEndpoint_Std_t), .Type = DTYPE_Endpoint},
|
||||
|
||||
.EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_OUT | AUDIO_STREAM_EPNUM),
|
||||
.Attributes = (EP_TYPE_ISOCHRONOUS | ENDPOINT_ATTR_SYNC | ENDPOINT_USAGE_DATA),
|
||||
.EndpointSize = AUDIO_STREAM_EPSIZE,
|
||||
.PollingIntervalMS = 1
|
||||
},
|
||||
|
||||
.Refresh = 0,
|
||||
.SyncEndpointNumber = 0
|
||||
},
|
||||
|
||||
.Audio_StreamEndpoint_SPC =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Audio_StreamEndpoint_Spc_t), .Type = DTYPE_AudioEndpoint},
|
||||
.Subtype = DSUBTYPE_General,
|
||||
|
||||
.Attributes = EP_ACCEPTS_SMALL_PACKETS,
|
||||
|
||||
.LockDelayUnits = 0x00,
|
||||
.LockDelay = 0x0000
|
||||
}
|
||||
};
|
||||
|
||||
/** 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
|
||||
* via the language ID table available at USB.org what languages the device supports for its string descriptors.
|
||||
*/
|
||||
USB_Descriptor_String_t PROGMEM LanguageString =
|
||||
{
|
||||
.Header = {.Size = USB_STRING_LEN(1), .Type = DTYPE_String},
|
||||
|
||||
.UnicodeString = {LANGUAGE_ID_ENG}
|
||||
};
|
||||
|
||||
/** 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
|
||||
* Descriptor.
|
||||
*/
|
||||
USB_Descriptor_String_t PROGMEM ManufacturerString =
|
||||
{
|
||||
.Header = {.Size = USB_STRING_LEN(11), .Type = DTYPE_String},
|
||||
|
||||
.UnicodeString = L"Dean Camera"
|
||||
};
|
||||
|
||||
/** 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
|
||||
* Descriptor.
|
||||
*/
|
||||
USB_Descriptor_String_t PROGMEM ProductString =
|
||||
{
|
||||
.Header = {.Size = USB_STRING_LEN(19), .Type = DTYPE_String},
|
||||
|
||||
.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"
|
||||
* 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
|
||||
* is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the
|
||||
* USB host.
|
||||
*/
|
||||
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 DescriptorNumber = (wValue & 0xFF);
|
||||
|
||||
void* Address = NULL;
|
||||
uint16_t Size = NO_DESCRIPTOR;
|
||||
|
||||
switch (DescriptorType)
|
||||
{
|
||||
case DTYPE_Device:
|
||||
Address = (void*)&DeviceDescriptor;
|
||||
Size = sizeof(USB_Descriptor_Device_t);
|
||||
break;
|
||||
case DTYPE_Configuration:
|
||||
Address = (void*)&ConfigurationDescriptor;
|
||||
Size = sizeof(USB_Descriptor_Configuration_t);
|
||||
break;
|
||||
case DTYPE_String:
|
||||
switch (DescriptorNumber)
|
||||
{
|
||||
case 0x00:
|
||||
Address = (void*)&LanguageString;
|
||||
Size = pgm_read_byte(&LanguageString.Header.Size);
|
||||
break;
|
||||
case 0x01:
|
||||
Address = (void*)&ManufacturerString;
|
||||
Size = pgm_read_byte(&ManufacturerString.Header.Size);
|
||||
break;
|
||||
case 0x02:
|
||||
Address = (void*)&ProductString;
|
||||
Size = pgm_read_byte(&ProductString.Header.Size);
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
*DescriptorAddress = Address;
|
||||
return Size;
|
||||
}
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* 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
|
||||
* the device's capabilities and functions.
|
||||
*/
|
||||
|
||||
#include "Descriptors.h"
|
||||
|
||||
/** Device descriptor structure. This descriptor, located in FLASH memory, describes the overall
|
||||
* 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
|
||||
* process begins.
|
||||
*/
|
||||
USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device},
|
||||
|
||||
.USBSpecification = VERSION_BCD(02.00),
|
||||
.Class = 0x00,
|
||||
.SubClass = 0x00,
|
||||
.Protocol = 0x00,
|
||||
|
||||
.Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE,
|
||||
|
||||
.VendorID = 0x03EB,
|
||||
.ProductID = 0x2046,
|
||||
.ReleaseNumber = 0x0000,
|
||||
|
||||
.ManufacturerStrIndex = 0x01,
|
||||
.ProductStrIndex = 0x02,
|
||||
.SerialNumStrIndex = NO_DESCRIPTOR,
|
||||
|
||||
.NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS
|
||||
};
|
||||
|
||||
/** 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
|
||||
* 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.
|
||||
*/
|
||||
USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
|
||||
{
|
||||
.Config =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration},
|
||||
|
||||
.TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t),
|
||||
.TotalInterfaces = 2,
|
||||
|
||||
.ConfigurationNumber = 1,
|
||||
.ConfigurationStrIndex = NO_DESCRIPTOR,
|
||||
|
||||
.ConfigAttributes = (USB_CONFIG_ATTR_BUSPOWERED | USB_CONFIG_ATTR_SELFPOWERED),
|
||||
|
||||
.MaxPowerConsumption = USB_CONFIG_POWER_MA(100)
|
||||
},
|
||||
|
||||
.Audio_ControlInterface =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
|
||||
|
||||
.InterfaceNumber = 0,
|
||||
.AlternateSetting = 0,
|
||||
|
||||
.TotalEndpoints = 0,
|
||||
|
||||
.Class = 0x01,
|
||||
.SubClass = 0x01,
|
||||
.Protocol = 0x00,
|
||||
|
||||
.InterfaceStrIndex = NO_DESCRIPTOR
|
||||
},
|
||||
|
||||
.Audio_ControlInterface_SPC =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Audio_Interface_AC_t), .Type = DTYPE_AudioInterface},
|
||||
.Subtype = DSUBTYPE_Header,
|
||||
|
||||
.ACSpecification = VERSION_BCD(01.00),
|
||||
.TotalLength = (sizeof(USB_Audio_Interface_AC_t) +
|
||||
sizeof(USB_Audio_InputTerminal_t) +
|
||||
sizeof(USB_Audio_OutputTerminal_t)),
|
||||
|
||||
.InCollection = 1,
|
||||
.InterfaceNumbers = {1},
|
||||
},
|
||||
|
||||
.Audio_InputTerminal =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Audio_InputTerminal_t), .Type = DTYPE_AudioInterface},
|
||||
.Subtype = DSUBTYPE_InputTerminal,
|
||||
|
||||
.TerminalID = 0x01,
|
||||
.TerminalType = TERMINAL_STREAMING,
|
||||
.AssociatedOutputTerminal = 0x00,
|
||||
|
||||
.TotalChannels = 2,
|
||||
.ChannelConfig = (CHANNEL_LEFT_FRONT | CHANNEL_RIGHT_FRONT),
|
||||
|
||||
.ChannelStrIndex = NO_DESCRIPTOR,
|
||||
.TerminalStrIndex = NO_DESCRIPTOR
|
||||
},
|
||||
|
||||
.Audio_OutputTerminal =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Audio_OutputTerminal_t), .Type = DTYPE_AudioInterface},
|
||||
.Subtype = DSUBTYPE_OutputTerminal,
|
||||
|
||||
.TerminalID = 0x02,
|
||||
.TerminalType = TERMINAL_OUT_SPEAKER,
|
||||
.AssociatedInputTerminal = 0x00,
|
||||
|
||||
.SourceID = 0x01,
|
||||
|
||||
.TerminalStrIndex = NO_DESCRIPTOR
|
||||
},
|
||||
|
||||
.Audio_StreamInterface_Alt0 =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
|
||||
|
||||
.InterfaceNumber = 1,
|
||||
.AlternateSetting = 0,
|
||||
|
||||
.TotalEndpoints = 0,
|
||||
|
||||
.Class = 0x01,
|
||||
.SubClass = 0x02,
|
||||
.Protocol = 0x00,
|
||||
|
||||
.InterfaceStrIndex = NO_DESCRIPTOR
|
||||
},
|
||||
|
||||
.Audio_StreamInterface_Alt1 =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
|
||||
|
||||
.InterfaceNumber = 1,
|
||||
.AlternateSetting = 1,
|
||||
|
||||
.TotalEndpoints = 1,
|
||||
|
||||
.Class = 0x01,
|
||||
.SubClass = 0x02,
|
||||
.Protocol = 0x00,
|
||||
|
||||
.InterfaceStrIndex = NO_DESCRIPTOR
|
||||
},
|
||||
|
||||
.Audio_StreamInterface_SPC =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Audio_Interface_AS_t), .Type = DTYPE_AudioInterface},
|
||||
.Subtype = DSUBTYPE_General,
|
||||
|
||||
.TerminalLink = 0x01,
|
||||
|
||||
.FrameDelay = 1,
|
||||
.AudioFormat = 0x0001
|
||||
},
|
||||
|
||||
.Audio_AudioFormat =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Audio_Format_t), .Type = DTYPE_AudioInterface},
|
||||
.Subtype = DSUBTYPE_Format,
|
||||
|
||||
.FormatType = 0x01,
|
||||
.Channels = 0x02,
|
||||
|
||||
.SubFrameSize = 0x02,
|
||||
.BitResolution = 16,
|
||||
|
||||
.SampleFrequencyType = AUDIO_TOTAL_SAMPLE_RATES,
|
||||
.SampleFrequencies = {AUDIO_SAMPLE_FREQ(AUDIO_SAMPLE_FREQUENCY)}
|
||||
},
|
||||
|
||||
.Audio_StreamEndpoint =
|
||||
{
|
||||
.Endpoint =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Audio_StreamEndpoint_Std_t), .Type = DTYPE_Endpoint},
|
||||
|
||||
.EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_OUT | AUDIO_STREAM_EPNUM),
|
||||
.Attributes = (EP_TYPE_ISOCHRONOUS | ENDPOINT_ATTR_SYNC | ENDPOINT_USAGE_DATA),
|
||||
.EndpointSize = AUDIO_STREAM_EPSIZE,
|
||||
.PollingIntervalMS = 1
|
||||
},
|
||||
|
||||
.Refresh = 0,
|
||||
.SyncEndpointNumber = 0
|
||||
},
|
||||
|
||||
.Audio_StreamEndpoint_SPC =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Audio_StreamEndpoint_Spc_t), .Type = DTYPE_AudioEndpoint},
|
||||
.Subtype = DSUBTYPE_General,
|
||||
|
||||
.Attributes = EP_ACCEPTS_SMALL_PACKETS,
|
||||
|
||||
.LockDelayUnits = 0x00,
|
||||
.LockDelay = 0x0000
|
||||
}
|
||||
};
|
||||
|
||||
/** 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
|
||||
* via the language ID table available at USB.org what languages the device supports for its string descriptors.
|
||||
*/
|
||||
USB_Descriptor_String_t PROGMEM LanguageString =
|
||||
{
|
||||
.Header = {.Size = USB_STRING_LEN(1), .Type = DTYPE_String},
|
||||
|
||||
.UnicodeString = {LANGUAGE_ID_ENG}
|
||||
};
|
||||
|
||||
/** 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
|
||||
* Descriptor.
|
||||
*/
|
||||
USB_Descriptor_String_t PROGMEM ManufacturerString =
|
||||
{
|
||||
.Header = {.Size = USB_STRING_LEN(11), .Type = DTYPE_String},
|
||||
|
||||
.UnicodeString = L"Dean Camera"
|
||||
};
|
||||
|
||||
/** 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
|
||||
* Descriptor.
|
||||
*/
|
||||
USB_Descriptor_String_t PROGMEM ProductString =
|
||||
{
|
||||
.Header = {.Size = USB_STRING_LEN(19), .Type = DTYPE_String},
|
||||
|
||||
.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"
|
||||
* 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
|
||||
* is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the
|
||||
* USB host.
|
||||
*/
|
||||
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 DescriptorNumber = (wValue & 0xFF);
|
||||
|
||||
void* Address = NULL;
|
||||
uint16_t Size = NO_DESCRIPTOR;
|
||||
|
||||
switch (DescriptorType)
|
||||
{
|
||||
case DTYPE_Device:
|
||||
Address = (void*)&DeviceDescriptor;
|
||||
Size = sizeof(USB_Descriptor_Device_t);
|
||||
break;
|
||||
case DTYPE_Configuration:
|
||||
Address = (void*)&ConfigurationDescriptor;
|
||||
Size = sizeof(USB_Descriptor_Configuration_t);
|
||||
break;
|
||||
case DTYPE_String:
|
||||
switch (DescriptorNumber)
|
||||
{
|
||||
case 0x00:
|
||||
Address = (void*)&LanguageString;
|
||||
Size = pgm_read_byte(&LanguageString.Header.Size);
|
||||
break;
|
||||
case 0x01:
|
||||
Address = (void*)&ManufacturerString;
|
||||
Size = pgm_read_byte(&ManufacturerString.Header.Size);
|
||||
break;
|
||||
case 0x02:
|
||||
Address = (void*)&ProductString;
|
||||
Size = pgm_read_byte(&ProductString.Header.Size);
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
*DescriptorAddress = Address;
|
||||
return Size;
|
||||
}
|
||||
|
@ -1,82 +1,82 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Header file for Descriptors.c.
|
||||
*/
|
||||
|
||||
#ifndef _DESCRIPTORS_H_
|
||||
#define _DESCRIPTORS_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <LUFA/Drivers/USB/USB.h>
|
||||
#include <LUFA/Drivers/USB/Class/Audio.h>
|
||||
|
||||
#include <avr/pgmspace.h>
|
||||
|
||||
/* Macros: */
|
||||
/** Endpoint number of the Audio isochronous streaming data endpoint. */
|
||||
#define AUDIO_STREAM_EPNUM 1
|
||||
|
||||
/** 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
|
||||
* USB AVR models will result in unavoidable distorted output.
|
||||
*/
|
||||
#define AUDIO_STREAM_EPSIZE ENDPOINT_MAX_SIZE(AUDIO_STREAM_EPNUM)
|
||||
|
||||
/** Sample frequency of the data being transmitted through the streaming endpoint. */
|
||||
#define AUDIO_SAMPLE_FREQUENCY 48000
|
||||
|
||||
/* Type Defines: */
|
||||
/** 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
|
||||
* vary between devices, and which describe the device's usage to the host.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
USB_Descriptor_Configuration_Header_t Config;
|
||||
USB_Descriptor_Interface_t Audio_ControlInterface;
|
||||
USB_Audio_Interface_AC_t Audio_ControlInterface_SPC;
|
||||
USB_Audio_InputTerminal_t Audio_InputTerminal;
|
||||
USB_Audio_OutputTerminal_t Audio_OutputTerminal;
|
||||
USB_Descriptor_Interface_t Audio_StreamInterface_Alt0;
|
||||
USB_Descriptor_Interface_t Audio_StreamInterface_Alt1;
|
||||
USB_Audio_Interface_AS_t Audio_StreamInterface_SPC;
|
||||
USB_Audio_Format_t Audio_AudioFormat;
|
||||
USB_Audio_StreamEndpoint_Std_t Audio_StreamEndpoint;
|
||||
USB_Audio_StreamEndpoint_Spc_t Audio_StreamEndpoint_SPC;
|
||||
} USB_Descriptor_Configuration_t;
|
||||
|
||||
/* Function Prototypes: */
|
||||
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);
|
||||
|
||||
#endif
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Header file for Descriptors.c.
|
||||
*/
|
||||
|
||||
#ifndef _DESCRIPTORS_H_
|
||||
#define _DESCRIPTORS_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <LUFA/Drivers/USB/USB.h>
|
||||
#include <LUFA/Drivers/USB/Class/Audio.h>
|
||||
|
||||
#include <avr/pgmspace.h>
|
||||
|
||||
/* Macros: */
|
||||
/** Endpoint number of the Audio isochronous streaming data endpoint. */
|
||||
#define AUDIO_STREAM_EPNUM 1
|
||||
|
||||
/** 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
|
||||
* USB AVR models will result in unavoidable distorted output.
|
||||
*/
|
||||
#define AUDIO_STREAM_EPSIZE ENDPOINT_MAX_SIZE(AUDIO_STREAM_EPNUM)
|
||||
|
||||
/** Sample frequency of the data being transmitted through the streaming endpoint. */
|
||||
#define AUDIO_SAMPLE_FREQUENCY 48000
|
||||
|
||||
/* Type Defines: */
|
||||
/** 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
|
||||
* vary between devices, and which describe the device's usage to the host.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
USB_Descriptor_Configuration_Header_t Config;
|
||||
USB_Descriptor_Interface_t Audio_ControlInterface;
|
||||
USB_Audio_Interface_AC_t Audio_ControlInterface_SPC;
|
||||
USB_Audio_InputTerminal_t Audio_InputTerminal;
|
||||
USB_Audio_OutputTerminal_t Audio_OutputTerminal;
|
||||
USB_Descriptor_Interface_t Audio_StreamInterface_Alt0;
|
||||
USB_Descriptor_Interface_t Audio_StreamInterface_Alt1;
|
||||
USB_Audio_Interface_AS_t Audio_StreamInterface_SPC;
|
||||
USB_Audio_Format_t Audio_AudioFormat;
|
||||
USB_Audio_StreamEndpoint_Std_t Audio_StreamEndpoint;
|
||||
USB_Audio_StreamEndpoint_Spc_t Audio_StreamEndpoint_SPC;
|
||||
} USB_Descriptor_Configuration_t;
|
||||
|
||||
/* Function Prototypes: */
|
||||
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);
|
||||
|
||||
#endif
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,381 +1,381 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* 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
|
||||
* the device's capabilities and functions.
|
||||
*/
|
||||
|
||||
#include "Descriptors.h"
|
||||
|
||||
/* 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.
|
||||
* 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
|
||||
* 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
|
||||
* port location).
|
||||
*/
|
||||
#if (USE_INTERNAL_SERIAL == NO_DESCRIPTOR)
|
||||
#warning USE_INTERNAL_SERIAL is not available on this AVR - please manually construct a device serial descriptor.
|
||||
#endif
|
||||
|
||||
/** Device descriptor structure. This descriptor, located in FLASH memory, describes the overall
|
||||
* 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
|
||||
* process begins.
|
||||
*/
|
||||
USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device},
|
||||
|
||||
.USBSpecification = VERSION_BCD(01.10),
|
||||
.Class = 0xEF,
|
||||
.SubClass = 0x02,
|
||||
.Protocol = 0x01,
|
||||
|
||||
.Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE,
|
||||
|
||||
.VendorID = 0x03EB,
|
||||
.ProductID = 0x204E,
|
||||
.ReleaseNumber = 0x0000,
|
||||
|
||||
.ManufacturerStrIndex = 0x01,
|
||||
.ProductStrIndex = 0x02,
|
||||
.SerialNumStrIndex = USE_INTERNAL_SERIAL,
|
||||
|
||||
.NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS
|
||||
};
|
||||
|
||||
/** 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
|
||||
* 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.
|
||||
*/
|
||||
USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
|
||||
{
|
||||
.Config =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration},
|
||||
|
||||
.TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t),
|
||||
.TotalInterfaces = 4,
|
||||
|
||||
.ConfigurationNumber = 1,
|
||||
.ConfigurationStrIndex = NO_DESCRIPTOR,
|
||||
|
||||
.ConfigAttributes = (USB_CONFIG_ATTR_BUSPOWERED | USB_CONFIG_ATTR_SELFPOWERED),
|
||||
|
||||
.MaxPowerConsumption = USB_CONFIG_POWER_MA(100)
|
||||
},
|
||||
|
||||
.CDC1_IAD =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Interface_Association_t), .Type = DTYPE_InterfaceAssociation},
|
||||
|
||||
.FirstInterfaceIndex = 0,
|
||||
.TotalInterfaces = 2,
|
||||
|
||||
.Class = 0x02,
|
||||
.SubClass = 0x02,
|
||||
.Protocol = 0x01,
|
||||
|
||||
.IADStrIndex = NO_DESCRIPTOR
|
||||
},
|
||||
|
||||
.CDC1_CCI_Interface =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
|
||||
|
||||
.InterfaceNumber = 0,
|
||||
.AlternateSetting = 0,
|
||||
|
||||
.TotalEndpoints = 1,
|
||||
|
||||
.Class = 0x02,
|
||||
.SubClass = 0x02,
|
||||
.Protocol = 0x01,
|
||||
|
||||
.InterfaceStrIndex = NO_DESCRIPTOR
|
||||
},
|
||||
|
||||
.CDC1_Functional_IntHeader =
|
||||
{
|
||||
.Header = {.Size = sizeof(CDC_FUNCTIONAL_DESCRIPTOR(2)), .Type = 0x24},
|
||||
.SubType = 0x00,
|
||||
|
||||
.Data = {0x01, 0x10}
|
||||
},
|
||||
|
||||
.CDC1_Functional_AbstractControlManagement =
|
||||
{
|
||||
.Header = {.Size = sizeof(CDC_FUNCTIONAL_DESCRIPTOR(1)), .Type = 0x24},
|
||||
.SubType = 0x02,
|
||||
|
||||
.Data = {0x06}
|
||||
},
|
||||
|
||||
.CDC1_Functional_Union =
|
||||
{
|
||||
.Header = {.Size = sizeof(CDC_FUNCTIONAL_DESCRIPTOR(2)), .Type = 0x24},
|
||||
.SubType = 0x06,
|
||||
|
||||
.Data = {0x00, 0x01}
|
||||
},
|
||||
|
||||
.CDC1_ManagementEndpoint =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
|
||||
|
||||
.EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_IN | CDC1_NOTIFICATION_EPNUM),
|
||||
.Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
|
||||
.EndpointSize = CDC_NOTIFICATION_EPSIZE,
|
||||
.PollingIntervalMS = 0xFF
|
||||
},
|
||||
|
||||
.CDC1_DCI_Interface =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
|
||||
|
||||
.InterfaceNumber = 1,
|
||||
.AlternateSetting = 0,
|
||||
|
||||
.TotalEndpoints = 2,
|
||||
|
||||
.Class = 0x0A,
|
||||
.SubClass = 0x00,
|
||||
.Protocol = 0x00,
|
||||
|
||||
.InterfaceStrIndex = NO_DESCRIPTOR
|
||||
},
|
||||
|
||||
.CDC1_DataOutEndpoint =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
|
||||
|
||||
.EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_OUT | CDC1_RX_EPNUM),
|
||||
.Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
|
||||
.EndpointSize = CDC_TXRX_EPSIZE,
|
||||
.PollingIntervalMS = 0x00
|
||||
},
|
||||
|
||||
.CDC1_DataInEndpoint =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
|
||||
|
||||
.EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_IN | CDC1_TX_EPNUM),
|
||||
.Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
|
||||
.EndpointSize = CDC_TXRX_EPSIZE,
|
||||
.PollingIntervalMS = 0x00
|
||||
},
|
||||
|
||||
.CDC2_IAD =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Interface_Association_t), .Type = DTYPE_InterfaceAssociation},
|
||||
|
||||
.FirstInterfaceIndex = 2,
|
||||
.TotalInterfaces = 2,
|
||||
|
||||
.Class = 0x02,
|
||||
.SubClass = 0x02,
|
||||
.Protocol = 0x01,
|
||||
|
||||
.IADStrIndex = NO_DESCRIPTOR
|
||||
},
|
||||
|
||||
.CDC2_CCI_Interface =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
|
||||
|
||||
.InterfaceNumber = 2,
|
||||
.AlternateSetting = 0,
|
||||
|
||||
.TotalEndpoints = 1,
|
||||
|
||||
.Class = 0x02,
|
||||
.SubClass = 0x02,
|
||||
.Protocol = 0x01,
|
||||
|
||||
.InterfaceStrIndex = NO_DESCRIPTOR
|
||||
},
|
||||
|
||||
.CDC2_Functional_IntHeader =
|
||||
{
|
||||
.Header = {.Size = sizeof(CDC_FUNCTIONAL_DESCRIPTOR(2)), .Type = 0x24},
|
||||
.SubType = 0x00,
|
||||
|
||||
.Data = {0x01, 0x10}
|
||||
},
|
||||
|
||||
.CDC2_Functional_AbstractControlManagement =
|
||||
{
|
||||
.Header = {.Size = sizeof(CDC_FUNCTIONAL_DESCRIPTOR(1)), .Type = 0x24},
|
||||
.SubType = 0x02,
|
||||
|
||||
.Data = {0x06}
|
||||
},
|
||||
|
||||
.CDC2_Functional_Union =
|
||||
{
|
||||
.Header = {.Size = sizeof(CDC_FUNCTIONAL_DESCRIPTOR(2)), .Type = 0x24},
|
||||
.SubType = 0x06,
|
||||
|
||||
.Data = {0x02, 0x03}
|
||||
},
|
||||
|
||||
.CDC2_ManagementEndpoint =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
|
||||
|
||||
.EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_IN | CDC2_NOTIFICATION_EPNUM),
|
||||
.Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
|
||||
.EndpointSize = CDC_NOTIFICATION_EPSIZE,
|
||||
.PollingIntervalMS = 0xFF
|
||||
},
|
||||
|
||||
.CDC2_DCI_Interface =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
|
||||
|
||||
.InterfaceNumber = 3,
|
||||
.AlternateSetting = 0,
|
||||
|
||||
.TotalEndpoints = 2,
|
||||
|
||||
.Class = 0x0A,
|
||||
.SubClass = 0x00,
|
||||
.Protocol = 0x00,
|
||||
|
||||
.InterfaceStrIndex = NO_DESCRIPTOR
|
||||
},
|
||||
|
||||
.CDC2_DataOutEndpoint =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
|
||||
|
||||
.EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_OUT | CDC2_RX_EPNUM),
|
||||
.Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
|
||||
.EndpointSize = CDC_TXRX_EPSIZE,
|
||||
.PollingIntervalMS = 0x00
|
||||
},
|
||||
|
||||
.CDC2_DataInEndpoint =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
|
||||
|
||||
.EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_IN | CDC2_TX_EPNUM),
|
||||
.Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
|
||||
.EndpointSize = CDC_TXRX_EPSIZE,
|
||||
.PollingIntervalMS = 0x00
|
||||
}
|
||||
};
|
||||
|
||||
/** 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
|
||||
* via the language ID table available at USB.org what languages the device supports for its string descriptors.
|
||||
*/
|
||||
USB_Descriptor_String_t PROGMEM LanguageString =
|
||||
{
|
||||
.Header = {.Size = USB_STRING_LEN(1), .Type = DTYPE_String},
|
||||
|
||||
.UnicodeString = {LANGUAGE_ID_ENG}
|
||||
};
|
||||
|
||||
/** 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
|
||||
* Descriptor.
|
||||
*/
|
||||
USB_Descriptor_String_t PROGMEM ManufacturerString =
|
||||
{
|
||||
.Header = {.Size = USB_STRING_LEN(11), .Type = DTYPE_String},
|
||||
|
||||
.UnicodeString = L"Dean Camera"
|
||||
};
|
||||
|
||||
/** 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
|
||||
* Descriptor.
|
||||
*/
|
||||
USB_Descriptor_String_t PROGMEM ProductString =
|
||||
{
|
||||
.Header = {.Size = USB_STRING_LEN(13), .Type = DTYPE_String},
|
||||
|
||||
.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"
|
||||
* 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
|
||||
* is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the
|
||||
* USB host.
|
||||
*/
|
||||
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 DescriptorNumber = (wValue & 0xFF);
|
||||
|
||||
void* Address = NULL;
|
||||
uint16_t Size = NO_DESCRIPTOR;
|
||||
|
||||
switch (DescriptorType)
|
||||
{
|
||||
case DTYPE_Device:
|
||||
Address = (void*)&DeviceDescriptor;
|
||||
Size = sizeof(USB_Descriptor_Device_t);
|
||||
break;
|
||||
case DTYPE_Configuration:
|
||||
Address = (void*)&ConfigurationDescriptor;
|
||||
Size = sizeof(USB_Descriptor_Configuration_t);
|
||||
break;
|
||||
case DTYPE_String:
|
||||
switch (DescriptorNumber)
|
||||
{
|
||||
case 0x00:
|
||||
Address = (void*)&LanguageString;
|
||||
Size = pgm_read_byte(&LanguageString.Header.Size);
|
||||
break;
|
||||
case 0x01:
|
||||
Address = (void*)&ManufacturerString;
|
||||
Size = pgm_read_byte(&ManufacturerString.Header.Size);
|
||||
break;
|
||||
case 0x02:
|
||||
Address = (void*)&ProductString;
|
||||
Size = pgm_read_byte(&ProductString.Header.Size);
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
*DescriptorAddress = Address;
|
||||
return Size;
|
||||
}
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* 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
|
||||
* the device's capabilities and functions.
|
||||
*/
|
||||
|
||||
#include "Descriptors.h"
|
||||
|
||||
/* 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.
|
||||
* 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
|
||||
* 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
|
||||
* port location).
|
||||
*/
|
||||
#if (USE_INTERNAL_SERIAL == NO_DESCRIPTOR)
|
||||
#warning USE_INTERNAL_SERIAL is not available on this AVR - please manually construct a device serial descriptor.
|
||||
#endif
|
||||
|
||||
/** Device descriptor structure. This descriptor, located in FLASH memory, describes the overall
|
||||
* 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
|
||||
* process begins.
|
||||
*/
|
||||
USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device},
|
||||
|
||||
.USBSpecification = VERSION_BCD(01.10),
|
||||
.Class = 0xEF,
|
||||
.SubClass = 0x02,
|
||||
.Protocol = 0x01,
|
||||
|
||||
.Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE,
|
||||
|
||||
.VendorID = 0x03EB,
|
||||
.ProductID = 0x204E,
|
||||
.ReleaseNumber = 0x0000,
|
||||
|
||||
.ManufacturerStrIndex = 0x01,
|
||||
.ProductStrIndex = 0x02,
|
||||
.SerialNumStrIndex = USE_INTERNAL_SERIAL,
|
||||
|
||||
.NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS
|
||||
};
|
||||
|
||||
/** 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
|
||||
* 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.
|
||||
*/
|
||||
USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
|
||||
{
|
||||
.Config =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration},
|
||||
|
||||
.TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t),
|
||||
.TotalInterfaces = 4,
|
||||
|
||||
.ConfigurationNumber = 1,
|
||||
.ConfigurationStrIndex = NO_DESCRIPTOR,
|
||||
|
||||
.ConfigAttributes = (USB_CONFIG_ATTR_BUSPOWERED | USB_CONFIG_ATTR_SELFPOWERED),
|
||||
|
||||
.MaxPowerConsumption = USB_CONFIG_POWER_MA(100)
|
||||
},
|
||||
|
||||
.CDC1_IAD =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Interface_Association_t), .Type = DTYPE_InterfaceAssociation},
|
||||
|
||||
.FirstInterfaceIndex = 0,
|
||||
.TotalInterfaces = 2,
|
||||
|
||||
.Class = 0x02,
|
||||
.SubClass = 0x02,
|
||||
.Protocol = 0x01,
|
||||
|
||||
.IADStrIndex = NO_DESCRIPTOR
|
||||
},
|
||||
|
||||
.CDC1_CCI_Interface =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
|
||||
|
||||
.InterfaceNumber = 0,
|
||||
.AlternateSetting = 0,
|
||||
|
||||
.TotalEndpoints = 1,
|
||||
|
||||
.Class = 0x02,
|
||||
.SubClass = 0x02,
|
||||
.Protocol = 0x01,
|
||||
|
||||
.InterfaceStrIndex = NO_DESCRIPTOR
|
||||
},
|
||||
|
||||
.CDC1_Functional_IntHeader =
|
||||
{
|
||||
.Header = {.Size = sizeof(CDC_FUNCTIONAL_DESCRIPTOR(2)), .Type = 0x24},
|
||||
.SubType = 0x00,
|
||||
|
||||
.Data = {0x01, 0x10}
|
||||
},
|
||||
|
||||
.CDC1_Functional_AbstractControlManagement =
|
||||
{
|
||||
.Header = {.Size = sizeof(CDC_FUNCTIONAL_DESCRIPTOR(1)), .Type = 0x24},
|
||||
.SubType = 0x02,
|
||||
|
||||
.Data = {0x06}
|
||||
},
|
||||
|
||||
.CDC1_Functional_Union =
|
||||
{
|
||||
.Header = {.Size = sizeof(CDC_FUNCTIONAL_DESCRIPTOR(2)), .Type = 0x24},
|
||||
.SubType = 0x06,
|
||||
|
||||
.Data = {0x00, 0x01}
|
||||
},
|
||||
|
||||
.CDC1_ManagementEndpoint =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
|
||||
|
||||
.EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_IN | CDC1_NOTIFICATION_EPNUM),
|
||||
.Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
|
||||
.EndpointSize = CDC_NOTIFICATION_EPSIZE,
|
||||
.PollingIntervalMS = 0xFF
|
||||
},
|
||||
|
||||
.CDC1_DCI_Interface =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
|
||||
|
||||
.InterfaceNumber = 1,
|
||||
.AlternateSetting = 0,
|
||||
|
||||
.TotalEndpoints = 2,
|
||||
|
||||
.Class = 0x0A,
|
||||
.SubClass = 0x00,
|
||||
.Protocol = 0x00,
|
||||
|
||||
.InterfaceStrIndex = NO_DESCRIPTOR
|
||||
},
|
||||
|
||||
.CDC1_DataOutEndpoint =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
|
||||
|
||||
.EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_OUT | CDC1_RX_EPNUM),
|
||||
.Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
|
||||
.EndpointSize = CDC_TXRX_EPSIZE,
|
||||
.PollingIntervalMS = 0x00
|
||||
},
|
||||
|
||||
.CDC1_DataInEndpoint =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
|
||||
|
||||
.EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_IN | CDC1_TX_EPNUM),
|
||||
.Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
|
||||
.EndpointSize = CDC_TXRX_EPSIZE,
|
||||
.PollingIntervalMS = 0x00
|
||||
},
|
||||
|
||||
.CDC2_IAD =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Interface_Association_t), .Type = DTYPE_InterfaceAssociation},
|
||||
|
||||
.FirstInterfaceIndex = 2,
|
||||
.TotalInterfaces = 2,
|
||||
|
||||
.Class = 0x02,
|
||||
.SubClass = 0x02,
|
||||
.Protocol = 0x01,
|
||||
|
||||
.IADStrIndex = NO_DESCRIPTOR
|
||||
},
|
||||
|
||||
.CDC2_CCI_Interface =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
|
||||
|
||||
.InterfaceNumber = 2,
|
||||
.AlternateSetting = 0,
|
||||
|
||||
.TotalEndpoints = 1,
|
||||
|
||||
.Class = 0x02,
|
||||
.SubClass = 0x02,
|
||||
.Protocol = 0x01,
|
||||
|
||||
.InterfaceStrIndex = NO_DESCRIPTOR
|
||||
},
|
||||
|
||||
.CDC2_Functional_IntHeader =
|
||||
{
|
||||
.Header = {.Size = sizeof(CDC_FUNCTIONAL_DESCRIPTOR(2)), .Type = 0x24},
|
||||
.SubType = 0x00,
|
||||
|
||||
.Data = {0x01, 0x10}
|
||||
},
|
||||
|
||||
.CDC2_Functional_AbstractControlManagement =
|
||||
{
|
||||
.Header = {.Size = sizeof(CDC_FUNCTIONAL_DESCRIPTOR(1)), .Type = 0x24},
|
||||
.SubType = 0x02,
|
||||
|
||||
.Data = {0x06}
|
||||
},
|
||||
|
||||
.CDC2_Functional_Union =
|
||||
{
|
||||
.Header = {.Size = sizeof(CDC_FUNCTIONAL_DESCRIPTOR(2)), .Type = 0x24},
|
||||
.SubType = 0x06,
|
||||
|
||||
.Data = {0x02, 0x03}
|
||||
},
|
||||
|
||||
.CDC2_ManagementEndpoint =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
|
||||
|
||||
.EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_IN | CDC2_NOTIFICATION_EPNUM),
|
||||
.Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
|
||||
.EndpointSize = CDC_NOTIFICATION_EPSIZE,
|
||||
.PollingIntervalMS = 0xFF
|
||||
},
|
||||
|
||||
.CDC2_DCI_Interface =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
|
||||
|
||||
.InterfaceNumber = 3,
|
||||
.AlternateSetting = 0,
|
||||
|
||||
.TotalEndpoints = 2,
|
||||
|
||||
.Class = 0x0A,
|
||||
.SubClass = 0x00,
|
||||
.Protocol = 0x00,
|
||||
|
||||
.InterfaceStrIndex = NO_DESCRIPTOR
|
||||
},
|
||||
|
||||
.CDC2_DataOutEndpoint =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
|
||||
|
||||
.EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_OUT | CDC2_RX_EPNUM),
|
||||
.Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
|
||||
.EndpointSize = CDC_TXRX_EPSIZE,
|
||||
.PollingIntervalMS = 0x00
|
||||
},
|
||||
|
||||
.CDC2_DataInEndpoint =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
|
||||
|
||||
.EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_IN | CDC2_TX_EPNUM),
|
||||
.Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
|
||||
.EndpointSize = CDC_TXRX_EPSIZE,
|
||||
.PollingIntervalMS = 0x00
|
||||
}
|
||||
};
|
||||
|
||||
/** 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
|
||||
* via the language ID table available at USB.org what languages the device supports for its string descriptors.
|
||||
*/
|
||||
USB_Descriptor_String_t PROGMEM LanguageString =
|
||||
{
|
||||
.Header = {.Size = USB_STRING_LEN(1), .Type = DTYPE_String},
|
||||
|
||||
.UnicodeString = {LANGUAGE_ID_ENG}
|
||||
};
|
||||
|
||||
/** 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
|
||||
* Descriptor.
|
||||
*/
|
||||
USB_Descriptor_String_t PROGMEM ManufacturerString =
|
||||
{
|
||||
.Header = {.Size = USB_STRING_LEN(11), .Type = DTYPE_String},
|
||||
|
||||
.UnicodeString = L"Dean Camera"
|
||||
};
|
||||
|
||||
/** 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
|
||||
* Descriptor.
|
||||
*/
|
||||
USB_Descriptor_String_t PROGMEM ProductString =
|
||||
{
|
||||
.Header = {.Size = USB_STRING_LEN(13), .Type = DTYPE_String},
|
||||
|
||||
.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"
|
||||
* 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
|
||||
* is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the
|
||||
* USB host.
|
||||
*/
|
||||
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 DescriptorNumber = (wValue & 0xFF);
|
||||
|
||||
void* Address = NULL;
|
||||
uint16_t Size = NO_DESCRIPTOR;
|
||||
|
||||
switch (DescriptorType)
|
||||
{
|
||||
case DTYPE_Device:
|
||||
Address = (void*)&DeviceDescriptor;
|
||||
Size = sizeof(USB_Descriptor_Device_t);
|
||||
break;
|
||||
case DTYPE_Configuration:
|
||||
Address = (void*)&ConfigurationDescriptor;
|
||||
Size = sizeof(USB_Descriptor_Configuration_t);
|
||||
break;
|
||||
case DTYPE_String:
|
||||
switch (DescriptorNumber)
|
||||
{
|
||||
case 0x00:
|
||||
Address = (void*)&LanguageString;
|
||||
Size = pgm_read_byte(&LanguageString.Header.Size);
|
||||
break;
|
||||
case 0x01:
|
||||
Address = (void*)&ManufacturerString;
|
||||
Size = pgm_read_byte(&ManufacturerString.Header.Size);
|
||||
break;
|
||||
case 0x02:
|
||||
Address = (void*)&ProductString;
|
||||
Size = pgm_read_byte(&ProductString.Header.Size);
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
*DescriptorAddress = Address;
|
||||
return Size;
|
||||
}
|
||||
|
@ -1,102 +1,102 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Header file for Descriptors.c.
|
||||
*/
|
||||
|
||||
#ifndef _DESCRIPTORS_H_
|
||||
#define _DESCRIPTORS_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/pgmspace.h>
|
||||
|
||||
#include <LUFA/Drivers/USB/USB.h>
|
||||
#include <LUFA/Drivers/USB/Class/CDC.h>
|
||||
|
||||
/* Macros: */
|
||||
/** Endpoint number of the first CDC interface's device-to-host notification IN endpoint. */
|
||||
#define CDC1_NOTIFICATION_EPNUM 3
|
||||
|
||||
/** Endpoint number of the first CDC interface's device-to-host data IN endpoint. */
|
||||
#define CDC1_TX_EPNUM 1
|
||||
|
||||
/** Endpoint number of the first CDC interface's host-to-device data OUT endpoint. */
|
||||
#define CDC1_RX_EPNUM 2
|
||||
|
||||
/** Endpoint number of the second CDC interface's device-to-host notification IN endpoint. */
|
||||
#define CDC2_NOTIFICATION_EPNUM 4
|
||||
|
||||
/** Endpoint number of the second CDC interface's device-to-host data IN endpoint. */
|
||||
#define CDC2_TX_EPNUM 5
|
||||
|
||||
/** Endpoint number of the second CDC interface's host-to-device data OUT endpoint. */
|
||||
#define CDC2_RX_EPNUM 6
|
||||
|
||||
/** Size in bytes of the CDC device-to-host notification IN endpoints. */
|
||||
#define CDC_NOTIFICATION_EPSIZE 8
|
||||
|
||||
/** Size in bytes of the CDC data IN and OUT endpoints. */
|
||||
#define CDC_TXRX_EPSIZE 16
|
||||
|
||||
/* Type Defines: */
|
||||
/** 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
|
||||
* vary between devices, and which describe the device's usage to the host.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
USB_Descriptor_Configuration_Header_t Config;
|
||||
USB_Descriptor_Interface_Association_t CDC1_IAD;
|
||||
USB_Descriptor_Interface_t CDC1_CCI_Interface;
|
||||
CDC_FUNCTIONAL_DESCRIPTOR(2) CDC1_Functional_IntHeader;
|
||||
CDC_FUNCTIONAL_DESCRIPTOR(1) CDC1_Functional_AbstractControlManagement;
|
||||
CDC_FUNCTIONAL_DESCRIPTOR(2) CDC1_Functional_Union;
|
||||
USB_Descriptor_Endpoint_t CDC1_ManagementEndpoint;
|
||||
USB_Descriptor_Interface_t CDC1_DCI_Interface;
|
||||
USB_Descriptor_Endpoint_t CDC1_DataOutEndpoint;
|
||||
USB_Descriptor_Endpoint_t CDC1_DataInEndpoint;
|
||||
USB_Descriptor_Interface_Association_t CDC2_IAD;
|
||||
USB_Descriptor_Interface_t CDC2_CCI_Interface;
|
||||
CDC_FUNCTIONAL_DESCRIPTOR(2) CDC2_Functional_IntHeader;
|
||||
CDC_FUNCTIONAL_DESCRIPTOR(1) CDC2_Functional_AbstractControlManagement;
|
||||
CDC_FUNCTIONAL_DESCRIPTOR(2) CDC2_Functional_Union;
|
||||
USB_Descriptor_Endpoint_t CDC2_ManagementEndpoint;
|
||||
USB_Descriptor_Interface_t CDC2_DCI_Interface;
|
||||
USB_Descriptor_Endpoint_t CDC2_DataOutEndpoint;
|
||||
USB_Descriptor_Endpoint_t CDC2_DataInEndpoint;
|
||||
} USB_Descriptor_Configuration_t;
|
||||
|
||||
/* Function Prototypes: */
|
||||
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);
|
||||
|
||||
#endif
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Header file for Descriptors.c.
|
||||
*/
|
||||
|
||||
#ifndef _DESCRIPTORS_H_
|
||||
#define _DESCRIPTORS_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/pgmspace.h>
|
||||
|
||||
#include <LUFA/Drivers/USB/USB.h>
|
||||
#include <LUFA/Drivers/USB/Class/CDC.h>
|
||||
|
||||
/* Macros: */
|
||||
/** Endpoint number of the first CDC interface's device-to-host notification IN endpoint. */
|
||||
#define CDC1_NOTIFICATION_EPNUM 3
|
||||
|
||||
/** Endpoint number of the first CDC interface's device-to-host data IN endpoint. */
|
||||
#define CDC1_TX_EPNUM 1
|
||||
|
||||
/** Endpoint number of the first CDC interface's host-to-device data OUT endpoint. */
|
||||
#define CDC1_RX_EPNUM 2
|
||||
|
||||
/** Endpoint number of the second CDC interface's device-to-host notification IN endpoint. */
|
||||
#define CDC2_NOTIFICATION_EPNUM 4
|
||||
|
||||
/** Endpoint number of the second CDC interface's device-to-host data IN endpoint. */
|
||||
#define CDC2_TX_EPNUM 5
|
||||
|
||||
/** Endpoint number of the second CDC interface's host-to-device data OUT endpoint. */
|
||||
#define CDC2_RX_EPNUM 6
|
||||
|
||||
/** Size in bytes of the CDC device-to-host notification IN endpoints. */
|
||||
#define CDC_NOTIFICATION_EPSIZE 8
|
||||
|
||||
/** Size in bytes of the CDC data IN and OUT endpoints. */
|
||||
#define CDC_TXRX_EPSIZE 16
|
||||
|
||||
/* Type Defines: */
|
||||
/** 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
|
||||
* vary between devices, and which describe the device's usage to the host.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
USB_Descriptor_Configuration_Header_t Config;
|
||||
USB_Descriptor_Interface_Association_t CDC1_IAD;
|
||||
USB_Descriptor_Interface_t CDC1_CCI_Interface;
|
||||
CDC_FUNCTIONAL_DESCRIPTOR(2) CDC1_Functional_IntHeader;
|
||||
CDC_FUNCTIONAL_DESCRIPTOR(1) CDC1_Functional_AbstractControlManagement;
|
||||
CDC_FUNCTIONAL_DESCRIPTOR(2) CDC1_Functional_Union;
|
||||
USB_Descriptor_Endpoint_t CDC1_ManagementEndpoint;
|
||||
USB_Descriptor_Interface_t CDC1_DCI_Interface;
|
||||
USB_Descriptor_Endpoint_t CDC1_DataOutEndpoint;
|
||||
USB_Descriptor_Endpoint_t CDC1_DataInEndpoint;
|
||||
USB_Descriptor_Interface_Association_t CDC2_IAD;
|
||||
USB_Descriptor_Interface_t CDC2_CCI_Interface;
|
||||
CDC_FUNCTIONAL_DESCRIPTOR(2) CDC2_Functional_IntHeader;
|
||||
CDC_FUNCTIONAL_DESCRIPTOR(1) CDC2_Functional_AbstractControlManagement;
|
||||
CDC_FUNCTIONAL_DESCRIPTOR(2) CDC2_Functional_Union;
|
||||
USB_Descriptor_Endpoint_t CDC2_ManagementEndpoint;
|
||||
USB_Descriptor_Interface_t CDC2_DCI_Interface;
|
||||
USB_Descriptor_Endpoint_t CDC2_DataOutEndpoint;
|
||||
USB_Descriptor_Endpoint_t CDC2_DataInEndpoint;
|
||||
} USB_Descriptor_Configuration_t;
|
||||
|
||||
/* Function Prototypes: */
|
||||
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);
|
||||
|
||||
#endif
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,192 +1,192 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Main source file for the DualVirtualSerial demo. This file contains the main tasks of
|
||||
* the demo and is responsible for the initial application hardware configuration.
|
||||
*/
|
||||
|
||||
#include "DualVirtualSerial.h"
|
||||
|
||||
/** 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
|
||||
* 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.
|
||||
*/
|
||||
USB_ClassInfo_CDC_Device_t VirtualSerial1_CDC_Interface =
|
||||
{
|
||||
.Config =
|
||||
{
|
||||
.ControlInterfaceNumber = 0,
|
||||
|
||||
.DataINEndpointNumber = CDC1_TX_EPNUM,
|
||||
.DataINEndpointSize = CDC_TXRX_EPSIZE,
|
||||
.DataINEndpointDoubleBank = false,
|
||||
|
||||
.DataOUTEndpointNumber = CDC1_RX_EPNUM,
|
||||
.DataOUTEndpointSize = CDC_TXRX_EPSIZE,
|
||||
.DataOUTEndpointDoubleBank = false,
|
||||
|
||||
.NotificationEndpointNumber = CDC1_NOTIFICATION_EPNUM,
|
||||
.NotificationEndpointSize = CDC_NOTIFICATION_EPSIZE,
|
||||
.NotificationEndpointDoubleBank = false,
|
||||
},
|
||||
};
|
||||
|
||||
/** 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
|
||||
* 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.
|
||||
*/
|
||||
USB_ClassInfo_CDC_Device_t VirtualSerial2_CDC_Interface =
|
||||
{
|
||||
.Config =
|
||||
{
|
||||
.ControlInterfaceNumber = 2,
|
||||
|
||||
.DataINEndpointNumber = CDC2_TX_EPNUM,
|
||||
.DataINEndpointSize = CDC_TXRX_EPSIZE,
|
||||
.DataINEndpointDoubleBank = false,
|
||||
|
||||
.DataOUTEndpointNumber = CDC2_RX_EPNUM,
|
||||
.DataOUTEndpointSize = CDC_TXRX_EPSIZE,
|
||||
.DataOUTEndpointDoubleBank = false,
|
||||
|
||||
.NotificationEndpointNumber = CDC2_NOTIFICATION_EPNUM,
|
||||
.NotificationEndpointSize = CDC_NOTIFICATION_EPSIZE,
|
||||
.NotificationEndpointDoubleBank = false,
|
||||
},
|
||||
};
|
||||
|
||||
/** Main program entry point. This routine contains the overall program flow, including initial
|
||||
* setup of all components and the main program loop.
|
||||
*/
|
||||
int main(void)
|
||||
{
|
||||
SetupHardware();
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
|
||||
sei();
|
||||
|
||||
for (;;)
|
||||
{
|
||||
CheckJoystickMovement();
|
||||
|
||||
/* Discard all received data on the first CDC interface */
|
||||
while (CDC_Device_BytesReceived(&VirtualSerial1_CDC_Interface))
|
||||
CDC_Device_ReceiveByte(&VirtualSerial1_CDC_Interface);
|
||||
|
||||
/* Echo all received data on the second CDC interface */
|
||||
while (CDC_Device_BytesReceived(&VirtualSerial2_CDC_Interface))
|
||||
CDC_Device_SendByte(&VirtualSerial2_CDC_Interface, CDC_Device_ReceiveByte(&VirtualSerial2_CDC_Interface));
|
||||
|
||||
CDC_Device_USBTask(&VirtualSerial1_CDC_Interface);
|
||||
CDC_Device_USBTask(&VirtualSerial2_CDC_Interface);
|
||||
USB_USBTask();
|
||||
}
|
||||
}
|
||||
|
||||
/** Configures the board hardware and chip peripherals for the demo's functionality. */
|
||||
void SetupHardware(void)
|
||||
{
|
||||
/* Disable watchdog if enabled by bootloader/fuses */
|
||||
MCUSR &= ~(1 << WDRF);
|
||||
wdt_disable();
|
||||
|
||||
/* Disable clock division */
|
||||
clock_prescale_set(clock_div_1);
|
||||
|
||||
/* Hardware Initialization */
|
||||
Joystick_Init();
|
||||
LEDs_Init();
|
||||
USB_Init();
|
||||
}
|
||||
|
||||
/** 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.
|
||||
*/
|
||||
void CheckJoystickMovement(void)
|
||||
{
|
||||
uint8_t JoyStatus_LCL = Joystick_GetStatus();
|
||||
char* ReportString = NULL;
|
||||
static bool ActionSent = false;
|
||||
|
||||
if (JoyStatus_LCL & JOY_UP)
|
||||
ReportString = "Joystick Up\r\n";
|
||||
else if (JoyStatus_LCL & JOY_DOWN)
|
||||
ReportString = "Joystick Down\r\n";
|
||||
else if (JoyStatus_LCL & JOY_LEFT)
|
||||
ReportString = "Joystick Left\r\n";
|
||||
else if (JoyStatus_LCL & JOY_RIGHT)
|
||||
ReportString = "Joystick Right\r\n";
|
||||
else if (JoyStatus_LCL & JOY_PRESS)
|
||||
ReportString = "Joystick Pressed\r\n";
|
||||
else
|
||||
ActionSent = false;
|
||||
|
||||
if ((ReportString != NULL) && (ActionSent == false))
|
||||
{
|
||||
ActionSent = true;
|
||||
|
||||
CDC_Device_SendString(&VirtualSerial1_CDC_Interface, ReportString, strlen(ReportString));
|
||||
}
|
||||
}
|
||||
|
||||
/** Event handler for the library USB Connection event. */
|
||||
void EVENT_USB_Device_Connect(void)
|
||||
{
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
|
||||
}
|
||||
|
||||
/** Event handler for the library USB Disconnection event. */
|
||||
void EVENT_USB_Device_Disconnect(void)
|
||||
{
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
|
||||
}
|
||||
|
||||
/** Event handler for the library USB Configuration Changed event. */
|
||||
void EVENT_USB_Device_ConfigurationChanged(void)
|
||||
{
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
|
||||
if (!(CDC_Device_ConfigureEndpoints(&VirtualSerial1_CDC_Interface)))
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
if (!(CDC_Device_ConfigureEndpoints(&VirtualSerial2_CDC_Interface)))
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
}
|
||||
|
||||
/** Event handler for the library USB Unhandled Control Request event. */
|
||||
void EVENT_USB_Device_UnhandledControlRequest(void)
|
||||
{
|
||||
CDC_Device_ProcessControlRequest(&VirtualSerial1_CDC_Interface);
|
||||
CDC_Device_ProcessControlRequest(&VirtualSerial2_CDC_Interface);
|
||||
}
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Main source file for the DualVirtualSerial demo. This file contains the main tasks of
|
||||
* the demo and is responsible for the initial application hardware configuration.
|
||||
*/
|
||||
|
||||
#include "DualVirtualSerial.h"
|
||||
|
||||
/** 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
|
||||
* 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.
|
||||
*/
|
||||
USB_ClassInfo_CDC_Device_t VirtualSerial1_CDC_Interface =
|
||||
{
|
||||
.Config =
|
||||
{
|
||||
.ControlInterfaceNumber = 0,
|
||||
|
||||
.DataINEndpointNumber = CDC1_TX_EPNUM,
|
||||
.DataINEndpointSize = CDC_TXRX_EPSIZE,
|
||||
.DataINEndpointDoubleBank = false,
|
||||
|
||||
.DataOUTEndpointNumber = CDC1_RX_EPNUM,
|
||||
.DataOUTEndpointSize = CDC_TXRX_EPSIZE,
|
||||
.DataOUTEndpointDoubleBank = false,
|
||||
|
||||
.NotificationEndpointNumber = CDC1_NOTIFICATION_EPNUM,
|
||||
.NotificationEndpointSize = CDC_NOTIFICATION_EPSIZE,
|
||||
.NotificationEndpointDoubleBank = false,
|
||||
},
|
||||
};
|
||||
|
||||
/** 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
|
||||
* 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.
|
||||
*/
|
||||
USB_ClassInfo_CDC_Device_t VirtualSerial2_CDC_Interface =
|
||||
{
|
||||
.Config =
|
||||
{
|
||||
.ControlInterfaceNumber = 2,
|
||||
|
||||
.DataINEndpointNumber = CDC2_TX_EPNUM,
|
||||
.DataINEndpointSize = CDC_TXRX_EPSIZE,
|
||||
.DataINEndpointDoubleBank = false,
|
||||
|
||||
.DataOUTEndpointNumber = CDC2_RX_EPNUM,
|
||||
.DataOUTEndpointSize = CDC_TXRX_EPSIZE,
|
||||
.DataOUTEndpointDoubleBank = false,
|
||||
|
||||
.NotificationEndpointNumber = CDC2_NOTIFICATION_EPNUM,
|
||||
.NotificationEndpointSize = CDC_NOTIFICATION_EPSIZE,
|
||||
.NotificationEndpointDoubleBank = false,
|
||||
},
|
||||
};
|
||||
|
||||
/** Main program entry point. This routine contains the overall program flow, including initial
|
||||
* setup of all components and the main program loop.
|
||||
*/
|
||||
int main(void)
|
||||
{
|
||||
SetupHardware();
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
|
||||
sei();
|
||||
|
||||
for (;;)
|
||||
{
|
||||
CheckJoystickMovement();
|
||||
|
||||
/* Discard all received data on the first CDC interface */
|
||||
while (CDC_Device_BytesReceived(&VirtualSerial1_CDC_Interface))
|
||||
CDC_Device_ReceiveByte(&VirtualSerial1_CDC_Interface);
|
||||
|
||||
/* Echo all received data on the second CDC interface */
|
||||
while (CDC_Device_BytesReceived(&VirtualSerial2_CDC_Interface))
|
||||
CDC_Device_SendByte(&VirtualSerial2_CDC_Interface, CDC_Device_ReceiveByte(&VirtualSerial2_CDC_Interface));
|
||||
|
||||
CDC_Device_USBTask(&VirtualSerial1_CDC_Interface);
|
||||
CDC_Device_USBTask(&VirtualSerial2_CDC_Interface);
|
||||
USB_USBTask();
|
||||
}
|
||||
}
|
||||
|
||||
/** Configures the board hardware and chip peripherals for the demo's functionality. */
|
||||
void SetupHardware(void)
|
||||
{
|
||||
/* Disable watchdog if enabled by bootloader/fuses */
|
||||
MCUSR &= ~(1 << WDRF);
|
||||
wdt_disable();
|
||||
|
||||
/* Disable clock division */
|
||||
clock_prescale_set(clock_div_1);
|
||||
|
||||
/* Hardware Initialization */
|
||||
Joystick_Init();
|
||||
LEDs_Init();
|
||||
USB_Init();
|
||||
}
|
||||
|
||||
/** 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.
|
||||
*/
|
||||
void CheckJoystickMovement(void)
|
||||
{
|
||||
uint8_t JoyStatus_LCL = Joystick_GetStatus();
|
||||
char* ReportString = NULL;
|
||||
static bool ActionSent = false;
|
||||
|
||||
if (JoyStatus_LCL & JOY_UP)
|
||||
ReportString = "Joystick Up\r\n";
|
||||
else if (JoyStatus_LCL & JOY_DOWN)
|
||||
ReportString = "Joystick Down\r\n";
|
||||
else if (JoyStatus_LCL & JOY_LEFT)
|
||||
ReportString = "Joystick Left\r\n";
|
||||
else if (JoyStatus_LCL & JOY_RIGHT)
|
||||
ReportString = "Joystick Right\r\n";
|
||||
else if (JoyStatus_LCL & JOY_PRESS)
|
||||
ReportString = "Joystick Pressed\r\n";
|
||||
else
|
||||
ActionSent = false;
|
||||
|
||||
if ((ReportString != NULL) && (ActionSent == false))
|
||||
{
|
||||
ActionSent = true;
|
||||
|
||||
CDC_Device_SendString(&VirtualSerial1_CDC_Interface, ReportString, strlen(ReportString));
|
||||
}
|
||||
}
|
||||
|
||||
/** Event handler for the library USB Connection event. */
|
||||
void EVENT_USB_Device_Connect(void)
|
||||
{
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
|
||||
}
|
||||
|
||||
/** Event handler for the library USB Disconnection event. */
|
||||
void EVENT_USB_Device_Disconnect(void)
|
||||
{
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
|
||||
}
|
||||
|
||||
/** Event handler for the library USB Configuration Changed event. */
|
||||
void EVENT_USB_Device_ConfigurationChanged(void)
|
||||
{
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
|
||||
if (!(CDC_Device_ConfigureEndpoints(&VirtualSerial1_CDC_Interface)))
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
if (!(CDC_Device_ConfigureEndpoints(&VirtualSerial2_CDC_Interface)))
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
}
|
||||
|
||||
/** Event handler for the library USB Unhandled Control Request event. */
|
||||
void EVENT_USB_Device_UnhandledControlRequest(void)
|
||||
{
|
||||
CDC_Device_ProcessControlRequest(&VirtualSerial1_CDC_Interface);
|
||||
CDC_Device_ProcessControlRequest(&VirtualSerial2_CDC_Interface);
|
||||
}
|
||||
|
@ -1,76 +1,76 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Header file for DualVirtualSerial.c.
|
||||
*/
|
||||
|
||||
#ifndef _DUAL_VIRTUALSERIAL_H_
|
||||
#define _DUAL_VIRTUALSERIAL_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/io.h>
|
||||
#include <avr/wdt.h>
|
||||
#include <avr/power.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "Descriptors.h"
|
||||
|
||||
#include <LUFA/Version.h>
|
||||
#include <LUFA/Drivers/Board/LEDs.h>
|
||||
#include <LUFA/Drivers/Board/Joystick.h>
|
||||
#include <LUFA/Drivers/USB/USB.h>
|
||||
#include <LUFA/Drivers/USB/Class/CDC.h>
|
||||
|
||||
/* Macros: */
|
||||
/** LED mask for the library LED driver, to indicate that the USB interface is not ready. */
|
||||
#define LEDMASK_USB_NOTREADY LEDS_LED1
|
||||
|
||||
/** LED mask for the library LED driver, to indicate that the USB interface is enumerating. */
|
||||
#define LEDMASK_USB_ENUMERATING (LEDS_LED2 | LEDS_LED3)
|
||||
|
||||
/** LED mask for the library LED driver, to indicate that the USB interface is ready. */
|
||||
#define LEDMASK_USB_READY (LEDS_LED2 | LEDS_LED4)
|
||||
|
||||
/** LED mask for the library LED driver, to indicate that an error has occurred in the USB interface. */
|
||||
#define LEDMASK_USB_ERROR (LEDS_LED1 | LEDS_LED3)
|
||||
|
||||
/* Function Prototypes: */
|
||||
void SetupHardware(void);
|
||||
void CheckJoystickMovement(void);
|
||||
|
||||
void EVENT_USB_Device_Connect(void);
|
||||
void EVENT_USB_Device_Disconnect(void);
|
||||
void EVENT_USB_Device_ConfigurationChanged(void);
|
||||
void EVENT_USB_Device_UnhandledControlRequest(void);
|
||||
|
||||
#endif
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Header file for DualVirtualSerial.c.
|
||||
*/
|
||||
|
||||
#ifndef _DUAL_VIRTUALSERIAL_H_
|
||||
#define _DUAL_VIRTUALSERIAL_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/io.h>
|
||||
#include <avr/wdt.h>
|
||||
#include <avr/power.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "Descriptors.h"
|
||||
|
||||
#include <LUFA/Version.h>
|
||||
#include <LUFA/Drivers/Board/LEDs.h>
|
||||
#include <LUFA/Drivers/Board/Joystick.h>
|
||||
#include <LUFA/Drivers/USB/USB.h>
|
||||
#include <LUFA/Drivers/USB/Class/CDC.h>
|
||||
|
||||
/* Macros: */
|
||||
/** LED mask for the library LED driver, to indicate that the USB interface is not ready. */
|
||||
#define LEDMASK_USB_NOTREADY LEDS_LED1
|
||||
|
||||
/** LED mask for the library LED driver, to indicate that the USB interface is enumerating. */
|
||||
#define LEDMASK_USB_ENUMERATING (LEDS_LED2 | LEDS_LED3)
|
||||
|
||||
/** LED mask for the library LED driver, to indicate that the USB interface is ready. */
|
||||
#define LEDMASK_USB_READY (LEDS_LED2 | LEDS_LED4)
|
||||
|
||||
/** LED mask for the library LED driver, to indicate that an error has occurred in the USB interface. */
|
||||
#define LEDMASK_USB_ERROR (LEDS_LED1 | LEDS_LED3)
|
||||
|
||||
/* Function Prototypes: */
|
||||
void SetupHardware(void);
|
||||
void CheckJoystickMovement(void);
|
||||
|
||||
void EVENT_USB_Device_Connect(void);
|
||||
void EVENT_USB_Device_Disconnect(void);
|
||||
void EVENT_USB_Device_ConfigurationChanged(void);
|
||||
void EVENT_USB_Device_UnhandledControlRequest(void);
|
||||
|
||||
#endif
|
||||
|
@ -1,85 +1,85 @@
|
||||
/** \file
|
||||
*
|
||||
* This file contains special DoxyGen information for the generation of the main page and other special
|
||||
* documentation pages. It is not a project source file.
|
||||
*/
|
||||
|
||||
/** \mainpage Dual Communications Device Class (Dual Virtual Serial Port) Device
|
||||
*
|
||||
* \section SSec_Compat Demo Compatibility:
|
||||
*
|
||||
* The following list indicates what microcontrollers are compatible with this demo.
|
||||
*
|
||||
* - Series 7 USB AVRs
|
||||
* - Series 6 USB AVRs
|
||||
* - Series 4 USB AVRs
|
||||
*
|
||||
* \section SSec_Info USB Information:
|
||||
*
|
||||
* The following table gives a rundown of the USB utilization of this demo.
|
||||
*
|
||||
* <table>
|
||||
* <tr>
|
||||
* <td><b>USB Mode:</b></td>
|
||||
* <td>Device</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>USB Class:</b></td>
|
||||
* <td>Communications Device Class (CDC)</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>USB Subclass:</b></td>
|
||||
* <td>Abstract Control Model (ACM)</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>Relevant Standards:</b></td>
|
||||
* <td>USBIF CDC Class Standard</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>Relevant Standards:</b></td>
|
||||
* <td>USBIF Interface Association Descriptor ECN \n
|
||||
* USBIF CDC Class Standard</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>Usable Speeds:</b></td>
|
||||
* <td>Full Speed Mode</td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*
|
||||
* \section SSec_Description Project Description:
|
||||
*
|
||||
* Dual Communications Device Class demonstration application.
|
||||
* This gives a simple reference application for implementing
|
||||
* a compound device with dual CDC functions acting as a pair
|
||||
* of virtual serial ports. This demo uses Interface Association
|
||||
* Descriptors to link together the pair of related CDC
|
||||
* descriptors for each virtual serial port, which may not be
|
||||
* supported in all OSes - Windows Vista is supported, as is
|
||||
* XP (although the latter may need a hotfix to function).
|
||||
*
|
||||
* Joystick actions are transmitted to the host as strings
|
||||
* through the first serial port. The device does not respond to
|
||||
* serial data sent from the host in the first serial port.
|
||||
*
|
||||
* The second serial port echoes back data sent from the host.
|
||||
*
|
||||
* After running this demo for the first time on a new computer,
|
||||
* you will need to supply the .INF file located in this demo
|
||||
* 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 device. Other
|
||||
* Operating Systems should automatically use their own inbuilt
|
||||
* CDC-ACM drivers.
|
||||
*
|
||||
* \section SSec_Options Project Options
|
||||
*
|
||||
* The following defines can be found in this demo, which can control the demo behaviour when defined, or changed in value.
|
||||
*
|
||||
* <table>
|
||||
* <tr>
|
||||
* <td>
|
||||
* None
|
||||
* </td>
|
||||
* </tr>
|
||||
* </table>
|
||||
/** \file
|
||||
*
|
||||
* This file contains special DoxyGen information for the generation of the main page and other special
|
||||
* documentation pages. It is not a project source file.
|
||||
*/
|
||||
|
||||
/** \mainpage Dual Communications Device Class (Dual Virtual Serial Port) Device
|
||||
*
|
||||
* \section SSec_Compat Demo Compatibility:
|
||||
*
|
||||
* The following list indicates what microcontrollers are compatible with this demo.
|
||||
*
|
||||
* - Series 7 USB AVRs
|
||||
* - Series 6 USB AVRs
|
||||
* - Series 4 USB AVRs
|
||||
*
|
||||
* \section SSec_Info USB Information:
|
||||
*
|
||||
* The following table gives a rundown of the USB utilization of this demo.
|
||||
*
|
||||
* <table>
|
||||
* <tr>
|
||||
* <td><b>USB Mode:</b></td>
|
||||
* <td>Device</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>USB Class:</b></td>
|
||||
* <td>Communications Device Class (CDC)</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>USB Subclass:</b></td>
|
||||
* <td>Abstract Control Model (ACM)</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>Relevant Standards:</b></td>
|
||||
* <td>USBIF CDC Class Standard</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>Relevant Standards:</b></td>
|
||||
* <td>USBIF Interface Association Descriptor ECN \n
|
||||
* USBIF CDC Class Standard</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>Usable Speeds:</b></td>
|
||||
* <td>Full Speed Mode</td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*
|
||||
* \section SSec_Description Project Description:
|
||||
*
|
||||
* Dual Communications Device Class demonstration application.
|
||||
* This gives a simple reference application for implementing
|
||||
* a compound device with dual CDC functions acting as a pair
|
||||
* of virtual serial ports. This demo uses Interface Association
|
||||
* Descriptors to link together the pair of related CDC
|
||||
* descriptors for each virtual serial port, which may not be
|
||||
* supported in all OSes - Windows Vista is supported, as is
|
||||
* XP (although the latter may need a hotfix to function).
|
||||
*
|
||||
* Joystick actions are transmitted to the host as strings
|
||||
* through the first serial port. The device does not respond to
|
||||
* serial data sent from the host in the first serial port.
|
||||
*
|
||||
* The second serial port echoes back data sent from the host.
|
||||
*
|
||||
* After running this demo for the first time on a new computer,
|
||||
* you will need to supply the .INF file located in this demo
|
||||
* 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 device. Other
|
||||
* Operating Systems should automatically use their own inbuilt
|
||||
* CDC-ACM drivers.
|
||||
*
|
||||
* \section SSec_Options Project Options
|
||||
*
|
||||
* The following defines can be found in this demo, which can control the demo behaviour when defined, or changed in value.
|
||||
*
|
||||
* <table>
|
||||
* <tr>
|
||||
* <td>
|
||||
* None
|
||||
* </td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*/
|
@ -1,106 +1,106 @@
|
||||
;************************************************************
|
||||
; Windows USB CDC ACM Setup File
|
||||
; Copyright (c) 2000 Microsoft Corporation
|
||||
|
||||
|
||||
[Version]
|
||||
Signature="$Windows NT$"
|
||||
Class=Ports
|
||||
ClassGuid={4D36E978-E325-11CE-BFC1-08002BE10318}
|
||||
Provider=%MFGNAME%
|
||||
LayoutFile=layout.inf
|
||||
CatalogFile=%MFGFILENAME%.cat
|
||||
DriverVer=11/15/2007,5.1.2600.0
|
||||
|
||||
[Manufacturer]
|
||||
%MFGNAME%=DeviceList, NTamd64
|
||||
|
||||
[DestinationDirs]
|
||||
DefaultDestDir=12
|
||||
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; Windows 2000/XP/Vista-32bit Sections
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
[DriverInstall.nt]
|
||||
include=mdmcpq.inf
|
||||
CopyFiles=DriverCopyFiles.nt
|
||||
AddReg=DriverInstall.nt.AddReg
|
||||
|
||||
[DriverCopyFiles.nt]
|
||||
usbser.sys,,,0x20
|
||||
|
||||
[DriverInstall.nt.AddReg]
|
||||
HKR,,DevLoader,,*ntkern
|
||||
HKR,,NTMPDriver,,%DRIVERFILENAME%.sys
|
||||
HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider"
|
||||
|
||||
[DriverInstall.nt.Services]
|
||||
AddService=usbser, 0x00000002, DriverService.nt
|
||||
|
||||
[DriverService.nt]
|
||||
DisplayName=%SERVICE%
|
||||
ServiceType=1
|
||||
StartType=3
|
||||
ErrorControl=1
|
||||
ServiceBinary=%12%\%DRIVERFILENAME%.sys
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; Vista-64bit Sections
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
[DriverInstall.NTamd64]
|
||||
include=mdmcpq.inf
|
||||
CopyFiles=DriverCopyFiles.NTamd64
|
||||
AddReg=DriverInstall.NTamd64.AddReg
|
||||
|
||||
[DriverCopyFiles.NTamd64]
|
||||
%DRIVERFILENAME%.sys,,,0x20
|
||||
|
||||
[DriverInstall.NTamd64.AddReg]
|
||||
HKR,,DevLoader,,*ntkern
|
||||
HKR,,NTMPDriver,,%DRIVERFILENAME%.sys
|
||||
HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider"
|
||||
|
||||
[DriverInstall.NTamd64.Services]
|
||||
AddService=usbser, 0x00000002, DriverService.NTamd64
|
||||
|
||||
[DriverService.NTamd64]
|
||||
DisplayName=%SERVICE%
|
||||
ServiceType=1
|
||||
StartType=3
|
||||
ErrorControl=1
|
||||
ServiceBinary=%12%\%DRIVERFILENAME%.sys
|
||||
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; Vendor and Product ID Definitions
|
||||
;------------------------------------------------------------------------------
|
||||
; When developing your USB device, the VID and PID used in the PC side
|
||||
; 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.
|
||||
; 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.
|
||||
;------------------------------------------------------------------------------
|
||||
[SourceDisksFiles]
|
||||
[SourceDisksNames]
|
||||
[DeviceList]
|
||||
%DESCRIPTION%=DriverInstall, USB\VID_03EB&PID_204E&MI_00, USB\VID_03EB&PID_204E&MI_02
|
||||
|
||||
[DeviceList.NTamd64]
|
||||
%DESCRIPTION%=DriverInstall, USB\VID_03EB&PID_204E&MI_00, USB\VID_03EB&PID_204E&MI_02
|
||||
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; String Definitions
|
||||
;------------------------------------------------------------------------------
|
||||
;Modify these strings to customize your device
|
||||
;------------------------------------------------------------------------------
|
||||
[Strings]
|
||||
MFGFILENAME="CDC_vista"
|
||||
DRIVERFILENAME ="usbser"
|
||||
MFGNAME="http://www.fourwalledcubicle.com"
|
||||
INSTDISK="LUFA Dual CDC Driver Installer"
|
||||
DESCRIPTION="Communications Port"
|
||||
;************************************************************
|
||||
; Windows USB CDC ACM Setup File
|
||||
; Copyright (c) 2000 Microsoft Corporation
|
||||
|
||||
|
||||
[Version]
|
||||
Signature="$Windows NT$"
|
||||
Class=Ports
|
||||
ClassGuid={4D36E978-E325-11CE-BFC1-08002BE10318}
|
||||
Provider=%MFGNAME%
|
||||
LayoutFile=layout.inf
|
||||
CatalogFile=%MFGFILENAME%.cat
|
||||
DriverVer=11/15/2007,5.1.2600.0
|
||||
|
||||
[Manufacturer]
|
||||
%MFGNAME%=DeviceList, NTamd64
|
||||
|
||||
[DestinationDirs]
|
||||
DefaultDestDir=12
|
||||
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; Windows 2000/XP/Vista-32bit Sections
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
[DriverInstall.nt]
|
||||
include=mdmcpq.inf
|
||||
CopyFiles=DriverCopyFiles.nt
|
||||
AddReg=DriverInstall.nt.AddReg
|
||||
|
||||
[DriverCopyFiles.nt]
|
||||
usbser.sys,,,0x20
|
||||
|
||||
[DriverInstall.nt.AddReg]
|
||||
HKR,,DevLoader,,*ntkern
|
||||
HKR,,NTMPDriver,,%DRIVERFILENAME%.sys
|
||||
HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider"
|
||||
|
||||
[DriverInstall.nt.Services]
|
||||
AddService=usbser, 0x00000002, DriverService.nt
|
||||
|
||||
[DriverService.nt]
|
||||
DisplayName=%SERVICE%
|
||||
ServiceType=1
|
||||
StartType=3
|
||||
ErrorControl=1
|
||||
ServiceBinary=%12%\%DRIVERFILENAME%.sys
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; Vista-64bit Sections
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
[DriverInstall.NTamd64]
|
||||
include=mdmcpq.inf
|
||||
CopyFiles=DriverCopyFiles.NTamd64
|
||||
AddReg=DriverInstall.NTamd64.AddReg
|
||||
|
||||
[DriverCopyFiles.NTamd64]
|
||||
%DRIVERFILENAME%.sys,,,0x20
|
||||
|
||||
[DriverInstall.NTamd64.AddReg]
|
||||
HKR,,DevLoader,,*ntkern
|
||||
HKR,,NTMPDriver,,%DRIVERFILENAME%.sys
|
||||
HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider"
|
||||
|
||||
[DriverInstall.NTamd64.Services]
|
||||
AddService=usbser, 0x00000002, DriverService.NTamd64
|
||||
|
||||
[DriverService.NTamd64]
|
||||
DisplayName=%SERVICE%
|
||||
ServiceType=1
|
||||
StartType=3
|
||||
ErrorControl=1
|
||||
ServiceBinary=%12%\%DRIVERFILENAME%.sys
|
||||
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; Vendor and Product ID Definitions
|
||||
;------------------------------------------------------------------------------
|
||||
; When developing your USB device, the VID and PID used in the PC side
|
||||
; 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.
|
||||
; 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.
|
||||
;------------------------------------------------------------------------------
|
||||
[SourceDisksFiles]
|
||||
[SourceDisksNames]
|
||||
[DeviceList]
|
||||
%DESCRIPTION%=DriverInstall, USB\VID_03EB&PID_204E&MI_00, USB\VID_03EB&PID_204E&MI_02
|
||||
|
||||
[DeviceList.NTamd64]
|
||||
%DESCRIPTION%=DriverInstall, USB\VID_03EB&PID_204E&MI_00, USB\VID_03EB&PID_204E&MI_02
|
||||
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; String Definitions
|
||||
;------------------------------------------------------------------------------
|
||||
;Modify these strings to customize your device
|
||||
;------------------------------------------------------------------------------
|
||||
[Strings]
|
||||
MFGFILENAME="CDC_vista"
|
||||
DRIVERFILENAME ="usbser"
|
||||
MFGNAME="http://www.fourwalledcubicle.com"
|
||||
INSTDISK="LUFA Dual CDC Driver Installer"
|
||||
DESCRIPTION="Communications Port"
|
||||
SERVICE="USB RS-232 Emulation Driver"
|
File diff suppressed because it is too large
Load Diff
@ -1,240 +1,240 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* 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
|
||||
* the device's capabilities and functions.
|
||||
*/
|
||||
|
||||
#include "Descriptors.h"
|
||||
|
||||
/** 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
|
||||
* 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
|
||||
* more details on HID report descriptors.
|
||||
*/
|
||||
USB_Descriptor_HIDReport_Datatype_t PROGMEM GenericReport[] =
|
||||
{
|
||||
0x06, 0x9c, 0xff, /* Usage Page (Vendor Defined) */
|
||||
0x09, 0x01, /* Usage (Vendor Defined) */
|
||||
0xa1, 0x01, /* Collection (Vendor Defined) */
|
||||
0x09, 0x02, /* Usage (Vendor Defined) */
|
||||
0x75, 0x08, /* Report Size (8) */
|
||||
0x95, GENERIC_REPORT_SIZE, /* Report Count (GENERIC_REPORT_SIZE) */
|
||||
0x15, 0x80, /* Logical Minimum (-128) */
|
||||
0x25, 0x7F, /* Logical Maximum (127) */
|
||||
0x81, 0x02, /* Input (Data, Variable, Absolute) */
|
||||
0x09, 0x03, /* Usage (Vendor Defined) */
|
||||
0x75, 0x08, /* Report Size (8) */
|
||||
0x95, GENERIC_REPORT_SIZE, /* Report Count (GENERIC_REPORT_SIZE) */
|
||||
0x15, 0x00, /* Logical Minimum (0) */
|
||||
0x25, 0xff, /* Logical Maximum (255) */
|
||||
0x91, 0x02, /* Output (Data, Variable, Absolute) */
|
||||
0xc0 /* End Collection */
|
||||
};
|
||||
|
||||
/** Device descriptor structure. This descriptor, located in FLASH memory, describes the overall
|
||||
* 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
|
||||
* process begins.
|
||||
*/
|
||||
USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device},
|
||||
|
||||
.USBSpecification = VERSION_BCD(01.10),
|
||||
.Class = 0x00,
|
||||
.SubClass = 0x00,
|
||||
.Protocol = 0x00,
|
||||
|
||||
.Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE,
|
||||
|
||||
.VendorID = 0x03EB,
|
||||
.ProductID = 0x204F,
|
||||
.ReleaseNumber = 0x0000,
|
||||
|
||||
.ManufacturerStrIndex = 0x01,
|
||||
.ProductStrIndex = 0x02,
|
||||
.SerialNumStrIndex = NO_DESCRIPTOR,
|
||||
|
||||
.NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS
|
||||
};
|
||||
|
||||
/** 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
|
||||
* 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.
|
||||
*/
|
||||
USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
|
||||
{
|
||||
.Config =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration},
|
||||
|
||||
.TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t),
|
||||
.TotalInterfaces = 1,
|
||||
|
||||
.ConfigurationNumber = 1,
|
||||
.ConfigurationStrIndex = NO_DESCRIPTOR,
|
||||
|
||||
.ConfigAttributes = (USB_CONFIG_ATTR_BUSPOWERED | USB_CONFIG_ATTR_SELFPOWERED),
|
||||
|
||||
.MaxPowerConsumption = USB_CONFIG_POWER_MA(100)
|
||||
},
|
||||
|
||||
.HID_Interface =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
|
||||
|
||||
.InterfaceNumber = 0x00,
|
||||
.AlternateSetting = 0x00,
|
||||
|
||||
.TotalEndpoints = 1,
|
||||
|
||||
.Class = 0x03,
|
||||
.SubClass = 0x00,
|
||||
.Protocol = HID_NON_BOOT_PROTOCOL,
|
||||
|
||||
.InterfaceStrIndex = NO_DESCRIPTOR
|
||||
},
|
||||
|
||||
.HID_GenericHID =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_HID_Descriptor_t), .Type = DTYPE_HID},
|
||||
|
||||
.HIDSpec = VERSION_BCD(01.11),
|
||||
.CountryCode = 0x00,
|
||||
.TotalReportDescriptors = 1,
|
||||
.HIDReportType = DTYPE_Report,
|
||||
.HIDReportLength = sizeof(GenericReport)
|
||||
},
|
||||
|
||||
.HID_ReportINEndpoint =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
|
||||
|
||||
.EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_IN | GENERIC_IN_EPNUM),
|
||||
.Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
|
||||
.EndpointSize = GENERIC_EPSIZE,
|
||||
.PollingIntervalMS = 0x0A
|
||||
},
|
||||
};
|
||||
|
||||
/** 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
|
||||
* via the language ID table available at USB.org what languages the device supports for its string descriptors.
|
||||
*/
|
||||
USB_Descriptor_String_t PROGMEM LanguageString =
|
||||
{
|
||||
.Header = {.Size = USB_STRING_LEN(1), .Type = DTYPE_String},
|
||||
|
||||
.UnicodeString = {LANGUAGE_ID_ENG}
|
||||
};
|
||||
|
||||
/** 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
|
||||
* Descriptor.
|
||||
*/
|
||||
USB_Descriptor_String_t PROGMEM ManufacturerString =
|
||||
{
|
||||
.Header = {.Size = USB_STRING_LEN(11), .Type = DTYPE_String},
|
||||
|
||||
.UnicodeString = L"Dean Camera"
|
||||
};
|
||||
|
||||
/** 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
|
||||
* Descriptor.
|
||||
*/
|
||||
USB_Descriptor_String_t PROGMEM ProductString =
|
||||
{
|
||||
.Header = {.Size = USB_STRING_LEN(21), .Type = DTYPE_String},
|
||||
|
||||
.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"
|
||||
* 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
|
||||
* is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the
|
||||
* USB host.
|
||||
*/
|
||||
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 DescriptorNumber = (wValue & 0xFF);
|
||||
|
||||
void* Address = NULL;
|
||||
uint16_t Size = NO_DESCRIPTOR;
|
||||
|
||||
switch (DescriptorType)
|
||||
{
|
||||
case DTYPE_Device:
|
||||
Address = (void*)&DeviceDescriptor;
|
||||
Size = sizeof(USB_Descriptor_Device_t);
|
||||
break;
|
||||
case DTYPE_Configuration:
|
||||
Address = (void*)&ConfigurationDescriptor;
|
||||
Size = sizeof(USB_Descriptor_Configuration_t);
|
||||
break;
|
||||
case DTYPE_String:
|
||||
switch (DescriptorNumber)
|
||||
{
|
||||
case 0x00:
|
||||
Address = (void*)&LanguageString;
|
||||
Size = pgm_read_byte(&LanguageString.Header.Size);
|
||||
break;
|
||||
case 0x01:
|
||||
Address = (void*)&ManufacturerString;
|
||||
Size = pgm_read_byte(&ManufacturerString.Header.Size);
|
||||
break;
|
||||
case 0x02:
|
||||
Address = (void*)&ProductString;
|
||||
Size = pgm_read_byte(&ProductString.Header.Size);
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
case DTYPE_HID:
|
||||
Address = (void*)&ConfigurationDescriptor.HID_GenericHID;
|
||||
Size = sizeof(USB_HID_Descriptor_t);
|
||||
break;
|
||||
case DTYPE_Report:
|
||||
Address = (void*)&GenericReport;
|
||||
Size = sizeof(GenericReport);
|
||||
break;
|
||||
}
|
||||
|
||||
*DescriptorAddress = Address;
|
||||
return Size;
|
||||
}
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* 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
|
||||
* the device's capabilities and functions.
|
||||
*/
|
||||
|
||||
#include "Descriptors.h"
|
||||
|
||||
/** 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
|
||||
* 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
|
||||
* more details on HID report descriptors.
|
||||
*/
|
||||
USB_Descriptor_HIDReport_Datatype_t PROGMEM GenericReport[] =
|
||||
{
|
||||
0x06, 0x9c, 0xff, /* Usage Page (Vendor Defined) */
|
||||
0x09, 0x01, /* Usage (Vendor Defined) */
|
||||
0xa1, 0x01, /* Collection (Vendor Defined) */
|
||||
0x09, 0x02, /* Usage (Vendor Defined) */
|
||||
0x75, 0x08, /* Report Size (8) */
|
||||
0x95, GENERIC_REPORT_SIZE, /* Report Count (GENERIC_REPORT_SIZE) */
|
||||
0x15, 0x80, /* Logical Minimum (-128) */
|
||||
0x25, 0x7F, /* Logical Maximum (127) */
|
||||
0x81, 0x02, /* Input (Data, Variable, Absolute) */
|
||||
0x09, 0x03, /* Usage (Vendor Defined) */
|
||||
0x75, 0x08, /* Report Size (8) */
|
||||
0x95, GENERIC_REPORT_SIZE, /* Report Count (GENERIC_REPORT_SIZE) */
|
||||
0x15, 0x00, /* Logical Minimum (0) */
|
||||
0x25, 0xff, /* Logical Maximum (255) */
|
||||
0x91, 0x02, /* Output (Data, Variable, Absolute) */
|
||||
0xc0 /* End Collection */
|
||||
};
|
||||
|
||||
/** Device descriptor structure. This descriptor, located in FLASH memory, describes the overall
|
||||
* 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
|
||||
* process begins.
|
||||
*/
|
||||
USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device},
|
||||
|
||||
.USBSpecification = VERSION_BCD(01.10),
|
||||
.Class = 0x00,
|
||||
.SubClass = 0x00,
|
||||
.Protocol = 0x00,
|
||||
|
||||
.Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE,
|
||||
|
||||
.VendorID = 0x03EB,
|
||||
.ProductID = 0x204F,
|
||||
.ReleaseNumber = 0x0000,
|
||||
|
||||
.ManufacturerStrIndex = 0x01,
|
||||
.ProductStrIndex = 0x02,
|
||||
.SerialNumStrIndex = NO_DESCRIPTOR,
|
||||
|
||||
.NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS
|
||||
};
|
||||
|
||||
/** 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
|
||||
* 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.
|
||||
*/
|
||||
USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
|
||||
{
|
||||
.Config =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration},
|
||||
|
||||
.TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t),
|
||||
.TotalInterfaces = 1,
|
||||
|
||||
.ConfigurationNumber = 1,
|
||||
.ConfigurationStrIndex = NO_DESCRIPTOR,
|
||||
|
||||
.ConfigAttributes = (USB_CONFIG_ATTR_BUSPOWERED | USB_CONFIG_ATTR_SELFPOWERED),
|
||||
|
||||
.MaxPowerConsumption = USB_CONFIG_POWER_MA(100)
|
||||
},
|
||||
|
||||
.HID_Interface =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
|
||||
|
||||
.InterfaceNumber = 0x00,
|
||||
.AlternateSetting = 0x00,
|
||||
|
||||
.TotalEndpoints = 1,
|
||||
|
||||
.Class = 0x03,
|
||||
.SubClass = 0x00,
|
||||
.Protocol = HID_NON_BOOT_PROTOCOL,
|
||||
|
||||
.InterfaceStrIndex = NO_DESCRIPTOR
|
||||
},
|
||||
|
||||
.HID_GenericHID =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_HID_Descriptor_t), .Type = DTYPE_HID},
|
||||
|
||||
.HIDSpec = VERSION_BCD(01.11),
|
||||
.CountryCode = 0x00,
|
||||
.TotalReportDescriptors = 1,
|
||||
.HIDReportType = DTYPE_Report,
|
||||
.HIDReportLength = sizeof(GenericReport)
|
||||
},
|
||||
|
||||
.HID_ReportINEndpoint =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
|
||||
|
||||
.EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_IN | GENERIC_IN_EPNUM),
|
||||
.Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
|
||||
.EndpointSize = GENERIC_EPSIZE,
|
||||
.PollingIntervalMS = 0x0A
|
||||
},
|
||||
};
|
||||
|
||||
/** 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
|
||||
* via the language ID table available at USB.org what languages the device supports for its string descriptors.
|
||||
*/
|
||||
USB_Descriptor_String_t PROGMEM LanguageString =
|
||||
{
|
||||
.Header = {.Size = USB_STRING_LEN(1), .Type = DTYPE_String},
|
||||
|
||||
.UnicodeString = {LANGUAGE_ID_ENG}
|
||||
};
|
||||
|
||||
/** 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
|
||||
* Descriptor.
|
||||
*/
|
||||
USB_Descriptor_String_t PROGMEM ManufacturerString =
|
||||
{
|
||||
.Header = {.Size = USB_STRING_LEN(11), .Type = DTYPE_String},
|
||||
|
||||
.UnicodeString = L"Dean Camera"
|
||||
};
|
||||
|
||||
/** 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
|
||||
* Descriptor.
|
||||
*/
|
||||
USB_Descriptor_String_t PROGMEM ProductString =
|
||||
{
|
||||
.Header = {.Size = USB_STRING_LEN(21), .Type = DTYPE_String},
|
||||
|
||||
.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"
|
||||
* 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
|
||||
* is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the
|
||||
* USB host.
|
||||
*/
|
||||
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 DescriptorNumber = (wValue & 0xFF);
|
||||
|
||||
void* Address = NULL;
|
||||
uint16_t Size = NO_DESCRIPTOR;
|
||||
|
||||
switch (DescriptorType)
|
||||
{
|
||||
case DTYPE_Device:
|
||||
Address = (void*)&DeviceDescriptor;
|
||||
Size = sizeof(USB_Descriptor_Device_t);
|
||||
break;
|
||||
case DTYPE_Configuration:
|
||||
Address = (void*)&ConfigurationDescriptor;
|
||||
Size = sizeof(USB_Descriptor_Configuration_t);
|
||||
break;
|
||||
case DTYPE_String:
|
||||
switch (DescriptorNumber)
|
||||
{
|
||||
case 0x00:
|
||||
Address = (void*)&LanguageString;
|
||||
Size = pgm_read_byte(&LanguageString.Header.Size);
|
||||
break;
|
||||
case 0x01:
|
||||
Address = (void*)&ManufacturerString;
|
||||
Size = pgm_read_byte(&ManufacturerString.Header.Size);
|
||||
break;
|
||||
case 0x02:
|
||||
Address = (void*)&ProductString;
|
||||
Size = pgm_read_byte(&ProductString.Header.Size);
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
case DTYPE_HID:
|
||||
Address = (void*)&ConfigurationDescriptor.HID_GenericHID;
|
||||
Size = sizeof(USB_HID_Descriptor_t);
|
||||
break;
|
||||
case DTYPE_Report:
|
||||
Address = (void*)&GenericReport;
|
||||
Size = sizeof(GenericReport);
|
||||
break;
|
||||
}
|
||||
|
||||
*DescriptorAddress = Address;
|
||||
return Size;
|
||||
}
|
||||
|
@ -1,72 +1,72 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Header file for Descriptors.c.
|
||||
*/
|
||||
|
||||
#ifndef _DESCRIPTORS_H_
|
||||
#define _DESCRIPTORS_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/pgmspace.h>
|
||||
|
||||
#include <LUFA/Drivers/USB/USB.h>
|
||||
#include <LUFA/Drivers/USB/Class/HID.h>
|
||||
|
||||
/* Type Defines: */
|
||||
/** 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
|
||||
* vary between devices, and which describe the device's usage to the host.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
USB_Descriptor_Configuration_Header_t Config;
|
||||
USB_Descriptor_Interface_t HID_Interface;
|
||||
USB_HID_Descriptor_t HID_GenericHID;
|
||||
USB_Descriptor_Endpoint_t HID_ReportINEndpoint;
|
||||
} USB_Descriptor_Configuration_t;
|
||||
|
||||
/* Macros: */
|
||||
/** Endpoint number of the Generic HID reporting IN endpoint. */
|
||||
#define GENERIC_IN_EPNUM 1
|
||||
|
||||
/** Size in bytes of the Generic HID reporting endpoint. */
|
||||
#define GENERIC_EPSIZE 8
|
||||
|
||||
/** Size in bytes of the Generic HID reports (including report ID byte). */
|
||||
#define GENERIC_REPORT_SIZE 8
|
||||
|
||||
/* Function Prototypes: */
|
||||
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);
|
||||
|
||||
#endif
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Header file for Descriptors.c.
|
||||
*/
|
||||
|
||||
#ifndef _DESCRIPTORS_H_
|
||||
#define _DESCRIPTORS_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/pgmspace.h>
|
||||
|
||||
#include <LUFA/Drivers/USB/USB.h>
|
||||
#include <LUFA/Drivers/USB/Class/HID.h>
|
||||
|
||||
/* Type Defines: */
|
||||
/** 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
|
||||
* vary between devices, and which describe the device's usage to the host.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
USB_Descriptor_Configuration_Header_t Config;
|
||||
USB_Descriptor_Interface_t HID_Interface;
|
||||
USB_HID_Descriptor_t HID_GenericHID;
|
||||
USB_Descriptor_Endpoint_t HID_ReportINEndpoint;
|
||||
} USB_Descriptor_Configuration_t;
|
||||
|
||||
/* Macros: */
|
||||
/** Endpoint number of the Generic HID reporting IN endpoint. */
|
||||
#define GENERIC_IN_EPNUM 1
|
||||
|
||||
/** Size in bytes of the Generic HID reporting endpoint. */
|
||||
#define GENERIC_EPSIZE 8
|
||||
|
||||
/** Size in bytes of the Generic HID reports (including report ID byte). */
|
||||
#define GENERIC_REPORT_SIZE 8
|
||||
|
||||
/* Function Prototypes: */
|
||||
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);
|
||||
|
||||
#endif
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,171 +1,171 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Main source file for the GenericHID demo. This file contains the main tasks of
|
||||
* the demo and is responsible for the initial application hardware configuration.
|
||||
*/
|
||||
|
||||
#include "GenericHID.h"
|
||||
|
||||
/** Buffer to hold the previously generated HID report, for comparison purposes inside the HID class driver. */
|
||||
uint8_t PrevHIDReportBuffer[GENERIC_REPORT_SIZE];
|
||||
|
||||
/** Structure to contain reports from the host, so that they can be echoed back upon request */
|
||||
struct
|
||||
{
|
||||
uint8_t ReportID;
|
||||
uint16_t ReportSize;
|
||||
uint8_t ReportData[GENERIC_REPORT_SIZE];
|
||||
} HIDReportEcho;
|
||||
|
||||
/** LUFA HID Class driver interface configuration and state information. This structure is
|
||||
* passed to all HID Class driver functions, so that multiple instances of the same class
|
||||
* within a device can be differentiated from one another.
|
||||
*/
|
||||
USB_ClassInfo_HID_Device_t Generic_HID_Interface =
|
||||
{
|
||||
.Config =
|
||||
{
|
||||
.InterfaceNumber = 0,
|
||||
|
||||
.ReportINEndpointNumber = GENERIC_IN_EPNUM,
|
||||
.ReportINEndpointSize = GENERIC_EPSIZE,
|
||||
.ReportINEndpointDoubleBank = false,
|
||||
|
||||
.PrevReportINBuffer = PrevHIDReportBuffer,
|
||||
.PrevReportINBufferSize = sizeof(PrevHIDReportBuffer),
|
||||
},
|
||||
};
|
||||
|
||||
/** Main program entry point. This routine contains the overall program flow, including initial
|
||||
* setup of all components and the main program loop.
|
||||
*/
|
||||
int main(void)
|
||||
{
|
||||
SetupHardware();
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
|
||||
sei();
|
||||
|
||||
for (;;)
|
||||
{
|
||||
HID_Device_USBTask(&Generic_HID_Interface);
|
||||
USB_USBTask();
|
||||
}
|
||||
}
|
||||
|
||||
/** Configures the board hardware and chip peripherals for the demo's functionality. */
|
||||
void SetupHardware(void)
|
||||
{
|
||||
/* Disable watchdog if enabled by bootloader/fuses */
|
||||
MCUSR &= ~(1 << WDRF);
|
||||
wdt_disable();
|
||||
|
||||
/* Disable clock division */
|
||||
clock_prescale_set(clock_div_1);
|
||||
|
||||
/* Hardware Initialization */
|
||||
LEDs_Init();
|
||||
USB_Init();
|
||||
}
|
||||
|
||||
/** Event handler for the library USB Connection event. */
|
||||
void EVENT_USB_Device_Connect(void)
|
||||
{
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
|
||||
}
|
||||
|
||||
/** Event handler for the library USB Disconnection event. */
|
||||
void EVENT_USB_Device_Disconnect(void)
|
||||
{
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
|
||||
}
|
||||
|
||||
/** Event handler for the library USB Configuration Changed event. */
|
||||
void EVENT_USB_Device_ConfigurationChanged(void)
|
||||
{
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
|
||||
if (!(HID_Device_ConfigureEndpoints(&Generic_HID_Interface)))
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
USB_Device_EnableSOFEvents();
|
||||
}
|
||||
|
||||
/** Event handler for the library USB Unhandled Control Request event. */
|
||||
void EVENT_USB_Device_UnhandledControlRequest(void)
|
||||
{
|
||||
HID_Device_ProcessControlRequest(&Generic_HID_Interface);
|
||||
}
|
||||
|
||||
/** Event handler for the USB device Start Of Frame event. */
|
||||
void EVENT_USB_Device_StartOfFrame(void)
|
||||
{
|
||||
HID_Device_MillisecondElapsed(&Generic_HID_Interface);
|
||||
}
|
||||
|
||||
/** 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,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[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
|
||||
*
|
||||
* \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,
|
||||
const uint8_t ReportType, void* ReportData, uint16_t* ReportSize)
|
||||
{
|
||||
if (HIDReportEcho.ReportID)
|
||||
*ReportID = HIDReportEcho.ReportID;
|
||||
|
||||
memcpy(ReportData, HIDReportEcho.ReportData, HIDReportEcho.ReportSize);
|
||||
|
||||
*ReportSize = HIDReportEcho.ReportSize;
|
||||
return true;
|
||||
}
|
||||
|
||||
/** 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] 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] 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,
|
||||
const void* ReportData, const uint16_t ReportSize)
|
||||
{
|
||||
HIDReportEcho.ReportID = ReportID;
|
||||
HIDReportEcho.ReportSize = ReportSize;
|
||||
memcpy(HIDReportEcho.ReportData, ReportData, ReportSize);
|
||||
}
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Main source file for the GenericHID demo. This file contains the main tasks of
|
||||
* the demo and is responsible for the initial application hardware configuration.
|
||||
*/
|
||||
|
||||
#include "GenericHID.h"
|
||||
|
||||
/** Buffer to hold the previously generated HID report, for comparison purposes inside the HID class driver. */
|
||||
uint8_t PrevHIDReportBuffer[GENERIC_REPORT_SIZE];
|
||||
|
||||
/** Structure to contain reports from the host, so that they can be echoed back upon request */
|
||||
struct
|
||||
{
|
||||
uint8_t ReportID;
|
||||
uint16_t ReportSize;
|
||||
uint8_t ReportData[GENERIC_REPORT_SIZE];
|
||||
} HIDReportEcho;
|
||||
|
||||
/** LUFA HID Class driver interface configuration and state information. This structure is
|
||||
* passed to all HID Class driver functions, so that multiple instances of the same class
|
||||
* within a device can be differentiated from one another.
|
||||
*/
|
||||
USB_ClassInfo_HID_Device_t Generic_HID_Interface =
|
||||
{
|
||||
.Config =
|
||||
{
|
||||
.InterfaceNumber = 0,
|
||||
|
||||
.ReportINEndpointNumber = GENERIC_IN_EPNUM,
|
||||
.ReportINEndpointSize = GENERIC_EPSIZE,
|
||||
.ReportINEndpointDoubleBank = false,
|
||||
|
||||
.PrevReportINBuffer = PrevHIDReportBuffer,
|
||||
.PrevReportINBufferSize = sizeof(PrevHIDReportBuffer),
|
||||
},
|
||||
};
|
||||
|
||||
/** Main program entry point. This routine contains the overall program flow, including initial
|
||||
* setup of all components and the main program loop.
|
||||
*/
|
||||
int main(void)
|
||||
{
|
||||
SetupHardware();
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
|
||||
sei();
|
||||
|
||||
for (;;)
|
||||
{
|
||||
HID_Device_USBTask(&Generic_HID_Interface);
|
||||
USB_USBTask();
|
||||
}
|
||||
}
|
||||
|
||||
/** Configures the board hardware and chip peripherals for the demo's functionality. */
|
||||
void SetupHardware(void)
|
||||
{
|
||||
/* Disable watchdog if enabled by bootloader/fuses */
|
||||
MCUSR &= ~(1 << WDRF);
|
||||
wdt_disable();
|
||||
|
||||
/* Disable clock division */
|
||||
clock_prescale_set(clock_div_1);
|
||||
|
||||
/* Hardware Initialization */
|
||||
LEDs_Init();
|
||||
USB_Init();
|
||||
}
|
||||
|
||||
/** Event handler for the library USB Connection event. */
|
||||
void EVENT_USB_Device_Connect(void)
|
||||
{
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
|
||||
}
|
||||
|
||||
/** Event handler for the library USB Disconnection event. */
|
||||
void EVENT_USB_Device_Disconnect(void)
|
||||
{
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
|
||||
}
|
||||
|
||||
/** Event handler for the library USB Configuration Changed event. */
|
||||
void EVENT_USB_Device_ConfigurationChanged(void)
|
||||
{
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
|
||||
if (!(HID_Device_ConfigureEndpoints(&Generic_HID_Interface)))
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
USB_Device_EnableSOFEvents();
|
||||
}
|
||||
|
||||
/** Event handler for the library USB Unhandled Control Request event. */
|
||||
void EVENT_USB_Device_UnhandledControlRequest(void)
|
||||
{
|
||||
HID_Device_ProcessControlRequest(&Generic_HID_Interface);
|
||||
}
|
||||
|
||||
/** Event handler for the USB device Start Of Frame event. */
|
||||
void EVENT_USB_Device_StartOfFrame(void)
|
||||
{
|
||||
HID_Device_MillisecondElapsed(&Generic_HID_Interface);
|
||||
}
|
||||
|
||||
/** 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,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[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
|
||||
*
|
||||
* \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,
|
||||
const uint8_t ReportType, void* ReportData, uint16_t* ReportSize)
|
||||
{
|
||||
if (HIDReportEcho.ReportID)
|
||||
*ReportID = HIDReportEcho.ReportID;
|
||||
|
||||
memcpy(ReportData, HIDReportEcho.ReportData, HIDReportEcho.ReportSize);
|
||||
|
||||
*ReportSize = HIDReportEcho.ReportSize;
|
||||
return true;
|
||||
}
|
||||
|
||||
/** 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] 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] 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,
|
||||
const void* ReportData, const uint16_t ReportSize)
|
||||
{
|
||||
HIDReportEcho.ReportID = ReportID;
|
||||
HIDReportEcho.ReportSize = ReportSize;
|
||||
memcpy(HIDReportEcho.ReportData, ReportData, ReportSize);
|
||||
}
|
||||
|
@ -1,80 +1,80 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Header file for GenericHID.c.
|
||||
*/
|
||||
|
||||
#ifndef _GENERICHID_H_
|
||||
#define _GENERICHID_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/io.h>
|
||||
#include <avr/wdt.h>
|
||||
#include <avr/power.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "Descriptors.h"
|
||||
|
||||
#include <LUFA/Version.h>
|
||||
#include <LUFA/Drivers/Board/LEDs.h>
|
||||
#include <LUFA/Drivers/USB/USB.h>
|
||||
#include <LUFA/Drivers/USB/Class/HID.h>
|
||||
|
||||
/* Macros: */
|
||||
/** LED mask for the library LED driver, to indicate that the USB interface is not ready. */
|
||||
#define LEDMASK_USB_NOTREADY LEDS_LED1
|
||||
|
||||
/** LED mask for the library LED driver, to indicate that the USB interface is enumerating. */
|
||||
#define LEDMASK_USB_ENUMERATING (LEDS_LED2 | LEDS_LED3)
|
||||
|
||||
/** LED mask for the library LED driver, to indicate that the USB interface is ready. */
|
||||
#define LEDMASK_USB_READY (LEDS_LED2 | LEDS_LED4)
|
||||
|
||||
/** LED mask for the library LED driver, to indicate that an error has occurred in the USB interface. */
|
||||
#define LEDMASK_USB_ERROR (LEDS_LED1 | LEDS_LED3)
|
||||
|
||||
/* Function Prototypes: */
|
||||
void SetupHardware(void);
|
||||
|
||||
void EVENT_USB_Device_Connect(void);
|
||||
void EVENT_USB_Device_Disconnect(void);
|
||||
void EVENT_USB_Device_ConfigurationChanged(void);
|
||||
void EVENT_USB_Device_UnhandledControlRequest(void);
|
||||
void EVENT_USB_Device_StartOfFrame(void);
|
||||
|
||||
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);
|
||||
void CALLBACK_HID_Device_ProcessHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, const uint8_t ReportID,
|
||||
const void* ReportData, const uint16_t ReportSize);
|
||||
|
||||
#endif
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Header file for GenericHID.c.
|
||||
*/
|
||||
|
||||
#ifndef _GENERICHID_H_
|
||||
#define _GENERICHID_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/io.h>
|
||||
#include <avr/wdt.h>
|
||||
#include <avr/power.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "Descriptors.h"
|
||||
|
||||
#include <LUFA/Version.h>
|
||||
#include <LUFA/Drivers/Board/LEDs.h>
|
||||
#include <LUFA/Drivers/USB/USB.h>
|
||||
#include <LUFA/Drivers/USB/Class/HID.h>
|
||||
|
||||
/* Macros: */
|
||||
/** LED mask for the library LED driver, to indicate that the USB interface is not ready. */
|
||||
#define LEDMASK_USB_NOTREADY LEDS_LED1
|
||||
|
||||
/** LED mask for the library LED driver, to indicate that the USB interface is enumerating. */
|
||||
#define LEDMASK_USB_ENUMERATING (LEDS_LED2 | LEDS_LED3)
|
||||
|
||||
/** LED mask for the library LED driver, to indicate that the USB interface is ready. */
|
||||
#define LEDMASK_USB_READY (LEDS_LED2 | LEDS_LED4)
|
||||
|
||||
/** LED mask for the library LED driver, to indicate that an error has occurred in the USB interface. */
|
||||
#define LEDMASK_USB_ERROR (LEDS_LED1 | LEDS_LED3)
|
||||
|
||||
/* Function Prototypes: */
|
||||
void SetupHardware(void);
|
||||
|
||||
void EVENT_USB_Device_Connect(void);
|
||||
void EVENT_USB_Device_Disconnect(void);
|
||||
void EVENT_USB_Device_ConfigurationChanged(void);
|
||||
void EVENT_USB_Device_UnhandledControlRequest(void);
|
||||
void EVENT_USB_Device_StartOfFrame(void);
|
||||
|
||||
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);
|
||||
void CALLBACK_HID_Device_ProcessHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, const uint8_t ReportID,
|
||||
const void* ReportData, const uint16_t ReportSize);
|
||||
|
||||
#endif
|
||||
|
@ -1,75 +1,75 @@
|
||||
/** \file
|
||||
*
|
||||
* This file contains special DoxyGen information for the generation of the main page and other special
|
||||
* documentation pages. It is not a project source file.
|
||||
*/
|
||||
|
||||
/** \mainpage Generic HID Device
|
||||
*
|
||||
* \section SSec_Compat Demo Compatibility:
|
||||
*
|
||||
* The following list indicates what microcontrollers are compatible with this demo.
|
||||
*
|
||||
* - Series 7 USB AVRs
|
||||
* - Series 6 USB AVRs
|
||||
* - Series 4 USB AVRs
|
||||
* - Series 2 USB AVRs
|
||||
*
|
||||
* \section SSec_Info USB Information:
|
||||
*
|
||||
* The following table gives a rundown of the USB utilization of this demo.
|
||||
*
|
||||
* <table>
|
||||
* <tr>
|
||||
* <td><b>USB Mode:</b></td>
|
||||
* <td>Device</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>USB Class:</b></td>
|
||||
* <td>Human Interface Device (HID)</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>USB Subclass:</b></td>
|
||||
* <td>N/A</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>Relevant Standards:</b></td>
|
||||
* <td>USBIF HID Specification \n
|
||||
* USBIF HID Usage Tables</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>Usable Speeds:</b></td>
|
||||
* <td>Low Speed Mode \n
|
||||
* Full Speed Mode</td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*
|
||||
* \section SSec_Description Project Description:
|
||||
*
|
||||
* 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
|
||||
* 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.
|
||||
*
|
||||
* 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
|
||||
* both the standard data endpoint and control request methods defined in the HID specification.
|
||||
*
|
||||
* \section SSec_Options Project Options
|
||||
*
|
||||
* The following defines can be found in this demo, which can control the demo behaviour when defined, or changed in value.
|
||||
*
|
||||
* <table>
|
||||
* <tr>
|
||||
* <td><b>Define Name:</b></td>
|
||||
* <td><b>Location:</b></td>
|
||||
* <td><b>Description:</b></td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>GENERIC_REPORT_SIZE</td>
|
||||
* <td>Descriptors.h</td>
|
||||
* <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>
|
||||
* </tr>
|
||||
* </table>
|
||||
*/
|
||||
/** \file
|
||||
*
|
||||
* This file contains special DoxyGen information for the generation of the main page and other special
|
||||
* documentation pages. It is not a project source file.
|
||||
*/
|
||||
|
||||
/** \mainpage Generic HID Device
|
||||
*
|
||||
* \section SSec_Compat Demo Compatibility:
|
||||
*
|
||||
* The following list indicates what microcontrollers are compatible with this demo.
|
||||
*
|
||||
* - Series 7 USB AVRs
|
||||
* - Series 6 USB AVRs
|
||||
* - Series 4 USB AVRs
|
||||
* - Series 2 USB AVRs
|
||||
*
|
||||
* \section SSec_Info USB Information:
|
||||
*
|
||||
* The following table gives a rundown of the USB utilization of this demo.
|
||||
*
|
||||
* <table>
|
||||
* <tr>
|
||||
* <td><b>USB Mode:</b></td>
|
||||
* <td>Device</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>USB Class:</b></td>
|
||||
* <td>Human Interface Device (HID)</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>USB Subclass:</b></td>
|
||||
* <td>N/A</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>Relevant Standards:</b></td>
|
||||
* <td>USBIF HID Specification \n
|
||||
* USBIF HID Usage Tables</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>Usable Speeds:</b></td>
|
||||
* <td>Low Speed Mode \n
|
||||
* Full Speed Mode</td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*
|
||||
* \section SSec_Description Project Description:
|
||||
*
|
||||
* 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
|
||||
* 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.
|
||||
*
|
||||
* 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
|
||||
* both the standard data endpoint and control request methods defined in the HID specification.
|
||||
*
|
||||
* \section SSec_Options Project Options
|
||||
*
|
||||
* The following defines can be found in this demo, which can control the demo behaviour when defined, or changed in value.
|
||||
*
|
||||
* <table>
|
||||
* <tr>
|
||||
* <td><b>Define Name:</b></td>
|
||||
* <td><b>Location:</b></td>
|
||||
* <td><b>Description:</b></td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>GENERIC_REPORT_SIZE</td>
|
||||
* <td>Descriptors.h</td>
|
||||
* <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>
|
||||
* </tr>
|
||||
* </table>
|
||||
*/
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,250 +1,250 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* 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
|
||||
* the device's capabilities and functions.
|
||||
*/
|
||||
|
||||
#include "Descriptors.h"
|
||||
|
||||
/** 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
|
||||
* 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
|
||||
* more details on HID report descriptors.
|
||||
*/
|
||||
USB_Descriptor_HIDReport_Datatype_t PROGMEM JoystickReport[] =
|
||||
{
|
||||
0x05, 0x01, /* Usage Page (Generic Desktop) */
|
||||
0x09, 0x04, /* Usage (Joystick) */
|
||||
0xa1, 0x01, /* Collection (Application) */
|
||||
0x09, 0x01, /* Usage (Pointer) */
|
||||
0xa1, 0x00, /* Collection (Physical) */
|
||||
0x05, 0x01, /* Usage Page (Generic Desktop) */
|
||||
0x09, 0x30, /* Usage (X) */
|
||||
0x09, 0x31, /* Usage (Y) */
|
||||
0x15, 0x9c, /* Logical Minimum (-100) */
|
||||
0x25, 0x64, /* Logical Maximum (100) */
|
||||
0x75, 0x08, /* Report Size (8) */
|
||||
0x95, 0x02, /* Report Count (2) */
|
||||
0x81, 0x82, /* Input (Data, Variable, Absolute, Volatile) */
|
||||
0xc0, /* End Collection */
|
||||
0x05, 0x09, /* Usage Page (Button) */
|
||||
0x09, 0x02, /* Usage (Button 2) */
|
||||
0x09, 0x01, /* Usage (Button 1) */
|
||||
0x15, 0x00, /* Logical Minimum (0) */
|
||||
0x25, 0x01, /* Logical Maximum (1) */
|
||||
0x75, 0x01, /* Report Size (1) */
|
||||
0x95, 0x02, /* Report Count (2) */
|
||||
0x81, 0x02, /* Input (Data, Variable, Absolute) */
|
||||
0x75, 0x06, /* Report Size (6) */
|
||||
0x95, 0x01, /* Report Count (1) */
|
||||
0x81, 0x01, /* Input (Constant) */
|
||||
0xc0 /* End Collection */
|
||||
};
|
||||
|
||||
/** Device descriptor structure. This descriptor, located in FLASH memory, describes the overall
|
||||
* 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
|
||||
* process begins.
|
||||
*/
|
||||
USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device},
|
||||
|
||||
.USBSpecification = VERSION_BCD(01.10),
|
||||
.Class = 0x00,
|
||||
.SubClass = 0x00,
|
||||
.Protocol = 0x00,
|
||||
|
||||
.Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE,
|
||||
|
||||
.VendorID = 0x03EB,
|
||||
.ProductID = 0x2043,
|
||||
.ReleaseNumber = 0x0000,
|
||||
|
||||
.ManufacturerStrIndex = 0x01,
|
||||
.ProductStrIndex = 0x02,
|
||||
.SerialNumStrIndex = NO_DESCRIPTOR,
|
||||
|
||||
.NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS
|
||||
};
|
||||
|
||||
/** 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
|
||||
* 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.
|
||||
*/
|
||||
USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
|
||||
{
|
||||
.Config =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration},
|
||||
|
||||
.TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t),
|
||||
.TotalInterfaces = 1,
|
||||
|
||||
.ConfigurationNumber = 1,
|
||||
.ConfigurationStrIndex = NO_DESCRIPTOR,
|
||||
|
||||
.ConfigAttributes = (USB_CONFIG_ATTR_BUSPOWERED | USB_CONFIG_ATTR_SELFPOWERED),
|
||||
|
||||
.MaxPowerConsumption = USB_CONFIG_POWER_MA(100)
|
||||
},
|
||||
|
||||
.HID_Interface =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
|
||||
|
||||
.InterfaceNumber = 0x00,
|
||||
.AlternateSetting = 0x00,
|
||||
|
||||
.TotalEndpoints = 1,
|
||||
|
||||
.Class = 0x03,
|
||||
.SubClass = 0x00,
|
||||
.Protocol = HID_NON_BOOT_PROTOCOL,
|
||||
|
||||
.InterfaceStrIndex = NO_DESCRIPTOR
|
||||
},
|
||||
|
||||
.HID_JoystickHID =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_HID_Descriptor_t), .Type = DTYPE_HID},
|
||||
|
||||
.HIDSpec = VERSION_BCD(01.11),
|
||||
.CountryCode = 0x00,
|
||||
.TotalReportDescriptors = 1,
|
||||
.HIDReportType = DTYPE_Report,
|
||||
.HIDReportLength = sizeof(JoystickReport)
|
||||
},
|
||||
|
||||
.HID_ReportINEndpoint =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
|
||||
|
||||
.EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_IN | JOYSTICK_EPNUM),
|
||||
.Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
|
||||
.EndpointSize = JOYSTICK_EPSIZE,
|
||||
.PollingIntervalMS = 0x0A
|
||||
}
|
||||
};
|
||||
|
||||
/** 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
|
||||
* via the language ID table available at USB.org what languages the device supports for its string descriptors.
|
||||
*/
|
||||
USB_Descriptor_String_t PROGMEM LanguageString =
|
||||
{
|
||||
.Header = {.Size = USB_STRING_LEN(1), .Type = DTYPE_String},
|
||||
|
||||
.UnicodeString = {LANGUAGE_ID_ENG}
|
||||
};
|
||||
|
||||
/** 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
|
||||
* Descriptor.
|
||||
*/
|
||||
USB_Descriptor_String_t PROGMEM ManufacturerString =
|
||||
{
|
||||
.Header = {.Size = USB_STRING_LEN(11), .Type = DTYPE_String},
|
||||
|
||||
.UnicodeString = L"Dean Camera"
|
||||
};
|
||||
|
||||
/** 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
|
||||
* Descriptor.
|
||||
*/
|
||||
USB_Descriptor_String_t PROGMEM ProductString =
|
||||
{
|
||||
.Header = {.Size = USB_STRING_LEN(18), .Type = DTYPE_String},
|
||||
|
||||
.UnicodeString = L"LUFA Joystick Demo"
|
||||
};
|
||||
|
||||
/** 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
|
||||
* 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
|
||||
* USB host.
|
||||
*/
|
||||
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 DescriptorNumber = (wValue & 0xFF);
|
||||
|
||||
void* Address = NULL;
|
||||
uint16_t Size = NO_DESCRIPTOR;
|
||||
|
||||
switch (DescriptorType)
|
||||
{
|
||||
case DTYPE_Device:
|
||||
Address = (void*)&DeviceDescriptor;
|
||||
Size = sizeof(USB_Descriptor_Device_t);
|
||||
break;
|
||||
case DTYPE_Configuration:
|
||||
Address = (void*)&ConfigurationDescriptor;
|
||||
Size = sizeof(USB_Descriptor_Configuration_t);
|
||||
break;
|
||||
case DTYPE_String:
|
||||
switch (DescriptorNumber)
|
||||
{
|
||||
case 0x00:
|
||||
Address = (void*)&LanguageString;
|
||||
Size = pgm_read_byte(&LanguageString.Header.Size);
|
||||
break;
|
||||
case 0x01:
|
||||
Address = (void*)&ManufacturerString;
|
||||
Size = pgm_read_byte(&ManufacturerString.Header.Size);
|
||||
break;
|
||||
case 0x02:
|
||||
Address = (void*)&ProductString;
|
||||
Size = pgm_read_byte(&ProductString.Header.Size);
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
case DTYPE_HID:
|
||||
Address = (void*)&ConfigurationDescriptor.HID_JoystickHID;
|
||||
Size = sizeof(USB_HID_Descriptor_t);
|
||||
break;
|
||||
case DTYPE_Report:
|
||||
Address = (void*)&JoystickReport;
|
||||
Size = sizeof(JoystickReport);
|
||||
break;
|
||||
}
|
||||
|
||||
*DescriptorAddress = Address;
|
||||
return Size;
|
||||
}
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* 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
|
||||
* the device's capabilities and functions.
|
||||
*/
|
||||
|
||||
#include "Descriptors.h"
|
||||
|
||||
/** 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
|
||||
* 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
|
||||
* more details on HID report descriptors.
|
||||
*/
|
||||
USB_Descriptor_HIDReport_Datatype_t PROGMEM JoystickReport[] =
|
||||
{
|
||||
0x05, 0x01, /* Usage Page (Generic Desktop) */
|
||||
0x09, 0x04, /* Usage (Joystick) */
|
||||
0xa1, 0x01, /* Collection (Application) */
|
||||
0x09, 0x01, /* Usage (Pointer) */
|
||||
0xa1, 0x00, /* Collection (Physical) */
|
||||
0x05, 0x01, /* Usage Page (Generic Desktop) */
|
||||
0x09, 0x30, /* Usage (X) */
|
||||
0x09, 0x31, /* Usage (Y) */
|
||||
0x15, 0x9c, /* Logical Minimum (-100) */
|
||||
0x25, 0x64, /* Logical Maximum (100) */
|
||||
0x75, 0x08, /* Report Size (8) */
|
||||
0x95, 0x02, /* Report Count (2) */
|
||||
0x81, 0x82, /* Input (Data, Variable, Absolute, Volatile) */
|
||||
0xc0, /* End Collection */
|
||||
0x05, 0x09, /* Usage Page (Button) */
|
||||
0x09, 0x02, /* Usage (Button 2) */
|
||||
0x09, 0x01, /* Usage (Button 1) */
|
||||
0x15, 0x00, /* Logical Minimum (0) */
|
||||
0x25, 0x01, /* Logical Maximum (1) */
|
||||
0x75, 0x01, /* Report Size (1) */
|
||||
0x95, 0x02, /* Report Count (2) */
|
||||
0x81, 0x02, /* Input (Data, Variable, Absolute) */
|
||||
0x75, 0x06, /* Report Size (6) */
|
||||
0x95, 0x01, /* Report Count (1) */
|
||||
0x81, 0x01, /* Input (Constant) */
|
||||
0xc0 /* End Collection */
|
||||
};
|
||||
|
||||
/** Device descriptor structure. This descriptor, located in FLASH memory, describes the overall
|
||||
* 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
|
||||
* process begins.
|
||||
*/
|
||||
USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device},
|
||||
|
||||
.USBSpecification = VERSION_BCD(01.10),
|
||||
.Class = 0x00,
|
||||
.SubClass = 0x00,
|
||||
.Protocol = 0x00,
|
||||
|
||||
.Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE,
|
||||
|
||||
.VendorID = 0x03EB,
|
||||
.ProductID = 0x2043,
|
||||
.ReleaseNumber = 0x0000,
|
||||
|
||||
.ManufacturerStrIndex = 0x01,
|
||||
.ProductStrIndex = 0x02,
|
||||
.SerialNumStrIndex = NO_DESCRIPTOR,
|
||||
|
||||
.NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS
|
||||
};
|
||||
|
||||
/** 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
|
||||
* 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.
|
||||
*/
|
||||
USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
|
||||
{
|
||||
.Config =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration},
|
||||
|
||||
.TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t),
|
||||
.TotalInterfaces = 1,
|
||||
|
||||
.ConfigurationNumber = 1,
|
||||
.ConfigurationStrIndex = NO_DESCRIPTOR,
|
||||
|
||||
.ConfigAttributes = (USB_CONFIG_ATTR_BUSPOWERED | USB_CONFIG_ATTR_SELFPOWERED),
|
||||
|
||||
.MaxPowerConsumption = USB_CONFIG_POWER_MA(100)
|
||||
},
|
||||
|
||||
.HID_Interface =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
|
||||
|
||||
.InterfaceNumber = 0x00,
|
||||
.AlternateSetting = 0x00,
|
||||
|
||||
.TotalEndpoints = 1,
|
||||
|
||||
.Class = 0x03,
|
||||
.SubClass = 0x00,
|
||||
.Protocol = HID_NON_BOOT_PROTOCOL,
|
||||
|
||||
.InterfaceStrIndex = NO_DESCRIPTOR
|
||||
},
|
||||
|
||||
.HID_JoystickHID =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_HID_Descriptor_t), .Type = DTYPE_HID},
|
||||
|
||||
.HIDSpec = VERSION_BCD(01.11),
|
||||
.CountryCode = 0x00,
|
||||
.TotalReportDescriptors = 1,
|
||||
.HIDReportType = DTYPE_Report,
|
||||
.HIDReportLength = sizeof(JoystickReport)
|
||||
},
|
||||
|
||||
.HID_ReportINEndpoint =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
|
||||
|
||||
.EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_IN | JOYSTICK_EPNUM),
|
||||
.Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
|
||||
.EndpointSize = JOYSTICK_EPSIZE,
|
||||
.PollingIntervalMS = 0x0A
|
||||
}
|
||||
};
|
||||
|
||||
/** 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
|
||||
* via the language ID table available at USB.org what languages the device supports for its string descriptors.
|
||||
*/
|
||||
USB_Descriptor_String_t PROGMEM LanguageString =
|
||||
{
|
||||
.Header = {.Size = USB_STRING_LEN(1), .Type = DTYPE_String},
|
||||
|
||||
.UnicodeString = {LANGUAGE_ID_ENG}
|
||||
};
|
||||
|
||||
/** 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
|
||||
* Descriptor.
|
||||
*/
|
||||
USB_Descriptor_String_t PROGMEM ManufacturerString =
|
||||
{
|
||||
.Header = {.Size = USB_STRING_LEN(11), .Type = DTYPE_String},
|
||||
|
||||
.UnicodeString = L"Dean Camera"
|
||||
};
|
||||
|
||||
/** 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
|
||||
* Descriptor.
|
||||
*/
|
||||
USB_Descriptor_String_t PROGMEM ProductString =
|
||||
{
|
||||
.Header = {.Size = USB_STRING_LEN(18), .Type = DTYPE_String},
|
||||
|
||||
.UnicodeString = L"LUFA Joystick Demo"
|
||||
};
|
||||
|
||||
/** 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
|
||||
* 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
|
||||
* USB host.
|
||||
*/
|
||||
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 DescriptorNumber = (wValue & 0xFF);
|
||||
|
||||
void* Address = NULL;
|
||||
uint16_t Size = NO_DESCRIPTOR;
|
||||
|
||||
switch (DescriptorType)
|
||||
{
|
||||
case DTYPE_Device:
|
||||
Address = (void*)&DeviceDescriptor;
|
||||
Size = sizeof(USB_Descriptor_Device_t);
|
||||
break;
|
||||
case DTYPE_Configuration:
|
||||
Address = (void*)&ConfigurationDescriptor;
|
||||
Size = sizeof(USB_Descriptor_Configuration_t);
|
||||
break;
|
||||
case DTYPE_String:
|
||||
switch (DescriptorNumber)
|
||||
{
|
||||
case 0x00:
|
||||
Address = (void*)&LanguageString;
|
||||
Size = pgm_read_byte(&LanguageString.Header.Size);
|
||||
break;
|
||||
case 0x01:
|
||||
Address = (void*)&ManufacturerString;
|
||||
Size = pgm_read_byte(&ManufacturerString.Header.Size);
|
||||
break;
|
||||
case 0x02:
|
||||
Address = (void*)&ProductString;
|
||||
Size = pgm_read_byte(&ProductString.Header.Size);
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
case DTYPE_HID:
|
||||
Address = (void*)&ConfigurationDescriptor.HID_JoystickHID;
|
||||
Size = sizeof(USB_HID_Descriptor_t);
|
||||
break;
|
||||
case DTYPE_Report:
|
||||
Address = (void*)&JoystickReport;
|
||||
Size = sizeof(JoystickReport);
|
||||
break;
|
||||
}
|
||||
|
||||
*DescriptorAddress = Address;
|
||||
return Size;
|
||||
}
|
||||
|
@ -1,69 +1,69 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Header file for Descriptors.c.
|
||||
*/
|
||||
|
||||
#ifndef _DESCRIPTORS_H_
|
||||
#define _DESCRIPTORS_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/pgmspace.h>
|
||||
|
||||
#include <LUFA/Drivers/USB/USB.h>
|
||||
#include <LUFA/Drivers/USB/Class/HID.h>
|
||||
|
||||
/* Type Defines: */
|
||||
/** 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
|
||||
* vary between devices, and which describe the device's usage to the host.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
USB_Descriptor_Configuration_Header_t Config;
|
||||
USB_Descriptor_Interface_t HID_Interface;
|
||||
USB_HID_Descriptor_t HID_JoystickHID;
|
||||
USB_Descriptor_Endpoint_t HID_ReportINEndpoint;
|
||||
} USB_Descriptor_Configuration_t;
|
||||
|
||||
/* Macros: */
|
||||
/** Endpoint number of the Joystick HID reporting IN endpoint. */
|
||||
#define JOYSTICK_EPNUM 1
|
||||
|
||||
/** Size in bytes of the Joystick HID reporting IN endpoint. */
|
||||
#define JOYSTICK_EPSIZE 8
|
||||
|
||||
/* Function Prototypes: */
|
||||
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);
|
||||
|
||||
#endif
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Header file for Descriptors.c.
|
||||
*/
|
||||
|
||||
#ifndef _DESCRIPTORS_H_
|
||||
#define _DESCRIPTORS_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/pgmspace.h>
|
||||
|
||||
#include <LUFA/Drivers/USB/USB.h>
|
||||
#include <LUFA/Drivers/USB/Class/HID.h>
|
||||
|
||||
/* Type Defines: */
|
||||
/** 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
|
||||
* vary between devices, and which describe the device's usage to the host.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
USB_Descriptor_Configuration_Header_t Config;
|
||||
USB_Descriptor_Interface_t HID_Interface;
|
||||
USB_HID_Descriptor_t HID_JoystickHID;
|
||||
USB_Descriptor_Endpoint_t HID_ReportINEndpoint;
|
||||
} USB_Descriptor_Configuration_t;
|
||||
|
||||
/* Macros: */
|
||||
/** Endpoint number of the Joystick HID reporting IN endpoint. */
|
||||
#define JOYSTICK_EPNUM 1
|
||||
|
||||
/** Size in bytes of the Joystick HID reporting IN endpoint. */
|
||||
#define JOYSTICK_EPSIZE 8
|
||||
|
||||
/* Function Prototypes: */
|
||||
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);
|
||||
|
||||
#endif
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,179 +1,179 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Main source file for the Joystick demo. This file contains the main tasks of
|
||||
* the demo and is responsible for the initial application hardware configuration.
|
||||
*/
|
||||
|
||||
#include "Joystick.h"
|
||||
|
||||
/** Buffer to hold the previously generated HID report, for comparison purposes inside the HID class driver. */
|
||||
uint8_t PrevJoystickHIDReportBuffer[sizeof(USB_JoystickReport_Data_t)];
|
||||
|
||||
/** LUFA HID Class driver interface configuration and state information. This structure is
|
||||
* passed to all HID Class driver functions, so that multiple instances of the same class
|
||||
* within a device can be differentiated from one another.
|
||||
*/
|
||||
USB_ClassInfo_HID_Device_t Joystick_HID_Interface =
|
||||
{
|
||||
.Config =
|
||||
{
|
||||
.InterfaceNumber = 0,
|
||||
|
||||
.ReportINEndpointNumber = JOYSTICK_EPNUM,
|
||||
.ReportINEndpointSize = JOYSTICK_EPSIZE,
|
||||
.ReportINEndpointDoubleBank = false,
|
||||
|
||||
.PrevReportINBuffer = PrevJoystickHIDReportBuffer,
|
||||
.PrevReportINBufferSize = sizeof(PrevJoystickHIDReportBuffer),
|
||||
},
|
||||
};
|
||||
|
||||
/** Main program entry point. This routine contains the overall program flow, including initial
|
||||
* setup of all components and the main program loop.
|
||||
*/
|
||||
int main(void)
|
||||
{
|
||||
SetupHardware();
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
|
||||
sei();
|
||||
|
||||
for (;;)
|
||||
{
|
||||
HID_Device_USBTask(&Joystick_HID_Interface);
|
||||
USB_USBTask();
|
||||
}
|
||||
}
|
||||
|
||||
/** Configures the board hardware and chip peripherals for the demo's functionality. */
|
||||
void SetupHardware(void)
|
||||
{
|
||||
/* Disable watchdog if enabled by bootloader/fuses */
|
||||
MCUSR &= ~(1 << WDRF);
|
||||
wdt_disable();
|
||||
|
||||
/* Disable clock division */
|
||||
clock_prescale_set(clock_div_1);
|
||||
|
||||
/* Hardware Initialization */
|
||||
Joystick_Init();
|
||||
LEDs_Init();
|
||||
Buttons_Init();
|
||||
USB_Init();
|
||||
}
|
||||
|
||||
/** Event handler for the library USB Connection event. */
|
||||
void EVENT_USB_Device_Connect(void)
|
||||
{
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
|
||||
}
|
||||
|
||||
/** Event handler for the library USB Disconnection event. */
|
||||
void EVENT_USB_Device_Disconnect(void)
|
||||
{
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
|
||||
}
|
||||
|
||||
/** Event handler for the library USB Configuration Changed event. */
|
||||
void EVENT_USB_Device_ConfigurationChanged(void)
|
||||
{
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
|
||||
if (!(HID_Device_ConfigureEndpoints(&Joystick_HID_Interface)))
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
USB_Device_EnableSOFEvents();
|
||||
}
|
||||
|
||||
/** Event handler for the library USB Unhandled Control Request event. */
|
||||
void EVENT_USB_Device_UnhandledControlRequest(void)
|
||||
{
|
||||
HID_Device_ProcessControlRequest(&Joystick_HID_Interface);
|
||||
}
|
||||
|
||||
/** Event handler for the USB device Start Of Frame event. */
|
||||
void EVENT_USB_Device_StartOfFrame(void)
|
||||
{
|
||||
HID_Device_MillisecondElapsed(&Joystick_HID_Interface);
|
||||
}
|
||||
|
||||
/** 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,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[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
|
||||
*
|
||||
* \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,
|
||||
const uint8_t ReportType, void* ReportData, uint16_t* ReportSize)
|
||||
{
|
||||
USB_JoystickReport_Data_t* JoystickReport = (USB_JoystickReport_Data_t*)ReportData;
|
||||
|
||||
uint8_t JoyStatus_LCL = Joystick_GetStatus();
|
||||
uint8_t ButtonStatus_LCL = Buttons_GetStatus();
|
||||
|
||||
if (JoyStatus_LCL & JOY_UP)
|
||||
JoystickReport->Y = -100;
|
||||
else if (JoyStatus_LCL & JOY_DOWN)
|
||||
JoystickReport->Y = 100;
|
||||
|
||||
if (JoyStatus_LCL & JOY_LEFT)
|
||||
JoystickReport->X = -100;
|
||||
else if (JoyStatus_LCL & JOY_RIGHT)
|
||||
JoystickReport->X = 100;
|
||||
|
||||
if (JoyStatus_LCL & JOY_PRESS)
|
||||
JoystickReport->Button = (1 << 1);
|
||||
|
||||
if (ButtonStatus_LCL & BUTTONS_BUTTON1)
|
||||
JoystickReport->Button |= (1 << 0);
|
||||
|
||||
*ReportSize = sizeof(USB_JoystickReport_Data_t);
|
||||
return false;
|
||||
}
|
||||
|
||||
/** 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] 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] 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,
|
||||
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
|
||||
}
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Main source file for the Joystick demo. This file contains the main tasks of
|
||||
* the demo and is responsible for the initial application hardware configuration.
|
||||
*/
|
||||
|
||||
#include "Joystick.h"
|
||||
|
||||
/** Buffer to hold the previously generated HID report, for comparison purposes inside the HID class driver. */
|
||||
uint8_t PrevJoystickHIDReportBuffer[sizeof(USB_JoystickReport_Data_t)];
|
||||
|
||||
/** LUFA HID Class driver interface configuration and state information. This structure is
|
||||
* passed to all HID Class driver functions, so that multiple instances of the same class
|
||||
* within a device can be differentiated from one another.
|
||||
*/
|
||||
USB_ClassInfo_HID_Device_t Joystick_HID_Interface =
|
||||
{
|
||||
.Config =
|
||||
{
|
||||
.InterfaceNumber = 0,
|
||||
|
||||
.ReportINEndpointNumber = JOYSTICK_EPNUM,
|
||||
.ReportINEndpointSize = JOYSTICK_EPSIZE,
|
||||
.ReportINEndpointDoubleBank = false,
|
||||
|
||||
.PrevReportINBuffer = PrevJoystickHIDReportBuffer,
|
||||
.PrevReportINBufferSize = sizeof(PrevJoystickHIDReportBuffer),
|
||||
},
|
||||
};
|
||||
|
||||
/** Main program entry point. This routine contains the overall program flow, including initial
|
||||
* setup of all components and the main program loop.
|
||||
*/
|
||||
int main(void)
|
||||
{
|
||||
SetupHardware();
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
|
||||
sei();
|
||||
|
||||
for (;;)
|
||||
{
|
||||
HID_Device_USBTask(&Joystick_HID_Interface);
|
||||
USB_USBTask();
|
||||
}
|
||||
}
|
||||
|
||||
/** Configures the board hardware and chip peripherals for the demo's functionality. */
|
||||
void SetupHardware(void)
|
||||
{
|
||||
/* Disable watchdog if enabled by bootloader/fuses */
|
||||
MCUSR &= ~(1 << WDRF);
|
||||
wdt_disable();
|
||||
|
||||
/* Disable clock division */
|
||||
clock_prescale_set(clock_div_1);
|
||||
|
||||
/* Hardware Initialization */
|
||||
Joystick_Init();
|
||||
LEDs_Init();
|
||||
Buttons_Init();
|
||||
USB_Init();
|
||||
}
|
||||
|
||||
/** Event handler for the library USB Connection event. */
|
||||
void EVENT_USB_Device_Connect(void)
|
||||
{
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
|
||||
}
|
||||
|
||||
/** Event handler for the library USB Disconnection event. */
|
||||
void EVENT_USB_Device_Disconnect(void)
|
||||
{
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
|
||||
}
|
||||
|
||||
/** Event handler for the library USB Configuration Changed event. */
|
||||
void EVENT_USB_Device_ConfigurationChanged(void)
|
||||
{
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
|
||||
if (!(HID_Device_ConfigureEndpoints(&Joystick_HID_Interface)))
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
USB_Device_EnableSOFEvents();
|
||||
}
|
||||
|
||||
/** Event handler for the library USB Unhandled Control Request event. */
|
||||
void EVENT_USB_Device_UnhandledControlRequest(void)
|
||||
{
|
||||
HID_Device_ProcessControlRequest(&Joystick_HID_Interface);
|
||||
}
|
||||
|
||||
/** Event handler for the USB device Start Of Frame event. */
|
||||
void EVENT_USB_Device_StartOfFrame(void)
|
||||
{
|
||||
HID_Device_MillisecondElapsed(&Joystick_HID_Interface);
|
||||
}
|
||||
|
||||
/** 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,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[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
|
||||
*
|
||||
* \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,
|
||||
const uint8_t ReportType, void* ReportData, uint16_t* ReportSize)
|
||||
{
|
||||
USB_JoystickReport_Data_t* JoystickReport = (USB_JoystickReport_Data_t*)ReportData;
|
||||
|
||||
uint8_t JoyStatus_LCL = Joystick_GetStatus();
|
||||
uint8_t ButtonStatus_LCL = Buttons_GetStatus();
|
||||
|
||||
if (JoyStatus_LCL & JOY_UP)
|
||||
JoystickReport->Y = -100;
|
||||
else if (JoyStatus_LCL & JOY_DOWN)
|
||||
JoystickReport->Y = 100;
|
||||
|
||||
if (JoyStatus_LCL & JOY_LEFT)
|
||||
JoystickReport->X = -100;
|
||||
else if (JoyStatus_LCL & JOY_RIGHT)
|
||||
JoystickReport->X = 100;
|
||||
|
||||
if (JoyStatus_LCL & JOY_PRESS)
|
||||
JoystickReport->Button = (1 << 1);
|
||||
|
||||
if (ButtonStatus_LCL & BUTTONS_BUTTON1)
|
||||
JoystickReport->Button |= (1 << 0);
|
||||
|
||||
*ReportSize = sizeof(USB_JoystickReport_Data_t);
|
||||
return false;
|
||||
}
|
||||
|
||||
/** 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] 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] 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,
|
||||
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
|
||||
}
|
||||
|
@ -1,93 +1,93 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Header file for Joystick.c.
|
||||
*/
|
||||
|
||||
#ifndef _JOYSTICK_H_
|
||||
#define _JOYSTICK_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/io.h>
|
||||
#include <avr/wdt.h>
|
||||
#include <avr/power.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "Descriptors.h"
|
||||
|
||||
#include <LUFA/Version.h>
|
||||
#include <LUFA/Drivers/Board/Joystick.h>
|
||||
#include <LUFA/Drivers/Board/LEDs.h>
|
||||
#include <LUFA/Drivers/Board/Buttons.h>
|
||||
#include <LUFA/Drivers/USB/USB.h>
|
||||
#include <LUFA/Drivers/USB/Class/HID.h>
|
||||
|
||||
/* Type Defines: */
|
||||
/** 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.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
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 */
|
||||
uint8_t Button; /**< Bit mask of the currently pressed joystick buttons */
|
||||
} USB_JoystickReport_Data_t;
|
||||
|
||||
/* Macros: */
|
||||
/** LED mask for the library LED driver, to indicate that the USB interface is not ready. */
|
||||
#define LEDMASK_USB_NOTREADY LEDS_LED1
|
||||
|
||||
/** LED mask for the library LED driver, to indicate that the USB interface is enumerating. */
|
||||
#define LEDMASK_USB_ENUMERATING (LEDS_LED2 | LEDS_LED3)
|
||||
|
||||
/** LED mask for the library LED driver, to indicate that the USB interface is ready. */
|
||||
#define LEDMASK_USB_READY (LEDS_LED2 | LEDS_LED4)
|
||||
|
||||
/** LED mask for the library LED driver, to indicate that an error has occurred in the USB interface. */
|
||||
#define LEDMASK_USB_ERROR (LEDS_LED1 | LEDS_LED3)
|
||||
|
||||
/* Function Prototypes: */
|
||||
void SetupHardware(void);
|
||||
|
||||
void EVENT_USB_Device_Connect(void);
|
||||
void EVENT_USB_Device_Disconnect(void);
|
||||
void EVENT_USB_Device_ConfigurationChanged(void);
|
||||
void EVENT_USB_Device_UnhandledControlRequest(void);
|
||||
void EVENT_USB_Device_StartOfFrame(void);
|
||||
|
||||
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);
|
||||
void CALLBACK_HID_Device_ProcessHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, const uint8_t ReportID,
|
||||
const void* ReportData, const uint16_t ReportSize);
|
||||
|
||||
#endif
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Header file for Joystick.c.
|
||||
*/
|
||||
|
||||
#ifndef _JOYSTICK_H_
|
||||
#define _JOYSTICK_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/io.h>
|
||||
#include <avr/wdt.h>
|
||||
#include <avr/power.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "Descriptors.h"
|
||||
|
||||
#include <LUFA/Version.h>
|
||||
#include <LUFA/Drivers/Board/Joystick.h>
|
||||
#include <LUFA/Drivers/Board/LEDs.h>
|
||||
#include <LUFA/Drivers/Board/Buttons.h>
|
||||
#include <LUFA/Drivers/USB/USB.h>
|
||||
#include <LUFA/Drivers/USB/Class/HID.h>
|
||||
|
||||
/* Type Defines: */
|
||||
/** 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.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
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 */
|
||||
uint8_t Button; /**< Bit mask of the currently pressed joystick buttons */
|
||||
} USB_JoystickReport_Data_t;
|
||||
|
||||
/* Macros: */
|
||||
/** LED mask for the library LED driver, to indicate that the USB interface is not ready. */
|
||||
#define LEDMASK_USB_NOTREADY LEDS_LED1
|
||||
|
||||
/** LED mask for the library LED driver, to indicate that the USB interface is enumerating. */
|
||||
#define LEDMASK_USB_ENUMERATING (LEDS_LED2 | LEDS_LED3)
|
||||
|
||||
/** LED mask for the library LED driver, to indicate that the USB interface is ready. */
|
||||
#define LEDMASK_USB_READY (LEDS_LED2 | LEDS_LED4)
|
||||
|
||||
/** LED mask for the library LED driver, to indicate that an error has occurred in the USB interface. */
|
||||
#define LEDMASK_USB_ERROR (LEDS_LED1 | LEDS_LED3)
|
||||
|
||||
/* Function Prototypes: */
|
||||
void SetupHardware(void);
|
||||
|
||||
void EVENT_USB_Device_Connect(void);
|
||||
void EVENT_USB_Device_Disconnect(void);
|
||||
void EVENT_USB_Device_ConfigurationChanged(void);
|
||||
void EVENT_USB_Device_UnhandledControlRequest(void);
|
||||
void EVENT_USB_Device_StartOfFrame(void);
|
||||
|
||||
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);
|
||||
void CALLBACK_HID_Device_ProcessHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, const uint8_t ReportID,
|
||||
const void* ReportData, const uint16_t ReportSize);
|
||||
|
||||
#endif
|
||||
|
@ -1,73 +1,73 @@
|
||||
/** \file
|
||||
*
|
||||
* This file contains special DoxyGen information for the generation of the main page and other special
|
||||
* documentation pages. It is not a project source file.
|
||||
*/
|
||||
|
||||
/** \mainpage Joystick Device Demo
|
||||
*
|
||||
* \section SSec_Compat Demo Compatibility:
|
||||
*
|
||||
* The following list indicates what microcontrollers are compatible with this demo.
|
||||
*
|
||||
* - Series 7 USB AVRs
|
||||
* - Series 6 USB AVRs
|
||||
* - Series 4 USB AVRs
|
||||
* - Series 2 USB AVRs
|
||||
*
|
||||
* \section SSec_Info USB Information:
|
||||
*
|
||||
* The following table gives a rundown of the USB utilization of this demo.
|
||||
*
|
||||
* <table>
|
||||
* <tr>
|
||||
* <td><b>USB Mode:</b></td>
|
||||
* <td>Device</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>USB Class:</b></td>
|
||||
* <td>Human Interface Device (HID)</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>USB Subclass:</b></td>
|
||||
* <td>N/A</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>Relevant Standards:</b></td>
|
||||
* <td>USBIF HID Specification \n
|
||||
* USBIF HID Usage Tables</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>Usable Speeds:</b></td>
|
||||
* <td>Low Speed Mode \n
|
||||
* Full Speed Mode</td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*
|
||||
* \section SSec_Description Project Description:
|
||||
*
|
||||
* Joystick demonstration application. This gives a simple reference
|
||||
* application for implementing a USB Keyboard device, for USB Joysticks
|
||||
* using the standard Keyboard HID profile.
|
||||
*
|
||||
* 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
|
||||
* is the second.
|
||||
*
|
||||
* Moving the joystick on the selected board moves the joystick location on
|
||||
* the host computer.
|
||||
*
|
||||
* Currently only single interface joysticks are supported.
|
||||
*
|
||||
* \section SSec_Options Project Options
|
||||
*
|
||||
* The following defines can be found in this demo, which can control the demo behaviour when defined, or changed in value.
|
||||
*
|
||||
* <table>
|
||||
* <tr>
|
||||
* <td>
|
||||
* None
|
||||
* </td>
|
||||
* </tr>
|
||||
* </table>
|
||||
/** \file
|
||||
*
|
||||
* This file contains special DoxyGen information for the generation of the main page and other special
|
||||
* documentation pages. It is not a project source file.
|
||||
*/
|
||||
|
||||
/** \mainpage Joystick Device Demo
|
||||
*
|
||||
* \section SSec_Compat Demo Compatibility:
|
||||
*
|
||||
* The following list indicates what microcontrollers are compatible with this demo.
|
||||
*
|
||||
* - Series 7 USB AVRs
|
||||
* - Series 6 USB AVRs
|
||||
* - Series 4 USB AVRs
|
||||
* - Series 2 USB AVRs
|
||||
*
|
||||
* \section SSec_Info USB Information:
|
||||
*
|
||||
* The following table gives a rundown of the USB utilization of this demo.
|
||||
*
|
||||
* <table>
|
||||
* <tr>
|
||||
* <td><b>USB Mode:</b></td>
|
||||
* <td>Device</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>USB Class:</b></td>
|
||||
* <td>Human Interface Device (HID)</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>USB Subclass:</b></td>
|
||||
* <td>N/A</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>Relevant Standards:</b></td>
|
||||
* <td>USBIF HID Specification \n
|
||||
* USBIF HID Usage Tables</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>Usable Speeds:</b></td>
|
||||
* <td>Low Speed Mode \n
|
||||
* Full Speed Mode</td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*
|
||||
* \section SSec_Description Project Description:
|
||||
*
|
||||
* Joystick demonstration application. This gives a simple reference
|
||||
* application for implementing a USB Keyboard device, for USB Joysticks
|
||||
* using the standard Keyboard HID profile.
|
||||
*
|
||||
* 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
|
||||
* is the second.
|
||||
*
|
||||
* Moving the joystick on the selected board moves the joystick location on
|
||||
* the host computer.
|
||||
*
|
||||
* Currently only single interface joysticks are supported.
|
||||
*
|
||||
* \section SSec_Options Project Options
|
||||
*
|
||||
* The following defines can be found in this demo, which can control the demo behaviour when defined, or changed in value.
|
||||
*
|
||||
* <table>
|
||||
* <tr>
|
||||
* <td>
|
||||
* None
|
||||
* </td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*/
|
File diff suppressed because it is too large
Load Diff
@ -1,257 +1,257 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Denver Gingerich (denver [at] ossguy [dot] com)
|
||||
Based on code by Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* 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
|
||||
* the device's capabilities and functions.
|
||||
*/
|
||||
|
||||
#include "Descriptors.h"
|
||||
|
||||
/** 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
|
||||
* 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
|
||||
* more details on HID report descriptors.
|
||||
*/
|
||||
USB_Descriptor_HIDReport_Datatype_t PROGMEM KeyboardReport[] =
|
||||
{
|
||||
0x05, 0x01, /* Usage Page (Generic Desktop) */
|
||||
0x09, 0x06, /* Usage (Keyboard) */
|
||||
0xa1, 0x01, /* Collection (Application) */
|
||||
0x75, 0x01, /* Report Size (1) */
|
||||
0x95, 0x08, /* Report Count (8) */
|
||||
0x05, 0x07, /* Usage Page (Key Codes) */
|
||||
0x19, 0xe0, /* Usage Minimum (Keyboard LeftControl) */
|
||||
0x29, 0xe7, /* Usage Maximum (Keyboard Right GUI) */
|
||||
0x15, 0x00, /* Logical Minimum (0) */
|
||||
0x25, 0x01, /* Logical Maximum (1) */
|
||||
0x81, 0x02, /* Input (Data, Variable, Absolute) */
|
||||
0x95, 0x01, /* Report Count (1) */
|
||||
0x75, 0x08, /* Report Size (8) */
|
||||
0x81, 0x03, /* Input (Const, Variable, Absolute) */
|
||||
0x95, 0x05, /* Report Count (5) */
|
||||
0x75, 0x01, /* Report Size (1) */
|
||||
0x05, 0x08, /* Usage Page (LEDs) */
|
||||
0x19, 0x01, /* Usage Minimum (Num Lock) */
|
||||
0x29, 0x05, /* Usage Maximum (Kana) */
|
||||
0x91, 0x02, /* Output (Data, Variable, Absolute) */
|
||||
0x95, 0x01, /* Report Count (1) */
|
||||
0x75, 0x03, /* Report Size (3) */
|
||||
0x91, 0x03, /* Output (Const, Variable, Absolute) */
|
||||
0x95, 0x06, /* Report Count (6) */
|
||||
0x75, 0x08, /* Report Size (8) */
|
||||
0x15, 0x00, /* Logical Minimum (0) */
|
||||
0x25, 0x65, /* Logical Maximum (101) */
|
||||
0x05, 0x07, /* Usage Page (Keyboard) */
|
||||
0x19, 0x00, /* Usage Minimum (Reserved (no event indicated)) */
|
||||
0x29, 0x65, /* Usage Maximum (Keyboard Application) */
|
||||
0x81, 0x00, /* Input (Data, Array, Absolute) */
|
||||
0xc0 /* End Collection */
|
||||
};
|
||||
|
||||
/** Device descriptor structure. This descriptor, located in FLASH memory, describes the overall
|
||||
* 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
|
||||
* process begins.
|
||||
*/
|
||||
USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device},
|
||||
|
||||
.USBSpecification = VERSION_BCD(01.10),
|
||||
.Class = 0x00,
|
||||
.SubClass = 0x00,
|
||||
.Protocol = 0x00,
|
||||
|
||||
.Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE,
|
||||
|
||||
.VendorID = 0x03EB,
|
||||
.ProductID = 0x2042,
|
||||
.ReleaseNumber = 0x0000,
|
||||
|
||||
.ManufacturerStrIndex = 0x01,
|
||||
.ProductStrIndex = 0x02,
|
||||
.SerialNumStrIndex = NO_DESCRIPTOR,
|
||||
|
||||
.NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS
|
||||
};
|
||||
|
||||
/** 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
|
||||
* 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.
|
||||
*/
|
||||
USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
|
||||
{
|
||||
.Config =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration},
|
||||
|
||||
.TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t),
|
||||
.TotalInterfaces = 1,
|
||||
|
||||
.ConfigurationNumber = 1,
|
||||
.ConfigurationStrIndex = NO_DESCRIPTOR,
|
||||
|
||||
.ConfigAttributes = (USB_CONFIG_ATTR_BUSPOWERED | USB_CONFIG_ATTR_SELFPOWERED),
|
||||
|
||||
.MaxPowerConsumption = USB_CONFIG_POWER_MA(100)
|
||||
},
|
||||
|
||||
.HID_Interface =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
|
||||
|
||||
.InterfaceNumber = 0x00,
|
||||
.AlternateSetting = 0x00,
|
||||
|
||||
.TotalEndpoints = 1,
|
||||
|
||||
.Class = 0x03,
|
||||
.SubClass = 0x01,
|
||||
.Protocol = HID_BOOT_KEYBOARD_PROTOCOL,
|
||||
|
||||
.InterfaceStrIndex = NO_DESCRIPTOR
|
||||
},
|
||||
|
||||
.HID_KeyboardHID =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_HID_Descriptor_t), .Type = DTYPE_HID},
|
||||
|
||||
.HIDSpec = VERSION_BCD(01.11),
|
||||
.CountryCode = 0x00,
|
||||
.TotalReportDescriptors = 1,
|
||||
.HIDReportType = DTYPE_Report,
|
||||
.HIDReportLength = sizeof(KeyboardReport)
|
||||
},
|
||||
|
||||
.HID_ReportINEndpoint =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
|
||||
|
||||
.EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_IN | KEYBOARD_EPNUM),
|
||||
.Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
|
||||
.EndpointSize = KEYBOARD_EPSIZE,
|
||||
.PollingIntervalMS = 0x0A
|
||||
},
|
||||
};
|
||||
|
||||
/** 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
|
||||
* via the language ID table available at USB.org what languages the device supports for its string descriptors.
|
||||
*/
|
||||
USB_Descriptor_String_t PROGMEM LanguageString =
|
||||
{
|
||||
.Header = {.Size = USB_STRING_LEN(1), .Type = DTYPE_String},
|
||||
|
||||
.UnicodeString = {LANGUAGE_ID_ENG}
|
||||
};
|
||||
|
||||
/** 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
|
||||
* Descriptor.
|
||||
*/
|
||||
USB_Descriptor_String_t PROGMEM ManufacturerString =
|
||||
{
|
||||
.Header = {.Size = USB_STRING_LEN(16), .Type = DTYPE_String},
|
||||
|
||||
.UnicodeString = L"Denver Gingerich"
|
||||
};
|
||||
|
||||
/** 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
|
||||
* Descriptor.
|
||||
*/
|
||||
USB_Descriptor_String_t PROGMEM ProductString =
|
||||
{
|
||||
.Header = {.Size = USB_STRING_LEN(18), .Type = DTYPE_String},
|
||||
|
||||
.UnicodeString = L"LUFA Keyboard Demo"
|
||||
};
|
||||
|
||||
/** 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
|
||||
* 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
|
||||
* USB host.
|
||||
*/
|
||||
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 DescriptorNumber = (wValue & 0xFF);
|
||||
|
||||
void* Address = NULL;
|
||||
uint16_t Size = NO_DESCRIPTOR;
|
||||
|
||||
switch (DescriptorType)
|
||||
{
|
||||
case DTYPE_Device:
|
||||
Address = (void*)&DeviceDescriptor;
|
||||
Size = sizeof(USB_Descriptor_Device_t);
|
||||
break;
|
||||
case DTYPE_Configuration:
|
||||
Address = (void*)&ConfigurationDescriptor;
|
||||
Size = sizeof(USB_Descriptor_Configuration_t);
|
||||
break;
|
||||
case DTYPE_String:
|
||||
switch (DescriptorNumber)
|
||||
{
|
||||
case 0x00:
|
||||
Address = (void*)&LanguageString;
|
||||
Size = pgm_read_byte(&LanguageString.Header.Size);
|
||||
break;
|
||||
case 0x01:
|
||||
Address = (void*)&ManufacturerString;
|
||||
Size = pgm_read_byte(&ManufacturerString.Header.Size);
|
||||
break;
|
||||
case 0x02:
|
||||
Address = (void*)&ProductString;
|
||||
Size = pgm_read_byte(&ProductString.Header.Size);
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
case DTYPE_HID:
|
||||
Address = (void*)&ConfigurationDescriptor.HID_KeyboardHID;
|
||||
Size = sizeof(USB_HID_Descriptor_t);
|
||||
break;
|
||||
case DTYPE_Report:
|
||||
Address = (void*)&KeyboardReport;
|
||||
Size = sizeof(KeyboardReport);
|
||||
break;
|
||||
}
|
||||
|
||||
*DescriptorAddress = Address;
|
||||
return Size;
|
||||
}
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Denver Gingerich (denver [at] ossguy [dot] com)
|
||||
Based on code by Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* 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
|
||||
* the device's capabilities and functions.
|
||||
*/
|
||||
|
||||
#include "Descriptors.h"
|
||||
|
||||
/** 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
|
||||
* 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
|
||||
* more details on HID report descriptors.
|
||||
*/
|
||||
USB_Descriptor_HIDReport_Datatype_t PROGMEM KeyboardReport[] =
|
||||
{
|
||||
0x05, 0x01, /* Usage Page (Generic Desktop) */
|
||||
0x09, 0x06, /* Usage (Keyboard) */
|
||||
0xa1, 0x01, /* Collection (Application) */
|
||||
0x75, 0x01, /* Report Size (1) */
|
||||
0x95, 0x08, /* Report Count (8) */
|
||||
0x05, 0x07, /* Usage Page (Key Codes) */
|
||||
0x19, 0xe0, /* Usage Minimum (Keyboard LeftControl) */
|
||||
0x29, 0xe7, /* Usage Maximum (Keyboard Right GUI) */
|
||||
0x15, 0x00, /* Logical Minimum (0) */
|
||||
0x25, 0x01, /* Logical Maximum (1) */
|
||||
0x81, 0x02, /* Input (Data, Variable, Absolute) */
|
||||
0x95, 0x01, /* Report Count (1) */
|
||||
0x75, 0x08, /* Report Size (8) */
|
||||
0x81, 0x03, /* Input (Const, Variable, Absolute) */
|
||||
0x95, 0x05, /* Report Count (5) */
|
||||
0x75, 0x01, /* Report Size (1) */
|
||||
0x05, 0x08, /* Usage Page (LEDs) */
|
||||
0x19, 0x01, /* Usage Minimum (Num Lock) */
|
||||
0x29, 0x05, /* Usage Maximum (Kana) */
|
||||
0x91, 0x02, /* Output (Data, Variable, Absolute) */
|
||||
0x95, 0x01, /* Report Count (1) */
|
||||
0x75, 0x03, /* Report Size (3) */
|
||||
0x91, 0x03, /* Output (Const, Variable, Absolute) */
|
||||
0x95, 0x06, /* Report Count (6) */
|
||||
0x75, 0x08, /* Report Size (8) */
|
||||
0x15, 0x00, /* Logical Minimum (0) */
|
||||
0x25, 0x65, /* Logical Maximum (101) */
|
||||
0x05, 0x07, /* Usage Page (Keyboard) */
|
||||
0x19, 0x00, /* Usage Minimum (Reserved (no event indicated)) */
|
||||
0x29, 0x65, /* Usage Maximum (Keyboard Application) */
|
||||
0x81, 0x00, /* Input (Data, Array, Absolute) */
|
||||
0xc0 /* End Collection */
|
||||
};
|
||||
|
||||
/** Device descriptor structure. This descriptor, located in FLASH memory, describes the overall
|
||||
* 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
|
||||
* process begins.
|
||||
*/
|
||||
USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device},
|
||||
|
||||
.USBSpecification = VERSION_BCD(01.10),
|
||||
.Class = 0x00,
|
||||
.SubClass = 0x00,
|
||||
.Protocol = 0x00,
|
||||
|
||||
.Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE,
|
||||
|
||||
.VendorID = 0x03EB,
|
||||
.ProductID = 0x2042,
|
||||
.ReleaseNumber = 0x0000,
|
||||
|
||||
.ManufacturerStrIndex = 0x01,
|
||||
.ProductStrIndex = 0x02,
|
||||
.SerialNumStrIndex = NO_DESCRIPTOR,
|
||||
|
||||
.NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS
|
||||
};
|
||||
|
||||
/** 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
|
||||
* 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.
|
||||
*/
|
||||
USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
|
||||
{
|
||||
.Config =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration},
|
||||
|
||||
.TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t),
|
||||
.TotalInterfaces = 1,
|
||||
|
||||
.ConfigurationNumber = 1,
|
||||
.ConfigurationStrIndex = NO_DESCRIPTOR,
|
||||
|
||||
.ConfigAttributes = (USB_CONFIG_ATTR_BUSPOWERED | USB_CONFIG_ATTR_SELFPOWERED),
|
||||
|
||||
.MaxPowerConsumption = USB_CONFIG_POWER_MA(100)
|
||||
},
|
||||
|
||||
.HID_Interface =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
|
||||
|
||||
.InterfaceNumber = 0x00,
|
||||
.AlternateSetting = 0x00,
|
||||
|
||||
.TotalEndpoints = 1,
|
||||
|
||||
.Class = 0x03,
|
||||
.SubClass = 0x01,
|
||||
.Protocol = HID_BOOT_KEYBOARD_PROTOCOL,
|
||||
|
||||
.InterfaceStrIndex = NO_DESCRIPTOR
|
||||
},
|
||||
|
||||
.HID_KeyboardHID =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_HID_Descriptor_t), .Type = DTYPE_HID},
|
||||
|
||||
.HIDSpec = VERSION_BCD(01.11),
|
||||
.CountryCode = 0x00,
|
||||
.TotalReportDescriptors = 1,
|
||||
.HIDReportType = DTYPE_Report,
|
||||
.HIDReportLength = sizeof(KeyboardReport)
|
||||
},
|
||||
|
||||
.HID_ReportINEndpoint =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
|
||||
|
||||
.EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_IN | KEYBOARD_EPNUM),
|
||||
.Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
|
||||
.EndpointSize = KEYBOARD_EPSIZE,
|
||||
.PollingIntervalMS = 0x0A
|
||||
},
|
||||
};
|
||||
|
||||
/** 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
|
||||
* via the language ID table available at USB.org what languages the device supports for its string descriptors.
|
||||
*/
|
||||
USB_Descriptor_String_t PROGMEM LanguageString =
|
||||
{
|
||||
.Header = {.Size = USB_STRING_LEN(1), .Type = DTYPE_String},
|
||||
|
||||
.UnicodeString = {LANGUAGE_ID_ENG}
|
||||
};
|
||||
|
||||
/** 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
|
||||
* Descriptor.
|
||||
*/
|
||||
USB_Descriptor_String_t PROGMEM ManufacturerString =
|
||||
{
|
||||
.Header = {.Size = USB_STRING_LEN(16), .Type = DTYPE_String},
|
||||
|
||||
.UnicodeString = L"Denver Gingerich"
|
||||
};
|
||||
|
||||
/** 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
|
||||
* Descriptor.
|
||||
*/
|
||||
USB_Descriptor_String_t PROGMEM ProductString =
|
||||
{
|
||||
.Header = {.Size = USB_STRING_LEN(18), .Type = DTYPE_String},
|
||||
|
||||
.UnicodeString = L"LUFA Keyboard Demo"
|
||||
};
|
||||
|
||||
/** 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
|
||||
* 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
|
||||
* USB host.
|
||||
*/
|
||||
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 DescriptorNumber = (wValue & 0xFF);
|
||||
|
||||
void* Address = NULL;
|
||||
uint16_t Size = NO_DESCRIPTOR;
|
||||
|
||||
switch (DescriptorType)
|
||||
{
|
||||
case DTYPE_Device:
|
||||
Address = (void*)&DeviceDescriptor;
|
||||
Size = sizeof(USB_Descriptor_Device_t);
|
||||
break;
|
||||
case DTYPE_Configuration:
|
||||
Address = (void*)&ConfigurationDescriptor;
|
||||
Size = sizeof(USB_Descriptor_Configuration_t);
|
||||
break;
|
||||
case DTYPE_String:
|
||||
switch (DescriptorNumber)
|
||||
{
|
||||
case 0x00:
|
||||
Address = (void*)&LanguageString;
|
||||
Size = pgm_read_byte(&LanguageString.Header.Size);
|
||||
break;
|
||||
case 0x01:
|
||||
Address = (void*)&ManufacturerString;
|
||||
Size = pgm_read_byte(&ManufacturerString.Header.Size);
|
||||
break;
|
||||
case 0x02:
|
||||
Address = (void*)&ProductString;
|
||||
Size = pgm_read_byte(&ProductString.Header.Size);
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
case DTYPE_HID:
|
||||
Address = (void*)&ConfigurationDescriptor.HID_KeyboardHID;
|
||||
Size = sizeof(USB_HID_Descriptor_t);
|
||||
break;
|
||||
case DTYPE_Report:
|
||||
Address = (void*)&KeyboardReport;
|
||||
Size = sizeof(KeyboardReport);
|
||||
break;
|
||||
}
|
||||
|
||||
*DescriptorAddress = Address;
|
||||
return Size;
|
||||
}
|
||||
|
@ -1,70 +1,70 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Denver Gingerich (denver [at] ossguy [dot] com)
|
||||
Based on code by Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Header file for Descriptors.c.
|
||||
*/
|
||||
|
||||
#ifndef _DESCRIPTORS_H_
|
||||
#define _DESCRIPTORS_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/pgmspace.h>
|
||||
|
||||
#include <LUFA/Drivers/USB/USB.h>
|
||||
#include <LUFA/Drivers/USB/Class/HID.h>
|
||||
|
||||
/* Type Defines: */
|
||||
/** 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
|
||||
* vary between devices, and which describe the device's usage to the host.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
USB_Descriptor_Configuration_Header_t Config;
|
||||
USB_Descriptor_Interface_t HID_Interface;
|
||||
USB_HID_Descriptor_t HID_KeyboardHID;
|
||||
USB_Descriptor_Endpoint_t HID_ReportINEndpoint;
|
||||
} USB_Descriptor_Configuration_t;
|
||||
|
||||
/* Macros: */
|
||||
/** Endpoint number of the Keyboard HID reporting IN endpoint. */
|
||||
#define KEYBOARD_EPNUM 1
|
||||
|
||||
/** Size in bytes of the Keyboard HID reporting IN and OUT endpoints. */
|
||||
#define KEYBOARD_EPSIZE 8
|
||||
|
||||
/* Function Prototypes: */
|
||||
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);
|
||||
|
||||
#endif
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Denver Gingerich (denver [at] ossguy [dot] com)
|
||||
Based on code by Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Header file for Descriptors.c.
|
||||
*/
|
||||
|
||||
#ifndef _DESCRIPTORS_H_
|
||||
#define _DESCRIPTORS_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/pgmspace.h>
|
||||
|
||||
#include <LUFA/Drivers/USB/USB.h>
|
||||
#include <LUFA/Drivers/USB/Class/HID.h>
|
||||
|
||||
/* Type Defines: */
|
||||
/** 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
|
||||
* vary between devices, and which describe the device's usage to the host.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
USB_Descriptor_Configuration_Header_t Config;
|
||||
USB_Descriptor_Interface_t HID_Interface;
|
||||
USB_HID_Descriptor_t HID_KeyboardHID;
|
||||
USB_Descriptor_Endpoint_t HID_ReportINEndpoint;
|
||||
} USB_Descriptor_Configuration_t;
|
||||
|
||||
/* Macros: */
|
||||
/** Endpoint number of the Keyboard HID reporting IN endpoint. */
|
||||
#define KEYBOARD_EPNUM 1
|
||||
|
||||
/** Size in bytes of the Keyboard HID reporting IN and OUT endpoints. */
|
||||
#define KEYBOARD_EPSIZE 8
|
||||
|
||||
/* Function Prototypes: */
|
||||
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);
|
||||
|
||||
#endif
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,196 +1,196 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Main source file for the Keyboard demo. This file contains the main tasks of
|
||||
* the demo and is responsible for the initial application hardware configuration.
|
||||
*/
|
||||
|
||||
#include "Keyboard.h"
|
||||
|
||||
/** 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)];
|
||||
|
||||
/** LUFA HID Class driver interface configuration and state information. This structure is
|
||||
* passed to all HID Class driver functions, so that multiple instances of the same class
|
||||
* within a device can be differentiated from one another.
|
||||
*/
|
||||
USB_ClassInfo_HID_Device_t Keyboard_HID_Interface =
|
||||
{
|
||||
.Config =
|
||||
{
|
||||
.InterfaceNumber = 0,
|
||||
|
||||
.ReportINEndpointNumber = KEYBOARD_EPNUM,
|
||||
.ReportINEndpointSize = KEYBOARD_EPSIZE,
|
||||
.ReportINEndpointDoubleBank = false,
|
||||
|
||||
.PrevReportINBuffer = PrevKeyboardHIDReportBuffer,
|
||||
.PrevReportINBufferSize = sizeof(PrevKeyboardHIDReportBuffer),
|
||||
},
|
||||
};
|
||||
|
||||
/** Main program entry point. This routine contains the overall program flow, including initial
|
||||
* setup of all components and the main program loop.
|
||||
*/
|
||||
int main(void)
|
||||
{
|
||||
SetupHardware();
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
|
||||
sei();
|
||||
|
||||
for (;;)
|
||||
{
|
||||
HID_Device_USBTask(&Keyboard_HID_Interface);
|
||||
USB_USBTask();
|
||||
}
|
||||
}
|
||||
|
||||
/** Configures the board hardware and chip peripherals for the demo's functionality. */
|
||||
void SetupHardware()
|
||||
{
|
||||
/* Disable watchdog if enabled by bootloader/fuses */
|
||||
MCUSR &= ~(1 << WDRF);
|
||||
wdt_disable();
|
||||
|
||||
/* Disable clock division */
|
||||
clock_prescale_set(clock_div_1);
|
||||
|
||||
/* Hardware Initialization */
|
||||
Joystick_Init();
|
||||
LEDs_Init();
|
||||
Buttons_Init();
|
||||
USB_Init();
|
||||
}
|
||||
|
||||
/** Event handler for the library USB Connection event. */
|
||||
void EVENT_USB_Device_Connect(void)
|
||||
{
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
|
||||
}
|
||||
|
||||
/** Event handler for the library USB Disconnection event. */
|
||||
void EVENT_USB_Device_Disconnect(void)
|
||||
{
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
|
||||
}
|
||||
|
||||
/** Event handler for the library USB Configuration Changed event. */
|
||||
void EVENT_USB_Device_ConfigurationChanged(void)
|
||||
{
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
|
||||
if (!(HID_Device_ConfigureEndpoints(&Keyboard_HID_Interface)))
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
USB_Device_EnableSOFEvents();
|
||||
}
|
||||
|
||||
/** Event handler for the library USB Unhandled Control Request event. */
|
||||
void EVENT_USB_Device_UnhandledControlRequest(void)
|
||||
{
|
||||
HID_Device_ProcessControlRequest(&Keyboard_HID_Interface);
|
||||
}
|
||||
|
||||
/** Event handler for the USB device Start Of Frame event. */
|
||||
void EVENT_USB_Device_StartOfFrame(void)
|
||||
{
|
||||
HID_Device_MillisecondElapsed(&Keyboard_HID_Interface);
|
||||
}
|
||||
|
||||
/** 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,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[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
|
||||
*
|
||||
* \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,
|
||||
const uint8_t ReportType, void* ReportData, uint16_t* ReportSize)
|
||||
{
|
||||
USB_KeyboardReport_Data_t* KeyboardReport = (USB_KeyboardReport_Data_t*)ReportData;
|
||||
|
||||
uint8_t JoyStatus_LCL = Joystick_GetStatus();
|
||||
uint8_t ButtonStatus_LCL = Buttons_GetStatus();
|
||||
|
||||
uint8_t UsedKeyCodes = 0;
|
||||
|
||||
if (JoyStatus_LCL & JOY_UP)
|
||||
KeyboardReport->KeyCode[UsedKeyCodes++] = 0x04; // A
|
||||
else if (JoyStatus_LCL & JOY_DOWN)
|
||||
KeyboardReport->KeyCode[UsedKeyCodes++] = 0x05; // B
|
||||
|
||||
if (JoyStatus_LCL & JOY_LEFT)
|
||||
KeyboardReport->KeyCode[UsedKeyCodes++] = 0x06; // C
|
||||
else if (JoyStatus_LCL & JOY_RIGHT)
|
||||
KeyboardReport->KeyCode[UsedKeyCodes++] = 0x07; // D
|
||||
|
||||
if (JoyStatus_LCL & JOY_PRESS)
|
||||
KeyboardReport->KeyCode[UsedKeyCodes++] = 0x08; // E
|
||||
|
||||
if (ButtonStatus_LCL & BUTTONS_BUTTON1)
|
||||
KeyboardReport->KeyCode[UsedKeyCodes++] = 0x09; // F
|
||||
|
||||
if (UsedKeyCodes)
|
||||
KeyboardReport->Modifier = HID_KEYBOARD_MODIFER_LEFTSHIFT;
|
||||
|
||||
*ReportSize = sizeof(USB_KeyboardReport_Data_t);
|
||||
return false;
|
||||
}
|
||||
|
||||
/** 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] 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] 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,
|
||||
const void* ReportData, const uint16_t ReportSize)
|
||||
{
|
||||
uint8_t LEDMask = LEDS_NO_LEDS;
|
||||
uint8_t* LEDReport = (uint8_t*)ReportData;
|
||||
|
||||
if (*LEDReport & HID_KEYBOARD_LED_NUMLOCK)
|
||||
LEDMask |= LEDS_LED1;
|
||||
|
||||
if (*LEDReport & HID_KEYBOARD_LED_CAPSLOCK)
|
||||
LEDMask |= LEDS_LED3;
|
||||
|
||||
if (*LEDReport & HID_KEYBOARD_LED_SCROLLLOCK)
|
||||
LEDMask |= LEDS_LED4;
|
||||
|
||||
LEDs_SetAllLEDs(LEDMask);
|
||||
}
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Main source file for the Keyboard demo. This file contains the main tasks of
|
||||
* the demo and is responsible for the initial application hardware configuration.
|
||||
*/
|
||||
|
||||
#include "Keyboard.h"
|
||||
|
||||
/** 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)];
|
||||
|
||||
/** LUFA HID Class driver interface configuration and state information. This structure is
|
||||
* passed to all HID Class driver functions, so that multiple instances of the same class
|
||||
* within a device can be differentiated from one another.
|
||||
*/
|
||||
USB_ClassInfo_HID_Device_t Keyboard_HID_Interface =
|
||||
{
|
||||
.Config =
|
||||
{
|
||||
.InterfaceNumber = 0,
|
||||
|
||||
.ReportINEndpointNumber = KEYBOARD_EPNUM,
|
||||
.ReportINEndpointSize = KEYBOARD_EPSIZE,
|
||||
.ReportINEndpointDoubleBank = false,
|
||||
|
||||
.PrevReportINBuffer = PrevKeyboardHIDReportBuffer,
|
||||
.PrevReportINBufferSize = sizeof(PrevKeyboardHIDReportBuffer),
|
||||
},
|
||||
};
|
||||
|
||||
/** Main program entry point. This routine contains the overall program flow, including initial
|
||||
* setup of all components and the main program loop.
|
||||
*/
|
||||
int main(void)
|
||||
{
|
||||
SetupHardware();
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
|
||||
sei();
|
||||
|
||||
for (;;)
|
||||
{
|
||||
HID_Device_USBTask(&Keyboard_HID_Interface);
|
||||
USB_USBTask();
|
||||
}
|
||||
}
|
||||
|
||||
/** Configures the board hardware and chip peripherals for the demo's functionality. */
|
||||
void SetupHardware()
|
||||
{
|
||||
/* Disable watchdog if enabled by bootloader/fuses */
|
||||
MCUSR &= ~(1 << WDRF);
|
||||
wdt_disable();
|
||||
|
||||
/* Disable clock division */
|
||||
clock_prescale_set(clock_div_1);
|
||||
|
||||
/* Hardware Initialization */
|
||||
Joystick_Init();
|
||||
LEDs_Init();
|
||||
Buttons_Init();
|
||||
USB_Init();
|
||||
}
|
||||
|
||||
/** Event handler for the library USB Connection event. */
|
||||
void EVENT_USB_Device_Connect(void)
|
||||
{
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
|
||||
}
|
||||
|
||||
/** Event handler for the library USB Disconnection event. */
|
||||
void EVENT_USB_Device_Disconnect(void)
|
||||
{
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
|
||||
}
|
||||
|
||||
/** Event handler for the library USB Configuration Changed event. */
|
||||
void EVENT_USB_Device_ConfigurationChanged(void)
|
||||
{
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
|
||||
if (!(HID_Device_ConfigureEndpoints(&Keyboard_HID_Interface)))
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
USB_Device_EnableSOFEvents();
|
||||
}
|
||||
|
||||
/** Event handler for the library USB Unhandled Control Request event. */
|
||||
void EVENT_USB_Device_UnhandledControlRequest(void)
|
||||
{
|
||||
HID_Device_ProcessControlRequest(&Keyboard_HID_Interface);
|
||||
}
|
||||
|
||||
/** Event handler for the USB device Start Of Frame event. */
|
||||
void EVENT_USB_Device_StartOfFrame(void)
|
||||
{
|
||||
HID_Device_MillisecondElapsed(&Keyboard_HID_Interface);
|
||||
}
|
||||
|
||||
/** 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,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[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
|
||||
*
|
||||
* \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,
|
||||
const uint8_t ReportType, void* ReportData, uint16_t* ReportSize)
|
||||
{
|
||||
USB_KeyboardReport_Data_t* KeyboardReport = (USB_KeyboardReport_Data_t*)ReportData;
|
||||
|
||||
uint8_t JoyStatus_LCL = Joystick_GetStatus();
|
||||
uint8_t ButtonStatus_LCL = Buttons_GetStatus();
|
||||
|
||||
uint8_t UsedKeyCodes = 0;
|
||||
|
||||
if (JoyStatus_LCL & JOY_UP)
|
||||
KeyboardReport->KeyCode[UsedKeyCodes++] = 0x04; // A
|
||||
else if (JoyStatus_LCL & JOY_DOWN)
|
||||
KeyboardReport->KeyCode[UsedKeyCodes++] = 0x05; // B
|
||||
|
||||
if (JoyStatus_LCL & JOY_LEFT)
|
||||
KeyboardReport->KeyCode[UsedKeyCodes++] = 0x06; // C
|
||||
else if (JoyStatus_LCL & JOY_RIGHT)
|
||||
KeyboardReport->KeyCode[UsedKeyCodes++] = 0x07; // D
|
||||
|
||||
if (JoyStatus_LCL & JOY_PRESS)
|
||||
KeyboardReport->KeyCode[UsedKeyCodes++] = 0x08; // E
|
||||
|
||||
if (ButtonStatus_LCL & BUTTONS_BUTTON1)
|
||||
KeyboardReport->KeyCode[UsedKeyCodes++] = 0x09; // F
|
||||
|
||||
if (UsedKeyCodes)
|
||||
KeyboardReport->Modifier = HID_KEYBOARD_MODIFER_LEFTSHIFT;
|
||||
|
||||
*ReportSize = sizeof(USB_KeyboardReport_Data_t);
|
||||
return false;
|
||||
}
|
||||
|
||||
/** 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] 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] 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,
|
||||
const void* ReportData, const uint16_t ReportSize)
|
||||
{
|
||||
uint8_t LEDMask = LEDS_NO_LEDS;
|
||||
uint8_t* LEDReport = (uint8_t*)ReportData;
|
||||
|
||||
if (*LEDReport & HID_KEYBOARD_LED_NUMLOCK)
|
||||
LEDMask |= LEDS_LED1;
|
||||
|
||||
if (*LEDReport & HID_KEYBOARD_LED_CAPSLOCK)
|
||||
LEDMask |= LEDS_LED3;
|
||||
|
||||
if (*LEDReport & HID_KEYBOARD_LED_SCROLLLOCK)
|
||||
LEDMask |= LEDS_LED4;
|
||||
|
||||
LEDs_SetAllLEDs(LEDMask);
|
||||
}
|
||||
|
@ -1,84 +1,84 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Denver Gingerich (denver [at] ossguy [dot] com)
|
||||
Based on code by Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Header file for Keyboard.c.
|
||||
*/
|
||||
|
||||
#ifndef _KEYBOARD_H_
|
||||
#define _KEYBOARD_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/io.h>
|
||||
#include <avr/wdt.h>
|
||||
#include <avr/power.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "Descriptors.h"
|
||||
|
||||
#include <LUFA/Version.h>
|
||||
#include <LUFA/Drivers/Board/Joystick.h>
|
||||
#include <LUFA/Drivers/Board/LEDs.h>
|
||||
#include <LUFA/Drivers/Board/Buttons.h>
|
||||
#include <LUFA/Drivers/USB/USB.h>
|
||||
#include <LUFA/Drivers/USB/Class/HID.h>
|
||||
|
||||
/* Macros: */
|
||||
/** LED mask for the library LED driver, to indicate that the USB interface is not ready. */
|
||||
#define LEDMASK_USB_NOTREADY LEDS_LED1
|
||||
|
||||
/** LED mask for the library LED driver, to indicate that the USB interface is enumerating. */
|
||||
#define LEDMASK_USB_ENUMERATING (LEDS_LED2 | LEDS_LED3)
|
||||
|
||||
/** LED mask for the library LED driver, to indicate that the USB interface is ready. */
|
||||
#define LEDMASK_USB_READY (LEDS_LED2 | LEDS_LED4)
|
||||
|
||||
/** LED mask for the library LED driver, to indicate that an error has occurred in the USB interface. */
|
||||
#define LEDMASK_USB_ERROR (LEDS_LED1 | LEDS_LED3)
|
||||
|
||||
/* Function Prototypes: */
|
||||
void SetupHardware(void);
|
||||
|
||||
void EVENT_USB_Device_Connect(void);
|
||||
void EVENT_USB_Device_Disconnect(void);
|
||||
void EVENT_USB_Device_ConfigurationChanged(void);
|
||||
void EVENT_USB_Device_UnhandledControlRequest(void);
|
||||
void EVENT_USB_Device_StartOfFrame(void);
|
||||
|
||||
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);
|
||||
void CALLBACK_HID_Device_ProcessHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, const uint8_t ReportID,
|
||||
const void* ReportData, const uint16_t ReportSize);
|
||||
|
||||
#endif
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Denver Gingerich (denver [at] ossguy [dot] com)
|
||||
Based on code by Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Header file for Keyboard.c.
|
||||
*/
|
||||
|
||||
#ifndef _KEYBOARD_H_
|
||||
#define _KEYBOARD_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/io.h>
|
||||
#include <avr/wdt.h>
|
||||
#include <avr/power.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "Descriptors.h"
|
||||
|
||||
#include <LUFA/Version.h>
|
||||
#include <LUFA/Drivers/Board/Joystick.h>
|
||||
#include <LUFA/Drivers/Board/LEDs.h>
|
||||
#include <LUFA/Drivers/Board/Buttons.h>
|
||||
#include <LUFA/Drivers/USB/USB.h>
|
||||
#include <LUFA/Drivers/USB/Class/HID.h>
|
||||
|
||||
/* Macros: */
|
||||
/** LED mask for the library LED driver, to indicate that the USB interface is not ready. */
|
||||
#define LEDMASK_USB_NOTREADY LEDS_LED1
|
||||
|
||||
/** LED mask for the library LED driver, to indicate that the USB interface is enumerating. */
|
||||
#define LEDMASK_USB_ENUMERATING (LEDS_LED2 | LEDS_LED3)
|
||||
|
||||
/** LED mask for the library LED driver, to indicate that the USB interface is ready. */
|
||||
#define LEDMASK_USB_READY (LEDS_LED2 | LEDS_LED4)
|
||||
|
||||
/** LED mask for the library LED driver, to indicate that an error has occurred in the USB interface. */
|
||||
#define LEDMASK_USB_ERROR (LEDS_LED1 | LEDS_LED3)
|
||||
|
||||
/* Function Prototypes: */
|
||||
void SetupHardware(void);
|
||||
|
||||
void EVENT_USB_Device_Connect(void);
|
||||
void EVENT_USB_Device_Disconnect(void);
|
||||
void EVENT_USB_Device_ConfigurationChanged(void);
|
||||
void EVENT_USB_Device_UnhandledControlRequest(void);
|
||||
void EVENT_USB_Device_StartOfFrame(void);
|
||||
|
||||
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);
|
||||
void CALLBACK_HID_Device_ProcessHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, const uint8_t ReportID,
|
||||
const void* ReportData, const uint16_t ReportSize);
|
||||
|
||||
#endif
|
||||
|
@ -1,72 +1,72 @@
|
||||
/** \file
|
||||
*
|
||||
* This file contains special DoxyGen information for the generation of the main page and other special
|
||||
* documentation pages. It is not a project source file.
|
||||
*/
|
||||
|
||||
/** \mainpage Keyboard Device Demo
|
||||
*
|
||||
* \section SSec_Compat Demo Compatibility:
|
||||
*
|
||||
* The following list indicates what microcontrollers are compatible with this demo.
|
||||
*
|
||||
* - Series 7 USB AVRs
|
||||
* - Series 6 USB AVRs
|
||||
* - Series 4 USB AVRs
|
||||
* - Series 2 USB AVRs
|
||||
*
|
||||
* \section SSec_Info USB Information:
|
||||
*
|
||||
* The following table gives a rundown of the USB utilization of this demo.
|
||||
*
|
||||
* <table>
|
||||
* <tr>
|
||||
* <td><b>USB Mode:</b></td>
|
||||
* <td>Device</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>USB Class:</b></td>
|
||||
* <td>Human Interface Device (HID)</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>USB Subclass:</b></td>
|
||||
* <td>Keyboard Subclass</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>Relevant Standards:</b></td>
|
||||
* <td>USBIF HID Specification \n
|
||||
* USBIF HID Usage Tables</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>Usable Speeds:</b></td>
|
||||
* <td>Low Speed Mode \n
|
||||
* Full Speed Mode</td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*
|
||||
* \section SSec_Description Project Description:
|
||||
*
|
||||
* Keyboard demonstration application. This gives a simple reference application
|
||||
* 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
|
||||
* 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
|
||||
* 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
|
||||
* 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
|
||||
* inside the same report to the host.
|
||||
*
|
||||
* \section SSec_Options Project Options
|
||||
*
|
||||
* The following defines can be found in this demo, which can control the demo behaviour when defined, or changed in value.
|
||||
*
|
||||
* <table>
|
||||
* <tr>
|
||||
* <td>
|
||||
* None
|
||||
* </td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*/
|
||||
/** \file
|
||||
*
|
||||
* This file contains special DoxyGen information for the generation of the main page and other special
|
||||
* documentation pages. It is not a project source file.
|
||||
*/
|
||||
|
||||
/** \mainpage Keyboard Device Demo
|
||||
*
|
||||
* \section SSec_Compat Demo Compatibility:
|
||||
*
|
||||
* The following list indicates what microcontrollers are compatible with this demo.
|
||||
*
|
||||
* - Series 7 USB AVRs
|
||||
* - Series 6 USB AVRs
|
||||
* - Series 4 USB AVRs
|
||||
* - Series 2 USB AVRs
|
||||
*
|
||||
* \section SSec_Info USB Information:
|
||||
*
|
||||
* The following table gives a rundown of the USB utilization of this demo.
|
||||
*
|
||||
* <table>
|
||||
* <tr>
|
||||
* <td><b>USB Mode:</b></td>
|
||||
* <td>Device</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>USB Class:</b></td>
|
||||
* <td>Human Interface Device (HID)</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>USB Subclass:</b></td>
|
||||
* <td>Keyboard Subclass</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>Relevant Standards:</b></td>
|
||||
* <td>USBIF HID Specification \n
|
||||
* USBIF HID Usage Tables</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>Usable Speeds:</b></td>
|
||||
* <td>Low Speed Mode \n
|
||||
* Full Speed Mode</td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*
|
||||
* \section SSec_Description Project Description:
|
||||
*
|
||||
* Keyboard demonstration application. This gives a simple reference application
|
||||
* 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
|
||||
* 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
|
||||
* 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
|
||||
* 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
|
||||
* inside the same report to the host.
|
||||
*
|
||||
* \section SSec_Options Project Options
|
||||
*
|
||||
* The following defines can be found in this demo, which can control the demo behaviour when defined, or changed in value.
|
||||
*
|
||||
* <table>
|
||||
* <tr>
|
||||
* <td>
|
||||
* None
|
||||
* </td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*/
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,344 +1,344 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
Copyright 2010 Denver Gingerich (denver [at] ossguy [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* 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
|
||||
* the device's capabilities and functions.
|
||||
*/
|
||||
|
||||
#include "Descriptors.h"
|
||||
|
||||
/** 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
|
||||
* 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
|
||||
* more details on HID report descriptors.
|
||||
*
|
||||
* This descriptor describes the mouse HID interface's report structure.
|
||||
*/
|
||||
USB_Descriptor_HIDReport_Datatype_t PROGMEM MouseReport[] =
|
||||
{
|
||||
0x05, 0x01, /* Usage Page (Generic Desktop) */
|
||||
0x09, 0x02, /* Usage (Mouse) */
|
||||
0xA1, 0x01, /* Collection (Application) */
|
||||
0x09, 0x01, /* Usage (Pointer) */
|
||||
0xA1, 0x00, /* Collection (Physical) */
|
||||
0x95, 0x03, /* Report Count (3) */
|
||||
0x75, 0x01, /* Report Size (1) */
|
||||
0x05, 0x09, /* Usage Page (Button) */
|
||||
0x19, 0x01, /* Usage Minimum (Button 1) */
|
||||
0x29, 0x03, /* Usage Maximum (Button 3) */
|
||||
0x15, 0x00, /* Logical Minimum (0) */
|
||||
0x25, 0x01, /* Logical Maximum (1) */
|
||||
0x81, 0x02, /* Input (Data, Variable, Absolute) */
|
||||
0x95, 0x01, /* Report Count (1) */
|
||||
0x75, 0x05, /* Report Size (5) */
|
||||
0x81, 0x01, /* Input (Constant) */
|
||||
0x75, 0x08, /* Report Size (8) */
|
||||
0x95, 0x02, /* Report Count (2) */
|
||||
0x05, 0x01, /* Usage Page (Generic Desktop Control) */
|
||||
0x09, 0x30, /* Usage X */
|
||||
0x09, 0x31, /* Usage Y */
|
||||
0x15, 0x81, /* Logical Minimum (-127) */
|
||||
0x25, 0x7F, /* Logical Maximum (127) */
|
||||
0x81, 0x06, /* Input (Data, Variable, Relative) */
|
||||
0xC0, /* End Collection */
|
||||
0xC0, /* End Collection */
|
||||
};
|
||||
|
||||
/** Same as the MouseReport structure, but defines the keyboard HID interface's report structure. */
|
||||
USB_Descriptor_HIDReport_Datatype_t PROGMEM KeyboardReport[] =
|
||||
{
|
||||
0x05, 0x01, /* Usage Page (Generic Desktop) */
|
||||
0x09, 0x06, /* Usage (Keyboard) */
|
||||
0xa1, 0x01, /* Collection (Application) */
|
||||
0x75, 0x01, /* Report Size (1) */
|
||||
0x95, 0x08, /* Report Count (8) */
|
||||
0x05, 0x07, /* Usage Page (Key Codes) */
|
||||
0x19, 0xe0, /* Usage Minimum (Keyboard LeftControl) */
|
||||
0x29, 0xe7, /* Usage Maximum (Keyboard Right GUI) */
|
||||
0x15, 0x00, /* Logical Minimum (0) */
|
||||
0x25, 0x01, /* Logical Maximum (1) */
|
||||
0x81, 0x02, /* Input (Data, Variable, Absolute) */
|
||||
0x95, 0x01, /* Report Count (1) */
|
||||
0x75, 0x08, /* Report Size (8) */
|
||||
0x81, 0x03, /* Input (Const, Variable, Absolute) */
|
||||
0x95, 0x05, /* Report Count (5) */
|
||||
0x75, 0x01, /* Report Size (1) */
|
||||
0x05, 0x08, /* Usage Page (LEDs) */
|
||||
0x19, 0x01, /* Usage Minimum (Num Lock) */
|
||||
0x29, 0x05, /* Usage Maximum (Kana) */
|
||||
0x91, 0x02, /* Output (Data, Variable, Absolute) */
|
||||
0x95, 0x01, /* Report Count (1) */
|
||||
0x75, 0x03, /* Report Size (3) */
|
||||
0x91, 0x03, /* Output (Const, Variable, Absolute) */
|
||||
0x95, 0x06, /* Report Count (6) */
|
||||
0x75, 0x08, /* Report Size (8) */
|
||||
0x15, 0x00, /* Logical Minimum (0) */
|
||||
0x25, 0x65, /* Logical Maximum (101) */
|
||||
0x05, 0x07, /* Usage Page (Keyboard) */
|
||||
0x19, 0x00, /* Usage Minimum (Reserved (no event indicated)) */
|
||||
0x29, 0x65, /* Usage Maximum (Keyboard Application) */
|
||||
0x81, 0x00, /* Input (Data, Array, Absolute) */
|
||||
0xC0 /* End Collection */
|
||||
};
|
||||
|
||||
/** Device descriptor structure. This descriptor, located in FLASH memory, describes the overall
|
||||
* 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
|
||||
* process begins.
|
||||
*/
|
||||
USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device},
|
||||
|
||||
.USBSpecification = VERSION_BCD(01.10),
|
||||
.Class = 0x00,
|
||||
.SubClass = 0x00,
|
||||
.Protocol = 0x00,
|
||||
|
||||
.Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE,
|
||||
|
||||
.VendorID = 0x03EB,
|
||||
.ProductID = 0x204D,
|
||||
.ReleaseNumber = 0x0000,
|
||||
|
||||
.ManufacturerStrIndex = 0x01,
|
||||
.ProductStrIndex = 0x02,
|
||||
.SerialNumStrIndex = NO_DESCRIPTOR,
|
||||
|
||||
.NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS
|
||||
};
|
||||
|
||||
/** 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
|
||||
* 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.
|
||||
*/
|
||||
USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
|
||||
{
|
||||
.Config =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration},
|
||||
|
||||
.TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t),
|
||||
.TotalInterfaces = 2,
|
||||
|
||||
.ConfigurationNumber = 1,
|
||||
.ConfigurationStrIndex = NO_DESCRIPTOR,
|
||||
|
||||
.ConfigAttributes = (USB_CONFIG_ATTR_BUSPOWERED | USB_CONFIG_ATTR_SELFPOWERED),
|
||||
|
||||
.MaxPowerConsumption = USB_CONFIG_POWER_MA(100)
|
||||
},
|
||||
|
||||
.HID1_KeyboardInterface =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
|
||||
|
||||
.InterfaceNumber = 0x00,
|
||||
.AlternateSetting = 0x00,
|
||||
|
||||
.TotalEndpoints = 1,
|
||||
|
||||
.Class = 0x03,
|
||||
.SubClass = 0x01,
|
||||
.Protocol = HID_BOOT_KEYBOARD_PROTOCOL,
|
||||
|
||||
.InterfaceStrIndex = NO_DESCRIPTOR
|
||||
},
|
||||
|
||||
.HID1_KeyboardHID =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_HID_Descriptor_t), .Type = DTYPE_HID},
|
||||
|
||||
.HIDSpec = VERSION_BCD(01.11),
|
||||
.CountryCode = 0x00,
|
||||
.TotalReportDescriptors = 1,
|
||||
.HIDReportType = DTYPE_Report,
|
||||
.HIDReportLength = sizeof(KeyboardReport)
|
||||
},
|
||||
|
||||
.HID1_ReportINEndpoint =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
|
||||
|
||||
.EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_IN | KEYBOARD_IN_EPNUM),
|
||||
.Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
|
||||
.EndpointSize = HID_EPSIZE,
|
||||
.PollingIntervalMS = 0x0A
|
||||
},
|
||||
|
||||
.HID2_MouseInterface =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
|
||||
|
||||
.InterfaceNumber = 0x01,
|
||||
.AlternateSetting = 0x00,
|
||||
|
||||
.TotalEndpoints = 1,
|
||||
|
||||
.Class = 0x03,
|
||||
.SubClass = 0x01,
|
||||
.Protocol = HID_BOOT_MOUSE_PROTOCOL,
|
||||
|
||||
.InterfaceStrIndex = NO_DESCRIPTOR
|
||||
},
|
||||
|
||||
.HID2_MouseHID =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_HID_Descriptor_t), .Type = DTYPE_HID},
|
||||
|
||||
.HIDSpec = VERSION_BCD(01.11),
|
||||
.CountryCode = 0x00,
|
||||
.TotalReportDescriptors = 1,
|
||||
.HIDReportType = DTYPE_Report,
|
||||
.HIDReportLength = sizeof(MouseReport)
|
||||
},
|
||||
|
||||
.HID2_ReportINEndpoint =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
|
||||
|
||||
.EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_IN | MOUSE_IN_EPNUM),
|
||||
.Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
|
||||
.EndpointSize = HID_EPSIZE,
|
||||
.PollingIntervalMS = 0x0A
|
||||
}
|
||||
};
|
||||
|
||||
/** 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
|
||||
* via the language ID table available at USB.org what languages the device supports for its string descriptors.
|
||||
*/
|
||||
USB_Descriptor_String_t PROGMEM LanguageString =
|
||||
{
|
||||
.Header = {.Size = USB_STRING_LEN(1), .Type = DTYPE_String},
|
||||
|
||||
.UnicodeString = {LANGUAGE_ID_ENG}
|
||||
};
|
||||
|
||||
/** 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
|
||||
* Descriptor.
|
||||
*/
|
||||
USB_Descriptor_String_t PROGMEM ManufacturerString =
|
||||
{
|
||||
.Header = {.Size = USB_STRING_LEN(11), .Type = DTYPE_String},
|
||||
|
||||
.UnicodeString = L"Dean Camera"
|
||||
};
|
||||
|
||||
/** 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
|
||||
* Descriptor.
|
||||
*/
|
||||
USB_Descriptor_String_t PROGMEM ProductString =
|
||||
{
|
||||
.Header = {.Size = USB_STRING_LEN(28), .Type = DTYPE_String},
|
||||
|
||||
.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"
|
||||
* 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
|
||||
* is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the
|
||||
* USB host.
|
||||
*/
|
||||
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 DescriptorNumber = (wValue & 0xFF);
|
||||
|
||||
void* Address = NULL;
|
||||
uint16_t Size = NO_DESCRIPTOR;
|
||||
|
||||
switch (DescriptorType)
|
||||
{
|
||||
case DTYPE_Device:
|
||||
Address = (void*)&DeviceDescriptor;
|
||||
Size = sizeof(USB_Descriptor_Device_t);
|
||||
break;
|
||||
case DTYPE_Configuration:
|
||||
Address = (void*)&ConfigurationDescriptor;
|
||||
Size = sizeof(USB_Descriptor_Configuration_t);
|
||||
break;
|
||||
case DTYPE_String:
|
||||
switch (DescriptorNumber)
|
||||
{
|
||||
case 0x00:
|
||||
Address = (void*)&LanguageString;
|
||||
Size = pgm_read_byte(&LanguageString.Header.Size);
|
||||
break;
|
||||
case 0x01:
|
||||
Address = (void*)&ManufacturerString;
|
||||
Size = pgm_read_byte(&ManufacturerString.Header.Size);
|
||||
break;
|
||||
case 0x02:
|
||||
Address = (void*)&ProductString;
|
||||
Size = pgm_read_byte(&ProductString.Header.Size);
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
case DTYPE_HID:
|
||||
if (!(wIndex))
|
||||
{
|
||||
Address = (void*)&ConfigurationDescriptor.HID1_KeyboardHID;
|
||||
Size = sizeof(USB_HID_Descriptor_t);
|
||||
}
|
||||
else
|
||||
{
|
||||
Address = (void*)&ConfigurationDescriptor.HID2_MouseHID;
|
||||
Size = sizeof(USB_HID_Descriptor_t);
|
||||
}
|
||||
break;
|
||||
case DTYPE_Report:
|
||||
if (!(wIndex))
|
||||
{
|
||||
Address = (void*)&KeyboardReport;
|
||||
Size = sizeof(KeyboardReport);
|
||||
}
|
||||
else
|
||||
{
|
||||
Address = (void*)&MouseReport;
|
||||
Size = sizeof(MouseReport);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
*DescriptorAddress = Address;
|
||||
return Size;
|
||||
}
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
Copyright 2010 Denver Gingerich (denver [at] ossguy [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* 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
|
||||
* the device's capabilities and functions.
|
||||
*/
|
||||
|
||||
#include "Descriptors.h"
|
||||
|
||||
/** 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
|
||||
* 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
|
||||
* more details on HID report descriptors.
|
||||
*
|
||||
* This descriptor describes the mouse HID interface's report structure.
|
||||
*/
|
||||
USB_Descriptor_HIDReport_Datatype_t PROGMEM MouseReport[] =
|
||||
{
|
||||
0x05, 0x01, /* Usage Page (Generic Desktop) */
|
||||
0x09, 0x02, /* Usage (Mouse) */
|
||||
0xA1, 0x01, /* Collection (Application) */
|
||||
0x09, 0x01, /* Usage (Pointer) */
|
||||
0xA1, 0x00, /* Collection (Physical) */
|
||||
0x95, 0x03, /* Report Count (3) */
|
||||
0x75, 0x01, /* Report Size (1) */
|
||||
0x05, 0x09, /* Usage Page (Button) */
|
||||
0x19, 0x01, /* Usage Minimum (Button 1) */
|
||||
0x29, 0x03, /* Usage Maximum (Button 3) */
|
||||
0x15, 0x00, /* Logical Minimum (0) */
|
||||
0x25, 0x01, /* Logical Maximum (1) */
|
||||
0x81, 0x02, /* Input (Data, Variable, Absolute) */
|
||||
0x95, 0x01, /* Report Count (1) */
|
||||
0x75, 0x05, /* Report Size (5) */
|
||||
0x81, 0x01, /* Input (Constant) */
|
||||
0x75, 0x08, /* Report Size (8) */
|
||||
0x95, 0x02, /* Report Count (2) */
|
||||
0x05, 0x01, /* Usage Page (Generic Desktop Control) */
|
||||
0x09, 0x30, /* Usage X */
|
||||
0x09, 0x31, /* Usage Y */
|
||||
0x15, 0x81, /* Logical Minimum (-127) */
|
||||
0x25, 0x7F, /* Logical Maximum (127) */
|
||||
0x81, 0x06, /* Input (Data, Variable, Relative) */
|
||||
0xC0, /* End Collection */
|
||||
0xC0, /* End Collection */
|
||||
};
|
||||
|
||||
/** Same as the MouseReport structure, but defines the keyboard HID interface's report structure. */
|
||||
USB_Descriptor_HIDReport_Datatype_t PROGMEM KeyboardReport[] =
|
||||
{
|
||||
0x05, 0x01, /* Usage Page (Generic Desktop) */
|
||||
0x09, 0x06, /* Usage (Keyboard) */
|
||||
0xa1, 0x01, /* Collection (Application) */
|
||||
0x75, 0x01, /* Report Size (1) */
|
||||
0x95, 0x08, /* Report Count (8) */
|
||||
0x05, 0x07, /* Usage Page (Key Codes) */
|
||||
0x19, 0xe0, /* Usage Minimum (Keyboard LeftControl) */
|
||||
0x29, 0xe7, /* Usage Maximum (Keyboard Right GUI) */
|
||||
0x15, 0x00, /* Logical Minimum (0) */
|
||||
0x25, 0x01, /* Logical Maximum (1) */
|
||||
0x81, 0x02, /* Input (Data, Variable, Absolute) */
|
||||
0x95, 0x01, /* Report Count (1) */
|
||||
0x75, 0x08, /* Report Size (8) */
|
||||
0x81, 0x03, /* Input (Const, Variable, Absolute) */
|
||||
0x95, 0x05, /* Report Count (5) */
|
||||
0x75, 0x01, /* Report Size (1) */
|
||||
0x05, 0x08, /* Usage Page (LEDs) */
|
||||
0x19, 0x01, /* Usage Minimum (Num Lock) */
|
||||
0x29, 0x05, /* Usage Maximum (Kana) */
|
||||
0x91, 0x02, /* Output (Data, Variable, Absolute) */
|
||||
0x95, 0x01, /* Report Count (1) */
|
||||
0x75, 0x03, /* Report Size (3) */
|
||||
0x91, 0x03, /* Output (Const, Variable, Absolute) */
|
||||
0x95, 0x06, /* Report Count (6) */
|
||||
0x75, 0x08, /* Report Size (8) */
|
||||
0x15, 0x00, /* Logical Minimum (0) */
|
||||
0x25, 0x65, /* Logical Maximum (101) */
|
||||
0x05, 0x07, /* Usage Page (Keyboard) */
|
||||
0x19, 0x00, /* Usage Minimum (Reserved (no event indicated)) */
|
||||
0x29, 0x65, /* Usage Maximum (Keyboard Application) */
|
||||
0x81, 0x00, /* Input (Data, Array, Absolute) */
|
||||
0xC0 /* End Collection */
|
||||
};
|
||||
|
||||
/** Device descriptor structure. This descriptor, located in FLASH memory, describes the overall
|
||||
* 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
|
||||
* process begins.
|
||||
*/
|
||||
USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device},
|
||||
|
||||
.USBSpecification = VERSION_BCD(01.10),
|
||||
.Class = 0x00,
|
||||
.SubClass = 0x00,
|
||||
.Protocol = 0x00,
|
||||
|
||||
.Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE,
|
||||
|
||||
.VendorID = 0x03EB,
|
||||
.ProductID = 0x204D,
|
||||
.ReleaseNumber = 0x0000,
|
||||
|
||||
.ManufacturerStrIndex = 0x01,
|
||||
.ProductStrIndex = 0x02,
|
||||
.SerialNumStrIndex = NO_DESCRIPTOR,
|
||||
|
||||
.NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS
|
||||
};
|
||||
|
||||
/** 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
|
||||
* 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.
|
||||
*/
|
||||
USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
|
||||
{
|
||||
.Config =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration},
|
||||
|
||||
.TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t),
|
||||
.TotalInterfaces = 2,
|
||||
|
||||
.ConfigurationNumber = 1,
|
||||
.ConfigurationStrIndex = NO_DESCRIPTOR,
|
||||
|
||||
.ConfigAttributes = (USB_CONFIG_ATTR_BUSPOWERED | USB_CONFIG_ATTR_SELFPOWERED),
|
||||
|
||||
.MaxPowerConsumption = USB_CONFIG_POWER_MA(100)
|
||||
},
|
||||
|
||||
.HID1_KeyboardInterface =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
|
||||
|
||||
.InterfaceNumber = 0x00,
|
||||
.AlternateSetting = 0x00,
|
||||
|
||||
.TotalEndpoints = 1,
|
||||
|
||||
.Class = 0x03,
|
||||
.SubClass = 0x01,
|
||||
.Protocol = HID_BOOT_KEYBOARD_PROTOCOL,
|
||||
|
||||
.InterfaceStrIndex = NO_DESCRIPTOR
|
||||
},
|
||||
|
||||
.HID1_KeyboardHID =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_HID_Descriptor_t), .Type = DTYPE_HID},
|
||||
|
||||
.HIDSpec = VERSION_BCD(01.11),
|
||||
.CountryCode = 0x00,
|
||||
.TotalReportDescriptors = 1,
|
||||
.HIDReportType = DTYPE_Report,
|
||||
.HIDReportLength = sizeof(KeyboardReport)
|
||||
},
|
||||
|
||||
.HID1_ReportINEndpoint =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
|
||||
|
||||
.EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_IN | KEYBOARD_IN_EPNUM),
|
||||
.Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
|
||||
.EndpointSize = HID_EPSIZE,
|
||||
.PollingIntervalMS = 0x0A
|
||||
},
|
||||
|
||||
.HID2_MouseInterface =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
|
||||
|
||||
.InterfaceNumber = 0x01,
|
||||
.AlternateSetting = 0x00,
|
||||
|
||||
.TotalEndpoints = 1,
|
||||
|
||||
.Class = 0x03,
|
||||
.SubClass = 0x01,
|
||||
.Protocol = HID_BOOT_MOUSE_PROTOCOL,
|
||||
|
||||
.InterfaceStrIndex = NO_DESCRIPTOR
|
||||
},
|
||||
|
||||
.HID2_MouseHID =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_HID_Descriptor_t), .Type = DTYPE_HID},
|
||||
|
||||
.HIDSpec = VERSION_BCD(01.11),
|
||||
.CountryCode = 0x00,
|
||||
.TotalReportDescriptors = 1,
|
||||
.HIDReportType = DTYPE_Report,
|
||||
.HIDReportLength = sizeof(MouseReport)
|
||||
},
|
||||
|
||||
.HID2_ReportINEndpoint =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
|
||||
|
||||
.EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_IN | MOUSE_IN_EPNUM),
|
||||
.Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
|
||||
.EndpointSize = HID_EPSIZE,
|
||||
.PollingIntervalMS = 0x0A
|
||||
}
|
||||
};
|
||||
|
||||
/** 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
|
||||
* via the language ID table available at USB.org what languages the device supports for its string descriptors.
|
||||
*/
|
||||
USB_Descriptor_String_t PROGMEM LanguageString =
|
||||
{
|
||||
.Header = {.Size = USB_STRING_LEN(1), .Type = DTYPE_String},
|
||||
|
||||
.UnicodeString = {LANGUAGE_ID_ENG}
|
||||
};
|
||||
|
||||
/** 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
|
||||
* Descriptor.
|
||||
*/
|
||||
USB_Descriptor_String_t PROGMEM ManufacturerString =
|
||||
{
|
||||
.Header = {.Size = USB_STRING_LEN(11), .Type = DTYPE_String},
|
||||
|
||||
.UnicodeString = L"Dean Camera"
|
||||
};
|
||||
|
||||
/** 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
|
||||
* Descriptor.
|
||||
*/
|
||||
USB_Descriptor_String_t PROGMEM ProductString =
|
||||
{
|
||||
.Header = {.Size = USB_STRING_LEN(28), .Type = DTYPE_String},
|
||||
|
||||
.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"
|
||||
* 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
|
||||
* is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the
|
||||
* USB host.
|
||||
*/
|
||||
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 DescriptorNumber = (wValue & 0xFF);
|
||||
|
||||
void* Address = NULL;
|
||||
uint16_t Size = NO_DESCRIPTOR;
|
||||
|
||||
switch (DescriptorType)
|
||||
{
|
||||
case DTYPE_Device:
|
||||
Address = (void*)&DeviceDescriptor;
|
||||
Size = sizeof(USB_Descriptor_Device_t);
|
||||
break;
|
||||
case DTYPE_Configuration:
|
||||
Address = (void*)&ConfigurationDescriptor;
|
||||
Size = sizeof(USB_Descriptor_Configuration_t);
|
||||
break;
|
||||
case DTYPE_String:
|
||||
switch (DescriptorNumber)
|
||||
{
|
||||
case 0x00:
|
||||
Address = (void*)&LanguageString;
|
||||
Size = pgm_read_byte(&LanguageString.Header.Size);
|
||||
break;
|
||||
case 0x01:
|
||||
Address = (void*)&ManufacturerString;
|
||||
Size = pgm_read_byte(&ManufacturerString.Header.Size);
|
||||
break;
|
||||
case 0x02:
|
||||
Address = (void*)&ProductString;
|
||||
Size = pgm_read_byte(&ProductString.Header.Size);
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
case DTYPE_HID:
|
||||
if (!(wIndex))
|
||||
{
|
||||
Address = (void*)&ConfigurationDescriptor.HID1_KeyboardHID;
|
||||
Size = sizeof(USB_HID_Descriptor_t);
|
||||
}
|
||||
else
|
||||
{
|
||||
Address = (void*)&ConfigurationDescriptor.HID2_MouseHID;
|
||||
Size = sizeof(USB_HID_Descriptor_t);
|
||||
}
|
||||
break;
|
||||
case DTYPE_Report:
|
||||
if (!(wIndex))
|
||||
{
|
||||
Address = (void*)&KeyboardReport;
|
||||
Size = sizeof(KeyboardReport);
|
||||
}
|
||||
else
|
||||
{
|
||||
Address = (void*)&MouseReport;
|
||||
Size = sizeof(MouseReport);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
*DescriptorAddress = Address;
|
||||
return Size;
|
||||
}
|
||||
|
@ -1,76 +1,76 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
Copyright 2010 Denver Gingerich (denver [at] ossguy [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Header file for Descriptors.c.
|
||||
*/
|
||||
|
||||
#ifndef _DESCRIPTORS_H_
|
||||
#define _DESCRIPTORS_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/pgmspace.h>
|
||||
|
||||
#include <LUFA/Drivers/USB/USB.h>
|
||||
#include <LUFA/Drivers/USB/Class/HID.h>
|
||||
|
||||
/* Type Defines: */
|
||||
/** 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
|
||||
* vary between devices, and which describe the device's usage to the host.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
USB_Descriptor_Configuration_Header_t Config;
|
||||
USB_Descriptor_Interface_t HID1_KeyboardInterface;
|
||||
USB_HID_Descriptor_t HID1_KeyboardHID;
|
||||
USB_Descriptor_Endpoint_t HID1_ReportINEndpoint;
|
||||
USB_Descriptor_Interface_t HID2_MouseInterface;
|
||||
USB_HID_Descriptor_t HID2_MouseHID;
|
||||
USB_Descriptor_Endpoint_t HID2_ReportINEndpoint;
|
||||
} USB_Descriptor_Configuration_t;
|
||||
|
||||
/* Macros: */
|
||||
/** Endpoint number of the Keyboard HID reporting IN endpoint. */
|
||||
#define KEYBOARD_IN_EPNUM 1
|
||||
|
||||
/** Endpoint number of the Mouse HID reporting IN endpoint. */
|
||||
#define MOUSE_IN_EPNUM 3
|
||||
|
||||
/** Size in bytes of each of the HID reporting IN and OUT endpoints. */
|
||||
#define HID_EPSIZE 8
|
||||
|
||||
/* Function Prototypes: */
|
||||
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);
|
||||
|
||||
#endif
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
Copyright 2010 Denver Gingerich (denver [at] ossguy [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Header file for Descriptors.c.
|
||||
*/
|
||||
|
||||
#ifndef _DESCRIPTORS_H_
|
||||
#define _DESCRIPTORS_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/pgmspace.h>
|
||||
|
||||
#include <LUFA/Drivers/USB/USB.h>
|
||||
#include <LUFA/Drivers/USB/Class/HID.h>
|
||||
|
||||
/* Type Defines: */
|
||||
/** 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
|
||||
* vary between devices, and which describe the device's usage to the host.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
USB_Descriptor_Configuration_Header_t Config;
|
||||
USB_Descriptor_Interface_t HID1_KeyboardInterface;
|
||||
USB_HID_Descriptor_t HID1_KeyboardHID;
|
||||
USB_Descriptor_Endpoint_t HID1_ReportINEndpoint;
|
||||
USB_Descriptor_Interface_t HID2_MouseInterface;
|
||||
USB_HID_Descriptor_t HID2_MouseHID;
|
||||
USB_Descriptor_Endpoint_t HID2_ReportINEndpoint;
|
||||
} USB_Descriptor_Configuration_t;
|
||||
|
||||
/* Macros: */
|
||||
/** Endpoint number of the Keyboard HID reporting IN endpoint. */
|
||||
#define KEYBOARD_IN_EPNUM 1
|
||||
|
||||
/** Endpoint number of the Mouse HID reporting IN endpoint. */
|
||||
#define MOUSE_IN_EPNUM 3
|
||||
|
||||
/** Size in bytes of each of the HID reporting IN and OUT endpoints. */
|
||||
#define HID_EPSIZE 8
|
||||
|
||||
/* Function Prototypes: */
|
||||
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);
|
||||
|
||||
#endif
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,253 +1,253 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Main source file for the KeyboardMouse demo. This file contains the main tasks of
|
||||
* the demo and is responsible for the initial application hardware configuration.
|
||||
*/
|
||||
|
||||
#include "KeyboardMouse.h"
|
||||
|
||||
/** 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)];
|
||||
|
||||
/** 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)];
|
||||
|
||||
/** LUFA HID Class driver interface configuration and state information. This structure is
|
||||
* passed to all HID Class driver functions, so that multiple instances of the same class
|
||||
* within a device can be differentiated from one another. This is for the keyboard HID
|
||||
* interface within the device.
|
||||
*/
|
||||
USB_ClassInfo_HID_Device_t Keyboard_HID_Interface =
|
||||
{
|
||||
.Config =
|
||||
{
|
||||
.InterfaceNumber = 0,
|
||||
|
||||
.ReportINEndpointNumber = KEYBOARD_IN_EPNUM,
|
||||
.ReportINEndpointSize = HID_EPSIZE,
|
||||
.ReportINEndpointDoubleBank = false,
|
||||
|
||||
.PrevReportINBuffer = PrevKeyboardHIDReportBuffer,
|
||||
.PrevReportINBufferSize = sizeof(PrevKeyboardHIDReportBuffer),
|
||||
},
|
||||
};
|
||||
|
||||
/** LUFA HID Class driver interface configuration and state information. This structure is
|
||||
* passed to all HID Class driver functions, so that multiple instances of the same class
|
||||
* within a device can be differentiated from one another. This is for the mouse HID
|
||||
* interface within the device.
|
||||
*/
|
||||
USB_ClassInfo_HID_Device_t Mouse_HID_Interface =
|
||||
{
|
||||
.Config =
|
||||
{
|
||||
.InterfaceNumber = 1,
|
||||
|
||||
.ReportINEndpointNumber = MOUSE_IN_EPNUM,
|
||||
.ReportINEndpointSize = HID_EPSIZE,
|
||||
|
||||
.PrevReportINBuffer = PrevMouseHIDReportBuffer,
|
||||
.PrevReportINBufferSize = sizeof(PrevMouseHIDReportBuffer),
|
||||
},
|
||||
};
|
||||
|
||||
/** Main program entry point. This routine contains the overall program flow, including initial
|
||||
* setup of all components and the main program loop.
|
||||
*/
|
||||
int main(void)
|
||||
{
|
||||
SetupHardware();
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
|
||||
sei();
|
||||
|
||||
for (;;)
|
||||
{
|
||||
HID_Device_USBTask(&Keyboard_HID_Interface);
|
||||
HID_Device_USBTask(&Mouse_HID_Interface);
|
||||
USB_USBTask();
|
||||
}
|
||||
}
|
||||
|
||||
/** Configures the board hardware and chip peripherals for the demo's functionality. */
|
||||
void SetupHardware()
|
||||
{
|
||||
/* Disable watchdog if enabled by bootloader/fuses */
|
||||
MCUSR &= ~(1 << WDRF);
|
||||
wdt_disable();
|
||||
|
||||
/* Disable clock division */
|
||||
clock_prescale_set(clock_div_1);
|
||||
|
||||
/* Hardware Initialization */
|
||||
Joystick_Init();
|
||||
LEDs_Init();
|
||||
USB_Init();
|
||||
}
|
||||
|
||||
/** Event handler for the library USB Connection event. */
|
||||
void EVENT_USB_Device_Connect(void)
|
||||
{
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
|
||||
}
|
||||
|
||||
/** Event handler for the library USB Disconnection event. */
|
||||
void EVENT_USB_Device_Disconnect(void)
|
||||
{
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
|
||||
}
|
||||
|
||||
/** Event handler for the library USB Configuration Changed event. */
|
||||
void EVENT_USB_Device_ConfigurationChanged(void)
|
||||
{
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
|
||||
if (!(HID_Device_ConfigureEndpoints(&Keyboard_HID_Interface)))
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
if (!(HID_Device_ConfigureEndpoints(&Mouse_HID_Interface)))
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
USB_Device_EnableSOFEvents();
|
||||
}
|
||||
|
||||
/** Event handler for the library USB Unhandled Control Request event. */
|
||||
void EVENT_USB_Device_UnhandledControlRequest(void)
|
||||
{
|
||||
HID_Device_ProcessControlRequest(&Keyboard_HID_Interface);
|
||||
HID_Device_ProcessControlRequest(&Mouse_HID_Interface);
|
||||
}
|
||||
|
||||
/** Event handler for the USB device Start Of Frame event. */
|
||||
void EVENT_USB_Device_StartOfFrame(void)
|
||||
{
|
||||
HID_Device_MillisecondElapsed(&Keyboard_HID_Interface);
|
||||
HID_Device_MillisecondElapsed(&Mouse_HID_Interface);
|
||||
}
|
||||
|
||||
/** 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,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[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
|
||||
*
|
||||
* \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,
|
||||
const uint8_t ReportType, void* ReportData, uint16_t* ReportSize)
|
||||
{
|
||||
uint8_t JoyStatus_LCL = Joystick_GetStatus();
|
||||
uint8_t ButtonStatus_LCL = Buttons_GetStatus();
|
||||
|
||||
/* Determine which interface must have its report generated */
|
||||
if (HIDInterfaceInfo == &Keyboard_HID_Interface)
|
||||
{
|
||||
USB_KeyboardReport_Data_t* KeyboardReport = (USB_KeyboardReport_Data_t*)ReportData;
|
||||
|
||||
/* If first board button not being held down, no keyboard report */
|
||||
if (!(ButtonStatus_LCL & BUTTONS_BUTTON1))
|
||||
return 0;
|
||||
|
||||
KeyboardReport->Modifier = HID_KEYBOARD_MODIFER_LEFTSHIFT;
|
||||
|
||||
if (JoyStatus_LCL & JOY_UP)
|
||||
KeyboardReport->KeyCode[0] = 0x04; // A
|
||||
else if (JoyStatus_LCL & JOY_DOWN)
|
||||
KeyboardReport->KeyCode[0] = 0x05; // B
|
||||
|
||||
if (JoyStatus_LCL & JOY_LEFT)
|
||||
KeyboardReport->KeyCode[0] = 0x06; // C
|
||||
else if (JoyStatus_LCL & JOY_RIGHT)
|
||||
KeyboardReport->KeyCode[0] = 0x07; // D
|
||||
|
||||
if (JoyStatus_LCL & JOY_PRESS)
|
||||
KeyboardReport->KeyCode[0] = 0x08; // E
|
||||
|
||||
*ReportSize = sizeof(USB_KeyboardReport_Data_t);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
USB_MouseReport_Data_t* MouseReport = (USB_MouseReport_Data_t*)ReportData;
|
||||
|
||||
/* If first board button being held down, no mouse report */
|
||||
if (ButtonStatus_LCL & BUTTONS_BUTTON1)
|
||||
return 0;
|
||||
|
||||
if (JoyStatus_LCL & JOY_UP)
|
||||
MouseReport->Y = -1;
|
||||
else if (JoyStatus_LCL & JOY_DOWN)
|
||||
MouseReport->Y = 1;
|
||||
|
||||
if (JoyStatus_LCL & JOY_LEFT)
|
||||
MouseReport->X = -1;
|
||||
else if (JoyStatus_LCL & JOY_RIGHT)
|
||||
MouseReport->X = 1;
|
||||
|
||||
if (JoyStatus_LCL & JOY_PRESS)
|
||||
MouseReport->Button |= (1 << 0);
|
||||
|
||||
*ReportSize = sizeof(USB_MouseReport_Data_t);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/** 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] 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] 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,
|
||||
const void* ReportData, const uint16_t ReportSize)
|
||||
{
|
||||
if (HIDInterfaceInfo == &Keyboard_HID_Interface)
|
||||
{
|
||||
uint8_t LEDMask = LEDS_NO_LEDS;
|
||||
uint8_t* LEDReport = (uint8_t*)ReportData;
|
||||
|
||||
if (*LEDReport & HID_KEYBOARD_LED_NUMLOCK)
|
||||
LEDMask |= LEDS_LED1;
|
||||
|
||||
if (*LEDReport & HID_KEYBOARD_LED_CAPSLOCK)
|
||||
LEDMask |= LEDS_LED3;
|
||||
|
||||
if (*LEDReport & HID_KEYBOARD_LED_SCROLLLOCK)
|
||||
LEDMask |= LEDS_LED4;
|
||||
|
||||
LEDs_SetAllLEDs(LEDMask);
|
||||
}
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Main source file for the KeyboardMouse demo. This file contains the main tasks of
|
||||
* the demo and is responsible for the initial application hardware configuration.
|
||||
*/
|
||||
|
||||
#include "KeyboardMouse.h"
|
||||
|
||||
/** 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)];
|
||||
|
||||
/** 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)];
|
||||
|
||||
/** LUFA HID Class driver interface configuration and state information. This structure is
|
||||
* passed to all HID Class driver functions, so that multiple instances of the same class
|
||||
* within a device can be differentiated from one another. This is for the keyboard HID
|
||||
* interface within the device.
|
||||
*/
|
||||
USB_ClassInfo_HID_Device_t Keyboard_HID_Interface =
|
||||
{
|
||||
.Config =
|
||||
{
|
||||
.InterfaceNumber = 0,
|
||||
|
||||
.ReportINEndpointNumber = KEYBOARD_IN_EPNUM,
|
||||
.ReportINEndpointSize = HID_EPSIZE,
|
||||
.ReportINEndpointDoubleBank = false,
|
||||
|
||||
.PrevReportINBuffer = PrevKeyboardHIDReportBuffer,
|
||||
.PrevReportINBufferSize = sizeof(PrevKeyboardHIDReportBuffer),
|
||||
},
|
||||
};
|
||||
|
||||
/** LUFA HID Class driver interface configuration and state information. This structure is
|
||||
* passed to all HID Class driver functions, so that multiple instances of the same class
|
||||
* within a device can be differentiated from one another. This is for the mouse HID
|
||||
* interface within the device.
|
||||
*/
|
||||
USB_ClassInfo_HID_Device_t Mouse_HID_Interface =
|
||||
{
|
||||
.Config =
|
||||
{
|
||||
.InterfaceNumber = 1,
|
||||
|
||||
.ReportINEndpointNumber = MOUSE_IN_EPNUM,
|
||||
.ReportINEndpointSize = HID_EPSIZE,
|
||||
|
||||
.PrevReportINBuffer = PrevMouseHIDReportBuffer,
|
||||
.PrevReportINBufferSize = sizeof(PrevMouseHIDReportBuffer),
|
||||
},
|
||||
};
|
||||
|
||||
/** Main program entry point. This routine contains the overall program flow, including initial
|
||||
* setup of all components and the main program loop.
|
||||
*/
|
||||
int main(void)
|
||||
{
|
||||
SetupHardware();
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
|
||||
sei();
|
||||
|
||||
for (;;)
|
||||
{
|
||||
HID_Device_USBTask(&Keyboard_HID_Interface);
|
||||
HID_Device_USBTask(&Mouse_HID_Interface);
|
||||
USB_USBTask();
|
||||
}
|
||||
}
|
||||
|
||||
/** Configures the board hardware and chip peripherals for the demo's functionality. */
|
||||
void SetupHardware()
|
||||
{
|
||||
/* Disable watchdog if enabled by bootloader/fuses */
|
||||
MCUSR &= ~(1 << WDRF);
|
||||
wdt_disable();
|
||||
|
||||
/* Disable clock division */
|
||||
clock_prescale_set(clock_div_1);
|
||||
|
||||
/* Hardware Initialization */
|
||||
Joystick_Init();
|
||||
LEDs_Init();
|
||||
USB_Init();
|
||||
}
|
||||
|
||||
/** Event handler for the library USB Connection event. */
|
||||
void EVENT_USB_Device_Connect(void)
|
||||
{
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
|
||||
}
|
||||
|
||||
/** Event handler for the library USB Disconnection event. */
|
||||
void EVENT_USB_Device_Disconnect(void)
|
||||
{
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
|
||||
}
|
||||
|
||||
/** Event handler for the library USB Configuration Changed event. */
|
||||
void EVENT_USB_Device_ConfigurationChanged(void)
|
||||
{
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
|
||||
if (!(HID_Device_ConfigureEndpoints(&Keyboard_HID_Interface)))
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
if (!(HID_Device_ConfigureEndpoints(&Mouse_HID_Interface)))
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
USB_Device_EnableSOFEvents();
|
||||
}
|
||||
|
||||
/** Event handler for the library USB Unhandled Control Request event. */
|
||||
void EVENT_USB_Device_UnhandledControlRequest(void)
|
||||
{
|
||||
HID_Device_ProcessControlRequest(&Keyboard_HID_Interface);
|
||||
HID_Device_ProcessControlRequest(&Mouse_HID_Interface);
|
||||
}
|
||||
|
||||
/** Event handler for the USB device Start Of Frame event. */
|
||||
void EVENT_USB_Device_StartOfFrame(void)
|
||||
{
|
||||
HID_Device_MillisecondElapsed(&Keyboard_HID_Interface);
|
||||
HID_Device_MillisecondElapsed(&Mouse_HID_Interface);
|
||||
}
|
||||
|
||||
/** 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,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[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
|
||||
*
|
||||
* \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,
|
||||
const uint8_t ReportType, void* ReportData, uint16_t* ReportSize)
|
||||
{
|
||||
uint8_t JoyStatus_LCL = Joystick_GetStatus();
|
||||
uint8_t ButtonStatus_LCL = Buttons_GetStatus();
|
||||
|
||||
/* Determine which interface must have its report generated */
|
||||
if (HIDInterfaceInfo == &Keyboard_HID_Interface)
|
||||
{
|
||||
USB_KeyboardReport_Data_t* KeyboardReport = (USB_KeyboardReport_Data_t*)ReportData;
|
||||
|
||||
/* If first board button not being held down, no keyboard report */
|
||||
if (!(ButtonStatus_LCL & BUTTONS_BUTTON1))
|
||||
return 0;
|
||||
|
||||
KeyboardReport->Modifier = HID_KEYBOARD_MODIFER_LEFTSHIFT;
|
||||
|
||||
if (JoyStatus_LCL & JOY_UP)
|
||||
KeyboardReport->KeyCode[0] = 0x04; // A
|
||||
else if (JoyStatus_LCL & JOY_DOWN)
|
||||
KeyboardReport->KeyCode[0] = 0x05; // B
|
||||
|
||||
if (JoyStatus_LCL & JOY_LEFT)
|
||||
KeyboardReport->KeyCode[0] = 0x06; // C
|
||||
else if (JoyStatus_LCL & JOY_RIGHT)
|
||||
KeyboardReport->KeyCode[0] = 0x07; // D
|
||||
|
||||
if (JoyStatus_LCL & JOY_PRESS)
|
||||
KeyboardReport->KeyCode[0] = 0x08; // E
|
||||
|
||||
*ReportSize = sizeof(USB_KeyboardReport_Data_t);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
USB_MouseReport_Data_t* MouseReport = (USB_MouseReport_Data_t*)ReportData;
|
||||
|
||||
/* If first board button being held down, no mouse report */
|
||||
if (ButtonStatus_LCL & BUTTONS_BUTTON1)
|
||||
return 0;
|
||||
|
||||
if (JoyStatus_LCL & JOY_UP)
|
||||
MouseReport->Y = -1;
|
||||
else if (JoyStatus_LCL & JOY_DOWN)
|
||||
MouseReport->Y = 1;
|
||||
|
||||
if (JoyStatus_LCL & JOY_LEFT)
|
||||
MouseReport->X = -1;
|
||||
else if (JoyStatus_LCL & JOY_RIGHT)
|
||||
MouseReport->X = 1;
|
||||
|
||||
if (JoyStatus_LCL & JOY_PRESS)
|
||||
MouseReport->Button |= (1 << 0);
|
||||
|
||||
*ReportSize = sizeof(USB_MouseReport_Data_t);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/** 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] 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] 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,
|
||||
const void* ReportData, const uint16_t ReportSize)
|
||||
{
|
||||
if (HIDInterfaceInfo == &Keyboard_HID_Interface)
|
||||
{
|
||||
uint8_t LEDMask = LEDS_NO_LEDS;
|
||||
uint8_t* LEDReport = (uint8_t*)ReportData;
|
||||
|
||||
if (*LEDReport & HID_KEYBOARD_LED_NUMLOCK)
|
||||
LEDMask |= LEDS_LED1;
|
||||
|
||||
if (*LEDReport & HID_KEYBOARD_LED_CAPSLOCK)
|
||||
LEDMask |= LEDS_LED3;
|
||||
|
||||
if (*LEDReport & HID_KEYBOARD_LED_SCROLLLOCK)
|
||||
LEDMask |= LEDS_LED4;
|
||||
|
||||
LEDs_SetAllLEDs(LEDMask);
|
||||
}
|
||||
}
|
@ -1,79 +1,79 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
Copyright 2010 Denver Gingerich (denver [at] ossguy [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
#ifndef _KEYBOARD_MOUSE_H_
|
||||
#define _KEYBOARD_MOUSE_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/io.h>
|
||||
#include <avr/wdt.h>
|
||||
#include <avr/power.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "Descriptors.h"
|
||||
|
||||
#include <LUFA/Version.h>
|
||||
#include <LUFA/Drivers/Board/Joystick.h>
|
||||
#include <LUFA/Drivers/Board/LEDs.h>
|
||||
#include <LUFA/Drivers/Board/Buttons.h>
|
||||
#include <LUFA/Drivers/USB/USB.h>
|
||||
#include <LUFA/Drivers/USB/Class/HID.h>
|
||||
|
||||
/* Macros: */
|
||||
/** LED mask for the library LED driver, to indicate that the USB interface is not ready. */
|
||||
#define LEDMASK_USB_NOTREADY LEDS_LED1
|
||||
|
||||
/** LED mask for the library LED driver, to indicate that the USB interface is enumerating. */
|
||||
#define LEDMASK_USB_ENUMERATING (LEDS_LED2 | LEDS_LED3)
|
||||
|
||||
/** LED mask for the library LED driver, to indicate that the USB interface is ready. */
|
||||
#define LEDMASK_USB_READY (LEDS_LED2 | LEDS_LED4)
|
||||
|
||||
/** LED mask for the library LED driver, to indicate that an error has occurred in the USB interface. */
|
||||
#define LEDMASK_USB_ERROR (LEDS_LED1 | LEDS_LED3)
|
||||
|
||||
/* Function Prototypes: */
|
||||
void SetupHardware(void);
|
||||
|
||||
void EVENT_USB_Device_Connect(void);
|
||||
void EVENT_USB_Device_Disconnect(void);
|
||||
void EVENT_USB_Device_ConfigurationChanged(void);
|
||||
void EVENT_USB_Device_UnhandledControlRequest(void);
|
||||
void EVENT_USB_Device_StartOfFrame(void);
|
||||
|
||||
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);
|
||||
void CALLBACK_HID_Device_ProcessHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, const uint8_t ReportID,
|
||||
const void* ReportData, const uint16_t ReportSize);
|
||||
|
||||
#endif
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
Copyright 2010 Denver Gingerich (denver [at] ossguy [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
#ifndef _KEYBOARD_MOUSE_H_
|
||||
#define _KEYBOARD_MOUSE_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/io.h>
|
||||
#include <avr/wdt.h>
|
||||
#include <avr/power.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "Descriptors.h"
|
||||
|
||||
#include <LUFA/Version.h>
|
||||
#include <LUFA/Drivers/Board/Joystick.h>
|
||||
#include <LUFA/Drivers/Board/LEDs.h>
|
||||
#include <LUFA/Drivers/Board/Buttons.h>
|
||||
#include <LUFA/Drivers/USB/USB.h>
|
||||
#include <LUFA/Drivers/USB/Class/HID.h>
|
||||
|
||||
/* Macros: */
|
||||
/** LED mask for the library LED driver, to indicate that the USB interface is not ready. */
|
||||
#define LEDMASK_USB_NOTREADY LEDS_LED1
|
||||
|
||||
/** LED mask for the library LED driver, to indicate that the USB interface is enumerating. */
|
||||
#define LEDMASK_USB_ENUMERATING (LEDS_LED2 | LEDS_LED3)
|
||||
|
||||
/** LED mask for the library LED driver, to indicate that the USB interface is ready. */
|
||||
#define LEDMASK_USB_READY (LEDS_LED2 | LEDS_LED4)
|
||||
|
||||
/** LED mask for the library LED driver, to indicate that an error has occurred in the USB interface. */
|
||||
#define LEDMASK_USB_ERROR (LEDS_LED1 | LEDS_LED3)
|
||||
|
||||
/* Function Prototypes: */
|
||||
void SetupHardware(void);
|
||||
|
||||
void EVENT_USB_Device_Connect(void);
|
||||
void EVENT_USB_Device_Disconnect(void);
|
||||
void EVENT_USB_Device_ConfigurationChanged(void);
|
||||
void EVENT_USB_Device_UnhandledControlRequest(void);
|
||||
void EVENT_USB_Device_StartOfFrame(void);
|
||||
|
||||
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);
|
||||
void CALLBACK_HID_Device_ProcessHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, const uint8_t ReportID,
|
||||
const void* ReportData, const uint16_t ReportSize);
|
||||
|
||||
#endif
|
||||
|
@ -1,77 +1,77 @@
|
||||
/** \file
|
||||
*
|
||||
* This file contains special DoxyGen information for the generation of the main page and other special
|
||||
* documentation pages. It is not a project source file.
|
||||
*/
|
||||
|
||||
/** \mainpage Dual HID Keyboard and Mouse Device Demo
|
||||
*
|
||||
* \section SSec_Compat Demo Compatibility:
|
||||
*
|
||||
* The following list indicates what microcontrollers are compatible with this demo.
|
||||
*
|
||||
* - Series 7 USB AVRs
|
||||
* - Series 6 USB AVRs
|
||||
* - Series 4 USB AVRs
|
||||
* - Series 2 USB AVRs
|
||||
*
|
||||
* \section SSec_Info USB Information:
|
||||
*
|
||||
* The following table gives a rundown of the USB utilization of this demo.
|
||||
*
|
||||
* <table>
|
||||
* <tr>
|
||||
* <td><b>USB Mode:</b></td>
|
||||
* <td>Device</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>USB Class:</b></td>
|
||||
* <td>Human Interface Device (HID)</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>USB Subclass:</b></td>
|
||||
* <td>N/A</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>Relevant Standards:</b></td>
|
||||
* <td>USBIF HID Specification \n
|
||||
* USBIF HID Usage Tables</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>Usable Speeds:</b></td>
|
||||
* <td>Low Speed Mode \n
|
||||
* Full Speed Mode</td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*
|
||||
* \section SSec_Description Project Description:
|
||||
*
|
||||
* Keyboard/Mouse demonstration application. This gives a simple reference
|
||||
* application for implementing a composite device containing both USB Keyboard
|
||||
* 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
|
||||
* 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).
|
||||
*
|
||||
* 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
|
||||
* pressed. When enabled, 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.
|
||||
*
|
||||
* 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
|
||||
* left-button click.
|
||||
*
|
||||
* \section SSec_Options Project Options
|
||||
*
|
||||
* The following defines can be found in this demo, which can control the demo behaviour when defined, or changed in value.
|
||||
*
|
||||
* <table>
|
||||
* <tr>
|
||||
* <td>
|
||||
* None
|
||||
* </td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*/
|
||||
/** \file
|
||||
*
|
||||
* This file contains special DoxyGen information for the generation of the main page and other special
|
||||
* documentation pages. It is not a project source file.
|
||||
*/
|
||||
|
||||
/** \mainpage Dual HID Keyboard and Mouse Device Demo
|
||||
*
|
||||
* \section SSec_Compat Demo Compatibility:
|
||||
*
|
||||
* The following list indicates what microcontrollers are compatible with this demo.
|
||||
*
|
||||
* - Series 7 USB AVRs
|
||||
* - Series 6 USB AVRs
|
||||
* - Series 4 USB AVRs
|
||||
* - Series 2 USB AVRs
|
||||
*
|
||||
* \section SSec_Info USB Information:
|
||||
*
|
||||
* The following table gives a rundown of the USB utilization of this demo.
|
||||
*
|
||||
* <table>
|
||||
* <tr>
|
||||
* <td><b>USB Mode:</b></td>
|
||||
* <td>Device</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>USB Class:</b></td>
|
||||
* <td>Human Interface Device (HID)</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>USB Subclass:</b></td>
|
||||
* <td>N/A</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>Relevant Standards:</b></td>
|
||||
* <td>USBIF HID Specification \n
|
||||
* USBIF HID Usage Tables</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>Usable Speeds:</b></td>
|
||||
* <td>Low Speed Mode \n
|
||||
* Full Speed Mode</td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*
|
||||
* \section SSec_Description Project Description:
|
||||
*
|
||||
* Keyboard/Mouse demonstration application. This gives a simple reference
|
||||
* application for implementing a composite device containing both USB Keyboard
|
||||
* 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
|
||||
* 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).
|
||||
*
|
||||
* 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
|
||||
* pressed. When enabled, 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.
|
||||
*
|
||||
* 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
|
||||
* left-button click.
|
||||
*
|
||||
* \section SSec_Options Project Options
|
||||
*
|
||||
* The following defines can be found in this demo, which can control the demo behaviour when defined, or changed in value.
|
||||
*
|
||||
* <table>
|
||||
* <tr>
|
||||
* <td>
|
||||
* None
|
||||
* </td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*/
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,326 +1,326 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* 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
|
||||
* the device's capabilities and functions.
|
||||
*/
|
||||
|
||||
#include "Descriptors.h"
|
||||
|
||||
/** Device descriptor structure. This descriptor, located in FLASH memory, describes the overall
|
||||
* 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
|
||||
* process begins.
|
||||
*/
|
||||
USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device},
|
||||
|
||||
.USBSpecification = VERSION_BCD(01.10),
|
||||
.Class = 0x00,
|
||||
.SubClass = 0x00,
|
||||
.Protocol = 0x00,
|
||||
|
||||
.Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE,
|
||||
|
||||
.VendorID = 0x03EB,
|
||||
.ProductID = 0x2048,
|
||||
.ReleaseNumber = 0x0000,
|
||||
|
||||
.ManufacturerStrIndex = 0x01,
|
||||
.ProductStrIndex = 0x02,
|
||||
.SerialNumStrIndex = NO_DESCRIPTOR,
|
||||
|
||||
.NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS
|
||||
};
|
||||
|
||||
/** 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
|
||||
* 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.
|
||||
*/
|
||||
USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
|
||||
{
|
||||
.Config =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration},
|
||||
|
||||
.TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t),
|
||||
.TotalInterfaces = 2,
|
||||
|
||||
.ConfigurationNumber = 1,
|
||||
.ConfigurationStrIndex = NO_DESCRIPTOR,
|
||||
|
||||
.ConfigAttributes = (USB_CONFIG_ATTR_BUSPOWERED | USB_CONFIG_ATTR_SELFPOWERED),
|
||||
|
||||
.MaxPowerConsumption = USB_CONFIG_POWER_MA(100)
|
||||
},
|
||||
|
||||
.Audio_ControlInterface =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
|
||||
|
||||
.InterfaceNumber = 0,
|
||||
.AlternateSetting = 0,
|
||||
|
||||
.TotalEndpoints = 0,
|
||||
|
||||
.Class = 0x01,
|
||||
.SubClass = 0x01,
|
||||
.Protocol = 0x00,
|
||||
|
||||
.InterfaceStrIndex = NO_DESCRIPTOR
|
||||
},
|
||||
|
||||
.Audio_ControlInterface_SPC =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Audio_Interface_AC_t), .Type = DTYPE_AudioInterface},
|
||||
.Subtype = DSUBTYPE_Header,
|
||||
|
||||
.ACSpecification = VERSION_BCD(01.00),
|
||||
.TotalLength = sizeof(USB_Audio_Interface_AC_t),
|
||||
|
||||
.InCollection = 1,
|
||||
.InterfaceNumbers = {1},
|
||||
},
|
||||
|
||||
.Audio_StreamInterface =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
|
||||
|
||||
.InterfaceNumber = 1,
|
||||
.AlternateSetting = 0,
|
||||
|
||||
.TotalEndpoints = 2,
|
||||
|
||||
.Class = 0x01,
|
||||
.SubClass = 0x03,
|
||||
.Protocol = 0x00,
|
||||
|
||||
.InterfaceStrIndex = NO_DESCRIPTOR
|
||||
},
|
||||
|
||||
.Audio_StreamInterface_SPC =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_MIDI_AudioInterface_AS_t), .Type = DTYPE_AudioInterface},
|
||||
.Subtype = DSUBTYPE_General,
|
||||
|
||||
.AudioSpecification = VERSION_BCD(01.00),
|
||||
|
||||
.TotalLength = (sizeof(USB_Descriptor_Configuration_t) -
|
||||
offsetof(USB_Descriptor_Configuration_t, Audio_StreamInterface_SPC))
|
||||
},
|
||||
|
||||
.MIDI_In_Jack_Emb =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_MIDI_In_Jack_t), .Type = DTYPE_AudioInterface},
|
||||
.Subtype = DSUBTYPE_InputJack,
|
||||
|
||||
.JackType = MIDI_JACKTYPE_EMBEDDED,
|
||||
.JackID = 0x01,
|
||||
|
||||
.JackStrIndex = NO_DESCRIPTOR
|
||||
},
|
||||
|
||||
.MIDI_In_Jack_Ext =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_MIDI_In_Jack_t), .Type = DTYPE_AudioInterface},
|
||||
.Subtype = DSUBTYPE_InputJack,
|
||||
|
||||
.JackType = MIDI_JACKTYPE_EXTERNAL,
|
||||
.JackID = 0x02,
|
||||
|
||||
.JackStrIndex = NO_DESCRIPTOR
|
||||
},
|
||||
|
||||
.MIDI_Out_Jack_Emb =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_MIDI_Out_Jack_t), .Type = DTYPE_AudioInterface},
|
||||
.Subtype = DSUBTYPE_OutputJack,
|
||||
|
||||
.JackType = MIDI_JACKTYPE_EMBEDDED,
|
||||
.JackID = 0x03,
|
||||
|
||||
.NumberOfPins = 1,
|
||||
.SourceJackID = {0x02},
|
||||
.SourcePinID = {0x01},
|
||||
|
||||
.JackStrIndex = NO_DESCRIPTOR
|
||||
},
|
||||
|
||||
.MIDI_Out_Jack_Ext =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_MIDI_Out_Jack_t), .Type = DTYPE_AudioInterface},
|
||||
.Subtype = DSUBTYPE_OutputJack,
|
||||
|
||||
.JackType = MIDI_JACKTYPE_EXTERNAL,
|
||||
.JackID = 0x04,
|
||||
|
||||
.NumberOfPins = 1,
|
||||
.SourceJackID = {0x01},
|
||||
.SourcePinID = {0x01},
|
||||
|
||||
.JackStrIndex = NO_DESCRIPTOR
|
||||
},
|
||||
|
||||
.MIDI_In_Jack_Endpoint =
|
||||
{
|
||||
.Endpoint =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Audio_StreamEndpoint_Std_t), .Type = DTYPE_Endpoint},
|
||||
|
||||
.EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_OUT | MIDI_STREAM_OUT_EPNUM),
|
||||
.Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
|
||||
.EndpointSize = MIDI_STREAM_EPSIZE,
|
||||
.PollingIntervalMS = 0
|
||||
},
|
||||
|
||||
.Refresh = 0,
|
||||
.SyncEndpointNumber = 0
|
||||
},
|
||||
|
||||
.MIDI_In_Jack_Endpoint_SPC =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_MIDI_Jack_Endpoint_t), .Type = DTYPE_AudioEndpoint},
|
||||
.Subtype = DSUBTYPE_General,
|
||||
|
||||
.TotalEmbeddedJacks = 0x01,
|
||||
.AssociatedJackID = {0x01}
|
||||
},
|
||||
|
||||
.MIDI_Out_Jack_Endpoint =
|
||||
{
|
||||
.Endpoint =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Audio_StreamEndpoint_Std_t), .Type = DTYPE_Endpoint},
|
||||
|
||||
.EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_IN | MIDI_STREAM_IN_EPNUM),
|
||||
.Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
|
||||
.EndpointSize = MIDI_STREAM_EPSIZE,
|
||||
.PollingIntervalMS = 0
|
||||
},
|
||||
|
||||
.Refresh = 0,
|
||||
.SyncEndpointNumber = 0
|
||||
},
|
||||
|
||||
.MIDI_Out_Jack_Endpoint_SPC =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_MIDI_Jack_Endpoint_t), .Type = DTYPE_AudioEndpoint},
|
||||
.Subtype = DSUBTYPE_General,
|
||||
|
||||
.TotalEmbeddedJacks = 0x01,
|
||||
.AssociatedJackID = {0x03}
|
||||
}
|
||||
};
|
||||
|
||||
/** 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
|
||||
* via the language ID table available at USB.org what languages the device supports for its string descriptors.
|
||||
*/
|
||||
USB_Descriptor_String_t PROGMEM LanguageString =
|
||||
{
|
||||
.Header = {.Size = USB_STRING_LEN(1), .Type = DTYPE_String},
|
||||
|
||||
.UnicodeString = {LANGUAGE_ID_ENG}
|
||||
};
|
||||
|
||||
/** 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
|
||||
* Descriptor.
|
||||
*/
|
||||
USB_Descriptor_String_t PROGMEM ManufacturerString =
|
||||
{
|
||||
.Header = {.Size = USB_STRING_LEN(11), .Type = DTYPE_String},
|
||||
|
||||
.UnicodeString = L"Dean Camera"
|
||||
};
|
||||
|
||||
/** 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
|
||||
* Descriptor.
|
||||
*/
|
||||
USB_Descriptor_String_t PROGMEM ProductString =
|
||||
{
|
||||
.Header = {.Size = USB_STRING_LEN(14), .Type = DTYPE_String},
|
||||
|
||||
.UnicodeString = L"LUFA MIDI Demo"
|
||||
};
|
||||
|
||||
/** 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
|
||||
* 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
|
||||
* USB host.
|
||||
*/
|
||||
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 DescriptorNumber = (wValue & 0xFF);
|
||||
|
||||
void* Address = NULL;
|
||||
uint16_t Size = NO_DESCRIPTOR;
|
||||
|
||||
switch (DescriptorType)
|
||||
{
|
||||
case DTYPE_Device:
|
||||
Address = (void*)&DeviceDescriptor;
|
||||
Size = sizeof(USB_Descriptor_Device_t);
|
||||
break;
|
||||
case DTYPE_Configuration:
|
||||
Address = (void*)&ConfigurationDescriptor;
|
||||
Size = sizeof(USB_Descriptor_Configuration_t);
|
||||
break;
|
||||
case DTYPE_String:
|
||||
switch (DescriptorNumber)
|
||||
{
|
||||
case 0x00:
|
||||
Address = (void*)&LanguageString;
|
||||
Size = pgm_read_byte(&LanguageString.Header.Size);
|
||||
break;
|
||||
case 0x01:
|
||||
Address = (void*)&ManufacturerString;
|
||||
Size = pgm_read_byte(&ManufacturerString.Header.Size);
|
||||
break;
|
||||
case 0x02:
|
||||
Address = (void*)&ProductString;
|
||||
Size = pgm_read_byte(&ProductString.Header.Size);
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
*DescriptorAddress = Address;
|
||||
return Size;
|
||||
}
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* 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
|
||||
* the device's capabilities and functions.
|
||||
*/
|
||||
|
||||
#include "Descriptors.h"
|
||||
|
||||
/** Device descriptor structure. This descriptor, located in FLASH memory, describes the overall
|
||||
* 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
|
||||
* process begins.
|
||||
*/
|
||||
USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device},
|
||||
|
||||
.USBSpecification = VERSION_BCD(01.10),
|
||||
.Class = 0x00,
|
||||
.SubClass = 0x00,
|
||||
.Protocol = 0x00,
|
||||
|
||||
.Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE,
|
||||
|
||||
.VendorID = 0x03EB,
|
||||
.ProductID = 0x2048,
|
||||
.ReleaseNumber = 0x0000,
|
||||
|
||||
.ManufacturerStrIndex = 0x01,
|
||||
.ProductStrIndex = 0x02,
|
||||
.SerialNumStrIndex = NO_DESCRIPTOR,
|
||||
|
||||
.NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS
|
||||
};
|
||||
|
||||
/** 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
|
||||
* 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.
|
||||
*/
|
||||
USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
|
||||
{
|
||||
.Config =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration},
|
||||
|
||||
.TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t),
|
||||
.TotalInterfaces = 2,
|
||||
|
||||
.ConfigurationNumber = 1,
|
||||
.ConfigurationStrIndex = NO_DESCRIPTOR,
|
||||
|
||||
.ConfigAttributes = (USB_CONFIG_ATTR_BUSPOWERED | USB_CONFIG_ATTR_SELFPOWERED),
|
||||
|
||||
.MaxPowerConsumption = USB_CONFIG_POWER_MA(100)
|
||||
},
|
||||
|
||||
.Audio_ControlInterface =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
|
||||
|
||||
.InterfaceNumber = 0,
|
||||
.AlternateSetting = 0,
|
||||
|
||||
.TotalEndpoints = 0,
|
||||
|
||||
.Class = 0x01,
|
||||
.SubClass = 0x01,
|
||||
.Protocol = 0x00,
|
||||
|
||||
.InterfaceStrIndex = NO_DESCRIPTOR
|
||||
},
|
||||
|
||||
.Audio_ControlInterface_SPC =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Audio_Interface_AC_t), .Type = DTYPE_AudioInterface},
|
||||
.Subtype = DSUBTYPE_Header,
|
||||
|
||||
.ACSpecification = VERSION_BCD(01.00),
|
||||
.TotalLength = sizeof(USB_Audio_Interface_AC_t),
|
||||
|
||||
.InCollection = 1,
|
||||
.InterfaceNumbers = {1},
|
||||
},
|
||||
|
||||
.Audio_StreamInterface =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
|
||||
|
||||
.InterfaceNumber = 1,
|
||||
.AlternateSetting = 0,
|
||||
|
||||
.TotalEndpoints = 2,
|
||||
|
||||
.Class = 0x01,
|
||||
.SubClass = 0x03,
|
||||
.Protocol = 0x00,
|
||||
|
||||
.InterfaceStrIndex = NO_DESCRIPTOR
|
||||
},
|
||||
|
||||
.Audio_StreamInterface_SPC =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_MIDI_AudioInterface_AS_t), .Type = DTYPE_AudioInterface},
|
||||
.Subtype = DSUBTYPE_General,
|
||||
|
||||
.AudioSpecification = VERSION_BCD(01.00),
|
||||
|
||||
.TotalLength = (sizeof(USB_Descriptor_Configuration_t) -
|
||||
offsetof(USB_Descriptor_Configuration_t, Audio_StreamInterface_SPC))
|
||||
},
|
||||
|
||||
.MIDI_In_Jack_Emb =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_MIDI_In_Jack_t), .Type = DTYPE_AudioInterface},
|
||||
.Subtype = DSUBTYPE_InputJack,
|
||||
|
||||
.JackType = MIDI_JACKTYPE_EMBEDDED,
|
||||
.JackID = 0x01,
|
||||
|
||||
.JackStrIndex = NO_DESCRIPTOR
|
||||
},
|
||||
|
||||
.MIDI_In_Jack_Ext =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_MIDI_In_Jack_t), .Type = DTYPE_AudioInterface},
|
||||
.Subtype = DSUBTYPE_InputJack,
|
||||
|
||||
.JackType = MIDI_JACKTYPE_EXTERNAL,
|
||||
.JackID = 0x02,
|
||||
|
||||
.JackStrIndex = NO_DESCRIPTOR
|
||||
},
|
||||
|
||||
.MIDI_Out_Jack_Emb =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_MIDI_Out_Jack_t), .Type = DTYPE_AudioInterface},
|
||||
.Subtype = DSUBTYPE_OutputJack,
|
||||
|
||||
.JackType = MIDI_JACKTYPE_EMBEDDED,
|
||||
.JackID = 0x03,
|
||||
|
||||
.NumberOfPins = 1,
|
||||
.SourceJackID = {0x02},
|
||||
.SourcePinID = {0x01},
|
||||
|
||||
.JackStrIndex = NO_DESCRIPTOR
|
||||
},
|
||||
|
||||
.MIDI_Out_Jack_Ext =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_MIDI_Out_Jack_t), .Type = DTYPE_AudioInterface},
|
||||
.Subtype = DSUBTYPE_OutputJack,
|
||||
|
||||
.JackType = MIDI_JACKTYPE_EXTERNAL,
|
||||
.JackID = 0x04,
|
||||
|
||||
.NumberOfPins = 1,
|
||||
.SourceJackID = {0x01},
|
||||
.SourcePinID = {0x01},
|
||||
|
||||
.JackStrIndex = NO_DESCRIPTOR
|
||||
},
|
||||
|
||||
.MIDI_In_Jack_Endpoint =
|
||||
{
|
||||
.Endpoint =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Audio_StreamEndpoint_Std_t), .Type = DTYPE_Endpoint},
|
||||
|
||||
.EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_OUT | MIDI_STREAM_OUT_EPNUM),
|
||||
.Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
|
||||
.EndpointSize = MIDI_STREAM_EPSIZE,
|
||||
.PollingIntervalMS = 0
|
||||
},
|
||||
|
||||
.Refresh = 0,
|
||||
.SyncEndpointNumber = 0
|
||||
},
|
||||
|
||||
.MIDI_In_Jack_Endpoint_SPC =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_MIDI_Jack_Endpoint_t), .Type = DTYPE_AudioEndpoint},
|
||||
.Subtype = DSUBTYPE_General,
|
||||
|
||||
.TotalEmbeddedJacks = 0x01,
|
||||
.AssociatedJackID = {0x01}
|
||||
},
|
||||
|
||||
.MIDI_Out_Jack_Endpoint =
|
||||
{
|
||||
.Endpoint =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Audio_StreamEndpoint_Std_t), .Type = DTYPE_Endpoint},
|
||||
|
||||
.EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_IN | MIDI_STREAM_IN_EPNUM),
|
||||
.Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
|
||||
.EndpointSize = MIDI_STREAM_EPSIZE,
|
||||
.PollingIntervalMS = 0
|
||||
},
|
||||
|
||||
.Refresh = 0,
|
||||
.SyncEndpointNumber = 0
|
||||
},
|
||||
|
||||
.MIDI_Out_Jack_Endpoint_SPC =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_MIDI_Jack_Endpoint_t), .Type = DTYPE_AudioEndpoint},
|
||||
.Subtype = DSUBTYPE_General,
|
||||
|
||||
.TotalEmbeddedJacks = 0x01,
|
||||
.AssociatedJackID = {0x03}
|
||||
}
|
||||
};
|
||||
|
||||
/** 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
|
||||
* via the language ID table available at USB.org what languages the device supports for its string descriptors.
|
||||
*/
|
||||
USB_Descriptor_String_t PROGMEM LanguageString =
|
||||
{
|
||||
.Header = {.Size = USB_STRING_LEN(1), .Type = DTYPE_String},
|
||||
|
||||
.UnicodeString = {LANGUAGE_ID_ENG}
|
||||
};
|
||||
|
||||
/** 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
|
||||
* Descriptor.
|
||||
*/
|
||||
USB_Descriptor_String_t PROGMEM ManufacturerString =
|
||||
{
|
||||
.Header = {.Size = USB_STRING_LEN(11), .Type = DTYPE_String},
|
||||
|
||||
.UnicodeString = L"Dean Camera"
|
||||
};
|
||||
|
||||
/** 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
|
||||
* Descriptor.
|
||||
*/
|
||||
USB_Descriptor_String_t PROGMEM ProductString =
|
||||
{
|
||||
.Header = {.Size = USB_STRING_LEN(14), .Type = DTYPE_String},
|
||||
|
||||
.UnicodeString = L"LUFA MIDI Demo"
|
||||
};
|
||||
|
||||
/** 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
|
||||
* 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
|
||||
* USB host.
|
||||
*/
|
||||
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 DescriptorNumber = (wValue & 0xFF);
|
||||
|
||||
void* Address = NULL;
|
||||
uint16_t Size = NO_DESCRIPTOR;
|
||||
|
||||
switch (DescriptorType)
|
||||
{
|
||||
case DTYPE_Device:
|
||||
Address = (void*)&DeviceDescriptor;
|
||||
Size = sizeof(USB_Descriptor_Device_t);
|
||||
break;
|
||||
case DTYPE_Configuration:
|
||||
Address = (void*)&ConfigurationDescriptor;
|
||||
Size = sizeof(USB_Descriptor_Configuration_t);
|
||||
break;
|
||||
case DTYPE_String:
|
||||
switch (DescriptorNumber)
|
||||
{
|
||||
case 0x00:
|
||||
Address = (void*)&LanguageString;
|
||||
Size = pgm_read_byte(&LanguageString.Header.Size);
|
||||
break;
|
||||
case 0x01:
|
||||
Address = (void*)&ManufacturerString;
|
||||
Size = pgm_read_byte(&ManufacturerString.Header.Size);
|
||||
break;
|
||||
case 0x02:
|
||||
Address = (void*)&ProductString;
|
||||
Size = pgm_read_byte(&ProductString.Header.Size);
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
*DescriptorAddress = Address;
|
||||
return Size;
|
||||
}
|
||||
|
@ -1,81 +1,81 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Header file for Descriptors.c.
|
||||
*/
|
||||
|
||||
#ifndef _DESCRIPTORS_H_
|
||||
#define _DESCRIPTORS_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <LUFA/Drivers/USB/USB.h>
|
||||
#include <LUFA/Drivers/USB/Class/MIDI.h>
|
||||
|
||||
#include <avr/pgmspace.h>
|
||||
|
||||
/* Macros: */
|
||||
/** Endpoint number of the MIDI streaming data IN endpoint, for device-to-host data transfers. */
|
||||
#define MIDI_STREAM_IN_EPNUM 2
|
||||
|
||||
/** Endpoint number of the MIDI streaming data OUT endpoint, for host-to-device data transfers. */
|
||||
#define MIDI_STREAM_OUT_EPNUM 1
|
||||
|
||||
/** Endpoint size in bytes of the Audio isochronous streaming data IN and OUT endpoints. */
|
||||
#define MIDI_STREAM_EPSIZE 64
|
||||
|
||||
/* Type Defines: */
|
||||
/** 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
|
||||
* vary between devices, and which describe the device's usage to the host.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
USB_Descriptor_Configuration_Header_t Config;
|
||||
USB_Descriptor_Interface_t Audio_ControlInterface;
|
||||
USB_Audio_Interface_AC_t Audio_ControlInterface_SPC;
|
||||
USB_Descriptor_Interface_t Audio_StreamInterface;
|
||||
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_Ext;
|
||||
USB_MIDI_Out_Jack_t MIDI_Out_Jack_Emb;
|
||||
USB_MIDI_Out_Jack_t MIDI_Out_Jack_Ext;
|
||||
USB_Audio_StreamEndpoint_Std_t MIDI_In_Jack_Endpoint;
|
||||
USB_MIDI_Jack_Endpoint_t MIDI_In_Jack_Endpoint_SPC;
|
||||
USB_Audio_StreamEndpoint_Std_t MIDI_Out_Jack_Endpoint;
|
||||
USB_MIDI_Jack_Endpoint_t MIDI_Out_Jack_Endpoint_SPC;
|
||||
} USB_Descriptor_Configuration_t;
|
||||
|
||||
/* Function Prototypes: */
|
||||
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);
|
||||
|
||||
#endif
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Header file for Descriptors.c.
|
||||
*/
|
||||
|
||||
#ifndef _DESCRIPTORS_H_
|
||||
#define _DESCRIPTORS_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <LUFA/Drivers/USB/USB.h>
|
||||
#include <LUFA/Drivers/USB/Class/MIDI.h>
|
||||
|
||||
#include <avr/pgmspace.h>
|
||||
|
||||
/* Macros: */
|
||||
/** Endpoint number of the MIDI streaming data IN endpoint, for device-to-host data transfers. */
|
||||
#define MIDI_STREAM_IN_EPNUM 2
|
||||
|
||||
/** Endpoint number of the MIDI streaming data OUT endpoint, for host-to-device data transfers. */
|
||||
#define MIDI_STREAM_OUT_EPNUM 1
|
||||
|
||||
/** Endpoint size in bytes of the Audio isochronous streaming data IN and OUT endpoints. */
|
||||
#define MIDI_STREAM_EPSIZE 64
|
||||
|
||||
/* Type Defines: */
|
||||
/** 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
|
||||
* vary between devices, and which describe the device's usage to the host.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
USB_Descriptor_Configuration_Header_t Config;
|
||||
USB_Descriptor_Interface_t Audio_ControlInterface;
|
||||
USB_Audio_Interface_AC_t Audio_ControlInterface_SPC;
|
||||
USB_Descriptor_Interface_t Audio_StreamInterface;
|
||||
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_Ext;
|
||||
USB_MIDI_Out_Jack_t MIDI_Out_Jack_Emb;
|
||||
USB_MIDI_Out_Jack_t MIDI_Out_Jack_Ext;
|
||||
USB_Audio_StreamEndpoint_Std_t MIDI_In_Jack_Endpoint;
|
||||
USB_MIDI_Jack_Endpoint_t MIDI_In_Jack_Endpoint_SPC;
|
||||
USB_Audio_StreamEndpoint_Std_t MIDI_Out_Jack_Endpoint;
|
||||
USB_MIDI_Jack_Endpoint_t MIDI_Out_Jack_Endpoint_SPC;
|
||||
} USB_Descriptor_Configuration_t;
|
||||
|
||||
/* Function Prototypes: */
|
||||
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);
|
||||
|
||||
#endif
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,193 +1,193 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Main source file for the MIDI demo. This file contains the main tasks of
|
||||
* the demo and is responsible for the initial application hardware configuration.
|
||||
*/
|
||||
|
||||
#include "MIDI.h"
|
||||
|
||||
/** 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
|
||||
* within a device can be differentiated from one another.
|
||||
*/
|
||||
USB_ClassInfo_MIDI_Device_t Keyboard_MIDI_Interface =
|
||||
{
|
||||
.Config =
|
||||
{
|
||||
.StreamingInterfaceNumber = 1,
|
||||
|
||||
.DataINEndpointNumber = MIDI_STREAM_IN_EPNUM,
|
||||
.DataINEndpointSize = MIDI_STREAM_EPSIZE,
|
||||
.DataINEndpointDoubleBank = false,
|
||||
|
||||
.DataOUTEndpointNumber = MIDI_STREAM_OUT_EPNUM,
|
||||
.DataOUTEndpointSize = MIDI_STREAM_EPSIZE,
|
||||
.DataOUTEndpointDoubleBank = false,
|
||||
},
|
||||
};
|
||||
|
||||
/** Main program entry point. This routine contains the overall program flow, including initial
|
||||
* setup of all components and the main program loop.
|
||||
*/
|
||||
int main(void)
|
||||
{
|
||||
SetupHardware();
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
|
||||
sei();
|
||||
|
||||
for (;;)
|
||||
{
|
||||
CheckJoystickMovement();
|
||||
|
||||
MIDI_EventPacket_t ReceivedMIDIEvent;
|
||||
if (MIDI_Device_ReceiveEventPacket(&Keyboard_MIDI_Interface, &ReceivedMIDIEvent))
|
||||
{
|
||||
if ((ReceivedMIDIEvent.Command == (MIDI_COMMAND_NOTE_ON >> 4)) && (ReceivedMIDIEvent.Data3 > 0))
|
||||
LEDs_SetAllLEDs(ReceivedMIDIEvent.Data2 > 64 ? LEDS_LED1 : LEDS_LED2);
|
||||
else
|
||||
LEDs_SetAllLEDs(LEDS_NO_LEDS);
|
||||
}
|
||||
|
||||
MIDI_Device_USBTask(&Keyboard_MIDI_Interface);
|
||||
USB_USBTask();
|
||||
}
|
||||
}
|
||||
|
||||
/** Configures the board hardware and chip peripherals for the demo's functionality. */
|
||||
void SetupHardware(void)
|
||||
{
|
||||
/* Disable watchdog if enabled by bootloader/fuses */
|
||||
MCUSR &= ~(1 << WDRF);
|
||||
wdt_disable();
|
||||
|
||||
/* Disable clock division */
|
||||
clock_prescale_set(clock_div_1);
|
||||
|
||||
/* Hardware Initialization */
|
||||
Joystick_Init();
|
||||
LEDs_Init();
|
||||
Buttons_Init();
|
||||
USB_Init();
|
||||
}
|
||||
|
||||
/** Checks for changes in the position of the board joystick, sending MIDI events to the host upon each change. */
|
||||
void CheckJoystickMovement(void)
|
||||
{
|
||||
static uint8_t PrevJoystickStatus;
|
||||
|
||||
uint8_t MIDICommand = 0;
|
||||
uint8_t MIDIPitch;
|
||||
|
||||
/* Get current joystick mask, XOR with previous to detect joystick changes */
|
||||
uint8_t JoystickStatus = Joystick_GetStatus();
|
||||
uint8_t JoystickChanges = (JoystickStatus ^ PrevJoystickStatus);
|
||||
|
||||
/* 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));
|
||||
|
||||
if (JoystickChanges & JOY_LEFT)
|
||||
{
|
||||
MIDICommand = ((JoystickStatus & JOY_LEFT)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF);
|
||||
MIDIPitch = 0x3C;
|
||||
}
|
||||
|
||||
if (JoystickChanges & JOY_UP)
|
||||
{
|
||||
MIDICommand = ((JoystickStatus & JOY_UP)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF);
|
||||
MIDIPitch = 0x3D;
|
||||
}
|
||||
|
||||
if (JoystickChanges & JOY_RIGHT)
|
||||
{
|
||||
MIDICommand = ((JoystickStatus & JOY_RIGHT)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF);
|
||||
MIDIPitch = 0x3E;
|
||||
}
|
||||
|
||||
if (JoystickChanges & JOY_DOWN)
|
||||
{
|
||||
MIDICommand = ((JoystickStatus & JOY_DOWN)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF);
|
||||
MIDIPitch = 0x3F;
|
||||
}
|
||||
|
||||
if (JoystickChanges & JOY_PRESS)
|
||||
{
|
||||
MIDICommand = ((JoystickStatus & JOY_PRESS)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF);
|
||||
MIDIPitch = 0x3B;
|
||||
}
|
||||
|
||||
if (MIDICommand)
|
||||
{
|
||||
MIDI_EventPacket_t MIDIEvent = (MIDI_EventPacket_t)
|
||||
{
|
||||
.CableNumber = 0,
|
||||
.Command = (MIDICommand >> 4),
|
||||
|
||||
.Data1 = MIDICommand | Channel,
|
||||
.Data2 = MIDIPitch,
|
||||
.Data3 = MIDI_STANDARD_VELOCITY,
|
||||
};
|
||||
|
||||
MIDI_Device_SendEventPacket(&Keyboard_MIDI_Interface, &MIDIEvent);
|
||||
MIDI_Device_Flush(&Keyboard_MIDI_Interface);
|
||||
}
|
||||
|
||||
PrevJoystickStatus = JoystickStatus;
|
||||
}
|
||||
|
||||
/** Event handler for the library USB Connection event. */
|
||||
void EVENT_USB_Device_Connect(void)
|
||||
{
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
|
||||
}
|
||||
|
||||
/** Event handler for the library USB Disconnection event. */
|
||||
void EVENT_USB_Device_Disconnect(void)
|
||||
{
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
|
||||
}
|
||||
|
||||
/** Event handler for the library USB Configuration Changed event. */
|
||||
void EVENT_USB_Device_ConfigurationChanged(void)
|
||||
{
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
|
||||
if (!(MIDI_Device_ConfigureEndpoints(&Keyboard_MIDI_Interface)))
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
}
|
||||
|
||||
/** Event handler for the library USB Unhandled Control Request event. */
|
||||
void EVENT_USB_Device_UnhandledControlRequest(void)
|
||||
{
|
||||
MIDI_Device_ProcessControlRequest(&Keyboard_MIDI_Interface);
|
||||
}
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Main source file for the MIDI demo. This file contains the main tasks of
|
||||
* the demo and is responsible for the initial application hardware configuration.
|
||||
*/
|
||||
|
||||
#include "MIDI.h"
|
||||
|
||||
/** 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
|
||||
* within a device can be differentiated from one another.
|
||||
*/
|
||||
USB_ClassInfo_MIDI_Device_t Keyboard_MIDI_Interface =
|
||||
{
|
||||
.Config =
|
||||
{
|
||||
.StreamingInterfaceNumber = 1,
|
||||
|
||||
.DataINEndpointNumber = MIDI_STREAM_IN_EPNUM,
|
||||
.DataINEndpointSize = MIDI_STREAM_EPSIZE,
|
||||
.DataINEndpointDoubleBank = false,
|
||||
|
||||
.DataOUTEndpointNumber = MIDI_STREAM_OUT_EPNUM,
|
||||
.DataOUTEndpointSize = MIDI_STREAM_EPSIZE,
|
||||
.DataOUTEndpointDoubleBank = false,
|
||||
},
|
||||
};
|
||||
|
||||
/** Main program entry point. This routine contains the overall program flow, including initial
|
||||
* setup of all components and the main program loop.
|
||||
*/
|
||||
int main(void)
|
||||
{
|
||||
SetupHardware();
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
|
||||
sei();
|
||||
|
||||
for (;;)
|
||||
{
|
||||
CheckJoystickMovement();
|
||||
|
||||
MIDI_EventPacket_t ReceivedMIDIEvent;
|
||||
if (MIDI_Device_ReceiveEventPacket(&Keyboard_MIDI_Interface, &ReceivedMIDIEvent))
|
||||
{
|
||||
if ((ReceivedMIDIEvent.Command == (MIDI_COMMAND_NOTE_ON >> 4)) && (ReceivedMIDIEvent.Data3 > 0))
|
||||
LEDs_SetAllLEDs(ReceivedMIDIEvent.Data2 > 64 ? LEDS_LED1 : LEDS_LED2);
|
||||
else
|
||||
LEDs_SetAllLEDs(LEDS_NO_LEDS);
|
||||
}
|
||||
|
||||
MIDI_Device_USBTask(&Keyboard_MIDI_Interface);
|
||||
USB_USBTask();
|
||||
}
|
||||
}
|
||||
|
||||
/** Configures the board hardware and chip peripherals for the demo's functionality. */
|
||||
void SetupHardware(void)
|
||||
{
|
||||
/* Disable watchdog if enabled by bootloader/fuses */
|
||||
MCUSR &= ~(1 << WDRF);
|
||||
wdt_disable();
|
||||
|
||||
/* Disable clock division */
|
||||
clock_prescale_set(clock_div_1);
|
||||
|
||||
/* Hardware Initialization */
|
||||
Joystick_Init();
|
||||
LEDs_Init();
|
||||
Buttons_Init();
|
||||
USB_Init();
|
||||
}
|
||||
|
||||
/** Checks for changes in the position of the board joystick, sending MIDI events to the host upon each change. */
|
||||
void CheckJoystickMovement(void)
|
||||
{
|
||||
static uint8_t PrevJoystickStatus;
|
||||
|
||||
uint8_t MIDICommand = 0;
|
||||
uint8_t MIDIPitch;
|
||||
|
||||
/* Get current joystick mask, XOR with previous to detect joystick changes */
|
||||
uint8_t JoystickStatus = Joystick_GetStatus();
|
||||
uint8_t JoystickChanges = (JoystickStatus ^ PrevJoystickStatus);
|
||||
|
||||
/* 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));
|
||||
|
||||
if (JoystickChanges & JOY_LEFT)
|
||||
{
|
||||
MIDICommand = ((JoystickStatus & JOY_LEFT)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF);
|
||||
MIDIPitch = 0x3C;
|
||||
}
|
||||
|
||||
if (JoystickChanges & JOY_UP)
|
||||
{
|
||||
MIDICommand = ((JoystickStatus & JOY_UP)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF);
|
||||
MIDIPitch = 0x3D;
|
||||
}
|
||||
|
||||
if (JoystickChanges & JOY_RIGHT)
|
||||
{
|
||||
MIDICommand = ((JoystickStatus & JOY_RIGHT)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF);
|
||||
MIDIPitch = 0x3E;
|
||||
}
|
||||
|
||||
if (JoystickChanges & JOY_DOWN)
|
||||
{
|
||||
MIDICommand = ((JoystickStatus & JOY_DOWN)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF);
|
||||
MIDIPitch = 0x3F;
|
||||
}
|
||||
|
||||
if (JoystickChanges & JOY_PRESS)
|
||||
{
|
||||
MIDICommand = ((JoystickStatus & JOY_PRESS)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF);
|
||||
MIDIPitch = 0x3B;
|
||||
}
|
||||
|
||||
if (MIDICommand)
|
||||
{
|
||||
MIDI_EventPacket_t MIDIEvent = (MIDI_EventPacket_t)
|
||||
{
|
||||
.CableNumber = 0,
|
||||
.Command = (MIDICommand >> 4),
|
||||
|
||||
.Data1 = MIDICommand | Channel,
|
||||
.Data2 = MIDIPitch,
|
||||
.Data3 = MIDI_STANDARD_VELOCITY,
|
||||
};
|
||||
|
||||
MIDI_Device_SendEventPacket(&Keyboard_MIDI_Interface, &MIDIEvent);
|
||||
MIDI_Device_Flush(&Keyboard_MIDI_Interface);
|
||||
}
|
||||
|
||||
PrevJoystickStatus = JoystickStatus;
|
||||
}
|
||||
|
||||
/** Event handler for the library USB Connection event. */
|
||||
void EVENT_USB_Device_Connect(void)
|
||||
{
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
|
||||
}
|
||||
|
||||
/** Event handler for the library USB Disconnection event. */
|
||||
void EVENT_USB_Device_Disconnect(void)
|
||||
{
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
|
||||
}
|
||||
|
||||
/** Event handler for the library USB Configuration Changed event. */
|
||||
void EVENT_USB_Device_ConfigurationChanged(void)
|
||||
{
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
|
||||
if (!(MIDI_Device_ConfigureEndpoints(&Keyboard_MIDI_Interface)))
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
}
|
||||
|
||||
/** Event handler for the library USB Unhandled Control Request event. */
|
||||
void EVENT_USB_Device_UnhandledControlRequest(void)
|
||||
{
|
||||
MIDI_Device_ProcessControlRequest(&Keyboard_MIDI_Interface);
|
||||
}
|
||||
|
@ -1,79 +1,79 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Header file for AudioOutput.c.
|
||||
*/
|
||||
|
||||
#ifndef _AUDIO_OUTPUT_H_
|
||||
#define _AUDIO_OUTPUT_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/io.h>
|
||||
#include <avr/wdt.h>
|
||||
#include <avr/power.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "Descriptors.h"
|
||||
|
||||
#include <LUFA/Version.h>
|
||||
#include <LUFA/Drivers/Board/LEDs.h>
|
||||
#include <LUFA/Drivers/Board/Joystick.h>
|
||||
#include <LUFA/Drivers/Board/Buttons.h>
|
||||
#include <LUFA/Drivers/Peripheral/ADC.h>
|
||||
#include <LUFA/Drivers/USB/USB.h>
|
||||
#include <LUFA/Drivers/USB/Class/MIDI.h>
|
||||
|
||||
/* Macros: */
|
||||
/** LED mask for the library LED driver, to indicate that the USB interface is not ready. */
|
||||
#define LEDMASK_USB_NOTREADY LEDS_LED1
|
||||
|
||||
/** LED mask for the library LED driver, to indicate that the USB interface is enumerating. */
|
||||
#define LEDMASK_USB_ENUMERATING (LEDS_LED2 | LEDS_LED3)
|
||||
|
||||
/** LED mask for the library LED driver, to indicate that the USB interface is ready. */
|
||||
#define LEDMASK_USB_READY (LEDS_LED2 | LEDS_LED4)
|
||||
|
||||
/** LED mask for the library LED driver, to indicate that an error has occurred in the USB interface. */
|
||||
#define LEDMASK_USB_ERROR (LEDS_LED1 | LEDS_LED3)
|
||||
|
||||
/* Function Prototypes: */
|
||||
void SetupHardware(void);
|
||||
void CheckJoystickMovement(void);
|
||||
|
||||
void EVENT_USB_Device_Connect(void);
|
||||
void EVENT_USB_Device_Disconnect(void);
|
||||
void EVENT_USB_Device_ConfigurationChanged(void);
|
||||
void EVENT_USB_Device_UnhandledControlRequest(void);
|
||||
|
||||
#endif
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Header file for AudioOutput.c.
|
||||
*/
|
||||
|
||||
#ifndef _AUDIO_OUTPUT_H_
|
||||
#define _AUDIO_OUTPUT_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/io.h>
|
||||
#include <avr/wdt.h>
|
||||
#include <avr/power.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "Descriptors.h"
|
||||
|
||||
#include <LUFA/Version.h>
|
||||
#include <LUFA/Drivers/Board/LEDs.h>
|
||||
#include <LUFA/Drivers/Board/Joystick.h>
|
||||
#include <LUFA/Drivers/Board/Buttons.h>
|
||||
#include <LUFA/Drivers/Peripheral/ADC.h>
|
||||
#include <LUFA/Drivers/USB/USB.h>
|
||||
#include <LUFA/Drivers/USB/Class/MIDI.h>
|
||||
|
||||
/* Macros: */
|
||||
/** LED mask for the library LED driver, to indicate that the USB interface is not ready. */
|
||||
#define LEDMASK_USB_NOTREADY LEDS_LED1
|
||||
|
||||
/** LED mask for the library LED driver, to indicate that the USB interface is enumerating. */
|
||||
#define LEDMASK_USB_ENUMERATING (LEDS_LED2 | LEDS_LED3)
|
||||
|
||||
/** LED mask for the library LED driver, to indicate that the USB interface is ready. */
|
||||
#define LEDMASK_USB_READY (LEDS_LED2 | LEDS_LED4)
|
||||
|
||||
/** LED mask for the library LED driver, to indicate that an error has occurred in the USB interface. */
|
||||
#define LEDMASK_USB_ERROR (LEDS_LED1 | LEDS_LED3)
|
||||
|
||||
/* Function Prototypes: */
|
||||
void SetupHardware(void);
|
||||
void CheckJoystickMovement(void);
|
||||
|
||||
void EVENT_USB_Device_Connect(void);
|
||||
void EVENT_USB_Device_Disconnect(void);
|
||||
void EVENT_USB_Device_ConfigurationChanged(void);
|
||||
void EVENT_USB_Device_UnhandledControlRequest(void);
|
||||
|
||||
#endif
|
||||
|
@ -1,74 +1,74 @@
|
||||
/** \file
|
||||
*
|
||||
* This file contains special DoxyGen information for the generation of the main page and other special
|
||||
* documentation pages. It is not a project source file.
|
||||
*/
|
||||
|
||||
/** \mainpage MIDI Input Device Demo
|
||||
*
|
||||
* \section SSec_Compat Demo Compatibility:
|
||||
*
|
||||
* The following list indicates what microcontrollers are compatible with this demo.
|
||||
*
|
||||
* - Series 7 USB AVRs
|
||||
* - Series 6 USB AVRs
|
||||
* - Series 4 USB AVRs
|
||||
* - Series 2 USB AVRs
|
||||
*
|
||||
* \section SSec_Info USB Information:
|
||||
*
|
||||
* The following table gives a rundown of the USB utilization of this demo.
|
||||
*
|
||||
* <table>
|
||||
* <tr>
|
||||
* <td><b>USB Mode:</b></td>
|
||||
* <td>Device</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>USB Class:</b></td>
|
||||
* <td>Audio Class</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>USB Subclass:</b></td>
|
||||
* <td>Standard Audio Device</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>Relevant Standards:</b></td>
|
||||
* <td>USBIF Audio Class Specification \n
|
||||
* USB-MIDI Audio Class Extension Specification \n
|
||||
* General MIDI Specification</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>Usable Speeds:</b></td>
|
||||
* <td>Full Speed Mode</td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*
|
||||
* \section SSec_Description Project Description:
|
||||
*
|
||||
* MIDI demonstration application. This gives a simple reference
|
||||
* application for implementing the USB-MIDI class in USB devices.
|
||||
* It is built upon the USB Audio class.
|
||||
*
|
||||
* 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
|
||||
* MIDI program supporting MIDI IN devices.
|
||||
*
|
||||
* If the HWB is not pressed, channel 1 (default piano) is used. If
|
||||
* the HWB is set, then channel 10 (default percussion) is selected.
|
||||
*
|
||||
* This device implements MIDI-THRU mode, with the IN MIDI data being
|
||||
* generated by the device itself. OUT MIDI data is discarded.
|
||||
*
|
||||
* \section SSec_Options Project Options
|
||||
*
|
||||
* The following defines can be found in this demo, which can control the demo behaviour when defined, or changed in value.
|
||||
*
|
||||
* <table>
|
||||
* <tr>
|
||||
* <td>
|
||||
* None
|
||||
* </td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*/
|
||||
/** \file
|
||||
*
|
||||
* This file contains special DoxyGen information for the generation of the main page and other special
|
||||
* documentation pages. It is not a project source file.
|
||||
*/
|
||||
|
||||
/** \mainpage MIDI Input Device Demo
|
||||
*
|
||||
* \section SSec_Compat Demo Compatibility:
|
||||
*
|
||||
* The following list indicates what microcontrollers are compatible with this demo.
|
||||
*
|
||||
* - Series 7 USB AVRs
|
||||
* - Series 6 USB AVRs
|
||||
* - Series 4 USB AVRs
|
||||
* - Series 2 USB AVRs
|
||||
*
|
||||
* \section SSec_Info USB Information:
|
||||
*
|
||||
* The following table gives a rundown of the USB utilization of this demo.
|
||||
*
|
||||
* <table>
|
||||
* <tr>
|
||||
* <td><b>USB Mode:</b></td>
|
||||
* <td>Device</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>USB Class:</b></td>
|
||||
* <td>Audio Class</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>USB Subclass:</b></td>
|
||||
* <td>Standard Audio Device</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>Relevant Standards:</b></td>
|
||||
* <td>USBIF Audio Class Specification \n
|
||||
* USB-MIDI Audio Class Extension Specification \n
|
||||
* General MIDI Specification</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>Usable Speeds:</b></td>
|
||||
* <td>Full Speed Mode</td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*
|
||||
* \section SSec_Description Project Description:
|
||||
*
|
||||
* MIDI demonstration application. This gives a simple reference
|
||||
* application for implementing the USB-MIDI class in USB devices.
|
||||
* It is built upon the USB Audio class.
|
||||
*
|
||||
* 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
|
||||
* MIDI program supporting MIDI IN devices.
|
||||
*
|
||||
* If the HWB is not pressed, channel 1 (default piano) is used. If
|
||||
* the HWB is set, then channel 10 (default percussion) is selected.
|
||||
*
|
||||
* This device implements MIDI-THRU mode, with the IN MIDI data being
|
||||
* generated by the device itself. OUT MIDI data is discarded.
|
||||
*
|
||||
* \section SSec_Options Project Options
|
||||
*
|
||||
* The following defines can be found in this demo, which can control the demo behaviour when defined, or changed in value.
|
||||
*
|
||||
* <table>
|
||||
* <tr>
|
||||
* <td>
|
||||
* None
|
||||
* </td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*/
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,217 +1,217 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* 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
|
||||
* the device's capabilities and functions.
|
||||
*/
|
||||
|
||||
#include "Descriptors.h"
|
||||
|
||||
/* 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.
|
||||
* 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
|
||||
* 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
|
||||
* port location).
|
||||
*/
|
||||
#if (USE_INTERNAL_SERIAL == NO_DESCRIPTOR)
|
||||
#warning USE_INTERNAL_SERIAL is not available on this AVR - please manually construct a device serial descriptor.
|
||||
#endif
|
||||
|
||||
/** Device descriptor structure. This descriptor, located in FLASH memory, describes the overall
|
||||
* 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
|
||||
* process begins.
|
||||
*/
|
||||
USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device},
|
||||
|
||||
.USBSpecification = VERSION_BCD(01.10),
|
||||
.Class = 0x00,
|
||||
.SubClass = 0x00,
|
||||
.Protocol = 0x00,
|
||||
|
||||
.Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE,
|
||||
|
||||
.VendorID = 0x03EB,
|
||||
.ProductID = 0x2045,
|
||||
.ReleaseNumber = 0x0000,
|
||||
|
||||
.ManufacturerStrIndex = 0x01,
|
||||
.ProductStrIndex = 0x02,
|
||||
.SerialNumStrIndex = USE_INTERNAL_SERIAL,
|
||||
|
||||
.NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS
|
||||
};
|
||||
|
||||
/** 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
|
||||
* 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.
|
||||
*/
|
||||
USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
|
||||
{
|
||||
.Config =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration},
|
||||
|
||||
.TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t),
|
||||
.TotalInterfaces = 1,
|
||||
|
||||
.ConfigurationNumber = 1,
|
||||
.ConfigurationStrIndex = NO_DESCRIPTOR,
|
||||
|
||||
.ConfigAttributes = USB_CONFIG_ATTR_BUSPOWERED,
|
||||
|
||||
.MaxPowerConsumption = USB_CONFIG_POWER_MA(100)
|
||||
},
|
||||
|
||||
.MS_Interface =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
|
||||
|
||||
.InterfaceNumber = 0,
|
||||
.AlternateSetting = 0,
|
||||
|
||||
.TotalEndpoints = 2,
|
||||
|
||||
.Class = 0x08,
|
||||
.SubClass = 0x06,
|
||||
.Protocol = 0x50,
|
||||
|
||||
.InterfaceStrIndex = NO_DESCRIPTOR
|
||||
},
|
||||
|
||||
.MS_DataInEndpoint =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
|
||||
|
||||
.EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_IN | MASS_STORAGE_IN_EPNUM),
|
||||
.Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
|
||||
.EndpointSize = MASS_STORAGE_IO_EPSIZE,
|
||||
.PollingIntervalMS = 0x00
|
||||
},
|
||||
|
||||
.MS_DataOutEndpoint =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
|
||||
|
||||
.EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_OUT | MASS_STORAGE_OUT_EPNUM),
|
||||
.Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
|
||||
.EndpointSize = MASS_STORAGE_IO_EPSIZE,
|
||||
.PollingIntervalMS = 0x00
|
||||
}
|
||||
};
|
||||
|
||||
/** 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
|
||||
* via the language ID table available at USB.org what languages the device supports for its string descriptors.
|
||||
*/
|
||||
USB_Descriptor_String_t PROGMEM LanguageString =
|
||||
{
|
||||
.Header = {.Size = USB_STRING_LEN(1), .Type = DTYPE_String},
|
||||
|
||||
.UnicodeString = {LANGUAGE_ID_ENG}
|
||||
};
|
||||
|
||||
/** 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
|
||||
* Descriptor.
|
||||
*/
|
||||
USB_Descriptor_String_t PROGMEM ManufacturerString =
|
||||
{
|
||||
.Header = {.Size = USB_STRING_LEN(11), .Type = DTYPE_String},
|
||||
|
||||
.UnicodeString = L"Dean Camera"
|
||||
};
|
||||
|
||||
/** 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
|
||||
* Descriptor.
|
||||
*/
|
||||
USB_Descriptor_String_t PROGMEM ProductString =
|
||||
{
|
||||
.Header = {.Size = USB_STRING_LEN(22), .Type = DTYPE_String},
|
||||
|
||||
.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"
|
||||
* 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
|
||||
* is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the
|
||||
* USB host.
|
||||
*/
|
||||
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 DescriptorNumber = (wValue & 0xFF);
|
||||
|
||||
void* Address = NULL;
|
||||
uint16_t Size = NO_DESCRIPTOR;
|
||||
|
||||
switch (DescriptorType)
|
||||
{
|
||||
case DTYPE_Device:
|
||||
Address = (void*)&DeviceDescriptor;
|
||||
Size = sizeof(USB_Descriptor_Device_t);
|
||||
break;
|
||||
case DTYPE_Configuration:
|
||||
Address = (void*)&ConfigurationDescriptor;
|
||||
Size = sizeof(USB_Descriptor_Configuration_t);
|
||||
break;
|
||||
case DTYPE_String:
|
||||
switch (DescriptorNumber)
|
||||
{
|
||||
case 0x00:
|
||||
Address = (void*)&LanguageString;
|
||||
Size = pgm_read_byte(&LanguageString.Header.Size);
|
||||
break;
|
||||
case 0x01:
|
||||
Address = (void*)&ManufacturerString;
|
||||
Size = pgm_read_byte(&ManufacturerString.Header.Size);
|
||||
break;
|
||||
case 0x02:
|
||||
Address = (void*)&ProductString;
|
||||
Size = pgm_read_byte(&ProductString.Header.Size);
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
*DescriptorAddress = Address;
|
||||
return Size;
|
||||
}
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* 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
|
||||
* the device's capabilities and functions.
|
||||
*/
|
||||
|
||||
#include "Descriptors.h"
|
||||
|
||||
/* 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.
|
||||
* 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
|
||||
* 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
|
||||
* port location).
|
||||
*/
|
||||
#if (USE_INTERNAL_SERIAL == NO_DESCRIPTOR)
|
||||
#warning USE_INTERNAL_SERIAL is not available on this AVR - please manually construct a device serial descriptor.
|
||||
#endif
|
||||
|
||||
/** Device descriptor structure. This descriptor, located in FLASH memory, describes the overall
|
||||
* 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
|
||||
* process begins.
|
||||
*/
|
||||
USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device},
|
||||
|
||||
.USBSpecification = VERSION_BCD(01.10),
|
||||
.Class = 0x00,
|
||||
.SubClass = 0x00,
|
||||
.Protocol = 0x00,
|
||||
|
||||
.Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE,
|
||||
|
||||
.VendorID = 0x03EB,
|
||||
.ProductID = 0x2045,
|
||||
.ReleaseNumber = 0x0000,
|
||||
|
||||
.ManufacturerStrIndex = 0x01,
|
||||
.ProductStrIndex = 0x02,
|
||||
.SerialNumStrIndex = USE_INTERNAL_SERIAL,
|
||||
|
||||
.NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS
|
||||
};
|
||||
|
||||
/** 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
|
||||
* 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.
|
||||
*/
|
||||
USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
|
||||
{
|
||||
.Config =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration},
|
||||
|
||||
.TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t),
|
||||
.TotalInterfaces = 1,
|
||||
|
||||
.ConfigurationNumber = 1,
|
||||
.ConfigurationStrIndex = NO_DESCRIPTOR,
|
||||
|
||||
.ConfigAttributes = USB_CONFIG_ATTR_BUSPOWERED,
|
||||
|
||||
.MaxPowerConsumption = USB_CONFIG_POWER_MA(100)
|
||||
},
|
||||
|
||||
.MS_Interface =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
|
||||
|
||||
.InterfaceNumber = 0,
|
||||
.AlternateSetting = 0,
|
||||
|
||||
.TotalEndpoints = 2,
|
||||
|
||||
.Class = 0x08,
|
||||
.SubClass = 0x06,
|
||||
.Protocol = 0x50,
|
||||
|
||||
.InterfaceStrIndex = NO_DESCRIPTOR
|
||||
},
|
||||
|
||||
.MS_DataInEndpoint =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
|
||||
|
||||
.EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_IN | MASS_STORAGE_IN_EPNUM),
|
||||
.Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
|
||||
.EndpointSize = MASS_STORAGE_IO_EPSIZE,
|
||||
.PollingIntervalMS = 0x00
|
||||
},
|
||||
|
||||
.MS_DataOutEndpoint =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
|
||||
|
||||
.EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_OUT | MASS_STORAGE_OUT_EPNUM),
|
||||
.Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
|
||||
.EndpointSize = MASS_STORAGE_IO_EPSIZE,
|
||||
.PollingIntervalMS = 0x00
|
||||
}
|
||||
};
|
||||
|
||||
/** 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
|
||||
* via the language ID table available at USB.org what languages the device supports for its string descriptors.
|
||||
*/
|
||||
USB_Descriptor_String_t PROGMEM LanguageString =
|
||||
{
|
||||
.Header = {.Size = USB_STRING_LEN(1), .Type = DTYPE_String},
|
||||
|
||||
.UnicodeString = {LANGUAGE_ID_ENG}
|
||||
};
|
||||
|
||||
/** 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
|
||||
* Descriptor.
|
||||
*/
|
||||
USB_Descriptor_String_t PROGMEM ManufacturerString =
|
||||
{
|
||||
.Header = {.Size = USB_STRING_LEN(11), .Type = DTYPE_String},
|
||||
|
||||
.UnicodeString = L"Dean Camera"
|
||||
};
|
||||
|
||||
/** 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
|
||||
* Descriptor.
|
||||
*/
|
||||
USB_Descriptor_String_t PROGMEM ProductString =
|
||||
{
|
||||
.Header = {.Size = USB_STRING_LEN(22), .Type = DTYPE_String},
|
||||
|
||||
.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"
|
||||
* 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
|
||||
* is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the
|
||||
* USB host.
|
||||
*/
|
||||
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 DescriptorNumber = (wValue & 0xFF);
|
||||
|
||||
void* Address = NULL;
|
||||
uint16_t Size = NO_DESCRIPTOR;
|
||||
|
||||
switch (DescriptorType)
|
||||
{
|
||||
case DTYPE_Device:
|
||||
Address = (void*)&DeviceDescriptor;
|
||||
Size = sizeof(USB_Descriptor_Device_t);
|
||||
break;
|
||||
case DTYPE_Configuration:
|
||||
Address = (void*)&ConfigurationDescriptor;
|
||||
Size = sizeof(USB_Descriptor_Configuration_t);
|
||||
break;
|
||||
case DTYPE_String:
|
||||
switch (DescriptorNumber)
|
||||
{
|
||||
case 0x00:
|
||||
Address = (void*)&LanguageString;
|
||||
Size = pgm_read_byte(&LanguageString.Header.Size);
|
||||
break;
|
||||
case 0x01:
|
||||
Address = (void*)&ManufacturerString;
|
||||
Size = pgm_read_byte(&ManufacturerString.Header.Size);
|
||||
break;
|
||||
case 0x02:
|
||||
Address = (void*)&ProductString;
|
||||
Size = pgm_read_byte(&ProductString.Header.Size);
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
*DescriptorAddress = Address;
|
||||
return Size;
|
||||
}
|
||||
|
@ -1,72 +1,72 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Header file for Descriptors.c.
|
||||
*/
|
||||
|
||||
#ifndef _DESCRIPTORS_H_
|
||||
#define _DESCRIPTORS_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/pgmspace.h>
|
||||
|
||||
#include <LUFA/Drivers/USB/USB.h>
|
||||
#include <LUFA/Drivers/USB/Class/MassStorage.h>
|
||||
|
||||
/* Macros: */
|
||||
/** Endpoint number of the Mass Storage device-to-host data IN endpoint. */
|
||||
#define MASS_STORAGE_IN_EPNUM 3
|
||||
|
||||
/** Endpoint number of the Mass Storage host-to-device data OUT endpoint. */
|
||||
#define MASS_STORAGE_OUT_EPNUM 4
|
||||
|
||||
/** Size in bytes of the Mass Storage data endpoints. */
|
||||
#define MASS_STORAGE_IO_EPSIZE 64
|
||||
|
||||
/* Type Defines: */
|
||||
/** 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
|
||||
* vary between devices, and which describe the device's usage to the host.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
USB_Descriptor_Configuration_Header_t Config;
|
||||
USB_Descriptor_Interface_t MS_Interface;
|
||||
USB_Descriptor_Endpoint_t MS_DataInEndpoint;
|
||||
USB_Descriptor_Endpoint_t MS_DataOutEndpoint;
|
||||
} USB_Descriptor_Configuration_t;
|
||||
|
||||
/* Function Prototypes: */
|
||||
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);
|
||||
|
||||
#endif
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Header file for Descriptors.c.
|
||||
*/
|
||||
|
||||
#ifndef _DESCRIPTORS_H_
|
||||
#define _DESCRIPTORS_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/pgmspace.h>
|
||||
|
||||
#include <LUFA/Drivers/USB/USB.h>
|
||||
#include <LUFA/Drivers/USB/Class/MassStorage.h>
|
||||
|
||||
/* Macros: */
|
||||
/** Endpoint number of the Mass Storage device-to-host data IN endpoint. */
|
||||
#define MASS_STORAGE_IN_EPNUM 3
|
||||
|
||||
/** Endpoint number of the Mass Storage host-to-device data OUT endpoint. */
|
||||
#define MASS_STORAGE_OUT_EPNUM 4
|
||||
|
||||
/** Size in bytes of the Mass Storage data endpoints. */
|
||||
#define MASS_STORAGE_IO_EPSIZE 64
|
||||
|
||||
/* Type Defines: */
|
||||
/** 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
|
||||
* vary between devices, and which describe the device's usage to the host.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
USB_Descriptor_Configuration_Header_t Config;
|
||||
USB_Descriptor_Interface_t MS_Interface;
|
||||
USB_Descriptor_Endpoint_t MS_DataInEndpoint;
|
||||
USB_Descriptor_Endpoint_t MS_DataOutEndpoint;
|
||||
} USB_Descriptor_Configuration_t;
|
||||
|
||||
/* Function Prototypes: */
|
||||
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);
|
||||
|
||||
#endif
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,81 +1,81 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Header file for DataflashManager.c.
|
||||
*/
|
||||
|
||||
#ifndef _DATAFLASH_MANAGER_H_
|
||||
#define _DATAFLASH_MANAGER_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/io.h>
|
||||
|
||||
#include "MassStorage.h"
|
||||
#include "Descriptors.h"
|
||||
|
||||
#include <LUFA/Common/Common.h>
|
||||
#include <LUFA/Drivers/USB/USB.h>
|
||||
#include <LUFA/Drivers/USB/Class/MassStorage.h>
|
||||
#include <LUFA/Drivers/Board/Dataflash.h>
|
||||
|
||||
/* Preprocessor Checks: */
|
||||
#if (DATAFLASH_PAGE_SIZE % 16)
|
||||
#error Dataflash page size must be a multiple of 16 bytes.
|
||||
#endif
|
||||
|
||||
/* Defines: */
|
||||
/** 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)
|
||||
|
||||
/** 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.
|
||||
*/
|
||||
#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
|
||||
* change this value; change VIRTUAL_MEMORY_BYTES instead to alter the media size.
|
||||
*/
|
||||
#define VIRTUAL_MEMORY_BLOCKS (VIRTUAL_MEMORY_BYTES / VIRTUAL_MEMORY_BLOCK_SIZE)
|
||||
|
||||
/* Function Prototypes: */
|
||||
void DataflashManager_WriteBlocks(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);
|
||||
void DataflashManager_WriteBlocks_RAM(const uint32_t BlockAddress, uint16_t TotalBlocks,
|
||||
uint8_t* BufferPtr) ATTR_NON_NULL_PTR_ARG(3);
|
||||
void DataflashManager_ReadBlocks_RAM(const uint32_t BlockAddress, uint16_t TotalBlocks,
|
||||
uint8_t* BufferPtr) ATTR_NON_NULL_PTR_ARG(3);
|
||||
void DataflashManager_ResetDataflashProtections(void);
|
||||
bool DataflashManager_CheckDataflashOperation(void);
|
||||
|
||||
#endif
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Header file for DataflashManager.c.
|
||||
*/
|
||||
|
||||
#ifndef _DATAFLASH_MANAGER_H_
|
||||
#define _DATAFLASH_MANAGER_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/io.h>
|
||||
|
||||
#include "MassStorage.h"
|
||||
#include "Descriptors.h"
|
||||
|
||||
#include <LUFA/Common/Common.h>
|
||||
#include <LUFA/Drivers/USB/USB.h>
|
||||
#include <LUFA/Drivers/USB/Class/MassStorage.h>
|
||||
#include <LUFA/Drivers/Board/Dataflash.h>
|
||||
|
||||
/* Preprocessor Checks: */
|
||||
#if (DATAFLASH_PAGE_SIZE % 16)
|
||||
#error Dataflash page size must be a multiple of 16 bytes.
|
||||
#endif
|
||||
|
||||
/* Defines: */
|
||||
/** 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)
|
||||
|
||||
/** 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.
|
||||
*/
|
||||
#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
|
||||
* change this value; change VIRTUAL_MEMORY_BYTES instead to alter the media size.
|
||||
*/
|
||||
#define VIRTUAL_MEMORY_BLOCKS (VIRTUAL_MEMORY_BYTES / VIRTUAL_MEMORY_BLOCK_SIZE)
|
||||
|
||||
/* Function Prototypes: */
|
||||
void DataflashManager_WriteBlocks(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);
|
||||
void DataflashManager_WriteBlocks_RAM(const uint32_t BlockAddress, uint16_t TotalBlocks,
|
||||
uint8_t* BufferPtr) ATTR_NON_NULL_PTR_ARG(3);
|
||||
void DataflashManager_ReadBlocks_RAM(const uint32_t BlockAddress, uint16_t TotalBlocks,
|
||||
uint8_t* BufferPtr) ATTR_NON_NULL_PTR_ARG(3);
|
||||
void DataflashManager_ResetDataflashProtections(void);
|
||||
bool DataflashManager_CheckDataflashOperation(void);
|
||||
|
||||
#endif
|
||||
|
@ -1,286 +1,286 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* 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,
|
||||
* which wrap around standard SCSI device commands for controlling the actual storage medium.
|
||||
*/
|
||||
|
||||
#define INCLUDE_FROM_SCSI_C
|
||||
#include "SCSI.h"
|
||||
|
||||
/** Structure to hold the SCSI response data to a SCSI INQUIRY command. This gives information about the device's
|
||||
* features and capabilities.
|
||||
*/
|
||||
SCSI_Inquiry_Response_t InquiryData =
|
||||
{
|
||||
.DeviceType = DEVICE_TYPE_BLOCK,
|
||||
.PeripheralQualifier = 0,
|
||||
|
||||
.Removable = true,
|
||||
|
||||
.Version = 0,
|
||||
|
||||
.ResponseDataFormat = 2,
|
||||
.NormACA = false,
|
||||
.TrmTsk = false,
|
||||
.AERC = false,
|
||||
|
||||
.AdditionalLength = 0x1F,
|
||||
|
||||
.SoftReset = false,
|
||||
.CmdQue = false,
|
||||
.Linked = false,
|
||||
.Sync = false,
|
||||
.WideBus16Bit = false,
|
||||
.WideBus32Bit = false,
|
||||
.RelAddr = false,
|
||||
|
||||
.VendorID = "LUFA",
|
||||
.ProductID = "Dataflash Disk",
|
||||
.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
|
||||
* command is issued. This gives information on exactly why the last command failed to complete.
|
||||
*/
|
||||
SCSI_Request_Sense_Response_t SenseData =
|
||||
{
|
||||
.ResponseCode = 0x70,
|
||||
.AdditionalLength = 0x0A,
|
||||
};
|
||||
|
||||
|
||||
/** 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
|
||||
* 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
|
||||
*/
|
||||
bool SCSI_DecodeSCSICommand(USB_ClassInfo_MS_Device_t* MSInterfaceInfo)
|
||||
{
|
||||
/* Set initial sense data, before the requested command is processed */
|
||||
SCSI_SET_SENSE(SCSI_SENSE_KEY_GOOD,
|
||||
SCSI_ASENSE_NO_ADDITIONAL_INFORMATION,
|
||||
SCSI_ASENSEQ_NO_QUALIFIER);
|
||||
|
||||
/* Run the appropriate SCSI command hander function based on the passed command */
|
||||
switch (MSInterfaceInfo->State.CommandBlock.SCSICommandData[0])
|
||||
{
|
||||
case SCSI_CMD_INQUIRY:
|
||||
SCSI_Command_Inquiry(MSInterfaceInfo);
|
||||
break;
|
||||
case SCSI_CMD_REQUEST_SENSE:
|
||||
SCSI_Command_Request_Sense(MSInterfaceInfo);
|
||||
break;
|
||||
case SCSI_CMD_READ_CAPACITY_10:
|
||||
SCSI_Command_Read_Capacity_10(MSInterfaceInfo);
|
||||
break;
|
||||
case SCSI_CMD_SEND_DIAGNOSTIC:
|
||||
SCSI_Command_Send_Diagnostic(MSInterfaceInfo);
|
||||
break;
|
||||
case SCSI_CMD_WRITE_10:
|
||||
SCSI_Command_ReadWrite_10(MSInterfaceInfo, DATA_WRITE);
|
||||
break;
|
||||
case SCSI_CMD_READ_10:
|
||||
SCSI_Command_ReadWrite_10(MSInterfaceInfo, DATA_READ);
|
||||
break;
|
||||
case SCSI_CMD_TEST_UNIT_READY:
|
||||
case SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL:
|
||||
case SCSI_CMD_VERIFY_10:
|
||||
/* These commands should just succeed, no handling required */
|
||||
MSInterfaceInfo->State.CommandBlock.DataTransferLength = 0;
|
||||
break;
|
||||
default:
|
||||
/* Update the SENSE key to reflect the invalid command */
|
||||
SCSI_SET_SENSE(SCSI_SENSE_KEY_ILLEGAL_REQUEST,
|
||||
SCSI_ASENSE_INVALID_COMMAND,
|
||||
SCSI_ASENSEQ_NO_QUALIFIER);
|
||||
break;
|
||||
}
|
||||
|
||||
return (SenseData.SenseKey == SCSI_SENSE_KEY_GOOD);
|
||||
}
|
||||
|
||||
/** Command processing for an issued SCSI INQUIRY command. This command returns information about the device's features
|
||||
* and capabilities to the host.
|
||||
*
|
||||
* \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)
|
||||
{
|
||||
uint16_t AllocationLength = (((uint16_t)MSInterfaceInfo->State.CommandBlock.SCSICommandData[3] << 8) |
|
||||
MSInterfaceInfo->State.CommandBlock.SCSICommandData[4]);
|
||||
uint16_t BytesTransferred = (AllocationLength < sizeof(InquiryData))? AllocationLength :
|
||||
sizeof(InquiryData);
|
||||
|
||||
/* Only the standard INQUIRY data is supported, check if any optional INQUIRY bits set */
|
||||
if ((MSInterfaceInfo->State.CommandBlock.SCSICommandData[1] & ((1 << 0) | (1 << 1))) ||
|
||||
MSInterfaceInfo->State.CommandBlock.SCSICommandData[2])
|
||||
{
|
||||
/* Optional but unsupported bits set - update the SENSE key and fail the request */
|
||||
SCSI_SET_SENSE(SCSI_SENSE_KEY_ILLEGAL_REQUEST,
|
||||
SCSI_ASENSE_INVALID_FIELD_IN_CDB,
|
||||
SCSI_ASENSEQ_NO_QUALIFIER);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Endpoint_Write_Stream_LE(&InquiryData, BytesTransferred, NO_STREAM_CALLBACK);
|
||||
|
||||
uint8_t PadBytes[AllocationLength - BytesTransferred];
|
||||
|
||||
/* Pad out remaining bytes with 0x00 */
|
||||
Endpoint_Write_Stream_LE(&PadBytes, (AllocationLength - BytesTransferred), NO_STREAM_CALLBACK);
|
||||
|
||||
/* Finalize the stream transfer to send the last packet */
|
||||
Endpoint_ClearIN();
|
||||
|
||||
/* Succeed the command and update the bytes transferred counter */
|
||||
MSInterfaceInfo->State.CommandBlock.DataTransferLength -= BytesTransferred;
|
||||
}
|
||||
|
||||
/** 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.
|
||||
*
|
||||
* \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)
|
||||
{
|
||||
uint8_t AllocationLength = MSInterfaceInfo->State.CommandBlock.SCSICommandData[4];
|
||||
uint8_t BytesTransferred = (AllocationLength < sizeof(SenseData))? AllocationLength : sizeof(SenseData);
|
||||
|
||||
uint8_t PadBytes[AllocationLength - BytesTransferred];
|
||||
|
||||
Endpoint_Write_Stream_LE(&SenseData, BytesTransferred, NO_STREAM_CALLBACK);
|
||||
Endpoint_Write_Stream_LE(&PadBytes, (AllocationLength - BytesTransferred), NO_STREAM_CALLBACK);
|
||||
Endpoint_ClearIN();
|
||||
|
||||
/* Succeed the command and update the bytes transferred counter */
|
||||
MSInterfaceInfo->State.CommandBlock.DataTransferLength -= BytesTransferred;
|
||||
}
|
||||
|
||||
/** 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.
|
||||
*
|
||||
* \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)
|
||||
{
|
||||
uint32_t LastBlockAddressInLUN = (LUN_MEDIA_BLOCKS - 1);
|
||||
uint32_t MediaBlockSize = VIRTUAL_MEMORY_BLOCK_SIZE;
|
||||
|
||||
Endpoint_Write_Stream_BE(&LastBlockAddressInLUN, sizeof(LastBlockAddressInLUN), NO_STREAM_CALLBACK);
|
||||
Endpoint_Write_Stream_BE(&MediaBlockSize, sizeof(MediaBlockSize), NO_STREAM_CALLBACK);
|
||||
Endpoint_ClearIN();
|
||||
|
||||
/* Succeed the command and update the bytes transferred counter */
|
||||
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
|
||||
* board, and indicates if they are present and functioning correctly. Only the Self-Test portion of the diagnostic command is
|
||||
* supported.
|
||||
*
|
||||
* \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)
|
||||
{
|
||||
/* Check to see if the SELF TEST bit is not set */
|
||||
if (!(MSInterfaceInfo->State.CommandBlock.SCSICommandData[1] & (1 << 2)))
|
||||
{
|
||||
/* Only self-test supported - update SENSE key and fail the command */
|
||||
SCSI_SET_SENSE(SCSI_SENSE_KEY_ILLEGAL_REQUEST,
|
||||
SCSI_ASENSE_INVALID_FIELD_IN_CDB,
|
||||
SCSI_ASENSEQ_NO_QUALIFIER);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Check to see if all attached Dataflash ICs are functional */
|
||||
if (!(DataflashManager_CheckDataflashOperation()))
|
||||
{
|
||||
/* Update SENSE key with a hardware error condition and return command fail */
|
||||
SCSI_SET_SENSE(SCSI_SENSE_KEY_HARDWARE_ERROR,
|
||||
SCSI_ASENSE_NO_ADDITIONAL_INFORMATION,
|
||||
SCSI_ASENSEQ_NO_QUALIFIER);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Succeed the command and update the bytes transferred counter */
|
||||
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
|
||||
* 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.
|
||||
*
|
||||
* \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)
|
||||
*/
|
||||
static void SCSI_Command_ReadWrite_10(USB_ClassInfo_MS_Device_t* MSInterfaceInfo, const bool IsDataRead)
|
||||
{
|
||||
uint32_t BlockAddress;
|
||||
uint16_t TotalBlocks;
|
||||
|
||||
/* 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]);
|
||||
|
||||
/* 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]);
|
||||
|
||||
/* Check if the block address is outside the maximum allowable value for the LUN */
|
||||
if (BlockAddress >= LUN_MEDIA_BLOCKS)
|
||||
{
|
||||
/* Block address is invalid, update SENSE key and return command fail */
|
||||
SCSI_SET_SENSE(SCSI_SENSE_KEY_ILLEGAL_REQUEST,
|
||||
SCSI_ASENSE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
|
||||
SCSI_ASENSEQ_NO_QUALIFIER);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
#if (TOTAL_LUNS > 1)
|
||||
/* 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);
|
||||
#endif
|
||||
|
||||
/* Determine if the packet is a READ (10) or WRITE (10) command, call appropriate function */
|
||||
if (IsDataRead == DATA_READ)
|
||||
DataflashManager_ReadBlocks(MSInterfaceInfo, BlockAddress, TotalBlocks);
|
||||
else
|
||||
DataflashManager_WriteBlocks(MSInterfaceInfo, BlockAddress, TotalBlocks);
|
||||
|
||||
/* Update the bytes transferred counter and succeed the command */
|
||||
MSInterfaceInfo->State.CommandBlock.DataTransferLength -= ((uint32_t)TotalBlocks * VIRTUAL_MEMORY_BLOCK_SIZE);
|
||||
}
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* 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,
|
||||
* which wrap around standard SCSI device commands for controlling the actual storage medium.
|
||||
*/
|
||||
|
||||
#define INCLUDE_FROM_SCSI_C
|
||||
#include "SCSI.h"
|
||||
|
||||
/** Structure to hold the SCSI response data to a SCSI INQUIRY command. This gives information about the device's
|
||||
* features and capabilities.
|
||||
*/
|
||||
SCSI_Inquiry_Response_t InquiryData =
|
||||
{
|
||||
.DeviceType = DEVICE_TYPE_BLOCK,
|
||||
.PeripheralQualifier = 0,
|
||||
|
||||
.Removable = true,
|
||||
|
||||
.Version = 0,
|
||||
|
||||
.ResponseDataFormat = 2,
|
||||
.NormACA = false,
|
||||
.TrmTsk = false,
|
||||
.AERC = false,
|
||||
|
||||
.AdditionalLength = 0x1F,
|
||||
|
||||
.SoftReset = false,
|
||||
.CmdQue = false,
|
||||
.Linked = false,
|
||||
.Sync = false,
|
||||
.WideBus16Bit = false,
|
||||
.WideBus32Bit = false,
|
||||
.RelAddr = false,
|
||||
|
||||
.VendorID = "LUFA",
|
||||
.ProductID = "Dataflash Disk",
|
||||
.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
|
||||
* command is issued. This gives information on exactly why the last command failed to complete.
|
||||
*/
|
||||
SCSI_Request_Sense_Response_t SenseData =
|
||||
{
|
||||
.ResponseCode = 0x70,
|
||||
.AdditionalLength = 0x0A,
|
||||
};
|
||||
|
||||
|
||||
/** 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
|
||||
* 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
|
||||
*/
|
||||
bool SCSI_DecodeSCSICommand(USB_ClassInfo_MS_Device_t* MSInterfaceInfo)
|
||||
{
|
||||
/* Set initial sense data, before the requested command is processed */
|
||||
SCSI_SET_SENSE(SCSI_SENSE_KEY_GOOD,
|
||||
SCSI_ASENSE_NO_ADDITIONAL_INFORMATION,
|
||||
SCSI_ASENSEQ_NO_QUALIFIER);
|
||||
|
||||
/* Run the appropriate SCSI command hander function based on the passed command */
|
||||
switch (MSInterfaceInfo->State.CommandBlock.SCSICommandData[0])
|
||||
{
|
||||
case SCSI_CMD_INQUIRY:
|
||||
SCSI_Command_Inquiry(MSInterfaceInfo);
|
||||
break;
|
||||
case SCSI_CMD_REQUEST_SENSE:
|
||||
SCSI_Command_Request_Sense(MSInterfaceInfo);
|
||||
break;
|
||||
case SCSI_CMD_READ_CAPACITY_10:
|
||||
SCSI_Command_Read_Capacity_10(MSInterfaceInfo);
|
||||
break;
|
||||
case SCSI_CMD_SEND_DIAGNOSTIC:
|
||||
SCSI_Command_Send_Diagnostic(MSInterfaceInfo);
|
||||
break;
|
||||
case SCSI_CMD_WRITE_10:
|
||||
SCSI_Command_ReadWrite_10(MSInterfaceInfo, DATA_WRITE);
|
||||
break;
|
||||
case SCSI_CMD_READ_10:
|
||||
SCSI_Command_ReadWrite_10(MSInterfaceInfo, DATA_READ);
|
||||
break;
|
||||
case SCSI_CMD_TEST_UNIT_READY:
|
||||
case SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL:
|
||||
case SCSI_CMD_VERIFY_10:
|
||||
/* These commands should just succeed, no handling required */
|
||||
MSInterfaceInfo->State.CommandBlock.DataTransferLength = 0;
|
||||
break;
|
||||
default:
|
||||
/* Update the SENSE key to reflect the invalid command */
|
||||
SCSI_SET_SENSE(SCSI_SENSE_KEY_ILLEGAL_REQUEST,
|
||||
SCSI_ASENSE_INVALID_COMMAND,
|
||||
SCSI_ASENSEQ_NO_QUALIFIER);
|
||||
break;
|
||||
}
|
||||
|
||||
return (SenseData.SenseKey == SCSI_SENSE_KEY_GOOD);
|
||||
}
|
||||
|
||||
/** Command processing for an issued SCSI INQUIRY command. This command returns information about the device's features
|
||||
* and capabilities to the host.
|
||||
*
|
||||
* \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)
|
||||
{
|
||||
uint16_t AllocationLength = (((uint16_t)MSInterfaceInfo->State.CommandBlock.SCSICommandData[3] << 8) |
|
||||
MSInterfaceInfo->State.CommandBlock.SCSICommandData[4]);
|
||||
uint16_t BytesTransferred = (AllocationLength < sizeof(InquiryData))? AllocationLength :
|
||||
sizeof(InquiryData);
|
||||
|
||||
/* Only the standard INQUIRY data is supported, check if any optional INQUIRY bits set */
|
||||
if ((MSInterfaceInfo->State.CommandBlock.SCSICommandData[1] & ((1 << 0) | (1 << 1))) ||
|
||||
MSInterfaceInfo->State.CommandBlock.SCSICommandData[2])
|
||||
{
|
||||
/* Optional but unsupported bits set - update the SENSE key and fail the request */
|
||||
SCSI_SET_SENSE(SCSI_SENSE_KEY_ILLEGAL_REQUEST,
|
||||
SCSI_ASENSE_INVALID_FIELD_IN_CDB,
|
||||
SCSI_ASENSEQ_NO_QUALIFIER);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Endpoint_Write_Stream_LE(&InquiryData, BytesTransferred, NO_STREAM_CALLBACK);
|
||||
|
||||
uint8_t PadBytes[AllocationLength - BytesTransferred];
|
||||
|
||||
/* Pad out remaining bytes with 0x00 */
|
||||
Endpoint_Write_Stream_LE(&PadBytes, (AllocationLength - BytesTransferred), NO_STREAM_CALLBACK);
|
||||
|
||||
/* Finalize the stream transfer to send the last packet */
|
||||
Endpoint_ClearIN();
|
||||
|
||||
/* Succeed the command and update the bytes transferred counter */
|
||||
MSInterfaceInfo->State.CommandBlock.DataTransferLength -= BytesTransferred;
|
||||
}
|
||||
|
||||
/** 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.
|
||||
*
|
||||
* \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)
|
||||
{
|
||||
uint8_t AllocationLength = MSInterfaceInfo->State.CommandBlock.SCSICommandData[4];
|
||||
uint8_t BytesTransferred = (AllocationLength < sizeof(SenseData))? AllocationLength : sizeof(SenseData);
|
||||
|
||||
uint8_t PadBytes[AllocationLength - BytesTransferred];
|
||||
|
||||
Endpoint_Write_Stream_LE(&SenseData, BytesTransferred, NO_STREAM_CALLBACK);
|
||||
Endpoint_Write_Stream_LE(&PadBytes, (AllocationLength - BytesTransferred), NO_STREAM_CALLBACK);
|
||||
Endpoint_ClearIN();
|
||||
|
||||
/* Succeed the command and update the bytes transferred counter */
|
||||
MSInterfaceInfo->State.CommandBlock.DataTransferLength -= BytesTransferred;
|
||||
}
|
||||
|
||||
/** 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.
|
||||
*
|
||||
* \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)
|
||||
{
|
||||
uint32_t LastBlockAddressInLUN = (LUN_MEDIA_BLOCKS - 1);
|
||||
uint32_t MediaBlockSize = VIRTUAL_MEMORY_BLOCK_SIZE;
|
||||
|
||||
Endpoint_Write_Stream_BE(&LastBlockAddressInLUN, sizeof(LastBlockAddressInLUN), NO_STREAM_CALLBACK);
|
||||
Endpoint_Write_Stream_BE(&MediaBlockSize, sizeof(MediaBlockSize), NO_STREAM_CALLBACK);
|
||||
Endpoint_ClearIN();
|
||||
|
||||
/* Succeed the command and update the bytes transferred counter */
|
||||
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
|
||||
* board, and indicates if they are present and functioning correctly. Only the Self-Test portion of the diagnostic command is
|
||||
* supported.
|
||||
*
|
||||
* \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)
|
||||
{
|
||||
/* Check to see if the SELF TEST bit is not set */
|
||||
if (!(MSInterfaceInfo->State.CommandBlock.SCSICommandData[1] & (1 << 2)))
|
||||
{
|
||||
/* Only self-test supported - update SENSE key and fail the command */
|
||||
SCSI_SET_SENSE(SCSI_SENSE_KEY_ILLEGAL_REQUEST,
|
||||
SCSI_ASENSE_INVALID_FIELD_IN_CDB,
|
||||
SCSI_ASENSEQ_NO_QUALIFIER);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Check to see if all attached Dataflash ICs are functional */
|
||||
if (!(DataflashManager_CheckDataflashOperation()))
|
||||
{
|
||||
/* Update SENSE key with a hardware error condition and return command fail */
|
||||
SCSI_SET_SENSE(SCSI_SENSE_KEY_HARDWARE_ERROR,
|
||||
SCSI_ASENSE_NO_ADDITIONAL_INFORMATION,
|
||||
SCSI_ASENSEQ_NO_QUALIFIER);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Succeed the command and update the bytes transferred counter */
|
||||
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
|
||||
* 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.
|
||||
*
|
||||
* \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)
|
||||
*/
|
||||
static void SCSI_Command_ReadWrite_10(USB_ClassInfo_MS_Device_t* MSInterfaceInfo, const bool IsDataRead)
|
||||
{
|
||||
uint32_t BlockAddress;
|
||||
uint16_t TotalBlocks;
|
||||
|
||||
/* 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]);
|
||||
|
||||
/* 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]);
|
||||
|
||||
/* Check if the block address is outside the maximum allowable value for the LUN */
|
||||
if (BlockAddress >= LUN_MEDIA_BLOCKS)
|
||||
{
|
||||
/* Block address is invalid, update SENSE key and return command fail */
|
||||
SCSI_SET_SENSE(SCSI_SENSE_KEY_ILLEGAL_REQUEST,
|
||||
SCSI_ASENSE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
|
||||
SCSI_ASENSEQ_NO_QUALIFIER);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
#if (TOTAL_LUNS > 1)
|
||||
/* 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);
|
||||
#endif
|
||||
|
||||
/* Determine if the packet is a READ (10) or WRITE (10) command, call appropriate function */
|
||||
if (IsDataRead == DATA_READ)
|
||||
DataflashManager_ReadBlocks(MSInterfaceInfo, BlockAddress, TotalBlocks);
|
||||
else
|
||||
DataflashManager_WriteBlocks(MSInterfaceInfo, BlockAddress, TotalBlocks);
|
||||
|
||||
/* Update the bytes transferred counter and succeed the command */
|
||||
MSInterfaceInfo->State.CommandBlock.DataTransferLength -= ((uint32_t)TotalBlocks * VIRTUAL_MEMORY_BLOCK_SIZE);
|
||||
}
|
||||
|
@ -1,86 +1,86 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Header file for SCSI.c.
|
||||
*/
|
||||
|
||||
#ifndef _SCSI_H_
|
||||
#define _SCSI_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/io.h>
|
||||
#include <avr/pgmspace.h>
|
||||
|
||||
#include <LUFA/Drivers/USB/USB.h>
|
||||
#include <LUFA/Drivers/USB/Class/MassStorage.h>
|
||||
|
||||
#include "MassStorage.h"
|
||||
#include "Descriptors.h"
|
||||
#include "DataflashManager.h"
|
||||
|
||||
/* Macros: */
|
||||
/** 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
|
||||
* 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] 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
|
||||
*/
|
||||
#define SCSI_SET_SENSE(key, acode, aqual) MACROS{ SenseData.SenseKey = (key); \
|
||||
SenseData.AdditionalSenseCode = (acode); \
|
||||
SenseData.AdditionalSenseQualifier = (aqual); }MACROE
|
||||
|
||||
/** Macro for the SCSI_Command_ReadWrite_10() function, to indicate that data is to be read from the storage medium. */
|
||||
#define DATA_READ true
|
||||
|
||||
/** Macro for the SCSI_Command_ReadWrite_10() function, to indicate that data is to be written to the storage medium. */
|
||||
#define DATA_WRITE false
|
||||
|
||||
/** Value for the DeviceType entry in the SCSI_Inquiry_Response_t enum, indicating a Block Media device. */
|
||||
#define DEVICE_TYPE_BLOCK 0x00
|
||||
|
||||
/** Value for the DeviceType entry in the SCSI_Inquiry_Response_t enum, indicating a CD-ROM device. */
|
||||
#define DEVICE_TYPE_CDROM 0x05
|
||||
|
||||
/* Function Prototypes: */
|
||||
bool SCSI_DecodeSCSICommand(USB_ClassInfo_MS_Device_t* MSInterfaceInfo);
|
||||
|
||||
#if defined(INCLUDE_FROM_SCSI_C)
|
||||
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_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_ReadWrite_10(USB_ClassInfo_MS_Device_t* MSInterfaceInfo, const bool IsDataRead);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Header file for SCSI.c.
|
||||
*/
|
||||
|
||||
#ifndef _SCSI_H_
|
||||
#define _SCSI_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/io.h>
|
||||
#include <avr/pgmspace.h>
|
||||
|
||||
#include <LUFA/Drivers/USB/USB.h>
|
||||
#include <LUFA/Drivers/USB/Class/MassStorage.h>
|
||||
|
||||
#include "MassStorage.h"
|
||||
#include "Descriptors.h"
|
||||
#include "DataflashManager.h"
|
||||
|
||||
/* Macros: */
|
||||
/** 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
|
||||
* 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] 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
|
||||
*/
|
||||
#define SCSI_SET_SENSE(key, acode, aqual) MACROS{ SenseData.SenseKey = (key); \
|
||||
SenseData.AdditionalSenseCode = (acode); \
|
||||
SenseData.AdditionalSenseQualifier = (aqual); }MACROE
|
||||
|
||||
/** Macro for the SCSI_Command_ReadWrite_10() function, to indicate that data is to be read from the storage medium. */
|
||||
#define DATA_READ true
|
||||
|
||||
/** Macro for the SCSI_Command_ReadWrite_10() function, to indicate that data is to be written to the storage medium. */
|
||||
#define DATA_WRITE false
|
||||
|
||||
/** Value for the DeviceType entry in the SCSI_Inquiry_Response_t enum, indicating a Block Media device. */
|
||||
#define DEVICE_TYPE_BLOCK 0x00
|
||||
|
||||
/** Value for the DeviceType entry in the SCSI_Inquiry_Response_t enum, indicating a CD-ROM device. */
|
||||
#define DEVICE_TYPE_CDROM 0x05
|
||||
|
||||
/* Function Prototypes: */
|
||||
bool SCSI_DecodeSCSICommand(USB_ClassInfo_MS_Device_t* MSInterfaceInfo);
|
||||
|
||||
#if defined(INCLUDE_FROM_SCSI_C)
|
||||
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_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_ReadWrite_10(USB_ClassInfo_MS_Device_t* MSInterfaceInfo, const bool IsDataRead);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -1,138 +1,138 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Main source file for the MassStorage demo. This file contains the main tasks of
|
||||
* the demo and is responsible for the initial application hardware configuration.
|
||||
*/
|
||||
|
||||
#include "MassStorage.h"
|
||||
|
||||
/** 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
|
||||
* within a device can be differentiated from one another.
|
||||
*/
|
||||
USB_ClassInfo_MS_Device_t Disk_MS_Interface =
|
||||
{
|
||||
.Config =
|
||||
{
|
||||
.InterfaceNumber = 0,
|
||||
|
||||
.DataINEndpointNumber = MASS_STORAGE_IN_EPNUM,
|
||||
.DataINEndpointSize = MASS_STORAGE_IO_EPSIZE,
|
||||
.DataINEndpointDoubleBank = false,
|
||||
|
||||
.DataOUTEndpointNumber = MASS_STORAGE_OUT_EPNUM,
|
||||
.DataOUTEndpointSize = MASS_STORAGE_IO_EPSIZE,
|
||||
.DataOUTEndpointDoubleBank = false,
|
||||
|
||||
.TotalLUNs = TOTAL_LUNS,
|
||||
},
|
||||
};
|
||||
|
||||
/** Main program entry point. This routine contains the overall program flow, including initial
|
||||
* setup of all components and the main program loop.
|
||||
*/
|
||||
int main(void)
|
||||
{
|
||||
SetupHardware();
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
|
||||
sei();
|
||||
|
||||
for (;;)
|
||||
{
|
||||
MS_Device_USBTask(&Disk_MS_Interface);
|
||||
USB_USBTask();
|
||||
}
|
||||
}
|
||||
|
||||
/** Configures the board hardware and chip peripherals for the demo's functionality. */
|
||||
void SetupHardware(void)
|
||||
{
|
||||
/* Disable watchdog if enabled by bootloader/fuses */
|
||||
MCUSR &= ~(1 << WDRF);
|
||||
wdt_disable();
|
||||
|
||||
/* Disable clock division */
|
||||
clock_prescale_set(clock_div_1);
|
||||
|
||||
/* Hardware Initialization */
|
||||
LEDs_Init();
|
||||
SPI_Init(SPI_SPEED_FCPU_DIV_2 | SPI_SCK_LEAD_FALLING | SPI_SAMPLE_TRAILING | SPI_MODE_MASTER);
|
||||
Dataflash_Init();
|
||||
USB_Init();
|
||||
|
||||
/* Clear Dataflash sector protections, if enabled */
|
||||
DataflashManager_ResetDataflashProtections();
|
||||
}
|
||||
|
||||
/** Event handler for the library USB Connection event. */
|
||||
void EVENT_USB_Device_Connect(void)
|
||||
{
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
|
||||
}
|
||||
|
||||
/** Event handler for the library USB Disconnection event. */
|
||||
void EVENT_USB_Device_Disconnect(void)
|
||||
{
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
|
||||
}
|
||||
|
||||
/** Event handler for the library USB Configuration Changed event. */
|
||||
void EVENT_USB_Device_ConfigurationChanged(void)
|
||||
{
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
|
||||
if (!(MS_Device_ConfigureEndpoints(&Disk_MS_Interface)))
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
}
|
||||
|
||||
/** Event handler for the library USB Unhandled Control Request event. */
|
||||
void EVENT_USB_Device_UnhandledControlRequest(void)
|
||||
{
|
||||
MS_Device_ProcessControlRequest(&Disk_MS_Interface);
|
||||
}
|
||||
|
||||
/** 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
|
||||
*/
|
||||
bool CALLBACK_MS_Device_SCSICommandReceived(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo)
|
||||
{
|
||||
bool CommandSuccess;
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_BUSY);
|
||||
CommandSuccess = SCSI_DecodeSCSICommand(MSInterfaceInfo);
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
|
||||
return CommandSuccess;
|
||||
}
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Main source file for the MassStorage demo. This file contains the main tasks of
|
||||
* the demo and is responsible for the initial application hardware configuration.
|
||||
*/
|
||||
|
||||
#include "MassStorage.h"
|
||||
|
||||
/** 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
|
||||
* within a device can be differentiated from one another.
|
||||
*/
|
||||
USB_ClassInfo_MS_Device_t Disk_MS_Interface =
|
||||
{
|
||||
.Config =
|
||||
{
|
||||
.InterfaceNumber = 0,
|
||||
|
||||
.DataINEndpointNumber = MASS_STORAGE_IN_EPNUM,
|
||||
.DataINEndpointSize = MASS_STORAGE_IO_EPSIZE,
|
||||
.DataINEndpointDoubleBank = false,
|
||||
|
||||
.DataOUTEndpointNumber = MASS_STORAGE_OUT_EPNUM,
|
||||
.DataOUTEndpointSize = MASS_STORAGE_IO_EPSIZE,
|
||||
.DataOUTEndpointDoubleBank = false,
|
||||
|
||||
.TotalLUNs = TOTAL_LUNS,
|
||||
},
|
||||
};
|
||||
|
||||
/** Main program entry point. This routine contains the overall program flow, including initial
|
||||
* setup of all components and the main program loop.
|
||||
*/
|
||||
int main(void)
|
||||
{
|
||||
SetupHardware();
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
|
||||
sei();
|
||||
|
||||
for (;;)
|
||||
{
|
||||
MS_Device_USBTask(&Disk_MS_Interface);
|
||||
USB_USBTask();
|
||||
}
|
||||
}
|
||||
|
||||
/** Configures the board hardware and chip peripherals for the demo's functionality. */
|
||||
void SetupHardware(void)
|
||||
{
|
||||
/* Disable watchdog if enabled by bootloader/fuses */
|
||||
MCUSR &= ~(1 << WDRF);
|
||||
wdt_disable();
|
||||
|
||||
/* Disable clock division */
|
||||
clock_prescale_set(clock_div_1);
|
||||
|
||||
/* Hardware Initialization */
|
||||
LEDs_Init();
|
||||
SPI_Init(SPI_SPEED_FCPU_DIV_2 | SPI_SCK_LEAD_FALLING | SPI_SAMPLE_TRAILING | SPI_MODE_MASTER);
|
||||
Dataflash_Init();
|
||||
USB_Init();
|
||||
|
||||
/* Clear Dataflash sector protections, if enabled */
|
||||
DataflashManager_ResetDataflashProtections();
|
||||
}
|
||||
|
||||
/** Event handler for the library USB Connection event. */
|
||||
void EVENT_USB_Device_Connect(void)
|
||||
{
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
|
||||
}
|
||||
|
||||
/** Event handler for the library USB Disconnection event. */
|
||||
void EVENT_USB_Device_Disconnect(void)
|
||||
{
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
|
||||
}
|
||||
|
||||
/** Event handler for the library USB Configuration Changed event. */
|
||||
void EVENT_USB_Device_ConfigurationChanged(void)
|
||||
{
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
|
||||
if (!(MS_Device_ConfigureEndpoints(&Disk_MS_Interface)))
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
}
|
||||
|
||||
/** Event handler for the library USB Unhandled Control Request event. */
|
||||
void EVENT_USB_Device_UnhandledControlRequest(void)
|
||||
{
|
||||
MS_Device_ProcessControlRequest(&Disk_MS_Interface);
|
||||
}
|
||||
|
||||
/** 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
|
||||
*/
|
||||
bool CALLBACK_MS_Device_SCSICommandReceived(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo)
|
||||
{
|
||||
bool CommandSuccess;
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_BUSY);
|
||||
CommandSuccess = SCSI_DecodeSCSICommand(MSInterfaceInfo);
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
|
||||
return CommandSuccess;
|
||||
}
|
||||
|
@ -1,88 +1,88 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Header file for MassStorage.c.
|
||||
*/
|
||||
|
||||
#ifndef _MASS_STORAGE_H_
|
||||
#define _MASS_STORAGE_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/io.h>
|
||||
#include <avr/wdt.h>
|
||||
#include <avr/power.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "Descriptors.h"
|
||||
|
||||
#include "Lib/SCSI.h"
|
||||
#include "Lib/DataflashManager.h"
|
||||
|
||||
#include <LUFA/Version.h>
|
||||
#include <LUFA/Drivers/Board/LEDs.h>
|
||||
#include <LUFA/Drivers/USB/USB.h>
|
||||
#include <LUFA/Drivers/USB/Class/MassStorage.h>
|
||||
|
||||
/* Macros: */
|
||||
/** LED mask for the library LED driver, to indicate that the USB interface is not ready. */
|
||||
#define LEDMASK_USB_NOTREADY LEDS_LED1
|
||||
|
||||
/** LED mask for the library LED driver, to indicate that the USB interface is enumerating. */
|
||||
#define LEDMASK_USB_ENUMERATING (LEDS_LED2 | LEDS_LED3)
|
||||
|
||||
/** LED mask for the library LED driver, to indicate that the USB interface is ready. */
|
||||
#define LEDMASK_USB_READY (LEDS_LED2 | LEDS_LED4)
|
||||
|
||||
/** LED mask for the library LED driver, to indicate that an error has occurred in the USB interface. */
|
||||
#define LEDMASK_USB_ERROR (LEDS_LED1 | LEDS_LED3)
|
||||
|
||||
/** LED mask for the library LED driver, to indicate that the USB interface is busy. */
|
||||
#define LEDMASK_USB_BUSY LEDS_LED2
|
||||
|
||||
/** Total number of logical drives within the device - must be non-zero. */
|
||||
#define TOTAL_LUNS 1
|
||||
|
||||
/** 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)
|
||||
|
||||
/* Function Prototypes: */
|
||||
void SetupHardware(void);
|
||||
|
||||
void EVENT_USB_Device_Connect(void);
|
||||
void EVENT_USB_Device_Disconnect(void);
|
||||
void EVENT_USB_Device_ConfigurationChanged(void);
|
||||
void EVENT_USB_Device_UnhandledControlRequest(void);
|
||||
|
||||
bool CALLBACK_MS_Device_SCSICommandReceived(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo);
|
||||
|
||||
#endif
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Header file for MassStorage.c.
|
||||
*/
|
||||
|
||||
#ifndef _MASS_STORAGE_H_
|
||||
#define _MASS_STORAGE_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/io.h>
|
||||
#include <avr/wdt.h>
|
||||
#include <avr/power.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "Descriptors.h"
|
||||
|
||||
#include "Lib/SCSI.h"
|
||||
#include "Lib/DataflashManager.h"
|
||||
|
||||
#include <LUFA/Version.h>
|
||||
#include <LUFA/Drivers/Board/LEDs.h>
|
||||
#include <LUFA/Drivers/USB/USB.h>
|
||||
#include <LUFA/Drivers/USB/Class/MassStorage.h>
|
||||
|
||||
/* Macros: */
|
||||
/** LED mask for the library LED driver, to indicate that the USB interface is not ready. */
|
||||
#define LEDMASK_USB_NOTREADY LEDS_LED1
|
||||
|
||||
/** LED mask for the library LED driver, to indicate that the USB interface is enumerating. */
|
||||
#define LEDMASK_USB_ENUMERATING (LEDS_LED2 | LEDS_LED3)
|
||||
|
||||
/** LED mask for the library LED driver, to indicate that the USB interface is ready. */
|
||||
#define LEDMASK_USB_READY (LEDS_LED2 | LEDS_LED4)
|
||||
|
||||
/** LED mask for the library LED driver, to indicate that an error has occurred in the USB interface. */
|
||||
#define LEDMASK_USB_ERROR (LEDS_LED1 | LEDS_LED3)
|
||||
|
||||
/** LED mask for the library LED driver, to indicate that the USB interface is busy. */
|
||||
#define LEDMASK_USB_BUSY LEDS_LED2
|
||||
|
||||
/** Total number of logical drives within the device - must be non-zero. */
|
||||
#define TOTAL_LUNS 1
|
||||
|
||||
/** 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)
|
||||
|
||||
/* Function Prototypes: */
|
||||
void SetupHardware(void);
|
||||
|
||||
void EVENT_USB_Device_Connect(void);
|
||||
void EVENT_USB_Device_Disconnect(void);
|
||||
void EVENT_USB_Device_ConfigurationChanged(void);
|
||||
void EVENT_USB_Device_UnhandledControlRequest(void);
|
||||
|
||||
bool CALLBACK_MS_Device_SCSICommandReceived(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo);
|
||||
|
||||
#endif
|
||||
|
@ -1,92 +1,92 @@
|
||||
/** \file
|
||||
*
|
||||
* This file contains special DoxyGen information for the generation of the main page and other special
|
||||
* documentation pages. It is not a project source file.
|
||||
*/
|
||||
|
||||
/** \mainpage Mass Storage Device Demo
|
||||
*
|
||||
* \section SSec_Compat Demo Compatibility:
|
||||
*
|
||||
* The following list indicates what microcontrollers are compatible with this demo.
|
||||
*
|
||||
* - Series 7 USB AVRs
|
||||
* - Series 6 USB AVRs
|
||||
* - Series 4 USB AVRs
|
||||
* - Series 2 USB AVRs
|
||||
*
|
||||
* \section SSec_Info USB Information:
|
||||
*
|
||||
* The following table gives a rundown of the USB utilization of this demo.
|
||||
*
|
||||
* <table>
|
||||
* <tr>
|
||||
* <td><b>USB Mode:</b></td>
|
||||
* <td>Device</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>USB Class:</b></td>
|
||||
* <td>Mass Storage Device</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>USB Subclass:</b></td>
|
||||
* <td>Bulk-Only Transport</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>Relevant Standards:</b></td>
|
||||
* <td>USBIF Mass Storage Standard \n
|
||||
* USB Bulk-Only Transport Standard \n
|
||||
* SCSI Primary Commands Specification \n
|
||||
* SCSI Block Commands Specification</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>Usable Speeds:</b></td>
|
||||
* <td>Full Speed Mode</td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*
|
||||
* \section SSec_Description Project Description:
|
||||
*
|
||||
* Dual LUN Mass Storage demonstration application. This gives a simple
|
||||
* reference application for implementing a multiple LUN USB Mass Storage
|
||||
* device using the basic USB UFI drivers in all modern OSes (i.e. no
|
||||
* special drivers required).
|
||||
*
|
||||
* On start-up the system will automatically enumerate and function as an
|
||||
* external mass storage device with two LUNs (separate disks) which may
|
||||
* be formatted and used in the same manner as commercial USB Mass Storage
|
||||
* devices.
|
||||
*
|
||||
* 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
|
||||
* 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.
|
||||
*
|
||||
* 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
|
||||
* 255), with each LUN being allocated an equal portion of the available
|
||||
* Dataflash memory.
|
||||
*
|
||||
* The USB control endpoint is managed entirely by the library using endpoint
|
||||
* 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 need for complicated polling logic.
|
||||
*
|
||||
* \section SSec_Options Project Options
|
||||
*
|
||||
* The following defines can be found in this demo, which can control the demo behaviour when defined, or changed in value.
|
||||
*
|
||||
* <table>
|
||||
* <tr>
|
||||
* <td><b>Define Name:</b></td>
|
||||
* <td><b>Location:</b></td>
|
||||
* <td><b>Description:</b></td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>TOTAL_LUNS</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
|
||||
* - this can be set to any positive non-zero amount.</td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*/
|
||||
/** \file
|
||||
*
|
||||
* This file contains special DoxyGen information for the generation of the main page and other special
|
||||
* documentation pages. It is not a project source file.
|
||||
*/
|
||||
|
||||
/** \mainpage Mass Storage Device Demo
|
||||
*
|
||||
* \section SSec_Compat Demo Compatibility:
|
||||
*
|
||||
* The following list indicates what microcontrollers are compatible with this demo.
|
||||
*
|
||||
* - Series 7 USB AVRs
|
||||
* - Series 6 USB AVRs
|
||||
* - Series 4 USB AVRs
|
||||
* - Series 2 USB AVRs
|
||||
*
|
||||
* \section SSec_Info USB Information:
|
||||
*
|
||||
* The following table gives a rundown of the USB utilization of this demo.
|
||||
*
|
||||
* <table>
|
||||
* <tr>
|
||||
* <td><b>USB Mode:</b></td>
|
||||
* <td>Device</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>USB Class:</b></td>
|
||||
* <td>Mass Storage Device</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>USB Subclass:</b></td>
|
||||
* <td>Bulk-Only Transport</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>Relevant Standards:</b></td>
|
||||
* <td>USBIF Mass Storage Standard \n
|
||||
* USB Bulk-Only Transport Standard \n
|
||||
* SCSI Primary Commands Specification \n
|
||||
* SCSI Block Commands Specification</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>Usable Speeds:</b></td>
|
||||
* <td>Full Speed Mode</td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*
|
||||
* \section SSec_Description Project Description:
|
||||
*
|
||||
* Dual LUN Mass Storage demonstration application. This gives a simple
|
||||
* reference application for implementing a multiple LUN USB Mass Storage
|
||||
* device using the basic USB UFI drivers in all modern OSes (i.e. no
|
||||
* special drivers required).
|
||||
*
|
||||
* On start-up the system will automatically enumerate and function as an
|
||||
* external mass storage device with two LUNs (separate disks) which may
|
||||
* be formatted and used in the same manner as commercial USB Mass Storage
|
||||
* devices.
|
||||
*
|
||||
* 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
|
||||
* 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.
|
||||
*
|
||||
* 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
|
||||
* 255), with each LUN being allocated an equal portion of the available
|
||||
* Dataflash memory.
|
||||
*
|
||||
* The USB control endpoint is managed entirely by the library using endpoint
|
||||
* 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 need for complicated polling logic.
|
||||
*
|
||||
* \section SSec_Options Project Options
|
||||
*
|
||||
* The following defines can be found in this demo, which can control the demo behaviour when defined, or changed in value.
|
||||
*
|
||||
* <table>
|
||||
* <tr>
|
||||
* <td><b>Define Name:</b></td>
|
||||
* <td><b>Location:</b></td>
|
||||
* <td><b>Description:</b></td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>TOTAL_LUNS</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
|
||||
* - this can be set to any positive non-zero amount.</td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*/
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,305 +1,305 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
Copyright 2010 Matthias Hullin (lufa [at] matthias [dot] hullin [dot] net)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* 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
|
||||
* the device's capabilities and functions.
|
||||
*/
|
||||
|
||||
#include "Descriptors.h"
|
||||
|
||||
/* 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.
|
||||
* 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
|
||||
* 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
|
||||
* port location).
|
||||
*/
|
||||
#if (USE_INTERNAL_SERIAL == NO_DESCRIPTOR)
|
||||
#warning USE_INTERNAL_SERIAL is not available on this AVR - please manually construct a device serial descriptor.
|
||||
#endif
|
||||
|
||||
/** 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
|
||||
* 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
|
||||
* more details on HID report descriptors.
|
||||
*/
|
||||
USB_Descriptor_HIDReport_Datatype_t PROGMEM KeyboardReport[] =
|
||||
{
|
||||
0x05, 0x01, /* Usage Page (Generic Desktop) */
|
||||
0x09, 0x06, /* Usage (Keyboard) */
|
||||
0xa1, 0x01, /* Collection (Application) */
|
||||
0x75, 0x01, /* Report Size (1) */
|
||||
0x95, 0x08, /* Report Count (8) */
|
||||
0x05, 0x07, /* Usage Page (Key Codes) */
|
||||
0x19, 0xe0, /* Usage Minimum (Keyboard LeftControl) */
|
||||
0x29, 0xe7, /* Usage Maximum (Keyboard Right GUI) */
|
||||
0x15, 0x00, /* Logical Minimum (0) */
|
||||
0x25, 0x01, /* Logical Maximum (1) */
|
||||
0x81, 0x02, /* Input (Data, Variable, Absolute) */
|
||||
0x95, 0x01, /* Report Count (1) */
|
||||
0x75, 0x08, /* Report Size (8) */
|
||||
0x81, 0x03, /* Input (Const, Variable, Absolute) */
|
||||
0x95, 0x05, /* Report Count (5) */
|
||||
0x75, 0x01, /* Report Size (1) */
|
||||
0x05, 0x08, /* Usage Page (LEDs) */
|
||||
0x19, 0x01, /* Usage Minimum (Num Lock) */
|
||||
0x29, 0x05, /* Usage Maximum (Kana) */
|
||||
0x91, 0x02, /* Output (Data, Variable, Absolute) */
|
||||
0x95, 0x01, /* Report Count (1) */
|
||||
0x75, 0x03, /* Report Size (3) */
|
||||
0x91, 0x03, /* Output (Const, Variable, Absolute) */
|
||||
0x95, 0x06, /* Report Count (6) */
|
||||
0x75, 0x08, /* Report Size (8) */
|
||||
0x15, 0x00, /* Logical Minimum (0) */
|
||||
0x25, 0x65, /* Logical Maximum (101) */
|
||||
0x05, 0x07, /* Usage Page (Keyboard) */
|
||||
0x19, 0x00, /* Usage Minimum (Reserved (no event indicated)) */
|
||||
0x29, 0x65, /* Usage Maximum (Keyboard Application) */
|
||||
0x81, 0x00, /* Input (Data, Array, Absolute) */
|
||||
0xc0 /* End Collection */
|
||||
};
|
||||
|
||||
/** Device descriptor structure. This descriptor, located in FLASH memory, describes the overall
|
||||
* 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
|
||||
* process begins.
|
||||
*/
|
||||
USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device},
|
||||
|
||||
.USBSpecification = VERSION_BCD(01.10),
|
||||
.Class = 0x00,
|
||||
.SubClass = 0x00,
|
||||
.Protocol = 0x00,
|
||||
|
||||
.Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE,
|
||||
|
||||
.VendorID = 0x03EB,
|
||||
.ProductID = 0x2061,
|
||||
.ReleaseNumber = 0x0000,
|
||||
|
||||
.ManufacturerStrIndex = 0x01,
|
||||
.ProductStrIndex = 0x02,
|
||||
.SerialNumStrIndex = USE_INTERNAL_SERIAL,
|
||||
|
||||
.NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS
|
||||
};
|
||||
|
||||
/** 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
|
||||
* 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.
|
||||
*/
|
||||
USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
|
||||
{
|
||||
.Config =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration},
|
||||
|
||||
.TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t),
|
||||
.TotalInterfaces = 2,
|
||||
|
||||
.ConfigurationNumber = 1,
|
||||
.ConfigurationStrIndex = NO_DESCRIPTOR,
|
||||
|
||||
.ConfigAttributes = USB_CONFIG_ATTR_BUSPOWERED,
|
||||
|
||||
.MaxPowerConsumption = USB_CONFIG_POWER_MA(100)
|
||||
},
|
||||
|
||||
.MS_Interface =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
|
||||
|
||||
.InterfaceNumber = 0,
|
||||
.AlternateSetting = 0,
|
||||
|
||||
.TotalEndpoints = 2,
|
||||
|
||||
.Class = 0x08,
|
||||
.SubClass = 0x06,
|
||||
.Protocol = 0x50,
|
||||
|
||||
.InterfaceStrIndex = NO_DESCRIPTOR
|
||||
},
|
||||
|
||||
.MS_DataInEndpoint =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
|
||||
|
||||
.EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_IN | MASS_STORAGE_IN_EPNUM),
|
||||
.Attributes = EP_TYPE_BULK,
|
||||
.EndpointSize = MASS_STORAGE_IO_EPSIZE,
|
||||
.PollingIntervalMS = 0x00
|
||||
},
|
||||
|
||||
.MS_DataOutEndpoint =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
|
||||
|
||||
.EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_OUT | MASS_STORAGE_OUT_EPNUM),
|
||||
.Attributes = EP_TYPE_BULK,
|
||||
.EndpointSize = MASS_STORAGE_IO_EPSIZE,
|
||||
.PollingIntervalMS = 0x00
|
||||
},
|
||||
|
||||
.HID_KeyboardInterface =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
|
||||
|
||||
.InterfaceNumber = 1,
|
||||
.AlternateSetting = 0,
|
||||
|
||||
.TotalEndpoints = 1,
|
||||
|
||||
.Class = 0x03,
|
||||
.SubClass = 0x01,
|
||||
.Protocol = 0x01,
|
||||
|
||||
.InterfaceStrIndex = NO_DESCRIPTOR
|
||||
},
|
||||
|
||||
.HID_KeyboardHID =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_HID_Descriptor_t), .Type = DTYPE_HID},
|
||||
|
||||
.HIDSpec = VERSION_BCD(01.11),
|
||||
.CountryCode = 0x00,
|
||||
.TotalReportDescriptors = 1,
|
||||
.HIDReportType = DTYPE_Report,
|
||||
.HIDReportLength = sizeof(KeyboardReport)
|
||||
},
|
||||
|
||||
.HID_ReportINEndpoint =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
|
||||
|
||||
.EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_IN | KEYBOARD_EPNUM),
|
||||
.Attributes = EP_TYPE_INTERRUPT,
|
||||
.EndpointSize = KEYBOARD_EPSIZE,
|
||||
.PollingIntervalMS = 0x04
|
||||
},
|
||||
};
|
||||
|
||||
/** 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
|
||||
* via the language ID table available at USB.org what languages the device supports for its string descriptors.
|
||||
*/
|
||||
USB_Descriptor_String_t PROGMEM LanguageString =
|
||||
{
|
||||
.Header = {.Size = USB_STRING_LEN(1), .Type = DTYPE_String},
|
||||
|
||||
.UnicodeString = {LANGUAGE_ID_ENG}
|
||||
};
|
||||
|
||||
/** 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
|
||||
* Descriptor.
|
||||
*/
|
||||
USB_Descriptor_String_t PROGMEM ManufacturerString =
|
||||
{
|
||||
.Header = {.Size = USB_STRING_LEN(11), .Type = DTYPE_String},
|
||||
|
||||
.UnicodeString = L"Dean Camera"
|
||||
};
|
||||
|
||||
/** 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
|
||||
* Descriptor.
|
||||
*/
|
||||
USB_Descriptor_String_t PROGMEM ProductString =
|
||||
{
|
||||
.Header = {.Size = USB_STRING_LEN(35), .Type = DTYPE_String},
|
||||
|
||||
.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"
|
||||
* 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
|
||||
* is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the
|
||||
* USB host.
|
||||
*/
|
||||
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 DescriptorNumber = (wValue & 0xFF);
|
||||
|
||||
void* Address = NULL;
|
||||
uint16_t Size = NO_DESCRIPTOR;
|
||||
|
||||
switch (DescriptorType)
|
||||
{
|
||||
case DTYPE_Device:
|
||||
Address = (void*)&DeviceDescriptor;
|
||||
Size = sizeof(USB_Descriptor_Device_t);
|
||||
break;
|
||||
case DTYPE_Configuration:
|
||||
Address = (void*)&ConfigurationDescriptor;
|
||||
Size = sizeof(USB_Descriptor_Configuration_t);
|
||||
break;
|
||||
case DTYPE_String:
|
||||
switch (DescriptorNumber)
|
||||
{
|
||||
case 0x00:
|
||||
Address = (void*)&LanguageString;
|
||||
Size = pgm_read_byte(&LanguageString.Header.Size);
|
||||
break;
|
||||
case 0x01:
|
||||
Address = (void*)&ManufacturerString;
|
||||
Size = pgm_read_byte(&ManufacturerString.Header.Size);
|
||||
break;
|
||||
case 0x02:
|
||||
Address = (void*)&ProductString;
|
||||
Size = pgm_read_byte(&ProductString.Header.Size);
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
case DTYPE_HID:
|
||||
Address = (void*)&ConfigurationDescriptor.HID_KeyboardHID;
|
||||
Size = sizeof(USB_HID_Descriptor_t);
|
||||
break;
|
||||
case DTYPE_Report:
|
||||
Address = (void*)&KeyboardReport;
|
||||
Size = sizeof(KeyboardReport);
|
||||
break;
|
||||
}
|
||||
|
||||
*DescriptorAddress = Address;
|
||||
return Size;
|
||||
}
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
Copyright 2010 Matthias Hullin (lufa [at] matthias [dot] hullin [dot] net)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* 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
|
||||
* the device's capabilities and functions.
|
||||
*/
|
||||
|
||||
#include "Descriptors.h"
|
||||
|
||||
/* 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.
|
||||
* 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
|
||||
* 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
|
||||
* port location).
|
||||
*/
|
||||
#if (USE_INTERNAL_SERIAL == NO_DESCRIPTOR)
|
||||
#warning USE_INTERNAL_SERIAL is not available on this AVR - please manually construct a device serial descriptor.
|
||||
#endif
|
||||
|
||||
/** 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
|
||||
* 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
|
||||
* more details on HID report descriptors.
|
||||
*/
|
||||
USB_Descriptor_HIDReport_Datatype_t PROGMEM KeyboardReport[] =
|
||||
{
|
||||
0x05, 0x01, /* Usage Page (Generic Desktop) */
|
||||
0x09, 0x06, /* Usage (Keyboard) */
|
||||
0xa1, 0x01, /* Collection (Application) */
|
||||
0x75, 0x01, /* Report Size (1) */
|
||||
0x95, 0x08, /* Report Count (8) */
|
||||
0x05, 0x07, /* Usage Page (Key Codes) */
|
||||
0x19, 0xe0, /* Usage Minimum (Keyboard LeftControl) */
|
||||
0x29, 0xe7, /* Usage Maximum (Keyboard Right GUI) */
|
||||
0x15, 0x00, /* Logical Minimum (0) */
|
||||
0x25, 0x01, /* Logical Maximum (1) */
|
||||
0x81, 0x02, /* Input (Data, Variable, Absolute) */
|
||||
0x95, 0x01, /* Report Count (1) */
|
||||
0x75, 0x08, /* Report Size (8) */
|
||||
0x81, 0x03, /* Input (Const, Variable, Absolute) */
|
||||
0x95, 0x05, /* Report Count (5) */
|
||||
0x75, 0x01, /* Report Size (1) */
|
||||
0x05, 0x08, /* Usage Page (LEDs) */
|
||||
0x19, 0x01, /* Usage Minimum (Num Lock) */
|
||||
0x29, 0x05, /* Usage Maximum (Kana) */
|
||||
0x91, 0x02, /* Output (Data, Variable, Absolute) */
|
||||
0x95, 0x01, /* Report Count (1) */
|
||||
0x75, 0x03, /* Report Size (3) */
|
||||
0x91, 0x03, /* Output (Const, Variable, Absolute) */
|
||||
0x95, 0x06, /* Report Count (6) */
|
||||
0x75, 0x08, /* Report Size (8) */
|
||||
0x15, 0x00, /* Logical Minimum (0) */
|
||||
0x25, 0x65, /* Logical Maximum (101) */
|
||||
0x05, 0x07, /* Usage Page (Keyboard) */
|
||||
0x19, 0x00, /* Usage Minimum (Reserved (no event indicated)) */
|
||||
0x29, 0x65, /* Usage Maximum (Keyboard Application) */
|
||||
0x81, 0x00, /* Input (Data, Array, Absolute) */
|
||||
0xc0 /* End Collection */
|
||||
};
|
||||
|
||||
/** Device descriptor structure. This descriptor, located in FLASH memory, describes the overall
|
||||
* 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
|
||||
* process begins.
|
||||
*/
|
||||
USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device},
|
||||
|
||||
.USBSpecification = VERSION_BCD(01.10),
|
||||
.Class = 0x00,
|
||||
.SubClass = 0x00,
|
||||
.Protocol = 0x00,
|
||||
|
||||
.Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE,
|
||||
|
||||
.VendorID = 0x03EB,
|
||||
.ProductID = 0x2061,
|
||||
.ReleaseNumber = 0x0000,
|
||||
|
||||
.ManufacturerStrIndex = 0x01,
|
||||
.ProductStrIndex = 0x02,
|
||||
.SerialNumStrIndex = USE_INTERNAL_SERIAL,
|
||||
|
||||
.NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS
|
||||
};
|
||||
|
||||
/** 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
|
||||
* 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.
|
||||
*/
|
||||
USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
|
||||
{
|
||||
.Config =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration},
|
||||
|
||||
.TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t),
|
||||
.TotalInterfaces = 2,
|
||||
|
||||
.ConfigurationNumber = 1,
|
||||
.ConfigurationStrIndex = NO_DESCRIPTOR,
|
||||
|
||||
.ConfigAttributes = USB_CONFIG_ATTR_BUSPOWERED,
|
||||
|
||||
.MaxPowerConsumption = USB_CONFIG_POWER_MA(100)
|
||||
},
|
||||
|
||||
.MS_Interface =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
|
||||
|
||||
.InterfaceNumber = 0,
|
||||
.AlternateSetting = 0,
|
||||
|
||||
.TotalEndpoints = 2,
|
||||
|
||||
.Class = 0x08,
|
||||
.SubClass = 0x06,
|
||||
.Protocol = 0x50,
|
||||
|
||||
.InterfaceStrIndex = NO_DESCRIPTOR
|
||||
},
|
||||
|
||||
.MS_DataInEndpoint =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
|
||||
|
||||
.EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_IN | MASS_STORAGE_IN_EPNUM),
|
||||
.Attributes = EP_TYPE_BULK,
|
||||
.EndpointSize = MASS_STORAGE_IO_EPSIZE,
|
||||
.PollingIntervalMS = 0x00
|
||||
},
|
||||
|
||||
.MS_DataOutEndpoint =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
|
||||
|
||||
.EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_OUT | MASS_STORAGE_OUT_EPNUM),
|
||||
.Attributes = EP_TYPE_BULK,
|
||||
.EndpointSize = MASS_STORAGE_IO_EPSIZE,
|
||||
.PollingIntervalMS = 0x00
|
||||
},
|
||||
|
||||
.HID_KeyboardInterface =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
|
||||
|
||||
.InterfaceNumber = 1,
|
||||
.AlternateSetting = 0,
|
||||
|
||||
.TotalEndpoints = 1,
|
||||
|
||||
.Class = 0x03,
|
||||
.SubClass = 0x01,
|
||||
.Protocol = 0x01,
|
||||
|
||||
.InterfaceStrIndex = NO_DESCRIPTOR
|
||||
},
|
||||
|
||||
.HID_KeyboardHID =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_HID_Descriptor_t), .Type = DTYPE_HID},
|
||||
|
||||
.HIDSpec = VERSION_BCD(01.11),
|
||||
.CountryCode = 0x00,
|
||||
.TotalReportDescriptors = 1,
|
||||
.HIDReportType = DTYPE_Report,
|
||||
.HIDReportLength = sizeof(KeyboardReport)
|
||||
},
|
||||
|
||||
.HID_ReportINEndpoint =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
|
||||
|
||||
.EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_IN | KEYBOARD_EPNUM),
|
||||
.Attributes = EP_TYPE_INTERRUPT,
|
||||
.EndpointSize = KEYBOARD_EPSIZE,
|
||||
.PollingIntervalMS = 0x04
|
||||
},
|
||||
};
|
||||
|
||||
/** 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
|
||||
* via the language ID table available at USB.org what languages the device supports for its string descriptors.
|
||||
*/
|
||||
USB_Descriptor_String_t PROGMEM LanguageString =
|
||||
{
|
||||
.Header = {.Size = USB_STRING_LEN(1), .Type = DTYPE_String},
|
||||
|
||||
.UnicodeString = {LANGUAGE_ID_ENG}
|
||||
};
|
||||
|
||||
/** 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
|
||||
* Descriptor.
|
||||
*/
|
||||
USB_Descriptor_String_t PROGMEM ManufacturerString =
|
||||
{
|
||||
.Header = {.Size = USB_STRING_LEN(11), .Type = DTYPE_String},
|
||||
|
||||
.UnicodeString = L"Dean Camera"
|
||||
};
|
||||
|
||||
/** 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
|
||||
* Descriptor.
|
||||
*/
|
||||
USB_Descriptor_String_t PROGMEM ProductString =
|
||||
{
|
||||
.Header = {.Size = USB_STRING_LEN(35), .Type = DTYPE_String},
|
||||
|
||||
.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"
|
||||
* 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
|
||||
* is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the
|
||||
* USB host.
|
||||
*/
|
||||
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 DescriptorNumber = (wValue & 0xFF);
|
||||
|
||||
void* Address = NULL;
|
||||
uint16_t Size = NO_DESCRIPTOR;
|
||||
|
||||
switch (DescriptorType)
|
||||
{
|
||||
case DTYPE_Device:
|
||||
Address = (void*)&DeviceDescriptor;
|
||||
Size = sizeof(USB_Descriptor_Device_t);
|
||||
break;
|
||||
case DTYPE_Configuration:
|
||||
Address = (void*)&ConfigurationDescriptor;
|
||||
Size = sizeof(USB_Descriptor_Configuration_t);
|
||||
break;
|
||||
case DTYPE_String:
|
||||
switch (DescriptorNumber)
|
||||
{
|
||||
case 0x00:
|
||||
Address = (void*)&LanguageString;
|
||||
Size = pgm_read_byte(&LanguageString.Header.Size);
|
||||
break;
|
||||
case 0x01:
|
||||
Address = (void*)&ManufacturerString;
|
||||
Size = pgm_read_byte(&ManufacturerString.Header.Size);
|
||||
break;
|
||||
case 0x02:
|
||||
Address = (void*)&ProductString;
|
||||
Size = pgm_read_byte(&ProductString.Header.Size);
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
case DTYPE_HID:
|
||||
Address = (void*)&ConfigurationDescriptor.HID_KeyboardHID;
|
||||
Size = sizeof(USB_HID_Descriptor_t);
|
||||
break;
|
||||
case DTYPE_Report:
|
||||
Address = (void*)&KeyboardReport;
|
||||
Size = sizeof(KeyboardReport);
|
||||
break;
|
||||
}
|
||||
|
||||
*DescriptorAddress = Address;
|
||||
return Size;
|
||||
}
|
||||
|
@ -1,83 +1,83 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
Copyright 2010 Matthias Hullin (lufa [at] matthias [dot] hullin [dot] net)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Header file for Descriptors.c.
|
||||
*/
|
||||
|
||||
#ifndef _DESCRIPTORS_H_
|
||||
#define _DESCRIPTORS_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/pgmspace.h>
|
||||
|
||||
#include <LUFA/Drivers/USB/USB.h>
|
||||
#include <LUFA/Drivers/USB/Class/MassStorage.h>
|
||||
#include <LUFA/Drivers/USB/Class/HID.h>
|
||||
|
||||
/* Macros: */
|
||||
/** Endpoint number of the Keyboard HID reporting IN endpoint. */
|
||||
#define KEYBOARD_EPNUM 1
|
||||
|
||||
/** Size in bytes of the Keyboard HID reporting IN and OUT endpoints. */
|
||||
#define KEYBOARD_EPSIZE 8
|
||||
|
||||
/** Endpoint number of the Mass Storage device-to-host data IN endpoint. */
|
||||
#define MASS_STORAGE_IN_EPNUM 3
|
||||
|
||||
/** Endpoint number of the Mass Storage host-to-device data OUT endpoint. */
|
||||
#define MASS_STORAGE_OUT_EPNUM 4
|
||||
|
||||
/** Size in bytes of the Mass Storage data endpoints. */
|
||||
#define MASS_STORAGE_IO_EPSIZE 64
|
||||
|
||||
/* Type Defines: */
|
||||
/** 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
|
||||
* vary between devices, and which describe the device's usage to the host.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
USB_Descriptor_Configuration_Header_t Config;
|
||||
USB_Descriptor_Interface_t MS_Interface;
|
||||
USB_Descriptor_Endpoint_t MS_DataInEndpoint;
|
||||
USB_Descriptor_Endpoint_t MS_DataOutEndpoint;
|
||||
USB_Descriptor_Interface_t HID_KeyboardInterface;
|
||||
USB_HID_Descriptor_t HID_KeyboardHID;
|
||||
USB_Descriptor_Endpoint_t HID_ReportINEndpoint;
|
||||
} USB_Descriptor_Configuration_t;
|
||||
|
||||
/* Function Prototypes: */
|
||||
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);
|
||||
|
||||
#endif
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
Copyright 2010 Matthias Hullin (lufa [at] matthias [dot] hullin [dot] net)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Header file for Descriptors.c.
|
||||
*/
|
||||
|
||||
#ifndef _DESCRIPTORS_H_
|
||||
#define _DESCRIPTORS_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/pgmspace.h>
|
||||
|
||||
#include <LUFA/Drivers/USB/USB.h>
|
||||
#include <LUFA/Drivers/USB/Class/MassStorage.h>
|
||||
#include <LUFA/Drivers/USB/Class/HID.h>
|
||||
|
||||
/* Macros: */
|
||||
/** Endpoint number of the Keyboard HID reporting IN endpoint. */
|
||||
#define KEYBOARD_EPNUM 1
|
||||
|
||||
/** Size in bytes of the Keyboard HID reporting IN and OUT endpoints. */
|
||||
#define KEYBOARD_EPSIZE 8
|
||||
|
||||
/** Endpoint number of the Mass Storage device-to-host data IN endpoint. */
|
||||
#define MASS_STORAGE_IN_EPNUM 3
|
||||
|
||||
/** Endpoint number of the Mass Storage host-to-device data OUT endpoint. */
|
||||
#define MASS_STORAGE_OUT_EPNUM 4
|
||||
|
||||
/** Size in bytes of the Mass Storage data endpoints. */
|
||||
#define MASS_STORAGE_IO_EPSIZE 64
|
||||
|
||||
/* Type Defines: */
|
||||
/** 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
|
||||
* vary between devices, and which describe the device's usage to the host.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
USB_Descriptor_Configuration_Header_t Config;
|
||||
USB_Descriptor_Interface_t MS_Interface;
|
||||
USB_Descriptor_Endpoint_t MS_DataInEndpoint;
|
||||
USB_Descriptor_Endpoint_t MS_DataOutEndpoint;
|
||||
USB_Descriptor_Interface_t HID_KeyboardInterface;
|
||||
USB_HID_Descriptor_t HID_KeyboardHID;
|
||||
USB_Descriptor_Endpoint_t HID_ReportINEndpoint;
|
||||
} USB_Descriptor_Configuration_t;
|
||||
|
||||
/* Function Prototypes: */
|
||||
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);
|
||||
|
||||
#endif
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,492 +1,492 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* 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
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#define INCLUDE_FROM_DATAFLASHMANAGER_C
|
||||
#include "DataflashManager.h"
|
||||
|
||||
/** 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
|
||||
* 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] BlockAddress Data block starting address for the write sequence
|
||||
* \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)
|
||||
{
|
||||
uint16_t CurrDFPage = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) / DATAFLASH_PAGE_SIZE);
|
||||
uint16_t CurrDFPageByte = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) % DATAFLASH_PAGE_SIZE);
|
||||
uint8_t CurrDFPageByteDiv16 = (CurrDFPageByte >> 4);
|
||||
bool UsingSecondBuffer = false;
|
||||
|
||||
/* Select the correct starting Dataflash IC for the block requested */
|
||||
Dataflash_SelectChipFromPage(CurrDFPage);
|
||||
|
||||
#if (DATAFLASH_PAGE_SIZE > VIRTUAL_MEMORY_BLOCK_SIZE)
|
||||
/* Copy selected dataflash's current page contents to the dataflash buffer */
|
||||
Dataflash_SendByte(DF_CMD_MAINMEMTOBUFF1);
|
||||
Dataflash_SendAddressBytes(CurrDFPage, 0);
|
||||
Dataflash_WaitWhileBusy();
|
||||
#endif
|
||||
|
||||
/* Send the dataflash buffer write command */
|
||||
Dataflash_SendByte(DF_CMD_BUFF1WRITE);
|
||||
Dataflash_SendAddressBytes(0, CurrDFPageByte);
|
||||
|
||||
/* Wait until endpoint is ready before continuing */
|
||||
if (Endpoint_WaitUntilReady())
|
||||
return;
|
||||
|
||||
while (TotalBlocks)
|
||||
{
|
||||
uint8_t BytesInBlockDiv16 = 0;
|
||||
|
||||
/* Write an endpoint packet sized data block to the dataflash */
|
||||
while (BytesInBlockDiv16 < (VIRTUAL_MEMORY_BLOCK_SIZE >> 4))
|
||||
{
|
||||
/* Check if the endpoint is currently empty */
|
||||
if (!(Endpoint_IsReadWriteAllowed()))
|
||||
{
|
||||
/* Clear the current endpoint bank */
|
||||
Endpoint_ClearOUT();
|
||||
|
||||
/* Wait until the host has sent another packet */
|
||||
if (Endpoint_WaitUntilReady())
|
||||
return;
|
||||
}
|
||||
|
||||
/* Check if end of dataflash page reached */
|
||||
if (CurrDFPageByteDiv16 == (DATAFLASH_PAGE_SIZE >> 4))
|
||||
{
|
||||
/* Write the dataflash buffer contents back to the dataflash page */
|
||||
Dataflash_WaitWhileBusy();
|
||||
Dataflash_SendByte(UsingSecondBuffer ? DF_CMD_BUFF2TOMAINMEMWITHERASE : DF_CMD_BUFF1TOMAINMEMWITHERASE);
|
||||
Dataflash_SendAddressBytes(CurrDFPage, 0);
|
||||
|
||||
/* Reset the dataflash buffer counter, increment the page counter */
|
||||
CurrDFPageByteDiv16 = 0;
|
||||
CurrDFPage++;
|
||||
|
||||
/* Once all the dataflash ICs have had their first buffers filled, switch buffers to maintain throughput */
|
||||
if (Dataflash_GetSelectedChip() == DATAFLASH_CHIP_MASK(DATAFLASH_TOTALCHIPS))
|
||||
UsingSecondBuffer = !(UsingSecondBuffer);
|
||||
|
||||
/* Select the next dataflash chip based on the new dataflash page index */
|
||||
Dataflash_SelectChipFromPage(CurrDFPage);
|
||||
|
||||
#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 ((TotalBlocks * (VIRTUAL_MEMORY_BLOCK_SIZE >> 4)) < (DATAFLASH_PAGE_SIZE >> 4))
|
||||
{
|
||||
/* Copy selected dataflash's current page contents to the dataflash buffer */
|
||||
Dataflash_WaitWhileBusy();
|
||||
Dataflash_SendByte(UsingSecondBuffer ? DF_CMD_MAINMEMTOBUFF2 : DF_CMD_MAINMEMTOBUFF1);
|
||||
Dataflash_SendAddressBytes(CurrDFPage, 0);
|
||||
Dataflash_WaitWhileBusy();
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Send the dataflash buffer write command */
|
||||
Dataflash_SendByte(UsingSecondBuffer ? DF_CMD_BUFF2WRITE : DF_CMD_BUFF1WRITE);
|
||||
Dataflash_SendAddressBytes(0, 0);
|
||||
}
|
||||
|
||||
/* 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());
|
||||
|
||||
/* Increment the dataflash page 16 byte block counter */
|
||||
CurrDFPageByteDiv16++;
|
||||
|
||||
/* Increment the block 16 byte block counter */
|
||||
BytesInBlockDiv16++;
|
||||
|
||||
/* Check if the current command is being aborted by the host */
|
||||
if (MSInterfaceInfo->State.IsMassStoreReset)
|
||||
return;
|
||||
}
|
||||
|
||||
/* Decrement the blocks remaining counter and reset the sub block counter */
|
||||
TotalBlocks--;
|
||||
}
|
||||
|
||||
/* Write the dataflash buffer contents back to the dataflash page */
|
||||
Dataflash_WaitWhileBusy();
|
||||
Dataflash_SendByte(UsingSecondBuffer ? DF_CMD_BUFF2TOMAINMEMWITHERASE : DF_CMD_BUFF1TOMAINMEMWITHERASE);
|
||||
Dataflash_SendAddressBytes(CurrDFPage, 0x00);
|
||||
Dataflash_WaitWhileBusy();
|
||||
|
||||
/* If the endpoint is empty, clear it ready for the next packet from the host */
|
||||
if (!(Endpoint_IsReadWriteAllowed()))
|
||||
Endpoint_ClearOUT();
|
||||
|
||||
/* Deselect all dataflash chips */
|
||||
Dataflash_DeselectChip();
|
||||
}
|
||||
|
||||
/** 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
|
||||
* 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] BlockAddress Data block starting address for the read sequence
|
||||
* \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)
|
||||
{
|
||||
uint16_t CurrDFPage = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) / DATAFLASH_PAGE_SIZE);
|
||||
uint16_t CurrDFPageByte = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) % DATAFLASH_PAGE_SIZE);
|
||||
uint8_t CurrDFPageByteDiv16 = (CurrDFPageByte >> 4);
|
||||
|
||||
/* Select the correct starting Dataflash IC for the block requested */
|
||||
Dataflash_SelectChipFromPage(CurrDFPage);
|
||||
|
||||
/* Send the dataflash main memory page read command */
|
||||
Dataflash_SendByte(DF_CMD_MAINMEMPAGEREAD);
|
||||
Dataflash_SendAddressBytes(CurrDFPage, CurrDFPageByte);
|
||||
Dataflash_SendByte(0x00);
|
||||
Dataflash_SendByte(0x00);
|
||||
Dataflash_SendByte(0x00);
|
||||
Dataflash_SendByte(0x00);
|
||||
|
||||
/* Wait until endpoint is ready before continuing */
|
||||
if (Endpoint_WaitUntilReady())
|
||||
return;
|
||||
|
||||
while (TotalBlocks)
|
||||
{
|
||||
uint8_t BytesInBlockDiv16 = 0;
|
||||
|
||||
/* Write an endpoint packet sized data block to the dataflash */
|
||||
while (BytesInBlockDiv16 < (VIRTUAL_MEMORY_BLOCK_SIZE >> 4))
|
||||
{
|
||||
/* Check if the endpoint is currently full */
|
||||
if (!(Endpoint_IsReadWriteAllowed()))
|
||||
{
|
||||
/* Clear the endpoint bank to send its contents to the host */
|
||||
Endpoint_ClearIN();
|
||||
|
||||
/* Wait until the endpoint is ready for more data */
|
||||
if (Endpoint_WaitUntilReady())
|
||||
return;
|
||||
}
|
||||
|
||||
/* Check if end of dataflash page reached */
|
||||
if (CurrDFPageByteDiv16 == (DATAFLASH_PAGE_SIZE >> 4))
|
||||
{
|
||||
/* Reset the dataflash buffer counter, increment the page counter */
|
||||
CurrDFPageByteDiv16 = 0;
|
||||
CurrDFPage++;
|
||||
|
||||
/* Select the next dataflash chip based on the new dataflash page index */
|
||||
Dataflash_SelectChipFromPage(CurrDFPage);
|
||||
|
||||
/* Send the dataflash main memory page read command */
|
||||
Dataflash_SendByte(DF_CMD_MAINMEMPAGEREAD);
|
||||
Dataflash_SendAddressBytes(CurrDFPage, 0);
|
||||
Dataflash_SendByte(0x00);
|
||||
Dataflash_SendByte(0x00);
|
||||
Dataflash_SendByte(0x00);
|
||||
Dataflash_SendByte(0x00);
|
||||
}
|
||||
|
||||
/* 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());
|
||||
|
||||
/* Increment the dataflash page 16 byte block counter */
|
||||
CurrDFPageByteDiv16++;
|
||||
|
||||
/* Increment the block 16 byte block counter */
|
||||
BytesInBlockDiv16++;
|
||||
|
||||
/* Check if the current command is being aborted by the host */
|
||||
if (MSInterfaceInfo->State.IsMassStoreReset)
|
||||
return;
|
||||
}
|
||||
|
||||
/* Decrement the blocks remaining counter */
|
||||
TotalBlocks--;
|
||||
}
|
||||
|
||||
/* If the endpoint is full, send its contents to the host */
|
||||
if (!(Endpoint_IsReadWriteAllowed()))
|
||||
Endpoint_ClearIN();
|
||||
|
||||
/* Deselect all dataflash chips */
|
||||
Dataflash_DeselectChip();
|
||||
}
|
||||
|
||||
/** 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
|
||||
* dataflash in Dataflash page sized blocks. This can be linked to FAT libraries to write files to the
|
||||
* dataflash.
|
||||
*
|
||||
* \param[in] BlockAddress Data block starting address for the write sequence
|
||||
* \param[in] TotalBlocks Number of blocks of data to write
|
||||
* \param[in] BufferPtr Pointer to the data source RAM buffer
|
||||
*/
|
||||
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 CurrDFPageByte = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) % DATAFLASH_PAGE_SIZE);
|
||||
uint8_t CurrDFPageByteDiv16 = (CurrDFPageByte >> 4);
|
||||
bool UsingSecondBuffer = false;
|
||||
|
||||
/* Select the correct starting Dataflash IC for the block requested */
|
||||
Dataflash_SelectChipFromPage(CurrDFPage);
|
||||
|
||||
#if (DATAFLASH_PAGE_SIZE > VIRTUAL_MEMORY_BLOCK_SIZE)
|
||||
/* Copy selected dataflash's current page contents to the dataflash buffer */
|
||||
Dataflash_SendByte(DF_CMD_MAINMEMTOBUFF1);
|
||||
Dataflash_SendAddressBytes(CurrDFPage, 0);
|
||||
Dataflash_WaitWhileBusy();
|
||||
#endif
|
||||
|
||||
/* Send the dataflash buffer write command */
|
||||
Dataflash_SendByte(DF_CMD_BUFF1WRITE);
|
||||
Dataflash_SendAddressBytes(0, CurrDFPageByte);
|
||||
|
||||
while (TotalBlocks)
|
||||
{
|
||||
uint8_t BytesInBlockDiv16 = 0;
|
||||
|
||||
/* Write an endpoint packet sized data block to the dataflash */
|
||||
while (BytesInBlockDiv16 < (VIRTUAL_MEMORY_BLOCK_SIZE >> 4))
|
||||
{
|
||||
/* Check if end of dataflash page reached */
|
||||
if (CurrDFPageByteDiv16 == (DATAFLASH_PAGE_SIZE >> 4))
|
||||
{
|
||||
/* Write the dataflash buffer contents back to the dataflash page */
|
||||
Dataflash_WaitWhileBusy();
|
||||
Dataflash_SendByte(UsingSecondBuffer ? DF_CMD_BUFF2TOMAINMEMWITHERASE : DF_CMD_BUFF1TOMAINMEMWITHERASE);
|
||||
Dataflash_SendAddressBytes(CurrDFPage, 0);
|
||||
|
||||
/* Reset the dataflash buffer counter, increment the page counter */
|
||||
CurrDFPageByteDiv16 = 0;
|
||||
CurrDFPage++;
|
||||
|
||||
/* Once all the dataflash ICs have had their first buffers filled, switch buffers to maintain throughput */
|
||||
if (Dataflash_GetSelectedChip() == DATAFLASH_CHIP_MASK(DATAFLASH_TOTALCHIPS))
|
||||
UsingSecondBuffer = !(UsingSecondBuffer);
|
||||
|
||||
/* Select the next dataflash chip based on the new dataflash page index */
|
||||
Dataflash_SelectChipFromPage(CurrDFPage);
|
||||
|
||||
#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 ((TotalBlocks * (VIRTUAL_MEMORY_BLOCK_SIZE >> 4)) < (DATAFLASH_PAGE_SIZE >> 4))
|
||||
{
|
||||
/* Copy selected dataflash's current page contents to the dataflash buffer */
|
||||
Dataflash_WaitWhileBusy();
|
||||
Dataflash_SendByte(UsingSecondBuffer ? DF_CMD_MAINMEMTOBUFF2 : DF_CMD_MAINMEMTOBUFF1);
|
||||
Dataflash_SendAddressBytes(CurrDFPage, 0);
|
||||
Dataflash_WaitWhileBusy();
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Send the dataflash buffer write command */
|
||||
Dataflash_ToggleSelectedChipCS();
|
||||
Dataflash_SendByte(DF_CMD_BUFF1WRITE);
|
||||
Dataflash_SendAddressBytes(0, 0);
|
||||
}
|
||||
|
||||
/* Write one 16-byte chunk of data to the dataflash */
|
||||
for (uint8_t ByteNum = 0; ByteNum < 16; ByteNum++)
|
||||
Dataflash_SendByte(*(BufferPtr++));
|
||||
|
||||
/* Increment the dataflash page 16 byte block counter */
|
||||
CurrDFPageByteDiv16++;
|
||||
|
||||
/* Increment the block 16 byte block counter */
|
||||
BytesInBlockDiv16++;
|
||||
}
|
||||
|
||||
/* Decrement the blocks remaining counter and reset the sub block counter */
|
||||
TotalBlocks--;
|
||||
}
|
||||
|
||||
/* Write the dataflash buffer contents back to the dataflash page */
|
||||
Dataflash_WaitWhileBusy();
|
||||
Dataflash_SendByte(UsingSecondBuffer ? DF_CMD_BUFF2TOMAINMEMWITHERASE : DF_CMD_BUFF1TOMAINMEMWITHERASE);
|
||||
Dataflash_SendAddressBytes(CurrDFPage, 0x00);
|
||||
Dataflash_WaitWhileBusy();
|
||||
|
||||
/* Deselect all dataflash chips */
|
||||
Dataflash_DeselectChip();
|
||||
}
|
||||
|
||||
/** 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
|
||||
* 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.
|
||||
*
|
||||
* \param[in] BlockAddress Data block starting address for the read sequence
|
||||
* \param[in] TotalBlocks Number of blocks of data to read
|
||||
* \param[out] BufferPtr Pointer to the data destination RAM buffer
|
||||
*/
|
||||
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 CurrDFPageByte = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) % DATAFLASH_PAGE_SIZE);
|
||||
uint8_t CurrDFPageByteDiv16 = (CurrDFPageByte >> 4);
|
||||
|
||||
/* Select the correct starting Dataflash IC for the block requested */
|
||||
Dataflash_SelectChipFromPage(CurrDFPage);
|
||||
|
||||
/* Send the dataflash main memory page read command */
|
||||
Dataflash_SendByte(DF_CMD_MAINMEMPAGEREAD);
|
||||
Dataflash_SendAddressBytes(CurrDFPage, CurrDFPageByte);
|
||||
Dataflash_SendByte(0x00);
|
||||
Dataflash_SendByte(0x00);
|
||||
Dataflash_SendByte(0x00);
|
||||
Dataflash_SendByte(0x00);
|
||||
|
||||
while (TotalBlocks)
|
||||
{
|
||||
uint8_t BytesInBlockDiv16 = 0;
|
||||
|
||||
/* Write an endpoint packet sized data block to the dataflash */
|
||||
while (BytesInBlockDiv16 < (VIRTUAL_MEMORY_BLOCK_SIZE >> 4))
|
||||
{
|
||||
/* Check if end of dataflash page reached */
|
||||
if (CurrDFPageByteDiv16 == (DATAFLASH_PAGE_SIZE >> 4))
|
||||
{
|
||||
/* Reset the dataflash buffer counter, increment the page counter */
|
||||
CurrDFPageByteDiv16 = 0;
|
||||
CurrDFPage++;
|
||||
|
||||
/* Select the next dataflash chip based on the new dataflash page index */
|
||||
Dataflash_SelectChipFromPage(CurrDFPage);
|
||||
|
||||
/* Send the dataflash main memory page read command */
|
||||
Dataflash_SendByte(DF_CMD_MAINMEMPAGEREAD);
|
||||
Dataflash_SendAddressBytes(CurrDFPage, 0);
|
||||
Dataflash_SendByte(0x00);
|
||||
Dataflash_SendByte(0x00);
|
||||
Dataflash_SendByte(0x00);
|
||||
Dataflash_SendByte(0x00);
|
||||
}
|
||||
|
||||
/* Read one 16-byte chunk of data from the dataflash */
|
||||
for (uint8_t ByteNum = 0; ByteNum < 16; ByteNum++)
|
||||
*(BufferPtr++) = Dataflash_ReceiveByte();
|
||||
|
||||
/* Increment the dataflash page 16 byte block counter */
|
||||
CurrDFPageByteDiv16++;
|
||||
|
||||
/* Increment the block 16 byte block counter */
|
||||
BytesInBlockDiv16++;
|
||||
}
|
||||
|
||||
/* Decrement the blocks remaining counter */
|
||||
TotalBlocks--;
|
||||
}
|
||||
|
||||
/* Deselect all dataflash chips */
|
||||
Dataflash_DeselectChip();
|
||||
}
|
||||
|
||||
/** Disables the dataflash memory write protection bits on the board Dataflash ICs, if enabled. */
|
||||
void DataflashManager_ResetDataflashProtections(void)
|
||||
{
|
||||
/* Select first dataflash chip, send the read status register command */
|
||||
Dataflash_SelectChip(DATAFLASH_CHIP1);
|
||||
Dataflash_SendByte(DF_CMD_GETSTATUS);
|
||||
|
||||
/* Check if sector protection is enabled */
|
||||
if (Dataflash_ReceiveByte() & DF_STATUS_SECTORPROTECTION_ON)
|
||||
{
|
||||
Dataflash_ToggleSelectedChipCS();
|
||||
|
||||
/* Send the commands to disable sector protection */
|
||||
Dataflash_SendByte(DF_CMD_SECTORPROTECTIONOFF[0]);
|
||||
Dataflash_SendByte(DF_CMD_SECTORPROTECTIONOFF[1]);
|
||||
Dataflash_SendByte(DF_CMD_SECTORPROTECTIONOFF[2]);
|
||||
Dataflash_SendByte(DF_CMD_SECTORPROTECTIONOFF[3]);
|
||||
}
|
||||
|
||||
/* Select second dataflash chip (if present on selected board), send read status register command */
|
||||
#if (DATAFLASH_TOTALCHIPS == 2)
|
||||
Dataflash_SelectChip(DATAFLASH_CHIP2);
|
||||
Dataflash_SendByte(DF_CMD_GETSTATUS);
|
||||
|
||||
/* Check if sector protection is enabled */
|
||||
if (Dataflash_ReceiveByte() & DF_STATUS_SECTORPROTECTION_ON)
|
||||
{
|
||||
Dataflash_ToggleSelectedChipCS();
|
||||
|
||||
/* Send the commands to disable sector protection */
|
||||
Dataflash_SendByte(DF_CMD_SECTORPROTECTIONOFF[0]);
|
||||
Dataflash_SendByte(DF_CMD_SECTORPROTECTIONOFF[1]);
|
||||
Dataflash_SendByte(DF_CMD_SECTORPROTECTIONOFF[2]);
|
||||
Dataflash_SendByte(DF_CMD_SECTORPROTECTIONOFF[3]);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Deselect current dataflash chip */
|
||||
Dataflash_DeselectChip();
|
||||
}
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* 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
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#define INCLUDE_FROM_DATAFLASHMANAGER_C
|
||||
#include "DataflashManager.h"
|
||||
|
||||
/** 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
|
||||
* 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] BlockAddress Data block starting address for the write sequence
|
||||
* \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)
|
||||
{
|
||||
uint16_t CurrDFPage = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) / DATAFLASH_PAGE_SIZE);
|
||||
uint16_t CurrDFPageByte = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) % DATAFLASH_PAGE_SIZE);
|
||||
uint8_t CurrDFPageByteDiv16 = (CurrDFPageByte >> 4);
|
||||
bool UsingSecondBuffer = false;
|
||||
|
||||
/* Select the correct starting Dataflash IC for the block requested */
|
||||
Dataflash_SelectChipFromPage(CurrDFPage);
|
||||
|
||||
#if (DATAFLASH_PAGE_SIZE > VIRTUAL_MEMORY_BLOCK_SIZE)
|
||||
/* Copy selected dataflash's current page contents to the dataflash buffer */
|
||||
Dataflash_SendByte(DF_CMD_MAINMEMTOBUFF1);
|
||||
Dataflash_SendAddressBytes(CurrDFPage, 0);
|
||||
Dataflash_WaitWhileBusy();
|
||||
#endif
|
||||
|
||||
/* Send the dataflash buffer write command */
|
||||
Dataflash_SendByte(DF_CMD_BUFF1WRITE);
|
||||
Dataflash_SendAddressBytes(0, CurrDFPageByte);
|
||||
|
||||
/* Wait until endpoint is ready before continuing */
|
||||
if (Endpoint_WaitUntilReady())
|
||||
return;
|
||||
|
||||
while (TotalBlocks)
|
||||
{
|
||||
uint8_t BytesInBlockDiv16 = 0;
|
||||
|
||||
/* Write an endpoint packet sized data block to the dataflash */
|
||||
while (BytesInBlockDiv16 < (VIRTUAL_MEMORY_BLOCK_SIZE >> 4))
|
||||
{
|
||||
/* Check if the endpoint is currently empty */
|
||||
if (!(Endpoint_IsReadWriteAllowed()))
|
||||
{
|
||||
/* Clear the current endpoint bank */
|
||||
Endpoint_ClearOUT();
|
||||
|
||||
/* Wait until the host has sent another packet */
|
||||
if (Endpoint_WaitUntilReady())
|
||||
return;
|
||||
}
|
||||
|
||||
/* Check if end of dataflash page reached */
|
||||
if (CurrDFPageByteDiv16 == (DATAFLASH_PAGE_SIZE >> 4))
|
||||
{
|
||||
/* Write the dataflash buffer contents back to the dataflash page */
|
||||
Dataflash_WaitWhileBusy();
|
||||
Dataflash_SendByte(UsingSecondBuffer ? DF_CMD_BUFF2TOMAINMEMWITHERASE : DF_CMD_BUFF1TOMAINMEMWITHERASE);
|
||||
Dataflash_SendAddressBytes(CurrDFPage, 0);
|
||||
|
||||
/* Reset the dataflash buffer counter, increment the page counter */
|
||||
CurrDFPageByteDiv16 = 0;
|
||||
CurrDFPage++;
|
||||
|
||||
/* Once all the dataflash ICs have had their first buffers filled, switch buffers to maintain throughput */
|
||||
if (Dataflash_GetSelectedChip() == DATAFLASH_CHIP_MASK(DATAFLASH_TOTALCHIPS))
|
||||
UsingSecondBuffer = !(UsingSecondBuffer);
|
||||
|
||||
/* Select the next dataflash chip based on the new dataflash page index */
|
||||
Dataflash_SelectChipFromPage(CurrDFPage);
|
||||
|
||||
#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 ((TotalBlocks * (VIRTUAL_MEMORY_BLOCK_SIZE >> 4)) < (DATAFLASH_PAGE_SIZE >> 4))
|
||||
{
|
||||
/* Copy selected dataflash's current page contents to the dataflash buffer */
|
||||
Dataflash_WaitWhileBusy();
|
||||
Dataflash_SendByte(UsingSecondBuffer ? DF_CMD_MAINMEMTOBUFF2 : DF_CMD_MAINMEMTOBUFF1);
|
||||
Dataflash_SendAddressBytes(CurrDFPage, 0);
|
||||
Dataflash_WaitWhileBusy();
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Send the dataflash buffer write command */
|
||||
Dataflash_SendByte(UsingSecondBuffer ? DF_CMD_BUFF2WRITE : DF_CMD_BUFF1WRITE);
|
||||
Dataflash_SendAddressBytes(0, 0);
|
||||
}
|
||||
|
||||
/* 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());
|
||||
|
||||
/* Increment the dataflash page 16 byte block counter */
|
||||
CurrDFPageByteDiv16++;
|
||||
|
||||
/* Increment the block 16 byte block counter */
|
||||
BytesInBlockDiv16++;
|
||||
|
||||
/* Check if the current command is being aborted by the host */
|
||||
if (MSInterfaceInfo->State.IsMassStoreReset)
|
||||
return;
|
||||
}
|
||||
|
||||
/* Decrement the blocks remaining counter and reset the sub block counter */
|
||||
TotalBlocks--;
|
||||
}
|
||||
|
||||
/* Write the dataflash buffer contents back to the dataflash page */
|
||||
Dataflash_WaitWhileBusy();
|
||||
Dataflash_SendByte(UsingSecondBuffer ? DF_CMD_BUFF2TOMAINMEMWITHERASE : DF_CMD_BUFF1TOMAINMEMWITHERASE);
|
||||
Dataflash_SendAddressBytes(CurrDFPage, 0x00);
|
||||
Dataflash_WaitWhileBusy();
|
||||
|
||||
/* If the endpoint is empty, clear it ready for the next packet from the host */
|
||||
if (!(Endpoint_IsReadWriteAllowed()))
|
||||
Endpoint_ClearOUT();
|
||||
|
||||
/* Deselect all dataflash chips */
|
||||
Dataflash_DeselectChip();
|
||||
}
|
||||
|
||||
/** 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
|
||||
* 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] BlockAddress Data block starting address for the read sequence
|
||||
* \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)
|
||||
{
|
||||
uint16_t CurrDFPage = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) / DATAFLASH_PAGE_SIZE);
|
||||
uint16_t CurrDFPageByte = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) % DATAFLASH_PAGE_SIZE);
|
||||
uint8_t CurrDFPageByteDiv16 = (CurrDFPageByte >> 4);
|
||||
|
||||
/* Select the correct starting Dataflash IC for the block requested */
|
||||
Dataflash_SelectChipFromPage(CurrDFPage);
|
||||
|
||||
/* Send the dataflash main memory page read command */
|
||||
Dataflash_SendByte(DF_CMD_MAINMEMPAGEREAD);
|
||||
Dataflash_SendAddressBytes(CurrDFPage, CurrDFPageByte);
|
||||
Dataflash_SendByte(0x00);
|
||||
Dataflash_SendByte(0x00);
|
||||
Dataflash_SendByte(0x00);
|
||||
Dataflash_SendByte(0x00);
|
||||
|
||||
/* Wait until endpoint is ready before continuing */
|
||||
if (Endpoint_WaitUntilReady())
|
||||
return;
|
||||
|
||||
while (TotalBlocks)
|
||||
{
|
||||
uint8_t BytesInBlockDiv16 = 0;
|
||||
|
||||
/* Write an endpoint packet sized data block to the dataflash */
|
||||
while (BytesInBlockDiv16 < (VIRTUAL_MEMORY_BLOCK_SIZE >> 4))
|
||||
{
|
||||
/* Check if the endpoint is currently full */
|
||||
if (!(Endpoint_IsReadWriteAllowed()))
|
||||
{
|
||||
/* Clear the endpoint bank to send its contents to the host */
|
||||
Endpoint_ClearIN();
|
||||
|
||||
/* Wait until the endpoint is ready for more data */
|
||||
if (Endpoint_WaitUntilReady())
|
||||
return;
|
||||
}
|
||||
|
||||
/* Check if end of dataflash page reached */
|
||||
if (CurrDFPageByteDiv16 == (DATAFLASH_PAGE_SIZE >> 4))
|
||||
{
|
||||
/* Reset the dataflash buffer counter, increment the page counter */
|
||||
CurrDFPageByteDiv16 = 0;
|
||||
CurrDFPage++;
|
||||
|
||||
/* Select the next dataflash chip based on the new dataflash page index */
|
||||
Dataflash_SelectChipFromPage(CurrDFPage);
|
||||
|
||||
/* Send the dataflash main memory page read command */
|
||||
Dataflash_SendByte(DF_CMD_MAINMEMPAGEREAD);
|
||||
Dataflash_SendAddressBytes(CurrDFPage, 0);
|
||||
Dataflash_SendByte(0x00);
|
||||
Dataflash_SendByte(0x00);
|
||||
Dataflash_SendByte(0x00);
|
||||
Dataflash_SendByte(0x00);
|
||||
}
|
||||
|
||||
/* 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());
|
||||
|
||||
/* Increment the dataflash page 16 byte block counter */
|
||||
CurrDFPageByteDiv16++;
|
||||
|
||||
/* Increment the block 16 byte block counter */
|
||||
BytesInBlockDiv16++;
|
||||
|
||||
/* Check if the current command is being aborted by the host */
|
||||
if (MSInterfaceInfo->State.IsMassStoreReset)
|
||||
return;
|
||||
}
|
||||
|
||||
/* Decrement the blocks remaining counter */
|
||||
TotalBlocks--;
|
||||
}
|
||||
|
||||
/* If the endpoint is full, send its contents to the host */
|
||||
if (!(Endpoint_IsReadWriteAllowed()))
|
||||
Endpoint_ClearIN();
|
||||
|
||||
/* Deselect all dataflash chips */
|
||||
Dataflash_DeselectChip();
|
||||
}
|
||||
|
||||
/** 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
|
||||
* dataflash in Dataflash page sized blocks. This can be linked to FAT libraries to write files to the
|
||||
* dataflash.
|
||||
*
|
||||
* \param[in] BlockAddress Data block starting address for the write sequence
|
||||
* \param[in] TotalBlocks Number of blocks of data to write
|
||||
* \param[in] BufferPtr Pointer to the data source RAM buffer
|
||||
*/
|
||||
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 CurrDFPageByte = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) % DATAFLASH_PAGE_SIZE);
|
||||
uint8_t CurrDFPageByteDiv16 = (CurrDFPageByte >> 4);
|
||||
bool UsingSecondBuffer = false;
|
||||
|
||||
/* Select the correct starting Dataflash IC for the block requested */
|
||||
Dataflash_SelectChipFromPage(CurrDFPage);
|
||||
|
||||
#if (DATAFLASH_PAGE_SIZE > VIRTUAL_MEMORY_BLOCK_SIZE)
|
||||
/* Copy selected dataflash's current page contents to the dataflash buffer */
|
||||
Dataflash_SendByte(DF_CMD_MAINMEMTOBUFF1);
|
||||
Dataflash_SendAddressBytes(CurrDFPage, 0);
|
||||
Dataflash_WaitWhileBusy();
|
||||
#endif
|
||||
|
||||
/* Send the dataflash buffer write command */
|
||||
Dataflash_SendByte(DF_CMD_BUFF1WRITE);
|
||||
Dataflash_SendAddressBytes(0, CurrDFPageByte);
|
||||
|
||||
while (TotalBlocks)
|
||||
{
|
||||
uint8_t BytesInBlockDiv16 = 0;
|
||||
|
||||
/* Write an endpoint packet sized data block to the dataflash */
|
||||
while (BytesInBlockDiv16 < (VIRTUAL_MEMORY_BLOCK_SIZE >> 4))
|
||||
{
|
||||
/* Check if end of dataflash page reached */
|
||||
if (CurrDFPageByteDiv16 == (DATAFLASH_PAGE_SIZE >> 4))
|
||||
{
|
||||
/* Write the dataflash buffer contents back to the dataflash page */
|
||||
Dataflash_WaitWhileBusy();
|
||||
Dataflash_SendByte(UsingSecondBuffer ? DF_CMD_BUFF2TOMAINMEMWITHERASE : DF_CMD_BUFF1TOMAINMEMWITHERASE);
|
||||
Dataflash_SendAddressBytes(CurrDFPage, 0);
|
||||
|
||||
/* Reset the dataflash buffer counter, increment the page counter */
|
||||
CurrDFPageByteDiv16 = 0;
|
||||
CurrDFPage++;
|
||||
|
||||
/* Once all the dataflash ICs have had their first buffers filled, switch buffers to maintain throughput */
|
||||
if (Dataflash_GetSelectedChip() == DATAFLASH_CHIP_MASK(DATAFLASH_TOTALCHIPS))
|
||||
UsingSecondBuffer = !(UsingSecondBuffer);
|
||||
|
||||
/* Select the next dataflash chip based on the new dataflash page index */
|
||||
Dataflash_SelectChipFromPage(CurrDFPage);
|
||||
|
||||
#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 ((TotalBlocks * (VIRTUAL_MEMORY_BLOCK_SIZE >> 4)) < (DATAFLASH_PAGE_SIZE >> 4))
|
||||
{
|
||||
/* Copy selected dataflash's current page contents to the dataflash buffer */
|
||||
Dataflash_WaitWhileBusy();
|
||||
Dataflash_SendByte(UsingSecondBuffer ? DF_CMD_MAINMEMTOBUFF2 : DF_CMD_MAINMEMTOBUFF1);
|
||||
Dataflash_SendAddressBytes(CurrDFPage, 0);
|
||||
Dataflash_WaitWhileBusy();
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Send the dataflash buffer write command */
|
||||
Dataflash_ToggleSelectedChipCS();
|
||||
Dataflash_SendByte(DF_CMD_BUFF1WRITE);
|
||||
Dataflash_SendAddressBytes(0, 0);
|
||||
}
|
||||
|
||||
/* Write one 16-byte chunk of data to the dataflash */
|
||||
for (uint8_t ByteNum = 0; ByteNum < 16; ByteNum++)
|
||||
Dataflash_SendByte(*(BufferPtr++));
|
||||
|
||||
/* Increment the dataflash page 16 byte block counter */
|
||||
CurrDFPageByteDiv16++;
|
||||
|
||||
/* Increment the block 16 byte block counter */
|
||||
BytesInBlockDiv16++;
|
||||
}
|
||||
|
||||
/* Decrement the blocks remaining counter and reset the sub block counter */
|
||||
TotalBlocks--;
|
||||
}
|
||||
|
||||
/* Write the dataflash buffer contents back to the dataflash page */
|
||||
Dataflash_WaitWhileBusy();
|
||||
Dataflash_SendByte(UsingSecondBuffer ? DF_CMD_BUFF2TOMAINMEMWITHERASE : DF_CMD_BUFF1TOMAINMEMWITHERASE);
|
||||
Dataflash_SendAddressBytes(CurrDFPage, 0x00);
|
||||
Dataflash_WaitWhileBusy();
|
||||
|
||||
/* Deselect all dataflash chips */
|
||||
Dataflash_DeselectChip();
|
||||
}
|
||||
|
||||
/** 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
|
||||
* 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.
|
||||
*
|
||||
* \param[in] BlockAddress Data block starting address for the read sequence
|
||||
* \param[in] TotalBlocks Number of blocks of data to read
|
||||
* \param[out] BufferPtr Pointer to the data destination RAM buffer
|
||||
*/
|
||||
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 CurrDFPageByte = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) % DATAFLASH_PAGE_SIZE);
|
||||
uint8_t CurrDFPageByteDiv16 = (CurrDFPageByte >> 4);
|
||||
|
||||
/* Select the correct starting Dataflash IC for the block requested */
|
||||
Dataflash_SelectChipFromPage(CurrDFPage);
|
||||
|
||||
/* Send the dataflash main memory page read command */
|
||||
Dataflash_SendByte(DF_CMD_MAINMEMPAGEREAD);
|
||||
Dataflash_SendAddressBytes(CurrDFPage, CurrDFPageByte);
|
||||
Dataflash_SendByte(0x00);
|
||||
Dataflash_SendByte(0x00);
|
||||
Dataflash_SendByte(0x00);
|
||||
Dataflash_SendByte(0x00);
|
||||
|
||||
while (TotalBlocks)
|
||||
{
|
||||
uint8_t BytesInBlockDiv16 = 0;
|
||||
|
||||
/* Write an endpoint packet sized data block to the dataflash */
|
||||
while (BytesInBlockDiv16 < (VIRTUAL_MEMORY_BLOCK_SIZE >> 4))
|
||||
{
|
||||
/* Check if end of dataflash page reached */
|
||||
if (CurrDFPageByteDiv16 == (DATAFLASH_PAGE_SIZE >> 4))
|
||||
{
|
||||
/* Reset the dataflash buffer counter, increment the page counter */
|
||||
CurrDFPageByteDiv16 = 0;
|
||||
CurrDFPage++;
|
||||
|
||||
/* Select the next dataflash chip based on the new dataflash page index */
|
||||
Dataflash_SelectChipFromPage(CurrDFPage);
|
||||
|
||||
/* Send the dataflash main memory page read command */
|
||||
Dataflash_SendByte(DF_CMD_MAINMEMPAGEREAD);
|
||||
Dataflash_SendAddressBytes(CurrDFPage, 0);
|
||||
Dataflash_SendByte(0x00);
|
||||
Dataflash_SendByte(0x00);
|
||||
Dataflash_SendByte(0x00);
|
||||
Dataflash_SendByte(0x00);
|
||||
}
|
||||
|
||||
/* Read one 16-byte chunk of data from the dataflash */
|
||||
for (uint8_t ByteNum = 0; ByteNum < 16; ByteNum++)
|
||||
*(BufferPtr++) = Dataflash_ReceiveByte();
|
||||
|
||||
/* Increment the dataflash page 16 byte block counter */
|
||||
CurrDFPageByteDiv16++;
|
||||
|
||||
/* Increment the block 16 byte block counter */
|
||||
BytesInBlockDiv16++;
|
||||
}
|
||||
|
||||
/* Decrement the blocks remaining counter */
|
||||
TotalBlocks--;
|
||||
}
|
||||
|
||||
/* Deselect all dataflash chips */
|
||||
Dataflash_DeselectChip();
|
||||
}
|
||||
|
||||
/** Disables the dataflash memory write protection bits on the board Dataflash ICs, if enabled. */
|
||||
void DataflashManager_ResetDataflashProtections(void)
|
||||
{
|
||||
/* Select first dataflash chip, send the read status register command */
|
||||
Dataflash_SelectChip(DATAFLASH_CHIP1);
|
||||
Dataflash_SendByte(DF_CMD_GETSTATUS);
|
||||
|
||||
/* Check if sector protection is enabled */
|
||||
if (Dataflash_ReceiveByte() & DF_STATUS_SECTORPROTECTION_ON)
|
||||
{
|
||||
Dataflash_ToggleSelectedChipCS();
|
||||
|
||||
/* Send the commands to disable sector protection */
|
||||
Dataflash_SendByte(DF_CMD_SECTORPROTECTIONOFF[0]);
|
||||
Dataflash_SendByte(DF_CMD_SECTORPROTECTIONOFF[1]);
|
||||
Dataflash_SendByte(DF_CMD_SECTORPROTECTIONOFF[2]);
|
||||
Dataflash_SendByte(DF_CMD_SECTORPROTECTIONOFF[3]);
|
||||
}
|
||||
|
||||
/* Select second dataflash chip (if present on selected board), send read status register command */
|
||||
#if (DATAFLASH_TOTALCHIPS == 2)
|
||||
Dataflash_SelectChip(DATAFLASH_CHIP2);
|
||||
Dataflash_SendByte(DF_CMD_GETSTATUS);
|
||||
|
||||
/* Check if sector protection is enabled */
|
||||
if (Dataflash_ReceiveByte() & DF_STATUS_SECTORPROTECTION_ON)
|
||||
{
|
||||
Dataflash_ToggleSelectedChipCS();
|
||||
|
||||
/* Send the commands to disable sector protection */
|
||||
Dataflash_SendByte(DF_CMD_SECTORPROTECTIONOFF[0]);
|
||||
Dataflash_SendByte(DF_CMD_SECTORPROTECTIONOFF[1]);
|
||||
Dataflash_SendByte(DF_CMD_SECTORPROTECTIONOFF[2]);
|
||||
Dataflash_SendByte(DF_CMD_SECTORPROTECTIONOFF[3]);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Deselect current dataflash chip */
|
||||
Dataflash_DeselectChip();
|
||||
}
|
||||
|
@ -1,77 +1,77 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Header file for DataflashManager.c.
|
||||
*/
|
||||
|
||||
#ifndef _DATAFLASH_MANAGER_H_
|
||||
#define _DATAFLASH_MANAGER_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/io.h>
|
||||
|
||||
#include "MassStorageKeyboard.h"
|
||||
#include "Descriptors.h"
|
||||
|
||||
#include <LUFA/Common/Common.h>
|
||||
#include <LUFA/Drivers/USB/USB.h>
|
||||
#include <LUFA/Drivers/Board/Dataflash.h>
|
||||
|
||||
/* Preprocessor Checks: */
|
||||
#if (DATAFLASH_PAGE_SIZE % 16)
|
||||
#error Dataflash page size must be a multiple of 16 bytes.
|
||||
#endif
|
||||
|
||||
/* Defines: */
|
||||
/** 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)
|
||||
|
||||
/** 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.
|
||||
*/
|
||||
#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. */
|
||||
#define VIRTUAL_MEMORY_BLOCKS (VIRTUAL_MEMORY_BYTES / VIRTUAL_MEMORY_BLOCK_SIZE)
|
||||
|
||||
/* Function Prototypes: */
|
||||
void DataflashManager_WriteBlocks(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);
|
||||
void DataflashManager_WriteBlocks_RAM(const uint32_t BlockAddress, uint16_t TotalBlocks,
|
||||
uint8_t* BufferPtr) ATTR_NON_NULL_PTR_ARG(3);
|
||||
void DataflashManager_ReadBlocks_RAM(const uint32_t BlockAddress, uint16_t TotalBlocks,
|
||||
uint8_t* BufferPtr) ATTR_NON_NULL_PTR_ARG(3);
|
||||
void DataflashManager_ResetDataflashProtections(void);
|
||||
|
||||
#endif
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Header file for DataflashManager.c.
|
||||
*/
|
||||
|
||||
#ifndef _DATAFLASH_MANAGER_H_
|
||||
#define _DATAFLASH_MANAGER_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/io.h>
|
||||
|
||||
#include "MassStorageKeyboard.h"
|
||||
#include "Descriptors.h"
|
||||
|
||||
#include <LUFA/Common/Common.h>
|
||||
#include <LUFA/Drivers/USB/USB.h>
|
||||
#include <LUFA/Drivers/Board/Dataflash.h>
|
||||
|
||||
/* Preprocessor Checks: */
|
||||
#if (DATAFLASH_PAGE_SIZE % 16)
|
||||
#error Dataflash page size must be a multiple of 16 bytes.
|
||||
#endif
|
||||
|
||||
/* Defines: */
|
||||
/** 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)
|
||||
|
||||
/** 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.
|
||||
*/
|
||||
#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. */
|
||||
#define VIRTUAL_MEMORY_BLOCKS (VIRTUAL_MEMORY_BYTES / VIRTUAL_MEMORY_BLOCK_SIZE)
|
||||
|
||||
/* Function Prototypes: */
|
||||
void DataflashManager_WriteBlocks(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);
|
||||
void DataflashManager_WriteBlocks_RAM(const uint32_t BlockAddress, uint16_t TotalBlocks,
|
||||
uint8_t* BufferPtr) ATTR_NON_NULL_PTR_ARG(3);
|
||||
void DataflashManager_ReadBlocks_RAM(const uint32_t BlockAddress, uint16_t TotalBlocks,
|
||||
uint8_t* BufferPtr) ATTR_NON_NULL_PTR_ARG(3);
|
||||
void DataflashManager_ResetDataflashProtections(void);
|
||||
|
||||
#endif
|
||||
|
@ -1,345 +1,345 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* 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,
|
||||
* which wrap around standard SCSI device commands for controlling the actual storage medium.
|
||||
*/
|
||||
|
||||
#define INCLUDE_FROM_SCSI_C
|
||||
#include "SCSI.h"
|
||||
|
||||
/** Structure to hold the SCSI response data to a SCSI INQUIRY command. This gives information about the device's
|
||||
* features and capabilities.
|
||||
*/
|
||||
SCSI_Inquiry_Response_t InquiryData =
|
||||
{
|
||||
.DeviceType = DEVICE_TYPE_BLOCK,
|
||||
.PeripheralQualifier = 0,
|
||||
|
||||
.Removable = true,
|
||||
|
||||
.Version = 0,
|
||||
|
||||
.ResponseDataFormat = 2,
|
||||
.NormACA = false,
|
||||
.TrmTsk = false,
|
||||
.AERC = false,
|
||||
|
||||
.AdditionalLength = 0x1F,
|
||||
|
||||
.SoftReset = false,
|
||||
.CmdQue = false,
|
||||
.Linked = false,
|
||||
.Sync = false,
|
||||
.WideBus16Bit = false,
|
||||
.WideBus32Bit = false,
|
||||
.RelAddr = false,
|
||||
|
||||
.VendorID = "LUFA",
|
||||
.ProductID = "Dataflash Disk",
|
||||
.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
|
||||
* command is issued. This gives information on exactly why the last command failed to complete.
|
||||
*/
|
||||
SCSI_Request_Sense_Response_t SenseData =
|
||||
{
|
||||
.ResponseCode = 0x70,
|
||||
.AdditionalLength = 0x0A,
|
||||
};
|
||||
|
||||
|
||||
/** 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
|
||||
* 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
|
||||
*/
|
||||
bool SCSI_DecodeSCSICommand(USB_ClassInfo_MS_Device_t* MSInterfaceInfo)
|
||||
{
|
||||
bool CommandSuccess = false;
|
||||
|
||||
/* Run the appropriate SCSI command hander function based on the passed command */
|
||||
switch (MSInterfaceInfo->State.CommandBlock.SCSICommandData[0])
|
||||
{
|
||||
case SCSI_CMD_INQUIRY:
|
||||
CommandSuccess = SCSI_Command_Inquiry(MSInterfaceInfo);
|
||||
break;
|
||||
case SCSI_CMD_REQUEST_SENSE:
|
||||
CommandSuccess = SCSI_Command_Request_Sense(MSInterfaceInfo);
|
||||
break;
|
||||
case SCSI_CMD_READ_CAPACITY_10:
|
||||
CommandSuccess = SCSI_Command_Read_Capacity_10(MSInterfaceInfo);
|
||||
break;
|
||||
case SCSI_CMD_SEND_DIAGNOSTIC:
|
||||
CommandSuccess = SCSI_Command_Send_Diagnostic(MSInterfaceInfo);
|
||||
break;
|
||||
case SCSI_CMD_WRITE_10:
|
||||
CommandSuccess = SCSI_Command_ReadWrite_10(MSInterfaceInfo, DATA_WRITE);
|
||||
break;
|
||||
case SCSI_CMD_READ_10:
|
||||
CommandSuccess = SCSI_Command_ReadWrite_10(MSInterfaceInfo, DATA_READ);
|
||||
break;
|
||||
case SCSI_CMD_TEST_UNIT_READY:
|
||||
case SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL:
|
||||
case SCSI_CMD_VERIFY_10:
|
||||
/* These commands should just succeed, no handling required */
|
||||
CommandSuccess = true;
|
||||
MSInterfaceInfo->State.CommandBlock.DataTransferLength = 0;
|
||||
break;
|
||||
default:
|
||||
/* Update the SENSE key to reflect the invalid command */
|
||||
SCSI_SET_SENSE(SCSI_SENSE_KEY_ILLEGAL_REQUEST,
|
||||
SCSI_ASENSE_INVALID_COMMAND,
|
||||
SCSI_ASENSEQ_NO_QUALIFIER);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Check if command was successfully processed */
|
||||
if (CommandSuccess)
|
||||
{
|
||||
SCSI_SET_SENSE(SCSI_SENSE_KEY_GOOD,
|
||||
SCSI_ASENSE_NO_ADDITIONAL_INFORMATION,
|
||||
SCSI_ASENSEQ_NO_QUALIFIER);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Command processing for an issued SCSI INQUIRY command. This command returns information about the device's features
|
||||
* and capabilities to the host.
|
||||
*
|
||||
* \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.
|
||||
*/
|
||||
static bool SCSI_Command_Inquiry(USB_ClassInfo_MS_Device_t* MSInterfaceInfo)
|
||||
{
|
||||
uint16_t AllocationLength = (((uint16_t)MSInterfaceInfo->State.CommandBlock.SCSICommandData[3] << 8) |
|
||||
MSInterfaceInfo->State.CommandBlock.SCSICommandData[4]);
|
||||
uint16_t BytesTransferred = (AllocationLength < sizeof(InquiryData))? AllocationLength :
|
||||
sizeof(InquiryData);
|
||||
|
||||
/* Only the standard INQUIRY data is supported, check if any optional INQUIRY bits set */
|
||||
if ((MSInterfaceInfo->State.CommandBlock.SCSICommandData[1] & ((1 << 0) | (1 << 1))) ||
|
||||
MSInterfaceInfo->State.CommandBlock.SCSICommandData[2])
|
||||
{
|
||||
/* Optional but unsupported bits set - update the SENSE key and fail the request */
|
||||
SCSI_SET_SENSE(SCSI_SENSE_KEY_ILLEGAL_REQUEST,
|
||||
SCSI_ASENSE_INVALID_FIELD_IN_CDB,
|
||||
SCSI_ASENSEQ_NO_QUALIFIER);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Endpoint_Write_Stream_LE(&InquiryData, BytesTransferred, NO_STREAM_CALLBACK);
|
||||
|
||||
uint8_t PadBytes[AllocationLength - BytesTransferred];
|
||||
|
||||
/* Pad out remaining bytes with 0x00 */
|
||||
Endpoint_Write_Stream_LE(&PadBytes, (AllocationLength - BytesTransferred), NO_STREAM_CALLBACK);
|
||||
|
||||
/* Finalize the stream transfer to send the last packet */
|
||||
Endpoint_ClearIN();
|
||||
|
||||
/* Succeed the command and update the bytes transferred counter */
|
||||
MSInterfaceInfo->State.CommandBlock.DataTransferLength -= BytesTransferred;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/** 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.
|
||||
*
|
||||
* \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.
|
||||
*/
|
||||
static bool SCSI_Command_Request_Sense(USB_ClassInfo_MS_Device_t* MSInterfaceInfo)
|
||||
{
|
||||
uint8_t AllocationLength = MSInterfaceInfo->State.CommandBlock.SCSICommandData[4];
|
||||
uint8_t BytesTransferred = (AllocationLength < sizeof(SenseData))? AllocationLength : sizeof(SenseData);
|
||||
|
||||
uint8_t PadBytes[AllocationLength - BytesTransferred];
|
||||
|
||||
Endpoint_Write_Stream_LE(&SenseData, BytesTransferred, NO_STREAM_CALLBACK);
|
||||
Endpoint_Write_Stream_LE(&PadBytes, (AllocationLength - BytesTransferred), NO_STREAM_CALLBACK);
|
||||
Endpoint_ClearIN();
|
||||
|
||||
/* Succeed the command and update the bytes transferred counter */
|
||||
MSInterfaceInfo->State.CommandBlock.DataTransferLength -= BytesTransferred;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/** 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.
|
||||
*
|
||||
* \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.
|
||||
*/
|
||||
static bool SCSI_Command_Read_Capacity_10(USB_ClassInfo_MS_Device_t* MSInterfaceInfo)
|
||||
{
|
||||
uint32_t LastBlockAddressInLUN = (LUN_MEDIA_BLOCKS - 1);
|
||||
uint32_t MediaBlockSize = VIRTUAL_MEMORY_BLOCK_SIZE;
|
||||
|
||||
Endpoint_Write_Stream_BE(&LastBlockAddressInLUN, sizeof(LastBlockAddressInLUN), NO_STREAM_CALLBACK);
|
||||
Endpoint_Write_Stream_BE(&MediaBlockSize, sizeof(MediaBlockSize), NO_STREAM_CALLBACK);
|
||||
Endpoint_ClearIN();
|
||||
|
||||
/* Succeed the command and update the bytes transferred counter */
|
||||
MSInterfaceInfo->State.CommandBlock.DataTransferLength -= 8;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/** 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
|
||||
* supported.
|
||||
*
|
||||
* \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.
|
||||
*/
|
||||
static bool SCSI_Command_Send_Diagnostic(USB_ClassInfo_MS_Device_t* MSInterfaceInfo)
|
||||
{
|
||||
uint8_t ReturnByte;
|
||||
|
||||
/* Check to see if the SELF TEST bit is not set */
|
||||
if (!(MSInterfaceInfo->State.CommandBlock.SCSICommandData[1] & (1 << 2)))
|
||||
{
|
||||
/* Only self-test supported - update SENSE key and fail the command */
|
||||
SCSI_SET_SENSE(SCSI_SENSE_KEY_ILLEGAL_REQUEST,
|
||||
SCSI_ASENSE_INVALID_FIELD_IN_CDB,
|
||||
SCSI_ASENSEQ_NO_QUALIFIER);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Test first Dataflash IC is present and responding to commands */
|
||||
Dataflash_SelectChip(DATAFLASH_CHIP1);
|
||||
Dataflash_SendByte(DF_CMD_READMANUFACTURERDEVICEINFO);
|
||||
ReturnByte = Dataflash_ReceiveByte();
|
||||
Dataflash_DeselectChip();
|
||||
|
||||
/* If returned data is invalid, fail the command */
|
||||
if (ReturnByte != DF_MANUFACTURER_ATMEL)
|
||||
{
|
||||
/* Update SENSE key with a hardware error condition and return command fail */
|
||||
SCSI_SET_SENSE(SCSI_SENSE_KEY_HARDWARE_ERROR,
|
||||
SCSI_ASENSE_NO_ADDITIONAL_INFORMATION,
|
||||
SCSI_ASENSEQ_NO_QUALIFIER);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#if (DATAFLASH_TOTALCHIPS == 2)
|
||||
/* Test second Dataflash IC is present and responding to commands */
|
||||
Dataflash_SelectChip(DATAFLASH_CHIP2);
|
||||
Dataflash_SendByte(DF_CMD_READMANUFACTURERDEVICEINFO);
|
||||
ReturnByte = Dataflash_ReceiveByte();
|
||||
Dataflash_DeselectChip();
|
||||
|
||||
/* If returned data is invalid, fail the command */
|
||||
if (ReturnByte != DF_MANUFACTURER_ATMEL)
|
||||
{
|
||||
/* Update SENSE key with a hardware error condition and return command fail */
|
||||
SCSI_SET_SENSE(SCSI_SENSE_KEY_HARDWARE_ERROR,
|
||||
SCSI_ASENSE_NO_ADDITIONAL_INFORMATION,
|
||||
SCSI_ASENSEQ_NO_QUALIFIER);
|
||||
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Succeed the command and update the bytes transferred counter */
|
||||
MSInterfaceInfo->State.CommandBlock.DataTransferLength = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/** 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
|
||||
* 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] 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.
|
||||
*/
|
||||
static bool SCSI_Command_ReadWrite_10(USB_ClassInfo_MS_Device_t* MSInterfaceInfo, const bool IsDataRead)
|
||||
{
|
||||
uint32_t BlockAddress;
|
||||
uint16_t TotalBlocks;
|
||||
|
||||
/* 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)[2] = MSInterfaceInfo->State.CommandBlock.SCSICommandData[3];
|
||||
((uint8_t*)&BlockAddress)[1] = MSInterfaceInfo->State.CommandBlock.SCSICommandData[4];
|
||||
((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) */
|
||||
((uint8_t*)&TotalBlocks)[1] = MSInterfaceInfo->State.CommandBlock.SCSICommandData[7];
|
||||
((uint8_t*)&TotalBlocks)[0] = MSInterfaceInfo->State.CommandBlock.SCSICommandData[8];
|
||||
|
||||
/* Check if the block address is outside the maximum allowable value for the LUN */
|
||||
if (BlockAddress >= LUN_MEDIA_BLOCKS)
|
||||
{
|
||||
/* Block address is invalid, update SENSE key and return command fail */
|
||||
SCSI_SET_SENSE(SCSI_SENSE_KEY_ILLEGAL_REQUEST,
|
||||
SCSI_ASENSE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
|
||||
SCSI_ASENSEQ_NO_QUALIFIER);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#if (TOTAL_LUNS > 1)
|
||||
/* 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);
|
||||
#endif
|
||||
|
||||
/* Determine if the packet is a READ (10) or WRITE (10) command, call appropriate function */
|
||||
if (IsDataRead == DATA_READ)
|
||||
DataflashManager_ReadBlocks(MSInterfaceInfo, BlockAddress, TotalBlocks);
|
||||
else
|
||||
DataflashManager_WriteBlocks(MSInterfaceInfo, BlockAddress, TotalBlocks);
|
||||
|
||||
/* Update the bytes transferred counter and succeed the command */
|
||||
MSInterfaceInfo->State.CommandBlock.DataTransferLength -= ((uint32_t)TotalBlocks * VIRTUAL_MEMORY_BLOCK_SIZE);
|
||||
|
||||
return true;
|
||||
}
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* 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,
|
||||
* which wrap around standard SCSI device commands for controlling the actual storage medium.
|
||||
*/
|
||||
|
||||
#define INCLUDE_FROM_SCSI_C
|
||||
#include "SCSI.h"
|
||||
|
||||
/** Structure to hold the SCSI response data to a SCSI INQUIRY command. This gives information about the device's
|
||||
* features and capabilities.
|
||||
*/
|
||||
SCSI_Inquiry_Response_t InquiryData =
|
||||
{
|
||||
.DeviceType = DEVICE_TYPE_BLOCK,
|
||||
.PeripheralQualifier = 0,
|
||||
|
||||
.Removable = true,
|
||||
|
||||
.Version = 0,
|
||||
|
||||
.ResponseDataFormat = 2,
|
||||
.NormACA = false,
|
||||
.TrmTsk = false,
|
||||
.AERC = false,
|
||||
|
||||
.AdditionalLength = 0x1F,
|
||||
|
||||
.SoftReset = false,
|
||||
.CmdQue = false,
|
||||
.Linked = false,
|
||||
.Sync = false,
|
||||
.WideBus16Bit = false,
|
||||
.WideBus32Bit = false,
|
||||
.RelAddr = false,
|
||||
|
||||
.VendorID = "LUFA",
|
||||
.ProductID = "Dataflash Disk",
|
||||
.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
|
||||
* command is issued. This gives information on exactly why the last command failed to complete.
|
||||
*/
|
||||
SCSI_Request_Sense_Response_t SenseData =
|
||||
{
|
||||
.ResponseCode = 0x70,
|
||||
.AdditionalLength = 0x0A,
|
||||
};
|
||||
|
||||
|
||||
/** 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
|
||||
* 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
|
||||
*/
|
||||
bool SCSI_DecodeSCSICommand(USB_ClassInfo_MS_Device_t* MSInterfaceInfo)
|
||||
{
|
||||
bool CommandSuccess = false;
|
||||
|
||||
/* Run the appropriate SCSI command hander function based on the passed command */
|
||||
switch (MSInterfaceInfo->State.CommandBlock.SCSICommandData[0])
|
||||
{
|
||||
case SCSI_CMD_INQUIRY:
|
||||
CommandSuccess = SCSI_Command_Inquiry(MSInterfaceInfo);
|
||||
break;
|
||||
case SCSI_CMD_REQUEST_SENSE:
|
||||
CommandSuccess = SCSI_Command_Request_Sense(MSInterfaceInfo);
|
||||
break;
|
||||
case SCSI_CMD_READ_CAPACITY_10:
|
||||
CommandSuccess = SCSI_Command_Read_Capacity_10(MSInterfaceInfo);
|
||||
break;
|
||||
case SCSI_CMD_SEND_DIAGNOSTIC:
|
||||
CommandSuccess = SCSI_Command_Send_Diagnostic(MSInterfaceInfo);
|
||||
break;
|
||||
case SCSI_CMD_WRITE_10:
|
||||
CommandSuccess = SCSI_Command_ReadWrite_10(MSInterfaceInfo, DATA_WRITE);
|
||||
break;
|
||||
case SCSI_CMD_READ_10:
|
||||
CommandSuccess = SCSI_Command_ReadWrite_10(MSInterfaceInfo, DATA_READ);
|
||||
break;
|
||||
case SCSI_CMD_TEST_UNIT_READY:
|
||||
case SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL:
|
||||
case SCSI_CMD_VERIFY_10:
|
||||
/* These commands should just succeed, no handling required */
|
||||
CommandSuccess = true;
|
||||
MSInterfaceInfo->State.CommandBlock.DataTransferLength = 0;
|
||||
break;
|
||||
default:
|
||||
/* Update the SENSE key to reflect the invalid command */
|
||||
SCSI_SET_SENSE(SCSI_SENSE_KEY_ILLEGAL_REQUEST,
|
||||
SCSI_ASENSE_INVALID_COMMAND,
|
||||
SCSI_ASENSEQ_NO_QUALIFIER);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Check if command was successfully processed */
|
||||
if (CommandSuccess)
|
||||
{
|
||||
SCSI_SET_SENSE(SCSI_SENSE_KEY_GOOD,
|
||||
SCSI_ASENSE_NO_ADDITIONAL_INFORMATION,
|
||||
SCSI_ASENSEQ_NO_QUALIFIER);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Command processing for an issued SCSI INQUIRY command. This command returns information about the device's features
|
||||
* and capabilities to the host.
|
||||
*
|
||||
* \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.
|
||||
*/
|
||||
static bool SCSI_Command_Inquiry(USB_ClassInfo_MS_Device_t* MSInterfaceInfo)
|
||||
{
|
||||
uint16_t AllocationLength = (((uint16_t)MSInterfaceInfo->State.CommandBlock.SCSICommandData[3] << 8) |
|
||||
MSInterfaceInfo->State.CommandBlock.SCSICommandData[4]);
|
||||
uint16_t BytesTransferred = (AllocationLength < sizeof(InquiryData))? AllocationLength :
|
||||
sizeof(InquiryData);
|
||||
|
||||
/* Only the standard INQUIRY data is supported, check if any optional INQUIRY bits set */
|
||||
if ((MSInterfaceInfo->State.CommandBlock.SCSICommandData[1] & ((1 << 0) | (1 << 1))) ||
|
||||
MSInterfaceInfo->State.CommandBlock.SCSICommandData[2])
|
||||
{
|
||||
/* Optional but unsupported bits set - update the SENSE key and fail the request */
|
||||
SCSI_SET_SENSE(SCSI_SENSE_KEY_ILLEGAL_REQUEST,
|
||||
SCSI_ASENSE_INVALID_FIELD_IN_CDB,
|
||||
SCSI_ASENSEQ_NO_QUALIFIER);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Endpoint_Write_Stream_LE(&InquiryData, BytesTransferred, NO_STREAM_CALLBACK);
|
||||
|
||||
uint8_t PadBytes[AllocationLength - BytesTransferred];
|
||||
|
||||
/* Pad out remaining bytes with 0x00 */
|
||||
Endpoint_Write_Stream_LE(&PadBytes, (AllocationLength - BytesTransferred), NO_STREAM_CALLBACK);
|
||||
|
||||
/* Finalize the stream transfer to send the last packet */
|
||||
Endpoint_ClearIN();
|
||||
|
||||
/* Succeed the command and update the bytes transferred counter */
|
||||
MSInterfaceInfo->State.CommandBlock.DataTransferLength -= BytesTransferred;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/** 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.
|
||||
*
|
||||
* \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.
|
||||
*/
|
||||
static bool SCSI_Command_Request_Sense(USB_ClassInfo_MS_Device_t* MSInterfaceInfo)
|
||||
{
|
||||
uint8_t AllocationLength = MSInterfaceInfo->State.CommandBlock.SCSICommandData[4];
|
||||
uint8_t BytesTransferred = (AllocationLength < sizeof(SenseData))? AllocationLength : sizeof(SenseData);
|
||||
|
||||
uint8_t PadBytes[AllocationLength - BytesTransferred];
|
||||
|
||||
Endpoint_Write_Stream_LE(&SenseData, BytesTransferred, NO_STREAM_CALLBACK);
|
||||
Endpoint_Write_Stream_LE(&PadBytes, (AllocationLength - BytesTransferred), NO_STREAM_CALLBACK);
|
||||
Endpoint_ClearIN();
|
||||
|
||||
/* Succeed the command and update the bytes transferred counter */
|
||||
MSInterfaceInfo->State.CommandBlock.DataTransferLength -= BytesTransferred;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/** 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.
|
||||
*
|
||||
* \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.
|
||||
*/
|
||||
static bool SCSI_Command_Read_Capacity_10(USB_ClassInfo_MS_Device_t* MSInterfaceInfo)
|
||||
{
|
||||
uint32_t LastBlockAddressInLUN = (LUN_MEDIA_BLOCKS - 1);
|
||||
uint32_t MediaBlockSize = VIRTUAL_MEMORY_BLOCK_SIZE;
|
||||
|
||||
Endpoint_Write_Stream_BE(&LastBlockAddressInLUN, sizeof(LastBlockAddressInLUN), NO_STREAM_CALLBACK);
|
||||
Endpoint_Write_Stream_BE(&MediaBlockSize, sizeof(MediaBlockSize), NO_STREAM_CALLBACK);
|
||||
Endpoint_ClearIN();
|
||||
|
||||
/* Succeed the command and update the bytes transferred counter */
|
||||
MSInterfaceInfo->State.CommandBlock.DataTransferLength -= 8;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/** 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
|
||||
* supported.
|
||||
*
|
||||
* \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.
|
||||
*/
|
||||
static bool SCSI_Command_Send_Diagnostic(USB_ClassInfo_MS_Device_t* MSInterfaceInfo)
|
||||
{
|
||||
uint8_t ReturnByte;
|
||||
|
||||
/* Check to see if the SELF TEST bit is not set */
|
||||
if (!(MSInterfaceInfo->State.CommandBlock.SCSICommandData[1] & (1 << 2)))
|
||||
{
|
||||
/* Only self-test supported - update SENSE key and fail the command */
|
||||
SCSI_SET_SENSE(SCSI_SENSE_KEY_ILLEGAL_REQUEST,
|
||||
SCSI_ASENSE_INVALID_FIELD_IN_CDB,
|
||||
SCSI_ASENSEQ_NO_QUALIFIER);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Test first Dataflash IC is present and responding to commands */
|
||||
Dataflash_SelectChip(DATAFLASH_CHIP1);
|
||||
Dataflash_SendByte(DF_CMD_READMANUFACTURERDEVICEINFO);
|
||||
ReturnByte = Dataflash_ReceiveByte();
|
||||
Dataflash_DeselectChip();
|
||||
|
||||
/* If returned data is invalid, fail the command */
|
||||
if (ReturnByte != DF_MANUFACTURER_ATMEL)
|
||||
{
|
||||
/* Update SENSE key with a hardware error condition and return command fail */
|
||||
SCSI_SET_SENSE(SCSI_SENSE_KEY_HARDWARE_ERROR,
|
||||
SCSI_ASENSE_NO_ADDITIONAL_INFORMATION,
|
||||
SCSI_ASENSEQ_NO_QUALIFIER);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#if (DATAFLASH_TOTALCHIPS == 2)
|
||||
/* Test second Dataflash IC is present and responding to commands */
|
||||
Dataflash_SelectChip(DATAFLASH_CHIP2);
|
||||
Dataflash_SendByte(DF_CMD_READMANUFACTURERDEVICEINFO);
|
||||
ReturnByte = Dataflash_ReceiveByte();
|
||||
Dataflash_DeselectChip();
|
||||
|
||||
/* If returned data is invalid, fail the command */
|
||||
if (ReturnByte != DF_MANUFACTURER_ATMEL)
|
||||
{
|
||||
/* Update SENSE key with a hardware error condition and return command fail */
|
||||
SCSI_SET_SENSE(SCSI_SENSE_KEY_HARDWARE_ERROR,
|
||||
SCSI_ASENSE_NO_ADDITIONAL_INFORMATION,
|
||||
SCSI_ASENSEQ_NO_QUALIFIER);
|
||||
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Succeed the command and update the bytes transferred counter */
|
||||
MSInterfaceInfo->State.CommandBlock.DataTransferLength = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/** 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
|
||||
* 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] 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.
|
||||
*/
|
||||
static bool SCSI_Command_ReadWrite_10(USB_ClassInfo_MS_Device_t* MSInterfaceInfo, const bool IsDataRead)
|
||||
{
|
||||
uint32_t BlockAddress;
|
||||
uint16_t TotalBlocks;
|
||||
|
||||
/* 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)[2] = MSInterfaceInfo->State.CommandBlock.SCSICommandData[3];
|
||||
((uint8_t*)&BlockAddress)[1] = MSInterfaceInfo->State.CommandBlock.SCSICommandData[4];
|
||||
((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) */
|
||||
((uint8_t*)&TotalBlocks)[1] = MSInterfaceInfo->State.CommandBlock.SCSICommandData[7];
|
||||
((uint8_t*)&TotalBlocks)[0] = MSInterfaceInfo->State.CommandBlock.SCSICommandData[8];
|
||||
|
||||
/* Check if the block address is outside the maximum allowable value for the LUN */
|
||||
if (BlockAddress >= LUN_MEDIA_BLOCKS)
|
||||
{
|
||||
/* Block address is invalid, update SENSE key and return command fail */
|
||||
SCSI_SET_SENSE(SCSI_SENSE_KEY_ILLEGAL_REQUEST,
|
||||
SCSI_ASENSE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
|
||||
SCSI_ASENSEQ_NO_QUALIFIER);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#if (TOTAL_LUNS > 1)
|
||||
/* 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);
|
||||
#endif
|
||||
|
||||
/* Determine if the packet is a READ (10) or WRITE (10) command, call appropriate function */
|
||||
if (IsDataRead == DATA_READ)
|
||||
DataflashManager_ReadBlocks(MSInterfaceInfo, BlockAddress, TotalBlocks);
|
||||
else
|
||||
DataflashManager_WriteBlocks(MSInterfaceInfo, BlockAddress, TotalBlocks);
|
||||
|
||||
/* Update the bytes transferred counter and succeed the command */
|
||||
MSInterfaceInfo->State.CommandBlock.DataTransferLength -= ((uint32_t)TotalBlocks * VIRTUAL_MEMORY_BLOCK_SIZE);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -1,87 +1,87 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Header file for SCSI.c.
|
||||
*/
|
||||
|
||||
#ifndef _SCSI_H_
|
||||
#define _SCSI_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/io.h>
|
||||
#include <avr/pgmspace.h>
|
||||
|
||||
#include <LUFA/Drivers/USB/USB.h>
|
||||
#include <LUFA/Drivers/USB/Class/MassStorage.h>
|
||||
|
||||
#include "MassStorageKeyboard.h"
|
||||
#include "Descriptors.h"
|
||||
#include "DataflashManager.h"
|
||||
#include "SCSI_Codes.h"
|
||||
|
||||
/* Macros: */
|
||||
/** 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
|
||||
* 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] 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
|
||||
*/
|
||||
#define SCSI_SET_SENSE(key, acode, aqual) MACROS{ SenseData.SenseKey = key; \
|
||||
SenseData.AdditionalSenseCode = acode; \
|
||||
SenseData.AdditionalSenseQualifier = aqual; }MACROE
|
||||
|
||||
/** Macro for the SCSI_Command_ReadWrite_10() function, to indicate that data is to be read from the storage medium. */
|
||||
#define DATA_READ true
|
||||
|
||||
/** Macro for the SCSI_Command_ReadWrite_10() function, to indicate that data is to be written to the storage medium. */
|
||||
#define DATA_WRITE false
|
||||
|
||||
/** Value for the DeviceType entry in the SCSI_Inquiry_Response_t enum, indicating a Block Media device. */
|
||||
#define DEVICE_TYPE_BLOCK 0x00
|
||||
|
||||
/** Value for the DeviceType entry in the SCSI_Inquiry_Response_t enum, indicating a CD-ROM device. */
|
||||
#define DEVICE_TYPE_CDROM 0x05
|
||||
|
||||
/* Function Prototypes: */
|
||||
bool SCSI_DecodeSCSICommand(USB_ClassInfo_MS_Device_t* MSInterfaceInfo);
|
||||
|
||||
#if defined(INCLUDE_FROM_SCSI_C)
|
||||
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_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_ReadWrite_10(USB_ClassInfo_MS_Device_t* MSInterfaceInfo, const bool IsDataRead);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Header file for SCSI.c.
|
||||
*/
|
||||
|
||||
#ifndef _SCSI_H_
|
||||
#define _SCSI_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/io.h>
|
||||
#include <avr/pgmspace.h>
|
||||
|
||||
#include <LUFA/Drivers/USB/USB.h>
|
||||
#include <LUFA/Drivers/USB/Class/MassStorage.h>
|
||||
|
||||
#include "MassStorageKeyboard.h"
|
||||
#include "Descriptors.h"
|
||||
#include "DataflashManager.h"
|
||||
#include "SCSI_Codes.h"
|
||||
|
||||
/* Macros: */
|
||||
/** 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
|
||||
* 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] 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
|
||||
*/
|
||||
#define SCSI_SET_SENSE(key, acode, aqual) MACROS{ SenseData.SenseKey = key; \
|
||||
SenseData.AdditionalSenseCode = acode; \
|
||||
SenseData.AdditionalSenseQualifier = aqual; }MACROE
|
||||
|
||||
/** Macro for the SCSI_Command_ReadWrite_10() function, to indicate that data is to be read from the storage medium. */
|
||||
#define DATA_READ true
|
||||
|
||||
/** Macro for the SCSI_Command_ReadWrite_10() function, to indicate that data is to be written to the storage medium. */
|
||||
#define DATA_WRITE false
|
||||
|
||||
/** Value for the DeviceType entry in the SCSI_Inquiry_Response_t enum, indicating a Block Media device. */
|
||||
#define DEVICE_TYPE_BLOCK 0x00
|
||||
|
||||
/** Value for the DeviceType entry in the SCSI_Inquiry_Response_t enum, indicating a CD-ROM device. */
|
||||
#define DEVICE_TYPE_CDROM 0x05
|
||||
|
||||
/* Function Prototypes: */
|
||||
bool SCSI_DecodeSCSICommand(USB_ClassInfo_MS_Device_t* MSInterfaceInfo);
|
||||
|
||||
#if defined(INCLUDE_FROM_SCSI_C)
|
||||
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_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_ReadWrite_10(USB_ClassInfo_MS_Device_t* MSInterfaceInfo, const bool IsDataRead);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -1,85 +1,85 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Header containing macros for possible SCSI commands and SENSE data. Refer to
|
||||
* the SCSI standard documentation for more information on each SCSI command and
|
||||
* the SENSE data.
|
||||
*/
|
||||
|
||||
#ifndef _SCSI_CODES_H_
|
||||
#define _SCSI_CODES_H_
|
||||
|
||||
/* Macros: */
|
||||
#define SCSI_CMD_INQUIRY 0x12
|
||||
#define SCSI_CMD_REQUEST_SENSE 0x03
|
||||
#define SCSI_CMD_TEST_UNIT_READY 0x00
|
||||
#define SCSI_CMD_READ_CAPACITY_10 0x25
|
||||
#define SCSI_CMD_SEND_DIAGNOSTIC 0x1D
|
||||
#define SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL 0x1E
|
||||
#define SCSI_CMD_WRITE_10 0x2A
|
||||
#define SCSI_CMD_READ_10 0x28
|
||||
#define SCSI_CMD_WRITE_6 0x0A
|
||||
#define SCSI_CMD_READ_6 0x08
|
||||
#define SCSI_CMD_VERIFY_10 0x2F
|
||||
#define SCSI_CMD_MODE_SENSE_6 0x1A
|
||||
#define SCSI_CMD_MODE_SENSE_10 0x5A
|
||||
|
||||
#define SCSI_SENSE_KEY_GOOD 0x00
|
||||
#define SCSI_SENSE_KEY_RECOVERED_ERROR 0x01
|
||||
#define SCSI_SENSE_KEY_NOT_READY 0x02
|
||||
#define SCSI_SENSE_KEY_MEDIUM_ERROR 0x03
|
||||
#define SCSI_SENSE_KEY_HARDWARE_ERROR 0x04
|
||||
#define SCSI_SENSE_KEY_ILLEGAL_REQUEST 0x05
|
||||
#define SCSI_SENSE_KEY_UNIT_ATTENTION 0x06
|
||||
#define SCSI_SENSE_KEY_DATA_PROTECT 0x07
|
||||
#define SCSI_SENSE_KEY_BLANK_CHECK 0x08
|
||||
#define SCSI_SENSE_KEY_VENDOR_SPECIFIC 0x09
|
||||
#define SCSI_SENSE_KEY_COPY_ABORTED 0x0A
|
||||
#define SCSI_SENSE_KEY_ABORTED_COMMAND 0x0B
|
||||
#define SCSI_SENSE_KEY_VOLUME_OVERFLOW 0x0D
|
||||
#define SCSI_SENSE_KEY_MISCOMPARE 0x0E
|
||||
|
||||
#define SCSI_ASENSE_NO_ADDITIONAL_INFORMATION 0x00
|
||||
#define SCSI_ASENSE_LOGICAL_UNIT_NOT_READY 0x04
|
||||
#define SCSI_ASENSE_INVALID_FIELD_IN_CDB 0x24
|
||||
#define SCSI_ASENSE_WRITE_PROTECTED 0x27
|
||||
#define SCSI_ASENSE_FORMAT_ERROR 0x31
|
||||
#define SCSI_ASENSE_INVALID_COMMAND 0x20
|
||||
#define SCSI_ASENSE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE 0x21
|
||||
#define SCSI_ASENSE_MEDIUM_NOT_PRESENT 0x3A
|
||||
|
||||
#define SCSI_ASENSEQ_NO_QUALIFIER 0x00
|
||||
#define SCSI_ASENSEQ_FORMAT_COMMAND_FAILED 0x01
|
||||
#define SCSI_ASENSEQ_INITIALIZING_COMMAND_REQUIRED 0x02
|
||||
#define SCSI_ASENSEQ_OPERATION_IN_PROGRESS 0x07
|
||||
|
||||
#endif
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Header containing macros for possible SCSI commands and SENSE data. Refer to
|
||||
* the SCSI standard documentation for more information on each SCSI command and
|
||||
* the SENSE data.
|
||||
*/
|
||||
|
||||
#ifndef _SCSI_CODES_H_
|
||||
#define _SCSI_CODES_H_
|
||||
|
||||
/* Macros: */
|
||||
#define SCSI_CMD_INQUIRY 0x12
|
||||
#define SCSI_CMD_REQUEST_SENSE 0x03
|
||||
#define SCSI_CMD_TEST_UNIT_READY 0x00
|
||||
#define SCSI_CMD_READ_CAPACITY_10 0x25
|
||||
#define SCSI_CMD_SEND_DIAGNOSTIC 0x1D
|
||||
#define SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL 0x1E
|
||||
#define SCSI_CMD_WRITE_10 0x2A
|
||||
#define SCSI_CMD_READ_10 0x28
|
||||
#define SCSI_CMD_WRITE_6 0x0A
|
||||
#define SCSI_CMD_READ_6 0x08
|
||||
#define SCSI_CMD_VERIFY_10 0x2F
|
||||
#define SCSI_CMD_MODE_SENSE_6 0x1A
|
||||
#define SCSI_CMD_MODE_SENSE_10 0x5A
|
||||
|
||||
#define SCSI_SENSE_KEY_GOOD 0x00
|
||||
#define SCSI_SENSE_KEY_RECOVERED_ERROR 0x01
|
||||
#define SCSI_SENSE_KEY_NOT_READY 0x02
|
||||
#define SCSI_SENSE_KEY_MEDIUM_ERROR 0x03
|
||||
#define SCSI_SENSE_KEY_HARDWARE_ERROR 0x04
|
||||
#define SCSI_SENSE_KEY_ILLEGAL_REQUEST 0x05
|
||||
#define SCSI_SENSE_KEY_UNIT_ATTENTION 0x06
|
||||
#define SCSI_SENSE_KEY_DATA_PROTECT 0x07
|
||||
#define SCSI_SENSE_KEY_BLANK_CHECK 0x08
|
||||
#define SCSI_SENSE_KEY_VENDOR_SPECIFIC 0x09
|
||||
#define SCSI_SENSE_KEY_COPY_ABORTED 0x0A
|
||||
#define SCSI_SENSE_KEY_ABORTED_COMMAND 0x0B
|
||||
#define SCSI_SENSE_KEY_VOLUME_OVERFLOW 0x0D
|
||||
#define SCSI_SENSE_KEY_MISCOMPARE 0x0E
|
||||
|
||||
#define SCSI_ASENSE_NO_ADDITIONAL_INFORMATION 0x00
|
||||
#define SCSI_ASENSE_LOGICAL_UNIT_NOT_READY 0x04
|
||||
#define SCSI_ASENSE_INVALID_FIELD_IN_CDB 0x24
|
||||
#define SCSI_ASENSE_WRITE_PROTECTED 0x27
|
||||
#define SCSI_ASENSE_FORMAT_ERROR 0x31
|
||||
#define SCSI_ASENSE_INVALID_COMMAND 0x20
|
||||
#define SCSI_ASENSE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE 0x21
|
||||
#define SCSI_ASENSE_MEDIUM_NOT_PRESENT 0x3A
|
||||
|
||||
#define SCSI_ASENSEQ_NO_QUALIFIER 0x00
|
||||
#define SCSI_ASENSEQ_FORMAT_COMMAND_FAILED 0x01
|
||||
#define SCSI_ASENSEQ_INITIALIZING_COMMAND_REQUIRED 0x02
|
||||
#define SCSI_ASENSEQ_OPERATION_IN_PROGRESS 0x07
|
||||
|
||||
#endif
|
||||
|
@ -1,242 +1,242 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
Copyright 2010 Matthias Hullin (lufa [at] matthias [dot] hullin [dot] net)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Main source file for the MassStorageKeyboard demo. This file contains the main tasks of
|
||||
* the demo and is responsible for the initial application hardware configuration.
|
||||
*/
|
||||
|
||||
#include "MassStorageKeyboard.h"
|
||||
|
||||
/** 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
|
||||
* within a device can be differentiated from one another.
|
||||
*/
|
||||
USB_ClassInfo_MS_Device_t Disk_MS_Interface =
|
||||
{
|
||||
.Config =
|
||||
{
|
||||
.InterfaceNumber = 0,
|
||||
|
||||
.DataINEndpointNumber = MASS_STORAGE_IN_EPNUM,
|
||||
.DataINEndpointSize = MASS_STORAGE_IO_EPSIZE,
|
||||
.DataINEndpointDoubleBank = false,
|
||||
|
||||
.DataOUTEndpointNumber = MASS_STORAGE_OUT_EPNUM,
|
||||
.DataOUTEndpointSize = MASS_STORAGE_IO_EPSIZE,
|
||||
.DataOUTEndpointDoubleBank = false,
|
||||
|
||||
.TotalLUNs = TOTAL_LUNS,
|
||||
},
|
||||
};
|
||||
|
||||
/** 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)];
|
||||
|
||||
/** LUFA HID Class driver interface configuration and state information. This structure is
|
||||
* passed to all HID Class driver functions, so that multiple instances of the same class
|
||||
* within a device can be differentiated from one another.
|
||||
*/
|
||||
USB_ClassInfo_HID_Device_t Keyboard_HID_Interface =
|
||||
{
|
||||
.Config =
|
||||
{
|
||||
.InterfaceNumber = 1,
|
||||
|
||||
.ReportINEndpointNumber = KEYBOARD_EPNUM,
|
||||
.ReportINEndpointSize = KEYBOARD_EPSIZE,
|
||||
.ReportINEndpointDoubleBank = false,
|
||||
|
||||
.PrevReportINBuffer = PrevKeyboardHIDReportBuffer,
|
||||
.PrevReportINBufferSize = sizeof(PrevKeyboardHIDReportBuffer),
|
||||
},
|
||||
};
|
||||
|
||||
/** Main program entry point. This routine contains the overall program flow, including initial
|
||||
* setup of all components and the main program loop.
|
||||
*/
|
||||
int main(void)
|
||||
{
|
||||
SetupHardware();
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
|
||||
sei();
|
||||
|
||||
for (;;)
|
||||
{
|
||||
MS_Device_USBTask(&Disk_MS_Interface);
|
||||
HID_Device_USBTask(&Keyboard_HID_Interface);
|
||||
USB_USBTask();
|
||||
}
|
||||
}
|
||||
|
||||
/** Configures the board hardware and chip peripherals for the demo's functionality. */
|
||||
void SetupHardware(void)
|
||||
{
|
||||
/* Disable watchdog if enabled by bootloader/fuses */
|
||||
MCUSR &= ~(1 << WDRF);
|
||||
wdt_disable();
|
||||
|
||||
/* Disable clock division */
|
||||
clock_prescale_set(clock_div_1);
|
||||
|
||||
/* Hardware Initialization */
|
||||
LEDs_Init();
|
||||
Joystick_Init();
|
||||
Buttons_Init();
|
||||
SPI_Init(SPI_SPEED_FCPU_DIV_2 | SPI_SCK_LEAD_FALLING | SPI_SAMPLE_TRAILING | SPI_MODE_MASTER);
|
||||
Dataflash_Init();
|
||||
USB_Init();
|
||||
|
||||
/* Clear Dataflash sector protections, if enabled */
|
||||
DataflashManager_ResetDataflashProtections();
|
||||
}
|
||||
|
||||
/** Event handler for the library USB Connection event. */
|
||||
void EVENT_USB_Device_Connect(void)
|
||||
{
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
|
||||
}
|
||||
|
||||
/** Event handler for the library USB Disconnection event. */
|
||||
void EVENT_USB_Device_Disconnect(void)
|
||||
{
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
|
||||
}
|
||||
|
||||
/** Event handler for the library USB Configuration Changed event. */
|
||||
void EVENT_USB_Device_ConfigurationChanged(void)
|
||||
{
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
|
||||
if (!(MS_Device_ConfigureEndpoints(&Disk_MS_Interface)))
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
if (!(HID_Device_ConfigureEndpoints(&Keyboard_HID_Interface)))
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
USB_Device_EnableSOFEvents();
|
||||
}
|
||||
|
||||
/** Event handler for the library USB Unhandled Control Request event. */
|
||||
void EVENT_USB_Device_UnhandledControlRequest(void)
|
||||
{
|
||||
MS_Device_ProcessControlRequest(&Disk_MS_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.
|
||||
*
|
||||
* \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 CommandSuccess;
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_BUSY);
|
||||
CommandSuccess = SCSI_DecodeSCSICommand(MSInterfaceInfo);
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
|
||||
return CommandSuccess;
|
||||
}
|
||||
|
||||
/** Event handler for the USB device Start Of Frame event. */
|
||||
void EVENT_USB_Device_StartOfFrame(void)
|
||||
{
|
||||
HID_Device_MillisecondElapsed(&Keyboard_HID_Interface);
|
||||
}
|
||||
|
||||
/** 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,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[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
|
||||
*
|
||||
* \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,
|
||||
const uint8_t ReportType, void* ReportData, uint16_t* ReportSize)
|
||||
{
|
||||
USB_KeyboardReport_Data_t* KeyboardReport = (USB_KeyboardReport_Data_t*)ReportData;
|
||||
|
||||
uint8_t JoyStatus_LCL = Joystick_GetStatus();
|
||||
uint8_t ButtonStatus_LCL = Buttons_GetStatus();
|
||||
|
||||
KeyboardReport->Modifier = HID_KEYBOARD_MODIFER_LEFTSHIFT;
|
||||
|
||||
if (JoyStatus_LCL & JOY_UP)
|
||||
KeyboardReport->KeyCode[0] = 0x04; // A
|
||||
else if (JoyStatus_LCL & JOY_DOWN)
|
||||
KeyboardReport->KeyCode[0] = 0x05; // B
|
||||
|
||||
if (JoyStatus_LCL & JOY_LEFT)
|
||||
KeyboardReport->KeyCode[0] = 0x06; // C
|
||||
else if (JoyStatus_LCL & JOY_RIGHT)
|
||||
KeyboardReport->KeyCode[0] = 0x07; // D
|
||||
|
||||
if (JoyStatus_LCL & JOY_PRESS)
|
||||
KeyboardReport->KeyCode[0] = 0x08; // E
|
||||
|
||||
if (ButtonStatus_LCL & BUTTONS_BUTTON1)
|
||||
KeyboardReport->KeyCode[0] = 0x09; // F
|
||||
|
||||
*ReportSize = sizeof(USB_KeyboardReport_Data_t);
|
||||
return false;
|
||||
}
|
||||
|
||||
/** 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] 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] 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,
|
||||
const void* ReportData, const uint16_t ReportSize)
|
||||
{
|
||||
uint8_t LEDMask = LEDS_NO_LEDS;
|
||||
uint8_t* LEDReport = (uint8_t*)ReportData;
|
||||
|
||||
if (*LEDReport & HID_KEYBOARD_LED_NUMLOCK)
|
||||
LEDMask |= LEDS_LED1;
|
||||
|
||||
if (*LEDReport & HID_KEYBOARD_LED_CAPSLOCK)
|
||||
LEDMask |= LEDS_LED3;
|
||||
|
||||
if (*LEDReport & HID_KEYBOARD_LED_SCROLLLOCK)
|
||||
LEDMask |= LEDS_LED4;
|
||||
|
||||
LEDs_SetAllLEDs(LEDMask);
|
||||
}
|
||||
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2010.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
Copyright 2010 Matthias Hullin (lufa [at] matthias [dot] hullin [dot] net)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Main source file for the MassStorageKeyboard demo. This file contains the main tasks of
|
||||
* the demo and is responsible for the initial application hardware configuration.
|
||||
*/
|
||||
|
||||
#include "MassStorageKeyboard.h"
|
||||
|
||||
/** 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
|
||||
* within a device can be differentiated from one another.
|
||||
*/
|
||||
USB_ClassInfo_MS_Device_t Disk_MS_Interface =
|
||||
{
|
||||
.Config =
|
||||
{
|
||||
.InterfaceNumber = 0,
|
||||
|
||||
.DataINEndpointNumber = MASS_STORAGE_IN_EPNUM,
|
||||
.DataINEndpointSize = MASS_STORAGE_IO_EPSIZE,
|
||||
.DataINEndpointDoubleBank = false,
|
||||
|
||||
.DataOUTEndpointNumber = MASS_STORAGE_OUT_EPNUM,
|
||||
.DataOUTEndpointSize = MASS_STORAGE_IO_EPSIZE,
|
||||
.DataOUTEndpointDoubleBank = false,
|
||||
|
||||
.TotalLUNs = TOTAL_LUNS,
|
||||
},
|
||||
};
|
||||
|
||||
/** 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)];
|
||||
|
||||
/** LUFA HID Class driver interface configuration and state information. This structure is
|
||||
* passed to all HID Class driver functions, so that multiple instances of the same class
|
||||
* within a device can be differentiated from one another.
|
||||
*/
|
||||
USB_ClassInfo_HID_Device_t Keyboard_HID_Interface =
|
||||
{
|
||||
.Config =
|
||||
{
|
||||
.InterfaceNumber = 1,
|
||||
|
||||
.ReportINEndpointNumber = KEYBOARD_EPNUM,
|
||||
.ReportINEndpointSize = KEYBOARD_EPSIZE,
|
||||
.ReportINEndpointDoubleBank = false,
|
||||
|
||||
.PrevReportINBuffer = PrevKeyboardHIDReportBuffer,
|
||||
.PrevReportINBufferSize = sizeof(PrevKeyboardHIDReportBuffer),
|
||||
},
|
||||
};
|
||||
|
||||
/** Main program entry point. This routine contains the overall program flow, including initial
|
||||
* setup of all components and the main program loop.
|
||||
*/
|
||||
int main(void)
|
||||
{
|
||||
SetupHardware();
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
|
||||
sei();
|
||||
|
||||
for (;;)
|
||||
{
|
||||
MS_Device_USBTask(&Disk_MS_Interface);
|
||||
HID_Device_USBTask(&Keyboard_HID_Interface);
|
||||
USB_USBTask();
|
||||
}
|
||||
}
|
||||
|
||||
/** Configures the board hardware and chip peripherals for the demo's functionality. */
|
||||
void SetupHardware(void)
|
||||
{
|
||||
/* Disable watchdog if enabled by bootloader/fuses */
|
||||
MCUSR &= ~(1 << WDRF);
|
||||
wdt_disable();
|
||||
|
||||
/* Disable clock division */
|
||||
clock_prescale_set(clock_div_1);
|
||||
|
||||
/* Hardware Initialization */
|
||||
LEDs_Init();
|
||||
Joystick_Init();
|
||||
Buttons_Init();
|
||||
SPI_Init(SPI_SPEED_FCPU_DIV_2 | SPI_SCK_LEAD_FALLING | SPI_SAMPLE_TRAILING | SPI_MODE_MASTER);
|
||||
Dataflash_Init();
|
||||
USB_Init();
|
||||
|
||||
/* Clear Dataflash sector protections, if enabled */
|
||||
DataflashManager_ResetDataflashProtections();
|
||||
}
|
||||
|
||||
/** Event handler for the library USB Connection event. */
|
||||
void EVENT_USB_Device_Connect(void)
|
||||
{
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
|
||||
}
|
||||
|
||||
/** Event handler for the library USB Disconnection event. */
|
||||
void EVENT_USB_Device_Disconnect(void)
|
||||
{
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
|
||||
}
|
||||
|
||||
/** Event handler for the library USB Configuration Changed event. */
|
||||
void EVENT_USB_Device_ConfigurationChanged(void)
|
||||
{
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
|
||||
if (!(MS_Device_ConfigureEndpoints(&Disk_MS_Interface)))
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
if (!(HID_Device_ConfigureEndpoints(&Keyboard_HID_Interface)))
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
USB_Device_EnableSOFEvents();
|
||||
}
|
||||
|
||||
/** Event handler for the library USB Unhandled Control Request event. */
|
||||
void EVENT_USB_Device_UnhandledControlRequest(void)
|
||||
{
|
||||
MS_Device_ProcessControlRequest(&Disk_MS_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.
|
||||
*
|
||||
* \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 CommandSuccess;
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_BUSY);
|
||||
CommandSuccess = SCSI_DecodeSCSICommand(MSInterfaceInfo);
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
|
||||
return CommandSuccess;
|
||||
}
|
||||
|
||||
/** Event handler for the USB device Start Of Frame event. */
|
||||
void EVENT_USB_Device_StartOfFrame(void)
|
||||
{
|
||||
HID_Device_MillisecondElapsed(&Keyboard_HID_Interface);
|
||||
}
|
||||
|
||||
/** 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,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[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
|
||||
*
|
||||
* \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,
|
||||
const uint8_t ReportType, void* ReportData, uint16_t* ReportSize)
|
||||
{
|
||||
USB_KeyboardReport_Data_t* KeyboardReport = (USB_KeyboardReport_Data_t*)ReportData;
|
||||
|
||||
uint8_t JoyStatus_LCL = Joystick_GetStatus();
|
||||
uint8_t ButtonStatus_LCL = Buttons_GetStatus();
|
||||
|
||||
KeyboardReport->Modifier = HID_KEYBOARD_MODIFER_LEFTSHIFT;
|
||||
|
||||
if (JoyStatus_LCL & JOY_UP)
|
||||
KeyboardReport->KeyCode[0] = 0x04; // A
|
||||
else if (JoyStatus_LCL & JOY_DOWN)
|
||||
KeyboardReport->KeyCode[0] = 0x05; // B
|
||||
|
||||
if (JoyStatus_LCL & JOY_LEFT)
|
||||
KeyboardReport->KeyCode[0] = 0x06; // C
|
||||
else if (JoyStatus_LCL & JOY_RIGHT)
|
||||
KeyboardReport->KeyCode[0] = 0x07; // D
|
||||
|
||||
if (JoyStatus_LCL & JOY_PRESS)
|
||||
KeyboardReport->KeyCode[0] = 0x08; // E
|
||||
|
||||
if (ButtonStatus_LCL & BUTTONS_BUTTON1)
|
||||
KeyboardReport->KeyCode[0] = 0x09; // F
|
||||
|
||||
*ReportSize = sizeof(USB_KeyboardReport_Data_t);
|
||||
return false;
|
||||
}
|
||||
|
||||
/** 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] 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] 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,
|
||||
const void* ReportData, const uint16_t ReportSize)
|
||||
{
|
||||
uint8_t LEDMask = LEDS_NO_LEDS;
|
||||
uint8_t* LEDReport = (uint8_t*)ReportData;
|
||||
|
||||
if (*LEDReport & HID_KEYBOARD_LED_NUMLOCK)
|
||||
LEDMask |= LEDS_LED1;
|
||||
|
||||
if (*LEDReport & HID_KEYBOARD_LED_CAPSLOCK)
|
||||
LEDMask |= LEDS_LED3;
|
||||
|
||||
if (*LEDReport & HID_KEYBOARD_LED_SCROLLLOCK)
|
||||
LEDMask |= LEDS_LED4;
|
||||
|
||||
LEDs_SetAllLEDs(LEDMask);
|
||||
}
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user