summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGustav Sörnäs <gustav@sornas.net>2021-03-13 23:45:40 +0100
committerGustav Sörnäs <gustav@sornas.net>2021-03-13 23:45:40 +0100
commit36251ad76afbe22c78fabc2ff1186615aaef0662 (patch)
tree60e5a9d04d3ce7a24cd5ee7004a872ba9beba7be
downloadserial-morse-36251ad76afbe22c78fabc2ff1186615aaef0662.tar.gz
initial commit
-rw-r--r--.cargo/config.toml8
-rw-r--r--.gitignore1
-rw-r--r--Cargo.toml28
-rw-r--r--avr-atmega328p.json27
-rw-r--r--rust-toolchain1
-rw-r--r--src/main.rs94
-rwxr-xr-xuno-runner.sh58
7 files changed, 217 insertions, 0 deletions
diff --git a/.cargo/config.toml b/.cargo/config.toml
new file mode 100644
index 0000000..7f8c45b
--- /dev/null
+++ b/.cargo/config.toml
@@ -0,0 +1,8 @@
+[build]
+target = "avr-atmega328p.json"
+
+[unstable]
+build-std = ["core"]
+
+[target.'cfg(target_arch = "avr")']
+runner = "./uno-runner.sh"
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..ea8c4bf
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+/target
diff --git a/Cargo.toml b/Cargo.toml
new file mode 100644
index 0000000..6e24335
--- /dev/null
+++ b/Cargo.toml
@@ -0,0 +1,28 @@
+[package]
+name = "serial-morse"
+version = "0.1.0"
+authors = ["Gustav Sörnäs <gustav@sornas.net>"]
+edition = "2018"
+
+[dependencies]
+panic-halt = "0.2.0"
+
+embedded-hal = "0.2"
+nb = "1"
+
+[dependencies.arduino-uno]
+git = "https://github.com/rahix/avr-hal"
+rev = "a202778"
+
+# Configure the build for minimal size
+[profile.dev]
+panic = "abort"
+lto = true
+opt-level = "s"
+
+[profile.release]
+panic = "abort"
+codegen-units = 1
+debug = true
+lto = true
+opt-level = "s"
diff --git a/avr-atmega328p.json b/avr-atmega328p.json
new file mode 100644
index 0000000..e236b08
--- /dev/null
+++ b/avr-atmega328p.json
@@ -0,0 +1,27 @@
+{
+ "arch": "avr",
+ "atomic-cas": false,
+ "cpu": "atmega328p",
+ "data-layout": "e-P1-p:16:8-i8:8-i16:8-i32:8-i64:8-f32:8-f64:8-n8-a:8",
+ "eh-frame-header": false,
+ "exe-suffix": ".elf",
+ "executables": true,
+ "late-link-args": {
+ "gcc": [
+ "-lgcc"
+ ]
+ },
+ "linker": "avr-gcc",
+ "linker-is-gnu": true,
+ "llvm-target": "avr-unknown-unknown",
+ "max-atomic-width": 8,
+ "no-default-libraries": false,
+ "pre-link-args": {
+ "gcc": [
+ "-mmcu=atmega328p",
+ "-Wl,--as-needed"
+ ]
+ },
+ "target-c-int-width": "16",
+ "target-pointer-width": "16"
+}
diff --git a/rust-toolchain b/rust-toolchain
new file mode 100644
index 0000000..cef4e16
--- /dev/null
+++ b/rust-toolchain
@@ -0,0 +1 @@
+nightly-2021-01-07
diff --git a/src/main.rs b/src/main.rs
new file mode 100644
index 0000000..9bea689
--- /dev/null
+++ b/src/main.rs
@@ -0,0 +1,94 @@
+#![no_std]
+#![no_main]
+
+use core::char;
+
+use arduino_uno::{delay_ms, hal::port::{mode::Output, portb::PB5}, prelude::*};
+use panic_halt as _;
+
+const SHORT: u16 = 75;
+const LONG: u16 = SHORT * 3;
+const SPACE: u16 = SHORT * 7;
+
+macro_rules! morse {
+ ( $led:expr, $( $delay:expr ),* ) => {
+ {
+ $(
+ $led.set_high().void_unwrap();
+ delay_ms($delay);
+ $led.set_low().void_unwrap();
+ delay_ms(SHORT);
+ )*
+ delay_ms(LONG - SHORT);
+ }
+ };
+}
+
+fn blink_morse(led: &mut PB5<Output>, c: u8) {
+ let c = char::from_u32(c as u32);
+ if let Some(c) = c {
+ match c {
+ 'a' => morse!(led, SHORT, LONG),
+ 'b' => morse!(led, LONG, SHORT, SHORT, SHORT),
+ 'c' => morse!(led, LONG, SHORT, LONG, SHORT),
+ 'd' => morse!(led, LONG, SHORT, SHORT),
+ 'e' => morse!(led, SHORT),
+ 'f' => morse!(led, SHORT, SHORT, LONG, SHORT),
+ 'g' => morse!(led, LONG, LONG, SHORT),
+ 'h' => morse!(led, SHORT, SHORT, SHORT, SHORT),
+ 'i' => morse!(led, SHORT, SHORT),
+ 'j' => morse!(led, SHORT, LONG, LONG, LONG),
+ 'k' => morse!(led, LONG, SHORT, LONG),
+ 'l' => morse!(led, SHORT, LONG, SHORT, SHORT),
+ 'm' => morse!(led, LONG, LONG),
+ 'n' => morse!(led, LONG, SHORT),
+ 'o' => morse!(led, LONG, LONG, LONG),
+ 'p' => morse!(led, SHORT, LONG, LONG, SHORT),
+ 'q' => morse!(led, LONG, LONG, SHORT, LONG),
+ 'r' => morse!(led, SHORT, LONG, SHORT),
+ 's' => morse!(led, SHORT, SHORT, SHORT),
+ 't' => morse!(led, LONG),
+ 'u' => morse!(led, SHORT, SHORT, LONG),
+ 'v' => morse!(led, SHORT, SHORT, SHORT, LONG),
+ 'w' => morse!(led, SHORT, LONG, LONG),
+ 'x' => morse!(led, LONG, SHORT, SHORT, LONG),
+ 'y' => morse!(led, LONG, SHORT, LONG, LONG),
+ 'z' => morse!(led, LONG, LONG, SHORT, SHORT),
+ '1' => morse!(led, SHORT, LONG, LONG, LONG, LONG),
+ '2' => morse!(led, SHORT, SHORT, LONG, LONG, LONG),
+ '3' => morse!(led, SHORT, SHORT, SHORT, LONG, LONG),
+ '4' => morse!(led, SHORT, SHORT, SHORT, SHORT, LONG),
+ '5' => morse!(led, SHORT, SHORT, SHORT, SHORT, SHORT),
+ '6' => morse!(led, LONG, SHORT, SHORT, SHORT, SHORT),
+ '7' => morse!(led, LONG, LONG, SHORT, SHORT, SHORT),
+ '8' => morse!(led, LONG, LONG, LONG, SHORT, SHORT),
+ '9' => morse!(led, LONG, LONG, LONG, LONG, SHORT),
+ '0' => morse!(led, LONG, LONG, LONG, LONG, LONG),
+ ' ' => delay_ms(SPACE - LONG),
+ _ => {},
+ }
+ }
+}
+
+#[arduino_uno::entry]
+fn main() -> ! {
+ let dp = arduino_uno::Peripherals::take().unwrap();
+
+ let mut pins = arduino_uno::Pins::new(dp.PORTB, dp.PORTC, dp.PORTD);
+
+ let mut led = pins.d13.into_output(&mut pins.ddr);
+ led.set_low().void_unwrap();
+
+ let mut serial = arduino_uno::Serial::new(
+ dp.USART0,
+ pins.d0,
+ pins.d1.into_output(&mut pins.ddr),
+ 57600.into_baudrate(),
+ );
+
+ loop {
+ let b = nb::block!(serial.read()).void_unwrap();
+
+ blink_morse(&mut led, b);
+ }
+}
diff --git a/uno-runner.sh b/uno-runner.sh
new file mode 100755
index 0000000..066a598
--- /dev/null
+++ b/uno-runner.sh
@@ -0,0 +1,58 @@
+#!/usr/bin/env sh
+set -e
+
+case "$(uname -s)" in
+ Linux*) OS="Linux";;
+ Darwin*) OS="Mac";;
+ *) OS="Unknown";;
+esac
+
+if ! command -v numfmt > /dev/null 2>&1
+then
+ echo "numfmt is needed for human-readable sizes." >&2
+ echo "please install https://command-not-found.com/numfmt" >&2
+ alias numfmt=true
+fi
+
+if ! command -v avrdude > /dev/null 2>&1
+then
+ echo "required avrdude could not be found!" >&2
+ echo "please install https://command-not-found.com/avrdude" >&2
+ exit 1
+fi
+
+if [ $OS = "Linux" ]; then
+ SERIAL_PORT="/dev/ttyACM0"
+elif [ $OS = "Mac" ]; then
+ SERIAL_PORT="/dev/cu.usbmodem146201"
+else
+ echo "unsupported OS, things might not work" >&2
+ SERIAL_PORT="/dev/ttyACM0"
+fi
+
+if [ "$1" = "--help" ] || [ "$1" = "-h" ]; then
+ echo "usage: $0 <application.elf>" >&2
+ exit 1
+fi
+
+if [ "$#" -lt 1 ]; then
+ echo "$0: no ELF file given" >&2
+ exit 1
+fi
+
+NAME="$(basename "$1")"
+SIZE_TEXT="$(avr-size "$1" | tail -1 | cut -f1)"
+SIZE_DATA="$(avr-size "$1" | tail -1 | cut -f2)"
+SIZE_BSS="$(avr-size "$1" | tail -1 | cut -f3)"
+
+printf "\n"
+printf "Program: %s\n" "$NAME"
+printf "Size:\n"
+printf " .text %s (exact: %d)\n" "$(numfmt --to=si --padding=9 "$SIZE_TEXT")" "$SIZE_TEXT"
+printf " .data %s (exact: %d)\n" "$(numfmt --to=si --padding=9 "$SIZE_DATA")" "$SIZE_DATA"
+printf " .bss %s (exact: %d)\n" "$(numfmt --to=si --padding=9 "$SIZE_BSS")" "$SIZE_BSS"
+printf "\n"
+printf "Attempting to flash ...\n"
+printf "\n"
+
+avrdude -q -patmega328p -carduino -P"${SERIAL_PORT}" -D "-Uflash:w:$1:e"