Skip to content
Snippets Groups Projects
Commit d6824da3 authored by Per's avatar Per
Browse files

strange error

parent a3f22180
No related branches found
No related tags found
No related merge requests found
......@@ -7,22 +7,25 @@
extern crate cortex_m;
extern crate cortex_m_rt;
#[macro_use]
extern crate cortex_m_debug;
const RCC_AHPB1ENR: u32 = 0x4002_3810;
const GPIOA_MODER: u32 = 0x4002_0000;
//const GPIOA_ODR: u32 = 0x4002_0014;
const GPIOA_BSRR: u32 = 0x4002_0018;
// 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);
......@@ -36,14 +39,12 @@ fn wait(i: u32) {
}
fn main() {
// // power on GPIOA, RM0368 6.3.11
// p.RCC.ahb1enr.modify(|_, w| w.gpioaen().set_bit());
// power on GPIOA, RM0368 6.3.11
let r = read_u32(RCC_AHPB1ENR); // read
write_u32(RCC_AHPB1ENR, r | 1 << (0)); // set enable
let r = read_u32(RCC_AHB1ENR); // read
write_u32(RCC_AHB1ENR, r | 1); // set enable
// // configure PA5 as output, RM0368 8.4.1
// p.GPIOA.moder.modify(|_, w| w.moder5().bits(1));
// 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
......@@ -53,11 +54,11 @@ fn main() {
loop {
// set PA5 high, RM0368 8.4.7
write_u32(GPIOA_BSRR, r | 1 << 5); // set output mode
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, r | 1 << (5 + 16)); // set output mode
write_u32(GPIOA_BSRR, 1 << (5 + 16)); // clear bit, output low (turn off led)
wait(10_000);
}
}
......
//! 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();
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment