You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
83 lines
1.8 KiB
83 lines
1.8 KiB
/* |
|
* Copyright (c) 2020-2021 Vestas Wind Systems A/S |
|
* |
|
* SPDX-License-Identifier: Apache-2.0 |
|
*/ |
|
|
|
|
|
#include <zephyr/kernel.h> |
|
#include <zephyr/drivers/pwm.h> |
|
#include <zephyr/logging/log.h> |
|
|
|
LOG_MODULE_REGISTER(pwm_capture, CONFIG_PWM_LOG_LEVEL); |
|
|
|
struct z_pwm_capture_cb_data { |
|
uint32_t period; |
|
uint32_t pulse; |
|
struct k_sem sem; |
|
int status; |
|
}; |
|
|
|
static void z_pwm_capture_cycles_callback(const struct device *dev, |
|
uint32_t channel, |
|
uint32_t period_cycles, |
|
uint32_t pulse_cycles, int status, |
|
void *user_data) |
|
{ |
|
struct z_pwm_capture_cb_data *data = user_data; |
|
|
|
data->period = period_cycles; |
|
data->pulse = pulse_cycles; |
|
data->status = status; |
|
|
|
k_sem_give(&data->sem); |
|
} |
|
|
|
int z_impl_pwm_capture_cycles(const struct device *dev, uint32_t channel, |
|
pwm_flags_t flags, uint32_t *period, |
|
uint32_t *pulse, k_timeout_t timeout) |
|
{ |
|
struct z_pwm_capture_cb_data data; |
|
int err; |
|
|
|
if ((flags & PWM_CAPTURE_MODE_MASK) == PWM_CAPTURE_MODE_CONTINUOUS) { |
|
LOG_ERR("continuous capture mode only supported via callback"); |
|
return -ENOTSUP; |
|
} |
|
|
|
flags |= PWM_CAPTURE_MODE_SINGLE; |
|
k_sem_init(&data.sem, 0, 1); |
|
|
|
err = pwm_configure_capture(dev, channel, flags, |
|
z_pwm_capture_cycles_callback, &data); |
|
if (err) { |
|
LOG_ERR("failed to configure pwm capture"); |
|
return err; |
|
} |
|
|
|
err = pwm_enable_capture(dev, channel); |
|
if (err) { |
|
LOG_ERR("failed to enable pwm capture"); |
|
return err; |
|
} |
|
|
|
err = k_sem_take(&data.sem, timeout); |
|
if (err == -EAGAIN) { |
|
(void)pwm_disable_capture(dev, channel); |
|
(void)pwm_configure_capture(dev, channel, flags, NULL, NULL); |
|
LOG_WRN("pwm capture timed out"); |
|
return err; |
|
} |
|
|
|
if (data.status == 0) { |
|
if (period != NULL) { |
|
*period = data.period; |
|
} |
|
|
|
if (pulse != NULL) { |
|
*pulse = data.pulse; |
|
} |
|
} |
|
|
|
return data.status; |
|
}
|
|
|