From 8d75aca53d3c19fc1521248ae3307d9b4802aaf2 Mon Sep 17 00:00:00 2001 From: Brad Campbell Date: Thu, 29 Nov 2018 12:31:55 -0500 Subject: [PATCH] add imix bootloader --- .travis.yml | 1 + boards/imix-bootloader/Cargo.lock | 107 +++++++++++++++++ boards/imix-bootloader/Cargo.toml | 25 ++++ boards/imix-bootloader/Makefile | 14 +++ boards/imix-bootloader/README.md | 4 + boards/imix-bootloader/build.rs | 14 +++ boards/imix-bootloader/layout.ld | 8 ++ boards/imix-bootloader/src/main.rs | 182 +++++++++++++++++++++++++++++ 8 files changed, 355 insertions(+) create mode 100644 boards/imix-bootloader/Cargo.lock create mode 100644 boards/imix-bootloader/Cargo.toml create mode 100644 boards/imix-bootloader/Makefile create mode 100644 boards/imix-bootloader/README.md create mode 100644 boards/imix-bootloader/build.rs create mode 100644 boards/imix-bootloader/layout.ld create mode 100644 boards/imix-bootloader/src/main.rs diff --git a/.travis.yml b/.travis.yml index f7c6859..9234784 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,4 +17,5 @@ script: - tools/run_cargo_fmt.sh diff - make -C boards/hail-bootloader - make -C boards/nrf52-bootloader + - make -C boards/imix-bootloader diff --git a/boards/imix-bootloader/Cargo.lock b/boards/imix-bootloader/Cargo.lock new file mode 100644 index 0000000..479390c --- /dev/null +++ b/boards/imix-bootloader/Cargo.lock @@ -0,0 +1,107 @@ +[[package]] +name = "bootloader" +version = "0.1.0" +dependencies = [ + "kernel 0.1.0 (git+https://github.com/tock/tock)", + "tockloader-proto 0.2.1 (git+https://github.com/tock/tockloader-proto-rs)", +] + +[[package]] +name = "bootloader_attributes" +version = "0.1.0" + +[[package]] +name = "byteorder" +version = "1.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "capsules" +version = "0.1.0" +source = "git+https://github.com/tock/tock#7f31ad53384ce16c922364715d94aff5767ef0c6" +dependencies = [ + "enum_primitive 0.1.0 (git+https://github.com/tock/tock)", + "kernel 0.1.0 (git+https://github.com/tock/tock)", +] + +[[package]] +name = "cortexm" +version = "0.1.0" +source = "git+https://github.com/tock/tock#7f31ad53384ce16c922364715d94aff5767ef0c6" +dependencies = [ + "kernel 0.1.0 (git+https://github.com/tock/tock)", +] + +[[package]] +name = "cortexm4" +version = "0.1.0" +source = "git+https://github.com/tock/tock#7f31ad53384ce16c922364715d94aff5767ef0c6" +dependencies = [ + "cortexm 0.1.0 (git+https://github.com/tock/tock)", + "kernel 0.1.0 (git+https://github.com/tock/tock)", +] + +[[package]] +name = "enum_primitive" +version = "0.1.0" +source = "git+https://github.com/tock/tock#7f31ad53384ce16c922364715d94aff5767ef0c6" + +[[package]] +name = "imixbootloader" +version = "0.1.0" +dependencies = [ + "bootloader 0.1.0", + "bootloader_attributes 0.1.0", + "capsules 0.1.0 (git+https://github.com/tock/tock)", + "cortexm4 0.1.0 (git+https://github.com/tock/tock)", + "kernel 0.1.0 (git+https://github.com/tock/tock)", + "sam4l 0.1.0 (git+https://github.com/tock/tock)", +] + +[[package]] +name = "kernel" +version = "0.1.0" +source = "git+https://github.com/tock/tock#7f31ad53384ce16c922364715d94aff5767ef0c6" +dependencies = [ + "tock-cells 0.1.0 (git+https://github.com/tock/tock)", + "tock-registers 0.2.0 (git+https://github.com/tock/tock)", +] + +[[package]] +name = "sam4l" +version = "0.1.0" +source = "git+https://github.com/tock/tock#7f31ad53384ce16c922364715d94aff5767ef0c6" +dependencies = [ + "cortexm4 0.1.0 (git+https://github.com/tock/tock)", + "kernel 0.1.0 (git+https://github.com/tock/tock)", +] + +[[package]] +name = "tock-cells" +version = "0.1.0" +source = "git+https://github.com/tock/tock#7f31ad53384ce16c922364715d94aff5767ef0c6" + +[[package]] +name = "tock-registers" +version = "0.2.0" +source = "git+https://github.com/tock/tock#7f31ad53384ce16c922364715d94aff5767ef0c6" + +[[package]] +name = "tockloader-proto" +version = "0.2.1" +source = "git+https://github.com/tock/tockloader-proto-rs#945aedf6efb77221bc014ed590c56ff934ccdcac" +dependencies = [ + "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[metadata] +"checksum byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "94f88df23a25417badc922ab0f5716cc1330e87f71ddd9203b3a3ccd9cedf75d" +"checksum capsules 0.1.0 (git+https://github.com/tock/tock)" = "" +"checksum cortexm 0.1.0 (git+https://github.com/tock/tock)" = "" +"checksum cortexm4 0.1.0 (git+https://github.com/tock/tock)" = "" +"checksum enum_primitive 0.1.0 (git+https://github.com/tock/tock)" = "" +"checksum kernel 0.1.0 (git+https://github.com/tock/tock)" = "" +"checksum sam4l 0.1.0 (git+https://github.com/tock/tock)" = "" +"checksum tock-cells 0.1.0 (git+https://github.com/tock/tock)" = "" +"checksum tock-registers 0.2.0 (git+https://github.com/tock/tock)" = "" +"checksum tockloader-proto 0.2.1 (git+https://github.com/tock/tockloader-proto-rs)" = "" diff --git a/boards/imix-bootloader/Cargo.toml b/boards/imix-bootloader/Cargo.toml new file mode 100644 index 0000000..1aab4e0 --- /dev/null +++ b/boards/imix-bootloader/Cargo.toml @@ -0,0 +1,25 @@ +[package] +name = "imixbootloader" +version = "0.1.0" +authors = ["Tock Project Developers "] +build = "build.rs" + +[profile.dev] +panic = "abort" +lto = true +opt-level = 0 +debug = true + +[profile.release] +panic = "abort" +lto = true + +[dependencies] +cortexm4 = { git = "https://github.com/tock/tock" } +capsules = { git = "https://github.com/tock/tock" } +kernel = { git = "https://github.com/tock/tock" } +sam4l = { git = "https://github.com/tock/tock" } +bootloader = { path = "../../bootloader" } + +[build-dependencies] +bootloader_attributes = { path = "../../tools/bootloader_attributes" } diff --git a/boards/imix-bootloader/Makefile b/boards/imix-bootloader/Makefile new file mode 100644 index 0000000..870cc04 --- /dev/null +++ b/boards/imix-bootloader/Makefile @@ -0,0 +1,14 @@ +# Makefile for building the bootloader for Imix + +TARGET=thumbv7em-none-eabi +PLATFORM=imixbootloader + +include ../Common.mk + +TOCKLOADER = tockloader +TOCKLOADER_JTAG_FLAGS = --jtag --board imix --arch cortex-m4 --jtag-device ATSAM4LC8C + +# upload kernel over JTAG +.PHONY: flash +flash: target/$(TARGET)/release/$(PLATFORM).bin + $(TOCKLOADER) flash --address 0x0 $(TOCKLOADER_JTAG_FLAGS) $< diff --git a/boards/imix-bootloader/README.md b/boards/imix-bootloader/README.md new file mode 100644 index 0000000..fc7b66c --- /dev/null +++ b/boards/imix-bootloader/README.md @@ -0,0 +1,4 @@ +The Imix Bootloader +=================== + +Bootloader for Imix written on top of Tock. diff --git a/boards/imix-bootloader/build.rs b/boards/imix-bootloader/build.rs new file mode 100644 index 0000000..aa6b087 --- /dev/null +++ b/boards/imix-bootloader/build.rs @@ -0,0 +1,14 @@ +extern crate bootloader_attributes; + +fn main() { + println!("cargo:rerun-if-changed=layout.ld"); + println!("cargo:rerun-if-changed=chip_layout.ld"); + println!("cargo:rerun-if-changed=../kernel_layout.ld"); + + let mut f = bootloader_attributes::get_file(); + bootloader_attributes::write_flags(&mut f, 512, "1.0.1"); + bootloader_attributes::write_attribute(&mut f, "board", "imix"); + bootloader_attributes::write_attribute(&mut f, "arch", "cortex-m4"); + bootloader_attributes::write_attribute(&mut f, "jldevice", "ATSAM4LC8C"); + bootloader_attributes::write_attribute(&mut f, "appaddr", "0x40000"); +} diff --git a/boards/imix-bootloader/layout.ld b/boards/imix-bootloader/layout.ld new file mode 100644 index 0000000..3e2a44b --- /dev/null +++ b/boards/imix-bootloader/layout.ld @@ -0,0 +1,8 @@ +/* Memory Spaces Definitions, 448K flash, 64K ram */ +MEMORY +{ + rom (rx) : ORIGIN = 0x00000000, LENGTH = 0x00010000 + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00020000 +} + +INCLUDE ../kernel_layout.ld \ No newline at end of file diff --git a/boards/imix-bootloader/src/main.rs b/boards/imix-bootloader/src/main.rs new file mode 100644 index 0000000..a16a874 --- /dev/null +++ b/boards/imix-bootloader/src/main.rs @@ -0,0 +1,182 @@ +//! Board file for Imix bootloader. + +#![no_std] +#![no_main] +#![feature(asm, const_fn, lang_items, panic_implementation)] + +extern crate bootloader; +extern crate cortexm4; +#[macro_use(create_capability, static_init)] +extern crate kernel; +extern crate capsules; +extern crate sam4l; + +use core::panic::PanicInfo; + +use kernel::capabilities; +use kernel::hil; +use kernel::hil::Controller; +use kernel::Platform; + +include!(concat!(env!("OUT_DIR"), "/attributes.rs")); + +// No processes are supported. +static mut PROCESSES: [Option<&'static kernel::procs::ProcessType>; 0] = []; + +/// Dummy buffer that causes the linker to reserve enough space for the stack. +#[no_mangle] +#[link_section = ".stack_buffer"] +pub static mut STACK_MEMORY: [u8; 0x2000] = [0; 0x2000]; + +struct ImixBootloader { + bootloader: &'static bootloader::bootloader::Bootloader< + 'static, + sam4l::usart::USART, + sam4l::flashcalw::FLASHCALW, + sam4l::gpio::GPIOPin, + >, +} + +impl Platform for ImixBootloader { + fn with_driver(&self, driver_num: usize, f: F) -> R + where + F: FnOnce(Option<&kernel::Driver>) -> R, + { + // Bootloader does not support apps. + match driver_num { + _ => f(None), + } + } +} + +unsafe fn set_pin_primary_functions() { + use sam4l::gpio::PeripheralFunction::{A, B, C, E}; + use sam4l::gpio::{PA, PB, PC}; + + // Right column: Imix pin name + // Left column: SAM4L peripheral function + PA[04].configure(Some(A)); // AD0 -- ADCIFE AD0 + PA[05].configure(Some(A)); // AD1 -- ADCIFE AD1 + PA[06].configure(Some(C)); // EXTINT1 -- EIC EXTINT1 + PA[07].configure(Some(A)); // AD1 -- ADCIFE AD2 + PA[08].configure(None); //... RF233 IRQ -- GPIO pin + PA[09].configure(None); //... RF233 RST -- GPIO pin + PA[10].configure(None); //... RF233 SLP -- GPIO pin + PA[13].configure(None); //... TRNG EN -- GPIO pin + PA[14].configure(None); //... TRNG_OUT -- GPIO pin + PA[17].configure(None); //... NRF INT -- GPIO pin + PA[18].configure(Some(A)); // NRF CLK -- USART2_CLK + PA[20].configure(None); //... D8 -- GPIO pin + PA[21].configure(Some(E)); // TWI2 SDA -- TWIM2_SDA + PA[22].configure(Some(E)); // TWI2 SCL -- TWIM2 TWCK + PA[25].configure(Some(A)); // USB_N -- USB DM + PA[26].configure(Some(A)); // USB_P -- USB DP + PB[00].configure(Some(A)); // TWI1_SDA -- TWIMS1 TWD + PB[01].configure(Some(A)); // TWI1_SCL -- TWIMS1 TWCK + PB[02].configure(Some(A)); // AD3 -- ADCIFE AD3 + PB[03].configure(Some(A)); // AD4 -- ADCIFE AD4 + PB[04].configure(Some(A)); // AD5 -- ADCIFE AD5 + PB[05].configure(Some(A)); // VHIGHSAMPLE -- ADCIFE AD6 + PB[06].configure(None); //... RTS3 -- USART3 RTS !! FTDI DTR BOOTLOADER SELECT + PB[07].configure(None); //... NRF RESET -- GPIO + PB[09].configure(Some(A)); // RX3 -- USART3 RX + PB[10].configure(Some(A)); // TX3 -- USART3 TX + PB[11].configure(Some(A)); // CTS0 -- USART0 CTS + PB[12].configure(Some(A)); // RTS0 -- USART0 RTS + PB[13].configure(Some(A)); // CLK0 -- USART0 CLK + PB[14].configure(Some(A)); // RX0 -- USART0 RX + PB[15].configure(Some(A)); // TX0 -- USART0 TX + PC[00].configure(Some(A)); // CS2 -- SPI NPCS2 + PC[01].configure(Some(A)); // CS3 (RF233) -- SPI NPCS3 + PC[02].configure(Some(A)); // CS1 -- SPI NPCS1 + PC[03].configure(Some(A)); // CS0 -- SPI NPCS0 + PC[04].configure(Some(A)); // MISO -- SPI MISO + PC[05].configure(Some(A)); // MOSI -- SPI MOSI + PC[06].configure(Some(A)); // SCK -- SPI CLK + PC[07].configure(Some(B)); // RTS2 (BLE) -- USART2_RTS + PC[08].configure(Some(E)); // CTS2 (BLE) -- USART2_CTS + //PC[09].configure(None); //... NRF GPIO -- GPIO + //PC[10].configure(None); //... USER LED -- GPIO + PC[09].configure(Some(E)); // ACAN1 -- ACIFC comparator + PC[10].configure(Some(E)); // ACAP1 -- ACIFC comparator + PC[11].configure(Some(B)); // RX2 (BLE) -- USART2_RX + PC[12].configure(Some(B)); // TX2 (BLE) -- USART2_TX + //PC[13].configure(None); //... ACC_INT1 -- GPIO + //PC[14].configure(None); //... ACC_INT2 -- GPIO + PC[13].configure(Some(E)); //... ACBN1 -- ACIFC comparator + PC[14].configure(Some(E)); //... ACBP1 -- ACIFC comparator + PC[16].configure(None); //... SENSE_PWR -- GPIO pin + PC[17].configure(None); //... NRF_PWR -- GPIO pin + PC[18].configure(None); //... RF233_PWR -- GPIO pin + PC[19].configure(None); //... TRNG_PWR -- GPIO Pin + PC[22].configure(None); //... KERNEL LED -- GPIO Pin + PC[24].configure(None); //... USER_BTN -- GPIO Pin + PC[25].configure(Some(B)); // LI_INT -- EIC EXTINT2 + PC[26].configure(None); //... D7 -- GPIO Pin + PC[27].configure(None); //... D6 -- GPIO Pin + PC[28].configure(None); //... D5 -- GPIO Pin + PC[29].configure(None); //... D4 -- GPIO Pin + PC[30].configure(None); //... D3 -- GPIO Pin + PC[31].configure(None); //... D2 -- GPIO Pin +} + +#[no_mangle] +pub unsafe fn reset_handler() { + sam4l::init(); + + sam4l::pm::PM.setup_system_clock(sam4l::pm::SystemClockSource::PllExternalOscillatorAt48MHz { + frequency: sam4l::pm::OscillatorFrequency::Frequency16MHz, + startup_mode: sam4l::pm::OscillatorStartup::FastStart, + }); + + // Source 32Khz and 1Khz clocks from RC23K (SAM4L Datasheet 11.6.8) + sam4l::bpm::set_ck32source(sam4l::bpm::CK32Source::RC32K); + + set_pin_primary_functions(); + + // Create main kernel object. This contains the main loop function. + let board_kernel = static_init!(kernel::Kernel, kernel::Kernel::new(&PROCESSES)); + + // Initialize USART3 for Uart + sam4l::usart::USART3.set_mode(sam4l::usart::UsartMode::Uart); + + pub static mut PAGEBUFFER: sam4l::flashcalw::Sam4lPage = sam4l::flashcalw::Sam4lPage::new(); + + sam4l::flashcalw::FLASH_CONTROLLER.configure(); + let bootloader = static_init!( + bootloader::bootloader::Bootloader< + 'static, + sam4l::usart::USART, + sam4l::flashcalw::FLASHCALW, + sam4l::gpio::GPIOPin, + >, + bootloader::bootloader::Bootloader::new( + &sam4l::usart::USART3, + &mut sam4l::flashcalw::FLASH_CONTROLLER, + &sam4l::gpio::PB[06], + &mut PAGEBUFFER, + &mut bootloader::bootloader::BUF + ) + ); + hil::uart::UART::set_client(&sam4l::usart::USART3, bootloader); + hil::flash::HasClient::set_client(&sam4l::flashcalw::FLASH_CONTROLLER, bootloader); + + let imix = ImixBootloader { + bootloader: bootloader, + }; + + let chip = static_init!(sam4l::chip::Sam4l, sam4l::chip::Sam4l::new()); + + imix.bootloader.initialize(); + + let main_loop_capability = create_capability!(capabilities::MainLoopCapability); + board_kernel.kernel_loop(&imix, chip, None, &main_loop_capability); +} + +/// Panic handler. +#[cfg(not(test))] +#[no_mangle] +#[panic_implementation] +pub unsafe extern "C" fn panic_fmt(_pi: &PanicInfo) -> ! { + loop {} +}