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

to fresk

parent a06a5e0b
No related branches found
No related tags found
No related merge requests found
......@@ -6,7 +6,7 @@
//! - tracing over semihosting and ITM
//! - assembly calls and inline assembly
//! - more on arithmetics
//! ---
//!
#![no_main]
#![no_std]
......
......@@ -17,6 +17,7 @@ use cortex_m::{iprintln, peripheral::DWT, Peripherals};
use cortex_m_rt::entry;
// burns CPU cycles by just looping `i` times
#[inline(never)]
fn wait(i: u32) {
for _ in 0..i {
// no operation (ensured not optimized out)
......
......@@ -91,7 +91,7 @@ fn main() -> ! {
// commit your answers (bare3_4)
//
// 5. Look for a way to make this copy done without a loop.
// https://doc.rust-lang.org/beta/std/primitive.slice.html
// https://doc.rust-lang.org/std/primitive.slice.html
//
// Implement and test your solution.
//
......
......@@ -87,11 +87,11 @@ fn main() -> ! {
// 6.3.11, 8.4.1, 8.4.7
//
// Document each low level access *code* by the appropriate section in the
// data sheet
// data sheet.
//
// commit your answers (bare4_1)
//
// 2. comment out line 40 and uncomment line 41 (essentially omitting the `unsafe`)
// 2. Comment out line 40 and uncomment line 41 (essentially omitting the `unsafe`)
//
// //unsafe { core::ptr::read_volatile(addr as *const _) }
// core::ptr::read_volatile(addr as *const _)
......
......@@ -4,7 +4,7 @@
//!
//! What it covers:
//! - abstractions in Rust
//!
//! - structs and implementations
#![feature(uniform_paths)] // requires nightly
#![no_std]
......
......@@ -3,34 +3,21 @@
//! Clocking
//!
//! What it covers:
//! - using svd2rust generated API
//! - setting the clock via script (again)
//! - routing the clock to a PIN for monitoring by an oscilloscope
//! - changing the clock using Rust code
//!
// #![feature(used)]
// #![no_std]
// extern crate f4;
// extern crate stm32f40x;
// #[macro_use]
// extern crate cortex_m_debug;
// use f4::clock;
// use f4::prelude::*;
// use stm32f40x::{DWT, FLASH, GPIOA, GPIOC, RCC};
#![no_main]
#![no_std]
#![feature(uniform_paths)]
extern crate panic_halt;
use cortex_m::{iprintln, peripheral::itm::Stim};
use cortex_m_rt::entry;
use stm32f4::stm32f413;
use stm32f413::{DWT, GPIOA, GPIOC, RCC};
use stm32f4::stm32f413::{self, DWT, GPIOA, GPIOC, RCC};
#[entry]
fn main() -> ! {
......@@ -65,7 +52,7 @@ fn idle(stim: &mut Stim, rcc: RCC, gpioa: GPIOA) {
gpioa.moder.modify(|_, w| w.moder5().bits(1));
// at 16 Mhz, 8_000_000 cycles = period 0.5s
// at 64 Mhz, 4*8_000_000 cycles = period 0.55s
// at 64 Mhz, 4*8_000_000 cycles = period 0.5s
// let cycles = 8_000_000;
let cycles = 4 * 8_000_000;
......@@ -99,7 +86,8 @@ fn clock_out(rcc: &RCC, gpioc: &GPIOC) {
// mco2 : SYSCLK = 0b00
// mcopre : divide by 4 = 0b110
rcc.cfgr
.modify(|_, w| unsafe { w.mco2().bits(0b00).mco2pre().bits(0b110) });
//.modify(|_, w| unsafe { w.mco2().bits(0b00).mco2pre().bits(0b110) });
.modify(|_, w| w.mco2().sysclk().mco2pre().div4());
// power on GPIOC, RM0368 6.3.11
rcc.ahb1enr.modify(|_, w| w.gpiocen().set_bit());
......@@ -109,12 +97,15 @@ fn clock_out(rcc: &RCC, gpioc: &GPIOC) {
// AF0, gpioc reset value = AF0
// configure PC9 as alternate function 0b10, RM0368 6.2.10
gpioc.moder.modify(|_, w| w.moder9().bits(0b10));
gpioc.moder.modify(|_, w| w.moder9().alternate());
// gpioc.moder.modify(|_, w| w.moder9().bits(0b10));
// otyper reset state push/pull, in reset state (don't need to change)
// ospeedr 0b11 = high speed
gpioc.ospeedr.modify(|_, w| w.ospeedr9().bits(0b11));
// ospeedr 0b11 = very high speed
// gpioc.ospeedr.modify(|_, w| w.ospeedr9().bits(0b11));
gpioc.ospeedr.modify(|_, w| w.ospeedr9().very_high_speed())
}
// 1. Compile and run the example, in 16Mhz
......
//! bare6.rs
//!
//! Clocking
//!
//! What it covers:
//! - using svd2rust generated API
//! - setting the clock via script (again)
//! - routing the clock to a PIN for monitoring by an oscilloscope
//! - changing the clock using Rust code
//!
#![no_main]
#![no_std]
#![feature(uniform_paths)]
#![feature(type_alias_enum_variants)]
extern crate panic_halt;
use cortex_m::{iprintln, peripheral::itm::Stim};
use cortex_m_rt::entry;
use stm32f4::stm32f413;
use stm32f413::{DWT, GPIOA, GPIOC, RCC};
#[entry]
fn main() -> ! {
let p = stm32f413::Peripherals::take().unwrap();
let mut c = stm32f413::CorePeripherals::take().unwrap();
let stim = &mut c.ITM.stim[0];
iprintln!(stim, "Hello, bare6!");
c.DWT.enable_cycle_counter();
unsafe {
c.DWT.cyccnt.write(0);
}
let t = DWT::get_cycle_count();
iprintln!(stim, "{}", t);
clock_out(&p.RCC, &p.GPIOC);
// clock::set_84_mhz(rcc, flash);
idle(stim, p.RCC, p.GPIOA);
loop {}
}
// // user application
fn idle(stim: &mut Stim, rcc: RCC, gpioa: GPIOA) {
iprintln!(stim, "idle");
// power on GPIOA, RM0368 6.3.11
rcc.ahb1enr.modify(|_, w| w.gpioaen().set_bit());
// configure PA5 as output, RM0368 8.4.1
gpioa.moder.modify(|_, w| w.moder5().bits(1));
// at 16 Mhz, 8_000_000 cycles = period 0.5s
// at 64 Mhz, 4*8_000_000 cycles = period 0.5s
// let cycles = 8_000_000;
let cycles = 4 * 8_000_000;
loop {
iprintln!(stim, "on {}", DWT::get_cycle_count());
// set PA5 high, RM0368 8.4.7
gpioa.bsrr.write(|w| w.bs5().set_bit());
wait_cycles(cycles);
iprintln!(stim, "off {}", DWT::get_cycle_count());
// set PA5 low, RM0368 8.4.7
gpioa.bsrr.write(|w| w.br5().set_bit());
wait_cycles(cycles);
}
}
// uses the DWT.CYCNT
// doc: ARM trm_100166_0001_00_en.pdf, chapter 9.2
// we use the `cortex-m` abstraction, as re-exported by the stm32f40x
fn wait_cycles(nr_cycles: u32) {
let t = DWT::get_cycle_count().wrapping_add(nr_cycles);
while (DWT::get_cycle_count().wrapping_sub(t) as i32) < 0 {}
}
// see the Reference Manual RM0368 (www.st.com/resource/en/reference_manual/dm00096844.pdf)
// rcc, chapter 6
// gpio, chapter 8
fn clock_out(rcc: &RCC, gpioc: &GPIOC) {
// output MCO2 to pin PC9
// mco2 : SYSCLK = 0b00
// mcopre : divide by 4 = 0b110
rcc.cfgr
.modify(|_, w| unsafe { w.mco2().bits(0b00).mco2pre().bits(0b110) });
// power on GPIOC, RM0368 6.3.11
rcc.ahb1enr.modify(|_, w| w.gpiocen().set_bit());
// MCO_2 alternate function AF0, STM32F401xD STM32F401xE data sheet
// table 9
// AF0, gpioc reset value = AF0
// configure PC9 as alternate function 0b10, RM0368 6.2.10
gpioc.moder.modify(|_, w| w.moder9().bits(0b10));
// otyper reset state push/pull, in reset state (don't need to change)
// ospeedr 0b11 = high speed
// use stm32f4::stm32f413::gpiof::ospeedr::OSPEEDR9W;
// use gpioc::ospeedr::OSPEEDR9W;
// use stm32f4::stm32f413::gpiof as gpioc;
// use stm32f4::stm32f413::gpiof::ospeedr::OSPEEDR9W::*;
// gpioc.ospeedr.modify(|_, w| w.ospeedr9().bits(0b11));
// gpioc.ospeedr.modify(|_, w| {
// w.ospeedr9().variant(gpioc::ospeedr::OSPEEDR9W::HIGHSPEED)
// });
// gpioc.ospeedr.modify(|_, w| w.ospeedr9().low_speed())
gpioc.ospeedr.modify(|_, w| w.ospeedr9().very_high_speed())
}
// 1. Compile and run the example, in 16Mhz
// The processor SYSCLK defaults to HCI 16Mhz
// (this is what you get after a `monitor reset halt`).
//
// Confirm that your ITM dump traces the init, idle and led on/off.
// Make sure your TPIU is set to a system clock at 16Mhz
//
// What is the frequency of blinking?
//
// ** your answer here **
//
// commit your answers (bare6_1)
//
// 2. Now connect an oscilloscope to PC9, which is set to
// output the MCO2.
//
// What is the frequency of MCO2 read by the oscilloscope?
//
// ** your answer here **
//
// Compute the value of SYSCLK based on the oscilloscope reading
//
// ** your answer here **
//
// What is the peak to peak reading of the signal?
//
// ** your answer here **
//
// Make a folder called "pictures" in your git project.
// Make a screen dump or photo of the oscilloscope output.
// Save the the picture as "bare_6_16mhz_high_speed".
//
// commit your answers (bare6_2)
//
// 3. Now run the example in 64Mz
// You can do that by issuing a `monitor reset init`
// which reprograms SYSCLK to 4*HCI.
//
//
// Confirm that your ITM dump traces the init, idle and led on/off
// (make sure your TPIU is set to a system clock at 64Mhz)
//
// Uncommnet: `let cycles = 4 * 8_000_000;
//`
// What is the frequency of blinking?
//
// ** your answer here **
//
// commit your answers (bare6_3)
//
// 4. Repeat experiment 2
//
// What is the frequency of MCO2 read by the oscilloscope?
//
// ** your answer here **
//
// Compute the value of SYSCLK based on the oscilloscope reading.
//
// ** your answer here **
//
// What is the peak to peak reading of the signal?
//
// ** your answer here **
//
// Make a screen dump or photo of the oscilloscope output.
// Save the the picture as "bare_6_64mhz_high_speed".
//
// commit your answers (bare6_4)
//
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment