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