/*
LUFA Library
Copyright (C) Dean Camera, 2010.
-
+
dean [at] fourwalledcubicle [dot] com
- www.fourwalledcubicle.com
+ www.lufa-lib.org
*/
/*
Copyright 2010 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
#if defined(ENABLE_XPROG_PROTOCOL) || defined(__DOXYGEN__)
/** Base absolute address for the target's NVM controller for PDI programming */
-uint32_t XPROG_Param_NVMBase = 0x010001C0;
+uint32_t XPROG_Param_NVMBase = 0x010001C0;
/** Size in bytes of the target's EEPROM page */
-uint16_t XPROG_Param_EEPageSize;
+uint16_t XPROG_Param_EEPageSize = 32;
/** Address of the TPI device's NVMCMD register for TPI programming */
-uint8_t XPROG_Param_NVMCMDRegAddr;
+uint8_t XPROG_Param_NVMCMDRegAddr = 0x33;
/** Address of the TPI device's NVMCSR register for TPI programming */
-uint8_t XPROG_Param_NVMCSRRegAddr;
+uint8_t XPROG_Param_NVMCSRRegAddr = 0x32;
/** Currently selected XPROG programming protocol */
-uint8_t XPROG_SelectedProtocol = XPRG_PROTOCOL_PDI;
+uint8_t XPROG_SelectedProtocol = XPRG_PROTOCOL_PDI;
/** Handler for the CMD_XPROG_SETMODE command, which sets the programmer-to-target protocol used for PDI/TPI
* programming.
{
uint8_t Protocol;
} SetMode_XPROG_Params;
-
+
Endpoint_Read_Stream_LE(&SetMode_XPROG_Params, sizeof(SetMode_XPROG_Params), NO_STREAM_CALLBACK);
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_ClearIN();
}
/** Handler for the CMD_XPROG command, which wraps up XPROG commands in a V2 wrapper which need to be
void XPROGProtocol_Command(void)
{
uint8_t XPROGCommand = Endpoint_Read_Byte();
-
+
switch (XPROGCommand)
{
case XPRG_CMD_ENTER_PROGMODE:
Endpoint_ClearOUT();
Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPNUM);
Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
-
- bool NVMBusEnabled;
+
+ bool NVMBusEnabled = false;
if (XPROG_SelectedProtocol == XPRG_PROTOCOL_PDI)
{
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_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(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);
+ 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();
}
- else
+ 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);
+ 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);
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(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(PDI_CMD_STCS | PDI_RESET_REG);
XPROGTarget_SendByte(0x00);
XPROGTarget_DisableTargetPDI();
TINYNVM_WaitWhileNVMBusBusy();
/* Clear the NVMEN bit in the TPI CONTROL register to disable TPI mode */
- XPROGTarget_SendByte(TPI_CMD_SSTCS | TPI_CTRL_REG);
+ 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);
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)
{
EraseCommand = XMEGA_NVM_CMD_NOOP;
break;
}
-
- /* Erase the target memory, indicate timeout if ocurred */
+
+ /* Erase the target memory, indicate timeout if occurred */
if (!(XMEGANVM_EraseMemory(EraseCommand, Erase_XPROG_Params.Address)))
ReturnStatus = XPRG_ERR_TIMEOUT;
}
EraseCommand = TINY_NVM_CMD_CHIPERASE;
else
EraseCommand = TINY_NVM_CMD_SECTIONERASE;
-
- /* Erase the target memory, indicate timeout if ocurred */
+
+ /* 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_ClearIN();
}
/** Handler for the XPROG WRITE_MEMORY command to write to a specific memory space within the attached device. */
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);
WriteMemory_XPROG_Params.Address = SwapEndian_32(WriteMemory_XPROG_Params.Address);
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:
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:
- /* User signature is paged, but needs us to manually indicate the mode bits since the host doesn't set them */
- WriteMemory_XPROG_Params.PageMode = (XPRG_PAGEMODE_ERASE | XPRG_PAGEMODE_WRITE);
WriteCommand = XMEGA_NVM_CMD_WRITEUSERSIG;
break;
case XPRG_MEM_TYPE_FUSE:
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,
ReturnStatus = XPRG_ERR_TIMEOUT;
}
}
-
+
Endpoint_Write_Byte(CMD_XPROG);
Endpoint_Write_Byte(XPRG_CMD_WRITE_MEM);
- Endpoint_Write_Byte(ReturnStatus);
+ Endpoint_Write_Byte(ReturnStatus);
Endpoint_ClearIN();
}
uint32_t Address;
uint16_t Length;
} ReadMemory_XPROG_Params;
-
+
Endpoint_Read_Stream_LE(&ReadMemory_XPROG_Params, sizeof(ReadMemory_XPROG_Params), NO_STREAM_CALLBACK);
ReadMemory_XPROG_Params.Address = SwapEndian_32(ReadMemory_XPROG_Params.Address);
ReadMemory_XPROG_Params.Length = SwapEndian_16(ReadMemory_XPROG_Params.Length);
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 */
Endpoint_Write_Byte(CMD_XPROG);
Endpoint_Write_Byte(XPRG_CMD_READ_MEM);
Endpoint_Write_Byte(ReturnStatus);
-
+
if (ReturnStatus == XPRG_ERR_OK)
Endpoint_Write_Stream_LE(ReadBuffer, ReadMemory_XPROG_Params.Length, NO_STREAM_CALLBACK);
-
+
Endpoint_ClearIN();
}
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_ClearOUT();
Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPNUM);
Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
-
+
uint32_t MemoryCRC;
if (XPROG_SelectedProtocol == XPRG_PROTOCOL_PDI)
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;
/* 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);
-
+
if (ReturnStatus == XPRG_ERR_OK)
{
Endpoint_Write_Byte(MemoryCRC >> 16);
- Endpoint_Write_Word_LE(MemoryCRC & 0xFFFF);
+ Endpoint_Write_Word_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
uint8_t ReturnStatus = XPRG_ERR_OK;
uint8_t XPROGParam = Endpoint_Read_Byte();
-
+
/* Determine which parameter is being set, store the new parameter value */
switch (XPROGParam)
{
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);
}
#endif
+