Add svn:eol-style property to source files, so that the line endings are correctly converted to the target system's native end of line style.

This commit is contained in:
Dean Camera 2010-05-08 03:12:14 +00:00
parent e331b531c6
commit 071e02c6b6
839 changed files with 274562 additions and 274562 deletions

View file

@ -1,238 +1,238 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of
this software.
*/
/** \file
*
* Target-related functions for the TINY target's NVM module.
*/
#define INCLUDE_FROM_TINYNVM_C
#include "TINYNVM.h"
#if defined(ENABLE_XPROG_PROTOCOL) || defined(__DOXYGEN__)
/** Sends the given pointer address to the target's TPI pointer register */
static void TINYNVM_SendPointerAddress(const uint16_t AbsoluteAddress)
{
/* Send the given 16-bit address to the target, LSB first */
XPROGTarget_SendByte(TPI_CMD_SSTPR | 0);
XPROGTarget_SendByte(((uint8_t*)&AbsoluteAddress)[0]);
XPROGTarget_SendByte(TPI_CMD_SSTPR | 1);
XPROGTarget_SendByte(((uint8_t*)&AbsoluteAddress)[1]);
}
/** Sends a SIN command to the target with the specified I/O address, ready for the data byte to be written.
*
* \param[in] Address 6-bit I/O address to write to in the target's I/O memory space
*/
static void TINYNVM_SendReadNVMRegister(const uint8_t Address)
{
/* The TPI command for reading from the I/O space uses strange addressing, where the I/O address's upper
* two bits of the 6-bit address are shifted left once */
XPROGTarget_SendByte(TPI_CMD_SIN | ((Address & 0x30) << 1) | (Address & 0x0F));
}
/** Sends a SOUT command to the target with the specified I/O address, ready for the data byte to be read.
*
* \param[in] Address 6-bit I/O address to read from in the target's I/O memory space
*/
static void TINYNVM_SendWriteNVMRegister(const uint8_t Address)
{
/* The TPI command for reading from the I/O space uses strange addressing, where the I/O address's upper
* two bits of the 6-bit address are shifted left once */
XPROGTarget_SendByte(TPI_CMD_SOUT | ((Address & 0x30) << 1) | (Address & 0x0F));
}
/** Busy-waits while the NVM controller is busy performing a NVM operation, such as a FLASH page read.
*
* \return Boolean true if the NVM controller became ready within the timeout period, false otherwise
*/
bool TINYNVM_WaitWhileNVMBusBusy(void)
{
/* Poll the STATUS register to check to see if NVM access has been enabled */
while (TimeoutMSRemaining)
{
/* Send the SLDCS command to read the TPI STATUS register to see the NVM bus is active */
XPROGTarget_SendByte(TPI_CMD_SLDCS | TPI_STATUS_REG);
uint8_t StatusRegister = XPROGTarget_ReceiveByte();
/* We might have timed out waiting for the status register read response, check here */
if (!(TimeoutMSRemaining))
return false;
/* Check the status register read response to see if the NVM bus is enabled */
if (StatusRegister & TPI_STATUS_NVM)
{
TimeoutMSRemaining = COMMAND_TIMEOUT_MS;
return true;
}
}
return false;
}
/** 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 TINYNVM_WaitWhileNVMControllerBusy(void)
{
/* Poll the STATUS register to check to see if NVM access has been enabled */
while (TimeoutMSRemaining)
{
/* Send the SIN command to read the TPI STATUS register to see the NVM bus is busy */
TINYNVM_SendReadNVMRegister(XPROG_Param_NVMCSRRegAddr);
uint8_t StatusRegister = XPROGTarget_ReceiveByte();
/* We might have timed out waiting for the status register read response, check here */
if (!(TimeoutMSRemaining))
return false;
/* Check to see if the BUSY flag is still set */
if (!(StatusRegister & (1 << 7)))
{
TimeoutMSRemaining = COMMAND_TIMEOUT_MS;
return true;
}
}
return false;
}
/** 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 Length of the data to read from the device
*
* \return Boolean true if the command sequence complete successfully
*/
bool TINYNVM_ReadMemory(const uint16_t ReadAddress, uint8_t* ReadBuffer, uint16_t ReadSize)
{
/* Wait until the NVM controller is no longer busy */
if (!(TINYNVM_WaitWhileNVMControllerBusy()))
return false;
/* Set the NVM control register to the NO OP command for memory reading */
TINYNVM_SendWriteNVMRegister(XPROG_Param_NVMCMDRegAddr);
XPROGTarget_SendByte(TINY_NVM_CMD_NOOP);
/* Send the address of the location to read from */
TINYNVM_SendPointerAddress(ReadAddress);
while (ReadSize-- && TimeoutMSRemaining)
{
/* Read the byte of data from the target */
XPROGTarget_SendByte(TPI_CMD_SLD | TPI_POINTER_INDIRECT_PI);
*(ReadBuffer++) = XPROGTarget_ReceiveByte();
}
return (TimeoutMSRemaining != 0);
}
/** Writes word addressed memory to the target's memory spaces.
*
* \param[in] WriteAddress Start address to write to within the target's address space
* \param[in] WriteBuffer Buffer to source data from
* \param[in] WriteLength Total number of bytes to write to the device (must be an integer multiple of 2)
*
* \return Boolean true if the command sequence complete successfully
*/
bool TINYNVM_WriteMemory(const uint16_t WriteAddress, uint8_t* WriteBuffer, uint16_t WriteLength)
{
/* Wait until the NVM controller is no longer busy */
if (!(TINYNVM_WaitWhileNVMControllerBusy()))
return false;
/* Must have an integer number of words to write - if extra byte, word-align via a dummy high byte */
if (WriteLength & 0x01)
WriteBuffer[WriteLength++] = 0xFF;
/* Set the NVM control register to the WORD WRITE command for memory reading */
TINYNVM_SendWriteNVMRegister(XPROG_Param_NVMCMDRegAddr);
XPROGTarget_SendByte(TINY_NVM_CMD_WORDWRITE);
/* Send the address of the location to write to */
TINYNVM_SendPointerAddress(WriteAddress);
while (WriteLength)
{
/* Wait until the NVM controller is no longer busy */
if (!(TINYNVM_WaitWhileNVMControllerBusy()))
return false;
/* Write the low byte of data to the target */
XPROGTarget_SendByte(TPI_CMD_SST | TPI_POINTER_INDIRECT_PI);
XPROGTarget_SendByte(*(WriteBuffer++));
/* Write the high byte of data to the target */
XPROGTarget_SendByte(TPI_CMD_SST | TPI_POINTER_INDIRECT_PI);
XPROGTarget_SendByte(*(WriteBuffer++));
/* Need to decrement the write length twice, since we read out a whole word */
WriteLength -= 2;
}
return true;
}
/** Erases the target's memory space.
*
* \param[in] EraseCommand NVM erase command to send to the device
* \param[in] Address Address inside the memory space to erase
*
* \return Boolean true if the command sequence complete successfully
*/
bool TINYNVM_EraseMemory(const uint8_t EraseCommand, const uint16_t Address)
{
/* Wait until the NVM controller is no longer busy */
if (!(TINYNVM_WaitWhileNVMControllerBusy()))
return false;
/* Set the NVM control register to the target memory erase command */
TINYNVM_SendWriteNVMRegister(XPROG_Param_NVMCMDRegAddr);
XPROGTarget_SendByte(EraseCommand);
/* Write to a high byte location within the target address space to start the erase process */
TINYNVM_SendPointerAddress(Address | 0x0001);
XPROGTarget_SendByte(TPI_CMD_SST | TPI_POINTER_INDIRECT);
XPROGTarget_SendByte(0x00);
/* Wait until the NVM controller is no longer busy */
if (!(TINYNVM_WaitWhileNVMControllerBusy()))
return false;
return true;
}
#endif
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of
this software.
*/
/** \file
*
* Target-related functions for the TINY target's NVM module.
*/
#define INCLUDE_FROM_TINYNVM_C
#include "TINYNVM.h"
#if defined(ENABLE_XPROG_PROTOCOL) || defined(__DOXYGEN__)
/** Sends the given pointer address to the target's TPI pointer register */
static void TINYNVM_SendPointerAddress(const uint16_t AbsoluteAddress)
{
/* Send the given 16-bit address to the target, LSB first */
XPROGTarget_SendByte(TPI_CMD_SSTPR | 0);
XPROGTarget_SendByte(((uint8_t*)&AbsoluteAddress)[0]);
XPROGTarget_SendByte(TPI_CMD_SSTPR | 1);
XPROGTarget_SendByte(((uint8_t*)&AbsoluteAddress)[1]);
}
/** Sends a SIN command to the target with the specified I/O address, ready for the data byte to be written.
*
* \param[in] Address 6-bit I/O address to write to in the target's I/O memory space
*/
static void TINYNVM_SendReadNVMRegister(const uint8_t Address)
{
/* The TPI command for reading from the I/O space uses strange addressing, where the I/O address's upper
* two bits of the 6-bit address are shifted left once */
XPROGTarget_SendByte(TPI_CMD_SIN | ((Address & 0x30) << 1) | (Address & 0x0F));
}
/** Sends a SOUT command to the target with the specified I/O address, ready for the data byte to be read.
*
* \param[in] Address 6-bit I/O address to read from in the target's I/O memory space
*/
static void TINYNVM_SendWriteNVMRegister(const uint8_t Address)
{
/* The TPI command for reading from the I/O space uses strange addressing, where the I/O address's upper
* two bits of the 6-bit address are shifted left once */
XPROGTarget_SendByte(TPI_CMD_SOUT | ((Address & 0x30) << 1) | (Address & 0x0F));
}
/** Busy-waits while the NVM controller is busy performing a NVM operation, such as a FLASH page read.
*
* \return Boolean true if the NVM controller became ready within the timeout period, false otherwise
*/
bool TINYNVM_WaitWhileNVMBusBusy(void)
{
/* Poll the STATUS register to check to see if NVM access has been enabled */
while (TimeoutMSRemaining)
{
/* Send the SLDCS command to read the TPI STATUS register to see the NVM bus is active */
XPROGTarget_SendByte(TPI_CMD_SLDCS | TPI_STATUS_REG);
uint8_t StatusRegister = XPROGTarget_ReceiveByte();
/* We might have timed out waiting for the status register read response, check here */
if (!(TimeoutMSRemaining))
return false;
/* Check the status register read response to see if the NVM bus is enabled */
if (StatusRegister & TPI_STATUS_NVM)
{
TimeoutMSRemaining = COMMAND_TIMEOUT_MS;
return true;
}
}
return false;
}
/** 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 TINYNVM_WaitWhileNVMControllerBusy(void)
{
/* Poll the STATUS register to check to see if NVM access has been enabled */
while (TimeoutMSRemaining)
{
/* Send the SIN command to read the TPI STATUS register to see the NVM bus is busy */
TINYNVM_SendReadNVMRegister(XPROG_Param_NVMCSRRegAddr);
uint8_t StatusRegister = XPROGTarget_ReceiveByte();
/* We might have timed out waiting for the status register read response, check here */
if (!(TimeoutMSRemaining))
return false;
/* Check to see if the BUSY flag is still set */
if (!(StatusRegister & (1 << 7)))
{
TimeoutMSRemaining = COMMAND_TIMEOUT_MS;
return true;
}
}
return false;
}
/** 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 Length of the data to read from the device
*
* \return Boolean true if the command sequence complete successfully
*/
bool TINYNVM_ReadMemory(const uint16_t ReadAddress, uint8_t* ReadBuffer, uint16_t ReadSize)
{
/* Wait until the NVM controller is no longer busy */
if (!(TINYNVM_WaitWhileNVMControllerBusy()))
return false;
/* Set the NVM control register to the NO OP command for memory reading */
TINYNVM_SendWriteNVMRegister(XPROG_Param_NVMCMDRegAddr);
XPROGTarget_SendByte(TINY_NVM_CMD_NOOP);
/* Send the address of the location to read from */
TINYNVM_SendPointerAddress(ReadAddress);
while (ReadSize-- && TimeoutMSRemaining)
{
/* Read the byte of data from the target */
XPROGTarget_SendByte(TPI_CMD_SLD | TPI_POINTER_INDIRECT_PI);
*(ReadBuffer++) = XPROGTarget_ReceiveByte();
}
return (TimeoutMSRemaining != 0);
}
/** Writes word addressed memory to the target's memory spaces.
*
* \param[in] WriteAddress Start address to write to within the target's address space
* \param[in] WriteBuffer Buffer to source data from
* \param[in] WriteLength Total number of bytes to write to the device (must be an integer multiple of 2)
*
* \return Boolean true if the command sequence complete successfully
*/
bool TINYNVM_WriteMemory(const uint16_t WriteAddress, uint8_t* WriteBuffer, uint16_t WriteLength)
{
/* Wait until the NVM controller is no longer busy */
if (!(TINYNVM_WaitWhileNVMControllerBusy()))
return false;
/* Must have an integer number of words to write - if extra byte, word-align via a dummy high byte */
if (WriteLength & 0x01)
WriteBuffer[WriteLength++] = 0xFF;
/* Set the NVM control register to the WORD WRITE command for memory reading */
TINYNVM_SendWriteNVMRegister(XPROG_Param_NVMCMDRegAddr);
XPROGTarget_SendByte(TINY_NVM_CMD_WORDWRITE);
/* Send the address of the location to write to */
TINYNVM_SendPointerAddress(WriteAddress);
while (WriteLength)
{
/* Wait until the NVM controller is no longer busy */
if (!(TINYNVM_WaitWhileNVMControllerBusy()))
return false;
/* Write the low byte of data to the target */
XPROGTarget_SendByte(TPI_CMD_SST | TPI_POINTER_INDIRECT_PI);
XPROGTarget_SendByte(*(WriteBuffer++));
/* Write the high byte of data to the target */
XPROGTarget_SendByte(TPI_CMD_SST | TPI_POINTER_INDIRECT_PI);
XPROGTarget_SendByte(*(WriteBuffer++));
/* Need to decrement the write length twice, since we read out a whole word */
WriteLength -= 2;
}
return true;
}
/** Erases the target's memory space.
*
* \param[in] EraseCommand NVM erase command to send to the device
* \param[in] Address Address inside the memory space to erase
*
* \return Boolean true if the command sequence complete successfully
*/
bool TINYNVM_EraseMemory(const uint8_t EraseCommand, const uint16_t Address)
{
/* Wait until the NVM controller is no longer busy */
if (!(TINYNVM_WaitWhileNVMControllerBusy()))
return false;
/* Set the NVM control register to the target memory erase command */
TINYNVM_SendWriteNVMRegister(XPROG_Param_NVMCMDRegAddr);
XPROGTarget_SendByte(EraseCommand);
/* Write to a high byte location within the target address space to start the erase process */
TINYNVM_SendPointerAddress(Address | 0x0001);
XPROGTarget_SendByte(TPI_CMD_SST | TPI_POINTER_INDIRECT);
XPROGTarget_SendByte(0x00);
/* Wait until the NVM controller is no longer busy */
if (!(TINYNVM_WaitWhileNVMControllerBusy()))
return false;
return true;
}
#endif

View file

@ -1,77 +1,77 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of
this software.
*/
/** \file
*
* Header file for TINYNVM.c.
*/
#ifndef _TINY_NVM_
#define _TINY_NVM_
/* Includes: */
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdbool.h>
#include <LUFA/Common/Common.h>
#include "XPROGProtocol.h"
#include "XPROGTarget.h"
/* Preprocessor Checks: */
#if ((BOARD == BOARD_XPLAIN) || (BOARD == BOARD_XPLAIN_REV1))
#undef ENABLE_ISP_PROTOCOL
#if !defined(ENABLE_XPROG_PROTOCOL)
#define ENABLE_XPROG_PROTOCOL
#endif
#endif
/* Defines: */
#define TINY_NVM_CMD_NOOP 0x00
#define TINY_NVM_CMD_CHIPERASE 0x10
#define TINY_NVM_CMD_SECTIONERASE 0x14
#define TINY_NVM_CMD_WORDWRITE 0x1D
/* Function Prototypes: */
bool TINYNVM_WaitWhileNVMBusBusy(void);
bool TINYNVM_WaitWhileNVMControllerBusy(void);
bool TINYNVM_ReadMemory(const uint16_t ReadAddress, uint8_t* ReadBuffer, uint16_t ReadLength);
bool TINYNVM_WriteMemory(const uint16_t WriteAddress, uint8_t* WriteBuffer, uint16_t WriteLength);
bool TINYNVM_EraseMemory(const uint8_t EraseCommand, const uint16_t Address);
#if defined(INCLUDE_FROM_TINYNVM_C)
static void TINYNVM_SendReadNVMRegister(const uint8_t Address);
static void TINYNVM_SendWriteNVMRegister(const uint8_t Address);
static void TINYNVM_SendPointerAddress(const uint16_t AbsoluteAddress);
#endif
#endif
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of
this software.
*/
/** \file
*
* Header file for TINYNVM.c.
*/
#ifndef _TINY_NVM_
#define _TINY_NVM_
/* Includes: */
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdbool.h>
#include <LUFA/Common/Common.h>
#include "XPROGProtocol.h"
#include "XPROGTarget.h"
/* Preprocessor Checks: */
#if ((BOARD == BOARD_XPLAIN) || (BOARD == BOARD_XPLAIN_REV1))
#undef ENABLE_ISP_PROTOCOL
#if !defined(ENABLE_XPROG_PROTOCOL)
#define ENABLE_XPROG_PROTOCOL
#endif
#endif
/* Defines: */
#define TINY_NVM_CMD_NOOP 0x00
#define TINY_NVM_CMD_CHIPERASE 0x10
#define TINY_NVM_CMD_SECTIONERASE 0x14
#define TINY_NVM_CMD_WORDWRITE 0x1D
/* Function Prototypes: */
bool TINYNVM_WaitWhileNVMBusBusy(void);
bool TINYNVM_WaitWhileNVMControllerBusy(void);
bool TINYNVM_ReadMemory(const uint16_t ReadAddress, uint8_t* ReadBuffer, uint16_t ReadLength);
bool TINYNVM_WriteMemory(const uint16_t WriteAddress, uint8_t* WriteBuffer, uint16_t WriteLength);
bool TINYNVM_EraseMemory(const uint8_t EraseCommand, const uint16_t Address);
#if defined(INCLUDE_FROM_TINYNVM_C)
static void TINYNVM_SendReadNVMRegister(const uint8_t Address);
static void TINYNVM_SendWriteNVMRegister(const uint8_t Address);
static void TINYNVM_SendPointerAddress(const uint16_t AbsoluteAddress);
#endif
#endif

View file

@ -1,356 +1,356 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of
this software.
*/
/** \file
*
* Target-related functions for the XMEGA target's NVM module.
*/
#define INCLUDE_FROM_XMEGA_NVM_C
#include "XMEGANVM.h"
#if defined(ENABLE_XPROG_PROTOCOL) || defined(__DOXYGEN__)
/** Sends the given 32-bit absolute address to the target.
*
* \param[in] AbsoluteAddress Absolute address to send to the target
*/
static void XMEGANVM_SendAddress(const uint32_t AbsoluteAddress)
{
/* Send the given 32-bit address to the target, LSB first */
XPROGTarget_SendByte(((uint8_t*)&AbsoluteAddress)[0]);
XPROGTarget_SendByte(((uint8_t*)&AbsoluteAddress)[1]);
XPROGTarget_SendByte(((uint8_t*)&AbsoluteAddress)[2]);
XPROGTarget_SendByte(((uint8_t*)&AbsoluteAddress)[3]);
}
/** Sends the given NVM register address to the target.
*
* \param[in] Register NVM register whose absolute address is to be sent
*/
static void XMEGANVM_SendNVMRegAddress(const uint8_t Register)
{
/* Determine the absolute register address from the NVM base memory address and the NVM register address */
uint32_t Address = XPROG_Param_NVMBase | Register;
/* Send the calculated 32-bit address to the target, LSB first */
XMEGANVM_SendAddress(Address);
}
/** 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 XMEGANVM_WaitWhileNVMBusBusy(void)
{
/* Poll the STATUS register to check to see if NVM access has been enabled */
while (TimeoutMSRemaining)
{
/* Send the LDCS command to read the PDI STATUS register to see the NVM bus is active */
XPROGTarget_SendByte(PDI_CMD_LDCS | PDI_STATUS_REG);
uint8_t StatusRegister = XPROGTarget_ReceiveByte();
/* We might have timed out waiting for the status register read response, check here */
if (!(TimeoutMSRemaining))
return false;
/* Check the status register read response to see if the NVM bus is enabled */
if (StatusRegister & PDI_STATUS_NVM)
{
TimeoutMSRemaining = COMMAND_TIMEOUT_MS;
return true;
}
}
return false;
}
/** 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 XMEGANVM_WaitWhileNVMControllerBusy(void)
{
/* Poll the NVM STATUS register while the NVM controller is busy */
while (TimeoutMSRemaining)
{
/* Send a LDS command to read the NVM STATUS register to check the BUSY flag */
XPROGTarget_SendByte(PDI_CMD_LDS | (PDI_DATSIZE_4BYTES << 2));
XMEGANVM_SendNVMRegAddress(XMEGA_NVM_REG_STATUS);
uint8_t StatusRegister = XPROGTarget_ReceiveByte();
/* We might have timed out waiting for the status register read response, check here */
if (!(TimeoutMSRemaining))
return false;
/* Check to see if the BUSY flag is still set */
if (!(StatusRegister & (1 << 7)))
{
TimeoutMSRemaining = COMMAND_TIMEOUT_MS;
return true;
}
}
return false;
}
/** Retrieves the CRC value of the given memory space.
*
* \param[in] CRCCommand NVM CRC command to issue to the target
* \param[out] CRCDest CRC Destination when read from the target
*
* \return Boolean true if the command sequence complete successfully
*/
bool XMEGANVM_GetMemoryCRC(const uint8_t CRCCommand, uint32_t* const CRCDest)
{
/* Wait until the NVM controller is no longer busy */
if (!(XMEGANVM_WaitWhileNVMControllerBusy()))
return false;
/* Set the NVM command to the correct CRC read command */
XPROGTarget_SendByte(PDI_CMD_STS | (PDI_DATSIZE_4BYTES << 2));
XMEGANVM_SendNVMRegAddress(XMEGA_NVM_REG_CMD);
XPROGTarget_SendByte(CRCCommand);
/* Set CMDEX bit in NVM CTRLA register to start the CRC generation */
XPROGTarget_SendByte(PDI_CMD_STS | (PDI_DATSIZE_4BYTES << 2));
XMEGANVM_SendNVMRegAddress(XMEGA_NVM_REG_CTRLA);
XPROGTarget_SendByte(1 << 0);
/* Wait until the NVM bus is ready again */
if (!(XMEGANVM_WaitWhileNVMBusBusy()))
return false;
/* Wait until the NVM controller is no longer busy */
if (!(XMEGANVM_WaitWhileNVMControllerBusy()))
return false;
/* Load the PDI pointer register with the DAT0 register start address */
XPROGTarget_SendByte(PDI_CMD_ST | (PDI_POINTER_DIRECT << 2) | PDI_DATSIZE_4BYTES);
XMEGANVM_SendNVMRegAddress(XMEGA_NVM_REG_DAT0);
/* Send the REPEAT command to grab the CRC bytes */
XPROGTarget_SendByte(PDI_CMD_REPEAT | PDI_DATSIZE_1BYTE);
XPROGTarget_SendByte(XMEGA_CRC_LENGTH - 1);
/* Read in the CRC bytes from the target */
XPROGTarget_SendByte(PDI_CMD_LD | (PDI_POINTER_INDIRECT_PI << 2) | PDI_DATSIZE_1BYTE);
for (uint8_t i = 0; i < XMEGA_CRC_LENGTH; i++)
((uint8_t*)CRCDest)[i] = XPROGTarget_ReceiveByte();
return (TimeoutMSRemaining != 0);
}
/** 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
*
* \return Boolean true if the command sequence complete successfully
*/
bool XMEGANVM_ReadMemory(const uint32_t ReadAddress, uint8_t* ReadBuffer, uint16_t ReadSize)
{
/* Wait until the NVM controller is no longer busy */
if (!(XMEGANVM_WaitWhileNVMControllerBusy()))
return false;
/* Send the READNVM command to the NVM controller for reading of an arbitrary location */
XPROGTarget_SendByte(PDI_CMD_STS | (PDI_DATSIZE_4BYTES << 2));
XMEGANVM_SendNVMRegAddress(XMEGA_NVM_REG_CMD);
XPROGTarget_SendByte(XMEGA_NVM_CMD_READNVM);
/* Load the PDI pointer register with the start address we want to read from */
XPROGTarget_SendByte(PDI_CMD_ST | (PDI_POINTER_DIRECT << 2) | PDI_DATSIZE_4BYTES);
XMEGANVM_SendAddress(ReadAddress);
/* Send the REPEAT command with the specified number of bytes to read */
XPROGTarget_SendByte(PDI_CMD_REPEAT | PDI_DATSIZE_1BYTE);
XPROGTarget_SendByte(ReadSize - 1);
/* Send a LD command with indirect access and postincrement to read out the bytes */
XPROGTarget_SendByte(PDI_CMD_LD | (PDI_POINTER_INDIRECT_PI << 2) | PDI_DATSIZE_1BYTE);
while (ReadSize-- && TimeoutMSRemaining)
*(ReadBuffer++) = XPROGTarget_ReceiveByte();
return (TimeoutMSRemaining != 0);
}
/** Writes byte addressed memory to the target's memory spaces.
*
* \param[in] WriteCommand Command to send to the device to write each memory byte
* \param[in] WriteAddress Address to write to within the target's address space
* \param[in] Byte Byte to write to the target
*
* \return Boolean true if the command sequence complete successfully
*/
bool XMEGANVM_WriteByteMemory(const uint8_t WriteCommand, const uint32_t WriteAddress, const uint8_t Byte)
{
/* Wait until the NVM controller is no longer busy */
if (!(XMEGANVM_WaitWhileNVMControllerBusy()))
return false;
/* Send the memory write command to the target */
XPROGTarget_SendByte(PDI_CMD_STS | (PDI_DATSIZE_4BYTES << 2));
XMEGANVM_SendNVMRegAddress(XMEGA_NVM_REG_CMD);
XPROGTarget_SendByte(WriteCommand);
/* Send new memory byte to the memory to the target */
XPROGTarget_SendByte(PDI_CMD_STS | (PDI_DATSIZE_4BYTES << 2));
XMEGANVM_SendAddress(WriteAddress);
XPROGTarget_SendByte(Byte);
return true;
}
/** Writes page addressed memory to the target's memory spaces.
*
* \param[in] WriteBuffCommand Command to send to the device to write a byte to the memory page buffer
* \param[in] EraseBuffCommand Command to send to the device to erase the memory page buffer
* \param[in] WritePageCommand Command to send to the device to write the page buffer to the destination memory
* \param[in] PageMode Bitfield indicating what operations need to be executed on the specified page
* \param[in] WriteAddress Start address to write the page data to within the target's address space
* \param[in] WriteBuffer Buffer to source data from
* \param[in] WriteSize Number of bytes to write
*
* \return Boolean true if the command sequence complete successfully
*/
bool XMEGANVM_WritePageMemory(const uint8_t WriteBuffCommand, const uint8_t EraseBuffCommand,
const uint8_t WritePageCommand, const uint8_t PageMode, const uint32_t WriteAddress,
const uint8_t* WriteBuffer, uint16_t WriteSize)
{
if (PageMode & XPRG_PAGEMODE_ERASE)
{
/* Wait until the NVM controller is no longer busy */
if (!(XMEGANVM_WaitWhileNVMControllerBusy()))
return false;
/* Send the memory buffer erase command to the target */
XPROGTarget_SendByte(PDI_CMD_STS | (PDI_DATSIZE_4BYTES << 2));
XMEGANVM_SendNVMRegAddress(XMEGA_NVM_REG_CMD);
XPROGTarget_SendByte(EraseBuffCommand);
/* Set CMDEX bit in NVM CTRLA register to start the buffer erase */
XPROGTarget_SendByte(PDI_CMD_STS | (PDI_DATSIZE_4BYTES << 2));
XMEGANVM_SendNVMRegAddress(XMEGA_NVM_REG_CTRLA);
XPROGTarget_SendByte(1 << 0);
}
if (WriteSize)
{
/* Wait until the NVM controller is no longer busy */
if (!(XMEGANVM_WaitWhileNVMControllerBusy()))
return false;
/* Send the memory buffer write command to the target */
XPROGTarget_SendByte(PDI_CMD_STS | (PDI_DATSIZE_4BYTES << 2));
XMEGANVM_SendNVMRegAddress(XMEGA_NVM_REG_CMD);
XPROGTarget_SendByte(WriteBuffCommand);
/* Load the PDI pointer register with the start address we want to write to */
XPROGTarget_SendByte(PDI_CMD_ST | (PDI_POINTER_DIRECT << 2) | PDI_DATSIZE_4BYTES);
XMEGANVM_SendAddress(WriteAddress);
/* Send the REPEAT command with the specified number of bytes to write */
XPROGTarget_SendByte(PDI_CMD_REPEAT | PDI_DATSIZE_1BYTE);
XPROGTarget_SendByte(WriteSize - 1);
/* Send a ST command with indirect access and postincrement to write the bytes */
XPROGTarget_SendByte(PDI_CMD_ST | (PDI_POINTER_INDIRECT_PI << 2) | PDI_DATSIZE_1BYTE);
while (WriteSize--)
XPROGTarget_SendByte(*(WriteBuffer++));
}
if (PageMode & XPRG_PAGEMODE_WRITE)
{
/* Wait until the NVM controller is no longer busy */
if (!(XMEGANVM_WaitWhileNVMControllerBusy()))
return false;
/* Send the memory write command to the target */
XPROGTarget_SendByte(PDI_CMD_STS | (PDI_DATSIZE_4BYTES << 2));
XMEGANVM_SendNVMRegAddress(XMEGA_NVM_REG_CMD);
XPROGTarget_SendByte(WritePageCommand);
/* Send the address of the first page location to write the memory page */
XPROGTarget_SendByte(PDI_CMD_STS | (PDI_DATSIZE_4BYTES << 2));
XMEGANVM_SendAddress(WriteAddress);
XPROGTarget_SendByte(0x00);
}
return true;
}
/** 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
*
* \return Boolean true if the command sequence complete successfully
*/
bool XMEGANVM_EraseMemory(const uint8_t EraseCommand, const uint32_t Address)
{
/* Wait until the NVM controller is no longer busy */
if (!(XMEGANVM_WaitWhileNVMControllerBusy()))
return false;
/* Send the memory erase command to the target */
XPROGTarget_SendByte(PDI_CMD_STS | (PDI_DATSIZE_4BYTES << 2));
XMEGANVM_SendNVMRegAddress(XMEGA_NVM_REG_CMD);
XPROGTarget_SendByte(EraseCommand);
/* Chip erase is handled separately, since it's procedure is different to other erase types */
if (EraseCommand == XMEGA_NVM_CMD_CHIPERASE)
{
/* Set CMDEX bit in NVM CTRLA register to start the chip erase */
XPROGTarget_SendByte(PDI_CMD_STS | (PDI_DATSIZE_4BYTES << 2));
XMEGANVM_SendNVMRegAddress(XMEGA_NVM_REG_CTRLA);
XPROGTarget_SendByte(1 << 0);
}
else
{
/* Other erase modes just need us to address a byte within the target memory space */
XPROGTarget_SendByte(PDI_CMD_STS | (PDI_DATSIZE_4BYTES << 2));
XMEGANVM_SendAddress(Address);
XPROGTarget_SendByte(0x00);
}
/* Wait until the NVM bus is ready again */
if (!(XMEGANVM_WaitWhileNVMBusBusy()))
return false;
return true;
}
#endif
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of
this software.
*/
/** \file
*
* Target-related functions for the XMEGA target's NVM module.
*/
#define INCLUDE_FROM_XMEGA_NVM_C
#include "XMEGANVM.h"
#if defined(ENABLE_XPROG_PROTOCOL) || defined(__DOXYGEN__)
/** Sends the given 32-bit absolute address to the target.
*
* \param[in] AbsoluteAddress Absolute address to send to the target
*/
static void XMEGANVM_SendAddress(const uint32_t AbsoluteAddress)
{
/* Send the given 32-bit address to the target, LSB first */
XPROGTarget_SendByte(((uint8_t*)&AbsoluteAddress)[0]);
XPROGTarget_SendByte(((uint8_t*)&AbsoluteAddress)[1]);
XPROGTarget_SendByte(((uint8_t*)&AbsoluteAddress)[2]);
XPROGTarget_SendByte(((uint8_t*)&AbsoluteAddress)[3]);
}
/** Sends the given NVM register address to the target.
*
* \param[in] Register NVM register whose absolute address is to be sent
*/
static void XMEGANVM_SendNVMRegAddress(const uint8_t Register)
{
/* Determine the absolute register address from the NVM base memory address and the NVM register address */
uint32_t Address = XPROG_Param_NVMBase | Register;
/* Send the calculated 32-bit address to the target, LSB first */
XMEGANVM_SendAddress(Address);
}
/** 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 XMEGANVM_WaitWhileNVMBusBusy(void)
{
/* Poll the STATUS register to check to see if NVM access has been enabled */
while (TimeoutMSRemaining)
{
/* Send the LDCS command to read the PDI STATUS register to see the NVM bus is active */
XPROGTarget_SendByte(PDI_CMD_LDCS | PDI_STATUS_REG);
uint8_t StatusRegister = XPROGTarget_ReceiveByte();
/* We might have timed out waiting for the status register read response, check here */
if (!(TimeoutMSRemaining))
return false;
/* Check the status register read response to see if the NVM bus is enabled */
if (StatusRegister & PDI_STATUS_NVM)
{
TimeoutMSRemaining = COMMAND_TIMEOUT_MS;
return true;
}
}
return false;
}
/** 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 XMEGANVM_WaitWhileNVMControllerBusy(void)
{
/* Poll the NVM STATUS register while the NVM controller is busy */
while (TimeoutMSRemaining)
{
/* Send a LDS command to read the NVM STATUS register to check the BUSY flag */
XPROGTarget_SendByte(PDI_CMD_LDS | (PDI_DATSIZE_4BYTES << 2));
XMEGANVM_SendNVMRegAddress(XMEGA_NVM_REG_STATUS);
uint8_t StatusRegister = XPROGTarget_ReceiveByte();
/* We might have timed out waiting for the status register read response, check here */
if (!(TimeoutMSRemaining))
return false;
/* Check to see if the BUSY flag is still set */
if (!(StatusRegister & (1 << 7)))
{
TimeoutMSRemaining = COMMAND_TIMEOUT_MS;
return true;
}
}
return false;
}
/** Retrieves the CRC value of the given memory space.
*
* \param[in] CRCCommand NVM CRC command to issue to the target
* \param[out] CRCDest CRC Destination when read from the target
*
* \return Boolean true if the command sequence complete successfully
*/
bool XMEGANVM_GetMemoryCRC(const uint8_t CRCCommand, uint32_t* const CRCDest)
{
/* Wait until the NVM controller is no longer busy */
if (!(XMEGANVM_WaitWhileNVMControllerBusy()))
return false;
/* Set the NVM command to the correct CRC read command */
XPROGTarget_SendByte(PDI_CMD_STS | (PDI_DATSIZE_4BYTES << 2));
XMEGANVM_SendNVMRegAddress(XMEGA_NVM_REG_CMD);
XPROGTarget_SendByte(CRCCommand);
/* Set CMDEX bit in NVM CTRLA register to start the CRC generation */
XPROGTarget_SendByte(PDI_CMD_STS | (PDI_DATSIZE_4BYTES << 2));
XMEGANVM_SendNVMRegAddress(XMEGA_NVM_REG_CTRLA);
XPROGTarget_SendByte(1 << 0);
/* Wait until the NVM bus is ready again */
if (!(XMEGANVM_WaitWhileNVMBusBusy()))
return false;
/* Wait until the NVM controller is no longer busy */
if (!(XMEGANVM_WaitWhileNVMControllerBusy()))
return false;
/* Load the PDI pointer register with the DAT0 register start address */
XPROGTarget_SendByte(PDI_CMD_ST | (PDI_POINTER_DIRECT << 2) | PDI_DATSIZE_4BYTES);
XMEGANVM_SendNVMRegAddress(XMEGA_NVM_REG_DAT0);
/* Send the REPEAT command to grab the CRC bytes */
XPROGTarget_SendByte(PDI_CMD_REPEAT | PDI_DATSIZE_1BYTE);
XPROGTarget_SendByte(XMEGA_CRC_LENGTH - 1);
/* Read in the CRC bytes from the target */
XPROGTarget_SendByte(PDI_CMD_LD | (PDI_POINTER_INDIRECT_PI << 2) | PDI_DATSIZE_1BYTE);
for (uint8_t i = 0; i < XMEGA_CRC_LENGTH; i++)
((uint8_t*)CRCDest)[i] = XPROGTarget_ReceiveByte();
return (TimeoutMSRemaining != 0);
}
/** 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
*
* \return Boolean true if the command sequence complete successfully
*/
bool XMEGANVM_ReadMemory(const uint32_t ReadAddress, uint8_t* ReadBuffer, uint16_t ReadSize)
{
/* Wait until the NVM controller is no longer busy */
if (!(XMEGANVM_WaitWhileNVMControllerBusy()))
return false;
/* Send the READNVM command to the NVM controller for reading of an arbitrary location */
XPROGTarget_SendByte(PDI_CMD_STS | (PDI_DATSIZE_4BYTES << 2));
XMEGANVM_SendNVMRegAddress(XMEGA_NVM_REG_CMD);
XPROGTarget_SendByte(XMEGA_NVM_CMD_READNVM);
/* Load the PDI pointer register with the start address we want to read from */
XPROGTarget_SendByte(PDI_CMD_ST | (PDI_POINTER_DIRECT << 2) | PDI_DATSIZE_4BYTES);
XMEGANVM_SendAddress(ReadAddress);
/* Send the REPEAT command with the specified number of bytes to read */
XPROGTarget_SendByte(PDI_CMD_REPEAT | PDI_DATSIZE_1BYTE);
XPROGTarget_SendByte(ReadSize - 1);
/* Send a LD command with indirect access and postincrement to read out the bytes */
XPROGTarget_SendByte(PDI_CMD_LD | (PDI_POINTER_INDIRECT_PI << 2) | PDI_DATSIZE_1BYTE);
while (ReadSize-- && TimeoutMSRemaining)
*(ReadBuffer++) = XPROGTarget_ReceiveByte();
return (TimeoutMSRemaining != 0);
}
/** Writes byte addressed memory to the target's memory spaces.
*
* \param[in] WriteCommand Command to send to the device to write each memory byte
* \param[in] WriteAddress Address to write to within the target's address space
* \param[in] Byte Byte to write to the target
*
* \return Boolean true if the command sequence complete successfully
*/
bool XMEGANVM_WriteByteMemory(const uint8_t WriteCommand, const uint32_t WriteAddress, const uint8_t Byte)
{
/* Wait until the NVM controller is no longer busy */
if (!(XMEGANVM_WaitWhileNVMControllerBusy()))
return false;
/* Send the memory write command to the target */
XPROGTarget_SendByte(PDI_CMD_STS | (PDI_DATSIZE_4BYTES << 2));
XMEGANVM_SendNVMRegAddress(XMEGA_NVM_REG_CMD);
XPROGTarget_SendByte(WriteCommand);
/* Send new memory byte to the memory to the target */
XPROGTarget_SendByte(PDI_CMD_STS | (PDI_DATSIZE_4BYTES << 2));
XMEGANVM_SendAddress(WriteAddress);
XPROGTarget_SendByte(Byte);
return true;
}
/** Writes page addressed memory to the target's memory spaces.
*
* \param[in] WriteBuffCommand Command to send to the device to write a byte to the memory page buffer
* \param[in] EraseBuffCommand Command to send to the device to erase the memory page buffer
* \param[in] WritePageCommand Command to send to the device to write the page buffer to the destination memory
* \param[in] PageMode Bitfield indicating what operations need to be executed on the specified page
* \param[in] WriteAddress Start address to write the page data to within the target's address space
* \param[in] WriteBuffer Buffer to source data from
* \param[in] WriteSize Number of bytes to write
*
* \return Boolean true if the command sequence complete successfully
*/
bool XMEGANVM_WritePageMemory(const uint8_t WriteBuffCommand, const uint8_t EraseBuffCommand,
const uint8_t WritePageCommand, const uint8_t PageMode, const uint32_t WriteAddress,
const uint8_t* WriteBuffer, uint16_t WriteSize)
{
if (PageMode & XPRG_PAGEMODE_ERASE)
{
/* Wait until the NVM controller is no longer busy */
if (!(XMEGANVM_WaitWhileNVMControllerBusy()))
return false;
/* Send the memory buffer erase command to the target */
XPROGTarget_SendByte(PDI_CMD_STS | (PDI_DATSIZE_4BYTES << 2));
XMEGANVM_SendNVMRegAddress(XMEGA_NVM_REG_CMD);
XPROGTarget_SendByte(EraseBuffCommand);
/* Set CMDEX bit in NVM CTRLA register to start the buffer erase */
XPROGTarget_SendByte(PDI_CMD_STS | (PDI_DATSIZE_4BYTES << 2));
XMEGANVM_SendNVMRegAddress(XMEGA_NVM_REG_CTRLA);
XPROGTarget_SendByte(1 << 0);
}
if (WriteSize)
{
/* Wait until the NVM controller is no longer busy */
if (!(XMEGANVM_WaitWhileNVMControllerBusy()))
return false;
/* Send the memory buffer write command to the target */
XPROGTarget_SendByte(PDI_CMD_STS | (PDI_DATSIZE_4BYTES << 2));
XMEGANVM_SendNVMRegAddress(XMEGA_NVM_REG_CMD);
XPROGTarget_SendByte(WriteBuffCommand);
/* Load the PDI pointer register with the start address we want to write to */
XPROGTarget_SendByte(PDI_CMD_ST | (PDI_POINTER_DIRECT << 2) | PDI_DATSIZE_4BYTES);
XMEGANVM_SendAddress(WriteAddress);
/* Send the REPEAT command with the specified number of bytes to write */
XPROGTarget_SendByte(PDI_CMD_REPEAT | PDI_DATSIZE_1BYTE);
XPROGTarget_SendByte(WriteSize - 1);
/* Send a ST command with indirect access and postincrement to write the bytes */
XPROGTarget_SendByte(PDI_CMD_ST | (PDI_POINTER_INDIRECT_PI << 2) | PDI_DATSIZE_1BYTE);
while (WriteSize--)
XPROGTarget_SendByte(*(WriteBuffer++));
}
if (PageMode & XPRG_PAGEMODE_WRITE)
{
/* Wait until the NVM controller is no longer busy */
if (!(XMEGANVM_WaitWhileNVMControllerBusy()))
return false;
/* Send the memory write command to the target */
XPROGTarget_SendByte(PDI_CMD_STS | (PDI_DATSIZE_4BYTES << 2));
XMEGANVM_SendNVMRegAddress(XMEGA_NVM_REG_CMD);
XPROGTarget_SendByte(WritePageCommand);
/* Send the address of the first page location to write the memory page */
XPROGTarget_SendByte(PDI_CMD_STS | (PDI_DATSIZE_4BYTES << 2));
XMEGANVM_SendAddress(WriteAddress);
XPROGTarget_SendByte(0x00);
}
return true;
}
/** 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
*
* \return Boolean true if the command sequence complete successfully
*/
bool XMEGANVM_EraseMemory(const uint8_t EraseCommand, const uint32_t Address)
{
/* Wait until the NVM controller is no longer busy */
if (!(XMEGANVM_WaitWhileNVMControllerBusy()))
return false;
/* Send the memory erase command to the target */
XPROGTarget_SendByte(PDI_CMD_STS | (PDI_DATSIZE_4BYTES << 2));
XMEGANVM_SendNVMRegAddress(XMEGA_NVM_REG_CMD);
XPROGTarget_SendByte(EraseCommand);
/* Chip erase is handled separately, since it's procedure is different to other erase types */
if (EraseCommand == XMEGA_NVM_CMD_CHIPERASE)
{
/* Set CMDEX bit in NVM CTRLA register to start the chip erase */
XPROGTarget_SendByte(PDI_CMD_STS | (PDI_DATSIZE_4BYTES << 2));
XMEGANVM_SendNVMRegAddress(XMEGA_NVM_REG_CTRLA);
XPROGTarget_SendByte(1 << 0);
}
else
{
/* Other erase modes just need us to address a byte within the target memory space */
XPROGTarget_SendByte(PDI_CMD_STS | (PDI_DATSIZE_4BYTES << 2));
XMEGANVM_SendAddress(Address);
XPROGTarget_SendByte(0x00);
}
/* Wait until the NVM bus is ready again */
if (!(XMEGANVM_WaitWhileNVMBusBusy()))
return false;
return true;
}
#endif

View file

@ -1,124 +1,124 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of
this software.
*/
/** \file
*
* Header file for XMEGANVM.c.
*/
#ifndef _XMEGA_NVM_
#define _XMEGA_NVM_
/* Includes: */
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdbool.h>
#include <LUFA/Common/Common.h>
#include "XPROGProtocol.h"
#include "XPROGTarget.h"
/* Preprocessor Checks: */
#if ((BOARD == BOARD_XPLAIN) || (BOARD == BOARD_XPLAIN_REV1))
#undef ENABLE_ISP_PROTOCOL
#if !defined(ENABLE_XPROG_PROTOCOL)
#define ENABLE_XPROG_PROTOCOL
#endif
#endif
/* Defines: */
#define XMEGA_CRC_LENGTH 3
#define XMEGA_NVM_REG_ADDR0 0x00
#define XMEGA_NVM_REG_ADDR1 0x01
#define XMEGA_NVM_REG_ADDR2 0x02
#define XMEGA_NVM_REG_DAT0 0x04
#define XMEGA_NVM_REG_DAT1 0x05
#define XMEGA_NVM_REG_DAT2 0x06
#define XMEGA_NVM_REG_CMD 0x0A
#define XMEGA_NVM_REG_CTRLA 0x0B
#define XMEGA_NVM_REG_CTRLB 0x0C
#define XMEGA_NVM_REG_INTCTRL 0x0D
#define XMEGA_NVM_REG_STATUS 0x0F
#define XMEGA_NVM_REG_LOCKBITS 0x10
#define XMEGA_NVM_CMD_NOOP 0x00
#define XMEGA_NVM_CMD_CHIPERASE 0x40
#define XMEGA_NVM_CMD_READNVM 0x43
#define XMEGA_NVM_CMD_LOADFLASHPAGEBUFF 0x23
#define XMEGA_NVM_CMD_ERASEFLASHPAGEBUFF 0x26
#define XMEGA_NVM_CMD_ERASEFLASHPAGE 0x2B
#define XMEGA_NVM_CMD_WRITEFLASHPAGE 0x2E
#define XMEGA_NVM_CMD_ERASEWRITEFLASH 0x2F
#define XMEGA_NVM_CMD_FLASHCRC 0x78
#define XMEGA_NVM_CMD_ERASEAPPSEC 0x20
#define XMEGA_NVM_CMD_ERASEAPPSECPAGE 0x22
#define XMEGA_NVM_CMD_WRITEAPPSECPAGE 0x24
#define XMEGA_NVM_CMD_ERASEWRITEAPPSECPAGE 0x25
#define XMEGA_NVM_CMD_APPCRC 0x38
#define XMEGA_NVM_CMD_ERASEBOOTSEC 0x68
#define XMEGA_NVM_CMD_ERASEBOOTSECPAGE 0x2A
#define XMEGA_NVM_CMD_WRITEBOOTSECPAGE 0x2C
#define XMEGA_NVM_CMD_ERASEWRITEBOOTSECPAGE 0x2D
#define XMEGA_NVM_CMD_BOOTCRC 0x39
#define XMEGA_NVM_CMD_READUSERSIG 0x03
#define XMEGA_NVM_CMD_ERASEUSERSIG 0x18
#define XMEGA_NVM_CMD_WRITEUSERSIG 0x1A
#define XMEGA_NVM_CMD_READCALIBRATION 0x02
#define XMEGA_NVM_CMD_READFUSE 0x07
#define XMEGA_NVM_CMD_WRITEFUSE 0x4C
#define XMEGA_NVM_CMD_WRITELOCK 0x08
#define XMEGA_NVM_CMD_LOADEEPROMPAGEBUFF 0x33
#define XMEGA_NVM_CMD_ERASEEEPROMPAGEBUFF 0x36
#define XMEGA_NVM_CMD_ERASEEEPROM 0x30
#define XMEGA_NVM_CMD_ERASEEEPROMPAGE 0x32
#define XMEGA_NVM_CMD_WRITEEEPROMPAGE 0x34
#define XMEGA_NVM_CMD_ERASEWRITEEEPROMPAGE 0x35
#define XMEGA_NVM_CMD_READEEPROM 0x06
/* Function Prototypes: */
bool XMEGANVM_WaitWhileNVMBusBusy(void);
bool XMEGANVM_WaitWhileNVMControllerBusy(void);
bool XMEGANVM_GetMemoryCRC(const uint8_t CRCCommand, uint32_t* const CRCDest);
bool XMEGANVM_ReadMemory(const uint32_t ReadAddress, uint8_t* ReadBuffer, uint16_t ReadSize);
bool XMEGANVM_WriteByteMemory(const uint8_t WriteCommand, const uint32_t WriteAddress, const uint8_t Byte);
bool XMEGANVM_WritePageMemory(const uint8_t WriteBuffCommand, const uint8_t EraseBuffCommand,
const uint8_t WritePageCommand, const uint8_t PageMode, const uint32_t WriteAddress,
const uint8_t* WriteBuffer, uint16_t WriteSize);
bool XMEGANVM_EraseMemory(const uint8_t EraseCommand, const uint32_t Address);
#if defined(INCLUDE_FROM_XMEGANVM_C)
static void XMEGANVM_SendNVMRegAddress(const uint8_t Register);
static void XMEGANVM_SendAddress(const uint32_t AbsoluteAddress);
#endif
#endif
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of
this software.
*/
/** \file
*
* Header file for XMEGANVM.c.
*/
#ifndef _XMEGA_NVM_
#define _XMEGA_NVM_
/* Includes: */
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdbool.h>
#include <LUFA/Common/Common.h>
#include "XPROGProtocol.h"
#include "XPROGTarget.h"
/* Preprocessor Checks: */
#if ((BOARD == BOARD_XPLAIN) || (BOARD == BOARD_XPLAIN_REV1))
#undef ENABLE_ISP_PROTOCOL
#if !defined(ENABLE_XPROG_PROTOCOL)
#define ENABLE_XPROG_PROTOCOL
#endif
#endif
/* Defines: */
#define XMEGA_CRC_LENGTH 3
#define XMEGA_NVM_REG_ADDR0 0x00
#define XMEGA_NVM_REG_ADDR1 0x01
#define XMEGA_NVM_REG_ADDR2 0x02
#define XMEGA_NVM_REG_DAT0 0x04
#define XMEGA_NVM_REG_DAT1 0x05
#define XMEGA_NVM_REG_DAT2 0x06
#define XMEGA_NVM_REG_CMD 0x0A
#define XMEGA_NVM_REG_CTRLA 0x0B
#define XMEGA_NVM_REG_CTRLB 0x0C
#define XMEGA_NVM_REG_INTCTRL 0x0D
#define XMEGA_NVM_REG_STATUS 0x0F
#define XMEGA_NVM_REG_LOCKBITS 0x10
#define XMEGA_NVM_CMD_NOOP 0x00
#define XMEGA_NVM_CMD_CHIPERASE 0x40
#define XMEGA_NVM_CMD_READNVM 0x43
#define XMEGA_NVM_CMD_LOADFLASHPAGEBUFF 0x23
#define XMEGA_NVM_CMD_ERASEFLASHPAGEBUFF 0x26
#define XMEGA_NVM_CMD_ERASEFLASHPAGE 0x2B
#define XMEGA_NVM_CMD_WRITEFLASHPAGE 0x2E
#define XMEGA_NVM_CMD_ERASEWRITEFLASH 0x2F
#define XMEGA_NVM_CMD_FLASHCRC 0x78
#define XMEGA_NVM_CMD_ERASEAPPSEC 0x20
#define XMEGA_NVM_CMD_ERASEAPPSECPAGE 0x22
#define XMEGA_NVM_CMD_WRITEAPPSECPAGE 0x24
#define XMEGA_NVM_CMD_ERASEWRITEAPPSECPAGE 0x25
#define XMEGA_NVM_CMD_APPCRC 0x38
#define XMEGA_NVM_CMD_ERASEBOOTSEC 0x68
#define XMEGA_NVM_CMD_ERASEBOOTSECPAGE 0x2A
#define XMEGA_NVM_CMD_WRITEBOOTSECPAGE 0x2C
#define XMEGA_NVM_CMD_ERASEWRITEBOOTSECPAGE 0x2D
#define XMEGA_NVM_CMD_BOOTCRC 0x39
#define XMEGA_NVM_CMD_READUSERSIG 0x03
#define XMEGA_NVM_CMD_ERASEUSERSIG 0x18
#define XMEGA_NVM_CMD_WRITEUSERSIG 0x1A
#define XMEGA_NVM_CMD_READCALIBRATION 0x02
#define XMEGA_NVM_CMD_READFUSE 0x07
#define XMEGA_NVM_CMD_WRITEFUSE 0x4C
#define XMEGA_NVM_CMD_WRITELOCK 0x08
#define XMEGA_NVM_CMD_LOADEEPROMPAGEBUFF 0x33
#define XMEGA_NVM_CMD_ERASEEEPROMPAGEBUFF 0x36
#define XMEGA_NVM_CMD_ERASEEEPROM 0x30
#define XMEGA_NVM_CMD_ERASEEEPROMPAGE 0x32
#define XMEGA_NVM_CMD_WRITEEEPROMPAGE 0x34
#define XMEGA_NVM_CMD_ERASEWRITEEEPROMPAGE 0x35
#define XMEGA_NVM_CMD_READEEPROM 0x06
/* Function Prototypes: */
bool XMEGANVM_WaitWhileNVMBusBusy(void);
bool XMEGANVM_WaitWhileNVMControllerBusy(void);
bool XMEGANVM_GetMemoryCRC(const uint8_t CRCCommand, uint32_t* const CRCDest);
bool XMEGANVM_ReadMemory(const uint32_t ReadAddress, uint8_t* ReadBuffer, uint16_t ReadSize);
bool XMEGANVM_WriteByteMemory(const uint8_t WriteCommand, const uint32_t WriteAddress, const uint8_t Byte);
bool XMEGANVM_WritePageMemory(const uint8_t WriteBuffCommand, const uint8_t EraseBuffCommand,
const uint8_t WritePageCommand, const uint8_t PageMode, const uint32_t WriteAddress,
const uint8_t* WriteBuffer, uint16_t WriteSize);
bool XMEGANVM_EraseMemory(const uint8_t EraseCommand, const uint32_t Address);
#if defined(INCLUDE_FROM_XMEGANVM_C)
static void XMEGANVM_SendNVMRegAddress(const uint8_t Register);
static void XMEGANVM_SendAddress(const uint32_t AbsoluteAddress);
#endif
#endif

File diff suppressed because it is too large Load diff

View file

@ -1,132 +1,132 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of
this software.
*/
/** \file
*
* Header file for XPROGProtocol.c.
*/
#ifndef _XPROG_PROTOCOL_
#define _XPROG_PROTOCOL_
/* Includes: */
#include <avr/io.h>
#include <util/delay.h>
#include <stdio.h>
#include <LUFA/Drivers/USB/USB.h>
#include <LUFA/Drivers/Peripheral/SerialStream.h>
#include "../V2Protocol.h"
#include "XPROGTarget.h"
#include "XMEGANVM.h"
#include "TINYNVM.h"
/* Preprocessor Checks: */
#if ((BOARD == BOARD_XPLAIN) || (BOARD == BOARD_XPLAIN_REV1))
#undef ENABLE_ISP_PROTOCOL
#if !defined(ENABLE_XPROG_PROTOCOL)
#define ENABLE_XPROG_PROTOCOL
#endif
#endif
/* Macros: */
#define XPRG_CMD_ENTER_PROGMODE 0x01
#define XPRG_CMD_LEAVE_PROGMODE 0x02
#define XPRG_CMD_ERASE 0x03
#define XPRG_CMD_WRITE_MEM 0x04
#define XPRG_CMD_READ_MEM 0x05
#define XPRG_CMD_CRC 0x06
#define XPRG_CMD_SET_PARAM 0x07
#define XPRG_MEM_TYPE_APPL 1
#define XPRG_MEM_TYPE_BOOT 2
#define XPRG_MEM_TYPE_EEPROM 3
#define XPRG_MEM_TYPE_FUSE 4
#define XPRG_MEM_TYPE_LOCKBITS 5
#define XPRG_MEM_TYPE_USERSIG 6
#define XPRG_MEM_TYPE_FACTORY_CALIBRATION 7
#define XPRG_ERASE_CHIP 1
#define XPRG_ERASE_APP 2
#define XPRG_ERASE_BOOT 3
#define XPRG_ERASE_EEPROM 4
#define XPRG_ERASE_APP_PAGE 5
#define XPRG_ERASE_BOOT_PAGE 6
#define XPRG_ERASE_EEPROM_PAGE 7
#define XPRG_ERASE_USERSIG 8
#define XPRG_MEM_WRITE_ERASE 0
#define XPRG_MEM_WRITE_WRITE 1
#define XPRG_CRC_APP 1
#define XPRG_CRC_BOOT 2
#define XPRG_CRC_FLASH 3
#define XPRG_ERR_OK 0
#define XPRG_ERR_FAILED 1
#define XPRG_ERR_COLLISION 2
#define XPRG_ERR_TIMEOUT 3
#define XPRG_PARAM_NVMBASE 0x01
#define XPRG_PARAM_EEPPAGESIZE 0x02
#define XPRG_PARAM_NVMCMD_REG 0x03 /* Undocumented, Reverse-engineered */
#define XPRG_PARAM_NVMCSR_REG 0x04 /* Undocumented, Reverse-engineered */
#define XPRG_PROTOCOL_PDI 0x00
#define XPRG_PROTOCOL_JTAG 0x01
#define XPRG_PROTOCOL_TPI 0x02 /* Undocumented, Reverse-engineered */
#define XPRG_PAGEMODE_WRITE (1 << 1)
#define XPRG_PAGEMODE_ERASE (1 << 0)
/* External Variables: */
extern uint32_t XPROG_Param_NVMBase;
extern uint16_t XPROG_Param_EEPageSize;
extern uint8_t XPROG_Param_NVMCSRRegAddr;
extern uint8_t XPROG_Param_NVMCMDRegAddr;
extern uint8_t XPROG_SelectedProtocol;
/* Function Prototypes: */
void XPROGProtocol_SetMode(void);
void XPROGProtocol_Command(void);
#if defined(INCLUDE_FROM_XPROGPROTOCOL_C)
static void XPROGProtocol_EnterXPROGMode(void);
static void XPROGProtocol_LeaveXPROGMode(void);
static void XPROGProtocol_SetParam(void);
static void XPROGProtocol_Erase(void);
static void XPROGProtocol_WriteMemory(void);
static void XPROGProtocol_ReadMemory(void);
static void XPROGProtocol_ReadCRC(void);
#endif
#endif
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of
this software.
*/
/** \file
*
* Header file for XPROGProtocol.c.
*/
#ifndef _XPROG_PROTOCOL_
#define _XPROG_PROTOCOL_
/* Includes: */
#include <avr/io.h>
#include <util/delay.h>
#include <stdio.h>
#include <LUFA/Drivers/USB/USB.h>
#include <LUFA/Drivers/Peripheral/SerialStream.h>
#include "../V2Protocol.h"
#include "XPROGTarget.h"
#include "XMEGANVM.h"
#include "TINYNVM.h"
/* Preprocessor Checks: */
#if ((BOARD == BOARD_XPLAIN) || (BOARD == BOARD_XPLAIN_REV1))
#undef ENABLE_ISP_PROTOCOL
#if !defined(ENABLE_XPROG_PROTOCOL)
#define ENABLE_XPROG_PROTOCOL
#endif
#endif
/* Macros: */
#define XPRG_CMD_ENTER_PROGMODE 0x01
#define XPRG_CMD_LEAVE_PROGMODE 0x02
#define XPRG_CMD_ERASE 0x03
#define XPRG_CMD_WRITE_MEM 0x04
#define XPRG_CMD_READ_MEM 0x05
#define XPRG_CMD_CRC 0x06
#define XPRG_CMD_SET_PARAM 0x07
#define XPRG_MEM_TYPE_APPL 1
#define XPRG_MEM_TYPE_BOOT 2
#define XPRG_MEM_TYPE_EEPROM 3
#define XPRG_MEM_TYPE_FUSE 4
#define XPRG_MEM_TYPE_LOCKBITS 5
#define XPRG_MEM_TYPE_USERSIG 6
#define XPRG_MEM_TYPE_FACTORY_CALIBRATION 7
#define XPRG_ERASE_CHIP 1
#define XPRG_ERASE_APP 2
#define XPRG_ERASE_BOOT 3
#define XPRG_ERASE_EEPROM 4
#define XPRG_ERASE_APP_PAGE 5
#define XPRG_ERASE_BOOT_PAGE 6
#define XPRG_ERASE_EEPROM_PAGE 7
#define XPRG_ERASE_USERSIG 8
#define XPRG_MEM_WRITE_ERASE 0
#define XPRG_MEM_WRITE_WRITE 1
#define XPRG_CRC_APP 1
#define XPRG_CRC_BOOT 2
#define XPRG_CRC_FLASH 3
#define XPRG_ERR_OK 0
#define XPRG_ERR_FAILED 1
#define XPRG_ERR_COLLISION 2
#define XPRG_ERR_TIMEOUT 3
#define XPRG_PARAM_NVMBASE 0x01
#define XPRG_PARAM_EEPPAGESIZE 0x02
#define XPRG_PARAM_NVMCMD_REG 0x03 /* Undocumented, Reverse-engineered */
#define XPRG_PARAM_NVMCSR_REG 0x04 /* Undocumented, Reverse-engineered */
#define XPRG_PROTOCOL_PDI 0x00
#define XPRG_PROTOCOL_JTAG 0x01
#define XPRG_PROTOCOL_TPI 0x02 /* Undocumented, Reverse-engineered */
#define XPRG_PAGEMODE_WRITE (1 << 1)
#define XPRG_PAGEMODE_ERASE (1 << 0)
/* External Variables: */
extern uint32_t XPROG_Param_NVMBase;
extern uint16_t XPROG_Param_EEPageSize;
extern uint8_t XPROG_Param_NVMCSRRegAddr;
extern uint8_t XPROG_Param_NVMCMDRegAddr;
extern uint8_t XPROG_SelectedProtocol;
/* Function Prototypes: */
void XPROGProtocol_SetMode(void);
void XPROGProtocol_Command(void);
#if defined(INCLUDE_FROM_XPROGPROTOCOL_C)
static void XPROGProtocol_EnterXPROGMode(void);
static void XPROGProtocol_LeaveXPROGMode(void);
static void XPROGProtocol_SetParam(void);
static void XPROGProtocol_Erase(void);
static void XPROGProtocol_WriteMemory(void);
static void XPROGProtocol_ReadMemory(void);
static void XPROGProtocol_ReadCRC(void);
#endif
#endif

View file

@ -1,221 +1,221 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of
this software.
*/
/** \file
*
* Target-related functions for the PDI Protocol decoder.
*/
#define INCLUDE_FROM_XPROGTARGET_C
#include "XPROGTarget.h"
#if defined(ENABLE_XPROG_PROTOCOL) || defined(__DOXYGEN__)
/** Flag to indicate if the USART is currently in Tx or Rx mode. */
volatile bool IsSending;
/** Enables the target's PDI interface, holding the target in reset until PDI mode is exited. */
void XPROGTarget_EnableTargetPDI(void)
{
IsSending = false;
/* Set Tx and XCK as outputs, Rx as input */
DDRD |= (1 << 5) | (1 << 3);
DDRD &= ~(1 << 2);
/* Set DATA line high for at least 90ns to disable /RESET functionality */
PORTD |= (1 << 3);
_delay_us(1);
/* Set up the synchronous USART for XMEGA communications - 8 data bits, even parity, 2 stop bits */
UBRR1 = (F_CPU / XPROG_HARDWARE_SPEED);
UCSR1B = (1 << TXEN1);
UCSR1C = (1 << UMSEL10) | (1 << UPM11) | (1 << USBS1) | (1 << UCSZ11) | (1 << UCSZ10) | (1 << UCPOL1);
/* Send two BREAKs of 12 bits each to enable PDI interface (need at least 16 idle bits) */
XPROGTarget_SendBreak();
XPROGTarget_SendBreak();
}
/** Enables the target's TPI interface, holding the target in reset until TPI mode is exited. */
void XPROGTarget_EnableTargetTPI(void)
{
IsSending = false;
/* Set /RESET line low for at least 400ns to enable TPI functionality */
AUX_LINE_DDR |= AUX_LINE_MASK;
AUX_LINE_PORT &= ~AUX_LINE_MASK;
_delay_us(1);
/* Set Tx and XCK as outputs, Rx as input */
DDRD |= (1 << 5) | (1 << 3);
DDRD &= ~(1 << 2);
/* Set up the synchronous USART for TINY communications - 8 data bits, even parity, 2 stop bits */
UBRR1 = (F_CPU / XPROG_HARDWARE_SPEED);
UCSR1B = (1 << TXEN1);
UCSR1C = (1 << UMSEL10) | (1 << UPM11) | (1 << USBS1) | (1 << UCSZ11) | (1 << UCSZ10) | (1 << UCPOL1);
/* Send two BREAKs of 12 bits each to enable TPI interface (need at least 16 idle bits) */
XPROGTarget_SendBreak();
XPROGTarget_SendBreak();
}
/** Disables the target's PDI interface, exits programming mode and starts the target's application. */
void XPROGTarget_DisableTargetPDI(void)
{
/* Switch to Rx mode to ensure that all pending transmissions are complete */
XPROGTarget_SetRxMode();
/* Turn off receiver and transmitter of the USART, clear settings */
UCSR1A = ((1 << TXC1) | (1 << RXC1));
UCSR1B = 0;
UCSR1C = 0;
/* Tristate all pins */
DDRD &= ~((1 << 5) | (1 << 3));
PORTD &= ~((1 << 5) | (1 << 3) | (1 << 2));
}
/** Disables the target's TPI interface, exits programming mode and starts the target's application. */
void XPROGTarget_DisableTargetTPI(void)
{
/* Switch to Rx mode to ensure that all pending transmissions are complete */
XPROGTarget_SetRxMode();
/* Turn off receiver and transmitter of the USART, clear settings */
UCSR1A |= (1 << TXC1) | (1 << RXC1);
UCSR1B = 0;
UCSR1C = 0;
/* Set all USART lines as input, tristate */
DDRD &= ~((1 << 5) | (1 << 3));
PORTD &= ~((1 << 5) | (1 << 3) | (1 << 2));
/* Tristate target /RESET line */
AUX_LINE_DDR &= ~AUX_LINE_MASK;
AUX_LINE_PORT &= ~AUX_LINE_MASK;
}
/** Sends a byte via the USART.
*
* \param[in] Byte Byte to send through the USART
*/
void XPROGTarget_SendByte(const uint8_t Byte)
{
/* Switch to Tx mode if currently in Rx mode */
if (!(IsSending))
XPROGTarget_SetTxMode();
/* Wait until there is space in the hardware Tx buffer before writing */
while (!(UCSR1A & (1 << UDRE1)));
UCSR1A |= (1 << TXC1);
UDR1 = Byte;
if (TimeoutMSRemaining)
TimeoutMSRemaining = COMMAND_TIMEOUT_MS;
}
/** Receives a byte via the software USART, blocking until data is received.
*
* \return Received byte from the USART
*/
uint8_t XPROGTarget_ReceiveByte(void)
{
/* Switch to Rx mode if currently in Tx mode */
if (IsSending)
XPROGTarget_SetRxMode();
/* Wait until a byte has been received before reading */
while (!(UCSR1A & (1 << RXC1)) && TimeoutMSRemaining);
if (TimeoutMSRemaining)
TimeoutMSRemaining = COMMAND_TIMEOUT_MS;
return UDR1;
}
/** Sends a BREAK via the USART to the attached target, consisting of a full frame of idle bits. */
void XPROGTarget_SendBreak(void)
{
/* Switch to Tx mode if currently in Rx mode */
if (!(IsSending))
XPROGTarget_SetTxMode();
/* Need to do nothing for a full frame to send a BREAK */
for (uint8_t i = 0; i < BITS_IN_USART_FRAME; i++)
{
/* Wait for a full cycle of the clock */
while (PIND & (1 << 5));
while (!(PIND & (1 << 5)));
}
if (TimeoutMSRemaining)
TimeoutMSRemaining = COMMAND_TIMEOUT_MS;
}
static void XPROGTarget_SetTxMode(void)
{
/* Wait for a full cycle of the clock */
while (PIND & (1 << 5));
while (!(PIND & (1 << 5)));
PORTD |= (1 << 3);
DDRD |= (1 << 3);
UCSR1B &= ~(1 << RXEN1);
UCSR1B |= (1 << TXEN1);
IsSending = true;
if (TimeoutMSRemaining)
TimeoutMSRemaining = COMMAND_TIMEOUT_MS;
IsSending = true;
}
static void XPROGTarget_SetRxMode(void)
{
while (!(UCSR1A & (1 << TXC1)));
UCSR1A |= (1 << TXC1);
UCSR1B &= ~(1 << TXEN1);
UCSR1B |= (1 << RXEN1);
DDRD &= ~(1 << 3);
PORTD &= ~(1 << 3);
if (TimeoutMSRemaining)
TimeoutMSRemaining = COMMAND_TIMEOUT_MS;
IsSending = false;
}
#endif
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of
this software.
*/
/** \file
*
* Target-related functions for the PDI Protocol decoder.
*/
#define INCLUDE_FROM_XPROGTARGET_C
#include "XPROGTarget.h"
#if defined(ENABLE_XPROG_PROTOCOL) || defined(__DOXYGEN__)
/** Flag to indicate if the USART is currently in Tx or Rx mode. */
volatile bool IsSending;
/** Enables the target's PDI interface, holding the target in reset until PDI mode is exited. */
void XPROGTarget_EnableTargetPDI(void)
{
IsSending = false;
/* Set Tx and XCK as outputs, Rx as input */
DDRD |= (1 << 5) | (1 << 3);
DDRD &= ~(1 << 2);
/* Set DATA line high for at least 90ns to disable /RESET functionality */
PORTD |= (1 << 3);
_delay_us(1);
/* Set up the synchronous USART for XMEGA communications - 8 data bits, even parity, 2 stop bits */
UBRR1 = (F_CPU / XPROG_HARDWARE_SPEED);
UCSR1B = (1 << TXEN1);
UCSR1C = (1 << UMSEL10) | (1 << UPM11) | (1 << USBS1) | (1 << UCSZ11) | (1 << UCSZ10) | (1 << UCPOL1);
/* Send two BREAKs of 12 bits each to enable PDI interface (need at least 16 idle bits) */
XPROGTarget_SendBreak();
XPROGTarget_SendBreak();
}
/** Enables the target's TPI interface, holding the target in reset until TPI mode is exited. */
void XPROGTarget_EnableTargetTPI(void)
{
IsSending = false;
/* Set /RESET line low for at least 400ns to enable TPI functionality */
AUX_LINE_DDR |= AUX_LINE_MASK;
AUX_LINE_PORT &= ~AUX_LINE_MASK;
_delay_us(1);
/* Set Tx and XCK as outputs, Rx as input */
DDRD |= (1 << 5) | (1 << 3);
DDRD &= ~(1 << 2);
/* Set up the synchronous USART for TINY communications - 8 data bits, even parity, 2 stop bits */
UBRR1 = (F_CPU / XPROG_HARDWARE_SPEED);
UCSR1B = (1 << TXEN1);
UCSR1C = (1 << UMSEL10) | (1 << UPM11) | (1 << USBS1) | (1 << UCSZ11) | (1 << UCSZ10) | (1 << UCPOL1);
/* Send two BREAKs of 12 bits each to enable TPI interface (need at least 16 idle bits) */
XPROGTarget_SendBreak();
XPROGTarget_SendBreak();
}
/** Disables the target's PDI interface, exits programming mode and starts the target's application. */
void XPROGTarget_DisableTargetPDI(void)
{
/* Switch to Rx mode to ensure that all pending transmissions are complete */
XPROGTarget_SetRxMode();
/* Turn off receiver and transmitter of the USART, clear settings */
UCSR1A = ((1 << TXC1) | (1 << RXC1));
UCSR1B = 0;
UCSR1C = 0;
/* Tristate all pins */
DDRD &= ~((1 << 5) | (1 << 3));
PORTD &= ~((1 << 5) | (1 << 3) | (1 << 2));
}
/** Disables the target's TPI interface, exits programming mode and starts the target's application. */
void XPROGTarget_DisableTargetTPI(void)
{
/* Switch to Rx mode to ensure that all pending transmissions are complete */
XPROGTarget_SetRxMode();
/* Turn off receiver and transmitter of the USART, clear settings */
UCSR1A |= (1 << TXC1) | (1 << RXC1);
UCSR1B = 0;
UCSR1C = 0;
/* Set all USART lines as input, tristate */
DDRD &= ~((1 << 5) | (1 << 3));
PORTD &= ~((1 << 5) | (1 << 3) | (1 << 2));
/* Tristate target /RESET line */
AUX_LINE_DDR &= ~AUX_LINE_MASK;
AUX_LINE_PORT &= ~AUX_LINE_MASK;
}
/** Sends a byte via the USART.
*
* \param[in] Byte Byte to send through the USART
*/
void XPROGTarget_SendByte(const uint8_t Byte)
{
/* Switch to Tx mode if currently in Rx mode */
if (!(IsSending))
XPROGTarget_SetTxMode();
/* Wait until there is space in the hardware Tx buffer before writing */
while (!(UCSR1A & (1 << UDRE1)));
UCSR1A |= (1 << TXC1);
UDR1 = Byte;
if (TimeoutMSRemaining)
TimeoutMSRemaining = COMMAND_TIMEOUT_MS;
}
/** Receives a byte via the software USART, blocking until data is received.
*
* \return Received byte from the USART
*/
uint8_t XPROGTarget_ReceiveByte(void)
{
/* Switch to Rx mode if currently in Tx mode */
if (IsSending)
XPROGTarget_SetRxMode();
/* Wait until a byte has been received before reading */
while (!(UCSR1A & (1 << RXC1)) && TimeoutMSRemaining);
if (TimeoutMSRemaining)
TimeoutMSRemaining = COMMAND_TIMEOUT_MS;
return UDR1;
}
/** Sends a BREAK via the USART to the attached target, consisting of a full frame of idle bits. */
void XPROGTarget_SendBreak(void)
{
/* Switch to Tx mode if currently in Rx mode */
if (!(IsSending))
XPROGTarget_SetTxMode();
/* Need to do nothing for a full frame to send a BREAK */
for (uint8_t i = 0; i < BITS_IN_USART_FRAME; i++)
{
/* Wait for a full cycle of the clock */
while (PIND & (1 << 5));
while (!(PIND & (1 << 5)));
}
if (TimeoutMSRemaining)
TimeoutMSRemaining = COMMAND_TIMEOUT_MS;
}
static void XPROGTarget_SetTxMode(void)
{
/* Wait for a full cycle of the clock */
while (PIND & (1 << 5));
while (!(PIND & (1 << 5)));
PORTD |= (1 << 3);
DDRD |= (1 << 3);
UCSR1B &= ~(1 << RXEN1);
UCSR1B |= (1 << TXEN1);
IsSending = true;
if (TimeoutMSRemaining)
TimeoutMSRemaining = COMMAND_TIMEOUT_MS;
IsSending = true;
}
static void XPROGTarget_SetRxMode(void)
{
while (!(UCSR1A & (1 << TXC1)));
UCSR1A |= (1 << TXC1);
UCSR1B &= ~(1 << TXEN1);
UCSR1B |= (1 << RXEN1);
DDRD &= ~(1 << 3);
PORTD &= ~(1 << 3);
if (TimeoutMSRemaining)
TimeoutMSRemaining = COMMAND_TIMEOUT_MS;
IsSending = false;
}
#endif

View file

@ -1,126 +1,126 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of
this software.
*/
/** \file
*
* Header file for XPROGTarget.c.
*/
#ifndef _XPROG_TARGET_
#define _XPROG_TARGET_
/* Includes: */
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdbool.h>
#include <LUFA/Common/Common.h>
#include "../V2Protocol.h"
#include "XPROGProtocol.h"
/* Preprocessor Checks: */
#if ((BOARD == BOARD_XPLAIN) || (BOARD == BOARD_XPLAIN_REV1))
#undef ENABLE_ISP_PROTOCOL
#if !defined(ENABLE_XPROG_PROTOCOL)
#define ENABLE_XPROG_PROTOCOL
#endif
#endif
/** Serial carrier TPI/PDI speed when hardware TPI/PDI mode is used */
#define XPROG_HARDWARE_SPEED 1000000
/** Total number of bits in a single USART frame */
#define BITS_IN_USART_FRAME 12
#define PDI_CMD_LDS 0x00
#define PDI_CMD_LD 0x20
#define PDI_CMD_STS 0x40
#define PDI_CMD_ST 0x60
#define PDI_CMD_LDCS 0x80
#define PDI_CMD_REPEAT 0xA0
#define PDI_CMD_STCS 0xC0
#define PDI_CMD_KEY 0xE0
#define PDI_STATUS_REG 0
#define PDI_RESET_REG 1
#define PDI_CTRL_REG 2
#define PDI_STATUS_NVM (1 << 1)
#define PDI_RESET_KEY 0x59
#define PDI_NVMENABLE_KEY (uint8_t[]){0x12, 0x89, 0xAB, 0x45, 0xCD, 0xD8, 0x88, 0xFF}
#define PDI_DATSIZE_1BYTE 0
#define PDI_DATSIZE_2BYTES 1
#define PDI_DATSIZE_3BYTES 2
#define PDI_DATSIZE_4BYTES 3
#define PDI_POINTER_INDIRECT 0
#define PDI_POINTER_INDIRECT_PI 1
#define PDI_POINTER_DIRECT 2
#define TPI_CMD_SLD 0x20
#define TPI_CMD_SST 0x60
#define TPI_CMD_SSTPR 0x68
#define TPI_CMD_SIN 0x10
#define TPI_CMD_SOUT 0x90
#define TPI_CMD_SLDCS 0x80
#define TPI_CMD_SSTCS 0xC0
#define TPI_CMD_SKEY 0xE0
#define TPI_STATUS_REG 0x00
#define TPI_CTRL_REG 0x02
#define TPI_ID_REG 0x0F
#define TPI_STATUS_NVM (1 << 1)
#define TPI_NVMENABLE_KEY (uint8_t[]){0x12, 0x89, 0xAB, 0x45, 0xCD, 0xD8, 0x88, 0xFF}
#define TPI_POINTER_INDIRECT 0
#define TPI_POINTER_INDIRECT_PI 4
/* Function Prototypes: */
void XPROGTarget_EnableTargetPDI(void);
void XPROGTarget_EnableTargetTPI(void);
void XPROGTarget_DisableTargetPDI(void);
void XPROGTarget_DisableTargetTPI(void);
void XPROGTarget_SendByte(const uint8_t Byte);
uint8_t XPROGTarget_ReceiveByte(void);
void XPROGTarget_SendBreak(void);
bool XPROGTarget_WaitWhileNVMBusBusy(void);
#if defined(INCLUDE_FROM_XPROGTARGET_C)
static void XPROGTarget_SetTxMode(void);
static void XPROGTarget_SetRxMode(void);
#endif
#endif
/*
LUFA Library
Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of
this software.
*/
/** \file
*
* Header file for XPROGTarget.c.
*/
#ifndef _XPROG_TARGET_
#define _XPROG_TARGET_
/* Includes: */
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdbool.h>
#include <LUFA/Common/Common.h>
#include "../V2Protocol.h"
#include "XPROGProtocol.h"
/* Preprocessor Checks: */
#if ((BOARD == BOARD_XPLAIN) || (BOARD == BOARD_XPLAIN_REV1))
#undef ENABLE_ISP_PROTOCOL
#if !defined(ENABLE_XPROG_PROTOCOL)
#define ENABLE_XPROG_PROTOCOL
#endif
#endif
/** Serial carrier TPI/PDI speed when hardware TPI/PDI mode is used */
#define XPROG_HARDWARE_SPEED 1000000
/** Total number of bits in a single USART frame */
#define BITS_IN_USART_FRAME 12
#define PDI_CMD_LDS 0x00
#define PDI_CMD_LD 0x20
#define PDI_CMD_STS 0x40
#define PDI_CMD_ST 0x60
#define PDI_CMD_LDCS 0x80
#define PDI_CMD_REPEAT 0xA0
#define PDI_CMD_STCS 0xC0
#define PDI_CMD_KEY 0xE0
#define PDI_STATUS_REG 0
#define PDI_RESET_REG 1
#define PDI_CTRL_REG 2
#define PDI_STATUS_NVM (1 << 1)
#define PDI_RESET_KEY 0x59
#define PDI_NVMENABLE_KEY (uint8_t[]){0x12, 0x89, 0xAB, 0x45, 0xCD, 0xD8, 0x88, 0xFF}
#define PDI_DATSIZE_1BYTE 0
#define PDI_DATSIZE_2BYTES 1
#define PDI_DATSIZE_3BYTES 2
#define PDI_DATSIZE_4BYTES 3
#define PDI_POINTER_INDIRECT 0
#define PDI_POINTER_INDIRECT_PI 1
#define PDI_POINTER_DIRECT 2
#define TPI_CMD_SLD 0x20
#define TPI_CMD_SST 0x60
#define TPI_CMD_SSTPR 0x68
#define TPI_CMD_SIN 0x10
#define TPI_CMD_SOUT 0x90
#define TPI_CMD_SLDCS 0x80
#define TPI_CMD_SSTCS 0xC0
#define TPI_CMD_SKEY 0xE0
#define TPI_STATUS_REG 0x00
#define TPI_CTRL_REG 0x02
#define TPI_ID_REG 0x0F
#define TPI_STATUS_NVM (1 << 1)
#define TPI_NVMENABLE_KEY (uint8_t[]){0x12, 0x89, 0xAB, 0x45, 0xCD, 0xD8, 0x88, 0xFF}
#define TPI_POINTER_INDIRECT 0
#define TPI_POINTER_INDIRECT_PI 4
/* Function Prototypes: */
void XPROGTarget_EnableTargetPDI(void);
void XPROGTarget_EnableTargetTPI(void);
void XPROGTarget_DisableTargetPDI(void);
void XPROGTarget_DisableTargetTPI(void);
void XPROGTarget_SendByte(const uint8_t Byte);
uint8_t XPROGTarget_ReceiveByte(void);
void XPROGTarget_SendBreak(void);
bool XPROGTarget_WaitWhileNVMBusBusy(void);
#if defined(INCLUDE_FROM_XPROGTARGET_C)
static void XPROGTarget_SetTxMode(void);
static void XPROGTarget_SetRxMode(void);
#endif
#endif