forked from openwsn-berkeley/lakers
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request openwsn-berkeley#297 from malishav/296-add-standal…
…one-nrf52840-example Add standalone nRF52840-DK example over raw BLE radio
- Loading branch information
Showing
9 changed files
with
556 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
[target.'cfg(all(target_arch = "arm", target_os = "none"))'] | ||
# replace nRF82840_xxAA with your chip as listed in `probe-rs chip list` | ||
runner = "probe-rs run --chip nRF52840_xxAA" | ||
|
||
[build] | ||
target = "thumbv7em-none-eabi" | ||
|
||
[env] | ||
DEFMT_LOG = "trace" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
[package] | ||
name = "lakers-nrf52840" | ||
edition = "2021" | ||
version.workspace = true | ||
repository.workspace = true | ||
license.workspace = true | ||
keywords.workspace = true | ||
categories.workspace = true | ||
|
||
[dependencies] | ||
|
||
# embassy deps | ||
embassy-executor = { git = "https://github.com/embassy-rs/embassy", branch = "main", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] } | ||
embassy-time = { git = "https://github.com/embassy-rs/embassy", branch = "main", features = ["defmt", "defmt-timestamp-uptime"] } | ||
embassy-nrf = { git = "https://github.com/embassy-rs/embassy", branch = "main", features = ["defmt", "nrf52840", "time-driver-rtc1", "gpiote", "unstable-pac", "time"] } | ||
|
||
# lakers | ||
lakers = { package = "lakers", path = "../../lib", default-features = false } | ||
lakers-crypto = { path = "../../crypto", default-features = false } | ||
|
||
# misc | ||
hexlit = "0.5.3" | ||
|
||
# defmt | ||
defmt = "0.3" | ||
defmt-rtt = "0.4" | ||
|
||
# depend on an allocator | ||
embedded-alloc = "0.5.0" | ||
|
||
# arm cortex m3 deps | ||
cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } | ||
cortex-m-rt = "0.7.0" | ||
panic-probe = { version = "0.3", features = ["print-defmt"] } | ||
|
||
[features] | ||
default = [ "crypto-psa", "ead-none" ] | ||
crypto-cryptocell310 = [ "lakers-crypto/cryptocell310" ] | ||
crypto-psa = [ "lakers-crypto/psa-baremetal" ] | ||
ead-none = [ ] | ||
|
||
[profile.release] | ||
debug = 2 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
# Introduction | ||
|
||
This folder contains a bare metal (no_std) example of EDHOC Initiator and EDHOC Responder for nRF52840-DK. | ||
The Initiator and Responder communicate over a raw BLE radio. | ||
|
||
The example is configured to be ran on nRF52840-DK board. | ||
|
||
## Prerequisites | ||
|
||
- install probe-rs | ||
- `rustup target add thumbv7m-none-eabi` | ||
|
||
## How to use | ||
|
||
This folder's `.cargo/config.toml` configures the target (`thumbv7m-none-eabi`) and the probe-rs runner so the things should just work: | ||
|
||
cargo run --bin initiator | ||
cargo run --bin responder | ||
|
||
You may want to prefix the commands above with e.g. PROBE_RS_PROBE=1366:1051:001050288491 in order to specify which board you want to connect to. | ||
You can get the name of your probes by running: | ||
|
||
probe-rs list |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
//! This build script copies the `memory.x` file from the crate root into | ||
//! a directory where the linker can always find it at build time. | ||
//! For many projects this is optional, as the linker always searches the | ||
//! project root directory -- wherever `Cargo.toml` is. However, if you | ||
//! are using a workspace or have a more complicated build setup, this | ||
//! build script becomes required. Additionally, by requesting that | ||
//! Cargo re-run the build script whenever `memory.x` is changed, | ||
//! updating `memory.x` ensures a rebuild of the application with the | ||
//! new memory settings. | ||
use std::env; | ||
use std::fs::File; | ||
use std::io::Write; | ||
use std::path::PathBuf; | ||
|
||
fn main() { | ||
// Put `memory.x` in our output directory and ensure it's | ||
// on the linker search path. | ||
let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap()); | ||
File::create(out.join("memory.x")) | ||
.unwrap() | ||
.write_all(include_bytes!("memory.x")) | ||
.unwrap(); | ||
println!("cargo:rustc-link-search={}", out.display()); | ||
|
||
// By default, Cargo will re-run a build script whenever | ||
// any file in the project changes. By specifying `memory.x` | ||
// here, we ensure the build script is only re-run when | ||
// `memory.x` is changed. | ||
println!("cargo:rerun-if-changed=memory.x"); | ||
|
||
println!("cargo:rustc-link-arg-bins=--nmagic"); | ||
println!("cargo:rustc-link-arg-bins=-Tlink.x"); | ||
println!("cargo:rustc-link-arg-bins=-Tdefmt.x"); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
MEMORY | ||
{ | ||
/* NOTE 1 K = 1 KiBi = 1024 bytes */ | ||
FLASH : ORIGIN = 0x00000000, LENGTH = 1024K | ||
RAM : ORIGIN = 0x20000000, LENGTH = 256K | ||
|
||
/* These values correspond to the NRF52840 with Softdevices S140 7.3.0 */ | ||
/* | ||
FLASH : ORIGIN = 0x00027000, LENGTH = 868K | ||
RAM : ORIGIN = 0x20020000, LENGTH = 128K | ||
*/ | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,178 @@ | ||
use embassy_nrf::radio::ble::Radio; | ||
use embassy_nrf::saadc::Time; | ||
use embassy_nrf::{peripherals, radio}; | ||
use embassy_time::Duration; | ||
use embassy_time::TimeoutError; | ||
use embassy_time::WithTimeout; | ||
use hexlit::hex; | ||
|
||
use defmt::info; | ||
|
||
pub const MAX_PDU: usize = 258; | ||
pub const FREQ: u32 = 2408; | ||
pub const ADV_ADDRESS: u32 = 0x12345678; | ||
pub const ADV_CRC_INIT: u32 = 0xffff; | ||
pub const CRC_POLY: u32 = 0x00065b; | ||
|
||
pub const CRED_I: &[u8] = &hex!("A2027734322D35302D33312D46462D45462D33372D33322D333908A101A5010202412B2001215820AC75E9ECE3E50BFC8ED60399889522405C47BF16DF96660A41298CB4307F7EB62258206E5DE611388A4B8A8211334AC7D37ECB52A387D257E6DB3C2A93DF21FF3AFFC8"); | ||
pub const I: &[u8] = &hex!("fb13adeb6518cee5f88417660841142e830a81fe334380a953406a1305e8706b"); | ||
pub const R: &[u8] = &hex!("72cc4761dbd4c78f758931aa589d348d1ef874a7e303ede2f140dcf3e6aa4aac"); | ||
pub const CRED_R: &[u8] = &hex!("A2026008A101A5010202410A2001215820BBC34960526EA4D32E940CAD2A234148DDC21791A12AFBCBAC93622046DD44F02258204519E257236B2A0CE2023F0931F1F386CA7AFDA64FCDE0108C224C51EABF6072"); | ||
|
||
#[derive(Debug)] | ||
pub enum PacketError { | ||
SliceTooLong, | ||
SliceTooShort, | ||
ParsingError, | ||
TimeoutError, | ||
RadioError, | ||
} | ||
pub struct Packet { | ||
pub len: usize, // total length that gets transmitted over the air, equals length of pdu + 1, for pdu_header | ||
pub pdu_header: Option<u8>, // 1-byte application-level header, used for filtering the packets | ||
pub pdu: [u8; MAX_PDU], // application-level payload | ||
} | ||
|
||
impl Default for Packet { | ||
fn default() -> Self { | ||
Packet { | ||
len: 0, | ||
pdu_header: None, | ||
pdu: [0u8; MAX_PDU], | ||
} | ||
} | ||
} | ||
|
||
impl Packet { | ||
pub fn new() -> Self { | ||
Packet { | ||
len: 0, | ||
pdu_header: None, | ||
pdu: [0u8; MAX_PDU], | ||
} | ||
} | ||
|
||
pub fn new_from_slice(slice: &[u8], header: Option<u8>) -> Result<Self, PacketError> { | ||
let mut buffer = Self::new(); | ||
if buffer.fill_with_slice(slice, header).is_ok() { | ||
Ok(buffer) | ||
} else { | ||
Err(PacketError::SliceTooLong) | ||
} | ||
} | ||
|
||
pub fn fill_with_slice(&mut self, slice: &[u8], header: Option<u8>) -> Result<(), PacketError> { | ||
if slice.len() <= self.pdu.len() { | ||
self.len = slice.len(); | ||
self.pdu_header = header; | ||
self.pdu[..self.len].copy_from_slice(slice); | ||
Ok(()) | ||
} else { | ||
Err(PacketError::SliceTooLong) | ||
} | ||
} | ||
|
||
pub fn as_bytes(&mut self) -> &[u8] { | ||
let mut offset = 0; | ||
let mut len: usize = 0; | ||
|
||
if let Some(header) = self.pdu_header { | ||
offset = 3; | ||
len = self.len + 1; | ||
} else { | ||
offset = 2; | ||
len = self.len; | ||
} | ||
self.pdu.copy_within(..self.len, offset); | ||
self.pdu[0] = 0x00; | ||
self.pdu[1] = len as u8; | ||
|
||
if let Some(header) = self.pdu_header { | ||
self.pdu[2] = header; | ||
} | ||
&self.pdu[..len] | ||
} | ||
} | ||
|
||
impl TryInto<Packet> for &[u8] { | ||
type Error = (); | ||
|
||
fn try_into(self) -> Result<Packet, Self::Error> { | ||
let mut packet: Packet = Default::default(); | ||
|
||
if self.len() > 1 { | ||
packet.len = self[1] as usize; | ||
packet.pdu[..packet.len].copy_from_slice(&self[2..2 + packet.len]); | ||
Ok(packet) | ||
} else { | ||
Err(()) | ||
} | ||
} | ||
} | ||
|
||
impl From<TimeoutError> for PacketError { | ||
fn from(error: TimeoutError) -> Self { | ||
PacketError::TimeoutError | ||
} | ||
} | ||
|
||
impl From<embassy_nrf::radio::Error> for PacketError { | ||
fn from(error: embassy_nrf::radio::Error) -> Self { | ||
match error { | ||
_ => PacketError::RadioError, | ||
} | ||
} | ||
} | ||
|
||
pub async fn receive_and_filter( | ||
radio: &mut Radio<'static, embassy_nrf::peripherals::RADIO>, | ||
header: Option<u8>, | ||
) -> Result<Packet, PacketError> { | ||
let mut buffer: [u8; MAX_PDU] = [0x00u8; MAX_PDU]; | ||
loop { | ||
radio.receive(&mut buffer).await?; | ||
if let Ok(pckt) = <&[u8] as TryInto<Packet>>::try_into(&(buffer[..])) { | ||
if let Some(header) = header { | ||
if pckt.pdu[0] == header { | ||
return Ok(pckt); | ||
} else { | ||
continue; | ||
} | ||
} else { | ||
// header is None | ||
return Ok(pckt); | ||
} | ||
} else { | ||
continue; | ||
} | ||
} | ||
} | ||
|
||
pub async fn transmit_and_wait_response( | ||
radio: &mut Radio<'static, embassy_nrf::peripherals::RADIO>, | ||
mut packet: Packet, | ||
filter: Option<u8>, | ||
) -> Result<Packet, PacketError> { | ||
let mut rcvd_packet: Packet = Default::default(); | ||
let mut buffer: [u8; MAX_PDU] = [0x00u8; MAX_PDU]; | ||
|
||
radio.transmit(packet.as_bytes()).await?; | ||
let resp = receive_and_filter(radio, filter).await?; | ||
|
||
Ok(resp) | ||
} | ||
|
||
pub async fn transmit_without_response( | ||
radio: &mut Radio<'static, embassy_nrf::peripherals::RADIO>, | ||
mut packet: Packet, | ||
) -> Result<(), PacketError> { | ||
radio.transmit(packet.as_bytes()).await?; | ||
Ok(()) | ||
} | ||
|
||
use core::ffi::{c_char, c_void}; | ||
#[no_mangle] | ||
pub extern "C" fn strstr(cs: *const c_char, ct: *const c_char) -> *mut c_char { | ||
panic!("strstr handler!"); | ||
core::ptr::null_mut() | ||
} |
Oops, something went wrong.