forked from mfulz_github/qmk_firmware
Add Doxygen documentation to the completed portions of the PDI programming protocol in the AVRISP project.
This commit is contained in:
parent
f3e4fbe512
commit
bb38793312
|
@ -13,7 +13,7 @@
|
||||||
* - 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
|
* - Series 2 USB AVRs (8KB versions with reduced features only)
|
||||||
*
|
*
|
||||||
* \section SSec_Info USB Information:
|
* \section SSec_Info USB Information:
|
||||||
*
|
*
|
||||||
|
@ -51,7 +51,7 @@
|
||||||
* level conversion can be made to allow for the programming of 3.3V AVR designs.
|
* level conversion can be made to allow for the programming of 3.3V AVR designs.
|
||||||
*
|
*
|
||||||
* This device spoofs Atmel's official AVRISP-MKII device PID so that it remains compatible with Atmel's AVRISP-MKII
|
* This device spoofs Atmel's official AVRISP-MKII device PID so that it remains compatible with Atmel's AVRISP-MKII
|
||||||
* drivers. When promted, direct your OS to install Atmel's AVRISP-MKII drivers provided with AVRStudio.
|
* drivers. When prompted, direct your OS to install Atmel's AVRISP-MKII drivers provided with AVRStudio.
|
||||||
*
|
*
|
||||||
* Note that this design currently has several limitations:
|
* Note that this design currently has several limitations:
|
||||||
* - Minimum ISP target clock speed of 500KHz due to hardware SPI used
|
* - Minimum ISP target clock speed of 500KHz due to hardware SPI used
|
||||||
|
@ -62,7 +62,10 @@
|
||||||
* without an ADC converter, VTARGET will report at a fixed 5V level.
|
* without an ADC converter, VTARGET will report at a fixed 5V level.
|
||||||
*
|
*
|
||||||
* When compiled for the XPLAIN board target, this will automatically configure itself for the correct connections to the
|
* When compiled for the XPLAIN board target, this will automatically configure itself for the correct connections to the
|
||||||
* XPLAIN's XMEGA AVR, and will enable only PDI programming support.
|
* XPLAIN's XMEGA AVR, and will enable PDI only programming support (since ISP mode is not needed).
|
||||||
|
*
|
||||||
|
* While this application can be compiled for USB AVRs with as little as 8KB of FLASH, for full functionality 16KB or more
|
||||||
|
* of FLASH is required. On 8KB devices, either ISP or PDI programming support can be disabled to reduce program size.
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* Connections to the device for SPI programming (when enabled):
|
* Connections to the device for SPI programming (when enabled):
|
||||||
|
@ -203,8 +206,10 @@
|
||||||
* <tr>
|
* <tr>
|
||||||
* <td>PDI_VIA_HARDWARE_USART</td>
|
* <td>PDI_VIA_HARDWARE_USART</td>
|
||||||
* <td>Makefile CDEFS</td>
|
* <td>Makefile CDEFS</td>
|
||||||
* <td>Define to force the PDI protocol (when enabled) to use the hardware USART instead of bit-banging to match the official
|
* <td>Define to force the PDI protocol (when enabled) to use the much faster hardware USART instead of bit-banging to
|
||||||
* AVRISP pinout. <i>Automatically set when compiled for the XPLAIN board.</i></td>
|
* match the official AVRISP pinout. This breaks pinout compatibility with the official AVRISP MKII (and requires
|
||||||
|
* seperate ISP and PDI programming headers) but increases programming speed dramatically.
|
||||||
|
* <i>Ignored when compiled for the XPLAIN board.</i></td>
|
||||||
* </tr>
|
* </tr>
|
||||||
* </table>
|
* </table>
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -38,6 +38,10 @@
|
||||||
|
|
||||||
#if defined(ENABLE_PDI_PROTOCOL) || defined(__DOXYGEN__)
|
#if defined(ENABLE_PDI_PROTOCOL) || defined(__DOXYGEN__)
|
||||||
|
|
||||||
|
/** Sends the given NVM register address to the target.
|
||||||
|
*
|
||||||
|
* \param[in] Register NVM register whose absolute address is to be sent
|
||||||
|
*/
|
||||||
void NVMTarget_SendNVMRegAddress(uint8_t Register)
|
void NVMTarget_SendNVMRegAddress(uint8_t Register)
|
||||||
{
|
{
|
||||||
/* Determine the absolute register address from the NVM base memory address and the NVM register address */
|
/* Determine the absolute register address from the NVM base memory address and the NVM register address */
|
||||||
|
@ -50,6 +54,10 @@ void NVMTarget_SendNVMRegAddress(uint8_t Register)
|
||||||
PDITarget_SendByte(Address >> 24);
|
PDITarget_SendByte(Address >> 24);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Sends the given 32-bit absolute address to the target.
|
||||||
|
*
|
||||||
|
* \param[in] AbsoluteAddress Absolute address to send to the target
|
||||||
|
*/
|
||||||
void NVMTarget_SendAddress(uint32_t AbsoluteAddress)
|
void NVMTarget_SendAddress(uint32_t AbsoluteAddress)
|
||||||
{
|
{
|
||||||
/* Send the given 32-bit address to the target, LSB first */
|
/* Send the given 32-bit address to the target, LSB first */
|
||||||
|
@ -59,6 +67,11 @@ void NVMTarget_SendAddress(uint32_t AbsoluteAddress)
|
||||||
PDITarget_SendByte(AbsoluteAddress >> 24);
|
PDITarget_SendByte(AbsoluteAddress >> 24);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Waits while the target's NVM controller is busy performing an operation, exiting if the
|
||||||
|
* timeout period expires.
|
||||||
|
*
|
||||||
|
* \return Boolean true if the NVM controller became ready within the timeout period, false otherwise
|
||||||
|
*/
|
||||||
bool NVMTarget_WaitWhileNVMControllerBusy(void)
|
bool NVMTarget_WaitWhileNVMControllerBusy(void)
|
||||||
{
|
{
|
||||||
TCNT0 = 0;
|
TCNT0 = 0;
|
||||||
|
@ -78,7 +91,13 @@ bool NVMTarget_WaitWhileNVMControllerBusy(void)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t NVMTarget_GetMemoryCRC(uint8_t MemoryCommand)
|
/** Retrieves the CRC value of the given memory space.
|
||||||
|
*
|
||||||
|
* \param[in] CRCCommand NVM CRC command to issue to the target
|
||||||
|
*
|
||||||
|
* \return 24-bit CRC value for the given address space
|
||||||
|
*/
|
||||||
|
uint32_t NVMTarget_GetMemoryCRC(uint8_t CRCCommand)
|
||||||
{
|
{
|
||||||
uint32_t MemoryCRC;
|
uint32_t MemoryCRC;
|
||||||
|
|
||||||
|
@ -87,7 +106,7 @@ uint32_t NVMTarget_GetMemoryCRC(uint8_t MemoryCommand)
|
||||||
/* Set the NVM command to the correct CRC read command */
|
/* Set the NVM command to the correct CRC read command */
|
||||||
PDITarget_SendByte(PDI_CMD_STS | (PDI_DATSIZE_4BYTES << 2));
|
PDITarget_SendByte(PDI_CMD_STS | (PDI_DATSIZE_4BYTES << 2));
|
||||||
NVMTarget_SendNVMRegAddress(NVM_REG_CMD);
|
NVMTarget_SendNVMRegAddress(NVM_REG_CMD);
|
||||||
PDITarget_SendByte(MemoryCommand);
|
PDITarget_SendByte(CRCCommand);
|
||||||
|
|
||||||
/* Set CMDEX bit in NVM CTRLA register to start the CRC generation */
|
/* Set CMDEX bit in NVM CTRLA register to start the CRC generation */
|
||||||
PDITarget_SendByte(PDI_CMD_STS | (PDI_DATSIZE_4BYTES << 2));
|
PDITarget_SendByte(PDI_CMD_STS | (PDI_DATSIZE_4BYTES << 2));
|
||||||
|
@ -116,6 +135,12 @@ uint32_t NVMTarget_GetMemoryCRC(uint8_t MemoryCommand)
|
||||||
return MemoryCRC;
|
return MemoryCRC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Reads memory from the target's memory spaces.
|
||||||
|
*
|
||||||
|
* \param[in] ReadAddress Start address to read from within the target's address space
|
||||||
|
* \param[out] ReadBuffer Buffer to store read data into
|
||||||
|
* \param[in] ReadSize Number of bytes to read
|
||||||
|
*/
|
||||||
void NVMTarget_ReadMemory(uint32_t ReadAddress, uint8_t* ReadBuffer, uint16_t ReadSize)
|
void NVMTarget_ReadMemory(uint32_t ReadAddress, uint8_t* ReadBuffer, uint16_t ReadSize)
|
||||||
{
|
{
|
||||||
NVMTarget_WaitWhileNVMControllerBusy();
|
NVMTarget_WaitWhileNVMControllerBusy();
|
||||||
|
@ -149,6 +174,11 @@ void NVMTarget_ReadMemory(uint32_t ReadAddress, uint8_t* ReadBuffer, uint16_t Re
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Erases a specific memory space of the target.
|
||||||
|
*
|
||||||
|
* \param[in] EraseCommand NVM erase command to send to the device
|
||||||
|
* \param[in] Address Address inside the memory space to erase
|
||||||
|
*/
|
||||||
void NVMTarget_EraseMemory(uint8_t EraseCommand, uint32_t Address)
|
void NVMTarget_EraseMemory(uint8_t EraseCommand, uint32_t Address)
|
||||||
{
|
{
|
||||||
NVMTarget_WaitWhileNVMControllerBusy();
|
NVMTarget_WaitWhileNVMControllerBusy();
|
||||||
|
|
|
@ -109,7 +109,7 @@
|
||||||
void NVMTarget_SendNVMRegAddress(uint8_t Register);
|
void NVMTarget_SendNVMRegAddress(uint8_t Register);
|
||||||
void NVMTarget_SendAddress(uint32_t AbsoluteAddress);
|
void NVMTarget_SendAddress(uint32_t AbsoluteAddress);
|
||||||
bool NVMTarget_WaitWhileNVMControllerBusy(void);
|
bool NVMTarget_WaitWhileNVMControllerBusy(void);
|
||||||
uint32_t NVMTarget_GetMemoryCRC(uint8_t MemoryCommand);
|
uint32_t NVMTarget_GetMemoryCRC(uint8_t CRCCommand);
|
||||||
void NVMTarget_ReadMemory(uint32_t ReadAddress, uint8_t* ReadBuffer, uint16_t ReadSize);
|
void NVMTarget_ReadMemory(uint32_t ReadAddress, uint8_t* ReadBuffer, uint16_t ReadSize);
|
||||||
void NVMTarget_EraseMemory(uint8_t EraseCommand, uint32_t Address);
|
void NVMTarget_EraseMemory(uint8_t EraseCommand, uint32_t Address);
|
||||||
|
|
||||||
|
|
|
@ -37,9 +37,12 @@
|
||||||
#include "PDIProtocol.h"
|
#include "PDIProtocol.h"
|
||||||
|
|
||||||
#if defined(ENABLE_PDI_PROTOCOL) || defined(__DOXYGEN__)
|
#if defined(ENABLE_PDI_PROTOCOL) || defined(__DOXYGEN__)
|
||||||
#warning PDI Programming Protocol support is incomplete and not currently suitable for use.
|
#warning PDI Programming Protocol support is incomplete and not currently suitable for general use.
|
||||||
|
|
||||||
|
/** Base absolute address for the target's NVM controller */
|
||||||
uint32_t XPROG_Param_NVMBase;
|
uint32_t XPROG_Param_NVMBase;
|
||||||
|
|
||||||
|
/** Size in bytes of the target's EEPROM page */
|
||||||
uint32_t XPROG_Param_EEPageSize;
|
uint32_t XPROG_Param_EEPageSize;
|
||||||
|
|
||||||
/** Handler for the CMD_XPROG_SETMODE command, which sets the programmer-to-target protocol used for PDI
|
/** Handler for the CMD_XPROG_SETMODE command, which sets the programmer-to-target protocol used for PDI
|
||||||
|
|
|
@ -38,12 +38,18 @@
|
||||||
|
|
||||||
#if defined(ENABLE_PDI_PROTOCOL) || defined(__DOXYGEN__)
|
#if defined(ENABLE_PDI_PROTOCOL) || defined(__DOXYGEN__)
|
||||||
|
|
||||||
|
/** Flag to indicate if the USART is currently in Tx or Rx mode. */
|
||||||
volatile bool IsSending;
|
volatile bool IsSending;
|
||||||
|
|
||||||
#if !defined(PDI_VIA_HARDWARE_USART)
|
#if !defined(PDI_VIA_HARDWARE_USART)
|
||||||
|
/** Software USART raw frame bits for transmission/reception. */
|
||||||
volatile uint16_t SoftUSART_Data;
|
volatile uint16_t SoftUSART_Data;
|
||||||
|
|
||||||
|
/** Bits remaining to be sent or received via the software USART. */
|
||||||
volatile uint8_t SoftUSART_BitCount;
|
volatile uint8_t SoftUSART_BitCount;
|
||||||
|
|
||||||
|
|
||||||
|
/** ISR to manage the software USART when bit-banged USART mode is selected. */
|
||||||
ISR(TIMER1_COMPA_vect, ISR_BLOCK)
|
ISR(TIMER1_COMPA_vect, ISR_BLOCK)
|
||||||
{
|
{
|
||||||
/* Toggle CLOCK pin in a single cycle (see AVR datasheet) */
|
/* Toggle CLOCK pin in a single cycle (see AVR datasheet) */
|
||||||
|
@ -81,6 +87,7 @@ ISR(TIMER1_COMPA_vect, ISR_BLOCK)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/** Enables the target's PDI interface, holding the target in reset until PDI mode is exited. */
|
||||||
void PDITarget_EnableTargetPDI(void)
|
void PDITarget_EnableTargetPDI(void)
|
||||||
{
|
{
|
||||||
#if defined(PDI_VIA_HARDWARE_USART)
|
#if defined(PDI_VIA_HARDWARE_USART)
|
||||||
|
@ -122,6 +129,7 @@ void PDITarget_EnableTargetPDI(void)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Disables the target's PDI interface, exits programming mode and starts the target's application. */
|
||||||
void PDITarget_DisableTargetPDI(void)
|
void PDITarget_DisableTargetPDI(void)
|
||||||
{
|
{
|
||||||
#if defined(PDI_VIA_HARDWARE_USART)
|
#if defined(PDI_VIA_HARDWARE_USART)
|
||||||
|
@ -146,6 +154,10 @@ void PDITarget_DisableTargetPDI(void)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Sends a byte via the USART.
|
||||||
|
*
|
||||||
|
* \param[in] Byte Byte to send through the USART
|
||||||
|
*/
|
||||||
void PDITarget_SendByte(uint8_t Byte)
|
void PDITarget_SendByte(uint8_t Byte)
|
||||||
{
|
{
|
||||||
#if defined(PDI_VIA_HARDWARE_USART)
|
#if defined(PDI_VIA_HARDWARE_USART)
|
||||||
|
@ -192,6 +204,10 @@ void PDITarget_SendByte(uint8_t Byte)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Receives a byte via the software USART, blocking until data is received.
|
||||||
|
*
|
||||||
|
* \return Received byte from the USART
|
||||||
|
*/
|
||||||
uint8_t PDITarget_ReceiveByte(void)
|
uint8_t PDITarget_ReceiveByte(void)
|
||||||
{
|
{
|
||||||
#if defined(PDI_VIA_HARDWARE_USART)
|
#if defined(PDI_VIA_HARDWARE_USART)
|
||||||
|
@ -234,6 +250,7 @@ uint8_t PDITarget_ReceiveByte(void)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Sends a BREAK via the USART to the attached target, consisting of a full frame of idle bits. */
|
||||||
void PDITarget_SendBreak(void)
|
void PDITarget_SendBreak(void)
|
||||||
{
|
{
|
||||||
#if defined(PDI_VIA_HARDWARE_USART)
|
#if defined(PDI_VIA_HARDWARE_USART)
|
||||||
|
@ -274,6 +291,11 @@ void PDITarget_SendBreak(void)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Busy-waits while the NVM controller is busy performing a NVM operation, such as a FLASH page read or CRC
|
||||||
|
* calculation.
|
||||||
|
*
|
||||||
|
* \return Boolean true if the NVM controller became ready within the timeout period, false otherwise
|
||||||
|
*/
|
||||||
bool PDITarget_WaitWhileNVMBusBusy(void)
|
bool PDITarget_WaitWhileNVMBusBusy(void)
|
||||||
{
|
{
|
||||||
TCNT0 = 0;
|
TCNT0 = 0;
|
||||||
|
|
Loading…
Reference in New Issue