summaryrefslogtreecommitdiff
path: root/common/pwm.c
diff options
context:
space:
mode:
authorSam Hurst <shurst@google.com>2016-08-23 11:43:23 -0700
committerchrome-bot <chrome-bot@chromium.org>2016-09-02 15:12:13 -0700
commit26c5a22125916a53b62ac8226eb10af4c7a77c58 (patch)
tree4d81c2a2b7a73bb54d4bb2f671610e6346aaafe0 /common/pwm.c
parent8e4c2c630403ae816b2b0cc7dd9b5182880ffbd1 (diff)
downloadchrome-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.c71
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 */