├── .cargo └── config ├── .gdbinit ├── .gitignore ├── .travis.yml ├── Cargo.toml ├── LICENSE ├── README.md ├── build.rs ├── examples ├── adc_lpc17xx │ ├── .cargo │ │ └── config │ ├── Cargo.toml │ ├── src │ │ └── main.rs │ └── thumbv7m-none-eabi.json ├── blink_k20 │ ├── .cargo │ │ └── config │ ├── Cargo.toml │ ├── src │ │ └── main.rs │ └── thumbv7em-none-eabi.json ├── blink_k20_isr │ ├── .cargo │ │ └── config │ ├── Cargo.toml │ ├── src │ │ └── main.rs │ └── thumbv7em-none-eabi.json ├── blink_lpc17xx │ ├── .cargo │ │ └── config │ ├── Cargo.toml │ ├── src │ │ └── main.rs │ └── thumbv7m-none-eabi.json ├── blink_pt │ ├── .cargo │ │ └── config │ ├── Cargo.toml │ ├── src │ │ └── main.rs │ └── thumbv7m-none-eabi.json ├── blink_stm32f1 │ ├── Cargo.toml │ └── src │ │ └── main.rs ├── blink_stm32f4 │ ├── .cargo │ │ └── config │ ├── Cargo.toml │ ├── src │ │ └── main.rs │ └── thumbv7em-none-eabi.json ├── blink_stm32f7 │ ├── .cargo │ │ └── config │ ├── Cargo.toml │ ├── src │ │ └── main.rs │ └── thumbv7em-none-eabi.json ├── blink_stm32l1 │ ├── .cargo │ │ └── config │ ├── Cargo.toml │ ├── src │ │ └── main.rs │ └── thumbv7m-none-eabi.json ├── blink_tiva_c │ ├── .cargo │ │ └── config │ ├── Cargo.toml │ ├── src │ │ └── main.rs │ └── thumbv7em-none-eabi.json ├── bluenrg_stm32l1 │ ├── .cargo │ │ └── config │ ├── Cargo.toml │ ├── src │ │ └── main.rs │ └── thumbv7m-none-eabi.json ├── dht22 │ ├── .cargo │ │ └── config │ ├── Cargo.toml │ ├── src │ │ └── main.rs │ └── thumbv7m-none-eabi.json ├── empty │ ├── Cargo.toml │ ├── src │ │ └── main.rs │ ├── thumbv6m-none-eabi.json │ ├── thumbv7em-none-eabi.json │ └── thumbv7m-none-eabi.json ├── lcd_tiva_c │ ├── Cargo.toml │ └── src │ │ └── main.rs ├── rgb_pwm_lpc17xx │ ├── .cargo │ │ └── config │ ├── Cargo.toml │ ├── src │ │ └── main.rs │ └── thumbv7m-none-eabi.json ├── uart │ ├── .cargo │ │ └── config │ ├── Cargo.toml │ ├── src │ │ └── main.rs │ └── thumbv7m-none-eabi.json ├── uart_tiva_c │ ├── .cargo │ │ └── config │ ├── Cargo.toml │ ├── src │ │ └── main.rs │ └── thumbv7em-none-eabi.json ├── usart_stm32f1 │ ├── Cargo.toml │ └── src │ │ └── main.rs └── usart_stm32l1 │ ├── .cargo │ └── config │ ├── Cargo.toml │ ├── src │ └── main.rs │ └── thumbv7m-none-eabi.json ├── ioreg ├── Cargo.toml ├── src │ ├── builder │ │ ├── accessors.rs │ │ ├── getter.rs │ │ ├── mod.rs │ │ ├── register.rs │ │ ├── setter.rs │ │ ├── union.rs │ │ └── utils.rs │ ├── lib.rs │ ├── node.rs │ └── parser.rs └── tests │ └── test.rs ├── macro_platformtree ├── Cargo.toml └── src │ └── lib.rs ├── macro_zinc ├── Cargo.toml └── src │ └── lib.rs ├── platformtree ├── Cargo.toml └── src │ ├── builder │ ├── mcu.rs │ ├── meta_args.rs │ ├── mod.rs │ └── os.rs │ ├── lib.rs │ ├── node.rs │ ├── parser.rs │ ├── parser_test.rs │ └── test_helpers.rs ├── src ├── drivers │ ├── bluenrg.rs │ ├── chario.rs │ ├── dht22.rs │ ├── dht22_pt.rs │ ├── drivers_pt.rs │ ├── lcd │ │ ├── c12332.rs │ │ ├── font_small_7.rs │ │ ├── hd44780u.rs │ │ ├── ili9341.rs │ │ └── mod.rs │ └── mod.rs ├── hal │ ├── cortex_common │ │ ├── irq.rs │ │ ├── mod.rs │ │ ├── mpu.rs │ │ ├── nvic.rs │ │ ├── scb.rs │ │ └── systick.rs │ ├── cortex_m0 │ │ ├── isr.rs │ │ ├── lock.rs │ │ └── mod.rs │ ├── cortex_m3 │ │ ├── isr.rs │ │ ├── lock.rs │ │ ├── mod.rs │ │ ├── sched.S │ │ └── sched.rs │ ├── cortex_m4 │ │ └── mod.rs │ ├── cortex_m7 │ │ └── mod.rs │ ├── isr.rs │ ├── k20 │ │ ├── iomem.ld │ │ ├── isr.rs │ │ ├── layout.ld │ │ ├── mod.rs │ │ ├── pin.rs │ │ ├── sim.rs │ │ ├── uart.rs │ │ └── watchdog.rs │ ├── layout_common.ld │ ├── lpc11xx │ │ ├── layout.ld │ │ ├── mod.rs │ │ ├── regs.rs │ │ └── syscon.rs │ ├── lpc17xx │ │ ├── iomem.ld │ │ ├── isr.rs │ │ ├── layout.ld │ │ ├── mod.rs │ │ ├── peripheral_clock.rs │ │ ├── pin.rs │ │ ├── pin_pt.rs │ │ ├── pinmap.rs │ │ ├── pinmap.rs.rb │ │ ├── platformtree.rs │ │ ├── pwm.rs │ │ ├── ssp.rs │ │ ├── system_clock.rs │ │ ├── system_clock_pt.rs │ │ ├── timer.rs │ │ ├── timer_pt.rs │ │ ├── uart.rs │ │ └── uart_pt.rs │ ├── mem_init.rs │ ├── mod.rs │ ├── pin.rs │ ├── pwm.rs │ ├── spi.rs │ ├── stack.rs │ ├── stm32f1 │ │ ├── init.rs │ │ ├── iomem.ld │ │ ├── layout.ld │ │ ├── mod.rs │ │ ├── peripheral_clock.rs │ │ ├── pin.rs │ │ ├── regs.rs │ │ ├── spi.rs │ │ ├── timer.rs │ │ └── usart.rs │ ├── stm32f4 │ │ ├── init.rs │ │ ├── iomem.ld │ │ ├── layout.ld │ │ ├── mod.rs │ │ ├── peripheral_clock.rs │ │ ├── pin.rs │ │ ├── pinmap.rs.rb │ │ └── timer.rs │ ├── stm32f7 │ │ ├── init.rs │ │ ├── iomem.ld │ │ ├── layout.ld │ │ ├── mod.rs │ │ ├── peripheral_clock.rs │ │ ├── pin.rs │ │ └── timer.rs │ ├── stm32l1 │ │ ├── init.rs │ │ ├── iomem.ld │ │ ├── layout.ld │ │ ├── mod.rs │ │ ├── peripheral_clock.rs │ │ ├── pin.rs │ │ ├── spi.rs │ │ ├── timer.rs │ │ └── usart.rs │ ├── timer.rs │ ├── tiva_c │ │ ├── clock_pt.rs │ │ ├── isr.rs │ │ ├── layout.ld │ │ ├── mod.rs │ │ ├── pin.rs │ │ ├── pin_pt.rs │ │ ├── platformtree.rs │ │ ├── spi.rs │ │ ├── sysctl.rs │ │ ├── timer.rs │ │ ├── timer_pt.rs │ │ ├── uart.rs │ │ └── uart_pt.rs │ └── uart.rs ├── lib.rs ├── os │ ├── cond_var.rs │ ├── debug.rs │ ├── mod.rs │ ├── mutex.rs │ ├── syscall.rs │ └── task.rs └── util │ ├── app.rs │ ├── ioreg.rs │ ├── lang_items.rs │ ├── mod.rs │ ├── queue.rs │ ├── shared.rs │ ├── strconv.rs │ ├── support.rs │ └── wait_for.rs ├── support ├── build-examples.sh ├── build-jenkins.sh ├── fixcov.py ├── img_to_arr.rb ├── install-rustup.sh ├── pingen.rb └── svd │ ├── CMSIS-SVD_Schema_1_0.xsd │ ├── CMSIS-SVD_Schema_1_1_draft.xsd │ ├── Gemfile │ ├── data │ ├── CMSIS-SVD_Schema_1_0.xsd │ ├── CMSIS-SVD_Schema_1_1_draft.xsd │ ├── Freescale │ │ ├── Freescale CMSIS-SVD License Agreement.pdf │ │ ├── MK20D5.xml │ │ ├── MKL25Z4.xml │ │ └── README.md │ ├── NXP │ │ ├── Changelog.md │ │ └── LPC11xx-v6-z0.xml │ └── STMicro │ │ └── STM32F103xx.xml │ ├── svd.rb │ └── template.rs.erb ├── thumbv6m-none-eabi.json ├── thumbv7em-none-eabi.json ├── thumbv7m-none-eabi.json └── volatile_cell ├── Cargo.toml └── lib.rs /.cargo/config: -------------------------------------------------------------------------------- 1 | [target.thumbv6m-none-eabi] 2 | linker = "arm-none-eabi-gcc" 3 | ar = "arm-none-eabi-ar" 4 | 5 | [target.thumbv7m-none-eabi] 6 | linker = "arm-none-eabi-gcc" 7 | ar = "arm-none-eabi-ar" 8 | 9 | [target.thumbv7em-none-eabi] 10 | linker = "arm-none-eabi-gcc" 11 | ar = "arm-none-eabi-ar" 12 | -------------------------------------------------------------------------------- /.gdbinit: -------------------------------------------------------------------------------- 1 | define tr 2 | target remote localhost:3333 3 | end 4 | 5 | define trx 6 | target extended localhost:3333 7 | end 8 | 9 | define ld 10 | load build/zinc.elf 11 | end 12 | 13 | define rst 14 | monitor jtag_reset 15 | end 16 | 17 | define reload 18 | ld 19 | cont 20 | end 21 | 22 | set mem inaccessible-by-default off 23 | 24 | set environment RUST_BACKTRACE = 1 25 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /build/ 2 | /thirdparty/ 3 | /doc/ 4 | .DS_Store 5 | Cargo.lock 6 | target 7 | *.o 8 | *.bin 9 | *.lst 10 | autom4te.cache 11 | /config.log 12 | /config.status 13 | Makefile 14 | /cov 15 | *.pyc 16 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | os: 2 | - linux 3 | dist: trusty 4 | language: generic 5 | before_install: 6 | - sudo add-apt-repository -y ppa:terry.guo/gcc-arm-embedded 7 | - sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-key 6D1D8367A3421AFB 8 | - sudo apt-get update -o Dir::Etc::sourcelist="sources.list.d/terry_guo-gcc-arm-embedded-precise.list" -o Dir::Etc::sourceparts="-" -o APT::Get::List-Cleanup="0" 9 | - sudo apt-get install gcc-arm-none-eabi libcurl4-openssl-dev libelf-dev libdw-dev 10 | - wget https://github.com/SimonKagstrom/kcov/archive/master.tar.gz && tar xzf master.tar.gz 11 | - (mkdir kcov-master/build && cd kcov-master/build && cmake .. && make && make install DESTDIR=../tmp) 12 | - export PATH=$PATH:~/.cargo/bin 13 | - ./support/install-rustup.sh $RUST_TOOLCHAIN 14 | script: 15 | - export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$(dirname `rustup which rustc`)/../lib 16 | - ./support/build-jenkins.sh 17 | env: 18 | global: 19 | - RUST_TOOLCHAIN=nightly-2016-09-17 20 | matrix: 21 | - PLATFORM=native 22 | - PLATFORM=lpc11xx 23 | - PLATFORM=lpc17xx 24 | - PLATFORM=k20 25 | - PLATFORM=stm32f4 26 | - PLATFORM=stm32l1 27 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "zinc" 3 | version = "0.1.0" 4 | authors = ["Zinc Developers "] 5 | build = "build.rs" 6 | 7 | [lib] 8 | name = "zinc" 9 | crate-type = ["lib"] 10 | 11 | [features] 12 | test = ["volatile_cell/replayer"] 13 | 14 | cpu_cortex-m0 = [] 15 | cpu_cortex-m3 = [] 16 | cpu_cortex-m4 = [] 17 | cpu_cortex-m7 = [] 18 | 19 | mcu_lpc11xx = ["cpu_cortex-m0"] 20 | mcu_lpc17xx = ["cpu_cortex-m3"] 21 | mcu_stm32f1 = ["cpu_cortex-m3"] 22 | mcu_stm32f4 = ["cpu_cortex-m4"] 23 | mcu_stm32f7 = ["cpu_cortex-m7"] 24 | mcu_stm32l1 = ["cpu_cortex-m3"] 25 | mcu_k20 = ["cpu_cortex-m4"] 26 | mcu_tiva_c = ["cpu_cortex-m4"] 27 | multitasking = ["cpu_cortex-m4"] 28 | 29 | [dependencies.ioreg] 30 | path = "./ioreg" 31 | 32 | [dependencies.volatile_cell] 33 | path = "./volatile_cell" 34 | 35 | [dependencies] 36 | rlibc = "*" 37 | 38 | [dev-dependencies] 39 | expectest = "*" 40 | 41 | [dev-dependencies.platformtree] 42 | path = "./platformtree" 43 | 44 | [dev-dependencies.macro_platformtree] 45 | path = "./macro_platformtree" 46 | 47 | [dev-dependencies.macro_zinc] 48 | path = "./macro_zinc" 49 | -------------------------------------------------------------------------------- /build.rs: -------------------------------------------------------------------------------- 1 | use std::ascii::AsciiExt; 2 | use std::env; 3 | use std::fs; 4 | use std::io; 5 | use std::path::Path; 6 | 7 | fn get_platform() -> Option { 8 | let features = env::vars().filter(|&(ref key, _)| key.starts_with("CARGO_FEATURE_MCU_")); 9 | match features.last() { 10 | Some((feature_var, _)) => Some( 11 | feature_var.trim_left_matches("CARGO_FEATURE_MCU_") 12 | .to_string().to_ascii_lowercase()), 13 | None => None, 14 | } 15 | } 16 | 17 | fn file_exists(file: &Path) -> bool { 18 | match fs::metadata(file) { 19 | Ok(_) => true, 20 | // Check for ENOENT (No such file or directory) 21 | Err(e) => e.raw_os_error() != Some(2), 22 | } 23 | } 24 | 25 | fn copy_linker_scripts, Q: AsRef>(target: P, out_path: Q) -> io::Result<()> { 26 | let path_prefix = if env::var("CARGO_MANIFEST_DIR").unwrap().find("/examples/").is_none() { 27 | Path::new(".") 28 | } else { 29 | Path::new("./../..") 30 | }; 31 | // Try copying the linker scripts 32 | let target_dir = Path::new("src/hal").join(target); 33 | let out_dir: &Path = out_path.as_ref(); 34 | try!(fs::copy(path_prefix.join("src/hal/layout_common.ld"), out_dir.join("layout_common.ld"))); 35 | let iomem_ld = path_prefix.join(target_dir.join("iomem.ld")); 36 | if file_exists(iomem_ld.as_path()) { 37 | try!(fs::copy(iomem_ld, out_dir.join("iomem.ld"))); 38 | } 39 | try!(fs::copy(path_prefix.join(target_dir.join("layout.ld")), out_dir.join("layout.ld"))); 40 | 41 | Ok(()) 42 | } 43 | 44 | fn main() { 45 | let platform = match get_platform() { 46 | Some(p) => p, 47 | None => { 48 | return; 49 | }, 50 | }; 51 | // Get output directory for cargo for zinc crate 52 | let out_dir = env::var("OUT_DIR").unwrap(); 53 | 54 | // Move linker scripts to cargo output dir 55 | match copy_linker_scripts(&platform, &out_dir) { 56 | Ok(_) => {}, 57 | Err(e) => panic!("Failed to copy linker scripts: {}", e) 58 | } 59 | 60 | // Make sure that the output dir is passed to linker 61 | println!("cargo:rustc-link-search=native={}", out_dir); 62 | } 63 | -------------------------------------------------------------------------------- /examples/adc_lpc17xx/.cargo/config: -------------------------------------------------------------------------------- 1 | [build] 2 | target = "thumbv7m-none-eabi" 3 | -------------------------------------------------------------------------------- /examples/adc_lpc17xx/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "adc" 3 | version = "0.0.1" 4 | 5 | [features] 6 | default = ["mcu_lpc17xx"] 7 | mcu_lpc17xx = ["zinc/mcu_lpc17xx"] 8 | 9 | [dependencies] 10 | zinc = { path = "../.." } 11 | macro_platformtree = { path = "../../macro_platformtree" } 12 | -------------------------------------------------------------------------------- /examples/adc_lpc17xx/src/main.rs: -------------------------------------------------------------------------------- 1 | // ADC example for lpc17xx chips 2 | // Copyright 2015 Felix Obenhuber 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | #![feature(start, plugin, core_intrinsics)] 17 | #![no_std] 18 | #![plugin(macro_platformtree)] 19 | 20 | extern crate zinc; 21 | 22 | use zinc::hal::pin::{Adc, Gpio}; 23 | use zinc::hal::timer::Timer; 24 | 25 | platformtree!( 26 | lpc17xx@mcu { 27 | clock { 28 | source = "main-oscillator"; 29 | source_frequency = 12_000_000; 30 | pll { 31 | m = 50; 32 | n = 3; 33 | divisor = 4; 34 | } 35 | } 36 | 37 | timer { 38 | timer@1 { 39 | counter = 25; 40 | divisor = 4; 41 | } 42 | } 43 | 44 | gpio { 45 | 0 { 46 | led@22 { direction = "out"; } 47 | adc0@23 { direction = "out"; function = "ad0_0"; } 48 | } 49 | } 50 | } 51 | 52 | os { 53 | single_task { 54 | loop = "run"; 55 | args { 56 | adc0 = &adc0; 57 | led = &led; 58 | timer = &timer; 59 | } 60 | } 61 | } 62 | ); 63 | 64 | fn run(args: &pt::run_args) { 65 | loop { 66 | if args.adc0.read() > 2048 { 67 | args.led.set_high(); 68 | } else { 69 | args.led.set_low(); 70 | } 71 | args.timer.wait_ms(100); 72 | } 73 | } 74 | 75 | -------------------------------------------------------------------------------- /examples/adc_lpc17xx/thumbv7m-none-eabi.json: -------------------------------------------------------------------------------- 1 | ../../thumbv7m-none-eabi.json -------------------------------------------------------------------------------- /examples/blink_k20/.cargo/config: -------------------------------------------------------------------------------- 1 | [build] 2 | target = "thumbv7em-none-eabi" 3 | -------------------------------------------------------------------------------- /examples/blink_k20/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "blink" 3 | version = "0.0.1" 4 | 5 | [features] 6 | default = ["mcu_k20"] 7 | mcu_k20 = ["zinc/mcu_k20"] 8 | 9 | [dependencies] 10 | zinc = { path = "../.." } 11 | macro_zinc = { path = "../../macro_zinc" } 12 | -------------------------------------------------------------------------------- /examples/blink_k20/src/main.rs: -------------------------------------------------------------------------------- 1 | #![feature(plugin, start)] 2 | #![no_std] 3 | #![plugin(macro_zinc)] 4 | 5 | extern crate zinc; 6 | 7 | use core::option::Option::Some; 8 | 9 | use zinc::hal::cortex_m4::systick; 10 | use zinc::hal::k20::{pin, watchdog}; 11 | use zinc::hal::pin::Gpio; 12 | 13 | /// Wait the given number of SysTick ticks 14 | pub fn wait(ticks: u32) { 15 | let mut n = ticks; 16 | // Reset the tick flag 17 | systick::tick(); 18 | loop { 19 | if systick::tick() { 20 | n -= 1; 21 | if n == 0 { 22 | break; 23 | } 24 | } 25 | } 26 | } 27 | 28 | #[zinc_main] 29 | pub fn main() { 30 | zinc::hal::mem_init::init_stack(); 31 | zinc::hal::mem_init::init_data(); 32 | watchdog::init(watchdog::State::Disabled); 33 | 34 | // Pins for MC HCK (http://www.mchck.org/) 35 | let led1 = pin::Pin::new(pin::Port::PortB, 16, pin::Function::Gpio, Some(zinc::hal::pin::Out)); 36 | 37 | systick::setup(systick::ten_ms().unwrap_or(480000)); 38 | systick::enable(); 39 | loop { 40 | led1.set_high(); 41 | wait(10); 42 | led1.set_low(); 43 | wait(10); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /examples/blink_k20/thumbv7em-none-eabi.json: -------------------------------------------------------------------------------- 1 | ../../thumbv7em-none-eabi.json -------------------------------------------------------------------------------- /examples/blink_k20_isr/.cargo/config: -------------------------------------------------------------------------------- 1 | [build] 2 | target = "thumbv7em-none-eabi" 3 | -------------------------------------------------------------------------------- /examples/blink_k20_isr/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "blink_k20_isr" 3 | version = "0.0.1" 4 | 5 | [features] 6 | default = ["mcu_k20"] 7 | mcu_k20 = ["zinc/mcu_k20"] 8 | 9 | [dependencies] 10 | zinc = { path = "../.." } 11 | -------------------------------------------------------------------------------- /examples/blink_k20_isr/src/main.rs: -------------------------------------------------------------------------------- 1 | #![feature(start, core_intrinsics)] 2 | #![no_std] 3 | 4 | extern crate zinc; 5 | 6 | use core::intrinsics::volatile_load; 7 | 8 | use core::option::Option::Some; 9 | use zinc::hal::k20::{pin, watchdog}; 10 | use zinc::hal::pin::Gpio; 11 | use zinc::hal::cortex_m4::systick; 12 | use zinc::util::support::wfi; 13 | 14 | static mut i: u32 = 0; 15 | static mut global_on: u32 = 0; 16 | 17 | #[allow(dead_code)] 18 | #[no_mangle] 19 | pub unsafe extern fn isr_systick() { 20 | i += 1; 21 | if i > 100 { 22 | i = 0; 23 | global_on = !global_on; 24 | } 25 | } 26 | 27 | pub fn main() { 28 | zinc::hal::mem_init::init_stack(); 29 | zinc::hal::mem_init::init_data(); 30 | watchdog::init(watchdog::State::Disabled); 31 | 32 | // Pins for MC HCK (http://www.mchck.org/) 33 | let led1 = pin::Pin::new(pin::Port::PortB, 16, pin::Function::Gpio, Some(zinc::hal::pin::Out)); 34 | 35 | systick::setup(systick::ten_ms().unwrap_or(480000)); 36 | systick::enable(); 37 | systick::enable_irq(); 38 | 39 | loop { 40 | let on: bool = unsafe { volatile_load(&global_on as *const u32) == 0 }; 41 | match on { 42 | true => led1.set_high(), 43 | false => led1.set_low(), 44 | } 45 | wfi(); 46 | } 47 | } 48 | 49 | #[start] 50 | fn start(_: isize, _: *const *const u8) -> isize { 51 | main(); 52 | 0 53 | } 54 | -------------------------------------------------------------------------------- /examples/blink_k20_isr/thumbv7em-none-eabi.json: -------------------------------------------------------------------------------- 1 | ../../thumbv7em-none-eabi.json -------------------------------------------------------------------------------- /examples/blink_lpc17xx/.cargo/config: -------------------------------------------------------------------------------- 1 | [build] 2 | target = "thumbv7m-none-eabi" 3 | -------------------------------------------------------------------------------- /examples/blink_lpc17xx/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "blink" 3 | version = "0.0.1" 4 | 5 | [features] 6 | default = ["mcu_lpc17xx"] 7 | mcu_lpc17xx = ["zinc/mcu_lpc17xx"] 8 | 9 | [dependencies] 10 | zinc = { path = "../.." } 11 | macro_zinc = { path = "../../macro_zinc" } 12 | -------------------------------------------------------------------------------- /examples/blink_lpc17xx/src/main.rs: -------------------------------------------------------------------------------- 1 | #![feature(plugin, start)] 2 | #![no_std] 3 | #![plugin(macro_zinc)] 4 | 5 | extern crate zinc; 6 | 7 | use core::option::Option::Some; 8 | 9 | use zinc::hal::lpc17xx::{pin, timer}; 10 | use zinc::hal::pin::Gpio; 11 | use zinc::hal::pin::GpioDirection; 12 | use zinc::hal::timer::Timer; 13 | 14 | #[zinc_main] 15 | pub fn main() { 16 | zinc::hal::mem_init::init_stack(); 17 | zinc::hal::mem_init::init_data(); 18 | 19 | // P1.20 => LED-2 (mbed LPC1768) 20 | let led2 = pin::Pin::new( 21 | pin::Port::Port1, 21, 22 | pin::Function::Gpio, 23 | Some(GpioDirection::Out)); 24 | 25 | let timer = timer::Timer::new(timer::TimerPeripheral::Timer0, 25, 4); 26 | 27 | loop { 28 | led2.set_high(); 29 | timer.wait_ms(10); 30 | led2.set_low(); 31 | timer.wait_ms(10); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /examples/blink_lpc17xx/thumbv7m-none-eabi.json: -------------------------------------------------------------------------------- 1 | ../../thumbv7m-none-eabi.json -------------------------------------------------------------------------------- /examples/blink_pt/.cargo/config: -------------------------------------------------------------------------------- 1 | [build] 2 | target = "thumbv7m-none-eabi" 3 | -------------------------------------------------------------------------------- /examples/blink_pt/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "blink" 3 | version = "0.0.1" 4 | 5 | [features] 6 | default = ["mcu_lpc17xx"] 7 | mcu_lpc17xx = ["zinc/mcu_lpc17xx"] 8 | 9 | [dependencies] 10 | zinc = { path = "../.." } 11 | macro_platformtree = { path = "../../macro_platformtree" } 12 | -------------------------------------------------------------------------------- /examples/blink_pt/src/main.rs: -------------------------------------------------------------------------------- 1 | #![feature(plugin, start, core_intrinsics)] 2 | #![no_std] 3 | #![plugin(macro_platformtree)] 4 | 5 | extern crate zinc; 6 | 7 | platformtree!( 8 | lpc17xx@mcu { 9 | clock { 10 | source = "main-oscillator"; 11 | source_frequency = 12_000_000; 12 | pll { 13 | m = 50; 14 | n = 3; 15 | divisor = 4; 16 | } 17 | } 18 | 19 | timer { 20 | timer@1 { 21 | counter = 25; 22 | divisor = 4; 23 | } 24 | } 25 | 26 | gpio { 27 | 1 { 28 | led1@18 { direction = "out"; } 29 | led2@20 { direction = "out"; } 30 | } 31 | } 32 | } 33 | 34 | os { 35 | single_task { 36 | loop = "run"; 37 | args { 38 | timer = &timer; 39 | led1 = &led1; 40 | led2 = &led2; 41 | } 42 | } 43 | } 44 | ); 45 | 46 | fn run(args: &pt::run_args) { 47 | use zinc::hal::pin::Gpio; 48 | use zinc::hal::timer::Timer; 49 | 50 | args.led1.set_high(); 51 | args.led2.set_low(); 52 | args.timer.wait(1); 53 | 54 | args.led1.set_low(); 55 | args.led2.set_high(); 56 | args.timer.wait(1); 57 | } 58 | -------------------------------------------------------------------------------- /examples/blink_pt/thumbv7m-none-eabi.json: -------------------------------------------------------------------------------- 1 | ../../thumbv7m-none-eabi.json -------------------------------------------------------------------------------- /examples/blink_stm32f1/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "blink_stm32f1" 3 | version = "0.0.1" 4 | 5 | [features] 6 | default = ["mcu_stm32f1"] 7 | mcu_stm32f1 = ["zinc/mcu_stm32f1"] 8 | 9 | [dependencies] 10 | zinc = { path = "../.." } 11 | macro_zinc = { path = "../../macro_zinc" } 12 | -------------------------------------------------------------------------------- /examples/blink_stm32f1/src/main.rs: -------------------------------------------------------------------------------- 1 | #![feature(plugin, start)] 2 | #![no_std] 3 | #![plugin(macro_zinc)] 4 | 5 | extern crate zinc; 6 | 7 | #[zinc_main] 8 | fn main() { 9 | use zinc::hal::pin::Gpio; 10 | use zinc::hal::stm32f1::{init, pin, timer}; 11 | use zinc::hal::timer::Timer; 12 | zinc::hal::mem_init::init_stack(); 13 | zinc::hal::mem_init::init_data(); 14 | 15 | // configure PLL and set it as System Clock source 16 | let pll_conf = init::PllConf { 17 | source: init::PllClockSource::PllSourceHSIDiv2, 18 | mult: init::PllMult::PllMul12, 19 | hse_prediv: init::PllHsePrediv::PllHsePrediv1, 20 | usb_prescaler: init::PllUsbDiv::PllUsbDiv1, 21 | }; 22 | let sys_clock = init::ClockConfig { 23 | source: init::SystemClockSource::SystemClockPLL(pll_conf), 24 | ahb_prescaler: init::ClockAhbPrescaler::AhbDivNone, 25 | apb1_prescaler: init::ClockApbPrescaler::ApbDiv2, 26 | apb2_prescaler: init::ClockApbPrescaler::ApbDivNone, 27 | flash_latency: init::FlashLatency::FlashLatency1, 28 | mco: init::McoSource::McoClockNone, 29 | }; 30 | sys_clock.setup(); 31 | 32 | let led1 = pin::Pin::new(pin::Port::PortC, 13, pin::PinConf::OutPushPull50MHz); 33 | 34 | // TODO(kvark): why doesn't "sys_clock.get_apb1_frequency()" work better? 35 | // NOTE(blazewicz): Timers 2..7, 12..14 are not fed directly from APB1 36 | // if APB1 prescaler is different than 1 then timers get 2*APB1 frequency 37 | // in this example AHBCLK = 48 MHz, APB1 prescaler is set to 2, so Timer 2 gets 2*APB1=AHB=48 MHz 38 | let timer_clock = sys_clock.get_ahb_frequency(); 39 | let timer = timer::Timer::new(timer::TimerPeripheral::Timer2, timer_clock/1000, 0); 40 | 41 | loop { 42 | led1.set_high(); 43 | timer.wait_ms(1); 44 | led1.set_low(); 45 | timer.wait_ms(1); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /examples/blink_stm32f4/.cargo/config: -------------------------------------------------------------------------------- 1 | [build] 2 | target = "thumbv7em-none-eabi" 3 | -------------------------------------------------------------------------------- /examples/blink_stm32f4/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "blink_stm32f4" 3 | version = "0.0.1" 4 | 5 | [features] 6 | default = ["mcu_stm32f4"] 7 | mcu_stm32f4 = ["zinc/mcu_stm32f4"] 8 | 9 | [dependencies] 10 | zinc = { path = "../.." } 11 | macro_zinc = { path = "../../macro_zinc" } 12 | -------------------------------------------------------------------------------- /examples/blink_stm32f4/src/main.rs: -------------------------------------------------------------------------------- 1 | #![feature(plugin, start)] 2 | #![no_std] 3 | #![plugin(macro_zinc)] 4 | 5 | extern crate zinc; 6 | 7 | use zinc::hal::timer::Timer; 8 | use zinc::hal::pin::Gpio; 9 | use zinc::hal::stm32f4::{pin, timer}; 10 | 11 | #[zinc_main] 12 | pub fn main() { 13 | zinc::hal::mem_init::init_stack(); 14 | zinc::hal::mem_init::init_data(); 15 | 16 | let led1 = pin::Pin { 17 | port: pin::Port::PortD, 18 | pin: 13u8, 19 | function: pin::Function::GPIOOut 20 | }; 21 | let led2 = pin::Pin { 22 | port: pin::Port::PortD, 23 | pin: 14u8, 24 | function: pin::Function::GPIOOut 25 | }; 26 | led1.setup(); 27 | led2.setup(); 28 | 29 | let timer = timer::Timer::new(timer::TimerPeripheral::Timer2, 16u32); 30 | 31 | loop { 32 | led1.set_high(); 33 | led2.set_low(); 34 | timer.wait_ms(300); 35 | led1.set_low(); 36 | led2.set_high(); 37 | timer.wait_ms(300); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /examples/blink_stm32f4/thumbv7em-none-eabi.json: -------------------------------------------------------------------------------- 1 | ../../thumbv7em-none-eabi.json -------------------------------------------------------------------------------- /examples/blink_stm32f7/.cargo/config: -------------------------------------------------------------------------------- 1 | [build] 2 | target = "thumbv7em-none-eabi" 3 | rustflags = ["-Clink-args=-Wl,-Map=blink_stm32f7.map"] 4 | -------------------------------------------------------------------------------- /examples/blink_stm32f7/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "blink_stm32f7" 3 | version = "0.0.1" 4 | 5 | [features] 6 | default = ["mcu_stm32f7"] 7 | mcu_stm32f7 = ["zinc/mcu_stm32f7"] 8 | 9 | [dependencies] 10 | zinc = { path = "../.." } 11 | macro_zinc = { path = "../../macro_zinc" } 12 | -------------------------------------------------------------------------------- /examples/blink_stm32f7/src/main.rs: -------------------------------------------------------------------------------- 1 | #![feature(plugin, start)] 2 | #![no_std] 3 | #![plugin(macro_zinc)] 4 | 5 | extern crate zinc; 6 | 7 | use zinc::hal::timer::Timer; 8 | use zinc::hal::pin::Gpio; 9 | use zinc::hal::stm32f7::{pin, timer}; 10 | 11 | #[zinc_main] 12 | pub fn main() { 13 | zinc::hal::mem_init::init_stack(); 14 | zinc::hal::mem_init::init_data(); 15 | 16 | // Turn off the LCD backlight (PK3) 17 | let backlight = pin::Pin { 18 | port: pin::Port::PortK, 19 | pin: 3, 20 | function: pin::Function::GPIOOut 21 | }; 22 | backlight.setup(); 23 | backlight.set_low(); 24 | 25 | // The STM32F7 Discovery board LED is on PI1 26 | let led = pin::Pin { 27 | port: pin::Port::PortI, 28 | pin: 1, 29 | function: pin::Function::GPIOOut 30 | }; 31 | led.setup(); 32 | 33 | let timer = timer::Timer::new(timer::TimerPeripheral::Timer2, 16); 34 | 35 | loop { 36 | led.set_high(); 37 | timer.wait_ms(100); 38 | led.set_low(); 39 | timer.wait_ms(100); 40 | led.set_high(); 41 | timer.wait_ms(100); 42 | led.set_low(); 43 | timer.wait_ms(700); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /examples/blink_stm32f7/thumbv7em-none-eabi.json: -------------------------------------------------------------------------------- 1 | ../../thumbv7em-none-eabi.json -------------------------------------------------------------------------------- /examples/blink_stm32l1/.cargo/config: -------------------------------------------------------------------------------- 1 | [build] 2 | target = "thumbv7m-none-eabi" 3 | -------------------------------------------------------------------------------- /examples/blink_stm32l1/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "blink_stm32l1" 3 | version = "0.0.1" 4 | 5 | [features] 6 | default = ["mcu_stm32l1"] 7 | mcu_stm32l1 = ["zinc/mcu_stm32l1"] 8 | 9 | [dependencies] 10 | zinc = { path = "../.." } 11 | macro_zinc = { path = "../../macro_zinc" } 12 | -------------------------------------------------------------------------------- /examples/blink_stm32l1/src/main.rs: -------------------------------------------------------------------------------- 1 | #![feature(plugin, start)] 2 | #![no_std] 3 | #![plugin(macro_zinc)] 4 | 5 | extern crate zinc; 6 | 7 | #[zinc_main] 8 | fn main() { 9 | use core::option::Option; 10 | use zinc::hal::pin::Gpio; 11 | use zinc::hal::stm32l1::{init, pin, timer}; 12 | use zinc::hal::timer::Timer; 13 | zinc::hal::mem_init::init_stack(); 14 | zinc::hal::mem_init::init_data(); 15 | 16 | let sys_clock = init::ClockConfig { 17 | source: init::SystemClockSource::SystemClockHSI, 18 | ahb_shift: 0, 19 | apb1_shift: 0, 20 | apb2_shift: 0, 21 | mco: Option::None, 22 | }; 23 | sys_clock.setup(); 24 | 25 | let led1 = pin::Pin::new(pin::Port::PortA, 5, 26 | pin::Mode::GpioOut(pin::OutputType::OutPushPull, pin::Speed::VeryLow), 27 | pin::PullType::PullNone); 28 | 29 | // TODO(kvark): why doesn't "sys_clock.get_apb1_frequency()" work better? 30 | let timer_clock = sys_clock.source.frequency(); 31 | let timer = timer::Timer::new(timer::TimerPeripheral::Timer2, timer_clock/1000, 0); 32 | 33 | loop { 34 | led1.set_high(); 35 | timer.wait_ms(1); 36 | led1.set_low(); 37 | timer.wait_ms(1); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /examples/blink_stm32l1/thumbv7m-none-eabi.json: -------------------------------------------------------------------------------- 1 | ../../thumbv7m-none-eabi.json -------------------------------------------------------------------------------- /examples/blink_tiva_c/.cargo/config: -------------------------------------------------------------------------------- 1 | [build] 2 | target = "thumbv7em-none-eabi" 3 | -------------------------------------------------------------------------------- /examples/blink_tiva_c/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "blink_tiva_c" 3 | version = "0.0.1" 4 | 5 | [features] 6 | default = ["mcu_tiva_c"] 7 | mcu_tiva_c = ["zinc/mcu_tiva_c"] 8 | 9 | [dependencies] 10 | zinc = { path = "../.." } 11 | macro_platformtree = { path = "../../macro_platformtree" } 12 | -------------------------------------------------------------------------------- /examples/blink_tiva_c/src/main.rs: -------------------------------------------------------------------------------- 1 | #![feature(plugin, start, core_intrinsics)] 2 | #![no_std] 3 | #![plugin(macro_platformtree)] 4 | 5 | extern crate zinc; 6 | 7 | platformtree!( 8 | tiva_c@mcu { 9 | clock { 10 | source = "PIOSC"; 11 | xtal = "X16_0MHz"; 12 | pll = true; 13 | div = 5; 14 | } 15 | 16 | gpio { 17 | f { led1@1 { direction = "out"; } 18 | led2@2 { direction = "out"; } 19 | } 20 | } 21 | 22 | timer { 23 | /* The mcu contain both 16/32bit and "wide" 32/64bit timers. */ 24 | timer@w0 { 25 | /* prescale sysclk to 1Mhz since the wait code expects 1us 26 | * granularity */ 27 | prescale = 80; 28 | mode = "periodic"; 29 | } 30 | } 31 | } 32 | 33 | os { 34 | single_task { 35 | loop = "run"; 36 | args { 37 | timer = &timer; 38 | led1 = &led1; 39 | led2 = &led2; 40 | } 41 | } 42 | } 43 | ); 44 | 45 | fn run(args: &pt::run_args) { 46 | use zinc::hal::pin::Gpio; 47 | use zinc::hal::timer::Timer; 48 | 49 | loop { 50 | args.led1.set_high(); 51 | args.led2.set_low(); 52 | 53 | args.timer.wait(1); 54 | 55 | args.led1.set_low(); 56 | args.led2.set_high(); 57 | 58 | args.timer.wait(1); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /examples/blink_tiva_c/thumbv7em-none-eabi.json: -------------------------------------------------------------------------------- 1 | ../../thumbv7em-none-eabi.json -------------------------------------------------------------------------------- /examples/bluenrg_stm32l1/.cargo/config: -------------------------------------------------------------------------------- 1 | [build] 2 | target = "thumbv7m-none-eabi" 3 | -------------------------------------------------------------------------------- /examples/bluenrg_stm32l1/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "bluenrg_stm32l1" 3 | version = "0.0.1" 4 | 5 | [features] 6 | default = ["mcu_stm32l1"] 7 | mcu_stm32l1 = ["zinc/mcu_stm32l1"] 8 | 9 | [dependencies] 10 | zinc = { path = "../.." } 11 | -------------------------------------------------------------------------------- /examples/bluenrg_stm32l1/thumbv7m-none-eabi.json: -------------------------------------------------------------------------------- 1 | ../../thumbv7m-none-eabi.json -------------------------------------------------------------------------------- /examples/dht22/.cargo/config: -------------------------------------------------------------------------------- 1 | [build] 2 | target = "thumbv7m-none-eabi" 3 | -------------------------------------------------------------------------------- /examples/dht22/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "dht22" 3 | version = "0.0.1" 4 | 5 | [features] 6 | default = ["mcu_lpc17xx"] 7 | mcu_lpc17xx = ["zinc/mcu_lpc17xx"] 8 | 9 | [dependencies] 10 | zinc = { path = "../.." } 11 | macro_platformtree = { path = "../../macro_platformtree" } 12 | -------------------------------------------------------------------------------- /examples/dht22/src/main.rs: -------------------------------------------------------------------------------- 1 | #![feature(start, plugin, core_intrinsics)] 2 | #![no_std] 3 | #![plugin(macro_platformtree)] 4 | 5 | extern crate zinc; 6 | 7 | use core::option::Option::{Some, None}; 8 | 9 | platformtree!( 10 | lpc17xx@mcu { 11 | clock { 12 | source = "main-oscillator"; 13 | source_frequency = 12_000_000; 14 | pll { 15 | m = 50; 16 | n = 3; 17 | divisor = 4; 18 | } 19 | } 20 | 21 | timer { 22 | timer@1 { 23 | counter = 25; 24 | divisor = 4; 25 | } 26 | } 27 | 28 | uart { 29 | uart@0 { 30 | baud_rate = 115200; 31 | mode = "8N1"; 32 | tx = &uart_tx; 33 | rx = &uart_rx; 34 | } 35 | } 36 | 37 | gpio { 38 | 0 { 39 | uart_tx@2; 40 | uart_rx@3; 41 | dht_pin@4; 42 | } 43 | } 44 | } 45 | 46 | drivers { 47 | dht@dht22 { 48 | pin = &dht_pin; 49 | timer = &timer; 50 | } 51 | } 52 | 53 | os { 54 | single_task { 55 | loop = "run"; 56 | args { 57 | timer = &timer; 58 | uart = &uart; 59 | dht = &dht; 60 | } 61 | } 62 | } 63 | ); 64 | 65 | #[zinc_task] 66 | fn run(args: &pt::run_args) { 67 | use zinc::drivers::chario::CharIO; 68 | use zinc::hal::timer::Timer; 69 | 70 | args.timer.wait(3); 71 | 72 | let ret = args.dht.read(); 73 | match ret { 74 | Some(v) => { 75 | args.uart.puts("temp: "); args.uart.puti(v.temperature as u32); 76 | args.uart.puts("\n"); 77 | args.uart.puts("humidity: "); args.uart.puti(v.humidity as u32); 78 | args.uart.puts("\n"); 79 | }, 80 | None => { 81 | args.uart.puts("fail\n"); 82 | }, 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /examples/dht22/thumbv7m-none-eabi.json: -------------------------------------------------------------------------------- 1 | ../../thumbv7m-none-eabi.json -------------------------------------------------------------------------------- /examples/empty/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "empty" 3 | version = "0.0.1" 4 | 5 | [features] 6 | mcu_lpc11xx = ["zinc/mcu_lpc11xx"] 7 | mcu_lpc17xx = ["zinc/mcu_lpc17xx"] 8 | mcu_stm32f4 = ["zinc/mcu_stm32f4"] 9 | mcu_stm32l1 = ["zinc/mcu_stm32l1"] 10 | mcu_k20 = ["zinc/mcu_k20"] 11 | mcu_tiva_c = ["zinc/mcu_tiva_c"] 12 | 13 | [dependencies] 14 | zinc = { path = "../.." } 15 | macro_zinc = { path = "../../macro_zinc" } 16 | -------------------------------------------------------------------------------- /examples/empty/src/main.rs: -------------------------------------------------------------------------------- 1 | #![feature(plugin, asm, start)] 2 | #![no_std] 3 | #![plugin(macro_zinc)] 4 | 5 | extern crate zinc; 6 | 7 | use zinc::hal::mem_init::{init_data, init_stack}; 8 | 9 | #[zinc_main] 10 | fn run() { 11 | init_data(); 12 | init_stack(); 13 | unsafe { asm!("nop") } 14 | } 15 | -------------------------------------------------------------------------------- /examples/empty/thumbv6m-none-eabi.json: -------------------------------------------------------------------------------- 1 | ../../thumbv6m-none-eabi.json -------------------------------------------------------------------------------- /examples/empty/thumbv7em-none-eabi.json: -------------------------------------------------------------------------------- 1 | ../../thumbv7em-none-eabi.json -------------------------------------------------------------------------------- /examples/empty/thumbv7m-none-eabi.json: -------------------------------------------------------------------------------- 1 | ../../thumbv7m-none-eabi.json -------------------------------------------------------------------------------- /examples/lcd_tiva_c/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "lcd_tiva_c" 3 | version = "0.0.1" 4 | 5 | [features] 6 | default = ["mcu_tiva_c"] 7 | mcu_tiva_c = ["zinc/mcu_tiva_c"] 8 | 9 | [dependencies] 10 | zinc = { path = "../.." } 11 | macro_platformtree = { path = "../../macro_platformtree" } 12 | -------------------------------------------------------------------------------- /examples/lcd_tiva_c/src/main.rs: -------------------------------------------------------------------------------- 1 | #![feature(plugin, start, core_intrinsics)] 2 | #![no_std] 3 | #![plugin(macro_platformtree)] 4 | 5 | extern crate zinc; 6 | 7 | use zinc::drivers::chario::CharIO; 8 | use zinc::drivers::lcd::hd44780u::{Hd44780u, Font}; 9 | 10 | platformtree!( 11 | tiva_c@mcu { 12 | clock { 13 | source = "MOSC"; 14 | xtal = "X16_0MHz"; 15 | pll = false; 16 | } 17 | 18 | gpio { 19 | a { 20 | d7@5 { direction = "out"; } 21 | } 22 | b { 23 | rs@0 { direction = "out"; } 24 | en@1 { direction = "out"; } 25 | d6@4 { direction = "out"; } 26 | } 27 | e { 28 | d4@4 { direction = "out"; } 29 | d5@5 { direction = "out"; } 30 | } 31 | } 32 | 33 | timer { 34 | /* The mcu contain both 16/32bit and "wide" 32/64bit timers. */ 35 | timer@w0 { 36 | /* prescale sysclk to 1Mhz since the wait code expects 1us 37 | * granularity */ 38 | prescale = 80; 39 | mode = "periodic"; 40 | } 41 | } 42 | } 43 | 44 | os { 45 | single_task { 46 | loop = "run"; 47 | args { 48 | timer = &timer; 49 | rs = &rs; 50 | en = &en; 51 | d4 = &d4; 52 | d5 = &d5; 53 | d6 = &d6; 54 | d7 = &d7; 55 | } 56 | } 57 | } 58 | ); 59 | 60 | 61 | pub fn run(args: &pt::run_args) { 62 | 63 | let lcd = Hd44780u::new(args.timer, 64 | args.rs, 65 | args.en, 66 | [ args.d4, args.d5, args.d6, args.d7 ]); 67 | 68 | lcd.init(true, Font::Font5x8); 69 | 70 | // Create custom 'heart' character at index 0. 71 | lcd.custom_char_5x8(0, 72 | [0b00000, 73 | 0b01010, 74 | 0b11111, 75 | 0b11111, 76 | 0b11111, 77 | 0b01110, 78 | 0b00100, 79 | 0b00000]); 80 | // Create custom 'stick figure' character at index 1 81 | lcd.custom_char_5x8(1, 82 | [0b00100, 83 | 0b01010, 84 | 0b00100, 85 | 0b11111, 86 | 0b00100, 87 | 0b01010, 88 | 0b10001, 89 | 0b00000]); 90 | 91 | // Enable blinking 92 | lcd.display_control(true, false, true); 93 | 94 | // Display a message surounded by two hearts 95 | lcd.puts("\0 Hello Zinc \0"); 96 | 97 | // Move to the 2nd line 98 | lcd.set_pos(0, 1); 99 | 100 | // Write a line of stick figures 101 | lcd.puts("\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01"); 102 | 103 | // Move the cursor back to the middle of the first line 104 | lcd.set_pos(8, 0); 105 | 106 | loop {} 107 | } 108 | -------------------------------------------------------------------------------- /examples/rgb_pwm_lpc17xx/.cargo/config: -------------------------------------------------------------------------------- 1 | [build] 2 | target = "thumbv7m-none-eabi" 3 | -------------------------------------------------------------------------------- /examples/rgb_pwm_lpc17xx/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "rgb_pwm_lpc17xx" 3 | version = "0.0.1" 4 | 5 | [features] 6 | default = ["mcu_lpc17xx"] 7 | mcu_lpc17xx = ["zinc/mcu_lpc17xx"] 8 | 9 | [dependencies] 10 | zinc = { path = "../.." } 11 | macro_zinc = { path = "../../macro_zinc" } 12 | macro_platformtree = { path = "../../macro_platformtree" } 13 | 14 | [[bin]] 15 | name = "rgb_pwm_lpc17xx" 16 | test = false 17 | doc = false 18 | -------------------------------------------------------------------------------- /examples/rgb_pwm_lpc17xx/src/main.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2015, Paul Osborne 2 | // 3 | // Licensed under the Apache License, Version 2.0 or the MIT license 5 | // , at your 6 | // option. This file may not be copied, modified, or distributed 7 | // except according to those terms. 8 | #![feature(plugin, start, core_intrinsics)] 9 | #![no_std] 10 | #![plugin(macro_platformtree)] 11 | 12 | extern crate zinc; 13 | #[macro_use] #[no_link] extern crate macro_platformtree; 14 | 15 | use zinc::hal::timer::Timer; 16 | use zinc::hal::lpc17xx::pwm; 17 | use zinc::hal::pwm::PWMOutput; 18 | 19 | // This example shows use of the RGB LED that is availble on the MBED 20 | // Application Board. The LED is connected to 3 pins coming 21 | // from the MBED LPC1768. Here's the mapping: 22 | // 23 | platformtree!( 24 | lpc17xx@mcu { 25 | clock { 26 | source = "main-oscillator"; 27 | source_frequency = 12_000_000; 28 | pll { 29 | m = 50; 30 | n = 3; 31 | divisor = 4; 32 | } 33 | } 34 | 35 | timer { 36 | timer@1 { 37 | counter = 25; 38 | divisor = 4; 39 | } 40 | } 41 | 42 | gpio { 43 | 2 { 44 | // LPC1768 DIPP25 - P2.1/PWM1.2/RXD1 45 | rgb_blue@1 { 46 | direction = "out"; 47 | function = "pwm1_2"; 48 | } 49 | // LPC1768 DIPP24 - P2.2/PWM1.3/TRACEDATA3 50 | rgb_green@2 { 51 | direction = "out"; 52 | function = "pwm1_3"; 53 | } 54 | // LPC1768 DIPP23 - P2.3/PWM1.4/TRACEDATA2 55 | rgb_red@3 { 56 | direction = "out"; 57 | function = "pwm1_4"; 58 | } 59 | } 60 | } 61 | } 62 | 63 | os { 64 | single_task { 65 | loop = "run"; 66 | args { 67 | timer = &timer; 68 | } 69 | } 70 | } 71 | ); 72 | 73 | fn run(args: &pt::run_args) { 74 | let mut pwm_red = pwm::PWM::new(pwm::PWMChannel::Channel4, 20_000); 75 | let mut pwm_green = pwm::PWM::new(pwm::PWMChannel::Channel3, 20_000); 76 | let mut pwm_blue = pwm::PWM::new(pwm::PWMChannel::Channel2, 20_000); 77 | 78 | // turn all off 79 | pwm_red.write(0.0); 80 | pwm_green.write(1.0); 81 | pwm_blue.write(1.0); 82 | 83 | loop { 84 | for pwm in &mut [pwm_red, pwm_green, pwm_blue] { 85 | for i in 1..100 { 86 | pwm.write((i as f32) / 100.0); 87 | args.timer.wait_ms(10); 88 | } 89 | pwm.write(1.0); // turn off channel 90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /examples/rgb_pwm_lpc17xx/thumbv7m-none-eabi.json: -------------------------------------------------------------------------------- 1 | ../../thumbv7m-none-eabi.json -------------------------------------------------------------------------------- /examples/uart/.cargo/config: -------------------------------------------------------------------------------- 1 | [build] 2 | target = "thumbv7m-none-eabi" 3 | -------------------------------------------------------------------------------- /examples/uart/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "uart" 3 | version = "0.0.1" 4 | 5 | [features] 6 | default = ["mcu_lpc17xx"] 7 | mcu_lpc17xx = ["zinc/mcu_lpc17xx"] 8 | 9 | [dependencies] 10 | zinc = { path = "../.." } 11 | macro_platformtree = { path = "../../macro_platformtree" } 12 | -------------------------------------------------------------------------------- /examples/uart/src/main.rs: -------------------------------------------------------------------------------- 1 | #![feature(start, plugin, core_intrinsics)] 2 | #![no_std] 3 | #![plugin(macro_platformtree)] 4 | 5 | extern crate zinc; 6 | 7 | platformtree!( 8 | lpc17xx@mcu { 9 | clock { 10 | source = "main-oscillator"; 11 | source_frequency = 12_000_000; 12 | pll { 13 | m = 50; 14 | n = 3; 15 | divisor = 4; 16 | } 17 | } 18 | 19 | timer { 20 | timer@1 { 21 | counter = 25; 22 | divisor = 4; 23 | } 24 | } 25 | 26 | uart { 27 | uart@0 { 28 | baud_rate = 115200; 29 | mode = "8N1"; 30 | tx = &uart_tx; 31 | rx = &uart_rx; 32 | } 33 | } 34 | 35 | gpio { 36 | 0 { 37 | uart_tx@2; 38 | uart_rx@3; 39 | } 40 | 1 { 41 | led4@23 { direction = "out"; } 42 | } 43 | } 44 | } 45 | 46 | os { 47 | single_task { 48 | loop = "run"; 49 | args { 50 | timer = &timer; 51 | txled = &led4; 52 | uart = &uart; 53 | } 54 | } 55 | } 56 | ); 57 | 58 | fn run(args: &pt::run_args) { 59 | use zinc::drivers::chario::CharIO; 60 | use zinc::hal::timer::Timer; 61 | use zinc::hal::pin::Gpio; 62 | 63 | args.uart.puts("Hello, world\n"); 64 | 65 | let mut i = 0; 66 | loop { 67 | args.txled.set_high(); 68 | args.uart.puts("Waiting for "); 69 | args.uart.puti(i); 70 | args.uart.puts(" seconds...\n"); 71 | 72 | i += 1; 73 | args.txled.set_low(); 74 | 75 | args.timer.wait(1); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /examples/uart/thumbv7m-none-eabi.json: -------------------------------------------------------------------------------- 1 | ../../thumbv7m-none-eabi.json -------------------------------------------------------------------------------- /examples/uart_tiva_c/.cargo/config: -------------------------------------------------------------------------------- 1 | [build] 2 | target = "thumbv7em-none-eabi" 3 | -------------------------------------------------------------------------------- /examples/uart_tiva_c/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "uart_tiva_c" 3 | version = "0.0.1" 4 | 5 | [features] 6 | default = ["mcu_tiva_c"] 7 | mcu_tiva_c = ["zinc/mcu_tiva_c"] 8 | 9 | [dependencies] 10 | zinc = { path = "../.." } 11 | macro_platformtree = { path = "../../macro_platformtree" } 12 | -------------------------------------------------------------------------------- /examples/uart_tiva_c/src/main.rs: -------------------------------------------------------------------------------- 1 | #![feature(plugin, start, core_intrinsics)] 2 | #![no_std] 3 | #![plugin(macro_platformtree)] 4 | 5 | extern crate zinc; 6 | 7 | use zinc::drivers::chario::CharIO; 8 | 9 | platformtree!( 10 | tiva_c@mcu { 11 | clock { 12 | source = "MOSC"; 13 | xtal = "X16_0MHz"; 14 | pll = true; 15 | div = 5; 16 | } 17 | 18 | timer { 19 | /* The mcu contain both 16/32bit and "wide" 32/64bit timers. */ 20 | timer@w0 { 21 | /* prescale sysclk to 1Mhz since the wait code expects 1us 22 | * granularity */ 23 | prescale = 80; 24 | mode = "periodic"; 25 | } 26 | } 27 | 28 | gpio { 29 | a { 30 | uart_rx@0 { 31 | direction = "in"; 32 | function = 1; 33 | } 34 | uart_tx@1 { 35 | direction = "in"; 36 | function = 1; 37 | } 38 | } 39 | f { 40 | txled@2 { direction = "out"; } 41 | } 42 | } 43 | 44 | uart { 45 | uart@0 { 46 | mode = "115200,8n1"; 47 | } 48 | } 49 | 50 | } 51 | 52 | os { 53 | single_task { 54 | loop = "run"; 55 | args { 56 | timer = &timer; 57 | uart = &uart; 58 | txled = &txled; 59 | uart_tx = &uart_tx; 60 | } 61 | } 62 | } 63 | ); 64 | 65 | fn run(args: &pt::run_args) { 66 | use zinc::hal::timer::Timer; 67 | use zinc::hal::pin::Gpio; 68 | 69 | args.uart.puts("Hello, world\r\n"); 70 | 71 | let mut i = 0; 72 | loop { 73 | args.txled.set_high(); 74 | args.uart.puts("Waiting for "); 75 | args.uart.puti(i); 76 | args.uart.puts(" seconds...\r\n"); 77 | 78 | i += 1; 79 | args.txled.set_low(); 80 | 81 | args.timer.wait(1); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /examples/uart_tiva_c/thumbv7em-none-eabi.json: -------------------------------------------------------------------------------- 1 | ../../thumbv7em-none-eabi.json -------------------------------------------------------------------------------- /examples/usart_stm32f1/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "blink_stm32f1" 3 | version = "0.0.1" 4 | 5 | [features] 6 | default = ["mcu_stm32f1"] 7 | mcu_stm32f1 = ["zinc/mcu_stm32f1"] 8 | 9 | [dependencies] 10 | zinc = { path = "../.." } 11 | macro_zinc = { path = "../../macro_zinc" } 12 | -------------------------------------------------------------------------------- /examples/usart_stm32f1/src/main.rs: -------------------------------------------------------------------------------- 1 | #![feature(plugin, start)] 2 | #![no_std] 3 | #![plugin(macro_zinc)] 4 | 5 | extern crate zinc; 6 | 7 | #[zinc_main] 8 | fn main() { 9 | use zinc::drivers::chario::CharIO; 10 | use zinc::hal; 11 | use zinc::hal::pin::Gpio; 12 | use zinc::hal::stm32f1::{init, pin, usart}; 13 | 14 | // configure PLL and set it as System Clock source 15 | let pll_conf = init::PllConf { 16 | source: init::PllClockSource::PllSourceHSE(8_000_000), 17 | mult: init::PllMult::PllMul9, 18 | hse_prediv: init::PllHsePrediv::PllHsePrediv1, 19 | usb_prescaler: init::PllUsbDiv::PllUsbDiv1p5, 20 | }; 21 | let sys_clock = init::ClockConfig { 22 | source: init::SystemClockSource::SystemClockPLL(pll_conf), 23 | ahb_prescaler: init::ClockAhbPrescaler::AhbDivNone, 24 | apb1_prescaler: init::ClockApbPrescaler::ApbDiv2, 25 | apb2_prescaler: init::ClockApbPrescaler::ApbDivNone, 26 | flash_latency: init::FlashLatency::FlashLatency2, 27 | mco: init::McoSource::McoClockPLL, 28 | }; 29 | sys_clock.setup(); 30 | 31 | let _pin_tx = pin::Pin::new(pin::Port::PortA, 2, pin::PinConf::OutPushPullAlt2MHz); 32 | 33 | let led1 = pin::Pin::new(pin::Port::PortC, 13, pin::PinConf::OutPushPull50MHz); 34 | 35 | led1.set_low(); 36 | 37 | let uart = usart::Usart::new(usart::UsartPeripheral::Usart2, 38400, usart::WordLen::WordLen8bits, 38 | hal::uart::Parity::Disabled, usart::StopBit::StopBit1bit, &sys_clock); 39 | uart.puts("Hello, world\n"); 40 | 41 | led1.set_high(); 42 | 43 | loop {} 44 | } 45 | -------------------------------------------------------------------------------- /examples/usart_stm32l1/.cargo/config: -------------------------------------------------------------------------------- 1 | [build] 2 | target = "thumbv7m-none-eabi" 3 | -------------------------------------------------------------------------------- /examples/usart_stm32l1/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "usart_stm32l1" 3 | version = "0.0.1" 4 | 5 | [features] 6 | default = ["mcu_stm32l1"] 7 | mcu_stm32l1 = ["zinc/mcu_stm32l1"] 8 | 9 | [dependencies] 10 | zinc = { path = "../.." } 11 | macro_zinc = { path = "../../macro_zinc" } 12 | -------------------------------------------------------------------------------- /examples/usart_stm32l1/src/main.rs: -------------------------------------------------------------------------------- 1 | #![feature(plugin, start)] 2 | #![no_std] 3 | #![plugin(macro_zinc)] 4 | 5 | extern crate zinc; 6 | 7 | #[zinc_main] 8 | pub fn main() { 9 | use zinc::drivers::chario::CharIO; 10 | use zinc::hal; 11 | use zinc::hal::pin::Gpio; 12 | use zinc::hal::stm32l1::{init, pin, usart}; 13 | 14 | zinc::hal::mem_init::init_stack(); 15 | zinc::hal::mem_init::init_data(); 16 | 17 | let sys_clock = init::ClockConfig::new_default(); 18 | sys_clock.setup(); 19 | 20 | let _pin_tx = pin::Pin::new(pin::Port::PortA, 2, 21 | pin::Mode::AltFunction( 22 | pin::AltMode::AfUsart1_Usart2_Usart3, 23 | pin::OutputType::OutPushPull, 24 | pin::Speed::VeryLow), 25 | pin::PullType::PullNone); 26 | 27 | let led1 = pin::Pin::new(pin::Port::PortA, 5, 28 | pin::Mode::GpioOut(pin::OutputType::OutPushPull, pin::Speed::VeryLow), 29 | pin::PullType::PullNone); 30 | 31 | led1.set_low(); 32 | 33 | let uart = usart::Usart::new(usart::UsartPeripheral::Usart2, 38400, usart::WordLen::WordLen8bits, 34 | hal::uart::Parity::Disabled, usart::StopBit::StopBit1bit, &sys_clock); 35 | uart.puts("Hello, world\n"); 36 | 37 | led1.set_high(); 38 | 39 | loop {} 40 | } 41 | -------------------------------------------------------------------------------- /examples/usart_stm32l1/thumbv7m-none-eabi.json: -------------------------------------------------------------------------------- 1 | ../../thumbv7m-none-eabi.json -------------------------------------------------------------------------------- /ioreg/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "ioreg" 3 | version = "0.1.0" 4 | authors = ["Zinc Developers "] 5 | 6 | [lib] 7 | name = "ioreg" 8 | plugin = true 9 | 10 | [dev-dependencies.volatile_cell] 11 | path = "../volatile_cell" 12 | 13 | [dependencies] 14 | -------------------------------------------------------------------------------- /ioreg/src/builder/mod.rs: -------------------------------------------------------------------------------- 1 | // Zinc, the bare metal stack for rust. 2 | // Copyright 2014 Ben Gamari 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | use std::rc::Rc; 17 | use syntax::ast; 18 | use syntax::ptr::P; 19 | use syntax::ext::base::ExtCtxt; 20 | 21 | use node; 22 | mod utils; 23 | 24 | mod setter; 25 | mod getter; 26 | mod union; 27 | mod register; 28 | mod accessors; 29 | 30 | pub struct Builder { 31 | items: Vec>, 32 | } 33 | 34 | impl Builder { 35 | pub fn new() -> Builder { 36 | Builder {items: Vec::new()} 37 | } 38 | 39 | pub fn emit_items(&mut self, cx: &ExtCtxt, reg: Rc) 40 | -> Vec> { 41 | node::visit_reg(&*reg, &mut setter::BuildSetters::new(self, cx)); 42 | node::visit_reg(&*reg, &mut getter::BuildGetters::new(self, cx)); 43 | node::visit_reg(&*reg, &mut register::BuildRegStructs::new(self, cx)); 44 | node::visit_reg(&*reg, &mut union::BuildUnionTypes::new(self, cx)); 45 | node::visit_reg(&*reg, &mut accessors::BuildAccessors::new(self, cx)); 46 | self.items.clone() 47 | } 48 | 49 | pub fn push_item(&mut self, item: P) { 50 | self.items.push(item); 51 | } 52 | } 53 | 54 | -------------------------------------------------------------------------------- /macro_platformtree/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "macro_platformtree" 3 | version = "0.1.0" 4 | authors = ["Zinc Developers "] 5 | 6 | [lib] 7 | name = "macro_platformtree" 8 | plugin = true 9 | 10 | [dependencies.platformtree] 11 | path = "../platformtree" 12 | -------------------------------------------------------------------------------- /macro_zinc/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "macro_zinc" 3 | version = "0.1.0" 4 | authors = ["Matt Coffin "] 5 | 6 | [lib] 7 | name = "macro_zinc" 8 | plugin = true 9 | -------------------------------------------------------------------------------- /macro_zinc/src/lib.rs: -------------------------------------------------------------------------------- 1 | // Zinc, the bare metal stack for rust. 2 | // Copyright 2014 Matt "mcoffin" Coffin 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | #![feature(rustc_private, plugin_registrar, quote)] 17 | 18 | extern crate rustc; 19 | extern crate syntax; 20 | extern crate rustc_plugin; 21 | 22 | use rustc_plugin::Registry; 23 | use syntax::ast::MetaItem; 24 | use syntax::codemap::{Span, DUMMY_SP}; 25 | use syntax::ext::base::{Annotatable, ExtCtxt, MultiDecorator}; 26 | use syntax::ext::build::AstBuilder; 27 | 28 | macro_rules! and_return { 29 | ($a:stmt) => ( 30 | { 31 | $a; 32 | return; 33 | } 34 | ) 35 | } 36 | 37 | #[plugin_registrar] 38 | pub fn plugin_registrar(reg: &mut Registry) { 39 | reg.register_syntax_extension(syntax::parse::token::intern("zinc_main"), 40 | MultiDecorator(Box::new(decorator_zinc_main))); 41 | } 42 | 43 | pub fn decorator_zinc_main(cx: &mut ExtCtxt, 44 | sp: Span, 45 | _: &MetaItem, 46 | item: &Annotatable, 47 | push: &mut FnMut(Annotatable)) { 48 | let main = match item { 49 | &Annotatable::Item(ref main_item) => (*main_item).ident, 50 | _ => and_return!(cx.span_err(sp, "zinc_main must be an item")), 51 | }; 52 | 53 | let call_main = cx.expr_call_ident(DUMMY_SP, main, Vec::new()); 54 | let start = quote_item!(cx, 55 | #[start] 56 | fn start(_: isize, _: *const *const u8) -> isize { 57 | $call_main; 58 | 0 59 | } 60 | ).unwrap(); 61 | push(Annotatable::Item(start)); 62 | } 63 | -------------------------------------------------------------------------------- /platformtree/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "platformtree" 3 | version = "0.1.0" 4 | authors = ["Zinc Developers "] 5 | 6 | [lib] 7 | name = "platformtree" 8 | plugin = true 9 | 10 | [dependencies] 11 | regex = "*" 12 | 13 | [dev-dependencies.hamcrest] 14 | git = "https://github.com/carllerche/hamcrest-rust.git" 15 | -------------------------------------------------------------------------------- /platformtree/src/builder/mcu.rs: -------------------------------------------------------------------------------- 1 | // Zinc, the bare metal stack for rust. 2 | // Copyright 2014 Vladimir "farcaller" Pouzanov 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | use std::rc::Rc; 17 | use syntax::ext::base::ExtCtxt; 18 | 19 | use lpc17xx_pt; 20 | use tiva_c_pt; 21 | use node; 22 | 23 | use super::Builder; 24 | 25 | pub fn attach(builder: &mut Builder, cx: &mut ExtCtxt, node: Rc) { 26 | match node.name { 27 | Some(ref name) => { 28 | match name.as_str() { 29 | "lpc17xx" => lpc17xx_pt::attach(builder, cx, node.clone()), 30 | "tiva_c" => tiva_c_pt::attach(builder, cx, node.clone()), 31 | _ => node.materializer.set(Some(fail_build_mcu as fn(&mut Builder, &mut ExtCtxt, Rc))), 32 | } 33 | }, 34 | None => node.materializer.set(Some(fail_build_mcu as fn(&mut Builder, &mut ExtCtxt, Rc))), 35 | } 36 | } 37 | 38 | pub fn fail_build_mcu(_: &mut Builder, cx: &mut ExtCtxt, node: Rc) { 39 | match node.name { 40 | Some(ref name) => cx.parse_sess().span_diagnostic.span_err( 41 | node.name_span, format!("unknown mcu `{}`", name).as_str()), 42 | None => cx.parse_sess().span_diagnostic.span_err( 43 | node.name_span, "`mcu` node must have a name"), 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /platformtree/src/lib.rs: -------------------------------------------------------------------------------- 1 | // Zinc, the bare metal stack for rust. 2 | // Copyright 2014 Vladimir "farcaller" Pouzanov 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | //! Platform tree operations crate 17 | 18 | #![feature(quote, rustc_private)] 19 | 20 | // extern crate regex; 21 | extern crate syntax; 22 | extern crate regex; 23 | #[cfg(test)] extern crate hamcrest; 24 | 25 | pub mod builder; 26 | pub mod node; 27 | pub mod parser; 28 | 29 | #[path="../../src/hal/lpc17xx/platformtree.rs"] mod lpc17xx_pt; 30 | #[path="../../src/hal/tiva_c/platformtree.rs"] mod tiva_c_pt; 31 | #[path="../../src/drivers/drivers_pt.rs"] mod drivers_pt; 32 | 33 | #[cfg(test)] mod test_helpers; 34 | #[cfg(test)] mod parser_test; 35 | -------------------------------------------------------------------------------- /src/drivers/dht22.rs: -------------------------------------------------------------------------------- 1 | // Zinc, the bare metal stack for rust. 2 | // Copyright 2014 Vladimir "farcaller" Pouzanov 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | //! Driver for DHT22. 17 | 18 | use core::option::Option::{self, Some, None}; 19 | 20 | use hal::pin::Gpio; 21 | use hal::pin::GpioLevel::Low; 22 | use hal::pin::GpioLevel::High; 23 | use hal::pin::GpioDirection::In; 24 | use hal::pin::GpioDirection::Out; 25 | use hal::pin::GpioLevel; 26 | use hal::timer::Timer; 27 | 28 | /// Basic DHT22 driver ported over from Arduino example. 29 | pub struct DHT22<'a, T:'a, P:'a> { 30 | gpio: &'a P, 31 | timer: &'a T, 32 | } 33 | 34 | /// Measurement data from the DHT22. 35 | #[allow(missing_docs)] 36 | #[derive(Clone, Copy)] 37 | pub struct Measurements { 38 | pub humidity: f32, 39 | pub temperature: f32, 40 | } 41 | 42 | impl<'a, T: Timer, P: Gpio> DHT22<'a, T, P> { 43 | /// Creates a new DHT22 driver based on I/O GPIO and a timer with 10us resolution. 44 | pub fn new(timer: &'a T, gpio: &'a P) -> DHT22<'a, T, P> { 45 | DHT22 { 46 | gpio: gpio, 47 | timer: timer, 48 | } 49 | } 50 | 51 | /// Returns previous sensor measurements or None if synchronization failed. 52 | pub fn read(&self) -> Option { 53 | let buffer: &mut [u8; 5] = &mut [0; 5]; 54 | let mut idx: usize = 0; 55 | let mut mask: u8 = 128; 56 | 57 | self.gpio.set_direction(Out); 58 | self.gpio.set_low(); 59 | self.timer.wait_ms(20); 60 | self.gpio.set_high(); 61 | self.timer.wait_us(40); 62 | self.gpio.set_direction(In); 63 | 64 | if !self.wait_sync() { 65 | return None 66 | } 67 | 68 | for _ in 0..40 { 69 | if !self.wait_while(Low, 80) { 70 | return None 71 | } 72 | 73 | let t = self.timer.get_counter(); 74 | 75 | if !self.wait_while(High, 80) { 76 | return None 77 | } 78 | 79 | if self.timer.get_counter() - t > 40 { 80 | buffer[idx] |= mask; 81 | } 82 | 83 | mask >>= 1; 84 | if mask == 0 { 85 | mask = 128; 86 | idx += 1; 87 | } 88 | } 89 | 90 | let humidity: f32 = (((buffer[0] as u16) << 8) | buffer[1] as u16) as f32 * 0.1; 91 | let temperature: f32 = if buffer[2] & 0x80 != 0 { 92 | -0.1 * (((buffer[2] as u16 & 0x7F) << 8) | buffer[3] as u16) as f32 93 | } else { 94 | 0.1 * (((buffer[2] as u16) << 8) | buffer[3] as u16) as f32 95 | }; 96 | let checksum: u8 = buffer[0] + buffer[1] + buffer[2] + buffer[3]; 97 | 98 | if checksum != buffer[4] { 99 | None 100 | } else { 101 | Some(Measurements { 102 | humidity: humidity, 103 | temperature: temperature, 104 | }) 105 | } 106 | } 107 | 108 | fn wait_sync(&self) -> bool { 109 | if !self.wait_while(Low, 80) { 110 | false 111 | } else if !self.wait_while(High, 100) { 112 | false 113 | } else { 114 | true 115 | } 116 | } 117 | 118 | fn wait_while(&self, level: GpioLevel, timeout: usize) -> bool { 119 | for _ in 0..(timeout / 10) { 120 | self.timer.wait_us(10); 121 | if self.gpio.level() != level { 122 | return true; 123 | } 124 | } 125 | 126 | false 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /src/drivers/dht22_pt.rs: -------------------------------------------------------------------------------- 1 | // Zinc, the bare metal stack for rust. 2 | // Copyright 2014 Vladimir "farcaller" Pouzanov 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | use std::rc::Rc; 17 | use syntax::ext::base::ExtCtxt; 18 | 19 | use builder::{Builder, TokenString, add_node_dependency}; 20 | use node; 21 | 22 | pub fn attach(builder: &mut Builder, _: &mut ExtCtxt, node: Rc) { 23 | node.materializer.set(Some(build_dht22 as fn(&mut Builder, &mut ExtCtxt, Rc))); 24 | node.mutator.set(Some(mutate_pin as fn(&mut Builder, &mut ExtCtxt, Rc))); 25 | 26 | let pin_node_name = node.get_ref_attr("pin").unwrap(); 27 | let pin_node = builder.pt().get_by_name(pin_node_name.as_str()).unwrap(); 28 | add_node_dependency(&node, &pin_node); 29 | 30 | let timer_node_name = node.get_ref_attr("timer").unwrap(); 31 | let timer_node = builder.pt().get_by_name(timer_node_name.as_str()).unwrap(); 32 | add_node_dependency(&node, &timer_node); 33 | } 34 | 35 | fn mutate_pin(builder: &mut Builder, _: &mut ExtCtxt, node: Rc) { 36 | let pin_node_name = node.get_ref_attr("pin").unwrap(); 37 | let pin_node = builder.pt().get_by_name(pin_node_name.as_str()).unwrap(); 38 | pin_node.attributes.borrow_mut().insert("direction".to_string(), 39 | Rc::new(node::Attribute::new_nosp(node::StrValue("out".to_string())))); 40 | } 41 | 42 | fn build_dht22(builder: &mut Builder, cx: &mut ExtCtxt, node: Rc) { 43 | if !node.expect_no_subnodes(cx) {return} 44 | 45 | if !node.expect_attributes(cx, 46 | &[("pin", node::RefAttribute), ("timer", node::RefAttribute)]) { 47 | return 48 | } 49 | 50 | let pin_node_name = node.get_ref_attr("pin").unwrap(); 51 | let timer_node_name = node.get_ref_attr("timer").unwrap(); 52 | 53 | let pin = TokenString(pin_node_name); 54 | let timer = TokenString(timer_node_name); 55 | let name = TokenString(node.name.clone().unwrap()); 56 | 57 | let typename = format!("zinc::drivers::dht22::DHT22"); 58 | node.set_type_name(typename); 59 | let ty_params = vec!( 60 | "'a".to_string(), 61 | "zinc::hal::timer::Timer".to_string(), 62 | "zinc::hal::pin::Gpio".to_string()); 63 | node.set_type_params(ty_params); 64 | 65 | let st = quote_stmt!(&*cx, 66 | let $name = zinc::drivers::dht22::DHT22::new(&$timer, &$pin); 67 | ).unwrap(); 68 | builder.add_main_statement(st); 69 | } 70 | 71 | #[cfg(test)] 72 | mod test { 73 | use builder::Builder; 74 | use test_helpers::{assert_equal_source, with_parsed}; 75 | use hamcrest::{assert_that, is, equal_to}; 76 | 77 | #[test] 78 | fn builds_lpc17xx_pt() { 79 | with_parsed(" 80 | timer@timer; 81 | pin@pin; 82 | dht@dht22 { 83 | pin = &pin; 84 | timer = &timer; 85 | }", |cx, failed, pt| { 86 | let mut builder = Builder::new(pt.clone(), cx); 87 | pt.get_by_name("timer").unwrap().set_type_name("T".to_string()); 88 | pt.get_by_name("pin").unwrap().set_type_name("P".to_string()); 89 | super::mutate_pin(&mut builder, cx, pt.get_by_name("dht").unwrap()); 90 | super::build_dht22(&mut builder, cx, pt.get_by_name("dht").unwrap()); 91 | assert_that(unsafe{*failed}, is(equal_to(false))); 92 | assert_that(builder.main_stmts().len(), is(equal_to(1usize))); 93 | 94 | assert_equal_source(&builder.main_stmts()[0], 95 | "let dht = zinc::drivers::dht22::DHT22::new(&timer, &pin);"); 96 | 97 | let pin_node = pt.get_by_name("pin").unwrap(); 98 | assert_that(pin_node.get_string_attr("direction").unwrap(), 99 | is(equal_to("out".to_string()))); 100 | }); 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /src/drivers/drivers_pt.rs: -------------------------------------------------------------------------------- 1 | // Zinc, the bare metal stack for rust. 2 | // Copyright 2014 Vladimir "farcaller" Pouzanov 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | use std::rc::Rc; 17 | use syntax::ext::base::ExtCtxt; 18 | 19 | use builder::{Builder, add_node_dependency}; 20 | use node; 21 | 22 | mod dht22_pt; 23 | 24 | pub fn attach(builder: &mut Builder, cx: &mut ExtCtxt, node: Rc) { 25 | node.materializer.set(Some(verify as fn(&mut Builder, &mut ExtCtxt, Rc))); 26 | for sub in node.subnodes().iter() { 27 | add_node_dependency(&node, sub); 28 | 29 | match sub.path.as_str() { 30 | "dht22" => dht22_pt::attach(builder, cx, sub.clone()), 31 | _ => (), 32 | } 33 | } 34 | } 35 | 36 | fn verify(_: &mut Builder, cx: &mut ExtCtxt, node: Rc) { 37 | node.expect_no_attributes(cx); 38 | node.expect_subnodes(cx, &["dht22"]); 39 | } 40 | -------------------------------------------------------------------------------- /src/drivers/mod.rs: -------------------------------------------------------------------------------- 1 | // Zinc, the bare metal stack for rust. 2 | // Copyright 2014 Vladimir "farcaller" Pouzanov 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | //! Drivers for peripherals commonly found outside MCUs. 17 | 18 | pub mod lcd; 19 | pub mod bluenrg; 20 | pub mod chario; 21 | pub mod dht22; 22 | -------------------------------------------------------------------------------- /src/hal/cortex_common/irq.rs: -------------------------------------------------------------------------------- 1 | // Zinc, the bare metal stack for rust. 2 | // Copyright 2014 Ben Gamari 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | //! Disabling and enabling interrupts 17 | 18 | use core::ops::Drop; 19 | #[cfg(target_os = "none")] 20 | use core::intrinsics::abort; 21 | 22 | /// Phantom type to indicate that interrupts are disabled. 23 | pub struct NoInterrupts { 24 | #[allow(dead_code)] 25 | contents: () 26 | } 27 | 28 | impl NoInterrupts { 29 | /// Start a new critical section 30 | pub fn new() -> NoInterrupts { 31 | unsafe { 32 | disable_irqs(); 33 | } 34 | NoInterrupts { contents: () } 35 | } 36 | } 37 | 38 | impl Drop for NoInterrupts { 39 | fn drop(&mut self) { 40 | unsafe { 41 | enable_irqs(); 42 | } 43 | } 44 | } 45 | 46 | #[cfg(target_os = "none")] 47 | static mut irq_level : usize = 0; 48 | 49 | /// Disables all interrupts except Reset, HardFault, and NMI. 50 | /// Note that this is reference counted: if `disable_irqs` is called 51 | /// twice then interrupts will only be re-enabled upon the second call 52 | /// to `enable_irqs`. 53 | #[cfg(target_os = "none")] 54 | #[inline(always)] 55 | unsafe fn disable_irqs() { 56 | asm!("cpsid i" :::: "volatile"); 57 | irq_level += 1; 58 | } 59 | 60 | #[cfg(not(target_os = "none"))] 61 | unsafe fn disable_irqs() { unimplemented!() } 62 | 63 | /// Enables all interrupts except Reset, HardFault, and NMI. 64 | #[cfg(target_os = "none")] 65 | #[inline(always)] 66 | unsafe fn enable_irqs() { 67 | if irq_level == 0 { 68 | abort(); 69 | } 70 | // There is no race condition here as we know that interrupts are 71 | // disabled. 72 | irq_level -= 1; 73 | if irq_level == 0 { 74 | asm!("cpsie i" :::: "volatile"); 75 | } 76 | } 77 | 78 | #[cfg(not(target_os = "none"))] 79 | unsafe fn enable_irqs() { unimplemented!() } 80 | -------------------------------------------------------------------------------- /src/hal/cortex_common/mod.rs: -------------------------------------------------------------------------------- 1 | // Zinc, the bare metal stack for rust. 2 | // Copyright 2014 Vladimir "farcaller" Pouzanov 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | /*! 17 | Common definitions to all ARM Cortex M* family members 18 | */ 19 | 20 | pub mod systick; 21 | pub mod mpu; 22 | pub mod nvic; 23 | pub mod scb; 24 | pub mod irq; 25 | -------------------------------------------------------------------------------- /src/hal/cortex_common/mpu.rs: -------------------------------------------------------------------------------- 1 | // Zinc, the bare metal stack for rust. 2 | // Copyright 2014 Ben Harris 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | //! Interface to Memory Protection Unit. 17 | //! 18 | //! MPU memory location is 0xE000_ED90. 19 | // Link: http://infocenter.arm.com/help/topic/com.arm.doc.dui0552a/BIHJJABA.html 20 | 21 | // TODO(bharrisau): Remove dead_code when MPU is implemented. 22 | #[allow(dead_code)] 23 | #[inline(always)] 24 | fn get_reg() -> &'static reg::MPU { 25 | unsafe { &*(0xE000_ED90 as *mut reg::MPU) } 26 | } 27 | 28 | mod reg { 29 | use volatile_cell::VolatileCell; 30 | use core::ops::Drop; 31 | 32 | ioregs!(MPU = { 33 | 0x0 => reg32 mpu_type { //! MPU type register 34 | 0 => separate: ro, 35 | 8..15 => dregion: ro, 36 | 16..23 => iregion: ro, 37 | } 38 | 0x4 => reg32 ctrl { //= MPU control register 39 | 0 => enable, 40 | 1 => hfnmiena, 41 | 2 => privdefena, 42 | } 43 | 0x8 => reg32 rnr { //! Region number register 44 | 0..7 => region, 45 | } 46 | 0xc => reg32 rbar { //! Region base address register 47 | 0..3 => region, 48 | 4 => valid, 49 | 5..31 => addr, 50 | } 51 | 0x10 => reg32 rasr { //! Region attribute and size register 52 | 0 => enable, 53 | 1..5 => size, 54 | 8..15 => srd, 55 | 16 => b, 56 | 17 => c, 57 | 18 => s, 58 | 19..21 => tex, 59 | 24..26 => ap, 60 | 28 => xn, 61 | } 62 | }); 63 | } 64 | -------------------------------------------------------------------------------- /src/hal/cortex_common/nvic.rs: -------------------------------------------------------------------------------- 1 | // Zinc, the bare metal stack for rust. 2 | // Copyright 2014 Ben Harris 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | //! Interface to Nested Vector Interrupt Controller. 17 | //! 18 | //! NVIC memory location is 0xE000_E000. 19 | // Link: http://infocenter.arm.com/help/topic/com.arm.doc.dui0552a/CIHIGCIF.html 20 | 21 | #[inline(always)] 22 | fn get_reg() -> &'static reg::NVIC { 23 | unsafe { &*(0xE000_E000 as *mut reg::NVIC) } 24 | } 25 | 26 | /// Enable an interrupt 27 | pub fn enable_irq(irqn: usize) { 28 | get_reg().iser[irqn / 32].clear_iser(irqn % 32); 29 | } 30 | 31 | /// Disable an interrupt 32 | pub fn disable_irq(irqn: usize) { 33 | get_reg().icer[irqn / 32].clear_icer(irqn % 32); 34 | } 35 | 36 | /// Return whether the given interrupt is enabled 37 | pub fn is_enabled(irqn: usize) -> bool { 38 | get_reg().iser[irqn / 32].iser(irqn % 32) 39 | } 40 | 41 | /// Clear the pending flag for the given interrupt 42 | pub fn clear_pending(irqn: usize) { 43 | get_reg().icpr[irqn / 32].clear_icpr(irqn % 32); 44 | } 45 | 46 | /// Return whether the given interrupt is pending 47 | pub fn is_pending(irqn: usize) -> bool { 48 | get_reg().ispr[irqn / 32].ispr(irqn % 32) 49 | } 50 | 51 | /// Return whether the given interrupt is active 52 | pub fn is_active(irqn: usize) -> bool { 53 | get_reg().iabr[irqn / 32].iabr(irqn % 32) 54 | } 55 | 56 | /// Set the priority for the given interrupt 57 | pub fn set_priority(irqn: usize, prio: u8) { 58 | get_reg().ipr[irqn / 4].set_ipr(irqn % 4, prio as u32); 59 | } 60 | 61 | /// Return the priority for the given interrupt 62 | pub fn get_priority(irqn: usize) -> u8 { 63 | get_reg().ipr[irqn / 4].ipr(irqn % 4) as u8 64 | } 65 | 66 | mod reg { 67 | use volatile_cell::VolatileCell; 68 | use core::ops::Drop; 69 | 70 | ioregs!(NVIC = { 71 | 0x100 => reg32 iser[8] { //! Interrupt set enable register 72 | 0..31 => iser[32]: set_to_clear, 73 | } 74 | 0x180 => reg32 icer[8] { //! Interrupt clear enable register 75 | 0..31 => icer[32]: set_to_clear, 76 | } 77 | 0x200 => reg32 ispr[8] { //! Interrupt set pending register 78 | 0..31 => ispr[32]: set_to_clear, 79 | } 80 | 0x280 => reg32 icpr[8] { //! Interrupt clear pending register 81 | 0..31 => icpr[32]: set_to_clear, 82 | } 83 | 0x300 => reg32 iabr[8] { //! Interrupt active bit register 84 | 0..31 => iabr[32]: ro, 85 | } 86 | 0x400 => reg32 ipr[8] { //! Interrupt priority register 87 | 0..31 => ipr[4], 88 | } 89 | 0xF00 => reg32 stir[8] { //! Software triggered interrupt register 90 | 0..8 => stir, 91 | } 92 | }); 93 | } 94 | -------------------------------------------------------------------------------- /src/hal/cortex_common/systick.rs: -------------------------------------------------------------------------------- 1 | // Zinc, the bare metal stack for rust. 2 | // Copyright 2014 Vladimir "farcaller" Pouzanov 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | //! Interface to SYSTICK timer. 17 | //! 18 | //! Systick memory location is 0xE000_E010. 19 | 20 | use core::option::Option::{self, None, Some}; 21 | 22 | #[inline(always)] 23 | fn get_reg() -> &'static reg::SYSTICK { 24 | unsafe { &*(0xE000_E010 as *mut reg::SYSTICK) } 25 | } 26 | 27 | /// Initialize systick timer. 28 | /// 29 | /// After this call system timer will be disabled, and needs to be enabled manual. SysTick irq will 30 | /// be disabled and needs to be enabled manually, too. 31 | /// 32 | /// Arguments: 33 | /// 34 | /// * reload: Reload value for the timer 35 | pub fn setup(reload: u32) { 36 | use self::reg::SYSTICK_csr_clksource as clksource; 37 | get_reg().csr.set_enable(false).set_tickint(false).set_clksource(clksource::CPU); 38 | 39 | get_reg().rvr.set_reload(reload); 40 | get_reg().cvr.set_current(0); 41 | } 42 | 43 | /// Read ten millisecond calibration value from hardware 44 | pub fn ten_ms() -> Option { 45 | let calib = get_reg().calib.tenms(); 46 | match calib { 47 | 0 => None, 48 | val => Some(val) 49 | } 50 | } 51 | 52 | /// Enables the timer. 53 | pub fn enable() { 54 | get_reg().csr.set_enable(true); 55 | } 56 | 57 | /// Disable the timer. 58 | pub fn disable() { 59 | get_reg().csr.set_enable(false); 60 | } 61 | 62 | /// Enables interrupts generation for timer. 63 | pub fn enable_irq() { 64 | get_reg().csr.set_tickint(true); 65 | } 66 | 67 | /// Disables interrupts generation for timer, which is still ticking. 68 | pub fn disable_irq() { 69 | get_reg().csr.set_tickint(false); 70 | } 71 | 72 | /// Gets the current 24bit systick value. 73 | pub fn get_current() -> u32 { 74 | get_reg().cvr.current() 75 | } 76 | 77 | /// Checks if the timer has been triggered since last call. 78 | /// The flag is cleared when this is called. 79 | pub fn tick() -> bool { 80 | get_reg().csr.countflag() 81 | } 82 | 83 | #[allow(dead_code)] 84 | mod reg { 85 | use volatile_cell::VolatileCell; 86 | use core::ops::Drop; 87 | 88 | ioregs!(SYSTICK = { 89 | /// SysTick Control and Status Register 90 | 0x0 => reg32 csr 91 | { 92 | 16 => countflag : ro, //= Returns 1 if timer counted to 0 93 | //= since last time this was read. 94 | 2 => clksource : rw { 95 | 0 => External, //= External clock 96 | 1 => CPU, //= CPU clock 97 | }, 98 | 1 => tickint : rw, //= Enable SysTick exception 99 | 0 => enable : rw 100 | }, 101 | 102 | /// Reload Value Register 103 | 0x4 => reg32 rvr { 104 | 23..0 => reload : rw //= Reload value 105 | } 106 | 107 | /// Current Value Register 108 | 0x8 => reg32 cvr { 109 | 31..0 => current : rw //= Current timer value 110 | }, 111 | 112 | 0xc => reg32 calib { 113 | 31 => noref : ro, //= If 1, the reference clock is not provided 114 | 30 => skew : ro, //= If 1, the calibration value is inexact 115 | 23..0 => tenms : ro, //= An optional Reload value for 10ms (100Hz) timing 116 | //= If zero calibration value not known 117 | }, 118 | }); 119 | } 120 | -------------------------------------------------------------------------------- /src/hal/cortex_m0/isr.rs: -------------------------------------------------------------------------------- 1 | // Zinc, the bare metal stack for rust. 2 | // Copyright 2014 Vladimir "farcaller" Pouzanov 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | use core::option::Option; 17 | use core::option::Option::{Some, None}; 18 | 19 | extern { 20 | fn main(); 21 | fn __STACK_BASE(); 22 | 23 | fn isr_nmi(); 24 | fn isr_hardfault(); 25 | 26 | fn isr_svcall(); 27 | fn isr_pendsv(); 28 | fn isr_systick(); 29 | } 30 | 31 | #[no_mangle] 32 | pub unsafe extern fn isr_handler_wrapper() { 33 | asm!(".weak isr_nmi, isr_hardfault 34 | .weak isr_svcall, isr_pendsv, isr_systick 35 | 36 | .thumb_func 37 | isr_nmi: 38 | 39 | .thumb_func 40 | isr_hardfault: 41 | 42 | .thumb_func 43 | isr_svcall: 44 | 45 | .thumb_func 46 | isr_pendsv: 47 | 48 | .thumb_func 49 | isr_systick: 50 | 51 | b isr_default_fault 52 | 53 | .thumb_func 54 | isr_default_fault: 55 | mrs r0, psp 56 | mrs r1, msp 57 | ldr r2, [r0, 0x18] 58 | ldr r3, [r1, 0x18] 59 | bkpt" :::: "volatile"); 60 | } 61 | 62 | #[allow(non_upper_case_globals)] 63 | const ISRCount: usize = 16; 64 | 65 | #[link_section=".isr_vector"] 66 | #[allow(non_upper_case_globals)] 67 | #[no_mangle] 68 | pub static ISRVectors: [Option; ISRCount] = [ 69 | Some(__STACK_BASE), 70 | Some(main), // 1: Reset 71 | Some(isr_nmi), // 2: NMI 72 | Some(isr_hardfault), // 3: Hard Fault 73 | None, // Reserved 74 | None, // Reserved 75 | None, // Reserved 76 | None, // Reserved 77 | None, // Reserved 78 | None, // Reserved 79 | None, // Reserved 80 | Some(isr_svcall), // 11: SVCall 81 | None, // Reserved 82 | None, // Reserved 83 | Some(isr_pendsv), // 14: PendSV 84 | Some(isr_systick), // 15: SysTick 85 | ]; 86 | -------------------------------------------------------------------------------- /src/hal/cortex_m0/lock.rs: -------------------------------------------------------------------------------- 1 | // Zinc, the bare metal stack for rust. 2 | // Copyright 2014 Ben Gamari 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | use core::ty::Unsafe; 17 | use core::option::Option::{self, Some, None}; 18 | use core::ops::Drop; 19 | use core::kinds::Share; 20 | 21 | /// A lock. Note that this disables interrupts. Consequently, a task 22 | /// dying (e.g. by running out of stack space) while holding a lock 23 | /// may cause a deadlock. 24 | pub struct Lock { 25 | locked: Unsafe 26 | } 27 | 28 | #[must_use] 29 | pub struct Guard<'a>(&'a Lock); 30 | 31 | pub static STATIC_LOCK: Lock = Lock { locked: Unsafe { value: false, marker1: InvariantType } }; 32 | 33 | impl Lock { 34 | pub fn new() -> Lock { 35 | Lock { locked: Unsafe::new(false) } 36 | } 37 | 38 | pub fn try_lock<'a>(&'a self) -> Option> { 39 | unsafe { 40 | let crit = NoInterrupts::new(); 41 | let locked = self.locked.get(); 42 | match *locked { 43 | true => return None, 44 | false => { 45 | *locked = true; 46 | return Some(Guard(self)); 47 | } 48 | } 49 | } 50 | } 51 | 52 | fn unlock<'a>(&'a self) { 53 | unsafe { 54 | let crit = NoInterrupts::new(); 55 | *self.locked.get() = false; 56 | } 57 | } 58 | } 59 | 60 | #[unsafe_destructor] 61 | impl<'a> Drop for Guard<'a> { 62 | fn drop(&mut self) { 63 | let &Guard(ref lock) = self; 64 | lock.unlock(); 65 | } 66 | } 67 | 68 | impl Share for Lock { } 69 | -------------------------------------------------------------------------------- /src/hal/cortex_m0/mod.rs: -------------------------------------------------------------------------------- 1 | // Zinc, the bare metal stack for rust. 2 | // Copyright 2014 Ben Gamari 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | /*! 17 | Generic routines for ARM Cortex-M0 cores. 18 | 19 | This module also provides `isr.rs`, that is not compiled as a part of this 20 | crate. `isr.rs` provides ISR vector table. 21 | */ 22 | 23 | pub use super::cortex_common::systick; 24 | pub use super::cortex_common::scb; 25 | pub use super::cortex_common::nvic; 26 | pub use super::cortex_common::irq; 27 | pub mod lock; 28 | -------------------------------------------------------------------------------- /src/hal/cortex_m3/isr.rs: -------------------------------------------------------------------------------- 1 | // Zinc, the bare metal stack for rust. 2 | // Copyright 2014 Vladimir "farcaller" Pouzanov 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | use core::option::Option; 17 | use core::option::Option::{Some, None}; 18 | 19 | extern { 20 | fn main(); 21 | fn __STACK_BASE(); 22 | 23 | fn isr_nmi(); 24 | fn isr_hardfault(); 25 | fn isr_mmfault(); 26 | fn isr_busfault(); 27 | fn isr_usagefault(); 28 | 29 | fn isr_svcall(); 30 | fn isr_pendsv(); 31 | fn isr_systick(); 32 | 33 | fn isr_debugmon(); 34 | fn isr_reserved_1(); 35 | } 36 | 37 | #[no_mangle] 38 | pub unsafe extern fn isr_handler_wrapper() { 39 | asm!(".weak isr_nmi, isr_hardfault, isr_mmfault, isr_busfault 40 | .weak isr_usagefault, isr_svcall, isr_pendsv, isr_systick 41 | .weak isr_debugmon 42 | .weak isr_reserved_1 43 | 44 | .thumb_func 45 | isr_nmi: 46 | 47 | .thumb_func 48 | isr_hardfault: 49 | 50 | .thumb_func 51 | isr_mmfault: 52 | 53 | .thumb_func 54 | isr_busfault: 55 | 56 | .thumb_func 57 | isr_usagefault: 58 | 59 | .thumb_func 60 | isr_svcall: 61 | 62 | .thumb_func 63 | isr_pendsv: 64 | 65 | .thumb_func 66 | isr_systick: 67 | 68 | b isr_default_fault 69 | 70 | .thumb_func 71 | isr_default_fault: 72 | mrs r0, psp 73 | mrs r1, msp 74 | ldr r2, [r0, 0x18] 75 | ldr r3, [r1, 0x18] 76 | bkpt" :::: "volatile"); 77 | } 78 | 79 | #[allow(non_upper_case_globals)] 80 | const ISRCount: usize = 16; 81 | 82 | #[link_section=".isr_vector"] 83 | #[allow(non_upper_case_globals)] 84 | #[no_mangle] 85 | pub static ISRVectors: [Option; ISRCount] = [ 86 | Some(__STACK_BASE), 87 | Some(main), // Reset 88 | Some(isr_nmi), // NMI 89 | Some(isr_hardfault), // Hard Fault 90 | Some(isr_mmfault), // CM3 Memory Management Fault 91 | Some(isr_busfault), // CM3 Bus Fault 92 | Some(isr_usagefault), // CM3 Usage Fault 93 | Some(isr_reserved_1), // Reserved - Used as NXP Checksum 94 | None, // Reserved 95 | None, // Reserved 96 | None, // Reserved 97 | Some(isr_svcall), // SVCall 98 | Some(isr_debugmon), // Reserved for debug 99 | None, // Reserved 100 | Some(isr_pendsv), // PendSV 101 | Some(isr_systick), // SysTick 102 | ]; 103 | -------------------------------------------------------------------------------- /src/hal/cortex_m3/lock.rs: -------------------------------------------------------------------------------- 1 | // Zinc, the bare metal stack for rust. 2 | // Copyright 2014 Ben Gamari 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | use core::ty::Unsafe; 17 | use core::option::Option::{self, Some, None}; 18 | use core::ops::Drop; 19 | use core::kinds::Share; 20 | use core::kinds::marker::InvariantType; 21 | 22 | /// A lock 23 | pub struct Lock { 24 | locked: Unsafe 25 | } 26 | 27 | #[must_use] 28 | pub struct Guard<'a>(&'a Lock); 29 | 30 | pub static STATIC_LOCK: Lock = Lock { locked: Unsafe { value: 0, marker1: InvariantType } }; 31 | 32 | #[cfg(target_arch = "arm")] 33 | #[inline(always)] 34 | unsafe fn exclusive_load(addr: *const u32) -> u32 { 35 | let mut value: u32; 36 | asm!("ldrex $0, [$1]" 37 | : "=r"(value) 38 | : "r"(addr) 39 | : 40 | : "volatile" 41 | ); 42 | value 43 | } 44 | 45 | #[cfg(not(target_arch = "arm"))] 46 | unsafe fn exclusive_load(addr: *const u32) -> u32 { unimplemented!() } 47 | 48 | #[cfg(target_arch = "arm")] 49 | #[inline(always)] 50 | unsafe fn exclusive_store(addr: *mut u32, value: u32) -> bool { 51 | let mut success: u32; 52 | asm!("strex $0, $2, [$1]" 53 | : "=r"(success) 54 | : "r"(addr), "r"(value) 55 | : 56 | : "volatile" 57 | ); 58 | success == 0 59 | } 60 | 61 | #[cfg(not(target_arch = "arm"))] 62 | unsafe fn exclusive_store(addr: *mut u32, value: u32) -> bool { 63 | unimplemented!() 64 | } 65 | 66 | impl Lock { 67 | pub fn new() -> Lock { 68 | Lock { locked: Unsafe::new(0) } 69 | } 70 | 71 | pub fn try_lock<'a>(&'a self) -> Option> { 72 | unsafe { 73 | let ptr: *mut u32 = self.locked.get(); 74 | let locked = exclusive_load(&*ptr) == 1; 75 | let success = exclusive_store(ptr, 1); 76 | if !locked && success { 77 | return Some(Guard(self)); 78 | } else { 79 | return None; 80 | } 81 | } 82 | } 83 | 84 | fn unlock<'a>(&'a self) { 85 | unsafe { 86 | loop { 87 | let ptr: *mut u32 = self.locked.get(); 88 | let _locked = exclusive_load(&*ptr) == 1; 89 | let success = exclusive_store(ptr, 0); 90 | if success { 91 | break; 92 | } 93 | } 94 | } 95 | } 96 | } 97 | 98 | #[unsafe_destructor] 99 | impl<'a> Drop for Guard<'a> { 100 | fn drop(&mut self) { 101 | let &Guard(ref lock) = self; 102 | lock.unlock(); 103 | } 104 | } 105 | 106 | impl Share for Lock { } 107 | -------------------------------------------------------------------------------- /src/hal/cortex_m3/mod.rs: -------------------------------------------------------------------------------- 1 | // Zinc, the bare metal stack for rust. 2 | // Copyright 2014 Vladimir "farcaller" Pouzanov 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | /*! 17 | Generic routines for ARM Cortex-M3 cores. 18 | 19 | This module also provides `isr.rs`, that is not compiled as a part of this 20 | crate. `isr.rs` provides ISR vector table. 21 | */ 22 | 23 | pub use super::cortex_common::systick; 24 | pub use super::cortex_common::scb; 25 | pub use super::cortex_common::nvic; 26 | pub use super::cortex_common::mpu; 27 | pub use super::cortex_common::irq; 28 | #[cfg(feature = "multitasking")] pub mod sched; 29 | #[cfg(feature = "multitasking")] pub mod lock; 30 | -------------------------------------------------------------------------------- /src/hal/cortex_m3/sched.S: -------------------------------------------------------------------------------- 1 | /* 2 | Zinc, the bare metal stack for rust. 3 | Copyright 2014 Vladimir "farcaller" Pouzanov 4 | 5 | Licensed under the Apache License, Version 2.0 (the "License"); 6 | you may not use this file except in compliance with the License. 7 | You may obtain a copy of the License at 8 | 9 | http://www.apache.org/licenses/LICENSE-2.0 10 | 11 | Unless required by applicable law or agreed to in writing, software 12 | distributed under the License is distributed on an "AS IS" BASIS, 13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | See the License for the specific language governing permissions and 15 | limitations under the License. 16 | */ 17 | 18 | 19 | .syntax unified 20 | .cpu cortex-m3 21 | .arch armv7-m 22 | .text 23 | 24 | #define THUMB_FUNC(NAME) \ 25 | .section .text.sched.##NAME; \ 26 | .align 2; \ 27 | .global NAME; \ 28 | .thumb; \ 29 | .thumb_func; \ 30 | .type NAME, %function; \ 31 | NAME: 32 | 33 | /* SysTick handler, for cortex-m3 we save r4-r11 and ask to switch context. */ 34 | THUMB_FUNC(isr_systick) 35 | mrs r0, psp 36 | stmdb r0!, {r4-r11} 37 | msr psp, r0 38 | 39 | bl task_scheduler 40 | 41 | mrs r0, psp 42 | ldmfd r0!, {r4-r11} 43 | msr psp, r0 44 | 45 | ldr lr, =0xfffffffd /* return to thread mode using stack at PSP */ 46 | bx lr 47 | 48 | /* PendSV handler, same as above. */ 49 | THUMB_FUNC(isr_pendsv) 50 | mrs r0, psp 51 | stmdb r0!, {r4-r11} 52 | msr psp, r0 53 | 54 | bl task_scheduler 55 | 56 | mrs r0, psp 57 | ldmfd r0!, {r4-r11} 58 | msr psp, r0 59 | 60 | ldr lr, =0xfffffffd 61 | bx lr 62 | 63 | /* SVCall handler, calls function at arg0 with arg1. */ 64 | THUMB_FUNC(isr_svcall) 65 | mrs r2, psp /* r2 points to user stack */ 66 | 67 | ldr r1, [r2] /* load func addr from stack */ 68 | ldr r0, [r2, 4] /* load func arg from stack */ 69 | push {lr} /* push lr onto msp */ 70 | 71 | blx r1 72 | 73 | pop {pc} 74 | 75 | THUMB_FUNC(syscall) 76 | svc 0 77 | bx lr 78 | -------------------------------------------------------------------------------- /src/hal/cortex_m3/sched.rs: -------------------------------------------------------------------------------- 1 | // Zinc, the bare metal stack for rust. 2 | // Copyright 2014 Vladimir "farcaller" Pouzanov 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | //! Cortex-M3 specific support code for scheduler. 17 | 18 | use core::ops::Drop; 19 | use core::intrinsics::abort; 20 | 21 | use os::task::Task; 22 | use super::scb; 23 | 24 | /// Force context switch. Triggers PendSV interrupt. 25 | #[inline(always)] 26 | pub fn switch_context() { 27 | scb::set_pendsv(true); 28 | } 29 | 30 | /// Sets task stack pointer (PSP). 31 | #[cfg(target_arch = "arm")] 32 | #[inline(always)] 33 | pub fn set_task_stack_pointer(val: u32) { 34 | unsafe { asm!("msr psp, $0" :: "r"(val) :: "volatile") }; 35 | } 36 | 37 | #[cfg(not(target_arch = "arm"))] 38 | pub fn set_task_stack_pointer(val: u32) { unimplemented!() } 39 | 40 | /// Returns task stack pointer (PSP). 41 | #[cfg(target_arch = "arm")] 42 | #[inline(always)] 43 | pub fn get_task_stack_pointer() -> u32 { 44 | let mut val: u32; 45 | unsafe { asm!("mrs $0, psp" : "=r"(val) ::: "volatile") }; 46 | val 47 | } 48 | 49 | #[cfg(not(target_arch = "arm"))] 50 | pub fn get_task_stack_pointer() -> u32 { unimplemented!() } 51 | 52 | /// Returns current stack pointer (SP, which may be PSP or MSP). 53 | #[cfg(target_arch = "arm")] 54 | #[inline(always)] 55 | pub fn get_current_stack_pointer() -> u32 { 56 | let mut val: u32; 57 | unsafe { asm!("mov $0, sp" : "=r"(val) ::: "volatile") }; 58 | val 59 | } 60 | 61 | #[cfg(not(target_arch = "arm"))] 62 | pub fn get_current_stack_pointer() -> u32 { unimplemented!() } 63 | 64 | /// State, that's saved by hardware upon entering an ISR. 65 | pub struct SavedState { 66 | pub r0: u32, 67 | pub r1: u32, 68 | pub r2: u32, 69 | pub r3: u32, 70 | pub r12: u32, 71 | pub lr: u32, 72 | pub pc: u32, 73 | pub psr: u32, 74 | } 75 | 76 | impl SavedState { 77 | #[inline(always)] 78 | pub fn new(t: Task, arg: u32) -> SavedState { 79 | SavedState { 80 | r0: arg, 81 | r1: 0, 82 | r2: 0, 83 | r3: 0, 84 | r12: 0, 85 | lr: task_finished as u32, 86 | pc: t as u32, 87 | psr: 0x01000000, // thumb state 88 | } 89 | } 90 | } 91 | 92 | // TODO(farcaller): this should actually kill the task. 93 | // TODO(bgamari): It should also unlock anything the task holds 94 | /// Default handler for task that tries to return. 95 | #[cfg(target_os = "none")] 96 | unsafe fn task_finished() { 97 | core::intrinsics::breakpoint(); 98 | } 99 | 100 | #[cfg(not(target_os = "none"))] 101 | unsafe fn task_finished() { unimplemented!() } 102 | 103 | -------------------------------------------------------------------------------- /src/hal/cortex_m4/mod.rs: -------------------------------------------------------------------------------- 1 | // Zinc, the bare metal stack for rust. 2 | // Copyright 2014 Ben Gamari 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | /*! 17 | Generic routines for ARM Cortex-M4 cores. 18 | 19 | This module also provides `isr.rs`, that is not compiled as a part of this 20 | crate. `isr.rs` provides ISR vector table. 21 | */ 22 | 23 | pub use super::cortex_common::systick; 24 | pub use super::cortex_common::scb; 25 | pub use super::cortex_common::nvic; 26 | pub use super::cortex_common::mpu; 27 | pub use super::cortex_common::irq; 28 | -------------------------------------------------------------------------------- /src/hal/cortex_m7/mod.rs: -------------------------------------------------------------------------------- 1 | // Zinc, the bare metal stack for rust. 2 | // Copyright 2014 Ben Gamari 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | /*! 17 | Generic routines for ARM Cortex-M7 cores. 18 | 19 | This module also provides `isr.rs`, that is not compiled as a part of this 20 | crate. `isr.rs` provides ISR vector table. 21 | */ 22 | 23 | pub use super::cortex_common::systick; 24 | pub use super::cortex_common::scb; 25 | pub use super::cortex_common::nvic; 26 | pub use super::cortex_common::mpu; 27 | pub use super::cortex_common::irq; 28 | -------------------------------------------------------------------------------- /src/hal/isr.rs: -------------------------------------------------------------------------------- 1 | // Zinc, the bare metal stack for rust. 2 | // Copyright 2014 Vladimir "farcaller" Pouzanov 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | //! This file is not part of zinc crate, it is linked separately, alongside the 17 | //! ISRs for the platform. 18 | 19 | #![allow(missing_docs)] 20 | 21 | #[cfg(feature = "cpu_cortex-m0")] 22 | #[path="cortex_m0/isr.rs"] pub mod isr_cortex_m0; 23 | 24 | #[cfg(feature = "cpu_cortex-m3")] 25 | #[path="cortex_m3/isr.rs"] pub mod isr_cortex_m3; 26 | 27 | #[cfg(feature = "cpu_cortex-m4")] 28 | #[path="cortex_m3/isr.rs"] pub mod isr_cortex_m4; 29 | 30 | #[cfg(feature = "cpu_cortex-m7")] 31 | #[path="cortex_m3/isr.rs"] pub mod isr_cortex_m7; 32 | 33 | #[cfg(feature = "mcu_lpc17xx")] 34 | #[path="lpc17xx/isr.rs"] pub mod isr_lpc17xx; 35 | 36 | #[cfg(feature = "mcu_k20")] 37 | #[path="k20/isr.rs"] pub mod isr_k20; 38 | 39 | #[cfg(feature = "mcu_tiva_c")] 40 | #[path="tiva_c/isr.rs"] pub mod isr_tiva_c; 41 | -------------------------------------------------------------------------------- /src/hal/k20/layout.ld: -------------------------------------------------------------------------------- 1 | __aeabi_unwind_cpp_pr0 = abort; 2 | __aeabi_unwind_cpp_pr1 = abort; 3 | __aeabi_unwind_cpp_pr2 = abort; 4 | __aeabi_memclr4 = __aeabi_memclr; 5 | 6 | /* FIXME(bgamari): Make stack base configurable? */ 7 | __STACK_BASE = 0x20001FFF; 8 | 9 | _data_load = LOADADDR(.data); 10 | 11 | INCLUDE iomem.ld 12 | 13 | ENTRY(main) 14 | 15 | /* For MK20DX32 */ 16 | MEMORY 17 | { 18 | VECT (R) : ORIGIN = 0x00000000, LENGTH = 0x3FC /* Vector area */ 19 | FIRC (R) : ORIGIN = 0x000003FC, LENGTH = 4 /* Custom IRC user trim */ 20 | FCFG (R) : ORIGIN = 0x00000400, LENGTH = 16 /* Flash config */ 21 | FLASH (RX) : ORIGIN = 0x00000410, LENGTH = 32K - 0x410 22 | RAM (WAIL) : ORIGIN = 0x20000000 - 8K / 2, LENGTH = 8K 23 | } 24 | 25 | REGION_ALIAS("vectors", VECT); 26 | REGION_ALIAS("flash_config", FCFG) 27 | REGION_ALIAS("rom", FLASH); 28 | REGION_ALIAS("ram", RAM); 29 | 30 | SECTIONS 31 | { 32 | .vector : ALIGN(4) 33 | { 34 | FILL(0xff) 35 | 36 | KEEP(*(.isr_vector)) 37 | KEEP(*(.isr_vector_nvic)) 38 | } > vectors 39 | 40 | .flashcfg : ALIGN(4) 41 | { 42 | KEEP(*(.flash_configuration)) 43 | } > flash_config 44 | 45 | .text : ALIGN(4) 46 | { 47 | FILL(0xff) 48 | *(.text*) 49 | *(.rodata .rodata.*) 50 | } > rom 51 | 52 | .data : ALIGN(4) 53 | { 54 | _data = .; 55 | 56 | *(SORT_BY_ALIGNMENT(.data*)) 57 | . = ALIGN(4); 58 | 59 | _edata = .; 60 | } > ram AT>rom = 0xff 61 | 62 | .bss : ALIGN(4) 63 | { 64 | _bss = .; 65 | 66 | *(.bss*) 67 | *(COMMON) 68 | . = ALIGN(4); 69 | 70 | _ebss = .; 71 | 72 | . += 4; 73 | 74 | __STACK_LIMIT = .; 75 | 76 | . += 4; 77 | 78 | _eglobals = .; 79 | } > ram 80 | 81 | /DISCARD/ : 82 | { 83 | *(.glue_7*) /* arm-thumb interworking */ 84 | *(.v4_bx) /* ARMv4 interworking fixup for missing BX */ 85 | *(.vfp11_veneer) /* VFP11 bugfixes s.a. http://sourceware.org/ml/binutils/2006-12/msg00196.html */ 86 | *(.iplt .igot.plt) /* STT_GNU_IFUNC symbols */ 87 | *(.rel.*) /* dynamic relocations */ 88 | *(.ARM.exidx*) /* index entries for section unwinding */ 89 | *(.ARM.extab*) /* exception unwinding information */ 90 | *(.debug_gdb_scripts) 91 | } 92 | } 93 | 94 | -------------------------------------------------------------------------------- /src/hal/k20/mod.rs: -------------------------------------------------------------------------------- 1 | // Zinc, the bare metal stack for rust. 2 | // Copyright 2014 Ben Gamari 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | //! HAL for Freescale Kinetis K20. 17 | 18 | pub mod sim; 19 | pub mod pin; 20 | pub mod uart; 21 | pub mod watchdog; 22 | -------------------------------------------------------------------------------- /src/hal/k20/watchdog.rs: -------------------------------------------------------------------------------- 1 | // Zinc, the bare metal stack for rust. 2 | // Copyright 2014 Dawid Ciężarkiewcz 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | //! Watchdog for Kinetis SIM module. 17 | 18 | use util::support::nop; 19 | 20 | #[path="../../util/ioreg.rs"] mod ioreg; 21 | 22 | /// Watchdog state 23 | #[allow(missing_docs)] 24 | #[derive(Clone, Copy)] 25 | pub enum State { 26 | Disabled, 27 | Enabled, 28 | } 29 | 30 | /// Init watchdog 31 | pub fn init(state : State) { 32 | use self::State::*; 33 | unlock(); 34 | match state { 35 | Disabled => { 36 | reg::WDOG.stctrlh.set_en(false); 37 | }, 38 | Enabled => { 39 | reg::WDOG.stctrlh.set_allowupdate(true); 40 | }, 41 | } 42 | } 43 | 44 | fn unlock() { 45 | use self::reg::WDOG_unlock_unlock::*; 46 | reg::WDOG.unlock.set_unlock(UnlockSeq1); 47 | reg::WDOG.unlock.set_unlock(UnlockSeq2); 48 | 49 | // Enforce one cycle delay 50 | nop(); 51 | } 52 | 53 | /// Write refresh sequence to refresh watchdog 54 | pub fn refresh() { 55 | use self::reg::WDOG_refresh_refresh::*; 56 | reg::WDOG.refresh.set_refresh(RefreshSeq1); 57 | reg::WDOG.refresh.set_refresh(RefreshSeq2); 58 | } 59 | 60 | #[allow(dead_code)] 61 | mod reg { 62 | use volatile_cell::VolatileCell; 63 | use core::ops::Drop; 64 | 65 | ioregs!(WDOG = { 66 | /// Status and Control Register High 67 | 0x0 => reg16 stctrlh 68 | { 69 | 0 => en, //= Watchdog enable 70 | 4 => allowupdate //= Enables updates to watchdog write-once registers, 71 | //= after the reset-triggered initial configuration window 72 | }, 73 | 74 | /// Refresh Register 75 | 0xc => reg16 refresh { 76 | 0..15 => refresh: wo 77 | { 78 | 0xa602 => RefreshSeq1, 79 | 0xb480 => RefreshSeq2, 80 | }, 81 | }, 82 | 83 | /// Unlock Register 84 | 0xe => reg16 unlock { 85 | 0..15 => unlock: wo 86 | { 87 | 0xc520 => UnlockSeq1, 88 | 0xd928 => UnlockSeq2, 89 | }, 90 | }, 91 | 92 | }); 93 | 94 | 95 | extern { 96 | #[link_name="k20_iomem_WDOG"] pub static WDOG: WDOG; 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /src/hal/layout_common.ld: -------------------------------------------------------------------------------- 1 | /* TODO(farcaller): layout_common isn't actually common. k20 keeps own copy */ 2 | __aeabi_unwind_cpp_pr0 = abort; 3 | __aeabi_unwind_cpp_pr1 = abort; 4 | __aeabi_unwind_cpp_pr2 = abort; 5 | __exidx_start = abort; 6 | __exidx_end = abort; 7 | 8 | __aeabi_memclr4 = __aeabi_memclr; 9 | 10 | SECTIONS 11 | { 12 | .vector : ALIGN(4) 13 | { 14 | FILL(0xff) 15 | 16 | KEEP(*(.isr_vector)) 17 | KEEP(*(.isr_vector_nvic)) 18 | } > vectors 19 | 20 | .text : ALIGN(4) 21 | { 22 | FILL(0xff) 23 | *(.text*) 24 | *(.rodata .rodata.*) 25 | } > rom 26 | 27 | .data : ALIGN(4) 28 | { 29 | _data = .; 30 | 31 | *(SORT_BY_ALIGNMENT(.data*)) 32 | . = ALIGN(4); 33 | 34 | _edata = .; 35 | } > ram AT>rom = 0xff 36 | 37 | .bss : ALIGN(4) 38 | { 39 | _bss = .; 40 | 41 | *(.bss*) 42 | *(COMMON) 43 | . = ALIGN(4); 44 | 45 | _ebss = .; 46 | 47 | . += 4; 48 | 49 | __STACK_LIMIT = .; 50 | 51 | . += 4; 52 | 53 | _eglobals = .; 54 | } > ram 55 | 56 | /DISCARD/ : 57 | { 58 | *(.glue_7*) /* arm-thumb interworking */ 59 | *(.v4_bx) /* ARMv4 interworking fixup for missing BX */ 60 | *(.vfp11_veneer) /* VFP11 bugfixes s.a. http://sourceware.org/ml/binutils/2006-12/msg00196.html */ 61 | *(.iplt .igot.plt) /* STT_GNU_IFUNC symbols */ 62 | *(.rel.*) /* dynamic relocations */ 63 | *(.ARM.exidx*) /* index entries for section unwinding */ 64 | *(.ARM.extab*) /* exception unwinding information */ 65 | *(.debug_gdb_scripts) 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/hal/lpc11xx/layout.ld: -------------------------------------------------------------------------------- 1 | __STACK_BASE = 0x10002000; 2 | 3 | _data_load = LOADADDR(.data); 4 | 5 | ENTRY(main) 6 | 7 | MEMORY 8 | { 9 | rom(RX) : ORIGIN = 0x00000000, LENGTH = 32K 10 | ram(WAIL) : ORIGIN = 0x10000000, LENGTH = 4K 11 | } 12 | 13 | REGION_ALIAS("vectors", rom); 14 | 15 | INCLUDE layout_common.ld 16 | -------------------------------------------------------------------------------- /src/hal/lpc11xx/mod.rs: -------------------------------------------------------------------------------- 1 | // Zinc, the bare metal stack for rust. 2 | // Copyright 2015 Vladimir "farcaller" Pouzanov 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | //! HAL for NXP LPC11xx. 17 | 18 | mod regs; 19 | pub mod syscon; 20 | -------------------------------------------------------------------------------- /src/hal/lpc17xx/iomem.ld: -------------------------------------------------------------------------------- 1 | PROVIDE(isr_wdt = isr_hardfault); 2 | PROVIDE(isr_timer_0 = isr_hardfault); 3 | PROVIDE(isr_timer_1 = isr_hardfault); 4 | PROVIDE(isr_timer_2 = isr_hardfault); 5 | PROVIDE(isr_timer_3 = isr_hardfault); 6 | PROVIDE(isr_uart_0 = isr_hardfault); 7 | PROVIDE(isr_uart_1 = isr_hardfault); 8 | PROVIDE(isr_uart_2 = isr_hardfault); 9 | PROVIDE(isr_uart_3 = isr_hardfault); 10 | PROVIDE(isr_pwm_1 = isr_hardfault); 11 | PROVIDE(isr_i2c_0 = isr_hardfault); 12 | PROVIDE(isr_i2c_1 = isr_hardfault); 13 | PROVIDE(isr_i2c_2 = isr_hardfault); 14 | PROVIDE(isr_spi = isr_hardfault); 15 | PROVIDE(isr_ssp_0 = isr_hardfault); 16 | PROVIDE(isr_ssp_1 = isr_hardfault); 17 | PROVIDE(isr_pll_0 = isr_hardfault); 18 | PROVIDE(isr_rtc = isr_hardfault); 19 | PROVIDE(isr_eint_0 = isr_hardfault); 20 | PROVIDE(isr_eint_1 = isr_hardfault); 21 | PROVIDE(isr_eint_2 = isr_hardfault); 22 | PROVIDE(isr_eint_3 = isr_hardfault); 23 | PROVIDE(isr_adc = isr_hardfault); 24 | PROVIDE(isr_bod = isr_hardfault); 25 | PROVIDE(isr_usb = isr_hardfault); 26 | PROVIDE(isr_can = isr_hardfault); 27 | PROVIDE(isr_dma = isr_hardfault); 28 | PROVIDE(isr_i2s = isr_hardfault); 29 | PROVIDE(isr_enet = isr_hardfault); 30 | PROVIDE(isr_rit = isr_hardfault); 31 | PROVIDE(isr_mcpwm = isr_hardfault); 32 | PROVIDE(isr_qei = isr_hardfault); 33 | PROVIDE(isr_pll_1 = isr_hardfault); 34 | PROVIDE(isr_usb_activity = isr_hardfault); 35 | PROVIDE(isr_can_activity = isr_hardfault); 36 | 37 | lpc17xx_iomem_GPIO0 = 0x2009C000; 38 | lpc17xx_iomem_GPIO1 = 0x2009C020; 39 | lpc17xx_iomem_GPIO2 = 0x2009C040; 40 | lpc17xx_iomem_GPIO3 = 0x2009C060; 41 | lpc17xx_iomem_GPIO4 = 0x2009C080; 42 | 43 | lpc17xx_iomem_TIMER0 = 0x40004000; 44 | lpc17xx_iomem_TIMER1 = 0x40008000; 45 | 46 | lpc17xx_iomem_UART0 = 0x4000C000; 47 | 48 | lpc17xx_iomem_PINSEL0 = 0x4002C000; 49 | lpc17xx_iomem_PINSEL1 = 0x4002C004; 50 | lpc17xx_iomem_PINSEL2 = 0x4002C008; 51 | lpc17xx_iomem_PINSEL3 = 0x4002C00C; 52 | lpc17xx_iomem_PINSEL4 = 0x4002C010; 53 | lpc17xx_iomem_PINSEL7 = 0x4002C01C; 54 | lpc17xx_iomem_PINSEL9 = 0x4002C024; 55 | lpc17xx_iomem_PINSEL10 = 0x4002C028; 56 | 57 | lpc17xx_iomem_PINMODE0 = 0x4002C040; 58 | lpc17xx_iomem_PINMODE1 = 0x4002C044; 59 | lpc17xx_iomem_PINMODE2 = 0x4002C048; 60 | lpc17xx_iomem_PINMODE3 = 0x4002C04C; 61 | lpc17xx_iomem_PINMODE4 = 0x4002C050; 62 | lpc17xx_iomem_PINMODE7 = 0x4002C05C; 63 | lpc17xx_iomem_PINMODE9 = 0x4002C064; 64 | 65 | lpc17xx_iomem_SSP1 = 0x40030000; 66 | lpc17xx_iomem_SSP0 = 0x40088000; 67 | 68 | lpc17xx_iomem_ADC = 0x40034000; 69 | 70 | lpc17xx_iomem_TIMER2 = 0x40090000; 71 | lpc17xx_iomem_TIMER3 = 0x40094000; 72 | 73 | lpc17xx_iomem_UART2 = 0x40098000; 74 | lpc17xx_iomem_UART3 = 0x4009C000; 75 | 76 | lpc17xx_iomem_FLASHCFG = 0x400FC000; 77 | 78 | lpc17xx_iomem_PLL0CON = 0x400FC080; 79 | lpc17xx_iomem_PLL0CFG = 0x400FC084; 80 | lpc17xx_iomem_PLL0STAT = 0x400FC088; 81 | lpc17xx_iomem_PLL0FEED = 0x400FC08C; 82 | 83 | lpc17xx_iomem_PCONP = 0x400FC0C4; 84 | 85 | lpc17xx_iomem_CCLKCFG = 0x400FC104; 86 | lpc17xx_iomem_CLKSRCSEL = 0x400FC10C; 87 | 88 | lpc17xx_iomem_PCLKSEL0 = 0x400FC1A8; 89 | lpc17xx_iomem_PCLKSEL1 = 0x400FC1AC; 90 | 91 | lpc17xx_iomem_SCS = 0x400FC1A0; 92 | -------------------------------------------------------------------------------- /src/hal/lpc17xx/isr.rs: -------------------------------------------------------------------------------- 1 | // Zinc, the bare metal stack for rust. 2 | // Copyright 2014 Vladimir "farcaller" Pouzanov 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | //! ISR Data for k20 17 | 18 | use core::option::Option::{self, Some}; 19 | 20 | extern { 21 | fn isr_wdt(); 22 | fn isr_timer_0(); 23 | fn isr_timer_1(); 24 | fn isr_timer_2(); 25 | fn isr_timer_3(); 26 | fn isr_uart_0(); 27 | fn isr_uart_1(); 28 | fn isr_uart_2(); 29 | fn isr_uart_3(); 30 | fn isr_pwm_1(); 31 | fn isr_i2c_0(); 32 | fn isr_i2c_1(); 33 | fn isr_i2c_2(); 34 | fn isr_spi(); 35 | fn isr_ssp_0(); 36 | fn isr_ssp_1(); 37 | fn isr_pll_0(); 38 | fn isr_rtc(); 39 | fn isr_eint_0(); 40 | fn isr_eint_1(); 41 | fn isr_eint_2(); 42 | fn isr_eint_3(); 43 | fn isr_adc(); 44 | fn isr_bod(); 45 | fn isr_usb(); 46 | fn isr_can(); 47 | fn isr_dma(); 48 | fn isr_i2s(); 49 | fn isr_enet(); 50 | fn isr_rit(); 51 | fn isr_mcpwm(); 52 | fn isr_qei(); 53 | fn isr_pll_1(); 54 | fn isr_usb_activity(); 55 | fn isr_can_activity(); 56 | } 57 | 58 | #[allow(non_upper_case_globals)] 59 | const ISRCount: usize = 35; 60 | 61 | #[allow(non_upper_case_globals)] 62 | #[link_section=".isr_vector_nvic"] 63 | #[no_mangle] 64 | pub static NVICVectors: [Option; ISRCount] = [ 65 | // s.a. lpc17xx user manual, table 50 (chapter 6.3) 66 | Some(isr_wdt), 67 | Some(isr_timer_0), 68 | Some(isr_timer_1), 69 | Some(isr_timer_2), 70 | Some(isr_timer_3), 71 | Some(isr_uart_0), 72 | Some(isr_uart_1), 73 | Some(isr_uart_2), 74 | Some(isr_uart_3), 75 | Some(isr_pwm_1), 76 | Some(isr_i2c_0), 77 | Some(isr_i2c_1), 78 | Some(isr_i2c_2), 79 | Some(isr_spi), 80 | Some(isr_ssp_0), 81 | Some(isr_ssp_1), 82 | Some(isr_pll_0), 83 | Some(isr_rtc), 84 | Some(isr_eint_0), 85 | Some(isr_eint_1), 86 | Some(isr_eint_2), 87 | Some(isr_eint_3), 88 | Some(isr_adc), 89 | Some(isr_bod), 90 | Some(isr_usb), 91 | Some(isr_can), 92 | Some(isr_dma), 93 | Some(isr_i2s), 94 | Some(isr_enet), 95 | Some(isr_rit), 96 | Some(isr_mcpwm), 97 | Some(isr_qei), 98 | Some(isr_pll_1), 99 | Some(isr_usb_activity), 100 | Some(isr_can_activity), 101 | ]; 102 | -------------------------------------------------------------------------------- /src/hal/lpc17xx/layout.ld: -------------------------------------------------------------------------------- 1 | __STACK_BASE = 0x10002000; 2 | 3 | INCLUDE iomem.ld 4 | 5 | isr_reserved_1 = 0 - (__STACK_BASE + main + 1 + isr_nmi + 1 + isr_hardfault + 1); 6 | 7 | _data_load = LOADADDR(.data); 8 | 9 | ENTRY(main) 10 | 11 | MEMORY 12 | { 13 | rom(RX) : ORIGIN = 0x00000000, LENGTH = 64K 14 | ram(WAIL) : ORIGIN = 0x10000000, LENGTH = 0x2000 15 | } 16 | 17 | REGION_ALIAS("vectors", rom); 18 | 19 | INCLUDE layout_common.ld 20 | -------------------------------------------------------------------------------- /src/hal/lpc17xx/mod.rs: -------------------------------------------------------------------------------- 1 | // Zinc, the bare metal stack for rust. 2 | // Copyright 2014 Vladimir "farcaller" Pouzanov 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | //! HAL for NXP LPC17xx. 17 | 18 | pub mod system_clock; 19 | pub mod peripheral_clock; 20 | pub mod pin; 21 | pub mod pwm; 22 | // pub mod ssp; 23 | pub mod timer; 24 | pub mod uart; 25 | -------------------------------------------------------------------------------- /src/hal/lpc17xx/timer.rs: -------------------------------------------------------------------------------- 1 | // Zinc, the bare metal stack for rust. 2 | // Copyright 2014 Vladimir "farcaller" Pouzanov 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | /*! 17 | Timer configuration. 18 | 19 | This code supports all four primary timers of the MCU. 20 | */ 21 | 22 | use hal::timer; 23 | 24 | use self::TimerPeripheral::*; 25 | 26 | #[path="../../util/ioreg.rs"] 27 | #[macro_use] mod ioreg; 28 | 29 | /// Available timer peripherals. 30 | #[allow(missing_docs)] 31 | #[derive(Clone, Copy)] 32 | pub enum TimerPeripheral { 33 | Timer0, 34 | Timer1, 35 | Timer2, 36 | Timer3, 37 | } 38 | 39 | /// Configuration for timer. 40 | #[derive(Clone, Copy)] 41 | pub struct TimerConf { 42 | /// Peripheral to use. 43 | pub timer: TimerPeripheral, 44 | /// Number of clock ticks to increment the counter. 45 | pub counter: u32, 46 | /// Clock divisor. 47 | pub divisor: u8, 48 | } 49 | 50 | /// Struct describing a timer instance. 51 | #[derive(Clone, Copy)] 52 | pub struct Timer { 53 | reg: &'static reg::TIMER, 54 | } 55 | 56 | impl Timer { 57 | /// Create an start a timer. 58 | pub fn new(peripheral: TimerPeripheral, counter: u32, divisor: u8) -> Timer { 59 | use hal::lpc17xx::peripheral_clock::PeripheralClock as Clock; 60 | let (clock, reg) = match peripheral { 61 | Timer0 => (Clock::TIM0Clock, ®::TIMER0), 62 | Timer1 => (Clock::TIM1Clock, ®::TIMER1), 63 | Timer2 => (Clock::TIM2Clock, ®::TIMER2), 64 | Timer3 => (Clock::TIM3Clock, ®::TIMER3), 65 | }; 66 | 67 | clock.enable(); 68 | clock.set_divisor(divisor); 69 | 70 | reg.set_CTCR(0); 71 | reg.set_TCR(2); 72 | reg.set_PR(counter - 1); 73 | reg.set_TCR(1); 74 | 75 | Timer { 76 | reg: reg, 77 | } 78 | } 79 | } 80 | 81 | impl timer::Timer for Timer { 82 | #[inline(always)] 83 | fn get_counter(&self) -> u32 { 84 | self.reg.TC() 85 | } 86 | } 87 | 88 | mod reg { 89 | use volatile_cell::VolatileCell; 90 | 91 | ioreg_old!(TIMER: u32, IR, TCR, TC, PR, PC, MCR, MR0, MR1, MR2, MR3, CCR, CR0, CR1, EMR, CTCR); 92 | reg_rw!(TIMER, u32, IR, set_IR, IR); 93 | reg_rw!(TIMER, u32, TCR, set_TCR, TCR); 94 | reg_rw!(TIMER, u32, TC, set_TC, TC); 95 | reg_rw!(TIMER, u32, PR, set_PR, PR); 96 | reg_rw!(TIMER, u32, PC, set_PC, PC); 97 | reg_rw!(TIMER, u32, MCR, set_MCR, MCR); 98 | reg_rw!(TIMER, u32, MR0, set_MR0, MR0); 99 | reg_rw!(TIMER, u32, MR1, set_MR1, MR1); 100 | reg_rw!(TIMER, u32, MR2, set_MR2, MR2); 101 | reg_rw!(TIMER, u32, MR3, set_MR3, MR3); 102 | reg_rw!(TIMER, u32, CCR, set_CCR, CCR); 103 | reg_rw!(TIMER, u32, CR0, set_CR0, CR0); 104 | reg_rw!(TIMER, u32, CR1, set_CR1, CR1); 105 | reg_rw!(TIMER, u32, EMR, set_EMR, EMR); 106 | reg_rw!(TIMER, u32, CTCR, set_CTCR, CTCR); 107 | 108 | extern { 109 | #[link_name="lpc17xx_iomem_TIMER0"] pub static TIMER0: TIMER; 110 | #[link_name="lpc17xx_iomem_TIMER1"] pub static TIMER1: TIMER; 111 | #[link_name="lpc17xx_iomem_TIMER2"] pub static TIMER2: TIMER; 112 | #[link_name="lpc17xx_iomem_TIMER3"] pub static TIMER3: TIMER; 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /src/hal/lpc17xx/timer_pt.rs: -------------------------------------------------------------------------------- 1 | // Zinc, the bare metal stack for rust. 2 | // Copyright 2014 Vladimir "farcaller" Pouzanov 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | use std::rc::Rc; 17 | use syntax::ext::base::ExtCtxt; 18 | 19 | use builder::{Builder, TokenString, add_node_dependency}; 20 | use node; 21 | 22 | pub fn attach(builder: &mut Builder, _: &mut ExtCtxt, node: Rc) { 23 | node.materializer.set(Some(verify as fn(&mut Builder, &mut ExtCtxt, Rc))); 24 | for timer_node in node.subnodes().iter() { 25 | timer_node.materializer.set(Some(build_timer as fn(&mut Builder, &mut ExtCtxt, Rc))); 26 | add_node_dependency(&node, timer_node); 27 | super::add_node_dependency_on_clock(builder, timer_node); 28 | } 29 | } 30 | 31 | pub fn verify(_: &mut Builder, cx: &mut ExtCtxt, node: Rc) { 32 | node.expect_no_attributes(cx); 33 | } 34 | 35 | fn build_timer(builder: &mut Builder, cx: &mut ExtCtxt, node: Rc) { 36 | if !node.expect_attributes(cx, &[ 37 | ("counter", node::IntAttribute), 38 | ("divisor", node::IntAttribute)]) { 39 | return 40 | } 41 | 42 | if node.name.is_none() { 43 | cx.parse_sess().span_diagnostic.span_err(node.name_span, 44 | "timer node must have a name"); 45 | return 46 | } 47 | 48 | let name = TokenString(node.name.clone().unwrap()); 49 | let timer_index: usize = node.path.as_str().parse().unwrap(); 50 | let counter: u32 = node.get_int_attr("counter").unwrap() as u32; 51 | let divisor: u8 = node.get_int_attr("divisor").unwrap() as u8; 52 | 53 | let timer_name = match timer_index { 54 | 0...3 => TokenString(format!( 55 | "zinc::hal::lpc17xx::timer::TimerPeripheral::Timer{}", timer_index)), 56 | other => { 57 | cx.parse_sess().span_diagnostic.span_err(node.path_span, 58 | format!("unknown timer index `{}`, allowed indexes: 0, 1, 2, 3", 59 | other).as_str()); 60 | return 61 | } 62 | }; 63 | 64 | node.set_type_name("zinc::hal::lpc17xx::timer::Timer".to_string()); 65 | 66 | let st = quote_stmt!(&*cx, 67 | let $name = zinc::hal::lpc17xx::timer::Timer::new( 68 | $timer_name, $counter, $divisor); 69 | ).unwrap(); 70 | builder.add_main_statement(st); 71 | } 72 | 73 | #[cfg(test)] 74 | mod test { 75 | use builder::Builder; 76 | use test_helpers::{assert_equal_source, with_parsed}; 77 | 78 | #[test] 79 | fn builds_timer() { 80 | with_parsed(" 81 | timer { 82 | tim@1 { 83 | counter = 25; 84 | divisor = 4; 85 | } 86 | }", |cx, failed, pt| { 87 | let mut builder = Builder::new(pt.clone(), cx); 88 | super::build_timer(&mut builder, cx, pt.get_by_name("tim").unwrap()); 89 | assert!(unsafe{*failed} == false); 90 | assert!(builder.main_stmts().len() == 1); 91 | 92 | assert_equal_source(&builder.main_stmts()[0], 93 | "let tim = zinc::hal::lpc17xx::timer::Timer::new( 94 | zinc::hal::lpc17xx::timer::TimerPeripheral::Timer1, 25u32, 4u8);"); 95 | }); 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /src/hal/mem_init.rs: -------------------------------------------------------------------------------- 1 | // Zinc, the bare metal stack for rust. 2 | // Copyright 2014 Vladimir "farcaller" Pouzanov 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | //! Helper functions for memory initialisation. 17 | 18 | use hal::stack::set_stack_limit; 19 | 20 | extern { 21 | static _data_load: u32; 22 | static mut _data: u32; 23 | static mut _edata: u32; 24 | static mut _bss: u32; 25 | static mut _ebss: u32; 26 | 27 | static _eglobals: u32; 28 | } 29 | 30 | /// Helper function to initialise the stack limit. 31 | #[inline(always)] 32 | pub fn init_stack() { 33 | set_stack_limit( unsafe { (&_eglobals as *const u32) } as u32); 34 | } 35 | 36 | /// Helper function to initialize memory. 37 | /// Copies `.data` sections in to RAM and initializes `.bss` sections to zero. 38 | #[inline(always)] 39 | pub fn init_data() { 40 | unsafe { 41 | let mut load_addr: *const u32 = &_data_load; 42 | let mut mem_addr: *mut u32 = &mut _data; 43 | while mem_addr < &mut _edata as *mut u32 { 44 | *mem_addr = *load_addr; 45 | mem_addr = ((mem_addr as u32) + 4) as *mut u32; 46 | load_addr = ((load_addr as u32) + 4) as *const u32; 47 | } 48 | 49 | mem_addr = &mut _bss as *mut u32; 50 | while mem_addr < &mut _ebss as *mut u32 { 51 | *mem_addr = 0u32; 52 | mem_addr = ((mem_addr as u32) + 4) as *mut u32; 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/hal/mod.rs: -------------------------------------------------------------------------------- 1 | // Zinc, the bare metal stack for rust. 2 | // Copyright 2014 Vladimir "farcaller" Pouzanov 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | /*! 17 | HAL provides abstractions for specific MCU hardware. 18 | 19 | Each peripheral in `hal` has a `xxxConf` struct that can be defined statically, 20 | and each such struct has a `setup()` method that configures the hardware 21 | (returning the object to interact with it where applicable). 22 | */ 23 | 24 | pub mod lpc11xx; 25 | #[cfg(feature = "mcu_lpc17xx")] pub mod lpc17xx; 26 | #[cfg(feature = "mcu_stm32f1")] pub mod stm32f1; 27 | #[cfg(feature = "mcu_stm32f4")] pub mod stm32f4; 28 | #[cfg(feature = "mcu_stm32f7")] pub mod stm32f7; 29 | #[cfg(feature = "mcu_stm32l1")] pub mod stm32l1; 30 | #[cfg(feature = "mcu_k20")] pub mod k20; 31 | #[cfg(feature = "mcu_tiva_c")] pub mod tiva_c; 32 | 33 | #[cfg(any(feature = "cpu_cortex-m0", 34 | feature = "cpu_cortex-m3", 35 | feature = "cpu_cortex-m4", 36 | feature = "cpu_cortex-m7"))] 37 | mod cortex_common; 38 | #[cfg(feature = "cpu_cortex-m3")] 39 | pub mod cortex_m3; 40 | #[cfg(feature = "cpu_cortex-m4")] 41 | pub mod cortex_m4; 42 | #[cfg(feature = "cpu_cortex-m7")] 43 | pub mod cortex_m7; 44 | 45 | pub mod mem_init; 46 | pub mod pin; 47 | pub mod pwm; 48 | pub mod spi; 49 | pub mod stack; 50 | pub mod timer; 51 | pub mod uart; 52 | 53 | #[cfg(target_os = "none")] 54 | pub mod isr; 55 | -------------------------------------------------------------------------------- /src/hal/pin.rs: -------------------------------------------------------------------------------- 1 | // Zinc, the bare metal stack for rust. 2 | // Copyright 2014 Vladimir "farcaller" Pouzanov 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | //! Common definitions for pin HAL. 17 | 18 | pub use self::GpioDirection::*; 19 | pub use self::GpioLevel::*; 20 | 21 | /// GPIO direction. 22 | #[derive(Clone, Copy)] 23 | pub enum GpioDirection { 24 | /// Input mode. 25 | In, 26 | /// Output mode. 27 | Out, 28 | } 29 | 30 | /// Logic levels. 31 | #[derive(PartialEq, Clone, Copy)] 32 | pub enum GpioLevel { 33 | /// Logic low. 34 | Low, 35 | /// Logic high. 36 | High, 37 | } 38 | 39 | /// General Purpose I/O. 40 | pub trait Gpio { 41 | /// Set to logic high. 42 | fn set_high(&self); 43 | 44 | /// Set to logic low. 45 | fn set_low(&self); 46 | 47 | /// Read current logic level. 48 | fn level(&self) -> GpioLevel; 49 | 50 | /// Set direction mode to `In` or `Out`, 51 | /// for reading or writing respectively. 52 | fn set_direction(&self, new_mode: GpioDirection); 53 | } 54 | 55 | /// Analog Input 56 | pub trait Adc { 57 | /// Read analog input value 58 | fn read(&self) -> u32; 59 | } 60 | -------------------------------------------------------------------------------- /src/hal/pwm.rs: -------------------------------------------------------------------------------- 1 | // Zinc, the bare metal stack for rust. 2 | // Copyright 2015 Paul Osborne 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | //! Common definitions for all PWM on all MCUs 17 | 18 | /// Trait for any Puluse Width Modulated output 19 | /// 20 | /// This interface is inspired by the mbed `PWMOut` interface. 21 | /// 22 | /// Note that on some MCUs, the period may be dictated by 23 | /// a timer shared by several differents PWMs. It is not 24 | /// guaranteed that the period and pulsewidth specified 25 | /// will remain identical if modified elsewhere. A proper 26 | /// implementaiton will still seek to maintain a similar 27 | /// duty cycle in the case of a period change. 28 | pub trait PWMOutput { 29 | /// set the period in microseconds 30 | fn set_period_us(&mut self, period_us: u32); 31 | 32 | /// get the period in microseconds 33 | fn get_period_us(&self) -> u32; 34 | 35 | /// Set the pulse width in microseconds 36 | fn set_pulsewidth_us(&mut self, pulsewidth_us: u32); 37 | 38 | /// get the duty cycle as a percentage 39 | fn get_pulsewidth_us(&self) -> u32; 40 | 41 | /// Set the duty cycle for this PWMOutput to the given percentage 42 | /// 43 | /// duty_cycle is expected to be a number between 0 and 1. 44 | /// Numbers below 0 will be set to 0 and above 1 will be set to 45 | /// 1.0. 46 | fn write(&mut self, duty_cycle: f32) { 47 | let adj_duty_cycle = if duty_cycle < 0.0 { 48 | 0.0 49 | } else if duty_cycle > 1.0 { 50 | 1.0 51 | } else { 52 | duty_cycle 53 | }; 54 | 55 | // assume the period is acceptable and adjust pulsewidth only 56 | let pulsewidth_us = (adj_duty_cycle * self.get_period_us() as f32) as u32; 57 | self.set_pulsewidth_us(pulsewidth_us) 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/hal/spi.rs: -------------------------------------------------------------------------------- 1 | // Zinc, the bare metal stack for rust. 2 | // Copyright 2014 Vladimir "farcaller" Pouzanov 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | /*! 17 | SPI interface. 18 | 19 | SPIConf is a MCU-specific struct. 20 | 21 | As SPI performs read and write as one operation, special care should be taken if 22 | `write()` and `read()` methods are used with several devices on one SPI 23 | peripheral. The best way is to always use `transfer()`. 24 | */ 25 | 26 | /// SPI trait. 27 | pub trait Spi { 28 | /// Writes a byte over SPI. 29 | /// 30 | /// It's implementation defined what happens if SPI is not configured to 8 31 | /// bits. 32 | fn write(&self, value: u8); 33 | 34 | /// Reads a byte from SPI. 35 | /// 36 | /// This function returns the last byte received (SPI sends and receives data 37 | /// at the same time). 38 | fn read(&self) -> u8; 39 | 40 | /// Performs an SPI transfer operation (writes one byte, returns the one byte 41 | /// read). 42 | fn transfer(&self, value: u8) -> u8 { 43 | self.write(value); 44 | self.read() 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/hal/stack.rs: -------------------------------------------------------------------------------- 1 | // Zinc, the bare metal stack for rust. 2 | // Copyright 2014 Vladimir "farcaller" Pouzanov 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | //! Stack layout information. 17 | 18 | use core::intrinsics::transmute; 19 | 20 | extern { 21 | fn __STACK_BASE(); 22 | static mut __STACK_LIMIT: u32; 23 | } 24 | 25 | /// Returns the address of main stack base (end of ram). 26 | pub fn stack_base() -> usize { 27 | unsafe { 28 | transmute(__STACK_BASE as unsafe extern "C" fn()) 29 | } 30 | } 31 | 32 | /// Returns the current stack limit. 33 | pub fn stack_limit() -> u32 { 34 | unsafe { __STACK_LIMIT } 35 | } 36 | 37 | /// Sets the current stack limit. 38 | pub fn set_stack_limit(val: u32) { 39 | unsafe { __STACK_LIMIT = val } 40 | } 41 | -------------------------------------------------------------------------------- /src/hal/stm32f1/iomem.ld: -------------------------------------------------------------------------------- 1 | stm32f1_iomem_PWR = 0x40007000; 2 | 3 | stm32f1_iomem_FLASH = 0x40022000; 4 | stm32f1_iomem_RCC = 0x40021000; 5 | 6 | stm32f1_iomem_GPIOA = 0x40010800; 7 | stm32f1_iomem_GPIOB = 0x40010C00; 8 | stm32f1_iomem_GPIOC = 0x40011000; 9 | stm32f1_iomem_GPIOD = 0x40011400; 10 | stm32f1_iomem_GPIOE = 0x40011800; 11 | stm32f1_iomem_GPIOF = 0x40011C00; 12 | stm32f1_iomem_GPIOG = 0x40012000; 13 | 14 | stm32f1_iomem_TIM1 = 0x40012C00; 15 | stm32f1_iomem_TIM2 = 0x40000000; 16 | stm32f1_iomem_TIM3 = 0x40000400; 17 | stm32f1_iomem_TIM4 = 0x40000800; 18 | stm32f1_iomem_TIM5 = 0x40000C00; 19 | stm32f1_iomem_TIM6 = 0x40001000; 20 | stm32f1_iomem_TIM7 = 0x40001400; 21 | stm32f1_iomem_TIM8 = 0x40013400; 22 | stm32f1_iomem_TIM9 = 0x40014C00; 23 | stm32f1_iomem_TIM10 = 0x40015000; 24 | stm32f1_iomem_TIM11 = 0x40015400; 25 | stm32f1_iomem_TIM12 = 0x40001800; 26 | stm32f1_iomem_TIM13 = 0x40001C00; 27 | stm32f1_iomem_TIM14 = 0x40002000; 28 | 29 | stm32f1_iomem_USART1 = 0x40013800; 30 | stm32f1_iomem_USART2 = 0x40004400; 31 | stm32f1_iomem_USART3 = 0x40004800; 32 | stm32f1_iomem_UART4 = 0x40004C00; 33 | stm32f1_iomem_UART5 = 0x40005000; 34 | 35 | stm32f1_iomem_SPI1 = 0x40013000; 36 | stm32f1_iomem_SPI2 = 0x40003800; 37 | stm32f1_iomem_SPI3 = 0x40003C00; 38 | -------------------------------------------------------------------------------- /src/hal/stm32f1/layout.ld: -------------------------------------------------------------------------------- 1 | __STACK_BASE = 0x20004FFF; /* end of ram */ 2 | _data_load = LOADADDR(.data); 3 | 4 | INCLUDE iomem.ld 5 | 6 | ENTRY(main) 7 | 8 | MEMORY 9 | { 10 | rom(RX) : ORIGIN = 0x08000000, LENGTH = 64K 11 | ram(WAIL) : ORIGIN = 0x20000000, LENGTH = 20K 12 | } 13 | 14 | REGION_ALIAS("vectors", rom); 15 | 16 | INCLUDE layout_common.ld 17 | -------------------------------------------------------------------------------- /src/hal/stm32f1/mod.rs: -------------------------------------------------------------------------------- 1 | // Zinc, the bare metal stack for rust. 2 | // Copyright 2014 Dzmitry "kvark" Malyshau 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | //! HAL for STM32F1. 17 | 18 | pub mod init; 19 | pub mod peripheral_clock; 20 | pub mod pin; 21 | pub mod spi; 22 | pub mod timer; 23 | pub mod usart; 24 | -------------------------------------------------------------------------------- /src/hal/stm32f1/timer.rs: -------------------------------------------------------------------------------- 1 | // Zinc, the bare metal stack for rust. 2 | // Copyright 2014 Dzmitry "kvark" Malyshau 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | //! Timer configuration for ST STM32F1. 17 | //! 18 | //! This code supports only TIM2 at the moment. 19 | 20 | #[path="../../util/ioreg.rs"] mod ioreg; 21 | 22 | /// Available timer peripherals. 23 | #[allow(missing_docs)] 24 | #[derive(Clone, Copy)] 25 | pub enum TimerPeripheral { 26 | Timer2, 27 | } 28 | 29 | /// Structure describing a Timer. 30 | #[derive(Clone, Copy)] 31 | pub struct Timer { 32 | reg: &'static reg::TIMER, 33 | } 34 | 35 | impl Timer { 36 | /// Create and start a Timer. 37 | pub fn new(peripheral: TimerPeripheral, counter: u32, div_shift: u16) -> Timer { 38 | use super::peripheral_clock as pc; 39 | use self::TimerPeripheral::*; 40 | let (reg, clock) = match peripheral { 41 | Timer2 => (®::TIM2, pc::BusApb1::Tim2), 42 | }; 43 | 44 | pc::PeripheralClock::Apb1(clock).enable(); 45 | 46 | reg.cr1.set_counter_enable(true); 47 | reg.cr1.set_divisor_shift(div_shift); 48 | reg.psc.set_prescaler(counter as u16 - 1); 49 | reg.egr.set_generate(1); 50 | 51 | Timer { 52 | reg: reg, 53 | } 54 | } 55 | } 56 | 57 | impl ::hal::timer::Timer for Timer { 58 | #[inline(always)] 59 | fn get_counter(&self) -> u32 { 60 | self.reg.cnt.counter() as u32 61 | } 62 | } 63 | 64 | mod reg { 65 | use volatile_cell::VolatileCell; 66 | use core::ops::Drop; 67 | 68 | ioregs!(TIMER = { 69 | 0x00 => reg16 cr1 { // control 1 70 | 0 => counter_enable : rw, 71 | 1 => update_disable : rw, 72 | 2 => update_request_source : rw, 73 | 3 => one_pulse_mode : rw, 74 | 4 => direction : rw, 75 | 6..5 => center_alignment_mode : rw, 76 | 7 => auto_reload_enable : rw, 77 | 9..8 => divisor_shift : rw, 78 | }, 79 | 0x04 => reg16 cr2 { // control 2 80 | 15..0 => control : rw, 81 | }, 82 | 0x08 => reg16 smcr { // slave mode control 83 | 15..0 => slave_control : rw, 84 | }, 85 | 0x0A => reg16 dier { // DMA/interrupt enable 86 | 15..0 => enable : rw, 87 | }, 88 | 0x10 => reg16 sr { // status 89 | 15..0 => status : rw, 90 | }, 91 | 0x14 => reg16 egr { // event generation 92 | 15..0 => generate : wo, 93 | }, 94 | 0x18 => reg16 ccmr1 { // capture/compare mode 1 95 | 15..0 => mode : rw, 96 | }, 97 | 0x1C => reg16 ccmr2 { // capture/compare mode 2 98 | 15..0 => mode : rw, 99 | }, 100 | 0x20 => reg16 ccer { // capture/compare enable 101 | 15..0 => enable : rw, 102 | }, 103 | 0x24 => reg16 cnt { // counter 104 | 15..0 => counter : rw, 105 | }, 106 | 0x28 => reg16 psc { // prescaler 107 | 15..0 => prescaler : rw, 108 | }, 109 | 0x2C => reg32 arr { // auto-reload 110 | 31..0 => reload : rw, 111 | }, 112 | 0x34 => reg32 ccr1 { // capture/compare 1 113 | 31..0 => cc : rw, 114 | }, 115 | 0x38 => reg32 ccr2 { // capture/compare 2 116 | 31..0 => cc : rw, 117 | }, 118 | 0x3C => reg32 ccr3 { // capture/compare 3 119 | 31..0 => cc : rw, 120 | }, 121 | 0x40 => reg32 ccr4 { // capture/compare 4 122 | 31..0 => cc : rw, 123 | }, 124 | 0x48 => reg16 dcr { // DMA control 125 | 15..0 => control : rw, 126 | }, 127 | 0x4C => reg16 dmap { // DMA address for full transfer 128 | 15..0 => address : rw, 129 | }, 130 | 0x50 => reg16 or { // option 131 | 15..0 => option : rw, 132 | }, 133 | }); 134 | 135 | extern { 136 | #[link_name="stm32f1_iomem_TIM2"] pub static TIM2: TIMER; 137 | } 138 | } 139 | -------------------------------------------------------------------------------- /src/hal/stm32f4/iomem.ld: -------------------------------------------------------------------------------- 1 | stm32f4_iomem_TIM2 = 0x40000000; 2 | 3 | stm32f4_iomem_PWR = 0x40007000; 4 | 5 | stm32f4_iomem_FLASH = 0x40023C00; 6 | stm32f4_iomem_RCC = 0x40023800; 7 | 8 | stm32f4_iomem_GPIOA = 0x40020000; 9 | stm32f4_iomem_GPIOB = 0x40020400; 10 | stm32f4_iomem_GPIOC = 0x40020800; 11 | stm32f4_iomem_GPIOD = 0x40020c00; 12 | stm32f4_iomem_GPIOE = 0x40021000; 13 | stm32f4_iomem_GPIOF = 0x40021400; 14 | stm32f4_iomem_GPIOG = 0x40021800; 15 | stm32f4_iomem_GPIOH = 0x40021c00; 16 | stm32f4_iomem_GPIOI = 0x40022000; 17 | -------------------------------------------------------------------------------- /src/hal/stm32f4/layout.ld: -------------------------------------------------------------------------------- 1 | __STACK_BASE = 0x2001FFFF; 2 | _data_load = LOADADDR(.data); 3 | 4 | INCLUDE iomem.ld 5 | 6 | ENTRY(main) 7 | 8 | MEMORY 9 | { 10 | rom(RX) : ORIGIN = 0x08000000, LENGTH = 1024K 11 | ram_c(WAIL) : ORIGIN = 0x10000000, LENGTH = 64K 12 | ram(WAIL) : ORIGIN = 0x20000000, LENGTH = 112K + 16K 13 | /* ram(WAIL) : ORIGIN = 0x2001C000, LENGTH = 16K */ 14 | } 15 | 16 | REGION_ALIAS("vectors", rom); 17 | 18 | INCLUDE layout_common.ld 19 | -------------------------------------------------------------------------------- /src/hal/stm32f4/mod.rs: -------------------------------------------------------------------------------- 1 | // Zinc, the bare metal stack for rust. 2 | // Copyright 2014 Vladimir "farcaller" Pouzanov 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | //! HAL for STM32F4. 17 | 18 | pub mod init; 19 | pub mod peripheral_clock; 20 | pub mod pin; 21 | pub mod timer; 22 | -------------------------------------------------------------------------------- /src/hal/stm32f4/timer.rs: -------------------------------------------------------------------------------- 1 | // Zinc, the bare metal stack for rust. 2 | // Copyright 2014 Vladimir "farcaller" Pouzanov 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | //! Timer configuration for ST STM32F4. 17 | //! 18 | //! This code supports only TIM2 at the moment. 19 | 20 | use super::peripheral_clock; 21 | use hal::timer; 22 | 23 | #[path="../../util/ioreg.rs"] 24 | #[macro_use] mod ioreg; 25 | 26 | /// Available timer peripherals. 27 | #[allow(missing_docs)] 28 | #[derive(Clone, Copy)] 29 | pub enum TimerPeripheral { 30 | Timer2, 31 | } 32 | 33 | /// Structure describing a Timer. 34 | #[derive(Clone, Copy)] 35 | pub struct Timer { 36 | reg: &'static reg::TIM2To5, 37 | } 38 | 39 | impl Timer { 40 | /// Create and start a Timer. 41 | pub fn new(peripheral: TimerPeripheral, counter: u32) -> Timer { 42 | use self::TimerPeripheral::*; 43 | let (clock, reg) = match peripheral { 44 | Timer2 => (peripheral_clock::PeripheralClock::TIM2Clock, ®::TIM2), 45 | }; 46 | 47 | clock.enable(); 48 | 49 | reg.set_PSC(counter - 1); 50 | reg.set_CR1(1); 51 | reg.set_EGR(1); 52 | 53 | Timer { 54 | reg: reg, 55 | } 56 | } 57 | } 58 | 59 | impl timer::Timer for Timer { 60 | #[inline(always)] 61 | fn get_counter(&self) -> u32 { 62 | self.reg.CNT() 63 | } 64 | } 65 | 66 | mod reg { 67 | use volatile_cell::VolatileCell; 68 | 69 | ioreg_old!(TIM2To5: u32, CR1, CR2, SMCR, DIER, SR, EGR, CCMR1, CCMR2, CCER, CNT, 70 | PSC, ARR, _pad_0, CCR1, CCR2, CCR3, CCR4, _pad_1, DCR, 71 | DMAR, OR); 72 | reg_rw!(TIM2To5, u32, CR1, set_CR1, CR1); 73 | reg_rw!(TIM2To5, u32, CR2, set_CR2, CR2); 74 | reg_rw!(TIM2To5, u32, SMCR, set_SMCR, SMCR); 75 | reg_rw!(TIM2To5, u32, DIER, set_DIER, DIER); 76 | reg_rw!(TIM2To5, u32, SR, set_SR, SR); 77 | reg_w!( TIM2To5, u32, set_EGR, EGR); 78 | reg_rw!(TIM2To5, u32, CCMR1, set_CCMR1, CCMR1); 79 | reg_rw!(TIM2To5, u32, CCMR2, set_CCMR2, CCMR2); 80 | reg_rw!(TIM2To5, u32, CCER, set_CCER, CCER); 81 | reg_rw!(TIM2To5, u32, CNT, set_CNT, CNT); 82 | reg_rw!(TIM2To5, u32, PSC, set_PSC, PSC); 83 | reg_rw!(TIM2To5, u32, ARR, set_ARR, ARR); 84 | reg_rw!(TIM2To5, u32, CCR1, set_CCR1, CCR1); 85 | reg_rw!(TIM2To5, u32, CCR2, set_CCR2, CCR2); 86 | reg_rw!(TIM2To5, u32, CCR3, set_CCR3, CCR3); 87 | reg_rw!(TIM2To5, u32, CCR4, set_CCR4, CCR4); 88 | reg_rw!(TIM2To5, u32, DCR, set_DCR, DCR); 89 | reg_rw!(TIM2To5, u32, DMAR, set_DMAR, DMAR); 90 | reg_rw!(TIM2To5, u32, OR, set_OR, OR); 91 | 92 | extern { 93 | #[link_name="stm32f4_iomem_TIM2"] pub static TIM2: TIM2To5; 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /src/hal/stm32f7/iomem.ld: -------------------------------------------------------------------------------- 1 | stm32f7_iomem_TIM2 = 0x40000000; 2 | 3 | stm32f7_iomem_PWR = 0x40007000; 4 | 5 | stm32f7_iomem_FLASH = 0x40023C00; 6 | stm32f7_iomem_RCC = 0x40023800; 7 | 8 | stm32f7_iomem_GPIOA = 0x40020000; 9 | stm32f7_iomem_GPIOB = 0x40020400; 10 | stm32f7_iomem_GPIOC = 0x40020800; 11 | stm32f7_iomem_GPIOD = 0x40020c00; 12 | stm32f7_iomem_GPIOE = 0x40021000; 13 | stm32f7_iomem_GPIOF = 0x40021400; 14 | stm32f7_iomem_GPIOG = 0x40021800; 15 | stm32f7_iomem_GPIOH = 0x40021c00; 16 | stm32f7_iomem_GPIOI = 0x40022000; 17 | stm32f7_iomem_GPIOJ = 0x40022400; 18 | stm32f7_iomem_GPIOK = 0x40022800; 19 | -------------------------------------------------------------------------------- /src/hal/stm32f7/layout.ld: -------------------------------------------------------------------------------- 1 | __STACK_BASE = 0x2004FFFF; 2 | _data_load = LOADADDR(.data); 3 | 4 | INCLUDE iomem.ld 5 | 6 | ENTRY(main) 7 | 8 | MEMORY 9 | { 10 | rom(RX) : ORIGIN = 0x08000000, LENGTH = 1024K 11 | ram_c(WAIL) : ORIGIN = 0x10000000, LENGTH = 64K 12 | 13 | /* DTCM: 0x20000000 for 64K 14 | * SRAM1: 0x20010000 for 240K 15 | * SRAM2: 0x2004C000 for 16K 16 | */ 17 | ram(WAIL) : ORIGIN = 0x20000000, LENGTH = 64K + 240K + 16K 18 | } 19 | 20 | REGION_ALIAS("vectors", rom); 21 | 22 | INCLUDE layout_common.ld 23 | -------------------------------------------------------------------------------- /src/hal/stm32f7/mod.rs: -------------------------------------------------------------------------------- 1 | // Zinc, the bare metal stack for rust. 2 | // Copyright 2014 Vladimir "farcaller" Pouzanov 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | //! HAL for STM32F7. 17 | 18 | pub mod init; 19 | pub mod peripheral_clock; 20 | pub mod pin; 21 | pub mod timer; 22 | -------------------------------------------------------------------------------- /src/hal/stm32l1/iomem.ld: -------------------------------------------------------------------------------- 1 | stm32l1_iomem_PWR = 0x40007000; 2 | 3 | stm32l1_iomem_FLASH = 0x40023C00; 4 | stm32l1_iomem_RCC = 0x40023800; 5 | 6 | stm32l1_iomem_GPIOA = 0x40020000; 7 | stm32l1_iomem_GPIOB = 0x40020400; 8 | stm32l1_iomem_GPIOC = 0x40020800; 9 | stm32l1_iomem_GPIOD = 0x40020c00; 10 | stm32l1_iomem_GPIOE = 0x40021000; 11 | stm32l1_iomem_GPIOF = 0x40021800; 12 | stm32l1_iomem_GPIOG = 0x40021C00; 13 | stm32l1_iomem_GPIOH = 0x40021400; 14 | 15 | stm32l1_iomem_TIM2 = 0x40000000; 16 | 17 | stm32l1_iomem_USART1 = 0x40013800; 18 | stm32l1_iomem_USART2 = 0x40004400; 19 | stm32l1_iomem_USART3 = 0x40004800; 20 | stm32l1_iomem_UART4 = 0x40004C00; 21 | stm32l1_iomem_UART5 = 0x40005000; 22 | 23 | stm32l1_iomem_SPI1 = 0x40013000; 24 | stm32l1_iomem_SPI2 = 0x40003800; 25 | stm32l1_iomem_SPI3 = 0x40003C00; 26 | -------------------------------------------------------------------------------- /src/hal/stm32l1/layout.ld: -------------------------------------------------------------------------------- 1 | __STACK_BASE = 0x20008000; /* end of ram */ 2 | _data_load = LOADADDR(.data); 3 | 4 | INCLUDE iomem.ld 5 | 6 | ENTRY(main) 7 | 8 | MEMORY 9 | { 10 | rom(RX) : ORIGIN = 0x08000000, LENGTH = 6 * 64K 11 | ram(WAIL) : ORIGIN = 0x20000000, LENGTH = 32K 12 | } 13 | 14 | REGION_ALIAS("vectors", rom); 15 | 16 | INCLUDE layout_common.ld 17 | -------------------------------------------------------------------------------- /src/hal/stm32l1/mod.rs: -------------------------------------------------------------------------------- 1 | // Zinc, the bare metal stack for rust. 2 | // Copyright 2014 Dzmitry "kvark" Malyshau 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | //! HAL for STM32L1. 17 | 18 | pub mod init; 19 | pub mod peripheral_clock; 20 | pub mod pin; 21 | pub mod spi; 22 | pub mod timer; 23 | pub mod usart; 24 | -------------------------------------------------------------------------------- /src/hal/stm32l1/timer.rs: -------------------------------------------------------------------------------- 1 | // Zinc, the bare metal stack for rust. 2 | // Copyright 2014 Dzmitry "kvark" Malyshau 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | //! Timer configuration for ST STM32L1. 17 | //! 18 | //! This code supports only TIM2 at the moment. 19 | 20 | #[path="../../util/ioreg.rs"] mod ioreg; 21 | 22 | /// Available timer peripherals. 23 | #[allow(missing_docs)] 24 | #[derive(Clone, Copy)] 25 | pub enum TimerPeripheral { 26 | Timer2, 27 | } 28 | 29 | /// Structure describing a Timer. 30 | #[derive(Clone, Copy)] 31 | pub struct Timer { 32 | reg: &'static reg::TIMER, 33 | } 34 | 35 | impl Timer { 36 | /// Create and start a Timer. 37 | pub fn new(peripheral: TimerPeripheral, counter: u32, div_shift: u16) -> Timer { 38 | use super::peripheral_clock as pc; 39 | use self::TimerPeripheral::*; 40 | let (reg, clock) = match peripheral { 41 | Timer2 => (®::TIM2, pc::BusApb1::Tim2), 42 | }; 43 | 44 | pc::PeripheralClock::Apb1(clock).enable(); 45 | 46 | reg.cr1.set_counter_enable(true); 47 | reg.cr1.set_divisor_shift(div_shift); 48 | reg.psc.set_prescaler(counter as u16 - 1); 49 | reg.egr.set_generate(1); 50 | 51 | Timer { 52 | reg: reg, 53 | } 54 | } 55 | } 56 | 57 | impl ::hal::timer::Timer for Timer { 58 | #[inline(always)] 59 | fn get_counter(&self) -> u32 { 60 | self.reg.cnt.counter() as u32 61 | } 62 | } 63 | 64 | mod reg { 65 | use volatile_cell::VolatileCell; 66 | use core::ops::Drop; 67 | 68 | ioregs!(TIMER = { 69 | 0x00 => reg16 cr1 { // control 1 70 | 0 => counter_enable : rw, 71 | 1 => update_disable : rw, 72 | 2 => update_request_source : rw, 73 | 3 => one_pulse_mode : rw, 74 | 4 => direction : rw, 75 | 6..5 => center_alignment_mode : rw, 76 | 7 => auto_reload_enable : rw, 77 | 9..8 => divisor_shift : rw, 78 | }, 79 | 0x04 => reg16 cr2 { // control 2 80 | 15..0 => control : rw, 81 | }, 82 | 0x08 => reg16 smcr { // slave mode control 83 | 15..0 => slave_control : rw, 84 | }, 85 | 0x0A => reg16 dier { // DMA/interrupt enable 86 | 15..0 => enable : rw, 87 | }, 88 | 0x10 => reg16 sr { // status 89 | 15..0 => status : rw, 90 | }, 91 | 0x14 => reg16 egr { // event generation 92 | 15..0 => generate : wo, 93 | }, 94 | 0x18 => reg16 ccmr1 { // capture/compare mode 1 95 | 15..0 => mode : rw, 96 | }, 97 | 0x1C => reg16 ccmr2 { // capture/compare mode 2 98 | 15..0 => mode : rw, 99 | }, 100 | 0x20 => reg16 ccer { // capture/compare enable 101 | 15..0 => enable : rw, 102 | }, 103 | 0x24 => reg16 cnt { // counter 104 | 15..0 => counter : rw, 105 | }, 106 | 0x28 => reg16 psc { // prescaler 107 | 15..0 => prescaler : rw, 108 | }, 109 | 0x2C => reg32 arr { // auto-reload 110 | 31..0 => reload : rw, 111 | }, 112 | 0x34 => reg32 ccr1 { // capture/compare 1 113 | 31..0 => cc : rw, 114 | }, 115 | 0x38 => reg32 ccr2 { // capture/compare 2 116 | 31..0 => cc : rw, 117 | }, 118 | 0x3C => reg32 ccr3 { // capture/compare 3 119 | 31..0 => cc : rw, 120 | }, 121 | 0x40 => reg32 ccr4 { // capture/compare 4 122 | 31..0 => cc : rw, 123 | }, 124 | 0x48 => reg16 dcr { // DMA control 125 | 15..0 => control : rw, 126 | }, 127 | 0x4C => reg16 dmap { // DMA address for full transfer 128 | 15..0 => address : rw, 129 | }, 130 | 0x50 => reg16 or { // option 131 | 15..0 => option : rw, 132 | }, 133 | }); 134 | 135 | extern { 136 | #[link_name="stm32l1_iomem_TIM2"] pub static TIM2: TIMER; 137 | } 138 | } 139 | -------------------------------------------------------------------------------- /src/hal/timer.rs: -------------------------------------------------------------------------------- 1 | // Zinc, the bare metal stack for rust. 2 | // Copyright 2014 Vladimir "farcaller" Pouzanov 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | /*! 17 | Timer interface. 18 | 19 | TimerConf is a MCU-specific struct. 20 | 21 | Timers provide a simple way to delay program execution for some time. 22 | */ 23 | 24 | #[path="../util/wait_for.rs"] 25 | #[macro_use] mod wait_for; 26 | 27 | /// Timer implementation. 28 | pub trait Timer { 29 | /// Implementation-specific method to wait a given number of microseconds. 30 | fn get_counter(&self) -> u32; 31 | 32 | #[inline(always)] 33 | /// Waits for specified number of microseconds. 34 | fn wait_us(&self, us: u32) { 35 | let start = self.get_counter(); 36 | wait_for!((self.get_counter() - start) >= us); 37 | } 38 | 39 | #[inline(always)] 40 | /// Waits for specified number of milliseconds. 41 | fn wait_ms(&self, ms: u32) { 42 | self.wait_us(ms * 1000); 43 | } 44 | 45 | #[inline(always)] 46 | /// Waits for specified number of seconds. 47 | fn wait(&self, s: u32) { 48 | self.wait_us(s * 1000000); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/hal/tiva_c/clock_pt.rs: -------------------------------------------------------------------------------- 1 | // Zinc, the bare metal stack for rust. 2 | // Copyright 2014 Lionel Flandrin 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | use std::rc::Rc; 17 | use syntax::ext::base::ExtCtxt; 18 | use syntax::ext::build::AstBuilder; 19 | 20 | use builder::{Builder, TokenString}; 21 | use node; 22 | 23 | pub fn attach(_: &mut Builder, _: &mut ExtCtxt, node: Rc) { 24 | node.materializer.set(Some(build_clock as fn(&mut Builder, &mut ExtCtxt, Rc))); 25 | } 26 | 27 | fn build_clock(builder: &mut Builder, 28 | cx: &mut ExtCtxt, 29 | node: Rc) { 30 | if !node.expect_attributes(cx, &[("source", node::StrAttribute)]) { 31 | return; 32 | } 33 | 34 | let source = TokenString(node.get_string_attr("source").unwrap()); 35 | 36 | let use_pll = node.get_bool_attr("pll").unwrap_or(false); 37 | let div = node.get_int_attr("div").unwrap_or(1); 38 | let xtal = TokenString(node.get_string_attr("xtal") 39 | .unwrap_or("X16_0MHz".to_string())); 40 | 41 | let ex = quote_expr!(&*cx, 42 | { 43 | use zinc::hal::tiva_c::sysctl::clock; 44 | use core::option::Option::Some; 45 | 46 | clock::sysclk_configure( 47 | zinc::hal::tiva_c::sysctl::clock::ClockSource::$source, 48 | Some(zinc::hal::tiva_c::sysctl::clock::MOSCFreq::$xtal), 49 | $use_pll, 50 | Some($div)); 51 | } 52 | ); 53 | builder.add_main_statement(cx.stmt_expr(ex)); 54 | } 55 | -------------------------------------------------------------------------------- /src/hal/tiva_c/layout.ld: -------------------------------------------------------------------------------- 1 | _boot_checksum = 0; /* TODO(farcaller): extract this to lpc code only */ 2 | _data_load = LOADADDR(.data); 3 | 4 | ENTRY(main) 5 | 6 | MEMORY 7 | { 8 | rom(RX) : ORIGIN = 0x00000000, LENGTH = 0x40000 9 | ram(WAIL) : ORIGIN = 0x20000000, LENGTH = 0x8000 /* 32KB SRAM */ 10 | } 11 | 12 | __STACK_BASE = ORIGIN(ram) + LENGTH(ram); 13 | 14 | REGION_ALIAS("vectors", rom); 15 | 16 | INCLUDE layout_common.ld 17 | -------------------------------------------------------------------------------- /src/hal/tiva_c/mod.rs: -------------------------------------------------------------------------------- 1 | // Zinc, the bare metal stack for rust. 2 | // Copyright 2014 Lionel Flandrin 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | //! HAL for TI TM4C123GH6PM 17 | /// This MCU is used on the TI stellaris and Tiva C launchpad development boards. 18 | 19 | pub mod sysctl; 20 | pub mod pin; 21 | pub mod timer; 22 | pub mod uart; 23 | pub mod spi; 24 | 25 | #[path="../../util/ioreg.rs"] mod util; 26 | -------------------------------------------------------------------------------- /src/hal/tiva_c/pin_pt.rs: -------------------------------------------------------------------------------- 1 | // Zinc, the bare metal stack for rust. 2 | // Copyright 2014 Lionel Flandrin 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | use std::rc::Rc; 17 | use syntax::ext::base::ExtCtxt; 18 | 19 | use builder::{Builder, TokenString, add_node_dependency}; 20 | use node; 21 | 22 | pub fn attach(builder: &mut Builder, _: &mut ExtCtxt, node: Rc) { 23 | node.materializer.set(Some(verify as fn(&mut Builder, &mut ExtCtxt, Rc))); 24 | for port_node in node.subnodes().iter() { 25 | port_node.materializer.set(Some(verify as fn(&mut Builder, &mut ExtCtxt, Rc))); 26 | add_node_dependency(&node, port_node); 27 | for pin_node in port_node.subnodes().iter() { 28 | pin_node.materializer.set(Some(build_pin as fn(&mut Builder, &mut ExtCtxt, Rc))); 29 | add_node_dependency(port_node, pin_node); 30 | super::add_node_dependency_on_clock(builder, pin_node); 31 | } 32 | } 33 | } 34 | 35 | pub fn verify(_: &mut Builder, cx: &mut ExtCtxt, node: Rc) { 36 | node.expect_no_attributes(cx); 37 | } 38 | 39 | fn get_port_id(s: &str) -> Option { 40 | match s.len() { 41 | 1 => match s.chars().nth(0).unwrap().to_uppercase().nth(0).unwrap() { 42 | p @ 'A'...'F' => Some(p), 43 | _ => None, 44 | }, 45 | _ => None, 46 | } 47 | } 48 | 49 | fn build_pin(builder: &mut Builder, cx: &mut ExtCtxt, node: Rc) { 50 | let port_node = node.parent.clone().unwrap().upgrade().unwrap(); 51 | let ref port_path = port_node.path; 52 | 53 | let error = |err: &str | { 54 | cx.parse_sess().span_diagnostic.span_err(port_node.path_span, err); 55 | }; 56 | 57 | let port_str = format!("Port{}", match get_port_id(port_path.as_str()) { 58 | Some(port) => port, 59 | None => { 60 | cx.parse_sess().span_diagnostic.span_err(port_node.path_span, 61 | format!("unknown port `{}`, allowed values: a...f", 62 | port_path).as_str()); 63 | return; 64 | } 65 | }); 66 | 67 | let port = TokenString(port_str); 68 | 69 | if node.name.is_none() { 70 | error("pin node must have a name"); 71 | return; 72 | } 73 | 74 | let direction_str = 75 | match node.get_string_attr("direction").unwrap().as_str() { 76 | "out" => "zinc::hal::pin::Out", 77 | "in" => "zinc::hal::pin::In", 78 | bad => { 79 | error(format!("unknown direction `{}`, allowed values: `in`, `out`", 80 | bad).as_str()); 81 | return; 82 | } 83 | }; 84 | 85 | let direction = TokenString(direction_str.to_string()); 86 | 87 | let function = match node.get_int_attr("function") { 88 | None => 0, // Default to GPIO function 89 | Some(f) => f as u8, 90 | }; 91 | 92 | let pin_str = match node.path.as_str().parse::().unwrap() { 93 | 0 ...7 => &node.path, 94 | other => { 95 | error(format!("unknown pin `{}`, allowed values: 0...7", 96 | other).as_str()); 97 | return; 98 | } 99 | }; 100 | 101 | let pin = TokenString(format!("{}u8", pin_str)); 102 | let pin_name = TokenString(node.name.clone().unwrap()); 103 | 104 | node.set_type_name("zinc::hal::tiva_c::pin::Pin".to_string()); 105 | 106 | // TODO(simias): need to handle pin muxing 107 | let st = quote_stmt!(&*cx, 108 | let $pin_name = zinc::hal::tiva_c::pin::Pin::new( 109 | zinc::hal::tiva_c::pin::PortId::$port, 110 | $pin, 111 | $direction, 112 | $function); 113 | ); 114 | builder.add_main_statement(st.unwrap()); 115 | } 116 | -------------------------------------------------------------------------------- /src/hal/tiva_c/platformtree.rs: -------------------------------------------------------------------------------- 1 | // Zinc, the bare metal stack for rust. 2 | // Copyright 2014 Lionel Flandrin 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | use std::rc::Rc; 17 | use syntax::ext::base::ExtCtxt; 18 | 19 | use builder::{Builder, add_node_dependency}; 20 | use node; 21 | 22 | mod clock_pt; 23 | mod pin_pt; 24 | mod timer_pt; 25 | mod uart_pt; 26 | 27 | pub fn attach(builder: &mut Builder, cx: &mut ExtCtxt, node: Rc) { 28 | node.materializer.set(Some(verify as fn(&mut Builder, &mut ExtCtxt, Rc))); 29 | for sub in node.subnodes().iter() { 30 | add_node_dependency(&node, sub); 31 | 32 | match sub.path.as_str() { 33 | "clock" => clock_pt::attach(builder, cx, sub.clone()), 34 | "gpio" => pin_pt ::attach(builder, cx, sub.clone()), 35 | "timer" => timer_pt::attach(builder, cx, sub.clone()), 36 | "uart" => uart_pt ::attach(builder, cx, sub.clone()), 37 | _ => (), 38 | } 39 | } 40 | } 41 | 42 | fn verify(_: &mut Builder, cx: &mut ExtCtxt, node: Rc) { 43 | node.expect_no_attributes(cx); 44 | node.expect_subnodes(cx, &["clock", "gpio", "timer", "uart"]); 45 | } 46 | 47 | pub fn add_node_dependency_on_clock(builder: &mut Builder, 48 | node: &Rc) { 49 | let mcu_node = builder.pt().get_by_path("mcu").unwrap(); 50 | let clock_node = mcu_node.get_by_path("clock").unwrap(); 51 | add_node_dependency(node, &clock_node); 52 | } 53 | -------------------------------------------------------------------------------- /src/hal/tiva_c/timer_pt.rs: -------------------------------------------------------------------------------- 1 | // Zinc, the bare metal stack for rust. 2 | // Copyright 2014 Lionel Flandrin 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | use std::rc::Rc; 17 | use syntax::ext::base::ExtCtxt; 18 | use regex::Regex; 19 | 20 | use builder::{Builder, TokenString, add_node_dependency}; 21 | use node; 22 | 23 | pub fn attach(builder: &mut Builder, _: &mut ExtCtxt, node: Rc) { 24 | node.materializer.set(Some(verify as fn(&mut Builder, &mut ExtCtxt, Rc))); 25 | for timer_node in node.subnodes().iter() { 26 | timer_node.materializer.set(Some(build_timer as fn(&mut Builder, &mut ExtCtxt, Rc))); 27 | add_node_dependency(&node, timer_node); 28 | super::add_node_dependency_on_clock(builder, timer_node); 29 | } 30 | } 31 | 32 | pub fn verify(_: &mut Builder, cx: &mut ExtCtxt, node: Rc) { 33 | node.expect_no_attributes(cx); 34 | } 35 | 36 | fn build_timer(builder: &mut Builder, cx: &mut ExtCtxt, node: Rc) { 37 | 38 | let error = |err: &str | { 39 | cx.parse_sess().span_diagnostic.span_err(node.path_span, err); 40 | }; 41 | 42 | if !node.expect_attributes(cx, &[ 43 | ("prescale", node::IntAttribute), 44 | ("mode", node::StrAttribute)]) { 45 | return 46 | } 47 | 48 | if node.name.is_none() { 49 | cx.parse_sess().span_diagnostic.span_err(node.name_span, 50 | "timer node must have a name"); 51 | return 52 | } 53 | 54 | let name = TokenString(node.name.clone().unwrap()); 55 | let prescale = node.get_int_attr("prescale").unwrap() as u32; 56 | let mode = node.get_string_attr("mode").unwrap(); 57 | 58 | // Timer path is in the form "w?[0-5][A-B]": 59 | // - 'w' denotes a wide (32/64bit) counter. 60 | // - The number is the timer ID. 61 | // - The letter says which counter to use within that timer (each timer has 62 | // two counters, A and B which can be configured independantly. 63 | 64 | let (wide_timer, id) = 65 | match Regex::new(r"(w?)([0-5])").unwrap().captures(node.path.as_str()) { 66 | Some(c) => { 67 | (c.at(1) != Some(""), c.at(2)) 68 | } 69 | None => { 70 | error( 71 | format!("invalid timer index `{}`, it should match `w?[0-5]`", 72 | node.path).as_str()); 73 | return; 74 | } 75 | }; 76 | 77 | let mode = TokenString( 78 | format!("zinc::hal::tiva_c::timer::Mode::{}", 79 | match mode.as_str() { 80 | "periodic" => "Periodic", 81 | "one-shot" => "OneShot", 82 | "RTC" => "RTC", 83 | "edge-count" => "EdgeCount", 84 | "edge-time" => "EdgeTime", 85 | "PWM" => "PWM", 86 | _ => { 87 | error(format!("unknown mode {}, expected one of \ 88 | periodic, one-shot, RTC, edge-count, edge-time \ 89 | or PWM", mode).as_str()); 90 | return; 91 | }})); 92 | 93 | let timer_name = TokenString( 94 | format!("zinc::hal::tiva_c::timer::TimerId::{}{}", 95 | if wide_timer { 96 | "TimerW" 97 | } else { 98 | "Timer" 99 | }, id.unwrap())); 100 | 101 | node.set_type_name("zinc::hal::tiva_c::timer::Timer".to_string()); 102 | 103 | let st = quote_stmt!(&*cx, 104 | let $name = zinc::hal::tiva_c::timer::Timer::new( 105 | $timer_name, $mode, $prescale); 106 | ); 107 | builder.add_main_statement(st.unwrap()); 108 | } 109 | -------------------------------------------------------------------------------- /src/hal/tiva_c/uart_pt.rs: -------------------------------------------------------------------------------- 1 | // Zinc, the bare metal stack for rust. 2 | // Copyright 2014 Lionel Flandrin 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | use std::rc::Rc; 17 | use syntax::ext::base::ExtCtxt; 18 | use regex::Regex; 19 | 20 | use builder::{Builder, TokenString, add_node_dependency}; 21 | use node; 22 | 23 | pub fn attach(builder: &mut Builder, _: &mut ExtCtxt, node: Rc) { 24 | node.materializer.set(Some(verify as fn(&mut Builder, &mut ExtCtxt, Rc))); 25 | 26 | for sub in node.subnodes().iter() { 27 | add_node_dependency(&node, sub); 28 | super::add_node_dependency_on_clock(builder, sub); 29 | 30 | sub.materializer.set(Some(build_uart as fn(&mut Builder, &mut ExtCtxt, Rc))); 31 | } 32 | } 33 | 34 | pub fn verify(_: &mut Builder, cx: &mut ExtCtxt, node: Rc) { 35 | node.expect_no_attributes(cx); 36 | } 37 | 38 | pub fn build_uart(builder: &mut Builder, 39 | cx: &mut ExtCtxt, 40 | sub: Rc) { 41 | let error = |err: &str | { 42 | cx.parse_sess().span_diagnostic.span_err(sub.path_span, err); 43 | }; 44 | 45 | let uart_peripheral_str = format!("Uart{}", 46 | match sub.path.as_str().parse::().unwrap() { 47 | 0 ... 7 => sub.path.clone(), 48 | p => { 49 | error(format!("unknown UART `{}`, allowed values: 0, 2, 3", 50 | p).as_str()); 51 | return; 52 | } 53 | }); 54 | let uart_peripheral = TokenString(uart_peripheral_str); 55 | 56 | if sub.name.is_none() { 57 | cx.parse_sess().span_diagnostic.span_err(sub.name_span, 58 | "UART node must have a name"); 59 | return 60 | } 61 | 62 | if !sub.expect_attributes(cx, &[("mode", node::StrAttribute)]) { 63 | return 64 | } 65 | 66 | let mode = sub.get_string_attr("mode").unwrap(); 67 | 68 | let mode_re = 69 | Regex::new(r"([[:digit:]]+),?([[:digit:]]*)([nNoOEe]?)([[:digit:]])?").unwrap(); 70 | 71 | let mode_captures = match mode_re.captures(mode.as_str()) { 72 | Some(c) => c, 73 | None => { 74 | error(format!("invalid format {}", mode).as_str()); 75 | return; 76 | } 77 | }; 78 | 79 | let baud_rate = mode_captures.at(1).unwrap().parse::().unwrap(); 80 | 81 | let word_len = match mode_captures.at(2).unwrap() { 82 | "" => 8, 83 | l => l.parse::().unwrap(), 84 | }; 85 | 86 | let parity = TokenString(match mode_captures.at(3).unwrap() { 87 | ""|"N"|"n" => "Disabled", 88 | "O"|"o" => "Odd", 89 | "E"|"e" => "Even", 90 | "1" => "Forced1", 91 | "0" => "Forced0", 92 | p => { 93 | error(format!("invalid parity setting {}", p).as_str()); 94 | return; 95 | } 96 | }.to_string()); 97 | 98 | let stop_bits = match mode_captures.at(4).unwrap() { 99 | "" => 1, 100 | s => s.parse::().unwrap(), 101 | }; 102 | 103 | sub.set_type_name("zinc::hal::tiva_c::uart::Uart".to_string()); 104 | let uart_name = TokenString(sub.name.clone().unwrap()); 105 | 106 | let st = quote_stmt!(&*cx, 107 | let $uart_name = zinc::hal::tiva_c::uart::Uart::new( 108 | zinc::hal::tiva_c::uart::UartId::$uart_peripheral, 109 | $baud_rate, 110 | $word_len, 111 | zinc::hal::uart::Parity::$parity, 112 | $stop_bits 113 | ) 114 | ); 115 | 116 | builder.add_main_statement(st.unwrap()); 117 | } 118 | -------------------------------------------------------------------------------- /src/hal/uart.rs: -------------------------------------------------------------------------------- 1 | // Zinc, the bare metal stack for rust. 2 | // Copyright 2014 Vladimir "farcaller" Pouzanov 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | /*! 17 | UART interface. 18 | 19 | UARTConf is a MCU-specific struct. 20 | 21 | UART objects implement CharIO trait to perform actual data transmission. 22 | */ 23 | 24 | /// UART parity mode. 25 | #[derive(Clone, Copy)] 26 | pub enum Parity { 27 | /// Partity disabled. 28 | Disabled, 29 | /// Partity bit added to make number of 1s odd. 30 | Odd, 31 | /// Partity bit added to make number of 1s even. 32 | Even, 33 | /// Partity bit forced to 1. 34 | Forced1, 35 | /// Partity bit forced to 0. 36 | Forced0, 37 | } 38 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | // Zinc, the bare metal stack for rust. 2 | // Copyright 2014 Vladimir "farcaller" Pouzanov 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | #![feature(asm, lang_items, plugin)] 17 | #![feature(core_intrinsics, core_slice_ext, core_str_ext)] 18 | #![allow(improper_ctypes)] 19 | #![feature(const_fn)] 20 | #![deny(missing_docs)] 21 | #![no_std] 22 | 23 | /*! 24 | Zinc is an embedded stack for rust. 25 | 26 | Zinc provides a complete embedded stack for application development in rust. It 27 | is provided in a form of library, compiled for a specific MCU, that can be 28 | linked into user's own applications. 29 | 30 | ### Supported architectures 31 | 32 | ARM is the only architecture, supported at the moment. Zinc can be compiled for 33 | "native" architecture as well, which should be useful only for testing the code, 34 | though. 35 | 36 | ### Supported ARM MCUs 37 | 38 | Two MCUs are supported at the moment, specifically 39 | 40 | * NXP LPC1768 41 | * ST STM32F407 42 | * ST STM32L152RCT6 43 | * Freescale MK20DX32 44 | * TI TM4C123GXL 45 | 46 | The code is generic enough to support other MCUs in the same family (LPC17xx and 47 | STM32F403/407). 48 | */ 49 | #![plugin(ioreg)] 50 | 51 | #[cfg(target_os = "none")] 52 | extern crate rlibc; 53 | 54 | #[macro_use] #[no_link] extern crate ioreg; 55 | #[macro_use] extern crate volatile_cell; 56 | 57 | #[cfg(test)] extern crate std; 58 | 59 | #[cfg(test)] #[macro_use(expect)] extern crate expectest; 60 | 61 | pub mod drivers; 62 | pub mod hal; 63 | pub mod util; 64 | pub mod os; 65 | 66 | /// Export a subset of `core` as `std. 67 | /// 68 | /// This is exported as a temporary convenience as `rustc` still looks 69 | /// for some items in the `std` namespace. 70 | /// 71 | /// TODO(farcaller): clean up when fixed. 72 | #[cfg(target_os = "none")] 73 | pub mod std { 74 | pub use core::cmp; // used for #[derive(Eq)] until fixed in rust. 75 | pub use core::option; 76 | pub use core::num; 77 | pub use core::marker; 78 | } 79 | -------------------------------------------------------------------------------- /src/os/cond_var.rs: -------------------------------------------------------------------------------- 1 | // Zinc, the bare metal stack for rust. 2 | // Copyright 2014 Ben Gamari 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | //! Condition variables 17 | 18 | pub use os::cond_var::internal::{CondVar, COND_VAR_INIT}; 19 | 20 | #[cfg(multitasking)] 21 | mod internal { 22 | use core::option::{None, Some}; 23 | use core::ty::Unsafe; 24 | use core::marker::Sync; 25 | 26 | use hal::cortex_m3::sched::NoInterrupts; 27 | use util::queue::{Queue, Node}; 28 | use os::task::{TaskDescriptor, Tasks}; 29 | 30 | /// A condition variable 31 | pub struct CondVar { 32 | waiting: Queue<*mut TaskDescriptor> 33 | } 34 | 35 | /// Static initializer 36 | pub const COND_VAR_INIT: CondVar = CondVar { 37 | waiting: Queue { 38 | head: Unsafe { value: 0 as *mut Node<*mut TaskDescriptor>, marker1: marker::InvariantType }, 39 | tail: Unsafe { value: 0 as *mut Node<*mut TaskDescriptor>, marker1: marker::InvariantType }, 40 | } 41 | }; 42 | 43 | impl CondVar { 44 | /// Create a new condition variable 45 | pub fn new() -> CondVar { 46 | CondVar { waiting: Queue::new() } 47 | } 48 | 49 | /// Wait on a condition variable. 50 | pub fn wait(&self) { 51 | /* 52 | * The signalling thread is responsible for removing the waiting 53 | * thread which ensures that a signal wakes up exactly one thread 54 | * whenever there is one waiting. 55 | */ 56 | unsafe { 57 | let crit = NoInterrupts::new(); 58 | let mut waiting = Node::new(Tasks.current_task() as *mut TaskDescriptor); 59 | self.waiting.push(&mut waiting, &crit); 60 | Tasks.current_task().block(crit); 61 | } 62 | } 63 | 64 | /// Wake up a thread waiting on a condition variable. 65 | pub fn signal(&self) { 66 | unsafe { 67 | let crit = NoInterrupts::new(); 68 | match self.waiting.pop(&crit) { 69 | None => { }, 70 | Some(task) => (*(*task).data).unblock(&crit) 71 | } 72 | } 73 | } 74 | 75 | /// Wake up all threads waiting on a condition variable. 76 | pub fn broadcast(&self) { 77 | unsafe { 78 | let crit = NoInterrupts::new(); 79 | loop { 80 | match self.waiting.pop(&crit) { 81 | None => break, 82 | Some(task) => (*(*task).data).unblock(&crit) 83 | } 84 | } 85 | } 86 | } 87 | } 88 | 89 | impl Sync for CondVar {} 90 | } 91 | 92 | #[cfg(not(multitasking))] 93 | mod internal { 94 | use core::marker::Sync; 95 | use core::cell::UnsafeCell; 96 | 97 | use util::support::wfi; 98 | 99 | /// A condition variable 100 | pub struct CondVar { 101 | waiting: UnsafeCell, 102 | } 103 | 104 | /// Static initializer 105 | pub const COND_VAR_INIT: CondVar = CondVar { 106 | waiting: UnsafeCell::new(false), 107 | }; 108 | 109 | impl CondVar { 110 | /// Create a new condition variable 111 | pub fn new() -> CondVar { 112 | CondVar { 113 | waiting: UnsafeCell::new(false), 114 | } 115 | } 116 | 117 | /// Wait on a condition variable. 118 | pub fn wait(&self) { 119 | unsafe { 120 | // TODO(bgamari): There is a race condition here 121 | *self.waiting.get() = true; 122 | while *self.waiting.get() { 123 | wfi(); 124 | } 125 | } 126 | } 127 | 128 | /// Wake up a thread waiting on a condition variable. 129 | pub fn signal(&self) { 130 | unsafe { 131 | *self.waiting.get() = false; 132 | } 133 | } 134 | 135 | /// Wake up all threads waiting on a condition variable. 136 | pub fn broadcast(&self) { 137 | self.signal(); 138 | } 139 | } 140 | 141 | unsafe impl Sync for CondVar {} 142 | } 143 | -------------------------------------------------------------------------------- /src/os/debug.rs: -------------------------------------------------------------------------------- 1 | // Zinc, the bare metal stack for rust. 2 | // Copyright 2014 Ben Gamari 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | //! Tracing for debugging. 17 | // 18 | // Use `set_backend` 19 | 20 | pub use os::debug::internal::{set_backend, print, Token}; 21 | 22 | #[cfg(debug)] 23 | mod internal { 24 | use core::option::{Some, None, Option}; 25 | use core::ops::Drop; 26 | use core::mem::transmute; 27 | use drivers::chario::CharIO; 28 | 29 | static mut backend: Option<*const CharIO + 'static> = None; 30 | 31 | /// A token to ensure the life of the reference to the debugging output backend 32 | /// doesn't outlive the backend itself. 33 | #[must_use] 34 | pub struct Token<'a> { 35 | #[allow(dead_code)] 36 | hello: () 37 | } 38 | 39 | #[unsafe_destructor] 40 | impl<'a> Drop for Token<'a> { 41 | fn drop(&mut self) { 42 | unsafe { 43 | backend = None; 44 | } 45 | } 46 | } 47 | 48 | /// Set the debugging output backend (mock) 49 | pub fn set_backend<'a>(b: &'a CharIO) -> Token<'a> { 50 | unsafe { 51 | backend = Some(transmute(b)); 52 | Token { hello: () } 53 | } 54 | } 55 | 56 | /// Print debugging output backend (mock) 57 | pub fn print(s: &str) { 58 | unsafe { 59 | match backend { 60 | Some(b) => (*b).puts(s), 61 | None => {}, 62 | } 63 | } 64 | } 65 | } 66 | 67 | #[cfg(not(debug))] 68 | mod internal { 69 | use drivers::chario::CharIO; 70 | 71 | /// Set the debugging output backend (mock) 72 | pub fn set_backend(_: &CharIO) { } 73 | 74 | /// Print debugging output backend (mock) 75 | pub fn print(_: &str) { } 76 | 77 | /// A token to ensure the life of the reference to the debugging output backend 78 | /// doesn't outlive the backend itself. 79 | #[must_use] 80 | pub struct Token { 81 | #[allow(dead_code)] 82 | hello: () 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /src/os/mod.rs: -------------------------------------------------------------------------------- 1 | // Zinc, the bare metal stack for rust. 2 | // Copyright 2014 Vladimir "farcaller" Pouzanov 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | /*! 17 | RTOS support code. 18 | 19 | This module is a higher level abstraction over hardware than hal. It might be 20 | incompatible direct hal usage in some cases. 21 | */ 22 | 23 | // pub mod debug; 24 | pub mod syscall; 25 | #[cfg(feature = "multitasking")] pub mod task; 26 | pub mod mutex; 27 | pub mod cond_var; 28 | pub mod debug; 29 | -------------------------------------------------------------------------------- /src/os/syscall.rs: -------------------------------------------------------------------------------- 1 | // Zinc, the bare metal stack for rust. 2 | // Copyright 2014 Vladimir "farcaller" Pouzanov 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | /*! 17 | Syscall interface. 18 | 19 | This module provides syscall interface that is implemented in assembly due to 20 | current rust restrictions (see hal/cortex_m3/sched.S for actual implementation). 21 | */ 22 | 23 | extern { 24 | pub fn syscall(f: fn(u32), arg: u32); 25 | } 26 | -------------------------------------------------------------------------------- /src/util/app.rs: -------------------------------------------------------------------------------- 1 | // Zinc, the bare metal stack for rust. 2 | // Copyright 2014 Vladimir "farcaller" Pouzanov 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | //! The final object that gets linked into the binary. Provides trampilines 17 | //! for stack management, scheduler, ISRs and other symbols with global 18 | //! visibility. 19 | 20 | #![crate_type="staticlib"] 21 | #![no_std] 22 | 23 | extern crate zinc; 24 | extern crate app; 25 | 26 | #[no_stack_check] 27 | #[no_mangle] 28 | pub extern fn main() { 29 | app::main(); 30 | } 31 | 32 | #[no_stack_check] 33 | #[no_mangle] 34 | #[cfg(not(feature = "multitasking"))] 35 | pub extern fn __morestack() { 36 | unsafe { core::intrinsics::abort() }; 37 | } 38 | 39 | #[no_stack_check] 40 | #[no_mangle] 41 | #[cfg(feature = "multitasking")] 42 | pub extern fn __morestack() { 43 | zinc::os::task::morestack(); 44 | } 45 | 46 | #[no_stack_check] 47 | #[no_mangle] 48 | #[cfg(feature = "multitasking")] 49 | pub unsafe fn task_scheduler() { 50 | zinc::os::task::task_scheduler(); 51 | } 52 | -------------------------------------------------------------------------------- /src/util/ioreg.rs: -------------------------------------------------------------------------------- 1 | // Zinc, the bare metal stack for rust. 2 | // Copyright 2014 Vladimir "farcaller" Pouzanov 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | macro_rules! ioreg_old( 17 | ($io:ident: $ty:ty, $($reg:ident),+) => ( 18 | #[allow(non_snake_case)] 19 | #[derive(Clone, Copy)] 20 | pub struct $io { 21 | $( 22 | $reg: VolatileCell<$ty>, 23 | )+ 24 | } 25 | ) 26 | ); 27 | 28 | macro_rules! reg_r( 29 | ($t:ident, $ty:ty, $getter_name:ident, $reg:ident) => ( 30 | impl $t { 31 | #[allow(dead_code,non_snake_case)] 32 | #[inline(always)] 33 | pub fn $getter_name(&self) -> $ty { 34 | self.$reg.get() 35 | } 36 | } 37 | ) 38 | ); 39 | 40 | macro_rules! reg_w( 41 | ($t:ident, $ty:ty, $setter_name:ident, $reg:ident) => ( 42 | impl $t { 43 | #[allow(dead_code,non_snake_case)] 44 | #[inline(always)] 45 | pub fn $setter_name(&self, val: $ty) { 46 | self.$reg.set(val); 47 | } 48 | } 49 | ) 50 | ); 51 | 52 | macro_rules! reg_rw( 53 | ($t:ident, $ty:ty, $getter_name:ident, $setter_name:ident, $reg:ident) => ( 54 | reg_r!($t, $ty, $getter_name, $reg); 55 | reg_w!($t, $ty, $setter_name, $reg); 56 | ) 57 | ); 58 | -------------------------------------------------------------------------------- /src/util/lang_items.rs: -------------------------------------------------------------------------------- 1 | // Zinc, the bare metal stack for rust. 2 | // Copyright 2014 Vladimir "farcaller" Pouzanov 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | #[cfg(all(not(test), not(feature = "test")))] 17 | use core::fmt::Arguments; 18 | 19 | #[cfg(all(not(test), not(feature = "test")))] 20 | #[lang="eh_personality"] 21 | extern fn eh_personality() {} 22 | 23 | #[cfg(all(not(test), not(feature = "test")))] 24 | #[lang="panic_fmt"] 25 | pub fn panic_fmt(_fmt: &Arguments, _file_line: &(&'static str, usize)) -> ! { 26 | loop { } 27 | } 28 | -------------------------------------------------------------------------------- /src/util/mod.rs: -------------------------------------------------------------------------------- 1 | // Zinc, the bare metal stack for rust. 2 | // Copyright 2014 Vladimir "farcaller" Pouzanov 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | //! Helper methods. 17 | 18 | pub mod strconv; 19 | pub mod support; 20 | pub mod shared; 21 | #[cfg(feature = "multitasking")] pub mod queue; 22 | 23 | mod lang_items; 24 | -------------------------------------------------------------------------------- /src/util/queue.rs: -------------------------------------------------------------------------------- 1 | // Rough structure taken from libsync's mpcs_intrusive 2 | // all links are usize to allow for static initialization 3 | 4 | // 5 | // head tail 6 | // | |--->| |--->| |--->| |--->| | 7 | // 8 | 9 | use core::ty::Unsafe; 10 | use core::cmp::Ord; 11 | use core::ops::Deref; 12 | use core::ptr::RawPtr; 13 | use core::option::Option::{self, Some, None}; 14 | 15 | use hal::cortex_m3::sched::NoInterrupts; 16 | 17 | pub struct Node { 18 | pub next: Unsafe<*mut Node>, 19 | pub data: T 20 | } 21 | 22 | pub struct Queue { 23 | pub head: Unsafe<*mut Node>, 24 | pub tail: Unsafe<*mut Node> 25 | } 26 | 27 | fn null_mut() -> *mut T { 0 as *mut T } 28 | 29 | impl Queue { 30 | pub fn new() -> Queue { 31 | Queue { 32 | head: Unsafe::new(null_mut()), 33 | tail: Unsafe::new(null_mut()) 34 | } 35 | } 36 | 37 | /// Push to tail. 38 | pub unsafe fn push(&self, node: *mut Node, _: &NoInterrupts) { 39 | if (*self.head.get()).is_null() { 40 | *self.head.get() = node; 41 | } 42 | let tail: *mut Node = *self.tail.get(); 43 | *(*node).next.get() = null_mut(); 44 | if !tail.is_null() { 45 | *(*tail).next.get() = node; 46 | } 47 | *self.tail.get() = node; 48 | } 49 | 50 | /// Peek at head. 51 | pub unsafe fn peek(&self) -> Option<*mut Node> { 52 | let head = self.head.get(); 53 | if (*head).is_null() { 54 | None 55 | } else { 56 | Some(*head) 57 | } 58 | } 59 | 60 | /// Pop off of head. 61 | pub unsafe fn pop(&self, _: &NoInterrupts) -> Option<*mut Node> { 62 | let head = self.head.get(); 63 | if (*head).is_null() { 64 | None 65 | } else { 66 | *head = *(**head).next.get(); 67 | Some(*head) 68 | } 69 | } 70 | } 71 | 72 | impl Queue { 73 | /// Priority insertion (higher ends up closer to head). 74 | pub unsafe fn insert(&self, node: *mut Node, _: &NoInterrupts) { 75 | let mut next: &Unsafe<*mut Node> = &self.head; 76 | loop { 77 | let i: *mut Node = *next.get(); 78 | if i.is_null() { 79 | break; 80 | } 81 | if (*i).data > (*node).data { 82 | break; 83 | } 84 | next = &(*i).next; 85 | } 86 | *(*node).next.get() = *next.get(); 87 | *next.get() = node; 88 | if (*(*node).next.get()).is_null() { 89 | *self.tail.get() = node; 90 | } 91 | } 92 | } 93 | 94 | impl Node { 95 | pub fn new(data: T) -> Node { 96 | Node { next: Unsafe::new(null_mut()), data: data } 97 | } 98 | } 99 | 100 | impl Deref for Node { 101 | fn deref<'a>(&'a self) -> &'a T {&self.data} 102 | } 103 | -------------------------------------------------------------------------------- /src/util/shared.rs: -------------------------------------------------------------------------------- 1 | // Zinc, the bare metal stack for rust. 2 | // Copyright 2014 Ben Gamari 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | //! Concurrency-friendly shared state 17 | 18 | use core::cell::UnsafeCell; 19 | use core::ops::{Deref, DerefMut}; 20 | use core::marker::{Sync, Send}; 21 | 22 | #[cfg(feature = "cpu_cortex-m3")] 23 | use hal::cortex_m3::irq::NoInterrupts; 24 | #[cfg(feature = "cpu_cortex-m4")] 25 | use hal::cortex_m4::irq::NoInterrupts; 26 | // If cpu doesn't have nointerrupts provide dummy implementation 27 | #[cfg(not(any(feature = "cpu_cortex-m3", 28 | feature = "cpu_cortex-m4")))] 29 | use self::dummy_irq::NoInterrupts; 30 | 31 | #[allow(missing_docs)] 32 | mod dummy_irq { 33 | pub struct NoInterrupts; 34 | 35 | impl NoInterrupts { 36 | #[allow(dead_code)] 37 | pub fn new() -> NoInterrupts { 38 | NoInterrupts 39 | } 40 | } 41 | } 42 | 43 | /// This allows safe sharing of state, ensuring access occurs only 44 | /// when in a critical section. 45 | #[allow(missing_docs)] 46 | pub struct Shared { 47 | pub value: UnsafeCell, 48 | } 49 | 50 | /// A reference to a shared value 51 | pub struct SharedRef<'a, T: 'a> { 52 | ptr: &'a Shared, 53 | #[allow(dead_code)] 54 | crit: &'a NoInterrupts 55 | } 56 | 57 | impl Shared { 58 | /// Create a new `Shared` value 59 | pub fn new(value: T) -> Shared { 60 | Shared { 61 | value: UnsafeCell::new(value), 62 | } 63 | } 64 | 65 | /// Borrow a reference to the value 66 | pub fn borrow<'a>(&'a self, crit: &'a NoInterrupts) -> SharedRef<'a, T> { 67 | SharedRef {ptr: self, crit: crit} 68 | } 69 | } 70 | 71 | impl<'a, T> Deref for SharedRef<'a, T> { 72 | type Target = T; 73 | fn deref<'b>(&'b self) -> &'b T { 74 | unsafe { 75 | &*self.ptr.value.get() 76 | } 77 | } 78 | } 79 | 80 | impl<'a, T> DerefMut for SharedRef<'a, T> { 81 | fn deref_mut<'b>(&'b mut self) -> &'b mut T { 82 | unsafe { 83 | &mut *self.ptr.value.get() 84 | } 85 | } 86 | } 87 | 88 | unsafe impl Sync for Shared {} 89 | -------------------------------------------------------------------------------- /src/util/strconv.rs: -------------------------------------------------------------------------------- 1 | // Zinc, the bare metal stack for rust. 2 | // Copyright 2014 Vladimir "farcaller" Pouzanov 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | //! A simple integer-to-string conversion code with statically sized buffers. 17 | 18 | use core::mem::uninitialized; 19 | 20 | /// Convert an integer to a string. 21 | pub fn itoa(val: u32, buf : &mut [u8], base: u32) { 22 | let mut rbuf : [u8; 32] = unsafe { uninitialized() }; 23 | let mut myval : u32 = val; 24 | let mut idx: isize = 0; 25 | 26 | if myval == 0 { 27 | buf[0] = '0' as u8; 28 | return; 29 | } 30 | 31 | while myval > 0 { 32 | let digit : u8 = (myval % base) as u8; 33 | myval = myval / base; 34 | 35 | rbuf[idx as usize] = digit; 36 | 37 | idx += 1; 38 | } 39 | 40 | idx -= 1; 41 | 42 | let mut ridx = 0; 43 | 44 | while idx >= 0 { 45 | let charcode : u8 = ['0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'][rbuf[idx as usize] as usize] as u8; 46 | 47 | buf[ridx] = charcode; 48 | 49 | idx -= 1; 50 | ridx += 1; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/util/support.rs: -------------------------------------------------------------------------------- 1 | // Zinc, the bare metal stack for rust. 2 | // Copyright 2014 Vladimir "farcaller" Pouzanov 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | //! Support functions currently required by the linker for bare-metal targets. 17 | 18 | pub use core::intrinsics::breakpoint; 19 | 20 | /// Call the debugger and halts execution. 21 | #[no_mangle] 22 | pub extern fn abort() -> ! { 23 | unsafe { 24 | breakpoint(); 25 | } 26 | loop {} 27 | } 28 | 29 | // TODO(bgamari): This is only necessary for exception handling and 30 | // can be removed when we have this issue resolved. 31 | #[doc(hidden)] 32 | #[no_mangle] 33 | pub extern fn __aeabi_memset(dest: *mut u8, size: usize, value: u32) { 34 | unsafe { 35 | use core::intrinsics::volatile_set_memory; 36 | volatile_set_memory(dest, value as u8, size); 37 | } 38 | } 39 | 40 | #[doc(hidden)] 41 | #[no_mangle] 42 | pub extern fn __aeabi_memclr(dest: *mut u8, size: usize) { 43 | unsafe { 44 | use core::intrinsics::volatile_set_memory; 45 | volatile_set_memory(dest, 0, size); 46 | } 47 | } 48 | 49 | #[cfg(target_arch = "arm")] 50 | #[inline(always)] 51 | /// NOP instruction 52 | pub fn nop() { 53 | unsafe { asm!("nop" :::: "volatile"); } 54 | } 55 | 56 | #[cfg(not(target_arch = "arm"))] 57 | /// NOP instruction (mock) 58 | pub fn nop() { 59 | } 60 | 61 | #[cfg(target_arch = "arm")] 62 | #[inline(always)] 63 | /// WFI instruction 64 | pub fn wfi() { 65 | unsafe { asm!("wfi" :::: "volatile"); } 66 | } 67 | 68 | #[cfg(not(target_arch = "arm"))] 69 | /// WFI instruction (mock) 70 | pub fn wfi() { 71 | } 72 | 73 | /// Hack to get a static 'ioreg' reference from a raw pointer to the register 74 | /// base 75 | pub fn get_reg_ref(t: *const T) -> &'static T { 76 | unsafe { 77 | &*t 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/util/wait_for.rs: -------------------------------------------------------------------------------- 1 | // Zinc, the bare metal stack for rust. 2 | // Copyright 2014 Vladimir "farcaller" Pouzanov 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | macro_rules! wait_for( 17 | ($cond:expr) => ( 18 | loop { 19 | if $cond { 20 | break; 21 | } 22 | } 23 | ) 24 | ); 25 | -------------------------------------------------------------------------------- /support/build-examples.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # Zinc, the bare metal stack for rust. 4 | # Copyright 2014 Matt Coffin 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | set -e 19 | for e in $EXAMPLES; do 20 | EXAMPLE_NAME=$e make build 21 | done 22 | -------------------------------------------------------------------------------- /support/build-jenkins.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | rustup show 6 | 7 | print_info() { 8 | echo " * $1 at: $(which $1)" 9 | echo " * $1 version: `$1 --version`" 10 | } 11 | 12 | print_info rustc 13 | print_info cargo 14 | print_info xargo 15 | 16 | if [ "$PLATFORM" == "native" ]; then 17 | # build unit tests 18 | echo " * building zinc" 19 | cargo test --features test --lib --verbose 20 | echo " * building ioreg" 21 | (cd ./ioreg; cargo build --verbose; cargo test --verbose) 22 | echo " * building platformtree" 23 | (cd ./platformtree; cargo build --verbose; cargo test --verbose) 24 | echo " * building platformtree macro" 25 | (cd ./macro_platformtree; cargo build --verbose; cargo test --verbose) 26 | echo " * building zinc macro" 27 | (cd ./macro_zinc; cargo test --verbose) 28 | 29 | echo " * generating coverage data" 30 | if [ "$TRAVIS_JOB_ID" != "" ]; then 31 | kcov-master/tmp/usr/local/bin/kcov --coveralls-id=$TRAVIS_JOB_ID --exclude-pattern=/.cargo target/kcov target/debug/zinc-* 32 | kcov-master/tmp/usr/local/bin/kcov --coveralls-id=$TRAVIS_JOB_ID --exclude-pattern=/.cargo target/kcov ioreg/target/debug/test-* 33 | kcov-master/tmp/usr/local/bin/kcov --coveralls-id=$TRAVIS_JOB_ID --exclude-pattern=/.cargo target/kcov platformtree/target/debug/platformtree-* 34 | else 35 | kcov cov/ target/debug/zinc-* 36 | support/fixcov.py src/ cov/zinc-????????????????/cobertura.xml 37 | kcov cov/ ioreg/target/debug/test-* 38 | support/fixcov.py ioreg/src/ cov/test-????????????????/cobertura.xml 39 | kcov cov/ platformtree/target/debug/platformtree-* 40 | support/fixcov.py platformtree/src/ cov/platformtree-????????????????/cobertura.xml 41 | fi 42 | 43 | else 44 | # build cross-compiled lib and examples 45 | case "$PLATFORM" in 46 | lpc11xx ) 47 | TARGET=thumbv6m-none-eabi 48 | EXAMPLES="empty" 49 | ;; 50 | lpc17xx ) 51 | TARGET=thumbv7m-none-eabi 52 | EXAMPLES="empty blink_lpc17xx blink_pt uart dht22 rgb_pwm_lpc17xx adc_lpc17xx" 53 | ;; 54 | k20 ) 55 | TARGET=thumbv7em-none-eabi 56 | EXAMPLES="empty blink_k20 blink_k20_isr" 57 | ;; 58 | stm32f1 ) 59 | TARGET=thumbv7m-none-eabi 60 | EXAMPLES="empty blink_stm32f1 usart_stm32f1" 61 | ;; 62 | stm32f4 ) 63 | TARGET=thumbv7em-none-eabi 64 | EXAMPLES="empty blink_stm32f4" 65 | ;; 66 | stm32l1 ) 67 | TARGET=thumbv7m-none-eabi 68 | EXAMPLES="empty blink_stm32l1 bluenrg_stm32l1 usart_stm32l1" 69 | ;; 70 | esac 71 | 72 | xargo build --target=$TARGET --verbose --features "mcu_$PLATFORM" --lib 73 | 74 | for e in $EXAMPLES; do 75 | pushd "examples/$e" 76 | xargo build --target=$TARGET --verbose --features "mcu_$PLATFORM" --release 77 | popd 78 | done 79 | fi 80 | -------------------------------------------------------------------------------- /support/fixcov.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import os, sys 4 | 5 | from lxml import objectify, etree 6 | E = objectify.ElementMaker(annotate=False) 7 | 8 | def all_rs_sources(path, prefix): 9 | if prefix[-1] != '/': 10 | raise RuntimeError('"{}" needs to end with /'.format(path)) 11 | def fixpath(p): 12 | p = os.path.abspath(p) 13 | if not p.startswith(prefix): 14 | raise RuntimeError('expected prefix "{}", got "{}"'.format(prefix, p)) 15 | return p[len(prefix):] 16 | return [(fixpath(os.path.join(dirpath, f)), os.path.join(os.path.abspath(dirpath), f)) 17 | for dirpath, dirnames, files in os.walk(path) 18 | for f in files if f.endswith('.rs')] 19 | 20 | def source_to_lines(source): 21 | lines = open(source).readlines() 22 | out = [] 23 | i = 0 24 | for l in lines: 25 | i += 1 26 | 27 | l = l.strip() 28 | if ( 29 | l.startswith('//') # comments 30 | or len(l) == 0 # empty lines 31 | or l == '}' # single closing brace 32 | or l.startswith('use ') # use 33 | ): 34 | continue 35 | 36 | out.append(i) 37 | return out 38 | 39 | def build_source_xml(relpath, source): 40 | name = os.path.split(source)[-1].replace('.rs', '_rs') 41 | lines = source_to_lines(source) 42 | 43 | s = '\n'.format(name, relpath) 44 | for l in lines: 45 | s += ' '.format(l) 46 | s += '' 47 | 48 | return etree.XML(s) 49 | 50 | def update_cov(path, cov_file): 51 | cov = etree.parse(cov_file) 52 | source_prefix = cov.xpath('//source')[0].text 53 | existing_files = set(cov.xpath('//class/@filename')) 54 | all_files = all_rs_sources(path, source_prefix) 55 | 56 | new_files = [] 57 | for f, ap in all_files: 58 | if not f in existing_files: 59 | new_files.append((f, ap)) 60 | 61 | classes = cov.xpath('//classes')[0] 62 | for f, ap in new_files: 63 | classes.append(build_source_xml(f, ap)) 64 | 65 | genxml = etree.tostring(cov) 66 | f = open(cov_file, 'w') 67 | f.write(genxml) 68 | f.close() 69 | print " * fixcov added {} empty coverge files to {}".format(len(new_files), cov_file) 70 | 71 | if __name__ == '__main__': 72 | update_cov(sys.argv[1], sys.argv[2]) 73 | -------------------------------------------------------------------------------- /support/img_to_arr.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | require 'chunky_png' 4 | image = ChunkyPNG::Image.from_file '/Users/farcaller/Desktop/header-firefox.png' 5 | 6 | open('img.rs', 'w') do |f| 7 | f.write(<<-EOF) 8 | 9 | pub static image_width: u32 = #{image.width}; 10 | pub static image_height: u32 = #{image.height}; 11 | pub static image_data: &'static [u16] = &[ 12 | EOF 13 | 14 | image.height.times do |y| 15 | image.width.times do |x| 16 | pixel = image[x, y] 17 | 18 | # split 19 | r = (pixel & 0xff000000) >> 24 20 | g = (pixel & 0xff0000) >> 16 21 | b = (pixel & 0xff00) >> 8 22 | a = (pixel & 0xff) 23 | 24 | # scale to 5:6:5 25 | r5 = (0b11111.to_f * r / 255).floor 26 | g6 = (0b111111.to_f * g / 255).floor 27 | b5 = (0b11111.to_f * b / 255).floor 28 | 29 | out_pixel = (r5 << 11) | (g6 << 5) | b5 30 | 31 | f.write("#{out_pixel}, ") 32 | end 33 | f.write("\n") 34 | end 35 | 36 | f.write("];") 37 | end 38 | -------------------------------------------------------------------------------- /support/install-rustup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Usage: install-rustup.sh 3 | 4 | set -e 5 | 6 | rustup_file=$(mktemp -p .) 7 | 8 | curl https://sh.rustup.rs -sSf -o $rustup_file && chmod +x $rustup_file 9 | $rustup_file -y 10 | 11 | rustup override set $1 12 | rustup component add rust-src 13 | 14 | cargo install xargo 15 | 16 | # Cleanup 17 | rm $rustup_file 18 | -------------------------------------------------------------------------------- /support/svd/Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | gem 'nokogiri' 3 | gem 'erubis' 4 | -------------------------------------------------------------------------------- /support/svd/data/Freescale/Freescale CMSIS-SVD License Agreement.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hackndev/zinc/63826151df91f87c2195c9f2c5f6422f275d3191/support/svd/data/Freescale/Freescale CMSIS-SVD License Agreement.pdf -------------------------------------------------------------------------------- /support/svd/data/Freescale/README.md: -------------------------------------------------------------------------------- 1 | ## Finding More Freescale SVD Files 2 | 3 | Additional SVD XML files for various freescale processors may be found 4 | as part of the McuOnEclipse Sourceforge pages here: 5 | 6 | http://sourceforge.net/projects/mcuoneclipse/files/Eclipse%20Plugins/EmbSysReg/ 7 | 8 | Many of these files are included in the Eclipse EmbSysRegView plugin. 9 | -------------------------------------------------------------------------------- /support/svd/data/NXP/Changelog.md: -------------------------------------------------------------------------------- 1 | LPC11xx 2 | ======= 3 | 4 | * LPC11xx-v6-z0 5 | modified a few constants to make the enums compilable 6 | 7 | * LPC11xx-v6 8 | original fetched from http://www.lpcware.com/content/nxpfile/lpc11xx-svd-file 9 | -------------------------------------------------------------------------------- /support/svd/template.rs.erb: -------------------------------------------------------------------------------- 1 | // Zinc, the bare metal stack for rust. 2 | // Copyright 2015 zinc developers 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | // THIS FILE IS AUTOMATICALLY GENERATED. DO NOT MODIFY IT DIRECTLY, UPDATE THE 17 | // SVD DEFINITION IN SUPPORT/SVD/DATA AND RE-GENERATE, ADDING THE CHANGES MADE 18 | // INTO THE RELEVANT CHANGELOG ENTRY. 19 | 20 | //! ioregs definition based on <%= @filename %> 21 | 22 | use volatile_cell::VolatileCell; 23 | use core::ops::Drop; 24 | 25 | <% @svd.peripherals.each do |peripheral| %> 26 | ioregs! (<%= peripheral.name %> @ <%= peripheral.base_address.to_hex %> = { //! <%= peripheral.description %> 27 | <% peripheral.registers.each do |reg| %> 28 | <%= reg.offset.to_hex %> => reg<%= reg.size %> <%= reg.name %> { //! <%= reg.description %> 29 | <% reg.fields.each do |f| %> 30 | <% unless f.enums.empty? %> 31 | <%= f.bits_string %> => <%= f.name %><%= @map_access.call(f.access) %> { //! <%= f.description %> 32 | <% f.enums.each do |e| %> 33 | <% if !e.name['RESERVED'] %> 34 | <%= e.value %> => <%= e.name %>, //= <%= e.description %> 35 | <% end %> 36 | <% end %> 37 | } 38 | <% else %> 39 | <%= f.bits_string %> => <%= f.name %><%= @map_access.call(f.access) %>, //= <%= f.description %> 40 | <% end %> 41 | <% end %> 42 | }, 43 | <% end %> 44 | }); 45 | <% end %> 46 | -------------------------------------------------------------------------------- /thumbv6m-none-eabi.json: -------------------------------------------------------------------------------- 1 | { 2 | "llvm-target": "thumbv6m-none-eabi", 3 | "target-endian": "little", 4 | "target-pointer-width": "32", 5 | "os": "none", 6 | "env": "eabi", 7 | "vendor": "unknown", 8 | "arch": "arm", 9 | 10 | "data-layout": "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64", 11 | "pre-link-args": [ 12 | "-Tlayout.ld" 13 | ], 14 | "post-link-args": [ 15 | "-lm", "-lgcc", "-lnosys" 16 | ], 17 | "cpu": "cortex-m0", 18 | "executables": true, 19 | "relocation-model": "static", 20 | "no-compiler-rt": true 21 | } 22 | -------------------------------------------------------------------------------- /thumbv7em-none-eabi.json: -------------------------------------------------------------------------------- 1 | { 2 | "arch": "arm", 3 | "cpu": "cortex-m4", 4 | "data-layout": "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64", 5 | "disable-redzone": true, 6 | "executables": true, 7 | "llvm-target": "thumbv7em-none-eabi", 8 | "morestack": false, 9 | "os": "none", 10 | "relocation-model": "static", 11 | "target-endian": "little", 12 | "target-pointer-width": "32", 13 | "no-compiler-rt": true, 14 | "pre-link-args": [ 15 | "-mcpu=cortex-m4", "-mthumb", 16 | "-Tlayout.ld" 17 | ], 18 | "post-link-args": [ 19 | "-lm", "-lgcc", "-lnosys" 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /thumbv7m-none-eabi.json: -------------------------------------------------------------------------------- 1 | { 2 | "arch": "arm", 3 | "cpu": "cortex-m3", 4 | "data-layout": "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64", 5 | "disable-redzone": true, 6 | "executables": true, 7 | "llvm-target": "thumbv7m-none-eabi", 8 | "morestack": false, 9 | "os": "none", 10 | "relocation-model": "static", 11 | "target-endian": "little", 12 | "target-pointer-width": "32", 13 | "no-compiler-rt": true, 14 | "pre-link-args": [ 15 | "-mcpu=cortex-m3", "-mthumb", 16 | "-Tlayout.ld" 17 | ], 18 | "post-link-args": [ 19 | "-lm", "-lgcc", "-lnosys" 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /volatile_cell/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | 3 | name = "volatile_cell" 4 | version = "1.0.0" 5 | authors = ["Vladimir Pouzanov "] 6 | 7 | [lib] 8 | name = "volatile_cell" 9 | path = "lib.rs" 10 | test = false 11 | doctest = false 12 | doc = true 13 | crate-type = ["rlib"] 14 | 15 | [features] 16 | replayer = ["expectest"] 17 | 18 | [dependencies.expectest] 19 | version = "^0.6" 20 | optional = true 21 | --------------------------------------------------------------------------------