-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathPWM.cpp
executable file
·145 lines (120 loc) · 5.02 KB
/
PWM.cpp
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
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software *
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA *
* *
***************************************************************************
* *
* (c) Copyright, 1997-2012, ANSR *
* *
***************************************************************************
* *
* Filename: PWM.cpp *
* *
***************************************************************************/
#include "armlib.h"
/// Reserve memory for the singleton object.
static PWM pwmSingletonObject;
/**
* Get a pointer to the PWM object.
*/
PWM *PWM::GetInstance()
{
return &pwmSingletonObject;
}
/**
* Configure the PWM subsystem with the desired PWM channel(s) and period.
* The duty cycle of all active channels defaults to 0%.
*
* @param pwmChannel one or more PWM channels logically ORed
* @param frequency PWM periodic rate in Hertz
*/
void PWM::Enable(PWMChannel pwmChannel, uint32_t frequency)
{
// Reset the PWM subsystem.
PWMTCR = PWMTCR_RESET;
// Set the pin select values required for each PWM channel.
if (pwmChannel & PWM1)
{
PINSEL0 |= (0x02 << 0);
PWMPCR |= PWMENA1;
} // END if
if (pwmChannel & PWM2)
{
PINSEL0 |= (0x02 << 14);
PWMPCR |= PWMENA2;
} // END if
if (pwmChannel & PWM3)
{
PINSEL0 |= (0x02 << 2);
PWMPCR |= PWMENA3;
} // END if
if (pwmChannel & PWM4)
{
PINSEL0 |= (0x02 << 16);
PWMPCR |= PWMENA4;
} // END if
if (pwmChannel & PWM5)
{
PINSEL1 |= (0x01 << 10);
PWMPCR |= PWMENA5;
} // END if
if (pwmChannel & PWM6)
{
PINSEL0 |= (0x02 << 18);
PWMPCR |= PWMENA6;
} // END if
// Set the prescalar to 0 so the counter matchs the clock.
PWMPR = 0x00000000;
// Reset PWMTC when it matches PWMMR0
PWMMCR = PWMMR0R;
// Set PWM 0 so it will match and reset at the desired period.
this->period = SystemControl::GetInstance()->GetPClock() / frequency;
PWMMR0 = period - 1;
// Latch all the match registers.
PWMLER = LER0_EN | LER1_EN | LER2_EN | LER3_EN | LER4_EN | LER5_EN | LER6_EN;
// Enable the counter and PWM subsystem.
PWMTCR = PWMTCR_COUNTER_ENABLE | PWMTCR_PWM_ENABLE;
}
/**
* Set the duty cycle of one or more PWM channels. The duty cycle is in
* units of 0.01%, i.e. 25% is 2500, 37.5% is 3750.
*
* @param pwmChannel one or more PWM channels logically ORed
* @param dutyCycle in units of 0.01 percent
* @param invertFlag when set true set the duty cycle of the OFF cycle
*/
void PWM::SetDutyCycle (PWMChannel pwmChannel, uint32_t dutyCycle, bool_t invertFlag)
{
uint32_t matchRegister;
if (invertFlag)
matchRegister = (this->period * (10000 - dutyCycle)) / 10000;
else
matchRegister = (this->period * dutyCycle) / 10000 ;
// Set the pin select values required for each PWM channel.
if (pwmChannel & PWM1)
PWMMR1 = matchRegister;
if (pwmChannel & PWM2)
PWMMR2 = matchRegister;
if (pwmChannel & PWM3)
PWMMR3 = matchRegister;
if (pwmChannel & PWM4)
PWMMR4 = matchRegister;
if (pwmChannel & PWM5)
PWMMR5 = matchRegister;
if (pwmChannel & PWM6)
PWMMR6 = matchRegister;
// Latch the match registers.
PWMLER = LER1_EN | LER2_EN | LER3_EN | LER4_EN | LER5_EN | LER6_EN;
}