diff options
author | Sam Hurst <shurst@google.com> | 2016-08-23 11:43:23 -0700 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2016-09-02 15:12:13 -0700 |
commit | 26c5a22125916a53b62ac8226eb10af4c7a77c58 (patch) | |
tree | 4d81c2a2b7a73bb54d4bb2f671610e6346aaafe0 /common/pwm.c | |
parent | 8e4c2c630403ae816b2b0cc7dd9b5182880ffbd1 (diff) | |
download | chrome-ec-26c5a22125916a53b62ac8226eb10af4c7a77c58.tar.gz |
pwm: Increse PWM duty resolution to 16bits
The current PWM interface allows for a pwm duty setting ranging from
0 to 100, resulting in a very coarse adjustment. To alleviate the
problem, the interface now allows for a pwm duty setting in the range
of 0 to 65535.
BUG=chromium:615109
BRANCH=None
TEST=Manual on chell.
`ectool pwmsetduty 1 65535` - Verify LCD backlight goes to 100%
`ectool pwmgetduty 1` - Prints 65535
`ectool pwmsetduty 1 0` - Verify LCD backlight goes to 0%
`ectool pwmgetduty 1` - Prints 0
terminal pwmduty tests:
>pwmduty
PWM channels:
0: 100%
1: 62%
2: 100%
3: 80%
> pwmduty 1 50
Setting channel 1 to 50%
1: 50%
> pwmduty 1 0
Setting channel 1 to 0%
1: disabled
> pwmduty 1 100
Setting channel 1 to 100%
1: 100%
> pwmduty 1 raw 0
Setting channel 1 to raw 0%
1: disabled
> pwmduty 1 raw 65535
Setting channel 1 to raw 65535%
1: 65535
> pwmduty
PWM channels:
0: 100%
1: 100%
2: 100%
3: 80%
> pwmduty 1 raw 30000
Setting channel 1 to raw 30000%
1: 30000
> pwmduty
PWM channels:
0: 100%
1: 46%
2: 100%
3: 80%
Change-Id: I299b77585f3988e72d9ac918bdde7dc5fa3df6de
Reviewed-on: https://chromium-review.googlesource.com/374481
Commit-Ready: Shawn N <shawnn@chromium.org>
Tested-by: Sam Hurst <shurst@google.com>
Reviewed-by: Shawn N <shawnn@chromium.org>
Diffstat (limited to 'common/pwm.c')
-rw-r--r-- | common/pwm.c | 71 |
1 files changed, 46 insertions, 25 deletions
diff --git a/common/pwm.c b/common/pwm.c index c7fb627ec7..761d1dad25 100644 --- a/common/pwm.c +++ b/common/pwm.c @@ -40,25 +40,30 @@ static int get_target_channel(enum pwm_channel *channel, int type, int index) return *channel >= PWM_CH_COUNT; } -/* - * TODO(crbug.com/615109): These host commands use 16 bit duty cycle, but - * all of our internal code uses percent on [0, 100]. Convert internal - * functions to use 16 bit duty and remove the conversions below. - */ -static int host_command_pwm_set_duty(struct host_cmd_handler_args *args) +__attribute__((weak)) void pwm_set_raw_duty(enum pwm_channel ch, uint16_t duty) { - const struct ec_params_pwm_set_duty *p = args->params; - enum pwm_channel channel; int percent; /* Convert 16 bit duty to percent on [0, 100] */ - percent = DIV_ROUND_NEAREST(p->duty * 100, EC_PWM_MAX_DUTY); + percent = DIV_ROUND_NEAREST((uint32_t)duty * 100, 65535); + pwm_set_duty(ch, percent); +} + +__attribute__((weak)) uint16_t pwm_get_raw_duty(enum pwm_channel ch) +{ + return (pwm_get_duty(ch) * 65535) / 100; +} + +static int host_command_pwm_set_duty(struct host_cmd_handler_args *args) +{ + const struct ec_params_pwm_set_duty *p = args->params; + enum pwm_channel channel; if (get_target_channel(&channel, p->pwm_type, p->index)) return EC_RES_INVALID_PARAM; - pwm_set_duty(channel, percent); - pwm_enable(channel, percent > 0); + pwm_set_raw_duty(channel, p->duty); + pwm_enable(channel, p->duty > 0); return EC_RES_SUCCESS; } @@ -76,8 +81,7 @@ static int host_command_pwm_get_duty(struct host_cmd_handler_args *args) if (get_target_channel(&channel, p->pwm_type, p->index)) return EC_RES_INVALID_PARAM; - /* Convert percent on [0, 100] to 16 bit duty */ - r->duty = pwm_get_duty(channel) * EC_PWM_MAX_DUTY / 100; + r->duty = pwm_get_raw_duty(channel); args->response_size = sizeof(*r); return EC_RES_SUCCESS; @@ -91,24 +95,29 @@ DECLARE_HOST_COMMAND(EC_CMD_PWM_GET_DUTY, * * @param ch Channel to print. */ -static void print_channel(enum pwm_channel ch) +static void print_channel(enum pwm_channel ch, int max_duty) { if (pwm_get_enabled(ch)) - ccprintf(" %d: %d%%\n", ch, pwm_get_duty(ch)); + if (max_duty == 100) + ccprintf(" %d: %d%%\n", ch, pwm_get_duty(ch)); + else + ccprintf(" %d: %d\n", ch, pwm_get_raw_duty(ch)); else ccprintf(" %d: disabled\n", ch); } static int cc_pwm_duty(int argc, char **argv) { - int percent = 0; + int value = 0; + int max_duty = 100; int ch; char *e; + char *raw; if (argc < 2) { ccprintf("PWM channels:\n"); for (ch = 0; ch < PWM_CH_COUNT; ch++) - print_channel(ch); + print_channel(ch, max_duty); return EC_SUCCESS; } @@ -117,26 +126,38 @@ static int cc_pwm_duty(int argc, char **argv) return EC_ERROR_PARAM1; if (argc > 2) { - percent = strtoi(argv[2], &e, 0); - if (*e || percent > 100) { + raw = argv[2]; + if (!strcasecmp(raw, "raw")) { + /* use raw duty */ + value = strtoi(argv[3], &e, 0); + max_duty = EC_PWM_MAX_DUTY; + } else { + /* use percent duty */ + value = strtoi(argv[2], &e, 0); + max_duty = 100; + } + + if (*e || value > max_duty) { /* Bad param */ - return EC_ERROR_PARAM1; - } else if (percent < 0) { + return EC_ERROR_PARAM2; + } else if (value < 0) { /* Negative = disable */ pwm_enable(ch, 0); } else { - ccprintf("Setting channel %d to %d%%\n", ch, percent); + ccprintf("Setting channel %d to%s%d%%\n", + ch, (max_duty == 100) ? " " : " raw ", value); pwm_enable(ch, 1); - pwm_set_duty(ch, percent); + (max_duty == 100) ? pwm_set_duty(ch, value) : + pwm_set_raw_duty(ch, value); } } - print_channel(ch); + print_channel(ch, max_duty); return EC_SUCCESS; } DECLARE_CONSOLE_COMMAND(pwmduty, cc_pwm_duty, - "[channel [<percent> | -1=disable]]", + "[channel [<percent> | -1=disable] | [raw <value>]]", "Get/set PWM duty cycles "); #endif /* CONFIG_PWM */ |