diff options
| author | bernard.xiong <[email protected]> | 2009-07-02 23:18:14 +0000 |
|---|---|---|
| committer | bernard.xiong <[email protected]> | 2009-07-02 23:18:14 +0000 |
| commit | 99922cdf19851bf89989d997ae4a0c02f6eed523 (patch) | |
| tree | 74e90bf61ad6edf7586f7e9193f5496a1a986423 /libcpu | |
| parent | 1d74273319cd82ebd3b569f40b38fdd33cef2de7 (diff) | |
import lm3s, lpc2148/lpc2478, x86/qemu, AT91SAM7S/7X, s3c44b0, STM32F103ZE bsp
git-svn-id: https://rt-thread.googlecode.com/svn/trunk@4 bbd45198-f89e-11dd-88c7-29a3b14d5316
Diffstat (limited to 'libcpu')
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"); +} + +/*@}*/ |
