Skip to content

Commit

Permalink
Merge #73
Browse files Browse the repository at this point in the history
73: Prototype Teensy 4.1 support r=mciantyre a=mciantyre

The PR demonstrates how we could support both Teensy 4.0 and 4.1 boards from a single BSP. This has breaking changes. See #69 for details.

This work is based on the `iomuxc-integration` branch. To keep the diff relevant, this PR target that branch.

Co-authored-by: Ian McIntyre <[email protected]>
  • Loading branch information
bors[bot] and mciantyre authored Aug 29, 2020
2 parents a414c3c + d7427ed commit a0a9169
Show file tree
Hide file tree
Showing 28 changed files with 1,031 additions and 506 deletions.
3 changes: 2 additions & 1 deletion .github/bors.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ status = [
"doc",
"format",
"precompiled",
"template"
"template",
"test"
]
delete_merged_branches = true
13 changes: 11 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@ jobs:
command: fmt
args: --verbose --all -- --check

# Since we don't have any automated tests right now, we can use a clippy
# run to check the build and surface linting errors.
clippy:
runs-on: ubuntu-latest
steps:
Expand All @@ -45,3 +43,14 @@ jobs:
run: INSTALL_DEPS=0 make libt4boot
- name: Build USB stack
run: INSTALL_DEPS=0 make libt4usb

test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions-rs/toolchain@v1
with:
toolchain: nightly
override: true
- name: Run unit and documentation tests
run: INSTALL_DEPS=0 make test
24 changes: 14 additions & 10 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,12 @@ Part of the teensy4-rs project.
[dependencies]
cortex-m = "0.6.2"
cortex-m-rt = "0.6.12" # Note: not the 'real' cortex-m-rt

[target.thumbv7em-none-eabihf.dependencies]
teensy4-fcb = { path = "teensy4-fcb" }

[dependencies.imxrt-hal]
version = "0.3.0"
version = "0.4.0"
features = ["imxrt1062", "rt"]

# Tied to "systick" feature, since
Expand All @@ -35,27 +37,32 @@ optional = true
path = "teensy4-usb-sys"
optional = true

[dev-dependencies]
[target.thumbv7em-none-eabihf.dev-dependencies]
cortex-m-rtic = "0.5.3"
embedded-hal = "0.2.4"
heapless = "0.5.5"
imxrt-uart-log = "0.2.0"
log = "0.4.8"
imxrt-uart-log = "0.1.0"
nb = "0.1.2"

[dev-dependencies]
panic-halt = "0.2.0"

[[example]]
name = "rtic_led"
path = "examples/rtic_led.rs"
required-features = ["rtic"]

[[example]]
name = "rtic_blink"
path = "examples/rtic_blink.rs"
required-features = ["rtic"]

[[example]]
name = "rtic_uart_log"
path = "examples/rtic_uart_log.rs"
required-features = ["rtic"]

[[example]]
name = "rtic_dma_uart_log"
path = "examples/rtic_dma_uart_log.rs"
Expand Down Expand Up @@ -89,7 +96,7 @@ systick = ["embedded-hal"]
# NOTE: When using this feature along with the `rtic` crate the
# default features must first be disabled in order to avoid a
# duplicate definition of `SysTick`.
rtic = []
rtic = ["imxrt-hal/rtic"]

# Don't optimize build dependencies, like proc macros.
# Helps with build times.
Expand All @@ -101,9 +108,6 @@ opt-level = 0
[patch.crates-io.cortex-m-rt]
path = "cortex-m-rt-patch"

# Patch `imxrt-hal` so that we may access the `hal::Peripherals::steal`
# constructor. This patch should be removed once a new version of
# `imxrt-hal` is published with the new constructor.
[patch.crates-io.imxrt-hal]
git = "https://github.com/imxrt-rs/imxrt-rs"
rev = "0305aed"
[package.metadata.docs.rs]
all-features = true
rustdoc-args = ["--cfg", "docsrs"]
39 changes: 21 additions & 18 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ CARGO ?= cargo
TEENSY_LOADER ?= teensy_loader_cli
MODE ?= --release
INSTALL_DEPS ?= 1
HOST ?= $(shell rustc --version --verbose | grep host | cut -d ' ' -f 2)

ifneq ($(INSTALL_DEPS),0)
# Ensure the thumbv7em-none-eabihf component is installed
Expand Down Expand Up @@ -34,31 +35,28 @@ endif
endif # INSTALL_DEPS != 0

TARGET_EXAMPLES := target/thumbv7em-none-eabihf/release/examples
EXAMPLES := $(shell ls examples | xargs basename | cut -f 1 -d .)
EXAMPLES := $(shell ls examples | grep -v rtic | xargs basename | cut -f 1 -d .)
RTIC_EXAMPLES := $(shell ls examples | grep rtic | xargs basename | cut -f 1 -d .)

.PHONY: all
all:
@cargo build $(MODE) --examples
@for example in $(EXAMPLES);\
do cargo objcopy $(MODE) --example $$example \
-- -O ihex $(TARGET_EXAMPLES)/$$example.hex;\
done
@for example in $(RTIC_EXAMPLES);\
do cargo objcopy $(MODE) --example $$example \
--no-default-features --features=rtic \
-- -O ihex $(TARGET_EXAMPLES)/$$example.hex;\
done

.PHONY: example_%
example_%:
@cargo build \
$(MODE) --example $(subst example_,,$@)

.PHONY: objcopy_%
objcopy_%: example_%
@cargo objcopy \
$(MODE) --example $(subst objcopy_,,$@) \
-- -O ihex \
$(TARGET_EXAMPLES)/$(subst objcopy_,,$@).hex

.PHONY: download_%
download_%: objcopy_%
@$(LOADER) $(TARGET_EXAMPLES)/$(subst download_,,$@).hex
# Build all RTIC-related examples
.PHONY: rtic
rtic:
@for example in $(RTIC_EXAMPLES);\
do cargo build $(MODE) --example $$example \
--no-default-features --features=rtic;\
done

libt4boot:
@make -C teensy4-rt/bin
Expand All @@ -68,4 +66,9 @@ libt4usb:

.PHONY: clean
clean:
@cargo clean
@cargo clean

.PHONY: test
test:
@cargo +nightly test --lib --tests --target $(HOST)
@cargo +nightly test --doc --target $(HOST)
7 changes: 4 additions & 3 deletions examples/dma_memcpy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,9 @@ const NUMBER_OF_ELEMENTS: Element = (BUFFER_SIZE - 7) as Element;
#[entry]
fn main() -> ! {
let mut peripherals = bsp::Peripherals::take().unwrap();
peripherals.usb.init(Default::default());
peripherals.systick.delay(5_000);
let mut systick = bsp::SysTick::new(cortex_m::Peripherals::take().unwrap().SYST);
bsp::usb::init(&systick, Default::default()).unwrap();
systick.delay(5_000);

let mut dma_channels = peripherals.dma.clock(&mut peripherals.ccm.handle);
let channel = dma_channels[13].take().unwrap();
Expand Down Expand Up @@ -141,6 +142,6 @@ fn main() -> ! {
tx_buffer.clear();

start += 1;
peripherals.systick.delay(5_000);
systick.delay(5_000);
}
}
39 changes: 15 additions & 24 deletions examples/dma_spi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ static TX_BUFFER: Mutex<RefCell<Option<TxBuffer>>> = Mutex::new(RefCell::new(Non
static RX_BUFFER: Mutex<RefCell<Option<RxBuffer>>> = Mutex::new(RefCell::new(None));

type SpiDma =
dma::Peripheral<bsp::hal::spi::SPI<bsp::hal::spi::module::_4>, u16, TxBuffer, RxBuffer>;
dma::Peripheral<bsp::hal::spi::SPI<bsp::hal::iomuxc::consts::U4>, u16, TxBuffer, RxBuffer>;

// TODO types should be Send
static mut SPI_DMA: Option<SpiDma> = None;
Expand Down Expand Up @@ -158,13 +158,15 @@ fn rx_buffer_mut<F: FnOnce(&mut RxBuffer) -> R, R>(act: F) -> Option<R> {
}

// Pin 20
type HardwareFlag = bsp::hal::gpio::GPIO1IO26<bsp::hal::gpio::GPIO1, bsp::hal::gpio::Output>;
type HardwareFlag = bsp::hal::gpio::GPIO<bsp::hal::iomuxc::ad_b1::AD_B1_10, bsp::hal::gpio::Output>;
static mut HARDWARE_FLAG: Option<HardwareFlag> = None;

#[entry]
fn main() -> ! {
let mut peripherals = bsp::Peripherals::take().unwrap();
peripherals.usb.init(Default::default());
let mut systick = bsp::SysTick::new(cortex_m::Peripherals::take().unwrap().SYST);
bsp::usb::init(&systick, Default::default()).unwrap();
let pins = bsp::t40::pins(peripherals.iomuxc);

peripherals.ccm.pll1.set_arm_clock(
bsp::hal::ccm::PLL1::ARM_HZ,
Expand All @@ -173,16 +175,15 @@ fn main() -> ! {
);

unsafe {
let p20 = peripherals.pins.p20;
use bsp::hal::gpio::IntoGpio;
HARDWARE_FLAG = Some(p20.alt5().into_gpio().output());
let p20 = pins.p20;
HARDWARE_FLAG = Some(bsp::hal::gpio::GPIO::new(p20).output());
}

//
// SPI setup
//

peripherals.systick.delay(5000);
systick.delay(5000);
log::info!("Initializing SPI4 clocks...");

let (_, _, _, spi4_builder) = peripherals.spi.clock(
Expand All @@ -192,12 +193,8 @@ fn main() -> ! {
);

log::info!("Constructing SPI4 peripheral...");
let mut spi4 = spi4_builder.build(
peripherals.pins.p11.alt3(),
peripherals.pins.p12.alt3(),
peripherals.pins.p13.alt3(),
);
spi4.enable_chip_select_0(peripherals.pins.p10.alt3());
let mut spi4 = spi4_builder.build(pins.p11, pins.p12, pins.p13);
spi4.enable_chip_select_0(pins.p10);

match spi4.set_clock_speed(bsp::hal::spi::ClockSpeed(SPI_BAUD_RATE_HZ)) {
Ok(()) => {
Expand All @@ -221,20 +218,14 @@ fn main() -> ! {

let mut dma_channels = peripherals.dma.clock(&mut peripherals.ccm.handle);
let tx_channel = dma_channels[9].take().unwrap();
let rx_channel = dma_channels[25].take().unwrap();
let rx_config = dma::ConfigBuilder::new()
.interrupt_on_completion(true)
.build();
let mut rx_channel = dma_channels[25].take().unwrap();
rx_channel.set_interrupt_on_completion(true);

// We only want to interrupt when the receive completes. When
// the receive completes, we know that we're also done transferring
// data.
let spi = unsafe {
SPI_DMA = Some(dma::bidirectional_u16(
spi4,
(tx_channel, dma::ConfigBuilder::new().build()),
(rx_channel, rx_config),
));
SPI_DMA = Some(dma::bidirectional_u16(spi4, tx_channel, rx_channel));
cortex_m::peripheral::NVIC::unmask(interrupt::DMA9_DMA25);
SPI_DMA.as_mut().unwrap()
};
Expand Down Expand Up @@ -270,7 +261,7 @@ fn main() -> ! {
core::sync::atomic::spin_loop_hint();
}
}
peripherals.systick.delay(500);
systick.delay(500);

log::info!("Started DMA transfers for WHO_AM_I");
FLAG.store(false, Ordering::Release);
Expand Down Expand Up @@ -322,7 +313,7 @@ fn main() -> ! {
}
}

peripherals.systick.delay(500);
systick.delay(500);
FLAG.store(false, Ordering::Release);
prepare_transfer(spi);
loop {
Expand Down
37 changes: 14 additions & 23 deletions examples/dma_uart.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ use bsp::interrupt;
use bsp::rt::entry;
use teensy4_bsp as bsp;

use embedded_hal::digital::v2::ToggleableOutputPin;

use core::{
cell::RefCell,
sync::atomic::{AtomicBool, Ordering},
Expand All @@ -42,7 +40,7 @@ static TX_BUFFER: Mutex<RefCell<Option<TxBuffer>>> = Mutex::new(RefCell::new(Non
static RX_BUFFER: Mutex<RefCell<Option<RxBuffer>>> = Mutex::new(RefCell::new(None));

type DmaUart = bsp::hal::dma::Peripheral<
bsp::hal::uart::UART<bsp::hal::uart::module::_2>,
bsp::hal::uart::UART<bsp::hal::iomuxc::consts::U2>,
u8,
TxBuffer,
RxBuffer,
Expand Down Expand Up @@ -81,40 +79,33 @@ unsafe fn DMA7_DMA23() {
#[entry]
fn main() -> ! {
let mut peripherals = bsp::Peripherals::take().unwrap();
peripherals.usb.init(Default::default());
peripherals.systick.delay(5_000);
let mut systick = bsp::SysTick::new(cortex_m::Peripherals::take().unwrap().SYST);
bsp::usb::init(&systick, Default::default()).unwrap();
let pins = bsp::t40::pins(peripherals.iomuxc);

systick.delay(5_000);
let uarts = peripherals.uart.clock(
&mut peripherals.ccm.handle,
bsp::hal::ccm::uart::ClockSelect::OSC,
bsp::hal::ccm::uart::PrescalarSelect::DIVIDE_1,
);
let uart = uarts
.uart2
.init(
peripherals.pins.p14.alt2(),
peripherals.pins.p15.alt2(),
BAUD,
)
.unwrap();
let uart = uarts.uart2.init(pins.p14, pins.p15, BAUD).unwrap();

let mut dma_channels = peripherals.dma.clock(&mut peripherals.ccm.handle);
let tx_channel = dma_channels[7].take().unwrap();
let rx_channel = dma_channels[23].take().unwrap();
let mut tx_channel = dma_channels[7].take().unwrap();
let mut rx_channel = dma_channels[23].take().unwrap();

let config = bsp::hal::dma::ConfigBuilder::new()
.interrupt_on_completion(true)
.build();
tx_channel.set_interrupt_on_completion(true);
rx_channel.set_interrupt_on_completion(true);

let dma_uart = unsafe {
DMA_PERIPHERAL = Some(bsp::hal::dma::Peripheral::new_bidirectional(
uart,
(tx_channel, config),
(rx_channel, config),
uart, tx_channel, rx_channel,
));
cortex_m::peripheral::NVIC::unmask(interrupt::DMA7_DMA23);
DMA_PERIPHERAL.as_mut().unwrap()
};
let mut led = bsp::configure_led(&mut peripherals.gpr, peripherals.pins.p13);
let mut led = bsp::configure_led(pins.p13);

let rx_buffer = match bsp::hal::dma::Circular::new(&RX_MEM.0) {
Ok(circular) => circular,
Expand Down Expand Up @@ -156,7 +147,7 @@ fn main() -> ! {
loop {
cortex_m::asm::wfi();
if RX_READY.load(Ordering::Acquire) {
led.toggle().unwrap();
led.toggle();
RX_READY.store(false, Ordering::Release);
let mut rx_buffer = free(|cs| RX_BUFFER.borrow(cs).borrow_mut().take()).unwrap();
let value = match rx_buffer.pop() {
Expand Down
Loading

0 comments on commit a0a9169

Please sign in to comment.