X-Git-Url: http://git.linex4red.de/pub/USBasp.git/blobdiff_plain/d4ca7fb44c7d326b96cf391f0275dc323dbe24de..d26a9ed5fd6fc60a0dfa61d04f5ae2bd7163a85d:/Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c diff --git a/Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c b/Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c index def34991f..140642869 100644 --- a/Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c +++ b/Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c @@ -1,13 +1,13 @@ /* LUFA Library - Copyright (C) Dean Camera, 2009. + Copyright (C) Dean Camera, 2010. dean [at] fourwalledcubicle [dot] com www.fourwalledcubicle.com */ /* - Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com) + Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com) Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted @@ -71,7 +71,7 @@ ISR(TIMER1_COMPA_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_PDIDATA_PIN & BITBANG_PDIDATA_MASK) ((uint8_t*)&SoftUSART_Data)[1] |= (1 << (BITS_IN_USART_FRAME - 9)); @@ -117,7 +117,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,12 +154,11 @@ 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_ms(1); /* Set up the synchronous USART for XMEGA communications - 8 data bits, even parity, 2 stop bits */ - UBRR1 = (F_CPU / 1000000UL); + UBRR1 = (F_CPU / 500000UL); UCSR1B = (1 << TXEN1); UCSR1C = (1 << UMSEL10) | (1 << UPM11) | (1 << USBS1) | (1 << UCSZ11) | (1 << UCSZ10) | (1 << UCPOL1); #else @@ -169,8 +168,7 @@ 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_ms(1); /* Fire timer compare channel A ISR to manage the software USART */ OCR1A = BITS_BETWEEN_USART_CLOCKS; @@ -188,20 +186,19 @@ void XPROGTarget_EnableTargetTPI(void) { IsSending = false; - /* Set /RESET line low for at least 90ns to enable TPI functionality */ - RESET_LINE_DDR |= RESET_LINE_MASK; - RESET_LINE_PORT &= ~RESET_LINE_MASK; - asm volatile ("NOP"::); - asm volatile ("NOP"::); + /* Set /RESET line low for at least 400ns to enable TPI functionality */ + AUX_LINE_DDR |= AUX_LINE_MASK; + AUX_LINE_PORT &= ~AUX_LINE_MASK; + _delay_ms(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 / 1000000UL); + UBRR1 = (F_CPU / 500000UL); UCSR1B = (1 << TXEN1); UCSR1C = (1 << UMSEL10) | (1 << UPM11) | (1 << USBS1) | (1 << UCSZ11) | (1 << UCSZ10) | (1 << UCPOL1); #else @@ -226,7 +223,14 @@ void XPROGTarget_EnableTargetTPI(void) /** Disables the target's PDI interface, exits programming mode and starts the target's application. */ void XPROGTarget_DisableTargetPDI(void) { + /* Switch to Rx mode to ensure that all pending transmissions are complete */ + 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; @@ -236,6 +240,10 @@ void XPROGTarget_DisableTargetPDI(void) DDRD &= ~((1 << 5) | (1 << 3)); PORTD &= ~((1 << 5) | (1 << 3) | (1 << 2)); #else + /* 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; @@ -249,6 +257,9 @@ void XPROGTarget_DisableTargetPDI(void) /** Disables the target's TPI interface, exits programming mode and starts the target's application. */ void XPROGTarget_DisableTargetTPI(void) { + /* Switch to Rx mode to ensure that all pending transmissions are complete */ + XPROGTarget_SetRxMode(); + #if defined(XPROG_VIA_HARDWARE_USART) /* Turn off receiver and transmitter of the USART, clear settings */ UCSR1A |= (1 << TXC1) | (1 << RXC1); @@ -269,8 +280,8 @@ void XPROGTarget_DisableTargetTPI(void) #endif /* Tristate target /RESET line */ - RESET_LINE_DDR &= ~RESET_LINE_MASK; - RESET_LINE_PORT &= ~RESET_LINE_MASK; + AUX_LINE_DDR &= ~AUX_LINE_MASK; + AUX_LINE_PORT &= ~AUX_LINE_MASK; } /** Sends a byte via the USART. @@ -279,38 +290,21 @@ void XPROGTarget_DisableTargetTPI(void) */ void XPROGTarget_SendByte(const uint8_t Byte) { -#if defined(XPROG_VIA_HARDWARE_USART) /* Switch to Tx mode if currently in Rx mode */ if (!(IsSending)) - { - PORTD |= (1 << 3); - DDRD |= (1 << 3); - - UCSR1B |= (1 << TXEN1); - UCSR1B &= ~(1 << RXEN1); - - IsSending = true; - } - + XPROGTarget_SetTxMode(); + +#if defined(XPROG_VIA_HARDWARE_USART) /* Wait until there is space in the hardware Tx buffer before writing */ while (!(UCSR1A & (1 << UDRE1))); UCSR1A |= (1 << TXC1); UDR1 = Byte; #else - /* Switch to Tx mode if currently in Rx mode */ - if (!(IsSending)) - { - BITBANG_PDIDATA_PORT |= BITBANG_PDIDATA_MASK; - BITBANG_PDIDATA_DDR |= BITBANG_PDIDATA_MASK; - - IsSending = true; - } - /* Calculate the new USART frame data here while while we wait for a previous byte (if any) to finish sending */ 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); @@ -332,37 +326,15 @@ void XPROGTarget_SendByte(const uint8_t Byte) */ uint8_t XPROGTarget_ReceiveByte(void) { -#if defined(XPROG_VIA_HARDWARE_USART) /* Switch to Rx mode if currently in Tx mode */ if (IsSending) - { - while (!(UCSR1A & (1 << TXC1))); - UCSR1A |= (1 << TXC1); - - UCSR1B &= ~(1 << TXEN1); - UCSR1B |= (1 << RXEN1); - - DDRD &= ~(1 << 3); - PORTD &= ~(1 << 3); - - IsSending = false; - } + XPROGTarget_SetRxMode(); +#if defined(XPROG_VIA_HARDWARE_USART) /* Wait until a byte has been received before reading */ while (!(UCSR1A & (1 << RXC1)) && TimeoutMSRemaining); return UDR1; #else - /* Switch to Rx mode if currently in Tx mode */ - if (IsSending) - { - while (SoftUSART_BitCount); - - BITBANG_PDIDATA_DDR &= ~BITBANG_PDIDATA_MASK; - BITBANG_PDIDATA_PORT &= ~BITBANG_PDIDATA_MASK; - - IsSending = false; - } - /* Wait until a byte has been received before reading */ SoftUSART_BitCount = BITS_IN_USART_FRAME; while (SoftUSART_BitCount && TimeoutMSRemaining); @@ -375,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. */ void XPROGTarget_SendBreak(void) { -#if defined(XPROG_VIA_HARDWARE_USART) /* Switch to Tx mode if currently in Rx mode */ if (!(IsSending)) - { - PORTD |= (1 << 3); - DDRD |= (1 << 3); - - UCSR1B &= ~(1 << RXEN1); - UCSR1B |= (1 << TXEN1); - - IsSending = true; - } + XPROGTarget_SetTxMode(); +#if defined(XPROG_VIA_HARDWARE_USART) /* Need to do nothing for a full frame to send a BREAK */ for (uint8_t i = 0; i < BITS_IN_USART_FRAME; i++) { @@ -396,21 +360,81 @@ void XPROGTarget_SendBreak(void) while (!(PIND & (1 << 5))); } #else - /* Switch to Tx mode if currently in Rx mode */ - if (!(IsSending)) + while (SoftUSART_BitCount); + + /* Need to do nothing for a full frame to send a BREAK */ + SoftUSART_Data = 0x0FFF; + SoftUSART_BitCount = BITS_IN_USART_FRAME; +#endif +} + +static void XPROGTarget_SetTxMode(void) +{ +#if defined(XPROG_VIA_HARDWARE_USART) + /* Wait for a full cycle of the clock */ + while (PIND & (1 << 5)); + while (!(PIND & (1 << 5))); + + PORTD |= (1 << 3); + DDRD |= (1 << 3); + + UCSR1B &= ~(1 << RXEN1); + UCSR1B |= (1 << TXEN1); + + IsSending = true; +#else + while (SoftUSART_BitCount); + + /* Wait for a full cycle of the clock */ + SoftUSART_Data = 0x0001; + SoftUSART_BitCount = 1; + while (SoftUSART_BitCount); + + if (XPROG_SelectedProtocol == XPRG_PROTOCOL_PDI) { BITBANG_PDIDATA_PORT |= BITBANG_PDIDATA_MASK; BITBANG_PDIDATA_DDR |= BITBANG_PDIDATA_MASK; - - IsSending = true; } - + else + { + BITBANG_TPIDATA_PORT |= BITBANG_TPIDATA_MASK; + BITBANG_TPIDATA_DDR |= BITBANG_TPIDATA_MASK; + } +#endif + + IsSending = true; +} + +static void XPROGTarget_SetRxMode(void) +{ +#if defined(XPROG_VIA_HARDWARE_USART) + while (!(UCSR1A & (1 << TXC1))); + UCSR1A |= (1 << TXC1); + + UCSR1B &= ~(1 << TXEN1); + UCSR1B |= (1 << RXEN1); + + DDRD &= ~(1 << 3); + PORTD &= ~(1 << 3); +#else while (SoftUSART_BitCount); - /* Need to do nothing for a full frame to send a BREAK */ - SoftUSART_Data = 0x0FFF; - SoftUSART_BitCount = BITS_IN_USART_FRAME; + if (XPROG_SelectedProtocol == XPRG_PROTOCOL_PDI) + { + BITBANG_PDIDATA_DDR &= ~BITBANG_PDIDATA_MASK; + BITBANG_PDIDATA_PORT &= ~BITBANG_PDIDATA_MASK; + } + else + { + BITBANG_TPIDATA_DDR &= ~BITBANG_TPIDATA_MASK; + BITBANG_TPIDATA_PORT &= ~BITBANG_TPIDATA_MASK; + } + + /* Wait until DATA line has been pulled up to idle by the target */ + while (!(BITBANG_PDIDATA_PIN & BITBANG_PDIDATA_MASK) && TimeoutMSRemaining); #endif + + IsSending = false; } #endif