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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
|
use log::info;
use nrf52840_hal::uarte::{self, Uarte};
use starb::{Reader, RingBuffer, Writer};
static mut RB: RingBuffer<u8> = RingBuffer::new(0);
pub fn setup<I>(mut uarte: Uarte<I>) -> (Reader<'static, u8>, impl FnMut())
where
I: uarte::Instance,
{
uarte.0.intenset.write(|w| {
w.endrx().set_bit();
w.error().set_bit();
w.rxto().set_bit();
w.rxstarted().set_bit()
});
let mut buf: [u8; 255] = [0; 255];
uarte
.0
.rxd
.ptr
.write(|w| unsafe { w.ptr().bits(buf.as_mut_ptr() as _) });
uarte
.0
.rxd
.maxcnt
.write(|w| unsafe { w.maxcnt().bits(buf.len() as _) });
uarte.0.tasks_startrx.write(|w| w.tasks_startrx().set_bit());
let (rbr, mut rbw) = unsafe { RB.split() };
// start rx into a buffer. it would be nice if we could do this
// with rxrdy or something like i2c does.
let cl = move || handler(&mut uarte, &mut rbw, &mut buf);
(rbr, cl)
}
fn handler<I>(uarte: &mut Uarte<I>, writer: &mut Writer<u8>, buf: &mut [u8])
where
I: uarte::Instance,
{
if uarte.0.events_endrx.read().events_endrx().bit_is_set() {
uarte.0.events_endrx.write(|w| w.events_endrx().clear_bit());
// Copy DMA buffer to ring buffer.
let len = uarte.0.rxd.amount.read().amount().bits();
info!("endrx - {}", len);
for i in 0..len {
writer.unshift(buf[i as usize]).ok();
}
// Reset the DMA buffer. TODO: this is probably unneccesary.
uarte
.0
.rxd
.ptr
.write(|w| unsafe { w.ptr().bits(buf.as_mut_ptr() as _) });
uarte
.0
.rxd
.maxcnt
.write(|w| unsafe { w.maxcnt().bits(buf.len() as _) });
// restart the read.
uarte.0.tasks_startrx.write(|w| w.tasks_startrx().set_bit());
} else if uarte.0.events_error.read().events_error().bit_is_set() {
uarte.0.events_error.write(|w| w.events_error().clear_bit());
info!("error: {:b}", uarte.0.errorsrc.read().bits());
} else if uarte.0.events_rxto.read().events_rxto().bit_is_set() {
uarte.0.events_rxto.write(|w| w.events_rxto().clear_bit());
info!("rxto");
} else if uarte
.0
.events_rxstarted
.read()
.events_rxstarted()
.bit_is_set()
{
uarte
.0
.events_rxstarted
.write(|w| w.events_rxstarted().clear_bit());
info!("rxstarted");
}
}
|