Commit bb387933 authored by Dean Camera's avatar Dean Camera
Browse files

Add Doxygen documentation to the completed portions of the PDI programming...

Add Doxygen documentation to the completed portions of the PDI programming protocol in the AVRISP project.
parent f3e4fbe5
......@@ -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 @@
* <tr>
* <td>PDI_VIA_HARDWARE_USART</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
* AVRISP pinout. <i>Automatically set when compiled for the XPLAIN board.</i></td>
* <td>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.
* <i>Ignored when compiled for the XPLAIN board.</i></td>
* </tr>
* </table>
*/
......@@ -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();
......
......@@ -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);
......
......@@ -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
......
......@@ -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;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment