[][src]Crate teensy

Teensy

This crate provide multiple helpers functions to manipulate the teensy in baremetal rust. Currently everything is tested on a teensy 3.2. It provide:

Quick start

Get the dependencies

# archlinux
sudo pacman -S arm-none-eabi-binutils
# ubuntu
sudo apt install binutils-arm-none-eabi
# macOS
brew install gcc-arm-none-eabi
# archlinux aur
yay -S teensy_loader_cli
# or
yaourt -S teensy_loader_cli
# macOS
brew install teensy_loader_cli

For other distribution or if you want to avoid the aur package you can manually install it from here

Prepare your environment

  1. Add the crate as a dependency Currently the crate is still under heavy development so there is no release on crate.io. To include this crate in your project add this line to the dependency section of your Cargo.toml file:
teensy = { git = "https://github.com/irevoire/teensy.git"}
  1. Nightly rust Finally to compile with this crate you need to use the nightly channel, just run:
rustup override set nightly
  1. The correct target You’ll not compile your code for the casual x86 assembly. You'll need to install a new target for arm processor:
rustup target add thumbv7em-none-eabi

Compile with this crate

Linker

To compile code for the teensy this crate provide multiple section that you'll need to put in the right place. To do this we provide a linker script that you can copy paste as layout.ld:

MEMORY
{
	FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 256K
	RAM  (rwx) : ORIGIN = 0x1FFF8000, LENGTH = 64K
}
EXTERN(_INTERRUPTS);
SECTIONS
{
    PROVIDE(_stack_top = ORIGIN(RAM) + LENGTH(RAM));
    .vector_table ORIGIN(FLASH) : {
        LONG(_stack_top);
        KEEP(*(.vector_table.interrupts));
    } > FLASH
	.text : {
		. = 0x400;
		KEEP(*(.flashconfig*))
		. = ALIGN(4);
		*(.text*)
    } > FLASH = 0xFF
    .rodata : ALIGN(4){
	    *(.rodata .rodata.*);
	    . = ALIGN(4);
    } > FLASH
    /DISCARD/ : {
	    *(.ARM.*)
    }
}

This script is also available with comments in the repository as layout.ld.

Target

In order to compile your code for the teensy you need to specify the architecture you are targetting. Create a .cargo/config file like that:

[build]
target = "thumbv7em-none-eabi"

[target.thumbv7em-none-eabi]
rustflags = [
	"-C", "link-arg=-Tlayout.ld",
]

Code with this crate

Here is a minimal example of valid code:

#![no_std]
#![no_main]

// needed because we have no std to handle the panic
teensy::define_panic!{empty}

#[no_mangle]
fn main() {
    loop {}
}

Flashing the Teensy

We provide a Makefile to generate a binary for the teensy 3.2 and sending it using the teensy_loader_cli command:

BIN=my_application
OUTDIR=target/thumbv7em-none-eabi/release
HEX=$(OUTDIR)/$(BIN).hex
ELF=$(OUTDIR)/$(BIN)

all:: $(ELF)

.PHONY: $(ELF)
$(ELF):
	cargo build --release

$(HEX): $(ELF)
	arm-none-eabi-objcopy -O ihex $(ELF) $(HEX)

.PHONY: flash
flash: $(HEX)
	teensy_loader_cli -w -mmcu=mk20dx256 $(HEX) -v

Complete example

You can find a complete example of the setup blinking a led here

Advanced usage

Choosing yourself which components are used

If you use the crate without specifying anything, as seen in the quickstart guide, every components will be enbled and the teensy will run at max clock speed. This crate provide a feature manual_init to provide your own initialization function. You can see the examples/blink_manual_init.rs file to see how to use the feature in your code. You’ll also need to import the crate with the feature enabled:

[dependencies.teensy]
git = "https://github.com/irevoire/teensy.git"
default-features = false
features = ["manual_init"]

Here is an example of repository showing the usage of this feature.

Modules

boot

This module provide all the needed functions to boot the teensy. Here is the most important file of this crate. When you add this crate as a dependency it will move the bootloader to the good section. Enable all the port, the clock at 72MHz and disable the watchdog and then call your main. Right now if you don't want something you'll need to either disable it in your main or edit this crate.

interrupts
mcg

The Multipurpose Clock Generator.

osc

The Oscillator Unit.

panic

Helper module to define easily panic function.

port

The port, pins and gpio. There are two ways to access the GPIO registers. The first is through a block of 32-bit registers, associated with a port. It looks something like this:

sim

The System Integration Module.

sleep

Implementation of the sleep function

uart
watchdog

The watchdog is a piece of hardware which will reset the microcontroller unless the running application “checks in” in a certain interval.

Macros

blink_panic

A panic blinking a led

define_panic

Helper macro to call the other panic macro Use it like that:

empty_panic

A panic doing nothing

make_pin

This macro is an helper to create pin easily. You can create your pins by the name they have on the little flyer you got when you bought your teensy. You can create your pin with name like:

uart_panic

A panic sending your message on the uart serial port 1 in a loop