Document the PDI programming routines implemented so far in the AVRISP project. Add ability to selectively disable ISP programming support in addition to the existing ability to disable PDI programming support.

pull/1469/head
Dean Camera 15 years ago
parent f69f03cb0d
commit a5adbae652

@ -16,6 +16,7 @@
* - Added new RNDIS Ethernet Host Class Driver * - Added new RNDIS Ethernet Host Class Driver
* - Added new RNDIS Ethernet Host ClassDriver demo * - 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 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
* *
* <b>Changed:</b> * <b>Changed:</b>
* - Removed code in the Keyboard demos to send zeroed reports between two reports with differing numbers of keycodes * - Removed code in the Keyboard demos to send zeroed reports between two reports with differing numbers of keycodes

@ -178,6 +178,11 @@
* <td>ADC channel number (on supported AVRs) to use for VTARGET level detection.</td> * <td>ADC channel number (on supported AVRs) to use for VTARGET level detection.</td>
* </tr> * </tr>
* <tr> * <tr>
* <td>ENABLE_SPI_PROTOCOL</td>
* <td>Makefile CDEFS</td>
* <td>Define to enable SPI programming protocol support.</td>
* </tr>
* <tr>
* <td>ENABLE_XPROG_PROTOCOL</td> * <td>ENABLE_XPROG_PROTOCOL</td>
* <td>Makefile CDEFS</td> * <td>Makefile CDEFS</td>
* <td>Define to enable XMEGA PDI programming protocol support.</td> * <td>Define to enable XMEGA PDI programming protocol support.</td>

@ -1221,7 +1221,7 @@ INCLUDE_FILE_PATTERNS =
# undefined via #undef or recursively expanded use the := operator # undefined via #undef or recursively expanded use the := operator
# instead of 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 # 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. # this tag can be used to specify a list of macro names that should be expanded.

@ -28,6 +28,8 @@
this software. this software.
*/ */
#if defined(ENABLE_SPI_PROTOCOL)
/** \file /** \file
* *
* ISP Protocol handler, to process V2 Protocol wrapped ISP commands used in Atmel programmer devices. * 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_Write_Byte(STATUS_CMD_OK);
Endpoint_ClearIN(); Endpoint_ClearIN();
} }
#endif

@ -28,6 +28,8 @@
this software. this software.
*/ */
#if defined(ENABLE_SPI_PROTOCOL)
/** \file /** \file
* *
* Target-related functions for the ISP Protocol decoder. * Target-related functions for the ISP Protocol decoder.
@ -178,3 +180,5 @@ void ISPTarget_LoadExtendedAddress(void)
SPI_SendByte((CurrentAddress & 0x00FF0000) >> 16); SPI_SendByte((CurrentAddress & 0x00FF0000) >> 16);
SPI_SendByte(0x00); SPI_SendByte(0x00);
} }
#endif

@ -30,6 +30,8 @@
#if defined(ENABLE_XPROG_PROTOCOL) #if defined(ENABLE_XPROG_PROTOCOL)
#warning PDI Programming Protocol support is incomplete and not currently suitable for use.
/** \file /** \file
* *
* PDI Protocol handler, to process V2 Protocol wrapped PDI commands used in Atmel programmer devices. * 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(); 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) void PDIProtocol_XPROG_Command(void)
{ {
uint8_t XPROGCommand = Endpoint_Read_Byte(); uint8_t XPROGCommand = Endpoint_Read_Byte();
@ -74,7 +79,7 @@ void PDIProtocol_XPROG_Command(void)
PDIProtocol_LeaveXPROGMode(); PDIProtocol_LeaveXPROGMode();
break; break;
case XPRG_CMD_ERASE: case XPRG_CMD_ERASE:
PDIProtocol_EraseChip(); PDIProtocol_Erase();
break; break;
case XPRG_CMD_WRITE_MEM: case XPRG_CMD_WRITE_MEM:
PDIProtocol_WriteMemory(); 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) static void PDIProtocol_EnterXPROGMode(void)
{ {
uint8_t ReturnStatus = XPRG_ERR_OK; uint8_t ReturnStatus = XPRG_ERR_OK;
@ -101,22 +107,20 @@ static void PDIProtocol_EnterXPROGMode(void)
PDIDATA_LINE_DDR |= PDIDATA_LINE_MASK; PDIDATA_LINE_DDR |= PDIDATA_LINE_MASK;
PDICLOCK_LINE_DDR |= PDICLOCK_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; PDIDATA_LINE_PORT |= PDIDATA_LINE_MASK;
_delay_us(1); _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++) for (uint8_t i = 0; i < 16; i++)
{ TOGGLE_PDI_CLOCK;
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};
/* Enable access to the XPROG NVM bus by sending the documented NVM access key to the device */
PDITarget_SendByte(PDI_CMD_KEY); PDITarget_SendByte(PDI_CMD_KEY);
for (uint8_t i = 0; i < 8; i++) 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); PDITarget_SendByte(PDI_CMD_LDCS | PD_STATUS_REG);
if (!(PDITarget_ReceiveByte() & PDI_STATUS_NVM)) if (!(PDITarget_ReceiveByte() & PDI_STATUS_NVM))
ReturnStatus = XPRG_ERR_FAILED; ReturnStatus = XPRG_ERR_FAILED;
@ -127,14 +131,19 @@ static void PDIProtocol_EnterXPROGMode(void)
Endpoint_ClearIN(); Endpoint_ClearIN();
} }
/** Handler for the XPROG LEAVE_PROGMODE command to terminate the PDI programming connection with
* the attached device.
*/
static void PDIProtocol_LeaveXPROGMode(void) static void PDIProtocol_LeaveXPROGMode(void)
{ {
Endpoint_ClearOUT(); Endpoint_ClearOUT();
Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN); Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
/* Set DATA and CLOCK lines to inputs */
PDIDATA_LINE_DDR &= ~PDIDATA_LINE_MASK; PDIDATA_LINE_DDR &= ~PDIDATA_LINE_MASK;
PDICLOCK_LINE_DDR &= ~PDICLOCK_LINE_MASK; PDICLOCK_LINE_DDR &= ~PDICLOCK_LINE_MASK;
/* Tristate DATA and CLOCK lines */
PDIDATA_LINE_PORT &= ~PDIDATA_LINE_MASK; PDIDATA_LINE_PORT &= ~PDIDATA_LINE_MASK;
PDICLOCK_LINE_PORT &= ~PDICLOCK_LINE_MASK; PDICLOCK_LINE_PORT &= ~PDICLOCK_LINE_MASK;
@ -144,7 +153,8 @@ static void PDIProtocol_LeaveXPROGMode(void)
Endpoint_ClearIN(); 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; uint8_t ReturnStatus = XPRG_ERR_OK;
@ -167,6 +177,7 @@ static void PDIProtocol_EraseChip(void)
Endpoint_ClearIN(); 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) static void PDIProtocol_WriteMemory(void)
{ {
uint8_t ReturnStatus = XPRG_ERR_OK; uint8_t ReturnStatus = XPRG_ERR_OK;
@ -196,6 +207,9 @@ static void PDIProtocol_WriteMemory(void)
Endpoint_ClearIN(); 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) static void PDIProtocol_ReadMemory(void)
{ {
uint8_t ReturnStatus = XPRG_ERR_OK; uint8_t ReturnStatus = XPRG_ERR_OK;
@ -220,22 +234,12 @@ static void PDIProtocol_ReadMemory(void)
Endpoint_Write_Byte(XPRG_CMD_READ_MEM); Endpoint_Write_Byte(XPRG_CMD_READ_MEM);
Endpoint_Write_Byte(ReturnStatus); 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(); 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) static void PDIProtocol_ReadCRC(void)
{ {
uint8_t ReturnStatus = XPRG_ERR_OK; uint8_t ReturnStatus = XPRG_ERR_OK;
@ -262,6 +266,9 @@ static void PDIProtocol_ReadCRC(void)
Endpoint_ClearIN(); 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) static void PDIProtocol_SetParam(void)
{ {
uint8_t ReturnStatus = XPRG_ERR_OK; uint8_t ReturnStatus = XPRG_ERR_OK;

@ -92,7 +92,7 @@
static void PDIProtocol_EnterXPROGMode(void); static void PDIProtocol_EnterXPROGMode(void);
static void PDIProtocol_LeaveXPROGMode(void); static void PDIProtocol_LeaveXPROGMode(void);
static void PDIProtocol_SetParam(void); static void PDIProtocol_SetParam(void);
static void PDIProtocol_EraseChip(void); static void PDIProtocol_Erase(void);
static void PDIProtocol_WriteMemory(void); static void PDIProtocol_WriteMemory(void);
static void PDIProtocol_ReadMemory(void); static void PDIProtocol_ReadMemory(void);
static void PDIProtocol_ReadCRC(void); static void PDIProtocol_ReadCRC(void);

@ -38,12 +38,16 @@
#define INCLUDE_FROM_PDITARGET_C #define INCLUDE_FROM_PDITARGET_C
#include "PDITarget.h" #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) void PDITarget_SendByte(uint8_t Byte)
{ {
PDIDATA_LINE_PORT &= ~PDIDATA_LINE_MASK; PDIDATA_LINE_PORT &= ~PDIDATA_LINE_MASK;
PDICLOCK_LINE_PORT ^= PDICLOCK_LINE_MASK; TOGGLE_PDI_CLOCK;
PDICLOCK_LINE_PORT ^= PDICLOCK_LINE_MASK;
for (uint8_t i = 0; i < 8; i++) for (uint8_t i = 0; i < 8; i++)
{ {
@ -54,32 +58,27 @@ void PDITarget_SendByte(uint8_t Byte)
Byte >>= 1; Byte >>= 1;
PDICLOCK_LINE_PORT ^= PDICLOCK_LINE_MASK; TOGGLE_PDI_CLOCK;
PDICLOCK_LINE_PORT ^= PDICLOCK_LINE_MASK;
} }
PDIDATA_LINE_PORT |= PDIDATA_LINE_MASK; PDIDATA_LINE_PORT |= PDIDATA_LINE_MASK;
PDICLOCK_LINE_PORT ^= PDICLOCK_LINE_MASK; TOGGLE_PDI_CLOCK;
PDICLOCK_LINE_PORT ^= PDICLOCK_LINE_MASK; TOGGLE_PDI_CLOCK;
PDICLOCK_LINE_PORT ^= PDICLOCK_LINE_MASK;
PDICLOCK_LINE_PORT ^= PDICLOCK_LINE_MASK;
} }
/** 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 PDITarget_ReceiveByte(void)
{ {
uint8_t ReceivedByte = 0; uint8_t ReceivedByte = 0;
PDIDATA_LINE_DDR &= ~PDIDATA_LINE_MASK; PDIDATA_LINE_DDR &= ~PDIDATA_LINE_MASK;
bool FoundStartBit;
do while (PDIDATA_LINE_PIN & PDIDATA_LINE_MASK);
{ TOGGLE_PDI_CLOCK;
PDICLOCK_LINE_PORT ^= PDICLOCK_LINE_MASK;
PDICLOCK_LINE_PORT ^= PDICLOCK_LINE_MASK;
FoundStartBit = !(PDIDATA_LINE_PIN & PDIDATA_LINE_MASK);
} while (!FoundStartBit);
for (uint8_t i = 0; i < 8; i++) for (uint8_t i = 0; i < 8; i++)
{ {
@ -88,16 +87,13 @@ uint8_t PDITarget_ReceiveByte(void)
ReceivedByte <<= 1; ReceivedByte <<= 1;
PDICLOCK_LINE_PORT ^= PDICLOCK_LINE_MASK; TOGGLE_PDI_CLOCK;
PDICLOCK_LINE_PORT ^= PDICLOCK_LINE_MASK;
} }
PDICLOCK_LINE_PORT ^= PDICLOCK_LINE_MASK; TOGGLE_PDI_CLOCK;
PDICLOCK_LINE_PORT ^= PDICLOCK_LINE_MASK; TOGGLE_PDI_CLOCK;
PDICLOCK_LINE_PORT ^= PDICLOCK_LINE_MASK;
PDICLOCK_LINE_PORT ^= PDICLOCK_LINE_MASK;
PDIDATA_LINE_DDR |= PDIDATA_LINE_MASK; PDIDATA_LINE_DDR |= PDIDATA_LINE_MASK;
return ReceivedByte; return ReceivedByte;
} }

@ -40,6 +40,8 @@
#include <avr/io.h> #include <avr/io.h>
#include <stdbool.h> #include <stdbool.h>
#include <LUFA/Common/Common.h>
/* Defines: */ /* Defines: */
#define PDIDATA_LINE_PORT PORTB #define PDIDATA_LINE_PORT PORTB
#define PDIDATA_LINE_DDR DDRB #define PDIDATA_LINE_DDR DDRB
@ -64,8 +66,12 @@
#define PD_CTRL_REG 2 #define PD_CTRL_REG 2
#define PDI_STATUS_NVM (1 << 1) #define PDI_STATUS_NVM (1 << 1)
#define PDI_RESET_KEY 0x59 #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: */ /* Function Prototypes: */
void PDITarget_SendByte(uint8_t Byte); void PDITarget_SendByte(uint8_t Byte);

@ -66,6 +66,7 @@ void V2Protocol_ProcessCommand(void)
case CMD_RESET_PROTECTION: case CMD_RESET_PROTECTION:
V2Protocol_ResetProtection(); V2Protocol_ResetProtection();
break; break;
#if defined(ENABLE_SPI_PROTOCOL)
case CMD_ENTER_PROGMODE_ISP: case CMD_ENTER_PROGMODE_ISP:
ISPProtocol_EnterISPMode(); ISPProtocol_EnterISPMode();
break; break;
@ -83,14 +84,6 @@ void V2Protocol_ProcessCommand(void)
case CMD_CHIP_ERASE_ISP: case CMD_CHIP_ERASE_ISP:
ISPProtocol_ChipErase(); ISPProtocol_ChipErase();
break; 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_FUSE_ISP:
case CMD_READ_LOCK_ISP: case CMD_READ_LOCK_ISP:
case CMD_READ_SIGNATURE_ISP: case CMD_READ_SIGNATURE_ISP:
@ -104,6 +97,15 @@ void V2Protocol_ProcessCommand(void)
case CMD_SPI_MULTI: case CMD_SPI_MULTI:
ISPProtocol_SPIMulti(); ISPProtocol_SPIMulti();
break; break;
#endif
#if defined(ENABLE_XPROG_PROTOCOL)
case CMD_XPROG_SETMODE:
PDIProtocol_XPROG_SetMode();
break;
case CMD_XPROG:
PDIProtocol_XPROG_Command();
break;
#endif
default: default:
V2Protocol_UnknownCommand(V2Command); V2Protocol_UnknownCommand(V2Command);
break; break;

@ -193,6 +193,7 @@ CDEFS += -DRESET_LINE_PORT=PORTB
CDEFS += -DRESET_LINE_DDR=DDRB CDEFS += -DRESET_LINE_DDR=DDRB
CDEFS += -DRESET_LINE_MASK="(1 << 4)" CDEFS += -DRESET_LINE_MASK="(1 << 4)"
CDEFS += -DVTARGET_ADC_CHANNEL=2 CDEFS += -DVTARGET_ADC_CHANNEL=2
CDEFS += -DENABLE_SPI_PROTOCOL
CDEFS += -DENABLE_XPROG_PROTOCOL CDEFS += -DENABLE_XPROG_PROTOCOL

Loading…
Cancel
Save