diff --git a/Projects/AVRISP/AVRISP.txt b/Projects/AVRISP/AVRISP.txt
index 6eeef385c8..2de8dd2e7a 100644
--- a/Projects/AVRISP/AVRISP.txt
+++ b/Projects/AVRISP/AVRISP.txt
@@ -13,7 +13,7 @@
* - Series 7 USB AVRs
* - Series 6 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:
*
@@ -51,7 +51,7 @@
* 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
- * 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:
* - 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.
*
* 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):
@@ -203,8 +206,10 @@
*
* PDI_VIA_HARDWARE_USART |
* Makefile CDEFS |
- * Define to force the PDI protocol (when enabled) to use the hardware USART instead of bit-banging to match the official
- * AVRISP pinout. Automatically set when compiled for the XPLAIN board. |
+ * Define to force the PDI protocol (when enabled) to use the much faster hardware USART instead of bit-banging to
+ * 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.
+ * Ignored when compiled for the XPLAIN board. |
*
*
*/
diff --git a/Projects/AVRISP/Lib/NVMTarget.c b/Projects/AVRISP/Lib/NVMTarget.c
index b57cf6d311..85de130694 100644
--- a/Projects/AVRISP/Lib/NVMTarget.c
+++ b/Projects/AVRISP/Lib/NVMTarget.c
@@ -38,6 +38,10 @@
#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)
{
/* 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);
}
+/** 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)
{
/* 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);
}
+/** 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)
{
TCNT0 = 0;
@@ -78,7 +91,13 @@ bool NVMTarget_WaitWhileNVMControllerBusy(void)
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;
@@ -87,7 +106,7 @@ uint32_t NVMTarget_GetMemoryCRC(uint8_t MemoryCommand)
/* Set the NVM command to the correct CRC read command */
PDITarget_SendByte(PDI_CMD_STS | (PDI_DATSIZE_4BYTES << 2));
NVMTarget_SendNVMRegAddress(NVM_REG_CMD);
- PDITarget_SendByte(MemoryCommand);
+ PDITarget_SendByte(CRCCommand);
/* Set CMDEX bit in NVM CTRLA register to start the CRC generation */
PDITarget_SendByte(PDI_CMD_STS | (PDI_DATSIZE_4BYTES << 2));
@@ -116,6 +135,12 @@ uint32_t NVMTarget_GetMemoryCRC(uint8_t MemoryCommand)
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)
{
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)
{
NVMTarget_WaitWhileNVMControllerBusy();
diff --git a/Projects/AVRISP/Lib/NVMTarget.h b/Projects/AVRISP/Lib/NVMTarget.h
index 7fde845384..b43967f996 100644
--- a/Projects/AVRISP/Lib/NVMTarget.h
+++ b/Projects/AVRISP/Lib/NVMTarget.h
@@ -109,7 +109,7 @@
void NVMTarget_SendNVMRegAddress(uint8_t Register);
void NVMTarget_SendAddress(uint32_t AbsoluteAddress);
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_EraseMemory(uint8_t EraseCommand, uint32_t Address);
diff --git a/Projects/AVRISP/Lib/PDIProtocol.c b/Projects/AVRISP/Lib/PDIProtocol.c
index af6fbeaf93..24ce26cb65 100644
--- a/Projects/AVRISP/Lib/PDIProtocol.c
+++ b/Projects/AVRISP/Lib/PDIProtocol.c
@@ -37,9 +37,12 @@
#include "PDIProtocol.h"
#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;
+
+/** Size in bytes of the target's EEPROM page */
uint32_t XPROG_Param_EEPageSize;
/** Handler for the CMD_XPROG_SETMODE command, which sets the programmer-to-target protocol used for PDI
diff --git a/Projects/AVRISP/Lib/PDITarget.c b/Projects/AVRISP/Lib/PDITarget.c
index 9f2bea8d43..c774fdab81 100644
--- a/Projects/AVRISP/Lib/PDITarget.c
+++ b/Projects/AVRISP/Lib/PDITarget.c
@@ -38,12 +38,18 @@
#if defined(ENABLE_PDI_PROTOCOL) || defined(__DOXYGEN__)
+/** Flag to indicate if the USART is currently in Tx or Rx mode. */
volatile bool IsSending;
#if !defined(PDI_VIA_HARDWARE_USART)
+/** Software USART raw frame bits for transmission/reception. */
volatile uint16_t SoftUSART_Data;
+
+/** Bits remaining to be sent or received via the software USART. */
volatile uint8_t SoftUSART_BitCount;
+
+/** ISR to manage the software USART when bit-banged USART mode is selected. */
ISR(TIMER1_COMPA_vect, ISR_BLOCK)
{
/* Toggle CLOCK pin in a single cycle (see AVR datasheet) */
@@ -81,6 +87,7 @@ ISR(TIMER1_COMPA_vect, ISR_BLOCK)
}
#endif
+/** Enables the target's PDI interface, holding the target in reset until PDI mode is exited. */
void PDITarget_EnableTargetPDI(void)
{
#if defined(PDI_VIA_HARDWARE_USART)
@@ -122,6 +129,7 @@ void PDITarget_EnableTargetPDI(void)
#endif
}
+/** Disables the target's PDI interface, exits programming mode and starts the target's application. */
void PDITarget_DisableTargetPDI(void)
{
#if defined(PDI_VIA_HARDWARE_USART)
@@ -146,6 +154,10 @@ void PDITarget_DisableTargetPDI(void)
#endif
}
+/** Sends a byte via the USART.
+ *
+ * \param[in] Byte Byte to send through the USART
+ */
void PDITarget_SendByte(uint8_t Byte)
{
#if defined(PDI_VIA_HARDWARE_USART)
@@ -192,6 +204,10 @@ void PDITarget_SendByte(uint8_t Byte)
#endif
}
+/** Receives a byte via the software USART, blocking until data is received.
+ *
+ * \return Received byte from the USART
+ */
uint8_t PDITarget_ReceiveByte(void)
{
#if defined(PDI_VIA_HARDWARE_USART)
@@ -234,6 +250,7 @@ uint8_t PDITarget_ReceiveByte(void)
#endif
}
+/** Sends a BREAK via the USART to the attached target, consisting of a full frame of idle bits. */
void PDITarget_SendBreak(void)
{
#if defined(PDI_VIA_HARDWARE_USART)
@@ -274,6 +291,11 @@ void PDITarget_SendBreak(void)
#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)
{
TCNT0 = 0;