blob: 7068db1138940f3c2545dab34cb40694fd701775 [file] [log] [blame]
/*This file is prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief AVR32 UC3 ISP boot.
*
* - Compiler: IAR EWAVR32
* - Supported devices: All AVR32UC devices with an INTC module can be used.
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support and FAQ: http://support.atmel.no/
*
******************************************************************************/
/* Copyright (c) 2009 Atmel Corporation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of Atmel may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* 4. This software may only be redistributed and used in connection with an Atmel
* AVR product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
*
*/
#include <avr32/io.h>
#include "conf_isp.h"
#include "parts.h"
#if UC3C
// These defines are missing from or wrong in the toolchain header file ip_xxx.h or part.h
#ifndef AVR32_WDT_KEY_VALUE
#define AVR32_WDT_KEY_VALUE 0x00000055
#endif
#define AVR32_SR_M_SUP 0x00000001
#define AVR32_SR_M_SIZE 3
#define AVR32_SR_M_OFFSET 22
#define AVR32_SRAM_ADDRESS 0x00000000
#endif
//! @{
//! \verbatim
// Performs efficiently a bitwise logical Exclusive-OR between the specified
// register and an immediate value of up to 32 bits. The result is stored in
// the destination register.
eor_w\
MACRO rd, imm
IF (imm) & 0x0000FFFF
eorl rd, LWRD(imm)
ENDIF
IF (imm) & 0xFFFF0000
eorh rd, HWRD(imm)
ENDIF
ENDM
// Moves efficiently an immediate value of up to 32 bits into a register.
mov_w\
MACRO rd, imm
IF (((-(1 << (21 - 1))) <= (imm)) && ((imm) <= ((1 << (21 - 1)) - 1))) ||\
(((1 << 32) - (1 << (21 - 1))) <= (imm))
mov rd, imm
#if __CORE_REVISION__ >= 2
ELSEIF !((imm) & 0x0000FFFF)
movh rd, HWRD(imm)
#endif
ELSE
mov rd, LWRD(imm)
orh rd, HWRD(imm)
ENDIF
ENDM
// Performs efficiently a bitwise logical OR between the specified register
// and an immediate value of up to 32 bits. The result is stored in the
// destination register.
or_w\
MACRO rd, imm
IF (imm) & 0x0000FFFF
orl rd, LWRD(imm)
ENDIF
IF (imm) & 0xFFFF0000
orh rd, HWRD(imm)
ENDIF
ENDM
RSEG SSTACK:DATA:NOROOT(2)
RSEG RESET:CODE:NOROOT(1)
ALIGN 1
// Reset vector: This must be linked @ 0x80000000.
PUBLIC __program_start
__program_start:
// Start of exception vector table: Unrecoverable exception.
PUBLIC _evba
_evba:
mfsr r8, AVR32_SR
bfextu r8, r8, AVR32_SR_M_OFFSET, AVR32_SR_M_SIZE
cp.w r8, 001b
breq boot_supervisor_mode
sub r8, pc, $ - boot_supervisor_mode
mov_w r9, AVR32_SR_GM_MASK | AVR32_SR_EM_MASK | (AVR32_SR_M_SUP << AVR32_SR_M_OFFSET)
mov sp, SFE(SSTACK) - 6 * 4
pushm r8-r9
rete
boot_supervisor_mode:
mov_w r8, ISP_KEY_ADDRESS
mov_w r9, AVR32_WDT_ADDRESS
mov_w r10, ISP_CFG1_ADDRESS
mov_w r11, AVR32_PM_ADDRESS
ld.w r0, r8[0]
mov_w r1, ISP_KEY_VALUE
// Check CRC8 validity of the user page configuration word1.
ld.w r2, r10[0] // r2 = config_word1
mov_w r3, ISP_CFG1_CRC8_POLYNOMIAL // r3 = crc8_polynomial
mov r4, r2 // r4 = config_word1_tempo
rcall test_crc8_end
brne start_loader // The config word1 CRC8 is invalid: launch the ISP process.
// Check the magic key of the user page configuration word1.
bfextu r3, r2, ISP_CFG1_BOOT_KEY1_OFFSET, ISP_CFG1_BOOT_KEY1_SIZE // r3 = ISP_BOOT_KEY1
cp.w r3, ISP_CFG1_BOOT_KEY1_VALUE
brne start_loader // The config word1 magic key is incorrect: launch the ISP process
// Test the value of the ISP_FORCE bit.
test_isp_force:
bld r2, ISP_CFG1_FORCE_OFFSET
brcs start_loader // The ISP_FORCE bit is set: launch the ISP process.
// Test the reset cause.
ld.w r3, r11[AVR32_PM_RCAUSE]
#if (UC3A || UC3B)
mov_w r4, AVR32_PM_RCAUSE_POR_MASK |\
AVR32_PM_RCAUSE_EXT_MASK |\
AVR32_PM_RCAUSE_JTAG_MASK |\
AVR32_PM_RCAUSE_OCDRST_MASK |\
AVR32_PM_RCAUSE_JTAGHARD_MASK
#elif ( UC3C || UC3D )
mov_w r4, AVR32_PM_RCAUSE_POR_MASK |\
AVR32_PM_RCAUSE_EXT_MASK |\
AVR32_PM_RCAUSE_JTAG_MASK |\
AVR32_PM_RCAUSE_OCDRST_MASK |\
AVR32_PM_RCAUSE_JTAGHARD_MASK|\
AVR32_PM_RCAUSE_BOD33_MASK |\
AVR32_PM_RCAUSE_BOD_MASK // r4 = POR|EXT|OCD|JTAG|BOD33|BOD
#else
#error 'Part configuration is missing'
#endif
tst r3, r4
brne manage_io_cond // The reset cause was one of POR|EXT|OCD|JTAG|JTAGHARD: check the IO conditions that control the ISP activation.
// Was the reset cause a WDT reset?
bld r3, AVR32_PM_RCAUSE_WDT_OFFSET
brcs start_program // The reset cause was a WDT reset: start the application
// ISP RAM Key set?
cp.w r0, r1
brne start_program_no_isp_key // Start the application
// Start of the ISP process
start_loader:
rcall disable_wdt
st.w r8[0], r1 // Set ISP RAM Key
// Set initial stack pointer.
mov sp, SFE(SSTACK)
// Disable the exception processing.
ssrf AVR32_SR_EM_OFFSET
// Set up EVBA so interrupts can be enabled.
sub r0, pc, $ - _evba
mtsr AVR32_EVBA, r0
// Initialize segments.
PUBLIC ?need_segment_init
?need_segment_init:
EXTERN __segment_init
rcall __segment_init
// Call the ISP main function, which must not return.
EXTERN main
rcall main
// Check of the IO conditions that control the ISP activation.
manage_io_cond:
// Test the ISP_IO_COND_EN bit.
bld r2, ISP_CFG1_IO_COND_EN_OFFSET
brcc start_program // ISP_IO_COND_EN is 0: start the application.
// Check CRC8 validity of the user page configuration word2.
mov_w r10, ISP_CFG2_ADDRESS
ld.w r2, r10[0] // r2 = config_word2
mov_w r3, ISP_CFG2_CRC8_POLYNOMIAL // r3 = crc8_polynomial
mov r4, r2 // r4 = config_word2_tempo
rcall test_crc8_end
brne start_loader // The config word2 CRC8 is invalid: launch the ISP process.
// Check the magic key of the user page configuration word2
bfextu r3, r2, ISP_CFG2_BOOT_KEY_OFFSET, ISP_CFG2_BOOT_KEY_SIZE
cp.w r3, ISP_CFG2_BOOT_KEY_VALUE
brne start_loader // The config word2 magic key is incorrect: launch the ISP process
// ISP IO Condition active?
bfextu r3, r2, ISP_CFG2_IO_COND_PIN_OFFSET, ISP_CFG2_IO_COND_PIN_SIZE // r3 = IO_COND_PIN
cp.w r3, AVR32_GPIO_NUMBER_OF_PINS
brhs start_loader // The IO pin is invalid: launch the ISP process
// Check the IO condition
mov_w r10, AVR32_GPIO_ADDRESS
lsr r4, r3, 5
#if (UC3A || UC3B)
lsl r4, 8
#elif (UC3C || UC3L || UC3D)
lsl r4, 9
#endif
add r10, r4
ld.w r4, r10[AVR32_GPIO_PVR]
andl r3, 0x1F
lsr r4, r4, r3
bfextu r3, r2, ISP_CFG2_IO_COND_LEVEL_OFFSET, ISP_CFG2_IO_COND_LEVEL_SIZE
eor r4, r3
bld r4, 0
brcc start_loader // The ISP IO Condition is not active: launch the ISP process
start_program:
cp.w r0, r1
brne start_program_no_isp_key
rcall disable_wdt
PUBLIC boot_program
boot_program:
mov_w r8, ISP_KEY_ADDRESS
mov_w r0, 0
st.w r8[0], r0
start_program_no_isp_key:
mov_w r0, AVR32_SR_GM_MASK | AVR32_SR_EM_MASK | (AVR32_SR_M_SUP << AVR32_SR_M_OFFSET)
mtsr AVR32_SR, r0
REPTI rd, r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, sp, lr
mov_w rd, 0
ENDR
mtsr AVR32_EVBA, r0
mtsr AVR32_COUNT, r0
lddpc pc, program_start_address
disable_wdt:
mov_w r2, AVR32_WDT_KEY_VALUE << AVR32_WDT_CTRL_KEY_OFFSET
st.w r9[AVR32_WDT_CTRL], r2
eor_w r2, AVR32_WDT_CTRL_KEY_MASK
st.w r9[AVR32_WDT_CTRL], r2
mov pc, lr
// Common CRC8 function
crc8:
clz r5, r4
rsub r5, r5, 32 - 9
lsl r5, r3, r5
eor r4, r5
test_crc8_end:
cp.w r4, 0xFF
brhi crc8
cp.w r4, 0
retal r4
// Constant data area.
ALIGN 2
program_start_address:
DC32 PROGRAM_START_ADDRESS
END
//! \endverbatim
//! @}