Skip to content

Commit c7ceba7

Browse files
mstasiaknordicnordicjm
authored andcommitted
[nrf fromtree] drivers: pwm: nrfx: 0/100% duty for PWM120
Fast PWM120 prevents GPIO from driving pin with low/high state when PWM duty is 0% or 100%. In such case, regular PWM signal generation needs to be used. Signed-off-by: Michał Stasiak <[email protected]> (cherry picked from commit a71f042)
1 parent 912cca9 commit c7ceba7

File tree

1 file changed

+47
-4
lines changed

1 file changed

+47
-4
lines changed

drivers/pwm/pwm_nrfx.c

Lines changed: 47 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,11 @@ LOG_MODULE_REGISTER(pwm_nrfx, CONFIG_PWM_LOG_LEVEL);
4646
(IS_EQ(DT_PHA(PWM(idx), power_domains, id), NRF_GPD_FAST_ACTIVE1)), \
4747
(0))), (0))
4848

49-
#if (NRFX_FOREACH_PRESENT(PWM, PWM_NRFX_IS_FAST, (||), (0))) && \
50-
CONFIG_CLOCK_CONTROL_NRF2_GLOBAL_HSFLL
49+
#if NRFX_FOREACH_PRESENT(PWM, PWM_NRFX_IS_FAST, (||), (0))
50+
#define PWM_NRFX_FAST_PRESENT 1
51+
#endif
52+
53+
#if defined(PWM_NRFX_FAST_PRESENT) && CONFIG_CLOCK_CONTROL_NRF2_GLOBAL_HSFLL
5154
#define PWM_NRFX_USE_CLOCK_CONTROL 1
5255
#endif
5356

@@ -86,6 +89,18 @@ struct pwm_nrfx_data {
8689
#error "Current implementation supports maximum 8 channels."
8790
#endif
8891

92+
#ifdef PWM_NRFX_FAST_PRESENT
93+
static bool pwm_is_fast(const struct pwm_nrfx_config *config)
94+
{
95+
return config->clock_freq > MHZ(16);
96+
}
97+
#else
98+
static bool pwm_is_fast(const struct pwm_nrfx_config *config)
99+
{
100+
return false;
101+
}
102+
#endif
103+
89104
static uint16_t *seq_values_ptr_get(const struct device *dev)
90105
{
91106
const struct pwm_nrfx_config *config = dev->config;
@@ -259,8 +274,20 @@ static int pwm_nrfx_set_cycles(const struct device *dev, uint32_t channel,
259274
if (inverted) {
260275
out_level ^= 1;
261276
}
262-
263-
nrf_gpio_pin_write(psel, out_level);
277+
/* Output of fast PWM instance is directly connected to GPIO pads,
278+
* thus it cannot controlled by GPIO. Use regular 0%/100% duty cycle
279+
* playback instead.
280+
*/
281+
#ifdef PWM_NRFX_FAST_PRESENT
282+
if (pwm_is_fast(config)) {
283+
nrfx_pwm_simple_playback(&config->pwm, &config->seq, 1,
284+
NRFX_PWM_FLAG_NO_EVT_FINISHED);
285+
} else {
286+
#else
287+
{
288+
#endif
289+
nrf_gpio_pin_write(psel, out_level);
290+
}
264291
}
265292

266293
data->pwm_needed &= ~BIT(channel);
@@ -275,6 +302,22 @@ static int pwm_nrfx_set_cycles(const struct device *dev, uint32_t channel,
275302
* registers and drives its outputs accordingly.
276303
*/
277304
if (data->pwm_needed == 0) {
305+
if (pwm_is_fast(config)) {
306+
#if PWM_NRFX_USE_CLOCK_CONTROL
307+
if (data->clock_requested) {
308+
int ret = nrf_clock_control_release(config->clk_dev,
309+
&config->clk_spec);
310+
311+
if (ret < 0) {
312+
LOG_ERR("Global HSFLL release failed: %d", ret);
313+
return ret;
314+
}
315+
316+
data->clock_requested = false;
317+
}
318+
#endif
319+
return 0;
320+
}
278321
int ret = stop_pwm(dev);
279322

280323
if (ret < 0) {

0 commit comments

Comments
 (0)