Created
May 16, 2023 12:35
-
-
Save ricardomatias/f4412ad065fc89105bb5f1ae7d614431 to your computer and use it in GitHub Desktop.
pico pwm irq
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include "hardware/pwm.h" | |
| #include "hardware/clocks.h" | |
| #include "hardware/irq.h" | |
| #include "pico/binary_info.h" | |
| #include "pico/cyw43_arch.h" | |
| #include "pico/stdlib.h" | |
| #include "sonovolt/time.h" | |
| #define LED_PIN 15 | |
| #define PWM_PIN LED_PIN | |
| uint32_t pwm_set_freq_duty(uint slice_num, uint chan, uint32_t hz, int duty) { | |
| // 125mhz | |
| uint32_t clock = 125000000; | |
| uint32_t divider16 = (clock + hz * 2048) / (hz * 4096); | |
| if (divider16 / 16 == 0) divider16 = 16; | |
| uint32_t wrap = clock * 16 / divider16 / hz - 1; | |
| printf("wrap: %d\n", wrap); | |
| pwm_config config = pwm_get_default_config(); | |
| // Set divider, reduces counter clock to sysclock/this value | |
| pwm_config_set_clkdiv_int_frac(&config, divider16 / 16, divider16 & 0xF); | |
| pwm_config_set_wrap(&config, wrap); | |
| pwm_init(slice_num, &config, true); | |
| // pwm_set_clkdiv_int_frac(slice_num, divider16 / 16, divider16 & 0xF); | |
| // pwm_set_wrap(slice_num, wrap); | |
| // pwm_set_chan_level(slice_num, chan, wrap * duty / 100); | |
| return wrap; | |
| } | |
| static uint64_t ticks = 0; | |
| static uint64_t ticks_next = 960; | |
| void on_pwm_wrap() { | |
| static int fade = 0; | |
| static bool going_up = true; | |
| uint slice_num = pwm_gpio_to_slice_num(PWM_PIN); | |
| pwm_clear_irq(slice_num); | |
| if (going_up) { | |
| ++fade; | |
| if (fade > 255) { | |
| fade = 255; | |
| going_up = false; | |
| gpio_put(0, 1); | |
| } | |
| } else { | |
| --fade; | |
| if (fade < 0) { | |
| fade = 0; | |
| going_up = true; | |
| gpio_put(0, 0); | |
| } | |
| } | |
| pwm_set_gpio_level(PWM_PIN, fade * fade); | |
| } | |
| int main() { | |
| stdio_init_all(); | |
| gpio_init(0); | |
| gpio_set_dir(0, GPIO_OUT); | |
| // Tell GPIO 0 and 1 they are allocated to the PWM | |
| gpio_set_function(PWM_PIN, GPIO_FUNC_PWM); | |
| bi_decl(bi_program_description("PWM program")); | |
| bi_decl(bi_1pin_with_name(PWM_PIN, "PWM 0 Pin")); | |
| if (cyw43_arch_init()) { | |
| printf("Wi-Fi init failed"); | |
| return -1; | |
| } | |
| // Find out which PWM slice is connected to GPIO 0 (it's slice 0) | |
| uint slice_num = pwm_gpio_to_slice_num(PWM_PIN); | |
| uint chan = pwm_gpio_to_channel(PWM_PIN); | |
| sleep_ms(1000); | |
| const float f_pwm = sonovolt::time::bpm_to_hz(120) * 960.f; | |
| pwm_set_irq_enabled(slice_num, true); | |
| irq_set_exclusive_handler(PWM_IRQ_WRAP, on_pwm_wrap); | |
| irq_set_enabled(PWM_IRQ_WRAP, true); | |
| pwm_set_freq_duty(slice_num, chan, f_pwm, 50); | |
| while (true) { | |
| tight_loop_contents(); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment