diff --git a/targets/TARGET_Freescale/TARGET_K20XX/pwmout_api.c b/targets/TARGET_Freescale/TARGET_K20XX/pwmout_api.c index 75015aa638..121518df8a 100644 --- a/targets/TARGET_Freescale/TARGET_K20XX/pwmout_api.c +++ b/targets/TARGET_Freescale/TARGET_K20XX/pwmout_api.c @@ -22,7 +22,8 @@ static float pwm_clock = 0; -void pwmout_init(pwmout_t* obj, PinName pin) { +void pwmout_init(pwmout_t *obj, PinName pin) +{ // determine the channel PWMName pwm = (PWMName)pinmap_peripheral(pin, PinMap_PWM); MBED_ASSERT(pwm != (PWMName)NC); @@ -36,8 +37,9 @@ void pwmout_init(pwmout_t* obj, PinName pin) { while (clkval > 1) { clkdiv++; clkval /= 2.0; - if (clkdiv == 7) + if (clkdiv == 7) { break; + } } pwm_clock = clkval; @@ -53,7 +55,7 @@ void pwmout_init(pwmout_t* obj, PinName pin) { ftm->MODE = FTM_MODE_FTMEN_MASK; ftm->SYNC = FTM_SYNC_CNTMIN_MASK; ftm->SYNCONF = FTM_SYNCONF_SYNCMODE_MASK | FTM_SYNCONF_SWSOC_MASK | FTM_SYNCONF_SWWRBUF_MASK; - + //Without SYNCEN set CnV does not seem to update ftm->COMBINE = FTM_COMBINE_SYNCEN0_MASK | FTM_COMBINE_SYNCEN1_MASK | FTM_COMBINE_SYNCEN2_MASK | FTM_COMBINE_SYNCEN3_MASK; @@ -64,60 +66,86 @@ void pwmout_init(pwmout_t* obj, PinName pin) { // default to 20ms: standard for servos, and fine for e.g. brightness control pwmout_period_ms(obj, 20); pwmout_write(obj, 0.0); - + // Wire pinout pinmap_pinout(pin, PinMap_PWM); } -void pwmout_free(pwmout_t* obj) {} +void pwmout_free(pwmout_t *obj) {} -void pwmout_write(pwmout_t* obj, float value) { +void pwmout_write(pwmout_t *obj, float value) +{ if (value < 0.0) { value = 0.0; } else if (value > 1.0) { value = 1.0; } - - while(*obj->SYNC & FTM_SYNC_SWSYNC_MASK); + + while (*obj->SYNC & FTM_SYNC_SWSYNC_MASK); *obj->CnV = (uint32_t)((float)(*obj->MOD + 1) * value); - *obj->SYNC |= FTM_SYNC_SWSYNC_MASK; + *obj->SYNC |= FTM_SYNC_SWSYNC_MASK; } -float pwmout_read(pwmout_t* obj) { - while(*obj->SYNC & FTM_SYNC_SWSYNC_MASK); +float pwmout_read(pwmout_t *obj) +{ + while (*obj->SYNC & FTM_SYNC_SWSYNC_MASK); float v = (float)(*obj->CnV) / (float)(*obj->MOD + 1); return (v > 1.0) ? (1.0) : (v); } -void pwmout_period(pwmout_t* obj, float seconds) { +void pwmout_period(pwmout_t *obj, float seconds) +{ pwmout_period_us(obj, seconds * 1000000.0f); } -void pwmout_period_ms(pwmout_t* obj, int ms) { +void pwmout_period_ms(pwmout_t *obj, int ms) +{ pwmout_period_us(obj, ms * 1000); } // Set the PWM period, keeping the duty cycle the same. -void pwmout_period_us(pwmout_t* obj, int us) { +void pwmout_period_us(pwmout_t *obj, int us) +{ float dc = pwmout_read(obj); *obj->MOD = (uint32_t)(pwm_clock * (float)us) - 1; *obj->SYNC |= FTM_SYNC_SWSYNC_MASK; pwmout_write(obj, dc); } -void pwmout_pulsewidth(pwmout_t* obj, float seconds) { +int pwmout_read_period_us(pwmout_t *obj) +{ + uint32_t tmp = 0; + if (pwm_clock > 0) { + tmp = ((*obj->MOD) + 1) / pwm_clock; + } + return tmp; +} + +void pwmout_pulsewidth(pwmout_t *obj, float seconds) +{ pwmout_pulsewidth_us(obj, seconds * 1000000.0f); } -void pwmout_pulsewidth_ms(pwmout_t* obj, int ms) { +void pwmout_pulsewidth_ms(pwmout_t *obj, int ms) +{ pwmout_pulsewidth_us(obj, ms * 1000); } -void pwmout_pulsewidth_us(pwmout_t* obj, int us) { +void pwmout_pulsewidth_us(pwmout_t *obj, int us) +{ *obj->CnV = (uint32_t)(pwm_clock * (float)us); *obj->SYNC |= FTM_SYNC_SWSYNC_MASK; } +int pwmout_read_pulsewidth_us(pwmout_t *obj) +{ + uint32_t tmp = 0; + if (pwm_clock > 0) { + tmp = (*obj->CnV) / pwm_clock; + } + return tmp; +} + const PinMap *pwmout_pinmap() { return PinMap_PWM;