Index: hal/arm/at91/var/current/ChangeLog =================================================================== RCS file: /cvs/ecos/ecos/packages/hal/arm/at91/var/current/ChangeLog,v retrieving revision 1.28 diff -u -r1.28 ChangeLog --- hal/arm/at91/var/current/ChangeLog 12 Jun 2005 13:34:21 -0000 1.28 +++ hal/arm/at91/var/current/ChangeLog 19 Feb 2006 18:31:59 -0000 @@ -1,3 +1,21 @@ +2006-02-19 Andrew Lunn + Oliver Munz + + * cdl/hal_arm_at9a.cdl: Add the AT91SAM7S variant and control + for new timer and debug usart code. + * include/var_io.h: Register definitions for AT91SAM7S + * include/var_arch.h: Idle action for AT91SAM7S + * src/at91_misc.c (hal_hardware_init): Call HAL_PLF_HARDWARE_INIT + for any platform specific initialization + * src/at91_misc.c (hal_at91_reset_cpu): Use the reset controller + if it exists. + * src/at91_misc.c (hal_IRQ_handler): Decode interrupts from + the system controller if it exists. + * src/timer_tc.c (NEW) eCos timer using the Timer Counter + * src/timer_pit.c (NEW) eCos timer using Periodic Interval Timer + * src/hal_diag_dbg.c (NEW) Debug output via debug UART. + * src/hal_diag.h: Indicate hal_at91_reset_cpu() is a C function + otherwise we have problems with the watchdog driver which is C++. 2005-05-30 Ezequiel Conde Index: hal/arm/at91/var/current/cdl/hal_arm_at91.cdl =================================================================== RCS file: /cvs/ecos/ecos/packages/hal/arm/at91/var/current/cdl/hal_arm_at91.cdl,v retrieving revision 1.9 diff -u -r1.9 hal_arm_at91.cdl --- hal/arm/at91/var/current/cdl/hal_arm_at91.cdl 25 Sep 2004 09:44:10 -0000 1.9 +++ hal/arm/at91/var/current/cdl/hal_arm_at91.cdl 19 Feb 2006 18:31:59 -0000 @@ -59,7 +59,7 @@ The AT91 HAL package provides the support needed to run eCos on Atmel AT91 based targets." - compile hal_diag.c at91_misc.c + compile at91_misc.c implements CYGINT_HAL_DEBUG_GDB_STUBS implements CYGINT_HAL_DEBUG_GDB_STUBS_BREAK @@ -78,7 +78,8 @@ display "AT91 variant used" flavor data default_value {"R40807"} - legal_values {"R40807" "R40008" "M42800A" "M55800A" "JTST"} + legal_values {"R40807" "R40008" "M42800A" "M55800A" "JTST" + "AT91SAM7S" } description "The AT91 microcontroller family has several variants, the main differences being the amount of on-chip SRAM, peripherals and their layout. This option allows the @@ -95,4 +96,77 @@ normal way, i.e. a FIQ interrupt will be treated as a normal IRQ using the highest priority" } + + cdl_interface CYGINT_HAL_ARM_AT91_SYS_INTERRUPT { + display "AT91 core has multiplexed system interrupts" + description " + Some AT91 cores have a system controller which multiplexes + many interrupts onto the system interrupt. When this interface + is enabled the variant hal will perform a second level + expansion of these interrupts" + } + + cdl_interface CYGINT_HAL_ARM_AT91_PIT_HW { + display "Platform has a Periodic Interval Timer" + description " + This interface if implemented by HALs for CPU cores which + have the Periodic Interval Timer." + } + + cdl_option CYGBLD_HAL_ARM_AT91_TIMER_TC { + display "Use Timer Counter for eCos Clock" + flavor bool + default_value 1 + requires !CYGBLD_HAL_ARM_AT91_TIMER_PIT + compile timer_tc.c + description " + Use a Timer Counter Channel to generate the eCos Clock." + } + + cdl_option CYGBLD_HAL_ARM_AT91_TIMER_PIT { + display "Use Periodic Interval Timer for eCos Clock" + flavor bool + default_value !CYGBLD_HAL_ARM_AT91_TIMER_TC + requires !CYGBLD_HAL_ARM_AT91_TIMER_TC + active_if CYGINT_HAL_ARM_AT91_PIT_HW + compile timer_pit.c + description " + Use Periodic Interval Timer to generate the eCos Clock." + } + + cdl_interface CYGINT_HAL_ARM_AT91_SERIAL_DBG_HW { + display "Platform has the DBG serial port" + description " + Some varients of the AT91 have a dedicated debug serial + port. The HALs of such a varient should implement this interface + so allowing the serial driver to the compiled" + } + + cdl_option CYGBLD_HAL_ARM_AT91_SERIAL_DBG { + display "Enable the use of the DBG serial port" + flavor bool + active_if CYGINT_HAL_ARM_AT91_SERIAL_DBG_HW + active_if !CYGBLD_HAL_ARM_AT91_SERIAL_UART + requires CYGINT_HAL_ARM_AT91_SYS_INTERRUPT + default_value 1 + + compile hal_diag_dbg.c + requires CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL == 0 + requires CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL == 0 + + description " + The driver for the dedicated DBG UART will be compiled in the + varient HAL when this option is enabled." + } + + cdl_option CYGBLD_HAL_ARM_AT91_SERIAL_UART { + display "Enable the use of the UARTS for debug output" + flavor bool + default_value 1 + compile hal_diag.c + requires !CYGBLD_HAL_ARM_AT91_SERIAL_DBG + description " + The driver for using the UARTS will be compiled in the + varient HAL when this option is enabled." + } } Index: hal/arm/at91/var/current/include/hal_diag.h =================================================================== RCS file: /cvs/ecos/ecos/packages/hal/arm/at91/var/current/include/hal_diag.h,v retrieving revision 1.4 diff -u -r1.4 hal_diag.h --- hal/arm/at91/var/current/include/hal_diag.h 20 Feb 2004 18:36:43 -0000 1.4 +++ hal/arm/at91/var/current/include/hal_diag.h 19 Feb 2006 18:31:59 -0000 @@ -79,7 +79,7 @@ //----------------------------------------------------------------------------- // reset -extern void hal_at91_reset_cpu(void); +externC void hal_at91_reset_cpu(void); //----------------------------------------------------------------------------- // end of hal_diag.h Index: hal/arm/at91/var/current/include/var_arch.h =================================================================== RCS file: /cvs/ecos/ecos/packages/hal/arm/at91/var/current/include/var_arch.h,v retrieving revision 1.2 diff -u -r1.2 var_arch.h --- hal/arm/at91/var/current/include/var_arch.h 25 Sep 2004 09:44:10 -0000 1.2 +++ hal/arm/at91/var/current/include/var_arch.h 19 Feb 2006 18:31:59 -0000 @@ -74,7 +74,8 @@ CYG_MACRO_END #elif defined(CYGHWR_HAL_ARM_AT91_M42800A) || \ - defined(CYGHWR_HAL_ARM_AT91_M55800A) + defined(CYGHWR_HAL_ARM_AT91_M55800A) || \ + defined(CYGHWR_HAL_ARM_AT91SAM7S) #define HAL_IDLE_THREAD_ACTION(_count_) \ CYG_MACRO_START \ Index: hal/arm/at91/var/current/include/var_io.h =================================================================== RCS file: /cvs/ecos/ecos/packages/hal/arm/at91/var/current/include/var_io.h,v retrieving revision 1.12 diff -u -r1.12 var_io.h --- hal/arm/at91/var/current/include/var_io.h 12 Nov 2004 09:45:16 -0000 1.12 +++ hal/arm/at91/var/current/include/var_io.h 19 Feb 2006 18:32:01 -0000 @@ -12,6 +12,7 @@ // This file is part of eCos, the Embedded Configurable Operating System. // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. // Copyright (C) 2003 Nick Garnett +// Copyright (C) 2005, 2006 Andrew Lunn (andrew.lunn@ascom.ch> // // eCos 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 @@ -35,16 +36,13 @@ // // This exception does not invalidate any other reasons why a work based on // this file might be covered by the GNU General Public License. -// -// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. -// at http://sources.redhat.com/ecos/ecos-license/ // ------------------------------------------- //####ECOSGPLCOPYRIGHTEND#### //============================================================================= //#####DESCRIPTIONBEGIN#### // // Author(s): jskov -// Contributors:jskov, gthomas, tkoeller, tdrury, nickg +// Contributors:jskov, gthomas, tkoeller, tdrury, nickg, asl // Date: 2001-07-12 // Purpose: AT91 variant specific registers // Description: @@ -217,6 +215,81 @@ #define AT91_PIO_PSR_TIOA2 0x04000000 // Timer 2 Signal A #define AT91_PIO_PSR_TIOB2 0x08000000 // Timer 2 Signal B +#elif defined (CYGHWR_HAL_ARM_AT91SAM7S) +#include + +// PIOA +#define AT91_PIO_PSR_PWM0 0x00000001 // Pulse Width Modulation 0 +#define AT91_PIO_PSR_PWM1 0x00000002 // Pulse Width Modulation 1 +#define AT91_PIO_PSR_PWM2 0x00000004 // Pulse Width Modulation 2 +#define AT91_PIO_PSR_TWD 0x00000008 // Two Wire Data +#define AT91_PIO_PSR_TWCK 0x00000010 // Two Wire Clock +#define AT91_PIO_PSR_RXD0 0x00000020 // USART 0 Receive Data +#define AT91_PIO_PSR_TXD0 0x00000040 // USART 0 Transmit Data +#define AT91_PIO_PSR_RTS0 0x00000080 // USART 0 Ready To Send +#define AT91_PIO_PSR_CTS0 0x00000100 // USART 0 Clear To Send +#define AT91_PIO_PSR_DRXD 0x00000200 // Debug UART Receive +#define AT91_PIO_PSR_DTXD 0x00000400 // Debug UAET Transmit +#define AT91_PIO_PSR_NPCS0 0x00000800 // SPI Chip Select 0 +#define AT91_PIO_PSR_MISO 0x00001000 // SPI Input +#define AT91_PIO_PSR_MOIS 0x00002000 // SPI Output +#define AT91_PIO_PSR_SPCK 0x00004000 // SPI clock +#define AT91_PIO_PSR_TF 0x00008000 // Transmit Frame Sync +#define AT91_PIO_PSR_TK 0x00010000 // Transmit Clock +#define AT91_PIO_PSR_TD 0x00020000 // Transmit Data +#define AT91_PIO_PSR_RD 0x00040000 // Receive Data +#define AT91_PIO_PSR_RK 0x00080000 // Receive Clock +#define AT91_PIO_PSR_RF 0x00100000 // Receive Frame Sync +#if !defined(CYGHWR_HAL_ARM_AT91SAM7S_at91sam7s32) +#define AT91_PIO_PSR_RXD1 0x00200000 // USART 1 Receive Data +#define AT91_PIO_PSR_TXD1 0x00400000 // USART 1 Transmit Data +#define AT91_PIO_PSR_SCK1 0x00800000 // USART 1 Serial Clock +#define AT91_PIO_PSR_RTS1 0x01000000 // USART 1 Ready To Send +#define AT91_PIO_PSR_CTS1 0x02000000 // USART 1 Clear To Send +#define AT91_PIO_PSR_DCD1 0x04000000 // USART 1 Data Carrier Detect +#define AT91_PIO_PSR_DTR1 0x08000000 // USART 1 Data Terminal Ready +#define AT91_PIO_PSR_DSR1 0x10000000 // USART 1 Data Set Ready +#define AT91_PIO_PSR_RI1 0x20000000 // USART 2 Ring Indicator +#define AT91_PIO_PSR_IRQ1 0x40000000 // Interrupt Request 1 +#define AT01_PIO_PSR_NPCS1 x800000000 // SPI Chip Select 1 +#endif // !defined(CYGHWR_HAL_ARM_AT91SAM7S_at91sam7s64) + +// PIOB +#define AT91_PIO_PSR_TIOA0 0x00000001 // Timer/Counter 0 IO Line A +#define AT91_PIO_PSR_TIOB0 0x00000002 // Timer/Counter 0 IO Line B +#define AT91_PIO_PSR_SCK0 0x00000004 // USART 0 Serial Clock +#define AT91_PIO_PSR_NPCS3 0x00000008 // SPI Chip Select 3 +#define AT91_PIO_PSR_TCLK0 0x00000010 // Timer/Counter 0 Clock Input +#define AT91_PIO_PSR_NPCS3X 0x00000020 // SPI Chip Select 3 (again) +#define AT91_PIO_PSR_PCK0 0x00000040 // Programmable Clock Output 0 +#define AT91_PIO_PSR_PWM3 0x00000080 // Pulse Width Modulation #3 +#define AT91_PIO_PSR_ADTRG 0x00000100 // ADC Trigger +#define AT91_PIO_PSR_NPCS1 0x00000200 // SPI Chip Select 1 +#define AT91_PIO_PSR_NPCS2 0x00000400 // SPI Chip Select 2 +#define AT91_PIO_PSR_PWMOX 0x00000800 // Pulse Width Modulation #0 (again) +#define AT91_PIO_PSR_PWM1X 0x00001000 // Pulse Width Modulation #1 (again) +#define AT91_PIO_PSR_PWM2X 0x00002000 // Pulse Width Modulation #2 (again) +#define AT91_PIO_PSR_PWM3X 0x00004000 // Pulse Width Modulation #4 (again) +#define AT91_PIO_PSR_TIOA1 0x00008000 // Timer/Counter 1 IO Line A +#define AT91_PIO_PSR_TIOB1 0x00010000 // Timer/Counter 1 IO Line B +#define AT91_PIO_PSR_PCK1 0x00020000 // Programmable Clock Output 1 +#define AT91_PIO_PSR_PCK2 0x00040000 // Programmable Clock Output 2 +#define AT91_PIO_PSR_FIQ 0x00080000 // Fast Interrupt Request +#define AT91_PIO_PSR_IRQ0 0x00100000 // Interrupt Request 0 +#if !defined(CYGHWR_HAL_ARM_AT91SAM7S_at91sam7s32) +#define AT91_PIO_PSR_PCK1X 0x00200000 // Programmable Clock Output 1(again) +#define AT91_PIO_PSR_NPCS3XX 0x00400000 // SPI Chip Select 3 (yet again) +#define AT91_PIO_PSR_PWMOXX 0x00800000 // Pulse Width Modulation #0 (again) +#define AT91_PIO_PSR_PWM1XX 0x01000000 // Pulse Width Modulation #1 (again) +#define AT91_PIO_PSR_PWM2XX 0x02000000 // Pulse Width Modulation #2 (again) +#define AT91_PIO_PSR_TIOA2 0x04000000 // Timer/Counter 2 IO Line A +#define AT91_PIO_PSR_TIOB2 0x08000000 // Timer/Counter 2 IO Line B +#define AT91_PIO_PSR_TCLK1 0x10000000 // External Clock Input 1 +#define AT91_PIO_PSR_TCLK2 0x20000000 // External Clock Input 2 +#define AT91_PIO_PSR_NPCS2X 0x40000000 // SPI Chip Select 2 (again) +#define AT91_PIO_PSR_PCK2X 0x80000000 // Programmable Clock Output 2(again) +#endif // !defined(CYGHWR_HAL_ARM_AT91SAM7S_at91sam7s64) + #else #define AT91_PIO_PSR_TCLK0 0x00000001 // Timer #0 clock @@ -269,6 +342,20 @@ #define AT91_PIO_IMR 0x48 // Interrupt mask #define AT91_PIO_ISR 0x4C // Interrupt status +#ifdef CYGHWR_HAL_ARM_AT91SAM7S +#define AT91_PIO_MDER 0x50 // Multi-drive Enable Register +#define AT91_PIO_MDDR 0x54 // Multi-drive Disable Register +#define AT91_PIO_MDSR 0x58 // Multi-drive Status Register +#define AT91_PIO_PPUDR 0x60 // Pad Pull-up Disable Register +#define AT91_PIO_PPUER 0x64 // Pad Pull-up Enable Register +#define AT91_PIO_PPUSR 0x68 // Pad Pull-Up Status Register +#define AT91_PIO_ASR 0x70 // Select A Register +#define AT91_PIO_BSR 0x74 // Select B Regsiter +#define AT91_PIO_ABS 0x78 // AB Select Regsiter +#define AT91_PIO_OWER 0xa0 // Output Write Enable Register +#define AT91_PIO_OWDR 0xa4 // Output Write Disable Register +#define AT91_PIO_OWSR 0xa8 // Output Write Status Register +#endif // CYGHWR_HAL_ARM_AT91SAM7S //============================================================================= // Advanced Interrupt Controller (AIC) @@ -358,6 +445,13 @@ #define AT91_AIC_EOI 0x130 #define AT91_AIC_SVR 0x134 +#ifdef CYGHWR_HAL_ARM_AT91SAM7S +#define AT91_AIC_DCR 0x138 // Debug Control Register +#define AT91_AIC_FFER 0x140 // Fast Forcing Enable Register +#define AT91_AIC_FFDR 0x144 // Fast Forcing Enable Register +#define AT91_AIC_FFSR 0x148 // Fast Forcing Enable Register +#endif + //============================================================================= // Timer / counter @@ -535,7 +629,6 @@ #define AT91_EBI_MCR_ALE_1M 0x7 // Address line enable #define AT91_EBI_MCR_DRP (0x1 << 4) // Data read protocol - //============================================================================= // Power Saving or Management @@ -555,7 +648,8 @@ #define AT91_PS_PCSR 0x00c // Peripheral clock status #elif defined(CYGHWR_HAL_ARM_AT91_M42800A) || \ - defined(CYGHWR_HAL_ARM_AT91_M55800A) + defined(CYGHWR_HAL_ARM_AT91_M55800A) || \ + defined(CYGHWR_HAL_ARM_AT91SAM7S) // (Advanced) Power Management @@ -572,11 +666,22 @@ #define AT91_PMC_PCSR 0x18 #define AT91_PMC_CGMR 0x20 - + +#ifndef AT91_PMC_SR #define AT91_PMC_SR 0x30 +#endif + +#ifndef AT91_PMC_IER #define AT91_PMC_IER 0x34 +#endif + +#ifndef AT91_PMC_IDR #define AT91_PMC_IDR 0x38 +#endif + +#ifndef AT91_PMC_IMR #define AT91_PMC_IMR 0x3c +#endif #if defined(CYGHWR_HAL_ARM_AT91_M42800A) @@ -683,16 +788,35 @@ #define AT91_PMC_SR_MOSCS 0x01 #define AT91_PMC_SR_LOCK 0x02 -#endif - #elif defined(CYGHWR_HAL_ARM_AT91_JTST) -// Now power management control for the JTST +// No power management control for the JTST + +#elif defined(CYGHWR_HAL_ARM_AT91SAM7S) +#define AT91_PMC_SCER_PCK (1 << 0) // Processor Clock +#define AT91_PMC_SCER_UDP (1 << 7) // USB Device Clock +#define AT91_PMC_SCER_PCK0 (1 << 8) // Programmable Clock Output +#define AT91_PMC_SCER_PCK1 (1 << 9) // Programmable Clock Output +#define AT91_PMC_SCER_PCK2 (1 << 10) // Programmable Clock Output +#define AT91_PMC_SCER_PCK3 (1 << 11) // Programmable Clock Output + +#define AT91_PMC_PCER_PIOA (1 << 2) // Parallel IO Controller +#define AT91_PMC_PCER_ADC (1 << 4) // Analog-to-Digital Conveter +#define AT91_PMC_PCER_SPI (1 << 5) // Serial Peripheral Interface +#define AT91_PMC_PCER_US0 (1 << 6) // USART 0 +#define AT91_PMC_PCER_US1 (1 << 7) // USART 1 +#define AT91_PMC_PCER_SSC (1 << 8) // Serial Synchronous Controller +#define AT91_PMC_PCER_TWI (1 << 9) // Two-Wire Interface +#define AT91_PMC_PCER_PWMC (1 <<10) // PWM Controller +#define AT91_PMC_PCER_UDP (1 <<11) // USB Device Port +#define AT91_PMC_PCER_TC0 (1 <<12) // Timer Counter 0 +#define AT91_PMC_PCER_TC1 (1 <<13) // Timer Counter 1 +#define AT91_PMC_PCER_TC2 (1 <<14) // Timer Counter 2 #else #error Unknown AT91 variant -#endif - +#endif +#endif //============================================================================= // Watchdog @@ -788,6 +912,272 @@ #define AT91_SPI_PIO_NPCS(x) (((x)&0x0F)<<26) #endif +#if defined(CYGHWR_HAL_ARM_AT91SAM7S) + +#define AT91_SPI_PIO AT91_PIOA +#define AT91_SPI_PIO_NPCS(x) \ + ( (x & (1 << 0) ? AT91_PIO_PSR_NPCS0 : 0) | \ + (x & (1 << 1) ? AT91_PIO_PSR_NPCS1 : 0) | \ + (x & (1 << 2) ? AT91_PIO_PSR_NPCS2 : 0) | \ + (x & (1 << 3) ? AT91_PIO_PSR_NPCS3 : 0)) +#endif + +//============================================================================= +// Watchdog Timer Controller + +#if defined(CYGHWR_HAL_ARM_AT91SAM7S) + +#ifndef AT91_WDTC +#define AT91_WDTC 0xFFFFFD40 +#endif + +#define AT91_WDTC_WDCR 0x00 // Watchdog Control Register +#define AT91_WDTC_WDCR_RELOAD (1 << 0) // Reload the watchdog +#define AT91_WDTC_WDCR_KEY (0xa5 << 24) // Password for the write op +#define AT91_WDTC_WDMR 0x04 // Watchdog Mode Register +#define AT91_WDTC_WDMR_FIEN (1 << 12) // Fault Interrupt Mode Enable +#define AT91_WDTC_WDMR_RSTEN (1 << 13) // Reset Enable +#define AT91_WDTC_WDMR_RPROC (1 << 14) // Trigger a processor reset +#define AT91_WDTC_WDMR_DIS (1 << 15) // Disable +#define AT91_WDTC_WDMR_WDD_SHIFT (16) // Delta Value shift +#define AT91_WDTC_WDMR_DBGHLT (1 << 28) // Stop when in debug state +#define AT91_WDTC_WDMR_IDLEHLT (1 << 29) // Stop when in idle more +#define AT91_WDTC_WDSR 0x08 // Watchdog Status Register +#define AT91_WDTC_WDSR_UNDER (1 << 0) // Underflow has occurred +#define AT91_WDTC_WDSR_ERROR (1 << 1) // Error has occurred +#endif //CYGHWR_HAL_ARM_AT91SAM7S + +//============================================================================= +// Reset Controller + +#if defined(CYGHWR_HAL_ARM_AT91SAM7S) + +#ifndef AT91_RST +#define AT91_RST 0xFFFFFD00 +#endif + +#define AT91_RST_RCR 0x00 // Reset Control Register +#define AT91_RST_RCR_PROCRST (1 << 0) // Processor Reset +#define AT91_RST_RCR_ICERST (1 << 1) // ICE Reset +#define AT91_RST_RCR_PERRST (1 << 2) // Peripheral Reset +#define AT91_RST_RCR_EXTRST (1 << 3) // External Reset +#define AT91_RST_RCR_KEY (0xA5 << 24) // Key +#define AT91_RST_RSR 0x04 // Reset Status Register +#define AT91_RST_RSR_USER (1 << 0) // User Reset +#define AT91_RST_RSR_BROWN (1 << 1) // Brownout detected +#define AT91_RST_RSR_TYPE_POWERUP (0 << 8) // Power on Reset +#define AT91_RST_RSR_TYPE_WATCHDOG (2 << 8) // Watchdog Reset +#define AT91_RST_RSR_TYPE_SW (3 << 8) // Software Reset +#define AT91_RST_RSR_TYPE_USER (4 << 8) // NRST pin Reset +#define AT91_RST_RSR_TYPE_BROWNOUT (5 << 8) // Brown-out Reset +#define AT91_RST_RSR_NRST_SET (1 << 16) // NRST pin set +#define AT91_RST_RSR_SRCMP (1 << 17) // Software reset in progress +#define AT91_RST_RMR 0x08 // Reset Mode Register +#define AT91_RST_RMR_URSTEN (1 << 0) // User Reset Enabled +#define AT91_RST_RMR_URSTIEN (1 << 4) // User Reset Interrupt Enabled +#define AT91_RST_RMR_BODIEN (1 << 16) // Brownout Dection Interrupt Enabled +#define AT91_RST_RMR_KEY (0xA5 << 24) // Key + +#endif + +//============================================================================= +// Memory Controller + +#if defined(CYGHWR_HAL_ARM_AT91SAM7S) + +#ifndef AT91_MC +#define AT91_MC 0xFFFFFF00 +#endif + +#define AT91_MC_RCR 0x00 // Remap Control Register +#define AT91_MC_ASR 0x04 // Abort Status Register +#define AT91_MC_AASR 0x08 // Abort Address Status Register +#define AT91_MC_FMR 0x60 // Flash Mode Register +#define AT91_MC_FMR_FRDY (1 << 0) // Enable interrupt for Flash Ready +#define AT91_MC_FMR_LOCKE (1 << 2) // Enable interrupt for Flash Lock Error +#define AT91_MC_FMR_PROGE (1 << 3) // Enable interrupt for Flash Prog Error +#define AT91_MC_FMR_NEBP (1 << 7) // No erase before programming +#define AT91_MC_FMR_0FWS (0 << 8) // 1R,2W wait states +#define AT91_MC_FMR_1FWS (1 << 8) // 2R,3W wait states +#define AT91_MC_FMR_2FWS (2 << 8) // 3R,4W wait states +#define AT91_MC_FMR_3FWS (3 << 8) // 4R,4W wait states +#define AT91_MC_FMR_FMCN_MASK (0xff << 16) +#define AT91_MC_FMR_FMCN_SHIFT 16 +#define AT91_MC_FCR 0x64 // Flash Command Register +#define AT91_MC_FCR_START_PROG (0x1 << 0) // Start Programming of Page +#define AT91_MC_FCR_LOCK (0x2 << 0) // Lock sector +#define AT91_MC_FCR_PROG_LOCK (0x3 << 0) // Program and Lock +#define AT91_MC_FCR_UNLOCK (0x4 << 0) // Unlock a segment +#define AT91_MC_FCR_ERASE_ALL (0x8 << 0) // Erase everything +#define AT91_MC_FCR_SET_GP_NVM (0xb << 0) // Set general purpose NVM bits +#define AT91_MC_FCR_CLR_GP_NVM (0xd << 0) // Clear general purpose NVM bits +#define AT91_MC_FCR_SET_SECURITY (0xf << 0) // Set security bit +#define AT91_MC_FCR_PAGE_MASK (0x3ff) +#define AT91_MC_FCR_PAGE_SHIFT 8 +#define AT91_MC_FCR_KEY (0x5a << 24) // Key to enable command +#define AT91_MC_FSR 0x68 // Flash Status Register +#define AT91_MC_FSR_FRDY (1 << 0) // Flash Ready for next command +#define AT91_MC_FSR_LOCKE (1 << 2) // Programming of a locked block +#define AT91_MC_FSR_PROGE (1 << 3) // Programming error +#define AT91_MC_FSR_SECURITY (1 << 4) // Security bit is set +#define AT91_MC_FSR_GPNVM0 (1 << 8) // General purpose NVM bit 0 +#define AT91_MC_FSR_GPNVM1 (1 << 9) // General purpose NVM bit 1 +#endif + +//============================================================================= +// Debug Unit + +#if defined(CYGHWR_HAL_ARM_AT91SAM7S) + +#ifndef AT91_DBG +#define AT91_DBG 0xFFFFF200 +#endif + +#define AT91_DBG_CR 0x00 // Control Register +#define AT91_DBG_CR_RSTRX (0x1 << 2) // Reset Receiver +#define AT91_DBG_CR_RSTTX (0x1 << 3) // Reset Transmitter +#define AT91_DBG_CR_RXEN (0x1 << 4) // Receiver Enable +#define AT91_DBG_CR_RXDIS (0x1 << 5) // Receiver Disable +#define AT91_DBG_CR_TXEN (0x1 << 6) // Transmitter Enable +#define AT91_DBG_CR_TXDIS (0x1 << 7) // Transmitter Disable +#define AT91_DBG_CR_RSTSTA (0x1 << 8) // Reset Status Bits +#define AT91_DBG_MR 0x04 // Mode Register +#define AT91_DBG_MR_PAR_EVEN (0x0 << 9) // Even Parity +#define AT91_DBG_MR_PAR_ODD (0x1 << 9) // Odd Parity +#define AT91_DBG_MR_PAR_SPACE (0x2 << 9) // Parity forced to Space +#define AT91_DBG_MR_PAR_MARK (0x3 << 9) // Parity forced to Mark +#define AT91_DBG_MR_PAR_NONE (0x4 << 9) // No Parity +#define AT91_DBG_MR_PAR_MULTI (0x6 << 9) // Multi-drop mode +#define AT91_DBG_MR_CHMODE_NORMAL (0x0 << 14) // Normal mode +#define AT91_DBG_MR_CHMODE_AUTO (0x1 << 14) // Automatic Echo +#define AT91_DBG_MR_CHMODE_LOCAL (0x2 << 14) // Local Loopback +#define AT91_DBG_MR_CHMODE_REMOTE (0x3 << 14) // Remote Loopback +#define AT91_DBG_IER 0x08 // Interrupt Enable Register +#define AT91_DBG_IDR 0x0c // Interrupt Disable Register +#define AT91_DBG_IMR 0x10 // Interrupt Mask Register +#define AT91_DBG_CSR 0x14 // Channel Status Register +#define AT91_DBG_CSR_RXRDY (1 << 0) // Receiver Ready +#define AT91_DBG_CSR_TXRDY (1 << 1) // Transmitter Ready +#define AT91_DBG_RHR 0x18 // Receiver Holding Register +#define AT91_DBG_THR 0x1c // Transmitter Holding Register +#define AT91_DBG_BRGR 0x20 // Baud Rate Generator Register +#define AT91_DBG_C1R 0x40 // Chip ID1 register +#define AT91_DBG_C1R_ARM945ES (1 << 5) +#define AT91_DBG_C1R_ARM7TDMI (2 << 5) +#define AT91_DBG_C1R_ARM920T (4 << 5) +#define AT91_DBG_C1R_ARM926EJ (5 << 5) +#define AT91_DBG_C1R_CPU_MASK (0x7 << 5) +#define AT91_DBG_C1R_FLASH_0K (0x0 << 8) +#define AT91_DBG_C1R_FLASH_8K (0x1 << 8) +#define AT91_DBG_C1R_FLASH_16K (0x2 << 8) +#define AT91_DBG_C1R_FLASH_32K (0x3 << 8) +#define AT91_DBG_C1R_FLASH_64K (0x5 << 8) +#define AT91_DBG_C1R_FLASH_128K (0x7 << 8) +#define AT91_DBG_C1R_FLASH_256K (0x9 << 8) +#define AT91_DBG_C1R_FLASH_512K (0xa << 8) +#define AT91_DBG_C1R_FLASH_1024K (0xc << 8) +#define AT91_DBG_C1R_FLASH_2048K (0xe << 8) +#define AT91_DBG_C1R_FLASH_MASK (0xf << 8) +#define AT91_DBG_C1R_FLASH2_0K (0x0 << 12) +#define AT91_DBG_C1R_FLASH2_8K (0x1 << 12) +#define AT91_DBG_C1R_FLASH2_16K (0x2 << 12) +#define AT91_DBG_C1R_FLASH2_32K (0x3 << 12) +#define AT91_DBG_C1R_FLASH2_64K (0x5 << 12) +#define AT91_DBG_C1R_FLASH2_128K (0x7 << 12) +#define AT91_DBG_C1R_FLASH2_256K (0x9 << 12) +#define AT91_DBG_C1R_FLASH2_512K (0xa << 12) +#define AT91_DBG_C1R_FLASH2_1024K (0xc << 12) +#define AT91_DBG_C1R_FLASH2_2048K (0xe << 12) +#define AT91_DBG_C1R_FLASH2_MASK (0xf << 12) +#define AT91_DBG_C1R_SRAM_1K (0x1 << 16) +#define AT91_DBG_C1R_SRAM_2K (0x2 << 16) +#define AT91_DBG_C1R_SRAM_112K (0x4 << 16) +#define AT91_DBG_C1R_SRAM_4K (0x5 << 16) +#define AT91_DBG_C1R_SRAM_80K (0x6 << 16) +#define AT91_DBG_C1R_SRAM_160K (0x7 << 16) +#define AT91_DBG_C1R_SRAM_8K (0x8 << 16) +#define AT91_DBG_C1R_SRAM_16K (0x9 << 16) +#define AT91_DBG_C1R_SRAM_32K (0xa << 16) +#define AT91_DBG_C1R_SRAM_64K (0xb << 16) +#define AT91_DBG_C1R_SRAM_128K (0xc << 16) +#define AT91_DBG_C1R_SRAM_256K (0xd << 16) +#define AT91_DBG_C1R_SRAM_96K (0xe << 16) +#define AT91_DBG_C1R_SRAM_512K (0xf << 16) +#define AT91_DBG_C1R_SRAM_MASK (0xf << 16) +#define AT91_DBG_C1R_ARCH_AT75Cxx (0xf0 << 20) +#define AT91_DBG_C1R_ARCH_AT91x40 (0x40 << 20) +#define AT91_DBG_C1R_ARCH_AT91x63 (0x63 << 20) +#define AT91_DBG_C1R_ARCH_AT91x55 (0x55 << 20) +#define AT91_DBG_C1R_ARCH_AT91x42 (0x42 << 20) +#define AT91_DBG_C1R_ARCH_AT91x92 (0x92 << 20) +#define AT91_DBG_C1R_ARCH_AT91x34 (0x24 << 20) +#define AT91_DBG_C1R_ARCH_AT91SAM7Axx (0x60 << 20) +#define AT91_DBG_C1R_ARCH_AT91SAM7Sxx (0x70 << 20) +#define AT91_DBG_C1R_ARCH_AT91SAM7XC (0x71 << 20) +#define AT91_DBG_C1R_ARCH_AT91SAM7SExx (0x72 << 20) +#define AT91_DBG_C1R_ARCH_AT91SAM7Lxx (0x73 << 20) +#define AT91_DBG_C1R_ARCH_AT91SAM7Xxx (0x75 << 20) +#define AT91_DBG_C1R_ARCH_AT91SAM9xx (0x19 << 20) +#define AT91_DBG_C1R_ARCH_MASK (0xff << 20) +#define AT91_DBG_C1R_NVPTYP_ROM (0 << 28) // ROM only +#define AT91_DBG_C1R_NVPTYP_RLOCF (1 << 28) // ROMless of on chip Flash +#define AT91_DBG_C1R_NVPTYP_SRAMROM (4 << 28) // SRAM emulating ROM +#define AT91_DBG_C1R_NVPTYP_EFLASH (2 << 28) // Embedded Flash +#define AT91_DBG_C1R_NVPTYP_ROMFLASH (3 << 28) // ROM & FLASH +#define AT91_DBG_C1R_NVPTYP_MASK (7 << 28) +#define AT91_DBG_C1R_EXT (1 << 31) // Extension Register Exists +#define AT91_DBG_C2R 0x44 // Chip ID2 register +#define AT91_DBG_FNTR 0x48 // Force NTRST Register +#define AT91_DBG_RPR 0x100 // Receiver Pointer Register +#define AT91_DBG_RCR 0x104 // Receiver Counter Register +#define AT91_DBG_TPR 0x108 // Transmit Pointer Register +#define AT91_DBG_TCR 0x10c // Transmit Counter Register +#define AT91_DBG_RNPR 0x110 // Receiver Next Pointer Register +#define AT91_DBG_RNCR 0x114 // Receiver Next Counter Register +#define AT91_DBG_TNPR 0x118 // Transmit Next Pointer Register +#define AT91_DBG_TNCR 0x11c // Transmit Next Counter Register +#define AT91_DBG_PTCR 0x120 // PDC Transfer Control Register +#define AT91_DBG_PTSR 0x124 // PDC Transfer Status Register +#endif + +//============================================================================= +// Periodic Interval Timer Controller + +#if defined(CYGHWR_HAL_ARM_AT91SAM7S) + +#ifndef AT91_PITC +#define AT91_PITC 0xfffffd30 +#endif + +#define AT91_PITC_PIMR 0x00 // Period Interval Mode Register +#define AT91_PITC_PIMR_PITEN (1 << 24) // Periodic Interval Timer Enable +#define AT91_PITC_PIMR_PITIEN (1 << 25) // Periodic Interval Timer Interrupt Enable +#define AT91_PITC_PISR 0x04 // Period Interval Status Register +#define AT91_PITC_PISR_PITS (1 << 0) // Periodic Interval Timer Status +#define AT91_PITC_PIVR 0x08 // Period Interval Status Register +#define AT91_PITC_PIIR 0x0C // Period Interval Image Register +#endif + +//============================================================================= +// Real Time Timer Controller + +#if defined(CYGHWR_HAL_ARM_AT91SAM7S) + +#ifndef AT91_RTTC +#define AT91_RTTC 0xFFFFFD20 +#endif + +#define AT91_RTTC_RTMR 0x00 // Real Time Mode Register +#define AT91_RTTC_RTMR_ALMIEN (1 << 16) // Alarm Interrupt Enable +#define AT91_RTTC_RTMR_RTTINCIEN (1 << 17) // Timer Increment Interrupt Enable +#define AT91_RTTC_RTMR_RTTRST (1 << 18) // Timer Reset +#define AT91_RTTC_RTAR 0x04 // Real Time Alarm Register +#define AT91_RTTC_RTVR 0x08 // Real Time Value Register +#define AT91_RTTC_RTSR 0x0C // Real Time Status Register +#define AT91_RTTC_RTSR_ALMS (1 << 0) // Alarm Status +#define AT91_RTTC_RTSR_RTTINC (1 << 1) // Timer Increment +#endif + //============================================================================= // FIQ interrupt vector which is shared by all HAL varients. Index: hal/arm/at91/var/current/src/at91_misc.c =================================================================== RCS file: /cvs/ecos/ecos/packages/hal/arm/at91/var/current/src/at91_misc.c,v retrieving revision 1.11 diff -u -r1.11 at91_misc.c --- hal/arm/at91/var/current/src/at91_misc.c 12 Jun 2005 13:34:21 -0000 1.11 +++ hal/arm/at91/var/current/src/at91_misc.c 19 Feb 2006 18:32:02 -0000 @@ -70,97 +70,6 @@ #include // platform registers // ------------------------------------------------------------------------- -// Clock support - -static cyg_uint32 _period; - -void hal_clock_initialize(cyg_uint32 period) -{ - CYG_ADDRESS timer = AT91_TC+AT91_TC_TC0; - - CYG_ASSERT(period < 0x10000, "Invalid clock period"); - - // Disable counter - HAL_WRITE_UINT32(timer+AT91_TC_CCR, AT91_TC_CCR_CLKDIS); - - // Set registers - HAL_WRITE_UINT32(timer+AT91_TC_CMR, AT91_TC_CMR_CPCTRG | // Reset counter on CPC - AT91_TC_CMR_CLKS_MCK32); // 1 MHz - HAL_WRITE_UINT32(timer+AT91_TC_RC, period); - - // Start timer - HAL_WRITE_UINT32(timer+AT91_TC_CCR, AT91_TC_CCR_TRIG | AT91_TC_CCR_CLKEN); - - // Enable timer 0 interrupt - HAL_WRITE_UINT32(timer+AT91_TC_IER, AT91_TC_IER_CPC); -} - -void hal_clock_reset(cyg_uint32 vector, cyg_uint32 period) -{ - CYG_ADDRESS timer = AT91_TC+AT91_TC_TC0; - cyg_uint32 sr; - - CYG_ASSERT(period < 0x10000, "Invalid clock period"); - - HAL_READ_UINT32(timer+AT91_TC_SR, sr); // Clear interrupt - - if (period != _period) { - hal_clock_initialize(period); - } - _period = period; - -} - -void hal_clock_read(cyg_uint32 *pvalue) -{ - CYG_ADDRESS timer = AT91_TC+AT91_TC_TC0; - cyg_uint32 val; - - HAL_READ_UINT32(timer+AT91_TC_CV, val); - *pvalue = val; -} - -// ------------------------------------------------------------------------- -// -// Delay for some number of micro-seconds -// Use timer #2 in MCLOCK/32 mode. -// -void hal_delay_us(cyg_int32 usecs) -{ - cyg_uint32 stat; - cyg_uint64 ticks; -#if defined(CYGHWR_HAL_ARM_AT91_JTST) - // TC2 is reserved for AD/DA. Use TC1 instead. - CYG_ADDRESS timer = AT91_TC+AT91_TC_TC1; -#else - CYG_ADDRESS timer = AT91_TC+AT91_TC_TC2; -#endif - // Calculate how many timer ticks the required number of - // microseconds equate to. We do this calculation in 64 bit - // arithmetic to avoid overflow. - ticks = (((cyg_uint64)usecs) * ((cyg_uint64)CYGNUM_HAL_ARM_AT91_CLOCK_SPEED))/32000000LL; - - // Disable counter - HAL_WRITE_UINT32(timer+AT91_TC_CCR, AT91_TC_CCR_CLKDIS); - - // Set registers - HAL_WRITE_UINT32(timer+AT91_TC_CMR, AT91_TC_CMR_CLKS_MCK32); // 1MHz - HAL_WRITE_UINT32(timer+AT91_TC_RA, 0); - HAL_WRITE_UINT32(timer+AT91_TC_RC, ticks); - - // Clear status flags - HAL_READ_UINT32(timer+AT91_TC_SR, stat); - - // Start timer - HAL_WRITE_UINT32(timer+AT91_TC_CCR, AT91_TC_CCR_TRIG | AT91_TC_CCR_CLKEN); - - // Wait for the compare - do { - HAL_READ_UINT32(timer+AT91_TC_SR, stat); - } while ((stat & AT91_TC_SR_CPC) == 0); -} - -// ------------------------------------------------------------------------- // Hardware init void hal_hardware_init(void) @@ -173,11 +82,106 @@ // Flush internal priority level stack for (i = 0; i < 8; ++i) HAL_WRITE_UINT32(AT91_AIC+AT91_AIC_EOI, 0xFFFFFFFF); - + +#ifdef HAL_PLF_HARDWARE_INIT + // Perform any platform specific initializations + HAL_PLF_HARDWARE_INIT(); +#endif + // Set up eCos/ROM interfaces hal_if_init(); +} +#if CYGINT_HAL_ARM_AT91_SYS_INTERRUPT +// Decode a system interrupt. Not all systems have all interrupts. So +// code will only be generated for those interrupts which have a +// defined value. +static int sys_irq_handler(void) +{ + cyg_uint32 sr, mr; + +#ifdef CYGNUM_HAL_INTERRUPT_PITC + // Periodic Interrupt Timer Controller + HAL_READ_UINT32((AT91_PITC+AT91_PITC_PISR), sr); + if (sr & AT91_PITC_PISR_PITS) { + return CYGNUM_HAL_INTERRUPT_PITC; + } +#endif + +#ifdef CYGNUM_HAL_INTERRUPT_DBG + // Debug Unit + HAL_READ_UINT32((AT91_DBG + AT91_DBG_CSR), sr); + HAL_READ_UINT32((AT91_DBG + AT91_DBG_IMR), mr); + if (sr & mr) { + return CYGNUM_HAL_INTERRUPT_DBG; + } +#endif + +#ifdef CYGNUM_HAL_INTERRUPT_RTTC + /* Real Time Timer. Check the interrupt is enabled, not that just + the status indicates there is an interrupt. It takes a while for + the status bit to clear. */ + HAL_READ_UINT32((AT91_RTTC+AT91_RTTC_RTSR), sr); + HAL_READ_UINT32((AT91_RTTC+AT91_RTTC_RTMR), mr); + if (((mr & AT91_RTTC_RTMR_ALMIEN) && + (sr & AT91_RTTC_RTSR_ALMS)) || + ((mr & AT91_RTTC_RTMR_RTTINCIEN) && + (sr & AT91_RTTC_RTSR_RTTINC))) { + return CYGNUM_HAL_INTERRUPT_RTTC; + } +#endif + +#ifdef CYGNUM_HAL_INTERRUPT_PMC + // Power Management Controller + HAL_READ_UINT32((AT91_PMC+AT91_PMC_IMR), mr); + HAL_READ_UINT32((AT91_PMC+AT91_PMC_SR), sr); + if ((sr & mr) & + (AT91_PMC_SR_MOSCS | + AT91_PMC_SR_LOCK | + AT91_PMC_SR_MCKRDY | + AT91_PMC_SR_PCK0RDY | + AT91_PMC_SR_PCK1RDY | + AT91_PMC_SR_PCK2RDY | + AT91_PMC_SR_PCK3RDY)) { + return CYGNUM_HAL_INTERRUPT_PMC; + } +#endif + +#ifdef CYGNUM_HAL_INTERRUPT_MC + // Memory controller + HAL_READ_UINT32((AT91_MC+AT91_MC_FMR), mr); + HAL_READ_UINT32((AT91_MC+AT91_MC_FSR), sr); + if ((sr & mr) & + (AT91_MC_FSR_FRDY | + AT91_MC_FSR_LOCKE | + AT91_MC_FSR_PROGE)) { + return CYGNUM_HAL_INTERRUPT_MC; + } +#endif + +#ifdef CYGNUM_HAL_INTERRUPT_WDTC + // Watchdog Timer Controller + HAL_READ_UINT32((AT91_WDTC+AT91_WDTC_WDSR), sr); + HAL_READ_UINT32((AT91_WDTC+AT91_WDTC_WDMR), mr); + if ((mr & AT91_WDTC_WDMR_FIEN) && + sr & (AT91_WDTC_WDSR_UNDER | + AT91_WDTC_WDSR_ERROR)) { + return CYGNUM_HAL_INTERRUPT_WDTC; + } +#endif + +#ifdef CYGNUM_HAL_INTERRUPT_RSTC + // Reset Controller + HAL_READ_UINT32((AT91_RST + AT91_RST_RSR), sr); + HAL_READ_UINT32((AT91_RST + AT91_RST_RMR), mr); + if (((mr & AT91_RST_RMR_URSTIEN) && (sr & AT91_RST_RSR_USER)) || + ((mr & AT91_RST_RMR_BODIEN) && (sr & AT91_RST_RSR_BROWN))) + return CYGNUM_HAL_INTERRUPT_RSTC; +#endif + + return CYGNUM_HAL_INTERRUPT_NONE; } +#endif // ------------------------------------------------------------------------- // This routine is called to respond to a hardware interrupt (IRQ). It @@ -204,7 +208,13 @@ HAL_READ_UINT32(AT91_AIC+AT91_AIC_ISR, irq_num); - // An invalid interrrupt source is treated as a spurious interrupt +#if CYGINT_HAL_ARM_AT91_SYS_INTERRUPT + if (irq_num == CYGNUM_HAL_INTERRUPT_SYS) { + // determine the source of the system interrupt + irq_num = sys_irq_handler(); + } +#endif + // An invalid interrupt source is treated as a spurious interrupt if (irq_num < CYGNUM_HAL_ISR_MIN || irq_num > CYGNUM_HAL_ISR_MAX) irq_num = CYGNUM_HAL_INTERRUPT_NONE; @@ -220,6 +230,13 @@ CYG_ASSERT(vector <= CYGNUM_HAL_ISR_MAX && vector >= CYGNUM_HAL_ISR_MIN , "Invalid vector"); +#if CYGINT_HAL_ARM_AT91_SYS_INTERRUPT + if (vector >= 32) { + HAL_WRITE_UINT32(AT91_AIC+AT91_AIC_IDCR, + (1 << CYGINT_HAL_ARM_AT91_SYS_INTERRUPT)); + return; + } +#endif HAL_WRITE_UINT32(AT91_AIC+AT91_AIC_IDCR, (1<= CYGNUM_HAL_ISR_MIN , "Invalid vector"); +#if CYGINT_HAL_ARM_AT91_SYS_INTERRUPT + if (vector >= 32) { + hal_interrupt_configure(CYGINT_HAL_ARM_AT91_SYS_INTERRUPT, true, true); + HAL_WRITE_UINT32(AT91_AIC+AT91_AIC_IECR, + (1 <= CYGNUM_HAL_ISR_MIN , "Invalid vector"); +#if CYGINT_HAL_ARM_AT91_SYS_INTERRUPT + if (vector >= 32) + return; +#endif if (level) { if (up) { mode = AT91_AIC_SMR_LEVEL_HI; @@ -270,6 +299,11 @@ vector >= CYGNUM_HAL_ISR_MIN , "Invalid vector"); CYG_ASSERT(level >= 0 && level <= 7, "Invalid level"); +#if CYGINT_HAL_ARM_AT91_SYS_INTERRUPT + if (vector >= 32) + return; +#endif + HAL_READ_UINT32(AT91_AIC+(AT91_AIC_SMR0+(vector*4)), mode); mode = (mode & ~AT91_AIC_SMR_PRIORITY) | level; HAL_WRITE_UINT32(AT91_AIC+(AT91_AIC_SMR0+(vector*4)), mode); @@ -281,15 +315,30 @@ } +#ifndef AT91_RST /* Use the watchdog to generate a reset */ void hal_at91_reset_cpu(void) { HAL_WRITE_UINT32(AT91_WD + AT91_WD_OMR, AT91_WD_OMR_OKEY); HAL_WRITE_UINT32(AT91_WD + AT91_WD_CMR, AT91_WD_CMR_CKEY); HAL_WRITE_UINT32(AT91_WD + AT91_WD_CR, AT91_WD_CR_RSTKEY); - HAL_WRITE_UINT32(AT91_WD + AT91_WD_OMR, AT91_WD_OMR_OKEY | AT91_WD_OMR_RSTEN | AT91_WD_OMR_WDEN); + HAL_WRITE_UINT32(AT91_WD + AT91_WD_OMR, + (AT91_WD_OMR_OKEY | + AT91_WD_OMR_RSTEN | + AT91_WD_OMR_WDEN)); while(1) CYG_EMPTY_STATEMENT; } - +#else +/* Use the Reset Controller to generate a reset */ +void hal_at91_reset_cpu(void) +{ + HAL_WRITE_UINT32(AT91_RST + AT91_RST_RCR, + AT91_RST_RCR_PROCRST | + AT91_RST_RCR_ICERST | + AT91_RST_RCR_PERRST | + AT91_RST_RCR_KEY); + while(1) CYG_EMPTY_STATEMENT; +} +#endif //-------------------------------------------------------------------------- // EOF at91_misc.c Index: hal/arm/at91/var/current/src/hal_diag_dbg.c =================================================================== RCS file: hal/arm/at91/var/current/src/hal_diag_dbg.c diff -N hal/arm/at91/var/current/src/hal_diag_dbg.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ hal/arm/at91/var/current/src/hal_diag_dbg.c 19 Feb 2006 18:32:02 -0000 @@ -0,0 +1,343 @@ +/*============================================================================= +// +// hal_diag_dbg.c +// +// HAL diagnostic output code using the debug serial port +// +//============================================================================= +//####ECOSGPLCOPYRIGHTBEGIN#### +// ------------------------------------------- +// This file is part of eCos, the Embedded Configurable Operating System. +// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. +// Copyright (C) 2006 eCosCentric Ltd. +// +// eCos 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 2 or (at your option) any later version. +// +// eCos 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 eCos; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. +// +// As a special exception, if other files instantiate templates or use macros +// or inline functions from this file, or you compile this file and link it +// with other works to produce a work based on this file, this file does not +// by itself cause the resulting work to be covered by the GNU General Public +// License. However the source code for this file must still be made available +// in accordance with section (3) of the GNU General Public License. +// +// This exception does not invalidate any other reasons why a work based on +// this file might be covered by the GNU General Public License. +// ------------------------------------------- +//####ECOSGPLCOPYRIGHTEND#### +//============================================================================= +//#####DESCRIPTIONBEGIN#### +// +// Author(s): jskov +// Contributors:jskov, gthomas +// Date: 2001-07-12 +// Purpose: HAL diagnostic output +// Description: Implementations of HAL diagnostic output support. +// +//####DESCRIPTIONEND#### +// +//===========================================================================*/ + + +#include +#include + +#include CYGBLD_HAL_PLATFORM_H + +#include // base types + +#include // SAVE/RESTORE GP macros +#include // IO macros +#include // interface API +#include // HAL_ENABLE/MASK/UNMASK_INTERRUPTS +#include // Helper functions +#include // CYG_ISR_HANDLED +#include + +#include // Device registers + +//----------------------------------------------------------------------------- +typedef struct { + cyg_uint8* base; + cyg_int32 msec_timeout; + int isr_vector; + cyg_uint32 baud_rate; +} channel_data_t; + +//----------------------------------------------------------------------------- + +static void +cyg_hal_plf_serial_dbg_init_channel(void* __ch_data) +{ + cyg_uint8 *base = ((channel_data_t*)__ch_data)->base; + + cyg_uint32 baud_value = 0; + cyg_uint32 baud_rate = ((channel_data_t*)__ch_data)->baud_rate; + + /* Enable pins to be driven by peripheral, using peripheral A. */ + HAL_WRITE_UINT32((AT91_PIO+AT91_PIO_ASR), + (AT91_PIO_PSR_DRXD | + AT91_PIO_PSR_DTXD)); + + /* Disables the PIO from controlling the corresponding pin + (enables peripheral control of the pin). */ + HAL_WRITE_UINT32((AT91_PIO+AT91_PIO_PDR), + (AT91_PIO_PSR_DRXD | + AT91_PIO_PSR_DTXD)); + + /* Disable interrupt */ + HAL_WRITE_UINT32((base+AT91_DBG_IDR), 0xFFFFFFFF); + + /* Reset receiver and transmitter */ + HAL_WRITE_UINT32((base+AT91_DBG_CR), + (AT91_DBG_CR_RSTRX | AT91_DBG_CR_RSTTX | + AT91_DBG_CR_RXDIS | AT91_DBG_CR_TXDIS)); + + baud_value = AT91_US_BAUD(baud_rate); + + HAL_WRITE_UINT32((base+AT91_DBG_BRGR), baud_value); + + /* Define the USART mode */ + /* (USART) Normal, 1 stop bit, No Parity, Character Length: 8 bits, Clock */ + HAL_WRITE_UINT32(base+AT91_DBG_MR, + (AT91_DBG_MR_CHMODE_NORMAL | + AT91_DBG_MR_PAR_NONE)); + + /* Enable Transmitter */ + HAL_WRITE_UINT32((base+AT91_DBG_CR), AT91_DBG_CR_TXEN); + + /* Enable Receiver */ + HAL_WRITE_UINT32((base+AT91_DBG_CR), AT91_DBG_CR_RXEN); +} + +void +cyg_hal_plf_serial_dbg_putc(void* __ch_data, char c) +{ + cyg_uint8 * base = ((channel_data_t*)__ch_data)->base; + cyg_uint32 status; + CYGARC_HAL_SAVE_GP(); + + // Wait for Tx FIFO not full + do + { + HAL_READ_UINT32((base+AT91_DBG_CSR), status); + } + while (!(status & AT91_DBG_CSR_TXRDY)) ; + + //UART TX data register + HAL_WRITE_UINT8((base+AT91_DBG_THR), c); + + CYGARC_HAL_RESTORE_GP(); +} + +static cyg_bool +cyg_hal_plf_serial_dbg_getc_nonblock(void* __ch_data, cyg_uint8* ch) +{ + cyg_uint8 * base = ((channel_data_t*)__ch_data)->base; + cyg_uint32 status; + + HAL_READ_UINT32((base+AT91_DBG_CSR), status); + if (status & AT91_DBG_CSR_RXRDY) + { + HAL_READ_UINT8((base+AT91_DBG_RHR), *ch); + return true; + } + return false; +} + +cyg_uint8 +cyg_hal_plf_serial_dbg_getc(void* __ch_data) +{ + cyg_uint8 ch; + CYGARC_HAL_SAVE_GP(); + + while (!cyg_hal_plf_serial_dbg_getc_nonblock(__ch_data, &ch)); + + CYGARC_HAL_RESTORE_GP(); + return ch; +} + +static void +cyg_hal_plf_serial_dbg_write(void* __ch_data, const cyg_uint8* __buf, + cyg_uint32 __len) +{ + CYGARC_HAL_SAVE_GP(); + + while (__len-- > 0) + cyg_hal_plf_serial_dbg_putc(__ch_data, *__buf++); + + CYGARC_HAL_RESTORE_GP(); +} + +static void +cyg_hal_plf_serial_dbg_read(void* __ch_data, cyg_uint8* __buf, cyg_uint32 __len) +{ + CYGARC_HAL_SAVE_GP(); + + while (__len-- > 0) + *__buf++ = cyg_hal_plf_serial_dbg_getc(__ch_data); + + CYGARC_HAL_RESTORE_GP(); +} + +cyg_bool +cyg_hal_plf_serial_dbg_getc_timeout(void* __ch_data, cyg_uint8* ch) +{ + int delay_count; + channel_data_t* chan = (channel_data_t*)__ch_data; + cyg_bool res; + CYGARC_HAL_SAVE_GP(); + + delay_count = chan->msec_timeout * 10; // delay in .1 ms steps + + for (;;) { + res = cyg_hal_plf_serial_dbg_getc_nonblock(__ch_data, ch); + if (res || 0 == delay_count--) + break; + + CYGACC_CALL_IF_DELAY_US(100); + } + + CYGARC_HAL_RESTORE_GP(); + return res; +} + +static int +cyg_hal_plf_serial_dbg_control(void *__ch_data, __comm_control_cmd_t __func, ...) +{ + static int irq_state = 0; + channel_data_t* chan = (channel_data_t*)__ch_data; + int ret = 0; + va_list ap; + + CYGARC_HAL_SAVE_GP(); + va_start(ap, __func); + + switch (__func) { + case __COMMCTL_GETBAUD: + ret = chan->baud_rate; + break; + case __COMMCTL_SETBAUD: + chan->baud_rate = va_arg(ap, cyg_int32); + // Should we verify this value here? + cyg_hal_plf_serial_dbg_init_channel(chan); + ret = 0; + break; + case __COMMCTL_IRQ_ENABLE: + irq_state = 1; + HAL_INTERRUPT_UNMASK(chan->isr_vector); + HAL_WRITE_UINT32((chan->base+AT91_DBG_IER), AT91_DBG_CSR_RXRDY); + break; + case __COMMCTL_IRQ_DISABLE: + ret = irq_state; + irq_state = 0; + HAL_WRITE_UINT32((chan->base+AT91_DBG_IDR), AT91_DBG_CSR_RXRDY); + HAL_INTERRUPT_MASK(chan->isr_vector); + break; + case __COMMCTL_DBG_ISR_VECTOR: + ret = chan->isr_vector; + break; + case __COMMCTL_SET_TIMEOUT: + ret = chan->msec_timeout; + chan->msec_timeout = va_arg(ap, cyg_uint32); + default: + break; + } + CYGARC_HAL_RESTORE_GP(); + return ret; +} + +static int +cyg_hal_plf_serial_dbg_isr(void *__ch_data, int* __ctrlc, + CYG_ADDRWORD __vector, CYG_ADDRWORD __data) +{ + int res = 0; + channel_data_t* chan = (channel_data_t*)__ch_data; + cyg_uint32 status; + cyg_uint32 c; + cyg_uint8 ch; + CYGARC_HAL_SAVE_GP(); + + *__ctrlc = 0; + HAL_READ_UINT32(chan->base+AT91_DBG_CSR, status); + if ( (status & AT91_DBG_CSR_RXRDY) != 0 ) { + + HAL_READ_UINT32(chan->base+AT91_DBG_RHR, c); + ch = (cyg_uint8)(c & 0xff); + if( cyg_hal_is_break( &ch , 1 ) ) + *__ctrlc = 1; + + res = CYG_ISR_HANDLED; + } + + HAL_INTERRUPT_ACKNOWLEDGE(chan->isr_vector); + + CYGARC_HAL_RESTORE_GP(); + return res; +} + +static channel_data_t at91_ser_channels[1] = { + { (cyg_uint8*)AT91_DBG, 1000, CYGNUM_HAL_INTERRUPT_DBG, + CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD} +}; + +static void +cyg_hal_plf_serial_init(void) +{ + hal_virtual_comm_table_t* comm; + int cur; + + cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT); + + // Init channels + cyg_hal_plf_serial_dbg_init_channel(&at91_ser_channels[0]); + + // Setup procs in the vector table + + // Set channel 0 + CYGACC_CALL_IF_SET_CONSOLE_COMM(0); + comm = CYGACC_CALL_IF_CONSOLE_PROCS(); + CYGACC_COMM_IF_CH_DATA_SET(*comm, &at91_ser_channels[0]); + CYGACC_COMM_IF_WRITE_SET(*comm, cyg_hal_plf_serial_dbg_write); + CYGACC_COMM_IF_READ_SET(*comm, cyg_hal_plf_serial_dbg_read); + CYGACC_COMM_IF_PUTC_SET(*comm, cyg_hal_plf_serial_dbg_putc); + CYGACC_COMM_IF_GETC_SET(*comm, cyg_hal_plf_serial_dbg_getc); + CYGACC_COMM_IF_CONTROL_SET(*comm, cyg_hal_plf_serial_dbg_control); + CYGACC_COMM_IF_DBG_ISR_SET(*comm, cyg_hal_plf_serial_dbg_isr); + CYGACC_COMM_IF_GETC_TIMEOUT_SET(*comm, cyg_hal_plf_serial_dbg_getc_timeout); + + // Restore original console + CYGACC_CALL_IF_SET_CONSOLE_COMM(cur); +} + +void +cyg_hal_plf_comms_init(void) +{ + static int initialized = 0; + + if (initialized) + return; + + initialized = 1; + + cyg_hal_plf_serial_init(); +} + +void +hal_diag_led(int mask) +{ + hal_at91_set_leds(mask); +} + +//----------------------------------------------------------------------------- +// End of hal_diag_dbg.c Index: hal/arm/at91/var/current/src/timer_pit.c =================================================================== RCS file: hal/arm/at91/var/current/src/timer_pit.c diff -N hal/arm/at91/var/current/src/timer_pit.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ hal/arm/at91/var/current/src/timer_pit.c 19 Feb 2006 18:32:02 -0000 @@ -0,0 +1,138 @@ +/*========================================================================== +// +// timer_pit.c +// +// HAL timer code using the Periodic Interval Timer +// +//========================================================================== +//####ECOSGPLCOPYRIGHTBEGIN#### +// ------------------------------------------- +// This file is part of eCos, the Embedded Configurable Operating System. +// Copyright (C) 2006 eCosCentric Ltd +// +// eCos 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 2 or (at your option) any later version. +// +// eCos 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 eCos; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. +// +// As a special exception, if other files instantiate templates or use macros +// or inline functions from this file, or you compile this file and link it +// with other works to produce a work based on this file, this file does not +// by itself cause the resulting work to be covered by the GNU General Public +// License. However the source code for this file must still be made available +// in accordance with section (3) of the GNU General Public License. +// +// This exception does not invalidate any other reasons why a work based on +// this file might be covered by the GNU General Public License. +// ------------------------------------------- +//####ECOSGPLCOPYRIGHTEND#### +//========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): asl, Oliver Munz +// Contributors: asl, Oliver Munz +// Date: 2006-02-12 +// Purpose: Clock support using the PIT +// Description: +// +//####DESCRIPTIONEND#### +// +//========================================================================*/ + +#include + +#include // base types +#include // assertion macros + +#include // IO macros +#include +// ------------------------------------------------------------------------- +// Use system clock +void +hal_clock_initialize(cyg_uint32 period) +{ + cyg_uint32 sr; + + CYG_ASSERT(CYGNUM_HAL_INTERRUPT_RTC == CYGNUM_HAL_INTERRUPT_PITC, + "Invalid timer interrupt"); + + /* Set Period Interval timer and enable interrupt */ + HAL_WRITE_UINT32((AT91_PITC + AT91_PITC_PIMR), + period | + AT91_PITC_PIMR_PITEN | + AT91_PITC_PIMR_PITIEN); + + // Read the status register to clear any pending interrupt + HAL_READ_UINT32(AT91_PITC + AT91_PITC_PISR, sr); +} + +// This routine is called during a clock interrupt. +void +hal_clock_reset(cyg_uint32 vector, cyg_uint32 period) +{ + cyg_uint32 reg; + + /* Read the value register so that we clear the interrupt */ + HAL_READ_UINT32(AT91_PITC + AT91_PITC_PIVR, reg); +} + +// Read the current value of the clock, returning the number of hardware +// "ticks" that have occurred (i.e. how far away the current value is from +// the start) +void +hal_clock_read(cyg_uint32 *pvalue) +{ + cyg_uint32 ir; + + HAL_READ_UINT32(AT91_PITC + AT91_PITC_PIIR, ir); + *pvalue = ir & 0xfffff; +} + +// ------------------------------------------------------------------------- +// +// Delay for some number of micro-seconds +// PIT is clocked at MCLK / 16 +// +void hal_delay_us(cyg_int32 usecs) +{ + cyg_int64 ticks; + cyg_uint32 val1, val2; + cyg_uint32 piv; + + // Calculate how many PIT ticks the required number of microseconds + // equate to. We do this calculation in 64 bit arithmetic to avoid + // overflow. + ticks = (((cyg_uint64)usecs) * + ((cyg_uint64)CYGNUM_HAL_ARM_AT91_CLOCK_SPEED))/16/1000000LL; + + // I've no idea why, but waiting for the number of ticks calculated + // above does not work by about a factor or 3. If anybody works out + // why, please let me know! + ticks = ticks / 3; + + HAL_READ_UINT32(AT91_PITC + AT91_PITC_PIMR, piv); + + while (ticks > 0) { + hal_clock_read(&val1); + do { + hal_clock_read(&val2); + } while (val1 == val2); + // Sometimes we miss a tick, maybe because of interrupt handling? + // So calculate the number of ticks, without making a big error + // with wrap around. + if (val2 > val1) + ticks -= (val2 - val1); + else + ticks--; + } +} + +// timer_pit.c Index: hal/arm/at91/var/current/src/timer_tc.c =================================================================== RCS file: hal/arm/at91/var/current/src/timer_tc.c diff -N hal/arm/at91/var/current/src/timer_tc.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ hal/arm/at91/var/current/src/timer_tc.c 19 Feb 2006 18:32:02 -0000 @@ -0,0 +1,154 @@ +/*========================================================================== +// +// timer_tc.c +// +// HAL timer code using the Timer Counter +// +//========================================================================== +//####ECOSGPLCOPYRIGHTBEGIN#### +// ------------------------------------------- +// This file is part of eCos, the Embedded Configurable Operating System. +// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. +// Copyright (C) 2003 Nick Garnett +// +// eCos 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 2 or (at your option) any later version. +// +// eCos 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 eCos; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. +// +// As a special exception, if other files instantiate templates or use macros +// or inline functions from this file, or you compile this file and link it +// with other works to produce a work based on this file, this file does not +// by itself cause the resulting work to be covered by the GNU General Public +// License. However the source code for this file must still be made available +// in accordance with section (3) of the GNU General Public License. +// +// This exception does not invalidate any other reasons why a work based on +// this file might be covered by the GNU General Public License. +// ------------------------------------------- +//####ECOSGPLCOPYRIGHTEND#### +//========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): gthomas +// Contributors: gthomas, jskov, nickg, tkoeller +// Date: 2001-07-12 +// Purpose: HAL board support +// Description: Implementations of HAL board interfaces +// +//####DESCRIPTIONEND#### +// +//========================================================================*/ + +#include + +#include // base types +#include // assertion macros + +#include // IO macros +#include // Register state info +#include // necessary? + +// ------------------------------------------------------------------------- +// Clock support + +static cyg_uint32 _period; + +void hal_clock_initialize(cyg_uint32 period) +{ + CYG_ADDRESS timer = AT91_TC+AT91_TC_TC0; + + CYG_ASSERT(period < 0x10000, "Invalid clock period"); + + // Disable counter + HAL_WRITE_UINT32(timer+AT91_TC_CCR, AT91_TC_CCR_CLKDIS); + + // Set registers + HAL_WRITE_UINT32(timer+AT91_TC_CMR, AT91_TC_CMR_CPCTRG | // Reset counter on CPC + AT91_TC_CMR_CLKS_MCK32); // 1 MHz + HAL_WRITE_UINT32(timer+AT91_TC_RC, period); + + // Start timer + HAL_WRITE_UINT32(timer+AT91_TC_CCR, AT91_TC_CCR_TRIG | AT91_TC_CCR_CLKEN); + + // Enable timer 0 interrupt + HAL_WRITE_UINT32(timer+AT91_TC_IER, AT91_TC_IER_CPC); +} + +void hal_clock_reset(cyg_uint32 vector, cyg_uint32 period) +{ + CYG_ADDRESS timer = AT91_TC+AT91_TC_TC0; + cyg_uint32 sr; + + CYG_ASSERT(period < 0x10000, "Invalid clock period"); + + HAL_READ_UINT32(timer+AT91_TC_SR, sr); // Clear interrupt + + if (period != _period) { + hal_clock_initialize(period); + } + _period = period; + +} + +void hal_clock_read(cyg_uint32 *pvalue) +{ + CYG_ADDRESS timer = AT91_TC+AT91_TC_TC0; + cyg_uint32 val; + + HAL_READ_UINT32(timer+AT91_TC_CV, val); + *pvalue = val; +} + +// ------------------------------------------------------------------------- +// +// Delay for some number of micro-seconds +// Use timer #2 in MCLOCK/32 mode. +// +void hal_delay_us(cyg_int32 usecs) +{ + cyg_uint32 stat; + cyg_uint64 ticks; +#if defined(CYGHWR_HAL_ARM_AT91_JTST) + // TC2 is reserved for AD/DA. Use TC1 instead. + CYG_ADDRESS timer = AT91_TC+AT91_TC_TC1; +#else + CYG_ADDRESS timer = AT91_TC+AT91_TC_TC2; +#endif + // Calculate how many timer ticks the required number of + // microseconds equate to. We do this calculation in 64 bit + // arithmetic to avoid overflow. + ticks = (((cyg_uint64)usecs) * + ((cyg_uint64)CYGNUM_HAL_ARM_AT91_CLOCK_SPEED))/32000000LL; + + CYG_ASSERT(ticks < (1 << 16), "Timer overflow"); + + // Disable counter + HAL_WRITE_UINT32(timer+AT91_TC_CCR, AT91_TC_CCR_CLKDIS); + + // Set registers + HAL_WRITE_UINT32(timer+AT91_TC_CMR, AT91_TC_CMR_CLKS_MCK32); // 1MHz + HAL_WRITE_UINT32(timer+AT91_TC_RA, 0); + HAL_WRITE_UINT32(timer+AT91_TC_RC, ticks); + + // Clear status flags + HAL_READ_UINT32(timer+AT91_TC_SR, stat); + + // Start timer + HAL_WRITE_UINT32(timer+AT91_TC_CCR, AT91_TC_CCR_TRIG | AT91_TC_CCR_CLKEN); + + // Wait for the compare + do { + HAL_READ_UINT32(timer+AT91_TC_SR, stat); + } while ((stat & AT91_TC_SR_CPC) == 0); +} + +// timer_tc.c