Skip to content

Commit c3f8e34

Browse files
committed
refactor hardware pwm
1 parent cca5ada commit c3f8e34

File tree

3 files changed

+65
-67
lines changed

3 files changed

+65
-67
lines changed

cores/nRF5/HardwarePWM.cpp

Lines changed: 56 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
110142
void 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-
227218
bool 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
}

cores/nRF5/HardwarePWM.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,6 @@ class HardwarePWM
5757
uint16_t _max_value;
5858
uint8_t _clock_div;
5959

60-
void _start(void);
61-
6260
public:
6361
HardwarePWM(NRF_PWM_Type* pwm);
6462

@@ -82,9 +80,13 @@ class HardwarePWM
8280
return this->_owner_token == token;
8381
}
8482

83+
// Add a pin to PWM module
8584
bool addPin (uint8_t pin);
85+
86+
// Remove a pin from PWM module
8687
bool removePin (uint8_t pin);
8788

89+
// Get the mapped channel of a pin
8890
int pin2channel(uint8_t pin) const
8991
{
9092
pin = g_ADigitalPinMap[pin];
@@ -95,6 +97,7 @@ class HardwarePWM
9597
return (-1);
9698
}
9799

100+
// Check if pin is controlled by PWM
98101
bool checkPin(uint8_t pin) const
99102
{
100103
return pin2channel(pin) >= 0;
@@ -117,6 +120,9 @@ class HardwarePWM
117120
uint8_t freeChannelCount(void) const;
118121

119122
static void DebugOutput(Stream& logger);
123+
124+
private:
125+
void _set_psel(int ch, uint32_t value);
120126
};
121127

122128
extern HardwarePWM HwPWM0;

cores/nRF5/wiring_analog.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,8 @@ void analogWrite( uint32_t pin, uint32_t value )
9595
if ( HwPWMx[i]->isOwner(_analogToken) && HwPWMx[i]->addPin(pin) )
9696
{
9797
// successfully added the pin, so write the value also
98-
LOG_LV2("Analog", "Added pin %" PRIu32 " to already-owned PWM %d", pin, i);
9998
HwPWMx[i]->writePin(pin, value);
99+
LOG_LV2("Analog", "Added pin %" PRIu32 " to already-owned PWM %d", pin, i);
100100
return;
101101
}
102102
}

0 commit comments

Comments
 (0)