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.
This commit is contained in:
		
							parent
							
								
									35a0fe9384
								
							
						
					
					
						commit
						ab195ab1da
					
				
					 6 changed files with 45 additions and 14 deletions
				
			
		| 
						 | 
				
			
			@ -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…
	
	Add table
		Add a link
		
	
		Reference in a new issue