import lm3s, lpc2148/lpc2478, x86/qemu, AT91SAM7S/7X, s3c44b0, STM32F103ZE bsp
git-svn-id: https://rt-thread.googlecode.com/svn/trunk@4 bbd45198-f89e-11dd-88c7-29a3b14d5316
This commit is contained in:
parent
1d74273319
commit
99922cdf19
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -0,0 +1,42 @@
|
||||||
|
/*
|
||||||
|
* File : cpu.c
|
||||||
|
* This file is part of RT-Thread RTOS
|
||||||
|
* COPYRIGHT (C) 2006, RT-Thread Develop Team
|
||||||
|
*
|
||||||
|
* The license and distribution terms for this file may be
|
||||||
|
* found in the file LICENSE in this distribution or at
|
||||||
|
* http://www.rt-thread.org/license/LICENSE
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2006-08-23 Bernard first version
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <rtthread.h>
|
||||||
|
#include "AT91SAM7S.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @addtogroup AT91SAM7
|
||||||
|
*/
|
||||||
|
/*@{*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* this function will reset CPU
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void rt_hw_cpu_reset()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* this function will shutdown CPU
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void rt_hw_cpu_shutdown()
|
||||||
|
{
|
||||||
|
rt_kprintf("shutdown...\n");
|
||||||
|
|
||||||
|
while (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*@}*/
|
|
@ -0,0 +1,91 @@
|
||||||
|
/*
|
||||||
|
* File : trap.c
|
||||||
|
* This file is part of RT-Thread RTOS
|
||||||
|
* COPYRIGHT (C) 2006, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* The license and distribution terms for this file may be
|
||||||
|
* found in the file LICENSE in this distribution or at
|
||||||
|
* http://openlab.rt-thread.com/license/LICENSE
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2006-08-23 Bernard first version
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <rtthread.h>
|
||||||
|
#include "AT91SAM7S.h"
|
||||||
|
|
||||||
|
#define MAX_HANDLERS 32
|
||||||
|
|
||||||
|
extern rt_uint32_t rt_interrupt_nest;
|
||||||
|
|
||||||
|
rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread;
|
||||||
|
rt_uint32_t rt_thread_switch_interrput_flag;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @addtogroup AT91SAM7
|
||||||
|
*/
|
||||||
|
/*@{*/
|
||||||
|
|
||||||
|
void rt_hw_interrupt_handler(int vector)
|
||||||
|
{
|
||||||
|
rt_kprintf("Unhandled interrupt %d occured!!!\n", vector);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function will initialize hardware interrupt
|
||||||
|
*/
|
||||||
|
void rt_hw_interrupt_init()
|
||||||
|
{
|
||||||
|
rt_base_t index;
|
||||||
|
|
||||||
|
for (index = 0; index < MAX_HANDLERS; index ++)
|
||||||
|
{
|
||||||
|
AT91C_AIC_SVR(index) = (rt_uint32_t)rt_hw_interrupt_handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* init interrupt nest, and context in thread sp */
|
||||||
|
rt_interrupt_nest = 0;
|
||||||
|
rt_interrupt_from_thread = 0;
|
||||||
|
rt_interrupt_to_thread = 0;
|
||||||
|
rt_thread_switch_interrput_flag = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function will mask a interrupt.
|
||||||
|
* @param vector the interrupt number
|
||||||
|
*/
|
||||||
|
void rt_hw_interrupt_mask(int vector)
|
||||||
|
{
|
||||||
|
/* disable interrupt */
|
||||||
|
AT91C_AIC_IDCR = 1 << vector;
|
||||||
|
|
||||||
|
/* clear interrupt */
|
||||||
|
AT91C_AIC_ICCR = 1 << vector;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function will un-mask a interrupt.
|
||||||
|
* @param vector the interrupt number
|
||||||
|
*/
|
||||||
|
void rt_hw_interrupt_umask(int vector)
|
||||||
|
{
|
||||||
|
AT91C_AIC_IECR = 1 << vector;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function will install a interrupt service routine to a interrupt.
|
||||||
|
* @param vector the interrupt number
|
||||||
|
* @param new_handler the interrupt service routine to be installed
|
||||||
|
* @param old_handler the old interrupt service routine
|
||||||
|
*/
|
||||||
|
void rt_hw_interrupt_install(int vector, rt_isr_handler_t new_handler, rt_isr_handler_t *old_handler)
|
||||||
|
{
|
||||||
|
if(vector >= 0 && vector < MAX_HANDLERS)
|
||||||
|
{
|
||||||
|
if (*old_handler != RT_NULL) *old_handler = (rt_isr_handler_t)AT91C_AIC_SVR(vector);
|
||||||
|
if (new_handler != RT_NULL) AT91C_AIC_SVR(vector) = (rt_uint32_t)new_handler;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*@}*/
|
|
@ -0,0 +1,387 @@
|
||||||
|
/*
|
||||||
|
* File : serial.c
|
||||||
|
* This file is part of RT-Thread RTOS
|
||||||
|
* COPYRIGHT (C) 2006, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* The license and distribution terms for this file may be
|
||||||
|
* found in the file LICENSE in this distribution or at
|
||||||
|
* http://openlab.rt-thread.com/license/LICENSE
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2006-08-23 Bernard first version
|
||||||
|
* 2009-05-14 Bernard add RT-THread device interface
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <rthw.h>
|
||||||
|
#include <rtthread.h>
|
||||||
|
|
||||||
|
#include "AT91SAM7S.h"
|
||||||
|
#include "serial.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @addtogroup AT91SAM7
|
||||||
|
*/
|
||||||
|
/*@{*/
|
||||||
|
typedef volatile rt_uint32_t REG32;
|
||||||
|
struct rt_at91serial_hw
|
||||||
|
{
|
||||||
|
REG32 US_CR; // Control Register
|
||||||
|
REG32 US_MR; // Mode Register
|
||||||
|
REG32 US_IER; // Interrupt Enable Register
|
||||||
|
REG32 US_IDR; // Interrupt Disable Register
|
||||||
|
REG32 US_IMR; // Interrupt Mask Register
|
||||||
|
REG32 US_CSR; // Channel Status Register
|
||||||
|
REG32 US_RHR; // Receiver Holding Register
|
||||||
|
REG32 US_THR; // Transmitter Holding Register
|
||||||
|
REG32 US_BRGR; // Baud Rate Generator Register
|
||||||
|
REG32 US_RTOR; // Receiver Time-out Register
|
||||||
|
REG32 US_TTGR; // Transmitter Time-guard Register
|
||||||
|
REG32 Reserved0[5]; //
|
||||||
|
REG32 US_FIDI; // FI_DI_Ratio Register
|
||||||
|
REG32 US_NER; // Nb Errors Register
|
||||||
|
REG32 Reserved1[1]; //
|
||||||
|
REG32 US_IF; // IRDA_FILTER Register
|
||||||
|
REG32 Reserved2[44]; //
|
||||||
|
REG32 US_RPR; // Receive Pointer Register
|
||||||
|
REG32 US_RCR; // Receive Counter Register
|
||||||
|
REG32 US_TPR; // Transmit Pointer Register
|
||||||
|
REG32 US_TCR; // Transmit Counter Register
|
||||||
|
REG32 US_RNPR; // Receive Next Pointer Register
|
||||||
|
REG32 US_RNCR; // Receive Next Counter Register
|
||||||
|
REG32 US_TNPR; // Transmit Next Pointer Register
|
||||||
|
REG32 US_TNCR; // Transmit Next Counter Register
|
||||||
|
REG32 US_PTCR; // PDC Transfer Control Register
|
||||||
|
REG32 US_PTSR; // PDC Transfer Status Register
|
||||||
|
};
|
||||||
|
|
||||||
|
struct rt_at91serial
|
||||||
|
{
|
||||||
|
struct rt_device parent;
|
||||||
|
|
||||||
|
struct rt_at91serial_hw* hw_base;
|
||||||
|
rt_uint16_t peripheral_id;
|
||||||
|
rt_uint32_t baudrate;
|
||||||
|
|
||||||
|
/* reception field */
|
||||||
|
rt_uint16_t save_index, read_index;
|
||||||
|
rt_uint8_t rx_buffer[RT_UART_RX_BUFFER_SIZE];
|
||||||
|
};
|
||||||
|
#ifdef RT_USING_UART1
|
||||||
|
struct rt_at91serial serial1;
|
||||||
|
#endif
|
||||||
|
#ifdef RT_USING_UART2
|
||||||
|
struct rt_at91serial serial2;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void rt_hw_serial_isr(int irqno)
|
||||||
|
{
|
||||||
|
rt_base_t level;
|
||||||
|
struct rt_device* device;
|
||||||
|
struct rt_at91serial* serial = RT_NULL;
|
||||||
|
|
||||||
|
if (irqno == AT91C_ID_US0)
|
||||||
|
{
|
||||||
|
#ifdef RT_USING_UART1
|
||||||
|
/* serial 1 */
|
||||||
|
serial = &serial1;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else if (irqno == AT91C_ID_US1)
|
||||||
|
{
|
||||||
|
#ifdef RT_USING_UART2
|
||||||
|
/* serial 2 */
|
||||||
|
serial = &serial2;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
RT_ASSERT(serial != RT_NULL);
|
||||||
|
|
||||||
|
/* get generic device object */
|
||||||
|
device = (rt_device_t)serial;
|
||||||
|
|
||||||
|
/* disable interrupt */
|
||||||
|
level = rt_hw_interrupt_disable();
|
||||||
|
|
||||||
|
/* get received character */
|
||||||
|
serial->rx_buffer[serial->save_index] = serial->hw_base->US_RHR;
|
||||||
|
|
||||||
|
/* move to next position */
|
||||||
|
serial->save_index ++;
|
||||||
|
if (serial->save_index >= RT_UART_RX_BUFFER_SIZE)
|
||||||
|
serial->save_index = 0;
|
||||||
|
|
||||||
|
/* if the next position is read index, discard this 'read char' */
|
||||||
|
if (serial->save_index == serial->read_index)
|
||||||
|
{
|
||||||
|
serial->read_index ++;
|
||||||
|
if (serial->read_index >= RT_UART_RX_BUFFER_SIZE)
|
||||||
|
serial->read_index = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* enable interrupt */
|
||||||
|
rt_hw_interrupt_enable(level);
|
||||||
|
|
||||||
|
/* indicate to upper layer application */
|
||||||
|
if (device->rx_indicate != RT_NULL)
|
||||||
|
device->rx_indicate(device, 1);
|
||||||
|
|
||||||
|
/* ack interrupt */
|
||||||
|
AT91C_AIC_EOICR = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static rt_err_t rt_serial_init (rt_device_t dev)
|
||||||
|
{
|
||||||
|
rt_uint32_t bd;
|
||||||
|
struct rt_at91serial* serial = (struct rt_at91serial*) dev;
|
||||||
|
|
||||||
|
RT_ASSERT(serial != RT_NULL);
|
||||||
|
/* must be US0 or US1 */
|
||||||
|
RT_ASSERT((serial->peripheral_id != AT91C_ID_US0) &&
|
||||||
|
(serial->peripheral_id != AT91C_ID_US1));
|
||||||
|
|
||||||
|
/* Enable Clock for USART */
|
||||||
|
AT91C_PMC_PCER = 1 << serial->peripheral_id;
|
||||||
|
|
||||||
|
/* Enable RxD0 and TxDO Pin */
|
||||||
|
if (serial->peripheral_id == AT91C_ID_US0)
|
||||||
|
{
|
||||||
|
/* set pinmux */
|
||||||
|
AT91C_PIO_PDR = (1 << 5) | (1 << 6);
|
||||||
|
}
|
||||||
|
else if (serial->peripheral_id == AT91C_ID_US1)
|
||||||
|
{
|
||||||
|
/* set pinmux */
|
||||||
|
AT91C_PIO_PDR = (1 << 21) | (1 << 22);
|
||||||
|
}
|
||||||
|
|
||||||
|
serial->hw_base->US_CR = AT91C_US_RSTRX | /* Reset Receiver */
|
||||||
|
AT91C_US_RSTTX | /* Reset Transmitter */
|
||||||
|
AT91C_US_RXDIS | /* Receiver Disable */
|
||||||
|
AT91C_US_TXDIS; /* Transmitter Disable */
|
||||||
|
|
||||||
|
serial->hw_base->US_MR = AT91C_US_USMODE_NORMAL | /* Normal Mode */
|
||||||
|
AT91C_US_CLKS_CLOCK | /* Clock = MCK */
|
||||||
|
AT91C_US_CHRL_8_BITS | /* 8-bit Data */
|
||||||
|
AT91C_US_PAR_NONE | /* No Parity */
|
||||||
|
AT91C_US_NBSTOP_1_BIT; /* 1 Stop Bit */
|
||||||
|
|
||||||
|
/* set baud rate divisor */
|
||||||
|
bd = ((MCK*10)/(serial->baudrate * 16));
|
||||||
|
if ((bd % 10) >= 5) bd = (bd / 10) + 1;
|
||||||
|
else bd /= 10;
|
||||||
|
|
||||||
|
serial->hw_base->US_BRGR = bd;
|
||||||
|
serial->hw_base->US_CR = AT91C_US_RXEN | /* Receiver Enable */
|
||||||
|
AT91C_US_TXEN; /* Transmitter Enable */
|
||||||
|
|
||||||
|
/* reset rx index */
|
||||||
|
serial->save_index = 0;
|
||||||
|
serial->read_index = 0;
|
||||||
|
|
||||||
|
/* reset rx buffer */
|
||||||
|
rt_memset(serial->rx_buffer, 0, RT_UART_RX_BUFFER_SIZE);
|
||||||
|
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static rt_err_t rt_serial_open(rt_device_t dev, rt_uint16_t oflag)
|
||||||
|
{
|
||||||
|
struct rt_at91serial *serial = (struct rt_at91serial*)dev;
|
||||||
|
RT_ASSERT(serial != RT_NULL);
|
||||||
|
|
||||||
|
if (dev->flag & RT_DEVICE_FLAG_INT_RX)
|
||||||
|
{
|
||||||
|
/* enable UART rx interrupt */
|
||||||
|
serial->hw_base->US_IER = 1 << 0; /* RxReady interrupt */
|
||||||
|
serial->hw_base->US_IMR |= 1 << 0; /* umask RxReady interrupt */
|
||||||
|
|
||||||
|
/* install UART handler */
|
||||||
|
rt_hw_interrupt_install(serial->peripheral_id, rt_hw_serial_isr, RT_NULL);
|
||||||
|
AT91C_AIC_SMR(serial->peripheral_id) = 5 | (0x01 << 5);
|
||||||
|
rt_hw_interrupt_umask(serial->peripheral_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static rt_err_t rt_serial_close(rt_device_t dev)
|
||||||
|
{
|
||||||
|
struct rt_at91serial *serial = (struct rt_at91serial*)dev;
|
||||||
|
RT_ASSERT(serial != RT_NULL);
|
||||||
|
|
||||||
|
if (dev->flag & RT_DEVICE_FLAG_INT_RX)
|
||||||
|
{
|
||||||
|
/* disable interrupt */
|
||||||
|
serial->hw_base->US_IDR = 1 << 0; /* RxReady interrupt */
|
||||||
|
serial->hw_base->US_IMR &= ~(1 << 0); /* mask RxReady interrupt */
|
||||||
|
}
|
||||||
|
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static rt_size_t rt_serial_read (rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
|
||||||
|
{
|
||||||
|
rt_uint8_t* ptr;
|
||||||
|
struct rt_at91serial *serial = (struct rt_at91serial*)dev;
|
||||||
|
RT_ASSERT(serial != RT_NULL);
|
||||||
|
|
||||||
|
/* point to buffer */
|
||||||
|
ptr = (rt_uint8_t*) buffer;
|
||||||
|
|
||||||
|
if (dev->flag & RT_DEVICE_FLAG_INT_RX)
|
||||||
|
{
|
||||||
|
while (size)
|
||||||
|
{
|
||||||
|
/* interrupt receive */
|
||||||
|
rt_base_t level;
|
||||||
|
|
||||||
|
/* disable interrupt */
|
||||||
|
level = rt_hw_interrupt_disable();
|
||||||
|
if (serial->read_index != serial->save_index)
|
||||||
|
{
|
||||||
|
*ptr = serial->rx_buffer[serial->read_index];
|
||||||
|
|
||||||
|
serial->read_index ++;
|
||||||
|
if (serial->read_index >= RT_UART_RX_BUFFER_SIZE)
|
||||||
|
serial->read_index = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* no data in rx buffer */
|
||||||
|
|
||||||
|
/* enable interrupt */
|
||||||
|
rt_hw_interrupt_enable(level);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* enable interrupt */
|
||||||
|
rt_hw_interrupt_enable(level);
|
||||||
|
|
||||||
|
ptr ++; size --;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (rt_uint32_t)ptr - (rt_uint32_t)buffer;
|
||||||
|
}
|
||||||
|
else if (dev->flag & RT_DEVICE_FLAG_DMA_RX)
|
||||||
|
{
|
||||||
|
/* not support right now */
|
||||||
|
RT_ASSERT(0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* poll mode */
|
||||||
|
while (size)
|
||||||
|
{
|
||||||
|
/* Wait for Full Rx Buffer */
|
||||||
|
while (!(serial->hw_base->US_CSR & AT91C_US_RXRDY));
|
||||||
|
|
||||||
|
/* Read Character */
|
||||||
|
*ptr = serial->hw_base->US_RHR;
|
||||||
|
ptr ++;
|
||||||
|
size --;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (rt_size_t)ptr - (rt_size_t)buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static rt_size_t rt_serial_write (rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
|
||||||
|
{
|
||||||
|
rt_uint8_t* ptr;
|
||||||
|
struct rt_at91serial *serial = (struct rt_at91serial*)dev;
|
||||||
|
RT_ASSERT(serial != RT_NULL);
|
||||||
|
|
||||||
|
ptr = (rt_uint8_t*) buffer;
|
||||||
|
if (dev->open_flag & RT_DEVICE_OFLAG_WRONLY)
|
||||||
|
{
|
||||||
|
if (dev->flag & RT_DEVICE_FLAG_STREAM)
|
||||||
|
{
|
||||||
|
/* it's a stream mode device */
|
||||||
|
while (size)
|
||||||
|
{
|
||||||
|
/* stream mode */
|
||||||
|
if (*ptr == '\n')
|
||||||
|
{
|
||||||
|
while (!(serial->hw_base->US_CSR & AT91C_US_TXRDY));
|
||||||
|
serial->hw_base->US_THR = '\r';
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Wait for Empty Tx Buffer */
|
||||||
|
while (!(serial->hw_base->US_CSR & AT91C_US_TXRDY));
|
||||||
|
|
||||||
|
/* Transmit Character */
|
||||||
|
serial->hw_base->US_THR = *ptr;
|
||||||
|
ptr ++; size --;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
while (size)
|
||||||
|
{
|
||||||
|
/* Wait for Empty Tx Buffer */
|
||||||
|
while (!(serial->hw_base->US_CSR & AT91C_US_TXRDY));
|
||||||
|
|
||||||
|
/* Transmit Character */
|
||||||
|
serial->hw_base->US_THR = *ptr;
|
||||||
|
ptr ++; size --;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (rt_size_t)ptr - (rt_size_t)buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
static rt_err_t rt_serial_control (rt_device_t dev, rt_uint8_t cmd, void *args)
|
||||||
|
{
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
rt_err_t rt_hw_serial_init()
|
||||||
|
{
|
||||||
|
rt_device_t device;
|
||||||
|
|
||||||
|
#ifdef RT_USING_UART1
|
||||||
|
device = (rt_device_t) &serial1;
|
||||||
|
|
||||||
|
/* init serial device private data */
|
||||||
|
serial1.hw_base = (struct rt_at91serial_hw*)AT91C_BASE_US0;
|
||||||
|
serial1.peripheral_id = AT91C_ID_US0;
|
||||||
|
serial1.baudrate = 115200;
|
||||||
|
|
||||||
|
/* set device virtual interface */
|
||||||
|
device->init = rt_serial_init;
|
||||||
|
device->open = rt_serial_open;
|
||||||
|
device->close = rt_serial_close;
|
||||||
|
device->read = rt_serial_read;
|
||||||
|
device->write = rt_serial_write;
|
||||||
|
device->control = rt_serial_control;
|
||||||
|
|
||||||
|
/* register uart1 on device subsystem */
|
||||||
|
rt_device_register(device, "uart1", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef RT_USING_UART2
|
||||||
|
device = (rt_device_t) &serial2;
|
||||||
|
|
||||||
|
serial2.hw_base = (struct rt_at91serial_hw*)AT91C_BASE_US1;
|
||||||
|
serial2.peripheral_id = AT91C_ID_US1;
|
||||||
|
serial2.baudrate = 115200;
|
||||||
|
|
||||||
|
/* set device virtual interface */
|
||||||
|
device->init = rt_serial_init;
|
||||||
|
device->open = rt_serial_open;
|
||||||
|
device->close = rt_serial_close;
|
||||||
|
device->read = rt_serial_read;
|
||||||
|
device->write = rt_serial_write;
|
||||||
|
device->control = rt_serial_control;
|
||||||
|
|
||||||
|
/* register uart2 on device subsystem */
|
||||||
|
rt_device_register(device, "uart2", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*@}*/
|
|
@ -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
|
|
@ -0,0 +1,60 @@
|
||||||
|
/*
|
||||||
|
* File : stack.c
|
||||||
|
* This file is part of RT-Thread RTOS
|
||||||
|
* COPYRIGHT (C) 2006, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* The license and distribution terms for this file may be
|
||||||
|
* found in the file LICENSE in this distribution or at
|
||||||
|
* http://openlab.rt-thread.com/license/LICENSE
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2006-08-23 Bernard the first version
|
||||||
|
*/
|
||||||
|
#include <rtthread.h>
|
||||||
|
#include "AT91SAM7S.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @addtogroup AT91SAM7
|
||||||
|
*/
|
||||||
|
/*@{*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function will initialize thread stack
|
||||||
|
*
|
||||||
|
* @param tentry the entry of thread
|
||||||
|
* @param parameter the parameter of entry
|
||||||
|
* @param stack_addr the beginning stack address
|
||||||
|
* @param texit the function will be called when thread exit
|
||||||
|
*
|
||||||
|
* @return stack address
|
||||||
|
*/
|
||||||
|
rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter,
|
||||||
|
rt_uint8_t *stack_addr, void *texit)
|
||||||
|
{
|
||||||
|
unsigned long *stk;
|
||||||
|
|
||||||
|
stk = (unsigned long *)stack_addr;
|
||||||
|
*(stk) = (unsigned long)tentry; /* entry point */
|
||||||
|
*(--stk) = (unsigned long)texit; /* lr */
|
||||||
|
*(--stk) = 0; /* r12 */
|
||||||
|
*(--stk) = 0; /* r11 */
|
||||||
|
*(--stk) = 0; /* r10 */
|
||||||
|
*(--stk) = 0; /* r9 */
|
||||||
|
*(--stk) = 0; /* r8 */
|
||||||
|
*(--stk) = 0; /* r7 */
|
||||||
|
*(--stk) = 0; /* r6 */
|
||||||
|
*(--stk) = 0; /* r5 */
|
||||||
|
*(--stk) = 0; /* r4 */
|
||||||
|
*(--stk) = 0; /* r3 */
|
||||||
|
*(--stk) = 0; /* r2 */
|
||||||
|
*(--stk) = 0; /* r1 */
|
||||||
|
*(--stk) = (unsigned long)parameter; /* r0 : argument */
|
||||||
|
*(--stk) = SVCMODE; /* cpsr */
|
||||||
|
*(--stk) = SVCMODE; /* spsr */
|
||||||
|
|
||||||
|
/* return task's current stack address */
|
||||||
|
return (rt_uint8_t *)stk;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*@}*/
|
|
@ -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 */
|
|
@ -0,0 +1,498 @@
|
||||||
|
;/*****************************************************************************/
|
||||||
|
;/* SAM7.S: Startup file for Atmel AT91SAM7 device series */
|
||||||
|
;/*****************************************************************************/
|
||||||
|
;/* <<< Use Configuration Wizard in Context Menu >>> */
|
||||||
|
;/*****************************************************************************/
|
||||||
|
;/* This file is part of the uVision/ARM development tools. */
|
||||||
|
;/* Copyright (c) 2005-2006 Keil Software. All rights reserved. */
|
||||||
|
;/* This software may only be used under the terms of a valid, current, */
|
||||||
|
;/* end user licence from KEIL for a compatible version of KEIL software */
|
||||||
|
;/* development tools. Nothing else gives you the right to use this software. */
|
||||||
|
;/*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
;/*
|
||||||
|
; * The SAM7.S code is executed after CPU Reset. This file may be
|
||||||
|
; * translated with the following SET symbols. In uVision these SET
|
||||||
|
; * symbols are entered under Options - ASM - Define.
|
||||||
|
; *
|
||||||
|
; * REMAP: when set the startup code remaps exception vectors from
|
||||||
|
; * on-chip RAM to address 0.
|
||||||
|
; *
|
||||||
|
; * RAM_INTVEC: when set the startup code copies exception vectors
|
||||||
|
; * from on-chip Flash to on-chip RAM.
|
||||||
|
; */
|
||||||
|
|
||||||
|
|
||||||
|
; Standard definitions of Mode bits and Interrupt (I & F) flags in PSRs
|
||||||
|
|
||||||
|
Mode_USR EQU 0x10
|
||||||
|
Mode_FIQ EQU 0x11
|
||||||
|
Mode_IRQ EQU 0x12
|
||||||
|
Mode_SVC EQU 0x13
|
||||||
|
Mode_ABT EQU 0x17
|
||||||
|
Mode_UND EQU 0x1B
|
||||||
|
Mode_SYS EQU 0x1F
|
||||||
|
|
||||||
|
I_Bit EQU 0x80 ; when I bit is set, IRQ is disabled
|
||||||
|
F_Bit EQU 0x40 ; when F bit is set, FIQ is disabled
|
||||||
|
|
||||||
|
|
||||||
|
; Internal Memory Base Addresses
|
||||||
|
FLASH_BASE EQU 0x00100000
|
||||||
|
RAM_BASE EQU 0x00200000
|
||||||
|
|
||||||
|
|
||||||
|
;// <h> Stack Configuration (Stack Sizes in Bytes)
|
||||||
|
;// <o0> Undefined Mode <0x0-0xFFFFFFFF:8>
|
||||||
|
;// <o1> Supervisor Mode <0x0-0xFFFFFFFF:8>
|
||||||
|
;// <o2> Abort Mode <0x0-0xFFFFFFFF:8>
|
||||||
|
;// <o3> Fast Interrupt Mode <0x0-0xFFFFFFFF:8>
|
||||||
|
;// <o4> Interrupt Mode <0x0-0xFFFFFFFF:8>
|
||||||
|
;// <o5> User/System Mode <0x0-0xFFFFFFFF:8>
|
||||||
|
;// </h>
|
||||||
|
|
||||||
|
UND_Stack_Size EQU 0x00000000
|
||||||
|
SVC_Stack_Size EQU 0x00000100
|
||||||
|
ABT_Stack_Size EQU 0x00000000
|
||||||
|
FIQ_Stack_Size EQU 0x00000000
|
||||||
|
IRQ_Stack_Size EQU 0x00000100
|
||||||
|
USR_Stack_Size EQU 0x00000100
|
||||||
|
|
||||||
|
ISR_Stack_Size EQU (UND_Stack_Size + SVC_Stack_Size + ABT_Stack_Size + \
|
||||||
|
FIQ_Stack_Size + IRQ_Stack_Size)
|
||||||
|
|
||||||
|
AREA STACK, NOINIT, READWRITE, ALIGN=3
|
||||||
|
|
||||||
|
Stack_Mem SPACE USR_Stack_Size
|
||||||
|
__initial_sp SPACE ISR_Stack_Size
|
||||||
|
Stack_Top
|
||||||
|
|
||||||
|
|
||||||
|
;// <h> Heap Configuration
|
||||||
|
;// <o> Heap Size (in Bytes) <0x0-0xFFFFFFFF>
|
||||||
|
;// </h>
|
||||||
|
|
||||||
|
Heap_Size EQU 0x00000000
|
||||||
|
|
||||||
|
AREA HEAP, NOINIT, READWRITE, ALIGN=3
|
||||||
|
__heap_base
|
||||||
|
Heap_Mem SPACE Heap_Size
|
||||||
|
__heap_limit
|
||||||
|
|
||||||
|
|
||||||
|
; Reset Controller (RSTC) definitions
|
||||||
|
RSTC_BASE EQU 0xFFFFFD00 ; RSTC Base Address
|
||||||
|
RSTC_MR EQU 0x08 ; RSTC_MR Offset
|
||||||
|
|
||||||
|
;/*
|
||||||
|
;// <e> Reset Controller (RSTC)
|
||||||
|
;// <o1.0> URSTEN: User Reset Enable
|
||||||
|
;// <i> Enables NRST Pin to generate Reset
|
||||||
|
;// <o1.8..11> ERSTL: External Reset Length <0-15>
|
||||||
|
;// <i> External Reset Time in 2^(ERSTL+1) Slow Clock Cycles
|
||||||
|
;// </e>
|
||||||
|
;*/
|
||||||
|
RSTC_SETUP EQU 1
|
||||||
|
RSTC_MR_Val EQU 0xA5000401
|
||||||
|
|
||||||
|
|
||||||
|
; Embedded Flash Controller (EFC) definitions
|
||||||
|
EFC_BASE EQU 0xFFFFFF00 ; EFC Base Address
|
||||||
|
EFC0_FMR EQU 0x60 ; EFC0_FMR Offset
|
||||||
|
EFC1_FMR EQU 0x70 ; EFC1_FMR Offset
|
||||||
|
|
||||||
|
;// <e> Embedded Flash Controller 0 (EFC0)
|
||||||
|
;// <o1.16..23> FMCN: Flash Microsecond Cycle Number <0-255>
|
||||||
|
;// <i> Number of Master Clock Cycles in 1us
|
||||||
|
;// <o1.8..9> FWS: Flash Wait State
|
||||||
|
;// <0=> Read: 1 cycle / Write: 2 cycles
|
||||||
|
;// <1=> Read: 2 cycle / Write: 3 cycles
|
||||||
|
;// <2=> Read: 3 cycle / Write: 4 cycles
|
||||||
|
;// <3=> Read: 4 cycle / Write: 4 cycles
|
||||||
|
;// </e>
|
||||||
|
EFC0_SETUP EQU 1
|
||||||
|
EFC0_FMR_Val EQU 0x00320100
|
||||||
|
|
||||||
|
;// <e> Embedded Flash Controller 1 (EFC1)
|
||||||
|
;// <o1.16..23> FMCN: Flash Microsecond Cycle Number <0-255>
|
||||||
|
;// <i> Number of Master Clock Cycles in 1us
|
||||||
|
;// <o1.8..9> FWS: Flash Wait State
|
||||||
|
;// <0=> Read: 1 cycle / Write: 2 cycles
|
||||||
|
;// <1=> Read: 2 cycle / Write: 3 cycles
|
||||||
|
;// <2=> Read: 3 cycle / Write: 4 cycles
|
||||||
|
;// <3=> Read: 4 cycle / Write: 4 cycles
|
||||||
|
;// </e>
|
||||||
|
EFC1_SETUP EQU 0
|
||||||
|
EFC1_FMR_Val EQU 0x00320100
|
||||||
|
|
||||||
|
|
||||||
|
; Watchdog Timer (WDT) definitions
|
||||||
|
WDT_BASE EQU 0xFFFFFD40 ; WDT Base Address
|
||||||
|
WDT_MR EQU 0x04 ; WDT_MR Offset
|
||||||
|
|
||||||
|
;// <e> Watchdog Timer (WDT)
|
||||||
|
;// <o1.0..11> WDV: Watchdog Counter Value <0-4095>
|
||||||
|
;// <o1.16..27> WDD: Watchdog Delta Value <0-4095>
|
||||||
|
;// <o1.12> WDFIEN: Watchdog Fault Interrupt Enable
|
||||||
|
;// <o1.13> WDRSTEN: Watchdog Reset Enable
|
||||||
|
;// <o1.14> WDRPROC: Watchdog Reset Processor
|
||||||
|
;// <o1.28> WDDBGHLT: Watchdog Debug Halt
|
||||||
|
;// <o1.29> WDIDLEHLT: Watchdog Idle Halt
|
||||||
|
;// <o1.15> WDDIS: Watchdog Disable
|
||||||
|
;// </e>
|
||||||
|
WDT_SETUP EQU 1
|
||||||
|
WDT_MR_Val EQU 0x00008000
|
||||||
|
|
||||||
|
|
||||||
|
; Power Mangement Controller (PMC) definitions
|
||||||
|
PMC_BASE EQU 0xFFFFFC00 ; PMC Base Address
|
||||||
|
PMC_MOR EQU 0x20 ; PMC_MOR Offset
|
||||||
|
PMC_MCFR EQU 0x24 ; PMC_MCFR Offset
|
||||||
|
PMC_PLLR EQU 0x2C ; PMC_PLLR Offset
|
||||||
|
PMC_MCKR EQU 0x30 ; PMC_MCKR Offset
|
||||||
|
PMC_SR EQU 0x68 ; PMC_SR Offset
|
||||||
|
PMC_MOSCEN EQU (1<<0) ; Main Oscillator Enable
|
||||||
|
PMC_OSCBYPASS EQU (1<<1) ; Main Oscillator Bypass
|
||||||
|
PMC_OSCOUNT EQU (0xFF<<8) ; Main OScillator Start-up Time
|
||||||
|
PMC_DIV EQU (0xFF<<0) ; PLL Divider
|
||||||
|
PMC_PLLCOUNT EQU (0x3F<<8) ; PLL Lock Counter
|
||||||
|
PMC_OUT EQU (0x03<<14) ; PLL Clock Frequency Range
|
||||||
|
PMC_MUL EQU (0x7FF<<16) ; PLL Multiplier
|
||||||
|
PMC_USBDIV EQU (0x03<<28) ; USB Clock Divider
|
||||||
|
PMC_CSS EQU (3<<0) ; Clock Source Selection
|
||||||
|
PMC_PRES EQU (7<<2) ; Prescaler Selection
|
||||||
|
PMC_MOSCS EQU (1<<0) ; Main Oscillator Stable
|
||||||
|
PMC_LOCK EQU (1<<2) ; PLL Lock Status
|
||||||
|
PMC_MCKRDY EQU (1<<3) ; Master Clock Status
|
||||||
|
|
||||||
|
;// <e> Power Mangement Controller (PMC)
|
||||||
|
;// <h> Main Oscillator
|
||||||
|
;// <o1.0> MOSCEN: Main Oscillator Enable
|
||||||
|
;// <o1.1> OSCBYPASS: Oscillator Bypass
|
||||||
|
;// <o1.8..15> OSCCOUNT: Main Oscillator Startup Time <0-255>
|
||||||
|
;// </h>
|
||||||
|
;// <h> Phase Locked Loop (PLL)
|
||||||
|
;// <o2.0..7> DIV: PLL Divider <0-255>
|
||||||
|
;// <o2.16..26> MUL: PLL Multiplier <0-2047>
|
||||||
|
;// <i> PLL Output is multiplied by MUL+1
|
||||||
|
;// <o2.14..15> OUT: PLL Clock Frequency Range
|
||||||
|
;// <0=> 80..160MHz <1=> Reserved
|
||||||
|
;// <2=> 150..220MHz <3=> Reserved
|
||||||
|
;// <o2.8..13> PLLCOUNT: PLL Lock Counter <0-63>
|
||||||
|
;// <o2.28..29> USBDIV: USB Clock Divider
|
||||||
|
;// <0=> None <1=> 2 <2=> 4 <3=> Reserved
|
||||||
|
;// </h>
|
||||||
|
;// <o3.0..1> CSS: Clock Source Selection
|
||||||
|
;// <0=> Slow Clock
|
||||||
|
;// <1=> Main Clock
|
||||||
|
;// <2=> Reserved
|
||||||
|
;// <3=> PLL Clock
|
||||||
|
;// <o3.2..4> PRES: Prescaler
|
||||||
|
;// <0=> None
|
||||||
|
;// <1=> Clock / 2 <2=> Clock / 4
|
||||||
|
;// <3=> Clock / 8 <4=> Clock / 16
|
||||||
|
;// <5=> Clock / 32 <6=> Clock / 64
|
||||||
|
;// <7=> Reserved
|
||||||
|
;// </e>
|
||||||
|
PMC_SETUP EQU 1
|
||||||
|
PMC_MOR_Val EQU 0x00000601
|
||||||
|
PMC_PLLR_Val EQU 0x00191C05
|
||||||
|
PMC_MCKR_Val EQU 0x00000007
|
||||||
|
|
||||||
|
|
||||||
|
PRESERVE8
|
||||||
|
|
||||||
|
|
||||||
|
; Area Definition and Entry Point
|
||||||
|
; Startup Code must be linked first at Address at which it expects to run.
|
||||||
|
|
||||||
|
AREA RESET, CODE, READONLY
|
||||||
|
ARM
|
||||||
|
|
||||||
|
|
||||||
|
; Exception Vectors
|
||||||
|
; Mapped to Address 0.
|
||||||
|
; Absolute addressing mode must be used.
|
||||||
|
; Dummy Handlers are implemented as infinite loops which can be modified.
|
||||||
|
|
||||||
|
Vectors LDR PC,Reset_Addr
|
||||||
|
LDR PC,Undef_Addr
|
||||||
|
LDR PC,SWI_Addr
|
||||||
|
LDR PC,PAbt_Addr
|
||||||
|
LDR PC,DAbt_Addr
|
||||||
|
NOP ; Reserved Vector
|
||||||
|
LDR PC,IRQ_Addr
|
||||||
|
LDR PC,FIQ_Addr
|
||||||
|
|
||||||
|
Reset_Addr DCD Reset_Handler
|
||||||
|
Undef_Addr DCD Undef_Handler
|
||||||
|
SWI_Addr DCD SWI_Handler
|
||||||
|
PAbt_Addr DCD PAbt_Handler
|
||||||
|
DAbt_Addr DCD DAbt_Handler
|
||||||
|
DCD 0 ; Reserved Address
|
||||||
|
IRQ_Addr DCD IRQ_Handler
|
||||||
|
FIQ_Addr DCD FIQ_Handler
|
||||||
|
|
||||||
|
Undef_Handler B Undef_Handler
|
||||||
|
SWI_Handler B SWI_Handler
|
||||||
|
PAbt_Handler B PAbt_Handler
|
||||||
|
DAbt_Handler B DAbt_Handler
|
||||||
|
FIQ_Handler B FIQ_Handler
|
||||||
|
|
||||||
|
|
||||||
|
; Reset Handler
|
||||||
|
|
||||||
|
EXPORT Reset_Handler
|
||||||
|
Reset_Handler
|
||||||
|
|
||||||
|
|
||||||
|
; Setup RSTC
|
||||||
|
IF RSTC_SETUP != 0
|
||||||
|
LDR R0, =RSTC_BASE
|
||||||
|
LDR R1, =RSTC_MR_Val
|
||||||
|
STR R1, [R0, #RSTC_MR]
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
|
||||||
|
; Setup EFC0
|
||||||
|
IF EFC0_SETUP != 0
|
||||||
|
LDR R0, =EFC_BASE
|
||||||
|
LDR R1, =EFC0_FMR_Val
|
||||||
|
STR R1, [R0, #EFC0_FMR]
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
; Setup EFC1
|
||||||
|
IF EFC1_SETUP != 0
|
||||||
|
LDR R0, =EFC_BASE
|
||||||
|
LDR R1, =EFC1_FMR_Val
|
||||||
|
STR R1, [R0, #EFC1_FMR]
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
; Setup WDT
|
||||||
|
IF WDT_SETUP != 0
|
||||||
|
LDR R0, =WDT_BASE
|
||||||
|
LDR R1, =WDT_MR_Val
|
||||||
|
STR R1, [R0, #WDT_MR]
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
|
||||||
|
; Setup PMC
|
||||||
|
IF PMC_SETUP != 0
|
||||||
|
LDR R0, =PMC_BASE
|
||||||
|
|
||||||
|
; Setup Main Oscillator
|
||||||
|
LDR R1, =PMC_MOR_Val
|
||||||
|
STR R1, [R0, #PMC_MOR]
|
||||||
|
|
||||||
|
; Wait until Main Oscillator is stablilized
|
||||||
|
IF (PMC_MOR_Val:AND:PMC_MOSCEN) != 0
|
||||||
|
MOSCS_Loop LDR R2, [R0, #PMC_SR]
|
||||||
|
ANDS R2, R2, #PMC_MOSCS
|
||||||
|
BEQ MOSCS_Loop
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
; Setup the PLL
|
||||||
|
IF (PMC_PLLR_Val:AND:PMC_MUL) != 0
|
||||||
|
LDR R1, =PMC_PLLR_Val
|
||||||
|
STR R1, [R0, #PMC_PLLR]
|
||||||
|
|
||||||
|
; Wait until PLL is stabilized
|
||||||
|
PLL_Loop LDR R2, [R0, #PMC_SR]
|
||||||
|
ANDS R2, R2, #PMC_LOCK
|
||||||
|
BEQ PLL_Loop
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
; Select Clock
|
||||||
|
IF (PMC_MCKR_Val:AND:PMC_CSS) == 1 ; Main Clock Selected
|
||||||
|
LDR R1, =PMC_MCKR_Val
|
||||||
|
AND R1, #PMC_CSS
|
||||||
|
STR R1, [R0, #PMC_MCKR]
|
||||||
|
WAIT_Rdy1 LDR R2, [R0, #PMC_SR]
|
||||||
|
ANDS R2, R2, #PMC_MCKRDY
|
||||||
|
BEQ WAIT_Rdy1
|
||||||
|
LDR R1, =PMC_MCKR_Val
|
||||||
|
STR R1, [R0, #PMC_MCKR]
|
||||||
|
WAIT_Rdy2 LDR R2, [R0, #PMC_SR]
|
||||||
|
ANDS R2, R2, #PMC_MCKRDY
|
||||||
|
BEQ WAIT_Rdy2
|
||||||
|
ELIF (PMC_MCKR_Val:AND:PMC_CSS) == 3 ; PLL Clock Selected
|
||||||
|
LDR R1, =PMC_MCKR_Val
|
||||||
|
AND R1, #PMC_PRES
|
||||||
|
STR R1, [R0, #PMC_MCKR]
|
||||||
|
WAIT_Rdy1 LDR R2, [R0, #PMC_SR]
|
||||||
|
ANDS R2, R2, #PMC_MCKRDY
|
||||||
|
BEQ WAIT_Rdy1
|
||||||
|
LDR R1, =PMC_MCKR_Val
|
||||||
|
STR R1, [R0, #PMC_MCKR]
|
||||||
|
WAIT_Rdy2 LDR R2, [R0, #PMC_SR]
|
||||||
|
ANDS R2, R2, #PMC_MCKRDY
|
||||||
|
BEQ WAIT_Rdy2
|
||||||
|
ENDIF ; Select Clock
|
||||||
|
ENDIF ; PMC_SETUP
|
||||||
|
|
||||||
|
|
||||||
|
; Copy Exception Vectors to Internal RAM
|
||||||
|
|
||||||
|
IF :DEF:RAM_INTVEC
|
||||||
|
ADR R8, Vectors ; Source
|
||||||
|
LDR R9, =RAM_BASE ; Destination
|
||||||
|
LDMIA R8!, {R0-R7} ; Load Vectors
|
||||||
|
STMIA R9!, {R0-R7} ; Store Vectors
|
||||||
|
LDMIA R8!, {R0-R7} ; Load Handler Addresses
|
||||||
|
STMIA R9!, {R0-R7} ; Store Handler Addresses
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
|
||||||
|
; Remap on-chip RAM to address 0
|
||||||
|
|
||||||
|
MC_BASE EQU 0xFFFFFF00 ; MC Base Address
|
||||||
|
MC_RCR EQU 0x00 ; MC_RCR Offset
|
||||||
|
|
||||||
|
IF :DEF:REMAP
|
||||||
|
LDR R0, =MC_BASE
|
||||||
|
MOV R1, #1
|
||||||
|
STR R1, [R0, #MC_RCR] ; Remap
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
|
||||||
|
; Setup Stack for each mode
|
||||||
|
|
||||||
|
LDR R0, =Stack_Top
|
||||||
|
|
||||||
|
; Enter Undefined Instruction Mode and set its Stack Pointer
|
||||||
|
MSR CPSR_c, #Mode_UND:OR:I_Bit:OR:F_Bit
|
||||||
|
MOV SP, R0
|
||||||
|
SUB R0, R0, #UND_Stack_Size
|
||||||
|
|
||||||
|
; Enter Abort Mode and set its Stack Pointer
|
||||||
|
MSR CPSR_c, #Mode_ABT:OR:I_Bit:OR:F_Bit
|
||||||
|
MOV SP, R0
|
||||||
|
SUB R0, R0, #ABT_Stack_Size
|
||||||
|
|
||||||
|
; Enter FIQ Mode and set its Stack Pointer
|
||||||
|
MSR CPSR_c, #Mode_FIQ:OR:I_Bit:OR:F_Bit
|
||||||
|
MOV SP, R0
|
||||||
|
SUB R0, R0, #FIQ_Stack_Size
|
||||||
|
|
||||||
|
; Enter IRQ Mode and set its Stack Pointer
|
||||||
|
MSR CPSR_c, #Mode_IRQ:OR:I_Bit:OR:F_Bit
|
||||||
|
MOV SP, R0
|
||||||
|
SUB R0, R0, #IRQ_Stack_Size
|
||||||
|
|
||||||
|
; Enter Supervisor Mode and set its Stack Pointer
|
||||||
|
MSR CPSR_c, #Mode_SVC:OR:I_Bit:OR:F_Bit
|
||||||
|
MOV SP, R0
|
||||||
|
SUB R0, R0, #SVC_Stack_Size
|
||||||
|
|
||||||
|
; Enter User Mode and set its Stack Pointer
|
||||||
|
; MSR CPSR_c, #Mode_USR
|
||||||
|
IF :DEF:__MICROLIB
|
||||||
|
|
||||||
|
EXPORT __initial_sp
|
||||||
|
|
||||||
|
ELSE
|
||||||
|
|
||||||
|
MOV SP, R0
|
||||||
|
SUB SL, SP, #USR_Stack_Size
|
||||||
|
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
|
||||||
|
; Enter the C code
|
||||||
|
|
||||||
|
IMPORT __main
|
||||||
|
LDR R0, =__main
|
||||||
|
BX R0
|
||||||
|
|
||||||
|
IMPORT rt_interrupt_enter
|
||||||
|
IMPORT rt_interrupt_leave
|
||||||
|
IMPORT rt_thread_switch_interrput_flag
|
||||||
|
IMPORT rt_interrupt_from_thread
|
||||||
|
IMPORT rt_interrupt_to_thread
|
||||||
|
IMPORT rt_hw_trap_irq
|
||||||
|
|
||||||
|
IRQ_Handler PROC
|
||||||
|
EXPORT IRQ_Handler
|
||||||
|
STMFD sp!, {r0-r12,lr}
|
||||||
|
BL rt_interrupt_enter
|
||||||
|
BL rt_hw_trap_irq
|
||||||
|
BL rt_interrupt_leave
|
||||||
|
|
||||||
|
; if rt_thread_switch_interrput_flag set, jump to
|
||||||
|
; rt_hw_context_switch_interrupt_do and don't return
|
||||||
|
LDR r0, =rt_thread_switch_interrput_flag
|
||||||
|
LDR r1, [r0]
|
||||||
|
CMP r1, #1
|
||||||
|
BEQ rt_hw_context_switch_interrupt_do
|
||||||
|
|
||||||
|
LDMFD sp!, {r0-r12,lr}
|
||||||
|
SUBS pc, lr, #4
|
||||||
|
ENDP
|
||||||
|
|
||||||
|
; /*
|
||||||
|
; * void rt_hw_context_switch_interrupt_do(rt_base_t flag)
|
||||||
|
; */
|
||||||
|
rt_hw_context_switch_interrupt_do PROC
|
||||||
|
EXPORT rt_hw_context_switch_interrupt_do
|
||||||
|
MOV r1, #0 ; clear flag
|
||||||
|
STR r1, [r0]
|
||||||
|
|
||||||
|
LDMFD sp!, {r0-r12,lr}; reload saved registers
|
||||||
|
STMFD sp!, {r0-r3} ; save r0-r3
|
||||||
|
MOV r1, sp
|
||||||
|
ADD sp, sp, #16 ; restore sp
|
||||||
|
SUB r2, lr, #4 ; save old task's pc to r2
|
||||||
|
|
||||||
|
MRS r3, spsr ; get cpsr of interrupt thread
|
||||||
|
|
||||||
|
; switch to SVC mode and no interrupt
|
||||||
|
MSR cpsr_c, #I_Bit|F_Bit|Mode_SVC
|
||||||
|
|
||||||
|
STMFD sp!, {r2} ; push old task's pc
|
||||||
|
STMFD sp!, {r4-r12,lr}; push old task's lr,r12-r4
|
||||||
|
MOV r4, r1 ; Special optimised code below
|
||||||
|
MOV r5, r3
|
||||||
|
LDMFD r4!, {r0-r3}
|
||||||
|
STMFD sp!, {r0-r3} ; push old task's r3-r0
|
||||||
|
STMFD sp!, {r5} ; push old task's cpsr
|
||||||
|
MRS r4, spsr
|
||||||
|
STMFD sp!, {r4} ; push old task's spsr
|
||||||
|
|
||||||
|
LDR r4, =rt_interrupt_from_thread
|
||||||
|
LDR r5, [r4]
|
||||||
|
STR sp, [r5] ; store sp in preempted tasks's TCB
|
||||||
|
|
||||||
|
LDR r6, =rt_interrupt_to_thread
|
||||||
|
LDR r6, [r6]
|
||||||
|
LDR sp, [r6] ; get new task's stack pointer
|
||||||
|
|
||||||
|
LDMFD sp!, {r4} ; pop new task's spsr
|
||||||
|
MSR spsr_cxsf, r4
|
||||||
|
LDMFD sp!, {r4} ; pop new task's psr
|
||||||
|
MSR cpsr_cxsf, r4
|
||||||
|
|
||||||
|
LDMFD sp!, {r0-r12,lr,pc} ; pop new task's r0-r12,lr & pc
|
||||||
|
ENDP
|
||||||
|
|
||||||
|
IF :DEF:__MICROLIB
|
||||||
|
|
||||||
|
EXPORT __heap_base
|
||||||
|
EXPORT __heap_limit
|
||||||
|
|
||||||
|
ELSE
|
||||||
|
; User Initial Stack & Heap
|
||||||
|
AREA |.text|, CODE, READONLY
|
||||||
|
|
||||||
|
IMPORT __use_two_region_memory
|
||||||
|
EXPORT __user_initial_stackheap
|
||||||
|
__user_initial_stackheap
|
||||||
|
|
||||||
|
LDR R0, = Heap_Mem
|
||||||
|
LDR R1, =(Stack_Mem + USR_Stack_Size)
|
||||||
|
LDR R2, = (Heap_Mem + Heap_Size)
|
||||||
|
LDR R3, = Stack_Mem
|
||||||
|
BX LR
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
END
|
|
@ -0,0 +1,40 @@
|
||||||
|
/*
|
||||||
|
* File : trap.c
|
||||||
|
* This file is part of RT-Thread RTOS
|
||||||
|
* COPYRIGHT (C) 2006, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* The license and distribution terms for this file may be
|
||||||
|
* found in the file LICENSE in this distribution or at
|
||||||
|
* http://openlab.rt-thread.com/license/LICENSE
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2006-08-25 Bernard first version
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <rtthread.h>
|
||||||
|
#include <rthw.h>
|
||||||
|
|
||||||
|
#include "AT91SAM7S.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @addtogroup AT91SAM7
|
||||||
|
*/
|
||||||
|
/*@{*/
|
||||||
|
|
||||||
|
void rt_hw_trap_irq()
|
||||||
|
{
|
||||||
|
rt_isr_handler_t hander = (rt_isr_handler_t)AT91C_AIC_IVR;
|
||||||
|
|
||||||
|
hander(AT91C_AIC_ISR);
|
||||||
|
|
||||||
|
/* end of interrupt */
|
||||||
|
AT91C_AIC_EOICR = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void rt_hw_trap_fiq()
|
||||||
|
{
|
||||||
|
rt_kprintf("fast interrupt request\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*@}*/
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -0,0 +1,42 @@
|
||||||
|
/*
|
||||||
|
* File : cpu.c
|
||||||
|
* This file is part of RT-Thread RTOS
|
||||||
|
* COPYRIGHT (C) 2006, RT-Thread Develop Team
|
||||||
|
*
|
||||||
|
* The license and distribution terms for this file may be
|
||||||
|
* found in the file LICENSE in this distribution or at
|
||||||
|
* http://www.rt-thread.org/license/LICENSE
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2006-08-23 Bernard first version
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <rtthread.h>
|
||||||
|
#include "AT91SAM7X.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @addtogroup AT91SAM7X
|
||||||
|
*/
|
||||||
|
/*@{*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* this function will reset CPU
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void rt_hw_cpu_reset()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* this function will shutdown CPU
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void rt_hw_cpu_shutdown()
|
||||||
|
{
|
||||||
|
rt_kprintf("shutdown...\n");
|
||||||
|
|
||||||
|
while (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*@}*/
|
|
@ -0,0 +1,91 @@
|
||||||
|
/*
|
||||||
|
* File : trap.c
|
||||||
|
* This file is part of RT-Thread RTOS
|
||||||
|
* COPYRIGHT (C) 2006, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* The license and distribution terms for this file may be
|
||||||
|
* found in the file LICENSE in this distribution or at
|
||||||
|
* http://openlab.rt-thread.com/license/LICENSE
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2006-08-23 Bernard first version
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <rtthread.h>
|
||||||
|
#include "AT91SAM7X.h"
|
||||||
|
|
||||||
|
#define MAX_HANDLERS 32
|
||||||
|
|
||||||
|
extern rt_uint32_t rt_interrupt_nest;
|
||||||
|
|
||||||
|
rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread;
|
||||||
|
rt_uint32_t rt_thread_switch_interrput_flag;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @addtogroup AT91SAM7
|
||||||
|
*/
|
||||||
|
/*@{*/
|
||||||
|
|
||||||
|
void rt_hw_interrupt_handler(int vector)
|
||||||
|
{
|
||||||
|
rt_kprintf("Unhandled interrupt %d occured!!!\n", vector);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function will initialize hardware interrupt
|
||||||
|
*/
|
||||||
|
void rt_hw_interrupt_init()
|
||||||
|
{
|
||||||
|
rt_base_t index;
|
||||||
|
|
||||||
|
for (index = 0; index < MAX_HANDLERS; index ++)
|
||||||
|
{
|
||||||
|
AT91C_AIC_SVR(index) = (rt_uint32_t)rt_hw_interrupt_handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* init interrupt nest, and context in thread sp */
|
||||||
|
rt_interrupt_nest = 0;
|
||||||
|
rt_interrupt_from_thread = 0;
|
||||||
|
rt_interrupt_to_thread = 0;
|
||||||
|
rt_thread_switch_interrput_flag = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function will mask a interrupt.
|
||||||
|
* @param vector the interrupt number
|
||||||
|
*/
|
||||||
|
void rt_hw_interrupt_mask(int vector)
|
||||||
|
{
|
||||||
|
/* disable interrupt */
|
||||||
|
AT91C_AIC_IDCR = 1 << vector;
|
||||||
|
|
||||||
|
/* clear interrupt */
|
||||||
|
AT91C_AIC_ICCR = 1 << vector;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function will un-mask a interrupt.
|
||||||
|
* @param vector the interrupt number
|
||||||
|
*/
|
||||||
|
void rt_hw_interrupt_umask(int vector)
|
||||||
|
{
|
||||||
|
AT91C_AIC_IECR = 1 << vector;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function will install a interrupt service routine to a interrupt.
|
||||||
|
* @param vector the interrupt number
|
||||||
|
* @param new_handler the interrupt service routine to be installed
|
||||||
|
* @param old_handler the old interrupt service routine
|
||||||
|
*/
|
||||||
|
void rt_hw_interrupt_install(int vector, rt_isr_handler_t new_handler, rt_isr_handler_t *old_handler)
|
||||||
|
{
|
||||||
|
if(vector >= 0 && vector < MAX_HANDLERS)
|
||||||
|
{
|
||||||
|
if (*old_handler != RT_NULL) *old_handler = (rt_isr_handler_t)AT91C_AIC_SVR(vector);
|
||||||
|
if (new_handler != RT_NULL) AT91C_AIC_SVR(vector) = (rt_uint32_t)new_handler;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*@}*/
|
|
@ -0,0 +1,156 @@
|
||||||
|
/*
|
||||||
|
ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
|
||||||
|
|
||||||
|
This file is part of ChibiOS/RT.
|
||||||
|
|
||||||
|
ChibiOS/RT is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
ChibiOS/RT is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Parts of this file are borrowed by the Linux include file linux/mii.h:
|
||||||
|
* Copyright (C) 1996, 1999, 2001 David S. Miller (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_ */
|
|
@ -0,0 +1,554 @@
|
||||||
|
#include <rthw.h>
|
||||||
|
#include <rtthread.h>
|
||||||
|
#include <netif/ethernetif.h>
|
||||||
|
|
||||||
|
#include "sam7x_emac.h"
|
||||||
|
#include "AT91SAM7X256.h"
|
||||||
|
#include "lwipopts.h"
|
||||||
|
|
||||||
|
#define MAX_ADDR_LEN 6
|
||||||
|
#define EMAC_PIO_CFG (AT91C_PB0_ETXCK_EREFCK | \
|
||||||
|
AT91C_PB1_ETXEN | \
|
||||||
|
AT91C_PB2_ETX0 | \
|
||||||
|
AT91C_PB3_ETX1 | \
|
||||||
|
AT91C_PB4_ECRS | \
|
||||||
|
AT91C_PB5_ERX0 | \
|
||||||
|
AT91C_PB6_ERX1 | \
|
||||||
|
AT91C_PB7_ERXER | \
|
||||||
|
AT91C_PB8_EMDC | \
|
||||||
|
AT91C_PB9_EMDIO | \
|
||||||
|
AT91C_PB10_ETX2 | \
|
||||||
|
AT91C_PB11_ETX3 | \
|
||||||
|
AT91C_PB10_ETX2 | \
|
||||||
|
AT91C_PB13_ERX2 | \
|
||||||
|
AT91C_PB14_ERX3 | \
|
||||||
|
AT91C_PB15_ERXDV_ECRSDV| \
|
||||||
|
AT91C_PB16_ECOL | \
|
||||||
|
AT91C_PB17_ERXCK)
|
||||||
|
|
||||||
|
#define RB_BUFFER_SIZE 8 /* max number of receive buffers */
|
||||||
|
#define ETH_RX_BUF_SIZE 128
|
||||||
|
|
||||||
|
#define TB_BUFFER_SIZE 4
|
||||||
|
#define ETH_TX_BUF_SIZE (PBUF_POOL_BUFSIZE)
|
||||||
|
|
||||||
|
struct rbf_t
|
||||||
|
{
|
||||||
|
rt_uint32_t addr;
|
||||||
|
rt_uint32_t status;
|
||||||
|
};
|
||||||
|
|
||||||
|
static rt_uint32_t current_rb_index; /* current receive buffer index */
|
||||||
|
static volatile struct rbf_t rb_descriptors[RB_BUFFER_SIZE];
|
||||||
|
static volatile struct rbf_t tb_descriptors[TB_BUFFER_SIZE];
|
||||||
|
static rt_uint8_t rx_buf[RB_BUFFER_SIZE][ETH_RX_BUF_SIZE] __attribute__ ((aligned (8)));
|
||||||
|
static rt_uint8_t tx_buf[TB_BUFFER_SIZE][ETH_TX_BUF_SIZE] __attribute__ ((aligned (8)));
|
||||||
|
static struct rt_semaphore tx_sem;
|
||||||
|
|
||||||
|
struct net_device
|
||||||
|
{
|
||||||
|
/* inherit from ethernet device */
|
||||||
|
struct eth_device parent;
|
||||||
|
|
||||||
|
/* interface address info. */
|
||||||
|
rt_uint8_t dev_addr[MAX_ADDR_LEN]; /* hw address */
|
||||||
|
};
|
||||||
|
static struct net_device sam7x_dev_entry;
|
||||||
|
static struct net_device *sam7x_dev =&sam7x_dev_entry;
|
||||||
|
AT91PS_EMAC pEmac = AT91C_BASE_EMAC;
|
||||||
|
|
||||||
|
rt_inline void write_phy(rt_uint8_t addr, rt_uint32_t value)
|
||||||
|
{
|
||||||
|
AT91C_BASE_EMAC->EMAC_MAN = ((0x01<<30) | (2 << 16) | (1 << 28) |
|
||||||
|
(AT91C_PHY_ADDR << 23) | (addr << 18)) | value;
|
||||||
|
|
||||||
|
/* Wait until IDLE bit in Network Status register is cleared */
|
||||||
|
while (!(AT91C_BASE_EMAC->EMAC_NSR & AT91C_EMAC_IDLE));
|
||||||
|
}
|
||||||
|
|
||||||
|
rt_inline rt_uint32_t read_phy(rt_uint8_t addr)
|
||||||
|
{
|
||||||
|
AT91C_BASE_EMAC->EMAC_MAN = (0x01<<30) | (0x02 << 16) | (0x02 << 28) |
|
||||||
|
(AT91C_PHY_ADDR << 23) | (addr << 18);
|
||||||
|
|
||||||
|
/* Wait until IDLE bit in Network Status register is cleared */
|
||||||
|
while (!(AT91C_BASE_EMAC->EMAC_NSR & AT91C_EMAC_IDLE));
|
||||||
|
|
||||||
|
return (AT91C_BASE_EMAC->EMAC_MAN & 0x0000ffff);
|
||||||
|
}
|
||||||
|
|
||||||
|
rt_inline void sam7xether_reset_tx_desc(void)
|
||||||
|
{
|
||||||
|
static rt_uint32_t index = 0;
|
||||||
|
|
||||||
|
if(tb_descriptors[index].status & TxDESC_STATUS_USED)
|
||||||
|
{
|
||||||
|
while(!tb_descriptors[index].status & TxDESC_STATUS_LAST_BUF)
|
||||||
|
{
|
||||||
|
index ++;
|
||||||
|
if(index >= TB_BUFFER_SIZE)index = 0;
|
||||||
|
|
||||||
|
tb_descriptors[index].status |= TxDESC_STATUS_USED;
|
||||||
|
}
|
||||||
|
|
||||||
|
index ++;
|
||||||
|
if(index >= TB_BUFFER_SIZE)index = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* interrupt service routing */
|
||||||
|
static void sam7xether_isr(int irq)
|
||||||
|
{
|
||||||
|
/* Variable definitions can be made now. */
|
||||||
|
volatile rt_uint32_t isr, rsr;
|
||||||
|
|
||||||
|
/* get status */
|
||||||
|
isr = AT91C_BASE_EMAC->EMAC_ISR;
|
||||||
|
rsr = AT91C_BASE_EMAC->EMAC_RSR;
|
||||||
|
|
||||||
|
if( ( isr & AT91C_EMAC_RCOMP ) || ( rsr & AT91C_EMAC_REC ) )
|
||||||
|
{
|
||||||
|
rt_err_t result;
|
||||||
|
|
||||||
|
/* a frame has been received */
|
||||||
|
result = eth_device_ready((struct eth_device*)&(sam7x_dev->parent));
|
||||||
|
RT_ASSERT(result == RT_EOK);
|
||||||
|
|
||||||
|
AT91C_BASE_EMAC->EMAC_RSR = AT91C_EMAC_REC;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( isr & AT91C_EMAC_TCOMP )
|
||||||
|
{
|
||||||
|
/* A frame has been transmitted. Mark all the buffers as free */
|
||||||
|
sam7xether_reset_tx_desc();
|
||||||
|
|
||||||
|
AT91C_BASE_EMAC->EMAC_TSR = AT91C_EMAC_COMP;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rt_inline void linksetup(void)
|
||||||
|
{
|
||||||
|
rt_uint32_t value;
|
||||||
|
|
||||||
|
/* Check if this is a RTL8201 PHY. */
|
||||||
|
rt_uint16_t id1 = read_phy(PHY_REG_PHYID1);
|
||||||
|
rt_uint16_t id2 = read_phy(PHY_REG_PHYID2);
|
||||||
|
|
||||||
|
if (((id2 << 16) | (id1 & 0xfff0)) == MII_RTL8201_ID)
|
||||||
|
{
|
||||||
|
rt_uint32_t tout;
|
||||||
|
|
||||||
|
/* Configure the PHY device */
|
||||||
|
/* Use autonegotiation about the link speed. */
|
||||||
|
write_phy (PHY_REG_BMCR, PHY_AUTO_NEG);
|
||||||
|
|
||||||
|
/* Wait to complete Auto_Negotiation. */
|
||||||
|
for (tout = 0; tout < 0x100000; tout++)
|
||||||
|
{
|
||||||
|
value = read_phy (PHY_REG_BMSR);
|
||||||
|
if (value & BMSR_ANEGCOMPLETE) break; /* autonegotiation finished. */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check the link status. */
|
||||||
|
for (tout = 0; tout < 0x10000; tout++)
|
||||||
|
{
|
||||||
|
value = read_phy (PHY_REG_BMSR);
|
||||||
|
if (value & BMSR_LINKST) break; /* Link is on. */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
value = read_phy (PHY_REG_ANLPAR);
|
||||||
|
|
||||||
|
/* Update the MAC register NCFGR. */
|
||||||
|
AT91C_BASE_EMAC->EMAC_NCFGR &= ~(AT91C_EMAC_SPD | AT91C_EMAC_FD);
|
||||||
|
|
||||||
|
/* set full duplex . */
|
||||||
|
if (value & 0xA000) AT91C_BASE_EMAC->EMAC_NCFGR |= AT91C_EMAC_FD;
|
||||||
|
/* set speed */
|
||||||
|
if (value & 0xC000) AT91C_BASE_EMAC->EMAC_NCFGR |= AT91C_EMAC_SPD;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set the MAC address.
|
||||||
|
*/
|
||||||
|
rt_inline void update_mac_address(struct net_device* device)
|
||||||
|
{
|
||||||
|
AT91C_BASE_EMAC->EMAC_SA1L = (device->dev_addr[3] << 24) |
|
||||||
|
(device->dev_addr[2] << 16) |
|
||||||
|
(device->dev_addr[1] << 8) |
|
||||||
|
device->dev_addr[0];
|
||||||
|
AT91C_BASE_EMAC->EMAC_SA1H = (device->dev_addr[5] << 8) |
|
||||||
|
device->dev_addr[4];
|
||||||
|
}
|
||||||
|
|
||||||
|
rt_inline void sam7xether_desc_init()
|
||||||
|
{
|
||||||
|
rt_uint32_t i;
|
||||||
|
|
||||||
|
/* Rx Buffer Descriptor initialization */
|
||||||
|
current_rb_index = 0;
|
||||||
|
for (i = 0; i < RB_BUFFER_SIZE; i++)
|
||||||
|
{
|
||||||
|
rb_descriptors[i].addr = (rt_uint32_t)&(rx_buf[i][0]);
|
||||||
|
rb_descriptors[i].status = 0;
|
||||||
|
}
|
||||||
|
/* Set the WRAP bit at the end of the list descriptor. */
|
||||||
|
rb_descriptors[RB_BUFFER_SIZE-1].addr |= 0x02;
|
||||||
|
/* Set Rx Queue pointer to descriptor list. */
|
||||||
|
AT91C_BASE_EMAC->EMAC_RBQP = (unsigned int)&(rb_descriptors[0]);
|
||||||
|
|
||||||
|
/* Tx Buffer Descriptor initialization */
|
||||||
|
for (i = 0; i < TB_BUFFER_SIZE; i++)
|
||||||
|
{
|
||||||
|
tb_descriptors[i].addr = (rt_uint32_t)&(tx_buf[i][0]);
|
||||||
|
tb_descriptors[i].status = TxDESC_STATUS_USED;
|
||||||
|
}
|
||||||
|
/* Set the WRAP bit at the end of the list descriptor. */
|
||||||
|
tb_descriptors[TB_BUFFER_SIZE-1].status |= TxDESC_STATUS_WRAP;
|
||||||
|
/* Set Tx Queue pointer to descriptor list. */
|
||||||
|
AT91C_BASE_EMAC->EMAC_TBQP = (unsigned int)&(tb_descriptors[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* RT-Thread Device Interface */
|
||||||
|
|
||||||
|
/* initialize the interface */
|
||||||
|
rt_err_t sam7xether_init(rt_device_t dev)
|
||||||
|
{
|
||||||
|
/* enable peripheral clock for EMAC and PIO B */
|
||||||
|
AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_PIOB | 1 << AT91C_ID_EMAC;
|
||||||
|
|
||||||
|
/* Disable pull up on RXDV => PHY normal mode (not in test mode), */
|
||||||
|
/* and set MII mode. PHY has internal pull down. */
|
||||||
|
AT91C_BASE_PIOB->PIO_PPUDR = (1<<16) | (1 << 15);
|
||||||
|
|
||||||
|
/* Clear PB18 <=> PHY powerdown */
|
||||||
|
AT91C_BASE_PIOB->PIO_PER = 1<<18;
|
||||||
|
AT91C_BASE_PIOB->PIO_OER = 1<<18;
|
||||||
|
AT91C_BASE_PIOB->PIO_CODR = 1<<18;
|
||||||
|
|
||||||
|
/* EMAC IO init for EMAC-PHY communication. */
|
||||||
|
AT91C_BASE_PIOB->PIO_ASR = EMAC_PIO_CFG;
|
||||||
|
AT91C_BASE_PIOB->PIO_PDR = EMAC_PIO_CFG; // Set in Periph mode
|
||||||
|
|
||||||
|
/* Enable communication between EMAC-PHY. */
|
||||||
|
AT91C_BASE_EMAC->EMAC_NCR |= AT91C_EMAC_MPE;
|
||||||
|
/* MDC = MCK/32 */
|
||||||
|
AT91C_BASE_EMAC->EMAC_NCFGR |= 2<<10;
|
||||||
|
|
||||||
|
/* Reset PHY */
|
||||||
|
AT91C_BASE_PIOB->PIO_PPUDR = AT91C_PB7_ERXER;
|
||||||
|
|
||||||
|
AT91C_BASE_RSTC->RSTC_RMR = 0xA5000000 | (0x08 << 8) ;
|
||||||
|
AT91C_BASE_RSTC->RSTC_RCR = 0xA5000000 | AT91C_RSTC_EXTRST;
|
||||||
|
while(!(AT91C_BASE_RSTC->RSTC_RSR & AT91C_RSTC_NRSTL));
|
||||||
|
|
||||||
|
linksetup();
|
||||||
|
|
||||||
|
/* Disable management port in MAC control register. */
|
||||||
|
AT91C_BASE_EMAC->EMAC_NCR &= ~AT91C_EMAC_MPE;
|
||||||
|
|
||||||
|
/* Enable EMAC in MII mode, enable clock ERXCK and ETXCK */
|
||||||
|
AT91C_BASE_EMAC->EMAC_USRIO= AT91C_EMAC_CLKEN;
|
||||||
|
|
||||||
|
/* Transmit and Receive disable. */
|
||||||
|
AT91C_BASE_EMAC->EMAC_NCR &= ~(AT91C_EMAC_RE | AT91C_EMAC_TE);
|
||||||
|
|
||||||
|
/* init descriptor */
|
||||||
|
sam7xether_desc_init();
|
||||||
|
|
||||||
|
/* Clear receive and transmit status registers. */
|
||||||
|
AT91C_BASE_EMAC->EMAC_RSR = (AT91C_EMAC_OVR | AT91C_EMAC_REC | AT91C_EMAC_BNA);
|
||||||
|
AT91C_BASE_EMAC->EMAC_TSR = (AT91C_EMAC_UND | AT91C_EMAC_COMP| AT91C_EMAC_BEX |
|
||||||
|
AT91C_EMAC_RLES| AT91C_EMAC_COL | AT91C_EMAC_UBR);
|
||||||
|
|
||||||
|
/* Configure EMAC operation mode. */
|
||||||
|
AT91C_BASE_EMAC->EMAC_NCFGR |= (AT91C_EMAC_BIG | AT91C_EMAC_DRFCS);
|
||||||
|
AT91C_BASE_EMAC->EMAC_NCR |= (AT91C_EMAC_TE | AT91C_EMAC_RE | AT91C_EMAC_WESTAT);
|
||||||
|
|
||||||
|
/* update MAC address */
|
||||||
|
update_mac_address(sam7x_dev);
|
||||||
|
|
||||||
|
/* enable interrupt */
|
||||||
|
AT91C_BASE_EMAC->EMAC_IER = AT91C_EMAC_RCOMP | AT91C_EMAC_TCOMP;
|
||||||
|
|
||||||
|
/* setup interrupt */
|
||||||
|
rt_hw_interrupt_install(AT91C_ID_EMAC, sam7xether_isr, RT_NULL);
|
||||||
|
*(volatile unsigned int*)(0xFFFFF000 + AT91C_ID_EMAC * 4) = AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL | 5;
|
||||||
|
// AT91C_AIC_SMR(AT91C_ID_EMAC) = AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL | 5;
|
||||||
|
rt_hw_interrupt_umask(AT91C_ID_EMAC);
|
||||||
|
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* control the interface */
|
||||||
|
rt_err_t sam7xether_control(rt_device_t dev, rt_uint8_t cmd, void *args)
|
||||||
|
{
|
||||||
|
switch(cmd)
|
||||||
|
{
|
||||||
|
case NIOCTL_GADDR:
|
||||||
|
/* get mac address */
|
||||||
|
if(args) rt_memcpy(args, sam7x_dev_entry.dev_addr, 6);
|
||||||
|
else return -RT_ERROR;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default :
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Open the ethernet interface */
|
||||||
|
rt_err_t sam7xether_open(rt_device_t dev, rt_uint16_t oflags)
|
||||||
|
{
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Close the interface */
|
||||||
|
rt_err_t sam7xether_close(rt_device_t dev)
|
||||||
|
{
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read */
|
||||||
|
rt_size_t sam7xether_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
|
||||||
|
{
|
||||||
|
rt_set_errno(-RT_ENOSYS);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Write */
|
||||||
|
rt_size_t sam7xether_write(rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
|
||||||
|
{
|
||||||
|
rt_set_errno(-RT_ENOSYS);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* See the header file for descriptions of public functions. */
|
||||||
|
void sam7xether_write_frame(rt_uint8_t *ptr, rt_uint32_t length, rt_bool_t eof)
|
||||||
|
{
|
||||||
|
rt_uint8_t *buf_ptr;
|
||||||
|
static rt_uint32_t current_tb_index = 0;
|
||||||
|
rt_uint32_t is_last, tx_offset = 0, remain, pdu_length;
|
||||||
|
|
||||||
|
while(tx_offset < length)
|
||||||
|
{
|
||||||
|
/* check whether buffer is available */
|
||||||
|
while(!(tb_descriptors[current_tb_index].status & TxDESC_STATUS_USED))
|
||||||
|
{
|
||||||
|
/* no buffer */
|
||||||
|
rt_thread_delay(5);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the address of the buffer from the descriptor, then copy
|
||||||
|
the data into the buffer. */
|
||||||
|
buf_ptr = (rt_uint8_t *)tb_descriptors[current_tb_index].addr;
|
||||||
|
|
||||||
|
/* How much can we write to the buffer? */
|
||||||
|
remain = length - tx_offset;
|
||||||
|
pdu_length = (remain <= ETH_TX_BUF_SIZE)? remain : ETH_TX_BUF_SIZE;
|
||||||
|
|
||||||
|
/* Copy the data into the buffer. */
|
||||||
|
rt_memcpy(buf_ptr, &ptr[tx_offset], pdu_length );
|
||||||
|
tx_offset += pdu_length;
|
||||||
|
|
||||||
|
/* Is this the last data for the frame? */
|
||||||
|
if((eof == RT_TRUE) && ( tx_offset >= length )) is_last = TxDESC_STATUS_LAST_BUF;
|
||||||
|
else is_last = 0;
|
||||||
|
|
||||||
|
/* Fill out the necessary in the descriptor to get the data sent,
|
||||||
|
then move to the next descriptor, wrapping if necessary. */
|
||||||
|
if(current_tb_index >= (TB_BUFFER_SIZE - 1))
|
||||||
|
{
|
||||||
|
tb_descriptors[current_tb_index].status = ( pdu_length & TxDESC_STATUS_BUF_SIZE )
|
||||||
|
| is_last
|
||||||
|
| TxDESC_STATUS_WRAP;
|
||||||
|
current_tb_index = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tb_descriptors[current_tb_index].status = ( pdu_length & TxDESC_STATUS_BUF_SIZE )
|
||||||
|
| is_last;
|
||||||
|
current_tb_index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If this is the last buffer to be sent for this frame we can
|
||||||
|
start the transmission. */
|
||||||
|
if(is_last)
|
||||||
|
{
|
||||||
|
AT91C_BASE_EMAC->EMAC_NCR |= AT91C_EMAC_TSTART;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ethernet device interface */
|
||||||
|
/*
|
||||||
|
* Transmit packet.
|
||||||
|
*/
|
||||||
|
rt_err_t sam7xether_tx( rt_device_t dev, struct pbuf* p)
|
||||||
|
{
|
||||||
|
struct pbuf* q;
|
||||||
|
|
||||||
|
/* lock tx operation */
|
||||||
|
rt_sem_take(&tx_sem, RT_WAITING_FOREVER);
|
||||||
|
|
||||||
|
for (q = p; q != NULL; q = q->next)
|
||||||
|
{
|
||||||
|
if (q->next == RT_NULL) sam7xether_write_frame(q->payload, q->len, RT_TRUE);
|
||||||
|
else sam7xether_write_frame(q->payload, q->len, RT_FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
rt_sem_release(&tx_sem);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void sam7xether_read_frame(rt_uint8_t* ptr, rt_uint32_t section_length, rt_uint32_t total)
|
||||||
|
{
|
||||||
|
static rt_uint8_t* src_ptr;
|
||||||
|
register rt_uint32_t buf_remain, section_remain;
|
||||||
|
static rt_uint32_t section_read = 0, buf_offset = 0, frame_read = 0;
|
||||||
|
|
||||||
|
if(ptr == RT_NULL)
|
||||||
|
{
|
||||||
|
/* Reset our state variables ready for the next read from this buffer. */
|
||||||
|
src_ptr = (rt_uint8_t *)(rb_descriptors[current_rb_index].addr & RxDESC_FLAG_ADDR_MASK);
|
||||||
|
frame_read = (rt_uint32_t)0;
|
||||||
|
buf_offset = (rt_uint32_t)0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Loop until we have obtained the required amount of data. */
|
||||||
|
section_read = 0;
|
||||||
|
while( section_read < section_length )
|
||||||
|
{
|
||||||
|
buf_remain = (ETH_RX_BUF_SIZE - buf_offset);
|
||||||
|
section_remain = section_length - section_read;
|
||||||
|
|
||||||
|
if( section_remain > buf_remain )
|
||||||
|
{
|
||||||
|
/* more data on section than buffer size */
|
||||||
|
rt_memcpy(&ptr[ section_read ], &src_ptr[buf_offset], buf_remain);
|
||||||
|
section_read += buf_remain;
|
||||||
|
frame_read += buf_remain;
|
||||||
|
|
||||||
|
/* free buffer */
|
||||||
|
rb_descriptors[current_rb_index].addr &= ~RxDESC_FLAG_OWNSHIP;
|
||||||
|
|
||||||
|
/* move to the next frame. */
|
||||||
|
current_rb_index++;
|
||||||
|
if(current_rb_index >= RB_BUFFER_SIZE) current_rb_index = 0;
|
||||||
|
|
||||||
|
/* Reset the variables for the new buffer. */
|
||||||
|
src_ptr = (rt_uint8_t *)(rb_descriptors[current_rb_index].addr & RxDESC_FLAG_ADDR_MASK);
|
||||||
|
buf_offset = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* more data on buffer than section size */
|
||||||
|
rt_memcpy(&ptr[section_read], &src_ptr[buf_offset], section_remain);
|
||||||
|
buf_offset += section_remain;
|
||||||
|
section_read += section_remain;
|
||||||
|
frame_read += section_remain;
|
||||||
|
|
||||||
|
/* finish this read */
|
||||||
|
if((buf_offset >= ETH_RX_BUF_SIZE) || (frame_read >= total))
|
||||||
|
{
|
||||||
|
/* free buffer */
|
||||||
|
rb_descriptors[current_rb_index].addr &= ~(RxDESC_FLAG_OWNSHIP);
|
||||||
|
|
||||||
|
/* move to the next frame. */
|
||||||
|
current_rb_index++;
|
||||||
|
if( current_rb_index >= RB_BUFFER_SIZE ) current_rb_index = 0;
|
||||||
|
|
||||||
|
src_ptr = (rt_uint8_t*)(rb_descriptors[current_rb_index].addr & RxDESC_FLAG_ADDR_MASK);
|
||||||
|
buf_offset = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct pbuf *sam7xether_rx(rt_device_t dev)
|
||||||
|
{
|
||||||
|
struct pbuf *p = RT_NULL;
|
||||||
|
|
||||||
|
/* skip fragment frame */
|
||||||
|
while((rb_descriptors[current_rb_index].addr & RxDESC_FLAG_OWNSHIP)
|
||||||
|
&& !(rb_descriptors[current_rb_index].status & RxDESC_STATUS_FRAME_START))
|
||||||
|
{
|
||||||
|
rb_descriptors[current_rb_index].addr &= (~RxDESC_FLAG_OWNSHIP);
|
||||||
|
|
||||||
|
current_rb_index++;
|
||||||
|
if(current_rb_index >= RB_BUFFER_SIZE) current_rb_index = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((rb_descriptors[current_rb_index].addr & RxDESC_FLAG_OWNSHIP))
|
||||||
|
{
|
||||||
|
struct pbuf* q;
|
||||||
|
rt_uint32_t index, pkt_len = 0;
|
||||||
|
|
||||||
|
/* first of all, find the frame length */
|
||||||
|
index = current_rb_index;
|
||||||
|
while (rb_descriptors[index].addr & RxDESC_FLAG_OWNSHIP)
|
||||||
|
{
|
||||||
|
pkt_len = rb_descriptors[index].status & RxDESC_STATUS_BUF_SIZE;
|
||||||
|
if (pkt_len > 0) break;
|
||||||
|
|
||||||
|
index ++;
|
||||||
|
if (index > RB_BUFFER_SIZE) index = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pkt_len)
|
||||||
|
{
|
||||||
|
p = pbuf_alloc(PBUF_LINK, pkt_len, PBUF_RAM);
|
||||||
|
if(p != RT_NULL)
|
||||||
|
{
|
||||||
|
sam7xether_read_frame(RT_NULL, 0, pkt_len);
|
||||||
|
for(q = p; q != RT_NULL; q= q->next)
|
||||||
|
sam7xether_read_frame(q->payload, q->len, pkt_len);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rt_kprintf("no memory in pbuf\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* enable interrupt */
|
||||||
|
AT91C_BASE_EMAC->EMAC_IER = AT91C_EMAC_RCOMP;
|
||||||
|
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sam7xether_register(char *name)
|
||||||
|
{
|
||||||
|
rt_err_t result;
|
||||||
|
|
||||||
|
/* init rt-thread device interface */
|
||||||
|
sam7x_dev_entry.parent.parent.init = sam7xether_init;
|
||||||
|
sam7x_dev_entry.parent.parent.open = sam7xether_open;
|
||||||
|
sam7x_dev_entry.parent.parent.close = sam7xether_close;
|
||||||
|
sam7x_dev_entry.parent.parent.read = sam7xether_read;
|
||||||
|
sam7x_dev_entry.parent.parent.write = sam7xether_write;
|
||||||
|
sam7x_dev_entry.parent.parent.control = sam7xether_control;
|
||||||
|
sam7x_dev_entry.parent.eth_rx = sam7xether_rx;
|
||||||
|
sam7x_dev_entry.parent.eth_tx = sam7xether_tx;
|
||||||
|
|
||||||
|
/* Update MAC address */
|
||||||
|
sam7x_dev_entry.dev_addr[0] = 0x1e;
|
||||||
|
sam7x_dev_entry.dev_addr[1] = 0x30;
|
||||||
|
sam7x_dev_entry.dev_addr[2] = 0x6c;
|
||||||
|
sam7x_dev_entry.dev_addr[3] = 0xa2;
|
||||||
|
sam7x_dev_entry.dev_addr[4] = 0x45;
|
||||||
|
sam7x_dev_entry.dev_addr[5] = 0x5e;
|
||||||
|
/* update mac address */
|
||||||
|
update_mac_address(sam7x_dev);
|
||||||
|
|
||||||
|
rt_sem_init(&tx_sem, "emac", 1, RT_IPC_FLAG_FIFO);
|
||||||
|
|
||||||
|
result = eth_device_init(&(sam7x_dev->parent), (char*)name);
|
||||||
|
RT_ASSERT(result == RT_EOK);
|
||||||
|
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
|
@ -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
|
|
@ -0,0 +1,396 @@
|
||||||
|
/*
|
||||||
|
* File : serial.c
|
||||||
|
* This file is part of RT-Thread RTOS
|
||||||
|
* COPYRIGHT (C) 2006, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* The license and distribution terms for this file may be
|
||||||
|
* found in the file LICENSE in this distribution or at
|
||||||
|
* http://openlab.rt-thread.com/license/LICENSE
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2006-08-23 Bernard first version
|
||||||
|
* 2009-05-14 Bernard add RT-THread device interface
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <rthw.h>
|
||||||
|
#include <rtthread.h>
|
||||||
|
|
||||||
|
#include "AT91SAM7X.h"
|
||||||
|
#include "serial.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @addtogroup AT91SAM7X256
|
||||||
|
*/
|
||||||
|
/*@{*/
|
||||||
|
typedef volatile rt_uint32_t REG32;
|
||||||
|
struct rt_at91serial_hw
|
||||||
|
{
|
||||||
|
REG32 US_CR; // Control Register
|
||||||
|
REG32 US_MR; // Mode Register
|
||||||
|
REG32 US_IER; // Interrupt Enable Register
|
||||||
|
REG32 US_IDR; // Interrupt Disable Register
|
||||||
|
REG32 US_IMR; // Interrupt Mask Register
|
||||||
|
REG32 US_CSR; // Channel Status Register
|
||||||
|
REG32 US_RHR; // Receiver Holding Register
|
||||||
|
REG32 US_THR; // Transmitter Holding Register
|
||||||
|
REG32 US_BRGR; // Baud Rate Generator Register
|
||||||
|
REG32 US_RTOR; // Receiver Time-out Register
|
||||||
|
REG32 US_TTGR; // Transmitter Time-guard Register
|
||||||
|
REG32 Reserved0[5]; //
|
||||||
|
REG32 US_FIDI; // FI_DI_Ratio Register
|
||||||
|
REG32 US_NER; // Nb Errors Register
|
||||||
|
REG32 Reserved1[1]; //
|
||||||
|
REG32 US_IF; // IRDA_FILTER Register
|
||||||
|
REG32 Reserved2[44]; //
|
||||||
|
REG32 US_RPR; // Receive Pointer Register
|
||||||
|
REG32 US_RCR; // Receive Counter Register
|
||||||
|
REG32 US_TPR; // Transmit Pointer Register
|
||||||
|
REG32 US_TCR; // Transmit Counter Register
|
||||||
|
REG32 US_RNPR; // Receive Next Pointer Register
|
||||||
|
REG32 US_RNCR; // Receive Next Counter Register
|
||||||
|
REG32 US_TNPR; // Transmit Next Pointer Register
|
||||||
|
REG32 US_TNCR; // Transmit Next Counter Register
|
||||||
|
REG32 US_PTCR; // PDC Transfer Control Register
|
||||||
|
REG32 US_PTSR; // PDC Transfer Status Register
|
||||||
|
};
|
||||||
|
|
||||||
|
struct rt_at91serial
|
||||||
|
{
|
||||||
|
struct rt_device parent;
|
||||||
|
|
||||||
|
struct rt_at91serial_hw* hw_base;
|
||||||
|
rt_uint16_t peripheral_id;
|
||||||
|
rt_uint32_t baudrate;
|
||||||
|
|
||||||
|
/* reception field */
|
||||||
|
rt_uint16_t save_index, read_index;
|
||||||
|
rt_uint8_t rx_buffer[RT_UART_RX_BUFFER_SIZE];
|
||||||
|
};
|
||||||
|
#ifdef RT_USING_UART1
|
||||||
|
struct rt_at91serial serial1;
|
||||||
|
#endif
|
||||||
|
#ifdef RT_USING_UART2
|
||||||
|
struct rt_at91serial serial2;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void rt_hw_serial_isr(int irqno)
|
||||||
|
{
|
||||||
|
rt_base_t level;
|
||||||
|
struct rt_device* device;
|
||||||
|
struct rt_at91serial* serial = RT_NULL;
|
||||||
|
|
||||||
|
#ifdef RT_USING_UART1
|
||||||
|
if (irqno == AT91C_ID_US0)
|
||||||
|
{
|
||||||
|
/* serial 1 */
|
||||||
|
serial = &serial1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef RT_USING_UART2
|
||||||
|
if (irqno == AT91C_ID_US1)
|
||||||
|
{
|
||||||
|
/* serial 2 */
|
||||||
|
serial = &serial2;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
RT_ASSERT(serial != RT_NULL);
|
||||||
|
|
||||||
|
/* get generic device object */
|
||||||
|
device = (rt_device_t)serial;
|
||||||
|
|
||||||
|
/* disable interrupt */
|
||||||
|
level = rt_hw_interrupt_disable();
|
||||||
|
|
||||||
|
/* get received character */
|
||||||
|
serial->rx_buffer[serial->save_index] = serial->hw_base->US_RHR;
|
||||||
|
|
||||||
|
/* move to next position */
|
||||||
|
serial->save_index ++;
|
||||||
|
if (serial->save_index >= RT_UART_RX_BUFFER_SIZE)
|
||||||
|
serial->save_index = 0;
|
||||||
|
|
||||||
|
/* if the next position is read index, discard this 'read char' */
|
||||||
|
if (serial->save_index == serial->read_index)
|
||||||
|
{
|
||||||
|
serial->read_index ++;
|
||||||
|
if (serial->read_index >= RT_UART_RX_BUFFER_SIZE)
|
||||||
|
serial->read_index = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* enable interrupt */
|
||||||
|
rt_hw_interrupt_enable(level);
|
||||||
|
|
||||||
|
/* indicate to upper layer application */
|
||||||
|
if (device->rx_indicate != RT_NULL)
|
||||||
|
device->rx_indicate(device, 1);
|
||||||
|
|
||||||
|
/* ack interrupt */
|
||||||
|
AT91C_AIC_EOICR = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static rt_err_t rt_serial_init (rt_device_t dev)
|
||||||
|
{
|
||||||
|
rt_uint32_t bd;
|
||||||
|
struct rt_at91serial* serial = (struct rt_at91serial*) dev;
|
||||||
|
|
||||||
|
RT_ASSERT(serial != RT_NULL);
|
||||||
|
/* must be US0 or US1 */
|
||||||
|
RT_ASSERT((serial->peripheral_id != AT91C_ID_US0) &&
|
||||||
|
(serial->peripheral_id != AT91C_ID_US1));
|
||||||
|
|
||||||
|
/* Enable Clock for USART */
|
||||||
|
AT91C_PMC_PCER = 1 << serial->peripheral_id;
|
||||||
|
|
||||||
|
/* Enable RxD0 and TxDO Pin */
|
||||||
|
if (serial->peripheral_id == AT91C_ID_US0)
|
||||||
|
{
|
||||||
|
/* set pinmux */
|
||||||
|
AT91C_PIO_PDR = (1 << 5) | (1 << 6);
|
||||||
|
}
|
||||||
|
else if (serial->peripheral_id == AT91C_ID_US1)
|
||||||
|
{
|
||||||
|
/* set pinmux */
|
||||||
|
AT91C_PIO_PDR = (1 << 21) | (1 << 22);
|
||||||
|
}
|
||||||
|
|
||||||
|
serial->hw_base->US_CR = AT91C_US_RSTRX | /* Reset Receiver */
|
||||||
|
AT91C_US_RSTTX | /* Reset Transmitter */
|
||||||
|
AT91C_US_RXDIS | /* Receiver Disable */
|
||||||
|
AT91C_US_TXDIS; /* Transmitter Disable */
|
||||||
|
|
||||||
|
serial->hw_base->US_MR = AT91C_US_USMODE_NORMAL | /* Normal Mode */
|
||||||
|
AT91C_US_CLKS_CLOCK | /* Clock = MCK */
|
||||||
|
AT91C_US_CHRL_8_BITS | /* 8-bit Data */
|
||||||
|
AT91C_US_PAR_NONE | /* No Parity */
|
||||||
|
AT91C_US_NBSTOP_1_BIT; /* 1 Stop Bit */
|
||||||
|
|
||||||
|
/* set baud rate divisor */
|
||||||
|
bd = ((MCK*10)/(serial->baudrate * 16));
|
||||||
|
if ((bd % 10) >= 5) bd = (bd / 10) + 1;
|
||||||
|
else bd /= 10;
|
||||||
|
|
||||||
|
serial->hw_base->US_BRGR = bd;
|
||||||
|
serial->hw_base->US_CR = AT91C_US_RXEN | /* Receiver Enable */
|
||||||
|
AT91C_US_TXEN; /* Transmitter Enable */
|
||||||
|
|
||||||
|
/* reset rx index */
|
||||||
|
serial->save_index = 0;
|
||||||
|
serial->read_index = 0;
|
||||||
|
|
||||||
|
/* reset rx buffer */
|
||||||
|
rt_memset(serial->rx_buffer, 0, RT_UART_RX_BUFFER_SIZE);
|
||||||
|
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static rt_err_t rt_serial_open(rt_device_t dev, rt_uint16_t oflag)
|
||||||
|
{
|
||||||
|
struct rt_at91serial *serial = (struct rt_at91serial*)dev;
|
||||||
|
RT_ASSERT(serial != RT_NULL);
|
||||||
|
|
||||||
|
if (dev->flag & RT_DEVICE_FLAG_INT_RX)
|
||||||
|
{
|
||||||
|
/* enable UART rx interrupt */
|
||||||
|
serial->hw_base->US_IER = 1 << 0; /* RxReady interrupt */
|
||||||
|
serial->hw_base->US_IMR |= 1 << 0; /* umask RxReady interrupt */
|
||||||
|
|
||||||
|
/* install UART handler */
|
||||||
|
rt_hw_interrupt_install(serial->peripheral_id, rt_hw_serial_isr, RT_NULL);
|
||||||
|
AT91C_AIC_SMR(serial->peripheral_id) = 5 | (0x01 << 5);
|
||||||
|
rt_hw_interrupt_umask(serial->peripheral_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static rt_err_t rt_serial_close(rt_device_t dev)
|
||||||
|
{
|
||||||
|
struct rt_at91serial *serial = (struct rt_at91serial*)dev;
|
||||||
|
RT_ASSERT(serial != RT_NULL);
|
||||||
|
|
||||||
|
if (dev->flag & RT_DEVICE_FLAG_INT_RX)
|
||||||
|
{
|
||||||
|
/* disable interrupt */
|
||||||
|
serial->hw_base->US_IDR = 1 << 0; /* RxReady interrupt */
|
||||||
|
serial->hw_base->US_IMR &= ~(1 << 0); /* mask RxReady interrupt */
|
||||||
|
}
|
||||||
|
|
||||||
|
serial->hw_base->US_CR = AT91C_US_RSTRX | /* Reset Receiver */
|
||||||
|
AT91C_US_RSTTX | /* Reset Transmitter */
|
||||||
|
AT91C_US_RXDIS | /* Receiver Disable */
|
||||||
|
AT91C_US_TXDIS; /* Transmitter Disable */
|
||||||
|
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static rt_size_t rt_serial_read (rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
|
||||||
|
{
|
||||||
|
rt_uint8_t* ptr;
|
||||||
|
struct rt_at91serial *serial = (struct rt_at91serial*)dev;
|
||||||
|
RT_ASSERT(serial != RT_NULL);
|
||||||
|
|
||||||
|
/* point to buffer */
|
||||||
|
ptr = (rt_uint8_t*) buffer;
|
||||||
|
|
||||||
|
if (dev->flag & RT_DEVICE_FLAG_INT_RX)
|
||||||
|
{
|
||||||
|
while (size)
|
||||||
|
{
|
||||||
|
/* interrupt receive */
|
||||||
|
rt_base_t level;
|
||||||
|
|
||||||
|
/* disable interrupt */
|
||||||
|
level = rt_hw_interrupt_disable();
|
||||||
|
if (serial->read_index != serial->save_index)
|
||||||
|
{
|
||||||
|
*ptr = serial->rx_buffer[serial->read_index];
|
||||||
|
|
||||||
|
serial->read_index ++;
|
||||||
|
if (serial->read_index >= RT_UART_RX_BUFFER_SIZE)
|
||||||
|
serial->read_index = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* no data in rx buffer */
|
||||||
|
|
||||||
|
/* enable interrupt */
|
||||||
|
rt_hw_interrupt_enable(level);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* enable interrupt */
|
||||||
|
rt_hw_interrupt_enable(level);
|
||||||
|
|
||||||
|
ptr ++;
|
||||||
|
size --;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (rt_uint32_t)ptr - (rt_uint32_t)buffer;
|
||||||
|
}
|
||||||
|
else if (dev->flag & RT_DEVICE_FLAG_DMA_RX)
|
||||||
|
{
|
||||||
|
/* not support right now */
|
||||||
|
RT_ASSERT(0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* poll mode */
|
||||||
|
while (size)
|
||||||
|
{
|
||||||
|
/* Wait for Full Rx Buffer */
|
||||||
|
while (!(serial->hw_base->US_CSR & AT91C_US_RXRDY));
|
||||||
|
|
||||||
|
/* Read Character */
|
||||||
|
*ptr = serial->hw_base->US_RHR;
|
||||||
|
ptr ++;
|
||||||
|
size --;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (rt_size_t)ptr - (rt_size_t)buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static rt_size_t rt_serial_write (rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
|
||||||
|
{
|
||||||
|
rt_uint8_t* ptr;
|
||||||
|
struct rt_at91serial *serial = (struct rt_at91serial*)dev;
|
||||||
|
RT_ASSERT(serial != RT_NULL);
|
||||||
|
|
||||||
|
ptr = (rt_uint8_t*) buffer;
|
||||||
|
if (dev->open_flag & RT_DEVICE_OFLAG_WRONLY)
|
||||||
|
{
|
||||||
|
if (dev->flag & RT_DEVICE_FLAG_STREAM)
|
||||||
|
{
|
||||||
|
/* it's a stream mode device */
|
||||||
|
while (size)
|
||||||
|
{
|
||||||
|
/* stream mode */
|
||||||
|
if (*ptr == '\n')
|
||||||
|
{
|
||||||
|
while (!(serial->hw_base->US_CSR & AT91C_US_TXRDY));
|
||||||
|
serial->hw_base->US_THR = '\r';
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Wait for Empty Tx Buffer */
|
||||||
|
while (!(serial->hw_base->US_CSR & AT91C_US_TXRDY));
|
||||||
|
|
||||||
|
/* Transmit Character */
|
||||||
|
serial->hw_base->US_THR = *ptr;
|
||||||
|
ptr ++;
|
||||||
|
size --;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
while (size)
|
||||||
|
{
|
||||||
|
/* Wait for Empty Tx Buffer */
|
||||||
|
while (!(serial->hw_base->US_CSR & AT91C_US_TXRDY));
|
||||||
|
|
||||||
|
/* Transmit Character */
|
||||||
|
serial->hw_base->US_THR = *ptr;
|
||||||
|
ptr ++;
|
||||||
|
size --;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (rt_size_t)ptr - (rt_size_t)buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
static rt_err_t rt_serial_control (rt_device_t dev, rt_uint8_t cmd, void *args)
|
||||||
|
{
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
rt_err_t rt_hw_serial_init()
|
||||||
|
{
|
||||||
|
rt_device_t device;
|
||||||
|
|
||||||
|
#ifdef RT_USING_UART1
|
||||||
|
device = (rt_device_t) &serial1;
|
||||||
|
|
||||||
|
/* init serial device private data */
|
||||||
|
serial1.hw_base = (struct rt_at91serial_hw*)AT91C_BASE_US0;
|
||||||
|
serial1.peripheral_id = AT91C_ID_US0;
|
||||||
|
serial1.baudrate = 115200;
|
||||||
|
|
||||||
|
/* set device virtual interface */
|
||||||
|
device->init = rt_serial_init;
|
||||||
|
device->open = rt_serial_open;
|
||||||
|
device->close = rt_serial_close;
|
||||||
|
device->read = rt_serial_read;
|
||||||
|
device->write = rt_serial_write;
|
||||||
|
device->control = rt_serial_control;
|
||||||
|
|
||||||
|
/* register uart1 on device subsystem */
|
||||||
|
rt_device_register(device, "uart1", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef RT_USING_UART2
|
||||||
|
device = (rt_device_t) &serial2;
|
||||||
|
|
||||||
|
serial2.hw_base = (struct rt_at91serial_hw*)AT91C_BASE_US1;
|
||||||
|
serial2.peripheral_id = AT91C_ID_US1;
|
||||||
|
serial2.baudrate = 115200;
|
||||||
|
|
||||||
|
/* set device virtual interface */
|
||||||
|
device->init = rt_serial_init;
|
||||||
|
device->open = rt_serial_open;
|
||||||
|
device->close = rt_serial_close;
|
||||||
|
device->read = rt_serial_read;
|
||||||
|
device->write = rt_serial_write;
|
||||||
|
device->control = rt_serial_control;
|
||||||
|
|
||||||
|
/* register uart2 on device subsystem */
|
||||||
|
rt_device_register(device, "uart2", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*@}*/
|
|
@ -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
|
|
@ -0,0 +1,60 @@
|
||||||
|
/*
|
||||||
|
* File : stack.c
|
||||||
|
* This file is part of RT-Thread RTOS
|
||||||
|
* COPYRIGHT (C) 2006, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* The license and distribution terms for this file may be
|
||||||
|
* found in the file LICENSE in this distribution or at
|
||||||
|
* http://openlab.rt-thread.com/license/LICENSE
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2006-08-23 Bernard the first version
|
||||||
|
*/
|
||||||
|
#include <rtthread.h>
|
||||||
|
#include "AT91SAM7X.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @addtogroup AT91SAM7
|
||||||
|
*/
|
||||||
|
/*@{*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function will initialize thread stack
|
||||||
|
*
|
||||||
|
* @param tentry the entry of thread
|
||||||
|
* @param parameter the parameter of entry
|
||||||
|
* @param stack_addr the beginning stack address
|
||||||
|
* @param texit the function will be called when thread exit
|
||||||
|
*
|
||||||
|
* @return stack address
|
||||||
|
*/
|
||||||
|
rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter,
|
||||||
|
rt_uint8_t *stack_addr, void *texit)
|
||||||
|
{
|
||||||
|
unsigned long *stk;
|
||||||
|
|
||||||
|
stk = (unsigned long *)stack_addr;
|
||||||
|
*(stk) = (unsigned long)tentry; /* entry point */
|
||||||
|
*(--stk) = (unsigned long)texit; /* lr */
|
||||||
|
*(--stk) = 0; /* r12 */
|
||||||
|
*(--stk) = 0; /* r11 */
|
||||||
|
*(--stk) = 0; /* r10 */
|
||||||
|
*(--stk) = 0; /* r9 */
|
||||||
|
*(--stk) = 0; /* r8 */
|
||||||
|
*(--stk) = 0; /* r7 */
|
||||||
|
*(--stk) = 0; /* r6 */
|
||||||
|
*(--stk) = 0; /* r5 */
|
||||||
|
*(--stk) = 0; /* r4 */
|
||||||
|
*(--stk) = 0; /* r3 */
|
||||||
|
*(--stk) = 0; /* r2 */
|
||||||
|
*(--stk) = 0; /* r1 */
|
||||||
|
*(--stk) = (unsigned long)parameter; /* r0 : argument */
|
||||||
|
*(--stk) = SVCMODE; /* cpsr */
|
||||||
|
*(--stk) = SVCMODE; /* spsr */
|
||||||
|
|
||||||
|
/* return task's current stack address */
|
||||||
|
return (rt_uint8_t *)stk;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*@}*/
|
|
@ -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
|
|
@ -0,0 +1,498 @@
|
||||||
|
;/*****************************************************************************/
|
||||||
|
;/* SAM7.S: Startup file for Atmel AT91SAM7 device series */
|
||||||
|
;/*****************************************************************************/
|
||||||
|
;/* <<< Use Configuration Wizard in Context Menu >>> */
|
||||||
|
;/*****************************************************************************/
|
||||||
|
;/* This file is part of the uVision/ARM development tools. */
|
||||||
|
;/* Copyright (c) 2005-2006 Keil Software. All rights reserved. */
|
||||||
|
;/* This software may only be used under the terms of a valid, current, */
|
||||||
|
;/* end user licence from KEIL for a compatible version of KEIL software */
|
||||||
|
;/* development tools. Nothing else gives you the right to use this software. */
|
||||||
|
;/*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
;/*
|
||||||
|
; * The SAM7.S code is executed after CPU Reset. This file may be
|
||||||
|
; * translated with the following SET symbols. In uVision these SET
|
||||||
|
; * symbols are entered under Options - ASM - Define.
|
||||||
|
; *
|
||||||
|
; * REMAP: when set the startup code remaps exception vectors from
|
||||||
|
; * on-chip RAM to address 0.
|
||||||
|
; *
|
||||||
|
; * RAM_INTVEC: when set the startup code copies exception vectors
|
||||||
|
; * from on-chip Flash to on-chip RAM.
|
||||||
|
; */
|
||||||
|
|
||||||
|
|
||||||
|
; Standard definitions of Mode bits and Interrupt (I & F) flags in PSRs
|
||||||
|
|
||||||
|
Mode_USR EQU 0x10
|
||||||
|
Mode_FIQ EQU 0x11
|
||||||
|
Mode_IRQ EQU 0x12
|
||||||
|
Mode_SVC EQU 0x13
|
||||||
|
Mode_ABT EQU 0x17
|
||||||
|
Mode_UND EQU 0x1B
|
||||||
|
Mode_SYS EQU 0x1F
|
||||||
|
|
||||||
|
I_Bit EQU 0x80 ; when I bit is set, IRQ is disabled
|
||||||
|
F_Bit EQU 0x40 ; when F bit is set, FIQ is disabled
|
||||||
|
|
||||||
|
|
||||||
|
; Internal Memory Base Addresses
|
||||||
|
FLASH_BASE EQU 0x00100000
|
||||||
|
RAM_BASE EQU 0x00200000
|
||||||
|
|
||||||
|
|
||||||
|
;// <h> Stack Configuration (Stack Sizes in Bytes)
|
||||||
|
;// <o0> Undefined Mode <0x0-0xFFFFFFFF:8>
|
||||||
|
;// <o1> Supervisor Mode <0x0-0xFFFFFFFF:8>
|
||||||
|
;// <o2> Abort Mode <0x0-0xFFFFFFFF:8>
|
||||||
|
;// <o3> Fast Interrupt Mode <0x0-0xFFFFFFFF:8>
|
||||||
|
;// <o4> Interrupt Mode <0x0-0xFFFFFFFF:8>
|
||||||
|
;// <o5> User/System Mode <0x0-0xFFFFFFFF:8>
|
||||||
|
;// </h>
|
||||||
|
|
||||||
|
UND_Stack_Size EQU 0x00000000
|
||||||
|
SVC_Stack_Size EQU 0x00000100
|
||||||
|
ABT_Stack_Size EQU 0x00000000
|
||||||
|
FIQ_Stack_Size EQU 0x00000000
|
||||||
|
IRQ_Stack_Size EQU 0x00000100
|
||||||
|
USR_Stack_Size EQU 0x00000100
|
||||||
|
|
||||||
|
ISR_Stack_Size EQU (UND_Stack_Size + SVC_Stack_Size + ABT_Stack_Size + \
|
||||||
|
FIQ_Stack_Size + IRQ_Stack_Size)
|
||||||
|
|
||||||
|
AREA STACK, NOINIT, READWRITE, ALIGN=3
|
||||||
|
|
||||||
|
Stack_Mem SPACE USR_Stack_Size
|
||||||
|
__initial_sp SPACE ISR_Stack_Size
|
||||||
|
Stack_Top
|
||||||
|
|
||||||
|
|
||||||
|
;// <h> Heap Configuration
|
||||||
|
;// <o> Heap Size (in Bytes) <0x0-0xFFFFFFFF>
|
||||||
|
;// </h>
|
||||||
|
|
||||||
|
Heap_Size EQU 0x00000000
|
||||||
|
|
||||||
|
AREA HEAP, NOINIT, READWRITE, ALIGN=3
|
||||||
|
__heap_base
|
||||||
|
Heap_Mem SPACE Heap_Size
|
||||||
|
__heap_limit
|
||||||
|
|
||||||
|
|
||||||
|
; Reset Controller (RSTC) definitions
|
||||||
|
RSTC_BASE EQU 0xFFFFFD00 ; RSTC Base Address
|
||||||
|
RSTC_MR EQU 0x08 ; RSTC_MR Offset
|
||||||
|
|
||||||
|
;/*
|
||||||
|
;// <e> Reset Controller (RSTC)
|
||||||
|
;// <o1.0> URSTEN: User Reset Enable
|
||||||
|
;// <i> Enables NRST Pin to generate Reset
|
||||||
|
;// <o1.8..11> ERSTL: External Reset Length <0-15>
|
||||||
|
;// <i> External Reset Time in 2^(ERSTL+1) Slow Clock Cycles
|
||||||
|
;// </e>
|
||||||
|
;*/
|
||||||
|
RSTC_SETUP EQU 1
|
||||||
|
RSTC_MR_Val EQU 0xA5000401
|
||||||
|
|
||||||
|
|
||||||
|
; Embedded Flash Controller (EFC) definitions
|
||||||
|
EFC_BASE EQU 0xFFFFFF00 ; EFC Base Address
|
||||||
|
EFC0_FMR EQU 0x60 ; EFC0_FMR Offset
|
||||||
|
EFC1_FMR EQU 0x70 ; EFC1_FMR Offset
|
||||||
|
|
||||||
|
;// <e> Embedded Flash Controller 0 (EFC0)
|
||||||
|
;// <o1.16..23> FMCN: Flash Microsecond Cycle Number <0-255>
|
||||||
|
;// <i> Number of Master Clock Cycles in 1us
|
||||||
|
;// <o1.8..9> FWS: Flash Wait State
|
||||||
|
;// <0=> Read: 1 cycle / Write: 2 cycles
|
||||||
|
;// <1=> Read: 2 cycle / Write: 3 cycles
|
||||||
|
;// <2=> Read: 3 cycle / Write: 4 cycles
|
||||||
|
;// <3=> Read: 4 cycle / Write: 4 cycles
|
||||||
|
;// </e>
|
||||||
|
EFC0_SETUP EQU 1
|
||||||
|
EFC0_FMR_Val EQU 0x00320100
|
||||||
|
|
||||||
|
;// <e> Embedded Flash Controller 1 (EFC1)
|
||||||
|
;// <o1.16..23> FMCN: Flash Microsecond Cycle Number <0-255>
|
||||||
|
;// <i> Number of Master Clock Cycles in 1us
|
||||||
|
;// <o1.8..9> FWS: Flash Wait State
|
||||||
|
;// <0=> Read: 1 cycle / Write: 2 cycles
|
||||||
|
;// <1=> Read: 2 cycle / Write: 3 cycles
|
||||||
|
;// <2=> Read: 3 cycle / Write: 4 cycles
|
||||||
|
;// <3=> Read: 4 cycle / Write: 4 cycles
|
||||||
|
;// </e>
|
||||||
|
EFC1_SETUP EQU 0
|
||||||
|
EFC1_FMR_Val EQU 0x00320100
|
||||||
|
|
||||||
|
|
||||||
|
; Watchdog Timer (WDT) definitions
|
||||||
|
WDT_BASE EQU 0xFFFFFD40 ; WDT Base Address
|
||||||
|
WDT_MR EQU 0x04 ; WDT_MR Offset
|
||||||
|
|
||||||
|
;// <e> Watchdog Timer (WDT)
|
||||||
|
;// <o1.0..11> WDV: Watchdog Counter Value <0-4095>
|
||||||
|
;// <o1.16..27> WDD: Watchdog Delta Value <0-4095>
|
||||||
|
;// <o1.12> WDFIEN: Watchdog Fault Interrupt Enable
|
||||||
|
;// <o1.13> WDRSTEN: Watchdog Reset Enable
|
||||||
|
;// <o1.14> WDRPROC: Watchdog Reset Processor
|
||||||
|
;// <o1.28> WDDBGHLT: Watchdog Debug Halt
|
||||||
|
;// <o1.29> WDIDLEHLT: Watchdog Idle Halt
|
||||||
|
;// <o1.15> WDDIS: Watchdog Disable
|
||||||
|
;// </e>
|
||||||
|
WDT_SETUP EQU 1
|
||||||
|
WDT_MR_Val EQU 0x00008000
|
||||||
|
|
||||||
|
|
||||||
|
; Power Mangement Controller (PMC) definitions
|
||||||
|
PMC_BASE EQU 0xFFFFFC00 ; PMC Base Address
|
||||||
|
PMC_MOR EQU 0x20 ; PMC_MOR Offset
|
||||||
|
PMC_MCFR EQU 0x24 ; PMC_MCFR Offset
|
||||||
|
PMC_PLLR EQU 0x2C ; PMC_PLLR Offset
|
||||||
|
PMC_MCKR EQU 0x30 ; PMC_MCKR Offset
|
||||||
|
PMC_SR EQU 0x68 ; PMC_SR Offset
|
||||||
|
PMC_MOSCEN EQU (1<<0) ; Main Oscillator Enable
|
||||||
|
PMC_OSCBYPASS EQU (1<<1) ; Main Oscillator Bypass
|
||||||
|
PMC_OSCOUNT EQU (0xFF<<8) ; Main OScillator Start-up Time
|
||||||
|
PMC_DIV EQU (0xFF<<0) ; PLL Divider
|
||||||
|
PMC_PLLCOUNT EQU (0x3F<<8) ; PLL Lock Counter
|
||||||
|
PMC_OUT EQU (0x03<<14) ; PLL Clock Frequency Range
|
||||||
|
PMC_MUL EQU (0x7FF<<16) ; PLL Multiplier
|
||||||
|
PMC_USBDIV EQU (0x03<<28) ; USB Clock Divider
|
||||||
|
PMC_CSS EQU (3<<0) ; Clock Source Selection
|
||||||
|
PMC_PRES EQU (7<<2) ; Prescaler Selection
|
||||||
|
PMC_MOSCS EQU (1<<0) ; Main Oscillator Stable
|
||||||
|
PMC_LOCK EQU (1<<2) ; PLL Lock Status
|
||||||
|
PMC_MCKRDY EQU (1<<3) ; Master Clock Status
|
||||||
|
|
||||||
|
;// <e> Power Mangement Controller (PMC)
|
||||||
|
;// <h> Main Oscillator
|
||||||
|
;// <o1.0> MOSCEN: Main Oscillator Enable
|
||||||
|
;// <o1.1> OSCBYPASS: Oscillator Bypass
|
||||||
|
;// <o1.8..15> OSCCOUNT: Main Oscillator Startup Time <0-255>
|
||||||
|
;// </h>
|
||||||
|
;// <h> Phase Locked Loop (PLL)
|
||||||
|
;// <o2.0..7> DIV: PLL Divider <0-255>
|
||||||
|
;// <o2.16..26> MUL: PLL Multiplier <0-2047>
|
||||||
|
;// <i> PLL Output is multiplied by MUL+1
|
||||||
|
;// <o2.14..15> OUT: PLL Clock Frequency Range
|
||||||
|
;// <0=> 80..160MHz <1=> Reserved
|
||||||
|
;// <2=> 150..220MHz <3=> Reserved
|
||||||
|
;// <o2.8..13> PLLCOUNT: PLL Lock Counter <0-63>
|
||||||
|
;// <o2.28..29> USBDIV: USB Clock Divider
|
||||||
|
;// <0=> None <1=> 2 <2=> 4 <3=> Reserved
|
||||||
|
;// </h>
|
||||||
|
;// <o3.0..1> CSS: Clock Source Selection
|
||||||
|
;// <0=> Slow Clock
|
||||||
|
;// <1=> Main Clock
|
||||||
|
;// <2=> Reserved
|
||||||
|
;// <3=> PLL Clock
|
||||||
|
;// <o3.2..4> PRES: Prescaler
|
||||||
|
;// <0=> None
|
||||||
|
;// <1=> Clock / 2 <2=> Clock / 4
|
||||||
|
;// <3=> Clock / 8 <4=> Clock / 16
|
||||||
|
;// <5=> Clock / 32 <6=> Clock / 64
|
||||||
|
;// <7=> Reserved
|
||||||
|
;// </e>
|
||||||
|
PMC_SETUP EQU 1
|
||||||
|
PMC_MOR_Val EQU 0x00000601
|
||||||
|
PMC_PLLR_Val EQU 0x00191C05
|
||||||
|
PMC_MCKR_Val EQU 0x00000007
|
||||||
|
|
||||||
|
|
||||||
|
PRESERVE8
|
||||||
|
|
||||||
|
|
||||||
|
; Area Definition and Entry Point
|
||||||
|
; Startup Code must be linked first at Address at which it expects to run.
|
||||||
|
|
||||||
|
AREA RESET, CODE, READONLY
|
||||||
|
ARM
|
||||||
|
|
||||||
|
|
||||||
|
; Exception Vectors
|
||||||
|
; Mapped to Address 0.
|
||||||
|
; Absolute addressing mode must be used.
|
||||||
|
; Dummy Handlers are implemented as infinite loops which can be modified.
|
||||||
|
|
||||||
|
Vectors LDR PC,Reset_Addr
|
||||||
|
LDR PC,Undef_Addr
|
||||||
|
LDR PC,SWI_Addr
|
||||||
|
LDR PC,PAbt_Addr
|
||||||
|
LDR PC,DAbt_Addr
|
||||||
|
NOP ; Reserved Vector
|
||||||
|
LDR PC,IRQ_Addr
|
||||||
|
LDR PC,FIQ_Addr
|
||||||
|
|
||||||
|
Reset_Addr DCD Reset_Handler
|
||||||
|
Undef_Addr DCD Undef_Handler
|
||||||
|
SWI_Addr DCD SWI_Handler
|
||||||
|
PAbt_Addr DCD PAbt_Handler
|
||||||
|
DAbt_Addr DCD DAbt_Handler
|
||||||
|
DCD 0 ; Reserved Address
|
||||||
|
IRQ_Addr DCD IRQ_Handler
|
||||||
|
FIQ_Addr DCD FIQ_Handler
|
||||||
|
|
||||||
|
Undef_Handler B Undef_Handler
|
||||||
|
SWI_Handler B SWI_Handler
|
||||||
|
PAbt_Handler B PAbt_Handler
|
||||||
|
DAbt_Handler B DAbt_Handler
|
||||||
|
FIQ_Handler B FIQ_Handler
|
||||||
|
|
||||||
|
|
||||||
|
; Reset Handler
|
||||||
|
|
||||||
|
EXPORT Reset_Handler
|
||||||
|
Reset_Handler
|
||||||
|
|
||||||
|
|
||||||
|
; Setup RSTC
|
||||||
|
IF RSTC_SETUP != 0
|
||||||
|
LDR R0, =RSTC_BASE
|
||||||
|
LDR R1, =RSTC_MR_Val
|
||||||
|
STR R1, [R0, #RSTC_MR]
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
|
||||||
|
; Setup EFC0
|
||||||
|
IF EFC0_SETUP != 0
|
||||||
|
LDR R0, =EFC_BASE
|
||||||
|
LDR R1, =EFC0_FMR_Val
|
||||||
|
STR R1, [R0, #EFC0_FMR]
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
; Setup EFC1
|
||||||
|
IF EFC1_SETUP != 0
|
||||||
|
LDR R0, =EFC_BASE
|
||||||
|
LDR R1, =EFC1_FMR_Val
|
||||||
|
STR R1, [R0, #EFC1_FMR]
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
; Setup WDT
|
||||||
|
IF WDT_SETUP != 0
|
||||||
|
LDR R0, =WDT_BASE
|
||||||
|
LDR R1, =WDT_MR_Val
|
||||||
|
STR R1, [R0, #WDT_MR]
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
|
||||||
|
; Setup PMC
|
||||||
|
IF PMC_SETUP != 0
|
||||||
|
LDR R0, =PMC_BASE
|
||||||
|
|
||||||
|
; Setup Main Oscillator
|
||||||
|
LDR R1, =PMC_MOR_Val
|
||||||
|
STR R1, [R0, #PMC_MOR]
|
||||||
|
|
||||||
|
; Wait until Main Oscillator is stablilized
|
||||||
|
IF (PMC_MOR_Val:AND:PMC_MOSCEN) != 0
|
||||||
|
MOSCS_Loop LDR R2, [R0, #PMC_SR]
|
||||||
|
ANDS R2, R2, #PMC_MOSCS
|
||||||
|
BEQ MOSCS_Loop
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
; Setup the PLL
|
||||||
|
IF (PMC_PLLR_Val:AND:PMC_MUL) != 0
|
||||||
|
LDR R1, =PMC_PLLR_Val
|
||||||
|
STR R1, [R0, #PMC_PLLR]
|
||||||
|
|
||||||
|
; Wait until PLL is stabilized
|
||||||
|
PLL_Loop LDR R2, [R0, #PMC_SR]
|
||||||
|
ANDS R2, R2, #PMC_LOCK
|
||||||
|
BEQ PLL_Loop
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
; Select Clock
|
||||||
|
IF (PMC_MCKR_Val:AND:PMC_CSS) == 1 ; Main Clock Selected
|
||||||
|
LDR R1, =PMC_MCKR_Val
|
||||||
|
AND R1, #PMC_CSS
|
||||||
|
STR R1, [R0, #PMC_MCKR]
|
||||||
|
WAIT_Rdy1 LDR R2, [R0, #PMC_SR]
|
||||||
|
ANDS R2, R2, #PMC_MCKRDY
|
||||||
|
BEQ WAIT_Rdy1
|
||||||
|
LDR R1, =PMC_MCKR_Val
|
||||||
|
STR R1, [R0, #PMC_MCKR]
|
||||||
|
WAIT_Rdy2 LDR R2, [R0, #PMC_SR]
|
||||||
|
ANDS R2, R2, #PMC_MCKRDY
|
||||||
|
BEQ WAIT_Rdy2
|
||||||
|
ELIF (PMC_MCKR_Val:AND:PMC_CSS) == 3 ; PLL Clock Selected
|
||||||
|
LDR R1, =PMC_MCKR_Val
|
||||||
|
AND R1, #PMC_PRES
|
||||||
|
STR R1, [R0, #PMC_MCKR]
|
||||||
|
WAIT_Rdy1 LDR R2, [R0, #PMC_SR]
|
||||||
|
ANDS R2, R2, #PMC_MCKRDY
|
||||||
|
BEQ WAIT_Rdy1
|
||||||
|
LDR R1, =PMC_MCKR_Val
|
||||||
|
STR R1, [R0, #PMC_MCKR]
|
||||||
|
WAIT_Rdy2 LDR R2, [R0, #PMC_SR]
|
||||||
|
ANDS R2, R2, #PMC_MCKRDY
|
||||||
|
BEQ WAIT_Rdy2
|
||||||
|
ENDIF ; Select Clock
|
||||||
|
ENDIF ; PMC_SETUP
|
||||||
|
|
||||||
|
|
||||||
|
; Copy Exception Vectors to Internal RAM
|
||||||
|
|
||||||
|
IF :DEF:RAM_INTVEC
|
||||||
|
ADR R8, Vectors ; Source
|
||||||
|
LDR R9, =RAM_BASE ; Destination
|
||||||
|
LDMIA R8!, {R0-R7} ; Load Vectors
|
||||||
|
STMIA R9!, {R0-R7} ; Store Vectors
|
||||||
|
LDMIA R8!, {R0-R7} ; Load Handler Addresses
|
||||||
|
STMIA R9!, {R0-R7} ; Store Handler Addresses
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
|
||||||
|
; Remap on-chip RAM to address 0
|
||||||
|
|
||||||
|
MC_BASE EQU 0xFFFFFF00 ; MC Base Address
|
||||||
|
MC_RCR EQU 0x00 ; MC_RCR Offset
|
||||||
|
|
||||||
|
IF :DEF:REMAP
|
||||||
|
LDR R0, =MC_BASE
|
||||||
|
MOV R1, #1
|
||||||
|
STR R1, [R0, #MC_RCR] ; Remap
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
|
||||||
|
; Setup Stack for each mode
|
||||||
|
|
||||||
|
LDR R0, =Stack_Top
|
||||||
|
|
||||||
|
; Enter Undefined Instruction Mode and set its Stack Pointer
|
||||||
|
MSR CPSR_c, #Mode_UND:OR:I_Bit:OR:F_Bit
|
||||||
|
MOV SP, R0
|
||||||
|
SUB R0, R0, #UND_Stack_Size
|
||||||
|
|
||||||
|
; Enter Abort Mode and set its Stack Pointer
|
||||||
|
MSR CPSR_c, #Mode_ABT:OR:I_Bit:OR:F_Bit
|
||||||
|
MOV SP, R0
|
||||||
|
SUB R0, R0, #ABT_Stack_Size
|
||||||
|
|
||||||
|
; Enter FIQ Mode and set its Stack Pointer
|
||||||
|
MSR CPSR_c, #Mode_FIQ:OR:I_Bit:OR:F_Bit
|
||||||
|
MOV SP, R0
|
||||||
|
SUB R0, R0, #FIQ_Stack_Size
|
||||||
|
|
||||||
|
; Enter IRQ Mode and set its Stack Pointer
|
||||||
|
MSR CPSR_c, #Mode_IRQ:OR:I_Bit:OR:F_Bit
|
||||||
|
MOV SP, R0
|
||||||
|
SUB R0, R0, #IRQ_Stack_Size
|
||||||
|
|
||||||
|
; Enter Supervisor Mode and set its Stack Pointer
|
||||||
|
MSR CPSR_c, #Mode_SVC:OR:I_Bit:OR:F_Bit
|
||||||
|
MOV SP, R0
|
||||||
|
SUB R0, R0, #SVC_Stack_Size
|
||||||
|
|
||||||
|
; Enter User Mode and set its Stack Pointer
|
||||||
|
; MSR CPSR_c, #Mode_USR
|
||||||
|
IF :DEF:__MICROLIB
|
||||||
|
|
||||||
|
EXPORT __initial_sp
|
||||||
|
|
||||||
|
ELSE
|
||||||
|
|
||||||
|
MOV SP, R0
|
||||||
|
SUB SL, SP, #USR_Stack_Size
|
||||||
|
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
|
||||||
|
; Enter the C code
|
||||||
|
|
||||||
|
IMPORT __main
|
||||||
|
LDR R0, =__main
|
||||||
|
BX R0
|
||||||
|
|
||||||
|
IMPORT rt_interrupt_enter
|
||||||
|
IMPORT rt_interrupt_leave
|
||||||
|
IMPORT rt_thread_switch_interrput_flag
|
||||||
|
IMPORT rt_interrupt_from_thread
|
||||||
|
IMPORT rt_interrupt_to_thread
|
||||||
|
IMPORT rt_hw_trap_irq
|
||||||
|
|
||||||
|
IRQ_Handler PROC
|
||||||
|
EXPORT IRQ_Handler
|
||||||
|
STMFD sp!, {r0-r12,lr}
|
||||||
|
BL rt_interrupt_enter
|
||||||
|
BL rt_hw_trap_irq
|
||||||
|
BL rt_interrupt_leave
|
||||||
|
|
||||||
|
; if rt_thread_switch_interrput_flag set, jump to
|
||||||
|
; rt_hw_context_switch_interrupt_do and don't return
|
||||||
|
LDR r0, =rt_thread_switch_interrput_flag
|
||||||
|
LDR r1, [r0]
|
||||||
|
CMP r1, #1
|
||||||
|
BEQ rt_hw_context_switch_interrupt_do
|
||||||
|
|
||||||
|
LDMFD sp!, {r0-r12,lr}
|
||||||
|
SUBS pc, lr, #4
|
||||||
|
ENDP
|
||||||
|
|
||||||
|
; /*
|
||||||
|
; * void rt_hw_context_switch_interrupt_do(rt_base_t flag)
|
||||||
|
; */
|
||||||
|
rt_hw_context_switch_interrupt_do PROC
|
||||||
|
EXPORT rt_hw_context_switch_interrupt_do
|
||||||
|
MOV r1, #0 ; clear flag
|
||||||
|
STR r1, [r0]
|
||||||
|
|
||||||
|
LDMFD sp!, {r0-r12,lr}; reload saved registers
|
||||||
|
STMFD sp!, {r0-r3} ; save r0-r3
|
||||||
|
MOV r1, sp
|
||||||
|
ADD sp, sp, #16 ; restore sp
|
||||||
|
SUB r2, lr, #4 ; save old task's pc to r2
|
||||||
|
|
||||||
|
MRS r3, spsr ; get cpsr of interrupt thread
|
||||||
|
|
||||||
|
; switch to SVC mode and no interrupt
|
||||||
|
MSR cpsr_c, #I_Bit|F_Bit|Mode_SVC
|
||||||
|
|
||||||
|
STMFD sp!, {r2} ; push old task's pc
|
||||||
|
STMFD sp!, {r4-r12,lr}; push old task's lr,r12-r4
|
||||||
|
MOV r4, r1 ; Special optimised code below
|
||||||
|
MOV r5, r3
|
||||||
|
LDMFD r4!, {r0-r3}
|
||||||
|
STMFD sp!, {r0-r3} ; push old task's r3-r0
|
||||||
|
STMFD sp!, {r5} ; push old task's cpsr
|
||||||
|
MRS r4, spsr
|
||||||
|
STMFD sp!, {r4} ; push old task's spsr
|
||||||
|
|
||||||
|
LDR r4, =rt_interrupt_from_thread
|
||||||
|
LDR r5, [r4]
|
||||||
|
STR sp, [r5] ; store sp in preempted tasks's TCB
|
||||||
|
|
||||||
|
LDR r6, =rt_interrupt_to_thread
|
||||||
|
LDR r6, [r6]
|
||||||
|
LDR sp, [r6] ; get new task's stack pointer
|
||||||
|
|
||||||
|
LDMFD sp!, {r4} ; pop new task's spsr
|
||||||
|
MSR spsr_cxsf, r4
|
||||||
|
LDMFD sp!, {r4} ; pop new task's psr
|
||||||
|
MSR cpsr_cxsf, r4
|
||||||
|
|
||||||
|
LDMFD sp!, {r0-r12,lr,pc} ; pop new task's r0-r12,lr & pc
|
||||||
|
ENDP
|
||||||
|
|
||||||
|
IF :DEF:__MICROLIB
|
||||||
|
|
||||||
|
EXPORT __heap_base
|
||||||
|
EXPORT __heap_limit
|
||||||
|
|
||||||
|
ELSE
|
||||||
|
; User Initial Stack & Heap
|
||||||
|
AREA |.text|, CODE, READONLY
|
||||||
|
|
||||||
|
IMPORT __use_two_region_memory
|
||||||
|
EXPORT __user_initial_stackheap
|
||||||
|
__user_initial_stackheap
|
||||||
|
|
||||||
|
LDR R0, = Heap_Mem
|
||||||
|
LDR R1, =(Stack_Mem + USR_Stack_Size)
|
||||||
|
LDR R2, = (Heap_Mem + Heap_Size)
|
||||||
|
LDR R3, = Stack_Mem
|
||||||
|
BX LR
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
END
|
|
@ -0,0 +1,40 @@
|
||||||
|
/*
|
||||||
|
* File : trap.c
|
||||||
|
* This file is part of RT-Thread RTOS
|
||||||
|
* COPYRIGHT (C) 2006, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* The license and distribution terms for this file may be
|
||||||
|
* found in the file LICENSE in this distribution or at
|
||||||
|
* http://openlab.rt-thread.com/license/LICENSE
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2006-08-25 Bernard first version
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <rtthread.h>
|
||||||
|
#include <rthw.h>
|
||||||
|
|
||||||
|
#include "AT91SAM7X.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @addtogroup AT91SAM7
|
||||||
|
*/
|
||||||
|
/*@{*/
|
||||||
|
|
||||||
|
void rt_hw_trap_irq()
|
||||||
|
{
|
||||||
|
rt_isr_handler_t hander = (rt_isr_handler_t)AT91C_AIC_IVR;
|
||||||
|
|
||||||
|
hander(AT91C_AIC_ISR);
|
||||||
|
|
||||||
|
/* end of interrupt */
|
||||||
|
AT91C_AIC_EOICR = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void rt_hw_trap_fiq()
|
||||||
|
{
|
||||||
|
rt_kprintf("fast interrupt request\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*@}*/
|
|
@ -0,0 +1,67 @@
|
||||||
|
/*
|
||||||
|
* File : backtrace.c
|
||||||
|
* This file is part of RT-Thread RTOS
|
||||||
|
* COPYRIGHT (C) 2006, 2008 RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* The license and distribution terms for this file may be
|
||||||
|
* found in the file LICENSE in this distribution or at
|
||||||
|
* http://openlab.rt-thread.com/license/LICENSE
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2008-07-29 Bernard first version from QiuYi implementation
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <rtthread.h>
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
/*
|
||||||
|
-->High Address,Stack Top
|
||||||
|
PC<-----|
|
||||||
|
LR |
|
||||||
|
IP |
|
||||||
|
FP |
|
||||||
|
...... |
|
||||||
|
PC<-| |
|
||||||
|
LR | |
|
||||||
|
IP | |
|
||||||
|
FP---|-- |
|
||||||
|
...... |
|
||||||
|
PC |
|
||||||
|
LR |
|
||||||
|
IP |
|
||||||
|
FP---
|
||||||
|
-->Low Address,Stack Bottom
|
||||||
|
*/
|
||||||
|
void rt_hw_backtrace(rt_uint32_t *fp, rt_uint32_t thread_entry)
|
||||||
|
{
|
||||||
|
rt_uint32_t i, pc, func_entry;
|
||||||
|
|
||||||
|
pc = *fp;
|
||||||
|
rt_kprintf("[0x%x]\n", pc-0xC);
|
||||||
|
|
||||||
|
for(i=0; i<10; i++)
|
||||||
|
{
|
||||||
|
fp = *(fp - 3);
|
||||||
|
pc = *fp ;
|
||||||
|
|
||||||
|
func_entry = pc - 0xC;
|
||||||
|
|
||||||
|
if(func_entry <= 0x30000000) break;
|
||||||
|
|
||||||
|
if((func_entry == thread_entry))
|
||||||
|
{
|
||||||
|
rt_kprintf("EntryPoint:0x%x\n", func_entry);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
rt_kprintf("[0x%x]\n", func_entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
void rt_hw_backtrace(rt_uint32_t *fp, rt_uint32_t thread_entry)
|
||||||
|
{
|
||||||
|
/* old compiler implementation */
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -0,0 +1,4 @@
|
||||||
|
void __div0 (void)
|
||||||
|
{
|
||||||
|
while (1) ;
|
||||||
|
}
|
|
@ -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
|
|
@ -0,0 +1,42 @@
|
||||||
|
/*
|
||||||
|
* File : showmem.c
|
||||||
|
* This file is part of RT-Thread RTOS
|
||||||
|
* COPYRIGHT (C) 2006, 2008 RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* The license and distribution terms for this file may be
|
||||||
|
* found in the file LICENSE in this distribution or at
|
||||||
|
* http://openlab.rt-thread.com/license/LICENSE
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2008-07-29 Bernard first version from QiuYi implementation
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <rtthread.h>
|
||||||
|
|
||||||
|
void rt_hw_show_memory(rt_uint32_t addr, rt_uint32_t size)
|
||||||
|
{
|
||||||
|
int i = 0, j =0;
|
||||||
|
|
||||||
|
RT_ASSERT(addr);
|
||||||
|
|
||||||
|
addr = addr & ~0xF;
|
||||||
|
size = 4*((size + 3)/4);
|
||||||
|
|
||||||
|
while(i < size)
|
||||||
|
{
|
||||||
|
rt_kprintf("0x%08x: ", addr );
|
||||||
|
|
||||||
|
for(j=0; j<4; j++)
|
||||||
|
{
|
||||||
|
rt_kprintf("0x%08x ", *(rt_uint32_t *)addr);
|
||||||
|
|
||||||
|
addr += 4;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
rt_kprintf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
|
@ -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
|
|
@ -0,0 +1,42 @@
|
||||||
|
/*
|
||||||
|
* File : cpu.c
|
||||||
|
* This file is part of RT-Thread RTOS
|
||||||
|
* COPYRIGHT (C) 2006, RT-Thread Develop Team
|
||||||
|
*
|
||||||
|
* The license and distribution terms for this file may be
|
||||||
|
* found in the file LICENSE in this distribution or at
|
||||||
|
* http://openlab.rt-thread.com/license/LICENSE
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2006-03-13 Bernard first version
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <rtthread.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @addtogroup S3C2410
|
||||||
|
*/
|
||||||
|
/*@{*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* reset cpu by dog's time-out
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void rt_hw_cpu_reset()
|
||||||
|
{
|
||||||
|
/*NOTREACHED*/
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* shutdown CPU
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void rt_hw_cpu_shutdown()
|
||||||
|
{
|
||||||
|
rt_kprintf("shutdown...\n");
|
||||||
|
|
||||||
|
RT_ASSERT(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*@}*/
|
|
@ -0,0 +1,25 @@
|
||||||
|
/*
|
||||||
|
* File : trap.c
|
||||||
|
* This file is part of RT-Thread RTOS
|
||||||
|
* COPYRIGHT (C) 2006, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* The license and distribution terms for this file may be
|
||||||
|
* found in the file LICENSE in this distribution or at
|
||||||
|
* http://openlab.rt-thread.com/license/LICENSE
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2006-03-13 Bernard first version
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <rtthread.h>
|
||||||
|
|
||||||
|
#define MAX_HANDLERS 32
|
||||||
|
|
||||||
|
extern rt_uint32_t rt_interrupt_nest;
|
||||||
|
|
||||||
|
/* exception and interrupt handler table */
|
||||||
|
rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread;
|
||||||
|
rt_uint32_t rt_thread_switch_interrput_flag;
|
||||||
|
|
||||||
|
/*@}*/
|
|
@ -0,0 +1,42 @@
|
||||||
|
#include <rtthread.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Only need when RealView MDK is used.
|
||||||
|
*/
|
||||||
|
void *rt_memset(void * s, int c, rt_ubase_t count)
|
||||||
|
{
|
||||||
|
return memset(s, c, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *rt_memcpy(void * dst, const void *src, rt_ubase_t count)
|
||||||
|
{
|
||||||
|
return memcpy(dst, src, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
rt_ubase_t rt_strncmp(const char * cs, const char * ct, rt_ubase_t count)
|
||||||
|
{
|
||||||
|
return strncmp(cs, ct, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function will show the version of rt-thread rtos
|
||||||
|
*/
|
||||||
|
void rt_show_version()
|
||||||
|
{
|
||||||
|
rt_kprintf(" \\ | /\n");
|
||||||
|
rt_kprintf("- RT - Thread Operating System\n");
|
||||||
|
rt_kprintf(" / | \\ 0.%d.%d build %s\n", RT_VERSION, RT_SUBVERSION, __DATE__);
|
||||||
|
rt_kprintf(" 2006 - 2009 Copyright by rt-thread team\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void rt_kprintf(const char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
|
||||||
|
va_start(args, fmt);
|
||||||
|
vprintf(fmt, args);
|
||||||
|
va_end(args);
|
||||||
|
}
|
|
@ -0,0 +1,362 @@
|
||||||
|
/*
|
||||||
|
* File : serial.c
|
||||||
|
* This file is part of RT-Thread RTOS
|
||||||
|
* COPYRIGHT (C) 2006, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* The license and distribution terms for this file may be
|
||||||
|
* found in the file LICENSE in this distribution or at
|
||||||
|
* http://openlab.rt-thread.com/license/LICENSE
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2009-06-11 Bernard first version
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <rthw.h>
|
||||||
|
#include <rtthread.h>
|
||||||
|
|
||||||
|
#include <inc/hw_types.h>
|
||||||
|
#include <inc/hw_memmap.h>
|
||||||
|
#include <inc/hw_uart.h>
|
||||||
|
#include <inc/hw_ints.h>
|
||||||
|
#include <driverlib/gpio.h>
|
||||||
|
#include <driverlib/sysctl.h>
|
||||||
|
#include <driverlib/interrupt.h>
|
||||||
|
|
||||||
|
#include <uart.h>
|
||||||
|
#include "board.h"
|
||||||
|
|
||||||
|
extern void rt_hw_interrupt_thread_switch(void);
|
||||||
|
|
||||||
|
#define RT_UART_RX_BUFFER_SIZE 64
|
||||||
|
|
||||||
|
/* LM3S serial device */
|
||||||
|
struct rt_lm3s_serial
|
||||||
|
{
|
||||||
|
/* inherit from device */
|
||||||
|
struct rt_device parent;
|
||||||
|
|
||||||
|
rt_uint32_t hw_base;
|
||||||
|
rt_uint32_t baudrate;
|
||||||
|
|
||||||
|
/* reception field */
|
||||||
|
rt_uint16_t save_index, read_index;
|
||||||
|
rt_uint8_t rx_buffer[RT_UART_RX_BUFFER_SIZE];
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef RT_USING_UART1
|
||||||
|
struct rt_lm3s_serial serial1;
|
||||||
|
#endif
|
||||||
|
#ifdef RT_USING_UART2
|
||||||
|
struct rt_lm3s_serial serial2;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void rt_hw_serial_init(void);
|
||||||
|
|
||||||
|
void rt_hw_uart_isr(struct rt_lm3s_serial* serial)
|
||||||
|
{
|
||||||
|
rt_device_t device;
|
||||||
|
rt_uint32_t status;
|
||||||
|
|
||||||
|
device = (struct rt_device*)serial;
|
||||||
|
UARTIntStatus(serial->hw_base, true);
|
||||||
|
|
||||||
|
/* clear interrupt status */
|
||||||
|
UARTIntClear(serial->hw_base, status);
|
||||||
|
|
||||||
|
if (device->flag & RT_DEVICE_FLAG_INT_RX)
|
||||||
|
{
|
||||||
|
char ch;
|
||||||
|
rt_base_t level;
|
||||||
|
|
||||||
|
while (UARTCharsAvail(serial->hw_base))
|
||||||
|
{
|
||||||
|
ch = UARTCharGetNonBlocking(serial->hw_base);
|
||||||
|
|
||||||
|
/* disable interrupt */
|
||||||
|
level = rt_hw_interrupt_disable();
|
||||||
|
|
||||||
|
/* read character */
|
||||||
|
serial->rx_buffer[serial->save_index] = ch;
|
||||||
|
serial->save_index ++;
|
||||||
|
if (serial->save_index >= RT_UART_RX_BUFFER_SIZE)
|
||||||
|
serial->save_index = 0;
|
||||||
|
|
||||||
|
/* if the next position is read index, discard this 'read char' */
|
||||||
|
if (serial->save_index == serial->read_index)
|
||||||
|
{
|
||||||
|
serial->read_index ++;
|
||||||
|
if (serial->read_index >= RT_UART_RX_BUFFER_SIZE)
|
||||||
|
serial->read_index = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* enable interrupt */
|
||||||
|
rt_hw_interrupt_enable(level);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* invoke callback */
|
||||||
|
if(device->rx_indicate != RT_NULL)
|
||||||
|
{
|
||||||
|
rt_int32_t length;
|
||||||
|
|
||||||
|
length = serial->save_index - serial->read_index;
|
||||||
|
if (length < 0) length += RT_UART_RX_BUFFER_SIZE;
|
||||||
|
device->rx_indicate(device, length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef RT_USING_UART1
|
||||||
|
void rt_hw_uart_isr_1(int irqno)
|
||||||
|
{
|
||||||
|
/* enter interrupt */
|
||||||
|
rt_interrupt_enter();
|
||||||
|
|
||||||
|
/* get serial device */
|
||||||
|
rt_hw_uart_isr(&serial1);
|
||||||
|
|
||||||
|
/* leave interrupt */
|
||||||
|
rt_interrupt_leave();
|
||||||
|
rt_hw_interrupt_thread_switch();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef RT_USING_UART2
|
||||||
|
void rt_hw_uart_isr_2(int irqno)
|
||||||
|
{
|
||||||
|
/* enter interrupt */
|
||||||
|
rt_interrupt_enter();
|
||||||
|
|
||||||
|
/* get serial device */
|
||||||
|
rt_hw_uart_isr(&serial2);
|
||||||
|
|
||||||
|
/* leave interrupt */
|
||||||
|
rt_interrupt_leave();
|
||||||
|
rt_hw_interrupt_thread_switch();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @addtogroup LM3S
|
||||||
|
*/
|
||||||
|
/*@{*/
|
||||||
|
|
||||||
|
static rt_err_t rt_serial_init (rt_device_t dev)
|
||||||
|
{
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static rt_err_t rt_serial_open(rt_device_t dev, rt_uint16_t oflag)
|
||||||
|
{
|
||||||
|
struct rt_lm3s_serial* serial;
|
||||||
|
serial = (struct rt_lm3s_serial*) dev;
|
||||||
|
|
||||||
|
RT_ASSERT(serial != RT_NULL);
|
||||||
|
|
||||||
|
if (dev->flag & RT_DEVICE_FLAG_INT_RX)
|
||||||
|
{
|
||||||
|
/* enable interrupt */
|
||||||
|
if (serial->hw_base == UART0_BASE)
|
||||||
|
IntEnable(INT_UART0);
|
||||||
|
else if (serial->hw_base == UART1_BASE)
|
||||||
|
IntEnable(INT_UART1);
|
||||||
|
|
||||||
|
UARTIntEnable(serial->hw_base, UART_INT_RX | UART_INT_RT);
|
||||||
|
}
|
||||||
|
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static rt_err_t rt_serial_close(rt_device_t dev)
|
||||||
|
{
|
||||||
|
struct rt_lm3s_serial* serial;
|
||||||
|
serial = (struct rt_lm3s_serial*) dev;
|
||||||
|
|
||||||
|
RT_ASSERT(serial != RT_NULL);
|
||||||
|
|
||||||
|
if (dev->flag & RT_DEVICE_FLAG_INT_RX)
|
||||||
|
{
|
||||||
|
/* disable UART rx interrupt */
|
||||||
|
UARTIntDisable(serial->hw_base, UART_INT_RX | UART_INT_RT);
|
||||||
|
}
|
||||||
|
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static rt_err_t rt_serial_control(rt_device_t dev, rt_uint8_t cmd, void *args)
|
||||||
|
{
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static rt_size_t rt_serial_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
|
||||||
|
{
|
||||||
|
rt_uint8_t* ptr;
|
||||||
|
struct rt_lm3s_serial *serial = (struct rt_lm3s_serial*)dev;
|
||||||
|
RT_ASSERT(serial != RT_NULL);
|
||||||
|
|
||||||
|
/* point to buffer */
|
||||||
|
ptr = (rt_uint8_t*) buffer;
|
||||||
|
|
||||||
|
if (dev->flag & RT_DEVICE_FLAG_INT_RX)
|
||||||
|
{
|
||||||
|
while (size)
|
||||||
|
{
|
||||||
|
/* interrupt receive */
|
||||||
|
rt_base_t level;
|
||||||
|
|
||||||
|
/* disable interrupt */
|
||||||
|
level = rt_hw_interrupt_disable();
|
||||||
|
if (serial->read_index != serial->save_index)
|
||||||
|
{
|
||||||
|
*ptr = serial->rx_buffer[serial->read_index];
|
||||||
|
|
||||||
|
serial->read_index ++;
|
||||||
|
if (serial->read_index >= RT_UART_RX_BUFFER_SIZE)
|
||||||
|
serial->read_index = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* no data in rx buffer */
|
||||||
|
|
||||||
|
/* enable interrupt */
|
||||||
|
rt_hw_interrupt_enable(level);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* enable interrupt */
|
||||||
|
rt_hw_interrupt_enable(level);
|
||||||
|
|
||||||
|
ptr ++; size --;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (rt_uint32_t)ptr - (rt_uint32_t)buffer;
|
||||||
|
}
|
||||||
|
else if (dev->flag & RT_DEVICE_FLAG_DMA_RX)
|
||||||
|
{
|
||||||
|
/* not support right now */
|
||||||
|
RT_ASSERT(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* polling mode */
|
||||||
|
while (size)
|
||||||
|
{
|
||||||
|
*ptr = UARTCharGetNonBlocking(serial->hw_base);
|
||||||
|
|
||||||
|
ptr ++; size --;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (rt_size_t)ptr - (rt_size_t)buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
static rt_size_t rt_serial_write(rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
|
||||||
|
{
|
||||||
|
struct rt_lm3s_serial* serial;
|
||||||
|
char *ptr;
|
||||||
|
|
||||||
|
serial = (struct rt_lm3s_serial*) dev;
|
||||||
|
if (dev->flag & RT_DEVICE_FLAG_INT_TX)
|
||||||
|
{
|
||||||
|
/* not support */
|
||||||
|
RT_ASSERT(0);
|
||||||
|
}
|
||||||
|
else if (dev->flag & RT_DEVICE_FLAG_DMA_TX)
|
||||||
|
{
|
||||||
|
/* not support */
|
||||||
|
RT_ASSERT(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* polling write */
|
||||||
|
ptr = (char *)buffer;
|
||||||
|
|
||||||
|
if (dev->flag & RT_DEVICE_FLAG_STREAM)
|
||||||
|
{
|
||||||
|
/* stream mode */
|
||||||
|
while (size)
|
||||||
|
{
|
||||||
|
if (*ptr == '\n')
|
||||||
|
while (UARTCharPutNonBlocking(serial->hw_base, '\r') == false);
|
||||||
|
|
||||||
|
while (UARTCharPutNonBlocking(serial->hw_base, *ptr) == false);
|
||||||
|
|
||||||
|
ptr ++;
|
||||||
|
size --;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
while (size)
|
||||||
|
{
|
||||||
|
while (UARTCharPutNonBlocking(serial->hw_base, *ptr) == false);
|
||||||
|
|
||||||
|
ptr ++;
|
||||||
|
size --;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (rt_size_t) ptr - (rt_size_t) buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
void rt_hw_serial_init(void)
|
||||||
|
{
|
||||||
|
struct rt_lm3s_serial* serial;
|
||||||
|
|
||||||
|
#ifdef RT_USING_UART1
|
||||||
|
serial = &serial1;
|
||||||
|
|
||||||
|
serial->parent.type = RT_Device_Class_Char;
|
||||||
|
|
||||||
|
serial->hw_base = UART0_BASE;
|
||||||
|
serial->baudrate = 115200;
|
||||||
|
|
||||||
|
rt_memset(serial->rx_buffer, 0, sizeof(serial->rx_buffer));
|
||||||
|
serial->read_index = serial->save_index = 0;
|
||||||
|
|
||||||
|
/* enable UART0 clock */
|
||||||
|
SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
|
||||||
|
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
|
||||||
|
|
||||||
|
/* set UART0 pinmux */
|
||||||
|
GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
|
||||||
|
|
||||||
|
/* Configure the UART for 115,200, 8-N-1 operation. */
|
||||||
|
UARTConfigSetExpClk(UART0_BASE, SysCtlClockGet(), serial->baudrate,
|
||||||
|
(UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |
|
||||||
|
UART_CONFIG_PAR_NONE));
|
||||||
|
|
||||||
|
serial->parent.init = rt_serial_init;
|
||||||
|
serial->parent.open = rt_serial_open;
|
||||||
|
serial->parent.close = rt_serial_close;
|
||||||
|
serial->parent.read = rt_serial_read;
|
||||||
|
serial->parent.write = rt_serial_write;
|
||||||
|
serial->parent.control = rt_serial_control;
|
||||||
|
serial->parent.private = RT_NULL;
|
||||||
|
|
||||||
|
rt_device_register(&serial->parent,
|
||||||
|
"uart1", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef RT_USING_UART2
|
||||||
|
serial = &serial2;
|
||||||
|
|
||||||
|
serial->parent.type = RT_Device_Class_Char;
|
||||||
|
|
||||||
|
serial->hw_base = 0xE0010000;
|
||||||
|
serial->baudrate = 115200;
|
||||||
|
|
||||||
|
rt_memset(serial->rx_buffer, 0, sizeof(serial->rx_buffer));
|
||||||
|
serial->read_index = serial->save_index = 0;
|
||||||
|
|
||||||
|
serial->parent.init = rt_serial_init;
|
||||||
|
serial->parent.open = rt_serial_open;
|
||||||
|
serial->parent.close = rt_serial_close;
|
||||||
|
serial->parent.read = rt_serial_read;
|
||||||
|
serial->parent.write = rt_serial_write;
|
||||||
|
serial->parent.control = rt_serial_control;
|
||||||
|
serial->parent.private = RT_NULL;
|
||||||
|
|
||||||
|
rt_device_register(&serial->parent,
|
||||||
|
"uart2", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/*@}*/
|
|
@ -0,0 +1,59 @@
|
||||||
|
/*
|
||||||
|
* File : stack.c
|
||||||
|
* This file is part of RT-Thread RTOS
|
||||||
|
* COPYRIGHT (C) 2006, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* The license and distribution terms for this file may be
|
||||||
|
* found in the file LICENSE in this distribution or at
|
||||||
|
* http://openlab.rt-thread.com/license/LICENSE
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2006-08-23 Bernard the first version
|
||||||
|
*/
|
||||||
|
#include <rtthread.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @addtogroup STM32
|
||||||
|
*/
|
||||||
|
/*@{*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function will initialize thread stack
|
||||||
|
*
|
||||||
|
* @param tentry the entry of thread
|
||||||
|
* @param parameter the parameter of entry
|
||||||
|
* @param stack_addr the beginning stack address
|
||||||
|
* @param texit the function will be called when thread exit
|
||||||
|
*
|
||||||
|
* @return stack address
|
||||||
|
*/
|
||||||
|
rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter,
|
||||||
|
rt_uint8_t *stack_addr, void *texit)
|
||||||
|
{
|
||||||
|
unsigned long *stk;
|
||||||
|
|
||||||
|
stk = (unsigned long *)stack_addr;
|
||||||
|
*(stk) = 0x01000000L; /* PSR */
|
||||||
|
*(--stk) = (unsigned long)tentry; /* entry point, pc */
|
||||||
|
*(--stk) = (unsigned long)texit; /* lr */
|
||||||
|
*(--stk) = 0; /* r12 */
|
||||||
|
*(--stk) = 0; /* r3 */
|
||||||
|
*(--stk) = 0; /* r2 */
|
||||||
|
*(--stk) = 0; /* r1 */
|
||||||
|
*(--stk) = (unsigned long)parameter; /* r0 : argument */
|
||||||
|
|
||||||
|
*(--stk) = 0; /* r11 */
|
||||||
|
*(--stk) = 0; /* r10 */
|
||||||
|
*(--stk) = 0; /* r9 */
|
||||||
|
*(--stk) = 0; /* r8 */
|
||||||
|
*(--stk) = 0; /* r7 */
|
||||||
|
*(--stk) = 0; /* r6 */
|
||||||
|
*(--stk) = 0; /* r5 */
|
||||||
|
*(--stk) = 0; /* r4 */
|
||||||
|
|
||||||
|
/* return task's current stack address */
|
||||||
|
return (rt_uint8_t *)stk;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*@}*/
|
|
@ -0,0 +1,251 @@
|
||||||
|
; <<< Use Configuration Wizard in Context Menu >>>
|
||||||
|
;******************************************************************************
|
||||||
|
;
|
||||||
|
; Startup.s - Startup code for Stellaris.
|
||||||
|
;
|
||||||
|
; Copyright (c) 2006-2008 Luminary Micro, Inc. All rights reserved.
|
||||||
|
;
|
||||||
|
; Software License Agreement
|
||||||
|
;
|
||||||
|
; Luminary Micro, Inc. (LMI) is supplying this software for use solely and
|
||||||
|
; exclusively on LMI's microcontroller products.
|
||||||
|
;
|
||||||
|
; The software is owned by LMI and/or its suppliers, and is protected under
|
||||||
|
; applicable copyright laws. All rights are reserved. You may not combine
|
||||||
|
; this software with "viral" open-source software in order to form a larger
|
||||||
|
; program. Any use in violation of the foregoing restrictions may subject
|
||||||
|
; the user to criminal sanctions under applicable laws, as well as to civil
|
||||||
|
; liability for the breach of the terms and conditions of this license.
|
||||||
|
;
|
||||||
|
; THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
|
||||||
|
; OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
|
||||||
|
; MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
|
||||||
|
; LMI SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
|
||||||
|
; CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
|
||||||
|
;
|
||||||
|
; This is part of revision 2523 of the Stellaris Peripheral Driver Library.
|
||||||
|
;
|
||||||
|
;******************************************************************************
|
||||||
|
|
||||||
|
;******************************************************************************
|
||||||
|
;
|
||||||
|
; <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
|
||||||
|
;
|
||||||
|
;******************************************************************************
|
||||||
|
Stack EQU 0x00000100
|
||||||
|
|
||||||
|
;******************************************************************************
|
||||||
|
;
|
||||||
|
; <o> Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
|
||||||
|
;
|
||||||
|
;******************************************************************************
|
||||||
|
Heap EQU 0x00000000
|
||||||
|
|
||||||
|
;******************************************************************************
|
||||||
|
;
|
||||||
|
; Allocate space for the stack.
|
||||||
|
;
|
||||||
|
;******************************************************************************
|
||||||
|
AREA STACK, NOINIT, READWRITE, ALIGN=3
|
||||||
|
StackMem
|
||||||
|
SPACE Stack
|
||||||
|
__initial_sp
|
||||||
|
|
||||||
|
;******************************************************************************
|
||||||
|
;
|
||||||
|
; Allocate space for the heap.
|
||||||
|
;
|
||||||
|
;******************************************************************************
|
||||||
|
AREA HEAP, NOINIT, READWRITE, ALIGN=3
|
||||||
|
__heap_base
|
||||||
|
HeapMem
|
||||||
|
SPACE Heap
|
||||||
|
__heap_limit
|
||||||
|
|
||||||
|
IMPORT rt_hw_pend_sv
|
||||||
|
IMPORT rt_hw_timer_handler
|
||||||
|
IMPORT rt_hw_uart_isr_1
|
||||||
|
|
||||||
|
;******************************************************************************
|
||||||
|
;
|
||||||
|
; Indicate that the code in this file preserves 8-byte alignment of the stack.
|
||||||
|
;
|
||||||
|
;******************************************************************************
|
||||||
|
PRESERVE8
|
||||||
|
|
||||||
|
;******************************************************************************
|
||||||
|
;
|
||||||
|
; Place code into the reset code section.
|
||||||
|
;
|
||||||
|
;******************************************************************************
|
||||||
|
AREA RESET, CODE, READONLY
|
||||||
|
THUMB
|
||||||
|
|
||||||
|
;******************************************************************************
|
||||||
|
;
|
||||||
|
; The vector table.
|
||||||
|
;
|
||||||
|
;******************************************************************************
|
||||||
|
EXPORT __Vectors
|
||||||
|
__Vectors
|
||||||
|
DCD StackMem + Stack ; Top of Stack
|
||||||
|
DCD Reset_Handler ; Reset Handler
|
||||||
|
DCD NmiSR ; NMI Handler
|
||||||
|
DCD FaultISR ; Hard Fault Handler
|
||||||
|
DCD IntDefaultHandler ; MPU Fault Handler
|
||||||
|
DCD IntDefaultHandler ; Bus Fault Handler
|
||||||
|
DCD IntDefaultHandler ; Usage Fault Handler
|
||||||
|
DCD 0 ; Reserved
|
||||||
|
DCD 0 ; Reserved
|
||||||
|
DCD 0 ; Reserved
|
||||||
|
DCD 0 ; Reserved
|
||||||
|
DCD IntDefaultHandler ; SVCall Handler
|
||||||
|
DCD IntDefaultHandler ; Debug Monitor Handler
|
||||||
|
DCD 0 ; Reserved
|
||||||
|
DCD rt_hw_pend_sv ; PendSV Handler
|
||||||
|
DCD rt_hw_timer_handler ; SysTick Handler
|
||||||
|
DCD IntDefaultHandler ; GPIO Port A
|
||||||
|
DCD IntDefaultHandler ; GPIO Port B
|
||||||
|
DCD IntDefaultHandler ; GPIO Port C
|
||||||
|
DCD IntDefaultHandler ; GPIO Port D
|
||||||
|
DCD IntDefaultHandler ; GPIO Port E
|
||||||
|
DCD rt_hw_uart_isr_1 ; UART0
|
||||||
|
DCD IntDefaultHandler ; UART1
|
||||||
|
DCD IntDefaultHandler ; SSI
|
||||||
|
DCD IntDefaultHandler ; I2C
|
||||||
|
DCD IntDefaultHandler ; PWM Fault
|
||||||
|
DCD IntDefaultHandler ; PWM Generator 0
|
||||||
|
DCD IntDefaultHandler ; PWM Generator 1
|
||||||
|
DCD IntDefaultHandler ; PWM Generator 2
|
||||||
|
DCD IntDefaultHandler ; Quadrature Encoder
|
||||||
|
DCD IntDefaultHandler ; ADC Sequence 0
|
||||||
|
DCD IntDefaultHandler ; ADC Sequence 1
|
||||||
|
DCD IntDefaultHandler ; ADC Sequence 2
|
||||||
|
DCD IntDefaultHandler ; ADC Sequence 3
|
||||||
|
DCD IntDefaultHandler ; Watchdog
|
||||||
|
DCD IntDefaultHandler ; Timer 0A
|
||||||
|
DCD IntDefaultHandler ; Timer 0B
|
||||||
|
DCD IntDefaultHandler ; Timer 1A
|
||||||
|
DCD IntDefaultHandler ; Timer 1B
|
||||||
|
DCD IntDefaultHandler ; Timer 2A
|
||||||
|
DCD IntDefaultHandler ; Timer 2B
|
||||||
|
DCD IntDefaultHandler ; Comp 0
|
||||||
|
DCD IntDefaultHandler ; Comp 1
|
||||||
|
DCD IntDefaultHandler ; Comp 2
|
||||||
|
DCD IntDefaultHandler ; System Control
|
||||||
|
DCD IntDefaultHandler ; Flash Control
|
||||||
|
DCD IntDefaultHandler ; GPIO Port F
|
||||||
|
DCD IntDefaultHandler ; GPIO Port G
|
||||||
|
DCD IntDefaultHandler ; GPIO Port H
|
||||||
|
DCD IntDefaultHandler ; UART2 Rx and Tx
|
||||||
|
DCD IntDefaultHandler ; SSI1 Rx and Tx
|
||||||
|
DCD IntDefaultHandler ; Timer 3 subtimer A
|
||||||
|
DCD IntDefaultHandler ; Timer 3 subtimer B
|
||||||
|
DCD IntDefaultHandler ; I2C1 Master and Slave
|
||||||
|
DCD IntDefaultHandler ; Quadrature Encoder 1
|
||||||
|
DCD IntDefaultHandler ; CAN0
|
||||||
|
DCD IntDefaultHandler ; CAN1
|
||||||
|
DCD IntDefaultHandler ; CAN2
|
||||||
|
DCD IntDefaultHandler ; Ethernet
|
||||||
|
DCD IntDefaultHandler ; Hibernate
|
||||||
|
DCD IntDefaultHandler ; USB0
|
||||||
|
DCD IntDefaultHandler ; PWM Generator 3
|
||||||
|
DCD IntDefaultHandler ; uDMA Software Transfer
|
||||||
|
DCD IntDefaultHandler ; uDMA Error
|
||||||
|
|
||||||
|
;******************************************************************************
|
||||||
|
;
|
||||||
|
; This is the code that gets called when the processor first starts execution
|
||||||
|
; following a reset event.
|
||||||
|
;
|
||||||
|
;******************************************************************************
|
||||||
|
EXPORT Reset_Handler
|
||||||
|
Reset_Handler
|
||||||
|
;
|
||||||
|
; Call the C library enty point that handles startup. This will copy
|
||||||
|
; the .data section initializers from flash to SRAM and zero fill the
|
||||||
|
; .bss section.
|
||||||
|
;
|
||||||
|
IMPORT __main
|
||||||
|
B __main
|
||||||
|
|
||||||
|
;******************************************************************************
|
||||||
|
;
|
||||||
|
; This is the code that gets called when the processor receives a NMI. This
|
||||||
|
; simply enters an infinite loop, preserving the system state for examination
|
||||||
|
; by a debugger.
|
||||||
|
;
|
||||||
|
;******************************************************************************
|
||||||
|
NmiSR
|
||||||
|
B NmiSR
|
||||||
|
|
||||||
|
;******************************************************************************
|
||||||
|
;
|
||||||
|
; This is the code that gets called when the processor receives a fault
|
||||||
|
; interrupt. This simply enters an infinite loop, preserving the system state
|
||||||
|
; for examination by a debugger.
|
||||||
|
;
|
||||||
|
;******************************************************************************
|
||||||
|
FaultISR
|
||||||
|
B FaultISR
|
||||||
|
|
||||||
|
;******************************************************************************
|
||||||
|
;
|
||||||
|
; This is the code that gets called when the processor receives an unexpected
|
||||||
|
; interrupt. This simply enters an infinite loop, preserving the system state
|
||||||
|
; for examination by a debugger.
|
||||||
|
;
|
||||||
|
;******************************************************************************
|
||||||
|
IntDefaultHandler
|
||||||
|
B IntDefaultHandler
|
||||||
|
|
||||||
|
;******************************************************************************
|
||||||
|
;
|
||||||
|
; Make sure the end of this section is aligned.
|
||||||
|
;
|
||||||
|
;******************************************************************************
|
||||||
|
ALIGN
|
||||||
|
|
||||||
|
;******************************************************************************
|
||||||
|
;
|
||||||
|
; Some code in the normal code section for initializing the heap and stack.
|
||||||
|
;
|
||||||
|
;******************************************************************************
|
||||||
|
AREA |.text|, CODE, READONLY
|
||||||
|
|
||||||
|
;******************************************************************************
|
||||||
|
;
|
||||||
|
; The function expected of the C library startup code for defining the stack
|
||||||
|
; and heap memory locations. For the C library version of the startup code,
|
||||||
|
; provide this function so that the C library initialization code can find out
|
||||||
|
; the location of the stack and heap.
|
||||||
|
;
|
||||||
|
;******************************************************************************
|
||||||
|
IF :DEF: __MICROLIB
|
||||||
|
EXPORT __initial_sp
|
||||||
|
EXPORT __heap_base
|
||||||
|
EXPORT __heap_limit
|
||||||
|
ELSE
|
||||||
|
IMPORT __use_two_region_memory
|
||||||
|
EXPORT __user_initial_stackheap
|
||||||
|
__user_initial_stackheap
|
||||||
|
LDR R0, =HeapMem
|
||||||
|
LDR R1, =(StackMem + Stack)
|
||||||
|
LDR R2, =(HeapMem + Heap)
|
||||||
|
LDR R3, =StackMem
|
||||||
|
BX LR
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
;******************************************************************************
|
||||||
|
;
|
||||||
|
; Make sure the end of this section is aligned.
|
||||||
|
;
|
||||||
|
;******************************************************************************
|
||||||
|
ALIGN
|
||||||
|
|
||||||
|
;******************************************************************************
|
||||||
|
;
|
||||||
|
; Tell the assembler that we're done.
|
||||||
|
;
|
||||||
|
;******************************************************************************
|
||||||
|
END
|
|
@ -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
|
|
@ -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 – 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 – 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 – 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
|
|
@ -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
|
|
@ -0,0 +1,42 @@
|
||||||
|
/*
|
||||||
|
* File : cpu.c
|
||||||
|
* This file is part of RT-Thread RTOS
|
||||||
|
* COPYRIGHT (C) 2006, RT-Thread Develop Team
|
||||||
|
*
|
||||||
|
* The license and distribution terms for this file may be
|
||||||
|
* found in the file LICENSE in this distribution or at
|
||||||
|
* http://www.rt-thread.org/license/LICENSE
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2006-08-23 Bernard first version
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <rtthread.h>
|
||||||
|
#include "lpc214x.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @addtogroup LPC214x
|
||||||
|
*/
|
||||||
|
/*@{*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* this function will reset CPU
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void rt_hw_cpu_reset()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* this function will shutdown CPU
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void rt_hw_cpu_shutdown()
|
||||||
|
{
|
||||||
|
rt_kprintf("shutdown...\n");
|
||||||
|
|
||||||
|
while (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*@}*/
|
|
@ -0,0 +1,105 @@
|
||||||
|
/*
|
||||||
|
* File : trap.c
|
||||||
|
* This file is part of RT-Thread RTOS
|
||||||
|
* COPYRIGHT (C) 2006, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* The license and distribution terms for this file may be
|
||||||
|
* found in the file LICENSE in this distribution or at
|
||||||
|
* http://openlab.rt-thread.com/license/LICENSE
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2006-08-23 Bernard first version
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <rtthread.h>
|
||||||
|
#include "lpc214x.h"
|
||||||
|
|
||||||
|
#define MAX_HANDLERS 32
|
||||||
|
|
||||||
|
extern rt_uint32_t rt_interrupt_nest;
|
||||||
|
|
||||||
|
rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread;
|
||||||
|
rt_uint32_t rt_thread_switch_interrput_flag;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @addtogroup LPC214x
|
||||||
|
*/
|
||||||
|
/*@{*/
|
||||||
|
|
||||||
|
void rt_hw_interrupt_handler(int vector)
|
||||||
|
{
|
||||||
|
rt_kprintf("Unhandled interrupt %d occured!!!\n", vector);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function will initialize hardware interrupt
|
||||||
|
*/
|
||||||
|
void rt_hw_interrupt_init()
|
||||||
|
{
|
||||||
|
rt_base_t index;
|
||||||
|
rt_uint32_t *vect_addr, *vect_ctl;
|
||||||
|
|
||||||
|
/* initialize VIC*/
|
||||||
|
VICIntEnClr = 0xffffffff;
|
||||||
|
VICVectAddr = 0;
|
||||||
|
/* set all to IRQ */
|
||||||
|
VICIntSelect = 0;
|
||||||
|
|
||||||
|
for (index = 0; index < MAX_HANDLERS; index ++)
|
||||||
|
{
|
||||||
|
vect_addr = (rt_uint32_t *)(VIC_BASE_ADDR + 0x100 + (index << 2));
|
||||||
|
vect_ctl = (rt_uint32_t *)(VIC_BASE_ADDR + 0x200 + (index << 2));
|
||||||
|
|
||||||
|
*vect_addr = (rt_uint32_t)rt_hw_interrupt_handler;
|
||||||
|
*vect_ctl = 0xF;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* init interrupt nest, and context in thread sp */
|
||||||
|
rt_interrupt_nest = 0;
|
||||||
|
rt_interrupt_from_thread = 0;
|
||||||
|
rt_interrupt_to_thread = 0;
|
||||||
|
rt_thread_switch_interrput_flag = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function will mask a interrupt.
|
||||||
|
* @param vector the interrupt number
|
||||||
|
*/
|
||||||
|
void rt_hw_interrupt_mask(int vector)
|
||||||
|
{
|
||||||
|
VICIntEnClr = (1 << vector);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function will un-mask a interrupt.
|
||||||
|
* @param vector the interrupt number
|
||||||
|
*/
|
||||||
|
void rt_hw_interrupt_umask(int vector)
|
||||||
|
{
|
||||||
|
VICIntEnable = (1 << vector);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function will install a interrupt service routine to a interrupt.
|
||||||
|
* @param vector the interrupt number
|
||||||
|
* @param new_handler the interrupt service routine to be installed
|
||||||
|
* @param old_handler the old interrupt service routine
|
||||||
|
*/
|
||||||
|
void rt_hw_interrupt_install(int vector, rt_isr_handler_t new_handler, rt_isr_handler_t *old_handler)
|
||||||
|
{
|
||||||
|
if(vector >= 0 && vector < MAX_HANDLERS)
|
||||||
|
{
|
||||||
|
/* get VIC address */
|
||||||
|
rt_uint32_t* vect_addr = (rt_uint32_t *)(VIC_BASE_ADDR + 0x100 + (vector << 2));
|
||||||
|
rt_uint32_t* vect_ctl = (rt_uint32_t *)(VIC_BASE_ADDR + 0x200 + (vector << 2));
|
||||||
|
|
||||||
|
/* assign IRQ slot and enable this slot */
|
||||||
|
*vect_ctl = 0x20 | (vector & 0x1F);
|
||||||
|
|
||||||
|
if (old_handler != RT_NULL) *old_handler = (rt_isr_handler_t) *vect_addr;
|
||||||
|
if (new_handler != RT_NULL) *vect_addr = (rt_uint32_t) new_handler;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*@}*/
|
|
@ -0,0 +1,387 @@
|
||||||
|
/*
|
||||||
|
* File : serial.c
|
||||||
|
* This file is part of RT-Thread RTOS
|
||||||
|
* COPYRIGHT (C) 2006, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* The license and distribution terms for this file may be
|
||||||
|
* found in the file LICENSE in this distribution or at
|
||||||
|
* http://openlab.rt-thread.com/license/LICENSE
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2006-08-23 Bernard first version
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <rthw.h>
|
||||||
|
#include <rtthread.h>
|
||||||
|
|
||||||
|
#include "lpc214x.h"
|
||||||
|
#include "board.h"
|
||||||
|
|
||||||
|
/* serial hardware register */
|
||||||
|
#define REG8(d) (*((volatile unsigned char *)(d)))
|
||||||
|
#define REG32(d) (*((volatile unsigned long *)(d)))
|
||||||
|
|
||||||
|
#define UART_RBR(base) REG8(base + 0x00)
|
||||||
|
#define UART_THR(base) REG8(base + 0x00)
|
||||||
|
#define UART_IER(base) REG32(base + 0x04)
|
||||||
|
#define UART_IIR(base) REG32(base + 0x08)
|
||||||
|
#define UART_FCR(base) REG8(base + 0x08)
|
||||||
|
#define UART_LCR(base) REG8(base + 0x0C)
|
||||||
|
#define UART_MCR(base) REG8(base + 0x10)
|
||||||
|
#define UART_LSR(base) REG8(base + 0x14)
|
||||||
|
#define UART_MSR(base) REG8(base + 0x18)
|
||||||
|
#define UART_SCR(base) REG8(base + 0x1C)
|
||||||
|
#define UART_DLL(base) REG8(base + 0x00)
|
||||||
|
#define UART_DLM(base) REG8(base + 0x04)
|
||||||
|
#define UART_ACR(base) REG32(base + 0x20)
|
||||||
|
#define UART_FDR(base) REG32(base + 0x28)
|
||||||
|
#define UART_TER(base) REG8(base + 0x30)
|
||||||
|
|
||||||
|
/* LPC serial device */
|
||||||
|
struct rt_lpcserial
|
||||||
|
{
|
||||||
|
/* inherit from device */
|
||||||
|
struct rt_device parent;
|
||||||
|
|
||||||
|
rt_uint32_t hw_base;
|
||||||
|
rt_uint32_t irqno;
|
||||||
|
rt_uint32_t baudrate;
|
||||||
|
|
||||||
|
/* reception field */
|
||||||
|
rt_uint16_t save_index, read_index;
|
||||||
|
rt_uint8_t rx_buffer[RT_UART_RX_BUFFER_SIZE];
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef RT_USING_UART1
|
||||||
|
struct rt_lpcserial serial1;
|
||||||
|
#endif
|
||||||
|
#ifdef RT_USING_UART2
|
||||||
|
struct rt_lpcserial serial2;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void rt_hw_serial_init(void);
|
||||||
|
|
||||||
|
#define U0PINS 0x00000005
|
||||||
|
|
||||||
|
void rt_hw_uart_isr(struct rt_lpcserial* lpc_serial)
|
||||||
|
{
|
||||||
|
UNUSED rt_uint32_t iir;
|
||||||
|
|
||||||
|
RT_ASSERT(lpc_serial != RT_NULL)
|
||||||
|
|
||||||
|
if (UART_LSR(lpc_serial->hw_base) & 0x01)
|
||||||
|
{
|
||||||
|
rt_base_t level;
|
||||||
|
|
||||||
|
while (UART_LSR(lpc_serial->hw_base) & 0x01)
|
||||||
|
{
|
||||||
|
/* disable interrupt */
|
||||||
|
level = rt_hw_interrupt_disable();
|
||||||
|
|
||||||
|
/* read character */
|
||||||
|
lpc_serial->rx_buffer[lpc_serial->save_index] =
|
||||||
|
UART_RBR(lpc_serial->hw_base);
|
||||||
|
lpc_serial->save_index ++;
|
||||||
|
if (lpc_serial->save_index >= RT_UART_RX_BUFFER_SIZE)
|
||||||
|
lpc_serial->save_index = 0;
|
||||||
|
|
||||||
|
/* if the next position is read index, discard this 'read char' */
|
||||||
|
if (lpc_serial->save_index == lpc_serial->read_index)
|
||||||
|
{
|
||||||
|
lpc_serial->read_index ++;
|
||||||
|
if (lpc_serial->read_index >= RT_UART_RX_BUFFER_SIZE)
|
||||||
|
lpc_serial->read_index = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* enable interrupt */
|
||||||
|
rt_hw_interrupt_enable(level);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* invoke callback */
|
||||||
|
if(lpc_serial->parent.rx_indicate != RT_NULL)
|
||||||
|
{
|
||||||
|
lpc_serial->parent.rx_indicate(&lpc_serial->parent, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* clear interrupt source */
|
||||||
|
iir = UART_IIR(lpc_serial->hw_base);
|
||||||
|
|
||||||
|
/* acknowledge Interrupt */
|
||||||
|
VICVectAddr = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef RT_USING_UART1
|
||||||
|
void rt_hw_uart_isr_1(int irqno)
|
||||||
|
{
|
||||||
|
/* get lpc serial device */
|
||||||
|
rt_hw_uart_isr(&serial1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef RT_USING_UART2
|
||||||
|
void rt_hw_uart_isr_2(int irqno)
|
||||||
|
{
|
||||||
|
/* get lpc serial device */
|
||||||
|
rt_hw_uart_isr(&serial2);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @addtogroup LPC214x
|
||||||
|
*/
|
||||||
|
/*@{*/
|
||||||
|
|
||||||
|
static rt_err_t rt_serial_init (rt_device_t dev)
|
||||||
|
{
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static rt_err_t rt_serial_open(rt_device_t dev, rt_uint16_t oflag)
|
||||||
|
{
|
||||||
|
struct rt_lpcserial* lpc_serial;
|
||||||
|
lpc_serial = (struct rt_lpcserial*) dev;
|
||||||
|
|
||||||
|
RT_ASSERT(lpc_serial != RT_NULL);
|
||||||
|
if (dev->flag & RT_DEVICE_FLAG_INT_RX)
|
||||||
|
{
|
||||||
|
/* init UART rx interrupt */
|
||||||
|
UART_IER(lpc_serial->hw_base) = 0x01;
|
||||||
|
|
||||||
|
/* install ISR */
|
||||||
|
if (lpc_serial->irqno == UART0_INT)
|
||||||
|
{
|
||||||
|
#ifdef RT_USING_UART1
|
||||||
|
rt_hw_interrupt_install(lpc_serial->irqno, rt_hw_uart_isr_1, RT_NULL);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#ifdef RT_USING_UART2
|
||||||
|
rt_hw_interrupt_install(lpc_serial->irqno, rt_hw_uart_isr_2, RT_NULL);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
rt_hw_interrupt_umask(lpc_serial->irqno);
|
||||||
|
}
|
||||||
|
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static rt_err_t rt_serial_close(rt_device_t dev)
|
||||||
|
{
|
||||||
|
struct rt_lpcserial* lpc_serial;
|
||||||
|
lpc_serial = (struct rt_lpcserial*) dev;
|
||||||
|
|
||||||
|
RT_ASSERT(lpc_serial != RT_NULL);
|
||||||
|
|
||||||
|
if (dev->flag & RT_DEVICE_FLAG_INT_RX)
|
||||||
|
{
|
||||||
|
/* disable UART rx interrupt */
|
||||||
|
UART_IER(lpc_serial->hw_base) = 0x00;
|
||||||
|
}
|
||||||
|
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static rt_err_t rt_serial_control(rt_device_t dev, rt_uint8_t cmd, void *args)
|
||||||
|
{
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static rt_size_t rt_serial_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
|
||||||
|
{
|
||||||
|
rt_uint8_t* ptr;
|
||||||
|
struct rt_lpcserial *lpc_serial = (struct rt_lpcserial*)dev;
|
||||||
|
RT_ASSERT(lpc_serial != RT_NULL);
|
||||||
|
|
||||||
|
/* point to buffer */
|
||||||
|
ptr = (rt_uint8_t*) buffer;
|
||||||
|
|
||||||
|
if (dev->flag & RT_DEVICE_FLAG_INT_RX)
|
||||||
|
{
|
||||||
|
while (size)
|
||||||
|
{
|
||||||
|
/* interrupt receive */
|
||||||
|
rt_base_t level;
|
||||||
|
|
||||||
|
/* disable interrupt */
|
||||||
|
level = rt_hw_interrupt_disable();
|
||||||
|
if (lpc_serial->read_index != lpc_serial->save_index)
|
||||||
|
{
|
||||||
|
*ptr = lpc_serial->rx_buffer[lpc_serial->read_index];
|
||||||
|
|
||||||
|
lpc_serial->read_index ++;
|
||||||
|
if (lpc_serial->read_index >= RT_UART_RX_BUFFER_SIZE)
|
||||||
|
lpc_serial->read_index = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* no data in rx buffer */
|
||||||
|
|
||||||
|
/* enable interrupt */
|
||||||
|
rt_hw_interrupt_enable(level);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* enable interrupt */
|
||||||
|
rt_hw_interrupt_enable(level);
|
||||||
|
|
||||||
|
ptr ++; size --;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (rt_uint32_t)ptr - (rt_uint32_t)buffer;
|
||||||
|
}
|
||||||
|
else if (dev->flag & RT_DEVICE_FLAG_DMA_RX)
|
||||||
|
{
|
||||||
|
/* not support right now */
|
||||||
|
RT_ASSERT(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* polling mode */
|
||||||
|
while (size && (UART_LSR(lpc_serial->hw_base) & 0x01))
|
||||||
|
{
|
||||||
|
/* Read Character */
|
||||||
|
*ptr = UART_RBR(lpc_serial->hw_base);
|
||||||
|
|
||||||
|
ptr ++;
|
||||||
|
size --;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (rt_size_t)ptr - (rt_size_t)buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
static rt_size_t rt_serial_write(rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
|
||||||
|
{
|
||||||
|
struct rt_lpcserial* lpc_serial;
|
||||||
|
char *ptr;
|
||||||
|
|
||||||
|
lpc_serial = (struct rt_lpcserial*) dev;
|
||||||
|
if (dev->flag & RT_DEVICE_FLAG_INT_TX)
|
||||||
|
{
|
||||||
|
/* not support */
|
||||||
|
RT_ASSERT(0);
|
||||||
|
}
|
||||||
|
else if (dev->flag & RT_DEVICE_FLAG_DMA_TX)
|
||||||
|
{
|
||||||
|
/* not support */
|
||||||
|
RT_ASSERT(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* polling write */
|
||||||
|
ptr = (char *)buffer;
|
||||||
|
|
||||||
|
if (dev->flag & RT_DEVICE_FLAG_STREAM)
|
||||||
|
{
|
||||||
|
/* stream mode */
|
||||||
|
while (size)
|
||||||
|
{
|
||||||
|
if (*ptr == '\n')
|
||||||
|
{
|
||||||
|
while (!(UART_LSR(lpc_serial->hw_base) & 0x20));
|
||||||
|
UART_THR(lpc_serial->hw_base) = '\r';
|
||||||
|
}
|
||||||
|
|
||||||
|
while (!(UART_LSR(lpc_serial->hw_base) & 0x20));
|
||||||
|
UART_THR(lpc_serial->hw_base) = *ptr;
|
||||||
|
|
||||||
|
ptr ++;
|
||||||
|
size --;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
while (size)
|
||||||
|
{
|
||||||
|
while (!(UART_LSR(lpc_serial->hw_base) & 0x20));
|
||||||
|
UART_THR(lpc_serial->hw_base) = *ptr;
|
||||||
|
|
||||||
|
ptr ++;
|
||||||
|
size --;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (rt_size_t) ptr - (rt_size_t) buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
void rt_hw_serial_init(void)
|
||||||
|
{
|
||||||
|
struct rt_lpcserial* lpc_serial;
|
||||||
|
|
||||||
|
#ifdef RT_USING_UART1
|
||||||
|
lpc_serial = &serial1;
|
||||||
|
|
||||||
|
lpc_serial->parent.type = RT_Device_Class_Char;
|
||||||
|
|
||||||
|
lpc_serial->hw_base = 0xE000C000;
|
||||||
|
lpc_serial->baudrate = 115200;
|
||||||
|
lpc_serial->irqno = UART0_INT;
|
||||||
|
|
||||||
|
rt_memset(lpc_serial->rx_buffer, 0, sizeof(lpc_serial->rx_buffer));
|
||||||
|
lpc_serial->read_index = lpc_serial->save_index = 0;
|
||||||
|
|
||||||
|
/* Enable UART0 RxD and TxD pins */
|
||||||
|
PINSEL0 |= 0x05;
|
||||||
|
|
||||||
|
/* 8 bits, no Parity, 1 Stop bit */
|
||||||
|
UART_LCR(lpc_serial->hw_base) = 0x83;
|
||||||
|
|
||||||
|
/* Setup Baudrate */
|
||||||
|
UART_DLL(lpc_serial->hw_base) = (PCLK/16/lpc_serial->baudrate) & 0xFF;
|
||||||
|
UART_DLM(lpc_serial->hw_base) = ((PCLK/16/lpc_serial->baudrate) >> 8) & 0xFF;
|
||||||
|
|
||||||
|
/* DLAB = 0 */
|
||||||
|
UART_LCR(lpc_serial->hw_base) = 0x03;
|
||||||
|
|
||||||
|
lpc_serial->parent.init = rt_serial_init;
|
||||||
|
lpc_serial->parent.open = rt_serial_open;
|
||||||
|
lpc_serial->parent.close = rt_serial_close;
|
||||||
|
lpc_serial->parent.read = rt_serial_read;
|
||||||
|
lpc_serial->parent.write = rt_serial_write;
|
||||||
|
lpc_serial->parent.control = rt_serial_control;
|
||||||
|
lpc_serial->parent.private = RT_NULL;
|
||||||
|
|
||||||
|
rt_device_register(&lpc_serial->parent,
|
||||||
|
"uart1", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef RT_USING_UART2
|
||||||
|
lpc_serial = &serial2;
|
||||||
|
|
||||||
|
lpc_serial->parent.type = RT_Device_Class_Char;
|
||||||
|
|
||||||
|
lpc_serial->hw_base = 0xE0010000;
|
||||||
|
lpc_serial->baudrate = 115200;
|
||||||
|
lpc_serial->irqno = UART1_INT;
|
||||||
|
|
||||||
|
rt_memset(lpc_serial->rx_buffer, 0, sizeof(lpc_serial->rx_buffer));
|
||||||
|
lpc_serial->read_index = lpc_serial->save_index = 0;
|
||||||
|
|
||||||
|
/* Enable UART1 RxD and TxD pins */
|
||||||
|
PINSEL0 |= 0x05 << 16;
|
||||||
|
|
||||||
|
/* 8 bits, no Parity, 1 Stop bit */
|
||||||
|
UART_LCR(lpc_serial->hw_base) = 0x83;
|
||||||
|
|
||||||
|
/* Setup Baudrate */
|
||||||
|
UART_DLL(lpc_serial->hw_base) = (PCLK/16/lpc_serial->baudrate) & 0xFF;
|
||||||
|
UART_DLM(lpc_serial->hw_base) = ((PCLK/16/lpc_serial->baudrate) >> 8) & 0xFF;
|
||||||
|
|
||||||
|
/* DLAB = 0 */
|
||||||
|
UART_LCR(lpc_serial->hw_base) = 0x03;
|
||||||
|
|
||||||
|
lpc_serial->parent.init = rt_serial_init;
|
||||||
|
lpc_serial->parent.open = rt_serial_open;
|
||||||
|
lpc_serial->parent.close = rt_serial_close;
|
||||||
|
lpc_serial->parent.read = rt_serial_read;
|
||||||
|
lpc_serial->parent.write = rt_serial_write;
|
||||||
|
lpc_serial->parent.control = rt_serial_control;
|
||||||
|
lpc_serial->parent.private = RT_NULL;
|
||||||
|
|
||||||
|
rt_device_register(&lpc_serial->parent,
|
||||||
|
"uart2", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/*@}*/
|
|
@ -0,0 +1,61 @@
|
||||||
|
/*
|
||||||
|
* File : stack.c
|
||||||
|
* This file is part of RT-Thread RTOS
|
||||||
|
* COPYRIGHT (C) 2006, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* The license and distribution terms for this file may be
|
||||||
|
* found in the file LICENSE in this distribution or at
|
||||||
|
* http://openlab.rt-thread.com/license/LICENSE
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2006-08-23 Bernard the first version
|
||||||
|
*/
|
||||||
|
#include <rtthread.h>
|
||||||
|
|
||||||
|
#define SVCMODE 0x13
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @addtogroup LPC214x
|
||||||
|
*/
|
||||||
|
/*@{*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function will initialize thread stack
|
||||||
|
*
|
||||||
|
* @param tentry the entry of thread
|
||||||
|
* @param parameter the parameter of entry
|
||||||
|
* @param stack_addr the beginning stack address
|
||||||
|
* @param texit the function will be called when thread exit
|
||||||
|
*
|
||||||
|
* @return stack address
|
||||||
|
*/
|
||||||
|
rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter,
|
||||||
|
rt_uint8_t *stack_addr, void *texit)
|
||||||
|
{
|
||||||
|
unsigned long *stk;
|
||||||
|
|
||||||
|
stk = (unsigned long *)stack_addr;
|
||||||
|
*(stk) = (unsigned long)tentry; /* entry point */
|
||||||
|
*(--stk) = (unsigned long)texit; /* lr */
|
||||||
|
*(--stk) = 0; /* r12 */
|
||||||
|
*(--stk) = 0; /* r11 */
|
||||||
|
*(--stk) = 0; /* r10 */
|
||||||
|
*(--stk) = 0; /* r9 */
|
||||||
|
*(--stk) = 0; /* r8 */
|
||||||
|
*(--stk) = 0; /* r7 */
|
||||||
|
*(--stk) = 0; /* r6 */
|
||||||
|
*(--stk) = 0; /* r5 */
|
||||||
|
*(--stk) = 0; /* r4 */
|
||||||
|
*(--stk) = 0; /* r3 */
|
||||||
|
*(--stk) = 0; /* r2 */
|
||||||
|
*(--stk) = 0; /* r1 */
|
||||||
|
*(--stk) = (unsigned long)parameter; /* r0 : argument */
|
||||||
|
*(--stk) = SVCMODE; /* cpsr */
|
||||||
|
*(--stk) = SVCMODE; /* spsr */
|
||||||
|
|
||||||
|
/* return task's current stack address */
|
||||||
|
return (rt_uint8_t *)stk;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*@}*/
|
|
@ -0,0 +1,508 @@
|
||||||
|
;/*****************************************************************************/
|
||||||
|
;/* STARTUP.S: Startup file for Philips LPC2000 */
|
||||||
|
;/*****************************************************************************/
|
||||||
|
;/* <<< Use Configuration Wizard in Context Menu >>> */
|
||||||
|
;/*****************************************************************************/
|
||||||
|
;/* This file is part of the uVision/ARM development tools. */
|
||||||
|
;/* Copyright (c) 2005-2007 Keil Software. All rights reserved. */
|
||||||
|
;/* This software may only be used under the terms of a valid, current, */
|
||||||
|
;/* end user licence from KEIL for a compatible version of KEIL software */
|
||||||
|
;/* development tools. Nothing else gives you the right to use this software. */
|
||||||
|
;/*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
;/*
|
||||||
|
; * The STARTUP.S code is executed after CPU Reset. This file may be
|
||||||
|
; * translated with the following SET symbols. In uVision these SET
|
||||||
|
; * symbols are entered under Options - ASM - Define.
|
||||||
|
; *
|
||||||
|
; * REMAP: when set the startup code initializes the register MEMMAP
|
||||||
|
; * which overwrites the settings of the CPU configuration pins. The
|
||||||
|
; * startup and interrupt vectors are remapped from:
|
||||||
|
; * 0x00000000 default setting (not remapped)
|
||||||
|
; * 0x80000000 when EXTMEM_MODE is used
|
||||||
|
; * 0x40000000 when RAM_MODE is used
|
||||||
|
; *
|
||||||
|
; * EXTMEM_MODE: when set the device is configured for code execution
|
||||||
|
; * from external memory starting at address 0x80000000.
|
||||||
|
; *
|
||||||
|
; * RAM_MODE: when set the device is configured for code execution
|
||||||
|
; * from on-chip RAM starting at address 0x40000000.
|
||||||
|
; *
|
||||||
|
; * EXTERNAL_MODE: when set the PIN2SEL values are written that enable
|
||||||
|
; * the external BUS at startup.
|
||||||
|
; */
|
||||||
|
|
||||||
|
|
||||||
|
; Standard definitions of Mode bits and Interrupt (I & F) flags in PSRs
|
||||||
|
|
||||||
|
Mode_USR EQU 0x10
|
||||||
|
Mode_FIQ EQU 0x11
|
||||||
|
Mode_IRQ EQU 0x12
|
||||||
|
Mode_SVC EQU 0x13
|
||||||
|
Mode_ABT EQU 0x17
|
||||||
|
Mode_UND EQU 0x1B
|
||||||
|
Mode_SYS EQU 0x1F
|
||||||
|
|
||||||
|
I_Bit EQU 0x80 ; when I bit is set, IRQ is disabled
|
||||||
|
F_Bit EQU 0x40 ; when F bit is set, FIQ is disabled
|
||||||
|
|
||||||
|
|
||||||
|
;// <h> Stack Configuration (Stack Sizes in Bytes)
|
||||||
|
;// <o0> Undefined Mode <0x0-0xFFFFFFFF:8>
|
||||||
|
;// <o1> Supervisor Mode <0x0-0xFFFFFFFF:8>
|
||||||
|
;// <o2> Abort Mode <0x0-0xFFFFFFFF:8>
|
||||||
|
;// <o3> Fast Interrupt Mode <0x0-0xFFFFFFFF:8>
|
||||||
|
;// <o4> Interrupt Mode <0x0-0xFFFFFFFF:8>
|
||||||
|
;// <o5> User/System Mode <0x0-0xFFFFFFFF:8>
|
||||||
|
;// </h>
|
||||||
|
|
||||||
|
UND_Stack_Size EQU 0x00000000
|
||||||
|
SVC_Stack_Size EQU 0x00000100
|
||||||
|
ABT_Stack_Size EQU 0x00000000
|
||||||
|
FIQ_Stack_Size EQU 0x00000000
|
||||||
|
IRQ_Stack_Size EQU 0x00000100
|
||||||
|
USR_Stack_Size EQU 0x00000100
|
||||||
|
|
||||||
|
ISR_Stack_Size EQU (UND_Stack_Size + SVC_Stack_Size + ABT_Stack_Size + \
|
||||||
|
FIQ_Stack_Size + IRQ_Stack_Size)
|
||||||
|
|
||||||
|
AREA STACK, NOINIT, READWRITE, ALIGN=3
|
||||||
|
|
||||||
|
Stack_Mem SPACE USR_Stack_Size
|
||||||
|
__initial_sp SPACE ISR_Stack_Size
|
||||||
|
|
||||||
|
Stack_Top
|
||||||
|
|
||||||
|
|
||||||
|
;// <h> Heap Configuration
|
||||||
|
;// <o> Heap Size (in Bytes) <0x0-0xFFFFFFFF>
|
||||||
|
;// </h>
|
||||||
|
|
||||||
|
Heap_Size EQU 0x00000000
|
||||||
|
|
||||||
|
AREA HEAP, NOINIT, READWRITE, ALIGN=3
|
||||||
|
__heap_base
|
||||||
|
Heap_Mem SPACE Heap_Size
|
||||||
|
__heap_limit
|
||||||
|
|
||||||
|
|
||||||
|
; VPBDIV definitions
|
||||||
|
VPBDIV EQU 0xE01FC100 ; VPBDIV Address
|
||||||
|
|
||||||
|
;// <e> VPBDIV Setup
|
||||||
|
;// <i> Peripheral Bus Clock Rate
|
||||||
|
;// <o1.0..1> VPBDIV: VPB Clock
|
||||||
|
;// <0=> VPB Clock = CPU Clock / 4
|
||||||
|
;// <1=> VPB Clock = CPU Clock
|
||||||
|
;// <2=> VPB Clock = CPU Clock / 2
|
||||||
|
;// <o1.4..5> XCLKDIV: XCLK Pin
|
||||||
|
;// <0=> XCLK Pin = CPU Clock / 4
|
||||||
|
;// <1=> XCLK Pin = CPU Clock
|
||||||
|
;// <2=> XCLK Pin = CPU Clock / 2
|
||||||
|
;// </e>
|
||||||
|
VPBDIV_SETUP EQU 0
|
||||||
|
VPBDIV_Val EQU 0x00000000
|
||||||
|
|
||||||
|
|
||||||
|
; Phase Locked Loop (PLL) definitions
|
||||||
|
PLL_BASE EQU 0xE01FC080 ; PLL Base Address
|
||||||
|
PLLCON_OFS EQU 0x00 ; PLL Control Offset
|
||||||
|
PLLCFG_OFS EQU 0x04 ; PLL Configuration Offset
|
||||||
|
PLLSTAT_OFS EQU 0x08 ; PLL Status Offset
|
||||||
|
PLLFEED_OFS EQU 0x0C ; PLL Feed Offset
|
||||||
|
PLLCON_PLLE EQU (1<<0) ; PLL Enable
|
||||||
|
PLLCON_PLLC EQU (1<<1) ; PLL Connect
|
||||||
|
PLLCFG_MSEL EQU (0x1F<<0) ; PLL Multiplier
|
||||||
|
PLLCFG_PSEL EQU (0x03<<5) ; PLL Divider
|
||||||
|
PLLSTAT_PLOCK EQU (1<<10) ; PLL Lock Status
|
||||||
|
|
||||||
|
;// <e> PLL Setup
|
||||||
|
;// <o1.0..4> MSEL: PLL Multiplier Selection
|
||||||
|
;// <1-32><#-1>
|
||||||
|
;// <i> M Value
|
||||||
|
;// <o1.5..6> PSEL: PLL Divider Selection
|
||||||
|
;// <0=> 1 <1=> 2 <2=> 4 <3=> 8
|
||||||
|
;// <i> P Value
|
||||||
|
;// </e>
|
||||||
|
PLL_SETUP EQU 1
|
||||||
|
PLLCFG_Val EQU 0x00000024
|
||||||
|
|
||||||
|
|
||||||
|
; Memory Accelerator Module (MAM) definitions
|
||||||
|
MAM_BASE EQU 0xE01FC000 ; MAM Base Address
|
||||||
|
MAMCR_OFS EQU 0x00 ; MAM Control Offset
|
||||||
|
MAMTIM_OFS EQU 0x04 ; MAM Timing Offset
|
||||||
|
|
||||||
|
;// <e> MAM Setup
|
||||||
|
;// <o1.0..1> MAM Control
|
||||||
|
;// <0=> Disabled
|
||||||
|
;// <1=> Partially Enabled
|
||||||
|
;// <2=> Fully Enabled
|
||||||
|
;// <i> Mode
|
||||||
|
;// <o2.0..2> MAM Timing
|
||||||
|
;// <0=> Reserved <1=> 1 <2=> 2 <3=> 3
|
||||||
|
;// <4=> 4 <5=> 5 <6=> 6 <7=> 7
|
||||||
|
;// <i> Fetch Cycles
|
||||||
|
;// </e>
|
||||||
|
MAM_SETUP EQU 1
|
||||||
|
MAMCR_Val EQU 0x00000002
|
||||||
|
MAMTIM_Val EQU 0x00000004
|
||||||
|
|
||||||
|
|
||||||
|
; External Memory Controller (EMC) definitions
|
||||||
|
EMC_BASE EQU 0xFFE00000 ; EMC Base Address
|
||||||
|
BCFG0_OFS EQU 0x00 ; BCFG0 Offset
|
||||||
|
BCFG1_OFS EQU 0x04 ; BCFG1 Offset
|
||||||
|
BCFG2_OFS EQU 0x08 ; BCFG2 Offset
|
||||||
|
BCFG3_OFS EQU 0x0C ; BCFG3 Offset
|
||||||
|
|
||||||
|
;// <e> External Memory Controller (EMC)
|
||||||
|
EMC_SETUP EQU 0
|
||||||
|
|
||||||
|
;// <e> Bank Configuration 0 (BCFG0)
|
||||||
|
;// <o1.0..3> IDCY: Idle Cycles <0-15>
|
||||||
|
;// <o1.5..9> WST1: Wait States 1 <0-31>
|
||||||
|
;// <o1.11..15> WST2: Wait States 2 <0-31>
|
||||||
|
;// <o1.10> RBLE: Read Byte Lane Enable
|
||||||
|
;// <o1.26> WP: Write Protect
|
||||||
|
;// <o1.27> BM: Burst ROM
|
||||||
|
;// <o1.28..29> MW: Memory Width <0=> 8-bit <1=> 16-bit
|
||||||
|
;// <2=> 32-bit <3=> Reserved
|
||||||
|
;// </e>
|
||||||
|
BCFG0_SETUP EQU 0
|
||||||
|
BCFG0_Val EQU 0x0000FBEF
|
||||||
|
|
||||||
|
;// <e> Bank Configuration 1 (BCFG1)
|
||||||
|
;// <o1.0..3> IDCY: Idle Cycles <0-15>
|
||||||
|
;// <o1.5..9> WST1: Wait States 1 <0-31>
|
||||||
|
;// <o1.11..15> WST2: Wait States 2 <0-31>
|
||||||
|
;// <o1.10> RBLE: Read Byte Lane Enable
|
||||||
|
;// <o1.26> WP: Write Protect
|
||||||
|
;// <o1.27> BM: Burst ROM
|
||||||
|
;// <o1.28..29> MW: Memory Width <0=> 8-bit <1=> 16-bit
|
||||||
|
;// <2=> 32-bit <3=> Reserved
|
||||||
|
;// </e>
|
||||||
|
BCFG1_SETUP EQU 0
|
||||||
|
BCFG1_Val EQU 0x0000FBEF
|
||||||
|
|
||||||
|
;// <e> Bank Configuration 2 (BCFG2)
|
||||||
|
;// <o1.0..3> IDCY: Idle Cycles <0-15>
|
||||||
|
;// <o1.5..9> WST1: Wait States 1 <0-31>
|
||||||
|
;// <o1.11..15> WST2: Wait States 2 <0-31>
|
||||||
|
;// <o1.10> RBLE: Read Byte Lane Enable
|
||||||
|
;// <o1.26> WP: Write Protect
|
||||||
|
;// <o1.27> BM: Burst ROM
|
||||||
|
;// <o1.28..29> MW: Memory Width <0=> 8-bit <1=> 16-bit
|
||||||
|
;// <2=> 32-bit <3=> Reserved
|
||||||
|
;// </e>
|
||||||
|
BCFG2_SETUP EQU 0
|
||||||
|
BCFG2_Val EQU 0x0000FBEF
|
||||||
|
|
||||||
|
;// <e> Bank Configuration 3 (BCFG3)
|
||||||
|
;// <o1.0..3> IDCY: Idle Cycles <0-15>
|
||||||
|
;// <o1.5..9> WST1: Wait States 1 <0-31>
|
||||||
|
;// <o1.11..15> WST2: Wait States 2 <0-31>
|
||||||
|
;// <o1.10> RBLE: Read Byte Lane Enable
|
||||||
|
;// <o1.26> WP: Write Protect
|
||||||
|
;// <o1.27> BM: Burst ROM
|
||||||
|
;// <o1.28..29> MW: Memory Width <0=> 8-bit <1=> 16-bit
|
||||||
|
;// <2=> 32-bit <3=> Reserved
|
||||||
|
;// </e>
|
||||||
|
BCFG3_SETUP EQU 0
|
||||||
|
BCFG3_Val EQU 0x0000FBEF
|
||||||
|
|
||||||
|
;// </e> End of EMC
|
||||||
|
|
||||||
|
|
||||||
|
; External Memory Pins definitions
|
||||||
|
PINSEL2 EQU 0xE002C014 ; PINSEL2 Address
|
||||||
|
PINSEL2_Val EQU 0x0E6149E4 ; CS0..3, OE, WE, BLS0..3,
|
||||||
|
; D0..31, A2..23, JTAG Pins
|
||||||
|
|
||||||
|
|
||||||
|
PRESERVE8
|
||||||
|
|
||||||
|
|
||||||
|
; Area Definition and Entry Point
|
||||||
|
; Startup Code must be linked first at Address at which it expects to run.
|
||||||
|
|
||||||
|
AREA RESET, CODE, READONLY
|
||||||
|
ARM
|
||||||
|
|
||||||
|
|
||||||
|
; Exception Vectors
|
||||||
|
; Mapped to Address 0.
|
||||||
|
; Absolute addressing mode must be used.
|
||||||
|
; Dummy Handlers are implemented as infinite loops which can be modified.
|
||||||
|
|
||||||
|
Vectors LDR PC, Reset_Addr
|
||||||
|
LDR PC, Undef_Addr
|
||||||
|
LDR PC, SWI_Addr
|
||||||
|
LDR PC, PAbt_Addr
|
||||||
|
LDR PC, DAbt_Addr
|
||||||
|
NOP ; Reserved Vector
|
||||||
|
LDR PC, IRQ_Addr
|
||||||
|
LDR PC, FIQ_Addr
|
||||||
|
|
||||||
|
Reset_Addr DCD Reset_Handler
|
||||||
|
Undef_Addr DCD Undef_Handler
|
||||||
|
SWI_Addr DCD SWI_Handler
|
||||||
|
PAbt_Addr DCD PAbt_Handler
|
||||||
|
DAbt_Addr DCD DAbt_Handler
|
||||||
|
DCD 0 ; Reserved Address
|
||||||
|
IRQ_Addr DCD IRQ_Handler
|
||||||
|
FIQ_Addr DCD FIQ_Handler
|
||||||
|
|
||||||
|
Undef_Handler B Undef_Handler
|
||||||
|
SWI_Handler B SWI_Handler
|
||||||
|
PAbt_Handler B PAbt_Handler
|
||||||
|
DAbt_Handler B DAbt_Handler
|
||||||
|
FIQ_Handler B FIQ_Handler
|
||||||
|
|
||||||
|
|
||||||
|
; Reset Handler
|
||||||
|
|
||||||
|
EXPORT Reset_Handler
|
||||||
|
Reset_Handler
|
||||||
|
|
||||||
|
|
||||||
|
; Setup External Memory Pins
|
||||||
|
IF :DEF:EXTERNAL_MODE
|
||||||
|
LDR R0, =PINSEL2
|
||||||
|
LDR R1, =PINSEL2_Val
|
||||||
|
STR R1, [R0]
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
|
||||||
|
; Setup External Memory Controller
|
||||||
|
IF EMC_SETUP <> 0
|
||||||
|
LDR R0, =EMC_BASE
|
||||||
|
|
||||||
|
IF BCFG0_SETUP <> 0
|
||||||
|
LDR R1, =BCFG0_Val
|
||||||
|
STR R1, [R0, #BCFG0_OFS]
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
IF BCFG1_SETUP <> 0
|
||||||
|
LDR R1, =BCFG1_Val
|
||||||
|
STR R1, [R0, #BCFG1_OFS]
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
IF BCFG2_SETUP <> 0
|
||||||
|
LDR R1, =BCFG2_Val
|
||||||
|
STR R1, [R0, #BCFG2_OFS]
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
IF BCFG3_SETUP <> 0
|
||||||
|
LDR R1, =BCFG3_Val
|
||||||
|
STR R1, [R0, #BCFG3_OFS]
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
ENDIF ; EMC_SETUP
|
||||||
|
|
||||||
|
|
||||||
|
; Setup VPBDIV
|
||||||
|
IF VPBDIV_SETUP <> 0
|
||||||
|
LDR R0, =VPBDIV
|
||||||
|
LDR R1, =VPBDIV_Val
|
||||||
|
STR R1, [R0]
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
|
||||||
|
; Setup PLL
|
||||||
|
IF PLL_SETUP <> 0
|
||||||
|
LDR R0, =PLL_BASE
|
||||||
|
MOV R1, #0xAA
|
||||||
|
MOV R2, #0x55
|
||||||
|
|
||||||
|
; Configure and Enable PLL
|
||||||
|
MOV R3, #PLLCFG_Val
|
||||||
|
STR R3, [R0, #PLLCFG_OFS]
|
||||||
|
MOV R3, #PLLCON_PLLE
|
||||||
|
STR R3, [R0, #PLLCON_OFS]
|
||||||
|
STR R1, [R0, #PLLFEED_OFS]
|
||||||
|
STR R2, [R0, #PLLFEED_OFS]
|
||||||
|
|
||||||
|
; Wait until PLL Locked
|
||||||
|
PLL_Loop LDR R3, [R0, #PLLSTAT_OFS]
|
||||||
|
ANDS R3, R3, #PLLSTAT_PLOCK
|
||||||
|
BEQ PLL_Loop
|
||||||
|
|
||||||
|
; Switch to PLL Clock
|
||||||
|
MOV R3, #(PLLCON_PLLE:OR:PLLCON_PLLC)
|
||||||
|
STR R3, [R0, #PLLCON_OFS]
|
||||||
|
STR R1, [R0, #PLLFEED_OFS]
|
||||||
|
STR R2, [R0, #PLLFEED_OFS]
|
||||||
|
ENDIF ; PLL_SETUP
|
||||||
|
|
||||||
|
|
||||||
|
; Setup MAM
|
||||||
|
IF MAM_SETUP <> 0
|
||||||
|
LDR R0, =MAM_BASE
|
||||||
|
MOV R1, #MAMTIM_Val
|
||||||
|
STR R1, [R0, #MAMTIM_OFS]
|
||||||
|
MOV R1, #MAMCR_Val
|
||||||
|
STR R1, [R0, #MAMCR_OFS]
|
||||||
|
ENDIF ; MAM_SETUP
|
||||||
|
|
||||||
|
|
||||||
|
; Memory Mapping (when Interrupt Vectors are in RAM)
|
||||||
|
MEMMAP EQU 0xE01FC040 ; Memory Mapping Control
|
||||||
|
IF :DEF:REMAP
|
||||||
|
LDR R0, =MEMMAP
|
||||||
|
IF :DEF:EXTMEM_MODE
|
||||||
|
MOV R1, #3
|
||||||
|
ELIF :DEF:RAM_MODE
|
||||||
|
MOV R1, #2
|
||||||
|
ELSE
|
||||||
|
MOV R1, #1
|
||||||
|
ENDIF
|
||||||
|
STR R1, [R0]
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
|
||||||
|
; Initialise Interrupt System
|
||||||
|
; ...
|
||||||
|
|
||||||
|
|
||||||
|
; Setup Stack for each mode
|
||||||
|
|
||||||
|
LDR R0, =Stack_Top
|
||||||
|
|
||||||
|
; Enter Undefined Instruction Mode and set its Stack Pointer
|
||||||
|
MSR CPSR_c, #Mode_UND:OR:I_Bit:OR:F_Bit
|
||||||
|
MOV SP, R0
|
||||||
|
SUB R0, R0, #UND_Stack_Size
|
||||||
|
|
||||||
|
; Enter Abort Mode and set its Stack Pointer
|
||||||
|
MSR CPSR_c, #Mode_ABT:OR:I_Bit:OR:F_Bit
|
||||||
|
MOV SP, R0
|
||||||
|
SUB R0, R0, #ABT_Stack_Size
|
||||||
|
|
||||||
|
; Enter FIQ Mode and set its Stack Pointer
|
||||||
|
MSR CPSR_c, #Mode_FIQ:OR:I_Bit:OR:F_Bit
|
||||||
|
MOV SP, R0
|
||||||
|
SUB R0, R0, #FIQ_Stack_Size
|
||||||
|
|
||||||
|
; Enter IRQ Mode and set its Stack Pointer
|
||||||
|
MSR CPSR_c, #Mode_IRQ:OR:I_Bit:OR:F_Bit
|
||||||
|
MOV SP, R0
|
||||||
|
SUB R0, R0, #IRQ_Stack_Size
|
||||||
|
|
||||||
|
; Enter Supervisor Mode and set its Stack Pointer
|
||||||
|
MSR CPSR_c, #Mode_SVC:OR:I_Bit:OR:F_Bit
|
||||||
|
MOV SP, R0
|
||||||
|
; SUB R0, R0, #SVC_Stack_Size
|
||||||
|
|
||||||
|
; Enter User Mode and set its Stack Pointer
|
||||||
|
; RT-Thread does not use user mode
|
||||||
|
; MSR CPSR_c, #Mode_USR
|
||||||
|
IF :DEF:__MICROLIB
|
||||||
|
|
||||||
|
EXPORT __initial_sp
|
||||||
|
|
||||||
|
ELSE
|
||||||
|
|
||||||
|
; MOV SP, R0
|
||||||
|
; SUB SL, SP, #USR_Stack_Size
|
||||||
|
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
; Enter the C code
|
||||||
|
|
||||||
|
IMPORT __main
|
||||||
|
LDR R0, =__main
|
||||||
|
BX R0
|
||||||
|
|
||||||
|
IMPORT rt_interrupt_enter
|
||||||
|
IMPORT rt_interrupt_leave
|
||||||
|
IMPORT rt_thread_switch_interrput_flag
|
||||||
|
IMPORT rt_interrupt_from_thread
|
||||||
|
IMPORT rt_interrupt_to_thread
|
||||||
|
IMPORT rt_hw_trap_irq
|
||||||
|
|
||||||
|
IRQ_Handler PROC
|
||||||
|
EXPORT IRQ_Handler
|
||||||
|
STMFD sp!, {r0-r12,lr}
|
||||||
|
BL rt_interrupt_enter
|
||||||
|
BL rt_hw_trap_irq
|
||||||
|
BL rt_interrupt_leave
|
||||||
|
|
||||||
|
; if rt_thread_switch_interrput_flag set, jump to
|
||||||
|
; rt_hw_context_switch_interrupt_do and don't return
|
||||||
|
LDR r0, =rt_thread_switch_interrput_flag
|
||||||
|
LDR r1, [r0]
|
||||||
|
CMP r1, #1
|
||||||
|
BEQ rt_hw_context_switch_interrupt_do
|
||||||
|
|
||||||
|
LDMFD sp!, {r0-r12,lr}
|
||||||
|
SUBS pc, lr, #4
|
||||||
|
ENDP
|
||||||
|
|
||||||
|
; /*
|
||||||
|
; * void rt_hw_context_switch_interrupt_do(rt_base_t flag)
|
||||||
|
; */
|
||||||
|
rt_hw_context_switch_interrupt_do PROC
|
||||||
|
EXPORT rt_hw_context_switch_interrupt_do
|
||||||
|
MOV r1, #0 ; clear flag
|
||||||
|
STR r1, [r0]
|
||||||
|
|
||||||
|
LDMFD sp!, {r0-r12,lr}; reload saved registers
|
||||||
|
STMFD sp!, {r0-r3} ; save r0-r3
|
||||||
|
MOV r1, sp
|
||||||
|
ADD sp, sp, #16 ; restore sp
|
||||||
|
SUB r2, lr, #4 ; save old task's pc to r2
|
||||||
|
|
||||||
|
MRS r3, spsr ; get cpsr of interrupt thread
|
||||||
|
|
||||||
|
; switch to SVC mode and no interrupt
|
||||||
|
MSR cpsr_c, #I_Bit|F_Bit|Mode_SVC
|
||||||
|
|
||||||
|
STMFD sp!, {r2} ; push old task's pc
|
||||||
|
STMFD sp!, {r4-r12,lr}; push old task's lr,r12-r4
|
||||||
|
MOV r4, r1 ; Special optimised code below
|
||||||
|
MOV r5, r3
|
||||||
|
LDMFD r4!, {r0-r3}
|
||||||
|
STMFD sp!, {r0-r3} ; push old task's r3-r0
|
||||||
|
STMFD sp!, {r5} ; push old task's cpsr
|
||||||
|
MRS r4, spsr
|
||||||
|
STMFD sp!, {r4} ; push old task's spsr
|
||||||
|
|
||||||
|
LDR r4, =rt_interrupt_from_thread
|
||||||
|
LDR r5, [r4]
|
||||||
|
STR sp, [r5] ; store sp in preempted tasks's TCB
|
||||||
|
|
||||||
|
LDR r6, =rt_interrupt_to_thread
|
||||||
|
LDR r6, [r6]
|
||||||
|
LDR sp, [r6] ; get new task's stack pointer
|
||||||
|
|
||||||
|
LDMFD sp!, {r4} ; pop new task's spsr
|
||||||
|
MSR spsr_cxsf, r4
|
||||||
|
LDMFD sp!, {r4} ; pop new task's psr
|
||||||
|
MSR cpsr_cxsf, r4
|
||||||
|
|
||||||
|
LDMFD sp!, {r0-r12,lr,pc} ; pop new task's r0-r12,lr & pc
|
||||||
|
ENDP
|
||||||
|
|
||||||
|
IF :DEF:__MICROLIB
|
||||||
|
|
||||||
|
EXPORT __heap_base
|
||||||
|
EXPORT __heap_limit
|
||||||
|
|
||||||
|
ELSE
|
||||||
|
; User Initial Stack & Heap
|
||||||
|
AREA |.text|, CODE, READONLY
|
||||||
|
|
||||||
|
IMPORT __use_two_region_memory
|
||||||
|
EXPORT __user_initial_stackheap
|
||||||
|
__user_initial_stackheap
|
||||||
|
|
||||||
|
LDR R0, = Heap_Mem
|
||||||
|
LDR R1, =(Stack_Mem + USR_Stack_Size)
|
||||||
|
LDR R2, = (Heap_Mem + Heap_Size)
|
||||||
|
LDR R3, = Stack_Mem
|
||||||
|
BX LR
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
END
|
|
@ -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 – 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 – 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 – R12,LR寄存器 */
|
||||||
|
mov r4, r1 /* Special optimised code below */
|
||||||
|
/* R1保存有压栈R0 – R3处的栈位置 */
|
||||||
|
mov r5, r3 /* R3切换出线程的CPSR */
|
||||||
|
ldmfd r4!, {r0-r3} /* 恢复R0 – R3 */
|
||||||
|
stmfd sp!, {r0-r3} /* push old task's r3-r0 */
|
||||||
|
/* R0 – R3压栈到切换出线程 */
|
||||||
|
stmfd sp!, {r5} /* push old task's psr */
|
||||||
|
/* 切换出线程CPSR压栈 */
|
||||||
|
mrs r4, spsr
|
||||||
|
stmfd sp!, {r4} /* push old task's spsr */
|
||||||
|
/* 切换出线程SPSR压栈 */
|
||||||
|
|
||||||
|
ldr r4, =rt_interrupt_from_thread
|
||||||
|
ldr r5, [r4]
|
||||||
|
str sp, [r5] /* store sp in preempted tasks's TCB */
|
||||||
|
/* 保存切换出线程的SP指针 */
|
||||||
|
|
||||||
|
ldr r6, =rt_interrupt_to_thread
|
||||||
|
ldr r6, [r6]
|
||||||
|
ldr sp, [r6] /* get new task's stack pointer */
|
||||||
|
/* 获得切换到线程的栈 */
|
||||||
|
|
||||||
|
ldmfd sp!, {r4} /* pop new task's spsr */
|
||||||
|
/* 恢复SPSR */
|
||||||
|
msr SPSR_cxsf, r4
|
||||||
|
ldmfd sp!, {r4} /* pop new task's psr */
|
||||||
|
/* 恢复CPSR */
|
||||||
|
msr CPSR_cxsf, r4
|
||||||
|
|
||||||
|
ldmfd sp!, {r0-r12,lr,pc} /* pop new task's r0-r12,lr & pc */
|
||||||
|
/* 恢复R0 – R12,LR及PC寄存器 */
|
||||||
|
|
||||||
|
/* 代码加密功能 */
|
||||||
|
#if defined(CODE_PROTECTION)
|
||||||
|
.org 0x01FC
|
||||||
|
.word 0x87654321
|
||||||
|
#endif
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
/*
|
||||||
|
* File : trap.c
|
||||||
|
* This file is part of RT-Thread RTOS
|
||||||
|
* COPYRIGHT (C) 2006, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* The license and distribution terms for this file may be
|
||||||
|
* found in the file LICENSE in this distribution or at
|
||||||
|
* http://openlab.rt-thread.com/license/LICENSE
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2006-08-25 Bernard first version
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <rthw.h>
|
||||||
|
#include <rtthread.h>
|
||||||
|
#include "lpc214x.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @addtogroup LPC214x
|
||||||
|
*/
|
||||||
|
/*@{*/
|
||||||
|
|
||||||
|
void rt_hw_trap_irq()
|
||||||
|
{
|
||||||
|
rt_isr_handler_t isr_func;
|
||||||
|
|
||||||
|
isr_func = (rt_isr_handler_t) VICVectAddr;
|
||||||
|
isr_func(0);
|
||||||
|
|
||||||
|
/* acknowledge Interrupt */
|
||||||
|
// VICVectAddr = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void rt_hw_trap_fiq()
|
||||||
|
{
|
||||||
|
rt_kprintf("fast interrupt request\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*@}*/
|
File diff suppressed because it is too large
Load Diff
|
@ -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
|
|
@ -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
|
|
@ -0,0 +1,42 @@
|
||||||
|
/*
|
||||||
|
* File : cpu.c
|
||||||
|
* This file is part of RT-Thread RTOS
|
||||||
|
* COPYRIGHT (C) 2006, RT-Thread Develop Team
|
||||||
|
*
|
||||||
|
* The license and distribution terms for this file may be
|
||||||
|
* found in the file LICENSE in this distribution or at
|
||||||
|
* http://openlab.rt-thread.com/license/LICENSE
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2008-12-11 XuXinming first version
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <rtthread.h>
|
||||||
|
#include "LPC24xx.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @addtogroup LPC2478
|
||||||
|
*/
|
||||||
|
/*@{*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* this function will reset CPU
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void rt_hw_cpu_reset()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* this function will shutdown CPU
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void rt_hw_cpu_shutdown()
|
||||||
|
{
|
||||||
|
rt_kprintf("shutdown...\n");
|
||||||
|
|
||||||
|
while (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*@}*/
|
|
@ -0,0 +1,86 @@
|
||||||
|
/*
|
||||||
|
* File : trap.c
|
||||||
|
* This file is part of RT-Thread RTOS
|
||||||
|
* COPYRIGHT (C) 2006, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* The license and distribution terms for this file may be
|
||||||
|
* found in the file LICENSE in this distribution or at
|
||||||
|
* http://openlab.rt-thread.com/license/LICENSE
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2008-12-11 XuXinming first version
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <rtthread.h>
|
||||||
|
#include "LPC24xx.h"
|
||||||
|
|
||||||
|
#define MAX_HANDLERS 32
|
||||||
|
|
||||||
|
extern rt_uint32_t rt_interrupt_nest;
|
||||||
|
|
||||||
|
/* exception and interrupt handler table */
|
||||||
|
rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread;
|
||||||
|
rt_uint32_t rt_thread_switch_interrput_flag;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @addtogroup LPC2478
|
||||||
|
*/
|
||||||
|
/*@{*/
|
||||||
|
|
||||||
|
void rt_hw_interrupt_handle(int vector)
|
||||||
|
{
|
||||||
|
rt_kprintf("Unhandled interrupt %d occured!!!\n", vector);
|
||||||
|
}
|
||||||
|
|
||||||
|
void rt_hw_interrupt_init()
|
||||||
|
{
|
||||||
|
register int i;
|
||||||
|
|
||||||
|
rt_uint32_t *vect_addr, *vect_cntl;
|
||||||
|
|
||||||
|
/* initialize VIC*/
|
||||||
|
VICIntEnClr = 0xffffffff;
|
||||||
|
VICVectAddr = 0;
|
||||||
|
VICIntSelect = 0;
|
||||||
|
|
||||||
|
for ( i = 0; i < 32; i++ )
|
||||||
|
{
|
||||||
|
vect_addr = (rt_uint32_t *)(VIC_BASE_ADDR + 0x100 + i*4);
|
||||||
|
vect_cntl = (rt_uint32_t *)(VIC_BASE_ADDR + 0x200 + i*4);
|
||||||
|
*vect_addr = 0x0;
|
||||||
|
*vect_cntl = 0xF;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* init interrupt nest, and context in thread sp */
|
||||||
|
rt_interrupt_nest = 0;
|
||||||
|
rt_interrupt_from_thread = 0;
|
||||||
|
rt_interrupt_to_thread = 0;
|
||||||
|
rt_thread_switch_interrput_flag = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void rt_hw_interrupt_mask(int vector)
|
||||||
|
{
|
||||||
|
VICIntEnClr = (1 << vector);
|
||||||
|
}
|
||||||
|
|
||||||
|
void rt_hw_interrupt_umask(int vector)
|
||||||
|
{
|
||||||
|
VICIntEnable = (1 << vector);
|
||||||
|
}
|
||||||
|
|
||||||
|
void rt_hw_interrupt_install(int vector, rt_isr_handler_t new_handler, rt_isr_handler_t *old_handler)
|
||||||
|
{
|
||||||
|
rt_uint32_t *vect_addr;
|
||||||
|
|
||||||
|
if(vector < MAX_HANDLERS)
|
||||||
|
{
|
||||||
|
/* find first un-assigned VIC address for the handler */
|
||||||
|
vect_addr = (rt_uint32_t *)(VIC_BASE_ADDR + 0x100 + vector*4);
|
||||||
|
*vect_addr = (rt_uint32_t)new_handler; /* set interrupt vector */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*@}*/
|
|
@ -0,0 +1,149 @@
|
||||||
|
/*
|
||||||
|
* File : serial.c
|
||||||
|
* This file is part of RT-Thread RTOS
|
||||||
|
* COPYRIGHT (C) 2006, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* The license and distribution terms for this file may be
|
||||||
|
* found in the file LICENSE in this distribution or at
|
||||||
|
* http://openlab.rt-thread.com/license/LICENSE
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2006-08-23 Bernard first version
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <rthw.h>
|
||||||
|
#include <rtthread.h>
|
||||||
|
#include "lpc214x.h"
|
||||||
|
#include "board.h"
|
||||||
|
|
||||||
|
void rt_serial_init(void);
|
||||||
|
|
||||||
|
#define PCLK 18000000
|
||||||
|
#define BAUD_RATE 115200
|
||||||
|
#define U0PINS 0x00000005
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @addtogroup LPC2100
|
||||||
|
*/
|
||||||
|
/*@{*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function is used to display a string on console, normally, it's
|
||||||
|
* invoked by rt_kprintf
|
||||||
|
*
|
||||||
|
* @param str the displayed string
|
||||||
|
*/
|
||||||
|
void rt_console_puts(const char* str)
|
||||||
|
{
|
||||||
|
while (*str)
|
||||||
|
{
|
||||||
|
rt_serial_putc (*str++);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define UART_RX_BUFFER_SIZE 64
|
||||||
|
static rt_uint8_t uart_rx_buffer[UART_RX_BUFFER_SIZE];
|
||||||
|
static rt_uint32_t uart_read_index, uart_save_index;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function initializes serial
|
||||||
|
*/
|
||||||
|
void rt_serial_init()
|
||||||
|
{
|
||||||
|
unsigned long Fdiv;
|
||||||
|
|
||||||
|
PINSEL0 = 0x00000050; /* RxD0 and TxD0 */
|
||||||
|
|
||||||
|
rt_memset(uart_rx_buffer, 0, sizeof(uart_rx_buffer));
|
||||||
|
uart_read_index = uart_save_index = 0;
|
||||||
|
|
||||||
|
U0LCR = 0x83; /* 8 bits, no Parity, 1 Stop bit */
|
||||||
|
/*PCLK select is 00,so /4*/
|
||||||
|
Fdiv = ( PCLK / 16 ) / BAUD_RATE ; /*baud rate */
|
||||||
|
U0DLM = Fdiv / 256;
|
||||||
|
U0DLL = Fdiv % 256;
|
||||||
|
U0FCR = 0x00; /* Enable and reset TX and RX FIFO. */
|
||||||
|
U0LCR = 0x03; /* DLAB = 0 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* save a char to serial buffer */
|
||||||
|
void rt_serial_savechar(char ch)
|
||||||
|
{
|
||||||
|
rt_base_t level;
|
||||||
|
|
||||||
|
/* disable interrupt */
|
||||||
|
level = rt_hw_interrupt_disable();
|
||||||
|
|
||||||
|
uart_rx_buffer[uart_save_index] = ch;
|
||||||
|
uart_save_index ++;
|
||||||
|
if (uart_save_index >= UART_RX_BUFFER_SIZE)
|
||||||
|
uart_save_index = 0;
|
||||||
|
|
||||||
|
/* if the next position is read index, discard this 'read char' */
|
||||||
|
if (uart_save_index == uart_read_index)
|
||||||
|
{
|
||||||
|
uart_read_index ++;
|
||||||
|
if (uart_read_index >= UART_RX_BUFFER_SIZE)
|
||||||
|
uart_read_index = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* enable interrupt */
|
||||||
|
rt_hw_interrupt_enable(level);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function read a character from serial without interrupt enable mode
|
||||||
|
*
|
||||||
|
* @return the read char
|
||||||
|
*/
|
||||||
|
char rt_serial_getc()
|
||||||
|
{
|
||||||
|
char ch;
|
||||||
|
rt_base_t level;
|
||||||
|
|
||||||
|
/* disable interrupt */
|
||||||
|
level = rt_hw_interrupt_disable();
|
||||||
|
|
||||||
|
if (uart_read_index != uart_save_index)
|
||||||
|
{
|
||||||
|
ch = uart_rx_buffer[uart_read_index];
|
||||||
|
|
||||||
|
uart_read_index ++;
|
||||||
|
if (uart_read_index >= UART_RX_BUFFER_SIZE)
|
||||||
|
uart_read_index = 0;
|
||||||
|
|
||||||
|
/* enable interrupt */
|
||||||
|
rt_hw_interrupt_enable(level);
|
||||||
|
|
||||||
|
return ch;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* enable interrupt */
|
||||||
|
rt_hw_interrupt_enable(level);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function will write a character to serial without interrupt enable mode
|
||||||
|
*
|
||||||
|
* @param c the char to write
|
||||||
|
*/
|
||||||
|
void rt_serial_putc(const char c)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
to be polite with serial console add a line feed
|
||||||
|
to the carriage return character
|
||||||
|
*/
|
||||||
|
if (c=='\n')
|
||||||
|
{
|
||||||
|
while (!(U0LSR & 0x20));
|
||||||
|
U0THR = '\r';
|
||||||
|
}
|
||||||
|
|
||||||
|
while (!(U0LSR & 0x20));
|
||||||
|
U0THR = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*@}*/
|
|
@ -0,0 +1,60 @@
|
||||||
|
/*
|
||||||
|
* File : stack.c
|
||||||
|
* This file is part of RT-Thread RTOS
|
||||||
|
* COPYRIGHT (C) 2006, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* The license and distribution terms for this file may be
|
||||||
|
* found in the file LICENSE in this distribution or at
|
||||||
|
* http://openlab.rt-thread.com/license/LICENSE
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2008-12-11 XuXinming first version
|
||||||
|
*/
|
||||||
|
#include <rtthread.h>
|
||||||
|
#include "LPC24xx.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @addtogroup LPC2478
|
||||||
|
*/
|
||||||
|
/*@{*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function will initialize thread stack
|
||||||
|
*
|
||||||
|
* @param tentry the entry of thread
|
||||||
|
* @param parameter the parameter of entry
|
||||||
|
* @param stack_addr the beginning stack address
|
||||||
|
* @param texit the function will be called when thread exit
|
||||||
|
*
|
||||||
|
* @return stack address
|
||||||
|
*/
|
||||||
|
rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter,
|
||||||
|
rt_uint8_t *stack_addr, void *texit)
|
||||||
|
{
|
||||||
|
unsigned long *stk;
|
||||||
|
|
||||||
|
stk = (unsigned long *)stack_addr;
|
||||||
|
*(stk) = (unsigned long)tentry; /* entry point */
|
||||||
|
*(--stk) = (unsigned long)texit; /* lr */
|
||||||
|
*(--stk) = 0; /* r12 */
|
||||||
|
*(--stk) = 0; /* r11 */
|
||||||
|
*(--stk) = 0; /* r10 */
|
||||||
|
*(--stk) = 0; /* r9 */
|
||||||
|
*(--stk) = 0; /* r8 */
|
||||||
|
*(--stk) = 0; /* r7 */
|
||||||
|
*(--stk) = 0; /* r6 */
|
||||||
|
*(--stk) = 0; /* r5 */
|
||||||
|
*(--stk) = 0; /* r4 */
|
||||||
|
*(--stk) = 0; /* r3 */
|
||||||
|
*(--stk) = 0; /* r2 */
|
||||||
|
*(--stk) = 0; /* r1 */
|
||||||
|
*(--stk) = (unsigned long)parameter; /* r0 : argument */
|
||||||
|
*(--stk) = SVCMODE; /* cpsr */
|
||||||
|
*(--stk) = SVCMODE; /* spsr */
|
||||||
|
|
||||||
|
/* return task's current stack address */
|
||||||
|
return (rt_uint8_t *)stk;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*@}*/
|
|
@ -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
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,132 @@
|
||||||
|
/*
|
||||||
|
* File : trap.c
|
||||||
|
* This file is part of RT-Thread RTOS
|
||||||
|
* COPYRIGHT (C) 2006, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* The license and distribution terms for this file may be
|
||||||
|
* found in the file LICENSE in this distribution or at
|
||||||
|
* http://openlab.rt-thread.com/license/LICENSE
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2008-12-11 XuXinming first version
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <rtthread.h>
|
||||||
|
#include <rthw.h>
|
||||||
|
|
||||||
|
#include "LPC24xx.h"
|
||||||
|
|
||||||
|
//#define BSP_INT_DEBUG
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @addtogroup LPC2478
|
||||||
|
*/
|
||||||
|
/*@{*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* this function will show registers of CPU
|
||||||
|
*
|
||||||
|
* @param regs the registers point
|
||||||
|
*/
|
||||||
|
void rt_hw_show_register (struct rt_hw_register *regs)
|
||||||
|
{
|
||||||
|
rt_kprintf("Execption:\n");
|
||||||
|
rt_kprintf("r00:0x%08x r01:0x%08x r02:0x%08x r03:0x%08x\n", regs->r0, regs->r1, regs->r2, regs->r3);
|
||||||
|
rt_kprintf("r04:0x%08x r05:0x%08x r06:0x%08x r07:0x%08x\n", regs->r4, regs->r5, regs->r6, regs->r7);
|
||||||
|
rt_kprintf("r08:0x%08x r09:0x%08x r10:0x%08x\n", regs->r8, regs->r9, regs->r10);
|
||||||
|
rt_kprintf("fp :0x%08x ip :0x%08x\n", regs->fp, regs->ip);
|
||||||
|
rt_kprintf("sp :0x%08x lr :0x%08x pc :0x%08x\n", regs->sp, regs->lr, regs->pc);
|
||||||
|
rt_kprintf("cpsr:0x%08x\n", regs->cpsr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When ARM7TDMI comes across an instruction which it cannot handle,
|
||||||
|
* it takes the undefined instruction trap.
|
||||||
|
*
|
||||||
|
* @param regs system registers
|
||||||
|
*
|
||||||
|
* @note never invoke this function in application
|
||||||
|
*/
|
||||||
|
void rt_hw_trap_udef(struct rt_hw_register *regs)
|
||||||
|
{
|
||||||
|
rt_kprintf("undefined instruction\n");
|
||||||
|
rt_hw_show_register(regs);
|
||||||
|
rt_hw_cpu_shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The software interrupt instruction (SWI) is used for entering
|
||||||
|
* Supervisor mode, usually to request a particular supervisor
|
||||||
|
* function.
|
||||||
|
*
|
||||||
|
* @param regs system registers
|
||||||
|
*
|
||||||
|
* @note never invoke this function in application
|
||||||
|
*/
|
||||||
|
void rt_hw_trap_swi(struct rt_hw_register *regs)
|
||||||
|
{
|
||||||
|
rt_kprintf("software interrupt\n");
|
||||||
|
rt_hw_show_register(regs);
|
||||||
|
rt_hw_cpu_shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An abort indicates that the current memory access cannot be completed,
|
||||||
|
* which occurs during an instruction prefetch.
|
||||||
|
*
|
||||||
|
* @param regs system registers
|
||||||
|
*
|
||||||
|
* @note never invoke this function in application
|
||||||
|
*/
|
||||||
|
void rt_hw_trap_pabt(struct rt_hw_register *regs)
|
||||||
|
{
|
||||||
|
rt_kprintf("prefetch abort\n");
|
||||||
|
rt_hw_show_register(regs);
|
||||||
|
rt_hw_cpu_shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An abort indicates that the current memory access cannot be completed,
|
||||||
|
* which occurs during a data access.
|
||||||
|
*
|
||||||
|
* @param regs system registers
|
||||||
|
*
|
||||||
|
* @note never invoke this function in application
|
||||||
|
*/
|
||||||
|
void rt_hw_trap_dabt(struct rt_hw_register *regs)
|
||||||
|
{
|
||||||
|
rt_kprintf("Data Abort ");
|
||||||
|
rt_hw_show_register(regs);
|
||||||
|
rt_hw_cpu_shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Normally, system will never reach here
|
||||||
|
*
|
||||||
|
* @param regs system registers
|
||||||
|
*
|
||||||
|
* @note never invoke this function in application
|
||||||
|
*/
|
||||||
|
void rt_hw_trap_resv(struct rt_hw_register *regs)
|
||||||
|
{
|
||||||
|
rt_kprintf("not used\n");
|
||||||
|
rt_hw_show_register(regs);
|
||||||
|
rt_hw_cpu_shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
extern rt_isr_handler_t isr_table[];
|
||||||
|
void rt_hw_trap_irq()
|
||||||
|
{
|
||||||
|
rt_isr_handler_t isr_func;
|
||||||
|
|
||||||
|
isr_func = (rt_isr_handler_t) VICVectAddr;
|
||||||
|
isr_func(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void rt_hw_trap_fiq()
|
||||||
|
{
|
||||||
|
rt_kprintf("fast interrupt request\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*@}*/
|
|
@ -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
|
|
@ -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
|
|
@ -0,0 +1,122 @@
|
||||||
|
/*
|
||||||
|
* File : cpu.c
|
||||||
|
* This file is part of RT-Thread RTOS
|
||||||
|
* COPYRIGHT (C) 2006, RT-Thread Develop Team
|
||||||
|
*
|
||||||
|
* The license and distribution terms for this file may be
|
||||||
|
* found in the file LICENSE in this distribution or at
|
||||||
|
* http://openlab.rt-thread.com/license/LICENSE
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2006-09-06 XuXinming first version
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <rtthread.h>
|
||||||
|
#include "s3c44b0.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @addtogroup S3C44B0
|
||||||
|
*/
|
||||||
|
/*@{*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function will enable I-Cache of CPU
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void rt_hw_cpu_icache_enable()
|
||||||
|
{
|
||||||
|
rt_base_t reg;
|
||||||
|
|
||||||
|
volatile int i;
|
||||||
|
/* flush cycle */
|
||||||
|
for(i = 0x10002000; i < 0x10004800; i+=16)
|
||||||
|
{
|
||||||
|
*((int *)i)=0x0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Init cache
|
||||||
|
* Non-cacheable area (everything outside RAM)
|
||||||
|
* 0x0000:0000 - 0x0C00:0000
|
||||||
|
*/
|
||||||
|
NCACHBE0 = 0xC0000000;
|
||||||
|
NCACHBE1 = 0x00000000;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Enable chache
|
||||||
|
*/
|
||||||
|
reg = SYSCFG;
|
||||||
|
reg |= 0x00000006; /* 8kB */
|
||||||
|
SYSCFG = reg;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function will disable I-Cache of CPU
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void rt_hw_cpu_icache_disable()
|
||||||
|
{
|
||||||
|
rt_base_t reg;
|
||||||
|
|
||||||
|
reg = SYSCFG;
|
||||||
|
reg &= ~0x00000006; /* 8kB */
|
||||||
|
SYSCFG = reg;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* this function will get the status of I-Cache
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
rt_base_t rt_hw_cpu_icache_status()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* this function will enable D-Cache of CPU
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void rt_hw_cpu_dcache_enable()
|
||||||
|
{
|
||||||
|
rt_hw_cpu_icache_enable();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* this function will disable D-Cache of CPU
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void rt_hw_cpu_dcache_disable()
|
||||||
|
{
|
||||||
|
rt_hw_cpu_icache_disable();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* this function will get the status of D-Cache
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
rt_base_t rt_hw_cpu_dcache_status()
|
||||||
|
{
|
||||||
|
return rt_hw_cpu_icache_status();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* this function will reset CPU
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void rt_hw_cpu_reset()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* this function will shutdown CPU
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void rt_hw_cpu_shutdown()
|
||||||
|
{
|
||||||
|
rt_kprintf("shutdown...\n");
|
||||||
|
|
||||||
|
while (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*@}*/
|
|
@ -0,0 +1,148 @@
|
||||||
|
/*
|
||||||
|
* File : trap.c
|
||||||
|
* This file is part of RT-Thread RTOS
|
||||||
|
* COPYRIGHT (C) 2006, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* The license and distribution terms for this file may be
|
||||||
|
* found in the file LICENSE in this distribution or at
|
||||||
|
* http://openlab.rt-thread.com/license/LICENSE
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2006-09-06 XuXinming first version
|
||||||
|
* 2006-09-15 Bernard add interrupt bank 0..3 for more effective
|
||||||
|
* in irq trap
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <rtthread.h>
|
||||||
|
#include "s3c44b0.h"
|
||||||
|
|
||||||
|
#define MAX_HANDLERS 26
|
||||||
|
|
||||||
|
extern rt_uint32_t rt_interrupt_nest;
|
||||||
|
|
||||||
|
/* exception and interrupt handler table */
|
||||||
|
rt_isr_handler_t isr_table[MAX_HANDLERS];
|
||||||
|
rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread;
|
||||||
|
rt_uint32_t rt_thread_switch_interrput_flag;
|
||||||
|
|
||||||
|
unsigned char interrupt_bank0[256];
|
||||||
|
unsigned char interrupt_bank1[256];
|
||||||
|
unsigned char interrupt_bank2[256];
|
||||||
|
unsigned char interrupt_bank3[256];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @addtogroup S3C44B0
|
||||||
|
*/
|
||||||
|
/*@{*/
|
||||||
|
|
||||||
|
void rt_hw_interrupt_handle(int vector)
|
||||||
|
{
|
||||||
|
rt_kprintf("Unhandled interrupt %d occured!!!\n", vector);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function will initialize hardware interrupt
|
||||||
|
*/
|
||||||
|
void rt_hw_interrupt_init()
|
||||||
|
{
|
||||||
|
register int i;
|
||||||
|
|
||||||
|
/* all interrupt disabled include global bit */
|
||||||
|
INTMSK = 0x07ffffff;
|
||||||
|
|
||||||
|
/* clear pending register */
|
||||||
|
I_ISPC = 0x03ffffff;
|
||||||
|
|
||||||
|
/* non-vector mode IRQ enable */
|
||||||
|
INTCON = 0x5;
|
||||||
|
|
||||||
|
/* all IRQ mode */
|
||||||
|
INTMOD = 0x0;
|
||||||
|
|
||||||
|
/* init exceptions table */
|
||||||
|
for(i=0; i<MAX_HANDLERS; i++)
|
||||||
|
{
|
||||||
|
isr_table[i] = rt_hw_interrupt_handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( i = 0; i < 256; i++)
|
||||||
|
{
|
||||||
|
interrupt_bank0[i] = 0;
|
||||||
|
interrupt_bank1[i] = 0;
|
||||||
|
interrupt_bank2[i] = 0;
|
||||||
|
interrupt_bank3[i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* setup interrupt bank table */
|
||||||
|
interrupt_bank0[1] = 0;
|
||||||
|
interrupt_bank0[2] = 1;
|
||||||
|
interrupt_bank0[4] = 2;
|
||||||
|
interrupt_bank0[8] = 3;
|
||||||
|
interrupt_bank0[16] = 4;
|
||||||
|
interrupt_bank0[32] = 5;
|
||||||
|
interrupt_bank0[64] = 6;
|
||||||
|
interrupt_bank0[128]= 7;
|
||||||
|
|
||||||
|
interrupt_bank1[1] = 8;
|
||||||
|
interrupt_bank1[2] = 9;
|
||||||
|
interrupt_bank1[4] = 10;
|
||||||
|
interrupt_bank1[8] = 11;
|
||||||
|
interrupt_bank1[16] = 12;
|
||||||
|
interrupt_bank1[32] = 13;
|
||||||
|
interrupt_bank1[64] = 14;
|
||||||
|
interrupt_bank1[128]= 15;
|
||||||
|
|
||||||
|
interrupt_bank2[1] = 16;
|
||||||
|
interrupt_bank2[2] = 17;
|
||||||
|
interrupt_bank2[4] = 18;
|
||||||
|
interrupt_bank2[8] = 19;
|
||||||
|
interrupt_bank2[16] = 20;
|
||||||
|
interrupt_bank2[32] = 21;
|
||||||
|
interrupt_bank2[64] = 22;
|
||||||
|
interrupt_bank2[128]= 23;
|
||||||
|
|
||||||
|
interrupt_bank3[1] = 24;
|
||||||
|
interrupt_bank3[2] = 25;
|
||||||
|
|
||||||
|
/* init interrupt nest, and context in thread sp */
|
||||||
|
rt_interrupt_nest = 0;
|
||||||
|
rt_interrupt_from_thread = 0;
|
||||||
|
rt_interrupt_to_thread = 0;
|
||||||
|
rt_thread_switch_interrput_flag = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function will mask a interrupt.
|
||||||
|
* @param vector the interrupt number
|
||||||
|
*/
|
||||||
|
void rt_hw_interrupt_mask(int vector)
|
||||||
|
{
|
||||||
|
INTMSK |= 1 << vector;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function will un-mask a interrupt.
|
||||||
|
* @param vector the interrupt number
|
||||||
|
*/
|
||||||
|
void rt_hw_interrupt_umask(int vector)
|
||||||
|
{
|
||||||
|
INTMSK &= ~(1 << vector);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function will install a interrupt service routine to a interrupt.
|
||||||
|
* @param vector the interrupt number
|
||||||
|
* @param new_handler the interrupt service routine to be installed
|
||||||
|
* @param old_handler the old interrupt service routine
|
||||||
|
*/
|
||||||
|
void rt_hw_interrupt_install(int vector, rt_isr_handler_t new_handler, rt_isr_handler_t *old_handler)
|
||||||
|
{
|
||||||
|
if(vector < MAX_HANDLERS)
|
||||||
|
{
|
||||||
|
if (old_handler != RT_NULL) *old_handler = isr_table[vector];
|
||||||
|
if (new_handler != RT_NULL) isr_table[vector] = new_handler;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*@}*/
|
|
@ -0,0 +1,346 @@
|
||||||
|
/*
|
||||||
|
* File : s3c45b0.h
|
||||||
|
* This file is part of RT-Thread RTOS
|
||||||
|
* COPYRIGHT (C) 2006, RT-Thread Develop Team
|
||||||
|
*
|
||||||
|
* The license and distribution terms for this file may be
|
||||||
|
* found in the file LICENSE in this distribution or at
|
||||||
|
* http://openlab.rt-thread.com/license/LICENSE
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2006-09-06 XuXinming first version
|
||||||
|
* 2006-09-16 Bernard modify according to code style
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __S3C44B0_H__
|
||||||
|
#define __S3C44B0_H__
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @addtogroup S3C44B0
|
||||||
|
*/
|
||||||
|
/*@{*/
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------
|
||||||
|
* ASIC Address Definition
|
||||||
|
*----------------------------------------------------------------------*/
|
||||||
|
#define S3C_REG *(volatile unsigned int *)
|
||||||
|
#define S3C_REGW *(volatile unsigned short *)
|
||||||
|
#define S3C_REGB *(volatile unsigned char *)
|
||||||
|
|
||||||
|
/* System */
|
||||||
|
#define SYSCFG (S3C_REG(0x1c00000))
|
||||||
|
|
||||||
|
/* Cache */
|
||||||
|
#define NCACHBE0 (S3C_REG(0x1c00004))
|
||||||
|
#define NCACHBE1 (S3C_REG(0x1c00008))
|
||||||
|
|
||||||
|
/* Bus control */
|
||||||
|
#define SBUSCON (S3C_REG(0x1c40000))
|
||||||
|
|
||||||
|
/* Memory control */
|
||||||
|
#define BWSCON (S3C_REG(0x1c80000))
|
||||||
|
#define BANKCON0 (S3C_REG(0x1c80004))
|
||||||
|
#define BANKCON1 (S3C_REG(0x1c80008))
|
||||||
|
#define BANKCON2 (S3C_REG(0x1c8000c))
|
||||||
|
#define BANKCON3 (S3C_REG(0x1c80010))
|
||||||
|
#define BANKCON4 (S3C_REG(0x1c80014))
|
||||||
|
#define BANKCON5 (S3C_REG(0x1c80018))
|
||||||
|
#define BANKCON6 (S3C_REG(0x1c8001c))
|
||||||
|
#define BANKCON7 (S3C_REG(0x1c80020))
|
||||||
|
#define REFRESH (S3C_REG(0x1c80024))
|
||||||
|
#define BANKSIZE (S3C_REG(0x1c80028))
|
||||||
|
#define MRSRB6 (S3C_REG(0x1c8002c))
|
||||||
|
#define MRSRB7 (S3C_REG(0x1c80030))
|
||||||
|
|
||||||
|
/* UART */
|
||||||
|
#define ULCON0 (S3C_REG(0x1d00000))
|
||||||
|
#define ULCON1 (S3C_REG(0x1d04000))
|
||||||
|
#define UCON0 (S3C_REG(0x1d00004))
|
||||||
|
#define UCON1 (S3C_REG(0x1d04004))
|
||||||
|
#define UFCON0 (S3C_REG(0x1d00008))
|
||||||
|
#define UFCON1 (S3C_REG(0x1d04008))
|
||||||
|
#define UMCON0 (S3C_REG(0x1d0000c))
|
||||||
|
#define UMCON1 (S3C_REG(0x1d0400c))
|
||||||
|
#define UTRSTAT0 (S3C_REG(0x1d00010))
|
||||||
|
#define UTRSTAT1 (S3C_REG(0x1d04010))
|
||||||
|
#define UERSTAT0 (S3C_REG(0x1d00014))
|
||||||
|
#define UERSTAT1 (S3C_REG(0x1d04014))
|
||||||
|
#define UFSTAT0 (S3C_REG(0x1d00018))
|
||||||
|
#define UFSTAT1 (S3C_REG(0x1d04018))
|
||||||
|
#define UMSTAT0 (S3C_REG(0x1d0001c))
|
||||||
|
#define UMSTAT1 (S3C_REG(0x1d0401c))
|
||||||
|
#define UBRDIV0 (S3C_REG(0x1d00028))
|
||||||
|
#define UBRDIV1 (S3C_REG(0x1d04028))
|
||||||
|
|
||||||
|
#define UTXH0 (S3C_REGB(0x1d00020))
|
||||||
|
#define UTXH1 (S3C_REGB(0x1d04020))
|
||||||
|
#define URXH0 (S3C_REGB(0x1d00024))
|
||||||
|
#define URXH1 (S3C_REGB(0x1d04024))
|
||||||
|
|
||||||
|
/* SIO */
|
||||||
|
#define SIOCON (S3C_REG(0x1d14000))
|
||||||
|
#define SIODAT (S3C_REG(0x1d14004))
|
||||||
|
#define SBRDR (S3C_REG(0x1d14008))
|
||||||
|
#define IVTCNT (S3C_REG(0x1d1400c))
|
||||||
|
#define DCNTZ (S3C_REG(0x1d14010))
|
||||||
|
|
||||||
|
/* IIS */
|
||||||
|
#define IISCON (S3C_REG(0x1d18000))
|
||||||
|
#define IISMOD (S3C_REG(0x1d18004))
|
||||||
|
#define IISPSR (S3C_REG(0x1d18008))
|
||||||
|
#define IISFCON (S3C_REG(0x1d1800c))
|
||||||
|
|
||||||
|
#define IISFIF (S3C_REQW(0x1d18010))
|
||||||
|
|
||||||
|
/* I/O Port */
|
||||||
|
#define PCONA (S3C_REG(0x1d20000))
|
||||||
|
#define PDATA (S3C_REG(0x1d20004))
|
||||||
|
|
||||||
|
#define PCONB (S3C_REG(0x1d20008))
|
||||||
|
#define PDATB (S3C_REG(0x1d2000c))
|
||||||
|
|
||||||
|
#define PCONC (S3C_REG(0x1d20010))
|
||||||
|
#define PDATC (S3C_REG(0x1d20014))
|
||||||
|
#define PUPC (S3C_REG(0x1d20018))
|
||||||
|
|
||||||
|
#define PCOND (S3C_REG(0x1d2001c))
|
||||||
|
#define PDATD (S3C_REG(0x1d20020))
|
||||||
|
#define PUPD (S3C_REG(0x1d20024))
|
||||||
|
|
||||||
|
#define PCONE (S3C_REG(0x1d20028))
|
||||||
|
#define PDATE (S3C_REG(0x1d2002c))
|
||||||
|
#define PUPE (S3C_REG(0x1d20030))
|
||||||
|
|
||||||
|
#define PCONF (S3C_REG(0x1d20034))
|
||||||
|
#define PDATF (S3C_REG(0x1d20038))
|
||||||
|
#define PUPF (S3C_REG(0x1d2003c))
|
||||||
|
|
||||||
|
#define PCONG (S3C_REG(0x1d20040))
|
||||||
|
#define PDATG (S3C_REG(0x1d20044))
|
||||||
|
#define PUPG (S3C_REG(0x1d20048))
|
||||||
|
|
||||||
|
#define SPUCR (S3C_REG(0x1d2004c))
|
||||||
|
#define EXTINT (S3C_REG(0x1d20050))
|
||||||
|
#define EXTINTPND (S3C_REG(0x1d20054))
|
||||||
|
|
||||||
|
/* Watchdog */
|
||||||
|
#define WTCON (S3C_REG(0x1d30000))
|
||||||
|
#define WTDAT (S3C_REG(0x1d30004))
|
||||||
|
#define WTCNT (S3C_REG(0x1d30008))
|
||||||
|
|
||||||
|
/* ADC */
|
||||||
|
#define ADCCON (S3C_REG(0x1d40000))
|
||||||
|
#define ADCPSR (S3C_REG(0x1d40004))
|
||||||
|
#define ADCDAT (S3C_REG(0x1d40008))
|
||||||
|
|
||||||
|
/* Timer */
|
||||||
|
#define TCFG0 (S3C_REG(0x1d50000))
|
||||||
|
#define TCFG1 (S3C_REG(0x1d50004))
|
||||||
|
#define TCON (S3C_REG(0x1d50008))
|
||||||
|
|
||||||
|
#define TCNTB0 (S3C_REG(0x1d5000c))
|
||||||
|
#define TCMPB0 (S3C_REG(0x1d50010))
|
||||||
|
#define TCNTO0 (S3C_REG(0x1d50014))
|
||||||
|
|
||||||
|
#define TCNTB1 (S3C_REG(0x1d50018))
|
||||||
|
#define TCMPB1 (S3C_REG(0x1d5001c))
|
||||||
|
#define TCNTO1 (S3C_REG(0x1d50020))
|
||||||
|
|
||||||
|
#define TCNTB2 (S3C_REG(0x1d50024))
|
||||||
|
#define TCMPB2 (S3C_REG(0x1d50028))
|
||||||
|
#define TCNTO2 (S3C_REG(0x1d5002c))
|
||||||
|
|
||||||
|
#define TCNTB3 (S3C_REG(0x1d50030))
|
||||||
|
#define TCMPB3 (S3C_REG(0x1d50034))
|
||||||
|
#define TCNTO3 (S3C_REG(0x1d50038))
|
||||||
|
|
||||||
|
#define TCNTB4 (S3C_REG(0x1d5003c))
|
||||||
|
#define TCMPB4 (S3C_REG(0x1d50040))
|
||||||
|
#define TCNTO4 (S3C_REG(0x1d50044))
|
||||||
|
|
||||||
|
#define TCNTB5 (S3C_REG(0x1d50048))
|
||||||
|
#define TCNTO5 (S3C_REG(0x1d5004c))
|
||||||
|
|
||||||
|
/* IIC */
|
||||||
|
#define IICCON (S3C_REG(0x1d60000))
|
||||||
|
#define IICSTAT (S3C_REG(0x1d60004))
|
||||||
|
#define IICADD (S3C_REG(0x1d60008))
|
||||||
|
#define IICDS (S3C_REG(0x1d6000c))
|
||||||
|
|
||||||
|
/* RTC */
|
||||||
|
#define RTCCON (S3C_REGB(0x1d70040)
|
||||||
|
#define RTCALM (S3C_REGB(0x1d70050)
|
||||||
|
#define ALMSEC (S3C_REGB(0x1d70054)
|
||||||
|
#define ALMMIN (S3C_REGB(0x1d70058)
|
||||||
|
#define ALMHOUR (S3C_REGB(0x1d7005c)
|
||||||
|
#define ALMDAY (S3C_REGB(0x1d70060)
|
||||||
|
#define ALMMON (S3C_REGB(0x1d70064)
|
||||||
|
#define ALMYEAR (S3C_REGB(0x1d70068)
|
||||||
|
#define RTCRST (S3C_REGB(0x1d7006c)
|
||||||
|
#define BCDSEC (S3C_REGB(0x1d70070)
|
||||||
|
#define BCDMIN (S3C_REGB(0x1d70074)
|
||||||
|
#define BCDHOUR (S3C_REGB(0x1d70078)
|
||||||
|
#define BCDDAY (S3C_REGB(0x1d7007c)
|
||||||
|
#define BCDDATE (S3C_REGB(0x1d70080)
|
||||||
|
#define BCDMON (S3C_REGB(0x1d70084)
|
||||||
|
#define BCDYEAR (S3C_REGB(0x1d70088)
|
||||||
|
#define TICINT (S3C_REGB(0x1d7008c)
|
||||||
|
|
||||||
|
/* Clock & Power management */
|
||||||
|
#define PLLCON (S3C_REG(0x1d80000))
|
||||||
|
#define CLKCON (S3C_REG(0x1d80004))
|
||||||
|
#define CLKSLOW (S3C_REG(0x1d80008))
|
||||||
|
#define LOCKTIME (S3C_REG(0x1d8000c))
|
||||||
|
|
||||||
|
/* Interrupt */
|
||||||
|
#define INTCON (S3C_REG(0x1e00000))
|
||||||
|
#define INTPND (S3C_REG(0x1e00004))
|
||||||
|
#define INTMOD (S3C_REG(0x1e00008))
|
||||||
|
#define INTMSK (S3C_REG(0x1e0000c))
|
||||||
|
|
||||||
|
#define I_PSLV (S3C_REG(0x1e00010))
|
||||||
|
#define I_PMST (S3C_REG(0x1e00014))
|
||||||
|
#define I_CSLV (S3C_REG(0x1e00018))
|
||||||
|
#define I_CMST (S3C_REG(0x1e0001c))
|
||||||
|
#define I_ISPR (S3C_REG(0x1e00020))
|
||||||
|
#define I_ISPC (S3C_REG(0x1e00024))
|
||||||
|
|
||||||
|
#define F_ISPR (S3C_REG(0x1e00038))
|
||||||
|
#define F_ISPC (S3C_REG(0x1e0003c))
|
||||||
|
|
||||||
|
/********************************/
|
||||||
|
/* LCD Controller Registers */
|
||||||
|
/********************************/
|
||||||
|
#define LCDCON1 (S3C_REG(0x300000))
|
||||||
|
#define LCDCON2 (S3C_REG(0x300004))
|
||||||
|
#define LCDSADDR1 (S3C_REG(0x300008))
|
||||||
|
#define LCDSADDR2 (S3C_REG(0x30000c))
|
||||||
|
#define LCDSADDR3 (S3C_REG(0x300010))
|
||||||
|
#define REDLUT (S3C_REG(0x300014))
|
||||||
|
#define GREENLUT (S3C_REG(0x300018))
|
||||||
|
#define BLUELUT (S3C_REG(0x30001c))
|
||||||
|
#define DP1_2 (S3C_REG(0x300020))
|
||||||
|
#define DP4_7 (S3C_REG(0x300024))
|
||||||
|
#define DP3_5 (S3C_REG(0x300028))
|
||||||
|
#define DP2_3 (S3C_REG(0x30002c))
|
||||||
|
#define DP5_7 (S3C_REG(0x300030))
|
||||||
|
#define DP3_4 (S3C_REG(0x300034))
|
||||||
|
#define DP4_5 (S3C_REG(0x300038))
|
||||||
|
#define DP6_7 (S3C_REG(0x30003c))
|
||||||
|
#define LCDCON3 (S3C_REG(0x300040))
|
||||||
|
#define DITHMODE (S3C_REG(0x300044))
|
||||||
|
|
||||||
|
/* ZDMA0 */
|
||||||
|
#define ZDCON0 (S3C_REG(0x1e80000))
|
||||||
|
#define ZDISRC0 (S3C_REG(0x1e80004))
|
||||||
|
#define ZDIDES0 (S3C_REG(0x1e80008))
|
||||||
|
#define ZDICNT0 (S3C_REG(0x1e8000c))
|
||||||
|
#define ZDCSRC0 (S3C_REG(0x1e80010))
|
||||||
|
#define ZDCDES0 (S3C_REG(0x1e80014))
|
||||||
|
#define ZDCCNT0 (S3C_REG(0x1e80018))
|
||||||
|
|
||||||
|
/* ZDMA1 */
|
||||||
|
#define ZDCON1 (S3C_REG(0x1e80020))
|
||||||
|
#define ZDISRC1 (S3C_REG(0x1e80024))
|
||||||
|
#define ZDIDES1 (S3C_REG(0x1e80028))
|
||||||
|
#define ZDICNT1 (S3C_REG(0x1e8002c))
|
||||||
|
#define ZDCSRC1 (S3C_REG(0x1e80030))
|
||||||
|
#define ZDCDES1 (S3C_REG(0x1e80034))
|
||||||
|
#define ZDCCNT1 (S3C_REG(0x1e80038))
|
||||||
|
|
||||||
|
/* BDMA0 */
|
||||||
|
#define BDCON0 (S3C_REG(0x1f80000))
|
||||||
|
#define BDISRC0 (S3C_REG(0x1f80004))
|
||||||
|
#define BDIDES0 (S3C_REG(0x1f80008))
|
||||||
|
#define BDICNT0 (S3C_REG(0x1f8000c))
|
||||||
|
#define BDCSRC0 (S3C_REG(0x1f80010))
|
||||||
|
#define BDCDES0 (S3C_REG(0x1f80014))
|
||||||
|
#define BDCCNT0 (S3C_REG(0x1f80018))
|
||||||
|
|
||||||
|
/* BDMA1 */
|
||||||
|
#define BDCON1 (S3C_REG(0x1f80020))
|
||||||
|
#define BDISRC1 (S3C_REG(0x1f80024))
|
||||||
|
#define BDIDES1 (S3C_REG(0x1f80028))
|
||||||
|
#define BDICNT1 (S3C_REG(0x1f8002c))
|
||||||
|
#define BDCSRC1 (S3C_REG(0x1f80030))
|
||||||
|
#define BDCDES1 (S3C_REG(0x1f80034))
|
||||||
|
#define BDCCNT1 (S3C_REG(0x1f80038))
|
||||||
|
|
||||||
|
/*****************************/
|
||||||
|
/* CPU Mode */
|
||||||
|
/*****************************/
|
||||||
|
#define USERMODE 0x10 /* User Mode(USR) */
|
||||||
|
#define FIQMODE 0x11 /* Fast Interrupt Mode (FIQ) */
|
||||||
|
#define IRQMODE 0x12 /* Interrupt Mode (IRQ) */
|
||||||
|
#define SVCMODE 0x13 /* Supervisor Mode (SVC) */
|
||||||
|
#define ABORTMODE 0x17 /* Abort Mode(ABT) */
|
||||||
|
#define UNDEFMODE 0x1b /* Undefine Mode(UDF) */
|
||||||
|
#define MODEMASK 0x1f /* Processor Mode Mask */
|
||||||
|
#define NOINT 0xc0
|
||||||
|
|
||||||
|
/*****************************/
|
||||||
|
/* INT Define */
|
||||||
|
/*****************************/
|
||||||
|
#define INT_ADC 0x00
|
||||||
|
#define INT_RTC 0x01
|
||||||
|
#define INT_UTXD1 0x02
|
||||||
|
#define INT_UTXD0 0x03
|
||||||
|
#define INT_SIO 0x04
|
||||||
|
#define INT_IIC 0x05
|
||||||
|
#define INT_URXD1 0x06
|
||||||
|
#define INT_URXD0 0x07
|
||||||
|
#define INT_TIMER5 0x08
|
||||||
|
#define INT_TIMER4 0x09
|
||||||
|
#define INT_TIMER3 0x0A
|
||||||
|
#define INT_TIMER2 0x0B
|
||||||
|
#define INT_TIMER1 0x0C
|
||||||
|
#define INT_TIMER0 0x0D
|
||||||
|
#define INT_UERR01 0x0E
|
||||||
|
#define INT_WDT 0x1F
|
||||||
|
#define INT_BDMA1 0x10
|
||||||
|
#define INT_BDMA0 0x11
|
||||||
|
#define INT_ZDMA1 0x12
|
||||||
|
#define INT_ZDMA0 0x13
|
||||||
|
#define INT_TICK 0x14
|
||||||
|
#define INT_EINT4567 0x15
|
||||||
|
#define INT_EINT3 0x16
|
||||||
|
#define INT_EINT2 0x17
|
||||||
|
#define INT_EINT1 0x18
|
||||||
|
#define INT_EINT0 0x19
|
||||||
|
|
||||||
|
#define INT_GLOBAL 26
|
||||||
|
|
||||||
|
struct rt_hw_register
|
||||||
|
{
|
||||||
|
unsigned long r0;
|
||||||
|
unsigned long r1;
|
||||||
|
unsigned long r2;
|
||||||
|
unsigned long r3;
|
||||||
|
unsigned long r4;
|
||||||
|
unsigned long r5;
|
||||||
|
unsigned long r6;
|
||||||
|
unsigned long r7;
|
||||||
|
unsigned long r8;
|
||||||
|
unsigned long r9;
|
||||||
|
unsigned long r10;
|
||||||
|
unsigned long fp;
|
||||||
|
unsigned long ip;
|
||||||
|
unsigned long sp;
|
||||||
|
unsigned long lr;
|
||||||
|
unsigned long pc;
|
||||||
|
unsigned long cpsr;
|
||||||
|
unsigned long ORIG_r0;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*@}*/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,118 @@
|
||||||
|
/*
|
||||||
|
* File : serial.c
|
||||||
|
* This file is part of RT-Thread RTOS
|
||||||
|
* COPYRIGHT (C) 2006, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* The license and distribution terms for this file may be
|
||||||
|
* found in the file LICENSE in this distribution or at
|
||||||
|
* http://openlab.rt-thread.com/license/LICENSE
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2006-09-06 XuXinming first version
|
||||||
|
* 2006-09-20 Bernard clean code according code style
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <rtthread.h>
|
||||||
|
#include <rthw.h>
|
||||||
|
|
||||||
|
#include "s3c44b0.h"
|
||||||
|
|
||||||
|
void rt_serial_init(void);
|
||||||
|
void rt_console_puts(const char* str);
|
||||||
|
void rt_serial_putc(const char c);
|
||||||
|
|
||||||
|
#define USTAT_RCV_READY 0x01 /* receive data ready */
|
||||||
|
#define USTAT_TXB_EMPTY 0x02 /* tx buffer empty */
|
||||||
|
|
||||||
|
rt_inline void serial_flush_input(void)
|
||||||
|
{
|
||||||
|
volatile unsigned int tmp;
|
||||||
|
|
||||||
|
/* keep on reading as long as the receiver is not empty */
|
||||||
|
while(UTRSTAT0 & USTAT_RCV_READY) tmp = URXH0;
|
||||||
|
}
|
||||||
|
|
||||||
|
rt_inline void serial_flush_output(void)
|
||||||
|
{
|
||||||
|
/* wait until the transmitter is no longer busy */
|
||||||
|
while(!(UTRSTAT0 & USTAT_TXB_EMPTY)) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @addtogroup S3C44B0
|
||||||
|
*/
|
||||||
|
/*@{*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function is used to display a string on console, normally, it's
|
||||||
|
* invoked by rt_kprintf
|
||||||
|
*
|
||||||
|
* @param str the displayed string
|
||||||
|
*/
|
||||||
|
void rt_console_puts(const char* str)
|
||||||
|
{
|
||||||
|
while (*str)
|
||||||
|
{
|
||||||
|
rt_serial_putc (*str++);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function initializes serial
|
||||||
|
*/
|
||||||
|
void rt_serial_init()
|
||||||
|
{
|
||||||
|
rt_uint32_t divisor = 0;
|
||||||
|
|
||||||
|
divisor = 0x20;
|
||||||
|
|
||||||
|
serial_flush_output();
|
||||||
|
serial_flush_input();
|
||||||
|
|
||||||
|
/* UART interrupt off */
|
||||||
|
UCON0 = 0;
|
||||||
|
/* FIFO disable */
|
||||||
|
UFCON0 =0x0;
|
||||||
|
UMCON0 =0x0;
|
||||||
|
/* set baudrate */
|
||||||
|
UBRDIV0 = divisor;
|
||||||
|
|
||||||
|
/* word length=8bit, stop bit = 1, no parity, use external clock */
|
||||||
|
ULCON0 = 0x03|0x00|0x00;
|
||||||
|
|
||||||
|
UCON0 = 0x5;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function read a character from serial without interrupt enable mode
|
||||||
|
*
|
||||||
|
* @return the read char
|
||||||
|
*/
|
||||||
|
char rt_serial_getc()
|
||||||
|
{
|
||||||
|
while ((UTRSTAT0 & USTAT_RCV_READY) == 0);
|
||||||
|
|
||||||
|
return URXH0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function will write a character to serial without interrupt enable mode
|
||||||
|
*
|
||||||
|
* @param c the char to write
|
||||||
|
*/
|
||||||
|
void rt_serial_putc(const char c)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
to be polite with serial console add a line feed
|
||||||
|
to the carriage return character
|
||||||
|
*/
|
||||||
|
if (c=='\n')rt_serial_putc('\r');
|
||||||
|
|
||||||
|
/* wait for room in the transmit FIFO */
|
||||||
|
while(!(UTRSTAT0 & USTAT_TXB_EMPTY));
|
||||||
|
|
||||||
|
UTXH0 = (rt_uint8_t)c;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*@}*/
|
|
@ -0,0 +1,60 @@
|
||||||
|
/*
|
||||||
|
* File : stack.c
|
||||||
|
* This file is part of RT-Thread RTOS
|
||||||
|
* COPYRIGHT (C) 2006, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* The license and distribution terms for this file may be
|
||||||
|
* found in the file LICENSE in this distribution or at
|
||||||
|
* http://openlab.rt-thread.com/license/LICENSE
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2006-09-06 XuXinming first version
|
||||||
|
*/
|
||||||
|
#include <rtthread.h>
|
||||||
|
#include "s3c44b0.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @addtogroup S3C44B0
|
||||||
|
*/
|
||||||
|
/*@{*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function will initialize thread stack
|
||||||
|
*
|
||||||
|
* @param tentry the entry of thread
|
||||||
|
* @param parameter the parameter of entry
|
||||||
|
* @param stack_addr the beginning stack address
|
||||||
|
* @param texit the function will be called when thread exit
|
||||||
|
*
|
||||||
|
* @return stack address
|
||||||
|
*/
|
||||||
|
rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter,
|
||||||
|
rt_uint8_t *stack_addr, void *texit)
|
||||||
|
{
|
||||||
|
unsigned long *stk;
|
||||||
|
|
||||||
|
stk = (unsigned long *)stack_addr;
|
||||||
|
*(stk) = (unsigned long)tentry; /* entry point */
|
||||||
|
*(--stk) = (unsigned long)texit; /* lr */
|
||||||
|
*(--stk) = 0; /* r12 */
|
||||||
|
*(--stk) = 0; /* r11 */
|
||||||
|
*(--stk) = 0; /* r10 */
|
||||||
|
*(--stk) = 0; /* r9 */
|
||||||
|
*(--stk) = 0; /* r8 */
|
||||||
|
*(--stk) = 0; /* r7 */
|
||||||
|
*(--stk) = 0; /* r6 */
|
||||||
|
*(--stk) = 0; /* r5 */
|
||||||
|
*(--stk) = 0; /* r4 */
|
||||||
|
*(--stk) = 0; /* r3 */
|
||||||
|
*(--stk) = 0; /* r2 */
|
||||||
|
*(--stk) = 0; /* r1 */
|
||||||
|
*(--stk) = (unsigned long)parameter; /* r0 : argument */
|
||||||
|
*(--stk) = SVCMODE; /* cpsr */
|
||||||
|
*(--stk) = SVCMODE; /* spsr */
|
||||||
|
|
||||||
|
/* return task's current stack address */
|
||||||
|
return (rt_uint8_t *)stk;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*@}*/
|
|
@ -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
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,181 @@
|
||||||
|
/*
|
||||||
|
* File : trap.c
|
||||||
|
* This file is part of RT-Thread RTOS
|
||||||
|
* COPYRIGHT (C) 2006, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* The license and distribution terms for this file may be
|
||||||
|
* found in the file LICENSE in this distribution or at
|
||||||
|
* http://openlab.rt-thread.com/license/LICENSE
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2006-09-06 XuXinming first version
|
||||||
|
* 2006-09-15 Bernard modify rt_hw_trap_irq for more effective
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <rtthread.h>
|
||||||
|
#include <rthw.h>
|
||||||
|
|
||||||
|
#include "s3c44b0.h"
|
||||||
|
|
||||||
|
extern unsigned char interrupt_bank0[256];
|
||||||
|
extern unsigned char interrupt_bank1[256];
|
||||||
|
extern unsigned char interrupt_bank2[256];
|
||||||
|
extern unsigned char interrupt_bank3[256];
|
||||||
|
|
||||||
|
extern struct rt_thread *rt_current_thread;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @addtogroup S3C44B0
|
||||||
|
*/
|
||||||
|
/*@{*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* this function will show registers of CPU
|
||||||
|
*
|
||||||
|
* @param regs the registers point
|
||||||
|
*/
|
||||||
|
void rt_hw_show_register (struct rt_hw_register *regs)
|
||||||
|
{
|
||||||
|
rt_kprintf("Execption:\n");
|
||||||
|
rt_kprintf("r00:0x%08x r01:0x%08x r02:0x%08x r03:0x%08x\n", regs->r0, regs->r1, regs->r2, regs->r3);
|
||||||
|
rt_kprintf("r04:0x%08x r05:0x%08x r06:0x%08x r07:0x%08x\n", regs->r4, regs->r5, regs->r6, regs->r7);
|
||||||
|
rt_kprintf("r08:0x%08x r09:0x%08x r10:0x%08x\n", regs->r8, regs->r9, regs->r10);
|
||||||
|
rt_kprintf("fp :0x%08x ip :0x%08x\n", regs->fp, regs->ip);
|
||||||
|
rt_kprintf("sp :0x%08x lr :0x%08x pc :0x%08x\n", regs->sp, regs->lr, regs->pc);
|
||||||
|
rt_kprintf("cpsr:0x%08x\n", regs->cpsr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When ARM7TDMI comes across an instruction which it cannot handle,
|
||||||
|
* it takes the undefined instruction trap.
|
||||||
|
*
|
||||||
|
* @param regs system registers
|
||||||
|
*
|
||||||
|
* @note never invoke this function in application
|
||||||
|
*/
|
||||||
|
void rt_hw_trap_udef(struct rt_hw_register *regs)
|
||||||
|
{
|
||||||
|
rt_hw_show_register(regs);
|
||||||
|
|
||||||
|
rt_kprintf("undefined instruction\n");
|
||||||
|
rt_hw_cpu_shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The software interrupt instruction (SWI) is used for entering
|
||||||
|
* Supervisor mode, usually to request a particular supervisor
|
||||||
|
* function.
|
||||||
|
*
|
||||||
|
* @param regs system registers
|
||||||
|
*
|
||||||
|
* @note never invoke this function in application
|
||||||
|
*/
|
||||||
|
void rt_hw_trap_swi(struct rt_hw_register *regs)
|
||||||
|
{
|
||||||
|
rt_kprintf("software interrupt\n");
|
||||||
|
rt_hw_show_register(regs);
|
||||||
|
rt_hw_cpu_shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An abort indicates that the current memory access cannot be completed,
|
||||||
|
* which occurs during an instruction prefetch.
|
||||||
|
*
|
||||||
|
* @param regs system registers
|
||||||
|
*
|
||||||
|
* @note never invoke this function in application
|
||||||
|
*/
|
||||||
|
void rt_hw_trap_pabt(struct rt_hw_register *regs)
|
||||||
|
{
|
||||||
|
rt_hw_show_register(regs);
|
||||||
|
|
||||||
|
rt_kprintf("prefetch abort\n");
|
||||||
|
rt_hw_cpu_shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An abort indicates that the current memory access cannot be completed,
|
||||||
|
* which occurs during a data access.
|
||||||
|
*
|
||||||
|
* @param regs system registers
|
||||||
|
*
|
||||||
|
* @note never invoke this function in application
|
||||||
|
*/
|
||||||
|
void rt_hw_trap_dabt(struct rt_hw_register *regs)
|
||||||
|
{
|
||||||
|
rt_hw_show_register(regs);
|
||||||
|
|
||||||
|
rt_kprintf("data abort\n");
|
||||||
|
rt_hw_cpu_shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Normally, system will never reach here
|
||||||
|
*
|
||||||
|
* @param regs system registers
|
||||||
|
*
|
||||||
|
* @note never invoke this function in application
|
||||||
|
*/
|
||||||
|
void rt_hw_trap_resv(struct rt_hw_register *regs)
|
||||||
|
{
|
||||||
|
rt_kprintf("not used\n");
|
||||||
|
rt_hw_show_register(regs);
|
||||||
|
rt_hw_cpu_shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
extern rt_isr_handler_t isr_table[];
|
||||||
|
void rt_hw_trap_irq()
|
||||||
|
{
|
||||||
|
register unsigned long ispr, intstat;
|
||||||
|
register rt_isr_handler_t isr_func;
|
||||||
|
|
||||||
|
#ifdef BSP_INT_DEBUG
|
||||||
|
rt_kprintf("irq coming, ");
|
||||||
|
#endif
|
||||||
|
intstat = I_ISPR & 0x7ffffff;
|
||||||
|
#ifdef BSP_INT_DEBUG
|
||||||
|
rt_kprintf("I_ISPR: %d\n", intstat);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ispr = intstat;
|
||||||
|
|
||||||
|
/* to find interrupt */
|
||||||
|
if ( intstat & 0xff ) /* lowest 8bits */
|
||||||
|
{
|
||||||
|
intstat = interrupt_bank0[intstat & 0xff];
|
||||||
|
isr_func = (rt_isr_handler_t)isr_table[ intstat ];
|
||||||
|
}
|
||||||
|
else if ( intstat & 0xff00 ) /* low 8bits */
|
||||||
|
{
|
||||||
|
intstat = interrupt_bank1[(intstat & 0xff00) >> 8];
|
||||||
|
isr_func = (rt_isr_handler_t)isr_table[ intstat ];
|
||||||
|
}
|
||||||
|
else if ( intstat & 0xff0000 ) /* high 8bits */
|
||||||
|
{
|
||||||
|
intstat = interrupt_bank2[(intstat & 0xff0000) >> 16];
|
||||||
|
isr_func = (rt_isr_handler_t)isr_table[ intstat ];
|
||||||
|
}
|
||||||
|
else if ( intstat & 0xff000000 ) /* highest 8bits */
|
||||||
|
{
|
||||||
|
intstat = interrupt_bank3[(intstat & 0xff000000) >> 24];
|
||||||
|
isr_func = (rt_isr_handler_t)isr_table[ intstat ];
|
||||||
|
}
|
||||||
|
else return;
|
||||||
|
|
||||||
|
#ifdef BSP_INT_DEBUG
|
||||||
|
rt_kprintf("irq: %d happen\n", intstat);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* turn to interrupt service routine */
|
||||||
|
isr_func(intstat);
|
||||||
|
|
||||||
|
I_ISPC = ispr; /* clear interrupt */
|
||||||
|
}
|
||||||
|
|
||||||
|
void rt_hw_trap_fiq()
|
||||||
|
{
|
||||||
|
rt_kprintf("fast interrupt request\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*@}*/
|
Loading…
Reference in New Issue