/* * Copyright (c) 2016 Intel Corporation * Copyright (c) 2020 Nordic Semiconductor ASA * * SPDX-License-Identifier: Apache-2.0 */ /** * @file Sample app to demonstrate PWM. */ #include #include #include #include static const struct pwm_dt_spec pwm_led0 = PWM_DT_SPEC_GET(DT_ALIAS(pwm_led0)); #define MIN_PERIOD PWM_SEC(1U) / 128U #define MAX_PERIOD PWM_SEC(1U) int main(void) { uint32_t max_period; uint32_t period; uint8_t dir = 0U; int ret; printk("PWM-based blinky\n"); if (!pwm_is_ready_dt(&pwm_led0)) { printk("Error: PWM device %s is not ready\n", pwm_led0.dev->name); return 0; } /* * In case the default MAX_PERIOD value cannot be set for * some PWM hardware, decrease its value until it can. * * Keep its value at least MIN_PERIOD * 4 to make sure * the sample changes frequency at least once. */ printk("Calibrating for channel %d...\n", pwm_led0.channel); max_period = MAX_PERIOD; while (pwm_set_dt(&pwm_led0, max_period, max_period / 2U)) { max_period /= 2U; if (max_period < (4U * MIN_PERIOD)) { printk("Error: PWM device " "does not support a period at least %lu\n", 4U * MIN_PERIOD); return 0; } } printk("Done calibrating; maximum/minimum periods %u/%lu nsec\n", max_period, MIN_PERIOD); period = max_period; while (1) { ret = pwm_set_dt(&pwm_led0, period, period / 2U); if (ret) { printk("Error %d: failed to set pulse width\n", ret); return 0; } printk("Using period %d\n", period); period = dir ? (period * 2U) : (period / 2U); if (period > max_period) { period = max_period / 2U; dir = 0U; } else if (period < MIN_PERIOD) { period = MIN_PERIOD * 2U; dir = 1U; } k_sleep(K_SECONDS(4U)); } return 0; }