mirror of
				https://github.com/mfulz/qmk_firmware.git
				synced 2025-11-04 07:12:33 +01:00 
			
		
		
		
	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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user