]> rtime.felk.cvut.cz Git - mirosot.git/blobdiff - autodemo/timer3.c
Autodemo updated, timer routeines calculate proper values for given timer period.
[mirosot.git] / autodemo / timer3.c
index 259a3ece8704c8ed73bf3c01886e95e1beb6b450..a531debe274ff6f730fa278176046ea850d1f95a 100644 (file)
@@ -1,6 +1,7 @@
 #include <timer3.h>
 #include <mcu_regs.h>
 #include <cpu_def.h>
+#include <system_def.h>
 
 static volatile timer_t timer;
 
@@ -10,23 +11,44 @@ static void
 timer_isr(void)
 {
     timer++;
-    *TPU_TSR3 &= ~TSR2_TCFVm ; //reset overflow flag (clear interrupt)
+    //*TPU_TSR3 &= ~TSR2_TCFVm ; //reset overflow flag (clear interrupt)
+    *TPU_TSR3 &= ~TSR3_TCFVm & ~TSR3_TGFAm; //reset overflow and comare match flags
 }    
 
 //timer initialisation
 /*free running counter*/
-void init_timer3()
+int init_timer3(long long nsec)
 {
-    *SYS_MSTPCRA &= ~MSTPCRA_TPUm; // power TPU unit
-
-    *TPU_TCR3 =0x00 | 0x06;     //rising edge, f divided by 256
-    *TPU_TMDR3 =0x00;           // normal mode
-    *TPU_TSR3 &= ~TSR3_TCFVm ;  //reset overflow flag
-    *TPU_TIER3 |=TIER3_TCIEVm;  //enable overflow interrupt
-
-    *TPU_TSTR |=TSTR_CST3m;     //start timer
-
-    excptvec_set(52, timer_isr); 
+#define CPU_CYCLE_NSEC (1000000000/CPU_SYS_HZ)
+  long long timer_tick = CPU_CYCLE_NSEC;
+  int presc_ind = 0;
+  const signed char presc_tab[] = {0,1,2,3,6,5,7,-1};
+  long long nsec_scaled = nsec >> 16;
+  while (presc_ind < 8 &&
+         (timer_tick < nsec_scaled
+          || presc_tab[presc_ind] < 0)) {
+    presc_ind++;
+    timer_tick <<= 2;
+  }
+  if (timer_tick < nsec_scaled)
+    return -1;
+
+
+  *SYS_MSTPCRA &= ~MSTPCRA_TPUm; // power TPU unit
+  
+  *TPU_TCR3 = TCR3_CCLR0m | presc_tab[presc_ind]; //rising edge, cleared by TGA, prescaler is calculated
+  *TPU_TMDR3 =0x00;             // normal mode
+  *TPU_TIOR3L = TIOR3L_IOC1m;   // output 1 at compare match
+  *TPU_TSR3 &= ~TSR3_TCFVm & ~TSR3_TGFAm; //reset overflow and comare match flags
+  //*TPU_TIER3 |=TIER3_TCIEVm;    //enable overflow interrupt
+  *TPU_TIER3 |=TIER3_TGIEAm;    //enable compare match interrupt
+  *TPU_TGR3A = (unsigned)(nsec/timer_tick);
+
+  *TPU_TSTR |=TSTR_CST3m;       //start timer
+  
+  //excptvec_set(EXCPTVEC_TCI3V, timer_isr);  /* handle overflow interrupt */
+  excptvec_set(EXCPTVEC_TGI3A, timer_isr); /* handle TGRA match interrupt */
+  return 0;
 }
 
 timer_t get_timer()