2011-06-09 01:30:39 +02:00
|
|
|
/****************************************************************************
|
2014-01-15 18:05:15 +01:00
|
|
|
* arch/avr/src/atmega/atmega_head.S
|
2011-06-09 01:30:39 +02:00
|
|
|
*
|
|
|
|
* Copyright (C) 2011 Gregory Nutt. All rights reserved.
|
2012-09-13 20:32:24 +02:00
|
|
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
2011-06-09 01:30:39 +02:00
|
|
|
*
|
|
|
|
* 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. Neither the name NuttX nor the names of its contributors may be
|
|
|
|
* used to endorse or promote products derived from this software
|
|
|
|
* without specific prior written permission.
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
|
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
|
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
|
|
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
|
|
|
* COPYRIGHT OWNER OR CONTRIBUTORS 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.
|
|
|
|
*
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* Included Files
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
#include <nuttx/config.h>
|
|
|
|
|
|
|
|
#include <arch/irq.h>
|
|
|
|
#include <avr/io.h>
|
|
|
|
#include <avr/sfr_defs.h>
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* Pre-processor definitions
|
|
|
|
****************************************************************************/
|
|
|
|
|
2011-06-16 01:54:25 +02:00
|
|
|
/* Stack is allocated just after uninitialized data and just before the heap */
|
2011-06-09 01:30:39 +02:00
|
|
|
|
2011-06-16 01:54:25 +02:00
|
|
|
#define STACKBASE (_enoinit+CONFIG_IDLETHREAD_STACKSIZE-1)
|
2011-06-09 01:30:39 +02:00
|
|
|
|
|
|
|
/* The RAMPZ register is only available for CPUs with more than 64Kb of FLASH.
|
|
|
|
* At present, only the ATMega128 is supported so RAMPZ should always be
|
|
|
|
* available.
|
|
|
|
*
|
|
|
|
* - Support for the EPLMX instructions is assumed if RAMPZ is present
|
|
|
|
* - If RAMPZ is not present, support for LPMX is assumed
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define HAVE_RAMPZ 1
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* External Symbols
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
.file "up_nommuhead.S"
|
|
|
|
.global __start /* Entry point */
|
|
|
|
.global _sbss /* Start of .bss. Defined by ld.script */
|
|
|
|
.global _ebss /* End of .bss. Defined by ld.script */
|
|
|
|
.global _sdata /* Start of .data section in RAM */
|
|
|
|
.global _edata /* End of .data section in RAM */
|
|
|
|
.global _eronly /* Start of .data section in FLASH */
|
2011-06-16 01:54:25 +02:00
|
|
|
.global _enoinit /* End of uninitilized data. Defined by ld.script */
|
2011-06-09 01:30:39 +02:00
|
|
|
.global up_lowinit /* Perform low level initialization */
|
|
|
|
.global os_start /* NuttX entry point */
|
|
|
|
|
|
|
|
.global vectortab
|
|
|
|
.global atmega_int0 /* External interrupt request 0 */
|
|
|
|
.global atmega_int1 /* External interrupt request 1 */
|
|
|
|
.global atmega_int2 /* External interrupt request 2 */
|
|
|
|
.global atmega_int3 /* External interrupt request 3 */
|
|
|
|
.global atmega_int4 /* External interrupt request 4 */
|
|
|
|
.global atmega_int5 /* External interrupt request 5 */
|
|
|
|
.global atmega_int6 /* External interrupt request 6 */
|
|
|
|
.global atmega_int7 /* External interrupt request 7 */
|
|
|
|
.global atmega_t2comp /* TIMER2 COMP timer/counter2 compare match */
|
|
|
|
.global atmega_t2ovf /* TIMER2 OVF timer/counter2 overflow */
|
|
|
|
.global atmega_t1capt /* TIMER1 CAPT timer/counter1 capture event */
|
|
|
|
.global atmega_t1compa /* TIMER1 COMPA timer/counter1 compare match a */
|
|
|
|
.global atmega_t1compb /* TIMER1 COMPB timer/counter1 compare match b */
|
|
|
|
.global atmega_t1ovf /* TIMER1 OVF timer/counter1 overflow */
|
|
|
|
.global atmega_t0comp /* TIMER0 COMP timer/counter0 compare match */
|
|
|
|
.global atmega_t0ovf /* TIMER0 OVF timer/counter0 overflow */
|
|
|
|
.global atmega_spi /* STC SPI serial transfer complete */
|
|
|
|
.global atmega_u0rx /* USART0 RX complete */
|
|
|
|
.global atmega_u0dre /* USART0 data register empty */
|
|
|
|
.global atmega_u0tx /* USART0 TX complete */
|
|
|
|
.global atmega_adc /* ADC conversion complete */
|
|
|
|
.global atmega_ee /* EEPROM ready */
|
|
|
|
.global atmega_anacomp /* ANALOG COMP analog comparator */
|
|
|
|
.global atmega_t1compc /* TIMER1 COMPC timer/countre1 compare match c */
|
|
|
|
.global atmega_t3capt /* TIMER3 CAPT timer/counter3 capture event */
|
|
|
|
.global atmega_t3compa /* TIMER3 COMPA timer/counter3 compare match a */
|
|
|
|
.global atmega_t3compb /* TIMER3 COMPB timer/counter3 compare match b */
|
|
|
|
.global atmega_t3compc /* TIMER3 COMPC timer/counter3 compare match c */
|
|
|
|
.global atmega_t3ovf /* TIMER3 OVF timer/counter3 overflow */
|
|
|
|
.global atmega_u1rx /* USART1 RX complete */
|
|
|
|
.global atmega_u1dre /* USART1 data register empty */
|
|
|
|
.global atmega_u1tx /* USART1 TX complete */
|
|
|
|
.global atmega_twi /* TWI two-wire serial interface */
|
|
|
|
.global atmega_spmrdy /* Store program memory ready */
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* Macros
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
.macro vector name
|
2011-06-16 18:58:30 +02:00
|
|
|
jmp \name
|
2011-06-09 01:30:39 +02:00
|
|
|
.endm
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* Vector Table
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
/* The ATmega128 has 35 interrupt vectors including vector 0, the reset
|
|
|
|
* vector.
|
|
|
|
*/
|
|
|
|
|
|
|
|
.section .vectors, "ax", @progbits
|
|
|
|
.func vectortab
|
|
|
|
vectortab:
|
2011-06-16 18:58:30 +02:00
|
|
|
jmp __start /* 0: Vector 0 is the reset vector */
|
2011-06-09 01:30:39 +02:00
|
|
|
vector atmega_int0 /* 1: External interrupt request 0 */
|
|
|
|
vector atmega_int1 /* 2: External interrupt request 1 */
|
|
|
|
vector atmega_int2 /* 3: External interrupt request 2 */
|
|
|
|
vector atmega_int3 /* 4: External interrupt request 3 */
|
|
|
|
vector atmega_int4 /* 5: External interrupt request 4 */
|
|
|
|
vector atmega_int5 /* 6 : External interrupt request 5 */
|
|
|
|
vector atmega_int6 /* 7: External interrupt request 6 */
|
|
|
|
vector atmega_int7 /* 8: External interrupt request 7 */
|
|
|
|
vector atmega_t2comp /* 9: TIMER2 COMP timer/counter2 compare match */
|
|
|
|
vector atmega_t2ovf /* 10: TIMER2 OVF timer/counter2 overflow */
|
|
|
|
vector atmega_t1capt /* 11: TIMER1 CAPT timer/counter1 capture event */
|
|
|
|
vector atmega_t1compa /* 12: TIMER1 COMPA timer/counter1 compare match a */
|
|
|
|
vector atmega_t1compb /* 13: TIMER1 COMPB timer/counter1 compare match b */
|
|
|
|
vector atmega_t1ovf /* 14: TIMER1 OVF timer/counter1 overflow */
|
|
|
|
vector atmega_t0comp /* 15: TIMER0 COMP timer/counter0 compare match */
|
|
|
|
vector atmega_t0ovf /* 16: TIMER0 OVF timer/counter0 overflow */
|
|
|
|
vector atmega_spi /* 17: STC SPI serial transfer complete */
|
|
|
|
vector atmega_u0rx /* 18: USART0 RX complete */
|
|
|
|
vector atmega_u0dre /* 19: USART0 data register empty */
|
|
|
|
vector atmega_u0tx /* 20: USART0 TX complete */
|
|
|
|
vector atmega_adc /* 21: ADC conversion complete */
|
|
|
|
vector atmega_ee /* 22: EEPROM ready */
|
|
|
|
vector atmega_anacomp /* 23: ANALOG COMP analog comparator */
|
|
|
|
vector atmega_t1compc /* 24: TIMER1 COMPC timer/countre1 compare match c */
|
|
|
|
vector atmega_t3capt /* 25: TIMER3 CAPT timer/counter3 capture event */
|
|
|
|
vector atmega_t3compa /* 26: TIMER3 COMPA timer/counter3 compare match a */
|
|
|
|
vector atmega_t3compb /* 27: TIMER3 COMPB timer/counter3 compare match b */
|
|
|
|
vector atmega_t3compc /* 28: TIMER3 COMPC timer/counter3 compare match c */
|
|
|
|
vector atmega_t3ovf /* 29: TIMER3 OVF timer/counter3 overflow */
|
|
|
|
vector atmega_u1rx /* 30: USART1 RX complete */
|
|
|
|
vector atmega_u1dre /* 31: USART1 data register empty */
|
|
|
|
vector atmega_u1tx /* 32: USART1 TX complete */
|
|
|
|
vector atmega_twi /* 33: TWI two-wire serial interface */
|
|
|
|
vector atmega_spmrdy /* 34: Store program memory ready */
|
|
|
|
.endfunc
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* Reset Entry Point
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
.section .init, "ax", @progbits
|
|
|
|
.func __start
|
|
|
|
__start:
|
|
|
|
|
|
|
|
/* Clear the zero register, clear the status register and initialize the
|
|
|
|
* IDLE thread stack
|
|
|
|
*/
|
|
|
|
|
|
|
|
clr r1
|
|
|
|
out _SFR_IO_ADDR(SREG), r1
|
|
|
|
ldi r28, lo8(STACKBASE)
|
|
|
|
ldi r29, hi8(STACKBASE)
|
|
|
|
out _SFR_IO_ADDR(SPH), r29
|
|
|
|
out _SFR_IO_ADDR(SPL), r28
|
|
|
|
|
|
|
|
/* Copy initial global data values from FLASH into RAM */
|
|
|
|
|
|
|
|
.global __do_copy_data; /* Required to suppress dragging in logic from libgcc */
|
|
|
|
__do_copy_data:
|
|
|
|
|
|
|
|
#ifdef HAVE_RAMPZ
|
|
|
|
ldi r17, hi8(_edata)
|
|
|
|
ldi r26, lo8(_sdata)
|
|
|
|
ldi r27, hi8(_sdata)
|
|
|
|
ldi r30, lo8(_eronly)
|
|
|
|
ldi r31, hi8(_eronly)
|
|
|
|
ldi r16, hh8(_eronly)
|
|
|
|
out _SFR_IO_ADDR(RAMPZ), r16
|
|
|
|
rjmp .Lcopystart
|
|
|
|
|
|
|
|
.Lcopyloop:
|
|
|
|
elpm r0, Z+
|
|
|
|
st X+, r0
|
|
|
|
|
|
|
|
.Lcopystart:
|
|
|
|
cpi r26, lo8(_edata)
|
|
|
|
cpc r27, r17
|
|
|
|
brne .Lcopyloop
|
|
|
|
#else
|
|
|
|
ldi r17, hi8(_edata)
|
|
|
|
ldi r26, lo8(_sdata)
|
|
|
|
ldi r27, hi8(_sdata)
|
|
|
|
ldi r30, lo8(_eronly)
|
|
|
|
ldi r31, hi8(_eronly)
|
|
|
|
rjmp .Lcopystart
|
|
|
|
|
|
|
|
.Lcopyloop:
|
|
|
|
lpm r0, Z+
|
|
|
|
st X+, r0
|
2011-06-16 16:28:18 +02:00
|
|
|
|
2011-06-09 01:30:39 +02:00
|
|
|
.Lcopystart:
|
|
|
|
cpi r26, lo8(_edata)
|
|
|
|
cpc r27, r17
|
|
|
|
brne .Lcopyloop
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* Clear uninitialized data */
|
|
|
|
|
|
|
|
.global __do_clear_bss; /* Required to suppress dragging in logic from libgcc */
|
|
|
|
__do_clear_bss:
|
|
|
|
|
|
|
|
ldi r17, hi8(_ebss)
|
|
|
|
ldi r26, lo8(_sbss)
|
|
|
|
ldi r27, hi8(_sbss)
|
|
|
|
rjmp .Lclearstart
|
|
|
|
|
|
|
|
.Lclearloop:
|
|
|
|
st X+, r1
|
2011-06-16 16:28:18 +02:00
|
|
|
|
2011-06-09 01:30:39 +02:00
|
|
|
.Lclearstart:
|
|
|
|
cpi r26, lo8(_ebss)
|
|
|
|
cpc r27, r17
|
|
|
|
brne .Lclearloop
|
|
|
|
|
|
|
|
/* Perform any low-level initialization */
|
|
|
|
|
|
|
|
call up_lowinit
|
|
|
|
|
|
|
|
/* Now start NuttX */
|
|
|
|
|
|
|
|
call os_start
|
|
|
|
jmp exit
|
|
|
|
.endfunc
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* Heap Base
|
|
|
|
****************************************************************************/
|
|
|
|
|
2013-03-14 15:42:52 +01:00
|
|
|
/* This global variable is unsigned long g_idle_topstack and is exported from
|
2011-06-16 01:54:25 +02:00
|
|
|
* here only because of its coupling to other uses of _enoinit in this file
|
2011-06-09 01:30:39 +02:00
|
|
|
*/
|
|
|
|
|
|
|
|
.data
|
2013-03-14 15:42:52 +01:00
|
|
|
.globl g_idle_topstack
|
|
|
|
.type g_idle_topstack, object
|
|
|
|
g_idle_topstack:
|
2011-06-16 01:54:25 +02:00
|
|
|
.word _enoinit+CONFIG_IDLETHREAD_STACKSIZE
|
2013-03-14 15:42:52 +01:00
|
|
|
.size g_idle_topstack, .-g_idle_topstack
|
2011-06-09 01:30:39 +02:00
|
|
|
.end
|