Combined page and word ISP programming mode code in the AVRISP-MKII clone project to reduce compiled size and increase maintainability of the code.

pull/1469/head
Dean Camera 14 years ago
parent 958b20a8ef
commit 12418e6eaf

@ -25,6 +25,8 @@
* - Library Applications: * - Library Applications:
* - Changed the XPLAINBridge software UART to use the regular CTC mode instead of the alternative CTC mode * - Changed the XPLAINBridge software UART to use the regular CTC mode instead of the alternative CTC mode
* via the Input Capture register, to reduce user confusion * via the Input Capture register, to reduce user confusion
* - Combined page and word ISP programming mode code in the AVRISP-MKII clone project to reduce compiled size and
* increase maintainability of the code
* *
* <b>Fixed:</b> * <b>Fixed:</b>
* - Core: * - Core:

@ -70,7 +70,7 @@ void ISPProtocol_EnterISPMode(void)
/* Continuously attempt to synchronize with the target until either the number of attempts specified /* 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 */ * by the host has exceeded, or the the device sends back the expected response values */
while (Enter_ISP_Params.SynchLoops-- && (ResponseStatus == STATUS_CMD_FAILED) && TimeoutTicksRemaining) while (Enter_ISP_Params.SynchLoops-- && (ResponseStatus != STATUS_CMD_OK) && TimeoutTicksRemaining)
{ {
uint8_t ResponseBytes[4]; uint8_t ResponseBytes[4];
@ -167,15 +167,16 @@ void ISPProtocol_ProgramMemory(uint8_t V2Command)
Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN); Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
uint8_t ProgrammingStatus = STATUS_CMD_OK; uint8_t ProgrammingStatus = STATUS_CMD_OK;
uint16_t PollAddress = 0;
uint8_t PollValue = (V2Command == CMD_PROGRAM_FLASH_ISP) ? Write_Memory_Params.PollValue1 : uint8_t PollValue = (V2Command == CMD_PROGRAM_FLASH_ISP) ? Write_Memory_Params.PollValue1 :
Write_Memory_Params.PollValue2; Write_Memory_Params.PollValue2;
uint16_t PollAddress = 0;
uint8_t* NextWriteByte = Write_Memory_Params.ProgData; uint8_t* NextWriteByte = Write_Memory_Params.ProgData;
uint16_t PageStartAddress = (CurrentAddress & 0xFFFF);
/* Check the programming mode desired by the host, either Paged or Word memory writes */ for (uint16_t CurrentByte = 0; CurrentByte < Write_Memory_Params.BytesToWrite; CurrentByte++)
if (Write_Memory_Params.ProgrammingMode & PROG_MODE_PAGED_WRITES_MASK)
{ {
uint16_t StartAddress = (CurrentAddress & 0xFFFF); uint8_t ByteToWrite = *(NextWriteByte++);
uint8_t ProgrammingMode = Write_Memory_Params.ProgrammingMode;
/* Check to see if we need to send a LOAD EXTENDED ADDRESS command to the target */ /* Check to see if we need to send a LOAD EXTENDED ADDRESS command to the target */
if (MustLoadExtendedAddress) if (MustLoadExtendedAddress)
@ -184,125 +185,80 @@ void ISPProtocol_ProgramMemory(uint8_t V2Command)
MustLoadExtendedAddress = false; MustLoadExtendedAddress = false;
} }
/* Paged mode memory programming */ ISPTarget_SendByte(Write_Memory_Params.ProgrammingCommands[0]);
for (uint16_t CurrentByte = 0; CurrentByte < Write_Memory_Params.BytesToWrite; CurrentByte++) ISPTarget_SendByte(CurrentAddress >> 8);
{ ISPTarget_SendByte(CurrentAddress & 0xFF);
bool IsOddByte = (CurrentByte & 0x01); ISPTarget_SendByte(ByteToWrite);
uint8_t ByteToWrite = *(NextWriteByte++);
/* AVR FLASH addressing requires us to modify the write command based on if we are writing a high
ISPTarget_SendByte(Write_Memory_Params.ProgrammingCommands[0]); * or low byte at the current word address */
ISPTarget_SendByte(CurrentAddress >> 8); if (V2Command == CMD_PROGRAM_FLASH_ISP)
ISPTarget_SendByte(CurrentAddress & 0xFF); Write_Memory_Params.ProgrammingCommands[0] ^= READ_WRITE_HIGH_BYTE_MASK;
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 */
if (V2Command == CMD_PROGRAM_FLASH_ISP)
Write_Memory_Params.ProgrammingCommands[0] ^= READ_WRITE_HIGH_BYTE_MASK;
/* Check to see the write completion method, to see if we have a valid polling address */
if (!(PollAddress) && (ByteToWrite != PollValue))
{
if (IsOddByte && (V2Command == CMD_PROGRAM_FLASH_ISP))
Write_Memory_Params.ProgrammingCommands[2] |= READ_WRITE_HIGH_BYTE_MASK;
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 */ /* Check to see if we have a valid polling address */
if (Write_Memory_Params.ProgrammingMode & PROG_MODE_COMMIT_PAGE_MASK) if (!(PollAddress) && (ByteToWrite != PollValue))
{ {
ISPTarget_SendByte(Write_Memory_Params.ProgrammingCommands[1]); if ((CurrentByte & 0x01) && (V2Command == CMD_PROGRAM_FLASH_ISP))
ISPTarget_SendByte(StartAddress >> 8); Write_Memory_Params.ProgrammingCommands[2] |= READ_WRITE_HIGH_BYTE_MASK;
ISPTarget_SendByte(StartAddress & 0xFF); else
ISPTarget_SendByte(0x00); Write_Memory_Params.ProgrammingCommands[2] &= ~READ_WRITE_HIGH_BYTE_MASK;
/* Check if polling is enabled and possible, if not switch to timed delay mode */
if ((Write_Memory_Params.ProgrammingMode & PROG_MODE_PAGED_VALUE_MASK) && !(PollAddress))
{
Write_Memory_Params.ProgrammingMode = (Write_Memory_Params.ProgrammingMode & ~PROG_MODE_PAGED_VALUE_MASK) |
PROG_MODE_PAGED_TIMEDELAY_MASK;
}
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 */ PollAddress = (CurrentAddress & 0xFFFF);
if ((V2Command == CMD_PROGRAM_FLASH_ISP) && !(CurrentAddress & 0xFFFF))
MustLoadExtendedAddress = true;
} }
}
else /* If in word programming mode, commit the byte to the target's memory */
{ if (!(ProgrammingMode & PROG_MODE_PAGED_WRITES_MASK))
/* Word/byte mode memory programming */
for (uint16_t CurrentByte = 0; CurrentByte < Write_Memory_Params.BytesToWrite; CurrentByte++)
{ {
bool IsOddByte = (CurrentByte & 0x01); /* If the current polling address is invalid, switch to timed delay write completion mode */
uint8_t ByteToWrite = *(NextWriteByte++); if (!(PollAddress) && !(ProgrammingMode & PROG_MODE_WORD_READYBUSY_MASK))
ProgrammingMode = (ProgrammingMode & ~PROG_MODE_WORD_VALUE_MASK) | PROG_MODE_WORD_TIMEDELAY_MASK;
/* Check to see if we need to send a LOAD EXTENDED ADDRESS command to the target */
if (MustLoadExtendedAddress) ProgrammingStatus = ISPTarget_WaitForProgComplete(ProgrammingMode, PollAddress, PollValue,
{
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 */
if (V2Command == CMD_PROGRAM_FLASH_ISP)
Write_Memory_Params.ProgrammingCommands[0] ^= READ_WRITE_HIGH_BYTE_MASK;
/* Save previous programming mode in case we modify it for the current word */
uint8_t PreviousProgrammingMode = Write_Memory_Params.ProgrammingMode;
if (ByteToWrite != PollValue)
{
if (IsOddByte && (V2Command == CMD_PROGRAM_FLASH_ISP))
Write_Memory_Params.ProgrammingCommands[2] |= READ_WRITE_HIGH_BYTE_MASK;
else
Write_Memory_Params.ProgrammingCommands[2] &= ~READ_WRITE_HIGH_BYTE_MASK;
PollAddress = (CurrentAddress & 0xFFFF);
}
else if (!(Write_Memory_Params.ProgrammingMode & PROG_MODE_WORD_READYBUSY_MASK))
{
Write_Memory_Params.ProgrammingMode = (Write_Memory_Params.ProgrammingMode & ~PROG_MODE_WORD_VALUE_MASK) |
PROG_MODE_WORD_TIMEDELAY_MASK;
}
ProgrammingStatus = ISPTarget_WaitForProgComplete(Write_Memory_Params.ProgrammingMode, PollAddress, PollValue,
Write_Memory_Params.DelayMS, Write_Memory_Params.DelayMS,
Write_Memory_Params.ProgrammingCommands[2]); Write_Memory_Params.ProgrammingCommands[2]);
/* Restore previous programming mode mask in case the current word needed to change it */
Write_Memory_Params.ProgrammingMode = PreviousProgrammingMode;
/* Abort the programming loop early if the byte/word programming failed */ /* Abort the programming loop early if the byte/word programming failed */
if (ProgrammingStatus != STATUS_CMD_OK) if (ProgrammingStatus != STATUS_CMD_OK)
break; break;
/* EEPROM just increments the address each byte, flash needs to increment on each word and /* Must reset the polling address afterwards, so it is not erronously used for the next byte */
* also check to ensure that a LOAD EXTENDED ADDRESS command is issued each time the extended PollAddress = 0;
* address boundary has been crossed */ }
if (IsOddByte || (V2Command == CMD_PROGRAM_EEPROM_ISP))
{ /* EEPROM just increments the address each byte, flash needs to increment on each word and
CurrentAddress++; * 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;
}
}
/* 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)
{
ISPTarget_SendByte(Write_Memory_Params.ProgrammingCommands[1]);
ISPTarget_SendByte(PageStartAddress >> 8);
ISPTarget_SendByte(PageStartAddress & 0xFF);
ISPTarget_SendByte(0x00);
if ((V2Command != CMD_PROGRAM_EEPROM_ISP) && !(CurrentAddress & 0xFFFF)) /* Check if polling is enabled and possible, if not switch to timed delay mode */
MustLoadExtendedAddress = true; if ((Write_Memory_Params.ProgrammingMode & PROG_MODE_PAGED_VALUE_MASK) && !(PollAddress))
} {
Write_Memory_Params.ProgrammingMode = (Write_Memory_Params.ProgrammingMode & ~PROG_MODE_PAGED_VALUE_MASK) |
PROG_MODE_PAGED_TIMEDELAY_MASK;
} }
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;
} }
Endpoint_Write_Byte(V2Command); Endpoint_Write_Byte(V2Command);

@ -118,6 +118,7 @@ LUFA_PATH = ../..
# LUFA library compile-time options and predefined tokens # LUFA library compile-time options and predefined tokens
LUFA_OPTS = -D USB_DEVICE_ONLY LUFA_OPTS = -D USB_DEVICE_ONLY
LUFA_OPTS += -D DEVICE_STATE_AS_GPIOR=0 LUFA_OPTS += -D DEVICE_STATE_AS_GPIOR=0
LUFA_OPTS += -D ORDERED_EP_CONFIG
LUFA_OPTS += -D FIXED_CONTROL_ENDPOINT_SIZE=16 LUFA_OPTS += -D FIXED_CONTROL_ENDPOINT_SIZE=16
LUFA_OPTS += -D FIXED_NUM_CONFIGURATIONS=1 LUFA_OPTS += -D FIXED_NUM_CONFIGURATIONS=1
LUFA_OPTS += -D USE_FLASH_DESCRIPTORS LUFA_OPTS += -D USE_FLASH_DESCRIPTORS

Loading…
Cancel
Save