This is the mail archive of the ecos-patches@sourceware.org mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

at91sam7s patch for PIT EFC PMC all in one...


Hier comes the announced patch:

1. It allows the use of the second flash in the 512k devices.
2. It solves a possible problem with a late PIT-initalisation.
3. It improves the startup-time and prevents changes in the holly
system-clock when booting from a boot-monitor.
4. It removes a spaces at the end of the line.

Index: packages/devs/flash/arm/at91/current/ChangeLog
===================================================================
RCS file: /cvs/ecos/ecos/packages/devs/flash/arm/at91/current/ChangeLog,v
retrieving revision 1.9
diff -u -r1.9 ChangeLog
--- packages/devs/flash/arm/at91/current/ChangeLog	3 Nov 2008 08:41:59 -0000	1.9
+++ packages/devs/flash/arm/at91/current/ChangeLog	4 Jun 2009 07:30:43 -0000
@@ -1,3 +1,7 @@
+2009-06-03  Oliver Munz <munz@speag.ch>
+
+	* src/at91_flash.c (Add support for 512kByte-devices.
+
 2008-11-03  Gabor Toeroek <tgabor84@gmail.com>
 
 	* src/at91_flash.c (flash_hwr_init): Add partial support for
Index: packages/devs/flash/arm/at91/current/src/at91_flash.c
===================================================================
RCS file: /cvs/ecos/ecos/packages/devs/flash/arm/at91/current/src/at91_flash.c,v
retrieving revision 1.9
diff -u -r1.9 at91_flash.c
--- packages/devs/flash/arm/at91/current/src/at91_flash.c	3 Nov 2008 08:41:59 -0000	1.9
+++ packages/devs/flash/arm/at91/current/src/at91_flash.c	4 Jun 2009 07:30:43 -0000
@@ -2,7 +2,7 @@
 //
 //      at91_flash.c
 //
-//      Flash programming for the at91 devices which have the 
+//      Flash programming for the at91 devices which have the
 //      Embedded Flash Controller.
 //
 //==========================================================================
@@ -41,11 +41,11 @@
 //#####DESCRIPTIONBEGIN####
 //
 // Author(s):    gthomas
-// Contributors: gthomas, dmoseley, Andrew Lunn, Oliver Munz
-// Date:         2000-07-26
-// Purpose:      
-// Description:  
-//              
+// Contributors: gthomas, dmoseley, Andrew Lunn, Oliver Munz, Kasim Malla
+// Date:         2009-06-03
+// Purpose:
+// Description:
+//
 //####DESCRIPTIONEND####
 //
 //==========================================================================
@@ -53,7 +53,7 @@
 #include <pkgconf/hal.h>
 #include <pkgconf/devs_flash_at91.h>
 
-#include <cyg/hal/hal_io.h>             
+#include <cyg/hal/hal_io.h>
 #include <cyg/hal/hal_intr.h>
 #include <cyg/infra/cyg_ass.h>
 
@@ -62,7 +62,8 @@
 
 #include <string.h>
 
-#define FLASH_TIMEOUT       100000
+#define FLASH_TIMEOUT       100000 /* Stupid timeout depends of the CPU clock speed... */
+#define AT91_FLASH_FMCN_VALUE (CYGNUM_HAL_ARM_AT91_CLOCK_SPEED * 15 / 10000000 + 1)
 
 #ifdef CYGBLD_DEV_FLASH_AT91_LOCKING
 static cyg_uint32 sector_size;
@@ -70,50 +71,169 @@
 
 // Disable the flash controller from erasing the page before
 // programming it
-static void 
+
+#ifdef AT91_MC_FMR1
+    #define PAGE_AT_WITCH_WE_USE_THE_EFC1 1024
+    #define SECTOR_AT_WITCH_WE_USE_THE_EFC1 16
+#endif
+
+
+static void
 flash_erase_before_write_disable (void)
 {
   cyg_uint32 fmr;
-  
+
   HAL_READ_UINT32(AT91_MC+AT91_MC_FMR, fmr);
   fmr = fmr | AT91_MC_FMR_NEBP;
   HAL_WRITE_UINT32(AT91_MC+AT91_MC_FMR, fmr);
+#ifdef AT91_MC_FMR1  /* or in other words at91sam7x512 */
+  HAL_WRITE_UINT32(AT91_MC+AT91_MC_FMR1, fmr);
+#endif
 }
 
 // Enable the flash controller to erase the page before programming
 // it
-static void 
-flash_erase_before_write_enable (void) 
+static void
+flash_erase_before_write_enable (void)
 {
-  
+
   cyg_uint32 fmr;
 
   HAL_READ_UINT32(AT91_MC+AT91_MC_FMR, fmr);
   fmr = fmr & ~((cyg_uint32) AT91_MC_FMR_NEBP);
   HAL_WRITE_UINT32(AT91_MC+AT91_MC_FMR, fmr);
+#ifdef AT91_MC_FMR1  /* or in other words at91sam7x512 */
+  HAL_WRITE_UINT32(AT91_MC+AT91_MC_FMR1, fmr);
+#endif
+}
+
+#ifdef AT91_MC_FMR1  /* or in other words at91sam7x512 */
+
+// Is the flash controller ready to accept the next command?
+static __inline__ cyg_bool
+flash_controller_is_ready(cyg_uint32 page)
+CYGBLD_ATTRIB_SECTION(".2ram.flash_run_command");
+
+static __inline__ cyg_bool
+flash_controller_is_ready(cyg_uint32 page)
+{
+  cyg_uint32 fsr;
+
+  if (page < PAGE_AT_WITCH_WE_USE_THE_EFC1){
+    HAL_READ_UINT32(AT91_MC+AT91_MC_FSR, fsr);
+  } else {
+    HAL_READ_UINT32(AT91_MC+AT91_MC_FSR1, fsr);
+  }
+  return (fsr & AT91_MC_FSR_FRDY ? true : false);
+}
+
+// Busy loop waiting for the controller to finish the command.
+// Wait a maximum of timeout loops and then return an error.
+static __inline__ int
+flash_wait_for_controller (cyg_uint32 page, cyg_uint32 timeout)
+CYGBLD_ATTRIB_SECTION(".2ram.flash_run_command");
+
+static __inline__ int
+flash_wait_for_controller (cyg_uint32 page, cyg_uint32 timeout)
+{
+  while (!flash_controller_is_ready(page)){
+    timeout--;
+    if (!timeout) {
+      return FLASH_ERR_DRV_TIMEOUT;
+    }
+  }
+  return FLASH_ERR_OK;
+}
+
+
+// Execute one command on the flash controller. This code should
+// probably not be in flash
+
+static int
+flash_run_command(cyg_uint32 address,
+                  cyg_uint32 command,
+                  cyg_uint32 timeout)
+CYGBLD_ATTRIB_SECTION(".2ram.flash_run_command");
+
+static int
+flash_run_command(cyg_uint32 address,
+                  cyg_uint32 command,
+                  cyg_uint32 timeout)
+{
+  cyg_uint32 retcode;
+  cyg_uint32 fsr;
+  cyg_uint32 mask;
+  cyg_uint32 page;
+
+  page = ((cyg_uint32) address - (cyg_uint32) flash_info.start) /
+    flash_info.block_size;
+
+  // Wait for the last command to finish
+  retcode = flash_wait_for_controller(page, timeout);
+  if (retcode != FLASH_ERR_OK){
+    return retcode;
+  }
+
+  HAL_DISABLE_INTERRUPTS(mask);
+
+  if (page < PAGE_AT_WITCH_WE_USE_THE_EFC1){
+      HAL_WRITE_UINT32(AT91_MC+AT91_MC_FCR,
+                       command |
+                       ((page & AT91_MC_FCR_PAGE_MASK) << AT91_MC_FCR_PAGE_SHIFT) |
+                       AT91_MC_FCR_KEY);
+  } else {
+      HAL_WRITE_UINT32(AT91_MC+AT91_MC_FCR1,
+                       command |
+                       (((page - PAGE_AT_WITCH_WE_USE_THE_EFC1) & AT91_MC_FCR_PAGE_MASK) << AT91_MC_FCR_PAGE_SHIFT) |
+                       AT91_MC_FCR_KEY);
+  }
+
+  retcode = flash_wait_for_controller(page, timeout);
+
+  HAL_RESTORE_INTERRUPTS(mask);
+
+  if (retcode != FLASH_ERR_OK){
+    return retcode;
+  }
+
+  // Check for an error
+  if (page < PAGE_AT_WITCH_WE_USE_THE_EFC1){
+    HAL_READ_UINT32(AT91_MC+AT91_MC_FSR, fsr);
+  } else {
+    HAL_READ_UINT32(AT91_MC+AT91_MC_FSR1, fsr);
+  }
+
+  if ((fsr & AT91_MC_FSR_LOCKE) == AT91_MC_FSR_LOCKE)
+    return FLASH_ERR_PROTECT;
+  if ((fsr & AT91_MC_FSR_PROGE) == AT91_MC_FSR_PROGE)
+    return FLASH_ERR_PROGRAM;
+
+  return FLASH_ERR_OK;
 }
+#else /* not at91sam7x512 */
+
 
 // Is the flash controller ready to accept the next command?
-static __inline__ cyg_bool 
-flash_controller_is_ready(void) 
+static __inline__ cyg_bool
+flash_controller_is_ready(void)
 CYGBLD_ATTRIB_SECTION(".2ram.flash_run_command");
 
-static __inline__ cyg_bool 
-flash_controller_is_ready(void) 
+static __inline__ cyg_bool
+flash_controller_is_ready(void)
 {
   cyg_uint32 fsr;
-  
+
   HAL_READ_UINT32(AT91_MC+AT91_MC_FSR, fsr);
   return (fsr & AT91_MC_FSR_FRDY ? true : false);
 }
 
 // Busy loop waiting for the controller to finish the command.
 // Wait a maximum of timeout loops and then return an error.
-static __inline__ int 
-flash_wait_for_controller (cyg_uint32 timeout) 
+static __inline__ int
+flash_wait_for_controller (cyg_uint32 timeout)
 CYGBLD_ATTRIB_SECTION(".2ram.flash_run_command");
 
-static __inline__ int 
+static __inline__ int
 flash_wait_for_controller (cyg_uint32 timeout)
 {
   while (!flash_controller_is_ready()){
@@ -128,34 +248,34 @@
 // Execute one command on the flash controller. This code should
 // probably not be in flash
 
-static int 
-flash_run_command(cyg_uint32 address, 
-                  cyg_uint32 command, 
-                  cyg_uint32 timeout) 
+static int
+flash_run_command(cyg_uint32 address,
+                  cyg_uint32 command,
+                  cyg_uint32 timeout)
 CYGBLD_ATTRIB_SECTION(".2ram.flash_run_command");
 
-static int 
-flash_run_command(cyg_uint32 address, 
-                  cyg_uint32 command, 
-                  cyg_uint32 timeout) 
+static int
+flash_run_command(cyg_uint32 address,
+                  cyg_uint32 command,
+                  cyg_uint32 timeout)
 {
   cyg_uint32 retcode;
   cyg_uint32 fsr;
   cyg_uint32 mask;
   cyg_uint32 page;
-  
-  page = ((cyg_uint32) address - (cyg_uint32) flash_info.start) / 
+
+  page = ((cyg_uint32) address - (cyg_uint32) flash_info.start) /
     flash_info.block_size;
-  
+
   // Wait for the last command to finish
   retcode = flash_wait_for_controller(timeout);
   if (retcode != FLASH_ERR_OK){
     return retcode;
   }
-  
+
   HAL_DISABLE_INTERRUPTS(mask);
-  
-  HAL_WRITE_UINT32(AT91_MC+AT91_MC_FCR, 
+
+  HAL_WRITE_UINT32(AT91_MC+AT91_MC_FCR,
                    command |
                    ((page & AT91_MC_FCR_PAGE_MASK) << AT91_MC_FCR_PAGE_SHIFT) |
                    AT91_MC_FCR_KEY);
@@ -179,15 +299,18 @@
   return FLASH_ERR_OK;
 }
 
+#endif
+
+
 // The flash is embedded in the CPU package. So return the chip
 // ID. This allows us to determine if the chip is one we support and
 // the size of the flash
-int flash_query(void *data) 
+int flash_query(void *data)
 {
   cyg_uint32 chipID1r;
-  
+
   HAL_READ_UINT32(AT91_DBG+AT91_DBG_C1R, chipID1r);
-  
+
   memcpy(data, &chipID1r, sizeof(chipID1r));
   return FLASH_ERR_OK;
 }
@@ -197,14 +320,13 @@
 // the number of blocks. The query function returns the chip ID 1
 // register which tells us about the CPU we are running on, the flash
 // size etc. Use this information to determine we have a valid setup.
-int 
+int
 flash_hwr_init(void){
 
   cyg_uint32 chipID1r;
   cyg_uint32 flash_mode;
-  cyg_uint8  fmcn;
   cyg_uint32 lock_bits;
-  
+
   flash_query (&chipID1r);
 
   if ((chipID1r & AT91_DBG_C1R_CPU_MASK) != AT91_DBG_C1R_ARM7TDMI)
@@ -215,10 +337,10 @@
       ((chipID1r & AT91_DBG_C1R_ARCH_MASK) != AT91_DBG_C1R_ARCH_AT91SAM7XC) &&
       ((chipID1r & AT91_DBG_C1R_ARCH_MASK) != AT91_DBG_C1R_ARCH_AT91SAM7SExx))
     goto out;
-  
+
   if ((chipID1r & AT91_DBG_C1R_FLASH_MASK) == AT91_DBG_C1R_FLASH_0K)
     goto out;
-  
+
 
   if ((chipID1r & AT91_DBG_C1R_NVPTYP_MASK) != AT91_DBG_C1R_NVPTYP_ROMFLASH)
   {
@@ -243,19 +365,20 @@
       flash_info.blocks = 1024;
       lock_bits = 16;
       break;
+    case AT91_DBG_C1R_FLASH_512K:
+	  flash_info.block_size = 256;
 #ifdef AT91_MC_FMR1
-		case AT91_DBG_C1R_FLASH_512K:
-		  flash_info.block_size = 256;
-		  flash_info.blocks = 1024;
-		  lock_bits = 16;
-		  (*flash_info.pf)("at91_flash: Only EFC0 is supported for writes and locks");
-		  //flash_info.blocks = 2048;
-		  //lock_bits = 32;
-		  break;
+	  flash_info.blocks = 2048;
+	  lock_bits = 32;
+#else
+	  flash_info.blocks = 1024;
+	  lock_bits = 16;
+	  (*flash_info.pf)("at91_flash: Only EFC0 is supported for writes and locks");
 #endif
-		default:
-		  goto out;
-	  }
+	  break;
+	default:
+	  goto out;
+	}
   } else {
 	  // if there is both flash & ROM then: ROM=AT91_DBG_C1R_FLASH, flash=AT91_DBG_C1R_FLASH2
 	  switch (chipID1r & AT91_DBG_C1R_FLASH2_MASK) {
@@ -279,44 +402,41 @@
 		  flash_info.blocks = 1024;
 		  lock_bits = 16;
 		  break;
-#ifdef AT91_MC_FMR1
 		case AT91_DBG_C1R_FLASH2_512K:
 		  flash_info.block_size = 256;
+#ifdef AT91_MC_FMR1
+		  flash_info.blocks = 2048;
+		  lock_bits = 32;
+#else
 		  flash_info.blocks = 1024;
 		  lock_bits = 16;
 		  (*flash_info.pf)("at91_flash: Only EFC0 is supported for writes and locks");
-		  //flash_info.blocks = 2048;
-		  //lock_bits = 32;
-		  break;
 #endif
-    default:
-      goto out;
-  }
+		  break;
+        default:
+          goto out;
+      }
   }
   flash_info.buffer_size = 0;
   flash_info.start = (void *) 0x00100000;
-  flash_info.end = (void *)(((cyg_uint32) flash_info.start) + 
+  flash_info.end = (void *)(((cyg_uint32) flash_info.start) +
                             flash_info.block_size * flash_info.blocks);
 #ifdef CYGBLD_DEV_FLASH_AT91_LOCKING
   sector_size = flash_info.block_size * flash_info.blocks / lock_bits;
 #endif
   // Set the FLASH clock to 1.5 microseconds based on the MCLK.  This
   // assumes the CPU is still running from the PLL clock as defined in
-  // the HAL CDL and the HAL startup code. 
-  fmcn = CYGNUM_HAL_ARM_AT91_CLOCK_SPEED * 1.5 / 1000000 + 0.999999; // We must round up!
+  // the HAL CDL and the HAL startup code.
   HAL_READ_UINT32(AT91_MC+AT91_MC_FMR, flash_mode);
   flash_mode = flash_mode & ~AT91_MC_FMR_FMCN_MASK;
-  flash_mode = flash_mode | (fmcn << AT91_MC_FMR_FMCN_SHIFT);
+  flash_mode = flash_mode | (AT91_FLASH_FMCN_VALUE << AT91_MC_FMR_FMCN_SHIFT);
   HAL_WRITE_UINT32(AT91_MC+AT91_MC_FMR, flash_mode);
 #ifdef AT91_MC_FMR1
-  HAL_READ_UINT32(AT91_MC+AT91_MC_FMR1, flash_mode);
-  flash_mode = flash_mode & ~AT91_MC_FMR_FMCN_MASK;
-  flash_mode = flash_mode | (fmcn << AT91_MC_FMR_FMCN_SHIFT);
   HAL_WRITE_UINT32(AT91_MC+AT91_MC_FMR1, flash_mode);
 #endif
-  
+
   return FLASH_ERR_OK;
-  
+
  out:
   (*flash_info.pf)("Can't identify FLASH, sorry, ChipID1 %x\n",
                    chipID1r );
@@ -326,26 +446,26 @@
 // Erase a block. The flash controller does not have a command to
 // erase a block. So instead we setup the controller to do a program
 // writing all 0xff with an erase operation first.
-int 
-flash_erase_block (volatile unsigned long block) 
+int
+flash_erase_block (volatile unsigned long block)
 {
   cyg_uint32 retcode;
   cyg_uint32 *buffer;
   cyg_uint32 *end;
-  
+
   buffer = (cyg_uint32 *) block;
   end = (cyg_uint32 *) (block + flash_info.block_size);
-  
-  while (buffer < end){ 
+
+  while (buffer < end){
     *buffer = (cyg_uint32) 0xffffffff;
     buffer++;
   }
-  
+
   flash_erase_before_write_enable();
-  retcode = flash_run_command(block, 
-                              AT91_MC_FCR_START_PROG, 
+  retcode = flash_run_command(block,
+                              AT91_MC_FCR_START_PROG,
                               FLASH_TIMEOUT);
-  
+
   return retcode;
 }
 
@@ -354,29 +474,29 @@
 // checks that these conditions are upheld. It would be possible to
 // perform extra reads and masking operation to support writing to
 // none word assigned addresses or not multiple or a word length.
-int 
+int
 flash_program_buf (volatile unsigned long addr, unsigned long *data, int len)
 {
   cyg_uint32 retcode;
   volatile unsigned long *target;
-  
+
   CYG_ASSERT(len % 4 == 0, "Only word writes allowed by current code");
   CYG_ASSERT(addr % 4 == 0, "Address must be word aligned for current code");
-  
+
   target = (volatile unsigned long *)addr;
-  
+
   while (len > 0) {
     *target = *data;
     data++;
     target++;
     len = len - sizeof(unsigned long);
   }
-  
+
   flash_erase_before_write_disable();
-  retcode = flash_run_command(addr, 
-                              AT91_MC_FCR_START_PROG, 
+  retcode = flash_run_command(addr,
+                              AT91_MC_FCR_START_PROG,
                               FLASH_TIMEOUT);
-  
+
   return retcode;
 }
 
@@ -390,15 +510,24 @@
   cyg_uint32 sector;
   cyg_uint32 retcode;
   cyg_uint32 status;
-  
-  sector = (((cyg_uint32) block) - (cyg_uint32) flash_info.start) / 
+
+  sector = (((cyg_uint32) block) - (cyg_uint32) flash_info.start) /
     sector_size;
- 
+
+#ifdef AT91_MC_FMR1  /* or in other words at91sam7x512 */
+    if (sector < SECTOR_AT_WITCH_WE_USE_THE_EFC1){
+        HAL_READ_UINT32(AT91_MC + AT91_MC_FSR, status);
+    } else {
+        HAL_READ_UINT32(AT91_MC + AT91_MC_FSR1, status);
+        sector = sector - SECTOR_AT_WITCH_WE_USE_THE_EFC1;
+    }
+#else
   HAL_READ_UINT32(AT91_MC + AT91_MC_FSR, status);
-  
+#endif
+
   if (status & (1 << (sector + 16))){
-      retcode = flash_run_command(block, 
-                                  AT91_MC_FCR_UNLOCK, 
+      retcode = flash_run_command(block,
+                                  AT91_MC_FCR_UNLOCK,
                                   FLASH_TIMEOUT);
       return retcode;
   } else {
@@ -415,24 +544,33 @@
   cyg_uint32 sector;
   cyg_uint32 retcode;
   cyg_uint32 status;
-  
-  sector = (((cyg_uint32) block) - (cyg_uint32) flash_info.start) / 
+
+  sector = (((cyg_uint32) block) - (cyg_uint32) flash_info.start) /
     sector_size;
 
+#ifdef AT91_MC_FMR1  /* or in other words at91sam7x512 */
+    if (sector < SECTOR_AT_WITCH_WE_USE_THE_EFC1){
+        HAL_READ_UINT32(AT91_MC + AT91_MC_FSR, status);
+    } else {
+        HAL_READ_UINT32(AT91_MC + AT91_MC_FSR1, status);
+        sector = sector - SECTOR_AT_WITCH_WE_USE_THE_EFC1;
+    }
+#else
   HAL_READ_UINT32(AT91_MC + AT91_MC_FSR, status);
-  
+#endif
+
   if (!(status & (1 << (sector + 16)))){
-      retcode = flash_run_command(block, 
-                                  AT91_MC_FCR_LOCK, 
+      retcode = flash_run_command(block,
+                                  AT91_MC_FCR_LOCK,
                                   FLASH_TIMEOUT);
-      
+
       return retcode;
   } else {
     return FLASH_ERR_OK;
   }
 }
-#endif 
-  
+#endif
+
 // Map a hardware status to a package error. NOP since the errors are
 // already mapped.
 int flash_hwr_map_error(int err){
Index: packages/hal/arm/at91/at91sam7s/current/ChangeLog
===================================================================
RCS file: /cvs/ecos/ecos/packages/hal/arm/at91/at91sam7s/current/ChangeLog,v
retrieving revision 1.21
diff -u -r1.21 ChangeLog
--- packages/hal/arm/at91/at91sam7s/current/ChangeLog	3 Nov 2008 08:40:01 -0000	1.21
+++ packages/hal/arm/at91/at91sam7s/current/ChangeLog	4 Jun 2009 07:30:50 -0000
@@ -1,3 +1,8 @@
+2009-06-03 Oliver Munz oli@snr.ch
+	* Fix the the problem of switching the PCM-settings if 
+	the PCM is allready up. And impruve the flash-controller 
+	programming. 
+
 2009-11-03  Gabor Toeroek <tgabor84@gmail.com>
 
 	* cdl/hal_arm_at91sam7s.cdl

Index: packages/hal/arm/at91/at91sam7s/current/include/hal_platform_setup.h
===================================================================
RCS file: /cvs/ecos/ecos/packages/hal/arm/at91/at91sam7s/current/include/hal_platform_setup.h,v
retrieving revision 1.5
diff -u -r1.5 hal_platform_setup.h
--- packages/hal/arm/at91/at91sam7s/current/include/hal_platform_setup.h	2 Sep 2008 05:37:51 -0000	1.5
+++ packages/hal/arm/at91/at91sam7s/current/include/hal_platform_setup.h	4 Jun 2009 07:30:50 -0000
@@ -43,10 +43,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,79 +56,109 @@
 #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
+#   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
-        ldr     r1,=(AT91_MC_FMR_1FWS)
-# else
+#       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
-        ldr     r1,=AT91_MC_FMR_0FWS
-# endif
+#      define AT91_PMC_FLASH_VALUE (AT91_MC_FMR_0FWS | (AT91_FLASH_FMCN_VALUE << AT91_MC_FMR_FMCN_SHIFT))
+#   endif
 #endif
+
+
+
+// Macro whit 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.
         .macro  _main_clock_init
 __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]
-
-#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     r2,=AT91_PMC_MOR_VALUE // Load our PMC settings in registers
+        ldr     r3,=AT91_PMC_PLLR_VALUE
+        ldr     r4,=AT91_PMC_MCKR_VALUE
+
+        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 +167,7 @@
         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 +178,16 @@
 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
 
Index: packages/hal/arm/at91/at91sam7s/current/include/plf_io.h
===================================================================
RCS file: /cvs/ecos/ecos/packages/hal/arm/at91/at91sam7s/current/include/plf_io.h,v
retrieving revision 1.10
diff -u -r1.10 plf_io.h
--- packages/hal/arm/at91/at91sam7s/current/include/plf_io.h	3 Nov 2008 08:40:01 -0000	1.10
+++ packages/hal/arm/at91/at91sam7s/current/include/plf_io.h	4 Jun 2009 07:30:50 -0000
@@ -41,9 +41,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####
@@ -62,7 +62,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
@@ -92,8 +92,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
@@ -108,7 +108,7 @@
 #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
@@ -175,16 +175,19 @@
 
 // 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
 
 //----------------------------------------------------------------------
@@ -199,9 +202,9 @@
 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
 
Index: packages/hal/arm/at91/var/current/ChangeLog
===================================================================
RCS file: /cvs/ecos/ecos/packages/hal/arm/at91/var/current/ChangeLog,v
retrieving revision 1.44
diff -u -r1.44 ChangeLog
--- packages/hal/arm/at91/var/current/ChangeLog	3 Nov 2008 08:39:26 -0000	1.44
+++ packages/hal/arm/at91/var/current/ChangeLog	4 Jun 2009 07:30:52 -0000
@@ -1,3 +1,9 @@
+2009-06-03 Oliver Munz oli@snr.ch
+	* Fix the a problem in the kernel delay_us, if the PIT is initalised
+	later then the periode. If the PIT has a big periode (after reset)
+	and has to be set to a lower periode one has to be sure that the counter
+	is lower then the periode value one want to set... 
+
 2008-11-03  Gabor Toeroek <tgabor84@gmail.com>
 
 	* include/var_io.h: Added defines for AT91SAM7SE.
    
Index: packages/hal/arm/at91/var/current/src/timer_pit.c
===================================================================
RCS file: /cvs/ecos/ecos/packages/hal/arm/at91/var/current/src/timer_pit.c,v
retrieving revision 1.4
diff -u -r1.4 timer_pit.c
--- packages/hal/arm/at91/var/current/src/timer_pit.c	20 Feb 2007 21:33:03 -0000	1.4
+++ packages/hal/arm/at91/var/current/src/timer_pit.c	4 Jun 2009 07:30:52 -0000
@@ -39,9 +39,9 @@
 //
 // Author(s):    asl, Oliver Munz
 // Contributors: asl, Oliver Munz
-// Date:         2006-02-12
+// Date:         2009-06-03
 // Purpose:      Clock support using the PIT
-// Description:  
+// Description:
 //
 //####DESCRIPTIONEND####
 //
@@ -57,21 +57,48 @@
 // -------------------------------------------------------------------------
 // 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 - 1) |  
-                   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);
+hal_clock_initialize(cyg_uint32 period){
+
+    cyg_uint32 ir;
+    cyg_uint32 pimr;
+
+    CYG_ASSERT(CYGNUM_HAL_INTERRUPT_RTC == CYGNUM_HAL_INTERRUPT_PITC,
+                "Invalid timer interrupt");
+    CYG_ASSERT(period <= AT91_PITC_VALUE_MASK,
+                "Invalid timer period");
+
+    pimr = (period - 1); /* This is what we want */
+    HAL_READ_UINT32(AT91_PITC + AT91_PITC_PIIR, ir); /* Counter */
+    ir = ir & AT91_PITC_VALUE_MASK; /* The current counts */
+
+    do { /* Test if the new PITC-Moduls is overrun by the counter */
+
+        if (ir > pimr){ /* If the counter is already to high */
+
+            pimr = (ir + 100) & AT91_PITC_VALUE_MASK; /* Set the comparator a head */
+            HAL_WRITE_UINT32((AT91_PITC + AT91_PITC_PIMR),
+                              pimr | AT91_PITC_PIMR_PITEN);
+        }
+        if (ir < (period - 1)){ /* If we can try it */
+
+            pimr = (period - 1); /* This is what we want */
+            /* Set the real Period Interval timer */
+            HAL_WRITE_UINT32((AT91_PITC + AT91_PITC_PIMR),
+                              pimr | AT91_PITC_PIMR_PITEN);
+        }
+        HAL_READ_UINT32(AT91_PITC + AT91_PITC_PIMR, pimr); /* The real value */
+        pimr = pimr & AT91_PITC_VALUE_MASK; /* Value */
+        HAL_READ_UINT32(AT91_PITC + AT91_PITC_PIIR, ir); /* Counter */
+        ir = ir & AT91_PITC_VALUE_MASK; /* The current counts */
+
+    } while (ir > (period -1) || pimr != (period - 1)); // Is it correct?
+
+    /* Enable interrupt */
+    HAL_WRITE_UINT32((AT91_PITC + AT91_PITC_PIMR), (period - 1) |
+                        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, ir);
 }
 
 // This routine is called during a clock interrupt.
@@ -80,14 +107,14 @@
 {
   cyg_uint32 reg;
   cyg_uint32 pimr;
-  
+
   CYG_ASSERT(period < AT91_PITC_VALUE_MASK, "Invalid HAL clock configuration");
-  
+
   // Check that the PIT has the right period.
   HAL_READ_UINT32((AT91_PITC + AT91_PITC_PIMR), pimr);
   if ((pimr & AT91_PITC_VALUE_MASK) != (period - 1)) {
-    HAL_WRITE_UINT32((AT91_PITC + AT91_PITC_PIMR), 
-                     (period - 1) |  
+    HAL_WRITE_UINT32((AT91_PITC + AT91_PITC_PIMR),
+                     (period - 1) |
                      AT91_PITC_PIMR_PITEN |
                      AT91_PITC_PIMR_PITIEN);
   }
@@ -104,14 +131,14 @@
 {
   cyg_uint32 ir;
   cyg_uint32 pimr;
-  
+
   // Check that the PIT is running. If not start it.
   HAL_READ_UINT32((AT91_PITC + AT91_PITC_PIMR),pimr);
   if (!(pimr & AT91_PITC_PIMR_PITEN)) {
-    HAL_WRITE_UINT32((AT91_PITC + AT91_PITC_PIMR), 
+    HAL_WRITE_UINT32((AT91_PITC + AT91_PITC_PIMR),
                      AT91_PITC_VALUE_MASK | AT91_PITC_PIMR_PITEN);
   }
-  
+
   HAL_READ_UINT32(AT91_PITC + AT91_PITC_PIIR, ir);
   *pvalue = ir & AT91_PITC_VALUE_MASK;
 }
@@ -126,23 +153,23 @@
   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) * 
+  ticks = (((cyg_uint64)usecs) *
            ((cyg_uint64)CYGNUM_HAL_ARM_AT91_CLOCK_SPEED))/16/1000000LL;
-  
-  // Calculate the wrap around period. 
+
+  // Calculate the wrap around period.
   HAL_READ_UINT32(AT91_PITC + AT91_PITC_PIMR, piv);
-  piv = (piv & AT91_PITC_VALUE_MASK) - 1; 
-  
+  piv = (piv & AT91_PITC_VALUE_MASK) - 1;
+
   hal_clock_read(&val1);
   while (ticks > 0) {
     hal_clock_read(&val2);
     if (val2 < val1)
       ticks -= ((piv + val2) - val1); //overflow occurred
-    else 
+    else
       ticks -= (val2 - val1);
     val1 = val2;
   }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]