Skip to content

Commit 301e215

Browse files
authored
Merge pull request #76 from torfmaster/syscall
ADC Support and new Error Types
2 parents fc221c8 + 41d6f71 commit 301e215

File tree

10 files changed

+258
-7
lines changed

10 files changed

+258
-7
lines changed

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,11 @@ to use:
4040
you will end up with a TAB file in `target/tab` that you can program onto your
4141
Tock board (e.g. with `tockloader install target/tab/blink.tab`).
4242

43+
If you have a hail board you can flash your device as follows:
44+
- set the environment variable `hail` to `1`
45+
- set `link-arg=-Tnrf52_layout.ld` in `.cargo/config` to `link-arg=-Thail_layout.ld`
46+
- run `run_example.sh` as above.
47+
4348
## Using libtock-rs
4449

4550
The easiest way to start using libtock-rs is adding an example to the examples folder.

examples/adc.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#![no_std]
2+
3+
use core::fmt::Write;
4+
use libtock::adc;
5+
use libtock::console::Console;
6+
use libtock::timer;
7+
use libtock::timer::Duration;
8+
9+
fn main() {
10+
let mut console = Console::new();
11+
let mut with_callback = adc::with_callback(|channel: usize, value: usize| {
12+
writeln!(console, "channel: {}, value: {}", channel, value).unwrap();
13+
});
14+
15+
let adc = with_callback.init().unwrap();
16+
17+
loop {
18+
adc.sample(0).unwrap();
19+
timer::sleep(Duration::from_ms(2000));
20+
}
21+
}

examples/adc_buffer.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#![no_std]
2+
3+
use core::fmt::Write;
4+
use libtock::adc;
5+
use libtock::adc::AdcBuffer;
6+
use libtock::console::Console;
7+
use libtock::syscalls;
8+
9+
/// Reads a 128 byte sample into a buffer and prints the first value to the console.
10+
fn main() {
11+
let mut console = Console::new();
12+
let mut adc_buffer = AdcBuffer::new();
13+
let mut temp_buffer = [0; libtock::adc::BUFFER_SIZE];
14+
15+
let adc_buffer = libtock::adc::Adc::init_buffer(&mut adc_buffer).unwrap();
16+
17+
let mut with_callback = adc::with_callback(|_, _| {
18+
adc_buffer.read_bytes(&mut temp_buffer);
19+
writeln!(console, "First sample in buffer: {}", temp_buffer[0]).unwrap();
20+
});
21+
22+
let adc = with_callback.init().unwrap();
23+
24+
loop {
25+
adc.sample_continuous_buffered(0, 128).unwrap();
26+
syscalls::yieldk();
27+
}
28+
}

hail_layout.ld

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/* Layout for the Hail board, used by the examples in this repository. */
2+
3+
MEMORY {
4+
/* The application region is 64 bytes (0x40) */
5+
FLASH (rx) : ORIGIN = 0x00030040, LENGTH = 0x0005FFC0
6+
SRAM (rwx) : ORIGIN = 0x20004000, LENGTH = 62K
7+
}
8+
9+
MPU_MIN_ALIGN = 8K;
10+
11+
INCLUDE layout.ld

run_example.sh

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,15 @@ cargo build --release --target=thumbv7em-none-eabi --example "$1"
1010
elf_file_name="target/tab/$1/cortex-m4.elf"
1111
tab_file_name="target/tab/$1.tab"
1212

13+
# Default value for nRF52-DK
14+
tockloader_flags="--jlink --arch cortex-m4 --board nrf52dk --jtag-device nrf52 --app-address 0x20000"
15+
16+
hail_defined=${hail:-}
17+
if [ -n "$hail_defined" ]
18+
then
19+
tockloader_flags=""
20+
fi
21+
1322
mkdir -p "target/tab/$1"
1423
cp "target/thumbv7em-none-eabi/release/examples/$1" "$elf_file_name"
1524

@@ -21,9 +30,9 @@ then
2130
then
2231
echo "do not delete apps from board."
2332
else
24-
tockloader uninstall --jlink --arch cortex-m4 --board nrf52dk --jtag-device nrf52 --app-address 0x20000 || true
33+
tockloader uninstall $tockloader_flags || true
2534
fi
2635
else
27-
tockloader uninstall --jlink --arch cortex-m4 --board nrf52dk --jtag-device nrf52 --app-address 0x20000 || true
36+
tockloader uninstall $tockloader_flags || true
2837
fi
29-
tockloader install --jlink --arch cortex-m4 --board nrf52dk --jtag-device nrf52 --app-address 0x20000 "$tab_file_name"
38+
tockloader install $tockloader_flags "$tab_file_name"

src/adc.rs

Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
use crate::callback::{CallbackSubscription, SubscribableCallback};
2+
use crate::shared_memory::SharedMemory;
3+
use crate::syscalls;
4+
5+
pub const DRIVER_NUM: usize = 0x0005;
6+
pub const BUFFER_SIZE: usize = 128;
7+
8+
mod command {
9+
pub const COUNT: usize = 0;
10+
pub const START: usize = 1;
11+
pub const START_REPEAT: usize = 2;
12+
pub const START_REPEAT_BUFFER: usize = 3;
13+
pub const START_REPEAT_BUFFER_ALT: usize = 4;
14+
pub const STOP: usize = 5;
15+
}
16+
17+
mod subscribe {
18+
pub const SUBSCRIBE_CALLBACK: usize = 0;
19+
}
20+
21+
mod allow {
22+
pub const BUFFER: usize = 0;
23+
pub const BUFFER_ALT: usize = 1;
24+
}
25+
26+
pub struct AdcBuffer {
27+
// TODO: make this generic if possible with the driver impl
28+
buffer: [u8; BUFFER_SIZE],
29+
}
30+
31+
impl AdcBuffer {
32+
pub fn new() -> AdcBuffer {
33+
AdcBuffer {
34+
buffer: [0; BUFFER_SIZE],
35+
}
36+
}
37+
}
38+
39+
pub struct Adc<'a> {
40+
count: usize,
41+
#[allow(dead_code)]
42+
subscription: CallbackSubscription<'a>,
43+
}
44+
45+
pub fn with_callback<CB>(callback: CB) -> WithCallback<CB> {
46+
WithCallback { callback }
47+
}
48+
49+
pub struct WithCallback<CB> {
50+
callback: CB,
51+
}
52+
53+
impl<CB: FnMut(usize, usize)> SubscribableCallback for WithCallback<CB> {
54+
fn call_rust(&mut self, _: usize, channel: usize, value: usize) {
55+
(self.callback)(channel, value);
56+
}
57+
}
58+
59+
impl<'a, CB> WithCallback<CB>
60+
where
61+
Self: SubscribableCallback,
62+
{
63+
pub fn init(&mut self) -> Result<Adc, isize> {
64+
let return_value = unsafe { syscalls::command(DRIVER_NUM, command::COUNT, 0, 0) };
65+
if return_value < 0 {
66+
return Err(return_value);
67+
}
68+
69+
syscalls::subscribe(DRIVER_NUM, subscribe::SUBSCRIBE_CALLBACK, self).map(|subscription| {
70+
Adc {
71+
count: return_value as usize,
72+
subscription,
73+
}
74+
})
75+
}
76+
}
77+
78+
impl<'a> Adc<'a> {
79+
pub fn init_buffer(buffer: &'a mut AdcBuffer) -> Result<SharedMemory, isize> {
80+
syscalls::allow(DRIVER_NUM, allow::BUFFER, &mut buffer.buffer)
81+
}
82+
83+
pub fn init_alt_buffer(alt_buffer: &'a mut AdcBuffer) -> Result<SharedMemory, isize> {
84+
syscalls::allow(DRIVER_NUM, allow::BUFFER_ALT, &mut alt_buffer.buffer)
85+
}
86+
87+
/// Return the number of available channels
88+
pub fn count(&self) -> usize {
89+
self.count
90+
}
91+
92+
/// Start a single sample of channel
93+
pub fn sample(&self, channel: usize) -> Result<(), isize> {
94+
unsafe {
95+
let code = syscalls::command(DRIVER_NUM, command::START, channel, 0);
96+
if code < 0 {
97+
Err(code)
98+
} else {
99+
Ok(())
100+
}
101+
}
102+
}
103+
104+
/// Start continuous sampling of channel
105+
pub fn sample_continuous(&self, channel: usize) -> Result<(), isize> {
106+
unsafe {
107+
let code = syscalls::command(DRIVER_NUM, command::START_REPEAT, channel, 0);
108+
if code < 0 {
109+
Err(code)
110+
} else {
111+
Ok(())
112+
}
113+
}
114+
}
115+
116+
/// Start continuous sampling to first buffer
117+
pub fn sample_continuous_buffered(
118+
&self,
119+
channel: usize,
120+
frequency: usize,
121+
) -> Result<(), isize> {
122+
unsafe {
123+
let code =
124+
syscalls::command(DRIVER_NUM, command::START_REPEAT_BUFFER, channel, frequency);
125+
if code < 0 {
126+
Err(code)
127+
} else {
128+
Ok(())
129+
}
130+
}
131+
}
132+
133+
/// Start continuous sampling to alternating buffer
134+
pub fn sample_continuous_buffered_alt(
135+
&self,
136+
channel: usize,
137+
frequency: usize,
138+
) -> Result<(), isize> {
139+
unsafe {
140+
let code = syscalls::command(
141+
DRIVER_NUM,
142+
command::START_REPEAT_BUFFER_ALT,
143+
channel,
144+
frequency,
145+
);
146+
if code < 0 {
147+
Err(code)
148+
} else {
149+
Ok(())
150+
}
151+
}
152+
}
153+
154+
/// Stop any started sampling operation
155+
pub fn stop(&self) -> Result<(), isize> {
156+
unsafe {
157+
let code = syscalls::command(DRIVER_NUM, command::STOP, 0, 0);
158+
if code < 0 {
159+
Err(code)
160+
} else {
161+
Ok(())
162+
}
163+
}
164+
}
165+
}
166+
167+
impl<'a> Drop for Adc<'a> {
168+
fn drop(&mut self) {
169+
self.stop().unwrap();
170+
}
171+
}

src/lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ extern crate alloc;
1212

1313
mod callback;
1414

15+
pub mod adc;
1516
pub mod ble_composer;
1617
pub mod ble_parser;
1718
pub mod buttons;
@@ -30,10 +31,13 @@ pub mod unwind_symbols;
3031

3132
#[cfg(target_arch = "arm")]
3233
pub mod entry_point;
34+
3335
#[cfg(target_arch = "arm")]
3436
mod lang_items;
37+
3538
#[cfg(target_arch = "arm")]
3639
pub mod syscalls;
40+
3741
#[cfg(not(target_arch = "arm"))]
3842
#[path = "syscalls_mock.rs"]
3943
mod syscalls;

src/result.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ impl<T, E> TockResultExt<T, E> for TockResult<T, E> {
2121
}
2222

2323
pub const SUCCESS: isize = 0;
24+
pub const FAIL: isize = -1;
25+
pub const EBUSY: isize = -2;
2426
pub const EALREADY: isize = -3;
2527
pub const EINVAL: isize = -6;
2628
pub const ESIZE: isize = -7;

src/sensors/mod.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,9 @@ macro_rules! single_value_sensor {
6363
};
6464
}
6565

66-
single_value_sensor!(AmbientLightSensor, AmbientLight, 6);
67-
single_value_sensor!(TemperatureSensor, Temperature, 10);
68-
single_value_sensor!(HumiditySensor, Humidity, 35);
66+
single_value_sensor!(AmbientLightSensor, AmbientLight, 0x60002);
67+
single_value_sensor!(TemperatureSensor, Temperature, 0x60000);
68+
single_value_sensor!(HumiditySensor, Humidity, 0x60001);
6969

7070
impl fmt::Display for AmbientLight {
7171
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {

src/sensors/ninedof.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,5 +71,5 @@ pub unsafe fn start_accel_reading() {
7171
}
7272

7373
pub unsafe fn start_magnetometer_reading() {
74-
syscalls::command(DRIVER_NUM, 1, 0, 0);
74+
syscalls::command(DRIVER_NUM, 100, 0, 0);
7575
}

0 commit comments

Comments
 (0)