diff --git a/Projects/AVRISP/Lib/XPROG/TINYNVM.c b/Projects/AVRISP/Lib/XPROG/TINYNVM.c
index 5eb59892eb98e2f5d58e3b93ac03762ac6b54a51..f4b90ffa58f4b5ff65807cee5e05aafa3ca5153e 100644
--- a/Projects/AVRISP/Lib/XPROG/TINYNVM.c
+++ b/Projects/AVRISP/Lib/XPROG/TINYNVM.c
@@ -38,44 +38,35 @@
 
 #if defined(ENABLE_XPROG_PROTOCOL) || defined(__DOXYGEN__)
 
-/** Busy-waits while the NVM controller is busy performing a NVM operation, such as a FLASH page read or CRC
- *  calculation.
+/** Busy-waits while the NVM controller is busy performing a NVM operation, such as a FLASH page read.
  *
  *  \return Boolean true if the NVM controller became ready within the timeout period, false otherwise
  */
-bool XMEGANVM_WaitWhileNVMBusBusy(void)
+bool TINYNVM_WaitWhileNVMBusBusy(void)
 {
-	// TODO
+	TCNT0 = 0;
+	TIFR0 = (1 << OCF1A);
+			
+	uint8_t TimeoutMS = TINY_NVM_BUSY_TIMEOUT_MS;
 	
-	return false;
-}
+	/* Poll the STATUS register to check to see if NVM access has been enabled */
+	while (TimeoutMS)
+	{
+		/* Send the SLDCS command to read the TPI STATUS register to see the NVM bus is active */
+		XPROGTarget_SendByte(TPI_CMD_SLDCS | TPI_STATUS_REG);
+		if (XPROGTarget_ReceiveByte() & TPI_STATUS_NVM)
+		  return true;
 
-/** Waits while the target's NVM controller is busy performing an operation, exiting if the
- *  timeout period expires.
- *
- *  \return Boolean true if the NVM controller became ready within the timeout period, false otherwise
- */
-bool XMEGANVM_WaitWhileNVMControllerBusy(void)
-{
-	// TODO
+		if (TIFR0 & (1 << OCF1A))
+		{
+			TIFR0 = (1 << OCF1A);
+			TimeoutMS--;
+		}
+	}
 	
 	return false;
 }
 
-/** Retrieves the CRC value of the given memory space.
- *
- *  \param[in]  CRCCommand  NVM CRC command to issue to the target
- *  \param[out] CRCDest     CRC Destination when read from the target
- *
- *  \return Boolean true if the command sequence complete successfully
- */
-bool XMEGANVM_GetMemoryCRC(const uint8_t CRCCommand, uint32_t* const CRCDest)
-{
-	// TODO
-
-	return true;
-}
-
 /** Reads memory from the target's memory spaces.
  *
  *  \param[in]  ReadAddress  Start address to read from within the target's address space
@@ -84,7 +75,7 @@ bool XMEGANVM_GetMemoryCRC(const uint8_t CRCCommand, uint32_t* const CRCDest)
  *
  *  \return Boolean true if the command sequence complete successfully
  */
-bool XMEGANVM_ReadMemory(const uint32_t ReadAddress, uint8_t* ReadBuffer, const uint16_t ReadSize)
+bool TINYNVM_ReadMemory(const uint32_t ReadAddress, uint8_t* ReadBuffer, const uint16_t ReadSize)
 {
 	// TODO
 	
@@ -99,7 +90,7 @@ bool XMEGANVM_ReadMemory(const uint32_t ReadAddress, uint8_t* ReadBuffer, const
  *
  *  \return Boolean true if the command sequence complete successfully
  */
-bool XMEGANVM_WriteMemory(const uint8_t WriteCommand, const uint32_t WriteAddress, const uint8_t* WriteBuffer)
+bool TINYNVM_WriteMemory(const uint8_t WriteCommand, const uint32_t WriteAddress, const uint8_t* WriteBuffer)
 {
 	// TODO
 	
@@ -113,7 +104,7 @@ bool XMEGANVM_WriteMemory(const uint8_t WriteCommand, const uint32_t WriteAddres
  *
  *  \return Boolean true if the command sequence complete successfully
  */
-bool XMEGANVM_EraseMemory(const uint8_t EraseCommand, const uint32_t Address)
+bool TINYNVM_EraseMemory(const uint8_t EraseCommand, const uint32_t Address)
 {
 	// TODO
 	
diff --git a/Projects/AVRISP/Lib/XPROG/TINYNVM.h b/Projects/AVRISP/Lib/XPROG/TINYNVM.h
index 11d4efcd1cd6ff7adf81bd301d21c49179141ce3..ecf429e774e1a62a4df54609ff237f111ebc4996 100644
--- a/Projects/AVRISP/Lib/XPROG/TINYNVM.h
+++ b/Projects/AVRISP/Lib/XPROG/TINYNVM.h
@@ -59,10 +59,9 @@
 		#define TINY_NVM_BUSY_TIMEOUT_MS       100
 
 	/* Function Prototypes: */
-		bool TINYNVM_WaitWhileNVMControllerBusy(void);
+		bool TINYNVM_WaitWhileNVMBusBusy(void);
 		bool TINYNVM_ReadMemory(const uint32_t ReadAddress, uint8_t* ReadBuffer, const uint16_t ReadSize);
 		bool TINYNVM_WriteMemory(const uint8_t WriteCommand, const uint32_t WriteAddress, const uint8_t* WriteBuffer);
 		bool TINYNVM_EraseMemory(const uint8_t EraseCommand, const uint32_t Address);
-		bool TINYNVM_WaitWhileNVMBusBusy(void);
 
 #endif
diff --git a/Projects/AVRISP/Lib/XPROG/XMEGANVM.h b/Projects/AVRISP/Lib/XPROG/XMEGANVM.h
index 10049f4a12c014764601462d2eee7884c03b4149..6a4de1fb127d3eb1ffee3418ea019cb8a8c9a242 100644
--- a/Projects/AVRISP/Lib/XPROG/XMEGANVM.h
+++ b/Projects/AVRISP/Lib/XPROG/XMEGANVM.h
@@ -108,6 +108,7 @@
 	/* Function Prototypes: */
 		void XMEGANVM_SendNVMRegAddress(const uint8_t Register);
 		void XMEGANVM_SendAddress(const uint32_t AbsoluteAddress);
+		bool XMEGANVM_WaitWhileNVMBusBusy(void);
 		bool XMEGANVM_WaitWhileNVMControllerBusy(void);
 		bool XMEGANVM_GetMemoryCRC(const uint8_t CRCCommand, uint32_t* const CRCDest);
 		bool XMEGANVM_ReadMemory(const uint32_t ReadAddress, uint8_t* ReadBuffer, const uint16_t ReadSize);
@@ -116,6 +117,5 @@
 		                              const uint8_t WritePageCommand, const uint8_t PageMode, const uint32_t WriteAddress,
 		                              const uint8_t* WriteBuffer, const uint16_t WriteSize);
 		bool XMEGANVM_EraseMemory(const uint8_t EraseCommand, const uint32_t Address);
-		bool XMEGANVM_WaitWhileNVMBusBusy(void);
 
 #endif
diff --git a/Projects/AVRISP/Lib/XPROG/XPROGProtocol.c b/Projects/AVRISP/Lib/XPROG/XPROGProtocol.c
index f83561c832ec8c59390b1ee75893635edda10961..edcc874d745c7faee3d3c799e031b177ba62ce67 100644
--- a/Projects/AVRISP/Lib/XPROG/XPROGProtocol.c
+++ b/Projects/AVRISP/Lib/XPROG/XPROGProtocol.c
@@ -132,7 +132,13 @@ static void XPROGProtocol_EnterXPROGMode(void)
 		/* Enable TPI programming mode with the attached target */
 		XPROGTarget_EnableTargetTPI();
 		
-		// TODO - enable NVM bus via KEY		
+		/* Enable access to the XPROG NVM bus by sending the documented NVM access key to the device */
+		XPROGTarget_SendByte(TPI_CMD_SKEY);	
+		for (uint8_t i = sizeof(TPI_NVMENABLE_KEY); i > 0; i--)
+		  XPROGTarget_SendByte(TPI_NVMENABLE_KEY[i - 1]);
+
+		/* Wait until the NVM bus becomes active */
+		NVMBusEnabled = TINYNVM_WaitWhileNVMBusBusy();
 	}
 	
 	Endpoint_Write_Byte(CMD_XPROG);
@@ -159,7 +165,9 @@ static void XPROGProtocol_LeaveXPROGMode(void)
 	}
 	else
 	{
-		// TODO - Disable TPI via register
+		/* Clear the NVMEN bit in the TPI CONTROL register to disable TPI mode */
+		XPROGTarget_SendByte(TPI_CMD_SSTCS | TPI_CTRL_REG);	
+		XPROGTarget_SendByte(0x00);
 	
 		XPROGTarget_DisableTargetTPI();
 	}