From f0b4d796297cd4be311b8596c8308bad218adabd Mon Sep 17 00:00:00 2001 From: Dean Camera Date: Wed, 16 Dec 2009 08:03:04 +0000 Subject: [PATCH] Slightly speed up software USART in the AVRISP project - faster parity computation, ensure received data is byte aligned when receive is complete by throwing away the start bit during reception. --- Projects/AVRISP/Lib/PDITarget.c | 20 +++++++++++++------- Projects/AVRISP/Lib/PDITarget.h | 12 +++++++++++- Projects/AVRISP/makefile | 2 +- 3 files changed, 25 insertions(+), 9 deletions(-) diff --git a/Projects/AVRISP/Lib/PDITarget.c b/Projects/AVRISP/Lib/PDITarget.c index a8fe21e9be..e21942a1f3 100644 --- a/Projects/AVRISP/Lib/PDITarget.c +++ b/Projects/AVRISP/Lib/PDITarget.c @@ -70,8 +70,10 @@ ISR(TIMER1_COMPA_vect, ISR_BLOCK) if ((SoftUSART_BitCount == BITS_IN_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) - SoftUSART_Data |= (1 << BITS_IN_FRAME); + SoftUSART_Data |= (1 << (BITS_IN_FRAME - 1)); SoftUSART_Data >>= 1; SoftUSART_BitCount--; @@ -82,6 +84,7 @@ ISR(TIMER1_COMPA_vect, ISR_BLOCK) if (!IsSending) return; + /* Set the data line to the next bit value */ if (SoftUSART_Data & 0x01) BITBANG_PDIDATA_PORT |= BITBANG_PDIDATA_MASK; else @@ -196,17 +199,20 @@ void PDITarget_SendByte(uint8_t Byte) bool EvenParityBit = false; uint8_t ParityData = Byte; - /* Compute Even parity bit */ - for (uint8_t i = 0; i < 8; i++) + /* Compute Even parity - while a bit is still set, chop off lowest bit and toggle parity bit */ + while (ParityData) { - EvenParityBit ^= ParityData & 0x01; - ParityData >>= 1; + EvenParityBit ^= true; + ParityData &= (ParityData - 1); } + /* 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) | ((uint16_t)EvenParityBit << 9) | ((uint16_t)Byte << 1) | (0 << 0)); + while (SoftUSART_BitCount); /* Data shifted out LSB first, START DATA PARITY STOP STOP */ - SoftUSART_Data = ((uint16_t)EvenParityBit << 9) | ((uint16_t)Byte << 1) | (1 << 10) | (1 << 11); + SoftUSART_Data = NewUSARTData; SoftUSART_BitCount = BITS_IN_FRAME; #endif } @@ -253,7 +259,7 @@ uint8_t PDITarget_ReceiveByte(void) while (SoftUSART_BitCount); /* Throw away the start, parity and stop bits to leave only the data */ - return (uint8_t)(SoftUSART_Data >> 1); + return (uint8_t)SoftUSART_Data; #endif } diff --git a/Projects/AVRISP/Lib/PDITarget.h b/Projects/AVRISP/Lib/PDITarget.h index 03083fcb6f..2a704b3d8d 100644 --- a/Projects/AVRISP/Lib/PDITarget.h +++ b/Projects/AVRISP/Lib/PDITarget.h @@ -54,7 +54,17 @@ /* Defines: */ #if ((BOARD == BOARD_XPLAIN) || (BOARD == BOARD_XPLAIN_REV1)) - #define PDI_VIA_HARDWARE_USART +// #define PDI_VIA_HARDWARE_USART + + #define BITBANG_PDIDATA_PORT PORTD + #define BITBANG_PDIDATA_DDR DDRD + #define BITBANG_PDIDATA_PIN PIND + #define BITBANG_PDIDATA_MASK (1 << 3) + + #define BITBANG_PDICLOCK_PORT PORTD + #define BITBANG_PDICLOCK_DDR DDRD + #define BITBANG_PDICLOCK_PIN PIND + #define BITBANG_PDICLOCK_MASK (1 << 5) #else #define BITBANG_PDIDATA_PORT PORTB #define BITBANG_PDIDATA_DDR DDRB diff --git a/Projects/AVRISP/makefile b/Projects/AVRISP/makefile index 2b6a1e858b..23e27c52d2 100644 --- a/Projects/AVRISP/makefile +++ b/Projects/AVRISP/makefile @@ -66,7 +66,7 @@ MCU = at90usb1287 # Target board (see library "Board Types" documentation, USER or blank for projects not requiring # LUFA board drivers). If USER is selected, put custom board drivers in a directory called # "Board" inside the application directory. -BOARD = USBKEY +BOARD = XPLAIN # Processor frequency.