Skip to content

Instantly share code, notes, and snippets.

@ricardomatias
Created May 16, 2023 12:35
Show Gist options
  • Save ricardomatias/f4412ad065fc89105bb5f1ae7d614431 to your computer and use it in GitHub Desktop.
Save ricardomatias/f4412ad065fc89105bb5f1ae7d614431 to your computer and use it in GitHub Desktop.
pico pwm irq
#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