summaryrefslogtreecommitdiffstats
path: root/ble/src/i2c.rs
blob: e95987cc594936a6ec57fb8fcb8f8eb5514ceab9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
use log::{error, trace};
use nrf52840_hal::twis::{self, Twis, TwisInterrupt};
use starb::{Reader, RingBuffer, Writer};

static mut RB: RingBuffer<u8> = RingBuffer::new();

pub fn setup<T>(mut twis: Twis<T>) -> (Reader<'static, u8>, impl FnMut())
where
    T: twis::Instance,
{
    // TODO: we only care about `Write` and `Stopped`.
    twis.enable_interrupt(TwisInterrupt::Stopped);
    twis.enable_interrupt(TwisInterrupt::Error);
    //twis.enable_interrupt(TwisInterrupt::RxStarted);
    //twis.enable_interrupt(TwisInterrupt::TxStarted);
    twis.enable_interrupt(TwisInterrupt::Write);
    //twis.enable_interrupt(TwisInterrupt::Read);

    let (rbr, mut rbw) = unsafe { RB.split() };

    let cl = move || handler(&mut twis, &mut rbw);
    (rbr, cl)
}

fn handler<T>(twis: &mut Twis<T>, writer: &mut Writer<u8>)
where
    T: twis::Instance,
{
    if twis.get_event_triggered(TwisInterrupt::Stopped, true) {
        trace!("i²c stopped: {}", twis.amount());
    } else if twis.get_event_triggered(TwisInterrupt::Error, true) {
        trace!("i²c error");
    //} else if twis.get_event_triggered(TwisInterrupt::RxStarted, true) {
    //    trace!("i²c rxstarted");
    //} else if twis.get_event_triggered(TwisInterrupt::TxStarted, true) {
    //    trace!("i²c txstarted");
    } else if twis.get_event_triggered(TwisInterrupt::Write, true) {
        trace!("i²c write");
        let mut buf: [u8; 255] = [0; 255];
        match twis.read(&mut buf) {
            Ok(len) => {
                // Ignore unshift overflow for now, as I don't think
                // there's much we can do about it.
                writer.unshift_from(&buf[0..len]);
                trace!("write done");
            }
            Err(e) => error!("{:?}", e),
        }
    //} else if twis.get_event_triggered(TwisInterrupt::Read, true) {
    //trace!("i²c read");
    } else {
        trace!("i²c unknown");
    }
}