Skip to content
Snippets Groups Projects
Select Git revision
  • e49e56743294f5eb72048109f6c8112ddd7b3684
  • master default protected
  • usb
  • fresk
4 results

bare4.rs

Blame
  • bare4.rs 3.74 KiB
    //! bare4.rs
    //!
    //! Access to Peripherals
    //!
    //! What it covers:
    //! - raw pointers
    //! - volatile read/write
    //! - busses and clocking
    //! - gpio
    
    #![feature(uniform_paths)] // requires nightly
    #![no_std]
    #![no_main]
    
    extern crate panic_halt;
    
    extern crate cortex_m;
    use cortex_m_rt::entry;
    
    // Peripheral addresses as constants
    #[rustfmt::skip]
    mod address {
        pub const PERIPH_BASE: u32      = 0x40000000;
        pub const AHB1PERIPH_BASE: u32  = PERIPH_BASE + 0x00020000;
        pub const RCC_BASE: u32         = AHB1PERIPH_BASE + 0x3800;
        pub const RCC_AHB1ENR: u32      = RCC_BASE + 0x30;
        pub const GBPIA_BASE: u32       = AHB1PERIPH_BASE + 0x0000;
        pub const GPIOA_MODER: u32      = GBPIA_BASE + 0x00;
        pub const GPIOA_BSRR: u32       = GBPIA_BASE + 0x18;
    }
    
    use address::*;
    
    // 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 _) }
        //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)
        }
    }
    
    #[entry]
    fn main() -> ! {
        // power on GPIOA
        let r = read_u32(RCC_AHB1ENR); // read
        write_u32(RCC_AHB1ENR, r | 1); // set enable
    
        // configure PA5 as output
        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 is not needed.
    
        loop {