diff --git a/Projects/Incomplete/AVRISP/AVRISP.c b/Projects/Incomplete/AVRISP/AVRISP.c
index f3634fd70609290ee1e06b21085203bde0a63639..32919ef8ef4bbee5662c08e5393af5b86e5f0a93 100644
--- a/Projects/Incomplete/AVRISP/AVRISP.c
+++ b/Projects/Incomplete/AVRISP/AVRISP.c
@@ -37,6 +37,7 @@
 // TODO: Add reversed target connector checks
 // TODO: Add in software SPI for lower programming speeds below 125KHz
 // TODO: Add in VTARGET detection
+// TODO: Add in software SPI for lower programming speeds
 
 #include "AVRISP.h"
 
@@ -72,6 +73,11 @@ void SetupHardware(void)
 	/* Hardware Initialization */
 	LEDs_Init();
 	USB_Init();
+
+	/* Millisecond timer initialization for timeout checking */
+	OCR0A  = ((F_CPU / 64) / 1000);
+	TCCR0A = (1 << WGM01);
+	TCCR0B = ((1 << CS01) | (1 << CS00));
 }
 
 /** Event handler for the library USB Connection event. */
diff --git a/Projects/Incomplete/AVRISP/Lib/V2Protocol.c b/Projects/Incomplete/AVRISP/Lib/V2Protocol.c
index 16a1a0708661707d89b8f844fe98c188b53ce664..2c2966906769dcf1e034f7ade2c83722dc2af9a6 100644
--- a/Projects/Incomplete/AVRISP/Lib/V2Protocol.c
+++ b/Projects/Incomplete/AVRISP/Lib/V2Protocol.c
@@ -52,6 +52,9 @@ void V2Protocol_ProcessCommand(void)
 		case CMD_LOAD_ADDRESS:
 			V2Protocol_Command_LoadAddress();
 			break;
+		case CMD_RESET_PROTECTION:
+			V2Protocol_Command_ResetProtection();
+			break;
 		case CMD_ENTER_PROGMODE_ISP:
 			V2Protocol_Command_EnterISPMode();
 			break;
@@ -168,6 +171,16 @@ static void V2Protocol_Command_LoadAddress(void)
 	Endpoint_ClearIN();
 }
 
+static void V2Protocol_Command_ResetProtection(void)
+{
+	Endpoint_ClearOUT();
+	Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
+	
+	Endpoint_Write_Byte(CMD_RESET_PROTECTION);
+	Endpoint_Write_Byte(STATUS_CMD_OK);
+	Endpoint_ClearIN();	
+}
+
 static void V2Protocol_Command_EnterISPMode(void)
 {
 	struct
@@ -208,7 +221,7 @@ static void V2Protocol_Command_EnterISPMode(void)
 		}
 		
 		/* Check if polling disabled, or if the polled value matches the expected value */
-		if (!Enter_ISP_Params.PollIndex || (ResponseBytes[Enter_ISP_Params.PollIndex - 1] == Enter_ISP_Params.PollValue))
+		if (!(Enter_ISP_Params.PollIndex) || (ResponseBytes[Enter_ISP_Params.PollIndex - 1] == Enter_ISP_Params.PollValue))
 		{
 			ResponseStatus = STATUS_CMD_OK;
 		}
@@ -264,6 +277,8 @@ static void V2Protocol_Command_ProgramMemory(uint8_t V2Command)
 	
 	uint8_t  ProgrammingStatus = STATUS_CMD_OK;	
 	uint16_t PollAddress       = 0;
+	uint8_t  PollValue         = (V2Command == CMD_PROGRAM_FLASH_ISP) ? Write_Memory_Params.PollValue1 :
+	                                                                    Write_Memory_Params.PollValue2;
 	
 	if (Write_Memory_Params.ProgrammingMode & PROG_MODE_PAGED_WRITES_MASK)
 	{
@@ -281,11 +296,11 @@ static void V2Protocol_Command_ProgramMemory(uint8_t V2Command)
 			SPI_SendByte(CurrentAddress & 0xFF);
 			SPI_SendByte(ByteToWrite);
 			
-			if (!(PollAddress))
+			if (!(PollAddress) && (ByteToWrite != PollValue))
 			{
-				if ((ByteToWrite != Write_Memory_Params.PollValue1) && (V2Command == CMD_PROGRAM_FLASH_ISP))
+				if (V2Command == CMD_PROGRAM_FLASH_ISP)
 				  PollAddress = (((CurrentAddress & 0xFFFF) << 1) | IsOddByte);
-				else if ((ByteToWrite != Write_Memory_Params.PollValue2) && (V2Command == CMD_PROGRAM_EEPROM_ISP))
+				else
 				  PollAddress = (CurrentAddress & 0xFFFF);				
 			}
 
@@ -309,7 +324,9 @@ static void V2Protocol_Command_ProgramMemory(uint8_t V2Command)
 			}
 		}
 		
-		ProgrammingStatus = V2Protocol_WaitForProgrammingComplete(PollAddress, Write_Memory_Params.ProgrammingMode);
+		ProgrammingStatus = V2Protocol_WaitForProgComplete(Write_Memory_Params.ProgrammingMode, PollAddress, PollValue,
+			                                               Write_Memory_Params.DelayMS, (V2Command == CMD_READ_FLASH_ISP),
+			                                               Write_Memory_Params.ProgrammingCommands[2]);
 	}
 	else
 	{
@@ -327,15 +344,20 @@ static void V2Protocol_Command_ProgramMemory(uint8_t V2Command)
 			SPI_SendByte(CurrentAddress & 0xFF);
 			SPI_SendByte(ByteToWrite);
 			
-			if ((ByteToWrite != Write_Memory_Params.PollValue1) && (V2Command == CMD_PROGRAM_FLASH_ISP))
-			  PollAddress = (((CurrentAddress & 0xFFFF) << 1) | IsOddByte);
-			else if ((ByteToWrite != Write_Memory_Params.PollValue2) && (V2Command == CMD_PROGRAM_EEPROM_ISP))
-			  PollAddress = (CurrentAddress & 0xFFFF);
-
-			ProgrammingStatus = V2Protocol_WaitForProgrammingComplete(PollAddress, Write_Memory_Params.ProgrammingMode);
-
+			if (ByteToWrite != PollValue)
+			{
+				if (V2Command == CMD_PROGRAM_FLASH_ISP)
+				  PollAddress = (((CurrentAddress & 0xFFFF) << 1) | IsOddByte);
+				else
+				  PollAddress = (CurrentAddress & 0xFFFF);
+			}
+			
 			if (IsOddByte || (V2Command == CMD_PROGRAM_EEPROM_ISP))
 			  CurrentAddress++;
+			
+			ProgrammingStatus = V2Protocol_WaitForProgComplete(Write_Memory_Params.ProgrammingMode, PollAddress, PollValue,
+			                                                   Write_Memory_Params.DelayMS, (V2Command == CMD_READ_FLASH_ISP),
+			                                                   Write_Memory_Params.ProgrammingCommands[2]);
 			  
 			if (ProgrammingStatus != STATUS_CMD_OK)
 			  break;
@@ -390,7 +412,17 @@ static void V2Protocol_Command_ReadMemory(uint8_t V2Command)
 	}
 
 	Endpoint_Write_Byte(STATUS_CMD_OK);
+
+	bool IsEndpointFull = !(Endpoint_IsReadWriteAllowed());
 	Endpoint_ClearIN();
+	
+	/* Ensure last packet is a short packet to terminate the transfer */
+	if (IsEndpointFull)
+	{
+		Endpoint_WaitUntilReady();	
+		Endpoint_ClearIN();
+		Endpoint_WaitUntilReady();	
+	}
 }
 
 static void V2Protocol_Command_ChipErase(void)
@@ -412,7 +444,7 @@ static void V2Protocol_Command_ChipErase(void)
 	for (uint8_t SByte = 0; SByte < sizeof(Erase_Chip_Params.EraseCommandBytes); SByte++)
 	  SPI_SendByte(Erase_Chip_Params.EraseCommandBytes[SByte]);
 
-	if (Erase_Chip_Params.PollMethod == 0)
+	if (!(Erase_Chip_Params.PollMethod))
 	  V2Protocol_DelayMS(Erase_Chip_Params.EraseDelayMS);
 	else
 	  ResponseStatus = V2Protocol_WaitWhileTargetBusy();
diff --git a/Projects/Incomplete/AVRISP/Lib/V2Protocol.h b/Projects/Incomplete/AVRISP/Lib/V2Protocol.h
index cd9648253ff8b550ca4e9ea730dd5ed3e55dfca0..55c1c78c24a5b009f7b64c8fa1d0fb63e91d1816 100644
--- a/Projects/Incomplete/AVRISP/Lib/V2Protocol.h
+++ b/Projects/Incomplete/AVRISP/Lib/V2Protocol.h
@@ -56,7 +56,6 @@
 		#define PROG_MODE_PAGED_TIMEDELAY_MASK  (1 << 4)
 		#define PROG_MODE_PAGED_VALUE_MASK      (1 << 5)
 		#define PROG_MODE_PAGED_READYBUSY_MASK  (1 << 6)
-
 		#define PROG_MODE_COMMIT_PAGE_MASK      (1 << 7)
 
 	/* Function Prototypes: */
@@ -67,6 +66,7 @@
 			static void V2Protocol_Command_SignOn(void);
 			static void V2Protocol_Command_GetSetParam(uint8_t V2Command);
 			static void V2Protocol_Command_LoadAddress(void);
+			static void V2Protocol_Command_ResetProtection(void);
 			static void V2Protocol_Command_EnterISPMode(void);
 			static void V2Protocol_Command_LeaveISPMode(void);
 			static void V2Protocol_Command_ProgramMemory(uint8_t V2Command);
diff --git a/Projects/Incomplete/AVRISP/Lib/V2ProtocolParams.c b/Projects/Incomplete/AVRISP/Lib/V2ProtocolParams.c
index 74c8f202406107e613f81366e9110611ece3c9e2..a95e8757efc8e0ef5673d4674141f8e18629f831 100644
--- a/Projects/Incomplete/AVRISP/Lib/V2ProtocolParams.c
+++ b/Projects/Incomplete/AVRISP/Lib/V2ProtocolParams.c
@@ -63,7 +63,7 @@ static ParameterItem_t ParameterTable[] =
 		  .ParamPrivellages = PARAM_PRIV_READ                    },
 
 		{ .ParamID          = PARAM_VTARGET,
-		  .ParamValue       = 0x00,
+		  .ParamValue       = 0x32,
 		  .ParamPrivellages = PARAM_PRIV_READ                    },
 
 		{ .ParamID          = PARAM_SCK_DURATION,
diff --git a/Projects/Incomplete/AVRISP/Lib/V2ProtocolTarget.c b/Projects/Incomplete/AVRISP/Lib/V2ProtocolTarget.c
index b2064fc26ce6149a51c78f75076e15c8810ff48c..f9b4427cedbebce3a0dcc24d98307ce65d0a1410 100644
--- a/Projects/Incomplete/AVRISP/Lib/V2ProtocolTarget.c
+++ b/Projects/Incomplete/AVRISP/Lib/V2ProtocolTarget.c
@@ -78,22 +78,58 @@ void V2Protocol_ChangeTargetResetLine(bool ResetTarget)
 
 void V2Protocol_DelayMS(uint8_t MS)
 {
-	while (MS--)
-	  _delay_ms(1);
+	TCNT0  = 0;
+	while (TCNT0 < MS);
 }
 
-uint8_t V2Protocol_WaitForProgrammingComplete(uint16_t PollAddress, uint8_t ProgrammingMode)
+uint8_t V2Protocol_WaitForProgComplete(uint8_t ProgrammingMode, uint16_t PollAddress, uint8_t PollValue,
+                                       uint8_t DelayMS, bool IsFlashMemory, uint8_t ReadMemCommand)
 {
-	// TODO
+	uint8_t ProgrammingStatus = STATUS_CMD_OK;
 
-	return STATUS_CMD_OK;
+	/* Determine method of Programming Complete check */
+	switch (ProgrammingMode & ~(PROG_MODE_PAGED_WRITES_MASK | PROG_MODE_COMMIT_PAGE_MASK))
+	{
+		case PROG_MODE_WORD_TIMEDELAY_MASK:
+		case PROG_MODE_PAGED_TIMEDELAY_MASK:
+			V2Protocol_DelayMS(DelayMS);
+			break;
+		case PROG_MODE_WORD_VALUE_MASK:
+		case PROG_MODE_PAGED_VALUE_MASK:
+			if (IsFlashMemory && (PollAddress & 0x01))
+			{
+				ReadMemCommand |= READ_WRITE_ODD_BYTE_MASK;
+				PollAddress >>= 1;
+			}
+
+			TCNT0  = 0;
+
+			do
+			{
+				SPI_SendByte(ReadMemCommand);
+				SPI_SendByte(PollAddress >> 8);
+				SPI_SendByte(PollAddress & 0xFF);				
+			}
+			while ((SPI_TransferByte(0x00) != PollValue) && (TCNT0 < TARGET_BUSY_TIMEOUT_MS));
+
+			if (TCNT0 >= TARGET_BUSY_TIMEOUT_MS)
+			 ProgrammingStatus = STATUS_RDY_BSY_TOUT;
+			
+			break;		
+		case PROG_MODE_WORD_READYBUSY_MASK:
+		case PROG_MODE_PAGED_READYBUSY_MASK:
+			ProgrammingStatus = V2Protocol_WaitWhileTargetBusy();
+	}
+
+	return ProgrammingStatus;
 }
 
 uint8_t V2Protocol_WaitWhileTargetBusy(void)
 {
-	uint8_t TimeoutMS = TARGET_BUSY_TIMEOUT_MS;
 	uint8_t ResponseByte;
 	
+	TCNT0  = 0;
+	
 	do
 	{
 		SPI_SendByte(0xF0);
@@ -101,13 +137,11 @@ uint8_t V2Protocol_WaitWhileTargetBusy(void)
 
 		SPI_SendByte(0x00);
 		ResponseByte = SPI_ReceiveByte();
-
-		V2Protocol_DelayMS(1);
 	}
-	while ((ResponseByte & 0x01) && (TimeoutMS--));
+	while ((ResponseByte & 0x01) && (TCNT0 < TARGET_BUSY_TIMEOUT_MS));
 
-	if (!(TimeoutMS))
-	  return STATUS_CMD_TOUT;
+	if (TCNT0 >= TARGET_BUSY_TIMEOUT_MS)
+	  return STATUS_RDY_BSY_TOUT;
 	else
 	  return STATUS_CMD_OK;
 }
diff --git a/Projects/Incomplete/AVRISP/Lib/V2ProtocolTarget.h b/Projects/Incomplete/AVRISP/Lib/V2ProtocolTarget.h
index 847770c7b81fa26d0451e469e73cdb7174f5db11..d67f84708a8c6b6e18f9412010f49d9b7816a7bb 100644
--- a/Projects/Incomplete/AVRISP/Lib/V2ProtocolTarget.h
+++ b/Projects/Incomplete/AVRISP/Lib/V2ProtocolTarget.h
@@ -48,7 +48,7 @@
 		#include "V2ProtocolParams.h"
 
 	/* Macros: */
-		#define TARGET_BUSY_TIMEOUT_MS    100
+		#define TARGET_BUSY_TIMEOUT_MS    200
 	
 	/* External Variables: */
 		extern uint32_t CurrentAddress;
@@ -57,7 +57,8 @@
 			uint8_t V2Protocol_GetSPIPrescalerMask(void);
 			void    V2Protocol_ChangeTargetResetLine(bool ResetTarget);
 			void    V2Protocol_DelayMS(uint8_t MS);
-			uint8_t V2Protocol_WaitForProgrammingComplete(uint16_t PollAddress, uint8_t ProgrammingMode);
+			uint8_t V2Protocol_WaitForProgComplete(uint8_t ProgrammingMode, uint16_t PollAddress, uint8_t PollValue,
+                                                   uint8_t DelayMS, bool IsFlashMemory, uint8_t ReadMemCommand);
 			uint8_t V2Protocol_WaitWhileTargetBusy(void);
 			void    V2Protocol_LoadExtendedAddress(void);