X-Git-Url: http://git.linex4red.de/pub/USBasp.git/blobdiff_plain/efb6c357784af2293a50b3fca9503c3a4c13a9e1..ce8d0424b1a59bb2b0bd3ab8f69f4e4cf8c9930b:/Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c?ds=sidebyside diff --git a/Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c b/Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c index 2b733d363..45c1d225d 100644 --- a/Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c +++ b/Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c @@ -49,54 +49,63 @@ volatile uint16_t SoftUSART_Data; #define SoftUSART_BitCount GPIOR2 -/** ISR to manage the PDI software USART when bit-banged PDI USART mode is selected. */ +/** ISR to manage the rising edge of the PDI/TPI software USART when bit-banged USART mode is selected. */ ISR(TIMER1_COMPA_vect, ISR_BLOCK) { /* Toggle CLOCK pin in a single cycle (see AVR datasheet) */ BITBANG_PDICLOCK_PIN |= BITBANG_PDICLOCK_MASK; + TIFR1 |= (1 << OCF1B); + TIMSK1 = (1 << OCIE1B); /* If not sending or receiving, just exit */ if (!(SoftUSART_BitCount)) return; - /* Check to see if we are at a rising or falling edge of the clock */ - if (BITBANG_PDICLOCK_PORT & BITBANG_PDICLOCK_MASK) - { - /* If at rising clock edge and we are in send mode, abort */ - if (IsSending) - return; - - /* Wait for the start bit when receiving */ - if ((SoftUSART_BitCount == BITS_IN_USART_FRAME) && (BITBANG_PDIDATA_PIN & BITBANG_PDIDATA_MASK)) - return; - - /* Shift in the bit one less than the frame size in position, so that the start bit will eventually - * be discarded leaving the data to be byte-aligned for quick access */ - if (BITBANG_PDIDATA_PIN & BITBANG_PDIDATA_MASK) - ((uint8_t*)&SoftUSART_Data)[1] |= (1 << (BITS_IN_USART_FRAME - 9)); + /* If at rising clock edge and we are in send mode, abort */ + if (IsSending) + return; + + /* Wait for the start bit when receiving */ + if ((SoftUSART_BitCount == BITS_IN_USART_FRAME) && (BITBANG_PDIDATA_PIN & BITBANG_PDIDATA_MASK)) + return; - SoftUSART_Data >>= 1; - SoftUSART_BitCount--; - } - else - { - /* If at falling clock edge and we are in receive mode, abort */ - if (!IsSending) - return; + /* Shift in the bit one less than the frame size in position, so that the start bit will eventually + * be discarded leaving the data to be byte-aligned for quick access (subtract 9 as we are ORing to the MSB) */ + if (BITBANG_PDIDATA_PIN & BITBANG_PDIDATA_MASK) + ((uint8_t*)&SoftUSART_Data)[1] |= (1 << (BITS_IN_USART_FRAME - 9)); - /* Set the data line to the next bit value */ - if (((uint8_t*)&SoftUSART_Data)[0] & 0x01) - BITBANG_PDIDATA_PORT |= BITBANG_PDIDATA_MASK; - else - BITBANG_PDIDATA_PORT &= ~BITBANG_PDIDATA_MASK; + SoftUSART_Data >>= 1; + SoftUSART_BitCount--; +} - SoftUSART_Data >>= 1; - SoftUSART_BitCount--; - } +/** ISR to manage the falling edge of the PDI/TPI software USART when bit-banged USART mode is selected. */ +ISR(TIMER1_COMPB_vect, ISR_BLOCK) +{ + /* Toggle CLOCK pin in a single cycle (see AVR datasheet) */ + BITBANG_PDICLOCK_PIN |= BITBANG_PDICLOCK_MASK; + TIFR1 |= (1 << OCF1A); + TIMSK1 = (1 << OCIE1A); + + /* If not sending or receiving, just exit */ + if (!(SoftUSART_BitCount)) + return; + + /* If at falling clock edge and we are in receive mode, abort */ + if (!IsSending) + return; + + /* Set the data line to the next bit value */ + if (((uint8_t*)&SoftUSART_Data)[0] & 0x01) + BITBANG_PDIDATA_PORT |= BITBANG_PDIDATA_MASK; + else + BITBANG_PDIDATA_PORT &= ~BITBANG_PDIDATA_MASK; + + SoftUSART_Data >>= 1; + SoftUSART_BitCount--; } /** ISR to manage the TPI software USART when bit-banged TPI USART mode is selected. */ -ISR(TIMER1_COMPB_vect, ISR_BLOCK) +ISR(TIMER1_CAPT_vect, ISR_BLOCK) { /* Toggle CLOCK pin in a single cycle (see AVR datasheet) */ BITBANG_TPICLOCK_PIN |= BITBANG_TPICLOCK_MASK; @@ -117,7 +126,7 @@ ISR(TIMER1_COMPB_vect, ISR_BLOCK) return; /* Shift in the bit one less than the frame size in position, so that the start bit will eventually - * be discarded leaving the data to be byte-aligned for quick access */ + * be discarded leaving the data to be byte-aligned for quick access (subtract 9 as we are ORing to the MSB) */ if (BITBANG_TPIDATA_PIN & BITBANG_TPIDATA_MASK) ((uint8_t*)&SoftUSART_Data)[1] |= (1 << (BITS_IN_USART_FRAME - 9)); @@ -154,8 +163,7 @@ void XPROGTarget_EnableTargetPDI(void) /* Set DATA line high for at least 90ns to disable /RESET functionality */ PORTD |= (1 << 3); - asm volatile ("NOP"::); - asm volatile ("NOP"::); + _delay_us(1); /* Set up the synchronous USART for XMEGA communications - 8 data bits, even parity, 2 stop bits */ @@ -169,12 +177,13 @@ void XPROGTarget_EnableTargetPDI(void) /* Set DATA line high for at least 90ns to disable /RESET functionality */ BITBANG_PDIDATA_PORT |= BITBANG_PDIDATA_MASK; - asm volatile ("NOP"::); - asm volatile ("NOP"::); + _delay_us(1); /* Fire timer compare channel A ISR to manage the software USART */ OCR1A = BITS_BETWEEN_USART_CLOCKS; + OCR1B = BITS_BETWEEN_USART_CLOCKS; TCCR1B = (1 << WGM12) | (1 << CS10); + TCCR1C = (1 << FOC1B); TIMSK1 = (1 << OCIE1A); #endif @@ -188,18 +197,17 @@ void XPROGTarget_EnableTargetTPI(void) { IsSending = false; - /* Set /RESET line low for at least 90ns to enable TPI functionality */ + /* Set /RESET line low for at least 400ns to enable TPI functionality */ AUX_LINE_DDR |= AUX_LINE_MASK; AUX_LINE_PORT &= ~AUX_LINE_MASK; - asm volatile ("NOP"::); - asm volatile ("NOP"::); + _delay_us(1); #if defined(XPROG_VIA_HARDWARE_USART) /* Set Tx and XCK as outputs, Rx as input */ DDRD |= (1 << 5) | (1 << 3); DDRD &= ~(1 << 2); - /* Set up the synchronous USART for XMEGA communications - + /* Set up the synchronous USART for TINY communications - 8 data bits, even parity, 2 stop bits */ UBRR1 = (F_CPU / 500000UL); UCSR1B = (1 << TXEN1); @@ -212,10 +220,10 @@ void XPROGTarget_EnableTargetTPI(void) /* Set DATA line high for idle state */ BITBANG_TPIDATA_PORT |= BITBANG_TPIDATA_MASK; - /* Fire timer capture channel B ISR to manage the software USART */ - OCR1B = BITS_BETWEEN_USART_CLOCKS; - TCCR1B = (1 << WGM12) | (1 << CS10); - TIMSK1 = (1 << OCIE1B); + /* Fire timer capture channel ISR to manage the software USART */ + ICR1 = BITS_BETWEEN_USART_CLOCKS; + TCCR1B = (1 << WGM13) | (1 << WGM12) | (1 << CS10); + TIMSK1 = (1 << ICIE1); #endif /* Send two BREAKs of 12 bits each to enable TPI interface (need at least 16 idle bits) */ @@ -230,6 +238,10 @@ void XPROGTarget_DisableTargetPDI(void) XPROGTarget_SetRxMode(); #if defined(XPROG_VIA_HARDWARE_USART) + /* Set /RESET high for a one millisecond to ensure target device is restarted */ + PORTD |= (1 << 5); + _delay_ms(1); + /* Turn off receiver and transmitter of the USART, clear settings */ UCSR1A |= (1 << TXC1) | (1 << RXC1); UCSR1B = 0; @@ -239,13 +251,21 @@ void XPROGTarget_DisableTargetPDI(void) DDRD &= ~((1 << 5) | (1 << 3)); PORTD &= ~((1 << 5) | (1 << 3) | (1 << 2)); #else + /* Turn off software USART management timer */ + TCCR1B = 0; + TCCR1C = 0; + + /* Set /RESET high for a one millisecond to ensure target device is restarted */ + BITBANG_PDICLOCK_PORT |= BITBANG_PDICLOCK_MASK; + _delay_ms(1); + /* Set DATA and CLOCK lines to inputs */ BITBANG_PDIDATA_DDR &= ~BITBANG_PDIDATA_MASK; BITBANG_PDICLOCK_DDR &= ~BITBANG_PDICLOCK_MASK; /* Tristate DATA and CLOCK lines */ BITBANG_PDIDATA_PORT &= ~BITBANG_PDIDATA_MASK; - BITBANG_PDICLOCK_PORT &= ~BITBANG_PDICLOCK_MASK; + BITBANG_PDICLOCK_PORT &= ~BITBANG_PDICLOCK_MASK; #endif } @@ -265,6 +285,9 @@ void XPROGTarget_DisableTargetTPI(void) DDRD &= ~((1 << 5) | (1 << 3)); PORTD &= ~((1 << 5) | (1 << 3) | (1 << 2)); #else + /* Turn off software USART management timer */ + TCCR1B = 0; + /* Set DATA and CLOCK lines to inputs */ BITBANG_TPIDATA_DDR &= ~BITBANG_TPIDATA_MASK; BITBANG_TPICLOCK_DDR &= ~BITBANG_TPICLOCK_MASK; @@ -299,7 +322,7 @@ void XPROGTarget_SendByte(const uint8_t Byte) uint16_t NewUSARTData = ((1 << 11) | (1 << 10) | (0 << 9) | ((uint16_t)Byte << 1) | (0 << 0)); /* Compute Even parity - while a bit is still set, chop off lowest bit and toggle parity bit */ - uint8_t ParityData = Byte; + uint8_t ParityData = Byte; while (ParityData) { NewUSARTData ^= (1 << 9); @@ -327,12 +350,31 @@ uint8_t XPROGTarget_ReceiveByte(void) #if defined(XPROG_VIA_HARDWARE_USART) /* Wait until a byte has been received before reading */ - while (!(UCSR1A & (1 << RXC1)) && TimeoutMSRemaining); + uint8_t TimeoutMSRemaining = 100; + while (!(UCSR1A & (1 << RXC1)) && TimeoutMSRemaining) + { + /* Manage software timeout */ + if (TIFR0 & (1 << OCF0A)) + { + TIFR0 |= (1 << OCF0A); + TimeoutMSRemaining--; + } + } + return UDR1; #else /* Wait until a byte has been received before reading */ SoftUSART_BitCount = BITS_IN_USART_FRAME; - while (SoftUSART_BitCount && TimeoutMSRemaining); + uint8_t TimeoutMSRemaining = 100; + while (SoftUSART_BitCount && TimeoutMSRemaining) + { + /* Manage software timeout */ + if (TIFR0 & (1 << OCF0A)) + { + TIFR0 |= (1 << OCF0A); + TimeoutMSRemaining--; + } + } /* Throw away the parity and stop bits to leave only the data (start bit is already discarded) */ return (uint8_t)SoftUSART_Data; @@ -426,7 +468,16 @@ static void XPROGTarget_SetRxMode(void) } /* Wait until DATA line has been pulled up to idle by the target */ - while (!(BITBANG_PDIDATA_PIN & BITBANG_PDIDATA_MASK) && TimeoutMSRemaining); + uint8_t TimeoutMSRemaining = 100; + while (!(BITBANG_PDIDATA_PIN & BITBANG_PDIDATA_MASK) && TimeoutMSRemaining) + { + /* Manage software timeout */ + if (TIFR0 & (1 << OCF0A)) + { + TIFR0 |= (1 << OCF0A); + TimeoutMSRemaining--; + } + } #endif IsSending = false;