diff --git a/flow3-rs-rt/src/flow3r.rs b/flow3-rs-rt/src/flow3r.rs
index 6a425fefef29de5d23c02eb0e736480807de66fd..aad306250463edc0641d93e1f967599c94846fa8 100644
--- a/flow3-rs-rt/src/flow3r.rs
+++ b/flow3-rs-rt/src/flow3r.rs
@@ -14,17 +14,17 @@ use static_cell::StaticCell;
 
 use flow3_rs::{
     // badgelink::BadgeLink,
-    captouch::{Captouch, CaptouchRunner},
+    captouch::CaptouchRunner,
     display::Display,
     // imu::ImuHandler,
-    input::{Inputs, InputRunner},
+    input::InputRunner,
     leds::init_leds,
     Flow3r,
 };
 
 static CLOCKS: StaticCell<Clocks> = StaticCell::new();
 
-pub async fn init_flow3r() -> (Flow3r, InputRunner, CaptouchRunner)  {
+pub(crate) async fn init_flow3r() -> (Flow3r, InputRunner, CaptouchRunner)  {
     let peripherals = Peripherals::take();
     let mut system = peripherals.SYSTEM.split();
     let clocks = CLOCKS.init(ClockControl::boot_defaults(system.clock_control).freeze());
@@ -179,11 +179,9 @@ pub async fn init_flow3r() -> (Flow3r, InputRunner, CaptouchRunner)  {
 
     //let badgelink = BadgeLink::new(i2c_busmanager.acquire_i2c());
     //let imu = ImuHandler::new(i2c_busmanager.acquire_i2c());
-    let inputs = Inputs;
-    let captouch = Captouch;
     let leds = init_leds(rmt, io.pins.gpio14);
 
-    let flow3r = Flow3r::new(None, Some(captouch), Some(display), None, Some(inputs), Some(leds), Some(uart0), Some(uart1), Some(rng));
+    let flow3r = Flow3r::new(None, Some(display), None, Some(leds), Some(uart0), Some(uart1), Some(rng));
 
     (flow3r, input_runner, captouch_runner)
 }
\ No newline at end of file
diff --git a/flow3-rs-rt/src/lib.rs b/flow3-rs-rt/src/lib.rs
index af2e7bdc6623cf9a06b003c147b4241b2dadb93d..709127de6772cec54e7b60a1ca2f94a34799e8bf 100644
--- a/flow3-rs-rt/src/lib.rs
+++ b/flow3-rs-rt/src/lib.rs
@@ -1,6 +1,17 @@
 #![no_std]
 #![feature(type_alias_impl_trait)]
 
+//! This crate provides a runtime implementation for the [`Flow3r`] based on [`embassy`] as the async runtime.
+//! It takes care of initializing the hardware and starting the async runtime and all necessary background tasks.
+//! 
+//! If you want to get started quickly, use the [`flow3-rs-template`] to set up a minimal `flow3-rs-rt` project, by running:
+//! ```
+//! cargo generate --git https://git.flow3r.garden/flow3r/flow3-rs
+//! ```
+//! 
+//! [`Flow3r`]: https://flow3r.garden
+//! [`embassy`]: https://embassy.dev
+
 mod runtime;
 mod flow3r;
 pub use runtime::start_runtime;
\ No newline at end of file
diff --git a/flow3-rs-rt/src/runtime.rs b/flow3-rs-rt/src/runtime.rs
index 31b21055eba13508dad97aa058494b2bb5b1f01e..d2b5370bb6d312cab2a081f16bb0dea857405d03 100644
--- a/flow3-rs-rt/src/runtime.rs
+++ b/flow3-rs-rt/src/runtime.rs
@@ -10,6 +10,21 @@ use crate::flow3r::init_flow3r;
 
 pub static EXECUTOR: StaticCell<Executor> = StaticCell::new();
 
+
+/// This function starts the async runtime, initializes the hardware and then starts the provided `main` function.
+/// The function passed as an argument must be an embassy-task.
+/// 
+/// ```rust
+/// #[entry]
+/// fn runtime() -> ! {
+///     start_runtime(main)
+/// }
+/// 
+/// #[embassy_runtime::task]
+/// async fn main(flow3r: Flow3r) {
+///     // do something
+/// }
+/// ```
 pub fn start_runtime<S>(main: fn(Flow3r) -> SpawnToken<S>) -> ! 
 {
     println!("starting runtime");
@@ -39,12 +54,12 @@ async fn init_runtime(main: fn(Flow3r) -> SpawnToken<*mut ()>) {
 }
 
 #[embassy_executor::task]
-pub async fn input_task(runner: InputRunner) -> ! {
+async fn input_task(runner: InputRunner) -> ! {
     runner.run().await
 }
 
 #[embassy_executor::task]
-pub async fn captouch_task(runner: CaptouchRunner) -> ! {
+async fn captouch_task(runner: CaptouchRunner) -> ! {
     runner.run().await
 }
 
diff --git a/flow3-rs-template/src/main.rs b/flow3-rs-template/src/main.rs
index 2544fd37d05aadcf92f1fab46471c57fccdc9685..b1c78c46dd241683371eb5b47358b0c951a91c57 100644
--- a/flow3-rs-template/src/main.rs
+++ b/flow3-rs-template/src/main.rs
@@ -1,7 +1,6 @@
 #![no_std]
 #![no_main]
 #![feature(type_alias_impl_trait)]
-#![feature(async_fn_in_trait)]
 
 use embassy_executor::Spawner;
 use embassy_time::{Duration, Timer};
@@ -19,7 +18,7 @@ fn runtime() -> ! {
 }
 
 #[embassy_executor::task]
-async fn main(mut flow3r: Flow3r) {
+async fn main(_flow3r: Flow3r) {
     let spawner = Spawner::for_current_executor().await;
     spawner.spawn(task()).unwrap();
 }
diff --git a/flow3-rs/src/captouch.rs b/flow3-rs/src/captouch.rs
index 894e00bac670156b29449d2dea13ce2333009861..6a9850d0483fe48c85b6a0ac081d5eae5be671cd 100644
--- a/flow3-rs/src/captouch.rs
+++ b/flow3-rs/src/captouch.rs
@@ -1,3 +1,30 @@
+//! The Flow3r has a total of 10 captouch surfaces, five top petals on the upper pcb, and five bottom petals on the lower pcb.
+//! Those petals are each divided into three touch surfaces for the top petals, and two for the bottom petals, allowing for 2/1 axis position resolution.
+//! 
+//! The petals are numbered clockwise starting from petal 0 above the USB-C port, leading to even-numbered top petals 0,2,4,6,8 and odd-numbered bottom petals 1,3,5,7,9.
+//! 
+//! The captouch as a whole can be accessed via the [`Captouch`] struct, which can be split into individual top and bottom petals.
+//! 
+//! ```rust
+//! let captouch = Captouch;
+//! 
+//! // split into top and bottom petals;
+//! let top_petals = captouch.top_petals();
+//! let bottom_petals = captouch.bottom_petals();
+//! 
+//! // check if Petal 7 is pressed
+//! if bottom_petals.petal7.pressed() {
+//!     // do something
+//! }
+//! ```
+//! 
+//! ## Runner
+//! ### Usage with `flow3-rs-rt`
+//! If you use the `flow3-rs` runtime, the runner is automatically set up and started for you.
+//! ### Without `flow3-rs` runtime
+//! If you don't use the `flow3-rs-rt`, you have to start the captouch runner before you can recieve any captouch events.
+//! In a seperate async task, execute the `run` function of the `CaptouchRunner`.
+
 use ad7147::{
     device::DecimationFactor,
     stage::{CapInput, CdcInput, InputConnection, StageSensitivity, ThresholdSensitivity, PeakDetect},
@@ -31,6 +58,7 @@ static PETALS: Mutex<CriticalSectionRawMutex, [Flow3rPetal; 10]> = Mutex::new([
     Flow3rPetal::new(Flow3rCaptouchController::BOTTOM),
 ]);
 
+#[derive(Copy, Clone)]
 pub struct Captouch;
 
 impl Captouch {
diff --git a/flow3-rs/src/lib.rs b/flow3-rs/src/lib.rs
index f0eb5f1c307f3ea6b61ff123ca9fd85bd8d3fa4a..f3ebbbb7b823a3aa3fa4fc63ede4c85fdcf6ad2b 100644
--- a/flow3-rs/src/lib.rs
+++ b/flow3-rs/src/lib.rs
@@ -1,6 +1,14 @@
 #![no_std]
 #![feature(type_alias_impl_trait, async_fn_in_trait)]
 
+//! This crate contains the board support for the [`Flow3r`]. It provides higher-level
+//! abstractions for the hardware components of the flower.
+//! 
+//! This crate is written for an async runtime. There are some tasks that need to be running in the
+//! background for all functionality to work. It was tested with embassy and the flow3-rs-rt, however
+//! it _should_ be agnostic over the async runtime used.
+
+
 use hal::Rng;
 
 use self::badgelink::BadgeLink;
@@ -21,12 +29,14 @@ pub mod sdcard;
 
 unsafe impl Sync for Flow3r {}
 
+/// This struct contains all the high-level peripherals of the board.
+/// To use a peripheral, call the respective `take` or `get` function. This returns an owned version of that peripheral.
+/// Each `take` function can only be called once, and will panic if called twice. 
+/// The peripherals behind a `get` function can exist multiple times.
 pub struct Flow3r {
     badgelink: Option<BadgeLink>,
-    captouch: Option<Captouch>,
     display: Option<Display>,
     imu: Option<ImuHandler>,
-    inputs: Option<Inputs>,
     leds: Option<Leds>,
     uart0: Option<BadgenetUartLeft>,
     uart1: Option<BadgenetUartRight>,
@@ -36,10 +46,8 @@ pub struct Flow3r {
 impl Flow3r {
     pub fn new(
         badgelink: Option<BadgeLink>,
-        captouch: Option<Captouch>,
         display: Option<Display>,
         imu: Option<ImuHandler>,
-        inputs: Option<Inputs>,
         leds: Option<Leds>,
         uart0: Option<BadgenetUartLeft>,
         uart1: Option<BadgenetUartRight>,
@@ -47,10 +55,8 @@ impl Flow3r {
     ) -> Self {
         Self {
             badgelink,
-            captouch,
             display,
             imu,
-            inputs,
             leds,
             uart0,
             uart1,
@@ -62,16 +68,16 @@ impl Flow3r {
         self.badgelink.take().expect("can only take badgelink once!")
     }
 
-    pub fn take_captouch(&mut self) -> Captouch {
-        self.captouch.take().expect("can only take captouch once!")
+    pub fn get_captouch(&mut self) -> Captouch {
+        Captouch
     }
 
     pub fn take_display(&mut self) -> Display {
         self.display.take().expect("can only take display once!")
     }
 
-    pub fn take_inputs(&mut self) -> Inputs {
-        self.inputs.take().expect("can only take inputs once!")
+    pub fn get_inputs(&mut self) -> Inputs {
+        Inputs
     }
 
     pub fn take_imu(&mut self) -> ImuHandler {