From 1f8dfd0205d431351425f468627984280b21cd5a Mon Sep 17 00:00:00 2001 From: Dean Camera Date: Wed, 2 Dec 2009 13:42:08 +0000 Subject: Add support for unwrapping of the XMEGA PDI programming protocol to the AVRISP Programmer project. --- Projects/AVRISP/AVRISP.c | 1 + Projects/AVRISP/AVRISP.h | 1 + Projects/AVRISP/AVRISP.txt | 14 +- Projects/AVRISP/Lib/ISPProtocol.c | 5 +- Projects/AVRISP/Lib/PDIProtocol.c | 262 ++++++++++++++++++++++++++++++ Projects/AVRISP/Lib/PDIProtocol.h | 100 ++++++++++++ Projects/AVRISP/Lib/V2Protocol.c | 6 +- Projects/AVRISP/Lib/V2Protocol.h | 1 + Projects/AVRISP/Lib/V2ProtocolConstants.h | 41 ----- Projects/AVRISP/makefile | 3 + 10 files changed, 389 insertions(+), 45 deletions(-) create mode 100644 Projects/AVRISP/Lib/PDIProtocol.c create mode 100644 Projects/AVRISP/Lib/PDIProtocol.h (limited to 'Projects/AVRISP') diff --git a/Projects/AVRISP/AVRISP.c b/Projects/AVRISP/AVRISP.c index c0572fca2..02292aa46 100644 --- a/Projects/AVRISP/AVRISP.c +++ b/Projects/AVRISP/AVRISP.c @@ -70,6 +70,7 @@ void SetupHardware(void) /* Hardware Initialization */ LEDs_Init(); USB_Init(); + SerialStream_Init(9600, true); #if defined(ADC) /* Initialize the ADC converter for VTARGET level detection on supported AVR models */ diff --git a/Projects/AVRISP/AVRISP.h b/Projects/AVRISP/AVRISP.h index a0f4d5e79..bf9763afb 100644 --- a/Projects/AVRISP/AVRISP.h +++ b/Projects/AVRISP/AVRISP.h @@ -47,6 +47,7 @@ #include #include #include + #include #if defined(ADC) #include diff --git a/Projects/AVRISP/AVRISP.txt b/Projects/AVRISP/AVRISP.txt index fcb0fdd3d..0ccf72ace 100644 --- a/Projects/AVRISP/AVRISP.txt +++ b/Projects/AVRISP/AVRISP.txt @@ -56,13 +56,12 @@ * Note that this design currently has several limitations: * - Minimum target clock speed of 500KHz due to hardware SPI used * - No reversed/shorted target connector detection and notification - * - PDI programming is not supported for XMEGA targets * * On AVR models with an ADC converter, ACC should be tied to 5V (e.g. VBUS) and the VTARGET_ADC_CHANNEL token should be * set to an appropriate ADC channel number in the project makefile for VTARGET detection to operate correctly. On models * without an ADC converter, VTARGET will report at a fixed 5V level. * - * Connections to the device are simple: + * Connections to the device are simple for SPI programming: * * * @@ -105,6 +104,12 @@ * 1Optional, see \ref SSec_Options section - for USB AVRs with ADC modules only \n * 2See \ref SSec_Options section * + * + * Connections to the device are simple for SPI programming: + * + *
+ * + *
PDI Programming is not yet fully implemented.
* \section SSec_Options Project Options * * The following defines can be found in this demo, which can control the demo behaviour when defined, or changed in value. @@ -137,5 +142,10 @@ * Makefile CDEFS * ADC channel number (on supported AVRs) to use for VTARGET level detection. * + * + * ENABLE_XPROG_PROTOCOL + * Makefile CDEFS + * Define to enable XMEGA PDI programming protocol support. + * * */ diff --git a/Projects/AVRISP/Lib/ISPProtocol.c b/Projects/AVRISP/Lib/ISPProtocol.c index bfd917a09..8bfa4d4d7 100644 --- a/Projects/AVRISP/Lib/ISPProtocol.c +++ b/Projects/AVRISP/Lib/ISPProtocol.c @@ -136,7 +136,10 @@ void ISPProtocol_ProgramMemory(uint8_t V2Command) uint8_t ProgData[256]; // Note, the Jungo driver has a very short ACK timeout period, need to buffer the } Write_Memory_Params; // whole page and ACK the packet as fast as possible to prevent it from aborting - Endpoint_Read_Stream_LE(&Write_Memory_Params, sizeof(Write_Memory_Params) - sizeof(Write_Memory_Params.ProgData)); + Endpoint_Read_Stream_LE(&Write_Memory_Params, (sizeof(Write_Memory_Params) - + sizeof(Write_Memory_Params.ProgData))); + + Write_Memory_Params.BytesToWrite = SwapEndian_16(Write_Memory_Params.BytesToWrite); if (Write_Memory_Params.BytesToWrite > sizeof(Write_Memory_Params.ProgData)) diff --git a/Projects/AVRISP/Lib/PDIProtocol.c b/Projects/AVRISP/Lib/PDIProtocol.c new file mode 100644 index 000000000..b095a49c5 --- /dev/null +++ b/Projects/AVRISP/Lib/PDIProtocol.c @@ -0,0 +1,262 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2009. + + dean [at] fourwalledcubicle [dot] com + www.fourwalledcubicle.com +*/ + +/* + Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, and distribute this software + and its documentation for any purpose and without fee is hereby + granted, 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 + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +#if defined(ENABLE_XPROG_PROTOCOL) + +/** \file + * + * PDI Protocol handler, to process V2 Protocol wrapped PDI commands used in Atmel programmer devices. + */ + +#define INCLUDE_FROM_XPROG_C +#include "PDIProtocol.h" + +uint32_t XPROG_Param_NVMBase; +uint32_t XPROG_Param_EEPageSize; + +/** Handler for the CMD_XPROG_SETMODE command, which sets the programmer-to-target protocol used for PDI + * XMEGA programming (either PDI or JTAG). Only PDI programming is supported. + */ +void PDIProtocol_XPROG_SetMode(void) +{ + struct + { + uint8_t Protocol; + } SetMode_XPROG_Params; + + Endpoint_Read_Stream_LE(&SetMode_XPROG_Params, sizeof(SetMode_XPROG_Params)); + + Endpoint_ClearOUT(); + Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN); + + Endpoint_Write_Byte(CMD_XPROG_SETMODE); + Endpoint_Write_Byte(SetMode_XPROG_Params.Protocol ? STATUS_CMD_FAILED : STATUS_CMD_OK); + Endpoint_ClearIN(); +} + +void PDIProtocol_XPROG_Command(void) +{ + uint8_t XPROGCommand = Endpoint_Read_Byte(); + + switch (XPROGCommand) + { + case XPRG_CMD_ENTER_PROGMODE: + PDIProtocol_EnterXPROGMode(); + break; + case XPRG_CMD_LEAVE_PROGMODE: + PDIProtocol_LeaveXPROGMode(); + break; + case XPRG_CMD_ERASE: + PDIProtocol_EraseChip(); + break; + case XPRG_CMD_WRITE_MEM: + PDIProtocol_WriteMemory(); + break; + case XPRG_CMD_READ_MEM: + PDIProtocol_ReadMemory(); + break; + case XPRG_CMD_CRC: + PDIProtocol_ReadCRC(); + break; + case XPRG_CMD_SET_PARAM: + PDIProtocol_SetParam(); + break; + } +} + +static void PDIProtocol_EraseChip(void) +{ + uint8_t ReturnStatus = XPRG_ERR_OK; + + struct + { + uint8_t MemoryType; + uint32_t Address; + } Erase_XPROG_Params; + + Endpoint_Read_Stream_LE(&Erase_XPROG_Params, sizeof(Erase_XPROG_Params)); + + Endpoint_ClearOUT(); + Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN); + + // TODO: Send erase command here via PDI protocol + + Endpoint_Write_Byte(CMD_XPROG); + Endpoint_Write_Byte(XPRG_CMD_ERASE); + Endpoint_Write_Byte(ReturnStatus); + Endpoint_ClearIN(); +} + +static void PDIProtocol_WriteMemory(void) +{ + uint8_t ReturnStatus = XPRG_ERR_OK; + + struct + { + uint8_t MemoryType; + uint32_t Address; + 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)); + 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); + + Endpoint_ClearOUT(); + Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN); + + // TODO: Send program command here via PDI protocol + + Endpoint_Write_Byte(CMD_XPROG); + Endpoint_Write_Byte(XPRG_CMD_READ_MEM); + Endpoint_Write_Byte(ReturnStatus); + Endpoint_ClearIN(); +} + +static void PDIProtocol_ReadMemory(void) +{ + uint8_t ReturnStatus = XPRG_ERR_OK; + + struct + { + uint8_t MemoryType; + uint32_t Address; + uint16_t Length; + } ReadMemory_XPROG_Params; + + Endpoint_Read_Stream_LE(&ReadMemory_XPROG_Params, sizeof(ReadMemory_XPROG_Params)); + ReadMemory_XPROG_Params.Address = SwapEndian_32(ReadMemory_XPROG_Params.Address); + ReadMemory_XPROG_Params.Length = SwapEndian_16(ReadMemory_XPROG_Params.Length); + + Endpoint_ClearOUT(); + Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN); + + // TODO: Send read command here via PDI protocol + + Endpoint_Write_Byte(CMD_XPROG); + Endpoint_Write_Byte(XPRG_CMD_READ_MEM); + Endpoint_Write_Byte(ReturnStatus); + + // START TEMP + uint8_t ProgData[256]; + for (uint16_t i = 0; i < ReadMemory_XPROG_Params.Length; i++) + ProgData[i] = i; + Endpoint_Write_Stream_LE(ProgData, ReadMemory_XPROG_Params.Length); + + if (!Endpoint_IsReadWriteAllowed()) + { + Endpoint_ClearIN(); + while(!(Endpoint_IsReadWriteAllowed())); + } + // END TEMP + + Endpoint_ClearIN(); +} + +static void PDIProtocol_ReadCRC(void) +{ + uint8_t ReturnStatus = XPRG_ERR_OK; + + uint8_t CRCType = Endpoint_Read_Byte(); + + Endpoint_ClearOUT(); + Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN); + + uint32_t MemoryCRC = 0; + + // TODO: Read device CRC for desired memory via PDI protocol + + Endpoint_Write_Byte(CMD_XPROG); + Endpoint_Write_Byte(XPRG_CMD_CRC); + Endpoint_Write_Byte(ReturnStatus); + + if (ReturnStatus == XPRG_ERR_OK) + { + Endpoint_Write_Byte(MemoryCRC >> 16); + Endpoint_Write_Word_LE(MemoryCRC & 0xFFFF); + } + + Endpoint_ClearIN(); +} + +static void PDIProtocol_EnterXPROGMode(void) +{ + uint8_t ReturnStatus = XPRG_ERR_OK; + + Endpoint_ClearOUT(); + Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN); + + // TODO: Enter device programming mode here via PDI protocol + + Endpoint_Write_Byte(CMD_XPROG); + Endpoint_Write_Byte(XPRG_CMD_ENTER_PROGMODE); + Endpoint_Write_Byte(ReturnStatus); + Endpoint_ClearIN(); +} + +static void PDIProtocol_LeaveXPROGMode(void) +{ + Endpoint_ClearOUT(); + Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN); + + // TODO: Exit device programming mode here via PDI protocol + + Endpoint_Write_Byte(CMD_XPROG); + Endpoint_Write_Byte(XPRG_CMD_LEAVE_PROGMODE); + Endpoint_Write_Byte(XPRG_ERR_OK); + Endpoint_ClearIN(); +} + +static void PDIProtocol_SetParam(void) +{ + uint8_t ReturnStatus = XPRG_ERR_OK; + + uint8_t XPROGParam = Endpoint_Read_Byte(); + + if (XPROGParam == XPRG_PARAM_NVMBASE) + XPROG_Param_NVMBase = Endpoint_Read_DWord_LE(); + else if (XPROGParam == XPRG_PARAM_EEPPAGESIZE) + XPROG_Param_EEPageSize = Endpoint_Read_Word_LE(); + else + ReturnStatus = XPRG_ERR_FAILED; + + Endpoint_ClearOUT(); + Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN); + + Endpoint_Write_Byte(CMD_XPROG); + Endpoint_Write_Byte(XPRG_CMD_SET_PARAM); + Endpoint_Write_Byte(ReturnStatus); + Endpoint_ClearIN(); +} + +#endif diff --git a/Projects/AVRISP/Lib/PDIProtocol.h b/Projects/AVRISP/Lib/PDIProtocol.h new file mode 100644 index 000000000..2710b2ff5 --- /dev/null +++ b/Projects/AVRISP/Lib/PDIProtocol.h @@ -0,0 +1,100 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2009. + + dean [at] fourwalledcubicle [dot] com + www.fourwalledcubicle.com +*/ + +/* + Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, and distribute this software + and its documentation for any purpose and without fee is hereby + granted, 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 + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * + * Header file for PDIProtocol.c. + */ + +#ifndef _PDI_PROTOCOL_ +#define _PDI_PROTOCOL_ + + /* Includes: */ + #include + #include + + #include "V2Protocol.h" + + /* Macros: */ + #define XPRG_CMD_ENTER_PROGMODE 0x01 + #define XPRG_CMD_LEAVE_PROGMODE 0x02 + #define XPRG_CMD_ERASE 0x03 + #define XPRG_CMD_WRITE_MEM 0x04 + #define XPRG_CMD_READ_MEM 0x05 + #define XPRG_CMD_CRC 0x06 + #define XPRG_CMD_SET_PARAM 0x07 + + #define XPRG_MEM_TYPE_APPL 1 + #define XPRG_MEM_TYPE_BOOT 2 + #define XPRG_MEM_TYPE_EEPROM 3 + #define XPRG_MEM_TYPE_FUSE 4 + #define XPRG_MEM_TYPE_LOCKBITS 5 + #define XPRG_MEM_TYPE_USERSIG 6 + #define XPRG_MEM_TYPE_FACTORY_CALIBRATION 7 + + #define XPRG_ERASE_CHIP 1 + #define XPRG_ERASE_APP 2 + #define XPRG_ERASE_BOOT 3 + #define XPRG_ERASE_EEPROM 4 + #define XPRG_ERASE_APP_PAGE 5 + #define XPRG_ERASE_BOOT_PAGE 6 + #define XPRG_ERASE_EEPROM_PAGE 7 + #define XPRG_ERASE_USERSIG 8 + + #define XPRG_MEM_WRITE_ERASE 0 + #define XPRG_MEM_WRITE_WRITE 1 + + #define XPRG_CRC_APP 1 + #define XPRG_CRC_BOOT 2 + #define XPRG_CRC_FLASH 3 + + #define XPRG_ERR_OK 0 + #define XPRG_ERR_FAILED 1 + #define XPRG_ERR_COLLISION 2 + #define XPRG_ERR_TIMEOUT 3 + + #define XPRG_PARAM_NVMBASE 0x01 + #define XPRG_PARAM_EEPPAGESIZE 0x02 + + /* Function Prototypes: */ + void PDIProtocol_XPROG_SetMode(void); + void PDIProtocol_XPROG_Command(void); + + #if defined(INCLUDE_FROM_XPROG_C) + static void PDIProtocol_EnterXPROGMode(void); + static void PDIProtocol_LeaveXPROGMode(void); + static void PDIProtocol_SetParam(void); + static void PDIProtocol_EraseChip(void); + static void PDIProtocol_WriteMemory(void); + static void PDIProtocol_ReadMemory(void); + static void PDIProtocol_ReadCRC(void); + #endif + +#endif diff --git a/Projects/AVRISP/Lib/V2Protocol.c b/Projects/AVRISP/Lib/V2Protocol.c index c0028f72a..d2e0b1686 100644 --- a/Projects/AVRISP/Lib/V2Protocol.c +++ b/Projects/AVRISP/Lib/V2Protocol.c @@ -85,7 +85,11 @@ void V2Protocol_ProcessCommand(void) break; #if defined(ENABLE_XPROG_PROTOCOL) case CMD_XPROG_SETMODE: - V2Protocol_XPROG_SetMode(); + PDIProtocol_XPROG_SetMode(); + break; + case CMD_XPROG: + PDIProtocol_XPROG_Command(); + break; #endif case CMD_READ_FUSE_ISP: case CMD_READ_LOCK_ISP: diff --git a/Projects/AVRISP/Lib/V2Protocol.h b/Projects/AVRISP/Lib/V2Protocol.h index b31147846..7a181e32b 100644 --- a/Projects/AVRISP/Lib/V2Protocol.h +++ b/Projects/AVRISP/Lib/V2Protocol.h @@ -44,6 +44,7 @@ #include "V2ProtocolConstants.h" #include "V2ProtocolParams.h" #include "ISPProtocol.h" + #include "PDIProtocol.h" /* Macros: */ /** Programmer ID string, returned to the host during the CMD_SIGN_ON command processing */ diff --git a/Projects/AVRISP/Lib/V2ProtocolConstants.h b/Projects/AVRISP/Lib/V2ProtocolConstants.h index 5e6bd3638..d01b42b46 100644 --- a/Projects/AVRISP/Lib/V2ProtocolConstants.h +++ b/Projects/AVRISP/Lib/V2ProtocolConstants.h @@ -58,50 +58,9 @@ #define CMD_READ_SIGNATURE_ISP 0x1B #define CMD_READ_OSCCAL_ISP 0x1C #define CMD_SPI_MULTI 0x1D - #define CMD_XPROG 0x50 #define CMD_XPROG_SETMODE 0x51 - #define XPRG_CMD_ENTER_PROGMODE 0x01 - #define XPRG_CMD_LEAVE_PROGMODE 0x02 - #define XPRG_CMD_ERASE 0x03 - #define XPRG_CMD_WRITE_MEM 0x04 - #define XPRG_CMD_READ_MEM 0x05 - #define XPRG_CMD_CRC 0x06 - #define XPRG_CMD_SET_PARAM 0x07 - - #define XPRG_MEM_TYPE_APPL 1 - #define XPRG_MEM_TYPE_BOOT 2 - #define XPRG_MEM_TYPE_EEPROM 3 - #define XPRG_MEM_TYPE_FUSE 4 - #define XPRG_MEM_TYPE_LOCKBITS 5 - #define XPRG_MEM_TYPE_USERSIG 6 - #define XPRG_MEM_TYPE_FACTORY_CALIBRATION 7 - - #define XPRG_ERASE_CHIP 1 - #define XPRG_ERASE_APP 2 - #define XPRG_ERASE_BOOT 3 - #define XPRG_ERASE_EEPROM 4 - #define XPRG_ERASE_APP_PAGE 5 - #define XPRG_ERASE_BOOT_PAGE 6 - #define XPRG_ERASE_EEPROM_PAGE 7 - #define XPRG_ERASE_USERSIG 8 - - #define XPRG_MEM_WRITE_ERASE 0 - #define XPRG_MEM_WRITE_WRITE 1 - - #define XPRG_CRC_APP 1 - #define XPRG_CRC_BOOT 2 - #define XPRG_CRC_FLASH 3 - - #define XPRG_ERR_OK 0 - #define XPRG_ERR_FAILED 1 - #define XPRG_ERR_COLLISION 2 - #define XPRG_ERR_TIMEOUT 3 - - #define XPRG_PARAM_NVMBASE 0x01 - #define XPRG_PARAM_EEPPAGESIZE 0x02 - #define STATUS_CMD_OK 0x00 #define STATUS_CMD_TOUT 0x80 #define STATUS_RDY_BSY_TOUT 0x81 diff --git a/Projects/AVRISP/makefile b/Projects/AVRISP/makefile index 1aab6a3c5..91e6b0899 100644 --- a/Projects/AVRISP/makefile +++ b/Projects/AVRISP/makefile @@ -131,6 +131,8 @@ SRC = $(TARGET).c \ Lib/V2ProtocolParams.c \ Lib/ISPProtocol.c \ Lib/ISPTarget.c \ + Lib/PDIProtocol.c \ + $(LUFA_PATH)/LUFA/Drivers/Peripheral/SerialStream.c \ $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/DevChapter9.c \ $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/Endpoint.c \ $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/Host.c \ @@ -191,6 +193,7 @@ CDEFS += -DRESET_LINE_PORT=PORTB CDEFS += -DRESET_LINE_DDR=DDRB CDEFS += -DRESET_LINE_MASK="(1 << 4)" CDEFS += -DVTARGET_ADC_CHANNEL=2 +CDEFS += -DENABLE_XPROG_PROTOCOL # Place -D or -U options here for ASM sources -- cgit v1.2.3