From 3d146e5793a2ef0e3c52867b25e14df854949238 Mon Sep 17 00:00:00 2001
From: Benjamin Koch <bbbsnowball@gmail.com>
Date: Sat, 20 May 2023 16:46:23 +0200
Subject: [PATCH] remove our copy of embassy_rp::i2c because we cannot use it
 for zero-length writes anyway

---
 firmware/rust1/src/rp/i2c.rs | 961 -----------------------------------
 firmware/rust1/src/rp/mod.rs |   1 -
 2 files changed, 962 deletions(-)
 delete mode 100644 firmware/rust1/src/rp/i2c.rs

diff --git a/firmware/rust1/src/rp/i2c.rs b/firmware/rust1/src/rp/i2c.rs
deleted file mode 100644
index 48c3e32..0000000
--- a/firmware/rust1/src/rp/i2c.rs
+++ /dev/null
@@ -1,961 +0,0 @@
-// This is a modified copy of embassy/embassy-rp/src/i2c.rs.
-// We have changed:
-// - allow empty buffer for write (for I2C scan)
-// - don't block access to reserved addresses (also for I2C scan)
-
-use core::future;
-use core::marker::PhantomData;
-use core::task::Poll;
-
-use embassy_cortex_m::interrupt::InterruptExt;
-use embassy_hal_common::{into_ref, PeripheralRef};
-use embassy_sync::waitqueue::AtomicWaker;
-use pac::i2c;
-
-use embassy_rp::gpio::Pin;
-use embassy_rp::gpio::AnyPin;
-use embassy_rp::{pac, peripherals, Peripheral};
-
-/// I2C error abort reason
-#[derive(Debug)]
-#[cfg_attr(feature = "defmt", derive(defmt::Format))]
-pub enum AbortReason {
-    /// A bus operation was not acknowledged, e.g. due to the addressed device
-    /// not being available on the bus or the device not being ready to process
-    /// requests at the moment
-    NoAcknowledge,
-    /// The arbitration was lost, e.g. electrical problems with the clock signal
-    ArbitrationLoss,
-    Other(u32),
-}
-
-/// I2C error
-#[derive(Debug)]
-#[cfg_attr(feature = "defmt", derive(defmt::Format))]
-pub enum Error {
-    /// I2C abort with error
-    Abort(AbortReason),
-    /// User passed in a read buffer that was 0 length
-    InvalidReadBufferLength,
-    /// User passed in a write buffer that was 0 length
-    InvalidWriteBufferLength,
-    /// Target i2c address is out of range
-    AddressOutOfRange(u16),
-    /// Target i2c address is reserved
-    AddressReserved(u16),
-}
-
-#[non_exhaustive]
-#[derive(Copy, Clone)]
-pub struct Config {
-    pub frequency: u32,
-}
-
-impl Default for Config {
-    fn default() -> Self {
-        Self { frequency: 100_000 }
-    }
-}
-
-const FIFO_SIZE: u8 = 16;
-
-pub struct I2c<'d, T: Instance, M: Mode> {
-    phantom: PhantomData<(&'d mut T, M)>,
-}
-
-/*
-impl<'d, T: Instance> I2c<'d, T, Blocking> {
-    pub fn new_blocking(
-        peri: impl Peripheral<P = T> + 'd,
-        scl: impl Peripheral<P = impl SclPin<T>> + 'd,
-        sda: impl Peripheral<P = impl SdaPin<T>> + 'd,
-        config: Config,
-    ) -> Self {
-        into_ref!(scl, sda);
-        Self::new_inner(peri, scl.map_into(), sda.map_into(), config)
-    }
-}
-*/
-
-impl<'d, T: Instance> I2c<'d, T, Async> {
-    pub fn new_async(
-        peri: impl Peripheral<P = T> + 'd,
-        scl: impl Peripheral<P = impl SclPin<T>> + 'd,
-        sda: impl Peripheral<P = impl SdaPin<T>> + 'd,
-        irq: impl Peripheral<P = T::Interrupt> + 'd,
-        config: Config,
-    ) -> Self {
-        into_ref!(scl, sda, irq);
-
-        let i2c = Self::new_inner(peri, scl.map_into(), sda.map_into(), config);
-
-        irq.set_handler(Self::on_interrupt);
-        unsafe {
-            let i2c = T::regs();
-
-            // mask everything initially
-            i2c.ic_intr_mask().write_value(i2c::regs::IcIntrMask(0));
-        }
-        irq.unpend();
-        debug_assert!(!irq.is_pending());
-        irq.enable();
-
-        i2c
-    }
-
-    /// Calls `f` to check if we are ready or not.
-    /// If not, `g` is called once the waker is set (to eg enable the required interrupts).
-    async fn wait_on<F, U, G>(&mut self, mut f: F, mut g: G) -> U
-    where
-        F: FnMut(&mut Self) -> Poll<U>,
-        G: FnMut(&mut Self),
-    {
-        future::poll_fn(|cx| {
-            let r = f(self);
-
-            if r.is_pending() {
-                T::waker().register(cx.waker());
-                g(self);
-            }
-            r
-        })
-        .await
-    }
-
-    // Mask interrupts and wake any task waiting for this interrupt
-    unsafe fn on_interrupt(_: *mut ()) {
-        let i2c = T::regs();
-        i2c.ic_intr_mask().write_value(pac::i2c::regs::IcIntrMask::default());
-
-        T::waker().wake();
-    }
-
-    async fn read_async_internal(&mut self, buffer: &mut [u8], restart: bool, send_stop: bool) -> Result<(), Error> {
-        if buffer.is_empty() {
-            return Err(Error::InvalidReadBufferLength);
-        }
-
-        let p = T::regs();
-
-        let mut remaining = buffer.len();
-        let mut remaining_queue = buffer.len();
-
-        let mut abort_reason = Ok(());
-
-        while remaining > 0 {
-            // Waggle SCK - basically the same as write
-            let tx_fifo_space = Self::tx_fifo_capacity();
-            let mut batch = 0;
-
-            debug_assert!(remaining_queue > 0);
-
-            for _ in 0..remaining_queue.min(tx_fifo_space as usize) {
-                remaining_queue -= 1;
-                let last = remaining_queue == 0;
-                batch += 1;
-
-                unsafe {
-                    p.ic_data_cmd().write(|w| {
-                        w.set_restart(restart && remaining_queue == buffer.len() - 1);
-                        w.set_stop(last && send_stop);
-                        w.set_cmd(true);
-                    });
-                }
-            }
-
-            // We've either run out of txfifo or just plain finished setting up
-            // the clocks for the message - either way we need to wait for rx
-            // data.
-
-            debug_assert!(batch > 0);
-            let res = self
-                .wait_on(
-                    |me| {
-                        let rxfifo = Self::rx_fifo_len();
-                        if let Err(abort_reason) = me.read_and_clear_abort_reason(false) {
-                            Poll::Ready(Err(abort_reason))
-                        } else if rxfifo >= batch {
-                            Poll::Ready(Ok(rxfifo))
-                        } else {
-                            Poll::Pending
-                        }
-                    },
-                    |_me| unsafe {
-                        // Set the read threshold to the number of bytes we're
-                        // expecting so we don't get spurious interrupts.
-                        p.ic_rx_tl().write(|w| w.set_rx_tl(batch - 1));
-
-                        p.ic_intr_mask().modify(|w| {
-                            w.set_m_rx_full(true);
-                            w.set_m_tx_abrt(true);
-                        });
-                    },
-                )
-                .await;
-
-            match res {
-                Err(reason) => {
-                    abort_reason = Err(reason);
-                    break;
-                }
-                Ok(rxfifo) => {
-                    // Fetch things from rx fifo. We're assuming we're the only
-                    // rxfifo reader, so nothing else can take things from it.
-                    let rxbytes = (rxfifo as usize).min(remaining);
-                    let received = buffer.len() - remaining;
-                    for b in &mut buffer[received..received + rxbytes] {
-                        *b = unsafe { p.ic_data_cmd().read().dat() };
-                    }
-                    remaining -= rxbytes;
-                }
-            };
-        }
-
-        self.wait_stop_det(abort_reason, send_stop, false).await
-    }
-
-    async fn write_async_internal(
-        &mut self,
-        bytes: impl IntoIterator<Item = u8>,
-        send_stop: bool,
-    ) -> Result<(), Error> {
-        let p = T::regs();
-
-        let mut bytes = bytes.into_iter().peekable();
-        let mut empty_transfer = true;
-
-        let status = unsafe { p.ic_status().read() };
-        defmt::info!("ic_status: {:?}, {}", status.0, status.mst_activity());
-
-        let res = 'xmit: loop {
-            let tx_fifo_space = Self::tx_fifo_capacity();
-
-            for _ in 0..tx_fifo_space {
-                if let Some(byte) = bytes.next() {
-                    let last = bytes.peek().is_none();
-                    empty_transfer = false;
-
-                    unsafe {
-                        p.ic_data_cmd().write(|w| {
-                            w.set_stop(last && send_stop);
-                            w.set_cmd(false);
-                            w.set_dat(byte);
-                        });
-                    }
-                } else if empty_transfer && send_stop {
-                    // This is no good because it will still send one byte before stopping.
-                    //p.ic_data_cmd().write(|w| {
-                    //    w.set_stop(send_stop);
-                    //});
-    
-                    // The Arduino code that we used before resorts to bitbanging in this case:
-                    // https://github.com/earlephilhower/arduino-pico/blob/6e52b72523b11470b2ad2b0578ca1500be238108/libraries/Wire/src/Wire.cpp#L257
-    
-                    // We can abort the transfer to send a STOP but we have to wait for the address
-                    // to be sent. If we set TX_EMPTY_CTRL=1, it should wait until the address has
-                    // been sent.
-                    //FIXME I think we set this in any case.
-                    unsafe {
-                        p.ic_con().modify(|w| {
-                            w.set_tx_empty_ctrl(true);
-                        });
-                    }
-                } else {
-                    break 'xmit Ok(());
-                }
-            }
-
-            let res = self
-                .wait_on(
-                    |me| {
-                        if let abort_reason @ Err(_) = me.read_and_clear_abort_reason(false) {
-                            Poll::Ready(abort_reason)
-                        } else if !Self::tx_fifo_full() {
-                            // resume if there's any space free in the tx fifo
-                            Poll::Ready(Ok(()))
-                        } else {
-                            Poll::Pending
-                        }
-                    },
-                    |_me| unsafe {
-                        // Set tx "free" threshold a little high so that we get
-                        // woken before the fifo completely drains to minimize
-                        // transfer stalls.
-                        p.ic_tx_tl().write(|w| w.set_tx_tl(1));
-
-                        p.ic_intr_mask().modify(|w| {
-                            w.set_m_tx_empty(true);
-                            w.set_m_tx_abrt(true);
-                        })
-                    },
-                )
-                .await;
-            //defmt::info!("got tx empty: {:?}", res);
-            if res.is_err() {
-                break res;
-            }
-
-            if empty_transfer && send_stop {
-                let status = unsafe { p.ic_status().read() };
-                let abort_reason = unsafe { p.ic_tx_abrt_source().read() };
-                defmt::info!("ic_status: {:?}, {}, {:?}", status.0, status.mst_activity(), abort_reason.0);
-                unsafe {
-                    p.ic_enable().modify(|w| {
-                        w.set_abort(true);
-                    })
-                }
-                let status = unsafe { p.ic_status().read() };
-                let abort_reason = unsafe { p.ic_tx_abrt_source().read() };
-                defmt::info!("ic_status: {:?}, {}, {:?}", status.0, status.mst_activity(), abort_reason.0);
-
-                defmt::info!("wait_stop_det");
-                let x = self.wait_stop_det(res, send_stop, empty_transfer && send_stop && false).await;
-                return match x {
-                    Ok(()) => Ok(()),
-                    Err(Error::Abort(AbortReason::Other(65536))) => Ok(()),  // user abort is expected
-                    Err(e) => Err(e),
-                }
-            }
-        };
-
-        self.wait_stop_det(res, send_stop, empty_transfer && send_stop && false).await
-    }
-
-    /// Helper to wait for a stop bit, for both tx and rx. If we had an abort,
-    /// then we'll get a hardware-generated stop, otherwise wait for a stop if
-    /// we're expecting it.
-    ///
-    /// Also handles an abort which arises while processing the tx fifo.
-    async fn wait_stop_det(&mut self, had_abort: Result<(), Error>, do_stop: bool, user_abort_is_ok: bool) -> Result<(), Error> {
-        if had_abort.is_err() || do_stop {
-            let p = T::regs();
-
-            let had_abort2 = self
-                .wait_on(
-                    |me| unsafe {
-                        // We could see an abort while processing fifo backlog,
-                        // so handle it here.
-                        let abort = me.read_and_clear_abort_reason(user_abort_is_ok);
-                        if had_abort.is_ok() && abort.is_err() {
-                            Poll::Ready(abort)
-                        } else if p.ic_raw_intr_stat().read().stop_det() {
-                            Poll::Ready(Ok(()))
-                        } else {
-                            Poll::Pending
-                        }
-                    },
-                    |_me| unsafe {
-                        p.ic_intr_mask().modify(|w| {
-                            w.set_m_stop_det(true);
-                            w.set_m_tx_abrt(true);
-                        });
-                    },
-                )
-                .await;
-            unsafe {
-                p.ic_clr_stop_det().read();
-            }
-
-            had_abort.and(had_abort2)
-        } else {
-            had_abort
-        }
-    }
-
-    pub async fn read_async(&mut self, addr: u16, buffer: &mut [u8]) -> Result<(), Error> {
-        Self::setup(addr)?;
-        self.read_async_internal(buffer, false, true).await
-    }
-
-    pub async fn write_async(&mut self, addr: u16, bytes: impl IntoIterator<Item = u8>) -> Result<(), Error> {
-        Self::setup(addr)?;
-        self.write_async_internal(bytes, true).await
-    }
-}
-
-// copy of internal method because we need it here
-fn io<'d>(pin : &PeripheralRef<'d, AnyPin>) -> pac::io::Gpio {
-    use embassy_rp::gpio::Bank;
-    let block = match pin.bank() {
-        Bank::Bank0 => embassy_rp::pac::IO_BANK0,
-        Bank::Qspi => embassy_rp::pac::IO_QSPI,
-    };
-    block.gpio(pin.pin() as _)
-}
-
-// copy of internal method because we need it here
-fn pad_ctrl<'d>(pin : &PeripheralRef<'d, AnyPin>) -> embassy_rp::pac::common::Reg<pac::pads::regs::GpioCtrl, embassy_rp::pac::common::RW> {
-    use embassy_rp::gpio::Bank;
-    let block = match pin.bank() {
-        Bank::Bank0 => embassy_rp::pac::PADS_BANK0,
-        Bank::Qspi => embassy_rp::pac::PADS_QSPI,
-    };
-    block.gpio(pin.pin() as _)
-}
-
-// copy of internal method because we need it here
-pub unsafe fn reset(peris: embassy_rp::pac::resets::regs::Peripherals) {
-    embassy_rp::pac::RESETS.reset().write_value(peris);
-}
-
-// copy of internal method because we need it here
-pub unsafe fn unreset_wait(peris: embassy_rp::pac::resets::regs::Peripherals) {
-    // TODO use the "atomic clear" register version
-    embassy_rp::pac::RESETS.reset().modify(|v| *v = embassy_rp::pac::resets::regs::Peripherals(v.0 & !peris.0));
-    while ((!embassy_rp::pac::RESETS.reset_done().read().0) & peris.0) != 0 {}
-}
-
-
-impl<'d, T: Instance + 'd, M: Mode> I2c<'d, T, M> {
-    fn new_inner(
-        _peri: impl Peripheral<P = T> + 'd,
-        scl: PeripheralRef<'d, AnyPin>,
-        sda: PeripheralRef<'d, AnyPin>,
-        config: Config,
-    ) -> Self {
-        into_ref!(_peri);
-
-        assert!(config.frequency <= 1_000_000);
-        assert!(config.frequency > 0);
-
-        let p = T::regs();
-
-        unsafe {
-            let reset = T::reset();
-            self::reset(reset);
-            unreset_wait(reset);
-
-            p.ic_enable().write(|w| w.set_enable(false));
-
-            // Select controller mode & speed
-            p.ic_con().modify(|w| {
-                // Always use "fast" mode (<= 400 kHz, works fine for standard
-                // mode too)
-                w.set_speed(i2c::vals::Speed::FAST);
-                w.set_master_mode(true);
-                w.set_ic_slave_disable(true);
-                w.set_ic_restart_en(true);
-                w.set_tx_empty_ctrl(true);
-            });
-
-            // Set FIFO watermarks to 1 to make things simpler. This is encoded
-            // by a register value of 0.
-            p.ic_tx_tl().write(|w| w.set_tx_tl(0));
-            p.ic_rx_tl().write(|w| w.set_rx_tl(0));
-
-            // Configure SCL & SDA pins
-            io(&scl).ctrl().write(|w| w.set_funcsel(3));
-            io(&sda).ctrl().write(|w| w.set_funcsel(3));
-
-            pad_ctrl(&scl).write(|w| {
-                w.set_schmitt(true);
-                w.set_ie(true);
-                w.set_od(false);
-                w.set_pue(true);
-                w.set_pde(false);
-            });
-            pad_ctrl(&sda).write(|w| {
-                w.set_schmitt(true);
-                w.set_ie(true);
-                w.set_od(false);
-                w.set_pue(true);
-                w.set_pde(false);
-            });
-
-            // Configure baudrate
-
-            // There are some subtleties to I2C timing which we are completely
-            // ignoring here See:
-            // https://github.com/raspberrypi/pico-sdk/blob/bfcbefafc5d2a210551a4d9d80b4303d4ae0adf7/src/rp2_common/hardware_i2c/i2c.c#L69
-            let clk_base = embassy_rp::clocks::clk_peri_freq();
-
-            let period = (clk_base + config.frequency / 2) / config.frequency;
-            let lcnt = period * 3 / 5; // spend 3/5 (60%) of the period low
-            let hcnt = period - lcnt; // and 2/5 (40%) of the period high
-
-            // Check for out-of-range divisors:
-            assert!(hcnt <= 0xffff);
-            assert!(lcnt <= 0xffff);
-            assert!(hcnt >= 8);
-            assert!(lcnt >= 8);
-
-            // Per I2C-bus specification a device in standard or fast mode must
-            // internally provide a hold time of at least 300ns for the SDA
-            // signal to bridge the undefined region of the falling edge of SCL.
-            // A smaller hold time of 120ns is used for fast mode plus.
-            let sda_tx_hold_count = if config.frequency < 1_000_000 {
-                // sda_tx_hold_count = clk_base [cycles/s] * 300ns * (1s /
-                // 1e9ns) Reduce 300/1e9 to 3/1e7 to avoid numbers that don't
-                // fit in uint. Add 1 to avoid division truncation.
-                ((clk_base * 3) / 10_000_000) + 1
-            } else {
-                // fast mode plus requires a clk_base > 32MHz
-                assert!(clk_base >= 32_000_000);
-
-                // sda_tx_hold_count = clk_base [cycles/s] * 120ns * (1s /
-                // 1e9ns) Reduce 120/1e9 to 3/25e6 to avoid numbers that don't
-                // fit in uint. Add 1 to avoid division truncation.
-                ((clk_base * 3) / 25_000_000) + 1
-            };
-            assert!(sda_tx_hold_count <= lcnt - 2);
-
-            p.ic_fs_scl_hcnt().write(|w| w.set_ic_fs_scl_hcnt(hcnt as u16));
-            p.ic_fs_scl_lcnt().write(|w| w.set_ic_fs_scl_lcnt(lcnt as u16));
-            p.ic_fs_spklen()
-                .write(|w| w.set_ic_fs_spklen(if lcnt < 16 { 1 } else { (lcnt / 16) as u8 }));
-            p.ic_sda_hold()
-                .modify(|w| w.set_ic_sda_tx_hold(sda_tx_hold_count as u16));
-
-            // Enable I2C block
-            p.ic_enable().write(|w| w.set_enable(true));
-        }
-
-        Self { phantom: PhantomData }
-    }
-
-    fn setup(addr: u16) -> Result<(), Error> {
-        if addr >= 0x80 {
-            return Err(Error::AddressOutOfRange(addr));
-        }
-
-        //if i2c_reserved_addr(addr) {
-        //    return Err(Error::AddressReserved(addr));
-        //}
-
-        let p = T::regs();
-        unsafe {
-            p.ic_enable().write(|w| w.set_enable(false));
-            p.ic_tar().write(|w| w.set_ic_tar(addr));
-            p.ic_enable().write(|w| w.set_enable(true));
-        }
-        Ok(())
-    }
-
-    #[inline]
-    fn tx_fifo_full() -> bool {
-        Self::tx_fifo_capacity() == 0
-    }
-
-    #[inline]
-    fn tx_fifo_capacity() -> u8 {
-        let p = T::regs();
-        unsafe { FIFO_SIZE - p.ic_txflr().read().txflr() }
-    }
-
-    #[inline]
-    fn rx_fifo_len() -> u8 {
-        let p = T::regs();
-        unsafe { p.ic_rxflr().read().rxflr() }
-    }
-
-    fn read_and_clear_abort_reason(&mut self, user_abort_is_ok: bool) -> Result<(), Error> {
-        let p = T::regs();
-        unsafe {
-            let abort_reason = p.ic_tx_abrt_source().read();
-            if abort_reason.0 != 0 {
-                // Note clearing the abort flag also clears the reason, and this
-                // instance of flag is clear-on-read! Note also the
-                // IC_CLR_TX_ABRT register always reads as 0.
-                p.ic_clr_tx_abrt().read();
-
-                let reason = if abort_reason.abrt_7b_addr_noack()
-                    | abort_reason.abrt_10addr1_noack()
-                    | abort_reason.abrt_10addr2_noack()
-                {
-                    AbortReason::NoAcknowledge
-                } else if abort_reason.arb_lost() {
-                    AbortReason::ArbitrationLoss
-                } else if user_abort_is_ok && abort_reason.abrt_user_abrt() {
-                    return Ok(())
-                } else {
-                    AbortReason::Other(abort_reason.0)
-                };
-
-                Err(Error::Abort(reason))
-            } else {
-                Ok(())
-            }
-        }
-    }
-
-    fn read_blocking_internal(&mut self, read: &mut [u8], restart: bool, send_stop: bool) -> Result<(), Error> {
-        if read.is_empty() {
-            return Err(Error::InvalidReadBufferLength);
-        }
-
-        let p = T::regs();
-        let lastindex = read.len() - 1;
-        for (i, byte) in read.iter_mut().enumerate() {
-            let first = i == 0;
-            let last = i == lastindex;
-
-            // NOTE(unsafe) We have &mut self
-            unsafe {
-                // wait until there is space in the FIFO to write the next byte
-                while Self::tx_fifo_full() {}
-
-                p.ic_data_cmd().write(|w| {
-                    w.set_restart(restart && first);
-                    w.set_stop(send_stop && last);
-
-                    w.set_cmd(true);
-                });
-
-                while Self::rx_fifo_len() == 0 {
-                    self.read_and_clear_abort_reason(false)?;
-                }
-
-                *byte = p.ic_data_cmd().read().dat();
-            }
-        }
-
-        Ok(())
-    }
-
-    fn write_blocking_internal(&mut self, write: &[u8], send_stop: bool) -> Result<(), Error> {
-        if write.is_empty() {
-            return Err(Error::InvalidWriteBufferLength);
-        }
-
-        let p = T::regs();
-
-        for (i, byte) in write.iter().enumerate() {
-            let last = i == write.len() - 1;
-
-            // NOTE(unsafe) We have &mut self
-            unsafe {
-                p.ic_data_cmd().write(|w| {
-                    w.set_stop(send_stop && last);
-                    w.set_dat(*byte);
-                });
-
-                // Wait until the transmission of the address/data from the
-                // internal shift register has completed. For this to function
-                // correctly, the TX_EMPTY_CTRL flag in IC_CON must be set. The
-                // TX_EMPTY_CTRL flag was set in i2c_init.
-                while !p.ic_raw_intr_stat().read().tx_empty() {}
-
-                let abort_reason = self.read_and_clear_abort_reason(false);
-
-                if abort_reason.is_err() || (send_stop && last) {
-                    // If the transaction was aborted or if it completed
-                    // successfully wait until the STOP condition has occurred.
-
-                    while !p.ic_raw_intr_stat().read().stop_det() {}
-
-                    p.ic_clr_stop_det().read().clr_stop_det();
-                }
-
-                // Note the hardware issues a STOP automatically on an abort
-                // condition. Note also the hardware clears RX FIFO as well as
-                // TX on abort, ecause we set hwparam
-                // IC_AVOID_RX_FIFO_FLUSH_ON_TX_ABRT to 0.
-                abort_reason?;
-            }
-        }
-        Ok(())
-    }
-
-    // =========================
-    // Blocking public API
-    // =========================
-
-    pub fn blocking_read(&mut self, address: u8, read: &mut [u8]) -> Result<(), Error> {
-        Self::setup(address.into())?;
-        self.read_blocking_internal(read, true, true)
-        // Automatic Stop
-    }
-
-    pub fn blocking_write(&mut self, address: u8, write: &[u8]) -> Result<(), Error> {
-        Self::setup(address.into())?;
-        self.write_blocking_internal(write, true)
-    }
-
-    pub fn blocking_write_read(&mut self, address: u8, write: &[u8], read: &mut [u8]) -> Result<(), Error> {
-        Self::setup(address.into())?;
-        self.write_blocking_internal(write, false)?;
-        self.read_blocking_internal(read, true, true)
-        // Automatic Stop
-    }
-}
-
-/*
-mod eh02 {
-    use super::*;
-
-    impl<'d, T: Instance, M: Mode> embedded_hal_02::blocking::i2c::Read for I2c<'d, T, M> {
-        type Error = Error;
-
-        fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Self::Error> {
-            self.blocking_read(address, buffer)
-        }
-    }
-
-    impl<'d, T: Instance, M: Mode> embedded_hal_02::blocking::i2c::Write for I2c<'d, T, M> {
-        type Error = Error;
-
-        fn write(&mut self, address: u8, bytes: &[u8]) -> Result<(), Self::Error> {
-            self.blocking_write(address, bytes)
-        }
-    }
-
-    impl<'d, T: Instance, M: Mode> embedded_hal_02::blocking::i2c::WriteRead for I2c<'d, T, M> {
-        type Error = Error;
-
-        fn write_read(&mut self, address: u8, bytes: &[u8], buffer: &mut [u8]) -> Result<(), Self::Error> {
-            self.blocking_write_read(address, bytes, buffer)
-        }
-    }
-
-    impl<'d, T: Instance, M: Mode> embedded_hal_02::blocking::i2c::Transactional for I2c<'d, T, M> {
-        type Error = Error;
-
-        fn exec(
-            &mut self,
-            address: u8,
-            operations: &mut [embedded_hal_02::blocking::i2c::Operation<'_>],
-        ) -> Result<(), Self::Error> {
-            Self::setup(address.into())?;
-            for i in 0..operations.len() {
-                let last = i == operations.len() - 1;
-                match &mut operations[i] {
-                    embedded_hal_02::blocking::i2c::Operation::Read(buf) => {
-                        self.read_blocking_internal(buf, false, last)?
-                    }
-                    embedded_hal_02::blocking::i2c::Operation::Write(buf) => self.write_blocking_internal(buf, last)?,
-                }
-            }
-            Ok(())
-        }
-    }
-}
-*/
-
-#[cfg(feature = "unstable-traits")]
-mod eh1 {
-    use super::*;
-
-    impl embedded_hal_1::i2c::Error for Error {
-        fn kind(&self) -> embedded_hal_1::i2c::ErrorKind {
-            match *self {
-                Self::Abort(AbortReason::ArbitrationLoss) => embedded_hal_1::i2c::ErrorKind::ArbitrationLoss,
-                Self::Abort(AbortReason::NoAcknowledge) => {
-                    embedded_hal_1::i2c::ErrorKind::NoAcknowledge(embedded_hal_1::i2c::NoAcknowledgeSource::Address)
-                }
-                Self::Abort(AbortReason::Other(_)) => embedded_hal_1::i2c::ErrorKind::Other,
-                Self::InvalidReadBufferLength => embedded_hal_1::i2c::ErrorKind::Other,
-                Self::InvalidWriteBufferLength => embedded_hal_1::i2c::ErrorKind::Other,
-                Self::AddressOutOfRange(_) => embedded_hal_1::i2c::ErrorKind::Other,
-                Self::AddressReserved(_) => embedded_hal_1::i2c::ErrorKind::Other,
-            }
-        }
-    }
-
-    impl<'d, T: Instance, M: Mode> embedded_hal_1::i2c::ErrorType for I2c<'d, T, M> {
-        type Error = Error;
-    }
-
-    impl<'d, T: Instance, M: Mode> embedded_hal_1::i2c::I2c for I2c<'d, T, M> {
-        fn read(&mut self, address: u8, read: &mut [u8]) -> Result<(), Self::Error> {
-            self.blocking_read(address, read)
-        }
-
-        fn write(&mut self, address: u8, write: &[u8]) -> Result<(), Self::Error> {
-            self.blocking_write(address, write)
-        }
-
-        fn write_read(&mut self, address: u8, write: &[u8], read: &mut [u8]) -> Result<(), Self::Error> {
-            self.blocking_write_read(address, write, read)
-        }
-
-        fn transaction(
-            &mut self,
-            address: u8,
-            operations: &mut [embedded_hal_1::i2c::Operation<'_>],
-        ) -> Result<(), Self::Error> {
-            Self::setup(address.into())?;
-            for i in 0..operations.len() {
-                let last = i == operations.len() - 1;
-                match &mut operations[i] {
-                    embedded_hal_1::i2c::Operation::Read(buf) => self.read_blocking_internal(buf, false, last)?,
-                    embedded_hal_1::i2c::Operation::Write(buf) => self.write_blocking_internal(buf, last)?,
-                }
-            }
-            Ok(())
-        }
-    }
-}
-#[cfg(all(feature = "unstable-traits", feature = "nightly"))]
-mod nightly {
-    use embedded_hal_1::i2c::Operation;
-    use embedded_hal_async::i2c::AddressMode;
-
-    use super::*;
-
-    impl<'d, A, T> embedded_hal_async::i2c::I2c<A> for I2c<'d, T, Async>
-    where
-        A: AddressMode + Into<u16> + 'static,
-        T: Instance + 'd,
-    {
-        async fn read(&mut self, address: A, read: &mut [u8]) -> Result<(), Self::Error> {
-            let addr: u16 = address.into();
-
-            Self::setup(addr)?;
-            self.read_async_internal(read, false, true).await
-        }
-
-        async fn write(&mut self, address: A, write: &[u8]) -> Result<(), Self::Error> {
-            let addr: u16 = address.into();
-
-            Self::setup(addr)?;
-            self.write_async_internal(write.iter().copied(), true).await
-        }
-
-        async fn write_read(&mut self, address: A, write: &[u8], read: &mut [u8]) -> Result<(), Self::Error> {
-            let addr: u16 = address.into();
-
-            Self::setup(addr)?;
-            self.write_async_internal(write.iter().cloned(), false).await?;
-            self.read_async_internal(read, false, true).await
-        }
-
-        async fn transaction(&mut self, address: A, operations: &mut [Operation<'_>]) -> Result<(), Self::Error> {
-            let addr: u16 = address.into();
-
-            let mut iterator = operations.iter_mut();
-
-            while let Some(op) = iterator.next() {
-                let last = iterator.len() == 0;
-
-                match op {
-                    Operation::Read(buffer) => {
-                        Self::setup(addr)?;
-                        self.read_async_internal(buffer, false, last).await?;
-                    }
-                    Operation::Write(buffer) => {
-                        Self::setup(addr)?;
-                        self.write_async_internal(buffer.into_iter().cloned(), last).await?;
-                    }
-                }
-            }
-            Ok(())
-        }
-    }
-}
-
-fn _i2c_reserved_addr(addr: u16) -> bool {
-    (addr & 0x78) == 0 || (addr & 0x78) == 0x78
-}
-
-mod sealed {
-    use embassy_cortex_m::interrupt::Interrupt;
-    use embassy_sync::waitqueue::AtomicWaker;
-
-    pub trait Instance {
-        const TX_DREQ: u8;
-        const RX_DREQ: u8;
-
-        type Interrupt: Interrupt;
-
-        fn regs() -> embassy_rp::pac::i2c::I2c;
-        fn reset() -> embassy_rp::pac::resets::regs::Peripherals;
-        fn waker() -> &'static AtomicWaker;
-    }
-
-    pub trait Mode {}
-
-    pub trait SdaPin<T: Instance> {}
-    pub trait SclPin<T: Instance> {}
-}
-
-pub trait Mode: sealed::Mode {}
-
-macro_rules! impl_mode {
-    ($name:ident) => {
-        impl sealed::Mode for $name {}
-        impl Mode for $name {}
-    };
-}
-
-pub struct Blocking;
-pub struct Async;
-
-impl_mode!(Blocking);
-impl_mode!(Async);
-
-pub trait Instance: sealed::Instance {}
-
-macro_rules! impl_instance {
-    ($type:ident, $irq:ident, $reset:ident, $tx_dreq:expr, $rx_dreq:expr) => {
-        impl sealed::Instance for peripherals::$type {
-            const TX_DREQ: u8 = $tx_dreq;
-            const RX_DREQ: u8 = $rx_dreq;
-
-            type Interrupt = embassy_rp::interrupt::$irq;
-
-            #[inline]
-            fn regs() -> pac::i2c::I2c {
-                pac::$type
-            }
-
-            #[inline]
-            fn reset() -> pac::resets::regs::Peripherals {
-                let mut ret = pac::resets::regs::Peripherals::default();
-                ret.$reset(true);
-                ret
-            }
-
-            #[inline]
-            fn waker() -> &'static AtomicWaker {
-                static WAKER: AtomicWaker = AtomicWaker::new();
-
-                &WAKER
-            }
-        }
-        impl Instance for peripherals::$type {}
-    };
-}
-
-impl_instance!(I2C0, I2C0_IRQ, set_i2c0, 32, 33);
-impl_instance!(I2C1, I2C1_IRQ, set_i2c1, 34, 35);
-
-pub trait SdaPin<T: Instance>: sealed::SdaPin<T> + embassy_rp::gpio::Pin {}
-pub trait SclPin<T: Instance>: sealed::SclPin<T> + embassy_rp::gpio::Pin {}
-
-macro_rules! impl_pin {
-    ($pin:ident, $instance:ident, $function:ident) => {
-        impl sealed::$function<peripherals::$instance> for peripherals::$pin {}
-        impl $function<peripherals::$instance> for peripherals::$pin {}
-    };
-}
-
-impl_pin!(PIN_0, I2C0, SdaPin);
-impl_pin!(PIN_1, I2C0, SclPin);
-impl_pin!(PIN_2, I2C1, SdaPin);
-impl_pin!(PIN_3, I2C1, SclPin);
-impl_pin!(PIN_4, I2C0, SdaPin);
-impl_pin!(PIN_5, I2C0, SclPin);
-impl_pin!(PIN_6, I2C1, SdaPin);
-impl_pin!(PIN_7, I2C1, SclPin);
-impl_pin!(PIN_8, I2C0, SdaPin);
-impl_pin!(PIN_9, I2C0, SclPin);
-impl_pin!(PIN_10, I2C1, SdaPin);
-impl_pin!(PIN_11, I2C1, SclPin);
-impl_pin!(PIN_12, I2C0, SdaPin);
-impl_pin!(PIN_13, I2C0, SclPin);
-impl_pin!(PIN_14, I2C1, SdaPin);
-impl_pin!(PIN_15, I2C1, SclPin);
-impl_pin!(PIN_16, I2C0, SdaPin);
-impl_pin!(PIN_17, I2C0, SclPin);
-impl_pin!(PIN_18, I2C1, SdaPin);
-impl_pin!(PIN_19, I2C1, SclPin);
-impl_pin!(PIN_20, I2C0, SdaPin);
-impl_pin!(PIN_21, I2C0, SclPin);
-impl_pin!(PIN_22, I2C1, SdaPin);
-impl_pin!(PIN_23, I2C1, SclPin);
-impl_pin!(PIN_24, I2C0, SdaPin);
-impl_pin!(PIN_25, I2C0, SclPin);
-impl_pin!(PIN_26, I2C1, SdaPin);
-impl_pin!(PIN_27, I2C1, SclPin);
-impl_pin!(PIN_28, I2C0, SdaPin);
-impl_pin!(PIN_29, I2C0, SclPin);
diff --git a/firmware/rust1/src/rp/mod.rs b/firmware/rust1/src/rp/mod.rs
index eec2637..e69de29 100644
--- a/firmware/rust1/src/rp/mod.rs
+++ b/firmware/rust1/src/rp/mod.rs
@@ -1 +0,0 @@
-pub mod i2c;
-- 
GitLab