Make TPI writes add a dummy high byte if the data isn't word-aligned.
[pub/USBasp.git] / Projects / AVRISP-MKII / Lib / XPROG / XPROGTarget.c
index 7908c65..e77d77b 100644 (file)
@@ -1,21 +1,21 @@
 /*\r
              LUFA Library\r
 /*\r
              LUFA Library\r
-     Copyright (C) Dean Camera, 2009.\r
+     Copyright (C) Dean Camera, 2010.\r
               \r
   dean [at] fourwalledcubicle [dot] com\r
       www.fourwalledcubicle.com\r
 */\r
 \r
 /*\r
               \r
   dean [at] fourwalledcubicle [dot] com\r
       www.fourwalledcubicle.com\r
 */\r
 \r
 /*\r
-  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
-\r
-  Permission to use, copy, modify, and distribute this software\r
-  and its documentation for any purpose and without fee is hereby\r
-  granted, provided that the above copyright notice appear in all\r
-  copies and that both that the copyright notice and this\r
-  permission notice and warranty disclaimer appear in supporting\r
-  documentation, and that the name of the author not be used in\r
-  advertising or publicity pertaining to distribution of the\r
+  Copyright 2010  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
+\r
+  Permission to use, copy, modify, distribute, and sell this \r
+  software and its documentation for any purpose is hereby granted\r
+  without fee, provided that the above copyright notice appear in \r
+  all copies and that both that the copyright notice and this\r
+  permission notice and warranty disclaimer appear in supporting \r
+  documentation, and that the name of the author not be used in \r
+  advertising or publicity pertaining to distribution of the \r
   software without specific, written prior permission.\r
 \r
   The author disclaim all warranties with regard to this\r
   software without specific, written prior permission.\r
 \r
   The author disclaim all warranties with regard to this\r
@@ -71,7 +71,7 @@ ISR(TIMER1_COMPA_vect, ISR_BLOCK)
                  return;\r
        \r
                /* Shift in the bit one less than the frame size in position, so that the start bit will eventually\r
                  return;\r
        \r
                /* Shift in the bit one less than the frame size in position, so that the start bit will eventually\r
-                * be discarded leaving the data to be byte-aligned for quick access */\r
+                * be discarded leaving the data to be byte-aligned for quick access (subtract 9 as we are ORing to the MSB) */\r
                if (BITBANG_PDIDATA_PIN & BITBANG_PDIDATA_MASK)\r
                  ((uint8_t*)&SoftUSART_Data)[1] |= (1 << (BITS_IN_USART_FRAME - 9));\r
 \r
                if (BITBANG_PDIDATA_PIN & BITBANG_PDIDATA_MASK)\r
                  ((uint8_t*)&SoftUSART_Data)[1] |= (1 << (BITS_IN_USART_FRAME - 9));\r
 \r
@@ -96,7 +96,7 @@ ISR(TIMER1_COMPA_vect, ISR_BLOCK)
 }\r
 \r
 /** ISR to manage the TPI software USART when bit-banged TPI USART mode is selected. */\r
 }\r
 \r
 /** ISR to manage the TPI software USART when bit-banged TPI USART mode is selected. */\r
-ISR(TIMER1_COMPB_vect, ISR_BLOCK)\r
+ISR(TIMER1_CAPT_vect, ISR_BLOCK)\r
 {\r
        /* Toggle CLOCK pin in a single cycle (see AVR datasheet) */\r
        BITBANG_TPICLOCK_PIN |= BITBANG_TPICLOCK_MASK;\r
 {\r
        /* Toggle CLOCK pin in a single cycle (see AVR datasheet) */\r
        BITBANG_TPICLOCK_PIN |= BITBANG_TPICLOCK_MASK;\r
@@ -117,7 +117,7 @@ ISR(TIMER1_COMPB_vect, ISR_BLOCK)
                  return;\r
        \r
                /* Shift in the bit one less than the frame size in position, so that the start bit will eventually\r
                  return;\r
        \r
                /* Shift in the bit one less than the frame size in position, so that the start bit will eventually\r
-                * be discarded leaving the data to be byte-aligned for quick access */\r
+                * be discarded leaving the data to be byte-aligned for quick access (subtract 9 as we are ORing to the MSB) */\r
                if (BITBANG_TPIDATA_PIN & BITBANG_TPIDATA_MASK)\r
                 ((uint8_t*)&SoftUSART_Data)[1] |= (1 << (BITS_IN_USART_FRAME - 9));\r
 \r
                if (BITBANG_TPIDATA_PIN & BITBANG_TPIDATA_MASK)\r
                 ((uint8_t*)&SoftUSART_Data)[1] |= (1 << (BITS_IN_USART_FRAME - 9));\r
 \r
@@ -145,6 +145,8 @@ ISR(TIMER1_COMPB_vect, ISR_BLOCK)
 /** Enables the target's PDI interface, holding the target in reset until PDI mode is exited. */\r
 void XPROGTarget_EnableTargetPDI(void)\r
 {\r
 /** Enables the target's PDI interface, holding the target in reset until PDI mode is exited. */\r
 void XPROGTarget_EnableTargetPDI(void)\r
 {\r
+       IsSending = false;\r
+\r
 #if defined(XPROG_VIA_HARDWARE_USART)\r
        /* Set Tx and XCK as outputs, Rx as input */\r
        DDRD |=  (1 << 5) | (1 << 3);\r
 #if defined(XPROG_VIA_HARDWARE_USART)\r
        /* Set Tx and XCK as outputs, Rx as input */\r
        DDRD |=  (1 << 5) | (1 << 3);\r
@@ -152,18 +154,13 @@ void XPROGTarget_EnableTargetPDI(void)
        \r
        /* Set DATA line high for at least 90ns to disable /RESET functionality */\r
        PORTD |= (1 << 3);\r
        \r
        /* Set DATA line high for at least 90ns to disable /RESET functionality */\r
        PORTD |= (1 << 3);\r
-       asm volatile ("NOP"::);\r
-       asm volatile ("NOP"::);\r
+       _delay_us(1);\r
        \r
        /* Set up the synchronous USART for XMEGA communications - \r
           8 data bits, even parity, 2 stop bits */\r
        \r
        /* Set up the synchronous USART for XMEGA communications - \r
           8 data bits, even parity, 2 stop bits */\r
-       UBRR1  = (F_CPU / 1000000UL);\r
+       UBRR1  = (F_CPU / 500000UL);\r
        UCSR1B = (1 << TXEN1);\r
        UCSR1C = (1 << UMSEL10) | (1 << UPM11) | (1 << USBS1) | (1 << UCSZ11) | (1 << UCSZ10) | (1 << UCPOL1);\r
        UCSR1B = (1 << TXEN1);\r
        UCSR1C = (1 << UMSEL10) | (1 << UPM11) | (1 << USBS1) | (1 << UCSZ11) | (1 << UCSZ10) | (1 << UCPOL1);\r
-\r
-       /* Send two BREAKs of 12 bits each to enable PDI interface (need at least 16 idle bits) */\r
-       XPROGTarget_SendBreak();\r
-       XPROGTarget_SendBreak();\r
 #else\r
        /* Set DATA and CLOCK lines to outputs */\r
        BITBANG_PDIDATA_DDR  |= BITBANG_PDIDATA_MASK;\r
 #else\r
        /* Set DATA and CLOCK lines to outputs */\r
        BITBANG_PDIDATA_DDR  |= BITBANG_PDIDATA_MASK;\r
@@ -171,43 +168,39 @@ void XPROGTarget_EnableTargetPDI(void)
        \r
        /* Set DATA line high for at least 90ns to disable /RESET functionality */\r
        BITBANG_PDIDATA_PORT |= BITBANG_PDIDATA_MASK;\r
        \r
        /* Set DATA line high for at least 90ns to disable /RESET functionality */\r
        BITBANG_PDIDATA_PORT |= BITBANG_PDIDATA_MASK;\r
-       asm volatile ("NOP"::);\r
-       asm volatile ("NOP"::);\r
+       _delay_us(1);\r
 \r
 \r
-       /* Fire timer compare channel A ISR every 90 cycles to manage the software USART */\r
-       OCR1A   = 90;\r
+       /* Fire timer compare channel A ISR to manage the software USART */\r
+       OCR1A   = BITS_BETWEEN_USART_CLOCKS;\r
        TCCR1B  = (1 << WGM12) | (1 << CS10);\r
        TIMSK1  = (1 << OCIE1A);\r
        TCCR1B  = (1 << WGM12) | (1 << CS10);\r
        TIMSK1  = (1 << OCIE1A);\r
-       \r
-       /* Send two BREAKs of 12 bits each to enable TPI interface (need at least 16 idle bits) */\r
+#endif\r
+\r
+       /* Send two BREAKs of 12 bits each to enable PDI interface (need at least 16 idle bits) */\r
        XPROGTarget_SendBreak();\r
        XPROGTarget_SendBreak();\r
        XPROGTarget_SendBreak();\r
        XPROGTarget_SendBreak();\r
-#endif\r
 }\r
 \r
 /** Enables the target's TPI interface, holding the target in reset until TPI mode is exited. */\r
 void XPROGTarget_EnableTargetTPI(void)\r
 {\r
 }\r
 \r
 /** Enables the target's TPI interface, holding the target in reset until TPI mode is exited. */\r
 void XPROGTarget_EnableTargetTPI(void)\r
 {\r
-       /* Set /RESET line low for at least 90ns to enable TPI functionality */\r
-       RESET_LINE_DDR  |= RESET_LINE_MASK;\r
-       RESET_LINE_PORT &= ~RESET_LINE_MASK;\r
-       asm volatile ("NOP"::);\r
-       asm volatile ("NOP"::);\r
+       IsSending = false;\r
+\r
+       /* Set /RESET line low for at least 400ns to enable TPI functionality */\r
+       AUX_LINE_DDR  |=  AUX_LINE_MASK;\r
+       AUX_LINE_PORT &= ~AUX_LINE_MASK;\r
+       _delay_us(1);\r
 \r
 #if defined(XPROG_VIA_HARDWARE_USART)\r
        /* Set Tx and XCK as outputs, Rx as input */\r
        DDRD |=  (1 << 5) | (1 << 3);\r
        DDRD &= ~(1 << 2);\r
                \r
 \r
 #if defined(XPROG_VIA_HARDWARE_USART)\r
        /* Set Tx and XCK as outputs, Rx as input */\r
        DDRD |=  (1 << 5) | (1 << 3);\r
        DDRD &= ~(1 << 2);\r
                \r
-       /* Set up the synchronous USART for XMEGA communications - \r
+       /* Set up the synchronous USART for TINY communications - \r
           8 data bits, even parity, 2 stop bits */\r
           8 data bits, even parity, 2 stop bits */\r
-       UBRR1  = (F_CPU / 1000000UL);\r
+       UBRR1  = (F_CPU / 500000UL);\r
        UCSR1B = (1 << TXEN1);\r
        UCSR1C = (1 << UMSEL10) | (1 << UPM11) | (1 << USBS1) | (1 << UCSZ11) | (1 << UCSZ10) | (1 << UCPOL1);\r
        UCSR1B = (1 << TXEN1);\r
        UCSR1C = (1 << UMSEL10) | (1 << UPM11) | (1 << USBS1) | (1 << UCSZ11) | (1 << UCSZ10) | (1 << UCPOL1);\r
-\r
-       /* Send two BREAKs of 12 bits each to enable TPI interface (need at least 16 idle bits) */\r
-       XPROGTarget_SendBreak();\r
-       XPROGTarget_SendBreak();\r
 #else\r
        /* Set DATA and CLOCK lines to outputs */\r
        BITBANG_TPIDATA_DDR  |= BITBANG_TPIDATA_MASK;\r
 #else\r
        /* Set DATA and CLOCK lines to outputs */\r
        BITBANG_TPIDATA_DDR  |= BITBANG_TPIDATA_MASK;\r
@@ -216,21 +209,28 @@ void XPROGTarget_EnableTargetTPI(void)
        /* Set DATA line high for idle state */\r
        BITBANG_TPIDATA_PORT |= BITBANG_TPIDATA_MASK;\r
 \r
        /* Set DATA line high for idle state */\r
        BITBANG_TPIDATA_PORT |= BITBANG_TPIDATA_MASK;\r
 \r
-       /* Fire timer capture channel B ISR every 90 cycles to manage the software USART */\r
-       OCR1B   = 9;\r
-       TCCR1B  = (1 << WGM12) | (1 << CS10);\r
-       TIMSK1  = (1 << OCIE1B);\r
-       \r
+       /* Fire timer capture channel ISR to manage the software USART */\r
+       ICR1    = BITS_BETWEEN_USART_CLOCKS;\r
+       TCCR1B  = (1 << WGM13) | (1 << WGM12) | (1 << CS10);\r
+       TIMSK1  = (1 << ICIE1);\r
+#endif\r
+\r
        /* Send two BREAKs of 12 bits each to enable TPI interface (need at least 16 idle bits) */\r
        XPROGTarget_SendBreak();\r
        XPROGTarget_SendBreak();\r
        /* Send two BREAKs of 12 bits each to enable TPI interface (need at least 16 idle bits) */\r
        XPROGTarget_SendBreak();\r
        XPROGTarget_SendBreak();\r
-#endif\r
 }\r
 \r
 /** Disables the target's PDI interface, exits programming mode and starts the target's application. */\r
 void XPROGTarget_DisableTargetPDI(void)\r
 {\r
 }\r
 \r
 /** Disables the target's PDI interface, exits programming mode and starts the target's application. */\r
 void XPROGTarget_DisableTargetPDI(void)\r
 {\r
+       /* Switch to Rx mode to ensure that all pending transmissions are complete */\r
+       XPROGTarget_SetRxMode();\r
+\r
 #if defined(XPROG_VIA_HARDWARE_USART)\r
 #if defined(XPROG_VIA_HARDWARE_USART)\r
+       /* Set /RESET high for a one millisecond to ensure target device is restarted */\r
+       PORTD |= (1 << 5);\r
+       _delay_ms(1);\r
+\r
        /* Turn off receiver and transmitter of the USART, clear settings */\r
        UCSR1A |= (1 << TXC1) | (1 << RXC1);\r
        UCSR1B  = 0;\r
        /* Turn off receiver and transmitter of the USART, clear settings */\r
        UCSR1A |= (1 << TXC1) | (1 << RXC1);\r
        UCSR1B  = 0;\r
@@ -240,6 +240,10 @@ void XPROGTarget_DisableTargetPDI(void)
        DDRD  &= ~((1 << 5) | (1 << 3));\r
        PORTD &= ~((1 << 5) | (1 << 3) | (1 << 2));\r
 #else\r
        DDRD  &= ~((1 << 5) | (1 << 3));\r
        PORTD &= ~((1 << 5) | (1 << 3) | (1 << 2));\r
 #else\r
+       /* Set /RESET high for a one millisecond to ensure target device is restarted */\r
+       BITBANG_PDICLOCK_PORT |= BITBANG_PDICLOCK_MASK;\r
+       _delay_ms(1);\r
+\r
        /* Set DATA and CLOCK lines to inputs */\r
        BITBANG_PDIDATA_DDR   &= ~BITBANG_PDIDATA_MASK;\r
        BITBANG_PDICLOCK_DDR  &= ~BITBANG_PDICLOCK_MASK;\r
        /* Set DATA and CLOCK lines to inputs */\r
        BITBANG_PDIDATA_DDR   &= ~BITBANG_PDIDATA_MASK;\r
        BITBANG_PDICLOCK_DDR  &= ~BITBANG_PDICLOCK_MASK;\r
@@ -253,6 +257,9 @@ void XPROGTarget_DisableTargetPDI(void)
 /** Disables the target's TPI interface, exits programming mode and starts the target's application. */\r
 void XPROGTarget_DisableTargetTPI(void)\r
 {\r
 /** Disables the target's TPI interface, exits programming mode and starts the target's application. */\r
 void XPROGTarget_DisableTargetTPI(void)\r
 {\r
+       /* Switch to Rx mode to ensure that all pending transmissions are complete */\r
+       XPROGTarget_SetRxMode();\r
+\r
 #if defined(XPROG_VIA_HARDWARE_USART)\r
        /* Turn off receiver and transmitter of the USART, clear settings */\r
        UCSR1A |= (1 << TXC1) | (1 << RXC1);\r
 #if defined(XPROG_VIA_HARDWARE_USART)\r
        /* Turn off receiver and transmitter of the USART, clear settings */\r
        UCSR1A |= (1 << TXC1) | (1 << RXC1);\r
@@ -273,8 +280,8 @@ void XPROGTarget_DisableTargetTPI(void)
 #endif\r
 \r
        /* Tristate target /RESET line */\r
 #endif\r
 \r
        /* Tristate target /RESET line */\r
-       RESET_LINE_DDR  &= ~RESET_LINE_MASK;\r
-       RESET_LINE_PORT &= ~RESET_LINE_MASK;\r
+       AUX_LINE_DDR  &= ~AUX_LINE_MASK;\r
+       AUX_LINE_PORT &= ~AUX_LINE_MASK;\r
 }\r
 \r
 /** Sends a byte via the USART.\r
 }\r
 \r
 /** Sends a byte via the USART.\r
@@ -283,38 +290,21 @@ void XPROGTarget_DisableTargetTPI(void)
  */\r
 void XPROGTarget_SendByte(const uint8_t Byte)\r
 {\r
  */\r
 void XPROGTarget_SendByte(const uint8_t Byte)\r
 {\r
-#if defined(XPROG_VIA_HARDWARE_USART)\r
        /* Switch to Tx mode if currently in Rx mode */\r
        if (!(IsSending))\r
        /* Switch to Tx mode if currently in Rx mode */\r
        if (!(IsSending))\r
-       {\r
-               PORTD  |=  (1 << 3);\r
-               DDRD   |=  (1 << 3);\r
-\r
-               UCSR1B |=  (1 << TXEN1);\r
-               UCSR1B &= ~(1 << RXEN1);\r
-               \r
-               IsSending = true;\r
-       }\r
-       \r
+         XPROGTarget_SetTxMode();\r
+         \r
+#if defined(XPROG_VIA_HARDWARE_USART)\r
        /* Wait until there is space in the hardware Tx buffer before writing */\r
        while (!(UCSR1A & (1 << UDRE1)));\r
        UCSR1A |= (1 << TXC1);\r
        UDR1    = Byte;\r
 #else\r
        /* Wait until there is space in the hardware Tx buffer before writing */\r
        while (!(UCSR1A & (1 << UDRE1)));\r
        UCSR1A |= (1 << TXC1);\r
        UDR1    = Byte;\r
 #else\r
-       /* Switch to Tx mode if currently in Rx mode */\r
-       if (!(IsSending))\r
-       {\r
-               BITBANG_PDIDATA_PORT |= BITBANG_PDIDATA_MASK;\r
-               BITBANG_PDIDATA_DDR  |= BITBANG_PDIDATA_MASK;\r
-\r
-               IsSending = true;\r
-       }\r
-\r
        /* Calculate the new USART frame data here while while we wait for a previous byte (if any) to finish sending */\r
        uint16_t NewUSARTData = ((1 << 11) | (1 << 10) | (0 << 9) | ((uint16_t)Byte << 1) | (0 << 0));\r
 \r
        /* Compute Even parity - while a bit is still set, chop off lowest bit and toggle parity bit */\r
        /* Calculate the new USART frame data here while while we wait for a previous byte (if any) to finish sending */\r
        uint16_t NewUSARTData = ((1 << 11) | (1 << 10) | (0 << 9) | ((uint16_t)Byte << 1) | (0 << 0));\r
 \r
        /* Compute Even parity - while a bit is still set, chop off lowest bit and toggle parity bit */\r
-       uint8_t ParityData    = Byte;\r
+       uint8_t ParityData = Byte;\r
        while (ParityData)\r
        {\r
                NewUSARTData ^= (1 << 9);\r
        while (ParityData)\r
        {\r
                NewUSARTData ^= (1 << 9);\r
@@ -336,37 +326,15 @@ void XPROGTarget_SendByte(const uint8_t Byte)
  */\r
 uint8_t XPROGTarget_ReceiveByte(void)\r
 {\r
  */\r
 uint8_t XPROGTarget_ReceiveByte(void)\r
 {\r
-#if defined(XPROG_VIA_HARDWARE_USART)\r
        /* Switch to Rx mode if currently in Tx mode */\r
        if (IsSending)\r
        /* Switch to Rx mode if currently in Tx mode */\r
        if (IsSending)\r
-       {\r
-               while (!(UCSR1A & (1 << TXC1)));\r
-               UCSR1A |=  (1 << TXC1);\r
-\r
-               UCSR1B &= ~(1 << TXEN1);\r
-               UCSR1B |=  (1 << RXEN1);\r
-\r
-               DDRD   &= ~(1 << 3);\r
-               PORTD  &= ~(1 << 3);\r
-               \r
-               IsSending = false;\r
-       }\r
+         XPROGTarget_SetRxMode();\r
 \r
 \r
+#if defined(XPROG_VIA_HARDWARE_USART)\r
        /* Wait until a byte has been received before reading */\r
        while (!(UCSR1A & (1 << RXC1)) && TimeoutMSRemaining);\r
        return UDR1;\r
 #else\r
        /* Wait until a byte has been received before reading */\r
        while (!(UCSR1A & (1 << RXC1)) && TimeoutMSRemaining);\r
        return UDR1;\r
 #else\r
-       /* Switch to Rx mode if currently in Tx mode */\r
-       if (IsSending)\r
-       {\r
-               while (SoftUSART_BitCount);\r
-\r
-               BITBANG_PDIDATA_DDR  &= ~BITBANG_PDIDATA_MASK;\r
-               BITBANG_PDIDATA_PORT &= ~BITBANG_PDIDATA_MASK;\r
-\r
-               IsSending = false;\r
-       }\r
-\r
        /* Wait until a byte has been received before reading */\r
        SoftUSART_BitCount = BITS_IN_USART_FRAME;\r
        while (SoftUSART_BitCount && TimeoutMSRemaining);\r
        /* Wait until a byte has been received before reading */\r
        SoftUSART_BitCount = BITS_IN_USART_FRAME;\r
        while (SoftUSART_BitCount && TimeoutMSRemaining);\r
@@ -379,19 +347,11 @@ uint8_t XPROGTarget_ReceiveByte(void)
 /** Sends a BREAK via the USART to the attached target, consisting of a full frame of idle bits. */\r
 void XPROGTarget_SendBreak(void)\r
 {\r
 /** Sends a BREAK via the USART to the attached target, consisting of a full frame of idle bits. */\r
 void XPROGTarget_SendBreak(void)\r
 {\r
-#if defined(XPROG_VIA_HARDWARE_USART)\r
        /* Switch to Tx mode if currently in Rx mode */\r
        if (!(IsSending))\r
        /* Switch to Tx mode if currently in Rx mode */\r
        if (!(IsSending))\r
-       {\r
-               PORTD  |=  (1 << 3);\r
-               DDRD   |=  (1 << 3);\r
-\r
-               UCSR1B &= ~(1 << RXEN1);\r
-               UCSR1B |=  (1 << TXEN1);\r
-               \r
-               IsSending = true;\r
-       }\r
+         XPROGTarget_SetTxMode();\r
 \r
 \r
+#if defined(XPROG_VIA_HARDWARE_USART)\r
        /* Need to do nothing for a full frame to send a BREAK */\r
        for (uint8_t i = 0; i < BITS_IN_USART_FRAME; i++)\r
        {\r
        /* Need to do nothing for a full frame to send a BREAK */\r
        for (uint8_t i = 0; i < BITS_IN_USART_FRAME; i++)\r
        {\r
@@ -400,21 +360,81 @@ void XPROGTarget_SendBreak(void)
                while (!(PIND & (1 << 5)));\r
        }\r
 #else\r
                while (!(PIND & (1 << 5)));\r
        }\r
 #else\r
-       /* Switch to Tx mode if currently in Rx mode */\r
-       if (!(IsSending))\r
+       while (SoftUSART_BitCount);\r
+\r
+       /* Need to do nothing for a full frame to send a BREAK */\r
+       SoftUSART_Data     = 0x0FFF;\r
+       SoftUSART_BitCount = BITS_IN_USART_FRAME;\r
+#endif\r
+}\r
+\r
+static void XPROGTarget_SetTxMode(void)\r
+{\r
+#if defined(XPROG_VIA_HARDWARE_USART)\r
+       /* Wait for a full cycle of the clock */\r
+       while (PIND & (1 << 5));\r
+       while (!(PIND & (1 << 5)));\r
+\r
+       PORTD  |=  (1 << 3);\r
+       DDRD   |=  (1 << 3);\r
+\r
+       UCSR1B &= ~(1 << RXEN1);\r
+       UCSR1B |=  (1 << TXEN1);\r
+               \r
+       IsSending = true;\r
+#else\r
+       while (SoftUSART_BitCount);\r
+\r
+       /* Wait for a full cycle of the clock */\r
+       SoftUSART_Data     = 0x0001;\r
+       SoftUSART_BitCount = 1;\r
+       while (SoftUSART_BitCount);\r
+\r
+       if (XPROG_SelectedProtocol == XPRG_PROTOCOL_PDI)\r
        {\r
                BITBANG_PDIDATA_PORT |= BITBANG_PDIDATA_MASK;\r
                BITBANG_PDIDATA_DDR  |= BITBANG_PDIDATA_MASK;\r
        {\r
                BITBANG_PDIDATA_PORT |= BITBANG_PDIDATA_MASK;\r
                BITBANG_PDIDATA_DDR  |= BITBANG_PDIDATA_MASK;\r
-\r
-               IsSending = true;\r
        }\r
        }\r
-       \r
+       else\r
+       {\r
+               BITBANG_TPIDATA_PORT |= BITBANG_TPIDATA_MASK;\r
+               BITBANG_TPIDATA_DDR  |= BITBANG_TPIDATA_MASK;   \r
+       }\r
+#endif\r
+\r
+       IsSending = true;\r
+}\r
+\r
+static void XPROGTarget_SetRxMode(void)\r
+{\r
+#if defined(XPROG_VIA_HARDWARE_USART)\r
+       while (!(UCSR1A & (1 << TXC1)));\r
+       UCSR1A |=  (1 << TXC1);\r
+\r
+       UCSR1B &= ~(1 << TXEN1);\r
+       UCSR1B |=  (1 << RXEN1);\r
+\r
+       DDRD   &= ~(1 << 3);\r
+       PORTD  &= ~(1 << 3);\r
+#else\r
        while (SoftUSART_BitCount);\r
 \r
        while (SoftUSART_BitCount);\r
 \r
-       /* Need to do nothing for a full frame to send a BREAK */\r
-       SoftUSART_Data     = 0x0FFF;\r
-       SoftUSART_BitCount = BITS_IN_USART_FRAME;\r
+       if (XPROG_SelectedProtocol == XPRG_PROTOCOL_PDI)\r
+       {\r
+               BITBANG_PDIDATA_DDR  &= ~BITBANG_PDIDATA_MASK;\r
+               BITBANG_PDIDATA_PORT &= ~BITBANG_PDIDATA_MASK;\r
+       }\r
+       else\r
+       {\r
+               BITBANG_TPIDATA_DDR  &= ~BITBANG_TPIDATA_MASK;\r
+               BITBANG_TPIDATA_PORT &= ~BITBANG_TPIDATA_MASK;  \r
+       }\r
+       \r
+       /* Wait until DATA line has been pulled up to idle by the target */\r
+       while (!(BITBANG_PDIDATA_PIN & BITBANG_PDIDATA_MASK) && TimeoutMSRemaining);\r
 #endif\r
 #endif\r
+\r
+       IsSending = false;\r
 }\r
 \r
 #endif\r
 }\r
 \r
 #endif\r