--- /dev/null
+#include <timer3.h>
+#include <mcu_regs.h>
+#include <cpu_def.h>
+#include <system_def.h>
+
+static volatile timer_t timer;
+
+static void timer_isr(void) __attribute__ ((interrupt_handler));
+
+static void
+timer_isr(void)
+{
+ timer++;
+ //*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*/
+int init_timer3(long long nsec)
+{
+#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()
+{
+ return timer;
+}