X-Git-Url: http://git.linex4red.de/pub/USBasp.git/blobdiff_plain/7c8f4a716f01f6598234fd60cd53345da4903fde..a9e0935a90346beb0c981924becc1f55d969a08b:/Projects/AVRISP-MKII/Lib/XPROG/XMEGANVM.c?ds=sidebyside diff --git a/Projects/AVRISP-MKII/Lib/XPROG/XMEGANVM.c b/Projects/AVRISP-MKII/Lib/XPROG/XMEGANVM.c index ea140be7b..1671d29ba 100644 --- a/Projects/AVRISP-MKII/Lib/XPROG/XMEGANVM.c +++ b/Projects/AVRISP-MKII/Lib/XPROG/XMEGANVM.c @@ -1,13 +1,13 @@ /* LUFA Library - Copyright (C) Dean Camera, 2009. + Copyright (C) Dean Camera, 2010. dean [at] fourwalledcubicle [dot] com www.fourwalledcubicle.com */ /* - Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com) + Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com) Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted @@ -38,24 +38,11 @@ #if defined(ENABLE_XPROG_PROTOCOL) || defined(__DOXYGEN__) -/** Sends the given NVM register address to the target. - * - * \param[in] Register NVM register whose absolute address is to be sent - */ -void XMEGANVM_SendNVMRegAddress(const uint8_t Register) -{ - /* Determine the absolute register address from the NVM base memory address and the NVM register address */ - uint32_t Address = XPROG_Param_NVMBase | Register; - - /* Send the calculated 32-bit address to the target, LSB first */ - XMEGANVM_SendAddress(Address); -} - /** Sends the given 32-bit absolute address to the target. * * \param[in] AbsoluteAddress Absolute address to send to the target */ -void XMEGANVM_SendAddress(const uint32_t AbsoluteAddress) +static void XMEGANVM_SendAddress(const uint32_t AbsoluteAddress) { /* Send the given 32-bit address to the target, LSB first */ XPROGTarget_SendByte(((uint8_t*)&AbsoluteAddress)[0]); @@ -64,6 +51,19 @@ void XMEGANVM_SendAddress(const uint32_t AbsoluteAddress) XPROGTarget_SendByte(((uint8_t*)&AbsoluteAddress)[3]); } +/** Sends the given NVM register address to the target. + * + * \param[in] Register NVM register whose absolute address is to be sent + */ +static void XMEGANVM_SendNVMRegAddress(const uint8_t Register) +{ + /* Determine the absolute register address from the NVM base memory address and the NVM register address */ + uint32_t Address = XPROG_Param_NVMBase | Register; + + /* Send the calculated 32-bit address to the target, LSB first */ + XMEGANVM_SendAddress(Address); +} + /** Busy-waits while the NVM controller is busy performing a NVM operation, such as a FLASH page read or CRC * calculation. * @@ -76,8 +76,19 @@ bool XMEGANVM_WaitWhileNVMBusBusy(void) { /* Send the LDCS command to read the PDI STATUS register to see the NVM bus is active */ XPROGTarget_SendByte(PDI_CMD_LDCS | PDI_STATUS_REG); - if (XPROGTarget_ReceiveByte() & PDI_STATUS_NVM) - return true; + + uint8_t StatusRegister = XPROGTarget_ReceiveByte(); + + /* We might have timed out waiting for the status register read response, check here */ + if (!(TimeoutMSRemaining)) + return false; + + /* Check the status register read response to see if the NVM bus is enabled */ + if (StatusRegister & PDI_STATUS_NVM) + { + TimeoutMSRemaining = COMMAND_TIMEOUT_MS; + return true; + } } return false; @@ -97,9 +108,18 @@ bool XMEGANVM_WaitWhileNVMControllerBusy(void) XPROGTarget_SendByte(PDI_CMD_LDS | (PDI_DATSIZE_4BYTES << 2)); XMEGANVM_SendNVMRegAddress(XMEGA_NVM_REG_STATUS); + uint8_t StatusRegister = XPROGTarget_ReceiveByte(); + + /* We might have timed out waiting for the status register read response, check here */ + if (!(TimeoutMSRemaining)) + return false; + /* Check to see if the BUSY flag is still set */ - if (!(XPROGTarget_ReceiveByte() & (1 << 7))) - return true; + if (!(StatusRegister & (1 << 7))) + { + TimeoutMSRemaining = COMMAND_TIMEOUT_MS; + return true; + } } return false; @@ -136,26 +156,20 @@ 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; + return (TimeoutMSRemaining != 0); } /** Reads memory from the target's memory spaces. @@ -187,10 +201,10 @@ bool XMEGANVM_ReadMemory(const uint32_t ReadAddress, uint8_t* ReadBuffer, uint16 /* Send a LD command with indirect access and postincrement to read out the bytes */ XPROGTarget_SendByte(PDI_CMD_LD | (PDI_POINTER_INDIRECT_PI << 2) | PDI_DATSIZE_1BYTE); - while (ReadSize--) + while (ReadSize-- && TimeoutMSRemaining) *(ReadBuffer++) = XPROGTarget_ReceiveByte(); - return true; + return (TimeoutMSRemaining != 0); } /** Writes byte addressed memory to the target's memory spaces. @@ -328,7 +342,7 @@ bool XMEGANVM_EraseMemory(const uint8_t EraseCommand, const uint32_t Address) { /* Other erase modes just need us to address a byte within the target memory space */ XPROGTarget_SendByte(PDI_CMD_STS | (PDI_DATSIZE_4BYTES << 2)); - XMEGANVM_SendAddress(Address); + XMEGANVM_SendAddress(Address); XPROGTarget_SendByte(0x00); }