diff --git a/LUFA/ManPages/ChangeLog.txt b/LUFA/ManPages/ChangeLog.txt index bd3b38f472..bbded93f35 100644 --- a/LUFA/ManPages/ChangeLog.txt +++ b/LUFA/ManPages/ChangeLog.txt @@ -16,6 +16,7 @@ * - Added new RNDIS Ethernet Host Class Driver * - Added new RNDIS Ethernet Host ClassDriver demo * - Added CDC_Host_Flush() function to the CDC Host Class driver to flush sent data to the attached device + * - Added PDI programming support for XMEGA devices to the AVRISP programmer project * * Changed: * - Removed code in the Keyboard demos to send zeroed reports between two reports with differing numbers of keycodes diff --git a/Projects/AVRISP/AVRISP.txt b/Projects/AVRISP/AVRISP.txt index 670c168a7a..c533af7251 100644 --- a/Projects/AVRISP/AVRISP.txt +++ b/Projects/AVRISP/AVRISP.txt @@ -178,6 +178,11 @@ * ADC channel number (on supported AVRs) to use for VTARGET level detection. * * + * ENABLE_SPI_PROTOCOL + * Makefile CDEFS + * Define to enable SPI programming protocol support. + * + * * ENABLE_XPROG_PROTOCOL * Makefile CDEFS * Define to enable XMEGA PDI programming protocol support. diff --git a/Projects/AVRISP/Doxygen.conf b/Projects/AVRISP/Doxygen.conf index eb8a1ab4c2..dcaaecb5e7 100644 --- a/Projects/AVRISP/Doxygen.conf +++ b/Projects/AVRISP/Doxygen.conf @@ -1221,7 +1221,7 @@ INCLUDE_FILE_PATTERNS = # undefined via #undef or recursively expanded use the := operator # instead of the = operator. -PREDEFINED = __DOXYGEN__ +PREDEFINED = __DOXYGEN__ ENABLE_SPI_PROTOCOL ENABLE_PDI_PROTOCOL # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. diff --git a/Projects/AVRISP/Lib/ISPProtocol.c b/Projects/AVRISP/Lib/ISPProtocol.c index c023234c3a..4847c35fcb 100644 --- a/Projects/AVRISP/Lib/ISPProtocol.c +++ b/Projects/AVRISP/Lib/ISPProtocol.c @@ -28,6 +28,8 @@ this software. */ +#if defined(ENABLE_SPI_PROTOCOL) + /** \file * * ISP Protocol handler, to process V2 Protocol wrapped ISP commands used in Atmel programmer devices. @@ -468,3 +470,5 @@ void ISPProtocol_SPIMulti(void) Endpoint_Write_Byte(STATUS_CMD_OK); Endpoint_ClearIN(); } + +#endif \ No newline at end of file diff --git a/Projects/AVRISP/Lib/ISPTarget.c b/Projects/AVRISP/Lib/ISPTarget.c index 87158460bc..aab64a939c 100644 --- a/Projects/AVRISP/Lib/ISPTarget.c +++ b/Projects/AVRISP/Lib/ISPTarget.c @@ -28,6 +28,8 @@ this software. */ +#if defined(ENABLE_SPI_PROTOCOL) + /** \file * * Target-related functions for the ISP Protocol decoder. @@ -178,3 +180,5 @@ void ISPTarget_LoadExtendedAddress(void) SPI_SendByte((CurrentAddress & 0x00FF0000) >> 16); SPI_SendByte(0x00); } + +#endif diff --git a/Projects/AVRISP/Lib/PDIProtocol.c b/Projects/AVRISP/Lib/PDIProtocol.c index c919561435..2ed3ff293e 100644 --- a/Projects/AVRISP/Lib/PDIProtocol.c +++ b/Projects/AVRISP/Lib/PDIProtocol.c @@ -30,6 +30,8 @@ #if defined(ENABLE_XPROG_PROTOCOL) +#warning PDI Programming Protocol support is incomplete and not currently suitable for use. + /** \file * * PDI Protocol handler, to process V2 Protocol wrapped PDI commands used in Atmel programmer devices. @@ -61,6 +63,9 @@ void PDIProtocol_XPROG_SetMode(void) Endpoint_ClearIN(); } +/** Handler for the CMD_XPROG command, which wraps up XPROG commands in a V2 wrapper which need to be + * removed and processed so that the underlying XPROG command can be handled. + */ void PDIProtocol_XPROG_Command(void) { uint8_t XPROGCommand = Endpoint_Read_Byte(); @@ -74,7 +79,7 @@ void PDIProtocol_XPROG_Command(void) PDIProtocol_LeaveXPROGMode(); break; case XPRG_CMD_ERASE: - PDIProtocol_EraseChip(); + PDIProtocol_Erase(); break; case XPRG_CMD_WRITE_MEM: PDIProtocol_WriteMemory(); @@ -91,6 +96,7 @@ void PDIProtocol_XPROG_Command(void) } } +/** Handler for the XPROG ENTER_PROGMODE command to establish a PDI connection with the attached device. */ static void PDIProtocol_EnterXPROGMode(void) { uint8_t ReturnStatus = XPRG_ERR_OK; @@ -101,22 +107,20 @@ static void PDIProtocol_EnterXPROGMode(void) PDIDATA_LINE_DDR |= PDIDATA_LINE_MASK; PDICLOCK_LINE_DDR |= PDICLOCK_LINE_MASK; + /* Must hold DATA line high for at least 90nS to enable PDI interface */ PDIDATA_LINE_PORT |= PDIDATA_LINE_MASK; - _delay_us(1); + /* Toggle CLOCK line 16 times within 100uS of the original 90nS timeout to keep PDI interface enabled */ for (uint8_t i = 0; i < 16; i++) - { - PDICLOCK_LINE_PORT ^= PDICLOCK_LINE_MASK; - PDICLOCK_LINE_PORT ^= PDICLOCK_LINE_MASK; - } - - static const uint8_t NVMKey[8] = {0x12, 0x89, 0xAB, 0x45, 0xCD, 0xD8, 0x88, 0xFF}; + TOGGLE_PDI_CLOCK; + /* Enable access to the XPROG NVM bus by sending the documented NVM access key to the device */ PDITarget_SendByte(PDI_CMD_KEY); for (uint8_t i = 0; i < 8; i++) - PDITarget_SendByte(NVMKey[i]); + PDITarget_SendByte(PDI_NVMENABLE_KEY[i]); + /* Read out the STATUS register to check that NVM access was successfully enabled */ PDITarget_SendByte(PDI_CMD_LDCS | PD_STATUS_REG); if (!(PDITarget_ReceiveByte() & PDI_STATUS_NVM)) ReturnStatus = XPRG_ERR_FAILED; @@ -127,14 +131,19 @@ static void PDIProtocol_EnterXPROGMode(void) Endpoint_ClearIN(); } +/** Handler for the XPROG LEAVE_PROGMODE command to terminate the PDI programming connection with + * the attached device. + */ static void PDIProtocol_LeaveXPROGMode(void) { Endpoint_ClearOUT(); Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN); + /* Set DATA and CLOCK lines to inputs */ PDIDATA_LINE_DDR &= ~PDIDATA_LINE_MASK; PDICLOCK_LINE_DDR &= ~PDICLOCK_LINE_MASK; - + + /* Tristate DATA and CLOCK lines */ PDIDATA_LINE_PORT &= ~PDIDATA_LINE_MASK; PDICLOCK_LINE_PORT &= ~PDICLOCK_LINE_MASK; @@ -144,7 +153,8 @@ static void PDIProtocol_LeaveXPROGMode(void) Endpoint_ClearIN(); } -static void PDIProtocol_EraseChip(void) +/** Handler for the XPRG ERASE command to erase a specific memory address space in the attached device. */ +static void PDIProtocol_Erase(void) { uint8_t ReturnStatus = XPRG_ERR_OK; @@ -167,6 +177,7 @@ static void PDIProtocol_EraseChip(void) Endpoint_ClearIN(); } +/** Handler for the XPROG WRITE_MEMORY command to write to a specific memory space within the attached device. */ static void PDIProtocol_WriteMemory(void) { uint8_t ReturnStatus = XPRG_ERR_OK; @@ -196,6 +207,9 @@ static void PDIProtocol_WriteMemory(void) Endpoint_ClearIN(); } +/** Handler for the XPROG READ_MEMORY command to read data from a specific address space within the + * attached device. + */ static void PDIProtocol_ReadMemory(void) { uint8_t ReturnStatus = XPRG_ERR_OK; @@ -219,23 +233,13 @@ static void PDIProtocol_ReadMemory(void) 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(); } +/** Handler for the XPROG CRC command to read a specific memory space's CRC value for comparison between the + * attached device's memory and a data set on the host. + */ static void PDIProtocol_ReadCRC(void) { uint8_t ReturnStatus = XPRG_ERR_OK; @@ -262,6 +266,9 @@ static void PDIProtocol_ReadCRC(void) Endpoint_ClearIN(); } +/** Handler for the XPROG SET_PARAM command to set a PDI parameter for use when communicating with the + * attached device. + */ static void PDIProtocol_SetParam(void) { uint8_t ReturnStatus = XPRG_ERR_OK; diff --git a/Projects/AVRISP/Lib/PDIProtocol.h b/Projects/AVRISP/Lib/PDIProtocol.h index 53388d0609..406ba27322 100644 --- a/Projects/AVRISP/Lib/PDIProtocol.h +++ b/Projects/AVRISP/Lib/PDIProtocol.h @@ -92,7 +92,7 @@ static void PDIProtocol_EnterXPROGMode(void); static void PDIProtocol_LeaveXPROGMode(void); static void PDIProtocol_SetParam(void); - static void PDIProtocol_EraseChip(void); + static void PDIProtocol_Erase(void); static void PDIProtocol_WriteMemory(void); static void PDIProtocol_ReadMemory(void); static void PDIProtocol_ReadCRC(void); diff --git a/Projects/AVRISP/Lib/PDITarget.c b/Projects/AVRISP/Lib/PDITarget.c index 57a1a29eeb..d1042068f6 100644 --- a/Projects/AVRISP/Lib/PDITarget.c +++ b/Projects/AVRISP/Lib/PDITarget.c @@ -38,12 +38,16 @@ #define INCLUDE_FROM_PDITARGET_C #include "PDITarget.h" +/** Writes a given byte to the attached XMEGA device, using a RS232 frame via software through the + * PDI interface. + * + * \param Byte Byte to send to the attached device + */ void PDITarget_SendByte(uint8_t Byte) { - PDIDATA_LINE_PORT &= ~PDIDATA_LINE_MASK; + PDIDATA_LINE_PORT &= ~PDIDATA_LINE_MASK; - PDICLOCK_LINE_PORT ^= PDICLOCK_LINE_MASK; - PDICLOCK_LINE_PORT ^= PDICLOCK_LINE_MASK; + TOGGLE_PDI_CLOCK; for (uint8_t i = 0; i < 8; i++) { @@ -54,33 +58,28 @@ void PDITarget_SendByte(uint8_t Byte) Byte >>= 1; - PDICLOCK_LINE_PORT ^= PDICLOCK_LINE_MASK; - PDICLOCK_LINE_PORT ^= PDICLOCK_LINE_MASK; + TOGGLE_PDI_CLOCK; } - PDIDATA_LINE_PORT |= PDIDATA_LINE_MASK; + PDIDATA_LINE_PORT |= PDIDATA_LINE_MASK; - PDICLOCK_LINE_PORT ^= PDICLOCK_LINE_MASK; - PDICLOCK_LINE_PORT ^= PDICLOCK_LINE_MASK; - PDICLOCK_LINE_PORT ^= PDICLOCK_LINE_MASK; - PDICLOCK_LINE_PORT ^= PDICLOCK_LINE_MASK; + TOGGLE_PDI_CLOCK; + TOGGLE_PDI_CLOCK; } +/** Reads a given byte from the attached XMEGA device, encoded in a RS232 frame through the PDI interface. + * + * \return Received byte from the attached device + */ uint8_t PDITarget_ReceiveByte(void) { uint8_t ReceivedByte = 0; - PDIDATA_LINE_DDR &= ~PDIDATA_LINE_MASK; + PDIDATA_LINE_DDR &= ~PDIDATA_LINE_MASK; - bool FoundStartBit; - - do - { - PDICLOCK_LINE_PORT ^= PDICLOCK_LINE_MASK; - PDICLOCK_LINE_PORT ^= PDICLOCK_LINE_MASK; - FoundStartBit = !(PDIDATA_LINE_PIN & PDIDATA_LINE_MASK); - } while (!FoundStartBit); - + while (PDIDATA_LINE_PIN & PDIDATA_LINE_MASK); + TOGGLE_PDI_CLOCK; + for (uint8_t i = 0; i < 8; i++) { if (PDIDATA_LINE_PIN & PDIDATA_LINE_MASK) @@ -88,16 +87,13 @@ uint8_t PDITarget_ReceiveByte(void) ReceivedByte <<= 1; - PDICLOCK_LINE_PORT ^= PDICLOCK_LINE_MASK; - PDICLOCK_LINE_PORT ^= PDICLOCK_LINE_MASK; + TOGGLE_PDI_CLOCK; } - PDICLOCK_LINE_PORT ^= PDICLOCK_LINE_MASK; - PDICLOCK_LINE_PORT ^= PDICLOCK_LINE_MASK; - PDICLOCK_LINE_PORT ^= PDICLOCK_LINE_MASK; - PDICLOCK_LINE_PORT ^= PDICLOCK_LINE_MASK; + TOGGLE_PDI_CLOCK; + TOGGLE_PDI_CLOCK; - PDIDATA_LINE_DDR |= PDIDATA_LINE_MASK; + PDIDATA_LINE_DDR |= PDIDATA_LINE_MASK; return ReceivedByte; } diff --git a/Projects/AVRISP/Lib/PDITarget.h b/Projects/AVRISP/Lib/PDITarget.h index cc8c7dbc5c..55a1a95622 100644 --- a/Projects/AVRISP/Lib/PDITarget.h +++ b/Projects/AVRISP/Lib/PDITarget.h @@ -39,6 +39,8 @@ /* Includes: */ #include #include + + #include /* Defines: */ #define PDIDATA_LINE_PORT PORTB @@ -64,8 +66,12 @@ #define PD_CTRL_REG 2 #define PDI_STATUS_NVM (1 << 1) + #define PDI_RESET_KEY 0x59 + #define PDI_NVMENABLE_KEY (uint8_t[]){0x12, 0x89, 0xAB, 0x45, 0xCD, 0xD8, 0x88, 0xFF} + #define TOGGLE_PDI_CLOCK MACROS{ PDICLOCK_LINE_PORT ^= PDICLOCK_LINE_MASK; \ + PDICLOCK_LINE_PORT ^= PDICLOCK_LINE_MASK; }MACROE /* Function Prototypes: */ void PDITarget_SendByte(uint8_t Byte); diff --git a/Projects/AVRISP/Lib/V2Protocol.c b/Projects/AVRISP/Lib/V2Protocol.c index d2e0b16867..24f208046c 100644 --- a/Projects/AVRISP/Lib/V2Protocol.c +++ b/Projects/AVRISP/Lib/V2Protocol.c @@ -66,6 +66,7 @@ void V2Protocol_ProcessCommand(void) case CMD_RESET_PROTECTION: V2Protocol_ResetProtection(); break; +#if defined(ENABLE_SPI_PROTOCOL) case CMD_ENTER_PROGMODE_ISP: ISPProtocol_EnterISPMode(); break; @@ -83,14 +84,6 @@ void V2Protocol_ProcessCommand(void) case CMD_CHIP_ERASE_ISP: ISPProtocol_ChipErase(); break; -#if defined(ENABLE_XPROG_PROTOCOL) - case CMD_XPROG_SETMODE: - PDIProtocol_XPROG_SetMode(); - break; - case CMD_XPROG: - PDIProtocol_XPROG_Command(); - break; -#endif case CMD_READ_FUSE_ISP: case CMD_READ_LOCK_ISP: case CMD_READ_SIGNATURE_ISP: @@ -104,6 +97,15 @@ void V2Protocol_ProcessCommand(void) case CMD_SPI_MULTI: ISPProtocol_SPIMulti(); break; +#endif +#if defined(ENABLE_XPROG_PROTOCOL) + case CMD_XPROG_SETMODE: + PDIProtocol_XPROG_SetMode(); + break; + case CMD_XPROG: + PDIProtocol_XPROG_Command(); + break; +#endif default: V2Protocol_UnknownCommand(V2Command); break; diff --git a/Projects/AVRISP/makefile b/Projects/AVRISP/makefile index cf4fa00783..d7fe4ac196 100644 --- a/Projects/AVRISP/makefile +++ b/Projects/AVRISP/makefile @@ -193,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_SPI_PROTOCOL CDEFS += -DENABLE_XPROG_PROTOCOL