Add missing SVN eol-style property to files where it was missing.

This commit is contained in:
Dean Camera 2011-07-15 08:46:08 +00:00
parent a36012fc4b
commit 0c2ad9eb34
105 changed files with 27742 additions and 27742 deletions

File diff suppressed because it is too large Load diff

View file

@ -1,320 +1,320 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2011.
dean [at] fourwalledcubicle [dot] com
www.lufa-lib.org
*/
/*
Copyright 2011 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 HIDReportViewer project. This file contains the main tasks of
* the project and is responsible for the initial application hardware configuration.
*/
#include "HIDReportViewer.h"
/** Processed HID report descriptor items structure, containing information on each HID report element */
static HID_ReportInfo_t HIDReportInfo;
/** LUFA HID Class driver interface configuration and state information. This structure is
* passed to all HID Class driver functions, so that multiple instances of the same class
* within a device can be differentiated from one another.
*/
USB_ClassInfo_HID_Host_t Device_HID_Interface =
{
.Config =
{
.DataINPipeNumber = 1,
.DataINPipeDoubleBank = false,
.DataOUTPipeNumber = 2,
.DataOUTPipeDoubleBank = false,
.HIDInterfaceProtocol = HID_CSCP_NonBootProtocol,
.HIDParserData = &HIDReportInfo
},
};
/** Main program entry point. This routine configures the hardware required by the application, then
* enters a loop to run the application tasks in sequence.
*/
int main(void)
{
SetupHardware();
puts_P(PSTR(ESC_FG_CYAN "HID Device Report Viewer Running.\r\n" ESC_FG_WHITE));
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
sei();
for (;;)
{
RetrieveDeviceData();
HID_Host_USBTask(&Device_HID_Interface);
USB_USBTask();
}
}
/** Task to retrieve the HID device information from an attached device, and output
* the relevant data to the serial port for analysis.
*/
void RetrieveDeviceData(void)
{
if (USB_CurrentMode != USB_MODE_Host)
return;
LEDs_SetAllLEDs(LEDMASK_USB_BUSY);
OutputReportSizes();
OutputParsedReportItems();
LEDs_SetAllLEDs(LEDMASK_USB_READY);
USB_Host_SetDeviceConfiguration(0);
}
/** Prints a summary of the device's HID report sizes from the HID parser output to the serial port
* for display to the user.
*/
void OutputReportSizes(void)
{
printf_P(PSTR("\r\n\r\nTotal Device Reports: %" PRId8 "\r\n"), HIDReportInfo.TotalDeviceReports);
for (uint8_t ReportIndex = 0; ReportIndex < HIDReportInfo.TotalDeviceReports; ReportIndex++)
{
const HID_ReportSizeInfo_t* CurrReportIDInfo = &HIDReportInfo.ReportIDSizes[ReportIndex];
uint8_t ReportSizeInBits = CurrReportIDInfo->ReportSizeBits[HID_REPORT_ITEM_In];
uint8_t ReportSizeOutBits = CurrReportIDInfo->ReportSizeBits[HID_REPORT_ITEM_Out];
uint8_t ReportSizeFeatureBits = CurrReportIDInfo->ReportSizeBits[HID_REPORT_ITEM_Feature];
/* Print out the byte sizes of each report within the device */
printf_P(PSTR(" + Report ID 0x%02" PRIX8 "\r\n"
" - Input Data: %" PRId8 " bits (%" PRId8 " bytes)\r\n"
" - Output Data: %" PRId8 " bits (%" PRId8 " bytes)\r\n"
" - Feature Data: %" PRId8 " bits (%" PRId8 " bytes)\r\n"),
CurrReportIDInfo->ReportID,
ReportSizeInBits,
((ReportSizeInBits >> 3) + ((ReportSizeInBits & 0x07) != 0)),
ReportSizeOutBits,
((ReportSizeOutBits >> 3) + ((ReportSizeOutBits & 0x07) != 0)),
ReportSizeFeatureBits,
((ReportSizeFeatureBits >> 3) + ((ReportSizeFeatureBits & 0x07) != 0)));
}
}
/** Prints a summary of the device's parsed and stored report items along with their attributes
* to the serial port for display to the user.
*/
void OutputParsedReportItems(void)
{
printf_P(PSTR("\r\nReport Items (%" PRId8 " in Table):\r\n"), HIDReportInfo.TotalReportItems);
for (uint8_t ItemIndex = 0; ItemIndex < HIDReportInfo.TotalReportItems; ItemIndex++)
{
const HID_ReportItem_t* RItem = &HIDReportInfo.ReportItems[ItemIndex];
printf_P(PSTR(" + Item %" PRId8 ":\r\n"
" - Report ID: 0x%02" PRIX8 "\r\n"
" - Data Direction: %s\r\n"
" - Item Flags: 0x%02" PRIX8 "\r\n"
" - Item Offset (Bits): 0x%02" PRIX8 "\r\n"
" - Item Size (Bits): 0x%02" PRIX8 "\r\n"
" - Usage Page: 0x%04" PRIX16 "\r\n"
" - Usage: 0x%04" PRIX16 "\r\n"
" - Unit Type: 0x%08" PRIX32 "\r\n"
" - Unit Exponent: 0x%02" PRIX8 "\r\n"
" - Logical Minimum: 0x%08" PRIX32 "\r\n"
" - Logical Maximum: 0x%08" PRIX32 "\r\n"
" - Physical Minimum: 0x%08" PRIX32 "\r\n"
" - Physical Maximum: 0x%08" PRIX32 "\r\n"
" - Collection Path:\r\n"),
ItemIndex,
RItem->ReportID,
((RItem->ItemType == HID_REPORT_ITEM_In) ? "IN" : ((RItem->ItemType == HID_REPORT_ITEM_Out) ? "OUT" : "FEATURE")),
RItem->ItemFlags,
RItem->BitOffset,
RItem->Attributes.BitSize,
RItem->Attributes.Usage.Page,
RItem->Attributes.Usage.Usage,
RItem->Attributes.Unit.Type,
RItem->Attributes.Unit.Exponent,
RItem->Attributes.Logical.Minimum,
RItem->Attributes.Logical.Maximum,
RItem->Attributes.Physical.Minimum,
RItem->Attributes.Physical.Maximum);
OutputCollectionPath(RItem->CollectionPath);
}
}
/** Prints the HID Collection path (along with each node's attributes) to the serial port
* for display to the user, from the given starting node to the root node.
*
* \param[in] CollectionPath Starting HID Collection node to print
*/
void OutputCollectionPath(const HID_CollectionPath_t* const CollectionPath)
{
const HID_CollectionPath_t* CurrentNode = CollectionPath;
while (CurrentNode != NULL)
{
printf_P(PSTR(" |\r\n"
" - Type: 0x%02" PRIX8 "\r\n"
" - Usage: 0x%02" PRIX8 "\r\n"),
CurrentNode->Type, CurrentNode->Usage);
CurrentNode = CurrentNode->Parent;
}
printf_P(PSTR(" |\r\n"
" END\r\n"));
}
/** 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 */
Serial_Init(9600, false);
LEDs_Init();
USB_Init();
/* Create a stdio stream for the serial port for stdin and stdout */
Serial_CreateStream(NULL);
}
/** Event handler for the USB_DeviceAttached event. This indicates that a device has been attached to the host, and
* starts the library USB task to begin the enumeration and USB management process.
*/
void EVENT_USB_Host_DeviceAttached(void)
{
puts_P(PSTR("Device Attached.\r\n"));
LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
}
/** Event handler for the USB_DeviceUnattached event. This indicates that a device has been removed from the host, and
* stops the library USB task management process.
*/
void EVENT_USB_Host_DeviceUnattached(void)
{
puts_P(PSTR("\r\nDevice Unattached.\r\n"));
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
}
/** Event handler for the USB_DeviceEnumerationComplete event. This indicates that a device has been successfully
* enumerated by the host and is now ready to be used by the application.
*/
void EVENT_USB_Host_DeviceEnumerationComplete(void)
{
LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
uint16_t ConfigDescriptorSize;
uint8_t ConfigDescriptorData[512];
if (USB_Host_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData,
sizeof(ConfigDescriptorData)) != HOST_GETCONFIG_Successful)
{
puts_P(PSTR("Error Retrieving Configuration Descriptor.\r\n"));
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
return;
}
if (HID_Host_ConfigurePipes(&Device_HID_Interface,
ConfigDescriptorSize, ConfigDescriptorData) != HID_ENUMERROR_NoError)
{
puts_P(PSTR("Attached Device Not a Valid HID Device.\r\n"));
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
return;
}
if (USB_Host_SetDeviceConfiguration(1) != HOST_SENDCONTROL_Successful)
{
puts_P(PSTR("Error Setting Device Configuration.\r\n"));
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
return;
}
if (HID_Host_SetReportProtocol(&Device_HID_Interface) != 0)
{
puts_P(PSTR("Error Setting Report Protocol Mode.\r\n"));
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
USB_Host_SetDeviceConfiguration(0);
return;
}
puts_P(PSTR("HID Device Enumerated.\r\n"));
LEDs_SetAllLEDs(LEDMASK_USB_READY);
}
/** Event handler for the USB_HostError event. This indicates that a hardware error occurred while in host mode. */
void EVENT_USB_Host_HostError(const uint8_t ErrorCode)
{
USB_Disable();
printf_P(PSTR(ESC_FG_RED "Host Mode Error\r\n"
" -- Error Code %d\r\n" ESC_FG_WHITE), ErrorCode);
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
for(;;);
}
/** Event handler for the USB_DeviceEnumerationFailed event. This indicates that a problem occurred while
* enumerating an attached USB device.
*/
void EVENT_USB_Host_DeviceEnumerationFailed(const uint8_t ErrorCode,
const uint8_t SubErrorCode)
{
printf_P(PSTR(ESC_FG_RED "Dev Enum Error\r\n"
" -- Error Code %d\r\n"
" -- Sub Error Code %d\r\n"
" -- In State %d\r\n" ESC_FG_WHITE), ErrorCode, SubErrorCode, USB_HostState);
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
}
/** Callback for the HID Report Parser. This function is called each time the HID report parser is about to store
* an IN, OUT or FEATURE item into the HIDReportInfo structure. To save on RAM, we are able to filter out items
* we aren't interested in (preventing us from being able to extract them later on, but saving on the RAM they would
* have occupied).
*
* \param[in] CurrentItem Pointer to the item the HID report parser is currently working with
*
* \return Boolean true if the item should be stored into the HID report structure, false if it should be discarded
*/
bool CALLBACK_HIDParser_FilterHIDReportItem(HID_ReportItem_t* const CurrentItem)
{
return true;
}
/*
LUFA Library
Copyright (C) Dean Camera, 2011.
dean [at] fourwalledcubicle [dot] com
www.lufa-lib.org
*/
/*
Copyright 2011 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 HIDReportViewer project. This file contains the main tasks of
* the project and is responsible for the initial application hardware configuration.
*/
#include "HIDReportViewer.h"
/** Processed HID report descriptor items structure, containing information on each HID report element */
static HID_ReportInfo_t HIDReportInfo;
/** LUFA HID Class driver interface configuration and state information. This structure is
* passed to all HID Class driver functions, so that multiple instances of the same class
* within a device can be differentiated from one another.
*/
USB_ClassInfo_HID_Host_t Device_HID_Interface =
{
.Config =
{
.DataINPipeNumber = 1,
.DataINPipeDoubleBank = false,
.DataOUTPipeNumber = 2,
.DataOUTPipeDoubleBank = false,
.HIDInterfaceProtocol = HID_CSCP_NonBootProtocol,
.HIDParserData = &HIDReportInfo
},
};
/** Main program entry point. This routine configures the hardware required by the application, then
* enters a loop to run the application tasks in sequence.
*/
int main(void)
{
SetupHardware();
puts_P(PSTR(ESC_FG_CYAN "HID Device Report Viewer Running.\r\n" ESC_FG_WHITE));
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
sei();
for (;;)
{
RetrieveDeviceData();
HID_Host_USBTask(&Device_HID_Interface);
USB_USBTask();
}
}
/** Task to retrieve the HID device information from an attached device, and output
* the relevant data to the serial port for analysis.
*/
void RetrieveDeviceData(void)
{
if (USB_CurrentMode != USB_MODE_Host)
return;
LEDs_SetAllLEDs(LEDMASK_USB_BUSY);
OutputReportSizes();
OutputParsedReportItems();
LEDs_SetAllLEDs(LEDMASK_USB_READY);
USB_Host_SetDeviceConfiguration(0);
}
/** Prints a summary of the device's HID report sizes from the HID parser output to the serial port
* for display to the user.
*/
void OutputReportSizes(void)
{
printf_P(PSTR("\r\n\r\nTotal Device Reports: %" PRId8 "\r\n"), HIDReportInfo.TotalDeviceReports);
for (uint8_t ReportIndex = 0; ReportIndex < HIDReportInfo.TotalDeviceReports; ReportIndex++)
{
const HID_ReportSizeInfo_t* CurrReportIDInfo = &HIDReportInfo.ReportIDSizes[ReportIndex];
uint8_t ReportSizeInBits = CurrReportIDInfo->ReportSizeBits[HID_REPORT_ITEM_In];
uint8_t ReportSizeOutBits = CurrReportIDInfo->ReportSizeBits[HID_REPORT_ITEM_Out];
uint8_t ReportSizeFeatureBits = CurrReportIDInfo->ReportSizeBits[HID_REPORT_ITEM_Feature];
/* Print out the byte sizes of each report within the device */
printf_P(PSTR(" + Report ID 0x%02" PRIX8 "\r\n"
" - Input Data: %" PRId8 " bits (%" PRId8 " bytes)\r\n"
" - Output Data: %" PRId8 " bits (%" PRId8 " bytes)\r\n"
" - Feature Data: %" PRId8 " bits (%" PRId8 " bytes)\r\n"),
CurrReportIDInfo->ReportID,
ReportSizeInBits,
((ReportSizeInBits >> 3) + ((ReportSizeInBits & 0x07) != 0)),
ReportSizeOutBits,
((ReportSizeOutBits >> 3) + ((ReportSizeOutBits & 0x07) != 0)),
ReportSizeFeatureBits,
((ReportSizeFeatureBits >> 3) + ((ReportSizeFeatureBits & 0x07) != 0)));
}
}
/** Prints a summary of the device's parsed and stored report items along with their attributes
* to the serial port for display to the user.
*/
void OutputParsedReportItems(void)
{
printf_P(PSTR("\r\nReport Items (%" PRId8 " in Table):\r\n"), HIDReportInfo.TotalReportItems);
for (uint8_t ItemIndex = 0; ItemIndex < HIDReportInfo.TotalReportItems; ItemIndex++)
{
const HID_ReportItem_t* RItem = &HIDReportInfo.ReportItems[ItemIndex];
printf_P(PSTR(" + Item %" PRId8 ":\r\n"
" - Report ID: 0x%02" PRIX8 "\r\n"
" - Data Direction: %s\r\n"
" - Item Flags: 0x%02" PRIX8 "\r\n"
" - Item Offset (Bits): 0x%02" PRIX8 "\r\n"
" - Item Size (Bits): 0x%02" PRIX8 "\r\n"
" - Usage Page: 0x%04" PRIX16 "\r\n"
" - Usage: 0x%04" PRIX16 "\r\n"
" - Unit Type: 0x%08" PRIX32 "\r\n"
" - Unit Exponent: 0x%02" PRIX8 "\r\n"
" - Logical Minimum: 0x%08" PRIX32 "\r\n"
" - Logical Maximum: 0x%08" PRIX32 "\r\n"
" - Physical Minimum: 0x%08" PRIX32 "\r\n"
" - Physical Maximum: 0x%08" PRIX32 "\r\n"
" - Collection Path:\r\n"),
ItemIndex,
RItem->ReportID,
((RItem->ItemType == HID_REPORT_ITEM_In) ? "IN" : ((RItem->ItemType == HID_REPORT_ITEM_Out) ? "OUT" : "FEATURE")),
RItem->ItemFlags,
RItem->BitOffset,
RItem->Attributes.BitSize,
RItem->Attributes.Usage.Page,
RItem->Attributes.Usage.Usage,
RItem->Attributes.Unit.Type,
RItem->Attributes.Unit.Exponent,
RItem->Attributes.Logical.Minimum,
RItem->Attributes.Logical.Maximum,
RItem->Attributes.Physical.Minimum,
RItem->Attributes.Physical.Maximum);
OutputCollectionPath(RItem->CollectionPath);
}
}
/** Prints the HID Collection path (along with each node's attributes) to the serial port
* for display to the user, from the given starting node to the root node.
*
* \param[in] CollectionPath Starting HID Collection node to print
*/
void OutputCollectionPath(const HID_CollectionPath_t* const CollectionPath)
{
const HID_CollectionPath_t* CurrentNode = CollectionPath;
while (CurrentNode != NULL)
{
printf_P(PSTR(" |\r\n"
" - Type: 0x%02" PRIX8 "\r\n"
" - Usage: 0x%02" PRIX8 "\r\n"),
CurrentNode->Type, CurrentNode->Usage);
CurrentNode = CurrentNode->Parent;
}
printf_P(PSTR(" |\r\n"
" END\r\n"));
}
/** 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 */
Serial_Init(9600, false);
LEDs_Init();
USB_Init();
/* Create a stdio stream for the serial port for stdin and stdout */
Serial_CreateStream(NULL);
}
/** Event handler for the USB_DeviceAttached event. This indicates that a device has been attached to the host, and
* starts the library USB task to begin the enumeration and USB management process.
*/
void EVENT_USB_Host_DeviceAttached(void)
{
puts_P(PSTR("Device Attached.\r\n"));
LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
}
/** Event handler for the USB_DeviceUnattached event. This indicates that a device has been removed from the host, and
* stops the library USB task management process.
*/
void EVENT_USB_Host_DeviceUnattached(void)
{
puts_P(PSTR("\r\nDevice Unattached.\r\n"));
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
}
/** Event handler for the USB_DeviceEnumerationComplete event. This indicates that a device has been successfully
* enumerated by the host and is now ready to be used by the application.
*/
void EVENT_USB_Host_DeviceEnumerationComplete(void)
{
LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
uint16_t ConfigDescriptorSize;
uint8_t ConfigDescriptorData[512];
if (USB_Host_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData,
sizeof(ConfigDescriptorData)) != HOST_GETCONFIG_Successful)
{
puts_P(PSTR("Error Retrieving Configuration Descriptor.\r\n"));
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
return;
}
if (HID_Host_ConfigurePipes(&Device_HID_Interface,
ConfigDescriptorSize, ConfigDescriptorData) != HID_ENUMERROR_NoError)
{
puts_P(PSTR("Attached Device Not a Valid HID Device.\r\n"));
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
return;
}
if (USB_Host_SetDeviceConfiguration(1) != HOST_SENDCONTROL_Successful)
{
puts_P(PSTR("Error Setting Device Configuration.\r\n"));
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
return;
}
if (HID_Host_SetReportProtocol(&Device_HID_Interface) != 0)
{
puts_P(PSTR("Error Setting Report Protocol Mode.\r\n"));
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
USB_Host_SetDeviceConfiguration(0);
return;
}
puts_P(PSTR("HID Device Enumerated.\r\n"));
LEDs_SetAllLEDs(LEDMASK_USB_READY);
}
/** Event handler for the USB_HostError event. This indicates that a hardware error occurred while in host mode. */
void EVENT_USB_Host_HostError(const uint8_t ErrorCode)
{
USB_Disable();
printf_P(PSTR(ESC_FG_RED "Host Mode Error\r\n"
" -- Error Code %d\r\n" ESC_FG_WHITE), ErrorCode);
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
for(;;);
}
/** Event handler for the USB_DeviceEnumerationFailed event. This indicates that a problem occurred while
* enumerating an attached USB device.
*/
void EVENT_USB_Host_DeviceEnumerationFailed(const uint8_t ErrorCode,
const uint8_t SubErrorCode)
{
printf_P(PSTR(ESC_FG_RED "Dev Enum Error\r\n"
" -- Error Code %d\r\n"
" -- Sub Error Code %d\r\n"
" -- In State %d\r\n" ESC_FG_WHITE), ErrorCode, SubErrorCode, USB_HostState);
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
}
/** Callback for the HID Report Parser. This function is called each time the HID report parser is about to store
* an IN, OUT or FEATURE item into the HIDReportInfo structure. To save on RAM, we are able to filter out items
* we aren't interested in (preventing us from being able to extract them later on, but saving on the RAM they would
* have occupied).
*
* \param[in] CurrentItem Pointer to the item the HID report parser is currently working with
*
* \return Boolean true if the item should be stored into the HID report structure, false if it should be discarded
*/
bool CALLBACK_HIDParser_FilterHIDReportItem(HID_ReportItem_t* const CurrentItem)
{
return true;
}

View file

@ -1,87 +1,87 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2011.
dean [at] fourwalledcubicle [dot] com
www.lufa-lib.org
*/
/*
Copyright 2011 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 HIDReportViewer.c.
*/
#ifndef _HID_REPORT_VIEWER_H_
#define _HID_REPORT_VIEWER_H_
/* Includes: */
#include <avr/io.h>
#include <avr/wdt.h>
#include <avr/pgmspace.h>
#include <avr/power.h>
#include <avr/interrupt.h>
#include <stdio.h>
#include <inttypes.h>
#include <LUFA/Version.h>
#include <LUFA/Drivers/Misc/TerminalCodes.h>
#include <LUFA/Drivers/Peripheral/Serial.h>
#include <LUFA/Drivers/Board/LEDs.h>
#include <LUFA/Drivers/USB/USB.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_LED1 | LEDS_LED3 | LEDS_LED4)
/* Function Prototypes: */
void SetupHardware(void);
void RetrieveDeviceData(void);
void OutputReportSizes(void);
void OutputParsedReportItems(void);
void OutputCollectionPath(const HID_CollectionPath_t* const CollectionPath);
void EVENT_USB_Host_HostError(const uint8_t ErrorCode);
void EVENT_USB_Host_DeviceAttached(void);
void EVENT_USB_Host_DeviceUnattached(void);
void EVENT_USB_Host_DeviceEnumerationFailed(const uint8_t ErrorCode,
const uint8_t SubErrorCode);
void EVENT_USB_Host_DeviceEnumerationComplete(void);
bool CALLBACK_HIDParser_FilterHIDReportItem(HID_ReportItem_t* const CurrentItem);
#endif
/*
LUFA Library
Copyright (C) Dean Camera, 2011.
dean [at] fourwalledcubicle [dot] com
www.lufa-lib.org
*/
/*
Copyright 2011 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 HIDReportViewer.c.
*/
#ifndef _HID_REPORT_VIEWER_H_
#define _HID_REPORT_VIEWER_H_
/* Includes: */
#include <avr/io.h>
#include <avr/wdt.h>
#include <avr/pgmspace.h>
#include <avr/power.h>
#include <avr/interrupt.h>
#include <stdio.h>
#include <inttypes.h>
#include <LUFA/Version.h>
#include <LUFA/Drivers/Misc/TerminalCodes.h>
#include <LUFA/Drivers/Peripheral/Serial.h>
#include <LUFA/Drivers/Board/LEDs.h>
#include <LUFA/Drivers/USB/USB.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_LED1 | LEDS_LED3 | LEDS_LED4)
/* Function Prototypes: */
void SetupHardware(void);
void RetrieveDeviceData(void);
void OutputReportSizes(void);
void OutputParsedReportItems(void);
void OutputCollectionPath(const HID_CollectionPath_t* const CollectionPath);
void EVENT_USB_Host_HostError(const uint8_t ErrorCode);
void EVENT_USB_Host_DeviceAttached(void);
void EVENT_USB_Host_DeviceUnattached(void);
void EVENT_USB_Host_DeviceEnumerationFailed(const uint8_t ErrorCode,
const uint8_t SubErrorCode);
void EVENT_USB_Host_DeviceEnumerationComplete(void);
bool CALLBACK_HIDParser_FilterHIDReportItem(HID_ReportItem_t* const CurrentItem);
#endif

View file

@ -1,64 +1,64 @@
/** \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 HID Device Report Viewer Programmer Project
*
* \section Sec_Compat Project Compatibility:
*
* The following list indicates what microcontrollers are compatible with this project.
*
* - Series 7 USB AVRs (AT90USBxxx7)
*
* \section Sec_Info USB Information:
*
* The following table gives a rundown of the USB utilization of this project.
*
* <table>
* <tr>
* <td><b>USB Mode:</b></td>
* <td>Host</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 Sec_Description Project Description:
*
* Firmware for a HID Report viewer. This project is designed to aid in the debugging of USB HID Hosts, where the contents of an
* unknown HID device's HID Report need to be examined. Once a HID device has been plugged into this application, the HID report
* descriptor will be parsed using the internal LUFA HID report parser, and the results dumped to the serial port in a human
* readable format. This output will contain information on the sizes of the reports within the device's HID interface, as well as
* information on each report element (size, usage, minimum/maximum values, etc.).
*
* \section Sec_Options Project Options
*
* The following defines can be found in this project, which can control the project 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 HID Device Report Viewer Programmer Project
*
* \section Sec_Compat Project Compatibility:
*
* The following list indicates what microcontrollers are compatible with this project.
*
* - Series 7 USB AVRs (AT90USBxxx7)
*
* \section Sec_Info USB Information:
*
* The following table gives a rundown of the USB utilization of this project.
*
* <table>
* <tr>
* <td><b>USB Mode:</b></td>
* <td>Host</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 Sec_Description Project Description:
*
* Firmware for a HID Report viewer. This project is designed to aid in the debugging of USB HID Hosts, where the contents of an
* unknown HID device's HID Report need to be examined. Once a HID device has been plugged into this application, the HID report
* descriptor will be parsed using the internal LUFA HID report parser, and the results dumped to the serial port in a human
* readable format. This output will contain information on the sizes of the reports within the device's HID interface, as well as
* information on each report element (size, usage, minimum/maximum values, etc.).
*
* \section Sec_Options Project Options
*
* The following defines can be found in this project, which can control the project behaviour when defined, or changed in value.
*
* <table>
* <tr>
* <td>
* None
* </td>
* </tr>
* </table>
*/

File diff suppressed because it is too large Load diff

View file

@ -1,329 +1,329 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2011.
dean [at] fourwalledcubicle [dot] com
www.lufa-lib.org
*/
/*
Copyright 2011 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.
*/
const USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
{
.Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device},
.USBSpecification = VERSION_BCD(01.10),
.Class = USB_CSCP_NoDeviceClass,
.SubClass = USB_CSCP_NoDeviceSubclass,
.Protocol = USB_CSCP_NoDeviceProtocol,
.Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE,
.VendorID = 0x03EB,
.ProductID = 0x2048,
.ReleaseNumber = VERSION_BCD(00.01),
.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.
*/
const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
{
.Config =
{
.Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration},
.TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t),
.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 = AUDIO_CSCP_AudioClass,
.SubClass = AUDIO_CSCP_ControlSubclass,
.Protocol = AUDIO_CSCP_ControlProtocol,
.InterfaceStrIndex = NO_DESCRIPTOR
},
.Audio_ControlInterface_SPC =
{
.Header = {.Size = sizeof(USB_Audio_Descriptor_Interface_AC_t), .Type = DTYPE_CSInterface},
.Subtype = AUDIO_DSUBTYPE_CSInterface_Header,
.ACSpecification = VERSION_BCD(01.00),
.TotalLength = sizeof(USB_Audio_Descriptor_Interface_AC_t),
.InCollection = 1,
.InterfaceNumber = 1,
},
.Audio_StreamInterface =
{
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
.InterfaceNumber = 1,
.AlternateSetting = 0,
.TotalEndpoints = 2,
.Class = AUDIO_CSCP_AudioClass,
.SubClass = AUDIO_CSCP_MIDIStreamingSubclass,
.Protocol = AUDIO_CSCP_StreamingProtocol,
.InterfaceStrIndex = NO_DESCRIPTOR
},
.Audio_StreamInterface_SPC =
{
.Header = {.Size = sizeof(USB_MIDI_Descriptor_AudioInterface_AS_t), .Type = DTYPE_CSInterface},
.Subtype = AUDIO_DSUBTYPE_CSInterface_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_Descriptor_InputJack_t), .Type = DTYPE_CSInterface},
.Subtype = AUDIO_DSUBTYPE_CSInterface_InputTerminal,
.JackType = MIDI_JACKTYPE_Embedded,
.JackID = 0x01,
.JackStrIndex = NO_DESCRIPTOR
},
.MIDI_In_Jack_Ext =
{
.Header = {.Size = sizeof(USB_MIDI_Descriptor_InputJack_t), .Type = DTYPE_CSInterface},
.Subtype = AUDIO_DSUBTYPE_CSInterface_InputTerminal,
.JackType = MIDI_JACKTYPE_External,
.JackID = 0x02,
.JackStrIndex = NO_DESCRIPTOR
},
.MIDI_Out_Jack_Emb =
{
.Header = {.Size = sizeof(USB_MIDI_Descriptor_OutputJack_t), .Type = DTYPE_CSInterface},
.Subtype = AUDIO_DSUBTYPE_CSInterface_OutputTerminal,
.JackType = MIDI_JACKTYPE_Embedded,
.JackID = 0x03,
.NumberOfPins = 1,
.SourceJackID = {0x02},
.SourcePinID = {0x01},
.JackStrIndex = NO_DESCRIPTOR
},
.MIDI_Out_Jack_Ext =
{
.Header = {.Size = sizeof(USB_MIDI_Descriptor_OutputJack_t), .Type = DTYPE_CSInterface},
.Subtype = AUDIO_DSUBTYPE_CSInterface_OutputTerminal,
.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_Descriptor_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 = 0x01
},
.Refresh = 0,
.SyncEndpointNumber = 0
},
.MIDI_In_Jack_Endpoint_SPC =
{
.Header = {.Size = sizeof(USB_MIDI_Descriptor_Jack_Endpoint_t), .Type = DTYPE_CSEndpoint},
.Subtype = AUDIO_DSUBTYPE_CSEndpoint_General,
.TotalEmbeddedJacks = 0x01,
.AssociatedJackID = {0x01}
},
.MIDI_Out_Jack_Endpoint =
{
.Endpoint =
{
.Header = {.Size = sizeof(USB_Audio_Descriptor_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 = 0x01
},
.Refresh = 0,
.SyncEndpointNumber = 0
},
.MIDI_Out_Jack_Endpoint_SPC =
{
.Header = {.Size = sizeof(USB_MIDI_Descriptor_Jack_Endpoint_t), .Type = DTYPE_CSEndpoint},
.Subtype = AUDIO_DSUBTYPE_CSEndpoint_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.
*/
const 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.
*/
const 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.
*/
const 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,
const void** const DescriptorAddress)
{
const uint8_t DescriptorType = (wValue >> 8);
const uint8_t DescriptorNumber = (wValue & 0xFF);
const 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:
switch (DescriptorNumber)
{
case 0x00:
Address = &LanguageString;
Size = pgm_read_byte(&LanguageString.Header.Size);
break;
case 0x01:
Address = &ManufacturerString;
Size = pgm_read_byte(&ManufacturerString.Header.Size);
break;
case 0x02:
Address = &ProductString;
Size = pgm_read_byte(&ProductString.Header.Size);
break;
}
break;
}
*DescriptorAddress = Address;
return Size;
}
/*
LUFA Library
Copyright (C) Dean Camera, 2011.
dean [at] fourwalledcubicle [dot] com
www.lufa-lib.org
*/
/*
Copyright 2011 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.
*/
const USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
{
.Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device},
.USBSpecification = VERSION_BCD(01.10),
.Class = USB_CSCP_NoDeviceClass,
.SubClass = USB_CSCP_NoDeviceSubclass,
.Protocol = USB_CSCP_NoDeviceProtocol,
.Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE,
.VendorID = 0x03EB,
.ProductID = 0x2048,
.ReleaseNumber = VERSION_BCD(00.01),
.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.
*/
const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
{
.Config =
{
.Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration},
.TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t),
.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 = AUDIO_CSCP_AudioClass,
.SubClass = AUDIO_CSCP_ControlSubclass,
.Protocol = AUDIO_CSCP_ControlProtocol,
.InterfaceStrIndex = NO_DESCRIPTOR
},
.Audio_ControlInterface_SPC =
{
.Header = {.Size = sizeof(USB_Audio_Descriptor_Interface_AC_t), .Type = DTYPE_CSInterface},
.Subtype = AUDIO_DSUBTYPE_CSInterface_Header,
.ACSpecification = VERSION_BCD(01.00),
.TotalLength = sizeof(USB_Audio_Descriptor_Interface_AC_t),
.InCollection = 1,
.InterfaceNumber = 1,
},
.Audio_StreamInterface =
{
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
.InterfaceNumber = 1,
.AlternateSetting = 0,
.TotalEndpoints = 2,
.Class = AUDIO_CSCP_AudioClass,
.SubClass = AUDIO_CSCP_MIDIStreamingSubclass,
.Protocol = AUDIO_CSCP_StreamingProtocol,
.InterfaceStrIndex = NO_DESCRIPTOR
},
.Audio_StreamInterface_SPC =
{
.Header = {.Size = sizeof(USB_MIDI_Descriptor_AudioInterface_AS_t), .Type = DTYPE_CSInterface},
.Subtype = AUDIO_DSUBTYPE_CSInterface_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_Descriptor_InputJack_t), .Type = DTYPE_CSInterface},
.Subtype = AUDIO_DSUBTYPE_CSInterface_InputTerminal,
.JackType = MIDI_JACKTYPE_Embedded,
.JackID = 0x01,
.JackStrIndex = NO_DESCRIPTOR
},
.MIDI_In_Jack_Ext =
{
.Header = {.Size = sizeof(USB_MIDI_Descriptor_InputJack_t), .Type = DTYPE_CSInterface},
.Subtype = AUDIO_DSUBTYPE_CSInterface_InputTerminal,
.JackType = MIDI_JACKTYPE_External,
.JackID = 0x02,
.JackStrIndex = NO_DESCRIPTOR
},
.MIDI_Out_Jack_Emb =
{
.Header = {.Size = sizeof(USB_MIDI_Descriptor_OutputJack_t), .Type = DTYPE_CSInterface},
.Subtype = AUDIO_DSUBTYPE_CSInterface_OutputTerminal,
.JackType = MIDI_JACKTYPE_Embedded,
.JackID = 0x03,
.NumberOfPins = 1,
.SourceJackID = {0x02},
.SourcePinID = {0x01},
.JackStrIndex = NO_DESCRIPTOR
},
.MIDI_Out_Jack_Ext =
{
.Header = {.Size = sizeof(USB_MIDI_Descriptor_OutputJack_t), .Type = DTYPE_CSInterface},
.Subtype = AUDIO_DSUBTYPE_CSInterface_OutputTerminal,
.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_Descriptor_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 = 0x01
},
.Refresh = 0,
.SyncEndpointNumber = 0
},
.MIDI_In_Jack_Endpoint_SPC =
{
.Header = {.Size = sizeof(USB_MIDI_Descriptor_Jack_Endpoint_t), .Type = DTYPE_CSEndpoint},
.Subtype = AUDIO_DSUBTYPE_CSEndpoint_General,
.TotalEmbeddedJacks = 0x01,
.AssociatedJackID = {0x01}
},
.MIDI_Out_Jack_Endpoint =
{
.Endpoint =
{
.Header = {.Size = sizeof(USB_Audio_Descriptor_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 = 0x01
},
.Refresh = 0,
.SyncEndpointNumber = 0
},
.MIDI_Out_Jack_Endpoint_SPC =
{
.Header = {.Size = sizeof(USB_MIDI_Descriptor_Jack_Endpoint_t), .Type = DTYPE_CSEndpoint},
.Subtype = AUDIO_DSUBTYPE_CSEndpoint_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.
*/
const 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.
*/
const 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.
*/
const 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,
const void** const DescriptorAddress)
{
const uint8_t DescriptorType = (wValue >> 8);
const uint8_t DescriptorNumber = (wValue & 0xFF);
const 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:
switch (DescriptorNumber)
{
case 0x00:
Address = &LanguageString;
Size = pgm_read_byte(&LanguageString.Header.Size);
break;
case 0x01:
Address = &ManufacturerString;
Size = pgm_read_byte(&ManufacturerString.Header.Size);
break;
case 0x02:
Address = &ProductString;
Size = pgm_read_byte(&ProductString.Header.Size);
break;
}
break;
}
*DescriptorAddress = Address;
return Size;
}

View file

@ -1,87 +1,87 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2011.
dean [at] fourwalledcubicle [dot] com
www.lufa-lib.org
*/
/*
Copyright 2011 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 <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;
// MIDI Audio Control Interface
USB_Descriptor_Interface_t Audio_ControlInterface;
USB_Audio_Descriptor_Interface_AC_t Audio_ControlInterface_SPC;
// MIDI Audio Streaming Interface
USB_Descriptor_Interface_t Audio_StreamInterface;
USB_MIDI_Descriptor_AudioInterface_AS_t Audio_StreamInterface_SPC;
USB_MIDI_Descriptor_InputJack_t MIDI_In_Jack_Emb;
USB_MIDI_Descriptor_InputJack_t MIDI_In_Jack_Ext;
USB_MIDI_Descriptor_OutputJack_t MIDI_Out_Jack_Emb;
USB_MIDI_Descriptor_OutputJack_t MIDI_Out_Jack_Ext;
USB_Audio_Descriptor_StreamEndpoint_Std_t MIDI_In_Jack_Endpoint;
USB_MIDI_Descriptor_Jack_Endpoint_t MIDI_In_Jack_Endpoint_SPC;
USB_Audio_Descriptor_StreamEndpoint_Std_t MIDI_Out_Jack_Endpoint;
USB_MIDI_Descriptor_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,
const void** const DescriptorAddress)
ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3);
#endif
/*
LUFA Library
Copyright (C) Dean Camera, 2011.
dean [at] fourwalledcubicle [dot] com
www.lufa-lib.org
*/
/*
Copyright 2011 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 <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;
// MIDI Audio Control Interface
USB_Descriptor_Interface_t Audio_ControlInterface;
USB_Audio_Descriptor_Interface_AC_t Audio_ControlInterface_SPC;
// MIDI Audio Streaming Interface
USB_Descriptor_Interface_t Audio_StreamInterface;
USB_MIDI_Descriptor_AudioInterface_AS_t Audio_StreamInterface_SPC;
USB_MIDI_Descriptor_InputJack_t MIDI_In_Jack_Emb;
USB_MIDI_Descriptor_InputJack_t MIDI_In_Jack_Ext;
USB_MIDI_Descriptor_OutputJack_t MIDI_Out_Jack_Emb;
USB_MIDI_Descriptor_OutputJack_t MIDI_Out_Jack_Ext;
USB_Audio_Descriptor_StreamEndpoint_Std_t MIDI_In_Jack_Endpoint;
USB_MIDI_Descriptor_Jack_Endpoint_t MIDI_In_Jack_Endpoint_SPC;
USB_Audio_Descriptor_StreamEndpoint_Std_t MIDI_Out_Jack_Endpoint;
USB_MIDI_Descriptor_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,
const void** const DescriptorAddress)
ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3);
#endif

File diff suppressed because it is too large Load diff

View file

@ -1,245 +1,245 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2011.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2011 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 "MIDIToneGenerator.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,
},
};
/** 8-bit 256 entry Sine Wave lookup table */
static const uint8_t SineTable[256] =
{
128, 131, 134, 137, 140, 143, 146, 149, 152, 156, 159, 162, 165, 168, 171, 174,
176, 179, 182, 185, 188, 191, 193, 196, 199, 201, 204, 206, 209, 211, 213, 216,
218, 220, 222, 224, 226, 228, 230, 232, 234, 236, 237, 239, 240, 242, 243, 245,
246, 247, 248, 249, 250, 251, 252, 252, 253, 254, 254, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 254, 254, 253, 252, 252, 251, 250, 249, 248, 247,
246, 245, 243, 242, 240, 239, 237, 236, 234, 232, 230, 228, 226, 224, 222, 220,
218, 216, 213, 211, 209, 206, 204, 201, 199, 196, 193, 191, 188, 185, 182, 179,
176, 174, 171, 168, 165, 162, 159, 156, 152, 149, 146, 143, 140, 137, 134, 131,
128, 124, 121, 118, 115, 112, 109, 106, 103, 99, 96, 93, 90, 87, 84, 81,
79, 76, 73, 70, 67, 64, 62, 59, 56, 54, 51, 49, 46, 44, 42, 39,
37, 35, 33, 31, 29, 27, 25, 23, 21, 19, 18, 16, 15, 13, 12, 10,
9, 8, 7, 6, 5, 4, 3, 3, 2, 1, 1, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 1, 1, 2, 3, 3, 4, 5, 6, 7, 8,
9, 10, 12, 13, 15, 16, 18, 19, 21, 23, 25, 27, 29, 31, 33, 35,
37, 39, 42, 44, 46, 49, 51, 54, 56, 59, 62, 64, 67, 70, 73, 76,
79, 81, 84, 87, 90, 93, 96, 99, 103, 106, 109, 112, 115, 118, 121, 124,
};
/** Array of structures describing each note being generated */
static DDSNoteData NoteData[MAX_SIMULTANEOUS_NOTES];
/** 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 (;;)
{
MIDI_EventPacket_t ReceivedMIDIEvent;
if (MIDI_Device_ReceiveEventPacket(&Keyboard_MIDI_Interface, &ReceivedMIDIEvent))
{
if ((ReceivedMIDIEvent.Command == (MIDI_COMMAND_NOTE_ON >> 4)) && ((ReceivedMIDIEvent.Data1 & 0x0F) == 0))
{
DDSNoteData* LRUNoteStruct = &NoteData[0];
/* Find a free entry in the note table to use for the note being turned on */
for (uint8_t i = 0; i < MAX_SIMULTANEOUS_NOTES; i++)
{
/* Check if the note is unused */
if (!(NoteData[i].Pitch))
{
/* If a note is unused, it's age is essentially infinite - always prefer unused not entries */
LRUNoteStruct = &NoteData[i];
break;
}
else if (NoteData[i].LRUAge >= LRUNoteStruct->LRUAge)
{
/* If an older entry that the current entry has been found, prefer overwriting that one */
LRUNoteStruct = &NoteData[i];
}
NoteData[i].LRUAge++;
}
/* Update the oldest note entry with the new note data and reset its age */
LRUNoteStruct->Pitch = ReceivedMIDIEvent.Data2;
LRUNoteStruct->TableIncrement = (uint32_t)(BASE_INCREMENT * SCALE_FACTOR) +
((uint32_t)(BASE_INCREMENT * NOTE_OCTIVE_RATIO * SCALE_FACTOR) *
(ReceivedMIDIEvent.Data2 - BASE_PITCH_INDEX));
LRUNoteStruct->TablePosition = 0;
LRUNoteStruct->LRUAge = 0;
/* Turn on indicator LED to indicate note generation activity */
LEDs_SetAllLEDs(LEDS_LED1);
}
else if ((ReceivedMIDIEvent.Command == (MIDI_COMMAND_NOTE_OFF >> 4)) && ((ReceivedMIDIEvent.Data1 & 0x0F) == 0))
{
bool FoundActiveNote = false;
/* Find the note in the note table to turn off */
for (uint8_t i = 0; i < MAX_SIMULTANEOUS_NOTES; i++)
{
if (NoteData[i].Pitch == ReceivedMIDIEvent.Data2)
NoteData[i].Pitch = 0;
else if (NoteData[i].Pitch)
FoundActiveNote = true;
}
/* If all notes off, turn off the indicator LED */
if (!(FoundActiveNote))
LEDs_SetAllLEDs(LEDS_NO_LEDS);
}
}
MIDI_Device_USBTask(&Keyboard_MIDI_Interface);
USB_USBTask();
}
}
/** ISR to handle the reloading of the PWM timer with the next sample. */
ISR(TIMER0_COMPA_vect, ISR_BLOCK)
{
uint16_t MixedSample = 0;
/* Sum together all the active notes to form a single sample */
for (uint8_t i = 0; i < MAX_SIMULTANEOUS_NOTES; i++)
{
/* A non-zero pitch indicates the note is active */
if (NoteData[i].Pitch)
{
/* Use the top 8 bits of the table position as the sample table index */
uint8_t TableIndex = (NoteData[i].TablePosition >> 24);
/* Add the new tone sample to the accumulator and increment the table position */
MixedSample += SineTable[TableIndex];
NoteData[i].TablePosition += NoteData[i].TableIncrement;
}
}
/* Output clamped mixed sample value to the PWM */
OCR3A = (MixedSample <= 0xFF) ? MixedSample : 0xFF;
}
/** 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();
/* Sample reload timer initialization */
TIMSK0 = (1 << OCIE0A);
OCR0A = (VIRTUAL_SAMPLE_TABLE_SIZE / 8);
TCCR0A = (1 << WGM01); // CTC mode
TCCR0B = (1 << CS01); // Fcpu/8 speed
/* Set speaker as output */
DDRC |= (1 << 6);
/* PWM speaker timer initialization */
TCCR3A = ((1 << WGM31) | (1 << COM3A1) | (1 << COM3A0)); // Set on match, clear on TOP
TCCR3B = ((1 << WGM32) | (1 << CS30)); // Fast 8-Bit PWM, Fcpu speed
}
/** Event handler for the library USB Connection event. */
void EVENT_USB_Device_Connect(void)
{
LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
/* Set speaker as output */
DDRC |= (1 << 6);
}
/** Event handler for the library USB Disconnection event. */
void EVENT_USB_Device_Disconnect(void)
{
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
/* Disable any notes currently being played */
for (uint8_t i = 0; i < MAX_SIMULTANEOUS_NOTES; i++)
NoteData[i].Pitch = 0;
/* Set speaker as input to reduce current draw */
DDRC &= ~(1 << 6);
}
/** Event handler for the library USB Configuration Changed event. */
void EVENT_USB_Device_ConfigurationChanged(void)
{
bool ConfigSuccess = true;
ConfigSuccess &= MIDI_Device_ConfigureEndpoints(&Keyboard_MIDI_Interface);
LEDs_SetAllLEDs(ConfigSuccess ? LEDMASK_USB_READY : LEDMASK_USB_ERROR);
}
/** Event handler for the library USB Control Request event. */
void EVENT_USB_Device_ControlRequest(void)
{
MIDI_Device_ProcessControlRequest(&Keyboard_MIDI_Interface);
}
/*
LUFA Library
Copyright (C) Dean Camera, 2011.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2011 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 "MIDIToneGenerator.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,
},
};
/** 8-bit 256 entry Sine Wave lookup table */
static const uint8_t SineTable[256] =
{
128, 131, 134, 137, 140, 143, 146, 149, 152, 156, 159, 162, 165, 168, 171, 174,
176, 179, 182, 185, 188, 191, 193, 196, 199, 201, 204, 206, 209, 211, 213, 216,
218, 220, 222, 224, 226, 228, 230, 232, 234, 236, 237, 239, 240, 242, 243, 245,
246, 247, 248, 249, 250, 251, 252, 252, 253, 254, 254, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 254, 254, 253, 252, 252, 251, 250, 249, 248, 247,
246, 245, 243, 242, 240, 239, 237, 236, 234, 232, 230, 228, 226, 224, 222, 220,
218, 216, 213, 211, 209, 206, 204, 201, 199, 196, 193, 191, 188, 185, 182, 179,
176, 174, 171, 168, 165, 162, 159, 156, 152, 149, 146, 143, 140, 137, 134, 131,
128, 124, 121, 118, 115, 112, 109, 106, 103, 99, 96, 93, 90, 87, 84, 81,
79, 76, 73, 70, 67, 64, 62, 59, 56, 54, 51, 49, 46, 44, 42, 39,
37, 35, 33, 31, 29, 27, 25, 23, 21, 19, 18, 16, 15, 13, 12, 10,
9, 8, 7, 6, 5, 4, 3, 3, 2, 1, 1, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 1, 1, 2, 3, 3, 4, 5, 6, 7, 8,
9, 10, 12, 13, 15, 16, 18, 19, 21, 23, 25, 27, 29, 31, 33, 35,
37, 39, 42, 44, 46, 49, 51, 54, 56, 59, 62, 64, 67, 70, 73, 76,
79, 81, 84, 87, 90, 93, 96, 99, 103, 106, 109, 112, 115, 118, 121, 124,
};
/** Array of structures describing each note being generated */
static DDSNoteData NoteData[MAX_SIMULTANEOUS_NOTES];
/** 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 (;;)
{
MIDI_EventPacket_t ReceivedMIDIEvent;
if (MIDI_Device_ReceiveEventPacket(&Keyboard_MIDI_Interface, &ReceivedMIDIEvent))
{
if ((ReceivedMIDIEvent.Command == (MIDI_COMMAND_NOTE_ON >> 4)) && ((ReceivedMIDIEvent.Data1 & 0x0F) == 0))
{
DDSNoteData* LRUNoteStruct = &NoteData[0];
/* Find a free entry in the note table to use for the note being turned on */
for (uint8_t i = 0; i < MAX_SIMULTANEOUS_NOTES; i++)
{
/* Check if the note is unused */
if (!(NoteData[i].Pitch))
{
/* If a note is unused, it's age is essentially infinite - always prefer unused not entries */
LRUNoteStruct = &NoteData[i];
break;
}
else if (NoteData[i].LRUAge >= LRUNoteStruct->LRUAge)
{
/* If an older entry that the current entry has been found, prefer overwriting that one */
LRUNoteStruct = &NoteData[i];
}
NoteData[i].LRUAge++;
}
/* Update the oldest note entry with the new note data and reset its age */
LRUNoteStruct->Pitch = ReceivedMIDIEvent.Data2;
LRUNoteStruct->TableIncrement = (uint32_t)(BASE_INCREMENT * SCALE_FACTOR) +
((uint32_t)(BASE_INCREMENT * NOTE_OCTIVE_RATIO * SCALE_FACTOR) *
(ReceivedMIDIEvent.Data2 - BASE_PITCH_INDEX));
LRUNoteStruct->TablePosition = 0;
LRUNoteStruct->LRUAge = 0;
/* Turn on indicator LED to indicate note generation activity */
LEDs_SetAllLEDs(LEDS_LED1);
}
else if ((ReceivedMIDIEvent.Command == (MIDI_COMMAND_NOTE_OFF >> 4)) && ((ReceivedMIDIEvent.Data1 & 0x0F) == 0))
{
bool FoundActiveNote = false;
/* Find the note in the note table to turn off */
for (uint8_t i = 0; i < MAX_SIMULTANEOUS_NOTES; i++)
{
if (NoteData[i].Pitch == ReceivedMIDIEvent.Data2)
NoteData[i].Pitch = 0;
else if (NoteData[i].Pitch)
FoundActiveNote = true;
}
/* If all notes off, turn off the indicator LED */
if (!(FoundActiveNote))
LEDs_SetAllLEDs(LEDS_NO_LEDS);
}
}
MIDI_Device_USBTask(&Keyboard_MIDI_Interface);
USB_USBTask();
}
}
/** ISR to handle the reloading of the PWM timer with the next sample. */
ISR(TIMER0_COMPA_vect, ISR_BLOCK)
{
uint16_t MixedSample = 0;
/* Sum together all the active notes to form a single sample */
for (uint8_t i = 0; i < MAX_SIMULTANEOUS_NOTES; i++)
{
/* A non-zero pitch indicates the note is active */
if (NoteData[i].Pitch)
{
/* Use the top 8 bits of the table position as the sample table index */
uint8_t TableIndex = (NoteData[i].TablePosition >> 24);
/* Add the new tone sample to the accumulator and increment the table position */
MixedSample += SineTable[TableIndex];
NoteData[i].TablePosition += NoteData[i].TableIncrement;
}
}
/* Output clamped mixed sample value to the PWM */
OCR3A = (MixedSample <= 0xFF) ? MixedSample : 0xFF;
}
/** 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();
/* Sample reload timer initialization */
TIMSK0 = (1 << OCIE0A);
OCR0A = (VIRTUAL_SAMPLE_TABLE_SIZE / 8);
TCCR0A = (1 << WGM01); // CTC mode
TCCR0B = (1 << CS01); // Fcpu/8 speed
/* Set speaker as output */
DDRC |= (1 << 6);
/* PWM speaker timer initialization */
TCCR3A = ((1 << WGM31) | (1 << COM3A1) | (1 << COM3A0)); // Set on match, clear on TOP
TCCR3B = ((1 << WGM32) | (1 << CS30)); // Fast 8-Bit PWM, Fcpu speed
}
/** Event handler for the library USB Connection event. */
void EVENT_USB_Device_Connect(void)
{
LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
/* Set speaker as output */
DDRC |= (1 << 6);
}
/** Event handler for the library USB Disconnection event. */
void EVENT_USB_Device_Disconnect(void)
{
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
/* Disable any notes currently being played */
for (uint8_t i = 0; i < MAX_SIMULTANEOUS_NOTES; i++)
NoteData[i].Pitch = 0;
/* Set speaker as input to reduce current draw */
DDRC &= ~(1 << 6);
}
/** Event handler for the library USB Configuration Changed event. */
void EVENT_USB_Device_ConfigurationChanged(void)
{
bool ConfigSuccess = true;
ConfigSuccess &= MIDI_Device_ConfigureEndpoints(&Keyboard_MIDI_Interface);
LEDs_SetAllLEDs(ConfigSuccess ? LEDMASK_USB_READY : LEDMASK_USB_ERROR);
}
/** Event handler for the library USB Control Request event. */
void EVENT_USB_Device_ControlRequest(void)
{
MIDI_Device_ProcessControlRequest(&Keyboard_MIDI_Interface);
}

View file

@ -1,108 +1,108 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2011.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2011 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/pgmspace.h>
#include <avr/interrupt.h>
#include <stdbool.h>
#include "Descriptors.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/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)
/** Scale factor used to convert the floating point frequencies and ratios into a fixed point number */
#define SCALE_FACTOR 65536
/** Base (lowest) allowable MIDI note frequency */
#define BASE_FREQUENCY 27.5
/** Ratio between each note in an octave */
#define NOTE_OCTIVE_RATIO 1.05946
/** Lowest valid MIDI pitch index */
#define BASE_PITCH_INDEX 21
/** Maximum number of MIDI notes that can be played simultaneously */
#define MAX_SIMULTANEOUS_NOTES 3
/** Number of samples in the virtual sample table (can be expanded to lower maximum frequency, but allow for
* more simultaneous notes due to the reduced amount of processing time needed when the samples are spaced out)
*/
#define VIRTUAL_SAMPLE_TABLE_SIZE 512
/** Sample table increments per period for the base MIDI note frequency */
#define BASE_INCREMENT (((F_CPU / VIRTUAL_SAMPLE_TABLE_SIZE / 2) / BASE_FREQUENCY))
/* Type Defines: */
typedef struct
{
uint8_t LRUAge;
uint8_t Pitch;
uint32_t TableIncrement;
uint32_t TablePosition;
} DDSNoteData;
/* 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);
#endif
/*
LUFA Library
Copyright (C) Dean Camera, 2011.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2011 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/pgmspace.h>
#include <avr/interrupt.h>
#include <stdbool.h>
#include "Descriptors.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/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)
/** Scale factor used to convert the floating point frequencies and ratios into a fixed point number */
#define SCALE_FACTOR 65536
/** Base (lowest) allowable MIDI note frequency */
#define BASE_FREQUENCY 27.5
/** Ratio between each note in an octave */
#define NOTE_OCTIVE_RATIO 1.05946
/** Lowest valid MIDI pitch index */
#define BASE_PITCH_INDEX 21
/** Maximum number of MIDI notes that can be played simultaneously */
#define MAX_SIMULTANEOUS_NOTES 3
/** Number of samples in the virtual sample table (can be expanded to lower maximum frequency, but allow for
* more simultaneous notes due to the reduced amount of processing time needed when the samples are spaced out)
*/
#define VIRTUAL_SAMPLE_TABLE_SIZE 512
/** Sample table increments per period for the base MIDI note frequency */
#define BASE_INCREMENT (((F_CPU / VIRTUAL_SAMPLE_TABLE_SIZE / 2) / BASE_FREQUENCY))
/* Type Defines: */
typedef struct
{
uint8_t LRUAge;
uint8_t Pitch;
uint32_t TableIncrement;
uint32_t TablePosition;
} DDSNoteData;
/* 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);
#endif

View file

@ -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 MIDI Tone Generator Project
*
* \section Sec_Compat Project Compatibility:
*
* The following list indicates what microcontrollers are compatible with this project.
*
* - Series 7 USB AVRs (AT90USBxxx7)
* - Series 6 USB AVRs (AT90USBxxx6)
* - Series 4 USB AVRs (ATMEGAxxU4)
*
* \section Sec_Info USB Information:
*
* The following table gives a rundown of the USB utilization of this project.
*
* <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 Sec_Description Project Description:
*
* MIDI note synthesiser project. This project implements a basic DDS frequency synthesiser, capable of producing 8-bit PWM sine
* waves of variable frequency. When attached to a USB host, this project will allow for multiple MIDI notes to be synthesised into
* audiable sound via PWM, using the notes sent to MIDI channel 1.
*
* Outgoing audio will output in 8-bit PWM onto the timer 3 output compare channel A. Decouple the audio output with a capacitor
* and attach to a speaker to hear the audio.
*
* \section Sec_Options Project Options
*
* The following defines can be found in this project, which can control the project 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>MAX_SIMULTANEOUS_NOTES</td>
* <td>MIDIToneGenerator.h</td>
* <td>Sets the maximum number of MIDI notes that can be generated simultaneously. More notes require more processing time,
* and thus a value that is too high will cause audiable sound distortion due to insufficient CPU time.</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 Tone Generator Project
*
* \section Sec_Compat Project Compatibility:
*
* The following list indicates what microcontrollers are compatible with this project.
*
* - Series 7 USB AVRs (AT90USBxxx7)
* - Series 6 USB AVRs (AT90USBxxx6)
* - Series 4 USB AVRs (ATMEGAxxU4)
*
* \section Sec_Info USB Information:
*
* The following table gives a rundown of the USB utilization of this project.
*
* <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 Sec_Description Project Description:
*
* MIDI note synthesiser project. This project implements a basic DDS frequency synthesiser, capable of producing 8-bit PWM sine
* waves of variable frequency. When attached to a USB host, this project will allow for multiple MIDI notes to be synthesised into
* audiable sound via PWM, using the notes sent to MIDI channel 1.
*
* Outgoing audio will output in 8-bit PWM onto the timer 3 output compare channel A. Decouple the audio output with a capacitor
* and attach to a speaker to hear the audio.
*
* \section Sec_Options Project Options
*
* The following defines can be found in this project, which can control the project 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>MAX_SIMULTANEOUS_NOTES</td>
* <td>MIDIToneGenerator.h</td>
* <td>Sets the maximum number of MIDI notes that can be generated simultaneously. More notes require more processing time,
* and thus a value that is too high will cause audiable sound distortion due to insufficient CPU time.</td>
* </tr>
* </table>
*/

File diff suppressed because it is too large Load diff

View file

@ -1,52 +1,52 @@
; Windows LUFA RNDIS Setup File
; Copyright (c) 2000 Microsoft Corporation
[Version]
Signature = "$Windows NT$"
Class = Net
ClassGUID = {4d36e972-e325-11ce-bfc1-08002be10318}
Provider = %COMPANY%
DriverVer = 06/21/2006,6.0.6000.16384
;CatalogFile = device.cat
[Manufacturer]
%COMPANY% = RndisDevices,NTx86,NTamd64,NTia64
; Decoration for x86 architecture
[RndisDevices.NTx86]
%RNDISDEV% = RNDIS.NT.5.1, USB\VID_03EB&PID_2069&MI_00
; Decoration for x64 architecture
[RndisDevices.NTamd64]
%RNDISDEV% = RNDIS.NT.5.1, USB\VID_03EB&PID_2069&MI_00
; Decoration for ia64 architecture
[RndisDevices.NTia64]
%RNDISDEV% = RNDIS.NT.5.1, USB\VID_03EB&PID_2069&MI_00
;@@@ This is the common setting for setup
[ControlFlags]
ExcludeFromSelect=*
; DDInstall section
; References the in-build Netrndis.inf
[RNDIS.NT.5.1]
Characteristics = 0x84 ; NCF_PHYSICAL + NCF_HAS_UI
BusType = 15
; NEVER REMOVE THE FOLLOWING REFERENCE FOR NETRNDIS.INF
include = netrndis.inf
needs = Usb_Rndis.ndi
AddReg = Rndis_AddReg_Vista
; DDInstal.Services section
[RNDIS.NT.5.1.Services]
include = netrndis.inf
needs = Usb_Rndis.ndi.Services
; No sys copyfiles - the sys files are already in-build
; (part of the operating system).
; Modify these strings for your device as needed.
[Strings]
COMPANY="LUFA Library"
; Windows LUFA RNDIS Setup File
; Copyright (c) 2000 Microsoft Corporation
[Version]
Signature = "$Windows NT$"
Class = Net
ClassGUID = {4d36e972-e325-11ce-bfc1-08002be10318}
Provider = %COMPANY%
DriverVer = 06/21/2006,6.0.6000.16384
;CatalogFile = device.cat
[Manufacturer]
%COMPANY% = RndisDevices,NTx86,NTamd64,NTia64
; Decoration for x86 architecture
[RndisDevices.NTx86]
%RNDISDEV% = RNDIS.NT.5.1, USB\VID_03EB&PID_2069&MI_00
; Decoration for x64 architecture
[RndisDevices.NTamd64]
%RNDISDEV% = RNDIS.NT.5.1, USB\VID_03EB&PID_2069&MI_00
; Decoration for ia64 architecture
[RndisDevices.NTia64]
%RNDISDEV% = RNDIS.NT.5.1, USB\VID_03EB&PID_2069&MI_00
;@@@ This is the common setting for setup
[ControlFlags]
ExcludeFromSelect=*
; DDInstall section
; References the in-build Netrndis.inf
[RNDIS.NT.5.1]
Characteristics = 0x84 ; NCF_PHYSICAL + NCF_HAS_UI
BusType = 15
; NEVER REMOVE THE FOLLOWING REFERENCE FOR NETRNDIS.INF
include = netrndis.inf
needs = Usb_Rndis.ndi
AddReg = Rndis_AddReg_Vista
; DDInstal.Services section
[RNDIS.NT.5.1.Services]
include = netrndis.inf
needs = Usb_Rndis.ndi.Services
; No sys copyfiles - the sys files are already in-build
; (part of the operating system).
; Modify these strings for your device as needed.
[Strings]
COMPANY="LUFA Library"
RNDISDEV="LUFA USB RNDIS Webserver"

View file

@ -1,265 +1,265 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2011.
dean [at] fourwalledcubicle [dot] com
www.lufa-lib.org
*/
/*
Copyright 2011 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.
*/
#if defined(ENABLE_DHCP_SERVER) || defined(__DOXYGEN__)
/** \file
*
* DHCP Server Application. When connected to the uIP stack, this will send IP configuration settings to a
* DHCP client on the network.
*/
#define INCLUDE_FROM_DHCPSERVERAPP_C
#include "DHCPServerApp.h"
struct uip_conn* BroadcastConnection;
uint8_t LeasedIPs[255 / 8];
/** Initialization function for the DHCP server. */
void DHCPServerApp_Init(void)
{
/* Listen on port 67 for DHCP server connections from hosts */
uip_listen(HTONS(DHCP_SERVER_PORT));
/* Create a new UDP connection to the DHCP server port for the DHCP solicitation */
struct uip_udp_conn* BroadcastConnection = uip_udp_new(&uip_broadcast_addr, HTONS(DHCP_CLIENT_PORT));
/* If the connection was successfully created, bind it to the local DHCP client port */
if (BroadcastConnection != NULL)
uip_udp_bind(BroadcastConnection, HTONS(DHCP_SERVER_PORT));
/* Set all IP addresses as unleased */
memset(LeasedIPs, 0x00, sizeof(LeasedIPs));
}
/** uIP stack application callback for the DHCP server. This function must be called each time the TCP/IP stack
* needs a UDP packet to be processed.
*/
void DHCPServerApp_Callback(void)
{
DHCP_Header_t* const AppData = (DHCP_Header_t*)uip_appdata;
uint16_t AppDataSize = 0;
/* Only process when new data arrives - don't retransmit lost packets */
if (uip_newdata())
{
/* Get the DHCP message type (if present), otherwise early-abort */
uint8_t DHCPMessageType;
if (!(DHCPCommon_GetOption(AppData->Options, DHCP_OPTION_MSG_TYPE, &DHCPMessageType)))
return;
uip_ipaddr_t Netmask, GatewayIPAddress, PreferredClientIP;
struct uip_eth_addr RemoteMACAddress;
uint32_t TransactionID;
/* Get configured network mask, gateway IP and extract out DHCP transaction ID and remote IP */
uip_getnetmask(&Netmask);
uip_getdraddr(&GatewayIPAddress);
memcpy(&RemoteMACAddress, &AppData->ClientHardwareAddress, sizeof(struct uip_eth_addr));
TransactionID = AppData->TransactionID;
/* Try to extract out the client's preferred IP address if it is indicated in the packet */
if (!(DHCPCommon_GetOption(AppData->Options, DHCP_OPTION_REQ_IPADDR, &PreferredClientIP)))
memcpy(&PreferredClientIP, &uip_all_zeroes_addr, sizeof(uip_ipaddr_t));
switch (DHCPMessageType)
{
case DHCP_DISCOVER:
/* If no preference was made or the preferred IP is already taken, find a new address */
if (DHCPServerApp_CheckIfIPLeased(&PreferredClientIP))
DHCPServerApp_GetUnleasedIP(&PreferredClientIP);
/* Create a new DHCP OFFER packet with the offered IP address */
AppDataSize += DHCPServerApp_FillDHCPHeader(AppData, DHCP_OFFER, &RemoteMACAddress, &PreferredClientIP, TransactionID);
/* Add network mask and router information to the list of DHCP OFFER packet options */
AppDataSize += DHCPCommon_SetOption(AppData->Options, DHCP_OPTION_SUBNET_MASK,
sizeof(uip_ipaddr_t), &Netmask);
AppDataSize += DHCPCommon_SetOption(AppData->Options, DHCP_OPTION_ROUTER,
sizeof(uip_ipaddr_t), &GatewayIPAddress);
/* Send the DHCP OFFER packet */
uip_poll_conn(BroadcastConnection);
memcpy(&uip_udp_conn->ripaddr, &uip_broadcast_addr, sizeof(uip_ipaddr_t));
uip_udp_send(AppDataSize);
break;
case DHCP_REQUEST:
/* Check to see if the requested IP address has already been leased to a client */
if (!(DHCPServerApp_CheckIfIPLeased(&PreferredClientIP)))
{
/* Create a new DHCP ACK packet to accept the IP address lease */
AppDataSize += DHCPServerApp_FillDHCPHeader(AppData, DHCP_ACK, &RemoteMACAddress, &PreferredClientIP, TransactionID);
/* Add network mask and router information to the list of DHCP ACK packet options */
AppDataSize += DHCPCommon_SetOption(AppData->Options, DHCP_OPTION_SUBNET_MASK,
sizeof(uip_ipaddr_t), &Netmask);
AppDataSize += DHCPCommon_SetOption(AppData->Options, DHCP_OPTION_ROUTER,
sizeof(uip_ipaddr_t), &GatewayIPAddress);
/* Mark the requested IP as leased to a client */
DHCPServerApp_LeaseIP(&PreferredClientIP);
}
else
{
/* Create a new DHCP NAK packet to reject the requested allocation */
AppDataSize += DHCPServerApp_FillDHCPHeader(AppData, DHCP_NAK, &RemoteMACAddress, &uip_all_zeroes_addr, TransactionID);
}
/* Send the DHCP ACK or NAK packet */
uip_poll_conn(BroadcastConnection);
memcpy(&uip_udp_conn->ripaddr, &uip_broadcast_addr, sizeof(uip_ipaddr_t));
uip_udp_send(AppDataSize);
break;
case DHCP_RELEASE:
/* Mark the IP address as released in the allocation table */
DHCPServerApp_UnleaseIP(&uip_udp_conn->ripaddr);
break;
}
}
}
/** Fills the DHCP packet response with the appropriate BOOTP header for DHCP. This fills out all the required
* fields, leaving only the additional DHCP options to be added to the packet before it is sent to the DHCP client.
*
* \param[out] DHCPHeader Location in the packet buffer where the BOOTP header should be written to
* \param[in] DHCPMessageType DHCP Message type, such as DHCP_DISCOVER
* \param[in] ClientHardwareAddress Client MAC address the created transaction should be directed to
* \param[in] PreferredClientIP Preferred IP that should be given to the client if it is unallocated
* \param[in] TransactionID Transaction ID the created transaction should be associated with
*
* \return Size in bytes of the created DHCP packet
*/
static uint16_t DHCPServerApp_FillDHCPHeader(DHCP_Header_t* const DHCPHeader,
const uint8_t DHCPMessageType,
const struct uip_eth_addr* const ClientHardwareAddress,
const uip_ipaddr_t* const PreferredClientIP,
const uint32_t TransactionID)
{
/* Erase existing packet data so that we start will all 0x00 DHCP header data */
memset(DHCPHeader, 0, sizeof(DHCP_Header_t));
DHCPHeader->Operation = DHCPMessageType;
DHCPHeader->HardwareType = DHCP_HTYPE_ETHERNET;
DHCPHeader->HardwareAddressLength = sizeof(MACAddress);
DHCPHeader->Hops = 0;
DHCPHeader->TransactionID = TransactionID;
DHCPHeader->ElapsedSeconds = 0;
DHCPHeader->Flags = 0;
memcpy(&DHCPHeader->NextServerIP, &uip_hostaddr, sizeof(uip_ipaddr_t));
memcpy(&DHCPHeader->YourIP, PreferredClientIP, sizeof(uip_ipaddr_t));
memcpy(&DHCPHeader->ClientHardwareAddress, ClientHardwareAddress, sizeof(struct uip_eth_addr));
DHCPHeader->Cookie = DHCP_MAGIC_COOKIE;
/* Add a DHCP message type and terminator options to the start of the DHCP options field */
DHCPHeader->Options[0] = DHCP_OPTION_MSG_TYPE;
DHCPHeader->Options[1] = 1;
DHCPHeader->Options[2] = DHCPMessageType;
DHCPHeader->Options[3] = DHCP_OPTION_END;
/* Calculate the total number of bytes added to the outgoing packet */
return (sizeof(DHCP_Header_t) + 4);
}
/** Checks to see if the nominated IP address has already been allocated to a client.
*
* \param[in] IPAddress IP Address whose lease status should be checked
*
* \pre The IP address must be within the same /24 subnet as the virtual webserver.
*
* \return Boolean true if the IP has already been leased to a client, false otherwise.
*/
static bool DHCPServerApp_CheckIfIPLeased(const uip_ipaddr_t* const IPAddress)
{
uint8_t Byte = (IPAddress->u8[3] / 8);
uint8_t Mask = (1 << (IPAddress->u8[3] % 8));
/* Make sure that the requested IP address isn't already leased to the virtual server or another client */
if (IPAddress->u8[3] && !(IPAddress->u8[3] == uip_hostaddr.u8[3]) && !(LeasedIPs[Byte] & Mask))
return false;
else
return true;
}
/** Retrieves the next unleased IP in the IP address pool.
*
* \param[out] NewIPAddress Location where the generated IP Address should be stored
*/
static void DHCPServerApp_GetUnleasedIP(uip_ipaddr_t* const NewIPAddress)
{
uip_ipaddr_copy(NewIPAddress, &uip_hostaddr);
/** Look through the current subnet, skipping the broadcast and zero IP addresses */
for (uint8_t IP = 1; IP < 254; IP++)
{
/* Update new IP address to lease with the current IP address to test */
NewIPAddress->u8[3] = IP;
/* If we've found an unleased IP, abort with the updated IP stored for the called */
if (!(DHCPServerApp_CheckIfIPLeased(NewIPAddress)))
return;
}
}
/** Marks the given IP Address as leased in the address pool, so that it will not be
* allocated to another client unless it is first released.
*
* \param[in] IPAddress IP Address to mark as leased
*
* \pre The IP address must be within the same /24 subnet as the virtual webserver.
*/
static void DHCPServerApp_LeaseIP(const uip_ipaddr_t* const IPAddress)
{
uint8_t Byte = (IPAddress->u8[3] / 8);
uint8_t Mask = (1 << (IPAddress->u8[3] % 8));
/* Mark the IP address as leased in the allocation table */
LeasedIPs[Byte] |= Mask;
}
/** Marks the given IP Address as not leased in the address pool, so that it can be
* allocated to another client upon request.
*
* \param[in] IPAddress IP Address to mark as not leased
*
* \pre The IP address must be within the same /24 subnet as the virtual webserver.
*/
static void DHCPServerApp_UnleaseIP(const uip_ipaddr_t* const IPAddress)
{
uint8_t Byte = (IPAddress->u8[3] / 8);
uint8_t Mask = (1 << (IPAddress->u8[3] % 8));
/* Mark the IP address as unleased in the allocation table */
LeasedIPs[Byte] &= ~Mask;
}
#endif
/*
LUFA Library
Copyright (C) Dean Camera, 2011.
dean [at] fourwalledcubicle [dot] com
www.lufa-lib.org
*/
/*
Copyright 2011 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.
*/
#if defined(ENABLE_DHCP_SERVER) || defined(__DOXYGEN__)
/** \file
*
* DHCP Server Application. When connected to the uIP stack, this will send IP configuration settings to a
* DHCP client on the network.
*/
#define INCLUDE_FROM_DHCPSERVERAPP_C
#include "DHCPServerApp.h"
struct uip_conn* BroadcastConnection;
uint8_t LeasedIPs[255 / 8];
/** Initialization function for the DHCP server. */
void DHCPServerApp_Init(void)
{
/* Listen on port 67 for DHCP server connections from hosts */
uip_listen(HTONS(DHCP_SERVER_PORT));
/* Create a new UDP connection to the DHCP server port for the DHCP solicitation */
struct uip_udp_conn* BroadcastConnection = uip_udp_new(&uip_broadcast_addr, HTONS(DHCP_CLIENT_PORT));
/* If the connection was successfully created, bind it to the local DHCP client port */
if (BroadcastConnection != NULL)
uip_udp_bind(BroadcastConnection, HTONS(DHCP_SERVER_PORT));
/* Set all IP addresses as unleased */
memset(LeasedIPs, 0x00, sizeof(LeasedIPs));
}
/** uIP stack application callback for the DHCP server. This function must be called each time the TCP/IP stack
* needs a UDP packet to be processed.
*/
void DHCPServerApp_Callback(void)
{
DHCP_Header_t* const AppData = (DHCP_Header_t*)uip_appdata;
uint16_t AppDataSize = 0;
/* Only process when new data arrives - don't retransmit lost packets */
if (uip_newdata())
{
/* Get the DHCP message type (if present), otherwise early-abort */
uint8_t DHCPMessageType;
if (!(DHCPCommon_GetOption(AppData->Options, DHCP_OPTION_MSG_TYPE, &DHCPMessageType)))
return;
uip_ipaddr_t Netmask, GatewayIPAddress, PreferredClientIP;
struct uip_eth_addr RemoteMACAddress;
uint32_t TransactionID;
/* Get configured network mask, gateway IP and extract out DHCP transaction ID and remote IP */
uip_getnetmask(&Netmask);
uip_getdraddr(&GatewayIPAddress);
memcpy(&RemoteMACAddress, &AppData->ClientHardwareAddress, sizeof(struct uip_eth_addr));
TransactionID = AppData->TransactionID;
/* Try to extract out the client's preferred IP address if it is indicated in the packet */
if (!(DHCPCommon_GetOption(AppData->Options, DHCP_OPTION_REQ_IPADDR, &PreferredClientIP)))
memcpy(&PreferredClientIP, &uip_all_zeroes_addr, sizeof(uip_ipaddr_t));
switch (DHCPMessageType)
{
case DHCP_DISCOVER:
/* If no preference was made or the preferred IP is already taken, find a new address */
if (DHCPServerApp_CheckIfIPLeased(&PreferredClientIP))
DHCPServerApp_GetUnleasedIP(&PreferredClientIP);
/* Create a new DHCP OFFER packet with the offered IP address */
AppDataSize += DHCPServerApp_FillDHCPHeader(AppData, DHCP_OFFER, &RemoteMACAddress, &PreferredClientIP, TransactionID);
/* Add network mask and router information to the list of DHCP OFFER packet options */
AppDataSize += DHCPCommon_SetOption(AppData->Options, DHCP_OPTION_SUBNET_MASK,
sizeof(uip_ipaddr_t), &Netmask);
AppDataSize += DHCPCommon_SetOption(AppData->Options, DHCP_OPTION_ROUTER,
sizeof(uip_ipaddr_t), &GatewayIPAddress);
/* Send the DHCP OFFER packet */
uip_poll_conn(BroadcastConnection);
memcpy(&uip_udp_conn->ripaddr, &uip_broadcast_addr, sizeof(uip_ipaddr_t));
uip_udp_send(AppDataSize);
break;
case DHCP_REQUEST:
/* Check to see if the requested IP address has already been leased to a client */
if (!(DHCPServerApp_CheckIfIPLeased(&PreferredClientIP)))
{
/* Create a new DHCP ACK packet to accept the IP address lease */
AppDataSize += DHCPServerApp_FillDHCPHeader(AppData, DHCP_ACK, &RemoteMACAddress, &PreferredClientIP, TransactionID);
/* Add network mask and router information to the list of DHCP ACK packet options */
AppDataSize += DHCPCommon_SetOption(AppData->Options, DHCP_OPTION_SUBNET_MASK,
sizeof(uip_ipaddr_t), &Netmask);
AppDataSize += DHCPCommon_SetOption(AppData->Options, DHCP_OPTION_ROUTER,
sizeof(uip_ipaddr_t), &GatewayIPAddress);
/* Mark the requested IP as leased to a client */
DHCPServerApp_LeaseIP(&PreferredClientIP);
}
else
{
/* Create a new DHCP NAK packet to reject the requested allocation */
AppDataSize += DHCPServerApp_FillDHCPHeader(AppData, DHCP_NAK, &RemoteMACAddress, &uip_all_zeroes_addr, TransactionID);
}
/* Send the DHCP ACK or NAK packet */
uip_poll_conn(BroadcastConnection);
memcpy(&uip_udp_conn->ripaddr, &uip_broadcast_addr, sizeof(uip_ipaddr_t));
uip_udp_send(AppDataSize);
break;
case DHCP_RELEASE:
/* Mark the IP address as released in the allocation table */
DHCPServerApp_UnleaseIP(&uip_udp_conn->ripaddr);
break;
}
}
}
/** Fills the DHCP packet response with the appropriate BOOTP header for DHCP. This fills out all the required
* fields, leaving only the additional DHCP options to be added to the packet before it is sent to the DHCP client.
*
* \param[out] DHCPHeader Location in the packet buffer where the BOOTP header should be written to
* \param[in] DHCPMessageType DHCP Message type, such as DHCP_DISCOVER
* \param[in] ClientHardwareAddress Client MAC address the created transaction should be directed to
* \param[in] PreferredClientIP Preferred IP that should be given to the client if it is unallocated
* \param[in] TransactionID Transaction ID the created transaction should be associated with
*
* \return Size in bytes of the created DHCP packet
*/
static uint16_t DHCPServerApp_FillDHCPHeader(DHCP_Header_t* const DHCPHeader,
const uint8_t DHCPMessageType,
const struct uip_eth_addr* const ClientHardwareAddress,
const uip_ipaddr_t* const PreferredClientIP,
const uint32_t TransactionID)
{
/* Erase existing packet data so that we start will all 0x00 DHCP header data */
memset(DHCPHeader, 0, sizeof(DHCP_Header_t));
DHCPHeader->Operation = DHCPMessageType;
DHCPHeader->HardwareType = DHCP_HTYPE_ETHERNET;
DHCPHeader->HardwareAddressLength = sizeof(MACAddress);
DHCPHeader->Hops = 0;
DHCPHeader->TransactionID = TransactionID;
DHCPHeader->ElapsedSeconds = 0;
DHCPHeader->Flags = 0;
memcpy(&DHCPHeader->NextServerIP, &uip_hostaddr, sizeof(uip_ipaddr_t));
memcpy(&DHCPHeader->YourIP, PreferredClientIP, sizeof(uip_ipaddr_t));
memcpy(&DHCPHeader->ClientHardwareAddress, ClientHardwareAddress, sizeof(struct uip_eth_addr));
DHCPHeader->Cookie = DHCP_MAGIC_COOKIE;
/* Add a DHCP message type and terminator options to the start of the DHCP options field */
DHCPHeader->Options[0] = DHCP_OPTION_MSG_TYPE;
DHCPHeader->Options[1] = 1;
DHCPHeader->Options[2] = DHCPMessageType;
DHCPHeader->Options[3] = DHCP_OPTION_END;
/* Calculate the total number of bytes added to the outgoing packet */
return (sizeof(DHCP_Header_t) + 4);
}
/** Checks to see if the nominated IP address has already been allocated to a client.
*
* \param[in] IPAddress IP Address whose lease status should be checked
*
* \pre The IP address must be within the same /24 subnet as the virtual webserver.
*
* \return Boolean true if the IP has already been leased to a client, false otherwise.
*/
static bool DHCPServerApp_CheckIfIPLeased(const uip_ipaddr_t* const IPAddress)
{
uint8_t Byte = (IPAddress->u8[3] / 8);
uint8_t Mask = (1 << (IPAddress->u8[3] % 8));
/* Make sure that the requested IP address isn't already leased to the virtual server or another client */
if (IPAddress->u8[3] && !(IPAddress->u8[3] == uip_hostaddr.u8[3]) && !(LeasedIPs[Byte] & Mask))
return false;
else
return true;
}
/** Retrieves the next unleased IP in the IP address pool.
*
* \param[out] NewIPAddress Location where the generated IP Address should be stored
*/
static void DHCPServerApp_GetUnleasedIP(uip_ipaddr_t* const NewIPAddress)
{
uip_ipaddr_copy(NewIPAddress, &uip_hostaddr);
/** Look through the current subnet, skipping the broadcast and zero IP addresses */
for (uint8_t IP = 1; IP < 254; IP++)
{
/* Update new IP address to lease with the current IP address to test */
NewIPAddress->u8[3] = IP;
/* If we've found an unleased IP, abort with the updated IP stored for the called */
if (!(DHCPServerApp_CheckIfIPLeased(NewIPAddress)))
return;
}
}
/** Marks the given IP Address as leased in the address pool, so that it will not be
* allocated to another client unless it is first released.
*
* \param[in] IPAddress IP Address to mark as leased
*
* \pre The IP address must be within the same /24 subnet as the virtual webserver.
*/
static void DHCPServerApp_LeaseIP(const uip_ipaddr_t* const IPAddress)
{
uint8_t Byte = (IPAddress->u8[3] / 8);
uint8_t Mask = (1 << (IPAddress->u8[3] % 8));
/* Mark the IP address as leased in the allocation table */
LeasedIPs[Byte] |= Mask;
}
/** Marks the given IP Address as not leased in the address pool, so that it can be
* allocated to another client upon request.
*
* \param[in] IPAddress IP Address to mark as not leased
*
* \pre The IP address must be within the same /24 subnet as the virtual webserver.
*/
static void DHCPServerApp_UnleaseIP(const uip_ipaddr_t* const IPAddress)
{
uint8_t Byte = (IPAddress->u8[3] / 8);
uint8_t Mask = (1 << (IPAddress->u8[3] % 8));
/* Mark the IP address as unleased in the allocation table */
LeasedIPs[Byte] &= ~Mask;
}
#endif

View file

@ -1,63 +1,63 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2011.
dean [at] fourwalledcubicle [dot] com
www.lufa-lib.org
*/
/*
Copyright 2011 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 DHCPServerApp.c.
*/
#ifndef _DHCPSERVER_APP_H_
#define _DHCPSERVER_APP_H_
/* Includes: */
#include <stdio.h>
#include <uip.h>
#include "../Webserver.h"
#include "DHCPCommon.h"
/* Function Prototypes: */
void DHCPServerApp_Init(void);
void DHCPServerApp_Callback(void);
#if defined(INCLUDE_FROM_DHCPSERVERAPP_C)
static uint16_t DHCPServerApp_FillDHCPHeader(DHCP_Header_t* const DHCPHeader,
const uint8_t DHCPMessageType,
const struct uip_eth_addr* const ClientHardwareAddress,
const uip_ipaddr_t* const PreferredClientIP,
const uint32_t TransactionID);
static bool DHCPServerApp_CheckIfIPLeased(const uip_ipaddr_t* const IPAddress);
static void DHCPServerApp_GetUnleasedIP(uip_ipaddr_t* const NewIPAddress);
static void DHCPServerApp_LeaseIP(const uip_ipaddr_t* const IPAddress);
static void DHCPServerApp_UnleaseIP(const uip_ipaddr_t* const IPAddress);
#endif
#endif
/*
LUFA Library
Copyright (C) Dean Camera, 2011.
dean [at] fourwalledcubicle [dot] com
www.lufa-lib.org
*/
/*
Copyright 2011 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 DHCPServerApp.c.
*/
#ifndef _DHCPSERVER_APP_H_
#define _DHCPSERVER_APP_H_
/* Includes: */
#include <stdio.h>
#include <uip.h>
#include "../Webserver.h"
#include "DHCPCommon.h"
/* Function Prototypes: */
void DHCPServerApp_Init(void);
void DHCPServerApp_Callback(void);
#if defined(INCLUDE_FROM_DHCPSERVERAPP_C)
static uint16_t DHCPServerApp_FillDHCPHeader(DHCP_Header_t* const DHCPHeader,
const uint8_t DHCPMessageType,
const struct uip_eth_addr* const ClientHardwareAddress,
const uip_ipaddr_t* const PreferredClientIP,
const uint32_t TransactionID);
static bool DHCPServerApp_CheckIfIPLeased(const uip_ipaddr_t* const IPAddress);
static void DHCPServerApp_GetUnleasedIP(uip_ipaddr_t* const NewIPAddress);
static void DHCPServerApp_LeaseIP(const uip_ipaddr_t* const IPAddress);
static void DHCPServerApp_UnleaseIP(const uip_ipaddr_t* const IPAddress);
#endif
#endif