@@ -107,6 +107,38 @@ HardwarePWM::HardwarePWM(NRF_PWM_Type* pwm) :
107
107
_pwm->PSEL .OUT [1 ] = 0xFFFFFFFFUL ;
108
108
}
109
109
110
+ void HardwarePWM::begin (void )
111
+ {
112
+ // Initialize Registers
113
+ _pwm->MODE = PWM_MODE_UPDOWN_Up;
114
+ _pwm->COUNTERTOP = _max_value; // default is 255 (8 bit), can be configured before begin()
115
+ _pwm->PRESCALER = _clock_div;
116
+ _pwm->DECODER = PWM_DECODER_LOAD_Individual;
117
+ _pwm->LOOP = 0 ;
118
+
119
+ _pwm->SEQ [0 ].PTR = (uint32_t ) _seq0;
120
+ _pwm->SEQ [0 ].CNT = MAX_CHANNELS; // default mode is Individual --> count must be 4
121
+ _pwm->SEQ [0 ].REFRESH = 0 ;
122
+ _pwm->SEQ [0 ].ENDDELAY = 0 ;
123
+
124
+ _pwm->SEQ [1 ].PTR = 0 ;
125
+ _pwm->SEQ [1 ].CNT = 0 ;
126
+ _pwm->SEQ [1 ].REFRESH = 0 ;
127
+ _pwm->SEQ [1 ].ENDDELAY = 0 ;
128
+
129
+ _pwm->ENABLE = 1 ;
130
+ }
131
+
132
+ void HardwarePWM::stop (void )
133
+ {
134
+ _pwm->ENABLE = 0 ;
135
+ }
136
+
137
+ bool HardwarePWM::enabled (void )
138
+ {
139
+ return _pwm->ENABLE ;
140
+ }
141
+
110
142
void HardwarePWM::setResolution (uint8_t bitnum)
111
143
{
112
144
setMaxValue ( bit (min8 (bitnum, 15 )) -1 );
@@ -124,6 +156,25 @@ void HardwarePWM::setClockDiv(uint8_t div)
124
156
_pwm->PRESCALER = _clock_div;
125
157
}
126
158
159
+ void HardwarePWM::_set_psel (int ch, uint32_t value)
160
+ {
161
+ // Must disable before changing PSEL
162
+ if ( enabled () )
163
+ {
164
+ _pwm->ENABLE = 0 ;
165
+ _pwm->PSEL .OUT [ch] = value;
166
+ _seq0[ch] = 0 ;
167
+ _pwm->ENABLE = 1 ;
168
+
169
+ // re-start sequence
170
+ if ( usedChannelCount () ) _pwm->TASKS_SEQSTART [0 ] = 1 ;
171
+ }else
172
+ {
173
+ _pwm->PSEL .OUT [ch] = value;
174
+ _seq0[ch] = 0 ;
175
+ }
176
+ }
177
+
127
178
/* *
128
179
* Add pin to this group.
129
180
* @param pin Pin to add
@@ -150,17 +201,7 @@ bool HardwarePWM::addPin(uint8_t pin)
150
201
pinMode (pin, OUTPUT);
151
202
digitalWrite (pin, LOW);
152
203
153
- // Must disable before changing PSEL
154
- if ( enabled () )
155
- {
156
- _pwm->ENABLE = 0 ;
157
- _pwm->PSEL .OUT [ch] = g_ADigitalPinMap[pin];
158
- _pwm->ENABLE = 1 ;
159
- _start ();
160
- }else
161
- {
162
- _pwm->PSEL .OUT [ch] = g_ADigitalPinMap[pin];
163
- }
204
+ _set_psel (ch, g_ADigitalPinMap[pin]);
164
205
165
206
return true ;
166
207
}
@@ -170,70 +211,21 @@ bool HardwarePWM::removePin(uint8_t pin)
170
211
int ch = pin2channel (pin);
171
212
VERIFY ( ch >= 0 );
172
213
173
- bool const en = enabled ();
174
-
175
- // Must disable before changing PSEL
176
- if ( en ) _pwm->ENABLE = 0 ;
177
-
178
- _pwm->PSEL .OUT [ch] = 0xFFFFFFFFUL ;
179
- _seq0[ch] = 0 ;
180
-
181
- if ( en ) _pwm->ENABLE = 1 ;
182
-
214
+ _set_psel (ch, 0xFFFFFFFFUL );
183
215
return true ;
184
216
}
185
217
186
- bool HardwarePWM::enabled (void )
187
- {
188
- return _pwm->ENABLE ;
189
- }
190
-
191
- void HardwarePWM::begin (void )
192
- {
193
- // Initialize Registers
194
- _pwm->MODE = PWM_MODE_UPDOWN_Up;
195
- _pwm->COUNTERTOP = _max_value; // default is 255 (8 bit), can be configured before begin()
196
- _pwm->PRESCALER = _clock_div;
197
- _pwm->DECODER = PWM_DECODER_LOAD_Individual;
198
- _pwm->LOOP = 0 ;
199
-
200
- _pwm->SEQ [0 ].PTR = (uint32_t ) _seq0;
201
- _pwm->SEQ [0 ].CNT = MAX_CHANNELS; // default mode is Individual --> count must be 4
202
- _pwm->SEQ [0 ].REFRESH = 0 ;
203
- _pwm->SEQ [0 ].ENDDELAY = 0 ;
204
-
205
- _pwm->SEQ [1 ].PTR = 0 ;
206
- _pwm->SEQ [1 ].CNT = 0 ;
207
- _pwm->SEQ [1 ].REFRESH = 0 ;
208
- _pwm->SEQ [1 ].ENDDELAY = 0 ;
209
-
210
- _pwm->ENABLE = 1 ;
211
- }
212
-
213
- void HardwarePWM::_start (void )
214
- {
215
- // update sequence count (depending on mode)
216
- // _pwm->SEQ[0].CNT = MAX_CHANNELS;
217
-
218
- // start sequence
219
- _pwm->TASKS_SEQSTART [0 ] = 1 ;
220
- }
221
-
222
- void HardwarePWM::stop (void )
223
- {
224
- _pwm->ENABLE = 0 ;
225
- }
226
-
227
218
bool HardwarePWM::writeChannel (uint8_t ch, uint16_t value, bool inverted)
228
219
{
229
220
VERIFY ( ch < MAX_CHANNELS );
230
221
231
222
_seq0[ch] = value | (inverted ? 0 : bit (15 ));
232
223
233
- // Start PWM if not already
224
+ // Initialize PWM if not already
234
225
if ( !enabled () ) begin ();
235
226
236
- _start ();
227
+ // start sequence
228
+ _pwm->TASKS_SEQSTART [0 ] = 1 ;
237
229
238
230
return true ;
239
231
}
0 commit comments