forked from mfulz_github/qmk_firmware
Fix AVRISP-MKII clone project's TPI Chip Erase command processing - ensure erase location is the high byte in the given address space, check NVMBUSY for completion rather than the NVM Bus Enable bit.
Change If-Else chains over to switch statements in XPROGProtocol.c for clarity.
This commit is contained in:
parent
6a48efd3bd
commit
7ae91099e9
|
@ -13,7 +13,6 @@
|
||||||
* - Series 7 USB AVRs
|
* - Series 7 USB AVRs
|
||||||
* - Series 6 USB AVRs
|
* - Series 6 USB AVRs
|
||||||
* - Series 4 USB AVRs
|
* - Series 4 USB AVRs
|
||||||
* - Series 2 USB AVRs
|
|
||||||
*
|
*
|
||||||
* \section SSec_Info USB Information:
|
* \section SSec_Info USB Information:
|
||||||
*
|
*
|
||||||
|
|
|
@ -13,7 +13,6 @@
|
||||||
* - Series 7 USB AVRs
|
* - Series 7 USB AVRs
|
||||||
* - Series 6 USB AVRs
|
* - Series 6 USB AVRs
|
||||||
* - Series 4 USB AVRs
|
* - Series 4 USB AVRs
|
||||||
* - Series 2 USB AVRs
|
|
||||||
*
|
*
|
||||||
* \section SSec_Info USB Information:
|
* \section SSec_Info USB Information:
|
||||||
*
|
*
|
||||||
|
|
|
@ -104,12 +104,13 @@
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
uint8_t HostToDevice; /**< Control line states from the host to device, as a set of CDC_CONTROL_LINE_OUT_*
|
uint8_t HostToDevice; /**< Control line states from the host to device, as a set of CDC_CONTROL_LINE_OUT_*
|
||||||
* masks.
|
* masks. This value is updated each time \ref CDC_Device_USBTask() is called.
|
||||||
*/
|
*/
|
||||||
uint8_t DeviceToHost; /**< Control line states from the device to host, as a set of CDC_CONTROL_LINE_IN_*
|
uint8_t DeviceToHost; /**< Control line states from the device to host, as a set of CDC_CONTROL_LINE_IN_*
|
||||||
* masks.
|
* masks - to notify the host of changes to these values, call the
|
||||||
|
* \ref CDC_Device_SendControlLineStateChange() function.
|
||||||
*/
|
*/
|
||||||
} ControlLineStates;
|
} ControlLineStates; /**< Current states of the virtual serial port's control lines between the device and host. */
|
||||||
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
|
@ -121,7 +122,9 @@
|
||||||
* CDCDevice_LineCodingParity_t enum
|
* CDCDevice_LineCodingParity_t enum
|
||||||
*/
|
*/
|
||||||
uint8_t DataBits; /**< Bits of data per character of the virtual serial port */
|
uint8_t DataBits; /**< Bits of data per character of the virtual serial port */
|
||||||
} LineEncoding;
|
} LineEncoding; /** Line encoding used in the virtual serial port, for the device's information. This is generally
|
||||||
|
* only used if the virtual serial port data is to be reconstructed on a physical UART.
|
||||||
|
*/
|
||||||
} State; /**< State data for the USB class interface within the device. All elements in this section
|
} State; /**< State data for the USB class interface within the device. All elements in this section
|
||||||
* are reset to their defaults when the interface is enumerated.
|
* are reset to their defaults when the interface is enumerated.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -92,12 +92,13 @@
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
uint8_t HostToDevice; /**< Control line states from the host to device, as a set of CDC_CONTROL_LINE_OUT_*
|
uint8_t HostToDevice; /**< Control line states from the host to device, as a set of CDC_CONTROL_LINE_OUT_*
|
||||||
* masks.
|
* masks - to notify the device of changes to these values, call the
|
||||||
|
* \ref CDC_Host_SendControlLineStateChange() function.
|
||||||
*/
|
*/
|
||||||
uint8_t DeviceToHost; /**< Control line states from the device to host, as a set of CDC_CONTROL_LINE_IN_*
|
uint8_t DeviceToHost; /**< Control line states from the device to host, as a set of CDC_CONTROL_LINE_IN_*
|
||||||
* masks.
|
* masks. This value is updated each time \ref CDC_Host_USBTask() is called.
|
||||||
*/
|
*/
|
||||||
} ControlLineStates;
|
} ControlLineStates; /**< Current states of the virtual serial port's control lines between the device and host. */
|
||||||
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
|
@ -109,7 +110,11 @@
|
||||||
* CDCDevice_LineCodingParity_t enum
|
* CDCDevice_LineCodingParity_t enum
|
||||||
*/
|
*/
|
||||||
uint8_t DataBits; /**< Bits of data per character of the virtual serial port */
|
uint8_t DataBits; /**< Bits of data per character of the virtual serial port */
|
||||||
} LineEncoding;
|
} LineEncoding; /** Line encoding used in the virtual serial port, for the device's information. This is generally
|
||||||
|
* only used if the virtual serial port data is to be reconstructed on a physical UART. When set
|
||||||
|
* by the host application, the \ref CDC_Host_SetLineEncoding() function must be called to push
|
||||||
|
* the changes to the device.
|
||||||
|
*/
|
||||||
} State; /**< State data for the USB class interface within the device. All elements in this section
|
} State; /**< State data for the USB class interface within the device. All elements in this section
|
||||||
* <b>may</b> be set to initial values, but may also be ignored to default to sane values when
|
* <b>may</b> be set to initial values, but may also be ignored to default to sane values when
|
||||||
* the interface is enumerated.
|
* the interface is enumerated.
|
||||||
|
|
|
@ -193,7 +193,7 @@
|
||||||
* 0x204D
|
* 0x204D
|
||||||
* </td>
|
* </td>
|
||||||
* <td>
|
* <td>
|
||||||
* Keyboard and Mouse Combination Demo Application
|
* Combined Keyboard and Mouse Demo Application
|
||||||
* </td>
|
* </td>
|
||||||
* </tr>
|
* </tr>
|
||||||
*
|
*
|
||||||
|
|
|
@ -204,13 +204,13 @@ bool TINYNVM_EraseMemory(const uint8_t EraseCommand, const uint16_t Address)
|
||||||
TINYNVM_SendWriteNVMRegister(XPROG_Param_NVMCMDRegAddr);
|
TINYNVM_SendWriteNVMRegister(XPROG_Param_NVMCMDRegAddr);
|
||||||
XPROGTarget_SendByte(EraseCommand);
|
XPROGTarget_SendByte(EraseCommand);
|
||||||
|
|
||||||
/* Write to a location within the target address space to start the erase process */
|
/* Write to a high byte location within the target address space to start the erase process */
|
||||||
TINYNVM_SendPointerAddress(Address);
|
TINYNVM_SendPointerAddress(Address | 0x0001);
|
||||||
XPROGTarget_SendByte(TPI_CMD_SST | TPI_POINTER_INDIRECT);
|
XPROGTarget_SendByte(TPI_CMD_SST | TPI_POINTER_INDIRECT);
|
||||||
XPROGTarget_SendByte(0x00);
|
XPROGTarget_SendByte(0x00);
|
||||||
|
|
||||||
/* Wait until the NVM bus is ready again */
|
/* Wait until the NVM controller is no longer busy */
|
||||||
if (!(TINYNVM_WaitWhileNVMBusBusy()))
|
if (!(TINYNVM_WaitWhileNVMControllerBusy()))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -63,6 +63,7 @@
|
||||||
|
|
||||||
/* Function Prototypes: */
|
/* Function Prototypes: */
|
||||||
bool TINYNVM_WaitWhileNVMBusBusy(void);
|
bool TINYNVM_WaitWhileNVMBusBusy(void);
|
||||||
|
bool TINYNVM_WaitWhileNVMControllerBusy(void);
|
||||||
bool TINYNVM_ReadMemory(const uint16_t ReadAddress, uint8_t* ReadBuffer, uint16_t ReadLength);
|
bool TINYNVM_ReadMemory(const uint16_t ReadAddress, uint8_t* ReadBuffer, uint16_t ReadLength);
|
||||||
bool TINYNVM_WriteMemory(const uint16_t WriteAddress, uint8_t* WriteBuffer, uint16_t WriteLength);
|
bool TINYNVM_WriteMemory(const uint16_t WriteAddress, uint8_t* WriteBuffer, uint16_t WriteLength);
|
||||||
bool TINYNVM_EraseMemory(const uint8_t EraseCommand, const uint16_t Address);
|
bool TINYNVM_EraseMemory(const uint8_t EraseCommand, const uint16_t Address);
|
||||||
|
|
|
@ -208,27 +208,38 @@ static void XPROGProtocol_Erase(void)
|
||||||
Endpoint_ClearOUT();
|
Endpoint_ClearOUT();
|
||||||
Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
|
Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
|
||||||
|
|
||||||
uint8_t EraseCommand = XMEGA_NVM_CMD_NOOP;
|
|
||||||
|
|
||||||
if (XPROG_SelectedProtocol == XPRG_PROTOCOL_PDI)
|
if (XPROG_SelectedProtocol == XPRG_PROTOCOL_PDI)
|
||||||
{
|
{
|
||||||
|
uint8_t EraseCommand = XMEGA_NVM_CMD_NOOP;
|
||||||
|
|
||||||
/* Determine which NVM command to send to the device depending on the memory to erase */
|
/* Determine which NVM command to send to the device depending on the memory to erase */
|
||||||
if (Erase_XPROG_Params.MemoryType == XPRG_ERASE_CHIP)
|
switch (Erase_XPROG_Params.MemoryType)
|
||||||
EraseCommand = XMEGA_NVM_CMD_CHIPERASE;
|
{
|
||||||
else if (Erase_XPROG_Params.MemoryType == XPRG_ERASE_APP)
|
case XPRG_ERASE_CHIP:
|
||||||
EraseCommand = XMEGA_NVM_CMD_ERASEAPPSEC;
|
EraseCommand = XMEGA_NVM_CMD_CHIPERASE;
|
||||||
else if (Erase_XPROG_Params.MemoryType == XPRG_ERASE_BOOT)
|
break;
|
||||||
EraseCommand = XMEGA_NVM_CMD_ERASEBOOTSEC;
|
case XPRG_ERASE_APP:
|
||||||
else if (Erase_XPROG_Params.MemoryType == XPRG_ERASE_EEPROM)
|
EraseCommand = XMEGA_NVM_CMD_ERASEAPPSEC;
|
||||||
EraseCommand = XMEGA_NVM_CMD_ERASEEEPROM;
|
break;
|
||||||
else if (Erase_XPROG_Params.MemoryType == XPRG_ERASE_APP_PAGE)
|
case XPRG_ERASE_BOOT:
|
||||||
EraseCommand = XMEGA_NVM_CMD_ERASEAPPSECPAGE;
|
EraseCommand = XMEGA_NVM_CMD_ERASEBOOTSEC;
|
||||||
else if (Erase_XPROG_Params.MemoryType == XPRG_ERASE_BOOT_PAGE)
|
break;
|
||||||
EraseCommand = XMEGA_NVM_CMD_ERASEBOOTSECPAGE;
|
case XPRG_ERASE_EEPROM:
|
||||||
else if (Erase_XPROG_Params.MemoryType == XPRG_ERASE_EEPROM_PAGE)
|
EraseCommand = XMEGA_NVM_CMD_ERASEEEPROM;
|
||||||
EraseCommand = XMEGA_NVM_CMD_ERASEEEPROMPAGE;
|
break;
|
||||||
else if (Erase_XPROG_Params.MemoryType == XPRG_ERASE_USERSIG)
|
case XPRG_ERASE_APP_PAGE:
|
||||||
EraseCommand = XMEGA_NVM_CMD_ERASEUSERSIG;
|
EraseCommand = XMEGA_NVM_CMD_ERASEAPPSECPAGE;
|
||||||
|
break;
|
||||||
|
case XPRG_ERASE_BOOT_PAGE:
|
||||||
|
EraseCommand = XMEGA_NVM_CMD_ERASEBOOTSECPAGE;
|
||||||
|
break;
|
||||||
|
case XPRG_ERASE_EEPROM_PAGE:
|
||||||
|
EraseCommand = XMEGA_NVM_CMD_ERASEEEPROMPAGE;
|
||||||
|
break;
|
||||||
|
case XPRG_ERASE_USERSIG:
|
||||||
|
EraseCommand = XMEGA_NVM_CMD_ERASEUSERSIG;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/* Erase the target memory, indicate timeout if ocurred */
|
/* Erase the target memory, indicate timeout if ocurred */
|
||||||
if (!(XMEGANVM_EraseMemory(EraseCommand, Erase_XPROG_Params.Address)))
|
if (!(XMEGANVM_EraseMemory(EraseCommand, Erase_XPROG_Params.Address)))
|
||||||
|
@ -277,36 +288,33 @@ static void XPROGProtocol_WriteMemory(void)
|
||||||
uint8_t WriteBuffCommand = XMEGA_NVM_CMD_LOADFLASHPAGEBUFF;
|
uint8_t WriteBuffCommand = XMEGA_NVM_CMD_LOADFLASHPAGEBUFF;
|
||||||
uint8_t EraseBuffCommand = XMEGA_NVM_CMD_ERASEFLASHPAGEBUFF;
|
uint8_t EraseBuffCommand = XMEGA_NVM_CMD_ERASEFLASHPAGEBUFF;
|
||||||
bool PagedMemory = true;
|
bool PagedMemory = true;
|
||||||
|
|
||||||
if (WriteMemory_XPROG_Params.MemoryType == XPRG_MEM_TYPE_APPL)
|
switch (WriteMemory_XPROG_Params.MemoryType)
|
||||||
{
|
{
|
||||||
WriteCommand = XMEGA_NVM_CMD_WRITEAPPSECPAGE;
|
case XPRG_MEM_TYPE_APPL:
|
||||||
}
|
WriteCommand = XMEGA_NVM_CMD_WRITEAPPSECPAGE;
|
||||||
else if (WriteMemory_XPROG_Params.MemoryType == XPRG_MEM_TYPE_BOOT)
|
break;
|
||||||
{
|
case XPRG_MEM_TYPE_BOOT:
|
||||||
WriteCommand = XMEGA_NVM_CMD_WRITEBOOTSECPAGE;
|
WriteCommand = XMEGA_NVM_CMD_WRITEBOOTSECPAGE;
|
||||||
}
|
break;
|
||||||
else if (WriteMemory_XPROG_Params.MemoryType == XPRG_MEM_TYPE_EEPROM)
|
case XPRG_MEM_TYPE_EEPROM:
|
||||||
{
|
WriteCommand = XMEGA_NVM_CMD_WRITEEEPROMPAGE;
|
||||||
WriteCommand = XMEGA_NVM_CMD_WRITEEEPROMPAGE;
|
WriteBuffCommand = XMEGA_NVM_CMD_LOADEEPROMPAGEBUFF;
|
||||||
WriteBuffCommand = XMEGA_NVM_CMD_LOADEEPROMPAGEBUFF;
|
EraseBuffCommand = XMEGA_NVM_CMD_ERASEEEPROMPAGEBUFF;
|
||||||
EraseBuffCommand = XMEGA_NVM_CMD_ERASEEEPROMPAGEBUFF;
|
break;
|
||||||
}
|
case XPRG_MEM_TYPE_USERSIG:
|
||||||
else if (WriteMemory_XPROG_Params.MemoryType == 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);
|
||||||
/* User signature is paged, but needs us to manually indicate the mode bits since the host doesn't set them */
|
WriteCommand = XMEGA_NVM_CMD_WRITEUSERSIG;
|
||||||
WriteMemory_XPROG_Params.PageMode = (XPRG_PAGEMODE_ERASE | XPRG_PAGEMODE_WRITE);
|
break;
|
||||||
WriteCommand = XMEGA_NVM_CMD_WRITEUSERSIG;
|
case XPRG_MEM_TYPE_FUSE:
|
||||||
}
|
WriteCommand = XMEGA_NVM_CMD_WRITEFUSE;
|
||||||
else if (WriteMemory_XPROG_Params.MemoryType == XPRG_MEM_TYPE_FUSE)
|
PagedMemory = false;
|
||||||
{
|
break;
|
||||||
WriteCommand = XMEGA_NVM_CMD_WRITEFUSE;
|
case XPRG_MEM_TYPE_LOCKBITS:
|
||||||
PagedMemory = false;
|
WriteCommand = XMEGA_NVM_CMD_WRITELOCK;
|
||||||
}
|
PagedMemory = false;
|
||||||
else if (WriteMemory_XPROG_Params.MemoryType == XPRG_MEM_TYPE_LOCKBITS)
|
break;
|
||||||
{
|
|
||||||
WriteCommand = XMEGA_NVM_CMD_WRITELOCK;
|
|
||||||
PagedMemory = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Send the appropriate memory write commands to the device, indicate timeout if occurred */
|
/* Send the appropriate memory write commands to the device, indicate timeout if occurred */
|
||||||
|
@ -394,21 +402,29 @@ static void XPROGProtocol_ReadCRC(void)
|
||||||
} ReadCRC_XPROG_Params;
|
} 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), NO_STREAM_CALLBACK);
|
||||||
|
|
||||||
Endpoint_ClearOUT();
|
Endpoint_ClearOUT();
|
||||||
Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
|
Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
|
||||||
|
|
||||||
uint8_t CRCCommand = XMEGA_NVM_CMD_NOOP;
|
|
||||||
uint32_t MemoryCRC;
|
uint32_t MemoryCRC;
|
||||||
|
|
||||||
if (XPROG_SelectedProtocol == XPRG_PROTOCOL_PDI)
|
if (XPROG_SelectedProtocol == XPRG_PROTOCOL_PDI)
|
||||||
{
|
{
|
||||||
|
uint8_t CRCCommand;
|
||||||
|
|
||||||
/* Determine which NVM command to send to the device depending on the memory to CRC */
|
/* Determine which NVM command to send to the device depending on the memory to CRC */
|
||||||
if (ReadCRC_XPROG_Params.CRCType == XPRG_CRC_APP)
|
switch (ReadCRC_XPROG_Params.CRCType)
|
||||||
CRCCommand = XMEGA_NVM_CMD_APPCRC;
|
{
|
||||||
else if (ReadCRC_XPROG_Params.CRCType == XPRG_CRC_BOOT)
|
case XPRG_CRC_APP:
|
||||||
CRCCommand = XMEGA_NVM_CMD_BOOTCRC;
|
CRCCommand = XMEGA_NVM_CMD_APPCRC;
|
||||||
else
|
break;
|
||||||
CRCCommand = XMEGA_NVM_CMD_FLASHCRC;
|
case XPRG_CRC_BOOT:
|
||||||
|
CRCCommand = XMEGA_NVM_CMD_BOOTCRC;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
CRCCommand = XMEGA_NVM_CMD_FLASHCRC;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/* Perform and retrieve the memory CRC, indicate timeout if occurred */
|
/* Perform and retrieve the memory CRC, indicate timeout if occurred */
|
||||||
if (!(XMEGANVM_GetMemoryCRC(CRCCommand, &MemoryCRC)))
|
if (!(XMEGANVM_GetMemoryCRC(CRCCommand, &MemoryCRC)))
|
||||||
|
|
|
@ -131,7 +131,7 @@
|
||||||
#define TPI_NVMENABLE_KEY (uint8_t[]){0x12, 0x89, 0xAB, 0x45, 0xCD, 0xD8, 0x88, 0xFF}
|
#define TPI_NVMENABLE_KEY (uint8_t[]){0x12, 0x89, 0xAB, 0x45, 0xCD, 0xD8, 0x88, 0xFF}
|
||||||
|
|
||||||
#define TPI_POINTER_INDIRECT 0
|
#define TPI_POINTER_INDIRECT 0
|
||||||
#define TPI_POINTER_INDIRECT_PI (1 << 2)
|
#define TPI_POINTER_INDIRECT_PI 4
|
||||||
|
|
||||||
/* Function Prototypes: */
|
/* Function Prototypes: */
|
||||||
void XPROGTarget_EnableTargetPDI(void);
|
void XPROGTarget_EnableTargetPDI(void);
|
||||||
|
|
Loading…
Reference in New Issue