/*
LUFA Library
- Copyright (C) Dean Camera, 2010.
-
+ Copyright (C) Dean Camera, 2011.
+
dean [at] fourwalledcubicle [dot] com
- www.fourwalledcubicle.com
+ www.lufa-lib.org
*/
/*
- Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+ Copyright 2011 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
{
uint8_t Protocol;
} SetMode_XPROG_Params;
-
- Endpoint_Read_Stream_LE(&SetMode_XPROG_Params, sizeof(SetMode_XPROG_Params), NO_STREAM_CALLBACK);
+
+ Endpoint_Read_Stream_LE(&SetMode_XPROG_Params, sizeof(SetMode_XPROG_Params), NULL);
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_Write_8(CMD_XPROG_SETMODE);
+ Endpoint_Write_8((SetMode_XPROG_Params.Protocol != XPRG_PROTOCOL_JTAG) ? STATUS_CMD_OK : STATUS_CMD_FAILED);
+ 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();
-
+ uint8_t XPROGCommand = Endpoint_Read_8();
+
switch (XPROGCommand)
{
case XPRG_CMD_ENTER_PROGMODE:
Endpoint_ClearOUT();
Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPNUM);
Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
-
- bool NVMBusEnabled;
-
- if (XPROG_SelectedProtocol == XPRG_PROTOCOL_PDI)
- {
- /* Enable PDI programming mode with the attached target */
- 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_RESET_KEY);
- /* Lower direction change guard time to 0 USART bits */
- XPROGTarget_SendByte(PDI_CMD_STCS | PDI_CTRL_REG);
- XPROGTarget_SendByte(0x07);
+ bool NVMBusEnabled = false;
- /* Enable access to the XPROG NVM bus by sending the documented NVM access key to the device */
- XPROGTarget_SendByte(PDI_CMD_KEY);
- for (uint8_t i = sizeof(PDI_NVMENABLE_KEY); i > 0; i--)
- XPROGTarget_SendByte(PDI_NVMENABLE_KEY[i - 1]);
+ if (XPROG_SelectedProtocol == XPRG_PROTOCOL_PDI)
+ NVMBusEnabled = XMEGANVM_EnablePDI();
+ else if (XPROG_SelectedProtocol == XPRG_PROTOCOL_TPI)
+ NVMBusEnabled = TINYNVM_EnableTPI();
- /* Wait until the NVM bus becomes active */
- NVMBusEnabled = XMEGANVM_WaitWhileNVMBusBusy();
- }
- else
- {
- /* 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);
- 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_Write_8(CMD_XPROG);
+ Endpoint_Write_8(XPRG_CMD_ENTER_PROGMODE);
+ Endpoint_Write_8(NVMBusEnabled ? XPRG_ERR_OK : XPRG_ERR_FAILED);
Endpoint_ClearIN();
}
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(0x00);
- /* Do it twice to make sure it takes affect (silicon bug?) */
- XPROGTarget_SendByte(PDI_CMD_STCS | PDI_RESET_REG);
- XPROGTarget_SendByte(0x00);
-
- XPROGTarget_DisableTargetPDI();
- }
+ if (XPROG_SelectedProtocol == XPRG_PROTOCOL_PDI)
+ XMEGANVM_DisablePDI();
else
- {
- TINYNVM_WaitWhileNVMBusBusy();
+ TINYNVM_DisableTPI();
- /* Clear the NVMEN bit in the TPI CONTROL register to disable TPI mode */
- 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);
+ #if defined(XCK_RESCUE_CLOCK_ENABLE) && defined(ENABLE_ISP_PROTOCOL)
+ /* If the XCK rescue clock option is enabled, we need to restart it once the
+ * XPROG mode has been exited, since the XPROG protocol stops it after use. */
+ ISPTarget_ConfigureRescueClock();
+ #endif
+
+ Endpoint_Write_8(CMD_XPROG);
+ Endpoint_Write_8(XPRG_CMD_LEAVE_PROGMODE);
+ Endpoint_Write_8(XPRG_ERR_OK);
Endpoint_ClearIN();
}
uint32_t Address;
} Erase_XPROG_Params;
- Endpoint_Read_Stream_LE(&Erase_XPROG_Params, sizeof(Erase_XPROG_Params), NO_STREAM_CALLBACK);
+ Endpoint_Read_Stream_LE(&Erase_XPROG_Params, sizeof(Erase_XPROG_Params), NULL);
Erase_XPROG_Params.Address = SwapEndian_32(Erase_XPROG_Params.Address);
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 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 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_Write_8(CMD_XPROG);
+ Endpoint_Write_8(XPRG_CMD_ERASE);
+ Endpoint_Write_8(ReturnStatus);
+ 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);
+ sizeof(WriteMemory_XPROG_Params).ProgData), NULL);
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, NO_STREAM_CALLBACK);
+ Endpoint_Read_Stream_LE(&WriteMemory_XPROG_Params.ProgData, WriteMemory_XPROG_Params.Length, NULL);
+ // The driver will terminate transfers that are a round multiple of the endpoint bank in size with a ZLP, need
+ // to catch this and discard it before continuing on with packet processing to prevent communication issues
+ if (((sizeof(uint8_t) + sizeof(WriteMemory_XPROG_Params) - sizeof(WriteMemory_XPROG_Params.ProgData)) +
+ WriteMemory_XPROG_Params.Length) % AVRISP_DATA_EPSIZE == 0)
+ {
+ Endpoint_ClearOUT();
+ Endpoint_WaitUntilReady();
+ }
+
Endpoint_ClearOUT();
Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPNUM);
Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
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_8(CMD_XPROG);
+ Endpoint_Write_8(XPRG_CMD_WRITE_MEM);
+ Endpoint_Write_8(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);
+
+ Endpoint_Read_Stream_LE(&ReadMemory_XPROG_Params, sizeof(ReadMemory_XPROG_Params), NULL);
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 */
ReturnStatus = XPRG_ERR_TIMEOUT;
}
- Endpoint_Write_Byte(CMD_XPROG);
- Endpoint_Write_Byte(XPRG_CMD_READ_MEM);
- Endpoint_Write_Byte(ReturnStatus);
-
+ Endpoint_Write_8(CMD_XPROG);
+ Endpoint_Write_8(XPRG_CMD_READ_MEM);
+ Endpoint_Write_8(ReturnStatus);
+
if (ReturnStatus == XPRG_ERR_OK)
- Endpoint_Write_Stream_LE(ReadBuffer, ReadMemory_XPROG_Params.Length, NO_STREAM_CALLBACK);
-
+ Endpoint_Write_Stream_LE(ReadBuffer, ReadMemory_XPROG_Params.Length, NULL);
+
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_Read_Stream_LE(&ReadCRC_XPROG_Params, sizeof(ReadCRC_XPROG_Params), NULL);
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);
-
+
+ Endpoint_Write_8(CMD_XPROG);
+ Endpoint_Write_8(XPRG_CMD_CRC);
+ Endpoint_Write_8(ReturnStatus);
+
if (ReturnStatus == XPRG_ERR_OK)
{
- Endpoint_Write_Byte(MemoryCRC >> 16);
- Endpoint_Write_Word_LE(MemoryCRC & 0xFFFF);
+ Endpoint_Write_8(MemoryCRC >> 16);
+ Endpoint_Write_16_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();
-
+ uint8_t XPROGParam = Endpoint_Read_8();
+
/* Determine which parameter is being set, store the new parameter value */
switch (XPROGParam)
{
case XPRG_PARAM_NVMBASE:
- XPROG_Param_NVMBase = Endpoint_Read_DWord_BE();
+ XPROG_Param_NVMBase = Endpoint_Read_32_BE();
break;
case XPRG_PARAM_EEPPAGESIZE:
- XPROG_Param_EEPageSize = Endpoint_Read_Word_BE();
+ XPROG_Param_EEPageSize = Endpoint_Read_16_BE();
break;
case XPRG_PARAM_NVMCMD_REG:
- XPROG_Param_NVMCMDRegAddr = Endpoint_Read_Byte();
+ XPROG_Param_NVMCMDRegAddr = Endpoint_Read_8();
break;
case XPRG_PARAM_NVMCSR_REG:
- XPROG_Param_NVMCSRRegAddr = Endpoint_Read_Byte();
+ XPROG_Param_NVMCSRRegAddr = Endpoint_Read_8();
break;
default:
ReturnStatus = XPRG_ERR_FAILED;
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);
+
+ Endpoint_Write_8(CMD_XPROG);
+ Endpoint_Write_8(XPRG_CMD_SET_PARAM);
+ Endpoint_Write_8(ReturnStatus);
Endpoint_ClearIN();
}
#endif
+