From 34781781278f0fb2557b7c5dd9c0de54ad2aba09 Mon Sep 17 00:00:00 2001
From: Dean Camera <dean@fourwalledcubicle.com>
Date: Tue, 16 Aug 2011 05:00:45 +0000
Subject: [PATCH] Add shortcuts to SwapEndian_16() and SwapEndian_32() internal
 functions to improve optimization if called with constant inputs.

---
 .../TestAndMeasurement/TestAndMeasurement.c   | 47 ++++++++++++++-----
 .../TestAndMeasurement/TestAndMeasurement.h   | 14 ++----
 LUFA/Common/CompilerSpecific.h                | 10 ++--
 LUFA/Common/Endianness.h                      |  6 +++
 LUFA/ManPages/ChangeLog.txt                   |  1 +
 5 files changed, 53 insertions(+), 25 deletions(-)

diff --git a/Demos/Device/Incomplete/TestAndMeasurement/TestAndMeasurement.c b/Demos/Device/Incomplete/TestAndMeasurement/TestAndMeasurement.c
index 039736a28..3b8c29586 100644
--- a/Demos/Device/Incomplete/TestAndMeasurement/TestAndMeasurement.c
+++ b/Demos/Device/Incomplete/TestAndMeasurement/TestAndMeasurement.c
@@ -65,7 +65,13 @@ static bool IsTMCBulkOUTReset = false;
 static uint8_t CurrentTransferTag = 0;
 
 /** Length of last data transfer, for reporting to the host in case an in-progress transfer is aborted */
-static uint32_t LastTransferLength = 0;
+static uint16_t LastTransferLength = 0;
+
+/** Buffer to hold the next message to sent to the TMC host */
+static uint8_t NextResponseBuffer[64];
+
+/** Indicates the length of the next response to send */
+static uint8_t NextReponseLen;
 
 /** Main program entry point. This routine contains the overall program flow, including initial
  *  setup of all components and the main program loop.
@@ -318,6 +324,27 @@ void EVENT_USB_Device_ControlRequest(void)
 	}
 }
 
+void ProcessSentMessage(uint8_t* const Data, const uint8_t Length)
+{
+	if (strncmp((char*)Data, "*IDN?", 5) == 0)
+	  strcpy((char*)NextResponseBuffer, "LUFA TMC DEMO");
+
+	NextReponseLen = strlen((char*)NextResponseBuffer);
+}
+
+uint8_t GetNextMessage(uint8_t* const Data)
+{
+	  strcpy((char*)NextResponseBuffer, "LUFA TMC DEMO");
+
+	NextReponseLen = strlen((char*)NextResponseBuffer);
+// ---
+	uint8_t DataLen = MIN(NextReponseLen, 64);
+
+	strlcpy((char*)Data, (char*)NextResponseBuffer, DataLen);
+
+	return DataLen;
+}
+
 /** Function to manage TMC data transmission and reception to and from the host. */
 void TMC_Task(void)
 {
@@ -326,7 +353,7 @@ void TMC_Task(void)
 	  return;
 	
 	TMC_MessageHeader_t MessageHeader;
-	uint16_t            BytesTransferred;
+	uint8_t             MessagePayload[128];
 	
 	/* Try to read in a TMC message from the interface, process if one is available */
 	if (ReadTMCHeader(&MessageHeader))
@@ -337,34 +364,32 @@ void TMC_Task(void)
 		switch (MessageHeader.MessageID)
 		{
 			case TMC_MESSAGEID_DEV_DEP_MSG_OUT:
-				BytesTransferred = 0;
-				while (Endpoint_Discard_Stream(MessageHeader.TransferSize, &BytesTransferred) ==
+				LastTransferLength = 0;
+				while (Endpoint_Read_Stream_LE(MessagePayload, MIN(MessageHeader.TransferSize, sizeof(MessagePayload)), &LastTransferLength) ==
 				       ENDPOINT_RWSTREAM_IncompleteTransfer)
 				{
 					if (IsTMCBulkOUTReset)
 					  break;
 				}
-				LastTransferLength = BytesTransferred;
 				
 				Endpoint_ClearOUT();
+
+				ProcessSentMessage(MessagePayload, LastTransferLength);				
 				break;
 			case TMC_MESSAGEID_DEV_DEP_MSG_IN:
 				Endpoint_ClearOUT();
 				
-				char MessageData[] = "TMC Class Test";
-
-				MessageHeader.TransferSize = strlen(MessageData);
+				MessageHeader.TransferSize = GetNextMessage(MessagePayload);				
 				MessageHeader.MessageIDSpecific.DeviceOUT.LastMessageTransaction = true;
 				WriteTMCHeader(&MessageHeader);
 
-				BytesTransferred = 0;
-				while (Endpoint_Write_Stream_LE(MessageData, MessageHeader.TransferSize, &BytesTransferred) ==
+				LastTransferLength = 0;
+				while (Endpoint_Write_Stream_LE(MessagePayload, MessageHeader.TransferSize, &LastTransferLength) ==
 				       ENDPOINT_RWSTREAM_IncompleteTransfer)
 				{
 					if (IsTMCBulkINReset)
 					  break;
 				}
-				LastTransferLength = BytesTransferred;
 
 				Endpoint_ClearIN();
 				break;
diff --git a/Demos/Device/Incomplete/TestAndMeasurement/TestAndMeasurement.h b/Demos/Device/Incomplete/TestAndMeasurement/TestAndMeasurement.h
index 53f32a2ae..7177f1843 100644
--- a/Demos/Device/Incomplete/TestAndMeasurement/TestAndMeasurement.h
+++ b/Demos/Device/Incomplete/TestAndMeasurement/TestAndMeasurement.h
@@ -108,19 +108,15 @@
 		
 		typedef struct
 		{
-			unsigned LastMessageTransaction     : 1;
-			unsigned Reserved                   : 7;
-
-			uint8_t Reserved2[3];
+			uint8_t LastMessageTransaction;
+			uint8_t TermChar;
+			uint8_t Reserved[2];
 		} TMC_DevOUTMessageHeader_t;
 
 		typedef struct
 		{
-			unsigned TermCharEnabled            : 1;
-			unsigned Reserved                   : 7;
-
-			uint8_t TermChar;
-			uint8_t Reserved2[2];
+			uint8_t LastMessageTransaction;
+			uint8_t Reserved[3];
 		} TMC_DevINMessageHeader_t;
 
 		typedef struct
diff --git a/LUFA/Common/CompilerSpecific.h b/LUFA/Common/CompilerSpecific.h
index 6b4826aa5..938cbe66c 100644
--- a/LUFA/Common/CompilerSpecific.h
+++ b/LUFA/Common/CompilerSpecific.h
@@ -70,26 +70,26 @@
 				 *
 				 *  \param[in, out] StructPtr  Pointer to a structure which is to be forced into indirect access mode.
 				 */
-				#define GCC_FORCE_POINTER_ACCESS(StructPtr) __asm__ __volatile__("" : "=b" (StructPtr) : "0" (StructPtr))
+				#define GCC_FORCE_POINTER_ACCESS(StructPtr)   __asm__ __volatile__("" : "=b" (StructPtr) : "0" (StructPtr))
 
 				/** Forces GCC to create a memory barrier, ensuring that memory accesses are not reordered past the barrier point.
 				 *  This can be used before ordering-critical operations, to ensure that the compiler does not re-order the resulting
 				 *  assembly output in an unexpected manner on sections of code that are ordering-specific.
 				 */
-				#define GCC_MEMORY_BARRIER()                __asm__ __volatile__("" ::: "memory");
+				#define GCC_MEMORY_BARRIER()                  __asm__ __volatile__("" ::: "memory");
 				
 				/** Evaluates to boolean true if the specified value can be determined at compile time to be a constant value
 				 *  when compiling under GCC.
 				 *
 				 *  \param[in] x  Value to check compile time constantness of.
 				 *
-				 *  \return Boolean true if the given value is known to be a compile time constant.
+				 *  \return Boolean true if the given value is known to be a compile time constant, false otherwise.
 				 */
-				#define GCC_IS_COMPILE_CONST(x)             __builtin_constant_p(x)
+				#define GCC_IS_COMPILE_CONST(x)               __builtin_constant_p(x)
 			#else
 				#define GCC_FORCE_POINTER_ACCESS(StructPtr)
 				#define GCC_MEMORY_BARRIER()
-				#define GCC_IS_COMPILE_CONST(x)             0
+				#define GCC_IS_COMPILE_CONST(x)               0
 			#endif
 
 #endif
diff --git a/LUFA/Common/Endianness.h b/LUFA/Common/Endianness.h
index 123ad425f..e26314975 100644
--- a/LUFA/Common/Endianness.h
+++ b/LUFA/Common/Endianness.h
@@ -394,6 +394,9 @@
 			static inline uint16_t SwapEndian_16(const uint16_t Word) ATTR_WARN_UNUSED_RESULT ATTR_CONST;
 			static inline uint16_t SwapEndian_16(const uint16_t Word)
 			{
+				if (GCC_IS_COMPILE_CONST(Word))
+				  return SWAPENDIAN_16(Word);
+			
 				uint8_t Temp;
 
 				union
@@ -420,6 +423,9 @@
 			static inline uint32_t SwapEndian_32(const uint32_t DWord) ATTR_WARN_UNUSED_RESULT ATTR_CONST;
 			static inline uint32_t SwapEndian_32(const uint32_t DWord)
 			{
+				if (GCC_IS_COMPILE_CONST(DWord))
+				  return SWAPENDIAN_32(DWord);
+
 				uint8_t Temp;
 
 				union
diff --git a/LUFA/ManPages/ChangeLog.txt b/LUFA/ManPages/ChangeLog.txt
index e6b279ed4..1bf8dae2a 100644
--- a/LUFA/ManPages/ChangeLog.txt
+++ b/LUFA/ManPages/ChangeLog.txt
@@ -75,6 +75,7 @@
   *   - Fixed KeyboardHost and KeyboardHostWithParser demos displaying incorrect values when numerical keys were pressed
   *   - Fixed compile errors in the incomplete BluetoothHost demo application (thanks to Timo Lindfors)
   *   - Fixed incorrect Dataflash buffer use in the DataflashManager_WriteBlocks_RAM() function of several demos/projects (thanks to Jeremy Willden)
+  *   - Fixed incorrect logging interval (always 500ms longer than requested) in the TempDataLogger project
   *
   *  \section Sec_ChangeLog110528 Version 110528
   *  <b>New:</b>
-- 
GitLab