X-Git-Url: http://git.linex4red.de/pub/USBasp.git/blobdiff_plain/a9f313afa9a65a692718b8609fd47ae1dcb60523..77a9df36a77d2523dd2bc24fa17f9f04c6c175c5:/Projects/AVRISP-MKII/Lib/XPROG/XMEGANVM.c diff --git a/Projects/AVRISP-MKII/Lib/XPROG/XMEGANVM.c b/Projects/AVRISP-MKII/Lib/XPROG/XMEGANVM.c index 60e755265..e4f1186b0 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, 2010. + Copyright (C) Dean Camera, 2011. dean [at] fourwalledcubicle [dot] com www.lufa-lib.org */ /* - Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com) + Copyright 2011 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 @@ -45,10 +45,10 @@ 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]); - XPROGTarget_SendByte(((uint8_t*)&AbsoluteAddress)[1]); - XPROGTarget_SendByte(((uint8_t*)&AbsoluteAddress)[2]); - XPROGTarget_SendByte(((uint8_t*)&AbsoluteAddress)[3]); + XPROGTarget_SendByte(AbsoluteAddress & 0xFF); + XPROGTarget_SendByte(AbsoluteAddress >> 8); + XPROGTarget_SendByte(AbsoluteAddress >> 16); + XPROGTarget_SendByte(AbsoluteAddress >> 24); } /** Sends the given NVM register address to the target. @@ -80,7 +80,7 @@ bool XMEGANVM_WaitWhileNVMBusBusy(void) uint8_t StatusRegister = XPROGTarget_ReceiveByte(); /* We might have timed out waiting for the status register read response, check here */ - if (!(TimeoutTicksRemaining)) + if (TimeoutExpired) return false; /* Check the status register read response to see if the NVM bus is enabled */ @@ -105,10 +105,11 @@ bool XMEGANVM_WaitWhileNVMControllerBusy(void) { /* Fetch the current status value via the pointer register (without auto-increment afterwards) */ XPROGTarget_SendByte(PDI_CMD_LD | (PDI_POINTER_INDIRECT << 2) | PDI_DATSIZE_1BYTE); + uint8_t StatusRegister = XPROGTarget_ReceiveByte(); /* We might have timed out waiting for the status register read response, check here */ - if (!(TimeoutTicksRemaining)) + if (TimeoutExpired) return false; /* Check to see if the BUSY flag is still set */ @@ -117,6 +118,48 @@ bool XMEGANVM_WaitWhileNVMControllerBusy(void) } } +/** Enables the physical PDI interface on the target and enables access to the internal NVM controller. + * + * \return Boolean true if the PDI interface was enabled successfully, false otherwise + */ +bool XMEGANVM_EnablePDI(void) +{ + /* Enable PDI programming mode with the attached target */ + XPROGTarget_EnableTargetPDI(); + + /* Store the RESET key into the RESET PDI register to keep the XMEGA in reset */ + XPROGTarget_SendByte(PDI_CMD_STCS | PDI_RESET_REG); + XPROGTarget_SendByte(PDI_RESET_KEY); + + /* Lower direction change guard time to 0 USART bits */ + XPROGTarget_SendByte(PDI_CMD_STCS | PDI_CTRL_REG); + XPROGTarget_SendByte(0x07); + + /* Enable access to the XPROG NVM bus by sending the documented NVM access key to the device */ + XPROGTarget_SendByte(PDI_CMD_KEY); + for (uint8_t i = sizeof(PDI_NVMENABLE_KEY); i > 0; i--) + XPROGTarget_SendByte(PDI_NVMENABLE_KEY[i - 1]); + + /* Wait until the NVM bus becomes active */ + return XMEGANVM_WaitWhileNVMBusBusy(); +} + +/** Removes access to the target's NVM controller and physically disables the target's physical PDI interface. */ +void XMEGANVM_DisablePDI(void) +{ + XMEGANVM_WaitWhileNVMBusBusy(); + + /* Clear the RESET key in the RESET PDI register to allow the XMEGA to run */ + XPROGTarget_SendByte(PDI_CMD_STCS | PDI_RESET_REG); + XPROGTarget_SendByte(0x00); + + /* Do it twice to make sure it takes effect (silicon bug?) */ + XPROGTarget_SendByte(PDI_CMD_STCS | PDI_RESET_REG); + XPROGTarget_SendByte(0x00); + + XPROGTarget_DisableTargetPDI(); +} + /** Retrieves the CRC value of the given memory space. * * \param[in] CRCCommand NVM CRC command to issue to the target @@ -161,7 +204,7 @@ bool XMEGANVM_GetMemoryCRC(const uint8_t CRCCommand, uint32_t* const CRCDest) for (uint8_t i = 0; i < XMEGA_CRC_LENGTH; i++) ((uint8_t*)CRCDest)[i] = XPROGTarget_ReceiveByte(); - return (TimeoutTicksRemaining != 0); + return (TimeoutExpired == false); } /** Reads memory from the target's memory spaces. @@ -193,10 +236,10 @@ bool XMEGANVM_ReadMemory(const uint32_t ReadAddress, uint8_t* ReadBuffer, uint16 /* Send a LD command with indirect access and post-increment to read out the bytes */ XPROGTarget_SendByte(PDI_CMD_LD | (PDI_POINTER_INDIRECT_PI << 2) | PDI_DATSIZE_1BYTE); - while (ReadSize-- && TimeoutTicksRemaining) + while (ReadSize-- && !(TimeoutExpired)) *(ReadBuffer++) = XPROGTarget_ReceiveByte(); - return (TimeoutTicksRemaining != 0); + return (TimeoutExpired == false); } /** Writes byte addressed memory to the target's memory spaces.