diff --git a/examples/rp/Cargo.toml b/examples/rp/Cargo.toml
index 3c8f923e77d8f987c5da6264fde85e1ecda6aede..07aaa0ad2add94ca5504578b58655fb049287ab9 100644
--- a/examples/rp/Cargo.toml
+++ b/examples/rp/Cargo.toml
@@ -16,6 +16,9 @@ embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
 defmt = "0.3"
 defmt-rtt = "0.3"
 
+heapless = "0.7"
+critical-section = "1.1"
+
 cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] }
 cortex-m-rt = "0.7.0"
 panic-probe = { version = "0.3", features = ["print-defmt"] }
diff --git a/examples/rp/src/bin/usb_serial.rs b/examples/rp/src/bin/usb_serial.rs
index b7d6493b4ec72ab78075ddeb58be68695b26f264..714fb2ce97e471422d8f44b8748a6b1ae3770eca 100644
--- a/examples/rp/src/bin/usb_serial.rs
+++ b/examples/rp/src/bin/usb_serial.rs
@@ -4,20 +4,30 @@
 
 use defmt::{info, panic};
 use embassy_executor::Spawner;
+use embassy_time::{Timer, Duration};
+use embassy_rp::pac as pac;
 use embassy_futures::join::join;
 use embassy_rp::interrupt;
+use embassy_rp::gpio::{Flex, Pull, Pin};
 use embassy_rp::usb::{Driver, Instance};
 use embassy_usb::class::cdc_acm::{CdcAcmClass, State};
 use embassy_usb::driver::EndpointError;
 use embassy_usb::{Builder, Config};
 use {defmt_rtt as _, panic_probe as _};
 
+use cortex_m::peripheral::SYST;
+use core::fmt::Write;
+
+const MAX_CDC_PACKET: u8 = 64;
+
 #[embassy_executor::main]
 async fn main(_spawner: Spawner) {
     info!("Hello there!");
 
     let p = embassy_rp::init(Default::default());
 
+    let mut cp = cortex_m::peripheral::Peripherals::take().unwrap();
+
     // Create the driver, from the HAL.
     let irq = interrupt::take!(USBCTRL_IRQ);
     let driver = Driver::new(p.USB, irq);
@@ -28,7 +38,7 @@ async fn main(_spawner: Spawner) {
     config.product = Some("USB-serial example");
     config.serial_number = Some("12345678");
     config.max_power = 100;
-    config.max_packet_size_0 = 64;
+    config.max_packet_size_0 = MAX_CDC_PACKET;
 
     // Required for windows compatiblity.
     // https://developer.nordicsemi.com/nRF_Connect_SDK/doc/1.9.1/kconfig/CONFIG_CDC_ACM_IAD.html#help
@@ -57,20 +67,23 @@ async fn main(_spawner: Spawner) {
     );
 
     // Create classes on the builder.
-    let mut class = CdcAcmClass::new(&mut builder, &mut state, 64);
+    let mut class = CdcAcmClass::new(&mut builder, &mut state, MAX_CDC_PACKET as u16);
 
     // Build the builder.
     let mut usb = builder.build();
 
     // Run the USB device.
     let usb_fut = usb.run();
+    let _ = class.write_packet(b"top\r\n").await;
+
+    let mut gpio6 = Flex::new(p.PIN_6);
 
     // Do stuff with the class!
     let echo_fut = async {
         loop {
             class.wait_connection().await;
             info!("Connected");
-            let _ = echo(&mut class).await;
+            let _ = echo(&mut class, &mut gpio6, &mut cp.SYST).await;
             info!("Disconnected");
         }
     };
@@ -91,12 +104,63 @@ impl From<EndpointError> for Disconnected {
     }
 }
 
-async fn echo<'d, T: Instance + 'd>(class: &mut CdcAcmClass<'d, Driver<'d, T>>) -> Result<(), Disconnected> {
-    let mut buf = [0; 64];
+#[derive(Default)]
+struct FmtBuf {
+    s: heapless::String<1024>,
+}
+
+impl FmtBuf {
+    fn str(&self) -> &str {
+        self.s.as_str()
+    }
+    async fn write<'d, T: Instance+'d>(cdc: &mut CdcAcmClass<'d, Driver<'d, T>>, args: core::fmt::Arguments<'_>) -> Result<(), core::fmt::Error> {
+        let mut f = Self::default();
+        f.write_fmt(args)?;
+
+        let b = f.str().as_bytes();
+        for c in b.chunks(MAX_CDC_PACKET as usize) {
+            cdc.write_packet(c).await.map_err(|_| core::fmt::Error)?
+        }
+        Ok(())
+    }
+}
+
+impl core::fmt::Write for FmtBuf {
+    fn write_str(&mut self, s: &str) -> Result<(), core::fmt::Error> {
+        self.s.push_str(s).map_err(|_| core::fmt::Error)
+    }
+}
+
+async fn echo<'d, P: Pin, T: Instance + 'd>(class: &mut CdcAcmClass<'d, Driver<'d, T>>,
+    pin: &mut Flex<'d, P>, syst: &mut SYST) -> Result<(), Disconnected> {
+    class.write_packet(b"hello\r\n").await?;
+
+    syst.set_reload(10_000_000-1);
+    syst.clear_current();
+    syst.set_clock_source(cortex_m::peripheral::syst::SystClkSource::Core);
+    syst.enable_counter();
+
+    unsafe{ pac::ROSC.ctrl().modify(|s| s.set_enable(pac::rosc::vals::Enable::DISABLE))};
+
     loop {
-        let n = class.read_packet(&mut buf).await?;
-        let data = &buf[..n];
-        info!("data: {:x}", data);
-        class.write_packet(data).await?;
+        let (t1, t2) = critical_section::with(|_cs| {
+            syst.clear_current();
+
+            pin.set_pull(Pull::Down);
+            pin.set_as_output();
+            pin.set_high();
+            // // approx 1ms
+            // cortex_m::asm::delay(125_000);
+            cortex_m::asm::delay(600);
+            let t1 = SYST::get_current();
+            pin.set_as_input();
+            while pin.is_high() {}
+
+            let t2 = SYST::get_current();
+            (t1, t2)
+        });
+        let del = t1 - t2;
+        FmtBuf::write(class, format_args!("{del}\n")).await.map_err(|_| Disconnected{})?;
+
     }
 }