1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
//! A crate to play with the [STM32F3DISCOVERY]
//!
//! [STM32F3DISCOVERY]: http://www.st.com/en/evaluation-tools/stm32f3discovery.html
//!
//! (What? You don't have one? How come? They are awesome and cheap ($15 + shipping))
//!
//! (No, I'm not associated to STM32. I just like this board in particular.)
//!
//! # Features
//!
//! - High-level API over LEDs, sensors, timers, etc.
//! - An `iprint!` family of macros that sink their output to the ITM (Instrumentation Trace
//!   Macrocell) so you send data to the host over the same USB cable that you are using to debug
//!   your device.
//! - By default, `panic!`s also sink their messages to the ITM
//! - By default, an informative exception handler that tells you what went wrong.
//! - By default, everything (LEDs, sensors, etc) is initialized before the user entry point,
//!   `main`. So everything Just Works out of the box.
//! - Plenty of examples
//!
//! Also, all the "default" behaviors can be overridden:
//!
//! - The default exception handler
//! - The default `panic_fmt` implementation
//! - The default system initialization routine that runs before main.
//!
//! # Requirements and starter code
//!
//! Today, you need these 7 things, one of them optional, but hopefully you won't need 3 of them in
//! the future:
//!
//! - Nightly Rust compiler: `rustup default nightly`
//! - [Xargo](https://crates.io/crates/xargo) version 0.1.12 or newer. (After
//!   [rust-lang/rfcs#1133](https://github.com/rust-lang/rfcs/pull/1133) gets accepted and
//!   implemented you won't need Xargo anymore)
//! - A binary Cargo project that depends on this crate.
//!
//! ``` text
//! $ cargo new --bin foo && cd $_
//! $ edit Cargo.toml && tail -n2 $_
//! [dependencies]
//! f3 = "0.1.0"
//! ```
//!
//! - Optionally, you can also set `profile.release.lto = true` for even smaller binaries.
//!
//! ``` text
//! $ edit Cargo.toml && tail -n2 $_
//! [profile.release]
//! lto = true
//! ```
//!
//! - This `.cargo/config` in the root of your Cargo project. (If Cargo build scripts ever gain a
//!   feature to pass arbitrary arguments to the linker then you won't *need* this. Setting
//!   `build.target` though always improves ergonomics)
//!
//! ``` text
//! $ cat .cargo/config
//! [build]
//! target = "thumbv7em-none-eabihf"
//!
//! [target.thumbv7em-none-eabihf]
//! rustflags = [
//!     "-C",
//!     "link-arg=-Tstm32f3discovery.ld",
//!     "-C",
//!     "link-arg=-nostartfiles",
//! ]
//! ```
//!
//! - This target specification file. (You won't need this after 2016-10-05 as these targets have
//!   already landed [in the compiler](https://github.com/rust-lang/rust/pull/36874))
//!
//! ``` text
//! $ cat thumbv7em-none-eabihf.json
//! {
//!     "arch": "arm",
//!     "data-layout": "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64",
//!     "executables": true,
//!     "features": "+vfp4,+d16,+fp-only-sp",
//!     "linker": "arm-none-eabi-gcc",
//!     "llvm-target": "thumbv7em-none-eabihf",
//!     "os": "none",
//!     "panic-strategy": "abort",
//!     "relocation-model": "static",
//!     "target-endian": "little",
//!     "target-pointer-width": "32"
//! }
//! ```
//!
//! - And this starter code:
//!
//! ``` text
//! $ cat src/main.rs
//! #![no_main]
//! #![no_std]
//!
//! extern crate f3;
//!
//! #[export_name = "main"]
//! pub fn main() -> ! {
//!     // Your code goes here!
//!
//!     loop {}
//! }
//! ```
//!
//! With all that in place, you can finally build the project using Xargo:
//!
//! ``` text
//! $ xargo build [--target thumbv7em-none-eabihf] [--release]
//! ```
//!
//! Check out the [Copper] book for instructions on how to Flash and Debug this program!
//!
//! [Copper]: http://japaric.github.io/copper/
//!
//! # Examples
//!
//! See the [examples](examples/index.html) module.

#![cfg_attr(target_arch = "arm", feature(core_intrinsics))]
#![deny(warnings)]
#![feature(asm)]
#![feature(lang_items)]
#![feature(linkage)]
#![feature(naked_functions)]
#![no_std]

#[macro_use]
extern crate cortex_m;
extern crate compiler_builtins_snapshot;
extern crate r0;
extern crate volatile_register;

#[macro_use]
mod macros;

#[cfg(target_arch = "arm")]
mod lang_items;

pub mod delay;
pub mod examples;
pub mod exception;
pub mod itm;
pub mod led;
pub mod peripheral;

// Default initialization routine
#[doc(hidden)]
#[export_name = "_init"]
#[linkage = "weak"]
pub unsafe extern "C" fn init() {
    delay::init();
    itm::init();
    led::init();
}

extern "C" {
    // `main`, the entry point of the user program
    // NOTE the right signature of `main` is `fn() -> !`. But the user might get that wrong so
    // let's err on the side of caution and install a safety net (see below).
    fn main();
}