I was playing with PWM on the RP2040. I can do square waves, but pretty much everything else does not work. I have recorded the PWM output with a sound card at 44100 Hz in order to verify it visually. (PIN 0 and GND are directly connected to Line In of the sound card.)
The square wave output looks pretty good (the highlighted selection is exactly 100 samples):
The sawtooth wave does not come out as such at all:
What am I doing wrong?
The code:
#define SYS_CLOCK_KHZ 133000
#define AUDIO_PIN 0
void on_pwm_wrap() {
const static bool sawtooth = true;
const static int period = 100;
static uint32_t i = 0;
pwm_clear_irq(pwm_gpio_to_slice_num(AUDIO_PIN));
i++;
uint16_t level = sawtooth
? (i % period) * (65535/(period-1)) // sawtooth
: (i % period) >= (period/2) ? 65535 : 0; // square
pwm_set_gpio_level(AUDIO_PIN, level);
}
int main() {
set_sys_clock_khz(SYS_CLOCK_KHZ, true);
gpio_set_function(AUDIO_PIN, GPIO_FUNC_PWM);
uint slice_num = pwm_gpio_to_slice_num(AUDIO_PIN);
pwm_clear_irq(slice_num);
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_config config = pwm_get_default_config();
// 3,015 * 1.00029 * 44,100 = 133,000,000
pwm_config_set_clkdiv(&config, 1.00029f);
pwm_config_set_wrap(&config, 3015);
pwm_init(slice_num, &config, true);
while (1)
tight_loop_contents();
}
period
variable.