diff --git a/.vscode/launch.json b/.vscode/launch.json index 3ff1ffe70c09208c57b589d1e8a2d7ad7f893150..5b205905c670bdfcfef8c60a86851341c4cd9a82 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -166,5 +166,23 @@ ], "cwd": "${workspaceRoot}" }, + { + "type": "gdb", + "request": "attach", + "name": "bare5", + "gdbpath": "/usr/bin/arm-none-eabi-gdb", + "executable": "./target/thumbv7em-none-eabihf/debug/examples/bare5", + "target": ":3333", + "remote": true, + "autorun": [ + "monitor reset init", + "monitor arm semihosting enable", + "monitor tpiu config internal /tmp/itm.log uart off 64000000", + "monitor itm port 0 on", + "load", + "monitor reset init" + ], + "cwd": "${workspaceRoot}" + }, ] } \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 760e36e48ef828d6684034a1aafa7d04ec45a8de..afdd4ba8a60ab65825de389cc99142f988286f4c 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -111,5 +111,29 @@ "isDefault": true } }, + { + "type": "shell", + "label": "xargo build --example bare5", + "command": "xargo build --example bare5", + "problemMatcher": [ + "$rustc" + ], + "group": { + "kind": "build", + "isDefault": true + } + }, + { + "type": "shell", + "label": "xargo build --example bare6", + "command": "xargo build --example bare6", + "problemMatcher": [ + "$rustc" + ], + "group": { + "kind": "build", + "isDefault": true + } + }, ] } \ No newline at end of file diff --git a/examples/bare5.rs b/examples/bare5.rs index 29f6744f9b76d034d9691d96bc0c71912d8083fd..3c19c2431839893c62e53f582046813c92345977 100644 --- a/examples/bare5.rs +++ b/examples/bare5.rs @@ -1,8 +1,8 @@ -//! bare4.rs +//! bare5.rs //! Simple bare metal application //! #![feature(used)] -#![feature(custom_attribute)] +#![feature(custom_attribute)] // needed for #[rustfmt_skip] #![no_std] extern crate cortex_m; @@ -15,10 +15,14 @@ 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; + #[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 GPIOA_BASE: u32 = AHB1PERIPH_BASE + 0x0000; + } + use stm32f40x::address::*; pub struct VolatileCell<T> { value: cell::UnsafeCell<T>, @@ -46,41 +50,41 @@ mod stm32f40x { #[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 */ + 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 + address::RCC_BASE as *mut RCC } } @@ -88,24 +92,18 @@ mod stm32f40x { #[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 */ + pub MODER: VolatileCell<u32>, // < GPIO port mode register, Address offset: 0x00 + 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 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>;2], // < 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 @@ -128,32 +126,31 @@ 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 + let rcc = RCC::get(); // get the reference to 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); - // } - // } + let gpioa = GPIOA::get(); // get the reference to GPIOA in memory + 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 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).BSRRL.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