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.
pull/1469/head
Dean Camera 15 years ago
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)
{
case XPRG_ERASE_CHIP:
EraseCommand = XMEGA_NVM_CMD_CHIPERASE; EraseCommand = XMEGA_NVM_CMD_CHIPERASE;
else if (Erase_XPROG_Params.MemoryType == XPRG_ERASE_APP) break;
case XPRG_ERASE_APP:
EraseCommand = XMEGA_NVM_CMD_ERASEAPPSEC; EraseCommand = XMEGA_NVM_CMD_ERASEAPPSEC;
else if (Erase_XPROG_Params.MemoryType == XPRG_ERASE_BOOT) break;
case XPRG_ERASE_BOOT:
EraseCommand = XMEGA_NVM_CMD_ERASEBOOTSEC; EraseCommand = XMEGA_NVM_CMD_ERASEBOOTSEC;
else if (Erase_XPROG_Params.MemoryType == XPRG_ERASE_EEPROM) break;
case XPRG_ERASE_EEPROM:
EraseCommand = XMEGA_NVM_CMD_ERASEEEPROM; EraseCommand = XMEGA_NVM_CMD_ERASEEEPROM;
else if (Erase_XPROG_Params.MemoryType == XPRG_ERASE_APP_PAGE) break;
case XPRG_ERASE_APP_PAGE:
EraseCommand = XMEGA_NVM_CMD_ERASEAPPSECPAGE; EraseCommand = XMEGA_NVM_CMD_ERASEAPPSECPAGE;
else if (Erase_XPROG_Params.MemoryType == XPRG_ERASE_BOOT_PAGE) break;
case XPRG_ERASE_BOOT_PAGE:
EraseCommand = XMEGA_NVM_CMD_ERASEBOOTSECPAGE; EraseCommand = XMEGA_NVM_CMD_ERASEBOOTSECPAGE;
else if (Erase_XPROG_Params.MemoryType == XPRG_ERASE_EEPROM_PAGE) break;
case XPRG_ERASE_EEPROM_PAGE:
EraseCommand = XMEGA_NVM_CMD_ERASEEEPROMPAGE; EraseCommand = XMEGA_NVM_CMD_ERASEEEPROMPAGE;
else if (Erase_XPROG_Params.MemoryType == XPRG_ERASE_USERSIG) break;
case XPRG_ERASE_USERSIG:
EraseCommand = XMEGA_NVM_CMD_ERASEUSERSIG; 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)))
@ -278,35 +289,32 @@ static void XPROGProtocol_WriteMemory(void)
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)
{ {
case XPRG_MEM_TYPE_APPL:
WriteCommand = XMEGA_NVM_CMD_WRITEAPPSECPAGE; WriteCommand = XMEGA_NVM_CMD_WRITEAPPSECPAGE;
} break;
else if (WriteMemory_XPROG_Params.MemoryType == XPRG_MEM_TYPE_BOOT) 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;
else if (WriteMemory_XPROG_Params.MemoryType == XPRG_MEM_TYPE_USERSIG) 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 */ /* 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); WriteMemory_XPROG_Params.PageMode = (XPRG_PAGEMODE_ERASE | XPRG_PAGEMODE_WRITE);
WriteCommand = XMEGA_NVM_CMD_WRITEUSERSIG; WriteCommand = XMEGA_NVM_CMD_WRITEUSERSIG;
} break;
else if (WriteMemory_XPROG_Params.MemoryType == XPRG_MEM_TYPE_FUSE) case XPRG_MEM_TYPE_FUSE:
{
WriteCommand = XMEGA_NVM_CMD_WRITEFUSE; WriteCommand = XMEGA_NVM_CMD_WRITEFUSE;
PagedMemory = false; PagedMemory = false;
} break;
else if (WriteMemory_XPROG_Params.MemoryType == XPRG_MEM_TYPE_LOCKBITS) case XPRG_MEM_TYPE_LOCKBITS:
{
WriteCommand = XMEGA_NVM_CMD_WRITELOCK; WriteCommand = XMEGA_NVM_CMD_WRITELOCK;
PagedMemory = false; PagedMemory = false;
break;
} }
/* 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)
{
case XPRG_CRC_APP:
CRCCommand = XMEGA_NVM_CMD_APPCRC; CRCCommand = XMEGA_NVM_CMD_APPCRC;
else if (ReadCRC_XPROG_Params.CRCType == XPRG_CRC_BOOT) break;
case XPRG_CRC_BOOT:
CRCCommand = XMEGA_NVM_CMD_BOOTCRC; CRCCommand = XMEGA_NVM_CMD_BOOTCRC;
else break;
default:
CRCCommand = XMEGA_NVM_CMD_FLASHCRC; 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…
Cancel
Save