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]

patch for timer_pit.c in at91 var - solves possible kernel-timer problem...


If the PIT is used as system-timer and the kernel does the initialisation of it late - may be after hanging a long time in a boot-monitor - then it's possible, that the kernel delay_us dont work korrekt. This is because the PIT looks at exact matches, and thus, if You set the compare-register while the counter is already higher, then You have a big counter reading as the couter periode for a long time and this must not be...

This patch will initalize the PIT in every circumstance correct and is important, because of the possible blocking of drivers that uese the delay_us from the kernel.


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	29 May 2009 10:49:56 -0000
@@ -39,9 +39,9 @@
 //
 // Author(s):    asl, Oliver Munz
 // Contributors: asl, Oliver Munz
-// Date:         2006-02-12
+// Date:         2009-05-29
 // Purpose:      Clock support using the PIT
-// Description:  
+// Description:
 //
 //####DESCRIPTIONEND####
 //
@@ -59,19 +59,42 @@
 void
 hal_clock_initialize(cyg_uint32 period)
 {
-  cyg_uint32 sr;
-  
+  cyg_uint32 ir;
+  cyg_uint32 pimr;
+
   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);
+  CYG_ASSERT(period < AT91_PITC_VALUE_MASK,
+             "Invalid timer period");
+
+  pimr = (period - 1); /* This is what we want */
+  do { /* Test if the new PITC-Moduls is overrun by the counter */
+
+	  HAL_READ_UINT32(AT91_PITC + AT91_PITC_PIIR, ir); /* Counter */
+	  ir = ir & AT91_PITC_VALUE_MASK; /* The current counts */
+
+	  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);
+	  }
+
+  } while (ir > (period -1) || pimr != (period - 1)); // Is it correct?
+
+  /* Enable interrupt */
+  HAL_WRITE_UINT32((AT91_PITC + AT91_PITC_PIMR),
+					  pimr | 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);
 }
 

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