User | Revision | Line number | New contents of line |
jp |
0:cf255d2aa92f
|
1
|
/*
|
jp |
2:98b11b7dd7b2
|
2
|
* Copyright or � or Copr. 2010, Thomas SOETE
|
jp |
0:cf255d2aa92f
|
3
|
*
|
jp |
0:cf255d2aa92f
|
4
|
* Author e-mail: thomas@soete.org
|
jp |
0:cf255d2aa92f
|
5
|
* Library website : http://mbed.org/users/Alkorin/libraries/SimpleLib/
|
jp |
0:cf255d2aa92f
|
6
|
*
|
jp |
0:cf255d2aa92f
|
7
|
* This software is governed by the CeCILL license under French law and
|
jp |
0:cf255d2aa92f
|
8
|
* abiding by the rules of distribution of free software. You can use,
|
jp |
0:cf255d2aa92f
|
9
|
* modify and/ or redistribute the software under the terms of the CeCILL
|
jp |
0:cf255d2aa92f
|
10
|
* license as circulated by CEA, CNRS and INRIA at the following URL
|
jp |
0:cf255d2aa92f
|
11
|
* "http://www.cecill.info".
|
jp |
0:cf255d2aa92f
|
12
|
*
|
jp |
0:cf255d2aa92f
|
13
|
* As a counterpart to the access to the source code and rights to copy,
|
jp |
0:cf255d2aa92f
|
14
|
* modify and redistribute granted by the license, users are provided only
|
jp |
0:cf255d2aa92f
|
15
|
* with a limited warranty and the software's author, the holder of the
|
jp |
0:cf255d2aa92f
|
16
|
* economic rights, and the successive licensors have only limited
|
jp |
0:cf255d2aa92f
|
17
|
* liability.
|
jp |
0:cf255d2aa92f
|
18
|
*
|
jp |
0:cf255d2aa92f
|
19
|
* In this respect, the user's attention is drawn to the risks associated
|
jp |
0:cf255d2aa92f
|
20
|
* with loading, using, modifying and/or developing or reproducing the
|
jp |
0:cf255d2aa92f
|
21
|
* software by the user in light of its specific status of free software,
|
jp |
0:cf255d2aa92f
|
22
|
* that may mean that it is complicated to manipulate, and that also
|
jp |
0:cf255d2aa92f
|
23
|
* therefore means that it is reserved for developers and experienced
|
jp |
0:cf255d2aa92f
|
24
|
* professionals having in-depth computer knowledge. Users are therefore
|
jp |
0:cf255d2aa92f
|
25
|
* encouraged to load and test the software's suitability as regards their
|
jp |
0:cf255d2aa92f
|
26
|
* requirements in conditions enabling the security of their systems and/or
|
jp |
0:cf255d2aa92f
|
27
|
* data to be ensured and, more generally, to use and operate it in the
|
jp |
0:cf255d2aa92f
|
28
|
* same conditions as regards security.
|
jp |
0:cf255d2aa92f
|
29
|
*
|
jp |
0:cf255d2aa92f
|
30
|
* The fact that you are presently reading this means that you have had
|
jp |
0:cf255d2aa92f
|
31
|
* knowledge of the CeCILL license and that you accept its terms.
|
jp |
0:cf255d2aa92f
|
32
|
*/
|
jp |
0:cf255d2aa92f
|
33
|
|
jp |
0:cf255d2aa92f
|
34
|
#ifndef __SIMPLELIB_TIMERS_H__
|
jp |
0:cf255d2aa92f
|
35
|
#define __SIMPLELIB_TIMERS_H__
|
jp |
0:cf255d2aa92f
|
36
|
|
jp |
0:cf255d2aa92f
|
37
|
#include "mbed_globals.h"
|
jp |
0:cf255d2aa92f
|
38
|
#include "interrupts.h"
|
jp |
0:cf255d2aa92f
|
39
|
|
jp |
0:cf255d2aa92f
|
40
|
/**********************************
|
jp |
0:cf255d2aa92f
|
41
|
* Simple Timers Managment *
|
jp |
0:cf255d2aa92f
|
42
|
**********************************
|
jp |
0:cf255d2aa92f
|
43
|
* The interrupt handler is : *
|
jp |
0:cf255d2aa92f
|
44
|
* TIMERn_INTERRUPT_HANDLER(void) *
|
jp |
0:cf255d2aa92f
|
45
|
**********************************/
|
jp |
0:cf255d2aa92f
|
46
|
|
jp |
0:cf255d2aa92f
|
47
|
/** Registers **/
|
jp |
0:cf255d2aa92f
|
48
|
#define TIMER0_BASE (LPC_TIM0)
|
jp |
0:cf255d2aa92f
|
49
|
#define TIMER1_BASE (LPC_TIM1)
|
jp |
0:cf255d2aa92f
|
50
|
#define TIMER2_BASE (LPC_TIM2)
|
jp |
0:cf255d2aa92f
|
51
|
#define TIMER3_BASE (LPC_TIM3)
|
jp |
0:cf255d2aa92f
|
52
|
#define TIMER_BASE(timer) TOKENPASTE2(timer,_BASE)
|
jp |
0:cf255d2aa92f
|
53
|
|
jp |
0:cf255d2aa92f
|
54
|
// Peripheral Clock Selection registers (See 4.7.3 p56)
|
jp |
0:cf255d2aa92f
|
55
|
#define TIMER0_PCLK_REG (LPC_SC->PCLKSEL0)
|
jp |
0:cf255d2aa92f
|
56
|
#define TIMER1_PCLK_REG (LPC_SC->PCLKSEL0)
|
jp |
0:cf255d2aa92f
|
57
|
#define TIMER2_PCLK_REG (LPC_SC->PCLKSEL1)
|
jp |
0:cf255d2aa92f
|
58
|
#define TIMER3_PCLK_REG (LPC_SC->PCLKSEL1)
|
jp |
0:cf255d2aa92f
|
59
|
#define TIMER_PCLK_REG(timer) TOKENPASTE2(timer,_PCLK_REG)
|
jp |
0:cf255d2aa92f
|
60
|
|
jp |
0:cf255d2aa92f
|
61
|
#define TIMER0_PCLK_OFFSET 2
|
jp |
0:cf255d2aa92f
|
62
|
#define TIMER1_PCLK_OFFSET 4
|
jp |
0:cf255d2aa92f
|
63
|
#define TIMER2_PCLK_OFFSET 12
|
jp |
0:cf255d2aa92f
|
64
|
#define TIMER3_PCLK_OFFSET 14
|
jp |
0:cf255d2aa92f
|
65
|
#define TIMER_PCLK_OFFSET(timer) TOKENPASTE2(timer,_PCLK_OFFSET)
|
jp |
0:cf255d2aa92f
|
66
|
|
jp |
0:cf255d2aa92f
|
67
|
/** Interrupt handlers **/
|
jp |
0:cf255d2aa92f
|
68
|
#define TIMER0_INTERRUPT_HANDLER TIMER_INTERRUPT_HANDLER(TIMER0)
|
jp |
0:cf255d2aa92f
|
69
|
#define TIMER1_INTERRUPT_HANDLER TIMER_INTERRUPT_HANDLER(TIMER1)
|
jp |
0:cf255d2aa92f
|
70
|
#define TIMER2_INTERRUPT_HANDLER TIMER_INTERRUPT_HANDLER(TIMER2)
|
jp |
0:cf255d2aa92f
|
71
|
#define TIMER3_INTERRUPT_HANDLER TIMER_INTERRUPT_HANDLER(TIMER3)
|
jp |
0:cf255d2aa92f
|
72
|
#define TIMER_INTERRUPT_HANDLER(timer) EXTERN_C void __IRQ TOKENPASTE2(timer,_IRQHandler)
|
jp |
0:cf255d2aa92f
|
73
|
|
jp |
0:cf255d2aa92f
|
74
|
/** Bits **/
|
jp |
0:cf255d2aa92f
|
75
|
// Power Control for Peripherals (PCONP, 4.8.7.1 p63)
|
jp |
0:cf255d2aa92f
|
76
|
#define TIMER0_PCONP_BIT 1
|
jp |
0:cf255d2aa92f
|
77
|
#define TIMER1_PCONP_BIT 2
|
jp |
0:cf255d2aa92f
|
78
|
#define TIMER2_PCONP_BIT 22
|
jp |
0:cf255d2aa92f
|
79
|
#define TIMER3_PCONP_BIT 23
|
jp |
0:cf255d2aa92f
|
80
|
|
jp |
0:cf255d2aa92f
|
81
|
// Match Control Register (TnMCR, 21.6.8 p496)
|
jp |
0:cf255d2aa92f
|
82
|
#define MATCH_INTERRUPT 1
|
jp |
0:cf255d2aa92f
|
83
|
#define MATCH_RESET 2
|
jp |
0:cf255d2aa92f
|
84
|
#define MATCH_STOP 4
|
jp |
0:cf255d2aa92f
|
85
|
#define MR0_OFFSET 0
|
jp |
0:cf255d2aa92f
|
86
|
#define MR1_OFFSET 3
|
jp |
0:cf255d2aa92f
|
87
|
#define MR2_OFFSET 6
|
jp |
0:cf255d2aa92f
|
88
|
#define MR3_OFFSET 9
|
jp |
0:cf255d2aa92f
|
89
|
|
jp |
0:cf255d2aa92f
|
90
|
// Interrupt Register (TnIR, 21.6.1, p493)
|
jp |
0:cf255d2aa92f
|
91
|
#define MR0_INT (1U << 0)
|
jp |
0:cf255d2aa92f
|
92
|
#define MR1_INT (1U << 1)
|
jp |
0:cf255d2aa92f
|
93
|
#define MR2_INT (1U << 2)
|
jp |
0:cf255d2aa92f
|
94
|
#define MR3_INT (1U << 3)
|
jp |
0:cf255d2aa92f
|
95
|
#define CR0_INT (1U << 4)
|
jp |
0:cf255d2aa92f
|
96
|
#define CR1_INT (1U << 5)
|
jp |
0:cf255d2aa92f
|
97
|
|
jp |
0:cf255d2aa92f
|
98
|
/** Macros **/
|
jp |
0:cf255d2aa92f
|
99
|
// Enable TIMERn
|
jp |
0:cf255d2aa92f
|
100
|
#define TIMER0_INIT() TIMER_INIT(TIMER0)
|
jp |
0:cf255d2aa92f
|
101
|
#define TIMER1_INIT() TIMER_INIT(TIMER1)
|
jp |
0:cf255d2aa92f
|
102
|
#define TIMER2_INIT() TIMER_INIT(TIMER2)
|
jp |
0:cf255d2aa92f
|
103
|
#define TIMER3_INIT() TIMER_INIT(TIMER3)
|
jp |
0:cf255d2aa92f
|
104
|
#define TIMER_INIT(timer) do { \
|
jp |
0:cf255d2aa92f
|
105
|
SET_BIT_VALUE(LPC_SC->PCONP, TOKENPASTE2(timer,_PCONP_BIT) , 1); /* Enable Timer */ \
|
jp |
0:cf255d2aa92f
|
106
|
TIMER_BASE(timer)->TCR = 0x2; /* Reset Timer, Table 427 p493 */ \
|
jp |
0:cf255d2aa92f
|
107
|
} while(0)
|
jp |
0:cf255d2aa92f
|
108
|
|
jp |
0:cf255d2aa92f
|
109
|
// Set Peripheral Clock
|
jp |
0:cf255d2aa92f
|
110
|
#define TIMER0_SETPCLK(clk) TIMER_SETPCLK(TIMER0, clk)
|
jp |
0:cf255d2aa92f
|
111
|
#define TIMER1_SETPCLK(clk) TIMER_SETPCLK(TIMER1, clk)
|
jp |
0:cf255d2aa92f
|
112
|
#define TIMER2_SETPCLK(clk) TIMER_SETPCLK(TIMER2, clk)
|
jp |
0:cf255d2aa92f
|
113
|
#define TIMER3_SETPCLK(clk) TIMER_SETPCLK(TIMER3, clk)
|
jp |
0:cf255d2aa92f
|
114
|
#define TIMER_SETPCLK(timer, clk) TIMER_PCLK_REG(timer) = ((TIMER_PCLK_REG(timer) & (~(3U << TIMER_PCLK_OFFSET(timer)))) | (clk << TIMER_PCLK_OFFSET(timer)))
|
jp |
0:cf255d2aa92f
|
115
|
|
jp |
0:cf255d2aa92f
|
116
|
// Set Prescale Register
|
jp |
0:cf255d2aa92f
|
117
|
#define TIMER0_SETPRESCALE(value) TIMER_SETPRESCALE(TIMER0, value)
|
jp |
0:cf255d2aa92f
|
118
|
#define TIMER1_SETPRESCALE(value) TIMER_SETPRESCALE(TIMER1, value)
|
jp |
0:cf255d2aa92f
|
119
|
#define TIMER2_SETPRESCALE(value) TIMER_SETPRESCALE(TIMER2, value)
|
jp |
0:cf255d2aa92f
|
120
|
#define TIMER3_SETPRESCALE(value) TIMER_SETPRESCALE(TIMER3, value)
|
jp |
0:cf255d2aa92f
|
121
|
#define TIMER_SETPRESCALE(timer, value) TIMER_BASE(timer)->PR = (value)
|
jp |
0:cf255d2aa92f
|
122
|
|
jp |
0:cf255d2aa92f
|
123
|
// Set Match Register (MR0-3, 21.6.7 p496)
|
jp |
0:cf255d2aa92f
|
124
|
#define TIMER0_SETMATCH(id, value) TIMER_SETMATCH(TIMER0, id, value)
|
jp |
0:cf255d2aa92f
|
125
|
#define TIMER1_SETMATCH(id, value) TIMER_SETMATCH(TIMER1, id, value)
|
jp |
0:cf255d2aa92f
|
126
|
#define TIMER2_SETMATCH(id, value) TIMER_SETMATCH(TIMER2, id, value)
|
jp |
0:cf255d2aa92f
|
127
|
#define TIMER3_SETMATCH(id, value) TIMER_SETMATCH(TIMER3, id, value)
|
jp |
0:cf255d2aa92f
|
128
|
#define TIMER_SETMATCH(timer, id, value) TIMER_BASE(timer)->TOKENPASTE2(MR,id) = (value)
|
jp |
0:cf255d2aa92f
|
129
|
|
jp |
0:cf255d2aa92f
|
130
|
// Set Match Control Register (TnMCR, 21.6.8 p496)
|
jp |
0:cf255d2aa92f
|
131
|
#define TIMER0_SETMATCHCONTROL(id, value) TIMER_SETMATCHCONTROL(TIMER0, id, value)
|
jp |
0:cf255d2aa92f
|
132
|
#define TIMER1_SETMATCHCONTROL(id, value) TIMER_SETMATCHCONTROL(TIMER1, id, value)
|
jp |
0:cf255d2aa92f
|
133
|
#define TIMER2_SETMATCHCONTROL(id, value) TIMER_SETMATCHCONTROL(TIMER2, id, value)
|
jp |
0:cf255d2aa92f
|
134
|
#define TIMER3_SETMATCHCONTROL(id, value) TIMER_SETMATCHCONTROL(TIMER3, id, value)
|
jp |
0:cf255d2aa92f
|
135
|
#define TIMER_SETMATCHCONTROL(timer, id, value) TIMER_BASE(timer)->MCR = (value) << (MR ## id ## _OFFSET)
|
jp |
0:cf255d2aa92f
|
136
|
|
jp |
0:cf255d2aa92f
|
137
|
// Enable interrupt for TIMERn
|
jp |
0:cf255d2aa92f
|
138
|
#define TIMER0_ENABLE_INTERRUPT() TIMER_ENABLE_INTERRUPT(TIMER0)
|
jp |
0:cf255d2aa92f
|
139
|
#define TIMER1_ENABLE_INTERRUPT() TIMER_ENABLE_INTERRUPT(TIMER1)
|
jp |
0:cf255d2aa92f
|
140
|
#define TIMER2_ENABLE_INTERRUPT() TIMER_ENABLE_INTERRUPT(TIMER2)
|
jp |
0:cf255d2aa92f
|
141
|
#define TIMER3_ENABLE_INTERRUPT() TIMER_ENABLE_INTERRUPT(TIMER3)
|
jp |
0:cf255d2aa92f
|
142
|
#define TIMER_ENABLE_INTERRUPT(timer) ENABLE_INTERRUPT(TOKENPASTE2(timer,_IRQn))
|
jp |
0:cf255d2aa92f
|
143
|
|
jp |
0:cf255d2aa92f
|
144
|
// Interrut Register (TnIR, 21.6.1, p493)
|
jp |
0:cf255d2aa92f
|
145
|
#define TIMER0_CLEAR_INTERRUPT(value) TIMER_CLEAR_INTERRUPT(TIMER0, value)
|
jp |
0:cf255d2aa92f
|
146
|
#define TIMER1_CLEAR_INTERRUPT(value) TIMER_CLEAR_INTERRUPT(TIMER1, value)
|
jp |
0:cf255d2aa92f
|
147
|
#define TIMER2_CLEAR_INTERRUPT(value) TIMER_CLEAR_INTERRUPT(TIMER2, value)
|
jp |
0:cf255d2aa92f
|
148
|
#define TIMER3_CLEAR_INTERRUPT(value) TIMER_CLEAR_INTERRUPT(TIMER3, value)
|
jp |
0:cf255d2aa92f
|
149
|
#define TIMER_CLEAR_INTERRUPT(timer, value) TIMER_BASE(timer)->IR = (value)
|
jp |
0:cf255d2aa92f
|
150
|
|
jp |
0:cf255d2aa92f
|
151
|
// Start Timer
|
jp |
0:cf255d2aa92f
|
152
|
#define TIMER0_START() TIMER_START(TIMER0)
|
jp |
0:cf255d2aa92f
|
153
|
#define TIMER1_START() TIMER_START(TIMER1)
|
jp |
0:cf255d2aa92f
|
154
|
#define TIMER2_START() TIMER_START(TIMER2)
|
jp |
0:cf255d2aa92f
|
155
|
#define TIMER3_START() TIMER_START(TIMER3)
|
jp |
0:cf255d2aa92f
|
156
|
#define TIMER_START(timer) TIMER_BASE(timer)->TCR = 0x1 /* Counter Enable, Table 427 p493*/
|
jp |
0:cf255d2aa92f
|
157
|
|
jp |
0:cf255d2aa92f
|
158
|
// Get Timer Value
|
jp |
0:cf255d2aa92f
|
159
|
#define TIMER0_VALUE() TIMER_VALUE(TIMER0)
|
jp |
0:cf255d2aa92f
|
160
|
#define TIMER1_VALUE() TIMER_VALUE(TIMER1)
|
jp |
0:cf255d2aa92f
|
161
|
#define TIMER2_VALUE() TIMER_VALUE(TIMER2)
|
jp |
0:cf255d2aa92f
|
162
|
#define TIMER3_VALUE() TIMER_VALUE(TIMER3)
|
jp |
0:cf255d2aa92f
|
163
|
#define TIMER_VALUE(timer) (TIMER_BASE(timer)->TC)
|
jp |
0:cf255d2aa92f
|
164
|
|
jp |
0:cf255d2aa92f
|
165
|
#endif |