summaryrefslogtreecommitdiff
path: root/libcpu
diff options
context:
space:
mode:
Diffstat (limited to 'libcpu')
-rw-r--r--libcpu/arm/AT91SAM7S/AT91SAM7S.h297
-rw-r--r--libcpu/arm/AT91SAM7S/context_gcc.S94
-rw-r--r--libcpu/arm/AT91SAM7S/context_rvds.S107
-rw-r--r--libcpu/arm/AT91SAM7S/cpu.c42
-rw-r--r--libcpu/arm/AT91SAM7S/interrupt.c91
-rw-r--r--libcpu/arm/AT91SAM7S/serial.c387
-rw-r--r--libcpu/arm/AT91SAM7S/serial.h56
-rw-r--r--libcpu/arm/AT91SAM7S/stack.c60
-rw-r--r--libcpu/arm/AT91SAM7S/start_gcc.S237
-rw-r--r--libcpu/arm/AT91SAM7S/start_rvds.S498
-rw-r--r--libcpu/arm/AT91SAM7S/trap.c40
-rw-r--r--libcpu/arm/AT91SAM7X/AT91SAM7X.h342
-rw-r--r--libcpu/arm/AT91SAM7X/context_gcc.S99
-rw-r--r--libcpu/arm/AT91SAM7X/context_rvds.S107
-rw-r--r--libcpu/arm/AT91SAM7X/cpu.c42
-rw-r--r--libcpu/arm/AT91SAM7X/interrupt.c91
-rw-r--r--libcpu/arm/AT91SAM7X/mii.h156
-rw-r--r--libcpu/arm/AT91SAM7X/sam7x_emac.c554
-rw-r--r--libcpu/arm/AT91SAM7X/sam7x_emac.h64
-rw-r--r--libcpu/arm/AT91SAM7X/serial.c396
-rw-r--r--libcpu/arm/AT91SAM7X/serial.h56
-rw-r--r--libcpu/arm/AT91SAM7X/stack.c60
-rw-r--r--libcpu/arm/AT91SAM7X/start_gcc.S235
-rw-r--r--libcpu/arm/AT91SAM7X/start_rvds.S498
-rw-r--r--libcpu/arm/AT91SAM7X/trap.c40
-rw-r--r--libcpu/arm/common/backtrace.c67
-rw-r--r--libcpu/arm/common/div0.c4
-rw-r--r--libcpu/arm/common/divsi3.S393
-rw-r--r--libcpu/arm/common/showmem.c42
-rw-r--r--libcpu/arm/lm3s/context_rvds.S178
-rw-r--r--libcpu/arm/lm3s/cpu.c42
-rw-r--r--libcpu/arm/lm3s/interrupt.c25
-rw-r--r--libcpu/arm/lm3s/kservice.c42
-rw-r--r--libcpu/arm/lm3s/serial.c362
-rw-r--r--libcpu/arm/lm3s/stack.c59
-rw-r--r--libcpu/arm/lm3s/start_rvds.S251
-rw-r--r--libcpu/arm/lpc214x/LPC214x.h393
-rw-r--r--libcpu/arm/lpc214x/context_gcc.S102
-rw-r--r--libcpu/arm/lpc214x/context_rvds.s107
-rw-r--r--libcpu/arm/lpc214x/cpu.c42
-rw-r--r--libcpu/arm/lpc214x/interrupt.c105
-rw-r--r--libcpu/arm/lpc214x/serial.c387
-rw-r--r--libcpu/arm/lpc214x/stack.c61
-rw-r--r--libcpu/arm/lpc214x/start_rvds.s508
-rw-r--r--libcpu/arm/lpc214x/startup_gcc.S350
-rw-r--r--libcpu/arm/lpc214x/trap.c40
-rw-r--r--libcpu/arm/lpc24xx/LPC24xx.h1201
-rw-r--r--libcpu/arm/lpc24xx/context_gcc.S99
-rw-r--r--libcpu/arm/lpc24xx/context_rvds.s107
-rw-r--r--libcpu/arm/lpc24xx/cpu.c42
-rw-r--r--libcpu/arm/lpc24xx/interrupt.c86
-rw-r--r--libcpu/arm/lpc24xx/serial.c149
-rw-r--r--libcpu/arm/lpc24xx/stack.c60
-rw-r--r--libcpu/arm/lpc24xx/start_gcc.S214
-rw-r--r--libcpu/arm/lpc24xx/start_rvds.s1581
-rw-r--r--libcpu/arm/lpc24xx/trap.c132
-rw-r--r--libcpu/arm/s3c44b0/context_gcc.S99
-rw-r--r--libcpu/arm/s3c44b0/context_rvds.s107
-rw-r--r--libcpu/arm/s3c44b0/cpu.c122
-rw-r--r--libcpu/arm/s3c44b0/interrupt.c148
-rw-r--r--libcpu/arm/s3c44b0/s3c44b0.h346
-rw-r--r--libcpu/arm/s3c44b0/serial.c118
-rw-r--r--libcpu/arm/s3c44b0/stack.c60
-rw-r--r--libcpu/arm/s3c44b0/start_gcc.S257
-rw-r--r--libcpu/arm/s3c44b0/start_rvds.s1072
-rw-r--r--libcpu/arm/s3c44b0/trap.c181
66 files changed, 14390 insertions, 0 deletions
diff --git a/libcpu/arm/AT91SAM7S/AT91SAM7S.h b/libcpu/arm/AT91SAM7S/AT91SAM7S.h
new file mode 100644
index 0000000000..3f0fef7097
--- /dev/null
+++ b/libcpu/arm/AT91SAM7S/AT91SAM7S.h
@@ -0,0 +1,297 @@
+/*
+ * File : at91sam7s.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Develop Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2006-08-23 Bernard first version
+ */
+
+#ifndef __AT91SAM7S_H__
+#define __AT91SAM7S_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define AT91_REG *(volatile unsigned int *) /* Hardware register definition */
+
+/* ========== Register definition for TC0 peripheral ========== */
+#define AT91C_TC0_SR (AT91_REG(0xFFFA0020)) /* TC0 Status Register */
+#define AT91C_TC0_RC (AT91_REG(0xFFFA001C)) /* TC0 Register C */
+#define AT91C_TC0_RB (AT91_REG(0xFFFA0018)) /* TC0 Register B */
+#define AT91C_TC0_CCR (AT91_REG(0xFFFA0000)) /* TC0 Channel Control Register */
+#define AT91C_TC0_CMR (AT91_REG(0xFFFA0004)) /* TC0 Channel Mode Register (Capture Mode / Waveform Mode) */
+#define AT91C_TC0_IER (AT91_REG(0xFFFA0024)) /* TC0 Interrupt Enable Register */
+#define AT91C_TC0_RA (AT91_REG(0xFFFA0014)) /* TC0 Register A */
+#define AT91C_TC0_IDR (AT91_REG(0xFFFA0028)) /* TC0 Interrupt Disable Register */
+#define AT91C_TC0_CV (AT91_REG(0xFFFA0010)) /* TC0 Counter Value */
+#define AT91C_TC0_IMR (AT91_REG(0xFFFA002C)) /* TC0 Interrupt Mask Register */
+
+/* ========== Register definition for TC1 peripheral ========== */
+#define AT91C_TC1_RB (AT91_REG(0xFFFA0058)) /* TC1 Register B */
+#define AT91C_TC1_CCR (AT91_REG(0xFFFA0040)) /* TC1 Channel Control Register */
+#define AT91C_TC1_IER (AT91_REG(0xFFFA0064)) /* TC1 Interrupt Enable Register */
+#define AT91C_TC1_IDR (AT91_REG(0xFFFA0068)) /* TC1 Interrupt Disable Register */
+#define AT91C_TC1_SR (AT91_REG(0xFFFA0060)) /* TC1 Status Register */
+#define AT91C_TC1_CMR (AT91_REG(0xFFFA0044)) /* TC1 Channel Mode Register (Capture Mode / Waveform Mode) */
+#define AT91C_TC1_RA (AT91_REG(0xFFFA0054)) /* TC1 Register A */
+#define AT91C_TC1_RC (AT91_REG(0xFFFA005C)) /* TC1 Register C */
+#define AT91C_TC1_IMR (AT91_REG(0xFFFA006C)) /* TC1 Interrupt Mask Register */
+#define AT91C_TC1_CV (AT91_REG(0xFFFA0050)) /* TC1 Counter Value */
+
+/* ========== Register definition for TC2 peripheral ========== */
+#define AT91C_TC2_CMR (AT91_REG(0xFFFA0084)) /* TC2 Channel Mode Register (Capture Mode / Waveform Mode) */
+#define AT91C_TC2_CCR (AT91_REG(0xFFFA0080)) /* TC2 Channel Control Register */
+#define AT91C_TC2_CV (AT91_REG(0xFFFA0090)) /* TC2 Counter Value */
+#define AT91C_TC2_RA (AT91_REG(0xFFFA0094)) /* TC2 Register A */
+#define AT91C_TC2_RB (AT91_REG(0xFFFA0098)) /* TC2 Register B */
+#define AT91C_TC2_IDR (AT91_REG(0xFFFA00A8)) /* TC2 Interrupt Disable Register */
+#define AT91C_TC2_IMR (AT91_REG(0xFFFA00AC)) /* TC2 Interrupt Mask Register */
+#define AT91C_TC2_RC (AT91_REG(0xFFFA009C)) /* TC2 Register C */
+#define AT91C_TC2_IER (AT91_REG(0xFFFA00A4)) /* TC2 Interrupt Enable Register */
+#define AT91C_TC2_SR (AT91_REG(0xFFFA00A0)) /* TC2 Status Register */
+
+/* ========== Register definition for PITC peripheral ========== */
+#define AT91C_PITC_PIVR (AT91_REG(0xFFFFFD38)) /* PITC Period Interval Value Register */
+#define AT91C_PITC_PISR (AT91_REG(0xFFFFFD34)) /* PITC Period Interval Status Register */
+#define AT91C_PITC_PIIR (AT91_REG(0xFFFFFD3C)) /* PITC Period Interval Image Register */
+#define AT91C_PITC_PIMR (AT91_REG(0xFFFFFD30)) /* PITC Period Interval Mode Register */
+
+/* ========== Register definition for UDP peripheral ========== */
+#define AT91C_UDP_NUM (AT91_REG(0xFFFB0000)) /* UDP Frame Number Register */
+#define AT91C_UDP_STAT (AT91_REG(0xFFFB0004)) /* UDP Global State Register */
+#define AT91C_UDP_FADDR (AT91_REG(0xFFFB0008)) /* UDP Function Address Register */
+#define AT91C_UDP_IER (AT91_REG(0xFFFB0010)) /* UDP Interrupt Enable Register */
+#define AT91C_UDP_IDR (AT91_REG(0xFFFB0014)) /* UDP Interrupt Disable Register */
+#define AT91C_UDP_IMR (AT91_REG(0xFFFB0018)) /* UDP Interrupt Mask Register */
+#define AT91C_UDP_ISR (AT91_REG(0xFFFB001C)) /* UDP Interrupt Status Register */
+#define AT91C_UDP_ICR (AT91_REG(0xFFFB0020)) /* UDP Interrupt Clear Register */
+#define AT91C_UDP_RSTEP (AT91_REG(0xFFFB0028)) /* UDP Reset Endpoint Register */
+#define AT91C_UDP_CSR0 (AT91_REG(0xFFFB0030)) /* UDP Endpoint Control and Status Register */
+#define AT91C_UDP_CSR(n) (*(&AT91C_UDP_CSR0 + n))
+#define AT91C_UDP_FDR0 (AT91_REG(0xFFFB0050)) /* UDP Endpoint FIFO Data Register */
+#define AT91C_UDP_FDR(n) (*(&AT91C_UDP_FDR0 + n))
+#define AT91C_UDP_TXVC (AT91_REG(0xFFFB0074)) /* UDP Transceiver Control Register */
+
+/* ========== Register definition for US0 peripheral ========== */
+#define AT91C_US0_CR (AT91_REG(0xFFFC0000)) /* US0 Control Register */
+#define AT91C_US0_MR (AT91_REG(0xFFFC0004)) /* US0 Mode Register */
+#define AT91C_US0_IER (AT91_REG(0xFFFC0008)) /* US0 Interrupt Enable Register */
+#define AT91C_US0_IDR (AT91_REG(0xFFFC000C)) /* US0 Interrupt Disable Register */
+#define AT91C_US0_IMR (AT91_REG(0xFFFC0010)) /* US0 Interrupt Mask Register */
+#define AT91C_US0_CSR (AT91_REG(0xFFFC0014)) /* US0 Channel Status Register */
+#define AT91C_US0_RHR (AT91_REG(0xFFFC0018)) /* US0 Receiver Holding Register */
+#define AT91C_US0_THR (AT91_REG(0xFFFC001C)) /* US0 Transmitter Holding Register */
+#define AT91C_US0_BRGR (AT91_REG(0xFFFC0020)) /* US0 Baud Rate Generator Register */
+#define AT91C_US0_RTOR (AT91_REG(0xFFFC0024)) /* US0 Receiver Time-out Register */
+#define AT91C_US0_TTGR (AT91_REG(0xFFFC0028)) /* US0 Transmitter Time-guard Register */
+#define AT91C_US0_NER (AT91_REG(0xFFFC0044)) /* US0 Nb Errors Register */
+#define AT91C_US0_FIDI (AT91_REG(0xFFFC0040)) /* US0 FI_DI_Ratio Register */
+#define AT91C_US0_IF (AT91_REG(0xFFFC004C)) /* US0 IRDA_FILTER Register */
+
+/* ========== Register definition for AIC peripheral ========== */
+#define AT91C_AIC_SMR0 (AT91_REG(0xFFFFF000)) /* AIC Source Mode Register */
+#define AT91C_AIC_SMR(n) (*(&AT91C_AIC_SMR0 + n))
+#define AT91C_AIC_SVR0 (AT91_REG(0xFFFFF080)) /* AIC Source Vector Register */
+#define AT91C_AIC_SVR(n) (*(&AT91C_AIC_SVR0 + n))
+#define AT91C_AIC_IVR (AT91_REG(0xFFFFF100)) /* AIC Interrupt Vector Register */
+#define AT91C_AIC_FVR (AT91_REG(0xFFFFF104)) /* AIC FIQ Vector Register */
+#define AT91C_AIC_ISR (AT91_REG(0xFFFFF108)) /* AIC Interrupt Status Register */
+#define AT91C_AIC_IPR (AT91_REG(0xFFFFF10C)) /* AIC Interrupt Pending Register */
+#define AT91C_AIC_IMR (AT91_REG(0xFFFFF110)) /* AIC Interrupt Mask Register */
+#define AT91C_AIC_CISR (AT91_REG(0xFFFFF114)) /* AIC Core Interrupt Status Register */
+#define AT91C_AIC_IECR (AT91_REG(0xFFFFF120)) /* AIC Interrupt Enable Command Register */
+#define AT91C_AIC_IDCR (AT91_REG(0xFFFFF124)) /* AIC Interrupt Disable Command Register */
+#define AT91C_AIC_ICCR (AT91_REG(0xFFFFF128)) /* AIC Interrupt Clear Command Register */
+#define AT91C_AIC_ISCR (AT91_REG(0xFFFFF12C)) /* AIC Interrupt Set Command Register */
+#define AT91C_AIC_EOICR (AT91_REG(0xFFFFF130)) /* AIC End of Interrupt Command Register */
+#define AT91C_AIC_SPU (AT91_REG(0xFFFFF134)) /* AIC Spurious Vector Register */
+#define AT91C_AIC_DCR (AT91_REG(0xFFFFF138)) /* AIC Debug Control Register (Protect) */
+#define AT91C_AIC_FFER (AT91_REG(0xFFFFF140)) /* AIC Fast Forcing Enable Register */
+#define AT91C_AIC_FFDR (AT91_REG(0xFFFFF144)) /* AIC Fast Forcing Disable Register */
+#define AT91C_AIC_FFSR (AT91_REG(0xFFFFF148)) /* AIC Fast Forcing Status Register */
+
+
+/* ========== Register definition for DBGU peripheral ========== */
+#define AT91C_DBGU_EXID (AT91_REG(0xFFFFF244)) /* DBGU Chip ID Extension Register */
+#define AT91C_DBGU_BRGR (AT91_REG(0xFFFFF220)) /* DBGU Baud Rate Generator Register */
+#define AT91C_DBGU_IDR (AT91_REG(0xFFFFF20C)) /* DBGU Interrupt Disable Register */
+#define AT91C_DBGU_CSR (AT91_REG(0xFFFFF214)) /* DBGU Channel Status Register */
+#define AT91C_DBGU_CIDR (AT91_REG(0xFFFFF240)) /* DBGU Chip ID Register */
+#define AT91C_DBGU_MR (AT91_REG(0xFFFFF204)) /* DBGU Mode Register */
+#define AT91C_DBGU_IMR (AT91_REG(0xFFFFF210)) /* DBGU Interrupt Mask Register */
+#define AT91C_DBGU_CR (AT91_REG(0xFFFFF200)) /* DBGU Control Register */
+#define AT91C_DBGU_FNTR (AT91_REG(0xFFFFF248)) /* DBGU Force NTRST Register */
+#define AT91C_DBGU_THR (AT91_REG(0xFFFFF21C)) /* DBGU Transmitter Holding Register */
+#define AT91C_DBGU_RHR (AT91_REG(0xFFFFF218)) /* DBGU Receiver Holding Register */
+#define AT91C_DBGU_IER (AT91_REG(0xFFFFF208)) /* DBGU Interrupt Enable Register */
+
+/* ========== Register definition for PIO peripheral ========== */
+#define AT91C_PIO_ODR (AT91_REG(0xFFFFF414)) /* PIOA Output Disable Registerr */
+#define AT91C_PIO_SODR (AT91_REG(0xFFFFF430)) /* PIOA Set Output Data Register */
+#define AT91C_PIO_ISR (AT91_REG(0xFFFFF44C)) /* PIOA Interrupt Status Register */
+#define AT91C_PIO_ABSR (AT91_REG(0xFFFFF478)) /* PIOA AB Select Status Register */
+#define AT91C_PIO_IER (AT91_REG(0xFFFFF440)) /* PIOA Interrupt Enable Register */
+#define AT91C_PIO_PPUDR (AT91_REG(0xFFFFF460)) /* PIOA Pull-up Disable Register */
+#define AT91C_PIO_IMR (AT91_REG(0xFFFFF448)) /* PIOA Interrupt Mask Register */
+#define AT91C_PIO_PER (AT91_REG(0xFFFFF400)) /* PIOA PIO Enable Register */
+#define AT91C_PIO_IFDR (AT91_REG(0xFFFFF424)) /* PIOA Input Filter Disable Register */
+#define AT91C_PIO_OWDR (AT91_REG(0xFFFFF4A4)) /* PIOA Output Write Disable Register */
+#define AT91C_PIO_MDSR (AT91_REG(0xFFFFF458)) /* PIOA Multi-driver Status Register */
+#define AT91C_PIO_IDR (AT91_REG(0xFFFFF444)) /* PIOA Interrupt Disable Register */
+#define AT91C_PIO_ODSR (AT91_REG(0xFFFFF438)) /* PIOA Output Data Status Register */
+#define AT91C_PIO_PPUSR (AT91_REG(0xFFFFF468)) /* PIOA Pull-up Status Register */
+#define AT91C_PIO_OWSR (AT91_REG(0xFFFFF4A8)) /* PIOA Output Write Status Register */
+#define AT91C_PIO_BSR (AT91_REG(0xFFFFF474)) /* PIOA Select B Register */
+#define AT91C_PIO_OWER (AT91_REG(0xFFFFF4A0)) /* PIOA Output Write Enable Register */
+#define AT91C_PIO_IFER (AT91_REG(0xFFFFF420)) /* PIOA Input Filter Enable Register */
+#define AT91C_PIO_PDSR (AT91_REG(0xFFFFF43C)) /* PIOA Pin Data Status Register */
+#define AT91C_PIO_PPUER (AT91_REG(0xFFFFF464)) /* PIOA Pull-up Enable Register */
+#define AT91C_PIO_OSR (AT91_REG(0xFFFFF418)) /* PIOA Output Status Register */
+#define AT91C_PIO_ASR (AT91_REG(0xFFFFF470)) /* PIOA Select A Register */
+#define AT91C_PIO_MDDR (AT91_REG(0xFFFFF454)) /* PIOA Multi-driver Disable Register */
+#define AT91C_PIO_CODR (AT91_REG(0xFFFFF434)) /* PIOA Clear Output Data Register */
+#define AT91C_PIO_MDER (AT91_REG(0xFFFFF450)) /* PIOA Multi-driver Enable Register */
+#define AT91C_PIO_PDR (AT91_REG(0xFFFFF404)) /* PIOA PIO Disable Register */
+#define AT91C_PIO_IFSR (AT91_REG(0xFFFFF428)) /* PIOA Input Filter Status Register */
+#define AT91C_PIO_OER (AT91_REG(0xFFFFF410)) /* PIOA Output Enable Register */
+#define AT91C_PIO_PSR (AT91_REG(0xFFFFF408)) /* PIOA PIO Status Register */
+
+// ========== Register definition for PIOA peripheral ==========
+#define AT91C_PIOA_IMR (AT91_REG(0xFFFFF448)) // (PIOA) Interrupt Mask Register
+#define AT91C_PIOA_IER (AT91_REG(0xFFFFF440)) // (PIOA) Interrupt Enable Register
+#define AT91C_PIOA_OWDR (AT91_REG(0xFFFFF4A4)) // (PIOA) Output Write Disable Register
+#define AT91C_PIOA_ISR (AT91_REG(0xFFFFF44C)) // (PIOA) Interrupt Status Register
+#define AT91C_PIOA_PPUDR (AT91_REG(0xFFFFF460)) // (PIOA) Pull-up Disable Register
+#define AT91C_PIOA_MDSR (AT91_REG(0xFFFFF458)) // (PIOA) Multi-driver Status Register
+#define AT91C_PIOA_MDER (AT91_REG(0xFFFFF450)) // (PIOA) Multi-driver Enable Register
+#define AT91C_PIOA_PER (AT91_REG(0xFFFFF400)) // (PIOA) PIO Enable Register
+#define AT91C_PIOA_PSR (AT91_REG(0xFFFFF408)) // (PIOA) PIO Status Register
+#define AT91C_PIOA_OER (AT91_REG(0xFFFFF410)) // (PIOA) Output Enable Register
+#define AT91C_PIOA_BSR (AT91_REG(0xFFFFF474)) // (PIOA) Select B Register
+#define AT91C_PIOA_PPUER (AT91_REG(0xFFFFF464)) // (PIOA) Pull-up Enable Register
+#define AT91C_PIOA_MDDR (AT91_REG(0xFFFFF454)) // (PIOA) Multi-driver Disable Register
+#define AT91C_PIOA_PDR (AT91_REG(0xFFFFF404)) // (PIOA) PIO Disable Register
+#define AT91C_PIOA_ODR (AT91_REG(0xFFFFF414)) // (PIOA) Output Disable Registerr
+#define AT91C_PIOA_IFDR (AT91_REG(0xFFFFF424)) // (PIOA) Input Filter Disable Register
+#define AT91C_PIOA_ABSR (AT91_REG(0xFFFFF478)) // (PIOA) AB Select Status Register
+#define AT91C_PIOA_ASR (AT91_REG(0xFFFFF470)) // (PIOA) Select A Register
+#define AT91C_PIOA_PPUSR (AT91_REG(0xFFFFF468)) // (PIOA) Pull-up Status Register
+#define AT91C_PIOA_ODSR (AT91_REG(0xFFFFF438)) // (PIOA) Output Data Status Register
+#define AT91C_PIOA_SODR (AT91_REG(0xFFFFF430)) // (PIOA) Set Output Data Register
+#define AT91C_PIOA_IFSR (AT91_REG(0xFFFFF428)) // (PIOA) Input Filter Status Register
+#define AT91C_PIOA_IFER (AT91_REG(0xFFFFF420)) // (PIOA) Input Filter Enable Register
+#define AT91C_PIOA_OSR (AT91_REG(0xFFFFF418)) // (PIOA) Output Status Register
+#define AT91C_PIOA_IDR (AT91_REG(0xFFFFF444)) // (PIOA) Interrupt Disable Register
+#define AT91C_PIOA_PDSR (AT91_REG(0xFFFFF43C)) // (PIOA) Pin Data Status Register
+#define AT91C_PIOA_CODR (AT91_REG(0xFFFFF434)) // (PIOA) Clear Output Data Register
+#define AT91C_PIOA_OWSR (AT91_REG(0xFFFFF4A8)) // (PIOA) Output Write Status Register
+#define AT91C_PIOA_OWER (AT91_REG(0xFFFFF4A0)) // (PIOA) Output Write Enable Register
+// ========== Register definition for PIOB peripheral ==========
+#define AT91C_PIOB_OWSR (AT91_REG(0xFFFFF6A8)) // (PIOB) Output Write Status Register
+#define AT91C_PIOB_PPUSR (AT91_REG(0xFFFFF668)) // (PIOB) Pull-up Status Register
+#define AT91C_PIOB_PPUDR (AT91_REG(0xFFFFF660)) // (PIOB) Pull-up Disable Register
+#define AT91C_PIOB_MDSR (AT91_REG(0xFFFFF658)) // (PIOB) Multi-driver Status Register
+#define AT91C_PIOB_MDER (AT91_REG(0xFFFFF650)) // (PIOB) Multi-driver Enable Register
+#define AT91C_PIOB_IMR (AT91_REG(0xFFFFF648)) // (PIOB) Interrupt Mask Register
+#define AT91C_PIOB_OSR (AT91_REG(0xFFFFF618)) // (PIOB) Output Status Register
+#define AT91C_PIOB_OER (AT91_REG(0xFFFFF610)) // (PIOB) Output Enable Register
+#define AT91C_PIOB_PSR (AT91_REG(0xFFFFF608)) // (PIOB) PIO Status Register
+#define AT91C_PIOB_PER (AT91_REG(0xFFFFF600)) // (PIOB) PIO Enable Register
+#define AT91C_PIOB_BSR (AT91_REG(0xFFFFF674)) // (PIOB) Select B Register
+#define AT91C_PIOB_PPUER (AT91_REG(0xFFFFF664)) // (PIOB) Pull-up Enable Register
+#define AT91C_PIOB_IFDR (AT91_REG(0xFFFFF624)) // (PIOB) Input Filter Disable Register
+#define AT91C_PIOB_ODR (AT91_REG(0xFFFFF614)) // (PIOB) Output Disable Registerr
+#define AT91C_PIOB_ABSR (AT91_REG(0xFFFFF678)) // (PIOB) AB Select Status Register
+#define AT91C_PIOB_ASR (AT91_REG(0xFFFFF670)) // (PIOB) Select A Register
+#define AT91C_PIOB_IFER (AT91_REG(0xFFFFF620)) // (PIOB) Input Filter Enable Register
+#define AT91C_PIOB_IFSR (AT91_REG(0xFFFFF628)) // (PIOB) Input Filter Status Register
+#define AT91C_PIOB_SODR (AT91_REG(0xFFFFF630)) // (PIOB) Set Output Data Register
+#define AT91C_PIOB_ODSR (AT91_REG(0xFFFFF638)) // (PIOB) Output Data Status Register
+#define AT91C_PIOB_CODR (AT91_REG(0xFFFFF634)) // (PIOB) Clear Output Data Register
+#define AT91C_PIOB_PDSR (AT91_REG(0xFFFFF63C)) // (PIOB) Pin Data Status Register
+#define AT91C_PIOB_OWER (AT91_REG(0xFFFFF6A0)) // (PIOB) Output Write Enable Register
+#define AT91C_PIOB_IER (AT91_REG(0xFFFFF640)) // (PIOB) Interrupt Enable Register
+#define AT91C_PIOB_OWDR (AT91_REG(0xFFFFF6A4)) // (PIOB) Output Write Disable Register
+#define AT91C_PIOB_MDDR (AT91_REG(0xFFFFF654)) // (PIOB) Multi-driver Disable Register
+#define AT91C_PIOB_ISR (AT91_REG(0xFFFFF64C)) // (PIOB) Interrupt Status Register
+#define AT91C_PIOB_IDR (AT91_REG(0xFFFFF644)) // (PIOB) Interrupt Disable Register
+#define AT91C_PIOB_PDR (AT91_REG(0xFFFFF604)) // (PIOB) PIO Disable Register
+
+/* ========== Register definition for PMC peripheral ========== */
+#define AT91C_PMC_SCER (AT91_REG(0xFFFFFC00)) /* PMC System Clock Enable Register */
+#define AT91C_PMC_SCDR (AT91_REG(0xFFFFFC04)) /* PMC System Clock Disable Register */
+#define AT91C_PMC_SCSR (AT91_REG(0xFFFFFC08)) /* PMC System Clock Status Register */
+#define AT91C_PMC_PCER (AT91_REG(0xFFFFFC10)) /* PMC Peripheral Clock Enable Register */
+#define AT91C_PMC_PCDR (AT91_REG(0xFFFFFC14)) /* PMC Peripheral Clock Disable Register */
+#define AT91C_PMC_PCSR (AT91_REG(0xFFFFFC18)) /* PMC Peripheral Clock Status Register */
+#define AT91C_PMC_MOR (AT91_REG(0xFFFFFC20)) /* PMC Main Oscillator Register */
+#define AT91C_PMC_MCFR (AT91_REG(0xFFFFFC24)) /* PMC Main Clock Frequency Register */
+#define AT91C_PMC_PLLR (AT91_REG(0xFFFFFC2C)) /* PMC PLL Register */
+#define AT91C_PMC_MCKR (AT91_REG(0xFFFFFC30)) /* PMC Master Clock Register */
+#define AT91C_PMC_PCKR (AT91_REG(0xFFFFFC40)) /* PMC Programmable Clock Register */
+#define AT91C_PMC_IER (AT91_REG(0xFFFFFC60)) /* PMC Interrupt Enable Register */
+#define AT91C_PMC_IDR (AT91_REG(0xFFFFFC64)) /* PMC Interrupt Disable Register */
+#define AT91C_PMC_SR (AT91_REG(0xFFFFFC68)) /* PMC Status Register */
+#define AT91C_PMC_IMR (AT91_REG(0xFFFFFC6C)) /* PMC Interrupt Mask Register */
+
+/******************************************************************************/
+/* PERIPHERAL ID DEFINITIONS FOR AT91SAM7S64 */
+/******************************************************************************/
+#define AT91C_ID_FIQ 0 /* Advanced Interrupt Controller (FIQ) */
+#define AT91C_ID_SYS 1 /* System Peripheral */
+#define AT91C_ID_PIOA 2 /* Parallel IO Controller A */
+#define AT91C_ID_PIOB 3 /* Parallel IO Controller B */
+#define AT91C_ID_ADC 4 /* Analog-to-Digital Converter */
+#define AT91C_ID_SPI 5 /* Serial Peripheral Interface */
+#define AT91C_ID_US0 6 /* USART 0 */
+#define AT91C_ID_US1 7 /* USART 1 */
+#define AT91C_ID_SSC 8 /* Serial Synchronous Controller */
+#define AT91C_ID_TWI 9 /* Two-Wire Interface */
+#define AT91C_ID_PWMC 10 /* PWM Controller */
+#define AT91C_ID_UDP 11 /* USB Device Port */
+#define AT91C_ID_TC0 12 /* Timer Counter 0 */
+#define AT91C_ID_TC1 13 /* Timer Counter 1 */
+#define AT91C_ID_TC2 14 /* Timer Counter 2 */
+#define AT91C_ID_15 15 /* Reserved */
+#define AT91C_ID_16 16 /* Reserved */
+#define AT91C_ID_17 17 /* Reserved */
+#define AT91C_ID_18 18 /* Reserved */
+#define AT91C_ID_19 19 /* Reserved */
+#define AT91C_ID_20 20 /* Reserved */
+#define AT91C_ID_21 21 /* Reserved */
+#define AT91C_ID_22 22 /* Reserved */
+#define AT91C_ID_23 23 /* Reserved */
+#define AT91C_ID_24 24 /* Reserved */
+#define AT91C_ID_25 25 /* Reserved */
+#define AT91C_ID_26 26 /* Reserved */
+#define AT91C_ID_27 27 /* Reserved */
+#define AT91C_ID_28 28 /* Reserved */
+#define AT91C_ID_29 29 /* Reserved */
+#define AT91C_ID_IRQ0 30 /* Advanced Interrupt Controller (IRQ0) */
+#define AT91C_ID_IRQ1 31 /* Advanced Interrupt Controller (IRQ1) */
+#define AT91C_ALL_INT 0xC0007FF7 /* ALL VALID INTERRUPTS */
+
+/*****************************/
+/* CPU Mode */
+/*****************************/
+#define USERMODE 0x10
+#define FIQMODE 0x11
+#define IRQMODE 0x12
+#define SVCMODE 0x13
+#define ABORTMODE 0x17
+#define UNDEFMODE 0x1b
+#define MODEMASK 0x1f
+#define NOINT 0xc0
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libcpu/arm/AT91SAM7S/context_gcc.S b/libcpu/arm/AT91SAM7S/context_gcc.S
new file mode 100644
index 0000000000..e18dcfa6ea
--- /dev/null
+++ b/libcpu/arm/AT91SAM7S/context_gcc.S
@@ -0,0 +1,94 @@
+/*
+ * File : context.S
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2006-03-13 Bernard first version
+ */
+
+#define NOINT 0xc0
+
+/*
+ * rt_base_t rt_hw_interrupt_disable()/*
+ */
+.globl rt_hw_interrupt_disable
+rt_hw_interrupt_disable:
+ mrs r0, cpsr
+ orr r1, r0, #NOINT
+ msr cpsr_c, r1
+ mov pc, lr
+
+/*
+ * void rt_hw_interrupt_enable(rt_base_t level)/*
+ */
+.globl rt_hw_interrupt_enable
+rt_hw_interrupt_enable:
+ msr cpsr, r0
+ mov pc, lr
+
+/*
+ * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to)/*
+ * r0 --> from
+ * r1 --> to
+ */
+.globl rt_hw_context_switch
+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
+ stmfd sp!, {r4} /* push cpsr */
+ mrs r4, spsr
+ stmfd sp!, {r4} /* push spsr */
+
+ str sp, [r0] /* store sp in preempted tasks TCB */
+ ldr sp, [r1] /* get new task stack pointer */
+
+ ldmfd sp!, {r4} /* pop new task spsr */
+ msr spsr_cxsf, r4
+ ldmfd sp!, {r4} /* pop new task cpsr */
+ msr cpsr_cxsf, r4
+
+ ldmfd sp!, {r0-r12, lr, pc} /* pop new task r0-r12, lr & pc */
+
+/*
+ * void rt_hw_context_switch_to(rt_uint32 to)/*
+ * r0 --> to
+ */
+.globl rt_hw_context_switch_to
+rt_hw_context_switch_to:
+ ldr sp, [r0] /* get new task stack pointer */
+
+ ldmfd sp!, {r4} /* pop new task spsr */
+ msr spsr_cxsf, r4
+ ldmfd sp!, {r4} /* pop new task cpsr */
+ msr cpsr_cxsf, r4
+
+ ldmfd sp!, {r0-r12, lr, pc} /* pop new task r0-r12, lr & pc */
+
+/*
+ * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to)/*
+ */
+.globl rt_thread_switch_interrput_flag
+.globl rt_interrupt_from_thread
+.globl rt_interrupt_to_thread
+.globl rt_hw_context_switch_interrupt
+rt_hw_context_switch_interrupt:
+ ldr r2, =rt_thread_switch_interrput_flag
+ ldr r3, [r2]
+ cmp r3, #1
+ beq _reswitch
+ mov r3, #1 /* set rt_thread_switch_interrput_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]
+ mov pc, lr
diff --git a/libcpu/arm/AT91SAM7S/context_rvds.S b/libcpu/arm/AT91SAM7S/context_rvds.S
new file mode 100644
index 0000000000..82c5adc574
--- /dev/null
+++ b/libcpu/arm/AT91SAM7S/context_rvds.S
@@ -0,0 +1,107 @@
+;/*
+; * File : context_rvds.S
+; * This file is part of RT-Thread RTOS
+; * COPYRIGHT (C) 2006, RT-Thread Development Team
+; *
+; * The license and distribution terms for this file may be
+; * found in the file LICENSE in this distribution or at
+; * http://www.rt-thread.org/license/LICENSE
+; *
+; * Change Logs:
+; * Date Author Notes
+; * 2009-01-20 Bernard first version
+; */
+
+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
+ STMFD sp!, {r4} ; push cpsr
+ MRS r4, spsr
+ STMFD sp!, {r4} ; push spsr
+
+ STR sp, [r0] ; store sp in preempted tasks TCB
+ LDR sp, [r1] ; get new task stack pointer
+
+ LDMFD sp!, {r4} ; pop new task spsr
+ MSR spsr_cxsf, r4
+ LDMFD sp!, {r4} ; pop new task cpsr
+ MSR cpsr_cxsf, r4
+
+ LDMFD sp!, {r0-r12, lr, pc} ; pop new task r0-r12, lr & pc
+ 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 spsr
+ MSR spsr_cxsf, r4
+ LDMFD sp!, {r4} ; pop new task cpsr
+ MSR cpsr_cxsf, r4
+
+ LDMFD sp!, {r0-r12, lr, pc} ; pop new task r0-r12, lr & pc
+ ENDP
+
+;/*
+; * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to);
+; */
+ IMPORT rt_thread_switch_interrput_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_interrput_flag
+ LDR r3, [r2]
+ CMP r3, #1
+ BEQ _reswitch
+ MOV r3, #1 ; set rt_thread_switch_interrput_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
+
+ END \ No newline at end of file
diff --git a/libcpu/arm/AT91SAM7S/cpu.c b/libcpu/arm/AT91SAM7S/cpu.c
new file mode 100644
index 0000000000..57db2b7d24
--- /dev/null
+++ b/libcpu/arm/AT91SAM7S/cpu.c
@@ -0,0 +1,42 @@
+/*
+ * File : cpu.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Develop Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2006-08-23 Bernard first version
+ */
+
+#include <rtthread.h>
+#include "AT91SAM7S.h"
+
+/**
+ * @addtogroup AT91SAM7
+ */
+/*@{*/
+
+/**
+ * this function will reset CPU
+ *
+ */
+void rt_hw_cpu_reset()
+{
+}
+
+/**
+ * this function will shutdown CPU
+ *
+ */
+void rt_hw_cpu_shutdown()
+{
+ rt_kprintf("shutdown...\n");
+
+ while (1);
+}
+
+/*@}*/
diff --git a/libcpu/arm/AT91SAM7S/interrupt.c b/libcpu/arm/AT91SAM7S/interrupt.c
new file mode 100644
index 0000000000..b8ef0c051c
--- /dev/null
+++ b/libcpu/arm/AT91SAM7S/interrupt.c
@@ -0,0 +1,91 @@
+/*
+ * File : trap.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2006-08-23 Bernard first version
+ */
+
+#include <rtthread.h>
+#include "AT91SAM7S.h"
+
+#define MAX_HANDLERS 32
+
+extern rt_uint32_t rt_interrupt_nest;
+
+rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread;
+rt_uint32_t rt_thread_switch_interrput_flag;
+
+/**
+ * @addtogroup AT91SAM7
+ */
+/*@{*/
+
+void rt_hw_interrupt_handler(int vector)
+{
+ rt_kprintf("Unhandled interrupt %d occured!!!\n", vector);
+}
+
+/**
+ * This function will initialize hardware interrupt
+ */
+void rt_hw_interrupt_init()
+{
+ rt_base_t index;
+
+ for (index = 0; index < MAX_HANDLERS; index ++)
+ {
+ AT91C_AIC_SVR(index) = (rt_uint32_t)rt_hw_interrupt_handler;
+ }
+
+ /* 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_interrput_flag = 0;
+}
+
+/**
+ * This function will mask a interrupt.
+ * @param vector the interrupt number
+ */
+void rt_hw_interrupt_mask(int vector)
+{
+ /* disable interrupt */
+ AT91C_AIC_IDCR = 1 << vector;
+
+ /* clear interrupt */
+ AT91C_AIC_ICCR = 1 << vector;
+}
+
+/**
+ * This function will un-mask a interrupt.
+ * @param vector the interrupt number
+ */
+void rt_hw_interrupt_umask(int vector)
+{
+ AT91C_AIC_IECR = 1 << vector;
+}
+
+/**
+ * This function will install a interrupt service routine to a interrupt.
+ * @param vector the interrupt number
+ * @param new_handler the interrupt service routine to be installed
+ * @param old_handler the old interrupt service routine
+ */
+void rt_hw_interrupt_install(int vector, rt_isr_handler_t new_handler, rt_isr_handler_t *old_handler)
+{
+ if(vector >= 0 && vector < MAX_HANDLERS)
+ {
+ if (*old_handler != RT_NULL) *old_handler = (rt_isr_handler_t)AT91C_AIC_SVR(vector);
+ if (new_handler != RT_NULL) AT91C_AIC_SVR(vector) = (rt_uint32_t)new_handler;
+ }
+}
+
+/*@}*/
diff --git a/libcpu/arm/AT91SAM7S/serial.c b/libcpu/arm/AT91SAM7S/serial.c
new file mode 100644
index 0000000000..307d713ed2
--- /dev/null
+++ b/libcpu/arm/AT91SAM7S/serial.c
@@ -0,0 +1,387 @@
+/*
+ * File : serial.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2006-08-23 Bernard first version
+ * 2009-05-14 Bernard add RT-THread device interface
+ */
+
+#include <rthw.h>
+#include <rtthread.h>
+
+#include "AT91SAM7S.h"
+#include "serial.h"
+
+/**
+ * @addtogroup AT91SAM7
+ */
+/*@{*/
+typedef volatile rt_uint32_t REG32;
+struct rt_at91serial_hw
+{
+ REG32 US_CR; // Control Register
+ REG32 US_MR; // Mode Register
+ REG32 US_IER; // Interrupt Enable Register
+ REG32 US_IDR; // Interrupt Disable Register
+ REG32 US_IMR; // Interrupt Mask Register
+ REG32 US_CSR; // Channel Status Register
+ REG32 US_RHR; // Receiver Holding Register
+ REG32 US_THR; // Transmitter Holding Register
+ REG32 US_BRGR; // Baud Rate Generator Register
+ REG32 US_RTOR; // Receiver Time-out Register
+ REG32 US_TTGR; // Transmitter Time-guard Register
+ REG32 Reserved0[5]; //
+ REG32 US_FIDI; // FI_DI_Ratio Register
+ REG32 US_NER; // Nb Errors Register
+ REG32 Reserved1[1]; //
+ REG32 US_IF; // IRDA_FILTER Register
+ REG32 Reserved2[44]; //
+ REG32 US_RPR; // Receive Pointer Register
+ REG32 US_RCR; // Receive Counter Register
+ REG32 US_TPR; // Transmit Pointer Register
+ REG32 US_TCR; // Transmit Counter Register
+ REG32 US_RNPR; // Receive Next Pointer Register
+ REG32 US_RNCR; // Receive Next Counter Register
+ REG32 US_TNPR; // Transmit Next Pointer Register
+ REG32 US_TNCR; // Transmit Next Counter Register
+ REG32 US_PTCR; // PDC Transfer Control Register
+ REG32 US_PTSR; // PDC Transfer Status Register
+};
+
+struct rt_at91serial
+{
+ struct rt_device parent;
+
+ struct rt_at91serial_hw* hw_base;
+ rt_uint16_t peripheral_id;
+ rt_uint32_t baudrate;
+
+ /* reception field */
+ rt_uint16_t save_index, read_index;
+ rt_uint8_t rx_buffer[RT_UART_RX_BUFFER_SIZE];
+};
+#ifdef RT_USING_UART1
+struct rt_at91serial serial1;
+#endif
+#ifdef RT_USING_UART2
+struct rt_at91serial serial2;
+#endif
+
+static void rt_hw_serial_isr(int irqno)
+{
+ rt_base_t level;
+ struct rt_device* device;
+ struct rt_at91serial* serial = RT_NULL;
+
+ if (irqno == AT91C_ID_US0)
+ {
+#ifdef RT_USING_UART1
+ /* serial 1 */
+ serial = &serial1;
+#endif
+ }
+ else if (irqno == AT91C_ID_US1)
+ {
+#ifdef RT_USING_UART2
+ /* serial 2 */
+ serial = &serial2;
+#endif
+ }
+ RT_ASSERT(serial != RT_NULL);
+
+ /* get generic device object */
+ device = (rt_device_t)serial;
+
+ /* disable interrupt */
+ level = rt_hw_interrupt_disable();
+
+ /* get received character */
+ serial->rx_buffer[serial->save_index] = serial->hw_base->US_RHR;
+
+ /* move to next position */
+ serial->save_index ++;
+ if (serial->save_index >= RT_UART_RX_BUFFER_SIZE)
+ serial->save_index = 0;
+
+ /* if the next position is read index, discard this 'read char' */
+ if (serial->save_index == serial->read_index)
+ {
+ serial->read_index ++;
+ if (serial->read_index >= RT_UART_RX_BUFFER_SIZE)
+ serial->read_index = 0;
+ }
+
+ /* enable interrupt */
+ rt_hw_interrupt_enable(level);
+
+ /* indicate to upper layer application */
+ if (device->rx_indicate != RT_NULL)
+ device->rx_indicate(device, 1);
+
+ /* ack interrupt */
+ AT91C_AIC_EOICR = 1;
+}
+
+static rt_err_t rt_serial_init (rt_device_t dev)
+{
+ rt_uint32_t bd;
+ struct rt_at91serial* serial = (struct rt_at91serial*) dev;
+
+ RT_ASSERT(serial != RT_NULL);
+ /* must be US0 or US1 */
+ RT_ASSERT((serial->peripheral_id != AT91C_ID_US0) &&
+ (serial->peripheral_id != AT91C_ID_US1));
+
+ /* Enable Clock for USART */
+ AT91C_PMC_PCER = 1 << serial->peripheral_id;
+
+ /* Enable RxD0 and TxDO Pin */
+ if (serial->peripheral_id == AT91C_ID_US0)
+ {
+ /* set pinmux */
+ AT91C_PIO_PDR = (1 << 5) | (1 << 6);
+ }
+ else if (serial->peripheral_id == AT91C_ID_US1)
+ {
+ /* set pinmux */
+ AT91C_PIO_PDR = (1 << 21) | (1 << 22);
+ }
+
+ serial->hw_base->US_CR = AT91C_US_RSTRX | /* Reset Receiver */
+ AT91C_US_RSTTX | /* Reset Transmitter */
+ AT91C_US_RXDIS | /* Receiver Disable */
+ AT91C_US_TXDIS; /* Transmitter Disable */
+
+ serial->hw_base->US_MR = AT91C_US_USMODE_NORMAL | /* Normal Mode */
+ AT91C_US_CLKS_CLOCK | /* Clock = MCK */
+ AT91C_US_CHRL_8_BITS | /* 8-bit Data */
+ AT91C_US_PAR_NONE | /* No Parity */
+ AT91C_US_NBSTOP_1_BIT; /* 1 Stop Bit */
+
+ /* set baud rate divisor */
+ bd = ((MCK*10)/(serial->baudrate * 16));
+ if ((bd % 10) >= 5) bd = (bd / 10) + 1;
+ else bd /= 10;
+
+ serial->hw_base->US_BRGR = bd;
+ serial->hw_base->US_CR = AT91C_US_RXEN | /* Receiver Enable */
+ AT91C_US_TXEN; /* Transmitter Enable */
+
+ /* reset rx index */
+ serial->save_index = 0;
+ serial->read_index = 0;
+
+ /* reset rx buffer */
+ rt_memset(serial->rx_buffer, 0, RT_UART_RX_BUFFER_SIZE);
+
+ return RT_EOK;
+}
+
+static rt_err_t rt_serial_open(rt_device_t dev, rt_uint16_t oflag)
+{
+ struct rt_at91serial *serial = (struct rt_at91serial*)dev;
+ RT_ASSERT(serial != RT_NULL);
+
+ if (dev->flag & RT_DEVICE_FLAG_INT_RX)
+ {
+ /* enable UART rx interrupt */
+ serial->hw_base->US_IER = 1 << 0; /* RxReady interrupt */
+ serial->hw_base->US_IMR |= 1 << 0; /* umask RxReady interrupt */
+
+ /* install UART handler */
+ rt_hw_interrupt_install(serial->peripheral_id, rt_hw_serial_isr, RT_NULL);
+ AT91C_AIC_SMR(serial->peripheral_id) = 5 | (0x01 << 5);
+ rt_hw_interrupt_umask(serial->peripheral_id);
+ }
+
+ return RT_EOK;
+}
+
+static rt_err_t rt_serial_close(rt_device_t dev)
+{
+ struct rt_at91serial *serial = (struct rt_at91serial*)dev;
+ RT_ASSERT(serial != RT_NULL);
+
+ if (dev->flag & RT_DEVICE_FLAG_INT_RX)
+ {
+ /* disable interrupt */
+ serial->hw_base->US_IDR = 1 << 0; /* RxReady interrupt */
+ serial->hw_base->US_IMR &= ~(1 << 0); /* mask RxReady interrupt */
+ }
+
+ return RT_EOK;
+}
+
+static rt_size_t rt_serial_read (rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
+{
+ rt_uint8_t* ptr;
+ struct rt_at91serial *serial = (struct rt_at91serial*)dev;
+ RT_ASSERT(serial != RT_NULL);
+
+ /* point to buffer */
+ ptr = (rt_uint8_t*) buffer;
+
+ if (dev->flag & RT_DEVICE_FLAG_INT_RX)
+ {
+ while (size)
+ {
+ /* interrupt receive */
+ rt_base_t level;
+
+ /* disable interrupt */
+ level = rt_hw_interrupt_disable();
+ if (serial->read_index != serial->save_index)
+ {
+ *ptr = serial->rx_buffer[serial->read_index];
+
+ serial->read_index ++;
+ if (serial->read_index >= RT_UART_RX_BUFFER_SIZE)
+ serial->read_index = 0;
+ }
+ else
+ {
+ /* no data in rx buffer */
+
+ /* enable interrupt */
+ rt_hw_interrupt_enable(level);
+ break;
+ }
+
+ /* enable interrupt */
+ rt_hw_interrupt_enable(level);
+
+ ptr ++; size --;
+ }
+
+ return (rt_uint32_t)ptr - (rt_uint32_t)buffer;
+ }
+ else if (dev->flag & RT_DEVICE_FLAG_DMA_RX)
+ {
+ /* not support right now */
+ RT_ASSERT(0);
+ }
+ else
+ {
+ /* poll mode */
+ while (size)
+ {
+ /* Wait for Full Rx Buffer */
+ while (!(serial->hw_base->US_CSR & AT91C_US_RXRDY));
+
+ /* Read Character */
+ *ptr = serial->hw_base->US_RHR;
+ ptr ++;
+ size --;
+ }
+
+ return (rt_size_t)ptr - (rt_size_t)buffer;
+ }
+
+ return 0;
+}
+
+static rt_size_t rt_serial_write (rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
+{
+ rt_uint8_t* ptr;
+ struct rt_at91serial *serial = (struct rt_at91serial*)dev;
+ RT_ASSERT(serial != RT_NULL);
+
+ ptr = (rt_uint8_t*) buffer;
+ if (dev->open_flag & RT_DEVICE_OFLAG_WRONLY)
+ {
+ if (dev->flag & RT_DEVICE_FLAG_STREAM)
+ {
+ /* it's a stream mode device */
+ while (size)
+ {
+ /* stream mode */
+ if (*ptr == '\n')
+ {
+ while (!(serial->hw_base->US_CSR & AT91C_US_TXRDY));
+ serial->hw_base->US_THR = '\r';
+ }
+
+ /* Wait for Empty Tx Buffer */
+ while (!(serial->hw_base->US_CSR & AT91C_US_TXRDY));
+
+ /* Transmit Character */
+ serial->hw_base->US_THR = *ptr;
+ ptr ++; size --;
+ }
+ }
+ else
+ {
+ while (size)
+ {
+ /* Wait for Empty Tx Buffer */
+ while (!(serial->hw_base->US_CSR & AT91C_US_TXRDY));
+
+ /* Transmit Character */
+ serial->hw_base->US_THR = *ptr;
+ ptr ++; size --;
+ }
+ }
+ }
+
+ return (rt_size_t)ptr - (rt_size_t)buffer;
+}
+
+static rt_err_t rt_serial_control (rt_device_t dev, rt_uint8_t cmd, void *args)
+{
+ return RT_EOK;
+}
+
+rt_err_t rt_hw_serial_init()
+{
+ rt_device_t device;
+
+#ifdef RT_USING_UART1
+ device = (rt_device_t) &serial1;
+
+ /* init serial device private data */
+ serial1.hw_base = (struct rt_at91serial_hw*)AT91C_BASE_US0;
+ serial1.peripheral_id = AT91C_ID_US0;
+ serial1.baudrate = 115200;
+
+ /* set device virtual interface */
+ device->init = rt_serial_init;
+ device->open = rt_serial_open;
+ device->close = rt_serial_close;
+ device->read = rt_serial_read;
+ device->write = rt_serial_write;
+ device->control = rt_serial_control;
+
+ /* register uart1 on device subsystem */
+ rt_device_register(device, "uart1", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX);
+#endif
+
+#ifdef RT_USING_UART2
+ device = (rt_device_t) &serial2;
+
+ serial2.hw_base = (struct rt_at91serial_hw*)AT91C_BASE_US1;
+ serial2.peripheral_id = AT91C_ID_US1;
+ serial2.baudrate = 115200;
+
+ /* set device virtual interface */
+ device->init = rt_serial_init;
+ device->open = rt_serial_open;
+ device->close = rt_serial_close;
+ device->read = rt_serial_read;
+ device->write = rt_serial_write;
+ device->control = rt_serial_control;
+
+ /* register uart2 on device subsystem */
+ rt_device_register(device, "uart2", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX);
+#endif
+
+ return RT_EOK;
+}
+
+/*@}*/
diff --git a/libcpu/arm/AT91SAM7S/serial.h b/libcpu/arm/AT91SAM7S/serial.h
new file mode 100644
index 0000000000..5fe0928c9a
--- /dev/null
+++ b/libcpu/arm/AT91SAM7S/serial.h
@@ -0,0 +1,56 @@
+#ifndef __RT_SERIAL_H__
+#define __RT_SERIAL_H__
+
+#ifndef AT91C_BASE_US0
+#define AT91C_BASE_US0 (0xFFFC0000) // (US0) Base Address
+#endif
+
+#ifndef AT91C_BASE_US1
+#define AT91C_BASE_US1 (0xFFFC4000) // (US1) Base Address
+#endif
+
+#define AT91C_US_RXRDY ((unsigned int) 0x1 << 0) /* US RXRDY Interrupt */
+#define AT91C_US_TXRDY ((unsigned int) 0x1 << 1) /* US TXRDY Interrupt */
+#define AT91C_US_RSTRX ((unsigned int) 0x1 << 2) /* US Reset Receiver */
+#define AT91C_US_RSTTX ((unsigned int) 0x1 << 3) /* US Reset Transmitter */
+#define AT91C_US_RXEN ((unsigned int) 0x1 << 4) /* US Receiver Enable */
+#define AT91C_US_RXDIS ((unsigned int) 0x1 << 5) /* US Receiver Disable */
+#define AT91C_US_TXEN ((unsigned int) 0x1 << 6) /* US Transmitter Enable */
+#define AT91C_US_TXDIS ((unsigned int) 0x1 << 7) /* US Transmitter Disable */
+#define AT91C_US_RSTSTA ((unsigned int) 0x1 << 8) /* US Reset Status Bits */
+
+#define AT91C_US_USMODE_NORMAL ((unsigned int) 0x0) /* USAR) Normal */
+#define AT91C_US_USMODE_RS485 ((unsigned int) 0x1) /* USAR) RS485 */
+#define AT91C_US_USMODE_HWHSH ((unsigned int) 0x2) /* USAR) Hardware Handshaking */
+#define AT91C_US_USMODE_MODEM ((unsigned int) 0x3) /* USAR) Modem */
+#define AT91C_US_USMODE_ISO7816_0 ((unsigned int) 0x4) /* USAR) ISO7816 protocol: T = 0 */
+#define AT91C_US_USMODE_ISO7816_1 ((unsigned int) 0x6) /* USAR) ISO7816 protocol: T = 1 */
+#define AT91C_US_USMODE_IRDA ((unsigned int) 0x8) /* USAR) IrDA */
+#define AT91C_US_USMODE_SWHSH ((unsigned int) 0xC) /* USAR) Software Handshaking */
+
+#define AT91C_US_CLKS_CLOCK ((unsigned int) 0x0 << 4) /* USAR) Clock */
+#define AT91C_US_CLKS_FDIV1 ((unsigned int) 0x1 << 4) /* USAR) fdiv1 */
+#define AT91C_US_CLKS_SLOW ((unsigned int) 0x2 << 4) /* USAR) slow_clock (ARM) */
+#define AT91C_US_CLKS_EXT ((unsigned int) 0x3 << 4) /* USAR) External (SCK) */
+
+#define AT91C_US_CHRL_5_BITS ((unsigned int) 0x0 << 6) /* USAR) Character Length: 5 bits */
+#define AT91C_US_CHRL_6_BITS ((unsigned int) 0x1 << 6) /* USAR) Character Length: 6 bits */
+#define AT91C_US_CHRL_7_BITS ((unsigned int) 0x2 << 6) /* USAR) Character Length: 7 bits */
+#define AT91C_US_CHRL_8_BITS ((unsigned int) 0x3 << 6) /* USAR) Character Length: 8 bits */
+
+#define AT91C_US_PAR_EVEN ((unsigned int) 0x0 << 9) /* DBGU Even Parity */
+#define AT91C_US_PAR_ODD ((unsigned int) 0x1 << 9) /* DBGU Odd Parity */
+#define AT91C_US_PAR_SPACE ((unsigned int) 0x2 << 9) /* DBGU Parity forced to 0 (Space) */
+#define AT91C_US_PAR_MARK ((unsigned int) 0x3 << 9) /* DBGU Parity forced to 1 (Mark) */
+#define AT91C_US_PAR_NONE ((unsigned int) 0x4 << 9) /* DBGU No Parity */
+#define AT91C_US_PAR_MULTI_DROP ((unsigned int) 0x6 << 9) /* DBGU Multi-drop mode */
+
+#define AT91C_US_NBSTOP_1_BIT ((unsigned int) 0x0 << 12) /* USART 1 stop bit */
+#define AT91C_US_NBSTOP_15_BIT ((unsigned int) 0x1 << 12) /* USART Asynchronous (SYNC=0) 2 stop bits Synchronous (SYNC=1) 2 stop bits */
+#define AT91C_US_NBSTOP_2_BIT ((unsigned int) 0x2 << 12) /* USART 2 stop bits */
+
+#define MCK 48054857
+#define BR 115200 /* Baud Rate */
+#define BRD (MCK/16/BR) /* Baud Rate Divisor */
+
+#endif
diff --git a/libcpu/arm/AT91SAM7S/stack.c b/libcpu/arm/AT91SAM7S/stack.c
new file mode 100644
index 0000000000..b0dc78db2c
--- /dev/null
+++ b/libcpu/arm/AT91SAM7S/stack.c
@@ -0,0 +1,60 @@
+/*
+ * File : stack.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2006-08-23 Bernard the first version
+ */
+#include <rtthread.h>
+#include "AT91SAM7S.h"
+
+/**
+ * @addtogroup AT91SAM7
+ */
+/*@{*/
+
+/**
+ * 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 */
+ *(--stk) = SVCMODE; /* cpsr */
+ *(--stk) = SVCMODE; /* spsr */
+
+ /* return task's current stack address */
+ return (rt_uint8_t *)stk;
+}
+
+/*@}*/
diff --git a/libcpu/arm/AT91SAM7S/start_gcc.S b/libcpu/arm/AT91SAM7S/start_gcc.S
new file mode 100644
index 0000000000..bcfbc261ca
--- /dev/null
+++ b/libcpu/arm/AT91SAM7S/start_gcc.S
@@ -0,0 +1,237 @@
+/*
+ * File : start_gcc.S
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2006-08-31 Bernard first version
+ */
+
+ /* Internal Memory Base Addresses */
+ .equ FLASH_BASE, 0x00100000
+ .equ RAM_BASE, 0x00200000
+
+ /* Stack Configuration */
+ .equ TOP_STACK, 0x00204000
+ .equ UND_STACK_SIZE, 0x00000100
+ .equ SVC_STACK_SIZE, 0x00000400
+ .equ ABT_STACK_SIZE, 0x00000100
+ .equ FIQ_STACK_SIZE, 0x00000100
+ .equ IRQ_STACK_SIZE, 0x00000100
+ .equ USR_STACK_SIZE, 0x00000004
+
+ /* ARM architecture definitions */
+ .equ MODE_USR, 0x10
+ .equ MODE_FIQ, 0x11
+ .equ MODE_IRQ, 0x12
+ .equ MODE_SVC, 0x13
+ .equ MODE_ABT, 0x17
+ .equ MODE_UND, 0x1B
+ .equ MODE_SYS, 0x1F
+
+ .equ I_BIT, 0x80 /* when this bit is set, IRQ is disabled */
+ .equ F_BIT, 0x40 /* when this bit is set, FIQ is disabled */
+
+.section .init, "ax"
+.code 32
+.align 0
+.globl _start
+_start:
+ b reset
+ ldr pc, _vector_undef
+ ldr pc, _vector_swi
+ ldr pc, _vector_pabt
+ ldr pc, _vector_dabt
+ nop /* reserved vector */
+ ldr pc, _vector_irq
+ ldr pc, _vector_fiq
+
+_vector_undef: .word vector_undef
+_vector_swi: .word vector_swi
+_vector_pabt: .word vector_pabt
+_vector_dabt: .word vector_dabt
+_vector_resv: .word vector_resv
+_vector_irq: .word vector_irq
+_vector_fiq: .word vector_fiq
+
+/*
+ * rtthread bss start and end
+ * which are defined in linker script
+ */
+.globl _bss_start
+_bss_start: .word __bss_start
+.globl _bss_end
+_bss_end: .word __bss_end
+
+/* the system entry */
+reset:
+ /* disable watchdog */
+ ldr r0, =0xFFFFFD40
+ ldr r1, =0x00008000
+ str r1, [r0, #0x04]
+
+ /* enable the main oscillator */
+ ldr r0, =0xFFFFFC00
+ ldr r1, =0x00000601
+ str r1, [r0, #0x20]
+
+ /* wait for main oscillator to stabilize */
+moscs_loop:
+ ldr r2, [r0, #0x68]
+ ands r2, r2, #1
+ beq moscs_loop
+
+ /* set up the PLL */
+ ldr r1, =0x00191C05
+ str r1, [r0, #0x2C]
+
+ /* wait for PLL to lock */
+pll_loop:
+ ldr r2, [r0, #0x68]
+ ands r2, r2, #0x04
+ beq pll_loop
+
+ /* select clock */
+ ldr r1, =0x00000007
+ str r1, [r0, #0x30]
+
+ /* setup stack for each mode */
+ ldr r0, =TOP_STACK
+
+ /* set stack */
+ /* undefined instruction mode */
+ msr cpsr_c, #MODE_UND|I_BIT|F_BIT
+ mov sp, r0
+ sub r0, r0, #UND_STACK_SIZE
+
+ /* abort mode */
+ msr cpsr_c, #MODE_ABT|I_BIT|F_BIT
+ mov sp, r0
+ sub r0, r0, #ABT_STACK_SIZE
+
+ /* FIQ mode */
+ msr cpsr_c, #MODE_FIQ|I_BIT|F_BIT
+ mov sp, r0
+ sub r0, r0, #FIQ_STACK_SIZE
+
+ /* IRQ mode */
+ msr cpsr_c, #MODE_IRQ|I_BIT|F_BIT
+ mov sp, r0
+ sub r0, r0, #IRQ_STACK_SIZE
+
+ /* supervisor mode */
+ msr cpsr_c, #MODE_SVC
+ mov sp, r0
+
+#ifdef __FLASH_BUILD__
+ /* Relocate .data section (Copy from ROM to RAM) */
+ ldr r1, =_etext
+ ldr r2, =_data
+ ldr r3, =_edata
+data_loop:
+ cmp r2, r3
+ ldrlo r0, [r1], #4
+ strlo r0, [r2], #4
+ blo data_loop
+#else
+ /* remap SRAM to 0x0000 */
+ ldr r0, =0xFFFFFF00
+ mov r1, #0x01
+ str r1, [r0]
+#endif
+
+ /* mask all IRQs */
+ ldr r1, =0xFFFFF124
+ ldr r0, =0XFFFFFFFF
+ str r0, [r1]
+
+ /* start RT-Thread Kernel */
+ ldr pc, _rtthread_startup
+
+_rtthread_startup: .word rtthread_startup
+
+/* exception handlers */
+vector_undef: b vector_undef
+vector_swi : b vector_swi
+vector_pabt : b vector_pabt
+vector_dabt : b vector_dabt
+vector_resv : b vector_resv
+
+.globl rt_interrupt_enter
+.globl rt_interrupt_leave
+.globl rt_thread_switch_interrput_flag
+.globl rt_interrupt_from_thread
+.globl rt_interrupt_to_thread
+vector_irq:
+ stmfd sp!, {r0-r12,lr}
+ bl rt_interrupt_enter
+ bl rt_hw_trap_irq
+ bl rt_interrupt_leave
+
+ /*
+ * if rt_thread_switch_interrput_flag set, jump to
+ * rt_hw_context_switch_interrupt_do and don't return
+ */
+ ldr r0, =rt_thread_switch_interrput_flag
+ ldr r1, [r0]
+ cmp r1, #1
+ beq rt_hw_context_switch_interrupt_do
+
+ ldmfd sp!, {r0-r12,lr}
+ subs pc, lr, #4
+
+vector_fiq:
+ stmfd sp!,{r0-r7,lr}
+ bl rt_hw_trap_fiq
+ ldmfd sp!,{r0-r7,lr}
+ subs pc,lr,#4
+
+/*
+ * 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 */
+ mov r1, sp
+ add sp, sp, #16 /* restore sp */
+ sub r2, lr, #4 /* save old task's pc to r2 */
+
+ mrs r3, spsr /* disable interrupt */
+ orr r0, r3, #I_BIT|F_BIT
+ msr spsr_c, r0
+
+ ldr r0, =.+8 /* switch to interrupted task's stack */
+ movs pc, r0
+
+ 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 psr */
+ mrs r4, spsr
+ stmfd sp!, {r4} /* push old task's spsr */
+
+ 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 spsr */
+ msr SPSR_cxsf, r4
+ ldmfd sp!, {r4} /* pop new task's psr */
+ msr CPSR_cxsf, r4
+
+ ldmfd sp!, {r0-r12,lr,pc} /* pop new task's r0-r12,lr & pc */
diff --git a/libcpu/arm/AT91SAM7S/start_rvds.S b/libcpu/arm/AT91SAM7S/start_rvds.S
new file mode 100644
index 0000000000..1dd4dd61a0
--- /dev/null
+++ b/libcpu/arm/AT91SAM7S/start_rvds.S
@@ -0,0 +1,498 @@
+;/*****************************************************************************/
+;/* SAM7.S: Startup file for Atmel AT91SAM7 device series */
+;/*****************************************************************************/
+;/* <<< Use Configuration Wizard in Context Menu >>> */
+;/*****************************************************************************/
+;/* This file is part of the uVision/ARM development tools. */
+;/* Copyright (c) 2005-2006 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 SAM7.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 remaps exception vectors from
+; * on-chip RAM to address 0.
+; *
+; * RAM_INTVEC: when set the startup code copies exception vectors
+; * from on-chip Flash to on-chip RAM.
+; */
+
+
+; 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
+
+
+; Internal Memory Base Addresses
+FLASH_BASE EQU 0x00100000
+RAM_BASE EQU 0x00200000
+
+
+;// <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
+
+
+; Reset Controller (RSTC) definitions
+RSTC_BASE EQU 0xFFFFFD00 ; RSTC Base Address
+RSTC_MR EQU 0x08 ; RSTC_MR Offset
+
+;/*
+;// <e> Reset Controller (RSTC)
+;// <o1.0> URSTEN: User Reset Enable
+;// <i> Enables NRST Pin to generate Reset
+;// <o1.8..11> ERSTL: External Reset Length <0-15>
+;// <i> External Reset Time in 2^(ERSTL+1) Slow Clock Cycles
+;// </e>
+;*/
+RSTC_SETUP EQU 1
+RSTC_MR_Val EQU 0xA5000401
+
+
+; Embedded Flash Controller (EFC) definitions
+EFC_BASE EQU 0xFFFFFF00 ; EFC Base Address
+EFC0_FMR EQU 0x60 ; EFC0_FMR Offset
+EFC1_FMR EQU 0x70 ; EFC1_FMR Offset
+
+;// <e> Embedded Flash Controller 0 (EFC0)
+;// <o1.16..23> FMCN: Flash Microsecond Cycle Number <0-255>
+;// <i> Number of Master Clock Cycles in 1us
+;// <o1.8..9> FWS: Flash Wait State
+;// <0=> Read: 1 cycle / Write: 2 cycles
+;// <1=> Read: 2 cycle / Write: 3 cycles
+;// <2=> Read: 3 cycle / Write: 4 cycles
+;// <3=> Read: 4 cycle / Write: 4 cycles
+;// </e>
+EFC0_SETUP EQU 1
+EFC0_FMR_Val EQU 0x00320100
+
+;// <e> Embedded Flash Controller 1 (EFC1)
+;// <o1.16..23> FMCN: Flash Microsecond Cycle Number <0-255>
+;// <i> Number of Master Clock Cycles in 1us
+;// <o1.8..9> FWS: Flash Wait State
+;// <0=> Read: 1 cycle / Write: 2 cycles
+;// <1=> Read: 2 cycle / Write: 3 cycles
+;// <2=> Read: 3 cycle / Write: 4 cycles
+;// <3=> Read: 4 cycle / Write: 4 cycles
+;// </e>
+EFC1_SETUP EQU 0
+EFC1_FMR_Val EQU 0x00320100
+
+
+; Watchdog Timer (WDT) definitions
+WDT_BASE EQU 0xFFFFFD40 ; WDT Base Address
+WDT_MR EQU 0x04 ; WDT_MR Offset
+
+;// <e> Watchdog Timer (WDT)
+;// <o1.0..11> WDV: Watchdog Counter Value <0-4095>
+;// <o1.16..27> WDD: Watchdog Delta Value <0-4095>
+;// <o1.12> WDFIEN: Watchdog Fault Interrupt Enable
+;// <o1.13> WDRSTEN: Watchdog Reset Enable
+;// <o1.14> WDRPROC: Watchdog Reset Processor
+;// <o1.28> WDDBGHLT: Watchdog Debug Halt
+;// <o1.29> WDIDLEHLT: Watchdog Idle Halt
+;// <o1.15> WDDIS: Watchdog Disable
+;// </e>
+WDT_SETUP EQU 1
+WDT_MR_Val EQU 0x00008000
+
+
+; Power Mangement Controller (PMC) definitions
+PMC_BASE EQU 0xFFFFFC00 ; PMC Base Address
+PMC_MOR EQU 0x20 ; PMC_MOR Offset
+PMC_MCFR EQU 0x24 ; PMC_MCFR Offset
+PMC_PLLR EQU 0x2C ; PMC_PLLR Offset
+PMC_MCKR EQU 0x30 ; PMC_MCKR Offset
+PMC_SR EQU 0x68 ; PMC_SR Offset
+PMC_MOSCEN EQU (1<<0) ; Main Oscillator Enable
+PMC_OSCBYPASS EQU (1<<1) ; Main Oscillator Bypass
+PMC_OSCOUNT EQU (0xFF<<8) ; Main OScillator Start-up Time
+PMC_DIV EQU (0xFF<<0) ; PLL Divider
+PMC_PLLCOUNT EQU (0x3F<<8) ; PLL Lock Counter
+PMC_OUT EQU (0x03<<14) ; PLL Clock Frequency Range
+PMC_MUL EQU (0x7FF<<16) ; PLL Multiplier
+PMC_USBDIV EQU (0x03<<28) ; USB Clock Divider
+PMC_CSS EQU (3<<0) ; Clock Source Selection
+PMC_PRES EQU (7<<2) ; Prescaler Selection
+PMC_MOSCS EQU (1<<0) ; Main Oscillator Stable
+PMC_LOCK EQU (1<<2) ; PLL Lock Status
+PMC_MCKRDY EQU (1<<3) ; Master Clock Status
+
+;// <e> Power Mangement Controller (PMC)
+;// <h> Main Oscillator
+;// <o1.0> MOSCEN: Main Oscillator Enable
+;// <o1.1> OSCBYPASS: Oscillator Bypass
+;// <o1.8..15> OSCCOUNT: Main Oscillator Startup Time <0-255>
+;// </h>
+;// <h> Phase Locked Loop (PLL)
+;// <o2.0..7> DIV: PLL Divider <0-255>
+;// <o2.16..26> MUL: PLL Multiplier <0-2047>
+;// <i> PLL Output is multiplied by MUL+1
+;// <o2.14..15> OUT: PLL Clock Frequency Range
+;// <0=> 80..160MHz <1=> Reserved
+;// <2=> 150..220MHz <3=> Reserved
+;// <o2.8..13> PLLCOUNT: PLL Lock Counter <0-63>
+;// <o2.28..29> USBDIV: USB Clock Divider
+;// <0=> None <1=> 2 <2=> 4 <3=> Reserved
+;// </h>
+;// <o3.0..1> CSS: Clock Source Selection
+;// <0=> Slow Clock
+;// <1=> Main Clock
+;// <2=> Reserved
+;// <3=> PLL Clock
+;// <o3.2..4> PRES: Prescaler
+;// <0=> None
+;// <1=> Clock / 2 <2=> Clock / 4
+;// <3=> Clock / 8 <4=> Clock / 16
+;// <5=> Clock / 32 <6=> Clock / 64
+;// <7=> Reserved
+;// </e>
+PMC_SETUP EQU 1
+PMC_MOR_Val EQU 0x00000601
+PMC_PLLR_Val EQU 0x00191C05
+PMC_MCKR_Val EQU 0x00000007
+
+
+ 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 RSTC
+ IF RSTC_SETUP != 0
+ LDR R0, =RSTC_BASE
+ LDR R1, =RSTC_MR_Val
+ STR R1, [R0, #RSTC_MR]
+ ENDIF
+
+
+; Setup EFC0
+ IF EFC0_SETUP != 0
+ LDR R0, =EFC_BASE
+ LDR R1, =EFC0_FMR_Val
+ STR R1, [R0, #EFC0_FMR]
+ ENDIF
+
+; Setup EFC1
+ IF EFC1_SETUP != 0
+ LDR R0, =EFC_BASE
+ LDR R1, =EFC1_FMR_Val
+ STR R1, [R0, #EFC1_FMR]
+ ENDIF
+
+; Setup WDT
+ IF WDT_SETUP != 0
+ LDR R0, =WDT_BASE
+ LDR R1, =WDT_MR_Val
+ STR R1, [R0, #WDT_MR]
+ ENDIF
+
+
+; Setup PMC
+ IF PMC_SETUP != 0
+ LDR R0, =PMC_BASE
+
+; Setup Main Oscillator
+ LDR R1, =PMC_MOR_Val
+ STR R1, [R0, #PMC_MOR]
+
+; Wait until Main Oscillator is stablilized
+ IF (PMC_MOR_Val:AND:PMC_MOSCEN) != 0
+MOSCS_Loop LDR R2, [R0, #PMC_SR]
+ ANDS R2, R2, #PMC_MOSCS
+ BEQ MOSCS_Loop
+ ENDIF
+
+; Setup the PLL
+ IF (PMC_PLLR_Val:AND:PMC_MUL) != 0
+ LDR R1, =PMC_PLLR_Val
+ STR R1, [R0, #PMC_PLLR]
+
+; Wait until PLL is stabilized
+PLL_Loop LDR R2, [R0, #PMC_SR]
+ ANDS R2, R2, #PMC_LOCK
+ BEQ PLL_Loop
+ ENDIF
+
+; Select Clock
+ IF (PMC_MCKR_Val:AND:PMC_CSS) == 1 ; Main Clock Selected
+ LDR R1, =PMC_MCKR_Val
+ AND R1, #PMC_CSS
+ STR R1, [R0, #PMC_MCKR]
+WAIT_Rdy1 LDR R2, [R0, #PMC_SR]
+ ANDS R2, R2, #PMC_MCKRDY
+ BEQ WAIT_Rdy1
+ LDR R1, =PMC_MCKR_Val
+ STR R1, [R0, #PMC_MCKR]
+WAIT_Rdy2 LDR R2, [R0, #PMC_SR]
+ ANDS R2, R2, #PMC_MCKRDY
+ BEQ WAIT_Rdy2
+ ELIF (PMC_MCKR_Val:AND:PMC_CSS) == 3 ; PLL Clock Selected
+ LDR R1, =PMC_MCKR_Val
+ AND R1, #PMC_PRES
+ STR R1, [R0, #PMC_MCKR]
+WAIT_Rdy1 LDR R2, [R0, #PMC_SR]
+ ANDS R2, R2, #PMC_MCKRDY
+ BEQ WAIT_Rdy1
+ LDR R1, =PMC_MCKR_Val
+ STR R1, [R0, #PMC_MCKR]
+WAIT_Rdy2 LDR R2, [R0, #PMC_SR]
+ ANDS R2, R2, #PMC_MCKRDY
+ BEQ WAIT_Rdy2
+ ENDIF ; Select Clock
+ ENDIF ; PMC_SETUP
+
+
+; Copy Exception Vectors to Internal RAM
+
+ IF :DEF:RAM_INTVEC
+ ADR R8, Vectors ; Source
+ LDR R9, =RAM_BASE ; Destination
+ LDMIA R8!, {R0-R7} ; Load Vectors
+ STMIA R9!, {R0-R7} ; Store Vectors
+ LDMIA R8!, {R0-R7} ; Load Handler Addresses
+ STMIA R9!, {R0-R7} ; Store Handler Addresses
+ ENDIF
+
+
+; Remap on-chip RAM to address 0
+
+MC_BASE EQU 0xFFFFFF00 ; MC Base Address
+MC_RCR EQU 0x00 ; MC_RCR Offset
+
+ IF :DEF:REMAP
+ LDR R0, =MC_BASE
+ MOV R1, #1
+ STR R1, [R0, #MC_RCR] ; Remap
+ ENDIF
+
+
+; 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
+ ; 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_interrput_flag
+ IMPORT rt_interrupt_from_thread
+ IMPORT rt_interrupt_to_thread
+ IMPORT rt_hw_trap_irq
+
+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_interrput_flag set, jump to
+ ; rt_hw_context_switch_interrupt_do and don't return
+ LDR r0, =rt_thread_switch_interrput_flag
+ LDR r1, [r0]
+ CMP r1, #1
+ BEQ rt_hw_context_switch_interrupt_do
+
+ LDMFD sp!, {r0-r12,lr}
+ SUBS pc, lr, #4
+ 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|F_Bit|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
+ MRS r4, spsr
+ STMFD sp!, {r4} ; push old task's spsr
+
+ 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 spsr
+ MSR spsr_cxsf, r4
+ LDMFD sp!, {r4} ; pop new task's psr
+ MSR cpsr_cxsf, r4
+
+ LDMFD sp!, {r0-r12,lr,pc} ; pop new task's r0-r12,lr & pc
+ 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
diff --git a/libcpu/arm/AT91SAM7S/trap.c b/libcpu/arm/AT91SAM7S/trap.c
new file mode 100644
index 0000000000..18534cda8b
--- /dev/null
+++ b/libcpu/arm/AT91SAM7S/trap.c
@@ -0,0 +1,40 @@
+/*
+ * File : trap.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2006-08-25 Bernard first version
+ */
+
+#include <rtthread.h>
+#include <rthw.h>
+
+#include "AT91SAM7S.h"
+
+/**
+ * @addtogroup AT91SAM7
+ */
+/*@{*/
+
+void rt_hw_trap_irq()
+{
+ rt_isr_handler_t hander = (rt_isr_handler_t)AT91C_AIC_IVR;
+
+ hander(AT91C_AIC_ISR);
+
+ /* end of interrupt */
+ AT91C_AIC_EOICR = 0;
+}
+
+void rt_hw_trap_fiq()
+{
+ rt_kprintf("fast interrupt request\n");
+}
+
+/*@}*/
diff --git a/libcpu/arm/AT91SAM7X/AT91SAM7X.h b/libcpu/arm/AT91SAM7X/AT91SAM7X.h
new file mode 100644
index 0000000000..54a7d11c46
--- /dev/null
+++ b/libcpu/arm/AT91SAM7X/AT91SAM7X.h
@@ -0,0 +1,342 @@
+/*
+ * File : at91sam7x.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Develop Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2006-08-23 Bernard first version
+ */
+
+#ifndef __AT91SAM7S_H__
+#define __AT91SAM7S_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define AT91_REG *(volatile unsigned int *) /* Hardware register definition */
+
+/* ========== Register definition for TC0 peripheral ========== */
+#define AT91C_TC0_SR (AT91_REG(0xFFFA0020)) /* TC0 Status Register */
+#define AT91C_TC0_RC (AT91_REG(0xFFFA001C)) /* TC0 Register C */
+#define AT91C_TC0_RB (AT91_REG(0xFFFA0018)) /* TC0 Register B */
+#define AT91C_TC0_CCR (AT91_REG(0xFFFA0000)) /* TC0 Channel Control Register */
+#define AT91C_TC0_CMR (AT91_REG(0xFFFA0004)) /* TC0 Channel Mode Register (Capture Mode / Waveform Mode) */
+#define AT91C_TC0_IER (AT91_REG(0xFFFA0024)) /* TC0 Interrupt Enable Register */
+#define AT91C_TC0_RA (AT91_REG(0xFFFA0014)) /* TC0 Register A */
+#define AT91C_TC0_IDR (AT91_REG(0xFFFA0028)) /* TC0 Interrupt Disable Register */
+#define AT91C_TC0_CV (AT91_REG(0xFFFA0010)) /* TC0 Counter Value */
+#define AT91C_TC0_IMR (AT91_REG(0xFFFA002C)) /* TC0 Interrupt Mask Register */
+
+/* ========== Register definition for TC1 peripheral ========== */
+#define AT91C_TC1_RB (AT91_REG(0xFFFA0058)) /* TC1 Register B */
+#define AT91C_TC1_CCR (AT91_REG(0xFFFA0040)) /* TC1 Channel Control Register */
+#define AT91C_TC1_IER (AT91_REG(0xFFFA0064)) /* TC1 Interrupt Enable Register */
+#define AT91C_TC1_IDR (AT91_REG(0xFFFA0068)) /* TC1 Interrupt Disable Register */
+#define AT91C_TC1_SR (AT91_REG(0xFFFA0060)) /* TC1 Status Register */
+#define AT91C_TC1_CMR (AT91_REG(0xFFFA0044)) /* TC1 Channel Mode Register (Capture Mode / Waveform Mode) */
+#define AT91C_TC1_RA (AT91_REG(0xFFFA0054)) /* TC1 Register A */
+#define AT91C_TC1_RC (AT91_REG(0xFFFA005C)) /* TC1 Register C */
+#define AT91C_TC1_IMR (AT91_REG(0xFFFA006C)) /* TC1 Interrupt Mask Register */
+#define AT91C_TC1_CV (AT91_REG(0xFFFA0050)) /* TC1 Counter Value */
+
+/* ========== Register definition for TC2 peripheral ========== */
+#define AT91C_TC2_CMR (AT91_REG(0xFFFA0084)) /* TC2 Channel Mode Register (Capture Mode / Waveform Mode) */
+#define AT91C_TC2_CCR (AT91_REG(0xFFFA0080)) /* TC2 Channel Control Register */
+#define AT91C_TC2_CV (AT91_REG(0xFFFA0090)) /* TC2 Counter Value */
+#define AT91C_TC2_RA (AT91_REG(0xFFFA0094)) /* TC2 Register A */
+#define AT91C_TC2_RB (AT91_REG(0xFFFA0098)) /* TC2 Register B */
+#define AT91C_TC2_IDR (AT91_REG(0xFFFA00A8)) /* TC2 Interrupt Disable Register */
+#define AT91C_TC2_IMR (AT91_REG(0xFFFA00AC)) /* TC2 Interrupt Mask Register */
+#define AT91C_TC2_RC (AT91_REG(0xFFFA009C)) /* TC2 Register C */
+#define AT91C_TC2_IER (AT91_REG(0xFFFA00A4)) /* TC2 Interrupt Enable Register */
+#define AT91C_TC2_SR (AT91_REG(0xFFFA00A0)) /* TC2 Status Register */
+
+/* ========== Register definition for PITC peripheral ========== */
+#define AT91C_PITC_PIVR (AT91_REG(0xFFFFFD38)) /* PITC Period Interval Value Register */
+#define AT91C_PITC_PISR (AT91_REG(0xFFFFFD34)) /* PITC Period Interval Status Register */
+#define AT91C_PITC_PIIR (AT91_REG(0xFFFFFD3C)) /* PITC Period Interval Image Register */
+#define AT91C_PITC_PIMR (AT91_REG(0xFFFFFD30)) /* PITC Period Interval Mode Register */
+
+/* ========== Register definition for UDP peripheral ========== */
+#define AT91C_UDP_NUM (AT91_REG(0xFFFB0000)) /* UDP Frame Number Register */
+#define AT91C_UDP_STAT (AT91_REG(0xFFFB0004)) /* UDP Global State Register */
+#define AT91C_UDP_FADDR (AT91_REG(0xFFFB0008)) /* UDP Function Address Register */
+#define AT91C_UDP_IER (AT91_REG(0xFFFB0010)) /* UDP Interrupt Enable Register */
+#define AT91C_UDP_IDR (AT91_REG(0xFFFB0014)) /* UDP Interrupt Disable Register */
+#define AT91C_UDP_IMR (AT91_REG(0xFFFB0018)) /* UDP Interrupt Mask Register */
+#define AT91C_UDP_ISR (AT91_REG(0xFFFB001C)) /* UDP Interrupt Status Register */
+#define AT91C_UDP_ICR (AT91_REG(0xFFFB0020)) /* UDP Interrupt Clear Register */
+#define AT91C_UDP_RSTEP (AT91_REG(0xFFFB0028)) /* UDP Reset Endpoint Register */
+#define AT91C_UDP_CSR0 (AT91_REG(0xFFFB0030)) /* UDP Endpoint Control and Status Register */
+#define AT91C_UDP_CSR(n) (*(&AT91C_UDP_CSR0 + n))
+#define AT91C_UDP_FDR0 (AT91_REG(0xFFFB0050)) /* UDP Endpoint FIFO Data Register */
+#define AT91C_UDP_FDR(n) (*(&AT91C_UDP_FDR0 + n))
+#define AT91C_UDP_TXVC (AT91_REG(0xFFFB0074)) /* UDP Transceiver Control Register */
+
+/* ========== Register definition for US0 peripheral ========== */
+#define AT91C_US0_CR (AT91_REG(0xFFFC0000)) /* US0 Control Register */
+#define AT91C_US0_MR (AT91_REG(0xFFFC0004)) /* US0 Mode Register */
+#define AT91C_US0_IER (AT91_REG(0xFFFC0008)) /* US0 Interrupt Enable Register */
+#define AT91C_US0_IDR (AT91_REG(0xFFFC000C)) /* US0 Interrupt Disable Register */
+#define AT91C_US0_IMR (AT91_REG(0xFFFC0010)) /* US0 Interrupt Mask Register */
+#define AT91C_US0_CSR (AT91_REG(0xFFFC0014)) /* US0 Channel Status Register */
+#define AT91C_US0_RHR (AT91_REG(0xFFFC0018)) /* US0 Receiver Holding Register */
+#define AT91C_US0_THR (AT91_REG(0xFFFC001C)) /* US0 Transmitter Holding Register */
+#define AT91C_US0_BRGR (AT91_REG(0xFFFC0020)) /* US0 Baud Rate Generator Register */
+#define AT91C_US0_RTOR (AT91_REG(0xFFFC0024)) /* US0 Receiver Time-out Register */
+#define AT91C_US0_TTGR (AT91_REG(0xFFFC0028)) /* US0 Transmitter Time-guard Register */
+#define AT91C_US0_NER (AT91_REG(0xFFFC0044)) /* US0 Nb Errors Register */
+#define AT91C_US0_FIDI (AT91_REG(0xFFFC0040)) /* US0 FI_DI_Ratio Register */
+#define AT91C_US0_IF (AT91_REG(0xFFFC004C)) /* US0 IRDA_FILTER Register */
+
+/* ========== Register definition for AIC peripheral ========== */
+#define AT91C_AIC_SMR0 (AT91_REG(0xFFFFF000)) /* AIC Source Mode Register */
+#define AT91C_AIC_SMR(n) (*(&AT91C_AIC_SMR0 + n))
+#define AT91C_AIC_SVR0 (AT91_REG(0xFFFFF080)) /* AIC Source Vector Register */
+#define AT91C_AIC_SVR(n) (*(&AT91C_AIC_SVR0 + n))
+#define AT91C_AIC_IVR (AT91_REG(0xFFFFF100)) /* AIC Interrupt Vector Register */
+#define AT91C_AIC_FVR (AT91_REG(0xFFFFF104)) /* AIC FIQ Vector Register */
+#define AT91C_AIC_ISR (AT91_REG(0xFFFFF108)) /* AIC Interrupt Status Register */
+#define AT91C_AIC_IPR (AT91_REG(0xFFFFF10C)) /* AIC Interrupt Pending Register */
+#define AT91C_AIC_IMR (AT91_REG(0xFFFFF110)) /* AIC Interrupt Mask Register */
+#define AT91C_AIC_CISR (AT91_REG(0xFFFFF114)) /* AIC Core Interrupt Status Register */
+#define AT91C_AIC_IECR (AT91_REG(0xFFFFF120)) /* AIC Interrupt Enable Command Register */
+#define AT91C_AIC_IDCR (AT91_REG(0xFFFFF124)) /* AIC Interrupt Disable Command Register */
+#define AT91C_AIC_ICCR (AT91_REG(0xFFFFF128)) /* AIC Interrupt Clear Command Register */
+#define AT91C_AIC_ISCR (AT91_REG(0xFFFFF12C)) /* AIC Interrupt Set Command Register */
+#define AT91C_AIC_EOICR (AT91_REG(0xFFFFF130)) /* AIC End of Interrupt Command Register */
+#define AT91C_AIC_SPU (AT91_REG(0xFFFFF134)) /* AIC Spurious Vector Register */
+#define AT91C_AIC_DCR (AT91_REG(0xFFFFF138)) /* AIC Debug Control Register (Protect) */
+#define AT91C_AIC_FFER (AT91_REG(0xFFFFF140)) /* AIC Fast Forcing Enable Register */
+#define AT91C_AIC_FFDR (AT91_REG(0xFFFFF144)) /* AIC Fast Forcing Disable Register */
+#define AT91C_AIC_FFSR (AT91_REG(0xFFFFF148)) /* AIC Fast Forcing Status Register */
+
+
+/* ========== Register definition for DBGU peripheral ========== */
+#define AT91C_DBGU_EXID (AT91_REG(0xFFFFF244)) /* DBGU Chip ID Extension Register */
+#define AT91C_DBGU_BRGR (AT91_REG(0xFFFFF220)) /* DBGU Baud Rate Generator Register */
+#define AT91C_DBGU_IDR (AT91_REG(0xFFFFF20C)) /* DBGU Interrupt Disable Register */
+#define AT91C_DBGU_CSR (AT91_REG(0xFFFFF214)) /* DBGU Channel Status Register */
+#define AT91C_DBGU_CIDR (AT91_REG(0xFFFFF240)) /* DBGU Chip ID Register */
+#define AT91C_DBGU_MR (AT91_REG(0xFFFFF204)) /* DBGU Mode Register */
+#define AT91C_DBGU_IMR (AT91_REG(0xFFFFF210)) /* DBGU Interrupt Mask Register */
+#define AT91C_DBGU_CR (AT91_REG(0xFFFFF200)) /* DBGU Control Register */
+#define AT91C_DBGU_FNTR (AT91_REG(0xFFFFF248)) /* DBGU Force NTRST Register */
+#define AT91C_DBGU_THR (AT91_REG(0xFFFFF21C)) /* DBGU Transmitter Holding Register */
+#define AT91C_DBGU_RHR (AT91_REG(0xFFFFF218)) /* DBGU Receiver Holding Register */
+#define AT91C_DBGU_IER (AT91_REG(0xFFFFF208)) /* DBGU Interrupt Enable Register */
+
+/* ========== Register definition for PIO peripheral ========== */
+#define AT91C_PIO_ODR (AT91_REG(0xFFFFF414)) /* PIOA Output Disable Registerr */
+#define AT91C_PIO_SODR (AT91_REG(0xFFFFF430)) /* PIOA Set Output Data Register */
+#define AT91C_PIO_ISR (AT91_REG(0xFFFFF44C)) /* PIOA Interrupt Status Register */
+#define AT91C_PIO_ABSR (AT91_REG(0xFFFFF478)) /* PIOA AB Select Status Register */
+#define AT91C_PIO_IER (AT91_REG(0xFFFFF440)) /* PIOA Interrupt Enable Register */
+#define AT91C_PIO_PPUDR (AT91_REG(0xFFFFF460)) /* PIOA Pull-up Disable Register */
+#define AT91C_PIO_IMR (AT91_REG(0xFFFFF448)) /* PIOA Interrupt Mask Register */
+#define AT91C_PIO_PER (AT91_REG(0xFFFFF400)) /* PIOA PIO Enable Register */
+#define AT91C_PIO_IFDR (AT91_REG(0xFFFFF424)) /* PIOA Input Filter Disable Register */
+#define AT91C_PIO_OWDR (AT91_REG(0xFFFFF4A4)) /* PIOA Output Write Disable Register */
+#define AT91C_PIO_MDSR (AT91_REG(0xFFFFF458)) /* PIOA Multi-driver Status Register */
+#define AT91C_PIO_IDR (AT91_REG(0xFFFFF444)) /* PIOA Interrupt Disable Register */
+#define AT91C_PIO_ODSR (AT91_REG(0xFFFFF438)) /* PIOA Output Data Status Register */
+#define AT91C_PIO_PPUSR (AT91_REG(0xFFFFF468)) /* PIOA Pull-up Status Register */
+#define AT91C_PIO_OWSR (AT91_REG(0xFFFFF4A8)) /* PIOA Output Write Status Register */
+#define AT91C_PIO_BSR (AT91_REG(0xFFFFF474)) /* PIOA Select B Register */
+#define AT91C_PIO_OWER (AT91_REG(0xFFFFF4A0)) /* PIOA Output Write Enable Register */
+#define AT91C_PIO_IFER (AT91_REG(0xFFFFF420)) /* PIOA Input Filter Enable Register */
+#define AT91C_PIO_PDSR (AT91_REG(0xFFFFF43C)) /* PIOA Pin Data Status Register */
+#define AT91C_PIO_PPUER (AT91_REG(0xFFFFF464)) /* PIOA Pull-up Enable Register */
+#define AT91C_PIO_OSR (AT91_REG(0xFFFFF418)) /* PIOA Output Status Register */
+#define AT91C_PIO_ASR (AT91_REG(0xFFFFF470)) /* PIOA Select A Register */
+#define AT91C_PIO_MDDR (AT91_REG(0xFFFFF454)) /* PIOA Multi-driver Disable Register */
+#define AT91C_PIO_CODR (AT91_REG(0xFFFFF434)) /* PIOA Clear Output Data Register */
+#define AT91C_PIO_MDER (AT91_REG(0xFFFFF450)) /* PIOA Multi-driver Enable Register */
+#define AT91C_PIO_PDR (AT91_REG(0xFFFFF404)) /* PIOA PIO Disable Register */
+#define AT91C_PIO_IFSR (AT91_REG(0xFFFFF428)) /* PIOA Input Filter Status Register */
+#define AT91C_PIO_OER (AT91_REG(0xFFFFF410)) /* PIOA Output Enable Register */
+#define AT91C_PIO_PSR (AT91_REG(0xFFFFF408)) /* PIOA PIO Status Register */
+
+// ========== Register definition for PIOA peripheral ==========
+#define AT91C_PIOA_IMR (AT91_REG(0xFFFFF448)) // (PIOA) Interrupt Mask Register
+#define AT91C_PIOA_IER (AT91_REG(0xFFFFF440)) // (PIOA) Interrupt Enable Register
+#define AT91C_PIOA_OWDR (AT91_REG(0xFFFFF4A4)) // (PIOA) Output Write Disable Register
+#define AT91C_PIOA_ISR (AT91_REG(0xFFFFF44C)) // (PIOA) Interrupt Status Register
+#define AT91C_PIOA_PPUDR (AT91_REG(0xFFFFF460)) // (PIOA) Pull-up Disable Register
+#define AT91C_PIOA_MDSR (AT91_REG(0xFFFFF458)) // (PIOA) Multi-driver Status Register
+#define AT91C_PIOA_MDER (AT91_REG(0xFFFFF450)) // (PIOA) Multi-driver Enable Register
+#define AT91C_PIOA_PER (AT91_REG(0xFFFFF400)) // (PIOA) PIO Enable Register
+#define AT91C_PIOA_PSR (AT91_REG(0xFFFFF408)) // (PIOA) PIO Status Register
+#define AT91C_PIOA_OER (AT91_REG(0xFFFFF410)) // (PIOA) Output Enable Register
+#define AT91C_PIOA_BSR (AT91_REG(0xFFFFF474)) // (PIOA) Select B Register
+#define AT91C_PIOA_PPUER (AT91_REG(0xFFFFF464)) // (PIOA) Pull-up Enable Register
+#define AT91C_PIOA_MDDR (AT91_REG(0xFFFFF454)) // (PIOA) Multi-driver Disable Register
+#define AT91C_PIOA_PDR (AT91_REG(0xFFFFF404)) // (PIOA) PIO Disable Register
+#define AT91C_PIOA_ODR (AT91_REG(0xFFFFF414)) // (PIOA) Output Disable Registerr
+#define AT91C_PIOA_IFDR (AT91_REG(0xFFFFF424)) // (PIOA) Input Filter Disable Register
+#define AT91C_PIOA_ABSR (AT91_REG(0xFFFFF478)) // (PIOA) AB Select Status Register
+#define AT91C_PIOA_ASR (AT91_REG(0xFFFFF470)) // (PIOA) Select A Register
+#define AT91C_PIOA_PPUSR (AT91_REG(0xFFFFF468)) // (PIOA) Pull-up Status Register
+#define AT91C_PIOA_ODSR (AT91_REG(0xFFFFF438)) // (PIOA) Output Data Status Register
+#define AT91C_PIOA_SODR (AT91_REG(0xFFFFF430)) // (PIOA) Set Output Data Register
+#define AT91C_PIOA_IFSR (AT91_REG(0xFFFFF428)) // (PIOA) Input Filter Status Register
+#define AT91C_PIOA_IFER (AT91_REG(0xFFFFF420)) // (PIOA) Input Filter Enable Register
+#define AT91C_PIOA_OSR (AT91_REG(0xFFFFF418)) // (PIOA) Output Status Register
+#define AT91C_PIOA_IDR (AT91_REG(0xFFFFF444)) // (PIOA) Interrupt Disable Register
+#define AT91C_PIOA_PDSR (AT91_REG(0xFFFFF43C)) // (PIOA) Pin Data Status Register
+#define AT91C_PIOA_CODR (AT91_REG(0xFFFFF434)) // (PIOA) Clear Output Data Register
+#define AT91C_PIOA_OWSR (AT91_REG(0xFFFFF4A8)) // (PIOA) Output Write Status Register
+#define AT91C_PIOA_OWER (AT91_REG(0xFFFFF4A0)) // (PIOA) Output Write Enable Register
+// ========== Register definition for PIOB peripheral ==========
+#define AT91C_PIOB_OWSR (AT91_REG(0xFFFFF6A8)) // (PIOB) Output Write Status Register
+#define AT91C_PIOB_PPUSR (AT91_REG(0xFFFFF668)) // (PIOB) Pull-up Status Register
+#define AT91C_PIOB_PPUDR (AT91_REG(0xFFFFF660)) // (PIOB) Pull-up Disable Register
+#define AT91C_PIOB_MDSR (AT91_REG(0xFFFFF658)) // (PIOB) Multi-driver Status Register
+#define AT91C_PIOB_MDER (AT91_REG(0xFFFFF650)) // (PIOB) Multi-driver Enable Register
+#define AT91C_PIOB_IMR (AT91_REG(0xFFFFF648)) // (PIOB) Interrupt Mask Register
+#define AT91C_PIOB_OSR (AT91_REG(0xFFFFF618)) // (PIOB) Output Status Register
+#define AT91C_PIOB_OER (AT91_REG(0xFFFFF610)) // (PIOB) Output Enable Register
+#define AT91C_PIOB_PSR (AT91_REG(0xFFFFF608)) // (PIOB) PIO Status Register
+#define AT91C_PIOB_PER (AT91_REG(0xFFFFF600)) // (PIOB) PIO Enable Register
+#define AT91C_PIOB_BSR (AT91_REG(0xFFFFF674)) // (PIOB) Select B Register
+#define AT91C_PIOB_PPUER (AT91_REG(0xFFFFF664)) // (PIOB) Pull-up Enable Register
+#define AT91C_PIOB_IFDR (AT91_REG(0xFFFFF624)) // (PIOB) Input Filter Disable Register
+#define AT91C_PIOB_ODR (AT91_REG(0xFFFFF614)) // (PIOB) Output Disable Registerr
+#define AT91C_PIOB_ABSR (AT91_REG(0xFFFFF678)) // (PIOB) AB Select Status Register
+#define AT91C_PIOB_ASR (AT91_REG(0xFFFFF670)) // (PIOB) Select A Register
+#define AT91C_PIOB_IFER (AT91_REG(0xFFFFF620)) // (PIOB) Input Filter Enable Register
+#define AT91C_PIOB_IFSR (AT91_REG(0xFFFFF628)) // (PIOB) Input Filter Status Register
+#define AT91C_PIOB_SODR (AT91_REG(0xFFFFF630)) // (PIOB) Set Output Data Register
+#define AT91C_PIOB_ODSR (AT91_REG(0xFFFFF638)) // (PIOB) Output Data Status Register
+#define AT91C_PIOB_CODR (AT91_REG(0xFFFFF634)) // (PIOB) Clear Output Data Register
+#define AT91C_PIOB_PDSR (AT91_REG(0xFFFFF63C)) // (PIOB) Pin Data Status Register
+#define AT91C_PIOB_OWER (AT91_REG(0xFFFFF6A0)) // (PIOB) Output Write Enable Register
+#define AT91C_PIOB_IER (AT91_REG(0xFFFFF640)) // (PIOB) Interrupt Enable Register
+#define AT91C_PIOB_OWDR (AT91_REG(0xFFFFF6A4)) // (PIOB) Output Write Disable Register
+#define AT91C_PIOB_MDDR (AT91_REG(0xFFFFF654)) // (PIOB) Multi-driver Disable Register
+#define AT91C_PIOB_ISR (AT91_REG(0xFFFFF64C)) // (PIOB) Interrupt Status Register
+#define AT91C_PIOB_IDR (AT91_REG(0xFFFFF644)) // (PIOB) Interrupt Disable Register
+#define AT91C_PIOB_PDR (AT91_REG(0xFFFFF604)) // (PIOB) PIO Disable Register
+
+/* ========== Register definition for PMC peripheral ========== */
+#define AT91C_PMC_SCER (AT91_REG(0xFFFFFC00)) /* PMC System Clock Enable Register */
+#define AT91C_PMC_SCDR (AT91_REG(0xFFFFFC04)) /* PMC System Clock Disable Register */
+#define AT91C_PMC_SCSR (AT91_REG(0xFFFFFC08)) /* PMC System Clock Status Register */
+#define AT91C_PMC_PCER (AT91_REG(0xFFFFFC10)) /* PMC Peripheral Clock Enable Register */
+#define AT91C_PMC_PCDR (AT91_REG(0xFFFFFC14)) /* PMC Peripheral Clock Disable Register */
+#define AT91C_PMC_PCSR (AT91_REG(0xFFFFFC18)) /* PMC Peripheral Clock Status Register */
+#define AT91C_PMC_MOR (AT91_REG(0xFFFFFC20)) /* PMC Main Oscillator Register */
+#define AT91C_PMC_MCFR (AT91_REG(0xFFFFFC24)) /* PMC Main Clock Frequency Register */
+#define AT91C_PMC_PLLR (AT91_REG(0xFFFFFC2C)) /* PMC PLL Register */
+#define AT91C_PMC_MCKR (AT91_REG(0xFFFFFC30)) /* PMC Master Clock Register */
+#define AT91C_PMC_PCKR (AT91_REG(0xFFFFFC40)) /* PMC Programmable Clock Register */
+#define AT91C_PMC_IER (AT91_REG(0xFFFFFC60)) /* PMC Interrupt Enable Register */
+#define AT91C_PMC_IDR (AT91_REG(0xFFFFFC64)) /* PMC Interrupt Disable Register */
+#define AT91C_PMC_SR (AT91_REG(0xFFFFFC68)) /* PMC Status Register */
+#define AT91C_PMC_IMR (AT91_REG(0xFFFFFC6C)) /* PMC Interrupt Mask Register */
+
+// ========== Register definition for PDC_SPI1 peripheral ==========
+#define AT91C_SPI1_RNPR (AT91_REG(0xFFFE4110)) // (PDC_SPI1) Receive Next Pointer Register
+#define AT91C_SPI1_TPR (AT91_REG(0xFFFE4108)) // (PDC_SPI1) Transmit Pointer Register
+#define AT91C_SPI1_RPR (AT91_REG(0xFFFE4100)) // (PDC_SPI1) Receive Pointer Register
+#define AT91C_SPI1_PTSR (AT91_REG(0xFFFE4124)) // (PDC_SPI1) PDC Transfer Status Register
+#define AT91C_SPI1_RCR (AT91_REG(0xFFFE4104)) // (PDC_SPI1) Receive Counter Register
+#define AT91C_SPI1_TCR (AT91_REG(0xFFFE410C)) // (PDC_SPI1) Transmit Counter Register
+#define AT91C_SPI1_RNCR (AT91_REG(0xFFFE4114)) // (PDC_SPI1) Receive Next Counter Register
+#define AT91C_SPI1_TNCR (AT91_REG(0xFFFE411C)) // (PDC_SPI1) Transmit Next Counter Register
+#define AT91C_SPI1_TNPR (AT91_REG(0xFFFE4118)) // (PDC_SPI1) Transmit Next Pointer Register
+#define AT91C_SPI1_PTCR (AT91_REG(0xFFFE4120)) // (PDC_SPI1) PDC Transfer Control Register
+// ========== Register definition for SPI1 peripheral ==========
+#define AT91C_SPI1_CSR (AT91_REG(0xFFFE4030)) // (SPI1) Chip Select Register
+#define AT91C_SPI1_IDR (AT91_REG(0xFFFE4018)) // (SPI1) Interrupt Disable Register
+#define AT91C_SPI1_SR (AT91_REG(0xFFFE4010)) // (SPI1) Status Register
+#define AT91C_SPI1_RDR (AT91_REG(0xFFFE4008)) // (SPI1) Receive Data Register
+#define AT91C_SPI1_CR (AT91_REG(0xFFFE4000)) // (SPI1) Control Register
+#define AT91C_SPI1_IMR (AT91_REG(0xFFFE401C)) // (SPI1) Interrupt Mask Register
+#define AT91C_SPI1_IER (AT91_REG(0xFFFE4014)) // (SPI1) Interrupt Enable Register
+#define AT91C_SPI1_TDR (AT91_REG(0xFFFE400C)) // (SPI1) Transmit Data Register
+#define AT91C_SPI1_MR (AT91_REG(0xFFFE4004)) // (SPI1) Mode Register
+// ========== Register definition for PDC_SPI0 peripheral ==========
+#define AT91C_SPI0_PTCR (AT91_REG(0xFFFE0120)) // (PDC_SPI0) PDC Transfer Control Register
+#define AT91C_SPI0_TNPR (AT91_REG(0xFFFE0118)) // (PDC_SPI0) Transmit Next Pointer Register
+#define AT91C_SPI0_RNPR (AT91_REG(0xFFFE0110)) // (PDC_SPI0) Receive Next Pointer Register
+#define AT91C_SPI0_TPR (AT91_REG(0xFFFE0108)) // (PDC_SPI0) Transmit Pointer Register
+#define AT91C_SPI0_RPR (AT91_REG(0xFFFE0100)) // (PDC_SPI0) Receive Pointer Register
+#define AT91C_SPI0_PTSR (AT91_REG(0xFFFE0124)) // (PDC_SPI0) PDC Transfer Status Register
+#define AT91C_SPI0_TNCR (AT91_REG(0xFFFE011C)) // (PDC_SPI0) Transmit Next Counter Register
+#define AT91C_SPI0_RNCR (AT91_REG(0xFFFE0114)) // (PDC_SPI0) Receive Next Counter Register
+#define AT91C_SPI0_TCR (AT91_REG(0xFFFE010C)) // (PDC_SPI0) Transmit Counter Register
+#define AT91C_SPI0_RCR (AT91_REG(0xFFFE0104)) // (PDC_SPI0) Receive Counter Register
+// ========== Register definition for SPI0 peripheral ==========
+#define AT91C_SPI0_CSR (AT91_REG(0xFFFE0030)) // (SPI0) Chip Select Register
+#define AT91C_SPI0_IDR (AT91_REG(0xFFFE0018)) // (SPI0) Interrupt Disable Register
+#define AT91C_SPI0_SR (AT91_REG(0xFFFE0010)) // (SPI0) Status Register
+#define AT91C_SPI0_RDR (AT91_REG(0xFFFE0008)) // (SPI0) Receive Data Register
+#define AT91C_SPI0_CR (AT91_REG(0xFFFE0000)) // (SPI0) Control Register
+#define AT91C_SPI0_IMR (AT91_REG(0xFFFE001C)) // (SPI0) Interrupt Mask Register
+#define AT91C_SPI0_IER (AT91_REG(0xFFFE0014)) // (SPI0) Interrupt Enable Register
+#define AT91C_SPI0_TDR (AT91_REG(0xFFFE000C)) // (SPI0) Transmit Data Register
+#define AT91C_SPI0_MR (AT91_REG(0xFFFE0004)) // (SPI0) Mode Register
+
+/******************************************************************************/
+/* PERIPHERAL ID DEFINITIONS FOR AT91SAM7X256 */
+/******************************************************************************/
+#define AT91C_ID_FIQ ( 0) /* Advanced Interrupt Controller (FIQ) */
+#define AT91C_ID_SYS ( 1) /* System Peripheral */
+#define AT91C_ID_PIOA ( 2) /* Parallel IO Controller A */
+#define AT91C_ID_PIOB ( 3) /* Parallel IO Controller B */
+#define AT91C_ID_SPI0 ( 4) /* Serial Peripheral Interface 0 */
+#define AT91C_ID_SPI1 ( 5) /* Serial Peripheral Interface 1 */
+#define AT91C_ID_US0 ( 6) /* USART 0 */
+#define AT91C_ID_US1 ( 7) /* USART 1 */
+#define AT91C_ID_SSC ( 8) /* Serial Synchronous Controller */
+#define AT91C_ID_TWI ( 9) /* Two-Wire Interface */
+#define AT91C_ID_PWMC (10) /* PWM Controller */
+#define AT91C_ID_UDP (11) /* USB Device Port */
+#define AT91C_ID_TC0 (12) /* Timer Counter 0 */
+#define AT91C_ID_TC1 (13) /* Timer Counter 1 */
+#define AT91C_ID_TC2 (14) /* Timer Counter 2 */
+#define AT91C_ID_CAN (15) /* Control Area Network Controller */
+#define AT91C_ID_EMAC (16) /* Ethernet MAC */
+#define AT91C_ID_ADC (17) /* Analog-to-Digital Converter */
+#define AT91C_ID_AES (18) /* Advanced Encryption Standard 128-bit */
+#define AT91C_ID_TDES (19) /* Triple Data Encryption Standard */
+#define AT91C_ID_20_Reserved (20) /* Reserved */
+#define AT91C_ID_21_Reserved (21) /* Reserved */
+#define AT91C_ID_22_Reserved (22) /* Reserved */
+#define AT91C_ID_23_Reserved (23) /* Reserved */
+#define AT91C_ID_24_Reserved (24) /* Reserved */
+#define AT91C_ID_25_Reserved (25) /* Reserved */
+#define AT91C_ID_26_Reserved (26) /* Reserved */
+#define AT91C_ID_27_Reserved (27) /* Reserved */
+#define AT91C_ID_28_Reserved (28) /* Reserved */
+#define AT91C_ID_29_Reserved (29) /* Reserved */
+#define AT91C_ID_IRQ0 (30) /* Advanced Interrupt Controller (IRQ0) */
+#define AT91C_ID_IRQ1 (31) /* Advanced Interrupt Controller (IRQ1) */
+#define AT91C_ALL_INT (0xC00FFFFF) /* ALL VALID INTERRUPTS */
+
+#define MCK 48054857
+
+/*****************************/
+/* CPU Mode */
+/*****************************/
+#define USERMODE 0x10
+#define FIQMODE 0x11
+#define IRQMODE 0x12
+#define SVCMODE 0x13
+#define ABORTMODE 0x17
+#define UNDEFMODE 0x1b
+#define MODEMASK 0x1f
+#define NOINT 0xc0
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libcpu/arm/AT91SAM7X/context_gcc.S b/libcpu/arm/AT91SAM7X/context_gcc.S
new file mode 100644
index 0000000000..83e9f05755
--- /dev/null
+++ b/libcpu/arm/AT91SAM7X/context_gcc.S
@@ -0,0 +1,99 @@
+/*
+ * File : context.S
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2006-03-13 Bernard first version
+ */
+
+/*!
+ * \addtogroup xgs3c4510
+ */
+/*@{*/
+
+#define NOINT 0xc0
+
+/*
+ * rt_base_t rt_hw_interrupt_disable();
+ */
+.globl rt_hw_interrupt_disable
+rt_hw_interrupt_disable:
+ mrs r0, cpsr
+ orr r1, r0, #NOINT
+ msr cpsr_c, r1
+ mov pc, lr
+
+/*
+ * void rt_hw_interrupt_enable(rt_base_t level);
+ */
+.globl rt_hw_interrupt_enable
+rt_hw_interrupt_enable:
+ msr cpsr, r0
+ mov pc, lr
+
+/*
+ * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
+ * r0 --> from
+ * r1 --> to
+ */
+.globl rt_hw_context_switch
+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
+ stmfd sp!, {r4} @ push cpsr
+ mrs r4, spsr
+ stmfd sp!, {r4} @ push spsr
+
+ str sp, [r0] @ store sp in preempted tasks TCB
+ ldr sp, [r1] @ get new task stack pointer
+
+ ldmfd sp!, {r4} @ pop new task spsr
+ msr spsr_cxsf, r4
+ ldmfd sp!, {r4} @ pop new task cpsr
+ msr cpsr_cxsf, r4
+
+ ldmfd sp!, {r0-r12, lr, pc} @ pop new task r0-r12, lr & pc
+
+/*
+ * void rt_hw_context_switch_to(rt_uint32 to);
+ * r0 --> to
+ */
+.globl rt_hw_context_switch_to
+rt_hw_context_switch_to:
+ ldr sp, [r0] @ get new task stack pointer
+
+ ldmfd sp!, {r4} @ pop new task spsr
+ msr spsr_cxsf, r4
+ ldmfd sp!, {r4} @ pop new task cpsr
+ msr cpsr_cxsf, r4
+
+ ldmfd sp!, {r0-r12, lr, pc} @ pop new task r0-r12, lr & pc
+
+/*
+ * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to);
+ */
+.globl rt_thread_switch_interrput_flag
+.globl rt_interrupt_from_thread
+.globl rt_interrupt_to_thread
+.globl rt_hw_context_switch_interrupt
+rt_hw_context_switch_interrupt:
+ ldr r2, =rt_thread_switch_interrput_flag
+ ldr r3, [r2]
+ cmp r3, #1
+ beq _reswitch
+ mov r3, #1 @ set rt_thread_switch_interrput_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]
+ mov pc, lr
diff --git a/libcpu/arm/AT91SAM7X/context_rvds.S b/libcpu/arm/AT91SAM7X/context_rvds.S
new file mode 100644
index 0000000000..82c5adc574
--- /dev/null
+++ b/libcpu/arm/AT91SAM7X/context_rvds.S
@@ -0,0 +1,107 @@
+;/*
+; * File : context_rvds.S
+; * This file is part of RT-Thread RTOS
+; * COPYRIGHT (C) 2006, RT-Thread Development Team
+; *
+; * The license and distribution terms for this file may be
+; * found in the file LICENSE in this distribution or at
+; * http://www.rt-thread.org/license/LICENSE
+; *
+; * Change Logs:
+; * Date Author Notes
+; * 2009-01-20 Bernard first version
+; */
+
+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
+ STMFD sp!, {r4} ; push cpsr
+ MRS r4, spsr
+ STMFD sp!, {r4} ; push spsr
+
+ STR sp, [r0] ; store sp in preempted tasks TCB
+ LDR sp, [r1] ; get new task stack pointer
+
+ LDMFD sp!, {r4} ; pop new task spsr
+ MSR spsr_cxsf, r4
+ LDMFD sp!, {r4} ; pop new task cpsr
+ MSR cpsr_cxsf, r4
+
+ LDMFD sp!, {r0-r12, lr, pc} ; pop new task r0-r12, lr & pc
+ 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 spsr
+ MSR spsr_cxsf, r4
+ LDMFD sp!, {r4} ; pop new task cpsr
+ MSR cpsr_cxsf, r4
+
+ LDMFD sp!, {r0-r12, lr, pc} ; pop new task r0-r12, lr & pc
+ ENDP
+
+;/*
+; * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to);
+; */
+ IMPORT rt_thread_switch_interrput_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_interrput_flag
+ LDR r3, [r2]
+ CMP r3, #1
+ BEQ _reswitch
+ MOV r3, #1 ; set rt_thread_switch_interrput_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
+
+ END \ No newline at end of file
diff --git a/libcpu/arm/AT91SAM7X/cpu.c b/libcpu/arm/AT91SAM7X/cpu.c
new file mode 100644
index 0000000000..679fddc454
--- /dev/null
+++ b/libcpu/arm/AT91SAM7X/cpu.c
@@ -0,0 +1,42 @@
+/*
+ * File : cpu.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Develop Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2006-08-23 Bernard first version
+ */
+
+#include <rtthread.h>
+#include "AT91SAM7X.h"
+
+/**
+ * @addtogroup AT91SAM7X
+ */
+/*@{*/
+
+/**
+ * this function will reset CPU
+ *
+ */
+void rt_hw_cpu_reset()
+{
+}
+
+/**
+ * this function will shutdown CPU
+ *
+ */
+void rt_hw_cpu_shutdown()
+{
+ rt_kprintf("shutdown...\n");
+
+ while (1);
+}
+
+/*@}*/
diff --git a/libcpu/arm/AT91SAM7X/interrupt.c b/libcpu/arm/AT91SAM7X/interrupt.c
new file mode 100644
index 0000000000..014451a1ff
--- /dev/null
+++ b/libcpu/arm/AT91SAM7X/interrupt.c
@@ -0,0 +1,91 @@
+/*
+ * File : trap.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2006-08-23 Bernard first version
+ */
+
+#include <rtthread.h>
+#include "AT91SAM7X.h"
+
+#define MAX_HANDLERS 32
+
+extern rt_uint32_t rt_interrupt_nest;
+
+rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread;
+rt_uint32_t rt_thread_switch_interrput_flag;
+
+/**
+ * @addtogroup AT91SAM7
+ */
+/*@{*/
+
+void rt_hw_interrupt_handler(int vector)
+{
+ rt_kprintf("Unhandled interrupt %d occured!!!\n", vector);
+}
+
+/**
+ * This function will initialize hardware interrupt
+ */
+void rt_hw_interrupt_init()
+{
+ rt_base_t index;
+
+ for (index = 0; index < MAX_HANDLERS; index ++)
+ {
+ AT91C_AIC_SVR(index) = (rt_uint32_t)rt_hw_interrupt_handler;
+ }
+
+ /* 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_interrput_flag = 0;
+}
+
+/**
+ * This function will mask a interrupt.
+ * @param vector the interrupt number
+ */
+void rt_hw_interrupt_mask(int vector)
+{
+ /* disable interrupt */
+ AT91C_AIC_IDCR = 1 << vector;
+
+ /* clear interrupt */
+ AT91C_AIC_ICCR = 1 << vector;
+}
+
+/**
+ * This function will un-mask a interrupt.
+ * @param vector the interrupt number
+ */
+void rt_hw_interrupt_umask(int vector)
+{
+ AT91C_AIC_IECR = 1 << vector;
+}
+
+/**
+ * This function will install a interrupt service routine to a interrupt.
+ * @param vector the interrupt number
+ * @param new_handler the interrupt service routine to be installed
+ * @param old_handler the old interrupt service routine
+ */
+void rt_hw_interrupt_install(int vector, rt_isr_handler_t new_handler, rt_isr_handler_t *old_handler)
+{
+ if(vector >= 0 && vector < MAX_HANDLERS)
+ {
+ if (*old_handler != RT_NULL) *old_handler = (rt_isr_handler_t)AT91C_AIC_SVR(vector);
+ if (new_handler != RT_NULL) AT91C_AIC_SVR(vector) = (rt_uint32_t)new_handler;
+ }
+}
+
+/*@}*/
diff --git a/libcpu/arm/AT91SAM7X/mii.h b/libcpu/arm/AT91SAM7X/mii.h
new file mode 100644
index 0000000000..4ec25667a3
--- /dev/null
+++ b/libcpu/arm/AT91SAM7X/mii.h
@@ -0,0 +1,156 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*
+ * Parts of this file are borrowed by the Linux include file linux/mii.h:
+ * Copyright (C) 1996, 1999, 2001 David S. Miller ([email protected])
+ */
+
+#ifndef _MII_H_
+#define _MII_H_
+
+/* Generic MII registers. */
+#define MII_BMCR 0x00 /* Basic mode control register */
+#define MII_BMSR 0x01 /* Basic mode status register */
+#define MII_PHYSID1 0x02 /* PHYS ID 1 */
+#define MII_PHYSID2 0x03 /* PHYS ID 2 */
+#define MII_ADVERTISE 0x04 /* Advertisement control reg */
+#define MII_LPA 0x05 /* Link partner ability reg */
+#define MII_EXPANSION 0x06 /* Expansion register */
+#define MII_CTRL1000 0x09 /* 1000BASE-T control */
+#define MII_STAT1000 0x0a /* 1000BASE-T status */
+#define MII_ESTATUS 0x0f /* Extended Status */
+#define MII_DCOUNTER 0x12 /* Disconnect counter */
+#define MII_FCSCOUNTER 0x13 /* False carrier counter */
+#define MII_NWAYTEST 0x14 /* N-way auto-neg test reg */
+#define MII_RERRCOUNTER 0x15 /* Receive error counter */
+#define MII_SREVISION 0x16 /* Silicon revision */
+#define MII_RESV1 0x17 /* Reserved... */
+#define MII_LBRERROR 0x18 /* Lpback, rx, bypass error */
+#define MII_PHYADDR 0x19 /* PHY address */
+#define MII_RESV2 0x1a /* Reserved... */
+#define MII_TPISTATUS 0x1b /* TPI status for 10mbps */
+#define MII_NCONFIG 0x1c /* Network interface config */
+
+/* Basic mode control register. */
+#define BMCR_RESV 0x003f /* Unused... */
+#define BMCR_SPEED1000 0x0040 /* MSB of Speed (1000) */
+#define BMCR_CTST 0x0080 /* Collision test */
+#define BMCR_FULLDPLX 0x0100 /* Full duplex */
+#define BMCR_ANRESTART 0x0200 /* Auto negotiation restart */
+#define BMCR_ISOLATE 0x0400 /* Disconnect DP83840 from MII */
+#define BMCR_PDOWN 0x0800 /* Powerdown the DP83840 */
+#define BMCR_ANENABLE 0x1000 /* Enable auto negotiation */
+#define BMCR_SPEED100 0x2000 /* Select 100Mbps */
+#define BMCR_LOOPBACK 0x4000 /* TXD loopback bits */
+#define BMCR_RESET 0x8000 /* Reset the DP83840 */
+
+/* Basic mode status register. */
+#define BMSR_ERCAP 0x0001 /* Ext-reg capability */
+#define BMSR_JCD 0x0002 /* Jabber detected */
+#define BMSR_LSTATUS 0x0004 /* Link status */
+#define BMSR_ANEGCAPABLE 0x0008 /* Able to do auto-negotiation */
+#define BMSR_RFAULT 0x0010 /* Remote fault detected */
+#define BMSR_ANEGCOMPLETE 0x0020 /* Auto-negotiation complete */
+#define BMSR_RESV 0x00c0 /* Unused... */
+#define BMSR_ESTATEN 0x0100 /* Extended Status in R15 */
+#define BMSR_100HALF2 0x0200 /* Can do 100BASE-T2 HDX */
+#define BMSR_100FULL2 0x0400 /* Can do 100BASE-T2 FDX */
+#define BMSR_10HALF 0x0800 /* Can do 10mbps, half-duplex */
+#define BMSR_10FULL 0x1000 /* Can do 10mbps, full-duplex */
+#define BMSR_100HALF 0x2000 /* Can do 100mbps, half-duplex */
+#define BMSR_100FULL 0x4000 /* Can do 100mbps, full-duplex */
+#define BMSR_100BASE4 0x8000 /* Can do 100mbps, 4k packets */
+
+/* Advertisement control register. */
+#define ADVERTISE_SLCT 0x001f /* Selector bits */
+#define ADVERTISE_CSMA 0x0001 /* Only selector supported */
+#define ADVERTISE_10HALF 0x0020 /* Try for 10mbps half-duplex */
+#define ADVERTISE_1000XFULL 0x0020 /* Try for 1000BASE-X full-duplex */
+#define ADVERTISE_10FULL 0x0040 /* Try for 10mbps full-duplex */
+#define ADVERTISE_1000XHALF 0x0040 /* Try for 1000BASE-X half-duplex */
+#define ADVERTISE_100HALF 0x0080 /* Try for 100mbps half-duplex */
+#define ADVERTISE_1000XPAUSE 0x0080 /* Try for 1000BASE-X pause */
+#define ADVERTISE_100FULL 0x0100 /* Try for 100mbps full-duplex */
+#define ADVERTISE_1000XPSE_ASYM 0x0100 /* Try for 1000BASE-X asym pause */
+#define ADVERTISE_100BASE4 0x0200 /* Try for 100mbps 4k packets */
+#define ADVERTISE_PAUSE_CAP 0x0400 /* Try for pause */
+#define ADVERTISE_PAUSE_ASYM 0x0800 /* Try for asymetric pause */
+#define ADVERTISE_RESV 0x1000 /* Unused... */
+#define ADVERTISE_RFAULT 0x2000 /* Say we can detect faults */
+#define ADVERTISE_LPACK 0x4000 /* Ack link partners response */
+#define ADVERTISE_NPAGE 0x8000 /* Next page bit */
+
+#define ADVERTISE_FULL (ADVERTISE_100FULL | ADVERTISE_10FULL | \
+ ADVERTISE_CSMA)
+#define ADVERTISE_ALL (ADVERTISE_10HALF | ADVERTISE_10FULL | \
+ ADVERTISE_100HALF | ADVERTISE_100FULL)
+
+/* Link partner ability register. */
+#define LPA_SLCT 0x001f /* Same as advertise selector */
+#define LPA_10HALF 0x0020 /* Can do 10mbps half-duplex */
+#define LPA_1000XFULL 0x0020 /* Can do 1000BASE-X full-duplex */
+#define LPA_10FULL 0x0040 /* Can do 10mbps full-duplex */
+#define LPA_1000XHALF 0x0040 /* Can do 1000BASE-X half-duplex */
+#define LPA_100HALF 0x0080 /* Can do 100mbps half-duplex */
+#define LPA_1000XPAUSE 0x0080 /* Can do 1000BASE-X pause */
+#define LPA_100FULL 0x0100 /* Can do 100mbps full-duplex */
+#define LPA_1000XPAUSE_ASYM 0x0100 /* Can do 1000BASE-X pause asym*/
+#define LPA_100BASE4 0x0200 /* Can do 100mbps 4k packets */
+#define LPA_PAUSE_CAP 0x0400 /* Can pause */
+#define LPA_PAUSE_ASYM 0x0800 /* Can pause asymetrically */
+#define LPA_RESV 0x1000 /* Unused... */
+#define LPA_RFAULT 0x2000 /* Link partner faulted */
+#define LPA_LPACK 0x4000 /* Link partner acked us */
+#define LPA_NPAGE 0x8000 /* Next page bit */
+
+#define LPA_DUPLEX (LPA_10FULL | LPA_100FULL)
+#define LPA_100 (LPA_100FULL | LPA_100HALF | LPA_100BASE4)
+
+/* Expansion register for auto-negotiation. */
+#define EXPANSION_NWAY 0x0001 /* Can do N-way auto-nego */
+#define EXPANSION_LCWP 0x0002 /* Got new RX page code word */
+#define EXPANSION_ENABLENPAGE 0x0004 /* This enables npage words */
+#define EXPANSION_NPCAPABLE 0x0008 /* Link partner supports npage */
+#define EXPANSION_MFAULTS 0x0010 /* Multiple faults detected */
+#define EXPANSION_RESV 0xffe0 /* Unused... */
+
+#define ESTATUS_1000_TFULL 0x2000 /* Can do 1000BT Full */
+#define ESTATUS_1000_THALF 0x1000 /* Can do 1000BT Half */
+
+/* N-way test register. */
+#define NWAYTEST_RESV1 0x00ff /* Unused... */
+#define NWAYTEST_LOOPBACK 0x0100 /* Enable loopback for N-way */
+#define NWAYTEST_RESV2 0xfe00 /* Unused... */
+
+/* 1000BASE-T Control register */
+#define ADVERTISE_1000FULL 0x0200 /* Advertise 1000BASE-T full duplex */
+#define ADVERTISE_1000HALF 0x0100 /* Advertise 1000BASE-T half duplex */
+
+/* 1000BASE-T Status register */
+#define LPA_1000LOCALRXOK 0x2000 /* Link partner local receiver status */
+#define LPA_1000REMRXOK 0x1000 /* Link partner remote receiver status */
+#define LPA_1000FULL 0x0800 /* Link partner 1000BASE-T full duplex */
+#define LPA_1000HALF 0x0400 /* Link partner 1000BASE-T half duplex */
+
+#define MII_DM9161_ID 0x0181b8a0
+#define MII_AM79C875_ID 0x00225540
+#define MII_MICREL_ID 0x00221610
+
+#endif /* _MII_H_ */
diff --git a/libcpu/arm/AT91SAM7X/sam7x_emac.c b/libcpu/arm/AT91SAM7X/sam7x_emac.c
new file mode 100644
index 0000000000..39fa8e5906
--- /dev/null
+++ b/libcpu/arm/AT91SAM7X/sam7x_emac.c
@@ -0,0 +1,554 @@
+#include <rthw.h>
+#include <rtthread.h>
+#include <netif/ethernetif.h>
+
+#include "sam7x_emac.h"
+#include "AT91SAM7X256.h"
+#include "lwipopts.h"
+
+#define MAX_ADDR_LEN 6
+#define EMAC_PIO_CFG (AT91C_PB0_ETXCK_EREFCK | \
+ AT91C_PB1_ETXEN | \
+ AT91C_PB2_ETX0 | \
+ AT91C_PB3_ETX1 | \
+ AT91C_PB4_ECRS | \
+ AT91C_PB5_ERX0 | \
+ AT91C_PB6_ERX1 | \
+ AT91C_PB7_ERXER | \
+ AT91C_PB8_EMDC | \
+ AT91C_PB9_EMDIO | \
+ AT91C_PB10_ETX2 | \
+ AT91C_PB11_ETX3 | \
+ AT91C_PB10_ETX2 | \
+ AT91C_PB13_ERX2 | \
+ AT91C_PB14_ERX3 | \
+ AT91C_PB15_ERXDV_ECRSDV| \
+ AT91C_PB16_ECOL | \
+ AT91C_PB17_ERXCK)
+
+#define RB_BUFFER_SIZE 8 /* max number of receive buffers */
+#define ETH_RX_BUF_SIZE 128
+
+#define TB_BUFFER_SIZE 4
+#define ETH_TX_BUF_SIZE (PBUF_POOL_BUFSIZE)
+
+struct rbf_t
+{
+ rt_uint32_t addr;
+ rt_uint32_t status;
+};
+
+static rt_uint32_t current_rb_index; /* current receive buffer index */
+static volatile struct rbf_t rb_descriptors[RB_BUFFER_SIZE];
+static volatile struct rbf_t tb_descriptors[TB_BUFFER_SIZE];
+static rt_uint8_t rx_buf[RB_BUFFER_SIZE][ETH_RX_BUF_SIZE] __attribute__ ((aligned (8)));
+static rt_uint8_t tx_buf[TB_BUFFER_SIZE][ETH_TX_BUF_SIZE] __attribute__ ((aligned (8)));
+static struct rt_semaphore tx_sem;
+
+struct net_device
+{
+ /* inherit from ethernet device */
+ struct eth_device parent;
+
+ /* interface address info. */
+ rt_uint8_t dev_addr[MAX_ADDR_LEN]; /* hw address */
+};
+static struct net_device sam7x_dev_entry;
+static struct net_device *sam7x_dev =&sam7x_dev_entry;
+AT91PS_EMAC pEmac = AT91C_BASE_EMAC;
+
+rt_inline void write_phy(rt_uint8_t addr, rt_uint32_t value)
+{
+ AT91C_BASE_EMAC->EMAC_MAN = ((0x01<<30) | (2 << 16) | (1 << 28) |
+ (AT91C_PHY_ADDR << 23) | (addr << 18)) | value;
+
+ /* Wait until IDLE bit in Network Status register is cleared */
+ while (!(AT91C_BASE_EMAC->EMAC_NSR & AT91C_EMAC_IDLE));
+}
+
+rt_inline rt_uint32_t read_phy(rt_uint8_t addr)
+{
+ AT91C_BASE_EMAC->EMAC_MAN = (0x01<<30) | (0x02 << 16) | (0x02 << 28) |
+ (AT91C_PHY_ADDR << 23) | (addr << 18);
+
+ /* Wait until IDLE bit in Network Status register is cleared */
+ while (!(AT91C_BASE_EMAC->EMAC_NSR & AT91C_EMAC_IDLE));
+
+ return (AT91C_BASE_EMAC->EMAC_MAN & 0x0000ffff);
+}
+
+rt_inline void sam7xether_reset_tx_desc(void)
+{
+ static rt_uint32_t index = 0;
+
+ if(tb_descriptors[index].status & TxDESC_STATUS_USED)
+ {
+ while(!tb_descriptors[index].status & TxDESC_STATUS_LAST_BUF)
+ {
+ index ++;
+ if(index >= TB_BUFFER_SIZE)index = 0;
+
+ tb_descriptors[index].status |= TxDESC_STATUS_USED;
+ }
+
+ index ++;
+ if(index >= TB_BUFFER_SIZE)index = 0;
+ }
+}
+
+/* interrupt service routing */
+static void sam7xether_isr(int irq)
+{
+ /* Variable definitions can be made now. */
+ volatile rt_uint32_t isr, rsr;
+
+ /* get status */
+ isr = AT91C_BASE_EMAC->EMAC_ISR;
+ rsr = AT91C_BASE_EMAC->EMAC_RSR;
+
+ if( ( isr & AT91C_EMAC_RCOMP ) || ( rsr & AT91C_EMAC_REC ) )
+ {
+ rt_err_t result;
+
+ /* a frame has been received */
+ result = eth_device_ready((struct eth_device*)&(sam7x_dev->parent));
+ RT_ASSERT(result == RT_EOK);
+
+ AT91C_BASE_EMAC->EMAC_RSR = AT91C_EMAC_REC;
+ }
+
+ if( isr & AT91C_EMAC_TCOMP )
+ {
+ /* A frame has been transmitted. Mark all the buffers as free */
+ sam7xether_reset_tx_desc();
+
+ AT91C_BASE_EMAC->EMAC_TSR = AT91C_EMAC_COMP;
+ }
+}
+
+rt_inline void linksetup(void)
+{
+ rt_uint32_t value;
+
+ /* Check if this is a RTL8201 PHY. */
+ rt_uint16_t id1 = read_phy(PHY_REG_PHYID1);
+ rt_uint16_t id2 = read_phy(PHY_REG_PHYID2);
+
+ if (((id2 << 16) | (id1 & 0xfff0)) == MII_RTL8201_ID)
+ {
+ rt_uint32_t tout;
+
+ /* Configure the PHY device */
+ /* Use autonegotiation about the link speed. */
+ write_phy (PHY_REG_BMCR, PHY_AUTO_NEG);
+
+ /* Wait to complete Auto_Negotiation. */
+ for (tout = 0; tout < 0x100000; tout++)
+ {
+ value = read_phy (PHY_REG_BMSR);
+ if (value & BMSR_ANEGCOMPLETE) break; /* autonegotiation finished. */
+ }
+
+ /* Check the link status. */
+ for (tout = 0; tout < 0x10000; tout++)
+ {
+ value = read_phy (PHY_REG_BMSR);
+ if (value & BMSR_LINKST) break; /* Link is on. */
+ }
+ }
+
+ value = read_phy (PHY_REG_ANLPAR);
+
+ /* Update the MAC register NCFGR. */
+ AT91C_BASE_EMAC->EMAC_NCFGR &= ~(AT91C_EMAC_SPD | AT91C_EMAC_FD);
+
+ /* set full duplex . */
+ if (value & 0xA000) AT91C_BASE_EMAC->EMAC_NCFGR |= AT91C_EMAC_FD;
+ /* set speed */
+ if (value & 0xC000) AT91C_BASE_EMAC->EMAC_NCFGR |= AT91C_EMAC_SPD;
+}
+
+/*
+ * Set the MAC address.
+ */
+rt_inline void update_mac_address(struct net_device* device)
+{
+ AT91C_BASE_EMAC->EMAC_SA1L = (device->dev_addr[3] << 24) |
+ (device->dev_addr[2] << 16) |
+ (device->dev_addr[1] << 8) |
+ device->dev_addr[0];
+ AT91C_BASE_EMAC->EMAC_SA1H = (device->dev_addr[5] << 8) |
+ device->dev_addr[4];
+}
+
+rt_inline void sam7xether_desc_init()
+{
+ rt_uint32_t i;
+
+ /* Rx Buffer Descriptor initialization */
+ current_rb_index = 0;
+ for (i = 0; i < RB_BUFFER_SIZE; i++)
+ {
+ rb_descriptors[i].addr = (rt_uint32_t)&(rx_buf[i][0]);
+ rb_descriptors[i].status = 0;
+ }
+ /* Set the WRAP bit at the end of the list descriptor. */
+ rb_descriptors[RB_BUFFER_SIZE-1].addr |= 0x02;
+ /* Set Rx Queue pointer to descriptor list. */
+ AT91C_BASE_EMAC->EMAC_RBQP = (unsigned int)&(rb_descriptors[0]);
+
+ /* Tx Buffer Descriptor initialization */
+ for (i = 0; i < TB_BUFFER_SIZE; i++)
+ {
+ tb_descriptors[i].addr = (rt_uint32_t)&(tx_buf[i][0]);
+ tb_descriptors[i].status = TxDESC_STATUS_USED;
+ }
+ /* Set the WRAP bit at the end of the list descriptor. */
+ tb_descriptors[TB_BUFFER_SIZE-1].status |= TxDESC_STATUS_WRAP;
+ /* Set Tx Queue pointer to descriptor list. */
+ AT91C_BASE_EMAC->EMAC_TBQP = (unsigned int)&(tb_descriptors[0]);
+}
+
+/* RT-Thread Device Interface */
+
+/* initialize the interface */
+rt_err_t sam7xether_init(rt_device_t dev)
+{
+ /* enable peripheral clock for EMAC and PIO B */
+ AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_PIOB | 1 << AT91C_ID_EMAC;
+
+ /* Disable pull up on RXDV => PHY normal mode (not in test mode), */
+ /* and set MII mode. PHY has internal pull down. */
+ AT91C_BASE_PIOB->PIO_PPUDR = (1<<16) | (1 << 15);
+
+ /* Clear PB18 <=> PHY powerdown */
+ AT91C_BASE_PIOB->PIO_PER = 1<<18;
+ AT91C_BASE_PIOB->PIO_OER = 1<<18;
+ AT91C_BASE_PIOB->PIO_CODR = 1<<18;
+
+ /* EMAC IO init for EMAC-PHY communication. */
+ AT91C_BASE_PIOB->PIO_ASR = EMAC_PIO_CFG;
+ AT91C_BASE_PIOB->PIO_PDR = EMAC_PIO_CFG; // Set in Periph mode
+
+ /* Enable communication between EMAC-PHY. */
+ AT91C_BASE_EMAC->EMAC_NCR |= AT91C_EMAC_MPE;
+ /* MDC = MCK/32 */
+ AT91C_BASE_EMAC->EMAC_NCFGR |= 2<<10;
+
+ /* Reset PHY */
+ AT91C_BASE_PIOB->PIO_PPUDR = AT91C_PB7_ERXER;
+
+ AT91C_BASE_RSTC->RSTC_RMR = 0xA5000000 | (0x08 << 8) ;
+ AT91C_BASE_RSTC->RSTC_RCR = 0xA5000000 | AT91C_RSTC_EXTRST;
+ while(!(AT91C_BASE_RSTC->RSTC_RSR & AT91C_RSTC_NRSTL));
+
+ linksetup();
+
+ /* Disable management port in MAC control register. */
+ AT91C_BASE_EMAC->EMAC_NCR &= ~AT91C_EMAC_MPE;
+
+ /* Enable EMAC in MII mode, enable clock ERXCK and ETXCK */
+ AT91C_BASE_EMAC->EMAC_USRIO= AT91C_EMAC_CLKEN;
+
+ /* Transmit and Receive disable. */
+ AT91C_BASE_EMAC->EMAC_NCR &= ~(AT91C_EMAC_RE | AT91C_EMAC_TE);
+
+ /* init descriptor */
+ sam7xether_desc_init();
+
+ /* Clear receive and transmit status registers. */
+ AT91C_BASE_EMAC->EMAC_RSR = (AT91C_EMAC_OVR | AT91C_EMAC_REC | AT91C_EMAC_BNA);
+ AT91C_BASE_EMAC->EMAC_TSR = (AT91C_EMAC_UND | AT91C_EMAC_COMP| AT91C_EMAC_BEX |
+ AT91C_EMAC_RLES| AT91C_EMAC_COL | AT91C_EMAC_UBR);
+
+ /* Configure EMAC operation mode. */
+ AT91C_BASE_EMAC->EMAC_NCFGR |= (AT91C_EMAC_BIG | AT91C_EMAC_DRFCS);
+ AT91C_BASE_EMAC->EMAC_NCR |= (AT91C_EMAC_TE | AT91C_EMAC_RE | AT91C_EMAC_WESTAT);
+
+ /* update MAC address */
+ update_mac_address(sam7x_dev);
+
+ /* enable interrupt */
+ AT91C_BASE_EMAC->EMAC_IER = AT91C_EMAC_RCOMP | AT91C_EMAC_TCOMP;
+
+ /* setup interrupt */
+ rt_hw_interrupt_install(AT91C_ID_EMAC, sam7xether_isr, RT_NULL);
+ *(volatile unsigned int*)(0xFFFFF000 + AT91C_ID_EMAC * 4) = AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL | 5;
+ // AT91C_AIC_SMR(AT91C_ID_EMAC) = AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL | 5;
+ rt_hw_interrupt_umask(AT91C_ID_EMAC);
+
+ return RT_EOK;
+}
+
+/* control the interface */
+rt_err_t sam7xether_control(rt_device_t dev, rt_uint8_t cmd, void *args)
+{
+ switch(cmd)
+ {
+ case NIOCTL_GADDR:
+ /* get mac address */
+ if(args) rt_memcpy(args, sam7x_dev_entry.dev_addr, 6);
+ else return -RT_ERROR;
+ break;
+
+ default :
+ break;
+ }
+
+ return RT_EOK;
+}
+
+/* Open the ethernet interface */
+rt_err_t sam7xether_open(rt_device_t dev, rt_uint16_t oflags)
+{
+ return RT_EOK;
+}
+
+/* Close the interface */
+rt_err_t sam7xether_close(rt_device_t dev)
+{
+ return RT_EOK;
+}
+
+/* Read */
+rt_size_t sam7xether_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
+{
+ rt_set_errno(-RT_ENOSYS);
+ return 0;
+}
+
+/* Write */
+rt_size_t sam7xether_write(rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
+{
+ rt_set_errno(-RT_ENOSYS);
+ return 0;
+}
+
+/* See the header file for descriptions of public functions. */
+void sam7xether_write_frame(rt_uint8_t *ptr, rt_uint32_t length, rt_bool_t eof)
+{
+ rt_uint8_t *buf_ptr;
+ static rt_uint32_t current_tb_index = 0;
+ rt_uint32_t is_last, tx_offset = 0, remain, pdu_length;
+
+ while(tx_offset < length)
+ {
+ /* check whether buffer is available */
+ while(!(tb_descriptors[current_tb_index].status & TxDESC_STATUS_USED))
+ {
+ /* no buffer */
+ rt_thread_delay(5);
+ }
+
+ /* Get the address of the buffer from the descriptor, then copy
+ the data into the buffer. */
+ buf_ptr = (rt_uint8_t *)tb_descriptors[current_tb_index].addr;
+
+ /* How much can we write to the buffer? */
+ remain = length - tx_offset;
+ pdu_length = (remain <= ETH_TX_BUF_SIZE)? remain : ETH_TX_BUF_SIZE;
+
+ /* Copy the data into the buffer. */
+ rt_memcpy(buf_ptr, &ptr[tx_offset], pdu_length );
+ tx_offset += pdu_length;
+
+ /* Is this the last data for the frame? */
+ if((eof == RT_TRUE) && ( tx_offset >= length )) is_last = TxDESC_STATUS_LAST_BUF;
+ else is_last = 0;
+
+ /* Fill out the necessary in the descriptor to get the data sent,
+ then move to the next descriptor, wrapping if necessary. */
+ if(current_tb_index >= (TB_BUFFER_SIZE - 1))
+ {
+ tb_descriptors[current_tb_index].status = ( pdu_length & TxDESC_STATUS_BUF_SIZE )
+ | is_last
+ | TxDESC_STATUS_WRAP;
+ current_tb_index = 0;
+ }
+ else
+ {
+ tb_descriptors[current_tb_index].status = ( pdu_length & TxDESC_STATUS_BUF_SIZE )
+ | is_last;
+ current_tb_index++;
+ }
+
+ /* If this is the last buffer to be sent for this frame we can
+ start the transmission. */
+ if(is_last)
+ {
+ AT91C_BASE_EMAC->EMAC_NCR |= AT91C_EMAC_TSTART;
+ }
+ }
+}
+
+/* ethernet device interface */
+/*
+ * Transmit packet.
+ */
+rt_err_t sam7xether_tx( rt_device_t dev, struct pbuf* p)
+{
+ struct pbuf* q;
+
+ /* lock tx operation */
+ rt_sem_take(&tx_sem, RT_WAITING_FOREVER);
+
+ for (q = p; q != NULL; q = q->next)
+ {
+ if (q->next == RT_NULL) sam7xether_write_frame(q->payload, q->len, RT_TRUE);
+ else sam7xether_write_frame(q->payload, q->len, RT_FALSE);
+ }
+
+ rt_sem_release(&tx_sem);
+
+ return 0;
+}
+
+void sam7xether_read_frame(rt_uint8_t* ptr, rt_uint32_t section_length, rt_uint32_t total)
+{
+ static rt_uint8_t* src_ptr;
+ register rt_uint32_t buf_remain, section_remain;
+ static rt_uint32_t section_read = 0, buf_offset = 0, frame_read = 0;
+
+ if(ptr == RT_NULL)
+ {
+ /* Reset our state variables ready for the next read from this buffer. */
+ src_ptr = (rt_uint8_t *)(rb_descriptors[current_rb_index].addr & RxDESC_FLAG_ADDR_MASK);
+ frame_read = (rt_uint32_t)0;
+ buf_offset = (rt_uint32_t)0;
+ }
+ else
+ {
+ /* Loop until we have obtained the required amount of data. */
+ section_read = 0;
+ while( section_read < section_length )
+ {
+ buf_remain = (ETH_RX_BUF_SIZE - buf_offset);
+ section_remain = section_length - section_read;
+
+ if( section_remain > buf_remain )
+ {
+ /* more data on section than buffer size */
+ rt_memcpy(&ptr[ section_read ], &src_ptr[buf_offset], buf_remain);
+ section_read += buf_remain;
+ frame_read += buf_remain;
+
+ /* free buffer */
+ rb_descriptors[current_rb_index].addr &= ~RxDESC_FLAG_OWNSHIP;
+
+ /* move to the next frame. */
+ current_rb_index++;
+ if(current_rb_index >= RB_BUFFER_SIZE) current_rb_index = 0;
+
+ /* Reset the variables for the new buffer. */
+ src_ptr = (rt_uint8_t *)(rb_descriptors[current_rb_index].addr & RxDESC_FLAG_ADDR_MASK);
+ buf_offset = 0;
+ }
+ else
+ {
+ /* more data on buffer than section size */
+ rt_memcpy(&ptr[section_read], &src_ptr[buf_offset], section_remain);
+ buf_offset += section_remain;
+ section_read += section_remain;
+ frame_read += section_remain;
+
+ /* finish this read */
+ if((buf_offset >= ETH_RX_BUF_SIZE) || (frame_read >= total))
+ {
+ /* free buffer */
+ rb_descriptors[current_rb_index].addr &= ~(RxDESC_FLAG_OWNSHIP);
+
+ /* move to the next frame. */
+ current_rb_index++;
+ if( current_rb_index >= RB_BUFFER_SIZE ) current_rb_index = 0;
+
+ src_ptr = (rt_uint8_t*)(rb_descriptors[current_rb_index].addr & RxDESC_FLAG_ADDR_MASK);
+ buf_offset = 0;
+ }
+ }
+ }
+ }
+}
+
+struct pbuf *sam7xether_rx(rt_device_t dev)
+{
+ struct pbuf *p = RT_NULL;
+
+ /* skip fragment frame */
+ while((rb_descriptors[current_rb_index].addr & RxDESC_FLAG_OWNSHIP)
+ && !(rb_descriptors[current_rb_index].status & RxDESC_STATUS_FRAME_START))
+ {
+ rb_descriptors[current_rb_index].addr &= (~RxDESC_FLAG_OWNSHIP);
+
+ current_rb_index++;
+ if(current_rb_index >= RB_BUFFER_SIZE) current_rb_index = 0;
+ }
+
+ if ((rb_descriptors[current_rb_index].addr & RxDESC_FLAG_OWNSHIP))
+ {
+ struct pbuf* q;
+ rt_uint32_t index, pkt_len = 0;
+
+ /* first of all, find the frame length */
+ index = current_rb_index;
+ while (rb_descriptors[index].addr & RxDESC_FLAG_OWNSHIP)
+ {
+ pkt_len = rb_descriptors[index].status & RxDESC_STATUS_BUF_SIZE;
+ if (pkt_len > 0) break;
+
+ index ++;
+ if (index > RB_BUFFER_SIZE) index = 0;
+ }
+
+ if (pkt_len)
+ {
+ p = pbuf_alloc(PBUF_LINK, pkt_len, PBUF_RAM);
+ if(p != RT_NULL)
+ {
+ sam7xether_read_frame(RT_NULL, 0, pkt_len);
+ for(q = p; q != RT_NULL; q= q->next)
+ sam7xether_read_frame(q->payload, q->len, pkt_len);
+ }
+ else
+ {
+ rt_kprintf("no memory in pbuf\n");
+ }
+ }
+ }
+
+ /* enable interrupt */
+ AT91C_BASE_EMAC->EMAC_IER = AT91C_EMAC_RCOMP;
+
+ return p;
+}
+
+int sam7xether_register(char *name)
+{
+ rt_err_t result;
+
+ /* init rt-thread device interface */
+ sam7x_dev_entry.parent.parent.init = sam7xether_init;
+ sam7x_dev_entry.parent.parent.open = sam7xether_open;
+ sam7x_dev_entry.parent.parent.close = sam7xether_close;
+ sam7x_dev_entry.parent.parent.read = sam7xether_read;
+ sam7x_dev_entry.parent.parent.write = sam7xether_write;
+ sam7x_dev_entry.parent.parent.control = sam7xether_control;
+ sam7x_dev_entry.parent.eth_rx = sam7xether_rx;
+ sam7x_dev_entry.parent.eth_tx = sam7xether_tx;
+
+ /* Update MAC address */
+ sam7x_dev_entry.dev_addr[0] = 0x1e;
+ sam7x_dev_entry.dev_addr[1] = 0x30;
+ sam7x_dev_entry.dev_addr[2] = 0x6c;
+ sam7x_dev_entry.dev_addr[3] = 0xa2;
+ sam7x_dev_entry.dev_addr[4] = 0x45;
+ sam7x_dev_entry.dev_addr[5] = 0x5e;
+ /* update mac address */
+ update_mac_address(sam7x_dev);
+
+ rt_sem_init(&tx_sem, "emac", 1, RT_IPC_FLAG_FIFO);
+
+ result = eth_device_init(&(sam7x_dev->parent), (char*)name);
+ RT_ASSERT(result == RT_EOK);
+
+ return RT_EOK;
+}
diff --git a/libcpu/arm/AT91SAM7X/sam7x_emac.h b/libcpu/arm/AT91SAM7X/sam7x_emac.h
new file mode 100644
index 0000000000..49d156f94b
--- /dev/null
+++ b/libcpu/arm/AT91SAM7X/sam7x_emac.h
@@ -0,0 +1,64 @@
+#ifndef __SAM7X_EMAC_H__
+#define __SAM7X_EMAC_H__
+
+#define AT91C_PHY_ADDR 0x01
+#define MII_RTL8201_ID 0x82010000
+
+/* RTL8201 PHY registers. */
+#define PHY_REG_BMCR 0x00 /* Basic mode control register */
+#define PHY_REG_BMSR 0x01 /* Basic mode status register */
+#define PHY_REG_PHYID1 0x02 /* PHY ID identifier #1 */
+#define PHY_REG_PHYID2 0x03 /* PHY ID identifier #2 */
+#define PHY_REG_ANAR 0x04 /* AutoNegotiation Advertisement reg.*/
+#define PHY_REG_ANLPAR 0x05 /* AutoNeg.Link partner ability reg */
+#define PHY_REG_ANER 0x06 /* AutoNeg. Expansion register */
+#define PHY_REG_DSCR 0x10 /* DAVICOM Specified Config. reg */
+#define PHY_REG_DSCSR 0x11 /* DAVICOM Spec. Config/Status reg */
+#define PHY_REG_10BTCSR 0x12 /* 10BASET Configuration/Status reg */
+#define PHY_REG_PWDOR 0x13 /* Power Down Control Register */
+#define PHY_REG_SCR 0x14 /* Specified Config register */
+#define PHY_REG_INTR 0x15 /* Interrupt register */
+#define PHY_REG_RECR 0x16 /* Receive Error Counter register */
+#define PHY_REG_DISCR 0x17 /* Disconnect Counter register */
+#define PHY_REG_RLSR 0x18 /* Hardware Reset Latch State reg. */
+
+#define PHY_FULLD_100M 0x2100 /* Full Duplex 100Mbit */
+#define PHY_HALFD_100M 0x2000 /* Half Duplex 100Mbit */
+#define PHY_FULLD_10M 0x0100 /* Full Duplex 10Mbit */
+#define PHY_HALFD_10M 0x0000 /* Half Duplex 10MBit */
+#define PHY_AUTO_NEG 0x3000 /* Select Auto Negotiation */
+
+/* Basic mode status register. */
+#define BMSR_ERCAP 0x0001 /* Ext-reg capability */
+#define BMSR_JCD 0x0002 /* Jabber detected */
+#define BMSR_LINKST 0x0004 /* Link status */
+#define BMSR_ANEGCAPABLE 0x0008 /* Able to do auto-negotiation */
+#define BMSR_RFAULT 0x0010 /* Remote fault detected */
+#define BMSR_ANEGCOMPLETE 0x0020 /* Auto-negotiation complete */
+#define BMSR_MIIPRESUP 0x0040 /* MII Frame Preamble Suppression */
+#define BMSR_RESV 0x0780 /* Unused... */
+#define BMSR_10HALF 0x0800 /* Can do 10mbps, half-duplex */
+#define BMSR_10FULL 0x1000 /* Can do 10mbps, full-duplex */
+#define BMSR_100HALF 0x2000 /* Can do 100mbps, half-duplex */
+#define BMSR_100FULL 0x4000 /* Can do 100mbps, full-duplex */
+#define BMSR_100BASE4 0x8000 /* Can do 100mbps, 4k packets */
+
+#define RxDESC_FLAG_ADDR_MASK 0xfffffffc
+#define RxDESC_FLAG_WARP 0x00000002
+#define RxDESC_FLAG_OWNSHIP 0x00000001
+#define RxDESC_STATUS_BUF_SIZE (0x00000FFF)
+#define RxDESC_STATUS_FRAME_START (1U << 14)
+#define RxDESC_STATUS_FRAME_END (1U << 15)
+
+#define TxDESC_STATUS_BUF_SIZE (0x000007FF)
+#define TxDESC_STATUS_LAST_BUF (1U << 15)
+#define TxDESC_STATUS_NO_CRC (1U << 16)
+#define TxDESC_STATUS_BUF_EXHAUSTED (1U << 27)
+#define TxDESC_STATUS_Tx_UNDERRUN (1U << 28)
+#define TxDESC_STATUS_Tx_ERROR (1U << 29)
+#define TxDESC_STATUS_WRAP (1U << 30)
+#define TxDESC_STATUS_USED (1U << 31)
+
+int sam7xether_register(char *name);
+
+#endif
diff --git a/libcpu/arm/AT91SAM7X/serial.c b/libcpu/arm/AT91SAM7X/serial.c
new file mode 100644
index 0000000000..68fcfb392d
--- /dev/null
+++ b/libcpu/arm/AT91SAM7X/serial.c
@@ -0,0 +1,396 @@
+/*
+ * File : serial.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2006-08-23 Bernard first version
+ * 2009-05-14 Bernard add RT-THread device interface
+ */
+
+#include <rthw.h>
+#include <rtthread.h>
+
+#include "AT91SAM7X.h"
+#include "serial.h"
+
+/**
+ * @addtogroup AT91SAM7X256
+ */
+/*@{*/
+typedef volatile rt_uint32_t REG32;
+struct rt_at91serial_hw
+{
+ REG32 US_CR; // Control Register
+ REG32 US_MR; // Mode Register
+ REG32 US_IER; // Interrupt Enable Register
+ REG32 US_IDR; // Interrupt Disable Register
+ REG32 US_IMR; // Interrupt Mask Register
+ REG32 US_CSR; // Channel Status Register
+ REG32 US_RHR; // Receiver Holding Register
+ REG32 US_THR; // Transmitter Holding Register
+ REG32 US_BRGR; // Baud Rate Generator Register
+ REG32 US_RTOR; // Receiver Time-out Register
+ REG32 US_TTGR; // Transmitter Time-guard Register
+ REG32 Reserved0[5]; //
+ REG32 US_FIDI; // FI_DI_Ratio Register
+ REG32 US_NER; // Nb Errors Register
+ REG32 Reserved1[1]; //
+ REG32 US_IF; // IRDA_FILTER Register
+ REG32 Reserved2[44]; //
+ REG32 US_RPR; // Receive Pointer Register
+ REG32 US_RCR; // Receive Counter Register
+ REG32 US_TPR; // Transmit Pointer Register
+ REG32 US_TCR; // Transmit Counter Register
+ REG32 US_RNPR; // Receive Next Pointer Register
+ REG32 US_RNCR; // Receive Next Counter Register
+ REG32 US_TNPR; // Transmit Next Pointer Register
+ REG32 US_TNCR; // Transmit Next Counter Register
+ REG32 US_PTCR; // PDC Transfer Control Register
+ REG32 US_PTSR; // PDC Transfer Status Register
+};
+
+struct rt_at91serial
+{
+ struct rt_device parent;
+
+ struct rt_at91serial_hw* hw_base;
+ rt_uint16_t peripheral_id;
+ rt_uint32_t baudrate;
+
+ /* reception field */
+ rt_uint16_t save_index, read_index;
+ rt_uint8_t rx_buffer[RT_UART_RX_BUFFER_SIZE];
+};
+#ifdef RT_USING_UART1
+struct rt_at91serial serial1;
+#endif
+#ifdef RT_USING_UART2
+struct rt_at91serial serial2;
+#endif
+
+static void rt_hw_serial_isr(int irqno)
+{
+ rt_base_t level;
+ struct rt_device* device;
+ struct rt_at91serial* serial = RT_NULL;
+
+#ifdef RT_USING_UART1
+ if (irqno == AT91C_ID_US0)
+ {
+ /* serial 1 */
+ serial = &serial1;
+ }
+#endif
+
+#ifdef RT_USING_UART2
+ if (irqno == AT91C_ID_US1)
+ {
+ /* serial 2 */
+ serial = &serial2;
+ }
+#endif
+ RT_ASSERT(serial != RT_NULL);
+
+ /* get generic device object */
+ device = (rt_device_t)serial;
+
+ /* disable interrupt */
+ level = rt_hw_interrupt_disable();
+
+ /* get received character */
+ serial->rx_buffer[serial->save_index] = serial->hw_base->US_RHR;
+
+ /* move to next position */
+ serial->save_index ++;
+ if (serial->save_index >= RT_UART_RX_BUFFER_SIZE)
+ serial->save_index = 0;
+
+ /* if the next position is read index, discard this 'read char' */
+ if (serial->save_index == serial->read_index)
+ {
+ serial->read_index ++;
+ if (serial->read_index >= RT_UART_RX_BUFFER_SIZE)
+ serial->read_index = 0;
+ }
+
+ /* enable interrupt */
+ rt_hw_interrupt_enable(level);
+
+ /* indicate to upper layer application */
+ if (device->rx_indicate != RT_NULL)
+ device->rx_indicate(device, 1);
+
+ /* ack interrupt */
+ AT91C_AIC_EOICR = 1;
+}
+
+static rt_err_t rt_serial_init (rt_device_t dev)
+{
+ rt_uint32_t bd;
+ struct rt_at91serial* serial = (struct rt_at91serial*) dev;
+
+ RT_ASSERT(serial != RT_NULL);
+ /* must be US0 or US1 */
+ RT_ASSERT((serial->peripheral_id != AT91C_ID_US0) &&
+ (serial->peripheral_id != AT91C_ID_US1));
+
+ /* Enable Clock for USART */
+ AT91C_PMC_PCER = 1 << serial->peripheral_id;
+
+ /* Enable RxD0 and TxDO Pin */
+ if (serial->peripheral_id == AT91C_ID_US0)
+ {
+ /* set pinmux */
+ AT91C_PIO_PDR = (1 << 5) | (1 << 6);
+ }
+ else if (serial->peripheral_id == AT91C_ID_US1)
+ {
+ /* set pinmux */
+ AT91C_PIO_PDR = (1 << 21) | (1 << 22);
+ }
+
+ serial->hw_base->US_CR = AT91C_US_RSTRX | /* Reset Receiver */
+ AT91C_US_RSTTX | /* Reset Transmitter */
+ AT91C_US_RXDIS | /* Receiver Disable */
+ AT91C_US_TXDIS; /* Transmitter Disable */
+
+ serial->hw_base->US_MR = AT91C_US_USMODE_NORMAL | /* Normal Mode */
+ AT91C_US_CLKS_CLOCK | /* Clock = MCK */
+ AT91C_US_CHRL_8_BITS | /* 8-bit Data */
+ AT91C_US_PAR_NONE | /* No Parity */
+ AT91C_US_NBSTOP_1_BIT; /* 1 Stop Bit */
+
+ /* set baud rate divisor */
+ bd = ((MCK*10)/(serial->baudrate * 16));
+ if ((bd % 10) >= 5) bd = (bd / 10) + 1;
+ else bd /= 10;
+
+ serial->hw_base->US_BRGR = bd;
+ serial->hw_base->US_CR = AT91C_US_RXEN | /* Receiver Enable */
+ AT91C_US_TXEN; /* Transmitter Enable */
+
+ /* reset rx index */
+ serial->save_index = 0;
+ serial->read_index = 0;
+
+ /* reset rx buffer */
+ rt_memset(serial->rx_buffer, 0, RT_UART_RX_BUFFER_SIZE);
+
+ return RT_EOK;
+}
+
+static rt_err_t rt_serial_open(rt_device_t dev, rt_uint16_t oflag)
+{
+ struct rt_at91serial *serial = (struct rt_at91serial*)dev;
+ RT_ASSERT(serial != RT_NULL);
+
+ if (dev->flag & RT_DEVICE_FLAG_INT_RX)
+ {
+ /* enable UART rx interrupt */
+ serial->hw_base->US_IER = 1 << 0; /* RxReady interrupt */
+ serial->hw_base->US_IMR |= 1 << 0; /* umask RxReady interrupt */
+
+ /* install UART handler */
+ rt_hw_interrupt_install(serial->peripheral_id, rt_hw_serial_isr, RT_NULL);
+ AT91C_AIC_SMR(serial->peripheral_id) = 5 | (0x01 << 5);
+ rt_hw_interrupt_umask(serial->peripheral_id);
+ }
+
+ return RT_EOK;
+}
+
+static rt_err_t rt_serial_close(rt_device_t dev)
+{
+ struct rt_at91serial *serial = (struct rt_at91serial*)dev;
+ RT_ASSERT(serial != RT_NULL);
+
+ if (dev->flag & RT_DEVICE_FLAG_INT_RX)
+ {
+ /* disable interrupt */
+ serial->hw_base->US_IDR = 1 << 0; /* RxReady interrupt */
+ serial->hw_base->US_IMR &= ~(1 << 0); /* mask RxReady interrupt */
+ }
+
+ serial->hw_base->US_CR = AT91C_US_RSTRX | /* Reset Receiver */
+ AT91C_US_RSTTX | /* Reset Transmitter */
+ AT91C_US_RXDIS | /* Receiver Disable */
+ AT91C_US_TXDIS; /* Transmitter Disable */
+
+ return RT_EOK;
+}
+
+static rt_size_t rt_serial_read (rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
+{
+ rt_uint8_t* ptr;
+ struct rt_at91serial *serial = (struct rt_at91serial*)dev;
+ RT_ASSERT(serial != RT_NULL);
+
+ /* point to buffer */
+ ptr = (rt_uint8_t*) buffer;
+
+ if (dev->flag & RT_DEVICE_FLAG_INT_RX)
+ {
+ while (size)
+ {
+ /* interrupt receive */
+ rt_base_t level;
+
+ /* disable interrupt */
+ level = rt_hw_interrupt_disable();
+ if (serial->read_index != serial->save_index)
+ {
+ *ptr = serial->rx_buffer[serial->read_index];
+
+ serial->read_index ++;
+ if (serial->read_index >= RT_UART_RX_BUFFER_SIZE)
+ serial->read_index = 0;
+ }
+ else
+ {
+ /* no data in rx buffer */
+
+ /* enable interrupt */
+ rt_hw_interrupt_enable(level);
+ break;
+ }
+
+ /* enable interrupt */
+ rt_hw_interrupt_enable(level);
+
+ ptr ++;
+ size --;
+ }
+
+ return (rt_uint32_t)ptr - (rt_uint32_t)buffer;
+ }
+ else if (dev->flag & RT_DEVICE_FLAG_DMA_RX)
+ {
+ /* not support right now */
+ RT_ASSERT(0);
+ }
+ else
+ {
+ /* poll mode */
+ while (size)
+ {
+ /* Wait for Full Rx Buffer */
+ while (!(serial->hw_base->US_CSR & AT91C_US_RXRDY));
+
+ /* Read Character */
+ *ptr = serial->hw_base->US_RHR;
+ ptr ++;
+ size --;
+ }
+
+ return (rt_size_t)ptr - (rt_size_t)buffer;
+ }
+
+ return 0;
+}
+
+static rt_size_t rt_serial_write (rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
+{
+ rt_uint8_t* ptr;
+ struct rt_at91serial *serial = (struct rt_at91serial*)dev;
+ RT_ASSERT(serial != RT_NULL);
+
+ ptr = (rt_uint8_t*) buffer;
+ if (dev->open_flag & RT_DEVICE_OFLAG_WRONLY)
+ {
+ if (dev->flag & RT_DEVICE_FLAG_STREAM)
+ {
+ /* it's a stream mode device */
+ while (size)
+ {
+ /* stream mode */
+ if (*ptr == '\n')
+ {
+ while (!(serial->hw_base->US_CSR & AT91C_US_TXRDY));
+ serial->hw_base->US_THR = '\r';
+ }
+
+ /* Wait for Empty Tx Buffer */
+ while (!(serial->hw_base->US_CSR & AT91C_US_TXRDY));
+
+ /* Transmit Character */
+ serial->hw_base->US_THR = *ptr;
+ ptr ++;
+ size --;
+ }
+ }
+ else
+ {
+ while (size)
+ {
+ /* Wait for Empty Tx Buffer */
+ while (!(serial->hw_base->US_CSR & AT91C_US_TXRDY));
+
+ /* Transmit Character */
+ serial->hw_base->US_THR = *ptr;
+ ptr ++;
+ size --;
+ }
+ }
+ }
+
+ return (rt_size_t)ptr - (rt_size_t)buffer;
+}
+
+static rt_err_t rt_serial_control (rt_device_t dev, rt_uint8_t cmd, void *args)
+{
+ return RT_EOK;
+}
+
+rt_err_t rt_hw_serial_init()
+{
+ rt_device_t device;
+
+#ifdef RT_USING_UART1
+ device = (rt_device_t) &serial1;
+
+ /* init serial device private data */
+ serial1.hw_base = (struct rt_at91serial_hw*)AT91C_BASE_US0;
+ serial1.peripheral_id = AT91C_ID_US0;
+ serial1.baudrate = 115200;
+
+ /* set device virtual interface */
+ device->init = rt_serial_init;
+ device->open = rt_serial_open;
+ device->close = rt_serial_close;
+ device->read = rt_serial_read;
+ device->write = rt_serial_write;
+ device->control = rt_serial_control;
+
+ /* register uart1 on device subsystem */
+ rt_device_register(device, "uart1", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX);
+#endif
+
+#ifdef RT_USING_UART2
+ device = (rt_device_t) &serial2;
+
+ serial2.hw_base = (struct rt_at91serial_hw*)AT91C_BASE_US1;
+ serial2.peripheral_id = AT91C_ID_US1;
+ serial2.baudrate = 115200;
+
+ /* set device virtual interface */
+ device->init = rt_serial_init;
+ device->open = rt_serial_open;
+ device->close = rt_serial_close;
+ device->read = rt_serial_read;
+ device->write = rt_serial_write;
+ device->control = rt_serial_control;
+
+ /* register uart2 on device subsystem */
+ rt_device_register(device, "uart2", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX);
+#endif
+
+ return RT_EOK;
+}
+
+/*@}*/
diff --git a/libcpu/arm/AT91SAM7X/serial.h b/libcpu/arm/AT91SAM7X/serial.h
new file mode 100644
index 0000000000..5fe0928c9a
--- /dev/null
+++ b/libcpu/arm/AT91SAM7X/serial.h
@@ -0,0 +1,56 @@
+#ifndef __RT_SERIAL_H__
+#define __RT_SERIAL_H__
+
+#ifndef AT91C_BASE_US0
+#define AT91C_BASE_US0 (0xFFFC0000) // (US0) Base Address
+#endif
+
+#ifndef AT91C_BASE_US1
+#define AT91C_BASE_US1 (0xFFFC4000) // (US1) Base Address
+#endif
+
+#define AT91C_US_RXRDY ((unsigned int) 0x1 << 0) /* US RXRDY Interrupt */
+#define AT91C_US_TXRDY ((unsigned int) 0x1 << 1) /* US TXRDY Interrupt */
+#define AT91C_US_RSTRX ((unsigned int) 0x1 << 2) /* US Reset Receiver */
+#define AT91C_US_RSTTX ((unsigned int) 0x1 << 3) /* US Reset Transmitter */
+#define AT91C_US_RXEN ((unsigned int) 0x1 << 4) /* US Receiver Enable */
+#define AT91C_US_RXDIS ((unsigned int) 0x1 << 5) /* US Receiver Disable */
+#define AT91C_US_TXEN ((unsigned int) 0x1 << 6) /* US Transmitter Enable */
+#define AT91C_US_TXDIS ((unsigned int) 0x1 << 7) /* US Transmitter Disable */
+#define AT91C_US_RSTSTA ((unsigned int) 0x1 << 8) /* US Reset Status Bits */
+
+#define AT91C_US_USMODE_NORMAL ((unsigned int) 0x0) /* USAR) Normal */
+#define AT91C_US_USMODE_RS485 ((unsigned int) 0x1) /* USAR) RS485 */
+#define AT91C_US_USMODE_HWHSH ((unsigned int) 0x2) /* USAR) Hardware Handshaking */
+#define AT91C_US_USMODE_MODEM ((unsigned int) 0x3) /* USAR) Modem */
+#define AT91C_US_USMODE_ISO7816_0 ((unsigned int) 0x4) /* USAR) ISO7816 protocol: T = 0 */
+#define AT91C_US_USMODE_ISO7816_1 ((unsigned int) 0x6) /* USAR) ISO7816 protocol: T = 1 */
+#define AT91C_US_USMODE_IRDA ((unsigned int) 0x8) /* USAR) IrDA */
+#define AT91C_US_USMODE_SWHSH ((unsigned int) 0xC) /* USAR) Software Handshaking */
+
+#define AT91C_US_CLKS_CLOCK ((unsigned int) 0x0 << 4) /* USAR) Clock */
+#define AT91C_US_CLKS_FDIV1 ((unsigned int) 0x1 << 4) /* USAR) fdiv1 */
+#define AT91C_US_CLKS_SLOW ((unsigned int) 0x2 << 4) /* USAR) slow_clock (ARM) */
+#define AT91C_US_CLKS_EXT ((unsigned int) 0x3 << 4) /* USAR) External (SCK) */
+
+#define AT91C_US_CHRL_5_BITS ((unsigned int) 0x0 << 6) /* USAR) Character Length: 5 bits */
+#define AT91C_US_CHRL_6_BITS ((unsigned int) 0x1 << 6) /* USAR) Character Length: 6 bits */
+#define AT91C_US_CHRL_7_BITS ((unsigned int) 0x2 << 6) /* USAR) Character Length: 7 bits */
+#define AT91C_US_CHRL_8_BITS ((unsigned int) 0x3 << 6) /* USAR) Character Length: 8 bits */
+
+#define AT91C_US_PAR_EVEN ((unsigned int) 0x0 << 9) /* DBGU Even Parity */
+#define AT91C_US_PAR_ODD ((unsigned int) 0x1 << 9) /* DBGU Odd Parity */
+#define AT91C_US_PAR_SPACE ((unsigned int) 0x2 << 9) /* DBGU Parity forced to 0 (Space) */
+#define AT91C_US_PAR_MARK ((unsigned int) 0x3 << 9) /* DBGU Parity forced to 1 (Mark) */
+#define AT91C_US_PAR_NONE ((unsigned int) 0x4 << 9) /* DBGU No Parity */
+#define AT91C_US_PAR_MULTI_DROP ((unsigned int) 0x6 << 9) /* DBGU Multi-drop mode */
+
+#define AT91C_US_NBSTOP_1_BIT ((unsigned int) 0x0 << 12) /* USART 1 stop bit */
+#define AT91C_US_NBSTOP_15_BIT ((unsigned int) 0x1 << 12) /* USART Asynchronous (SYNC=0) 2 stop bits Synchronous (SYNC=1) 2 stop bits */
+#define AT91C_US_NBSTOP_2_BIT ((unsigned int) 0x2 << 12) /* USART 2 stop bits */
+
+#define MCK 48054857
+#define BR 115200 /* Baud Rate */
+#define BRD (MCK/16/BR) /* Baud Rate Divisor */
+
+#endif
diff --git a/libcpu/arm/AT91SAM7X/stack.c b/libcpu/arm/AT91SAM7X/stack.c
new file mode 100644
index 0000000000..4f3b2c3976
--- /dev/null
+++ b/libcpu/arm/AT91SAM7X/stack.c
@@ -0,0 +1,60 @@
+/*
+ * File : stack.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2006-08-23 Bernard the first version
+ */
+#include <rtthread.h>
+#include "AT91SAM7X.h"
+
+/**
+ * @addtogroup AT91SAM7
+ */
+/*@{*/
+
+/**
+ * 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 */
+ *(--stk) = SVCMODE; /* cpsr */
+ *(--stk) = SVCMODE; /* spsr */
+
+ /* return task's current stack address */
+ return (rt_uint8_t *)stk;
+}
+
+/*@}*/
diff --git a/libcpu/arm/AT91SAM7X/start_gcc.S b/libcpu/arm/AT91SAM7X/start_gcc.S
new file mode 100644
index 0000000000..e7712eb436
--- /dev/null
+++ b/libcpu/arm/AT91SAM7X/start_gcc.S
@@ -0,0 +1,235 @@
+/*
+ * File : start.S
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2006-08-31 Bernard first version
+ */
+
+ /* Internal Memory Base Addresses */
+ .equ FLASH_BASE, 0x00100000
+ .equ RAM_BASE, 0x00200000
+
+ /* Stack Configuration */
+ .equ TOP_STACK, 0x00204000
+ .equ UND_STACK_SIZE, 0x00000100
+ .equ SVC_STACK_SIZE, 0x00000400
+ .equ ABT_STACK_SIZE, 0x00000100
+ .equ FIQ_STACK_SIZE, 0x00000100
+ .equ IRQ_STACK_SIZE, 0x00000100
+ .equ USR_STACK_SIZE, 0x00000004
+
+ /* ARM architecture definitions */
+ .equ MODE_USR, 0x10
+ .equ MODE_FIQ, 0x11
+ .equ MODE_IRQ, 0x12
+ .equ MODE_SVC, 0x13
+ .equ MODE_ABT, 0x17
+ .equ MODE_UND, 0x1B
+ .equ MODE_SYS, 0x1F
+
+ .equ I_BIT, 0x80 /* when this bit is set, IRQ is disabled */
+ .equ F_BIT, 0x40 /* when this bit is set, FIQ is disabled */
+
+.section .init, "ax"
+.code 32
+.align 0
+.globl _start
+_start:
+ b reset
+ ldr pc, _vector_undef
+ ldr pc, _vector_swi
+ ldr pc, _vector_pabt
+ ldr pc, _vector_dabt
+ nop /* reserved vector */
+ ldr pc, _vector_irq
+ ldr pc, _vector_fiq
+
+_vector_undef: .word vector_undef
+_vector_swi: .word vector_swi
+_vector_pabt: .word vector_pabt
+_vector_dabt: .word vector_dabt
+_vector_resv: .word vector_resv
+_vector_irq: .word vector_irq
+_vector_fiq: .word vector_fiq
+
+/*
+ * rtthread bss start and end
+ * which are defined in linker script
+ */
+.globl _bss_start
+_bss_start: .word __bss_start
+.globl _bss_end
+_bss_end: .word __bss_end
+
+/* the system entry */
+reset:
+ /* disable watchdog */
+ ldr r0, =0xFFFFFD40
+ ldr r1, =0x00008000
+ str r1, [r0, #0x04]
+
+ /* enable the main oscillator */
+ ldr r0, =0xFFFFFC00
+ ldr r1, =0x00000601
+ str r1, [r0, #0x20]
+
+ /* wait for main oscillator to stabilize */
+moscs_loop:
+ ldr r2, [r0, #0x68]
+ ands r2, r2, #1
+ beq moscs_loop
+
+ /* set up the PLL */
+ ldr r1, =0x00191C05
+ str r1, [r0, #0x2C]
+
+ /* wait for PLL to lock */
+pll_loop:
+ ldr r2, [r0, #0x68]
+ ands r2, r2, #0x04
+ beq pll_loop
+
+ /* select clock */
+ ldr r1, =0x00000007
+ str r1, [r0, #0x30]
+
+#ifdef __FLASH_BUILD__
+ /* copy exception vectors into internal sram */
+ mov r8, #RAM_BASE
+ ldr r9, =_start
+ ldmia r9!, {r0-r7}
+ stmia r8!, {r0-r7}
+ ldmia r9!, {r0-r6}
+ stmia r8!, {r0-r6}
+#endif
+
+ /* setup stack for each mode */
+ ldr r0, =TOP_STACK
+
+ /* set stack */
+ /* undefined instruction mode */
+ msr cpsr_c, #MODE_UND|I_BIT|F_BIT
+ mov sp, r0
+ sub r0, r0, #UND_STACK_SIZE
+
+ /* abort mode */
+ msr cpsr_c, #MODE_ABT|I_BIT|F_BIT
+ mov sp, r0
+ sub r0, r0, #ABT_STACK_SIZE
+
+ /* FIQ mode */
+ msr cpsr_c, #MODE_FIQ|I_BIT|F_BIT
+ mov sp, r0
+ sub r0, r0, #FIQ_STACK_SIZE
+
+ /* IRQ mode */
+ msr cpsr_c, #MODE_IRQ|I_BIT|F_BIT
+ mov sp, r0
+ sub r0, r0, #IRQ_STACK_SIZE
+
+ /* supervisor mode */
+ msr cpsr_c, #MODE_SVC
+ mov sp, r0
+
+ /* remap SRAM to 0x0000 */
+ ldr r0, =0xFFFFFF00
+ mov r1, #0x01
+ str r1, [r0]
+
+ /* mask all IRQs */
+ ldr r1, =0xFFFFF124
+ ldr r0, =0XFFFFFFFF
+ str r0, [r1]
+
+ /* start RT-Thread Kernel */
+ ldr pc, _rtthread_startup
+
+_rtthread_startup: .word rtthread_startup
+
+/* exception handlers */
+vector_undef: b vector_undef
+vector_swi : b vector_swi
+vector_pabt : b vector_pabt
+vector_dabt : b vector_dabt
+vector_resv : b vector_resv
+
+.globl rt_interrupt_enter
+.globl rt_interrupt_leave
+.globl rt_thread_switch_interrput_flag
+.globl rt_interrupt_from_thread
+.globl rt_interrupt_to_thread
+vector_irq:
+ stmfd sp!, {r0-r12,lr}
+ bl rt_interrupt_enter
+ bl rt_hw_trap_irq
+ bl rt_interrupt_leave
+
+ /*
+ * if rt_thread_switch_interrput_flag set, jump to
+ * rt_hw_context_switch_interrupt_do and don't return
+ */
+ ldr r0, =rt_thread_switch_interrput_flag
+ ldr r1, [r0]
+ cmp r1, #1
+ beq rt_hw_context_switch_interrupt_do
+
+ ldmfd sp!, {r0-r12,lr}
+ subs pc, lr, #4
+
+vector_fiq:
+ stmfd sp!,{r0-r7,lr}
+ bl rt_hw_trap_fiq
+ ldmfd sp!,{r0-r7,lr}
+ subs pc,lr,#4
+
+/*
+ * 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
+ mov r1, sp
+ add sp, sp, #16 @ restore sp
+ sub r2, lr, #4 @ save old task's pc to r2
+
+ mrs r3, spsr @ disable interrupt
+ orr r0, r3, #I_BIT|F_BIT
+ msr spsr_c, r0
+
+ ldr r0, =.+8 @ switch to interrupted task's stack
+ movs pc, r0
+
+ 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 psr
+ mrs r4, spsr
+ stmfd sp!, {r4} @ push old task's spsr
+
+ 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 spsr
+ msr SPSR_cxsf, r4
+ ldmfd sp!, {r4} @ pop new task's psr
+ msr CPSR_cxsf, r4
+
+ ldmfd sp!, {r0-r12,lr,pc} @ pop new task's r0-r12,lr & pc
diff --git a/libcpu/arm/AT91SAM7X/start_rvds.S b/libcpu/arm/AT91SAM7X/start_rvds.S
new file mode 100644
index 0000000000..c0f960d2fc
--- /dev/null
+++ b/libcpu/arm/AT91SAM7X/start_rvds.S
@@ -0,0 +1,498 @@
+;/*****************************************************************************/
+;/* SAM7.S: Startup file for Atmel AT91SAM7 device series */
+;/*****************************************************************************/
+;/* <<< Use Configuration Wizard in Context Menu >>> */
+;/*****************************************************************************/
+;/* This file is part of the uVision/ARM development tools. */
+;/* Copyright (c) 2005-2006 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 SAM7.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 remaps exception vectors from
+; * on-chip RAM to address 0.
+; *
+; * RAM_INTVEC: when set the startup code copies exception vectors
+; * from on-chip Flash to on-chip RAM.
+; */
+
+
+; 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
+
+
+; Internal Memory Base Addresses
+FLASH_BASE EQU 0x00100000
+RAM_BASE EQU 0x00200000
+
+
+;// <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
+
+
+; Reset Controller (RSTC) definitions
+RSTC_BASE EQU 0xFFFFFD00 ; RSTC Base Address
+RSTC_MR EQU 0x08 ; RSTC_MR Offset
+
+;/*
+;// <e> Reset Controller (RSTC)
+;// <o1.0> URSTEN: User Reset Enable
+;// <i> Enables NRST Pin to generate Reset
+;// <o1.8..11> ERSTL: External Reset Length <0-15>
+;// <i> External Reset Time in 2^(ERSTL+1) Slow Clock Cycles
+;// </e>
+;*/
+RSTC_SETUP EQU 1
+RSTC_MR_Val EQU 0xA5000401
+
+
+; Embedded Flash Controller (EFC) definitions
+EFC_BASE EQU 0xFFFFFF00 ; EFC Base Address
+EFC0_FMR EQU 0x60 ; EFC0_FMR Offset
+EFC1_FMR EQU 0x70 ; EFC1_FMR Offset
+
+;// <e> Embedded Flash Controller 0 (EFC0)
+;// <o1.16..23> FMCN: Flash Microsecond Cycle Number <0-255>
+;// <i> Number of Master Clock Cycles in 1us
+;// <o1.8..9> FWS: Flash Wait State
+;// <0=> Read: 1 cycle / Write: 2 cycles
+;// <1=> Read: 2 cycle / Write: 3 cycles
+;// <2=> Read: 3 cycle / Write: 4 cycles
+;// <3=> Read: 4 cycle / Write: 4 cycles
+;// </e>
+EFC0_SETUP EQU 1
+EFC0_FMR_Val EQU 0x00320100
+
+;// <e> Embedded Flash Controller 1 (EFC1)
+;// <o1.16..23> FMCN: Flash Microsecond Cycle Number <0-255>
+;// <i> Number of Master Clock Cycles in 1us
+;// <o1.8..9> FWS: Flash Wait State
+;// <0=> Read: 1 cycle / Write: 2 cycles
+;// <1=> Read: 2 cycle / Write: 3 cycles
+;// <2=> Read: 3 cycle / Write: 4 cycles
+;// <3=> Read: 4 cycle / Write: 4 cycles
+;// </e>
+EFC1_SETUP EQU 0
+EFC1_FMR_Val EQU 0x00320100
+
+
+; Watchdog Timer (WDT) definitions
+WDT_BASE EQU 0xFFFFFD40 ; WDT Base Address
+WDT_MR EQU 0x04 ; WDT_MR Offset
+
+;// <e> Watchdog Timer (WDT)
+;// <o1.0..11> WDV: Watchdog Counter Value <0-4095>
+;// <o1.16..27> WDD: Watchdog Delta Value <0-4095>
+;// <o1.12> WDFIEN: Watchdog Fault Interrupt Enable
+;// <o1.13> WDRSTEN: Watchdog Reset Enable
+;// <o1.14> WDRPROC: Watchdog Reset Processor
+;// <o1.28> WDDBGHLT: Watchdog Debug Halt
+;// <o1.29> WDIDLEHLT: Watchdog Idle Halt
+;// <o1.15> WDDIS: Watchdog Disable
+;// </e>
+WDT_SETUP EQU 1
+WDT_MR_Val EQU 0x00008000
+
+
+; Power Mangement Controller (PMC) definitions
+PMC_BASE EQU 0xFFFFFC00 ; PMC Base Address
+PMC_MOR EQU 0x20 ; PMC_MOR Offset
+PMC_MCFR EQU 0x24 ; PMC_MCFR Offset
+PMC_PLLR EQU 0x2C ; PMC_PLLR Offset
+PMC_MCKR EQU 0x30 ; PMC_MCKR Offset
+PMC_SR EQU 0x68 ; PMC_SR Offset
+PMC_MOSCEN EQU (1<<0) ; Main Oscillator Enable
+PMC_OSCBYPASS EQU (1<<1) ; Main Oscillator Bypass
+PMC_OSCOUNT EQU (0xFF<<8) ; Main OScillator Start-up Time
+PMC_DIV EQU (0xFF<<0) ; PLL Divider
+PMC_PLLCOUNT EQU (0x3F<<8) ; PLL Lock Counter
+PMC_OUT EQU (0x03<<14) ; PLL Clock Frequency Range
+PMC_MUL EQU (0x7FF<<16) ; PLL Multiplier
+PMC_USBDIV EQU (0x03<<28) ; USB Clock Divider
+PMC_CSS EQU (3<<0) ; Clock Source Selection
+PMC_PRES EQU (7<<2) ; Prescaler Selection
+PMC_MOSCS EQU (1<<0) ; Main Oscillator Stable
+PMC_LOCK EQU (1<<2) ; PLL Lock Status
+PMC_MCKRDY EQU (1<<3) ; Master Clock Status
+
+;// <e> Power Mangement Controller (PMC)
+;// <h> Main Oscillator
+;// <o1.0> MOSCEN: Main Oscillator Enable
+;// <o1.1> OSCBYPASS: Oscillator Bypass
+;// <o1.8..15> OSCCOUNT: Main Oscillator Startup Time <0-255>
+;// </h>
+;// <h> Phase Locked Loop (PLL)
+;// <o2.0..7> DIV: PLL Divider <0-255>
+;// <o2.16..26> MUL: PLL Multiplier <0-2047>
+;// <i> PLL Output is multiplied by MUL+1
+;// <o2.14..15> OUT: PLL Clock Frequency Range
+;// <0=> 80..160MHz <1=> Reserved
+;// <2=> 150..220MHz <3=> Reserved
+;// <o2.8..13> PLLCOUNT: PLL Lock Counter <0-63>
+;// <o2.28..29> USBDIV: USB Clock Divider
+;// <0=> None <1=> 2 <2=> 4 <3=> Reserved
+;// </h>
+;// <o3.0..1> CSS: Clock Source Selection
+;// <0=> Slow Clock
+;// <1=> Main Clock
+;// <2=> Reserved
+;// <3=> PLL Clock
+;// <o3.2..4> PRES: Prescaler
+;// <0=> None
+;// <1=> Clock / 2 <2=> Clock / 4
+;// <3=> Clock / 8 <4=> Clock / 16
+;// <5=> Clock / 32 <6=> Clock / 64
+;// <7=> Reserved
+;// </e>
+PMC_SETUP EQU 1
+PMC_MOR_Val EQU 0x00000601
+PMC_PLLR_Val EQU 0x00191C05
+PMC_MCKR_Val EQU 0x00000007
+
+
+ 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 RSTC
+ IF RSTC_SETUP != 0
+ LDR R0, =RSTC_BASE
+ LDR R1, =RSTC_MR_Val
+ STR R1, [R0, #RSTC_MR]
+ ENDIF
+
+
+; Setup EFC0
+ IF EFC0_SETUP != 0
+ LDR R0, =EFC_BASE
+ LDR R1, =EFC0_FMR_Val
+ STR R1, [R0, #EFC0_FMR]
+ ENDIF
+
+; Setup EFC1
+ IF EFC1_SETUP != 0
+ LDR R0, =EFC_BASE
+ LDR R1, =EFC1_FMR_Val
+ STR R1, [R0, #EFC1_FMR]
+ ENDIF
+
+; Setup WDT
+ IF WDT_SETUP != 0
+ LDR R0, =WDT_BASE
+ LDR R1, =WDT_MR_Val
+ STR R1, [R0, #WDT_MR]
+ ENDIF
+
+
+; Setup PMC
+ IF PMC_SETUP != 0
+ LDR R0, =PMC_BASE
+
+; Setup Main Oscillator
+ LDR R1, =PMC_MOR_Val
+ STR R1, [R0, #PMC_MOR]
+
+; Wait until Main Oscillator is stablilized
+ IF (PMC_MOR_Val:AND:PMC_MOSCEN) != 0
+MOSCS_Loop LDR R2, [R0, #PMC_SR]
+ ANDS R2, R2, #PMC_MOSCS
+ BEQ MOSCS_Loop
+ ENDIF
+
+; Setup the PLL
+ IF (PMC_PLLR_Val:AND:PMC_MUL) != 0
+ LDR R1, =PMC_PLLR_Val
+ STR R1, [R0, #PMC_PLLR]
+
+; Wait until PLL is stabilized
+PLL_Loop LDR R2, [R0, #PMC_SR]
+ ANDS R2, R2, #PMC_LOCK
+ BEQ PLL_Loop
+ ENDIF
+
+; Select Clock
+ IF (PMC_MCKR_Val:AND:PMC_CSS) == 1 ; Main Clock Selected
+ LDR R1, =PMC_MCKR_Val
+ AND R1, #PMC_CSS
+ STR R1, [R0, #PMC_MCKR]
+WAIT_Rdy1 LDR R2, [R0, #PMC_SR]
+ ANDS R2, R2, #PMC_MCKRDY
+ BEQ WAIT_Rdy1
+ LDR R1, =PMC_MCKR_Val
+ STR R1, [R0, #PMC_MCKR]
+WAIT_Rdy2 LDR R2, [R0, #PMC_SR]
+ ANDS R2, R2, #PMC_MCKRDY
+ BEQ WAIT_Rdy2
+ ELIF (PMC_MCKR_Val:AND:PMC_CSS) == 3 ; PLL Clock Selected
+ LDR R1, =PMC_MCKR_Val
+ AND R1, #PMC_PRES
+ STR R1, [R0, #PMC_MCKR]
+WAIT_Rdy1 LDR R2, [R0, #PMC_SR]
+ ANDS R2, R2, #PMC_MCKRDY
+ BEQ WAIT_Rdy1
+ LDR R1, =PMC_MCKR_Val
+ STR R1, [R0, #PMC_MCKR]
+WAIT_Rdy2 LDR R2, [R0, #PMC_SR]
+ ANDS R2, R2, #PMC_MCKRDY
+ BEQ WAIT_Rdy2
+ ENDIF ; Select Clock
+ ENDIF ; PMC_SETUP
+
+
+; Copy Exception Vectors to Internal RAM
+
+ IF :DEF:RAM_INTVEC
+ ADR R8, Vectors ; Source
+ LDR R9, =RAM_BASE ; Destination
+ LDMIA R8!, {R0-R7} ; Load Vectors
+ STMIA R9!, {R0-R7} ; Store Vectors
+ LDMIA R8!, {R0-R7} ; Load Handler Addresses
+ STMIA R9!, {R0-R7} ; Store Handler Addresses
+ ENDIF
+
+
+; Remap on-chip RAM to address 0
+
+MC_BASE EQU 0xFFFFFF00 ; MC Base Address
+MC_RCR EQU 0x00 ; MC_RCR Offset
+
+ IF :DEF:REMAP
+ LDR R0, =MC_BASE
+ MOV R1, #1
+ STR R1, [R0, #MC_RCR] ; Remap
+ ENDIF
+
+
+; 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
+ ; 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_interrput_flag
+ IMPORT rt_interrupt_from_thread
+ IMPORT rt_interrupt_to_thread
+ IMPORT rt_hw_trap_irq
+
+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_interrput_flag set, jump to
+ ; rt_hw_context_switch_interrupt_do and don't return
+ LDR r0, =rt_thread_switch_interrput_flag
+ LDR r1, [r0]
+ CMP r1, #1
+ BEQ rt_hw_context_switch_interrupt_do
+
+ LDMFD sp!, {r0-r12,lr}
+ SUBS pc, lr, #4
+ 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|F_Bit|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
+ MRS r4, spsr
+ STMFD sp!, {r4} ; push old task's spsr
+
+ 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 spsr
+ MSR spsr_cxsf, r4
+ LDMFD sp!, {r4} ; pop new task's psr
+ MSR cpsr_cxsf, r4
+
+ LDMFD sp!, {r0-r12,lr,pc} ; pop new task's r0-r12,lr & pc
+ 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
diff --git a/libcpu/arm/AT91SAM7X/trap.c b/libcpu/arm/AT91SAM7X/trap.c
new file mode 100644
index 0000000000..62346cb32d
--- /dev/null
+++ b/libcpu/arm/AT91SAM7X/trap.c
@@ -0,0 +1,40 @@
+/*
+ * File : trap.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2006-08-25 Bernard first version
+ */
+
+#include <rtthread.h>
+#include <rthw.h>
+
+#include "AT91SAM7X.h"
+
+/**
+ * @addtogroup AT91SAM7
+ */
+/*@{*/
+
+void rt_hw_trap_irq()
+{
+ rt_isr_handler_t hander = (rt_isr_handler_t)AT91C_AIC_IVR;
+
+ hander(AT91C_AIC_ISR);
+
+ /* end of interrupt */
+ AT91C_AIC_EOICR = 0;
+}
+
+void rt_hw_trap_fiq()
+{
+ rt_kprintf("fast interrupt request\n");
+}
+
+/*@}*/
diff --git a/libcpu/arm/common/backtrace.c b/libcpu/arm/common/backtrace.c
new file mode 100644
index 0000000000..59a4d0bf79
--- /dev/null
+++ b/libcpu/arm/common/backtrace.c
@@ -0,0 +1,67 @@
+/*
+ * File : backtrace.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, 2008 RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2008-07-29 Bernard first version from QiuYi implementation
+ */
+
+#include <rtthread.h>
+
+#ifdef __GNUC__
+/*
+-->High Address,Stack Top
+PC<-----|
+LR |
+IP |
+FP |
+...... |
+PC<-| |
+LR | |
+IP | |
+FP---|-- |
+...... |
+PC |
+LR |
+IP |
+FP---
+-->Low Address,Stack Bottom
+*/
+void rt_hw_backtrace(rt_uint32_t *fp, rt_uint32_t thread_entry)
+{
+ rt_uint32_t i, pc, func_entry;
+
+ pc = *fp;
+ rt_kprintf("[0x%x]\n", pc-0xC);
+
+ for(i=0; i<10; i++)
+ {
+ fp = *(fp - 3);
+ pc = *fp ;
+
+ func_entry = pc - 0xC;
+
+ if(func_entry <= 0x30000000) break;
+
+ if((func_entry == thread_entry))
+ {
+ rt_kprintf("EntryPoint:0x%x\n", func_entry);
+
+ break;
+ }
+
+ rt_kprintf("[0x%x]\n", func_entry);
+ }
+}
+#else
+void rt_hw_backtrace(rt_uint32_t *fp, rt_uint32_t thread_entry)
+{
+ /* old compiler implementation */
+}
+#endif
diff --git a/libcpu/arm/common/div0.c b/libcpu/arm/common/div0.c
new file mode 100644
index 0000000000..128a1eb859
--- /dev/null
+++ b/libcpu/arm/common/div0.c
@@ -0,0 +1,4 @@
+void __div0 (void)
+{
+ while (1) ;
+}
diff --git a/libcpu/arm/common/divsi3.S b/libcpu/arm/common/divsi3.S
new file mode 100644
index 0000000000..01eac6aabf
--- /dev/null
+++ b/libcpu/arm/common/divsi3.S
@@ -0,0 +1,393 @@
+/* $NetBSD: divsi3.S,v 1.5 2005/02/26 22:58:56 perry Exp $ */
+
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ */
+
+/*
+ * stack is aligned as there's a possibility of branching to L_overflow
+ * which makes a C call
+ */
+ .text
+ .align 0
+ .globl __umodsi3
+ .type __umodsi3 , function
+__umodsi3:
+ stmfd sp!, {lr}
+ sub sp, sp, #4 /* align stack */
+ bl .L_udivide
+ add sp, sp, #4 /* unalign stack */
+ mov r0, r1
+ ldmfd sp!, {pc}
+
+ .text
+ .align 0
+ .globl __modsi3
+ .type __modsi3 , function
+__modsi3:
+ stmfd sp!, {lr}
+ sub sp, sp, #4 /* align stack */
+ bl .L_divide
+ add sp, sp, #4 /* unalign stack */
+ mov r0, r1
+ ldmfd sp!, {pc}
+
+.L_overflow:
+ /* XXX should cause a fatal error */
+ mvn r0, #0
+ mov pc, lr
+
+ .text
+ .align 0
+ .globl __udivsi3
+ .type __udivsi3 , function
+__udivsi3:
+.L_udivide: /* r0 = r0 / r1; r1 = r0 % r1 */
+ eor r0, r1, r0
+ eor r1, r0, r1
+ eor r0, r1, r0
+ /* r0 = r1 / r0; r1 = r1 % r0 */
+ cmp r0, #1
+ bcc .L_overflow
+ beq .L_divide_l0
+ mov ip, #0
+ movs r1, r1
+ bpl .L_divide_l1
+ orr ip, ip, #0x20000000 /* ip bit 0x20000000 = -ve r1 */
+ movs r1, r1, lsr #1
+ orrcs ip, ip, #0x10000000 /* ip bit 0x10000000 = bit 0 of r1 */
+ b .L_divide_l1
+
+.L_divide_l0: /* r0 == 1 */
+ mov r0, r1
+ mov r1, #0
+ mov pc, lr
+
+ .text
+ .align 0
+ .globl __divsi3
+ .type __divsi3 , function
+__divsi3:
+.L_divide: /* r0 = r0 / r1; r1 = r0 % r1 */
+ eor r0, r1, r0
+ eor r1, r0, r1
+ eor r0, r1, r0
+ /* r0 = r1 / r0; r1 = r1 % r0 */
+ cmp r0, #1
+ bcc .L_overflow
+ beq .L_divide_l0
+ ands ip, r0, #0x80000000
+ rsbmi r0, r0, #0
+ ands r2, r1, #0x80000000
+ eor ip, ip, r2
+ rsbmi r1, r1, #0
+ orr ip, r2, ip, lsr #1 /* ip bit 0x40000000 = -ve division */
+ /* ip bit 0x80000000 = -ve remainder */
+
+.L_divide_l1:
+ mov r2, #1
+ mov r3, #0
+
+ /*
+ * If the highest bit of the dividend is set, we have to be
+ * careful when shifting the divisor. Test this.
+ */
+ movs r1,r1
+ bpl .L_old_code
+
+ /*
+ * At this point, the highest bit of r1 is known to be set.
+ * We abuse this below in the tst instructions.
+ */
+ tst r1, r0 /*, lsl #0 */
+ bmi .L_divide_b1
+ tst r1, r0, lsl #1
+ bmi .L_divide_b2
+ tst r1, r0, lsl #2
+ bmi .L_divide_b3
+ tst r1, r0, lsl #3
+ bmi .L_divide_b4
+ tst r1, r0, lsl #4
+ bmi .L_divide_b5
+ tst r1, r0, lsl #5
+ bmi .L_divide_b6
+ tst r1, r0, lsl #6
+ bmi .L_divide_b7
+ tst r1, r0, lsl #7
+ bmi .L_divide_b8
+ tst r1, r0, lsl #8
+ bmi .L_divide_b9
+ tst r1, r0, lsl #9
+ bmi .L_divide_b10
+ tst r1, r0, lsl #10
+ bmi .L_divide_b11
+ tst r1, r0, lsl #11
+ bmi .L_divide_b12
+ tst r1, r0, lsl #12
+ bmi .L_divide_b13
+ tst r1, r0, lsl #13
+ bmi .L_divide_b14
+ tst r1, r0, lsl #14
+ bmi .L_divide_b15
+ tst r1, r0, lsl #15
+ bmi .L_divide_b16
+ tst r1, r0, lsl #16
+ bmi .L_divide_b17
+ tst r1, r0, lsl #17
+ bmi .L_divide_b18
+ tst r1, r0, lsl #18
+ bmi .L_divide_b19
+ tst r1, r0, lsl #19
+ bmi .L_divide_b20
+ tst r1, r0, lsl #20
+ bmi .L_divide_b21
+ tst r1, r0, lsl #21
+ bmi .L_divide_b22
+ tst r1, r0, lsl #22
+ bmi .L_divide_b23
+ tst r1, r0, lsl #23
+ bmi .L_divide_b24
+ tst r1, r0, lsl #24
+ bmi .L_divide_b25
+ tst r1, r0, lsl #25
+ bmi .L_divide_b26
+ tst r1, r0, lsl #26
+ bmi .L_divide_b27
+ tst r1, r0, lsl #27
+ bmi .L_divide_b28
+ tst r1, r0, lsl #28
+ bmi .L_divide_b29
+ tst r1, r0, lsl #29
+ bmi .L_divide_b30
+ tst r1, r0, lsl #30
+ bmi .L_divide_b31
+/*
+ * instead of:
+ * tst r1, r0, lsl #31
+ * bmi .L_divide_b32
+ */
+ b .L_divide_b32
+
+.L_old_code:
+ cmp r1, r0
+ bcc .L_divide_b0
+ cmp r1, r0, lsl #1
+ bcc .L_divide_b1
+ cmp r1, r0, lsl #2
+ bcc .L_divide_b2
+ cmp r1, r0, lsl #3
+ bcc .L_divide_b3
+ cmp r1, r0, lsl #4
+ bcc .L_divide_b4
+ cmp r1, r0, lsl #5
+ bcc .L_divide_b5
+ cmp r1, r0, lsl #6
+ bcc .L_divide_b6
+ cmp r1, r0, lsl #7
+ bcc .L_divide_b7
+ cmp r1, r0, lsl #8
+ bcc .L_divide_b8
+ cmp r1, r0, lsl #9
+ bcc .L_divide_b9
+ cmp r1, r0, lsl #10
+ bcc .L_divide_b10
+ cmp r1, r0, lsl #11
+ bcc .L_divide_b11
+ cmp r1, r0, lsl #12
+ bcc .L_divide_b12
+ cmp r1, r0, lsl #13
+ bcc .L_divide_b13
+ cmp r1, r0, lsl #14
+ bcc .L_divide_b14
+ cmp r1, r0, lsl #15
+ bcc .L_divide_b15
+ cmp r1, r0, lsl #16
+ bcc .L_divide_b16
+ cmp r1, r0, lsl #17
+ bcc .L_divide_b17
+ cmp r1, r0, lsl #18
+ bcc .L_divide_b18
+ cmp r1, r0, lsl #19
+ bcc .L_divide_b19
+ cmp r1, r0, lsl #20
+ bcc .L_divide_b20
+ cmp r1, r0, lsl #21
+ bcc .L_divide_b21
+ cmp r1, r0, lsl #22
+ bcc .L_divide_b22
+ cmp r1, r0, lsl #23
+ bcc .L_divide_b23
+ cmp r1, r0, lsl #24
+ bcc .L_divide_b24
+ cmp r1, r0, lsl #25
+ bcc .L_divide_b25
+ cmp r1, r0, lsl #26
+ bcc .L_divide_b26
+ cmp r1, r0, lsl #27
+ bcc .L_divide_b27
+ cmp r1, r0, lsl #28
+ bcc .L_divide_b28
+ cmp r1, r0, lsl #29
+ bcc .L_divide_b29
+ cmp r1, r0, lsl #30
+ bcc .L_divide_b30
+.L_divide_b32:
+ cmp r1, r0, lsl #31
+ subhs r1, r1,r0, lsl #31
+ addhs r3, r3,r2, lsl #31
+.L_divide_b31:
+ cmp r1, r0, lsl #30
+ subhs r1, r1,r0, lsl #30
+ addhs r3, r3,r2, lsl #30
+.L_divide_b30:
+ cmp r1, r0, lsl #29
+ subhs r1, r1,r0, lsl #29
+ addhs r3, r3,r2, lsl #29
+.L_divide_b29:
+ cmp r1, r0, lsl #28
+ subhs r1, r1,r0, lsl #28
+ addhs r3, r3,r2, lsl #28
+.L_divide_b28:
+ cmp r1, r0, lsl #27
+ subhs r1, r1,r0, lsl #27
+ addhs r3, r3,r2, lsl #27
+.L_divide_b27:
+ cmp r1, r0, lsl #26
+ subhs r1, r1,r0, lsl #26
+ addhs r3, r3,r2, lsl #26
+.L_divide_b26:
+ cmp r1, r0, lsl #25
+ subhs r1, r1,r0, lsl #25
+ addhs r3, r3,r2, lsl #25
+.L_divide_b25:
+ cmp r1, r0, lsl #24
+ subhs r1, r1,r0, lsl #24
+ addhs r3, r3,r2, lsl #24
+.L_divide_b24:
+ cmp r1, r0, lsl #23
+ subhs r1, r1,r0, lsl #23
+ addhs r3, r3,r2, lsl #23
+.L_divide_b23:
+ cmp r1, r0, lsl #22
+ subhs r1, r1,r0, lsl #22
+ addhs r3, r3,r2, lsl #22
+.L_divide_b22:
+ cmp r1, r0, lsl #21
+ subhs r1, r1,r0, lsl #21
+ addhs r3, r3,r2, lsl #21
+.L_divide_b21:
+ cmp r1, r0, lsl #20
+ subhs r1, r1,r0, lsl #20
+ addhs r3, r3,r2, lsl #20
+.L_divide_b20:
+ cmp r1, r0, lsl #19
+ subhs r1, r1,r0, lsl #19
+ addhs r3, r3,r2, lsl #19
+.L_divide_b19:
+ cmp r1, r0, lsl #18
+ subhs r1, r1,r0, lsl #18
+ addhs r3, r3,r2, lsl #18
+.L_divide_b18:
+ cmp r1, r0, lsl #17
+ subhs r1, r1,r0, lsl #17
+ addhs r3, r3,r2, lsl #17
+.L_divide_b17:
+ cmp r1, r0, lsl #16
+ subhs r1, r1,r0, lsl #16
+ addhs r3, r3,r2, lsl #16
+.L_divide_b16:
+ cmp r1, r0, lsl #15
+ subhs r1, r1,r0, lsl #15
+ addhs r3, r3,r2, lsl #15
+.L_divide_b15:
+ cmp r1, r0, lsl #14
+ subhs r1, r1,r0, lsl #14
+ addhs r3, r3,r2, lsl #14
+.L_divide_b14:
+ cmp r1, r0, lsl #13
+ subhs r1, r1,r0, lsl #13
+ addhs r3, r3,r2, lsl #13
+.L_divide_b13:
+ cmp r1, r0, lsl #12
+ subhs r1, r1,r0, lsl #12
+ addhs r3, r3,r2, lsl #12
+.L_divide_b12:
+ cmp r1, r0, lsl #11
+ subhs r1, r1,r0, lsl #11
+ addhs r3, r3,r2, lsl #11
+.L_divide_b11:
+ cmp r1, r0, lsl #10
+ subhs r1, r1,r0, lsl #10
+ addhs r3, r3,r2, lsl #10
+.L_divide_b10:
+ cmp r1, r0, lsl #9
+ subhs r1, r1,r0, lsl #9
+ addhs r3, r3,r2, lsl #9
+.L_divide_b9:
+ cmp r1, r0, lsl #8
+ subhs r1, r1,r0, lsl #8
+ addhs r3, r3,r2, lsl #8
+.L_divide_b8:
+ cmp r1, r0, lsl #7
+ subhs r1, r1,r0, lsl #7
+ addhs r3, r3,r2, lsl #7
+.L_divide_b7:
+ cmp r1, r0, lsl #6
+ subhs r1, r1,r0, lsl #6
+ addhs r3, r3,r2, lsl #6
+.L_divide_b6:
+ cmp r1, r0, lsl #5
+ subhs r1, r1,r0, lsl #5
+ addhs r3, r3,r2, lsl #5
+.L_divide_b5:
+ cmp r1, r0, lsl #4
+ subhs r1, r1,r0, lsl #4
+ addhs r3, r3,r2, lsl #4
+.L_divide_b4:
+ cmp r1, r0, lsl #3
+ subhs r1, r1,r0, lsl #3
+ addhs r3, r3,r2, lsl #3
+.L_divide_b3:
+ cmp r1, r0, lsl #2
+ subhs r1, r1,r0, lsl #2
+ addhs r3, r3,r2, lsl #2
+.L_divide_b2:
+ cmp r1, r0, lsl #1
+ subhs r1, r1,r0, lsl #1
+ addhs r3, r3,r2, lsl #1
+.L_divide_b1:
+ cmp r1, r0
+ subhs r1, r1, r0
+ addhs r3, r3, r2
+.L_divide_b0:
+
+ tst ip, #0x20000000
+ bne .L_udivide_l1
+ mov r0, r3
+ cmp ip, #0
+ rsbmi r1, r1, #0
+ movs ip, ip, lsl #1
+ bicmi r0, r0, #0x80000000 /* Fix incase we divided 0x80000000 */
+ rsbmi r0, r0, #0
+ mov pc, lr
+
+.L_udivide_l1:
+ tst ip, #0x10000000
+ mov r1, r1, lsl #1
+ orrne r1, r1, #1
+ mov r3, r3, lsl #1
+ cmp r1, r0
+ subhs r1, r1, r0
+ addhs r3, r3, r2
+ mov r0, r3
+ mov pc, lr
diff --git a/libcpu/arm/common/showmem.c b/libcpu/arm/common/showmem.c
new file mode 100644
index 0000000000..c171a9bcd7
--- /dev/null
+++ b/libcpu/arm/common/showmem.c
@@ -0,0 +1,42 @@
+/*
+ * File : showmem.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, 2008 RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2008-07-29 Bernard first version from QiuYi implementation
+ */
+
+#include <rtthread.h>
+
+void rt_hw_show_memory(rt_uint32_t addr, rt_uint32_t size)
+{
+ int i = 0, j =0;
+
+ RT_ASSERT(addr);
+
+ addr = addr & ~0xF;
+ size = 4*((size + 3)/4);
+
+ while(i < size)
+ {
+ rt_kprintf("0x%08x: ", addr );
+
+ for(j=0; j<4; j++)
+ {
+ rt_kprintf("0x%08x ", *(rt_uint32_t *)addr);
+
+ addr += 4;
+ i++;
+ }
+
+ rt_kprintf("\n");
+ }
+
+ return;
+}
diff --git a/libcpu/arm/lm3s/context_rvds.S b/libcpu/arm/lm3s/context_rvds.S
new file mode 100644
index 0000000000..9f2eb7577a
--- /dev/null
+++ b/libcpu/arm/lm3s/context_rvds.S
@@ -0,0 +1,178 @@
+;/*
+; * File : context.S
+; * This file is part of RT-Thread RTOS
+; * COPYRIGHT (C) 2006, RT-Thread Development Team
+; *
+; * The license and distribution terms for this file may be
+; * found in the file LICENSE in this distribution or at
+; * http://www.rt-thread.org/license/LICENSE
+; *
+; * Change Logs:
+; * Date Author Notes
+; * 2009-01-17 Bernard first version
+; */
+
+;/**
+; * @addtogroup STM32
+; */
+;/*@{*/
+
+NVIC_INT_CTRL EQU 0xE000ED04 ; interrupt control state register
+NVIC_SYSPRI2 EQU 0xE000ED20 ; system priority register (2)
+NVIC_PENDSV_PRI EQU 0x00000000 ; PendSV priority value (lowest)
+NVIC_PENDSVSET EQU 0x10000000 ; value to trigger PendSV exception
+
+ AREA |.text|, CODE, READONLY, ALIGN=2
+ THUMB
+ REQUIRE8
+ PRESERVE8
+
+ IMPORT rt_thread_switch_interrput_flag
+ IMPORT rt_interrupt_from_thread
+ IMPORT rt_interrupt_to_thread
+
+;/*
+; * rt_base_t rt_hw_interrupt_disable();
+; */
+rt_hw_interrupt_disable PROC
+ EXPORT rt_hw_interrupt_disable
+ MRS r0, PRIMASK
+ CPSID I
+ BX LR
+ ENDP
+
+;/*
+; * void rt_hw_interrupt_enable(rt_base_t level);
+; */
+rt_hw_interrupt_enable PROC
+ EXPORT rt_hw_interrupt_enable
+ MSR PRIMASK, 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
+ LDR r2, =rt_interrupt_from_thread
+ STR r0, [r2]
+
+ LDR r2, =rt_interrupt_to_thread
+ STR r1, [r2]
+
+ LDR r0, =NVIC_INT_CTRL ; trigger the PendSV exception (causes context switch)
+ LDR r1, =NVIC_PENDSVSET
+ STR r1, [r0]
+ CPSIE I ; enable interrupts at processor level
+ BX LR
+ ENDP
+
+; r0 --> swith from thread stack
+; r1 --> swith to thread stack
+; psr, pc, lr, r12, r3, r2, r1, r0 are pushed into [from] stack
+rt_hw_pend_sv PROC
+ EXPORT rt_hw_pend_sv
+ LDR r0, =rt_interrupt_from_thread
+ LDR r1, [r0]
+ CBZ r1, swtich_to_thread ; skip register save at the first time
+
+ MRS r1, psp ; get from thread stack pointer
+ STMFD r1!, {r4 - r11} ; push r4 - r11 register
+ LDR r0, [r0]
+ STR r1, [r0] ; update from thread stack pointer
+
+swtich_to_thread
+ LDR r1, =rt_interrupt_to_thread
+ LDR r1, [r1]
+ LDR r1, [r1] ; load thread stack pointer
+
+ LDMFD r1!, {r4 - r11} ; pop r4 - r11 register
+ MSR psp, r1 ; update stack pointer
+
+ ORR lr, lr, #0x04
+ BX lr
+ 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 r1, =rt_interrupt_to_thread
+ STR r0, [r1]
+
+ ; set from thread to 0
+ LDR r1, =rt_interrupt_from_thread
+ MOV r0, #0x0
+ STR r0, [r1]
+
+ ; set the PendSV exception priority
+ LDR r0, =NVIC_SYSPRI2
+ LDR r1, =NVIC_PENDSV_PRI
+ STR r1, [r0]
+
+ LDR r0, =NVIC_INT_CTRL ; trigger the PendSV exception (causes context switch)
+ LDR r1, =NVIC_PENDSVSET
+ STR r1, [r0]
+
+ CPSIE I ; enable interrupts at processor level
+
+ ; never reach here!
+ ENDP
+
+;/*
+; * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to)
+; * {
+; * if (rt_thread_switch_interrput_flag == 1)
+; * {
+; * rt_interrupt_to_thread = to;
+; * }
+; * else
+; * {
+; * rt_thread_switch_interrput_flag = 1;
+; * rt_interrupt_from_thread = from;
+; * rt_interrupt_to_thread = to;
+; * }
+; * }
+; */
+rt_hw_context_switch_interrupt PROC
+ EXPORT rt_hw_context_switch_interrupt
+ LDR r2, =rt_thread_switch_interrput_flag
+ LDR r3, [r2]
+ CMP r3, #1
+ BEQ _reswitch
+ MOV r3, #1 ; set rt_thread_switch_interrput_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
+
+rt_hw_interrupt_thread_switch PROC
+ EXPORT rt_hw_interrupt_thread_switch
+ LDR r0, =rt_thread_switch_interrput_flag
+ LDR r1, [r0]
+ CBZ r1, _no_switch
+
+ ; clear rt_thread_switch_interrput_flag to 0
+ MOV r1, #0x00
+ STR r1, [r0]
+
+ ; trigger context switch
+ LDR r0, =NVIC_INT_CTRL ; trigger the PendSV exception (causes context switch)
+ LDR r1, =NVIC_PENDSVSET
+ STR r1, [r0]
+
+_no_switch
+ BX lr
+
+ ENDP
+
+ END \ No newline at end of file
diff --git a/libcpu/arm/lm3s/cpu.c b/libcpu/arm/lm3s/cpu.c
new file mode 100644
index 0000000000..080634c2b9
--- /dev/null
+++ b/libcpu/arm/lm3s/cpu.c
@@ -0,0 +1,42 @@
+/*
+ * File : cpu.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Develop Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2006-03-13 Bernard first version
+ */
+
+#include <rtthread.h>
+
+/**
+ * @addtogroup S3C2410
+ */
+/*@{*/
+
+/**
+ * reset cpu by dog's time-out
+ *
+ */
+void rt_hw_cpu_reset()
+{
+ /*NOTREACHED*/
+}
+
+/**
+ * shutdown CPU
+ *
+ */
+void rt_hw_cpu_shutdown()
+{
+ rt_kprintf("shutdown...\n");
+
+ RT_ASSERT(0);
+}
+
+/*@}*/
diff --git a/libcpu/arm/lm3s/interrupt.c b/libcpu/arm/lm3s/interrupt.c
new file mode 100644
index 0000000000..a57656c7fb
--- /dev/null
+++ b/libcpu/arm/lm3s/interrupt.c
@@ -0,0 +1,25 @@
+/*
+ * File : trap.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2006-03-13 Bernard first version
+ */
+
+#include <rtthread.h>
+
+#define MAX_HANDLERS 32
+
+extern rt_uint32_t rt_interrupt_nest;
+
+/* exception and interrupt handler table */
+rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread;
+rt_uint32_t rt_thread_switch_interrput_flag;
+
+/*@}*/
diff --git a/libcpu/arm/lm3s/kservice.c b/libcpu/arm/lm3s/kservice.c
new file mode 100644
index 0000000000..a87d84a90e
--- /dev/null
+++ b/libcpu/arm/lm3s/kservice.c
@@ -0,0 +1,42 @@
+#include <rtthread.h>
+
+#include <stdio.h>
+#include <string.h>
+
+/*
+ * Only need when RealView MDK is used.
+ */
+void *rt_memset(void * s, int c, rt_ubase_t count)
+{
+ return memset(s, c, count);
+}
+
+void *rt_memcpy(void * dst, const void *src, rt_ubase_t count)
+{
+ return memcpy(dst, src, count);
+}
+
+rt_ubase_t rt_strncmp(const char * cs, const char * ct, rt_ubase_t count)
+{
+ return strncmp(cs, ct, count);
+}
+
+/**
+ * This function will show the version of rt-thread rtos
+ */
+void rt_show_version()
+{
+ rt_kprintf(" \\ | /\n");
+ rt_kprintf("- RT - Thread Operating System\n");
+ rt_kprintf(" / | \\ 0.%d.%d build %s\n", RT_VERSION, RT_SUBVERSION, __DATE__);
+ rt_kprintf(" 2006 - 2009 Copyright by rt-thread team\n");
+}
+
+void rt_kprintf(const char *fmt, ...)
+{
+ va_list args;
+
+ va_start(args, fmt);
+ vprintf(fmt, args);
+ va_end(args);
+}
diff --git a/libcpu/arm/lm3s/serial.c b/libcpu/arm/lm3s/serial.c
new file mode 100644
index 0000000000..79cb0ff4b4
--- /dev/null
+++ b/libcpu/arm/lm3s/serial.c
@@ -0,0 +1,362 @@
+/*
+ * File : serial.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2009-06-11 Bernard first version
+ */
+
+#include <rthw.h>
+#include <rtthread.h>
+
+#include <inc/hw_types.h>
+#include <inc/hw_memmap.h>
+#include <inc/hw_uart.h>
+#include <inc/hw_ints.h>
+#include <driverlib/gpio.h>
+#include <driverlib/sysctl.h>
+#include <driverlib/interrupt.h>
+
+#include <uart.h>
+#include "board.h"
+
+extern void rt_hw_interrupt_thread_switch(void);
+
+#define RT_UART_RX_BUFFER_SIZE 64
+
+/* LM3S serial device */
+struct rt_lm3s_serial
+{
+ /* inherit from device */
+ struct rt_device parent;
+
+ rt_uint32_t hw_base;
+ rt_uint32_t baudrate;
+
+ /* reception field */
+ rt_uint16_t save_index, read_index;
+ rt_uint8_t rx_buffer[RT_UART_RX_BUFFER_SIZE];
+};
+
+#ifdef RT_USING_UART1
+struct rt_lm3s_serial serial1;
+#endif
+#ifdef RT_USING_UART2
+struct rt_lm3s_serial serial2;
+#endif
+
+void rt_hw_serial_init(void);
+
+void rt_hw_uart_isr(struct rt_lm3s_serial* serial)
+{
+ rt_device_t device;
+ rt_uint32_t status;
+
+ device = (struct rt_device*)serial;
+ UARTIntStatus(serial->hw_base, true);
+
+ /* clear interrupt status */
+ UARTIntClear(serial->hw_base, status);
+
+ if (device->flag & RT_DEVICE_FLAG_INT_RX)
+ {
+ char ch;
+ rt_base_t level;
+
+ while (UARTCharsAvail(serial->hw_base))
+ {
+ ch = UARTCharGetNonBlocking(serial->hw_base);
+
+ /* disable interrupt */
+ level = rt_hw_interrupt_disable();
+
+ /* read character */
+ serial->rx_buffer[serial->save_index] = ch;
+ serial->save_index ++;
+ if (serial->save_index >= RT_UART_RX_BUFFER_SIZE)
+ serial->save_index = 0;
+
+ /* if the next position is read index, discard this 'read char' */
+ if (serial->save_index == serial->read_index)
+ {
+ serial->read_index ++;
+ if (serial->read_index >= RT_UART_RX_BUFFER_SIZE)
+ serial->read_index = 0;
+ }
+
+ /* enable interrupt */
+ rt_hw_interrupt_enable(level);
+ }
+
+ /* invoke callback */
+ if(device->rx_indicate != RT_NULL)
+ {
+ rt_int32_t length;
+
+ length = serial->save_index - serial->read_index;
+ if (length < 0) length += RT_UART_RX_BUFFER_SIZE;
+ device->rx_indicate(device, length);
+ }
+ }
+}
+
+#ifdef RT_USING_UART1
+void rt_hw_uart_isr_1(int irqno)
+{
+ /* enter interrupt */
+ rt_interrupt_enter();
+
+ /* get serial device */
+ rt_hw_uart_isr(&serial1);
+
+ /* leave interrupt */
+ rt_interrupt_leave();
+ rt_hw_interrupt_thread_switch();
+}
+#endif
+
+#ifdef RT_USING_UART2
+void rt_hw_uart_isr_2(int irqno)
+{
+ /* enter interrupt */
+ rt_interrupt_enter();
+
+ /* get serial device */
+ rt_hw_uart_isr(&serial2);
+
+ /* leave interrupt */
+ rt_interrupt_leave();
+ rt_hw_interrupt_thread_switch();
+}
+#endif
+
+/**
+ * @addtogroup LM3S
+ */
+/*@{*/
+
+static rt_err_t rt_serial_init (rt_device_t dev)
+{
+ return RT_EOK;
+}
+
+static rt_err_t rt_serial_open(rt_device_t dev, rt_uint16_t oflag)
+{
+ struct rt_lm3s_serial* serial;
+ serial = (struct rt_lm3s_serial*) dev;
+
+ RT_ASSERT(serial != RT_NULL);
+
+ if (dev->flag & RT_DEVICE_FLAG_INT_RX)
+ {
+ /* enable interrupt */
+ if (serial->hw_base == UART0_BASE)
+ IntEnable(INT_UART0);
+ else if (serial->hw_base == UART1_BASE)
+ IntEnable(INT_UART1);
+
+ UARTIntEnable(serial->hw_base, UART_INT_RX | UART_INT_RT);
+ }
+
+ return RT_EOK;
+}
+
+static rt_err_t rt_serial_close(rt_device_t dev)
+{
+ struct rt_lm3s_serial* serial;
+ serial = (struct rt_lm3s_serial*) dev;
+
+ RT_ASSERT(serial != RT_NULL);
+
+ if (dev->flag & RT_DEVICE_FLAG_INT_RX)
+ {
+ /* disable UART rx interrupt */
+ UARTIntDisable(serial->hw_base, UART_INT_RX | UART_INT_RT);
+ }
+
+ return RT_EOK;
+}
+
+static rt_err_t rt_serial_control(rt_device_t dev, rt_uint8_t cmd, void *args)
+{
+ return RT_EOK;
+}
+
+static rt_size_t rt_serial_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
+{
+ rt_uint8_t* ptr;
+ struct rt_lm3s_serial *serial = (struct rt_lm3s_serial*)dev;
+ RT_ASSERT(serial != RT_NULL);
+
+ /* point to buffer */
+ ptr = (rt_uint8_t*) buffer;
+
+ if (dev->flag & RT_DEVICE_FLAG_INT_RX)
+ {
+ while (size)
+ {
+ /* interrupt receive */
+ rt_base_t level;
+
+ /* disable interrupt */
+ level = rt_hw_interrupt_disable();
+ if (serial->read_index != serial->save_index)
+ {
+ *ptr = serial->rx_buffer[serial->read_index];
+
+ serial->read_index ++;
+ if (serial->read_index >= RT_UART_RX_BUFFER_SIZE)
+ serial->read_index = 0;
+ }
+ else
+ {
+ /* no data in rx buffer */
+
+ /* enable interrupt */
+ rt_hw_interrupt_enable(level);
+ break;
+ }
+
+ /* enable interrupt */
+ rt_hw_interrupt_enable(level);
+
+ ptr ++; size --;
+ }
+
+ return (rt_uint32_t)ptr - (rt_uint32_t)buffer;
+ }
+ else if (dev->flag & RT_DEVICE_FLAG_DMA_RX)
+ {
+ /* not support right now */
+ RT_ASSERT(0);
+ }
+
+ /* polling mode */
+ while (size)
+ {
+ *ptr = UARTCharGetNonBlocking(serial->hw_base);
+
+ ptr ++; size --;
+ }
+
+ return (rt_size_t)ptr - (rt_size_t)buffer;
+}
+
+static rt_size_t rt_serial_write(rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
+{
+ struct rt_lm3s_serial* serial;
+ char *ptr;
+
+ serial = (struct rt_lm3s_serial*) dev;
+ if (dev->flag & RT_DEVICE_FLAG_INT_TX)
+ {
+ /* not support */
+ RT_ASSERT(0);
+ }
+ else if (dev->flag & RT_DEVICE_FLAG_DMA_TX)
+ {
+ /* not support */
+ RT_ASSERT(0);
+ }
+
+ /* polling write */
+ ptr = (char *)buffer;
+
+ if (dev->flag & RT_DEVICE_FLAG_STREAM)
+ {
+ /* stream mode */
+ while (size)
+ {
+ if (*ptr == '\n')
+ while (UARTCharPutNonBlocking(serial->hw_base, '\r') == false);
+
+ while (UARTCharPutNonBlocking(serial->hw_base, *ptr) == false);
+
+ ptr ++;
+ size --;
+ }
+ }
+ else
+ {
+ while (size)
+ {
+ while (UARTCharPutNonBlocking(serial->hw_base, *ptr) == false);
+
+ ptr ++;
+ size --;
+ }
+ }
+
+ return (rt_size_t) ptr - (rt_size_t) buffer;
+}
+
+void rt_hw_serial_init(void)
+{
+ struct rt_lm3s_serial* serial;
+
+#ifdef RT_USING_UART1
+ serial = &serial1;
+
+ serial->parent.type = RT_Device_Class_Char;
+
+ serial->hw_base = UART0_BASE;
+ serial->baudrate = 115200;
+
+ rt_memset(serial->rx_buffer, 0, sizeof(serial->rx_buffer));
+ serial->read_index = serial->save_index = 0;
+
+ /* enable UART0 clock */
+ SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
+ SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
+
+ /* set UART0 pinmux */
+ GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
+
+ /* Configure the UART for 115,200, 8-N-1 operation. */
+ UARTConfigSetExpClk(UART0_BASE, SysCtlClockGet(), serial->baudrate,
+ (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |
+ UART_CONFIG_PAR_NONE));
+
+ serial->parent.init = rt_serial_init;
+ serial->parent.open = rt_serial_open;
+ serial->parent.close = rt_serial_close;
+ serial->parent.read = rt_serial_read;
+ serial->parent.write = rt_serial_write;
+ serial->parent.control = rt_serial_control;
+ serial->parent.private = RT_NULL;
+
+ rt_device_register(&serial->parent,
+ "uart1", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX);
+#endif
+
+#ifdef RT_USING_UART2
+ serial = &serial2;
+
+ serial->parent.type = RT_Device_Class_Char;
+
+ serial->hw_base = 0xE0010000;
+ serial->baudrate = 115200;
+
+ rt_memset(serial->rx_buffer, 0, sizeof(serial->rx_buffer));
+ serial->read_index = serial->save_index = 0;
+
+ serial->parent.init = rt_serial_init;
+ serial->parent.open = rt_serial_open;
+ serial->parent.close = rt_serial_close;
+ serial->parent.read = rt_serial_read;
+ serial->parent.write = rt_serial_write;
+ serial->parent.control = rt_serial_control;
+ serial->parent.private = RT_NULL;
+
+ rt_device_register(&serial->parent,
+ "uart2", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX);
+#endif
+}
+
+/*@}*/
diff --git a/libcpu/arm/lm3s/stack.c b/libcpu/arm/lm3s/stack.c
new file mode 100644
index 0000000000..c7f8c71ab4
--- /dev/null
+++ b/libcpu/arm/lm3s/stack.c
@@ -0,0 +1,59 @@
+/*
+ * File : stack.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2006-08-23 Bernard the first version
+ */
+#include <rtthread.h>
+
+/**
+ * @addtogroup STM32
+ */
+/*@{*/
+
+/**
+ * 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) = 0x01000000L; /* PSR */
+ *(--stk) = (unsigned long)tentry; /* entry point, pc */
+ *(--stk) = (unsigned long)texit; /* lr */
+ *(--stk) = 0; /* r12 */
+ *(--stk) = 0; /* r3 */
+ *(--stk) = 0; /* r2 */
+ *(--stk) = 0; /* r1 */
+ *(--stk) = (unsigned long)parameter; /* r0 : argument */
+
+ *(--stk) = 0; /* r11 */
+ *(--stk) = 0; /* r10 */
+ *(--stk) = 0; /* r9 */
+ *(--stk) = 0; /* r8 */
+ *(--stk) = 0; /* r7 */
+ *(--stk) = 0; /* r6 */
+ *(--stk) = 0; /* r5 */
+ *(--stk) = 0; /* r4 */
+
+ /* return task's current stack address */
+ return (rt_uint8_t *)stk;
+}
+
+/*@}*/
diff --git a/libcpu/arm/lm3s/start_rvds.S b/libcpu/arm/lm3s/start_rvds.S
new file mode 100644
index 0000000000..ad5295faab
--- /dev/null
+++ b/libcpu/arm/lm3s/start_rvds.S
@@ -0,0 +1,251 @@
+; <<< Use Configuration Wizard in Context Menu >>>
+;******************************************************************************
+;
+; Startup.s - Startup code for Stellaris.
+;
+; Copyright (c) 2006-2008 Luminary Micro, Inc. All rights reserved.
+;
+; Software License Agreement
+;
+; Luminary Micro, Inc. (LMI) is supplying this software for use solely and
+; exclusively on LMI's microcontroller products.
+;
+; The software is owned by LMI and/or its suppliers, and is protected under
+; applicable copyright laws. All rights are reserved. You may not combine
+; this software with "viral" open-source software in order to form a larger
+; program. Any use in violation of the foregoing restrictions may subject
+; the user to criminal sanctions under applicable laws, as well as to civil
+; liability for the breach of the terms and conditions of this license.
+;
+; THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
+; OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
+; MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
+; LMI SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
+; CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
+;
+; This is part of revision 2523 of the Stellaris Peripheral Driver Library.
+;
+;******************************************************************************
+
+;******************************************************************************
+;
+; <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
+;
+;******************************************************************************
+Stack EQU 0x00000100
+
+;******************************************************************************
+;
+; <o> Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
+;
+;******************************************************************************
+Heap EQU 0x00000000
+
+;******************************************************************************
+;
+; Allocate space for the stack.
+;
+;******************************************************************************
+ AREA STACK, NOINIT, READWRITE, ALIGN=3
+StackMem
+ SPACE Stack
+__initial_sp
+
+;******************************************************************************
+;
+; Allocate space for the heap.
+;
+;******************************************************************************
+ AREA HEAP, NOINIT, READWRITE, ALIGN=3
+__heap_base
+HeapMem
+ SPACE Heap
+__heap_limit
+
+ IMPORT rt_hw_pend_sv
+ IMPORT rt_hw_timer_handler
+ IMPORT rt_hw_uart_isr_1
+
+;******************************************************************************
+;
+; Indicate that the code in this file preserves 8-byte alignment of the stack.
+;
+;******************************************************************************
+ PRESERVE8
+
+;******************************************************************************
+;
+; Place code into the reset code section.
+;
+;******************************************************************************
+ AREA RESET, CODE, READONLY
+ THUMB
+
+;******************************************************************************
+;
+; The vector table.
+;
+;******************************************************************************
+ EXPORT __Vectors
+__Vectors
+ DCD StackMem + Stack ; Top of Stack
+ DCD Reset_Handler ; Reset Handler
+ DCD NmiSR ; NMI Handler
+ DCD FaultISR ; Hard Fault Handler
+ DCD IntDefaultHandler ; MPU Fault Handler
+ DCD IntDefaultHandler ; Bus Fault Handler
+ DCD IntDefaultHandler ; Usage Fault Handler
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD IntDefaultHandler ; SVCall Handler
+ DCD IntDefaultHandler ; Debug Monitor Handler
+ DCD 0 ; Reserved
+ DCD rt_hw_pend_sv ; PendSV Handler
+ DCD rt_hw_timer_handler ; SysTick Handler
+ DCD IntDefaultHandler ; GPIO Port A
+ DCD IntDefaultHandler ; GPIO Port B
+ DCD IntDefaultHandler ; GPIO Port C
+ DCD IntDefaultHandler ; GPIO Port D
+ DCD IntDefaultHandler ; GPIO Port E
+ DCD rt_hw_uart_isr_1 ; UART0
+ DCD IntDefaultHandler ; UART1
+ DCD IntDefaultHandler ; SSI
+ DCD IntDefaultHandler ; I2C
+ DCD IntDefaultHandler ; PWM Fault
+ DCD IntDefaultHandler ; PWM Generator 0
+ DCD IntDefaultHandler ; PWM Generator 1
+ DCD IntDefaultHandler ; PWM Generator 2
+ DCD IntDefaultHandler ; Quadrature Encoder
+ DCD IntDefaultHandler ; ADC Sequence 0
+ DCD IntDefaultHandler ; ADC Sequence 1
+ DCD IntDefaultHandler ; ADC Sequence 2
+ DCD IntDefaultHandler ; ADC Sequence 3
+ DCD IntDefaultHandler ; Watchdog
+ DCD IntDefaultHandler ; Timer 0A
+ DCD IntDefaultHandler ; Timer 0B
+ DCD IntDefaultHandler ; Timer 1A
+ DCD IntDefaultHandler ; Timer 1B
+ DCD IntDefaultHandler ; Timer 2A
+ DCD IntDefaultHandler ; Timer 2B
+ DCD IntDefaultHandler ; Comp 0
+ DCD IntDefaultHandler ; Comp 1
+ DCD IntDefaultHandler ; Comp 2
+ DCD IntDefaultHandler ; System Control
+ DCD IntDefaultHandler ; Flash Control
+ DCD IntDefaultHandler ; GPIO Port F
+ DCD IntDefaultHandler ; GPIO Port G
+ DCD IntDefaultHandler ; GPIO Port H
+ DCD IntDefaultHandler ; UART2 Rx and Tx
+ DCD IntDefaultHandler ; SSI1 Rx and Tx
+ DCD IntDefaultHandler ; Timer 3 subtimer A
+ DCD IntDefaultHandler ; Timer 3 subtimer B
+ DCD IntDefaultHandler ; I2C1 Master and Slave
+ DCD IntDefaultHandler ; Quadrature Encoder 1
+ DCD IntDefaultHandler ; CAN0
+ DCD IntDefaultHandler ; CAN1
+ DCD IntDefaultHandler ; CAN2
+ DCD IntDefaultHandler ; Ethernet
+ DCD IntDefaultHandler ; Hibernate
+ DCD IntDefaultHandler ; USB0
+ DCD IntDefaultHandler ; PWM Generator 3
+ DCD IntDefaultHandler ; uDMA Software Transfer
+ DCD IntDefaultHandler ; uDMA Error
+
+;******************************************************************************
+;
+; This is the code that gets called when the processor first starts execution
+; following a reset event.
+;
+;******************************************************************************
+ EXPORT Reset_Handler
+Reset_Handler
+ ;
+ ; Call the C library enty point that handles startup. This will copy
+ ; the .data section initializers from flash to SRAM and zero fill the
+ ; .bss section.
+ ;
+ IMPORT __main
+ B __main
+
+;******************************************************************************
+;
+; This is the code that gets called when the processor receives a NMI. This
+; simply enters an infinite loop, preserving the system state for examination
+; by a debugger.
+;
+;******************************************************************************
+NmiSR
+ B NmiSR
+
+;******************************************************************************
+;
+; This is the code that gets called when the processor receives a fault
+; interrupt. This simply enters an infinite loop, preserving the system state
+; for examination by a debugger.
+;
+;******************************************************************************
+FaultISR
+ B FaultISR
+
+;******************************************************************************
+;
+; This is the code that gets called when the processor receives an unexpected
+; interrupt. This simply enters an infinite loop, preserving the system state
+; for examination by a debugger.
+;
+;******************************************************************************
+IntDefaultHandler
+ B IntDefaultHandler
+
+;******************************************************************************
+;
+; Make sure the end of this section is aligned.
+;
+;******************************************************************************
+ ALIGN
+
+;******************************************************************************
+;
+; Some code in the normal code section for initializing the heap and stack.
+;
+;******************************************************************************
+ AREA |.text|, CODE, READONLY
+
+;******************************************************************************
+;
+; The function expected of the C library startup code for defining the stack
+; and heap memory locations. For the C library version of the startup code,
+; provide this function so that the C library initialization code can find out
+; the location of the stack and heap.
+;
+;******************************************************************************
+ IF :DEF: __MICROLIB
+ EXPORT __initial_sp
+ EXPORT __heap_base
+ EXPORT __heap_limit
+ ELSE
+ IMPORT __use_two_region_memory
+ EXPORT __user_initial_stackheap
+__user_initial_stackheap
+ LDR R0, =HeapMem
+ LDR R1, =(StackMem + Stack)
+ LDR R2, =(HeapMem + Heap)
+ LDR R3, =StackMem
+ BX LR
+ ENDIF
+
+;******************************************************************************
+;
+; Make sure the end of this section is aligned.
+;
+;******************************************************************************
+ ALIGN
+
+;******************************************************************************
+;
+; Tell the assembler that we're done.
+;
+;******************************************************************************
+ END
diff --git a/libcpu/arm/lpc214x/LPC214x.h b/libcpu/arm/lpc214x/LPC214x.h
new file mode 100644
index 0000000000..ddf655a483
--- /dev/null
+++ b/libcpu/arm/lpc214x/LPC214x.h
@@ -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
diff --git a/libcpu/arm/lpc214x/context_gcc.S b/libcpu/arm/lpc214x/context_gcc.S
new file mode 100644
index 0000000000..3a77976073
--- /dev/null
+++ b/libcpu/arm/lpc214x/context_gcc.S
@@ -0,0 +1,102 @@
+.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 �C R12�Լ�LRѹ��ջ */
+
+ MRS r4, cpsr /* ��ȡCPSR�Ĵ�����R4�Ĵ��� */
+ STMFD sp!, {r4} /* push cpsr */
+ /* ��R4�Ĵ���ѹջ������һָ��ȡ����CPSR�Ĵ����� */
+ MRS r4, spsr /* ��ȡSPSR�Ĵ�����R4�Ĵ��� */
+ 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 �C 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 �C R12��LR��PC�Ĵ��� */
+ //ENDP
+
+rt_hw_context_switch_interrupt:
+ //EXPORT rt_hw_context_switch_interrupt
+ LDR r2, =rt_thread_switch_interrput_flag
+ LDR r3, [r2] /* �����ж����л����µ�ַ */
+ CMP r3, #1 /* ���� 1 ��*/
+ BEQ _reswitch /* �������1����ת��_reswitch*/
+ MOV r3, #1 /* set rt_thread_switch_interrput_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 \ No newline at end of file
diff --git a/libcpu/arm/lpc214x/context_rvds.s b/libcpu/arm/lpc214x/context_rvds.s
new file mode 100644
index 0000000000..82c5adc574
--- /dev/null
+++ b/libcpu/arm/lpc214x/context_rvds.s
@@ -0,0 +1,107 @@
+;/*
+; * File : context_rvds.S
+; * This file is part of RT-Thread RTOS
+; * COPYRIGHT (C) 2006, RT-Thread Development Team
+; *
+; * The license and distribution terms for this file may be
+; * found in the file LICENSE in this distribution or at
+; * http://www.rt-thread.org/license/LICENSE
+; *
+; * Change Logs:
+; * Date Author Notes
+; * 2009-01-20 Bernard first version
+; */
+
+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
+ STMFD sp!, {r4} ; push cpsr
+ MRS r4, spsr
+ STMFD sp!, {r4} ; push spsr
+
+ STR sp, [r0] ; store sp in preempted tasks TCB
+ LDR sp, [r1] ; get new task stack pointer
+
+ LDMFD sp!, {r4} ; pop new task spsr
+ MSR spsr_cxsf, r4
+ LDMFD sp!, {r4} ; pop new task cpsr
+ MSR cpsr_cxsf, r4
+
+ LDMFD sp!, {r0-r12, lr, pc} ; pop new task r0-r12, lr & pc
+ 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 spsr
+ MSR spsr_cxsf, r4
+ LDMFD sp!, {r4} ; pop new task cpsr
+ MSR cpsr_cxsf, r4
+
+ LDMFD sp!, {r0-r12, lr, pc} ; pop new task r0-r12, lr & pc
+ ENDP
+
+;/*
+; * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to);
+; */
+ IMPORT rt_thread_switch_interrput_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_interrput_flag
+ LDR r3, [r2]
+ CMP r3, #1
+ BEQ _reswitch
+ MOV r3, #1 ; set rt_thread_switch_interrput_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
+
+ END \ No newline at end of file
diff --git a/libcpu/arm/lpc214x/cpu.c b/libcpu/arm/lpc214x/cpu.c
new file mode 100644
index 0000000000..5e228171f5
--- /dev/null
+++ b/libcpu/arm/lpc214x/cpu.c
@@ -0,0 +1,42 @@
+/*
+ * File : cpu.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Develop Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2006-08-23 Bernard first version
+ */
+
+#include <rtthread.h>
+#include "lpc214x.h"
+
+/**
+ * @addtogroup LPC214x
+ */
+/*@{*/
+
+/**
+ * this function will reset CPU
+ *
+ */
+void rt_hw_cpu_reset()
+{
+}
+
+/**
+ * this function will shutdown CPU
+ *
+ */
+void rt_hw_cpu_shutdown()
+{
+ rt_kprintf("shutdown...\n");
+
+ while (1);
+}
+
+/*@}*/
diff --git a/libcpu/arm/lpc214x/interrupt.c b/libcpu/arm/lpc214x/interrupt.c
new file mode 100644
index 0000000000..3c4e78e855
--- /dev/null
+++ b/libcpu/arm/lpc214x/interrupt.c
@@ -0,0 +1,105 @@
+/*
+ * File : trap.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2006-08-23 Bernard first version
+ */
+
+#include <rtthread.h>
+#include "lpc214x.h"
+
+#define MAX_HANDLERS 32
+
+extern rt_uint32_t rt_interrupt_nest;
+
+rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread;
+rt_uint32_t rt_thread_switch_interrput_flag;
+
+/**
+ * @addtogroup LPC214x
+ */
+/*@{*/
+
+void rt_hw_interrupt_handler(int vector)
+{
+ rt_kprintf("Unhandled interrupt %d occured!!!\n", vector);
+}
+
+/**
+ * This function will initialize hardware interrupt
+ */
+void rt_hw_interrupt_init()
+{
+ rt_base_t index;
+ rt_uint32_t *vect_addr, *vect_ctl;
+
+ /* initialize VIC*/
+ VICIntEnClr = 0xffffffff;
+ VICVectAddr = 0;
+ /* set all to IRQ */
+ VICIntSelect = 0;
+
+ for (index = 0; index < MAX_HANDLERS; index ++)
+ {
+ 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)rt_hw_interrupt_handler;
+ *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_interrput_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 new_handler the interrupt service routine to be installed
+ * @param old_handler the old interrupt service routine
+ */
+void rt_hw_interrupt_install(int vector, rt_isr_handler_t new_handler, rt_isr_handler_t *old_handler)
+{
+ if(vector >= 0 && vector < MAX_HANDLERS)
+ {
+ /* get VIC address */
+ rt_uint32_t* vect_addr = (rt_uint32_t *)(VIC_BASE_ADDR + 0x100 + (vector << 2));
+ 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);
+
+ if (old_handler != RT_NULL) *old_handler = (rt_isr_handler_t) *vect_addr;
+ if (new_handler != RT_NULL) *vect_addr = (rt_uint32_t) new_handler;
+ }
+}
+
+/*@}*/
diff --git a/libcpu/arm/lpc214x/serial.c b/libcpu/arm/lpc214x/serial.c
new file mode 100644
index 0000000000..4bfa7614e9
--- /dev/null
+++ b/libcpu/arm/lpc214x/serial.c
@@ -0,0 +1,387 @@
+/*
+ * File : serial.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2006-08-23 Bernard first version
+ */
+
+#include <rthw.h>
+#include <rtthread.h>
+
+#include "lpc214x.h"
+#include "board.h"
+
+/* serial hardware register */
+#define REG8(d) (*((volatile unsigned char *)(d)))
+#define REG32(d) (*((volatile unsigned long *)(d)))
+
+#define UART_RBR(base) REG8(base + 0x00)
+#define UART_THR(base) REG8(base + 0x00)
+#define UART_IER(base) REG32(base + 0x04)
+#define UART_IIR(base) REG32(base + 0x08)
+#define UART_FCR(base) REG8(base + 0x08)
+#define UART_LCR(base) REG8(base + 0x0C)
+#define UART_MCR(base) REG8(base + 0x10)
+#define UART_LSR(base) REG8(base + 0x14)
+#define UART_MSR(base) REG8(base + 0x18)
+#define UART_SCR(base) REG8(base + 0x1C)
+#define UART_DLL(base) REG8(base + 0x00)
+#define UART_DLM(base) REG8(base + 0x04)
+#define UART_ACR(base) REG32(base + 0x20)
+#define UART_FDR(base) REG32(base + 0x28)
+#define UART_TER(base) REG8(base + 0x30)
+
+/* LPC serial device */
+struct rt_lpcserial
+{
+ /* inherit from device */
+ struct rt_device parent;
+
+ rt_uint32_t hw_base;
+ rt_uint32_t irqno;
+ rt_uint32_t baudrate;
+
+ /* reception field */
+ rt_uint16_t save_index, read_index;
+ rt_uint8_t rx_buffer[RT_UART_RX_BUFFER_SIZE];
+};
+
+#ifdef RT_USING_UART1
+struct rt_lpcserial serial1;
+#endif
+#ifdef RT_USING_UART2
+struct rt_lpcserial serial2;
+#endif
+
+void rt_hw_serial_init(void);
+
+#define U0PINS 0x00000005
+
+void rt_hw_uart_isr(struct rt_lpcserial* lpc_serial)
+{
+ UNUSED rt_uint32_t iir;
+
+ RT_ASSERT(lpc_serial != RT_NULL)
+
+ if (UART_LSR(lpc_serial->hw_base) & 0x01)
+ {
+ rt_base_t level;
+
+ while (UART_LSR(lpc_serial->hw_base) & 0x01)
+ {
+ /* disable interrupt */
+ level = rt_hw_interrupt_disable();
+
+ /* read character */
+ lpc_serial->rx_buffer[lpc_serial->save_index] =
+ UART_RBR(lpc_serial->hw_base);
+ lpc_serial->save_index ++;
+ if (lpc_serial->save_index >= RT_UART_RX_BUFFER_SIZE)
+ lpc_serial->save_index = 0;
+
+ /* if the next position is read index, discard this 'read char' */
+ if (lpc_serial->save_index == lpc_serial->read_index)
+ {
+ lpc_serial->read_index ++;
+ if (lpc_serial->read_index >= RT_UART_RX_BUFFER_SIZE)
+ lpc_serial->read_index = 0;
+ }
+
+ /* enable interrupt */
+ rt_hw_interrupt_enable(level);
+ }
+
+ /* invoke callback */
+ if(lpc_serial->parent.rx_indicate != RT_NULL)
+ {
+ lpc_serial->parent.rx_indicate(&lpc_serial->parent, 1);
+ }
+ }
+
+ /* clear interrupt source */
+ iir = UART_IIR(lpc_serial->hw_base);
+
+ /* acknowledge Interrupt */
+ VICVectAddr = 0;
+}
+
+#ifdef RT_USING_UART1
+void rt_hw_uart_isr_1(int irqno)
+{
+ /* get lpc serial device */
+ rt_hw_uart_isr(&serial1);
+}
+#endif
+
+#ifdef RT_USING_UART2
+void rt_hw_uart_isr_2(int irqno)
+{
+ /* get lpc serial device */
+ rt_hw_uart_isr(&serial2);
+}
+#endif
+
+/**
+ * @addtogroup LPC214x
+ */
+/*@{*/
+
+static rt_err_t rt_serial_init (rt_device_t dev)
+{
+ return RT_EOK;
+}
+
+static rt_err_t rt_serial_open(rt_device_t dev, rt_uint16_t oflag)
+{
+ struct rt_lpcserial* lpc_serial;
+ lpc_serial = (struct rt_lpcserial*) dev;
+
+ RT_ASSERT(lpc_serial != RT_NULL);
+ if (dev->flag & RT_DEVICE_FLAG_INT_RX)
+ {
+ /* init UART rx interrupt */
+ UART_IER(lpc_serial->hw_base) = 0x01;
+
+ /* install ISR */
+ if (lpc_serial->irqno == UART0_INT)
+ {
+#ifdef RT_USING_UART1
+ rt_hw_interrupt_install(lpc_serial->irqno, rt_hw_uart_isr_1, RT_NULL);
+#endif
+ }
+ else
+ {
+#ifdef RT_USING_UART2
+ rt_hw_interrupt_install(lpc_serial->irqno, rt_hw_uart_isr_2, RT_NULL);
+#endif
+ }
+
+ rt_hw_interrupt_umask(lpc_serial->irqno);
+ }
+
+ return RT_EOK;
+}
+
+static rt_err_t rt_serial_close(rt_device_t dev)
+{
+ struct rt_lpcserial* lpc_serial;
+ lpc_serial = (struct rt_lpcserial*) dev;
+
+ RT_ASSERT(lpc_serial != RT_NULL);
+
+ if (dev->flag & RT_DEVICE_FLAG_INT_RX)
+ {
+ /* disable UART rx interrupt */
+ UART_IER(lpc_serial->hw_base) = 0x00;
+ }
+
+ return RT_EOK;
+}
+
+static rt_err_t rt_serial_control(rt_device_t dev, rt_uint8_t cmd, void *args)
+{
+ return RT_EOK;
+}
+
+static rt_size_t rt_serial_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
+{
+ rt_uint8_t* ptr;
+ struct rt_lpcserial *lpc_serial = (struct rt_lpcserial*)dev;
+ RT_ASSERT(lpc_serial != RT_NULL);
+
+ /* point to buffer */
+ ptr = (rt_uint8_t*) buffer;
+
+ if (dev->flag & RT_DEVICE_FLAG_INT_RX)
+ {
+ while (size)
+ {
+ /* interrupt receive */
+ rt_base_t level;
+
+ /* disable interrupt */
+ level = rt_hw_interrupt_disable();
+ if (lpc_serial->read_index != lpc_serial->save_index)
+ {
+ *ptr = lpc_serial->rx_buffer[lpc_serial->read_index];
+
+ lpc_serial->read_index ++;
+ if (lpc_serial->read_index >= RT_UART_RX_BUFFER_SIZE)
+ lpc_serial->read_index = 0;
+ }
+ else
+ {
+ /* no data in rx buffer */
+
+ /* enable interrupt */
+ rt_hw_interrupt_enable(level);
+ break;
+ }
+
+ /* enable interrupt */
+ rt_hw_interrupt_enable(level);
+
+ ptr ++; size --;
+ }
+
+ return (rt_uint32_t)ptr - (rt_uint32_t)buffer;
+ }
+ else if (dev->flag & RT_DEVICE_FLAG_DMA_RX)
+ {
+ /* not support right now */
+ RT_ASSERT(0);
+ }
+
+ /* polling mode */
+ while (size && (UART_LSR(lpc_serial->hw_base) & 0x01))
+ {
+ /* Read Character */
+ *ptr = UART_RBR(lpc_serial->hw_base);
+
+ ptr ++;
+ size --;
+ }
+
+ return (rt_size_t)ptr - (rt_size_t)buffer;
+}
+
+static rt_size_t rt_serial_write(rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
+{
+ struct rt_lpcserial* lpc_serial;
+ char *ptr;
+
+ lpc_serial = (struct rt_lpcserial*) dev;
+ if (dev->flag & RT_DEVICE_FLAG_INT_TX)
+ {
+ /* not support */
+ RT_ASSERT(0);
+ }
+ else if (dev->flag & RT_DEVICE_FLAG_DMA_TX)
+ {
+ /* not support */
+ RT_ASSERT(0);
+ }
+
+ /* polling write */
+ ptr = (char *)buffer;
+
+ if (dev->flag & RT_DEVICE_FLAG_STREAM)
+ {
+ /* stream mode */
+ while (size)
+ {
+ if (*ptr == '\n')
+ {
+ while (!(UART_LSR(lpc_serial->hw_base) & 0x20));
+ UART_THR(lpc_serial->hw_base) = '\r';
+ }
+
+ while (!(UART_LSR(lpc_serial->hw_base) & 0x20));
+ UART_THR(lpc_serial->hw_base) = *ptr;
+
+ ptr ++;
+ size --;
+ }
+ }
+ else
+ {
+ while (size)
+ {
+ while (!(UART_LSR(lpc_serial->hw_base) & 0x20));
+ UART_THR(lpc_serial->hw_base) = *ptr;
+
+ ptr ++;
+ size --;
+ }
+ }
+
+ return (rt_size_t) ptr - (rt_size_t) buffer;
+}
+
+void rt_hw_serial_init(void)
+{
+ struct rt_lpcserial* lpc_serial;
+
+#ifdef RT_USING_UART1
+ lpc_serial = &serial1;
+
+ lpc_serial->parent.type = RT_Device_Class_Char;
+
+ lpc_serial->hw_base = 0xE000C000;
+ lpc_serial->baudrate = 115200;
+ lpc_serial->irqno = UART0_INT;
+
+ rt_memset(lpc_serial->rx_buffer, 0, sizeof(lpc_serial->rx_buffer));
+ lpc_serial->read_index = lpc_serial->save_index = 0;
+
+ /* Enable UART0 RxD and TxD pins */
+ PINSEL0 |= 0x05;
+
+ /* 8 bits, no Parity, 1 Stop bit */
+ UART_LCR(lpc_serial->hw_base) = 0x83;
+
+ /* Setup Baudrate */
+ UART_DLL(lpc_serial->hw_base) = (PCLK/16/lpc_serial->baudrate) & 0xFF;
+ UART_DLM(lpc_serial->hw_base) = ((PCLK/16/lpc_serial->baudrate) >> 8) & 0xFF;
+
+ /* DLAB = 0 */
+ UART_LCR(lpc_serial->hw_base) = 0x03;
+
+ lpc_serial->parent.init = rt_serial_init;
+ lpc_serial->parent.open = rt_serial_open;
+ lpc_serial->parent.close = rt_serial_close;
+ lpc_serial->parent.read = rt_serial_read;
+ lpc_serial->parent.write = rt_serial_write;
+ lpc_serial->parent.control = rt_serial_control;
+ lpc_serial->parent.private = RT_NULL;
+
+ rt_device_register(&lpc_serial->parent,
+ "uart1", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX);
+#endif
+
+#ifdef RT_USING_UART2
+ lpc_serial = &serial2;
+
+ lpc_serial->parent.type = RT_Device_Class_Char;
+
+ lpc_serial->hw_base = 0xE0010000;
+ lpc_serial->baudrate = 115200;
+ lpc_serial->irqno = UART1_INT;
+
+ rt_memset(lpc_serial->rx_buffer, 0, sizeof(lpc_serial->rx_buffer));
+ lpc_serial->read_index = lpc_serial->save_index = 0;
+
+ /* Enable UART1 RxD and TxD pins */
+ PINSEL0 |= 0x05 << 16;
+
+ /* 8 bits, no Parity, 1 Stop bit */
+ UART_LCR(lpc_serial->hw_base) = 0x83;
+
+ /* Setup Baudrate */
+ UART_DLL(lpc_serial->hw_base) = (PCLK/16/lpc_serial->baudrate) & 0xFF;
+ UART_DLM(lpc_serial->hw_base) = ((PCLK/16/lpc_serial->baudrate) >> 8) & 0xFF;
+
+ /* DLAB = 0 */
+ UART_LCR(lpc_serial->hw_base) = 0x03;
+
+ lpc_serial->parent.init = rt_serial_init;
+ lpc_serial->parent.open = rt_serial_open;
+ lpc_serial->parent.close = rt_serial_close;
+ lpc_serial->parent.read = rt_serial_read;
+ lpc_serial->parent.write = rt_serial_write;
+ lpc_serial->parent.control = rt_serial_control;
+ lpc_serial->parent.private = RT_NULL;
+
+ rt_device_register(&lpc_serial->parent,
+ "uart2", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX);
+#endif
+}
+
+/*@}*/
diff --git a/libcpu/arm/lpc214x/stack.c b/libcpu/arm/lpc214x/stack.c
new file mode 100644
index 0000000000..177545f374
--- /dev/null
+++ b/libcpu/arm/lpc214x/stack.c
@@ -0,0 +1,61 @@
+/*
+ * File : stack.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2006-08-23 Bernard the first version
+ */
+#include <rtthread.h>
+
+#define SVCMODE 0x13
+
+/**
+ * @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 */
+ *(--stk) = SVCMODE; /* cpsr */
+ *(--stk) = SVCMODE; /* spsr */
+
+ /* return task's current stack address */
+ return (rt_uint8_t *)stk;
+}
+
+/*@}*/
diff --git a/libcpu/arm/lpc214x/start_rvds.s b/libcpu/arm/lpc214x/start_rvds.s
new file mode 100644
index 0000000000..9d603a4709
--- /dev/null
+++ b/libcpu/arm/lpc214x/start_rvds.s
@@ -0,0 +1,508 @@
+;/*****************************************************************************/
+;/* 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_interrput_flag
+ IMPORT rt_interrupt_from_thread
+ IMPORT rt_interrupt_to_thread
+ IMPORT rt_hw_trap_irq
+
+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_interrput_flag set, jump to
+ ; rt_hw_context_switch_interrupt_do and don't return
+ LDR r0, =rt_thread_switch_interrput_flag
+ LDR r1, [r0]
+ CMP r1, #1
+ BEQ rt_hw_context_switch_interrupt_do
+
+ LDMFD sp!, {r0-r12,lr}
+ SUBS pc, lr, #4
+ 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|F_Bit|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
+ MRS r4, spsr
+ STMFD sp!, {r4} ; push old task's spsr
+
+ 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 spsr
+ MSR spsr_cxsf, r4
+ LDMFD sp!, {r4} ; pop new task's psr
+ MSR cpsr_cxsf, r4
+
+ LDMFD sp!, {r0-r12,lr,pc} ; pop new task's r0-r12,lr & pc
+ 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
diff --git a/libcpu/arm/lpc214x/startup_gcc.S b/libcpu/arm/lpc214x/startup_gcc.S
new file mode 100644
index 0000000000..f14bec39ae
--- /dev/null
+++ b/libcpu/arm/lpc214x/startup_gcc.S
@@ -0,0 +1,350 @@
+ .extern main /* �����ⲿC��� */
+
+ .extern __bss_beg__
+ .extern __bss_end__
+ .extern __stack_end__
+ .extern __data_beg__
+ .extern __data_end__
+ .extern __data+beg_src__
+
+ .extern rt_interrupt_enter
+ .extern rt_interrupt_leave
+ .extern rt_thread_switch_interrput_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
+
+/************* Ŀ������ *************/
+ .set UND_STACK_SIZE, 0x00000004
+ .set ABT_STACK_SIZE, 0x00000004
+ .set FIQ_STACK_SIZE, 0x00000004
+ .set IRQ_STACK_SIZE, 0x00000400
+ .set SVC_STACK_SIZE, 0x00000400
+
+ .set UND_Stack_Size, 0x00000004
+ .set ABT_Stack_Size, 0x00000004
+ .set FIQ_Stack_Size, 0x00000004
+ .set IRQ_Stack_Size, 0x00000400
+ .set SVC_Stack_Size, 0x00000400
+
+ /* 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 */
+ .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
+ .equ PLLCON_OFS, 0x00
+ .equ PLLCFG_OFS, 0x04
+ .equ PLLSTAT_OFS, 0x08
+ .equ PLLFEED_OFS, 0x0C
+
+ .equ PLLCON_PLLE, (1<<0) /* PLL Enable */
+ .equ PLLCON_PLLC, (1<<1) /* PLL Connect */
+ .equ PLLSTAT_LOCK, (1<<10) /* PLL Lock Status */
+ .equ PLLCFG_MSEL, ((PLL_MUL - 1) << 0)
+ .equ PLLCFG_PSEL, (0x02 << 5)
+ .equ PLLCFG_Val, (PLLCFG_MSEL|PLLCFG_PSEL)
+
+ .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 _start, start, _reset, reset,
+ .func _start,
+
+_start:
+start:
+_reset:
+reset:
+ .code 32
+ .align 0
+
+/************************* PLL_SETUP **********************************/
+#if (PLL_MUL>1)
+
+ 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_LOCK
+ 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]
+
+#endif
+/************************* 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, .LC6 /* LC6:__stack_end__ */
+ msr CPSR_c, #MODE_UND|I_BIT|F_BIT /* Undefined Instruction Mode */
+ mov sp, r0
+ sub r0, r0, #UND_STACK_SIZE
+ msr CPSR_c, #MODE_ABT|I_BIT|F_BIT /* Abort Mode */
+ mov sp, r0
+ sub r0, r0, #ABT_STACK_SIZE
+ msr CPSR_c, #MODE_FIQ|I_BIT|F_BIT /* FIQ Mode */
+ mov sp, r0
+ sub r0, r0, #FIQ_STACK_SIZE
+ msr CPSR_c, #MODE_IRQ|I_BIT|F_BIT /* IRQ Mode */
+ mov sp, r0
+ sub r0, r0, #IRQ_STACK_SIZE
+ msr CPSR_c, #MODE_SVC|I_BIT|F_BIT /* Supervisor Mode */
+ mov sp, r0
+/************************ setup stack ********************************/
+
+/************************ Clear BSS ********************************/
+ /* Clear BSS. */
+
+ mov a2, #0 /* Fill value */
+ mov fp, a2 /* Null frame pointer */
+ mov r7, a2 /* Null frame pointer for Thumb */
+
+ ldr r1, .LC1 /* Start of memory block */
+ ldr r3, .LC2 /* End of memory block */
+ subs r3, r3, r1 /* Length of block */
+ beq .end_clear_loop
+ mov r2, #0
+
+.clear_loop:
+ strb r2, [r1], #1
+ subs r3, r3, #1
+ bgt .clear_loop
+
+.end_clear_loop:
+
+ /* Initialise data. */
+
+ ldr r1, .LC3 /* Start of memory block */
+ ldr r2, .LC4 /* End of memory block */
+ ldr r3, .LC5
+ subs r3, r3, r1 /* Length of block */
+ beq .end_set_loop
+
+.set_loop:
+ ldrb r4, [r2], #1
+ strb r4, [r1], #1
+ subs r3, r3, #1
+ bgt .set_loop
+
+.end_set_loop:
+
+ mov r0, #0 /* no arguments */
+ mov r1, #0 /* no argv either */
+
+ bl main
+
+endless_loop:
+ b endless_loop
+
+ .align 0
+
+ .LC1:
+ .word __bss_beg__
+ .LC2:
+ .word __bss_end__
+ .LC3:
+ .word __data_beg__
+ .LC4:
+ .word __data_beg_src__
+ .LC5:
+ .word __data_end__
+ .LC6:
+ .word __stack_end__
+/*********************** END Clear BSS ******************************/
+
+/******************** ��ת�� main() ********************/
+ LDR R0, =main /* ���main()��ڵ�ַ */
+ BX R0 /* ����ת��main() */
+/******************** ��ת�� main() ********************/
+
+
+/* ����Ϊ.startup�� �����ӽű��б����ӵ������ͷ */
+.section .startup,"ax"
+ .code 32
+ .align 0
+
+ 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 0xB9205F80 /* Ĭ�� 0xB9205F80 */
+ .word 0xB8A06F58 /* 0xB8A06F58 ȫΪ */
+ ldr pc, __IRQ_Handler /* IRQ - read the VIC */
+ ldr pc, _fiq /* FIQ - _fiq */
+
+__start:.word _start
+_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 �C R12��LR�Ĵ���ѹջ */
+ bl rt_interrupt_enter /* ֪ͨRT-Thread�����ж�ģʽ */
+ bl rt_hw_trap_irq /* ��Ӧ�жϷ������̴��� */
+ bl rt_interrupt_leave /* ; ֪ͨRT-ThreadҪ�뿪�ж�ģʽ */
+
+ /* ���������rt_thread_switch_interrput_flag�������ж��е��߳������Ĵ��� */
+ ldr r0, =rt_thread_switch_interrput_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 �C 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 �����ж�ǰ��CPSR��R3�Ĵ��� */
+ /* ���SPSR�Ĵ���ֵ */
+ orr r0, r3, #I_BIT|F_BIT
+ msr spsr_c, r0 /* �ر�SPSR�е�IRQ/FIQ�ж� */
+
+ ldr r0, =.+8 /* �ѵ�ǰ��ַ+8���뵽R0�Ĵ����� switch to interrupted task's stack */
+ movs pc, r0 /* �˳�IRQģʽ������SPSR�����óɹ��ж�ģʽ */
+ /* ���Դ�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 �C R12��LR�Ĵ��� */
+ mov r4, r1 /* Special optimised code below */
+ /* R1������ѹջR0 �C R3����ջλ�� */
+ mov r5, r3 /* R3�л����̵߳�CPSR */
+ ldmfd r4!, {r0-r3} /* �ָ�R0 �C R3 */
+ stmfd sp!, {r0-r3} /* push old task's r3-r0 */
+ /* R0 �C 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 �C R12��LR��PC�Ĵ��� */
+
+/* ������ܹ��� */
+#if defined(CODE_PROTECTION)
+.org 0x01FC
+.word 0x87654321
+#endif
+
diff --git a/libcpu/arm/lpc214x/trap.c b/libcpu/arm/lpc214x/trap.c
new file mode 100644
index 0000000000..e0237e8b25
--- /dev/null
+++ b/libcpu/arm/lpc214x/trap.c
@@ -0,0 +1,40 @@
+/*
+ * File : trap.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2006-08-25 Bernard first version
+ */
+
+#include <rthw.h>
+#include <rtthread.h>
+#include "lpc214x.h"
+
+/**
+ * @addtogroup LPC214x
+ */
+/*@{*/
+
+void rt_hw_trap_irq()
+{
+ rt_isr_handler_t isr_func;
+
+ isr_func = (rt_isr_handler_t) VICVectAddr;
+ isr_func(0);
+
+ /* acknowledge Interrupt */
+ // VICVectAddr = 0;
+}
+
+void rt_hw_trap_fiq()
+{
+ rt_kprintf("fast interrupt request\n");
+}
+
+/*@}*/
diff --git a/libcpu/arm/lpc24xx/LPC24xx.h b/libcpu/arm/lpc24xx/LPC24xx.h
new file mode 100644
index 0000000000..01cbeec669
--- /dev/null
+++ b/libcpu/arm/lpc24xx/LPC24xx.h
@@ -0,0 +1,1201 @@
+/*
+ * File : LPC2478.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Develop Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2008-12-11 xuxinming first version
+ */
+
+#ifndef __LPC24xx_H
+#define __LPC24xx_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define USERMODE 0x10
+#define FIQMODE 0x11
+#define IRQMODE 0x12
+#define SVCMODE 0x13
+#define ABORTMODE 0x17
+#define UNDEFMODE 0x1b
+#define MODEMASK 0x1f
+#define NOINT 0xc0
+
+#define MCLK (72000000)
+
+/* Vectored Interrupt Controller (VIC) */
+#define VIC_BASE_ADDR 0xFFFFF000
+#define VICIRQStatus (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x000))
+#define VICFIQStatus (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x004))
+#define VICRawIntr (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x008))
+#define VICIntSelect (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x00C))
+#define VICIntEnable (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x010))
+#define VICIntEnClr (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x014))
+#define VICSoftInt (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x018))
+#define VICSoftIntClr (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x01C))
+#define VICProtection (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x020))
+#define VICSWPrioMask (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x024))
+
+#define VICVectAddr0 (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x100))
+#define VICVectAddr1 (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x104))
+#define VICVectAddr2 (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x108))
+#define VICVectAddr3 (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x10C))
+#define VICVectAddr4 (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x110))
+#define VICVectAddr5 (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x114))
+#define VICVectAddr6 (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x118))
+#define VICVectAddr7 (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x11C))
+#define VICVectAddr8 (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x120))
+#define VICVectAddr9 (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x124))
+#define VICVectAddr10 (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x128))
+#define VICVectAddr11 (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x12C))
+#define VICVectAddr12 (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x130))
+#define VICVectAddr13 (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x134))
+#define VICVectAddr14 (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x138))
+#define VICVectAddr15 (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x13C))
+#define VICVectAddr16 (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x140))
+#define VICVectAddr17 (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x144))
+#define VICVectAddr18 (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x148))
+#define VICVectAddr19 (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x14C))
+#define VICVectAddr20 (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x150))
+#define VICVectAddr21 (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x154))
+#define VICVectAddr22 (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x158))
+#define VICVectAddr23 (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x15C))
+#define VICVectAddr24 (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x160))
+#define VICVectAddr25 (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x164))
+#define VICVectAddr26 (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x168))
+#define VICVectAddr27 (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x16C))
+#define VICVectAddr28 (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x170))
+#define VICVectAddr29 (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x174))
+#define VICVectAddr30 (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x178))
+#define VICVectAddr31 (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x17C))
+
+/* The name convention below is from previous LPC2000 family MCUs, in LPC23xx/24xx,
+these registers are known as "VICVectPriority(x)". */
+#define VICVectCntl0 (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x200))
+#define VICVectCntl1 (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x204))
+#define VICVectCntl2 (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x208))
+#define VICVectCntl3 (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x20C))
+#define VICVectCntl4 (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x210))
+#define VICVectCntl5 (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x214))
+#define VICVectCntl6 (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x218))
+#define VICVectCntl7 (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x21C))
+#define VICVectCntl8 (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x220))
+#define VICVectCntl9 (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x224))
+#define VICVectCntl10 (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x228))
+#define VICVectCntl11 (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x22C))
+#define VICVectCntl12 (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x230))
+#define VICVectCntl13 (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x234))
+#define VICVectCntl14 (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x238))
+#define VICVectCntl15 (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x23C))
+#define VICVectCntl16 (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x240))
+#define VICVectCntl17 (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x244))
+#define VICVectCntl18 (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x248))
+#define VICVectCntl19 (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x24C))
+#define VICVectCntl20 (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x250))
+#define VICVectCntl21 (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x254))
+#define VICVectCntl22 (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x258))
+#define VICVectCntl23 (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x25C))
+#define VICVectCntl24 (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x260))
+#define VICVectCntl25 (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x264))
+#define VICVectCntl26 (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x268))
+#define VICVectCntl27 (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x26C))
+#define VICVectCntl28 (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x270))
+#define VICVectCntl29 (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x274))
+#define VICVectCntl30 (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x278))
+#define VICVectCntl31 (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x27C))
+
+#define VICVectAddr (*(volatile unsigned long *)(VIC_BASE_ADDR + 0xF00))
+
+
+/* Pin Connect Block */
+#define PINSEL_BASE_ADDR 0xE002C000
+#define PINSEL0 (*(volatile unsigned long *)(PINSEL_BASE_ADDR + 0x00))
+#define PINSEL1 (*(volatile unsigned long *)(PINSEL_BASE_ADDR + 0x04))
+#define PINSEL2 (*(volatile unsigned long *)(PINSEL_BASE_ADDR + 0x08))
+#define PINSEL3 (*(volatile unsigned long *)(PINSEL_BASE_ADDR + 0x0C))
+#define PINSEL4 (*(volatile unsigned long *)(PINSEL_BASE_ADDR + 0x10))
+#define PINSEL5 (*(volatile unsigned long *)(PINSEL_BASE_ADDR + 0x14))
+#define PINSEL6 (*(volatile unsigned long *)(PINSEL_BASE_ADDR + 0x18))
+#define PINSEL7 (*(volatile unsigned long *)(PINSEL_BASE_ADDR + 0x1C))
+#define PINSEL8 (*(volatile unsigned long *)(PINSEL_BASE_ADDR + 0x20))
+#define PINSEL9 (*(volatile unsigned long *)(PINSEL_BASE_ADDR + 0x24))
+#define PINSEL10 (*(volatile unsigned long *)(PINSEL_BASE_ADDR + 0x28))
+#define PINSEL11 (*(volatile unsigned long *)(PINSEL_BASE_ADDR + 0x2C))
+
+#define PINMODE0 (*(volatile unsigned long *)(PINSEL_BASE_ADDR + 0x40))
+#define PINMODE1 (*(volatile unsigned long *)(PINSEL_BASE_ADDR + 0x44))
+#define PINMODE2 (*(volatile unsigned long *)(PINSEL_BASE_ADDR + 0x48))
+#define PINMODE3 (*(volatile unsigned long *)(PINSEL_BASE_ADDR + 0x4C))
+#define PINMODE4 (*(volatile unsigned long *)(PINSEL_BASE_ADDR + 0x50))
+#define PINMODE5 (*(volatile unsigned long *)(PINSEL_BASE_ADDR + 0x54))
+#define PINMODE6 (*(volatile unsigned long *)(PINSEL_BASE_ADDR + 0x58))
+#define PINMODE7 (*(volatile unsigned long *)(PINSEL_BASE_ADDR + 0x5C))
+#define PINMODE8 (*(volatile unsigned long *)(PINSEL_BASE_ADDR + 0x60))
+#define PINMODE9 (*(volatile unsigned long *)(PINSEL_BASE_ADDR + 0x64))
+
+/* General Purpose Input/Output (GPIO) */
+#define GPIO_BASE_ADDR 0xE0028000
+#define IOPIN0 (*(volatile unsigned long *)(GPIO_BASE_ADDR + 0x00))
+#define IOSET0 (*(volatile unsigned long *)(GPIO_BASE_ADDR + 0x04))
+#define IODIR0 (*(volatile unsigned long *)(GPIO_BASE_ADDR + 0x08))
+#define IOCLR0 (*(volatile unsigned long *)(GPIO_BASE_ADDR + 0x0C))
+#define IOPIN1 (*(volatile unsigned long *)(GPIO_BASE_ADDR + 0x10))
+#define IOSET1 (*(volatile unsigned long *)(GPIO_BASE_ADDR + 0x14))
+#define IODIR1 (*(volatile unsigned long *)(GPIO_BASE_ADDR + 0x18))
+#define IOCLR1 (*(volatile unsigned long *)(GPIO_BASE_ADDR + 0x1C))
+
+/* GPIO Interrupt Registers */
+#define IO0_INT_EN_R (*(volatile unsigned long *)(GPIO_BASE_ADDR + 0x90))
+#define IO0_INT_EN_F (*(volatile unsigned long *)(GPIO_BASE_ADDR + 0x94))
+#define IO0_INT_STAT_R (*(volatile unsigned long *)(GPIO_BASE_ADDR + 0x84))
+#define IO0_INT_STAT_F (*(volatile unsigned long *)(GPIO_BASE_ADDR + 0x88))
+#define IO0_INT_CLR (*(volatile unsigned long *)(GPIO_BASE_ADDR + 0x8C))
+
+#define IO2_INT_EN_R (*(volatile unsigned long *)(GPIO_BASE_ADDR + 0xB0))
+#define IO2_INT_EN_F (*(volatile unsigned long *)(GPIO_BASE_ADDR + 0xB4))
+#define IO2_INT_STAT_R (*(volatile unsigned long *)(GPIO_BASE_ADDR + 0xA4))
+#define IO2_INT_STAT_F (*(volatile unsigned long *)(GPIO_BASE_ADDR + 0xA8))
+#define IO2_INT_CLR (*(volatile unsigned long *)(GPIO_BASE_ADDR + 0xAC))
+
+#define IO_INT_STAT (*(volatile unsigned long *)(GPIO_BASE_ADDR + 0x80))
+
+#define PARTCFG_BASE_ADDR 0x3FFF8000
+#define PARTCFG (*(volatile unsigned long *)(PARTCFG_BASE_ADDR + 0x00))
+
+/* Fast I/O setup */
+#define FIO_BASE_ADDR 0x3FFFC000
+#define FIO0DIR (*(volatile unsigned long *)(FIO_BASE_ADDR + 0x00))
+#define FIO0MASK (*(volatile unsigned long *)(FIO_BASE_ADDR + 0x10))
+#define FIO0PIN (*(volatile unsigned long *)(FIO_BASE_ADDR + 0x14))
+#define FIO0SET (*(volatile unsigned long *)(FIO_BASE_ADDR + 0x18))
+#define FIO0CLR (*(volatile unsigned long *)(FIO_BASE_ADDR + 0x1C))
+
+#define FIO1DIR (*(volatile unsigned long *)(FIO_BASE_ADDR + 0x20))
+#define FIO1MASK (*(volatile unsigned long *)(FIO_BASE_ADDR + 0x30))
+#define FIO1PIN (*(volatile unsigned long *)(FIO_BASE_ADDR + 0x34))
+#define FIO1SET (*(volatile unsigned long *)(FIO_BASE_ADDR + 0x38))
+#define FIO1CLR (*(volatile unsigned long *)(FIO_BASE_ADDR + 0x3C))
+
+#define FIO2DIR (*(volatile unsigned long *)(FIO_BASE_ADDR + 0x40))
+#define FIO2MASK (*(volatile unsigned long *)(FIO_BASE_ADDR + 0x50))
+#define FIO2PIN (*(volatile unsigned long *)(FIO_BASE_ADDR + 0x54))
+#define FIO2SET (*(volatile unsigned long *)(FIO_BASE_ADDR + 0x58))
+#define FIO2CLR (*(volatile unsigned long *)(FIO_BASE_ADDR + 0x5C))
+
+#define FIO3DIR (*(volatile unsigned long *)(FIO_BASE_ADDR + 0x60))
+#define FIO3MASK (*(volatile unsigned long *)(FIO_BASE_ADDR + 0x70))
+#define FIO3PIN (*(volatile unsigned long *)(FIO_BASE_ADDR + 0x74))
+#define FIO3SET (*(volatile unsigned long *)(FIO_BASE_ADDR + 0x78))
+#define FIO3CLR (*(volatile unsigned long *)(FIO_BASE_ADDR + 0x7C))
+
+#define FIO4DIR (*(volatile unsigned long *)(FIO_BASE_ADDR + 0x80))
+#define FIO4MASK (*(volatile unsigned long *)(FIO_BASE_ADDR + 0x90))
+#define FIO4PIN (*(volatile unsigned long *)(FIO_BASE_ADDR + 0x94))
+#define FIO4SET (*(volatile unsigned long *)(FIO_BASE_ADDR + 0x98))
+#define FIO4CLR (*(volatile unsigned long *)(FIO_BASE_ADDR + 0x9C))
+
+/* FIOs can be accessed through WORD, HALF-WORD or BYTE. */
+#define FIO0DIR0 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x00))
+#define FIO1DIR0 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x20))
+#define FIO2DIR0 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x40))
+#define FIO3DIR0 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x60))
+#define FIO4DIR0 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x80))
+
+#define FIO0DIR1 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x01))
+#define FIO1DIR1 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x21))
+#define FIO2DIR1 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x41))
+#define FIO3DIR1 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x61))
+#define FIO4DIR1 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x81))
+
+#define FIO0DIR2 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x02))
+#define FIO1DIR2 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x22))
+#define FIO2DIR2 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x42))
+#define FIO3DIR2 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x62))
+#define FIO4DIR2 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x82))
+
+#define FIO0DIR3 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x03))
+#define FIO1DIR3 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x23))
+#define FIO2DIR3 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x43))
+#define FIO3DIR3 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x63))
+#define FIO4DIR3 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x83))
+
+#define FIO0DIRL (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x00))
+#define FIO1DIRL (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x20))
+#define FIO2DIRL (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x40))
+#define FIO3DIRL (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x60))
+#define FIO4DIRL (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x80))
+
+#define FIO0DIRU (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x02))
+#define FIO1DIRU (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x22))
+#define FIO2DIRU (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x42))
+#define FIO3DIRU (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x62))
+#define FIO4DIRU (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x82))
+
+#define FIO0MASK0 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x10))
+#define FIO1MASK0 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x30))
+#define FIO2MASK0 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x50))
+#define FIO3MASK0 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x70))
+#define FIO4MASK0 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x90))
+
+#define FIO0MASK1 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x11))
+#define FIO1MASK1 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x21))
+#define FIO2MASK1 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x51))
+#define FIO3MASK1 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x71))
+#define FIO4MASK1 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x91))
+
+#define FIO0MASK2 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x12))
+#define FIO1MASK2 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x32))
+#define FIO2MASK2 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x52))
+#define FIO3MASK2 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x72))
+#define FIO4MASK2 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x92))
+
+#define FIO0MASK3 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x13))
+#define FIO1MASK3 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x33))
+#define FIO2MASK3 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x53))
+#define FIO3MASK3 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x73))
+#define FIO4MASK3 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x93))
+
+#define FIO0MASKL (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x10))
+#define FIO1MASKL (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x30))
+#define FIO2MASKL (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x50))
+#define FIO3MASKL (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x70))
+#define FIO4MASKL (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x90))
+
+#define FIO0MASKU (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x12))
+#define FIO1MASKU (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x32))
+#define FIO2MASKU (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x52))
+#define FIO3MASKU (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x72))
+#define FIO4MASKU (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x92))
+
+#define FIO0PIN0 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x14))
+#define FIO1PIN0 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x34))
+#define FIO2PIN0 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x54))
+#define FIO3PIN0 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x74))
+#define FIO4PIN0 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x94))
+
+#define FIO0PIN1 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x15))
+#define FIO1PIN1 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x35))
+#define FIO2PIN1 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x55))
+#define FIO3PIN1 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x75))
+#define FIO4PIN1 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x95))
+
+#define FIO0PIN2 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x16))
+#define FIO1PIN2 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x36))
+#define FIO2PIN2 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x56))
+#define FIO3PIN2 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x76))
+#define FIO4PIN2 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x96))
+
+#define FIO0PIN3 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x17))
+#define FIO1PIN3 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x37))
+#define FIO2PIN3 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x57))
+#define FIO3PIN3 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x77))
+#define FIO4PIN3 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x97))
+
+#define FIO0PINL (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x14))
+#define FIO1PINL (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x34))
+#define FIO2PINL (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x54))
+#define FIO3PINL (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x74))
+#define FIO4PINL (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x94))
+
+#define FIO0PINU (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x16))
+#define FIO1PINU (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x36))
+#define FIO2PINU (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x56))
+#define FIO3PINU (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x76))
+#define FIO4PINU (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x96))
+
+#define FIO0SET0 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x18))
+#define FIO1SET0 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x38))
+#define FIO2SET0 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x58))
+#define FIO3SET0 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x78))
+#define FIO4SET0 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x98))
+
+#define FIO0SET1 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x19))
+#define FIO1SET1 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x29))
+#define FIO2SET1 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x59))
+#define FIO3SET1 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x79))
+#define FIO4SET1 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x99))
+
+#define FIO0SET2 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x1A))
+#define FIO1SET2 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x3A))
+#define FIO2SET2 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x5A))
+#define FIO3SET2 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x7A))
+#define FIO4SET2 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x9A))
+
+#define FIO0SET3 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x1B))
+#define FIO1SET3 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x3B))
+#define FIO2SET3 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x5B))
+#define FIO3SET3 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x7B))
+#define FIO4SET3 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x9B))
+
+#define FIO0SETL (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x18))
+#define FIO1SETL (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x38))
+#define FIO2SETL (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x58))
+#define FIO3SETL (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x78))
+#define FIO4SETL (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x98))
+
+#define FIO0SETU (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x1A))
+#define FIO1SETU (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x3A))
+#define FIO2SETU (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x5A))
+#define FIO3SETU (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x7A))
+#define FIO4SETU (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x9A))
+
+#define FIO0CLR0 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x1C))
+#define FIO1CLR0 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x3C))
+#define FIO2CLR0 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x5C))
+#define FIO3CLR0 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x7C))
+#define FIO4CLR0 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x9C))
+
+#define FIO0CLR1 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x1D))
+#define FIO1CLR1 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x2D))
+#define FIO2CLR1 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x5D))
+#define FIO3CLR1 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x7D))
+#define FIO4CLR1 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x9D))
+
+#define FIO0CLR2 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x1E))
+#define FIO1CLR2 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x3E))
+#define FIO2CLR2 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x5E))
+#define FIO3CLR2 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x7E))
+#define FIO4CLR2 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x9E))
+
+#define FIO0CLR3 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x1F))
+#define FIO1CLR3 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x3F))
+#define FIO2CLR3 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x5F))
+#define FIO3CLR3 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x7F))
+#define FIO4CLR3 (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x9F))
+
+#define FIO0CLRL (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x1C))
+#define FIO1CLRL (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x3C))
+#define FIO2CLRL (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x5C))
+#define FIO3CLRL (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x7C))
+#define FIO4CLRL (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x9C))
+
+#define FIO0CLRU (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x1E))
+#define FIO1CLRU (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x3E))
+#define FIO2CLRU (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x5E))
+#define FIO3CLRU (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x7E))
+#define FIO4CLRU (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x9E))
+
+
+/* System Control Block(SCB) modules include Memory Accelerator Module,
+Phase Locked Loop, VPB divider, Power Control, External Interrupt,
+Reset, and Code Security/Debugging */
+#define SCB_BASE_ADDR 0xE01FC000
+
+/* Memory Accelerator Module (MAM) */
+#define MAMCR (*(volatile unsigned long *)(SCB_BASE_ADDR + 0x000))
+#define MAMTIM (*(volatile unsigned long *)(SCB_BASE_ADDR + 0x004))
+#define MEMMAP (*(volatile unsigned long *)(SCB_BASE_ADDR + 0x040))
+
+/* Phase Locked Loop (PLL) */
+#define PLLCON (*(volatile unsigned long *)(SCB_BASE_ADDR + 0x080))
+#define PLLCFG (*(volatile unsigned long *)(SCB_BASE_ADDR + 0x084))
+#define PLLSTAT (*(volatile unsigned long *)(SCB_BASE_ADDR + 0x088))
+#define PLLFEED (*(volatile unsigned long *)(SCB_BASE_ADDR + 0x08C))
+
+/* Power Control */
+#define PCON (*(volatile unsigned long *)(SCB_BASE_ADDR + 0x0C0))
+#define PCONP (*(volatile unsigned long *)(SCB_BASE_ADDR + 0x0C4))
+
+/* Clock Divider */
+#define CCLKCFG (*(volatile unsigned long *)(SCB_BASE_ADDR + 0x104))
+#define USBCLKCFG (*(volatile unsigned long *)(SCB_BASE_ADDR + 0x108))
+#define CLKSRCSEL (*(volatile unsigned long *)(SCB_BASE_ADDR + 0x10C))
+#define PCLKSEL0 (*(volatile unsigned long *)(SCB_BASE_ADDR + 0x1A8))
+#define PCLKSEL1 (*(volatile unsigned long *)(SCB_BASE_ADDR + 0x1AC))
+
+/* External Interrupts */
+#define EXTINT (*(volatile unsigned long *)(SCB_BASE_ADDR + 0x140))
+#define INTWAKE (*(volatile unsigned long *)(SCB_BASE_ADDR + 0x144))
+#define EXTMODE (*(volatile unsigned long *)(SCB_BASE_ADDR + 0x148))
+#define EXTPOLAR (*(volatile unsigned long *)(SCB_BASE_ADDR + 0x14C))
+
+/* Reset, reset source identification */
+#define RSIR (*(volatile unsigned long *)(SCB_BASE_ADDR + 0x180))
+
+/* RSID, code security protection */
+#define CSPR (*(volatile unsigned long *)(SCB_BASE_ADDR + 0x184))
+
+/* AHB configuration */
+#define AHBCFG1 (*(volatile unsigned long *)(SCB_BASE_ADDR + 0x188))
+#define AHBCFG2 (*(volatile unsigned long *)(SCB_BASE_ADDR + 0x18C))
+
+/* System Controls and Status */
+#define SCS (*(volatile unsigned long *)(SCB_BASE_ADDR + 0x1A0))
+
+/* MPMC(EMC) registers, note: all the external memory controller(EMC) registers
+are for LPC24xx only. */
+#define STATIC_MEM0_BASE 0x80000000
+#define STATIC_MEM1_BASE 0x81000000
+#define STATIC_MEM2_BASE 0x82000000
+#define STATIC_MEM3_BASE 0x83000000
+
+#define DYNAMIC_MEM0_BASE 0xA0000000
+#define DYNAMIC_MEM1_BASE 0xB0000000
+#define DYNAMIC_MEM2_BASE 0xC0000000
+#define DYNAMIC_MEM3_BASE 0xD0000000
+
+/* External Memory Controller (EMC) */
+#define EMC_BASE_ADDR 0xFFE08000
+#define EMC_CTRL (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x000))
+#define EMC_STAT (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x004))
+#define EMC_CONFIG (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x008))
+
+/* Dynamic RAM access registers */
+#define EMC_DYN_CTRL (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x020))
+#define EMC_DYN_RFSH (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x024))
+#define EMC_DYN_RD_CFG (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x028))
+#define EMC_DYN_RP (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x030))
+#define EMC_DYN_RAS (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x034))
+#define EMC_DYN_SREX (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x038))
+#define EMC_DYN_APR (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x03C))
+#define EMC_DYN_DAL (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x040))
+#define EMC_DYN_WR (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x044))
+#define EMC_DYN_RC (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x048))
+#define EMC_DYN_RFC (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x04C))
+#define EMC_DYN_XSR (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x050))
+#define EMC_DYN_RRD (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x054))
+#define EMC_DYN_MRD (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x058))
+
+#define EMC_DYN_CFG0 (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x100))
+#define EMC_DYN_RASCAS0 (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x104))
+#define EMC_DYN_CFG1 (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x140))
+#define EMC_DYN_RASCAS1 (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x144))
+#define EMC_DYN_CFG2 (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x160))
+#define EMC_DYN_RASCAS2 (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x164))
+#define EMC_DYN_CFG3 (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x180))
+#define EMC_DYN_RASCAS3 (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x184))
+
+/* static RAM access registers */
+#define EMC_STA_CFG0 (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x200))
+#define EMC_STA_WAITWEN0 (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x204))
+#define EMC_STA_WAITOEN0 (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x208))
+#define EMC_STA_WAITRD0 (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x20C))
+#define EMC_STA_WAITPAGE0 (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x210))
+#define EMC_STA_WAITWR0 (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x214))
+#define EMC_STA_WAITTURN0 (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x218))
+
+#define EMC_STA_CFG1 (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x220))
+#define EMC_STA_WAITWEN1 (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x224))
+#define EMC_STA_WAITOEN1 (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x228))
+#define EMC_STA_WAITRD1 (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x22C))
+#define EMC_STA_WAITPAGE1 (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x230))
+#define EMC_STA_WAITWR1 (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x234))
+#define EMC_STA_WAITTURN1 (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x238))
+
+#define EMC_STA_CFG2 (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x240))
+#define EMC_STA_WAITWEN2 (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x244))
+#define EMC_STA_WAITOEN2 (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x248))
+#define EMC_STA_WAITRD2 (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x24C))
+#define EMC_STA_WAITPAGE2 (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x250))
+#define EMC_STA_WAITWR2 (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x254))
+#define EMC_STA_WAITTURN2 (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x258))
+
+#define EMC_STA_CFG3 (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x260))
+#define EMC_STA_WAITWEN3 (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x264))
+#define EMC_STA_WAITOEN3 (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x268))
+#define EMC_STA_WAITRD3 (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x26C))
+#define EMC_STA_WAITPAGE3 (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x270))
+#define EMC_STA_WAITWR3 (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x274))
+#define EMC_STA_WAITTURN3 (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x278))
+
+#define EMC_STA_EXT_WAIT (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x880))
+
+
+/* Timer 0 */
+#define TMR0_BASE_ADDR 0xE0004000
+#define T0IR (*(volatile unsigned long *)(TMR0_BASE_ADDR + 0x00))
+#define T0TCR (*(volatile unsigned long *)(TMR0_BASE_ADDR + 0x04))
+#define T0TC (*(volatile unsigned long *)(TMR0_BASE_ADDR + 0x08))
+#define T0PR (*(volatile unsigned long *)(TMR0_BASE_ADDR + 0x0C))
+#define T0PC (*(volatile unsigned long *)(TMR0_BASE_ADDR + 0x10))
+#define T0MCR (*(volatile unsigned long *)(TMR0_BASE_ADDR + 0x14))
+#define T0MR0 (*(volatile unsigned long *)(TMR0_BASE_ADDR + 0x18))
+#define T0MR1 (*(volatile unsigned long *)(TMR0_BASE_ADDR + 0x1C))
+#define T0MR2 (*(volatile unsigned long *)(TMR0_BASE_ADDR + 0x20))
+#define T0MR3 (*(volatile unsigned long *)(TMR0_BASE_ADDR + 0x24))
+#define T0CCR (*(volatile unsigned long *)(TMR0_BASE_ADDR + 0x28))
+#define T0CR0 (*(volatile unsigned long *)(TMR0_BASE_ADDR + 0x2C))
+#define T0CR1 (*(volatile unsigned long *)(TMR0_BASE_ADDR + 0x30))
+#define T0CR2 (*(volatile unsigned long *)(TMR0_BASE_ADDR + 0x34))
+#define T0CR3 (*(volatile unsigned long *)(TMR0_BASE_ADDR + 0x38))
+#define T0EMR (*(volatile unsigned long *)(TMR0_BASE_ADDR + 0x3C))
+#define T0CTCR (*(volatile unsigned long *)(TMR0_BASE_ADDR + 0x70))
+
+/* Timer 1 */
+#define TMR1_BASE_ADDR 0xE0008000
+#define T1IR (*(volatile unsigned long *)(TMR1_BASE_ADDR + 0x00))
+#define T1TCR (*(volatile unsigned long *)(TMR1_BASE_ADDR + 0x04))
+#define T1TC (*(volatile unsigned long *)(TMR1_BASE_ADDR + 0x08))
+#define T1PR (*(volatile unsigned long *)(TMR1_BASE_ADDR + 0x0C))
+#define T1PC (*(volatile unsigned long *)(TMR1_BASE_ADDR + 0x10))
+#define T1MCR (*(volatile unsigned long *)(TMR1_BASE_ADDR + 0x14))
+#define T1MR0 (*(volatile unsigned long *)(TMR1_BASE_ADDR + 0x18))
+#define T1MR1 (*(volatile unsigned long *)(TMR1_BASE_ADDR + 0x1C))
+#define T1MR2 (*(volatile unsigned long *)(TMR1_BASE_ADDR + 0x20))
+#define T1MR3 (*(volatile unsigned long *)(TMR1_BASE_ADDR + 0x24))
+#define T1CCR (*(volatile unsigned long *)(TMR1_BASE_ADDR + 0x28))
+#define T1CR0 (*(volatile unsigned long *)(TMR1_BASE_ADDR + 0x2C))
+#define T1CR1 (*(volatile unsigned long *)(TMR1_BASE_ADDR + 0x30))
+#define T1CR2 (*(volatile unsigned long *)(TMR1_BASE_ADDR + 0x34))
+#define T1CR3 (*(volatile unsigned long *)(TMR1_BASE_ADDR + 0x38))
+#define T1EMR (*(volatile unsigned long *)(TMR1_BASE_ADDR + 0x3C))
+#define T1CTCR (*(volatile unsigned long *)(TMR1_BASE_ADDR + 0x70))
+
+/* Timer 2 */
+#define TMR2_BASE_ADDR 0xE0070000
+#define T2IR (*(volatile unsigned long *)(TMR2_BASE_ADDR + 0x00))
+#define T2TCR (*(volatile unsigned long *)(TMR2_BASE_ADDR + 0x04))
+#define T2TC (*(volatile unsigned long *)(TMR2_BASE_ADDR + 0x08))
+#define T2PR (*(volatile unsigned long *)(TMR2_BASE_ADDR + 0x0C))
+#define T2PC (*(volatile unsigned long *)(TMR2_BASE_ADDR + 0x10))
+#define T2MCR (*(volatile unsigned long *)(TMR2_BASE_ADDR + 0x14))
+#define T2MR0 (*(volatile unsigned long *)(TMR2_BASE_ADDR + 0x18))
+#define T2MR1 (*(volatile unsigned long *)(TMR2_BASE_ADDR + 0x1C))
+#define T2MR2 (*(volatile unsigned long *)(TMR2_BASE_ADDR + 0x20))
+#define T2MR3 (*(volatile unsigned long *)(TMR2_BASE_ADDR + 0x24))
+#define T2CCR (*(volatile unsigned long *)(TMR2_BASE_ADDR + 0x28))
+#define T2CR0 (*(volatile unsigned long *)(TMR2_BASE_ADDR + 0x2C))
+#define T2CR1 (*(volatile unsigned long *)(TMR2_BASE_ADDR + 0x30))
+#define T2CR2 (*(volatile unsigned long *)(TMR2_BASE_ADDR + 0x34))
+#define T2CR3 (*(volatile unsigned long *)(TMR2_BASE_ADDR + 0x38))
+#define T2EMR (*(volatile unsigned long *)(TMR2_BASE_ADDR + 0x3C))
+#define T2CTCR (*(volatile unsigned long *)(TMR2_BASE_ADDR + 0x70))
+
+/* Timer 3 */
+#define TMR3_BASE_ADDR 0xE0074000
+#define T3IR (*(volatile unsigned long *)(TMR3_BASE_ADDR + 0x00))
+#define T3TCR (*(volatile unsigned long *)(TMR3_BASE_ADDR + 0x04))
+#define T3TC (*(volatile unsigned long *)(TMR3_BASE_ADDR + 0x08))
+#define T3PR (*(volatile unsigned long *)(TMR3_BASE_ADDR + 0x0C))
+#define T3PC (*(volatile unsigned long *)(TMR3_BASE_ADDR + 0x10))
+#define T3MCR (*(volatile unsigned long *)(TMR3_BASE_ADDR + 0x14))
+#define T3MR0 (*(volatile unsigned long *)(TMR3_BASE_ADDR + 0x18))
+#define T3MR1 (*(volatile unsigned long *)(TMR3_BASE_ADDR + 0x1C))
+#define T3MR2 (*(volatile unsigned long *)(TMR3_BASE_ADDR + 0x20))
+#define T3MR3 (*(volatile unsigned long *)(TMR3_BASE_ADDR + 0x24))
+#define T3CCR (*(volatile unsigned long *)(TMR3_BASE_ADDR + 0x28))
+#define T3CR0 (*(volatile unsigned long *)(TMR3_BASE_ADDR + 0x2C))
+#define T3CR1 (*(volatile unsigned long *)(TMR3_BASE_ADDR + 0x30))
+#define T3CR2 (*(volatile unsigned long *)(TMR3_BASE_ADDR + 0x34))
+#define T3CR3 (*(volatile unsigned long *)(TMR3_BASE_ADDR + 0x38))
+#define T3EMR (*(volatile unsigned long *)(TMR3_BASE_ADDR + 0x3C))
+#define T3CTCR (*(volatile unsigned long *)(TMR3_BASE_ADDR + 0x70))
+
+
+/* Pulse Width Modulator (PWM) */
+#define PWM0_BASE_ADDR 0xE0014000
+#define PWM0IR (*(volatile unsigned long *)(PWM0_BASE_ADDR + 0x00))
+#define PWM0TCR (*(volatile unsigned long *)(PWM0_BASE_ADDR + 0x04))
+#define PWM0TC (*(volatile unsigned long *)(PWM0_BASE_ADDR + 0x08))
+#define PWM0PR (*(volatile unsigned long *)(PWM0_BASE_ADDR + 0x0C))
+#define PWM0PC (*(volatile unsigned long *)(PWM0_BASE_ADDR + 0x10))
+#define PWM0MCR (*(volatile unsigned long *)(PWM0_BASE_ADDR + 0x14))
+#define PWM0MR0 (*(volatile unsigned long *)(PWM0_BASE_ADDR + 0x18))
+#define PWM0MR1 (*(volatile unsigned long *)(PWM0_BASE_ADDR + 0x1C))
+#define PWM0MR2 (*(volatile unsigned long *)(PWM0_BASE_ADDR + 0x20))
+#define PWM0MR3 (*(volatile unsigned long *)(PWM0_BASE_ADDR + 0x24))
+#define PWM0CCR (*(volatile unsigned long *)(PWM0_BASE_ADDR + 0x28))
+#define PWM0CR0 (*(volatile unsigned long *)(PWM0_BASE_ADDR + 0x2C))
+#define PWM0CR1 (*(volatile unsigned long *)(PWM0_BASE_ADDR + 0x30))
+#define PWM0CR2 (*(volatile unsigned long *)(PWM0_BASE_ADDR + 0x34))
+#define PWM0CR3 (*(volatile unsigned long *)(PWM0_BASE_ADDR + 0x38))
+#define PWM0EMR (*(volatile unsigned long *)(PWM0_BASE_ADDR + 0x3C))
+#define PWM0MR4 (*(volatile unsigned long *)(PWM0_BASE_ADDR + 0x40))
+#define PWM0MR5 (*(volatile unsigned long *)(PWM0_BASE_ADDR + 0x44))
+#define PWM0MR6 (*(volatile unsigned long *)(PWM0_BASE_ADDR + 0x48))
+#define PWM0PCR (*(volatile unsigned long *)(PWM0_BASE_ADDR + 0x4C))
+#define PWM0LER (*(volatile unsigned long *)(PWM0_BASE_ADDR + 0x50))
+#define PWM0CTCR (*(volatile unsigned long *)(PWM0_BASE_ADDR + 0x70))
+
+#define PWM1_BASE_ADDR 0xE0018000
+#define PWM1IR (*(volatile unsigned long *)(PWM1_BASE_ADDR + 0x00))
+#define PWM1TCR (*(volatile unsigned long *)(PWM1_BASE_ADDR + 0x04))
+#define PWM1TC (*(volatile unsigned long *)(PWM1_BASE_ADDR + 0x08))
+#define PWM1PR (*(volatile unsigned long *)(PWM1_BASE_ADDR + 0x0C))
+#define PWM1PC (*(volatile unsigned long *)(PWM1_BASE_ADDR + 0x10))
+#define PWM1MCR (*(volatile unsigned long *)(PWM1_BASE_ADDR + 0x14))
+#define PWM1MR0 (*(volatile unsigned long *)(PWM1_BASE_ADDR + 0x18))
+#define PWM1MR1 (*(volatile unsigned long *)(PWM1_BASE_ADDR + 0x1C))
+#define PWM1MR2 (*(volatile unsigned long *)(PWM1_BASE_ADDR + 0x20))
+#define PWM1MR3 (*(volatile unsigned long *)(PWM1_BASE_ADDR + 0x24))
+#define PWM1CCR (*(volatile unsigned long *)(PWM1_BASE_ADDR + 0x28))
+#define PWM1CR0 (*(volatile unsigned long *)(PWM1_BASE_ADDR + 0x2C))
+#define PWM1CR1 (*(volatile unsigned long *)(PWM1_BASE_ADDR + 0x30))
+#define PWM1CR2 (*(volatile unsigned long *)(PWM1_BASE_ADDR + 0x34))
+#define PWM1CR3 (*(volatile unsigned long *)(PWM1_BASE_ADDR + 0x38))
+#define PWM1EMR (*(volatile unsigned long *)(PWM1_BASE_ADDR + 0x3C))
+#define PWM1MR4 (*(volatile unsigned long *)(PWM1_BASE_ADDR + 0x40))
+#define PWM1MR5 (*(volatile unsigned long *)(PWM1_BASE_ADDR + 0x44))
+#define PWM1MR6 (*(volatile unsigned long *)(PWM1_BASE_ADDR + 0x48))
+#define PWM1PCR (*(volatile unsigned long *)(PWM1_BASE_ADDR + 0x4C))
+#define PWM1LER (*(volatile unsigned long *)(PWM1_BASE_ADDR + 0x50))
+#define PWM1CTCR (*(volatile unsigned long *)(PWM1_BASE_ADDR + 0x70))
+
+
+/* Universal Asynchronous Receiver Transmitter 0 (UART0) */
+#define UART0_BASE_ADDR 0xE000C000
+#define U0RBR (*(volatile unsigned long *)(UART0_BASE_ADDR + 0x00))
+#define U0THR (*(volatile unsigned long *)(UART0_BASE_ADDR + 0x00))
+#define U0DLL (*(volatile unsigned long *)(UART0_BASE_ADDR + 0x00))
+#define U0DLM (*(volatile unsigned long *)(UART0_BASE_ADDR + 0x04))
+#define U0IER (*(volatile unsigned long *)(UART0_BASE_ADDR + 0x04))
+#define U0IIR (*(volatile unsigned long *)(UART0_BASE_ADDR + 0x08))
+#define U0FCR (*(volatile unsigned long *)(UART0_BASE_ADDR + 0x08))
+#define U0LCR (*(volatile unsigned long *)(UART0_BASE_ADDR + 0x0C))
+#define U0LSR (*(volatile unsigned long *)(UART0_BASE_ADDR + 0x14))
+#define U0SCR (*(volatile unsigned long *)(UART0_BASE_ADDR + 0x1C))
+#define U0ACR (*(volatile unsigned long *)(UART0_BASE_ADDR + 0x20))
+#define U0ICR (*(volatile unsigned long *)(UART0_BASE_ADDR + 0x24))
+#define U0FDR (*(volatile unsigned long *)(UART0_BASE_ADDR + 0x28))
+#define U0TER (*(volatile unsigned long *)(UART0_BASE_ADDR + 0x30))
+
+/* Universal Asynchronous Receiver Transmitter 1 (UART1) */
+#define UART1_BASE_ADDR 0xE0010000
+#define U1RBR (*(volatile unsigned long *)(UART1_BASE_ADDR + 0x00))
+#define U1THR (*(volatile unsigned long *)(UART1_BASE_ADDR + 0x00))
+#define U1DLL (*(volatile unsigned long *)(UART1_BASE_ADDR + 0x00))
+#define U1DLM (*(volatile unsigned long *)(UART1_BASE_ADDR + 0x04))
+#define U1IER (*(volatile unsigned long *)(UART1_BASE_ADDR + 0x04))
+#define U1IIR (*(volatile unsigned long *)(UART1_BASE_ADDR + 0x08))
+#define U1FCR (*(volatile unsigned long *)(UART1_BASE_ADDR + 0x08))
+#define U1LCR (*(volatile unsigned long *)(UART1_BASE_ADDR + 0x0C))
+#define U1MCR (*(volatile unsigned long *)(UART1_BASE_ADDR + 0x10))
+#define U1LSR (*(volatile unsigned long *)(UART1_BASE_ADDR + 0x14))
+#define U1MSR (*(volatile unsigned long *)(UART1_BASE_ADDR + 0x18))
+#define U1SCR (*(volatile unsigned long *)(UART1_BASE_ADDR + 0x1C))
+#define U1ACR (*(volatile unsigned long *)(UART1_BASE_ADDR + 0x20))
+#define U1FDR (*(volatile unsigned long *)(UART1_BASE_ADDR + 0x28))
+#define U1TER (*(volatile unsigned long *)(UART1_BASE_ADDR + 0x30))
+
+/* Universal Asynchronous Receiver Transmitter 2 (UART2) */
+#define UART2_BASE_ADDR 0xE0078000
+#define U2RBR (*(volatile unsigned long *)(UART2_BASE_ADDR + 0x00))
+#define U2THR (*(volatile unsigned long *)(UART2_BASE_ADDR + 0x00))
+#define U2DLL (*(volatile unsigned long *)(UART2_BASE_ADDR + 0x00))
+#define U2DLM (*(volatile unsigned long *)(UART2_BASE_ADDR + 0x04))
+#define U2IER (*(volatile unsigned long *)(UART2_BASE_ADDR + 0x04))
+#define U2IIR (*(volatile unsigned long *)(UART2_BASE_ADDR + 0x08))
+#define U2FCR (*(volatile unsigned long *)(UART2_BASE_ADDR + 0x08))
+#define U2LCR (*(volatile unsigned long *)(UART2_BASE_ADDR + 0x0C))
+#define U2LSR (*(volatile unsigned long *)(UART2_BASE_ADDR + 0x14))
+#define U2SCR (*(volatile unsigned long *)(UART2_BASE_ADDR + 0x1C))
+#define U2ACR (*(volatile unsigned long *)(UART2_BASE_ADDR + 0x20))
+#define U2ICR (*(volatile unsigned long *)(UART2_BASE_ADDR + 0x24))
+#define U2FDR (*(volatile unsigned long *)(UART2_BASE_ADDR + 0x28))
+#define U2TER (*(volatile unsigned long *)(UART2_BASE_ADDR + 0x30))
+
+/* Universal Asynchronous Receiver Transmitter 3 (UART3) */
+#define UART3_BASE_ADDR 0xE007C000
+#define U3RBR (*(volatile unsigned long *)(UART3_BASE_ADDR + 0x00))
+#define U3THR (*(volatile unsigned long *)(UART3_BASE_ADDR + 0x00))
+#define U3DLL (*(volatile unsigned long *)(UART3_BASE_ADDR + 0x00))
+#define U3DLM (*(volatile unsigned long *)(UART3_BASE_ADDR + 0x04))
+#define U3IER (*(volatile unsigned long *)(UART3_BASE_ADDR + 0x04))
+#define U3IIR (*(volatile unsigned long *)(UART3_BASE_ADDR + 0x08))
+#define U3FCR (*(volatile unsigned long *)(UART3_BASE_ADDR + 0x08))
+#define U3LCR (*(volatile unsigned long *)(UART3_BASE_ADDR + 0x0C))
+#define U3LSR (*(volatile unsigned long *)(UART3_BASE_ADDR + 0x14))
+#define U3SCR (*(volatile unsigned long *)(UART3_BASE_ADDR + 0x1C))
+#define U3ACR (*(volatile unsigned long *)(UART3_BASE_ADDR + 0x20))
+#define U3ICR (*(volatile unsigned long *)(UART3_BASE_ADDR + 0x24))
+#define U3FDR (*(volatile unsigned long *)(UART3_BASE_ADDR + 0x28))
+#define U3TER (*(volatile unsigned long *)(UART3_BASE_ADDR + 0x30))
+
+/* I2C Interface 0 */
+#define I2C0_BASE_ADDR 0xE001C000
+#define I20CONSET (*(volatile unsigned long *)(I2C0_BASE_ADDR + 0x00))
+#define I20STAT (*(volatile unsigned long *)(I2C0_BASE_ADDR + 0x04))
+#define I20DAT (*(volatile unsigned long *)(I2C0_BASE_ADDR + 0x08))
+#define I20ADR (*(volatile unsigned long *)(I2C0_BASE_ADDR + 0x0C))
+#define I20SCLH (*(volatile unsigned long *)(I2C0_BASE_ADDR + 0x10))
+#define I20SCLL (*(volatile unsigned long *)(I2C0_BASE_ADDR + 0x14))
+#define I20CONCLR (*(volatile unsigned long *)(I2C0_BASE_ADDR + 0x18))
+
+/* I2C Interface 1 */
+#define I2C1_BASE_ADDR 0xE005C000
+#define I21CONSET (*(volatile unsigned long *)(I2C1_BASE_ADDR + 0x00))
+#define I21STAT (*(volatile unsigned long *)(I2C1_BASE_ADDR + 0x04))
+#define I21DAT (*(volatile unsigned long *)(I2C1_BASE_ADDR + 0x08))
+#define I21ADR (*(volatile unsigned long *)(I2C1_BASE_ADDR + 0x0C))
+#define I21SCLH (*(volatile unsigned long *)(I2C1_BASE_ADDR + 0x10))
+#define I21SCLL (*(volatile unsigned long *)(I2C1_BASE_ADDR + 0x14))
+#define I21CONCLR (*(volatile unsigned long *)(I2C1_BASE_ADDR + 0x18))
+
+/* I2C Interface 2 */
+#define I2C2_BASE_ADDR 0xE0080000
+#define I22CONSET (*(volatile unsigned long *)(I2C2_BASE_ADDR + 0x00))
+#define I22STAT (*(volatile unsigned long *)(I2C2_BASE_ADDR + 0x04))
+#define I22DAT (*(volatile unsigned long *)(I2C2_BASE_ADDR + 0x08))
+#define I22ADR (*(volatile unsigned long *)(I2C2_BASE_ADDR + 0x0C))
+#define I22SCLH (*(volatile unsigned long *)(I2C2_BASE_ADDR + 0x10))
+#define I22SCLL (*(volatile unsigned long *)(I2C2_BASE_ADDR + 0x14))
+#define I22CONCLR (*(volatile unsigned long *)(I2C2_BASE_ADDR + 0x18))
+
+/* SPI0 (Serial Peripheral Interface 0) */
+#define SPI0_BASE_ADDR 0xE0020000
+#define S0SPCR (*(volatile unsigned long *)(SPI0_BASE_ADDR + 0x00))
+#define S0SPSR (*(volatile unsigned long *)(SPI0_BASE_ADDR + 0x04))
+#define S0SPDR (*(volatile unsigned long *)(SPI0_BASE_ADDR + 0x08))
+#define S0SPCCR (*(volatile unsigned long *)(SPI0_BASE_ADDR + 0x0C))
+#define S0SPINT (*(volatile unsigned long *)(SPI0_BASE_ADDR + 0x1C))
+
+/* SSP0 Controller */
+#define SSP0_BASE_ADDR 0xE0068000
+#define SSP0CR0 (*(volatile unsigned long *)(SSP0_BASE_ADDR + 0x00))
+#define SSP0CR1 (*(volatile unsigned long *)(SSP0_BASE_ADDR + 0x04))
+#define SSP0DR (*(volatile unsigned long *)(SSP0_BASE_ADDR + 0x08))
+#define SSP0SR (*(volatile unsigned long *)(SSP0_BASE_ADDR + 0x0C))
+#define SSP0CPSR (*(volatile unsigned long *)(SSP0_BASE_ADDR + 0x10))
+#define SSP0IMSC (*(volatile unsigned long *)(SSP0_BASE_ADDR + 0x14))
+#define SSP0RIS (*(volatile unsigned long *)(SSP0_BASE_ADDR + 0x18))
+#define SSP0MIS (*(volatile unsigned long *)(SSP0_BASE_ADDR + 0x1C))
+#define SSP0ICR (*(volatile unsigned long *)(SSP0_BASE_ADDR + 0x20))
+#define SSP0DMACR (*(volatile unsigned long *)(SSP0_BASE_ADDR + 0x24))
+
+/* SSP1 Controller */
+#define SSP1_BASE_ADDR 0xE0030000
+#define SSP1CR0 (*(volatile unsigned long *)(SSP1_BASE_ADDR + 0x00))
+#define SSP1CR1 (*(volatile unsigned long *)(SSP1_BASE_ADDR + 0x04))
+#define SSP1DR (*(volatile unsigned long *)(SSP1_BASE_ADDR + 0x08))
+#define SSP1SR (*(volatile unsigned long *)(SSP1_BASE_ADDR + 0x0C))
+#define SSP1CPSR (*(volatile unsigned long *)(SSP1_BASE_ADDR + 0x10))
+#define SSP1IMSC (*(volatile unsigned long *)(SSP1_BASE_ADDR + 0x14))
+#define SSP1RIS (*(volatile unsigned long *)(SSP1_BASE_ADDR + 0x18))
+#define SSP1MIS (*(volatile unsigned long *)(SSP1_BASE_ADDR + 0x1C))
+#define SSP1ICR (*(volatile unsigned long *)(SSP1_BASE_ADDR + 0x20))
+#define SSP1DMACR (*(volatile unsigned long *)(SSP1_BASE_ADDR + 0x24))
+
+
+/* Real Time Clock */
+#define RTC_BASE_ADDR 0xE0024000
+#define RTC_ILR (*(volatile unsigned long *)(RTC_BASE_ADDR + 0x00))
+#define RTC_CTC (*(volatile unsigned long *)(RTC_BASE_ADDR + 0x04))
+#define RTC_CCR (*(volatile unsigned long *)(RTC_BASE_ADDR + 0x08))
+#define RTC_CIIR (*(volatile unsigned long *)(RTC_BASE_ADDR + 0x0C))
+#define RTC_AMR (*(volatile unsigned long *)(RTC_BASE_ADDR + 0x10))
+#define RTC_CTIME0 (*(volatile unsigned long *)(RTC_BASE_ADDR + 0x14))
+#define RTC_CTIME1 (*(volatile unsigned long *)(RTC_BASE_ADDR + 0x18))
+#define RTC_CTIME2 (*(volatile unsigned long *)(RTC_BASE_ADDR + 0x1C))
+#define RTC_SEC (*(volatile unsigned long *)(RTC_BASE_ADDR + 0x20))
+#define RTC_MIN (*(volatile unsigned long *)(RTC_BASE_ADDR + 0x24))
+#define RTC_HOUR (*(volatile unsigned long *)(RTC_BASE_ADDR + 0x28))
+#define RTC_DOM (*(volatile unsigned long *)(RTC_BASE_ADDR + 0x2C))
+#define RTC_DOW (*(volatile unsigned long *)(RTC_BASE_ADDR + 0x30))
+#define RTC_DOY (*(volatile unsigned long *)(RTC_BASE_ADDR + 0x34))
+#define RTC_MONTH (*(volatile unsigned long *)(RTC_BASE_ADDR + 0x38))
+#define RTC_YEAR (*(volatile unsigned long *)(RTC_BASE_ADDR + 0x3C))
+#define RTC_CISS (*(volatile unsigned long *)(RTC_BASE_ADDR + 0x40))
+#define RTC_ALSEC (*(volatile unsigned long *)(RTC_BASE_ADDR + 0x60))
+#define RTC_ALMIN (*(volatile unsigned long *)(RTC_BASE_ADDR + 0x64))
+#define RTC_ALHOUR (*(volatile unsigned long *)(RTC_BASE_ADDR + 0x68))
+#define RTC_ALDOM (*(volatile unsigned long *)(RTC_BASE_ADDR + 0x6C))
+#define RTC_ALDOW (*(volatile unsigned long *)(RTC_BASE_ADDR + 0x70))
+#define RTC_ALDOY (*(volatile unsigned long *)(RTC_BASE_ADDR + 0x74))
+#define RTC_ALMON (*(volatile unsigned long *)(RTC_BASE_ADDR + 0x78))
+#define RTC_ALYEAR (*(volatile unsigned long *)(RTC_BASE_ADDR + 0x7C))
+#define RTC_PREINT (*(volatile unsigned long *)(RTC_BASE_ADDR + 0x80))
+#define RTC_PREFRAC (*(volatile unsigned long *)(RTC_BASE_ADDR + 0x84))
+
+
+/* A/D Converter 0 (AD0) */
+#define AD0_BASE_ADDR 0xE0034000
+#define AD0CR (*(volatile unsigned long *)(AD0_BASE_ADDR + 0x00))
+#define AD0GDR (*(volatile unsigned long *)(AD0_BASE_ADDR + 0x04))
+#define AD0INTEN (*(volatile unsigned long *)(AD0_BASE_ADDR + 0x0C))
+#define AD0DR0 (*(volatile unsigned long *)(AD0_BASE_ADDR + 0x10))
+#define AD0DR1 (*(volatile unsigned long *)(AD0_BASE_ADDR + 0x14))
+#define AD0DR2 (*(volatile unsigned long *)(AD0_BASE_ADDR + 0x18))
+#define AD0DR3 (*(volatile unsigned long *)(AD0_BASE_ADDR + 0x1C))
+#define AD0DR4 (*(volatile unsigned long *)(AD0_BASE_ADDR + 0x20))
+#define AD0DR5 (*(volatile unsigned long *)(AD0_BASE_ADDR + 0x24))
+#define AD0DR6 (*(volatile unsigned long *)(AD0_BASE_ADDR + 0x28))
+#define AD0DR7 (*(volatile unsigned long *)(AD0_BASE_ADDR + 0x2C))
+#define AD0STAT (*(volatile unsigned long *)(AD0_BASE_ADDR + 0x30))
+
+
+/* D/A Converter */
+#define DAC_BASE_ADDR 0xE006C000
+#define DACR (*(volatile unsigned long *)(DAC_BASE_ADDR + 0x00))
+
+
+/* Watchdog */
+#define WDG_BASE_ADDR 0xE0000000
+#define WDMOD (*(volatile unsigned long *)(WDG_BASE_ADDR + 0x00))
+#define WDTC (*(volatile unsigned long *)(WDG_BASE_ADDR + 0x04))
+#define WDFEED (*(volatile unsigned long *)(WDG_BASE_ADDR + 0x08))
+#define WDTV (*(volatile unsigned long *)(WDG_BASE_ADDR + 0x0C))
+#define WDCLKSEL (*(volatile unsigned long *)(WDG_BASE_ADDR + 0x10))
+
+/* CAN CONTROLLERS AND ACCEPTANCE FILTER */
+#define CAN_ACCEPT_BASE_ADDR 0xE003C000
+#define CAN_AFMR (*(volatile unsigned long *)(CAN_ACCEPT_BASE_ADDR + 0x00))
+#define CAN_SFF_SA (*(volatile unsigned long *)(CAN_ACCEPT_BASE_ADDR + 0x04))
+#define CAN_SFF_GRP_SA (*(volatile unsigned long *)(CAN_ACCEPT_BASE_ADDR + 0x08))
+#define CAN_EFF_SA (*(volatile unsigned long *)(CAN_ACCEPT_BASE_ADDR + 0x0C))
+#define CAN_EFF_GRP_SA (*(volatile unsigned long *)(CAN_ACCEPT_BASE_ADDR + 0x10))
+#define CAN_EOT (*(volatile unsigned long *)(CAN_ACCEPT_BASE_ADDR + 0x14))
+#define CAN_LUT_ERR_ADR (*(volatile unsigned long *)(CAN_ACCEPT_BASE_ADDR + 0x18))
+#define CAN_LUT_ERR (*(volatile unsigned long *)(CAN_ACCEPT_BASE_ADDR + 0x1C))
+
+#define CAN_CENTRAL_BASE_ADDR 0xE0040000
+#define CAN_TX_SR (*(volatile unsigned long *)(CAN_CENTRAL_BASE_ADDR + 0x00))
+#define CAN_RX_SR (*(volatile unsigned long *)(CAN_CENTRAL_BASE_ADDR + 0x04))
+#define CAN_MSR (*(volatile unsigned long *)(CAN_CENTRAL_BASE_ADDR + 0x08))
+
+#define CAN1_BASE_ADDR 0xE0044000
+#define CAN1MOD (*(volatile unsigned long *)(CAN1_BASE_ADDR + 0x00))
+#define CAN1CMR (*(volatile unsigned long *)(CAN1_BASE_ADDR + 0x04))
+#define CAN1GSR (*(volatile unsigned long *)(CAN1_BASE_ADDR + 0x08))
+#define CAN1ICR (*(volatile unsigned long *)(CAN1_BASE_ADDR + 0x0C))
+#define CAN1IER (*(volatile unsigned long *)(CAN1_BASE_ADDR + 0x10))
+#define CAN1BTR (*(volatile unsigned long *)(CAN1_BASE_ADDR + 0x14))
+#define CAN1EWL (*(volatile unsigned long *)(CAN1_BASE_ADDR + 0x18))
+#define CAN1SR (*(volatile unsigned long *)(CAN1_BASE_ADDR + 0x1C))
+#define CAN1RFS (*(volatile unsigned long *)(CAN1_BASE_ADDR + 0x20))
+#define CAN1RID (*(volatile unsigned long *)(CAN1_BASE_ADDR + 0x24))
+#define CAN1RDA (*(volatile unsigned long *)(CAN1_BASE_ADDR + 0x28))
+#define CAN1RDB (*(volatile unsigned long *)(CAN1_BASE_ADDR + 0x2C))
+
+#define CAN1TFI1 (*(volatile unsigned long *)(CAN1_BASE_ADDR + 0x30))
+#define CAN1TID1 (*(volatile unsigned long *)(CAN1_BASE_ADDR + 0x34))
+#define CAN1TDA1 (*(volatile unsigned long *)(CAN1_BASE_ADDR + 0x38))
+#define CAN1TDB1 (*(volatile unsigned long *)(CAN1_BASE_ADDR + 0x3C))
+#define CAN1TFI2 (*(volatile unsigned long *)(CAN1_BASE_ADDR + 0x40))
+#define CAN1TID2 (*(volatile unsigned long *)(CAN1_BASE_ADDR + 0x44))
+#define CAN1TDA2 (*(volatile unsigned long *)(CAN1_BASE_ADDR + 0x48))
+#define CAN1TDB2 (*(volatile unsigned long *)(CAN1_BASE_ADDR + 0x4C))
+#define CAN1TFI3 (*(volatile unsigned long *)(CAN1_BASE_ADDR + 0x50))
+#define CAN1TID3 (*(volatile unsigned long *)(CAN1_BASE_ADDR + 0x54))
+#define CAN1TDA3 (*(volatile unsigned long *)(CAN1_BASE_ADDR + 0x58))
+#define CAN1TDB3 (*(volatile unsigned long *)(CAN1_BASE_ADDR + 0x5C))
+
+#define CAN2_BASE_ADDR 0xE0048000
+#define CAN2MOD (*(volatile unsigned long *)(CAN2_BASE_ADDR + 0x00))
+#define CAN2CMR (*(volatile unsigned long *)(CAN2_BASE_ADDR + 0x04))
+#define CAN2GSR (*(volatile unsigned long *)(CAN2_BASE_ADDR + 0x08))
+#define CAN2ICR (*(volatile unsigned long *)(CAN2_BASE_ADDR + 0x0C))
+#define CAN2IER (*(volatile unsigned long *)(CAN2_BASE_ADDR + 0x10))
+#define CAN2BTR (*(volatile unsigned long *)(CAN2_BASE_ADDR + 0x14))
+#define CAN2EWL (*(volatile unsigned long *)(CAN2_BASE_ADDR + 0x18))
+#define CAN2SR (*(volatile unsigned long *)(CAN2_BASE_ADDR + 0x1C))
+#define CAN2RFS (*(volatile unsigned long *)(CAN2_BASE_ADDR + 0x20))
+#define CAN2RID (*(volatile unsigned long *)(CAN2_BASE_ADDR + 0x24))
+#define CAN2RDA (*(volatile unsigned long *)(CAN2_BASE_ADDR + 0x28))
+#define CAN2RDB (*(volatile unsigned long *)(CAN2_BASE_ADDR + 0x2C))
+
+#define CAN2TFI1 (*(volatile unsigned long *)(CAN2_BASE_ADDR + 0x30))
+#define CAN2TID1 (*(volatile unsigned long *)(CAN2_BASE_ADDR + 0x34))
+#define CAN2TDA1 (*(volatile unsigned long *)(CAN2_BASE_ADDR + 0x38))
+#define CAN2TDB1 (*(volatile unsigned long *)(CAN2_BASE_ADDR + 0x3C))
+#define CAN2TFI2 (*(volatile unsigned long *)(CAN2_BASE_ADDR + 0x40))
+#define CAN2TID2 (*(volatile unsigned long *)(CAN2_BASE_ADDR + 0x44))
+#define CAN2TDA2 (*(volatile unsigned long *)(CAN2_BASE_ADDR + 0x48))
+#define CAN2TDB2 (*(volatile unsigned long *)(CAN2_BASE_ADDR + 0x4C))
+#define CAN2TFI3 (*(volatile unsigned long *)(CAN2_BASE_ADDR + 0x50))
+#define CAN2TID3 (*(volatile unsigned long *)(CAN2_BASE_ADDR + 0x54))
+#define CAN2TDA3 (*(volatile unsigned long *)(CAN2_BASE_ADDR + 0x58))
+#define CAN2TDB3 (*(volatile unsigned long *)(CAN2_BASE_ADDR + 0x5C))
+
+
+/* MultiMedia Card Interface(MCI) Controller */
+#define MCI_BASE_ADDR 0xE008C000
+#define MCI_POWER (*(volatile unsigned long *)(MCI_BASE_ADDR + 0x00))
+#define MCI_CLOCK (*(volatile unsigned long *)(MCI_BASE_ADDR + 0x04))
+#define MCI_ARGUMENT (*(volatile unsigned long *)(MCI_BASE_ADDR + 0x08))
+#define MCI_COMMAND (*(volatile unsigned long *)(MCI_BASE_ADDR + 0x0C))
+#define MCI_RESP_CMD (*(volatile unsigned long *)(MCI_BASE_ADDR + 0x10))
+#define MCI_RESP0 (*(volatile unsigned long *)(MCI_BASE_ADDR + 0x14))
+#define MCI_RESP1 (*(volatile unsigned long *)(MCI_BASE_ADDR + 0x18))
+#define MCI_RESP2 (*(volatile unsigned long *)(MCI_BASE_ADDR + 0x1C))
+#define MCI_RESP3 (*(volatile unsigned long *)(MCI_BASE_ADDR + 0x20))
+#define MCI_DATA_TMR (*(volatile unsigned long *)(MCI_BASE_ADDR + 0x24))
+#define MCI_DATA_LEN (*(volatile unsigned long *)(MCI_BASE_ADDR + 0x28))
+#define MCI_DATA_CTRL (*(volatile unsigned long *)(MCI_BASE_ADDR + 0x2C))
+#define MCI_DATA_CNT (*(volatile unsigned long *)(MCI_BASE_ADDR + 0x30))
+#define MCI_STATUS (*(volatile unsigned long *)(MCI_BASE_ADDR + 0x34))
+#define MCI_CLEAR (*(volatile unsigned long *)(MCI_BASE_ADDR + 0x38))
+#define MCI_MASK0 (*(volatile unsigned long *)(MCI_BASE_ADDR + 0x3C))
+#define MCI_MASK1 (*(volatile unsigned long *)(MCI_BASE_ADDR + 0x40))
+#define MCI_FIFO_CNT (*(volatile unsigned long *)(MCI_BASE_ADDR + 0x48))
+#define MCI_FIFO (*(volatile unsigned long *)(MCI_BASE_ADDR + 0x80))
+
+
+/* I2S Interface Controller (I2S) */
+#define I2S_BASE_ADDR 0xE0088000
+#define I2S_DAO (*(volatile unsigned long *)(I2S_BASE_ADDR + 0x00))
+#define I2S_DAI (*(volatile unsigned long *)(I2S_BASE_ADDR + 0x04))
+#define I2S_TX_FIFO (*(volatile unsigned long *)(I2S_BASE_ADDR + 0x08))
+#define I2S_RX_FIFO (*(volatile unsigned long *)(I2S_BASE_ADDR + 0x0C))
+#define I2S_STATE (*(volatile unsigned long *)(I2S_BASE_ADDR + 0x10))
+#define I2S_DMA1 (*(volatile unsigned long *)(I2S_BASE_ADDR + 0x14))
+#define I2S_DMA2 (*(volatile unsigned long *)(I2S_BASE_ADDR + 0x18))
+#define I2S_IRQ (*(volatile unsigned long *)(I2S_BASE_ADDR + 0x1C))
+#define I2S_TXRATE (*(volatile unsigned long *)(I2S_BASE_ADDR + 0x20))
+#define I2S_RXRATE (*(volatile unsigned long *)(I2S_BASE_ADDR + 0x24))
+
+
+/* General-purpose DMA Controller */
+#define DMA_BASE_ADDR 0xFFE04000
+#define GPDMA_INT_STAT (*(volatile unsigned long *)(DMA_BASE_ADDR + 0x000))
+#define GPDMA_INT_TCSTAT (*(volatile unsigned long *)(DMA_BASE_ADDR + 0x004))
+#define GPDMA_INT_TCCLR (*(volatile unsigned long *)(DMA_BASE_ADDR + 0x008))
+#define GPDMA_INT_ERR_STAT (*(volatile unsigned long *)(DMA_BASE_ADDR + 0x00C))
+#define GPDMA_INT_ERR_CLR (*(volatile unsigned long *)(DMA_BASE_ADDR + 0x010))
+#define GPDMA_RAW_INT_TCSTAT (*(volatile unsigned long *)(DMA_BASE_ADDR + 0x014))
+#define GPDMA_RAW_INT_ERR_STAT (*(volatile unsigned long *)(DMA_BASE_ADDR + 0x018))
+#define GPDMA_ENABLED_CHNS (*(volatile unsigned long *)(DMA_BASE_ADDR + 0x01C))
+#define GPDMA_SOFT_BREQ (*(volatile unsigned long *)(DMA_BASE_ADDR + 0x020))
+#define GPDMA_SOFT_SREQ (*(volatile unsigned long *)(DMA_BASE_ADDR + 0x024))
+#define GPDMA_SOFT_LBREQ (*(volatile unsigned long *)(DMA_BASE_ADDR + 0x028))
+#define GPDMA_SOFT_LSREQ (*(volatile unsigned long *)(DMA_BASE_ADDR + 0x02C))
+#define GPDMA_CONFIG (*(volatile unsigned long *)(DMA_BASE_ADDR + 0x030))
+#define GPDMA_SYNC (*(volatile unsigned long *)(DMA_BASE_ADDR + 0x034))
+
+/* DMA channel 0 registers */
+#define GPDMA_CH0_SRC (*(volatile unsigned long *)(DMA_BASE_ADDR + 0x100))
+#define GPDMA_CH0_DEST (*(volatile unsigned long *)(DMA_BASE_ADDR + 0x104))
+#define GPDMA_CH0_LLI (*(volatile unsigned long *)(DMA_BASE_ADDR + 0x108))
+#define GPDMA_CH0_CTRL (*(volatile unsigned long *)(DMA_BASE_ADDR + 0x10C))
+#define GPDMA_CH0_CFG (*(volatile unsigned long *)(DMA_BASE_ADDR + 0x110))
+
+/* DMA channel 1 registers */
+#define GPDMA_CH1_SRC (*(volatile unsigned long *)(DMA_BASE_ADDR + 0x120))
+#define GPDMA_CH1_DEST (*(volatile unsigned long *)(DMA_BASE_ADDR + 0x124))
+#define GPDMA_CH1_LLI (*(volatile unsigned long *)(DMA_BASE_ADDR + 0x128))
+#define GPDMA_CH1_CTRL (*(volatile unsigned long *)(DMA_BASE_ADDR + 0x12C))
+#define GPDMA_CH1_CFG (*(volatile unsigned long *)(DMA_BASE_ADDR + 0x130))
+
+
+/* USB Controller */
+#define USB_INT_BASE_ADDR 0xE01FC1C0
+#define USB_BASE_ADDR 0xFFE0C200 /* USB Base Address */
+
+#define USB_INT_STAT (*(volatile unsigned long *)(USB_INT_BASE_ADDR + 0x00))
+
+/* USB Device Interrupt Registers */
+#define DEV_INT_STAT (*(volatile unsigned long *)(USB_BASE_ADDR + 0x00))
+#define DEV_INT_EN (*(volatile unsigned long *)(USB_BASE_ADDR + 0x04))
+#define DEV_INT_CLR (*(volatile unsigned long *)(USB_BASE_ADDR + 0x08))
+#define DEV_INT_SET (*(volatile unsigned long *)(USB_BASE_ADDR + 0x0C))
+#define DEV_INT_PRIO (*(volatile unsigned long *)(USB_BASE_ADDR + 0x2C))
+
+/* USB Device Endpoint Interrupt Registers */
+#define EP_INT_STAT (*(volatile unsigned long *)(USB_BASE_ADDR + 0x30))
+#define EP_INT_EN (*(volatile unsigned long *)(USB_BASE_ADDR + 0x34))
+#define EP_INT_CLR (*(volatile unsigned long *)(USB_BASE_ADDR + 0x38))
+#define EP_INT_SET (*(volatile unsigned long *)(USB_BASE_ADDR + 0x3C))
+#define EP_INT_PRIO (*(volatile unsigned long *)(USB_BASE_ADDR + 0x40))
+
+/* USB Device Endpoint Realization Registers */
+#define REALIZE_EP (*(volatile unsigned long *)(USB_BASE_ADDR + 0x44))
+#define EP_INDEX (*(volatile unsigned long *)(USB_BASE_ADDR + 0x48))
+#define MAXPACKET_SIZE (*(volatile unsigned long *)(USB_BASE_ADDR + 0x4C))
+
+/* USB Device Command Reagisters */
+#define CMD_CODE (*(volatile unsigned long *)(USB_BASE_ADDR + 0x10))
+#define CMD_DATA (*(volatile unsigned long *)(USB_BASE_ADDR + 0x14))
+
+/* USB Device Data Transfer Registers */
+#define RX_DATA (*(volatile unsigned long *)(USB_BASE_ADDR + 0x18))
+#define TX_DATA (*(volatile unsigned long *)(USB_BASE_ADDR + 0x1C))
+#define RX_PLENGTH (*(volatile unsigned long *)(USB_BASE_ADDR + 0x20))
+#define TX_PLENGTH (*(volatile unsigned long *)(USB_BASE_ADDR + 0x24))
+#define USB_CTRL (*(volatile unsigned long *)(USB_BASE_ADDR + 0x28))
+
+/* USB Device DMA Registers */
+#define DMA_REQ_STAT (*(volatile unsigned long *)(USB_BASE_ADDR + 0x50))
+#define DMA_REQ_CLR (*(volatile unsigned long *)(USB_BASE_ADDR + 0x54))
+#define DMA_REQ_SET (*(volatile unsigned long *)(USB_BASE_ADDR + 0x58))
+#define UDCA_HEAD (*(volatile unsigned long *)(USB_BASE_ADDR + 0x80))
+#define EP_DMA_STAT (*(volatile unsigned long *)(USB_BASE_ADDR + 0x84))
+#define EP_DMA_EN (*(volatile unsigned long *)(USB_BASE_ADDR + 0x88))
+#define EP_DMA_DIS (*(volatile unsigned long *)(USB_BASE_ADDR + 0x8C))
+#define DMA_INT_STAT (*(volatile unsigned long *)(USB_BASE_ADDR + 0x90))
+#define DMA_INT_EN (*(volatile unsigned long *)(USB_BASE_ADDR + 0x94))
+#define EOT_INT_STAT (*(volatile unsigned long *)(USB_BASE_ADDR + 0xA0))
+#define EOT_INT_CLR (*(volatile unsigned long *)(USB_BASE_ADDR + 0xA4))
+#define EOT_INT_SET (*(volatile unsigned long *)(USB_BASE_ADDR + 0xA8))
+#define NDD_REQ_INT_STAT (*(volatile unsigned long *)(USB_BASE_ADDR + 0xAC))
+#define NDD_REQ_INT_CLR (*(volatile unsigned long *)(USB_BASE_ADDR + 0xB0))
+#define NDD_REQ_INT_SET (*(volatile unsigned long *)(USB_BASE_ADDR + 0xB4))
+#define SYS_ERR_INT_STAT (*(volatile unsigned long *)(USB_BASE_ADDR + 0xB8))
+#define SYS_ERR_INT_CLR (*(volatile unsigned long *)(USB_BASE_ADDR + 0xBC))
+#define SYS_ERR_INT_SET (*(volatile unsigned long *)(USB_BASE_ADDR + 0xC0))
+
+/* USB Host and OTG registers are for LPC24xx only */
+/* USB Host Controller */
+#define USBHC_BASE_ADDR 0xFFE0C000
+#define HC_REVISION (*(volatile unsigned long *)(USBHC_BASE_ADDR + 0x00))
+#define HC_CONTROL (*(volatile unsigned long *)(USBHC_BASE_ADDR + 0x04))
+#define HC_CMD_STAT (*(volatile unsigned long *)(USBHC_BASE_ADDR + 0x08))
+#define HC_INT_STAT (*(volatile unsigned long *)(USBHC_BASE_ADDR + 0x0C))
+#define HC_INT_EN (*(volatile unsigned long *)(USBHC_BASE_ADDR + 0x10))
+#define HC_INT_DIS (*(volatile unsigned long *)(USBHC_BASE_ADDR + 0x14))
+#define HC_HCCA (*(volatile unsigned long *)(USBHC_BASE_ADDR + 0x18))
+#define HC_PERIOD_CUR_ED (*(volatile unsigned long *)(USBHC_BASE_ADDR + 0x1C))
+#define HC_CTRL_HEAD_ED (*(volatile unsigned long *)(USBHC_BASE_ADDR + 0x20))
+#define HC_CTRL_CUR_ED (*(volatile unsigned long *)(USBHC_BASE_ADDR + 0x24))
+#define HC_BULK_HEAD_ED (*(volatile unsigned long *)(USBHC_BASE_ADDR + 0x28))
+#define HC_BULK_CUR_ED (*(volatile unsigned long *)(USBHC_BASE_ADDR + 0x2C))
+#define HC_DONE_HEAD (*(volatile unsigned long *)(USBHC_BASE_ADDR + 0x30))
+#define HC_FM_INTERVAL (*(volatile unsigned long *)(USBHC_BASE_ADDR + 0x34))
+#define HC_FM_REMAINING (*(volatile unsigned long *)(USBHC_BASE_ADDR + 0x38))
+#define HC_FM_NUMBER (*(volatile unsigned long *)(USBHC_BASE_ADDR + 0x3C))
+#define HC_PERIOD_START (*(volatile unsigned long *)(USBHC_BASE_ADDR + 0x40))
+#define HC_LS_THRHLD (*(volatile unsigned long *)(USBHC_BASE_ADDR + 0x44))
+#define HC_RH_DESCA (*(volatile unsigned long *)(USBHC_BASE_ADDR + 0x48))
+#define HC_RH_DESCB (*(volatile unsigned long *)(USBHC_BASE_ADDR + 0x4C))
+#define HC_RH_STAT (*(volatile unsigned long *)(USBHC_BASE_ADDR + 0x50))
+#define HC_RH_PORT_STAT1 (*(volatile unsigned long *)(USBHC_BASE_ADDR + 0x54))
+#define HC_RH_PORT_STAT2 (*(volatile unsigned long *)(USBHC_BASE_ADDR + 0x58))
+
+/* USB OTG Controller */
+#define USBOTG_BASE_ADDR 0xFFE0C100
+#define OTG_INT_STAT (*(volatile unsigned long *)(USBOTG_BASE_ADDR + 0x00))
+#define OTG_INT_EN (*(volatile unsigned long *)(USBOTG_BASE_ADDR + 0x04))
+#define OTG_INT_SET (*(volatile unsigned long *)(USBOTG_BASE_ADDR + 0x08))
+#define OTG_INT_CLR (*(volatile unsigned long *)(USBOTG_BASE_ADDR + 0x0C))
+/* On LPC23xx, the name is USBPortSel, on LPC24xx, the name is OTG_STAT_CTRL */
+#define OTG_STAT_CTRL (*(volatile unsigned long *)(USBOTG_BASE_ADDR + 0x10))
+#define OTG_TIMER (*(volatile unsigned long *)(USBOTG_BASE_ADDR + 0x14))
+
+#define USBOTG_I2C_BASE_ADDR 0xFFE0C300
+#define OTG_I2C_RX (*(volatile unsigned long *)(USBOTG_I2C_BASE_ADDR + 0x00))
+#define OTG_I2C_TX (*(volatile unsigned long *)(USBOTG_I2C_BASE_ADDR + 0x00))
+#define OTG_I2C_STS (*(volatile unsigned long *)(USBOTG_I2C_BASE_ADDR + 0x04))
+#define OTG_I2C_CTL (*(volatile unsigned long *)(USBOTG_I2C_BASE_ADDR + 0x08))
+#define OTG_I2C_CLKHI (*(volatile unsigned long *)(USBOTG_I2C_BASE_ADDR + 0x0C))
+#define OTG_I2C_CLKLO (*(volatile unsigned long *)(USBOTG_I2C_BASE_ADDR + 0x10))
+
+/* On LPC23xx, the names are USBClkCtrl and USBClkSt; on LPC24xx, the names are
+OTG_CLK_CTRL and OTG_CLK_STAT respectively. */
+#define USBOTG_CLK_BASE_ADDR 0xFFE0CFF0
+#define OTG_CLK_CTRL (*(volatile unsigned long *)(USBOTG_CLK_BASE_ADDR + 0x04))
+#define OTG_CLK_STAT (*(volatile unsigned long *)(USBOTG_CLK_BASE_ADDR + 0x08))
+
+/* Note: below three register name convention is for LPC23xx USB device only, match
+with the spec. update in USB Device Section. */
+#define USBPortSel (*(volatile unsigned long *)(USBOTG_BASE_ADDR + 0x10))
+#define USBClkCtrl (*(volatile unsigned long *)(USBOTG_CLK_BASE_ADDR + 0x04))
+#define USBClkSt (*(volatile unsigned long *)(USBOTG_CLK_BASE_ADDR + 0x08))
+
+/* Ethernet MAC (32 bit data bus) -- all registers are RW unless indicated in parentheses */
+#define MAC_BASE_ADDR 0xFFE00000 /* AHB Peripheral # 0 */
+#define MAC_MAC1 (*(volatile unsigned long *)(MAC_BASE_ADDR + 0x000)) /* MAC config reg 1 */
+#define MAC_MAC2 (*(volatile unsigned long *)(MAC_BASE_ADDR + 0x004)) /* MAC config reg 2 */
+#define MAC_IPGT (*(volatile unsigned long *)(MAC_BASE_ADDR + 0x008)) /* b2b InterPacketGap reg */
+#define MAC_IPGR (*(volatile unsigned long *)(MAC_BASE_ADDR + 0x00C)) /* non b2b InterPacketGap reg */
+#define MAC_CLRT (*(volatile unsigned long *)(MAC_BASE_ADDR + 0x010)) /* CoLlision window/ReTry reg */
+#define MAC_MAXF (*(volatile unsigned long *)(MAC_BASE_ADDR + 0x014)) /* MAXimum Frame reg */
+#define MAC_SUPP (*(volatile unsigned long *)(MAC_BASE_ADDR + 0x018)) /* PHY SUPPort reg */
+#define MAC_TEST (*(volatile unsigned long *)(MAC_BASE_ADDR + 0x01C)) /* TEST reg */
+#define MAC_MCFG (*(volatile unsigned long *)(MAC_BASE_ADDR + 0x020)) /* MII Mgmt ConFiG reg */
+#define MAC_MCMD (*(volatile unsigned long *)(MAC_BASE_ADDR + 0x024)) /* MII Mgmt CoMmanD reg */
+#define MAC_MADR (*(volatile unsigned long *)(MAC_BASE_ADDR + 0x028)) /* MII Mgmt ADdRess reg */
+#define MAC_MWTD (*(volatile unsigned long *)(MAC_BASE_ADDR + 0x02C)) /* MII Mgmt WriTe Data reg (WO) */
+#define MAC_MRDD (*(volatile unsigned long *)(MAC_BASE_ADDR + 0x030)) /* MII Mgmt ReaD Data reg (RO) */
+#define MAC_MIND (*(volatile unsigned long *)(MAC_BASE_ADDR + 0x034)) /* MII Mgmt INDicators reg (RO) */
+
+#define MAC_SA0 (*(volatile unsigned long *)(MAC_BASE_ADDR + 0x040)) /* Station Address 0 reg */
+#define MAC_SA1 (*(volatile unsigned long *)(MAC_BASE_ADDR + 0x044)) /* Station Address 1 reg */
+#define MAC_SA2 (*(volatile unsigned long *)(MAC_BASE_ADDR + 0x048)) /* Station Address 2 reg */
+
+#define MAC_COMMAND (*(volatile unsigned long *)(MAC_BASE_ADDR + 0x100)) /* Command reg */
+#define MAC_STATUS (*(volatile unsigned long *)(MAC_BASE_ADDR + 0x104)) /* Status reg (RO) */
+#define MAC_RXDESCRIPTOR (*(volatile unsigned long *)(MAC_BASE_ADDR + 0x108)) /* Rx descriptor base address reg */
+#define MAC_RXSTATUS (*(volatile unsigned long *)(MAC_BASE_ADDR + 0x10C)) /* Rx status base address reg */
+#define MAC_RXDESCRIPTORNUM (*(volatile unsigned long *)(MAC_BASE_ADDR + 0x110)) /* Rx number of descriptors reg */
+#define MAC_RXPRODUCEINDEX (*(volatile unsigned long *)(MAC_BASE_ADDR + 0x114)) /* Rx produce index reg (RO) */
+#define MAC_RXCONSUMEINDEX (*(volatile unsigned long *)(MAC_BASE_ADDR + 0x118)) /* Rx consume index reg */
+#define MAC_TXDESCRIPTOR (*(volatile unsigned long *)(MAC_BASE_ADDR + 0x11C)) /* Tx descriptor base address reg */
+#define MAC_TXSTATUS (*(volatile unsigned long *)(MAC_BASE_ADDR + 0x120)) /* Tx status base address reg */
+#define MAC_TXDESCRIPTORNUM (*(volatile unsigned long *)(MAC_BASE_ADDR + 0x124)) /* Tx number of descriptors reg */
+#define MAC_TXPRODUCEINDEX (*(volatile unsigned long *)(MAC_BASE_ADDR + 0x128)) /* Tx produce index reg */
+#define MAC_TXCONSUMEINDEX (*(volatile unsigned long *)(MAC_BASE_ADDR + 0x12C)) /* Tx consume index reg (RO) */
+
+#define MAC_TSV0 (*(volatile unsigned long *)(MAC_BASE_ADDR + 0x158)) /* Tx status vector 0 reg (RO) */
+#define MAC_TSV1 (*(volatile unsigned long *)(MAC_BASE_ADDR + 0x15C)) /* Tx status vector 1 reg (RO) */
+#define MAC_RSV (*(volatile unsigned long *)(MAC_BASE_ADDR + 0x160)) /* Rx status vector reg (RO) */
+
+#define MAC_FLOWCONTROLCNT (*(volatile unsigned long *)(MAC_BASE_ADDR + 0x170)) /* Flow control counter reg */
+#define MAC_FLOWCONTROLSTS (*(volatile unsigned long *)(MAC_BASE_ADDR + 0x174)) /* Flow control status reg */
+
+#define MAC_RXFILTERCTRL (*(volatile unsigned long *)(MAC_BASE_ADDR + 0x200)) /* Rx filter ctrl reg */
+#define MAC_RXFILTERWOLSTS (*(volatile unsigned long *)(MAC_BASE_ADDR + 0x204)) /* Rx filter WoL status reg (RO) */
+#define MAC_RXFILTERWOLCLR (*(volatile unsigned long *)(MAC_BASE_ADDR + 0x208)) /* Rx filter WoL clear reg (WO) */
+
+#define MAC_HASHFILTERL (*(volatile unsigned long *)(MAC_BASE_ADDR + 0x210)) /* Hash filter LSBs reg */
+#define MAC_HASHFILTERH (*(volatile unsigned long *)(MAC_BASE_ADDR + 0x214)) /* Hash filter MSBs reg */
+
+#define MAC_INTSTATUS (*(volatile unsigned long *)(MAC_BASE_ADDR + 0xFE0)) /* Interrupt status reg (RO) */
+#define MAC_INTENABLE (*(volatile unsigned long *)(MAC_BASE_ADDR + 0xFE4)) /* Interrupt enable reg */
+#define MAC_INTCLEAR (*(volatile unsigned long *)(MAC_BASE_ADDR + 0xFE8)) /* Interrupt clear reg (WO) */
+#define MAC_INTSET (*(volatile unsigned long *)(MAC_BASE_ADDR + 0xFEC)) /* Interrupt set reg (WO) */
+
+#define MAC_POWERDOWN (*(volatile unsigned long *)(MAC_BASE_ADDR + 0xFF4)) /* Power-down reg */
+#define MAC_MODULEID (*(volatile unsigned long *)(MAC_BASE_ADDR + 0xFFC)) /* Module ID reg (RO) */
+
+/* LCD Controller registers */
+#define LCD_BASE_ADDR 0xFFE10000 /* AHB Peripheral # 4 */
+#define LCD_CFG (*(volatile unsigned long *)(0xE01FC1B8))
+#define LCD_TIMH (*(volatile unsigned long *)(LCD_BASE_ADDR + 0x000))
+#define LCD_TIMV (*(volatile unsigned long *)(LCD_BASE_ADDR + 0x004))
+#define LCD_POL (*(volatile unsigned long *)(LCD_BASE_ADDR + 0x008))
+#define LCD_LE (*(volatile unsigned long *)(LCD_BASE_ADDR + 0x00C))
+#define LCD_UPBASE (*(volatile unsigned long *)(LCD_BASE_ADDR + 0x010))
+#define LCD_LPBASE (*(volatile unsigned long *)(LCD_BASE_ADDR + 0x014))
+#define LCD_CTRL (*(volatile unsigned long *)(LCD_BASE_ADDR + 0x018))
+#define LCD_INTMSK (*(volatile unsigned long *)(LCD_BASE_ADDR + 0x01C))
+#define LCD_INTRAW (*(volatile unsigned long *)(LCD_BASE_ADDR + 0x020))
+#define LCD_INTSTAT (*(volatile unsigned long *)(LCD_BASE_ADDR + 0x024))
+#define LCD_INTCLR (*(volatile unsigned long *)(LCD_BASE_ADDR + 0x028))
+#define LCD_UPCURR (*(volatile unsigned long *)(LCD_BASE_ADDR + 0x02C))
+#define LCD_LPCURR (*(volatile unsigned long *)(LCD_BASE_ADDR + 0x030))
+#define LCD_PAL (*(volatile unsigned long *)(LCD_BASE_ADDR + 0x200))
+#define CRSR_IMG (*(volatile unsigned long *)(LCD_BASE_ADDR + 0x800))
+#define CRSR_CTRL (*(volatile unsigned long *)(LCD_BASE_ADDR + 0xC00))
+#define CRSR_CFG (*(volatile unsigned long *)(LCD_BASE_ADDR + 0xC04))
+#define CRSR_PAL0 (*(volatile unsigned long *)(LCD_BASE_ADDR + 0xC08))
+#define CRSR_PAL1 (*(volatile unsigned long *)(LCD_BASE_ADDR + 0xC0C))
+#define CRSR_XY (*(volatile unsigned long *)(LCD_BASE_ADDR + 0xC10))
+#define CRSR_CLIP (*(volatile unsigned long *)(LCD_BASE_ADDR + 0xC14))
+#define CRSR_INTMSK (*(volatile unsigned long *)(LCD_BASE_ADDR + 0xC20))
+#define CRSR_INTCLR (*(volatile unsigned long *)(LCD_BASE_ADDR + 0xC24))
+#define CRSR_INTRAW (*(volatile unsigned long *)(LCD_BASE_ADDR + 0xC28))
+#define CRSR_INTSTAT (*(volatile unsigned long *)(LCD_BASE_ADDR + 0xC2C))
+
+struct rt_hw_register
+{
+ unsigned long r0;
+ unsigned long r1;
+ unsigned long r2;
+ unsigned long r3;
+ unsigned long r4;
+ unsigned long r5;
+ unsigned long r6;
+ unsigned long r7;
+ unsigned long r8;
+ unsigned long r9;
+ unsigned long r10;
+ unsigned long fp;
+ unsigned long ip;
+ unsigned long sp;
+ unsigned long lr;
+ unsigned long pc;
+ unsigned long cpsr;
+ unsigned long ORIG_r0;
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // __LPC24xx_H
+
diff --git a/libcpu/arm/lpc24xx/context_gcc.S b/libcpu/arm/lpc24xx/context_gcc.S
new file mode 100644
index 0000000000..c83ac53dfc
--- /dev/null
+++ b/libcpu/arm/lpc24xx/context_gcc.S
@@ -0,0 +1,99 @@
+/*
+ * File : context.S
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2008-12-11 XuXinming first version
+ */
+
+/*!
+ * \addtogroup LPC2478
+ */
+/*@{*/
+
+#define NOINT 0xc0
+
+/*
+ * rt_base_t rt_hw_interrupt_disable();
+ */
+.globl rt_hw_interrupt_disable
+rt_hw_interrupt_disable:
+ mrs r0, cpsr
+ orr r1, r0, #NOINT
+ msr cpsr_c, r1
+ mov pc, lr
+
+/*
+ * void rt_hw_interrupt_enable(rt_base_t level);
+ */
+.globl rt_hw_interrupt_enable
+rt_hw_interrupt_enable:
+ msr cpsr, r0
+ mov pc, lr
+
+/*
+ * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
+ * r0 --> from
+ * r1 --> to
+ */
+.globl rt_hw_context_switch
+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
+ stmfd sp!, {r4} @ push cpsr
+ mrs r4, spsr
+ stmfd sp!, {r4} @ push spsr
+
+ str sp, [r0] @ store sp in preempted tasks TCB
+ ldr sp, [r1] @ get new task stack pointer
+
+ ldmfd sp!, {r4} @ pop new task spsr
+ msr spsr_cxsf, r4
+ ldmfd sp!, {r4} @ pop new task cpsr
+ msr cpsr_cxsf, r4
+
+ ldmfd sp!, {r0-r12, lr, pc} @ pop new task r0-r12, lr & pc
+
+/*
+ * void rt_hw_context_switch_to(rt_uint32 to);
+ * r0 --> to
+ */
+.globl rt_hw_context_switch_to
+rt_hw_context_switch_to:
+ ldr sp, [r0] @ get new task stack pointer
+
+ ldmfd sp!, {r4} @ pop new task spsr
+ msr spsr_cxsf, r4
+ ldmfd sp!, {r4} @ pop new task cpsr
+ msr cpsr_cxsf, r4
+
+ ldmfd sp!, {r0-r12, lr, pc} @ pop new task r0-r12, lr & pc
+
+/*
+ * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to);
+ */
+.globl rt_thread_switch_interrput_flag
+.globl rt_interrupt_from_thread
+.globl rt_interrupt_to_thread
+.globl rt_hw_context_switch_interrupt
+rt_hw_context_switch_interrupt:
+ ldr r2, =rt_thread_switch_interrput_flag
+ ldr r3, [r2]
+ cmp r3, #1
+ beq _reswitch
+ mov r3, #1 @ set rt_thread_switch_interrput_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]
+ mov pc, lr
diff --git a/libcpu/arm/lpc24xx/context_rvds.s b/libcpu/arm/lpc24xx/context_rvds.s
new file mode 100644
index 0000000000..82c5adc574
--- /dev/null
+++ b/libcpu/arm/lpc24xx/context_rvds.s
@@ -0,0 +1,107 @@
+;/*
+; * File : context_rvds.S
+; * This file is part of RT-Thread RTOS
+; * COPYRIGHT (C) 2006, RT-Thread Development Team
+; *
+; * The license and distribution terms for this file may be
+; * found in the file LICENSE in this distribution or at
+; * http://www.rt-thread.org/license/LICENSE
+; *
+; * Change Logs:
+; * Date Author Notes
+; * 2009-01-20 Bernard first version
+; */
+
+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
+ STMFD sp!, {r4} ; push cpsr
+ MRS r4, spsr
+ STMFD sp!, {r4} ; push spsr
+
+ STR sp, [r0] ; store sp in preempted tasks TCB
+ LDR sp, [r1] ; get new task stack pointer
+
+ LDMFD sp!, {r4} ; pop new task spsr
+ MSR spsr_cxsf, r4
+ LDMFD sp!, {r4} ; pop new task cpsr
+ MSR cpsr_cxsf, r4
+
+ LDMFD sp!, {r0-r12, lr, pc} ; pop new task r0-r12, lr & pc
+ 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 spsr
+ MSR spsr_cxsf, r4
+ LDMFD sp!, {r4} ; pop new task cpsr
+ MSR cpsr_cxsf, r4
+
+ LDMFD sp!, {r0-r12, lr, pc} ; pop new task r0-r12, lr & pc
+ ENDP
+
+;/*
+; * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to);
+; */
+ IMPORT rt_thread_switch_interrput_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_interrput_flag
+ LDR r3, [r2]
+ CMP r3, #1
+ BEQ _reswitch
+ MOV r3, #1 ; set rt_thread_switch_interrput_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
+
+ END \ No newline at end of file
diff --git a/libcpu/arm/lpc24xx/cpu.c b/libcpu/arm/lpc24xx/cpu.c
new file mode 100644
index 0000000000..0265ed96aa
--- /dev/null
+++ b/libcpu/arm/lpc24xx/cpu.c
@@ -0,0 +1,42 @@
+/*
+ * File : cpu.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Develop Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2008-12-11 XuXinming first version
+ */
+
+#include <rtthread.h>
+#include "LPC24xx.h"
+
+/**
+ * @addtogroup LPC2478
+ */
+/*@{*/
+
+/**
+ * this function will reset CPU
+ *
+ */
+void rt_hw_cpu_reset()
+{
+}
+
+/**
+ * this function will shutdown CPU
+ *
+ */
+void rt_hw_cpu_shutdown()
+{
+ rt_kprintf("shutdown...\n");
+
+ while (1);
+}
+
+/*@}*/
diff --git a/libcpu/arm/lpc24xx/interrupt.c b/libcpu/arm/lpc24xx/interrupt.c
new file mode 100644
index 0000000000..0b573d57e7
--- /dev/null
+++ b/libcpu/arm/lpc24xx/interrupt.c
@@ -0,0 +1,86 @@
+/*
+ * File : trap.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2008-12-11 XuXinming first version
+ */
+
+#include <rtthread.h>
+#include "LPC24xx.h"
+
+#define MAX_HANDLERS 32
+
+extern rt_uint32_t rt_interrupt_nest;
+
+/* exception and interrupt handler table */
+rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread;
+rt_uint32_t rt_thread_switch_interrput_flag;
+
+
+/**
+ * @addtogroup LPC2478
+ */
+/*@{*/
+
+void rt_hw_interrupt_handle(int vector)
+{
+ rt_kprintf("Unhandled interrupt %d occured!!!\n", vector);
+}
+
+void rt_hw_interrupt_init()
+{
+ register int i;
+
+ rt_uint32_t *vect_addr, *vect_cntl;
+
+ /* initialize VIC*/
+ VICIntEnClr = 0xffffffff;
+ VICVectAddr = 0;
+ VICIntSelect = 0;
+
+ for ( i = 0; i < 32; i++ )
+ {
+ vect_addr = (rt_uint32_t *)(VIC_BASE_ADDR + 0x100 + i*4);
+ vect_cntl = (rt_uint32_t *)(VIC_BASE_ADDR + 0x200 + i*4);
+ *vect_addr = 0x0;
+ *vect_cntl = 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_interrput_flag = 0;
+}
+
+void rt_hw_interrupt_mask(int vector)
+{
+ VICIntEnClr = (1 << vector);
+}
+
+void rt_hw_interrupt_umask(int vector)
+{
+ VICIntEnable = (1 << vector);
+}
+
+void rt_hw_interrupt_install(int vector, rt_isr_handler_t new_handler, rt_isr_handler_t *old_handler)
+{
+ rt_uint32_t *vect_addr;
+
+ if(vector < MAX_HANDLERS)
+ {
+ /* find first un-assigned VIC address for the handler */
+ vect_addr = (rt_uint32_t *)(VIC_BASE_ADDR + 0x100 + vector*4);
+ *vect_addr = (rt_uint32_t)new_handler; /* set interrupt vector */
+ }
+}
+
+/*@}*/
diff --git a/libcpu/arm/lpc24xx/serial.c b/libcpu/arm/lpc24xx/serial.c
new file mode 100644
index 0000000000..d3960a5e00
--- /dev/null
+++ b/libcpu/arm/lpc24xx/serial.c
@@ -0,0 +1,149 @@
+/*
+ * File : serial.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2006-08-23 Bernard first version
+ */
+
+#include <rthw.h>
+#include <rtthread.h>
+#include "lpc214x.h"
+#include "board.h"
+
+void rt_serial_init(void);
+
+#define PCLK 18000000
+#define BAUD_RATE 115200
+#define U0PINS 0x00000005
+
+/**
+ * @addtogroup LPC2100
+ */
+/*@{*/
+
+/**
+ * This function is used to display a string on console, normally, it's
+ * invoked by rt_kprintf
+ *
+ * @param str the displayed string
+ */
+void rt_console_puts(const char* str)
+{
+ while (*str)
+ {
+ rt_serial_putc (*str++);
+ }
+}
+
+#define UART_RX_BUFFER_SIZE 64
+static rt_uint8_t uart_rx_buffer[UART_RX_BUFFER_SIZE];
+static rt_uint32_t uart_read_index, uart_save_index;
+
+/**
+ * This function initializes serial
+ */
+void rt_serial_init()
+{
+ unsigned long Fdiv;
+
+ PINSEL0 = 0x00000050; /* RxD0 and TxD0 */
+
+ rt_memset(uart_rx_buffer, 0, sizeof(uart_rx_buffer));
+ uart_read_index = uart_save_index = 0;
+
+ U0LCR = 0x83; /* 8 bits, no Parity, 1 Stop bit */
+ /*PCLK select is 00,so /4*/
+ Fdiv = ( PCLK / 16 ) / BAUD_RATE ; /*baud rate */
+ U0DLM = Fdiv / 256;
+ U0DLL = Fdiv % 256;
+ U0FCR = 0x00; /* Enable and reset TX and RX FIFO. */
+ U0LCR = 0x03; /* DLAB = 0 */
+}
+
+/* save a char to serial buffer */
+void rt_serial_savechar(char ch)
+{
+ rt_base_t level;
+
+ /* disable interrupt */
+ level = rt_hw_interrupt_disable();
+
+ uart_rx_buffer[uart_save_index] = ch;
+ uart_save_index ++;
+ if (uart_save_index >= UART_RX_BUFFER_SIZE)
+ uart_save_index = 0;
+
+ /* if the next position is read index, discard this 'read char' */
+ if (uart_save_index == uart_read_index)
+ {
+ uart_read_index ++;
+ if (uart_read_index >= UART_RX_BUFFER_SIZE)
+ uart_read_index = 0;
+ }
+
+ /* enable interrupt */
+ rt_hw_interrupt_enable(level);
+}
+
+/**
+ * This function read a character from serial without interrupt enable mode
+ *
+ * @return the read char
+ */
+char rt_serial_getc()
+{
+ char ch;
+ rt_base_t level;
+
+ /* disable interrupt */
+ level = rt_hw_interrupt_disable();
+
+ if (uart_read_index != uart_save_index)
+ {
+ ch = uart_rx_buffer[uart_read_index];
+
+ uart_read_index ++;
+ if (uart_read_index >= UART_RX_BUFFER_SIZE)
+ uart_read_index = 0;
+
+ /* enable interrupt */
+ rt_hw_interrupt_enable(level);
+
+ return ch;
+ }
+
+ /* enable interrupt */
+ rt_hw_interrupt_enable(level);
+
+ return 0;
+}
+
+/**
+ * This function will write a character to serial without interrupt enable mode
+ *
+ * @param c the char to write
+ */
+void rt_serial_putc(const char c)
+{
+ /*
+ to be polite with serial console add a line feed
+ to the carriage return character
+ */
+ if (c=='\n')
+ {
+ while (!(U0LSR & 0x20));
+ U0THR = '\r';
+ }
+
+ while (!(U0LSR & 0x20));
+ U0THR = c;
+}
+
+/*@}*/
diff --git a/libcpu/arm/lpc24xx/stack.c b/libcpu/arm/lpc24xx/stack.c
new file mode 100644
index 0000000000..bfd4bc652c
--- /dev/null
+++ b/libcpu/arm/lpc24xx/stack.c
@@ -0,0 +1,60 @@
+/*
+ * File : stack.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2008-12-11 XuXinming first version
+ */
+#include <rtthread.h>
+#include "LPC24xx.h"
+
+/**
+ * @addtogroup LPC2478
+ */
+/*@{*/
+
+/**
+ * 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 */
+ *(--stk) = SVCMODE; /* cpsr */
+ *(--stk) = SVCMODE; /* spsr */
+
+ /* return task's current stack address */
+ return (rt_uint8_t *)stk;
+}
+
+/*@}*/
diff --git a/libcpu/arm/lpc24xx/start_gcc.S b/libcpu/arm/lpc24xx/start_gcc.S
new file mode 100644
index 0000000000..bd473bc0cd
--- /dev/null
+++ b/libcpu/arm/lpc24xx/start_gcc.S
@@ -0,0 +1,214 @@
+/*
+ * File : start.S
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2008-12-11 XuXinming first version
+ */
+
+/**
+ * @addtogroup LPC2478
+ */
+/*@{*/
+
+#define WDMOD (0xE0000000 + 0x00)
+#define VICIntEnClr (0xFFFFF000 + 0x014)
+#define VICVectAddr (0xFFFFF000 + 0xF00)
+#define VICIntSelect (0xFFFFF000 + 0x00C)
+#define PLLCFG (0xE01FC000 + 0x084)
+#define PLLCON (0xE01FC000 + 0x080)
+#define PLLFEED (0xE01FC000 + 0x08C)
+#define PLLSTAT (0xE01FC000 + 0x088)
+#define CCLKCFG (0xE01FC000 + 0x104)
+#define MEMMAP (0xE01FC000 + 0x040)
+#define SCS (0xE01FC000 + 0x1A0)
+#define CLKSRCSEL (0xE01FC000 + 0x10C)
+#define MAMCR (0xE01FC000 + 0x000)
+#define MAMTIM (0xE01FC000 + 0x004)
+
+
+/*.section .init, "ax"*/
+.section .vectors
+.code 32
+.globl _start
+_start:
+ b reset
+ ldr pc, _vector_undef
+ ldr pc, _vector_swi
+ ldr pc, _vector_pabt
+ ldr pc, _vector_dabt
+ ldr pc, _vector_resv
+ ldr pc, _vector_irq
+ ldr pc, _vector_fiq
+
+_vector_undef: .word vector_undef
+_vector_swi: .word vector_swi
+_vector_pabt: .word vector_pabt
+_vector_dabt: .word vector_dabt
+_vector_resv: .word vector_resv
+_vector_irq: .word vector_irq
+_vector_fiq: .word vector_fiq
+
+.text
+.code 32
+
+/* the system entry */
+reset:
+ /* enter svc mode */
+ msr cpsr_c, #SVCMODE|NOINT
+
+ /*watch dog disable */
+ ldr r0,=WDMOD
+ ldr r1,=0x0
+ str r1,[r0]
+
+ /* all interrupt disable */
+ ldr r0,=VICIntEnClr
+ ldr r1,=0xffffffff
+ str r1,[r0]
+
+ ldr r1, =VICVectAddr
+ ldr r0, =0x00
+ str r0, [r1]
+
+ ldr r1, =VICIntSelect
+ ldr r0, =0x00
+ str r0, [r1]
+
+ /* setup stack */
+ bl stack_setup
+
+_rtthread_startup: .word rtthread_startup
+
+ .equ USERMODE, 0x10
+ .equ FIQMODE, 0x11
+ .equ IRQMODE, 0x12
+ .equ SVCMODE, 0x13
+ .equ ABORTMODE, 0x17
+ .equ UNDEFMODE, 0x1b
+ .equ MODEMASK, 0x1f
+ .equ NOINT, 0xc0
+
+/* exception handlers */
+vector_undef: bl rt_hw_trap_udef
+vector_swi: bl rt_hw_trap_swi
+vector_pabt: bl rt_hw_trap_pabt
+vector_dabt: bl rt_hw_trap_dabt
+vector_resv: bl rt_hw_trap_resv
+
+.globl rt_interrupt_enter
+.globl rt_interrupt_leave
+.globl rt_thread_switch_interrput_flag
+.globl rt_interrupt_from_thread
+.globl rt_interrupt_to_thread
+vector_irq:
+ stmfd sp!, {r0-r12,lr}
+ bl rt_interrupt_enter
+ bl rt_hw_trap_irq
+ bl rt_interrupt_leave
+
+ /* if rt_thread_switch_interrput_flag set, jump to _interrupt_thread_switch and don't return */
+ ldr r0, =rt_thread_switch_interrput_flag
+ ldr r1, [r0]
+ cmp r1, #1
+ beq _interrupt_thread_switch
+
+ ldmfd sp!, {r0-r12,lr}
+ subs pc, lr, #4
+
+ .align 5
+vector_fiq:
+ stmfd sp!,{r0-r7,lr}
+ bl rt_hw_trap_fiq
+ ldmfd sp!,{r0-r7,lr}
+ subs pc,lr,#4
+
+_interrupt_thread_switch:
+ mov r1, #0 @ clear rt_thread_switch_interrput_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 @ disable interrupt
+ orr r0, r3, #NOINT
+ msr spsr_c, r0
+
+ ldr r0, =.+8 @ switch to interrupted task's stack
+ movs pc, r0
+
+ 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 psr
+ mrs r4, spsr
+ stmfd sp!, {r4} @ push old task's spsr
+
+ 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 spsr
+ msr SPSR_cxsf, r4
+ ldmfd sp!, {r4} @ pop new task's psr
+ msr CPSR_cxsf, r4
+
+ ldmfd sp!, {r0-r12,lr,pc} @ pop new task's r0-r12,lr & pc
+
+/* each mode stack memory */
+stack_setup:
+ mrs r0, cpsr
+ bic r0, r0, #MODEMASK
+ orr r1, r0, #UNDEFMODE|NOINT
+ msr cpsr_cxsf, r1 @ undef mode
+ ldr sp, =__UndStack_end
+
+ mrs r0, cpsr
+ bic r0, r0, #MODEMASK
+ orr r1,r0,#ABORTMODE|NOINT
+ msr cpsr_cxsf,r1 @ abort mode
+ ldr sp,=__ABTStack_end
+
+ mrs r0, cpsr
+ bic r0, r0, #MODEMASK
+ orr r1,r0,#IRQMODE|NOINT
+ msr cpsr_cxsf,r1 @ IRQ mode
+ ldr sp,=__IRQStack_end
+
+ mrs r0, cpsr
+ bic r0, r0, #MODEMASK
+ orr r1,r0,#FIQMODE|NOINT
+ msr cpsr_cxsf,r1 @ FIQ mode
+ ldr sp,=__FIQStack_end
+
+ mrs r0, cpsr
+ bic r0, r0, #MODEMASK
+ orr r1,r0,#SVCMODE|NOINT
+ msr cpsr_cxsf,r1 @ SVC mode
+ ldr sp,=__SVCStack_end
+
+ /* USER mode is not initialized. */
+ mrs r0, cpsr
+ bic r0, r0, #MODEMASK|0x80 //IRQ enable and FIQ disable
+ orr r1,r0,#USERMODE
+ msr cpsr_cxsf,r1 @ usr mode
+ ldr sp,=__USRStack_end
+
+ ldr pc, _rtthread_startup
+
diff --git a/libcpu/arm/lpc24xx/start_rvds.s b/libcpu/arm/lpc24xx/start_rvds.s
new file mode 100644
index 0000000000..a5b9de7d47
--- /dev/null
+++ b/libcpu/arm/lpc24xx/start_rvds.s
@@ -0,0 +1,1581 @@
+;/*****************************************************************************/
+;/* LPC2400.S: Startup file for Philips LPC2400 device series */
+;/*****************************************************************************/
+;/* <<< Use Configuration Wizard in Context Menu >>> */
+;/*****************************************************************************/
+;/* This file is part of the uVision/ARM development tools. */
+;/* Copyright (c) 2007-2008 Keil - An ARM Company. 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 LPC2400.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.
+; *
+; * NO_CLOCK_SETUP: when set the startup code will not initialize Clock
+; * (used mostly when clock is already initialized from script .ini
+; * file).
+; *
+; * NO_EMC_SETUP: when set the startup code will not initialize
+; * External Bus Controller.
+; *
+; * RAM_INTVEC: when set the startup code copies exception vectors
+; * from on-chip Flash to on-chip RAM.
+; *
+; * 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)
+; * 0x40000000 when RAM_MODE is used
+; * 0x80000000 when EXTMEM_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.
+; */
+
+
+; 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
+
+
+;----------------------- Memory Definitions ------------------------------------
+
+; Internal Memory Base Addresses
+FLASH_BASE EQU 0x00000000
+RAM_BASE EQU 0x40000000
+EXTMEM_BASE EQU 0x80000000
+
+; External Memory Base Addresses
+STA_MEM0_BASE EQU 0x80000000
+STA_MEM1_BASE EQU 0x81000000
+STA_MEM2_BASE EQU 0x82000000
+STA_MEM3_BASE EQU 0x83000000
+DYN_MEM0_BASE EQU 0xA0000000
+DYN_MEM1_BASE EQU 0xB0000000
+DYN_MEM2_BASE EQU 0xC0000000
+DYN_MEM3_BASE EQU 0xD0000000
+
+
+;----------------------- Stack and Heap Definitions ----------------------------
+
+;// <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
+
+
+;----------------------- Clock Definitions -------------------------------------
+
+; System Control Block (SCB) Module Definitions
+SCB_BASE EQU 0xE01FC000 ; SCB Base Address
+PLLCON_OFS EQU 0x80 ; PLL Control Offset
+PLLCFG_OFS EQU 0x84 ; PLL Configuration Offset
+PLLSTAT_OFS EQU 0x88 ; PLL Status Offset
+PLLFEED_OFS EQU 0x8C ; PLL Feed Offset
+CCLKCFG_OFS EQU 0x104 ; CPU Clock Divider Reg Offset
+USBCLKCFG_OFS EQU 0x108 ; USB Clock Divider Reg Offset
+CLKSRCSEL_OFS EQU 0x10C ; Clock Source Sel Reg Offset
+SCS_OFS EQU 0x1A0 ; Sys Control and Status Reg Offset
+PCLKSEL0_OFS EQU 0x1A8 ; Periph Clock Sel Reg 0 Offset
+PCLKSEL1_OFS EQU 0x1AC ; Periph Clock Sel Reg 0 Offset
+
+PCON_OFS EQU 0x0C0 ; Power Mode Control Reg Offset
+PCONP_OFS EQU 0x0C4 ; Power Control for Periphs Reg Offset
+
+; Constants
+OSCRANGE EQU (1<<4) ; Oscillator Range Select
+OSCEN EQU (1<<5) ; Main oscillator Enable
+OSCSTAT EQU (1<<6) ; Main Oscillator Status
+PLLCON_PLLE EQU (1<<0) ; PLL Enable
+PLLCON_PLLC EQU (1<<1) ; PLL Connect
+PLLSTAT_M EQU (0x7FFF<<0) ; PLL M Value
+PLLSTAT_N EQU (0xFF<<16) ; PLL N Value
+PLLSTAT_PLOCK EQU (1<<26) ; PLL Lock Status
+
+;// <e> Clock Setup
+;// <h> System Controls and Status Register (SYS)
+;// <o1.4> OSCRANGE: Main Oscillator Range Select
+;// <0=> 1 MHz to 20 MHz
+;// <1=> 15 MHz to 24 MHz
+;// <e1.5> OSCEN: Main Oscillator Enable
+;// </e>
+;// </h>
+;//
+;// <h> PLL Clock Source Select Register (CLKSRCSEL)
+;// <o2.0..1> CLKSRC: PLL Clock Source Selection
+;// <0=> Internal RC oscillator
+;// <1=> Main oscillator
+;// <2=> RTC oscillator
+;// </h>
+;//
+;// <h> PLL Configuration Register (PLLCFG)
+;// <i> PLL_clk = (2* M * PLL_clk_src) / N
+;// <o3.0..14> MSEL: PLL Multiplier Selection
+;// <1-32768><#-1>
+;// <i> M Value
+;// <o3.16..23> NSEL: PLL Divider Selection
+;// <1-256><#-1>
+;// <i> N Value
+;// </h>
+;//
+;// <h> CPU Clock Configuration Register (CCLKCFG)
+;// <o4.0..7> CCLKSEL: Divide Value for CPU Clock from PLL
+;// <1-256><#-1>
+;// </h>
+;//
+;// <h> USB Clock Configuration Register (USBCLKCFG)
+;// <o5.0..3> USBSEL: Divide Value for USB Clock from PLL
+;// <1-16><#-1>
+;// </h>
+;//
+;// <h> Peripheral Clock Selection Register 0 (PCLKSEL0)
+;// <o6.0..1> PCLK_WDT: Peripheral Clock Selection for WDT
+;// <0=> Pclk = Cclk / 4
+;// <1=> Pclk = Cclk
+;// <2=> Pclk = Cclk / 2
+;// <3=> Pclk = Cclk / 8
+;// <o6.2..3> PCLK_TIMER0: Peripheral Clock Selection for TIMER0
+;// <0=> Pclk = Cclk / 4
+;// <1=> Pclk = Cclk
+;// <2=> Pclk = Cclk / 2
+;// <3=> Pclk = Cclk / 8
+;// <o6.4..5> PCLK_TIMER1: Peripheral Clock Selection for TIMER1
+;// <0=> Pclk = Cclk / 4
+;// <1=> Pclk = Cclk
+;// <2=> Pclk = Cclk / 2
+;// <3=> Pclk = Cclk / 8
+;// <o6.6..7> PCLK_UART0: Peripheral Clock Selection for UART0
+;// <0=> Pclk = Cclk / 4
+;// <1=> Pclk = Cclk
+;// <2=> Pclk = Cclk / 2
+;// <3=> Pclk = Cclk / 8
+;// <o6.8..9> PCLK_UART1: Peripheral Clock Selection for UART1
+;// <0=> Pclk = Cclk / 4
+;// <1=> Pclk = Cclk
+;// <2=> Pclk = Cclk / 2
+;// <3=> Pclk = Cclk / 8
+;// <o6.10..11> PCLK_PWM0: Peripheral Clock Selection for PWM0
+;// <0=> Pclk = Cclk / 4
+;// <1=> Pclk = Cclk
+;// <2=> Pclk = Cclk / 2
+;// <3=> Pclk = Cclk / 8
+;// <o6.12..13> PCLK_PWM1: Peripheral Clock Selection for PWM1
+;// <0=> Pclk = Cclk / 4
+;// <1=> Pclk = Cclk
+;// <2=> Pclk = Cclk / 2
+;// <3=> Pclk = Cclk / 8
+;// <o6.14..15> PCLK_I2C0: Peripheral Clock Selection for I2C0
+;// <0=> Pclk = Cclk / 4
+;// <1=> Pclk = Cclk
+;// <2=> Pclk = Cclk / 2
+;// <3=> Pclk = Cclk / 8
+;// <o6.16..17> PCLK_SPI: Peripheral Clock Selection for SPI
+;// <0=> Pclk = Cclk / 4
+;// <1=> Pclk = Cclk
+;// <2=> Pclk = Cclk / 2
+;// <3=> Pclk = Cclk / 8
+;// <o6.18..19> PCLK_RTC: Peripheral Clock Selection for RTC
+;// <0=> Pclk = Cclk / 4
+;// <1=> Pclk = Cclk
+;// <2=> Pclk = Cclk / 2
+;// <3=> Pclk = Cclk / 8
+;// <o6.20..21> PCLK_SSP1: Peripheral Clock Selection for SSP1
+;// <0=> Pclk = Cclk / 4
+;// <1=> Pclk = Cclk
+;// <2=> Pclk = Cclk / 2
+;// <3=> Pclk = Cclk / 8
+;// <o6.22..23> PCLK_DAC: Peripheral Clock Selection for DAC
+;// <0=> Pclk = Cclk / 4
+;// <1=> Pclk = Cclk
+;// <2=> Pclk = Cclk / 2
+;// <3=> Pclk = Cclk / 8
+;// <o6.24..25> PCLK_ADC: Peripheral Clock Selection for ADC
+;// <0=> Pclk = Cclk / 4
+;// <1=> Pclk = Cclk
+;// <2=> Pclk = Cclk / 2
+;// <3=> Pclk = Cclk / 8
+;// <o6.26..27> PCLK_CAN1: Peripheral Clock Selection for CAN1
+;// <0=> Pclk = Cclk / 4
+;// <1=> Pclk = Cclk
+;// <2=> Pclk = Cclk / 2
+;// <3=> Pclk = Cclk / 6
+;// <o6.28..29> PCLK_CAN2: Peripheral Clock Selection for CAN2
+;// <0=> Pclk = Cclk / 4
+;// <1=> Pclk = Cclk
+;// <2=> Pclk = Cclk / 2
+;// <3=> Pclk = Cclk / 6
+;// <o6.30..31> PCLK_ACF: Peripheral Clock Selection for ACF
+;// <0=> Pclk = Cclk / 4
+;// <1=> Pclk = Cclk
+;// <2=> Pclk = Cclk / 2
+;// <3=> Pclk = Cclk / 6
+;// </h>
+;//
+;// <h> Peripheral Clock Selection Register 1 (PCLKSEL1)
+;// <o7.0..1> PCLK_BAT_RAM: Peripheral Clock Selection for the Battery Supported RAM
+;// <0=> Pclk = Cclk / 4
+;// <1=> Pclk = Cclk
+;// <2=> Pclk = Cclk / 2
+;// <3=> Pclk = Cclk / 8
+;// <o7.2..3> PCLK_GPIO: Peripheral Clock Selection for GPIOs
+;// <0=> Pclk = Cclk / 4
+;// <1=> Pclk = Cclk
+;// <2=> Pclk = Cclk / 2
+;// <3=> Pclk = Cclk / 8
+;// <o7.4..5> PCLK_PCB: Peripheral Clock Selection for Pin Connect Block
+;// <0=> Pclk = Cclk / 4
+;// <1=> Pclk = Cclk
+;// <2=> Pclk = Cclk / 2
+;// <3=> Pclk = Cclk / 8
+;// <o7.6..7> PCLK_I2C1: Peripheral Clock Selection for I2C1
+;// <0=> Pclk = Cclk / 4
+;// <1=> Pclk = Cclk
+;// <2=> Pclk = Cclk / 2
+;// <3=> Pclk = Cclk / 8
+;// <o7.10..11> PCLK_SSP0: Peripheral Clock Selection for SSP0
+;// <0=> Pclk = Cclk / 4
+;// <1=> Pclk = Cclk
+;// <2=> Pclk = Cclk / 2
+;// <3=> Pclk = Cclk / 8
+;// <o7.12..13> PCLK_TIMER2: Peripheral Clock Selection for TIMER2
+;// <0=> Pclk = Cclk / 4
+;// <1=> Pclk = Cclk
+;// <2=> Pclk = Cclk / 2
+;// <3=> Pclk = Cclk / 8
+;// <o7.14..15> PCLK_TIMER3: Peripheral Clock Selection for TIMER3
+;// <0=> Pclk = Cclk / 4
+;// <1=> Pclk = Cclk
+;// <2=> Pclk = Cclk / 2
+;// <3=> Pclk = Cclk / 8
+;// <o7.16..17> PCLK_UART2: Peripheral Clock Selection for UART2
+;// <0=> Pclk = Cclk / 4
+;// <1=> Pclk = Cclk
+;// <2=> Pclk = Cclk / 2
+;// <3=> Pclk = Cclk / 8
+;// <o7.18..19> PCLK_UART3: Peripheral Clock Selection for UART3
+;// <0=> Pclk = Cclk / 4
+;// <1=> Pclk = Cclk
+;// <2=> Pclk = Cclk / 2
+;// <3=> Pclk = Cclk / 8
+;// <o7.20..21> PCLK_I2C2: Peripheral Clock Selection for I2C2
+;// <0=> Pclk = Cclk / 4
+;// <1=> Pclk = Cclk
+;// <2=> Pclk = Cclk / 2
+;// <3=> Pclk = Cclk / 8
+;// <o7.22..23> PCLK_I2S: Peripheral Clock Selection for I2S
+;// <0=> Pclk = Cclk / 4
+;// <1=> Pclk = Cclk
+;// <2=> Pclk = Cclk / 2
+;// <3=> Pclk = Cclk / 8
+;// <o7.24..25> PCLK_MCI: Peripheral Clock Selection for MCI
+;// <0=> Pclk = Cclk / 4
+;// <1=> Pclk = Cclk
+;// <2=> Pclk = Cclk / 2
+;// <3=> Pclk = Cclk / 8
+;// <o7.28..29> PCLK_SYSCON: Peripheral Clock Selection for System Control Block
+;// <0=> Pclk = Cclk / 4
+;// <1=> Pclk = Cclk
+;// <2=> Pclk = Cclk / 2
+;// <3=> Pclk = Cclk / 8
+;// </h>
+;// </e>
+CLOCK_SETUP EQU 1
+SCS_Val EQU 0x00000020
+CLKSRCSEL_Val EQU 0x00000001
+PLLCFG_Val EQU 0x0000000B
+CCLKCFG_Val EQU 0x00000004
+USBCLKCFG_Val EQU 0x00000005
+PCLKSEL0_Val EQU 0x00000000
+PCLKSEL1_Val EQU 0x00000000
+
+
+;----------------------- 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
+
+
+;----------------------- Pin Connect Block Definitions -------------------------
+
+PCB_BASE EQU 0xE002C000 ; PCB Base Address
+PINSEL0_OFS EQU 0x00 ; PINSEL0 Address Offset
+PINSEL1_OFS EQU 0x04 ; PINSEL1 Address Offset
+PINSEL2_OFS EQU 0x08 ; PINSEL2 Address Offset
+PINSEL3_OFS EQU 0x0C ; PINSEL3 Address Offset
+PINSEL4_OFS EQU 0x10 ; PINSEL4 Address Offset
+PINSEL5_OFS EQU 0x14 ; PINSEL5 Address Offset
+PINSEL6_OFS EQU 0x18 ; PINSEL6 Address Offset
+PINSEL7_OFS EQU 0x1C ; PINSEL7 Address Offset
+PINSEL8_OFS EQU 0x20 ; PINSEL8 Address Offset
+PINSEL9_OFS EQU 0x24 ; PINSEL9 Address Offset
+PINSEL10_OFS EQU 0x28 ; PINSEL10 Address Offset
+
+
+;----------------------- External Memory Controller (EMC) Definitons -----------
+
+EMC_BASE EQU 0xFFE08000 ; EMC Base Address
+
+EMC_CTRL_OFS EQU 0x000
+EMC_STAT_OFS EQU 0x004
+EMC_CONFIG_OFS EQU 0x008
+EMC_DYN_CTRL_OFS EQU 0x020
+EMC_DYN_RFSH_OFS EQU 0x024
+EMC_DYN_RD_CFG_OFS EQU 0x028
+EMC_DYN_RP_OFS EQU 0x030
+EMC_DYN_RAS_OFS EQU 0x034
+EMC_DYN_SREX_OFS EQU 0x038
+EMC_DYN_APR_OFS EQU 0x03C
+EMC_DYN_DAL_OFS EQU 0x040
+EMC_DYN_WR_OFS EQU 0x044
+EMC_DYN_RC_OFS EQU 0x048
+EMC_DYN_RFC_OFS EQU 0x04C
+EMC_DYN_XSR_OFS EQU 0x050
+EMC_DYN_RRD_OFS EQU 0x054
+EMC_DYN_MRD_OFS EQU 0x058
+EMC_DYN_CFG0_OFS EQU 0x100
+EMC_DYN_RASCAS0_OFS EQU 0x104
+EMC_DYN_CFG1_OFS EQU 0x140
+EMC_DYN_RASCAS1_OFS EQU 0x144
+EMC_DYN_CFG2_OFS EQU 0x160
+EMC_DYN_RASCAS2_OFS EQU 0x164
+EMC_DYN_CFG3_OFS EQU 0x180
+EMC_DYN_RASCAS3_OFS EQU 0x184
+EMC_STA_CFG0_OFS EQU 0x200
+EMC_STA_WWEN0_OFS EQU 0x204
+EMC_STA_WOEN0_OFS EQU 0x208
+EMC_STA_WRD0_OFS EQU 0x20C
+EMC_STA_WPAGE0_OFS EQU 0x210
+EMC_STA_WWR0_OFS EQU 0x214
+EMC_STA_WTURN0_OFS EQU 0x218
+EMC_STA_CFG1_OFS EQU 0x220
+EMC_STA_WWEN1_OFS EQU 0x224
+EMC_STA_WOEN1_OFS EQU 0x228
+EMC_STA_WRD1_OFS EQU 0x22C
+EMC_STA_WPAGE1_OFS EQU 0x230
+EMC_STA_WWR1_OFS EQU 0x234
+EMC_STA_WTURN1_OFS EQU 0x238
+EMC_STA_CFG2_OFS EQU 0x240
+EMC_STA_WWEN2_OFS EQU 0x244
+EMC_STA_WOEN2_OFS EQU 0x248
+EMC_STA_WRD2_OFS EQU 0x24C
+EMC_STA_WPAGE2_OFS EQU 0x250
+EMC_STA_WWR2_OFS EQU 0x254
+EMC_STA_WTURN2_OFS EQU 0x258
+EMC_STA_CFG3_OFS EQU 0x260
+EMC_STA_WWEN3_OFS EQU 0x264
+EMC_STA_WOEN3_OFS EQU 0x268
+EMC_STA_WRD3_OFS EQU 0x26C
+EMC_STA_WPAGE3_OFS EQU 0x270
+EMC_STA_WWR3_OFS EQU 0x274
+EMC_STA_WTURN3_OFS EQU 0x278
+EMC_STA_EXT_W_OFS EQU 0x880
+
+; Constants
+NORMAL_CMD EQU (0x0 << 7) ; NORMAL Command
+MODE_CMD EQU (0x1 << 7) ; MODE Command
+PALL_CMD EQU (0x2 << 7) ; Precharge All Command
+NOP_CMD EQU (0x3 << 7) ; NOP Command
+
+BUFEN_Const EQU (1 << 19) ; Buffer enable bit
+EMC_PCONP_Const EQU (1 << 11) ; PCONP val to enable power for EMC
+
+; External Memory Pins definitions
+; pin functions for SDRAM, NOR and NAND flash interfacing
+EMC_PINSEL5_Val EQU 0x05010115 ; !CAS, !RAS, CLKOUT0, !DYCS0, DQMOUT0, DQMOUT1
+EMC_PINSEL6_Val EQU 0x55555555 ; D0 .. D15
+EMC_PINSEL8_Val EQU 0x55555555 ; A0 .. A15
+EMC_PINSEL9_Val EQU 0x50055555; ; A16 .. A23, !OE, !WE, !CS0, !CS1
+
+;// External Memory Controller Setup (EMC) ---------------------------------
+;// <e> External Memory Controller Setup (EMC)
+EMC_SETUP EQU 0
+
+;// <h> EMC Control Register (EMCControl)
+;// <i> Controls operation of the memory controller
+;// <o0.2> L: Low-power mode enable
+;// <o0.1> M: Address mirror enable
+;// <o0.0> E: EMC enable
+;// </h>
+EMC_CTRL_Val EQU 0x00000001
+
+;// <h> EMC Configuration Register (EMCConfig)
+;// <i> Configures operation of the memory controller
+;// <o0.8> CCLK: CLKOUT ratio
+;// <0=> 1:1
+;// <1=> 1:2
+;// <o0.0> Endian mode
+;// <0=> Little-endian
+;// <1=> Big-endian
+;// </h>
+EMC_CONFIG_Val EQU 0x00000000
+
+;// Dynamic Memory Interface Setup ---------------------------------------
+;// <e> Dynamic Memory Interface Setup
+EMC_DYNAMIC_SETUP EQU 1
+
+;// <h> Dynamic Memory Refresh Timer Register (EMCDynamicRefresh)
+;// <i> Configures dynamic memory refresh operation
+;// <o0.0..10> REFRESH: Refresh timer <0x000-0x7FF>
+;// <i> 0 = refresh disabled, 0x01-0x7FF: value * 16 CCLKS
+;// </h>
+EMC_DYN_RFSH_Val EQU 0x0000001C
+
+;// <h> Dynamic Memory Read Configuration Register (EMCDynamicReadConfig)
+;// <i> Configures the dynamic memory read strategy
+;// <o0.0..1> RD: Read data strategy
+;// <0=> Clock out delayed strategy
+;// <1=> Command delayed strategy
+;// <2=> Command delayed strategy plus one clock cycle
+;// <3=> Command delayed strategy plus two clock cycles
+;// </h>
+EMC_DYN_RD_CFG_Val EQU 0x00000001
+
+;// <h> Dynamic Memory Timings
+;// <h> Dynamic Memory Percentage Command Period Register (EMCDynamictRP)
+;// <o0.0..3> tRP: Precharge command period <1-16> <#-1>
+;// <i> The delay is in EMCCLK cycles
+;// <i> This value is normally found in SDRAM data sheets as tRP
+;// </h>
+;// <h> Dynamic Memory Active to Precharge Command Period Register (EMCDynamictRAS)
+;// <o1.0..3> tRAS: Active to precharge command period <1-16> <#-1>
+;// <i> The delay is in EMCCLK cycles
+;// <i> This value is normally found in SDRAM data sheets as tRAS
+;// </h>
+;// <h> Dynamic Memory Self-refresh Exit Time Register (EMCDynamictSREX)
+;// <o2.0..3> tSREX: Self-refresh exit time <1-16> <#-1>
+;// <i> The delay is in CCLK cycles
+;// <i> This value is normally found in SDRAM data sheets as tSREX,
+;// <i> for devices without this parameter you use the same value as tXSR
+;// </h>
+;// <h> Dynamic Memory Last Data Out to Active Time Register (EMCDynamictAPR)
+;// <o3.0..3> tAPR: Last-data-out to active command time <1-16> <#-1>
+;// <i> The delay is in CCLK cycles
+;// <i> This value is normally found in SDRAM data sheets as tAPR
+;// </h>
+;// <h> Dynamic Memory Data-in to Active Command Time Register (EMCDynamictDAL)
+;// <o4.0..3> tDAL: Data-in to active command time <1-16> <#-1>
+;// <i> The delay is in CCLK cycles
+;// <i> This value is normally found in SDRAM data sheets as tDAL or tAPW
+;// </h>
+;// <h> Dynamic Memory Write Recovery Time Register (EMCDynamictWR)
+;// <o5.0..3> tWR: Write recovery time <1-16> <#-1>
+;// <i> The delay is in CCLK cycles
+;// <i> This value is normally found in SDRAM data sheets as tWR, tDPL, tRWL, or tRDL
+;// </h>
+;// <h> Dynamic Memory Active to Active Command Period Register (EMCDynamictRC)
+;// <o6.0..4> tRC: Active to active command period <1-32> <#-1>
+;// <i> The delay is in CCLK cycles
+;// <i> This value is normally found in SDRAM data sheets as tRC
+;// </h>
+;// <h> Dynamic Memory Auto-refresh Period Register (EMCDynamictRFC)
+;// <o7.0..4> tRFC: Auto-refresh period and auto-refresh to active command period <1-32> <#-1>
+;// <i> The delay is in CCLK cycles
+;// <i> This value is normally found in SDRAM data sheets as tRFC or tRC
+;// </h>
+;// <h> Dynamic Memory Exit Self-refresh Register (EMCDynamictXSR)
+;// <o8.0..4> tXSR: Exit self-refresh to active command time <1-32> <#-1>
+;// <i> The delay is in CCLK cycles
+;// <i> This value is normally found in SDRAM data sheets as tXSR
+;// </h>
+;// <h> Dynamic Memory Active Bank A to Active Bank B Time Register (EMCDynamicRRD)
+;// <o9.0..3> tRRD: Active bank A to active bank B latency <1-16> <#-1>
+;// <i> The delay is in CCLK cycles
+;// <i> This value is normally found in SDRAM data sheets as tRRD
+;// </h>
+;// <h> Dynamic Memory Load Mode Register to Active Command Time (EMCDynamictMRD)
+;// <o10.0..3> tMRD: Load mode register to active command time <1-16> <#-1>
+;// <i> The delay is in CCLK cycles
+;// <i> This value is normally found in SDRAM data sheets as tMRD or tRSA
+;// </h>
+;// </h>
+EMC_DYN_RP_Val EQU 0x00000002
+EMC_DYN_RAS_Val EQU 0x00000003
+EMC_DYN_SREX_Val EQU 0x00000007
+EMC_DYN_APR_Val EQU 0x00000002
+EMC_DYN_DAL_Val EQU 0x00000005
+EMC_DYN_WR_Val EQU 0x00000001
+EMC_DYN_RC_Val EQU 0x00000005
+EMC_DYN_RFC_Val EQU 0x00000005
+EMC_DYN_XSR_Val EQU 0x00000007
+EMC_DYN_RRD_Val EQU 0x00000001
+EMC_DYN_MRD_Val EQU 0x00000002
+
+;// <e> Configure External Bus Behaviour for Dynamic CS0 Area
+EMC_DYNCS0_SETUP EQU 1
+
+;// <h> Dynamic Memory Configuration Register (EMCDynamicConfig0)
+;// <i> Defines the configuration information for the dynamic memory CS0
+;// <o0.20> P: Write protect
+;// <o0.19> B: Buffer enable
+;// <o0.14> AM 14: External bus data width
+;// <0=> 16 bit
+;// <1=> 32 bit
+;// <o0.12> AM 12: External bus memory type
+;// <0=> High-performance
+;// <1=> Low-power SDRAM
+;// <o0.7..11> AM 11..7: External bus address mapping (Row, Bank, Column)
+;// <0x00=> 16 Mb = 2MB (2Mx8), 2 banks, row length = 11, column length = 9
+;// <0x01=> 16 Mb = 2MB (1Mx16), 2 banks, row length = 11, column length = 8
+;// <0x04=> 64 Mb = 8MB (8Mx8), 4 banks, row length = 12, column length = 9
+;// <0x05=> 64 Mb = 8MB (4Mx16), 4 banks, row length = 12, column length = 8
+;// <0x08=> 128 Mb = 16MB (16Mx8), 4 banks, row length = 12, column length = 10
+;// <0x09=> 128 Mb = 16MB (8Mx16), 4 banks, row length = 12, column length = 9
+;// <0x0C=> 256 Mb = 32MB (32Mx8), 4 banks, row length = 13, column length = 10
+;// <0x0D=> 256 Mb = 32MB (16Mx16), 4 banks, row length = 13, column length = 9
+;// <0x10=> 512 Mb = 64MB (64Mx8), 4 banks, row length = 13, column length = 11
+;// <0x11=> 512 Mb = 64MB (32Mx16), 4 banks, row length = 13, column length = 10
+;// <o0.3..4> MD: Memory device
+;// <0=> SDRAM
+;// <1=> Low-power SDRAM
+;// <2=> Micron SyncFlash
+;// </h>
+EMC_DYN_CFG0_Val EQU 0x00080680
+
+;// <h> Dynamic Memory RAS & CAS Delay register (EMCDynamicRASCAS0)
+;// <i> Controls the RAS and CAS latencies for the dynamic memory CS0
+;// <o0.8..9> CAS: CAS latency
+;// <1=> One CCLK cycle
+;// <2=> Two CCLK cycles
+;// <3=> Three CCLK cycles
+;// <o0.0..1> RAS: RAS latency (active to read/write delay)
+;// <1=> One CCLK cycle
+;// <2=> Two CCLK cycles
+;// <3=> Three CCLK cycles
+;// </h>
+EMC_DYN_RASCAS0_Val EQU 0x00000303
+
+;// </e> End of Dynamic Setup for CS0 Area
+
+
+;// <e> Configure External Bus Behaviour for Dynamic CS1 Area
+EMC_DYNCS1_SETUP EQU 0
+
+;// <h> Dynamic Memory Configuration Register (EMCDynamicConfig1)
+;// <i> Defines the configuration information for the dynamic memory CS1
+;// <o0.20> P: Write protect
+;// <o0.19> B: Buffer enable
+;// <o0.14> AM 14: External bus data width
+;// <0=> 16 bit
+;// <1=> 32 bit
+;// <o0.12> AM 12: External bus memory type
+;// <0=> High-performance
+;// <1=> Low-power SDRAM
+;// <o0.7..11> AM 11..7: External bus address mapping (Row, Bank, Column)
+;// <0x00=> 16 Mb = 2MB (2Mx8), 2 banks, row length = 11, column length = 9
+;// <0x01=> 16 Mb = 2MB (1Mx16), 2 banks, row length = 11, column length = 8
+;// <0x04=> 64 Mb = 8MB (8Mx8), 4 banks, row length = 12, column length = 9
+;// <0x05=> 64 Mb = 8MB (4Mx16), 4 banks, row length = 12, column length = 8
+;// <0x08=> 128 Mb = 16MB (16Mx8), 4 banks, row length = 12, column length = 10
+;// <0x09=> 128 Mb = 16MB (8Mx16), 4 banks, row length = 12, column length = 9
+;// <0x0C=> 256 Mb = 32MB (32Mx8), 4 banks, row length = 13, column length = 10
+;// <0x0D=> 256 Mb = 32MB (16Mx16), 4 banks, row length = 13, column length = 9
+;// <0x10=> 512 Mb = 64MB (64Mx8), 4 banks, row length = 13, column length = 11
+;// <0x11=> 512 Mb = 64MB (32Mx16), 4 banks, row length = 13, column length = 10
+;// <o0.3..4> MD: Memory device
+;// <0=> SDRAM
+;// <1=> Low-power SDRAM
+;// <2=> Micron SyncFlash
+;// </h>
+EMC_DYN_CFG1_Val EQU 0x00000000
+
+;// <h> Dynamic Memory RAS & CAS Delay register (EMCDynamicRASCAS1)
+;// <i> Controls the RAS and CAS latencies for the dynamic memory CS1
+;// <o0.8..9> CAS: CAS latency
+;// <1=> One CCLK cycle
+;// <2=> Two CCLK cycles
+;// <3=> Three CCLK cycles
+;// <o0.0..1> RAS: RAS latency (active to read/write delay)
+;// <1=> One CCLK cycle
+;// <2=> Two CCLK cycles
+;// <3=> Three CCLK cycles
+;// </h>
+EMC_DYN_RASCAS1_Val EQU 0x00000303
+
+;// </e> End of Dynamic Setup for CS1 Area
+
+;// <e> Configure External Bus Behaviour for Dynamic CS2 Area
+EMC_DYNCS2_SETUP EQU 0
+
+;// <h> Dynamic Memory Configuration Register (EMCDynamicConfig2)
+;// <i> Defines the configuration information for the dynamic memory CS2
+;// <o0.20> P: Write protect
+;// <o0.19> B: Buffer enable
+;// <o0.14> AM 14: External bus data width
+;// <0=> 16 bit
+;// <1=> 32 bit
+;// <o0.12> AM 12: External bus memory type
+;// <0=> High-performance
+;// <1=> Low-power SDRAM
+;// <o0.7..11> AM 11..7: External bus address mapping (Row, Bank, Column)
+;// <0x00=> 16 Mb = 2MB (2Mx8), 2 banks, row length = 11, column length = 9
+;// <0x01=> 16 Mb = 2MB (1Mx16), 2 banks, row length = 11, column length = 8
+;// <0x04=> 64 Mb = 8MB (8Mx8), 4 banks, row length = 12, column length = 9
+;// <0x05=> 64 Mb = 8MB (4Mx16), 4 banks, row length = 12, column length = 8
+;// <0x08=> 128 Mb = 16MB (16Mx8), 4 banks, row length = 12, column length = 10
+;// <0x09=> 128 Mb = 16MB (8Mx16), 4 banks, row length = 12, column length = 9
+;// <0x0C=> 256 Mb = 32MB (32Mx8), 4 banks, row length = 13, column length = 10
+;// <0x0D=> 256 Mb = 32MB (16Mx16), 4 banks, row length = 13, column length = 9
+;// <0x10=> 512 Mb = 64MB (64Mx8), 4 banks, row length = 13, column length = 11
+;// <0x11=> 512 Mb = 64MB (32Mx16), 4 banks, row length = 13, column length = 10
+;// <o0.3..4> MD: Memory device
+;// <0=> SDRAM
+;// <1=> Low-power SDRAM
+;// <2=> Micron SyncFlash
+;// </h>
+EMC_DYN_CFG2_Val EQU 0x00000000
+
+;// <h> Dynamic Memory RAS & CAS Delay register (EMCDynamicRASCAS2)
+;// <i> Controls the RAS and CAS latencies for the dynamic memory CS2
+;// <o0.8..9> CAS: CAS latency
+;// <1=> One CCLK cycle
+;// <2=> Two CCLK cycles
+;// <3=> Three CCLK cycles
+;// <o0.0..1> RAS: RAS latency (active to read/write delay)
+;// <1=> One CCLK cycle
+;// <2=> Two CCLK cycles
+;// <3=> Three CCLK cycles
+;// </h>
+EMC_DYN_RASCAS2_Val EQU 0x00000303
+
+;// </e> End of Dynamic Setup for CS2 Area
+
+;// <e> Configure External Bus Behaviour for Dynamic CS3 Area
+EMC_DYNCS3_SETUP EQU 0
+
+;// <h> Dynamic Memory Configuration Register (EMCDynamicConfig3)
+;// <i> Defines the configuration information for the dynamic memory CS3
+;// <o0.20> P: Write protect
+;// <o0.19> B: Buffer enable
+;// <o0.14> AM 14: External bus data width
+;// <0=> 16 bit
+;// <1=> 32 bit
+;// <o0.12> AM 12: External bus memory type
+;// <0=> High-performance
+;// <1=> Low-power SDRAM
+;// <o0.7..11> AM 11..7: External bus address mapping (Row, Bank, Column)
+;// <0x00=> 16 Mb = 2MB (2Mx8), 2 banks, row length = 11, column length = 9
+;// <0x01=> 16 Mb = 2MB (1Mx16), 2 banks, row length = 11, column length = 8
+;// <0x04=> 64 Mb = 8MB (8Mx8), 4 banks, row length = 12, column length = 9
+;// <0x05=> 64 Mb = 8MB (4Mx16), 4 banks, row length = 12, column length = 8
+;// <0x08=> 128 Mb = 16MB (16Mx8), 4 banks, row length = 12, column length = 10
+;// <0x09=> 128 Mb = 16MB (8Mx16), 4 banks, row length = 12, column length = 9
+;// <0x0C=> 256 Mb = 32MB (32Mx8), 4 banks, row length = 13, column length = 10
+;// <0x0D=> 256 Mb = 32MB (16Mx16), 4 banks, row length = 13, column length = 9
+;// <0x10=> 512 Mb = 64MB (64Mx8), 4 banks, row length = 13, column length = 11
+;// <0x11=> 512 Mb = 64MB (32Mx16), 4 banks, row length = 13, column length = 10
+;// <o0.3..4> MD: Memory device
+;// <0=> SDRAM
+;// <1=> Low-power SDRAM
+;// <2=> Micron SyncFlash
+;// </h>
+EMC_DYN_CFG3_Val EQU 0x00000000
+
+;// <h> Dynamic Memory RAS & CAS Delay register (EMCDynamicRASCAS3)
+;// <i> Controls the RAS and CAS latencies for the dynamic memory CS3
+;// <o0.8..9> CAS: CAS latency
+;// <1=> One CCLK cycle
+;// <2=> Two CCLK cycles
+;// <3=> Three CCLK cycles
+;// <o0.0..1> RAS: RAS latency (active to read/write delay)
+;// <1=> One CCLK cycle
+;// <2=> Two CCLK cycles
+;// <3=> Three CCLK cycles
+;// </h>
+EMC_DYN_RASCAS3_Val EQU 0x00000303
+
+;// </e> End of Dynamic Setup for CS3 Area
+
+;// </e> End of Dynamic Setup
+
+;// Static Memory Interface Setup ----------------------------------------
+;// <e> Static Memory Interface Setup
+EMC_STATIC_SETUP EQU 1
+
+;// Configure External Bus Behaviour for Static CS0 Area ---------------
+;// <e> Configure External Bus Behaviour for Static CS0 Area
+EMC_STACS0_SETUP EQU 1
+
+;// <h> Static Memory Configuration Register (EMCStaticConfig0)
+;// <i> Defines the configuration information for the static memory CS0
+;// <o0.20> WP: Write protect
+;// <o0.19> B: Buffer enable
+;// <o0.8> EW: Extended wait enable
+;// <o0.7> PB: Byte lane state
+;// <0=> For reads BLSn are HIGH, for writes BLSn are LOW
+;// <1=> For reads BLSn are LOW, for writes BLSn are LOW
+;// <o0.6> PC: Chip select polarity
+;// <0=> Active LOW chip select
+;// <1=> Active HIGH chip select
+;// <o0.3> PM: Page mode enable
+;// <o0.0..1> MW: Memory width
+;// <0=> 8 bit
+;// <1=> 16 bit
+;// <2=> 32 bit
+;// </h>
+EMC_STA_CFG0_Val EQU 0x00000081
+
+;// <h> Static Memory Write Enable Delay Register (EMCStaticWaitWen0)
+;// <i> Selects the delay from CS0 to write enable
+;// <o.0..3> WAITWEN: Wait write enable <1-16> <#-1>
+;// <i> The delay is in CCLK cycles
+;// </h>
+EMC_STA_WWEN0_Val EQU 0x00000002
+
+;// <h> Static Memory Output Enable Delay register (EMCStaticWaitOen0)
+;// <i> Selects the delay from CS0 or address change, whichever is later, to output enable
+;// <o.0..3> WAITOEN: Wait output enable <0-15>
+;// <i> The delay is in CCLK cycles
+;// </h>
+EMC_STA_WOEN0_Val EQU 0x00000002
+
+;// <h> Static Memory Read Delay Register (EMCStaticWaitRd0)
+;// <i> Selects the delay from CS0 to a read access
+;// <o.0..4> WAITRD: Non-page mode read wait states or asynchronous page mode read first access wait states <1-32> <#-1>
+;// <i> The delay is in CCLK cycles
+;// </h>
+EMC_STA_WRD0_Val EQU 0x0000001F
+
+;// <h> Static Memory Page Mode Read Delay Register (EMCStaticWaitPage0)
+;// <i> Selects the delay for asynchronous page mode sequential accesses for CS0
+;// <o.0..4> WAITPAGE: Asynchronous page mode read after the first read wait states <1-32> <#-1>
+;// <i> The delay is in CCLK cycles
+;// </h>
+EMC_STA_WPAGE0_Val EQU 0x0000001F
+
+;// <h> Static Memory Write Delay Register (EMCStaticWaitWr0)
+;// <i> Selects the delay from CS0 to a write access
+;// <o.0..4> WAITWR: Write wait states <2-33> <#-2>
+;// <i> The delay is in CCLK cycles
+;// </h>
+EMC_STA_WWR0_Val EQU 0x0000001F
+
+;// <h> Static Memory Turn Round Delay Register (EMCStaticWaitTurn0)
+;// <i> Selects the number of bus turnaround cycles for CS0
+;// <o.0..4> WAITTURN: Bus turnaround cycles <1-16> <#-1>
+;// <i> The delay is in CCLK cycles
+;// </h>
+EMC_STA_WTURN0_Val EQU 0x0000000F
+
+;// </e> End of Static Setup for Static CS0 Area
+
+;// Configure External Bus Behaviour for Static CS1 Area ---------------
+;// <e> Configure External Bus Behaviour for Static CS1 Area
+EMC_STACS1_SETUP EQU 0
+
+;// <h> Static Memory Configuration Register (EMCStaticConfig1)
+;// <i> Defines the configuration information for the static memory CS1
+;// <o0.20> WP: Write protect
+;// <o0.19> B: Buffer enable
+;// <o0.8> EW: Extended wait enable
+;// <o0.7> PB: Byte lane state
+;// <0=> For reads BLSn are HIGH, for writes BLSn are LOW
+;// <1=> For reads BLSn are LOW, for writes BLSn are LOW
+;// <o0.6> PC: Chip select polarity
+;// <0=> Active LOW chip select
+;// <1=> Active HIGH chip select
+;// <o0.3> PM: Page mode enable
+;// <o0.0..1> MW: Memory width
+;// <0=> 8 bit
+;// <1=> 16 bit
+;// <2=> 32 bit
+;// </h>
+EMC_STA_CFG1_Val EQU 0x00000000
+
+;// <h> Static Memory Write Enable Delay Register (EMCStaticWaitWen1)
+;// <i> Selects the delay from CS1 to write enable
+;// <o.0..3> WAITWEN: Wait write enable <1-16> <#-1>
+;// <i> The delay is in CCLK cycles
+;// </h>
+EMC_STA_WWEN1_Val EQU 0x00000000
+
+;// <h> Static Memory Output Enable Delay register (EMCStaticWaitOen1)
+;// <i> Selects the delay from CS1 or address change, whichever is later, to output enable
+;// <o.0..3> WAITOEN: Wait output enable <0-15>
+;// <i> The delay is in CCLK cycles
+;// </h>
+EMC_STA_WOEN1_Val EQU 0x00000000
+
+;// <h> Static Memory Read Delay Register (EMCStaticWaitRd1)
+;// <i> Selects the delay from CS1 to a read access
+;// <o.0..4> WAITRD: Non-page mode read wait states or asynchronous page mode read first access wait states <1-32> <#-1>
+;// <i> The delay is in CCLK cycles
+;// </h>
+EMC_STA_WRD1_Val EQU 0x0000001F
+
+;// <h> Static Memory Page Mode Read Delay Register (EMCStaticWaitPage0)
+;// <i> Selects the delay for asynchronous page mode sequential accesses for CS1
+;// <o.0..4> WAITPAGE: Asynchronous page mode read after the first read wait states <1-32> <#-1>
+;// <i> The delay is in CCLK cycles
+;// </h>
+EMC_STA_WPAGE1_Val EQU 0x0000001F
+
+;// <h> Static Memory Write Delay Register (EMCStaticWaitWr1)
+;// <i> Selects the delay from CS1 to a write access
+;// <o.0..4> WAITWR: Write wait states <2-33> <#-2>
+;// <i> The delay is in CCLK cycles
+;// </h>
+EMC_STA_WWR1_Val EQU 0x0000001F
+
+;// <h> Static Memory Turn Round Delay Register (EMCStaticWaitTurn1)
+;// <i> Selects the number of bus turnaround cycles for CS1
+;// <o.0..4> WAITTURN: Bus turnaround cycles <1-16> <#-1>
+;// <i> The delay is in CCLK cycles
+;// </h>
+EMC_STA_WTURN1_Val EQU 0x0000000F
+
+;// </e> End of Static Setup for Static CS1 Area
+
+;// Configure External Bus Behaviour for Static CS2 Area ---------------
+;// <e> Configure External Bus Behaviour for Static CS2 Area
+EMC_STACS2_SETUP EQU 0
+
+;// <h> Static Memory Configuration Register (EMCStaticConfig2)
+;// <i> Defines the configuration information for the static memory CS2
+;// <o0.20> WP: Write protect
+;// <o0.19> B: Buffer enable
+;// <o0.8> EW: Extended wait enable
+;// <o0.7> PB: Byte lane state
+;// <0=> For reads BLSn are HIGH, for writes BLSn are LOW
+;// <1=> For reads BLSn are LOW, for writes BLSn are LOW
+;// <o0.6> PC: Chip select polarity
+;// <0=> Active LOW chip select
+;// <1=> Active HIGH chip select
+;// <o0.3> PM: Page mode enable
+;// <o0.0..1> MW: Memory width
+;// <0=> 8 bit
+;// <1=> 16 bit
+;// <2=> 32 bit
+;// </h>
+EMC_STA_CFG2_Val EQU 0x00000000
+
+;// <h> Static Memory Write Enable Delay Register (EMCStaticWaitWen2)
+;// <i> Selects the delay from CS2 to write enable
+;// <o.0..3> WAITWEN: Wait write enable <1-16> <#-1>
+;// <i> The delay is in CCLK cycles
+;// </h>
+EMC_STA_WWEN2_Val EQU 0x00000000
+
+;// <h> Static Memory Output Enable Delay register (EMCStaticWaitOen2)
+;// <i> Selects the delay from CS2 or address change, whichever is later, to output enable
+;// <o.0..3> WAITOEN: Wait output enable <0-15>
+;// <i> The delay is in CCLK cycles
+;// </h>
+EMC_STA_WOEN2_Val EQU 0x00000000
+
+;// <h> Static Memory Read Delay Register (EMCStaticWaitRd2)
+;// <i> Selects the delay from CS2 to a read access
+;// <o.0..4> WAITRD: Non-page mode read wait states or asynchronous page mode read first access wait states <1-32> <#-1>
+;// <i> The delay is in CCLK cycles
+;// </h>
+EMC_STA_WRD2_Val EQU 0x0000001F
+
+;// <h> Static Memory Page Mode Read Delay Register (EMCStaticWaitPage2)
+;// <i> Selects the delay for asynchronous page mode sequential accesses for CS2
+;// <o.0..4> WAITPAGE: Asynchronous page mode read after the first read wait states <1-32> <#-1>
+;// <i> The delay is in CCLK cycles
+;// </h>
+EMC_STA_WPAGE2_Val EQU 0x0000001F
+
+;// <h> Static Memory Write Delay Register (EMCStaticWaitWr2)
+;// <i> Selects the delay from CS2 to a write access
+;// <o.0..4> WAITWR: Write wait states <2-33> <#-2>
+;// <i> The delay is in CCLK cycles
+;// </h>
+EMC_STA_WWR2_Val EQU 0x0000001F
+
+;// <h> Static Memory Turn Round Delay Register (EMCStaticWaitTurn2)
+;// <i> Selects the number of bus turnaround cycles for CS2
+;// <o.0..4> WAITTURN: Bus turnaround cycles <1-16> <#-1>
+;// <i> The delay is in CCLK cycles
+;// </h>
+EMC_STA_WTURN2_Val EQU 0x0000000F
+
+;// </e> End of Static Setup for Static CS2 Area
+
+;// Configure External Bus Behaviour for Static CS3 Area ---------------
+;// <e> Configure External Bus Behaviour for Static CS3 Area
+EMC_STACS3_SETUP EQU 0
+
+;// <h> Static Memory Configuration Register (EMCStaticConfig3)
+;// <i> Defines the configuration information for the static memory CS3
+;// <o0.20> WP: Write protect
+;// <o0.19> B: Buffer enable
+;// <o0.8> EW: Extended wait enable
+;// <o0.7> PB: Byte lane state
+;// <0=> For reads BLSn are HIGH, for writes BLSn are LOW
+;// <1=> For reads BLSn are LOW, for writes BLSn are LOW
+;// <o0.6> PC: Chip select polarity
+;// <0=> Active LOW chip select
+;// <1=> Active HIGH chip select
+;// <o0.3> PM: Page mode enable
+;// <o0.0..1> MW: Memory width
+;// <0=> 8 bit
+;// <1=> 16 bit
+;// <2=> 32 bit
+;// </h>
+EMC_STA_CFG3_Val EQU 0x00000000
+
+;// <h> Static Memory Write Enable Delay Register (EMCStaticWaitWen3)
+;// <i> Selects the delay from CS3 to write enable
+;// <o.0..3> WAITWEN: Wait write enable <1-16> <#-1>
+;// <i> The delay is in CCLK cycles
+;// </h>
+EMC_STA_WWEN3_Val EQU 0x00000000
+
+;// <h> Static Memory Output Enable Delay register (EMCStaticWaitOen3)
+;// <i> Selects the delay from CS3 or address change, whichever is later, to output enable
+;// <o.0..3> WAITOEN: Wait output enable <0-15>
+;// <i> The delay is in CCLK cycles
+;// </h>
+EMC_STA_WOEN3_Val EQU 0x00000000
+
+;// <h> Static Memory Read Delay Register (EMCStaticWaitRd3)
+;// <i> Selects the delay from CS3 to a read access
+;// <o.0..4> WAITRD: Non-page mode read wait states or asynchronous page mode read first access wait states <1-32> <#-1>
+;// <i> The delay is in CCLK cycles
+;// </h>
+EMC_STA_WRD3_Val EQU 0x0000001F
+
+;// <h> Static Memory Page Mode Read Delay Register (EMCStaticWaitPage3)
+;// <i> Selects the delay for asynchronous page mode sequential accesses for CS3
+;// <o.0..4> WAITPAGE: Asynchronous page mode read after the first read wait states <1-32> <#-1>
+;// <i> The delay is in CCLK cycles
+;// </h>
+EMC_STA_WPAGE3_Val EQU 0x0000001F
+
+;// <h> Static Memory Write Delay Register (EMCStaticWaitWr3)
+;// <i> Selects the delay from CS3 to a write access
+;// <o.0..4> WAITWR: Write wait states <2-33> <#-2>
+;// <i> The delay is in CCLK cycles
+;// </h>
+EMC_STA_WWR3_Val EQU 0x0000001F
+
+;// <h> Static Memory Turn Round Delay Register (EMCStaticWaitTurn3)
+;// <i> Selects the number of bus turnaround cycles for CS3
+;// <o.0..4> WAITTURN: Bus turnaround cycles <1-16> <#-1>
+;// <i> The delay is in CCLK cycles
+;// </h>
+EMC_STA_WTURN3_Val EQU 0x0000000F
+
+;// </e> End of Static Setup for Static CS3 Area
+
+;// <h> Static Memory Extended Wait Register (EMCStaticExtendedWait)
+;// <i> Time long static memory read and write transfers
+;// <o.0..9> EXTENDEDWAIT: Extended wait time out <0-1023>
+;// <i> The delay is in (16 * CCLK) cycles
+;// </h>
+EMC_STA_EXT_W_Val EQU 0x00000000
+
+;// </e> End of Static Setup
+
+;// </e> End of EMC Setup
+
+
+ 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
+
+
+; Clock Setup ------------------------------------------------------------------
+
+ IF (:LNOT:(:DEF:NO_CLOCK_SETUP)):LAND:(CLOCK_SETUP != 0)
+ LDR R0, =SCB_BASE
+ MOV R1, #0xAA
+ MOV R2, #0x55
+
+; Configure and Enable PLL
+ LDR R3, =SCS_Val ; Enable main oscillator
+ STR R3, [R0, #SCS_OFS]
+
+ IF (SCS_Val:AND:OSCEN) != 0
+OSC_Loop LDR R3, [R0, #SCS_OFS] ; Wait for main osc stabilize
+ ANDS R3, R3, #OSCSTAT
+ BEQ OSC_Loop
+ ENDIF
+
+ LDR R3, =CLKSRCSEL_Val ; Select PLL source clock
+ STR R3, [R0, #CLKSRCSEL_OFS]
+ LDR R3, =PLLCFG_Val
+ STR R3, [R0, #PLLCFG_OFS]
+ STR R1, [R0, #PLLFEED_OFS]
+ STR R2, [R0, #PLLFEED_OFS]
+ MOV R3, #PLLCON_PLLE
+ STR R3, [R0, #PLLCON_OFS]
+ STR R1, [R0, #PLLFEED_OFS]
+ STR R2, [R0, #PLLFEED_OFS]
+
+ IF (CLKSRCSEL_Val:AND:3) != 2
+; Wait until PLL Locked (if source is not RTC oscillator)
+PLL_Loop LDR R3, [R0, #PLLSTAT_OFS]
+ ANDS R3, R3, #PLLSTAT_PLOCK
+ BEQ PLL_Loop
+ ELSE
+; Wait at least 200 cycles (if source is RTC oscillator)
+ MOV R3, #(200/4)
+PLL_Loop SUBS R3, R3, #1
+ BNE PLL_Loop
+ ENDIF
+
+M_N_Lock LDR R3, [R0, #PLLSTAT_OFS]
+ LDR R4, =(PLLSTAT_M:OR:PLLSTAT_N)
+ AND R3, R3, R4
+ LDR R4, =PLLCFG_Val
+ EORS R3, R3, R4
+ BNE M_N_Lock
+
+; Setup CPU clock divider
+ MOV R3, #CCLKCFG_Val
+ STR R3, [R0, #CCLKCFG_OFS]
+
+; Setup USB clock divider
+ LDR R3, =USBCLKCFG_Val
+ STR R3, [R0, #USBCLKCFG_OFS]
+
+; Setup Peripheral Clock
+ LDR R3, =PCLKSEL0_Val
+ STR R3, [R0, #PCLKSEL0_OFS]
+ LDR R3, =PCLKSEL1_Val
+ STR R3, [R0, #PCLKSEL1_OFS]
+
+; 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 ; CLOCK_SETUP
+
+
+; Setup Memory Accelerator Module ----------------------------------------------
+
+ 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
+
+
+; Setup External Memory Controller ---------------------------------------------
+
+ IF (:LNOT:(:DEF:NO_EMC_SETUP)):LAND:(EMC_SETUP != 0)
+ LDR R0, =EMC_BASE
+ LDR R1, =SCB_BASE
+ LDR R2, =PCB_BASE
+
+ LDR R4, =EMC_PCONP_Const ; Enable EMC
+ LDR R3, [R1, #PCONP_OFS]
+ ORR R4, R4, R3
+ STR R4, [R1, #PCONP_OFS]
+
+ LDR R4, =EMC_CTRL_Val
+ STR R4, [R0, #EMC_CTRL_OFS]
+ LDR R4, =EMC_CONFIG_Val
+ STR R4, [R0, #EMC_CONFIG_OFS]
+
+; Setup pin functions for External Bus functionality
+ LDR R4, =EMC_PINSEL5_Val
+ STR R4, [R2, #PINSEL5_OFS]
+ LDR R4, =EMC_PINSEL6_Val
+ STR R4, [R2, #PINSEL6_OFS]
+ LDR R4, =EMC_PINSEL8_Val
+ STR R4, [R2, #PINSEL8_OFS]
+ LDR R4, =EMC_PINSEL9_Val
+ STR R4, [R2, #PINSEL9_OFS]
+
+; Setup Dynamic Memory Interface
+ IF (EMC_DYNAMIC_SETUP != 0)
+
+ LDR R4, =EMC_DYN_RP_Val
+ STR R4, [R0, #EMC_DYN_RP_OFS]
+ LDR R4, =EMC_DYN_RAS_Val
+ STR R4, [R0, #EMC_DYN_RAS_OFS]
+ LDR R4, =EMC_DYN_SREX_Val
+ STR R4, [R0, #EMC_DYN_SREX_OFS]
+ LDR R4, =EMC_DYN_APR_Val
+ STR R4, [R0, #EMC_DYN_APR_OFS]
+ LDR R4, =EMC_DYN_DAL_Val
+ STR R4, [R0, #EMC_DYN_DAL_OFS]
+ LDR R4, =EMC_DYN_WR_Val
+ STR R4, [R0, #EMC_DYN_WR_OFS]
+ LDR R4, =EMC_DYN_RC_Val
+ STR R4, [R0, #EMC_DYN_RC_OFS]
+ LDR R4, =EMC_DYN_RFC_Val
+ STR R4, [R0, #EMC_DYN_RFC_OFS]
+ LDR R4, =EMC_DYN_XSR_Val
+ STR R4, [R0, #EMC_DYN_XSR_OFS]
+ LDR R4, =EMC_DYN_RRD_Val
+ STR R4, [R0, #EMC_DYN_RRD_OFS]
+ LDR R4, =EMC_DYN_MRD_Val
+ STR R4, [R0, #EMC_DYN_MRD_OFS]
+
+ LDR R4, =EMC_DYN_RD_CFG_Val
+ STR R4, [R0, #EMC_DYN_RD_CFG_OFS]
+
+ IF (EMC_DYNCS0_SETUP != 0)
+ LDR R4, =EMC_DYN_RASCAS0_Val
+ STR R4, [R0, #EMC_DYN_RASCAS0_OFS]
+ LDR R4, =EMC_DYN_CFG0_Val
+ MVN R5, #BUFEN_Const
+ AND R4, R4, R5
+ STR R4, [R0, #EMC_DYN_CFG0_OFS]
+ ENDIF
+ IF (EMC_DYNCS1_SETUP != 0)
+ LDR R4, =EMC_DYN_RASCAS1_Val
+ STR R4, [R0, #EMC_DYN_RASCAS1_OFS]
+ LDR R4, =EMC_DYN_CFG1_Val
+ MVN R5, =BUFEN_Const
+ AND R4, R4, R5
+ STR R4, [R0, #EMC_DYN_CFG1_OFS]
+ ENDIF
+ IF (EMC_DYNCS2_SETUP != 0)
+ LDR R4, =EMC_DYN_RASCAS2_Val
+ STR R4, [R0, #EMC_DYN_RASCAS2_OFS]
+ LDR R4, =EMC_DYN_CFG2_Val
+ MVN R5, =BUFEN_Const
+ AND R4, R4, R5
+ STR R4, [R0, #EMC_DYN_CFG2_OFS]
+ ENDIF
+ IF (EMC_DYNCS3_SETUP != 0)
+ LDR R4, =EMC_DYN_RASCAS3_Val
+ STR R4, [R0, #EMC_DYN_RASCAS3_OFS]
+ LDR R4, =EMC_DYN_CFG3_Val
+ MVN R5, =BUFEN_Const
+ AND R4, R4, R5
+ STR R4, [R0, #EMC_DYN_CFG3_OFS]
+ ENDIF
+
+ LDR R6, =1440000 ; Number of cycles to delay
+Wait_0 SUBS R6, R6, #1 ; Delay ~100 ms proc clk 57.6 MHz
+ BNE Wait_0 ; BNE (3 cyc) + SUBS (1 cyc) = 4 cyc
+
+ LDR R4, =(NOP_CMD:OR:0x03) ; Write NOP Command
+ STR R4, [R0, #EMC_DYN_CTRL_OFS]
+
+ LDR R6, =2880000 ; Number of cycles to delay
+Wait_1 SUBS R6, R6, #1 ; Delay ~200 ms proc clk 57.6 MHz
+ BNE Wait_1
+
+ LDR R4, =(PALL_CMD:OR:0x03) ; Write Precharge All Command
+ STR R4, [R0, #EMC_DYN_CTRL_OFS]
+
+ MOV R4, #2
+ STR R4, [R0, #EMC_DYN_RFSH_OFS]
+
+ MOV R6, #64 ; Number of cycles to delay
+Wait_2 SUBS R6, R6, #1 ; Delay
+ BNE Wait_2
+
+ LDR R4, =EMC_DYN_RFSH_Val
+ STR R4, [R0, #EMC_DYN_RFSH_OFS]
+
+ LDR R4, =(MODE_CMD:OR:0x03) ; Write MODE Command
+ STR R4, [R0, #EMC_DYN_CTRL_OFS]
+
+ ; Dummy read
+ IF (EMC_DYNCS0_SETUP != 0)
+ LDR R4, =DYN_MEM0_BASE
+ MOV R5, #(0x33 << 12)
+ ADD R4, R4, R5
+ LDR R4, [R4, #0]
+ ENDIF
+ IF (EMC_DYNCS1_SETUP != 0)
+ LDR R4, =DYN_MEM1_BASE
+ MOV R5, #(0x33 << 12)
+ ADD R4, R4, R5
+ LDR R4, [R4, #0]
+ ENDIF
+ IF (EMC_DYNCS2_SETUP != 0)
+ LDR R4, =DYN_MEM2_BASE
+ MOV R5, #(0x33 << 12)
+ ADD R4, R4, R5
+ LDR R4, [R4, #0]
+ ENDIF
+ IF (EMC_DYNCS3_SETUP != 0)
+ LDR R4, =DYN_MEM3_BASE
+ MOV R5, #(0x33 << 12)
+ ADD R4, R4, R5
+ LDR R4, [R4, #0]
+ ENDIF
+
+ LDR R4, =NORMAL_CMD ; Write NORMAL Command
+ STR R4, [R0, #EMC_DYN_CTRL_OFS]
+
+ ; Enable buffer if requested by settings
+ IF (EMC_DYNCS0_SETUP != 0):LAND:((EMC_DYN_CFG0_Val:AND:BUFEN_Const) != 0)
+ LDR R4, =EMC_DYN_CFG0_Val
+ STR R4, [R0, #EMC_DYN_CFG0_OFS]
+ ENDIF
+ IF (EMC_DYNCS1_SETUP != 0):LAND:((EMC_DYN_CFG1_Val:AND:BUFEN_Const) != 0)
+ LDR R4, =EMC_DYN_CFG1_Val
+ STR R4, [R0, #EMC_DYN_CFG1_OFS]
+ ENDIF
+ IF (EMC_DYNCS2_SETUP != 0):LAND:((EMC_DYN_CFG2_Val:AND:BUFEN_Const) != 0)
+ LDR R4, =EMC_DYN_CFG2_Val
+ STR R4, [R0, #EMC_DYN_CFG2_OFS]
+ ENDIF
+ IF (EMC_DYNCS3_SETUP != 0):LAND:((EMC_DYN_CFG3_Val:AND:BUFEN_Const) != 0)
+ LDR R4, =EMC_DYN_CFG3_Val
+ STR R4, [R0, #EMC_DYN_CFG3_OFS]
+ ENDIF
+
+ LDR R6, =14400 ; Number of cycles to delay
+Wait_3 SUBS R6, R6, #1 ; Delay ~1 ms @ proc clk 57.6 MHz
+ BNE Wait_3
+
+ ENDIF ; EMC_DYNAMIC_SETUP
+
+; Setup Static Memory Interface
+ IF (EMC_STATIC_SETUP != 0)
+
+ LDR R6, =1440000 ; Number of cycles to delay
+Wait_4 SUBS R6, R6, #1 ; Delay ~100 ms @ proc clk 57.6 MHz
+ BNE Wait_4
+
+ IF (EMC_STACS0_SETUP != 0)
+ LDR R4, =EMC_STA_CFG0_Val
+ STR R4, [R0, #EMC_STA_CFG0_OFS]
+ LDR R4, =EMC_STA_WWEN0_Val
+ STR R4, [R0, #EMC_STA_WWEN0_OFS]
+ LDR R4, =EMC_STA_WOEN0_Val
+ STR R4, [R0, #EMC_STA_WOEN0_OFS]
+ LDR R4, =EMC_STA_WRD0_Val
+ STR R4, [R0, #EMC_STA_WRD0_OFS]
+ LDR R4, =EMC_STA_WPAGE0_Val
+ STR R4, [R0, #EMC_STA_WPAGE0_OFS]
+ LDR R4, =EMC_STA_WWR0_Val
+ STR R4, [R0, #EMC_STA_WWR0_OFS]
+ LDR R4, =EMC_STA_WTURN0_Val
+ STR R4, [R0, #EMC_STA_WTURN0_OFS]
+ ENDIF
+
+ IF (EMC_STACS1_SETUP != 0)
+ LDR R4, =EMC_STA_CFG1_Val
+ STR R4, [R0, #EMC_STA_CFG1_OFS]
+ LDR R4, =EMC_STA_WWEN1_Val
+ STR R4, [R0, #EMC_STA_WWEN1_OFS]
+ LDR R4, =EMC_STA_WOEN1_Val
+ STR R4, [R0, #EMC_STA_WOEN1_OFS]
+ LDR R4, =EMC_STA_WRD1_Val
+ STR R4, [R0, #EMC_STA_WRD1_OFS]
+ LDR R4, =EMC_STA_WPAGE1_Val
+ STR R4, [R0, #EMC_STA_WPAGE1_OFS]
+ LDR R4, =EMC_STA_WWR1_Val
+ STR R4, [R0, #EMC_STA_WWR1_OFS]
+ LDR R4, =EMC_STA_WTURN1_Val
+ STR R4, [R0, #EMC_STA_WTURN1_OFS]
+ ENDIF
+
+ IF (EMC_STACS2_SETUP != 0)
+ LDR R4, =EMC_STA_CFG2_Val
+ STR R4, [R0, #EMC_STA_CFG2_OFS]
+ LDR R4, =EMC_STA_WWEN2_Val
+ STR R4, [R0, #EMC_STA_WWEN2_OFS]
+ LDR R4, =EMC_STA_WOEN2_Val
+ STR R4, [R0, #EMC_STA_WOEN2_OFS]
+ LDR R4, =EMC_STA_WRD2_Val
+ STR R4, [R0, #EMC_STA_WRD2_OFS]
+ LDR R4, =EMC_STA_WPAGE2_Val
+ STR R4, [R0, #EMC_STA_WPAGE2_OFS]
+ LDR R4, =EMC_STA_WWR2_Val
+ STR R4, [R0, #EMC_STA_WWR2_OFS]
+ LDR R4, =EMC_STA_WTURN2_Val
+ STR R4, [R0, #EMC_STA_WTURN2_OFS]
+ ENDIF
+
+ IF (EMC_STACS3_SETUP != 0)
+ LDR R4, =EMC_STA_CFG3_Val
+ STR R4, [R0, #EMC_STA_CFG3_OFS]
+ LDR R4, =EMC_STA_WWEN3_Val
+ STR R4, [R0, #EMC_STA_WWEN3_OFS]
+ LDR R4, =EMC_STA_WOEN3_Val
+ STR R4, [R0, #EMC_STA_WOEN3_OFS]
+ LDR R4, =EMC_STA_WRD3_Val
+ STR R4, [R0, #EMC_STA_WRD3_OFS]
+ LDR R4, =EMC_STA_WPAGE3_Val
+ STR R4, [R0, #EMC_STA_WPAGE3_OFS]
+ LDR R4, =EMC_STA_WWR3_Val
+ STR R4, [R0, #EMC_STA_WWR3_OFS]
+ LDR R4, =EMC_STA_WTURN3_Val
+ STR R4, [R0, #EMC_STA_WTURN3_OFS]
+ ENDIF
+
+ LDR R6, =144000 ; Number of cycles to delay
+Wait_5 SUBS R6, R6, #1 ; Delay ~10 ms @ proc clk 57.6 MHz
+ BNE Wait_5
+
+ LDR R4, =EMC_STA_EXT_W_Val
+ LDR R5, =EMC_STA_EXT_W_OFS
+ ADD R5, R5, R0
+ STR R4, [R5, #0]
+
+ ENDIF ; EMC_STATIC_SETUP
+
+ ENDIF ; EMC_SETUP
+
+
+; Copy Exception Vectors to Internal RAM ---------------------------------------
+
+ IF :DEF:RAM_INTVEC
+ ADR R8, Vectors ; Source
+ LDR R9, =RAM_BASE ; Destination
+ LDMIA R8!, {R0-R7} ; Load Vectors
+ STMIA R9!, {R0-R7} ; Store Vectors
+ LDMIA R8!, {R0-R7} ; Load Handler Addresses
+ STMIA R9!, {R0-R7} ; Store Handler Addresses
+ ENDIF
+
+
+; 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
+
+
+; 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
+
+ IF :DEF:__MICROLIB
+ EXPORT __initial_sp
+ ELSE
+ ENDIF
+
+; Enter the C code -------------------------------------------------------------
+
+ IMPORT __main
+ LDR R0, =__main
+ BX R0
+
+ IMPORT rt_interrupt_enter
+ IMPORT rt_interrupt_leave
+ IMPORT rt_thread_switch_interrput_flag
+ IMPORT rt_interrupt_from_thread
+ IMPORT rt_interrupt_to_thread
+ IMPORT rt_hw_trap_irq
+
+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_interrput_flag set, jump to
+ ; rt_hw_context_switch_interrupt_do and don't return
+ LDR r0, =rt_thread_switch_interrput_flag
+ LDR r1, [r0]
+ CMP r1, #1
+ BEQ rt_hw_context_switch_interrupt_do
+
+ LDMFD sp!, {r0-r12,lr}
+ SUBS pc, lr, #4
+ 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|F_Bit|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
+ MRS r4, spsr
+ STMFD sp!, {r4} ; push old task's spsr
+
+ 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 spsr
+ MSR spsr_cxsf, r4
+ LDMFD sp!, {r4} ; pop new task's psr
+ MSR cpsr_cxsf, r4
+
+ LDMFD sp!, {r0-r12,lr,pc} ; pop new task's r0-r12,lr & pc
+ 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
diff --git a/libcpu/arm/lpc24xx/trap.c b/libcpu/arm/lpc24xx/trap.c
new file mode 100644
index 0000000000..20ac45f8d2
--- /dev/null
+++ b/libcpu/arm/lpc24xx/trap.c
@@ -0,0 +1,132 @@
+/*
+ * File : trap.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2008-12-11 XuXinming first version
+ */
+
+#include <rtthread.h>
+#include <rthw.h>
+
+#include "LPC24xx.h"
+
+//#define BSP_INT_DEBUG
+
+/**
+ * @addtogroup LPC2478
+ */
+/*@{*/
+
+/**
+ * this function will show registers of CPU
+ *
+ * @param regs the registers point
+ */
+void rt_hw_show_register (struct rt_hw_register *regs)
+{
+ rt_kprintf("Execption:\n");
+ rt_kprintf("r00:0x%08x r01:0x%08x r02:0x%08x r03:0x%08x\n", regs->r0, regs->r1, regs->r2, regs->r3);
+ rt_kprintf("r04:0x%08x r05:0x%08x r06:0x%08x r07:0x%08x\n", regs->r4, regs->r5, regs->r6, regs->r7);
+ rt_kprintf("r08:0x%08x r09:0x%08x r10:0x%08x\n", regs->r8, regs->r9, regs->r10);
+ rt_kprintf("fp :0x%08x ip :0x%08x\n", regs->fp, regs->ip);
+ rt_kprintf("sp :0x%08x lr :0x%08x pc :0x%08x\n", regs->sp, regs->lr, regs->pc);
+ rt_kprintf("cpsr:0x%08x\n", regs->cpsr);
+}
+
+/**
+ * When ARM7TDMI comes across an instruction which it cannot handle,
+ * it takes the undefined instruction trap.
+ *
+ * @param regs system registers
+ *
+ * @note never invoke this function in application
+ */
+void rt_hw_trap_udef(struct rt_hw_register *regs)
+{
+ rt_kprintf("undefined instruction\n");
+ rt_hw_show_register(regs);
+ rt_hw_cpu_shutdown();
+}
+
+/**
+ * The software interrupt instruction (SWI) is used for entering
+ * Supervisor mode, usually to request a particular supervisor
+ * function.
+ *
+ * @param regs system registers
+ *
+ * @note never invoke this function in application
+ */
+void rt_hw_trap_swi(struct rt_hw_register *regs)
+{
+ rt_kprintf("software interrupt\n");
+ rt_hw_show_register(regs);
+ rt_hw_cpu_shutdown();
+}
+
+/**
+ * An abort indicates that the current memory access cannot be completed,
+ * which occurs during an instruction prefetch.
+ *
+ * @param regs system registers
+ *
+ * @note never invoke this function in application
+ */
+void rt_hw_trap_pabt(struct rt_hw_register *regs)
+{
+ rt_kprintf("prefetch abort\n");
+ rt_hw_show_register(regs);
+ rt_hw_cpu_shutdown();
+}
+
+/**
+ * An abort indicates that the current memory access cannot be completed,
+ * which occurs during a data access.
+ *
+ * @param regs system registers
+ *
+ * @note never invoke this function in application
+ */
+void rt_hw_trap_dabt(struct rt_hw_register *regs)
+{
+ rt_kprintf("Data Abort ");
+ rt_hw_show_register(regs);
+ rt_hw_cpu_shutdown();
+}
+
+/**
+ * Normally, system will never reach here
+ *
+ * @param regs system registers
+ *
+ * @note never invoke this function in application
+ */
+void rt_hw_trap_resv(struct rt_hw_register *regs)
+{
+ rt_kprintf("not used\n");
+ rt_hw_show_register(regs);
+ rt_hw_cpu_shutdown();
+}
+
+extern rt_isr_handler_t isr_table[];
+void rt_hw_trap_irq()
+{
+ rt_isr_handler_t isr_func;
+
+ isr_func = (rt_isr_handler_t) VICVectAddr;
+ isr_func(0);
+}
+
+void rt_hw_trap_fiq()
+{
+ rt_kprintf("fast interrupt request\n");
+}
+
+/*@}*/
diff --git a/libcpu/arm/s3c44b0/context_gcc.S b/libcpu/arm/s3c44b0/context_gcc.S
new file mode 100644
index 0000000000..7b39e32522
--- /dev/null
+++ b/libcpu/arm/s3c44b0/context_gcc.S
@@ -0,0 +1,99 @@
+/*
+ * File : context.S
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2006-09-06 XuXinming first version
+ */
+
+/*!
+ * \addtogroup S3C44B0
+ */
+/*@{*/
+
+#define NOINT 0xc0
+
+/*
+ * rt_base_t rt_hw_interrupt_disable();
+ */
+.globl rt_hw_interrupt_disable
+rt_hw_interrupt_disable:
+ mrs r0, cpsr
+ orr r1, r0, #NOINT
+ msr cpsr_c, r1
+ mov pc, lr
+
+/*
+ * void rt_hw_interrupt_enable(rt_base_t level);
+ */
+.globl rt_hw_interrupt_enable
+rt_hw_interrupt_enable:
+ msr cpsr, r0
+ mov pc, lr
+
+/*
+ * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
+ * r0 --> from
+ * r1 --> to
+ */
+.globl rt_hw_context_switch
+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
+ stmfd sp!, {r4} @ push cpsr
+ mrs r4, spsr
+ stmfd sp!, {r4} @ push spsr
+
+ str sp, [r0] @ store sp in preempted tasks TCB
+ ldr sp, [r1] @ get new task stack pointer
+
+ ldmfd sp!, {r4} @ pop new task spsr
+ msr spsr_cxsf, r4
+ ldmfd sp!, {r4} @ pop new task cpsr
+ msr cpsr_cxsf, r4
+
+ ldmfd sp!, {r0-r12, lr, pc} @ pop new task r0-r12, lr & pc
+
+/*
+ * void rt_hw_context_switch_to(rt_uint32 to);
+ * r0 --> to
+ */
+.globl rt_hw_context_switch_to
+rt_hw_context_switch_to:
+ ldr sp, [r0] @ get new task stack pointer
+
+ ldmfd sp!, {r4} @ pop new task spsr
+ msr spsr_cxsf, r4
+ ldmfd sp!, {r4} @ pop new task cpsr
+ msr cpsr_cxsf, r4
+
+ ldmfd sp!, {r0-r12, lr, pc} @ pop new task r0-r12, lr & pc
+
+/*
+ * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to);
+ */
+.globl rt_thread_switch_interrput_flag
+.globl rt_interrupt_from_thread
+.globl rt_interrupt_to_thread
+.globl rt_hw_context_switch_interrupt
+rt_hw_context_switch_interrupt:
+ ldr r2, =rt_thread_switch_interrput_flag
+ ldr r3, [r2]
+ cmp r3, #1
+ beq _reswitch
+ mov r3, #1 @ set rt_thread_switch_interrput_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]
+ mov pc, lr
diff --git a/libcpu/arm/s3c44b0/context_rvds.s b/libcpu/arm/s3c44b0/context_rvds.s
new file mode 100644
index 0000000000..82c5adc574
--- /dev/null
+++ b/libcpu/arm/s3c44b0/context_rvds.s
@@ -0,0 +1,107 @@
+;/*
+; * File : context_rvds.S
+; * This file is part of RT-Thread RTOS
+; * COPYRIGHT (C) 2006, RT-Thread Development Team
+; *
+; * The license and distribution terms for this file may be
+; * found in the file LICENSE in this distribution or at
+; * http://www.rt-thread.org/license/LICENSE
+; *
+; * Change Logs:
+; * Date Author Notes
+; * 2009-01-20 Bernard first version
+; */
+
+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
+ STMFD sp!, {r4} ; push cpsr
+ MRS r4, spsr
+ STMFD sp!, {r4} ; push spsr
+
+ STR sp, [r0] ; store sp in preempted tasks TCB
+ LDR sp, [r1] ; get new task stack pointer
+
+ LDMFD sp!, {r4} ; pop new task spsr
+ MSR spsr_cxsf, r4
+ LDMFD sp!, {r4} ; pop new task cpsr
+ MSR cpsr_cxsf, r4
+
+ LDMFD sp!, {r0-r12, lr, pc} ; pop new task r0-r12, lr & pc
+ 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 spsr
+ MSR spsr_cxsf, r4
+ LDMFD sp!, {r4} ; pop new task cpsr
+ MSR cpsr_cxsf, r4
+
+ LDMFD sp!, {r0-r12, lr, pc} ; pop new task r0-r12, lr & pc
+ ENDP
+
+;/*
+; * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to);
+; */
+ IMPORT rt_thread_switch_interrput_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_interrput_flag
+ LDR r3, [r2]
+ CMP r3, #1
+ BEQ _reswitch
+ MOV r3, #1 ; set rt_thread_switch_interrput_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
+
+ END \ No newline at end of file
diff --git a/libcpu/arm/s3c44b0/cpu.c b/libcpu/arm/s3c44b0/cpu.c
new file mode 100644
index 0000000000..088ca2e5fe
--- /dev/null
+++ b/libcpu/arm/s3c44b0/cpu.c
@@ -0,0 +1,122 @@
+/*
+ * File : cpu.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Develop Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2006-09-06 XuXinming first version
+ */
+
+#include <rtthread.h>
+#include "s3c44b0.h"
+
+/**
+ * @addtogroup S3C44B0
+ */
+/*@{*/
+
+/**
+ * This function will enable I-Cache of CPU
+ *
+ */
+void rt_hw_cpu_icache_enable()
+{
+ rt_base_t reg;
+
+ volatile int i;
+ /* flush cycle */
+ for(i = 0x10002000; i < 0x10004800; i+=16)
+ {
+ *((int *)i)=0x0;
+ }
+
+ /*
+ * Init cache
+ * Non-cacheable area (everything outside RAM)
+ * 0x0000:0000 - 0x0C00:0000
+ */
+ NCACHBE0 = 0xC0000000;
+ NCACHBE1 = 0x00000000;
+
+ /*
+ Enable chache
+ */
+ reg = SYSCFG;
+ reg |= 0x00000006; /* 8kB */
+ SYSCFG = reg;
+}
+
+/**
+ * This function will disable I-Cache of CPU
+ *
+ */
+void rt_hw_cpu_icache_disable()
+{
+ rt_base_t reg;
+
+ reg = SYSCFG;
+ reg &= ~0x00000006; /* 8kB */
+ SYSCFG = reg;
+}
+
+/**
+ * this function will get the status of I-Cache
+ *
+ */
+rt_base_t rt_hw_cpu_icache_status()
+{
+ return 0;
+}
+
+/**
+ * this function will enable D-Cache of CPU
+ *
+ */
+void rt_hw_cpu_dcache_enable()
+{
+ rt_hw_cpu_icache_enable();
+}
+
+/**
+ * this function will disable D-Cache of CPU
+ *
+ */
+void rt_hw_cpu_dcache_disable()
+{
+ rt_hw_cpu_icache_disable();
+}
+
+/**
+ * this function will get the status of D-Cache
+ *
+ */
+rt_base_t rt_hw_cpu_dcache_status()
+{
+ return rt_hw_cpu_icache_status();
+}
+
+/**
+ * this function will reset CPU
+ *
+ */
+void rt_hw_cpu_reset()
+{
+}
+
+/**
+ * this function will shutdown CPU
+ *
+ */
+void rt_hw_cpu_shutdown()
+{
+ rt_kprintf("shutdown...\n");
+
+ while (1);
+}
+
+/*@}*/
diff --git a/libcpu/arm/s3c44b0/interrupt.c b/libcpu/arm/s3c44b0/interrupt.c
new file mode 100644
index 0000000000..8051459712
--- /dev/null
+++ b/libcpu/arm/s3c44b0/interrupt.c
@@ -0,0 +1,148 @@
+/*
+ * File : trap.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2006-09-06 XuXinming first version
+ * 2006-09-15 Bernard add interrupt bank 0..3 for more effective
+ * in irq trap
+ */
+
+#include <rtthread.h>
+#include "s3c44b0.h"
+
+#define MAX_HANDLERS 26
+
+extern rt_uint32_t rt_interrupt_nest;
+
+/* exception and interrupt handler table */
+rt_isr_handler_t isr_table[MAX_HANDLERS];
+rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread;
+rt_uint32_t rt_thread_switch_interrput_flag;
+
+unsigned char interrupt_bank0[256];
+unsigned char interrupt_bank1[256];
+unsigned char interrupt_bank2[256];
+unsigned char interrupt_bank3[256];
+
+/**
+ * @addtogroup S3C44B0
+ */
+/*@{*/
+
+void rt_hw_interrupt_handle(int vector)
+{
+ rt_kprintf("Unhandled interrupt %d occured!!!\n", vector);
+}
+
+/**
+ * This function will initialize hardware interrupt
+ */
+void rt_hw_interrupt_init()
+{
+ register int i;
+
+ /* all interrupt disabled include global bit */
+ INTMSK = 0x07ffffff;
+
+ /* clear pending register */
+ I_ISPC = 0x03ffffff;
+
+ /* non-vector mode IRQ enable */
+ INTCON = 0x5;
+
+ /* all IRQ mode */
+ INTMOD = 0x0;
+
+ /* init exceptions table */
+ for(i=0; i<MAX_HANDLERS; i++)
+ {
+ isr_table[i] = rt_hw_interrupt_handle;
+ }
+
+ for ( i = 0; i < 256; i++)
+ {
+ interrupt_bank0[i] = 0;
+ interrupt_bank1[i] = 0;
+ interrupt_bank2[i] = 0;
+ interrupt_bank3[i] = 0;
+ }
+
+ /* setup interrupt bank table */
+ interrupt_bank0[1] = 0;
+ interrupt_bank0[2] = 1;
+ interrupt_bank0[4] = 2;
+ interrupt_bank0[8] = 3;
+ interrupt_bank0[16] = 4;
+ interrupt_bank0[32] = 5;
+ interrupt_bank0[64] = 6;
+ interrupt_bank0[128]= 7;
+
+ interrupt_bank1[1] = 8;
+ interrupt_bank1[2] = 9;
+ interrupt_bank1[4] = 10;
+ interrupt_bank1[8] = 11;
+ interrupt_bank1[16] = 12;
+ interrupt_bank1[32] = 13;
+ interrupt_bank1[64] = 14;
+ interrupt_bank1[128]= 15;
+
+ interrupt_bank2[1] = 16;
+ interrupt_bank2[2] = 17;
+ interrupt_bank2[4] = 18;
+ interrupt_bank2[8] = 19;
+ interrupt_bank2[16] = 20;
+ interrupt_bank2[32] = 21;
+ interrupt_bank2[64] = 22;
+ interrupt_bank2[128]= 23;
+
+ interrupt_bank3[1] = 24;
+ interrupt_bank3[2] = 25;
+
+ /* 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_interrput_flag = 0;
+}
+
+/**
+ * This function will mask a interrupt.
+ * @param vector the interrupt number
+ */
+void rt_hw_interrupt_mask(int vector)
+{
+ INTMSK |= 1 << vector;
+}
+
+/**
+ * This function will un-mask a interrupt.
+ * @param vector the interrupt number
+ */
+void rt_hw_interrupt_umask(int vector)
+{
+ INTMSK &= ~(1 << vector);
+}
+
+/**
+ * This function will install a interrupt service routine to a interrupt.
+ * @param vector the interrupt number
+ * @param new_handler the interrupt service routine to be installed
+ * @param old_handler the old interrupt service routine
+ */
+void rt_hw_interrupt_install(int vector, rt_isr_handler_t new_handler, rt_isr_handler_t *old_handler)
+{
+ if(vector < MAX_HANDLERS)
+ {
+ if (old_handler != RT_NULL) *old_handler = isr_table[vector];
+ if (new_handler != RT_NULL) isr_table[vector] = new_handler;
+ }
+}
+
+/*@}*/
diff --git a/libcpu/arm/s3c44b0/s3c44b0.h b/libcpu/arm/s3c44b0/s3c44b0.h
new file mode 100644
index 0000000000..36f9f5a1e4
--- /dev/null
+++ b/libcpu/arm/s3c44b0/s3c44b0.h
@@ -0,0 +1,346 @@
+/*
+ * File : s3c45b0.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Develop Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2006-09-06 XuXinming first version
+ * 2006-09-16 Bernard modify according to code style
+ */
+
+#ifndef __S3C44B0_H__
+#define __S3C44B0_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup S3C44B0
+ */
+/*@{*/
+
+/*------------------------------------------------------------------------
+ * ASIC Address Definition
+ *----------------------------------------------------------------------*/
+#define S3C_REG *(volatile unsigned int *)
+#define S3C_REGW *(volatile unsigned short *)
+#define S3C_REGB *(volatile unsigned char *)
+
+/* System */
+#define SYSCFG (S3C_REG(0x1c00000))
+
+/* Cache */
+#define NCACHBE0 (S3C_REG(0x1c00004))
+#define NCACHBE1 (S3C_REG(0x1c00008))
+
+/* Bus control */
+#define SBUSCON (S3C_REG(0x1c40000))
+
+/* Memory control */
+#define BWSCON (S3C_REG(0x1c80000))
+#define BANKCON0 (S3C_REG(0x1c80004))
+#define BANKCON1 (S3C_REG(0x1c80008))
+#define BANKCON2 (S3C_REG(0x1c8000c))
+#define BANKCON3 (S3C_REG(0x1c80010))
+#define BANKCON4 (S3C_REG(0x1c80014))
+#define BANKCON5 (S3C_REG(0x1c80018))
+#define BANKCON6 (S3C_REG(0x1c8001c))
+#define BANKCON7 (S3C_REG(0x1c80020))
+#define REFRESH (S3C_REG(0x1c80024))
+#define BANKSIZE (S3C_REG(0x1c80028))
+#define MRSRB6 (S3C_REG(0x1c8002c))
+#define MRSRB7 (S3C_REG(0x1c80030))
+
+/* UART */
+#define ULCON0 (S3C_REG(0x1d00000))
+#define ULCON1 (S3C_REG(0x1d04000))
+#define UCON0 (S3C_REG(0x1d00004))
+#define UCON1 (S3C_REG(0x1d04004))
+#define UFCON0 (S3C_REG(0x1d00008))
+#define UFCON1 (S3C_REG(0x1d04008))
+#define UMCON0 (S3C_REG(0x1d0000c))
+#define UMCON1 (S3C_REG(0x1d0400c))
+#define UTRSTAT0 (S3C_REG(0x1d00010))
+#define UTRSTAT1 (S3C_REG(0x1d04010))
+#define UERSTAT0 (S3C_REG(0x1d00014))
+#define UERSTAT1 (S3C_REG(0x1d04014))
+#define UFSTAT0 (S3C_REG(0x1d00018))
+#define UFSTAT1 (S3C_REG(0x1d04018))
+#define UMSTAT0 (S3C_REG(0x1d0001c))
+#define UMSTAT1 (S3C_REG(0x1d0401c))
+#define UBRDIV0 (S3C_REG(0x1d00028))
+#define UBRDIV1 (S3C_REG(0x1d04028))
+
+#define UTXH0 (S3C_REGB(0x1d00020))
+#define UTXH1 (S3C_REGB(0x1d04020))
+#define URXH0 (S3C_REGB(0x1d00024))
+#define URXH1 (S3C_REGB(0x1d04024))
+
+/* SIO */
+#define SIOCON (S3C_REG(0x1d14000))
+#define SIODAT (S3C_REG(0x1d14004))
+#define SBRDR (S3C_REG(0x1d14008))
+#define IVTCNT (S3C_REG(0x1d1400c))
+#define DCNTZ (S3C_REG(0x1d14010))
+
+/* IIS */
+#define IISCON (S3C_REG(0x1d18000))
+#define IISMOD (S3C_REG(0x1d18004))
+#define IISPSR (S3C_REG(0x1d18008))
+#define IISFCON (S3C_REG(0x1d1800c))
+
+#define IISFIF (S3C_REQW(0x1d18010))
+
+/* I/O Port */
+#define PCONA (S3C_REG(0x1d20000))
+#define PDATA (S3C_REG(0x1d20004))
+
+#define PCONB (S3C_REG(0x1d20008))
+#define PDATB (S3C_REG(0x1d2000c))
+
+#define PCONC (S3C_REG(0x1d20010))
+#define PDATC (S3C_REG(0x1d20014))
+#define PUPC (S3C_REG(0x1d20018))
+
+#define PCOND (S3C_REG(0x1d2001c))
+#define PDATD (S3C_REG(0x1d20020))
+#define PUPD (S3C_REG(0x1d20024))
+
+#define PCONE (S3C_REG(0x1d20028))
+#define PDATE (S3C_REG(0x1d2002c))
+#define PUPE (S3C_REG(0x1d20030))
+
+#define PCONF (S3C_REG(0x1d20034))
+#define PDATF (S3C_REG(0x1d20038))
+#define PUPF (S3C_REG(0x1d2003c))
+
+#define PCONG (S3C_REG(0x1d20040))
+#define PDATG (S3C_REG(0x1d20044))
+#define PUPG (S3C_REG(0x1d20048))
+
+#define SPUCR (S3C_REG(0x1d2004c))
+#define EXTINT (S3C_REG(0x1d20050))
+#define EXTINTPND (S3C_REG(0x1d20054))
+
+/* Watchdog */
+#define WTCON (S3C_REG(0x1d30000))
+#define WTDAT (S3C_REG(0x1d30004))
+#define WTCNT (S3C_REG(0x1d30008))
+
+/* ADC */
+#define ADCCON (S3C_REG(0x1d40000))
+#define ADCPSR (S3C_REG(0x1d40004))
+#define ADCDAT (S3C_REG(0x1d40008))
+
+/* Timer */
+#define TCFG0 (S3C_REG(0x1d50000))
+#define TCFG1 (S3C_REG(0x1d50004))
+#define TCON (S3C_REG(0x1d50008))
+
+#define TCNTB0 (S3C_REG(0x1d5000c))
+#define TCMPB0 (S3C_REG(0x1d50010))
+#define TCNTO0 (S3C_REG(0x1d50014))
+
+#define TCNTB1 (S3C_REG(0x1d50018))
+#define TCMPB1 (S3C_REG(0x1d5001c))
+#define TCNTO1 (S3C_REG(0x1d50020))
+
+#define TCNTB2 (S3C_REG(0x1d50024))
+#define TCMPB2 (S3C_REG(0x1d50028))
+#define TCNTO2 (S3C_REG(0x1d5002c))
+
+#define TCNTB3 (S3C_REG(0x1d50030))
+#define TCMPB3 (S3C_REG(0x1d50034))
+#define TCNTO3 (S3C_REG(0x1d50038))
+
+#define TCNTB4 (S3C_REG(0x1d5003c))
+#define TCMPB4 (S3C_REG(0x1d50040))
+#define TCNTO4 (S3C_REG(0x1d50044))
+
+#define TCNTB5 (S3C_REG(0x1d50048))
+#define TCNTO5 (S3C_REG(0x1d5004c))
+
+/* IIC */
+#define IICCON (S3C_REG(0x1d60000))
+#define IICSTAT (S3C_REG(0x1d60004))
+#define IICADD (S3C_REG(0x1d60008))
+#define IICDS (S3C_REG(0x1d6000c))
+
+/* RTC */
+#define RTCCON (S3C_REGB(0x1d70040)
+#define RTCALM (S3C_REGB(0x1d70050)
+#define ALMSEC (S3C_REGB(0x1d70054)
+#define ALMMIN (S3C_REGB(0x1d70058)
+#define ALMHOUR (S3C_REGB(0x1d7005c)
+#define ALMDAY (S3C_REGB(0x1d70060)
+#define ALMMON (S3C_REGB(0x1d70064)
+#define ALMYEAR (S3C_REGB(0x1d70068)
+#define RTCRST (S3C_REGB(0x1d7006c)
+#define BCDSEC (S3C_REGB(0x1d70070)
+#define BCDMIN (S3C_REGB(0x1d70074)
+#define BCDHOUR (S3C_REGB(0x1d70078)
+#define BCDDAY (S3C_REGB(0x1d7007c)
+#define BCDDATE (S3C_REGB(0x1d70080)
+#define BCDMON (S3C_REGB(0x1d70084)
+#define BCDYEAR (S3C_REGB(0x1d70088)
+#define TICINT (S3C_REGB(0x1d7008c)
+
+/* Clock & Power management */
+#define PLLCON (S3C_REG(0x1d80000))
+#define CLKCON (S3C_REG(0x1d80004))
+#define CLKSLOW (S3C_REG(0x1d80008))
+#define LOCKTIME (S3C_REG(0x1d8000c))
+
+/* Interrupt */
+#define INTCON (S3C_REG(0x1e00000))
+#define INTPND (S3C_REG(0x1e00004))
+#define INTMOD (S3C_REG(0x1e00008))
+#define INTMSK (S3C_REG(0x1e0000c))
+
+#define I_PSLV (S3C_REG(0x1e00010))
+#define I_PMST (S3C_REG(0x1e00014))
+#define I_CSLV (S3C_REG(0x1e00018))
+#define I_CMST (S3C_REG(0x1e0001c))
+#define I_ISPR (S3C_REG(0x1e00020))
+#define I_ISPC (S3C_REG(0x1e00024))
+
+#define F_ISPR (S3C_REG(0x1e00038))
+#define F_ISPC (S3C_REG(0x1e0003c))
+
+/********************************/
+/* LCD Controller Registers */
+/********************************/
+#define LCDCON1 (S3C_REG(0x300000))
+#define LCDCON2 (S3C_REG(0x300004))
+#define LCDSADDR1 (S3C_REG(0x300008))
+#define LCDSADDR2 (S3C_REG(0x30000c))
+#define LCDSADDR3 (S3C_REG(0x300010))
+#define REDLUT (S3C_REG(0x300014))
+#define GREENLUT (S3C_REG(0x300018))
+#define BLUELUT (S3C_REG(0x30001c))
+#define DP1_2 (S3C_REG(0x300020))
+#define DP4_7 (S3C_REG(0x300024))
+#define DP3_5 (S3C_REG(0x300028))
+#define DP2_3 (S3C_REG(0x30002c))
+#define DP5_7 (S3C_REG(0x300030))
+#define DP3_4 (S3C_REG(0x300034))
+#define DP4_5 (S3C_REG(0x300038))
+#define DP6_7 (S3C_REG(0x30003c))
+#define LCDCON3 (S3C_REG(0x300040))
+#define DITHMODE (S3C_REG(0x300044))
+
+/* ZDMA0 */
+#define ZDCON0 (S3C_REG(0x1e80000))
+#define ZDISRC0 (S3C_REG(0x1e80004))
+#define ZDIDES0 (S3C_REG(0x1e80008))
+#define ZDICNT0 (S3C_REG(0x1e8000c))
+#define ZDCSRC0 (S3C_REG(0x1e80010))
+#define ZDCDES0 (S3C_REG(0x1e80014))
+#define ZDCCNT0 (S3C_REG(0x1e80018))
+
+/* ZDMA1 */
+#define ZDCON1 (S3C_REG(0x1e80020))
+#define ZDISRC1 (S3C_REG(0x1e80024))
+#define ZDIDES1 (S3C_REG(0x1e80028))
+#define ZDICNT1 (S3C_REG(0x1e8002c))
+#define ZDCSRC1 (S3C_REG(0x1e80030))
+#define ZDCDES1 (S3C_REG(0x1e80034))
+#define ZDCCNT1 (S3C_REG(0x1e80038))
+
+/* BDMA0 */
+#define BDCON0 (S3C_REG(0x1f80000))
+#define BDISRC0 (S3C_REG(0x1f80004))
+#define BDIDES0 (S3C_REG(0x1f80008))
+#define BDICNT0 (S3C_REG(0x1f8000c))
+#define BDCSRC0 (S3C_REG(0x1f80010))
+#define BDCDES0 (S3C_REG(0x1f80014))
+#define BDCCNT0 (S3C_REG(0x1f80018))
+
+/* BDMA1 */
+#define BDCON1 (S3C_REG(0x1f80020))
+#define BDISRC1 (S3C_REG(0x1f80024))
+#define BDIDES1 (S3C_REG(0x1f80028))
+#define BDICNT1 (S3C_REG(0x1f8002c))
+#define BDCSRC1 (S3C_REG(0x1f80030))
+#define BDCDES1 (S3C_REG(0x1f80034))
+#define BDCCNT1 (S3C_REG(0x1f80038))
+
+/*****************************/
+/* CPU Mode */
+/*****************************/
+#define USERMODE 0x10 /* User Mode(USR) */
+#define FIQMODE 0x11 /* Fast Interrupt Mode (FIQ) */
+#define IRQMODE 0x12 /* Interrupt Mode (IRQ) */
+#define SVCMODE 0x13 /* Supervisor Mode (SVC) */
+#define ABORTMODE 0x17 /* Abort Mode(ABT) */
+#define UNDEFMODE 0x1b /* Undefine Mode(UDF) */
+#define MODEMASK 0x1f /* Processor Mode Mask */
+#define NOINT 0xc0
+
+/*****************************/
+/* INT Define */
+/*****************************/
+#define INT_ADC 0x00
+#define INT_RTC 0x01
+#define INT_UTXD1 0x02
+#define INT_UTXD0 0x03
+#define INT_SIO 0x04
+#define INT_IIC 0x05
+#define INT_URXD1 0x06
+#define INT_URXD0 0x07
+#define INT_TIMER5 0x08
+#define INT_TIMER4 0x09
+#define INT_TIMER3 0x0A
+#define INT_TIMER2 0x0B
+#define INT_TIMER1 0x0C
+#define INT_TIMER0 0x0D
+#define INT_UERR01 0x0E
+#define INT_WDT 0x1F
+#define INT_BDMA1 0x10
+#define INT_BDMA0 0x11
+#define INT_ZDMA1 0x12
+#define INT_ZDMA0 0x13
+#define INT_TICK 0x14
+#define INT_EINT4567 0x15
+#define INT_EINT3 0x16
+#define INT_EINT2 0x17
+#define INT_EINT1 0x18
+#define INT_EINT0 0x19
+
+#define INT_GLOBAL 26
+
+struct rt_hw_register
+{
+ unsigned long r0;
+ unsigned long r1;
+ unsigned long r2;
+ unsigned long r3;
+ unsigned long r4;
+ unsigned long r5;
+ unsigned long r6;
+ unsigned long r7;
+ unsigned long r8;
+ unsigned long r9;
+ unsigned long r10;
+ unsigned long fp;
+ unsigned long ip;
+ unsigned long sp;
+ unsigned long lr;
+ unsigned long pc;
+ unsigned long cpsr;
+ unsigned long ORIG_r0;
+};
+
+/*@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libcpu/arm/s3c44b0/serial.c b/libcpu/arm/s3c44b0/serial.c
new file mode 100644
index 0000000000..1e41ff8383
--- /dev/null
+++ b/libcpu/arm/s3c44b0/serial.c
@@ -0,0 +1,118 @@
+/*
+ * File : serial.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2006-09-06 XuXinming first version
+ * 2006-09-20 Bernard clean code according code style
+ */
+
+#include <rtthread.h>
+#include <rthw.h>
+
+#include "s3c44b0.h"
+
+void rt_serial_init(void);
+void rt_console_puts(const char* str);
+void rt_serial_putc(const char c);
+
+#define USTAT_RCV_READY 0x01 /* receive data ready */
+#define USTAT_TXB_EMPTY 0x02 /* tx buffer empty */
+
+rt_inline void serial_flush_input(void)
+{
+ volatile unsigned int tmp;
+
+ /* keep on reading as long as the receiver is not empty */
+ while(UTRSTAT0 & USTAT_RCV_READY) tmp = URXH0;
+}
+
+rt_inline void serial_flush_output(void)
+{
+ /* wait until the transmitter is no longer busy */
+ while(!(UTRSTAT0 & USTAT_TXB_EMPTY)) ;
+}
+
+/**
+ * @addtogroup S3C44B0
+ */
+/*@{*/
+
+/**
+ * This function is used to display a string on console, normally, it's
+ * invoked by rt_kprintf
+ *
+ * @param str the displayed string
+ */
+void rt_console_puts(const char* str)
+{
+ while (*str)
+ {
+ rt_serial_putc (*str++);
+ }
+}
+
+/**
+ * This function initializes serial
+ */
+void rt_serial_init()
+{
+ rt_uint32_t divisor = 0;
+
+ divisor = 0x20;
+
+ serial_flush_output();
+ serial_flush_input();
+
+ /* UART interrupt off */
+ UCON0 = 0;
+ /* FIFO disable */
+ UFCON0 =0x0;
+ UMCON0 =0x0;
+ /* set baudrate */
+ UBRDIV0 = divisor;
+
+ /* word length=8bit, stop bit = 1, no parity, use external clock */
+ ULCON0 = 0x03|0x00|0x00;
+
+ UCON0 = 0x5;
+}
+
+/**
+ * This function read a character from serial without interrupt enable mode
+ *
+ * @return the read char
+ */
+char rt_serial_getc()
+{
+ while ((UTRSTAT0 & USTAT_RCV_READY) == 0);
+
+ return URXH0;
+}
+
+/**
+ * This function will write a character to serial without interrupt enable mode
+ *
+ * @param c the char to write
+ */
+void rt_serial_putc(const char c)
+{
+ /*
+ to be polite with serial console add a line feed
+ to the carriage return character
+ */
+ if (c=='\n')rt_serial_putc('\r');
+
+ /* wait for room in the transmit FIFO */
+ while(!(UTRSTAT0 & USTAT_TXB_EMPTY));
+
+ UTXH0 = (rt_uint8_t)c;
+}
+
+/*@}*/
diff --git a/libcpu/arm/s3c44b0/stack.c b/libcpu/arm/s3c44b0/stack.c
new file mode 100644
index 0000000000..3f1d88a390
--- /dev/null
+++ b/libcpu/arm/s3c44b0/stack.c
@@ -0,0 +1,60 @@
+/*
+ * File : stack.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2006-09-06 XuXinming first version
+ */
+#include <rtthread.h>
+#include "s3c44b0.h"
+
+/**
+ * @addtogroup S3C44B0
+ */
+/*@{*/
+
+/**
+ * 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 */
+ *(--stk) = SVCMODE; /* cpsr */
+ *(--stk) = SVCMODE; /* spsr */
+
+ /* return task's current stack address */
+ return (rt_uint8_t *)stk;
+}
+
+/*@}*/
diff --git a/libcpu/arm/s3c44b0/start_gcc.S b/libcpu/arm/s3c44b0/start_gcc.S
new file mode 100644
index 0000000000..4108fc2462
--- /dev/null
+++ b/libcpu/arm/s3c44b0/start_gcc.S
@@ -0,0 +1,257 @@
+/*
+ * File : start.S
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2006-09-06 XuXinming first version
+ * 2006-09-20 Bernard clean the code
+ */
+
+/**
+ * @addtogroup S3C44B0
+ */
+/*@{*/
+
+.section .init, "ax"
+.code 32
+.globl _start
+_start:
+ b reset
+ ldr pc, _vector_undef
+ ldr pc, _vector_swi
+ ldr pc, _vector_pabt
+ ldr pc, _vector_dabt
+ ldr pc, _vector_resv
+ ldr pc, _vector_irq
+ ldr pc, _vector_fiq
+
+_vector_undef: .word vector_undef
+_vector_swi: .word vector_swi
+_vector_pabt: .word vector_pabt
+_vector_dabt: .word vector_dabt
+_vector_resv: .word vector_resv
+_vector_irq: .word vector_irq
+_vector_fiq: .word vector_fiq
+
+.text
+.code 32
+
+/*
+ * rtthread kernel start and end
+ * which are defined in linker script
+ */
+.globl _rtthread_start
+_rtthread_start:.word _start
+.globl _rtthread_end
+_rtthread_end: .word _end
+
+/*
+ * rtthread bss start and end
+ * which are defined in linker script
+ */
+.globl _bss_start
+_bss_start: .word __bss_start
+.globl _bss_end
+_bss_end: .word __bss_end
+
+#if defined(__FLASH_BUILD__)
+/*
+ * TEXT_BASE,
+ * which is defined in macro of make
+ */
+_TEXT_BASE: .word TEXT_BASE
+#endif
+
+ .equ WTCON, 0x1d30000
+ .equ INTCON, 0x1e00000
+ .equ INTMSK, 0x1e0000c
+
+/* the system entry */
+reset:
+ /* enter svc mode */
+ msr cpsr_c, #SVCMODE|NOINT
+
+ /*watch dog disable */
+ ldr r0,=WTCON
+ ldr r1,=0x0
+ str r1,[r0]
+
+ /* all interrupt disable */
+ ldr r0,=INTMSK
+ ldr r1,=0x07ffffff
+ str r1,[r0]
+
+ ldr r1, =INTCON
+ ldr r0, =0x05
+ str r0, [r1]
+
+#if defined(__FLASH_BUILD__)
+ /* init lowlevel */
+ bl lowlevel_init
+#endif
+
+ /* setup stack */
+ bl stack_setup
+
+#if defined(__FLASH_BUILD__)
+ mov r0, #0x0 /* r0 <- flash base address */
+ ldr r1, _TEXT_BASE /* r1 <- the taget address */
+
+ ldr r2, _rtthread_start
+ ldr r3, _bss_start
+ sub r2, r3, r2 /* r2 <- size of rtthread kernel */
+ add r2, r0, r2 /* r2 <- source end address */
+
+copy_loop:
+ ldmia r0!, {r3-r10} /* copy from source address [r0] */
+ stmia r1!, {r3-r10} /* copy to target address [r1] */
+ cmp r0, r2 /* until source end addreee [r2] */
+ ble copy_loop
+#endif
+
+ /* start RT-Thread Kernel */
+ ldr pc, _rtthread_startup
+
+_rtthread_startup: .word rtthread_startup
+
+ .equ USERMODE, 0x10
+ .equ FIQMODE, 0x11
+ .equ IRQMODE, 0x12
+ .equ SVCMODE, 0x13
+ .equ ABORTMODE, 0x17
+ .equ UNDEFMODE, 0x1b
+ .equ MODEMASK, 0x1f
+ .equ NOINT, 0xc0
+
+/* exception handlers */
+vector_undef: bl rt_hw_trap_udef
+vector_swi: bl rt_hw_trap_swi
+vector_pabt: bl rt_hw_trap_pabt
+vector_dabt: bl rt_hw_trap_dabt
+vector_resv: bl rt_hw_trap_resv
+
+.globl rt_interrupt_enter
+.globl rt_interrupt_leave
+.globl rt_thread_switch_interrput_flag
+.globl rt_interrupt_from_thread
+.globl rt_interrupt_to_thread
+vector_irq:
+ stmfd sp!, {r0-r12,lr}
+ bl led_off
+ bl rt_interrupt_enter
+ bl rt_hw_trap_irq
+ bl rt_interrupt_leave
+
+ /* if rt_thread_switch_interrput_flag set, jump to _interrupt_thread_switch and don't return */
+ ldr r0, =rt_thread_switch_interrput_flag
+ ldr r1, [r0]
+ cmp r1, #1
+ beq _interrupt_thread_switch
+
+ ldmfd sp!, {r0-r12,lr}
+ subs pc, lr, #4
+
+ .align 5
+vector_fiq:
+ stmfd sp!,{r0-r7,lr}
+ bl rt_hw_trap_fiq
+ ldmfd sp!,{r0-r7,lr}
+ subs pc,lr,#4
+
+_interrupt_thread_switch:
+ mov r1, #0 @ clear rt_thread_switch_interrput_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 @ disable interrupt
+ orr r0, r3, #NOINT
+ msr spsr_c, r0
+
+ ldr r0, =.+8 @ switch to interrupted task's stack
+ movs pc, r0
+
+ 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 psr
+ mrs r4, spsr
+ stmfd sp!, {r4} @ push old task's spsr
+
+ 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 spsr
+ msr SPSR_cxsf, r4
+ ldmfd sp!, {r4} @ pop new task's psr
+ msr CPSR_cxsf, r4
+
+ ldmfd sp!, {r0-r12,lr,pc} @ pop new task's r0-r12,lr & pc
+
+/* each mode stack memory */
+UNDSTACK_START: .word _undefined_stack_start + 128
+ABTSTACK_START: .word _abort_stack_start + 128
+FIQSTACK_START: .word _fiq_stack_start + 1024
+IRQSTACK_START: .word _irq_stack_start + 1024
+SVCSTACK_START: .word _svc_stack_start + 4096
+
+stack_setup:
+ /* undefined instruction mode */
+ msr cpsr_c, #UNDEFMODE|NOINT
+ ldr sp, UNDSTACK_START
+
+ /* abort mode */
+ msr cpsr_c, #ABORTMODE|NOINT
+ ldr sp, ABTSTACK_START
+
+ /* FIQ mode */
+ msr cpsr_c, #FIQMODE|NOINT
+ ldr sp, FIQSTACK_START
+
+ /* IRQ mode */
+ msr cpsr_c, #IRQMODE|NOINT
+ ldr sp, IRQSTACK_START
+
+ /* supervisor mode */
+ msr cpsr_c, #SVCMODE|NOINT
+ ldr sp, SVCSTACK_START
+
+ mov pc,lr @ The LR register may be not valid for the mode changes.
+
+.globl led_on
+led_on:
+ ldr r1, =0x1d20014 @ r1<-PDATC
+ ldr r0, [r1] @ r0<-[r1]
+ orr r0, r0, #0x0e @ r0=r0 or 0x0e
+ str r0, [r1] @ r0->[r1]
+ mov pc, lr
+
+.globl led_off
+led_off:
+ ldr r1, =0x1d20010 @ r1<-PCONC
+ ldr r0, =0x5f555555 @ r0<-0x5f555555
+ str r0, [r1] @ r0->[r1]
+
+ ldr r1, =0x1d20014 @ r1<-PDATC
+ ldr r0, =0x0 @ r0<-00
+ str r0, [r1] @ r0->[r1]
+
+ mov pc, lr
diff --git a/libcpu/arm/s3c44b0/start_rvds.s b/libcpu/arm/s3c44b0/start_rvds.s
new file mode 100644
index 0000000000..3154bf3751
--- /dev/null
+++ b/libcpu/arm/s3c44b0/start_rvds.s
@@ -0,0 +1,1072 @@
+;/*****************************************************************************/
+;/* S3C44B0X.S: Startup file for Samsung S3C44B0X */
+;/*****************************************************************************/
+;/* <<< Use Configuration Wizard in Context Menu >>> */
+;/*****************************************************************************/
+;/* This file is part of the uVision/ARM development tools. */
+;/* Copyright (c) 2005-2006 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. */
+;/*****************************************************************************/
+
+
+; *** Startup Code (executed after Reset) ***
+
+
+; 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
+
+
+; CPU Wrapper and Bus Priorities definitions
+CPUW_BASE EQU 0x01C00000 ; CPU Wrapper Base Address
+SYSCFG_OFS EQU 0x00 ; SYSCFG Offset
+NCACHBE0_OFS EQU 0x04 ; NCACHBE0 Offset
+NCACHBE1_OFS EQU 0x08 ; NCACHBE0 Offset
+BUSP_BASE EQU 0x01C40000 ; Bus Priority Base Address
+SBUSCON_OFS EQU 0x00 ; SBUSCON Offset
+
+;// <e> CPU Wrapper and Bus Priorities
+;// <h> CPU Wrapper
+;// <o1.0> SE: Stall Enable
+;// <o1.1..2> CM: Cache Mode
+;// <0=> Disable Cache (8kB SRAM)
+;// <1=> Half Cache Enable (4kB Cache, 4kB SRAM)
+;// <2=> Reserved
+;// <3=> Full Cache Enable (8kB Cache)
+;// <o1.3> WE: Write Buffer Enable
+;// <o1.4> RSE: Read Stall Enable
+;// <o1.5> DA: Data Abort <0=> Enable <1=> Disable
+;// <h> Non-cacheable Area 0
+;// <o2.0..15> Start Address <0x0-0x0FFFF000:0x1000><#/0x1000>
+;// <i> SA = (Start Address) / 4k
+;// <o2.16..31> End Address + 1 <0x0-0x10000000:0x1000><#/0x1000>
+;// <i> SE = (End Address + 1) / 4k
+;// </h>
+;// <h> Non-cacheable Area 1
+;// <o3.0..15> Start Address <0x0-0x0FFFF000:0x1000><#/0x1000>
+;// <i> SA = (Start Address) / 4k
+;// <o3.16..31> End Address + 1 <0x0-0x10000000:0x1000><#/0x1000>
+;// <i> SE = (End Address + 1) / 4k
+;// </h>
+;// </h>
+;// <h> Bus Priorities
+;// <o4.31> FIX: Fixed Priorities
+;// <o4.6..7> LCD_DMA <0=> 1st <1=> 2nd <2=> 3rd <3=> 4th
+;// <o4.4..5> ZDMA <0=> 1st <1=> 2nd <2=> 3rd <3=> 4th
+;// <o4.2..3> BDMA <0=> 1st <1=> 2nd <2=> 3rd <3=> 4th
+;// <o4.0..1> nBREQ <0=> 1st <1=> 2nd <2=> 3rd <3=> 4th
+;// </h>
+;// </e>
+SYS_SETUP EQU 0
+SYSCFG_Val EQU 0x00000001
+NCACHBE0_Val EQU 0x00000000
+NCACHBE1_Val EQU 0x00000000
+SBUSCON_Val EQU 0x80001B1B
+
+
+;// <e> Vectored Interrupt Mode (for IRQ)
+;// <o1.25> EINT0 <i> External Interrupt 0
+;// <o1.24> EINT1 <i> External Interrupt 1
+;// <o1.23> EINT2 <i> External Interrupt 2
+;// <o1.22> EINT3 <i> External Interrupt 3
+;// <o1.21> EINT4567 <i> External Interrupt 4/5/6/7
+;// <o1.20> TICK <i> RTC Time Tick Interrupt
+;// <o1.19> ZDMA0 <i> General DMA0 Interrupt
+;// <o1.18> ZDMA1 <i> General DMA1 Interrupt
+;// <o1.17> BDMA0 <i> Bridge DMA0 Interrupt
+;// <o1.16> BDMA1 <i> Bridge DMA1 Interrupt
+;// <o1.15> WDT <i> Watchdog Timer Interrupt
+;// <o1.14> UERR01 <i> UART0/1 Error Interrupt
+;// <o1.13> TIMER0 <i> Timer0 Interrupt
+;// <o1.12> TIMER1 <i> Timer1 Interrupt
+;// <o1.11> TIMER2 <i> Timer2 Interrupt
+;// <o1.10> TIMER3 <i> Timer3 Interrupt
+;// <o1.9> TIMER4 <i> Timer4 Interrupt
+;// <o1.8> TIMER5 <i> Timer5 Interrupt
+;// <o1.7> URXD0 <i> UART0 Rx Interrupt
+;// <o1.6> URXD1 <i> UART1 Rx Interrupt
+;// <o1.5> IIC <i> IIC Interrupt
+;// <o1.4> SIO <i> SIO Interrupt
+;// <o1.3> UTXD0 <i> UART0 Tx Interrupt
+;// <o1.2> UTXD1 <i> UART1 Tx Interrupt
+;// <o1.1> RTC <i> RTC Alarm Interrupt
+;// <o1.0> ADC <i> ADC EOC Interrupt
+;// </e>
+VIM_SETUP EQU 0
+VIM_CFG EQU 0x00000000
+
+
+; Clock Management definitions
+CLK_BASE EQU 0x01D80000 ; Clock Base Address
+PLLCON_OFS EQU 0x00 ; PLLCON Offset
+CLKCON_OFS EQU 0x04 ; CLKCON Offset
+CLKSLOW_OFS EQU 0x08 ; CLKSLOW Offset
+LOCKTIME_OFS EQU 0x0C ; LOCKTIME Offset
+
+;// <e> Clock Management
+;// <h> PLL Settings
+;// <i> Fpllo = (m * Fin) / (p * 2^s), 20MHz < Fpllo < 66MHz
+;// <o1.12..19> MDIV: Main divider <0x0-0xFF>
+;// <i> m = MDIV + 8
+;// <o1.4..9> PDIV: Pre-divider <0x0-0x3F>
+;// <i> p = PDIV + 2, 1MHz <= Fin/p < 2MHz
+;// <o1.0..1> SDIV: Post Divider <0x0-0x03>
+;// <i> s = SDIV, Fpllo * 2^s < 170MHz
+;// <o4.0..11> LTIME CNT: PLL Lock Time Count <0x0-0x0FFF>
+;// </h>
+;// <h> Master Clock
+;// <i> PLL Clock: Fout = Fpllo
+;// <i> Slow Clock: Fout = Fin / (2 * SLOW_VAL), SLOW_VAL > 0
+;// <i> Slow Clock: Fout = Fin, SLOW_VAL = 0
+;// <o3.5> PLL_OFF: PLL Off
+;// <i> PLL is turned Off only when SLOW_BIT = 1
+;// <o3.4> SLOW_BIT: Slow Clock
+;// <o3.0..3> SLOW_VAL: Slow Clock divider <0x0-0x0F>
+;// </h>
+;// <h> Clock Generation
+;// <o2.14> IIS <0=> Disable <1=> Enable
+;// <o2.13> IIC <0=> Disable <1=> Enable
+;// <o2.12> ADC <0=> Disable <1=> Enable
+;// <o2.11> RTC <0=> Disable <1=> Enable
+;// <o2.10> GPIO <0=> Disable <1=> Enable
+;// <o2.9> UART1 <0=> Disable <1=> Enable
+;// <o2.8> UART0 <0=> Disable <1=> Enable
+;// <o2.7> BDMA0,1 <0=> Disable <1=> Enable
+;// <o2.6> LCDC <0=> Disable <1=> Enable
+;// <o2.5> SIO <0=> Disable <1=> Enable
+;// <o2.4> ZDMA0,1 <0=> Disable <1=> Enable
+;// <o2.3> PWMTIMER <0=> Disable <1=> Enable
+;// </h>
+;// </e>
+CLK_SETUP EQU 1
+PLLCON_Val EQU 0x00038080
+CLKCON_Val EQU 0x00007FF8
+CLKSLOW_Val EQU 0x00000009
+LOCKTIME_Val EQU 0x00000FFF
+
+
+; Watchdog Timer definitions
+WT_BASE EQU 0x01D30000 ; WT Base Address
+WTCON_OFS EQU 0x00 ; WTCON Offset
+WTDAT_OFS EQU 0x04 ; WTDAT Offset
+WTCNT_OFS EQU 0x08 ; WTCNT Offset
+
+;// <e> Watchdog Timer
+;// <o1.5> Watchdog Timer Enable/Disable
+;// <o1.0> Reset Enable/Disable
+;// <o1.2> Interrupt Enable/Disable
+;// <o1.3..4> Clock Select
+;// <0=> 1/16 <1=> 1/32 <2=> 1/64 <3=> 1/128
+;// <i> Clock Division Factor
+;// <o1.8..15> Prescaler Value <0x0-0xFF>
+;// <o2.0..15> Time-out Value <0x0-0xFFFF>
+;// </e>
+WT_SETUP EQU 1
+WTCON_Val EQU 0x00008000
+WTDAT_Val EQU 0x00008000
+
+
+; Memory Controller definitions
+MC_BASE EQU 0x01C80000 ; Memory Controller Base Address
+
+;// <e> Memory Controller
+MC_SETUP EQU 1
+
+;// <h> Bank 0
+;// <o0.0..1> PMC: Page Mode Configuration
+;// <0=> 1 Data <1=> 4 Data <2=> 8 Data <3=> 16 Data
+;// <o0.2..3> Tpac: Page Mode Access Cycle
+;// <0=> 2 clks <1=> 3 clks <2=> 4 clks <3=> 6 clks
+;// <o0.4..5> Tcah: Address Holding Time after nGCSn
+;// <0=> 0 clk <1=> 1 clk <2=> 2 clks <3=> 4 clks
+;// <o0.6..7> Toch: Chip Select Hold on nOE
+;// <0=> 0 clk <1=> 1 clk <2=> 2 clks <3=> 4 clks
+;// <o0.8..10> Tacc: Access Cycle
+;// <0=> 1 clk <1=> 2 clks <2=> 3 clks <3=> 4 clks
+;// <4=> 6 clk <5=> 8 clks <6=> 10 clks <7=> 14 clks
+;// <o0.11..12> Tcos: Chip Select Set-up nOE
+;// <0=> 0 clk <1=> 1 clk <2=> 2 clks <3=> 4 clks
+;// <o0.13..14> Tacs: Address Set-up before nGCSn
+;// <0=> 0 clk <1=> 1 clk <2=> 2 clks <3=> 4 clks
+;// </h>
+;//
+;// <h> Bank 1
+;// <o8.4..5> DW: Data Bus Width
+;// <0=> 8-bit <1=> 16-bit <2=> 32-bit <3=> Rsrvd
+;// <o8.6> WS: WAIT Status
+;// <0=> WAIT Disable
+;// <1=> WAIT Enable
+;// <o8.7> ST: SRAM Type
+;// <0=> Not using UB/LB
+;// <1=> Using UB/LB
+;// <o1.0..1> PMC: Page Mode Configuration
+;// <0=> 1 Data <1=> 4 Data <2=> 8 Data <3=> 16 Data
+;// <o1.2..3> Tpac: Page Mode Access Cycle
+;// <0=> 2 clks <1=> 3 clks <2=> 4 clks <3=> 6 clks
+;// <o1.4..5> Tcah: Address Holding Time after nGCSn
+;// <0=> 0 clk <1=> 1 clk <2=> 2 clks <3=> 4 clks
+;// <o1.6..7> Toch: Chip Select Hold on nOE
+;// <0=> 0 clk <1=> 1 clk <2=> 2 clks <3=> 4 clks
+;// <o1.8..10> Tacc: Access Cycle
+;// <0=> 1 clk <1=> 2 clks <2=> 3 clks <3=> 4 clks
+;// <4=> 6 clk <5=> 8 clks <6=> 10 clks <7=> 14 clks
+;// <o1.11..12> Tcos: Chip Select Set-up nOE
+;// <0=> 0 clk <1=> 1 clk <2=> 2 clks <3=> 4 clks
+;// <o1.13..14> Tacs: Address Set-up before nGCSn
+;// <0=> 0 clk <1=> 1 clk <2=> 2 clks <3=> 4 clks
+;// </h>
+;//
+;// <h> Bank 2
+;// <o8.8..9> DW: Data Bus Width
+;// <0=> 8-bit <1=> 16-bit <2=> 32-bit <3=> Rsrvd
+;// <o8.10> WS: WAIT Status
+;// <0=> WAIT Disable
+;// <1=> WAIT Enable
+;// <o8.11> ST: SRAM Type
+;// <0=> Not using UB/LB
+;// <1=> Using UB/LB
+;// <o2.0..1> PMC: Page Mode Configuration
+;// <0=> 1 Data <1=> 4 Data <2=> 8 Data <3=> 16 Data
+;// <o2.2..3> Tpac: Page Mode Access Cycle
+;// <0=> 2 clks <1=> 3 clks <2=> 4 clks <3=> 6 clks
+;// <o2.4..5> Tcah: Address Holding Time after nGCSn
+;// <0=> 0 clk <1=> 1 clk <2=> 2 clks <3=> 4 clks
+;// <o2.6..7> Toch: Chip Select Hold on nOE
+;// <0=> 0 clk <1=> 1 clk <2=> 2 clks <3=> 4 clks
+;// <o2.8..10> Tacc: Access Cycle
+;// <0=> 1 clk <1=> 2 clks <2=> 3 clks <3=> 4 clks
+;// <4=> 6 clk <5=> 8 clks <6=> 10 clks <7=> 14 clks
+;// <o2.11..12> Tcos: Chip Select Set-up nOE
+;// <0=> 0 clk <1=> 1 clk <2=> 2 clks <3=> 4 clks
+;// <o2.13..14> Tacs: Address Set-up before nGCSn
+;// <0=> 0 clk <1=> 1 clk <2=> 2 clks <3=> 4 clks
+;// </h>
+;//
+;// <h> Bank 3
+;// <o8.12..13> DW: Data Bus Width
+;// <0=> 8-bit <1=> 16-bit <2=> 32-bit <3=> Rsrvd
+;// <o8.14> WS: WAIT Status
+;// <0=> WAIT Disable
+;// <1=> WAIT Enable
+;// <o8.15> ST: SRAM Type
+;// <0=> Not using UB/LB
+;// <1=> Using UB/LB
+;// <o3.0..1> PMC: Page Mode Configuration
+;// <0=> 1 Data <1=> 4 Data <2=> 8 Data <3=> 16 Data
+;// <o3.2..3> Tpac: Page Mode Access Cycle
+;// <0=> 2 clks <1=> 3 clks <2=> 4 clks <3=> 6 clks
+;// <o3.4..5> Tcah: Address Holding Time after nGCSn
+;// <0=> 0 clk <1=> 1 clk <2=> 2 clks <3=> 4 clks
+;// <o3.6..7> Toch: Chip Select Hold on nOE
+;// <0=> 0 clk <1=> 1 clk <2=> 2 clks <3=> 4 clks
+;// <o3.8..10> Tacc: Access Cycle
+;// <0=> 1 clk <1=> 2 clks <2=> 3 clks <3=> 4 clks
+;// <4=> 6 clk <5=> 8 clks <6=> 10 clks <7=> 14 clks
+;// <o3.11..12> Tcos: Chip Select Set-up nOE
+;// <0=> 0 clk <1=> 1 clk <2=> 2 clks <3=> 4 clks
+;// <o3.13..14> Tacs: Address Set-up before nGCSn
+;// <0=> 0 clk <1=> 1 clk <2=> 2 clks <3=> 4 clks
+;// </h>
+;//
+;// <h> Bank 4
+;// <o8.16..17> DW: Data Bus Width
+;// <0=> 8-bit <1=> 16-bit <2=> 32-bit <3=> Rsrvd
+;// <o8.18> WS: WAIT Status
+;// <0=> WAIT Disable
+;// <1=> WAIT Enable
+;// <o8.19> ST: SRAM Type
+;// <0=> Not using UB/LB
+;// <1=> Using UB/LB
+;// <o4.0..1> PMC: Page Mode Configuration
+;// <0=> 1 Data <1=> 4 Data <2=> 8 Data <3=> 16 Data
+;// <o4.2..3> Tpac: Page Mode Access Cycle
+;// <0=> 2 clks <1=> 3 clks <2=> 4 clks <3=> 6 clks
+;// <o4.4..5> Tcah: Address Holding Time after nGCSn
+;// <0=> 0 clk <1=> 1 clk <2=> 2 clks <3=> 4 clks
+;// <o4.6..7> Toch: Chip Select Hold on nOE
+;// <0=> 0 clk <1=> 1 clk <2=> 2 clks <3=> 4 clks
+;// <o4.8..10> Tacc: Access Cycle
+;// <0=> 1 clk <1=> 2 clks <2=> 3 clks <3=> 4 clks
+;// <4=> 6 clk <5=> 8 clks <6=> 10 clks <7=> 14 clks
+;// <o4.11..12> Tcos: Chip Select Set-up nOE
+;// <0=> 0 clk <1=> 1 clk <2=> 2 clks <3=> 4 clks
+;// <o4.13..14> Tacs: Address Set-up before nGCSn
+;// <0=> 0 clk <1=> 1 clk <2=> 2 clks <3=> 4 clks
+;// </h>
+;//
+;// <h> Bank 5
+;// <o8.20..21> DW: Data Bus Width
+;// <0=> 8-bit <1=> 16-bit <2=> 32-bit <3=> Rsrvd
+;// <o8.22> WS: WAIT Status
+;// <0=> WAIT Disable
+;// <1=> WAIT Enable
+;// <o8.23> ST: SRAM Type
+;// <0=> Not using UB/LB
+;// <1=> Using UB/LB
+;// <o5.0..1> PMC: Page Mode Configuration
+;// <0=> 1 Data <1=> 4 Data <2=> 8 Data <3=> 16 Data
+;// <o5.2..3> Tpac: Page Mode Access Cycle
+;// <0=> 2 clks <1=> 3 clks <2=> 4 clks <3=> 6 clks
+;// <o5.4..5> Tcah: Address Holding Time after nGCSn
+;// <0=> 0 clk <1=> 1 clk <2=> 2 clks <3=> 4 clks
+;// <o5.6..7> Toch: Chip Select Hold on nOE
+;// <0=> 0 clk <1=> 1 clk <2=> 2 clks <3=> 4 clks
+;// <o5.8..10> Tacc: Access Cycle
+;// <0=> 1 clk <1=> 2 clks <2=> 3 clks <3=> 4 clks
+;// <4=> 6 clk <5=> 8 clks <6=> 10 clks <7=> 14 clks
+;// <o5.11..12> Tcos: Chip Select Set-up nOE
+;// <0=> 0 clk <1=> 1 clk <2=> 2 clks <3=> 4 clks
+;// <o5.13..14> Tacs: Address Set-up before nGCSn
+;// <0=> 0 clk <1=> 1 clk <2=> 2 clks <3=> 4 clks
+;// </h>
+;//
+;// <h> Bank 6
+;// <o10.0..2> BK76MAP: Bank 6/7 Memory Map
+;// <0=> 32M <4=> 2M <5=> 4M <6=> 8M <7=> 16M
+;// <o8.24..25> DW: Data Bus Width
+;// <0=> 8-bit <1=> 16-bit <2=> 32-bit <3=> Rsrvd
+;// <o8.26> WS: WAIT Status
+;// <0=> WAIT Disable
+;// <1=> WAIT Enable
+;// <o8.27> ST: SRAM Type
+;// <0=> Not using UB/LB
+;// <1=> Using UB/LB
+;// <o6.15..16> MT: Memory Type
+;// <0=> ROM or SRAM
+;// <1=> FP DRAMP
+;// <2=> EDO DRAM
+;// <3=> SDRAM
+;// <h> ROM or SRAM
+;// <o6.0..1> PMC: Page Mode Configuration
+;// <0=> 1 Data <1=> 4 Data <2=> 8 Data <3=> 16 Data
+;// <o6.2..3> Tpac: Page Mode Access Cycle
+;// <0=> 2 clks <1=> 3 clks <2=> 4 clks <3=> 6 clks
+;// <o6.4..5> Tcah: Address Holding Time after nGCSn
+;// <0=> 0 clk <1=> 1 clk <2=> 2 clks <3=> 4 clks
+;// <o6.6..7> Toch: Chip Select Hold on nOE
+;// <0=> 0 clk <1=> 1 clk <2=> 2 clks <3=> 4 clks
+;// <o6.8..10> Tacc: Access Cycle
+;// <0=> 1 clk <1=> 2 clks <2=> 3 clks <3=> 4 clks
+;// <4=> 6 clk <5=> 8 clks <6=> 10 clks <7=> 14 clks
+;// <o6.11..12> Tcos: Chip Select Set-up nOE
+;// <0=> 0 clk <1=> 1 clk <2=> 2 clks <3=> 4 clks
+;// <o6.13..14> Tacs: Address Set-up before nGCSn
+;// <0=> 0 clk <1=> 1 clk <2=> 2 clks <3=> 4 clks
+;// </h>
+;// <h> FP DRAM or EDO DRAM
+;// <o6.0..1> CAN: Columnn Address Number
+;// <0=> 8-bit <1=> 9-bit <2=> 10-bit <3=> 11-bit
+;// <o6.2> Tcp: CAS Pre-charge
+;// <0=> 1 clk <1=> 2 clks
+;// <o6.3> Tcas: CAS Pulse Width
+;// <0=> 1 clk <1=> 2 clks
+;// <o6.4..5> Trcd: RAS to CAS Delay
+;// <0=> 1 clk <1=> 2 clks <2=> 3 clks <3=> 4 clks
+;// </h>
+;// <h> SDRAM
+;// <o6.0..1> SCAN: Columnn Address Number
+;// <0=> 8-bit <1=> 9-bit <2=> 10-bit <3=> Rsrvd
+;// <o6.2..3> Trcd: RAS to CAS Delay
+;// <0=> 2 clks <1=> 3 clks <2=> 4 clks <3=> Rsrvd
+;// <o10.4> SCLKEN: SCLK Selection (Bank 6/7)
+;// <0=> Normal
+;// <1=> Reduced Power
+;// <o11.0..2> BL: Burst Length
+;// <0=> 1
+;// <o11.3> BT: Burst Type
+;// <0=> Sequential
+;// <o11.4..6> CL: CAS Latency
+;// <0=> 1 clk <1=> 2 clks <2=> 3 clks
+;// <o11.7..8> TM: Test Mode
+;// <0=> Mode Register Set
+;// <o11.9> WBL: Write Burst Length
+;// <0=> 0
+;// </h>
+;// </h>
+;//
+;// <h> Bank 7
+;// <o10.0..2> BK76MAP: Bank 6/7 Memory Map
+;// <0=> 32M <4=> 2M <5=> 4M <6=> 8M <7=> 16M
+;// <o8.28..29> DW: Data Bus Width
+;// <0=> 8-bit <1=> 16-bit <2=> 32-bit <3=> Rsrvd
+;// <o8.30> WS: WAIT Status
+;// <0=> WAIT Disable
+;// <1=> WAIT Enable
+;// <o8.31> ST: SRAM Type
+;// <0=> Not using UB/LB
+;// <1=> Using UB/LB
+;// <o7.15..16> MT: Memory Type
+;// <0=> ROM or SRAM
+;// <1=> FP DRAMP
+;// <2=> EDO DRAM
+;// <3=> SDRAM
+;// <h> ROM or SRAM
+;// <o7.0..1> PMC: Page Mode Configuration
+;// <0=> 1 Data <1=> 4 Data <2=> 8 Data <3=> 16 Data
+;// <o7.2..3> Tpac: Page Mode Access Cycle
+;// <0=> 2 clks <1=> 3 clks <2=> 4 clks <3=> 6 clks
+;// <o7.4..5> Tcah: Address Holding Time after nGCSn
+;// <0=> 0 clk <1=> 1 clk <2=> 2 clks <3=> 4 clks
+;// <o7.6..7> Toch: Chip Select Hold on nOE
+;// <0=> 0 clk <1=> 1 clk <2=> 2 clks <3=> 4 clks
+;// <o7.8..10> Tacc: Access Cycle
+;// <0=> 1 clk <1=> 2 clks <2=> 3 clks <3=> 4 clks
+;// <4=> 6 clk <5=> 8 clks <6=> 10 clks <7=> 14 clks
+;// <o7.11..12> Tcos: Chip Select Set-up nOE
+;// <0=> 0 clk <1=> 1 clk <2=> 2 clks <3=> 4 clks
+;// <o7.13..14> Tacs: Address Set-up before nGCSn
+;// <0=> 0 clk <1=> 1 clk <2=> 2 clks <3=> 4 clks
+;// </h>
+;// <h> FP DRAM or EDO DRAM
+;// <o7.0..1> CAN: Columnn Address Number
+;// <0=> 8-bit <1=> 9-bit <2=> 10-bit <3=> 11-bit
+;// <o7.2> Tcp: CAS Pre-charge
+;// <0=> 1 clk <1=> 2 clks
+;// <o7.3> Tcas: CAS Pulse Width
+;// <0=> 1 clk <1=> 2 clks
+;// <o7.4..5> Trcd: RAS to CAS Delay
+;// <0=> 1 clk <1=> 2 clks <2=> 3 clks <3=> 4 clks
+;// </h>
+;// <h> SDRAM
+;// <o7.0..1> SCAN: Columnn Address Number
+;// <0=> 8-bit <1=> 9-bit <2=> 10-bit <3=> Rsrvd
+;// <o7.2..3> Trcd: RAS to CAS Delay
+;// <0=> 2 clks <1=> 3 clks <2=> 4 clks <3=> Rsrvd
+;// <o10.4> SCLKEN: SCLK Selection (Bank 6/7)
+;// <0=> Normal
+;// <1=> Reduced Power
+;// <o12.0..2> BL: Burst Length
+;// <0=> 1
+;// <o12.3> BT: Burst Type
+;// <0=> Sequential
+;// <o12.4..6> CL: CAS Latency
+;// <0=> 1 clk <1=> 2 clks <2=> 3 clks
+;// <o12.7..8> TM: Test Mode
+;// <0=> Mode Register Set
+;// <o12.9> WBL: Write Burst Length
+;// <0=> 0
+;// </h>
+;// </h>
+;//
+;// <h> Refresh
+;// <o9.23> REFEN: DRAM/SDRAM Refresh
+;// <0=> Disable <1=> Enable
+;// <o9.22> TREFMD: DRAM/SDRAM Refresh Mode
+;// <0=> CBR/Auto Refresh
+;// <1=> Self Refresh
+;// <o9.20..21> Trp: DRAM/SDRAM RAS Pre-charge Time
+;// <0=> 1.5 clks (DRAM) / 2 clks (SDRAM)
+;// <1=> 2.5 clks (DRAM) / 3 clks (SDRAM)
+;// <2=> 3.5 clks (DRAM) / 4 clks (SDRAM)
+;// <3=> 4.5 clks (DRAM) / Rsrvd (SDRAM)
+;// <o9.18..19> Trc: SDRAM RC Min Time
+;// <0=> 4 clks <1=> 5 clks <2=> 6 clks <3=> 7 clks
+;// <o9.16..17> Tchr: DRAM CAS Hold Time
+;// <0=> 1 clks <1=> 2 clks <2=> 3 clks <3=> 4 clks
+;// <o9.0..10> Refresh Counter <0x0-0x07FF>
+;// <i> Refresh Period = (2^11 - Refresh Count + 1) / MCLK
+;// </h>
+BANKCON0_Val EQU 0x00000700
+BANKCON1_Val EQU 0x00000700
+BANKCON2_Val EQU 0x00000700
+BANKCON3_Val EQU 0x00000700
+BANKCON4_Val EQU 0x00000700
+BANKCON5_Val EQU 0x00000700
+BANKCON6_Val EQU 0x00018008
+BANKCON7_Val EQU 0x00018008
+BWSCON_Val EQU 0x00000000
+REFRESH_Val EQU 0x00AC0000
+BANKSIZE_Val EQU 0x00000000
+MRSRB6_Val EQU 0x00000000
+MRSRB7_Val EQU 0x00000000
+
+;// </e> End of MC
+
+
+; I/O Ports definitions
+PIO_BASE EQU 0x01D20000 ; PIO Base Address
+PCONA_OFS EQU 0x00 ; PCONA Offset
+PCONB_OFS EQU 0x08 ; PCONB Offset
+PCONC_OFS EQU 0x10 ; PCONC Offset
+PCOND_OFS EQU 0x1C ; PCOND Offset
+PCONE_OFS EQU 0x28 ; PCONE Offset
+PCONF_OFS EQU 0x34 ; PCONF Offset
+PCONG_OFS EQU 0x40 ; PCONG Offset
+PUPC_OFS EQU 0x18 ; PUPC Offset
+PUPD_OFS EQU 0x24 ; PUPD Offset
+PUPE_OFS EQU 0x30 ; PUPE Offset
+PUPF_OFS EQU 0x3C ; PUPF Offset
+PUPG_OFS EQU 0x48 ; PUPG Offset
+SPUCR_OFS EQU 0x4C ; SPUCR Offset
+
+;// <e> I/O Configuration
+PIO_SETUP EQU 0
+
+;// <e> Port A
+;// <o1.0> PA0 <0=> Output <1=> ADDR0
+;// <o1.1> PA1 <0=> Output <1=> ADDR16
+;// <o1.2> PA2 <0=> Output <1=> ADDR17
+;// <o1.3> PA3 <0=> Output <1=> ADDR18
+;// <o1.4> PA4 <0=> Output <1=> ADDR19
+;// <o1.5> PA5 <0=> Output <1=> ADDR20
+;// <o1.6> PA6 <0=> Output <1=> ADDR21
+;// <o1.7> PA7 <0=> Output <1=> ADDR22
+;// <o1.8> PA8 <0=> Output <1=> ADDR23
+;// <o1.9> PA9 <0=> Output <1=> ADDR24
+;// </e>
+PIOA_SETUP EQU 1
+PCONA_Val EQU 0x000003FF
+
+;// <e> Port B
+;// <o1.0> PB0 <0=> Output <1=> SCKE
+;// <o1.1> PB1 <0=> Output <1=> CKLK
+;// <o1.2> PB2 <0=> Output <1=> nSCAS/nCAS2
+;// <o1.3> PB3 <0=> Output <1=> nSRAS/nCAS3
+;// <o1.4> PB4 <0=> Output <1=> nWBE2/nBE2/DQM2
+;// <o1.5> PB5 <0=> Output <1=> nWBE3/nBE3/DQM3
+;// <o1.6> PB6 <0=> Output <1=> nGCS1
+;// <o1.7> PB7 <0=> Output <1=> nGCS2
+;// <o1.8> PB8 <0=> Output <1=> nGCS3
+;// <o1.9> PB9 <0=> Output <1=> nGCS4
+;// <o1.10> PB10 <0=> Output <1=> nGCS5
+;// </e>
+PIOB_SETUP EQU 1
+PCONB_Val EQU 0x000007FF
+
+;// <e> Port C
+;// <o1.0..1> PC0 <0=> Input <1=> Output <2=> DATA16 <3=> IISLRCK
+;// <o1.2..3> PC1 <0=> Input <1=> Output <2=> DATA17 <3=> IISDO
+;// <o1.4..5> PC2 <0=> Input <1=> Output <2=> DATA18 <3=> IISDI
+;// <o1.6..7> PC3 <0=> Input <1=> Output <2=> DATA19 <3=> IISCLK
+;// <o1.8..9> PC4 <0=> Input <1=> Output <2=> DATA20 <3=> VD7
+;// <o1.10..11> PC5 <0=> Input <1=> Output <2=> DATA21 <3=> VD6
+;// <o1.12..13> PC6 <0=> Input <1=> Output <2=> DATA22 <3=> VD5
+;// <o1.14..15> PC7 <0=> Input <1=> Output <2=> DATA23 <3=> VD4
+;// <o1.16..17> PC8 <0=> Input <1=> Output <2=> DATA24 <3=> nXDACK1
+;// <o1.18..19> PC9 <0=> Input <1=> Output <2=> DATA25 <3=> nXDREQ1
+;// <o1.20..21> PC10 <0=> Input <1=> Output <2=> DATA26 <3=> nRTS1
+;// <o1.22..23> PC11 <0=> Input <1=> Output <2=> DATA27 <3=> nCTS1
+;// <o1.24..25> PC12 <0=> Input <1=> Output <2=> DATA28 <3=> TxD1
+;// <o1.26..27> PC13 <0=> Input <1=> Output <2=> DATA29 <3=> RxD1
+;// <o1.28..29> PC14 <0=> Input <1=> Output <2=> DATA30 <3=> nRTS0
+;// <o1.30..31> PC15 <0=> Input <1=> Output <2=> DATA31 <3=> nCTS0
+;// <h> Pull-up Resistors
+;// <o2.0> PC0 Pull-up <0=> Enabled <1=> Disabled
+;// <o2.1> PC1 Pull-up <0=> Enabled <1=> Disabled
+;// <o2.2> PC2 Pull-up <0=> Enabled <1=> Disabled
+;// <o2.3> PC3 Pull-up <0=> Enabled <1=> Disabled
+;// <o2.4> PC4 Pull-up <0=> Enabled <1=> Disabled
+;// <o2.5> PC5 Pull-up <0=> Enabled <1=> Disabled
+;// <o2.6> PC6 Pull-up <0=> Enabled <1=> Disabled
+;// <o2.7> PC7 Pull-up <0=> Enabled <1=> Disabled
+;// <o2.8> PC8 Pull-up <0=> Enabled <1=> Disabled
+;// <o2.9> PC9 Pull-up <0=> Enabled <1=> Disabled
+;// <o2.10> PC10 Pull-up <0=> Enabled <1=> Disabled
+;// <o2.11> PC11 Pull-up <0=> Enabled <1=> Disabled
+;// <o2.12> PC12 Pull-up <0=> Enabled <1=> Disabled
+;// <o2.13> PC13 Pull-up <0=> Enabled <1=> Disabled
+;// <o2.14> PC14 Pull-up <0=> Enabled <1=> Disabled
+;// <o2.15> PC15 Pull-up <0=> Enabled <1=> Disabled
+;// </h>
+;// </e>
+PIOC_SETUP EQU 1
+PCONC_Val EQU 0xAAAAAAAA
+PUPC_Val EQU 0x00000000
+
+;// <e> Port D
+;// <o1.0..1> PD0 <0=> Input <1=> Output <2=> VD0 <3=> Reserved
+;// <o1.2..3> PD1 <0=> Input <1=> Output <2=> VD1 <3=> Reserved
+;// <o1.4..5> PD2 <0=> Input <1=> Output <2=> VD2 <3=> Reserved
+;// <o1.6..7> PD3 <0=> Input <1=> Output <2=> VD3 <3=> Reserved
+;// <o1.8..9> PD4 <0=> Input <1=> Output <2=> VCLK <3=> Reserved
+;// <o1.10..11> PD5 <0=> Input <1=> Output <2=> VLINE <3=> Reserved
+;// <o1.12..13> PD6 <0=> Input <1=> Output <2=> VM <3=> Reserved
+;// <o1.14..15> PD7 <0=> Input <1=> Output <2=> VFRAME <3=> Reserved
+;// <h> Pull-up Resistors
+;// <o2.0> PD0 Pull-up <0=> Enabled <1=> Disabled
+;// <o2.1> PD1 Pull-up <0=> Enabled <1=> Disabled
+;// <o2.2> PD2 Pull-up <0=> Enabled <1=> Disabled
+;// <o2.3> PD3 Pull-up <0=> Enabled <1=> Disabled
+;// <o2.4> PD4 Pull-up <0=> Enabled <1=> Disabled
+;// <o2.5> PD5 Pull-up <0=> Enabled <1=> Disabled
+;// <o2.6> PD6 Pull-up <0=> Enabled <1=> Disabled
+;// <o2.7> PD7 Pull-up <0=> Enabled <1=> Disabled
+;// </h>
+;// </e>
+PIOD_SETUP EQU 1
+PCOND_Val EQU 0x00000000
+PUPD_Val EQU 0x00000000
+
+;// <e> Port E
+;// <o1.0..1> PE0 <0=> Input <1=> Output <2=> Fpllo <3=> Fout
+;// <o1.2..3> PE1 <0=> Input <1=> Output <2=> TxD0 <3=> Reserved
+;// <o1.4..5> PE2 <0=> Input <1=> Output <2=> RxD0 <3=> Reserved
+;// <o1.6..7> PE3 <0=> Input <1=> Output <2=> TOUT0 <3=> Reserved
+;// <o1.8..9> PE4 <0=> Input <1=> Output <2=> TOUT1 <3=> TCLK
+;// <o1.10..11> PE5 <0=> Input <1=> Output <2=> TOUT2 <3=> TCLK
+;// <o1.12..13> PE6 <0=> Input <1=> Output <2=> TOUT3 <3=> VD6
+;// <o1.14..15> PE7 <0=> Input <1=> Output <2=> TOUT4 <3=> VD7
+;// <o1.16..17> PE8 <0=> Input <1=> Output <2=> CODECLK <3=> Reserved
+;// <h> Pull-up Resistors
+;// <o2.0> PE0 Pull-up <0=> Enabled <1=> Disabled
+;// <o2.1> PE1 Pull-up <0=> Enabled <1=> Disabled
+;// <o2.2> PE2 Pull-up <0=> Enabled <1=> Disabled
+;// <o2.3> PE3 Pull-up <0=> Enabled <1=> Disabled
+;// <o2.4> PE4 Pull-up <0=> Enabled <1=> Disabled
+;// <o2.5> PE5 Pull-up <0=> Enabled <1=> Disabled
+;// <o2.6> PE6 Pull-up <0=> Enabled <1=> Disabled
+;// <o2.7> PE7 Pull-up <0=> Enabled <1=> Disabled
+;// <o2.8> PE8 Pull-up <0=> Enabled <1=> Disabled
+;// </h>
+;// </e>
+PIOE_SETUP EQU 1
+PCONE_Val EQU 0x00000000
+PUPE_Val EQU 0x00000000
+
+;// <e> Port F
+;// <o1.0..1> PF0 <0=> Input <1=> Output <2=> IICSCL <3=> Reserved
+;// <o1.2..3> PF1 <0=> Input <1=> Output <2=> IICSDA <3=> Reserved
+;// <o1.4..5> PF2 <0=> Input <1=> Output <2=> nWAIT <3=> Reserved
+;// <o1.6..7> PF3 <0=> Input <1=> Output <2=> nXBACK <3=> nXDACK0
+;// <o1.8..9> PF4 <0=> Input <1=> Output <2=> nXBREQ <3=> nXDREQ0
+;// <o1.10..12> PF5 <0=> Input <1=> Output <2=> nRTS1 <3=> SIOTxD
+;// <4=> IISLRCK <5=> Reserved <6=> Reserved <7=> Reserved
+;// <o1.13..15> PF6 <0=> Input <1=> Output <2=> TxD1 <3=> SIORDY
+;// <4=> IISDO <5=> Reserved <6=> Reserved <7=> Reserved
+;// <o1.16..18> PF7 <0=> Input <1=> Output <2=> RxD1 <3=> SIORxD
+;// <4=> IISDI <5=> Reserved <6=> Reserved <7=> Reserved
+;// <o1.19..21> PF8 <0=> Input <1=> Output <2=> nCTS1 <3=> SIOCLK
+;// <4=> IISCLK <5=> Reserved <6=> Reserved <7=> Reserved
+;// <h> Pull-up Resistors
+;// <o2.0> PF0 Pull-up <0=> Enabled <1=> Disabled
+;// <o2.1> PF1 Pull-up <0=> Enabled <1=> Disabled
+;// <o2.2> PF2 Pull-up <0=> Enabled <1=> Disabled
+;// <o2.3> PF3 Pull-up <0=> Enabled <1=> Disabled
+;// <o2.4> PF4 Pull-up <0=> Enabled <1=> Disabled
+;// <o2.5> PF5 Pull-up <0=> Enabled <1=> Disabled
+;// <o2.6> PF6 Pull-up <0=> Enabled <1=> Disabled
+;// <o2.7> PF7 Pull-up <0=> Enabled <1=> Disabled
+;// <o2.8> PF8 Pull-up <0=> Enabled <1=> Disabled
+;// </h>
+;// </e>
+PIOF_SETUP EQU 1
+PCONF_Val EQU 0x00000000
+PUPF_Val EQU 0x00000000
+
+;// <e> Port G
+;// <o1.0..1> PG0 <0=> Input <1=> Output <2=> VD4 <3=> EINT0
+;// <o1.2..3> PG1 <0=> Input <1=> Output <2=> VD5 <3=> EINT1
+;// <o1.4..5> PG2 <0=> Input <1=> Output <2=> nCTS0 <3=> EINT2
+;// <o1.6..7> PG3 <0=> Input <1=> Output <2=> nRTS0 <3=> EINT3
+;// <o1.8..9> PG4 <0=> Input <1=> Output <2=> IISCLK <3=> EINT4
+;// <o1.10..11> PG5 <0=> Input <1=> Output <2=> IISDI <3=> EINT5
+;// <o1.12..13> PG6 <0=> Input <1=> Output <2=> IISDO <3=> EINT6
+;// <o1.14..15> PG7 <0=> Input <1=> Output <2=> IISLRCK <3=> EINT7
+;// <h> Pull-up Resistors
+;// <o2.0> PG0 Pull-up <0=> Enabled <1=> Disabled
+;// <o2.1> PG1 Pull-up <0=> Enabled <1=> Disabled
+;// <o2.2> PG2 Pull-up <0=> Enabled <1=> Disabled
+;// <o2.3> PG3 Pull-up <0=> Enabled <1=> Disabled
+;// <o2.4> PG4 Pull-up <0=> Enabled <1=> Disabled
+;// <o2.5> PG5 Pull-up <0=> Enabled <1=> Disabled
+;// <o2.6> PG6 Pull-up <0=> Enabled <1=> Disabled
+;// <o2.7> PG7 Pull-up <0=> Enabled <1=> Disabled
+;// </h>
+;// </e>
+PIOG_SETUP EQU 1
+PCONG_Val EQU 0x00000000
+PUPG_Val EQU 0x00000000
+
+;// <e> Special Pull-up
+;// <o1.0> SPUCR0: DATA[7:0] Pull-up Resistor
+;// <0=> Enabled <1=> Disabled
+;// <o1.1> SPUCR1: DATA[15:8] Pull-up Resistor
+;// <0=> Enabled <1=> Disabled
+;// <o1.2> HZ@STOP
+;// <0=> Prevoius state of PAD
+;// <1=> HZ @ Stop
+;// </e>
+PSPU_SETUP EQU 1
+SPUCR_Val EQU 0x00000004
+
+;// </e>
+
+
+ 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
+
+
+; CPU Wrapper and Bus Priorities Configuration
+ IF SYS_SETUP <> 0
+SYS_CFG
+ DCD CPUW_BASE
+ DCD BUSP_BASE
+ DCD SYSCFG_Val
+ DCD NCACHBE0_Val
+ DCD NCACHBE1_Val
+ DCD SBUSCON_Val
+ ENDIF
+
+
+; Memory Controller Configuration
+ IF MC_SETUP <> 0
+MC_CFG
+ DCD BWSCON_Val
+ DCD BANKCON0_Val
+ DCD BANKCON1_Val
+ DCD BANKCON2_Val
+ DCD BANKCON3_Val
+ DCD BANKCON4_Val
+ DCD BANKCON5_Val
+ DCD BANKCON6_Val
+ DCD BANKCON7_Val
+ DCD REFRESH_Val
+ DCD BANKSIZE_Val
+ DCD MRSRB6_Val
+ DCD MRSRB7_Val
+ ENDIF
+
+
+; Clock Management Configuration
+ IF CLK_SETUP <> 0
+CLK_CFG
+ DCD CLK_BASE
+ DCD PLLCON_Val
+ DCD CLKCON_Val
+ DCD CLKSLOW_Val
+ DCD LOCKTIME_Val
+ ENDIF
+
+
+; I/O Configuration
+ IF PIO_SETUP <> 0
+PIO_CFG
+ DCD PCONA_Val
+ DCD PCONB_Val
+ DCD PCONC_Val
+ DCD PCOND_Val
+ DCD PCONE_Val
+ DCD PCONF_Val
+ DCD PCONG_Val
+ DCD PUPC_Val
+ DCD PUPD_Val
+ DCD PUPE_Val
+ DCD PUPF_Val
+ DCD PUPG_Val
+ DCD SPUCR_Val
+ ENDIF
+
+
+; Reset Handler
+
+ EXPORT Reset_Handler
+Reset_Handler
+
+
+ IF SYS_SETUP <> 0
+ ADR R8, SYS_CFG
+ LDMIA R8, {R0-R5}
+ STMIA R0, {R2-R4}
+ STR R5, [R1]
+ ENDIF
+
+
+ IF MC_SETUP <> 0
+ ADR R14, MC_CFG
+ LDMIA R14, {R0-R12}
+ LDR R14, =MC_BASE
+ STMIA R14, {R0-R12}
+ ENDIF
+
+
+ IF CLK_SETUP <> 0
+ ADR R8, CLK_CFG
+ LDMIA R8, {R0-R4}
+ STR R4, [R0, #LOCKTIME_OFS]
+ STR R1, [R0, #PLLCON_OFS]
+ STR R3, [R0, #CLKSLOW_OFS]
+ STR R2, [R0, #CLKCON_OFS]
+ ENDIF
+
+
+ IF WT_SETUP <> 0
+ LDR R0, =WT_BASE
+ LDR R1, =WTCON_Val
+ LDR R2, =WTDAT_Val
+ STR R2, [R0, #WTCNT_OFS]
+ STR R2, [R0, #WTDAT_OFS]
+ STR R1, [R0, #WTCON_OFS]
+ ENDIF
+
+
+ IF PIO_SETUP <> 0
+ ADR R14, PIO_CFG
+ LDMIA R14, {R0-R12}
+ LDR R14, =PIO_BASE
+
+ IF PIOA_SETUP <> 0
+ STR R0, [R14, #PCONA_OFS]
+ ENDIF
+
+ IF PIOB_SETUP <> 0
+ STR R1, [R14, #PCONB_OFS]
+ ENDIF
+
+ IF PIOC_SETUP <> 0
+ STR R2, [R14, #PCONC_OFS]
+ STR R7, [R14, #PUPC_OFS]
+ ENDIF
+
+ IF PIOD_SETUP <> 0
+ STR R3, [R14, #PCOND_OFS]
+ STR R8, [R14, #PUPD_OFS]
+ ENDIF
+
+ IF PIOE_SETUP <> 0
+ STR R4, [R14, #PCONE_OFS]
+ STR R9, [R14, #PUPE_OFS]
+ ENDIF
+
+ IF PIOF_SETUP <> 0
+ STR R5, [R14, #PCONF_OFS]
+ STR R10,[R14, #PUPF_OFS]
+ ENDIF
+
+ IF PIOG_SETUP <> 0
+ STR R6, [R14, #PCONG_OFS]
+ STR R11,[R14, #PUPG_OFS]
+ ENDIF
+
+ IF PSPU_SETUP <> 0
+ STR R12,[R14, #SPUCR_OFS]
+ ENDIF
+
+ ENDIF
+
+
+; 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
+ ; 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_interrput_flag
+ IMPORT rt_interrupt_from_thread
+ IMPORT rt_interrupt_to_thread
+ IMPORT rt_hw_trap_irq
+
+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_interrput_flag set, jump to
+ ; rt_hw_context_switch_interrupt_do and don't return
+ LDR r0, =rt_thread_switch_interrput_flag
+ LDR r1, [r0]
+ CMP r1, #1
+ BEQ rt_hw_context_switch_interrupt_do
+
+ LDMFD sp!, {r0-r12,lr}
+ SUBS pc, lr, #4
+ 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|F_Bit|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
+ MRS r4, spsr
+ STMFD sp!, {r4} ; push old task's spsr
+
+ 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 spsr
+ MSR spsr_cxsf, r4
+ LDMFD sp!, {r4} ; pop new task's psr
+ MSR cpsr_cxsf, r4
+
+ LDMFD sp!, {r0-r12,lr,pc} ; pop new task's r0-r12,lr & pc
+ 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
diff --git a/libcpu/arm/s3c44b0/trap.c b/libcpu/arm/s3c44b0/trap.c
new file mode 100644
index 0000000000..546d9b2ea0
--- /dev/null
+++ b/libcpu/arm/s3c44b0/trap.c
@@ -0,0 +1,181 @@
+/*
+ * File : trap.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2006-09-06 XuXinming first version
+ * 2006-09-15 Bernard modify rt_hw_trap_irq for more effective
+ */
+
+#include <rtthread.h>
+#include <rthw.h>
+
+#include "s3c44b0.h"
+
+extern unsigned char interrupt_bank0[256];
+extern unsigned char interrupt_bank1[256];
+extern unsigned char interrupt_bank2[256];
+extern unsigned char interrupt_bank3[256];
+
+extern struct rt_thread *rt_current_thread;
+
+/**
+ * @addtogroup S3C44B0
+ */
+/*@{*/
+
+/**
+ * this function will show registers of CPU
+ *
+ * @param regs the registers point
+ */
+void rt_hw_show_register (struct rt_hw_register *regs)
+{
+ rt_kprintf("Execption:\n");
+ rt_kprintf("r00:0x%08x r01:0x%08x r02:0x%08x r03:0x%08x\n", regs->r0, regs->r1, regs->r2, regs->r3);
+ rt_kprintf("r04:0x%08x r05:0x%08x r06:0x%08x r07:0x%08x\n", regs->r4, regs->r5, regs->r6, regs->r7);
+ rt_kprintf("r08:0x%08x r09:0x%08x r10:0x%08x\n", regs->r8, regs->r9, regs->r10);
+ rt_kprintf("fp :0x%08x ip :0x%08x\n", regs->fp, regs->ip);
+ rt_kprintf("sp :0x%08x lr :0x%08x pc :0x%08x\n", regs->sp, regs->lr, regs->pc);
+ rt_kprintf("cpsr:0x%08x\n", regs->cpsr);
+}
+
+/**
+ * When ARM7TDMI comes across an instruction which it cannot handle,
+ * it takes the undefined instruction trap.
+ *
+ * @param regs system registers
+ *
+ * @note never invoke this function in application
+ */
+void rt_hw_trap_udef(struct rt_hw_register *regs)
+{
+ rt_hw_show_register(regs);
+
+ rt_kprintf("undefined instruction\n");
+ rt_hw_cpu_shutdown();
+}
+
+/**
+ * The software interrupt instruction (SWI) is used for entering
+ * Supervisor mode, usually to request a particular supervisor
+ * function.
+ *
+ * @param regs system registers
+ *
+ * @note never invoke this function in application
+ */
+void rt_hw_trap_swi(struct rt_hw_register *regs)
+{
+ rt_kprintf("software interrupt\n");
+ rt_hw_show_register(regs);
+ rt_hw_cpu_shutdown();
+}
+
+/**
+ * An abort indicates that the current memory access cannot be completed,
+ * which occurs during an instruction prefetch.
+ *
+ * @param regs system registers
+ *
+ * @note never invoke this function in application
+ */
+void rt_hw_trap_pabt(struct rt_hw_register *regs)
+{
+ rt_hw_show_register(regs);
+
+ rt_kprintf("prefetch abort\n");
+ rt_hw_cpu_shutdown();
+}
+
+/**
+ * An abort indicates that the current memory access cannot be completed,
+ * which occurs during a data access.
+ *
+ * @param regs system registers
+ *
+ * @note never invoke this function in application
+ */
+void rt_hw_trap_dabt(struct rt_hw_register *regs)
+{
+ rt_hw_show_register(regs);
+
+ rt_kprintf("data abort\n");
+ rt_hw_cpu_shutdown();
+}
+
+/**
+ * Normally, system will never reach here
+ *
+ * @param regs system registers
+ *
+ * @note never invoke this function in application
+ */
+void rt_hw_trap_resv(struct rt_hw_register *regs)
+{
+ rt_kprintf("not used\n");
+ rt_hw_show_register(regs);
+ rt_hw_cpu_shutdown();
+}
+
+extern rt_isr_handler_t isr_table[];
+void rt_hw_trap_irq()
+{
+ register unsigned long ispr, intstat;
+ register rt_isr_handler_t isr_func;
+
+#ifdef BSP_INT_DEBUG
+ rt_kprintf("irq coming, ");
+#endif
+ intstat = I_ISPR & 0x7ffffff;
+#ifdef BSP_INT_DEBUG
+ rt_kprintf("I_ISPR: %d\n", intstat);
+#endif
+
+ ispr = intstat;
+
+ /* to find interrupt */
+ if ( intstat & 0xff ) /* lowest 8bits */
+ {
+ intstat = interrupt_bank0[intstat & 0xff];
+ isr_func = (rt_isr_handler_t)isr_table[ intstat ];
+ }
+ else if ( intstat & 0xff00 ) /* low 8bits */
+ {
+ intstat = interrupt_bank1[(intstat & 0xff00) >> 8];
+ isr_func = (rt_isr_handler_t)isr_table[ intstat ];
+ }
+ else if ( intstat & 0xff0000 ) /* high 8bits */
+ {
+ intstat = interrupt_bank2[(intstat & 0xff0000) >> 16];
+ isr_func = (rt_isr_handler_t)isr_table[ intstat ];
+ }
+ else if ( intstat & 0xff000000 ) /* highest 8bits */
+ {
+ intstat = interrupt_bank3[(intstat & 0xff000000) >> 24];
+ isr_func = (rt_isr_handler_t)isr_table[ intstat ];
+ }
+ else return;
+
+#ifdef BSP_INT_DEBUG
+ rt_kprintf("irq: %d happen\n", intstat);
+#endif
+
+ /* turn to interrupt service routine */
+ isr_func(intstat);
+
+ I_ISPC = ispr; /* clear interrupt */
+}
+
+void rt_hw_trap_fiq()
+{
+ rt_kprintf("fast interrupt request\n");
+}
+
+/*@}*/