From 8d4ba623c350462ccf3fb838f87d62e1abb44327 Mon Sep 17 00:00:00 2001 From: David Craven Date: Mon, 20 Nov 2017 08:03:09 +0100 Subject: [PATCH 001/112] Initial commit. --- .cargo/config | 6 + .gdbinit | 24 ++ .gitignore | 4 + Cargo.toml | 30 +++ Makefile | 51 ++++ README.md | 18 ++ Xargo.toml | 7 + build.rs | 24 ++ examples/blinky_clint.rs | 20 ++ examples/blinky_delay.rs | 34 +++ examples/blinky_plic.rs | 43 ++++ examples/blinky_pwm.rs | 81 ++++++ examples/hello_world.rs | 13 + examples/panicking.rs | 20 ++ memory.x | 22 ++ openocd.cfg | 34 +++ src/clint.rs | 156 ++++++++++++ src/clock.rs | 120 +++++++++ src/gpio.rs | 204 ++++++++++++++++ src/led.rs | 42 ++++ src/lib.rs | 225 +++++++++++++++++ src/plic.rs | 125 ++++++++++ src/pwm.rs | 515 +++++++++++++++++++++++++++++++++++++++ src/serial.rs | 151 ++++++++++++ src/time.rs | 110 +++++++++ 25 files changed, 2079 insertions(+) create mode 100644 .cargo/config create mode 100644 .gdbinit create mode 100644 .gitignore create mode 100644 Cargo.toml create mode 100644 Makefile create mode 100644 README.md create mode 100644 Xargo.toml create mode 100644 build.rs create mode 100644 examples/blinky_clint.rs create mode 100644 examples/blinky_delay.rs create mode 100644 examples/blinky_plic.rs create mode 100644 examples/blinky_pwm.rs create mode 100644 examples/hello_world.rs create mode 100644 examples/panicking.rs create mode 100644 memory.x create mode 100644 openocd.cfg create mode 100644 src/clint.rs create mode 100644 src/clock.rs create mode 100644 src/gpio.rs create mode 100644 src/led.rs create mode 100644 src/lib.rs create mode 100644 src/plic.rs create mode 100644 src/pwm.rs create mode 100644 src/serial.rs create mode 100644 src/time.rs diff --git a/.cargo/config b/.cargo/config new file mode 100644 index 0000000..a4229f7 --- /dev/null +++ b/.cargo/config @@ -0,0 +1,6 @@ +[target.riscv32-unknown-none] +runner = 'riscv32-unknown-elf-gdb' +rustflags = [ + "-C", "link-arg=-Tlink.x", + "-C", "linker=riscv32-unknown-elf-ld", +] \ No newline at end of file diff --git a/.gdbinit b/.gdbinit new file mode 100644 index 0000000..b99fc56 --- /dev/null +++ b/.gdbinit @@ -0,0 +1,24 @@ +set remotetimeout 240 +target extended-remote localhost:3333 + +define upload + monitor reset halt + monitor flash protect 0 64 last off + load + monitor flash protect 0 64 last on + continue +end +document upload +Upload program to hifive board +end + +# Load Rust's GDB pretty printers +python +import os; +import sys; +path = os.environ['TOOLCHAIN'] + '/lib/rustlib/etc' +sys.path.append(path) + +gdb.execute('directory %s' % path) +gdb.execute('add-auto-load-safe-path %s' % path) +end diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..becb52e --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +Cargo.lock +target/ +core +.gdb_history \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..acabf39 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,30 @@ +[package] +name = "hifive" +version = "0.1.0" +repository = "https://github.com/dvc94ch/hifive" +authors = ["David Craven "] +categories = ["embedded", "hardware-support", "no-std"] +description = "Board support crate for hifive and lofive boards." +keywords = ["riscv", "register", "peripheral"] +license = "ISC" + +[dependencies.embedded-hal] +git = "https://github.com/japaric/embedded-hal" +rev = "7d904f515d15fd5fe7ea34e18820ea83e2651fa2" + +[dependencies.nb] +git = "https://github.com/japaric/nb" + +[dependencies.e310x] +features = ["rt"] +version = "^0.1.1" + +[dependencies.riscv] +version = "^0.1.3" + +[dev-dependencies.riscv-rt] +version = "^0.1.3" + +[profile.release] +debug = true +lto = true \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..0ce4811 --- /dev/null +++ b/Makefile @@ -0,0 +1,51 @@ +# Examples (uncomment one) +EXAMPLE := blinky_delay +#EXAMPLE := blinky_clint +#EXAMPLE := blinky_pwm +#EXAMPLE := blinky_plic +#EXAMPLE := hello_world +#EXAMPLE := panicking +#EXAMPLE := heaps +#EXAMPLE := rtc +#EXAMPLE := watchdog +#EXAMPLE := utest +#EXAMPLE := rtfm + +# Board crate (uncomment one) +BOARD := hifive + +TARGET := riscv32-unknown-none +TARGET_DIR := $(abspath ./target/$(TARGET)/debug) +EXAMPLE_BIN := $(TARGET_DIR)/examples/$(EXAMPLE) +OPENOCD_CFG := $(wildcard $(TARGET_DIR)/build/$(BOARD)-*/out/openocd.cfg) + +build: + xargo build --examples --target $(TARGET) $(ARGS) + +test: + xargo test --all --target $(TARGET) $(ARGS) + +clean: + xargo clean $(ARGS) + +readelf: + llvm-readelf -a -h -s -r -symbols $(EXAMPLE_BIN) $(ARGS) + +objdump: + llvm-objdump -d -S $(EXAMPLE_BIN) $(ARGS) + +size: + llvm-size $(EXAMPLE_BIN) $(ARGS) + +# .gdbinit adds a upload command to gdb +gdb: + riscv32-unknown-elf-gdb $(EXAMPLE_BIN) $(ARGS) + +openocd: + openocd -f $(OPENOCD_CFG) $(ARGS) + +upload: + openocd -f $(OPENOCD_CFG) \ + -c "flash protect 0 64 last off; program ${EXAMPLE_BIN}; resume 0x20400000; exit" + +.PHONY: build clean readelf objdump framedump size gdb openocd spike diff --git a/README.md b/README.md new file mode 100644 index 0000000..46f873d --- /dev/null +++ b/README.md @@ -0,0 +1,18 @@ +# `hifive` + +> Board support crate for hifive and lofive boards. + +# License +Copyright 2017 David Craven + +Permission to use, copy, modify, and/or distribute this software for any purpose +with or without fee is hereby granted, provided that the above copyright notice +and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS +OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +THIS SOFTWARE. diff --git a/Xargo.toml b/Xargo.toml new file mode 100644 index 0000000..001a159 --- /dev/null +++ b/Xargo.toml @@ -0,0 +1,7 @@ +[dependencies] +core = {} +alloc = {} + +[dependencies.compiler_builtins] +features = ["mem"] +stage = 1 diff --git a/build.rs b/build.rs new file mode 100644 index 0000000..ab3a5b6 --- /dev/null +++ b/build.rs @@ -0,0 +1,24 @@ +use std::env; +use std::fs::File; +use std::io::Write; +use std::path::PathBuf; + +fn main() { + // Put the linker script somewhere the linker can find it + 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()); + println!("cargo:rerun-if-changed=memory.x"); + + // Copy openocd.cfg to output directory + File::create(out.join("openocd.cfg")) + .unwrap() + .write_all(include_bytes!("openocd.cfg")) + .unwrap(); + println!("cargo:rerun-if-changed=openocd.cfg"); + + println!("cargo:rerun-if-changed=build.rs"); +} diff --git a/examples/blinky_clint.rs b/examples/blinky_clint.rs new file mode 100644 index 0000000..f96cfdc --- /dev/null +++ b/examples/blinky_clint.rs @@ -0,0 +1,20 @@ +#![no_std] + +extern crate hifive; + +use hifive::prelude::*; +use hifive::{led, Blue, Clint, Peripherals, UExt}; + +fn main() { + let peripherals = hifive::init(115_200); + led::init(peripherals.GPIO0); + + let timer = Clint(peripherals.CLINT); + timer.set_timeout(1.s()); +} + +#[no_mangle] +pub fn mtimer_trap_handler(p: &Peripherals) { + Clint(p.CLINT).restart(); + Blue::toggle(p.GPIO0); +} diff --git a/examples/blinky_delay.rs b/examples/blinky_delay.rs new file mode 100644 index 0000000..3f40f33 --- /dev/null +++ b/examples/blinky_delay.rs @@ -0,0 +1,34 @@ +#![no_std] + +#[macro_use] +extern crate nb; +extern crate hifive; + +use hifive::prelude::*; +use hifive::{led, Red, Green, Blue, Clint, UExt}; + +fn delay(clint: &Clint) { + block!(clint.wait()).unwrap(); + clint.restart(); +} + +fn main() { + let peripherals = hifive::init(115_200); + led::init(peripherals.GPIO0); + + let clint = Clint(peripherals.CLINT); + clint.set_timeout(500.ms()); + + let gpio = peripherals.GPIO0; + loop { + Red::on(gpio); + delay(&clint); + Red::off(gpio); + Green::on(gpio); + delay(&clint); + Green::off(gpio); + Blue::on(gpio); + delay(&clint); + Blue::off(gpio); + } +} diff --git a/examples/blinky_plic.rs b/examples/blinky_plic.rs new file mode 100644 index 0000000..86c92e5 --- /dev/null +++ b/examples/blinky_plic.rs @@ -0,0 +1,43 @@ +#![no_std] + +extern crate hifive; + +use hifive::{led, Red, Blue, Green, Interrupt, Plic, Channel, Pwm, Peripherals}; + +fn main() { + let peripherals = hifive::init(115_200); + led::init(peripherals.GPIO0); + + let pwm = Pwm(peripherals.PWM0); + pwm.init(); + pwm.set_cmp(Channel::_0, u16::max_value()); + pwm.set_cmp(Channel::_1, 0); + pwm.set_cmp(Channel::_2, u16::max_value() / 2); + + let plic = Plic(peripherals.PLIC); + plic.enable(Interrupt::PWM0CMP0); + plic.enable(Interrupt::PWM0CMP1); + plic.enable(Interrupt::PWM0CMP2); + plic.enable(Interrupt::PWM0CMP3); +} + +#[no_mangle] +pub fn plic_trap_handler(p: &Peripherals, intr: &Interrupt) { + //let pwm = Pwm(p.PWM0); + + match *intr { + Interrupt::PWM0CMP0 => { + Blue::toggle(p.GPIO0); + }, + Interrupt::PWM0CMP1 => { + Green::toggle(p.GPIO0); + }, + Interrupt::PWM0CMP2 => { + Red::toggle(p.GPIO0); + }, + Interrupt::PWM0CMP3 => { + + }, + _ => {}, + } +} diff --git a/examples/blinky_pwm.rs b/examples/blinky_pwm.rs new file mode 100644 index 0000000..bf0d14a --- /dev/null +++ b/examples/blinky_pwm.rs @@ -0,0 +1,81 @@ +#![no_std] + +extern crate hifive; + +use hifive::{Channel, Align, Pwm}; + +const RED: Channel = Channel::_3; +const GREEN: Channel = Channel::_1; +const BLUE: Channel = Channel::_2; + +/* +struct Color { + red: u8, + green: u8, + blue: u8, +} + +impl Color { + pub fn from(red: u8, green: u8, blue: u8) -> Self { + Color { red, green, blue } + } +} + +fn set_color(pwm: Pwm, color: Color) { + pwm.set_cmp(RED, u16::max_value() / 255 * color.red as u16); + pwm.set_cmp(GREEN, u16::max_value() / 255 * color.green as u16); + pwm.set_cmp(BLUE, u16::max_value() / 255 * color.blue as u16); +} +*/ + +fn main() { + let peripherals = hifive::init(115_200); + let gpio = peripherals.GPIO0; + + //let clint = Clint(peripherals.CLINT); + let pwm = Pwm(peripherals.PWM1); + + pwm.set_cmp(Channel::_0, u16::max_value()); + //pwm.set_period(63); + + pwm.enable(RED, Align::Left, gpio); + pwm.invert(RED, gpio); + pwm.set_cmp(RED, u16::max_value() / 3); + + pwm.enable(GREEN, Align::Center, gpio); + pwm.invert(GREEN, gpio); + pwm.set_cmp(GREEN, u16::max_value() / 2); + + pwm.enable(BLUE, Align::Right, gpio); + pwm.invert(BLUE, gpio); + pwm.set_cmp(BLUE, u16::max_value() / 3 * 2); + + pwm.init(); + + //let delay = 1.s(); + + /*loop { + // Gray + set_color(pwm, Color::from(0x80, 0x80, 0x80)); + clint.set_timeout(delay); + block!(clint.wait()); + // Purple + set_color(pwm, Color::from(0x80, 0x00, 0x80)); + clint.set_timeout(delay); + block!(clint.wait()); + // Maroon + set_color(pwm, Color::from(0x80, 0x00, 0x00)); + clint.set_timeout(delay); + block!(clint.wait()); + }*/ + + //pwm.invert(GREEN, gpio, true); + //pwm.align_center(GREEN); + //pwm.set_cmp(GREEN, u16::max_value() / 2); + + //pwm.align_left(RED); + //pwm.align_right(BLUE); + //pwm.set_cmp(BLUE, u16::max_value() / 3 * 2); + //pwm.set_cmp(BLUE, 0); + //pwm.enable(BLUE, gpio); +} diff --git a/examples/hello_world.rs b/examples/hello_world.rs new file mode 100644 index 0000000..9f5678d --- /dev/null +++ b/examples/hello_world.rs @@ -0,0 +1,13 @@ +#![no_std] + +extern crate hifive; + +use core::fmt::Write; +use hifive::{Port, Serial}; + +fn main() { + let peripherals = hifive::init(115_200); + + let serial = Serial(peripherals.UART0); + writeln!(Port(&serial), "hello world!").unwrap(); +} diff --git a/examples/panicking.rs b/examples/panicking.rs new file mode 100644 index 0000000..5dba0f9 --- /dev/null +++ b/examples/panicking.rs @@ -0,0 +1,20 @@ +#![no_std] + +extern crate hifive; + +fn three() { + panic!() +} + +fn two() { + three(); +} + +fn one() { + two(); +} + +fn main() { + hifive::init(115_200); + one(); +} diff --git a/memory.x b/memory.x new file mode 100644 index 0000000..c991460 --- /dev/null +++ b/memory.x @@ -0,0 +1,22 @@ +MEMORY +{ +/* NOTE K = KiBi = 1024 bytes */ +/* TODO Adjust these memory regions to match your device memory layout */ +FLASH : ORIGIN = 0x20400000, LENGTH = 512M +RAM : ORIGIN = 0x80000000, LENGTH = 16K +} + +/* This is where the call stack will be allocated. */ +/* The stack is of the full descending type. */ +/* You may want to use this variable to locate the call stack and static +variables in different memory regions. Below is shown the default value */ + +/* _stack_start = ORIGIN(RAM) + LENGTH(RAM); */ + +/* You can use this symbol to customize the location of the .text section */ +/* If omitted the .text section will be placed right after the .vector_table +section */ +/* This is required only on microcontrollers that store some configuration right +after the vector table */ + +/* _stext = ORIGIN(FLASH); */ diff --git a/openocd.cfg b/openocd.cfg new file mode 100644 index 0000000..40e7849 --- /dev/null +++ b/openocd.cfg @@ -0,0 +1,34 @@ +adapter_khz 10000 + +interface ftdi +ftdi_device_desc "Dual RS232-HS" +ftdi_vid_pid 0x0403 0x6010 + +ftdi_layout_init 0x0008 0x001b +ftdi_layout_signal nSRST -oe 0x0020 -data 0x0020 + +#Reset Stretcher logic on FE310 is ~1 second long +#This doesn't apply if you use +# ftdi_set_signal, but still good to document +#adapter_nsrst_delay 1500 + +set _CHIPNAME riscv +jtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x10e31913 + +set _TARGETNAME $_CHIPNAME.cpu +target create $_TARGETNAME riscv -chain-position $_TARGETNAME +$_TARGETNAME configure -work-area-phys 0x80000000 -work-area-size 10000 -work-area-backup 1 + +flash bank onboard_spi_flash fespi 0x20000000 0 0 0 $_TARGETNAME +init +#reset -- This type of reset is not implemented yet +if {[ info exists pulse_srst]} { + ftdi_set_signal nSRST 0 + ftdi_set_signal nSRST z + #Wait for the reset stretcher + #It will work without this, but + #will incur lots of delays for later commands. + sleep 1500 +} +halt +#flash protect 0 64 last off \ No newline at end of file diff --git a/src/clint.rs b/src/clint.rs new file mode 100644 index 0000000..e0d905d --- /dev/null +++ b/src/clint.rs @@ -0,0 +1,156 @@ +//! Clint + +use riscv::{csr, interrupt}; +use e310x::CLINT; + +pub struct Clint<'a>(pub &'a CLINT); + +impl<'a> Clone for Clint<'a> { + fn clone(&self) -> Self { + *self + } +} + +impl<'a> Copy for Clint<'a> { +} + +impl<'a> Clint<'a> { + pub fn get_mtime(&self) -> ::aonclk::Ticks { + loop { + let hi = self.0.mtimeh.read().bits(); + let lo = self.0.mtime.read().bits(); + if hi == self.0.mtimeh.read().bits() { + return ::aonclk::Ticks(((hi as u64) << 32) | lo as u64); + } + } + } + + pub fn set_mtime(&self, time: ::aonclk::Ticks) { + unsafe { + self.0.mtimeh.write(|w| w.bits(time.into_hi())); + self.0.mtime.write(|w| w.bits(time.into())); + } + } + + pub fn get_mtimecmp(&self) -> ::aonclk::Ticks { + let hi = self.0.mtimecmph.read().bits() as u64; + let lo = self.0.mtimecmp.read().bits() as u64; + ::aonclk::Ticks(hi << 32 | lo) + } + + pub fn set_mtimecmp(&self, time: ::aonclk::Ticks) { + unsafe { + self.0.mtimecmph.write(|w| w.bits(time.into_hi())); + self.0.mtimecmp.write(|w| w.bits(time.into())); + } + } + + pub fn get_mcycle(&self) -> ::coreclk::Ticks { + loop { + let hi = csr::mcycleh.read().bits(); + let lo = csr::mcycle.read().bits(); + if hi == csr::mcycleh.read().bits() { + return ::coreclk::Ticks(((hi as u64) << 32) | lo as u64); + } + } + } + + pub fn set_mcycle(&self, cycle: ::coreclk::Ticks) { + csr::mcycleh.write(|w| w.bits(cycle.into_hi())); + csr::mcycle.write(|w| w.bits(cycle.into())); + } + + pub fn get_minstret(&self) -> u64 { + loop { + let hi = csr::minstreth.read().bits(); + let lo = csr::minstret.read().bits(); + if hi == csr::minstreth.read().bits() { + return ((hi as u64) << 32) | lo as u64; + } + } + } + + pub fn set_minstret(&self, instret: u64) { + csr::minstreth.write(|w| w.bits((instret >> 32) as u32)); + csr::minstret.write(|w| w.bits(instret as u32)); + } + + + /// Enable the Machine-Timer interrupt + pub fn enable_mtimer(&self) { + csr::mie.set(|w| w.mtimer()); + } + + /// Disable the Machine-Timer interrupt + pub fn disable_mtimer(&self) { + csr::mie.clear(|w| w.mtimer()); + } + + // Is Machine-Timer interrupt pending + pub fn is_mtimer_pending(&self) -> bool { + csr::mip.read().mtimer() + } + + pub fn measure_coreclk(&self, min_ticks: ::aonclk::Ticks) -> u32 { + interrupt::free(|_| { + let clint = self.0; + + // Don't start measuring until we see an mtime tick + while clint.mtime.read().bits() == clint.mtime.read().bits() {} + + let start_cycle = self.get_mcycle(); + let start_time = self.get_mtime(); + + // Wait for min_ticks to pass + while start_time + min_ticks > self.get_mtime() {} + + let end_cycle = self.get_mcycle(); + let end_time = self.get_mtime(); + + let delta_cycle: u32 = (end_cycle - start_cycle).into(); + let delta_time: u32 = (end_time - start_time).into(); + + (delta_cycle / delta_time) * 32768 + + ((delta_cycle % delta_time) * 32768) / delta_time + }) + } +} + +impl<'a> ::hal::Timer for Clint<'a> { + type Time = ::aonclk::Ticks; + + fn get_timeout(&self) -> ::aonclk::Ticks { + self.get_mtimecmp() + } + + fn pause(&self) { + self.disable_mtimer(); + } + + fn restart(&self) { + self.set_mtime(::aonclk::Ticks(0)); + self.enable_mtimer(); + } + + fn resume(&self) { + unimplemented!(); + } + + fn set_timeout(&self, timeout: T) + where + T: Into<::aonclk::Ticks>, + { + self.disable_mtimer(); + self.set_mtimecmp(timeout.into()); + self.set_mtime(::aonclk::Ticks(0)); + self.enable_mtimer(); + } + + fn wait(&self) -> ::nb::Result<(), !> { + if self.is_mtimer_pending() { + Ok(()) + } else { + Err(::nb::Error::WouldBlock) + } + } +} diff --git a/src/clock.rs b/src/clock.rs new file mode 100644 index 0000000..46e36b6 --- /dev/null +++ b/src/clock.rs @@ -0,0 +1,120 @@ +//! Clock configuration +use e310x::{AONCLK, prci, PRCI}; +use clint::Clint; + +/// Aon Clock interface +pub struct AonClock<'a>(pub &'a AONCLK); + +impl<'a> Clone for AonClock<'a> { + fn clone(&self) -> Self { + *self + } +} + +impl<'a> Copy for AonClock<'a> {} + +impl<'a> AonClock<'a> { + /// Use external real time oscillator + pub unsafe fn use_external(&self) { + // The G000 doesn't have a LFXOSC and is hardwired + // to use the an external oscillator. + // Disable unused LFROSC to save power. + self.0.lfrosccfg.write(|w| w.enable().bit(false)); + } +} + +/// Core Clock interface +pub struct CoreClock<'a>(pub &'a PRCI); + +impl<'a> Clone for CoreClock<'a> { + fn clone(&self) -> Self { + *self + } +} + +impl<'a> Copy for CoreClock<'a> { +} + +impl<'a> CoreClock<'a> { + pub unsafe fn use_external(&self, clint: &Clint) { + self.use_pll(clint, |_, w| { + // bypass PLL + w.bypass().bit(true) + // select HFXOSC + .refsel().bit(true) + }, |w| w.divby1().bit(true)); + } + + unsafe fn wait_for_lock(&self, clint: &Clint) { + // Won't lock when bypassed and will loop forever + if !self.0.pllcfg.read().bypass().bit_is_set() { + // Wait for PLL Lock + // Note that the Lock signal can be glitchy. + // Need to wait 100 us + // RTC is running at 32kHz. + // So wait 4 ticks of RTC. + let time = clint.get_mtime() + ::aonclk::Ticks(4); + while clint.get_mtime() < time {} + // Now it is safe to check for PLL Lock + while !self.0.pllcfg.read().lock().bit_is_set() {} + } + } + + pub unsafe fn use_pll(&self, clint: &Clint, pllcfg: F, plloutdiv: G) + where + for<'w> F: FnOnce(&prci::pllcfg::R, + &'w mut prci::pllcfg::W) -> &'w mut prci::pllcfg::W, + for<'w> G: FnOnce(&'w mut prci::plloutdiv::W) -> &'w mut prci::plloutdiv::W, + { + // Make sure we are running of internal clock + // before configuring the PLL. + self.use_internal(); + // Enable HFXOSC + self.0.hfxosccfg.write(|w| w.enable().bit(true)); + // Wait for HFXOSC to stabilize + while !self.0.hfxosccfg.read().ready().bit_is_set() {} + // Configure PLL + self.0.pllcfg.modify(pllcfg); + self.0.plloutdiv.write(plloutdiv); + // Wait for PLL lock + self.wait_for_lock(clint); + // Switch to PLL + self.0.pllcfg.modify(|_, w| { + w.sel().bit(true) + }); + // Disable HFROSC to save power + self.0.hfrosccfg.write(|w| w.enable().bit(false)); + } + + pub unsafe fn use_internal(&self) { + // Enable HFROSC + self.0.hfrosccfg.write(|w| { + w.enable().bit(true) + // It is OK to change this even if we are running off of it. + // Reset them to default values. + .div().bits(4) + .trim().bits(16) + }); + // Wait for HFROSC to stabilize + while !self.0.hfrosccfg.read().ready().bit_is_set() {} + // Switch to HFROSC + self.0.pllcfg.modify(|_, w| { + w.sel().bit(false) + }); + // Bypass PLL to save power + self.0.pllcfg.modify(|_, w| { + w.bypass().bit(true) + // Select HFROSC as PLL ref to disable HFXOSC later + .refsel().bit(false) + }); + // Disable HFXOSC to save power. + self.0.hfxosccfg.write(|w| w.enable().bit(false)); + } + + pub fn measure(&self, clint: &Clint) -> u32 { + // warm up I$ + clint.measure_coreclk(::aonclk::Ticks(1)); + // measure for real + clint.measure_coreclk(::aonclk::Ticks(10)) + } +} diff --git a/src/gpio.rs b/src/gpio.rs new file mode 100644 index 0000000..f5eb655 --- /dev/null +++ b/src/gpio.rs @@ -0,0 +1,204 @@ +//! General Purpose I/O + +use core::ops::Deref; +use e310x::gpio0; + +pub enum PinConfig { + Input, + InputPullup, + Output, + OutputDrive, + IoFn0, + IoFn1, +} + +pub enum PinInterrupt { + Rise, + Fall, + High, + Low, +} + +macro_rules! pin { + ($Pin:ident, $pinx:ident) => ( + pub struct $Pin; + + impl $Pin { + pub fn init(gpio: &T, config: PinConfig) + where + T: Deref, + { + match config { + PinConfig::Input => { + gpio.iof_en.modify(|_, w| w.$pinx().bit(false)); + gpio.pullup.modify(|_, w| w.$pinx().bit(false)); + gpio.input_en.modify(|_, w| w.$pinx().bit(true)); + }, + PinConfig::InputPullup => { + gpio.iof_en.modify(|_, w| w.$pinx().bit(false)); + gpio.pullup.modify(|_, w| w.$pinx().bit(true)); + gpio.input_en.modify(|_, w| w.$pinx().bit(true)); + }, + PinConfig::Output => { + gpio.iof_en.modify(|_, w| w.$pinx().bit(false)); + gpio.drive.modify(|_, w| w.$pinx().bit(false)); + gpio.output_en.modify(|_, w| w.$pinx().bit(true)); + }, + PinConfig::OutputDrive => { + gpio.iof_en.modify(|_, w| w.$pinx().bit(false)); + gpio.drive.modify(|_, w| w.$pinx().bit(true)); + gpio.output_en.modify(|_, w| w.$pinx().bit(true)); + }, + PinConfig::IoFn0 => { + gpio.iof_sel.modify(|_, w| w.$pinx().bit(false)); + gpio.iof_en.modify(|_, w| w.$pinx().bit(true)); + }, + PinConfig::IoFn1 => { + gpio.iof_sel.modify(|_, w| w.$pinx().bit(true)); + gpio.iof_en.modify(|_, w| w.$pinx().bit(true)); + }, + } + } + + pub fn read(gpio: &T) -> bool + where + T: Deref, + { + gpio.value.read().$pinx().bit() + } + + pub fn write(gpio: &T, value: bool) + where + T: Deref, + { + match value { + true => $Pin::high(gpio), + false => $Pin::low(gpio), + } + } + + pub fn high(gpio: &T) + where + T: Deref, + { + gpio.port.modify(|_, w| w.$pinx().bit(true)); + } + + pub fn low(gpio: &T) + where + T: Deref, + { + gpio.port.modify(|_, w| w.$pinx().bit(false)); + } + + pub fn toggle(gpio: &T) + where + T: Deref, + { + gpio.port.modify(|r, w| w.$pinx().bit(!r.$pinx().bit())); + } + + pub fn enable_interrupt(gpio: &T, intr: PinInterrupt) + where + T: Deref, + { + match intr { + PinInterrupt::Rise => + gpio.rise_ie.modify(|_, w| w.$pinx().bit(true)), + PinInterrupt::Fall => + gpio.fall_ie.modify(|_, w| w.$pinx().bit(true)), + PinInterrupt::High => + gpio.high_ie.modify(|_, w| w.$pinx().bit(true)), + PinInterrupt::Low => + gpio.low_ie.modify(|_, w| w.$pinx().bit(true)), + }; + } + + pub fn disable_interrupt(gpio: &T, intr: PinInterrupt) + where + T: Deref, + { + match intr { + PinInterrupt::Rise => + gpio.rise_ie.modify(|_, w| w.$pinx().bit(false)), + PinInterrupt::Fall => + gpio.fall_ie.modify(|_, w| w.$pinx().bit(false)), + PinInterrupt::High => + gpio.high_ie.modify(|_, w| w.$pinx().bit(false)), + PinInterrupt::Low => + gpio.low_ie.modify(|_, w| w.$pinx().bit(false)), + }; + } + + pub fn is_interrupt_pending(gpio: &T, intr: PinInterrupt) -> bool + where + T: Deref, + { + match intr { + PinInterrupt::Rise => + gpio.rise_ip.read().$pinx().bit(), + PinInterrupt::Fall => + gpio.fall_ip.read().$pinx().bit(), + PinInterrupt::High => + gpio.high_ip.read().$pinx().bit(), + PinInterrupt::Low => + gpio.low_ip.read().$pinx().bit(), + } + } + + pub fn is_inverted(gpio: &T) -> bool + where + T: Deref, + { + gpio.out_xor.read().$pinx().bit() + } + + pub fn set_invert(gpio: &T, value: bool) + where + T: Deref, + { + gpio.out_xor.modify(|_, w| w.$pinx().bit(value)); + } + + pub fn invert(gpio: &T) + where + T: Deref, + { + gpio.out_xor.modify(|r, w| w.$pinx().bit(!r.$pinx().bit())); + } + } + ) +} + +pin!(Pin0, pin0); +pin!(Pin1, pin1); +pin!(Pin2, pin2); +pin!(Pin3, pin3); +pin!(Pin4, pin4); +pin!(Pin5, pin5); +pin!(Pin6, pin6); +pin!(Pin7, pin7); +pin!(Pin8, pin8); +pin!(Pin9, pin9); +pin!(Pin10, pin10); +pin!(Pin11, pin11); +pin!(Pin12, pin12); +pin!(Pin13, pin13); +pin!(Pin14, pin14); +pin!(Pin15, pin15); +pin!(Pin16, pin16); +pin!(Pin17, pin17); +pin!(Pin18, pin18); +pin!(Pin19, pin19); +pin!(Pin20, pin20); +pin!(Pin21, pin21); +pin!(Pin22, pin22); +pin!(Pin23, pin23); +pin!(Pin24, pin24); +pin!(Pin25, pin25); +pin!(Pin26, pin26); +pin!(Pin27, pin27); +pin!(Pin28, pin28); +pin!(Pin29, pin29); +pin!(Pin30, pin30); +pin!(Pin31, pin31); diff --git a/src/led.rs b/src/led.rs new file mode 100644 index 0000000..a52d1d8 --- /dev/null +++ b/src/led.rs @@ -0,0 +1,42 @@ +//! User LEDs +//! +//! - Red = Pin 22 +//! - Green = Pin 19 +//! - Blue = Pin 21 + +use e310x::GPIO0; +use gpio::{PinConfig, Pin22, Pin19, Pin21}; + +pub fn init(gpio: &GPIO0) { + Pin22::set_invert(gpio, true); + Pin22::init(gpio, PinConfig::Output); + Pin19::set_invert(gpio, true); + Pin19::init(gpio, PinConfig::Output); + Pin21::set_invert(gpio, true); + Pin21::init(gpio, PinConfig::Output); +} + +#[macro_export] +macro_rules! led { + ($Color:ident, $Pin:ident) => { + pub struct $Color; + + impl $Color { + pub fn on(gpio: &GPIO0) { + $Pin::high(gpio); + } + + pub fn off(gpio: &GPIO0) { + $Pin::low(gpio); + } + + pub fn toggle(gpio: &GPIO0) { + $Pin::toggle(gpio); + } + } + } +} + +led!(Red, Pin22); +led!(Green, Pin19); +led!(Blue, Pin21); diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..d2ff730 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,225 @@ +#![no_std] +#![feature(asm)] +#![feature(core_intrinsics)] +#![feature(get_type_id)] +#![feature(lang_items)] +#![feature(linkage)] +#![feature(never_type)] +#![feature(used)] + +extern crate embedded_hal as hal; +#[macro_use] +extern crate nb; + +extern crate riscv; +pub extern crate e310x; + +pub mod clint; +pub mod clock; +pub mod gpio; +pub mod led; +pub mod plic; +pub mod pwm; +pub mod serial; +pub mod time; + +use core::fmt::Write; +use riscv::interrupt::Nr; + +pub use hal::prelude; +pub use e310x::Peripherals; +pub use clint::Clint; +pub use led::{Red, Green, Blue}; +pub use plic::{Priority, Interrupt, Plic}; +pub use pwm::{Align, Channel, Pwm}; +pub use serial::{Serial, Port}; +pub use time::UExt; + +/// Initializes the clocks, plic and uart0. Returns Peripherals +/// for application specific initialization. +pub fn init<'a>(baud_rate: u32) -> e310x::Peripherals<'a> { + let peripherals = unsafe { e310x::Peripherals::all() }; + + // Setup clocks + let clint = Clint(peripherals.CLINT); + let aon_clock = clock::AonClock(peripherals.AONCLK); + unsafe { aon_clock.use_external(); } + let clock = clock::CoreClock(peripherals.PRCI); + unsafe { clock.use_external(&clint); } + + // Setup PLIC + let plic = Plic(peripherals.PLIC); + plic.init(); + + // Initialize UART0 + let serial = Serial(peripherals.UART0); + serial.init(baud_rate.hz().invert(), peripherals.GPIO0); + writeln!(Port(&serial), "Initialized hifive board").unwrap(); + + peripherals +} + +/// Default trap handler +/// +/// Prints trap cause and calls mtimer_trap_handler or plic_trap_handler if +/// necessary. +#[used] +#[no_mangle] +fn trap_handler(trap: riscv::csr::Trap) { + use riscv::csr::{Trap, Interrupt}; + + let peripherals = unsafe { e310x::Peripherals::all() }; + let serial = Serial(peripherals.UART0); + + match trap { + Trap::Interrupt(x) => { + match x { + Interrupt::MachineTimer => { + writeln!(Port(&serial), "MachineTimer").unwrap(); + mtimer_trap_handler(&peripherals); + }, + Interrupt::MachineExternal => { + let plic = Plic(peripherals.PLIC); + let intr = plic.claim(); + + writeln!(Port(&serial), "{:?} {}", intr, intr.nr()).unwrap(); + plic_trap_handler(&peripherals, &intr); + + plic.complete(intr); + } + x => { + writeln!(Port(&serial), "Interrupt {:?}", x).unwrap(); + }, + } + }, + Trap::Exception(x) => { + writeln!(Port(&serial), "Exception {:?}", x).unwrap(); + }, + } +} + +/// Default MachineTimer Trap Handler +#[no_mangle] +#[linkage = "weak"] +fn mtimer_trap_handler(_: &e310x::Peripherals) {} + +/// Default MachineExternal Trap Handler +#[no_mangle] +#[linkage = "weak"] +fn plic_trap_handler(_: &e310x::Peripherals, _: &Interrupt) {} + + +macro_rules! ticks_impl { + ($n:ident, $t:ty, $f:expr) => { + pub const $n: $t = $f as $t; + + impl Ticks<$t> { + /// Applies the function `f` to the inner value + pub fn map(self, f: F) -> Ticks<$t> + where F: FnOnce($t) -> $t, + { + Ticks(f(self.0)) + } + } + + impl From> for Microseconds<$t> { + fn from(ticks: Ticks<$t>) -> Microseconds<$t> { + let divisor: $t = $n / 1_000_000; + Microseconds(ticks.0 / divisor) + } + } + + impl From> for Milliseconds<$t> { + fn from(ticks: Ticks<$t>) -> Milliseconds<$t> { + Milliseconds(ticks.0 / ($n / 1_000)) + } + } + + impl From> for Seconds<$t> { + fn from(ticks: Ticks<$t>) -> Seconds<$t> { + Seconds(ticks.0 / $n) + } + } + + impl From> for Ticks<$t> { + fn from(ihz: IHertz<$t>) -> Ticks<$t> { + Ticks($n / ihz.0) + } + } + + impl From> for Ticks<$t> { + fn from(us: Microseconds<$t>) -> Ticks<$t> { + Ticks(us.0 * ($n / 1_000_000)) + } + } + + impl From> for Ticks<$t> { + fn from(ms: Milliseconds<$t>) -> Ticks<$t> { + Ticks(ms.0 * ($n / 1_000)) + } + } + + impl From> for Ticks<$t> { + fn from(s: Seconds<$t>) -> Ticks<$t> { + Ticks(s.0 * $n) + } + } + + impl Into<$t> for Ticks<$t> { + fn into(self) -> $t { + self.0 + } + } + + impl ::core::ops::Add for Ticks<$t> { + type Output = Ticks<$t>; + + fn add(self, other: Ticks<$t>) -> Ticks<$t> { + Ticks(self.0 + other.0) + } + } + + impl ::core::ops::Sub for Ticks<$t> { + type Output = Ticks<$t>; + + fn sub(self, other: Ticks<$t>) -> Ticks<$t> { + Ticks(self.0 - other.0) + } + } + } +} + +macro_rules! frequency { + ($FREQUENCY:expr) => { + use time::*; + + /// Unit of time + #[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)] + pub struct Ticks(pub T); + + ticks_impl!(FREQUENCY_32, u32, $FREQUENCY); + ticks_impl!(FREQUENCY_64, u64, $FREQUENCY); + + impl Into for Ticks { + fn into(self) -> u32 { + self.0 as u32 + } + } + + impl Ticks { + pub fn into_hi(self) -> u32 { + (self.0 >> 32) as u32 + } + } + } +} + +/// Always-On Clock +pub mod aonclk { + frequency!(32_768); +} + +/// Core Clock +pub mod coreclk { + frequency!(16_000_000); +} diff --git a/src/plic.rs b/src/plic.rs new file mode 100644 index 0000000..8130cc6 --- /dev/null +++ b/src/plic.rs @@ -0,0 +1,125 @@ +use riscv::interrupt::Nr; +use e310x::PLIC; +pub use e310x::Interrupt; + +pub enum Priority { + Never, P1, P2, P3, P4, P5, P6, P7, +} + +impl Priority { + pub fn from(prio: u32) -> Priority { + match prio { + 0 => Priority::Never, + 1 => Priority::P1, + 2 => Priority::P2, + 3 => Priority::P3, + 4 => Priority::P4, + 5 => Priority::P5, + 6 => Priority::P6, + 7 => Priority::P7, + _ => unreachable!(), + } + } +} + +impl Into for Priority { + fn into(self) -> u32 { + match self { + Priority::Never => 0, + Priority::P1 => 1, + Priority::P2 => 2, + Priority::P3 => 3, + Priority::P4 => 4, + Priority::P5 => 5, + Priority::P6 => 6, + Priority::P7 => 7, + } + } +} + +pub struct Plic<'a>(pub &'a PLIC); + +impl<'a> Clone for Plic<'a> { + fn clone(&self) -> Self { + *self + } +} + +impl<'a> Copy for Plic<'a> { +} + +impl<'a> Plic<'a> { + pub fn init(&self) { + for reg in self.0.enable.iter() { + unsafe { + reg.write(|w| w.bits(0)); + } + } + //interrupt!(MachineExternal, plic::plic_handler()); + } + + /*pub fn handler(&self, f: F) where F: Fn { + let intr = plic.claim(); + f(intr); + plic.complete(intr); + }*/ + + pub fn is_pending(&self, intr: Interrupt) -> bool { + let mask = 1 << (intr.nr() % 32); + let pending = self.0.pending[(intr.nr() / 32) as usize].read(); + pending.bits() & mask == mask + } + + pub fn is_enabled(&self, intr: Interrupt) -> bool { + let mask = 1 << (intr.nr() % 32); + let enable = self.0.enable[(intr.nr() / 32) as usize].read(); + enable.bits() & mask == mask + } + + pub fn enable(&self, intr: Interrupt) { + let mask = 1 << (intr.nr() % 32); + unsafe { + self.0.enable[(intr.nr() / 32) as usize] + .modify(|r, w| w.bits(r.bits() | mask)); + } + } + + pub fn disable(&self, intr: Interrupt) { + let mask = 1 << (intr.nr() % 32); + unsafe { + self.0.enable[(intr.nr() / 32) as usize] + .modify(|r, w| w.bits(r.bits() & !mask)); + } + } + + pub fn claim(&self) -> Interrupt { + Interrupt::from(self.0.claim.read().bits() as u8) + } + + pub fn complete(&self, intr: Interrupt) { + unsafe { + self.0.claim.write(|w| w.bits(intr.nr() as u32)); + } + } + + pub fn get_priority(&self, intr: Interrupt) -> Priority { + Priority::from(self.0.priority[(intr.nr() - 1) as usize].read().bits()) + } + + pub fn set_priority(&self, intr: Interrupt, prio: Priority) { + unsafe { + self.0.priority[(intr.nr() - 1) as usize] + .write(|w| w.bits(prio.into())); + } + } + + pub fn get_threshold(&self) -> Priority { + Priority::from(self.0.threshold.read().bits()) + } + + pub fn set_threshold(&self, prio: Priority) { + unsafe { + self.0.threshold.write(|w| w.bits(prio.into())); + } + } +} diff --git a/src/pwm.rs b/src/pwm.rs new file mode 100644 index 0000000..a105226 --- /dev/null +++ b/src/pwm.rs @@ -0,0 +1,515 @@ +//! Pulse Width Modulation +//! +//! You can use the `Pwm` interface with these PWM instances +//! +//! # PWM0 +//! +//! - CH0: Pin 0 IOF1 +//! - CH1: Pin 1 IOF1 +//! - CH2: Pin 2 IOF1 +//! - CH3: Pin 3 IOF1 +//! +//! # PWM1 +//! +//! - CH0: Pin 20 IOF1 +//! - CH1: Pin 19 IOF1 +//! - CH2: Pin 21 IOF1 +//! - CH3: Pin 22 IOF1 +//! +//! # PWM2 +//! +//! - CH0: Pin 10 IOF1 +//! - CH1: Pin 11 IOF1 +//! - CH2: Pin 12 IOF1 +//! - CH3: Pin 13 IOF1 + +use core::any::{Any, TypeId}; +use core::ops::Deref; + +use e310x::{pwm0, PWM0, PWM1, PWM2, gpio0, GPIO0}; +use gpio::{PinConfig, Pin0, Pin1, Pin2, Pin3, Pin20, Pin19, + Pin21, Pin22, Pin10, Pin11, Pin12, Pin13}; + +/// Channel +#[derive(Clone, Copy, Debug)] +pub enum Channel { + /// CH0 + _0, + /// CH1 + _1, + /// CH2 + _2, + /// CH3 + _3, +} + +/// Channel +#[derive(Clone, Copy, Debug)] +pub enum Align { + /// Left + Left, + /// Center + Center, + /// Right + Right, +} + +/// IMPLEMENTATION DETAIL +pub unsafe trait PWM: Deref { + /// IMPLEMENTATION DETAIL + type GPIO: Deref; +} + +unsafe impl PWM for PWM0 { + type GPIO = GPIO0; +} + +unsafe impl PWM for PWM1 { + type GPIO = GPIO0; +} + +unsafe impl PWM for PWM2 { + type GPIO = GPIO0; +} + +pub struct Pwm<'a, T>(pub &'a T) + where + T: 'a; + +impl<'a, T> Clone for Pwm<'a, T> { + fn clone(&self) -> Self { + *self + } +} + +impl<'a, T> Copy for Pwm<'a, T> {} + +impl<'a, T> Pwm<'a, T> + where + T: Any + PWM, +{ + pub fn init(&self) { + unsafe { + self.0.cfg.modify(|_, w| { + w.enalways().bit(true) + // set period of 1s + .scale().bits(8) + .zerocmp().bit(true) + }); + self.0.count.write(|w| w.bits(0)); + } + } + + pub fn enable(&self, channel: Channel, align: Align, gpio: &T::GPIO) { + if self.0.get_type_id() == TypeId::of::() { + match channel { + Channel::_0 => { + Pin0::init(gpio, PinConfig::IoFn1); + match align { + Align::Left => { + Pin0::set_invert(gpio, true); + self.set_center(channel, false); + }, + Align::Center => { + Pin0::set_invert(gpio, false); + self.set_center(channel, true); + }, + Align::Right => { + Pin0::set_invert(gpio, false); + self.set_center(channel, false); + } + } + }, + Channel::_1 => { + Pin1::init(gpio, PinConfig::IoFn1); + match align { + Align::Left => { + Pin1::set_invert(gpio, true); + self.set_center(channel, false); + }, + Align::Center => { + Pin1::set_invert(gpio, false); + self.set_center(channel, true); + }, + Align::Right => { + Pin1::set_invert(gpio, false); + self.set_center(channel, false); + } + } + }, + Channel::_2 => { + Pin2::init(gpio, PinConfig::IoFn1); + match align { + Align::Left => { + Pin2::set_invert(gpio, true); + self.set_center(channel, false); + }, + Align::Center => { + Pin2::set_invert(gpio, false); + self.set_center(channel, true); + }, + Align::Right => { + Pin2::set_invert(gpio, false); + self.set_center(channel, false); + } + } + }, + Channel::_3 => { + Pin3::init(gpio, PinConfig::IoFn1); + match align { + Align::Left => { + Pin3::set_invert(gpio, true); + self.set_center(channel, false); + }, + Align::Center => { + Pin3::set_invert(gpio, false); + self.set_center(channel, true); + }, + Align::Right => { + Pin3::set_invert(gpio, false); + self.set_center(channel, false); + } + } + }, + } + } else if self.0.get_type_id() == TypeId::of::() { + match channel { + Channel::_0 => { + Pin20::init(gpio, PinConfig::IoFn1); + match align { + Align::Left => { + Pin20::set_invert(gpio, true); + self.set_center(channel, false); + }, + Align::Center => { + Pin20::set_invert(gpio, false); + self.set_center(channel, true); + }, + Align::Right => { + Pin20::set_invert(gpio, false); + self.set_center(channel, false); + } + } + }, + Channel::_1 => { + Pin19::init(gpio, PinConfig::IoFn1); + match align { + Align::Left => { + Pin19::set_invert(gpio, true); + self.set_center(channel, false); + }, + Align::Center => { + Pin19::set_invert(gpio, false); + self.set_center(channel, true); + }, + Align::Right => { + Pin19::set_invert(gpio, false); + self.set_center(channel, false); + } + } + }, + Channel::_2 => { + Pin21::init(gpio, PinConfig::IoFn1); + match align { + Align::Left => { + Pin21::set_invert(gpio, true); + self.set_center(channel, false); + }, + Align::Center => { + Pin21::set_invert(gpio, false); + self.set_center(channel, true); + }, + Align::Right => { + Pin21::set_invert(gpio, false); + self.set_center(channel, false); + } + } + }, + Channel::_3 => { + Pin22::init(gpio, PinConfig::IoFn1); + match align { + Align::Left => { + Pin22::set_invert(gpio, true); + self.set_center(channel, false); + }, + Align::Center => { + Pin22::set_invert(gpio, false); + self.set_center(channel, true); + }, + Align::Right => { + Pin22::set_invert(gpio, false); + self.set_center(channel, false); + } + } + }, + } + } else if self.0.get_type_id() == TypeId::of::() { + match channel { + Channel::_0 => { + Pin10::init(gpio, PinConfig::IoFn1); + match align { + Align::Left => { + Pin10::set_invert(gpio, true); + self.set_center(channel, false); + }, + Align::Center => { + Pin10::set_invert(gpio, false); + self.set_center(channel, true); + }, + Align::Right => { + Pin10::set_invert(gpio, false); + self.set_center(channel, false); + } + } + }, + Channel::_1 => { + Pin11::init(gpio, PinConfig::IoFn1); + match align { + Align::Left => { + Pin11::set_invert(gpio, true); + self.set_center(channel, false); + }, + Align::Center => { + Pin11::set_invert(gpio, false); + self.set_center(channel, true); + }, + Align::Right => { + Pin11::set_invert(gpio, false); + self.set_center(channel, false); + } + } + }, + Channel::_2 => { + Pin12::init(gpio, PinConfig::IoFn1); + match align { + Align::Left => { + Pin12::set_invert(gpio, true); + self.set_center(channel, false); + }, + Align::Center => { + Pin12::set_invert(gpio, false); + self.set_center(channel, true); + }, + Align::Right => { + Pin12::set_invert(gpio, false); + self.set_center(channel, false); + } + } + }, + Channel::_3 => { + Pin13::init(gpio, PinConfig::IoFn1); + match align { + Align::Left => { + Pin13::set_invert(gpio, true); + self.set_center(channel, false); + }, + Align::Center => { + Pin13::set_invert(gpio, false); + self.set_center(channel, true); + }, + Align::Right => { + Pin13::set_invert(gpio, false); + self.set_center(channel, false); + } + } + }, + } + } + } + + pub fn disable(&self, channel: Channel, gpio: &T::GPIO) { + if self.0.get_type_id() == TypeId::of::() { + match channel { + Channel::_0 => Pin0::init(gpio, PinConfig::Input), + Channel::_1 => Pin1::init(gpio, PinConfig::Input), + Channel::_2 => Pin2::init(gpio, PinConfig::Input), + Channel::_3 => Pin3::init(gpio, PinConfig::Input), + } + } else if self.0.get_type_id() == TypeId::of::() { + match channel { + Channel::_0 => Pin20::init(gpio, PinConfig::Input), + Channel::_1 => Pin19::init(gpio, PinConfig::Input), + Channel::_2 => Pin21::init(gpio, PinConfig::Input), + Channel::_3 => Pin22::init(gpio, PinConfig::Input), + } + } else if self.0.get_type_id() == TypeId::of::() { + match channel { + Channel::_0 => Pin10::init(gpio, PinConfig::Input), + Channel::_1 => Pin11::init(gpio, PinConfig::Input), + Channel::_2 => Pin12::init(gpio, PinConfig::Input), + Channel::_3 => Pin13::init(gpio, PinConfig::Input), + } + } + } + + pub fn invert(&self, channel: Channel, gpio: &T::GPIO) { + if self.0.get_type_id() == TypeId::of::() { + match channel { + Channel::_0 => Pin0::invert(gpio), + Channel::_1 => Pin1::invert(gpio), + Channel::_2 => Pin2::invert(gpio), + Channel::_3 => Pin3::invert(gpio), + } + } else if self.0.get_type_id() == TypeId::of::() { + match channel { + Channel::_0 => Pin20::invert(gpio), + Channel::_1 => Pin19::invert(gpio), + Channel::_2 => Pin21::invert(gpio), + Channel::_3 => Pin22::invert(gpio), + } + } else if self.0.get_type_id() == TypeId::of::() { + match channel { + Channel::_0 => Pin10::invert(gpio), + Channel::_1 => Pin11::invert(gpio), + Channel::_2 => Pin12::invert(gpio), + Channel::_3 => Pin13::invert(gpio), + } + } + } + + pub fn set_period

(&self, period: P) + where P: Into<::coreclk::Ticks> + { + let ticks: u32 = period.into().into(); + let scale = u16::max_value() as u32 / ticks; + assert!(scale < 0x10); + ::riscv::asm::ebreak(); + unsafe { + self.0.cfg.modify(|_, w| w.scale().bits(scale as u8)); + } + } + + pub fn get_period(&self) -> ::coreclk::Ticks { + let scale = self.0.cfg.read().scale().bits(); + ::coreclk::Ticks(scale as u32 * u16::max_value() as u32) + } + + pub fn align_left(&self, channel: Channel, gpio: &T::GPIO) { + match channel { + Channel::_0 => { + self.0.cfg.modify(|_, w| w.cmp0center().bit(false)); + self.invert(channel, gpio); + }, + Channel::_1 => { + self.0.cfg.modify(|_, w| w.cmp1center().bit(false)); + self.invert(channel, gpio); + }, + Channel::_2 => { + self.0.cfg.modify(|_, w| w.cmp2center().bit(false)); + self.invert(channel, gpio); + } + Channel::_3 => { + self.0.cfg.modify(|_, w| w.cmp3center().bit(false)); + self.invert(channel, gpio); + } + } + } + + fn set_center(&self, channel: Channel, value: bool) { + match channel { + Channel::_0 => self.0.cfg.modify(|_, w| w.cmp0center().bit(value)), + Channel::_1 => self.0.cfg.modify(|_, w| w.cmp1center().bit(value)), + Channel::_2 => self.0.cfg.modify(|_, w| w.cmp2center().bit(value)), + Channel::_3 => self.0.cfg.modify(|_, w| w.cmp3center().bit(value)), + } + } + + pub fn get_cmp(&self, channel: Channel) -> u16 { + match channel { + Channel::_0 => self.0.cmp0.read().value().bits(), + Channel::_1 => self.0.cmp1.read().value().bits(), + Channel::_2 => self.0.cmp2.read().value().bits(), + Channel::_3 => self.0.cmp3.read().value().bits(), + } + } + + pub fn set_cmp(&self, channel: Channel, cmp: u16) { + unsafe { + match channel { + Channel::_0 => self.0.cmp0.write(|w| w.value().bits(cmp)), + Channel::_1 => self.0.cmp1.write(|w| w.value().bits(cmp)), + Channel::_2 => self.0.cmp2.write(|w| w.value().bits(cmp)), + Channel::_3 => self.0.cmp3.write(|w| w.value().bits(cmp)), + } + } + } +} + +/* +/// `hal::Pwm` implementation +impl<'a, T> hal::Pwm for Pwm<'a, T> + where + T: Any + PWM, +{ + type Channel = Channel; + type Duty = u16; + type Time = ::coreclk::Ticks; + + fn get_duty(&self, channel: Channel) -> u16 { + self.get_cmp(channel) + } + + fn disable(&self, channel: Channel) { + + } + + fn enable(&self, channel: Channel) { + + } + + fn get_max_duty(&self) -> u16 { + u16::max_value() + } + + fn get_period(&self) -> ::coreclk::Ticks { + self.get_period() + } + + fn set_duty(&self, channel: Channel, duty: u16) { + self.set_cmp(channel, duty); + } + + fn set_period

(&self, period: P) + where + P: Into<::coreclk::Ticks>, + { + self.set_period(period.into()); + } +} + +#[allow(unused_variables)] +/// `hal::Timer` implementation +impl<'a, T> hal::Timer for Pwm<'a, T> + where + T: Any + PWM +{ + type Time = ::coreclk::Ticks; + + fn get_timeout(&self) -> ::coreclk::Ticks { + ::coreclk::Ticks(10) + } + + fn pause(&self) { + + } + + fn restart(&self) { + + } + + fn resume(&self) { + + } + + fn set_timeout(&self, timeout: TO) + where + TO: Into<::coreclk::Ticks>, + { + + } + + fn wait(&self) -> nb::Result<(), !> { + Ok(()) + } +} +*/ diff --git a/src/serial.rs b/src/serial.rs new file mode 100644 index 0000000..0008043 --- /dev/null +++ b/src/serial.rs @@ -0,0 +1,151 @@ +//! Serial interface +//! +//! You can use the `Serial` interface with these UART instances +//! +//! # UART0 +//! - TX: Pin 17 IOF0 +//! - RX: Pin 16 IOF0 +//! - Interrupt::UART0 +//! +//! # UART1 +//! - TX: Pin 25 IOF0 +//! - RX: Pin 24 IOF0 +//! - Interrupt::UART1 + + +use core::any::{Any, TypeId}; +use core::ops::Deref; +use e310x::{gpio0, GPIO0, uart0, UART0, UART1}; +use gpio::{PinConfig, Pin17, Pin16, Pin25, Pin24}; + +/// IMPLEMENTATION DETAIL +pub unsafe trait Uart: Deref { + /// IMPLEMENTATION DETAIL + type GPIO: Deref; + type Ticks: Into; +} + +unsafe impl Uart for UART0 { + type GPIO = GPIO0; + type Ticks = ::coreclk::Ticks; +} + +unsafe impl Uart for UART1 { + type GPIO = GPIO0; + type Ticks = ::coreclk::Ticks; +} + +/// Serial interface +pub struct Serial<'a, U>(pub &'a U) +where + U: Any + Uart; + +impl<'a, U> Clone for Serial<'a, U> +where + U: Any + Uart, +{ + fn clone(&self) -> Self { + *self + } +} + +impl<'a, U> Copy for Serial<'a, U> +where + U: Any + Uart, +{ +} + +impl<'a, U> Serial<'a, U> +where + U: Any + Uart, +{ + /// Initializes the serial interface with a baud rate of `baud_rate` bits + /// per second + pub fn init(&self, baud_rate: B, gpio: &U::GPIO) + where B: Into, + { + if self.0.get_type_id() == TypeId::of::() { + Pin16::init(gpio, PinConfig::IoFn0); + Pin17::init(gpio, PinConfig::IoFn0); + } else if self.0.get_type_id() == TypeId::of::() { + Pin24::init(gpio, PinConfig::IoFn0); + Pin25::init(gpio, PinConfig::IoFn0); + } + + unsafe { + let div = baud_rate.into().into(); + self.0.div.write(|w| w.bits(div)); + + self.0.txctrl.write(|w| w.enable().bit(true)); + self.0.rxctrl.write(|w| w.enable().bit(true)); + } + } +} + +impl<'a, U> ::hal::serial::Read for Serial<'a, U> +where + U: Any + Uart, +{ + type Error = !; + + fn read(&self) -> ::nb::Result { + let uart = self.0; + let rxdata = uart.rxdata.read(); + + if rxdata.empty().bit_is_set() { + Err(::nb::Error::WouldBlock) + } else { + Ok(rxdata.data().bits() as u8) + } + } +} + +impl<'a, U> ::hal::serial::Write for Serial<'a, U> +where + U: Any + Uart, +{ + type Error = !; + + fn write(&self, byte: u8) -> ::nb::Result<(), !> { + let uart = self.0; + let txdata = uart.txdata.read(); + + if txdata.full().bit_is_set() { + Err(::nb::Error::WouldBlock) + } else { + unsafe { + uart.txdata.write(|w| w.data().bits(byte)); + } + Ok(()) + } + } +} + +/// Port +pub struct Port<'p, T>(pub &'p T) + where + T: 'p; + +impl<'p, T> ::core::fmt::Write for Port<'p, T> + where + T: ::hal::serial::Write, +{ + fn write_str(&mut self, s: &str) -> ::core::fmt::Result { + for byte in s.as_bytes() { + let res = block!(self.0.write(*byte)); + + if res.is_err() { + return Err(::core::fmt::Error); + } + + if *byte == '\n' as u8 { + let res = block!(self.0.write('\r' as u8)); + + if res.is_err() { + return Err(::core::fmt::Error); + } + } + } + Ok(()) + } +} diff --git a/src/time.rs b/src/time.rs new file mode 100644 index 0000000..ed86a9f --- /dev/null +++ b/src/time.rs @@ -0,0 +1,110 @@ +//! Units of time + +macro_rules! map { + ($Self:ident) => { + impl $Self { + /// Applies the function `f` to inner value + pub fn map(self, f: F) -> $Self + where + F: FnOnce(T) -> T + { + $Self(f(self.0)) + } + } + } +} + +/// `Hz^-1` +#[derive(Clone, Copy, Debug)] +pub struct IHertz(pub T); + +impl IHertz { + /// Invert this quantity + pub fn invert(self) -> Hertz { + Hertz(self.0) + } +} + +map!(IHertz); + +/// `Hz` +#[derive(Clone, Copy, Debug)] +pub struct Hertz(pub T); + +impl Hertz { + /// Invert this quantity + pub fn invert(self) -> IHertz { + IHertz(self.0) + } +} + +map!(Hertz); + +/// `us` +#[derive(Clone, Copy, Debug)] +pub struct Microseconds(pub T); + +map!(Microseconds); + +/// `ms` +#[derive(Clone, Copy, Debug)] +pub struct Milliseconds(pub T); + +map!(Milliseconds); + +/// `s` +#[derive(Clone, Copy, Debug)] +pub struct Seconds(pub T); + +map!(Seconds); + +/// `u32` and `u64` extension trait +pub trait UExt { + /// Wrap in `Hz` + fn hz(self) -> Hertz; + + /// Wrap in `Milliseconds` + fn ms(self) -> Milliseconds; + + /// Wrap in `Seconds` + fn s(self) -> Seconds; + + /// Wrap in `Microseconds` + fn us(self) -> Microseconds; +} + +impl UExt for u32 { + fn hz(self) -> Hertz { + Hertz(self) + } + + fn ms(self) -> Milliseconds { + Milliseconds(self) + } + + fn s(self) -> Seconds { + Seconds(self) + } + + fn us(self) -> Microseconds { + Microseconds(self) + } +} + +impl UExt for u64 { + fn hz(self) -> Hertz { + Hertz(self) + } + + fn ms(self) -> Milliseconds { + Milliseconds(self) + } + + fn s(self) -> Seconds { + Seconds(self) + } + + fn us(self) -> Microseconds { + Microseconds(self) + } +} From cc1da45e80da5588732b4bde43eadf1743dbb35b Mon Sep 17 00:00:00 2001 From: David Craven Date: Mon, 20 Nov 2017 09:36:22 +0100 Subject: [PATCH 002/112] Remove unneeded feature. --- src/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index d2ff730..ca57aac 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,6 +1,5 @@ #![no_std] #![feature(asm)] -#![feature(core_intrinsics)] #![feature(get_type_id)] #![feature(lang_items)] #![feature(linkage)] From 7750e352f0a8ab9ca6f7d0b5056d67ccf3cbd41a Mon Sep 17 00:00:00 2001 From: David Craven Date: Mon, 20 Nov 2017 13:27:42 +0100 Subject: [PATCH 003/112] Cleanup. --- Makefile | 8 +++----- examples/panicking.rs | 1 - 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index 0ce4811..7cde44e 100644 --- a/Makefile +++ b/Makefile @@ -5,11 +5,6 @@ EXAMPLE := blinky_delay #EXAMPLE := blinky_plic #EXAMPLE := hello_world #EXAMPLE := panicking -#EXAMPLE := heaps -#EXAMPLE := rtc -#EXAMPLE := watchdog -#EXAMPLE := utest -#EXAMPLE := rtfm # Board crate (uncomment one) BOARD := hifive @@ -48,4 +43,7 @@ upload: openocd -f $(OPENOCD_CFG) \ -c "flash protect 0 64 last off; program ${EXAMPLE_BIN}; resume 0x20400000; exit" +framedump: + riscv32-unknown-elf-readelf --debug-dump=frames $(EXAMPLE_BIN) $(ARGS) + .PHONY: build clean readelf objdump framedump size gdb openocd spike diff --git a/examples/panicking.rs b/examples/panicking.rs index 5dba0f9..480534f 100644 --- a/examples/panicking.rs +++ b/examples/panicking.rs @@ -15,6 +15,5 @@ fn one() { } fn main() { - hifive::init(115_200); one(); } From a554b5e0d89f9eb29451500298e39bbc13469ace Mon Sep 17 00:00:00 2001 From: David Craven Date: Mon, 20 Nov 2017 14:32:27 +0100 Subject: [PATCH 004/112] Use git versions. --- Cargo.toml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index acabf39..29d8477 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,15 +15,15 @@ rev = "7d904f515d15fd5fe7ea34e18820ea83e2651fa2" [dependencies.nb] git = "https://github.com/japaric/nb" -[dependencies.e310x] -features = ["rt"] -version = "^0.1.1" - [dependencies.riscv] -version = "^0.1.3" +git = "https://github.com/dvc94ch/riscv" -[dev-dependencies.riscv-rt] -version = "^0.1.3" +[dependencies.riscv-rt] +git = "https://github.com/dvc94ch/riscv-rt" + +[dependencies.e310x] +features = ["rt"] +git = "https://github.com/dvc94ch/e310x" [profile.release] debug = true From f20ece3907f50f817dbccf0c155be108b94ee747 Mon Sep 17 00:00:00 2001 From: David Craven Date: Tue, 21 Nov 2017 10:25:58 +0100 Subject: [PATCH 005/112] Enable interrupts. --- examples/blinky_clint.rs | 6 +++++- examples/blinky_plic.rs | 7 ++++++- src/lib.rs | 14 ++++++++------ 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/examples/blinky_clint.rs b/examples/blinky_clint.rs index f96cfdc..3798ccf 100644 --- a/examples/blinky_clint.rs +++ b/examples/blinky_clint.rs @@ -3,7 +3,7 @@ extern crate hifive; use hifive::prelude::*; -use hifive::{led, Blue, Clint, Peripherals, UExt}; +use hifive::{interrupt, led, Blue, Clint, Peripherals, UExt}; fn main() { let peripherals = hifive::init(115_200); @@ -11,6 +11,10 @@ fn main() { let timer = Clint(peripherals.CLINT); timer.set_timeout(1.s()); + + unsafe { + interrupt::enable(); + } } #[no_mangle] diff --git a/examples/blinky_plic.rs b/examples/blinky_plic.rs index 86c92e5..e2b90e7 100644 --- a/examples/blinky_plic.rs +++ b/examples/blinky_plic.rs @@ -2,7 +2,8 @@ extern crate hifive; -use hifive::{led, Red, Blue, Green, Interrupt, Plic, Channel, Pwm, Peripherals}; +use hifive::{interrupt, led, Red, Blue, Green, Interrupt, Plic, + Channel, Pwm, Peripherals}; fn main() { let peripherals = hifive::init(115_200); @@ -19,6 +20,10 @@ fn main() { plic.enable(Interrupt::PWM0CMP1); plic.enable(Interrupt::PWM0CMP2); plic.enable(Interrupt::PWM0CMP3); + + unsafe { + interrupt::enable(); + } } #[no_mangle] diff --git a/src/lib.rs b/src/lib.rs index ca57aac..86078b2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -26,6 +26,7 @@ use core::fmt::Write; use riscv::interrupt::Nr; pub use hal::prelude; +pub use riscv::{csr, interrupt}; pub use e310x::Peripherals; pub use clint::Clint; pub use led::{Red, Green, Blue}; @@ -64,7 +65,7 @@ pub fn init<'a>(baud_rate: u32) -> e310x::Peripherals<'a> { /// necessary. #[used] #[no_mangle] -fn trap_handler(trap: riscv::csr::Trap) { +pub fn trap_handler(trap: riscv::csr::Trap) { use riscv::csr::{Trap, Interrupt}; let peripherals = unsafe { e310x::Peripherals::all() }; @@ -81,18 +82,19 @@ fn trap_handler(trap: riscv::csr::Trap) { let plic = Plic(peripherals.PLIC); let intr = plic.claim(); - writeln!(Port(&serial), "{:?} {}", intr, intr.nr()).unwrap(); + writeln!(Port(&serial), "{}", intr.nr()).unwrap(); plic_trap_handler(&peripherals, &intr); plic.complete(intr); } x => { - writeln!(Port(&serial), "Interrupt {:?}", x).unwrap(); + writeln!(Port(&serial), "Interrupt {}", x as u32).unwrap(); }, } }, Trap::Exception(x) => { - writeln!(Port(&serial), "Exception {:?}", x).unwrap(); + let mepc = csr::mepc.read().bits(); + writeln!(Port(&serial), "Exception {} at 0x{:x}", x as u32, mepc).unwrap(); }, } } @@ -100,12 +102,12 @@ fn trap_handler(trap: riscv::csr::Trap) { /// Default MachineTimer Trap Handler #[no_mangle] #[linkage = "weak"] -fn mtimer_trap_handler(_: &e310x::Peripherals) {} +pub fn mtimer_trap_handler(_: &e310x::Peripherals) {} /// Default MachineExternal Trap Handler #[no_mangle] #[linkage = "weak"] -fn plic_trap_handler(_: &e310x::Peripherals, _: &Interrupt) {} +pub fn plic_trap_handler(_: &e310x::Peripherals, _: &Interrupt) {} macro_rules! ticks_impl { From 39e9e520b16f8238e562a150863e975e7ec13fd5 Mon Sep 17 00:00:00 2001 From: David Craven Date: Tue, 21 Nov 2017 13:44:31 +0100 Subject: [PATCH 006/112] Clean up PLIC code. --- src/lib.rs | 6 +----- src/plic.rs | 16 ++++++++++------ 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 86078b2..13c3c23 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -47,10 +47,6 @@ pub fn init<'a>(baud_rate: u32) -> e310x::Peripherals<'a> { let clock = clock::CoreClock(peripherals.PRCI); unsafe { clock.use_external(&clint); } - // Setup PLIC - let plic = Plic(peripherals.PLIC); - plic.init(); - // Initialize UART0 let serial = Serial(peripherals.UART0); serial.init(baud_rate.hz().invert(), peripherals.GPIO0); @@ -82,7 +78,7 @@ pub fn trap_handler(trap: riscv::csr::Trap) { let plic = Plic(peripherals.PLIC); let intr = plic.claim(); - writeln!(Port(&serial), "{}", intr.nr()).unwrap(); + writeln!(Port(&serial), "ExternalInterrupt {}", intr.nr()).unwrap(); plic_trap_handler(&peripherals, &intr); plic.complete(intr); diff --git a/src/plic.rs b/src/plic.rs index 8130cc6..518b031 100644 --- a/src/plic.rs +++ b/src/plic.rs @@ -1,3 +1,4 @@ +use riscv::csr; use riscv::interrupt::Nr; use e310x::PLIC; pub use e310x::Interrupt; @@ -49,20 +50,23 @@ impl<'a> Copy for Plic<'a> { } impl<'a> Plic<'a> { - pub fn init(&self) { + /*pub fn init(&self) { for reg in self.0.enable.iter() { unsafe { reg.write(|w| w.bits(0)); } } + //interrupt!(MachineExternal, plic::plic_handler()); + }*/ + + pub fn enable_mexternal(&self) { + csr::mie.set(|w| w.mext()); } - /*pub fn handler(&self, f: F) where F: Fn { - let intr = plic.claim(); - f(intr); - plic.complete(intr); - }*/ + pub fn clear_mexternal(&self) { + csr::mie.clear(|w| w.mext()); + } pub fn is_pending(&self, intr: Interrupt) -> bool { let mask = 1 << (intr.nr() % 32); From d2eeacdce0aba84373134d30d26d732e26731468 Mon Sep 17 00:00:00 2001 From: David Craven Date: Wed, 22 Nov 2017 10:20:02 +0100 Subject: [PATCH 007/112] Refactor clock.rs `use_external` and `use_pll` now use `init_pll`. `use_pll` configures the pll to 256MHz, the maximum possible with an external 16MHz clock. Added `pll_mult` to compute the configured clock multiplier and an example. --- Makefile | 6 ++++-- examples/pll.rs | 27 ++++++++++++++++++++++++ src/clock.rs | 55 ++++++++++++++++++++++++++++++++++++++++++++----- 3 files changed, 81 insertions(+), 7 deletions(-) create mode 100644 examples/pll.rs diff --git a/Makefile b/Makefile index 7cde44e..027d085 100644 --- a/Makefile +++ b/Makefile @@ -1,17 +1,19 @@ # Examples (uncomment one) -EXAMPLE := blinky_delay +#EXAMPLE := blinky_delay #EXAMPLE := blinky_clint #EXAMPLE := blinky_pwm #EXAMPLE := blinky_plic #EXAMPLE := hello_world #EXAMPLE := panicking +#EXAMPLE := pll # Board crate (uncomment one) BOARD := hifive TARGET := riscv32-unknown-none TARGET_DIR := $(abspath ./target/$(TARGET)/debug) -EXAMPLE_BIN := $(TARGET_DIR)/examples/$(EXAMPLE) +EXAMPLE_DIR := $(TARGET_DIR)/examples +EXAMPLE_BIN := $(EXAMPLE_DIR)/$(EXAMPLE) OPENOCD_CFG := $(wildcard $(TARGET_DIR)/build/$(BOARD)-*/out/openocd.cfg) build: diff --git a/examples/pll.rs b/examples/pll.rs new file mode 100644 index 0000000..054efa1 --- /dev/null +++ b/examples/pll.rs @@ -0,0 +1,27 @@ +#![no_std] + +extern crate hifive; + +use core::fmt::Write; +use hifive::{clock, Clint, Port, Serial}; + +fn main() { + let p = hifive::init(115_200); + + let serial = Serial(p.UART0); + let mut stdout = Port(&serial); + writeln!(stdout, "Setting up PLL").unwrap(); + + let clint = Clint(p.CLINT); + let clock = clock::CoreClock(p.PRCI); + + let freq_calc_default = clock.pll_mult() * 16; + unsafe { clock.use_pll(&clint); } + let freq_calc = clock.pll_mult() * 16; + let freq_measured = clock.measure(&clint) / 1_000_000; + unsafe { clock.use_external(&clint); } + + writeln!(stdout, "Default PLL settings {}MHz", freq_calc_default).unwrap(); + writeln!(stdout, "Measured clock frequency of {}MHz", freq_measured).unwrap(); + writeln!(stdout, "Computed clock frequency of {}MHz", freq_calc).unwrap(); +} diff --git a/src/clock.rs b/src/clock.rs index 46e36b6..50ec9d2 100644 --- a/src/clock.rs +++ b/src/clock.rs @@ -14,7 +14,7 @@ impl<'a> Clone for AonClock<'a> { impl<'a> Copy for AonClock<'a> {} impl<'a> AonClock<'a> { - /// Use external real time oscillator + /// Use external real time oscillator. pub unsafe fn use_external(&self) { // The G000 doesn't have a LFXOSC and is hardwired // to use the an external oscillator. @@ -36,15 +36,60 @@ impl<'a> Copy for CoreClock<'a> { } impl<'a> CoreClock<'a> { + /// Use external oscillator with bypassed pll. pub unsafe fn use_external(&self, clint: &Clint) { - self.use_pll(clint, |_, w| { + self.init_pll(clint, |_, w| { // bypass PLL w.bypass().bit(true) // select HFXOSC .refsel().bit(true) }, |w| w.divby1().bit(true)); + // Disable HFROSC to save power + self.0.hfrosccfg.write(|w| w.enable().bit(false)); + } + + /// Use external oscillator with pll. Sets PLL + /// r=2, f=64, q=2 values to maximum allowable + /// for a 16MHz reference clock. Output frequency + /// is 16MHz / 2 * 64 / 2 = 256MHz. + /// NOTE: By trimming the internal clock to 12MHz + /// and using r=1, f=64, q=2 the maximum frequency + /// of 384MHz can be reached. + pub unsafe fn use_pll(&self, clint: &Clint) { + self.init_pll(clint, |_, w| { + // bypass PLL + w.bypass().bit(false) + // select HFXOSC + .refsel().bit(true) + // bits = r - 1 + .pllr().bits(1) + // bits = f / 2 - 1 + .pllf().bits(31) + // bits = q=2 -> 1, q=4 -> 2, q=8 -> 3 + .pllq().bits(1) + }, |w| w.divby1().bit(true)); + // Disable HFROSC to save power + self.0.hfrosccfg.write(|w| w.enable().bit(false)); + } + + /// Compute PLL multiplier. + pub fn pll_mult(&self) -> u32 { + let pllcfg = self.0.pllcfg.read(); + let plloutdiv = self.0.plloutdiv.read(); + + let r = pllcfg.pllr().bits() as u32 + 1; + let f = (pllcfg.pllf().bits() as u32 + 1) * 2; + let q = [2, 4, 8][pllcfg.pllq().bits() as usize - 1]; + + let div = match plloutdiv.divby1().bit() { + true => 1, + false => (plloutdiv.div().bits() as u32 + 1) * 2, + }; + + f / r / q / div } + /// Wait for the pll to lock. unsafe fn wait_for_lock(&self, clint: &Clint) { // Won't lock when bypassed and will loop forever if !self.0.pllcfg.read().bypass().bit_is_set() { @@ -60,7 +105,7 @@ impl<'a> CoreClock<'a> { } } - pub unsafe fn use_pll(&self, clint: &Clint, pllcfg: F, plloutdiv: G) + unsafe fn init_pll(&self, clint: &Clint, pllcfg: F, plloutdiv: G) where for<'w> F: FnOnce(&prci::pllcfg::R, &'w mut prci::pllcfg::W) -> &'w mut prci::pllcfg::W, @@ -82,10 +127,9 @@ impl<'a> CoreClock<'a> { self.0.pllcfg.modify(|_, w| { w.sel().bit(true) }); - // Disable HFROSC to save power - self.0.hfrosccfg.write(|w| w.enable().bit(false)); } + /// Use internal oscillator with bypassed pll. pub unsafe fn use_internal(&self) { // Enable HFROSC self.0.hfrosccfg.write(|w| { @@ -111,6 +155,7 @@ impl<'a> CoreClock<'a> { self.0.hfxosccfg.write(|w| w.enable().bit(false)); } + /// Measure the frequency of coreclk. pub fn measure(&self, clint: &Clint) -> u32 { // warm up I$ clint.measure_coreclk(::aonclk::Ticks(1)); From 9263484b2d80fb4ced3e2cd9b3331c12a7050330 Mon Sep 17 00:00:00 2001 From: David Craven Date: Wed, 22 Nov 2017 11:22:22 +0100 Subject: [PATCH 008/112] Document Plic driver. --- examples/blinky_plic.rs | 49 +++++++++---------- src/plic.rs | 104 ++++++++++++++++++++++++++++++---------- 2 files changed, 103 insertions(+), 50 deletions(-) diff --git a/examples/blinky_plic.rs b/examples/blinky_plic.rs index e2b90e7..fb75591 100644 --- a/examples/blinky_plic.rs +++ b/examples/blinky_plic.rs @@ -2,46 +2,43 @@ extern crate hifive; -use hifive::{interrupt, led, Red, Blue, Green, Interrupt, Plic, - Channel, Pwm, Peripherals}; +use core::fmt::Write; +use hifive::*; +use hifive::prelude::*; +use hifive::interrupt::Nr; fn main() { - let peripherals = hifive::init(115_200); - led::init(peripherals.GPIO0); + let p = hifive::init(115_200); + led::init(p.GPIO0); - let pwm = Pwm(peripherals.PWM0); - pwm.init(); - pwm.set_cmp(Channel::_0, u16::max_value()); - pwm.set_cmp(Channel::_1, 0); - pwm.set_cmp(Channel::_2, u16::max_value() / 2); + Red::on(p.GPIO0); - let plic = Plic(peripherals.PLIC); - plic.enable(Interrupt::PWM0CMP0); - plic.enable(Interrupt::PWM0CMP1); - plic.enable(Interrupt::PWM0CMP2); - plic.enable(Interrupt::PWM0CMP3); + let plic = Plic(p.PLIC); + plic.init(); + + RtcConf::new().end(p.RTC); + Rtc(p.RTC).set_timeout(500.ms()); + + plic.set_priority(Interrupt::RTC, Priority::P7); + plic.enable(Interrupt::RTC); + + let serial = Serial(p.UART0); + let mut stdout = Port(&serial); + writeln!(stdout, "RTC interrupt is set {}", plic.is_enabled(Interrupt::RTC)).unwrap(); + writeln!(stdout, "RTC interrupt nr is {}", Interrupt::RTC.nr()).unwrap(); unsafe { interrupt::enable(); } + + loop {} } #[no_mangle] pub fn plic_trap_handler(p: &Peripherals, intr: &Interrupt) { - //let pwm = Pwm(p.PWM0); - match *intr { - Interrupt::PWM0CMP0 => { + Interrupt::RTC => { Blue::toggle(p.GPIO0); - }, - Interrupt::PWM0CMP1 => { - Green::toggle(p.GPIO0); - }, - Interrupt::PWM0CMP2 => { - Red::toggle(p.GPIO0); - }, - Interrupt::PWM0CMP3 => { - }, _ => {}, } diff --git a/src/plic.rs b/src/plic.rs index 518b031..b2a4f31 100644 --- a/src/plic.rs +++ b/src/plic.rs @@ -3,14 +3,18 @@ use riscv::interrupt::Nr; use e310x::PLIC; pub use e310x::Interrupt; +/// Priority of a plic::Interrupt. +#[derive(Clone, Copy)] pub enum Priority { - Never, P1, P2, P3, P4, P5, P6, P7, + P0, P1, P2, P3, P4, P5, P6, P7, } impl Priority { - pub fn from(prio: u32) -> Priority { + /// Takes a read interrupt priority or plic threshold + /// register value and returns a plic::Priority enum. + fn from(prio: u32) -> Priority { match prio { - 0 => Priority::Never, + 0 => Priority::P0, 1 => Priority::P1, 2 => Priority::P2, 3 => Priority::P3, @@ -24,9 +28,11 @@ impl Priority { } impl Into for Priority { + /// Returns the numeric priority for wirting to a + /// interrupt priority or the plic threshold register. fn into(self) -> u32 { match self { - Priority::Never => 0, + Priority::P0 => 0, Priority::P1 => 1, Priority::P2 => 2, Priority::P3 => 3, @@ -38,6 +44,7 @@ impl Into for Priority { } } +/// Plic interface pub struct Plic<'a>(pub &'a PLIC); impl<'a> Clone for Plic<'a> { @@ -49,78 +56,127 @@ impl<'a> Clone for Plic<'a> { impl<'a> Copy for Plic<'a> { } +/// Represents a register offset and mask for +/// accessing an individual bit in a register +/// file. +struct Loc { + offset: usize, + mask: u32, +} + +impl Loc { + /// Computes the location of an interrupt. + //#[inline] + pub fn from(intr: Interrupt) -> Self { + // offset = nr / 32 + // bit = nr % 32 + // 32 = 2 ^ 5 + let nr = intr.nr(); + let bit = nr & 31; + Self { + offset: (nr >> 5) as usize, + mask: 1 << bit + } + } + + /// Checks if bit is set. + //#[inline] + pub fn is_set(&self, bits: u32) -> bool { + bits & self.mask == self.mask + } +} + impl<'a> Plic<'a> { - /*pub fn init(&self) { + /// Initializes PLIC controller by resetting all + /// enable bits to 0 and enables MachineExternal + /// interrupts. + pub fn init(&self) { for reg in self.0.enable.iter() { unsafe { reg.write(|w| w.bits(0)); } } + self.set_threshold(Priority::P0); + self.enable_mext(); + } - //interrupt!(MachineExternal, plic::plic_handler()); - }*/ - - pub fn enable_mexternal(&self) { + /// Enable MachineExternal interrupts. + #[inline] + pub fn enable_mext(&self) { csr::mie.set(|w| w.mext()); } - pub fn clear_mexternal(&self) { + /// Disable MachineExternal interrupts. + #[inline] + pub fn disable_mext(&self) { csr::mie.clear(|w| w.mext()); } + /// Returns true when plic::Interrupt is pending. pub fn is_pending(&self, intr: Interrupt) -> bool { - let mask = 1 << (intr.nr() % 32); - let pending = self.0.pending[(intr.nr() / 32) as usize].read(); - pending.bits() & mask == mask + let loc = Loc::from(intr); + let pending = self.0.pending[loc.offset].read(); + loc.is_set(pending.bits()) } + /// Returns true when plic::Interrupt is enabled. pub fn is_enabled(&self, intr: Interrupt) -> bool { - let mask = 1 << (intr.nr() % 32); - let enable = self.0.enable[(intr.nr() / 32) as usize].read(); - enable.bits() & mask == mask + let loc = Loc::from(intr); + let enable = self.0.enable[loc.offset].read(); + loc.is_set(enable.bits()) } + /// Enables plic::Interrupt. pub fn enable(&self, intr: Interrupt) { - let mask = 1 << (intr.nr() % 32); + let loc = Loc::from(intr); unsafe { - self.0.enable[(intr.nr() / 32) as usize] - .modify(|r, w| w.bits(r.bits() | mask)); + self.0.enable[loc.offset] + .modify(|r, w| w.bits(r.bits() | loc.mask)); } } + /// Disables plic::Interrupt. pub fn disable(&self, intr: Interrupt) { - let mask = 1 << (intr.nr() % 32); + let loc = Loc::from(intr); unsafe { - self.0.enable[(intr.nr() / 32) as usize] - .modify(|r, w| w.bits(r.bits() & !mask)); + self.0.enable[loc.offset] + .modify(|r, w| w.bits(r.bits() & !loc.mask)); } } + /// Claims the plic::Interrupt with the highest priority. pub fn claim(&self) -> Interrupt { Interrupt::from(self.0.claim.read().bits() as u8) } + /// Notifies the PLIC that the claimed plic::Interrupt is + /// complete. pub fn complete(&self, intr: Interrupt) { unsafe { self.0.claim.write(|w| w.bits(intr.nr() as u32)); } } + /// Returns the plic::Priority of a plic::Interrupt. pub fn get_priority(&self, intr: Interrupt) -> Priority { - Priority::from(self.0.priority[(intr.nr() - 1) as usize].read().bits()) + Priority::from(self.0.priority[intr.nr() as usize].read().bits()) } + /// Sets the plic::Priority of a plic::Interrupt. pub fn set_priority(&self, intr: Interrupt, prio: Priority) { unsafe { - self.0.priority[(intr.nr() - 1) as usize] + self.0.priority[intr.nr() as usize] .write(|w| w.bits(prio.into())); } } + /// Returns the PLIC threshold priority. pub fn get_threshold(&self) -> Priority { Priority::from(self.0.threshold.read().bits()) } + /// Sets the PLIC threshold priority. This disables all + /// interrupts with a lower plic::Priority. pub fn set_threshold(&self, prio: Priority) { unsafe { self.0.threshold.write(|w| w.bits(prio.into())); From 77c731228765f3e9441861bdbba97bbb50e8eb04 Mon Sep 17 00:00:00 2001 From: David Craven Date: Wed, 22 Nov 2017 18:16:23 +0100 Subject: [PATCH 009/112] Add rtc driver. --- examples/blinky_plic.rs | 12 +++- src/lib.rs | 2 + src/rtc.rs | 126 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 138 insertions(+), 2 deletions(-) create mode 100644 src/rtc.rs diff --git a/examples/blinky_plic.rs b/examples/blinky_plic.rs index fb75591..ed11cb2 100644 --- a/examples/blinky_plic.rs +++ b/examples/blinky_plic.rs @@ -24,8 +24,16 @@ fn main() { let serial = Serial(p.UART0); let mut stdout = Port(&serial); - writeln!(stdout, "RTC interrupt is set {}", plic.is_enabled(Interrupt::RTC)).unwrap(); - writeln!(stdout, "RTC interrupt nr is {}", Interrupt::RTC.nr()).unwrap(); + writeln!(stdout, "External interrupts enabled: {}", + csr::mstatus.read().meie()).unwrap(); + writeln!(stdout, "PLIC threshold priority: {}", + plic.get_threshold()).unwrap(); + writeln!(stdout, "RTC interrupt number: {}", + Interrupt::RTC.nr()).unwrap(); + writeln!(stdout, "RTC interrupt enabled: {}", + plic.is_enabled(Interrupt::RTC)).unwrap(); + writeln!(stdout, "RTC interrupt priority: {}", + plic.get_priority(Interrupt::RTC)).unwrap(); unsafe { interrupt::enable(); diff --git a/src/lib.rs b/src/lib.rs index 13c3c23..228a96b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -19,6 +19,7 @@ pub mod gpio; pub mod led; pub mod plic; pub mod pwm; +pub mod rtc; pub mod serial; pub mod time; @@ -32,6 +33,7 @@ pub use clint::Clint; pub use led::{Red, Green, Blue}; pub use plic::{Priority, Interrupt, Plic}; pub use pwm::{Align, Channel, Pwm}; +pub use rtc::{Rtc, RtcConf}; pub use serial::{Serial, Port}; pub use time::UExt; diff --git a/src/rtc.rs b/src/rtc.rs new file mode 100644 index 0000000..88dfa14 --- /dev/null +++ b/src/rtc.rs @@ -0,0 +1,126 @@ +//! RTC +use e310x::{PLIC, RTC}; +use plic::{Plic, Interrupt, Priority}; + +/// Rtc configuration +pub struct RtcConf { + enalways: bool, + scale: u8, + counter: u64, + cmp: u32, + priority: Priority, +} + +impl RtcConf { + pub fn new() -> Self { + Self { + enalways: true, + scale: 0, + counter: 0, + cmp: 0, + priority: Priority::P1, + } + } + + pub fn set_enalways(&mut self, en: bool) -> &mut Self { + self.enalways = en; + self + } + + pub fn set_scale(&mut self, scale: u8) -> &mut Self { + assert!(scale < 16); + self.scale = scale; + self + } + + pub fn set_counter(&mut self, counter: u64) -> &mut Self { + assert!(counter < (1 << 49) - 1); + self.counter = counter; + self + } + pub fn set_cmp(&mut self, cmp: u32) -> &mut Self { + self.cmp = cmp; + self + } + + pub fn set_priority(&mut self, prio: Priority) -> &mut Self { + self.priority = prio; + self + } + + pub fn end(&self, rtc: &RTC) { + //let plic = Plic(plic); + let rtc = Rtc(rtc); + + //plic.disable(Interrupt::RTC); + + unsafe { + rtc.0.rtccfg.modify(|_, w| { + w.enalways().bit(self.enalways) + .scale().bits(self.scale) + }); + + rtc.0.rtchi.write(|w| w.bits((self.counter >> 32) as u32)); + rtc.0.rtclo.write(|w| w.bits(self.counter as u32)); + rtc.0.rtccmp.write(|w| w.bits(self.cmp)); + } + + //plic.set_priority(Interrupt::RTC, self.priority); + //plic.enable(Interrupt::RTC); + } +} + + +/// Rtc interface +pub struct Rtc<'a>(pub &'a RTC); + +impl<'a> Clone for Rtc<'a> { + fn clone(&self) -> Self { + *self + } +} + +impl<'a> Copy for Rtc<'a> {} + +impl<'a> ::hal::Timer for Rtc<'a> { + type Time = ::aonclk::Ticks; + + fn get_timeout(&self) -> ::aonclk::Ticks { + ::aonclk::Ticks(self.0.rtccmp.read().bits()) + } + + fn pause(&self) { + self.0.rtccfg.modify(|_, w| w.enalways().bit(false)); + } + + fn restart(&self) { + unsafe { + self.0.rtchi.write(|w| w.bits(0)); + self.0.rtclo.write(|w| w.bits(0)); + } + self.0.rtccfg.modify(|_, w| w.enalways().bit(true)); + } + + fn resume(&self) { + self.0.rtccfg.modify(|_, w| w.enalways().bit(true)); + } + + fn set_timeout(&self, timeout: T) + where + T: Into<::aonclk::Ticks>, + { + self.pause(); + unsafe { + self.0.rtccmp.write(|w| w.bits(1)); + } + self.restart(); + } + + fn wait(&self) -> ::nb::Result<(), !> { + if self.0.rtccfg.read().cmpip().bit() { + Ok(()) + } else { + Err(::nb::Error::WouldBlock) + } + } +} From 00e8b7da020367739888ca046921b64496e9e117 Mon Sep 17 00:00:00 2001 From: David Craven Date: Wed, 22 Nov 2017 18:17:00 +0100 Subject: [PATCH 010/112] Add link to documentation. --- README.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 46f873d..6d5dfb2 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,13 @@ +[![crates.io](https://img.shields.io/crates/d/hifive.svg)](https://crates.io/crates/hifive) +[![crates.io](https://img.shields.io/crates/v/hifive.svg)](https://crates.io/crates/hifive) + # `hifive` > Board support crate for hifive and lofive boards. -# License +## [Documentation](https://docs.rs/crate/hifive) + +## License Copyright 2017 David Craven Permission to use, copy, modify, and/or distribute this software for any purpose From 39c6cccf78807f805649a9a4d5aead47955967aa Mon Sep 17 00:00:00 2001 From: David Craven Date: Wed, 22 Nov 2017 18:17:44 +0100 Subject: [PATCH 011/112] Extend panicking example. --- examples/panicking.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/panicking.rs b/examples/panicking.rs index 480534f..3043756 100644 --- a/examples/panicking.rs +++ b/examples/panicking.rs @@ -2,12 +2,12 @@ extern crate hifive; -fn three() { +fn three(_1: u32, _2: u32) { panic!() } fn two() { - three(); + three(0x0123_4567, 0x1234_5678); } fn one() { From d03041d2fd3d9e76265a9e927c9907cc75f1b7de Mon Sep 17 00:00:00 2001 From: David Craven Date: Thu, 23 Nov 2017 14:38:17 +0100 Subject: [PATCH 012/112] Add docstrings. --- src/clint.rs | 15 ++++++++++++--- src/gpio.rs | 2 ++ 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/clint.rs b/src/clint.rs index e0d905d..c2b86e0 100644 --- a/src/clint.rs +++ b/src/clint.rs @@ -15,6 +15,7 @@ impl<'a> Copy for Clint<'a> { } impl<'a> Clint<'a> { + /// Read mtime register. pub fn get_mtime(&self) -> ::aonclk::Ticks { loop { let hi = self.0.mtimeh.read().bits(); @@ -25,6 +26,7 @@ impl<'a> Clint<'a> { } } + /// Write mtime register. pub fn set_mtime(&self, time: ::aonclk::Ticks) { unsafe { self.0.mtimeh.write(|w| w.bits(time.into_hi())); @@ -32,12 +34,14 @@ impl<'a> Clint<'a> { } } + /// Read mtimecmp register. pub fn get_mtimecmp(&self) -> ::aonclk::Ticks { let hi = self.0.mtimecmph.read().bits() as u64; let lo = self.0.mtimecmp.read().bits() as u64; ::aonclk::Ticks(hi << 32 | lo) } + /// Write mtimecmp register. pub fn set_mtimecmp(&self, time: ::aonclk::Ticks) { unsafe { self.0.mtimecmph.write(|w| w.bits(time.into_hi())); @@ -45,6 +49,7 @@ impl<'a> Clint<'a> { } } + /// Read mcycle register. pub fn get_mcycle(&self) -> ::coreclk::Ticks { loop { let hi = csr::mcycleh.read().bits(); @@ -55,11 +60,13 @@ impl<'a> Clint<'a> { } } + /// Write mcycle register. pub fn set_mcycle(&self, cycle: ::coreclk::Ticks) { csr::mcycleh.write(|w| w.bits(cycle.into_hi())); csr::mcycle.write(|w| w.bits(cycle.into())); } + /// Read minstret register. pub fn get_minstret(&self) -> u64 { loop { let hi = csr::minstreth.read().bits(); @@ -70,27 +77,29 @@ impl<'a> Clint<'a> { } } + /// Write minstret register. pub fn set_minstret(&self, instret: u64) { csr::minstreth.write(|w| w.bits((instret >> 32) as u32)); csr::minstret.write(|w| w.bits(instret as u32)); } - /// Enable the Machine-Timer interrupt + /// Enable Machine-Timer interrupt. pub fn enable_mtimer(&self) { csr::mie.set(|w| w.mtimer()); } - /// Disable the Machine-Timer interrupt + /// Disable Machine-Timer interrupt. pub fn disable_mtimer(&self) { csr::mie.clear(|w| w.mtimer()); } - // Is Machine-Timer interrupt pending + /// Check if the Machine-Timer is interrupt pending. pub fn is_mtimer_pending(&self) -> bool { csr::mip.read().mtimer() } + /// Measure the coreclk frequency by counting the number of aonclk ticks. pub fn measure_coreclk(&self, min_ticks: ::aonclk::Ticks) -> u32 { interrupt::free(|_| { let clint = self.0; diff --git a/src/gpio.rs b/src/gpio.rs index f5eb655..ba89a04 100644 --- a/src/gpio.rs +++ b/src/gpio.rs @@ -3,6 +3,7 @@ use core::ops::Deref; use e310x::gpio0; +/// Enumeration of possible pin configurations. pub enum PinConfig { Input, InputPullup, @@ -12,6 +13,7 @@ pub enum PinConfig { IoFn1, } +/// Enumeration of pin interrupts. pub enum PinInterrupt { Rise, Fall, From acdbedb0bb462c80d527dd68fe052c068f296304 Mon Sep 17 00:00:00 2001 From: David Craven Date: Sat, 25 Nov 2017 10:28:23 +0100 Subject: [PATCH 013/112] Update example. --- examples/blinky_plic.rs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/examples/blinky_plic.rs b/examples/blinky_plic.rs index ed11cb2..a23c131 100644 --- a/examples/blinky_plic.rs +++ b/examples/blinky_plic.rs @@ -25,27 +25,28 @@ fn main() { let serial = Serial(p.UART0); let mut stdout = Port(&serial); writeln!(stdout, "External interrupts enabled: {}", - csr::mstatus.read().meie()).unwrap(); + csr::mie.read().mext()).unwrap(); + let threshold: u32 = plic.get_threshold().into(); writeln!(stdout, "PLIC threshold priority: {}", - plic.get_threshold()).unwrap(); + threshold).unwrap(); writeln!(stdout, "RTC interrupt number: {}", Interrupt::RTC.nr()).unwrap(); writeln!(stdout, "RTC interrupt enabled: {}", plic.is_enabled(Interrupt::RTC)).unwrap(); + let priority: u32 = plic.get_priority(Interrupt::RTC).into(); writeln!(stdout, "RTC interrupt priority: {}", - plic.get_priority(Interrupt::RTC)).unwrap(); + priority).unwrap(); unsafe { interrupt::enable(); } - - loop {} } #[no_mangle] pub fn plic_trap_handler(p: &Peripherals, intr: &Interrupt) { match *intr { Interrupt::RTC => { + Rtc(p.RTC).restart(); Blue::toggle(p.GPIO0); }, _ => {}, From 1756937351f3338d8d40edfa0379d9ad24efb283 Mon Sep 17 00:00:00 2001 From: David Craven Date: Sat, 25 Nov 2017 10:29:01 +0100 Subject: [PATCH 014/112] Fix priority register offset. --- src/plic.rs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/plic.rs b/src/plic.rs index b2a4f31..97226d0 100644 --- a/src/plic.rs +++ b/src/plic.rs @@ -28,7 +28,7 @@ impl Priority { } impl Into for Priority { - /// Returns the numeric priority for wirting to a + /// Returns the numeric priority for writing to a /// interrupt priority or the plic threshold register. fn into(self) -> u32 { match self { @@ -93,7 +93,8 @@ impl<'a> Plic<'a> { pub fn init(&self) { for reg in self.0.enable.iter() { unsafe { - reg.write(|w| w.bits(0)); + // bug somewhere enabling interrupts + reg.write(|w| w.bits(0xFFFF_FFFF)); } } self.set_threshold(Priority::P0); @@ -159,13 +160,15 @@ impl<'a> Plic<'a> { /// Returns the plic::Priority of a plic::Interrupt. pub fn get_priority(&self, intr: Interrupt) -> Priority { - Priority::from(self.0.priority[intr.nr() as usize].read().bits()) + // Priority array is offset by one. + Priority::from(self.0.priority[intr.nr() as usize - 1].read().bits()) } /// Sets the plic::Priority of a plic::Interrupt. pub fn set_priority(&self, intr: Interrupt, prio: Priority) { + // Priority array is offset by one. unsafe { - self.0.priority[intr.nr() as usize] + self.0.priority[intr.nr() as usize - 1] .write(|w| w.bits(prio.into())); } } From df5b87be333ea612fe72edfed2d783018f12ecf4 Mon Sep 17 00:00:00 2001 From: David Craven Date: Sat, 25 Nov 2017 10:29:18 +0100 Subject: [PATCH 015/112] Cleanup rtc driver. --- src/rtc.rs | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/src/rtc.rs b/src/rtc.rs index 88dfa14..cc8b41d 100644 --- a/src/rtc.rs +++ b/src/rtc.rs @@ -1,6 +1,5 @@ //! RTC -use e310x::{PLIC, RTC}; -use plic::{Plic, Interrupt, Priority}; +use e310x::RTC; /// Rtc configuration pub struct RtcConf { @@ -8,7 +7,6 @@ pub struct RtcConf { scale: u8, counter: u64, cmp: u32, - priority: Priority, } impl RtcConf { @@ -18,7 +16,6 @@ impl RtcConf { scale: 0, counter: 0, cmp: 0, - priority: Priority::P1, } } @@ -43,17 +40,8 @@ impl RtcConf { self } - pub fn set_priority(&mut self, prio: Priority) -> &mut Self { - self.priority = prio; - self - } - pub fn end(&self, rtc: &RTC) { - //let plic = Plic(plic); let rtc = Rtc(rtc); - - //plic.disable(Interrupt::RTC); - unsafe { rtc.0.rtccfg.modify(|_, w| { w.enalways().bit(self.enalways) @@ -64,9 +52,6 @@ impl RtcConf { rtc.0.rtclo.write(|w| w.bits(self.counter as u32)); rtc.0.rtccmp.write(|w| w.bits(self.cmp)); } - - //plic.set_priority(Interrupt::RTC, self.priority); - //plic.enable(Interrupt::RTC); } } @@ -111,7 +96,7 @@ impl<'a> ::hal::Timer for Rtc<'a> { { self.pause(); unsafe { - self.0.rtccmp.write(|w| w.bits(1)); + self.0.rtccmp.write(|w| w.bits(timeout.into().into())); } self.restart(); } From 90d1bc4edc6502e668dba4c7c26ea68d9e7a6407 Mon Sep 17 00:00:00 2001 From: David Craven Date: Sat, 25 Nov 2017 12:48:32 +0100 Subject: [PATCH 016/112] Export PinConfig and PinInterrupt. --- src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lib.rs b/src/lib.rs index 228a96b..ce04098 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -29,6 +29,7 @@ use riscv::interrupt::Nr; pub use hal::prelude; pub use riscv::{csr, interrupt}; pub use e310x::Peripherals; +pub use gpio::{PinConfig, PinInterrupt}; pub use clint::Clint; pub use led::{Red, Green, Blue}; pub use plic::{Priority, Interrupt, Plic}; From 43b09945dbffa80e0d3d3c03ea3126aac23cb817 Mon Sep 17 00:00:00 2001 From: David Craven Date: Sat, 2 Dec 2017 13:36:32 +0100 Subject: [PATCH 017/112] Implement clear_pending. --- src/gpio.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/gpio.rs b/src/gpio.rs index ba89a04..dd9ff2e 100644 --- a/src/gpio.rs +++ b/src/gpio.rs @@ -132,6 +132,22 @@ macro_rules! pin { }; } + pub fn clear_pending(gpio: &T, intr: PinInterrupt) + where + T: Deref, + { + match intr { + PinInterrupt::Rise => + gpio.rise_ip.write(|w| w.$pinx().bit(true)), + PinInterrupt::Fall => + gpio.fall_ip.write(|w| w.$pinx().bit(true)), + PinInterrupt::High => + gpio.high_ip.write(|w| w.$pinx().bit(true)), + PinInterrupt::Low => + gpio.low_ip.write(|w| w.$pinx().bit(true)), + } + } + pub fn is_interrupt_pending(gpio: &T, intr: PinInterrupt) -> bool where T: Deref, From e5a1bfc4faa17bbd631c4199b792be98c29b97ea Mon Sep 17 00:00:00 2001 From: David Craven Date: Fri, 23 Feb 2018 11:27:51 +0100 Subject: [PATCH 018/112] Move examples to workspace. --- .cargo/config | 6 --- .gdbinit | 24 ------------ Cargo.toml | 17 ++------- Makefile | 51 ------------------------- Xargo.toml | 7 ---- build.rs | 7 ---- examples/blinky_clint.rs | 24 ------------ examples/blinky_delay.rs | 34 ----------------- examples/blinky_plic.rs | 54 --------------------------- examples/blinky_pwm.rs | 81 ---------------------------------------- examples/hello_world.rs | 13 ------- examples/panicking.rs | 19 ---------- examples/pll.rs | 27 -------------- openocd.cfg | 34 ----------------- 14 files changed, 4 insertions(+), 394 deletions(-) delete mode 100644 .cargo/config delete mode 100644 .gdbinit delete mode 100644 Makefile delete mode 100644 Xargo.toml delete mode 100644 examples/blinky_clint.rs delete mode 100644 examples/blinky_delay.rs delete mode 100644 examples/blinky_plic.rs delete mode 100644 examples/blinky_pwm.rs delete mode 100644 examples/hello_world.rs delete mode 100644 examples/panicking.rs delete mode 100644 examples/pll.rs delete mode 100644 openocd.cfg diff --git a/.cargo/config b/.cargo/config deleted file mode 100644 index a4229f7..0000000 --- a/.cargo/config +++ /dev/null @@ -1,6 +0,0 @@ -[target.riscv32-unknown-none] -runner = 'riscv32-unknown-elf-gdb' -rustflags = [ - "-C", "link-arg=-Tlink.x", - "-C", "linker=riscv32-unknown-elf-ld", -] \ No newline at end of file diff --git a/.gdbinit b/.gdbinit deleted file mode 100644 index b99fc56..0000000 --- a/.gdbinit +++ /dev/null @@ -1,24 +0,0 @@ -set remotetimeout 240 -target extended-remote localhost:3333 - -define upload - monitor reset halt - monitor flash protect 0 64 last off - load - monitor flash protect 0 64 last on - continue -end -document upload -Upload program to hifive board -end - -# Load Rust's GDB pretty printers -python -import os; -import sys; -path = os.environ['TOOLCHAIN'] + '/lib/rustlib/etc' -sys.path.append(path) - -gdb.execute('directory %s' % path) -gdb.execute('add-auto-load-safe-path %s' % path) -end diff --git a/Cargo.toml b/Cargo.toml index 29d8477..9e9851d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,16 +15,7 @@ rev = "7d904f515d15fd5fe7ea34e18820ea83e2651fa2" [dependencies.nb] git = "https://github.com/japaric/nb" -[dependencies.riscv] -git = "https://github.com/dvc94ch/riscv" - -[dependencies.riscv-rt] -git = "https://github.com/dvc94ch/riscv-rt" - -[dependencies.e310x] -features = ["rt"] -git = "https://github.com/dvc94ch/e310x" - -[profile.release] -debug = true -lto = true \ No newline at end of file +[dependencies] +riscv = { path = "../riscv" } +riscv-rt = { path = "../riscv-rt" } +e310x = { path = "../e310x", features = ["rt"] } diff --git a/Makefile b/Makefile deleted file mode 100644 index 027d085..0000000 --- a/Makefile +++ /dev/null @@ -1,51 +0,0 @@ -# Examples (uncomment one) -#EXAMPLE := blinky_delay -#EXAMPLE := blinky_clint -#EXAMPLE := blinky_pwm -#EXAMPLE := blinky_plic -#EXAMPLE := hello_world -#EXAMPLE := panicking -#EXAMPLE := pll - -# Board crate (uncomment one) -BOARD := hifive - -TARGET := riscv32-unknown-none -TARGET_DIR := $(abspath ./target/$(TARGET)/debug) -EXAMPLE_DIR := $(TARGET_DIR)/examples -EXAMPLE_BIN := $(EXAMPLE_DIR)/$(EXAMPLE) -OPENOCD_CFG := $(wildcard $(TARGET_DIR)/build/$(BOARD)-*/out/openocd.cfg) - -build: - xargo build --examples --target $(TARGET) $(ARGS) - -test: - xargo test --all --target $(TARGET) $(ARGS) - -clean: - xargo clean $(ARGS) - -readelf: - llvm-readelf -a -h -s -r -symbols $(EXAMPLE_BIN) $(ARGS) - -objdump: - llvm-objdump -d -S $(EXAMPLE_BIN) $(ARGS) - -size: - llvm-size $(EXAMPLE_BIN) $(ARGS) - -# .gdbinit adds a upload command to gdb -gdb: - riscv32-unknown-elf-gdb $(EXAMPLE_BIN) $(ARGS) - -openocd: - openocd -f $(OPENOCD_CFG) $(ARGS) - -upload: - openocd -f $(OPENOCD_CFG) \ - -c "flash protect 0 64 last off; program ${EXAMPLE_BIN}; resume 0x20400000; exit" - -framedump: - riscv32-unknown-elf-readelf --debug-dump=frames $(EXAMPLE_BIN) $(ARGS) - -.PHONY: build clean readelf objdump framedump size gdb openocd spike diff --git a/Xargo.toml b/Xargo.toml deleted file mode 100644 index 001a159..0000000 --- a/Xargo.toml +++ /dev/null @@ -1,7 +0,0 @@ -[dependencies] -core = {} -alloc = {} - -[dependencies.compiler_builtins] -features = ["mem"] -stage = 1 diff --git a/build.rs b/build.rs index ab3a5b6..dedafe9 100644 --- a/build.rs +++ b/build.rs @@ -13,12 +13,5 @@ fn main() { println!("cargo:rustc-link-search={}", out.display()); println!("cargo:rerun-if-changed=memory.x"); - // Copy openocd.cfg to output directory - File::create(out.join("openocd.cfg")) - .unwrap() - .write_all(include_bytes!("openocd.cfg")) - .unwrap(); - println!("cargo:rerun-if-changed=openocd.cfg"); - println!("cargo:rerun-if-changed=build.rs"); } diff --git a/examples/blinky_clint.rs b/examples/blinky_clint.rs deleted file mode 100644 index 3798ccf..0000000 --- a/examples/blinky_clint.rs +++ /dev/null @@ -1,24 +0,0 @@ -#![no_std] - -extern crate hifive; - -use hifive::prelude::*; -use hifive::{interrupt, led, Blue, Clint, Peripherals, UExt}; - -fn main() { - let peripherals = hifive::init(115_200); - led::init(peripherals.GPIO0); - - let timer = Clint(peripherals.CLINT); - timer.set_timeout(1.s()); - - unsafe { - interrupt::enable(); - } -} - -#[no_mangle] -pub fn mtimer_trap_handler(p: &Peripherals) { - Clint(p.CLINT).restart(); - Blue::toggle(p.GPIO0); -} diff --git a/examples/blinky_delay.rs b/examples/blinky_delay.rs deleted file mode 100644 index 3f40f33..0000000 --- a/examples/blinky_delay.rs +++ /dev/null @@ -1,34 +0,0 @@ -#![no_std] - -#[macro_use] -extern crate nb; -extern crate hifive; - -use hifive::prelude::*; -use hifive::{led, Red, Green, Blue, Clint, UExt}; - -fn delay(clint: &Clint) { - block!(clint.wait()).unwrap(); - clint.restart(); -} - -fn main() { - let peripherals = hifive::init(115_200); - led::init(peripherals.GPIO0); - - let clint = Clint(peripherals.CLINT); - clint.set_timeout(500.ms()); - - let gpio = peripherals.GPIO0; - loop { - Red::on(gpio); - delay(&clint); - Red::off(gpio); - Green::on(gpio); - delay(&clint); - Green::off(gpio); - Blue::on(gpio); - delay(&clint); - Blue::off(gpio); - } -} diff --git a/examples/blinky_plic.rs b/examples/blinky_plic.rs deleted file mode 100644 index a23c131..0000000 --- a/examples/blinky_plic.rs +++ /dev/null @@ -1,54 +0,0 @@ -#![no_std] - -extern crate hifive; - -use core::fmt::Write; -use hifive::*; -use hifive::prelude::*; -use hifive::interrupt::Nr; - -fn main() { - let p = hifive::init(115_200); - led::init(p.GPIO0); - - Red::on(p.GPIO0); - - let plic = Plic(p.PLIC); - plic.init(); - - RtcConf::new().end(p.RTC); - Rtc(p.RTC).set_timeout(500.ms()); - - plic.set_priority(Interrupt::RTC, Priority::P7); - plic.enable(Interrupt::RTC); - - let serial = Serial(p.UART0); - let mut stdout = Port(&serial); - writeln!(stdout, "External interrupts enabled: {}", - csr::mie.read().mext()).unwrap(); - let threshold: u32 = plic.get_threshold().into(); - writeln!(stdout, "PLIC threshold priority: {}", - threshold).unwrap(); - writeln!(stdout, "RTC interrupt number: {}", - Interrupt::RTC.nr()).unwrap(); - writeln!(stdout, "RTC interrupt enabled: {}", - plic.is_enabled(Interrupt::RTC)).unwrap(); - let priority: u32 = plic.get_priority(Interrupt::RTC).into(); - writeln!(stdout, "RTC interrupt priority: {}", - priority).unwrap(); - - unsafe { - interrupt::enable(); - } -} - -#[no_mangle] -pub fn plic_trap_handler(p: &Peripherals, intr: &Interrupt) { - match *intr { - Interrupt::RTC => { - Rtc(p.RTC).restart(); - Blue::toggle(p.GPIO0); - }, - _ => {}, - } -} diff --git a/examples/blinky_pwm.rs b/examples/blinky_pwm.rs deleted file mode 100644 index bf0d14a..0000000 --- a/examples/blinky_pwm.rs +++ /dev/null @@ -1,81 +0,0 @@ -#![no_std] - -extern crate hifive; - -use hifive::{Channel, Align, Pwm}; - -const RED: Channel = Channel::_3; -const GREEN: Channel = Channel::_1; -const BLUE: Channel = Channel::_2; - -/* -struct Color { - red: u8, - green: u8, - blue: u8, -} - -impl Color { - pub fn from(red: u8, green: u8, blue: u8) -> Self { - Color { red, green, blue } - } -} - -fn set_color(pwm: Pwm, color: Color) { - pwm.set_cmp(RED, u16::max_value() / 255 * color.red as u16); - pwm.set_cmp(GREEN, u16::max_value() / 255 * color.green as u16); - pwm.set_cmp(BLUE, u16::max_value() / 255 * color.blue as u16); -} -*/ - -fn main() { - let peripherals = hifive::init(115_200); - let gpio = peripherals.GPIO0; - - //let clint = Clint(peripherals.CLINT); - let pwm = Pwm(peripherals.PWM1); - - pwm.set_cmp(Channel::_0, u16::max_value()); - //pwm.set_period(63); - - pwm.enable(RED, Align::Left, gpio); - pwm.invert(RED, gpio); - pwm.set_cmp(RED, u16::max_value() / 3); - - pwm.enable(GREEN, Align::Center, gpio); - pwm.invert(GREEN, gpio); - pwm.set_cmp(GREEN, u16::max_value() / 2); - - pwm.enable(BLUE, Align::Right, gpio); - pwm.invert(BLUE, gpio); - pwm.set_cmp(BLUE, u16::max_value() / 3 * 2); - - pwm.init(); - - //let delay = 1.s(); - - /*loop { - // Gray - set_color(pwm, Color::from(0x80, 0x80, 0x80)); - clint.set_timeout(delay); - block!(clint.wait()); - // Purple - set_color(pwm, Color::from(0x80, 0x00, 0x80)); - clint.set_timeout(delay); - block!(clint.wait()); - // Maroon - set_color(pwm, Color::from(0x80, 0x00, 0x00)); - clint.set_timeout(delay); - block!(clint.wait()); - }*/ - - //pwm.invert(GREEN, gpio, true); - //pwm.align_center(GREEN); - //pwm.set_cmp(GREEN, u16::max_value() / 2); - - //pwm.align_left(RED); - //pwm.align_right(BLUE); - //pwm.set_cmp(BLUE, u16::max_value() / 3 * 2); - //pwm.set_cmp(BLUE, 0); - //pwm.enable(BLUE, gpio); -} diff --git a/examples/hello_world.rs b/examples/hello_world.rs deleted file mode 100644 index 9f5678d..0000000 --- a/examples/hello_world.rs +++ /dev/null @@ -1,13 +0,0 @@ -#![no_std] - -extern crate hifive; - -use core::fmt::Write; -use hifive::{Port, Serial}; - -fn main() { - let peripherals = hifive::init(115_200); - - let serial = Serial(peripherals.UART0); - writeln!(Port(&serial), "hello world!").unwrap(); -} diff --git a/examples/panicking.rs b/examples/panicking.rs deleted file mode 100644 index 3043756..0000000 --- a/examples/panicking.rs +++ /dev/null @@ -1,19 +0,0 @@ -#![no_std] - -extern crate hifive; - -fn three(_1: u32, _2: u32) { - panic!() -} - -fn two() { - three(0x0123_4567, 0x1234_5678); -} - -fn one() { - two(); -} - -fn main() { - one(); -} diff --git a/examples/pll.rs b/examples/pll.rs deleted file mode 100644 index 054efa1..0000000 --- a/examples/pll.rs +++ /dev/null @@ -1,27 +0,0 @@ -#![no_std] - -extern crate hifive; - -use core::fmt::Write; -use hifive::{clock, Clint, Port, Serial}; - -fn main() { - let p = hifive::init(115_200); - - let serial = Serial(p.UART0); - let mut stdout = Port(&serial); - writeln!(stdout, "Setting up PLL").unwrap(); - - let clint = Clint(p.CLINT); - let clock = clock::CoreClock(p.PRCI); - - let freq_calc_default = clock.pll_mult() * 16; - unsafe { clock.use_pll(&clint); } - let freq_calc = clock.pll_mult() * 16; - let freq_measured = clock.measure(&clint) / 1_000_000; - unsafe { clock.use_external(&clint); } - - writeln!(stdout, "Default PLL settings {}MHz", freq_calc_default).unwrap(); - writeln!(stdout, "Measured clock frequency of {}MHz", freq_measured).unwrap(); - writeln!(stdout, "Computed clock frequency of {}MHz", freq_calc).unwrap(); -} diff --git a/openocd.cfg b/openocd.cfg deleted file mode 100644 index 40e7849..0000000 --- a/openocd.cfg +++ /dev/null @@ -1,34 +0,0 @@ -adapter_khz 10000 - -interface ftdi -ftdi_device_desc "Dual RS232-HS" -ftdi_vid_pid 0x0403 0x6010 - -ftdi_layout_init 0x0008 0x001b -ftdi_layout_signal nSRST -oe 0x0020 -data 0x0020 - -#Reset Stretcher logic on FE310 is ~1 second long -#This doesn't apply if you use -# ftdi_set_signal, but still good to document -#adapter_nsrst_delay 1500 - -set _CHIPNAME riscv -jtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x10e31913 - -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME riscv -chain-position $_TARGETNAME -$_TARGETNAME configure -work-area-phys 0x80000000 -work-area-size 10000 -work-area-backup 1 - -flash bank onboard_spi_flash fespi 0x20000000 0 0 0 $_TARGETNAME -init -#reset -- This type of reset is not implemented yet -if {[ info exists pulse_srst]} { - ftdi_set_signal nSRST 0 - ftdi_set_signal nSRST z - #Wait for the reset stretcher - #It will work without this, but - #will incur lots of delays for later commands. - sleep 1500 -} -halt -#flash protect 0 64 last off \ No newline at end of file From 9550d4ea044741a15d73cb442be4f075315916b9 Mon Sep 17 00:00:00 2001 From: David Craven Date: Tue, 27 Feb 2018 17:41:07 +0100 Subject: [PATCH 019/112] Disable init message. --- src/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index ce04098..20f29e2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -53,7 +53,6 @@ pub fn init<'a>(baud_rate: u32) -> e310x::Peripherals<'a> { // Initialize UART0 let serial = Serial(peripherals.UART0); serial.init(baud_rate.hz().invert(), peripherals.GPIO0); - writeln!(Port(&serial), "Initialized hifive board").unwrap(); peripherals } From 247d1820f5679d773f0a94c441d23b104e2be303 Mon Sep 17 00:00:00 2001 From: David Craven Date: Wed, 28 Feb 2018 20:07:05 +0100 Subject: [PATCH 020/112] Add interrupt and exception trap handler. --- src/lib.rs | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 20f29e2..2cd699b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -10,7 +10,7 @@ extern crate embedded_hal as hal; #[macro_use] extern crate nb; -extern crate riscv; +pub extern crate riscv; pub extern crate e310x; pub mod clint; @@ -23,9 +23,6 @@ pub mod rtc; pub mod serial; pub mod time; -use core::fmt::Write; -use riscv::interrupt::Nr; - pub use hal::prelude; pub use riscv::{csr, interrupt}; pub use e310x::Peripherals; @@ -66,33 +63,30 @@ pub fn init<'a>(baud_rate: u32) -> e310x::Peripherals<'a> { pub fn trap_handler(trap: riscv::csr::Trap) { use riscv::csr::{Trap, Interrupt}; - let peripherals = unsafe { e310x::Peripherals::all() }; - let serial = Serial(peripherals.UART0); + let p = unsafe { e310x::Peripherals::all() }; match trap { Trap::Interrupt(x) => { match x { Interrupt::MachineTimer => { - writeln!(Port(&serial), "MachineTimer").unwrap(); - mtimer_trap_handler(&peripherals); + mtimer_trap_handler(&p); }, Interrupt::MachineExternal => { - let plic = Plic(peripherals.PLIC); + let plic = Plic(p.PLIC); let intr = plic.claim(); - writeln!(Port(&serial), "ExternalInterrupt {}", intr.nr()).unwrap(); - plic_trap_handler(&peripherals, &intr); + plic_trap_handler(&p, &intr); plic.complete(intr); } x => { - writeln!(Port(&serial), "Interrupt {}", x as u32).unwrap(); + interrupt_trap_handler(&p, x); }, } }, Trap::Exception(x) => { let mepc = csr::mepc.read().bits(); - writeln!(Port(&serial), "Exception {} at 0x{:x}", x as u32, mepc).unwrap(); + exception_trap_handler(&p, x, mepc); }, } } @@ -107,6 +101,18 @@ pub fn mtimer_trap_handler(_: &e310x::Peripherals) {} #[linkage = "weak"] pub fn plic_trap_handler(_: &e310x::Peripherals, _: &Interrupt) {} +/// Default Interrupt Trap Handler +/// +/// Only called when interrupt is not a MachineTimer or +/// MachineExternal interrupt. +#[no_mangle] +#[linkage = "weak"] +pub fn interrupt_trap_handler(_: &e310x::Peripherals, _: riscv::csr::Interrupt) {} + +/// Default Exception Trap Handler +#[no_mangle] +#[linkage = "weak"] +pub fn exception_trap_handler(_: &e310x::Peripherals, _: riscv::csr::Exception, _: u32) {} macro_rules! ticks_impl { ($n:ident, $t:ty, $f:expr) => { From cf0b038da450c9730c1ff5a9091a07b96b812cbb Mon Sep 17 00:00:00 2001 From: David Craven Date: Thu, 1 Mar 2018 12:03:11 +0100 Subject: [PATCH 021/112] Update to svd2rust 0.12.0 --- src/lib.rs | 24 +++--------------------- src/plic.rs | 14 ++++++++------ 2 files changed, 11 insertions(+), 27 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 2cd699b..d1c93d4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,6 +4,7 @@ #![feature(lang_items)] #![feature(linkage)] #![feature(never_type)] +#![feature(try_from)] #![feature(used)] extern crate embedded_hal as hal; @@ -35,25 +36,6 @@ pub use rtc::{Rtc, RtcConf}; pub use serial::{Serial, Port}; pub use time::UExt; -/// Initializes the clocks, plic and uart0. Returns Peripherals -/// for application specific initialization. -pub fn init<'a>(baud_rate: u32) -> e310x::Peripherals<'a> { - let peripherals = unsafe { e310x::Peripherals::all() }; - - // Setup clocks - let clint = Clint(peripherals.CLINT); - let aon_clock = clock::AonClock(peripherals.AONCLK); - unsafe { aon_clock.use_external(); } - let clock = clock::CoreClock(peripherals.PRCI); - unsafe { clock.use_external(&clint); } - - // Initialize UART0 - let serial = Serial(peripherals.UART0); - serial.init(baud_rate.hz().invert(), peripherals.GPIO0); - - peripherals -} - /// Default trap handler /// /// Prints trap cause and calls mtimer_trap_handler or plic_trap_handler if @@ -63,7 +45,7 @@ pub fn init<'a>(baud_rate: u32) -> e310x::Peripherals<'a> { pub fn trap_handler(trap: riscv::csr::Trap) { use riscv::csr::{Trap, Interrupt}; - let p = unsafe { e310x::Peripherals::all() }; + let p = e310x::Peripherals::take().unwrap(); match trap { Trap::Interrupt(x) => { @@ -72,7 +54,7 @@ pub fn trap_handler(trap: riscv::csr::Trap) { mtimer_trap_handler(&p); }, Interrupt::MachineExternal => { - let plic = Plic(p.PLIC); + let plic = Plic(&p.PLIC); let intr = plic.claim(); plic_trap_handler(&p, &intr); diff --git a/src/plic.rs b/src/plic.rs index 97226d0..91f3ba6 100644 --- a/src/plic.rs +++ b/src/plic.rs @@ -1,3 +1,4 @@ +use core::convert::TryFrom; use riscv::csr; use riscv::interrupt::Nr; use e310x::PLIC; @@ -147,7 +148,7 @@ impl<'a> Plic<'a> { /// Claims the plic::Interrupt with the highest priority. pub fn claim(&self) -> Interrupt { - Interrupt::from(self.0.claim.read().bits() as u8) + Interrupt::try_from(self.0.claim.read().bits() as u8).unwrap() } /// Notifies the PLIC that the claimed plic::Interrupt is @@ -159,18 +160,19 @@ impl<'a> Plic<'a> { } /// Returns the plic::Priority of a plic::Interrupt. - pub fn get_priority(&self, intr: Interrupt) -> Priority { + pub fn get_priority(&self, _intr: Interrupt) -> Priority { // Priority array is offset by one. - Priority::from(self.0.priority[intr.nr() as usize - 1].read().bits()) + Priority::from(0) + //Priority::from(self.0.priority[intr.nr() as usize - 1].read().bits()) } /// Sets the plic::Priority of a plic::Interrupt. - pub fn set_priority(&self, intr: Interrupt, prio: Priority) { + pub fn set_priority(&self, _intr: Interrupt, _prio: Priority) { // Priority array is offset by one. - unsafe { + /*unsafe { self.0.priority[intr.nr() as usize - 1] .write(|w| w.bits(prio.into())); - } + }*/ } /// Returns the PLIC threshold priority. From 2a39d01f713d2074c6c1c378db508ec6dd66ef2f Mon Sep 17 00:00:00 2001 From: David Craven Date: Tue, 27 Mar 2018 20:20:25 +0200 Subject: [PATCH 022/112] Turn hifive into a bsp crate. --- Cargo.toml | 9 +- build.rs | 17 -- memory.x | 22 --- src/clint.rs | 165 ---------------- src/clock.rs | 165 ---------------- src/gpio.rs | 222 ---------------------- src/led.rs | 42 ---- src/lib.rs | 294 ++++++++++------------------ src/plic.rs | 190 ------------------- src/pwm.rs | 515 -------------------------------------------------- src/rtc.rs | 111 ----------- src/serial.rs | 151 --------------- src/time.rs | 110 ----------- 13 files changed, 104 insertions(+), 1909 deletions(-) delete mode 100644 build.rs delete mode 100644 memory.x delete mode 100644 src/clint.rs delete mode 100644 src/clock.rs delete mode 100644 src/gpio.rs delete mode 100644 src/led.rs delete mode 100644 src/plic.rs delete mode 100644 src/pwm.rs delete mode 100644 src/rtc.rs delete mode 100644 src/serial.rs delete mode 100644 src/time.rs diff --git a/Cargo.toml b/Cargo.toml index 9e9851d..c4b3a34 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,14 +8,7 @@ description = "Board support crate for hifive and lofive boards." keywords = ["riscv", "register", "peripheral"] license = "ISC" -[dependencies.embedded-hal] -git = "https://github.com/japaric/embedded-hal" -rev = "7d904f515d15fd5fe7ea34e18820ea83e2651fa2" - -[dependencies.nb] -git = "https://github.com/japaric/nb" - [dependencies] riscv = { path = "../riscv" } riscv-rt = { path = "../riscv-rt" } -e310x = { path = "../e310x", features = ["rt"] } +e310x-hal = { path = "../e310x-hal", features = ["pll", "hfxosc", "lfaltclk"] } diff --git a/build.rs b/build.rs deleted file mode 100644 index dedafe9..0000000 --- a/build.rs +++ /dev/null @@ -1,17 +0,0 @@ -use std::env; -use std::fs::File; -use std::io::Write; -use std::path::PathBuf; - -fn main() { - // Put the linker script somewhere the linker can find it - 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()); - println!("cargo:rerun-if-changed=memory.x"); - - println!("cargo:rerun-if-changed=build.rs"); -} diff --git a/memory.x b/memory.x deleted file mode 100644 index c991460..0000000 --- a/memory.x +++ /dev/null @@ -1,22 +0,0 @@ -MEMORY -{ -/* NOTE K = KiBi = 1024 bytes */ -/* TODO Adjust these memory regions to match your device memory layout */ -FLASH : ORIGIN = 0x20400000, LENGTH = 512M -RAM : ORIGIN = 0x80000000, LENGTH = 16K -} - -/* This is where the call stack will be allocated. */ -/* The stack is of the full descending type. */ -/* You may want to use this variable to locate the call stack and static -variables in different memory regions. Below is shown the default value */ - -/* _stack_start = ORIGIN(RAM) + LENGTH(RAM); */ - -/* You can use this symbol to customize the location of the .text section */ -/* If omitted the .text section will be placed right after the .vector_table -section */ -/* This is required only on microcontrollers that store some configuration right -after the vector table */ - -/* _stext = ORIGIN(FLASH); */ diff --git a/src/clint.rs b/src/clint.rs deleted file mode 100644 index c2b86e0..0000000 --- a/src/clint.rs +++ /dev/null @@ -1,165 +0,0 @@ -//! Clint - -use riscv::{csr, interrupt}; -use e310x::CLINT; - -pub struct Clint<'a>(pub &'a CLINT); - -impl<'a> Clone for Clint<'a> { - fn clone(&self) -> Self { - *self - } -} - -impl<'a> Copy for Clint<'a> { -} - -impl<'a> Clint<'a> { - /// Read mtime register. - pub fn get_mtime(&self) -> ::aonclk::Ticks { - loop { - let hi = self.0.mtimeh.read().bits(); - let lo = self.0.mtime.read().bits(); - if hi == self.0.mtimeh.read().bits() { - return ::aonclk::Ticks(((hi as u64) << 32) | lo as u64); - } - } - } - - /// Write mtime register. - pub fn set_mtime(&self, time: ::aonclk::Ticks) { - unsafe { - self.0.mtimeh.write(|w| w.bits(time.into_hi())); - self.0.mtime.write(|w| w.bits(time.into())); - } - } - - /// Read mtimecmp register. - pub fn get_mtimecmp(&self) -> ::aonclk::Ticks { - let hi = self.0.mtimecmph.read().bits() as u64; - let lo = self.0.mtimecmp.read().bits() as u64; - ::aonclk::Ticks(hi << 32 | lo) - } - - /// Write mtimecmp register. - pub fn set_mtimecmp(&self, time: ::aonclk::Ticks) { - unsafe { - self.0.mtimecmph.write(|w| w.bits(time.into_hi())); - self.0.mtimecmp.write(|w| w.bits(time.into())); - } - } - - /// Read mcycle register. - pub fn get_mcycle(&self) -> ::coreclk::Ticks { - loop { - let hi = csr::mcycleh.read().bits(); - let lo = csr::mcycle.read().bits(); - if hi == csr::mcycleh.read().bits() { - return ::coreclk::Ticks(((hi as u64) << 32) | lo as u64); - } - } - } - - /// Write mcycle register. - pub fn set_mcycle(&self, cycle: ::coreclk::Ticks) { - csr::mcycleh.write(|w| w.bits(cycle.into_hi())); - csr::mcycle.write(|w| w.bits(cycle.into())); - } - - /// Read minstret register. - pub fn get_minstret(&self) -> u64 { - loop { - let hi = csr::minstreth.read().bits(); - let lo = csr::minstret.read().bits(); - if hi == csr::minstreth.read().bits() { - return ((hi as u64) << 32) | lo as u64; - } - } - } - - /// Write minstret register. - pub fn set_minstret(&self, instret: u64) { - csr::minstreth.write(|w| w.bits((instret >> 32) as u32)); - csr::minstret.write(|w| w.bits(instret as u32)); - } - - - /// Enable Machine-Timer interrupt. - pub fn enable_mtimer(&self) { - csr::mie.set(|w| w.mtimer()); - } - - /// Disable Machine-Timer interrupt. - pub fn disable_mtimer(&self) { - csr::mie.clear(|w| w.mtimer()); - } - - /// Check if the Machine-Timer is interrupt pending. - pub fn is_mtimer_pending(&self) -> bool { - csr::mip.read().mtimer() - } - - /// Measure the coreclk frequency by counting the number of aonclk ticks. - pub fn measure_coreclk(&self, min_ticks: ::aonclk::Ticks) -> u32 { - interrupt::free(|_| { - let clint = self.0; - - // Don't start measuring until we see an mtime tick - while clint.mtime.read().bits() == clint.mtime.read().bits() {} - - let start_cycle = self.get_mcycle(); - let start_time = self.get_mtime(); - - // Wait for min_ticks to pass - while start_time + min_ticks > self.get_mtime() {} - - let end_cycle = self.get_mcycle(); - let end_time = self.get_mtime(); - - let delta_cycle: u32 = (end_cycle - start_cycle).into(); - let delta_time: u32 = (end_time - start_time).into(); - - (delta_cycle / delta_time) * 32768 - + ((delta_cycle % delta_time) * 32768) / delta_time - }) - } -} - -impl<'a> ::hal::Timer for Clint<'a> { - type Time = ::aonclk::Ticks; - - fn get_timeout(&self) -> ::aonclk::Ticks { - self.get_mtimecmp() - } - - fn pause(&self) { - self.disable_mtimer(); - } - - fn restart(&self) { - self.set_mtime(::aonclk::Ticks(0)); - self.enable_mtimer(); - } - - fn resume(&self) { - unimplemented!(); - } - - fn set_timeout(&self, timeout: T) - where - T: Into<::aonclk::Ticks>, - { - self.disable_mtimer(); - self.set_mtimecmp(timeout.into()); - self.set_mtime(::aonclk::Ticks(0)); - self.enable_mtimer(); - } - - fn wait(&self) -> ::nb::Result<(), !> { - if self.is_mtimer_pending() { - Ok(()) - } else { - Err(::nb::Error::WouldBlock) - } - } -} diff --git a/src/clock.rs b/src/clock.rs deleted file mode 100644 index 50ec9d2..0000000 --- a/src/clock.rs +++ /dev/null @@ -1,165 +0,0 @@ -//! Clock configuration -use e310x::{AONCLK, prci, PRCI}; -use clint::Clint; - -/// Aon Clock interface -pub struct AonClock<'a>(pub &'a AONCLK); - -impl<'a> Clone for AonClock<'a> { - fn clone(&self) -> Self { - *self - } -} - -impl<'a> Copy for AonClock<'a> {} - -impl<'a> AonClock<'a> { - /// Use external real time oscillator. - pub unsafe fn use_external(&self) { - // The G000 doesn't have a LFXOSC and is hardwired - // to use the an external oscillator. - // Disable unused LFROSC to save power. - self.0.lfrosccfg.write(|w| w.enable().bit(false)); - } -} - -/// Core Clock interface -pub struct CoreClock<'a>(pub &'a PRCI); - -impl<'a> Clone for CoreClock<'a> { - fn clone(&self) -> Self { - *self - } -} - -impl<'a> Copy for CoreClock<'a> { -} - -impl<'a> CoreClock<'a> { - /// Use external oscillator with bypassed pll. - pub unsafe fn use_external(&self, clint: &Clint) { - self.init_pll(clint, |_, w| { - // bypass PLL - w.bypass().bit(true) - // select HFXOSC - .refsel().bit(true) - }, |w| w.divby1().bit(true)); - // Disable HFROSC to save power - self.0.hfrosccfg.write(|w| w.enable().bit(false)); - } - - /// Use external oscillator with pll. Sets PLL - /// r=2, f=64, q=2 values to maximum allowable - /// for a 16MHz reference clock. Output frequency - /// is 16MHz / 2 * 64 / 2 = 256MHz. - /// NOTE: By trimming the internal clock to 12MHz - /// and using r=1, f=64, q=2 the maximum frequency - /// of 384MHz can be reached. - pub unsafe fn use_pll(&self, clint: &Clint) { - self.init_pll(clint, |_, w| { - // bypass PLL - w.bypass().bit(false) - // select HFXOSC - .refsel().bit(true) - // bits = r - 1 - .pllr().bits(1) - // bits = f / 2 - 1 - .pllf().bits(31) - // bits = q=2 -> 1, q=4 -> 2, q=8 -> 3 - .pllq().bits(1) - }, |w| w.divby1().bit(true)); - // Disable HFROSC to save power - self.0.hfrosccfg.write(|w| w.enable().bit(false)); - } - - /// Compute PLL multiplier. - pub fn pll_mult(&self) -> u32 { - let pllcfg = self.0.pllcfg.read(); - let plloutdiv = self.0.plloutdiv.read(); - - let r = pllcfg.pllr().bits() as u32 + 1; - let f = (pllcfg.pllf().bits() as u32 + 1) * 2; - let q = [2, 4, 8][pllcfg.pllq().bits() as usize - 1]; - - let div = match plloutdiv.divby1().bit() { - true => 1, - false => (plloutdiv.div().bits() as u32 + 1) * 2, - }; - - f / r / q / div - } - - /// Wait for the pll to lock. - unsafe fn wait_for_lock(&self, clint: &Clint) { - // Won't lock when bypassed and will loop forever - if !self.0.pllcfg.read().bypass().bit_is_set() { - // Wait for PLL Lock - // Note that the Lock signal can be glitchy. - // Need to wait 100 us - // RTC is running at 32kHz. - // So wait 4 ticks of RTC. - let time = clint.get_mtime() + ::aonclk::Ticks(4); - while clint.get_mtime() < time {} - // Now it is safe to check for PLL Lock - while !self.0.pllcfg.read().lock().bit_is_set() {} - } - } - - unsafe fn init_pll(&self, clint: &Clint, pllcfg: F, plloutdiv: G) - where - for<'w> F: FnOnce(&prci::pllcfg::R, - &'w mut prci::pllcfg::W) -> &'w mut prci::pllcfg::W, - for<'w> G: FnOnce(&'w mut prci::plloutdiv::W) -> &'w mut prci::plloutdiv::W, - { - // Make sure we are running of internal clock - // before configuring the PLL. - self.use_internal(); - // Enable HFXOSC - self.0.hfxosccfg.write(|w| w.enable().bit(true)); - // Wait for HFXOSC to stabilize - while !self.0.hfxosccfg.read().ready().bit_is_set() {} - // Configure PLL - self.0.pllcfg.modify(pllcfg); - self.0.plloutdiv.write(plloutdiv); - // Wait for PLL lock - self.wait_for_lock(clint); - // Switch to PLL - self.0.pllcfg.modify(|_, w| { - w.sel().bit(true) - }); - } - - /// Use internal oscillator with bypassed pll. - pub unsafe fn use_internal(&self) { - // Enable HFROSC - self.0.hfrosccfg.write(|w| { - w.enable().bit(true) - // It is OK to change this even if we are running off of it. - // Reset them to default values. - .div().bits(4) - .trim().bits(16) - }); - // Wait for HFROSC to stabilize - while !self.0.hfrosccfg.read().ready().bit_is_set() {} - // Switch to HFROSC - self.0.pllcfg.modify(|_, w| { - w.sel().bit(false) - }); - // Bypass PLL to save power - self.0.pllcfg.modify(|_, w| { - w.bypass().bit(true) - // Select HFROSC as PLL ref to disable HFXOSC later - .refsel().bit(false) - }); - // Disable HFXOSC to save power. - self.0.hfxosccfg.write(|w| w.enable().bit(false)); - } - - /// Measure the frequency of coreclk. - pub fn measure(&self, clint: &Clint) -> u32 { - // warm up I$ - clint.measure_coreclk(::aonclk::Ticks(1)); - // measure for real - clint.measure_coreclk(::aonclk::Ticks(10)) - } -} diff --git a/src/gpio.rs b/src/gpio.rs deleted file mode 100644 index dd9ff2e..0000000 --- a/src/gpio.rs +++ /dev/null @@ -1,222 +0,0 @@ -//! General Purpose I/O - -use core::ops::Deref; -use e310x::gpio0; - -/// Enumeration of possible pin configurations. -pub enum PinConfig { - Input, - InputPullup, - Output, - OutputDrive, - IoFn0, - IoFn1, -} - -/// Enumeration of pin interrupts. -pub enum PinInterrupt { - Rise, - Fall, - High, - Low, -} - -macro_rules! pin { - ($Pin:ident, $pinx:ident) => ( - pub struct $Pin; - - impl $Pin { - pub fn init(gpio: &T, config: PinConfig) - where - T: Deref, - { - match config { - PinConfig::Input => { - gpio.iof_en.modify(|_, w| w.$pinx().bit(false)); - gpio.pullup.modify(|_, w| w.$pinx().bit(false)); - gpio.input_en.modify(|_, w| w.$pinx().bit(true)); - }, - PinConfig::InputPullup => { - gpio.iof_en.modify(|_, w| w.$pinx().bit(false)); - gpio.pullup.modify(|_, w| w.$pinx().bit(true)); - gpio.input_en.modify(|_, w| w.$pinx().bit(true)); - }, - PinConfig::Output => { - gpio.iof_en.modify(|_, w| w.$pinx().bit(false)); - gpio.drive.modify(|_, w| w.$pinx().bit(false)); - gpio.output_en.modify(|_, w| w.$pinx().bit(true)); - }, - PinConfig::OutputDrive => { - gpio.iof_en.modify(|_, w| w.$pinx().bit(false)); - gpio.drive.modify(|_, w| w.$pinx().bit(true)); - gpio.output_en.modify(|_, w| w.$pinx().bit(true)); - }, - PinConfig::IoFn0 => { - gpio.iof_sel.modify(|_, w| w.$pinx().bit(false)); - gpio.iof_en.modify(|_, w| w.$pinx().bit(true)); - }, - PinConfig::IoFn1 => { - gpio.iof_sel.modify(|_, w| w.$pinx().bit(true)); - gpio.iof_en.modify(|_, w| w.$pinx().bit(true)); - }, - } - } - - pub fn read(gpio: &T) -> bool - where - T: Deref, - { - gpio.value.read().$pinx().bit() - } - - pub fn write(gpio: &T, value: bool) - where - T: Deref, - { - match value { - true => $Pin::high(gpio), - false => $Pin::low(gpio), - } - } - - pub fn high(gpio: &T) - where - T: Deref, - { - gpio.port.modify(|_, w| w.$pinx().bit(true)); - } - - pub fn low(gpio: &T) - where - T: Deref, - { - gpio.port.modify(|_, w| w.$pinx().bit(false)); - } - - pub fn toggle(gpio: &T) - where - T: Deref, - { - gpio.port.modify(|r, w| w.$pinx().bit(!r.$pinx().bit())); - } - - pub fn enable_interrupt(gpio: &T, intr: PinInterrupt) - where - T: Deref, - { - match intr { - PinInterrupt::Rise => - gpio.rise_ie.modify(|_, w| w.$pinx().bit(true)), - PinInterrupt::Fall => - gpio.fall_ie.modify(|_, w| w.$pinx().bit(true)), - PinInterrupt::High => - gpio.high_ie.modify(|_, w| w.$pinx().bit(true)), - PinInterrupt::Low => - gpio.low_ie.modify(|_, w| w.$pinx().bit(true)), - }; - } - - pub fn disable_interrupt(gpio: &T, intr: PinInterrupt) - where - T: Deref, - { - match intr { - PinInterrupt::Rise => - gpio.rise_ie.modify(|_, w| w.$pinx().bit(false)), - PinInterrupt::Fall => - gpio.fall_ie.modify(|_, w| w.$pinx().bit(false)), - PinInterrupt::High => - gpio.high_ie.modify(|_, w| w.$pinx().bit(false)), - PinInterrupt::Low => - gpio.low_ie.modify(|_, w| w.$pinx().bit(false)), - }; - } - - pub fn clear_pending(gpio: &T, intr: PinInterrupt) - where - T: Deref, - { - match intr { - PinInterrupt::Rise => - gpio.rise_ip.write(|w| w.$pinx().bit(true)), - PinInterrupt::Fall => - gpio.fall_ip.write(|w| w.$pinx().bit(true)), - PinInterrupt::High => - gpio.high_ip.write(|w| w.$pinx().bit(true)), - PinInterrupt::Low => - gpio.low_ip.write(|w| w.$pinx().bit(true)), - } - } - - pub fn is_interrupt_pending(gpio: &T, intr: PinInterrupt) -> bool - where - T: Deref, - { - match intr { - PinInterrupt::Rise => - gpio.rise_ip.read().$pinx().bit(), - PinInterrupt::Fall => - gpio.fall_ip.read().$pinx().bit(), - PinInterrupt::High => - gpio.high_ip.read().$pinx().bit(), - PinInterrupt::Low => - gpio.low_ip.read().$pinx().bit(), - } - } - - pub fn is_inverted(gpio: &T) -> bool - where - T: Deref, - { - gpio.out_xor.read().$pinx().bit() - } - - pub fn set_invert(gpio: &T, value: bool) - where - T: Deref, - { - gpio.out_xor.modify(|_, w| w.$pinx().bit(value)); - } - - pub fn invert(gpio: &T) - where - T: Deref, - { - gpio.out_xor.modify(|r, w| w.$pinx().bit(!r.$pinx().bit())); - } - } - ) -} - -pin!(Pin0, pin0); -pin!(Pin1, pin1); -pin!(Pin2, pin2); -pin!(Pin3, pin3); -pin!(Pin4, pin4); -pin!(Pin5, pin5); -pin!(Pin6, pin6); -pin!(Pin7, pin7); -pin!(Pin8, pin8); -pin!(Pin9, pin9); -pin!(Pin10, pin10); -pin!(Pin11, pin11); -pin!(Pin12, pin12); -pin!(Pin13, pin13); -pin!(Pin14, pin14); -pin!(Pin15, pin15); -pin!(Pin16, pin16); -pin!(Pin17, pin17); -pin!(Pin18, pin18); -pin!(Pin19, pin19); -pin!(Pin20, pin20); -pin!(Pin21, pin21); -pin!(Pin22, pin22); -pin!(Pin23, pin23); -pin!(Pin24, pin24); -pin!(Pin25, pin25); -pin!(Pin26, pin26); -pin!(Pin27, pin27); -pin!(Pin28, pin28); -pin!(Pin29, pin29); -pin!(Pin30, pin30); -pin!(Pin31, pin31); diff --git a/src/led.rs b/src/led.rs deleted file mode 100644 index a52d1d8..0000000 --- a/src/led.rs +++ /dev/null @@ -1,42 +0,0 @@ -//! User LEDs -//! -//! - Red = Pin 22 -//! - Green = Pin 19 -//! - Blue = Pin 21 - -use e310x::GPIO0; -use gpio::{PinConfig, Pin22, Pin19, Pin21}; - -pub fn init(gpio: &GPIO0) { - Pin22::set_invert(gpio, true); - Pin22::init(gpio, PinConfig::Output); - Pin19::set_invert(gpio, true); - Pin19::init(gpio, PinConfig::Output); - Pin21::set_invert(gpio, true); - Pin21::init(gpio, PinConfig::Output); -} - -#[macro_export] -macro_rules! led { - ($Color:ident, $Pin:ident) => { - pub struct $Color; - - impl $Color { - pub fn on(gpio: &GPIO0) { - $Pin::high(gpio); - } - - pub fn off(gpio: &GPIO0) { - $Pin::low(gpio); - } - - pub fn toggle(gpio: &GPIO0) { - $Pin::toggle(gpio); - } - } - } -} - -led!(Red, Pin22); -led!(Green, Pin19); -led!(Blue, Pin21); diff --git a/src/lib.rs b/src/lib.rs index d1c93d4..1f1b543 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,212 +1,124 @@ +//! Board support crate for the Hifive + +#![deny(missing_docs)] +#![deny(warnings)] #![no_std] -#![feature(asm)] -#![feature(get_type_id)] -#![feature(lang_items)] -#![feature(linkage)] -#![feature(never_type)] -#![feature(try_from)] -#![feature(used)] - -extern crate embedded_hal as hal; -#[macro_use] -extern crate nb; - -pub extern crate riscv; -pub extern crate e310x; - -pub mod clint; -pub mod clock; -pub mod gpio; -pub mod led; -pub mod plic; -pub mod pwm; -pub mod rtc; -pub mod serial; -pub mod time; - -pub use hal::prelude; -pub use riscv::{csr, interrupt}; -pub use e310x::Peripherals; -pub use gpio::{PinConfig, PinInterrupt}; -pub use clint::Clint; -pub use led::{Red, Green, Blue}; -pub use plic::{Priority, Interrupt, Plic}; -pub use pwm::{Align, Channel, Pwm}; -pub use rtc::{Rtc, RtcConf}; -pub use serial::{Serial, Port}; -pub use time::UExt; - -/// Default trap handler -/// -/// Prints trap cause and calls mtimer_trap_handler or plic_trap_handler if -/// necessary. -#[used] -#[no_mangle] -pub fn trap_handler(trap: riscv::csr::Trap) { - use riscv::csr::{Trap, Interrupt}; - - let p = e310x::Peripherals::take().unwrap(); - - match trap { - Trap::Interrupt(x) => { - match x { - Interrupt::MachineTimer => { - mtimer_trap_handler(&p); - }, - Interrupt::MachineExternal => { - let plic = Plic(&p.PLIC); - let intr = plic.claim(); - - plic_trap_handler(&p, &intr); - - plic.complete(intr); - } - x => { - interrupt_trap_handler(&p, x); - }, - } - }, - Trap::Exception(x) => { - let mepc = csr::mepc.read().bits(); - exception_trap_handler(&p, x, mepc); - }, + +pub extern crate e310x_hal as hal; + +pub use serial::{TX, RX, tx_rx}; +pub use led::{RED, GREEN, BLUE, rgb}; + +pub mod serial { + //! Single UART hooked up to FTDI + //! + //! - Tx = Pin 17 + //! - Rx = Pin 16 + use hal::gpio::gpio0::{Pin16, Pin17, OUT_XOR, IOF_SEL, IOF_EN}; + use hal::gpio::{IOF0, NoInvert}; + + /// UART0 TX Pin + pub type TX = Pin17>; + /// UART0 RX Pin + pub type RX = Pin16>; + + /// Return TX, RX pins. + pub fn tx_rx( + tx: Pin17, rx: Pin16, + out_xor: &mut OUT_XOR, iof_sel: &mut IOF_SEL, + iof_en: &mut IOF_EN + ) -> (TX, RX) + { + let tx: TX = tx.into_iof0(out_xor, iof_sel, iof_en); + let rx: RX = rx.into_iof0(out_xor, iof_sel, iof_en); + (tx, rx) } } -/// Default MachineTimer Trap Handler -#[no_mangle] -#[linkage = "weak"] -pub fn mtimer_trap_handler(_: &e310x::Peripherals) {} - -/// Default MachineExternal Trap Handler -#[no_mangle] -#[linkage = "weak"] -pub fn plic_trap_handler(_: &e310x::Peripherals, _: &Interrupt) {} - -/// Default Interrupt Trap Handler -/// -/// Only called when interrupt is not a MachineTimer or -/// MachineExternal interrupt. -#[no_mangle] -#[linkage = "weak"] -pub fn interrupt_trap_handler(_: &e310x::Peripherals, _: riscv::csr::Interrupt) {} - -/// Default Exception Trap Handler -#[no_mangle] -#[linkage = "weak"] -pub fn exception_trap_handler(_: &e310x::Peripherals, _: riscv::csr::Exception, _: u32) {} - -macro_rules! ticks_impl { - ($n:ident, $t:ty, $f:expr) => { - pub const $n: $t = $f as $t; - - impl Ticks<$t> { - /// Applies the function `f` to the inner value - pub fn map(self, f: F) -> Ticks<$t> - where F: FnOnce($t) -> $t, - { - Ticks(f(self.0)) - } - } - - impl From> for Microseconds<$t> { - fn from(ticks: Ticks<$t>) -> Microseconds<$t> { - let divisor: $t = $n / 1_000_000; - Microseconds(ticks.0 / divisor) - } - } - - impl From> for Milliseconds<$t> { - fn from(ticks: Ticks<$t>) -> Milliseconds<$t> { - Milliseconds(ticks.0 / ($n / 1_000)) - } - } - - impl From> for Seconds<$t> { - fn from(ticks: Ticks<$t>) -> Seconds<$t> { - Seconds(ticks.0 / $n) - } - } - - impl From> for Ticks<$t> { - fn from(ihz: IHertz<$t>) -> Ticks<$t> { - Ticks($n / ihz.0) - } - } +pub mod led { + //! On-board user LEDs + //! + //! - Red = Pin 22 + //! - Green = Pin 19 + //! - Blue = Pin 21 + use hal::prelude::*; + use hal::gpio::gpio0::{Pin19, Pin21, Pin22, OUTPUT_EN, DRIVE, + OUT_XOR, IOF_EN}; + use hal::gpio::{Output, Regular, Invert}; + + /// Red LED + pub type RED = Pin22>>; + + /// Green LED + pub type GREEN = Pin19>>; + + /// Blue LED + pub type BLUE = Pin21>>; + + /// Returns RED, GREEN and BLUE LEDs. + pub fn rgb( + red: Pin22, green: Pin19, blue: Pin21, + output_en: &mut OUTPUT_EN, drive: &mut DRIVE, + out_xor: &mut OUT_XOR, iof_en: &mut IOF_EN + ) -> (RED, GREEN, BLUE) + { + let red: RED = red.into_inverted_output( + output_en, + drive, + out_xor, + iof_en, + ); + let green: GREEN = green.into_inverted_output( + output_en, + drive, + out_xor, + iof_en, + ); + let blue: BLUE = blue.into_inverted_output( + output_en, + drive, + out_xor, + iof_en, + ); + (red, green, blue) + } - impl From> for Ticks<$t> { - fn from(us: Microseconds<$t>) -> Ticks<$t> { - Ticks(us.0 * ($n / 1_000_000)) - } - } + /// Generic LED + pub trait Led { + /// Turns the LED off + fn off(&mut self); - impl From> for Ticks<$t> { - fn from(ms: Milliseconds<$t>) -> Ticks<$t> { - Ticks(ms.0 * ($n / 1_000)) - } - } + /// Turns the LED on + fn on(&mut self); + } - impl From> for Ticks<$t> { - fn from(s: Seconds<$t>) -> Ticks<$t> { - Ticks(s.0 * $n) - } + impl Led for RED { + fn on(&mut self) { + _embedded_hal_digital_OutputPin::set_high(self); } - impl Into<$t> for Ticks<$t> { - fn into(self) -> $t { - self.0 - } + fn off(&mut self) { + _embedded_hal_digital_OutputPin::set_low(self); } + } - impl ::core::ops::Add for Ticks<$t> { - type Output = Ticks<$t>; - - fn add(self, other: Ticks<$t>) -> Ticks<$t> { - Ticks(self.0 + other.0) - } + impl Led for GREEN { + fn on(&mut self) { + _embedded_hal_digital_OutputPin::set_high(self); } - impl ::core::ops::Sub for Ticks<$t> { - type Output = Ticks<$t>; - - fn sub(self, other: Ticks<$t>) -> Ticks<$t> { - Ticks(self.0 - other.0) - } + fn off(&mut self) { + _embedded_hal_digital_OutputPin::set_low(self); } } -} - -macro_rules! frequency { - ($FREQUENCY:expr) => { - use time::*; - /// Unit of time - #[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)] - pub struct Ticks(pub T); - - ticks_impl!(FREQUENCY_32, u32, $FREQUENCY); - ticks_impl!(FREQUENCY_64, u64, $FREQUENCY); - - impl Into for Ticks { - fn into(self) -> u32 { - self.0 as u32 - } + impl Led for BLUE { + fn on(&mut self) { + _embedded_hal_digital_OutputPin::set_high(self); } - impl Ticks { - pub fn into_hi(self) -> u32 { - (self.0 >> 32) as u32 - } + fn off(&mut self) { + _embedded_hal_digital_OutputPin::set_low(self); } } } - -/// Always-On Clock -pub mod aonclk { - frequency!(32_768); -} - -/// Core Clock -pub mod coreclk { - frequency!(16_000_000); -} diff --git a/src/plic.rs b/src/plic.rs deleted file mode 100644 index 91f3ba6..0000000 --- a/src/plic.rs +++ /dev/null @@ -1,190 +0,0 @@ -use core::convert::TryFrom; -use riscv::csr; -use riscv::interrupt::Nr; -use e310x::PLIC; -pub use e310x::Interrupt; - -/// Priority of a plic::Interrupt. -#[derive(Clone, Copy)] -pub enum Priority { - P0, P1, P2, P3, P4, P5, P6, P7, -} - -impl Priority { - /// Takes a read interrupt priority or plic threshold - /// register value and returns a plic::Priority enum. - fn from(prio: u32) -> Priority { - match prio { - 0 => Priority::P0, - 1 => Priority::P1, - 2 => Priority::P2, - 3 => Priority::P3, - 4 => Priority::P4, - 5 => Priority::P5, - 6 => Priority::P6, - 7 => Priority::P7, - _ => unreachable!(), - } - } -} - -impl Into for Priority { - /// Returns the numeric priority for writing to a - /// interrupt priority or the plic threshold register. - fn into(self) -> u32 { - match self { - Priority::P0 => 0, - Priority::P1 => 1, - Priority::P2 => 2, - Priority::P3 => 3, - Priority::P4 => 4, - Priority::P5 => 5, - Priority::P6 => 6, - Priority::P7 => 7, - } - } -} - -/// Plic interface -pub struct Plic<'a>(pub &'a PLIC); - -impl<'a> Clone for Plic<'a> { - fn clone(&self) -> Self { - *self - } -} - -impl<'a> Copy for Plic<'a> { -} - -/// Represents a register offset and mask for -/// accessing an individual bit in a register -/// file. -struct Loc { - offset: usize, - mask: u32, -} - -impl Loc { - /// Computes the location of an interrupt. - //#[inline] - pub fn from(intr: Interrupt) -> Self { - // offset = nr / 32 - // bit = nr % 32 - // 32 = 2 ^ 5 - let nr = intr.nr(); - let bit = nr & 31; - Self { - offset: (nr >> 5) as usize, - mask: 1 << bit - } - } - - /// Checks if bit is set. - //#[inline] - pub fn is_set(&self, bits: u32) -> bool { - bits & self.mask == self.mask - } -} - -impl<'a> Plic<'a> { - /// Initializes PLIC controller by resetting all - /// enable bits to 0 and enables MachineExternal - /// interrupts. - pub fn init(&self) { - for reg in self.0.enable.iter() { - unsafe { - // bug somewhere enabling interrupts - reg.write(|w| w.bits(0xFFFF_FFFF)); - } - } - self.set_threshold(Priority::P0); - self.enable_mext(); - } - - /// Enable MachineExternal interrupts. - #[inline] - pub fn enable_mext(&self) { - csr::mie.set(|w| w.mext()); - } - - /// Disable MachineExternal interrupts. - #[inline] - pub fn disable_mext(&self) { - csr::mie.clear(|w| w.mext()); - } - - /// Returns true when plic::Interrupt is pending. - pub fn is_pending(&self, intr: Interrupt) -> bool { - let loc = Loc::from(intr); - let pending = self.0.pending[loc.offset].read(); - loc.is_set(pending.bits()) - } - - /// Returns true when plic::Interrupt is enabled. - pub fn is_enabled(&self, intr: Interrupt) -> bool { - let loc = Loc::from(intr); - let enable = self.0.enable[loc.offset].read(); - loc.is_set(enable.bits()) - } - - /// Enables plic::Interrupt. - pub fn enable(&self, intr: Interrupt) { - let loc = Loc::from(intr); - unsafe { - self.0.enable[loc.offset] - .modify(|r, w| w.bits(r.bits() | loc.mask)); - } - } - - /// Disables plic::Interrupt. - pub fn disable(&self, intr: Interrupt) { - let loc = Loc::from(intr); - unsafe { - self.0.enable[loc.offset] - .modify(|r, w| w.bits(r.bits() & !loc.mask)); - } - } - - /// Claims the plic::Interrupt with the highest priority. - pub fn claim(&self) -> Interrupt { - Interrupt::try_from(self.0.claim.read().bits() as u8).unwrap() - } - - /// Notifies the PLIC that the claimed plic::Interrupt is - /// complete. - pub fn complete(&self, intr: Interrupt) { - unsafe { - self.0.claim.write(|w| w.bits(intr.nr() as u32)); - } - } - - /// Returns the plic::Priority of a plic::Interrupt. - pub fn get_priority(&self, _intr: Interrupt) -> Priority { - // Priority array is offset by one. - Priority::from(0) - //Priority::from(self.0.priority[intr.nr() as usize - 1].read().bits()) - } - - /// Sets the plic::Priority of a plic::Interrupt. - pub fn set_priority(&self, _intr: Interrupt, _prio: Priority) { - // Priority array is offset by one. - /*unsafe { - self.0.priority[intr.nr() as usize - 1] - .write(|w| w.bits(prio.into())); - }*/ - } - - /// Returns the PLIC threshold priority. - pub fn get_threshold(&self) -> Priority { - Priority::from(self.0.threshold.read().bits()) - } - - /// Sets the PLIC threshold priority. This disables all - /// interrupts with a lower plic::Priority. - pub fn set_threshold(&self, prio: Priority) { - unsafe { - self.0.threshold.write(|w| w.bits(prio.into())); - } - } -} diff --git a/src/pwm.rs b/src/pwm.rs deleted file mode 100644 index a105226..0000000 --- a/src/pwm.rs +++ /dev/null @@ -1,515 +0,0 @@ -//! Pulse Width Modulation -//! -//! You can use the `Pwm` interface with these PWM instances -//! -//! # PWM0 -//! -//! - CH0: Pin 0 IOF1 -//! - CH1: Pin 1 IOF1 -//! - CH2: Pin 2 IOF1 -//! - CH3: Pin 3 IOF1 -//! -//! # PWM1 -//! -//! - CH0: Pin 20 IOF1 -//! - CH1: Pin 19 IOF1 -//! - CH2: Pin 21 IOF1 -//! - CH3: Pin 22 IOF1 -//! -//! # PWM2 -//! -//! - CH0: Pin 10 IOF1 -//! - CH1: Pin 11 IOF1 -//! - CH2: Pin 12 IOF1 -//! - CH3: Pin 13 IOF1 - -use core::any::{Any, TypeId}; -use core::ops::Deref; - -use e310x::{pwm0, PWM0, PWM1, PWM2, gpio0, GPIO0}; -use gpio::{PinConfig, Pin0, Pin1, Pin2, Pin3, Pin20, Pin19, - Pin21, Pin22, Pin10, Pin11, Pin12, Pin13}; - -/// Channel -#[derive(Clone, Copy, Debug)] -pub enum Channel { - /// CH0 - _0, - /// CH1 - _1, - /// CH2 - _2, - /// CH3 - _3, -} - -/// Channel -#[derive(Clone, Copy, Debug)] -pub enum Align { - /// Left - Left, - /// Center - Center, - /// Right - Right, -} - -/// IMPLEMENTATION DETAIL -pub unsafe trait PWM: Deref { - /// IMPLEMENTATION DETAIL - type GPIO: Deref; -} - -unsafe impl PWM for PWM0 { - type GPIO = GPIO0; -} - -unsafe impl PWM for PWM1 { - type GPIO = GPIO0; -} - -unsafe impl PWM for PWM2 { - type GPIO = GPIO0; -} - -pub struct Pwm<'a, T>(pub &'a T) - where - T: 'a; - -impl<'a, T> Clone for Pwm<'a, T> { - fn clone(&self) -> Self { - *self - } -} - -impl<'a, T> Copy for Pwm<'a, T> {} - -impl<'a, T> Pwm<'a, T> - where - T: Any + PWM, -{ - pub fn init(&self) { - unsafe { - self.0.cfg.modify(|_, w| { - w.enalways().bit(true) - // set period of 1s - .scale().bits(8) - .zerocmp().bit(true) - }); - self.0.count.write(|w| w.bits(0)); - } - } - - pub fn enable(&self, channel: Channel, align: Align, gpio: &T::GPIO) { - if self.0.get_type_id() == TypeId::of::() { - match channel { - Channel::_0 => { - Pin0::init(gpio, PinConfig::IoFn1); - match align { - Align::Left => { - Pin0::set_invert(gpio, true); - self.set_center(channel, false); - }, - Align::Center => { - Pin0::set_invert(gpio, false); - self.set_center(channel, true); - }, - Align::Right => { - Pin0::set_invert(gpio, false); - self.set_center(channel, false); - } - } - }, - Channel::_1 => { - Pin1::init(gpio, PinConfig::IoFn1); - match align { - Align::Left => { - Pin1::set_invert(gpio, true); - self.set_center(channel, false); - }, - Align::Center => { - Pin1::set_invert(gpio, false); - self.set_center(channel, true); - }, - Align::Right => { - Pin1::set_invert(gpio, false); - self.set_center(channel, false); - } - } - }, - Channel::_2 => { - Pin2::init(gpio, PinConfig::IoFn1); - match align { - Align::Left => { - Pin2::set_invert(gpio, true); - self.set_center(channel, false); - }, - Align::Center => { - Pin2::set_invert(gpio, false); - self.set_center(channel, true); - }, - Align::Right => { - Pin2::set_invert(gpio, false); - self.set_center(channel, false); - } - } - }, - Channel::_3 => { - Pin3::init(gpio, PinConfig::IoFn1); - match align { - Align::Left => { - Pin3::set_invert(gpio, true); - self.set_center(channel, false); - }, - Align::Center => { - Pin3::set_invert(gpio, false); - self.set_center(channel, true); - }, - Align::Right => { - Pin3::set_invert(gpio, false); - self.set_center(channel, false); - } - } - }, - } - } else if self.0.get_type_id() == TypeId::of::() { - match channel { - Channel::_0 => { - Pin20::init(gpio, PinConfig::IoFn1); - match align { - Align::Left => { - Pin20::set_invert(gpio, true); - self.set_center(channel, false); - }, - Align::Center => { - Pin20::set_invert(gpio, false); - self.set_center(channel, true); - }, - Align::Right => { - Pin20::set_invert(gpio, false); - self.set_center(channel, false); - } - } - }, - Channel::_1 => { - Pin19::init(gpio, PinConfig::IoFn1); - match align { - Align::Left => { - Pin19::set_invert(gpio, true); - self.set_center(channel, false); - }, - Align::Center => { - Pin19::set_invert(gpio, false); - self.set_center(channel, true); - }, - Align::Right => { - Pin19::set_invert(gpio, false); - self.set_center(channel, false); - } - } - }, - Channel::_2 => { - Pin21::init(gpio, PinConfig::IoFn1); - match align { - Align::Left => { - Pin21::set_invert(gpio, true); - self.set_center(channel, false); - }, - Align::Center => { - Pin21::set_invert(gpio, false); - self.set_center(channel, true); - }, - Align::Right => { - Pin21::set_invert(gpio, false); - self.set_center(channel, false); - } - } - }, - Channel::_3 => { - Pin22::init(gpio, PinConfig::IoFn1); - match align { - Align::Left => { - Pin22::set_invert(gpio, true); - self.set_center(channel, false); - }, - Align::Center => { - Pin22::set_invert(gpio, false); - self.set_center(channel, true); - }, - Align::Right => { - Pin22::set_invert(gpio, false); - self.set_center(channel, false); - } - } - }, - } - } else if self.0.get_type_id() == TypeId::of::() { - match channel { - Channel::_0 => { - Pin10::init(gpio, PinConfig::IoFn1); - match align { - Align::Left => { - Pin10::set_invert(gpio, true); - self.set_center(channel, false); - }, - Align::Center => { - Pin10::set_invert(gpio, false); - self.set_center(channel, true); - }, - Align::Right => { - Pin10::set_invert(gpio, false); - self.set_center(channel, false); - } - } - }, - Channel::_1 => { - Pin11::init(gpio, PinConfig::IoFn1); - match align { - Align::Left => { - Pin11::set_invert(gpio, true); - self.set_center(channel, false); - }, - Align::Center => { - Pin11::set_invert(gpio, false); - self.set_center(channel, true); - }, - Align::Right => { - Pin11::set_invert(gpio, false); - self.set_center(channel, false); - } - } - }, - Channel::_2 => { - Pin12::init(gpio, PinConfig::IoFn1); - match align { - Align::Left => { - Pin12::set_invert(gpio, true); - self.set_center(channel, false); - }, - Align::Center => { - Pin12::set_invert(gpio, false); - self.set_center(channel, true); - }, - Align::Right => { - Pin12::set_invert(gpio, false); - self.set_center(channel, false); - } - } - }, - Channel::_3 => { - Pin13::init(gpio, PinConfig::IoFn1); - match align { - Align::Left => { - Pin13::set_invert(gpio, true); - self.set_center(channel, false); - }, - Align::Center => { - Pin13::set_invert(gpio, false); - self.set_center(channel, true); - }, - Align::Right => { - Pin13::set_invert(gpio, false); - self.set_center(channel, false); - } - } - }, - } - } - } - - pub fn disable(&self, channel: Channel, gpio: &T::GPIO) { - if self.0.get_type_id() == TypeId::of::() { - match channel { - Channel::_0 => Pin0::init(gpio, PinConfig::Input), - Channel::_1 => Pin1::init(gpio, PinConfig::Input), - Channel::_2 => Pin2::init(gpio, PinConfig::Input), - Channel::_3 => Pin3::init(gpio, PinConfig::Input), - } - } else if self.0.get_type_id() == TypeId::of::() { - match channel { - Channel::_0 => Pin20::init(gpio, PinConfig::Input), - Channel::_1 => Pin19::init(gpio, PinConfig::Input), - Channel::_2 => Pin21::init(gpio, PinConfig::Input), - Channel::_3 => Pin22::init(gpio, PinConfig::Input), - } - } else if self.0.get_type_id() == TypeId::of::() { - match channel { - Channel::_0 => Pin10::init(gpio, PinConfig::Input), - Channel::_1 => Pin11::init(gpio, PinConfig::Input), - Channel::_2 => Pin12::init(gpio, PinConfig::Input), - Channel::_3 => Pin13::init(gpio, PinConfig::Input), - } - } - } - - pub fn invert(&self, channel: Channel, gpio: &T::GPIO) { - if self.0.get_type_id() == TypeId::of::() { - match channel { - Channel::_0 => Pin0::invert(gpio), - Channel::_1 => Pin1::invert(gpio), - Channel::_2 => Pin2::invert(gpio), - Channel::_3 => Pin3::invert(gpio), - } - } else if self.0.get_type_id() == TypeId::of::() { - match channel { - Channel::_0 => Pin20::invert(gpio), - Channel::_1 => Pin19::invert(gpio), - Channel::_2 => Pin21::invert(gpio), - Channel::_3 => Pin22::invert(gpio), - } - } else if self.0.get_type_id() == TypeId::of::() { - match channel { - Channel::_0 => Pin10::invert(gpio), - Channel::_1 => Pin11::invert(gpio), - Channel::_2 => Pin12::invert(gpio), - Channel::_3 => Pin13::invert(gpio), - } - } - } - - pub fn set_period

(&self, period: P) - where P: Into<::coreclk::Ticks> - { - let ticks: u32 = period.into().into(); - let scale = u16::max_value() as u32 / ticks; - assert!(scale < 0x10); - ::riscv::asm::ebreak(); - unsafe { - self.0.cfg.modify(|_, w| w.scale().bits(scale as u8)); - } - } - - pub fn get_period(&self) -> ::coreclk::Ticks { - let scale = self.0.cfg.read().scale().bits(); - ::coreclk::Ticks(scale as u32 * u16::max_value() as u32) - } - - pub fn align_left(&self, channel: Channel, gpio: &T::GPIO) { - match channel { - Channel::_0 => { - self.0.cfg.modify(|_, w| w.cmp0center().bit(false)); - self.invert(channel, gpio); - }, - Channel::_1 => { - self.0.cfg.modify(|_, w| w.cmp1center().bit(false)); - self.invert(channel, gpio); - }, - Channel::_2 => { - self.0.cfg.modify(|_, w| w.cmp2center().bit(false)); - self.invert(channel, gpio); - } - Channel::_3 => { - self.0.cfg.modify(|_, w| w.cmp3center().bit(false)); - self.invert(channel, gpio); - } - } - } - - fn set_center(&self, channel: Channel, value: bool) { - match channel { - Channel::_0 => self.0.cfg.modify(|_, w| w.cmp0center().bit(value)), - Channel::_1 => self.0.cfg.modify(|_, w| w.cmp1center().bit(value)), - Channel::_2 => self.0.cfg.modify(|_, w| w.cmp2center().bit(value)), - Channel::_3 => self.0.cfg.modify(|_, w| w.cmp3center().bit(value)), - } - } - - pub fn get_cmp(&self, channel: Channel) -> u16 { - match channel { - Channel::_0 => self.0.cmp0.read().value().bits(), - Channel::_1 => self.0.cmp1.read().value().bits(), - Channel::_2 => self.0.cmp2.read().value().bits(), - Channel::_3 => self.0.cmp3.read().value().bits(), - } - } - - pub fn set_cmp(&self, channel: Channel, cmp: u16) { - unsafe { - match channel { - Channel::_0 => self.0.cmp0.write(|w| w.value().bits(cmp)), - Channel::_1 => self.0.cmp1.write(|w| w.value().bits(cmp)), - Channel::_2 => self.0.cmp2.write(|w| w.value().bits(cmp)), - Channel::_3 => self.0.cmp3.write(|w| w.value().bits(cmp)), - } - } - } -} - -/* -/// `hal::Pwm` implementation -impl<'a, T> hal::Pwm for Pwm<'a, T> - where - T: Any + PWM, -{ - type Channel = Channel; - type Duty = u16; - type Time = ::coreclk::Ticks; - - fn get_duty(&self, channel: Channel) -> u16 { - self.get_cmp(channel) - } - - fn disable(&self, channel: Channel) { - - } - - fn enable(&self, channel: Channel) { - - } - - fn get_max_duty(&self) -> u16 { - u16::max_value() - } - - fn get_period(&self) -> ::coreclk::Ticks { - self.get_period() - } - - fn set_duty(&self, channel: Channel, duty: u16) { - self.set_cmp(channel, duty); - } - - fn set_period

(&self, period: P) - where - P: Into<::coreclk::Ticks>, - { - self.set_period(period.into()); - } -} - -#[allow(unused_variables)] -/// `hal::Timer` implementation -impl<'a, T> hal::Timer for Pwm<'a, T> - where - T: Any + PWM -{ - type Time = ::coreclk::Ticks; - - fn get_timeout(&self) -> ::coreclk::Ticks { - ::coreclk::Ticks(10) - } - - fn pause(&self) { - - } - - fn restart(&self) { - - } - - fn resume(&self) { - - } - - fn set_timeout(&self, timeout: TO) - where - TO: Into<::coreclk::Ticks>, - { - - } - - fn wait(&self) -> nb::Result<(), !> { - Ok(()) - } -} -*/ diff --git a/src/rtc.rs b/src/rtc.rs deleted file mode 100644 index cc8b41d..0000000 --- a/src/rtc.rs +++ /dev/null @@ -1,111 +0,0 @@ -//! RTC -use e310x::RTC; - -/// Rtc configuration -pub struct RtcConf { - enalways: bool, - scale: u8, - counter: u64, - cmp: u32, -} - -impl RtcConf { - pub fn new() -> Self { - Self { - enalways: true, - scale: 0, - counter: 0, - cmp: 0, - } - } - - pub fn set_enalways(&mut self, en: bool) -> &mut Self { - self.enalways = en; - self - } - - pub fn set_scale(&mut self, scale: u8) -> &mut Self { - assert!(scale < 16); - self.scale = scale; - self - } - - pub fn set_counter(&mut self, counter: u64) -> &mut Self { - assert!(counter < (1 << 49) - 1); - self.counter = counter; - self - } - pub fn set_cmp(&mut self, cmp: u32) -> &mut Self { - self.cmp = cmp; - self - } - - pub fn end(&self, rtc: &RTC) { - let rtc = Rtc(rtc); - unsafe { - rtc.0.rtccfg.modify(|_, w| { - w.enalways().bit(self.enalways) - .scale().bits(self.scale) - }); - - rtc.0.rtchi.write(|w| w.bits((self.counter >> 32) as u32)); - rtc.0.rtclo.write(|w| w.bits(self.counter as u32)); - rtc.0.rtccmp.write(|w| w.bits(self.cmp)); - } - } -} - - -/// Rtc interface -pub struct Rtc<'a>(pub &'a RTC); - -impl<'a> Clone for Rtc<'a> { - fn clone(&self) -> Self { - *self - } -} - -impl<'a> Copy for Rtc<'a> {} - -impl<'a> ::hal::Timer for Rtc<'a> { - type Time = ::aonclk::Ticks; - - fn get_timeout(&self) -> ::aonclk::Ticks { - ::aonclk::Ticks(self.0.rtccmp.read().bits()) - } - - fn pause(&self) { - self.0.rtccfg.modify(|_, w| w.enalways().bit(false)); - } - - fn restart(&self) { - unsafe { - self.0.rtchi.write(|w| w.bits(0)); - self.0.rtclo.write(|w| w.bits(0)); - } - self.0.rtccfg.modify(|_, w| w.enalways().bit(true)); - } - - fn resume(&self) { - self.0.rtccfg.modify(|_, w| w.enalways().bit(true)); - } - - fn set_timeout(&self, timeout: T) - where - T: Into<::aonclk::Ticks>, - { - self.pause(); - unsafe { - self.0.rtccmp.write(|w| w.bits(timeout.into().into())); - } - self.restart(); - } - - fn wait(&self) -> ::nb::Result<(), !> { - if self.0.rtccfg.read().cmpip().bit() { - Ok(()) - } else { - Err(::nb::Error::WouldBlock) - } - } -} diff --git a/src/serial.rs b/src/serial.rs deleted file mode 100644 index 0008043..0000000 --- a/src/serial.rs +++ /dev/null @@ -1,151 +0,0 @@ -//! Serial interface -//! -//! You can use the `Serial` interface with these UART instances -//! -//! # UART0 -//! - TX: Pin 17 IOF0 -//! - RX: Pin 16 IOF0 -//! - Interrupt::UART0 -//! -//! # UART1 -//! - TX: Pin 25 IOF0 -//! - RX: Pin 24 IOF0 -//! - Interrupt::UART1 - - -use core::any::{Any, TypeId}; -use core::ops::Deref; -use e310x::{gpio0, GPIO0, uart0, UART0, UART1}; -use gpio::{PinConfig, Pin17, Pin16, Pin25, Pin24}; - -/// IMPLEMENTATION DETAIL -pub unsafe trait Uart: Deref { - /// IMPLEMENTATION DETAIL - type GPIO: Deref; - type Ticks: Into; -} - -unsafe impl Uart for UART0 { - type GPIO = GPIO0; - type Ticks = ::coreclk::Ticks; -} - -unsafe impl Uart for UART1 { - type GPIO = GPIO0; - type Ticks = ::coreclk::Ticks; -} - -/// Serial interface -pub struct Serial<'a, U>(pub &'a U) -where - U: Any + Uart; - -impl<'a, U> Clone for Serial<'a, U> -where - U: Any + Uart, -{ - fn clone(&self) -> Self { - *self - } -} - -impl<'a, U> Copy for Serial<'a, U> -where - U: Any + Uart, -{ -} - -impl<'a, U> Serial<'a, U> -where - U: Any + Uart, -{ - /// Initializes the serial interface with a baud rate of `baud_rate` bits - /// per second - pub fn init(&self, baud_rate: B, gpio: &U::GPIO) - where B: Into, - { - if self.0.get_type_id() == TypeId::of::() { - Pin16::init(gpio, PinConfig::IoFn0); - Pin17::init(gpio, PinConfig::IoFn0); - } else if self.0.get_type_id() == TypeId::of::() { - Pin24::init(gpio, PinConfig::IoFn0); - Pin25::init(gpio, PinConfig::IoFn0); - } - - unsafe { - let div = baud_rate.into().into(); - self.0.div.write(|w| w.bits(div)); - - self.0.txctrl.write(|w| w.enable().bit(true)); - self.0.rxctrl.write(|w| w.enable().bit(true)); - } - } -} - -impl<'a, U> ::hal::serial::Read for Serial<'a, U> -where - U: Any + Uart, -{ - type Error = !; - - fn read(&self) -> ::nb::Result { - let uart = self.0; - let rxdata = uart.rxdata.read(); - - if rxdata.empty().bit_is_set() { - Err(::nb::Error::WouldBlock) - } else { - Ok(rxdata.data().bits() as u8) - } - } -} - -impl<'a, U> ::hal::serial::Write for Serial<'a, U> -where - U: Any + Uart, -{ - type Error = !; - - fn write(&self, byte: u8) -> ::nb::Result<(), !> { - let uart = self.0; - let txdata = uart.txdata.read(); - - if txdata.full().bit_is_set() { - Err(::nb::Error::WouldBlock) - } else { - unsafe { - uart.txdata.write(|w| w.data().bits(byte)); - } - Ok(()) - } - } -} - -/// Port -pub struct Port<'p, T>(pub &'p T) - where - T: 'p; - -impl<'p, T> ::core::fmt::Write for Port<'p, T> - where - T: ::hal::serial::Write, -{ - fn write_str(&mut self, s: &str) -> ::core::fmt::Result { - for byte in s.as_bytes() { - let res = block!(self.0.write(*byte)); - - if res.is_err() { - return Err(::core::fmt::Error); - } - - if *byte == '\n' as u8 { - let res = block!(self.0.write('\r' as u8)); - - if res.is_err() { - return Err(::core::fmt::Error); - } - } - } - Ok(()) - } -} diff --git a/src/time.rs b/src/time.rs deleted file mode 100644 index ed86a9f..0000000 --- a/src/time.rs +++ /dev/null @@ -1,110 +0,0 @@ -//! Units of time - -macro_rules! map { - ($Self:ident) => { - impl $Self { - /// Applies the function `f` to inner value - pub fn map(self, f: F) -> $Self - where - F: FnOnce(T) -> T - { - $Self(f(self.0)) - } - } - } -} - -/// `Hz^-1` -#[derive(Clone, Copy, Debug)] -pub struct IHertz(pub T); - -impl IHertz { - /// Invert this quantity - pub fn invert(self) -> Hertz { - Hertz(self.0) - } -} - -map!(IHertz); - -/// `Hz` -#[derive(Clone, Copy, Debug)] -pub struct Hertz(pub T); - -impl Hertz { - /// Invert this quantity - pub fn invert(self) -> IHertz { - IHertz(self.0) - } -} - -map!(Hertz); - -/// `us` -#[derive(Clone, Copy, Debug)] -pub struct Microseconds(pub T); - -map!(Microseconds); - -/// `ms` -#[derive(Clone, Copy, Debug)] -pub struct Milliseconds(pub T); - -map!(Milliseconds); - -/// `s` -#[derive(Clone, Copy, Debug)] -pub struct Seconds(pub T); - -map!(Seconds); - -/// `u32` and `u64` extension trait -pub trait UExt { - /// Wrap in `Hz` - fn hz(self) -> Hertz; - - /// Wrap in `Milliseconds` - fn ms(self) -> Milliseconds; - - /// Wrap in `Seconds` - fn s(self) -> Seconds; - - /// Wrap in `Microseconds` - fn us(self) -> Microseconds; -} - -impl UExt for u32 { - fn hz(self) -> Hertz { - Hertz(self) - } - - fn ms(self) -> Milliseconds { - Milliseconds(self) - } - - fn s(self) -> Seconds { - Seconds(self) - } - - fn us(self) -> Microseconds { - Microseconds(self) - } -} - -impl UExt for u64 { - fn hz(self) -> Hertz { - Hertz(self) - } - - fn ms(self) -> Milliseconds { - Milliseconds(self) - } - - fn s(self) -> Seconds { - Seconds(self) - } - - fn us(self) -> Microseconds { - Microseconds(self) - } -} From f6528c31a4d30bc6f1dffffa9c735c36253d38a7 Mon Sep 17 00:00:00 2001 From: David Craven Date: Wed, 28 Mar 2018 17:55:16 +0200 Subject: [PATCH 023/112] Define TX, RX, TxPin, RxPin types. --- src/lib.rs | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 1f1b543..230902a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -6,8 +6,8 @@ pub extern crate e310x_hal as hal; -pub use serial::{TX, RX, tx_rx}; -pub use led::{RED, GREEN, BLUE, rgb}; +pub use serial::{TX, RX, TxPin, RxPin, tx_rx}; +pub use led::{RED, GREEN, BLUE, rgb, Led}; pub mod serial { //! Single UART hooked up to FTDI @@ -16,21 +16,27 @@ pub mod serial { //! - Rx = Pin 16 use hal::gpio::gpio0::{Pin16, Pin17, OUT_XOR, IOF_SEL, IOF_EN}; use hal::gpio::{IOF0, NoInvert}; + use hal::serial::{Tx, Rx}; + use hal::e310x::UART0; /// UART0 TX Pin - pub type TX = Pin17>; + pub type TxPin = Pin17>; /// UART0 RX Pin - pub type RX = Pin16>; + pub type RxPin = Pin16>; + /// UART0 TX + pub type TX = Tx; + /// UART0 RX + pub type RX = Rx; /// Return TX, RX pins. pub fn tx_rx( tx: Pin17, rx: Pin16, out_xor: &mut OUT_XOR, iof_sel: &mut IOF_SEL, iof_en: &mut IOF_EN - ) -> (TX, RX) + ) -> (TxPin, RxPin) { - let tx: TX = tx.into_iof0(out_xor, iof_sel, iof_en); - let rx: RX = rx.into_iof0(out_xor, iof_sel, iof_en); + let tx: TxPin = tx.into_iof0(out_xor, iof_sel, iof_en); + let rx: RxPin = rx.into_iof0(out_xor, iof_sel, iof_en); (tx, rx) } } From d74f25b75b9e7d539d3e56e04a228ad8e1a9c4c2 Mon Sep 17 00:00:00 2001 From: David Craven Date: Sat, 11 Aug 2018 17:58:32 +0200 Subject: [PATCH 024/112] A unified contributing experience. --- .github/CODEOWNERS | 1 + .github/bors.toml | 4 ++++ .travis.yml | 50 ++++++++++++++++++++++++++++++++++++++++++++++ CODE_OF_CONDUCT.md | 37 ++++++++++++++++++++++++++++++++++ ci/install.sh | 9 +++++++++ ci/script.sh | 7 +++++++ 6 files changed, 108 insertions(+) create mode 100644 .github/CODEOWNERS create mode 100644 .github/bors.toml create mode 100644 .travis.yml create mode 100644 CODE_OF_CONDUCT.md create mode 100644 ci/install.sh create mode 100644 ci/script.sh diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..87f6c03 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1 @@ +* @rust-embedded/riscv \ No newline at end of file diff --git a/.github/bors.toml b/.github/bors.toml new file mode 100644 index 0000000..ca42be0 --- /dev/null +++ b/.github/bors.toml @@ -0,0 +1,4 @@ +block_labels = ["needs-decision"] +delete_merged_branches = true +required_approvals = 1 +status = ["continuous-integration/travis-ci/push"] diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..a3c9cf2 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,50 @@ +language: rust + +matrix: + include: + #- env: TARGET=x86_64-unknown-linux-gnu + # if: (branch = staging OR branch = trying OR branch = master) OR (type = pull_request AND branch = master) + + #- env: TARGET=riscv32imac-unknown-none-elf + # if: (branch = staging OR branch = trying OR branch = master) OR (type = pull_request AND branch = master) + + #- env: TARGET=x86_64-unknown-linux-gnu + # rust: beta + # if: (branch = staging OR branch = trying OR branch = master) OR (type = pull_request AND branch = master) + + #- env: TARGET=riscv32imac-unknown-none-elf + # rust: beta + # if: (branch = staging OR branch = trying OR branch = master) OR (type = pull_request AND branch = master) + + - env: TARGET=x86_64-unknown-linux-gnu + rust: nightly + if: (branch = staging OR branch = trying OR branch = master) OR (type = pull_request AND branch = master) + + - env: TARGET=riscv32imac-unknown-none-elf + rust: nightly + if: (branch = staging OR branch = trying OR branch = master) OR (type = pull_request AND branch = master) + +before_install: set -e + +install: + - bash ci/install.sh + +script: + - bash ci/script.sh + +after_script: set +e + +cache: cargo +before_cache: + # Travis can't cache files that are not readable by "others" + - chmod -R a+r $HOME/.cargo + +branches: + only: + - master + - staging + - trying + +notifications: + email: + on_success: never diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..a22c4f6 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,37 @@ +# The Rust Code of Conduct + +## Conduct + +**Contact**: [RISCV team](https://github.com/rust-embedded/wg#the-riscv-team) + +* We are committed to providing a friendly, safe and welcoming environment for all, regardless of level of experience, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, religion, nationality, or other similar characteristic. +* On IRC, please avoid using overtly sexual nicknames or other nicknames that might detract from a friendly, safe and welcoming environment for all. +* Please be kind and courteous. There's no need to be mean or rude. +* Respect that people have differences of opinion and that every design or implementation choice carries a trade-off and numerous costs. There is seldom a right answer. +* Please keep unstructured critique to a minimum. If you have solid ideas you want to experiment with, make a fork and see how it works. +* We will exclude you from interaction if you insult, demean or harass anyone. That is not welcome behavior. We interpret the term "harassment" as including the definition in the [Citizen Code of Conduct](http://citizencodeofconduct.org/); if you have any lack of clarity about what might be included in that concept, please read their definition. In particular, we don't tolerate behavior that excludes people in socially marginalized groups. +* Private harassment is also unacceptable. No matter who you are, if you feel you have been or are being harassed or made uncomfortable by a community member, please contact one of the channel ops or any of the [RISCV team][team] immediately. Whether you're a regular contributor or a newcomer, we care about making this community a safe place for you and we've got your back. +* Likewise any spamming, trolling, flaming, baiting or other attention-stealing behavior is not welcome. + +## Moderation + +These are the policies for upholding our community's standards of conduct. + +1. Remarks that violate the Rust standards of conduct, including hateful, hurtful, oppressive, or exclusionary remarks, are not allowed. (Cursing is allowed, but never targeting another user, and never in a hateful manner.) +2. Remarks that moderators find inappropriate, whether listed in the code of conduct or not, are also not allowed. +3. Moderators will first respond to such remarks with a warning. +4. If the warning is unheeded, the user will be "kicked," i.e., kicked out of the communication channel to cool off. +5. If the user comes back and continues to make trouble, they will be banned, i.e., indefinitely excluded. +6. Moderators may choose at their discretion to un-ban the user if it was a first offense and they offer the offended party a genuine apology. +7. If a moderator bans someone and you think it was unjustified, please take it up with that moderator, or with a different moderator, **in private**. Complaints about bans in-channel are not allowed. +8. Moderators are held to a higher standard than other community members. If a moderator creates an inappropriate situation, they should expect less leeway than others. + +In the Rust community we strive to go the extra step to look out for each other. Don't just aim to be technically unimpeachable, try to be your best self. In particular, avoid flirting with offensive or sensitive issues, particularly if they're off-topic; this all too often leads to unnecessary fights, hurt feelings, and damaged trust; worse, it can drive people away from the community entirely. + +And if someone takes issue with something you said or did, resist the urge to be defensive. Just stop doing what it was they complained about and apologize. Even if you feel you were misinterpreted or unfairly accused, chances are good there was something you could've communicated better — remember that it's your responsibility to make your fellow Rustaceans comfortable. Everyone wants to get along and we are all here first and foremost because we want to talk about cool technology. You will find that people will be eager to assume good intent and forgive as long as you earn their trust. + +The enforcement policies listed above apply to all official embedded WG venues; including official IRC channels (#rust-embedded); GitHub repositories under rust-embedded; and all forums under rust-embedded.org (forum.rust-embedded.org). + +*Adapted from the [Node.js Policy on Trolling](http://blog.izs.me/post/30036893703/policy-on-trolling) as well as the [Contributor Covenant v1.3.0](https://www.contributor-covenant.org/version/1/3/0/).* + +[team]: https://github.com/rust-embedded/wg#the-riscv-team diff --git a/ci/install.sh b/ci/install.sh new file mode 100644 index 0000000..3c41921 --- /dev/null +++ b/ci/install.sh @@ -0,0 +1,9 @@ +set -euxo pipefail + +main() { + if [ $TARGET != x86_64-unknown-linux-gnu ]; then + rustup target add $TARGET + fi +} + +main diff --git a/ci/script.sh b/ci/script.sh new file mode 100644 index 0000000..9e10e88 --- /dev/null +++ b/ci/script.sh @@ -0,0 +1,7 @@ +set -euxo pipefail + +main() { + cargo check --target $TARGET +} + +main From 84b30b9e47579840ba76d50143405ab9e6ba76c5 Mon Sep 17 00:00:00 2001 From: David Craven Date: Sun, 12 Aug 2018 10:58:03 +0200 Subject: [PATCH 025/112] Bump version. Update url and deps. --- Cargo.toml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index c4b3a34..7beb076 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "hifive" -version = "0.1.0" -repository = "https://github.com/dvc94ch/hifive" +version = "0.2.0" +repository = "https://github.com/riscv-rust/hifive" authors = ["David Craven "] categories = ["embedded", "hardware-support", "no-std"] description = "Board support crate for hifive and lofive boards." @@ -9,6 +9,6 @@ keywords = ["riscv", "register", "peripheral"] license = "ISC" [dependencies] -riscv = { path = "../riscv" } -riscv-rt = { path = "../riscv-rt" } -e310x-hal = { path = "../e310x-hal", features = ["pll", "hfxosc", "lfaltclk"] } +riscv = "0.3.0" +riscv-rt = "0.3.0" +e310x-hal = { version = "0.2.0", features = ["pll", "hfxosc", "lfaltclk"] } From 0b447ecf51c8f055bae47bf2c8bb4a37d0313560 Mon Sep 17 00:00:00 2001 From: David Craven Date: Sun, 12 Aug 2018 10:59:08 +0200 Subject: [PATCH 026/112] Update README. --- README.md | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 6d5dfb2..ea95c3e 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ [![crates.io](https://img.shields.io/crates/d/hifive.svg)](https://crates.io/crates/hifive) [![crates.io](https://img.shields.io/crates/v/hifive.svg)](https://crates.io/crates/hifive) +[![Build Status](https://travis-ci.org/riscv-rust/hifive.svg?branch=master)](https://travis-ci.org/riscv-rust/hifive) # `hifive` @@ -8,7 +9,8 @@ ## [Documentation](https://docs.rs/crate/hifive) ## License -Copyright 2017 David Craven + +Copyright 2018 [RISCV team][team] Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice @@ -21,3 +23,12 @@ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +## Code of Conduct + +Contribution to this crate is organized under the terms of the [Rust Code of +Conduct][CoC], the maintainer of this crate, the [RISCV team][team], promises +to intervene to uphold that code of conduct. + +[CoC]: CODE_OF_CONDUCT.md +[team]: https://github.com/rust-embedded/wg#the-riscv-team From 528d89b05f652b00eb7ae7f3a60413af1911be76 Mon Sep 17 00:00:00 2001 From: Vadim Kaushan Date: Sun, 24 Feb 2019 22:45:22 +0300 Subject: [PATCH 027/112] Update dependencies --- Cargo.toml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 7beb076..afdfcc5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,6 +9,6 @@ keywords = ["riscv", "register", "peripheral"] license = "ISC" [dependencies] -riscv = "0.3.0" -riscv-rt = "0.3.0" -e310x-hal = { version = "0.2.0", features = ["pll", "hfxosc", "lfaltclk"] } +riscv = "0.4.0" +riscv-rt = "0.4.0" +e310x-hal = "0.3.0" From 37aee31b15d8ca142d85fb043e4f6c30d82caec2 Mon Sep 17 00:00:00 2001 From: Vadim Kaushan Date: Thu, 28 Feb 2019 20:20:58 +0300 Subject: [PATCH 028/112] Move led and serial modules to separate files --- src/led.rs | 85 +++++++++++++++++++++++++++++++++++ src/lib.rs | 121 +------------------------------------------------- src/serial.rs | 29 ++++++++++++ 3 files changed, 116 insertions(+), 119 deletions(-) create mode 100644 src/led.rs create mode 100644 src/serial.rs diff --git a/src/led.rs b/src/led.rs new file mode 100644 index 0000000..e4df1f8 --- /dev/null +++ b/src/led.rs @@ -0,0 +1,85 @@ +//! On-board user LEDs +//! +//! - Red = Pin 22 +//! - Green = Pin 19 +//! - Blue = Pin 21 +use hal::prelude::*; +use hal::gpio::gpio0::{Pin19, Pin21, Pin22, OUTPUT_EN, DRIVE, + OUT_XOR, IOF_EN}; +use hal::gpio::{Output, Regular, Invert}; + +/// Red LED +pub type RED = Pin22>>; + +/// Green LED +pub type GREEN = Pin19>>; + +/// Blue LED +pub type BLUE = Pin21>>; + +/// Returns RED, GREEN and BLUE LEDs. +pub fn rgb( + red: Pin22, green: Pin19, blue: Pin21, + output_en: &mut OUTPUT_EN, drive: &mut DRIVE, + out_xor: &mut OUT_XOR, iof_en: &mut IOF_EN +) -> (RED, GREEN, BLUE) +{ + let red: RED = red.into_inverted_output( + output_en, + drive, + out_xor, + iof_en, + ); + let green: GREEN = green.into_inverted_output( + output_en, + drive, + out_xor, + iof_en, + ); + let blue: BLUE = blue.into_inverted_output( + output_en, + drive, + out_xor, + iof_en, + ); + (red, green, blue) +} + +/// Generic LED +pub trait Led { + /// Turns the LED off + fn off(&mut self); + + /// Turns the LED on + fn on(&mut self); +} + +impl Led for RED { + fn on(&mut self) { + _embedded_hal_digital_OutputPin::set_high(self); + } + + fn off(&mut self) { + _embedded_hal_digital_OutputPin::set_low(self); + } +} + +impl Led for GREEN { + fn on(&mut self) { + _embedded_hal_digital_OutputPin::set_high(self); + } + + fn off(&mut self) { + _embedded_hal_digital_OutputPin::set_low(self); + } +} + +impl Led for BLUE { + fn on(&mut self) { + _embedded_hal_digital_OutputPin::set_high(self); + } + + fn off(&mut self) { + _embedded_hal_digital_OutputPin::set_low(self); + } +} diff --git a/src/lib.rs b/src/lib.rs index 230902a..88e2aca 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -9,122 +9,5 @@ pub extern crate e310x_hal as hal; pub use serial::{TX, RX, TxPin, RxPin, tx_rx}; pub use led::{RED, GREEN, BLUE, rgb, Led}; -pub mod serial { - //! Single UART hooked up to FTDI - //! - //! - Tx = Pin 17 - //! - Rx = Pin 16 - use hal::gpio::gpio0::{Pin16, Pin17, OUT_XOR, IOF_SEL, IOF_EN}; - use hal::gpio::{IOF0, NoInvert}; - use hal::serial::{Tx, Rx}; - use hal::e310x::UART0; - - /// UART0 TX Pin - pub type TxPin = Pin17>; - /// UART0 RX Pin - pub type RxPin = Pin16>; - /// UART0 TX - pub type TX = Tx; - /// UART0 RX - pub type RX = Rx; - - /// Return TX, RX pins. - pub fn tx_rx( - tx: Pin17, rx: Pin16, - out_xor: &mut OUT_XOR, iof_sel: &mut IOF_SEL, - iof_en: &mut IOF_EN - ) -> (TxPin, RxPin) - { - let tx: TxPin = tx.into_iof0(out_xor, iof_sel, iof_en); - let rx: RxPin = rx.into_iof0(out_xor, iof_sel, iof_en); - (tx, rx) - } -} - -pub mod led { - //! On-board user LEDs - //! - //! - Red = Pin 22 - //! - Green = Pin 19 - //! - Blue = Pin 21 - use hal::prelude::*; - use hal::gpio::gpio0::{Pin19, Pin21, Pin22, OUTPUT_EN, DRIVE, - OUT_XOR, IOF_EN}; - use hal::gpio::{Output, Regular, Invert}; - - /// Red LED - pub type RED = Pin22>>; - - /// Green LED - pub type GREEN = Pin19>>; - - /// Blue LED - pub type BLUE = Pin21>>; - - /// Returns RED, GREEN and BLUE LEDs. - pub fn rgb( - red: Pin22, green: Pin19, blue: Pin21, - output_en: &mut OUTPUT_EN, drive: &mut DRIVE, - out_xor: &mut OUT_XOR, iof_en: &mut IOF_EN - ) -> (RED, GREEN, BLUE) - { - let red: RED = red.into_inverted_output( - output_en, - drive, - out_xor, - iof_en, - ); - let green: GREEN = green.into_inverted_output( - output_en, - drive, - out_xor, - iof_en, - ); - let blue: BLUE = blue.into_inverted_output( - output_en, - drive, - out_xor, - iof_en, - ); - (red, green, blue) - } - - /// Generic LED - pub trait Led { - /// Turns the LED off - fn off(&mut self); - - /// Turns the LED on - fn on(&mut self); - } - - impl Led for RED { - fn on(&mut self) { - _embedded_hal_digital_OutputPin::set_high(self); - } - - fn off(&mut self) { - _embedded_hal_digital_OutputPin::set_low(self); - } - } - - impl Led for GREEN { - fn on(&mut self) { - _embedded_hal_digital_OutputPin::set_high(self); - } - - fn off(&mut self) { - _embedded_hal_digital_OutputPin::set_low(self); - } - } - - impl Led for BLUE { - fn on(&mut self) { - _embedded_hal_digital_OutputPin::set_high(self); - } - - fn off(&mut self) { - _embedded_hal_digital_OutputPin::set_low(self); - } - } -} +pub mod serial; +pub mod led; diff --git a/src/serial.rs b/src/serial.rs new file mode 100644 index 0000000..cd2aca2 --- /dev/null +++ b/src/serial.rs @@ -0,0 +1,29 @@ +//! Single UART hooked up to FTDI +//! +//! - Tx = Pin 17 +//! - Rx = Pin 16 +use hal::gpio::gpio0::{Pin16, Pin17, OUT_XOR, IOF_SEL, IOF_EN}; +use hal::gpio::{IOF0, NoInvert}; +use hal::serial::{Tx, Rx}; +use hal::e310x::UART0; + +/// UART0 TX Pin +pub type TxPin = Pin17>; +/// UART0 RX Pin +pub type RxPin = Pin16>; +/// UART0 TX +pub type TX = Tx; +/// UART0 RX +pub type RX = Rx; + +/// Return TX, RX pins. +pub fn tx_rx( + tx: Pin17, rx: Pin16, + out_xor: &mut OUT_XOR, iof_sel: &mut IOF_SEL, + iof_en: &mut IOF_EN +) -> (TxPin, RxPin) +{ + let tx: TxPin = tx.into_iof0(out_xor, iof_sel, iof_en); + let rx: RxPin = rx.into_iof0(out_xor, iof_sel, iof_en); + (tx, rx) +} From 7d207bf5201bd51128ed3805771b2c15bd3abfd2 Mon Sep 17 00:00:00 2001 From: Vadim Kaushan Date: Thu, 28 Feb 2019 21:08:00 +0300 Subject: [PATCH 029/112] Board-specific clock configuration --- Cargo.toml | 7 +++++++ src/clock.rs | 37 +++++++++++++++++++++++++++++++++++++ src/lib.rs | 1 + 3 files changed, 45 insertions(+) create mode 100644 src/clock.rs diff --git a/Cargo.toml b/Cargo.toml index afdfcc5..ba4b344 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,3 +12,10 @@ license = "ISC" riscv = "0.4.0" riscv-rt = "0.4.0" e310x-hal = "0.3.0" + +[features] +board-hifive1 = [] +board-lofive = [] + +[package.metadata.docs.rs] +features = ['board-hifive1'] diff --git a/src/clock.rs b/src/clock.rs new file mode 100644 index 0000000..027f397 --- /dev/null +++ b/src/clock.rs @@ -0,0 +1,37 @@ +//! Board-specific clock configuration + +#[cfg(any(feature = "board-hifive1", feature = "board-lofive"))] +use hal::{ + e310x::{PRCI, AONCLK}, + clock::{Clocks, PrciExt, AonExt}, + time::Hertz, +}; + +#[cfg(feature = "board-hifive1")] +/// Configures clock generation system. +/// +/// For HiFive1 board external oscillators are enabled for both high-frequency and low-frequency clocks. +pub fn configure(prci: PRCI, aonclk: AONCLK, target_coreclk: Hertz) -> Clocks { + let coreclk = prci.constrain(); + let coreclk = coreclk.use_external(Hertz(16_000_000)).coreclk(target_coreclk); + + let aonclk = aonclk.constrain(); + let aonclk = aonclk.use_external(Hertz(32_768)); + + Clocks::freeze(coreclk, aonclk) +} + +#[cfg(feature = "board-lofive")] +/// Configures clock generation system. +/// +/// For LoFive board external oscillator is enabled for high-frequency clock. +/// For low-frequency clock internal oscillator is used. +pub fn configure(prci: PRCI, aonclk: AONCLK, target_coreclk: Hertz) -> Clocks { + let coreclk = prci.constrain(); + let coreclk = coreclk.use_external(Hertz(16_000_000)).coreclk(target_coreclk); + + let aonclk = aonclk.constrain(); + let aonclk = aonclk.use_external(Hertz(32_768)); + + Clocks::freeze(coreclk, aonclk) +} diff --git a/src/lib.rs b/src/lib.rs index 88e2aca..d0a8c15 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -11,3 +11,4 @@ pub use led::{RED, GREEN, BLUE, rgb, Led}; pub mod serial; pub mod led; +pub mod clock; From d114030a8c032468bd5d94c2e83dd8c3e66be7db Mon Sep 17 00:00:00 2001 From: Vadim Kaushan Date: Thu, 28 Feb 2019 21:11:46 +0300 Subject: [PATCH 030/112] Fix board names --- Cargo.toml | 2 +- README.md | 2 +- src/lib.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index ba4b344..8d28fe9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,7 +4,7 @@ version = "0.2.0" repository = "https://github.com/riscv-rust/hifive" authors = ["David Craven "] categories = ["embedded", "hardware-support", "no-std"] -description = "Board support crate for hifive and lofive boards." +description = "Board support crate for HiFive1 and LoFive boards" keywords = ["riscv", "register", "peripheral"] license = "ISC" diff --git a/README.md b/README.md index ea95c3e..d5e3b0f 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ # `hifive` -> Board support crate for hifive and lofive boards. +> Board support crate for HiFive1 and LoFive boards ## [Documentation](https://docs.rs/crate/hifive) diff --git a/src/lib.rs b/src/lib.rs index d0a8c15..3774644 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,4 @@ -//! Board support crate for the Hifive +//! Board support crate for HiFive1 and LoFive boards #![deny(missing_docs)] #![deny(warnings)] From 7081be1d6c415f90c7118539f2992c2125effb71 Mon Sep 17 00:00:00 2001 From: Vadim Kaushan Date: Thu, 28 Feb 2019 21:35:21 +0300 Subject: [PATCH 031/112] Feature-gate led module --- src/lib.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index 3774644..bff1628 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -7,8 +7,10 @@ pub extern crate e310x_hal as hal; pub use serial::{TX, RX, TxPin, RxPin, tx_rx}; +#[cfg(feature = "board-hifive1")] pub use led::{RED, GREEN, BLUE, rgb, Led}; pub mod serial; +#[cfg(feature = "board-hifive1")] pub mod led; pub mod clock; From a3522e880ee59586b500fb2d8b016163a5ae4c42 Mon Sep 17 00:00:00 2001 From: Vadim Kaushan Date: Thu, 28 Feb 2019 21:52:41 +0300 Subject: [PATCH 032/112] Tidy code --- src/led.rs | 16 ++++++++-------- src/lib.rs | 10 +++++----- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/led.rs b/src/led.rs index e4df1f8..1f321e1 100644 --- a/src/led.rs +++ b/src/led.rs @@ -55,31 +55,31 @@ pub trait Led { } impl Led for RED { - fn on(&mut self) { - _embedded_hal_digital_OutputPin::set_high(self); - } - fn off(&mut self) { _embedded_hal_digital_OutputPin::set_low(self); } -} -impl Led for GREEN { fn on(&mut self) { _embedded_hal_digital_OutputPin::set_high(self); } +} +impl Led for GREEN { fn off(&mut self) { _embedded_hal_digital_OutputPin::set_low(self); } -} -impl Led for BLUE { fn on(&mut self) { _embedded_hal_digital_OutputPin::set_high(self); } +} +impl Led for BLUE { fn off(&mut self) { _embedded_hal_digital_OutputPin::set_low(self); } + + fn on(&mut self) { + _embedded_hal_digital_OutputPin::set_high(self); + } } diff --git a/src/lib.rs b/src/lib.rs index bff1628..6850839 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -6,11 +6,11 @@ pub extern crate e310x_hal as hal; -pub use serial::{TX, RX, TxPin, RxPin, tx_rx}; +pub mod clock; #[cfg(feature = "board-hifive1")] -pub use led::{RED, GREEN, BLUE, rgb, Led}; - +pub mod led; pub mod serial; + #[cfg(feature = "board-hifive1")] -pub mod led; -pub mod clock; +pub use led::{RED, GREEN, BLUE, rgb, Led}; +pub use serial::{TX, RX, TxPin, RxPin, tx_rx}; From 478c21d4b58d56e3d852e1529a3602cb5e59cfe7 Mon Sep 17 00:00:00 2001 From: Vadim Kaushan Date: Thu, 28 Feb 2019 22:11:19 +0300 Subject: [PATCH 033/112] CI: build with features enabled --- ci/script.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ci/script.sh b/ci/script.sh index 9e10e88..bbb89ce 100644 --- a/ci/script.sh +++ b/ci/script.sh @@ -2,6 +2,8 @@ set -euxo pipefail main() { cargo check --target $TARGET + cargo check --target $TARGET --features 'board-hifive1' + cargo check --target $TARGET --features 'board-lofive' } main From e19b6e7a24ab18996e4b5cb0ace67de23a6243af Mon Sep 17 00:00:00 2001 From: Vadim Kaushan Date: Thu, 28 Feb 2019 22:11:54 +0300 Subject: [PATCH 034/112] Check build on stable --- .travis.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.travis.yml b/.travis.yml index a3c9cf2..d870f85 100644 --- a/.travis.yml +++ b/.travis.yml @@ -24,6 +24,14 @@ matrix: rust: nightly if: (branch = staging OR branch = trying OR branch = master) OR (type = pull_request AND branch = master) + - env: TARGET=x86_64-unknown-linux-gnu + rust: stable + if: (branch = staging OR branch = trying OR branch = master) OR (type = pull_request AND branch = master) + + - env: TARGET=riscv32imac-unknown-none-elf + rust: stable + if: (branch = staging OR branch = trying OR branch = master) OR (type = pull_request AND branch = master) + before_install: set -e install: From 4f039f981e897b0601a19e4e6e6a15161d10f5a6 Mon Sep 17 00:00:00 2001 From: Vadim Kaushan Date: Thu, 28 Feb 2019 22:19:00 +0300 Subject: [PATCH 035/112] Rename crate to 'hifive1' --- Cargo.toml | 4 ++-- README.md | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 8d28fe9..abca714 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] -name = "hifive" +name = "hifive1" version = "0.2.0" -repository = "https://github.com/riscv-rust/hifive" +repository = "https://github.com/riscv-rust/hifive1" authors = ["David Craven "] categories = ["embedded", "hardware-support", "no-std"] description = "Board support crate for HiFive1 and LoFive boards" diff --git a/README.md b/README.md index d5e3b0f..22456d8 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,12 @@ -[![crates.io](https://img.shields.io/crates/d/hifive.svg)](https://crates.io/crates/hifive) -[![crates.io](https://img.shields.io/crates/v/hifive.svg)](https://crates.io/crates/hifive) -[![Build Status](https://travis-ci.org/riscv-rust/hifive.svg?branch=master)](https://travis-ci.org/riscv-rust/hifive) +[![crates.io](https://img.shields.io/crates/d/hifive1.svg)](https://crates.io/crates/hifive1) +[![crates.io](https://img.shields.io/crates/v/hifive1.svg)](https://crates.io/crates/hifive1) +[![Build Status](https://travis-ci.org/riscv-rust/hifive1.svg?branch=master)](https://travis-ci.org/riscv-rust/hifive1) -# `hifive` +# `hifive1` > Board support crate for HiFive1 and LoFive boards -## [Documentation](https://docs.rs/crate/hifive) +## [Documentation](https://docs.rs/crate/hifive1) ## License From b18173217f97d82161ea00cd2a1d3aef8ffc6ec0 Mon Sep 17 00:00:00 2001 From: Vadim Kaushan Date: Thu, 28 Feb 2019 22:19:30 +0300 Subject: [PATCH 036/112] Bump version --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index abca714..cde1503 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "hifive1" -version = "0.2.0" +version = "0.3.0" repository = "https://github.com/riscv-rust/hifive1" authors = ["David Craven "] categories = ["embedded", "hardware-support", "no-std"] From 28234ea42e016573663ba0adccf43d893e8e245c Mon Sep 17 00:00:00 2001 From: Vadim Kaushan Date: Thu, 14 Mar 2019 16:14:54 +0300 Subject: [PATCH 037/112] Remove unused dependencies --- Cargo.toml | 2 -- 1 file changed, 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index cde1503..4ee1047 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,8 +9,6 @@ keywords = ["riscv", "register", "peripheral"] license = "ISC" [dependencies] -riscv = "0.4.0" -riscv-rt = "0.4.0" e310x-hal = "0.3.0" [features] From dd864a1cbc068f0cc44c17a4c76cf046f13eabef Mon Sep 17 00:00:00 2001 From: Vadim Kaushan Date: Thu, 14 Mar 2019 16:16:42 +0300 Subject: [PATCH 038/112] Update dependencies --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 4ee1047..88ed22f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,7 +9,7 @@ keywords = ["riscv", "register", "peripheral"] license = "ISC" [dependencies] -e310x-hal = "0.3.0" +e310x-hal = "0.4.0" [features] board-hifive1 = [] From 25c838331503bc3c555b5874860510e43ac2054c Mon Sep 17 00:00:00 2001 From: Vadim Kaushan Date: Thu, 14 Mar 2019 17:40:03 +0300 Subject: [PATCH 039/112] Update Travis build matrix --- .travis.yml | 35 +++++++---------------------------- 1 file changed, 7 insertions(+), 28 deletions(-) diff --git a/.travis.yml b/.travis.yml index d870f85..2e823ad 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,36 +1,15 @@ language: rust -matrix: - include: - #- env: TARGET=x86_64-unknown-linux-gnu - # if: (branch = staging OR branch = trying OR branch = master) OR (type = pull_request AND branch = master) +env: + - TARGET=x86_64-unknown-linux-gnu + - TARGET=riscv32imac-unknown-none-elf - #- env: TARGET=riscv32imac-unknown-none-elf - # if: (branch = staging OR branch = trying OR branch = master) OR (type = pull_request AND branch = master) +rust: + - nightly + - stable - #- env: TARGET=x86_64-unknown-linux-gnu - # rust: beta - # if: (branch = staging OR branch = trying OR branch = master) OR (type = pull_request AND branch = master) +if: (branch = staging OR branch = trying OR branch = master) OR (type = pull_request AND branch = master) - #- env: TARGET=riscv32imac-unknown-none-elf - # rust: beta - # if: (branch = staging OR branch = trying OR branch = master) OR (type = pull_request AND branch = master) - - - env: TARGET=x86_64-unknown-linux-gnu - rust: nightly - if: (branch = staging OR branch = trying OR branch = master) OR (type = pull_request AND branch = master) - - - env: TARGET=riscv32imac-unknown-none-elf - rust: nightly - if: (branch = staging OR branch = trying OR branch = master) OR (type = pull_request AND branch = master) - - - env: TARGET=x86_64-unknown-linux-gnu - rust: stable - if: (branch = staging OR branch = trying OR branch = master) OR (type = pull_request AND branch = master) - - - env: TARGET=riscv32imac-unknown-none-elf - rust: stable - if: (branch = staging OR branch = trying OR branch = master) OR (type = pull_request AND branch = master) before_install: set -e From e133f8ea807284680cb3a8c455b7cebfd0e780ab Mon Sep 17 00:00:00 2001 From: Vadim Kaushan Date: Thu, 14 Mar 2019 17:41:32 +0300 Subject: [PATCH 040/112] Remove useless 'set' commands --- .travis.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 2e823ad..57626b6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,15 +11,12 @@ rust: if: (branch = staging OR branch = trying OR branch = master) OR (type = pull_request AND branch = master) -before_install: set -e - install: - bash ci/install.sh script: - bash ci/script.sh -after_script: set +e cache: cargo before_cache: From 93acdbd09e7f591a2d52e75e91f3ad11fd216661 Mon Sep 17 00:00:00 2001 From: Vadim Kaushan Date: Thu, 14 Mar 2019 17:42:12 +0300 Subject: [PATCH 041/112] Simplify CI scripts --- .travis.yml | 4 ++-- ci/install.sh | 10 +++------- ci/script.sh | 12 +++++------- 3 files changed, 10 insertions(+), 16 deletions(-) mode change 100644 => 100755 ci/install.sh mode change 100644 => 100755 ci/script.sh diff --git a/.travis.yml b/.travis.yml index 57626b6..8821911 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,10 +12,10 @@ if: (branch = staging OR branch = trying OR branch = master) OR (type = pull_req install: - - bash ci/install.sh + - ci/install.sh script: - - bash ci/script.sh + - ci/script.sh cache: cargo diff --git a/ci/install.sh b/ci/install.sh old mode 100644 new mode 100755 index 3c41921..b2789a8 --- a/ci/install.sh +++ b/ci/install.sh @@ -1,9 +1,5 @@ -set -euxo pipefail +#!/usr/bin/env bash -main() { - if [ $TARGET != x86_64-unknown-linux-gnu ]; then - rustup target add $TARGET - fi -} +set -euxo pipefail -main +rustup target add $TARGET diff --git a/ci/script.sh b/ci/script.sh old mode 100644 new mode 100755 index bbb89ce..31f4802 --- a/ci/script.sh +++ b/ci/script.sh @@ -1,9 +1,7 @@ -set -euxo pipefail +#!/usr/bin/env bash -main() { - cargo check --target $TARGET - cargo check --target $TARGET --features 'board-hifive1' - cargo check --target $TARGET --features 'board-lofive' -} +set -euxo pipefail -main +cargo check --target $TARGET +cargo check --target $TARGET --features 'board-hifive1' +cargo check --target $TARGET --features 'board-lofive' From bd794a7b638a5ba0a71d571c1bd87eb683152de8 Mon Sep 17 00:00:00 2001 From: Vadim Kaushan Date: Thu, 14 Mar 2019 17:48:27 +0300 Subject: [PATCH 042/112] Bump version (0.4.0) --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 88ed22f..3f43257 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "hifive1" -version = "0.3.0" +version = "0.4.0" repository = "https://github.com/riscv-rust/hifive1" authors = ["David Craven "] categories = ["embedded", "hardware-support", "no-std"] From 28571780213c42ca743fc545d8e35061f40e4c74 Mon Sep 17 00:00:00 2001 From: Vadim Kaushan Date: Tue, 9 Apr 2019 18:31:38 +0300 Subject: [PATCH 043/112] Rename RISCV to RISC-V --- CODE_OF_CONDUCT.md | 4 ++-- README.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index a22c4f6..fccadf9 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -2,7 +2,7 @@ ## Conduct -**Contact**: [RISCV team](https://github.com/rust-embedded/wg#the-riscv-team) +**Contact**: [RISC-V team](https://github.com/rust-embedded/wg#the-riscv-team) * We are committed to providing a friendly, safe and welcoming environment for all, regardless of level of experience, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, religion, nationality, or other similar characteristic. * On IRC, please avoid using overtly sexual nicknames or other nicknames that might detract from a friendly, safe and welcoming environment for all. @@ -10,7 +10,7 @@ * Respect that people have differences of opinion and that every design or implementation choice carries a trade-off and numerous costs. There is seldom a right answer. * Please keep unstructured critique to a minimum. If you have solid ideas you want to experiment with, make a fork and see how it works. * We will exclude you from interaction if you insult, demean or harass anyone. That is not welcome behavior. We interpret the term "harassment" as including the definition in the [Citizen Code of Conduct](http://citizencodeofconduct.org/); if you have any lack of clarity about what might be included in that concept, please read their definition. In particular, we don't tolerate behavior that excludes people in socially marginalized groups. -* Private harassment is also unacceptable. No matter who you are, if you feel you have been or are being harassed or made uncomfortable by a community member, please contact one of the channel ops or any of the [RISCV team][team] immediately. Whether you're a regular contributor or a newcomer, we care about making this community a safe place for you and we've got your back. +* Private harassment is also unacceptable. No matter who you are, if you feel you have been or are being harassed or made uncomfortable by a community member, please contact one of the channel ops or any of the [RISC-V team][team] immediately. Whether you're a regular contributor or a newcomer, we care about making this community a safe place for you and we've got your back. * Likewise any spamming, trolling, flaming, baiting or other attention-stealing behavior is not welcome. ## Moderation diff --git a/README.md b/README.md index 22456d8..f3eb4d4 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ ## License -Copyright 2018 [RISCV team][team] +Copyright 2018 [RISC-V team][team] Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice @@ -27,7 +27,7 @@ THIS SOFTWARE. ## Code of Conduct Contribution to this crate is organized under the terms of the [Rust Code of -Conduct][CoC], the maintainer of this crate, the [RISCV team][team], promises +Conduct][CoC], the maintainer of this crate, the [RISC-V team][team], promises to intervene to uphold that code of conduct. [CoC]: CODE_OF_CONDUCT.md From ca417b567795a378a17e4b1bf236253eaa429499 Mon Sep 17 00:00:00 2001 From: Vadim Kaushan Date: Tue, 9 Apr 2019 18:31:53 +0300 Subject: [PATCH 044/112] Update copyright years --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f3eb4d4..0b85820 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ ## License -Copyright 2018 [RISC-V team][team] +Copyright 2018-2019 [RISC-V team][team] Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice From 3ffb1d54e9db2e1517f5348ad8015152e34744f5 Mon Sep 17 00:00:00 2001 From: Vadim Kaushan Date: Tue, 2 Apr 2019 18:46:58 +0300 Subject: [PATCH 045/112] Add memory definitions for HiFive1 board --- build.rs | 13 +++++++++++++ memory-hifive1.x | 15 +++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 build.rs create mode 100644 memory-hifive1.x diff --git a/build.rs b/build.rs new file mode 100644 index 0000000..b02b3a1 --- /dev/null +++ b/build.rs @@ -0,0 +1,13 @@ +use std::{env, fs}; +use std::path::PathBuf; +use std::io::Write; + +fn main() { + // Put the linker script somewhere the linker can find it + let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap()); + println!("cargo:rustc-link-search={}", out_dir.display()); + + fs::File::create(out_dir.join("memory-hifive1.x")).unwrap() + .write_all(include_bytes!("memory-hifive1.x")).unwrap(); + println!("cargo:rerun-if-changed=memory-hifive1.x"); +} diff --git a/memory-hifive1.x b/memory-hifive1.x new file mode 100644 index 0000000..cd55c70 --- /dev/null +++ b/memory-hifive1.x @@ -0,0 +1,15 @@ +INCLUDE memory-fe310.x +MEMORY +{ + FLASH : ORIGIN = 0x20000000, LENGTH = 16M +} + +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); + +/* Skip first 4M allocated for bootloader */ +_stext = 0x20400000; From a9d87a119367c98df57f02d5557cca298f05f90f Mon Sep 17 00:00:00 2001 From: Vadim Kaushan Date: Mon, 20 May 2019 09:42:53 +0300 Subject: [PATCH 046/112] Add memory definitions for HiFive1 Rev B board --- build.rs | 4 ++++ memory-hifive1-revb.x | 15 +++++++++++++++ 2 files changed, 19 insertions(+) create mode 100644 memory-hifive1-revb.x diff --git a/build.rs b/build.rs index b02b3a1..45b0eae 100644 --- a/build.rs +++ b/build.rs @@ -10,4 +10,8 @@ fn main() { fs::File::create(out_dir.join("memory-hifive1.x")).unwrap() .write_all(include_bytes!("memory-hifive1.x")).unwrap(); println!("cargo:rerun-if-changed=memory-hifive1.x"); + + fs::File::create(out_dir.join("memory-hifive1-revb.x")).unwrap() + .write_all(include_bytes!("memory-hifive1-revb.x")).unwrap(); + println!("cargo:rerun-if-changed=memory-hifive1-revb.x"); } diff --git a/memory-hifive1-revb.x b/memory-hifive1-revb.x new file mode 100644 index 0000000..e9e4bc5 --- /dev/null +++ b/memory-hifive1-revb.x @@ -0,0 +1,15 @@ +INCLUDE memory-fe310.x +MEMORY +{ + FLASH : ORIGIN = 0x20000000, LENGTH = 4M +} + +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); + +/* Skip first 64k allocated for bootloader */ +_stext = 0x20010000; From 28479b763e8a9ee8a27a5cd0a6d7f4b3479dbe2f Mon Sep 17 00:00:00 2001 From: Vadim Kaushan Date: Mon, 20 May 2019 11:18:39 +0300 Subject: [PATCH 047/112] Remove #![deny(warnings)] (anti-pattern) --- src/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 6850839..2fc6ca4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,7 +1,6 @@ //! Board support crate for HiFive1 and LoFive boards #![deny(missing_docs)] -#![deny(warnings)] #![no_std] pub extern crate e310x_hal as hal; From fa8b94ab5660424ae0e09f692a075806233bf174 Mon Sep 17 00:00:00 2001 From: Vadim Kaushan Date: Thu, 6 Jun 2019 15:47:53 +0300 Subject: [PATCH 048/112] Update e310x-hal dependency --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 3f43257..88ec87c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,7 +9,7 @@ keywords = ["riscv", "register", "peripheral"] license = "ISC" [dependencies] -e310x-hal = "0.4.0" +e310x-hal = "0.5.0" [features] board-hifive1 = [] From 0635193887f441c2902bbd7232fe9fdd02cb81c7 Mon Sep 17 00:00:00 2001 From: Vadim Kaushan Date: Thu, 6 Jun 2019 15:55:49 +0300 Subject: [PATCH 049/112] Downgrade memory definitions to prevent bootloader destruction --- memory-hifive1-revb.x | 12 +----------- memory-hifive1.x | 12 +----------- 2 files changed, 2 insertions(+), 22 deletions(-) diff --git a/memory-hifive1-revb.x b/memory-hifive1-revb.x index e9e4bc5..516306c 100644 --- a/memory-hifive1-revb.x +++ b/memory-hifive1-revb.x @@ -1,15 +1,5 @@ INCLUDE memory-fe310.x MEMORY { - FLASH : ORIGIN = 0x20000000, LENGTH = 4M + FLASH : ORIGIN = 0x20010000, LENGTH = 4032K } - -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); - -/* Skip first 64k allocated for bootloader */ -_stext = 0x20010000; diff --git a/memory-hifive1.x b/memory-hifive1.x index cd55c70..f38703b 100644 --- a/memory-hifive1.x +++ b/memory-hifive1.x @@ -1,15 +1,5 @@ INCLUDE memory-fe310.x MEMORY { - FLASH : ORIGIN = 0x20000000, LENGTH = 16M + FLASH : ORIGIN = 0x20400000, LENGTH = 12M } - -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); - -/* Skip first 4M allocated for bootloader */ -_stext = 0x20400000; From 747b66a6537bff70b58e4d50b2e1a42cc70ed865 Mon Sep 17 00:00:00 2001 From: Vadim Kaushan Date: Thu, 6 Jun 2019 16:15:04 +0300 Subject: [PATCH 050/112] Use digital::v2 traits --- Cargo.toml | 1 + src/led.rs | 14 +++++++------- src/lib.rs | 1 + 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 88ec87c..dbeea96 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,6 +10,7 @@ license = "ISC" [dependencies] e310x-hal = "0.5.0" +embedded-hal = "0.2.3" [features] board-hifive1 = [] diff --git a/src/led.rs b/src/led.rs index 1f321e1..521c050 100644 --- a/src/led.rs +++ b/src/led.rs @@ -3,7 +3,7 @@ //! - Red = Pin 22 //! - Green = Pin 19 //! - Blue = Pin 21 -use hal::prelude::*; +use embedded_hal::digital::v2::OutputPin; use hal::gpio::gpio0::{Pin19, Pin21, Pin22, OUTPUT_EN, DRIVE, OUT_XOR, IOF_EN}; use hal::gpio::{Output, Regular, Invert}; @@ -56,30 +56,30 @@ pub trait Led { impl Led for RED { fn off(&mut self) { - _embedded_hal_digital_OutputPin::set_low(self); + self.set_low().unwrap(); } fn on(&mut self) { - _embedded_hal_digital_OutputPin::set_high(self); + self.set_high().unwrap(); } } impl Led for GREEN { fn off(&mut self) { - _embedded_hal_digital_OutputPin::set_low(self); + self.set_low().unwrap(); } fn on(&mut self) { - _embedded_hal_digital_OutputPin::set_high(self); + self.set_high().unwrap(); } } impl Led for BLUE { fn off(&mut self) { - _embedded_hal_digital_OutputPin::set_low(self); + self.set_low().unwrap(); } fn on(&mut self) { - _embedded_hal_digital_OutputPin::set_high(self); + self.set_high().unwrap(); } } diff --git a/src/lib.rs b/src/lib.rs index 2fc6ca4..71fc5b2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,6 +4,7 @@ #![no_std] pub extern crate e310x_hal as hal; +extern crate embedded_hal; pub mod clock; #[cfg(feature = "board-hifive1")] From e692dd936ab602c2416990a0487b527fa94730ee Mon Sep 17 00:00:00 2001 From: Vadim Kaushan Date: Thu, 6 Jun 2019 16:17:37 +0300 Subject: [PATCH 051/112] Add support for HiFive1 Rev B --- Cargo.toml | 3 ++- ci/script.sh | 1 + src/clock.rs | 7 ++++--- src/lib.rs | 4 ++-- 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index dbeea96..210d48a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,7 +14,8 @@ embedded-hal = "0.2.3" [features] board-hifive1 = [] +board-hifive1-revb = ["e310x-hal/g002"] board-lofive = [] [package.metadata.docs.rs] -features = ['board-hifive1'] +features = ['board-hifive1-revb'] diff --git a/ci/script.sh b/ci/script.sh index 31f4802..a0c30a3 100755 --- a/ci/script.sh +++ b/ci/script.sh @@ -4,4 +4,5 @@ set -euxo pipefail cargo check --target $TARGET cargo check --target $TARGET --features 'board-hifive1' +cargo check --target $TARGET --features 'board-hifive1-revb' cargo check --target $TARGET --features 'board-lofive' diff --git a/src/clock.rs b/src/clock.rs index 027f397..5af13ea 100644 --- a/src/clock.rs +++ b/src/clock.rs @@ -1,16 +1,17 @@ //! Board-specific clock configuration -#[cfg(any(feature = "board-hifive1", feature = "board-lofive"))] +#[cfg(any(feature = "board-hifive1", feature = "board-hifive1-revb", feature = "board-lofive"))] use hal::{ e310x::{PRCI, AONCLK}, clock::{Clocks, PrciExt, AonExt}, time::Hertz, }; -#[cfg(feature = "board-hifive1")] +#[cfg(any(feature = "board-hifive1", feature = "board-hifive1-revb"))] /// Configures clock generation system. /// -/// For HiFive1 board external oscillators are enabled for both high-frequency and low-frequency clocks. +/// For HiFive1 and HiFive1 Rev B boards external oscillators are enabled for +/// both high-frequency and low-frequency clocks. pub fn configure(prci: PRCI, aonclk: AONCLK, target_coreclk: Hertz) -> Clocks { let coreclk = prci.constrain(); let coreclk = coreclk.use_external(Hertz(16_000_000)).coreclk(target_coreclk); diff --git a/src/lib.rs b/src/lib.rs index 71fc5b2..45e7d37 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -7,10 +7,10 @@ pub extern crate e310x_hal as hal; extern crate embedded_hal; pub mod clock; -#[cfg(feature = "board-hifive1")] +#[cfg(any(feature = "board-hifive1", feature = "board-hifive1-revb"))] pub mod led; pub mod serial; -#[cfg(feature = "board-hifive1")] +#[cfg(any(feature = "board-hifive1", feature = "board-hifive1-revb"))] pub use led::{RED, GREEN, BLUE, rgb, Led}; pub use serial::{TX, RX, TxPin, RxPin, tx_rx}; From 380538e63b6eb55abaf588117159ddeab8f7a3c8 Mon Sep 17 00:00:00 2001 From: Vadim Kaushan Date: Thu, 6 Jun 2019 16:31:58 +0300 Subject: [PATCH 052/112] Enforce board selection, provide old-style memory.x --- build.rs | 38 ++++++++++++++++++++++++++++++-------- ci/script.sh | 1 - src/clock.rs | 1 - 3 files changed, 30 insertions(+), 10 deletions(-) diff --git a/build.rs b/build.rs index 45b0eae..e8fd4a3 100644 --- a/build.rs +++ b/build.rs @@ -1,17 +1,39 @@ use std::{env, fs}; use std::path::PathBuf; -use std::io::Write; fn main() { - // Put the linker script somewhere the linker can find it + // Put the memory definitions somewhere the linker can find it let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap()); println!("cargo:rustc-link-search={}", out_dir.display()); - fs::File::create(out_dir.join("memory-hifive1.x")).unwrap() - .write_all(include_bytes!("memory-hifive1.x")).unwrap(); - println!("cargo:rerun-if-changed=memory-hifive1.x"); + let boards: Vec<_> = env::vars().filter_map(|(key, _value)| { + if key.starts_with("CARGO_FEATURE_BOARD") { + Some(key[20..].to_ascii_lowercase()) // Strip 'CARGO_FEATURE_BOARD_' + } else { + None + } + }).collect(); - fs::File::create(out_dir.join("memory-hifive1-revb.x")).unwrap() - .write_all(include_bytes!("memory-hifive1-revb.x")).unwrap(); - println!("cargo:rerun-if-changed=memory-hifive1-revb.x"); + if boards.is_empty() { + panic!("No board features selected"); + } + if boards.len() > 1 { + panic!("More than one board feature selected: {:?}", boards); + } + + let board = boards.first().unwrap(); + + match board.as_str() { + "hifive1" => { + fs::copy("memory-hifive1.x", out_dir.join("memory.x")).unwrap(); + println!("cargo:rerun-if-changed=memory-hifive1.x"); + } + "hifive1_revb" => { + fs::copy("memory-hifive1-revb.x", out_dir.join("memory.x")).unwrap(); + println!("cargo:rerun-if-changed=memory-hifive1-revb.x"); + } + "lofive" => {} + + other => panic!("Unknown board: {}", other), + } } diff --git a/ci/script.sh b/ci/script.sh index a0c30a3..29cd4d2 100755 --- a/ci/script.sh +++ b/ci/script.sh @@ -2,7 +2,6 @@ set -euxo pipefail -cargo check --target $TARGET cargo check --target $TARGET --features 'board-hifive1' cargo check --target $TARGET --features 'board-hifive1-revb' cargo check --target $TARGET --features 'board-lofive' diff --git a/src/clock.rs b/src/clock.rs index 5af13ea..bbfed6a 100644 --- a/src/clock.rs +++ b/src/clock.rs @@ -1,6 +1,5 @@ //! Board-specific clock configuration -#[cfg(any(feature = "board-hifive1", feature = "board-hifive1-revb", feature = "board-lofive"))] use hal::{ e310x::{PRCI, AONCLK}, clock::{Clocks, PrciExt, AonExt}, From 96dd9c1e0a620711c35d253d5508a4f991210d49 Mon Sep 17 00:00:00 2001 From: Vadim Kaushan Date: Thu, 6 Jun 2019 16:37:47 +0300 Subject: [PATCH 053/112] Bump version (0.5.0) --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 210d48a..0ad53ba 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "hifive1" -version = "0.4.0" +version = "0.5.0" repository = "https://github.com/riscv-rust/hifive1" authors = ["David Craven "] categories = ["embedded", "hardware-support", "no-std"] From b422dc2d5e41835a09ce1df1436ea95908e6736f Mon Sep 17 00:00:00 2001 From: Vadim Kaushan Date: Sat, 15 Jun 2019 16:00:53 +0300 Subject: [PATCH 054/112] 2018 edition --- Cargo.toml | 1 + src/clock.rs | 2 +- src/led.rs | 4 ++-- src/lib.rs | 3 +-- src/serial.rs | 8 ++++---- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 0ad53ba..67348e9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,6 +7,7 @@ categories = ["embedded", "hardware-support", "no-std"] description = "Board support crate for HiFive1 and LoFive boards" keywords = ["riscv", "register", "peripheral"] license = "ISC" +edition = "2018" [dependencies] e310x-hal = "0.5.0" diff --git a/src/clock.rs b/src/clock.rs index bbfed6a..84fb9d4 100644 --- a/src/clock.rs +++ b/src/clock.rs @@ -1,6 +1,6 @@ //! Board-specific clock configuration -use hal::{ +use e310x_hal::{ e310x::{PRCI, AONCLK}, clock::{Clocks, PrciExt, AonExt}, time::Hertz, diff --git a/src/led.rs b/src/led.rs index 521c050..6ee5e5a 100644 --- a/src/led.rs +++ b/src/led.rs @@ -4,9 +4,9 @@ //! - Green = Pin 19 //! - Blue = Pin 21 use embedded_hal::digital::v2::OutputPin; -use hal::gpio::gpio0::{Pin19, Pin21, Pin22, OUTPUT_EN, DRIVE, +use e310x_hal::gpio::gpio0::{Pin19, Pin21, Pin22, OUTPUT_EN, DRIVE, OUT_XOR, IOF_EN}; -use hal::gpio::{Output, Regular, Invert}; +use e310x_hal::gpio::{Output, Regular, Invert}; /// Red LED pub type RED = Pin22>>; diff --git a/src/lib.rs b/src/lib.rs index 45e7d37..9139af0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,8 +3,7 @@ #![deny(missing_docs)] #![no_std] -pub extern crate e310x_hal as hal; -extern crate embedded_hal; +pub use e310x_hal as hal; pub mod clock; #[cfg(any(feature = "board-hifive1", feature = "board-hifive1-revb"))] diff --git a/src/serial.rs b/src/serial.rs index cd2aca2..b01b468 100644 --- a/src/serial.rs +++ b/src/serial.rs @@ -2,10 +2,10 @@ //! //! - Tx = Pin 17 //! - Rx = Pin 16 -use hal::gpio::gpio0::{Pin16, Pin17, OUT_XOR, IOF_SEL, IOF_EN}; -use hal::gpio::{IOF0, NoInvert}; -use hal::serial::{Tx, Rx}; -use hal::e310x::UART0; +use e310x_hal::gpio::gpio0::{Pin16, Pin17, OUT_XOR, IOF_SEL, IOF_EN}; +use e310x_hal::gpio::{IOF0, NoInvert}; +use e310x_hal::serial::{Tx, Rx}; +use e310x_hal::e310x::UART0; /// UART0 TX Pin pub type TxPin = Pin17>; From f9d470329617bf857f24ca8bc2d1db39c8f89cf1 Mon Sep 17 00:00:00 2001 From: Vadim Kaushan Date: Sat, 15 Jun 2019 16:02:36 +0300 Subject: [PATCH 055/112] Update e310x-hal dependency --- Cargo.toml | 2 +- src/led.rs | 28 +++++----------------------- src/serial.rs | 10 ++++------ 3 files changed, 10 insertions(+), 30 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 67348e9..9492699 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,7 +10,7 @@ license = "ISC" edition = "2018" [dependencies] -e310x-hal = "0.5.0" +e310x-hal = "0.6.0" embedded-hal = "0.2.3" [features] diff --git a/src/led.rs b/src/led.rs index 6ee5e5a..9686f5d 100644 --- a/src/led.rs +++ b/src/led.rs @@ -4,8 +4,7 @@ //! - Green = Pin 19 //! - Blue = Pin 21 use embedded_hal::digital::v2::OutputPin; -use e310x_hal::gpio::gpio0::{Pin19, Pin21, Pin22, OUTPUT_EN, DRIVE, - OUT_XOR, IOF_EN}; +use e310x_hal::gpio::gpio0::{Pin19, Pin21, Pin22}; use e310x_hal::gpio::{Output, Regular, Invert}; /// Red LED @@ -19,29 +18,12 @@ pub type BLUE = Pin21>>; /// Returns RED, GREEN and BLUE LEDs. pub fn rgb( - red: Pin22, green: Pin19, blue: Pin21, - output_en: &mut OUTPUT_EN, drive: &mut DRIVE, - out_xor: &mut OUT_XOR, iof_en: &mut IOF_EN + red: Pin22, green: Pin19, blue: Pin21 ) -> (RED, GREEN, BLUE) { - let red: RED = red.into_inverted_output( - output_en, - drive, - out_xor, - iof_en, - ); - let green: GREEN = green.into_inverted_output( - output_en, - drive, - out_xor, - iof_en, - ); - let blue: BLUE = blue.into_inverted_output( - output_en, - drive, - out_xor, - iof_en, - ); + let red: RED = red.into_inverted_output(); + let green: GREEN = green.into_inverted_output(); + let blue: BLUE = blue.into_inverted_output(); (red, green, blue) } diff --git a/src/serial.rs b/src/serial.rs index b01b468..cbfc842 100644 --- a/src/serial.rs +++ b/src/serial.rs @@ -2,7 +2,7 @@ //! //! - Tx = Pin 17 //! - Rx = Pin 16 -use e310x_hal::gpio::gpio0::{Pin16, Pin17, OUT_XOR, IOF_SEL, IOF_EN}; +use e310x_hal::gpio::gpio0::{Pin16, Pin17}; use e310x_hal::gpio::{IOF0, NoInvert}; use e310x_hal::serial::{Tx, Rx}; use e310x_hal::e310x::UART0; @@ -18,12 +18,10 @@ pub type RX = Rx; /// Return TX, RX pins. pub fn tx_rx( - tx: Pin17, rx: Pin16, - out_xor: &mut OUT_XOR, iof_sel: &mut IOF_SEL, - iof_en: &mut IOF_EN + tx: Pin17, rx: Pin16 ) -> (TxPin, RxPin) { - let tx: TxPin = tx.into_iof0(out_xor, iof_sel, iof_en); - let rx: RxPin = rx.into_iof0(out_xor, iof_sel, iof_en); + let tx: TxPin = tx.into_iof0(); + let rx: RxPin = rx.into_iof0(); (tx, rx) } From 3fbdce1cc08c0c54335e6e13cf833c256266255d Mon Sep 17 00:00:00 2001 From: Vadim Kaushan Date: Sat, 15 Jun 2019 16:10:49 +0300 Subject: [PATCH 056/112] Replace serial methods with stdout --- Cargo.toml | 2 + src/lib.rs | 7 ++-- src/serial.rs | 27 -------------- src/stdout.rs | 100 ++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 106 insertions(+), 30 deletions(-) delete mode 100644 src/serial.rs create mode 100644 src/stdout.rs diff --git a/Cargo.toml b/Cargo.toml index 9492699..c62c96e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,6 +12,8 @@ edition = "2018" [dependencies] e310x-hal = "0.6.0" embedded-hal = "0.2.3" +riscv = "0.5.2" +nb = "0.1.2" [features] board-hifive1 = [] diff --git a/src/lib.rs b/src/lib.rs index 9139af0..856b050 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -6,10 +6,11 @@ pub use e310x_hal as hal; pub mod clock; + #[cfg(any(feature = "board-hifive1", feature = "board-hifive1-revb"))] pub mod led; -pub mod serial; - #[cfg(any(feature = "board-hifive1", feature = "board-hifive1-revb"))] pub use led::{RED, GREEN, BLUE, rgb, Led}; -pub use serial::{TX, RX, TxPin, RxPin, tx_rx}; + +pub mod stdout; +pub use stdout::configure as configure_stdout; diff --git a/src/serial.rs b/src/serial.rs deleted file mode 100644 index cbfc842..0000000 --- a/src/serial.rs +++ /dev/null @@ -1,27 +0,0 @@ -//! Single UART hooked up to FTDI -//! -//! - Tx = Pin 17 -//! - Rx = Pin 16 -use e310x_hal::gpio::gpio0::{Pin16, Pin17}; -use e310x_hal::gpio::{IOF0, NoInvert}; -use e310x_hal::serial::{Tx, Rx}; -use e310x_hal::e310x::UART0; - -/// UART0 TX Pin -pub type TxPin = Pin17>; -/// UART0 RX Pin -pub type RxPin = Pin16>; -/// UART0 TX -pub type TX = Tx; -/// UART0 RX -pub type RX = Rx; - -/// Return TX, RX pins. -pub fn tx_rx( - tx: Pin17, rx: Pin16 -) -> (TxPin, RxPin) -{ - let tx: TxPin = tx.into_iof0(); - let rx: RxPin = rx.into_iof0(); - (tx, rx) -} diff --git a/src/stdout.rs b/src/stdout.rs new file mode 100644 index 0000000..147a605 --- /dev/null +++ b/src/stdout.rs @@ -0,0 +1,100 @@ +//! Stdout based on the UART hooked up to FTDI or J-Link + +use core::fmt; +use nb::block; +use riscv::interrupt; +use e310x_hal::{ + serial::{Serial, Tx}, + gpio::gpio0::{Pin17, Pin16}, + time::Bps, + clock::Clocks, + e310x::UART0, + prelude::* +}; + + +static mut STDOUT: Option = None; + + +struct SerialWrapper(Tx); + +impl core::fmt::Write for SerialWrapper { + fn write_str(&mut self, s: &str) -> fmt::Result { + for byte in s.as_bytes() { + if *byte == '\n' as u8 { + let res = block!(self.0.write('\r' as u8)); + + if res.is_err() { + return Err(::core::fmt::Error); + } + } + + let res = block!(self.0.write(*byte)); + + if res.is_err() { + return Err(::core::fmt::Error); + } + } + Ok(()) + } +} + +/// Configures stdout +pub fn configure( + uart: UART0, tx: Pin17, rx: Pin16, + baud_rate: Bps, clocks: Clocks +) { + let tx = tx.into_iof0(); + let rx = rx.into_iof0(); + let serial = Serial::new(uart, (tx, rx), baud_rate, clocks); + let (tx, _) = serial.split(); + + interrupt::free(|_| { + unsafe { + STDOUT.replace(SerialWrapper(tx)); + } + }) +} + +/// Writes string to stdout +pub fn write_str(s: &str) { + interrupt::free(|_| unsafe { + if let Some(stdout) = STDOUT.as_mut() { + let _ = stdout.write_str(s); + } + }) +} + +/// Writes formatted string to stdout +pub fn write_fmt(args: fmt::Arguments) { + interrupt::free(|_| unsafe { + if let Some(stdout) = STDOUT.as_mut() { + let _ = stdout.write_fmt(args); + } + }) +} + +/// Macro for printing to the serial standard output +#[macro_export] +macro_rules! sprint { + ($s:expr) => { + $crate::stdout::write_str($s) + }; + ($($tt:tt)*) => { + $crate::stdout::write_fmt(format_args!($($tt)*)) + }; +} + +/// Macro for printing to the serial standard output, with a newline. +#[macro_export] +macro_rules! sprintln { + () => { + $crate::stdout::write_str("\n") + }; + ($s:expr) => { + $crate::stdout::write_str(concat!($s, "\n")) + }; + ($s:expr, $($tt:tt)*) => { + $crate::stdout::write_fmt(format_args!(concat!($s, "\n"), $($tt)*)) + }; +} From 8c0cffb805127bd090049bdd291cfc3d68a92ada Mon Sep 17 00:00:00 2001 From: Vadim Kaushan Date: Sat, 15 Jun 2019 17:20:33 +0300 Subject: [PATCH 057/112] Reexport clock::configure function --- src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lib.rs b/src/lib.rs index 856b050..5d9b14d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -6,6 +6,7 @@ pub use e310x_hal as hal; pub mod clock; +pub use clock::configure as configure_clocks; #[cfg(any(feature = "board-hifive1", feature = "board-hifive1-revb"))] pub mod led; From 2ea9db6a68385a5729fbd2a203806f1a4ec551fd Mon Sep 17 00:00:00 2001 From: Vadim Kaushan Date: Sat, 15 Jun 2019 17:22:08 +0300 Subject: [PATCH 058/112] Remove outdated hacks from .travis.yml --- .travis.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 8821911..1e9dc7a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,9 +19,6 @@ script: cache: cargo -before_cache: - # Travis can't cache files that are not readable by "others" - - chmod -R a+r $HOME/.cargo branches: only: From 1bf4073d64db241ed3a68c3bb34084bcfecf5d26 Mon Sep 17 00:00:00 2001 From: Vadim Kaushan Date: Sat, 15 Jun 2019 17:28:28 +0300 Subject: [PATCH 059/112] Bump version (0.6.0) --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index c62c96e..4ead38f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "hifive1" -version = "0.5.0" +version = "0.6.0" repository = "https://github.com/riscv-rust/hifive1" authors = ["David Craven "] categories = ["embedded", "hardware-support", "no-std"] From 7f01c37d86b82bde1179683f692f59beb4b0af9c Mon Sep 17 00:00:00 2001 From: Vadim Kaushan Date: Fri, 5 Jul 2019 17:54:19 +0300 Subject: [PATCH 060/112] Update e310x-hal dependency --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 4ead38f..7f61680 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,7 +10,7 @@ license = "ISC" edition = "2018" [dependencies] -e310x-hal = "0.6.0" +e310x-hal = "0.7.0" embedded-hal = "0.2.3" riscv = "0.5.2" nb = "0.1.2" From f60ffeb071bd906d9abbb9720816b0a13398003b Mon Sep 17 00:00:00 2001 From: Vadim Kaushan Date: Fri, 5 Jul 2019 18:43:53 +0300 Subject: [PATCH 061/112] Implement BoardResources --- src/board.rs | 127 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 3 ++ 2 files changed, 130 insertions(+) create mode 100644 src/board.rs diff --git a/src/board.rs b/src/board.rs new file mode 100644 index 0000000..3db7bd9 --- /dev/null +++ b/src/board.rs @@ -0,0 +1,127 @@ +//! Board resources + +use e310x_hal::gpio::{Unknown, gpio0::*}; +use e310x_hal::device::{DevicePeripherals, DeviceResources, DeviceGpioPins}; +use e310x_hal::core::CorePeripherals; + +/// Pins exposed on the Arduino connector +pub struct BoardPins { + /// DIG0 / UART_RX + pub dig0: Pin16, + + /// DIG1 / UART_TX + pub dig1: Pin17, + + /// DIG2 + pub dig2: Pin18, + + /// DIG3 / PWM + pub dig3: Pin19, + + /// DIG4 + pub dig4: Pin20, + + /// DIG5 / PWM + pub dig5: Pin21, + + /// DIG6 / PWM + pub dig6: Pin22, + + /// DIG7 + pub dig7: Pin23, + + /// DIG8 + pub dig8: Pin0, + + /// DIG9 / PWM + pub dig9: Pin1, + + /// DIG10 / SS / PWM + pub dig10: Pin2, + + /// DIG11 / MOSI / PWM + pub dig11: Pin3, + + /// DIG12 / MISO + pub dig12: Pin4, + + /// DIG13 / SCK + pub dig13: Pin5, + + /// DIG15 + pub dig15: Pin9, + + /// DIG16 + pub dig16: Pin10, + + /// DIG17 + pub dig17: Pin11, + + /// DIG18 / SDA (RevB) + pub dig18: Pin12, + + /// DIG19 / SCL (RevB) + pub dig19: Pin13, +} + +impl From for BoardPins { + fn from(pins: DeviceGpioPins) -> Self { + BoardPins { + dig0: pins.pin16, + dig1: pins.pin17, + dig2: pins.pin18, + dig3: pins.pin19, + dig4: pins.pin20, + dig5: pins.pin21, + dig6: pins.pin22, + dig7: pins.pin23, + dig8: pins.pin0, + dig9: pins.pin1, + dig10: pins.pin2, + dig11: pins.pin3, + dig12: pins.pin4, + dig13: pins.pin5, + dig15: pins.pin9, + dig16: pins.pin10, + dig17: pins.pin11, + dig18: pins.pin12, + dig19: pins.pin13, + } + } +} + + +/// Board resources +pub struct BoardResources { + /// Core peripherals + pub core_peripherals: CorePeripherals, + + /// Device peripherals + pub peripherals: DevicePeripherals, + + /// Board pins + pub pins: BoardPins, +} + +impl From for BoardResources { + fn from(r: DeviceResources) -> Self { + BoardResources { + core_peripherals: r.core_peripherals, + peripherals: r.peripherals, + pins: r.pins.into() + } + } +} + +impl BoardResources { + /// Returns all the board resources *once* + #[inline] + pub fn take() -> Option { + DeviceResources::take().map(BoardResources::from) + } + + /// Unchecked version of `BoardResources::take` + pub unsafe fn steal() -> Self { + DeviceResources::steal().into() + } +} diff --git a/src/lib.rs b/src/lib.rs index 5d9b14d..16c74cc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -13,5 +13,8 @@ pub mod led; #[cfg(any(feature = "board-hifive1", feature = "board-hifive1-revb"))] pub use led::{RED, GREEN, BLUE, rgb, Led}; +pub mod board; +pub use board::BoardResources; + pub mod stdout; pub use stdout::configure as configure_stdout; From fce90b99f6e4ade1deb29825091568e3f6e552c4 Mon Sep 17 00:00:00 2001 From: Vadim Kaushan Date: Fri, 5 Jul 2019 18:48:42 +0300 Subject: [PATCH 062/112] Bump version (0.7.0) --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 7f61680..eecdaee 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "hifive1" -version = "0.6.0" +version = "0.7.0" repository = "https://github.com/riscv-rust/hifive1" authors = ["David Craven "] categories = ["embedded", "hardware-support", "no-std"] From 08197c5f5b8bb8f813e7132db9a478d1bd54a178 Mon Sep 17 00:00:00 2001 From: Ales Katona Date: Mon, 8 Jul 2019 10:48:19 -0600 Subject: [PATCH 063/112] add pin! and pins! macros for easy pin selection --- Cargo.toml | 2 +- src/gpio.rs | 88 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 2 ++ 3 files changed, 91 insertions(+), 1 deletion(-) create mode 100644 src/gpio.rs diff --git a/Cargo.toml b/Cargo.toml index eecdaee..a45230a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "hifive1" -version = "0.7.0" +version = "0.7.1" repository = "https://github.com/riscv-rust/hifive1" authors = ["David Craven "] categories = ["embedded", "hardware-support", "no-std"] diff --git a/src/gpio.rs b/src/gpio.rs new file mode 100644 index 0000000..519c6d1 --- /dev/null +++ b/src/gpio.rs @@ -0,0 +1,88 @@ +//! GPIO Pin mapping macros crate + +/// +/// Hifive1 PIN mappings (alias -> GPIO.pinX) +/// +#[macro_export] +macro_rules! pin_name { + // empty + ($gpio:ident, none) => { () }; + // spi + ($gpio:ident, spi_sck) => { $gpio.pin5 }; + ($gpio:ident, spi_mosi) => { $gpio.pin3 }; + ($gpio:ident, spi_miso) => { $gpio.pin4 }; + ($gpio:ident, spi_ss0) => { $gpio.pin2 }; + // spi_ss1 is not documented + ($gpio:ident, spi_ss2) => { $gpio.pin9 }; + ($gpio:ident, spi_cs3) => { $gpio.pin10 }; + // i2c + ($gpio:ident, i2c_sda) => { $gpio.pin12 }; + ($gpio:ident, i2c_scl) => { $gpio.pin13 }; + // serial + ($gpio:ident, serial_tx) => { $gpio.pin17 }; + ($gpio:ident, serial_rx) => { $gpio.pin16 }; + // digital/physical + ($gpio:ident, dig0) => { $gpio.pin16 }; + ($gpio:ident, dig1) => { $gpio.pin17 }; + ($gpio:ident, dig2) => { $gpio.pin18 }; + ($gpio:ident, dig3) => { $gpio.pin19 }; + ($gpio:ident, dig4) => { $gpio.pin20 }; + ($gpio:ident, dig5) => { $gpio.pin21 }; + ($gpio:ident, dig6) => { $gpio.pin22 }; + ($gpio:ident, dig7) => { $gpio.pin23 }; + ($gpio:ident, dig8) => { $gpio.pin0 }; + ($gpio:ident, dig9) => { $gpio.pin1 }; + ($gpio:ident, dig10) => { $gpio.pin2 }; + ($gpio:ident, dig11) => { $gpio.pin3 }; + ($gpio:ident, dig12) => { $gpio.pin4 }; + ($gpio:ident, dig13) => { $gpio.pin5 }; + ($gpio:ident, dig14) => { $gpio.pin8 }; // tested + ($gpio:ident, dig15) => { $gpio.pin9 }; + ($gpio:ident, dig16) => { $gpio.pin10 }; + ($gpio:ident, dig17) => { $gpio.pin11 }; + ($gpio:ident, dig18) => { $gpio.pin12 }; + ($gpio:ident, dig19) => { $gpio.pin13 }; +} + +/// +/// Returns single pin for given gpio object mapped accordingly +/// +/// *mappings* +/// +/// - spi_ -- SPI pins where is one of (sck, mosi, miso, ss0, ss2, ss3) +/// - i2c_ -- I2C pins where is one of (sda, scl) +/// - serial_ -- Serial pins where is one of (tx, rx) +/// - dig# -- Digital/physical pins on the board where # is from range <0..19> +/// +/// *example* +/// +/// `pin!(gpio.spi_mosi) -> gpio.pin3` +/// +#[macro_export] +macro_rules! pin { + ($gpio:ident.$name:ident) => { + $crate::pin_name!($gpio, $name) + } +} + +/// +/// Returns tuple of pins for given gpio object mapped accordingly +/// +/// *mappings* +/// +/// - none -- Returns () for empty pin if needed in tuple +/// - spi_ -- SPI pins where is one of (sck, mosi, miso, ss0, ss2, ss3) +/// - i2c_ -- I2C pins where is one of (sda, scl) +/// - serial_ -- Serial pins where is one of (tx, rx) +/// - dig# -- Digital/physical pins on the board where # is from range <0..19> +/// +/// *example* +/// +/// `pin!(gpio.spi_mosi) -> gpio.pin3` +/// +#[macro_export] +macro_rules! pins { + ( $gpio:ident, ($($name:ident),+) ) => { + ($($crate::pin_name!($gpio, $name)),+) + } +} diff --git a/src/lib.rs b/src/lib.rs index 16c74cc..a3b78b1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -18,3 +18,5 @@ pub use board::BoardResources; pub mod stdout; pub use stdout::configure as configure_stdout; + +pub mod gpio; \ No newline at end of file From fef5ff7b016abbaffcf1567fd88a7f06b0a66152 Mon Sep 17 00:00:00 2001 From: Vadim Kaushan Date: Tue, 9 Jul 2019 00:08:14 +0300 Subject: [PATCH 064/112] Hide gpio from docs --- src/gpio.rs | 1 + src/lib.rs | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/gpio.rs b/src/gpio.rs index 519c6d1..7f3cfb3 100644 --- a/src/gpio.rs +++ b/src/gpio.rs @@ -4,6 +4,7 @@ /// Hifive1 PIN mappings (alias -> GPIO.pinX) /// #[macro_export] +#[doc(hidden)] macro_rules! pin_name { // empty ($gpio:ident, none) => { () }; diff --git a/src/lib.rs b/src/lib.rs index a3b78b1..b2f7923 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -19,4 +19,5 @@ pub use board::BoardResources; pub mod stdout; pub use stdout::configure as configure_stdout; -pub mod gpio; \ No newline at end of file +#[doc(hidden)] +pub mod gpio; From 3a41801aeaaeadb2d382aa14c8176cff5cbfcfeb Mon Sep 17 00:00:00 2001 From: Vadim Kaushan Date: Tue, 9 Jul 2019 00:17:11 +0300 Subject: [PATCH 065/112] Fix docs --- src/gpio.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/gpio.rs b/src/gpio.rs index 7f3cfb3..06abdff 100644 --- a/src/gpio.rs +++ b/src/gpio.rs @@ -1,7 +1,5 @@ -//! GPIO Pin mapping macros crate - /// -/// Hifive1 PIN mappings (alias -> GPIO.pinX) +/// HiFive1 PIN mappings (alias -> GPIO.pinX) /// #[macro_export] #[doc(hidden)] @@ -79,7 +77,7 @@ macro_rules! pin { /// /// *example* /// -/// `pin!(gpio.spi_mosi) -> gpio.pin3` +/// `pins!(gpio, (spi_mosi, spi_miso, spi_sck, spi_ss0)) -> (gpio.pin3, gpio.pin4, gpio.pin5, gpio.pin2)` /// #[macro_export] macro_rules! pins { From 2bd511726c03e808e204863cc44c836db0c6b876 Mon Sep 17 00:00:00 2001 From: Ales Katona Date: Mon, 8 Jul 2019 15:18:28 -0600 Subject: [PATCH 066/112] use pin directly with comma separator --- src/gpio.rs | 37 +++++++++++++------------------------ 1 file changed, 13 insertions(+), 24 deletions(-) diff --git a/src/gpio.rs b/src/gpio.rs index 06abdff..ca14de4 100644 --- a/src/gpio.rs +++ b/src/gpio.rs @@ -1,9 +1,19 @@ /// -/// HiFive1 PIN mappings (alias -> GPIO.pinX) +/// Returns single pin for given gpio object mapped accordingly +/// +/// *mappings* +/// +/// - spi_ -- SPI pins where is one of (sck, mosi, miso, ss0, ss2, ss3) +/// - i2c_ -- I2C pins where is one of (sda, scl) +/// - serial_ -- Serial pins where is one of (tx, rx) +/// - dig# -- Digital/physical pins on the board where # is from range <0..19> +/// +/// *example* +/// +/// `pin!(gpio.spi_mosi) -> gpio.pin3` /// #[macro_export] -#[doc(hidden)] -macro_rules! pin_name { +macro_rules! pin { // empty ($gpio:ident, none) => { () }; // spi @@ -43,27 +53,6 @@ macro_rules! pin_name { ($gpio:ident, dig19) => { $gpio.pin13 }; } -/// -/// Returns single pin for given gpio object mapped accordingly -/// -/// *mappings* -/// -/// - spi_ -- SPI pins where is one of (sck, mosi, miso, ss0, ss2, ss3) -/// - i2c_ -- I2C pins where is one of (sda, scl) -/// - serial_ -- Serial pins where is one of (tx, rx) -/// - dig# -- Digital/physical pins on the board where # is from range <0..19> -/// -/// *example* -/// -/// `pin!(gpio.spi_mosi) -> gpio.pin3` -/// -#[macro_export] -macro_rules! pin { - ($gpio:ident.$name:ident) => { - $crate::pin_name!($gpio, $name) - } -} - /// /// Returns tuple of pins for given gpio object mapped accordingly /// From 1e3c3054fded4749157d898df599b82efe70b18c Mon Sep 17 00:00:00 2001 From: Vadim Kaushan Date: Tue, 9 Jul 2019 00:28:15 +0300 Subject: [PATCH 067/112] Improve formatting --- src/gpio.rs | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/src/gpio.rs b/src/gpio.rs index ca14de4..835c354 100644 --- a/src/gpio.rs +++ b/src/gpio.rs @@ -1,16 +1,18 @@ /// /// Returns single pin for given gpio object mapped accordingly /// -/// *mappings* +/// # Mappings /// -/// - spi_ -- SPI pins where is one of (sck, mosi, miso, ss0, ss2, ss3) -/// - i2c_ -- I2C pins where is one of (sda, scl) -/// - serial_ -- Serial pins where is one of (tx, rx) -/// - dig# -- Digital/physical pins on the board where # is from range <0..19> +/// - `spi_` — SPI pins where `` is one of (`sck`, `mosi`, `miso`, `ss0`, `ss2`, `ss3`) +/// - `i2c_` — I2C pins where `` is one of (`sda`, `scl`) +/// - `serial_` — Serial pins where is one of (`tx`, `rx`) +/// - `dig#` — Digital/physical pins on the board where `#` is from range 0..19 /// -/// *example* +/// # Example /// -/// `pin!(gpio.spi_mosi) -> gpio.pin3` +/// ``` +/// let mosi = pin!(gpio, spi_mosi); // gpio.pin3 +/// ``` /// #[macro_export] macro_rules! pin { @@ -56,17 +58,20 @@ macro_rules! pin { /// /// Returns tuple of pins for given gpio object mapped accordingly /// -/// *mappings* +/// # Mappings /// -/// - none -- Returns () for empty pin if needed in tuple -/// - spi_ -- SPI pins where is one of (sck, mosi, miso, ss0, ss2, ss3) -/// - i2c_ -- I2C pins where is one of (sda, scl) -/// - serial_ -- Serial pins where is one of (tx, rx) -/// - dig# -- Digital/physical pins on the board where # is from range <0..19> +/// - `none` — Returns `()` for empty pin if needed in tuple +/// - `spi_` — SPI pins where `` is one of (`sck`, `mosi`, `miso`, `ss0`, `ss2`, `ss3`) +/// - `i2c_` — I2C pins where `` is one of (`sda`, `scl`) +/// - `serial_` — Serial pins where is one of (`tx`, `rx`) +/// - `dig#` — Digital/physical pins on the board where `#` is from range 0..19 /// -/// *example* +/// # Example /// -/// `pins!(gpio, (spi_mosi, spi_miso, spi_sck, spi_ss0)) -> (gpio.pin3, gpio.pin4, gpio.pin5, gpio.pin2)` +/// ``` +/// let (mosi, miso, sck, cs) = pins!(gpio, (spi_mosi, spi_miso, spi_sck, spi_ss0)); +/// // (gpio.pin3, gpio.pin4, gpio.pin5, gpio.pin2) +/// ``` /// #[macro_export] macro_rules! pins { From 6b5c354c6a63fdc0955324a4ea01c69dfaa28d45 Mon Sep 17 00:00:00 2001 From: Ales Katona Date: Mon, 8 Jul 2019 15:33:14 -0600 Subject: [PATCH 068/112] serial -> uart, add numbering to spi and i2c --- src/gpio.rs | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/gpio.rs b/src/gpio.rs index 835c354..121a4a3 100644 --- a/src/gpio.rs +++ b/src/gpio.rs @@ -3,15 +3,15 @@ /// /// # Mappings /// -/// - `spi_` — SPI pins where `` is one of (`sck`, `mosi`, `miso`, `ss0`, `ss2`, `ss3`) -/// - `i2c_` — I2C pins where `` is one of (`sda`, `scl`) -/// - `serial_` — Serial pins where is one of (`tx`, `rx`) +/// - `spi0_` — SPI pins where `` is one of (`sck`, `mosi`, `miso`, `ss0`, `ss2`, `ss3`) +/// - `i2c0_` — I2C pins where `` is one of (`sda`, `scl`) +/// - `uart0_` — Serial pins where is one of (`tx`, `rx`) /// - `dig#` — Digital/physical pins on the board where `#` is from range 0..19 /// /// # Example /// /// ``` -/// let mosi = pin!(gpio, spi_mosi); // gpio.pin3 +/// let mosi = pin!(gpio, spi0_mosi); // gpio.pin3 /// ``` /// #[macro_export] @@ -19,19 +19,19 @@ macro_rules! pin { // empty ($gpio:ident, none) => { () }; // spi - ($gpio:ident, spi_sck) => { $gpio.pin5 }; - ($gpio:ident, spi_mosi) => { $gpio.pin3 }; - ($gpio:ident, spi_miso) => { $gpio.pin4 }; - ($gpio:ident, spi_ss0) => { $gpio.pin2 }; + ($gpio:ident, spi0_sck) => { $gpio.pin5 }; + ($gpio:ident, spi0_mosi) => { $gpio.pin3 }; + ($gpio:ident, spi0_miso) => { $gpio.pin4 }; + ($gpio:ident, spi0_ss0) => { $gpio.pin2 }; // spi_ss1 is not documented - ($gpio:ident, spi_ss2) => { $gpio.pin9 }; - ($gpio:ident, spi_cs3) => { $gpio.pin10 }; + ($gpio:ident, spi0_ss2) => { $gpio.pin9 }; + ($gpio:ident, spi0_cs3) => { $gpio.pin10 }; // i2c - ($gpio:ident, i2c_sda) => { $gpio.pin12 }; - ($gpio:ident, i2c_scl) => { $gpio.pin13 }; + ($gpio:ident, i2c0_sda) => { $gpio.pin12 }; + ($gpio:ident, i2c0_scl) => { $gpio.pin13 }; // serial - ($gpio:ident, serial_tx) => { $gpio.pin17 }; - ($gpio:ident, serial_rx) => { $gpio.pin16 }; + ($gpio:ident, uart0_tx) => { $gpio.pin17 }; + ($gpio:ident, uart0_rx) => { $gpio.pin16 }; // digital/physical ($gpio:ident, dig0) => { $gpio.pin16 }; ($gpio:ident, dig1) => { $gpio.pin17 }; @@ -61,15 +61,15 @@ macro_rules! pin { /// # Mappings /// /// - `none` — Returns `()` for empty pin if needed in tuple -/// - `spi_` — SPI pins where `` is one of (`sck`, `mosi`, `miso`, `ss0`, `ss2`, `ss3`) -/// - `i2c_` — I2C pins where `` is one of (`sda`, `scl`) -/// - `serial_` — Serial pins where is one of (`tx`, `rx`) +/// - `spi0_` — SPI pins where `` is one of (`sck`, `mosi`, `miso`, `ss0`, `ss2`, `ss3`) +/// - `i2c0_` — I2C pins where `` is one of (`sda`, `scl`) +/// - `uart0_` — Serial pins where is one of (`tx`, `rx`) /// - `dig#` — Digital/physical pins on the board where `#` is from range 0..19 /// /// # Example /// /// ``` -/// let (mosi, miso, sck, cs) = pins!(gpio, (spi_mosi, spi_miso, spi_sck, spi_ss0)); +/// let (mosi, miso, sck, cs) = pins!(gpio, (spi0_mosi, spi0_miso, spi0_sck, spi0_ss0)); /// // (gpio.pin3, gpio.pin4, gpio.pin5, gpio.pin2) /// ``` /// From f4bdcfb0acff3cba519fc642b8b3e5587846fa29 Mon Sep 17 00:00:00 2001 From: Vadim Kaushan Date: Tue, 9 Jul 2019 00:35:30 +0300 Subject: [PATCH 069/112] Replace Serial with UART in docs --- src/gpio.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gpio.rs b/src/gpio.rs index 121a4a3..f01f024 100644 --- a/src/gpio.rs +++ b/src/gpio.rs @@ -5,7 +5,7 @@ /// /// - `spi0_` — SPI pins where `` is one of (`sck`, `mosi`, `miso`, `ss0`, `ss2`, `ss3`) /// - `i2c0_` — I2C pins where `` is one of (`sda`, `scl`) -/// - `uart0_` — Serial pins where is one of (`tx`, `rx`) +/// - `uart0_` — UART pins where is one of (`tx`, `rx`) /// - `dig#` — Digital/physical pins on the board where `#` is from range 0..19 /// /// # Example @@ -63,7 +63,7 @@ macro_rules! pin { /// - `none` — Returns `()` for empty pin if needed in tuple /// - `spi0_` — SPI pins where `` is one of (`sck`, `mosi`, `miso`, `ss0`, `ss2`, `ss3`) /// - `i2c0_` — I2C pins where `` is one of (`sda`, `scl`) -/// - `uart0_` — Serial pins where is one of (`tx`, `rx`) +/// - `uart0_` — UART pins where is one of (`tx`, `rx`) /// - `dig#` — Digital/physical pins on the board where `#` is from range 0..19 /// /// # Example From 73307003644d0ee4964f66c67e1cb9ec374b69a3 Mon Sep 17 00:00:00 2001 From: Ales Katona Date: Sat, 13 Jul 2019 21:06:14 -0600 Subject: [PATCH 070/112] use DeviceGpioPins directly --- src/board.rs | 90 +--------------------------------------------------- 1 file changed, 1 insertion(+), 89 deletions(-) diff --git a/src/board.rs b/src/board.rs index 3db7bd9..b441cf1 100644 --- a/src/board.rs +++ b/src/board.rs @@ -1,96 +1,8 @@ //! Board resources -use e310x_hal::gpio::{Unknown, gpio0::*}; use e310x_hal::device::{DevicePeripherals, DeviceResources, DeviceGpioPins}; use e310x_hal::core::CorePeripherals; -/// Pins exposed on the Arduino connector -pub struct BoardPins { - /// DIG0 / UART_RX - pub dig0: Pin16, - - /// DIG1 / UART_TX - pub dig1: Pin17, - - /// DIG2 - pub dig2: Pin18, - - /// DIG3 / PWM - pub dig3: Pin19, - - /// DIG4 - pub dig4: Pin20, - - /// DIG5 / PWM - pub dig5: Pin21, - - /// DIG6 / PWM - pub dig6: Pin22, - - /// DIG7 - pub dig7: Pin23, - - /// DIG8 - pub dig8: Pin0, - - /// DIG9 / PWM - pub dig9: Pin1, - - /// DIG10 / SS / PWM - pub dig10: Pin2, - - /// DIG11 / MOSI / PWM - pub dig11: Pin3, - - /// DIG12 / MISO - pub dig12: Pin4, - - /// DIG13 / SCK - pub dig13: Pin5, - - /// DIG15 - pub dig15: Pin9, - - /// DIG16 - pub dig16: Pin10, - - /// DIG17 - pub dig17: Pin11, - - /// DIG18 / SDA (RevB) - pub dig18: Pin12, - - /// DIG19 / SCL (RevB) - pub dig19: Pin13, -} - -impl From for BoardPins { - fn from(pins: DeviceGpioPins) -> Self { - BoardPins { - dig0: pins.pin16, - dig1: pins.pin17, - dig2: pins.pin18, - dig3: pins.pin19, - dig4: pins.pin20, - dig5: pins.pin21, - dig6: pins.pin22, - dig7: pins.pin23, - dig8: pins.pin0, - dig9: pins.pin1, - dig10: pins.pin2, - dig11: pins.pin3, - dig12: pins.pin4, - dig13: pins.pin5, - dig15: pins.pin9, - dig16: pins.pin10, - dig17: pins.pin11, - dig18: pins.pin12, - dig19: pins.pin13, - } - } -} - - /// Board resources pub struct BoardResources { /// Core peripherals @@ -100,7 +12,7 @@ pub struct BoardResources { pub peripherals: DevicePeripherals, /// Board pins - pub pins: BoardPins, + pub pins: DeviceGpioPins, } impl From for BoardResources { From 04c2de6ce48532d84ea1918717c480fda18723ce Mon Sep 17 00:00:00 2001 From: Ales Katona Date: Tue, 16 Jul 2019 11:01:36 -0600 Subject: [PATCH 071/112] remove BoardResources --- src/board.rs | 39 --------------------------------------- src/lib.rs | 3 --- 2 files changed, 42 deletions(-) delete mode 100644 src/board.rs diff --git a/src/board.rs b/src/board.rs deleted file mode 100644 index b441cf1..0000000 --- a/src/board.rs +++ /dev/null @@ -1,39 +0,0 @@ -//! Board resources - -use e310x_hal::device::{DevicePeripherals, DeviceResources, DeviceGpioPins}; -use e310x_hal::core::CorePeripherals; - -/// Board resources -pub struct BoardResources { - /// Core peripherals - pub core_peripherals: CorePeripherals, - - /// Device peripherals - pub peripherals: DevicePeripherals, - - /// Board pins - pub pins: DeviceGpioPins, -} - -impl From for BoardResources { - fn from(r: DeviceResources) -> Self { - BoardResources { - core_peripherals: r.core_peripherals, - peripherals: r.peripherals, - pins: r.pins.into() - } - } -} - -impl BoardResources { - /// Returns all the board resources *once* - #[inline] - pub fn take() -> Option { - DeviceResources::take().map(BoardResources::from) - } - - /// Unchecked version of `BoardResources::take` - pub unsafe fn steal() -> Self { - DeviceResources::steal().into() - } -} diff --git a/src/lib.rs b/src/lib.rs index b2f7923..ea37a19 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -13,9 +13,6 @@ pub mod led; #[cfg(any(feature = "board-hifive1", feature = "board-hifive1-revb"))] pub use led::{RED, GREEN, BLUE, rgb, Led}; -pub mod board; -pub use board::BoardResources; - pub mod stdout; pub use stdout::configure as configure_stdout; From 70bb47ceb7aa75fbb57c6337678f86e74a72a6ee Mon Sep 17 00:00:00 2001 From: Ales Katona Date: Tue, 16 Jul 2019 11:01:43 -0600 Subject: [PATCH 072/112] bump riscv dependency --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index a45230a..37f9713 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,7 @@ edition = "2018" [dependencies] e310x-hal = "0.7.0" embedded-hal = "0.2.3" -riscv = "0.5.2" +riscv = "0.5.3" nb = "0.1.2" [features] From 0b6ca1492f2090c7d441e934c548b4f95a3d6a20 Mon Sep 17 00:00:00 2001 From: Ales Katona Date: Tue, 16 Jul 2019 11:18:32 -0600 Subject: [PATCH 073/112] fix pins! typo + add led_ naming --- src/gpio.rs | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/gpio.rs b/src/gpio.rs index f01f024..522a018 100644 --- a/src/gpio.rs +++ b/src/gpio.rs @@ -5,8 +5,9 @@ /// /// - `spi0_` — SPI pins where `` is one of (`sck`, `mosi`, `miso`, `ss0`, `ss2`, `ss3`) /// - `i2c0_` — I2C pins where `` is one of (`sda`, `scl`) -/// - `uart0_` — UART pins where is one of (`tx`, `rx`) +/// - `uart0_` — UART pins where `` is one of (`tx`, `rx`) /// - `dig#` — Digital/physical pins on the board where `#` is from range 0..19 +/// - `led_` - Internal LED light pins where `` is one of (`red`, `green`, `blue`) /// /// # Example /// @@ -53,6 +54,11 @@ macro_rules! pin { ($gpio:ident, dig17) => { $gpio.pin11 }; ($gpio:ident, dig18) => { $gpio.pin12 }; ($gpio:ident, dig19) => { $gpio.pin13 }; + // internal LED + ($gpio:ident, led_red) => { $gpio.pin22 }; + ($gpio:ident, led_green) => { $gpio.pin19 }; + ($gpio:ident, led_blue) => { $gpio.pin21 }; + } /// @@ -63,8 +69,9 @@ macro_rules! pin { /// - `none` — Returns `()` for empty pin if needed in tuple /// - `spi0_` — SPI pins where `` is one of (`sck`, `mosi`, `miso`, `ss0`, `ss2`, `ss3`) /// - `i2c0_` — I2C pins where `` is one of (`sda`, `scl`) -/// - `uart0_` — UART pins where is one of (`tx`, `rx`) +/// - `uart0_` — UART pins where `` is one of (`tx`, `rx`) /// - `dig#` — Digital/physical pins on the board where `#` is from range 0..19 +/// - `led_` - Internal LED light pins `` is one of (`red`, `green`, `blue`) /// /// # Example /// @@ -76,6 +83,6 @@ macro_rules! pin { #[macro_export] macro_rules! pins { ( $gpio:ident, ($($name:ident),+) ) => { - ($($crate::pin_name!($gpio, $name)),+) + ($($crate::pin!($gpio, $name)),+) } } From c46f2f3058c984df3aff685637bf23635958b4ab Mon Sep 17 00:00:00 2001 From: Ales Katona Date: Tue, 16 Jul 2019 11:27:49 -0600 Subject: [PATCH 074/112] fix cs3 -> ss3 --- src/gpio.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gpio.rs b/src/gpio.rs index 522a018..d4bf258 100644 --- a/src/gpio.rs +++ b/src/gpio.rs @@ -26,7 +26,7 @@ macro_rules! pin { ($gpio:ident, spi0_ss0) => { $gpio.pin2 }; // spi_ss1 is not documented ($gpio:ident, spi0_ss2) => { $gpio.pin9 }; - ($gpio:ident, spi0_cs3) => { $gpio.pin10 }; + ($gpio:ident, spi0_ss3) => { $gpio.pin10 }; // i2c ($gpio:ident, i2c0_sda) => { $gpio.pin12 }; ($gpio:ident, i2c0_scl) => { $gpio.pin13 }; From 89bbef05b34f06ebb37de26184409da3af1486a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ale=C5=A1=20Katona?= Date: Tue, 16 Jul 2019 11:24:49 -0600 Subject: [PATCH 075/112] Update src/gpio.rs Co-Authored-By: Vadim Kaushan --- src/gpio.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gpio.rs b/src/gpio.rs index d4bf258..7a3d247 100644 --- a/src/gpio.rs +++ b/src/gpio.rs @@ -54,7 +54,7 @@ macro_rules! pin { ($gpio:ident, dig17) => { $gpio.pin11 }; ($gpio:ident, dig18) => { $gpio.pin12 }; ($gpio:ident, dig19) => { $gpio.pin13 }; - // internal LED + // onboard LEDs ($gpio:ident, led_red) => { $gpio.pin22 }; ($gpio:ident, led_green) => { $gpio.pin19 }; ($gpio:ident, led_blue) => { $gpio.pin21 }; From d0917639cd6d717fe8a8c5b7d53528d29c555949 Mon Sep 17 00:00:00 2001 From: Vadim Kaushan Date: Tue, 16 Jul 2019 22:49:24 +0300 Subject: [PATCH 076/112] Update e310x-hal dependency --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 37f9713..732bd40 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,7 +10,7 @@ license = "ISC" edition = "2018" [dependencies] -e310x-hal = "0.7.0" +e310x-hal = "0.8.0" embedded-hal = "0.2.3" riscv = "0.5.3" nb = "0.1.2" From 19f59414bdcd1620248af56ff5e71d0c34a1fc79 Mon Sep 17 00:00:00 2001 From: Vadim Kaushan Date: Tue, 16 Jul 2019 22:50:53 +0300 Subject: [PATCH 077/112] Revert "Downgrade memory definitions to prevent bootloader destruction" This reverts commit 0635193887f441c2902bbd7232fe9fdd02cb81c7. --- memory-hifive1-revb.x | 12 +++++++++++- memory-hifive1.x | 12 +++++++++++- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/memory-hifive1-revb.x b/memory-hifive1-revb.x index 516306c..e9e4bc5 100644 --- a/memory-hifive1-revb.x +++ b/memory-hifive1-revb.x @@ -1,5 +1,15 @@ INCLUDE memory-fe310.x MEMORY { - FLASH : ORIGIN = 0x20010000, LENGTH = 4032K + FLASH : ORIGIN = 0x20000000, LENGTH = 4M } + +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); + +/* Skip first 64k allocated for bootloader */ +_stext = 0x20010000; diff --git a/memory-hifive1.x b/memory-hifive1.x index f38703b..cd55c70 100644 --- a/memory-hifive1.x +++ b/memory-hifive1.x @@ -1,5 +1,15 @@ INCLUDE memory-fe310.x MEMORY { - FLASH : ORIGIN = 0x20400000, LENGTH = 12M + FLASH : ORIGIN = 0x20000000, LENGTH = 16M } + +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); + +/* Skip first 4M allocated for bootloader */ +_stext = 0x20400000; From fa68b807a25c6ae790c9b3173509c882237c35ee Mon Sep 17 00:00:00 2001 From: Vadim Kaushan Date: Tue, 16 Jul 2019 23:04:08 +0300 Subject: [PATCH 078/112] Generate a linker script configured for HiFive1 boards --- build.rs | 6 ++++-- hifive1-link.x | 2 ++ 2 files changed, 6 insertions(+), 2 deletions(-) create mode 100644 hifive1-link.x diff --git a/build.rs b/build.rs index e8fd4a3..cde3258 100644 --- a/build.rs +++ b/build.rs @@ -25,15 +25,17 @@ fn main() { match board.as_str() { "hifive1" => { - fs::copy("memory-hifive1.x", out_dir.join("memory.x")).unwrap(); + fs::copy("memory-hifive1.x", out_dir.join("hifive1-memory.x")).unwrap(); println!("cargo:rerun-if-changed=memory-hifive1.x"); } "hifive1_revb" => { - fs::copy("memory-hifive1-revb.x", out_dir.join("memory.x")).unwrap(); + fs::copy("memory-hifive1-revb.x", out_dir.join("hifive1-memory.x")).unwrap(); println!("cargo:rerun-if-changed=memory-hifive1-revb.x"); } "lofive" => {} other => panic!("Unknown board: {}", other), } + + fs::copy("hifive1-link.x", out_dir.join("hifive1-link.x")).unwrap(); } diff --git a/hifive1-link.x b/hifive1-link.x new file mode 100644 index 0000000..c472d9b --- /dev/null +++ b/hifive1-link.x @@ -0,0 +1,2 @@ +INCLUDE hifive1-memory.x +INCLUDE link.x From a3682e52b5ec128f1e2834b0aa1c6d7a7bbdbed1 Mon Sep 17 00:00:00 2001 From: Vadim Kaushan Date: Tue, 16 Jul 2019 23:05:30 +0300 Subject: [PATCH 079/112] Bump version (0.8.0) --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 732bd40..876d018 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "hifive1" -version = "0.7.1" +version = "0.8.0" repository = "https://github.com/riscv-rust/hifive1" authors = ["David Craven "] categories = ["embedded", "hardware-support", "no-std"] From a9da833d1e57fdc2ff2d565990af0d721385ba95 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Sat, 7 Sep 2019 11:34:38 +0200 Subject: [PATCH 080/112] readme: fix link --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0b85820..3c9dfd0 100644 --- a/README.md +++ b/README.md @@ -31,4 +31,4 @@ Conduct][CoC], the maintainer of this crate, the [RISC-V team][team], promises to intervene to uphold that code of conduct. [CoC]: CODE_OF_CONDUCT.md -[team]: https://github.com/rust-embedded/wg#the-riscv-team +[team]: https://github.com/rust-embedded/wg#the-risc-v-team From 9f12be56d2c2cdef7a0bb055620b3118847b65dd Mon Sep 17 00:00:00 2001 From: Vadim Kaushan Date: Wed, 6 Nov 2019 19:20:22 +0300 Subject: [PATCH 081/112] Fix clock setup for lofive board --- src/clock.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/clock.rs b/src/clock.rs index 84fb9d4..22d18df 100644 --- a/src/clock.rs +++ b/src/clock.rs @@ -31,7 +31,6 @@ pub fn configure(prci: PRCI, aonclk: AONCLK, target_coreclk: Hertz) -> Clocks { let coreclk = coreclk.use_external(Hertz(16_000_000)).coreclk(target_coreclk); let aonclk = aonclk.constrain(); - let aonclk = aonclk.use_external(Hertz(32_768)); Clocks::freeze(coreclk, aonclk) } From 2776fac8d1822e0f9c8ff4ddc71eb4a96e86513f Mon Sep 17 00:00:00 2001 From: Charles Hall Date: Wed, 6 Nov 2019 11:59:41 -0800 Subject: [PATCH 082/112] added support for the LoFive R1 (#17) * added support for the LoFive R1 * corrected src/clock.rs * added CI rule for `board-lofive-r1` feature * added linkerscript for the LoFive R1 Note that this linkerscript assumes the bootloader is installed. Instructions on how to do that can be found here: https://github.com/mwelling/lofive/wiki#programming-to-lofive-r1-using-the-new-sdk It'll "work" without the bootloader, but user code won't start after a reset. --- Cargo.toml | 1 + build.rs | 4 ++++ ci/script.sh | 1 + memory-lofive-r1.x | 15 +++++++++++++++ src/clock.rs | 6 +++--- 5 files changed, 24 insertions(+), 3 deletions(-) create mode 100644 memory-lofive-r1.x diff --git a/Cargo.toml b/Cargo.toml index 876d018..84d6b42 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,6 +19,7 @@ nb = "0.1.2" board-hifive1 = [] board-hifive1-revb = ["e310x-hal/g002"] board-lofive = [] +board-lofive-r1 = ["e310x-hal/g002"] [package.metadata.docs.rs] features = ['board-hifive1-revb'] diff --git a/build.rs b/build.rs index cde3258..a963519 100644 --- a/build.rs +++ b/build.rs @@ -33,6 +33,10 @@ fn main() { println!("cargo:rerun-if-changed=memory-hifive1-revb.x"); } "lofive" => {} + "lofive_r1" => { + fs::copy("memory-lofive-r1.x", out_dir.join("hifive1-memory.x")).unwrap(); + println!("cargo:rerun-if-changed=memory-lofive-r1.x"); + } other => panic!("Unknown board: {}", other), } diff --git a/ci/script.sh b/ci/script.sh index 29cd4d2..0dd41cd 100755 --- a/ci/script.sh +++ b/ci/script.sh @@ -5,3 +5,4 @@ set -euxo pipefail cargo check --target $TARGET --features 'board-hifive1' cargo check --target $TARGET --features 'board-hifive1-revb' cargo check --target $TARGET --features 'board-lofive' +cargo check --target $TARGET --features 'board-lofive-r1' diff --git a/memory-lofive-r1.x b/memory-lofive-r1.x new file mode 100644 index 0000000..cd55c70 --- /dev/null +++ b/memory-lofive-r1.x @@ -0,0 +1,15 @@ +INCLUDE memory-fe310.x +MEMORY +{ + FLASH : ORIGIN = 0x20000000, LENGTH = 16M +} + +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); + +/* Skip first 4M allocated for bootloader */ +_stext = 0x20400000; diff --git a/src/clock.rs b/src/clock.rs index 22d18df..3081152 100644 --- a/src/clock.rs +++ b/src/clock.rs @@ -21,11 +21,11 @@ pub fn configure(prci: PRCI, aonclk: AONCLK, target_coreclk: Hertz) -> Clocks { Clocks::freeze(coreclk, aonclk) } -#[cfg(feature = "board-lofive")] +#[cfg(any(feature = "board-lofive", feature = "board-lofive-r1"))] /// Configures clock generation system. /// -/// For LoFive board external oscillator is enabled for high-frequency clock. -/// For low-frequency clock internal oscillator is used. +/// For the LoFive and LoFive R1 boards, external oscillator is enabled for +/// high-frequency clock. For low-frequency clock internal oscillator is used. pub fn configure(prci: PRCI, aonclk: AONCLK, target_coreclk: Hertz) -> Clocks { let coreclk = prci.constrain(); let coreclk = coreclk.use_external(Hertz(16_000_000)).coreclk(target_coreclk); From 0f39dd4a936258850959c51edab8c25f2ae25421 Mon Sep 17 00:00:00 2001 From: Vadim Kaushan Date: Wed, 6 Nov 2019 23:02:53 +0300 Subject: [PATCH 083/112] Bump version (0.8.1) --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 84d6b42..3b4d39c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "hifive1" -version = "0.8.0" +version = "0.8.1" repository = "https://github.com/riscv-rust/hifive1" authors = ["David Craven "] categories = ["embedded", "hardware-support", "no-std"] From 3a122cc37c0c77b2158f23b83f119ff1768b27f0 Mon Sep 17 00:00:00 2001 From: PinkNoize <21967246+PinkNoize@users.noreply.github.com> Date: Wed, 25 Dec 2019 23:02:23 -0800 Subject: [PATCH 084/112] Merge pull request #18 from PinkNoize/master Return serial rx half from stdout::configure() --- src/stdout.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/stdout.rs b/src/stdout.rs index 147a605..2626773 100644 --- a/src/stdout.rs +++ b/src/stdout.rs @@ -4,7 +4,7 @@ use core::fmt; use nb::block; use riscv::interrupt; use e310x_hal::{ - serial::{Serial, Tx}, + serial::{Serial, Tx, Rx}, gpio::gpio0::{Pin17, Pin16}, time::Bps, clock::Clocks, @@ -43,17 +43,18 @@ impl core::fmt::Write for SerialWrapper { pub fn configure( uart: UART0, tx: Pin17, rx: Pin16, baud_rate: Bps, clocks: Clocks -) { +) -> Rx { let tx = tx.into_iof0(); let rx = rx.into_iof0(); let serial = Serial::new(uart, (tx, rx), baud_rate, clocks); - let (tx, _) = serial.split(); + let (tx, rx) = serial.split(); interrupt::free(|_| { unsafe { STDOUT.replace(SerialWrapper(tx)); } - }) + }); + return rx; } /// Writes string to stdout From 21afad3cbc95a1341507502390589dd786811ab8 Mon Sep 17 00:00:00 2001 From: Vadim Kaushan Date: Sun, 1 Nov 2020 19:22:39 +0300 Subject: [PATCH 085/112] Update riscv and e310x-hal dependencies --- Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 3b4d39c..206d83c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,9 +10,9 @@ license = "ISC" edition = "2018" [dependencies] -e310x-hal = "0.8.0" +e310x-hal = "0.9.0" embedded-hal = "0.2.3" -riscv = "0.5.3" +riscv = "0.6.0" nb = "0.1.2" [features] From f052443fcd7336871a728ba4d1dcaa72acf14136 Mon Sep 17 00:00:00 2001 From: Vadim Kaushan Date: Sun, 1 Nov 2020 19:27:42 +0300 Subject: [PATCH 086/112] Release v0.9.0 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 206d83c..cc0978d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "hifive1" -version = "0.8.1" +version = "0.9.0" repository = "https://github.com/riscv-rust/hifive1" authors = ["David Craven "] categories = ["embedded", "hardware-support", "no-std"] From 019ee60369cd3e471b42ea11f8789dd26119acba Mon Sep 17 00:00:00 2001 From: Vadim Kaushan Date: Fri, 25 Dec 2020 18:55:42 +0300 Subject: [PATCH 087/112] Implement flash configuration --- assemble.sh | 11 +++++++++++ bin/flash.a | Bin 0 -> 2222 bytes build.rs | 6 ++++++ flash.S | 45 +++++++++++++++++++++++++++++++++++++++++++++ src/flash.rs | 21 +++++++++++++++++++++ src/lib.rs | 2 ++ 6 files changed, 85 insertions(+) create mode 100755 assemble.sh create mode 100644 bin/flash.a create mode 100644 flash.S create mode 100644 src/flash.rs diff --git a/assemble.sh b/assemble.sh new file mode 100755 index 0000000..3a04536 --- /dev/null +++ b/assemble.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +set -euxo pipefail + +# remove existing blobs because otherwise this will append object files to the old blobs +rm -f bin/*.a + +riscv64-unknown-elf-gcc -ggdb3 -fdebug-prefix-map=$(pwd)=/hifive1 -c -mabi=ilp32 -march=rv32imac flash.S -o bin/flash.o +riscv64-unknown-elf-ar crs bin/flash.a bin/flash.o + +rm bin/flash.o diff --git a/bin/flash.a b/bin/flash.a new file mode 100644 index 0000000000000000000000000000000000000000..4c734e21c25daa429a7aced6fcbdaeb1545f37ce GIT binary patch literal 2222 zcma)6&rcIU6n@ifD@7=U5+x#L6-A6@DGS2I5J;>hhUft`Mh~!s0!_+~Y?lU&iNup8 z9zE#IgE2jL@Fs~~JaF{D-=GJNCSFWT)bGuY?Y2PlCG+O{-n{wV%(!+*wA$x#^?q;AU6`@G2Xze*&>k9?qPvU<7iQ!4-Db2dS3wH^45 z+D`x51bxeYxsmv-d^VYkf8R~yYrBuPUPH;E6YxU(O1Hzy@>qhOjxYMEK(qgGv9Hy(+Z`o5bw(E?zoYsc+2PQ~76zws|&2-k8 z8ieypmH8?OKFfq(9dS$UdTw@woyTq-&dfQew;H}Se;KuElW!psHH&b#(ZD`DI&2X> zSTvyX>u1rdhZ}+XmT->Zoe>^F0E_rh)Xkz~Q@u1IL}Ot}T%P4Xgm(d7i0}{sSadi_ z!P}d7x`}6~M@M*%8SIyw>6{Jc#)jdCwRfrU6>~1u!4AfsH={T0Fy=+V&Z7z55R5ya zm&5l(=%uiP&91bPQyGfi^RC8$7D_5qdWfV?90xqqhWX<^a+p2;W^}X6yk12J_e* z5SxKEeeG!jJX$vc!uOWz^0ha0p8~U94vlRSq)$QVd5qgj-OC`{3j}RL(6b)fbF^sP z!AMwCdI%(U`J7)-buF1x|xns<~BCv(Vzk{P_tjF(^pE&eFTL9Vbd+`3F Nd6N*>4rkTt{sl;fv@QSu literal 0 HcmV?d00001 diff --git a/build.rs b/build.rs index a963519..0c9cc96 100644 --- a/build.rs +++ b/build.rs @@ -42,4 +42,10 @@ fn main() { } fs::copy("hifive1-link.x", out_dir.join("hifive1-link.x")).unwrap(); + + // Copy library with flash setup code + let name = env::var("CARGO_PKG_NAME").unwrap(); + fs::copy("bin/flash.a", out_dir.join(format!("lib{}.a", name))).unwrap(); + println!("cargo:rustc-link-lib=static={}", name); + println!("cargo:rerun-if-changed=bin/flash.a"); } diff --git a/flash.S b/flash.S new file mode 100644 index 0000000..53dd795 --- /dev/null +++ b/flash.S @@ -0,0 +1,45 @@ +.cfi_sections .debug_frame + +.section .data._setup_is25lp +.global _setup_is25lp +.cfi_startproc +_setup_is25lp: + li a1, 0x10014000 // QSPI0 base address + + // Disable mapped region + sw zero,96(a1) // fctrl.en = 0 + + // Construct ffmt value for 4 dummy cycles + li a2, 0x00BB1447 + + beqz a0, 2f + + // We need to set 8 dummy cycles instead of 4. + // Issue a "Set Read Parameters" command. + + li a0,2 + sw a0,24(a1) // csmode = HOLD + li a0,0xC0 + sw a0,72(a1) // txdata = 0xC0 + li a0,0xF0 + sw a0,72(a1) // txdata = 0xF0 + sw zero,24(a1) // csmode = AUTO + + // Discard two response bytes +1: lw a0,76(a1) + bltz a0,1b +1: lw a0,76(a1) + bltz a0,1b + + addi a2,a2,0x40 // ffmt: 4 -> 8 dummy cycles +2: + sw a2,100(a1) // Write ffmt + + // Enable mapped region + li a0, 1 + sw a0,96(a1) // fctrl.en = 1 + ret + + +.cfi_endproc +.size _setup_is25lp, . - _setup_is25lp diff --git a/src/flash.rs b/src/flash.rs new file mode 100644 index 0000000..cb2ab58 --- /dev/null +++ b/src/flash.rs @@ -0,0 +1,21 @@ +//! On-board SPI Flash + +use e310x_hal::e310x::QSPI0; +use e310x_hal::clock::Clocks; + +/// Configure SPI Flash interface to maximum supported speed +#[inline(always)] +pub fn configure_spi_flash(qspi: &QSPI0, clocks: &Clocks) { + unsafe { + extern "C" { + fn _setup_is25lp(dummy8: bool); + } + + if clocks.coreclk().0 <= 208_000_000 { + _setup_is25lp(false) + } else { + _setup_is25lp(true) + } + } + qspi.sckdiv.modify(|_, w| unsafe { w.div().bits(0) }); +} diff --git a/src/lib.rs b/src/lib.rs index ea37a19..f47537a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -8,6 +8,8 @@ pub use e310x_hal as hal; pub mod clock; pub use clock::configure as configure_clocks; +pub mod flash; + #[cfg(any(feature = "board-hifive1", feature = "board-hifive1-revb"))] pub mod led; #[cfg(any(feature = "board-hifive1", feature = "board-hifive1-revb"))] From d9413b7d430daff73eda2f91948c9913e15bc98b Mon Sep 17 00:00:00 2001 From: Vadim Kaushan Date: Fri, 25 Dec 2020 19:04:57 +0300 Subject: [PATCH 088/112] Provide LoFive R0 memory definitions --- build.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/build.rs b/build.rs index 0c9cc96..5d647d4 100644 --- a/build.rs +++ b/build.rs @@ -32,8 +32,7 @@ fn main() { fs::copy("memory-hifive1-revb.x", out_dir.join("hifive1-memory.x")).unwrap(); println!("cargo:rerun-if-changed=memory-hifive1-revb.x"); } - "lofive" => {} - "lofive_r1" => { + "lofive" | "lofive_r1" => { fs::copy("memory-lofive-r1.x", out_dir.join("hifive1-memory.x")).unwrap(); println!("cargo:rerun-if-changed=memory-lofive-r1.x"); } From 997743bd5398a27ac303eac1cd67ac019c9b3ffa Mon Sep 17 00:00:00 2001 From: Vadim Kaushan Date: Fri, 25 Dec 2020 19:06:23 +0300 Subject: [PATCH 089/112] Release v0.9.1 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index cc0978d..7832ecf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "hifive1" -version = "0.9.0" +version = "0.9.1" repository = "https://github.com/riscv-rust/hifive1" authors = ["David Craven "] categories = ["embedded", "hardware-support", "no-std"] From dab45aec725596c7fd755a5b6aa9030d2002c4e3 Mon Sep 17 00:00:00 2001 From: Ales Katona Date: Wed, 14 Jul 2021 11:12:40 -0700 Subject: [PATCH 090/112] add SparkFun RED-V board support --- Cargo.toml | 1 + README.md | 8 +++++++ build.rs | 2 +- ci/script.sh | 1 + src/clock.rs | 2 +- src/gpio.rs | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/led.rs | 18 +++++++++++++++ src/lib.rs | 4 +++- 8 files changed, 96 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 7832ecf..514a62b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,6 +18,7 @@ nb = "0.1.2" [features] board-hifive1 = [] board-hifive1-revb = ["e310x-hal/g002"] +board-redv = ["e310x-hal/g002"] board-lofive = [] board-lofive-r1 = ["e310x-hal/g002"] diff --git a/README.md b/README.md index 3c9dfd0..c087cf0 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,14 @@ > Board support crate for HiFive1 and LoFive boards +## Supported Boards + +`hifive1` - use feature `board-hifive1` +`hifive1-revb` - use feature `board-hifive1-revb` +`redv` - use feature `board-redv` +`lofive` - use feature `board-lofive` +`lofive-r1` - use feature `board-lofive-r1` + ## [Documentation](https://docs.rs/crate/hifive1) ## License diff --git a/build.rs b/build.rs index 5d647d4..657ae69 100644 --- a/build.rs +++ b/build.rs @@ -28,7 +28,7 @@ fn main() { fs::copy("memory-hifive1.x", out_dir.join("hifive1-memory.x")).unwrap(); println!("cargo:rerun-if-changed=memory-hifive1.x"); } - "hifive1_revb" => { + "hifive1_revb" | "redv" => { fs::copy("memory-hifive1-revb.x", out_dir.join("hifive1-memory.x")).unwrap(); println!("cargo:rerun-if-changed=memory-hifive1-revb.x"); } diff --git a/ci/script.sh b/ci/script.sh index 0dd41cd..c5bc32b 100755 --- a/ci/script.sh +++ b/ci/script.sh @@ -4,5 +4,6 @@ set -euxo pipefail cargo check --target $TARGET --features 'board-hifive1' cargo check --target $TARGET --features 'board-hifive1-revb' +cargo check --target $TARGET --features 'board-redv' cargo check --target $TARGET --features 'board-lofive' cargo check --target $TARGET --features 'board-lofive-r1' diff --git a/src/clock.rs b/src/clock.rs index 3081152..650bad1 100644 --- a/src/clock.rs +++ b/src/clock.rs @@ -6,7 +6,7 @@ use e310x_hal::{ time::Hertz, }; -#[cfg(any(feature = "board-hifive1", feature = "board-hifive1-revb"))] +#[cfg(any(feature = "board-hifive1", feature = "board-hifive1-revb", feature = "board-redv"))] /// Configures clock generation system. /// /// For HiFive1 and HiFive1 Rev B boards external oscillators are enabled for diff --git a/src/gpio.rs b/src/gpio.rs index 7a3d247..1a12521 100644 --- a/src/gpio.rs +++ b/src/gpio.rs @@ -1,3 +1,4 @@ +#[cfg(any(feature = "board-hifive1", feature = "board-hifive1-revb"))] /// /// Returns single pin for given gpio object mapped accordingly /// @@ -58,7 +59,69 @@ macro_rules! pin { ($gpio:ident, led_red) => { $gpio.pin22 }; ($gpio:ident, led_green) => { $gpio.pin19 }; ($gpio:ident, led_blue) => { $gpio.pin21 }; + // #[cfg(feature = "redv")] + // ($gpio:ident, led_blue) => { $gpio.pin4 }; +} +#[cfg(feature = "board-redv")] +/// +/// Returns single pin for given gpio object mapped accordingly +/// +/// # Mappings +/// +/// - `spi0_` — SPI pins where `` is one of (`sck`, `mosi`, `miso`, `ss0`, `ss2`, `ss3`) +/// - `i2c0_` — I2C pins where `` is one of (`sda`, `scl`) +/// - `uart0_` — UART pins where `` is one of (`tx`, `rx`) +/// - `dig#` — Digital/physical pins on the board where `#` is from range 0..19 +/// - `led_` - Internal LED light pins where `` is one of (`red`, `green`, `blue`) +/// +/// # Example +/// +/// ``` +/// let mosi = pin!(gpio, spi0_mosi); // gpio.pin3 +/// ``` +/// +#[macro_export] +macro_rules! pin { + // empty + ($gpio:ident, none) => { () }; + // spi + ($gpio:ident, spi0_sck) => { $gpio.pin5 }; + ($gpio:ident, spi0_mosi) => { $gpio.pin3 }; + ($gpio:ident, spi0_miso) => { $gpio.pin4 }; + ($gpio:ident, spi0_ss0) => { $gpio.pin2 }; + // spi_ss1 is not documented + ($gpio:ident, spi0_ss2) => { $gpio.pin9 }; + ($gpio:ident, spi0_ss3) => { $gpio.pin10 }; + // i2c + ($gpio:ident, i2c0_sda) => { $gpio.pin12 }; + ($gpio:ident, i2c0_scl) => { $gpio.pin13 }; + // serial + ($gpio:ident, uart0_tx) => { $gpio.pin17 }; + ($gpio:ident, uart0_rx) => { $gpio.pin16 }; + // digital/physical + ($gpio:ident, dig0) => { $gpio.pin16 }; + ($gpio:ident, dig1) => { $gpio.pin17 }; + ($gpio:ident, dig2) => { $gpio.pin18 }; + ($gpio:ident, dig3) => { $gpio.pin19 }; + ($gpio:ident, dig4) => { $gpio.pin20 }; + ($gpio:ident, dig5) => { $gpio.pin21 }; + ($gpio:ident, dig6) => { $gpio.pin22 }; + ($gpio:ident, dig7) => { $gpio.pin23 }; + ($gpio:ident, dig8) => { $gpio.pin0 }; + ($gpio:ident, dig9) => { $gpio.pin1 }; + ($gpio:ident, dig10) => { $gpio.pin2 }; + ($gpio:ident, dig11) => { $gpio.pin3 }; + ($gpio:ident, dig12) => { $gpio.pin4 }; + ($gpio:ident, dig13) => { $gpio.pin5 }; + ($gpio:ident, dig14) => { $gpio.pin8 }; // tested + ($gpio:ident, dig15) => { $gpio.pin9 }; + ($gpio:ident, dig16) => { $gpio.pin10 }; + ($gpio:ident, dig17) => { $gpio.pin11 }; + ($gpio:ident, dig18) => { $gpio.pin12 }; + ($gpio:ident, dig19) => { $gpio.pin13 }; + // onboard LEDs + ($gpio:ident, led_blue) => { $gpio.pin4 }; } /// diff --git a/src/led.rs b/src/led.rs index 9686f5d..e85380f 100644 --- a/src/led.rs +++ b/src/led.rs @@ -1,21 +1,37 @@ //! On-board user LEDs //! +//! Hifive1 (+ revB) //! - Red = Pin 22 //! - Green = Pin 19 //! - Blue = Pin 21 +//! +//! RedV +//! - Blue = Pin 4 + use embedded_hal::digital::v2::OutputPin; +#[cfg(any(feature = "board-hifive1", feature = "board-hifive1-revb"))] use e310x_hal::gpio::gpio0::{Pin19, Pin21, Pin22}; +#[cfg(feature = "board-redv")] +use e310x_hal::gpio::gpio0::{Pin4}; use e310x_hal::gpio::{Output, Regular, Invert}; +#[cfg(any(feature = "board-hifive1", feature = "board-hifive1-revb"))] /// Red LED pub type RED = Pin22>>; +#[cfg(any(feature = "board-hifive1", feature = "board-hifive1-revb"))] /// Green LED pub type GREEN = Pin19>>; +#[cfg(any(feature = "board-hifive1", feature = "board-hifive1-revb"))] /// Blue LED pub type BLUE = Pin21>>; +#[cfg(feature = "board-redv")] +/// Blue LED +pub type BLUE = Pin4>>; + +#[cfg(any(feature = "board-hifive1", feature = "board-hifive1-revb"))] /// Returns RED, GREEN and BLUE LEDs. pub fn rgb( red: Pin22, green: Pin19, blue: Pin21 @@ -36,6 +52,7 @@ pub trait Led { fn on(&mut self); } +#[cfg(any(feature = "board-hifive1", feature = "board-hifive1-revb"))] impl Led for RED { fn off(&mut self) { self.set_low().unwrap(); @@ -46,6 +63,7 @@ impl Led for RED { } } +#[cfg(any(feature = "board-hifive1", feature = "board-hifive1-revb"))] impl Led for GREEN { fn off(&mut self) { self.set_low().unwrap(); diff --git a/src/lib.rs b/src/lib.rs index f47537a..59f9e1f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -10,10 +10,12 @@ pub use clock::configure as configure_clocks; pub mod flash; -#[cfg(any(feature = "board-hifive1", feature = "board-hifive1-revb"))] +#[cfg(any(feature = "board-hifive1", feature = "board-hifive1-revb", feature = "board-redv"))] pub mod led; #[cfg(any(feature = "board-hifive1", feature = "board-hifive1-revb"))] pub use led::{RED, GREEN, BLUE, rgb, Led}; +#[cfg(feature = "board-redv")] +pub use led::{BLUE, Led}; pub mod stdout; pub use stdout::configure as configure_stdout; From 5aca858d892ffabb116912edda44db851533125b Mon Sep 17 00:00:00 2001 From: Ales Katona Date: Wed, 14 Jul 2021 11:14:14 -0700 Subject: [PATCH 091/112] remove unused comment --- src/gpio.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/gpio.rs b/src/gpio.rs index 1a12521..39a2ef4 100644 --- a/src/gpio.rs +++ b/src/gpio.rs @@ -59,8 +59,6 @@ macro_rules! pin { ($gpio:ident, led_red) => { $gpio.pin22 }; ($gpio:ident, led_green) => { $gpio.pin19 }; ($gpio:ident, led_blue) => { $gpio.pin21 }; - // #[cfg(feature = "redv")] - // ($gpio:ident, led_blue) => { $gpio.pin4 }; } #[cfg(feature = "board-redv")] From 7a66069eaa8b6eeedec7e621ececa1188b87c95e Mon Sep 17 00:00:00 2001 From: Ales Katona Date: Wed, 14 Jul 2021 11:24:04 -0700 Subject: [PATCH 092/112] fix Pin4 -> Pin5 typo + fmt --- build.rs | 18 ++-- src/clock.rs | 18 +++- src/flash.rs | 2 +- src/gpio.rs | 294 ++++++++++++++++++++++++++++++++++++-------------- src/led.rs | 17 ++- src/lib.rs | 10 +- src/stdout.rs | 27 +++-- 7 files changed, 264 insertions(+), 122 deletions(-) diff --git a/build.rs b/build.rs index 657ae69..e731326 100644 --- a/build.rs +++ b/build.rs @@ -1,18 +1,20 @@ -use std::{env, fs}; use std::path::PathBuf; +use std::{env, fs}; fn main() { // Put the memory definitions somewhere the linker can find it let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap()); println!("cargo:rustc-link-search={}", out_dir.display()); - let boards: Vec<_> = env::vars().filter_map(|(key, _value)| { - if key.starts_with("CARGO_FEATURE_BOARD") { - Some(key[20..].to_ascii_lowercase()) // Strip 'CARGO_FEATURE_BOARD_' - } else { - None - } - }).collect(); + let boards: Vec<_> = env::vars() + .filter_map(|(key, _value)| { + if key.starts_with("CARGO_FEATURE_BOARD") { + Some(key[20..].to_ascii_lowercase()) // Strip 'CARGO_FEATURE_BOARD_' + } else { + None + } + }) + .collect(); if boards.is_empty() { panic!("No board features selected"); diff --git a/src/clock.rs b/src/clock.rs index 650bad1..05bd348 100644 --- a/src/clock.rs +++ b/src/clock.rs @@ -1,19 +1,25 @@ //! Board-specific clock configuration use e310x_hal::{ - e310x::{PRCI, AONCLK}, - clock::{Clocks, PrciExt, AonExt}, + clock::{AonExt, Clocks, PrciExt}, + e310x::{AONCLK, PRCI}, time::Hertz, }; -#[cfg(any(feature = "board-hifive1", feature = "board-hifive1-revb", feature = "board-redv"))] +#[cfg(any( + feature = "board-hifive1", + feature = "board-hifive1-revb", + feature = "board-redv" +))] /// Configures clock generation system. /// /// For HiFive1 and HiFive1 Rev B boards external oscillators are enabled for /// both high-frequency and low-frequency clocks. pub fn configure(prci: PRCI, aonclk: AONCLK, target_coreclk: Hertz) -> Clocks { let coreclk = prci.constrain(); - let coreclk = coreclk.use_external(Hertz(16_000_000)).coreclk(target_coreclk); + let coreclk = coreclk + .use_external(Hertz(16_000_000)) + .coreclk(target_coreclk); let aonclk = aonclk.constrain(); let aonclk = aonclk.use_external(Hertz(32_768)); @@ -28,7 +34,9 @@ pub fn configure(prci: PRCI, aonclk: AONCLK, target_coreclk: Hertz) -> Clocks { /// high-frequency clock. For low-frequency clock internal oscillator is used. pub fn configure(prci: PRCI, aonclk: AONCLK, target_coreclk: Hertz) -> Clocks { let coreclk = prci.constrain(); - let coreclk = coreclk.use_external(Hertz(16_000_000)).coreclk(target_coreclk); + let coreclk = coreclk + .use_external(Hertz(16_000_000)) + .coreclk(target_coreclk); let aonclk = aonclk.constrain(); diff --git a/src/flash.rs b/src/flash.rs index cb2ab58..e138c99 100644 --- a/src/flash.rs +++ b/src/flash.rs @@ -1,7 +1,7 @@ //! On-board SPI Flash -use e310x_hal::e310x::QSPI0; use e310x_hal::clock::Clocks; +use e310x_hal::e310x::QSPI0; /// Configure SPI Flash interface to maximum supported speed #[inline(always)] diff --git a/src/gpio.rs b/src/gpio.rs index 39a2ef4..4ba26e8 100644 --- a/src/gpio.rs +++ b/src/gpio.rs @@ -1,146 +1,278 @@ #[cfg(any(feature = "board-hifive1", feature = "board-hifive1-revb"))] /// /// Returns single pin for given gpio object mapped accordingly -/// +/// /// # Mappings -/// +/// /// - `spi0_` — SPI pins where `` is one of (`sck`, `mosi`, `miso`, `ss0`, `ss2`, `ss3`) /// - `i2c0_` — I2C pins where `` is one of (`sda`, `scl`) /// - `uart0_` — UART pins where `` is one of (`tx`, `rx`) /// - `dig#` — Digital/physical pins on the board where `#` is from range 0..19 /// - `led_` - Internal LED light pins where `` is one of (`red`, `green`, `blue`) -/// +/// /// # Example -/// +/// /// ``` /// let mosi = pin!(gpio, spi0_mosi); // gpio.pin3 /// ``` -/// +/// #[macro_export] macro_rules! pin { // empty - ($gpio:ident, none) => { () }; + ($gpio:ident, none) => { + () + }; // spi - ($gpio:ident, spi0_sck) => { $gpio.pin5 }; - ($gpio:ident, spi0_mosi) => { $gpio.pin3 }; - ($gpio:ident, spi0_miso) => { $gpio.pin4 }; - ($gpio:ident, spi0_ss0) => { $gpio.pin2 }; + ($gpio:ident, spi0_sck) => { + $gpio.pin5 + }; + ($gpio:ident, spi0_mosi) => { + $gpio.pin3 + }; + ($gpio:ident, spi0_miso) => { + $gpio.pin4 + }; + ($gpio:ident, spi0_ss0) => { + $gpio.pin2 + }; // spi_ss1 is not documented - ($gpio:ident, spi0_ss2) => { $gpio.pin9 }; - ($gpio:ident, spi0_ss3) => { $gpio.pin10 }; + ($gpio:ident, spi0_ss2) => { + $gpio.pin9 + }; + ($gpio:ident, spi0_ss3) => { + $gpio.pin10 + }; // i2c - ($gpio:ident, i2c0_sda) => { $gpio.pin12 }; - ($gpio:ident, i2c0_scl) => { $gpio.pin13 }; + ($gpio:ident, i2c0_sda) => { + $gpio.pin12 + }; + ($gpio:ident, i2c0_scl) => { + $gpio.pin13 + }; // serial - ($gpio:ident, uart0_tx) => { $gpio.pin17 }; - ($gpio:ident, uart0_rx) => { $gpio.pin16 }; + ($gpio:ident, uart0_tx) => { + $gpio.pin17 + }; + ($gpio:ident, uart0_rx) => { + $gpio.pin16 + }; // digital/physical - ($gpio:ident, dig0) => { $gpio.pin16 }; - ($gpio:ident, dig1) => { $gpio.pin17 }; - ($gpio:ident, dig2) => { $gpio.pin18 }; - ($gpio:ident, dig3) => { $gpio.pin19 }; - ($gpio:ident, dig4) => { $gpio.pin20 }; - ($gpio:ident, dig5) => { $gpio.pin21 }; - ($gpio:ident, dig6) => { $gpio.pin22 }; - ($gpio:ident, dig7) => { $gpio.pin23 }; - ($gpio:ident, dig8) => { $gpio.pin0 }; - ($gpio:ident, dig9) => { $gpio.pin1 }; - ($gpio:ident, dig10) => { $gpio.pin2 }; - ($gpio:ident, dig11) => { $gpio.pin3 }; - ($gpio:ident, dig12) => { $gpio.pin4 }; - ($gpio:ident, dig13) => { $gpio.pin5 }; - ($gpio:ident, dig14) => { $gpio.pin8 }; // tested - ($gpio:ident, dig15) => { $gpio.pin9 }; - ($gpio:ident, dig16) => { $gpio.pin10 }; - ($gpio:ident, dig17) => { $gpio.pin11 }; - ($gpio:ident, dig18) => { $gpio.pin12 }; - ($gpio:ident, dig19) => { $gpio.pin13 }; + ($gpio:ident, dig0) => { + $gpio.pin16 + }; + ($gpio:ident, dig1) => { + $gpio.pin17 + }; + ($gpio:ident, dig2) => { + $gpio.pin18 + }; + ($gpio:ident, dig3) => { + $gpio.pin19 + }; + ($gpio:ident, dig4) => { + $gpio.pin20 + }; + ($gpio:ident, dig5) => { + $gpio.pin21 + }; + ($gpio:ident, dig6) => { + $gpio.pin22 + }; + ($gpio:ident, dig7) => { + $gpio.pin23 + }; + ($gpio:ident, dig8) => { + $gpio.pin0 + }; + ($gpio:ident, dig9) => { + $gpio.pin1 + }; + ($gpio:ident, dig10) => { + $gpio.pin2 + }; + ($gpio:ident, dig11) => { + $gpio.pin3 + }; + ($gpio:ident, dig12) => { + $gpio.pin4 + }; + ($gpio:ident, dig13) => { + $gpio.pin5 + }; + ($gpio:ident, dig14) => { + $gpio.pin8 + }; // tested + ($gpio:ident, dig15) => { + $gpio.pin9 + }; + ($gpio:ident, dig16) => { + $gpio.pin10 + }; + ($gpio:ident, dig17) => { + $gpio.pin11 + }; + ($gpio:ident, dig18) => { + $gpio.pin12 + }; + ($gpio:ident, dig19) => { + $gpio.pin13 + }; // onboard LEDs - ($gpio:ident, led_red) => { $gpio.pin22 }; - ($gpio:ident, led_green) => { $gpio.pin19 }; - ($gpio:ident, led_blue) => { $gpio.pin21 }; + ($gpio:ident, led_red) => { + $gpio.pin22 + }; + ($gpio:ident, led_green) => { + $gpio.pin19 + }; + ($gpio:ident, led_blue) => { + $gpio.pin21 + }; } #[cfg(feature = "board-redv")] /// /// Returns single pin for given gpio object mapped accordingly -/// +/// /// # Mappings -/// +/// /// - `spi0_` — SPI pins where `` is one of (`sck`, `mosi`, `miso`, `ss0`, `ss2`, `ss3`) /// - `i2c0_` — I2C pins where `` is one of (`sda`, `scl`) /// - `uart0_` — UART pins where `` is one of (`tx`, `rx`) /// - `dig#` — Digital/physical pins on the board where `#` is from range 0..19 /// - `led_` - Internal LED light pins where `` is one of (`red`, `green`, `blue`) -/// +/// /// # Example -/// +/// /// ``` /// let mosi = pin!(gpio, spi0_mosi); // gpio.pin3 /// ``` -/// +/// #[macro_export] macro_rules! pin { // empty - ($gpio:ident, none) => { () }; + ($gpio:ident, none) => { + () + }; // spi - ($gpio:ident, spi0_sck) => { $gpio.pin5 }; - ($gpio:ident, spi0_mosi) => { $gpio.pin3 }; - ($gpio:ident, spi0_miso) => { $gpio.pin4 }; - ($gpio:ident, spi0_ss0) => { $gpio.pin2 }; + ($gpio:ident, spi0_sck) => { + $gpio.pin5 + }; + ($gpio:ident, spi0_mosi) => { + $gpio.pin3 + }; + ($gpio:ident, spi0_miso) => { + $gpio.pin4 + }; + ($gpio:ident, spi0_ss0) => { + $gpio.pin2 + }; // spi_ss1 is not documented - ($gpio:ident, spi0_ss2) => { $gpio.pin9 }; - ($gpio:ident, spi0_ss3) => { $gpio.pin10 }; + ($gpio:ident, spi0_ss2) => { + $gpio.pin9 + }; + ($gpio:ident, spi0_ss3) => { + $gpio.pin10 + }; // i2c - ($gpio:ident, i2c0_sda) => { $gpio.pin12 }; - ($gpio:ident, i2c0_scl) => { $gpio.pin13 }; + ($gpio:ident, i2c0_sda) => { + $gpio.pin12 + }; + ($gpio:ident, i2c0_scl) => { + $gpio.pin13 + }; // serial - ($gpio:ident, uart0_tx) => { $gpio.pin17 }; - ($gpio:ident, uart0_rx) => { $gpio.pin16 }; + ($gpio:ident, uart0_tx) => { + $gpio.pin17 + }; + ($gpio:ident, uart0_rx) => { + $gpio.pin16 + }; // digital/physical - ($gpio:ident, dig0) => { $gpio.pin16 }; - ($gpio:ident, dig1) => { $gpio.pin17 }; - ($gpio:ident, dig2) => { $gpio.pin18 }; - ($gpio:ident, dig3) => { $gpio.pin19 }; - ($gpio:ident, dig4) => { $gpio.pin20 }; - ($gpio:ident, dig5) => { $gpio.pin21 }; - ($gpio:ident, dig6) => { $gpio.pin22 }; - ($gpio:ident, dig7) => { $gpio.pin23 }; - ($gpio:ident, dig8) => { $gpio.pin0 }; - ($gpio:ident, dig9) => { $gpio.pin1 }; - ($gpio:ident, dig10) => { $gpio.pin2 }; - ($gpio:ident, dig11) => { $gpio.pin3 }; - ($gpio:ident, dig12) => { $gpio.pin4 }; - ($gpio:ident, dig13) => { $gpio.pin5 }; - ($gpio:ident, dig14) => { $gpio.pin8 }; // tested - ($gpio:ident, dig15) => { $gpio.pin9 }; - ($gpio:ident, dig16) => { $gpio.pin10 }; - ($gpio:ident, dig17) => { $gpio.pin11 }; - ($gpio:ident, dig18) => { $gpio.pin12 }; - ($gpio:ident, dig19) => { $gpio.pin13 }; + ($gpio:ident, dig0) => { + $gpio.pin16 + }; + ($gpio:ident, dig1) => { + $gpio.pin17 + }; + ($gpio:ident, dig2) => { + $gpio.pin18 + }; + ($gpio:ident, dig3) => { + $gpio.pin19 + }; + ($gpio:ident, dig4) => { + $gpio.pin20 + }; + ($gpio:ident, dig5) => { + $gpio.pin21 + }; + ($gpio:ident, dig6) => { + $gpio.pin22 + }; + ($gpio:ident, dig7) => { + $gpio.pin23 + }; + ($gpio:ident, dig8) => { + $gpio.pin0 + }; + ($gpio:ident, dig9) => { + $gpio.pin1 + }; + ($gpio:ident, dig10) => { + $gpio.pin2 + }; + ($gpio:ident, dig11) => { + $gpio.pin3 + }; + ($gpio:ident, dig12) => { + $gpio.pin4 + }; + ($gpio:ident, dig13) => { + $gpio.pin5 + }; + ($gpio:ident, dig14) => { + $gpio.pin8 + }; // tested + ($gpio:ident, dig15) => { + $gpio.pin9 + }; + ($gpio:ident, dig16) => { + $gpio.pin10 + }; + ($gpio:ident, dig17) => { + $gpio.pin11 + }; + ($gpio:ident, dig18) => { + $gpio.pin12 + }; + ($gpio:ident, dig19) => { + $gpio.pin13 + }; // onboard LEDs - ($gpio:ident, led_blue) => { $gpio.pin4 }; + ($gpio:ident, led_blue) => { + $gpio.pin5 + }; } /// /// Returns tuple of pins for given gpio object mapped accordingly -/// +/// /// # Mappings -/// +/// /// - `none` — Returns `()` for empty pin if needed in tuple /// - `spi0_` — SPI pins where `` is one of (`sck`, `mosi`, `miso`, `ss0`, `ss2`, `ss3`) /// - `i2c0_` — I2C pins where `` is one of (`sda`, `scl`) /// - `uart0_` — UART pins where `` is one of (`tx`, `rx`) /// - `dig#` — Digital/physical pins on the board where `#` is from range 0..19 /// - `led_` - Internal LED light pins `` is one of (`red`, `green`, `blue`) -/// +/// /// # Example -/// +/// /// ``` /// let (mosi, miso, sck, cs) = pins!(gpio, (spi0_mosi, spi0_miso, spi0_sck, spi0_ss0)); /// // (gpio.pin3, gpio.pin4, gpio.pin5, gpio.pin2) /// ``` -/// +/// #[macro_export] macro_rules! pins { ( $gpio:ident, ($($name:ident),+) ) => { diff --git a/src/led.rs b/src/led.rs index e85380f..d2c1b27 100644 --- a/src/led.rs +++ b/src/led.rs @@ -6,14 +6,14 @@ //! - Blue = Pin 21 //! //! RedV -//! - Blue = Pin 4 +//! - Blue = Pin 5 -use embedded_hal::digital::v2::OutputPin; +#[cfg(feature = "board-redv")] +use e310x_hal::gpio::gpio0::Pin5; #[cfg(any(feature = "board-hifive1", feature = "board-hifive1-revb"))] use e310x_hal::gpio::gpio0::{Pin19, Pin21, Pin22}; -#[cfg(feature = "board-redv")] -use e310x_hal::gpio::gpio0::{Pin4}; -use e310x_hal::gpio::{Output, Regular, Invert}; +use e310x_hal::gpio::{Invert, Output, Regular}; +use embedded_hal::digital::v2::OutputPin; #[cfg(any(feature = "board-hifive1", feature = "board-hifive1-revb"))] /// Red LED @@ -29,14 +29,11 @@ pub type BLUE = Pin21>>; #[cfg(feature = "board-redv")] /// Blue LED -pub type BLUE = Pin4>>; +pub type BLUE = Pin5>>; #[cfg(any(feature = "board-hifive1", feature = "board-hifive1-revb"))] /// Returns RED, GREEN and BLUE LEDs. -pub fn rgb( - red: Pin22, green: Pin19, blue: Pin21 -) -> (RED, GREEN, BLUE) -{ +pub fn rgb(red: Pin22, green: Pin19, blue: Pin21) -> (RED, GREEN, BLUE) { let red: RED = red.into_inverted_output(); let green: GREEN = green.into_inverted_output(); let blue: BLUE = blue.into_inverted_output(); diff --git a/src/lib.rs b/src/lib.rs index 59f9e1f..9ed422b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -10,12 +10,16 @@ pub use clock::configure as configure_clocks; pub mod flash; -#[cfg(any(feature = "board-hifive1", feature = "board-hifive1-revb", feature = "board-redv"))] +#[cfg(any( + feature = "board-hifive1", + feature = "board-hifive1-revb", + feature = "board-redv" +))] pub mod led; #[cfg(any(feature = "board-hifive1", feature = "board-hifive1-revb"))] -pub use led::{RED, GREEN, BLUE, rgb, Led}; +pub use led::{rgb, Led, BLUE, GREEN, RED}; #[cfg(feature = "board-redv")] -pub use led::{BLUE, Led}; +pub use led::{Led, BLUE}; pub mod stdout; pub use stdout::configure as configure_stdout; diff --git a/src/stdout.rs b/src/stdout.rs index 2626773..e683f36 100644 --- a/src/stdout.rs +++ b/src/stdout.rs @@ -1,21 +1,19 @@ //! Stdout based on the UART hooked up to FTDI or J-Link use core::fmt; -use nb::block; -use riscv::interrupt; use e310x_hal::{ - serial::{Serial, Tx, Rx}, - gpio::gpio0::{Pin17, Pin16}, - time::Bps, clock::Clocks, e310x::UART0, - prelude::* + gpio::gpio0::{Pin16, Pin17}, + prelude::*, + serial::{Rx, Serial, Tx}, + time::Bps, }; - +use nb::block; +use riscv::interrupt; static mut STDOUT: Option = None; - struct SerialWrapper(Tx); impl core::fmt::Write for SerialWrapper { @@ -41,18 +39,19 @@ impl core::fmt::Write for SerialWrapper { /// Configures stdout pub fn configure( - uart: UART0, tx: Pin17, rx: Pin16, - baud_rate: Bps, clocks: Clocks + uart: UART0, + tx: Pin17, + rx: Pin16, + baud_rate: Bps, + clocks: Clocks, ) -> Rx { let tx = tx.into_iof0(); let rx = rx.into_iof0(); let serial = Serial::new(uart, (tx, rx), baud_rate, clocks); let (tx, rx) = serial.split(); - interrupt::free(|_| { - unsafe { - STDOUT.replace(SerialWrapper(tx)); - } + interrupt::free(|_| unsafe { + STDOUT.replace(SerialWrapper(tx)); }); return rx; } From e5daaee8cd326b65488ccebb797723680cd30837 Mon Sep 17 00:00:00 2001 From: Ales Katona Date: Thu, 15 Jul 2021 09:53:16 -0700 Subject: [PATCH 093/112] fix formatting --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index c087cf0..dc0fe8d 100644 --- a/README.md +++ b/README.md @@ -8,11 +8,11 @@ ## Supported Boards -`hifive1` - use feature `board-hifive1` -`hifive1-revb` - use feature `board-hifive1-revb` -`redv` - use feature `board-redv` -`lofive` - use feature `board-lofive` -`lofive-r1` - use feature `board-lofive-r1` +* `hifive1` - use feature `board-hifive1` +* `hifive1-revb` - use feature `board-hifive1-revb` +* `redv` - use feature `board-redv` +* `lofive` - use feature `board-lofive` +* `lofive-r1` - use feature `board-lofive-r1` ## [Documentation](https://docs.rs/crate/hifive1) From ef0d173a04d8af490caf8869d50a1706f4ef52d6 Mon Sep 17 00:00:00 2001 From: Ales Katona Date: Thu, 15 Jul 2021 09:53:26 -0700 Subject: [PATCH 094/112] update nb to v1.0.0 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 514a62b..b0976fc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,7 +13,7 @@ edition = "2018" e310x-hal = "0.9.0" embedded-hal = "0.2.3" riscv = "0.6.0" -nb = "0.1.2" +nb = "1.0.0" [features] board-hifive1 = [] From ba4fd96caaeb34b0b8d0c33430bd1c4d15b403a5 Mon Sep 17 00:00:00 2001 From: Ales Katona Date: Thu, 15 Jul 2021 10:35:23 -0700 Subject: [PATCH 095/112] use full board names with links --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index dc0fe8d..a16a2e4 100644 --- a/README.md +++ b/README.md @@ -8,11 +8,11 @@ ## Supported Boards -* `hifive1` - use feature `board-hifive1` -* `hifive1-revb` - use feature `board-hifive1-revb` -* `redv` - use feature `board-redv` -* `lofive` - use feature `board-lofive` -* `lofive-r1` - use feature `board-lofive-r1` +* [SiFive Hifive1](https://www.sifive.com/boards/hifive1) - use feature `board-hifive1` +* [SiFive Hifive1 RevB](https://www.sifive.com/boards/hifive1-rev-b) - use feature `board-hifive1-revb` +* [SparkFun Red-V RedBoard](https://www.sparkfun.com/products/15594) - use feature `board-redv` +* [lofive1](https://github.com/mwelling/lofive) - use feature `board-lofive` +* [lofive1-r1](https://github.com/mwelling/lofive) - use feature `board-lofive-r1` ## [Documentation](https://docs.rs/crate/hifive1) From 46f2222a28ea80aca9a4103c10cce6e715d28178 Mon Sep 17 00:00:00 2001 From: Ales Katona Date: Thu, 15 Jul 2021 16:22:24 -0700 Subject: [PATCH 096/112] update dependencies --- Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index b0976fc..9a1aad2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,8 +10,8 @@ license = "ISC" edition = "2018" [dependencies] -e310x-hal = "0.9.0" -embedded-hal = "0.2.3" +e310x-hal = "0.9.1" +embedded-hal = "0.2.5" riscv = "0.6.0" nb = "1.0.0" From f0675d387b839c4b61019c7498e0e91ef713ef35 Mon Sep 17 00:00:00 2001 From: Ales Katona Date: Thu, 15 Jul 2021 16:22:33 -0700 Subject: [PATCH 097/112] bump version to v0.9.2 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 9a1aad2..d2da503 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "hifive1" -version = "0.9.1" +version = "0.9.2" repository = "https://github.com/riscv-rust/hifive1" authors = ["David Craven "] categories = ["embedded", "hardware-support", "no-std"] From fcc3f79fc6ab511604fffa9b434e3392aaabf648 Mon Sep 17 00:00:00 2001 From: Ales Katona Date: Thu, 15 Jul 2021 16:25:51 -0700 Subject: [PATCH 098/112] add CHANGELOG --- CHANGELOG.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..4df48f2 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,14 @@ +# Change Log + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](http://keepachangelog.com/) +and this project adheres to [Semantic Versioning](http://semver.org/). + +## [Unreleased] + +## [v0.10.0] - 2021-07-15 + +### Added + +- Added [SparkFun Red-V RedBoard](https://www.sparkfun.com/products/15594)` support From 4a81fd8015d21ebde7d9eea4a14b251cb59d78c2 Mon Sep 17 00:00:00 2001 From: Ales Katona Date: Thu, 15 Jul 2021 16:25:59 -0700 Subject: [PATCH 099/112] use v0.10.0 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index d2da503..601da86 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "hifive1" -version = "0.9.2" +version = "0.10.0" repository = "https://github.com/riscv-rust/hifive1" authors = ["David Craven "] categories = ["embedded", "hardware-support", "no-std"] From 19d97710d7a39aa6614ecc96647ea53bee6210e0 Mon Sep 17 00:00:00 2001 From: Ales Katona Date: Tue, 20 Jul 2021 09:17:16 -0700 Subject: [PATCH 100/112] use GHA --- .github/bors.toml | 8 +++- .github/workflows/ci.yaml | 82 ++++++++++++++++++++++++++++++++++ .github/workflows/rustfmt.yaml | 24 ++++++++++ README.md | 5 +++ ci/install.sh | 5 --- ci/script.sh | 9 ---- 6 files changed, 118 insertions(+), 15 deletions(-) create mode 100644 .github/workflows/ci.yaml create mode 100644 .github/workflows/rustfmt.yaml delete mode 100755 ci/install.sh delete mode 100755 ci/script.sh diff --git a/.github/bors.toml b/.github/bors.toml index ca42be0..b5b4935 100644 --- a/.github/bors.toml +++ b/.github/bors.toml @@ -1,4 +1,10 @@ block_labels = ["needs-decision"] delete_merged_branches = true required_approvals = 1 -status = ["continuous-integration/travis-ci/push"] +status = [ + "ci-linux (stable)", + "ci-linux (1.42.0)", + "build-other (macOS-latest)", + "build-other (windows-latest)", + "Rustfmt" +] diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml new file mode 100644 index 0000000..bdb839f --- /dev/null +++ b/.github/workflows/ci.yaml @@ -0,0 +1,82 @@ +on: + push: + branches: [ staging, trying, master ] + pull_request: + +name: Continuous integration + +jobs: + ci-linux: + runs-on: ubuntu-20.04 + continue-on-error: ${{ matrix.experimental || false }} + strategy: + matrix: + # All generated code should be running on stable now, MRSV is 1.42.0 + rust: [nightly, stable, 1.42.0] + + include: + # Nightly is only for reference and allowed to fail + - rust: nightly + experimental: true + + steps: + - uses: actions/checkout@v2 + - uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: ${{ matrix.rust }} + override: true + - name: Install all Rust targets for ${{ matrix.rust }} + run: rustup target install --toolchain=${{ matrix.rust }} x86_64-unknown-linux-gnu riscv32imac-unknown-none-elf riscv64imac-unknown-none-elf riscv64gc-unknown-none-elf + - name: Run CI script for x86_64-unknown-linux-gnu under ${{ matrix.rust }} + run: | + cargo check --target x86_64-unknown-linux-gnu --features board-hifive1 + cargo check --target x86_64-unknown-linux-gnu --features board-hifive1-revb + cargo check --target x86_64-unknown-linux-gnu --features board-redv + cargo check --target x86_64-unknown-linux-gnu --features board-lofive + cargo check --target x86_64-unknown-linux-gnu --features board-lofive-r1 + - name: Run CI script for riscv32imac-unknown-none-elf under ${{ matrix.rust }} + run: | + cargo check --target riscv32imac-unknown-none-elf --features board-hifive1 + cargo check --target riscv32imac-unknown-none-elf --features board-hifive1-revb + cargo check --target riscv32imac-unknown-none-elf --features board-redv + cargo check --target riscv32imac-unknown-none-elf --features board-lofive + cargo check --target riscv32imac-unknown-none-elf --features board-lofive-r1 + - name: Run CI script for riscv64imac-unknown-none-elf under ${{ matrix.rust }} + run: | + cargo check --target riscv64imac-unknown-none-elf --features board-hifive1 + cargo check --target riscv64imac-unknown-none-elf --features board-hifive1-revb + cargo check --target riscv64imac-unknown-none-elf --features board-redv + cargo check --target riscv64imac-unknown-none-elf --features board-lofive + cargo check --target riscv64imac-unknown-none-elf --features board-lofive-r1 + - name: Run CI script for riscv64gc-unknown-none-elf under ${{ matrix.rust }} + run: | + cargo check --target riscv64gc-unknown-none-elf --features board-hifive1 + cargo check --target riscv64gc-unknown-none-elf --features board-hifive1-revb + cargo check --target riscv64gc-unknown-none-elf --features board-redv + cargo check --target riscv64gc-unknown-none-elf --features board-lofive + cargo check --target riscv64gc-unknown-none-elf --features board-lofive-r1 + + # On macOS and Windows, we at least make sure that the crate builds and links. + build-other: + strategy: + matrix: + os: + - macOS-latest + - windows-latest + runs-on: ${{ matrix.os }} + + steps: + - uses: actions/checkout@v2 + - uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: stable + override: true + - name: Build crate for host OS + run: | + cargo build --features board-hifive1 + cargo build --features board-hifive1-revb + cargo build --features board-redv + cargo build --features board-lofive + cargo build --features board-lofive-r1 \ No newline at end of file diff --git a/.github/workflows/rustfmt.yaml b/.github/workflows/rustfmt.yaml new file mode 100644 index 0000000..0727384 --- /dev/null +++ b/.github/workflows/rustfmt.yaml @@ -0,0 +1,24 @@ + +on: + push: + branches: [ staging, trying, master ] + pull_request: + +name: Code formatting check + +jobs: + fmt: + name: Rustfmt + runs-on: ubuntu-20.04 + steps: + - uses: actions/checkout@v2 + - uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: stable + override: true + components: rustfmt + - uses: actions-rs/cargo@v1 + with: + command: fmt + args: --all -- --check \ No newline at end of file diff --git a/README.md b/README.md index a16a2e4..593b26c 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,11 @@ ## [Documentation](https://docs.rs/crate/hifive1) +## Minimum Supported Rust Version (MSRV) + +This crate is guaranteed to compile on stable Rust 1.42.0 and up. It *might* +compile with older versions but that may change in any new patch release. + ## License Copyright 2018-2019 [RISC-V team][team] diff --git a/ci/install.sh b/ci/install.sh deleted file mode 100755 index b2789a8..0000000 --- a/ci/install.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env bash - -set -euxo pipefail - -rustup target add $TARGET diff --git a/ci/script.sh b/ci/script.sh deleted file mode 100755 index c5bc32b..0000000 --- a/ci/script.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/usr/bin/env bash - -set -euxo pipefail - -cargo check --target $TARGET --features 'board-hifive1' -cargo check --target $TARGET --features 'board-hifive1-revb' -cargo check --target $TARGET --features 'board-redv' -cargo check --target $TARGET --features 'board-lofive' -cargo check --target $TARGET --features 'board-lofive-r1' From 288ef2878dfd57c674757c8003459befa9a33ef6 Mon Sep 17 00:00:00 2001 From: Ales Katona Date: Tue, 20 Jul 2021 23:03:07 -0700 Subject: [PATCH 101/112] remove unused target checks --- .github/workflows/ci.yaml | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index bdb839f..3d9685b 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -28,13 +28,6 @@ jobs: override: true - name: Install all Rust targets for ${{ matrix.rust }} run: rustup target install --toolchain=${{ matrix.rust }} x86_64-unknown-linux-gnu riscv32imac-unknown-none-elf riscv64imac-unknown-none-elf riscv64gc-unknown-none-elf - - name: Run CI script for x86_64-unknown-linux-gnu under ${{ matrix.rust }} - run: | - cargo check --target x86_64-unknown-linux-gnu --features board-hifive1 - cargo check --target x86_64-unknown-linux-gnu --features board-hifive1-revb - cargo check --target x86_64-unknown-linux-gnu --features board-redv - cargo check --target x86_64-unknown-linux-gnu --features board-lofive - cargo check --target x86_64-unknown-linux-gnu --features board-lofive-r1 - name: Run CI script for riscv32imac-unknown-none-elf under ${{ matrix.rust }} run: | cargo check --target riscv32imac-unknown-none-elf --features board-hifive1 @@ -42,20 +35,6 @@ jobs: cargo check --target riscv32imac-unknown-none-elf --features board-redv cargo check --target riscv32imac-unknown-none-elf --features board-lofive cargo check --target riscv32imac-unknown-none-elf --features board-lofive-r1 - - name: Run CI script for riscv64imac-unknown-none-elf under ${{ matrix.rust }} - run: | - cargo check --target riscv64imac-unknown-none-elf --features board-hifive1 - cargo check --target riscv64imac-unknown-none-elf --features board-hifive1-revb - cargo check --target riscv64imac-unknown-none-elf --features board-redv - cargo check --target riscv64imac-unknown-none-elf --features board-lofive - cargo check --target riscv64imac-unknown-none-elf --features board-lofive-r1 - - name: Run CI script for riscv64gc-unknown-none-elf under ${{ matrix.rust }} - run: | - cargo check --target riscv64gc-unknown-none-elf --features board-hifive1 - cargo check --target riscv64gc-unknown-none-elf --features board-hifive1-revb - cargo check --target riscv64gc-unknown-none-elf --features board-redv - cargo check --target riscv64gc-unknown-none-elf --features board-lofive - cargo check --target riscv64gc-unknown-none-elf --features board-lofive-r1 # On macOS and Windows, we at least make sure that the crate builds and links. build-other: From 0d9473233d2effcb15df68f4e03f01253852b3cf Mon Sep 17 00:00:00 2001 From: Vadim Kaushan Date: Sun, 4 Sep 2022 08:22:24 +0300 Subject: [PATCH 102/112] Track changes in hifive1-link.x --- build.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/build.rs b/build.rs index e731326..ec4ac5f 100644 --- a/build.rs +++ b/build.rs @@ -43,6 +43,7 @@ fn main() { } fs::copy("hifive1-link.x", out_dir.join("hifive1-link.x")).unwrap(); + println!("cargo:rerun-if-changed=hifive1-link.x"); // Copy library with flash setup code let name = env::var("CARGO_PKG_NAME").unwrap(); From e7c4bf17c3a65e63978da11d2bfe1a12163786bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20P=C3=A9rez?= Date: Mon, 17 Oct 2022 16:29:39 +0200 Subject: [PATCH 103/112] Replaced board-specific LED impls with a macro --- src/led.rs | 50 ++++++++++++++++++++++++-------------------------- 1 file changed, 24 insertions(+), 26 deletions(-) diff --git a/src/led.rs b/src/led.rs index d2c1b27..c860a94 100644 --- a/src/led.rs +++ b/src/led.rs @@ -13,7 +13,7 @@ use e310x_hal::gpio::gpio0::Pin5; #[cfg(any(feature = "board-hifive1", feature = "board-hifive1-revb"))] use e310x_hal::gpio::gpio0::{Pin19, Pin21, Pin22}; use e310x_hal::gpio::{Invert, Output, Regular}; -use embedded_hal::digital::v2::OutputPin; +use embedded_hal::digital::v2::{OutputPin, ToggleableOutputPin}; #[cfg(any(feature = "board-hifive1", feature = "board-hifive1-revb"))] /// Red LED @@ -47,36 +47,34 @@ pub trait Led { /// Turns the LED on fn on(&mut self); -} - -#[cfg(any(feature = "board-hifive1", feature = "board-hifive1-revb"))] -impl Led for RED { - fn off(&mut self) { - self.set_low().unwrap(); - } - fn on(&mut self) { - self.set_high().unwrap(); - } + /// Toggles the LED state + fn toggle(&mut self); } -#[cfg(any(feature = "board-hifive1", feature = "board-hifive1-revb"))] -impl Led for GREEN { - fn off(&mut self) { - self.set_low().unwrap(); - } +/// Macro to implement the Led trait for each of the board LEDs +macro_rules! led_impl { + ($($LEDTYPE:ident),+) => { + $( + impl Led for $LEDTYPE { + fn off(&mut self) { + self.set_low().unwrap(); + } + + fn on(&mut self) { + self.set_high().unwrap(); + } - fn on(&mut self) { - self.set_high().unwrap(); + fn toggle(&mut self) { + ToggleableOutputPin::toggle(self).unwrap(); + } + } + )+ } } -impl Led for BLUE { - fn off(&mut self) { - self.set_low().unwrap(); - } +/// Call the macro for each LED +#[cfg(any(feature = "board-hifive1", feature = "board-hifive1-revb"))] +led_impl!(RED, GREEN); - fn on(&mut self) { - self.set_high().unwrap(); - } -} +led_impl!(BLUE); \ No newline at end of file From f656193a3ca80400c1ec8502f9fcd97ffdffed6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rom=C3=A1n=20C=C3=A1rdenas?= Date: Mon, 17 Oct 2022 23:32:03 +0200 Subject: [PATCH 104/112] Cargo fmt --- src/led.rs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/led.rs b/src/led.rs index c860a94..5530d19 100644 --- a/src/led.rs +++ b/src/led.rs @@ -57,18 +57,18 @@ macro_rules! led_impl { ($($LEDTYPE:ident),+) => { $( impl Led for $LEDTYPE { - fn off(&mut self) { - self.set_low().unwrap(); - } + fn off(&mut self) { + self.set_low().unwrap(); + } - fn on(&mut self) { - self.set_high().unwrap(); - } + fn on(&mut self) { + self.set_high().unwrap(); + } - fn toggle(&mut self) { - ToggleableOutputPin::toggle(self).unwrap(); + fn toggle(&mut self) { + ToggleableOutputPin::toggle(self).unwrap(); + } } - } )+ } } @@ -77,4 +77,4 @@ macro_rules! led_impl { #[cfg(any(feature = "board-hifive1", feature = "board-hifive1-revb"))] led_impl!(RED, GREEN); -led_impl!(BLUE); \ No newline at end of file +led_impl!(BLUE); From a3c0965b348aed77d2a1182ec68fc0039e1ba4f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rom=C3=A1n=20C=C3=A1rdenas?= Date: Mon, 17 Oct 2022 23:33:35 +0200 Subject: [PATCH 105/112] Cargo clippy --- src/stdout.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/stdout.rs b/src/stdout.rs index e683f36..68779d4 100644 --- a/src/stdout.rs +++ b/src/stdout.rs @@ -19,8 +19,8 @@ struct SerialWrapper(Tx); impl core::fmt::Write for SerialWrapper { fn write_str(&mut self, s: &str) -> fmt::Result { for byte in s.as_bytes() { - if *byte == '\n' as u8 { - let res = block!(self.0.write('\r' as u8)); + if *byte == b'\n' { + let res = block!(self.0.write(b'\r')); if res.is_err() { return Err(::core::fmt::Error); @@ -53,7 +53,7 @@ pub fn configure( interrupt::free(|_| unsafe { STDOUT.replace(SerialWrapper(tx)); }); - return rx; + rx } /// Writes string to stdout From 99cfe9d19eaaebd60fcf674b5f6803fce47e2f42 Mon Sep 17 00:00:00 2001 From: Ales Katona Date: Fri, 3 Mar 2023 09:11:45 -0800 Subject: [PATCH 106/112] update to latest riscv crate --- Cargo.toml | 6 +++--- src/stdout.rs | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 601da86..2f5fbd2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,9 +10,9 @@ license = "ISC" edition = "2018" [dependencies] -e310x-hal = "0.9.1" -embedded-hal = "0.2.5" -riscv = "0.6.0" +e310x-hal = "0.9.3" +embedded-hal = "0.2.7" +riscv = "0.10.1" nb = "1.0.0" [features] diff --git a/src/stdout.rs b/src/stdout.rs index 68779d4..829cbbd 100644 --- a/src/stdout.rs +++ b/src/stdout.rs @@ -50,7 +50,7 @@ pub fn configure( let serial = Serial::new(uart, (tx, rx), baud_rate, clocks); let (tx, rx) = serial.split(); - interrupt::free(|_| unsafe { + interrupt::free(|| unsafe { STDOUT.replace(SerialWrapper(tx)); }); rx @@ -58,7 +58,7 @@ pub fn configure( /// Writes string to stdout pub fn write_str(s: &str) { - interrupt::free(|_| unsafe { + interrupt::free(|| unsafe { if let Some(stdout) = STDOUT.as_mut() { let _ = stdout.write_str(s); } @@ -67,7 +67,7 @@ pub fn write_str(s: &str) { /// Writes formatted string to stdout pub fn write_fmt(args: fmt::Arguments) { - interrupt::free(|_| unsafe { + interrupt::free(|| unsafe { if let Some(stdout) = STDOUT.as_mut() { let _ = stdout.write_fmt(args); } From 4b47b878d3e337b225f61ca49f29c029919bd5de Mon Sep 17 00:00:00 2001 From: Ales Katona Date: Fri, 3 Mar 2023 09:14:13 -0800 Subject: [PATCH 107/112] add dependecy bump changelog entry --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4df48f2..0e89bed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] +### Changed +- Updated riscv dependency to v0.10 with interrupt/critical section changes + ## [v0.10.0] - 2021-07-15 ### Added From 87c2c051a7a60f7a7b0d59f453005a6ecfeef470 Mon Sep 17 00:00:00 2001 From: Ales Katona Date: Fri, 3 Mar 2023 09:19:51 -0800 Subject: [PATCH 108/112] bump MSRV to 1.59 due to dependencies --- .github/bors.toml | 2 +- .github/workflows/ci.yaml | 4 ++-- Cargo.toml | 1 + README.md | 4 ++-- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/.github/bors.toml b/.github/bors.toml index b5b4935..ca7d72a 100644 --- a/.github/bors.toml +++ b/.github/bors.toml @@ -3,7 +3,7 @@ delete_merged_branches = true required_approvals = 1 status = [ "ci-linux (stable)", - "ci-linux (1.42.0)", + "ci-linux (1.59.0)", "build-other (macOS-latest)", "build-other (windows-latest)", "Rustfmt" diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 3d9685b..8f219a4 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -11,8 +11,8 @@ jobs: continue-on-error: ${{ matrix.experimental || false }} strategy: matrix: - # All generated code should be running on stable now, MRSV is 1.42.0 - rust: [nightly, stable, 1.42.0] + # All generated code should be running on stable now, MRSV is 1.59.0 + rust: [nightly, stable, 1.59.0] include: # Nightly is only for reference and allowed to fail diff --git a/Cargo.toml b/Cargo.toml index 2f5fbd2..20492e7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,6 +8,7 @@ description = "Board support crate for HiFive1 and LoFive boards" keywords = ["riscv", "register", "peripheral"] license = "ISC" edition = "2018" +rust-version = "1.59" [dependencies] e310x-hal = "0.9.3" diff --git a/README.md b/README.md index 593b26c..a734eb5 100644 --- a/README.md +++ b/README.md @@ -18,12 +18,12 @@ ## Minimum Supported Rust Version (MSRV) -This crate is guaranteed to compile on stable Rust 1.42.0 and up. It *might* +This crate is guaranteed to compile on stable Rust 1.59.0 and up. It *might* compile with older versions but that may change in any new patch release. ## License -Copyright 2018-2019 [RISC-V team][team] +Copyright 2018-2023 [RISC-V team][team] Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice From c425cae00a3941365a2eff4124833cc6fac33618 Mon Sep 17 00:00:00 2001 From: Ales Katona Date: Fri, 3 Mar 2023 09:25:54 -0800 Subject: [PATCH 109/112] releave v0.11.0 --- CHANGELOG.md | 2 ++ Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0e89bed..3506c4f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] +## [v0.11.0] - 2023-03-03 + ### Changed - Updated riscv dependency to v0.10 with interrupt/critical section changes diff --git a/Cargo.toml b/Cargo.toml index 20492e7..efc832f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "hifive1" -version = "0.10.0" +version = "0.11.0" repository = "https://github.com/riscv-rust/hifive1" authors = ["David Craven "] categories = ["embedded", "hardware-support", "no-std"] From d73593394c8f8eaccd22942912dd2b59ca57bec0 Mon Sep 17 00:00:00 2001 From: Ales Katona Date: Tue, 28 Mar 2023 15:25:07 -0700 Subject: [PATCH 110/112] release v0.12.0 with updated dependencies --- CHANGELOG.md | 3 +++ Cargo.toml | 4 ++-- memory-hifive1-revb.x | 2 +- memory-hifive1.x | 2 +- memory-lofive-r1.x | 2 +- 5 files changed, 8 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3506c4f..99d128e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] +## [v0.12.0] - 2023-03-28 +- Update e310x-hal to v0.11 with new svd2rust generated code + ## [v0.11.0] - 2023-03-03 ### Changed diff --git a/Cargo.toml b/Cargo.toml index efc832f..d875ffd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "hifive1" -version = "0.11.0" +version = "0.12.0" repository = "https://github.com/riscv-rust/hifive1" authors = ["David Craven "] categories = ["embedded", "hardware-support", "no-std"] @@ -11,7 +11,7 @@ edition = "2018" rust-version = "1.59" [dependencies] -e310x-hal = "0.9.3" +e310x-hal = "0.11.0" embedded-hal = "0.2.7" riscv = "0.10.1" nb = "1.0.0" diff --git a/memory-hifive1-revb.x b/memory-hifive1-revb.x index e9e4bc5..4239af3 100644 --- a/memory-hifive1-revb.x +++ b/memory-hifive1-revb.x @@ -1,4 +1,4 @@ -INCLUDE memory-fe310.x +INCLUDE device.x MEMORY { FLASH : ORIGIN = 0x20000000, LENGTH = 4M diff --git a/memory-hifive1.x b/memory-hifive1.x index cd55c70..e5dc86e 100644 --- a/memory-hifive1.x +++ b/memory-hifive1.x @@ -1,4 +1,4 @@ -INCLUDE memory-fe310.x +INCLUDE device.x MEMORY { FLASH : ORIGIN = 0x20000000, LENGTH = 16M diff --git a/memory-lofive-r1.x b/memory-lofive-r1.x index cd55c70..e5dc86e 100644 --- a/memory-lofive-r1.x +++ b/memory-lofive-r1.x @@ -1,4 +1,4 @@ -INCLUDE memory-fe310.x +INCLUDE device.x MEMORY { FLASH : ORIGIN = 0x20000000, LENGTH = 16M From 17b9b334ae58be0c04684a2e3336ffc4112e8e17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rom=C3=A1n=20C=C3=A1rdenas=20Rodr=C3=ADguez?= Date: Mon, 7 Oct 2024 18:55:14 +0200 Subject: [PATCH 111/112] inline assembly for flash --- .travis.yml | 31 ------------------------------- CHANGELOG.md | 1 + assemble.sh | 11 ----------- bin/flash.a | Bin 2222 -> 0 bytes build.rs | 6 ------ flash.S | 45 --------------------------------------------- src/flash.rs | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 51 insertions(+), 93 deletions(-) delete mode 100644 .travis.yml delete mode 100755 assemble.sh delete mode 100644 bin/flash.a delete mode 100644 flash.S diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 1e9dc7a..0000000 --- a/.travis.yml +++ /dev/null @@ -1,31 +0,0 @@ -language: rust - -env: - - TARGET=x86_64-unknown-linux-gnu - - TARGET=riscv32imac-unknown-none-elf - -rust: - - nightly - - stable - -if: (branch = staging OR branch = trying OR branch = master) OR (type = pull_request AND branch = master) - - -install: - - ci/install.sh - -script: - - ci/script.sh - - -cache: cargo - -branches: - only: - - master - - staging - - trying - -notifications: - email: - on_success: never diff --git a/CHANGELOG.md b/CHANGELOG.md index 99d128e..e229ad8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] +- Use inline assembly instead of binary blobs for flash ## [v0.12.0] - 2023-03-28 - Update e310x-hal to v0.11 with new svd2rust generated code diff --git a/assemble.sh b/assemble.sh deleted file mode 100755 index 3a04536..0000000 --- a/assemble.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/bash - -set -euxo pipefail - -# remove existing blobs because otherwise this will append object files to the old blobs -rm -f bin/*.a - -riscv64-unknown-elf-gcc -ggdb3 -fdebug-prefix-map=$(pwd)=/hifive1 -c -mabi=ilp32 -march=rv32imac flash.S -o bin/flash.o -riscv64-unknown-elf-ar crs bin/flash.a bin/flash.o - -rm bin/flash.o diff --git a/bin/flash.a b/bin/flash.a deleted file mode 100644 index 4c734e21c25daa429a7aced6fcbdaeb1545f37ce..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2222 zcma)6&rcIU6n@ifD@7=U5+x#L6-A6@DGS2I5J;>hhUft`Mh~!s0!_+~Y?lU&iNup8 z9zE#IgE2jL@Fs~~JaF{D-=GJNCSFWT)bGuY?Y2PlCG+O{-n{wV%(!+*wA$x#^?q;AU6`@G2Xze*&>k9?qPvU<7iQ!4-Db2dS3wH^45 z+D`x51bxeYxsmv-d^VYkf8R~yYrBuPUPH;E6YxU(O1Hzy@>qhOjxYMEK(qgGv9Hy(+Z`o5bw(E?zoYsc+2PQ~76zws|&2-k8 z8ieypmH8?OKFfq(9dS$UdTw@woyTq-&dfQew;H}Se;KuElW!psHH&b#(ZD`DI&2X> zSTvyX>u1rdhZ}+XmT->Zoe>^F0E_rh)Xkz~Q@u1IL}Ot}T%P4Xgm(d7i0}{sSadi_ z!P}d7x`}6~M@M*%8SIyw>6{Jc#)jdCwRfrU6>~1u!4AfsH={T0Fy=+V&Z7z55R5ya zm&5l(=%uiP&91bPQyGfi^RC8$7D_5qdWfV?90xqqhWX<^a+p2;W^}X6yk12J_e* z5SxKEeeG!jJX$vc!uOWz^0ha0p8~U94vlRSq)$QVd5qgj-OC`{3j}RL(6b)fbF^sP z!AMwCdI%(U`J7)-buF1x|xns<~BCv(Vzk{P_tjF(^pE&eFTL9Vbd+`3F Nd6N*>4rkTt{sl;fv@QSu diff --git a/build.rs b/build.rs index ec4ac5f..c16de98 100644 --- a/build.rs +++ b/build.rs @@ -44,10 +44,4 @@ fn main() { fs::copy("hifive1-link.x", out_dir.join("hifive1-link.x")).unwrap(); println!("cargo:rerun-if-changed=hifive1-link.x"); - - // Copy library with flash setup code - let name = env::var("CARGO_PKG_NAME").unwrap(); - fs::copy("bin/flash.a", out_dir.join(format!("lib{}.a", name))).unwrap(); - println!("cargo:rustc-link-lib=static={}", name); - println!("cargo:rerun-if-changed=bin/flash.a"); } diff --git a/flash.S b/flash.S deleted file mode 100644 index 53dd795..0000000 --- a/flash.S +++ /dev/null @@ -1,45 +0,0 @@ -.cfi_sections .debug_frame - -.section .data._setup_is25lp -.global _setup_is25lp -.cfi_startproc -_setup_is25lp: - li a1, 0x10014000 // QSPI0 base address - - // Disable mapped region - sw zero,96(a1) // fctrl.en = 0 - - // Construct ffmt value for 4 dummy cycles - li a2, 0x00BB1447 - - beqz a0, 2f - - // We need to set 8 dummy cycles instead of 4. - // Issue a "Set Read Parameters" command. - - li a0,2 - sw a0,24(a1) // csmode = HOLD - li a0,0xC0 - sw a0,72(a1) // txdata = 0xC0 - li a0,0xF0 - sw a0,72(a1) // txdata = 0xF0 - sw zero,24(a1) // csmode = AUTO - - // Discard two response bytes -1: lw a0,76(a1) - bltz a0,1b -1: lw a0,76(a1) - bltz a0,1b - - addi a2,a2,0x40 // ffmt: 4 -> 8 dummy cycles -2: - sw a2,100(a1) // Write ffmt - - // Enable mapped region - li a0, 1 - sw a0,96(a1) // fctrl.en = 1 - ret - - -.cfi_endproc -.size _setup_is25lp, . - _setup_is25lp diff --git a/src/flash.rs b/src/flash.rs index e138c99..4208379 100644 --- a/src/flash.rs +++ b/src/flash.rs @@ -3,6 +3,56 @@ use e310x_hal::clock::Clocks; use e310x_hal::e310x::QSPI0; +#[cfg(target_arch = "riscv32")] +core::arch::global_asm!( + r#" + .cfi_sections .debug_frame + + .section .data._setup_is25lp + .global _setup_is25lp + .cfi_startproc + _setup_is25lp: + li a1, 0x10014000 // QSPI0 base address + + // Disable mapped region + sw zero,96(a1) // fctrl.en = 0 + + // Construct ffmt value for 4 dummy cycles + li a2, 0x00BB1447 + + beqz a0, 2f + + // We need to set 8 dummy cycles instead of 4. + // Issue a "Set Read Parameters" command. + + li a0,2 + sw a0,24(a1) // csmode = HOLD + li a0,0xC0 + sw a0,72(a1) // txdata = 0xC0 + li a0,0xF0 + sw a0,72(a1) // txdata = 0xF0 + sw zero,24(a1) // csmode = AUTO + + // Discard two response bytes + 1: lw a0,76(a1) + bltz a0,1b + 1: lw a0,76(a1) + bltz a0,1b + + addi a2,a2,0x40 // ffmt: 4 -> 8 dummy cycles + 2: + sw a2,100(a1) // Write ffmt + + // Enable mapped region + li a0, 1 + sw a0,96(a1) // fctrl.en = 1 + ret + + .cfi_endproc + .size _setup_is25lp, . - _setup_is25lp + "# +); + /// Configure SPI Flash interface to maximum supported speed #[inline(always)] pub fn configure_spi_flash(qspi: &QSPI0, clocks: &Clocks) { From 4d4e23fc45c6d148d18359752ebaafeee0a9f439 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rom=C3=A1n=20C=C3=A1rdenas=20Rodr=C3=ADguez?= Date: Mon, 7 Oct 2024 18:58:05 +0200 Subject: [PATCH 112/112] prepare for workspace --- {.github => hifive1/.github}/CODEOWNERS | 0 {.github => hifive1/.github}/bors.toml | 0 {.github => hifive1/.github}/workflows/ci.yaml | 0 {.github => hifive1/.github}/workflows/rustfmt.yaml | 0 .gitignore => hifive1/.gitignore | 0 CHANGELOG.md => hifive1/CHANGELOG.md | 0 CODE_OF_CONDUCT.md => hifive1/CODE_OF_CONDUCT.md | 0 Cargo.toml => hifive1/Cargo.toml | 0 README.md => hifive1/README.md | 0 build.rs => hifive1/build.rs | 0 hifive1-link.x => hifive1/hifive1-link.x | 0 memory-hifive1-revb.x => hifive1/memory-hifive1-revb.x | 0 memory-hifive1.x => hifive1/memory-hifive1.x | 0 memory-lofive-r1.x => hifive1/memory-lofive-r1.x | 0 {src => hifive1/src}/clock.rs | 0 {src => hifive1/src}/flash.rs | 0 {src => hifive1/src}/gpio.rs | 0 {src => hifive1/src}/led.rs | 0 {src => hifive1/src}/lib.rs | 0 {src => hifive1/src}/stdout.rs | 0 20 files changed, 0 insertions(+), 0 deletions(-) rename {.github => hifive1/.github}/CODEOWNERS (100%) rename {.github => hifive1/.github}/bors.toml (100%) rename {.github => hifive1/.github}/workflows/ci.yaml (100%) rename {.github => hifive1/.github}/workflows/rustfmt.yaml (100%) rename .gitignore => hifive1/.gitignore (100%) rename CHANGELOG.md => hifive1/CHANGELOG.md (100%) rename CODE_OF_CONDUCT.md => hifive1/CODE_OF_CONDUCT.md (100%) rename Cargo.toml => hifive1/Cargo.toml (100%) rename README.md => hifive1/README.md (100%) rename build.rs => hifive1/build.rs (100%) rename hifive1-link.x => hifive1/hifive1-link.x (100%) rename memory-hifive1-revb.x => hifive1/memory-hifive1-revb.x (100%) rename memory-hifive1.x => hifive1/memory-hifive1.x (100%) rename memory-lofive-r1.x => hifive1/memory-lofive-r1.x (100%) rename {src => hifive1/src}/clock.rs (100%) rename {src => hifive1/src}/flash.rs (100%) rename {src => hifive1/src}/gpio.rs (100%) rename {src => hifive1/src}/led.rs (100%) rename {src => hifive1/src}/lib.rs (100%) rename {src => hifive1/src}/stdout.rs (100%) diff --git a/.github/CODEOWNERS b/hifive1/.github/CODEOWNERS similarity index 100% rename from .github/CODEOWNERS rename to hifive1/.github/CODEOWNERS diff --git a/.github/bors.toml b/hifive1/.github/bors.toml similarity index 100% rename from .github/bors.toml rename to hifive1/.github/bors.toml diff --git a/.github/workflows/ci.yaml b/hifive1/.github/workflows/ci.yaml similarity index 100% rename from .github/workflows/ci.yaml rename to hifive1/.github/workflows/ci.yaml diff --git a/.github/workflows/rustfmt.yaml b/hifive1/.github/workflows/rustfmt.yaml similarity index 100% rename from .github/workflows/rustfmt.yaml rename to hifive1/.github/workflows/rustfmt.yaml diff --git a/.gitignore b/hifive1/.gitignore similarity index 100% rename from .gitignore rename to hifive1/.gitignore diff --git a/CHANGELOG.md b/hifive1/CHANGELOG.md similarity index 100% rename from CHANGELOG.md rename to hifive1/CHANGELOG.md diff --git a/CODE_OF_CONDUCT.md b/hifive1/CODE_OF_CONDUCT.md similarity index 100% rename from CODE_OF_CONDUCT.md rename to hifive1/CODE_OF_CONDUCT.md diff --git a/Cargo.toml b/hifive1/Cargo.toml similarity index 100% rename from Cargo.toml rename to hifive1/Cargo.toml diff --git a/README.md b/hifive1/README.md similarity index 100% rename from README.md rename to hifive1/README.md diff --git a/build.rs b/hifive1/build.rs similarity index 100% rename from build.rs rename to hifive1/build.rs diff --git a/hifive1-link.x b/hifive1/hifive1-link.x similarity index 100% rename from hifive1-link.x rename to hifive1/hifive1-link.x diff --git a/memory-hifive1-revb.x b/hifive1/memory-hifive1-revb.x similarity index 100% rename from memory-hifive1-revb.x rename to hifive1/memory-hifive1-revb.x diff --git a/memory-hifive1.x b/hifive1/memory-hifive1.x similarity index 100% rename from memory-hifive1.x rename to hifive1/memory-hifive1.x diff --git a/memory-lofive-r1.x b/hifive1/memory-lofive-r1.x similarity index 100% rename from memory-lofive-r1.x rename to hifive1/memory-lofive-r1.x diff --git a/src/clock.rs b/hifive1/src/clock.rs similarity index 100% rename from src/clock.rs rename to hifive1/src/clock.rs diff --git a/src/flash.rs b/hifive1/src/flash.rs similarity index 100% rename from src/flash.rs rename to hifive1/src/flash.rs diff --git a/src/gpio.rs b/hifive1/src/gpio.rs similarity index 100% rename from src/gpio.rs rename to hifive1/src/gpio.rs diff --git a/src/led.rs b/hifive1/src/led.rs similarity index 100% rename from src/led.rs rename to hifive1/src/led.rs diff --git a/src/lib.rs b/hifive1/src/lib.rs similarity index 100% rename from src/lib.rs rename to hifive1/src/lib.rs diff --git a/src/stdout.rs b/hifive1/src/stdout.rs similarity index 100% rename from src/stdout.rs rename to hifive1/src/stdout.rs