原始版本
This commit is contained in:
293
RT_Thread/libcpu/arm/AT91SAM7S/AT91SAM7S.h
Normal file
293
RT_Thread/libcpu/arm/AT91SAM7S/AT91SAM7S.h
Normal file
@ -0,0 +1,293 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* 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
|
||||
23
RT_Thread/libcpu/arm/AT91SAM7S/SConscript
Normal file
23
RT_Thread/libcpu/arm/AT91SAM7S/SConscript
Normal file
@ -0,0 +1,23 @@
|
||||
# RT-Thread building script for component
|
||||
|
||||
from building import *
|
||||
|
||||
Import('rtconfig')
|
||||
|
||||
cwd = GetCurrentDir()
|
||||
src = Glob('*.c') + Glob('*.cpp')
|
||||
CPPPATH = [cwd]
|
||||
|
||||
if rtconfig.PLATFORM in ['armcc', 'armclang']:
|
||||
src += Glob('*_rvds.S')
|
||||
|
||||
if rtconfig.PLATFORM in ['gcc']:
|
||||
src += Glob('*_init.S')
|
||||
src += Glob('*_gcc.S')
|
||||
|
||||
if rtconfig.PLATFORM in ['iccarm']:
|
||||
src += Glob('*_iar.S')
|
||||
|
||||
group = DefineGroup('libcpu', src, depend = [''], CPPPATH = CPPPATH)
|
||||
|
||||
Return('group')
|
||||
90
RT_Thread/libcpu/arm/AT91SAM7S/context_gcc.S
Normal file
90
RT_Thread/libcpu/arm/AT91SAM7S/context_gcc.S
Normal file
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2022, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* 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_interrupt_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_interrupt_flag
|
||||
ldr r3, [r2]
|
||||
cmp r3, #1
|
||||
beq _reswitch
|
||||
mov r3, #1 /* set rt_thread_switch_interrupt_flag to 1 */
|
||||
str r3, [r2]
|
||||
ldr r2, =rt_interrupt_from_thread /* set rt_interrupt_from_thread */
|
||||
str r0, [r2]
|
||||
_reswitch:
|
||||
ldr r2, =rt_interrupt_to_thread /* set rt_interrupt_to_thread */
|
||||
str r1, [r2]
|
||||
mov pc, lr
|
||||
103
RT_Thread/libcpu/arm/AT91SAM7S/context_rvds.S
Normal file
103
RT_Thread/libcpu/arm/AT91SAM7S/context_rvds.S
Normal file
@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2022, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2009-01-20 Bernard first version
|
||||
*/
|
||||
|
||||
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_interrupt_flag
|
||||
IMPORT rt_interrupt_from_thread
|
||||
IMPORT rt_interrupt_to_thread
|
||||
|
||||
rt_hw_context_switch_interrupt PROC
|
||||
EXPORT rt_hw_context_switch_interrupt
|
||||
LDR r2, =rt_thread_switch_interrupt_flag
|
||||
LDR r3, [r2]
|
||||
CMP r3, #1
|
||||
BEQ _reswitch
|
||||
MOV r3, #1 ; set rt_thread_switch_interrupt_flag to 1
|
||||
STR r3, [r2]
|
||||
LDR r2, =rt_interrupt_from_thread ; set rt_interrupt_from_thread
|
||||
STR r0, [r2]
|
||||
_reswitch
|
||||
LDR r2, =rt_interrupt_to_thread ; set rt_interrupt_to_thread
|
||||
STR r1, [r2]
|
||||
BX lr
|
||||
ENDP
|
||||
|
||||
END
|
||||
19
RT_Thread/libcpu/arm/AT91SAM7S/cpu.c
Normal file
19
RT_Thread/libcpu/arm/AT91SAM7S/cpu.c
Normal file
@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2006-08-23 Bernard first version
|
||||
*/
|
||||
|
||||
#include <rtthread.h>
|
||||
#include "AT91SAM7S.h"
|
||||
|
||||
/**
|
||||
* @addtogroup AT91SAM7
|
||||
*/
|
||||
/*@{*/
|
||||
|
||||
/*@}*/
|
||||
87
RT_Thread/libcpu/arm/AT91SAM7S/interrupt.c
Normal file
87
RT_Thread/libcpu/arm/AT91SAM7S/interrupt.c
Normal file
@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2006-08-23 Bernard first version
|
||||
*/
|
||||
|
||||
#include <rtthread.h>
|
||||
#include "AT91SAM7S.h"
|
||||
|
||||
#define MAX_HANDLERS 32
|
||||
|
||||
extern rt_atomic_t rt_interrupt_nest;
|
||||
|
||||
rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread;
|
||||
rt_uint32_t rt_thread_switch_interrupt_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_interrupt_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;
|
||||
}
|
||||
}
|
||||
|
||||
/*@}*/
|
||||
383
RT_Thread/libcpu/arm/AT91SAM7S/serial.c
Normal file
383
RT_Thread/libcpu/arm/AT91SAM7S/serial.c
Normal file
@ -0,0 +1,383 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* 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_ssize_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_ssize_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, int 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;
|
||||
}
|
||||
|
||||
/*@}*/
|
||||
64
RT_Thread/libcpu/arm/AT91SAM7S/serial.h
Normal file
64
RT_Thread/libcpu/arm/AT91SAM7S/serial.h
Normal file
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
*/
|
||||
#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
|
||||
59
RT_Thread/libcpu/arm/AT91SAM7S/stack.c
Normal file
59
RT_Thread/libcpu/arm/AT91SAM7S/stack.c
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* 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)
|
||||
{
|
||||
rt_uint32_t *stk;
|
||||
|
||||
stack_addr += sizeof(rt_uint32_t);
|
||||
stack_addr = (rt_uint8_t *)RT_ALIGN_DOWN((rt_uint32_t)stack_addr, 8);
|
||||
stk = (rt_uint32_t *)stack_addr;
|
||||
|
||||
*(--stk) = (rt_uint32_t)tentry; /* entry point */
|
||||
*(--stk) = (rt_uint32_t)texit; /* lr */
|
||||
*(--stk) = 0xdeadbeef; /* r12 */
|
||||
*(--stk) = 0xdeadbeef; /* r11 */
|
||||
*(--stk) = 0xdeadbeef; /* r10 */
|
||||
*(--stk) = 0xdeadbeef; /* r9 */
|
||||
*(--stk) = 0xdeadbeef; /* r8 */
|
||||
*(--stk) = 0xdeadbeef; /* r7 */
|
||||
*(--stk) = 0xdeadbeef; /* r6 */
|
||||
*(--stk) = 0xdeadbeef; /* r5 */
|
||||
*(--stk) = 0xdeadbeef; /* r4 */
|
||||
*(--stk) = 0xdeadbeef; /* r3 */
|
||||
*(--stk) = 0xdeadbeef; /* r2 */
|
||||
*(--stk) = 0xdeadbeef; /* r1 */
|
||||
*(--stk) = (rt_uint32_t)parameter; /* r0 : argument */
|
||||
*(--stk) = SVCMODE; /* cpsr */
|
||||
*(--stk) = SVCMODE; /* spsr */
|
||||
|
||||
/* return task's current stack address */
|
||||
return (rt_uint8_t *)stk;
|
||||
}
|
||||
|
||||
/*@}*/
|
||||
233
RT_Thread/libcpu/arm/AT91SAM7S/start_gcc.S
Normal file
233
RT_Thread/libcpu/arm/AT91SAM7S/start_gcc.S
Normal file
@ -0,0 +1,233 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2022, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* 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_interrupt_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_interrupt_flag set, jump to
|
||||
* rt_hw_context_switch_interrupt_do and don't return
|
||||
*/
|
||||
ldr r0, =rt_thread_switch_interrupt_flag
|
||||
ldr r1, [r0]
|
||||
cmp r1, #1
|
||||
beq rt_hw_context_switch_interrupt_do
|
||||
|
||||
ldmfd sp!, {r0-r12,lr}
|
||||
subs pc, lr, #4
|
||||
|
||||
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 */
|
||||
499
RT_Thread/libcpu/arm/AT91SAM7S/start_rvds.S
Normal file
499
RT_Thread/libcpu/arm/AT91SAM7S/start_rvds.S
Normal file
@ -0,0 +1,499 @@
|
||||
;/*****************************************************************************/
|
||||
;/* 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
|
||||
|
||||
; No usr mode stack here.
|
||||
;MOV SP, R0
|
||||
;SUB SL, SP, #USR_Stack_Size
|
||||
|
||||
ENDIF
|
||||
|
||||
|
||||
; Enter the C code
|
||||
|
||||
IMPORT __main
|
||||
LDR R0, =__main
|
||||
BX R0
|
||||
|
||||
IMPORT rt_interrupt_enter
|
||||
IMPORT rt_interrupt_leave
|
||||
IMPORT rt_thread_switch_interrupt_flag
|
||||
IMPORT rt_interrupt_from_thread
|
||||
IMPORT rt_interrupt_to_thread
|
||||
IMPORT rt_hw_trap_irq
|
||||
|
||||
IRQ_Handler PROC
|
||||
EXPORT IRQ_Handler
|
||||
STMFD sp!, {r0-r12,lr}
|
||||
BL rt_interrupt_enter
|
||||
BL rt_hw_trap_irq
|
||||
BL rt_interrupt_leave
|
||||
|
||||
; if rt_thread_switch_interrupt_flag set, jump to
|
||||
; rt_hw_context_switch_interrupt_do and don't return
|
||||
LDR r0, =rt_thread_switch_interrupt_flag
|
||||
LDR r1, [r0]
|
||||
CMP r1, #1
|
||||
BEQ rt_hw_context_switch_interrupt_do
|
||||
|
||||
LDMFD sp!, {r0-r12,lr}
|
||||
SUBS pc, lr, #4
|
||||
ENDP
|
||||
|
||||
; /*
|
||||
; * 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 + IRQ_Stack_Size)
|
||||
LDR R2, = (Heap_Mem + Heap_Size)
|
||||
LDR R3, = Stack_Mem
|
||||
BX LR
|
||||
ENDIF
|
||||
|
||||
END
|
||||
36
RT_Thread/libcpu/arm/AT91SAM7S/trap.c
Normal file
36
RT_Thread/libcpu/arm/AT91SAM7S/trap.c
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* 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");
|
||||
}
|
||||
|
||||
/*@}*/
|
||||
Reference in New Issue
Block a user