changeset 2885:361d4d7aa0b3

* Fix the the problem of switching the PCM-settings if the PCM is already up. And improve the flash-controller programming.
author asl
date Sat, 13 Jun 2009 15:02:30 +0000
parents a01ea9250635
children 7c9e64d8c436
files packages/hal/arm/at91/at91sam7s/current/ChangeLog packages/hal/arm/at91/at91sam7s/current/include/hal_platform_setup.h packages/hal/arm/at91/at91sam7s/current/include/plf_io.h
diffstat 3 files changed, 120 insertions(+), 69 deletions(-) [+]
line wrap: on
line diff
--- a/packages/hal/arm/at91/at91sam7s/current/ChangeLog
+++ b/packages/hal/arm/at91/at91sam7s/current/ChangeLog
@@ -1,3 +1,9 @@
+2009-06-03 Oliver Munz <oli@snr.ch>
+
+ 	* Fix the the problem of switching the PCM-settings if 
+ 	the PCM is already up. And improve the flash-controller 
+ 	programming. 
+ 
 2009-01-31  Bart Veer <bartv@ecoscentric.com>
 
 	* cdl/hal_arm_at91sam7s.cdl: update compiler flags for gcc 4.x
--- a/packages/hal/arm/at91/at91sam7s/current/include/hal_platform_setup.h
+++ b/packages/hal/arm/at91/at91sam7s/current/include/hal_platform_setup.h
@@ -11,7 +11,8 @@
 // ####ECOSGPLCOPYRIGHTBEGIN####                                            
 // -------------------------------------------                              
 // This file is part of eCos, the Embedded Configurable Operating System.   
-// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2006 Free Software Foundation, Inc.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2006 Free Software
+// Foundation, Inc.
 //
 // 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     
@@ -43,10 +44,10 @@
 //#####DESCRIPTIONBEGIN####
 //
 // Author(s):   gthomas
-// Contributors:gthomas, asl
-// Date:        2006-02-18
+// Contributors:gthomas, asl, Oliver Munz
+// Date:        2009-06-03
 // Purpose:     AT91SAM7S platform specific support routines
-// Description: 
+// Description:
 // Usage:       #include <cyg/hal/hal_platform_setup.h>
 //
 //####DESCRIPTIONEND####
@@ -56,27 +57,69 @@
 #include <cyg/hal/var_io.h>
 #include <cyg/hal/plf_io.h>
 
-// Macro to initialise the Memory Controller
-        .macro _flash_init
-__flash_init__:
-        ldr     r0,=AT91_MC
+#ifdef CYG_HAL_STARTUP_ROM
+
+
+#define AT91_FLASH_FMCN_VALUE                           \
+  (CYGNUM_HAL_ARM_AT91_CLOCK_SPEED * 15 / 10000000 + 1)
+#if defined(CYGNUM_HAL_ARM_AT91_CLOCK_TYPE_EXTCLOCK)
+#define AT91_PMC_MOR_VALUE (AT91_PMC_MOR_OSCBYPASS)
+#else
+#define AT91_PMC_MOR_VALUE                                              \
+  (AT91_PMC_MOR_OSCCOUNT(CYGNUM_HAL_ARM_AT91_PMC_MOR_OSCCOUNT) |        \
+   AT91_PMC_MOR_MOSCEN)
+#endif
+#define AT91_PMC_PLLR_VALUE                                             \
+  (AT91_PMC_PLLR_DIV(CYGNUM_HAL_ARM_AT91_PLL_DIVIDER) |                 \
+   AT91_PMC_PLLR_PLLCOUNT(CYGNUM_HAL_ARM_AT91_PLL_COUNT) |              \
+   AT91_PMC_PLLR_MUL(CYGNUM_HAL_ARM_AT91_PLL_MULTIPLIER-1) |            \
+   AT91_PMC_PLLR_USBDIV_1)
+#define AT91_PMC_MCKR_VALUE                             \
+  (AT91_PMC_MCKR_PRES_CLK_2 | AT91_PMC_MCKR_PLL_CLK)
+
+#define AT91_PMC_FLASH_VALUE_SLOW                                       \
+  (AT91_MC_FMR_2FWS | (AT91_FLASH_FMCN_VALUE << AT91_MC_FMR_FMCN_SHIFT))
 #if CYGNUM_HAL_ARM_AT91_CLOCK_SPEED > 60000000
-        // When the clock is running faster than 60MHz we need two wait states
-        ldr     r1,=(AT91_MC_FMR_2FWS)
-#else 
-# if CYGNUM_HAL_ARM_AT91_CLOCK_SPEED > 30000000
-        // When the clock is running faster than 30MHz we need a wait state
-        ldr     r1,=(AT91_MC_FMR_1FWS)
-# else
-        // We have a slow clock, no extra wait states are needed
-        ldr     r1,=AT91_MC_FMR_0FWS
-# endif
+// When the clock is running faster than 60MHz we need two wait states
+#define AT91_PMC_FLASH_VALUE                    \
+  AT91_PMC_FLASH_VALUE_SLOW
+#else
+#if CYGNUM_HAL_ARM_AT91_CLOCK_SPEED > 30000000
+// When the clock is running faster than 30MHz we need a wait state
+#define AT91_PMC_FLASH_VALUE                                            \
+  (AT91_MC_FMR_1FWS | (AT91_FLASH_FMCN_VALUE << AT91_MC_FMR_FMCN_SHIFT))
+#else
+// We have a slow clock, no extra wait states are needed
+#define AT91_PMC_FLASH_VALUE                                            \
+  (AT91_MC_FMR_0FWS | (AT91_FLASH_FMCN_VALUE << AT91_MC_FMR_FMCN_SHIFT))
 #endif
+#endif
+
+// Macro with subroutines
+        .macro  _subroutines
+        b       subroutines_end
+
+
+set_flash_from_r1:
+        push    {lr}
+        ldr     r0,=AT91_MC
         str     r1,[r0,#AT91_MC_FMR]
 #if defined(AT91_MC_FMR1)
-          // If we have a second flash controller we need to set that up as well
         str     r1,[r0,#AT91_MC_FMR1]
 #endif
+        pop     {pc}
+
+
+wait_for_flag_pcm_r0r1:
+        push    {r2, lr}
+wait_loop:
+        ldr     r2,[r0,#AT91_PMC_SR]
+        ands    r2,r1,r2
+        beq     wait_loop
+        pop     {r2, pc}
+
+
+subroutines_end:
         .endm
 
 // Macro to start the main clock.
@@ -84,51 +127,45 @@
 __main_clock_init__:
         ldr     r0,=AT91_PMC
 
-          // Check that we have a stable clock before we start switching
-wait_pmc_sr_0:
-        ldr     r1,[r0,#AT91_PMC_SR]
-        ands    r1,r1,#AT91_PMC_SR_MCKRDY
-        beq     wait_pmc_sr_0
-
-          // Swap to the slow clock, just to be sure.
-        ldr     r1,=(AT91_PMC_MCKR_PRES_CLK|AT91_PMC_MCKR_SLOW_CLK)
-        str     r1,[r0,#AT91_PMC_MCKR]
+        ldr     r2,=AT91_PMC_MOR_VALUE // Load our PMC settings in registers
+        ldr     r3,=AT91_PMC_PLLR_VALUE
+        ldr     r4,=AT91_PMC_MCKR_VALUE
 
-#if defined(CYGNUM_HAL_ARM_AT91_CLOCK_TYPE_EXTCLOCK)
-        ldr     r1,=(AT91_PMC_MOR_OSCBYPASS)
-#else
-        ldr     r1,=(AT91_PMC_MOR_OSCCOUNT(CYGNUM_HAL_ARM_AT91_PMC_MOR_OSCCOUNT)|AT91_PMC_MOR_MOSCEN)
-#endif
-        str     r1,[r0,#AT91_PMC_MOR]
+        ldr     r5,[r0,#AT91_PMC_MOR] // Test if the PMC is allready up
+        cmp     r2, r5
+        bne     set_pcm_registers // Do the init
+        ldr     r5,[r0,#AT91_PMC_PLLR]
+        cmp     r3, r5
+        bne     set_pcm_registers // Do the init
+        ldr     r5,[r0,#AT91_PMC_MCKR]
+        cmp     r4, r5
+        bne     set_pcm_registers // Do the init
+        b       pmc_done // All registers are where we want it...
 
+          // We have to set the PMC
+set_pcm_registers:
+        str     r2,[r0,#AT91_PMC_MOR]
         // Wait for oscilator start timeout
-wait_pmc_sr_1:  
-        ldr     r1,[r0,#AT91_PMC_SR]
-        ands    r1,r1,#AT91_PMC_SR_MOSCS
-        beq     wait_pmc_sr_1
+        ldr     r1, =AT91_PMC_SR_MOSCS
+        bl      wait_for_flag_pcm_r0r1
 
         // Set the PLL multiplier and divider. 16 slow clocks go by
         // before the LOCK bit is set. */
-        ldr     r1,=((AT91_PMC_PLLR_DIV(CYGNUM_HAL_ARM_AT91_PLL_DIVIDER))|(AT91_PMC_PLLR_PLLCOUNT(CYGNUM_HAL_ARM_AT91_PLL_COUNT))|(AT91_PMC_PLLR_MUL(CYGNUM_HAL_ARM_AT91_PLL_MULTIPLIER-1)))
-        str     r1,[r0,#AT91_PMC_PLLR]
-
+        str     r3,[r0,#AT91_PMC_PLLR]
         // Wait for PLL locked indication
-wait_pmc_sr_2:
-        ldr     r1,[r0,#AT91_PMC_SR]
-        ands    r1,r1,#AT91_PMC_SR_LOCK
-        beq     wait_pmc_sr_2
+        ldr     r1, =AT91_PMC_SR_LOCK
+        bl      wait_for_flag_pcm_r0r1
 
         // Enable the PLL clock and set the prescale to 2 */
-        ldr     r1,=(AT91_PMC_MCKR_PRES_CLK_2|AT91_PMC_MCKR_PLL_CLK)
-        str     r1,[r0,#AT91_PMC_MCKR]
-
+        str     r4,[r0,#AT91_PMC_MCKR]
         // Wait for the MCLK ready indication
-wait_pmc_sr_3:
-        ldr     r1,[r0,#AT91_PMC_SR]
-        ands    r1,r1,#AT91_PMC_SR_MCKRDY
-        beq     wait_pmc_sr_3
+        ldr     r1, =AT91_PMC_SR_MCKRDY
+        bl      wait_for_flag_pcm_r0r1
+
+pmc_done:
         .endm
 
+
 // Remap the flash from address 0x0 and place RAM there instead.
         .macro  _remap_flash
 __remap_flash:
@@ -137,7 +174,7 @@ wait_pmc_sr_3:
         ldr     r2,[r0]      // Save away copies so we can restore them
         ldr     r3,[r1]
         ldr     r4,=0xffffff
-        eor     r4,r3,r4     // XOR the contents of 0x20004 
+        eor     r4,r3,r4     // XOR the contents of 0x20004
         str     r4,[r1]      // and write it
         ldr     r5,[r0]      // Read from low memory
         cmp     r5,r4
@@ -148,11 +185,16 @@ wait_pmc_sr_3:
 remap_done:
         str     r3,[r1]      // restore the value we changed
         .endm
-        
-#if defined(CYG_HAL_STARTUP_ROM)
-        .macro  _setup
-        _flash_init
+
+
+        .macro  _setup //The "main" of the macros...
+        _subroutines
+        ldr     sp,.__startup_stack
+        ldr     r1,=AT91_PMC_FLASH_VALUE_SLOW // May be we run >60Mhz at the moment
+        bl 		set_flash_from_r1
         _main_clock_init
+        ldr     r1,=AT91_PMC_FLASH_VALUE
+        bl 		set_flash_from_r1
         _remap_flash
         .endm
 
--- a/packages/hal/arm/at91/at91sam7s/current/include/plf_io.h
+++ b/packages/hal/arm/at91/at91sam7s/current/include/plf_io.h
@@ -43,9 +43,9 @@
 //
 // Author(s):   tkoeller
 // Contributors: andrew lunn, Oliver Munz
-// Date:        2005-12-31
+// Date:        2009-06-03
 // Purpose:     Atmel AT91SAM7S board specific registers
-// Description: 
+// Description:
 // Usage:       #include <cyg/hal/plf_io.h>
 //
 //####DESCRIPTIONEND####
@@ -64,7 +64,7 @@
 
 #define AT91_SPI AT91_SPI0
 
-// DMA registers 
+// DMA registers
 #define AT91_SPI_RPR  0x100 // Receive Pointer Register
 #define AT91_SPI_RCR  0x104 // Receive Counter Register
 #define AT91_SPI_TPR  0x108 // Transmit Pointer Register
@@ -94,8 +94,8 @@
 // Define USART2 to be the debug UART. It is similar enough to a USART
 // that both the hal_diag and interrupt driven driver will work.
 // However trying to change parity, start/stop bits etc will not work.
-#define CYGNUM_HAL_INTERRUPT_USART2 CYGNUM_HAL_INTERRUPT_DBG 
-#define AT91_USART2 AT91_DBG 
+#define CYGNUM_HAL_INTERRUPT_USART2 CYGNUM_HAL_INTERRUPT_DBG
+#define AT91_USART2 AT91_DBG
 
 #ifndef __ASSEMBLER__
 #ifdef CYGBLD_HAL_ARM_AT91_BAUD_DYNAMIC
@@ -110,7 +110,7 @@ extern cyg_uint32 hal_at91_us_baud(cyg_u
 #define AT91_US_TCR  0x10C // Transmit Counter Register
 #define AT91_US_NRPR 0x110 // Next Receive Pointer Register
 #define AT91_US_NRCR 0x114 // Next Receive Counter Register
-#define AT91_US_NTPR 0x118 // Next Transmit Pointer Register 
+#define AT91_US_NTPR 0x118 // Next Transmit Pointer Register
 #define AT91_US_NTCR 0x11C // Next Transmit Counter Register
 #define AT91_US_PTCR 0x120 // PDC Transfer Control Register
 #define AT91_US_PTSR 0x124 // PDC Transfer Status Register
@@ -177,16 +177,19 @@ extern cyg_uint32 hal_at91_us_baud(cyg_u
 
 // CAN - Controller Area Network
 
-#define AT91_CAN 0xFFFD0000 
+#define AT91_CAN 0xFFFD0000
 
 #endif
 
 #if defined(CYGHWR_HAL_ARM_AT91SAM7_at91sam7x512) || \
     defined(CYGHWR_HAL_ARM_AT91SAM7_at91sam7s512) || \
     defined(CYGHWR_HAL_ARM_AT91SAM7_at91sam7se512)
-#define AT91_MC_FMR0 0x60
-#define AT91_MC_FMR1 0x70
-#define AT91_MC_FMR AT91_MC_FMR0
+#define AT91_MC_FMR0 AT91_MC_FMR
+#define AT91_MC_FCR0 AT91_MC_FCR
+#define AT91_MC_FSR0 AT91_MC_FSR
+#define AT91_MC_FMR1 (AT91_MC_FMR + 0x10)
+#define AT91_MC_FCR1 (AT91_MC_FCR + 0x10)
+#define AT91_MC_FSR1 (AT91_MC_FSR + 0x10)
 #endif
 
 //----------------------------------------------------------------------
@@ -201,9 +204,9 @@ extern void hal_plf_hardware_init(void);
 extern void hal_plf_eth_init(void);
 #define HAL_PLF_ETH_INIT() \
     hal_plf_eth_init()
-#endif          
+#endif
 
-#endif  //__ASSEMBLER__         
+#endif  //__ASSEMBLER__
 
 #endif //CYGONCE_HAL_PLF_IO_H