Add Doxygen documentation to the completed portions of the PDI programming protocol in the AVRISP project.

pull/1469/head
Dean Camera 15 years ago
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…
Cancel
Save