diff options
| author | Dean Camera <dean@fourwalledcubicle.com> | 2009-12-15 00:14:17 +0000 | 
|---|---|---|
| committer | Dean Camera <dean@fourwalledcubicle.com> | 2009-12-15 00:14:17 +0000 | 
| commit | a7880ac1cdbfe8ddaf957173bc08f334aad8bca7 (patch) | |
| tree | b2119bd8eaa823940abda4ce596ff195d9bf84f1 /Projects/AVRISP/Lib | |
| parent | bb3879331211a19c3adc3927cac870cc7e36b775 (diff) | |
| download | lufa-a7880ac1cdbfe8ddaf957173bc08f334aad8bca7.tar.gz lufa-a7880ac1cdbfe8ddaf957173bc08f334aad8bca7.tar.bz2 lufa-a7880ac1cdbfe8ddaf957173bc08f334aad8bca7.zip  | |
Fix error in AVRISP programmer when repeatedly using PDI mode via the hardware USART due to the SendByte routine not clearing the Transmit Complete USART flag.
Diffstat (limited to 'Projects/AVRISP/Lib')
| -rw-r--r-- | Projects/AVRISP/Lib/NVMTarget.c | 67 | ||||
| -rw-r--r-- | Projects/AVRISP/Lib/NVMTarget.h | 12 | ||||
| -rw-r--r-- | Projects/AVRISP/Lib/PDIProtocol.c | 10 | ||||
| -rw-r--r-- | Projects/AVRISP/Lib/PDITarget.c | 7 | 
4 files changed, 57 insertions, 39 deletions
diff --git a/Projects/AVRISP/Lib/NVMTarget.c b/Projects/AVRISP/Lib/NVMTarget.c index 85de13069..c2ed92d2e 100644 --- a/Projects/AVRISP/Lib/NVMTarget.c +++ b/Projects/AVRISP/Lib/NVMTarget.c @@ -93,16 +93,17 @@ bool NVMTarget_WaitWhileNVMControllerBusy(void)  /** Retrieves the CRC value of the given memory space.
   *
 - *  \param[in] CRCCommand  NVM CRC command to issue to the target
 + *  \param[in]  CRCCommand  NVM CRC command to issue to the target
 + *  \param[out] CRCDest     CRC Destination when read from the target
   *
 - *  \return 24-bit CRC value for the given address space
 + *  \return Boolean true if the command sequence complete sucessfully
   */
 -uint32_t NVMTarget_GetMemoryCRC(uint8_t CRCCommand)
 +bool NVMTarget_GetMemoryCRC(uint8_t CRCCommand, uint32_t* CRCDest)
  {
 -	uint32_t MemoryCRC;
 -
 -	NVMTarget_WaitWhileNVMControllerBusy();
 -
 +	/* Wait until the NVM controller is no longer busy */
 +	if (!(NVMTarget_WaitWhileNVMControllerBusy()))
 +	  return false;
 +	  
  	/* Set the NVM command to the correct CRC read command */
  	PDITarget_SendByte(PDI_CMD_STS | (PDI_DATSIZE_4BYTES << 2));
  	NVMTarget_SendNVMRegAddress(NVM_REG_CMD);
 @@ -113,26 +114,28 @@ uint32_t NVMTarget_GetMemoryCRC(uint8_t CRCCommand)  	NVMTarget_SendNVMRegAddress(NVM_REG_CTRLA);
  	PDITarget_SendByte(1 << 0);
 -	/* Wait until the NVM bus and controller is no longer busy */
 -	PDITarget_WaitWhileNVMBusBusy();
 -	NVMTarget_WaitWhileNVMControllerBusy();
 +	/* Wait until the NVM controller is no longer busy */
 +	if (!(NVMTarget_WaitWhileNVMControllerBusy()))
 +	  return false;
 +	
 +	*CRCDest = 0;
  	/* Read the first generated CRC byte value */
  	PDITarget_SendByte(PDI_CMD_LDS | (PDI_DATSIZE_4BYTES << 2));
  	NVMTarget_SendNVMRegAddress(NVM_REG_DAT0);
 -	MemoryCRC  = PDITarget_ReceiveByte();
 +	*CRCDest  = PDITarget_ReceiveByte();
  	/* Read the second generated CRC byte value */
  	PDITarget_SendByte(PDI_CMD_LDS | (PDI_DATSIZE_4BYTES << 2));
  	NVMTarget_SendNVMRegAddress(NVM_REG_DAT1);
 -	MemoryCRC |= ((uint16_t)PDITarget_ReceiveByte() << 8);
 +	*CRCDest |= ((uint16_t)PDITarget_ReceiveByte() << 8);
  	/* Read the third generated CRC byte value */
  	PDITarget_SendByte(PDI_CMD_LDS | (PDI_DATSIZE_4BYTES << 2));
  	NVMTarget_SendNVMRegAddress(NVM_REG_DAT2);
 -	MemoryCRC |= ((uint32_t)PDITarget_ReceiveByte() << 16);
 +	*CRCDest |= ((uint32_t)PDITarget_ReceiveByte() << 16);
 -	return MemoryCRC;
 +	return true;
  }
  /** Reads memory from the target's memory spaces.
 @@ -140,10 +143,14 @@ uint32_t NVMTarget_GetMemoryCRC(uint8_t CRCCommand)   *  \param[in]  ReadAddress  Start address to read from within the target's address space
   *  \param[out] ReadBuffer   Buffer to store read data into
   *  \param[in]  ReadSize     Number of bytes to read
 + *
 + *  \return Boolean true if the command sequence complete sucessfully
   */
 -void NVMTarget_ReadMemory(uint32_t ReadAddress, uint8_t* ReadBuffer, uint16_t ReadSize)
 +bool NVMTarget_ReadMemory(uint32_t ReadAddress, uint8_t* ReadBuffer, uint16_t ReadSize)
  {
 -	NVMTarget_WaitWhileNVMControllerBusy();
 +	/* Wait until the NVM controller is no longer busy */
 +	if (!(NVMTarget_WaitWhileNVMControllerBusy()))
 +	  return false;
  	/* Send the READNVM command to the NVM controller for reading of an aribtrary location */
  	PDITarget_SendByte(PDI_CMD_STS | (PDI_DATSIZE_4BYTES << 2));
 @@ -154,14 +161,11 @@ void NVMTarget_ReadMemory(uint32_t ReadAddress, uint8_t* ReadBuffer, uint16_t Re  	 * counters so that we can use the REPEAT command later to save on overhead for multiple bytes */
  	PDITarget_SendByte(PDI_CMD_LDS | (PDI_DATSIZE_4BYTES << 2));
  	NVMTarget_SendAddress(ReadAddress);
 -	*(ReadBuffer++) = PDITarget_ReceiveByte();
 +	*ReadBuffer = PDITarget_ReceiveByte();
  	/* Check to see if we are reading more than a single byte */
  	if (ReadSize > 1)
  	{
 -		/* Decrement the ReadSize counter as we have already read once byte of memory */
 -		ReadSize--;
 -	
  		/* Send the REPEAT command with the specified number of bytes remaining to read */
  		PDITarget_SendByte(PDI_CMD_REPEAT | PDI_DATSIZE_2BYTES);
  		PDITarget_SendByte(ReadSize &  0xFF);
 @@ -169,20 +173,27 @@ void NVMTarget_ReadMemory(uint32_t ReadAddress, uint8_t* ReadBuffer, uint16_t Re  		/* Send a LD command with indirect access and postincrement to read out the remaining bytes */
  		PDITarget_SendByte(PDI_CMD_LD | (PDI_POINTER_INDIRECT_PI << 2) | PDI_DATSIZE_1BYTE);
 -		for (uint16_t i = 1; i < ReadSize; i++)
 +		for (uint16_t i = 0; i < ReadSize; i++)
  		  *(ReadBuffer++) = PDITarget_ReceiveByte();
  	}
 +	
 +	return true;
  }
  /** Erases a specific memory space of the target.
   *
   *  \param[in] EraseCommand  NVM erase command to send to the device
   *  \param[in] Address  Address inside the memory space to erase
 + *
 + *  \return Boolean true if the command sequence complete sucessfully
   */
 -void NVMTarget_EraseMemory(uint8_t EraseCommand, uint32_t Address)
 +bool NVMTarget_EraseMemory(uint8_t EraseCommand, uint32_t Address)
  {
 -	NVMTarget_WaitWhileNVMControllerBusy();
 -
 +	/* Wait until the NVM controller is no longer busy */
 +	if (!(NVMTarget_WaitWhileNVMControllerBusy()))
 +	  return false;
 +	  
 +	/* Send the memory erase command to the target */
  	PDITarget_SendByte(PDI_CMD_STS | (PDI_DATSIZE_4BYTES << 2));
  	NVMTarget_SendNVMRegAddress(NVM_REG_CMD);
  	PDITarget_SendByte(EraseCommand);
 @@ -203,9 +214,11 @@ void NVMTarget_EraseMemory(uint8_t EraseCommand, uint32_t Address)  		PDITarget_SendByte(0x00);
  	}
 -	/* Wait until both the NVM bus and NVM controller are ready again */
 -	PDITarget_WaitWhileNVMBusBusy();
 -	NVMTarget_WaitWhileNVMControllerBusy();
 +	/* Wait until the NVM bus is ready again */
 +	if (!(PDITarget_WaitWhileNVMBusBusy()))
 +	  return false;
 +	  
 +	return true;
  }
  #endif
 diff --git a/Projects/AVRISP/Lib/NVMTarget.h b/Projects/AVRISP/Lib/NVMTarget.h index b43967f99..dae55ed12 100644 --- a/Projects/AVRISP/Lib/NVMTarget.h +++ b/Projects/AVRISP/Lib/NVMTarget.h @@ -106,11 +106,11 @@  		#define NVM_CMD_READEEPROM             0x06
  	/* Function Prototypes: */
 -		void     NVMTarget_SendNVMRegAddress(uint8_t Register);
 -		void     NVMTarget_SendAddress(uint32_t AbsoluteAddress);
 -		bool     NVMTarget_WaitWhileNVMControllerBusy(void);
 -		uint32_t NVMTarget_GetMemoryCRC(uint8_t CRCCommand);
 -		void     NVMTarget_ReadMemory(uint32_t ReadAddress, uint8_t* ReadBuffer, uint16_t ReadSize);
 -		void     NVMTarget_EraseMemory(uint8_t EraseCommand, uint32_t Address);
 +		void NVMTarget_SendNVMRegAddress(uint8_t Register);
 +		void NVMTarget_SendAddress(uint32_t AbsoluteAddress);
 +		bool NVMTarget_WaitWhileNVMControllerBusy(void);
 +		bool NVMTarget_GetMemoryCRC(uint8_t CRCCommand, uint32_t* CRCDest);
 +		bool NVMTarget_ReadMemory(uint32_t ReadAddress, uint8_t* ReadBuffer, uint16_t ReadSize);
 +		bool NVMTarget_EraseMemory(uint8_t EraseCommand, uint32_t Address);
  #endif
 diff --git a/Projects/AVRISP/Lib/PDIProtocol.c b/Projects/AVRISP/Lib/PDIProtocol.c index 24ce26cb6..46d6dd417 100644 --- a/Projects/AVRISP/Lib/PDIProtocol.c +++ b/Projects/AVRISP/Lib/PDIProtocol.c @@ -181,7 +181,8 @@ static void PDIProtocol_Erase(void)  	else if (Erase_XPROG_Params.MemoryType == XPRG_ERASE_USERSIG)
  	  EraseCommand = NVM_CMD_ERASEUSERSIG;
 -	NVMTarget_EraseMemory(EraseCommand, Erase_XPROG_Params.Address);
 +	if (!(NVMTarget_EraseMemory(EraseCommand, Erase_XPROG_Params.Address)))
 +	  ReturnStatus = XPRG_ERR_TIMEOUT;
  	Endpoint_Write_Byte(CMD_XPROG);
  	Endpoint_Write_Byte(XPRG_CMD_ERASE);
 @@ -241,7 +242,9 @@ static void PDIProtocol_ReadMemory(void)  	Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
  	uint8_t ReadBuffer[ReadMemory_XPROG_Params.Length];
 -	NVMTarget_ReadMemory(ReadMemory_XPROG_Params.Address, ReadBuffer, ReadMemory_XPROG_Params.Length);
 +	
 +	if (!(NVMTarget_ReadMemory(ReadMemory_XPROG_Params.Address, ReadBuffer, ReadMemory_XPROG_Params.Length)))
 +	  ReturnStatus = XPRG_ERR_TIMEOUT;
  	Endpoint_Write_Byte(CMD_XPROG);
  	Endpoint_Write_Byte(XPRG_CMD_READ_MEM);
 @@ -279,7 +282,8 @@ static void PDIProtocol_ReadCRC(void)  	else
  	  CRCCommand = NVM_CMD_FLASHCRC;
 -	MemoryCRC = NVMTarget_GetMemoryCRC(CRCCommand);
 +	if (!(NVMTarget_GetMemoryCRC(CRCCommand, &MemoryCRC)))
 +	  ReturnStatus = XPRG_ERR_TIMEOUT;
  	Endpoint_Write_Byte(CMD_XPROG);
  	Endpoint_Write_Byte(XPRG_CMD_CRC);
 diff --git a/Projects/AVRISP/Lib/PDITarget.c b/Projects/AVRISP/Lib/PDITarget.c index c774fdab8..28df55021 100644 --- a/Projects/AVRISP/Lib/PDITarget.c +++ b/Projects/AVRISP/Lib/PDITarget.c @@ -102,7 +102,7 @@ void PDITarget_EnableTargetPDI(void)  	/* Set up the synchronous USART for XMEGA communications - 
  	   8 data bits, even parity, 2 stop bits */
 -	UBRR1  = 10;
 +	UBRR1  = (F_CPU / 1000000UL);
  	UCSR1B = (1 << TXEN1);
  	UCSR1C = (1 << UMSEL10) | (1 << UPM11) | (1 << USBS1) | (1 << UCSZ11) | (1 << UCSZ10) | (1 << UCPOL1);
 @@ -167,15 +167,16 @@ void PDITarget_SendByte(uint8_t Byte)  		PORTD  |=  (1 << 3);
  		DDRD   |=  (1 << 3);
 -		UCSR1B &= ~(1 << RXEN1);
  		UCSR1B |=  (1 << TXEN1);
 +		UCSR1B &= ~(1 << RXEN1);
  		IsSending = true;
  	}
  	/* Wait until there is space in the hardware Tx buffer before writing */
  	while (!(UCSR1A & (1 << UDRE1)));
 -	UDR1 = Byte;
 +	UCSR1A |= (1 << TXC1);
 +	UDR1    = Byte;
  #else
  	/* Switch to Tx mode if currently in Rx mode */
  	if (!(IsSending))
  | 
