X-Git-Url: http://git.code-monkey.de/?a=blobdiff_plain;f=src%2Fbootloader%2Fmain.rs;h=2ce598050464a12deedb8c32c94153ca319f653e;hb=727108edeb96e0b534c86d52ad3f7515b26c1798;hp=16255f601b4a0c2ab8874fe19d434174a3312a59;hpb=2cd9f6b175d16cb0a5c8bb7f3e387fecd27a7199;p=gps-watch.git diff --git a/src/bootloader/main.rs b/src/bootloader/main.rs index 16255f6..2ce5980 100644 --- a/src/bootloader/main.rs +++ b/src/bootloader/main.rs @@ -22,24 +22,102 @@ */ #![no_std] -#![crate_type="staticlib"] +#![no_main] #[link(name="libcommon.rlib")] extern crate common; mod flash; +mod bootloader; +use common::register; use common::clock; +use common::systick; +use common::port; +use common::gpio; +use common::watchdog; use common::usb_serial; +type Reg32 = register::Register; + +extern { + fn enable_interrupts(); + fn disable_interrupts(); + + fn jump_to_application(address: u32) -> !; +} + +#[cfg(bootloader_type = "intermediate")] +const APPLICATION_ADDR: u32 = 0x0; + +#[cfg(bootloader_type = "final")] +const APPLICATION_ADDR: u32 = 0x8000; + +#[cfg(bootloader_type = "intermediate")] +const USB_PID: u16 = 0x635b; + +#[cfg(bootloader_type = "final")] +const USB_PID: u16 = 0x635c; + +unsafe fn application_missing() -> bool { + let first_app_word = Reg32::new(APPLICATION_ADDR); + + first_app_word.read() == 0xffffffff +} + +#[cfg(bootloader_type = "intermediate")] +fn bootloader_requested() -> bool { + true +} + +#[cfg(bootloader_type = "final")] +fn bootloader_requested() -> bool { + let start_ticks = systick::now(); + + while !systick::has_timeout_ms(start_ticks, 3000) { + if (gpio::get(gpio::GPIOE) & (1 << 24)) == 0 { + return true; + } + } + + false +} + +#[inline(never)] +#[panic_handler] +fn panic(_info: &core::panic::PanicInfo) -> ! { + loop { + } +} + #[no_mangle] -pub unsafe extern fn main() { +pub unsafe extern "C" fn _start() -> ! { + watchdog::disable(); clock::configure(); + systick::init(); + port::init(); - if true { - usb_serial::init(); + // Configure lower left push button. + gpio::set_direction(gpio::GPIOE, 1 << 24, gpio::Direction::Input); + port::set_af(port::PORTE, 24, 1); + port::set_pull(port::PORTE, 24, port::Pull::Up); - loop { + enable_interrupts(); + + if application_missing() || bootloader_requested() { + usb_serial::init(0xf055, USB_PID); + + let mut b = bootloader::Bootloader::new(); + + while b.run() || application_missing() { } + + usb_serial::shutdown(); } + + disable_interrupts(); + + clock::reset(); + + jump_to_application(APPLICATION_ADDR); }