From: Dean Camera Date: Fri, 27 May 2011 03:33:40 +0000 (+0000) Subject: Merge over trunk changes to the 110528 BETA to form the 110528 release. X-Git-Tag: LUFA-110528~1 X-Git-Url: http://git.linex4red.de/pub/USBasp.git/commitdiff_plain/397c2f913668b9806b2388ed55c421147c2c9230 Merge over trunk changes to the 110528 BETA to form the 110528 release. --- diff --git a/Bootloaders/CDC/BootloaderCDC.c b/Bootloaders/CDC/BootloaderCDC.c index 8e6a58b0a..7695e33d8 100644 --- a/Bootloaders/CDC/BootloaderCDC.c +++ b/Bootloaders/CDC/BootloaderCDC.c @@ -66,6 +66,9 @@ int main(void) /* Setup hardware required for the bootloader */ SetupHardware(); + /* Turn on first LED on the board to indicate that the bootloader has started */ + LEDs_SetAllLEDs(LEDS_LED1); + /* Enable global interrupts so that the USB stack can function */ sei(); @@ -100,6 +103,17 @@ void SetupHardware(void) /* Initialize USB Subsystem */ USB_Init(); + LEDs_Init(); + + /* Bootloader active LED toggle timer initialization */ + TIMSK1 = (1 << TOIE1); + TCCR1B = ((1 << CS11) | (1 << CS10)); +} + +/** ISR to periodically toggle the LEDs on the board to indicate that the bootloader is active. */ +ISR(TIMER1_OVF_vect, ISR_BLOCK) +{ + LEDs_ToggleLEDs(LEDS_LED1 | LEDS_LED2); } /** Event handler for the USB_ConfigurationChanged event. This configures the device's endpoints ready @@ -134,6 +148,9 @@ void EVENT_USB_Device_ControlRequest(void) return; } + /* Activity - toggle indicator LEDs */ + LEDs_ToggleLEDs(LEDS_LED1 | LEDS_LED2); + /* Process CDC specific control requests */ switch (USB_ControlRequest.bRequest) { diff --git a/Bootloaders/CDC/BootloaderCDC.h b/Bootloaders/CDC/BootloaderCDC.h index b6bea11e4..72bc1e773 100644 --- a/Bootloaders/CDC/BootloaderCDC.h +++ b/Bootloaders/CDC/BootloaderCDC.h @@ -48,6 +48,7 @@ #include "Descriptors.h" #include + #include /* Macros: */ /** Version major of the CDC bootloader. */ diff --git a/Bootloaders/DFU/BootloaderDFU.c b/Bootloaders/DFU/BootloaderDFU.c index 113bea748..fdd4d2de6 100644 --- a/Bootloaders/DFU/BootloaderDFU.c +++ b/Bootloaders/DFU/BootloaderDFU.c @@ -119,6 +119,9 @@ int main(void) MCUCR &= ~(1 << JTD); #endif + /* Turn on first LED on the board to indicate that the bootloader has started */ + LEDs_SetAllLEDs(LEDS_LED1); + /* Enable global interrupts so that the USB stack can function */ sei(); @@ -149,6 +152,11 @@ void SetupHardware(void) /* Initialize the USB subsystem */ USB_Init(); + LEDs_Init(); + + /* Bootloader active LED toggle timer initialization */ + TIMSK1 = (1 << TOIE1); + TCCR1B = ((1 << CS11) | (1 << CS10)); } /** Resets all configured hardware required for the bootloader back to their original states. */ @@ -162,15 +170,18 @@ void ResetHardware(void) MCUCR = 0; } +/** ISR to periodically toggle the LEDs on the board to indicate that the bootloader is active. */ +ISR(TIMER1_OVF_vect, ISR_BLOCK) +{ + LEDs_ToggleLEDs(LEDS_LED1 | LEDS_LED2); +} + /** Event handler for the USB_ControlRequest event. This is used to catch and process control requests sent to * the device from the USB host before passing along unhandled control requests to the library for processing * internally. */ void EVENT_USB_Device_ControlRequest(void) -{ - /* Get the size of the command and data from the wLength value */ - SentCommand.DataSize = USB_ControlRequest.wLength; - +{ /* Ignore any requests that aren't directed to the DFU interface */ if ((USB_ControlRequest.bmRequestType & (CONTROL_REQTYPE_TYPE | CONTROL_REQTYPE_RECIPIENT)) != (REQTYPE_CLASS | REQREC_INTERFACE)) @@ -178,6 +189,12 @@ void EVENT_USB_Device_ControlRequest(void) return; } + /* Activity - toggle indicator LEDs */ + LEDs_ToggleLEDs(LEDS_LED1 | LEDS_LED2); + + /* Get the size of the command and data from the wLength value */ + SentCommand.DataSize = USB_ControlRequest.wLength; + switch (USB_ControlRequest.bRequest) { case DFU_REQ_DNLOAD: diff --git a/Bootloaders/DFU/BootloaderDFU.h b/Bootloaders/DFU/BootloaderDFU.h index 1c1ebba6c..8fbf64c7e 100644 --- a/Bootloaders/DFU/BootloaderDFU.h +++ b/Bootloaders/DFU/BootloaderDFU.h @@ -50,6 +50,7 @@ #include "Descriptors.h" #include + #include /* Macros: */ /** Configuration define. Define this token to true to case the bootloader to reject all memory commands diff --git a/Bootloaders/HID/BootloaderHID.c b/Bootloaders/HID/BootloaderHID.c index f04804306..4a439544f 100644 --- a/Bootloaders/HID/BootloaderHID.c +++ b/Bootloaders/HID/BootloaderHID.c @@ -113,10 +113,18 @@ void EVENT_USB_Device_ControlRequest(void) while (!(Endpoint_IsOUTReceived())); /* Read in the write destination address */ + #if (FLASHEND > 0xFFFF) + uint32_t PageAddress = ((uint32_t)Endpoint_Read_16_LE() << 8); + #else uint16_t PageAddress = Endpoint_Read_16_LE(); + #endif /* Check if the command is a program page command, or a start application command */ + #if (FLASHEND > 0xFFFF) + if ((uint16_t)(PageAddress >> 8) == COMMAND_STARTAPPLICATION) + #else if (PageAddress == COMMAND_STARTAPPLICATION) + #endif { RunBootloader = false; } diff --git a/Demos/Device/ClassDriver/RNDISEthernet/Lib/DHCP.c b/Demos/Device/ClassDriver/RNDISEthernet/Lib/DHCP.c index 6bd920fd0..cc8861736 100644 --- a/Demos/Device/ClassDriver/RNDISEthernet/Lib/DHCP.c +++ b/Demos/Device/ClassDriver/RNDISEthernet/Lib/DHCP.c @@ -59,7 +59,7 @@ int16_t DHCP_ProcessDHCPPacket(void* IPHeaderInStart, DecodeDHCPHeader(DHCPHeaderInStart); - /* Zero out the response DHCP packet, as much of it legacy and left at 0 */ + /* Zero out the response DHCP packet, as much of it is legacy and left at 0 */ memset(DHCPHeaderOUT, 0, sizeof(DHCP_Header_t)); /* Fill out the response DHCP packet */ diff --git a/Demos/Device/ClassDriver/RNDISEthernet/Lib/Ethernet.c b/Demos/Device/ClassDriver/RNDISEthernet/Lib/Ethernet.c index 918b627a5..dacbdbf89 100644 --- a/Demos/Device/ClassDriver/RNDISEthernet/Lib/Ethernet.c +++ b/Demos/Device/ClassDriver/RNDISEthernet/Lib/Ethernet.c @@ -96,7 +96,6 @@ void Ethernet_ProcessPacket(Ethernet_Frame_Info_t* const FrameIN, /* Set the response length in the buffer and indicate that a response is ready to be sent */ FrameOUT->FrameLength = (sizeof(Ethernet_Frame_Header_t) + RetSize); - FrameOUT->FrameInBuffer = true; } } @@ -104,7 +103,7 @@ void Ethernet_ProcessPacket(Ethernet_Frame_Info_t* const FrameIN, if (RetSize != NO_PROCESS) { /* Clear the frame buffer */ - FrameIN->FrameInBuffer = false; + FrameIN->FrameLength = 0; } } diff --git a/Demos/Device/ClassDriver/RNDISEthernet/Lib/TCP.c b/Demos/Device/ClassDriver/RNDISEthernet/Lib/TCP.c index a748289a2..f6354f509 100644 --- a/Demos/Device/ClassDriver/RNDISEthernet/Lib/TCP.c +++ b/Demos/Device/ClassDriver/RNDISEthernet/Lib/TCP.c @@ -55,7 +55,8 @@ TCP_ConnectionState_t ConnectionStateTable[MAX_TCP_CONNECTIONS]; * level. If an application produces a response, this task constructs the appropriate Ethernet frame and places it into the Ethernet OUT * buffer for later transmission. */ -void TCP_TCPTask(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo) +void TCP_TCPTask(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo, + Ethernet_Frame_Info_t* const FrameOUT) { /* Run each application in sequence, to process incoming and generate outgoing packets */ for (uint8_t CSTableEntry = 0; CSTableEntry < MAX_TCP_CONNECTIONS; CSTableEntry++) @@ -73,11 +74,8 @@ void TCP_TCPTask(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo) } } - /* Get pointer to the output frame info struct for convenience */ - Ethernet_Frame_Info_t* FrameOUT = &RNDISInterfaceInfo->State.FrameOUT; - /* Bail out early if there is already a frame waiting to be sent in the Ethernet OUT buffer */ - if (FrameOUT->FrameInBuffer) + if (FrameOUT->FrameLength) return; /* Send response packets from each application as the TCP packet buffers are filled by the applications */ @@ -147,7 +145,6 @@ void TCP_TCPTask(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo) /* Set the response length in the buffer and indicate that a response is ready to be sent */ FrameOUT->FrameLength = PacketSize; - FrameOUT->FrameInBuffer = true; ConnectionStateTable[CSTableEntry].Info.Buffer.Ready = false; diff --git a/Demos/Device/ClassDriver/RNDISEthernet/Lib/TCP.h b/Demos/Device/ClassDriver/RNDISEthernet/Lib/TCP.h index cbb3c6eec..aad63a4fe 100644 --- a/Demos/Device/ClassDriver/RNDISEthernet/Lib/TCP.h +++ b/Demos/Device/ClassDriver/RNDISEthernet/Lib/TCP.h @@ -228,7 +228,8 @@ } TCP_Header_t; /* Function Prototypes: */ - void TCP_TCPTask(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo); + void TCP_TCPTask(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo, + Ethernet_Frame_Info_t* const FrameOUT); void TCP_Init(void); bool TCP_SetPortState(const uint16_t Port, const uint8_t State, diff --git a/Demos/Device/ClassDriver/RNDISEthernet/RNDISEthernet.c b/Demos/Device/ClassDriver/RNDISEthernet/RNDISEthernet.c index e14f3f1de..adcb2939a 100644 --- a/Demos/Device/ClassDriver/RNDISEthernet/RNDISEthernet.c +++ b/Demos/Device/ClassDriver/RNDISEthernet/RNDISEthernet.c @@ -63,6 +63,11 @@ USB_ClassInfo_RNDIS_Device_t Ethernet_RNDIS_Interface = }, }; +/** Global to store the incoming frame from the host before it is processed by the device. */ +static Ethernet_Frame_Info_t FrameIN; + +/** Global to store the outgoing frame created in the device before it is sent to the host. */ +static Ethernet_Frame_Info_t FrameOUT; /** Main program entry point. This routine contains the overall program flow, including initial * setup of all components and the main program loop. @@ -79,14 +84,23 @@ int main(void) for (;;) { - if (Ethernet_RNDIS_Interface.State.FrameIN.FrameInBuffer) + if (RNDIS_Device_IsPacketReceived(&Ethernet_RNDIS_Interface)) { LEDs_SetAllLEDs(LEDMASK_USB_BUSY); - Ethernet_ProcessPacket(&Ethernet_RNDIS_Interface.State.FrameIN, &Ethernet_RNDIS_Interface.State.FrameOUT); + + RNDIS_Device_ReadPacket(&Ethernet_RNDIS_Interface, &FrameIN.FrameData, &FrameIN.FrameLength); + Ethernet_ProcessPacket(&FrameIN, &FrameOUT); + + if (FrameOUT.FrameLength) + { + RNDIS_Device_SendPacket(&Ethernet_RNDIS_Interface, &FrameOUT.FrameData, FrameOUT.FrameLength); + FrameOUT.FrameLength = 0; + } + LEDs_SetAllLEDs(LEDMASK_USB_READY); } - TCP_TCPTask(&Ethernet_RNDIS_Interface); + TCP_TCPTask(&Ethernet_RNDIS_Interface, &FrameOUT); RNDIS_Device_USBTask(&Ethernet_RNDIS_Interface); USB_USBTask(); diff --git a/Demos/Device/LowLevel/RNDISEthernet/Lib/DHCP.c b/Demos/Device/LowLevel/RNDISEthernet/Lib/DHCP.c index 56668112e..5fce88a6f 100644 --- a/Demos/Device/LowLevel/RNDISEthernet/Lib/DHCP.c +++ b/Demos/Device/LowLevel/RNDISEthernet/Lib/DHCP.c @@ -59,7 +59,7 @@ int16_t DHCP_ProcessDHCPPacket(void* IPHeaderInStart, DecodeDHCPHeader(DHCPHeaderInStart); - /* Zero out the response DHCP packet, as much of it legacy and left at 0 */ + /* Zero out the response DHCP packet, as much of it is legacy and left at 0 */ memset(DHCPHeaderOUT, 0, sizeof(DHCP_Header_t)); /* Fill out the response DHCP packet */ diff --git a/Demos/Device/LowLevel/RNDISEthernet/Lib/Ethernet.c b/Demos/Device/LowLevel/RNDISEthernet/Lib/Ethernet.c index 488db7688..1e66cf03f 100644 --- a/Demos/Device/LowLevel/RNDISEthernet/Lib/Ethernet.c +++ b/Demos/Device/LowLevel/RNDISEthernet/Lib/Ethernet.c @@ -100,7 +100,6 @@ void Ethernet_ProcessPacket(void) /* Set the response length in the buffer and indicate that a response is ready to be sent */ FrameOUT.FrameLength = (sizeof(Ethernet_Frame_Header_t) + RetSize); - FrameOUT.FrameInBuffer = true; } } @@ -108,7 +107,7 @@ void Ethernet_ProcessPacket(void) if (RetSize != NO_PROCESS) { /* Clear the frame buffer */ - FrameIN.FrameInBuffer = false; + FrameIN.FrameLength = 0; } } diff --git a/Demos/Device/LowLevel/RNDISEthernet/Lib/TCP.c b/Demos/Device/LowLevel/RNDISEthernet/Lib/TCP.c index c773a6444..97c1355b2 100644 --- a/Demos/Device/LowLevel/RNDISEthernet/Lib/TCP.c +++ b/Demos/Device/LowLevel/RNDISEthernet/Lib/TCP.c @@ -74,7 +74,7 @@ void TCP_Task(void) } /* Bail out early if there is already a frame waiting to be sent in the Ethernet OUT buffer */ - if (FrameOUT.FrameInBuffer) + if (FrameOUT.FrameLength) return; /* Send response packets from each application as the TCP packet buffers are filled by the applications */ @@ -144,7 +144,6 @@ void TCP_Task(void) /* Set the response length in the buffer and indicate that a response is ready to be sent */ FrameOUT.FrameLength = PacketSize; - FrameOUT.FrameInBuffer = true; ConnectionStateTable[CSTableEntry].Info.Buffer.Ready = false; diff --git a/Demos/Device/LowLevel/RNDISEthernet/RNDISEthernet.c b/Demos/Device/LowLevel/RNDISEthernet/RNDISEthernet.c index cc5f9e302..9ad26dd2f 100644 --- a/Demos/Device/LowLevel/RNDISEthernet/RNDISEthernet.c +++ b/Demos/Device/LowLevel/RNDISEthernet/RNDISEthernet.c @@ -204,7 +204,7 @@ void RNDIS_Task(void) Endpoint_SelectEndpoint(CDC_RX_EPNUM); /* Check if the data OUT endpoint contains data, and that the IN buffer is empty */ - if (Endpoint_IsOUTReceived() && !(FrameIN.FrameInBuffer)) + if (Endpoint_IsOUTReceived() && !(FrameIN.FrameLength)) { /* Read in the packet message header */ Endpoint_Read_Stream_LE(&RNDISPacketHeader, sizeof(RNDIS_Packet_Message_t), NULL); @@ -224,16 +224,13 @@ void RNDIS_Task(void) /* Store the size of the Ethernet frame */ FrameIN.FrameLength = RNDISPacketHeader.DataLength; - - /* Indicate Ethernet IN buffer full */ - FrameIN.FrameInBuffer = true; } /* Select the data IN endpoint */ Endpoint_SelectEndpoint(CDC_TX_EPNUM); /* Check if the data IN endpoint is ready for more data, and that the IN buffer is full */ - if (Endpoint_IsINReady() && FrameOUT.FrameInBuffer) + if (Endpoint_IsINReady() && FrameOUT.FrameLength) { /* Clear the packet header with all 0s so that the relevant fields can be filled */ memset(&RNDISPacketHeader, 0, sizeof(RNDIS_Packet_Message_t)); @@ -254,7 +251,7 @@ void RNDIS_Task(void) Endpoint_ClearIN(); /* Indicate Ethernet OUT buffer no longer full */ - FrameOUT.FrameInBuffer = false; + FrameOUT.FrameLength = 0; } } } @@ -273,7 +270,7 @@ void Ethernet_Task(void) return; /* Check if a frame has been written to the IN frame buffer */ - if (FrameIN.FrameInBuffer) + if (FrameIN.FrameLength) { /* Indicate packet processing started */ LEDs_SetAllLEDs(LEDMASK_USB_BUSY); diff --git a/LUFA/CodeTemplates/makefile_template.uc3 b/LUFA/CodeTemplates/makefile_template.uc3 index 843d775af..e56cb324a 100644 --- a/LUFA/CodeTemplates/makefile_template.uc3 +++ b/LUFA/CodeTemplates/makefile_template.uc3 @@ -236,9 +236,7 @@ ASFLAGS = $(ADEFS) -Wa,-adhlns=$(<:%.S=$(OBJDIR)/%.lst),-gstabs,--listing-cont-l # -Map: create map file # --cref: add cross reference to map file LDFLAGS = -Wl,-Map=$(TARGET).map,--cref -LDFLAGS += -Wl,--relax -LDFLAGS += -Wl,--gc-sections -LDFLAGS += -Wl,--rodata-writable +LDFLAGS += -Wl,--gc-sections --rodata-writable LDFLAGS += -Wl,--direct-data #LDFLAGS += -T linker_script.x diff --git a/LUFA/Common/Common.h b/LUFA/Common/Common.h index e349063da..b66aaa381 100644 --- a/LUFA/Common/Common.h +++ b/LUFA/Common/Common.h @@ -73,7 +73,10 @@ /* Architecture specific utility includes: */ #if defined(__DOXYGEN__) - /** Type define for an unsigned integer the same width as the selected architecture's machine register. */ + /** Type define for an unsigned integer the same width as the selected architecture's machine register. + * This is distinct from the non-specific standard int data type, whose width is machine dependant but + * which may not reflect the actual machine register width on some targets (e.g. AVR8). + */ typedef MACHINE_REG_t uint_reg_t; #elif (ARCH == ARCH_AVR8) #include diff --git a/LUFA/Common/Endianness.h b/LUFA/Common/Endianness.h index ef8c1a788..115d054f2 100644 --- a/LUFA/Common/Endianness.h +++ b/LUFA/Common/Endianness.h @@ -78,7 +78,7 @@ * * \return Input value with the byte ordering reversed. */ - #define SWAPENDIAN_16(x) ((((x) & 0xFF00) >> 8) | (((x) & 0x00FF) << 8)) + #define SWAPENDIAN_16(x) (uint16_t)((((x) & 0xFF00) >> 8) | (((x) & 0x00FF) << 8)) /** Swaps the byte ordering of a 32-bit value at compile-time. Do not use this macro for swapping byte orderings * of dynamic values computed at runtime- use \ref SwapEndian_32() instead. The result of this macro can be used @@ -91,8 +91,8 @@ * * \return Input value with the byte ordering reversed. */ - #define SWAPENDIAN_32(x) ((((x) & 0xFF000000UL) >> 24UL) | (((x) & 0x00FF0000UL) >> 8UL) | \ - (((x) & 0x0000FF00UL) << 8UL) | (((x) & 0x000000FFUL) << 24UL)) + #define SWAPENDIAN_32(x) (uint32_t)((((x) & 0xFF000000UL) >> 24UL) | (((x) & 0x00FF0000UL) >> 8UL) | \ + (((x) & 0x0000FF00UL) << 8UL) | (((x) & 0x000000FFUL) << 24UL)) #if defined(ARCH_BIG_ENDIAN) && !defined(le16_to_cpu) #define le16_to_cpu(x) SwapEndian_16(x) diff --git a/LUFA/Drivers/USB/Class/Common/CDC.h b/LUFA/Drivers/USB/Class/Common/CDC.h index 91686d86e..e74b0f1dd 100644 --- a/LUFA/Drivers/USB/Class/Common/CDC.h +++ b/LUFA/Drivers/USB/Class/Common/CDC.h @@ -145,10 +145,10 @@ CDC_CSCP_ATCommandProtocol = 0x01, /**< Descriptor Protocol value indicating that the device or interface * belongs to the AT Command protocol of the CDC class. */ - CDC_CSCP_NoSpecificProtocol = 0x00, /**< Descriptor Class value indicating that the device or interface + CDC_CSCP_NoSpecificProtocol = 0x00, /**< Descriptor Protocol value indicating that the device or interface * belongs to no specific protocol of the CDC class. */ - CDC_CSCP_VendorSpecificProtocol = 0xFF, /**< Descriptor Class value indicating that the device or interface + CDC_CSCP_VendorSpecificProtocol = 0xFF, /**< Descriptor Protocol value indicating that the device or interface * belongs to a vendor-specific protocol of the CDC class. */ CDC_CSCP_CDCDataClass = 0x0A, /**< Descriptor Class value indicating that the device or interface diff --git a/LUFA/Drivers/USB/Class/Common/RNDIS.h b/LUFA/Drivers/USB/Class/Common/RNDIS.h index f98fc6d81..0ca50d5af 100644 --- a/LUFA/Drivers/USB/Class/Common/RNDIS.h +++ b/LUFA/Drivers/USB/Class/Common/RNDIS.h @@ -68,6 +68,9 @@ #endif /* Macros: */ + /** Additional error code for RNDIS functions when a device returns a logical command failure. */ + #define RNDIS_ERROR_LOGICAL_CMD_FAILED 0x80 + /** Implemented RNDIS Version Major. */ #define REMOTE_NDIS_VERSION_MAJOR 0x01 @@ -205,25 +208,25 @@ }; /* Type Defines: */ - /** \brief MAC Address Structure. + /** \brief Ethernet Frame Packet Information Structure. * - * Type define for a physical MAC address of a device on a network. + * Type define for an Ethernet frame buffer data and information structure. This can be used to conveniently + * store both the size and data in an Ethernet frame. */ typedef struct { - uint8_t Octets[6]; /**< Individual bytes of a MAC address */ - } ATTR_PACKED MAC_Address_t; + uint8_t FrameData[ETHERNET_FRAME_SIZE_MAX]; /**< Ethernet frame contents. */ + uint16_t FrameLength; /**< Length in bytes of the Ethernet frame stored in the buffer. */ + } Ethernet_Frame_Info_t; - /** \brief RNDIS Ethernet Frame Packet Information Structure. + /** \brief MAC Address Structure. * - * Type define for an Ethernet frame buffer data and information structure. + * Type define for a physical MAC address of a device on a network. */ typedef struct { - uint8_t FrameData[ETHERNET_FRAME_SIZE_MAX]; /**< Ethernet frame contents. */ - uint16_t FrameLength; /**< Length in bytes of the Ethernet frame stored in the buffer. */ - bool FrameInBuffer; /**< Indicates if a frame is currently stored in the buffer. */ - } ATTR_PACKED Ethernet_Frame_Info_t; + uint8_t Octets[6]; /**< Individual bytes of a MAC address */ + } ATTR_PACKED MAC_Address_t; /** \brief RNDIS Common Message Header Structure. * diff --git a/LUFA/Drivers/USB/Class/Device/RNDIS.c b/LUFA/Drivers/USB/Class/Device/RNDIS.c index 616af5f7d..a9bbcfaba 100644 --- a/LUFA/Drivers/USB/Class/Device/RNDIS.c +++ b/LUFA/Drivers/USB/Class/Device/RNDIS.c @@ -163,8 +163,6 @@ void RNDIS_Device_USBTask(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo if (USB_DeviceState != DEVICE_STATE_Configured) return; - RNDIS_Message_Header_t* MessageHeader = (RNDIS_Message_Header_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer; - Endpoint_SelectEndpoint(RNDISInterfaceInfo->Config.NotificationEndpointNumber); if (Endpoint_IsINReady() && RNDISInterfaceInfo->State.ResponseReady) @@ -184,50 +182,6 @@ void RNDIS_Device_USBTask(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo RNDISInterfaceInfo->State.ResponseReady = false; } - - if ((RNDISInterfaceInfo->State.CurrRNDISState == RNDIS_Data_Initialized) && !(MessageHeader->MessageLength)) - { - RNDIS_Packet_Message_t RNDISPacketHeader; - - Endpoint_SelectEndpoint(RNDISInterfaceInfo->Config.DataOUTEndpointNumber); - - if (Endpoint_IsOUTReceived() && !(RNDISInterfaceInfo->State.FrameIN.FrameInBuffer)) - { - Endpoint_Read_Stream_LE(&RNDISPacketHeader, sizeof(RNDIS_Packet_Message_t), NULL); - - if (RNDISPacketHeader.DataLength > ETHERNET_FRAME_SIZE_MAX) - { - Endpoint_StallTransaction(); - return; - } - - Endpoint_Read_Stream_LE(RNDISInterfaceInfo->State.FrameIN.FrameData, RNDISPacketHeader.DataLength, NULL); - - Endpoint_ClearOUT(); - - RNDISInterfaceInfo->State.FrameIN.FrameLength = RNDISPacketHeader.DataLength; - - RNDISInterfaceInfo->State.FrameIN.FrameInBuffer = true; - } - - Endpoint_SelectEndpoint(RNDISInterfaceInfo->Config.DataINEndpointNumber); - - if (Endpoint_IsINReady() && RNDISInterfaceInfo->State.FrameOUT.FrameInBuffer) - { - memset(&RNDISPacketHeader, 0, sizeof(RNDIS_Packet_Message_t)); - - RNDISPacketHeader.MessageType = REMOTE_NDIS_PACKET_MSG; - RNDISPacketHeader.MessageLength = (sizeof(RNDIS_Packet_Message_t) + RNDISInterfaceInfo->State.FrameOUT.FrameLength); - RNDISPacketHeader.DataOffset = (sizeof(RNDIS_Packet_Message_t) - sizeof(RNDIS_Message_Header_t)); - RNDISPacketHeader.DataLength = RNDISInterfaceInfo->State.FrameOUT.FrameLength; - - Endpoint_Write_Stream_LE(&RNDISPacketHeader, sizeof(RNDIS_Packet_Message_t), NULL); - Endpoint_Write_Stream_LE(RNDISInterfaceInfo->State.FrameOUT.FrameData, RNDISPacketHeader.DataLength, NULL); - Endpoint_ClearIN(); - - RNDISInterfaceInfo->State.FrameOUT.FrameInBuffer = false; - } - } } void RNDIS_Device_ProcessRNDISControlMessage(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo) @@ -493,5 +447,85 @@ static bool RNDIS_Device_ProcessNDISSet(USB_ClassInfo_RNDIS_Device_t* const RNDI } } +bool RNDIS_Device_IsPacketReceived(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo) +{ + if ((USB_DeviceState != DEVICE_STATE_Configured) || + (RNDISInterfaceInfo->State.CurrRNDISState != RNDIS_Data_Initialized)) + { + return false; + } + + Endpoint_SelectEndpoint(RNDISInterfaceInfo->Config.DataOUTEndpointNumber); + return Endpoint_IsOUTReceived(); +} + +uint8_t RNDIS_Device_ReadPacket(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo, + void* Buffer, + uint16_t* const PacketLength) +{ + if ((USB_DeviceState != DEVICE_STATE_Configured) || + (RNDISInterfaceInfo->State.CurrRNDISState != RNDIS_Data_Initialized)) + { + return ENDPOINT_RWSTREAM_DeviceDisconnected; + } + + Endpoint_SelectEndpoint(RNDISInterfaceInfo->Config.DataOUTEndpointNumber); + + *PacketLength = 0; + + if (!(Endpoint_IsOUTReceived())) + return ENDPOINT_RWSTREAM_NoError; + + RNDIS_Packet_Message_t RNDISPacketHeader; + Endpoint_Read_Stream_LE(&RNDISPacketHeader, sizeof(RNDIS_Packet_Message_t), NULL); + + if (RNDISPacketHeader.DataLength > ETHERNET_FRAME_SIZE_MAX) + { + Endpoint_StallTransaction(); + + return RNDIS_ERROR_LOGICAL_CMD_FAILED; + } + + *PacketLength = (uint16_t)RNDISPacketHeader.DataLength; + + Endpoint_Read_Stream_LE(Buffer, RNDISPacketHeader.DataLength, NULL); + Endpoint_ClearOUT(); + + return ENDPOINT_RWSTREAM_NoError; +} + +uint8_t RNDIS_Device_SendPacket(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo, + void* Buffer, + const uint16_t PacketLength) +{ + uint8_t ErrorCode; + + if ((USB_DeviceState != DEVICE_STATE_Configured) || + (RNDISInterfaceInfo->State.CurrRNDISState != RNDIS_Data_Initialized)) + { + return ENDPOINT_RWSTREAM_DeviceDisconnected; + } + + Endpoint_SelectEndpoint(RNDISInterfaceInfo->Config.DataINEndpointNumber); + + if ((ErrorCode = Endpoint_WaitUntilReady()) != ENDPOINT_READYWAIT_NoError) + return ErrorCode; + + RNDIS_Packet_Message_t RNDISPacketHeader; + + memset(&RNDISPacketHeader, 0, sizeof(RNDIS_Packet_Message_t)); + + RNDISPacketHeader.MessageType = REMOTE_NDIS_PACKET_MSG; + RNDISPacketHeader.MessageLength = (sizeof(RNDIS_Packet_Message_t) + PacketLength); + RNDISPacketHeader.DataOffset = (sizeof(RNDIS_Packet_Message_t) - sizeof(RNDIS_Message_Header_t)); + RNDISPacketHeader.DataLength = PacketLength; + + Endpoint_Write_Stream_LE(&RNDISPacketHeader, sizeof(RNDIS_Packet_Message_t), NULL); + Endpoint_Write_Stream_LE(Buffer, PacketLength, NULL); + Endpoint_ClearIN(); + + return ENDPOINT_RWSTREAM_NoError; +} + #endif diff --git a/LUFA/Drivers/USB/Class/Device/RNDIS.h b/LUFA/Drivers/USB/Class/Device/RNDIS.h index f53a8e01f..734ceb3fd 100644 --- a/LUFA/Drivers/USB/Class/Device/RNDIS.h +++ b/LUFA/Drivers/USB/Class/Device/RNDIS.h @@ -106,12 +106,6 @@ bool ResponseReady; /**< Internal flag indicating if a RNDIS message is waiting to be returned to the host. */ uint8_t CurrRNDISState; /**< Current RNDIS state of the adapter, a value from the \ref RNDIS_States_t enum. */ uint32_t CurrPacketFilter; /**< Current packet filter mode, used internally by the class driver. */ - Ethernet_Frame_Info_t FrameIN; /**< Structure holding the last received Ethernet frame from the host, for user - * processing. - */ - Ethernet_Frame_Info_t FrameOUT; /**< Structure holding the next Ethernet frame to send to the host, populated by the - * user application. - */ } State; /**< State data for the USB class interface within the device. All elements in this section * are reset to their defaults when the interface is enumerated. */ @@ -146,6 +140,48 @@ */ void RNDIS_Device_USBTask(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); + /** Determines if a packet is currently waiting for the device to read in and process. + * + * \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or the + * call will fail. + * + * \param[in,out] RNDISInterfaceInfo Pointer to a structure containing an RNDIS Class configuration and state. + * + * \return Boolean \c true if a packet is waiting to be read in by the host, \c false otherwise. + */ + bool RNDIS_Device_IsPacketReceived(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo); + + /** Retrieves the next pending packet from the device, discarding the remainder of the RNDIS packet header to leave + * only the packet contents for processing by the device in the nominated buffer. + * + * \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or the + * call will fail. + * + * \param[in,out] RNDISInterfaceInfo Pointer to a structure containing an RNDIS Class configuration and state. + * \param[out] Buffer Pointer to a buffer where the packer data is to be written to. + * \param[out] PacketLength Pointer to where the length in bytes of the read packet is to be stored. + * + * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. + */ + uint8_t RNDIS_Device_ReadPacket(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo, + void* Buffer, + uint16_t* const PacketLength); + + /** Sends the given packet to the attached RNDIS device, after adding a RNDIS packet message header. + * + * \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or the + * call will fail. + * + * \param[in,out] RNDISInterfaceInfo Pointer to a structure containing an RNDIS Class configuration and state. + * \param[in] Buffer Pointer to a buffer where the packer data is to be read from. + * \param[in] PacketLength Length in bytes of the packet to send. + * + * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. + */ + uint8_t RNDIS_Device_SendPacket(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo, + void* Buffer, + const uint16_t PacketLength); + /* Private Interface - For use in library only: */ #if !defined(__DOXYGEN__) /* Function Prototypes: */ diff --git a/LUFA/Drivers/USB/Class/Host/RNDIS.c b/LUFA/Drivers/USB/Class/Host/RNDIS.c index 23497574c..a75adcc97 100644 --- a/LUFA/Drivers/USB/Class/Host/RNDIS.c +++ b/LUFA/Drivers/USB/Class/Host/RNDIS.c @@ -315,7 +315,7 @@ uint8_t RNDIS_Host_InitializeDevice(USB_ClassInfo_RNDIS_Host_t* const RNDISInter } if (InitMessageResponse.Status != REMOTE_NDIS_STATUS_SUCCESS) - return RNDIS_COMMAND_FAILED; + return RNDIS_ERROR_LOGICAL_CMD_FAILED; RNDISInterfaceInfo->State.DeviceMaxPacketSize = InitMessageResponse.MaxTransferSize; @@ -361,7 +361,7 @@ uint8_t RNDIS_Host_SetRNDISProperty(USB_ClassInfo_RNDIS_Host_t* const RNDISInter } if (SetMessageResponse.Status != REMOTE_NDIS_STATUS_SUCCESS) - return RNDIS_COMMAND_FAILED; + return RNDIS_ERROR_LOGICAL_CMD_FAILED; return HOST_SENDCONTROL_Successful; } @@ -403,7 +403,7 @@ uint8_t RNDIS_Host_QueryRNDISProperty(USB_ClassInfo_RNDIS_Host_t* const RNDISInt } if (QueryMessageResponseData.QueryMessageResponse.Status != REMOTE_NDIS_STATUS_SUCCESS) - return RNDIS_COMMAND_FAILED; + return RNDIS_ERROR_LOGICAL_CMD_FAILED; memcpy(Buffer, &QueryMessageResponseData.ContiguousBuffer, MaxLength); @@ -458,7 +458,8 @@ uint8_t RNDIS_Host_ReadPacket(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceIn *PacketLength = (uint16_t)DeviceMessage.DataLength; - Pipe_Discard_Stream(DeviceMessage.DataOffset - (sizeof(RNDIS_Packet_Message_t) - sizeof(RNDIS_Message_Header_t)), + Pipe_Discard_Stream(DeviceMessage.DataOffset - + (sizeof(RNDIS_Packet_Message_t) - sizeof(RNDIS_Message_Header_t)), NULL); Pipe_Read_Stream_LE(Buffer, *PacketLength, NULL); diff --git a/LUFA/Drivers/USB/Class/Host/RNDIS.h b/LUFA/Drivers/USB/Class/Host/RNDIS.h index 376cc5925..41b235bdf 100644 --- a/LUFA/Drivers/USB/Class/Host/RNDIS.h +++ b/LUFA/Drivers/USB/Class/Host/RNDIS.h @@ -124,10 +124,6 @@ RNDIS_ENUMERROR_PipeConfigurationFailed = 3, /**< One or more pipes for the specified interface could not be configured correctly. */ }; - /* Macros: */ - /** Additional error code for RNDIS functions when a device returns a logical command failure. */ - #define RNDIS_COMMAND_FAILED 0xC0 - /* Function Prototypes: */ /** Host interface configuration routine, to configure a given RNDIS host interface instance using the Configuration * Descriptor read from an attached USB device. This function automatically updates the given RNDIS Host instance's @@ -154,7 +150,7 @@ * * \param[in,out] RNDISInterfaceInfo Pointer to a structure containing an RNDIS Class host configuration and state. * - * \return A value from the \ref USB_Host_SendControlErrorCodes_t enum or \ref RNDIS_COMMAND_FAILED if the device returned a + * \return A value from the \ref USB_Host_SendControlErrorCodes_t enum or \ref RNDIS_ERROR_LOGICAL_CMD_FAILED if the device returned a * logical command failure. */ uint8_t RNDIS_Host_SendKeepAlive(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); @@ -164,8 +160,8 @@ * * \param[in,out] RNDISInterfaceInfo Pointer to a structure containing an RNDIS Class host configuration and state. * - * \return A value from the \ref USB_Host_SendControlErrorCodes_t enum or \ref RNDIS_COMMAND_FAILED if the device returned a - * logical command failure. + * \return A value from the \ref USB_Host_SendControlErrorCodes_t enum or \ref RNDIS_ERROR_LOGICAL_CMD_FAILED if the + * device returned a logical command failure. */ uint8_t RNDIS_Host_InitializeDevice(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); @@ -176,8 +172,8 @@ * \param[in] Buffer Pointer to where the property data is to be sourced from. * \param[in] Length Length in bytes of the property data to sent to the device. * - * \return A value from the \ref USB_Host_SendControlErrorCodes_t enum or \ref RNDIS_COMMAND_FAILED if the device returned a - * logical command failure. + * \return A value from the \ref USB_Host_SendControlErrorCodes_t enum or \ref RNDIS_ERROR_LOGICAL_CMD_FAILED if the + * device returned a logical command failure. */ uint8_t RNDIS_Host_SetRNDISProperty(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo, const uint32_t Oid, @@ -191,8 +187,8 @@ * \param[in] Buffer Pointer to where the property data is to be written to. * \param[in] MaxLength Length in bytes of the destination buffer size. * - * \return A value from the \ref USB_Host_SendControlErrorCodes_t enum or \ref RNDIS_COMMAND_FAILED if the device returned a - * logical command failure. + * \return A value from the \ref USB_Host_SendControlErrorCodes_t enum or \ref RNDIS_ERROR_LOGICAL_CMD_FAILED if the + * device returned a logical command failure. */ uint8_t RNDIS_Host_QueryRNDISProperty(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo, const uint32_t Oid, diff --git a/LUFA/Drivers/USB/Core/AVR8/Device_AVR8.h b/LUFA/Drivers/USB/Core/AVR8/Device_AVR8.h index f88c2f1b2..c98e17cd5 100644 --- a/LUFA/Drivers/USB/Core/AVR8/Device_AVR8.h +++ b/LUFA/Drivers/USB/Core/AVR8/Device_AVR8.h @@ -99,16 +99,22 @@ * On unsupported devices, this will evaluate to \ref NO_DESCRIPTOR and so will force the host to create a pseudo-serial * number for the device. */ - #define USE_INTERNAL_SERIAL 0xDC + #define USE_INTERNAL_SERIAL 0xDC /** Length of the device's unique internal serial number, in bits, if present on the selected microcontroller * model. */ - #define INTERNAL_SERIAL_LENGTH_BITS 80 + #define INTERNAL_SERIAL_LENGTH_BITS 80 + + /** Start address of the internal serial number, in the appropriate address space, if present on the selected microcontroller + * model. + */ + #define INTERNAL_SERIAL_START_ADDRESS 0x0E #else - #define USE_INTERNAL_SERIAL NO_DESCRIPTOR + #define USE_INTERNAL_SERIAL NO_DESCRIPTOR - #define INTERNAL_SERIAL_LENGTH_BITS 0 + #define INTERNAL_SERIAL_LENGTH_BITS 0 + #define INTERNAL_SERIAL_START_ADDRESS 0 #endif /* Function Prototypes: */ @@ -198,12 +204,13 @@ return (UDADDR & (1 << ADDEN)); } - static inline void USB_Device_GetSerialString(uint16_t* UnicodeString) + #if (USE_INTERNAL_SERIAL != NO_DESCRIPTOR) + static inline void USB_Device_GetSerialString(uint16_t* const UnicodeString) { uint_reg_t CurrentGlobalInt = GetGlobalInterruptMask(); GlobalInterruptDisable(); - uint8_t SigReadAddress = 0x0E; + uint8_t SigReadAddress = INTERNAL_SERIAL_START_ADDRESS; for (uint8_t SerialCharNum = 0; SerialCharNum < (INTERNAL_SERIAL_LENGTH_BITS / 4); SerialCharNum++) { @@ -223,7 +230,8 @@ SetGlobalInterruptMask(CurrentGlobalInt); } - + #endif + #endif #endif diff --git a/LUFA/Drivers/USB/Core/AVR8/USBController_AVR8.h b/LUFA/Drivers/USB/Core/AVR8/USBController_AVR8.h index a6e0067e3..6be41fd96 100644 --- a/LUFA/Drivers/USB/Core/AVR8/USBController_AVR8.h +++ b/LUFA/Drivers/USB/Core/AVR8/USBController_AVR8.h @@ -119,14 +119,15 @@ /** \name USB Controller Option Masks */ //@{ /** Regulator disable option mask for \ref USB_Init(). This indicates that the internal 3.3V USB data pad - * regulator should be enabled to regulate the data pin voltages to within the USB standard. + * regulator should be disabled and the AVR's VCC level used for the data pads. * * \note See USB AVR data sheet for more information on the internal pad regulator. */ #define USB_OPT_REG_DISABLED (1 << 1) /** Regulator enable option mask for \ref USB_Init(). This indicates that the internal 3.3V USB data pad - * regulator should be disabled and the AVR's VCC level used for the data pads. + * regulator should be enabled to regulate the data pin voltages from the VBUS level down to a level within + * the range allowable by the USB standard. * * \note See USB AVR data sheet for more information on the internal pad regulator. */ diff --git a/LUFA/Drivers/USB/Core/ConfigDescriptor.c b/LUFA/Drivers/USB/Core/ConfigDescriptor.c index 9671659d6..a7f4d3ba0 100644 --- a/LUFA/Drivers/USB/Core/ConfigDescriptor.c +++ b/LUFA/Drivers/USB/Core/ConfigDescriptor.c @@ -32,8 +32,10 @@ #include "ConfigDescriptor.h" #if defined(USB_CAN_BE_HOST) -uint8_t USB_Host_GetDeviceConfigDescriptor(uint8_t ConfigNumber, uint16_t* const ConfigSizePtr, - void* BufferPtr, uint16_t BufferSize) +uint8_t USB_Host_GetDeviceConfigDescriptor(const uint8_t ConfigNumber, + uint16_t* const ConfigSizePtr, + void* const BufferPtr, + const uint16_t BufferSize) { uint8_t ErrorCode; uint8_t ConfigHeader[sizeof(USB_Descriptor_Configuration_Header_t)]; @@ -114,7 +116,9 @@ void USB_GetNextDescriptorOfTypeAfter(uint16_t* const BytesRem, USB_GetNextDescriptorOfType(BytesRem, CurrConfigLoc, Type); } -uint8_t USB_GetNextDescriptorComp(uint16_t* const BytesRem, void** const CurrConfigLoc, ConfigComparatorPtr_t const ComparatorRoutine) +uint8_t USB_GetNextDescriptorComp(uint16_t* const BytesRem, + void** const CurrConfigLoc, + const ConfigComparatorPtr_t const ComparatorRoutine) { uint8_t ErrorCode; diff --git a/LUFA/Drivers/USB/Core/ConfigDescriptor.h b/LUFA/Drivers/USB/Core/ConfigDescriptor.h index 54bf14dad..634dc8ff9 100644 --- a/LUFA/Drivers/USB/Core/ConfigDescriptor.h +++ b/LUFA/Drivers/USB/Core/ConfigDescriptor.h @@ -166,8 +166,10 @@ * * \return A value from the \ref USB_Host_GetConfigDescriptor_ErrorCodes_t enum. */ - uint8_t USB_Host_GetDeviceConfigDescriptor(uint8_t ConfigNumber, uint16_t* const ConfigSizePtr, void* BufferPtr, - uint16_t BufferSize) ATTR_NON_NULL_PTR_ARG(2) ATTR_NON_NULL_PTR_ARG(3); + uint8_t USB_Host_GetDeviceConfigDescriptor(const uint8_t ConfigNumber, + uint16_t* const ConfigSizePtr, + void* const BufferPtr, + const uint16_t BufferSize) ATTR_NON_NULL_PTR_ARG(2) ATTR_NON_NULL_PTR_ARG(3); /** Skips to the next sub-descriptor inside the configuration descriptor of the specified type value. * The bytes remaining value is automatically decremented. @@ -254,7 +256,7 @@ */ uint8_t USB_GetNextDescriptorComp(uint16_t* const BytesRem, void** const CurrConfigLoc, - ConfigComparatorPtr_t const ComparatorRoutine); + const ConfigComparatorPtr_t const ComparatorRoutine); /* Inline Functions: */ /** Skips over the current sub-descriptor inside the configuration descriptor, so that the pointer then @@ -269,8 +271,11 @@ void** CurrConfigLoc) { uint16_t CurrDescriptorSize = DESCRIPTOR_CAST(*CurrConfigLoc, USB_Descriptor_Header_t).Size; + + if (*BytesRem < CurrDescriptorSize) + CurrDescriptorSize = *BytesRem; - *CurrConfigLoc = ((uint8_t*)*CurrConfigLoc) + CurrDescriptorSize; + *CurrConfigLoc = (void*)((uintptr_t)*CurrConfigLoc + CurrDescriptorSize); *BytesRem -= CurrDescriptorSize; } diff --git a/LUFA/Drivers/USB/Core/Device.h b/LUFA/Drivers/USB/Core/Device.h index be3dfd118..0e8662417 100644 --- a/LUFA/Drivers/USB/Core/Device.h +++ b/LUFA/Drivers/USB/Core/Device.h @@ -63,6 +63,13 @@ /* Public Interface - May be used in end-application: */ /* Enums: */ + /** Enum for the various states of the USB Device state machine. Only some states are + * implemented in the LUFA library - other states are left to the user to implement. + * + * For information on each possible USB device state, refer to the USB 2.0 specification. + * + * \see \ref USB_DeviceState, which stores the current device state machine state. + */ enum USB_Device_States_t { DEVICE_STATE_Unattached = 0, /**< Internally implemented by the library. This state indicates diff --git a/LUFA/Drivers/USB/Core/DeviceStandardReq.c b/LUFA/Drivers/USB/Core/DeviceStandardReq.c index 2e6d8f8c0..f9c64b6f8 100644 --- a/LUFA/Drivers/USB/Core/DeviceStandardReq.c +++ b/LUFA/Drivers/USB/Core/DeviceStandardReq.c @@ -114,7 +114,7 @@ void USB_Device_ProcessControlRequest(void) static void USB_Device_SetAddress(void) { - uint8_t DeviceAddress = (USB_ControlRequest.wValue & 0x7F); + uint8_t DeviceAddress = (USB_ControlRequest.wValue & 0x7F); uint_reg_t CurrentGlobalInt = GetGlobalInterruptMask(); GlobalInterruptDisable(); diff --git a/LUFA/Drivers/USB/Core/StdDescriptors.h b/LUFA/Drivers/USB/Core/StdDescriptors.h index 32777cc0f..7840bcb8e 100644 --- a/LUFA/Drivers/USB/Core/StdDescriptors.h +++ b/LUFA/Drivers/USB/Core/StdDescriptors.h @@ -612,17 +612,21 @@ { USB_Descriptor_Header_t Header; /**< Descriptor header, including type and size. */ - wchar_t UnicodeString[]; /**< String data, as unicode characters (alternatively, - * string language IDs). If normal ASCII characters are - * to be used, they must be added as an array of characters - * rather than a normal C string so that they are widened to - * Unicode size. - * - * Under GCC, strings prefixed with the "L" character (before - * the opening string quotation mark) are considered to be - * Unicode strings, and may be used instead of an explicit - * array of ASCII characters. - */ + #if (ARCH == ARCH_AVR8) + wchar_t UnicodeString[]; + #else + uint16_t UnicodeString[]; /**< String data, as unicode characters (alternatively, + * string language IDs). If normal ASCII characters are + * to be used, they must be added as an array of characters + * rather than a normal C string so that they are widened to + * Unicode size. + * + * Under GCC, strings prefixed with the "L" character (before + * the opening string quotation mark) are considered to be + * Unicode strings, and may be used instead of an explicit + * array of ASCII characters. + */ + #endif } ATTR_PACKED USB_Descriptor_String_t; /** \brief Standard USB String Descriptor (USB-IF naming conventions). diff --git a/LUFA/Drivers/USB/Core/UC3/Device_UC3.h b/LUFA/Drivers/USB/Core/UC3/Device_UC3.h index ed7409856..8bc8188d2 100644 --- a/LUFA/Drivers/USB/Core/UC3/Device_UC3.h +++ b/LUFA/Drivers/USB/Core/UC3/Device_UC3.h @@ -89,18 +89,24 @@ * On unsupported devices, this will evaluate to \ref NO_DESCRIPTOR and so will force the host to create a pseudo-serial * number for the device. */ - #define USE_INTERNAL_SERIAL 0xDC + #define USE_INTERNAL_SERIAL 0xDC /** Length of the device's unique internal serial number, in bits, if present on the selected microcontroller * model. */ - #define INTERNAL_SERIAL_LENGTH_BITS 120 + #define INTERNAL_SERIAL_LENGTH_BITS 120 + + /** Start address of the internal serial number, in the appropriate address space, if present on the selected microcontroller + * model. + */ + #define INTERNAL_SERIAL_START_ADDRESS 0x80800204 #else - #define USE_INTERNAL_SERIAL NO_DESCRIPTOR + #define USE_INTERNAL_SERIAL NO_DESCRIPTOR - #define INTERNAL_SERIAL_LENGTH_BITS 0 + #define INTERNAL_SERIAL_LENGTH_BITS 0 + #define INTERNAL_SERIAL_START_ADDRESS 0 #endif - + /* Function Prototypes: */ /** Sends a Remote Wakeup request to the host. This signals to the host that the device should * be taken out of suspended mode, and communications should resume. @@ -186,12 +192,13 @@ return AVR32_USBB.UDCON.adden; } - static inline void USB_Device_GetSerialString(uint16_t* UnicodeString) + #if (USE_INTERNAL_SERIAL != NO_DESCRIPTOR) + static inline void USB_Device_GetSerialString(uint16_t* const UnicodeString) { uint_reg_t CurrentGlobalInt = GetGlobalInterruptMask(); GlobalInterruptDisable(); - uint8_t* SigReadAddress = (uint8_t*)0x80800204; + uint8_t* SigReadAddress = (uint8_t*)INTERNAL_SERIAL_START_ADDRESS; for (uint8_t SerialCharNum = 0; SerialCharNum < (INTERNAL_SERIAL_LENGTH_BITS / 4); SerialCharNum++) { @@ -211,6 +218,8 @@ SetGlobalInterruptMask(CurrentGlobalInt); } + #endif + #endif #endif diff --git a/LUFA/Drivers/USB/Core/UC3/Endpoint_UC3.c b/LUFA/Drivers/USB/Core/UC3/Endpoint_UC3.c index b978ec7f1..9c7d6b62d 100644 --- a/LUFA/Drivers/USB/Core/UC3/Endpoint_UC3.c +++ b/LUFA/Drivers/USB/Core/UC3/Endpoint_UC3.c @@ -61,7 +61,7 @@ void Endpoint_ClearEndpoints(void) { Endpoint_SelectEndpoint(EPNum); (&AVR32_USBB.uecfg0)[EPNum] = 0; - (&AVR32_USBB.uecon0clr)[EPNum] = 0xFFFFFFFF; + (&AVR32_USBB.uecon0clr)[EPNum] = -1; USB_EndpointFIFOPos[EPNum] = &AVR32_USBB_SLAVE[EPNum * 0x10000]; Endpoint_DisableEndpoint(); } diff --git a/LUFA/Drivers/USB/Core/UC3/Pipe_UC3.c b/LUFA/Drivers/USB/Core/UC3/Pipe_UC3.c index 86bed0388..92589a870 100644 --- a/LUFA/Drivers/USB/Core/UC3/Pipe_UC3.c +++ b/LUFA/Drivers/USB/Core/UC3/Pipe_UC3.c @@ -69,7 +69,7 @@ void Pipe_ClearPipes(void) { Pipe_SelectPipe(PNum); (&AVR32_USBB.upcfg0)[PNum] = 0; - (&AVR32_USBB.upcon0clr)[PNum] = 0xFFFFFFFF; + (&AVR32_USBB.upcon0clr)[PNum] = -1; USB_PipeFIFOPos[PNum] = &AVR32_USBB_SLAVE[PNum * 0x10000]; Pipe_DisablePipe(); } diff --git a/LUFA/Drivers/USB/Core/UC3/USBController_UC3.c b/LUFA/Drivers/USB/Core/UC3/USBController_UC3.c index e3d97d684..0b0d04d63 100644 --- a/LUFA/Drivers/USB/Core/UC3/USBController_UC3.c +++ b/LUFA/Drivers/USB/Core/UC3/USBController_UC3.c @@ -72,6 +72,8 @@ void USB_Init( AVR32_USBB.USBCON.uide = false; USB_CurrentMode = Mode; } + #else + AVR32_USBB.USBCON.uide = false; #endif USB_IsInitialized = true; diff --git a/LUFA/Drivers/USB/Core/UC3/USBInterrupt_UC3.c b/LUFA/Drivers/USB/Core/UC3/USBInterrupt_UC3.c index 76f4ef022..5191ee67f 100644 --- a/LUFA/Drivers/USB/Core/UC3/USBInterrupt_UC3.c +++ b/LUFA/Drivers/USB/Core/UC3/USBInterrupt_UC3.c @@ -36,8 +36,8 @@ void USB_INT_DisableAllInterrupts(void) AVR32_USBB.USBCON.vbuste = false; AVR32_USBB.USBCON.idte = false; - AVR32_USBB.uhinteclr = 0xFFFFFFFF; - AVR32_USBB.udinteclr = 0xFFFFFFFF; + AVR32_USBB.uhinteclr = -1; + AVR32_USBB.udinteclr = -1; } void USB_INT_ClearAllInterrupts(void) @@ -45,8 +45,8 @@ void USB_INT_ClearAllInterrupts(void) AVR32_USBB.USBSTACLR.vbustic = true; AVR32_USBB.USBSTACLR.idtic = true; - AVR32_USBB.uhintclr = 0xFFFFFFFF; - AVR32_USBB.udintclr = 0xFFFFFFFF; + AVR32_USBB.uhintclr = -1; + AVR32_USBB.udintclr = -1; } ISR(USB_GEN_vect) diff --git a/LUFA/ManPages/ChangeLog.txt b/LUFA/ManPages/ChangeLog.txt index 9671ea893..925364077 100644 --- a/LUFA/ManPages/ChangeLog.txt +++ b/LUFA/ManPages/ChangeLog.txt @@ -18,7 +18,7 @@ * - Added new Endpoint_Null_Stream() and Pipe_Null_Stream() functions * - Added new ADC_GET_CHANNEL_MASK() convenience macro * - Added new HID report item macros (with HID_RI_ prefix) to allow for easy creation and editing of HID report descriptors - * - Added new HID_DESCRIPTOR_MOUSE, HID_DESCRIPTOR_KEYBOARD, HID_DESCRIPTOR_JOYSTICK and HID_DESCRIPTOR_VENDOR macros + * - Added new HID_DESCRIPTOR_MOUSE(), HID_DESCRIPTOR_KEYBOARD(), HID_DESCRIPTOR_JOYSTICK() and HID_DESCRIPTOR_VENDOR() macros * for easy automatic creation of basic USB HID device reports * - Added new MAX() and MIN() convenience macros * - Added new Serial_SendData() function to the Serial driver @@ -33,6 +33,7 @@ * - Added new KeyboardMouseMultiReport Device ClassDriver demo * - Added new VirtualSerialMassStorage Device ClassDriver demo * - Added HID class bootloader, compatible with a modified version of the command line Teensy loader from PJRC.com + * - Added LED flashing to the CDC and DFU class bootloaders to indicate when they are running * * Changed: * - Core: @@ -66,6 +67,7 @@ * a symbolic size (Byte, Word, DWord) so that the function names are applicable and correct across all architectures * - Renamed all low level Pipe_Read_*, Pipe_Write_* and Pipe_Discard_* functions to use the number of bits instead of * a symbolic size (Byte, Word, DWord) so that the function names are applicable and correct across all architectures + * - Seperated out board drivers by architecture in the library internals for better organisation * - Library Applications: * - Changed the XPLAINBridge software UART to use the regular timer CTC mode instead of the alternative CTC mode * via the Input Capture register, to reduce user confusion @@ -96,6 +98,7 @@ * is found * - Fixed missing call to Pipe_SetInfiniteINRequests() in the Pipe_ConfigurePipe() routine * - Fixed Remote Wakeup broken on the AVRs due to the mechanism only operating when the SUSPI bit is set (thanks to Holger Steinhaus) + * - Fixed possible invalid program execution when in host mode if corrupt descriptor lengths are supplied by the attached device * - Library Applications: * - Fixed Benito project discarding incoming data from the USB virtual serial port when the USART is busy * - Fixed broken DFU bootloader, added XPLAIN support for bootloader start when XCK jumpered to ground diff --git a/LUFA/ManPages/DeviceSupport.txt b/LUFA/ManPages/DeviceSupport.txt index 2381d2a9e..f25625b4f 100644 --- a/LUFA/ManPages/DeviceSupport.txt +++ b/LUFA/ManPages/DeviceSupport.txt @@ -7,42 +7,6 @@ /** * \page Page_DeviceSupport Device and Hardware Support * - * \section Sec_AVR8_Support Atmel 32-Bit UC3 AVR (UC3) - * The AVR32 UC3 device support is currently experimental, and is included for preview purposes only. - * - * Currently supported UC3 models: - * - AT32UC3A064 (USB Host and Device) - * - AT32UC3A164 (USB Host and Device) - * - AT32UC3A364 (USB Host and Device) - * - AT32UC3A364S (USB Host and Device) - * - AT32UC3A464 (USB Host and Device) - * - AT32UC3A464S (USB Host and Device) - * - AT32UC3B064 (USB Host and Device) - * - AT32UC3B164 (USB Host and Device) - * - AT32UC3A0128 (USB Host and Device) - * - AT32UC3A1128 (USB Host and Device) - * - AT32UC3A3128 (USB Host and Device) - * - AT32UC3A3128S (USB Host and Device) - * - AT32UC3A4128 (USB Host and Device) - * - AT32UC3A4128S (USB Host and Device) - * - AT32UC3B0128 (USB Host and Device) - * - AT32UC3B1128 (USB Host and Device) - * - AT32UC3A0256 (USB Host and Device) - * - AT32UC3A1256 (USB Host and Device) - * - AT32UC3A3256 (USB Host and Device) - * - AT32UC3A3256S (USB Host and Device) - * - AT32UC3A4256 (USB Host and Device) - * - AT32UC3A4256S (USB Host and Device) - * - AT32UC3B0256 (USB Host and Device) - * - AT32UC3B1256 (USB Host and Device) - * - AT32UC3A0512 (USB Host and Device) - * - AT32UC3A1512 (USB Host and Device) - * - AT32UC3B0512 (USB Host and Device) - * - AT32UC3B1512 (USB Host and Device) - * - * Currently supported Atmel boards (see \ref Group_BoardTypes): - * - EVK1101 - * * \section Sec_AVR8_Support Atmel 8-Bit AVR (AVR8) * * Currently supported AVR8 models: @@ -59,14 +23,14 @@ * - AT90USB1286 (USB Device Only) * - AT90USB1287 (USB Host and Device) * - * Currently supported Atmel boards (see \ref Group_BoardTypes): + * Currently supported Atmel AVR8 boards (see \ref Group_BoardTypes): * - AT90USBKEY * - ATAVRUSBRF01 * - EVK527 * - RZUSBSTICK * - STK525 * - STK526 - * - XPLAIN (Both original first revision board, and newer boards with a different Dataflash model) + * - XPLAIN (Excluding the blue XPLAINED family boards) * * Currently supported third-party boards (see \ref Group_BoardTypes for makefile BOARD constant names): * - Adafruit U4 Breakout Board @@ -86,6 +50,45 @@ * - TCNISO Blackcat USB JTAG * - Tempusdictum Benito * - Tom's USBTINY-MKII (all revisions and versions) - * - Any Other Custom User Boards (with Board Drivers if desired, see \ref Page_WritingBoardDrivers) + * - Custom User Boards (with Board Drivers if desired, see \ref Page_WritingBoardDrivers) + * + * \section Sec_AVR32_Support Atmel 32-Bit UC3 AVR (UC3) + * Note: The AVR32 UC3 device support is currently experimental, and is included for preview purposes only. + * + * Currently supported UC3 models: + * - AT32UC3A064 (USB Host and Device) + * - AT32UC3A164 (USB Host and Device) + * - AT32UC3A364 (USB Host and Device) + * - AT32UC3A364S (USB Host and Device) + * - AT32UC3A464 (USB Host and Device) + * - AT32UC3A464S (USB Host and Device) + * - AT32UC3B064 (USB Host and Device) + * - AT32UC3B164 (USB Host and Device) + * - AT32UC3A0128 (USB Host and Device) + * - AT32UC3A1128 (USB Host and Device) + * - AT32UC3A3128 (USB Host and Device) + * - AT32UC3A3128S (USB Host and Device) + * - AT32UC3A4128 (USB Host and Device) + * - AT32UC3A4128S (USB Host and Device) + * - AT32UC3B0128 (USB Host and Device) + * - AT32UC3B1128 (USB Host and Device) + * - AT32UC3A0256 (USB Host and Device) + * - AT32UC3A1256 (USB Host and Device) + * - AT32UC3A3256 (USB Host and Device) + * - AT32UC3A3256S (USB Host and Device) + * - AT32UC3A4256 (USB Host and Device) + * - AT32UC3A4256S (USB Host and Device) + * - AT32UC3B0256 (USB Host and Device) + * - AT32UC3B1256 (USB Host and Device) + * - AT32UC3A0512 (USB Host and Device) + * - AT32UC3A1512 (USB Host and Device) + * - AT32UC3B0512 (USB Host and Device) + * - AT32UC3B1512 (USB Host and Device) + * + * Currently supported Atmel UC3 boards (see \ref Group_BoardTypes): + * - EVK1101 + * + * Currently supported third-party boards (see \ref Group_BoardTypes for makefile BOARD constant names): + * - Custom User Boards (with Board Drivers if desired, see \ref Page_WritingBoardDrivers) */ diff --git a/LUFA/ManPages/FutureChanges.txt b/LUFA/ManPages/FutureChanges.txt index 414240653..3dbe7c804 100644 --- a/LUFA/ManPages/FutureChanges.txt +++ b/LUFA/ManPages/FutureChanges.txt @@ -18,6 +18,10 @@ * -# Change makefiles to allow for absolute LUFA location to be used * -# Re-add interrupt Pipe/Endpoint support * -# Add makefile includes to reduce boilerplate in user makefiles + * -# Update stream APIs to use DMA transfers on supported architectures + * -# Pull out third party libraries into a seperate folder and reference them as required + * -# Add a LUFA_YIELD macro for integration into a third-party RTOS + * -# Abstract out Mass Storage byte send/receive to prevent low level API use in projects * - Documentation/Support * -# Add detailed overviews of how each demo works * -# Add board overviews diff --git a/LUFA/ManPages/LUFAPoweredProjects.txt b/LUFA/ManPages/LUFAPoweredProjects.txt index 59baa9745..23ad126a6 100644 --- a/LUFA/ManPages/LUFAPoweredProjects.txt +++ b/LUFA/ManPages/LUFAPoweredProjects.txt @@ -56,6 +56,7 @@ * - LED Panel controller: http://projects.peterpolidoro.net/caltech/panelscontroller/panelscontroller.htm * - LUFA powered DDR dance mat (French): http://logicien-parfait.fr/dokuwiki/doku.php?id=projet:ddr_repair * - MIDI Theremin: http://baldwisdom.com/usb-midi-controller-theremin-style-on-arduino-uno/ + * - MiniBloq, a graphical Ardunio programming environment : http://minibloq.org/ * - Motherboard BIOS flasher: http://www.coreboot.org/InSystemFlasher * - Multi-button Joystick (French): http://logicien-parfait.fr/dokuwiki/doku.php?id=projet:joystick * - Nikon wireless camera remote control (Norwegian): http://hekta.org/~hpe1119/ @@ -64,6 +65,7 @@ * - Linux Secure Storage Dongle: http://github.com/TomMD/teensy * - MakeTV Episode Dispenser: http://www.youtube.com/watch?v=BkWUi18hl3g * - MidiMonster, a USB-to-MIDI gateway board: http://www.dorkbotpdx.org/wiki/midimonster + * - MiXley, a port of the Teacup 3D printer firmware for the USB AVRs: http://codaset.com/michielh/mixley * - Mobo 4.3, a USB controlled all band (160-10m) HF SDR transceiver: http://sites.google.com/site/lofturj/mobo4_3 * - Moco, a native Arduino Uno MIDI replacement firmware: http://web.mac.com/kuwatay/morecat_lab./MocoLUFA.html * - Music Playing Alarm Clock (Tutorial): http://www.instructables.com/id/Music-Playing-Alarm-Clock/ @@ -81,7 +83,9 @@ * - Teensy SD Card .WAV file player: http://elasticsheep.com/2010/04/teensy2-usb-wav-player-part-1/ * - Touchscreen Input Device: http://capnstech.blogspot.com/2010/07/touchscreen-update.html * - Universal USB AVR Module: http://usbavr.bplaced.net/ + * - USB2AX, a USB to Dynamixel network adapter: http://trac.assembla.com/XD_DSbot/browser/trunk * - USB Interface for Playstation Portable Devices: http://forums.ps2dev.org/viewtopic.php?t=11001 + * - USB powered Geiger Counter: http://uhrheber.wordpress.com/2011/04/28/a-usb-powered-geiger-counter-for-the-z2-and-other-computers/ * - Userial, a USB to Serial converter with SPI, I2C and other protocols: http://www.tty1.net/userial/ * - Wireless MIDI Guitar system: http://www.ise.pw.edu.pl/~wzab/wireless_guitar_system/ * - XUM1541, a Commodore 64 floppy drive to USB adapter: http://www.root.org/~nate/c64/xum1541/ @@ -90,17 +94,20 @@ * \section Sec_LUFACommercialProjects Projects Using LUFA (Commercial) * * The following is a list of known commercial products using LUFA. Some of these are open source, although many are "black-box" - * solutions with no source code given. + * solutions with no source code given. Those companies which have purchased a Commercial License to LUFA (see \ref Page_LicenseInfo) + * are not listed here unless specifically requested. * - * - Arduino Uno, the official Arduino board: www.arduino.cc + * - Arduino Uno, the official Arduino board: http://www.arduino.cc * - ARPS Locator: http://la3t.hamradio.no/lab//?id=tracker_en * - Digital Survey Instruments Magnetometer and Pointer: http://www.digitalsurveyinstruments.com/ + * - FinchRobot, a robot designed for educational use: http://www.finchrobot.com/ * - Penguino, an Arduino Board With On-Board LUFA Powered Debugger/Programmer: http://wiki.icy.com.au/PenguinoAVR * - PIR-1, an IR control interface for consumer electronics: http://www.promixis.com/pir-1.php * - PIR-4, a USB Connected 4 port IR transmitter: http://promixis.com/pir-4.php * - Many of Busware's Products: http://www.busware.de/ * - MIDIFighter, a USB-MIDI controller: http://www.midifighter.com/ * - Retrode, a USB Games Console Cartridge Reader: http://www.retrode.org + * - SmartCardDetective, a Smart Card analysis tool: http://www.smartcarddetective.com/ * - USBTINY-MKII, an AVRISP-MKII Clone AVR Programmer: http://tom-itx.dyndns.org:81/~webpage/boards/USBTiny_Mkii/USBTiny_Mkii_index.php * - XMEGA Development Board, using LUFA as an On-Board Programmer: http://xmega.mattair.net/ * - Zeptoprog, a multifunction AVR programmer: http://www.mattairtech.com/index.php/featured/zeptoprog.html diff --git a/LUFA/ManPages/LibraryResources.txt b/LUFA/ManPages/LibraryResources.txt index c5e636c67..8ec544bed 100644 --- a/LUFA/ManPages/LibraryResources.txt +++ b/LUFA/ManPages/LibraryResources.txt @@ -20,9 +20,8 @@ * * \section Sec_InDevelopment Latest In-Development Source Code * Issue Tracker: http://www.lufa-lib.org/tracker \n - * Bazaar Access: http://www.lufa-lib.org/bzr \n * SVN Access: http://www.lufa-lib.org/svn \n - * Git Access: http://www.lufa-lib.org/git \n + * GIT Access: http://www.lufa-lib.org/git \n * Latest Repository Source Archive: http://www.lufa-lib.org/latest-archive \n * Commit RSS Feed: http://www.lufa-lib.org/rss \n * diff --git a/LUFA/ManPages/MigrationInformation.txt b/LUFA/ManPages/MigrationInformation.txt index 61bdd61df..727922808 100644 --- a/LUFA/ManPages/MigrationInformation.txt +++ b/LUFA/ManPages/MigrationInformation.txt @@ -51,6 +51,9 @@ * code using these functions should replace the previous function names with the new function names. * - The Endpoint_*_DWord() functions have been renamed Endpoint_*_32() to ensure they are correct across all architectures. Existing * code using these functions should replace the previous function names with the new function names. + * - 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(). * * Host Mode * - The Pipe stream functions now all require a \c BytesProcessed parameter instead of the previous callback parameter. diff --git a/LUFA/makefile b/LUFA/makefile index e75e105b6..46dcc0843 100644 --- a/LUFA/makefile +++ b/LUFA/makefile @@ -58,9 +58,12 @@ LUFA_SRC_SCHEDULER = $(LUFA_ROOT_PATH)/Scheduler/Scheduler.c # Check to see if the LUFA_PATH variable has not been set (the makefile is not being included from a project makefile) ifeq ($(origin LUFA_PATH), undefined) - LUFA_SRC_ALL_FILES = $(LUFA_SRC_USB) $(LUFA_SRC_USBCLASS) \ - $(LUFA_SRC_TEMPERATURE) $(LUFA_SRC_SERIAL) \ - $(LUFA_SRC_TWI) $(LUFA_SRC_SCHEDULER) + LUFA_SRC_ALL_FILES = $(LUFA_SRC_USB) \ + $(LUFA_SRC_USBCLASS) \ + $(LUFA_SRC_TEMPERATURE) \ + $(LUFA_SRC_SERIAL) \ + $(LUFA_SRC_TWI) \ + $(LUFA_SRC_SCHEDULER) all: @@ -77,6 +80,9 @@ ifeq ($(origin LUFA_PATH), undefined) clean_doxygen: rm -rf Documentation + + version: + @echo "LUFA `grep LUFA_VERSION_STRING Version.h | cut -d'"' -f2`" - .PHONY: all clean clean_list doxygen clean_doxygen + .PHONY: all clean clean_list doxygen clean_doxygen version endif