diff --git a/boards/dongle/README.md b/boards/dongle/README.md
index cb24652..f7f8968 100644
--- a/boards/dongle/README.md
+++ b/boards/dongle/README.md
@@ -47,7 +47,7 @@ to: [81, 78, 109, 61, 120, 87, 125, 98, 100, 91, 97, 66, 57, 117, 49, 64, 48, 85
secret: "
>?>h$IUQhL&P*Up&6w"
```
-### Generate `puzzle.hex`
+### Generate `puzzle` ELF
``` console
$ git clone --branch dongle-puzzle https://github.com/japaric/embedded2020
@@ -55,9 +55,9 @@ $ git clone --branch dongle-puzzle https://github.com/japaric/embedded2020
$ cd embedded2020/firmware/apps
```
-Copy the `puzzle.rs` from this folder into the `embedded2020/firmware/apps/src/bin` folder.
+Find `puzzle.rs` in the `embedded2020/firmware/apps/src/bin` folder.
-Update that copy of `puzzle.rs` with the `FROM`, `TO` and `SECRET` data that you got from `puzzlegen`
+Update `puzzle.rs` with the `FROM`, `TO` and `SECRET` data that you got from `puzzlegen`
```` rust
static FROM: &[u8] = &[
@@ -80,38 +80,34 @@ static TO: &[u8] = &[
static SECRET: &[u8] = b"
>?>h$IUQhL&P*Up&6w";
````
-Build the program; this will produce an ELF file.
+Build the program; this will produce an ELF file called `puzzle` (no file ending).
``` console
$ cargo build --bin puzzle --release
```
-Convert that ELF file into a .hex file.
+Copy this ELF file from `embedded2020/firmware/target/thumbv7em-none-eabi/release` to `embedded-trainings-2020/boards/dongle`
-``` console
-$ arm-none-eabi-objcopy -O ihex ../target/thumbv7em-none-eabi/release/puzzle puzzle.hex
-```
+Test the produced `puzzle` file:
-Test the produced `puzzle.hex` file:
-
-- flash it onto a dongle using `cargo xtask dongle-flash`. The green LED on the dongle should turn on
+- flash it onto a dongle using `nrfdfu puzzle`. The green LED on the dongle should turn on
- run `cargo xtask serial-term`; you should see the following output. `deviceid` will be different
``` text
-deviceid=d90eedf1978d5fd2 channel=25 TxPower=+8dBm app=puzzle.hex
+deviceid=d90eedf1978d5fd2 channel=25 TxPower=+8dBm app=puzzle
```
- run the `radio-puzzle-solution` program on a DK; it should be able to decrypt the new secret
- run `cargo xtask change-channel ` to test changing the Dongle's radio channel
- modify and re-run the `radio-puzzle-solution` program on a DK to solve the puzzle using a the channel you set in the previous step
-### Generate `puzzle-nousb-*.hex`
+### Generate `puzzle-nousb-*`
-The procedure is similar to the one for generating the `puzzle.hex`. The differences are:
+The procedure is similar to the one for generating the `puzzle` ELF file. The differences are:
-- you copy `puzzle-nousb.rs` into the `embedded2020` repository
-- you also need to change `const CHANNEL` in the `puzzle-nousb.rs` copy
-- you need to produce one hex file per hard-coded radio channel.
+- you build `puzzle-nousb.rs` in the `embedded2020` repository and copy `embedded2020/firmware/target/thumbv7em-none-eabi/release/puzzle-nousb` over
+- you also need to change `const CHANNEL` in `puzzle-nousb.rs`
+- you need to produce one ELF file per hard-coded radio channel.
-Also test these `nousb` .hex files. Note that the green LED won't turn on when the dongle restarts! The green LED will toggle when a new packet is received and the blue LED will turn on when the decoded secret is received. Also, `cargo xtask change-channel` won't work with the `nousb` variants so you can skip that test.
+Also test these `nousb` ELF files. Note that the green LED won't turn on when the dongle restarts! The green LED will toggle when a new packet is received and the blue LED will turn on when the decoded secret is received. Also, `cargo xtask change-channel` won't work with the `nousb` variants so you can skip that test.
## References
diff --git a/boards/dongle/deprecated_hex/README.md b/boards/dongle/deprecated_hex/README.md
new file mode 100644
index 0000000..c633af8
--- /dev/null
+++ b/boards/dongle/deprecated_hex/README.md
@@ -0,0 +1,5 @@
+# For `nrfutil` Users only
+
+The files in this directory are only relevant if you are still using the `nrfutil` python tool distributed by Nordic Semiconductors.
+
+For a smoother installation and usage experience, we recommend you install [`nrfdfu`](https://crates.io/crates/nrfdfu) if at all possible.
\ No newline at end of file
diff --git a/boards/dongle/loopback-nousb11.hex b/boards/dongle/deprecated_hex/loopback-nousb11.hex
similarity index 100%
rename from boards/dongle/loopback-nousb11.hex
rename to boards/dongle/deprecated_hex/loopback-nousb11.hex
diff --git a/boards/dongle/loopback-nousb16.hex b/boards/dongle/deprecated_hex/loopback-nousb16.hex
similarity index 100%
rename from boards/dongle/loopback-nousb16.hex
rename to boards/dongle/deprecated_hex/loopback-nousb16.hex
diff --git a/boards/dongle/loopback-nousb21.hex b/boards/dongle/deprecated_hex/loopback-nousb21.hex
similarity index 100%
rename from boards/dongle/loopback-nousb21.hex
rename to boards/dongle/deprecated_hex/loopback-nousb21.hex
diff --git a/boards/dongle/loopback-nousb26.hex b/boards/dongle/deprecated_hex/loopback-nousb26.hex
similarity index 100%
rename from boards/dongle/loopback-nousb26.hex
rename to boards/dongle/deprecated_hex/loopback-nousb26.hex
diff --git a/boards/dongle/loopback.hex b/boards/dongle/deprecated_hex/loopback.hex
similarity index 100%
rename from boards/dongle/loopback.hex
rename to boards/dongle/deprecated_hex/loopback.hex
diff --git a/boards/dongle/puzzle-nousb11.hex b/boards/dongle/deprecated_hex/puzzle-nousb11.hex
similarity index 100%
rename from boards/dongle/puzzle-nousb11.hex
rename to boards/dongle/deprecated_hex/puzzle-nousb11.hex
diff --git a/boards/dongle/puzzle-nousb16.hex b/boards/dongle/deprecated_hex/puzzle-nousb16.hex
similarity index 100%
rename from boards/dongle/puzzle-nousb16.hex
rename to boards/dongle/deprecated_hex/puzzle-nousb16.hex
diff --git a/boards/dongle/puzzle-nousb21.hex b/boards/dongle/deprecated_hex/puzzle-nousb21.hex
similarity index 100%
rename from boards/dongle/puzzle-nousb21.hex
rename to boards/dongle/deprecated_hex/puzzle-nousb21.hex
diff --git a/boards/dongle/puzzle-nousb26.hex b/boards/dongle/deprecated_hex/puzzle-nousb26.hex
similarity index 100%
rename from boards/dongle/puzzle-nousb26.hex
rename to boards/dongle/deprecated_hex/puzzle-nousb26.hex
diff --git a/boards/dongle/puzzle.hex b/boards/dongle/deprecated_hex/puzzle.hex
similarity index 100%
rename from boards/dongle/puzzle.hex
rename to boards/dongle/deprecated_hex/puzzle.hex
diff --git a/boards/dongle/loopback-nousb.rs b/boards/dongle/loopback-nousb.rs
deleted file mode 100644
index 2283049..0000000
--- a/boards/dongle/loopback-nousb.rs
+++ /dev/null
@@ -1,35 +0,0 @@
-#![deny(unused_must_use)]
-#![no_main]
-#![no_std]
-
-use hal::{radio::{self, Channel}, led};
-use panic_abort as _;
-
-#[no_mangle]
-fn main() -> ! {
- let (mut rtx, mut rrx) = radio::claim(Channel::_21); // <- change this
- let led = led::Green;
-
- let task = async {
- let mut packet = radio::Packet::new().await;
- let mut on = true;
-
- loop {
- let crcres = rrx.read(&mut packet).await;
- // togle LED on each new packet
- if on {
- led.on();
- } else {
- led.off();
- }
- on = !on;
-
- if crcres.is_ok() {
- packet.reverse();
- rtx.write(&packet).await.ok();
- }
- }
- };
-
- executor::run!(task)
-}
diff --git a/boards/dongle/loopback-nousb11 b/boards/dongle/loopback-nousb11
new file mode 100755
index 0000000..ab0a0b1
Binary files /dev/null and b/boards/dongle/loopback-nousb11 differ
diff --git a/boards/dongle/loopback-nousb16 b/boards/dongle/loopback-nousb16
new file mode 100755
index 0000000..d38f561
Binary files /dev/null and b/boards/dongle/loopback-nousb16 differ
diff --git a/boards/dongle/loopback-nousb21 b/boards/dongle/loopback-nousb21
new file mode 100755
index 0000000..41c0f9f
Binary files /dev/null and b/boards/dongle/loopback-nousb21 differ
diff --git a/boards/dongle/loopback-nousb26 b/boards/dongle/loopback-nousb26
new file mode 100755
index 0000000..5b53798
Binary files /dev/null and b/boards/dongle/loopback-nousb26 differ
diff --git a/boards/dongle/loopback.rs b/boards/dongle/loopback.rs
deleted file mode 100644
index 65a886c..0000000
--- a/boards/dongle/loopback.rs
+++ /dev/null
@@ -1,125 +0,0 @@
-#![deny(unused_must_use)]
-#![no_main]
-#![no_std]
-
-use core::{convert::TryFrom, fmt::Write as _};
-
-use async_core::unsync::Mutex;
-use hal::{
- radio::{self, Channel},
- usbd,
-};
-use heapless::{consts, String};
-use panic_abort as _;
-
-#[no_mangle]
-fn main() -> ! {
- let stx = Mutex::new(usbd::serial());
- let (mut hidout, _) = usbd::hid();
- let (rtx, mut rrx) = radio::claim(Channel::_20);
-
- let mut output = String::::new();
-
- output.push_str("deviceid=").ok();
- write!(output, "{:08x}{:08x}", hal::deviceid1(), hal::deviceid0()).ok();
- write!(
- output,
- " channel={} TxPower=+8dBm app=loopback.hex\n",
- rtx.channel()
- )
- .ok();
-
- let rtx = Mutex::new(rtx);
-
- let t1 = async {
- let mut output = String::::new();
- let mut hidbuf = usbd::Packet::new().await;
- let zlp = radio::Packet::new().await;
-
- loop {
- hidout.recv(&mut hidbuf).await;
- semidap::info!("HID: {}", *hidbuf);
-
- let arg = if hidbuf.len() == 1 {
- // Linux / macOS
- Some(hidbuf[0])
- } else if hidbuf.len() == 64 {
- // Windows (it zero pads the packet)
- Some(hidbuf[0])
- } else {
- None
- };
-
- if let Some(arg) = arg {
- if let Ok(chan) = Channel::try_from(arg) {
- let mut rtx = rtx.lock().await;
- rtx.set_channel(chan);
- // send a zero-length packet to force the radio to listen on the new channel
- rtx.write(&zlp).await.ok();
- drop(rtx);
-
- output.clear();
- writeln!(output, "now listening on channel {}", chan).ok();
- stx.lock().await.write(output.as_bytes());
- } else {
- stx.lock()
- .await
- .write(b"requested channel is out of range (11-26)\n");
- }
- } else {
- stx.lock().await.write(b"invalid HID packet\n");
- }
- }
- };
-
- let t2 = async {
- let mut packet = radio::Packet::new().await;
- stx.lock().await.write(output.as_bytes());
-
- loop {
- let crcres = rrx.read(&mut packet).await;
- let len = packet.len();
- let lqi = if len >= 3 {
- Some(packet.lqi())
- } else {
- // packet is too small; LQI is not valid
- None
- };
-
- let mut busy = false;
- if crcres.is_ok() {
- packet.reverse();
- busy = rtx.lock().await.write(&packet).await.is_err();
- }
-
- output.clear();
- write!(
- &mut output,
- "received {} byte{}",
- len,
- if len == 1 { "" } else { "s" }
- )
- .ok();
-
- let (res, crc) = match crcres {
- Ok(x) => ("Ok", x),
- Err(x) => ("Err", x),
- };
-
- write!(&mut output, " (CRC={}({:#06x})", res, crc).ok();
- if let Some(lqi) = lqi {
- write!(&mut output, ", LQI={}", lqi).ok();
- }
- output.push_str(")\n").ok();
-
- if busy {
- output.push_str("didn't reply -- channel was busy\n").ok();
- stx.lock().await.write(output.as_bytes());
- }
-
- stx.lock().await.write(output.as_bytes());
- }
- };
-
- executor::run!(t1, t2)
-}
diff --git a/boards/dongle/puzzle-nousb.rs b/boards/dongle/puzzle-nousb.rs
deleted file mode 100644
index b1962c8..0000000
--- a/boards/dongle/puzzle-nousb.rs
+++ /dev/null
@@ -1,80 +0,0 @@
-#![deny(unused_must_use)]
-#![no_main]
-#![no_std]
-
-use hal::{
- led,
- radio::{self, Channel, Packet},
-};
-use heapless::{consts, LinearMap};
-use panic_abort as _;
-
-const CHANNEL: Channel = Channel::_26;
-
-static FROM: &[u8] = &[
- //
-];
-
-static TO: &[u8] = &[
- //
-];
-
-// store the secret rather than the plaintext -- otherwise `strings $elf` will reveal the answer
-static SECRET: &[u8] = b"";
-
-#[no_mangle]
-fn main() -> ! {
- let (mut rtx, mut rrx) = radio::claim(CHANNEL);
- let led = led::Green;
-
- let mut dict = LinearMap::<_, _, consts::U128>::new();
- for (&from, &to) in FROM.iter().zip(TO.iter()) {
- dict.insert(from, to).ok();
- }
-
- let task = async {
- let mut packet = Packet::new().await;
- let mut on = true;
-
- loop {
- let crcres = rrx.read(&mut packet).await;
- // toggle LED on each new packet
- if on {
- led.on();
- } else {
- led.off();
- }
- on = !on;
-
- if crcres.is_ok() {
- if packet.is_empty() {
- packet.copy_from_slice(SECRET);
- } else if packet.len() == 1 {
- let p = packet[0];
- let c = dict.get(&p).unwrap_or(&p);
- packet.copy_from_slice(&[*c]);
- } else {
- // encrypt
- for slot in packet.iter_mut() {
- if let Some(c) = dict.get(slot) {
- *slot = *c;
- }
- }
-
- let matches = &packet[..] == SECRET;
- packet.copy_from_slice(if matches {
- led::Blue.on();
- b"correct"
- } else {
- led::Blue.off();
- b"incorrect"
- });
- }
-
- rtx.write(&packet).await.ok();
- }
- }
- };
-
- executor::run!(task)
-}
diff --git a/boards/dongle/puzzle-nousb11 b/boards/dongle/puzzle-nousb11
new file mode 100755
index 0000000..0dc9aea
Binary files /dev/null and b/boards/dongle/puzzle-nousb11 differ
diff --git a/boards/dongle/puzzle-nousb16 b/boards/dongle/puzzle-nousb16
new file mode 100755
index 0000000..c470aa2
Binary files /dev/null and b/boards/dongle/puzzle-nousb16 differ
diff --git a/boards/dongle/puzzle-nousb21 b/boards/dongle/puzzle-nousb21
new file mode 100755
index 0000000..f5e9915
Binary files /dev/null and b/boards/dongle/puzzle-nousb21 differ
diff --git a/boards/dongle/puzzle-nousb26 b/boards/dongle/puzzle-nousb26
new file mode 100755
index 0000000..3e1591e
Binary files /dev/null and b/boards/dongle/puzzle-nousb26 differ
diff --git a/boards/dongle/puzzle.rs b/boards/dongle/puzzle.rs
deleted file mode 100644
index c2b9727..0000000
--- a/boards/dongle/puzzle.rs
+++ /dev/null
@@ -1,156 +0,0 @@
-#![deny(unused_must_use)]
-#![no_main]
-#![no_std]
-
-use core::{fmt::Write as _, convert::TryFrom};
-
-use async_core::unsync::Mutex;
-use hal::{radio::{self, Packet, Channel}, usbd, led};
-use heapless::{consts, LinearMap, String};
-use panic_abort as _;
-
-static FROM: &[u8] = &[
- //
-];
-
-static TO: &[u8] = &[
- //
-];
-
-// store the secret rather than the plaintext -- otherwise `strings $elf` will reveal the answer
-static SECRET: &[u8] = b"";
-
-#[no_mangle]
-fn main() -> ! {
- // so we can visually differentiate this one from `loopback.hex`
- led::Green.on();
-
- let stx = Mutex::new(usbd::serial());
- let (mut hidout, _) = usbd::hid();
- let (rtx, mut rrx) = radio::claim(Channel::_25);
- let mut output = String::::new();
-
- let mut dict = LinearMap::<_, _, consts::U128>::new();
- for (&from, &to) in FROM.iter().zip(TO.iter()) {
- dict.insert(from, to).ok();
- }
-
- output.push_str("deviceid=").ok();
- write!(output, "{:08x}{:08x}", hal::deviceid1(), hal::deviceid0()).ok();
- write!(output, " channel={} TxPower=+8dBm app=puzzle.hex\n", rtx.channel()).ok();
-
- let rtx = Mutex::new(rtx);
-
- let t1 = async {
- let mut output = String::::new();
- let mut hidbuf = usbd::Packet::new().await;
- let zlp = radio::Packet::new().await;
-
- loop {
- hidout.recv(&mut hidbuf).await;
- semidap::info!("HID: {}", *hidbuf);
-
- let arg = if hidbuf.len() == 1 {
- // Linux / macOS
- Some(hidbuf[0])
- } else if hidbuf.len() == 64 {
- // Windows (it zero pads the packet)
- Some(hidbuf[0])
- } else {
- None
- };
-
- if let Some(arg) = arg {
- if let Ok(chan) = Channel::try_from(arg) {
- let mut rtx = rtx.lock().await;
- rtx.set_channel(chan);
- // send a zero-length packet to force the radio to listen on the new channel
- rtx.write(&zlp).await.ok();
- drop(rtx);
-
- output.clear();
- writeln!(output, "now listening on channel {}", chan).ok();
- stx.lock().await.write(output.as_bytes());
- } else {
- stx.lock()
- .await
- .write(b"requested channel is out of range (11-26)\n");
- }
- } else {
- stx.lock().await.write(b"invalid HID packet\n");
- }
- }
- };
-
- let t2 = async {
- let mut packet = Packet::new().await;
- stx.lock().await.write(output.as_bytes());
-
- loop {
- let crcres = rrx.read(&mut packet).await;
- let len = packet.len();
- let lqi = if len >= 3 {
- Some(packet.lqi())
- } else {
- // packet is too small; LQI is not valid
- None
- };
-
- let mut busy = false;
- if crcres.is_ok() {
- if packet.is_empty() {
- packet.copy_from_slice(SECRET);
- } else if packet.len() == 1 {
- let p = packet[0];
- let c = dict.get(&p).unwrap_or(&p);
- packet.copy_from_slice(&[*c]);
- } else {
- // encrypt
- for slot in packet.iter_mut() {
- if let Some(c) = dict.get(slot) {
- *slot = *c;
- }
- }
-
- let matches = &packet[..] == SECRET;
- packet.copy_from_slice(if matches {
- b"correct"
- } else {
- b"incorrect"
- });
- }
-
- busy = rtx.lock().await.write(&packet).await.is_err();
- }
-
- output.clear();
- write!(
- &mut output,
- "received {} byte{}",
- len,
- if len == 1 { "" } else { "s" }
- )
- .ok();
-
- let (res, crc) = match crcres {
- Ok(x) => ("Ok", x),
- Err(x) => ("Err", x),
- };
-
- write!(&mut output, " (CRC={}({:#06x})", res, crc).ok();
- if let Some(lqi) = lqi {
- write!(&mut output, ", LQI={}", lqi).ok();
- }
- output.push_str(")\n").ok();
-
- if busy {
- output.push_str("didn't reply -- channel was busy\n").ok();
- stx.lock().await.write(output.as_bytes());
- }
-
- stx.lock().await.write(output.as_bytes());
- }
- };
-
- executor::run!(t1, t2)
-}