Skip to content
Snippets Groups Projects
Select Git revision
  • 134b920c133094d65ffdca9cec3f5ce907f665bd
  • master default protected
  • home_exam
3 results

crust.rs

Blame
  • Forked from Per Lindgren / D7050E
    Source project has a limited visibility.
    bare4.rs 1.98 KiB
    //! bare4.rs
    //! Simple bare metal application
    //!
    #![feature(used)]
    #![no_std]
    
    extern crate cortex_m;
    extern crate cortex_m_rt;
    
    // Peripheral addresses as constants
    const PERIPH_BASE: u32 = 0x40000000;
    const AHB1PERIPH_BASE: u32 = PERIPH_BASE + 0x00020000;
    const RCC_BASE: u32 = AHB1PERIPH_BASE + 0x3800;
    const RCC_AHB1ENR: u32 = RCC_BASE + 0x30;
    const GBPIA_BASE: u32 = AHB1PERIPH_BASE + 0x0000;
    const GPIOA_MODER: u32 = GBPIA_BASE + 0x00;
    const GPIOA_BSRR: u32 = GBPIA_BASE + 0x18;
    
    // see the Reference Manual RM0368 (www.st.com/resource/en/reference_manual/dm00096844.pdf)
    // rcc,     chapter 6
    // gpio,    chapter 8
    
    #[inline(always)]
    fn read_u32(addr: u32) -> u32 {
        unsafe { core::ptr::read_volatile(addr as *const _) }
    }
    
    #[inline(always)]
    fn write_u32(addr: u32, val: u32) {
        unsafe {
            core::ptr::write_volatile(addr as *mut _, val);
        }
    }
    
    fn wait(i: u32) {
        for _ in 0..i {
            cortex_m::asm::nop(); // no operation (cannot be optimized out)
        }
    }
    
    fn main() {
        // power on GPIOA, RM0368 6.3.11
    
        let r = read_u32(RCC_AHB1ENR); // read
        write_u32(RCC_AHB1ENR, r | 1); // set enable
    
        // configure PA5 as output, RM0368 8.4.1
        let r = read_u32(GPIOA_MODER) & !(0b11 << (5 * 2)); // read and mask
        write_u32(GPIOA_MODER, r | 0b01 << (5 * 2)); // set output mode
    
        // and alter the data output through the BSRR register
        // this is more efficient as the read register (in modify)
        // is not needed.
    
        loop {
            // set PA5 high, RM0368 8.4.7
            write_u32(GPIOA_BSRR, 1 << 5); // set bit, output hight (turn on led)
            wait(10_000);
    
            // set PA5 low, RM0368 8.4.7
            write_u32(GPIOA_BSRR, 1 << (5 + 16)); // clear bit, output low (turn off led)
            wait(10_000);
        }
    }
    
    // As we are not using interrupts, we just register a dummy catch all handler
    #[link_section = ".vector_table.interrupts"]
    #[used]
    static INTERRUPTS: [extern "C" fn(); 240] = [default_handler; 240];
    
    extern "C" fn default_handler() {
        cortex_m::asm::bkpt();
    }