aboutsummaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2024-09-09 20:03:28 +0000
committerGitHub <[email protected]>2024-09-09 20:03:28 +0000
commit2286e5da13b11f0cfc37e5345e3ed3c40f774055 (patch)
tree5afa31997e3dd024135151ce64813f5db478569b /examples
parent0ef06cc19b61c8196fea941514ec313a0f15d145 (diff)
parent6af1cb7a20fe15750b353e2e6af6832786f8c065 (diff)
Merge pull request #3105 from embassy-rs/net-nrf91
embassy-net driver for nrf91
Diffstat (limited to 'examples')
-rw-r--r--examples/nrf9160/.cargo/config.toml3
-rw-r--r--examples/nrf9160/Cargo.toml6
-rw-r--r--examples/nrf9160/memory.x8
-rw-r--r--examples/nrf9160/src/bin/modem_tcp_client.rs204
4 files changed, 218 insertions, 3 deletions
diff --git a/examples/nrf9160/.cargo/config.toml b/examples/nrf9160/.cargo/config.toml
index f64c63966..6072b8595 100644
--- a/examples/nrf9160/.cargo/config.toml
+++ b/examples/nrf9160/.cargo/config.toml
@@ -1,5 +1,6 @@
1[target.'cfg(all(target_arch = "arm", target_os = "none"))'] 1[target.'cfg(all(target_arch = "arm", target_os = "none"))']
2runner = "probe-rs run --chip nRF9160_xxAA" 2# runner = "probe-rs run --chip nRF9160_xxAA"
3runner = [ "probe-rs", "run", "--chip=nRF9160_xxAA", "--always-print-stacktrace", "--log-format={t} {[{L}]%bold} {s} {{c} {ff}:{l:1}%dimmed}" ]
3 4
4[build] 5[build]
5target = "thumbv8m.main-none-eabihf" 6target = "thumbv8m.main-none-eabihf"
diff --git a/examples/nrf9160/Cargo.toml b/examples/nrf9160/Cargo.toml
index c30b54ebd..9aeb99317 100644
--- a/examples/nrf9160/Cargo.toml
+++ b/examples/nrf9160/Cargo.toml
@@ -8,13 +8,19 @@ license = "MIT OR Apache-2.0"
8embassy-executor = { version = "0.6.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] } 8embassy-executor = { version = "0.6.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] }
9embassy-time = { version = "0.3.2", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } 9embassy-time = { version = "0.3.2", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] }
10embassy-nrf = { version = "0.2.0", path = "../../embassy-nrf", features = ["defmt", "nrf9160-s", "time-driver-rtc1", "gpiote", "unstable-pac", "time"] } 10embassy-nrf = { version = "0.2.0", path = "../../embassy-nrf", features = ["defmt", "nrf9160-s", "time-driver-rtc1", "gpiote", "unstable-pac", "time"] }
11embassy-net-nrf91 = { version = "0.1.0", path = "../../embassy-net-nrf91", features = ["defmt"] }
12embassy-net = { version = "0.4.0", path = "../../embassy-net", features = ["defmt", "tcp", "proto-ipv4", "medium-ip"] }
11 13
12defmt = "0.3" 14defmt = "0.3"
13defmt-rtt = "0.4" 15defmt-rtt = "0.4"
14 16
17heapless = "0.8"
15cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } 18cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] }
16cortex-m-rt = "0.7.0" 19cortex-m-rt = "0.7.0"
17panic-probe = { version = "0.3", features = ["print-defmt"] } 20panic-probe = { version = "0.3", features = ["print-defmt"] }
21static_cell = { version = "2" }
22embedded-io = "0.6.1"
23embedded-io-async = { version = "0.6.1", features = ["defmt-03"] }
18 24
19[profile.release] 25[profile.release]
20debug = 2 26debug = 2
diff --git a/examples/nrf9160/memory.x b/examples/nrf9160/memory.x
index 4c7d4ebf0..e33498773 100644
--- a/examples/nrf9160/memory.x
+++ b/examples/nrf9160/memory.x
@@ -1,5 +1,9 @@
1MEMORY 1MEMORY
2{ 2{
3 FLASH : ORIGIN = 0x00000000, LENGTH = 1024K 3 FLASH : ORIGIN = 0x00000000, LENGTH = 1024K
4 RAM : ORIGIN = 0x20018000, LENGTH = 160K 4 RAM : ORIGIN = 0x20010000, LENGTH = 192K
5 IPC : ORIGIN = 0x20000000, LENGTH = 64K
5} 6}
7
8PROVIDE(__start_ipc = ORIGIN(IPC));
9PROVIDE(__end_ipc = ORIGIN(IPC) + LENGTH(IPC));
diff --git a/examples/nrf9160/src/bin/modem_tcp_client.rs b/examples/nrf9160/src/bin/modem_tcp_client.rs
new file mode 100644
index 000000000..5335b6b51
--- /dev/null
+++ b/examples/nrf9160/src/bin/modem_tcp_client.rs
@@ -0,0 +1,204 @@
1#![no_std]
2#![no_main]
3
4use core::mem::MaybeUninit;
5use core::net::IpAddr;
6use core::ptr::addr_of_mut;
7use core::slice;
8use core::str::FromStr;
9
10use defmt::{info, unwrap, warn};
11use embassy_executor::Spawner;
12use embassy_net::{Ipv4Address, Ipv4Cidr, Stack, StackResources};
13use embassy_net_nrf91::context::Status;
14use embassy_net_nrf91::{context, Runner, State, TraceBuffer, TraceReader};
15use embassy_nrf::buffered_uarte::{self, BufferedUarteTx};
16use embassy_nrf::gpio::{AnyPin, Level, Output, OutputDrive, Pin};
17use embassy_nrf::uarte::Baudrate;
18use embassy_nrf::{bind_interrupts, interrupt, peripherals, uarte};
19use embassy_time::{Duration, Timer};
20use embedded_io_async::Write;
21use heapless::Vec;
22use static_cell::StaticCell;
23use {defmt_rtt as _, panic_probe as _};
24
25#[interrupt]
26fn IPC() {
27 embassy_net_nrf91::on_ipc_irq();
28}
29
30bind_interrupts!(struct Irqs {
31 UARTE0_SPIM0_SPIS0_TWIM0_TWIS0 => buffered_uarte::InterruptHandler<peripherals::SERIAL0>;
32});
33
34#[embassy_executor::task]
35async fn trace_task(mut uart: BufferedUarteTx<'static, peripherals::SERIAL0>, reader: TraceReader<'static>) -> ! {
36 let mut rx = [0u8; 1024];
37 loop {
38 let n = reader.read(&mut rx[..]).await;
39 unwrap!(uart.write_all(&rx[..n]).await);
40 }
41}
42
43#[embassy_executor::task]
44async fn modem_task(runner: Runner<'static>) -> ! {
45 runner.run().await
46}
47
48#[embassy_executor::task]
49async fn net_task(stack: &'static Stack<embassy_net_nrf91::NetDriver<'static>>) -> ! {
50 stack.run().await
51}
52
53#[embassy_executor::task]
54async fn control_task(
55 control: &'static context::Control<'static>,
56 config: context::Config<'static>,
57 stack: &'static Stack<embassy_net_nrf91::NetDriver<'static>>,
58) {
59 unwrap!(control.configure(&config).await);
60 unwrap!(
61 control
62 .run(|status| {
63 stack.set_config_v4(status_to_config(status));
64 })
65 .await
66 );
67}
68
69fn status_to_config(status: &Status) -> embassy_net::ConfigV4 {
70 let Some(IpAddr::V4(addr)) = status.ip else {
71 panic!("Unexpected IP address");
72 };
73 let addr = Ipv4Address(addr.octets());
74
75 let gateway = if let Some(IpAddr::V4(addr)) = status.gateway {
76 Some(Ipv4Address(addr.octets()))
77 } else {
78 None
79 };
80
81 let mut dns_servers = Vec::new();
82 for dns in status.dns.iter() {
83 if let IpAddr::V4(ip) = dns {
84 unwrap!(dns_servers.push(Ipv4Address(ip.octets())));
85 }
86 }
87
88 embassy_net::ConfigV4::Static(embassy_net::StaticConfigV4 {
89 address: Ipv4Cidr::new(addr, 32),
90 gateway,
91 dns_servers,
92 })
93}
94
95#[embassy_executor::task]
96async fn blink_task(pin: AnyPin) {
97 let mut led = Output::new(pin, Level::Low, OutputDrive::Standard);
98 loop {
99 led.set_high();
100 Timer::after_millis(1000).await;
101 led.set_low();
102 Timer::after_millis(1000).await;
103 }
104}
105
106extern "C" {
107 static __start_ipc: u8;
108 static __end_ipc: u8;
109}
110
111#[embassy_executor::main]
112async fn main(spawner: Spawner) {
113 let p = embassy_nrf::init(Default::default());
114
115 info!("Hello World!");
116
117 unwrap!(spawner.spawn(blink_task(p.P0_02.degrade())));
118
119 let ipc_mem = unsafe {
120 let ipc_start = &__start_ipc as *const u8 as *mut MaybeUninit<u8>;
121 let ipc_end = &__end_ipc as *const u8 as *mut MaybeUninit<u8>;
122 let ipc_len = ipc_end.offset_from(ipc_start) as usize;
123 slice::from_raw_parts_mut(ipc_start, ipc_len)
124 };
125
126 static mut TRACE_BUF: [u8; 4096] = [0u8; 4096];
127 let mut config = uarte::Config::default();
128 config.baudrate = Baudrate::BAUD1M;
129 let uart = BufferedUarteTx::new(
130 //let trace_uart = BufferedUarteTx::new(
131 unsafe { peripherals::SERIAL0::steal() },
132 Irqs,
133 unsafe { peripherals::P0_01::steal() },
134 //unsafe { peripherals::P0_14::steal() },
135 config,
136 unsafe { &mut *addr_of_mut!(TRACE_BUF) },
137 );
138
139 static STATE: StaticCell<State> = StaticCell::new();
140 static TRACE: StaticCell<TraceBuffer> = StaticCell::new();
141 let (device, control, runner, tracer) =
142 embassy_net_nrf91::new_with_trace(STATE.init(State::new()), ipc_mem, TRACE.init(TraceBuffer::new())).await;
143 unwrap!(spawner.spawn(modem_task(runner)));
144 unwrap!(spawner.spawn(trace_task(uart, tracer)));
145
146 let config = embassy_net::Config::default();
147
148 // Generate "random" seed. nRF91 has no RNG, TODO figure out something...
149 let seed = 123456;
150
151 // Init network stack
152 static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new();
153 static STACK: StaticCell<Stack<embassy_net_nrf91::NetDriver<'static>>> = StaticCell::new();
154 let stack = &*STACK.init(Stack::new(
155 device,
156 config,
157 RESOURCES.init(StackResources::<2>::new()),
158 seed,
159 ));
160
161 unwrap!(spawner.spawn(net_task(stack)));
162
163 static CONTROL: StaticCell<context::Control<'static>> = StaticCell::new();
164 let control = CONTROL.init(context::Control::new(control, 0).await);
165
166 unwrap!(spawner.spawn(control_task(
167 control,
168 context::Config {
169 apn: b"iot.nat.es",
170 auth_prot: context::AuthProt::Pap,
171 auth: Some((b"orange", b"orange")),
172 },
173 stack
174 )));
175
176 stack.wait_config_up().await;
177
178 let mut rx_buffer = [0; 4096];
179 let mut tx_buffer = [0; 4096];
180 loop {
181 let mut socket = embassy_net::tcp::TcpSocket::new(stack, &mut rx_buffer, &mut tx_buffer);
182 socket.set_timeout(Some(Duration::from_secs(10)));
183
184 info!("Connecting...");
185 let host_addr = embassy_net::Ipv4Address::from_str("45.79.112.203").unwrap();
186 if let Err(e) = socket.connect((host_addr, 4242)).await {
187 warn!("connect error: {:?}", e);
188 Timer::after_secs(10).await;
189 continue;
190 }
191 info!("Connected to {:?}", socket.remote_endpoint());
192
193 let msg = b"Hello world!\n";
194 for _ in 0..10 {
195 if let Err(e) = socket.write_all(msg).await {
196 warn!("write error: {:?}", e);
197 break;
198 }
199 info!("txd: {}", core::str::from_utf8(msg).unwrap());
200 Timer::after_secs(1).await;
201 }
202 Timer::after_secs(4).await;
203 }
204}