summaryrefslogtreecommitdiff
path: root/arm9/src/timer3.c
blob: 4e7b03c72189bdfc7bacdd228718437c0dded52e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#include "timer3.h"

#include "OS_interrupt.h"
#include "OS_irqTable.h"
#include "OS_timer.h"
#include "OS_system.h"
#include "registers.h"

static BOOL timer3_needReset;
static vu64 timer3_counter;


THUMB_FUNC void Init_Timer3()
{
    timer3_counter = 0;
    timer3_needReset = FALSE;

    OS_SetTimerControl(OS_TIMER_3, 0);
    OS_SetTimerCount(OS_TIMER_3, 0);
    OS_SetTimerControl(OS_TIMER_3, REG_OS_TM3CNT_H_E_MASK | REG_OS_TM3CNT_H_I_MASK | OS_TIMER_PRESCALER_64); // start timer3 with f/64 and irq enable

    OS_SetIrqFunction(OS_IE_TIMER3, &CountUpTimer3);
    OS_EnableIrqMask(OS_IE_TIMER3); // irq on timer3 overflow
}


THUMB_FUNC void CountUpTimer3()
{
    timer3_counter++;

    if (timer3_needReset)
    {
        OS_SetTimerControl(OS_TIMER_3, 0);
        OS_SetTimerCount(OS_TIMER_3, 0);
        OS_SetTimerControl(OS_TIMER_3, REG_OS_TM3CNT_H_E_MASK | REG_OS_TM3CNT_H_I_MASK | OS_TIMER_PRESCALER_64);
        timer3_needReset = FALSE;
    }

    OS_SetIrqCheckFlag(OS_IE_TIMER3);
    OS_SetIrqFunction(OS_IE_TIMER3, &CountUpTimer3);
}

THUMB_FUNC u64 internal_GetTimer3Count()
{
    OSIntrMode intr_mode = OS_DisableInterrupts();

    vu16 timer3 = reg_OS_TM3CNT_L;
    vu64 counter = timer3_counter & 0x0000ffffffffffff;

    if (reg_OS_IF & OS_IE_TIMER3 && !(timer3 & 0x8000))
    {
        counter++;
    }

    OS_RestoreInterrupts(intr_mode);
    return (counter << 16) | timer3;
}

THUMB_FUNC u64 GetTimer3Count()
{
    return internal_GetTimer3Count();
}

THUMB_FUNC u64 Timer3CountToMilliSeconds(u64 count)
{
    return (count * 64) / (HW_SYSTEM_CLOCK / 1000);
}

THUMB_FUNC u64 Timer3CountToSeconds(u64 count)
{
    return (count * 64) / HW_SYSTEM_CLOCK;
}