From ce274040af48058e678b4e83ff9d89a569de7789 Mon Sep 17 00:00:00 2001 From: alanbjohnston Date: Mon, 4 Jul 2022 17:00:39 -0400 Subject: [PATCH] added pwm code --- cubesatsim/cubesatsim.ino | 56 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/cubesatsim/cubesatsim.ino b/cubesatsim/cubesatsim.ino index 5af2ac55..10dc8038 100644 --- a/cubesatsim/cubesatsim.ino +++ b/cubesatsim/cubesatsim.ino @@ -28,6 +28,11 @@ #include #include #include +#include +#include "pico/stdlib.h" // stdlib +#include "hardware/irq.h" // interrupts +#include "hardware/pwm.h" // pwm +#include "hardware/sync.h" // wait for interrupt Adafruit_INA219 ina219_1_0x40; Adafruit_INA219 ina219_1_0x41(0x41); @@ -1972,3 +1977,54 @@ void start_ina219() { ina219_2_0x44.setCalibration_16V_400mA(); ina219_2_0x45.setCalibration_16V_400mA(); } + +void start_pwm() { +// based on code https://github.com/rgrosset/pico-pwm-audio +// + set_sys_clock_khz(125000, true); + gpio_set_function(AUDIO_OUT_PIN, GPIO_FUNC_PWM); + + int audio_pin_slice = pwm_gpio_to_slice_num(AUDIO_PIN); + + // Setup PWM interrupt to fire when PWM cycle is complete + pwm_clear_irq(audio_pin_slice); + pwm_set_irq_enabled(audio_pin_slice, true); + // set the handle function above + irq_set_exclusive_handler(PWM_IRQ_WRAP, pwm_interrupt_handler); + irq_set_enabled(PWM_IRQ_WRAP, true); + + // Setup PWM for audio output + pwm_config config = pwm_get_default_config(); + /* Base clock 176,000,000 Hz divide by wrap 250 then the clock divider further divides + * to set the interrupt rate. + * + * 11 KHz is fine for speech. Phone lines generally sample at 8 KHz + * + * + * So clkdiv should be as follows for given sample rate + * 8.0f for 11 KHz + * 4.0f for 22 KHz + * 2.0f for 44 KHz etc + */ + pwm_config_set_clkdiv(&config, 16.0); // 8.0f); + pwm_config_set_wrap(&config, 250); + pwm_init(audio_pin_slice, &config, true); + + pwm_set_gpio_level(AUDIO_OUT_PIN, 0); + +} + +void pwm_interrupt_handler() { +// based on code https://github.com/rgrosset/pico-pwm-audio +// + pwm_clear_irq(pwm_gpio_to_slice_num(AUDIO_OUT_PIN)); + if (wav_position < (WAV_DATA_LENGTH<<3) - 1) { + // set pwm level + // allow the pwm value to repeat for 8 cycles this is >>3 + pwm_set_gpio_level(AUDIO_OUT_PIN, WAV_DATA[wav_position>>3]); + wav_position++; + } else { + // reset to start + wav_position = 0; + } +}