From 2d9f98b592c41a0b79eb6d15122fc00f4f91c836 Mon Sep 17 00:00:00 2001
From: Dean Camera <dean@fourwalledcubicle.com>
Date: Tue, 23 Aug 2011 07:07:34 +0000
Subject: [PATCH] Add multiple axis support to the HID joystick report in the
 HID_DESCRIPTOR_JOYSTICK() macro.

---
 .../Device/ClassDriver/Joystick/Descriptors.c |  3 +-
 LUFA/Drivers/USB/Class/Common/HID.h           | 42 ++++++++++---------
 LUFA/ManPages/ChangeLog.txt                   |  1 +
 LUFA/ManPages/MigrationInformation.txt        | 30 ++++++-------
 4 files changed, 41 insertions(+), 35 deletions(-)

diff --git a/Demos/Device/ClassDriver/Joystick/Descriptors.c b/Demos/Device/ClassDriver/Joystick/Descriptors.c
index a9abb5d81..cc7399288 100644
--- a/Demos/Device/ClassDriver/Joystick/Descriptors.c
+++ b/Demos/Device/ClassDriver/Joystick/Descriptors.c
@@ -46,13 +46,14 @@
 const USB_Descriptor_HIDReport_Datatype_t PROGMEM JoystickReport[] =
 {
 	/* Use the HID class driver's standard Joystick report.
+	 *   Number of Axis: 2 (X/Y)
 	 *   Min X/Y Axis values: -100
 	 *   Max X/Y Axis values:  100
 	 *   Min physical X/Y Axis values (used to determine resolution): -1
 	 *   Max physical X/Y Axis values (used to determine resolution):  1
 	 *   Buttons: 2
 	 */
-	HID_DESCRIPTOR_JOYSTICK(-100, 100, -1, 1, 2)
+	HID_DESCRIPTOR_JOYSTICK(2, -100, 100, -1, 1, 2)
 };
 
 /** Device descriptor structure. This descriptor, located in FLASH memory, describes the overall
diff --git a/LUFA/Drivers/USB/Class/Common/HID.h b/LUFA/Drivers/USB/Class/Common/HID.h
index 4e3c701cc..74012b67b 100644
--- a/LUFA/Drivers/USB/Class/Common/HID.h
+++ b/LUFA/Drivers/USB/Class/Common/HID.h
@@ -328,43 +328,46 @@
 		#define HID_KEYBOARD_SC_RIGHT_GUI                         0xE7
 		//@}
 
-		/** \name Standard HID Device Report Descriptors */
+		/** \name Common HID Device Report Descriptors */
 		//@{
 		/** \hideinitializer
-		 *  A list of HID report item array elements that describe a typical HID USB Joystick. The resulting report descriptor
-		 *  is structured according to the following layout:
+		 *  A list of HID report item array elements that describe a typical HID USB Joystick. The resulting report
+		 *  descriptor is structured according to the following layout:
 		 *
 		 *  \code
 		 *  struct
 		 *  {
-		 *      uintA_t Buttons; // Pressed buttons bitmask
 		 *      intB_t X; // Signed X axis value
 		 *      intB_t Y; // Signed Y axis value
+		 *      int8_t Z; // Signed Z axis value
+		 *      // Additional axis elements here
+		 *      uintA_t Buttons; // Pressed buttons bitmask
 		 *  } Joystick_Report;
 		 *  \endcode
 		 *
 		 *  Where \c uintA_t is a type large enough to hold one bit per button, and \c intB_t is a type large enough to hold the
 		 *  ranges of the signed \c MinAxisVal and \c MaxAxisVal values.
 		 *
-		 *  \param[in] MinAxisVal      Minimum X/Y logical axis value.
-		 *  \param[in] MaxAxisVal      Maximum X/Y logical axis value.
-		 *  \param[in] MinPhysicalVal  Minimum X/Y physical axis value, for movement resolution calculations.
-		 *  \param[in] MaxPhysicalVal  Maximum X/Y physical axis value, for movement resolution calculations.
-		 *  \param[in] Buttons         Total number of buttons in the device.
+		 *  \param[in] NumAxis         Number of axis in the joystick (8-bit)
+		 *  \param[in] MinAxisVal      Minimum logical axis value (16-bit).
+		 *  \param[in] MaxAxisVal      Maximum logical axis value (16-bit).
+		 *  \param[in] MinPhysicalVal  Minimum physical axis value, for movement resolution calculations (16-bit).
+		 *  \param[in] MaxPhysicalVal  Maximum physical axis value, for movement resolution calculations (16-bit).
+		 *  \param[in] Buttons         Total number of buttons in the device (8-bit).
 		 */
-		#define HID_DESCRIPTOR_JOYSTICK(MinAxisVal, MaxAxisVal, MinPhysicalVal, MaxPhysicalVal, Buttons) \
+		#define HID_DESCRIPTOR_JOYSTICK(NumAxis, MinAxisVal, MaxAxisVal, MinPhysicalVal, MaxPhysicalVal, Buttons) \
 			HID_RI_USAGE_PAGE(8, 0x01),                     \
 			HID_RI_USAGE(8, 0x04),                          \
 			HID_RI_COLLECTION(8, 0x01),                     \
 				HID_RI_USAGE(8, 0x01),                      \
 				HID_RI_COLLECTION(8, 0x00),                 \
-					HID_RI_USAGE(8, 0x30),                  \
-					HID_RI_USAGE(8, 0x31),                  \
+					HID_RI_USAGE_MINIMUM(8, 0x30),          \
+					HID_RI_USAGE_MAXIMUM(8, (0x30 + (NumAxis - 1))), \
 					HID_RI_LOGICAL_MINIMUM(16, MinAxisVal), \
 					HID_RI_LOGICAL_MAXIMUM(16, MaxAxisVal), \
 					HID_RI_PHYSICAL_MINIMUM(16, MinPhysicalVal), \
 					HID_RI_PHYSICAL_MAXIMUM(16, MaxPhysicalVal), \
-					HID_RI_REPORT_COUNT(8, 0x02),           \
+					HID_RI_REPORT_COUNT(8, NumAxis),        \
 					HID_RI_REPORT_SIZE(8, ((((MinAxisVal >= -0xFF) && (MaxAxisVal <= 0xFF)) ? 8 : 16))), \
 					HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE), \
 				HID_RI_END_COLLECTION(0),                   \
@@ -395,8 +398,7 @@
 		 *  } Keyboard_Report;
 		 *  \endcode
 		 *
-		 *  \param[in] MaxKeys  Number of simultaneous keys that can be reported at the one time (a value between 1 and
-		 *                      (ENDPOINT_SIZE - 2) ).
+		 *  \param[in] MaxKeys  Number of simultaneous keys that can be reported at the one time (8-bit).
 		 */
 		#define HID_DESCRIPTOR_KEYBOARD(MaxKeys)            \
 			HID_RI_USAGE_PAGE(8, 0x01),                     \
@@ -449,11 +451,11 @@
 		 *  Where \c intA_t is a type large enough to hold one bit per button, and \c intB_t is a type large enough to hold the
 		 *  ranges of the signed \c MinAxisVal and \c MaxAxisVal values.
 		 *
-		 *  \param[in] MinAxisVal      Minimum X/Y logical axis value.
-		 *  \param[in] MaxAxisVal      Maximum X/Y logical axis value.
-		 *  \param[in] MinPhysicalVal  Minimum X/Y physical axis value, for movement resolution calculations.
-		 *  \param[in] MaxPhysicalVal  Maximum X/Y physical axis value, for movement resolution calculations.
-		 *  \param[in] Buttons         Total number of buttons in the device.
+		 *  \param[in] MinAxisVal      Minimum X/Y logical axis value (16-bit).
+		 *  \param[in] MaxAxisVal      Maximum X/Y logical axis value (16-bit).
+		 *  \param[in] MinPhysicalVal  Minimum X/Y physical axis value, for movement resolution calculations (16-bit).
+		 *  \param[in] MaxPhysicalVal  Maximum X/Y physical axis value, for movement resolution calculations (16-bit).
+		 *  \param[in] Buttons         Total number of buttons in the device (8-bit).
 		 *  \param[in] AbsoluteCoords  Boolean true to use absolute X/Y coordinates (e.g. touchscreen).
 		 */
 		#define HID_DESCRIPTOR_MOUSE(MinAxisVal, MaxAxisVal, MinPhysicalVal, MaxPhysicalVal, Buttons, AbsoluteCoords) \
diff --git a/LUFA/ManPages/ChangeLog.txt b/LUFA/ManPages/ChangeLog.txt
index fcfce3e9a..6782e8d59 100644
--- a/LUFA/ManPages/ChangeLog.txt
+++ b/LUFA/ManPages/ChangeLog.txt
@@ -57,6 +57,7 @@
   *   - Added endian correcting code to the library USB class drivers for multiple architecture support
   *   - Removed the ENDPOINT_DESCRIPTOR_DIR_* macros, replaced by ENDPOINT_DIR_* instead
   *   - Renamed the JTAG_DEBUG_ASSERT() macro to JTAG_ASSERT()
+  *   - Added variable number of axis to HID_DESCRIPTOR_JOYSTICK() for multi-axis joysticks above just X and Y
   *  - Library Applications:
   *   - Modified the Low Level and Class Driver AudioInput and AudioOutput demos to support multiple audio sample rates
   *   - Updated all host mode demos and projects to use the EVENT_USB_Host_DeviceEnumerationComplete() event callback for device configuration
diff --git a/LUFA/ManPages/MigrationInformation.txt b/LUFA/ManPages/MigrationInformation.txt
index 17dd59dd6..078887a76 100644
--- a/LUFA/ManPages/MigrationInformation.txt
+++ b/LUFA/ManPages/MigrationInformation.txt
@@ -11,20 +11,8 @@
  *  areas relevant to making older projects compatible with the API changes of each new release.
  *
  *  \section Sec_MigrationXXXXXX Migrating from 110528 to XXXXXX
- *  <b>Device Mode</b>
- *    - The definition of the Audio class \ref USB_Audio_Descriptor_Format_t has been altered, to remove the fixed singular
- *      audio sample rate in the descriptor definition, and to rename the \c SampleFrequencyType to the more appropriate
- *      \c TotalDiscreteSampleRates. Existing applications will need to add an array of \ref USB_Audio_SampleFreq_t elements
- *      immediately following any \ref USB_Audio_Descriptor_Format_t descriptors, and insert the appropriate sampling rates
- *      supported by the device, as well as rename the descriptor elements to match the updated element names.
- *    - The device mode Audio class driver now requires a new user application callback, \ref CALLBACK_Audio_Device_GetSetEndpointProperty().
- *      Existing applications must implement this new callback, however if multiple sample rates or pitch control is not used,
- *      this function may be hard-coded to always return false for previous behaviour to be retained.
- *    - The \c USB_ConfigurationNumber, \c USB_RemoteWakeupEnabled and \c USB_CurrentlySelfPowered globals have been renamed to
- *      \ref USB_Device_ConfigurationNumber, \ref USB_Device_RemoteWakeupEnabled and \ref USB_Device_CurrentlySelfPowered to clearly indicate
- *      the USB mode they relate to. Existing applications using these variables should rename all references to the previous names.
- *    - The \c ENDPOINT_DESCRIPTOR_DIR_IN and \c ENDPOINT_DESCRIPTOR_DIR_OUT macros have now been replaced by \ref ENDPOINT_DIR_IN and
- *      \ref ENDPOINT_DIR_OUT to improve code clarity.
+ *  <b>Non-USB Library Components</b>
+ *    - The \c JTAG_DEBUG_ASSERT() macro has been renamed \ref JTAG_ASSERT() to be consistent with \ref STDOUT_ASSERT().
  *
  *  <b>USB Core</b>
  *    - By default, unordered Endpoint and Pipe configuration is now allowed once again, via the previous workaround of
@@ -53,6 +41,20 @@
  *    - The Device mode RNDIS class driver no longer stores the incoming and outgoing packets in the class driver instance; the user is
  *      now expected to manually define a storage location for the packet data. Packets must now be sent and received manually via a call
  *      to \ref RNDIS_Device_ReadPacket() and/or \ref RNDIS_Device_SendPacket().
+ *    - The definition of the Audio class \ref USB_Audio_Descriptor_Format_t has been altered, to remove the fixed singular
+ *      audio sample rate in the descriptor definition, and to rename the \c SampleFrequencyType to the more appropriate
+ *      \c TotalDiscreteSampleRates. Existing applications will need to add an array of \ref USB_Audio_SampleFreq_t elements
+ *      immediately following any \ref USB_Audio_Descriptor_Format_t descriptors, and insert the appropriate sampling rates
+ *      supported by the device, as well as rename the descriptor elements to match the updated element names.
+ *    - The device mode Audio class driver now requires a new user application callback, \ref CALLBACK_Audio_Device_GetSetEndpointProperty().
+ *      Existing applications must implement this new callback, however if multiple sample rates or pitch control is not used,
+ *      this function may be hard-coded to always return false for previous behaviour to be retained.
+ *    - The \c USB_ConfigurationNumber, \c USB_RemoteWakeupEnabled and \c USB_CurrentlySelfPowered globals have been renamed to
+ *      \ref USB_Device_ConfigurationNumber, \ref USB_Device_RemoteWakeupEnabled and \ref USB_Device_CurrentlySelfPowered to clearly indicate
+ *      the USB mode they relate to. Existing applications using these variables should rename all references to the previous names.
+ *    - The \c ENDPOINT_DESCRIPTOR_DIR_IN and \c ENDPOINT_DESCRIPTOR_DIR_OUT macros have now been replaced by \ref ENDPOINT_DIR_IN and
+ *      \ref ENDPOINT_DIR_OUT to improve code clarity.
+ *    - The \ref HID_DESCRIPTOR_JOYSTICK() macro now takes an additional (first) parameter indicating the number of axis in the joystick.
  *
  *  <b>Host Mode</b>
  *    - The Pipe stream functions now all require a \c BytesProcessed parameter instead of the previous callback parameter.
-- 
GitLab