This commit is contained in:
2024-08-05 20:57:09 +08:00
commit 46d9ee7795
3020 changed files with 1725767 additions and 0 deletions

View File

@@ -0,0 +1,23 @@
# RT-Thread building script for component
from building import *
Import('rtconfig')
cwd = GetCurrentDir()
src = Glob('*.c') + Glob('*.cpp')
CPPPATH = [cwd]
if rtconfig.PLATFORM in ['armcc', 'armclang']:
src += Glob('*_rvds.S')
if rtconfig.PLATFORM in ['gcc']:
src += Glob('*_init.S')
src += Glob('*_gcc.S')
if rtconfig.PLATFORM in ['iccarm']:
src += Glob('*_iar.S')
group = DefineGroup('libcpu', src, depend = [''], CPPPATH = CPPPATH)
Return('group')

View File

@@ -0,0 +1,110 @@
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
*/
.global rt_hw_interrupt_disable
.global rt_hw_interrupt_enable
.global rt_hw_context_switch
.global rt_hw_context_switch_to
.global rt_hw_context_switch_interrupt
.equ NOINT, 0xc0
/*
* rt_base_t rt_hw_interrupt_disable();
CPSR
*/
rt_hw_interrupt_disable:
//EXPORT rt_hw_interrupt_disable
MRS r0, cpsr
ORR r1, r0, #NOINT
MSR cpsr_c, r1
BX lr
//ENDP
/*
* void rt_hw_interrupt_enable(rt_base_t level);
*/
rt_hw_interrupt_enable:
//EXPORT rt_hw_interrupt_enable
MSR cpsr_c, r0
BX lr
//ENDP
/*
* void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
* r0 --> from
* r1 --> to
线
*/
rt_hw_context_switch:
//EXPORT rt_hw_context_switch
STMFD sp!, {lr} /* push pc (lr should be pushed in place of PC) */
/* 把LR寄存器压入栈这个函数返回后的下一个执行处 */
STMFD sp!, {r0-r12, lr} /* push lr & register file */
/* 把R0 R12以及LR压入栈 */
MRS r4, cpsr /* CPSRR4 */
STMFD sp!, {r4} /* push cpsr */
/* 把R4寄存器压栈即上一指令取出的CPSR寄存器 */
MRS r4, spsr /* SPSRR4 */
STMFD sp!, {r4} /* push spsr */
/* 把R4寄存器压栈即SPSR寄存器 */
STR sp, [r0] /* store sp in preempted tasks TCB */
/* 把栈指针更新到TCB的sp是由R0传入此函数 */
/* 到这里换出线程的上下文都保存在栈中 */
LDR sp, [r1] /* get new task stack pointer */
/* 载入切换到线程的TCB的sp */
/* 从切换到线程的栈中恢复上下文,次序和保存的时候刚好相反 */
LDMFD sp!, {r4} /* pop new task spsr */
/* 出栈到R4寄存器保存了SPSR寄存器 */
MSR spsr_cxsf, r4 /* SPSR */
LDMFD sp!, {r4} /* pop new task cpsr */
/* 出栈到R4寄存器保存了CPSR寄存器 */
MSR cpsr_cxsf, r4 /* CPSR */
LDMFD sp!, {r0-r12, lr, pc} /* pop new task r0-r12, lr & pc */
/* 对R0 R12及LR、PC进行恢复 */
//ENDP
rt_hw_context_switch_to:
//EXPORT rt_hw_context_switch_to
LDR sp, [r0] /* get new task stack pointer */
/* 获得切换到线程的SP指针 */
LDMFD sp!, {r4} /* pop new task spsr */
/* 出栈R4寄存器保存了SPSR寄存器值 */
MSR spsr_cxsf, r4 /* SPSR */
LDMFD sp!, {r4} /* pop new task cpsr */
/* 出栈R4寄存器保存了CPSR寄存器值 */
MSR cpsr_cxsf, r4 /* CPSR */
LDMFD sp!, {r0-r12, lr, pc} /* pop new task r0-r12, lr & pc */
/* 恢复R0 R12LR及PC寄存器 */
//ENDP
rt_hw_context_switch_interrupt:
//EXPORT rt_hw_context_switch_interrupt
LDR r2, =rt_thread_switch_interrupt_flag
LDR r3, [r2] /* */
CMP r3, #1 /* 1 */
BEQ _reswitch /* 1_reswitch*/
MOV r3, #1 /* set rt_thread_switch_interrupt_flag to 1*/
/* 设置中断中切换标志位1 */
STR r3, [r2] /* */
LDR r2, =rt_interrupt_from_thread /* set rt_interrupt_from_thread*/
STR r0, [r2] /* 线*/
_reswitch:
LDR r2, =rt_interrupt_to_thread /* set rt_interrupt_to_thread*/
STR r1, [r2] /* 线*/
BX lr
//ENDP
//END

View File

@@ -0,0 +1,160 @@
;/*
; * Copyright (c) 2006-2022, RT-Thread Development Team
; *
; * SPDX-License-Identifier: Apache-2.0
; *
; * Change Logs:
; * Date Author Notes
; * 2009-01-20 Bernard first version
; * 2011-07-22 Bernard added thumb mode porting
; */
Mode_USR EQU 0x10
Mode_FIQ EQU 0x11
Mode_IRQ EQU 0x12
Mode_SVC EQU 0x13
Mode_ABT EQU 0x17
Mode_UND EQU 0x1B
Mode_SYS EQU 0x1F
I_Bit EQU 0x80 ; when I bit is set, IRQ is disabled
F_Bit EQU 0x40 ; when F bit is set, FIQ is disabled
NOINT EQU 0xc0 ; disable interrupt in psr
AREA |.text|, CODE, READONLY, ALIGN=2
ARM
REQUIRE8
PRESERVE8
;/*
; * rt_base_t rt_hw_interrupt_disable();
; */
rt_hw_interrupt_disable PROC
EXPORT rt_hw_interrupt_disable
MRS r0, cpsr
ORR r1, r0, #NOINT
MSR cpsr_c, r1
BX lr
ENDP
;/*
; * void rt_hw_interrupt_enable(rt_base_t level);
; */
rt_hw_interrupt_enable PROC
EXPORT rt_hw_interrupt_enable
MSR cpsr_c, r0
BX lr
ENDP
;/*
; * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
; * r0 --> from
; * r1 --> to
; */
rt_hw_context_switch PROC
EXPORT rt_hw_context_switch
STMFD sp!, {lr} ; push pc (lr should be pushed in place of PC)
STMFD sp!, {r0-r12, lr} ; push lr & register file
MRS r4, cpsr
TST lr, #0x01
BEQ _ARM_MODE
ORR r4, r4, #0x20 ; it's thumb code
_ARM_MODE
STMFD sp!, {r4} ; push cpsr
STR sp, [r0] ; store sp in preempted tasks TCB
LDR sp, [r1] ; get new task stack pointer
LDMFD sp!, {r4} ; pop new task cpsr to spsr
MSR spsr_cxsf, r4
BIC r4, r4, #0x20 ; must be ARM mode
MSR cpsr_cxsf, r4
LDMFD sp!, {r0-r12, lr, pc}^ ; pop new task r0-r12, lr & pc, copy spsr to cpsr
ENDP
;/*
; * void rt_hw_context_switch_to(rt_uint32 to);
; * r0 --> to
; */
rt_hw_context_switch_to PROC
EXPORT rt_hw_context_switch_to
LDR sp, [r0] ; get new task stack pointer
LDMFD sp!, {r4} ; pop new task cpsr to spsr
MSR spsr_cxsf, r4
BIC r4, r4, #0x20 ; must be ARM mode
MSR cpsr_cxsf, r4
LDMFD sp!, {r0-r12, lr, pc}^ ; pop new task r0-r12, lr & pc, copy spsr to cpsr
ENDP
;/*
; * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to);
; */
IMPORT rt_thread_switch_interrupt_flag
IMPORT rt_interrupt_from_thread
IMPORT rt_interrupt_to_thread
rt_hw_context_switch_interrupt PROC
EXPORT rt_hw_context_switch_interrupt
LDR r2, =rt_thread_switch_interrupt_flag
LDR r3, [r2]
CMP r3, #1
BEQ _reswitch
MOV r3, #1 ; set rt_thread_switch_interrupt_flag to 1
STR r3, [r2]
LDR r2, =rt_interrupt_from_thread ; set rt_interrupt_from_thread
STR r0, [r2]
_reswitch
LDR r2, =rt_interrupt_to_thread ; set rt_interrupt_to_thread
STR r1, [r2]
BX lr
ENDP
; /*
; * void rt_hw_context_switch_interrupt_do(rt_base_t flag)
; */
rt_hw_context_switch_interrupt_do PROC
EXPORT rt_hw_context_switch_interrupt_do
MOV r1, #0 ; clear flag
STR r1, [r0]
LDMFD sp!, {r0-r12,lr}; reload saved registers
STMFD sp!, {r0-r3} ; save r0-r3
MOV r1, sp
ADD sp, sp, #16 ; restore sp
SUB r2, lr, #4 ; save old task's pc to r2
MRS r3, spsr ; get cpsr of interrupt thread
; switch to SVC mode and no interrupt
MSR cpsr_c, #I_Bit:OR:F_Bit:OR:Mode_SVC
STMFD sp!, {r2} ; push old task's pc
STMFD sp!, {r4-r12,lr}; push old task's lr,r12-r4
MOV r4, r1 ; Special optimised code below
MOV r5, r3
LDMFD r4!, {r0-r3}
STMFD sp!, {r0-r3} ; push old task's r3-r0
STMFD sp!, {r5} ; push old task's cpsr
LDR r4, =rt_interrupt_from_thread
LDR r5, [r4]
STR sp, [r5] ; store sp in preempted tasks's TCB
LDR r6, =rt_interrupt_to_thread
LDR r6, [r6]
LDR sp, [r6] ; get new task's stack pointer
LDMFD sp!, {r4} ; pop new task's cpsr to spsr
MSR spsr_cxsf, r4
BIC r4, r4, #0x20 ; must be ARM mode
MSR cpsr_cxsf, r4
LDMFD sp!, {r0-r12,lr,pc}^ ; pop new task's r0-r12,lr & pc, copy spsr to cpsr
ENDP
END

View File

@@ -0,0 +1,183 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2011-06-15 aozima the first version for lpc214x
* 2013-03-29 aozima Modify the interrupt interface implementations.
*/
#include <rtthread.h>
#include <rthw.h>
#include "lpc214x.h"
#define MAX_HANDLERS 32
#define SVCMODE 0x13
extern rt_uint32_t rt_interrupt_nest;
/* exception and interrupt handler table */
struct rt_irq_desc irq_desc[MAX_HANDLERS];
/**
* @addtogroup LPC214x
*/
/*@{*/
/**
* This function will initialize thread stack
*
* @param tentry the entry of thread
* @param parameter the parameter of entry
* @param stack_addr the beginning stack address
* @param texit the function will be called when thread exit
*
* @return stack address
*/
rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter,
rt_uint8_t *stack_addr, void *texit)
{
unsigned long *stk;
stk = (unsigned long *)stack_addr;
*(stk) = (unsigned long)tentry; /* entry point */
*(--stk) = (unsigned long)texit; /* lr */
*(--stk) = 0; /* r12 */
*(--stk) = 0; /* r11 */
*(--stk) = 0; /* r10 */
*(--stk) = 0; /* r9 */
*(--stk) = 0; /* r8 */
*(--stk) = 0; /* r7 */
*(--stk) = 0; /* r6 */
*(--stk) = 0; /* r5 */
*(--stk) = 0; /* r4 */
*(--stk) = 0; /* r3 */
*(--stk) = 0; /* r2 */
*(--stk) = 0; /* r1 */
*(--stk) = (unsigned long)parameter; /* r0 : argument */
/* cpsr */
if ((rt_uint32_t)tentry & 0x01)
*(--stk) = SVCMODE | 0x20; /* thumb mode */
else
*(--stk) = SVCMODE; /* arm mode */
/* return task's current stack address */
return (rt_uint8_t *)stk;
}
/* exception and interrupt handler table */
rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread;
rt_uint32_t rt_thread_switch_interrupt_flag;
void rt_hw_interrupt_handler(int vector, void *param)
{
rt_kprintf("Unhandled interrupt %d occured!!!\n", vector);
}
/**
* This function will initialize hardware interrupt
*/
void rt_hw_interrupt_init(void)
{
rt_base_t index;
rt_uint32_t *vect_addr, *vect_ctl;
/* initialize VIC*/
VICIntEnClr = 0xffffffff;
VICVectAddr = 0;
/* set all to IRQ */
VICIntSelect = 0;
rt_memset(irq_desc, 0x00, sizeof(irq_desc));
for (index = 0; index < MAX_HANDLERS; index ++)
{
irq_desc[index].handler = rt_hw_interrupt_handler;
vect_addr = (rt_uint32_t *)(VIC_BASE_ADDR + 0x100 + (index << 2));
vect_ctl = (rt_uint32_t *)(VIC_BASE_ADDR + 0x200 + (index << 2));
*vect_addr = (rt_uint32_t)&irq_desc[index];
*vect_ctl = 0xF;
}
/* init interrupt nest, and context in thread sp */
rt_interrupt_nest = 0;
rt_interrupt_from_thread = 0;
rt_interrupt_to_thread = 0;
rt_thread_switch_interrupt_flag = 0;
}
/**
* This function will mask a interrupt.
* @param vector the interrupt number
*/
void rt_hw_interrupt_mask(int vector)
{
VICIntEnClr = (1 << vector);
}
/**
* This function will un-mask a interrupt.
* @param vector the interrupt number
*/
void rt_hw_interrupt_umask(int vector)
{
VICIntEnable = (1 << vector);
}
/**
* This function will install a interrupt service routine to a interrupt.
* @param vector the interrupt number
* @param handler the interrupt service routine to be installed
* @param param the interrupt service function parameter
* @param name the interrupt name
* @return old handler
*/
rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler,
void *param, const char *name)
{
rt_isr_handler_t old_handler = RT_NULL;
if(vector >= 0 && vector < MAX_HANDLERS)
{
rt_uint32_t* vect_ctl = (rt_uint32_t *)(VIC_BASE_ADDR + 0x200 + (vector << 2));
/* assign IRQ slot and enable this slot */
*vect_ctl = 0x20 | (vector & 0x1F);
old_handler = irq_desc[vector].handler;
if (handler != RT_NULL)
{
irq_desc[vector].handler = handler;
irq_desc[vector].param = param;
}
}
return old_handler;
}
void rt_hw_trap_irq(void)
{
int irqno;
struct rt_irq_desc* irq;
extern struct rt_irq_desc irq_desc[];
irq = (struct rt_irq_desc*) VICVectAddr;
irqno = ((rt_uint32_t) irq - (rt_uint32_t) &irq_desc[0])/sizeof(struct rt_irq_desc);
/* invoke isr */
irq->handler(irqno, irq->param);
/* acknowledge Interrupt */
// VICVectAddr = 0;
}
void rt_hw_trap_fiq(void)
{
rt_kprintf("fast interrupt request\n");
}
/*@}*/

View File

@@ -0,0 +1,393 @@
/***********************************************************************/
/* This file is part of the uVision/ARM development tools */
/* Copyright KEIL ELEKTRONIK GmbH 2002-2005 */
/***********************************************************************/
/* */
/* LPC214X.H: Header file for Philips LPC2141/42/44/46/48 */
/* */
/***********************************************************************/
#ifndef __LPC214x_H
#define __LPC214x_H
/* Vectored Interrupt Controller (VIC) */
#define VICIRQStatus (*((volatile unsigned long *) 0xFFFFF000))
#define VICFIQStatus (*((volatile unsigned long *) 0xFFFFF004))
#define VICRawIntr (*((volatile unsigned long *) 0xFFFFF008))
#define VICIntSelect (*((volatile unsigned long *) 0xFFFFF00C))
#define VICIntEnable (*((volatile unsigned long *) 0xFFFFF010))
#define VICIntEnClr (*((volatile unsigned long *) 0xFFFFF014))
#define VICSoftInt (*((volatile unsigned long *) 0xFFFFF018))
#define VICSoftIntClr (*((volatile unsigned long *) 0xFFFFF01C))
#define VICProtection (*((volatile unsigned long *) 0xFFFFF020))
#define VICVectAddr (*((volatile unsigned long *) 0xFFFFF030))
#define VICDefVectAddr (*((volatile unsigned long *) 0xFFFFF034))
#define VICVectAddr0 (*((volatile unsigned long *) 0xFFFFF100))
#define VICVectAddr1 (*((volatile unsigned long *) 0xFFFFF104))
#define VICVectAddr2 (*((volatile unsigned long *) 0xFFFFF108))
#define VICVectAddr3 (*((volatile unsigned long *) 0xFFFFF10C))
#define VICVectAddr4 (*((volatile unsigned long *) 0xFFFFF110))
#define VICVectAddr5 (*((volatile unsigned long *) 0xFFFFF114))
#define VICVectAddr6 (*((volatile unsigned long *) 0xFFFFF118))
#define VICVectAddr7 (*((volatile unsigned long *) 0xFFFFF11C))
#define VICVectAddr8 (*((volatile unsigned long *) 0xFFFFF120))
#define VICVectAddr9 (*((volatile unsigned long *) 0xFFFFF124))
#define VICVectAddr10 (*((volatile unsigned long *) 0xFFFFF128))
#define VICVectAddr11 (*((volatile unsigned long *) 0xFFFFF12C))
#define VICVectAddr12 (*((volatile unsigned long *) 0xFFFFF130))
#define VICVectAddr13 (*((volatile unsigned long *) 0xFFFFF134))
#define VICVectAddr14 (*((volatile unsigned long *) 0xFFFFF138))
#define VICVectAddr15 (*((volatile unsigned long *) 0xFFFFF13C))
#define VICVectCntl0 (*((volatile unsigned long *) 0xFFFFF200))
#define VICVectCntl1 (*((volatile unsigned long *) 0xFFFFF204))
#define VICVectCntl2 (*((volatile unsigned long *) 0xFFFFF208))
#define VICVectCntl3 (*((volatile unsigned long *) 0xFFFFF20C))
#define VICVectCntl4 (*((volatile unsigned long *) 0xFFFFF210))
#define VICVectCntl5 (*((volatile unsigned long *) 0xFFFFF214))
#define VICVectCntl6 (*((volatile unsigned long *) 0xFFFFF218))
#define VICVectCntl7 (*((volatile unsigned long *) 0xFFFFF21C))
#define VICVectCntl8 (*((volatile unsigned long *) 0xFFFFF220))
#define VICVectCntl9 (*((volatile unsigned long *) 0xFFFFF224))
#define VICVectCntl10 (*((volatile unsigned long *) 0xFFFFF228))
#define VICVectCntl11 (*((volatile unsigned long *) 0xFFFFF22C))
#define VICVectCntl12 (*((volatile unsigned long *) 0xFFFFF230))
#define VICVectCntl13 (*((volatile unsigned long *) 0xFFFFF234))
#define VICVectCntl14 (*((volatile unsigned long *) 0xFFFFF238))
#define VICVectCntl15 (*((volatile unsigned long *) 0xFFFFF23C))
/* Pin Connect Block */
#define PINSEL0 (*((volatile unsigned long *) 0xE002C000))
#define PINSEL1 (*((volatile unsigned long *) 0xE002C004))
#define PINSEL2 (*((volatile unsigned long *) 0xE002C014))
/* General Purpose Input/Output (GPIO) */
#define IOPIN0 (*((volatile unsigned long *) 0xE0028000))
#define IOSET0 (*((volatile unsigned long *) 0xE0028004))
#define IODIR0 (*((volatile unsigned long *) 0xE0028008))
#define IOCLR0 (*((volatile unsigned long *) 0xE002800C))
#define IOPIN1 (*((volatile unsigned long *) 0xE0028010))
#define IOSET1 (*((volatile unsigned long *) 0xE0028014))
#define IODIR1 (*((volatile unsigned long *) 0xE0028018))
#define IOCLR1 (*((volatile unsigned long *) 0xE002801C))
#define IO0PIN (*((volatile unsigned long *) 0xE0028000))
#define IO0SET (*((volatile unsigned long *) 0xE0028004))
#define IO0DIR (*((volatile unsigned long *) 0xE0028008))
#define IO0CLR (*((volatile unsigned long *) 0xE002800C))
#define IO1PIN (*((volatile unsigned long *) 0xE0028010))
#define IO1SET (*((volatile unsigned long *) 0xE0028014))
#define IO1DIR (*((volatile unsigned long *) 0xE0028018))
#define IO1CLR (*((volatile unsigned long *) 0xE002801C))
#define FIO0DIR (*((volatile unsigned long *) 0x3FFFC000))
#define FIO0MASK (*((volatile unsigned long *) 0x3FFFC010))
#define FIO0PIN (*((volatile unsigned long *) 0x3FFFC014))
#define FIO0SET (*((volatile unsigned long *) 0x3FFFC018))
#define FIO0CLR (*((volatile unsigned long *) 0x3FFFC01C))
#define FIO1DIR (*((volatile unsigned long *) 0x3FFFC020))
#define FIO1MASK (*((volatile unsigned long *) 0x3FFFC030))
#define FIO1PIN (*((volatile unsigned long *) 0x3FFFC034))
#define FIO1SET (*((volatile unsigned long *) 0x3FFFC038))
#define FIO1CLR (*((volatile unsigned long *) 0x3FFFC03C))
/* Memory Accelerator Module (MAM) */
#define MAMCR (*((volatile unsigned char *) 0xE01FC000))
#define MAMTIM (*((volatile unsigned char *) 0xE01FC004))
#define MEMMAP (*((volatile unsigned char *) 0xE01FC040))
/* Phase Locked Loop 0 (PLL0) */
#define PLL0CON (*((volatile unsigned char *) 0xE01FC080))
#define PLL0CFG (*((volatile unsigned char *) 0xE01FC084))
#define PLL0STAT (*((volatile unsigned short*) 0xE01FC088))
#define PLL0FEED (*((volatile unsigned char *) 0xE01FC08C))
/* Phase Locked Loop 1 (PLL1) */
#define PLL1CON (*((volatile unsigned char *) 0xE01FC0A0))
#define PLL1CFG (*((volatile unsigned char *) 0xE01FC0A4))
#define PLL1STAT (*((volatile unsigned short*) 0xE01FC0A8))
#define PLL1FEED (*((volatile unsigned char *) 0xE01FC0AC))
/* VPB Divider */
#define VPBDIV (*((volatile unsigned char *) 0xE01FC100))
/* Power Control */
#define PCON (*((volatile unsigned char *) 0xE01FC0C0))
#define PCONP (*((volatile unsigned long *) 0xE01FC0C4))
/* External Interrupts */
#define EXTINT (*((volatile unsigned char *) 0xE01FC140))
#define INTWAKE (*((volatile unsigned short*) 0xE01FC144))
#define EXTMODE (*((volatile unsigned char *) 0xE01FC148))
#define EXTPOLAR (*((volatile unsigned char *) 0xE01FC14C))
/* Reset */
#define RSID (*((volatile unsigned char *) 0xE01FC180))
/* Code Security / Debugging */
#define CSPR (*((volatile unsigned char *) 0xE01FC184))
/* System Control Miscellaneous */
#define SCS (*((volatile unsigned long *) 0xE01FC1A0))
/* Timer 0 */
#define T0IR (*((volatile unsigned long *) 0xE0004000))
#define T0TCR (*((volatile unsigned long *) 0xE0004004))
#define T0TC (*((volatile unsigned long *) 0xE0004008))
#define T0PR (*((volatile unsigned long *) 0xE000400C))
#define T0PC (*((volatile unsigned long *) 0xE0004010))
#define T0MCR (*((volatile unsigned long *) 0xE0004014))
#define T0MR0 (*((volatile unsigned long *) 0xE0004018))
#define T0MR1 (*((volatile unsigned long *) 0xE000401C))
#define T0MR2 (*((volatile unsigned long *) 0xE0004020))
#define T0MR3 (*((volatile unsigned long *) 0xE0004024))
#define T0CCR (*((volatile unsigned long *) 0xE0004028))
#define T0CR0 (*((volatile unsigned long *) 0xE000402C))
#define T0CR1 (*((volatile unsigned long *) 0xE0004030))
#define T0CR2 (*((volatile unsigned long *) 0xE0004034))
#define T0CR3 (*((volatile unsigned long *) 0xE0004038))
#define T0EMR (*((volatile unsigned long *) 0xE000403C))
#define T0CTCR (*((volatile unsigned long *) 0xE0004070))
/* Timer 1 */
#define T1IR (*((volatile unsigned long *) 0xE0008000))
#define T1TCR (*((volatile unsigned long *) 0xE0008004))
#define T1TC (*((volatile unsigned long *) 0xE0008008))
#define T1PR (*((volatile unsigned long *) 0xE000800C))
#define T1PC (*((volatile unsigned long *) 0xE0008010))
#define T1MCR (*((volatile unsigned long *) 0xE0008014))
#define T1MR0 (*((volatile unsigned long *) 0xE0008018))
#define T1MR1 (*((volatile unsigned long *) 0xE000801C))
#define T1MR2 (*((volatile unsigned long *) 0xE0008020))
#define T1MR3 (*((volatile unsigned long *) 0xE0008024))
#define T1CCR (*((volatile unsigned long *) 0xE0008028))
#define T1CR0 (*((volatile unsigned long *) 0xE000802C))
#define T1CR1 (*((volatile unsigned long *) 0xE0008030))
#define T1CR2 (*((volatile unsigned long *) 0xE0008034))
#define T1CR3 (*((volatile unsigned long *) 0xE0008038))
#define T1EMR (*((volatile unsigned long *) 0xE000803C))
#define T1CTCR (*((volatile unsigned long *) 0xE0008070))
/* Pulse Width Modulator (PWM) */
#define PWMIR (*((volatile unsigned long *) 0xE0014000))
#define PWMTCR (*((volatile unsigned long *) 0xE0014004))
#define PWMTC (*((volatile unsigned long *) 0xE0014008))
#define PWMPR (*((volatile unsigned long *) 0xE001400C))
#define PWMPC (*((volatile unsigned long *) 0xE0014010))
#define PWMMCR (*((volatile unsigned long *) 0xE0014014))
#define PWMMR0 (*((volatile unsigned long *) 0xE0014018))
#define PWMMR1 (*((volatile unsigned long *) 0xE001401C))
#define PWMMR2 (*((volatile unsigned long *) 0xE0014020))
#define PWMMR3 (*((volatile unsigned long *) 0xE0014024))
#define PWMMR4 (*((volatile unsigned long *) 0xE0014040))
#define PWMMR5 (*((volatile unsigned long *) 0xE0014044))
#define PWMMR6 (*((volatile unsigned long *) 0xE0014048))
#define PWMPCR (*((volatile unsigned long *) 0xE001404C))
#define PWMLER (*((volatile unsigned long *) 0xE0014050))
/* Universal Asynchronous Receiver Transmitter 0 (UART0) */
#define U0RBR (*((volatile unsigned char *) 0xE000C000))
#define U0THR (*((volatile unsigned char *) 0xE000C000))
#define U0IER (*((volatile unsigned long *) 0xE000C004))
#define U0IIR (*((volatile unsigned long *) 0xE000C008))
#define U0FCR (*((volatile unsigned char *) 0xE000C008))
#define U0LCR (*((volatile unsigned char *) 0xE000C00C))
#define U0MCR (*((volatile unsigned char *) 0xE000C010))
#define U0LSR (*((volatile unsigned char *) 0xE000C014))
#define U0MSR (*((volatile unsigned char *) 0xE000C018))
#define U0SCR (*((volatile unsigned char *) 0xE000C01C))
#define U0DLL (*((volatile unsigned char *) 0xE000C000))
#define U0DLM (*((volatile unsigned char *) 0xE000C004))
#define U0ACR (*((volatile unsigned long *) 0xE000C020))
#define U0FDR (*((volatile unsigned long *) 0xE000C028))
#define U0TER (*((volatile unsigned char *) 0xE000C030))
/* Universal Asynchronous Receiver Transmitter 1 (UART1) */
#define U1RBR (*((volatile unsigned char *) 0xE0010000))
#define U1THR (*((volatile unsigned char *) 0xE0010000))
#define U1IER (*((volatile unsigned long *) 0xE0010004))
#define U1IIR (*((volatile unsigned long *) 0xE0010008))
#define U1FCR (*((volatile unsigned char *) 0xE0010008))
#define U1LCR (*((volatile unsigned char *) 0xE001000C))
#define U1MCR (*((volatile unsigned char *) 0xE0010010))
#define U1LSR (*((volatile unsigned char *) 0xE0010014))
#define U1MSR (*((volatile unsigned char *) 0xE0010018))
#define U1SCR (*((volatile unsigned char *) 0xE001001C))
#define U1DLL (*((volatile unsigned char *) 0xE0010000))
#define U1DLM (*((volatile unsigned char *) 0xE0010004))
#define U1ACR (*((volatile unsigned long *) 0xE0010020))
#define U1FDR (*((volatile unsigned long *) 0xE0010028))
#define U1TER (*((volatile unsigned char *) 0xE0010030))
/* I2C Interface 0 */
#define I2C0CONSET (*((volatile unsigned char *) 0xE001C000))
#define I2C0STAT (*((volatile unsigned char *) 0xE001C004))
#define I2C0DAT (*((volatile unsigned char *) 0xE001C008))
#define I2C0ADR (*((volatile unsigned char *) 0xE001C00C))
#define I2C0SCLH (*((volatile unsigned short*) 0xE001C010))
#define I2C0SCLL (*((volatile unsigned short*) 0xE001C014))
#define I2C0CONCLR (*((volatile unsigned char *) 0xE001C018))
/* I2C Interface 1 */
#define I2C1CONSET (*((volatile unsigned char *) 0xE005C000))
#define I2C1STAT (*((volatile unsigned char *) 0xE005C004))
#define I2C1DAT (*((volatile unsigned char *) 0xE005C008))
#define I2C1ADR (*((volatile unsigned char *) 0xE005C00C))
#define I2C1SCLH (*((volatile unsigned short*) 0xE005C010))
#define I2C1SCLL (*((volatile unsigned short*) 0xE005C014))
#define I2C1CONCLR (*((volatile unsigned char *) 0xE005C018))
/* SPI0 (Serial Peripheral Interface 0) */
#define S0SPCR (*((volatile unsigned short*) 0xE0020000))
#define S0SPSR (*((volatile unsigned char *) 0xE0020004))
#define S0SPDR (*((volatile unsigned short*) 0xE0020008))
#define S0SPCCR (*((volatile unsigned char *) 0xE002000C))
#define S0SPINT (*((volatile unsigned char *) 0xE002001C))
/* SSP Controller (SPI1) */
#define SSPCR0 (*((volatile unsigned short*) 0xE0068000))
#define SSPCR1 (*((volatile unsigned char *) 0xE0068004))
#define SSPDR (*((volatile unsigned short*) 0xE0068008))
#define SSPSR (*((volatile unsigned char *) 0xE006800C))
#define SSPCPSR (*((volatile unsigned char *) 0xE0068010))
#define SSPIMSC (*((volatile unsigned char *) 0xE0068014))
#define SSPRIS (*((volatile unsigned char *) 0xE0068018))
#define SSPMIS (*((volatile unsigned char *) 0xE006801C))
#define SSPICR (*((volatile unsigned char *) 0xE0068020))
/* Real Time Clock */
#define ILR (*((volatile unsigned char *) 0xE0024000))
#define CTC (*((volatile unsigned short*) 0xE0024004))
#define CCR (*((volatile unsigned char *) 0xE0024008))
#define CIIR (*((volatile unsigned char *) 0xE002400C))
#define AMR (*((volatile unsigned char *) 0xE0024010))
#define CTIME0 (*((volatile unsigned long *) 0xE0024014))
#define CTIME1 (*((volatile unsigned long *) 0xE0024018))
#define CTIME2 (*((volatile unsigned long *) 0xE002401C))
#define SEC (*((volatile unsigned char *) 0xE0024020))
#define MIN (*((volatile unsigned char *) 0xE0024024))
#define HOUR (*((volatile unsigned char *) 0xE0024028))
#define DOM (*((volatile unsigned char *) 0xE002402C))
#define DOW (*((volatile unsigned char *) 0xE0024030))
#define DOY (*((volatile unsigned short*) 0xE0024034))
#define MONTH (*((volatile unsigned char *) 0xE0024038))
#define YEAR (*((volatile unsigned short*) 0xE002403C))
#define ALSEC (*((volatile unsigned char *) 0xE0024060))
#define ALMIN (*((volatile unsigned char *) 0xE0024064))
#define ALHOUR (*((volatile unsigned char *) 0xE0024068))
#define ALDOM (*((volatile unsigned char *) 0xE002406C))
#define ALDOW (*((volatile unsigned char *) 0xE0024070))
#define ALDOY (*((volatile unsigned short*) 0xE0024074))
#define ALMON (*((volatile unsigned char *) 0xE0024078))
#define ALYEAR (*((volatile unsigned short*) 0xE002407C))
#define PREINT (*((volatile unsigned short*) 0xE0024080))
#define PREFRAC (*((volatile unsigned short*) 0xE0024084))
/* A/D Converter 0 (AD0) */
#define AD0CR (*((volatile unsigned long *) 0xE0034000))
#define AD0GDR (*((volatile unsigned long *) 0xE0034004))
#define AD0STAT (*((volatile unsigned long *) 0xE0034030))
#define AD0INTEN (*((volatile unsigned long *) 0xE003400C))
#define AD0DR0 (*((volatile unsigned long *) 0xE0034010))
#define AD0DR1 (*((volatile unsigned long *) 0xE0034014))
#define AD0DR2 (*((volatile unsigned long *) 0xE0034018))
#define AD0DR3 (*((volatile unsigned long *) 0xE003401C))
#define AD0DR4 (*((volatile unsigned long *) 0xE0034020))
#define AD0DR5 (*((volatile unsigned long *) 0xE0034024))
#define AD0DR6 (*((volatile unsigned long *) 0xE0034028))
#define AD0DR7 (*((volatile unsigned long *) 0xE003402C))
/* A/D Converter 1 (AD1) */
#define AD1CR (*((volatile unsigned long *) 0xE0060000))
#define AD1GDR (*((volatile unsigned long *) 0xE0060004))
#define AD1STAT (*((volatile unsigned long *) 0xE0060030))
#define AD1INTEN (*((volatile unsigned long *) 0xE006000C))
#define AD1DR0 (*((volatile unsigned long *) 0xE0060010))
#define AD1DR1 (*((volatile unsigned long *) 0xE0060014))
#define AD1DR2 (*((volatile unsigned long *) 0xE0060018))
#define AD1DR3 (*((volatile unsigned long *) 0xE006001C))
#define AD1DR4 (*((volatile unsigned long *) 0xE0060020))
#define AD1DR5 (*((volatile unsigned long *) 0xE0060024))
#define AD1DR6 (*((volatile unsigned long *) 0xE0060028))
#define AD1DR7 (*((volatile unsigned long *) 0xE006002C))
/* A/D Converter Global */
#define ADGSR (*((volatile unsigned long *) 0xE0034008))
/* D/A Converter */
#define DACR (*((volatile unsigned long *) 0xE006C000))
/* Watchdog */
#define WDMOD (*((volatile unsigned char *) 0xE0000000))
#define WDTC (*((volatile unsigned long *) 0xE0000004))
#define WDFEED (*((volatile unsigned char *) 0xE0000008))
#define WDTV (*((volatile unsigned long *) 0xE000000C))
/* USB Controller */
#define USBIntSt (*((volatile unsigned long *) 0xE01FC1C0))
#define USBDevIntSt (*((volatile unsigned long *) 0xE0090000))
#define USBDevIntEn (*((volatile unsigned long *) 0xE0090004))
#define USBDevIntClr (*((volatile unsigned long *) 0xE0090008))
#define USBDevIntSet (*((volatile unsigned long *) 0xE009000C))
#define USBDevIntPri (*((volatile unsigned char *) 0xE009002C))
#define USBEpIntSt (*((volatile unsigned long *) 0xE0090030))
#define USBEpIntEn (*((volatile unsigned long *) 0xE0090034))
#define USBEpIntClr (*((volatile unsigned long *) 0xE0090038))
#define USBEpIntSet (*((volatile unsigned long *) 0xE009003C))
#define USBEpIntPri (*((volatile unsigned long *) 0xE0090040))
#define USBReEp (*((volatile unsigned long *) 0xE0090044))
#define USBEpInd (*((volatile unsigned long *) 0xE0090048))
#define USBMaxPSize (*((volatile unsigned long *) 0xE009004C))
#define USBRxData (*((volatile unsigned long *) 0xE0090018))
#define USBRxPLen (*((volatile unsigned long *) 0xE0090020))
#define USBTxData (*((volatile unsigned long *) 0xE009001C))
#define USBTxPLen (*((volatile unsigned long *) 0xE0090024))
#define USBCtrl (*((volatile unsigned long *) 0xE0090028))
#define USBCmdCode (*((volatile unsigned long *) 0xE0090010))
#define USBCmdData (*((volatile unsigned long *) 0xE0090014))
#define USBDMARSt (*((volatile unsigned long *) 0xE0090050))
#define USBDMARClr (*((volatile unsigned long *) 0xE0090054))
#define USBDMARSet (*((volatile unsigned long *) 0xE0090058))
#define USBUDCAH (*((volatile unsigned long *) 0xE0090080))
#define USBEpDMASt (*((volatile unsigned long *) 0xE0090084))
#define USBEpDMAEn (*((volatile unsigned long *) 0xE0090088))
#define USBEpDMADis (*((volatile unsigned long *) 0xE009008C))
#define USBDMAIntSt (*((volatile unsigned long *) 0xE0090090))
#define USBDMAIntEn (*((volatile unsigned long *) 0xE0090094))
#define USBEoTIntSt (*((volatile unsigned long *) 0xE00900A0))
#define USBEoTIntClr (*((volatile unsigned long *) 0xE00900A4))
#define USBEoTIntSet (*((volatile unsigned long *) 0xE00900A8))
#define USBNDDRIntSt (*((volatile unsigned long *) 0xE00900AC))
#define USBNDDRIntClr (*((volatile unsigned long *) 0xE00900B0))
#define USBNDDRIntSet (*((volatile unsigned long *) 0xE00900B4))
#define USBSysErrIntSt (*((volatile unsigned long *) 0xE00900B8))
#define USBSysErrIntClr (*((volatile unsigned long *) 0xE00900BC))
#define USBSysErrIntSet (*((volatile unsigned long *) 0xE00900C0))
#define VIC_BASE_ADDR 0xFFFFF000
enum LPC214x_INT
{
WDT_INT = 0,
SW_INT_reserved,
DbgCommRx_INT,
DbgCommTx_INT,
TIMER0_INT,
TIMER1_INT,
UART0_INT,
UART1_INT,
PWM0_INT,
I2C0_INT,
SP0_INT,
SP1_INT,
PLL_INT,
RTC_INT,
EINT0_INT,
EINT1_INT,
EINT2_INT,
EINT3_INT,
ADC0_INT,
I2C1_INT,
BOD_INT,
ADC1_INT,
USB_INT
};
#endif // __LPC214x_H

View File

@@ -0,0 +1,464 @@
;/*****************************************************************************/
;/* STARTUP.S: Startup file for Philips LPC2000 */
;/*****************************************************************************/
;/* <<< Use Configuration Wizard in Context Menu >>> */
;/*****************************************************************************/
;/* This file is part of the uVision/ARM development tools. */
;/* Copyright (c) 2005-2007 Keil Software. All rights reserved. */
;/* This software may only be used under the terms of a valid, current, */
;/* end user licence from KEIL for a compatible version of KEIL software */
;/* development tools. Nothing else gives you the right to use this software. */
;/*****************************************************************************/
;/*
; * The STARTUP.S code is executed after CPU Reset. This file may be
; * translated with the following SET symbols. In uVision these SET
; * symbols are entered under Options - ASM - Define.
; *
; * REMAP: when set the startup code initializes the register MEMMAP
; * which overwrites the settings of the CPU configuration pins. The
; * startup and interrupt vectors are remapped from:
; * 0x00000000 default setting (not remapped)
; * 0x80000000 when EXTMEM_MODE is used
; * 0x40000000 when RAM_MODE is used
; *
; * EXTMEM_MODE: when set the device is configured for code execution
; * from external memory starting at address 0x80000000.
; *
; * RAM_MODE: when set the device is configured for code execution
; * from on-chip RAM starting at address 0x40000000.
; *
; * EXTERNAL_MODE: when set the PIN2SEL values are written that enable
; * the external BUS at startup.
; */
; Standard definitions of Mode bits and Interrupt (I & F) flags in PSRs
Mode_USR EQU 0x10
Mode_FIQ EQU 0x11
Mode_IRQ EQU 0x12
Mode_SVC EQU 0x13
Mode_ABT EQU 0x17
Mode_UND EQU 0x1B
Mode_SYS EQU 0x1F
I_Bit EQU 0x80 ; when I bit is set, IRQ is disabled
F_Bit EQU 0x40 ; when F bit is set, FIQ is disabled
;// <h> Stack Configuration (Stack Sizes in Bytes)
;// <o0> Undefined Mode <0x0-0xFFFFFFFF:8>
;// <o1> Supervisor Mode <0x0-0xFFFFFFFF:8>
;// <o2> Abort Mode <0x0-0xFFFFFFFF:8>
;// <o3> Fast Interrupt Mode <0x0-0xFFFFFFFF:8>
;// <o4> Interrupt Mode <0x0-0xFFFFFFFF:8>
;// <o5> User/System Mode <0x0-0xFFFFFFFF:8>
;// </h>
UND_Stack_Size EQU 0x00000000
SVC_Stack_Size EQU 0x00000100
ABT_Stack_Size EQU 0x00000000
FIQ_Stack_Size EQU 0x00000000
IRQ_Stack_Size EQU 0x00000100
USR_Stack_Size EQU 0x00000100
ISR_Stack_Size EQU (UND_Stack_Size + SVC_Stack_Size + ABT_Stack_Size + \
FIQ_Stack_Size + IRQ_Stack_Size)
AREA STACK, NOINIT, READWRITE, ALIGN=3
Stack_Mem SPACE USR_Stack_Size
__initial_sp SPACE ISR_Stack_Size
Stack_Top
;// <h> Heap Configuration
;// <o> Heap Size (in Bytes) <0x0-0xFFFFFFFF>
;// </h>
Heap_Size EQU 0x00000000
AREA HEAP, NOINIT, READWRITE, ALIGN=3
__heap_base
Heap_Mem SPACE Heap_Size
__heap_limit
; VPBDIV definitions
VPBDIV EQU 0xE01FC100 ; VPBDIV Address
;// <e> VPBDIV Setup
;// <i> Peripheral Bus Clock Rate
;// <o1.0..1> VPBDIV: VPB Clock
;// <0=> VPB Clock = CPU Clock / 4
;// <1=> VPB Clock = CPU Clock
;// <2=> VPB Clock = CPU Clock / 2
;// <o1.4..5> XCLKDIV: XCLK Pin
;// <0=> XCLK Pin = CPU Clock / 4
;// <1=> XCLK Pin = CPU Clock
;// <2=> XCLK Pin = CPU Clock / 2
;// </e>
VPBDIV_SETUP EQU 0
VPBDIV_Val EQU 0x00000000
; Phase Locked Loop (PLL) definitions
PLL_BASE EQU 0xE01FC080 ; PLL Base Address
PLLCON_OFS EQU 0x00 ; PLL Control Offset
PLLCFG_OFS EQU 0x04 ; PLL Configuration Offset
PLLSTAT_OFS EQU 0x08 ; PLL Status Offset
PLLFEED_OFS EQU 0x0C ; PLL Feed Offset
PLLCON_PLLE EQU (1<<0) ; PLL Enable
PLLCON_PLLC EQU (1<<1) ; PLL Connect
PLLCFG_MSEL EQU (0x1F<<0) ; PLL Multiplier
PLLCFG_PSEL EQU (0x03<<5) ; PLL Divider
PLLSTAT_PLOCK EQU (1<<10) ; PLL Lock Status
;// <e> PLL Setup
;// <o1.0..4> MSEL: PLL Multiplier Selection
;// <1-32><#-1>
;// <i> M Value
;// <o1.5..6> PSEL: PLL Divider Selection
;// <0=> 1 <1=> 2 <2=> 4 <3=> 8
;// <i> P Value
;// </e>
PLL_SETUP EQU 1
PLLCFG_Val EQU 0x00000024
; Memory Accelerator Module (MAM) definitions
MAM_BASE EQU 0xE01FC000 ; MAM Base Address
MAMCR_OFS EQU 0x00 ; MAM Control Offset
MAMTIM_OFS EQU 0x04 ; MAM Timing Offset
;// <e> MAM Setup
;// <o1.0..1> MAM Control
;// <0=> Disabled
;// <1=> Partially Enabled
;// <2=> Fully Enabled
;// <i> Mode
;// <o2.0..2> MAM Timing
;// <0=> Reserved <1=> 1 <2=> 2 <3=> 3
;// <4=> 4 <5=> 5 <6=> 6 <7=> 7
;// <i> Fetch Cycles
;// </e>
MAM_SETUP EQU 1
MAMCR_Val EQU 0x00000002
MAMTIM_Val EQU 0x00000004
; External Memory Controller (EMC) definitions
EMC_BASE EQU 0xFFE00000 ; EMC Base Address
BCFG0_OFS EQU 0x00 ; BCFG0 Offset
BCFG1_OFS EQU 0x04 ; BCFG1 Offset
BCFG2_OFS EQU 0x08 ; BCFG2 Offset
BCFG3_OFS EQU 0x0C ; BCFG3 Offset
;// <e> External Memory Controller (EMC)
EMC_SETUP EQU 0
;// <e> Bank Configuration 0 (BCFG0)
;// <o1.0..3> IDCY: Idle Cycles <0-15>
;// <o1.5..9> WST1: Wait States 1 <0-31>
;// <o1.11..15> WST2: Wait States 2 <0-31>
;// <o1.10> RBLE: Read Byte Lane Enable
;// <o1.26> WP: Write Protect
;// <o1.27> BM: Burst ROM
;// <o1.28..29> MW: Memory Width <0=> 8-bit <1=> 16-bit
;// <2=> 32-bit <3=> Reserved
;// </e>
BCFG0_SETUP EQU 0
BCFG0_Val EQU 0x0000FBEF
;// <e> Bank Configuration 1 (BCFG1)
;// <o1.0..3> IDCY: Idle Cycles <0-15>
;// <o1.5..9> WST1: Wait States 1 <0-31>
;// <o1.11..15> WST2: Wait States 2 <0-31>
;// <o1.10> RBLE: Read Byte Lane Enable
;// <o1.26> WP: Write Protect
;// <o1.27> BM: Burst ROM
;// <o1.28..29> MW: Memory Width <0=> 8-bit <1=> 16-bit
;// <2=> 32-bit <3=> Reserved
;// </e>
BCFG1_SETUP EQU 0
BCFG1_Val EQU 0x0000FBEF
;// <e> Bank Configuration 2 (BCFG2)
;// <o1.0..3> IDCY: Idle Cycles <0-15>
;// <o1.5..9> WST1: Wait States 1 <0-31>
;// <o1.11..15> WST2: Wait States 2 <0-31>
;// <o1.10> RBLE: Read Byte Lane Enable
;// <o1.26> WP: Write Protect
;// <o1.27> BM: Burst ROM
;// <o1.28..29> MW: Memory Width <0=> 8-bit <1=> 16-bit
;// <2=> 32-bit <3=> Reserved
;// </e>
BCFG2_SETUP EQU 0
BCFG2_Val EQU 0x0000FBEF
;// <e> Bank Configuration 3 (BCFG3)
;// <o1.0..3> IDCY: Idle Cycles <0-15>
;// <o1.5..9> WST1: Wait States 1 <0-31>
;// <o1.11..15> WST2: Wait States 2 <0-31>
;// <o1.10> RBLE: Read Byte Lane Enable
;// <o1.26> WP: Write Protect
;// <o1.27> BM: Burst ROM
;// <o1.28..29> MW: Memory Width <0=> 8-bit <1=> 16-bit
;// <2=> 32-bit <3=> Reserved
;// </e>
BCFG3_SETUP EQU 0
BCFG3_Val EQU 0x0000FBEF
;// </e> End of EMC
; External Memory Pins definitions
PINSEL2 EQU 0xE002C014 ; PINSEL2 Address
PINSEL2_Val EQU 0x0E6149E4 ; CS0..3, OE, WE, BLS0..3,
; D0..31, A2..23, JTAG Pins
PRESERVE8
; Area Definition and Entry Point
; Startup Code must be linked first at Address at which it expects to run.
AREA RESET, CODE, READONLY
ARM
; Exception Vectors
; Mapped to Address 0.
; Absolute addressing mode must be used.
; Dummy Handlers are implemented as infinite loops which can be modified.
Vectors LDR PC, Reset_Addr
LDR PC, Undef_Addr
LDR PC, SWI_Addr
LDR PC, PAbt_Addr
LDR PC, DAbt_Addr
NOP ; Reserved Vector
LDR PC, IRQ_Addr
LDR PC, FIQ_Addr
Reset_Addr DCD Reset_Handler
Undef_Addr DCD Undef_Handler
SWI_Addr DCD SWI_Handler
PAbt_Addr DCD PAbt_Handler
DAbt_Addr DCD DAbt_Handler
DCD 0 ; Reserved Address
IRQ_Addr DCD IRQ_Handler
FIQ_Addr DCD FIQ_Handler
Undef_Handler B Undef_Handler
SWI_Handler B SWI_Handler
PAbt_Handler B PAbt_Handler
DAbt_Handler B DAbt_Handler
FIQ_Handler B FIQ_Handler
; Reset Handler
EXPORT Reset_Handler
Reset_Handler
; Setup External Memory Pins
IF :DEF:EXTERNAL_MODE
LDR R0, =PINSEL2
LDR R1, =PINSEL2_Val
STR R1, [R0]
ENDIF
; Setup External Memory Controller
IF EMC_SETUP <> 0
LDR R0, =EMC_BASE
IF BCFG0_SETUP <> 0
LDR R1, =BCFG0_Val
STR R1, [R0, #BCFG0_OFS]
ENDIF
IF BCFG1_SETUP <> 0
LDR R1, =BCFG1_Val
STR R1, [R0, #BCFG1_OFS]
ENDIF
IF BCFG2_SETUP <> 0
LDR R1, =BCFG2_Val
STR R1, [R0, #BCFG2_OFS]
ENDIF
IF BCFG3_SETUP <> 0
LDR R1, =BCFG3_Val
STR R1, [R0, #BCFG3_OFS]
ENDIF
ENDIF ; EMC_SETUP
; Setup VPBDIV
IF VPBDIV_SETUP <> 0
LDR R0, =VPBDIV
LDR R1, =VPBDIV_Val
STR R1, [R0]
ENDIF
; Setup PLL
IF PLL_SETUP <> 0
LDR R0, =PLL_BASE
MOV R1, #0xAA
MOV R2, #0x55
; Configure and Enable PLL
MOV R3, #PLLCFG_Val
STR R3, [R0, #PLLCFG_OFS]
MOV R3, #PLLCON_PLLE
STR R3, [R0, #PLLCON_OFS]
STR R1, [R0, #PLLFEED_OFS]
STR R2, [R0, #PLLFEED_OFS]
; Wait until PLL Locked
PLL_Loop LDR R3, [R0, #PLLSTAT_OFS]
ANDS R3, R3, #PLLSTAT_PLOCK
BEQ PLL_Loop
; Switch to PLL Clock
MOV R3, #(PLLCON_PLLE:OR:PLLCON_PLLC)
STR R3, [R0, #PLLCON_OFS]
STR R1, [R0, #PLLFEED_OFS]
STR R2, [R0, #PLLFEED_OFS]
ENDIF ; PLL_SETUP
; Setup MAM
IF MAM_SETUP <> 0
LDR R0, =MAM_BASE
MOV R1, #MAMTIM_Val
STR R1, [R0, #MAMTIM_OFS]
MOV R1, #MAMCR_Val
STR R1, [R0, #MAMCR_OFS]
ENDIF ; MAM_SETUP
; Memory Mapping (when Interrupt Vectors are in RAM)
MEMMAP EQU 0xE01FC040 ; Memory Mapping Control
IF :DEF:REMAP
LDR R0, =MEMMAP
IF :DEF:EXTMEM_MODE
MOV R1, #3
ELIF :DEF:RAM_MODE
MOV R1, #2
ELSE
MOV R1, #1
ENDIF
STR R1, [R0]
ENDIF
; Initialise Interrupt System
; ...
; Setup Stack for each mode
LDR R0, =Stack_Top
; Enter Undefined Instruction Mode and set its Stack Pointer
MSR CPSR_c, #Mode_UND:OR:I_Bit:OR:F_Bit
MOV SP, R0
SUB R0, R0, #UND_Stack_Size
; Enter Abort Mode and set its Stack Pointer
MSR CPSR_c, #Mode_ABT:OR:I_Bit:OR:F_Bit
MOV SP, R0
SUB R0, R0, #ABT_Stack_Size
; Enter FIQ Mode and set its Stack Pointer
MSR CPSR_c, #Mode_FIQ:OR:I_Bit:OR:F_Bit
MOV SP, R0
SUB R0, R0, #FIQ_Stack_Size
; Enter IRQ Mode and set its Stack Pointer
MSR CPSR_c, #Mode_IRQ:OR:I_Bit:OR:F_Bit
MOV SP, R0
SUB R0, R0, #IRQ_Stack_Size
; Enter Supervisor Mode and set its Stack Pointer
MSR CPSR_c, #Mode_SVC:OR:I_Bit:OR:F_Bit
MOV SP, R0
; SUB R0, R0, #SVC_Stack_Size
; Enter User Mode and set its Stack Pointer
; RT-Thread does not use user mode
; MSR CPSR_c, #Mode_USR
IF :DEF:__MICROLIB
EXPORT __initial_sp
ELSE
; MOV SP, R0
; SUB SL, SP, #USR_Stack_Size
ENDIF
; Enter the C code
IMPORT __main
LDR R0, =__main
BX R0
IMPORT rt_interrupt_enter
IMPORT rt_interrupt_leave
IMPORT rt_thread_switch_interrupt_flag
IMPORT rt_interrupt_from_thread
IMPORT rt_interrupt_to_thread
IMPORT rt_hw_trap_irq
IMPORT rt_hw_context_switch_interrupt_do
IRQ_Handler PROC
EXPORT IRQ_Handler
STMFD sp!, {r0-r12,lr}
BL rt_interrupt_enter
BL rt_hw_trap_irq
BL rt_interrupt_leave
; if rt_thread_switch_interrupt_flag set, jump to
; rt_hw_context_switch_interrupt_do and don't return
LDR r0, =rt_thread_switch_interrupt_flag
LDR r1, [r0]
CMP r1, #1
BEQ rt_hw_context_switch_interrupt_do
LDMFD sp!, {r0-r12,lr}
SUBS pc, lr, #4
ENDP
IF :DEF:__MICROLIB
EXPORT __heap_base
EXPORT __heap_limit
ELSE
; User Initial Stack & Heap
AREA |.text|, CODE, READONLY
IMPORT __use_two_region_memory
EXPORT __user_initial_stackheap
__user_initial_stackheap
LDR R0, = Heap_Mem
LDR R1, =(Stack_Mem + USR_Stack_Size)
LDR R2, = (Heap_Mem + Heap_Size)
LDR R3, = Stack_Mem
BX LR
ENDIF
END

View File

@@ -0,0 +1,320 @@
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
*/
.extern main /* 引入外部C入口 */
.extern rt_interrupt_enter
.extern rt_interrupt_leave
.extern rt_thread_switch_interrupt_flag
.extern rt_interrupt_from_thread
.extern rt_interrupt_to_thread
.extern rt_hw_trap_irq
.global start
.global endless_loop
.global rt_hw_context_switch_interrupt_do
/* Standard definitions of Mode bits and Interrupt (I & F) flags in PSRs */
.set MODE_USR, 0x10 /* User Mode */
.set MODE_FIQ, 0x11 /* FIQ Mode */
.set MODE_IRQ, 0x12 /* IRQ Mode */
.set MODE_SVC, 0x13 /* Supervisor Mode */
.set MODE_ABT, 0x17 /* Abort Mode */
.set MODE_UND, 0x1B /* Undefined Mode */
.set MODE_SYS, 0x1F /* System Mode */
.equ I_BIT, 0x80 /* when I bit is set, IRQ is disabled */
.equ F_BIT, 0x40 /* when F bit is set, FIQ is disabled */
.equ I_Bit, 0x80 /* when I bit is set, IRQ is disabled */
.equ F_Bit, 0x40 /* when F bit is set, FIQ is disabled */
/* VPBDIV definitions*/
.equ VPBDIV, 0xE01FC100
.set VPBDIV_VALUE, 0x00000000
/* Phase Locked Loop (PLL) definitions*/
.equ PLL_BASE, 0xE01FC080 /* PLL Base Address */
.equ PLLCON_OFS, 0x00 /* PLL Control Offset */
.equ PLLCFG_OFS, 0x04 /* PLL Configuration Offset */
.equ PLLSTAT_OFS, 0x08 /* PLL Status Offset */
.equ PLLFEED_OFS, 0x0C /* PLL Feed Offset */
.equ PLLCON_PLLE, (1<<0) /* PLL Enable */
.equ PLLCON_PLLC, (1<<1) /* PLL Connect */
.equ PLLCFG_MSEL, (0x1F<<0) /* PLL Multiplier */
.equ PLLCFG_PSEL, (0x03<<5) /* PLL Divider */
.equ PLLSTAT_PLOCK, (1<<10) /* PLL Lock Status */
.equ PLLCFG_Val, 0x00000024 /* <o1.0..4> MSEL: PLL Multiplier Selection,<o1.5..6> PSEL: PLL Divider Selection */
.equ MEMMAP, 0xE01FC040 /*Memory Mapping Control*/
/* Memory Accelerator Module (MAM) definitions*/
.equ MAM_BASE, 0xE01FC000
.equ MAMCR_OFS, 0x00
.equ MAMTIM_OFS, 0x04
.equ MAMCR_Val, 0x00000002
.equ MAMTIM_Val, 0x00000004
.equ VICIntEnClr, 0xFFFFF014
.equ VICIntSelect, 0xFFFFF00C
/************* 目标配置结束 *************/
/* Setup the operating mode & stack.*/
/* --------------------------------- */
.global _reset
_reset:
.code 32
.align 0
/************************* PLL_SETUP **********************************/
ldr r0, =PLL_BASE
mov r1, #0xAA
mov r2, #0x55
/* Configure and Enable PLL */
mov r3, #PLLCFG_Val
str r3, [r0, #PLLCFG_OFS]
mov r3, #PLLCON_PLLE
str r3, [r0, #PLLCON_OFS]
str r1, [r0, #PLLFEED_OFS]
str r2, [r0, #PLLFEED_OFS]
/* Wait until PLL Locked */
PLL_Locked_loop:
ldr r3, [r0, #PLLSTAT_OFS]
ands r3, r3, #PLLSTAT_PLOCK
beq PLL_Locked_loop
/* Switch to PLL Clock */
mov r3, #(PLLCON_PLLE|PLLCON_PLLC)
str r3, [r0, #PLLCON_OFS]
str r1, [r0, #PLLFEED_OFS]
str R2, [r0, #PLLFEED_OFS]
/************************* PLL_SETUP **********************************/
/************************ Setup VPBDIV ********************************/
ldr r0, =VPBDIV
ldr r1, =VPBDIV_VALUE
str r1, [r0]
/************************ Setup VPBDIV ********************************/
/************** Setup MAM **************/
ldr r0, =MAM_BASE
mov r1, #MAMTIM_Val
str r1, [r0, #MAMTIM_OFS]
mov r1, #MAMCR_Val
str r1, [r0, #MAMCR_OFS]
/************** Setup MAM **************/
/************************ setup stack *********************************/
ldr r0, .undefined_stack_top
sub r0, r0, #4
msr CPSR_c, #MODE_UND|I_BIT|F_BIT /* Undefined Instruction Mode */
mov sp, r0
ldr r0, .abort_stack_top
sub r0, r0, #4
msr CPSR_c, #MODE_ABT|I_BIT|F_BIT /* Abort Mode */
mov sp, r0
ldr r0, .fiq_stack_top
sub r0, r0, #4
msr CPSR_c, #MODE_FIQ|I_BIT|F_BIT /* FIQ Mode */
mov sp, r0
ldr r0, .irq_stack_top
sub r0, r0, #4
msr CPSR_c, #MODE_IRQ|I_BIT|F_BIT /* IRQ Mode */
mov sp, r0
ldr r0, .svc_stack_top
sub r0, r0, #4
msr CPSR_c, #MODE_SVC|I_BIT|F_BIT /* Supervisor Mode */
mov sp, r0
/************************ setup stack ********************************/
/* copy .data to SRAM */
ldr r1, =_sidata /* .data start in image */
ldr r2, =_edata /* .data end in image */
ldr r3, =_sdata /* sram data start */
data_loop:
ldr r0, [r1, #0]
str r0, [r3]
add r1, r1, #4
add r3, r3, #4
cmp r3, r2 /* check if data to clear */
blo data_loop /* loop until done */
/* clear .bss */
mov r0,#0 /* get a zero */
ldr r1,=__bss_start /* bss start */
ldr r2,=__bss_end /* bss end */
bss_loop:
cmp r1,r2 /* check if data to clear */
strlo r0,[r1],#4 /* clear 4 bytes */
blo bss_loop /* loop until done */
/* call C++ constructors of global objects */
ldr r0, =__ctors_start__
ldr r1, =__ctors_end__
ctor_loop:
cmp r0, r1
beq ctor_end
ldr r2, [r0], #4
stmfd sp!, {r0-r1}
mov lr, pc
bx r2
ldmfd sp!, {r0-r1}
b ctor_loop
ctor_end:
/* enter C code */
bl main
.align 0
.undefined_stack_top:
.word _undefined_stack_top
.abort_stack_top:
.word _abort_stack_top
.fiq_stack_top:
.word _fiq_stack_top
.irq_stack_top:
.word _irq_stack_top
.svc_stack_top:
.word _svc_stack_top
/*********************** END Clear BSS ******************************/
.section .init,"ax"
.code 32
.align 0
.globl _start
_start:
ldr pc, __start /* reset - _start */
ldr pc, _undf /* undefined - _undf */
ldr pc, _swi /* SWI - _swi */
ldr pc, _pabt /* program abort - _pabt */
ldr pc, _dabt /* data abort - _dabt */
.word 0xB8A06F58 /* reserved */
ldr pc, __IRQ_Handler /* IRQ - read the VIC */
ldr pc, _fiq /* FIQ - _fiq */
__start:.word _reset
_undf: .word __undf /* undefined */
_swi: .word __swi /* SWI */
_pabt: .word __pabt /* program abort */
_dabt: .word __dabt /* data abort */
temp1: .word 0
__IRQ_Handler: .word IRQ_Handler
_fiq: .word __fiq /* FIQ */
__undf: b . /* undefined */
__swi : b .
__pabt: b . /* program abort */
__dabt: b . /* data abort */
__fiq : b . /* FIQ */
/* IRQ入口 */
IRQ_Handler :
stmfd sp!, {r0-r12,lr} /* R0 R12LR */
bl rt_interrupt_enter /* RT-Thread */
bl rt_hw_trap_irq /* */
bl rt_interrupt_leave /* ; 通知RT-Thread要离开中断模式 */
/* 如果设置了rt_thread_switch_interrupt_flag进行中断中的线程上下文处理 */
ldr r0, =rt_thread_switch_interrupt_flag
ldr r1, [r0]
cmp r1, #1
beq rt_hw_context_switch_interrupt_do /* */
/* 如果跳转了,将不会回来 */
ldmfd sp!, {r0-r12,lr} /* */
subs pc, lr, #4 /* IRQ */
/*
* void rt_hw_context_switch_interrupt_do(rt_base_t flag)
*
*/
rt_hw_context_switch_interrupt_do:
mov r1, #0 /* clear flag */
/* 清楚中断中切换标志 */
str r1, [r0] /* */
ldmfd sp!, {r0-r12,lr}/* reload saved registers */
/* 先恢复被中断线程的上下文 */
stmfd sp!, {r0-r3} /* save r0-r3 */
/* 对R0 R3压栈因为后面会用到 */
mov r1, sp /* R1 */
add sp, sp, #16 /* restore sp */
/* 恢复IRQ的栈后面会跳出IRQ模式 */
sub r2, lr, #4 /* save old task's pc to r2 */
/* 保存切换出线程的PC到R2 */
mrs r3, spsr /* disable interrupt CPSRR3 */
/* 获得SPSR寄存器值 */
orr r0, r3, #I_BIT|F_BIT
msr spsr_c, r0 /* SPSRIRQ/FIQ */
ldr r0, =.+8 /* +8R0 switch to interrupted task's stack */
movs pc, r0 /* 退IRQSPSR */
/* IRQ
; R0寄存器中的位置实际就是下一条指令
; 即PC继续往下走
; 此时
; 模式已经换成中断前的SVC模式
; SP寄存器也是SVC模式下的栈寄存器
; R1保存IRQ模式下的栈指针
; R2保存切换出线程的PC
; R3保存切换出线程的CPSR */
stmfd sp!, {r2} /* push old task's pc */
/* 保存切换出任务的PC */
stmfd sp!, {r4-r12,lr}/* push old task's lr,r12-r4 */
/* 保存R4 R12LR寄存器 */
mov r4, r1 /* Special optimised code below */
/* R1保存有压栈R0 R3处的栈位置 */
mov r5, r3 /* R3线CPSR */
ldmfd r4!, {r0-r3} /* R0 R3 */
stmfd sp!, {r0-r3} /* push old task's r3-r0 */
/* R0 R3压栈到切换出线程 */
stmfd sp!, {r5} /* push old task's psr */
/* 切换出线程CPSR压栈 */
mrs r4, spsr
stmfd sp!, {r4} /* push old task's spsr */
/* 切换出线程SPSR压栈 */
ldr r4, =rt_interrupt_from_thread
ldr r5, [r4]
str sp, [r5] /* store sp in preempted tasks's TCB */
/* 保存切换出线程的SP指针 */
ldr r6, =rt_interrupt_to_thread
ldr r6, [r6]
ldr sp, [r6] /* get new task's stack pointer */
/* 获得切换到线程的栈 */
ldmfd sp!, {r4} /* pop new task's spsr */
/* 恢复SPSR */
msr SPSR_cxsf, r4
ldmfd sp!, {r4} /* pop new task's psr */
/* 恢复CPSR */
msr CPSR_cxsf, r4
ldmfd sp!, {r0-r12,lr,pc} /* pop new task's r0-r12,lr & pc */
/* 恢复R0 R12LR及PC寄存器 */
/* 代码加密功能 */
#if defined(CODE_PROTECTION)
.org 0x01FC
.word 0x87654321
#endif