@@ -107,6 +107,38 @@ HardwarePWM::HardwarePWM(NRF_PWM_Type* pwm) :
107107 _pwm->PSEL .OUT [1 ] = 0xFFFFFFFFUL ;
108108}
109109
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+
110142void HardwarePWM::setResolution (uint8_t bitnum)
111143{
112144 setMaxValue ( bit (min8 (bitnum, 15 )) -1 );
@@ -124,6 +156,25 @@ void HardwarePWM::setClockDiv(uint8_t div)
124156 _pwm->PRESCALER = _clock_div;
125157}
126158
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+
127178/* *
128179 * Add pin to this group.
129180 * @param pin Pin to add
@@ -150,17 +201,7 @@ bool HardwarePWM::addPin(uint8_t pin)
150201 pinMode (pin, OUTPUT);
151202 digitalWrite (pin, LOW);
152203
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]);
164205
165206 return true ;
166207}
@@ -170,70 +211,21 @@ bool HardwarePWM::removePin(uint8_t pin)
170211 int ch = pin2channel (pin);
171212 VERIFY ( ch >= 0 );
172213
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 );
183215 return true ;
184216}
185217
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-
227218bool HardwarePWM::writeChannel (uint8_t ch, uint16_t value, bool inverted)
228219{
229220 VERIFY ( ch < MAX_CHANNELS );
230221
231222 _seq0[ch] = value | (inverted ? 0 : bit (15 ));
232223
233- // Start PWM if not already
224+ // Initialize PWM if not already
234225 if ( !enabled () ) begin ();
235226
236- _start ();
227+ // start sequence
228+ _pwm->TASKS_SEQSTART [0 ] = 1 ;
237229
238230 return true ;
239231}
0 commit comments