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;