diff --git a/UNITTESTS/stubs/pwmout_api_stub.c b/UNITTESTS/stubs/pwmout_api_stub.c index cf9cce8f995..3da073b83d1 100644 --- a/UNITTESTS/stubs/pwmout_api_stub.c +++ b/UNITTESTS/stubs/pwmout_api_stub.c @@ -51,6 +51,11 @@ void pwmout_period_us(pwmout_t *obj, int us) { } +int pwmout_read_period_us(pwmout_t *obj) +{ + return 0; +} + void pwmout_pulsewidth(pwmout_t *obj, float seconds) { } @@ -63,4 +68,9 @@ void pwmout_pulsewidth_us(pwmout_t *obj, int us) { } +int pwmout_read_pulsewidth_us(pwmout_t *obj) +{ + return 0; +} + #endif // DEVICE_PWMOUT diff --git a/drivers/include/drivers/PwmOut.h b/drivers/include/drivers/PwmOut.h index a004ca09146..462c5760b91 100644 --- a/drivers/include/drivers/PwmOut.h +++ b/drivers/include/drivers/PwmOut.h @@ -110,6 +110,12 @@ class PwmOut { */ void period_us(int us); + /** Read the PWM period + * @returns + * The PWM period, specified in microseconds (int) + */ + int read_period_us(); + /** Set the PWM pulsewidth, specified in seconds (float), keeping the period the same. * @param seconds Change the pulse width of a PWM signal specified in seconds (float) */ @@ -125,6 +131,12 @@ class PwmOut { */ void pulsewidth_us(int us); + /** Read the PWM pulsewidth + * @returns + * The PWM pulsewith, specified in microseconds (int) + */ + int read_pulsewitdth_us(); + /** Suspend PWM operation * * Control the PWM state. This is primarily intended @@ -191,6 +203,7 @@ class PwmOut { bool _deep_sleep_locked; bool _initialized; float _duty_cycle; + int _period_us; #endif }; diff --git a/drivers/source/PwmOut.cpp b/drivers/source/PwmOut.cpp index 3470d38f455..ccada968ed7 100644 --- a/drivers/source/PwmOut.cpp +++ b/drivers/source/PwmOut.cpp @@ -30,7 +30,8 @@ PwmOut::PwmOut(PinName pin) : _pin(pin), _deep_sleep_locked(false), _initialized(false), - _duty_cycle(0) + _duty_cycle(0), + _period_us(0) { PwmOut::init(); } @@ -83,6 +84,14 @@ void PwmOut::period_us(int us) core_util_critical_section_exit(); } +int PwmOut::read_period_us() +{ + core_util_critical_section_enter(); + auto val = pwmout_read_period_us(&_pwm); + core_util_critical_section_exit(); + return val; +} + void PwmOut::pulsewidth(float seconds) { core_util_critical_section_enter(); @@ -104,11 +113,20 @@ void PwmOut::pulsewidth_us(int us) core_util_critical_section_exit(); } +int PwmOut::read_pulsewitdth_us() +{ + core_util_critical_section_enter(); + auto val = pwmout_read_pulsewidth_us(&_pwm); + core_util_critical_section_exit(); + return val; +} + void PwmOut::suspend() { core_util_critical_section_enter(); if (_initialized) { _duty_cycle = PwmOut::read(); + _period_us = PwmOut::read_period_us(); PwmOut::deinit(); } core_util_critical_section_exit(); @@ -120,6 +138,7 @@ void PwmOut::resume() if (!_initialized) { PwmOut::init(); PwmOut::write(_duty_cycle); + PwmOut::period_us(_period_us); } core_util_critical_section_exit(); } diff --git a/hal/include/hal/pwmout_api.h b/hal/include/hal/pwmout_api.h index 977f7c643a2..c606183931a 100644 --- a/hal/include/hal/pwmout_api.h +++ b/hal/include/hal/pwmout_api.h @@ -44,9 +44,11 @@ typedef struct pwmout_s pwmout_t; * * ::pwmout_period sets the PWM period specified in seconds, keeping the duty cycle the same * * ::pwmout_period_ms sets the PWM period specified in miliseconds, keeping the duty cycle the same * * ::pwmout_period_us sets the PWM period specified in microseconds, keeping the duty cycle the same + * * ::pwmout_read_period_us reads the PWM period specified in microseconds * * ::pwmout_pulsewidth sets the PWM pulsewidth specified in seconds, keeping the period the same * * ::pwmout_pulsewidth_ms sets the PWM pulsewidth specified in miliseconds, keeping the period the same * * ::pwmout_pulsewidth_us sets the PWM pulsewidth specified in microseconds, keeping the period the same + * * ::pwmout_read_pulsewidth_us read the PWM pulsewidth specified in microseconds * * The accuracy of the PWM is +/- 10% * * The PWM operations ::pwmout_write, ::pwmout_read, ::pwmout_read, ::pwmout_period_ms, ::pwmout_period_us * ::pwmout_pulsewidth, ::pwmout_pulsewidth_ms, ::pwmout_pulsewidth_us take less than 20us to complete @@ -125,6 +127,13 @@ void pwmout_period_ms(pwmout_t *obj, int ms); */ void pwmout_period_us(pwmout_t *obj, int us); +/** Read the PWM period specified in microseconds + * + * @param obj The pwmout object + * @return A int output period + */ +int pwmout_read_period_us(pwmout_t *obj); + /** Set the PWM pulsewidth specified in seconds, keeping the period the same. * * @param obj The pwmout object @@ -146,6 +155,13 @@ void pwmout_pulsewidth_ms(pwmout_t *obj, int ms); */ void pwmout_pulsewidth_us(pwmout_t *obj, int us); +/** Read the PWM pulsewidth specified in microseconds + * + * @param obj The pwmout object + * @return A int output pulsewitdth + */ +int pwmout_read_pulsewidth_us(pwmout_t *obj); + /** Get the pins that support PWM * * Return a PinMap array of pins that support PWM. diff --git a/targets/TARGET_Cypress/TARGET_PSOC6/cy_pwmout_api.c b/targets/TARGET_Cypress/TARGET_PSOC6/cy_pwmout_api.c index 6e83a81fcad..dee7cf2b252 100644 --- a/targets/TARGET_Cypress/TARGET_PSOC6/cy_pwmout_api.c +++ b/targets/TARGET_Cypress/TARGET_PSOC6/cy_pwmout_api.c @@ -74,6 +74,11 @@ void pwmout_period_us(pwmout_t *obj, int us) } } +int pwmout_read_period_us(pwmout_t *obj) +{ + return obj->period_us; +} + void pwmout_pulsewidth(pwmout_t *obj, float seconds) { pwmout_pulsewidth_us(obj, (int)(seconds * CY_US_PER_SECOND)); @@ -92,6 +97,11 @@ void pwmout_pulsewidth_us(pwmout_t *obj, int us) } } +int pwmout_read_pulsewidth_us(pwmout_t *obj) +{ + return obj->width_us; +} + const PinMap *pwmout_pinmap(void) { return PinMap_PWM_OUT; diff --git a/targets/TARGET_Freescale/TARGET_K20XX/pwmout_api.c b/targets/TARGET_Freescale/TARGET_K20XX/pwmout_api.c index 75015aa638e..3c7e25d7127 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 pwm_period = 0; + if (pwm_clock > 0) { + pwm_period = ((*obj->MOD) + 1) / pwm_clock; + } + return pwm_period; +} + +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 pwm_pulsewidth = 0; + if (pwm_clock > 0) { + pwm_pulsewidth = (*obj->CnV) / pwm_clock; + } + return pwm_pulsewidth; +} + const PinMap *pwmout_pinmap() { return PinMap_PWM; diff --git a/targets/TARGET_Freescale/TARGET_KLXX/pwmout_api.c b/targets/TARGET_Freescale/TARGET_KLXX/pwmout_api.c index 27570a52b2e..35bb782ccef 100644 --- a/targets/TARGET_Freescale/TARGET_KLXX/pwmout_api.c +++ b/targets/TARGET_Freescale/TARGET_KLXX/pwmout_api.c @@ -23,7 +23,8 @@ static float pwm_clock; -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); @@ -51,10 +52,11 @@ 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; unsigned int port = (unsigned int)pin >> PORT_SHIFT; unsigned int tpm_n = (pwm >> TPM_SHIFT); @@ -73,15 +75,16 @@ 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); + pwmout_write(obj, 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) { @@ -92,38 +95,63 @@ void pwmout_write(pwmout_t* obj, float value) { *obj->CNT = 0; } -float pwmout_read(pwmout_t* obj) { +float pwmout_read(pwmout_t *obj) +{ 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; pwmout_write(obj, dc); } -void pwmout_pulsewidth(pwmout_t* obj, float seconds) { +int pwmout_read_period_us(pwmout_t *obj) +{ + uint32_t pwm_period = 0; + if (pwm_clock > 0) { + pwm_period = ((*obj->MOD) + 1) / pwm_clock; + } + return pwm_period; +} + +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); } +int pwmout_read_pulsewidth_us(pwmout_t *obj) +{ + uint32_t pwm_pulsewidth = 0; + if (pwm_clock > 0) { + pwm_pulsewidth = (*obj->CnV) / pwm_clock; + } + return pwm_pulsewidth; +} + const PinMap *pwmout_pinmap() { return PinMap_PWM; diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/pwmout_api.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/pwmout_api.c index 848868eabfd..346b2d49001 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/pwmout_api.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/pwmout_api.c @@ -27,7 +27,7 @@ static float pwm_clock_mhz; /* Array of FTM peripheral base address. */ static FTM_Type *const ftm_addrs[] = FTM_BASE_PTRS; -void pwmout_init(pwmout_t* obj, PinName pin) +void pwmout_init(pwmout_t *obj, PinName pin) { PWMName pwm = (PWMName)pinmap_peripheral(pin, PinMap_PWM); MBED_ASSERT(pwm != (PWMName)NC); @@ -73,12 +73,12 @@ void pwmout_init(pwmout_t* obj, PinName pin) pinmap_pinout(pin, PinMap_PWM); } -void pwmout_free(pwmout_t* obj) +void pwmout_free(pwmout_t *obj) { FTM_Deinit(ftm_addrs[obj->pwm_name >> TPM_SHIFT]); } -void pwmout_write(pwmout_t* obj, float value) +void pwmout_write(pwmout_t *obj, float value) { if (value < 0.0f) { value = 0.0f; @@ -96,30 +96,31 @@ void pwmout_write(pwmout_t* obj, float value) FTM_SetSoftwareTrigger(base, true); } -float pwmout_read(pwmout_t* obj) +float pwmout_read(pwmout_t *obj) { FTM_Type *base = ftm_addrs[obj->pwm_name >> TPM_SHIFT]; uint16_t count = (base->CONTROLS[obj->pwm_name & 0xF].CnV) & FTM_CnV_VAL_MASK; uint16_t mod = base->MOD & FTM_MOD_MOD_MASK; - if (mod == 0) + if (mod == 0) { return 0.0; + } float v = (float)(count) / (float)(mod); return (v > 1.0f) ? (1.0f) : (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) { FTM_Type *base = ftm_addrs[obj->pwm_name >> TPM_SHIFT]; float dc = pwmout_read(obj); @@ -129,17 +130,27 @@ void pwmout_period_us(pwmout_t* obj, int us) pwmout_write(obj, dc); } -void pwmout_pulsewidth(pwmout_t* obj, float seconds) +int pwmout_read_period_us(pwmout_t *obj) +{ + uint32_t pwm_period = 0; + if (pwm_clock_mhz > 0) { + FTM_Type *base = ftm_addrs[obj->pwm_name >> TPM_SHIFT]; + pwm_period = ((base->MOD) + 1) / pwm_clock_mhz; + } + return pwm_period; +} + +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) { FTM_Type *base = ftm_addrs[obj->pwm_name >> TPM_SHIFT]; uint32_t value = (uint32_t)(pwm_clock_mhz * (float)us); @@ -150,6 +161,16 @@ void pwmout_pulsewidth_us(pwmout_t* obj, int us) FTM_SetSoftwareTrigger(base, true); } +int pwmout_read_pulsewidth_us(pwmout_t *obj) +{ + uint32_t pwm_pulsewidth = 0; + if (pwm_clock_mhz > 0) { + FTM_Type *base = ftm_addrs[obj->pwm_name >> TPM_SHIFT]; + pwm_pulsewidth = (base->CONTROLS[obj->pwm_name & 0xF].CnV) / pwm_clock_mhz; + } + return pwm_pulsewidth; +} + const PinMap *pwmout_pinmap() { return PinMap_PWM; diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K82F/pwmout_api.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K82F/pwmout_api.c index 848868eabfd..346b2d49001 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K82F/pwmout_api.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K82F/pwmout_api.c @@ -27,7 +27,7 @@ static float pwm_clock_mhz; /* Array of FTM peripheral base address. */ static FTM_Type *const ftm_addrs[] = FTM_BASE_PTRS; -void pwmout_init(pwmout_t* obj, PinName pin) +void pwmout_init(pwmout_t *obj, PinName pin) { PWMName pwm = (PWMName)pinmap_peripheral(pin, PinMap_PWM); MBED_ASSERT(pwm != (PWMName)NC); @@ -73,12 +73,12 @@ void pwmout_init(pwmout_t* obj, PinName pin) pinmap_pinout(pin, PinMap_PWM); } -void pwmout_free(pwmout_t* obj) +void pwmout_free(pwmout_t *obj) { FTM_Deinit(ftm_addrs[obj->pwm_name >> TPM_SHIFT]); } -void pwmout_write(pwmout_t* obj, float value) +void pwmout_write(pwmout_t *obj, float value) { if (value < 0.0f) { value = 0.0f; @@ -96,30 +96,31 @@ void pwmout_write(pwmout_t* obj, float value) FTM_SetSoftwareTrigger(base, true); } -float pwmout_read(pwmout_t* obj) +float pwmout_read(pwmout_t *obj) { FTM_Type *base = ftm_addrs[obj->pwm_name >> TPM_SHIFT]; uint16_t count = (base->CONTROLS[obj->pwm_name & 0xF].CnV) & FTM_CnV_VAL_MASK; uint16_t mod = base->MOD & FTM_MOD_MOD_MASK; - if (mod == 0) + if (mod == 0) { return 0.0; + } float v = (float)(count) / (float)(mod); return (v > 1.0f) ? (1.0f) : (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) { FTM_Type *base = ftm_addrs[obj->pwm_name >> TPM_SHIFT]; float dc = pwmout_read(obj); @@ -129,17 +130,27 @@ void pwmout_period_us(pwmout_t* obj, int us) pwmout_write(obj, dc); } -void pwmout_pulsewidth(pwmout_t* obj, float seconds) +int pwmout_read_period_us(pwmout_t *obj) +{ + uint32_t pwm_period = 0; + if (pwm_clock_mhz > 0) { + FTM_Type *base = ftm_addrs[obj->pwm_name >> TPM_SHIFT]; + pwm_period = ((base->MOD) + 1) / pwm_clock_mhz; + } + return pwm_period; +} + +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) { FTM_Type *base = ftm_addrs[obj->pwm_name >> TPM_SHIFT]; uint32_t value = (uint32_t)(pwm_clock_mhz * (float)us); @@ -150,6 +161,16 @@ void pwmout_pulsewidth_us(pwmout_t* obj, int us) FTM_SetSoftwareTrigger(base, true); } +int pwmout_read_pulsewidth_us(pwmout_t *obj) +{ + uint32_t pwm_pulsewidth = 0; + if (pwm_clock_mhz > 0) { + FTM_Type *base = ftm_addrs[obj->pwm_name >> TPM_SHIFT]; + pwm_pulsewidth = (base->CONTROLS[obj->pwm_name & 0xF].CnV) / pwm_clock_mhz; + } + return pwm_pulsewidth; +} + const PinMap *pwmout_pinmap() { return PinMap_PWM; diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL27Z/pwmout_api.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL27Z/pwmout_api.c index 110d40a5d18..87b9c6d9720 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL27Z/pwmout_api.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL27Z/pwmout_api.c @@ -27,7 +27,7 @@ static float pwm_clock_mhz; /* Array of TPM peripheral base address. */ static TPM_Type *const tpm_addrs[] = TPM_BASE_PTRS; -void pwmout_init(pwmout_t* obj, PinName pin) +void pwmout_init(pwmout_t *obj, PinName pin) { PWMName pwm = (PWMName)pinmap_peripheral(pin, PinMap_PWM); MBED_ASSERT(pwm != (PWMName)NC); @@ -72,12 +72,12 @@ void pwmout_init(pwmout_t* obj, PinName pin) pinmap_pinout(pin, PinMap_PWM); } -void pwmout_free(pwmout_t* obj) +void pwmout_free(pwmout_t *obj) { TPM_Deinit(tpm_addrs[obj->pwm_name >> TPM_SHIFT]); } -void pwmout_write(pwmout_t* obj, float value) +void pwmout_write(pwmout_t *obj, float value) { if (value < 0.0f) { value = 0.0f; @@ -93,30 +93,31 @@ void pwmout_write(pwmout_t* obj, float value) base->CNT = 0; } -float pwmout_read(pwmout_t* obj) +float pwmout_read(pwmout_t *obj) { TPM_Type *base = tpm_addrs[obj->pwm_name >> TPM_SHIFT]; uint16_t count = (base->CONTROLS[obj->pwm_name & 0xF].CnV) & TPM_CnV_VAL_MASK; uint16_t mod = base->MOD & TPM_MOD_MOD_MASK; - if (mod == 0) + if (mod == 0) { return 0.0; + } float v = (float)(count) / (float)(mod); return (v > 1.0f) ? (1.0f) : (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) { TPM_Type *base = tpm_addrs[obj->pwm_name >> TPM_SHIFT]; float dc = pwmout_read(obj); @@ -126,17 +127,27 @@ void pwmout_period_us(pwmout_t* obj, int us) pwmout_write(obj, dc); } -void pwmout_pulsewidth(pwmout_t* obj, float seconds) +int pwmout_read_period_us(pwmout_t *obj) +{ + uint32_t pwm_period = 0; + if (pwm_clock_mhz > 0) { + TPM_Type *base = tpm_addrs[obj->pwm_name >> TPM_SHIFT]; + pwm_period = ((base->MOD) + 1) / pwm_clock_mhz; + } + return pwm_period; +} + +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) { TPM_Type *base = tpm_addrs[obj->pwm_name >> TPM_SHIFT]; uint32_t value = (uint32_t)(pwm_clock_mhz * (float)us); @@ -145,6 +156,16 @@ void pwmout_pulsewidth_us(pwmout_t* obj, int us) base->CONTROLS[obj->pwm_name & 0xF].CnV = value; } +int pwmout_read_pulsewidth_us(pwmout_t *obj) +{ + uint32_t pwm_pulsewidth = 0; + if (pwm_clock_mhz > 0) { + TPM_Type *base = tpm_addrs[obj->pwm_name >> TPM_SHIFT]; + pwm_pulsewidth = (base->CONTROLS[obj->pwm_name & 0xF].CnV) / pwm_clock_mhz; + } + return pwm_pulsewidth; +} + const PinMap *pwmout_pinmap() { return PinMap_PWM; diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL43Z/pwmout_api.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL43Z/pwmout_api.c index 110d40a5d18..87b9c6d9720 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL43Z/pwmout_api.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL43Z/pwmout_api.c @@ -27,7 +27,7 @@ static float pwm_clock_mhz; /* Array of TPM peripheral base address. */ static TPM_Type *const tpm_addrs[] = TPM_BASE_PTRS; -void pwmout_init(pwmout_t* obj, PinName pin) +void pwmout_init(pwmout_t *obj, PinName pin) { PWMName pwm = (PWMName)pinmap_peripheral(pin, PinMap_PWM); MBED_ASSERT(pwm != (PWMName)NC); @@ -72,12 +72,12 @@ void pwmout_init(pwmout_t* obj, PinName pin) pinmap_pinout(pin, PinMap_PWM); } -void pwmout_free(pwmout_t* obj) +void pwmout_free(pwmout_t *obj) { TPM_Deinit(tpm_addrs[obj->pwm_name >> TPM_SHIFT]); } -void pwmout_write(pwmout_t* obj, float value) +void pwmout_write(pwmout_t *obj, float value) { if (value < 0.0f) { value = 0.0f; @@ -93,30 +93,31 @@ void pwmout_write(pwmout_t* obj, float value) base->CNT = 0; } -float pwmout_read(pwmout_t* obj) +float pwmout_read(pwmout_t *obj) { TPM_Type *base = tpm_addrs[obj->pwm_name >> TPM_SHIFT]; uint16_t count = (base->CONTROLS[obj->pwm_name & 0xF].CnV) & TPM_CnV_VAL_MASK; uint16_t mod = base->MOD & TPM_MOD_MOD_MASK; - if (mod == 0) + if (mod == 0) { return 0.0; + } float v = (float)(count) / (float)(mod); return (v > 1.0f) ? (1.0f) : (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) { TPM_Type *base = tpm_addrs[obj->pwm_name >> TPM_SHIFT]; float dc = pwmout_read(obj); @@ -126,17 +127,27 @@ void pwmout_period_us(pwmout_t* obj, int us) pwmout_write(obj, dc); } -void pwmout_pulsewidth(pwmout_t* obj, float seconds) +int pwmout_read_period_us(pwmout_t *obj) +{ + uint32_t pwm_period = 0; + if (pwm_clock_mhz > 0) { + TPM_Type *base = tpm_addrs[obj->pwm_name >> TPM_SHIFT]; + pwm_period = ((base->MOD) + 1) / pwm_clock_mhz; + } + return pwm_period; +} + +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) { TPM_Type *base = tpm_addrs[obj->pwm_name >> TPM_SHIFT]; uint32_t value = (uint32_t)(pwm_clock_mhz * (float)us); @@ -145,6 +156,16 @@ void pwmout_pulsewidth_us(pwmout_t* obj, int us) base->CONTROLS[obj->pwm_name & 0xF].CnV = value; } +int pwmout_read_pulsewidth_us(pwmout_t *obj) +{ + uint32_t pwm_pulsewidth = 0; + if (pwm_clock_mhz > 0) { + TPM_Type *base = tpm_addrs[obj->pwm_name >> TPM_SHIFT]; + pwm_pulsewidth = (base->CONTROLS[obj->pwm_name & 0xF].CnV) / pwm_clock_mhz; + } + return pwm_pulsewidth; +} + const PinMap *pwmout_pinmap() { return PinMap_PWM; diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KW41Z/pwmout_api.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KW41Z/pwmout_api.c index 83de4f25673..31b953c0419 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KW41Z/pwmout_api.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KW41Z/pwmout_api.c @@ -27,7 +27,7 @@ static float pwm_clock_mhz; /* Array of TPM peripheral base address. */ static TPM_Type *const tpm_addrs[] = TPM_BASE_PTRS; -void pwmout_init(pwmout_t* obj, PinName pin) +void pwmout_init(pwmout_t *obj, PinName pin) { PWMName pwm = (PWMName)pinmap_peripheral(pin, PinMap_PWM); MBED_ASSERT(pwm != (PWMName)NC); @@ -72,12 +72,12 @@ void pwmout_init(pwmout_t* obj, PinName pin) pinmap_pinout(pin, PinMap_PWM); } -void pwmout_free(pwmout_t* obj) +void pwmout_free(pwmout_t *obj) { TPM_Deinit(tpm_addrs[obj->pwm_name >> TPM_SHIFT]); } -void pwmout_write(pwmout_t* obj, float value) +void pwmout_write(pwmout_t *obj, float value) { if (value < 0.0f) { value = 0.0f; @@ -93,30 +93,31 @@ void pwmout_write(pwmout_t* obj, float value) base->CNT = 0; } -float pwmout_read(pwmout_t* obj) +float pwmout_read(pwmout_t *obj) { TPM_Type *base = tpm_addrs[obj->pwm_name >> TPM_SHIFT]; uint16_t count = (base->CONTROLS[obj->pwm_name & 0xF].CnV) & TPM_CnV_VAL_MASK; uint16_t mod = base->MOD & TPM_MOD_MOD_MASK; - if (mod == 0) + if (mod == 0) { return 0.0; + } float v = (float)(count) / (float)(mod); return (v > 1.0f) ? (1.0f) : (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) { TPM_Type *base = tpm_addrs[obj->pwm_name >> TPM_SHIFT]; float dc = pwmout_read(obj); @@ -126,17 +127,27 @@ void pwmout_period_us(pwmout_t* obj, int us) pwmout_write(obj, dc); } -void pwmout_pulsewidth(pwmout_t* obj, float seconds) +int pwmout_read_period_us(pwmout_t *obj) +{ + uint32_t pwm_period = 0; + if (pwm_clock_mhz > 0) { + TPM_Type *base = tpm_addrs[obj->pwm_name >> TPM_SHIFT]; + pwm_period = ((base->MOD) + 1) / pwm_clock_mhz; + } + return pwm_period; +} + +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) { TPM_Type *base = tpm_addrs[obj->pwm_name >> TPM_SHIFT]; uint32_t value = (uint32_t)(pwm_clock_mhz * (float)us); @@ -145,6 +156,16 @@ void pwmout_pulsewidth_us(pwmout_t* obj, int us) base->CONTROLS[obj->pwm_name & 0xF].CnV = value; } +int pwmout_read_pulsewidth_us(pwmout_t *obj) +{ + uint32_t pwm_pulsewidth = 0; + if (pwm_clock_mhz > 0) { + TPM_Type *base = tpm_addrs[obj->pwm_name >> TPM_SHIFT]; + pwm_pulsewidth = (base->CONTROLS[obj->pwm_name & 0xF].CnV) / pwm_clock_mhz; + } + return pwm_pulsewidth; +} + const PinMap *pwmout_pinmap() { return PinMap_PWM; diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K22F/pwmout_api.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K22F/pwmout_api.c index 848868eabfd..6efe704b14c 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K22F/pwmout_api.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K22F/pwmout_api.c @@ -27,7 +27,7 @@ static float pwm_clock_mhz; /* Array of FTM peripheral base address. */ static FTM_Type *const ftm_addrs[] = FTM_BASE_PTRS; -void pwmout_init(pwmout_t* obj, PinName pin) +void pwmout_init(pwmout_t *obj, PinName pin) { PWMName pwm = (PWMName)pinmap_peripheral(pin, PinMap_PWM); MBED_ASSERT(pwm != (PWMName)NC); @@ -73,12 +73,12 @@ void pwmout_init(pwmout_t* obj, PinName pin) pinmap_pinout(pin, PinMap_PWM); } -void pwmout_free(pwmout_t* obj) +void pwmout_free(pwmout_t *obj) { FTM_Deinit(ftm_addrs[obj->pwm_name >> TPM_SHIFT]); } -void pwmout_write(pwmout_t* obj, float value) +void pwmout_write(pwmout_t *obj, float value) { if (value < 0.0f) { value = 0.0f; @@ -96,30 +96,31 @@ void pwmout_write(pwmout_t* obj, float value) FTM_SetSoftwareTrigger(base, true); } -float pwmout_read(pwmout_t* obj) +float pwmout_read(pwmout_t *obj) { FTM_Type *base = ftm_addrs[obj->pwm_name >> TPM_SHIFT]; uint16_t count = (base->CONTROLS[obj->pwm_name & 0xF].CnV) & FTM_CnV_VAL_MASK; uint16_t mod = base->MOD & FTM_MOD_MOD_MASK; - if (mod == 0) + if (mod == 0) { return 0.0; + } float v = (float)(count) / (float)(mod); return (v > 1.0f) ? (1.0f) : (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) { FTM_Type *base = ftm_addrs[obj->pwm_name >> TPM_SHIFT]; float dc = pwmout_read(obj); @@ -129,17 +130,27 @@ void pwmout_period_us(pwmout_t* obj, int us) pwmout_write(obj, dc); } -void pwmout_pulsewidth(pwmout_t* obj, float seconds) +int pwmout_read_period_us(pwmout_t *obj) +{ + uint32_t pwm_period = 0; + if (pwm_clock_mhz > 0) { + FTM_Type *base = ftm_addrs[obj->pwm_name >> TPM_SHIFT];; + pwm_period = ((base->MOD) + 1) / pwm_clock_mhz; + } + return pwm_period; +} + +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) { FTM_Type *base = ftm_addrs[obj->pwm_name >> TPM_SHIFT]; uint32_t value = (uint32_t)(pwm_clock_mhz * (float)us); @@ -150,6 +161,16 @@ void pwmout_pulsewidth_us(pwmout_t* obj, int us) FTM_SetSoftwareTrigger(base, true); } +int pwmout_read_pulsewidth_us(pwmout_t *obj) +{ + uint32_t pwm_pulsewidth = 0; + if (pwm_clock_mhz > 0) { + FTM_Type *base = ftm_addrs[obj->pwm_name >> TPM_SHIFT]; + pwm_pulsewidth = (base->CONTROLS[obj->pwm_name & 0xF].CnV) / pwm_clock_mhz; + } + return pwm_pulsewidth; +} + const PinMap *pwmout_pinmap() { return PinMap_PWM; diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/pwmout_api.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/pwmout_api.c index c8b6778196d..805020c862e 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/pwmout_api.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/pwmout_api.c @@ -158,6 +158,17 @@ void pwmout_period_us(pwmout_t *obj, int us) pwmout_write(obj, dc); } +int pwmout_read_period_us(pwmout_t *obj) +{ + uint32_t pwm_period = 0; + if (pwm_clock_mhz > 0) { + FTM_Type *base = ftm_addrs[obj->pwm_name >> TPM_SHIFT]; + uint16_t mod = base->MOD & FTM_MOD_MOD_MASK; + pwm_period = ((mod) + 1) / pwm_clock_mhz; + } + return pwm_period; +} + void pwmout_pulsewidth(pwmout_t *obj, float seconds) { pwmout_pulsewidth_us(obj, seconds * 1000000.0f); @@ -179,6 +190,16 @@ void pwmout_pulsewidth_us(pwmout_t *obj, int us) FTM_SetSoftwareTrigger(base, true); } +int pwmout_read_pulsewidth_us(pwmout_t *obj) +{ + uint32_t pwm_pulsewidth = 0; + if (pwm_clock_mhz > 0) { + FTM_Type *base = ftm_addrs[obj->pwm_name >> TPM_SHIFT]; + pwm_pulsewidth = (base->CONTROLS[obj->pwm_name & 0xF].CnV) / pwm_clock_mhz; + } + return pwm_pulsewidth; +} + const PinMap *pwmout_pinmap() { return PinMap_PWM; diff --git a/targets/TARGET_GigaDevice/TARGET_GD32F30X/pwmout_api.c b/targets/TARGET_GigaDevice/TARGET_GD32F30X/pwmout_api.c index aa1288424cc..a1eeb17b327 100644 --- a/targets/TARGET_GigaDevice/TARGET_GD32F30X/pwmout_api.c +++ b/targets/TARGET_GigaDevice/TARGET_GD32F30X/pwmout_api.c @@ -249,6 +249,11 @@ void pwmout_period_us(pwmout_t *obj, int us) timer_enable(obj->pwm); } +int pwmout_read_period_us(pwmout_t *obj) +{ + return TIMER_CAR(obj->pwm); +} + void pwmout_pulsewidth(pwmout_t *obj, float seconds) { pwmout_pulsewidth_us(obj, seconds * 1000000.0f); @@ -298,6 +303,34 @@ static uint32_t timer_get_clock(uint32_t timer_periph) return timerclk; } +int pwmout_read_pulsewidth_us(pwmout_t *obj) +{ + uint16_t pulse = 0; + + switch (obj->ch) { + case TIMER_CH_0: + pulse = TIMER_CH0CV(obj->pwm); + break; + + case TIMER_CH_1: + pulse = TIMER_CH1CV(obj->pwm); + break; + + case TIMER_CH_2: + pulse = TIMER_CH2CV(obj->pwm); + break; + + case TIMER_CH_3: + pulse = TIMER_CH3CV(obj->pwm); + break; + + default: + error("Error: pwm channel error! \r\n"); + } + + return pulse; +} + const PinMap *pwmout_pinmap() { return PinMap_PWM; diff --git a/targets/TARGET_GigaDevice/TARGET_GD32F4XX/pwmout_api.c b/targets/TARGET_GigaDevice/TARGET_GD32F4XX/pwmout_api.c index d23d2daa3a5..45d5eed6700 100644 --- a/targets/TARGET_GigaDevice/TARGET_GD32F4XX/pwmout_api.c +++ b/targets/TARGET_GigaDevice/TARGET_GD32F4XX/pwmout_api.c @@ -194,6 +194,11 @@ void pwmout_period_us(pwmout_t *obj, int us) timer_enable(obj->pwm); } +int pwmout_read_period_us(pwmout_t *obj) +{ + return TIMER_CAR(obj->pwm); +} + /** Set the PWM pulsewidth specified in seconds, keeping the period the same. * * @param obj The pwmout object @@ -234,6 +239,34 @@ void pwmout_pulsewidth_us(pwmout_t *obj, int us) timer_channel_output_pulse_value_config(obj->pwm, obj->ch, pulse); } +int pwmout_read_pulsewidth_us(pwmout_t *obj) +{ + uint16_t pulse = 0; + + switch (obj->ch) { + case TIMER_CH_0: + pulse = TIMER_CH0CV(obj->pwm); + break; + + case TIMER_CH_1: + pulse = TIMER_CH1CV(obj->pwm); + break; + + case TIMER_CH_2: + pulse = TIMER_CH2CV(obj->pwm); + break; + + case TIMER_CH_3: + pulse = TIMER_CH3CV(obj->pwm); + break; + + default: + error("Error: pwm channel error! \r\n"); + } + + return pulse; +} + static uint32_t timer_get_clock(uint32_t timer_periph) { uint32_t timerclk; diff --git a/targets/TARGET_Maxim/TARGET_MAX32600/pwmout_api.c b/targets/TARGET_Maxim/TARGET_MAX32600/pwmout_api.c index ae5d22671d3..5faa1b003a9 100644 --- a/targets/TARGET_Maxim/TARGET_MAX32600/pwmout_api.c +++ b/targets/TARGET_Maxim/TARGET_MAX32600/pwmout_api.c @@ -40,7 +40,7 @@ #include "PeripheralPins.h" //****************************************************************************** -void pwmout_init(pwmout_t* obj, PinName pin) +void pwmout_init(pwmout_t *obj, PinName pin) { // Make sure the pin is free for GPIO use unsigned int port = (unsigned int)pin >> PORT_SHIFT; @@ -51,20 +51,20 @@ void pwmout_init(pwmout_t* obj, PinName pin) PinMap pwm = PinMap_PWM[0]; // Check if there is a pulse train already active on this port - int pin_func = (MXC_GPIO->func_sel[port] & (0xF << (port_pin*4))) >> (port_pin*4); + int pin_func = (MXC_GPIO->func_sel[port] & (0xF << (port_pin * 4))) >> (port_pin * 4); MBED_ASSERT((pin_func < 1) || (pin_func > 3)); // Search through PinMap_PWM to find the pin - while(pwm.pin != pin) { + while (pwm.pin != pin) { pwm = PinMap_PWM[++i]; } // Find a free PT instance on this pin - while(pwm.pin == pin) { + while (pwm.pin == pin) { // Check to see if this PT instance is free - if((((mxc_pt_regs_t*)pwm.peripheral)->rate_length & - MXC_F_PT_RATE_LENGTH_MODE)) { + if ((((mxc_pt_regs_t *)pwm.peripheral)->rate_length & + MXC_F_PT_RATE_LENGTH_MODE)) { break; } @@ -78,10 +78,10 @@ void pwmout_init(pwmout_t* obj, PinName pin) MXC_CLKMAN->clk_ctrl_2_pt = MXC_E_CLKMAN_CLK_SCALE_ENABLED; // Set the obj pointer to the propper PWM instance - obj->pwm = (mxc_pt_regs_t*)pwm.peripheral; + obj->pwm = (mxc_pt_regs_t *)pwm.peripheral; // Initialize object period and pulse width - obj->period = -1; + obj->period = -1; obj->pulse_width = -1; // Disable the output @@ -94,17 +94,17 @@ void pwmout_init(pwmout_t* obj, PinName pin) // default to 20ms: standard for servos, and fine for e.g. brightness control pwmout_period_us(obj, 20000); - pwmout_write (obj, 0); + pwmout_write(obj, 0); // Set the drive mode to normal - MXC_SET_FIELD(&MXC_GPIO->out_mode[port], (0x7 << (port_pin*4)), (MXC_V_GPIO_OUT_MODE_NORMAL_DRIVE << (port_pin*4))); + MXC_SET_FIELD(&MXC_GPIO->out_mode[port], (0x7 << (port_pin * 4)), (MXC_V_GPIO_OUT_MODE_NORMAL_DRIVE << (port_pin * 4))); // Enable the global pwm MXC_PTG->ctrl = MXC_F_PT_CTRL_ENABLE_ALL; } //****************************************************************************** -void pwmout_free(pwmout_t* obj) +void pwmout_free(pwmout_t *obj) { // Set the registers to the reset value obj->pwm->train = 0; @@ -112,39 +112,39 @@ void pwmout_free(pwmout_t* obj) } //****************************************************************************** -static void pwmout_update(pwmout_t* obj) +static void pwmout_update(pwmout_t *obj) { // Calculate and set the divider ratio - int div = (obj->period * (SystemCoreClock/1000000))/32; - if (div < 2){ + int div = (obj->period * (SystemCoreClock / 1000000)) / 32; + if (div < 2) { div = 2; } MXC_SET_FIELD(&obj->pwm->rate_length, MXC_F_PT_RATE_LENGTH_RATE_CONTROL, div); // Change the duty cycle to adjust the pulse width - obj->pwm->train = (0xFFFFFFFF << (32-((32*obj->pulse_width)/obj->period))); + obj->pwm->train = (0xFFFFFFFF << (32 - ((32 * obj->pulse_width) / obj->period))); } //****************************************************************************** -void pwmout_write(pwmout_t* obj, float percent) +void pwmout_write(pwmout_t *obj, float percent) { // Saturate percent if outside of range - if(percent < 0.0) { + if (percent < 0.0) { percent = 0.0; - } else if(percent > 1.0) { + } else if (percent > 1.0) { percent = 1.0; } // Resize the pulse width to set the duty cycle - pwmout_pulsewidth_us(obj, (int)(percent*obj->period)); + pwmout_pulsewidth_us(obj, (int)(percent * obj->period)); } //****************************************************************************** -float pwmout_read(pwmout_t* obj) +float pwmout_read(pwmout_t *obj) { // Check for when pulsewidth or period equals 0 - if((obj->pulse_width == 0) || (obj->period == 0)){ + if ((obj->pulse_width == 0) || (obj->period == 0)) { return 0; } @@ -153,26 +153,26 @@ float pwmout_read(pwmout_t* obj) } //****************************************************************************** -void pwmout_period(pwmout_t* obj, float seconds) +void pwmout_period(pwmout_t *obj, float seconds) { pwmout_period_us(obj, (int)(seconds * 1000000.0)); } //****************************************************************************** -void pwmout_period_ms(pwmout_t* obj, int ms) +void pwmout_period_ms(pwmout_t *obj, int ms) { - pwmout_period_us(obj, ms*1000); + pwmout_period_us(obj, ms * 1000); } //****************************************************************************** -void pwmout_period_us(pwmout_t* obj, int us) +void pwmout_period_us(pwmout_t *obj, int us) { // Check the range of the period - MBED_ASSERT((us >= 0) && (us <= (int)(SystemCoreClock/32))); + MBED_ASSERT((us >= 0) && (us <= (int)(SystemCoreClock / 32))); // Set pulse width to half the period if uninitialized - if(obj->pulse_width == -1){ - obj->pulse_width = us/2; + if (obj->pulse_width == -1) { + obj->pulse_width = us / 2; } // Save the period @@ -183,26 +183,32 @@ void pwmout_period_us(pwmout_t* obj, int us) } //****************************************************************************** -void pwmout_pulsewidth(pwmout_t* obj, float seconds) +int pwmout_read_period_us(pwmout_t *obj) +{ + return obj->period; +} + +//****************************************************************************** +void pwmout_pulsewidth(pwmout_t *obj, float seconds) { pwmout_pulsewidth_us(obj, (int)(seconds * 1000000.0)); } //****************************************************************************** -void pwmout_pulsewidth_ms(pwmout_t* obj, int ms) +void pwmout_pulsewidth_ms(pwmout_t *obj, int ms) { - pwmout_pulsewidth_us(obj, ms*1000); + pwmout_pulsewidth_us(obj, ms * 1000); } //****************************************************************************** -void pwmout_pulsewidth_us(pwmout_t* obj, int us) +void pwmout_pulsewidth_us(pwmout_t *obj, int us) { // Check the range of the pulsewidth - MBED_ASSERT((us >= 0) && (us <= (int)(SystemCoreClock/32))); + MBED_ASSERT((us >= 0) && (us <= (int)(SystemCoreClock / 32))); // Initialize period to double the pulsewidth if uninitialized - if(obj->period == -1){ - obj->period = 2*us; + if (obj->period == -1) { + obj->period = 2 * us; } // Save the pulsewidth @@ -212,6 +218,12 @@ void pwmout_pulsewidth_us(pwmout_t* obj, int us) pwmout_update(obj); } +//****************************************************************************** +int pwmout_read_pulsewidth_us(pwmout_t *obj) +{ + return obj->pulse_width; +} + const PinMap *pwmout_pinmap() { return PinMap_PWM; diff --git a/targets/TARGET_Maxim/TARGET_MAX32610/pwmout_api.c b/targets/TARGET_Maxim/TARGET_MAX32610/pwmout_api.c index ae5d22671d3..5faa1b003a9 100644 --- a/targets/TARGET_Maxim/TARGET_MAX32610/pwmout_api.c +++ b/targets/TARGET_Maxim/TARGET_MAX32610/pwmout_api.c @@ -40,7 +40,7 @@ #include "PeripheralPins.h" //****************************************************************************** -void pwmout_init(pwmout_t* obj, PinName pin) +void pwmout_init(pwmout_t *obj, PinName pin) { // Make sure the pin is free for GPIO use unsigned int port = (unsigned int)pin >> PORT_SHIFT; @@ -51,20 +51,20 @@ void pwmout_init(pwmout_t* obj, PinName pin) PinMap pwm = PinMap_PWM[0]; // Check if there is a pulse train already active on this port - int pin_func = (MXC_GPIO->func_sel[port] & (0xF << (port_pin*4))) >> (port_pin*4); + int pin_func = (MXC_GPIO->func_sel[port] & (0xF << (port_pin * 4))) >> (port_pin * 4); MBED_ASSERT((pin_func < 1) || (pin_func > 3)); // Search through PinMap_PWM to find the pin - while(pwm.pin != pin) { + while (pwm.pin != pin) { pwm = PinMap_PWM[++i]; } // Find a free PT instance on this pin - while(pwm.pin == pin) { + while (pwm.pin == pin) { // Check to see if this PT instance is free - if((((mxc_pt_regs_t*)pwm.peripheral)->rate_length & - MXC_F_PT_RATE_LENGTH_MODE)) { + if ((((mxc_pt_regs_t *)pwm.peripheral)->rate_length & + MXC_F_PT_RATE_LENGTH_MODE)) { break; } @@ -78,10 +78,10 @@ void pwmout_init(pwmout_t* obj, PinName pin) MXC_CLKMAN->clk_ctrl_2_pt = MXC_E_CLKMAN_CLK_SCALE_ENABLED; // Set the obj pointer to the propper PWM instance - obj->pwm = (mxc_pt_regs_t*)pwm.peripheral; + obj->pwm = (mxc_pt_regs_t *)pwm.peripheral; // Initialize object period and pulse width - obj->period = -1; + obj->period = -1; obj->pulse_width = -1; // Disable the output @@ -94,17 +94,17 @@ void pwmout_init(pwmout_t* obj, PinName pin) // default to 20ms: standard for servos, and fine for e.g. brightness control pwmout_period_us(obj, 20000); - pwmout_write (obj, 0); + pwmout_write(obj, 0); // Set the drive mode to normal - MXC_SET_FIELD(&MXC_GPIO->out_mode[port], (0x7 << (port_pin*4)), (MXC_V_GPIO_OUT_MODE_NORMAL_DRIVE << (port_pin*4))); + MXC_SET_FIELD(&MXC_GPIO->out_mode[port], (0x7 << (port_pin * 4)), (MXC_V_GPIO_OUT_MODE_NORMAL_DRIVE << (port_pin * 4))); // Enable the global pwm MXC_PTG->ctrl = MXC_F_PT_CTRL_ENABLE_ALL; } //****************************************************************************** -void pwmout_free(pwmout_t* obj) +void pwmout_free(pwmout_t *obj) { // Set the registers to the reset value obj->pwm->train = 0; @@ -112,39 +112,39 @@ void pwmout_free(pwmout_t* obj) } //****************************************************************************** -static void pwmout_update(pwmout_t* obj) +static void pwmout_update(pwmout_t *obj) { // Calculate and set the divider ratio - int div = (obj->period * (SystemCoreClock/1000000))/32; - if (div < 2){ + int div = (obj->period * (SystemCoreClock / 1000000)) / 32; + if (div < 2) { div = 2; } MXC_SET_FIELD(&obj->pwm->rate_length, MXC_F_PT_RATE_LENGTH_RATE_CONTROL, div); // Change the duty cycle to adjust the pulse width - obj->pwm->train = (0xFFFFFFFF << (32-((32*obj->pulse_width)/obj->period))); + obj->pwm->train = (0xFFFFFFFF << (32 - ((32 * obj->pulse_width) / obj->period))); } //****************************************************************************** -void pwmout_write(pwmout_t* obj, float percent) +void pwmout_write(pwmout_t *obj, float percent) { // Saturate percent if outside of range - if(percent < 0.0) { + if (percent < 0.0) { percent = 0.0; - } else if(percent > 1.0) { + } else if (percent > 1.0) { percent = 1.0; } // Resize the pulse width to set the duty cycle - pwmout_pulsewidth_us(obj, (int)(percent*obj->period)); + pwmout_pulsewidth_us(obj, (int)(percent * obj->period)); } //****************************************************************************** -float pwmout_read(pwmout_t* obj) +float pwmout_read(pwmout_t *obj) { // Check for when pulsewidth or period equals 0 - if((obj->pulse_width == 0) || (obj->period == 0)){ + if ((obj->pulse_width == 0) || (obj->period == 0)) { return 0; } @@ -153,26 +153,26 @@ float pwmout_read(pwmout_t* obj) } //****************************************************************************** -void pwmout_period(pwmout_t* obj, float seconds) +void pwmout_period(pwmout_t *obj, float seconds) { pwmout_period_us(obj, (int)(seconds * 1000000.0)); } //****************************************************************************** -void pwmout_period_ms(pwmout_t* obj, int ms) +void pwmout_period_ms(pwmout_t *obj, int ms) { - pwmout_period_us(obj, ms*1000); + pwmout_period_us(obj, ms * 1000); } //****************************************************************************** -void pwmout_period_us(pwmout_t* obj, int us) +void pwmout_period_us(pwmout_t *obj, int us) { // Check the range of the period - MBED_ASSERT((us >= 0) && (us <= (int)(SystemCoreClock/32))); + MBED_ASSERT((us >= 0) && (us <= (int)(SystemCoreClock / 32))); // Set pulse width to half the period if uninitialized - if(obj->pulse_width == -1){ - obj->pulse_width = us/2; + if (obj->pulse_width == -1) { + obj->pulse_width = us / 2; } // Save the period @@ -183,26 +183,32 @@ void pwmout_period_us(pwmout_t* obj, int us) } //****************************************************************************** -void pwmout_pulsewidth(pwmout_t* obj, float seconds) +int pwmout_read_period_us(pwmout_t *obj) +{ + return obj->period; +} + +//****************************************************************************** +void pwmout_pulsewidth(pwmout_t *obj, float seconds) { pwmout_pulsewidth_us(obj, (int)(seconds * 1000000.0)); } //****************************************************************************** -void pwmout_pulsewidth_ms(pwmout_t* obj, int ms) +void pwmout_pulsewidth_ms(pwmout_t *obj, int ms) { - pwmout_pulsewidth_us(obj, ms*1000); + pwmout_pulsewidth_us(obj, ms * 1000); } //****************************************************************************** -void pwmout_pulsewidth_us(pwmout_t* obj, int us) +void pwmout_pulsewidth_us(pwmout_t *obj, int us) { // Check the range of the pulsewidth - MBED_ASSERT((us >= 0) && (us <= (int)(SystemCoreClock/32))); + MBED_ASSERT((us >= 0) && (us <= (int)(SystemCoreClock / 32))); // Initialize period to double the pulsewidth if uninitialized - if(obj->period == -1){ - obj->period = 2*us; + if (obj->period == -1) { + obj->period = 2 * us; } // Save the pulsewidth @@ -212,6 +218,12 @@ void pwmout_pulsewidth_us(pwmout_t* obj, int us) pwmout_update(obj); } +//****************************************************************************** +int pwmout_read_pulsewidth_us(pwmout_t *obj) +{ + return obj->pulse_width; +} + const PinMap *pwmout_pinmap() { return PinMap_PWM; diff --git a/targets/TARGET_Maxim/TARGET_MAX32620/pwmout_api.c b/targets/TARGET_Maxim/TARGET_MAX32620/pwmout_api.c index 883d1a4a3c1..61ea845185a 100644 --- a/targets/TARGET_Maxim/TARGET_MAX32620/pwmout_api.c +++ b/targets/TARGET_Maxim/TARGET_MAX32620/pwmout_api.c @@ -39,7 +39,7 @@ #include "PeripheralPins.h" //****************************************************************************** -void pwmout_init(pwmout_t* obj, PinName pin) +void pwmout_init(pwmout_t *obj, PinName pin) { // Make sure the pin is free for GPIO use unsigned int port = (unsigned int)pin >> PORT_SHIFT; @@ -50,7 +50,7 @@ void pwmout_init(pwmout_t* obj, PinName pin) PinMap pwm = PinMap_PWM[0]; // Check if there is a pulse train already active on this port - int pin_func = (MXC_GPIO->func_sel[port] & (0xF << (port_pin*4))) >> (port_pin*4); + int pin_func = (MXC_GPIO->func_sel[port] & (0xF << (port_pin * 4))) >> (port_pin * 4); MBED_ASSERT((pin_func < 1) || (pin_func > 3)); // Search through PinMap_PWM to find the pin @@ -62,7 +62,7 @@ void pwmout_init(pwmout_t* obj, PinName pin) while (pwm.pin == pin) { // Check to see if this PT instance is free - if (((mxc_pt_regs_t*)pwm.peripheral)->rate_length & MXC_F_PT_RATE_LENGTH_MODE) { + if (((mxc_pt_regs_t *)pwm.peripheral)->rate_length & MXC_F_PT_RATE_LENGTH_MODE) { break; } @@ -76,7 +76,7 @@ void pwmout_init(pwmout_t* obj, PinName pin) MXC_CLKMAN->sys_clk_ctrl_7_pt = MXC_S_CLKMAN_CLK_SCALE_DIV_1; // Set the obj pointer to the propper PWM instance - obj->pwm = (mxc_pt_regs_t*)pwm.peripheral; + obj->pwm = (mxc_pt_regs_t *)pwm.peripheral; // Initialize object period and pulse width obj->period = -1; @@ -92,17 +92,17 @@ void pwmout_init(pwmout_t* obj, PinName pin) // default to 20ms: standard for servos, and fine for e.g. brightness control pwmout_period_us(obj, 20000); - pwmout_write (obj, 0); + pwmout_write(obj, 0); // Set the drive mode to normal - MXC_SET_FIELD(&MXC_GPIO->out_mode[port], (0x7 << (port_pin*4)), (MXC_V_GPIO_OUT_MODE_NORMAL << (port_pin*4))); + MXC_SET_FIELD(&MXC_GPIO->out_mode[port], (0x7 << (port_pin * 4)), (MXC_V_GPIO_OUT_MODE_NORMAL << (port_pin * 4))); // Enable this PWM channel MXC_PTG->enable |= (1 << MXC_PT_GET_IDX(obj->pwm)); } //****************************************************************************** -void pwmout_free(pwmout_t* obj) +void pwmout_free(pwmout_t *obj) { // Set the registers to the reset value obj->pwm->train = 0; @@ -110,36 +110,36 @@ void pwmout_free(pwmout_t* obj) } //****************************************************************************** -static void pwmout_update(pwmout_t* obj) +static void pwmout_update(pwmout_t *obj) { // Calculate and set the divider ratio - int div = (obj->period * (SystemCoreClock/1000000))/32; + int div = (obj->period * (SystemCoreClock / 1000000)) / 32; if (div < 2) { div = 2; } MXC_SET_FIELD(&obj->pwm->rate_length, MXC_F_PT_RATE_LENGTH_RATE_CONTROL, div); // Change the duty cycle to adjust the pulse width - obj->pwm->train = (0xFFFFFFFF << (32-((32*obj->pulse_width)/obj->period))); + obj->pwm->train = (0xFFFFFFFF << (32 - ((32 * obj->pulse_width) / obj->period))); } //****************************************************************************** -void pwmout_write(pwmout_t* obj, float percent) +void pwmout_write(pwmout_t *obj, float percent) { // Saturate percent if outside of range if (percent < 0.0f) { percent = 0.0f; - } else if(percent > 1.0f) { + } else if (percent > 1.0f) { percent = 1.0f; } // Resize the pulse width to set the duty cycle - pwmout_pulsewidth_us(obj, (int)(percent*obj->period)); + pwmout_pulsewidth_us(obj, (int)(percent * obj->period)); } //****************************************************************************** -float pwmout_read(pwmout_t* obj) +float pwmout_read(pwmout_t *obj) { // Check for when pulsewidth or period equals 0 if ((obj->pulse_width == 0) || (obj->period == 0)) { @@ -151,26 +151,26 @@ float pwmout_read(pwmout_t* obj) } //****************************************************************************** -void pwmout_period(pwmout_t* obj, float seconds) +void pwmout_period(pwmout_t *obj, float seconds) { pwmout_period_us(obj, (int)(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); + pwmout_period_us(obj, ms * 1000); } //****************************************************************************** -void pwmout_period_us(pwmout_t* obj, int us) +void pwmout_period_us(pwmout_t *obj, int us) { // Check the range of the period - MBED_ASSERT((us >= 0) && (us <= (int)(SystemCoreClock/32))); + MBED_ASSERT((us >= 0) && (us <= (int)(SystemCoreClock / 32))); // Set pulse width to half the period if uninitialized if (obj->pulse_width == -1) { - obj->pulse_width = us/2; + obj->pulse_width = us / 2; } // Save the period @@ -181,26 +181,32 @@ void pwmout_period_us(pwmout_t* obj, int us) } //****************************************************************************** -void pwmout_pulsewidth(pwmout_t* obj, float seconds) +int pwmout_read_period_us(pwmout_t *obj) +{ + return obj->period; +} + +//****************************************************************************** +void pwmout_pulsewidth(pwmout_t *obj, float seconds) { pwmout_pulsewidth_us(obj, (int)(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); + pwmout_pulsewidth_us(obj, ms * 1000); } //****************************************************************************** -void pwmout_pulsewidth_us(pwmout_t* obj, int us) +void pwmout_pulsewidth_us(pwmout_t *obj, int us) { // Check the range of the pulsewidth - MBED_ASSERT((us >= 0) && (us <= (int)(SystemCoreClock/32))); + MBED_ASSERT((us >= 0) && (us <= (int)(SystemCoreClock / 32))); // Initialize period to double the pulsewidth if uninitialized if (obj->period == -1) { - obj->period = 2*us; + obj->period = 2 * us; } // Save the pulsewidth @@ -210,6 +216,12 @@ void pwmout_pulsewidth_us(pwmout_t* obj, int us) pwmout_update(obj); } +//****************************************************************************** +int pwmout_read_pulsewidth_us(pwmout_t *obj) +{ + return obj->pulse_width; +} + const PinMap *pwmout_pinmap() { return PinMap_PWM; diff --git a/targets/TARGET_Maxim/TARGET_MAX32620C/pwmout_api.c b/targets/TARGET_Maxim/TARGET_MAX32620C/pwmout_api.c index f1949210cb0..358e4ea3992 100644 --- a/targets/TARGET_Maxim/TARGET_MAX32620C/pwmout_api.c +++ b/targets/TARGET_Maxim/TARGET_MAX32620C/pwmout_api.c @@ -45,7 +45,7 @@ //****************************************************************************** -void pwmout_init(pwmout_t* obj, PinName pin) +void pwmout_init(pwmout_t *obj, PinName pin) { // Make sure the pin is free for GPIO use unsigned int port = (unsigned int)pin >> PORT_SHIFT; @@ -69,7 +69,7 @@ void pwmout_init(pwmout_t* obj, PinName pin) while (pwm.pin == pin) { // Check to see if this PT instance is free - if (((mxc_pt_regs_t*)pwm.peripheral)->rate_length & MXC_F_PT_RATE_LENGTH_MODE) { + if (((mxc_pt_regs_t *)pwm.peripheral)->rate_length & MXC_F_PT_RATE_LENGTH_MODE) { break; } @@ -83,7 +83,7 @@ void pwmout_init(pwmout_t* obj, PinName pin) MXC_CLKMAN->sys_clk_ctrl_7_pt = MXC_S_CLKMAN_CLK_SCALE_DIV_1; // Set the obj pointer to the propper PWM instance - obj->pwm = (mxc_pt_regs_t*)pwm.peripheral; + obj->pwm = (mxc_pt_regs_t *)pwm.peripheral; // Initialize object period and pulse width obj->period = -1; @@ -99,7 +99,7 @@ void pwmout_init(pwmout_t* obj, PinName pin) // default to 20ms: standard for servos, and fine for e.g. brightness control pwmout_period_us(obj, 20000); - pwmout_write (obj, 0); + pwmout_write(obj, 0); // Set the drive mode to normal MXC_SET_FIELD(&MXC_GPIO->out_mode[port], @@ -111,7 +111,7 @@ void pwmout_init(pwmout_t* obj, PinName pin) } //****************************************************************************** -void pwmout_free(pwmout_t* obj) +void pwmout_free(pwmout_t *obj) { // Set the registers to the reset value obj->pwm->train = 0; @@ -119,10 +119,10 @@ void pwmout_free(pwmout_t* obj) } //****************************************************************************** -static void pwmout_update(pwmout_t* obj) +static void pwmout_update(pwmout_t *obj) { // Calculate and set the divider ratio - int div = (obj->period * (SystemCoreClock / 1000000))/32; + int div = (obj->period * (SystemCoreClock / 1000000)) / 32; if (div < 2) { div = 2; } @@ -134,24 +134,24 @@ static void pwmout_update(pwmout_t* obj) //****************************************************************************** -void pwmout_write(pwmout_t* obj, float percent) +void pwmout_write(pwmout_t *obj, float percent) { // Saturate percent if outside of range - if(percent < 0.0f) { + if (percent < 0.0f) { percent = 0.0f; - } else if(percent > 1.0f) { + } else if (percent > 1.0f) { percent = 1.0f; } // Resize the pulse width to set the duty cycle - pwmout_pulsewidth_us(obj, (int)(percent*obj->period)); + pwmout_pulsewidth_us(obj, (int)(percent * obj->period)); } //****************************************************************************** -float pwmout_read(pwmout_t* obj) +float pwmout_read(pwmout_t *obj) { // Check for when pulsewidth or period equals 0 - if((obj->pulse_width == 0) || (obj->period == 0)) { + if ((obj->pulse_width == 0) || (obj->period == 0)) { return 0; } @@ -160,19 +160,19 @@ float pwmout_read(pwmout_t* obj) } //****************************************************************************** -void pwmout_period(pwmout_t* obj, float seconds) +void pwmout_period(pwmout_t *obj, float seconds) { pwmout_period_us(obj, (int)(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); } //****************************************************************************** -void pwmout_period_us(pwmout_t* obj, int us) +void pwmout_period_us(pwmout_t *obj, int us) { // Check the range of the period MBED_ASSERT((us >= 0) && (us <= (int)(SystemCoreClock / 32))); @@ -190,19 +190,25 @@ void pwmout_period_us(pwmout_t* obj, int us) } //****************************************************************************** -void pwmout_pulsewidth(pwmout_t* obj, float seconds) +int pwmout_read_period_us(pwmout_t *obj) +{ + return obj->period; +} + +//****************************************************************************** +void pwmout_pulsewidth(pwmout_t *obj, float seconds) { pwmout_pulsewidth_us(obj, (int)(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) { // Check the range of the pulsewidth MBED_ASSERT((us >= 0) && (us <= (int)(SystemCoreClock / 32))); @@ -219,6 +225,12 @@ void pwmout_pulsewidth_us(pwmout_t* obj, int us) pwmout_update(obj); } +//****************************************************************************** +int pwmout_read_pulsewidth_us(pwmout_t *obj) +{ + return obj->pulse_width; +} + const PinMap *pwmout_pinmap() { return PinMap_PWM; diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/pwmout_api.c b/targets/TARGET_Maxim/TARGET_MAX32625/pwmout_api.c index f1949210cb0..358e4ea3992 100644 --- a/targets/TARGET_Maxim/TARGET_MAX32625/pwmout_api.c +++ b/targets/TARGET_Maxim/TARGET_MAX32625/pwmout_api.c @@ -45,7 +45,7 @@ //****************************************************************************** -void pwmout_init(pwmout_t* obj, PinName pin) +void pwmout_init(pwmout_t *obj, PinName pin) { // Make sure the pin is free for GPIO use unsigned int port = (unsigned int)pin >> PORT_SHIFT; @@ -69,7 +69,7 @@ void pwmout_init(pwmout_t* obj, PinName pin) while (pwm.pin == pin) { // Check to see if this PT instance is free - if (((mxc_pt_regs_t*)pwm.peripheral)->rate_length & MXC_F_PT_RATE_LENGTH_MODE) { + if (((mxc_pt_regs_t *)pwm.peripheral)->rate_length & MXC_F_PT_RATE_LENGTH_MODE) { break; } @@ -83,7 +83,7 @@ void pwmout_init(pwmout_t* obj, PinName pin) MXC_CLKMAN->sys_clk_ctrl_7_pt = MXC_S_CLKMAN_CLK_SCALE_DIV_1; // Set the obj pointer to the propper PWM instance - obj->pwm = (mxc_pt_regs_t*)pwm.peripheral; + obj->pwm = (mxc_pt_regs_t *)pwm.peripheral; // Initialize object period and pulse width obj->period = -1; @@ -99,7 +99,7 @@ void pwmout_init(pwmout_t* obj, PinName pin) // default to 20ms: standard for servos, and fine for e.g. brightness control pwmout_period_us(obj, 20000); - pwmout_write (obj, 0); + pwmout_write(obj, 0); // Set the drive mode to normal MXC_SET_FIELD(&MXC_GPIO->out_mode[port], @@ -111,7 +111,7 @@ void pwmout_init(pwmout_t* obj, PinName pin) } //****************************************************************************** -void pwmout_free(pwmout_t* obj) +void pwmout_free(pwmout_t *obj) { // Set the registers to the reset value obj->pwm->train = 0; @@ -119,10 +119,10 @@ void pwmout_free(pwmout_t* obj) } //****************************************************************************** -static void pwmout_update(pwmout_t* obj) +static void pwmout_update(pwmout_t *obj) { // Calculate and set the divider ratio - int div = (obj->period * (SystemCoreClock / 1000000))/32; + int div = (obj->period * (SystemCoreClock / 1000000)) / 32; if (div < 2) { div = 2; } @@ -134,24 +134,24 @@ static void pwmout_update(pwmout_t* obj) //****************************************************************************** -void pwmout_write(pwmout_t* obj, float percent) +void pwmout_write(pwmout_t *obj, float percent) { // Saturate percent if outside of range - if(percent < 0.0f) { + if (percent < 0.0f) { percent = 0.0f; - } else if(percent > 1.0f) { + } else if (percent > 1.0f) { percent = 1.0f; } // Resize the pulse width to set the duty cycle - pwmout_pulsewidth_us(obj, (int)(percent*obj->period)); + pwmout_pulsewidth_us(obj, (int)(percent * obj->period)); } //****************************************************************************** -float pwmout_read(pwmout_t* obj) +float pwmout_read(pwmout_t *obj) { // Check for when pulsewidth or period equals 0 - if((obj->pulse_width == 0) || (obj->period == 0)) { + if ((obj->pulse_width == 0) || (obj->period == 0)) { return 0; } @@ -160,19 +160,19 @@ float pwmout_read(pwmout_t* obj) } //****************************************************************************** -void pwmout_period(pwmout_t* obj, float seconds) +void pwmout_period(pwmout_t *obj, float seconds) { pwmout_period_us(obj, (int)(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); } //****************************************************************************** -void pwmout_period_us(pwmout_t* obj, int us) +void pwmout_period_us(pwmout_t *obj, int us) { // Check the range of the period MBED_ASSERT((us >= 0) && (us <= (int)(SystemCoreClock / 32))); @@ -190,19 +190,25 @@ void pwmout_period_us(pwmout_t* obj, int us) } //****************************************************************************** -void pwmout_pulsewidth(pwmout_t* obj, float seconds) +int pwmout_read_period_us(pwmout_t *obj) +{ + return obj->period; +} + +//****************************************************************************** +void pwmout_pulsewidth(pwmout_t *obj, float seconds) { pwmout_pulsewidth_us(obj, (int)(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) { // Check the range of the pulsewidth MBED_ASSERT((us >= 0) && (us <= (int)(SystemCoreClock / 32))); @@ -219,6 +225,12 @@ void pwmout_pulsewidth_us(pwmout_t* obj, int us) pwmout_update(obj); } +//****************************************************************************** +int pwmout_read_pulsewidth_us(pwmout_t *obj) +{ + return obj->pulse_width; +} + const PinMap *pwmout_pinmap() { return PinMap_PWM; diff --git a/targets/TARGET_Maxim/TARGET_MAX32630/pwmout_api.c b/targets/TARGET_Maxim/TARGET_MAX32630/pwmout_api.c index f1949210cb0..358e4ea3992 100644 --- a/targets/TARGET_Maxim/TARGET_MAX32630/pwmout_api.c +++ b/targets/TARGET_Maxim/TARGET_MAX32630/pwmout_api.c @@ -45,7 +45,7 @@ //****************************************************************************** -void pwmout_init(pwmout_t* obj, PinName pin) +void pwmout_init(pwmout_t *obj, PinName pin) { // Make sure the pin is free for GPIO use unsigned int port = (unsigned int)pin >> PORT_SHIFT; @@ -69,7 +69,7 @@ void pwmout_init(pwmout_t* obj, PinName pin) while (pwm.pin == pin) { // Check to see if this PT instance is free - if (((mxc_pt_regs_t*)pwm.peripheral)->rate_length & MXC_F_PT_RATE_LENGTH_MODE) { + if (((mxc_pt_regs_t *)pwm.peripheral)->rate_length & MXC_F_PT_RATE_LENGTH_MODE) { break; } @@ -83,7 +83,7 @@ void pwmout_init(pwmout_t* obj, PinName pin) MXC_CLKMAN->sys_clk_ctrl_7_pt = MXC_S_CLKMAN_CLK_SCALE_DIV_1; // Set the obj pointer to the propper PWM instance - obj->pwm = (mxc_pt_regs_t*)pwm.peripheral; + obj->pwm = (mxc_pt_regs_t *)pwm.peripheral; // Initialize object period and pulse width obj->period = -1; @@ -99,7 +99,7 @@ void pwmout_init(pwmout_t* obj, PinName pin) // default to 20ms: standard for servos, and fine for e.g. brightness control pwmout_period_us(obj, 20000); - pwmout_write (obj, 0); + pwmout_write(obj, 0); // Set the drive mode to normal MXC_SET_FIELD(&MXC_GPIO->out_mode[port], @@ -111,7 +111,7 @@ void pwmout_init(pwmout_t* obj, PinName pin) } //****************************************************************************** -void pwmout_free(pwmout_t* obj) +void pwmout_free(pwmout_t *obj) { // Set the registers to the reset value obj->pwm->train = 0; @@ -119,10 +119,10 @@ void pwmout_free(pwmout_t* obj) } //****************************************************************************** -static void pwmout_update(pwmout_t* obj) +static void pwmout_update(pwmout_t *obj) { // Calculate and set the divider ratio - int div = (obj->period * (SystemCoreClock / 1000000))/32; + int div = (obj->period * (SystemCoreClock / 1000000)) / 32; if (div < 2) { div = 2; } @@ -134,24 +134,24 @@ static void pwmout_update(pwmout_t* obj) //****************************************************************************** -void pwmout_write(pwmout_t* obj, float percent) +void pwmout_write(pwmout_t *obj, float percent) { // Saturate percent if outside of range - if(percent < 0.0f) { + if (percent < 0.0f) { percent = 0.0f; - } else if(percent > 1.0f) { + } else if (percent > 1.0f) { percent = 1.0f; } // Resize the pulse width to set the duty cycle - pwmout_pulsewidth_us(obj, (int)(percent*obj->period)); + pwmout_pulsewidth_us(obj, (int)(percent * obj->period)); } //****************************************************************************** -float pwmout_read(pwmout_t* obj) +float pwmout_read(pwmout_t *obj) { // Check for when pulsewidth or period equals 0 - if((obj->pulse_width == 0) || (obj->period == 0)) { + if ((obj->pulse_width == 0) || (obj->period == 0)) { return 0; } @@ -160,19 +160,19 @@ float pwmout_read(pwmout_t* obj) } //****************************************************************************** -void pwmout_period(pwmout_t* obj, float seconds) +void pwmout_period(pwmout_t *obj, float seconds) { pwmout_period_us(obj, (int)(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); } //****************************************************************************** -void pwmout_period_us(pwmout_t* obj, int us) +void pwmout_period_us(pwmout_t *obj, int us) { // Check the range of the period MBED_ASSERT((us >= 0) && (us <= (int)(SystemCoreClock / 32))); @@ -190,19 +190,25 @@ void pwmout_period_us(pwmout_t* obj, int us) } //****************************************************************************** -void pwmout_pulsewidth(pwmout_t* obj, float seconds) +int pwmout_read_period_us(pwmout_t *obj) +{ + return obj->period; +} + +//****************************************************************************** +void pwmout_pulsewidth(pwmout_t *obj, float seconds) { pwmout_pulsewidth_us(obj, (int)(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) { // Check the range of the pulsewidth MBED_ASSERT((us >= 0) && (us <= (int)(SystemCoreClock / 32))); @@ -219,6 +225,12 @@ void pwmout_pulsewidth_us(pwmout_t* obj, int us) pwmout_update(obj); } +//****************************************************************************** +int pwmout_read_pulsewidth_us(pwmout_t *obj) +{ + return obj->pulse_width; +} + const PinMap *pwmout_pinmap() { return PinMap_PWM; 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 691af9d6f30..25b214a801c 100644 --- a/targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_NRF52/pwmout_api.c +++ b/targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_NRF52/pwmout_api.c @@ -143,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(nrfx_pwm_t))); + MBED_ASSERT(instance < (int)(sizeof(nordic_nrf5_pwm_instance) / sizeof(nrfx_pwm_t))); /* Populate PWM object with default values. */ obj->instance = instance; @@ -287,6 +287,11 @@ void pwmout_period_us(pwmout_t *obj, int period) nordic_pwm_restart(obj); } +int pwmout_read_period_us(pwmout_t *obj) +{ + return obj->period; +} + /** Set the PWM pulsewidth specified in seconds, keeping the period the same. * * Parameter obj The pwmout object @@ -348,6 +353,10 @@ void pwmout_pulsewidth_us(pwmout_t *obj, int pulse) nordic_pwm_restart(obj); } +int pwmout_read_pulsewidth_us(pwmout_t *obj) { + return (obj->period) * (obj->percent); +} + const PinMap *pwmout_pinmap() { return PinMap_PWM_testing; diff --git a/targets/TARGET_NUVOTON/TARGET_M2351/pwmout_api.c b/targets/TARGET_NUVOTON/TARGET_M2351/pwmout_api.c index 690ad6db2f2..23e56c543e9 100644 --- a/targets/TARGET_NUVOTON/TARGET_M2351/pwmout_api.c +++ b/targets/TARGET_NUVOTON/TARGET_M2351/pwmout_api.c @@ -59,9 +59,9 @@ static const struct nu_modinit_s pwm_modinit_tab[] = { {NC, 0, 0, 0, 0, (IRQn_Type) 0, NULL} }; -static void pwmout_config(pwmout_t* obj, int start); +static void pwmout_config(pwmout_t *obj, int start); -void pwmout_init(pwmout_t* obj, PinName pin) +void pwmout_init(pwmout_t *obj, PinName pin) { obj->pwm = (PWMName) pinmap_peripheral(pin, PinMap_PWM); MBED_ASSERT((int) obj->pwm != NC); @@ -91,7 +91,7 @@ void pwmout_init(pwmout_t* obj, PinName pin) } // NOTE: All channels (identified by PWMName) share a PWM module. This reset will also affect other channels of the same PWM module. - if (! ((struct nu_pwm_var *) modinit->var)->en_msk) { + if (!((struct nu_pwm_var *) modinit->var)->en_msk) { /* Reset module * * NOTE: We must call secure version (from non-secure domain) because SYS/CLK regions are secure. @@ -113,7 +113,7 @@ void pwmout_init(pwmout_t* obj, PinName pin) pwm_modinit_mask |= 1 << i; } -void pwmout_free(pwmout_t* obj) +void pwmout_free(pwmout_t *obj) { EPWM_T *pwm_base = (EPWM_T *) NU_MODBASE(obj->pwm); uint32_t chn = NU_MODSUBINDEX(obj->pwm); @@ -142,29 +142,29 @@ void pwmout_free(pwmout_t* obj) obj->pin = NC; } -void pwmout_write(pwmout_t* obj, float value) +void pwmout_write(pwmout_t *obj, float value) { - obj->pulsewidth_us = NU_CLAMP((uint32_t) (value * obj->period_us), 0, obj->period_us); + obj->pulsewidth_us = NU_CLAMP((uint32_t)(value * obj->period_us), 0, obj->period_us); pwmout_config(obj, 1); } -float pwmout_read(pwmout_t* obj) +float pwmout_read(pwmout_t *obj) { return NU_CLAMP((((float) obj->pulsewidth_us) / obj->period_us), 0.0f, 1.0f); } -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) { uint32_t period_us_old = obj->period_us; uint32_t pulsewidth_us_old = obj->pulsewidth_us; @@ -173,23 +173,33 @@ void pwmout_period_us(pwmout_t* obj, int us) pwmout_config(obj, 1); } -void pwmout_pulsewidth(pwmout_t* obj, float seconds) +int pwmout_read_period_us(pwmout_t *obj) +{ + return obj->period_us; +} + +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->pulsewidth_us = NU_CLAMP(us, 0, obj->period_us); pwmout_config(obj, 1); } -static void pwmout_config(pwmout_t* obj, int start) +int pwmout_read_pulsewidth_us(pwmout_t *obj) +{ + return obj->pulsewidth_us; +} + +static void pwmout_config(pwmout_t *obj, int start) { EPWM_T *pwm_base = (EPWM_T *) NU_MODBASE(obj->pwm); uint32_t chn = NU_MODSUBINDEX(obj->pwm); diff --git a/targets/TARGET_NUVOTON/TARGET_M251/pwmout_api.c b/targets/TARGET_NUVOTON/TARGET_M251/pwmout_api.c index eec6974f4f2..4ce8c93d86c 100644 --- a/targets/TARGET_NUVOTON/TARGET_M251/pwmout_api.c +++ b/targets/TARGET_NUVOTON/TARGET_M251/pwmout_api.c @@ -59,9 +59,9 @@ static const struct nu_modinit_s pwm_modinit_tab[] = { {NC, 0, 0, 0, 0, (IRQn_Type) 0, NULL} }; -static void pwmout_config(pwmout_t* obj, int start); +static void pwmout_config(pwmout_t *obj, int start); -void pwmout_init(pwmout_t* obj, PinName pin) +void pwmout_init(pwmout_t *obj, PinName pin) { obj->pwm = (PWMName) pinmap_peripheral(pin, PinMap_PWM); MBED_ASSERT((int) obj->pwm != NC); @@ -86,7 +86,7 @@ void pwmout_init(pwmout_t* obj, PinName pin) } // NOTE: All channels (identified by PWMName) share a PWM module. This reset will also affect other channels of the same PWM module. - if (! ((struct nu_pwm_var *) modinit->var)->en_msk) { + if (!((struct nu_pwm_var *) modinit->var)->en_msk) { // Reset this module if no channel enabled SYS_ResetModule(modinit->rsetidx); } @@ -103,7 +103,7 @@ void pwmout_init(pwmout_t* obj, PinName pin) pwm_modinit_mask |= 1 << i; } -void pwmout_free(pwmout_t* obj) +void pwmout_free(pwmout_t *obj) { PWM_T *pwm_base = (PWM_T *) NU_MODBASE(obj->pwm); uint32_t chn = NU_MODSUBINDEX(obj->pwm); @@ -128,29 +128,29 @@ void pwmout_free(pwmout_t* obj) obj->pin = NC; } -void pwmout_write(pwmout_t* obj, float value) +void pwmout_write(pwmout_t *obj, float value) { - obj->pulsewidth_us = NU_CLAMP((uint32_t) (value * obj->period_us), 0, obj->period_us); + obj->pulsewidth_us = NU_CLAMP((uint32_t)(value * obj->period_us), 0, obj->period_us); pwmout_config(obj, 1); } -float pwmout_read(pwmout_t* obj) +float pwmout_read(pwmout_t *obj) { return NU_CLAMP((((float) obj->pulsewidth_us) / obj->period_us), 0.0f, 1.0f); } -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) { uint32_t period_us_old = obj->period_us; uint32_t pulsewidth_us_old = obj->pulsewidth_us; @@ -159,23 +159,32 @@ void pwmout_period_us(pwmout_t* obj, int us) pwmout_config(obj, 1); } -void pwmout_pulsewidth(pwmout_t* obj, float seconds) +int pwmout_read_period_us(pwmout_t *obj) +{ + return obj->period_us; +} + +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->pulsewidth_us = NU_CLAMP(us, 0, obj->period_us); pwmout_config(obj, 1); } -static void pwmout_config(pwmout_t* obj, int start) +int pwmout_read_pulsewidth_us(pwmout_t *obj) { + return obj->pulsewidth_us; +} + +static void pwmout_config(pwmout_t *obj, int start) { PWM_T *pwm_base = (PWM_T *) NU_MODBASE(obj->pwm); uint32_t chn = NU_MODSUBINDEX(obj->pwm); diff --git a/targets/TARGET_NUVOTON/TARGET_M261/pwmout_api.c b/targets/TARGET_NUVOTON/TARGET_M261/pwmout_api.c index 4ad6deb2629..0030b39ff01 100644 --- a/targets/TARGET_NUVOTON/TARGET_M261/pwmout_api.c +++ b/targets/TARGET_NUVOTON/TARGET_M261/pwmout_api.c @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2019-2020 Nuvoton Technology Corporation * SPDX-License-Identifier: Apache-2.0 * @@ -58,9 +58,9 @@ static const struct nu_modinit_s pwm_modinit_tab[] = { {NC, 0, 0, 0, 0, (IRQn_Type) 0, NULL} }; -static void pwmout_config(pwmout_t* obj, int start); +static void pwmout_config(pwmout_t *obj, int start); -void pwmout_init(pwmout_t* obj, PinName pin) +void pwmout_init(pwmout_t *obj, PinName pin) { obj->pwm = (PWMName) pinmap_peripheral(pin, PinMap_PWM); MBED_ASSERT((int) obj->pwm != NC); @@ -85,7 +85,7 @@ void pwmout_init(pwmout_t* obj, PinName pin) } // NOTE: All channels (identified by PWMName) share a PWM module. This reset will also affect other channels of the same PWM module. - if (! ((struct nu_pwm_var *) modinit->var)->en_msk) { + if (!((struct nu_pwm_var *) modinit->var)->en_msk) { // Reset this module if no channel enabled SYS_ResetModule(modinit->rsetidx); } @@ -102,7 +102,7 @@ void pwmout_init(pwmout_t* obj, PinName pin) pwm_modinit_mask |= 1 << i; } -void pwmout_free(pwmout_t* obj) +void pwmout_free(pwmout_t *obj) { EPWM_T *pwm_base = (EPWM_T *) NU_MODBASE(obj->pwm); uint32_t chn = NU_MODSUBINDEX(obj->pwm); @@ -127,29 +127,29 @@ void pwmout_free(pwmout_t* obj) obj->pin = NC; } -void pwmout_write(pwmout_t* obj, float value) +void pwmout_write(pwmout_t *obj, float value) { - obj->pulsewidth_us = NU_CLAMP((uint32_t) (value * obj->period_us), 0, obj->period_us); + obj->pulsewidth_us = NU_CLAMP((uint32_t)(value * obj->period_us), 0, obj->period_us); pwmout_config(obj, 1); } -float pwmout_read(pwmout_t* obj) +float pwmout_read(pwmout_t *obj) { return NU_CLAMP((((float) obj->pulsewidth_us) / obj->period_us), 0.0f, 1.0f); } -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) { uint32_t period_us_old = obj->period_us; uint32_t pulsewidth_us_old = obj->pulsewidth_us; @@ -158,23 +158,33 @@ void pwmout_period_us(pwmout_t* obj, int us) pwmout_config(obj, 1); } -void pwmout_pulsewidth(pwmout_t* obj, float seconds) +int pwmout_read_period_us(pwmout_t *obj) +{ + return obj->period_us; +} + +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->pulsewidth_us = NU_CLAMP(us, 0, obj->period_us); pwmout_config(obj, 1); } -static void pwmout_config(pwmout_t* obj, int start) +int pwmout_read_pulsewidth_us(pwmout_t *obj) +{ + return obj->pulsewidth_us; +} + +static void pwmout_config(pwmout_t *obj, int start) { EPWM_T *pwm_base = (EPWM_T *) NU_MODBASE(obj->pwm); uint32_t chn = NU_MODSUBINDEX(obj->pwm); diff --git a/targets/TARGET_NUVOTON/TARGET_M451/pwmout_api.c b/targets/TARGET_NUVOTON/TARGET_M451/pwmout_api.c index 80aa592a892..e3089d98749 100644 --- a/targets/TARGET_NUVOTON/TARGET_M451/pwmout_api.c +++ b/targets/TARGET_NUVOTON/TARGET_M451/pwmout_api.c @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - + #include "pwmout_api.h" #if DEVICE_PWMOUT @@ -46,20 +46,20 @@ static const struct nu_modinit_s pwm_modinit_tab[] = { {PWM_0_3, PWM0_MODULE, CLK_CLKSEL2_PWM0SEL_PCLK0, 0, PWM0_RST, PWM0P1_IRQn, &pwm0_var}, {PWM_0_4, PWM0_MODULE, CLK_CLKSEL2_PWM0SEL_PCLK0, 0, PWM0_RST, PWM0P2_IRQn, &pwm0_var}, {PWM_0_5, PWM0_MODULE, CLK_CLKSEL2_PWM0SEL_PCLK0, 0, PWM0_RST, PWM0P2_IRQn, &pwm0_var}, - + {PWM_1_0, PWM1_MODULE, CLK_CLKSEL2_PWM1SEL_PCLK1, 0, PWM1_RST, PWM1P0_IRQn, &pwm1_var}, {PWM_1_1, PWM1_MODULE, CLK_CLKSEL2_PWM1SEL_PCLK1, 0, PWM1_RST, PWM1P0_IRQn, &pwm1_var}, {PWM_1_2, PWM1_MODULE, CLK_CLKSEL2_PWM1SEL_PCLK1, 0, PWM1_RST, PWM1P1_IRQn, &pwm1_var}, {PWM_1_3, PWM1_MODULE, CLK_CLKSEL2_PWM1SEL_PCLK1, 0, PWM1_RST, PWM1P1_IRQn, &pwm1_var}, {PWM_1_4, PWM1_MODULE, CLK_CLKSEL2_PWM1SEL_PCLK1, 0, PWM1_RST, PWM1P2_IRQn, &pwm1_var}, {PWM_1_5, PWM1_MODULE, CLK_CLKSEL2_PWM1SEL_PCLK1, 0, PWM1_RST, PWM1P2_IRQn, &pwm1_var}, - + {NC, 0, 0, 0, 0, (IRQn_Type) 0, NULL} }; -static void pwmout_config(pwmout_t* obj); +static void pwmout_config(pwmout_t *obj); -void pwmout_init(pwmout_t* obj, PinName pin) +void pwmout_init(pwmout_t *obj, PinName pin) { obj->pwm = (PWMName) pinmap_peripheral(pin, PinMap_PWM); MBED_ASSERT((int) obj->pwm != NC); @@ -83,7 +83,7 @@ void pwmout_init(pwmout_t* obj, PinName pin) } // NOTE: All channels (identified by PWMName) share a PWM module. This reset will also affect other channels of the same PWM module. - if (! ((struct nu_pwm_var *) modinit->var)->en_msk) { + if (!((struct nu_pwm_var *) modinit->var)->en_msk) { // Reset this module if no channel enabled SYS_ResetModule(modinit->rsetidx); } @@ -107,22 +107,22 @@ void pwmout_init(pwmout_t* obj, PinName pin) pwm_modinit_mask |= 1 << i; } -void pwmout_free(pwmout_t* obj) +void pwmout_free(pwmout_t *obj) { PWM_T *pwm_base = (PWM_T *) NU_MODBASE(obj->pwm); uint32_t chn = NU_MODSUBINDEX(obj->pwm); PWM_ForceStop(pwm_base, 1 << chn); - + const struct nu_modinit_s *modinit = get_modinit(obj->pwm, pwm_modinit_tab); MBED_ASSERT(modinit != NULL); MBED_ASSERT(modinit->modname == obj->pwm); ((struct nu_pwm_var *) modinit->var)->en_msk &= ~(1 << chn); - - + + if ((((struct nu_pwm_var *) modinit->var)->en_msk & 0x3F) == 0) { CLK_DisableModuleClock(modinit->clkidx); } - + // Mark this module to be deinited. int i = modinit - pwm_modinit_tab; pwm_modinit_mask &= ~(1 << i); @@ -132,29 +132,29 @@ void pwmout_free(pwmout_t* obj) obj->pin = NC; } -void pwmout_write(pwmout_t* obj, float value) +void pwmout_write(pwmout_t *obj, float value) { - obj->pulsewidth_us = NU_CLAMP((uint32_t) (value * obj->period_us), 0, obj->period_us); + obj->pulsewidth_us = NU_CLAMP((uint32_t)(value * obj->period_us), 0, obj->period_us); pwmout_config(obj); } -float pwmout_read(pwmout_t* obj) +float pwmout_read(pwmout_t *obj) { return NU_CLAMP((((float) obj->pulsewidth_us) / obj->period_us), 0.0f, 1.0f); } -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) { uint32_t period_us_old = obj->period_us; uint32_t pulsewidth_us_old = obj->pulsewidth_us; @@ -163,23 +163,33 @@ void pwmout_period_us(pwmout_t* obj, int us) pwmout_config(obj); } -void pwmout_pulsewidth(pwmout_t* obj, float seconds) +int pwmout_read_period_us(pwmout_t *obj) +{ + return obj->period_us; +} + +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->pulsewidth_us = NU_CLAMP(us, 0, obj->period_us); pwmout_config(obj); } -static void pwmout_config(pwmout_t* obj) +int pwmout_read_pulsewidth_us(pwmout_t *obj) +{ + return obj->pulsewidth_us; +} + +static void pwmout_config(pwmout_t *obj) { PWM_T *pwm_base = (PWM_T *) NU_MODBASE(obj->pwm); uint32_t chn = NU_MODSUBINDEX(obj->pwm); diff --git a/targets/TARGET_NUVOTON/TARGET_M480/pwmout_api.c b/targets/TARGET_NUVOTON/TARGET_M480/pwmout_api.c index 10b22f6a325..b71731aeb74 100644 --- a/targets/TARGET_NUVOTON/TARGET_M480/pwmout_api.c +++ b/targets/TARGET_NUVOTON/TARGET_M480/pwmout_api.c @@ -60,9 +60,9 @@ static const struct nu_modinit_s pwm_modinit_tab[] = { {NC, 0, 0, 0, 0, (IRQn_Type) 0, NULL} }; -static void pwmout_config(pwmout_t* obj, int start); +static void pwmout_config(pwmout_t *obj, int start); -void pwmout_init(pwmout_t* obj, PinName pin) +void pwmout_init(pwmout_t *obj, PinName pin) { obj->pwm = (PWMName) pinmap_peripheral(pin, PinMap_PWM); MBED_ASSERT((int) obj->pwm != NC); @@ -86,7 +86,7 @@ void pwmout_init(pwmout_t* obj, PinName pin) } // NOTE: All channels (identified by PWMName) share a PWM module. This reset will also affect other channels of the same PWM module. - if (! ((struct nu_pwm_var *) modinit->var)->en_msk) { + if (!((struct nu_pwm_var *) modinit->var)->en_msk) { // Reset this module if no channel enabled SYS_ResetModule(modinit->rsetidx); } @@ -105,7 +105,7 @@ void pwmout_init(pwmout_t* obj, PinName pin) pwm_modinit_mask |= 1 << i; } -void pwmout_free(pwmout_t* obj) +void pwmout_free(pwmout_t *obj) { EPWM_T *pwm_base = (EPWM_T *) NU_MODBASE(obj->pwm); uint32_t chn = NU_MODSUBINDEX(obj->pwm); @@ -130,29 +130,29 @@ void pwmout_free(pwmout_t* obj) obj->pin = NC; } -void pwmout_write(pwmout_t* obj, float value) +void pwmout_write(pwmout_t *obj, float value) { - obj->pulsewidth_us = NU_CLAMP((uint32_t) (value * obj->period_us), 0, obj->period_us); + obj->pulsewidth_us = NU_CLAMP((uint32_t)(value * obj->period_us), 0, obj->period_us); pwmout_config(obj, 1); } -float pwmout_read(pwmout_t* obj) +float pwmout_read(pwmout_t *obj) { return NU_CLAMP((((float) obj->pulsewidth_us) / obj->period_us), 0.0f, 1.0f); } -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) { uint32_t period_us_old = obj->period_us; uint32_t pulsewidth_us_old = obj->pulsewidth_us; @@ -161,23 +161,33 @@ void pwmout_period_us(pwmout_t* obj, int us) pwmout_config(obj, 1); } -void pwmout_pulsewidth(pwmout_t* obj, float seconds) +int pwmout_read_period_us(pwmout_t *obj) +{ + return obj->period_us; +} + +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->pulsewidth_us = NU_CLAMP(us, 0, obj->period_us); pwmout_config(obj, 1); } -static void pwmout_config(pwmout_t* obj, int start) +int pwmout_read_pulsewidth_us(pwmout_t *obj) +{ + return obj->pulsewidth_us; +} + +static void pwmout_config(pwmout_t *obj, int start) { EPWM_T *pwm_base = (EPWM_T *) NU_MODBASE(obj->pwm); uint32_t chn = NU_MODSUBINDEX(obj->pwm); diff --git a/targets/TARGET_NUVOTON/TARGET_NANO100/pwmout_api.c b/targets/TARGET_NUVOTON/TARGET_NANO100/pwmout_api.c index e959ca770db..c6ad54e1f9f 100644 --- a/targets/TARGET_NUVOTON/TARGET_NANO100/pwmout_api.c +++ b/targets/TARGET_NUVOTON/TARGET_NANO100/pwmout_api.c @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - + #include "pwmout_api.h" #if DEVICE_PWMOUT @@ -52,18 +52,18 @@ static const struct nu_modinit_s pwm_modinit_tab[] = { {PWM_0_1, PWM0_CH01_MODULE, CLK_CLKSEL1_PWM0_CH01_S_HCLK, 0, PWM0_RST, PWM0_IRQn, &pwm0_01_var}, {PWM_0_2, PWM0_CH23_MODULE, CLK_CLKSEL1_PWM0_CH23_S_HCLK, 0, PWM0_RST, PWM0_IRQn, &pwm0_23_var}, {PWM_0_3, PWM0_CH23_MODULE, CLK_CLKSEL1_PWM0_CH23_S_HCLK, 0, PWM0_RST, PWM0_IRQn, &pwm0_23_var}, - + {PWM_1_0, PWM1_CH01_MODULE, CLK_CLKSEL2_PWM1_CH01_S_HCLK, 0, PWM1_RST, PWM1_IRQn, &pwm1_01_var}, {PWM_1_1, PWM1_CH01_MODULE, CLK_CLKSEL2_PWM1_CH01_S_HCLK, 0, PWM1_RST, PWM1_IRQn, &pwm1_01_var}, {PWM_1_2, PWM1_CH23_MODULE, CLK_CLKSEL2_PWM1_CH23_S_HCLK, 0, PWM1_RST, PWM1_IRQn, &pwm1_23_var}, {PWM_1_3, PWM1_CH23_MODULE, CLK_CLKSEL2_PWM1_CH23_S_HCLK, 0, PWM1_RST, PWM1_IRQn, &pwm1_23_var}, - + {NC, 0, 0, 0, 0, (IRQn_Type) 0, NULL} }; -static void pwmout_config(pwmout_t* obj); +static void pwmout_config(pwmout_t *obj); -void pwmout_init(pwmout_t* obj, PinName pin) +void pwmout_init(pwmout_t *obj, PinName pin) { obj->pwm = (PWMName) pinmap_peripheral(pin, PinMap_PWM); MBED_ASSERT((int) obj->pwm != NC); @@ -108,22 +108,22 @@ void pwmout_init(pwmout_t* obj, PinName pin) } } -void pwmout_free(pwmout_t* obj) +void pwmout_free(pwmout_t *obj) { PWM_T *pwm_base = (PWM_T *) NU_MODBASE(obj->pwm); uint32_t chn = NU_MODSUBINDEX(obj->pwm); PWM_ForceStop(pwm_base, 1 << chn); - + const struct nu_modinit_s *modinit = get_modinit(obj->pwm, pwm_modinit_tab); MBED_ASSERT(modinit != NULL); MBED_ASSERT((PWMName) modinit->modname == obj->pwm); ((struct nu_pwm_var *) modinit->var)->en_msk &= ~(1 << chn); - - + + if ((((struct nu_pwm_var *) modinit->var)->en_msk & 0xF) == 0) { CLK_DisableModuleClock(modinit->clkidx); } - + if (((struct nu_pwm_var *) modinit->var)->en_msk == 0) { // Mark this module to be deinited. int i = modinit - pwm_modinit_tab; @@ -135,29 +135,29 @@ void pwmout_free(pwmout_t* obj) obj->pin = NC; } -void pwmout_write(pwmout_t* obj, float value) +void pwmout_write(pwmout_t *obj, float value) { - obj->pulsewidth_us = NU_CLAMP((uint32_t) (value * obj->period_us), 0, obj->period_us); + obj->pulsewidth_us = NU_CLAMP((uint32_t)(value * obj->period_us), 0, obj->period_us); pwmout_config(obj); } -float pwmout_read(pwmout_t* obj) +float pwmout_read(pwmout_t *obj) { return NU_CLAMP((((float) obj->pulsewidth_us) / obj->period_us), 0.0f, 1.0f); } -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) { uint32_t period_us_old = obj->period_us; uint32_t pulsewidth_us_old = obj->pulsewidth_us; @@ -166,23 +166,33 @@ void pwmout_period_us(pwmout_t* obj, int us) pwmout_config(obj); } -void pwmout_pulsewidth(pwmout_t* obj, float seconds) +int pwmout_read_period_us(pwmout_t *obj) +{ + return obj->period_us; +} + +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->pulsewidth_us = NU_CLAMP(us, 0, obj->period_us); pwmout_config(obj); } -static void pwmout_config(pwmout_t* obj) +int pwmout_read_pulsewidth_us(pwmout_t *obj) +{ + return obj->pulsewidth_us; +} + +static void pwmout_config(pwmout_t *obj) { PWM_T *pwm_base = (PWM_T *) NU_MODBASE(obj->pwm); uint32_t chn = NU_MODSUBINDEX(obj->pwm); diff --git a/targets/TARGET_NUVOTON/TARGET_NUC472/pwmout_api.c b/targets/TARGET_NUVOTON/TARGET_NUC472/pwmout_api.c index 0c1d655e7cd..c1891bfc1f2 100644 --- a/targets/TARGET_NUVOTON/TARGET_NUC472/pwmout_api.c +++ b/targets/TARGET_NUVOTON/TARGET_NUC472/pwmout_api.c @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - + #include "pwmout_api.h" #if DEVICE_PWMOUT @@ -47,20 +47,20 @@ static const struct nu_modinit_s pwm_modinit_tab[] = { {PWM_0_3, PWM0CH23_MODULE, CLK_CLKSEL2_PWM0CH23SEL_HIRC, 0, PWM0_RST, PWM0CH3_IRQn, &pwm0_var}, {PWM_0_4, PWM0CH45_MODULE, CLK_CLKSEL2_PWM0CH45SEL_HIRC, 0, PWM0_RST, PWM0CH4_IRQn, &pwm0_var}, {PWM_0_5, PWM0CH45_MODULE, CLK_CLKSEL2_PWM0CH45SEL_HIRC, 0, PWM0_RST, PWM0CH5_IRQn, &pwm0_var}, - + {PWM_1_0, PWM1CH01_MODULE, CLK_CLKSEL2_PWM1CH01SEL_HIRC, 0, PWM1_RST, PWM1CH0_IRQn, &pwm1_var}, {PWM_1_1, PWM1CH01_MODULE, CLK_CLKSEL2_PWM1CH01SEL_HIRC, 0, PWM1_RST, PWM1CH1_IRQn, &pwm1_var}, {PWM_1_2, PWM1CH23_MODULE, CLK_CLKSEL2_PWM1CH23SEL_HIRC, 0, PWM1_RST, PWM1CH2_IRQn, &pwm1_var}, {PWM_1_3, PWM1CH23_MODULE, CLK_CLKSEL2_PWM1CH23SEL_HIRC, 0, PWM1_RST, PWM1CH3_IRQn, &pwm1_var}, {PWM_1_4, PWM1CH45_MODULE, CLK_CLKSEL2_PWM1CH45SEL_HIRC, 0, PWM1_RST, PWM1CH4_IRQn, &pwm1_var}, {PWM_1_5, PWM1CH45_MODULE, CLK_CLKSEL2_PWM1CH45SEL_HIRC, 0, PWM1_RST, PWM1CH5_IRQn, &pwm1_var}, - + {NC, 0, 0, 0, 0, (IRQn_Type) 0, NULL} }; -static void pwmout_config(pwmout_t* obj); +static void pwmout_config(pwmout_t *obj); -void pwmout_init(pwmout_t* obj, PinName pin) +void pwmout_init(pwmout_t *obj, PinName pin) { obj->pwm = (PWMName) pinmap_peripheral(pin, PinMap_PWM); MBED_ASSERT((int) obj->pwm != NC); @@ -83,7 +83,7 @@ void pwmout_init(pwmout_t* obj, PinName pin) // Enable clock of paired channels CLK_EnableModuleClock(modinit->clkidx); - + // FIXME: PWM_1_2/3 design bug. PWM_1_2/3 also require PWM_1_0/1 clock enabled. if (obj->pwm == PWM_1_2 || obj->pwm == PWM_1_3) { CLK_EnableModuleClock(PWM1CH01_MODULE); @@ -91,7 +91,7 @@ void pwmout_init(pwmout_t* obj, PinName pin) } // NOTE: All channels (identified by PWMName) share a PWM module. This reset will also affect other channels of the same PWM module. - if (! ((struct nu_pwm_var *) modinit->var)->en_msk) { + if (!((struct nu_pwm_var *) modinit->var)->en_msk) { // Reset this module if no channel enabled SYS_ResetModule(modinit->rsetidx); } @@ -102,30 +102,30 @@ void pwmout_init(pwmout_t* obj, PinName pin) obj->period_us = 1000 * 10; obj->pulsewidth_us = 0; pwmout_config(obj); - + // Enable output of the specified PWM channel PWM_EnableOutput(pwm_base, 1 << chn); PWM_Start(pwm_base, 1 << chn); - + ((struct nu_pwm_var *) modinit->var)->en_msk |= 1 << chn; - + // Mark this module to be inited. int i = modinit - pwm_modinit_tab; pwm_modinit_mask |= 1 << i; } -void pwmout_free(pwmout_t* obj) +void pwmout_free(pwmout_t *obj) { PWM_T *pwm_base = (PWM_T *) NU_MODBASE(obj->pwm); uint32_t chn = NU_MODSUBINDEX(obj->pwm); PWM_ForceStop(pwm_base, 1 << chn); - + const struct nu_modinit_s *modinit = get_modinit(obj->pwm, pwm_modinit_tab); MBED_ASSERT(modinit != NULL); MBED_ASSERT(modinit->modname == obj->pwm); ((struct nu_pwm_var *) modinit->var)->en_msk &= ~(1 << chn); - - + + if ((((struct nu_pwm_var *) modinit->var)->en_msk & (0x3 << (chn / 2 * 2))) == 0) { // FIXME: PWM_1_2/3 design bug. PWM_1_2/3 also require PWM_1_0/1 clock enabled. switch (obj->pwm) { @@ -134,51 +134,51 @@ void pwmout_free(pwmout_t* obj) if (pwm1_var.en_msk & 0xC) { break; } - + case PWM_1_2: case PWM_1_3: - if (! (pwm1_var.en_msk & 0x3)) { + if (!(pwm1_var.en_msk & 0x3)) { CLK_DisableModuleClock(PWM1CH01_MODULE); } - + default: // Disable clock of paired channels CLK_DisableModuleClock(modinit->clkidx); } } - + // Mark this module to be deinited. int i = modinit - pwm_modinit_tab; pwm_modinit_mask &= ~(1 << i); - + // Free up pins gpio_set(obj->pin); obj->pin = NC; } -void pwmout_write(pwmout_t* obj, float value) +void pwmout_write(pwmout_t *obj, float value) { - obj->pulsewidth_us = NU_CLAMP((uint32_t) (value * obj->period_us), 0, obj->period_us); + obj->pulsewidth_us = NU_CLAMP((uint32_t)(value * obj->period_us), 0, obj->period_us); pwmout_config(obj); } -float pwmout_read(pwmout_t* obj) +float pwmout_read(pwmout_t *obj) { return NU_CLAMP((((float) obj->pulsewidth_us) / obj->period_us), 0.0f, 1.0f); } -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) { uint32_t period_us_old = obj->period_us; uint32_t pulsewidth_us_old = obj->pulsewidth_us; @@ -187,23 +187,33 @@ void pwmout_period_us(pwmout_t* obj, int us) pwmout_config(obj); } -void pwmout_pulsewidth(pwmout_t* obj, float seconds) +int pwmout_read_period_us(pwmout_t *obj) +{ + return obj->period_us; +} + +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->pulsewidth_us = NU_CLAMP(us, 0, obj->period_us); pwmout_config(obj); } -static void pwmout_config(pwmout_t* obj) +int pwmout_read_pulsewidth_us(pwmout_t *obj) +{ + return obj->pulsewidth_us; +} + +static void pwmout_config(pwmout_t *obj) { PWM_T *pwm_base = (PWM_T *) NU_MODBASE(obj->pwm); uint32_t chn = NU_MODSUBINDEX(obj->pwm); diff --git a/targets/TARGET_NXP/TARGET_LPC11U6X/pwmout_api.c b/targets/TARGET_NXP/TARGET_LPC11U6X/pwmout_api.c index b5751d109b3..be7f9808ac2 100644 --- a/targets/TARGET_NXP/TARGET_LPC11U6X/pwmout_api.c +++ b/targets/TARGET_NXP/TARGET_LPC11U6X/pwmout_api.c @@ -25,36 +25,39 @@ static const PinMap PinMap_PWM[] = { {P1_19, SCT0_0, 2}, - {P2_2 , SCT0_1, 3}, - {P2_7 , SCT0_2, 2}, + {P2_2, SCT0_1, 3}, + {P2_7, SCT0_2, 2}, {P1_13, SCT0_3, 2}, {P2_16, SCT1_0, 1}, {P2_17, SCT1_1, 1}, {P2_18, SCT1_2, 1}, {P2_19, SCT1_3, 1}, - {NC , NC ,0} + {NC, NC, 0} }; static LPC_SCT0_Type *SCTs[SCT_CHANNELS] = { - (LPC_SCT0_Type*)LPC_SCT0, - (LPC_SCT0_Type*)LPC_SCT1, + (LPC_SCT0_Type *)LPC_SCT0, + (LPC_SCT0_Type *)LPC_SCT1, }; // bit flags for used SCTs static unsigned char sct_used = 0; -static int get_available_sct(void) { +static int get_available_sct(void) +{ int i; - for (i=0; iSYSAHBCLKCTRL |= (1UL << 31); // Clear peripheral reset the SCT: - LPC_SYSCON->PRESETCTRL |= (1 << (obj->pwm_ch + 9)); + LPC_SYSCON->PRESETCTRL |= (1 << (obj->pwm_ch + 9)); pinmap_pinout(pin, PinMap_PWM); - LPC_SCT0_Type* pwm = obj->pwm; - + LPC_SCT0_Type *pwm = obj->pwm; + // Unified 32-bit counter, autolimit pwm->CONFIG |= ((0x3 << 17) | 0x01); - + // halt and clear the counter pwm->CTRL |= (1 << 2) | (1 << 3); - - switch(pwm_mapped) { + + switch (pwm_mapped) { case SCT0_0: case SCT1_0: pwm->OUT0_SET = (1 << 0); // event 0 @@ -116,10 +119,11 @@ 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); + pwmout_write(obj, 0); } -void pwmout_free(pwmout_t* obj) { +void pwmout_free(pwmout_t *obj) +{ sct_used &= ~(1 << obj->pwm_ch); if (sct_used == 0) { // Disable the SCT clock @@ -127,8 +131,9 @@ void pwmout_free(pwmout_t* obj) { } } -void pwmout_write(pwmout_t* obj, float value) { - LPC_SCT0_Type* pwm = obj->pwm; +void pwmout_write(pwmout_t *obj, float value) +{ + LPC_SCT0_Type *pwm = obj->pwm; if (value < 0.0f) { value = 0.0; } else if (value > 1.0f) { @@ -137,7 +142,7 @@ void pwmout_write(pwmout_t* obj, float value) { uint32_t t_on = (uint32_t)((float)(pwm->MATCHREL0 + 1) * value); if (t_on > 0) { pwm->MATCHREL1 = t_on - 1; - + // Un-halt the timer and ensure the new pulse-width takes immediate effect if necessary if (pwm->CTRL & (1 << 2)) { pwm->MATCH1 = pwm->MATCHREL1; @@ -150,34 +155,38 @@ void pwmout_write(pwmout_t* obj, float value) { } } -float pwmout_read(pwmout_t* obj) { - LPC_SCT0_Type* pwm = obj->pwm; +float pwmout_read(pwmout_t *obj) +{ + LPC_SCT0_Type *pwm = obj->pwm; uint32_t t_off = pwm->MATCHREL0 + 1; uint32_t t_on = (!(pwm->CTRL & (1 << 2))) ? pwm->MATCHREL1 + 1 : 0; - float v = (float)t_on/(float)t_off; + float v = (float)t_on / (float)t_off; return (v > 1.0f) ? (1.0f) : (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) { - LPC_SCT0_Type* pwm = obj->pwm; +void pwmout_period_us(pwmout_t *obj, int us) +{ + LPC_SCT0_Type *pwm = obj->pwm; uint32_t t_off = pwm->MATCHREL0 + 1; uint32_t t_on = (!(pwm->CTRL & (1 << 2))) ? pwm->MATCHREL1 + 1 : 0; - float v = (float)t_on/(float)t_off; + float v = (float)t_on / (float)t_off; uint32_t period_ticks = (uint32_t)(((uint64_t)SystemCoreClock * (uint64_t)us) / (uint64_t)1000000); uint32_t pulsewidth_ticks = period_ticks * v; pwm->MATCHREL0 = period_ticks - 1; if (pulsewidth_ticks > 0) { pwm->MATCHREL1 = pulsewidth_ticks - 1; - + // Un-halt the timer and ensure the new period & pulse-width take immediate effect if necessary if (pwm->CTRL & (1 << 2)) { pwm->MATCH0 = pwm->MATCHREL0; @@ -188,25 +197,33 @@ void pwmout_period_us(pwmout_t* obj, int us) { // Halt the timer and force the output low pwm->CTRL |= (1 << 2) | (1 << 3); pwm->OUTPUT = 0x00000000; - + // Ensure the new period will take immediate effect when the timer is un-halted pwm->MATCH0 = pwm->MATCHREL0; } } -void pwmout_pulsewidth(pwmout_t* obj, float seconds) { +int pwmout_read_period_us(pwmout_t *obj) +{ + return pwm->MATCHREL0 + 1; +} + +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) { - LPC_SCT0_Type* pwm = obj->pwm; +void pwmout_pulsewidth_us(pwmout_t *obj, int us) +{ + LPC_SCT0_Type *pwm = obj->pwm; if (us > 0) { pwm->MATCHREL1 = (uint32_t)(((uint64_t)SystemCoreClock * (uint64_t)us) / (uint64_t)1000000) - 1; - + // Un-halt the timer and ensure the new pulse-width takes immediate effect if necessary if (pwm->CTRL & (1 << 2)) { pwm->MATCH1 = pwm->MATCHREL1; @@ -219,6 +236,11 @@ void pwmout_pulsewidth_us(pwmout_t* obj, int us) { } } +int pwmout_read_pulsewidth_us(pwmout_t *obj) +{ + return (!(pwm->CTRL & (1 << 2))) ? pwm->MATCHREL1 + 1 : 0; +} + const PinMap *pwmout_pinmap() { return PinMap_PWM; diff --git a/targets/TARGET_NXP/TARGET_LPC11XX_11CXX/pwmout_api.c b/targets/TARGET_NXP/TARGET_LPC11XX_11CXX/pwmout_api.c index 8226a549f8a..90f9e794665 100644 --- a/targets/TARGET_NXP/TARGET_LPC11XX_11CXX/pwmout_api.c +++ b/targets/TARGET_NXP/TARGET_LPC11XX_11CXX/pwmout_api.c @@ -28,17 +28,17 @@ */ static const PinMap PinMap_PWM[] = { /* CT16B0 */ - {P0_8 , PWM_1, 0x02}, /* MR0 */ - {P0_9 , PWM_2, 0x02}, /* MR1 */ + {P0_8, PWM_1, 0x02}, /* MR0 */ + {P0_9, PWM_2, 0x02}, /* MR1 */ /* CT16B1 */ - {P1_9 , PWM_3, 0x01}, /* MR0 */ + {P1_9, PWM_3, 0x01}, /* MR0 */ {P1_10, PWM_4, 0x02}, /* MR1 */ /* CT32B0 */ - {P0_1 , PWM_5, 0x02}, /* MR2 */ + {P0_1, PWM_5, 0x02}, /* MR2 */ - {NC , NC ,0x00} + {NC, NC, 0x00} }; typedef struct { @@ -61,49 +61,52 @@ static LPC_TMR_TypeDef *Timers[3] = { LPC_TMR32B0 }; -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); obj->pwm = pwm; - + // Timer registers timer_mr tid = pwm_timer_map[pwm]; LPC_TMR_TypeDef *timer = Timers[tid.timer]; - + // Disable timer timer->TCR = 0; - + // Power the correspondent timer LPC_SYSCON->SYSAHBCLKCTRL |= 1 << (tid.timer + 7); - + /* Enable PWM function */ - timer->PWMC = (1 << 3)|(1 << 2)|(1 << 1)|(1 << 0); - + timer->PWMC = (1 << 3) | (1 << 2) | (1 << 1) | (1 << 0); + /* Reset Functionality on MR3 controlling the PWM period */ timer->MCR = 1 << 10; - + if (timer == LPC_TMR16B0 || timer == LPC_TMR16B1) { - /* Set 16-bit timer prescaler to avoid timer expire for default 20ms */ - /* This can be also modified by user application, but the prescaler value */ - /* might be trade-off to timer accuracy */ + /* Set 16-bit timer prescaler to avoid timer expire for default 20ms */ + /* This can be also modified by user application, but the prescaler value */ + /* might be trade-off to timer accuracy */ timer->PR = 30; } // default to 20ms: standard for servos, and fine for e.g. brightness control pwmout_period_ms(obj, 20); - pwmout_write (obj, 0); - + pwmout_write(obj, 0); + // Wire pinout pinmap_pinout(pin, PinMap_PWM); } -void pwmout_free(pwmout_t* obj) { +void pwmout_free(pwmout_t *obj) +{ // [TODO] } -void pwmout_write(pwmout_t* obj, float value) { +void pwmout_write(pwmout_t *obj, float value) +{ if (value < 0.0f) { value = 0.0; } else if (value > 1.0f) { @@ -123,10 +126,11 @@ void pwmout_write(pwmout_t* obj, float value) { timer->TCR = TCR_CNT_EN; } -float pwmout_read(pwmout_t* obj) { +float pwmout_read(pwmout_t *obj) +{ timer_mr tid = pwm_timer_map[obj->pwm]; LPC_TMR_TypeDef *timer = Timers[tid.timer]; - + float v = (float)(timer->MR3 - timer->MR[tid.mr]) / (float)(timer->MR3); if (timer->MR[tid.mr] > timer->MR3) { v = 0.0f; @@ -134,19 +138,22 @@ float pwmout_read(pwmout_t* obj) { return (v > 1.0f) ? (1.0f) : (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) +{ int i = 0; uint32_t period_ticks; - + timer_mr tid = pwm_timer_map[obj->pwm]; LPC_TMR_TypeDef *timer = Timers[tid.timer]; uint32_t old_period_ticks = timer->MR3; @@ -154,10 +161,10 @@ void pwmout_period_us(pwmout_t* obj, int us) { timer->TCR = TCR_RESET; timer->MR3 = period_ticks; - + // Scale the pulse width to preserve the duty ratio if (old_period_ticks > 0) { - for (i=0; i<3; i++) { + for (i = 0; i < 3; i++) { uint32_t t_off = period_ticks - (uint32_t)(((uint64_t)timer->MR[i] * (uint64_t)period_ticks) / (uint64_t)old_period_ticks); timer->MR[i] = t_off; } @@ -165,19 +172,29 @@ void pwmout_period_us(pwmout_t* obj, int us) { timer->TCR = TCR_CNT_EN; } -void pwmout_pulsewidth(pwmout_t* obj, float seconds) { +int pwmout_read_period_us(pwmout_t *obj) +{ + timer_mr tid = pwm_timer_map[obj->pwm]; + LPC_TMR_TypeDef *timer = Timers[tid.timer]; + return (timer->MR3); +} + +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) +{ timer_mr tid = pwm_timer_map[obj->pwm]; LPC_TMR_TypeDef *timer = Timers[tid.timer]; uint32_t t_on = (uint32_t)((((uint64_t)SystemCoreClock * (uint64_t)us) / (uint64_t)1000000) / (timer->PR + 1)); - + timer->TCR = TCR_RESET; if (t_on > timer->MR3) { pwmout_period_us(obj, us); @@ -187,6 +204,13 @@ void pwmout_pulsewidth_us(pwmout_t* obj, int us) { timer->TCR = TCR_CNT_EN; } +int pwmout_read_pulsewidth_us(pwmout_t *obj) +{ + timer_mr tid = pwm_timer_map[obj->pwm]; + LPC_TMR_TypeDef *timer = Timers[tid.timer]; + return (timer->MR3 - timer->MR[tid.mr]); +} + const PinMap *pwmout_pinmap() { return PinMap_PWM; diff --git a/targets/TARGET_NXP/TARGET_LPC176X/pwmout_api.c b/targets/TARGET_NXP/TARGET_LPC176X/pwmout_api.c index dd4f2fe4932..538bbfe7fb7 100644 --- a/targets/TARGET_NXP/TARGET_LPC176X/pwmout_api.c +++ b/targets/TARGET_NXP/TARGET_LPC176X/pwmout_api.c @@ -29,12 +29,12 @@ static const PinMap PinMap_PWM[] = { {P1_23, PWM_4, 2}, {P1_24, PWM_5, 2}, {P1_26, PWM_6, 2}, - {P2_0 , PWM_1, 1}, - {P2_1 , PWM_2, 1}, - {P2_2 , PWM_3, 1}, - {P2_3 , PWM_4, 1}, - {P2_4 , PWM_5, 1}, - {P2_5 , PWM_6, 1}, + {P2_0, PWM_1, 1}, + {P2_1, PWM_2, 1}, + {P2_2, PWM_3, 1}, + {P2_3, PWM_4, 1}, + {P2_4, PWM_5, 1}, + {P2_5, PWM_6, 1}, {P3_25, PWM_2, 3}, {P3_26, PWM_3, 3}, {NC, NC, 0} @@ -54,77 +54,84 @@ __IO uint32_t *PWM_MATCH[] = { static unsigned int pwm_clock_mhz; -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); obj->pwm = pwm; obj->MR = PWM_MATCH[pwm]; - + // ensure the power is on LPC_SC->PCONP |= 1 << 6; - + // ensure clock to /4 LPC_SC->PCLKSEL0 &= ~(0x3 << 12); // pclk = /4 LPC_PWM1->PR = 0; // no pre-scale - + // ensure single PWM mode LPC_PWM1->MCR = 1 << 1; // reset TC on match 0 - + // enable the specific PWM output LPC_PWM1->PCR |= 1 << (8 + pwm); - + pwm_clock_mhz = SystemCoreClock / 4000000; - + // default to 20ms: standard for servos, and fine for e.g. brightness control pwmout_period_ms(obj, 20); - pwmout_write (obj, 0); - + pwmout_write(obj, 0); + // Wire pinout pinmap_pinout(pin, PinMap_PWM); } -void pwmout_free(pwmout_t* obj) { +void pwmout_free(pwmout_t *obj) +{ // [TODO] } -void pwmout_write(pwmout_t* obj, float value) { +void pwmout_write(pwmout_t *obj, float value) +{ if (value < 0.0f) { value = 0.0; } else if (value > 1.0f) { value = 1.0; } - + // set channel match to percentage uint32_t v = (uint32_t)((float)(LPC_PWM1->MR0) * value); - + // workaround for PWM1[1] - Never make it equal MR0, else we get 1 cycle dropout if (v == LPC_PWM1->MR0) { v++; } - + *obj->MR = v; - + // accept on next period start LPC_PWM1->LER |= 1 << obj->pwm; } -float pwmout_read(pwmout_t* obj) { +float pwmout_read(pwmout_t *obj) +{ float v = (float)(*obj->MR) / (float)(LPC_PWM1->MR0); return (v > 1.0f) ? (1.0f) : (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) +{ // calculate number of ticks uint32_t ticks = pwm_clock_mhz * us; @@ -146,30 +153,43 @@ void pwmout_period_us(pwmout_t* obj, int us) { LPC_PWM1->TCR = TCR_CNT_EN | TCR_PWM_EN; } -void pwmout_pulsewidth(pwmout_t* obj, float seconds) { +int pwmout_read_period_us(pwmout_t *obj) +{ + return (LPC_PWM1->MR0); +} + +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) +{ // calculate number of ticks uint32_t v = pwm_clock_mhz * us; - + // workaround for PWM1[1] - Never make it equal MR0, else we get 1 cycle dropout if (v == LPC_PWM1->MR0) { v++; } - + // set the match register value *obj->MR = v; - + // set the channel latch to update value at next period start LPC_PWM1->LER |= 1 << obj->pwm; } +int pwmout_read_pulsewidth_us(pwmout_t *obj) +{ + return (*obj->MR); +} + const PinMap *pwmout_pinmap() { return PinMap_PWM; diff --git a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_IMX/pwmout_api.c b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_IMX/pwmout_api.c index f6c32935c40..1f8dd319d34 100644 --- a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_IMX/pwmout_api.c +++ b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_IMX/pwmout_api.c @@ -32,7 +32,7 @@ static PWM_Type *const pwm_addrs[] = PWM_BASE_PTRS; extern void pwm_setup(); extern uint32_t pwm_get_clock(); -void pwmout_init(pwmout_t* obj, PinName pin) +void pwmout_init(pwmout_t *obj, PinName pin) { PWMName pwm = (PWMName)pinmap_peripheral(pin, PinMap_PWM); MBED_ASSERT(pwm != (PWMName)NC); @@ -93,7 +93,7 @@ void pwmout_init(pwmout_t* obj, PinName pin) pinmap_pinout(pin, PinMap_PWM); } -void pwmout_free(pwmout_t* obj) +void pwmout_free(pwmout_t *obj) { uint32_t instance = (obj->pwm_name >> PWM_SHIFT) & 0x7; uint32_t module = (obj->pwm_name >> PWM_MODULE_SHIFT) & 0x3; @@ -101,7 +101,7 @@ void pwmout_free(pwmout_t* obj) PWM_StopTimer(pwm_addrs[instance], (1 << module)); } -void pwmout_write(pwmout_t* obj, float value) +void pwmout_write(pwmout_t *obj, float value) { if (value < 0.0f) { value = 0.0f; @@ -130,7 +130,7 @@ void pwmout_write(pwmout_t* obj, float value) PWM_SetPwmLdok(base, (1 << module), true); } -float pwmout_read(pwmout_t* obj) +float pwmout_read(pwmout_t *obj) { PWM_Type *base = pwm_addrs[(obj->pwm_name >> PWM_SHIFT) & 0x7]; uint32_t module = (obj->pwm_name >> PWM_MODULE_SHIFT) & 0x3; @@ -153,18 +153,18 @@ float pwmout_read(pwmout_t* obj) return (v > 1.0f) ? (1.0f) : (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) { PWM_Type *base = pwm_addrs[(obj->pwm_name >> PWM_SHIFT) & 0x7]; uint32_t module = (obj->pwm_name >> PWM_MODULE_SHIFT) & 0x3; @@ -194,17 +194,24 @@ void pwmout_period_us(pwmout_t* obj, int us) pwmout_write(obj, dc); } -void pwmout_pulsewidth(pwmout_t* obj, float seconds) +int pwmout_read_period_us(pwmout_t *obj) +{ + PWM_Type *base = pwm_addrs[(obj->pwm_name >> PWM_SHIFT) & 0x7]; + uint32_t module = (obj->pwm_name >> PWM_MODULE_SHIFT) & 0x3; + return (base->SM[module].VAL1) & PWM_VAL1_VAL1_MASK; +} + +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) { PWM_Type *base = pwm_addrs[(obj->pwm_name >> PWM_SHIFT) & 0x7]; uint32_t module = (obj->pwm_name >> PWM_MODULE_SHIFT) & 0x3; @@ -223,6 +230,20 @@ void pwmout_pulsewidth_us(pwmout_t* obj, int us) PWM_SetPwmLdok(base, (1 << module), true); } +int pwmout_read_pulsewidth_us(pwmout_t *obj) { + uint16_t count; + PWM_Type *base = pwm_addrs[(obj->pwm_name >> PWM_SHIFT) & 0x7]; + uint32_t module = (obj->pwm_name >> PWM_MODULE_SHIFT) & 0x3; + uint32_t pwmchannel = obj->pwm_name & 0x1; + if (pwmchannel == 0) + { + count = (base->SM[module].VAL3) & PWM_VAL3_VAL3_MASK; + } else + { + count = (base->SM[module].VAL5) & PWM_VAL5_VAL5_MASK; + } +} + const PinMap *pwmout_pinmap() { return PinMap_PWM; diff --git a/targets/TARGET_RENESAS/TARGET_RZ_A1XX/pwmout_api.c b/targets/TARGET_RENESAS/TARGET_RZ_A1XX/pwmout_api.c index 2a93d3697c1..a5d9a457322 100644 --- a/targets/TARGET_RENESAS/TARGET_RZ_A1XX/pwmout_api.c +++ b/targets/TARGET_RENESAS/TARGET_RZ_A1XX/pwmout_api.c @@ -46,22 +46,22 @@ typedef enum { } PWMType; static const PWMType PORT[] = { - PWM1A, // PWM_PWM1A - PWM1B, // PWM_PWM1B - PWM1C, // PWM_PWM1C - PWM1D, // PWM_PWM1D - PWM1E, // PWM_PWM1E - PWM1F, // PWM_PWM1F - PWM1G, // PWM_PWM1G - PWM1H, // PWM_PWM1H - PWM2A, // PWM_PWM2A - PWM2B, // PWM_PWM2B - PWM2C, // PWM_PWM2C - PWM2D, // PWM_PWM2D - PWM2E, // PWM_PWM2E - PWM2F, // PWM_PWM2F - PWM2G, // PWM_PWM2G - PWM2H, // PWM_PWM2H + PWM1A, // PWM_PWM1A + PWM1B, // PWM_PWM1B + PWM1C, // PWM_PWM1C + PWM1D, // PWM_PWM1D + PWM1E, // PWM_PWM1E + PWM1F, // PWM_PWM1F + PWM1G, // PWM_PWM1G + PWM1H, // PWM_PWM1H + PWM2A, // PWM_PWM2A + PWM2B, // PWM_PWM2B + PWM2C, // PWM_PWM2C + PWM2D, // PWM_PWM2D + PWM2E, // PWM_PWM2E + PWM2F, // PWM_PWM2F + PWM2G, // PWM_PWM2G + PWM2H, // PWM_PWM2H }; static __IO uint16_t *PWM_MATCH[] = { @@ -111,23 +111,23 @@ typedef enum { typedef struct { MTU2_PWMType port; - __IO uint16_t * pulse1; - __IO uint16_t * pulse2; - __IO uint16_t * period1; - __IO uint16_t * period2; - __IO uint8_t * tior; - __IO uint8_t * tcr; - __IO uint8_t * tmdr; + __IO uint16_t *pulse1; + __IO uint16_t *pulse2; + __IO uint16_t *period1; + __IO uint16_t *period2; + __IO uint8_t *tior; + __IO uint8_t *tcr; + __IO uint8_t *tmdr; int max_period; } st_mtu2_ctrl_t; static st_mtu2_ctrl_t mtu2_ctl[] = { { TIOC0A, &MTU2TGRA_0, &MTU2TGRC_0, &MTU2TGRB_0, &MTU2TGRD_0, &MTU2TIORH_0, &MTU2TCR_0, &MTU2TMDR_0, 125000 }, // PWM_TIOC0A { TIOC0C, &MTU2TGRC_0, &MTU2TGRA_0, &MTU2TGRB_0, &MTU2TGRD_0, &MTU2TIORL_0, &MTU2TCR_0, &MTU2TMDR_0, 125000 }, // PWM_TIOC0C - { TIOC1A, &MTU2TGRA_1, NULL , &MTU2TGRB_1, NULL , &MTU2TIOR_1 , &MTU2TCR_1, &MTU2TMDR_1, 503000 }, // PWM_TIOC1A - { TIOC1B, &MTU2TGRB_1, NULL , &MTU2TGRA_1, NULL , &MTU2TIOR_1 , &MTU2TCR_1, &MTU2TMDR_1, 503000 }, // PWM_TIOC1B - { TIOC2A, &MTU2TGRA_2, NULL , &MTU2TGRB_2, NULL , &MTU2TIOR_2 , &MTU2TCR_2, &MTU2TMDR_2, 2000000 }, // PWM_TIOC2A - { TIOC2B, &MTU2TGRB_2, NULL , &MTU2TGRA_2, NULL , &MTU2TIOR_2 , &MTU2TCR_2, &MTU2TMDR_2, 2000000 }, // PWM_TIOC2B + { TIOC1A, &MTU2TGRA_1, NULL, &MTU2TGRB_1, NULL, &MTU2TIOR_1, &MTU2TCR_1, &MTU2TMDR_1, 503000 }, // PWM_TIOC1A + { TIOC1B, &MTU2TGRB_1, NULL, &MTU2TGRA_1, NULL, &MTU2TIOR_1, &MTU2TCR_1, &MTU2TMDR_1, 503000 }, // PWM_TIOC1B + { TIOC2A, &MTU2TGRA_2, NULL, &MTU2TGRB_2, NULL, &MTU2TIOR_2, &MTU2TCR_2, &MTU2TMDR_2, 2000000 }, // PWM_TIOC2A + { TIOC2B, &MTU2TGRB_2, NULL, &MTU2TGRA_2, NULL, &MTU2TIOR_2, &MTU2TCR_2, &MTU2TMDR_2, 2000000 }, // PWM_TIOC2B { TIOC3A, &MTU2TGRA_3, &MTU2TGRC_3, &MTU2TGRB_3, &MTU2TGRD_3, &MTU2TIORH_3, &MTU2TCR_3, &MTU2TMDR_3, 2000000 }, // PWM_TIOC3A { TIOC3C, &MTU2TGRC_3, &MTU2TGRA_3, &MTU2TGRB_3, &MTU2TGRD_3, &MTU2TIORL_3, &MTU2TCR_3, &MTU2TMDR_3, 2000000 }, // PWM_TIOC3C { TIOC4A, &MTU2TGRA_4, &MTU2TGRC_4, &MTU2TGRB_4, &MTU2TGRD_4, &MTU2TIORH_4, &MTU2TCR_4, &MTU2TMDR_4, 2000000 }, // PWM_TIOC4A @@ -138,7 +138,8 @@ static uint16_t init_mtu2_period_ch[5] = {0}; static int32_t mtu2_period_ch[5] = {1, 1, 1, 1, 1}; #endif -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); @@ -150,7 +151,7 @@ void pwmout_init(pwmout_t* obj, PinName pin) { mtu2_init(); obj->pwm = pwm; - st_mtu2_ctrl_t * p_mtu2_ctl = &mtu2_ctl[(int)(obj->pwm - MTU2_PWM_OFFSET)]; + st_mtu2_ctrl_t *p_mtu2_ctl = &mtu2_ctl[(int)(obj->pwm - MTU2_PWM_OFFSET)]; obj->ch = (uint8_t)(((uint32_t)p_mtu2_ctl->port & 0x000000F0) >> 4); if (obj->ch == 4) { @@ -208,18 +209,20 @@ void pwmout_init(pwmout_t* obj, PinName pin) { } } -void pwmout_free(pwmout_t* obj) { +void pwmout_free(pwmout_t *obj) +{ pwmout_write(obj, 0); mtu2_free(); } -void pwmout_write(pwmout_t* obj, float value) { +void pwmout_write(pwmout_t *obj, float value) +{ uint32_t wk_cycle; if (obj->pwm >= MTU2_PWM_OFFSET) { #ifdef FUMC_MTU2_PWM /* PWM by MTU2 */ - st_mtu2_ctrl_t * p_mtu2_ctl = &mtu2_ctl[(int)(obj->pwm - MTU2_PWM_OFFSET)]; + st_mtu2_ctrl_t *p_mtu2_ctl = &mtu2_ctl[(int)(obj->pwm - MTU2_PWM_OFFSET)]; uint8_t tmp_tstr_st; if (value < 0.0f) { @@ -229,7 +232,7 @@ void pwmout_write(pwmout_t* obj, float value) { } else { // Do Nothing } - wk_cycle = (uint32_t)*p_mtu2_ctl->period1; + wk_cycle = (uint32_t) * p_mtu2_ctl->period1; if ((obj->ch == 4) || (obj->ch == 3)) { tmp_tstr_st = (1 << (obj->ch + 3)); } else { @@ -291,7 +294,8 @@ void pwmout_write(pwmout_t* obj, float value) { } } -float pwmout_read(pwmout_t* obj) { +float pwmout_read(pwmout_t *obj) +{ uint32_t wk_cycle; float value; @@ -299,10 +303,10 @@ float pwmout_read(pwmout_t* obj) { #ifdef FUMC_MTU2_PWM /* PWM by MTU2 */ uint32_t wk_pulse; - st_mtu2_ctrl_t * p_mtu2_ctl = &mtu2_ctl[(int)(obj->pwm - MTU2_PWM_OFFSET)]; + st_mtu2_ctrl_t *p_mtu2_ctl = &mtu2_ctl[(int)(obj->pwm - MTU2_PWM_OFFSET)]; - wk_cycle = (uint32_t)*p_mtu2_ctl->period1; - wk_pulse = (uint32_t)*p_mtu2_ctl->pulse1; + wk_cycle = (uint32_t) * p_mtu2_ctl->period1; + wk_pulse = (uint32_t) * p_mtu2_ctl->pulse1; value = ((float)wk_pulse / (float)wk_cycle); #endif } else { @@ -320,16 +324,19 @@ float pwmout_read(pwmout_t* obj) { return (value > 1.0f) ? (1.0f) : (value); } -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); } #ifdef FUNC_MOTOR_CTL_PWM -static void set_duty_again(__IO uint16_t *p_pwmpbfr, uint16_t last_cycle, uint16_t new_cycle){ +static void set_duty_again(__IO uint16_t *p_pwmpbfr, uint16_t last_cycle, uint16_t new_cycle) +{ uint16_t wk_pwmpbfr; float value; uint16_t v; @@ -342,7 +349,8 @@ static void set_duty_again(__IO uint16_t *p_pwmpbfr, uint16_t last_cycle, uint16 #endif #ifdef FUMC_MTU2_PWM -static void set_mtu2_duty_again(__IO uint16_t *p_pwmpbfr, uint16_t last_cycle, uint16_t new_cycle){ +static void set_mtu2_duty_again(__IO uint16_t *p_pwmpbfr, uint16_t last_cycle, uint16_t new_cycle) +{ uint16_t wk_pwmpbfr; float value; @@ -353,7 +361,8 @@ static void set_mtu2_duty_again(__IO uint16_t *p_pwmpbfr, uint16_t last_cycle, u #endif // 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) +{ uint32_t pclk_base; uint32_t wk_cycle; uint32_t wk_cks = 0; @@ -365,7 +374,7 @@ void pwmout_period_us(pwmout_t* obj, int us) { int max_us = 0; /* PWM by MTU2 */ - st_mtu2_ctrl_t * p_mtu2_ctl = &mtu2_ctl[(int)(obj->pwm - MTU2_PWM_OFFSET)]; + st_mtu2_ctrl_t *p_mtu2_ctl = &mtu2_ctl[(int)(obj->pwm - MTU2_PWM_OFFSET)]; uint8_t tmp_tcr_up; uint8_t tmp_tstr_st; @@ -387,10 +396,10 @@ void pwmout_period_us(pwmout_t* obj, int us) { wk_cycle_mtu2 = (uint64_t)pclk_base * us; while (wk_cycle_mtu2 >= 65535000000) { if ((obj->ch == 1) && (wk_cks == 3)) { - wk_cks+=2; + wk_cks += 2; } else if ((obj->ch == 2) && (wk_cks == 3)) { wk_cycle_mtu2 >>= 2; - wk_cks+=3; + wk_cks += 3; } wk_cycle_mtu2 >>= 2; wk_cks++; @@ -494,15 +503,44 @@ void pwmout_period_us(pwmout_t* obj, int us) { } } -void pwmout_pulsewidth(pwmout_t* obj, float seconds) { +int pwmout_read_period_us(pwmout_t *obj) +{ + uint32_t wk_cycle; + float value; + + if (obj->pwm >= MTU2_PWM_OFFSET) { +#ifdef FUMC_MTU2_PWM + /* PWM by MTU2 */ + st_mtu2_ctrl_t *p_mtu2_ctl = &mtu2_ctl[(int)(obj->pwm - MTU2_PWM_OFFSET)]; + + wk_cycle = (uint32_t) * p_mtu2_ctl->period1; +#endif + } else { +#ifdef FUNC_MOTOR_CTL_PWM + /* PWM */ + if (obj->ch == 2) { + wk_cycle = PWMPWCYR_2 & 0x03ff; + } else { + wk_cycle = PWMPWCYR_1 & 0x03ff; + } +#endif + } + + return wk_cycle; +} + +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) +{ float value = 0; if (obj->pwm >= MTU2_PWM_OFFSET) { @@ -529,6 +567,23 @@ void pwmout_pulsewidth_us(pwmout_t* obj, int us) { pwmout_write(obj, value); } +int pwmout_read_pulsewidth_us(pwmout_t *obj) +{ + uint32_t wk_pulse = 0; + + if (obj->pwm >= MTU2_PWM_OFFSET) { +#ifdef FUMC_MTU2_PWM + /* PWM by MTU2 */ + + st_mtu2_ctrl_t *p_mtu2_ctl = &mtu2_ctl[(int)(obj->pwm - MTU2_PWM_OFFSET)]; + + wk_pulse = (uint32_t) * p_mtu2_ctl->pulse1; +#endif + } + + return wk_pulse; +} + const PinMap *pwmout_pinmap() { return PinMap_PWM; diff --git a/targets/TARGET_RENESAS/TARGET_RZ_A2XX/pwmout_api.c b/targets/TARGET_RENESAS/TARGET_RZ_A2XX/pwmout_api.c index f5c4ae63f56..533322b5422 100644 --- a/targets/TARGET_RENESAS/TARGET_RZ_A2XX/pwmout_api.c +++ b/targets/TARGET_RENESAS/TARGET_RZ_A2XX/pwmout_api.c @@ -166,6 +166,11 @@ void pwmout_period_us(pwmout_t *obj, int us) pwmout_write(obj, obj->duty); } +int pwmout_read_period_us(pwmout_t *obj) +{ + return obj->pwm->GTPR.LONG; +} + void pwmout_pulsewidth(pwmout_t *obj, float seconds) { pwmout_pulsewidth_us(obj, seconds * 1000000.0f); @@ -188,6 +193,14 @@ void pwmout_pulsewidth_us(pwmout_t *obj, int us) pwmout_write(obj, value); } +int pwmout_read_pulsewidth_us(pwmout_t *obj) +{ + if (obj->type == 0) { + return (float)obj->pwm->GTCCRC.LONG; + } + return (float)obj->pwm->GTCCRE.LONG ; +} + const PinMap *pwmout_pinmap() { return PinMap_PWM; diff --git a/targets/TARGET_STM/pwmout_api.c b/targets/TARGET_STM/pwmout_api.c index b8ce81a7451..27f140a5306 100644 --- a/targets/TARGET_STM/pwmout_api.c +++ b/targets/TARGET_STM/pwmout_api.c @@ -386,6 +386,11 @@ void pwmout_period_us(pwmout_t *obj, int us) __HAL_TIM_ENABLE(&TimHandle); } +int pwmout_read_period_us(pwmout_t *obj) +{ + return obj->period; +} + void pwmout_pulsewidth(pwmout_t *obj, float seconds) { pwmout_pulsewidth_us(obj, seconds * 1000000.0f); @@ -402,6 +407,12 @@ void pwmout_pulsewidth_us(pwmout_t *obj, int us) pwmout_write(obj, value); } +int pwmout_read_pulsewidth_us(pwmout_t *obj) +{ + float pwm_duty_cycle = pwmout_read(obj); + return (int)(pwm_duty_cycle * (float)obj->period); +} + const PinMap *pwmout_pinmap() { return PinMap_PWM; diff --git a/targets/TARGET_Silicon_Labs/TARGET_EFM32/pwmout_api.c b/targets/TARGET_Silicon_Labs/TARGET_EFM32/pwmout_api.c index a733f875d4d..15c85604344 100644 --- a/targets/TARGET_Silicon_Labs/TARGET_EFM32/pwmout_api.c +++ b/targets/TARGET_Silicon_Labs/TARGET_EFM32/pwmout_api.c @@ -78,15 +78,16 @@ uint32_t pwmout_get_channel_route(uint32_t channel) /* * Disables the route location given. Returns true if it was enabled, false if it wasn't. */ -bool pwmout_disable_channel_route(uint32_t routeloc) { +bool pwmout_disable_channel_route(uint32_t routeloc) +{ #ifdef TIMER_ROUTEPEN_CC0PEN - if(PWM_TIMER->ROUTEPEN & routeloc) { + if (PWM_TIMER->ROUTEPEN & routeloc) { //This channel was in use, so disable PWM_TIMER->ROUTEPEN &= ~routeloc; return true; } #else - if(PWM_TIMER->ROUTE & routeloc) { + if (PWM_TIMER->ROUTE & routeloc) { //This channel was in use, so disable PWM_TIMER->ROUTE &= ~routeloc; return true; @@ -98,13 +99,14 @@ bool pwmout_disable_channel_route(uint32_t routeloc) { /* * Check if a channel is active */ -bool pwmout_channel_route_active(uint32_t routeloc) { +bool pwmout_channel_route_active(uint32_t routeloc) +{ #ifdef TIMER_ROUTEPEN_CC0PEN - if(PWM_TIMER->ROUTEPEN & routeloc) { + if (PWM_TIMER->ROUTEPEN & routeloc) { return true; } #else - if(PWM_TIMER->ROUTE & routeloc) { + if (PWM_TIMER->ROUTE & routeloc) { return true; } #endif @@ -114,7 +116,8 @@ bool pwmout_channel_route_active(uint32_t routeloc) { /* * Set the given route PEN flag */ -void pwmout_set_channel_route(uint32_t routeloc) { +void pwmout_set_channel_route(uint32_t routeloc) +{ #ifdef TIMER_ROUTEPEN_CC0PEN PWM_TIMER->ROUTEPEN |= routeloc; #else @@ -125,9 +128,10 @@ void pwmout_set_channel_route(uint32_t routeloc) { /* * Check if all routes are disabled */ -bool pwmout_all_inactive(void) { +bool pwmout_all_inactive(void) +{ #ifdef TIMER_ROUTEPEN_CC0PEN - if(PWM_TIMER->ROUTEPEN == _TIMER_ROUTEPEN_RESETVALUE) { + if (PWM_TIMER->ROUTEPEN == _TIMER_ROUTEPEN_RESETVALUE) { return true; } #else @@ -148,7 +152,8 @@ void pwmout_enable_pins(pwmout_t *obj, uint8_t enable) } } -void pwmout_enable(pwmout_t *obj, uint8_t enable){ +void pwmout_enable(pwmout_t *obj, uint8_t enable) +{ if (enable) { // Set mode to PWM PWM_TIMER->CC[obj->channel].CTRL = TIMER_CC_CTRL_MODE_PWM; @@ -168,13 +173,13 @@ void pwmout_init(pwmout_t *obj, PinName pin) CMU_ClockEnable(PWM_TIMER_CLOCK, true); /* Turn on timer */ - if(!(PWM_TIMER->STATUS & TIMER_STATUS_RUNNING)) { + if (!(PWM_TIMER->STATUS & TIMER_STATUS_RUNNING)) { TIMER_Init_TypeDef timerInit = TIMER_INIT_DEFAULT; TIMER_Init(PWM_TIMER, &timerInit); } // Set route enable - if(pwmout_channel_route_active(pwmout_get_channel_route(obj->channel))) { + if (pwmout_channel_route_active(pwmout_get_channel_route(obj->channel))) { //This channel was already in use //TODO: gracefully handle this case. mbed_error? return; @@ -190,19 +195,19 @@ void pwmout_init(pwmout_t *obj, PinName pin) switch (obj->channel) { case PWM_CH0: PWM_TIMER->ROUTELOC0 &= ~_TIMER_ROUTELOC0_CC0LOC_MASK; - PWM_TIMER->ROUTELOC0 |= pinmap_find_function(pin,PinMap_PWM) << _TIMER_ROUTELOC0_CC0LOC_SHIFT; + PWM_TIMER->ROUTELOC0 |= pinmap_find_function(pin, PinMap_PWM) << _TIMER_ROUTELOC0_CC0LOC_SHIFT; break; case PWM_CH1: PWM_TIMER->ROUTELOC0 &= ~_TIMER_ROUTELOC0_CC1LOC_MASK; - PWM_TIMER->ROUTELOC0 |= pinmap_find_function(pin,PinMap_PWM)<< _TIMER_ROUTELOC0_CC1LOC_SHIFT; + PWM_TIMER->ROUTELOC0 |= pinmap_find_function(pin, PinMap_PWM) << _TIMER_ROUTELOC0_CC1LOC_SHIFT; break; case PWM_CH2: PWM_TIMER->ROUTELOC0 &= ~_TIMER_ROUTELOC0_CC2LOC_MASK; - PWM_TIMER->ROUTELOC0 |= pinmap_find_function(pin,PinMap_PWM) << _TIMER_ROUTELOC0_CC2LOC_SHIFT; + PWM_TIMER->ROUTELOC0 |= pinmap_find_function(pin, PinMap_PWM) << _TIMER_ROUTELOC0_CC2LOC_SHIFT; break; case PWM_CH3: PWM_TIMER->ROUTELOC0 &= ~_TIMER_ROUTELOC0_CC3LOC_MASK; - PWM_TIMER->ROUTELOC0 |= pinmap_find_function(pin,PinMap_PWM) << _TIMER_ROUTELOC0_CC3LOC_SHIFT; + PWM_TIMER->ROUTELOC0 |= pinmap_find_function(pin, PinMap_PWM) << _TIMER_ROUTELOC0_CC3LOC_SHIFT; break; default: MBED_ASSERT(false); @@ -211,10 +216,10 @@ void pwmout_init(pwmout_t *obj, PinName pin) // On P1, the route location is statically defined for the entire timer. PWM_TIMER->ROUTE &= ~_TIMER_ROUTE_LOCATION_MASK; // Make sure the route location is not overwritten - if(pwmout_all_inactive()) { - PWM_TIMER->ROUTE |= pinmap_find_function(pin,PinMap_PWM) << _TIMER_ROUTE_LOCATION_SHIFT; + if (pwmout_all_inactive()) { + PWM_TIMER->ROUTE |= pinmap_find_function(pin, PinMap_PWM) << _TIMER_ROUTE_LOCATION_SHIFT; } else { - MBED_ASSERT((PWM_TIMER->ROUTE & _TIMER_ROUTE_LOCATION_MASK) == pinmap_find_function(pin,PinMap_PWM) << _TIMER_ROUTE_LOCATION_SHIFT); + MBED_ASSERT((PWM_TIMER->ROUTE & _TIMER_ROUTE_LOCATION_MASK) == pinmap_find_function(pin, PinMap_PWM) << _TIMER_ROUTE_LOCATION_SHIFT); } #endif @@ -224,7 +229,7 @@ void pwmout_init(pwmout_t *obj, PinName pin) void pwmout_free(pwmout_t *obj) { - if(pwmout_disable_channel_route(pwmout_get_channel_route(obj->channel))) { + if (pwmout_disable_channel_route(pwmout_get_channel_route(obj->channel))) { //Channel was previously enabled, so do housekeeping sleep_manager_unlock_deep_sleep(); } else { @@ -233,10 +238,10 @@ void pwmout_free(pwmout_t *obj) pwmout_enable_pins(obj, false); - if(pwmout_all_inactive()) { + if (pwmout_all_inactive()) { //Stop timer PWM_TIMER->CMD = TIMER_CMD_STOP; - while(PWM_TIMER->STATUS & TIMER_STATUS_RUNNING); + while (PWM_TIMER->STATUS & TIMER_STATUS_RUNNING); //Disable clock CMU_ClockEnable(PWM_TIMER_CLOCK, false); @@ -248,14 +253,15 @@ void pwmout_write(pwmout_t *obj, float value) pwmout_write_channel(obj->channel, value); } -void pwmout_write_channel(uint32_t channel, float value) { +void pwmout_write_channel(uint32_t channel, float value) +{ uint32_t width_cycles = 0; if (value < 0.0f) { width_cycles = 0; } else if (value >= 1.0f) { width_cycles = PWM_TIMER->TOPB + 1; } else { - width_cycles = (uint16_t)((float)PWM_TIMER->TOPB * value); + width_cycles = (uint16_t)((float)PWM_TIMER->TOPB * value); } TIMER_CompareBufSet(PWM_TIMER, channel, width_cycles); @@ -266,14 +272,13 @@ float pwmout_read(pwmout_t *obj) return pwmout_calculate_duty(TIMER_CaptureGet(PWM_TIMER, obj->channel), TIMER_TopGet(PWM_TIMER)); } -float pwmout_calculate_duty(uint32_t width_cycles, uint32_t period_cycles) { - if(width_cycles > period_cycles) { +float pwmout_calculate_duty(uint32_t width_cycles, uint32_t period_cycles) +{ + if (width_cycles > period_cycles) { return 1.0f; - } - else if (width_cycles == 0) { + } else if (width_cycles == 0) { return 0.0f; - } - else { + } else { return (float) width_cycles / (float) period_cycles; } } @@ -302,7 +307,9 @@ void pwmout_period(pwmout_t *obj, float seconds) } //Check if anything changed - if(((PWM_TIMER->CTRL & _TIMER_CTRL_PRESC_MASK) == (pwm_prescaler_div << _TIMER_CTRL_PRESC_SHIFT)) && (TIMER_TopGet(PWM_TIMER) == cycles)) return; + if (((PWM_TIMER->CTRL & _TIMER_CTRL_PRESC_MASK) == (pwm_prescaler_div << _TIMER_CTRL_PRESC_SHIFT)) && (TIMER_TopGet(PWM_TIMER) == cycles)) { + return; + } //Save previous period for recalculation of duty cycles uint32_t previous_period_cycles = PWM_TIMER->TOPB; @@ -315,8 +322,8 @@ void pwmout_period(pwmout_t *obj, float seconds) //For each active channel, re-calculate the compare value uint32_t channel = 0; - while(pwmout_get_channel_route(channel) != 0) { - if(pwmout_channel_route_active(channel)) { + while (pwmout_get_channel_route(channel) != 0) { + if (pwmout_channel_route_active(channel)) { //recalc and reset compare value pwmout_write_channel(channel, pwmout_calculate_duty(PWM_TIMER->CC[channel].CCVB, previous_period_cycles)); } @@ -334,24 +341,34 @@ void pwmout_period_us(pwmout_t *obj, int us) pwmout_period(obj, us / 1000000.0f); } +int pwmout_read_period_us(pwmout_t *obj) +{ + return (TIMER_TopGet(PWM_TIMER) * 1000000) / REFERENCE_FREQUENCY; +} + void pwmout_pulsewidth(pwmout_t *obj, float seconds) { - uint16_t width_cycles = (uint16_t) (((float) (REFERENCE_FREQUENCY >> pwm_prescaler_div)) * seconds); + uint16_t width_cycles = (uint16_t)(((float)(REFERENCE_FREQUENCY >> pwm_prescaler_div)) * seconds); TIMER_CompareBufSet(PWM_TIMER, obj->channel, width_cycles); } void pwmout_pulsewidth_ms(pwmout_t *obj, int ms) { - uint16_t width_cycles = (uint16_t) (((REFERENCE_FREQUENCY >> pwm_prescaler_div) * ms) / 1000); + uint16_t width_cycles = (uint16_t)(((REFERENCE_FREQUENCY >> pwm_prescaler_div) * ms) / 1000); TIMER_CompareBufSet(PWM_TIMER, obj->channel, width_cycles); } void pwmout_pulsewidth_us(pwmout_t *obj, int us) { - uint16_t width_cycles = (uint16_t) (((uint64_t)(REFERENCE_FREQUENCY >> pwm_prescaler_div) * (uint64_t)us) / 1000000UL); + uint16_t width_cycles = (uint16_t)(((uint64_t)(REFERENCE_FREQUENCY >> pwm_prescaler_div) * (uint64_t)us) / 1000000UL); TIMER_CompareBufSet(PWM_TIMER, obj->channel, width_cycles); } +int pwmout_read_pulsewidth_us(pwmout_t *obj) +{ + return (TIMER_CaptureGet(PWM_TIMER, obj->channel) * 1000000) / REFERENCE_FREQUENCY ; +} + const PinMap *pwmout_pinmap() { return PinMap_PWM; diff --git a/targets/TARGET_TOSHIBA/TARGET_TMPM46B/pwmout_api.c b/targets/TARGET_TOSHIBA/TARGET_TMPM46B/pwmout_api.c index d68254a7ca5..035e8eecf25 100644 --- a/targets/TARGET_TOSHIBA/TARGET_TMPM46B/pwmout_api.c +++ b/targets/TARGET_TOSHIBA/TARGET_TMPM46B/pwmout_api.c @@ -80,7 +80,7 @@ void pwmout_free(pwmout_t *obj) { // Stops and clear count operation TMRB_SetRunState(obj->channel, TMRB_STOP); - pwmout_write(obj,0); + pwmout_write(obj, 0); obj->channel = NULL; obj->trailing_timing = 0; obj->leading_timing = 0; @@ -169,7 +169,7 @@ void pwmout_period_us(pwmout_t *obj, int us) // Restore the duty-cycle duty_cycle = (float)((obj->trailing_timing - obj->leading_timing) / obj->trailing_timing); obj->trailing_timing = cycles; - obj->leading_timing = ((cycles)- (uint16_t)(cycles * duty_cycle)); + obj->leading_timing = ((cycles) - (uint16_t)(cycles * duty_cycle)); // Change the source clock division and period m_tmrb.Mode = TMRB_INTERVAL_TIMER; @@ -192,6 +192,11 @@ void pwmout_period_us(pwmout_t *obj, int us) TMRB_SetRunState(obj->channel, TMRB_RUN); } +int pwmout_read_period_us(pwmout_t *obj) +{ + return obj->trailing_timing; +} + void pwmout_pulsewidth(pwmout_t *obj, float seconds) { pwmout_pulsewidth_us(obj, (seconds * 1000000.0f)); @@ -212,6 +217,11 @@ void pwmout_pulsewidth_us(pwmout_t *obj, int us) pwmout_write(obj, value); } +int pwmout_read_pulsewidth_us(pwmout_t *obj) +{ + return obj->trailing_timing - obj->leading_timing; +} + const PinMap *pwmout_pinmap() { return PinMap_PWM; diff --git a/targets/TARGET_TOSHIBA/TARGET_TMPM4G9/pwmout_api.c b/targets/TARGET_TOSHIBA/TARGET_TMPM4G9/pwmout_api.c index 212e8fa7e4c..05b27da0f2c 100644 --- a/targets/TARGET_TOSHIBA/TARGET_TMPM4G9/pwmout_api.c +++ b/targets/TARGET_TOSHIBA/TARGET_TMPM4G9/pwmout_api.c @@ -193,7 +193,7 @@ void pwmout_period_us(pwmout_t *obj, int us) prscl = T32A_PRSCLx_32; obj->trailing_timing = (us * CALCULATE_RGC1_VAL); - obj->leading_timing = ((obj->trailing_timing)- (obj->trailing_timing * duty_cycle)); + obj->leading_timing = ((obj->trailing_timing) - (obj->trailing_timing * duty_cycle)); obj->p_t32a.p_instance->MOD = T32A_MODE_32; obj->p_t32a.p_instance->RUNC = (T32A_RUN_DISABLE | T32A_COUNT_STOP); @@ -207,6 +207,11 @@ void pwmout_period_us(pwmout_t *obj, int us) obj->p_t32a.p_instance->RUNC = (T32A_RUN_ENABLE | T32A_COUNT_START); } +int pwmout_read_period_us(pwmout_t *obj) +{ + return obj->trailing_timing; +} + void pwmout_pulsewidth(pwmout_t *obj, float seconds) { pwmout_pulsewidth_us(obj, (seconds * 1000000.0f)); @@ -227,6 +232,11 @@ void pwmout_pulsewidth_us(pwmout_t *obj, int us) pwmout_write(obj, value); } +int pwmout_read_pulsewidth_us(pwmout_t *obj) +{ + return obj->trailing_timing - obj->leading_timing; +} + const PinMap *pwmout_pinmap() { return PinMap_PWM;