-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathTimer32.c
173 lines (138 loc) · 4.86 KB
/
Timer32.c
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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
#include "msp.h"
#include "Timer32.h"
#include "Common.h"
#include "CortexM.h"
// Sections borrowed from Jonathan Valvano UTexas
extern uint32_t SystemCoreClock;
// NOTE: By default the MCLK is running at 3MHz
double systemTimer = 0;
void (*Timer32_1_PeriodicTask)(void); // user function
void (*Timer32_2_PeriodicTask)(void); // user function
static unsigned long timer1Period;
static unsigned long timer2Period;
///////////////////////////////////////////////////////
//
// Helper function
//
///////////////////////////////////////////////////////
unsigned long CalcPeriodFromFrequency (double Hz)
{
double period = 0.0;
period = (double)SystemCoreClock/Hz;
period = period; // we divide by 2 because we want an interrupt for both the rising edge and the falling edge
return (unsigned long) period;
}
BOOLEAN timeOut = FALSE;
// this will timeout after 1 millisecond
void MS_Timeout_Handler(void)
{
timeOut = TRUE;
}
// ***************** Timer32_1_Init ****************
// Activate Timer32 Timer 1 interrupts to run user task periodically
// Inputs: task is a pointer to a user function
// period in units (1/(bus clock)/div), 32 bits
// div is clock divider for Timer32 Timer 1
// T32DIV1 for input clock divider /1
// T32DIV16 for input clock divider /16
// T32DIV256 for input clock divider /256
// NOTE: The default clock is 3MHz
// Outputs: none
void Timer32_1_Init(void(*task)(void), unsigned long period, enum timer32divider div)
{
long sr;
timer1Period = period;
// default MCLK is 3MHz
// but set MCLK to 48 MHz
sr = StartCritical();
// unsigned long function
Timer32_1_PeriodicTask = task;
// timer reload value
// TIMER32_LOAD1
TIMER32_LOAD1 = period;
// clear Timer32 Timer 1 interrupt
// TIMER32_INTCLR1
TIMER32_INTCLR1 = 1;
// bits31-8=X...X, reserved
// bit7, timer 0=disable, 1=enable
// bit6, 0 = Timer is in free-running mode, 1=timer in periodic mode
// bit5, interrupt 0=disable, 1=enable
// bit4=X, reserved
// bits3-2=??, input clock divider according to parameter
// bit1, 0=16bit counter, 1=32-bit counter
// bit0, 1=one shot mode, 0=wrapping mode
// TIMER32_CONTROL1, enable, periodic, 32 bit counter
TIMER32_CONTROL1 |= (BIT7 | BIT6 | BIT1); //0xE2;
// interrupts enabled in the main program after all devices initialized
// NVIC_IPR6
NVIC_IPR6 = (NVIC_IPR6&0xFFFF00FF)|0x00004000; // priority 2
// enable interrupt 25 in NVIC, NVIC_ISER0
// NVIC_ISER0
NVIC_ISER0 |= BIT(25); // changed from 0x2000000
EndCritical(sr);
}
void T32_INT1_IRQHandler(void)
{
// acknowledge Timer32 Timer 1 interrupt
// TIMER32_INTCLR1
TIMER32_INTCLR1 |= 1;
// execute user task
(*Timer32_1_PeriodicTask)();
// timer reload value to start the timer again
// TIMER32_LOAD1
TIMER32_LOAD1 = timer1Period;
}
// ***************** Timer32_2_Init ****************
// Activate Timer32 Timer 2 interrupts to run user task periodically
// Inputs: task is a pointer to a user function
// period in units (1/(bus clock)/div), 32 bits
// div is clock divider for Timer32 Timer 1
// T32DIV1 for input clock divider /1
// T32DIV16 for input clock divider /16
// T32DIV256 for input clock divider /256
// NOTE: The default clock is 3MHz
// Outputs: none
void Timer32_2_Init(void(*task)(void), unsigned long period, enum timer32divider div)
{
long sr;
timer2Period = period;
// default MCLK is 3MHz
// but set MCLK to 48 MHz
sr = StartCritical();
// unsigned long function
// assigns the ISR
Timer32_2_PeriodicTask = task;
// timer reload value
// TIMER32_LOAD2
TIMER32_LOAD2 = period;
// clear Timer32 Timer 2 interrupt
// TIMER32_INTCLR2
TIMER32_INTCLR2 = 1;
// bits31-8=X...X, reserved
// bit7, timer 0=disable, 1=enable
// bit6, 0 = Timer is in free-running mode, 1=timer in periodic mode
// bit5, interrupt 0=disable, 1=enable
// bit4=X, reserved
// bits3-2=??, input clock divider according to parameter
// bit1, 0=16bit counter, 1=32-bit counter
// bit0, 1=one shot mode, 0=wrapping mode
//TIMER32_CONTROL2
TIMER32_CONTROL2 |= (BIT7 | BIT6 | BIT1); //0xE2;
// interrupts enabled in the main program after all devices initialized
NVIC_IPR6 = (NVIC_IPR6&0xFFFF00FF)|0x00004000; // priority 2
// enable interrupt 26 in NVIC, NVIC_ISER0
// NVIC_ISER0
NVIC_ISER0 |= BIT(26); // changed from 0x4000000;
EndCritical(sr);
}
void T32_INT2_IRQHandler(void)
{
// acknowledge Timer32 Timer 1 interrupt
// TIMER32_INTCLR2
TIMER32_INTCLR2 |= 1;
// execute user task
(*Timer32_2_PeriodicTask)();
// timer reload value
// TIMER32_LOAD2
TIMER32_LOAD2 = timer2Period;
}