X-Git-Url: http://git.linex4red.de/pub/USBasp.git/blobdiff_plain/a447ae134f416ab45dcfe3dfe5dd1222bb908be2..a9abe1fdea5ccf67aaccab6fdde300d6fcf2d15a:/Projects/AVRISP-MKII/Lib/XPROG/XPROGProtocol.c diff --git a/Projects/AVRISP-MKII/Lib/XPROG/XPROGProtocol.c b/Projects/AVRISP-MKII/Lib/XPROG/XPROGProtocol.c index 85820fd31..2e3d11fbb 100644 --- a/Projects/AVRISP-MKII/Lib/XPROG/XPROGProtocol.c +++ b/Projects/AVRISP-MKII/Lib/XPROG/XPROGProtocol.c @@ -1,21 +1,21 @@ /* LUFA Library - Copyright (C) Dean Camera, 2010. - + Copyright (C) Dean Camera, 2012. + dean [at] fourwalledcubicle [dot] com - www.fourwalledcubicle.com + www.lufa-lib.org */ /* - Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com) + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) - Permission to use, copy, modify, distribute, and sell this + Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted - without fee, provided that the above copyright notice appear in + without fee, provided that the above copyright notice appear in all copies and that both that the copyright notice and this - permission notice and warranty disclaimer appear in supporting - documentation, and that the name of the author not be used in - advertising or publicity pertaining to distribution of the + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the software without specific, written prior permission. The author disclaim all warranties with regard to this @@ -61,18 +61,18 @@ void XPROGProtocol_SetMode(void) { uint8_t Protocol; } SetMode_XPROG_Params; - - Endpoint_Read_Stream_LE(&SetMode_XPROG_Params, sizeof(SetMode_XPROG_Params), NO_STREAM_CALLBACK); + + Endpoint_Read_Stream_LE(&SetMode_XPROG_Params, sizeof(SetMode_XPROG_Params), NULL); Endpoint_ClearOUT(); Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPNUM); Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN); - + XPROG_SelectedProtocol = SetMode_XPROG_Params.Protocol; - - Endpoint_Write_Byte(CMD_XPROG_SETMODE); - Endpoint_Write_Byte((SetMode_XPROG_Params.Protocol != XPRG_PROTOCOL_JTAG) ? STATUS_CMD_OK : STATUS_CMD_FAILED); - Endpoint_ClearIN(); + + Endpoint_Write_8(CMD_XPROG_SETMODE); + Endpoint_Write_8((SetMode_XPROG_Params.Protocol != XPRG_PROTOCOL_JTAG) ? STATUS_CMD_OK : STATUS_CMD_FAILED); + Endpoint_ClearIN(); } /** Handler for the CMD_XPROG command, which wraps up XPROG commands in a V2 wrapper which need to be @@ -80,8 +80,8 @@ void XPROGProtocol_SetMode(void) */ void XPROGProtocol_Command(void) { - uint8_t XPROGCommand = Endpoint_Read_Byte(); - + uint8_t XPROGCommand = Endpoint_Read_8(); + switch (XPROGCommand) { case XPRG_CMD_ENTER_PROGMODE: @@ -114,51 +114,17 @@ static void XPROGProtocol_EnterXPROGMode(void) Endpoint_ClearOUT(); Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPNUM); Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN); - + 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(); - } - - Endpoint_Write_Byte(CMD_XPROG); - Endpoint_Write_Byte(XPRG_CMD_ENTER_PROGMODE); - Endpoint_Write_Byte(NVMBusEnabled ? XPRG_ERR_OK : XPRG_ERR_FAILED); + NVMBusEnabled = TINYNVM_EnableTPI(); + + Endpoint_Write_8(CMD_XPROG); + Endpoint_Write_8(XPRG_CMD_ENTER_PROGMODE); + Endpoint_Write_8(NVMBusEnabled ? XPRG_ERR_OK : XPRG_ERR_FAILED); Endpoint_ClearIN(); } @@ -170,35 +136,21 @@ static void XPROGProtocol_LeaveXPROGMode(void) Endpoint_ClearOUT(); Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPNUM); 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(); - } + if (XPROG_SelectedProtocol == XPRG_PROTOCOL_PDI) + XMEGANVM_DisablePDI(); else - { - TINYNVM_WaitWhileNVMBusBusy(); + TINYNVM_DisableTPI(); - /* 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(); - } - - Endpoint_Write_Byte(CMD_XPROG); - Endpoint_Write_Byte(XPRG_CMD_LEAVE_PROGMODE); - Endpoint_Write_Byte(XPRG_ERR_OK); + #if defined(XCK_RESCUE_CLOCK_ENABLE) && defined(ENABLE_ISP_PROTOCOL) + /* If the XCK rescue clock option is enabled, we need to restart it once the + * XPROG mode has been exited, since the XPROG protocol stops it after use. */ + ISPTarget_ConfigureRescueClock(); + #endif + + Endpoint_Write_8(CMD_XPROG); + Endpoint_Write_8(XPRG_CMD_LEAVE_PROGMODE); + Endpoint_Write_8(XPRG_ERR_OK); Endpoint_ClearIN(); } @@ -213,17 +165,17 @@ static void XPROGProtocol_Erase(void) uint32_t Address; } Erase_XPROG_Params; - Endpoint_Read_Stream_LE(&Erase_XPROG_Params, sizeof(Erase_XPROG_Params), NO_STREAM_CALLBACK); + Endpoint_Read_Stream_LE(&Erase_XPROG_Params, sizeof(Erase_XPROG_Params), NULL); Erase_XPROG_Params.Address = SwapEndian_32(Erase_XPROG_Params.Address); Endpoint_ClearOUT(); Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPNUM); Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN); - + uint8_t EraseCommand; if (XPROG_SelectedProtocol == XPRG_PROTOCOL_PDI) - { + { /* Determine which NVM command to send to the device depending on the memory to erase */ switch (Erase_XPROG_Params.MemoryType) { @@ -255,7 +207,7 @@ static void XPROGProtocol_Erase(void) EraseCommand = XMEGA_NVM_CMD_NOOP; break; } - + /* Erase the target memory, indicate timeout if occurred */ if (!(XMEGANVM_EraseMemory(EraseCommand, Erase_XPROG_Params.Address))) ReturnStatus = XPRG_ERR_TIMEOUT; @@ -266,16 +218,16 @@ static void XPROGProtocol_Erase(void) EraseCommand = TINY_NVM_CMD_CHIPERASE; else EraseCommand = TINY_NVM_CMD_SECTIONERASE; - + /* Erase the target memory, indicate timeout if occurred */ if (!(TINYNVM_EraseMemory(EraseCommand, Erase_XPROG_Params.Address))) ReturnStatus = XPRG_ERR_TIMEOUT; } - - Endpoint_Write_Byte(CMD_XPROG); - Endpoint_Write_Byte(XPRG_CMD_ERASE); - Endpoint_Write_Byte(ReturnStatus); - Endpoint_ClearIN(); + + Endpoint_Write_8(CMD_XPROG); + Endpoint_Write_8(XPRG_CMD_ERASE); + Endpoint_Write_8(ReturnStatus); + Endpoint_ClearIN(); } /** Handler for the XPROG WRITE_MEMORY command to write to a specific memory space within the attached device. */ @@ -291,12 +243,21 @@ static void XPROGProtocol_WriteMemory(void) uint16_t Length; uint8_t ProgData[256]; } WriteMemory_XPROG_Params; - + Endpoint_Read_Stream_LE(&WriteMemory_XPROG_Params, (sizeof(WriteMemory_XPROG_Params) - - sizeof(WriteMemory_XPROG_Params).ProgData), NO_STREAM_CALLBACK); + sizeof(WriteMemory_XPROG_Params).ProgData), NULL); WriteMemory_XPROG_Params.Address = SwapEndian_32(WriteMemory_XPROG_Params.Address); WriteMemory_XPROG_Params.Length = SwapEndian_16(WriteMemory_XPROG_Params.Length); - Endpoint_Read_Stream_LE(&WriteMemory_XPROG_Params.ProgData, WriteMemory_XPROG_Params.Length, NO_STREAM_CALLBACK); + Endpoint_Read_Stream_LE(&WriteMemory_XPROG_Params.ProgData, WriteMemory_XPROG_Params.Length, NULL); + + // The driver will terminate transfers that are a round multiple of the endpoint bank in size with a ZLP, need + // to catch this and discard it before continuing on with packet processing to prevent communication issues + if (((sizeof(uint8_t) + sizeof(WriteMemory_XPROG_Params) - sizeof(WriteMemory_XPROG_Params.ProgData)) + + WriteMemory_XPROG_Params.Length) % AVRISP_DATA_EPSIZE == 0) + { + Endpoint_ClearOUT(); + Endpoint_WaitUntilReady(); + } Endpoint_ClearOUT(); Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPNUM); @@ -309,7 +270,7 @@ static void XPROGProtocol_WriteMemory(void) uint8_t WriteBuffCommand = XMEGA_NVM_CMD_LOADFLASHPAGEBUFF; uint8_t EraseBuffCommand = XMEGA_NVM_CMD_ERASEFLASHPAGEBUFF; bool PagedMemory = true; - + switch (WriteMemory_XPROG_Params.MemoryType) { case XPRG_MEM_TYPE_APPL: @@ -321,7 +282,7 @@ static void XPROGProtocol_WriteMemory(void) case XPRG_MEM_TYPE_EEPROM: WriteCommand = XMEGA_NVM_CMD_ERASEWRITEEEPROMPAGE; WriteBuffCommand = XMEGA_NVM_CMD_LOADEEPROMPAGEBUFF; - EraseBuffCommand = XMEGA_NVM_CMD_ERASEEEPROMPAGEBUFF; + EraseBuffCommand = XMEGA_NVM_CMD_ERASEEEPROMPAGEBUFF; break; case XPRG_MEM_TYPE_USERSIG: WriteCommand = XMEGA_NVM_CMD_WRITEUSERSIG; @@ -335,9 +296,9 @@ static void XPROGProtocol_WriteMemory(void) PagedMemory = false; break; } - + /* Send the appropriate memory write commands to the device, indicate timeout if occurred */ - if ((PagedMemory && !(XMEGANVM_WritePageMemory(WriteBuffCommand, EraseBuffCommand, WriteCommand, + if ((PagedMemory && !(XMEGANVM_WritePageMemory(WriteBuffCommand, EraseBuffCommand, WriteCommand, WriteMemory_XPROG_Params.PageMode, WriteMemory_XPROG_Params.Address, WriteMemory_XPROG_Params.ProgData, WriteMemory_XPROG_Params.Length))) || (!PagedMemory && !(XMEGANVM_WriteByteMemory(WriteCommand, WriteMemory_XPROG_Params.Address, @@ -355,10 +316,10 @@ static void XPROGProtocol_WriteMemory(void) ReturnStatus = XPRG_ERR_TIMEOUT; } } - - Endpoint_Write_Byte(CMD_XPROG); - Endpoint_Write_Byte(XPRG_CMD_WRITE_MEM); - Endpoint_Write_Byte(ReturnStatus); + + Endpoint_Write_8(CMD_XPROG); + Endpoint_Write_8(XPRG_CMD_WRITE_MEM); + Endpoint_Write_8(ReturnStatus); Endpoint_ClearIN(); } @@ -375,8 +336,8 @@ static void XPROGProtocol_ReadMemory(void) uint32_t Address; uint16_t Length; } ReadMemory_XPROG_Params; - - Endpoint_Read_Stream_LE(&ReadMemory_XPROG_Params, sizeof(ReadMemory_XPROG_Params), NO_STREAM_CALLBACK); + + Endpoint_Read_Stream_LE(&ReadMemory_XPROG_Params, sizeof(ReadMemory_XPROG_Params), NULL); ReadMemory_XPROG_Params.Address = SwapEndian_32(ReadMemory_XPROG_Params.Address); ReadMemory_XPROG_Params.Length = SwapEndian_16(ReadMemory_XPROG_Params.Length); @@ -385,7 +346,7 @@ static void XPROGProtocol_ReadMemory(void) Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN); uint8_t ReadBuffer[256]; - + if (XPROG_SelectedProtocol == XPRG_PROTOCOL_PDI) { /* Read the PDI target's memory, indicate timeout if occurred */ @@ -399,13 +360,13 @@ static void XPROGProtocol_ReadMemory(void) ReturnStatus = XPRG_ERR_TIMEOUT; } - Endpoint_Write_Byte(CMD_XPROG); - Endpoint_Write_Byte(XPRG_CMD_READ_MEM); - Endpoint_Write_Byte(ReturnStatus); - + Endpoint_Write_8(CMD_XPROG); + Endpoint_Write_8(XPRG_CMD_READ_MEM); + Endpoint_Write_8(ReturnStatus); + if (ReturnStatus == XPRG_ERR_OK) - Endpoint_Write_Stream_LE(ReadBuffer, ReadMemory_XPROG_Params.Length, NO_STREAM_CALLBACK); - + Endpoint_Write_Stream_LE(ReadBuffer, ReadMemory_XPROG_Params.Length, NULL); + Endpoint_ClearIN(); } @@ -415,18 +376,18 @@ static void XPROGProtocol_ReadMemory(void) static void XPROGProtocol_ReadCRC(void) { uint8_t ReturnStatus = XPRG_ERR_OK; - + struct { uint8_t CRCType; } ReadCRC_XPROG_Params; - - Endpoint_Read_Stream_LE(&ReadCRC_XPROG_Params, sizeof(ReadCRC_XPROG_Params), NO_STREAM_CALLBACK); + + Endpoint_Read_Stream_LE(&ReadCRC_XPROG_Params, sizeof(ReadCRC_XPROG_Params), NULL); Endpoint_ClearOUT(); Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPNUM); Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN); - + uint32_t MemoryCRC; if (XPROG_SelectedProtocol == XPRG_PROTOCOL_PDI) @@ -446,7 +407,7 @@ static void XPROGProtocol_ReadCRC(void) CRCCommand = XMEGA_NVM_CMD_FLASHCRC; break; } - + /* Perform and retrieve the memory CRC, indicate timeout if occurred */ if (!(XMEGANVM_GetMemoryCRC(CRCCommand, &MemoryCRC))) ReturnStatus = XPRG_ERR_TIMEOUT; @@ -456,18 +417,18 @@ static void XPROGProtocol_ReadCRC(void) /* TPI does not support memory CRC */ ReturnStatus = XPRG_ERR_FAILED; } - - Endpoint_Write_Byte(CMD_XPROG); - Endpoint_Write_Byte(XPRG_CMD_CRC); - Endpoint_Write_Byte(ReturnStatus); - + + Endpoint_Write_8(CMD_XPROG); + Endpoint_Write_8(XPRG_CMD_CRC); + Endpoint_Write_8(ReturnStatus); + if (ReturnStatus == XPRG_ERR_OK) { - Endpoint_Write_Byte(MemoryCRC >> 16); - Endpoint_Write_Word_LE(MemoryCRC & 0xFFFF); + Endpoint_Write_8(MemoryCRC >> 16); + Endpoint_Write_16_LE(MemoryCRC & 0xFFFF); } - - Endpoint_ClearIN(); + + Endpoint_ClearIN(); } /** Handler for the XPROG SET_PARAM command to set a XPROG parameter for use when communicating with the @@ -477,22 +438,22 @@ static void XPROGProtocol_SetParam(void) { uint8_t ReturnStatus = XPRG_ERR_OK; - uint8_t XPROGParam = Endpoint_Read_Byte(); - + uint8_t XPROGParam = Endpoint_Read_8(); + /* Determine which parameter is being set, store the new parameter value */ switch (XPROGParam) { case XPRG_PARAM_NVMBASE: - XPROG_Param_NVMBase = Endpoint_Read_DWord_BE(); + XPROG_Param_NVMBase = Endpoint_Read_32_BE(); break; case XPRG_PARAM_EEPPAGESIZE: - XPROG_Param_EEPageSize = Endpoint_Read_Word_BE(); + XPROG_Param_EEPageSize = Endpoint_Read_16_BE(); break; case XPRG_PARAM_NVMCMD_REG: - XPROG_Param_NVMCMDRegAddr = Endpoint_Read_Byte(); + XPROG_Param_NVMCMDRegAddr = Endpoint_Read_8(); break; case XPRG_PARAM_NVMCSR_REG: - XPROG_Param_NVMCSRRegAddr = Endpoint_Read_Byte(); + XPROG_Param_NVMCSRRegAddr = Endpoint_Read_8(); break; default: ReturnStatus = XPRG_ERR_FAILED; @@ -502,11 +463,12 @@ static void XPROGProtocol_SetParam(void) Endpoint_ClearOUT(); Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPNUM); Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN); - - Endpoint_Write_Byte(CMD_XPROG); - Endpoint_Write_Byte(XPRG_CMD_SET_PARAM); - Endpoint_Write_Byte(ReturnStatus); + + Endpoint_Write_8(CMD_XPROG); + Endpoint_Write_8(XPRG_CMD_SET_PARAM); + Endpoint_Write_8(ReturnStatus); Endpoint_ClearIN(); } #endif +