diff options
| -rw-r--r-- | LUFA/Drivers/USB/HighLevel/Events.h | 12 | ||||
| -rw-r--r-- | Projects/AVRISP-MKII/Descriptors.c | 4 | ||||
| -rw-r--r-- | Projects/AVRISP-MKII/Lib/ISP/ISPProtocol.c | 65 | ||||
| -rw-r--r-- | Projects/AVRISP-MKII/Lib/V2Protocol.c | 6 | ||||
| -rw-r--r-- | Projects/AVRISP-MKII/Lib/V2ProtocolParams.c | 2 | ||||
| -rw-r--r-- | Projects/AVRISP-MKII/Lib/V2ProtocolParams.h | 7 | ||||
| -rw-r--r-- | Projects/AVRISP-MKII/Lib/XPROG/XMEGANVM.c | 24 | ||||
| -rw-r--r-- | Projects/AVRISP-MKII/Lib/XPROG/XMEGANVM.h | 2 | ||||
| -rw-r--r-- | Projects/AVRISP-MKII/Lib/XPROG/XPROGProtocol.c | 6 | ||||
| -rw-r--r-- | Projects/AVRISP-MKII/Lib/XPROG/XPROGProtocol.h | 6 | 
10 files changed, 87 insertions, 47 deletions
| diff --git a/LUFA/Drivers/USB/HighLevel/Events.h b/LUFA/Drivers/USB/HighLevel/Events.h index 84b951ead4..08727d749e 100644 --- a/LUFA/Drivers/USB/HighLevel/Events.h +++ b/LUFA/Drivers/USB/HighLevel/Events.h @@ -40,8 +40,8 @@   *  listed here. If an event with no user-associated handler is fired within the library, it by default maps to an
   *  internal empty stub function.
   *
 - *  Each event must only have one associated event handler, but can be raised by multiple sources by calling the event
 - *  name just like any regular C function (with any required event parameters).
 + *  Each event must only have one associated event handler, but can be raised by multiple sources by calling the
 + *  event handler function (with any required event parameters).
   *
   *  @{
   */
 @@ -233,19 +233,25 @@  			 *  \note This event does not exist if the USB_HOST_ONLY token is supplied to the compiler (see
  			 *        \ref Group_USBManagement documentation).
  			 *
 +			 *  \note This event does not exist on the series 2 USB AVRs when the NO_LIMITED_CONTROLLER_CONNECT
 +			 *        compile time token is not set - see \ref EVENT_USB_Device_Disconnect.
 +			 *
  			 *  \see \ref EVENT_USB_Device_WakeUp() event for accompanying Wake Up event.
  			 */
  			void EVENT_USB_Device_Suspend(void);
  			/** Event for USB wake up. This event fires when a the USB interface is suspended while in device
  			 *  mode, and the host wakes up the device by supplying Start Of Frame pulses. This is generally
 -			 *  hooked to pull the user application out of a lowe power state and back into normal operating
 +			 *  hooked to pull the user application out of a low power state and back into normal operating
  			 *  mode. If the USB interface is enumerated with the \ref USB_OPT_AUTO_PLL option set, the library
  			 *  will automatically restart the USB PLL before the event is fired.
  			 *
  			 *  \note This event does not exist if the USB_HOST_ONLY token is supplied to the compiler (see
  			 *        \ref Group_USBManagement documentation).
  			 *
 +			 *  \note This event does not exist on the series 2 USB AVRs when the NO_LIMITED_CONTROLLER_CONNECT
 +			 *        compile time token is not set - see \ref EVENT_USB_Device_Connect.
 +			 *
  			 *  \see \ref EVENT_USB_Device_Suspend() event for accompanying Suspend event.
  			 */
  			void EVENT_USB_Device_WakeUp(void);
 diff --git a/Projects/AVRISP-MKII/Descriptors.c b/Projects/AVRISP-MKII/Descriptors.c index f89cfae7c3..6b4264f480 100644 --- a/Projects/AVRISP-MKII/Descriptors.c +++ b/Projects/AVRISP-MKII/Descriptors.c @@ -151,9 +151,9 @@ USB_Descriptor_String_t PROGMEM ManufacturerString =   */
  USB_Descriptor_String_t PROGMEM ProductString =
  {
 -	.Header                 = {.Size = USB_STRING_LEN(33), .Type = DTYPE_String},
 +	.Header                 = {.Size = USB_STRING_LEN(22), .Type = DTYPE_String},
 -	.UnicodeString          = L"LUFA AVRISP MkII Clone Programmer"
 +	.UnicodeString          = L"LUFA AVRISP MkII Clone"
  };
  USB_Descriptor_String_t PROGMEM SerialString =
 diff --git a/Projects/AVRISP-MKII/Lib/ISP/ISPProtocol.c b/Projects/AVRISP-MKII/Lib/ISP/ISPProtocol.c index 3a7e640b4f..936c9abc9e 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 093c07862e..976f24b9e3 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 c2595e78f6..00788515dd 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 04e32fe2ee..995468a4d8 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 c23b9d75b5..573f8fde5c 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 63fe05cc3f..cbd9e26f0e 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 9c6ee7e0c1..1be159c380 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 2bc7d8a50f..8e5d1b06d5 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)
 | 
