Added .5MHz recovery clock to the AVRISP programmer project when in ISP programming mode to correct mis-set fuses.

Fixed AVRISP project not extending the command delay after each successful page/word/byte program.
pull/1469/head
Dean Camera 15 years ago
parent 35a0fe9384
commit ab195ab1da

@ -25,6 +25,7 @@
* do not adversely affect the code operation (currently only the LEDs driver)
* - Added keyboard modifier masks (HID_KEYBOARD_MODIFER_*) and LED report masks (KEYBOARD_LED_*) to the HID class driver and
* Keyboard demos
* - Added .5MHz recovery clock to the AVRISP programmer project when in ISP programming mode to correct mis-set fuses
*
* <b>Changed:</b>
* - Slowed down software USART carried PDI programming in the AVRISP project to prevent transmission errors
@ -58,6 +59,7 @@
* - Fixed SerialStream driver blocking while waiting for characters to be received instead of returning EOF
* - Fixed SerialStream driver not setting stdin to the created serial stream
* - Fixed USB_GetHIDReportSize() returning the number of bits in the specified report instead of bytes
* - Fixed AVRISP project not extending the command delay after each successful page/word/byte program
*
* \section Sec_ChangeLog091223 Version 091223
*

@ -110,6 +110,10 @@
* </tr>
* </table>
*
* In addition, the AVR's XCK pin will generate a .5MHz clock when SPI programming is used, to act as an external
* device clock if the fuses have been mis-set. To use the recovery clock, connect XCK to the target AVR's XTAL1
* pin, and set the ISP programming speed to 125KHz or below.
*
* <b><sup>1</sup></b> <i>Optional, see \ref SSec_Options section - for USB AVRs with ADC modules only</i> \n
* <b><sup>2</sup></b> <i>See AUX line related tokens in the \ref SSec_Options section</i>
*

@ -62,7 +62,14 @@ void ISPProtocol_EnterISPMode(void)
uint8_t ResponseStatus = STATUS_CMD_FAILED;
CurrentAddress = 0;
/* Set up the synchronous USART to generate the recovery clock on XCK pin */
UBRR1 = (F_CPU / 500000UL);
UCSR1B = (1 << TXEN1);
UCSR1C = (1 << UMSEL10) | (1 << UPM11) | (1 << USBS1) | (1 << UCSZ11) | (1 << UCSZ10) | (1 << UCPOL1);
DDRD |= (1 << 5);
/* Perform execution delay, initialize SPI bus */
ISPProtocol_DelayMS(Enter_ISP_Params.ExecutionDelayMS);
SPI_Init(ISPTarget_GetSPIPrescalerMask() | SPI_SCK_LEAD_RISING | SPI_SAMPLE_LEADING | SPI_MODE_MASTER);
@ -118,6 +125,12 @@ void ISPProtocol_LeaveISPMode(void)
SPI_ShutDown();
ISPProtocol_DelayMS(Leave_ISP_Params.PostDelayMS);
/* Turn off the synchronous USART to terminate the recovery clock on XCK pin */
UBRR1 = (F_CPU / 500000UL);
UCSR1B = (1 << TXEN1);
UCSR1C = (1 << UMSEL10) | (1 << UPM11) | (1 << USBS1) | (1 << UCSZ11) | (1 << UCSZ10) | (1 << UCPOL1);
DDRD &= ~(1 << 5);
Endpoint_Write_Byte(CMD_LEAVE_PROGMODE_ISP);
Endpoint_Write_Byte(STATUS_CMD_OK);
Endpoint_ClearIN();

@ -139,6 +139,9 @@ uint8_t ISPTarget_WaitForProgComplete(const uint8_t ProgrammingMode, const uint1
ProgrammingStatus = ISPTarget_WaitWhileTargetBusy();
break;
}
if (ProgrammingStatus == STATUS_CMD_OK)
TimeoutMSRemaining = COMMAND_TIMEOUT_MS;
return ProgrammingStatus;
}
@ -159,10 +162,7 @@ uint8_t ISPTarget_WaitWhileTargetBusy(void)
}
while ((SPI_ReceiveByte() & 0x01) && TimeoutMSRemaining);
if (!(TimeoutMSRemaining))
return STATUS_RDY_BSY_TOUT;
else
return STATUS_CMD_OK;
return ((TimeoutMSRemaining) ? STATUS_CMD_OK : STATUS_RDY_BSY_TOUT);
}
/** Sends a low-level LOAD EXTENDED ADDRESS command to the target, for addressing of memory beyond the

@ -82,9 +82,12 @@ bool TINYNVM_WaitWhileNVMBusBusy(void)
/* 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);
if (XPROGTarget_ReceiveByte() & TPI_STATUS_NVM)
return true;
{
TimeoutMSRemaining = COMMAND_TIMEOUT_MS;
return true;
}
}
return false;
}
@ -103,9 +106,12 @@ bool TINYNVM_WaitWhileNVMControllerBusy(void)
/* Check to see if the BUSY flag is still set */
if (!(XPROGTarget_ReceiveByte() & (1 << 7)))
return true;
{
TimeoutMSRemaining = COMMAND_TIMEOUT_MS;
return true;
}
}
return false;
}
@ -167,6 +173,10 @@ bool TINYNVM_WriteMemory(const uint16_t WriteAddress, uint8_t* WriteBuffer, uint
while (WriteLength)
{
/* Wait until the NVM controller is no longer busy */
if (!(TINYNVM_WaitWhileNVMControllerBusy()))
return false;
/* Write the low byte of data to the target */
XPROGTarget_SendByte(TPI_CMD_SST | TPI_POINTER_INDIRECT_PI);
XPROGTarget_SendByte(*(WriteBuffer++));
@ -175,10 +185,6 @@ bool TINYNVM_WriteMemory(const uint16_t WriteAddress, uint8_t* WriteBuffer, uint
XPROGTarget_SendByte(TPI_CMD_SST | TPI_POINTER_INDIRECT_PI);
XPROGTarget_SendByte(*(WriteBuffer++));
/* Wait until the NVM controller is no longer busy */
if (!(TINYNVM_WaitWhileNVMControllerBusy()))
return false;
/* Need to decrement the write length twice, since we read out a whole word */
WriteLength -= 2;
}

@ -77,7 +77,10 @@ bool XMEGANVM_WaitWhileNVMBusBusy(void)
/* 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);
if (XPROGTarget_ReceiveByte() & PDI_STATUS_NVM)
return true;
{
TimeoutMSRemaining = COMMAND_TIMEOUT_MS;
return true;
}
}
return false;
@ -99,7 +102,10 @@ bool XMEGANVM_WaitWhileNVMControllerBusy(void)
/* Check to see if the BUSY flag is still set */
if (!(XPROGTarget_ReceiveByte() & (1 << 7)))
return true;
{
TimeoutMSRemaining = COMMAND_TIMEOUT_MS;
return true;
}
}
return false;

Loading…
Cancel
Save