diff --git a/targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_NRF52/pwmout_api.c b/targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_NRF52/pwmout_api.c index f294ce935c..3db9cf58e0 100644 --- a/targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_NRF52/pwmout_api.c +++ b/targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_NRF52/pwmout_api.c @@ -57,6 +57,9 @@ #define MAX_PWM_PERIOD_MS (MAX_PWM_PERIOD_US / 1000) #define MAX_PWM_PERIOD_S ((float) MAX_PWM_PERIOD_US / 1000000.0f) +/* Sequence bit that denotes the polarity of the pwm waveform. */ +#define SEQ_POLARITY_BIT (0x8000) + /* Allocate PWM instances. */ static nrf_drv_pwm_t nordic_nrf5_pwm_instance[] = { #if PWM0_ENABLED @@ -140,7 +143,7 @@ void pwmout_init(pwmout_t *obj, PinName pin) /* Get hardware instance from pinmap. */ int instance = pin_instance_pwm(pin); - MBED_ASSERT(instance < (int)(sizeof(nordic_nrf5_pwm_instance) / sizeof(nrf_drv_pwm_t))); + MBED_ASSERT(instance < (int) (sizeof(nordic_nrf5_pwm_instance) / sizeof(nrf_drv_pwm_t))); /* Populate PWM object with default values. */ obj->instance = instance; @@ -153,6 +156,9 @@ void pwmout_init(pwmout_t *obj, PinName pin) obj->sequence.repeats = 0; obj->sequence.end_delay = 0; + /* Set active low logic. */ + obj->pulse |= SEQ_POLARITY_BIT; + /* Initialize PWM instance. */ nordic_pwm_init(obj); } @@ -184,17 +190,20 @@ void pwmout_write(pwmout_t *obj, float percent) /* Find counts based on period. */ uint16_t pulse = obj->period * percent; + /* Clear sequence, but keep the polarity bit */ + obj->pulse &= SEQ_POLARITY_BIT; + /* Ensure we don't overcount. */ - obj->pulse = (pulse > MAX_PWM_COUNTERTOP) ? MAX_PWM_COUNTERTOP : pulse; + obj->pulse |= (pulse > MAX_PWM_COUNTERTOP) ? MAX_PWM_COUNTERTOP : pulse; /* Store actual percentage passed as parameter to avoid floating point rounding errors. */ obj->percent = percent; /* Set new duty-cycle. */ ret_code_t result = nrf_drv_pwm_simple_playback(&nordic_nrf5_pwm_instance[obj->instance], - &obj->sequence, - 1, - NRF_DRV_PWM_FLAG_LOOP); + &obj->sequence, + 1, + NRF_DRV_PWM_FLAG_LOOP); MBED_ASSERT(result == NRF_SUCCESS); } @@ -266,10 +275,11 @@ void pwmout_period_us(pwmout_t *obj, int period) } /* Scale new count based on stored duty-cycle and new period. */ - uint32_t pulse = (period * obj->pulse) / obj->period; + uint32_t pulse = (period * (obj->pulse & ~SEQ_POLARITY_BIT)) / obj->period; /* Store new values in object. */ - obj->pulse = pulse; + obj->pulse &= SEQ_POLARITY_BIT; + obj->pulse |= pulse; obj->period = period; obj->percent = (float) pulse / (float) period; @@ -287,8 +297,9 @@ void pwmout_pulsewidth(pwmout_t *obj, float pulse) DEBUG_PRINTF("pwmout_pulsewidt: %f\r\n", pulse); /* Cap pulsewidth to period before setting it. */ - if ((pulse * 1000000) > (float) obj->pulse) { - obj->pulse = obj->period; + if ((pulse * 1000000) > (float) (obj->pulse & ~SEQ_POLARITY_BIT)) { + obj->pulse &= SEQ_POLARITY_BIT; + obj->pulse |= obj->period; pwmout_pulsewidth_us(obj, obj->pulse); } else { pwmout_pulsewidth_us(obj, pulse * 1000000); @@ -306,7 +317,8 @@ void pwmout_pulsewidth_ms(pwmout_t *obj, int pulse) /* Cap pulsewidth to period before setting it. */ if ((pulse * 1000) > (int) obj->period) { - obj->pulse = obj->period; + obj->pulse &= SEQ_POLARITY_BIT; + obj->pulse |= obj->period; pwmout_pulsewidth_us(obj, obj->pulse); } else { pwmout_pulsewidth_us(obj, pulse * 1000); @@ -328,7 +340,8 @@ void pwmout_pulsewidth_us(pwmout_t *obj, int pulse) } /* Store new values in object. */ - obj->pulse = pulse; + obj->pulse &= SEQ_POLARITY_BIT; + obj->pulse |= pulse; obj->percent = (float) pulse / (float) obj->period; /* Restart instance with new values. */