aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDean Camera <dean@fourwalledcubicle.com>2010-05-31 06:55:23 +0000
committerDean Camera <dean@fourwalledcubicle.com>2010-05-31 06:55:23 +0000
commitf606afeffffcfffba837ad1350bcda7b458b4031 (patch)
tree7992a58ecd831ad8d0ee065f1acfc9df26ddc903
parent152b2764c3c719e3e9e34ee60b5db8d99ff2611b (diff)
downloadlufa-f606afeffffcfffba837ad1350bcda7b458b4031.tar.gz
lufa-f606afeffffcfffba837ad1350bcda7b458b4031.tar.bz2
lufa-f606afeffffcfffba837ad1350bcda7b458b4031.zip
Remove void* arithmetic in the USB_GetNextDescriptor() static inline function, to make the header file C++ compatible once again. Implement workaround for an obscure GCC bug which can cause incorrect code generation under some circumstances when the void* is re-cast.
-rw-r--r--LUFA/Drivers/USB/HighLevel/ConfigDescriptor.c4
-rw-r--r--LUFA/Drivers/USB/HighLevel/ConfigDescriptor.h107
-rw-r--r--LUFA/ManPages/LUFAPoweredProjects.txt2
3 files changed, 62 insertions, 51 deletions
diff --git a/LUFA/Drivers/USB/HighLevel/ConfigDescriptor.c b/LUFA/Drivers/USB/HighLevel/ConfigDescriptor.c
index 07a3d4292..ffac8ae0f 100644
--- a/LUFA/Drivers/USB/HighLevel/ConfigDescriptor.c
+++ b/LUFA/Drivers/USB/HighLevel/ConfigDescriptor.c
@@ -114,13 +114,13 @@ void USB_GetNextDescriptorOfTypeAfter(uint16_t* const BytesRem,
USB_GetNextDescriptorOfType(BytesRem, CurrConfigLoc, Type);
}
-uint8_t USB_GetNextDescriptorComp(uint16_t* BytesRem, void** CurrConfigLoc, ConfigComparatorPtr_t const ComparatorRoutine)
+uint8_t USB_GetNextDescriptorComp(uint16_t* BytesRem, void** const CurrConfigLoc, ConfigComparatorPtr_t const ComparatorRoutine)
{
uint8_t ErrorCode;
while (*BytesRem)
{
- void* PrevDescLoc = *CurrConfigLoc;
+ uint8_t* PrevDescLoc = *CurrConfigLoc;
uint16_t PrevBytesRem = *BytesRem;
USB_GetNextDescriptor(BytesRem, CurrConfigLoc);
diff --git a/LUFA/Drivers/USB/HighLevel/ConfigDescriptor.h b/LUFA/Drivers/USB/HighLevel/ConfigDescriptor.h
index 211128ca2..87610c7ba 100644
--- a/LUFA/Drivers/USB/HighLevel/ConfigDescriptor.h
+++ b/LUFA/Drivers/USB/HighLevel/ConfigDescriptor.h
@@ -119,49 +119,6 @@
* \see \ref USB_GetNextDescriptorComp function for more details
*/
typedef uint8_t (* ConfigComparatorPtr_t)(void*);
-
- /* Function Prototypes: */
- /** Searches for the next descriptor in the given configuration descriptor using a premade comparator
- * function. The routine updates the position and remaining configuration descriptor bytes values
- * automatically. If a comparator routine fails a search, the descriptor pointer is retreated back
- * so that the next descriptor search invocation will start from the descriptor which first caused the
- * original search to fail. This behaviour allows for one comparator to be used immediately after another
- * has failed, starting the second search from the descriptor which failed the first.
- *
- * Comparator functions should be standard functions which accept a pointer to the header of the current
- * descriptor inside the configuration descriptor which is being compared, and should return a value from
- * the \ref DSearch_Return_ErrorCodes_t enum as a uint8_t value.
- *
- * \note This function is available in USB Host mode only.
- *
- * \param[in,out] BytesRem Pointer to an int storing the remaining bytes in the configuration descriptor
- * \param[in,out] CurrConfigLoc Pointer to the current position in the configuration descriptor
- * \param[in] ComparatorRoutine Name of the comparator search function to use on the configuration descriptor
- *
- * \return Value of one of the members of the \ref DSearch_Comp_Return_ErrorCodes_t enum
- *
- * Usage Example:
- * \code
- * uint8_t EndpointSearcher(void* CurrentDescriptor); // Comparator Prototype
- *
- * uint8_t EndpointSearcher(void* CurrentDescriptor)
- * {
- * if (DESCRIPTOR_TYPE(CurrentDescriptor) == DTYPE_Endpoint)
- * return DESCRIPTOR_SEARCH_Found;
- * else
- * return DESCRIPTOR_SEARCH_NotFound;
- * }
- *
- * //...
- * // After retrieving configuration descriptor:
- * if (USB_Host_GetNextDescriptorComp(&BytesRemaining, &CurrentConfigLoc, EndpointSearcher) ==
- * Descriptor_Search_Comp_Found)
- * {
- * // Do something with the endpoint descriptor
- * }
- * \endcode
- */
- uint8_t USB_GetNextDescriptorComp(uint16_t* BytesRem, void** CurrConfigLoc, ConfigComparatorPtr_t const ComparatorRoutine);
/* Enums: */
/** Enum for the possible return codes of the \ref USB_Host_GetDeviceConfigDescriptor() function. */
@@ -257,7 +214,59 @@
const uint8_t AfterType)
ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
+ /** Searches for the next descriptor in the given configuration descriptor using a premade comparator
+ * function. The routine updates the position and remaining configuration descriptor bytes values
+ * automatically. If a comparator routine fails a search, the descriptor pointer is retreated back
+ * so that the next descriptor search invocation will start from the descriptor which first caused the
+ * original search to fail. This behaviour allows for one comparator to be used immediately after another
+ * has failed, starting the second search from the descriptor which failed the first.
+ *
+ * Comparator functions should be standard functions which accept a pointer to the header of the current
+ * descriptor inside the configuration descriptor which is being compared, and should return a value from
+ * the \ref DSearch_Return_ErrorCodes_t enum as a uint8_t value.
+ *
+ * \note This function is available in USB Host mode only.
+ *
+ * \param[in,out] BytesRem Pointer to an int storing the remaining bytes in the configuration descriptor
+ * \param[in,out] CurrConfigLoc Pointer to the current position in the configuration descriptor
+ * \param[in] ComparatorRoutine Name of the comparator search function to use on the configuration descriptor
+ *
+ * \return Value of one of the members of the \ref DSearch_Comp_Return_ErrorCodes_t enum
+ *
+ * Usage Example:
+ * \code
+ * uint8_t EndpointSearcher(void* CurrentDescriptor); // Comparator Prototype
+ *
+ * uint8_t EndpointSearcher(void* CurrentDescriptor)
+ * {
+ * if (DESCRIPTOR_TYPE(CurrentDescriptor) == DTYPE_Endpoint)
+ * return DESCRIPTOR_SEARCH_Found;
+ * else
+ * return DESCRIPTOR_SEARCH_NotFound;
+ * }
+ *
+ * //...
+ * // After retrieving configuration descriptor:
+ * if (USB_Host_GetNextDescriptorComp(&BytesRemaining, &CurrentConfigLoc, EndpointSearcher) ==
+ * Descriptor_Search_Comp_Found)
+ * {
+ * // Do something with the endpoint descriptor
+ * }
+ * \endcode
+ */
+ uint8_t USB_GetNextDescriptorComp(uint16_t* BytesRem, void** const CurrConfigLoc, ConfigComparatorPtr_t const ComparatorRoutine);
+
/* Inline Functions: */
+ #if !defined(__DOXYGEN__)
+ static inline void USB_GetNextDescriptorST(uint16_t* const BytesRem, uint8_t** CurrConfigLoc)
+ {
+ uint16_t CurrDescriptorSize = DESCRIPTOR_CAST(*CurrConfigLoc, USB_Descriptor_Header_t).Size;
+
+ *CurrConfigLoc += CurrDescriptorSize;
+ *BytesRem -= CurrDescriptorSize;
+ }
+ #endif
+
/** Skips over the current sub-descriptor inside the configuration descriptor, so that the pointer then
points to the next sub-descriptor. The bytes remaining value is automatically decremented.
*
@@ -268,12 +277,14 @@
ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
static inline void USB_GetNextDescriptor(uint16_t* const BytesRem, void** CurrConfigLoc)
{
- uint16_t CurrDescriptorSize = DESCRIPTOR_CAST(*CurrConfigLoc, USB_Descriptor_Header_t).Size;
-
- *CurrConfigLoc += CurrDescriptorSize;
- *BytesRem -= CurrDescriptorSize;
+ /* Horrible workaround for a bug in GCC - in some circumstances, the code generated for the strongly-typed
+ * (uint8_t**) cast to avoid void pointer arithmetic (which is not allowed in C++) causes incorrect code to
+ * be generated. Performing the cast and using a secondary inline routine show here seems to avoid the
+ * problem.
+ */
+ USB_GetNextDescriptorST(BytesRem, (uint8_t**)CurrConfigLoc);
}
-
+
/* Disable C linkage for C++ Compilers: */
#if defined(__cplusplus)
}
diff --git a/LUFA/ManPages/LUFAPoweredProjects.txt b/LUFA/ManPages/LUFAPoweredProjects.txt
index 4fb8c3425..617380a19 100644
--- a/LUFA/ManPages/LUFAPoweredProjects.txt
+++ b/LUFA/ManPages/LUFAPoweredProjects.txt
@@ -21,7 +21,7 @@
* - AT90USB162 Breadboard PCB (Russian): http://microsin.ru/content/view/685/44/
* - Benito #7, a no-frills USB board: http://www.dorkbotpdx.org/wiki/benito
* - Bumble-B, yet another AT90USB162 development board: http://fletchtronics.net/bumble-b
- * - JM-DB-U2, an ATMEGA32U2 development board: http://u2.mattair.net/index.html
+ * - JM-DB-U2, an ATMEGA32U2 development board: http://www.mattairtech.com/index.php/development-boards/atmega32u2-development-board.html
* - Micropendous, an open design/source set of AVR USB development boards: http://micropendous.org/
* - Nanduino, a do-it-yourself AT90USB162 board: http://www.makestuff.eu/wordpress/?page_id=569
* - Teensy and Teensy++, two other AVR USB development boards: http://www.pjrc.com/teensy/index.html