Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
  • Programming_of_nuttali
  • master
  • upstream
3 results

Target

Select target project
  • Frappe/e7020e_2021
  • rognda-6/e7020e_2021
  • Klomega/e7020e_2021
  • pln/e7020e_2021
  • CarlOsterberg/e7020e_2021
  • jonjac-6/e7020e_2021
  • deux-babiri-futari/e7020e_2021
  • samgra-7/e7020e_2021
  • JosefUtbult/e7020e_2021
  • edwkll-7/e7020e_2021
10 results
Select Git revision
  • master
1 result
Show changes
Commits on Source (32)
Showing
with 54844 additions and 101 deletions
......@@ -9,6 +9,15 @@
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"cwd": "${workspaceRoot}",
"executable": "./bin/executable.elf",
"name": "Debug Microcontroller",
"request": "launch",
"type": "cortex-debug",
"servertype": "openocd"
},
{
"type": "cortex-debug",
"request": "launch",
......
# Changelog
<<<<<<< HEAD
=======
## 2021-03-18
- examples/usb-mouse.rs, a very small example using external hid library.
>>>>>>> 8d3a36604d8080052d125e924e11622c6bf8b01c
## 2021-03-07
- examples/rtic_bare7.rs, using embedded HAL.
......
......@@ -36,6 +36,10 @@ version = "0.13.0"
features = ["stm32f411", "rt"]
# [dependencies.stm32f4]
# version = "0.13.0"
# features = ["stm32f411", "rt"]
[dependencies.stm32f4xx-hal]
version = "0.8.3"
features = ["rt", "stm32f411", "usb_fs"]
......
This diff is collapsed.
This diff is collapsed.
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"cwd": "${workspaceRoot}",
"executable": "./bin/executable.elf",
"name": "Debug Microcontroller",
"request": "launch",
"type": "cortex-debug",
"servertype": "openocd"
},
{
"cwd": "${workspaceRoot}",
"executable": "./bin/executable.elf",
"name": "Debug Microcontroller",
"request": "launch",
"type": "cortex-debug",
"servertype": "jlink"
}
]
}
\ No newline at end of file
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"label": "cargo build --example",
"command": "cargo",
"args": [
"build",
"--example",
"${fileBasenameNoExtension}"
],
"problemMatcher": [
"$rustc"
],
"group": "build",
},
{
"label": "cargo build --example --release",
"command": "cargo",
"args": [
"build",
"--example",
"${fileBasenameNoExtension}",
"--release"
],
"problemMatcher": [
"$rustc"
],
"group": "build",
},
]
}
\ No newline at end of file
{
"version": "2.0.0",
"tasks": [
{
"type": "cargo",
"command": "build",
"problemMatcher": [
"$rustc"
],
"group": {
"kind": "build",
"isDefault": true
},
"label": "rust: cargo build"
}
]
}
\ No newline at end of file
examples/bare_6_48mhz_low_speed.jpg

2.44 MiB

......@@ -20,9 +20,10 @@ const APP: () = {
fn init(_cx: init::Context) {
let mut x = core::u32::MAX - 1;
loop {
// cortex_m::asm::bkpt();
x += 1;
// cortex_m::asm::bkpt();
cortex_m::asm::bkpt();
//x += 1;
x = x.wrapping_add(1);
cortex_m::asm::bkpt();
// prevent optimization by read-volatile (unsafe)
unsafe {
......@@ -45,11 +46,11 @@ const APP: () = {
//
// Paste the error message:
//
// ** your answer here **
// panicked at 'attempt to add with overflow', examples/rtic_bare1.rs:24:13
//
// Explain in your own words why the code panic:ed.
//
// ** your answer here **
// It panicked because of an attempted overflow
//
// Commit your answer (bare1_1)
//
......@@ -65,11 +66,18 @@ const APP: () = {
//
// Paste the backtrace:
//
// ** your answer here
// #0 lib::__bkpt () at asm/lib.rs:49
// #1 0x0800104e in cortex_m::asm::bkpt () at /root/.cargo/registry/src/github.com-1ecc6299db9ec823/cortex-m-0.7.1/src/asm.rs:15
// #2 panic_semihosting::panic (info=0x2000fed8) at /root/.cargo/registry/src/github.com-1ecc6299db9ec823/panic-semihosting-0.5.6/src/lib.rs:92
// #3 0x0800039a in core::panicking::panic_fmt () at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b//library/core/src/panicking.rs:92
// #4 0x08000374 in core::panicking::panic () at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b//library/core/src/panicking.rs:50
// #5 0x08000ebe in rtic_bare1::init (_cx=...) at /home/tommy/Documents/Inbygda_system/e7020e_2021/examples/rtic_bare1.rs:24
// #6 0x08000f08 in rtic_bare1::APP::main () at /home/tommy/Documents/Inbygda_system/e7020e_2021/examples/rtic_bare1.rs:15
// {"token":181,"outOfBandRecord":[],"resultRecords":{"resultClass":"done","results":[]}}
//
// Explain in your own words the chain of calls.
//
// ** your answer here
// The error occurs and then sends it further up and into panic and ending up in asm/lib
//
// Commit your answer (bare1_2)
//
......@@ -82,20 +90,22 @@ const APP: () = {
//
// What is the value of `x`?
//
// ** your answer here **
// x: 4294967294
//
// Explain in your own words where this value comes from.
//
// ** your answer here **
// x is initiated as usigned 32-bit integer set as max - 1 that will set it as 2^32 - 1
//
// Now continue the program, since you are in a loop
// the program will halt again at line 24.
//
// What is the value of `x`?
//
// x: 4294967295
//
// Explain in your own words why `x` now has this value.
//
// ** your answer here **
// Since we increase x by 1 for every time we loop
//
// Now continue again.
//
......@@ -109,7 +119,7 @@ const APP: () = {
//
// Explain in your own words why a panic makes sense at this point.
//
// ** your answer here **
// The panic makes sense because x overflows by increasing the max (2^32 = 4294967295) by 1 and we are using a u32 and checking if it overflows.
//
// Commit your answer (bare1_3)
//
......@@ -126,13 +136,13 @@ const APP: () = {
//
// Explain in your own words what this assembly line does.
//
// ** your answer here **
// load r0 with the value that stackpointer points to.
//
// In Cortex Registers (left) you can see the content of `r0`
//
// What value do you observe?
//
// ** your answer here **
// r0 = -2
//
// You can also get the register info from GDB directly.
//
......@@ -150,7 +160,7 @@ const APP: () = {
//
// Explain in your own words what is happening here.
//
// ** your answer here **
// We add 1 to r0 and update the N. Z, C and V flags.
//
// We move to the next assembly instruction:
//
......@@ -159,7 +169,7 @@ const APP: () = {
//
// What is the reported value for `r0`
//
// ** your answer here **
// r0 = -1
//
// So far so good.
//
......@@ -190,7 +200,7 @@ const APP: () = {
//
// What does BCS do?
//
// ** your answer here **
// Checks if carry flag is set, if it is branches to +36
//
// Now let's see what happens.
//
......@@ -204,7 +214,7 @@ const APP: () = {
//
// Explain in your own words where we are heading.
//
// ** your answer here **
// we move in 20485872 into r0, 20485856 into r2 and 28 into r1 but only overwrites the 9 lowest bits.
//
// To validate that your answer, let's let the program continue
//
......@@ -215,13 +225,13 @@ const APP: () = {
// Explain in your own words what the code
// 0x08000f28 .. 0x08000f38 achieves
//
// #28 generates the panic (overflow) while r0 and r2 tells where.
//
// Hint 1, look at the error message?
// Hint 2, look at the call stack.
// Hint 3, the code is generated by the Rust compiler to produce the error message.
// there is no "magic" here, just a compiler generating code...
//
// ** your answer here **
//
// Commit your answer (bare1_4)
//
// 5. Now we can remove the break point (click the `Remove All Breakpoints`),
......@@ -229,7 +239,7 @@ const APP: () = {
//
// Close the debug session and press F5 again to re-compile and launch the app.
//
// Continue until you hit the firs breakpoint.
// Continue until you hit the first breakpoint.
//
// The disassembly should look like this:
//
......@@ -273,7 +283,7 @@ const APP: () = {
//
// Do you see any way this code may end up in a panic?
//
// ** your answer here **
// When calling bkpt when not in debug will cause a panic.
//
// So clearly, the "semantics" (meaning) of the program has changed.
// This is on purpose, Rust adopts "unchecked" (wrapping) additions (and subtractions)
......@@ -288,16 +298,45 @@ const APP: () = {
//
// Paste the generated assembly:
//
// ** your answer here **
// Dump of assembler code for function rtic_bare1::APP::main:
/* 0x08000eae <+0>: push {r7, lr}
0x08000eb0 <+2>: mov r7, sp
0x08000eb2 <+4>: sub sp, #56 ; 0x38
=> 0x08000eb4 <+6>: bl 0x8000faa <lib::__cpsid>
0x08000eb8 <+10>: movw r0, #0
0x08000ebc <+14>: movw r4, #60688 ; 0xed10
0x08000ec0 <+18>: movt r0, #8192 ; 0x2000
0x08000ec4 <+22>: movs r1, #1
0x08000ec6 <+24>: strb r1, [r0, #0]
0x08000ec8 <+26>: add r0, sp, #4
0x08000eca <+28>: movt r4, #57344 ; 0xe000
0x08000ece <+32>: str r0, [sp, #20]
0x08000ed0 <+34>: mov r0, r4
0x08000ed2 <+36>: strd r4, r4, [sp, #28]
0x08000ed6 <+40>: bl 0x8000f78 <_ZN4core4cell19UnsafeCell$LT$T$GT$3get17hc981151b10f99f20E>
0x08000eda <+44>: bl 0x8000f46 <_ZN4core3ptr13read_volatile17hb977623ea709e27cE>
0x08000ede <+48>: orr.w r5, r0, #2
0x08000ee2 <+52>: str r0, [sp, #24]
0x08000ee4 <+54>: mov r0, r4
0x08000ee6 <+56>: str r4, [sp, #36] ; 0x24
0x08000ee8 <+58>: str r5, [sp, #40] ; 0x28
0x08000eea <+60>: bl 0x8000f78 <_ZN4core4cell19UnsafeCell$LT$T$GT$3get17hc981151b10f99f20E>
0x08000eee <+64>: mov r1, r5
0x08000ef0 <+66>: bl 0x8000f54 <_ZN4core3ptr14write_volatile17h73c310961d025d87E>
0x08000ef4 <+70>: bl 0x8000e84 <rtic_bare1::init>
0x08000ef8 <+74>: bl 0x8000fae <lib::__cpsie>
0x08000efc <+78>: bl 0x8000fb2 <lib::__wfi>
0x08000f00 <+82>: b.n 0x8000efc <rtic_bare1::APP::main+78>
End of assembler dump. */
//
// Can this code generate a panic?
//
// ** your answer here **
// No.
//
// Is there now any reference to the panic handler?
// If not, why is that the case?
//
// ** your answer here **
// When we use wrap it allows us to wrap around, hence no overflow or panic.
//
// commit your answers (bare1_5)
//
......@@ -327,12 +366,30 @@ const APP: () = {
//
// Dump the generated assembly.
//
// ** your answer here **
/*Dump of assembler code for function rtic_bare1::init:
0x08000e84 <+0>: push {r4, r6, r7, lr}
0x08000e86 <+2>: add r7, sp, #8
0x08000e88 <+4>: sub sp, #16
0x08000e8a <+6>: movw r0, #5808 ; 0x16b0
0x08000e8e <+10>: mov r4, sp
0x08000e90 <+12>: movt r0, #2048 ; 0x800
0x08000e94 <+16>: ldr r0, [r0, #0]
0x08000e96 <+18>: str r0, [sp, #0]
0x08000e98 <+20>: bl 0x8000fa6 <lib::__bkpt>
0x08000e9c <+24>: ldr r0, [sp, #0]
0x08000e9e <+26>: adds r0, #1
0x08000ea0 <+28>: str r0, [sp, #0]
0x08000ea2 <+30>: bl 0x8000fa6 <lib::__bkpt>
=> 0x08000ea6 <+34>: mov r0, r4
0x08000ea8 <+36>: bl 0x8000f46 <_ZN4core3ptr13read_volatile17hb977623ea709e27cE>
0x08000eac <+40>: b.n 0x8000e98 <rtic_bare1::init+20>
End of assembler dump.
*/
//
// Where is the local variable stored?
// What happened, and why is Rust + LLVM allowed to optimize out your code?
//
// ** your answer here **
// On the stack pointer. When volatile is commented the Rust + LLVM is allowed to make optimizations.
//
// Commit your answers (bare1_6)
//
......
......@@ -39,7 +39,7 @@ const APP: () = {
hprintln!("End {:?}", end).ok();
hprintln!("Diff {:?}", end.wrapping_sub(start)).ok();
// wait(100);
wait(100);
}
};
......@@ -71,16 +71,22 @@ fn wait(i: u32) {
// What is the output in the Adapter Output console?
// (Notice, it will take a while we loop one million times at only 16 MHz.)
//
// ** your answer here **
// Start 128543196
// End 295543279
// Diff 167000083
//
// Rebuild and run in (Cortex Release).
//
// ** your answer here **
// Start 1088552331
// End 1092552347
// Diff 4000016
//
// Compute the ratio between debug/release optimized code
// (the speedup).
//
// ** your answer here **
// Start: 128543196/1088552331 = 0,118086372459
// End: 295543279/1092552347 = 0,270507202526
// Diff: 167000083/4000016 = 41,7498537506
//
// commit your answers (bare2_1)
//
......@@ -105,7 +111,17 @@ fn wait(i: u32) {
//
// Dump generated assembly for the "wait" function.
//
// ** your answer here **
/* Dump of assembler code for function rtic_bare2::wait:
0x080004a0 <+0>: push {r7, lr}
0x080004a2 <+2>: mov r7, sp
0x080004a4 <+4>: movw r0, #16960 ; 0x4240
0x080004a8 <+8>: movt r0, #15
=> 0x080004ac <+12>: nop
0x080004ae <+14>: subs r0, #1
0x080004b0 <+16>: bne.n 0x80004ac <rtic_bare2::wait+12>
0x080004b2 <+18>: pop {r7, pc}
End of assembler dump.
*/
//
// Under the ARM calling convention, r0.. is used as arguments.
// However in this case, we se that r0 is set by the assembly instructions,
......@@ -115,7 +131,8 @@ fn wait(i: u32) {
//
// Answer in your own words, how they assign r0 to 1000000.
//
// ** your answer here **
// By combining instruction +4 and +8 we get 0xf4240 since movt is the upper 16-bit
// and movw is lower 16-bit and converting it from hexa to decimal we get 1000000.
//
// Commit your answers (bare2_2)
//
......@@ -125,10 +142,30 @@ fn wait(i: u32) {
//
// Dump the generated assembly for the "wait" function.
//
// ** your answer here **
// Dump of assembler code for function rtic_bare2::wait:
/*
0x080004a0 <+0>: push {r7, lr}
0x080004a2 <+2>: mov r7, sp
=> 0x080004a4 <+4>: nop
0x080004a6 <+6>: subs r0, #1
0x080004a8 <+8>: bne.n 0x80004a4 <rtic_bare2::wait+4>
0x080004aa <+10>: pop {r7, pc}
End of assembler dump.
*/
//
// Answer in your own words, why you believe the generated code differs?
//
// ** your answer here **
/*
To save space the compiler makes some optimizations in the code.
So wait is now compiled as a function and takes an argument in r0 instead of
just setting a value before it runs.
*/
/*
To save space the compiler makes some optimizations in the code.
So wait is now compiled as a function and takes an argument in r0 instead of
just setting a value before it runs.
*/
//
// Commit your answers (bare2_3)
......@@ -13,25 +13,35 @@
use cortex_m_semihosting::hprintln;
use panic_semihosting as _;
use rtic::cyccnt::Instant;
use rtic::cyccnt::Duration;
use stm32f4;
#[rtic::app(device = stm32f4)]
#[rtic::app(device = stm32f4, monotonic = rtic::cyccnt::CYCCNT)]
const APP: () = {
#[init]
fn init(mut cx: init::Context) {
cx.core.DWT.enable_cycle_counter();
let start = Instant::now();
//let start = Instant::elapsed(&Instant::now());
wait(1_000_000);
let end = Instant::now();
let timeElapsed = start.elapsed();
//let diff_f = Duration::as_cycles(&(end-start));
//let diff = Duration::as_cycles(&end.duration_since(start));
let diff_elapsed = Duration::as_cycles(&timeElapsed);
// notice all printing outside of the section to measure!
hprintln!("Start {:?}", start).ok();
hprintln!("End {:?}", end).ok();
// hprintln!("Diff {:?}", (end - start) ).ok();
//hprintln!("Diff {:?}", diff).ok();
//hprintln!("Diff {:?}", diff_f).ok();
hprintln!("Diff {:?}", diff_elapsed).ok();
}
};
// burns CPU cycles by just looping `i` times
#[inline(never)]
#[no_mangle]
......@@ -42,6 +52,7 @@ fn wait(i: u32) {
}
}
// 0. Setup
//
// > cargo doc --open
......@@ -62,7 +73,8 @@ fn wait(i: u32) {
//
// What is the output in the Adapter Output console?
//
// ** your answer here **
// Start Instant(47356)
// End Instant(4047373)
//
// As you see line 31 is commented out (we never print the difference).
//
......@@ -76,7 +88,9 @@ fn wait(i: u32) {
//
// What is now the output in the Adapter Output console?
//
// ** your answer here **
// Start Instant(4025484479)
// End Instant(4029484495)
// Diff 4000016
//
// Commit your answers (bare3_1)
//
......@@ -86,7 +100,9 @@ fn wait(i: u32) {
//
// What is now the output in the Adapter Output console?
//
// ** your answer here **
// Start Instant(1525994886)
// End Instant(1529994902)
// Diff 4000016
//
// Commit your answers (bare3_2)
//
......@@ -95,7 +111,9 @@ fn wait(i: u32) {
//
// What is now the output in the Adapter Output console?
//
// ** your answer here **
// Start Instant(4000822764)
// End Instant(4004822780)
// Diff 4000020
//
// Commit your answers (bare3_3)
//
......
......@@ -36,7 +36,6 @@ use address::*;
#[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)]
......@@ -83,7 +82,7 @@ const APP: () = {
//
// 1. Did you enjoy the blinking?
//
// ** your answer here **
// Yeah
//
// Now lookup the data-sheets, and read each section referred,
// 6.3.11, 8.4.1, 8.4.7
......@@ -100,12 +99,20 @@ const APP: () = {
//
// What was the error message and explain why.
//
// ** your answer here **
/*
error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
--> examples\rtic_bare4.rs:39:5
|
39 | core::ptr::read_volatile(addr as *const _)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function
|
= note: consult the function's documentation for information on how to avoid undefined behavior
*/
//
// Digging a bit deeper, why do you think `read_volatile` is declared `unsafe`.
// (https://doc.rust-lang.org/core/ptr/fn.read_volatile.html, for some food for thought )
//
// ** your answer here **
// It is not safe. You create a copy of a register without using borrow checking so Rust consider it unsafe.
//
// Commit your answers (bare4_2)
//
......@@ -118,16 +125,18 @@ const APP: () = {
//
// Why is it important that ordering of volatile operations are ensured by the compiler?
//
// ** your answer here **
// Because we are messing around with the registers and the stack in a specific way and want it to behave exactly the way we specified.
// Thats the whole point with volatile operations.
//
// Give an example in the above code, where reordering might make things go horribly wrong
// (hint, accessing a peripheral not being powered...)
//
// ** your answer here **
// When we specify a specific address we really mean that address and want to know that we get exactly that address and nothing else.
// Line 44 and 38 is places where it could be really bad if the compiler assumes something else.
//
// Without the non-reordering property of `write_volatile/read_volatile` could that happen in theory
// (argue from the point of data dependencies).
//
// ** your answer here **
// We write/read from some unwanted address and get/set the wrong information. This could lead to unwanted behaviors and is not very good.
//
// Commit your answers (bare4_3)
......@@ -11,6 +11,7 @@
extern crate cortex_m;
extern crate panic_semihosting;
//use bitvec::prelude::*; <-- Might wont to look in to this.
// C like API...
mod stm32f40x {
......@@ -58,7 +59,9 @@ mod stm32f40x {
impl VolatileCell<u32> {
#[inline(always)]
pub fn modify(&self, offset: u8, width: u8, value: u32) {
// your code here
let mut value_mut = value << 32-width;
value_mut = value_mut >> 32-width;
self.write(value_mut << offset);
}
}
......@@ -178,23 +181,28 @@ const APP: () = {
gpioa.MODER.write(r | 0b01 << (5 * 2)); // set output mode
// test_modify();
<<<<<<< HEAD
=======
test_modify();
>>>>>>> 4897099 (Did my best)
loop {
// set PA5 high
gpioa.BSRRH.write(1 << 5); // set bit, output hight (turn on led)
//gpioa.BSRRH.write(1 << 5); // set bit, output hight (turn on led)
// alternatively to set the bit high we can
// read the value, or with PA5 (bit 5) and write back
// gpioa.ODR.write(gpioa.ODR.read() | (1 << 5));
gpioa.ODR.write(gpioa.ODR.read() | (1 << 5));
wait(10_000);
// set PA5 low
gpioa.BSRRL.write(1 << 5); // clear bit, output low (turn off led)
//gpioa.BSRRL.write(1 << 5); // clear bit, output low (turn off led)
// alternatively to clear the bit we can
// read the value, mask out PA5 (bit 5) and write back
// gpioa.ODR.write(gpioa.ODR.read() & !(1 << 5));
gpioa.ODR.write(gpioa.ODR.read() & !(1 << 5));
wait(10_000);
}
}
......@@ -241,6 +249,10 @@ const APP: () = {
// What if we could automatically generate that from Vendors specifications (SVD files)?
// Wouldn't that be great?
//
<<<<<<< HEAD
// ** your answer here **
=======
// I got the first assert to work. But I don't understand the second. What are we supposed to do?
>>>>>>> 4897099 (Did my best)
//
// Commit your answers (bare5_2)
......@@ -17,9 +17,11 @@ use stm32f4xx_hal::{
prelude::*,
stm32::{self, GPIOC, RCC},
};
//original
const OFFSET: u32 = 8_000_000;
//const OFFSET: u32 = 24_000_000;
#[rtic::app(device = stm32f4xx_hal::stm32, monotonic = rtic::cyccnt::CYCCNT, peripherals = true)]
const APP: () = {
struct Resources {
......@@ -55,29 +57,32 @@ const APP: () = {
let rcc = device.RCC.constrain();
let _clocks = rcc.cfgr.freeze();
// let _clocks = rcc.cfgr.freeze();
// Set up the system clock. 48 MHz?
// let _clocks = rcc
// .cfgr
// .sysclk(48.mhz())
// .pclk1(24.mhz())
// .freeze();
// let _clocks = rcc
// .cfgr
// .sysclk(64.mhz())
// .pclk1(64.mhz())
// .pclk2(64.mhz())
// .freeze();
//
// let _clocks = rcc
// .cfgr
// .sysclk(84.mhz())
// .pclk1(42.mhz())
// .pclk2(64.mhz())
// .freeze();
let _clocks = rcc
.cfgr
.sysclk(48.mhz())
.pclk1(24.mhz())
.freeze();
/*
let _clocks = rcc
.cfgr
.sysclk(64.mhz())
.pclk1(64.mhz())
.pclk2(64.mhz())
.freeze();
*/
/*
let _clocks = rcc
.cfgr
.sysclk(84.mhz())
.pclk1(42.mhz())
.pclk2(64.mhz())
.freeze();
*/
// pass on late resources
init::LateResources {
GPIOA: device.GPIOA,
......@@ -119,10 +124,10 @@ const APP: () = {
fn clock_out(rcc: &RCC, gpioc: &GPIOC) {
// output MCO2 to pin PC9
// mco2 : SYSCLK = 0b00
//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().sysclk().mco2pre().div4() });
// power on GPIOC, RM0368 6.3.11
rcc.ahb1enr.modify(|_, w| w.gpiocen().set_bit());
......@@ -132,12 +137,12 @@ 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());
// otyper reset state push/pull, in reset state (don't need to change)
// ospeedr 0b11 = very high speed
gpioc.ospeedr.modify(|_, w| w.ospeedr9().bits(0b11));
gpioc.ospeedr.modify(|_, w| w.ospeedr9().medium_speed());
}
// 0. Background reading:
......@@ -202,7 +207,7 @@ fn clock_out(rcc: &RCC, gpioc: &GPIOC) {
//
// `rcc.cfgr.sysclk(64.mhz()).pclk1(64.mhz()).pclk2(64.mhz()).freeze()`;
//
// ** your answer here **
// pclk1 is restricted to not run faster than 48 mHz
//
// `rcc.cfgr.sysclk(84.mhz()).pclk1(42.mhz()).pclk2(64.mhz()).freeze();`
//
......@@ -217,7 +222,8 @@ fn clock_out(rcc: &RCC, gpioc: &GPIOC) {
//
// What happens?
//
// ** your answer here **
// I get the error "Frequency searched for is out of range for this VOS range
// when changing PCLK1 from 32 to 64
//
// Try to setup the clock according to:
//
......@@ -225,7 +231,7 @@ fn clock_out(rcc: &RCC, gpioc: &GPIOC) {
//
// `rcc.cfgr.sysclk(84.mhz()).pclk1(42.mhz()).pclk2(64.mhz()).freeze();`
//
// ** your answer here **
// When I chnage pclk2 to 64 the other sysclk chnages to 64 and pclk1 changes to 32.
//
// Commit your answers (bare6_0)
//
......@@ -237,7 +243,7 @@ fn clock_out(rcc: &RCC, gpioc: &GPIOC) {
//
// What is the (default) MCU (SYSCLK) frequency?
//
// ** your answer here **
// 16 Mhz
//
// What is the (default) DWT CYCCNT frequency?
//
......@@ -245,7 +251,7 @@ fn clock_out(rcc: &RCC, gpioc: &GPIOC) {
//
// What is the frequency of blinking?
//
// ** your answer here **
// 1 Hz
//
// Commit your answers (bare6_1)
//
......@@ -254,11 +260,11 @@ fn clock_out(rcc: &RCC, gpioc: &GPIOC) {
//
// Compute the value of SYSCLK based on the oscilloscope reading
//
// ** your answer here **
// 3.91 MHz
//
// What is the peak to peak (voltage) reading of the signal?
//
// ** your answer here **
// 5.4 - 5.6 V or 4.7 - 4.8 V
//
// Make a folder called "pictures" in your git project.
// Make a screen dump or photo of the oscilloscope output.
......@@ -271,7 +277,7 @@ fn clock_out(rcc: &RCC, gpioc: &GPIOC) {
//`
// What is the frequency of blinking?
//
// ** your answer here **
// 3 Hz (ociloscope: 11.9 MHz or 12 MHz)
//
// Now change the constant `OFFSET` so you get the same blinking frequency as in 1.
// Test and validate that you got the desired behavior.
......@@ -282,15 +288,15 @@ fn clock_out(rcc: &RCC, gpioc: &GPIOC) {
//
// What is the frequency of MCO2 read by the oscilloscope?
//
// ** your answer here **
// 12 MHz
//
// Compute the value of SYSCLK based on the oscilloscope reading.
//
// ** your answer here **
// 12 * 4 = 48 MHz (roughly rounded)
//
// What is the peak to peak reading of the signal?
//
// ** your answer here **
// 4.9 V
//
// Make a screen dump or photo of the oscilloscope output.
// Save the the picture as "bare_6_48mhz_high_speed".
......@@ -325,11 +331,13 @@ fn clock_out(rcc: &RCC, gpioc: &GPIOC) {
//
// Did the frequency change in comparison to assignment 5?
//
// ** your answer here **
// No. It is the same.
//
// What is the peak to peak reading of the signal (and why did it change)?
//
// ** your answer here **
// 3.58 - 3.6 V. Since the speed of the signal is lowered the the amount af volt will be lowered since the
// duty scycle is reduced. If we increase the speed further the volt increas and decrease if the speed is even
// lowered.
//
// Make a screen dump or photo of the oscilloscope output.
// Save the the picture as "bare_6_48mhz_low_speed".
......@@ -342,11 +350,11 @@ fn clock_out(rcc: &RCC, gpioc: &GPIOC) {
//
// Does the code compile?
//
// ** your answer here **
// Yes, but it panics.
//
// What happens at run-time?
//
// ** your answer here **
// It panics.
//
// Try setting the clocks according to:
//
......@@ -354,14 +362,16 @@ fn clock_out(rcc: &RCC, gpioc: &GPIOC) {
//
// Does the code compile?
//
// ** your answer here **
// Yes.
//
// What happens at run-time?
//
// ** your answer here **
// It runs.
//
// Is that a correct?
//
// Yes, I suppose?
//
// Optional: If you find it incorrect, file an issue to `stm32f4xx-hal` describing the problem.
// (Remember always check already open issues, and add to existing if related.)
//
......
......@@ -17,7 +17,7 @@ use stm32f4xx_hal::{
gpio::{gpioa::PA5, Output, PushPull},
prelude::*,
};
;
use embedded_hal::digital::v2::{OutputPin, ToggleableOutputPin};
const OFFSET: u32 = 8_000_000;
......@@ -27,7 +27,8 @@ const APP: () = {
struct Resources {
// late resources
GPIOA: stm32::GPIOA,
// led: PA5<Output<PushPull>>,
led: PA5<Output<PushPull>>,
}
#[init(schedule = [toggle])]
fn init(cx: init::Context) -> init::LateResources {
......@@ -37,6 +38,7 @@ const APP: () = {
let mut core = cx.core;
let device = cx.device;
// Initialize (enable) the monotonic timer (CYCCNT)
core.DCB.enable_trace();
core.DWT.enable_cycle_counter();
......@@ -50,15 +52,18 @@ const APP: () = {
// power on GPIOA, RM0368 6.3.11
device.RCC.ahb1enr.modify(|_, w| w.gpioaen().set_bit());
// configure PA5 as output, RM0368 8.4.1
// configure PA5 as output, 8.4.1
device.GPIOA.moder.modify(|_, w| w.moder5().bits(1));
// pass on late resources
init::LateResources {
GPIOA: device.GPIOA,
led: ,
}
}
#[idle]
fn idle(_cx: idle::Context) -> ! {
rprintln!("idle");
......@@ -67,7 +72,7 @@ const APP: () = {
}
}
#[task(resources = [GPIOA], schedule = [toggle])]
#[task(resources = [led], schedule = [toggle])]
fn toggle(cx: toggle::Context) {
static mut TOGGLE: bool = false;
rprintln!("toggle @ {:?}", Instant::now());
......
......@@ -14,6 +14,7 @@ const APP: () = {
struct Resources {
// late resources
GPIOA: stm32::GPIOA,
GPIOC: stm32::GPIOC,
}
#[init(schedule = [toggle])]
fn init(cx: init::Context) -> init::LateResources {
......@@ -41,9 +42,11 @@ const APP: () = {
// configure PA5 as output, RM0368 8.4.1
device.GPIOA.moder.modify(|_, w| w.moder5().bits(1));
device.GPIOC.moder.modify(|_, w| w.moder13().bits(0));
// pass on late resources
init::LateResources {
GPIOA: device.GPIOA,
GPIOC: device.GPIOC,
}
}
......@@ -54,6 +57,7 @@ const APP: () = {
continue;
}
}
read_bit();
#[task(resources = [GPIOA], schedule = [toggle])]
fn toggle(cx: toggle::Context) {
......