mirror of
https://github.com/qmk/qmk_firmware.git
synced 2025-06-12 11:54:14 +00:00
AVRISP programmer project now has a more robust timeout system, allowing for a doubling of the software USART speed for PDI and TPI programming.
This commit is contained in:
parent
04d40897cf
commit
ce8d0424b1
@ -8,6 +8,16 @@
|
|||||||
*
|
*
|
||||||
* \section Sec_ChangeLogXXXXXX Version XXXXXX
|
* \section Sec_ChangeLogXXXXXX Version XXXXXX
|
||||||
*
|
*
|
||||||
|
* <b>New:</b>
|
||||||
|
* - (None)
|
||||||
|
*
|
||||||
|
* <b>Changed:</b>
|
||||||
|
* - AVRISP programmer project now has a more robust timeout system, allowing for a doubling of the software USART speed
|
||||||
|
* for PDI and TPI programming
|
||||||
|
*
|
||||||
|
* <b>Fixed:</b>
|
||||||
|
* - (None)
|
||||||
|
*
|
||||||
* \section Sec_ChangeLog100219 Version 100219
|
* \section Sec_ChangeLog100219 Version 100219
|
||||||
*
|
*
|
||||||
* <b>New:</b>
|
* <b>New:</b>
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
* \section Sec_MigrationXXXXXX Migrating from 100219 to XXXXXX
|
* \section Sec_MigrationXXXXXX Migrating from 100219 to XXXXXX
|
||||||
*
|
*
|
||||||
* \section Sec_Migration100219 Migrating from 091223 to 100219
|
* \section Sec_Migration100219 Migrating from 091223 to 100219
|
||||||
|
* - (None)
|
||||||
*
|
*
|
||||||
* <b>Non-USB Library Components</b>
|
* <b>Non-USB Library Components</b>
|
||||||
* - Due to some ADC channels not being identical to their ADC MUX selection masks for single-ended conversions on some AVR models,
|
* - Due to some ADC channels not being identical to their ADC MUX selection masks for single-ended conversions on some AVR models,
|
||||||
|
@ -42,14 +42,6 @@ uint32_t CurrentAddress;
|
|||||||
/** Flag to indicate that the next read/write operation must update the device's current address */
|
/** Flag to indicate that the next read/write operation must update the device's current address */
|
||||||
bool MustSetAddress;
|
bool MustSetAddress;
|
||||||
|
|
||||||
|
|
||||||
/** ISR for the management of the command execution timeout counter */
|
|
||||||
ISR(TIMER0_COMPA_vect, ISR_BLOCK)
|
|
||||||
{
|
|
||||||
if (TimeoutMSRemaining)
|
|
||||||
TimeoutMSRemaining--;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Initializes the hardware and software associated with the V2 protocol command handling. */
|
/** Initializes the hardware and software associated with the V2 protocol command handling. */
|
||||||
void V2Protocol_Init(void)
|
void V2Protocol_Init(void)
|
||||||
{
|
{
|
||||||
@ -76,10 +68,6 @@ void V2Protocol_ProcessCommand(void)
|
|||||||
{
|
{
|
||||||
uint8_t V2Command = Endpoint_Read_Byte();
|
uint8_t V2Command = Endpoint_Read_Byte();
|
||||||
|
|
||||||
/* Set total command processing timeout value, enable timeout management interrupt */
|
|
||||||
TimeoutMSRemaining = COMMAND_TIMEOUT_MS;
|
|
||||||
TIMSK0 |= (1 << OCIE0A);
|
|
||||||
|
|
||||||
switch (V2Command)
|
switch (V2Command)
|
||||||
{
|
{
|
||||||
case CMD_SIGN_ON:
|
case CMD_SIGN_ON:
|
||||||
@ -140,9 +128,6 @@ void V2Protocol_ProcessCommand(void)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Disable timeout management interrupt once processing has completed */
|
|
||||||
TIMSK0 &= ~(1 << OCIE0A);
|
|
||||||
|
|
||||||
Endpoint_WaitUntilReady();
|
Endpoint_WaitUntilReady();
|
||||||
Endpoint_SetEndpointDirection(ENDPOINT_DIR_OUT);
|
Endpoint_SetEndpointDirection(ENDPOINT_DIR_OUT);
|
||||||
}
|
}
|
||||||
|
@ -64,12 +64,6 @@
|
|||||||
/** Programmer ID string, returned to the host during the CMD_SIGN_ON command processing */
|
/** Programmer ID string, returned to the host during the CMD_SIGN_ON command processing */
|
||||||
#define PROGRAMMER_ID "AVRISP_MK2"
|
#define PROGRAMMER_ID "AVRISP_MK2"
|
||||||
|
|
||||||
/** Timeout period for each issued command from the host before it is aborted */
|
|
||||||
#define COMMAND_TIMEOUT_MS 200
|
|
||||||
|
|
||||||
/** Command timeout counter register, GPIOR for speed */
|
|
||||||
#define TimeoutMSRemaining GPIOR0
|
|
||||||
|
|
||||||
/** MUX mask for the VTARGET ADC channel number */
|
/** MUX mask for the VTARGET ADC channel number */
|
||||||
#define VTARGET_ADC_CHANNEL_MASK _GETADCMUXMASK(ADC_CHANNEL, VTARGET_ADC_CHANNEL)
|
#define VTARGET_ADC_CHANNEL_MASK _GETADCMUXMASK(ADC_CHANNEL, VTARGET_ADC_CHANNEL)
|
||||||
|
|
||||||
|
@ -77,14 +77,19 @@ static void TINYNVM_SendWriteNVMRegister(const uint8_t Address)
|
|||||||
bool TINYNVM_WaitWhileNVMBusBusy(void)
|
bool TINYNVM_WaitWhileNVMBusBusy(void)
|
||||||
{
|
{
|
||||||
/* Poll the STATUS register to check to see if NVM access has been enabled */
|
/* Poll the STATUS register to check to see if NVM access has been enabled */
|
||||||
|
uint8_t TimeoutMSRemaining = 100;
|
||||||
while (TimeoutMSRemaining)
|
while (TimeoutMSRemaining)
|
||||||
{
|
{
|
||||||
/* Send the SLDCS command to read the TPI STATUS register to see the NVM bus is active */
|
/* 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);
|
XPROGTarget_SendByte(TPI_CMD_SLDCS | TPI_STATUS_REG);
|
||||||
if (XPROGTarget_ReceiveByte() & TPI_STATUS_NVM)
|
if (XPROGTarget_ReceiveByte() & TPI_STATUS_NVM)
|
||||||
{
|
|
||||||
TimeoutMSRemaining = COMMAND_TIMEOUT_MS;
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
/* Manage software timeout */
|
||||||
|
if (TIFR0 & (1 << OCF0A))
|
||||||
|
{
|
||||||
|
TIFR0 |= (1 << OCF0A);
|
||||||
|
TimeoutMSRemaining--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,6 +104,7 @@ bool TINYNVM_WaitWhileNVMBusBusy(void)
|
|||||||
bool TINYNVM_WaitWhileNVMControllerBusy(void)
|
bool TINYNVM_WaitWhileNVMControllerBusy(void)
|
||||||
{
|
{
|
||||||
/* Poll the STATUS register to check to see if NVM access has been enabled */
|
/* Poll the STATUS register to check to see if NVM access has been enabled */
|
||||||
|
uint8_t TimeoutMSRemaining = 100;
|
||||||
while (TimeoutMSRemaining)
|
while (TimeoutMSRemaining)
|
||||||
{
|
{
|
||||||
/* Send the SIN command to read the TPI STATUS register to see the NVM bus is busy */
|
/* Send the SIN command to read the TPI STATUS register to see the NVM bus is busy */
|
||||||
@ -106,9 +112,13 @@ bool TINYNVM_WaitWhileNVMControllerBusy(void)
|
|||||||
|
|
||||||
/* Check to see if the BUSY flag is still set */
|
/* Check to see if the BUSY flag is still set */
|
||||||
if (!(XPROGTarget_ReceiveByte() & (1 << 7)))
|
if (!(XPROGTarget_ReceiveByte() & (1 << 7)))
|
||||||
{
|
|
||||||
TimeoutMSRemaining = COMMAND_TIMEOUT_MS;
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
/* Manage software timeout */
|
||||||
|
if (TIFR0 & (1 << OCF0A))
|
||||||
|
{
|
||||||
|
TIFR0 |= (1 << OCF0A);
|
||||||
|
TimeoutMSRemaining--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,14 +72,19 @@ static void XMEGANVM_SendNVMRegAddress(const uint8_t Register)
|
|||||||
bool XMEGANVM_WaitWhileNVMBusBusy(void)
|
bool XMEGANVM_WaitWhileNVMBusBusy(void)
|
||||||
{
|
{
|
||||||
/* Poll the STATUS register to check to see if NVM access has been enabled */
|
/* Poll the STATUS register to check to see if NVM access has been enabled */
|
||||||
|
uint8_t TimeoutMSRemaining = 100;
|
||||||
while (TimeoutMSRemaining)
|
while (TimeoutMSRemaining)
|
||||||
{
|
{
|
||||||
/* Send the LDCS command to read the PDI STATUS register to see the NVM bus is active */
|
/* Send the LDCS command to read the PDI STATUS register to see the NVM bus is active */
|
||||||
XPROGTarget_SendByte(PDI_CMD_LDCS | PDI_STATUS_REG);
|
XPROGTarget_SendByte(PDI_CMD_LDCS | PDI_STATUS_REG);
|
||||||
if (XPROGTarget_ReceiveByte() & PDI_STATUS_NVM)
|
if (XPROGTarget_ReceiveByte() & PDI_STATUS_NVM)
|
||||||
{
|
|
||||||
TimeoutMSRemaining = COMMAND_TIMEOUT_MS;
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
/* Manage software timeout */
|
||||||
|
if (TIFR0 & (1 << OCF0A))
|
||||||
|
{
|
||||||
|
TIFR0 |= (1 << OCF0A);
|
||||||
|
TimeoutMSRemaining--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,6 +99,7 @@ bool XMEGANVM_WaitWhileNVMBusBusy(void)
|
|||||||
bool XMEGANVM_WaitWhileNVMControllerBusy(void)
|
bool XMEGANVM_WaitWhileNVMControllerBusy(void)
|
||||||
{
|
{
|
||||||
/* Poll the NVM STATUS register while the NVM controller is busy */
|
/* Poll the NVM STATUS register while the NVM controller is busy */
|
||||||
|
uint8_t TimeoutMSRemaining = 100;
|
||||||
while (TimeoutMSRemaining)
|
while (TimeoutMSRemaining)
|
||||||
{
|
{
|
||||||
/* Send a LDS command to read the NVM STATUS register to check the BUSY flag */
|
/* Send a LDS command to read the NVM STATUS register to check the BUSY flag */
|
||||||
@ -102,9 +108,13 @@ bool XMEGANVM_WaitWhileNVMControllerBusy(void)
|
|||||||
|
|
||||||
/* Check to see if the BUSY flag is still set */
|
/* Check to see if the BUSY flag is still set */
|
||||||
if (!(XPROGTarget_ReceiveByte() & (1 << 7)))
|
if (!(XPROGTarget_ReceiveByte() & (1 << 7)))
|
||||||
{
|
|
||||||
TimeoutMSRemaining = COMMAND_TIMEOUT_MS;
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
/* Manage software timeout */
|
||||||
|
if (TIFR0 & (1 << OCF0A))
|
||||||
|
{
|
||||||
|
TIFR0 |= (1 << OCF0A);
|
||||||
|
TimeoutMSRemaining--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,19 +49,18 @@ volatile uint16_t SoftUSART_Data;
|
|||||||
#define SoftUSART_BitCount GPIOR2
|
#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)
|
ISR(TIMER1_COMPA_vect, ISR_BLOCK)
|
||||||
{
|
{
|
||||||
/* Toggle CLOCK pin in a single cycle (see AVR datasheet) */
|
/* Toggle CLOCK pin in a single cycle (see AVR datasheet) */
|
||||||
BITBANG_PDICLOCK_PIN |= BITBANG_PDICLOCK_MASK;
|
BITBANG_PDICLOCK_PIN |= BITBANG_PDICLOCK_MASK;
|
||||||
|
TIFR1 |= (1 << OCF1B);
|
||||||
|
TIMSK1 = (1 << OCIE1B);
|
||||||
|
|
||||||
/* If not sending or receiving, just exit */
|
/* If not sending or receiving, just exit */
|
||||||
if (!(SoftUSART_BitCount))
|
if (!(SoftUSART_BitCount))
|
||||||
return;
|
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 at rising clock edge and we are in send mode, abort */
|
||||||
if (IsSending)
|
if (IsSending)
|
||||||
return;
|
return;
|
||||||
@ -78,8 +77,19 @@ ISR(TIMER1_COMPA_vect, ISR_BLOCK)
|
|||||||
SoftUSART_Data >>= 1;
|
SoftUSART_Data >>= 1;
|
||||||
SoftUSART_BitCount--;
|
SoftUSART_BitCount--;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
/** 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 at falling clock edge and we are in receive mode, abort */
|
||||||
if (!IsSending)
|
if (!IsSending)
|
||||||
return;
|
return;
|
||||||
@ -93,7 +103,6 @@ ISR(TIMER1_COMPA_vect, ISR_BLOCK)
|
|||||||
SoftUSART_Data >>= 1;
|
SoftUSART_Data >>= 1;
|
||||||
SoftUSART_BitCount--;
|
SoftUSART_BitCount--;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/** ISR to manage the TPI software USART when bit-banged TPI USART mode is selected. */
|
/** ISR to manage the TPI software USART when bit-banged TPI USART mode is selected. */
|
||||||
ISR(TIMER1_CAPT_vect, ISR_BLOCK)
|
ISR(TIMER1_CAPT_vect, ISR_BLOCK)
|
||||||
@ -172,7 +181,9 @@ void XPROGTarget_EnableTargetPDI(void)
|
|||||||
|
|
||||||
/* Fire timer compare channel A ISR to manage the software USART */
|
/* Fire timer compare channel A ISR to manage the software USART */
|
||||||
OCR1A = BITS_BETWEEN_USART_CLOCKS;
|
OCR1A = BITS_BETWEEN_USART_CLOCKS;
|
||||||
|
OCR1B = BITS_BETWEEN_USART_CLOCKS;
|
||||||
TCCR1B = (1 << WGM12) | (1 << CS10);
|
TCCR1B = (1 << WGM12) | (1 << CS10);
|
||||||
|
TCCR1C = (1 << FOC1B);
|
||||||
TIMSK1 = (1 << OCIE1A);
|
TIMSK1 = (1 << OCIE1A);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -240,6 +251,10 @@ void XPROGTarget_DisableTargetPDI(void)
|
|||||||
DDRD &= ~((1 << 5) | (1 << 3));
|
DDRD &= ~((1 << 5) | (1 << 3));
|
||||||
PORTD &= ~((1 << 5) | (1 << 3) | (1 << 2));
|
PORTD &= ~((1 << 5) | (1 << 3) | (1 << 2));
|
||||||
#else
|
#else
|
||||||
|
/* Turn off software USART management timer */
|
||||||
|
TCCR1B = 0;
|
||||||
|
TCCR1C = 0;
|
||||||
|
|
||||||
/* Set /RESET high for a one millisecond to ensure target device is restarted */
|
/* Set /RESET high for a one millisecond to ensure target device is restarted */
|
||||||
BITBANG_PDICLOCK_PORT |= BITBANG_PDICLOCK_MASK;
|
BITBANG_PDICLOCK_PORT |= BITBANG_PDICLOCK_MASK;
|
||||||
_delay_ms(1);
|
_delay_ms(1);
|
||||||
@ -270,6 +285,9 @@ void XPROGTarget_DisableTargetTPI(void)
|
|||||||
DDRD &= ~((1 << 5) | (1 << 3));
|
DDRD &= ~((1 << 5) | (1 << 3));
|
||||||
PORTD &= ~((1 << 5) | (1 << 3) | (1 << 2));
|
PORTD &= ~((1 << 5) | (1 << 3) | (1 << 2));
|
||||||
#else
|
#else
|
||||||
|
/* Turn off software USART management timer */
|
||||||
|
TCCR1B = 0;
|
||||||
|
|
||||||
/* Set DATA and CLOCK lines to inputs */
|
/* Set DATA and CLOCK lines to inputs */
|
||||||
BITBANG_TPIDATA_DDR &= ~BITBANG_TPIDATA_MASK;
|
BITBANG_TPIDATA_DDR &= ~BITBANG_TPIDATA_MASK;
|
||||||
BITBANG_TPICLOCK_DDR &= ~BITBANG_TPICLOCK_MASK;
|
BITBANG_TPICLOCK_DDR &= ~BITBANG_TPICLOCK_MASK;
|
||||||
@ -332,12 +350,31 @@ uint8_t XPROGTarget_ReceiveByte(void)
|
|||||||
|
|
||||||
#if defined(XPROG_VIA_HARDWARE_USART)
|
#if defined(XPROG_VIA_HARDWARE_USART)
|
||||||
/* Wait until a byte has been received before reading */
|
/* 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;
|
return UDR1;
|
||||||
#else
|
#else
|
||||||
/* Wait until a byte has been received before reading */
|
/* Wait until a byte has been received before reading */
|
||||||
SoftUSART_BitCount = BITS_IN_USART_FRAME;
|
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) */
|
/* Throw away the parity and stop bits to leave only the data (start bit is already discarded) */
|
||||||
return (uint8_t)SoftUSART_Data;
|
return (uint8_t)SoftUSART_Data;
|
||||||
@ -431,7 +468,16 @@ static void XPROGTarget_SetRxMode(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Wait until DATA line has been pulled up to idle by the target */
|
/* 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
|
#endif
|
||||||
|
|
||||||
IsSending = false;
|
IsSending = false;
|
||||||
|
@ -81,7 +81,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/** Number of cycles between each clock when software USART mode is used */
|
/** Number of cycles between each clock when software USART mode is used */
|
||||||
#define BITS_BETWEEN_USART_CLOCKS 200
|
#define BITS_BETWEEN_USART_CLOCKS 100
|
||||||
|
|
||||||
/** Total number of bits in a single USART frame */
|
/** Total number of bits in a single USART frame */
|
||||||
#define BITS_IN_USART_FRAME 12
|
#define BITS_IN_USART_FRAME 12
|
||||||
|
Loading…
Reference in New Issue
Block a user