aboutsummaryrefslogtreecommitdiffstats
path: root/Projects/AVRISP/Lib
diff options
context:
space:
mode:
authorDean Camera <dean@fourwalledcubicle.com>2009-12-15 00:14:17 +0000
committerDean Camera <dean@fourwalledcubicle.com>2009-12-15 00:14:17 +0000
commita7880ac1cdbfe8ddaf957173bc08f334aad8bca7 (patch)
treeb2119bd8eaa823940abda4ce596ff195d9bf84f1 /Projects/AVRISP/Lib
parentbb3879331211a19c3adc3927cac870cc7e36b775 (diff)
downloadlufa-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.c67
-rw-r--r--Projects/AVRISP/Lib/NVMTarget.h12
-rw-r--r--Projects/AVRISP/Lib/PDIProtocol.c10
-rw-r--r--Projects/AVRISP/Lib/PDITarget.c7
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))