From c9148f9b473187163f9b1384b993315e39a14711 Mon Sep 17 00:00:00 2001
From: Dean Camera <dean@fourwalledcubicle.com>
Date: Wed, 31 Mar 2010 09:20:24 +0000
Subject: [PATCH] Added WIN_LIBUSB_COMPAT compile time option to the AVRISP
 programmer project to make the code compatible with Windows builds of avrdude
 at the expense of AVRStudio compatibility.

---
 LUFA/ManPages/ChangeLog.txt                    |  2 ++
 Projects/AVRISP-MKII/AVRISP.c                  | 13 +++++++++++--
 Projects/AVRISP-MKII/AVRISP.txt                |  7 +++++++
 Projects/AVRISP-MKII/Descriptors.c             |  4 ++--
 Projects/AVRISP-MKII/Descriptors.h             | 17 ++++++++++++++---
 Projects/AVRISP-MKII/Lib/ISP/ISPProtocol.c     |  9 +++++++++
 Projects/AVRISP-MKII/Lib/V2Protocol.c          |  6 ++++++
 Projects/AVRISP-MKII/Lib/V2Protocol.h          |  6 ++++++
 Projects/AVRISP-MKII/Lib/XPROG/XPROGProtocol.c |  8 ++++++++
 Projects/AVRISP-MKII/makefile                  |  1 +
 Projects/XPLAINBridge/AVRISPDescriptors.c      |  4 ++--
 Projects/XPLAINBridge/AVRISPDescriptors.h      | 15 +++++++++++++--
 Projects/XPLAINBridge/XPLAINBridge.c           | 18 ++++++++++++------
 Projects/XPLAINBridge/XPLAINBridge.txt         |  7 +++++++
 Projects/XPLAINBridge/makefile                 |  2 ++
 15 files changed, 102 insertions(+), 17 deletions(-)

diff --git a/LUFA/ManPages/ChangeLog.txt b/LUFA/ManPages/ChangeLog.txt
index 370963e6e..c8eddc1a7 100644
--- a/LUFA/ManPages/ChangeLog.txt
+++ b/LUFA/ManPages/ChangeLog.txt
@@ -24,6 +24,8 @@
   *  - Standardized the naming scheme given to configuration descriptor sub-elements in the Device mode demos, bootloaders
   *    and projects
   *  - All Class Driver Host mode demos now correctly set the board LEDs to READY once the enumeration process has completed
+  *  - Added WIN_LIBUSB_COMPAT compile time option to the AVRISP programmer project to make the code compatible with Windows
+  *    builds of avrdude at the expense of AVRStudio compatibility
   *
   *  <b>Fixed:</b>
   *  - Fixed software PDI/TPI programming mode in the AVRISP project not correctly toggling just the clock pin
diff --git a/Projects/AVRISP-MKII/AVRISP.c b/Projects/AVRISP-MKII/AVRISP.c
index b78923f5b..ed101b889 100644
--- a/Projects/AVRISP-MKII/AVRISP.c
+++ b/Projects/AVRISP-MKII/AVRISP.c
@@ -90,12 +90,21 @@ void EVENT_USB_Device_ConfigurationChanged(void)
 	LEDs_SetAllLEDs(LEDMASK_USB_READY);
 
 	/* Setup AVRISP data Endpoints */
-	if (!(Endpoint_ConfigureEndpoint(AVRISP_DATA_EPNUM, EP_TYPE_BULK,
+	if (!(Endpoint_ConfigureEndpoint(AVRISP_DATA_OUT_EPNUM, EP_TYPE_BULK,
 		                             ENDPOINT_DIR_OUT, AVRISP_DATA_EPSIZE,
 	                                 ENDPOINT_BANK_SINGLE)))
 	{
 		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
 	}
+
+	#if defined(WIN_LIBUSB_COMPAT)
+	if (!(Endpoint_ConfigureEndpoint(AVRISP_DATA_IN_EPNUM, EP_TYPE_BULK,
+		                             ENDPOINT_DIR_IN, AVRISP_DATA_EPSIZE,
+	                                 ENDPOINT_BANK_SINGLE)))
+	{
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+	}
+	#endif
 }
 
 /** Processes incoming V2 Protocol commands from the host, returning a response when required. */
@@ -105,7 +114,7 @@ void Process_AVRISP_Commands(void)
 	if (USB_DeviceState != DEVICE_STATE_Configured)
 	  return;
 
-	Endpoint_SelectEndpoint(AVRISP_DATA_EPNUM);
+	Endpoint_SelectEndpoint(AVRISP_DATA_OUT_EPNUM);
 	
 	/* Check to see if a V2 Protocol command has been received */
 	if (Endpoint_IsOUTReceived())
diff --git a/Projects/AVRISP-MKII/AVRISP.txt b/Projects/AVRISP-MKII/AVRISP.txt
index feccfcabe..b54125795 100644
--- a/Projects/AVRISP-MKII/AVRISP.txt
+++ b/Projects/AVRISP-MKII/AVRISP.txt
@@ -273,5 +273,12 @@
  *    <td>Define to disable VTARGET sampling and reporting on AVR models with an ADC converter. This will cause the programmer
  *        to report a fixed 5V target voltage to the host regardless of the real target voltage.</td>  
  *   </tr>
+ *   <tr>
+ *    <td>WIN_LIBUSB_COMPAT</td>
+ *    <td>Makefile CDEFS</td>
+ *    <td>Define to switch to a non-standard endpoint scheme, breaking compatibility with AVRStudio under Windows but making
+ *        the code compatible with Windows builds of avrdude using the libUSB driver. Linux platforms are not affected by this
+ *        option.
+ *   </tr>
  *  </table>
  */
diff --git a/Projects/AVRISP-MKII/Descriptors.c b/Projects/AVRISP-MKII/Descriptors.c
index f756e2903..af28b4b30 100644
--- a/Projects/AVRISP-MKII/Descriptors.c
+++ b/Projects/AVRISP-MKII/Descriptors.c
@@ -106,7 +106,7 @@ USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
 		{
 			.Header                 = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
 			
-			.EndpointAddress        = (ENDPOINT_DESCRIPTOR_DIR_IN | AVRISP_DATA_EPNUM),
+			.EndpointAddress        = (ENDPOINT_DESCRIPTOR_DIR_IN | AVRISP_DATA_IN_EPNUM),
 			.Attributes             = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
 			.EndpointSize           = AVRISP_DATA_EPSIZE,
 			.PollingIntervalMS      = 0x00
@@ -116,7 +116,7 @@ USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
 		{
 			.Header                 = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
 			
-			.EndpointAddress        = (ENDPOINT_DESCRIPTOR_DIR_OUT | AVRISP_DATA_EPNUM),
+			.EndpointAddress        = (ENDPOINT_DESCRIPTOR_DIR_OUT | AVRISP_DATA_OUT_EPNUM),
 			.Attributes             = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
 			.EndpointSize           = AVRISP_DATA_EPSIZE,
 			.PollingIntervalMS      = 0x00
diff --git a/Projects/AVRISP-MKII/Descriptors.h b/Projects/AVRISP-MKII/Descriptors.h
index ced47386b..9f6a41208 100644
--- a/Projects/AVRISP-MKII/Descriptors.h
+++ b/Projects/AVRISP-MKII/Descriptors.h
@@ -42,11 +42,22 @@
 		#include <LUFA/Drivers/USB/USB.h>
 
 	/* Macros: */
-		/** Endpoint number of the AVRISP bidirectional data endpoint. */
-		#define AVRISP_DATA_EPNUM              2
+		#if !defined(WIN_LIBUSB_COMPAT)
+			/** Endpoint number of the AVRISP data OUT endpoint. */
+			#define AVRISP_DATA_OUT_EPNUM      2
+
+			/** Endpoint number of the AVRISP data IN endpoint. */
+			#define AVRISP_DATA_IN_EPNUM       2
+		#else
+			/** Endpoint number of the AVRISP data OUT endpoint. */
+			#define AVRISP_DATA_OUT_EPNUM      2
+
+			/** Endpoint number of the AVRISP data IN endpoint. */
+			#define AVRISP_DATA_IN_EPNUM       3
+		#endif
 
 		/** Size in bytes of the AVRISP data endpoint. */
-		#define AVRISP_DATA_EPSIZE             64	
+		#define AVRISP_DATA_EPSIZE             64
 
 	/* Type Defines: */
 		/** Type define for the device configuration descriptor structure. This must be defined in the
diff --git a/Projects/AVRISP-MKII/Lib/ISP/ISPProtocol.c b/Projects/AVRISP-MKII/Lib/ISP/ISPProtocol.c
index 85b31fbdb..9d0a26c33 100644
--- a/Projects/AVRISP-MKII/Lib/ISP/ISPProtocol.c
+++ b/Projects/AVRISP-MKII/Lib/ISP/ISPProtocol.c
@@ -57,6 +57,7 @@ void ISPProtocol_EnterISPMode(void)
 	Endpoint_Read_Stream_LE(&Enter_ISP_Params, sizeof(Enter_ISP_Params), NO_STREAM_CALLBACK);
 
 	Endpoint_ClearOUT();
+	Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPNUM);
 	Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
 
 	uint8_t ResponseStatus = STATUS_CMD_FAILED;
@@ -117,6 +118,7 @@ void ISPProtocol_LeaveISPMode(void)
 	Endpoint_Read_Stream_LE(&Leave_ISP_Params, sizeof(Leave_ISP_Params), NO_STREAM_CALLBACK);
 	
 	Endpoint_ClearOUT();
+	Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPNUM);
 	Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
 
 	/* Perform pre-exit delay, release the target /RESET, disable the SPI bus and perform the post-exit delay */
@@ -163,6 +165,7 @@ void ISPProtocol_ProgramMemory(uint8_t V2Command)
 	if (Write_Memory_Params.BytesToWrite > sizeof(Write_Memory_Params.ProgData))
 	{
 		Endpoint_ClearOUT();
+		Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPNUM);
 		Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
 
 		Endpoint_Write_Byte(V2Command);
@@ -174,6 +177,7 @@ void ISPProtocol_ProgramMemory(uint8_t V2Command)
 	Endpoint_Read_Stream_LE(&Write_Memory_Params.ProgData, Write_Memory_Params.BytesToWrite, NO_STREAM_CALLBACK);
 
 	Endpoint_ClearOUT();
+	Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPNUM);
 	Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
 
 	uint8_t  ProgrammingStatus = STATUS_CMD_OK;	
@@ -305,6 +309,7 @@ void ISPProtocol_ReadMemory(uint8_t V2Command)
 	Read_Memory_Params.BytesToRead = SwapEndian_16(Read_Memory_Params.BytesToRead);
 	
 	Endpoint_ClearOUT();
+	Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPNUM);
 	Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
 	
 	Endpoint_Write_Byte(V2Command);
@@ -375,6 +380,7 @@ void ISPProtocol_ChipErase(void)
 	Endpoint_Read_Stream_LE(&Erase_Chip_Params, sizeof(Erase_Chip_Params), NO_STREAM_CALLBACK);
 	
 	Endpoint_ClearOUT();
+	Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPNUM);
 	Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
 	
 	uint8_t ResponseStatus = STATUS_CMD_OK;
@@ -410,6 +416,7 @@ void ISPProtocol_ReadFuseLockSigOSCCAL(uint8_t V2Command)
 	Endpoint_Read_Stream_LE(&Read_FuseLockSigOSCCAL_Params, sizeof(Read_FuseLockSigOSCCAL_Params), NO_STREAM_CALLBACK);
 
 	Endpoint_ClearOUT();
+	Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPNUM);
 	Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
 
 	uint8_t ResponseBytes[4];
@@ -440,6 +447,7 @@ void ISPProtocol_WriteFuseLock(uint8_t V2Command)
 	Endpoint_Read_Stream_LE(&Write_FuseLockSig_Params, sizeof(Write_FuseLockSig_Params), NO_STREAM_CALLBACK);
 
 	Endpoint_ClearOUT();
+	Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPNUM);
 	Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
 
 	/* Send the Fuse or Lock byte program commands as given by the host to the device */
@@ -467,6 +475,7 @@ void ISPProtocol_SPIMulti(void)
 	Endpoint_Read_Stream_LE(&SPI_Multi_Params.TxData, SPI_Multi_Params.TxBytes, NO_STREAM_CALLBACK);
 	
 	Endpoint_ClearOUT();
+	Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPNUM);
 	Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
 	
 	Endpoint_Write_Byte(CMD_SPI_MULTI);
diff --git a/Projects/AVRISP-MKII/Lib/V2Protocol.c b/Projects/AVRISP-MKII/Lib/V2Protocol.c
index 3df8045aa..431f9c2d5 100644
--- a/Projects/AVRISP-MKII/Lib/V2Protocol.c
+++ b/Projects/AVRISP-MKII/Lib/V2Protocol.c
@@ -131,6 +131,7 @@ void V2Protocol_ProcessCommand(void)
 	}
 
 	Endpoint_WaitUntilReady();
+	Endpoint_SelectEndpoint(AVRISP_DATA_OUT_EPNUM);
 	Endpoint_SetEndpointDirection(ENDPOINT_DIR_OUT);
 }
 
@@ -149,6 +150,7 @@ static void V2Protocol_UnknownCommand(const uint8_t V2Command)
 	}
 
 	Endpoint_ClearOUT();
+	Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPNUM);
 	Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
 
 	Endpoint_Write_Byte(V2Command);
@@ -160,6 +162,7 @@ static void V2Protocol_UnknownCommand(const uint8_t V2Command)
 static void V2Protocol_SignOn(void)
 {
 	Endpoint_ClearOUT();
+	Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPNUM);
 	Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
 
 	Endpoint_Write_Byte(CMD_SIGN_ON);
@@ -175,6 +178,7 @@ static void V2Protocol_SignOn(void)
 static void V2Protocol_ResetProtection(void)
 {
 	Endpoint_ClearOUT();
+	Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPNUM);
 	Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
 	
 	Endpoint_Write_Byte(CMD_RESET_PROTECTION);
@@ -197,6 +201,7 @@ static void V2Protocol_GetSetParam(const uint8_t V2Command)
 	  ParamValue = Endpoint_Read_Byte();
 
 	Endpoint_ClearOUT();
+	Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPNUM);
 	Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
 	
 	Endpoint_Write_Byte(V2Command);
@@ -230,6 +235,7 @@ static void V2Protocol_LoadAddress(void)
 	Endpoint_Read_Stream_BE(&CurrentAddress, sizeof(CurrentAddress), NO_STREAM_CALLBACK);
 
 	Endpoint_ClearOUT();
+	Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPNUM);
 	Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
 	
 	MustSetAddress = true;
diff --git a/Projects/AVRISP-MKII/Lib/V2Protocol.h b/Projects/AVRISP-MKII/Lib/V2Protocol.h
index 26c42ab75..43dee1e77 100644
--- a/Projects/AVRISP-MKII/Lib/V2Protocol.h
+++ b/Projects/AVRISP-MKII/Lib/V2Protocol.h
@@ -72,6 +72,12 @@
 
 		/** MUX mask for the VTARGET ADC channel number */
 		#define VTARGET_ADC_CHANNEL_MASK   _GETADCMUXMASK(ADC_CHANNEL, VTARGET_ADC_CHANNEL)
+		
+		#if !defined(WIN_AVRDUDE_COMPAT)
+			#define SELECT_DATA_OUT_ENDPOINT() Endpoint_SetEndpointDirection(ENDPOINT_DIR_OUT);
+		#else
+			#define SELECT_DATA_OUT_ENDPOINT() Endpoint_SelectEndpoint();
+		#endif
 
 	/* External Variables: */
 		extern uint32_t CurrentAddress;
diff --git a/Projects/AVRISP-MKII/Lib/XPROG/XPROGProtocol.c b/Projects/AVRISP-MKII/Lib/XPROG/XPROGProtocol.c
index 07dce5011..ef86e30f2 100644
--- a/Projects/AVRISP-MKII/Lib/XPROG/XPROGProtocol.c
+++ b/Projects/AVRISP-MKII/Lib/XPROG/XPROGProtocol.c
@@ -65,6 +65,7 @@ void XPROGProtocol_SetMode(void)
 	Endpoint_Read_Stream_LE(&SetMode_XPROG_Params, sizeof(SetMode_XPROG_Params), NO_STREAM_CALLBACK);
 
 	Endpoint_ClearOUT();
+	Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPNUM);
 	Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
 	
 	XPROG_SelectedProtocol = SetMode_XPROG_Params.Protocol;
@@ -111,6 +112,7 @@ void XPROGProtocol_Command(void)
 static void XPROGProtocol_EnterXPROGMode(void)
 {
 	Endpoint_ClearOUT();
+	Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPNUM);
 	Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
 	
 	bool NVMBusEnabled;
@@ -166,6 +168,7 @@ static void XPROGProtocol_EnterXPROGMode(void)
 static void XPROGProtocol_LeaveXPROGMode(void)
 {
 	Endpoint_ClearOUT();
+	Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPNUM);
 	Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
 	
 	if (XPROG_SelectedProtocol == XPRG_PROTOCOL_PDI)
@@ -210,6 +213,7 @@ static void XPROGProtocol_Erase(void)
 	Erase_XPROG_Params.Address = SwapEndian_32(Erase_XPROG_Params.Address);
 
 	Endpoint_ClearOUT();
+	Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPNUM);
 	Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
 	
 	uint8_t EraseCommand;
@@ -291,6 +295,7 @@ static void XPROGProtocol_WriteMemory(void)
 	Endpoint_Read_Stream_LE(&WriteMemory_XPROG_Params.ProgData, WriteMemory_XPROG_Params.Length, NO_STREAM_CALLBACK);
 
 	Endpoint_ClearOUT();
+	Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPNUM);
 	Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
 
 	if (XPROG_SelectedProtocol == XPRG_PROTOCOL_PDI)
@@ -374,6 +379,7 @@ static void XPROGProtocol_ReadMemory(void)
 	ReadMemory_XPROG_Params.Length  = SwapEndian_16(ReadMemory_XPROG_Params.Length);
 
 	Endpoint_ClearOUT();
+	Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPNUM);
 	Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
 
 	uint8_t ReadBuffer[256];
@@ -416,6 +422,7 @@ static void XPROGProtocol_ReadCRC(void)
 	Endpoint_Read_Stream_LE(&ReadCRC_XPROG_Params, sizeof(ReadCRC_XPROG_Params), NO_STREAM_CALLBACK);
 
 	Endpoint_ClearOUT();
+	Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPNUM);
 	Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
 	
 	uint32_t MemoryCRC;
@@ -491,6 +498,7 @@ static void XPROGProtocol_SetParam(void)
 	}
 
 	Endpoint_ClearOUT();
+	Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPNUM);
 	Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
 		  
 	Endpoint_Write_Byte(CMD_XPROG);
diff --git a/Projects/AVRISP-MKII/makefile b/Projects/AVRISP-MKII/makefile
index b0b26c24c..1ea3b8d5b 100644
--- a/Projects/AVRISP-MKII/makefile
+++ b/Projects/AVRISP-MKII/makefile
@@ -199,6 +199,7 @@ CDEFS += -DENABLE_ISP_PROTOCOL
 CDEFS += -DENABLE_XPROG_PROTOCOL
 #CDEFS += -DXPROG_VIA_HARDWARE_USART
 #CDEFS += -DNO_VTARGET_DETECT
+#CDEFS += -DWIN_LIBUSB_COMPAT
 
 
 # Place -D or -U options here for ASM sources
diff --git a/Projects/XPLAINBridge/AVRISPDescriptors.c b/Projects/XPLAINBridge/AVRISPDescriptors.c
index e19178391..30e72e9e3 100644
--- a/Projects/XPLAINBridge/AVRISPDescriptors.c
+++ b/Projects/XPLAINBridge/AVRISPDescriptors.c
@@ -106,7 +106,7 @@ AVRISP_USB_Descriptor_Configuration_t PROGMEM AVRISP_ConfigurationDescriptor =
 		{
 			.Header                 = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
 			
-			.EndpointAddress        = (ENDPOINT_DESCRIPTOR_DIR_IN | AVRISP_DATA_EPNUM),
+			.EndpointAddress        = (ENDPOINT_DESCRIPTOR_DIR_IN | AVRISP_DATA_IN_EPNUM),
 			.Attributes             = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
 			.EndpointSize           = AVRISP_DATA_EPSIZE,
 			.PollingIntervalMS      = 0x00
@@ -116,7 +116,7 @@ AVRISP_USB_Descriptor_Configuration_t PROGMEM AVRISP_ConfigurationDescriptor =
 		{
 			.Header                 = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
 			
-			.EndpointAddress        = (ENDPOINT_DESCRIPTOR_DIR_OUT | AVRISP_DATA_EPNUM),
+			.EndpointAddress        = (ENDPOINT_DESCRIPTOR_DIR_OUT | AVRISP_DATA_OUT_EPNUM),
 			.Attributes             = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
 			.EndpointSize           = AVRISP_DATA_EPSIZE,
 			.PollingIntervalMS      = 0x00
diff --git a/Projects/XPLAINBridge/AVRISPDescriptors.h b/Projects/XPLAINBridge/AVRISPDescriptors.h
index 7287ce639..2fa18095d 100644
--- a/Projects/XPLAINBridge/AVRISPDescriptors.h
+++ b/Projects/XPLAINBridge/AVRISPDescriptors.h
@@ -42,9 +42,20 @@
 		#include <LUFA/Drivers/USB/USB.h>
 
 	/* Macros: */
-		/** Endpoint number of the AVRISP bidirectional data endpoint. */
-		#define AVRISP_DATA_EPNUM              2
+		#if !defined(LIBUSB_FILTERDRV_COMPAT)
+			/** Endpoint number of the AVRISP data OUT endpoint. */
+			#define AVRISP_DATA_OUT_EPNUM      2
 
+			/** Endpoint number of the AVRISP data IN endpoint. */
+			#define AVRISP_DATA_IN_EPNUM       2
+		#else
+			/** Endpoint number of the AVRISP data OUT endpoint. */
+			#define AVRISP_DATA_OUT_EPNUM      2
+
+			/** Endpoint number of the AVRISP data IN endpoint. */
+			#define AVRISP_DATA_IN_EPNUM       3
+		#endif
+		
 		/** Size in bytes of the AVRISP data endpoint. */
 		#define AVRISP_DATA_EPSIZE             64	
 
diff --git a/Projects/XPLAINBridge/XPLAINBridge.c b/Projects/XPLAINBridge/XPLAINBridge.c
index e5b282ee5..7ca94b273 100644
--- a/Projects/XPLAINBridge/XPLAINBridge.c
+++ b/Projects/XPLAINBridge/XPLAINBridge.c
@@ -99,7 +99,7 @@ void AVRISP_Task(void)
 	if (USB_DeviceState != DEVICE_STATE_Configured)
 	  return;
 
-	Endpoint_SelectEndpoint(AVRISP_DATA_EPNUM);
+	Endpoint_SelectEndpoint(AVRISP_DATA_OUT_EPNUM);
 	
 	/* Check to see if a V2 Protocol command has been received */
 	if (Endpoint_IsOUTReceived())
@@ -178,18 +178,24 @@ void SetupHardware(void)
 /** Event handler for the library USB Configuration Changed event. */
 void EVENT_USB_Device_ConfigurationChanged(void)
 {
-	bool EndpointConfigSuccess;
+	bool EndpointConfigSuccess = true;
 
 	/* Configure the device endpoints according to the selected mode */
 	if (CurrentFirmwareMode == MODE_USART_BRIDGE)
 	{
-		EndpointConfigSuccess = CDC_Device_ConfigureEndpoints(&VirtualSerial_CDC_Interface);
+		EndpointConfigSuccess &= CDC_Device_ConfigureEndpoints(&VirtualSerial_CDC_Interface);
 	}
 	else
 	{
-		EndpointConfigSuccess = Endpoint_ConfigureEndpoint(AVRISP_DATA_EPNUM, EP_TYPE_BULK,
-										                   ENDPOINT_DIR_OUT, AVRISP_DATA_EPSIZE,
-										                   ENDPOINT_BANK_SINGLE);
+		EndpointConfigSuccess &= Endpoint_ConfigureEndpoint(AVRISP_DATA_OUT_EPNUM, EP_TYPE_BULK,
+										                    ENDPOINT_DIR_OUT, AVRISP_DATA_EPSIZE,
+										                    ENDPOINT_BANK_SINGLE);
+
+		#if defined(WIN_LIBUSB_COMPAT)
+		EndpointConfigSuccess &= Endpoint_ConfigureEndpoint(AVRISP_DATA_IN_EPNUM, EP_TYPE_BULK,
+		                                                    ENDPOINT_DIR_IN, AVRISP_DATA_EPSIZE,
+		                                                    ENDPOINT_BANK_SINGLE);
+		#endif
 	}
 
 	if (EndpointConfigSuccess)
diff --git a/Projects/XPLAINBridge/XPLAINBridge.txt b/Projects/XPLAINBridge/XPLAINBridge.txt
index f967d3b76..cd8efbc10 100644
--- a/Projects/XPLAINBridge/XPLAINBridge.txt
+++ b/Projects/XPLAINBridge/XPLAINBridge.txt
@@ -78,5 +78,12 @@
  *    <td>RingBuff.h</td>
  *    <td>Defines the maximum number of bytes which can be buffered in each Ring Buffer.</td>
  *   </tr>
+ *   <tr>
+ *    <td>WIN_LIBUSB_COMPAT</td>
+ *    <td>Makefile CDEFS</td>
+ *    <td>Define to switch to a non-standard endpoint scheme, breaking compatibility with AVRStudio under Windows but making
+ *        the code compatible with Windows builds of avrdude using the libUSB driver. Linux platforms are not affected by this
+ *        option.
+ *   </tr>
  *  </table>
  */
\ No newline at end of file
diff --git a/Projects/XPLAINBridge/makefile b/Projects/XPLAINBridge/makefile
index ba87e8a1f..dfecaa2d5 100644
--- a/Projects/XPLAINBridge/makefile
+++ b/Projects/XPLAINBridge/makefile
@@ -202,6 +202,8 @@ CDEFS += -DAUX_LINE_PIN=PINB
 CDEFS += -DAUX_LINE_DDR=DDRB
 CDEFS += -DAUX_LINE_MASK="(1 << 4)"
 CDEFS += -DVTARGET_ADC_CHANNEL=2
+#CDEFS += -DLIBUSB_FILTERDRV_COMPAT
+
 
 # Place -D or -U options here for ASM sources
 ADEFS = -DF_CPU=$(F_CPU)
-- 
GitLab