From 34781781278f0fb2557b7c5dd9c0de54ad2aba09 Mon Sep 17 00:00:00 2001 From: Dean Camera 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 039736a28d..3b8c295864 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 53f32a2aeb..7177f18434 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 6b4826aa51..938cbe66c8 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 123ad425f4..e263149753 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 e6b279ed42..1bf8dae2a4 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 * New: