CurrentAddress = 0;
- /* Set up the synchronous USART to generate the recovery clock on XCK pin */
+ /* Set up the synchronous USART to generate the .5MHz 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);
/* 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);
+ ISPTarget_Init();
/* Continuously attempt to synchronize with the target until either the number of attempts specified
* by the host has exceeded, or the the device sends back the expected response values */
- while (Enter_ISP_Params.SynchLoops-- && (ResponseStatus == STATUS_CMD_FAILED) && TimeoutMSRemaining)
+ while (Enter_ISP_Params.SynchLoops-- && (ResponseStatus == STATUS_CMD_FAILED) && TimeoutTicksRemaining)
{
uint8_t ResponseBytes[4];
for (uint8_t RByte = 0; RByte < sizeof(ResponseBytes); RByte++)
{
ISPProtocol_DelayMS(Enter_ISP_Params.ByteDelay);
- ResponseBytes[RByte] = SPI_TransferByte(Enter_ISP_Params.EnterProgBytes[RByte]);
+ ResponseBytes[RByte] = ISPTarget_TransferByte(Enter_ISP_Params.EnterProgBytes[RByte]);
}
/* Check if polling disabled, or if the polled value matches the expected value */
/* Perform pre-exit delay, release the target /RESET, disable the SPI bus and perform the post-exit delay */
ISPProtocol_DelayMS(Leave_ISP_Params.PreDelayMS);
ISPTarget_ChangeTargetResetLine(false);
- SPI_ShutDown();
+ ISPTarget_ShutDown();
ISPProtocol_DelayMS(Leave_ISP_Params.PostDelayMS);
/* Turn off the synchronous USART to terminate the recovery clock on XCK pin */
Write_Memory_Params.PollValue2;
uint8_t* NextWriteByte = Write_Memory_Params.ProgData;
- /* Check to see if the host has issued a SET ADDRESS command and we haven't sent a
- * LOAD EXTENDED ADDRESS command (if needed, used when operating beyond the 128KB
- * FLASH barrier) */
- if (MustSetAddress)
- {
- if (CurrentAddress & (1UL << 31))
- ISPTarget_LoadExtendedAddress();
-
- MustSetAddress = false;
- }
-
/* Check the programming mode desired by the host, either Paged or Word memory writes */
if (Write_Memory_Params.ProgrammingMode & PROG_MODE_PAGED_WRITES_MASK)
{
uint16_t StartAddress = (CurrentAddress & 0xFFFF);
+ /* Check to see if we need to send a LOAD EXTENDED ADDRESS command to the target */
+ if (MustLoadExtendedAddress)
+ {
+ ISPTarget_LoadExtendedAddress();
+ MustLoadExtendedAddress = false;
+ }
+
/* Paged mode memory programming */
for (uint16_t CurrentByte = 0; CurrentByte < Write_Memory_Params.BytesToWrite; CurrentByte++)
{
bool IsOddByte = (CurrentByte & 0x01);
uint8_t ByteToWrite = *(NextWriteByte++);
- SPI_SendByte(Write_Memory_Params.ProgrammingCommands[0]);
- SPI_SendByte(CurrentAddress >> 8);
- SPI_SendByte(CurrentAddress & 0xFF);
- SPI_SendByte(ByteToWrite);
+ ISPTarget_SendByte(Write_Memory_Params.ProgrammingCommands[0]);
+ ISPTarget_SendByte(CurrentAddress >> 8);
+ ISPTarget_SendByte(CurrentAddress & 0xFF);
+ ISPTarget_SendByte(ByteToWrite);
/* AVR FLASH addressing requires us to modify the write command based on if we are writing a high
* or low byte at the current word address */
PollAddress = (CurrentAddress & 0xFFFF);
}
+ /* EEPROM increments the address on each byte, flash needs to increment on each word */
if (IsOddByte || (V2Command == CMD_PROGRAM_EEPROM_ISP))
CurrentAddress++;
}
/* If the current page must be committed, send the PROGRAM PAGE command to the target */
if (Write_Memory_Params.ProgrammingMode & PROG_MODE_COMMIT_PAGE_MASK)
{
- SPI_SendByte(Write_Memory_Params.ProgrammingCommands[1]);
- SPI_SendByte(StartAddress >> 8);
- SPI_SendByte(StartAddress & 0xFF);
- SPI_SendByte(0x00);
+ ISPTarget_SendByte(Write_Memory_Params.ProgrammingCommands[1]);
+ ISPTarget_SendByte(StartAddress >> 8);
+ ISPTarget_SendByte(StartAddress & 0xFF);
+ ISPTarget_SendByte(0x00);
/* Check if polling is possible, if not switch to timed delay mode */
if (!(PollAddress))
ProgrammingStatus = ISPTarget_WaitForProgComplete(Write_Memory_Params.ProgrammingMode, PollAddress, PollValue,
Write_Memory_Params.DelayMS, Write_Memory_Params.ProgrammingCommands[2]);
+
+ /* Check to see if the FLASH address has crossed the extended address boundary */
+ if ((V2Command == CMD_PROGRAM_FLASH_ISP) && !(CurrentAddress & 0xFFFF))
+ MustLoadExtendedAddress = true;
}
}
else
bool IsOddByte = (CurrentByte & 0x01);
uint8_t ByteToWrite = *(NextWriteByte++);
- SPI_SendByte(Write_Memory_Params.ProgrammingCommands[0]);
- SPI_SendByte(CurrentAddress >> 8);
- SPI_SendByte(CurrentAddress & 0xFF);
- SPI_SendByte(ByteToWrite);
+ /* Check to see if we need to send a LOAD EXTENDED ADDRESS command to the target */
+ if (MustLoadExtendedAddress)
+ {
+ ISPTarget_LoadExtendedAddress();
+ MustLoadExtendedAddress = false;
+ }
+
+ ISPTarget_SendByte(Write_Memory_Params.ProgrammingCommands[0]);
+ ISPTarget_SendByte(CurrentAddress >> 8);
+ ISPTarget_SendByte(CurrentAddress & 0xFF);
+ ISPTarget_SendByte(ByteToWrite);
/* AVR FLASH addressing requires us to modify the write command based on if we are writing a high
* or low byte at the current word address */
PollAddress = (CurrentAddress & 0xFFFF);
}
-
- if (IsOddByte || (V2Command == CMD_PROGRAM_EEPROM_ISP))
- CurrentAddress++;
ProgrammingStatus = ISPTarget_WaitForProgComplete(Write_Memory_Params.ProgrammingMode, PollAddress, PollValue,
Write_Memory_Params.DelayMS, Write_Memory_Params.ProgrammingCommands[2]);
+ /* Abort the programming loop early if the byte/word programming failed */
if (ProgrammingStatus != STATUS_CMD_OK)
break;
+
+ /* EEPROM just increments the address each byte, flash needs to increment on each word and
+ * also check to ensure that a LOAD EXTENDED ADDRESS command is issued each time the extended
+ * address boundary has been crossed */
+ if ((CurrentByte & 0x01) || (V2Command == CMD_PROGRAM_EEPROM_ISP))
+ {
+ CurrentAddress++;
+
+ if ((V2Command != CMD_PROGRAM_EEPROM_ISP) && !(CurrentAddress & 0xFFFF))
+ MustLoadExtendedAddress = true;
+ }
}
}
Endpoint_Write_Byte(V2Command);
Endpoint_Write_Byte(STATUS_CMD_OK);
-
- /* Check to see if the host has issued a SET ADDRESS command and we haven't sent a
- * LOAD EXTENDED ADDRESS command (if needed, used when operating beyond the 128KB
- * FLASH barrier) */
- if (MustSetAddress)
- {
- if (CurrentAddress & (1UL << 31))
- ISPTarget_LoadExtendedAddress();
-
- MustSetAddress = false;
- }
/* Read each byte from the device and write them to the packet for the host */
for (uint16_t CurrentByte = 0; CurrentByte < Read_Memory_Params.BytesToRead; CurrentByte++)
{
+ /* Check to see if we need to send a LOAD EXTENDED ADDRESS command to the target */
+ if (MustLoadExtendedAddress)
+ {
+ ISPTarget_LoadExtendedAddress();
+ MustLoadExtendedAddress = false;
+ }
+
/* Read the next byte from the desired memory space in the device */
- SPI_SendByte(Read_Memory_Params.ReadMemoryCommand);
- SPI_SendByte(CurrentAddress >> 8);
- SPI_SendByte(CurrentAddress & 0xFF);
- Endpoint_Write_Byte(SPI_ReceiveByte());
+ ISPTarget_SendByte(Read_Memory_Params.ReadMemoryCommand);
+ ISPTarget_SendByte(CurrentAddress >> 8);
+ ISPTarget_SendByte(CurrentAddress & 0xFF);
+ Endpoint_Write_Byte(ISPTarget_ReceiveByte());
/* Check if the endpoint bank is currently full, if so send the packet */
if (!(Endpoint_IsReadWriteAllowed()))
* or low byte at the current word address */
if (V2Command == CMD_READ_FLASH_ISP)
Read_Memory_Params.ReadMemoryCommand ^= READ_WRITE_HIGH_BYTE_MASK;
-
- /* Only increment the current address if we have read both bytes in the current word when in FLASH
- * read mode, or for each byte when in EEPROM read mode */
- if (((CurrentByte & 0x01) && (V2Command == CMD_READ_FLASH_ISP)) || (V2Command == CMD_READ_EEPROM_ISP))
- CurrentAddress++;
+
+ /* EEPROM just increments the address each byte, flash needs to increment on each word and
+ * also check to ensure that a LOAD EXTENDED ADDRESS command is issued each time the extended
+ * address boundary has been crossed */
+ if ((CurrentByte & 0x01) || (V2Command == CMD_READ_EEPROM_ISP))
+ {
+ CurrentAddress++;
+
+ if ((V2Command != CMD_READ_EEPROM_ISP) && !(CurrentAddress & 0xFFFF))
+ MustLoadExtendedAddress = true;
+ }
}
Endpoint_Write_Byte(STATUS_CMD_OK);
/* Send the chip erase commands as given by the host to the device */
for (uint8_t SByte = 0; SByte < sizeof(Erase_Chip_Params.EraseCommandBytes); SByte++)
- SPI_SendByte(Erase_Chip_Params.EraseCommandBytes[SByte]);
+ ISPTarget_SendByte(Erase_Chip_Params.EraseCommandBytes[SByte]);
/* Use appropriate command completion check as given by the host (delay or busy polling) */
if (!(Erase_Chip_Params.PollMethod))
/* Send the Fuse or Lock byte read commands as given by the host to the device, store response */
for (uint8_t RByte = 0; RByte < sizeof(ResponseBytes); RByte++)
- ResponseBytes[RByte] = SPI_TransferByte(Read_FuseLockSigOSCCAL_Params.ReadCommandBytes[RByte]);
+ ResponseBytes[RByte] = ISPTarget_TransferByte(Read_FuseLockSigOSCCAL_Params.ReadCommandBytes[RByte]);
Endpoint_Write_Byte(V2Command);
Endpoint_Write_Byte(STATUS_CMD_OK);
/* Send the Fuse or Lock byte program commands as given by the host to the device */
for (uint8_t SByte = 0; SByte < sizeof(Write_FuseLockSig_Params.WriteCommandBytes); SByte++)
- SPI_SendByte(Write_FuseLockSig_Params.WriteCommandBytes[SByte]);
+ ISPTarget_SendByte(Write_FuseLockSig_Params.WriteCommandBytes[SByte]);
Endpoint_Write_Byte(V2Command);
Endpoint_Write_Byte(STATUS_CMD_OK);
while (CurrTxPos < SPI_Multi_Params.RxStartAddr)
{
if (CurrTxPos < SPI_Multi_Params.TxBytes)
- SPI_SendByte(SPI_Multi_Params.TxData[CurrTxPos]);
+ ISPTarget_SendByte(SPI_Multi_Params.TxData[CurrTxPos]);
else
- SPI_SendByte(0);
+ ISPTarget_SendByte(0);
CurrTxPos++;
}
while (CurrRxPos < SPI_Multi_Params.RxBytes)
{
if (CurrTxPos < SPI_Multi_Params.TxBytes)
- Endpoint_Write_Byte(SPI_TransferByte(SPI_Multi_Params.TxData[CurrTxPos++]));
+ Endpoint_Write_Byte(ISPTarget_TransferByte(SPI_Multi_Params.TxData[CurrTxPos++]));
else
- Endpoint_Write_Byte(SPI_ReceiveByte());
+ Endpoint_Write_Byte(ISPTarget_ReceiveByte());
/* Check to see if we have filled the endpoint bank and need to send the packet */
if (!(Endpoint_IsReadWriteAllowed()))
*/
void ISPProtocol_DelayMS(uint8_t DelayMS)
{
- while (DelayMS-- && TimeoutMSRemaining)
- {
- if (TimeoutMSRemaining)
- TimeoutMSRemaining--;
-
- _delay_ms(1);
- }
+ while (DelayMS-- && TimeoutTicksRemaining)
+ _delay_ms(1);
}
#endif
\ No newline at end of file