Skip to content

Commit db611e6

Browse files
henrikbrixandersencarlescufi
authored andcommitted
drivers: pwm: add support for inverted PWM signals
Add support for requesting an inverted PWM pulse (active-low) when setting up the period and pulse width of a PWM pin. This is useful when driving external, active-low circuitry (e.g. an LED) with a PWM signal. All in-tree PWM drivers is updated to match the new API signature, but no driver support for inverted PWM signals is added yet. All in-tree PWM consumers are updated to pass a flags value of 0 (0 meaning default, which is normal PWM polarity). Fixes zephyrproject-rtos#21384. Signed-off-by: Henrik Brix Andersen <[email protected]>
1 parent def1f0e commit db611e6

File tree

24 files changed

+152
-38
lines changed

24 files changed

+152
-38
lines changed

drivers/pwm/pwm_dw.c

+8-1
Original file line numberDiff line numberDiff line change
@@ -135,11 +135,13 @@ static int __set_one_port(struct device *dev, u32_t pwm,
135135
* @param pwm Which PWM pin to set
136136
* @param period_cycles Period in clock cycles of the pwm.
137137
* @param pulse_cycles PWM width in clock cycles
138+
* @param flags Flags for pin configuration (polarity).
138139
*
139140
* @return 0
140141
*/
141142
static int pwm_dw_pin_set_cycles(struct device *dev,
142-
u32_t pwm, u32_t period_cycles, u32_t pulse_cycles)
143+
u32_t pwm, u32_t period_cycles,
144+
u32_t pulse_cycles, pwm_flags_t flags)
143145
{
144146
const struct pwm_dw_config * const cfg =
145147
(struct pwm_dw_config *)dev->config->config_info;
@@ -151,6 +153,11 @@ static int pwm_dw_pin_set_cycles(struct device *dev,
151153
return -EIO;
152154
}
153155

156+
if (flags) {
157+
/* PWM polarity not supported (yet?) */
158+
return -ENOTSUP;
159+
}
160+
154161
if (period_cycles == 0U || pulse_cycles > period_cycles) {
155162
return -EINVAL;
156163
}

drivers/pwm/pwm_handlers.c

+3-2
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,12 @@
88
#include <drivers/pwm.h>
99

1010
static inline int z_vrfy_pwm_pin_set_cycles(struct device *dev, u32_t pwm,
11-
u32_t period, u32_t pulse)
11+
u32_t period, u32_t pulse,
12+
pwm_flags_t flags)
1213
{
1314
Z_OOPS(Z_SYSCALL_DRIVER_PWM(dev, pin_set));
1415
return z_impl_pwm_pin_set_cycles((struct device *)dev, pwm, period,
15-
pulse);
16+
pulse, flags);
1617
}
1718
#include <syscalls/pwm_pin_set_cycles_mrsh.c>
1819

drivers/pwm/pwm_imx.c

+7-1
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,8 @@ static int imx_pwm_get_cycles_per_sec(struct device *dev, u32_t pwm,
5252
}
5353

5454
static int imx_pwm_pin_set(struct device *dev, u32_t pwm,
55-
u32_t period_cycles, u32_t pulse_cycles)
55+
u32_t period_cycles, u32_t pulse_cycles,
56+
pwm_flags_t flags)
5657
{
5758
PWM_Type *base = DEV_BASE(dev);
5859
const struct imx_pwm_config *config = DEV_CFG(dev);
@@ -69,6 +70,11 @@ static int imx_pwm_pin_set(struct device *dev, u32_t pwm,
6970
return -EINVAL;
7071
}
7172

73+
if (flags) {
74+
/* PWM polarity not supported (yet?) */
75+
return -ENOTSUP;
76+
}
77+
7278
LOG_DBG("enabled=%d, pulse_cycles=%d, period_cycles=%d,"
7379
" duty_cycle=%d\n", enabled, pulse_cycles, period_cycles,
7480
(pulse_cycles * 100U / period_cycles));

drivers/pwm/pwm_led_esp32.c

+6-1
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,7 @@ static int pwm_led_esp32_timer_set(int speed_mode, int timer,
311311
/* period_cycles is not used, set frequency on menuconfig instead. */
312312
static int pwm_led_esp32_pin_set_cycles(struct device *dev,
313313
u32_t pwm, u32_t period_cycles,
314-
u32_t pulse_cycles)
314+
u32_t pulse_cycles, pwm_flags_t flags)
315315
{
316316
int speed_mode;
317317
int channel;
@@ -322,6 +322,11 @@ static int pwm_led_esp32_pin_set_cycles(struct device *dev,
322322

323323
ARG_UNUSED(period_cycles);
324324

325+
if (flags) {
326+
/* PWM polarity not supported (yet?) */
327+
return -ENOTSUP;
328+
}
329+
325330
channel = pwm_led_esp32_get_gpio_config(pwm, config->ch_cfg);
326331
if (channel < 0) {
327332
return -EINVAL;

drivers/pwm/pwm_mchp_xec.c

+7-1
Original file line numberDiff line numberDiff line change
@@ -305,7 +305,8 @@ static void xec_compute_and_set_parameters(struct device *dev,
305305
}
306306

307307
static int pwm_xec_pin_set(struct device *dev, u32_t pwm,
308-
u32_t period_cycles, u32_t pulse_cycles)
308+
u32_t period_cycles, u32_t pulse_cycles,
309+
pwm_flags_t flags)
309310
{
310311
PWM_Type *pwm_regs = PWM_XEC_REG_BASE(dev);
311312
u32_t target_freq;
@@ -319,6 +320,11 @@ static int pwm_xec_pin_set(struct device *dev, u32_t pwm,
319320
return -EINVAL;
320321
}
321322

323+
if (flags) {
324+
/* PWM polarity not supported (yet?) */
325+
return -ENOTSUP;
326+
}
327+
322328
on = pulse_cycles;
323329
off = period_cycles - pulse_cycles;
324330

drivers/pwm/pwm_mcux.c

+7-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ struct pwm_mcux_data {
3030
};
3131

3232
static int mcux_pwm_pin_set(struct device *dev, u32_t pwm,
33-
u32_t period_cycles, u32_t pulse_cycles)
33+
u32_t period_cycles, u32_t pulse_cycles,
34+
pwm_flags_t flags)
3435
{
3536
const struct pwm_mcux_config *config = dev->config->config_info;
3637
struct pwm_mcux_data *data = dev->driver_data;
@@ -41,6 +42,11 @@ static int mcux_pwm_pin_set(struct device *dev, u32_t pwm,
4142
return -EINVAL;
4243
}
4344

45+
if (flags) {
46+
/* PWM polarity not supported (yet?) */
47+
return -ENOTSUP;
48+
}
49+
4450
if ((period_cycles == 0) || (pulse_cycles > period_cycles)) {
4551
LOG_ERR("Invalid combination: period_cycles=%u, "
4652
"pulse_cycles=%u", period_cycles, pulse_cycles);

drivers/pwm/pwm_mcux_ftm.c

+7-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ struct mcux_ftm_data {
3434
};
3535

3636
static int mcux_ftm_pin_set(struct device *dev, u32_t pwm,
37-
u32_t period_cycles, u32_t pulse_cycles)
37+
u32_t period_cycles, u32_t pulse_cycles,
38+
pwm_flags_t flags)
3839
{
3940
const struct mcux_ftm_config *config = dev->config->config_info;
4041
struct mcux_ftm_data *data = dev->driver_data;
@@ -51,6 +52,11 @@ static int mcux_ftm_pin_set(struct device *dev, u32_t pwm,
5152
return -ENOTSUP;
5253
}
5354

55+
if (flags) {
56+
/* PWM polarity not supported (yet?) */
57+
return -ENOTSUP;
58+
}
59+
5460
duty_cycle = pulse_cycles * 100U / period_cycles;
5561
data->channel[pwm].dutyCyclePercent = duty_cycle;
5662

drivers/pwm/pwm_nrf5_sw.c

+7-1
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,8 @@ static u8_t pwm_channel_map(struct pwm_data *data, u8_t map_size,
8787
}
8888

8989
static int pwm_nrf5_sw_pin_set(struct device *dev, u32_t pwm,
90-
u32_t period_cycles, u32_t pulse_cycles)
90+
u32_t period_cycles, u32_t pulse_cycles,
91+
pwm_flags_t flags)
9192
{
9293
struct pwm_config *config;
9394
NRF_TIMER_Type *timer;
@@ -101,6 +102,11 @@ static int pwm_nrf5_sw_pin_set(struct device *dev, u32_t pwm,
101102
timer = config->timer;
102103
data = dev->driver_data;
103104

105+
if (flags) {
106+
/* PWM polarity not supported (yet?) */
107+
return -ENOTSUP;
108+
}
109+
104110
/* check if requested period is allowed while other channels are
105111
* active.
106112
*/

drivers/pwm/pwm_nrfx.c

+7-1
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,8 @@ static bool any_other_channel_is_active(u8_t channel,
123123
}
124124

125125
static int pwm_nrfx_pin_set(struct device *dev, u32_t pwm,
126-
u32_t period_cycles, u32_t pulse_cycles)
126+
u32_t period_cycles, u32_t pulse_cycles,
127+
pwm_flags_t flags)
127128
{
128129
/* We assume here that period_cycles will always be 16MHz
129130
* peripheral clock. Since pwm_nrfx_get_cycles_per_sec() function might
@@ -134,6 +135,11 @@ static int pwm_nrfx_pin_set(struct device *dev, u32_t pwm,
134135
struct pwm_nrfx_data *data = dev->driver_data;
135136
u8_t channel;
136137

138+
if (flags) {
139+
/* PWM polarity not supported (yet?) */
140+
return -ENOTSUP;
141+
}
142+
137143
/* Check if PWM pin is one of the predefiend DTS config pins.
138144
* Return its array index (channel number),
139145
* or NRF_PWM_CHANNEL_COUNT if not initialized through DTS.

drivers/pwm/pwm_pca9685.c

+7-1
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,8 @@ static inline int has_i2c_master(struct device *dev)
6161
* value to pulse_count
6262
*/
6363
static int pwm_pca9685_pin_set_cycles(struct device *dev, u32_t pwm,
64-
u32_t period_count, u32_t pulse_count)
64+
u32_t period_count, u32_t pulse_count,
65+
pwm_flags_t flags)
6566
{
6667
const struct pwm_pca9685_config * const config =
6768
dev->config->config_info;
@@ -76,6 +77,11 @@ static int pwm_pca9685_pin_set_cycles(struct device *dev, u32_t pwm,
7677
return -EINVAL;
7778
}
7879

80+
if (flags) {
81+
/* PWM polarity not supported (yet?) */
82+
return -ENOTSUP;
83+
}
84+
7985
if (pwm > MAX_PWM_OUT) {
8086
return -EINVAL;
8187
}

drivers/pwm/pwm_sam.c

+7-1
Original file line numberDiff line numberDiff line change
@@ -36,14 +36,20 @@ static int sam_pwm_get_cycles_per_sec(struct device *dev, u32_t pwm,
3636
}
3737

3838
static int sam_pwm_pin_set(struct device *dev, u32_t ch,
39-
u32_t period_cycles, u32_t pulse_cycles)
39+
u32_t period_cycles, u32_t pulse_cycles,
40+
pwm_flags_t flags)
4041
{
4142
Pwm *const pwm = DEV_CFG(dev)->regs;
4243

4344
if (ch >= PWMCHNUM_NUMBER) {
4445
return -EINVAL;
4546
}
4647

48+
if (flags) {
49+
/* PWM polarity not supported (yet?) */
50+
return -ENOTSUP;
51+
}
52+
4753
if (period_cycles == 0U || pulse_cycles > period_cycles) {
4854
return -EINVAL;
4955
}

drivers/pwm/pwm_shell.c

+3-3
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ static int cmd_cycles(const struct shell *shell, size_t argc, char **argv)
4545
period = strtoul(argv[args_indx.period], NULL, 0);
4646
pulse = strtoul(argv[args_indx.pulse], NULL, 0);
4747

48-
err = pwm_pin_set_cycles(dev, pwm, period, pulse);
48+
err = pwm_pin_set_cycles(dev, pwm, period, pulse, 0);
4949
if (err) {
5050
shell_error(shell, "failed to setup PWM (err %d)",
5151
err);
@@ -73,7 +73,7 @@ static int cmd_usec(const struct shell *shell, size_t argc, char **argv)
7373
period = strtoul(argv[args_indx.period], NULL, 0);
7474
pulse = strtoul(argv[args_indx.pulse], NULL, 0);
7575

76-
err = pwm_pin_set_usec(dev, pwm, period, pulse);
76+
err = pwm_pin_set_usec(dev, pwm, period, pulse, 0);
7777
if (err) {
7878
shell_error(shell, "failed to setup PWM (err %d)", err);
7979
return err;
@@ -100,7 +100,7 @@ static int cmd_nsec(const struct shell *shell, size_t argc, char **argv)
100100
period = strtoul(argv[args_indx.period], NULL, 0);
101101
pulse = strtoul(argv[args_indx.pulse], NULL, 0);
102102

103-
err = pwm_pin_set_nsec(dev, pwm, period, pulse);
103+
err = pwm_pin_set_nsec(dev, pwm, period, pulse, 0);
104104
if (err) {
105105
shell_error(shell, "failed to setup PWM (err %d)", err);
106106
return err;

drivers/pwm/pwm_sifive.c

+7-1
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,8 @@ static int pwm_sifive_init(struct device *dev)
9696
static int pwm_sifive_pin_set(struct device *dev,
9797
u32_t pwm,
9898
u32_t period_cycles,
99-
u32_t pulse_cycles)
99+
u32_t pulse_cycles,
100+
pwm_flags_t flags)
100101
{
101102
const struct pwm_sifive_cfg *config = NULL;
102103
u32_t count_max = 0U;
@@ -112,6 +113,11 @@ static int pwm_sifive_pin_set(struct device *dev,
112113
return -EFAULT;
113114
}
114115

116+
if (flags) {
117+
/* PWM polarity not supported (yet?) */
118+
return -ENOTSUP;
119+
}
120+
115121
config = dev->config->config_info;
116122
if (config == NULL) {
117123
LOG_ERR("The device configuration is NULL\n");

drivers/pwm/pwm_stm32.c

+7-1
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,8 @@ static u32_t __get_tim_clk(u32_t bus_clk,
7171
* return 0, or negative errno code
7272
*/
7373
static int pwm_stm32_pin_set(struct device *dev, u32_t pwm,
74-
u32_t period_cycles, u32_t pulse_cycles)
74+
u32_t period_cycles, u32_t pulse_cycles,
75+
pwm_flags_t flags)
7576
{
7677
struct pwm_stm32_data *data = DEV_DATA(dev);
7778
TIM_HandleTypeDef *TimerHandle = &data->hpwm;
@@ -83,6 +84,11 @@ static int pwm_stm32_pin_set(struct device *dev, u32_t pwm,
8384
return -EINVAL;
8485
}
8586

87+
if (flags) {
88+
/* PWM polarity not supported (yet?) */
89+
return -ENOTSUP;
90+
}
91+
8692
/* configure channel */
8793
channel = (pwm - 1)*CHANNEL_LENGTH;
8894

0 commit comments

Comments
 (0)