diff --git a/libcpu/arm/AT91SAM7S/AT91SAM7S.h b/libcpu/arm/AT91SAM7S/AT91SAM7S.h new file mode 100644 index 0000000000000000000000000000000000000000..3f0fef709775f7cf78df5768d353ae1d427f1a4b --- /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 0000000000000000000000000000000000000000..e18dcfa6eaa02f668ecca67b6abf9dd781729e8f --- /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 0000000000000000000000000000000000000000..82c5adc574304888b47f94c4007090505ced887f --- /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 0000000000000000000000000000000000000000..57db2b7d24b0949645cd95651254805171326d52 --- /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 +#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 0000000000000000000000000000000000000000..b8ef0c051cc4df06e13fcfc8b2ef81bd866ce74a --- /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 +#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 0000000000000000000000000000000000000000..307d713ed2740037e59032de7792e568c5575b89 --- /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 +#include + +#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 0000000000000000000000000000000000000000..5fe0928c9a9669c4e077c1c34c8b412d8487453d --- /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 0000000000000000000000000000000000000000..b0dc78db2c9b4f7f37da46eaace7202d752110b4 --- /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 +#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 0000000000000000000000000000000000000000..bcfbc261cab49474e9c73ceac8da93e86cbc1d02 --- /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 0000000000000000000000000000000000000000..1dd4dd61a086cb019226b710e1a940ca80a7d89e --- /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 + + +;// Stack Configuration (Stack Sizes in Bytes) +;// Undefined Mode <0x0-0xFFFFFFFF:8> +;// Supervisor Mode <0x0-0xFFFFFFFF:8> +;// Abort Mode <0x0-0xFFFFFFFF:8> +;// Fast Interrupt Mode <0x0-0xFFFFFFFF:8> +;// Interrupt Mode <0x0-0xFFFFFFFF:8> +;// User/System Mode <0x0-0xFFFFFFFF:8> +;// + +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 + + +;// Heap Configuration +;// Heap Size (in Bytes) <0x0-0xFFFFFFFF> +;// + +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 + +;/* +;// Reset Controller (RSTC) +;// URSTEN: User Reset Enable +;// Enables NRST Pin to generate Reset +;// ERSTL: External Reset Length <0-15> +;// External Reset Time in 2^(ERSTL+1) Slow Clock Cycles +;// +;*/ +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 + +;// Embedded Flash Controller 0 (EFC0) +;// FMCN: Flash Microsecond Cycle Number <0-255> +;// Number of Master Clock Cycles in 1us +;// 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 +;// +EFC0_SETUP EQU 1 +EFC0_FMR_Val EQU 0x00320100 + +;// Embedded Flash Controller 1 (EFC1) +;// FMCN: Flash Microsecond Cycle Number <0-255> +;// Number of Master Clock Cycles in 1us +;// 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 +;// +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 + +;// Watchdog Timer (WDT) +;// WDV: Watchdog Counter Value <0-4095> +;// WDD: Watchdog Delta Value <0-4095> +;// WDFIEN: Watchdog Fault Interrupt Enable +;// WDRSTEN: Watchdog Reset Enable +;// WDRPROC: Watchdog Reset Processor +;// WDDBGHLT: Watchdog Debug Halt +;// WDIDLEHLT: Watchdog Idle Halt +;// WDDIS: Watchdog Disable +;// +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 + +;// Power Mangement Controller (PMC) +;// Main Oscillator +;// MOSCEN: Main Oscillator Enable +;// OSCBYPASS: Oscillator Bypass +;// OSCCOUNT: Main Oscillator Startup Time <0-255> +;// +;// Phase Locked Loop (PLL) +;// DIV: PLL Divider <0-255> +;// MUL: PLL Multiplier <0-2047> +;// PLL Output is multiplied by MUL+1 +;// OUT: PLL Clock Frequency Range +;// <0=> 80..160MHz <1=> Reserved +;// <2=> 150..220MHz <3=> Reserved +;// PLLCOUNT: PLL Lock Counter <0-63> +;// USBDIV: USB Clock Divider +;// <0=> None <1=> 2 <2=> 4 <3=> Reserved +;// +;// CSS: Clock Source Selection +;// <0=> Slow Clock +;// <1=> Main Clock +;// <2=> Reserved +;// <3=> PLL Clock +;// PRES: Prescaler +;// <0=> None +;// <1=> Clock / 2 <2=> Clock / 4 +;// <3=> Clock / 8 <4=> Clock / 16 +;// <5=> Clock / 32 <6=> Clock / 64 +;// <7=> Reserved +;// +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 0000000000000000000000000000000000000000..18534cda8be3991d7478009c048c050d96497160 --- /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 +#include + +#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 0000000000000000000000000000000000000000..54a7d11c46b4ec4e7e9d6f050d66aa2ffc67335f --- /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 0000000000000000000000000000000000000000..83e9f057558bf774f24e0e9b4f953c864be45055 --- /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 0000000000000000000000000000000000000000..82c5adc574304888b47f94c4007090505ced887f --- /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 0000000000000000000000000000000000000000..679fddc45491978d141ce55e22a3f9ce6ed0f5cc --- /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 +#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 0000000000000000000000000000000000000000..014451a1ff7ddf28e402ce29ef67f78fb5f261e2 --- /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 +#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 0000000000000000000000000000000000000000..4ec25667a36211c8e83cecb184d3e7208b62eabd --- /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 . +*/ + +/* + * Parts of this file are borrowed by the Linux include file linux/mii.h: + * Copyright (C) 1996, 1999, 2001 David S. Miller (davem@redhat.com) + */ + +#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 0000000000000000000000000000000000000000..39fa8e5906fdd220ec504bed0a598527002ebe95 --- /dev/null +++ b/libcpu/arm/AT91SAM7X/sam7x_emac.c @@ -0,0 +1,554 @@ +#include +#include +#include + +#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 0000000000000000000000000000000000000000..49d156f94b7051c0e9deb05ee1153032865b5785 --- /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 0000000000000000000000000000000000000000..68fcfb392dbf2f1c891f7578d78f9cb79f95b3cb --- /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 +#include + +#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 0000000000000000000000000000000000000000..5fe0928c9a9669c4e077c1c34c8b412d8487453d --- /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 0000000000000000000000000000000000000000..4f3b2c397628c3b75a8e5f4688f8ddaa55d209c2 --- /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 +#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 0000000000000000000000000000000000000000..e7712eb436e7c2ab284c1f009c3c89969fe18a57 --- /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 0000000000000000000000000000000000000000..c0f960d2fcf3b776b7ffc8705e013ec9594a5947 --- /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 + + +;// Stack Configuration (Stack Sizes in Bytes) +;// Undefined Mode <0x0-0xFFFFFFFF:8> +;// Supervisor Mode <0x0-0xFFFFFFFF:8> +;// Abort Mode <0x0-0xFFFFFFFF:8> +;// Fast Interrupt Mode <0x0-0xFFFFFFFF:8> +;// Interrupt Mode <0x0-0xFFFFFFFF:8> +;// User/System Mode <0x0-0xFFFFFFFF:8> +;// + +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 + + +;// Heap Configuration +;// Heap Size (in Bytes) <0x0-0xFFFFFFFF> +;// + +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 + +;/* +;// Reset Controller (RSTC) +;// URSTEN: User Reset Enable +;// Enables NRST Pin to generate Reset +;// ERSTL: External Reset Length <0-15> +;// External Reset Time in 2^(ERSTL+1) Slow Clock Cycles +;// +;*/ +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 + +;// Embedded Flash Controller 0 (EFC0) +;// FMCN: Flash Microsecond Cycle Number <0-255> +;// Number of Master Clock Cycles in 1us +;// 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 +;// +EFC0_SETUP EQU 1 +EFC0_FMR_Val EQU 0x00320100 + +;// Embedded Flash Controller 1 (EFC1) +;// FMCN: Flash Microsecond Cycle Number <0-255> +;// Number of Master Clock Cycles in 1us +;// 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 +;// +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 + +;// Watchdog Timer (WDT) +;// WDV: Watchdog Counter Value <0-4095> +;// WDD: Watchdog Delta Value <0-4095> +;// WDFIEN: Watchdog Fault Interrupt Enable +;// WDRSTEN: Watchdog Reset Enable +;// WDRPROC: Watchdog Reset Processor +;// WDDBGHLT: Watchdog Debug Halt +;// WDIDLEHLT: Watchdog Idle Halt +;// WDDIS: Watchdog Disable +;// +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 + +;// Power Mangement Controller (PMC) +;// Main Oscillator +;// MOSCEN: Main Oscillator Enable +;// OSCBYPASS: Oscillator Bypass +;// OSCCOUNT: Main Oscillator Startup Time <0-255> +;// +;// Phase Locked Loop (PLL) +;// DIV: PLL Divider <0-255> +;// MUL: PLL Multiplier <0-2047> +;// PLL Output is multiplied by MUL+1 +;// OUT: PLL Clock Frequency Range +;// <0=> 80..160MHz <1=> Reserved +;// <2=> 150..220MHz <3=> Reserved +;// PLLCOUNT: PLL Lock Counter <0-63> +;// USBDIV: USB Clock Divider +;// <0=> None <1=> 2 <2=> 4 <3=> Reserved +;// +;// CSS: Clock Source Selection +;// <0=> Slow Clock +;// <1=> Main Clock +;// <2=> Reserved +;// <3=> PLL Clock +;// PRES: Prescaler +;// <0=> None +;// <1=> Clock / 2 <2=> Clock / 4 +;// <3=> Clock / 8 <4=> Clock / 16 +;// <5=> Clock / 32 <6=> Clock / 64 +;// <7=> Reserved +;// +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 0000000000000000000000000000000000000000..62346cb32ded59fea5517ef48eb9588030f0f659 --- /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 +#include + +#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 0000000000000000000000000000000000000000..59a4d0bf79e48e61e3e0fa30380252e962cc1631 --- /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 + +#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 0000000000000000000000000000000000000000..128a1eb859c26e1a299805a5a0dfd84df1047ebd --- /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 0000000000000000000000000000000000000000..01eac6aabf2efcaf23515d23a8a24e953d69817d --- /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 0000000000000000000000000000000000000000..c171a9bcd75b9206d3fa2949ddb021d5cccd7b3f --- /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 + +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 0000000000000000000000000000000000000000..9f2eb7577a257fbfd5c515907195a3d08dbfe8cf --- /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 0000000000000000000000000000000000000000..080634c2b9a57fdc02376072feac42c01a4638af --- /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 + +/** + * @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 0000000000000000000000000000000000000000..a57656c7fb7054132729043f97ab42d7d52db8bd --- /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 + +#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 0000000000000000000000000000000000000000..a87d84a90e64b0a90024ea78d9779c7fd8fbbfdb --- /dev/null +++ b/libcpu/arm/lm3s/kservice.c @@ -0,0 +1,42 @@ +#include + +#include +#include + +/* + * 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 0000000000000000000000000000000000000000..79cb0ff4b4bab25786638afddba78e304dbf5f2c --- /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 +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#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 0000000000000000000000000000000000000000..c7f8c71ab4076e74eed5ce0638f91f4faad1e2ed --- /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 + +/** + * @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 0000000000000000000000000000000000000000..ad5295faab647d1a8681c43a223d947e67449921 --- /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. +; +;****************************************************************************** + +;****************************************************************************** +; +; Stack Size (in Bytes) <0x0-0xFFFFFFFF:8> +; +;****************************************************************************** +Stack EQU 0x00000100 + +;****************************************************************************** +; +; 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 0000000000000000000000000000000000000000..ddf655a4839f0c229d00e0bd3e6351485b1e78f3 --- /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 0000000000000000000000000000000000000000..3a77976073beadc7bdc4972fefca15c0f87c50f3 --- /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 0000000000000000000000000000000000000000..82c5adc574304888b47f94c4007090505ced887f --- /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 0000000000000000000000000000000000000000..5e228171f52e0dea69841ef290273e57b66096de --- /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 +#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 0000000000000000000000000000000000000000..3c4e78e855119f345cea44464620d363bb9c0223 --- /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 +#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 0000000000000000000000000000000000000000..4bfa7614e929cbb566c3e5e623173d71961810bd --- /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 +#include + +#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 0000000000000000000000000000000000000000..177545f374dc4d5cbb1f75ceca7bcdbd5ef90ebb --- /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 + +#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 0000000000000000000000000000000000000000..9d603a4709c6c2b367b80df7b976907c1be5b576 --- /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 + + +;// Stack Configuration (Stack Sizes in Bytes) +;// Undefined Mode <0x0-0xFFFFFFFF:8> +;// Supervisor Mode <0x0-0xFFFFFFFF:8> +;// Abort Mode <0x0-0xFFFFFFFF:8> +;// Fast Interrupt Mode <0x0-0xFFFFFFFF:8> +;// Interrupt Mode <0x0-0xFFFFFFFF:8> +;// User/System Mode <0x0-0xFFFFFFFF:8> +;// + +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 + + +;// Heap Configuration +;// Heap Size (in Bytes) <0x0-0xFFFFFFFF> +;// + +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 + +;// VPBDIV Setup +;// Peripheral Bus Clock Rate +;// VPBDIV: VPB Clock +;// <0=> VPB Clock = CPU Clock / 4 +;// <1=> VPB Clock = CPU Clock +;// <2=> VPB Clock = CPU Clock / 2 +;// XCLKDIV: XCLK Pin +;// <0=> XCLK Pin = CPU Clock / 4 +;// <1=> XCLK Pin = CPU Clock +;// <2=> XCLK Pin = CPU Clock / 2 +;// +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 + +;// PLL Setup +;// MSEL: PLL Multiplier Selection +;// <1-32><#-1> +;// M Value +;// PSEL: PLL Divider Selection +;// <0=> 1 <1=> 2 <2=> 4 <3=> 8 +;// P Value +;// +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 + +;// MAM Setup +;// MAM Control +;// <0=> Disabled +;// <1=> Partially Enabled +;// <2=> Fully Enabled +;// Mode +;// MAM Timing +;// <0=> Reserved <1=> 1 <2=> 2 <3=> 3 +;// <4=> 4 <5=> 5 <6=> 6 <7=> 7 +;// Fetch Cycles +;// +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 + +;// External Memory Controller (EMC) +EMC_SETUP EQU 0 + +;// Bank Configuration 0 (BCFG0) +;// IDCY: Idle Cycles <0-15> +;// WST1: Wait States 1 <0-31> +;// WST2: Wait States 2 <0-31> +;// RBLE: Read Byte Lane Enable +;// WP: Write Protect +;// BM: Burst ROM +;// MW: Memory Width <0=> 8-bit <1=> 16-bit +;// <2=> 32-bit <3=> Reserved +;// +BCFG0_SETUP EQU 0 +BCFG0_Val EQU 0x0000FBEF + +;// Bank Configuration 1 (BCFG1) +;// IDCY: Idle Cycles <0-15> +;// WST1: Wait States 1 <0-31> +;// WST2: Wait States 2 <0-31> +;// RBLE: Read Byte Lane Enable +;// WP: Write Protect +;// BM: Burst ROM +;// MW: Memory Width <0=> 8-bit <1=> 16-bit +;// <2=> 32-bit <3=> Reserved +;// +BCFG1_SETUP EQU 0 +BCFG1_Val EQU 0x0000FBEF + +;// Bank Configuration 2 (BCFG2) +;// IDCY: Idle Cycles <0-15> +;// WST1: Wait States 1 <0-31> +;// WST2: Wait States 2 <0-31> +;// RBLE: Read Byte Lane Enable +;// WP: Write Protect +;// BM: Burst ROM +;// MW: Memory Width <0=> 8-bit <1=> 16-bit +;// <2=> 32-bit <3=> Reserved +;// +BCFG2_SETUP EQU 0 +BCFG2_Val EQU 0x0000FBEF + +;// Bank Configuration 3 (BCFG3) +;// IDCY: Idle Cycles <0-15> +;// WST1: Wait States 1 <0-31> +;// WST2: Wait States 2 <0-31> +;// RBLE: Read Byte Lane Enable +;// WP: Write Protect +;// BM: Burst ROM +;// MW: Memory Width <0=> 8-bit <1=> 16-bit +;// <2=> 32-bit <3=> Reserved +;// +BCFG3_SETUP EQU 0 +BCFG3_Val EQU 0x0000FBEF + +;// 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 0000000000000000000000000000000000000000..f14bec39aec6fc61f7e4fbea96f0154645e7b2d5 --- /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 0000000000000000000000000000000000000000..e0237e8b259f40c2a979ebc48b411766a3f25949 --- /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 +#include +#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 0000000000000000000000000000000000000000..01cbeec6696b7ab7be1dea284dc90b145f78b7a6 --- /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 0000000000000000000000000000000000000000..c83ac53dfc399fb3fce33edd467d777ad45bd391 --- /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 0000000000000000000000000000000000000000..82c5adc574304888b47f94c4007090505ced887f --- /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 0000000000000000000000000000000000000000..0265ed96aa7ccdfb1c8fc4c94f03ba0e5922476c --- /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 +#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 0000000000000000000000000000000000000000..0b573d57e71cfeafa3ad5b73685cdde2b71a565a --- /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 +#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 0000000000000000000000000000000000000000..d3960a5e000a0e0709a1acf66eeb2f01ac3b5560 --- /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 +#include +#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 0000000000000000000000000000000000000000..bfd4bc652cdd6efd0ccbc4981dff460947d5b859 --- /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 +#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 0000000000000000000000000000000000000000..bd473bc0cdc30fb3be9bb115995ec82066040a0c --- /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 0000000000000000000000000000000000000000..a5b9de7d478874dc69848874a83be40bb8324dd7 --- /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 ---------------------------- + +;// Stack Configuration (Stack Sizes in Bytes) +;// Undefined Mode <0x0-0xFFFFFFFF:8> +;// Supervisor Mode <0x0-0xFFFFFFFF:8> +;// Abort Mode <0x0-0xFFFFFFFF:8> +;// Fast Interrupt Mode <0x0-0xFFFFFFFF:8> +;// Interrupt Mode <0x0-0xFFFFFFFF:8> +;// User/System Mode <0x0-0xFFFFFFFF:8> +;// + +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 + + +;// Heap Configuration +;// Heap Size (in Bytes) <0x0-0xFFFFFFFF> +;// + +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 + +;// Clock Setup +;// System Controls and Status Register (SYS) +;// OSCRANGE: Main Oscillator Range Select +;// <0=> 1 MHz to 20 MHz +;// <1=> 15 MHz to 24 MHz +;// OSCEN: Main Oscillator Enable +;// +;// +;// +;// PLL Clock Source Select Register (CLKSRCSEL) +;// CLKSRC: PLL Clock Source Selection +;// <0=> Internal RC oscillator +;// <1=> Main oscillator +;// <2=> RTC oscillator +;// +;// +;// PLL Configuration Register (PLLCFG) +;// PLL_clk = (2* M * PLL_clk_src) / N +;// MSEL: PLL Multiplier Selection +;// <1-32768><#-1> +;// M Value +;// NSEL: PLL Divider Selection +;// <1-256><#-1> +;// N Value +;// +;// +;// CPU Clock Configuration Register (CCLKCFG) +;// CCLKSEL: Divide Value for CPU Clock from PLL +;// <1-256><#-1> +;// +;// +;// USB Clock Configuration Register (USBCLKCFG) +;// USBSEL: Divide Value for USB Clock from PLL +;// <1-16><#-1> +;// +;// +;// Peripheral Clock Selection Register 0 (PCLKSEL0) +;// PCLK_WDT: Peripheral Clock Selection for WDT +;// <0=> Pclk = Cclk / 4 +;// <1=> Pclk = Cclk +;// <2=> Pclk = Cclk / 2 +;// <3=> Pclk = Cclk / 8 +;// PCLK_TIMER0: Peripheral Clock Selection for TIMER0 +;// <0=> Pclk = Cclk / 4 +;// <1=> Pclk = Cclk +;// <2=> Pclk = Cclk / 2 +;// <3=> Pclk = Cclk / 8 +;// PCLK_TIMER1: Peripheral Clock Selection for TIMER1 +;// <0=> Pclk = Cclk / 4 +;// <1=> Pclk = Cclk +;// <2=> Pclk = Cclk / 2 +;// <3=> Pclk = Cclk / 8 +;// PCLK_UART0: Peripheral Clock Selection for UART0 +;// <0=> Pclk = Cclk / 4 +;// <1=> Pclk = Cclk +;// <2=> Pclk = Cclk / 2 +;// <3=> Pclk = Cclk / 8 +;// PCLK_UART1: Peripheral Clock Selection for UART1 +;// <0=> Pclk = Cclk / 4 +;// <1=> Pclk = Cclk +;// <2=> Pclk = Cclk / 2 +;// <3=> Pclk = Cclk / 8 +;// PCLK_PWM0: Peripheral Clock Selection for PWM0 +;// <0=> Pclk = Cclk / 4 +;// <1=> Pclk = Cclk +;// <2=> Pclk = Cclk / 2 +;// <3=> Pclk = Cclk / 8 +;// PCLK_PWM1: Peripheral Clock Selection for PWM1 +;// <0=> Pclk = Cclk / 4 +;// <1=> Pclk = Cclk +;// <2=> Pclk = Cclk / 2 +;// <3=> Pclk = Cclk / 8 +;// PCLK_I2C0: Peripheral Clock Selection for I2C0 +;// <0=> Pclk = Cclk / 4 +;// <1=> Pclk = Cclk +;// <2=> Pclk = Cclk / 2 +;// <3=> Pclk = Cclk / 8 +;// PCLK_SPI: Peripheral Clock Selection for SPI +;// <0=> Pclk = Cclk / 4 +;// <1=> Pclk = Cclk +;// <2=> Pclk = Cclk / 2 +;// <3=> Pclk = Cclk / 8 +;// PCLK_RTC: Peripheral Clock Selection for RTC +;// <0=> Pclk = Cclk / 4 +;// <1=> Pclk = Cclk +;// <2=> Pclk = Cclk / 2 +;// <3=> Pclk = Cclk / 8 +;// PCLK_SSP1: Peripheral Clock Selection for SSP1 +;// <0=> Pclk = Cclk / 4 +;// <1=> Pclk = Cclk +;// <2=> Pclk = Cclk / 2 +;// <3=> Pclk = Cclk / 8 +;// PCLK_DAC: Peripheral Clock Selection for DAC +;// <0=> Pclk = Cclk / 4 +;// <1=> Pclk = Cclk +;// <2=> Pclk = Cclk / 2 +;// <3=> Pclk = Cclk / 8 +;// PCLK_ADC: Peripheral Clock Selection for ADC +;// <0=> Pclk = Cclk / 4 +;// <1=> Pclk = Cclk +;// <2=> Pclk = Cclk / 2 +;// <3=> Pclk = Cclk / 8 +;// PCLK_CAN1: Peripheral Clock Selection for CAN1 +;// <0=> Pclk = Cclk / 4 +;// <1=> Pclk = Cclk +;// <2=> Pclk = Cclk / 2 +;// <3=> Pclk = Cclk / 6 +;// PCLK_CAN2: Peripheral Clock Selection for CAN2 +;// <0=> Pclk = Cclk / 4 +;// <1=> Pclk = Cclk +;// <2=> Pclk = Cclk / 2 +;// <3=> Pclk = Cclk / 6 +;// PCLK_ACF: Peripheral Clock Selection for ACF +;// <0=> Pclk = Cclk / 4 +;// <1=> Pclk = Cclk +;// <2=> Pclk = Cclk / 2 +;// <3=> Pclk = Cclk / 6 +;// +;// +;// Peripheral Clock Selection Register 1 (PCLKSEL1) +;// 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 +;// PCLK_GPIO: Peripheral Clock Selection for GPIOs +;// <0=> Pclk = Cclk / 4 +;// <1=> Pclk = Cclk +;// <2=> Pclk = Cclk / 2 +;// <3=> Pclk = Cclk / 8 +;// PCLK_PCB: Peripheral Clock Selection for Pin Connect Block +;// <0=> Pclk = Cclk / 4 +;// <1=> Pclk = Cclk +;// <2=> Pclk = Cclk / 2 +;// <3=> Pclk = Cclk / 8 +;// PCLK_I2C1: Peripheral Clock Selection for I2C1 +;// <0=> Pclk = Cclk / 4 +;// <1=> Pclk = Cclk +;// <2=> Pclk = Cclk / 2 +;// <3=> Pclk = Cclk / 8 +;// PCLK_SSP0: Peripheral Clock Selection for SSP0 +;// <0=> Pclk = Cclk / 4 +;// <1=> Pclk = Cclk +;// <2=> Pclk = Cclk / 2 +;// <3=> Pclk = Cclk / 8 +;// PCLK_TIMER2: Peripheral Clock Selection for TIMER2 +;// <0=> Pclk = Cclk / 4 +;// <1=> Pclk = Cclk +;// <2=> Pclk = Cclk / 2 +;// <3=> Pclk = Cclk / 8 +;// PCLK_TIMER3: Peripheral Clock Selection for TIMER3 +;// <0=> Pclk = Cclk / 4 +;// <1=> Pclk = Cclk +;// <2=> Pclk = Cclk / 2 +;// <3=> Pclk = Cclk / 8 +;// PCLK_UART2: Peripheral Clock Selection for UART2 +;// <0=> Pclk = Cclk / 4 +;// <1=> Pclk = Cclk +;// <2=> Pclk = Cclk / 2 +;// <3=> Pclk = Cclk / 8 +;// PCLK_UART3: Peripheral Clock Selection for UART3 +;// <0=> Pclk = Cclk / 4 +;// <1=> Pclk = Cclk +;// <2=> Pclk = Cclk / 2 +;// <3=> Pclk = Cclk / 8 +;// PCLK_I2C2: Peripheral Clock Selection for I2C2 +;// <0=> Pclk = Cclk / 4 +;// <1=> Pclk = Cclk +;// <2=> Pclk = Cclk / 2 +;// <3=> Pclk = Cclk / 8 +;// PCLK_I2S: Peripheral Clock Selection for I2S +;// <0=> Pclk = Cclk / 4 +;// <1=> Pclk = Cclk +;// <2=> Pclk = Cclk / 2 +;// <3=> Pclk = Cclk / 8 +;// PCLK_MCI: Peripheral Clock Selection for MCI +;// <0=> Pclk = Cclk / 4 +;// <1=> Pclk = Cclk +;// <2=> Pclk = Cclk / 2 +;// <3=> Pclk = Cclk / 8 +;// PCLK_SYSCON: Peripheral Clock Selection for System Control Block +;// <0=> Pclk = Cclk / 4 +;// <1=> Pclk = Cclk +;// <2=> Pclk = Cclk / 2 +;// <3=> Pclk = Cclk / 8 +;// +;// +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 + +;// MAM Setup +;// MAM Control +;// <0=> Disabled +;// <1=> Partially Enabled +;// <2=> Fully Enabled +;// Mode +;// MAM Timing +;// <0=> Reserved <1=> 1 <2=> 2 <3=> 3 +;// <4=> 4 <5=> 5 <6=> 6 <7=> 7 +;// Fetch Cycles +;// +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) --------------------------------- +;// External Memory Controller Setup (EMC) +EMC_SETUP EQU 0 + +;// EMC Control Register (EMCControl) +;// Controls operation of the memory controller +;// L: Low-power mode enable +;// M: Address mirror enable +;// E: EMC enable +;// +EMC_CTRL_Val EQU 0x00000001 + +;// EMC Configuration Register (EMCConfig) +;// Configures operation of the memory controller +;// CCLK: CLKOUT ratio +;// <0=> 1:1 +;// <1=> 1:2 +;// Endian mode +;// <0=> Little-endian +;// <1=> Big-endian +;// +EMC_CONFIG_Val EQU 0x00000000 + +;// Dynamic Memory Interface Setup --------------------------------------- +;// Dynamic Memory Interface Setup +EMC_DYNAMIC_SETUP EQU 1 + +;// Dynamic Memory Refresh Timer Register (EMCDynamicRefresh) +;// Configures dynamic memory refresh operation +;// REFRESH: Refresh timer <0x000-0x7FF> +;// 0 = refresh disabled, 0x01-0x7FF: value * 16 CCLKS +;// +EMC_DYN_RFSH_Val EQU 0x0000001C + +;// Dynamic Memory Read Configuration Register (EMCDynamicReadConfig) +;// Configures the dynamic memory read strategy +;// 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 +;// +EMC_DYN_RD_CFG_Val EQU 0x00000001 + +;// Dynamic Memory Timings +;// Dynamic Memory Percentage Command Period Register (EMCDynamictRP) +;// tRP: Precharge command period <1-16> <#-1> +;// The delay is in EMCCLK cycles +;// This value is normally found in SDRAM data sheets as tRP +;// +;// Dynamic Memory Active to Precharge Command Period Register (EMCDynamictRAS) +;// tRAS: Active to precharge command period <1-16> <#-1> +;// The delay is in EMCCLK cycles +;// This value is normally found in SDRAM data sheets as tRAS +;// +;// Dynamic Memory Self-refresh Exit Time Register (EMCDynamictSREX) +;// tSREX: Self-refresh exit time <1-16> <#-1> +;// The delay is in CCLK cycles +;// This value is normally found in SDRAM data sheets as tSREX, +;// for devices without this parameter you use the same value as tXSR +;// +;// Dynamic Memory Last Data Out to Active Time Register (EMCDynamictAPR) +;// tAPR: Last-data-out to active command time <1-16> <#-1> +;// The delay is in CCLK cycles +;// This value is normally found in SDRAM data sheets as tAPR +;// +;// Dynamic Memory Data-in to Active Command Time Register (EMCDynamictDAL) +;// tDAL: Data-in to active command time <1-16> <#-1> +;// The delay is in CCLK cycles +;// This value is normally found in SDRAM data sheets as tDAL or tAPW +;// +;// Dynamic Memory Write Recovery Time Register (EMCDynamictWR) +;// tWR: Write recovery time <1-16> <#-1> +;// The delay is in CCLK cycles +;// This value is normally found in SDRAM data sheets as tWR, tDPL, tRWL, or tRDL +;// +;// Dynamic Memory Active to Active Command Period Register (EMCDynamictRC) +;// tRC: Active to active command period <1-32> <#-1> +;// The delay is in CCLK cycles +;// This value is normally found in SDRAM data sheets as tRC +;// +;// Dynamic Memory Auto-refresh Period Register (EMCDynamictRFC) +;// tRFC: Auto-refresh period and auto-refresh to active command period <1-32> <#-1> +;// The delay is in CCLK cycles +;// This value is normally found in SDRAM data sheets as tRFC or tRC +;// +;// Dynamic Memory Exit Self-refresh Register (EMCDynamictXSR) +;// tXSR: Exit self-refresh to active command time <1-32> <#-1> +;// The delay is in CCLK cycles +;// This value is normally found in SDRAM data sheets as tXSR +;// +;// Dynamic Memory Active Bank A to Active Bank B Time Register (EMCDynamicRRD) +;// tRRD: Active bank A to active bank B latency <1-16> <#-1> +;// The delay is in CCLK cycles +;// This value is normally found in SDRAM data sheets as tRRD +;// +;// Dynamic Memory Load Mode Register to Active Command Time (EMCDynamictMRD) +;// tMRD: Load mode register to active command time <1-16> <#-1> +;// The delay is in CCLK cycles +;// This value is normally found in SDRAM data sheets as tMRD or tRSA +;// +;// +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 + +;// Configure External Bus Behaviour for Dynamic CS0 Area +EMC_DYNCS0_SETUP EQU 1 + +;// Dynamic Memory Configuration Register (EMCDynamicConfig0) +;// Defines the configuration information for the dynamic memory CS0 +;// P: Write protect +;// B: Buffer enable +;// AM 14: External bus data width +;// <0=> 16 bit +;// <1=> 32 bit +;// AM 12: External bus memory type +;// <0=> High-performance +;// <1=> Low-power SDRAM +;// 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 +;// MD: Memory device +;// <0=> SDRAM +;// <1=> Low-power SDRAM +;// <2=> Micron SyncFlash +;// +EMC_DYN_CFG0_Val EQU 0x00080680 + +;// Dynamic Memory RAS & CAS Delay register (EMCDynamicRASCAS0) +;// Controls the RAS and CAS latencies for the dynamic memory CS0 +;// CAS: CAS latency +;// <1=> One CCLK cycle +;// <2=> Two CCLK cycles +;// <3=> Three CCLK cycles +;// RAS: RAS latency (active to read/write delay) +;// <1=> One CCLK cycle +;// <2=> Two CCLK cycles +;// <3=> Three CCLK cycles +;// +EMC_DYN_RASCAS0_Val EQU 0x00000303 + +;// End of Dynamic Setup for CS0 Area + + +;// Configure External Bus Behaviour for Dynamic CS1 Area +EMC_DYNCS1_SETUP EQU 0 + +;// Dynamic Memory Configuration Register (EMCDynamicConfig1) +;// Defines the configuration information for the dynamic memory CS1 +;// P: Write protect +;// B: Buffer enable +;// AM 14: External bus data width +;// <0=> 16 bit +;// <1=> 32 bit +;// AM 12: External bus memory type +;// <0=> High-performance +;// <1=> Low-power SDRAM +;// 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 +;// MD: Memory device +;// <0=> SDRAM +;// <1=> Low-power SDRAM +;// <2=> Micron SyncFlash +;// +EMC_DYN_CFG1_Val EQU 0x00000000 + +;// Dynamic Memory RAS & CAS Delay register (EMCDynamicRASCAS1) +;// Controls the RAS and CAS latencies for the dynamic memory CS1 +;// CAS: CAS latency +;// <1=> One CCLK cycle +;// <2=> Two CCLK cycles +;// <3=> Three CCLK cycles +;// RAS: RAS latency (active to read/write delay) +;// <1=> One CCLK cycle +;// <2=> Two CCLK cycles +;// <3=> Three CCLK cycles +;// +EMC_DYN_RASCAS1_Val EQU 0x00000303 + +;// End of Dynamic Setup for CS1 Area + +;// Configure External Bus Behaviour for Dynamic CS2 Area +EMC_DYNCS2_SETUP EQU 0 + +;// Dynamic Memory Configuration Register (EMCDynamicConfig2) +;// Defines the configuration information for the dynamic memory CS2 +;// P: Write protect +;// B: Buffer enable +;// AM 14: External bus data width +;// <0=> 16 bit +;// <1=> 32 bit +;// AM 12: External bus memory type +;// <0=> High-performance +;// <1=> Low-power SDRAM +;// 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 +;// MD: Memory device +;// <0=> SDRAM +;// <1=> Low-power SDRAM +;// <2=> Micron SyncFlash +;// +EMC_DYN_CFG2_Val EQU 0x00000000 + +;// Dynamic Memory RAS & CAS Delay register (EMCDynamicRASCAS2) +;// Controls the RAS and CAS latencies for the dynamic memory CS2 +;// CAS: CAS latency +;// <1=> One CCLK cycle +;// <2=> Two CCLK cycles +;// <3=> Three CCLK cycles +;// RAS: RAS latency (active to read/write delay) +;// <1=> One CCLK cycle +;// <2=> Two CCLK cycles +;// <3=> Three CCLK cycles +;// +EMC_DYN_RASCAS2_Val EQU 0x00000303 + +;// End of Dynamic Setup for CS2 Area + +;// Configure External Bus Behaviour for Dynamic CS3 Area +EMC_DYNCS3_SETUP EQU 0 + +;// Dynamic Memory Configuration Register (EMCDynamicConfig3) +;// Defines the configuration information for the dynamic memory CS3 +;// P: Write protect +;// B: Buffer enable +;// AM 14: External bus data width +;// <0=> 16 bit +;// <1=> 32 bit +;// AM 12: External bus memory type +;// <0=> High-performance +;// <1=> Low-power SDRAM +;// 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 +;// MD: Memory device +;// <0=> SDRAM +;// <1=> Low-power SDRAM +;// <2=> Micron SyncFlash +;// +EMC_DYN_CFG3_Val EQU 0x00000000 + +;// Dynamic Memory RAS & CAS Delay register (EMCDynamicRASCAS3) +;// Controls the RAS and CAS latencies for the dynamic memory CS3 +;// CAS: CAS latency +;// <1=> One CCLK cycle +;// <2=> Two CCLK cycles +;// <3=> Three CCLK cycles +;// RAS: RAS latency (active to read/write delay) +;// <1=> One CCLK cycle +;// <2=> Two CCLK cycles +;// <3=> Three CCLK cycles +;// +EMC_DYN_RASCAS3_Val EQU 0x00000303 + +;// End of Dynamic Setup for CS3 Area + +;// End of Dynamic Setup + +;// Static Memory Interface Setup ---------------------------------------- +;// Static Memory Interface Setup +EMC_STATIC_SETUP EQU 1 + +;// Configure External Bus Behaviour for Static CS0 Area --------------- +;// Configure External Bus Behaviour for Static CS0 Area +EMC_STACS0_SETUP EQU 1 + +;// Static Memory Configuration Register (EMCStaticConfig0) +;// Defines the configuration information for the static memory CS0 +;// WP: Write protect +;// B: Buffer enable +;// EW: Extended wait enable +;// 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 +;// PC: Chip select polarity +;// <0=> Active LOW chip select +;// <1=> Active HIGH chip select +;// PM: Page mode enable +;// MW: Memory width +;// <0=> 8 bit +;// <1=> 16 bit +;// <2=> 32 bit +;// +EMC_STA_CFG0_Val EQU 0x00000081 + +;// Static Memory Write Enable Delay Register (EMCStaticWaitWen0) +;// Selects the delay from CS0 to write enable +;// WAITWEN: Wait write enable <1-16> <#-1> +;// The delay is in CCLK cycles +;// +EMC_STA_WWEN0_Val EQU 0x00000002 + +;// Static Memory Output Enable Delay register (EMCStaticWaitOen0) +;// Selects the delay from CS0 or address change, whichever is later, to output enable +;// WAITOEN: Wait output enable <0-15> +;// The delay is in CCLK cycles +;// +EMC_STA_WOEN0_Val EQU 0x00000002 + +;// Static Memory Read Delay Register (EMCStaticWaitRd0) +;// Selects the delay from CS0 to a read access +;// WAITRD: Non-page mode read wait states or asynchronous page mode read first access wait states <1-32> <#-1> +;// The delay is in CCLK cycles +;// +EMC_STA_WRD0_Val EQU 0x0000001F + +;// Static Memory Page Mode Read Delay Register (EMCStaticWaitPage0) +;// Selects the delay for asynchronous page mode sequential accesses for CS0 +;// WAITPAGE: Asynchronous page mode read after the first read wait states <1-32> <#-1> +;// The delay is in CCLK cycles +;// +EMC_STA_WPAGE0_Val EQU 0x0000001F + +;// Static Memory Write Delay Register (EMCStaticWaitWr0) +;// Selects the delay from CS0 to a write access +;// WAITWR: Write wait states <2-33> <#-2> +;// The delay is in CCLK cycles +;// +EMC_STA_WWR0_Val EQU 0x0000001F + +;// Static Memory Turn Round Delay Register (EMCStaticWaitTurn0) +;// Selects the number of bus turnaround cycles for CS0 +;// WAITTURN: Bus turnaround cycles <1-16> <#-1> +;// The delay is in CCLK cycles +;// +EMC_STA_WTURN0_Val EQU 0x0000000F + +;// End of Static Setup for Static CS0 Area + +;// Configure External Bus Behaviour for Static CS1 Area --------------- +;// Configure External Bus Behaviour for Static CS1 Area +EMC_STACS1_SETUP EQU 0 + +;// Static Memory Configuration Register (EMCStaticConfig1) +;// Defines the configuration information for the static memory CS1 +;// WP: Write protect +;// B: Buffer enable +;// EW: Extended wait enable +;// 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 +;// PC: Chip select polarity +;// <0=> Active LOW chip select +;// <1=> Active HIGH chip select +;// PM: Page mode enable +;// MW: Memory width +;// <0=> 8 bit +;// <1=> 16 bit +;// <2=> 32 bit +;// +EMC_STA_CFG1_Val EQU 0x00000000 + +;// Static Memory Write Enable Delay Register (EMCStaticWaitWen1) +;// Selects the delay from CS1 to write enable +;// WAITWEN: Wait write enable <1-16> <#-1> +;// The delay is in CCLK cycles +;// +EMC_STA_WWEN1_Val EQU 0x00000000 + +;// Static Memory Output Enable Delay register (EMCStaticWaitOen1) +;// Selects the delay from CS1 or address change, whichever is later, to output enable +;// WAITOEN: Wait output enable <0-15> +;// The delay is in CCLK cycles +;// +EMC_STA_WOEN1_Val EQU 0x00000000 + +;// Static Memory Read Delay Register (EMCStaticWaitRd1) +;// Selects the delay from CS1 to a read access +;// WAITRD: Non-page mode read wait states or asynchronous page mode read first access wait states <1-32> <#-1> +;// The delay is in CCLK cycles +;// +EMC_STA_WRD1_Val EQU 0x0000001F + +;// Static Memory Page Mode Read Delay Register (EMCStaticWaitPage0) +;// Selects the delay for asynchronous page mode sequential accesses for CS1 +;// WAITPAGE: Asynchronous page mode read after the first read wait states <1-32> <#-1> +;// The delay is in CCLK cycles +;// +EMC_STA_WPAGE1_Val EQU 0x0000001F + +;// Static Memory Write Delay Register (EMCStaticWaitWr1) +;// Selects the delay from CS1 to a write access +;// WAITWR: Write wait states <2-33> <#-2> +;// The delay is in CCLK cycles +;// +EMC_STA_WWR1_Val EQU 0x0000001F + +;// Static Memory Turn Round Delay Register (EMCStaticWaitTurn1) +;// Selects the number of bus turnaround cycles for CS1 +;// WAITTURN: Bus turnaround cycles <1-16> <#-1> +;// The delay is in CCLK cycles +;// +EMC_STA_WTURN1_Val EQU 0x0000000F + +;// End of Static Setup for Static CS1 Area + +;// Configure External Bus Behaviour for Static CS2 Area --------------- +;// Configure External Bus Behaviour for Static CS2 Area +EMC_STACS2_SETUP EQU 0 + +;// Static Memory Configuration Register (EMCStaticConfig2) +;// Defines the configuration information for the static memory CS2 +;// WP: Write protect +;// B: Buffer enable +;// EW: Extended wait enable +;// 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 +;// PC: Chip select polarity +;// <0=> Active LOW chip select +;// <1=> Active HIGH chip select +;// PM: Page mode enable +;// MW: Memory width +;// <0=> 8 bit +;// <1=> 16 bit +;// <2=> 32 bit +;// +EMC_STA_CFG2_Val EQU 0x00000000 + +;// Static Memory Write Enable Delay Register (EMCStaticWaitWen2) +;// Selects the delay from CS2 to write enable +;// WAITWEN: Wait write enable <1-16> <#-1> +;// The delay is in CCLK cycles +;// +EMC_STA_WWEN2_Val EQU 0x00000000 + +;// Static Memory Output Enable Delay register (EMCStaticWaitOen2) +;// Selects the delay from CS2 or address change, whichever is later, to output enable +;// WAITOEN: Wait output enable <0-15> +;// The delay is in CCLK cycles +;// +EMC_STA_WOEN2_Val EQU 0x00000000 + +;// Static Memory Read Delay Register (EMCStaticWaitRd2) +;// Selects the delay from CS2 to a read access +;// WAITRD: Non-page mode read wait states or asynchronous page mode read first access wait states <1-32> <#-1> +;// The delay is in CCLK cycles +;// +EMC_STA_WRD2_Val EQU 0x0000001F + +;// Static Memory Page Mode Read Delay Register (EMCStaticWaitPage2) +;// Selects the delay for asynchronous page mode sequential accesses for CS2 +;// WAITPAGE: Asynchronous page mode read after the first read wait states <1-32> <#-1> +;// The delay is in CCLK cycles +;// +EMC_STA_WPAGE2_Val EQU 0x0000001F + +;// Static Memory Write Delay Register (EMCStaticWaitWr2) +;// Selects the delay from CS2 to a write access +;// WAITWR: Write wait states <2-33> <#-2> +;// The delay is in CCLK cycles +;// +EMC_STA_WWR2_Val EQU 0x0000001F + +;// Static Memory Turn Round Delay Register (EMCStaticWaitTurn2) +;// Selects the number of bus turnaround cycles for CS2 +;// WAITTURN: Bus turnaround cycles <1-16> <#-1> +;// The delay is in CCLK cycles +;// +EMC_STA_WTURN2_Val EQU 0x0000000F + +;// End of Static Setup for Static CS2 Area + +;// Configure External Bus Behaviour for Static CS3 Area --------------- +;// Configure External Bus Behaviour for Static CS3 Area +EMC_STACS3_SETUP EQU 0 + +;// Static Memory Configuration Register (EMCStaticConfig3) +;// Defines the configuration information for the static memory CS3 +;// WP: Write protect +;// B: Buffer enable +;// EW: Extended wait enable +;// 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 +;// PC: Chip select polarity +;// <0=> Active LOW chip select +;// <1=> Active HIGH chip select +;// PM: Page mode enable +;// MW: Memory width +;// <0=> 8 bit +;// <1=> 16 bit +;// <2=> 32 bit +;// +EMC_STA_CFG3_Val EQU 0x00000000 + +;// Static Memory Write Enable Delay Register (EMCStaticWaitWen3) +;// Selects the delay from CS3 to write enable +;// WAITWEN: Wait write enable <1-16> <#-1> +;// The delay is in CCLK cycles +;// +EMC_STA_WWEN3_Val EQU 0x00000000 + +;// Static Memory Output Enable Delay register (EMCStaticWaitOen3) +;// Selects the delay from CS3 or address change, whichever is later, to output enable +;// WAITOEN: Wait output enable <0-15> +;// The delay is in CCLK cycles +;// +EMC_STA_WOEN3_Val EQU 0x00000000 + +;// Static Memory Read Delay Register (EMCStaticWaitRd3) +;// Selects the delay from CS3 to a read access +;// WAITRD: Non-page mode read wait states or asynchronous page mode read first access wait states <1-32> <#-1> +;// The delay is in CCLK cycles +;// +EMC_STA_WRD3_Val EQU 0x0000001F + +;// Static Memory Page Mode Read Delay Register (EMCStaticWaitPage3) +;// Selects the delay for asynchronous page mode sequential accesses for CS3 +;// WAITPAGE: Asynchronous page mode read after the first read wait states <1-32> <#-1> +;// The delay is in CCLK cycles +;// +EMC_STA_WPAGE3_Val EQU 0x0000001F + +;// Static Memory Write Delay Register (EMCStaticWaitWr3) +;// Selects the delay from CS3 to a write access +;// WAITWR: Write wait states <2-33> <#-2> +;// The delay is in CCLK cycles +;// +EMC_STA_WWR3_Val EQU 0x0000001F + +;// Static Memory Turn Round Delay Register (EMCStaticWaitTurn3) +;// Selects the number of bus turnaround cycles for CS3 +;// WAITTURN: Bus turnaround cycles <1-16> <#-1> +;// The delay is in CCLK cycles +;// +EMC_STA_WTURN3_Val EQU 0x0000000F + +;// End of Static Setup for Static CS3 Area + +;// Static Memory Extended Wait Register (EMCStaticExtendedWait) +;// Time long static memory read and write transfers +;// EXTENDEDWAIT: Extended wait time out <0-1023> +;// The delay is in (16 * CCLK) cycles +;// +EMC_STA_EXT_W_Val EQU 0x00000000 + +;// End of Static Setup + +;// 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 0000000000000000000000000000000000000000..20ac45f8d2ce23dd1f2efe4ed41e4fd82404e2bb --- /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 +#include + +#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 0000000000000000000000000000000000000000..7b39e3252216c0915c7352bcd8b9b0a945da2bbe --- /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 0000000000000000000000000000000000000000..82c5adc574304888b47f94c4007090505ced887f --- /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 0000000000000000000000000000000000000000..088ca2e5feb79dcbdf5a3498cbb3a4799efba04d --- /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 +#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 0000000000000000000000000000000000000000..8051459712adf0554660be7a28aa2fdba5466b73 --- /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 +#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 +#include + +#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 0000000000000000000000000000000000000000..3f1d88a390f61d1bcebef99a97e69b058443f406 --- /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 +#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 0000000000000000000000000000000000000000..4108fc2462b95da7364c95862b4a18e2be63ffe2 --- /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 0000000000000000000000000000000000000000..3154bf37517fe0473059b99b9cd727fc1e8fd313 --- /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 + + +;// Stack Configuration (Stack Sizes in Bytes) +;// Undefined Mode <0x0-0xFFFFFFFF:8> +;// Supervisor Mode <0x0-0xFFFFFFFF:8> +;// Abort Mode <0x0-0xFFFFFFFF:8> +;// Fast Interrupt Mode <0x0-0xFFFFFFFF:8> +;// Interrupt Mode <0x0-0xFFFFFFFF:8> +;// User/System Mode <0x0-0xFFFFFFFF:8> +;// + +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 + + +;// Heap Configuration +;// Heap Size (in Bytes) <0x0-0xFFFFFFFF> +;// + +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 + +;// CPU Wrapper and Bus Priorities +;// CPU Wrapper +;// SE: Stall Enable +;// CM: Cache Mode +;// <0=> Disable Cache (8kB SRAM) +;// <1=> Half Cache Enable (4kB Cache, 4kB SRAM) +;// <2=> Reserved +;// <3=> Full Cache Enable (8kB Cache) +;// WE: Write Buffer Enable +;// RSE: Read Stall Enable +;// DA: Data Abort <0=> Enable <1=> Disable +;// Non-cacheable Area 0 +;// Start Address <0x0-0x0FFFF000:0x1000><#/0x1000> +;// SA = (Start Address) / 4k +;// End Address + 1 <0x0-0x10000000:0x1000><#/0x1000> +;// SE = (End Address + 1) / 4k +;// +;// Non-cacheable Area 1 +;// Start Address <0x0-0x0FFFF000:0x1000><#/0x1000> +;// SA = (Start Address) / 4k +;// End Address + 1 <0x0-0x10000000:0x1000><#/0x1000> +;// SE = (End Address + 1) / 4k +;// +;// +;// Bus Priorities +;// FIX: Fixed Priorities +;// LCD_DMA <0=> 1st <1=> 2nd <2=> 3rd <3=> 4th +;// ZDMA <0=> 1st <1=> 2nd <2=> 3rd <3=> 4th +;// BDMA <0=> 1st <1=> 2nd <2=> 3rd <3=> 4th +;// nBREQ <0=> 1st <1=> 2nd <2=> 3rd <3=> 4th +;// +;// +SYS_SETUP EQU 0 +SYSCFG_Val EQU 0x00000001 +NCACHBE0_Val EQU 0x00000000 +NCACHBE1_Val EQU 0x00000000 +SBUSCON_Val EQU 0x80001B1B + + +;// Vectored Interrupt Mode (for IRQ) +;// EINT0 External Interrupt 0 +;// EINT1 External Interrupt 1 +;// EINT2 External Interrupt 2 +;// EINT3 External Interrupt 3 +;// EINT4567 External Interrupt 4/5/6/7 +;// TICK RTC Time Tick Interrupt +;// ZDMA0 General DMA0 Interrupt +;// ZDMA1 General DMA1 Interrupt +;// BDMA0 Bridge DMA0 Interrupt +;// BDMA1 Bridge DMA1 Interrupt +;// WDT Watchdog Timer Interrupt +;// UERR01 UART0/1 Error Interrupt +;// TIMER0 Timer0 Interrupt +;// TIMER1 Timer1 Interrupt +;// TIMER2 Timer2 Interrupt +;// TIMER3 Timer3 Interrupt +;// TIMER4 Timer4 Interrupt +;// TIMER5 Timer5 Interrupt +;// URXD0 UART0 Rx Interrupt +;// URXD1 UART1 Rx Interrupt +;// IIC IIC Interrupt +;// SIO SIO Interrupt +;// UTXD0 UART0 Tx Interrupt +;// UTXD1 UART1 Tx Interrupt +;// RTC RTC Alarm Interrupt +;// ADC ADC EOC Interrupt +;// +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 + +;// Clock Management +;// PLL Settings +;// Fpllo = (m * Fin) / (p * 2^s), 20MHz < Fpllo < 66MHz +;// MDIV: Main divider <0x0-0xFF> +;// m = MDIV + 8 +;// PDIV: Pre-divider <0x0-0x3F> +;// p = PDIV + 2, 1MHz <= Fin/p < 2MHz +;// SDIV: Post Divider <0x0-0x03> +;// s = SDIV, Fpllo * 2^s < 170MHz +;// LTIME CNT: PLL Lock Time Count <0x0-0x0FFF> +;// +;// Master Clock +;// PLL Clock: Fout = Fpllo +;// Slow Clock: Fout = Fin / (2 * SLOW_VAL), SLOW_VAL > 0 +;// Slow Clock: Fout = Fin, SLOW_VAL = 0 +;// PLL_OFF: PLL Off +;// PLL is turned Off only when SLOW_BIT = 1 +;// SLOW_BIT: Slow Clock +;// SLOW_VAL: Slow Clock divider <0x0-0x0F> +;// +;// Clock Generation +;// IIS <0=> Disable <1=> Enable +;// IIC <0=> Disable <1=> Enable +;// ADC <0=> Disable <1=> Enable +;// RTC <0=> Disable <1=> Enable +;// GPIO <0=> Disable <1=> Enable +;// UART1 <0=> Disable <1=> Enable +;// UART0 <0=> Disable <1=> Enable +;// BDMA0,1 <0=> Disable <1=> Enable +;// LCDC <0=> Disable <1=> Enable +;// SIO <0=> Disable <1=> Enable +;// ZDMA0,1 <0=> Disable <1=> Enable +;// PWMTIMER <0=> Disable <1=> Enable +;// +;// +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 + +;// Watchdog Timer +;// Watchdog Timer Enable/Disable +;// Reset Enable/Disable +;// Interrupt Enable/Disable +;// Clock Select +;// <0=> 1/16 <1=> 1/32 <2=> 1/64 <3=> 1/128 +;// Clock Division Factor +;// Prescaler Value <0x0-0xFF> +;// Time-out Value <0x0-0xFFFF> +;// +WT_SETUP EQU 1 +WTCON_Val EQU 0x00008000 +WTDAT_Val EQU 0x00008000 + + +; Memory Controller definitions +MC_BASE EQU 0x01C80000 ; Memory Controller Base Address + +;// Memory Controller +MC_SETUP EQU 1 + +;// Bank 0 +;// PMC: Page Mode Configuration +;// <0=> 1 Data <1=> 4 Data <2=> 8 Data <3=> 16 Data +;// Tpac: Page Mode Access Cycle +;// <0=> 2 clks <1=> 3 clks <2=> 4 clks <3=> 6 clks +;// Tcah: Address Holding Time after nGCSn +;// <0=> 0 clk <1=> 1 clk <2=> 2 clks <3=> 4 clks +;// Toch: Chip Select Hold on nOE +;// <0=> 0 clk <1=> 1 clk <2=> 2 clks <3=> 4 clks +;// 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 +;// Tcos: Chip Select Set-up nOE +;// <0=> 0 clk <1=> 1 clk <2=> 2 clks <3=> 4 clks +;// Tacs: Address Set-up before nGCSn +;// <0=> 0 clk <1=> 1 clk <2=> 2 clks <3=> 4 clks +;// +;// +;// Bank 1 +;// DW: Data Bus Width +;// <0=> 8-bit <1=> 16-bit <2=> 32-bit <3=> Rsrvd +;// WS: WAIT Status +;// <0=> WAIT Disable +;// <1=> WAIT Enable +;// ST: SRAM Type +;// <0=> Not using UB/LB +;// <1=> Using UB/LB +;// PMC: Page Mode Configuration +;// <0=> 1 Data <1=> 4 Data <2=> 8 Data <3=> 16 Data +;// Tpac: Page Mode Access Cycle +;// <0=> 2 clks <1=> 3 clks <2=> 4 clks <3=> 6 clks +;// Tcah: Address Holding Time after nGCSn +;// <0=> 0 clk <1=> 1 clk <2=> 2 clks <3=> 4 clks +;// Toch: Chip Select Hold on nOE +;// <0=> 0 clk <1=> 1 clk <2=> 2 clks <3=> 4 clks +;// 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 +;// Tcos: Chip Select Set-up nOE +;// <0=> 0 clk <1=> 1 clk <2=> 2 clks <3=> 4 clks +;// Tacs: Address Set-up before nGCSn +;// <0=> 0 clk <1=> 1 clk <2=> 2 clks <3=> 4 clks +;// +;// +;// Bank 2 +;// DW: Data Bus Width +;// <0=> 8-bit <1=> 16-bit <2=> 32-bit <3=> Rsrvd +;// WS: WAIT Status +;// <0=> WAIT Disable +;// <1=> WAIT Enable +;// ST: SRAM Type +;// <0=> Not using UB/LB +;// <1=> Using UB/LB +;// PMC: Page Mode Configuration +;// <0=> 1 Data <1=> 4 Data <2=> 8 Data <3=> 16 Data +;// Tpac: Page Mode Access Cycle +;// <0=> 2 clks <1=> 3 clks <2=> 4 clks <3=> 6 clks +;// Tcah: Address Holding Time after nGCSn +;// <0=> 0 clk <1=> 1 clk <2=> 2 clks <3=> 4 clks +;// Toch: Chip Select Hold on nOE +;// <0=> 0 clk <1=> 1 clk <2=> 2 clks <3=> 4 clks +;// 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 +;// Tcos: Chip Select Set-up nOE +;// <0=> 0 clk <1=> 1 clk <2=> 2 clks <3=> 4 clks +;// Tacs: Address Set-up before nGCSn +;// <0=> 0 clk <1=> 1 clk <2=> 2 clks <3=> 4 clks +;// +;// +;// Bank 3 +;// DW: Data Bus Width +;// <0=> 8-bit <1=> 16-bit <2=> 32-bit <3=> Rsrvd +;// WS: WAIT Status +;// <0=> WAIT Disable +;// <1=> WAIT Enable +;// ST: SRAM Type +;// <0=> Not using UB/LB +;// <1=> Using UB/LB +;// PMC: Page Mode Configuration +;// <0=> 1 Data <1=> 4 Data <2=> 8 Data <3=> 16 Data +;// Tpac: Page Mode Access Cycle +;// <0=> 2 clks <1=> 3 clks <2=> 4 clks <3=> 6 clks +;// Tcah: Address Holding Time after nGCSn +;// <0=> 0 clk <1=> 1 clk <2=> 2 clks <3=> 4 clks +;// Toch: Chip Select Hold on nOE +;// <0=> 0 clk <1=> 1 clk <2=> 2 clks <3=> 4 clks +;// 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 +;// Tcos: Chip Select Set-up nOE +;// <0=> 0 clk <1=> 1 clk <2=> 2 clks <3=> 4 clks +;// Tacs: Address Set-up before nGCSn +;// <0=> 0 clk <1=> 1 clk <2=> 2 clks <3=> 4 clks +;// +;// +;// Bank 4 +;// DW: Data Bus Width +;// <0=> 8-bit <1=> 16-bit <2=> 32-bit <3=> Rsrvd +;// WS: WAIT Status +;// <0=> WAIT Disable +;// <1=> WAIT Enable +;// ST: SRAM Type +;// <0=> Not using UB/LB +;// <1=> Using UB/LB +;// PMC: Page Mode Configuration +;// <0=> 1 Data <1=> 4 Data <2=> 8 Data <3=> 16 Data +;// Tpac: Page Mode Access Cycle +;// <0=> 2 clks <1=> 3 clks <2=> 4 clks <3=> 6 clks +;// Tcah: Address Holding Time after nGCSn +;// <0=> 0 clk <1=> 1 clk <2=> 2 clks <3=> 4 clks +;// Toch: Chip Select Hold on nOE +;// <0=> 0 clk <1=> 1 clk <2=> 2 clks <3=> 4 clks +;// 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 +;// Tcos: Chip Select Set-up nOE +;// <0=> 0 clk <1=> 1 clk <2=> 2 clks <3=> 4 clks +;// Tacs: Address Set-up before nGCSn +;// <0=> 0 clk <1=> 1 clk <2=> 2 clks <3=> 4 clks +;// +;// +;// Bank 5 +;// DW: Data Bus Width +;// <0=> 8-bit <1=> 16-bit <2=> 32-bit <3=> Rsrvd +;// WS: WAIT Status +;// <0=> WAIT Disable +;// <1=> WAIT Enable +;// ST: SRAM Type +;// <0=> Not using UB/LB +;// <1=> Using UB/LB +;// PMC: Page Mode Configuration +;// <0=> 1 Data <1=> 4 Data <2=> 8 Data <3=> 16 Data +;// Tpac: Page Mode Access Cycle +;// <0=> 2 clks <1=> 3 clks <2=> 4 clks <3=> 6 clks +;// Tcah: Address Holding Time after nGCSn +;// <0=> 0 clk <1=> 1 clk <2=> 2 clks <3=> 4 clks +;// Toch: Chip Select Hold on nOE +;// <0=> 0 clk <1=> 1 clk <2=> 2 clks <3=> 4 clks +;// 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 +;// Tcos: Chip Select Set-up nOE +;// <0=> 0 clk <1=> 1 clk <2=> 2 clks <3=> 4 clks +;// Tacs: Address Set-up before nGCSn +;// <0=> 0 clk <1=> 1 clk <2=> 2 clks <3=> 4 clks +;// +;// +;// Bank 6 +;// BK76MAP: Bank 6/7 Memory Map +;// <0=> 32M <4=> 2M <5=> 4M <6=> 8M <7=> 16M +;// DW: Data Bus Width +;// <0=> 8-bit <1=> 16-bit <2=> 32-bit <3=> Rsrvd +;// WS: WAIT Status +;// <0=> WAIT Disable +;// <1=> WAIT Enable +;// ST: SRAM Type +;// <0=> Not using UB/LB +;// <1=> Using UB/LB +;// MT: Memory Type +;// <0=> ROM or SRAM +;// <1=> FP DRAMP +;// <2=> EDO DRAM +;// <3=> SDRAM +;// ROM or SRAM +;// PMC: Page Mode Configuration +;// <0=> 1 Data <1=> 4 Data <2=> 8 Data <3=> 16 Data +;// Tpac: Page Mode Access Cycle +;// <0=> 2 clks <1=> 3 clks <2=> 4 clks <3=> 6 clks +;// Tcah: Address Holding Time after nGCSn +;// <0=> 0 clk <1=> 1 clk <2=> 2 clks <3=> 4 clks +;// Toch: Chip Select Hold on nOE +;// <0=> 0 clk <1=> 1 clk <2=> 2 clks <3=> 4 clks +;// 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 +;// Tcos: Chip Select Set-up nOE +;// <0=> 0 clk <1=> 1 clk <2=> 2 clks <3=> 4 clks +;// Tacs: Address Set-up before nGCSn +;// <0=> 0 clk <1=> 1 clk <2=> 2 clks <3=> 4 clks +;// +;// FP DRAM or EDO DRAM +;// CAN: Columnn Address Number +;// <0=> 8-bit <1=> 9-bit <2=> 10-bit <3=> 11-bit +;// Tcp: CAS Pre-charge +;// <0=> 1 clk <1=> 2 clks +;// Tcas: CAS Pulse Width +;// <0=> 1 clk <1=> 2 clks +;// Trcd: RAS to CAS Delay +;// <0=> 1 clk <1=> 2 clks <2=> 3 clks <3=> 4 clks +;// +;// SDRAM +;// SCAN: Columnn Address Number +;// <0=> 8-bit <1=> 9-bit <2=> 10-bit <3=> Rsrvd +;// Trcd: RAS to CAS Delay +;// <0=> 2 clks <1=> 3 clks <2=> 4 clks <3=> Rsrvd +;// SCLKEN: SCLK Selection (Bank 6/7) +;// <0=> Normal +;// <1=> Reduced Power +;// BL: Burst Length +;// <0=> 1 +;// BT: Burst Type +;// <0=> Sequential +;// CL: CAS Latency +;// <0=> 1 clk <1=> 2 clks <2=> 3 clks +;// TM: Test Mode +;// <0=> Mode Register Set +;// WBL: Write Burst Length +;// <0=> 0 +;// +;// +;// +;// Bank 7 +;// BK76MAP: Bank 6/7 Memory Map +;// <0=> 32M <4=> 2M <5=> 4M <6=> 8M <7=> 16M +;// DW: Data Bus Width +;// <0=> 8-bit <1=> 16-bit <2=> 32-bit <3=> Rsrvd +;// WS: WAIT Status +;// <0=> WAIT Disable +;// <1=> WAIT Enable +;// ST: SRAM Type +;// <0=> Not using UB/LB +;// <1=> Using UB/LB +;// MT: Memory Type +;// <0=> ROM or SRAM +;// <1=> FP DRAMP +;// <2=> EDO DRAM +;// <3=> SDRAM +;// ROM or SRAM +;// PMC: Page Mode Configuration +;// <0=> 1 Data <1=> 4 Data <2=> 8 Data <3=> 16 Data +;// Tpac: Page Mode Access Cycle +;// <0=> 2 clks <1=> 3 clks <2=> 4 clks <3=> 6 clks +;// Tcah: Address Holding Time after nGCSn +;// <0=> 0 clk <1=> 1 clk <2=> 2 clks <3=> 4 clks +;// Toch: Chip Select Hold on nOE +;// <0=> 0 clk <1=> 1 clk <2=> 2 clks <3=> 4 clks +;// 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 +;// Tcos: Chip Select Set-up nOE +;// <0=> 0 clk <1=> 1 clk <2=> 2 clks <3=> 4 clks +;// Tacs: Address Set-up before nGCSn +;// <0=> 0 clk <1=> 1 clk <2=> 2 clks <3=> 4 clks +;// +;// FP DRAM or EDO DRAM +;// CAN: Columnn Address Number +;// <0=> 8-bit <1=> 9-bit <2=> 10-bit <3=> 11-bit +;// Tcp: CAS Pre-charge +;// <0=> 1 clk <1=> 2 clks +;// Tcas: CAS Pulse Width +;// <0=> 1 clk <1=> 2 clks +;// Trcd: RAS to CAS Delay +;// <0=> 1 clk <1=> 2 clks <2=> 3 clks <3=> 4 clks +;// +;// SDRAM +;// SCAN: Columnn Address Number +;// <0=> 8-bit <1=> 9-bit <2=> 10-bit <3=> Rsrvd +;// Trcd: RAS to CAS Delay +;// <0=> 2 clks <1=> 3 clks <2=> 4 clks <3=> Rsrvd +;// SCLKEN: SCLK Selection (Bank 6/7) +;// <0=> Normal +;// <1=> Reduced Power +;// BL: Burst Length +;// <0=> 1 +;// BT: Burst Type +;// <0=> Sequential +;// CL: CAS Latency +;// <0=> 1 clk <1=> 2 clks <2=> 3 clks +;// TM: Test Mode +;// <0=> Mode Register Set +;// WBL: Write Burst Length +;// <0=> 0 +;// +;// +;// +;// Refresh +;// REFEN: DRAM/SDRAM Refresh +;// <0=> Disable <1=> Enable +;// TREFMD: DRAM/SDRAM Refresh Mode +;// <0=> CBR/Auto Refresh +;// <1=> Self Refresh +;// 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) +;// Trc: SDRAM RC Min Time +;// <0=> 4 clks <1=> 5 clks <2=> 6 clks <3=> 7 clks +;// Tchr: DRAM CAS Hold Time +;// <0=> 1 clks <1=> 2 clks <2=> 3 clks <3=> 4 clks +;// Refresh Counter <0x0-0x07FF> +;// Refresh Period = (2^11 - Refresh Count + 1) / MCLK +;// +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 + +;// 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 + +;// I/O Configuration +PIO_SETUP EQU 0 + +;// Port A +;// PA0 <0=> Output <1=> ADDR0 +;// PA1 <0=> Output <1=> ADDR16 +;// PA2 <0=> Output <1=> ADDR17 +;// PA3 <0=> Output <1=> ADDR18 +;// PA4 <0=> Output <1=> ADDR19 +;// PA5 <0=> Output <1=> ADDR20 +;// PA6 <0=> Output <1=> ADDR21 +;// PA7 <0=> Output <1=> ADDR22 +;// PA8 <0=> Output <1=> ADDR23 +;// PA9 <0=> Output <1=> ADDR24 +;// +PIOA_SETUP EQU 1 +PCONA_Val EQU 0x000003FF + +;// Port B +;// PB0 <0=> Output <1=> SCKE +;// PB1 <0=> Output <1=> CKLK +;// PB2 <0=> Output <1=> nSCAS/nCAS2 +;// PB3 <0=> Output <1=> nSRAS/nCAS3 +;// PB4 <0=> Output <1=> nWBE2/nBE2/DQM2 +;// PB5 <0=> Output <1=> nWBE3/nBE3/DQM3 +;// PB6 <0=> Output <1=> nGCS1 +;// PB7 <0=> Output <1=> nGCS2 +;// PB8 <0=> Output <1=> nGCS3 +;// PB9 <0=> Output <1=> nGCS4 +;// PB10 <0=> Output <1=> nGCS5 +;// +PIOB_SETUP EQU 1 +PCONB_Val EQU 0x000007FF + +;// Port C +;// PC0 <0=> Input <1=> Output <2=> DATA16 <3=> IISLRCK +;// PC1 <0=> Input <1=> Output <2=> DATA17 <3=> IISDO +;// PC2 <0=> Input <1=> Output <2=> DATA18 <3=> IISDI +;// PC3 <0=> Input <1=> Output <2=> DATA19 <3=> IISCLK +;// PC4 <0=> Input <1=> Output <2=> DATA20 <3=> VD7 +;// PC5 <0=> Input <1=> Output <2=> DATA21 <3=> VD6 +;// PC6 <0=> Input <1=> Output <2=> DATA22 <3=> VD5 +;// PC7 <0=> Input <1=> Output <2=> DATA23 <3=> VD4 +;// PC8 <0=> Input <1=> Output <2=> DATA24 <3=> nXDACK1 +;// PC9 <0=> Input <1=> Output <2=> DATA25 <3=> nXDREQ1 +;// PC10 <0=> Input <1=> Output <2=> DATA26 <3=> nRTS1 +;// PC11 <0=> Input <1=> Output <2=> DATA27 <3=> nCTS1 +;// PC12 <0=> Input <1=> Output <2=> DATA28 <3=> TxD1 +;// PC13 <0=> Input <1=> Output <2=> DATA29 <3=> RxD1 +;// PC14 <0=> Input <1=> Output <2=> DATA30 <3=> nRTS0 +;// PC15 <0=> Input <1=> Output <2=> DATA31 <3=> nCTS0 +;// Pull-up Resistors +;// PC0 Pull-up <0=> Enabled <1=> Disabled +;// PC1 Pull-up <0=> Enabled <1=> Disabled +;// PC2 Pull-up <0=> Enabled <1=> Disabled +;// PC3 Pull-up <0=> Enabled <1=> Disabled +;// PC4 Pull-up <0=> Enabled <1=> Disabled +;// PC5 Pull-up <0=> Enabled <1=> Disabled +;// PC6 Pull-up <0=> Enabled <1=> Disabled +;// PC7 Pull-up <0=> Enabled <1=> Disabled +;// PC8 Pull-up <0=> Enabled <1=> Disabled +;// PC9 Pull-up <0=> Enabled <1=> Disabled +;// PC10 Pull-up <0=> Enabled <1=> Disabled +;// PC11 Pull-up <0=> Enabled <1=> Disabled +;// PC12 Pull-up <0=> Enabled <1=> Disabled +;// PC13 Pull-up <0=> Enabled <1=> Disabled +;// PC14 Pull-up <0=> Enabled <1=> Disabled +;// PC15 Pull-up <0=> Enabled <1=> Disabled +;// +;// +PIOC_SETUP EQU 1 +PCONC_Val EQU 0xAAAAAAAA +PUPC_Val EQU 0x00000000 + +;// Port D +;// PD0 <0=> Input <1=> Output <2=> VD0 <3=> Reserved +;// PD1 <0=> Input <1=> Output <2=> VD1 <3=> Reserved +;// PD2 <0=> Input <1=> Output <2=> VD2 <3=> Reserved +;// PD3 <0=> Input <1=> Output <2=> VD3 <3=> Reserved +;// PD4 <0=> Input <1=> Output <2=> VCLK <3=> Reserved +;// PD5 <0=> Input <1=> Output <2=> VLINE <3=> Reserved +;// PD6 <0=> Input <1=> Output <2=> VM <3=> Reserved +;// PD7 <0=> Input <1=> Output <2=> VFRAME <3=> Reserved +;// Pull-up Resistors +;// PD0 Pull-up <0=> Enabled <1=> Disabled +;// PD1 Pull-up <0=> Enabled <1=> Disabled +;// PD2 Pull-up <0=> Enabled <1=> Disabled +;// PD3 Pull-up <0=> Enabled <1=> Disabled +;// PD4 Pull-up <0=> Enabled <1=> Disabled +;// PD5 Pull-up <0=> Enabled <1=> Disabled +;// PD6 Pull-up <0=> Enabled <1=> Disabled +;// PD7 Pull-up <0=> Enabled <1=> Disabled +;// +;// +PIOD_SETUP EQU 1 +PCOND_Val EQU 0x00000000 +PUPD_Val EQU 0x00000000 + +;// Port E +;// PE0 <0=> Input <1=> Output <2=> Fpllo <3=> Fout +;// PE1 <0=> Input <1=> Output <2=> TxD0 <3=> Reserved +;// PE2 <0=> Input <1=> Output <2=> RxD0 <3=> Reserved +;// PE3 <0=> Input <1=> Output <2=> TOUT0 <3=> Reserved +;// PE4 <0=> Input <1=> Output <2=> TOUT1 <3=> TCLK +;// PE5 <0=> Input <1=> Output <2=> TOUT2 <3=> TCLK +;// PE6 <0=> Input <1=> Output <2=> TOUT3 <3=> VD6 +;// PE7 <0=> Input <1=> Output <2=> TOUT4 <3=> VD7 +;// PE8 <0=> Input <1=> Output <2=> CODECLK <3=> Reserved +;// Pull-up Resistors +;// PE0 Pull-up <0=> Enabled <1=> Disabled +;// PE1 Pull-up <0=> Enabled <1=> Disabled +;// PE2 Pull-up <0=> Enabled <1=> Disabled +;// PE3 Pull-up <0=> Enabled <1=> Disabled +;// PE4 Pull-up <0=> Enabled <1=> Disabled +;// PE5 Pull-up <0=> Enabled <1=> Disabled +;// PE6 Pull-up <0=> Enabled <1=> Disabled +;// PE7 Pull-up <0=> Enabled <1=> Disabled +;// PE8 Pull-up <0=> Enabled <1=> Disabled +;// +;// +PIOE_SETUP EQU 1 +PCONE_Val EQU 0x00000000 +PUPE_Val EQU 0x00000000 + +;// Port F +;// PF0 <0=> Input <1=> Output <2=> IICSCL <3=> Reserved +;// PF1 <0=> Input <1=> Output <2=> IICSDA <3=> Reserved +;// PF2 <0=> Input <1=> Output <2=> nWAIT <3=> Reserved +;// PF3 <0=> Input <1=> Output <2=> nXBACK <3=> nXDACK0 +;// PF4 <0=> Input <1=> Output <2=> nXBREQ <3=> nXDREQ0 +;// PF5 <0=> Input <1=> Output <2=> nRTS1 <3=> SIOTxD +;// <4=> IISLRCK <5=> Reserved <6=> Reserved <7=> Reserved +;// PF6 <0=> Input <1=> Output <2=> TxD1 <3=> SIORDY +;// <4=> IISDO <5=> Reserved <6=> Reserved <7=> Reserved +;// PF7 <0=> Input <1=> Output <2=> RxD1 <3=> SIORxD +;// <4=> IISDI <5=> Reserved <6=> Reserved <7=> Reserved +;// PF8 <0=> Input <1=> Output <2=> nCTS1 <3=> SIOCLK +;// <4=> IISCLK <5=> Reserved <6=> Reserved <7=> Reserved +;// Pull-up Resistors +;// PF0 Pull-up <0=> Enabled <1=> Disabled +;// PF1 Pull-up <0=> Enabled <1=> Disabled +;// PF2 Pull-up <0=> Enabled <1=> Disabled +;// PF3 Pull-up <0=> Enabled <1=> Disabled +;// PF4 Pull-up <0=> Enabled <1=> Disabled +;// PF5 Pull-up <0=> Enabled <1=> Disabled +;// PF6 Pull-up <0=> Enabled <1=> Disabled +;// PF7 Pull-up <0=> Enabled <1=> Disabled +;// PF8 Pull-up <0=> Enabled <1=> Disabled +;// +;// +PIOF_SETUP EQU 1 +PCONF_Val EQU 0x00000000 +PUPF_Val EQU 0x00000000 + +;// Port G +;// PG0 <0=> Input <1=> Output <2=> VD4 <3=> EINT0 +;// PG1 <0=> Input <1=> Output <2=> VD5 <3=> EINT1 +;// PG2 <0=> Input <1=> Output <2=> nCTS0 <3=> EINT2 +;// PG3 <0=> Input <1=> Output <2=> nRTS0 <3=> EINT3 +;// PG4 <0=> Input <1=> Output <2=> IISCLK <3=> EINT4 +;// PG5 <0=> Input <1=> Output <2=> IISDI <3=> EINT5 +;// PG6 <0=> Input <1=> Output <2=> IISDO <3=> EINT6 +;// PG7 <0=> Input <1=> Output <2=> IISLRCK <3=> EINT7 +;// Pull-up Resistors +;// PG0 Pull-up <0=> Enabled <1=> Disabled +;// PG1 Pull-up <0=> Enabled <1=> Disabled +;// PG2 Pull-up <0=> Enabled <1=> Disabled +;// PG3 Pull-up <0=> Enabled <1=> Disabled +;// PG4 Pull-up <0=> Enabled <1=> Disabled +;// PG5 Pull-up <0=> Enabled <1=> Disabled +;// PG6 Pull-up <0=> Enabled <1=> Disabled +;// PG7 Pull-up <0=> Enabled <1=> Disabled +;// +;// +PIOG_SETUP EQU 1 +PCONG_Val EQU 0x00000000 +PUPG_Val EQU 0x00000000 + +;// Special Pull-up +;// SPUCR0: DATA[7:0] Pull-up Resistor +;// <0=> Enabled <1=> Disabled +;// SPUCR1: DATA[15:8] Pull-up Resistor +;// <0=> Enabled <1=> Disabled +;// HZ@STOP +;// <0=> Prevoius state of PAD +;// <1=> HZ @ Stop +;// +PSPU_SETUP EQU 1 +SPUCR_Val EQU 0x00000004 + +;// + + + 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 0000000000000000000000000000000000000000..546d9b2ea09231b2c1d4278fd8c9beda427bcd45 --- /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 +#include + +#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"); +} + +/*@}*/