Skip to content

Commit

Permalink
enhancement(example): rp2040 + lara-r6 example (#100)
Browse files Browse the repository at this point in the history
* add APNInfo to config as const

* change apn settings to enum

* update dependencies to new embassy release

* can establish psd context and a dns request works

* move statemachine out of main runner select loop

* a bit of formatting

* update to newest atat changes

* Add RP2040 example

---------

Co-authored-by: Tobias Breitwieser <tobias@breitwieser.biz>
  • Loading branch information
MathiasKoch and tarfu committed Feb 15, 2024
1 parent dc4f74a commit 5e654f0
Show file tree
Hide file tree
Showing 8 changed files with 335 additions and 0 deletions.
8 changes: 8 additions & 0 deletions examples/embassy-rp2040-example/.cargo/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[target.thumbv6m-none-eabi]
runner = 'probe-rs run --chip RP2040'

[build]
target = "thumbv6m-none-eabi"

[env]
DEFMT_LOG = "trace,embassy_hal_internal=error"
9 changes: 9 additions & 0 deletions examples/embassy-rp2040-example/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
**/*.rs.bk
.#*
.gdb_history
*.fifo
target/
*.o
**/*secrets*

.DS_Store
47 changes: 47 additions & 0 deletions examples/embassy-rp2040-example/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
[package]
name = "embassy-rp2040-example"
version = "0.1.0"
edition = "2021"

[dependencies]
embassy-rp = { version = "0.1.0", features = ["defmt", "time-driver", "unstable-pac", "rom-v2-intrinsics", "critical-section-impl"] }
embassy-executor = { version = "0.5.0", features = ["arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] }
embassy-time = { version = "0.3", features = ["defmt", "defmt-timestamp-uptime"] }
embassy-sync = { version = "0.5", features = ["defmt"] }
portable-atomic = { version = "1.5.1", features = ["critical-section"] }

cortex-m = { version = "0.7.7", features = ["inline-asm"] }
cortex-m-rt = "0.7.3"

defmt = "0.3.5"
defmt-rtt = "0.4.0"
panic-probe = { version = "0.3.1", features = ["print-defmt"] }

static_cell = { version = "2.0", features = []}

atat = { version = "0.21.0", features = ["derive", "bytes", "defmt"] }
ublox-cellular-rs = {version = "0.4.0", path = "../..", features = ["lara-r6", "defmt", "async"]}

[patch.crates-io]
ublox-sockets = { git = "https://github.com/BlackbirdHQ/ublox-sockets", branch = "feature/async-borrowed-sockets" }
atat = { git = "https://github.com/BlackbirdHQ/atat", branch = "master" }
no-std-net = { git = "https://github.com/rushmorem/no-std-net", branch = "issue-15" }
embassy-rp = { git = "https://github.com/embassy-rs/embassy", branch = "main" }
embassy-time = { git = "https://github.com/embassy-rs/embassy", branch = "main" }
embassy-sync = { git = "https://github.com/embassy-rs/embassy", branch = "main" }
embassy-futures = { git = "https://github.com/embassy-rs/embassy", branch = "main" }
embassy-executor = { git = "https://github.com/embassy-rs/embassy", branch = "main" }

#embassy-time = { path = "../../../embassy/embassy-time" }
#embassy-sync = { path = "../../../embassy/embassy-sync" }
#embassy-futures = { path = "../../../embassy/embassy-futures" }
#embassy-executor = { path = "../../../embassy/embassy-executor" }

#ublox-sockets = { path = "../../../ublox-sockets" }
#atat = { path = "../../../atat/atat" }

[profile.dev]
opt-level = "s"

[profile.release]
opt-level = "s"
6 changes: 6 additions & 0 deletions examples/embassy-rp2040-example/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
fn main() {
println!("cargo:rustc-link-arg-bins=--nmagic");
println!("cargo:rustc-link-arg-bins=-Tlink.x");
println!("cargo:rustc-link-arg-bins=-Tlink-rp.x");
println!("cargo:rustc-link-arg-bins=-Tdefmt.x");
}
5 changes: 5 additions & 0 deletions examples/embassy-rp2040-example/memory.x
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
MEMORY {
BOOT2 : ORIGIN = 0x10000000, LENGTH = 0x100
FLASH : ORIGIN = 0x10000100, LENGTH = 1024K - 0x100
RAM : ORIGIN = 0x20000000, LENGTH = 256K
}
14 changes: 14 additions & 0 deletions examples/embassy-rp2040-example/rust-toolchain.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Before upgrading check that everything is available on all tier1 targets here:
# https://rust-lang.github.io/rustup-components-history
[toolchain]
channel = "1.75"
components = [ "rust-src", "rustfmt", "llvm-tools" ]
targets = [
"thumbv7em-none-eabi",
"thumbv7m-none-eabi",
"thumbv6m-none-eabi",
"thumbv7em-none-eabihf",
"thumbv8m.main-none-eabihf",
"riscv32imac-unknown-none-elf",
"wasm32-unknown-unknown",
]
237 changes: 237 additions & 0 deletions examples/embassy-rp2040-example/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,237 @@
#![no_std]
#![no_main]
#![allow(stable_features)]

use atat::asynch::Client;

use atat::ResponseSlot;
use atat::UrcChannel;

use cortex_m_rt::entry;
use defmt::*;
use embassy_executor::{Executor, Spawner};
use embassy_rp::gpio;
use embassy_rp::gpio::Input;

use embassy_rp::gpio::OutputOpenDrain;
use embassy_rp::uart::BufferedUart;
use embassy_rp::uart::BufferedUartRx;
use embassy_rp::uart::BufferedUartTx;
use embassy_rp::{bind_interrupts, peripherals::UART0, uart::BufferedInterruptHandler};
use embassy_time::{Duration, Timer};
use static_cell::StaticCell;
use {defmt_rtt as _, panic_probe as _};

use ublox_cellular::config::{Apn, CellularConfig};

use atat::{AtatIngress, DefaultDigester, Ingress};
use ublox_cellular::asynch::runner::Runner;
use ublox_cellular::asynch::state::OperationState;
use ublox_cellular::asynch::State;
use ublox_cellular::command;
use ublox_cellular::command::Urc;

bind_interrupts!(struct Irqs {
UART0_IRQ => BufferedInterruptHandler<UART0>;
});

const INGRESS_BUF_SIZE: usize = 1024;
const URC_CAPACITY: usize = 2;
const URC_SUBSCRIBERS: usize = 2;

struct MyCelullarConfig {
reset_pin: Option<OutputOpenDrain<'static>>,
power_pin: Option<OutputOpenDrain<'static>>,
vint_pin: Option<Input<'static>>,
}

impl<'a> CellularConfig<'a> for MyCelullarConfig {
type ResetPin = OutputOpenDrain<'static>;
type PowerPin = OutputOpenDrain<'static>;
type VintPin = Input<'static>;

const FLOW_CONTROL: bool = true;
const HEX_MODE: bool = true;
const APN: Apn<'a> = Apn::Given {
name: "em",
username: None,
password: None,
};
fn reset_pin(&mut self) -> Option<&mut Self::ResetPin> {
info!("reset_pin");
self.reset_pin.as_mut()
}
fn power_pin(&mut self) -> Option<&mut Self::PowerPin> {
info!("power_pin");
self.power_pin.as_mut()
}
fn vint_pin(&mut self) -> Option<&mut Self::VintPin> {
info!("vint_pin = {}", self.vint_pin.as_mut()?.is_high());
self.vint_pin.as_mut()
}
}

#[embassy_executor::task]
async fn main_task(spawner: Spawner) {
let p = {
let config =
embassy_rp::config::Config::new(embassy_rp::clocks::ClockConfig::crystal(12_000_000));
embassy_rp::init(config)
};

static TX_BUF: StaticCell<[u8; 16]> = StaticCell::new();
static RX_BUF: StaticCell<[u8; 16]> = StaticCell::new();
static INGRESS_BUF: StaticCell<[u8; INGRESS_BUF_SIZE]> = StaticCell::new();

let mut cell_uart_config = embassy_rp::uart::Config::default();
cell_uart_config.baudrate = 115200;

let cell_uart = BufferedUart::new_with_rtscts(
p.UART0,
Irqs,
p.PIN_0,
p.PIN_1,
p.PIN_3,
p.PIN_2,
TX_BUF.init([0; 16]),
RX_BUF.init([0; 16]),
cell_uart_config,
);

let (uart_rx, uart_tx) = cell_uart.split();
let cell_nrst = gpio::OutputOpenDrain::new(p.PIN_4, gpio::Level::High);
let cell_pwr = gpio::OutputOpenDrain::new(p.PIN_5, gpio::Level::High);
let cell_vint = gpio::Input::new(p.PIN_6, gpio::Pull::None);

let celullar_config = MyCelullarConfig {
reset_pin: Some(cell_nrst),
power_pin: Some(cell_pwr),
vint_pin: Some(cell_vint),
};

static RES_SLOT: ResponseSlot<INGRESS_BUF_SIZE> = ResponseSlot::new();
static URC_CHANNEL: UrcChannel<command::Urc, URC_CAPACITY, URC_SUBSCRIBERS> = UrcChannel::new();
let ingress = Ingress::new(
DefaultDigester::<command::Urc>::default(),
INGRESS_BUF.init([0; INGRESS_BUF_SIZE]),
&RES_SLOT,
&URC_CHANNEL,
);
static BUF: StaticCell<[u8; INGRESS_BUF_SIZE]> = StaticCell::new();
let client = Client::new(
uart_tx,
&RES_SLOT,
BUF.init([0; INGRESS_BUF_SIZE]),
atat::Config::default(),
);

spawner.spawn(ingress_task(ingress, uart_rx)).unwrap();

static STATE: StaticCell<State<Client<BufferedUartTx<UART0>, INGRESS_BUF_SIZE>>> =
StaticCell::new();
let (_device, mut control, runner) = ublox_cellular::asynch::new(
STATE.init(State::new(client)),
&URC_CHANNEL,
celullar_config,
)
.await;
// defmt::info!("{:?}", runner.init().await);
// control.set_desired_state(PowerState::Connected).await;
// control
// .send(&crate::command::network_service::SetOperatorSelection {
// mode: crate::command::network_service::types::OperatorSelectionMode::Automatic,
// format: Some(0),
// })
// .await;

defmt::unwrap!(spawner.spawn(cellular_task(runner)));
Timer::after(Duration::from_millis(1000)).await;
loop {
control
.set_desired_state(OperationState::DataEstablished)
.await;
info!("set_desired_state(PowerState::Alive)");
while control.power_state() != OperationState::DataEstablished {
Timer::after(Duration::from_millis(1000)).await;
}
Timer::after(Duration::from_millis(10000)).await;

loop {
Timer::after(Duration::from_millis(1000)).await;
let operator = control.get_operator().await;
info!("{}", operator);
let signal_quality = control.get_signal_quality().await;
info!("{}", signal_quality);
if signal_quality.is_err() {
let desired_state = control.desired_state();
control.set_desired_state(desired_state).await
}
if let Ok(sq) = signal_quality {
if let Ok(op) = operator {
if op.oper.is_none() {
continue;
}
}
if sq.rxlev > 0 && sq.rsrp != 255 {
break;
}
}
}
let dns = control
.send(&ublox_cellular::command::dns::ResolveNameIp {
resolution_type:
ublox_cellular::command::dns::types::ResolutionType::DomainNameToIp,
ip_domain_string: "www.google.com",
})
.await;
info!("dns: {:?}", dns);
Timer::after(Duration::from_millis(10000)).await;
control.set_desired_state(OperationState::PowerDown).await;
info!("set_desired_state(PowerState::PowerDown)");
while control.power_state() != OperationState::PowerDown {
Timer::after(Duration::from_millis(1000)).await;
}

Timer::after(Duration::from_millis(5000)).await;
}
}

#[embassy_executor::task]
async fn ingress_task(
mut ingress: Ingress<
'static,
DefaultDigester<Urc>,
ublox_cellular::command::Urc,
{ INGRESS_BUF_SIZE },
{ URC_CAPACITY },
{ URC_SUBSCRIBERS },
>,
mut reader: BufferedUartRx<'static, UART0>,
) -> ! {
ingress.read_from(&mut reader).await
}

#[embassy_executor::task]
async fn cellular_task(
runner: Runner<
'static,
atat::asynch::Client<'_, BufferedUartTx<'static, UART0>, { INGRESS_BUF_SIZE }>,
MyCelullarConfig,
{ URC_CAPACITY },
>,
) -> ! {
runner.run().await
}

static EXECUTOR: StaticCell<Executor> = StaticCell::new();

#[entry]
fn main() -> ! {
info!("Hello World!");

let executor = EXECUTOR.init(Executor::new());

executor.run(|spawner| {
unwrap!(spawner.spawn(main_task(spawner)));
})
}
9 changes: 9 additions & 0 deletions examples/embassy-stm32-example/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
**/*.rs.bk
.#*
.gdb_history
*.fifo
target/
*.o
**/*secrets*

.DS_Store

0 comments on commit 5e654f0

Please sign in to comment.