aboutsummaryrefslogtreecommitdiff
path: root/examples/rp235x/src/bin
diff options
context:
space:
mode:
Diffstat (limited to 'examples/rp235x/src/bin')
-rw-r--r--examples/rp235x/src/bin/assign_resources.rs6
-rw-r--r--examples/rp235x/src/bin/blinky_two_channels.rs4
-rw-r--r--examples/rp235x/src/bin/blinky_two_tasks.rs4
-rw-r--r--examples/rp235x/src/bin/blinky_wifi.rs8
-rw-r--r--examples/rp235x/src/bin/blinky_wifi_pico_plus_2.rs2
-rw-r--r--examples/rp235x/src/bin/ethernet_w5500_icmp.rs143
-rw-r--r--examples/rp235x/src/bin/ethernet_w5500_icmp_ping.rs134
-rw-r--r--examples/rp235x/src/bin/ethernet_w5500_multisocket.rs139
-rw-r--r--examples/rp235x/src/bin/ethernet_w5500_tcp_client.rs127
-rw-r--r--examples/rp235x/src/bin/ethernet_w5500_tcp_server.rs136
-rw-r--r--examples/rp235x/src/bin/ethernet_w5500_udp.rs116
-rw-r--r--examples/rp235x/src/bin/i2c_slave.rs4
-rw-r--r--examples/rp235x/src/bin/interrupt.rs2
-rw-r--r--examples/rp235x/src/bin/multicore.rs4
-rw-r--r--examples/rp235x/src/bin/multiprio.rs6
-rw-r--r--examples/rp235x/src/bin/overclock.rs74
-rw-r--r--examples/rp235x/src/bin/pio_async.rs6
-rw-r--r--examples/rp235x/src/bin/pio_i2s.rs2
-rw-r--r--examples/rp235x/src/bin/pio_i2s_rx.rs81
-rw-r--r--examples/rp235x/src/bin/pio_onewire.rs103
-rw-r--r--examples/rp235x/src/bin/pio_onewire_parasite.rs89
-rw-r--r--examples/rp235x/src/bin/pio_rotary_encoder.rs4
-rw-r--r--examples/rp235x/src/bin/psram.rs49
-rw-r--r--examples/rp235x/src/bin/pwm.rs4
-rw-r--r--examples/rp235x/src/bin/shared_bus.rs8
-rw-r--r--examples/rp235x/src/bin/sharing.rs7
-rw-r--r--examples/rp235x/src/bin/trng.rs5
-rw-r--r--examples/rp235x/src/bin/uart_buffered_split.rs2
-rw-r--r--examples/rp235x/src/bin/uart_unidir.rs2
-rw-r--r--examples/rp235x/src/bin/usb_webusb.rs4
-rw-r--r--examples/rp235x/src/bin/zerocopy.rs4
31 files changed, 1184 insertions, 95 deletions
diff --git a/examples/rp235x/src/bin/assign_resources.rs b/examples/rp235x/src/bin/assign_resources.rs
index 341f54d22..4ee4278b5 100644
--- a/examples/rp235x/src/bin/assign_resources.rs
+++ b/examples/rp235x/src/bin/assign_resources.rs
@@ -26,15 +26,13 @@ async fn main(spawner: Spawner) {
26 let p = embassy_rp::init(Default::default()); 26 let p = embassy_rp::init(Default::default());
27 27
28 // 1) Assigning a resource to a task by passing parts of the peripherals. 28 // 1) Assigning a resource to a task by passing parts of the peripherals.
29 spawner 29 spawner.spawn(double_blinky_manually_assigned(spawner, p.PIN_20, p.PIN_21).unwrap());
30 .spawn(double_blinky_manually_assigned(spawner, p.PIN_20, p.PIN_21))
31 .unwrap();
32 30
33 // 2) Using the assign-resources macro to assign resources to a task. 31 // 2) Using the assign-resources macro to assign resources to a task.
34 // we perform the split, see further below for the definition of the resources struct 32 // we perform the split, see further below for the definition of the resources struct
35 let r = split_resources!(p); 33 let r = split_resources!(p);
36 // and then we can use them 34 // and then we can use them
37 spawner.spawn(double_blinky_macro_assigned(spawner, r.leds)).unwrap(); 35 spawner.spawn(double_blinky_macro_assigned(spawner, r.leds).unwrap());
38} 36}
39 37
40// 1) Assigning a resource to a task by passing parts of the peripherals. 38// 1) Assigning a resource to a task by passing parts of the peripherals.
diff --git a/examples/rp235x/src/bin/blinky_two_channels.rs b/examples/rp235x/src/bin/blinky_two_channels.rs
index 51e139e94..87f3a3545 100644
--- a/examples/rp235x/src/bin/blinky_two_channels.rs
+++ b/examples/rp235x/src/bin/blinky_two_channels.rs
@@ -27,8 +27,8 @@ async fn main(spawner: Spawner) {
27 let dt = 100 * 1_000_000; 27 let dt = 100 * 1_000_000;
28 let k = 1.003; 28 let k = 1.003;
29 29
30 unwrap!(spawner.spawn(toggle_led(CHANNEL.sender(), Duration::from_nanos(dt)))); 30 spawner.spawn(unwrap!(toggle_led(CHANNEL.sender(), Duration::from_nanos(dt))));
31 unwrap!(spawner.spawn(toggle_led( 31 spawner.spawn(unwrap!(toggle_led(
32 CHANNEL.sender(), 32 CHANNEL.sender(),
33 Duration::from_nanos((dt as f64 * k) as u64) 33 Duration::from_nanos((dt as f64 * k) as u64)
34 ))); 34 )));
diff --git a/examples/rp235x/src/bin/blinky_two_tasks.rs b/examples/rp235x/src/bin/blinky_two_tasks.rs
index 67a9108c0..aac7d928b 100644
--- a/examples/rp235x/src/bin/blinky_two_tasks.rs
+++ b/examples/rp235x/src/bin/blinky_two_tasks.rs
@@ -30,8 +30,8 @@ async fn main(spawner: Spawner) {
30 let dt = 100 * 1_000_000; 30 let dt = 100 * 1_000_000;
31 let k = 1.003; 31 let k = 1.003;
32 32
33 unwrap!(spawner.spawn(toggle_led(&LED, Duration::from_nanos(dt)))); 33 spawner.spawn(unwrap!(toggle_led(&LED, Duration::from_nanos(dt))));
34 unwrap!(spawner.spawn(toggle_led(&LED, Duration::from_nanos((dt as f64 * k) as u64)))); 34 spawner.spawn(unwrap!(toggle_led(&LED, Duration::from_nanos((dt as f64 * k) as u64))));
35} 35}
36 36
37#[embassy_executor::task(pool_size = 2)] 37#[embassy_executor::task(pool_size = 2)]
diff --git a/examples/rp235x/src/bin/blinky_wifi.rs b/examples/rp235x/src/bin/blinky_wifi.rs
index 8c352ebc4..b2201f0ae 100644
--- a/examples/rp235x/src/bin/blinky_wifi.rs
+++ b/examples/rp235x/src/bin/blinky_wifi.rs
@@ -5,7 +5,7 @@
5#![no_std] 5#![no_std]
6#![no_main] 6#![no_main]
7 7
8use cyw43_pio::{PioSpi, DEFAULT_CLOCK_DIVIDER}; 8use cyw43_pio::{PioSpi, RM2_CLOCK_DIVIDER};
9use defmt::*; 9use defmt::*;
10use embassy_executor::Spawner; 10use embassy_executor::Spawner;
11use embassy_rp::bind_interrupts; 11use embassy_rp::bind_interrupts;
@@ -58,7 +58,9 @@ async fn main(spawner: Spawner) {
58 let spi = PioSpi::new( 58 let spi = PioSpi::new(
59 &mut pio.common, 59 &mut pio.common,
60 pio.sm0, 60 pio.sm0,
61 DEFAULT_CLOCK_DIVIDER, 61 // SPI communication won't work if the speed is too high, so we use a divider larger than `DEFAULT_CLOCK_DIVIDER`.
62 // See: https://github.com/embassy-rs/embassy/issues/3960.
63 RM2_CLOCK_DIVIDER,
62 pio.irq0, 64 pio.irq0,
63 cs, 65 cs,
64 p.PIN_24, 66 p.PIN_24,
@@ -69,7 +71,7 @@ async fn main(spawner: Spawner) {
69 static STATE: StaticCell<cyw43::State> = StaticCell::new(); 71 static STATE: StaticCell<cyw43::State> = StaticCell::new();
70 let state = STATE.init(cyw43::State::new()); 72 let state = STATE.init(cyw43::State::new());
71 let (_net_device, mut control, runner) = cyw43::new(state, pwr, spi, fw).await; 73 let (_net_device, mut control, runner) = cyw43::new(state, pwr, spi, fw).await;
72 unwrap!(spawner.spawn(cyw43_task(runner))); 74 spawner.spawn(unwrap!(cyw43_task(runner)));
73 75
74 control.init(clm).await; 76 control.init(clm).await;
75 control 77 control
diff --git a/examples/rp235x/src/bin/blinky_wifi_pico_plus_2.rs b/examples/rp235x/src/bin/blinky_wifi_pico_plus_2.rs
index 0a5bccfb3..e6d6f687b 100644
--- a/examples/rp235x/src/bin/blinky_wifi_pico_plus_2.rs
+++ b/examples/rp235x/src/bin/blinky_wifi_pico_plus_2.rs
@@ -68,7 +68,7 @@ async fn main(spawner: Spawner) {
68 static STATE: StaticCell<cyw43::State> = StaticCell::new(); 68 static STATE: StaticCell<cyw43::State> = StaticCell::new();
69 let state = STATE.init(cyw43::State::new()); 69 let state = STATE.init(cyw43::State::new());
70 let (_net_device, mut control, runner) = cyw43::new(state, pwr, spi, fw).await; 70 let (_net_device, mut control, runner) = cyw43::new(state, pwr, spi, fw).await;
71 unwrap!(spawner.spawn(cyw43_task(runner))); 71 spawner.spawn(unwrap!(cyw43_task(runner)));
72 72
73 control.init(clm).await; 73 control.init(clm).await;
74 control 74 control
diff --git a/examples/rp235x/src/bin/ethernet_w5500_icmp.rs b/examples/rp235x/src/bin/ethernet_w5500_icmp.rs
new file mode 100644
index 000000000..f012c9589
--- /dev/null
+++ b/examples/rp235x/src/bin/ethernet_w5500_icmp.rs
@@ -0,0 +1,143 @@
1//! This example implements an echo (ping) with an ICMP Socket and using defmt to report the results.
2//!
3//! Although there is a better way to execute pings using the child module ping of the icmp module,
4//! this example allows for other icmp messages like `Destination unreachable` to be sent aswell.
5//!
6//! Example written for the [`WIZnet W5500-EVB-Pico2`](https://docs.wiznet.io/Product/iEthernet/W5500/w5500-evb-pico2) board.
7
8#![no_std]
9#![no_main]
10
11use defmt::*;
12use embassy_executor::Spawner;
13use embassy_futures::yield_now;
14use embassy_net::icmp::{ChecksumCapabilities, IcmpEndpoint, IcmpSocket, Icmpv4Packet, Icmpv4Repr, PacketMetadata};
15use embassy_net::{Stack, StackResources};
16use embassy_net_wiznet::chip::W5500;
17use embassy_net_wiznet::*;
18use embassy_rp::clocks::RoscRng;
19use embassy_rp::gpio::{Input, Level, Output, Pull};
20use embassy_rp::peripherals::SPI0;
21use embassy_rp::spi::{Async, Config as SpiConfig, Spi};
22use embassy_time::{Delay, Instant, Timer};
23use embedded_hal_bus::spi::ExclusiveDevice;
24use static_cell::StaticCell;
25use {defmt_rtt as _, panic_probe as _};
26
27type ExclusiveSpiDevice = ExclusiveDevice<Spi<'static, SPI0, Async>, Output<'static>, Delay>;
28
29#[embassy_executor::task]
30async fn ethernet_task(runner: Runner<'static, W5500, ExclusiveSpiDevice, Input<'static>, Output<'static>>) -> ! {
31 runner.run().await
32}
33
34#[embassy_executor::task]
35async fn net_task(mut runner: embassy_net::Runner<'static, Device<'static>>) -> ! {
36 runner.run().await
37}
38
39#[embassy_executor::main]
40async fn main(spawner: Spawner) {
41 let p = embassy_rp::init(Default::default());
42 let mut rng = RoscRng;
43
44 let mut spi_cfg = SpiConfig::default();
45 spi_cfg.frequency = 50_000_000;
46 let (miso, mosi, clk) = (p.PIN_16, p.PIN_19, p.PIN_18);
47 let spi = Spi::new(p.SPI0, clk, mosi, miso, p.DMA_CH0, p.DMA_CH1, spi_cfg);
48 let cs = Output::new(p.PIN_17, Level::High);
49 let w5500_int = Input::new(p.PIN_21, Pull::Up);
50 let w5500_reset = Output::new(p.PIN_20, Level::High);
51
52 let mac_addr = [0x02, 0x00, 0x00, 0x00, 0x00, 0x00];
53 static STATE: StaticCell<State<8, 8>> = StaticCell::new();
54 let state = STATE.init(State::<8, 8>::new());
55 let (device, runner) = embassy_net_wiznet::new(
56 mac_addr,
57 state,
58 ExclusiveDevice::new(spi, cs, Delay),
59 w5500_int,
60 w5500_reset,
61 )
62 .await
63 .unwrap();
64 spawner.spawn(unwrap!(ethernet_task(runner)));
65
66 // Generate random seed
67 let seed = rng.next_u64();
68
69 // Init network stack
70 static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new();
71 let (stack, runner) = embassy_net::new(
72 device,
73 embassy_net::Config::dhcpv4(Default::default()),
74 RESOURCES.init(StackResources::new()),
75 seed,
76 );
77
78 // Launch network task
79 spawner.spawn(unwrap!(net_task(runner)));
80
81 info!("Waiting for DHCP...");
82 let cfg = wait_for_config(stack).await;
83 let local_addr = cfg.address.address();
84 info!("IP address: {:?}", local_addr);
85
86 // Then we can use it!
87 let mut rx_buffer = [0; 256];
88 let mut tx_buffer = [0; 256];
89 let mut rx_meta = [PacketMetadata::EMPTY];
90 let mut tx_meta = [PacketMetadata::EMPTY];
91
92 // Identifier used for the ICMP socket
93 let ident = 42;
94
95 // Create and bind the socket
96 let mut socket = IcmpSocket::new(stack, &mut rx_meta, &mut rx_buffer, &mut tx_meta, &mut tx_buffer);
97 socket.bind(IcmpEndpoint::Ident(ident)).unwrap();
98
99 // Create the repr for the packet
100 let icmp_repr = Icmpv4Repr::EchoRequest {
101 ident,
102 seq_no: 0,
103 data: b"Hello, icmp!",
104 };
105
106 // Send the packet and store the starting instant to mesure latency later
107 let start = socket
108 .send_to_with(icmp_repr.buffer_len(), cfg.gateway.unwrap(), |buf| {
109 // Create and populate the packet buffer allocated by `send_to_with`
110 let mut icmp_packet = Icmpv4Packet::new_unchecked(buf);
111 icmp_repr.emit(&mut icmp_packet, &ChecksumCapabilities::default());
112 Instant::now() // Return the instant where the packet was sent
113 })
114 .await
115 .unwrap();
116
117 // Recieve and log the data of the reply
118 socket
119 .recv_from_with(|(buf, addr)| {
120 let packet = Icmpv4Packet::new_checked(buf).unwrap();
121 info!(
122 "Recieved {:?} from {} in {}ms",
123 packet.data(),
124 addr,
125 start.elapsed().as_millis()
126 );
127 })
128 .await
129 .unwrap();
130
131 loop {
132 Timer::after_secs(10).await;
133 }
134}
135
136async fn wait_for_config(stack: Stack<'static>) -> embassy_net::StaticConfigV4 {
137 loop {
138 if let Some(config) = stack.config_v4() {
139 return config.clone();
140 }
141 yield_now().await;
142 }
143}
diff --git a/examples/rp235x/src/bin/ethernet_w5500_icmp_ping.rs b/examples/rp235x/src/bin/ethernet_w5500_icmp_ping.rs
new file mode 100644
index 000000000..309d3e4f7
--- /dev/null
+++ b/examples/rp235x/src/bin/ethernet_w5500_icmp_ping.rs
@@ -0,0 +1,134 @@
1//! This example implements a LAN ping scan with the ping utilities in the icmp module of embassy-net.
2//!
3//! Example written for the [`WIZnet W5500-EVB-Pico2`](https://docs.wiznet.io/Product/iEthernet/W5500/w5500-evb-pico2) board.
4
5#![no_std]
6#![no_main]
7
8use core::net::Ipv4Addr;
9use core::ops::Not;
10use core::str::FromStr;
11
12use defmt::*;
13use embassy_executor::Spawner;
14use embassy_futures::yield_now;
15use embassy_net::icmp::ping::{PingManager, PingParams};
16use embassy_net::icmp::PacketMetadata;
17use embassy_net::{Ipv4Cidr, Stack, StackResources};
18use embassy_net_wiznet::chip::W5500;
19use embassy_net_wiznet::*;
20use embassy_rp::clocks::RoscRng;
21use embassy_rp::gpio::{Input, Level, Output, Pull};
22use embassy_rp::peripherals::SPI0;
23use embassy_rp::spi::{Async, Config as SpiConfig, Spi};
24use embassy_time::{Delay, Duration};
25use embedded_hal_bus::spi::ExclusiveDevice;
26use static_cell::StaticCell;
27use {defmt_rtt as _, panic_probe as _};
28
29type ExclusiveSpiDevice = ExclusiveDevice<Spi<'static, SPI0, Async>, Output<'static>, Delay>;
30
31#[embassy_executor::task]
32async fn ethernet_task(runner: Runner<'static, W5500, ExclusiveSpiDevice, Input<'static>, Output<'static>>) -> ! {
33 runner.run().await
34}
35
36#[embassy_executor::task]
37async fn net_task(mut runner: embassy_net::Runner<'static, Device<'static>>) -> ! {
38 runner.run().await
39}
40
41#[embassy_executor::main]
42async fn main(spawner: Spawner) {
43 let p = embassy_rp::init(Default::default());
44 let mut rng = RoscRng;
45
46 let mut spi_cfg = SpiConfig::default();
47 spi_cfg.frequency = 50_000_000;
48 let (miso, mosi, clk) = (p.PIN_16, p.PIN_19, p.PIN_18);
49 let spi = Spi::new(p.SPI0, clk, mosi, miso, p.DMA_CH0, p.DMA_CH1, spi_cfg);
50 let cs = Output::new(p.PIN_17, Level::High);
51 let w5500_int = Input::new(p.PIN_21, Pull::Up);
52 let w5500_reset = Output::new(p.PIN_20, Level::High);
53
54 let mac_addr = [0x02, 0x00, 0x00, 0x00, 0x00, 0x00];
55 static STATE: StaticCell<State<8, 8>> = StaticCell::new();
56 let state = STATE.init(State::<8, 8>::new());
57 let (device, runner) = embassy_net_wiznet::new(
58 mac_addr,
59 state,
60 ExclusiveDevice::new(spi, cs, Delay),
61 w5500_int,
62 w5500_reset,
63 )
64 .await
65 .unwrap();
66 spawner.spawn(unwrap!(ethernet_task(runner)));
67
68 // Generate random seed
69 let seed = rng.next_u64();
70
71 // Init network stack
72 static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new();
73 let (stack, runner) = embassy_net::new(
74 device,
75 embassy_net::Config::dhcpv4(Default::default()),
76 RESOURCES.init(StackResources::new()),
77 seed,
78 );
79
80 // Launch network task
81 spawner.spawn(unwrap!(net_task(runner)));
82
83 info!("Waiting for DHCP...");
84 let cfg = wait_for_config(stack).await;
85 let local_addr = cfg.address.address();
86 info!("IP address: {:?}", local_addr);
87 let gateway = cfg.gateway.unwrap();
88 let mask = cfg.address.netmask();
89 let lower_bound = (gateway.to_bits() & mask.to_bits()) + 1;
90 let upper_bound = gateway.to_bits() | mask.to_bits().not();
91 let addr_range = lower_bound..=upper_bound;
92
93 // Then we can use it!
94 let mut rx_buffer = [0; 256];
95 let mut tx_buffer = [0; 256];
96 let mut rx_meta = [PacketMetadata::EMPTY];
97 let mut tx_meta = [PacketMetadata::EMPTY];
98
99 // Create the ping manager instance
100 let mut ping_manager = PingManager::new(stack, &mut rx_meta, &mut rx_buffer, &mut tx_meta, &mut tx_buffer);
101 let addr = "192.168.8.1"; // Address to ping to
102 // Create the PingParams with the target address
103 let mut ping_params = PingParams::new(Ipv4Addr::from_str(addr).unwrap());
104 // (optional) Set custom properties of the ping
105 ping_params.set_payload(b"Hello, Ping!"); // custom payload
106 ping_params.set_count(1); // ping 1 times per ping call
107 ping_params.set_timeout(Duration::from_millis(500)); // wait .5 seconds instead of 4
108
109 info!("Online hosts in {}:", Ipv4Cidr::from_netmask(gateway, mask).unwrap());
110 let mut total_online_hosts = 0u32;
111 for addr in addr_range {
112 let ip_addr = Ipv4Addr::from_bits(addr);
113 // Set the target address in the ping params
114 ping_params.set_target(ip_addr);
115 // Execute the ping with the given parameters and wait for the reply
116 match ping_manager.ping(&ping_params).await {
117 Ok(time) => {
118 info!("{} is online\n- latency: {}ms\n", ip_addr, time.as_millis());
119 total_online_hosts += 1;
120 }
121 _ => continue,
122 }
123 }
124 info!("Ping scan complete, total online hosts: {}", total_online_hosts);
125}
126
127async fn wait_for_config(stack: Stack<'static>) -> embassy_net::StaticConfigV4 {
128 loop {
129 if let Some(config) = stack.config_v4() {
130 return config.clone();
131 }
132 yield_now().await;
133 }
134}
diff --git a/examples/rp235x/src/bin/ethernet_w5500_multisocket.rs b/examples/rp235x/src/bin/ethernet_w5500_multisocket.rs
new file mode 100644
index 000000000..7cfc00776
--- /dev/null
+++ b/examples/rp235x/src/bin/ethernet_w5500_multisocket.rs
@@ -0,0 +1,139 @@
1//! This example shows how you can allow multiple simultaneous TCP connections, by having multiple sockets listening on the same port.
2//!
3//! Example written for the [`WIZnet W5500-EVB-Pico2`](https://docs.wiznet.io/Product/iEthernet/W5500/w5500-evb-pico2) board.
4
5#![no_std]
6#![no_main]
7
8use defmt::*;
9use embassy_executor::Spawner;
10use embassy_futures::yield_now;
11use embassy_net::{Stack, StackResources};
12use embassy_net_wiznet::chip::W5500;
13use embassy_net_wiznet::*;
14use embassy_rp::clocks::RoscRng;
15use embassy_rp::gpio::{Input, Level, Output, Pull};
16use embassy_rp::peripherals::SPI0;
17use embassy_rp::spi::{Async, Config as SpiConfig, Spi};
18use embassy_time::{Delay, Duration};
19use embedded_hal_bus::spi::ExclusiveDevice;
20use embedded_io_async::Write;
21use static_cell::StaticCell;
22use {defmt_rtt as _, panic_probe as _};
23
24#[embassy_executor::task]
25async fn ethernet_task(
26 runner: Runner<
27 'static,
28 W5500,
29 ExclusiveDevice<Spi<'static, SPI0, Async>, Output<'static>, Delay>,
30 Input<'static>,
31 Output<'static>,
32 >,
33) -> ! {
34 runner.run().await
35}
36
37#[embassy_executor::task]
38async fn net_task(mut runner: embassy_net::Runner<'static, Device<'static>>) -> ! {
39 runner.run().await
40}
41
42#[embassy_executor::main]
43async fn main(spawner: Spawner) {
44 let p = embassy_rp::init(Default::default());
45 let mut rng = RoscRng;
46
47 let mut spi_cfg = SpiConfig::default();
48 spi_cfg.frequency = 50_000_000;
49 let (miso, mosi, clk) = (p.PIN_16, p.PIN_19, p.PIN_18);
50 let spi = Spi::new(p.SPI0, clk, mosi, miso, p.DMA_CH0, p.DMA_CH1, spi_cfg);
51 let cs = Output::new(p.PIN_17, Level::High);
52 let w5500_int = Input::new(p.PIN_21, Pull::Up);
53 let w5500_reset = Output::new(p.PIN_20, Level::High);
54
55 let mac_addr = [0x02, 0x00, 0x00, 0x00, 0x00, 0x00];
56 static STATE: StaticCell<State<8, 8>> = StaticCell::new();
57 let state = STATE.init(State::<8, 8>::new());
58 let (device, runner) = embassy_net_wiznet::new(
59 mac_addr,
60 state,
61 ExclusiveDevice::new(spi, cs, Delay),
62 w5500_int,
63 w5500_reset,
64 )
65 .await
66 .unwrap();
67 spawner.spawn(unwrap!(ethernet_task(runner)));
68
69 // Generate random seed
70 let seed = rng.next_u64();
71
72 // Init network stack
73 static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new();
74 let (stack, runner) = embassy_net::new(
75 device,
76 embassy_net::Config::dhcpv4(Default::default()),
77 RESOURCES.init(StackResources::new()),
78 seed,
79 );
80
81 // Launch network task
82 spawner.spawn(unwrap!(net_task(runner)));
83
84 info!("Waiting for DHCP...");
85 let cfg = wait_for_config(stack).await;
86 let local_addr = cfg.address.address();
87 info!("IP address: {:?}", local_addr);
88
89 // Create two sockets listening to the same port, to handle simultaneous connections
90 spawner.spawn(unwrap!(listen_task(stack, 0, 1234)));
91 spawner.spawn(unwrap!(listen_task(stack, 1, 1234)));
92}
93
94#[embassy_executor::task(pool_size = 2)]
95async fn listen_task(stack: Stack<'static>, id: u8, port: u16) {
96 let mut rx_buffer = [0; 4096];
97 let mut tx_buffer = [0; 4096];
98 let mut buf = [0; 4096];
99 loop {
100 let mut socket = embassy_net::tcp::TcpSocket::new(stack, &mut rx_buffer, &mut tx_buffer);
101 socket.set_timeout(Some(Duration::from_secs(10)));
102
103 info!("SOCKET {}: Listening on TCP:{}...", id, port);
104 if let Err(e) = socket.accept(port).await {
105 warn!("accept error: {:?}", e);
106 continue;
107 }
108 info!("SOCKET {}: Received connection from {:?}", id, socket.remote_endpoint());
109
110 loop {
111 let n = match socket.read(&mut buf).await {
112 Ok(0) => {
113 warn!("read EOF");
114 break;
115 }
116 Ok(n) => n,
117 Err(e) => {
118 warn!("SOCKET {}: {:?}", id, e);
119 break;
120 }
121 };
122 info!("SOCKET {}: rxd {}", id, core::str::from_utf8(&buf[..n]).unwrap());
123
124 if let Err(e) = socket.write_all(&buf[..n]).await {
125 warn!("write error: {:?}", e);
126 break;
127 }
128 }
129 }
130}
131
132async fn wait_for_config(stack: Stack<'static>) -> embassy_net::StaticConfigV4 {
133 loop {
134 if let Some(config) = stack.config_v4() {
135 return config.clone();
136 }
137 yield_now().await;
138 }
139}
diff --git a/examples/rp235x/src/bin/ethernet_w5500_tcp_client.rs b/examples/rp235x/src/bin/ethernet_w5500_tcp_client.rs
new file mode 100644
index 000000000..254aada9a
--- /dev/null
+++ b/examples/rp235x/src/bin/ethernet_w5500_tcp_client.rs
@@ -0,0 +1,127 @@
1//! This example implements a TCP client that attempts to connect to a host on port 1234 and send it some data once per second.
2//!
3//! Example written for the [`WIZnet W5500-EVB-Pico2`](https://docs.wiznet.io/Product/iEthernet/W5500/w5500-evb-pico2) board.
4
5#![no_std]
6#![no_main]
7
8use core::str::FromStr;
9
10use defmt::*;
11use embassy_executor::Spawner;
12use embassy_futures::yield_now;
13use embassy_net::{Stack, StackResources};
14use embassy_net_wiznet::chip::W5500;
15use embassy_net_wiznet::*;
16use embassy_rp::clocks::RoscRng;
17use embassy_rp::gpio::{Input, Level, Output, Pull};
18use embassy_rp::peripherals::SPI0;
19use embassy_rp::spi::{Async, Config as SpiConfig, Spi};
20use embassy_time::{Delay, Duration, Timer};
21use embedded_hal_bus::spi::ExclusiveDevice;
22use embedded_io_async::Write;
23use static_cell::StaticCell;
24use {defmt_rtt as _, panic_probe as _};
25
26#[embassy_executor::task]
27async fn ethernet_task(
28 runner: Runner<
29 'static,
30 W5500,
31 ExclusiveDevice<Spi<'static, SPI0, Async>, Output<'static>, Delay>,
32 Input<'static>,
33 Output<'static>,
34 >,
35) -> ! {
36 runner.run().await
37}
38
39#[embassy_executor::task]
40async fn net_task(mut runner: embassy_net::Runner<'static, Device<'static>>) -> ! {
41 runner.run().await
42}
43
44#[embassy_executor::main]
45async fn main(spawner: Spawner) {
46 let p = embassy_rp::init(Default::default());
47 let mut rng = RoscRng;
48 let mut led = Output::new(p.PIN_25, Level::Low);
49
50 let mut spi_cfg = SpiConfig::default();
51 spi_cfg.frequency = 50_000_000;
52 let (miso, mosi, clk) = (p.PIN_16, p.PIN_19, p.PIN_18);
53 let spi = Spi::new(p.SPI0, clk, mosi, miso, p.DMA_CH0, p.DMA_CH1, spi_cfg);
54 let cs = Output::new(p.PIN_17, Level::High);
55 let w5500_int = Input::new(p.PIN_21, Pull::Up);
56 let w5500_reset = Output::new(p.PIN_20, Level::High);
57
58 let mac_addr = [0x02, 0x00, 0x00, 0x00, 0x00, 0x00];
59 static STATE: StaticCell<State<8, 8>> = StaticCell::new();
60 let state = STATE.init(State::<8, 8>::new());
61 let (device, runner) = embassy_net_wiznet::new(
62 mac_addr,
63 state,
64 ExclusiveDevice::new(spi, cs, Delay),
65 w5500_int,
66 w5500_reset,
67 )
68 .await
69 .unwrap();
70 spawner.spawn(unwrap!(ethernet_task(runner)));
71
72 // Generate random seed
73 let seed = rng.next_u64();
74
75 // Init network stack
76 static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new();
77 let (stack, runner) = embassy_net::new(
78 device,
79 embassy_net::Config::dhcpv4(Default::default()),
80 RESOURCES.init(StackResources::new()),
81 seed,
82 );
83
84 // Launch network task
85 spawner.spawn(unwrap!(net_task(runner)));
86
87 info!("Waiting for DHCP...");
88 let cfg = wait_for_config(stack).await;
89 let local_addr = cfg.address.address();
90 info!("IP address: {:?}", local_addr);
91
92 let mut rx_buffer = [0; 4096];
93 let mut tx_buffer = [0; 4096];
94 loop {
95 let mut socket = embassy_net::tcp::TcpSocket::new(stack, &mut rx_buffer, &mut tx_buffer);
96 socket.set_timeout(Some(Duration::from_secs(10)));
97
98 led.set_low();
99 info!("Connecting...");
100 let host_addr = embassy_net::Ipv4Address::from_str("192.168.0.118").unwrap();
101 if let Err(e) = socket.connect((host_addr, 1234)).await {
102 warn!("connect error: {:?}", e);
103 continue;
104 }
105 info!("Connected to {:?}", socket.remote_endpoint());
106 led.set_high();
107
108 let msg = b"Hello world!\n";
109 loop {
110 if let Err(e) = socket.write_all(msg).await {
111 warn!("write error: {:?}", e);
112 break;
113 }
114 info!("txd: {}", core::str::from_utf8(msg).unwrap());
115 Timer::after_secs(1).await;
116 }
117 }
118}
119
120async fn wait_for_config(stack: Stack<'static>) -> embassy_net::StaticConfigV4 {
121 loop {
122 if let Some(config) = stack.config_v4() {
123 return config.clone();
124 }
125 yield_now().await;
126 }
127}
diff --git a/examples/rp235x/src/bin/ethernet_w5500_tcp_server.rs b/examples/rp235x/src/bin/ethernet_w5500_tcp_server.rs
new file mode 100644
index 000000000..ba812f4fd
--- /dev/null
+++ b/examples/rp235x/src/bin/ethernet_w5500_tcp_server.rs
@@ -0,0 +1,136 @@
1//! This example implements a TCP echo server on port 1234 and using DHCP.
2//! Send it some data, you should see it echoed back and printed in the console.
3//!
4//! Example written for the [`WIZnet W5500-EVB-Pico2`](https://docs.wiznet.io/Product/iEthernet/W5500/w5500-evb-pico2) board.
5
6#![no_std]
7#![no_main]
8
9use defmt::*;
10use embassy_executor::Spawner;
11use embassy_futures::yield_now;
12use embassy_net::{Stack, StackResources};
13use embassy_net_wiznet::chip::W5500;
14use embassy_net_wiznet::*;
15use embassy_rp::clocks::RoscRng;
16use embassy_rp::gpio::{Input, Level, Output, Pull};
17use embassy_rp::peripherals::SPI0;
18use embassy_rp::spi::{Async, Config as SpiConfig, Spi};
19use embassy_time::{Delay, Duration};
20use embedded_hal_bus::spi::ExclusiveDevice;
21use embedded_io_async::Write;
22use static_cell::StaticCell;
23use {defmt_rtt as _, panic_probe as _};
24
25#[embassy_executor::task]
26async fn ethernet_task(
27 runner: Runner<
28 'static,
29 W5500,
30 ExclusiveDevice<Spi<'static, SPI0, Async>, Output<'static>, Delay>,
31 Input<'static>,
32 Output<'static>,
33 >,
34) -> ! {
35 runner.run().await
36}
37
38#[embassy_executor::task]
39async fn net_task(mut runner: embassy_net::Runner<'static, Device<'static>>) -> ! {
40 runner.run().await
41}
42
43#[embassy_executor::main]
44async fn main(spawner: Spawner) {
45 let p = embassy_rp::init(Default::default());
46 let mut rng = RoscRng;
47 let mut led = Output::new(p.PIN_25, Level::Low);
48
49 let mut spi_cfg = SpiConfig::default();
50 spi_cfg.frequency = 50_000_000;
51 let (miso, mosi, clk) = (p.PIN_16, p.PIN_19, p.PIN_18);
52 let spi = Spi::new(p.SPI0, clk, mosi, miso, p.DMA_CH0, p.DMA_CH1, spi_cfg);
53 let cs = Output::new(p.PIN_17, Level::High);
54 let w5500_int = Input::new(p.PIN_21, Pull::Up);
55 let w5500_reset = Output::new(p.PIN_20, Level::High);
56
57 let mac_addr = [0x02, 0x00, 0x00, 0x00, 0x00, 0x00];
58 static STATE: StaticCell<State<8, 8>> = StaticCell::new();
59 let state = STATE.init(State::<8, 8>::new());
60 let (device, runner) = embassy_net_wiznet::new(
61 mac_addr,
62 state,
63 ExclusiveDevice::new(spi, cs, Delay),
64 w5500_int,
65 w5500_reset,
66 )
67 .await
68 .unwrap();
69 spawner.spawn(unwrap!(ethernet_task(runner)));
70
71 // Generate random seed
72 let seed = rng.next_u64();
73
74 // Init network stack
75 static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new();
76 let (stack, runner) = embassy_net::new(
77 device,
78 embassy_net::Config::dhcpv4(Default::default()),
79 RESOURCES.init(StackResources::new()),
80 seed,
81 );
82
83 // Launch network task
84 spawner.spawn(unwrap!(net_task(runner)));
85
86 info!("Waiting for DHCP...");
87 let cfg = wait_for_config(stack).await;
88 let local_addr = cfg.address.address();
89 info!("IP address: {:?}", local_addr);
90
91 let mut rx_buffer = [0; 4096];
92 let mut tx_buffer = [0; 4096];
93 let mut buf = [0; 4096];
94 loop {
95 let mut socket = embassy_net::tcp::TcpSocket::new(stack, &mut rx_buffer, &mut tx_buffer);
96 socket.set_timeout(Some(Duration::from_secs(10)));
97
98 led.set_low();
99 info!("Listening on TCP:1234...");
100 if let Err(e) = socket.accept(1234).await {
101 warn!("accept error: {:?}", e);
102 continue;
103 }
104 info!("Received connection from {:?}", socket.remote_endpoint());
105 led.set_high();
106
107 loop {
108 let n = match socket.read(&mut buf).await {
109 Ok(0) => {
110 warn!("read EOF");
111 break;
112 }
113 Ok(n) => n,
114 Err(e) => {
115 warn!("{:?}", e);
116 break;
117 }
118 };
119 info!("rxd {}", core::str::from_utf8(&buf[..n]).unwrap());
120
121 if let Err(e) = socket.write_all(&buf[..n]).await {
122 warn!("write error: {:?}", e);
123 break;
124 }
125 }
126 }
127}
128
129async fn wait_for_config(stack: Stack<'static>) -> embassy_net::StaticConfigV4 {
130 loop {
131 if let Some(config) = stack.config_v4() {
132 return config.clone();
133 }
134 yield_now().await;
135 }
136}
diff --git a/examples/rp235x/src/bin/ethernet_w5500_udp.rs b/examples/rp235x/src/bin/ethernet_w5500_udp.rs
new file mode 100644
index 000000000..ae74ad518
--- /dev/null
+++ b/examples/rp235x/src/bin/ethernet_w5500_udp.rs
@@ -0,0 +1,116 @@
1//! This example implements a UDP server listening on port 1234 and echoing back the data.
2//!
3//! Example written for the [`WIZnet W5500-EVB-Pico2`](https://docs.wiznet.io/Product/iEthernet/W5500/w5500-evb-pico2) board.
4
5#![no_std]
6#![no_main]
7
8use defmt::*;
9use embassy_executor::Spawner;
10use embassy_futures::yield_now;
11use embassy_net::udp::{PacketMetadata, UdpSocket};
12use embassy_net::{Stack, StackResources};
13use embassy_net_wiznet::chip::W5500;
14use embassy_net_wiznet::*;
15use embassy_rp::clocks::RoscRng;
16use embassy_rp::gpio::{Input, Level, Output, Pull};
17use embassy_rp::peripherals::SPI0;
18use embassy_rp::spi::{Async, Config as SpiConfig, Spi};
19use embassy_time::Delay;
20use embedded_hal_bus::spi::ExclusiveDevice;
21use static_cell::StaticCell;
22use {defmt_rtt as _, panic_probe as _};
23
24#[embassy_executor::task]
25async fn ethernet_task(
26 runner: Runner<
27 'static,
28 W5500,
29 ExclusiveDevice<Spi<'static, SPI0, Async>, Output<'static>, Delay>,
30 Input<'static>,
31 Output<'static>,
32 >,
33) -> ! {
34 runner.run().await
35}
36
37#[embassy_executor::task]
38async fn net_task(mut runner: embassy_net::Runner<'static, Device<'static>>) -> ! {
39 runner.run().await
40}
41
42#[embassy_executor::main]
43async fn main(spawner: Spawner) {
44 let p = embassy_rp::init(Default::default());
45 let mut rng = RoscRng;
46
47 let mut spi_cfg = SpiConfig::default();
48 spi_cfg.frequency = 50_000_000;
49 let (miso, mosi, clk) = (p.PIN_16, p.PIN_19, p.PIN_18);
50 let spi = Spi::new(p.SPI0, clk, mosi, miso, p.DMA_CH0, p.DMA_CH1, spi_cfg);
51 let cs = Output::new(p.PIN_17, Level::High);
52 let w5500_int = Input::new(p.PIN_21, Pull::Up);
53 let w5500_reset = Output::new(p.PIN_20, Level::High);
54
55 let mac_addr = [0x02, 0x00, 0x00, 0x00, 0x00, 0x00];
56 static STATE: StaticCell<State<8, 8>> = StaticCell::new();
57 let state = STATE.init(State::<8, 8>::new());
58 let (device, runner) = embassy_net_wiznet::new(
59 mac_addr,
60 state,
61 ExclusiveDevice::new(spi, cs, Delay),
62 w5500_int,
63 w5500_reset,
64 )
65 .await
66 .unwrap();
67 spawner.spawn(unwrap!(ethernet_task(runner)));
68
69 // Generate random seed
70 let seed = rng.next_u64();
71
72 // Init network stack
73 static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new();
74 let (stack, runner) = embassy_net::new(
75 device,
76 embassy_net::Config::dhcpv4(Default::default()),
77 RESOURCES.init(StackResources::new()),
78 seed,
79 );
80
81 // Launch network task
82 spawner.spawn(unwrap!(net_task(runner)));
83
84 info!("Waiting for DHCP...");
85 let cfg = wait_for_config(stack).await;
86 let local_addr = cfg.address.address();
87 info!("IP address: {:?}", local_addr);
88
89 // Then we can use it!
90 let mut rx_buffer = [0; 4096];
91 let mut tx_buffer = [0; 4096];
92 let mut rx_meta = [PacketMetadata::EMPTY; 16];
93 let mut tx_meta = [PacketMetadata::EMPTY; 16];
94 let mut buf = [0; 4096];
95 loop {
96 let mut socket = UdpSocket::new(stack, &mut rx_meta, &mut rx_buffer, &mut tx_meta, &mut tx_buffer);
97 socket.bind(1234).unwrap();
98
99 loop {
100 let (n, ep) = socket.recv_from(&mut buf).await.unwrap();
101 if let Ok(s) = core::str::from_utf8(&buf[..n]) {
102 info!("rxd from {}: {}", ep, s);
103 }
104 socket.send_to(&buf[..n], ep).await.unwrap();
105 }
106 }
107}
108
109async fn wait_for_config(stack: Stack<'static>) -> embassy_net::StaticConfigV4 {
110 loop {
111 if let Some(config) = stack.config_v4() {
112 return config.clone();
113 }
114 yield_now().await;
115 }
116}
diff --git a/examples/rp235x/src/bin/i2c_slave.rs b/examples/rp235x/src/bin/i2c_slave.rs
index 9fffb4646..02ad9a003 100644
--- a/examples/rp235x/src/bin/i2c_slave.rs
+++ b/examples/rp235x/src/bin/i2c_slave.rs
@@ -105,7 +105,7 @@ async fn main(spawner: Spawner) {
105 config.addr = DEV_ADDR as u16; 105 config.addr = DEV_ADDR as u16;
106 let device = i2c_slave::I2cSlave::new(p.I2C1, d_sda, d_scl, Irqs, config); 106 let device = i2c_slave::I2cSlave::new(p.I2C1, d_sda, d_scl, Irqs, config);
107 107
108 unwrap!(spawner.spawn(device_task(device))); 108 spawner.spawn(unwrap!(device_task(device)));
109 109
110 let c_sda = p.PIN_1; 110 let c_sda = p.PIN_1;
111 let c_scl = p.PIN_0; 111 let c_scl = p.PIN_0;
@@ -113,5 +113,5 @@ async fn main(spawner: Spawner) {
113 config.frequency = 1_000_000; 113 config.frequency = 1_000_000;
114 let controller = i2c::I2c::new_async(p.I2C0, c_sda, c_scl, Irqs, config); 114 let controller = i2c::I2c::new_async(p.I2C0, c_sda, c_scl, Irqs, config);
115 115
116 unwrap!(spawner.spawn(controller_task(controller))); 116 spawner.spawn(unwrap!(controller_task(controller)));
117} 117}
diff --git a/examples/rp235x/src/bin/interrupt.rs b/examples/rp235x/src/bin/interrupt.rs
index e9ac76486..88513180c 100644
--- a/examples/rp235x/src/bin/interrupt.rs
+++ b/examples/rp235x/src/bin/interrupt.rs
@@ -51,7 +51,7 @@ async fn main(spawner: Spawner) {
51 // No Mutex needed when sharing within the same executor/prio level 51 // No Mutex needed when sharing within the same executor/prio level
52 static AVG: StaticCell<Cell<u32>> = StaticCell::new(); 52 static AVG: StaticCell<Cell<u32>> = StaticCell::new();
53 let avg = AVG.init(Default::default()); 53 let avg = AVG.init(Default::default());
54 spawner.must_spawn(processing(avg)); 54 spawner.spawn(processing(avg).unwrap());
55 55
56 let mut ticker = Ticker::every(Duration::from_secs(1)); 56 let mut ticker = Ticker::every(Duration::from_secs(1));
57 loop { 57 loop {
diff --git a/examples/rp235x/src/bin/multicore.rs b/examples/rp235x/src/bin/multicore.rs
index f02dc3876..4f82801d6 100644
--- a/examples/rp235x/src/bin/multicore.rs
+++ b/examples/rp235x/src/bin/multicore.rs
@@ -35,12 +35,12 @@ fn main() -> ! {
35 unsafe { &mut *core::ptr::addr_of_mut!(CORE1_STACK) }, 35 unsafe { &mut *core::ptr::addr_of_mut!(CORE1_STACK) },
36 move || { 36 move || {
37 let executor1 = EXECUTOR1.init(Executor::new()); 37 let executor1 = EXECUTOR1.init(Executor::new());
38 executor1.run(|spawner| unwrap!(spawner.spawn(core1_task(led)))); 38 executor1.run(|spawner| spawner.spawn(unwrap!(core1_task(led))));
39 }, 39 },
40 ); 40 );
41 41
42 let executor0 = EXECUTOR0.init(Executor::new()); 42 let executor0 = EXECUTOR0.init(Executor::new());
43 executor0.run(|spawner| unwrap!(spawner.spawn(core0_task()))); 43 executor0.run(|spawner| spawner.spawn(unwrap!(core0_task())));
44} 44}
45 45
46#[embassy_executor::task] 46#[embassy_executor::task]
diff --git a/examples/rp235x/src/bin/multiprio.rs b/examples/rp235x/src/bin/multiprio.rs
index 2b397f97d..96cdf8fb1 100644
--- a/examples/rp235x/src/bin/multiprio.rs
+++ b/examples/rp235x/src/bin/multiprio.rs
@@ -130,16 +130,16 @@ fn main() -> ! {
130 // High-priority executor: SWI_IRQ_1, priority level 2 130 // High-priority executor: SWI_IRQ_1, priority level 2
131 interrupt::SWI_IRQ_1.set_priority(Priority::P2); 131 interrupt::SWI_IRQ_1.set_priority(Priority::P2);
132 let spawner = EXECUTOR_HIGH.start(interrupt::SWI_IRQ_1); 132 let spawner = EXECUTOR_HIGH.start(interrupt::SWI_IRQ_1);
133 unwrap!(spawner.spawn(run_high())); 133 spawner.spawn(unwrap!(run_high()));
134 134
135 // Medium-priority executor: SWI_IRQ_0, priority level 3 135 // Medium-priority executor: SWI_IRQ_0, priority level 3
136 interrupt::SWI_IRQ_0.set_priority(Priority::P3); 136 interrupt::SWI_IRQ_0.set_priority(Priority::P3);
137 let spawner = EXECUTOR_MED.start(interrupt::SWI_IRQ_0); 137 let spawner = EXECUTOR_MED.start(interrupt::SWI_IRQ_0);
138 unwrap!(spawner.spawn(run_med())); 138 spawner.spawn(unwrap!(run_med()));
139 139
140 // Low priority executor: runs in thread mode, using WFE/SEV 140 // Low priority executor: runs in thread mode, using WFE/SEV
141 let executor = EXECUTOR_LOW.init(Executor::new()); 141 let executor = EXECUTOR_LOW.init(Executor::new());
142 executor.run(|spawner| { 142 executor.run(|spawner| {
143 unwrap!(spawner.spawn(run_low())); 143 spawner.spawn(unwrap!(run_low()));
144 }); 144 });
145} 145}
diff --git a/examples/rp235x/src/bin/overclock.rs b/examples/rp235x/src/bin/overclock.rs
new file mode 100644
index 000000000..5fd97ef97
--- /dev/null
+++ b/examples/rp235x/src/bin/overclock.rs
@@ -0,0 +1,74 @@
1//! # Overclocking the RP2350 to 200 MHz
2//!
3//! This example demonstrates how to configure the RP2350 to run at 200 MHz instead of the default 150 MHz.
4//!
5//! ## Note
6//!
7//! As of yet there is no official support for running the RP235x at higher clock frequencies and/or other core voltages than the default.
8//! Doing so may cause unexpected behavior and/or damage the chip.
9
10#![no_std]
11#![no_main]
12
13use defmt::*;
14use embassy_executor::Spawner;
15use embassy_rp::clocks::{clk_sys_freq, core_voltage, ClockConfig, CoreVoltage};
16use embassy_rp::config::Config;
17use embassy_rp::gpio::{Level, Output};
18use embassy_time::{Duration, Instant, Timer};
19use {defmt_rtt as _, panic_probe as _};
20
21const COUNT_TO: i64 = 10_000_000;
22
23#[embassy_executor::main]
24async fn main(_spawner: Spawner) -> ! {
25 // Set up for clock frequency of 200 MHz, setting all necessary defaults.
26 let mut config = Config::new(ClockConfig::system_freq(200_000_000).unwrap());
27
28 // since for the rp235x there is no official support for higher clock frequencies, `system_freq()` will not set a voltage for us.
29 // We need to guess the core voltage, that is needed for the higher clock frequency. Going with a small increase from the default 1.1V here, based on
30 // what we know about the RP2040. This is not guaranteed to be correct.
31 config.clocks.core_voltage = CoreVoltage::V1_15;
32
33 // Initialize the peripherals
34 let p = embassy_rp::init(config);
35
36 // Show CPU frequency for verification
37 let sys_freq = clk_sys_freq();
38 info!("System clock frequency: {} MHz", sys_freq / 1_000_000);
39 // Show core voltage for verification
40 let core_voltage = core_voltage().unwrap();
41 info!("Core voltage: {}", core_voltage);
42
43 // LED to indicate the system is running
44 let mut led = Output::new(p.PIN_25, Level::Low);
45
46 loop {
47 // Reset the counter at the start of measurement period
48 let mut counter = 0;
49
50 // Turn LED on while counting
51 led.set_high();
52
53 let start = Instant::now();
54
55 // This is a busy loop that will take some time to complete
56 while counter < COUNT_TO {
57 counter += 1;
58 }
59
60 let elapsed = Instant::now() - start;
61
62 // Report the elapsed time
63 led.set_low();
64 info!(
65 "At {}Mhz: Elapsed time to count to {}: {}ms",
66 sys_freq / 1_000_000,
67 counter,
68 elapsed.as_millis()
69 );
70
71 // Wait 2 seconds before starting the next measurement
72 Timer::after(Duration::from_secs(2)).await;
73 }
74}
diff --git a/examples/rp235x/src/bin/pio_async.rs b/examples/rp235x/src/bin/pio_async.rs
index a519b8a50..d76930f5c 100644
--- a/examples/rp235x/src/bin/pio_async.rs
+++ b/examples/rp235x/src/bin/pio_async.rs
@@ -125,7 +125,7 @@ async fn main(spawner: Spawner) {
125 setup_pio_task_sm0(&mut common, &mut sm0, p.PIN_0); 125 setup_pio_task_sm0(&mut common, &mut sm0, p.PIN_0);
126 setup_pio_task_sm1(&mut common, &mut sm1); 126 setup_pio_task_sm1(&mut common, &mut sm1);
127 setup_pio_task_sm2(&mut common, &mut sm2); 127 setup_pio_task_sm2(&mut common, &mut sm2);
128 spawner.spawn(pio_task_sm0(sm0)).unwrap(); 128 spawner.spawn(pio_task_sm0(sm0).unwrap());
129 spawner.spawn(pio_task_sm1(sm1)).unwrap(); 129 spawner.spawn(pio_task_sm1(sm1).unwrap());
130 spawner.spawn(pio_task_sm2(irq3, sm2)).unwrap(); 130 spawner.spawn(pio_task_sm2(irq3, sm2).unwrap());
131} 131}
diff --git a/examples/rp235x/src/bin/pio_i2s.rs b/examples/rp235x/src/bin/pio_i2s.rs
index 5a4bcfcac..cfcb0221d 100644
--- a/examples/rp235x/src/bin/pio_i2s.rs
+++ b/examples/rp235x/src/bin/pio_i2s.rs
@@ -27,7 +27,6 @@ bind_interrupts!(struct Irqs {
27 27
28const SAMPLE_RATE: u32 = 48_000; 28const SAMPLE_RATE: u32 = 48_000;
29const BIT_DEPTH: u32 = 16; 29const BIT_DEPTH: u32 = 16;
30const CHANNELS: u32 = 2;
31 30
32#[embassy_executor::main] 31#[embassy_executor::main]
33async fn main(_spawner: Spawner) { 32async fn main(_spawner: Spawner) {
@@ -50,7 +49,6 @@ async fn main(_spawner: Spawner) {
50 left_right_clock_pin, 49 left_right_clock_pin,
51 SAMPLE_RATE, 50 SAMPLE_RATE,
52 BIT_DEPTH, 51 BIT_DEPTH,
53 CHANNELS,
54 &program, 52 &program,
55 ); 53 );
56 54
diff --git a/examples/rp235x/src/bin/pio_i2s_rx.rs b/examples/rp235x/src/bin/pio_i2s_rx.rs
new file mode 100644
index 000000000..c3f505b13
--- /dev/null
+++ b/examples/rp235x/src/bin/pio_i2s_rx.rs
@@ -0,0 +1,81 @@
1//! This example shows receiving audio from a connected I2S microphone (or other audio source)
2//! using the PIO module of the RP235x.
3//!
4//!
5//! Connect the i2s microphone as follows:
6//! bclk : GPIO 18
7//! lrc : GPIO 19
8//! din : GPIO 20
9//! Then hold down the boot select button to begin receiving audio. Received I2S words will be written to
10//! buffers for the left and right channels for use in your application, whether that's storage or
11//! further processing
12//!
13//! Note the const USE_ONBOARD_PULLDOWN is by default set to false, meaning an external
14//! pull-down resistor is being used on the data pin if required by the mic being used.
15
16#![no_std]
17#![no_main]
18use core::mem;
19
20use defmt::*;
21use embassy_executor::Spawner;
22use embassy_rp::bind_interrupts;
23use embassy_rp::peripherals::PIO0;
24use embassy_rp::pio::{InterruptHandler, Pio};
25use embassy_rp::pio_programs::i2s::{PioI2sIn, PioI2sInProgram};
26use static_cell::StaticCell;
27use {defmt_rtt as _, panic_probe as _};
28
29bind_interrupts!(struct Irqs {
30 PIO0_IRQ_0 => InterruptHandler<PIO0>;
31});
32
33const SAMPLE_RATE: u32 = 48_000;
34const BIT_DEPTH: u32 = 16;
35const CHANNELS: u32 = 2;
36const USE_ONBOARD_PULLDOWN: bool = false; // whether or not to use the onboard pull-down resistor,
37 // which has documented issues on many RP235x boards
38#[embassy_executor::main]
39async fn main(_spawner: Spawner) {
40 let p = embassy_rp::init(Default::default());
41
42 // Setup pio state machine for i2s input
43 let Pio { mut common, sm0, .. } = Pio::new(p.PIO0, Irqs);
44
45 let bit_clock_pin = p.PIN_18;
46 let left_right_clock_pin = p.PIN_19;
47 let data_pin = p.PIN_20;
48
49 let program = PioI2sInProgram::new(&mut common);
50 let mut i2s = PioI2sIn::new(
51 &mut common,
52 sm0,
53 p.DMA_CH0,
54 USE_ONBOARD_PULLDOWN,
55 data_pin,
56 bit_clock_pin,
57 left_right_clock_pin,
58 SAMPLE_RATE,
59 BIT_DEPTH,
60 CHANNELS,
61 &program,
62 );
63
64 // create two audio buffers (back and front) which will take turns being
65 // filled with new audio data from the PIO fifo using DMA
66 const BUFFER_SIZE: usize = 960;
67 static DMA_BUFFER: StaticCell<[u32; BUFFER_SIZE * 2]> = StaticCell::new();
68 let dma_buffer = DMA_BUFFER.init_with(|| [0u32; BUFFER_SIZE * 2]);
69 let (mut back_buffer, mut front_buffer) = dma_buffer.split_at_mut(BUFFER_SIZE);
70
71 loop {
72 // trigger transfer of front buffer data to the pio fifo
73 // but don't await the returned future, yet
74 let dma_future = i2s.read(front_buffer);
75 // now await the dma future. once the dma finishes, the next buffer needs to be queued
76 // within DMA_DEPTH / SAMPLE_RATE = 8 / 48000 seconds = 166us
77 dma_future.await;
78 info!("Received I2S data word: {:?}", &front_buffer);
79 mem::swap(&mut back_buffer, &mut front_buffer);
80 }
81}
diff --git a/examples/rp235x/src/bin/pio_onewire.rs b/examples/rp235x/src/bin/pio_onewire.rs
index 991510851..102f13c45 100644
--- a/examples/rp235x/src/bin/pio_onewire.rs
+++ b/examples/rp235x/src/bin/pio_onewire.rs
@@ -1,4 +1,5 @@
1//! This example shows how you can use PIO to read a `DS18B20` one-wire temperature sensor. 1//! This example shows how you can use PIO to read one or more `DS18B20` one-wire temperature sensors.
2//! This uses externally powered sensors. For parasite power, see the pio_onewire_parasite.rs example.
2 3
3#![no_std] 4#![no_std]
4#![no_main] 5#![no_main]
@@ -6,9 +7,10 @@ use defmt::*;
6use embassy_executor::Spawner; 7use embassy_executor::Spawner;
7use embassy_rp::bind_interrupts; 8use embassy_rp::bind_interrupts;
8use embassy_rp::peripherals::PIO0; 9use embassy_rp::peripherals::PIO0;
9use embassy_rp::pio::{self, InterruptHandler, Pio}; 10use embassy_rp::pio::{InterruptHandler, Pio};
10use embassy_rp::pio_programs::onewire::{PioOneWire, PioOneWireProgram}; 11use embassy_rp::pio_programs::onewire::{PioOneWire, PioOneWireProgram, PioOneWireSearch};
11use embassy_time::Timer; 12use embassy_time::Timer;
13use heapless::Vec;
12use {defmt_rtt as _, panic_probe as _}; 14use {defmt_rtt as _, panic_probe as _};
13 15
14bind_interrupts!(struct Irqs { 16bind_interrupts!(struct Irqs {
@@ -21,63 +23,66 @@ async fn main(_spawner: Spawner) {
21 let mut pio = Pio::new(p.PIO0, Irqs); 23 let mut pio = Pio::new(p.PIO0, Irqs);
22 24
23 let prg = PioOneWireProgram::new(&mut pio.common); 25 let prg = PioOneWireProgram::new(&mut pio.common);
24 let onewire = PioOneWire::new(&mut pio.common, pio.sm0, p.PIN_2, &prg); 26 let mut onewire = PioOneWire::new(&mut pio.common, pio.sm0, p.PIN_2, &prg);
25 27
26 let mut sensor = Ds18b20::new(onewire); 28 info!("Starting onewire search");
27 29
28 loop { 30 let mut devices = Vec::<u64, 10>::new();
29 sensor.start().await; // Start a new measurement 31 let mut search = PioOneWireSearch::new();
30 Timer::after_secs(1).await; // Allow 1s for the measurement to finish 32 for _ in 0..10 {
31 match sensor.temperature().await { 33 if !search.is_finished() {
32 Ok(temp) => info!("temp = {:?} deg C", temp), 34 if let Some(address) = search.next(&mut onewire).await {
33 _ => error!("sensor error"), 35 if crc8(&address.to_le_bytes()) == 0 {
36 info!("Found addres: {:x}", address);
37 let _ = devices.push(address);
38 } else {
39 warn!("Found invalid address: {:x}", address);
40 }
41 }
34 } 42 }
35 Timer::after_secs(1).await;
36 } 43 }
37}
38 44
39/// DS18B20 temperature sensor driver 45 info!("Search done, found {} devices", devices.len());
40pub struct Ds18b20<'d, PIO: pio::Instance, const SM: usize> {
41 wire: PioOneWire<'d, PIO, SM>,
42}
43 46
44impl<'d, PIO: pio::Instance, const SM: usize> Ds18b20<'d, PIO, SM> { 47 loop {
45 pub fn new(wire: PioOneWire<'d, PIO, SM>) -> Self { 48 onewire.reset().await;
46 Self { wire } 49 // Skip rom and trigger conversion, we can trigger all devices on the bus immediately
47 } 50 onewire.write_bytes(&[0xCC, 0x44]).await;
48 51
49 /// Calculate CRC8 of the data 52 Timer::after_secs(1).await; // Allow 1s for the measurement to finish
50 fn crc8(data: &[u8]) -> u8 { 53
51 let mut temp; 54 // Read all devices one by one
52 let mut data_byte; 55 for device in &devices {
53 let mut crc = 0; 56 onewire.reset().await;
54 for b in data { 57 onewire.write_bytes(&[0x55]).await; // Match rom
55 data_byte = *b; 58 onewire.write_bytes(&device.to_le_bytes()).await;
56 for _ in 0..8 { 59 onewire.write_bytes(&[0xBE]).await; // Read scratchpad
57 temp = (crc ^ data_byte) & 0x01; 60
58 crc >>= 1; 61 let mut data = [0; 9];
59 if temp != 0 { 62 onewire.read_bytes(&mut data).await;
60 crc ^= 0x8C; 63 if crc8(&data) == 0 {
61 } 64 let temp = ((data[1] as u32) << 8 | data[0] as u32) as f32 / 16.;
62 data_byte >>= 1; 65 info!("Read device {:x}: {} deg C", device, temp);
66 } else {
67 warn!("Reading device {:x} failed", device);
63 } 68 }
64 } 69 }
65 crc 70 Timer::after_secs(1).await;
66 }
67
68 /// Start a new measurement. Allow at least 1000ms before getting `temperature`.
69 pub async fn start(&mut self) {
70 self.wire.write_bytes(&[0xCC, 0x44]).await;
71 } 71 }
72}
72 73
73 /// Read the temperature. Ensure >1000ms has passed since `start` before calling this. 74fn crc8(data: &[u8]) -> u8 {
74 pub async fn temperature(&mut self) -> Result<f32, ()> { 75 let mut crc = 0;
75 self.wire.write_bytes(&[0xCC, 0xBE]).await; 76 for b in data {
76 let mut data = [0; 9]; 77 let mut data_byte = *b;
77 self.wire.read_bytes(&mut data).await; 78 for _ in 0..8 {
78 match Self::crc8(&data) == 0 { 79 let temp = (crc ^ data_byte) & 0x01;
79 true => Ok(((data[1] as u32) << 8 | data[0] as u32) as f32 / 16.), 80 crc >>= 1;
80 false => Err(()), 81 if temp != 0 {
82 crc ^= 0x8C;
83 }
84 data_byte >>= 1;
81 } 85 }
82 } 86 }
87 crc
83} 88}
diff --git a/examples/rp235x/src/bin/pio_onewire_parasite.rs b/examples/rp235x/src/bin/pio_onewire_parasite.rs
new file mode 100644
index 000000000..fd076dee0
--- /dev/null
+++ b/examples/rp235x/src/bin/pio_onewire_parasite.rs
@@ -0,0 +1,89 @@
1//! This example shows how you can use PIO to read one or more `DS18B20`
2//! one-wire temperature sensors using parasite power.
3//! It applies a strong pullup during conversion, see "Powering the DS18B20" in the datasheet.
4//! For externally powered sensors, use the pio_onewire.rs example.
5
6#![no_std]
7#![no_main]
8use defmt::*;
9use embassy_executor::Spawner;
10use embassy_rp::bind_interrupts;
11use embassy_rp::peripherals::PIO0;
12use embassy_rp::pio::{InterruptHandler, Pio};
13use embassy_rp::pio_programs::onewire::{PioOneWire, PioOneWireProgram, PioOneWireSearch};
14use embassy_time::Duration;
15use heapless::Vec;
16use {defmt_rtt as _, panic_probe as _};
17
18bind_interrupts!(struct Irqs {
19 PIO0_IRQ_0 => InterruptHandler<PIO0>;
20});
21
22#[embassy_executor::main]
23async fn main(_spawner: Spawner) {
24 let p = embassy_rp::init(Default::default());
25 let mut pio = Pio::new(p.PIO0, Irqs);
26
27 let prg = PioOneWireProgram::new(&mut pio.common);
28 let mut onewire = PioOneWire::new(&mut pio.common, pio.sm0, p.PIN_2, &prg);
29
30 info!("Starting onewire search");
31
32 let mut devices = Vec::<u64, 10>::new();
33 let mut search = PioOneWireSearch::new();
34 for _ in 0..10 {
35 if !search.is_finished() {
36 if let Some(address) = search.next(&mut onewire).await {
37 if crc8(&address.to_le_bytes()) == 0 {
38 info!("Found address: {:x}", address);
39 let _ = devices.push(address);
40 } else {
41 warn!("Found invalid address: {:x}", address);
42 }
43 }
44 }
45 }
46
47 info!("Search done, found {} devices", devices.len());
48
49 loop {
50 // Read all devices one by one
51 for device in &devices {
52 onewire.reset().await;
53 onewire.write_bytes(&[0x55]).await; // Match rom
54 onewire.write_bytes(&device.to_le_bytes()).await;
55 // 750 ms delay required for default 12-bit resolution.
56 onewire.write_bytes_pullup(&[0x44], Duration::from_millis(750)).await;
57
58 onewire.reset().await;
59 onewire.write_bytes(&[0x55]).await; // Match rom
60 onewire.write_bytes(&device.to_le_bytes()).await;
61 onewire.write_bytes(&[0xBE]).await; // Read scratchpad
62
63 let mut data = [0; 9];
64 onewire.read_bytes(&mut data).await;
65 if crc8(&data) == 0 {
66 let temp = ((data[1] as u32) << 8 | data[0] as u32) as f32 / 16.;
67 info!("Read device {:x}: {} deg C", device, temp);
68 } else {
69 warn!("Reading device {:x} failed. {:02x}", device, data);
70 }
71 }
72 }
73}
74
75fn crc8(data: &[u8]) -> u8 {
76 let mut crc = 0;
77 for b in data {
78 let mut data_byte = *b;
79 for _ in 0..8 {
80 let temp = (crc ^ data_byte) & 0x01;
81 crc >>= 1;
82 if temp != 0 {
83 crc ^= 0x8C;
84 }
85 data_byte >>= 1;
86 }
87 }
88 crc
89}
diff --git a/examples/rp235x/src/bin/pio_rotary_encoder.rs b/examples/rp235x/src/bin/pio_rotary_encoder.rs
index e820d316d..610d1a40b 100644
--- a/examples/rp235x/src/bin/pio_rotary_encoder.rs
+++ b/examples/rp235x/src/bin/pio_rotary_encoder.rs
@@ -50,6 +50,6 @@ async fn main(spawner: Spawner) {
50 let encoder0 = PioEncoder::new(&mut common, sm0, p.PIN_4, p.PIN_5, &prg); 50 let encoder0 = PioEncoder::new(&mut common, sm0, p.PIN_4, p.PIN_5, &prg);
51 let encoder1 = PioEncoder::new(&mut common, sm1, p.PIN_6, p.PIN_7, &prg); 51 let encoder1 = PioEncoder::new(&mut common, sm1, p.PIN_6, p.PIN_7, &prg);
52 52
53 spawner.must_spawn(encoder_0(encoder0)); 53 spawner.spawn(encoder_0(encoder0).unwrap());
54 spawner.must_spawn(encoder_1(encoder1)); 54 spawner.spawn(encoder_1(encoder1).unwrap());
55} 55}
diff --git a/examples/rp235x/src/bin/psram.rs b/examples/rp235x/src/bin/psram.rs
new file mode 100644
index 000000000..716ac7695
--- /dev/null
+++ b/examples/rp235x/src/bin/psram.rs
@@ -0,0 +1,49 @@
1//! This example tests an APS6404L PSRAM chip connected to the RP235x
2//! It fills the PSRAM with alternating patterns and reads back a value
3//!
4//! In this example, the PSRAM CS is connected to Pin 0.
5
6#![no_std]
7#![no_main]
8
9use core::slice;
10
11use defmt::*;
12use embassy_executor::Spawner;
13use embassy_time::Timer;
14use {defmt_rtt as _, panic_probe as _};
15
16#[embassy_executor::main]
17async fn main(_spawner: Spawner) {
18 let config = embassy_rp::config::Config::default();
19 let p = embassy_rp::init(config);
20 let psram_config = embassy_rp::psram::Config::aps6404l();
21 let psram = embassy_rp::psram::Psram::new(embassy_rp::qmi_cs1::QmiCs1::new(p.QMI_CS1, p.PIN_0), psram_config);
22
23 let Ok(psram) = psram else {
24 error!("PSRAM not found");
25 loop {
26 Timer::after_secs(1).await;
27 }
28 };
29
30 let psram_slice = unsafe {
31 let psram_ptr = psram.base_address();
32 let slice: &'static mut [u8] = slice::from_raw_parts_mut(psram_ptr, psram.size() as usize);
33 slice
34 };
35
36 loop {
37 psram_slice.fill(0x55);
38 info!("PSRAM filled with 0x55");
39 let at_addr = psram_slice[0x100];
40 info!("Read from PSRAM at address 0x100: 0x{:02x}", at_addr);
41 Timer::after_secs(1).await;
42
43 psram_slice.fill(0xAA);
44 info!("PSRAM filled with 0xAA");
45 let at_addr = psram_slice[0x100];
46 info!("Read from PSRAM at address 0x100: 0x{:02x}", at_addr);
47 Timer::after_secs(1).await;
48 }
49}
diff --git a/examples/rp235x/src/bin/pwm.rs b/examples/rp235x/src/bin/pwm.rs
index da1acc18a..289480c85 100644
--- a/examples/rp235x/src/bin/pwm.rs
+++ b/examples/rp235x/src/bin/pwm.rs
@@ -18,8 +18,8 @@ use {defmt_rtt as _, panic_probe as _};
18#[embassy_executor::main] 18#[embassy_executor::main]
19async fn main(spawner: Spawner) { 19async fn main(spawner: Spawner) {
20 let p = embassy_rp::init(Default::default()); 20 let p = embassy_rp::init(Default::default());
21 spawner.spawn(pwm_set_config(p.PWM_SLICE4, p.PIN_25)).unwrap(); 21 spawner.spawn(pwm_set_config(p.PWM_SLICE4, p.PIN_25).unwrap());
22 spawner.spawn(pwm_set_dutycycle(p.PWM_SLICE2, p.PIN_4)).unwrap(); 22 spawner.spawn(pwm_set_dutycycle(p.PWM_SLICE2, p.PIN_4).unwrap());
23} 23}
24 24
25/// Demonstrate PWM by modifying & applying the config 25/// Demonstrate PWM by modifying & applying the config
diff --git a/examples/rp235x/src/bin/shared_bus.rs b/examples/rp235x/src/bin/shared_bus.rs
index 9267dfccb..db7566b1a 100644
--- a/examples/rp235x/src/bin/shared_bus.rs
+++ b/examples/rp235x/src/bin/shared_bus.rs
@@ -35,8 +35,8 @@ async fn main(spawner: Spawner) {
35 static I2C_BUS: StaticCell<I2c1Bus> = StaticCell::new(); 35 static I2C_BUS: StaticCell<I2c1Bus> = StaticCell::new();
36 let i2c_bus = I2C_BUS.init(Mutex::new(i2c)); 36 let i2c_bus = I2C_BUS.init(Mutex::new(i2c));
37 37
38 spawner.must_spawn(i2c_task_a(i2c_bus)); 38 spawner.spawn(i2c_task_a(i2c_bus).unwrap());
39 spawner.must_spawn(i2c_task_b(i2c_bus)); 39 spawner.spawn(i2c_task_b(i2c_bus).unwrap());
40 40
41 // Shared SPI bus 41 // Shared SPI bus
42 let spi_cfg = spi::Config::default(); 42 let spi_cfg = spi::Config::default();
@@ -48,8 +48,8 @@ async fn main(spawner: Spawner) {
48 let cs_a = Output::new(p.PIN_0, Level::High); 48 let cs_a = Output::new(p.PIN_0, Level::High);
49 let cs_b = Output::new(p.PIN_1, Level::High); 49 let cs_b = Output::new(p.PIN_1, Level::High);
50 50
51 spawner.must_spawn(spi_task_a(spi_bus, cs_a)); 51 spawner.spawn(spi_task_a(spi_bus, cs_a).unwrap());
52 spawner.must_spawn(spi_task_b(spi_bus, cs_b)); 52 spawner.spawn(spi_task_b(spi_bus, cs_b).unwrap());
53} 53}
54 54
55#[embassy_executor::task] 55#[embassy_executor::task]
diff --git a/examples/rp235x/src/bin/sharing.rs b/examples/rp235x/src/bin/sharing.rs
index 497c4f845..d4c89946b 100644
--- a/examples/rp235x/src/bin/sharing.rs
+++ b/examples/rp235x/src/bin/sharing.rs
@@ -27,7 +27,6 @@ use embassy_rp::{bind_interrupts, interrupt};
27use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; 27use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
28use embassy_sync::{blocking_mutex, mutex}; 28use embassy_sync::{blocking_mutex, mutex};
29use embassy_time::{Duration, Ticker}; 29use embassy_time::{Duration, Ticker};
30use rand::RngCore;
31use static_cell::{ConstStaticCell, StaticCell}; 30use static_cell::{ConstStaticCell, StaticCell};
32use {defmt_rtt as _, panic_probe as _}; 31use {defmt_rtt as _, panic_probe as _};
33 32
@@ -69,7 +68,7 @@ fn main() -> ! {
69 // High-priority executor: runs in interrupt mode 68 // High-priority executor: runs in interrupt mode
70 interrupt::SWI_IRQ_0.set_priority(Priority::P3); 69 interrupt::SWI_IRQ_0.set_priority(Priority::P3);
71 let spawner = EXECUTOR_HI.start(interrupt::SWI_IRQ_0); 70 let spawner = EXECUTOR_HI.start(interrupt::SWI_IRQ_0);
72 spawner.must_spawn(task_a(uart)); 71 spawner.spawn(task_a(uart).unwrap());
73 72
74 // Low priority executor: runs in thread mode 73 // Low priority executor: runs in thread mode
75 let executor = EXECUTOR_LOW.init(Executor::new()); 74 let executor = EXECUTOR_LOW.init(Executor::new());
@@ -84,8 +83,8 @@ fn main() -> ! {
84 static REF_CELL: ConstStaticCell<RefCell<MyType>> = ConstStaticCell::new(RefCell::new(MyType { inner: 0 })); 83 static REF_CELL: ConstStaticCell<RefCell<MyType>> = ConstStaticCell::new(RefCell::new(MyType { inner: 0 }));
85 let ref_cell = REF_CELL.take(); 84 let ref_cell = REF_CELL.take();
86 85
87 spawner.must_spawn(task_b(uart, cell, ref_cell)); 86 spawner.spawn(task_b(uart, cell, ref_cell).unwrap());
88 spawner.must_spawn(task_c(cell, ref_cell)); 87 spawner.spawn(task_c(cell, ref_cell).unwrap());
89 }); 88 });
90} 89}
91 90
diff --git a/examples/rp235x/src/bin/trng.rs b/examples/rp235x/src/bin/trng.rs
index ad19aef3e..100d6b104 100644
--- a/examples/rp235x/src/bin/trng.rs
+++ b/examples/rp235x/src/bin/trng.rs
@@ -10,7 +10,6 @@ use embassy_rp::gpio::{Level, Output};
10use embassy_rp::peripherals::TRNG; 10use embassy_rp::peripherals::TRNG;
11use embassy_rp::trng::Trng; 11use embassy_rp::trng::Trng;
12use embassy_time::Timer; 12use embassy_time::Timer;
13use rand::RngCore;
14use {defmt_rtt as _, panic_probe as _}; 13use {defmt_rtt as _, panic_probe as _};
15 14
16bind_interrupts!(struct Irqs { 15bind_interrupts!(struct Irqs {
@@ -33,8 +32,8 @@ async fn main(_spawner: Spawner) {
33 info!("Random bytes async {}", &randomness); 32 info!("Random bytes async {}", &randomness);
34 trng.blocking_fill_bytes(&mut randomness); 33 trng.blocking_fill_bytes(&mut randomness);
35 info!("Random bytes blocking {}", &randomness); 34 info!("Random bytes blocking {}", &randomness);
36 let random_u32 = trng.next_u32(); 35 let random_u32 = trng.blocking_next_u32();
37 let random_u64 = trng.next_u64(); 36 let random_u64 = trng.blocking_next_u64();
38 info!("Random u32 {} u64 {}", random_u32, random_u64); 37 info!("Random u32 {} u64 {}", random_u32, random_u64);
39 // Random number of blinks between 0 and 31 38 // Random number of blinks between 0 and 31
40 let blinks = random_u32 % 32; 39 let blinks = random_u32 % 32;
diff --git a/examples/rp235x/src/bin/uart_buffered_split.rs b/examples/rp235x/src/bin/uart_buffered_split.rs
index 7cad09f9b..061be873d 100644
--- a/examples/rp235x/src/bin/uart_buffered_split.rs
+++ b/examples/rp235x/src/bin/uart_buffered_split.rs
@@ -33,7 +33,7 @@ async fn main(spawner: Spawner) {
33 let uart = BufferedUart::new(uart, tx_pin, rx_pin, Irqs, tx_buf, rx_buf, Config::default()); 33 let uart = BufferedUart::new(uart, tx_pin, rx_pin, Irqs, tx_buf, rx_buf, Config::default());
34 let (mut tx, rx) = uart.split(); 34 let (mut tx, rx) = uart.split();
35 35
36 unwrap!(spawner.spawn(reader(rx))); 36 spawner.spawn(unwrap!(reader(rx)));
37 37
38 info!("Writing..."); 38 info!("Writing...");
39 loop { 39 loop {
diff --git a/examples/rp235x/src/bin/uart_unidir.rs b/examples/rp235x/src/bin/uart_unidir.rs
index 45c9c8407..0c80d24c9 100644
--- a/examples/rp235x/src/bin/uart_unidir.rs
+++ b/examples/rp235x/src/bin/uart_unidir.rs
@@ -27,7 +27,7 @@ async fn main(spawner: Spawner) {
27 let mut uart_tx = UartTx::new(p.UART0, p.PIN_0, p.DMA_CH0, Config::default()); 27 let mut uart_tx = UartTx::new(p.UART0, p.PIN_0, p.DMA_CH0, Config::default());
28 let uart_rx = UartRx::new(p.UART1, p.PIN_5, Irqs, p.DMA_CH1, Config::default()); 28 let uart_rx = UartRx::new(p.UART1, p.PIN_5, Irqs, p.DMA_CH1, Config::default());
29 29
30 unwrap!(spawner.spawn(reader(uart_rx))); 30 spawner.spawn(unwrap!(reader(uart_rx)));
31 31
32 info!("Writing..."); 32 info!("Writing...");
33 loop { 33 loop {
diff --git a/examples/rp235x/src/bin/usb_webusb.rs b/examples/rp235x/src/bin/usb_webusb.rs
index 75d28c853..a68163b61 100644
--- a/examples/rp235x/src/bin/usb_webusb.rs
+++ b/examples/rp235x/src/bin/usb_webusb.rs
@@ -125,8 +125,8 @@ impl<'d, D: Driver<'d>> WebEndpoints<'d, D> {
125 let mut iface = func.interface(); 125 let mut iface = func.interface();
126 let mut alt = iface.alt_setting(0xff, 0x00, 0x00, None); 126 let mut alt = iface.alt_setting(0xff, 0x00, 0x00, None);
127 127
128 let write_ep = alt.endpoint_bulk_in(config.max_packet_size); 128 let write_ep = alt.endpoint_bulk_in(None, config.max_packet_size);
129 let read_ep = alt.endpoint_bulk_out(config.max_packet_size); 129 let read_ep = alt.endpoint_bulk_out(None, config.max_packet_size);
130 130
131 WebEndpoints { write_ep, read_ep } 131 WebEndpoints { write_ep, read_ep }
132 } 132 }
diff --git a/examples/rp235x/src/bin/zerocopy.rs b/examples/rp235x/src/bin/zerocopy.rs
index 086c86cac..62ba4cfb8 100644
--- a/examples/rp235x/src/bin/zerocopy.rs
+++ b/examples/rp235x/src/bin/zerocopy.rs
@@ -52,8 +52,8 @@ async fn main(spawner: Spawner) {
52 let channel = CHANNEL.init(Channel::new(buf)); 52 let channel = CHANNEL.init(Channel::new(buf));
53 let (sender, receiver) = channel.split(); 53 let (sender, receiver) = channel.split();
54 54
55 spawner.must_spawn(consumer(receiver)); 55 spawner.spawn(consumer(receiver).unwrap());
56 spawner.must_spawn(producer(sender, adc_parts)); 56 spawner.spawn(producer(sender, adc_parts).unwrap());
57 57
58 let mut ticker = Ticker::every(Duration::from_secs(1)); 58 let mut ticker = Ticker::every(Duration::from_secs(1));
59 loop { 59 loop {