aboutsummaryrefslogtreecommitdiff
path: root/examples/rp235x/src/bin/pwm.rs
diff options
context:
space:
mode:
authorCurly <[email protected]>2025-02-23 07:33:58 -0800
committerCurly <[email protected]>2025-02-23 07:33:58 -0800
commit3932835998802fc3abf7cce4f736e072858ebfd1 (patch)
tree5dd714b99bc74a03556c58809237c88691c293bb /examples/rp235x/src/bin/pwm.rs
parentc3c67db93e627a4fafe5e1a1123e5cbb4abafe47 (diff)
rename `rp23` (?) folder to `rp235x`; fix `ci.sh` to use `rp235x` folder
Diffstat (limited to 'examples/rp235x/src/bin/pwm.rs')
-rw-r--r--examples/rp235x/src/bin/pwm.rs79
1 files changed, 79 insertions, 0 deletions
diff --git a/examples/rp235x/src/bin/pwm.rs b/examples/rp235x/src/bin/pwm.rs
new file mode 100644
index 000000000..a3c0f7e49
--- /dev/null
+++ b/examples/rp235x/src/bin/pwm.rs
@@ -0,0 +1,79 @@
1//! This example shows how to use PWM (Pulse Width Modulation) in the RP235x chip.
2//!
3//! We demonstrate two ways of using PWM:
4//! 1. Via config
5//! 2. Via setting a duty cycle
6
7#![no_std]
8#![no_main]
9
10use defmt::*;
11use embassy_executor::Spawner;
12use embassy_rp::peripherals::{PIN_25, PIN_4, PWM_SLICE2, PWM_SLICE4};
13use embassy_rp::pwm::{Config, Pwm, SetDutyCycle};
14use embassy_time::Timer;
15use {defmt_rtt as _, panic_probe as _};
16
17#[embassy_executor::main]
18async fn main(spawner: Spawner) {
19 let p = embassy_rp::init(Default::default());
20 spawner.spawn(pwm_set_config(p.PWM_SLICE4, p.PIN_25)).unwrap();
21 spawner.spawn(pwm_set_dutycycle(p.PWM_SLICE2, p.PIN_4)).unwrap();
22}
23
24/// Demonstrate PWM by modifying & applying the config
25///
26/// Using the onboard led, if You are using a different Board than plain Pico2 (i.e. W variant)
27/// you must use another slice & pin and an appropriate resistor.
28#[embassy_executor::task]
29async fn pwm_set_config(slice4: PWM_SLICE4, pin25: PIN_25) {
30 let mut c = Config::default();
31 c.top = 32_768;
32 c.compare_b = 8;
33 let mut pwm = Pwm::new_output_b(slice4, pin25, c.clone());
34
35 loop {
36 info!("current LED duty cycle: {}/32768", c.compare_b);
37 Timer::after_secs(1).await;
38 c.compare_b = c.compare_b.rotate_left(4);
39 pwm.set_config(&c);
40 }
41}
42
43/// Demonstrate PWM by setting duty cycle
44///
45/// Using GP4 in Slice2, make sure to use an appropriate resistor.
46#[embassy_executor::task]
47async fn pwm_set_dutycycle(slice2: PWM_SLICE2, pin4: PIN_4) {
48 // If we aim for a specific frequency, here is how we can calculate the top value.
49 // The top value sets the period of the PWM cycle, so a counter goes from 0 to top and then wraps around to 0.
50 // Every such wraparound is one PWM cycle. So here is how we get 25KHz:
51 let desired_freq_hz = 25_000;
52 let clock_freq_hz = embassy_rp::clocks::clk_sys_freq();
53 let divider = 16u8;
54 let period = (clock_freq_hz / (desired_freq_hz * divider as u32)) as u16 - 1;
55
56 let mut c = Config::default();
57 c.top = period;
58 c.divider = divider.into();
59
60 let mut pwm = Pwm::new_output_a(slice2, pin4, c.clone());
61
62 loop {
63 // 100% duty cycle, fully on
64 pwm.set_duty_cycle_fully_on().unwrap();
65 Timer::after_secs(1).await;
66
67 // 66% duty cycle. Expressed as simple percentage.
68 pwm.set_duty_cycle_percent(66).unwrap();
69 Timer::after_secs(1).await;
70
71 // 25% duty cycle. Expressed as 32768/4 = 8192.
72 pwm.set_duty_cycle(c.top / 4).unwrap();
73 Timer::after_secs(1).await;
74
75 // 0% duty cycle, fully off.
76 pwm.set_duty_cycle_fully_off().unwrap();
77 Timer::after_secs(1).await;
78 }
79}