Skip to content

Commit 2aa67b8

Browse files
author
MateuszM
committed
Fix for issue #7707 PwmOut inverted
since obj->sequence = &obj->pulse and most significant bit of sequence denotes the polarity, we should set it.
1 parent e1d5019 commit 2aa67b8

File tree

1 file changed

+24
-11
lines changed

1 file changed

+24
-11
lines changed

targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_NRF52/pwmout_api.c

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,9 @@
5757
#define MAX_PWM_PERIOD_MS (MAX_PWM_PERIOD_US / 1000)
5858
#define MAX_PWM_PERIOD_S ((float) MAX_PWM_PERIOD_US / 1000000.0f)
5959

60+
/* Sequence bit that denotes the polarity of the pwm waveform. */
61+
#define SEQ_POLARITY_BIT (0x8000)
62+
6063
/* Allocate PWM instances. */
6164
static nrf_drv_pwm_t nordic_nrf5_pwm_instance[] = {
6265
#if PWM0_ENABLED
@@ -140,7 +143,7 @@ void pwmout_init(pwmout_t *obj, PinName pin)
140143
/* Get hardware instance from pinmap. */
141144
int instance = pin_instance_pwm(pin);
142145

143-
MBED_ASSERT(instance < (int)(sizeof(nordic_nrf5_pwm_instance) / sizeof(nrf_drv_pwm_t)));
146+
MBED_ASSERT(instance < (int) (sizeof(nordic_nrf5_pwm_instance) / sizeof(nrf_drv_pwm_t)));
144147

145148
/* Populate PWM object with default values. */
146149
obj->instance = instance;
@@ -153,6 +156,9 @@ void pwmout_init(pwmout_t *obj, PinName pin)
153156
obj->sequence.repeats = 0;
154157
obj->sequence.end_delay = 0;
155158

159+
/* Set active low logic. */
160+
obj->pulse |= SEQ_POLARITY_BIT;
161+
156162
/* Initialize PWM instance. */
157163
nordic_pwm_init(obj);
158164
}
@@ -184,17 +190,20 @@ void pwmout_write(pwmout_t *obj, float percent)
184190
/* Find counts based on period. */
185191
uint16_t pulse = obj->period * percent;
186192

193+
/* Clear sequence, but keep the polarity bit */
194+
obj->pulse &= SEQ_POLARITY_BIT;
195+
187196
/* Ensure we don't overcount. */
188-
obj->pulse = (pulse > MAX_PWM_COUNTERTOP) ? MAX_PWM_COUNTERTOP : pulse;
197+
obj->pulse |= (pulse > MAX_PWM_COUNTERTOP) ? MAX_PWM_COUNTERTOP : pulse;
189198

190199
/* Store actual percentage passed as parameter to avoid floating point rounding errors. */
191200
obj->percent = percent;
192201

193202
/* Set new duty-cycle. */
194203
ret_code_t result = nrf_drv_pwm_simple_playback(&nordic_nrf5_pwm_instance[obj->instance],
195-
&obj->sequence,
196-
1,
197-
NRF_DRV_PWM_FLAG_LOOP);
204+
&obj->sequence,
205+
1,
206+
NRF_DRV_PWM_FLAG_LOOP);
198207

199208
MBED_ASSERT(result == NRF_SUCCESS);
200209
}
@@ -266,10 +275,11 @@ void pwmout_period_us(pwmout_t *obj, int period)
266275
}
267276

268277
/* Scale new count based on stored duty-cycle and new period. */
269-
uint32_t pulse = (period * obj->pulse) / obj->period;
278+
uint32_t pulse = (period * (obj->pulse & ~SEQ_POLARITY_BIT)) / obj->period;
270279

271280
/* Store new values in object. */
272-
obj->pulse = pulse;
281+
obj->pulse &= SEQ_POLARITY_BIT;
282+
obj->pulse |= pulse;
273283
obj->period = period;
274284
obj->percent = (float) pulse / (float) period;
275285

@@ -287,8 +297,9 @@ void pwmout_pulsewidth(pwmout_t *obj, float pulse)
287297
DEBUG_PRINTF("pwmout_pulsewidt: %f\r\n", pulse);
288298

289299
/* Cap pulsewidth to period before setting it. */
290-
if ((pulse * 1000000) > (float) obj->pulse) {
291-
obj->pulse = obj->period;
300+
if ((pulse * 1000000) > (float) (obj->pulse & ~SEQ_POLARITY_BIT)) {
301+
obj->pulse &= SEQ_POLARITY_BIT;
302+
obj->pulse |= obj->period;
292303
pwmout_pulsewidth_us(obj, obj->pulse);
293304
} else {
294305
pwmout_pulsewidth_us(obj, pulse * 1000000);
@@ -306,7 +317,8 @@ void pwmout_pulsewidth_ms(pwmout_t *obj, int pulse)
306317

307318
/* Cap pulsewidth to period before setting it. */
308319
if ((pulse * 1000) > (int) obj->period) {
309-
obj->pulse = obj->period;
320+
obj->pulse &= SEQ_POLARITY_BIT;
321+
obj->pulse |= obj->period;
310322
pwmout_pulsewidth_us(obj, obj->pulse);
311323
} else {
312324
pwmout_pulsewidth_us(obj, pulse * 1000);
@@ -328,7 +340,8 @@ void pwmout_pulsewidth_us(pwmout_t *obj, int pulse)
328340
}
329341

330342
/* Store new values in object. */
331-
obj->pulse = pulse;
343+
obj->pulse &= SEQ_POLARITY_BIT;
344+
obj->pulse |= pulse;
332345
obj->percent = (float) pulse / (float) obj->period;
333346

334347
/* Restart instance with new values. */

0 commit comments

Comments
 (0)