Skip to content

The PwmOut::suspend() and PwmOut::resume() functions should use *_pulsewitdth_us() functions #15135

Open
@billwatersiii

Description

@billwatersiii

Description of defect

The problem identified here...
#13480

Was fixed here...
#13492

But, I believe that the intent was to have the PwmOut::suspend() and PwmOut::resume() functions use *_pulsewitdth_us() functions. The #13492 update added PwmOut::read_pulsewitdth_us() and the associated pwmout_read_pulsewidth_us functions, but it didn't use them.

Right now, the code uses a percentage for the saving/restoring the _duty_cycle. And when restoring this, it provides the "percentage of the period" before providing the period. This will likely be a problem for many devices.

From mbed-os/drivers/source/PwmOut.cpp:

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();
}

void PwmOut::resume()
{
    core_util_critical_section_enter();
    if (!_initialized) {
        PwmOut::init();
        PwmOut::write(_duty_cycle);
        PwmOut::period_us(_period_us);
    }
    core_util_critical_section_exit();
}

I believe that the intent was to update the code to the following...

void PwmOut::suspend()
{
    core_util_critical_section_enter();
    if (_initialized) {
        _duty_cycle = PwmOut::read_pulsewitdth_us();
        _period_us = PwmOut::read_period_us();
        PwmOut::deinit();
    }
    core_util_critical_section_exit();
}

void PwmOut::resume()
{
    core_util_critical_section_enter();
    if (!_initialized) {
        PwmOut::init();
        PwmOut::pulsewitdth_us(_duty_cycle);
        PwmOut::period_us(_period_us);
    }
    core_util_critical_section_exit();
}

There still could be hardware-specific issues here. I think that a better approach is to push this into target-specific code and just call save/restore functions here.

void PwmOut::suspend()
{
    core_util_critical_section_enter();
    if (_initialized) {
        PwmOut::save();
        PwmOut::deinit();
    }
    core_util_critical_section_exit();
}

void PwmOut::resume()
{
    core_util_critical_section_enter();
    if (!_initialized) {
        PwmOut::init();
        PwmOut::restore();
    }
    core_util_critical_section_exit();
}

Target(s) affected by this defect ?

Probably several devices from multiple vendors. At least these:

CY8CKIT064B0S2_4343W
CY8CKIT_062S2_43012
CY8CKIT_062_BLE
CY8CKIT_062_WIFI_BT
CY8CPROTO_062S3_4343W
CY8CPROTO_062_4343W

Toolchain(s) (name and version) displaying this defect ?

All

What version of Mbed-os are you using (tag or sha) ?

Latest

What version(s) of tools are you using. List all that apply (E.g. mbed-cli)

N/A

How is this defect reproduced ?

As outlined here...
#13480

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions