diff --git a/LUFA/ManPages/ChangeLog.txt b/LUFA/ManPages/ChangeLog.txt index 1297202afc..b399a75d66 100644 --- a/LUFA/ManPages/ChangeLog.txt +++ b/LUFA/ManPages/ChangeLog.txt @@ -102,6 +102,7 @@ * - Fixed USBtoSerial and XPLAINBridge demos discarding data from the PC if the send buffer becomes full * - Fixed broken input in the MagStripe reader project due to an incorrect HID report descriptor * - Fixed incorrect PollingIntervalMS values in the demo/project/bootloader endpoint descriptors (thanks to MCS Electronics) + * - Fixed AVRISP-MKII clone project not starting the target's program automatically after exiting TPI programming mode * * \section Sec_ChangeLog100807 Version 100807 * New: diff --git a/Projects/AVRISP-MKII/Lib/XPROG/TINYNVM.c b/Projects/AVRISP-MKII/Lib/XPROG/TINYNVM.c index 26d6bf16f7..551d4029c8 100644 --- a/Projects/AVRISP-MKII/Lib/XPROG/TINYNVM.c +++ b/Projects/AVRISP-MKII/Lib/XPROG/TINYNVM.c @@ -119,6 +119,40 @@ bool TINYNVM_WaitWhileNVMControllerBusy(void) } } +/** Enables the physical TPI interface on the target and enables access to the internal NVM controller. + * + * \return Boolean true if the TPI interface was enabled successfully, false otherwise + */ +bool TINYNVM_EnableTPI(void) +{ + /* Enable TPI programming mode with the attached target */ + XPROGTarget_EnableTargetTPI(); + + /* Lower direction change guard time to 0 USART bits */ + XPROGTarget_SendByte(TPI_CMD_SSTCS | TPI_CTRL_REG); + XPROGTarget_SendByte(0x07); + + /* Enable access to the XPROG NVM bus by sending the documented NVM access key to the device */ + XPROGTarget_SendByte(TPI_CMD_SKEY); + for (uint8_t i = sizeof(TPI_NVMENABLE_KEY); i > 0; i--) + XPROGTarget_SendByte(TPI_NVMENABLE_KEY[i - 1]); + + /* Wait until the NVM bus becomes active */ + return TINYNVM_WaitWhileNVMBusBusy(); +} + +/** Removes access to the target's NVM controller and physically disables the target's physical TPI interface. */ +void TINYNVM_DisableTPI(void) +{ + TINYNVM_WaitWhileNVMBusBusy(); + + /* Clear the NVMEN bit in the TPI STATUS register to disable TPI mode */ + XPROGTarget_SendByte(TPI_CMD_SSTCS | TPI_STATUS_REG); + XPROGTarget_SendByte(0x00); + + XPROGTarget_DisableTargetTPI(); +} + /** Reads memory from the target's memory spaces. * * \param[in] ReadAddress Start address to read from within the target's address space diff --git a/Projects/AVRISP-MKII/Lib/XPROG/TINYNVM.h b/Projects/AVRISP-MKII/Lib/XPROG/TINYNVM.h index 905f6fc7d8..27a3dba832 100644 --- a/Projects/AVRISP-MKII/Lib/XPROG/TINYNVM.h +++ b/Projects/AVRISP-MKII/Lib/XPROG/TINYNVM.h @@ -64,6 +64,8 @@ /* Function Prototypes: */ bool TINYNVM_WaitWhileNVMBusBusy(void); bool TINYNVM_WaitWhileNVMControllerBusy(void); + bool TINYNVM_EnableTPI(void); + void TINYNVM_DisableTPI(void); bool TINYNVM_ReadMemory(const uint16_t ReadAddress, uint8_t* ReadBuffer, uint16_t ReadLength); diff --git a/Projects/AVRISP-MKII/Lib/XPROG/XMEGANVM.c b/Projects/AVRISP-MKII/Lib/XPROG/XMEGANVM.c index 60e755265c..378e691ad0 100644 --- a/Projects/AVRISP-MKII/Lib/XPROG/XMEGANVM.c +++ b/Projects/AVRISP-MKII/Lib/XPROG/XMEGANVM.c @@ -105,6 +105,7 @@ 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 */ @@ -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 diff --git a/Projects/AVRISP-MKII/Lib/XPROG/XMEGANVM.h b/Projects/AVRISP-MKII/Lib/XPROG/XMEGANVM.h index 5f5eded1f9..6ec8b7ebac 100644 --- a/Projects/AVRISP-MKII/Lib/XPROG/XMEGANVM.h +++ b/Projects/AVRISP-MKII/Lib/XPROG/XMEGANVM.h @@ -108,6 +108,8 @@ /* Function Prototypes: */ bool XMEGANVM_WaitWhileNVMBusBusy(void); bool XMEGANVM_WaitWhileNVMControllerBusy(void); + bool XMEGANVM_EnablePDI(void); + void XMEGANVM_DisablePDI(void); bool XMEGANVM_GetMemoryCRC(const uint8_t CRCCommand, uint32_t* const CRCDest); bool XMEGANVM_ReadMemory(const uint32_t ReadAddress, uint8_t* ReadBuffer, uint16_t ReadSize); bool XMEGANVM_WriteByteMemory(const uint8_t WriteCommand, const uint32_t WriteAddress, const uint8_t Byte); diff --git a/Projects/AVRISP-MKII/Lib/XPROG/XPROGProtocol.c b/Projects/AVRISP-MKII/Lib/XPROG/XPROGProtocol.c index 276f63e0ea..223a735112 100644 --- a/Projects/AVRISP-MKII/Lib/XPROG/XPROGProtocol.c +++ b/Projects/AVRISP-MKII/Lib/XPROG/XPROGProtocol.c @@ -118,43 +118,9 @@ static void XPROGProtocol_EnterXPROGMode(void) bool NVMBusEnabled = false; if (XPROG_SelectedProtocol == XPRG_PROTOCOL_PDI) - { - /* 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 */ - NVMBusEnabled = XMEGANVM_WaitWhileNVMBusBusy(); - } + NVMBusEnabled = XMEGANVM_EnablePDI(); else if (XPROG_SelectedProtocol == XPRG_PROTOCOL_TPI) - { - /* Enable TPI programming mode with the attached target */ - XPROGTarget_EnableTargetTPI(); - - /* Lower direction change guard time to 0 USART bits */ - XPROGTarget_SendByte(TPI_CMD_SSTCS | TPI_CTRL_REG); - XPROGTarget_SendByte(0x07); - - /* Enable access to the XPROG NVM bus by sending the documented NVM access key to the device */ - XPROGTarget_SendByte(TPI_CMD_SKEY); - for (uint8_t i = sizeof(TPI_NVMENABLE_KEY); i > 0; i--) - XPROGTarget_SendByte(TPI_NVMENABLE_KEY[i - 1]); - - /* Wait until the NVM bus becomes active */ - NVMBusEnabled = TINYNVM_WaitWhileNVMBusBusy(); - } + NVMBusEnabled = TINYNVM_EnableTPI(); Endpoint_Write_Byte(CMD_XPROG); Endpoint_Write_Byte(XPRG_CMD_ENTER_PROGMODE); @@ -172,29 +138,9 @@ static void XPROGProtocol_LeaveXPROGMode(void) Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN); if (XPROG_SelectedProtocol == XPRG_PROTOCOL_PDI) - { - 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 affect (silicon bug?) */ - XPROGTarget_SendByte(PDI_CMD_STCS | PDI_RESET_REG); - XPROGTarget_SendByte(0x00); - - XPROGTarget_DisableTargetPDI(); - } + XMEGANVM_DisablePDI(); else - { - TINYNVM_WaitWhileNVMBusBusy(); - - /* Clear the NVMEN bit in the TPI CONTROL register to disable TPI mode */ - XPROGTarget_SendByte(TPI_CMD_SSTCS | TPI_CTRL_REG); - XPROGTarget_SendByte(0x00); - - XPROGTarget_DisableTargetTPI(); - } + TINYNVM_DisableTPI(); #if defined(XCK_RESCUE_CLOCK_ENABLE) && defined(ENABLE_ISP_PROTOCOL) ISPTarget_ConfigureRescueClock(); diff --git a/Projects/AVRISP-MKII/Lib/XPROG/XPROGProtocol.h b/Projects/AVRISP-MKII/Lib/XPROG/XPROGProtocol.h index e5952a1ac8..c0ab7d082b 100644 --- a/Projects/AVRISP-MKII/Lib/XPROG/XPROGProtocol.h +++ b/Projects/AVRISP-MKII/Lib/XPROG/XPROGProtocol.h @@ -45,7 +45,6 @@ #include #include "../V2Protocol.h" - #include "XPROGTarget.h" #include "XMEGANVM.h" #include "TINYNVM.h" diff --git a/Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c b/Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c index f6fff1cf77..9be78d0620 100644 --- a/Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c +++ b/Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c @@ -39,7 +39,7 @@ #if defined(ENABLE_XPROG_PROTOCOL) || defined(__DOXYGEN__) /** Flag to indicate if the USART is currently in Tx or Rx mode. */ -volatile bool IsSending; +bool IsSending; /** Enables the target's PDI interface, holding the target in reset until PDI mode is exited. */ void XPROGTarget_EnableTargetPDI(void) @@ -115,7 +115,7 @@ void XPROGTarget_DisableTargetTPI(void) UCSR1B = 0; UCSR1C = 0; - /* Set all USART lines as input, tristate */ + /* Set all USART lines as inputs, tristate */ DDRD &= ~((1 << 5) | (1 << 3)); PORTD &= ~((1 << 5) | (1 << 3) | (1 << 2));