aboutsummaryrefslogtreecommitdiffstats
path: root/Projects/AVRISP-MKII/Lib
diff options
context:
space:
mode:
authorDean Camera <dean@fourwalledcubicle.com>2010-01-17 04:39:33 +0000
committerDean Camera <dean@fourwalledcubicle.com>2010-01-17 04:39:33 +0000
commitf3d370a7778dc8e374efc3b76e26f8ecefc27e84 (patch)
tree8e6b6a3842e05e78d7bb51a38975ff09286558c0 /Projects/AVRISP-MKII/Lib
parentb0ce1eab668ac2e4779bbf8c3e6ef193d0ab0368 (diff)
downloadlufa-f3d370a7778dc8e374efc3b76e26f8ecefc27e84.tar.gz
lufa-f3d370a7778dc8e374efc3b76e26f8ecefc27e84.tar.bz2
lufa-f3d370a7778dc8e374efc3b76e26f8ecefc27e84.zip
Clean up and add more comments to the AVRISP-MKII project. Make sure the SPI_MULTI command handler supports multiple packet responses. Use slightly smaller/faster repeated indirect-load commands when retrieving the PDI target's memory CRCs.
Diffstat (limited to 'Projects/AVRISP-MKII/Lib')
-rw-r--r--Projects/AVRISP-MKII/Lib/ISP/ISPProtocol.c65
-rw-r--r--Projects/AVRISP-MKII/Lib/V2Protocol.c6
-rw-r--r--Projects/AVRISP-MKII/Lib/V2ProtocolParams.c2
-rw-r--r--Projects/AVRISP-MKII/Lib/V2ProtocolParams.h7
-rw-r--r--Projects/AVRISP-MKII/Lib/XPROG/XMEGANVM.c24
-rw-r--r--Projects/AVRISP-MKII/Lib/XPROG/XMEGANVM.h2
-rw-r--r--Projects/AVRISP-MKII/Lib/XPROG/XPROGProtocol.c6
-rw-r--r--Projects/AVRISP-MKII/Lib/XPROG/XPROGProtocol.h6
8 files changed, 76 insertions, 42 deletions
diff --git a/Projects/AVRISP-MKII/Lib/ISP/ISPProtocol.c b/Projects/AVRISP-MKII/Lib/ISP/ISPProtocol.c
index 3a7e640b4..936c9abc9 100644
--- a/Projects/AVRISP-MKII/Lib/ISP/ISPProtocol.c
+++ b/Projects/AVRISP-MKII/Lib/ISP/ISPProtocol.c
@@ -65,7 +65,9 @@ void ISPProtocol_EnterISPMode(void)
ISPProtocol_DelayMS(Enter_ISP_Params.ExecutionDelayMS);
SPI_Init(ISPTarget_GetSPIPrescalerMask() | SPI_SCK_LEAD_RISING | SPI_SAMPLE_LEADING | SPI_MODE_MASTER);
-
+
+ /* 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))
{
uint8_t ResponseBytes[4];
@@ -110,6 +112,7 @@ void ISPProtocol_LeaveISPMode(void)
Endpoint_ClearOUT();
Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
+ /* 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();
@@ -166,6 +169,9 @@ void ISPProtocol_ProgramMemory(uint8_t V2Command)
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))
@@ -174,6 +180,7 @@ void ISPProtocol_ProgramMemory(uint8_t V2Command)
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);
@@ -184,16 +191,16 @@ void ISPProtocol_ProgramMemory(uint8_t V2Command)
bool IsOddByte = (CurrentByte & 0x01);
uint8_t ByteToWrite = *(NextWriteByte++);
- if (IsOddByte && (V2Command == CMD_PROGRAM_FLASH_ISP))
- Write_Memory_Params.ProgrammingCommands[0] |= READ_WRITE_HIGH_BYTE_MASK;
- else
- Write_Memory_Params.ProgrammingCommands[0] &= ~READ_WRITE_HIGH_BYTE_MASK;
-
SPI_SendByte(Write_Memory_Params.ProgrammingCommands[0]);
SPI_SendByte(CurrentAddress >> 8);
SPI_SendByte(CurrentAddress & 0xFF);
SPI_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 */
+ 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))
@@ -289,6 +296,9 @@ void ISPProtocol_ReadMemory(uint8_t V2Command)
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))
@@ -297,28 +307,30 @@ void ISPProtocol_ReadMemory(uint8_t V2Command)
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++)
{
- bool IsOddByte = (CurrentByte & 0x01);
-
- if (IsOddByte && (V2Command == CMD_READ_FLASH_ISP))
- Read_Memory_Params.ReadMemoryCommand |= READ_WRITE_HIGH_BYTE_MASK;
- else
- Read_Memory_Params.ReadMemoryCommand &= ~READ_WRITE_HIGH_BYTE_MASK;
-
+ /* 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());
- /* Check if the endpoint bank is currently full */
+ /* Check if the endpoint bank is currently full, if so send the packet */
if (!(Endpoint_IsReadWriteAllowed()))
{
Endpoint_ClearIN();
Endpoint_WaitUntilReady();
}
- if ((IsOddByte && (V2Command == CMD_READ_FLASH_ISP)) || (V2Command == CMD_READ_EEPROM_ISP))
+ /* AVR FLASH addressing requires us to modify the read command based on if we are reading a high
+ * 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++;
}
@@ -353,9 +365,11 @@ void ISPProtocol_ChipErase(void)
uint8_t ResponseStatus = 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]);
+ /* Use appropriate command completion check as given by the host (delay or busy polling) */
if (!(Erase_Chip_Params.PollMethod))
ISPProtocol_DelayMS(Erase_Chip_Params.EraseDelayMS);
else
@@ -385,7 +399,8 @@ void ISPProtocol_ReadFuseLockSigOSCCAL(uint8_t V2Command)
Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
uint8_t ResponseBytes[4];
-
+
+ /* 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]);
@@ -413,6 +428,7 @@ void ISPProtocol_WriteFuseLock(uint8_t V2Command)
Endpoint_ClearOUT();
Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
+ /* 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]);
@@ -463,12 +479,29 @@ void ISPProtocol_SPIMulti(void)
Endpoint_Write_Byte(SPI_TransferByte(SPI_Multi_Params.TxData[CurrTxPos++]));
else
Endpoint_Write_Byte(SPI_ReceiveByte());
+
+ /* Check to see if we have filled the endpoint bank and need to send the packet */
+ if (!(Endpoint_IsReadWriteAllowed()))
+ {
+ Endpoint_ClearIN();
+ Endpoint_WaitUntilReady();
+ }
CurrRxPos++;
}
Endpoint_Write_Byte(STATUS_CMD_OK);
+
+ bool IsEndpointFull = !(Endpoint_IsReadWriteAllowed());
Endpoint_ClearIN();
+
+ /* Ensure last packet is a short packet to terminate the transfer */
+ if (IsEndpointFull)
+ {
+ Endpoint_WaitUntilReady();
+ Endpoint_ClearIN();
+ Endpoint_WaitUntilReady();
+ }
}
#endif \ No newline at end of file
diff --git a/Projects/AVRISP-MKII/Lib/V2Protocol.c b/Projects/AVRISP-MKII/Lib/V2Protocol.c
index 093c07862..976f24b9e 100644
--- a/Projects/AVRISP-MKII/Lib/V2Protocol.c
+++ b/Projects/AVRISP-MKII/Lib/V2Protocol.c
@@ -58,6 +58,7 @@ void V2Protocol_ProcessCommand(void)
{
uint8_t V2Command = Endpoint_Read_Byte();
+ /* Set total command processing timeout value, enable timeout management interrupt */
TimeoutMSRemaining = COMMAND_TIMEOUT_MS;
TIMSK0 |= (1 << OCIE0A);
@@ -121,6 +122,7 @@ void V2Protocol_ProcessCommand(void)
break;
}
+ /* Disable timeout management interrupt once processing has completed */
TIMSK0 &= ~(1 << OCIE0A);
Endpoint_WaitUntilReady();
@@ -162,8 +164,8 @@ static void V2Protocol_SignOn(void)
Endpoint_ClearIN();
}
-/** Handler for the CMD_RESET_PROTECTION command, currently implemented as a dummy ACK function
- * as no ISP short-circuit protection is currently implemented.
+/** Handler for the CMD_RESET_PROTECTION command, implemented as a dummy ACK function as
+ * no target short-circuit protection is currently implemented.
*/
static void V2Protocol_ResetProtection(void)
{
diff --git a/Projects/AVRISP-MKII/Lib/V2ProtocolParams.c b/Projects/AVRISP-MKII/Lib/V2ProtocolParams.c
index c2595e78f..00788515d 100644
--- a/Projects/AVRISP-MKII/Lib/V2ProtocolParams.c
+++ b/Projects/AVRISP-MKII/Lib/V2ProtocolParams.c
@@ -170,7 +170,7 @@ static ParameterItem_t* V2Params_GetParamFromTable(const uint8_t ParamID)
ParameterItem_t* CurrTableItem = ParameterTable;
/* Find the parameter in the parameter table if present */
- for (uint8_t TableIndex = 0; TableIndex < (sizeof(ParameterTable) / sizeof(ParameterTable[0])); TableIndex++)
+ for (uint8_t TableIndex = 0; TableIndex < TABLE_PARAM_COUNT; TableIndex++)
{
if (ParamID == CurrTableItem->ParamID)
return CurrTableItem;
diff --git a/Projects/AVRISP-MKII/Lib/V2ProtocolParams.h b/Projects/AVRISP-MKII/Lib/V2ProtocolParams.h
index 04e32fe2e..995468a4d 100644
--- a/Projects/AVRISP-MKII/Lib/V2ProtocolParams.h
+++ b/Projects/AVRISP-MKII/Lib/V2ProtocolParams.h
@@ -52,10 +52,13 @@
/* Macros: */
/** Parameter privilege mask to allow the host PC to read the parameter's value */
- #define PARAM_PRIV_READ (1 << 0)
+ #define PARAM_PRIV_READ (1 << 0)
/** Parameter privilege mask to allow the host PC to change the parameter's value */
- #define PARAM_PRIV_WRITE (1 << 1)
+ #define PARAM_PRIV_WRITE (1 << 1)
+
+ /** Total number of parameters in the parameter table */
+ #define TABLE_PARAM_COUNT (sizeof(ParameterTable) / sizeof(ParameterTable[0]))
/* Type Defines: */
/** Type define for a parameter table entry indicating a PC readable or writable device parameter. */
diff --git a/Projects/AVRISP-MKII/Lib/XPROG/XMEGANVM.c b/Projects/AVRISP-MKII/Lib/XPROG/XMEGANVM.c
index c23b9d75b..573f8fde5 100644
--- a/Projects/AVRISP-MKII/Lib/XPROG/XMEGANVM.c
+++ b/Projects/AVRISP-MKII/Lib/XPROG/XMEGANVM.c
@@ -136,24 +136,18 @@ bool XMEGANVM_GetMemoryCRC(const uint8_t CRCCommand, uint32_t* const CRCDest)
if (!(XMEGANVM_WaitWhileNVMControllerBusy()))
return false;
- uint32_t MemoryCRC = 0;
-
- /* Read the first generated CRC byte value */
- XPROGTarget_SendByte(PDI_CMD_LDS | (PDI_DATSIZE_4BYTES << 2));
+ /* Load the PDI pointer register with the DAT0 register start address */
+ XPROGTarget_SendByte(PDI_CMD_ST | (PDI_POINTER_DIRECT << 2) | PDI_DATSIZE_4BYTES);
XMEGANVM_SendNVMRegAddress(XMEGA_NVM_REG_DAT0);
- MemoryCRC = XPROGTarget_ReceiveByte();
-
- /* Read the second generated CRC byte value */
- XPROGTarget_SendByte(PDI_CMD_LDS | (PDI_DATSIZE_4BYTES << 2));
- XMEGANVM_SendNVMRegAddress(XMEGA_NVM_REG_DAT1);
- MemoryCRC |= ((uint16_t)XPROGTarget_ReceiveByte() << 8);
- /* Read the third generated CRC byte value */
- XPROGTarget_SendByte(PDI_CMD_LDS | (PDI_DATSIZE_4BYTES << 2));
- XMEGANVM_SendNVMRegAddress(XMEGA_NVM_REG_DAT2);
- MemoryCRC |= ((uint32_t)XPROGTarget_ReceiveByte() << 16);
+ /* Send the REPEAT command to grab the CRC bytes */
+ XPROGTarget_SendByte(PDI_CMD_REPEAT | PDI_DATSIZE_1BYTE);
+ XPROGTarget_SendByte(XMEGA_CRC_LENGTH - 1);
- *CRCDest = MemoryCRC;
+ /* Read in the CRC bytes from the target */
+ XPROGTarget_SendByte(PDI_CMD_LD | (PDI_POINTER_INDIRECT_PI << 2) | PDI_DATSIZE_1BYTE);
+ for (uint8_t i = 0; i < XMEGA_CRC_LENGTH; i++)
+ ((uint8_t*)CRCDest)[i] = XPROGTarget_ReceiveByte();
return true;
}
diff --git a/Projects/AVRISP-MKII/Lib/XPROG/XMEGANVM.h b/Projects/AVRISP-MKII/Lib/XPROG/XMEGANVM.h
index 63fe05cc3..cbd9e26f0 100644
--- a/Projects/AVRISP-MKII/Lib/XPROG/XMEGANVM.h
+++ b/Projects/AVRISP-MKII/Lib/XPROG/XMEGANVM.h
@@ -56,6 +56,8 @@
#endif
/* Defines: */
+ #define XMEGA_CRC_LENGTH 3
+
#define XMEGA_NVM_REG_ADDR0 0x00
#define XMEGA_NVM_REG_ADDR1 0x01
#define XMEGA_NVM_REG_ADDR2 0x02
diff --git a/Projects/AVRISP-MKII/Lib/XPROG/XPROGProtocol.c b/Projects/AVRISP-MKII/Lib/XPROG/XPROGProtocol.c
index 9c6ee7e0c..1be159c38 100644
--- a/Projects/AVRISP-MKII/Lib/XPROG/XPROGProtocol.c
+++ b/Projects/AVRISP-MKII/Lib/XPROG/XPROGProtocol.c
@@ -38,7 +38,7 @@
#if defined(ENABLE_XPROG_PROTOCOL) || defined(__DOXYGEN__)
/** Base absolute address for the target's NVM controller for PDI programming */
-uint32_t XPROG_Param_NVMBase = 0x010001C0;
+uint32_t XPROG_Param_NVMBase = 0x010001C0;
/** Size in bytes of the target's EEPROM page */
uint16_t XPROG_Param_EEPageSize;
@@ -455,10 +455,10 @@ static void XPROGProtocol_SetParam(void)
case XPRG_PARAM_EEPPAGESIZE:
XPROG_Param_EEPageSize = Endpoint_Read_Word_BE();
break;
- case XPRG_PARAM_NVMCMD:
+ case XPRG_PARAM_NVMCMD_REG:
XPROG_Param_NVMCMDRegAddr = Endpoint_Read_Byte();
break;
- case XPRG_PARAM_NVMCSR:
+ case XPRG_PARAM_NVMCSR_REG:
XPROG_Param_NVMCSRRegAddr = Endpoint_Read_Byte();
break;
default:
diff --git a/Projects/AVRISP-MKII/Lib/XPROG/XPROGProtocol.h b/Projects/AVRISP-MKII/Lib/XPROG/XPROGProtocol.h
index 2bc7d8a50..8e5d1b06d 100644
--- a/Projects/AVRISP-MKII/Lib/XPROG/XPROGProtocol.h
+++ b/Projects/AVRISP-MKII/Lib/XPROG/XPROGProtocol.h
@@ -98,12 +98,12 @@
#define XPRG_PARAM_NVMBASE 0x01
#define XPRG_PARAM_EEPPAGESIZE 0x02
- #define XPRG_PARAM_NVMCMD 0x03
- #define XPRG_PARAM_NVMCSR 0x04
+ #define XPRG_PARAM_NVMCMD_REG 0x03 /* Undocumented, Reverse-engineered */
+ #define XPRG_PARAM_NVMCSR_REG 0x04 /* Undocumented, Reverse-engineered */
#define XPRG_PROTOCOL_PDI 0x00
#define XPRG_PROTOCOL_JTAG 0x01
- #define XPRG_PROTOCOL_TPI 0x02
+ #define XPRG_PROTOCOL_TPI 0x02 /* Undocumented, Reverse-engineered */
#define XPRG_PAGEMODE_WRITE (1 << 1)
#define XPRG_PAGEMODE_ERASE (1 << 0)