v2.0.0
pwm.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#ifndef _HARDWARE_PWM_H
8#define _HARDWARE_PWM_H
9
10#include "pico.h"
11#include "hardware/structs/pwm.h"
12#include "hardware/regs/dreq.h"
13#include "hardware/regs/intctrl.h"
14
15#ifdef __cplusplus
16extern "C" {
17#endif
18
19// PICO_CONFIG: PARAM_ASSERTIONS_ENABLED_HARDWARE_PWM, Enable/disable assertions in the hardware_pwm module, type=bool, default=0, group=hardware_pwm
20#ifndef PARAM_ASSERTIONS_ENABLED_HARDWARE_PWM
21#ifdef PARAM_ASSERTIONS_ENABLED_PWM // backwards compatibility with SDK < 2.0.0
22#define PARAM_ASSERTIONS_ENABLED_HARDWARE_PWM PARAM_ASSERTIONS_ENABLED_PWM
23#else
24#define PARAM_ASSERTIONS_ENABLED_HARDWARE_PWM 0
25#endif
26#endif
27
54 enum pwm_clkdiv_mode
55{
56 PWM_DIV_FREE_RUNNING = 0,
57 PWM_DIV_B_HIGH = 1,
58 PWM_DIV_B_RISING = 2,
59 PWM_DIV_B_FALLING = 3
60};
61
62enum pwm_chan
63{
64 PWM_CHAN_A = 0,
65 PWM_CHAN_B = 1
66};
67
68 typedef struct {
69 uint32_t csr;
70 uint32_t div;
71 uint32_t top;
72} pwm_config;
73
82#ifndef PWM_DREQ_NUM
83static_assert(DREQ_PWM_WRAP1 == DREQ_PWM_WRAP0 + 1, "");
84static_assert(DREQ_PWM_WRAP7 == DREQ_PWM_WRAP0 + 7, "");
85#define PWM_DREQ_NUM(slice_num) (DREQ_PWM_WRAP0 + (slice_num))
86#endif
87
94#ifndef PWM_GPIO_SLICE_NUM
95#define PWM_GPIO_SLICE_NUM(gpio) ({ \
96 uint slice_num; \
97 if ((gpio) < 32) { \
98 slice_num = ((gpio) >> 1u) & 7u; \
99 } else { \
100 slice_num = 8u + (((gpio) >> 1u) & 3u); \
101 } \
102 slice_num; \
103})
104#endif
105
106static inline void check_slice_num_param(__unused uint slice_num) {
107 valid_params_if(HARDWARE_PWM, slice_num < NUM_PWM_SLICES);
108}
109
115 static inline uint pwm_gpio_to_slice_num(uint gpio) {
116 valid_params_if(HARDWARE_PWM, gpio < NUM_BANK0_GPIOS);
117 return PWM_GPIO_SLICE_NUM(gpio);
118}
119
127 static inline uint pwm_gpio_to_channel(uint gpio) {
128 valid_params_if(HARDWARE_PWM, gpio < NUM_BANK0_GPIOS);
129 return gpio & 1u;
130}
131
141 static inline void pwm_config_set_phase_correct(pwm_config *c, bool phase_correct) {
142 c->csr = (c->csr & ~PWM_CH0_CSR_PH_CORRECT_BITS)
143 | (bool_to_bit(phase_correct) << PWM_CH0_CSR_PH_CORRECT_LSB);
144}
145
156 static inline void pwm_config_set_clkdiv(pwm_config *c, float div) {
157 valid_params_if(HARDWARE_PWM, div >= 1.f && div < 256.f);
158 c->div = (uint32_t)(div * (float)(1u << PWM_CH0_DIV_INT_LSB));
159}
160
172 static inline void pwm_config_set_clkdiv_int_frac(pwm_config *c, uint8_t integer, uint8_t fract) {
173 valid_params_if(HARDWARE_PWM, integer >= 1);
174 valid_params_if(HARDWARE_PWM, fract < 16);
175 c->div = (((uint)integer) << PWM_CH0_DIV_INT_LSB) | (((uint)fract) << PWM_CH0_DIV_FRAC_LSB);
176}
177
188 static inline void pwm_config_set_clkdiv_int(pwm_config *c, uint div) {
189 valid_params_if(HARDWARE_PWM, div >= 1 && div < 256);
190 pwm_config_set_clkdiv_int_frac(c, (uint8_t)div, 0);
191}
192
203 static inline void pwm_config_set_clkdiv_mode(pwm_config *c, enum pwm_clkdiv_mode mode) {
204 valid_params_if(HARDWARE_PWM, mode == PWM_DIV_FREE_RUNNING ||
205 mode == PWM_DIV_B_RISING ||
206 mode == PWM_DIV_B_HIGH ||
207 mode == PWM_DIV_B_FALLING);
208 c->csr = (c->csr & ~PWM_CH0_CSR_DIVMODE_BITS)
209 | (((uint)mode) << PWM_CH0_CSR_DIVMODE_LSB);
210}
211
219 static inline void pwm_config_set_output_polarity(pwm_config *c, bool a, bool b) {
220 c->csr = (c->csr & ~(PWM_CH0_CSR_A_INV_BITS | PWM_CH0_CSR_B_INV_BITS))
221 | ((bool_to_bit(a) << PWM_CH0_CSR_A_INV_LSB) | (bool_to_bit(b) << PWM_CH0_CSR_B_INV_LSB));
222}
223
232 static inline void pwm_config_set_wrap(pwm_config *c, uint16_t wrap) {
233 c->top = wrap;
234}
235
247 static inline void pwm_init(uint slice_num, pwm_config *c, bool start) {
248 check_slice_num_param(slice_num);
249 pwm_hw->slice[slice_num].csr = 0;
250
251 pwm_hw->slice[slice_num].ctr = PWM_CH0_CTR_RESET;
252 pwm_hw->slice[slice_num].cc = PWM_CH0_CC_RESET;
253 pwm_hw->slice[slice_num].top = c->top;
254 pwm_hw->slice[slice_num].div = c->div;
255 pwm_hw->slice[slice_num].csr = c->csr | (bool_to_bit(start) << PWM_CH0_CSR_EN_LSB);
256}
257
266 static inline pwm_config pwm_get_default_config(void) {
267 pwm_config c = {0, 0, 0};
268 pwm_config_set_phase_correct(&c, false);
269 pwm_config_set_clkdiv_int(&c, 1);
270 pwm_config_set_clkdiv_mode(&c, PWM_DIV_FREE_RUNNING);
271 pwm_config_set_output_polarity(&c, false, false);
272 pwm_config_set_wrap(&c, 0xffffu);
273 return c;
274}
275
291 static inline void pwm_set_wrap(uint slice_num, uint16_t wrap) {
292 check_slice_num_param(slice_num);
293 pwm_hw->slice[slice_num].top = wrap;
294}
295
311 static inline void pwm_set_chan_level(uint slice_num, uint chan, uint16_t level) {
312 check_slice_num_param(slice_num);
313 hw_write_masked(
314 &pwm_hw->slice[slice_num].cc,
315 ((uint)level) << (chan ? PWM_CH0_CC_B_LSB : PWM_CH0_CC_A_LSB),
316 chan ? PWM_CH0_CC_B_BITS : PWM_CH0_CC_A_BITS
317 );
318}
319
335 static inline void pwm_set_both_levels(uint slice_num, uint16_t level_a, uint16_t level_b) {
336 check_slice_num_param(slice_num);
337 pwm_hw->slice[slice_num].cc = (((uint)level_b) << PWM_CH0_CC_B_LSB) | (((uint)level_a) << PWM_CH0_CC_A_LSB);
338}
339
358 static inline void pwm_set_gpio_level(uint gpio, uint16_t level) {
359 valid_params_if(HARDWARE_PWM, gpio < NUM_BANK0_GPIOS);
360 pwm_set_chan_level(pwm_gpio_to_slice_num(gpio), pwm_gpio_to_channel(gpio), level);
361}
362
371 static inline uint16_t pwm_get_counter(uint slice_num) {
372 check_slice_num_param(slice_num);
373 return (uint16_t)(pwm_hw->slice[slice_num].ctr);
374}
375
385 static inline void pwm_set_counter(uint slice_num, uint16_t c) {
386 check_slice_num_param(slice_num);
387 pwm_hw->slice[slice_num].ctr = c;
388}
389
399 static inline void pwm_advance_count(uint slice_num) {
400 check_slice_num_param(slice_num);
401 hw_set_bits(&pwm_hw->slice[slice_num].csr, PWM_CH0_CSR_PH_ADV_BITS);
402 while (pwm_hw->slice[slice_num].csr & PWM_CH0_CSR_PH_ADV_BITS) {
403 tight_loop_contents();
404 }
405}
406
416 static inline void pwm_retard_count(uint slice_num) {
417 check_slice_num_param(slice_num);
418 hw_set_bits(&pwm_hw->slice[slice_num].csr, PWM_CH0_CSR_PH_RET_BITS);
419 while (pwm_hw->slice[slice_num].csr & PWM_CH0_CSR_PH_RET_BITS) {
420 tight_loop_contents();
421 }
422}
423
433 static inline void pwm_set_clkdiv_int_frac(uint slice_num, uint8_t integer, uint8_t fract) {
434 check_slice_num_param(slice_num);
435 valid_params_if(HARDWARE_PWM, integer >= 1);
436 valid_params_if(HARDWARE_PWM, fract < 16);
437 pwm_hw->slice[slice_num].div = (((uint)integer) << PWM_CH0_DIV_INT_LSB) | (((uint)fract) << PWM_CH0_DIV_FRAC_LSB);
438}
439
448 static inline void pwm_set_clkdiv(uint slice_num, float divider) {
449 check_slice_num_param(slice_num);
450 valid_params_if(HARDWARE_PWM, divider >= 1.f && divider < 256.f);
451 uint8_t i = (uint8_t)divider;
452 uint8_t f = (uint8_t)((divider - i) * (0x01 << 4));
453 pwm_set_clkdiv_int_frac(slice_num, i, f);
454}
455
463 static inline void pwm_set_output_polarity(uint slice_num, bool a, bool b) {
464 check_slice_num_param(slice_num);
465 hw_write_masked(&pwm_hw->slice[slice_num].csr, bool_to_bit(a) << PWM_CH0_CSR_A_INV_LSB | bool_to_bit(b) << PWM_CH0_CSR_B_INV_LSB,
466 PWM_CH0_CSR_A_INV_BITS | PWM_CH0_CSR_B_INV_BITS);
467}
468
469
476 static inline void pwm_set_clkdiv_mode(uint slice_num, enum pwm_clkdiv_mode mode) {
477 check_slice_num_param(slice_num);
478 valid_params_if(HARDWARE_PWM, mode == PWM_DIV_FREE_RUNNING ||
479 mode == PWM_DIV_B_RISING ||
480 mode == PWM_DIV_B_HIGH ||
481 mode == PWM_DIV_B_FALLING);
482 hw_write_masked(&pwm_hw->slice[slice_num].csr, ((uint)mode) << PWM_CH0_CSR_DIVMODE_LSB, PWM_CH0_CSR_DIVMODE_BITS);
483}
484
494 static inline void pwm_set_phase_correct(uint slice_num, bool phase_correct) {
495 check_slice_num_param(slice_num);
496 hw_write_masked(&pwm_hw->slice[slice_num].csr, bool_to_bit(phase_correct) << PWM_CH0_CSR_PH_CORRECT_LSB, PWM_CH0_CSR_PH_CORRECT_BITS);
497}
498
525 static inline void pwm_set_enabled(uint slice_num, bool enabled) {
526 check_slice_num_param(slice_num);
527 hw_write_masked(&pwm_hw->slice[slice_num].csr, bool_to_bit(enabled) << PWM_CH0_CSR_EN_LSB, PWM_CH0_CSR_EN_BITS);
528}
529
535 static inline void pwm_set_mask_enabled(uint32_t mask) {
536 pwm_hw->en = mask;
537}
538
555#ifndef PWM_DEFAULT_IRQ_NUM
556#if PICO_RP2040
557#define PWM_DEFAULT_IRQ_NUM() PWM_IRQ_WRAP
558#else
559#define PWM_DEFAULT_IRQ_NUM() PWM_IRQ_WRAP_0
560// backwards compatibility with RP2040
561#define PWM_IRQ_WRAP PWM_IRQ_WRAP_0
562#define isr_pwm_wrap isr_pwm_wrap_0
563#endif
564#endif
565
576 static inline void pwm_set_irq_enabled(uint slice_num, bool enabled) {
577 check_slice_num_param(slice_num);
578 if (enabled) {
579 hw_set_bits(&pwm_hw->inte, 1u << slice_num);
580 } else {
581 hw_clear_bits(&pwm_hw->inte, 1u << slice_num);
582 }
583}
584
593 static inline void pwm_set_irq0_enabled(uint slice_num, bool enabled) {
594 // irq0 always corresponds to the default IRQ
595 pwm_set_irq_enabled(slice_num, enabled);
596}
597
598#if NUM_PWM_IRQS > 1
607static inline void pwm_set_irq1_enabled(uint slice_num, bool enabled) {
608 check_slice_num_param(slice_num);
609 if (enabled) {
610 hw_set_bits(&pwm_hw->inte1, 1u << slice_num);
611 } else {
612 hw_clear_bits(&pwm_hw->inte1, 1u << slice_num);
613 }
614}
615#endif
616
628 static inline void pwm_irqn_set_slice_enabled(uint irq_index, uint slice_num, bool enabled) {
629 check_slice_num_param(slice_num);
630 invalid_params_if(HARDWARE_PWM, irq_index >= NUM_PWM_IRQS);
631 check_slice_num_param(slice_num);
632 if (enabled) {
633 hw_set_bits(&pwm_hw->irq_ctrl[irq_index].inte, 1u << slice_num);
634 } else {
635 hw_clear_bits(&pwm_hw->irq_ctrl[irq_index].inte, 1u << slice_num);
636 }
637}
638
649 static inline void pwm_set_irq_mask_enabled(uint32_t slice_mask, bool enabled) {
650 valid_params_if(HARDWARE_PWM, slice_mask < 256);
651#if PICO_RP2040
652 if (enabled) {
653 hw_set_bits(&pwm_hw->inte, slice_mask);
654 } else {
655 hw_clear_bits(&pwm_hw->inte, slice_mask);
656 }
657#else
658 static_assert(PWM_IRQ_WRAP_1 == PWM_IRQ_WRAP_0 + 1);
659 uint irq_index = PWM_DEFAULT_IRQ_NUM() - PWM_IRQ_WRAP_0;
660 if (enabled) {
661 hw_set_bits(&pwm_hw->irq_ctrl[irq_index].inte, slice_mask);
662 } else {
663 hw_clear_bits(&pwm_hw->irq_ctrl[irq_index].inte, slice_mask);
664 }
665#endif
666}
667
676 static inline void pwm_set_irq0_mask_enabled(uint32_t slice_mask, bool enabled) {
677 // default irq is irq0
678 pwm_set_irq_mask_enabled(slice_mask, enabled);
679}
680
681#if NUM_PWM_IRQS > 1
690static inline void pwm_set_irq1_mask_enabled(uint32_t slice_mask, bool enabled) {
691 if (enabled) {
692 hw_set_bits(&pwm_hw->inte1, slice_mask);
693 } else {
694 hw_clear_bits(&pwm_hw->inte1, slice_mask);
695 }
696}
697#endif
698
710 static inline void pwm_irqn_set_slice_mask_enabled(uint irq_index, uint slice_mask, bool enabled) {
711 invalid_params_if(HARDWARE_PWM, irq_index >= NUM_PWM_IRQS);
712 if (enabled) {
713 hw_set_bits(&pwm_hw->irq_ctrl[irq_index].inte, slice_mask);
714 } else {
715 hw_clear_bits(&pwm_hw->irq_ctrl[irq_index].inte, slice_mask);
716 }
717}
718
724 static inline void pwm_clear_irq(uint slice_num) {
725 pwm_hw->intr = 1u << slice_num;
726}
727
733 static inline uint32_t pwm_get_irq_status_mask(void) {
734 return pwm_hw->ints;
735}
736
742 static inline uint32_t pwm_get_irq0_status_mask(void) {
743 return pwm_get_irq_status_mask();
744}
745
746#if NUM_PWM_IRQS > 1
752static inline uint32_t pwm_get_irq1_status_mask(void) {
753 return pwm_hw->ints1;
754}
755#endif
756
763 static inline uint32_t pwm_irqn_get_status_mask(uint irq_index) {
764 invalid_params_if(HARDWARE_PWM, irq_index >= NUM_DMA_IRQS);
765 return pwm_hw->irq_ctrl[irq_index].ints;
766}
767
773 static inline void pwm_force_irq(uint slice_num) {
774 pwm_hw->intf = 1u << slice_num;
775}
776
782 static inline void pwm_force_irq0(uint slice_num) {
783 pwm_force_irq(slice_num);
784}
785
786#if NUM_PWM_IRQS > 1
792static inline void pwm_force_irq1(uint slice_num) {
793 pwm_hw->intf1 = 1u << slice_num;
794}
795#endif
796
803 static inline void pwm_irqn_force(uint irq_index, uint slice_num) {
804 invalid_params_if(HARDWARE_PWM, irq_index >= NUM_PWM_IRQS);
805 pwm_hw->irq_ctrl[irq_index].intf = 1u << slice_num;
806}
807
813 static inline uint pwm_get_dreq(uint slice_num) {
814 check_slice_num_param(slice_num);
815 return PWM_DREQ_NUM(slice_num);
816}
817
818#ifdef __cplusplus
819}
820#endif
821
822#endif
hw_set_bits
static __force_inline void hw_set_bits(io_rw_32 *addr, uint32_t mask)
Atomically set the specified bits to 1 in a HW register.
Definition: address_mapped.h:135
hw_write_masked
static __force_inline void hw_write_masked(io_rw_32 *addr, uint32_t values, uint32_t write_mask)
Set new values for a sub-set of the bits in a HW register.
Definition: address_mapped.h:171
hw_clear_bits
static __force_inline void hw_clear_bits(io_rw_32 *addr, uint32_t mask)
Atomically clear the specified bits to 0 in a HW register.
Definition: address_mapped.h:145
DREQ_PWM_WRAP1
@ DREQ_PWM_WRAP1
Select PWM Counter 1's Wrap Value as DREQ.
Definition: dreq.h:115
DREQ_PWM_WRAP0
@ DREQ_PWM_WRAP0
Select PWM Counter 0's Wrap Value as DREQ.
Definition: dreq.h:114
DREQ_PWM_WRAP7
@ DREQ_PWM_WRAP7
Select PWM Counter 7's Wrap Value as DREQ.
Definition: dreq.h:121
PWM_IRQ_WRAP_1
@ PWM_IRQ_WRAP_1
Select PWM's IRQ_WRAP 1 output.
Definition: intctrl.h:83
PWM_IRQ_WRAP_0
@ PWM_IRQ_WRAP_0
Select PWM's IRQ_WRAP 0 output.
Definition: intctrl.h:82
pwm_init
static void pwm_init(uint slice_num, pwm_config *c, bool start)
Initialise a PWM with settings from a configuration object.
Definition: pwm.h:247
pwm_config_set_phase_correct
static void pwm_config_set_phase_correct(pwm_config *c, bool phase_correct)
Set phase correction in a PWM configuration.
Definition: pwm.h:141
pwm_set_irq_enabled
static void pwm_set_irq_enabled(uint slice_num, bool enabled)
Enable PWM instance interrupt via the default PWM IRQ (PWM_IRQ_WRAP_0 on RP2350)
Definition: pwm.h:576
pwm_clkdiv_mode
pwm_clkdiv_mode
PWM Divider mode settings.
Definition: pwm.h:55
pwm_set_clkdiv_int_frac
static void pwm_set_clkdiv_int_frac(uint slice_num, uint8_t integer, uint8_t fract)
Set PWM clock divider using an 8:4 fractional value.
Definition: pwm.h:433
pwm_retard_count
static void pwm_retard_count(uint slice_num)
Retard PWM count.
Definition: pwm.h:416
pwm_get_counter
static uint16_t pwm_get_counter(uint slice_num)
Get PWM counter.
Definition: pwm.h:371
pwm_set_chan_level
static void pwm_set_chan_level(uint slice_num, uint chan, uint16_t level)
Set the current PWM counter compare value for one channel.
Definition: pwm.h:311
pwm_get_irq0_status_mask
static uint32_t pwm_get_irq0_status_mask(void)
Get PWM interrupt status, raw for the PWM_IRQ_WRAP_0.
Definition: pwm.h:742
pwm_config_set_clkdiv_int
static void pwm_config_set_clkdiv_int(pwm_config *c, uint div)
Set PWM clock divider in a PWM configuration.
Definition: pwm.h:188
pwm_set_clkdiv_mode
static void pwm_set_clkdiv_mode(uint slice_num, enum pwm_clkdiv_mode mode)
Set PWM divider mode.
Definition: pwm.h:476
pwm_set_enabled
static void pwm_set_enabled(uint slice_num, bool enabled)
Enable/Disable PWM.
Definition: pwm.h:525
pwm_set_mask_enabled
static void pwm_set_mask_enabled(uint32_t mask)
Enable/Disable multiple PWM slices simultaneously.
Definition: pwm.h:535
pwm_set_gpio_level
static void pwm_set_gpio_level(uint gpio, uint16_t level)
Helper function to set the PWM level for the slice and channel associated with a GPIO.
Definition: pwm.h:358
pwm_config_set_clkdiv_mode
static void pwm_config_set_clkdiv_mode(pwm_config *c, enum pwm_clkdiv_mode mode)
Set PWM counting mode in a PWM configuration.
Definition: pwm.h:203
pwm_irqn_set_slice_enabled
static void pwm_irqn_set_slice_enabled(uint irq_index, uint slice_num, bool enabled)
Enable PWM instance interrupt via either PWM_IRQ_WRAP_0 or PWM_IRQ_WRAP_1.
Definition: pwm.h:628
pwm_get_dreq
static uint pwm_get_dreq(uint slice_num)
Return the DREQ to use for pacing transfers to a particular PWM slice.
Definition: pwm.h:813
pwm_config_set_clkdiv_int_frac
static void pwm_config_set_clkdiv_int_frac(pwm_config *c, uint8_t integer, uint8_t fract)
Set PWM clock divider in a PWM configuration using an 8:4 fractional value.
Definition: pwm.h:172
pwm_force_irq
static void pwm_force_irq(uint slice_num)
Force PWM interrupt for the default PWM IRQ (PWM_IRQ_WRAP_0 on RP2350)
Definition: pwm.h:773
pwm_irqn_force
static void pwm_irqn_force(uint irq_index, uint slice_num)
Force PWM interrupt via PWM_IRQ_WRAP_0 or PWM_IRQ_WRAP_1.
Definition: pwm.h:803
pwm_set_counter
static void pwm_set_counter(uint slice_num, uint16_t c)
Set PWM counter.
Definition: pwm.h:385
pwm_force_irq0
static void pwm_force_irq0(uint slice_num)
Force PWM interrupt via PWM_IRQ_WRAP_0.
Definition: pwm.h:782
pwm_get_irq_status_mask
static uint32_t pwm_get_irq_status_mask(void)
Get PWM interrupt status, raw for the default PWM IRQ (PWM_IRQ_WRAP_0 on RP2350)
Definition: pwm.h:733
pwm_config_set_clkdiv
static void pwm_config_set_clkdiv(pwm_config *c, float div)
Set PWM clock divider in a PWM configuration.
Definition: pwm.h:156
pwm_irqn_set_slice_mask_enabled
static void pwm_irqn_set_slice_mask_enabled(uint irq_index, uint slice_mask, bool enabled)
Enable PWM instance interrupts via either PWM_IRQ_WRAP_0 or PWM_IRQ_WRAP_1.
Definition: pwm.h:710
pwm_set_wrap
static void pwm_set_wrap(uint slice_num, uint16_t wrap)
Set the current PWM counter wrap value.
Definition: pwm.h:291
PWM_DEFAULT_IRQ_NUM
#define PWM_DEFAULT_IRQ_NUM()
Returns the irq_num_t for the default PWM IRQ.
Definition: pwm.h:557
pwm_set_irq0_enabled
static void pwm_set_irq0_enabled(uint slice_num, bool enabled)
Enable PWM instance interrupt via PWM_IRQ_WRAP_0.
Definition: pwm.h:593
pwm_gpio_to_slice_num
static uint pwm_gpio_to_slice_num(uint gpio)
Determine the PWM slice that is attached to the specified GPIO.
Definition: pwm.h:115
pwm_clear_irq
static void pwm_clear_irq(uint slice_num)
Clear a single PWM channel interrupt.
Definition: pwm.h:724
pwm_set_clkdiv
static void pwm_set_clkdiv(uint slice_num, float divider)
Set PWM clock divider.
Definition: pwm.h:448
pwm_gpio_to_channel
static uint pwm_gpio_to_channel(uint gpio)
Determine the PWM channel that is attached to the specified GPIO.
Definition: pwm.h:127
pwm_advance_count
static void pwm_advance_count(uint slice_num)
Advance PWM count.
Definition: pwm.h:399
pwm_set_output_polarity
static void pwm_set_output_polarity(uint slice_num, bool a, bool b)
Set PWM output polarity.
Definition: pwm.h:463
pwm_irqn_get_status_mask
static uint32_t pwm_irqn_get_status_mask(uint irq_index)
Get PWM interrupt status, raw for either PWM_IRQ_WRAP_0 or PWM_IRQ_WRAP_1.
Definition: pwm.h:763
PWM_DREQ_NUM
#define PWM_DREQ_NUM(slice_num)
Returns the dreq_num_t used for pacing DMA transfers for a given PWM slice.
Definition: pwm.h:85
pwm_config_set_output_polarity
static void pwm_config_set_output_polarity(pwm_config *c, bool a, bool b)
Set output polarity in a PWM configuration.
Definition: pwm.h:219
pwm_set_irq_mask_enabled
static void pwm_set_irq_mask_enabled(uint32_t slice_mask, bool enabled)
Enable multiple PWM instance interrupts via the default PWM IRQ (PWM_IRQ_WRAP_0 on RP2350)
Definition: pwm.h:649
pwm_set_phase_correct
static void pwm_set_phase_correct(uint slice_num, bool phase_correct)
Set PWM phase correct on/off.
Definition: pwm.h:494
pwm_config_set_wrap
static void pwm_config_set_wrap(pwm_config *c, uint16_t wrap)
Set PWM counter wrap value in a PWM configuration.
Definition: pwm.h:232
pwm_get_default_config
static pwm_config pwm_get_default_config(void)
Get a set of default values for PWM configuration.
Definition: pwm.h:266
PWM_GPIO_SLICE_NUM
#define PWM_GPIO_SLICE_NUM(gpio)
Returns the PWM slice number for a given GPIO number.
Definition: pwm.h:95
pwm_set_irq0_mask_enabled
static void pwm_set_irq0_mask_enabled(uint32_t slice_mask, bool enabled)
Enable multiple PWM instance interrupts via PWM_IRQ_WRAP_0.
Definition: pwm.h:676
pwm_set_both_levels
static void pwm_set_both_levels(uint slice_num, uint16_t level_a, uint16_t level_b)
Set PWM counter compare values.
Definition: pwm.h:335
PWM_DIV_B_FALLING
@ PWM_DIV_B_FALLING
Fractional divider advances with each falling edge of the PWM B pin.
Definition: pwm.h:59
PWM_DIV_B_HIGH
@ PWM_DIV_B_HIGH
Fractional divider is gated by the PWM B pin.
Definition: pwm.h:57
PWM_DIV_FREE_RUNNING
@ PWM_DIV_FREE_RUNNING
Free-running counting at rate dictated by fractional divider.
Definition: pwm.h:56
PWM_DIV_B_RISING
@ PWM_DIV_B_RISING
Fractional divider advances with each rising edge of the PWM B pin.
Definition: pwm.h:58
tight_loop_contents
static __force_inline void tight_loop_contents(void)
No-op function for the body of tight loops.
Definition: platform.h:67
pico.h
pwm_config
Definition: pwm.h:68