Skip to content

Commit be8e7e0

Browse files
Merge pull request #230 from kalkyl/twis-dma
Non-blocking TWIS, use embedded-dma
2 parents 70d34ae + 6003c00 commit be8e7e0

File tree

7 files changed

+444
-37
lines changed

7 files changed

+444
-37
lines changed

examples/twis-demo/src/main.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ const APP: () = {
4343
let sda = p0.p0_16.into_floating_input().degrade();
4444

4545
let twis = Twis::new(ctx.device.TWIS0, Pins { scl, sda }, ADDR0);
46-
twis.address1(ADDR1) // Add a secondary i2c address
46+
twis.set_address1(ADDR1) // Add a secondary i2c address
4747
.enable_interrupt(TwiEvent::Write) // Trigger interrupt on WRITE command
4848
.enable_interrupt(TwiEvent::Read) // Trigger interrupt on READ command
4949
.enable();
@@ -73,11 +73,11 @@ const APP: () = {
7373
rprintln!("Writing data to controller...");
7474
match twis.address_match() {
7575
ADDR0 => {
76-
let res = twis.tx(&buffer0[..]);
76+
let res = twis.tx_blocking(&buffer0[..]);
7777
rprintln!("Result: {:?}\n{:?}", res, buffer0);
7878
}
7979
ADDR1 => {
80-
let res = twis.tx(&buffer1[..]);
80+
let res = twis.tx_blocking(&buffer1[..]);
8181
rprintln!("Result: {:?}\n{:?}", res, buffer1);
8282
}
8383
_ => unreachable!(),
@@ -90,11 +90,11 @@ const APP: () = {
9090
rprintln!("Reading data from controller...");
9191
match twis.address_match() {
9292
ADDR0 => {
93-
let res = twis.rx(&mut buffer0[..]);
93+
let res = twis.rx_blocking(&mut buffer0[..]);
9494
rprintln!("Result: {:?}\n{:?}", res, buffer0);
9595
}
9696
ADDR1 => {
97-
let res = twis.rx(&mut buffer1[..]);
97+
let res = twis.rx_blocking(&mut buffer1[..]);
9898
rprintln!("Result: {:?}\n{:?}", res, buffer1);
9999
}
100100
_ => unreachable!(),

examples/twis-dma-demo/Cargo.toml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
[package]
2+
name = "twis-dma-demo"
3+
version = "0.1.0"
4+
authors = ["Henrik Alsér"]
5+
edition = "2018"
6+
7+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
8+
9+
[dependencies]
10+
cortex-m = "0.6.2"
11+
cortex-m-rtic = "0.5.3"
12+
rtt-target = {version = "0.2.0", features = ["cortex-m"] }
13+
nrf52840-hal = { features = ["rt"], path = "../../nrf52840-hal" }
14+
15+
[dependencies.embedded-hal]
16+
version = "0.2.3"
17+
features = ["unproven"]

examples/twis-dma-demo/Embed.toml

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
[default.probe]
2+
# The index of the probe in the connected probe list.
3+
# probe_index = 0
4+
# The protocol to be used for communicating with the target.
5+
protocol = "Swd"
6+
# The speed in kHz of the data link to the target.
7+
# speed = 1337
8+
9+
[default.flashing]
10+
# Whether or not the target should be flashed.
11+
enabled = true
12+
# Whether or not the target should be halted after flashing.
13+
halt_afterwards = false
14+
# Whether or not bytes erased but not rewritten with data from the ELF
15+
# should be restored with their contents before erasing.
16+
restore_unwritten_bytes = false
17+
# The path where an SVG of the assembled flash layout should be written to.
18+
# flash_layout_output_path = "out.svg"
19+
20+
[default.general]
21+
# The chip name of the chip to be debugged.
22+
chip = "nRF52840"
23+
# A list of chip descriptions to be loaded during runtime.
24+
chip_descriptions = []
25+
# The default log level to be used.
26+
log_level = "Warn"
27+
28+
[default.rtt]
29+
# Whether or not an RTTUI should be opened after flashing.
30+
# This is exclusive and cannot be used with GDB at the moment.
31+
enabled = true
32+
# A list of channel associations to be displayed. If left empty, all channels are displayed.
33+
channels = [
34+
# { up = 0, down = 0, name = "name" }
35+
]
36+
# The duration in ms for which the logger should retry to attach to RTT.
37+
timeout = 3000
38+
# Whether timestamps in the RTTUI are enabled
39+
show_timestamps = true
40+
41+
[default.gdb]
42+
# Whether or not a GDB server should be opened after flashing.
43+
# This is exclusive and cannot be used with RTT at the moment.
44+
enabled = false
45+
# The connection string in host:port format wher the GDB server will open a socket.
46+
# gdb_connection_string

examples/twis-dma-demo/src/main.rs

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
#![no_std]
2+
#![no_main]
3+
4+
// Demo of using non-blocking DMA transactions with the
5+
// TWIS (Two Wire Interface/I2C in peripheral mode) module.
6+
7+
use {
8+
core::{
9+
panic::PanicInfo,
10+
sync::atomic::{compiler_fence, Ordering},
11+
},
12+
hal::{gpio::p0::Parts, gpiote::Gpiote, pac::TWIS0, twis::*},
13+
nrf52840_hal as hal,
14+
rtt_target::{rprintln, rtt_init_print},
15+
};
16+
17+
type DmaBuffer = &'static mut [u8; 8];
18+
19+
pub enum TwisTransfer {
20+
Running(Transfer<TWIS0, DmaBuffer>),
21+
Idle((DmaBuffer, Twis<TWIS0>)),
22+
}
23+
24+
#[rtic::app(device = crate::hal::pac, peripherals = true)]
25+
const APP: () = {
26+
struct Resources {
27+
gpiote: Gpiote,
28+
transfer: Option<TwisTransfer>,
29+
}
30+
31+
#[init]
32+
fn init(ctx: init::Context) -> init::LateResources {
33+
static mut BUF: [u8; 8] = [0; 8];
34+
let _clocks = hal::clocks::Clocks::new(ctx.device.CLOCK).enable_ext_hfosc();
35+
rtt_init_print!();
36+
rprintln!("Waiting for commands from controller...");
37+
38+
let p0 = Parts::new(ctx.device.P0);
39+
let scl = p0.p0_14.into_floating_input().degrade();
40+
let sda = p0.p0_16.into_floating_input().degrade();
41+
42+
let twis = Twis::new(ctx.device.TWIS0, Pins { scl, sda }, 0x1A);
43+
twis.enable_interrupt(TwiEvent::Write)
44+
.enable_interrupt(TwiEvent::Read)
45+
.enable_interrupt(TwiEvent::Stopped)
46+
.enable();
47+
48+
let btn = p0.p0_29.into_pullup_input().degrade();
49+
let gpiote = Gpiote::new(ctx.device.GPIOTE);
50+
gpiote.port().input_pin(&btn).low();
51+
gpiote.port().enable_interrupt();
52+
53+
init::LateResources {
54+
gpiote,
55+
transfer: Some(TwisTransfer::Idle((BUF, twis))),
56+
}
57+
}
58+
59+
#[task(binds = GPIOTE, resources = [gpiote, transfer])]
60+
fn on_gpiote(ctx: on_gpiote::Context) {
61+
ctx.resources.gpiote.reset_events();
62+
rprintln!("Reset buffer");
63+
let transfer = ctx.resources.transfer;
64+
let (buf, twis) = match transfer.take().unwrap() {
65+
TwisTransfer::Running(t) => t.wait(),
66+
TwisTransfer::Idle(t) => t,
67+
};
68+
buf.copy_from_slice(&[0; 8][..]);
69+
rprintln!("{:?}", buf);
70+
transfer.replace(TwisTransfer::Idle((buf, twis)));
71+
}
72+
73+
#[task(binds = SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0, resources = [transfer])]
74+
fn on_twis(ctx: on_twis::Context) {
75+
let transfer = ctx.resources.transfer;
76+
let (buf, twis) = match transfer.take().unwrap() {
77+
TwisTransfer::Running(t) => t.wait(),
78+
TwisTransfer::Idle(t) => t,
79+
};
80+
if twis.is_event_triggered(TwiEvent::Read) {
81+
twis.reset_event(TwiEvent::Read);
82+
rprintln!("READ command received");
83+
let tx = twis.tx(buf).unwrap();
84+
transfer.replace(TwisTransfer::Running(tx));
85+
} else if twis.is_event_triggered(TwiEvent::Write) {
86+
twis.reset_event(TwiEvent::Write);
87+
rprintln!("WRITE command received");
88+
let rx = twis.rx(buf).unwrap();
89+
transfer.replace(TwisTransfer::Running(rx));
90+
} else {
91+
twis.reset_event(TwiEvent::Stopped);
92+
rprintln!("{:?}", buf);
93+
transfer.replace(TwisTransfer::Idle((buf, twis)));
94+
}
95+
}
96+
};
97+
98+
#[inline(never)]
99+
#[panic_handler]
100+
fn panic(info: &PanicInfo) -> ! {
101+
cortex_m::interrupt::disable();
102+
rprintln!("{}", info);
103+
loop {
104+
compiler_fence(Ordering::SeqCst);
105+
}
106+
}

nrf-hal-common/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ pub mod timer;
7070
pub mod twi;
7171
#[cfg(not(feature = "51"))]
7272
pub mod twim;
73-
#[cfg(not(any(feature = "51", feature = "9160")))]
73+
#[cfg(not(feature = "51"))]
7474
pub mod twis;
7575
#[cfg(feature = "51")]
7676
pub mod uart;

0 commit comments

Comments
 (0)