#include <timer3.h>
#include <mcu_regs.h>
#include <cpu_def.h>
+#include <system_def.h>
static volatile timer_t timer;
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()