diff --git a/firmware/.cargo/config b/firmware/.cargo/config new file mode 100644 index 0000000..5ca804d --- /dev/null +++ b/firmware/.cargo/config @@ -0,0 +1,8 @@ +[target.riscv32i-unknown-none-elf] +rustflags = [ + "-C", "link-arg=-Tmemory.x", + "-C", "link-arg=-Tlink.x", +] + +[build] +target = "riscv32i-unknown-none-elf" \ No newline at end of file diff --git a/firmware/.gitignore b/firmware/.gitignore new file mode 100644 index 0000000..cdc8c75 --- /dev/null +++ b/firmware/.gitignore @@ -0,0 +1,2 @@ +target/ +*.bin \ No newline at end of file diff --git a/firmware/Cargo.lock b/firmware/Cargo.lock new file mode 100644 index 0000000..cc42d99 --- /dev/null +++ b/firmware/Cargo.lock @@ -0,0 +1,183 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "aho-corasick" +version = "0.7.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac" +dependencies = [ + "memchr", +] + +[[package]] +name = "bit_field" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcb6dd1c2376d2e096796e234a70e17e94cc2d5d54ff8ce42b28cef1d0d359a4" + +[[package]] +name = "critical-section" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6548a0ad5d2549e111e1f6a11a6c2e2d00ce6a3dafe22948d67c2b443f775e52" + +[[package]] +name = "embedded-hal" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35949884794ad573cf46071e41c9b60efb0cb311e3ca01f7af807af1debc66ff" +dependencies = [ + "nb 0.1.3", + "void", +] + +[[package]] +name = "fw" +version = "0.1.0" +dependencies = [ + "panic-halt", + "riscv-rt", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "memchr" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" + +[[package]] +name = "nb" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "801d31da0513b6ec5214e9bf433a77966320625a37860f910be265be6e18d06f" +dependencies = [ + "nb 1.0.0", +] + +[[package]] +name = "nb" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "546c37ac5d9e56f55e73b677106873d9d9f5190605e41a856503623648488cae" + +[[package]] +name = "panic-halt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de96540e0ebde571dc55c73d60ef407c653844e6f9a1e2fdbd40c07b9252d812" + +[[package]] +name = "proc-macro2" +version = "1.0.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ef7d57beacfaf2d8aee5937dab7b7f28de3cb8b1828479bb5de2a7106f2bae2" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "r0" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd7a31eed1591dcbc95d92ad7161908e72f4677f8fabf2a32ca49b4237cbf211" + +[[package]] +name = "regex" +version = "1.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48aaa5748ba571fb95cd2c85c09f629215d3a6ece942baa100950af03a34f733" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.6.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848" + +[[package]] +name = "riscv" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa3145d2fae3778b1e31ec2e827b228bdc6abd9b74bb5705ba46dcb82069bc4f" +dependencies = [ + "bit_field", + "critical-section", + "embedded-hal", +] + +[[package]] +name = "riscv-rt" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "102c52c89defde24dedf9ac077cc69df77b85aa2400dd2d5aad6eea6a6a5c089" +dependencies = [ + "r0", + "riscv", + "riscv-rt-macros", + "riscv-target", +] + +[[package]] +name = "riscv-rt-macros" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f38509d7b17c2f604ceab3e5ff8ac97bb8cd2f544688c512be75c715edaf4daf" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "riscv-target" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88aa938cda42a0cf62a20cfe8d139ff1af20c2e681212b5b34adb5a58333f222" +dependencies = [ + "lazy_static", + "regex", +] + +[[package]] +name = "syn" +version = "1.0.107" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "unicode-ident" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc" + +[[package]] +name = "void" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" diff --git a/firmware/Cargo.toml b/firmware/Cargo.toml new file mode 100644 index 0000000..e2c8e57 --- /dev/null +++ b/firmware/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "fw" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +riscv-rt = "0.11.0" +panic-halt = "0.2.0" diff --git a/firmware/README.md b/firmware/README.md new file mode 100644 index 0000000..0104507 --- /dev/null +++ b/firmware/README.md @@ -0,0 +1,3 @@ +# Firmware + +This was set up according to docs here: https://docs.rs/riscv-rt/latest/riscv_rt/ \ No newline at end of file diff --git a/firmware/build.rs b/firmware/build.rs new file mode 100644 index 0000000..8709ff2 --- /dev/null +++ b/firmware/build.rs @@ -0,0 +1,14 @@ +use std::env; +use std::fs; +use std::path::PathBuf; + +fn main() { + let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap()); + + // Put the linker script somewhere the linker can find it. + fs::write(out_dir.join("memory.x"), include_bytes!("memory.x")).unwrap(); + println!("cargo:rustc-link-search={}", out_dir.display()); + println!("cargo:rerun-if-changed=memory.x"); + + println!("cargo:rerun-if-changed=build.rs"); +} \ No newline at end of file diff --git a/firmware/hello_world_c/Makefile b/firmware/hello_world_c/Makefile index d1edfbe..d471531 100644 --- a/firmware/hello_world_c/Makefile +++ b/firmware/hello_world_c/Makefile @@ -2,7 +2,7 @@ PREFIX := riscv64-unknown-elf- CC := $(PREFIX)gcc OBJCOPY := $(PREFIX)objcopy -ARGS := -mabi=ilp32 -march=rv32im -ffreestanding -nostdlib -Wl,-Bstatic,-T,memory.ld,--strip-debug +ARGS := -mabi=ilp32 -march=rv32im -ffreestanding -nostdlib -Wl,-Bstatic,-T,memory.ld -g SOURCES := main.c INCLUDES := uart.h diff --git a/firmware/hello_world_c/main.c b/firmware/hello_world_c/main.c index c295dc4..ae2c91b 100644 --- a/firmware/hello_world_c/main.c +++ b/firmware/hello_world_c/main.c @@ -1,13 +1,28 @@ #include "uart.h" #include +#include void write_cstring(const char* string); void write_char(char c); +void toggle_led(); + +#define LED *((uint32_t*) 0x01002000) int main() { + uint32_t i = 0; + bool toggle = false; for (;;) { + if (i >= 100) { + i = 0; + if (toggle) { + LED = 1; + } else { + LED = 0; + } + } + write_char('H'); write_char('e'); write_char('l'); @@ -22,17 +37,19 @@ int main() { write_char('!'); write_char('\n'); write_char('\r'); + + i += 1; } } void write_char(char c) { - while (!UART0->TXEMPTY); + //while (!UART0->TXEMPTY); - // Wait for room to clear up - if (!UART0->TXFULL) { - UART0->RXTX = c; - } + //// Wait for room to clear up + //if (!UART0->TXFULL) { + // UART0->RXTX = c; + //} } void write_cstring(const char* string) { int i = 0; @@ -52,3 +69,8 @@ void write_cstring(const char* string) { } } + +void toggle_led() { + LED = !LED; + write_char('0' + LED); +} diff --git a/firmware/memory.x b/firmware/memory.x new file mode 100644 index 0000000..11e0748 --- /dev/null +++ b/firmware/memory.x @@ -0,0 +1,12 @@ +MEMORY +{ + RAM : ORIGIN = 0x01001000, LENGTH = 4K + FLASH : ORIGIN = 0x01000000, LENGTH = 4K +} + +REGION_ALIAS("REGION_TEXT", FLASH); +REGION_ALIAS("REGION_RODATA", FLASH); +REGION_ALIAS("REGION_DATA", RAM); +REGION_ALIAS("REGION_BSS", RAM); +REGION_ALIAS("REGION_HEAP", RAM); +REGION_ALIAS("REGION_STACK", RAM); diff --git a/firmware/src/main.rs b/firmware/src/main.rs new file mode 100644 index 0000000..27ad0e5 --- /dev/null +++ b/firmware/src/main.rs @@ -0,0 +1,33 @@ +#![no_std] +#![no_main] + +extern crate panic_halt; + +use core::{arch::asm, ptr::write}; + +use riscv_rt::entry; + +// use `main` as the entry point of this application +// `main` is not allowed to return +#[entry] +fn main() -> ! { + // do something here + loop { + unsafe { + write(0x01002000 as *mut u32, 0); + busy_wait(10_000_000); + write(0x01002000 as *mut u32, 1); + busy_wait(10_000_000); + } + } +} + +fn busy_wait(num_nops: u32) { + for _ in 0..num_nops { + unsafe { asm!("nop"); } + } +} + +fn write_led(val: u32) { + unsafe { write(0x01002000 as *mut u32, val); } +} \ No newline at end of file