CC2652P7: PWM_Stop does not restore the GPIO idle level (only on recent TI SimpleLink SDK)

Part Number: CC2652P7

Tool/software:

Hi,

I guess I have found a regression on the latest TI SimpleLink SDK and a fix for it.

* On an old SDK (ex: 5_20_00_52), PWMTimerCC26XX_stop is working fine.
* On a recent SDK (ex: 7_40_00_77), PWMTimerCC26XX_stop does not set the GPIO back to its idle level (e.g. it ignores PWM_Params.idleLevel).
* Apparently a workaround is to set the expected level with PWM_setDuty prior to PWM_Stop.
* Below is sample code to reproduce the problem and a tentative fix.

Please confirm or infirm.

Regards,
-- Olivier
__________________________________________________

    PWM_init();
    PWM_Handle pwm_handle;
    PWM_Params pwm_params;
    PWM_Params_init(&pwm_params);

    pwm_params.periodUnits = PWM_PERIOD_HZ;
    pwm_params.periodValue = 1e6;
    pwm_params.dutyUnits = PWM_DUTY_FRACTION;
    pwm_params.dutyValue = 0;
    pwm_params.idleLevel = PWM_IDLE_LOW;
    pwm_handle = PWM_open(CONFIG_PWM, &pwm_params);

    PWM_start(pwm_handle);
    PWM_setDuty(pwm_handle, PWM_DUTY_FRACTION_MAX);
    PWM_stop(pwm_handle);
    sleep(3) // Here, the output is high (because of PWM_setDuty) and not PWM_IDLE_LOW
    PWM_close(pwm_handle);

    pwm_params.idleLevel = PWM_IDLE_HIGH;
    pwm_handle = PWM_open(CONFIG_PWM, &pwm_params);

    PWM_start(pwm_handle);
    PWM_setDuty(pwm_handle, 0);
    PWM_stop(pwm_handle);
    sleep(3) // Here, the output is low (because of PWM_setDuty) and not PWM_IDLE_HIGH
    PWM_close(pwm_handle);

__________________________________________________

diff --git a/source/ti/drivers/pwm/PWMTimerCC26XX.c b/source/ti/drivers/pwm/PWMTimerCC26XX.c
index 1498bbd3e..32387db2b 100644
--- a/source/ti/drivers/pwm/PWMTimerCC26XX.c
+++ b/source/ti/drivers/pwm/PWMTimerCC26XX.c
@@ -404,6 +404,10 @@ void PWMTimerCC26XX_stop(PWM_Handle handle)
 
     /* Route PWM pin to GPIO module */
     GPIO_getConfig(hwAttrs->pwmPin, &pinConfig);
+    if (object->idleLevel == PWM_IDLE_HIGH)
+        pinConfig |= GPIO_CFG_OUT_HIGH;
+    else
+        pinConfig &= ~GPIO_CFG_OUT_HIGH;
     GPIO_setConfigAndMux(hwAttrs->pwmPin, pinConfig, GPIO_MUX_GPIO);
 }
 
--
2.34.1


  • Hi Oliver,

    I'm observing similar behavior to what you reported and confirmed your workaround.  Thank you for reporting this as it is probably a condition of Pin to GPIO++ TI Driver migration.  I've notified the TI Driver Software Development Team so that they can implement a solution into a future SDK release.

    Regards,
    Ryan

  • Thanks for confirming and bringing it to the development team.

    While at it, I have noticed a similar problem with PWM_Start: the second call ignores pwm_params.dutyValue. Below is sample code to reproduce. A workaround is to call PWM_setDuty right before PWM_Start.

    Please confirm this one as well ;-)

    Regards,
    -- Olivier
    __________________________________________________

    pwm_params.dutyValue = 2147483647;
    pwm_params.idleLevel = PWM_IDLE_LOW;
    pwm_handle = PWM_open(CONFIG_PWM, &pwm_params);
    PWM_Start();
    sleep(3); // Here, the output is 2147483647 (pwm_params.dutyValue), as expected
    PWM_setDuty(pwm_handle, PWM_DUTY_FRACTION_MAX);
    PWM_stop(pwm_handle);
    PWM_Start();
    sleep(3); // Here, the output is 0 but should be 2147483647
    __________________________________________________

  • This one is likely because PWM_Start does not call GPTimerCC26XX_setMatchValue, since this was handled during PWM_Open, so the GPTimer remains unconfigured since PWM_Stop.  I can add this behavior to the existing ticket, however it may be the preference of the TI Driver code execution to leave behavior as it is and workaround in such a way as you've described for unique cases.

    Regards,
    Ryan

  • Well, the documentation about PWM_Params.dutyValue says "PWM initial duty". Even though it is passed to PWM_Open, its effect is visible only after PWM_Start, and only once.

    Regardless of any design decision, I would recommend to add a note in the documentation.

    Regards,

    -- Olivier