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

openocd.gdb

Blame
  • bare5.rs 8.23 KiB
    //! bare4.rs
    //! Simple bare metal application
    //!
    #![feature(used)]
    #![feature(custom_attribute)]
    #![no_std]
    
    extern crate cortex_m;
    extern crate cortex_m_rt;
    
    // #[macro_use]
    // extern crate cortex_m_debug;
    
    mod stm32f40x {
        use core::{cell, ptr};
    
        // C like API...
        const PERIPH_BASE: u32 = 0x40000000;
        const AHB1PERIPH_BASE: u32 = PERIPH_BASE + 0x00020000;
        const RCC_BASE: u32 = AHB1PERIPH_BASE + 0x3800;
        const GPIOA_BASE: u32 = AHB1PERIPH_BASE;
    
        pub struct VolatileCell<T> {
            value: cell::UnsafeCell<T>,
        }
    
        impl<T> VolatileCell<T> {
            #[inline(always)]
            pub fn read(&self) -> T
            where
                T: Copy,
            {
                unsafe { ptr::read_volatile(self.value.get()) }
            }
    
            #[inline(always)]
            pub fn write(&self, value: T)
            where
                T: Copy,
            {
                unsafe { ptr::write_volatile(self.value.get(), value) }
            }
        }
    
        #[repr(C)]
        #[allow(non_snake_case)]
        #[rustfmt_skip]
        pub struct RCC {
            pub CR:         VolatileCell<u32>,      // < RCC clock control register,                                  Address offset: 0x00 */
            pub PLLCFGR:    VolatileCell<u32>,      // < RCC PLL configuration register,                              Address offset: 0x04 */
            pub CFGR:       VolatileCell<u32>,      // < RCC clock configuration register,                            Address offset: 0x08 */
            pub CIR:        VolatileCell<u32>,      // < RCC clock interrupt register,                                Address offset: 0x0C */
            pub AHB1RSTR:   VolatileCell<u32>,      // < RCC AHB1 peripheral reset register,                          Address offset: 0x10 */
            pub AHB2RSTR:   VolatileCell<u32>,      // < RCC AHB2 peripheral reset register,                          Address offset: 0x14 */
            pub AHB3RSTR:   VolatileCell<u32>,      // < RCC AHB3 peripheral reset register,                          Address offset: 0x18 */
            pub RESERVED0:  VolatileCell<u32>,      // < Reserved, 0x1C                                                                    */
            pub APB1RSTR:   VolatileCell<u32>,      // < RCC APB1 peripheral reset register,                          Address offset: 0x20 */
            pub APB2RSTR:   VolatileCell<u32>,      // < RCC APB2 peripheral reset register,                          Address offset: 0x24 */
            pub RESERVED1:  [VolatileCell<u32>; 2], // < Reserved, 0x28-0x2C                                                               */
            pub AHB1ENR:    VolatileCell<u32>,      // < RCC AHB1 peripheral clock register,                          Address offset: 0x30 */
            pub AHB2ENR:    VolatileCell<u32>,      // < RCC AHB2 peripheral clock register,                          Address offset: 0x34 */
            pub AHB3ENR:    VolatileCell<u32>,      // < RCC AHB3 peripheral clock register,                          Address offset: 0x38 */
            pub RESERVED2:  VolatileCell<u32>,      // < Reserved, 0x3C                                                                    */
            pub APB1ENR:    VolatileCell<u32>,      // < RCC APB1 peripheral clock enable register,                   Address offset: 0x40 */
            pub APB2ENR:    VolatileCell<u32>,      // < RCC APB2 peripheral clock enable register,                   Address offset: 0x44 */
            pub RESERVED3:  [VolatileCell<u32>; 2], // < Reserved, 0x48-0x4C                                                               */
            pub AHB1LPENR:  VolatileCell<u32>,      // < RCC AHB1 peripheral clock enable in low power mode register, Address offset: 0x50 */
            pub AHB2LPENR:  VolatileCell<u32>,      // < RCC AHB2 peripheral clock enable in low power mode register, Address offset: 0x54 */
            pub AHB3LPENR:  VolatileCell<u32>,      // < RCC AHB3 peripheral clock enable in low power mode register, Address offset: 0x58 */
            pub RESERVED4:  VolatileCell<u32>,      // < Reserved, 0x5C                                                                    */
            pub APB1LPENR:  VolatileCell<u32>,      // < RCC APB1 peripheral clock enable in low power mode register, Address offset: 0x60 */
            pub APB2LPENR:  VolatileCell<u32>,      // < RCC APB2 peripheral clock enable in low power mode register, Address offset: 0x64 */
            pub RESERVED5:  [VolatileCell<u32>; 2], // < Reserved, 0x68-0x6C                                                               */
            pub BDCR:       VolatileCell<u32>,      // < RCC Backup domain control register,                          Address offset: 0x70 */
            pub CSR:        VolatileCell<u32>,      // < RCC clock control & status register,                         Address offset: 0x74 */
            pub RESERVED6:  [VolatileCell<u32>; 2], // < Reserved, 0x78-0x7C                                                               */
            pub SSCGR:      VolatileCell<u32>,      // < RCC spread spectrum clock generation register,               Address offset: 0x80 */
            pub PLLI2SCFGR: VolatileCell<u32>,      // < RCC PLLI2S configuration register,                           Address offset: 0x84 */
        }
    
        impl RCC {
            pub fn get() -> *mut RCC {
                RCC_BASE as *mut RCC
            }
        }
    
        #[repr(C)]
        #[allow(non_snake_case)]
        #[rustfmt_skip]
        pub struct GPIOA {
            pub OTYPER:     VolatileCell<u32>,      // < GPIO port output type register,        Address offset: 0x04      */
            pub OSPEEDR:    VolatileCell<u32>,      // < GPIO port output speed register,       Address offset: 0x08      */
            pub PUPDR:      VolatileCell<u32>,      // < GPIO port pull-up/pull-down register,  Address offset: 0x0C      */
            pub MODER:      VolatileCell<u32>,      // < GPIO port mode register,               Address offset: 0x00      */
            pub IDR:        VolatileCell<u32>,      // < GPIO port input data register,         Address offset: 0x10      */
            pub ODR:        VolatileCell<u32>,      // < GPIO port output data register,        Address offset: 0x14      */
            pub BSRRL:      VolatileCell<u16>,      // < GPIO port bit set/reset low register,  Address offset: 0x18      */
            pub BSRRH:      VolatileCell<u16>,      // < GPIO port bit set/reset high register, Address offset: 0x1A      */
            pub LCKR:       VolatileCell<u32>,      // < GPIO port configuration lock register, Address offset: 0x1C      */
            pub AFR:        [VolatileCell<u32>],    // < GPIO alternate function registers,     Address offset: 0x20-0x24 */
        }
    
        // impl GPIOA {
        //     pub fn get() -> *mut GPIOA {
        //         GPIOA_BASE as *mut GPIOA
        //     }
        // }
    
        impl GPIOA {
            pub fn get() -> *mut GPIOA {
                GPIOA_BASE as *mut GPIOA
            }
        }
    }
    use stm32f40x::*;
    
    // see the Reference Manual RM0368 (www.st.com/resource/en/reference_manual/dm00096844.pdf)
    // rcc,     chapter 6
    // gpio,    chapter 8
    
    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
        // p.RCC.ahb1enr.modify(|_, w| w.gpioaen().set_bit());
    
        let rcc = RCC::get(); // get the reference to the Rcc in memory
        unsafe {
            let r = (*rcc).AHB1ENR.read(); // read
            (*rcc).AHB1ENR.write(r | 1 << (0)); // set enable
        }
    
        // configure PA5 as output, RM0368 8.4.1
        // let gpioa = GPIOA::get();
        // unsafe {
        //     let r = (*gpioa).MODER.read() & !(0b11 << (5 * 2)); // read and mask
        //     (*gpioa).MODER.write(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
        //         (*gpioa).BSRRH.write(1 << 5); // set bit, output hight (turn on led)
        //         wait(10_000);
    
        //         // set PA5 low, RM0368 8.4.7
        //         (*gpioa).BSRRH.write(1 << 5); // 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();
    }