move reports to git
This commit is contained in:
commit
7b622c2577
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
[submodule "wiki"]
|
||||
path = wiki
|
||||
url = https://bitbucket.org/HR_ELEKTRO/rts10.git/wiki
|
||||
BIN
assets/opdr_2_1.zip
Normal file
BIN
assets/opdr_2_1.zip
Normal file
Binary file not shown.
BIN
assets/opdr_2_2.zip
Normal file
BIN
assets/opdr_2_2.zip
Normal file
Binary file not shown.
256
report-1/assambly_assignments.md
Normal file
256
report-1/assambly_assignments.md
Normal file
@ -0,0 +1,256 @@
|
||||
---
|
||||
path: /elektro/hr/rts10/
|
||||
tags: kladjes, elektro, elektro/hr, elektro/hr/rts10
|
||||
auther:
|
||||
- Finley van Reenen (0964590@hr.nl)
|
||||
auther_short: "E.L.F. van Reenen"
|
||||
---
|
||||
|
||||
# Assembly Assignments
|
||||
|
||||
This is the first report for _realtime systems 10_. I needed to do the following assignments:
|
||||
|
||||
- Assignment 1: Testing a simple LEGv7 Pinky program
|
||||
- Assignment 2: Writing a simple multiplication program
|
||||
- Assignment 3: A smarter multiply algorithm
|
||||
- Assignment 10: Using your multiply function to calculate the dot product of two vectors
|
||||
|
||||
## Assignment 1: Testing a simple LEGv7 Pinky program
|
||||
|
||||
First is getting a very basic example/base project to compile and run. The university supplied a zip file with a preconfigured project. I imported it into _STM Cube IDE_ and tried to debug.
|
||||
|
||||
First I got a message to update the debugger firmware. After doing this, I still got an error. It could not determine the GDB version.
|
||||
|
||||

|
||||
|
||||
Last year I also had problems with GDB, but that time it was because it could not find the Windows version while I'm on Linux. Looking at the command, it does look like the usual Linux command.
|
||||
In the terminal this command is not found. After searching around on my system, I found it in the install directory from the IDE. Running the command on this executable gave the exact same error as the popup gave.
|
||||
|
||||
I have ncruses 6.5 installed, but version 5 is requested. I installed the older version and tried it again. Now I get the same error as last year.
|
||||
|
||||

|
||||
|
||||
I applied the same fix as last year. In the debug config, replace the `\` with an `/` and remove the `.exe` in the path to the OpenOCD command. This fixed the problem that the debugger successfully stated.
|
||||
|
||||

|
||||
|
||||
## Assignment 2: Writing a simple multiplication program
|
||||
|
||||
The algorithm in question is given in C code.
|
||||
|
||||
```c-like=
|
||||
unsigned int multiply(unsigned int a , unsigned int b)
|
||||
{
|
||||
unsigned int m = 0;
|
||||
for (unsigned int i = 0; i != a; i ++)
|
||||
{
|
||||
m = m + b;
|
||||
}
|
||||
return m;
|
||||
}
|
||||
```
|
||||
|
||||
This code can be simplified without changing the algorithm by replacing the variable `i` with `b`. This will result in the following code.
|
||||
|
||||
```c-like=
|
||||
unsigned int multiply ( unsigned int a , unsigned int b)
|
||||
{
|
||||
unsigned int m = 0;
|
||||
for (; b > 0; b --)
|
||||
{
|
||||
m = m + a;
|
||||
}
|
||||
return m;
|
||||
}
|
||||
```
|
||||
|
||||
This is also the code I have implemented. The compiler puts _a_ in `R0` and _b_ in `R1`, I accepted them in place and used `R2` for _m_. At the end _m_ (`R2`) is moved to `R0` to set it as the return value.
|
||||
|
||||
```ass=
|
||||
.cpu cortex-m4
|
||||
.thumb
|
||||
.syntax unified
|
||||
.globl multiply
|
||||
.text
|
||||
.thumb_func
|
||||
multiply:
|
||||
MOVS.N R2, #0 // set m to 0
|
||||
CMP.N R1, #0
|
||||
BEQ.N mul_exit // goto mul_exit if b == 0
|
||||
mul_loop:
|
||||
ADDS.N R2, R0, R2 // add a to m
|
||||
SUBS.N R1, #1 // substract 1 from b
|
||||
BNE.N mul_loop // goto mul_loop if b != 0
|
||||
mul_exit:
|
||||
MOVS.N R0, R2 // move m to R0
|
||||
BX.N LR
|
||||
```
|
||||
|
||||
a better representation of the essembly code in C would be:
|
||||
|
||||
```c-like=
|
||||
unsigned int multiply ( unsigned int a , unsigned int b)
|
||||
{
|
||||
unsigned int m = 0;
|
||||
if (b == 0) {
|
||||
return m;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
m = m + b;
|
||||
b --;
|
||||
} while (b > 0)
|
||||
|
||||
return m;
|
||||
}
|
||||
```
|
||||
|
||||

|
||||
|
||||
|
||||
> How many instructions does it take your procedure to run the code: `multiply(65535, 65535)`?
|
||||
|
||||
It does not take the branch at line 10 and at line 14 it takes the branch 65535 times. There are 3 instructions in this loop and 5 outside it, so $3\cdot 65535 + 5 = 196610$ instructions.
|
||||
|
||||
## Assignment 3: A smarter multiply algorithm
|
||||
|
||||
Now a smarter version.
|
||||
|
||||
```c-like=
|
||||
unsigned int multiply(unsigned int a , unsigned int b)
|
||||
{
|
||||
unsigned int m = 0;
|
||||
while (b != 0)
|
||||
{
|
||||
if ((b & 1) == 1) /* b is odd */
|
||||
{
|
||||
m = m + a;
|
||||
}
|
||||
a = a << 1;
|
||||
b = b >> 1;
|
||||
}
|
||||
return m;
|
||||
}
|
||||
```
|
||||
|
||||
```asm=
|
||||
.cpu cortex-m4
|
||||
.thumb
|
||||
.syntax unified
|
||||
.globl better_multiply
|
||||
.text
|
||||
.thumb_func
|
||||
// R0 = a, R1 = b, R2 = result (m), R3 = bitmask or odd/even bit
|
||||
better_multiply:
|
||||
MOVS.N R2, #0 // set m to 0
|
||||
CMP.N R1, #0
|
||||
BEQ.N bmul_exit // goto bmul_exit if b == 0
|
||||
bmul_while:
|
||||
MOVS.N R3, #1 // set R3 to 1 as bit mask
|
||||
ANDS.N R3, R1 // and R3 (bit mask) with b
|
||||
BEQ.N bmul_even // goto even if result is 0
|
||||
ADDS.N R2, R0 // add a to m
|
||||
bmul_even:
|
||||
LSLS.N R0, R0, #1 // a = a << 1
|
||||
LSRS.N R1, R1, #1 // b = b >> 1
|
||||
BNE.N bmul_while // goto while if b != 0
|
||||
bmul_exit:
|
||||
MOVS.N R0, R2 // move m to R0
|
||||
BX.N LR
|
||||
```
|
||||
|
||||
a better representation of the essembly code in C would be:
|
||||
|
||||
```c-like=
|
||||
unsigned int multiply ( unsigned int a , unsigned int b)
|
||||
{
|
||||
unsigned int m = 0;
|
||||
if (b == 0) {
|
||||
return m;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
unsigned int t = 1;
|
||||
if ((b & t) != 0) {
|
||||
m += a;
|
||||
}
|
||||
a = a << 1;
|
||||
b = b >> 1;
|
||||
} while (b != 0)
|
||||
|
||||
return m;
|
||||
}
|
||||
```
|
||||
|
||||

|
||||
|
||||
> How many instructions does it take your procedure to run the code: `multiply(65535, 65535)`?
|
||||
|
||||
There are 7 instructions in the loop where one only runs every `1` bit in `b`. The loop only runs every bit in `b` until it's zero. In this case `b` is $65535$ or 16 ones in a row in binary. The full 7 instructions run 16 times plus the 5 instructions outside the loop. In total it's $16\cdot 7+5=117$ instructions. This is about 1680 times less instructions than the other algarium.
|
||||
|
||||
## Assignment 10: Using your multiply function to calculate the dot product of two vectors
|
||||
|
||||
```c-like=
|
||||
unsigned int dotProduct(unsigned int a[], unsigned int b[], size_t n)
|
||||
{
|
||||
unsigned int p = 0;
|
||||
for (size_t i = 0; i != n; i++)
|
||||
{
|
||||
p = p + multiply (a[i], b[i]);
|
||||
}
|
||||
return p;
|
||||
}
|
||||
```
|
||||
|
||||
This function needs to call another and remember 5 variables (`*a`, `*b`, `n`, `p` and `i`). `R0` through `R3` are expected to change with a function call. There are only `R4` through `R7` left, only four spots. To solve this problem, I reversed the for loop by using n and decrementing it. This will not change the result since addition is not order sensitive. The code I implemented is the following.
|
||||
|
||||
```c-like=
|
||||
unsigned int dotProduct(unsigned int a[] , unsigned int b[], size_t n)
|
||||
{
|
||||
unsigned int p = 0;
|
||||
if (n == 0) {
|
||||
return p;
|
||||
}
|
||||
unsigned int i = n;
|
||||
do
|
||||
{
|
||||
i--;
|
||||
p = p + multiply(a[i], b[i]);
|
||||
} while (i != 0)
|
||||
return p;
|
||||
}
|
||||
```
|
||||
|
||||
My assembly code:
|
||||
|
||||
```asm=
|
||||
.cpu cortex-m4
|
||||
.thumb
|
||||
.syntax unified
|
||||
.globl dot_product
|
||||
.text
|
||||
.thumb_func
|
||||
// R4 = a, R5 = b, R6 = i, R7 = p (result)
|
||||
dot_product:
|
||||
PUSH.N {R4, R5, R6, R7, LR}
|
||||
MOVS.N R4, R0 // move *a to R4
|
||||
MOVS.N R5, R1 // move *b to R5
|
||||
MOVS.N R7, #0 // set p to 0
|
||||
MOVS.N R0, R2 // move n to R0
|
||||
MOVS.N R1, #4 // set R1 to 4
|
||||
BLX.N =better_multiply // n * 4
|
||||
MOVS.N R6, R0 // move result to R6
|
||||
dotp_loop:
|
||||
SUBS.N R6, R6, #4 // i = i - 4
|
||||
LDR.N R0, [R4,R6] // load a[i] to R0
|
||||
LDR.N R1, [R5,R6] // load b[i] to R1
|
||||
BLX.N =better_multiply
|
||||
ADDS.N R7, R7, R0 // p = p + result
|
||||
BNE.N dotp_loop // goto dotp_loop if i != 0
|
||||
dotp_exit:
|
||||
MOVS.N R0, R7 // move m to R0
|
||||
POP.N {R4, R5, R6, R7, PC}
|
||||
BX.N LR
|
||||
```
|
||||
162
report-1/week_1.2.md
Normal file
162
report-1/week_1.2.md
Normal file
@ -0,0 +1,162 @@
|
||||
---
|
||||
path: /elektro/hr/rts10/
|
||||
tags: kladjes, elektro, elektro/hr, elektro/hr/rts10
|
||||
auther:
|
||||
- Finley van Reenen (0964590@hr.nl)
|
||||
auther_short: "E.L.F. van Reenen"
|
||||
---
|
||||
|
||||
# Report Week 1.2
|
||||
|
||||
## volatile
|
||||
|
||||
`volatile` is a keyword in c to specify to the comiler it soult not optimize the variable away. This can be usfull for debugging perpeses, if a it is used somewhere the compiler does not reconize or (for example hardwere registers). I learnd this form colleagues on my internship at Erisk.
|
||||
|
||||
## assignment 2.2
|
||||
|
||||
> will in line 14 and 21^[line numerbers differ from the assignment, becouse change longer lines te prevent linewrapping] to alternate the green and red with oragne and blue.
|
||||
|
||||
The pinout is as followed
|
||||
|
||||
orange: port D bit 13
|
||||
green: port D bit 12
|
||||
red: port D bit 14
|
||||
blue: port D bit 15
|
||||
|
||||
Bit 12 and 14 sould start different as bit 13 and 15. Then invert all four bits every loop to achees the assignment.
|
||||
|
||||
I found the defines in the sourcefile where the _modder_ defines are defined.
|
||||
|
||||
```c-like=
|
||||
#include <stdint.h>
|
||||
#include <stm32f4xx.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
// GPIO Port D Clock Enable
|
||||
RCC->AHB1ENR = RCC_AHB1ENR_GPIODEN;
|
||||
// GPIO Port D Pin 15 down to 12 Push/Pull Output
|
||||
GPIOD->MODER = GPIO_MODER_MODER12_0
|
||||
| GPIO_MODER_MODER13_0
|
||||
| GPIO_MODER_MODER14_0
|
||||
| GPIO_MODER_MODER15_0;
|
||||
// Set green and red LEDs
|
||||
GPIOD->ODR = GPIO_ODR_OD12 | GPIO_ODR_OD14;
|
||||
// Do forever:
|
||||
while (1)
|
||||
{
|
||||
// Wait a moment
|
||||
for (volatile int32_t i = 0; i < 1000000; i++);
|
||||
// Flip all LEDs
|
||||
GPIOD->ODR ^= GPIO_ODR_OD12
|
||||
| GPIO_ODR_OD13
|
||||
| GPIO_ODR_OD14
|
||||
| GPIO_ODR_OD15;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
> How is the assambly generated for line 9 compeard to the magic value `0x55000000`
|
||||
|
||||
The compiler regonizes that it can calculate the or opperations at compile time becouse it only used compile time defines as inputs. This reults in the foloing line of assambly.
|
||||
|
||||
```asm
|
||||
mov.w r2, #1426063360 @ 0x55000000
|
||||
```
|
||||
|
||||
## assignment 2.3
|
||||
|
||||
skiped
|
||||
|
||||
## assignment 2.4
|
||||
|
||||
skiped
|
||||
|
||||
## assignment 2.5
|
||||
|
||||
> Copy the project from assignment 2.2 and update the clock to use the $8 MHz$ external cristal (HSE).
|
||||
|
||||
I added line 6 throw 15, the rest is uncheached.
|
||||
|
||||
```c-like=
|
||||
#include <stdint.h>
|
||||
#include <stm32f4xx.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
// Enable HSE
|
||||
RCC->CR |= RCC_CR_HSEON;
|
||||
// Wait until HSE is stable
|
||||
while ((RCC->CR & RCC_CR_HSERDY) == 0);
|
||||
// Select HSE as the system clock
|
||||
RCC->CFGR |= RCC_CFGR_SW_HSE;
|
||||
// Wait until HSE used as the system clock
|
||||
while ((RCC->CFGR & RCC_CFGR_SWS_HSE ) == 0);
|
||||
// Disable HSI
|
||||
RCC->CR &= ~RCC_CR_HSION;
|
||||
|
||||
|
||||
// GPIO Port D Clock Enable
|
||||
RCC->AHB1ENR = RCC_AHB1ENR_GPIODEN;
|
||||
// GPIO Port D Pin 15 down to 12 Push/Pull Output
|
||||
GPIOD->MODER = GPIO_MODER_MODER12_0
|
||||
| GPIO_MODER_MODER13_0
|
||||
| GPIO_MODER_MODER14_0
|
||||
| GPIO_MODER_MODER15_0;
|
||||
// Set green and red LEDs
|
||||
GPIOD->ODR = GPIO_ODR_OD12 | GPIO_ODR_OD14;
|
||||
// Do forever:
|
||||
while (1)
|
||||
{
|
||||
// Wait a moment
|
||||
for (volatile int32_t i = 0; i < 1000000; i++);
|
||||
// Flip all LEDs
|
||||
GPIOD->ODR ^= GPIO_ODR_OD12
|
||||
| GPIO_ODR_OD13
|
||||
| GPIO_ODR_OD14
|
||||
| GPIO_ODR_OD15;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
I mesured the toggle time to be around 1.5 seconsds. This is what is expected.
|
||||
|
||||
> Make use of the PLL to acheef a CPU clock of $100MHz$.
|
||||
|
||||
First the power modules needs to be configured to allow for the hige clockspeed.
|
||||
|
||||
```c-like
|
||||
// enable power control
|
||||
RCC->APB1ENR |= RCC_APB1ENR_PWREN;
|
||||
// set voltage to support 100 MHz
|
||||
PWR->CR |= PWR_CR_VOS_0 | PWR_CR_VOS_1;
|
||||
```
|
||||
|
||||
Now the flash latancy is set. The powersupply on the board is $3V$. This means there sould be 3 wait states.
|
||||
|
||||

|
||||
|
||||
```c-like
|
||||
// set flash latency to support 100 MHz
|
||||
FLASH->ACR |= FLASH_ACR_LATENCY_3WS;
|
||||
// Wait until the wait states are used
|
||||
while ((FLASH->ACR & /* ... */ ) == 0);
|
||||
```
|
||||
|
||||
Finaly we configur the PLL itself.
|
||||
|
||||
$$
|
||||
f_{(VCO\ clock)} = f_{(PLL\ clock\ input)} \cdot (\frac{PLLN}{PLLM}) \\
|
||||
f_{(PLL\ general\ clock\ output)} = \frac{f_{(VCO\ clock)}}{PLLP}
|
||||
$$
|
||||
|
||||
$f_{(PLL\ clock\ input)} = 8 MHz$
|
||||
$f_{(PLL\ general\ clock\ output)} = 100 MHz$
|
||||
$100 MHz \leq f_{(VCO\ clock)} \leq 432 MHz$
|
||||
$PLLP \rightarrow \{2, 4, 6, 8\}$
|
||||
$50 \leq PLLN \leq 432$
|
||||
$2 \leq PLLM \leq 63$
|
||||
|
||||
Becouse of the liminitan of $PLLP$, $f_{(VCO\ clock)}$ can only be 200 or 400 MHz to acheve the correct $f_{(PLL\ general\ clock\ output)}$.
|
||||
|
||||
...
|
||||
386
report-2/week_1.3.md
Normal file
386
report-2/week_1.3.md
Normal file
@ -0,0 +1,386 @@
|
||||
---
|
||||
sub_title: "Real Time Systems 10"
|
||||
auther:
|
||||
- name: "Finley van Reenen"
|
||||
email: "mail@lailatheelf.nl"
|
||||
name_short: "E.L.F. van Reenen"
|
||||
---
|
||||
|
||||
# Week 1.3
|
||||
|
||||
## assignment 3.1
|
||||
|
||||
base project [opdr_2_1](/assets/opdr_2_1.zip).
|
||||
|
||||
```c
|
||||
#include <stdint.h>
|
||||
|
||||
#define RCC_AHB1ENR_BIT_GPIODEN *(volatile uint32_t*)(0x42000000 + 0x00023830 * 32 + 3 * 4)
|
||||
#define GPIOD_BASE 0x40020C00
|
||||
#define GPIOD_MODER *(volatile uint32_t*)(GPIOD_BASE + 0x00)
|
||||
#define GPIOD_ODR *(volatile uint32_t*)(GPIOD_BASE + 0x14)
|
||||
|
||||
#define STK_CTRL *(volatile uint32_t*)(0xE000E010)
|
||||
#define STK_LOAD *(volatile uint32_t*)(0xE000E014)
|
||||
|
||||
int main(void)
|
||||
{
|
||||
// GPIO Port D Clock Enable
|
||||
RCC_AHB1ENR_BIT_GPIODEN = 1;
|
||||
// GPIO Port D Pin 15 down to 12 Push/Pull Output
|
||||
GPIOD_MODER = 0x55000000;
|
||||
// Set green and red LEDs
|
||||
GPIOD_ODR = 0x5000;
|
||||
|
||||
// SysTick enable with clk source to AHB/8
|
||||
STK_CTRL = (1<<2) | 1;
|
||||
STK_LOAD = 500000; // 0.5 sec / (8 MHz / 8)
|
||||
// Do forever:
|
||||
while (1)
|
||||
{
|
||||
// Wait a moment
|
||||
while ((STK_CTRL & (1 << 16)) == 0);
|
||||
// Flip all LEDs
|
||||
GPIOD_ODR ^= 0xF000;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## assignment 3.2
|
||||
|
||||
```c
|
||||
#include <stdint.h>
|
||||
#include <stm32f4xx.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
// GPIO Port D Clock Enable
|
||||
RCC->AHB1ENR = RCC_AHB1ENR_GPIODEN;
|
||||
// GPIO Port D Pin 15 down to 12 Push/Pull Output
|
||||
GPIOD->MODER = GPIO_MODER_MODER12_0
|
||||
| GPIO_MODER_MODER13_0
|
||||
| GPIO_MODER_MODER14_0
|
||||
| GPIO_MODER_MODER15_0;
|
||||
// Set green and red LEDs
|
||||
GPIOD->ODR = GPIO_ODR_OD12 | GPIO_ODR_OD14;
|
||||
|
||||
// SysTick enable with clk source to AHB/8
|
||||
SysTick->CTRL = SysTick_CTRL_ENABLE_Msk;
|
||||
SysTick->LOAD = 500000; // 0.5 sec / (8 MHz / 8)
|
||||
|
||||
// Do forever:
|
||||
while (1)
|
||||
{
|
||||
// Wait a moment
|
||||
while ((SysTick->CTRL & (1 << 16)) == 0);
|
||||
// Flip all LEDs
|
||||
GPIOD->ODR ^= GPIO_ODR_OD12
|
||||
| GPIO_ODR_OD13
|
||||
| GPIO_ODR_OD14
|
||||
| GPIO_ODR_OD15;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## assignment 3.3
|
||||
|
||||
```c
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#define RCC_AHB1ENR_BIT_GPIODEN *(volatile uint32_t*)(0x42000000 + 0x00023830 * 32 + 3 * 4)
|
||||
#define GPIOD_BASE 0x40020C00
|
||||
#define GPIOD_MODER *(volatile uint32_t*)(GPIOD_BASE + 0x00)
|
||||
#define GPIOD_ODR *(volatile uint32_t*)(GPIOD_BASE + 0x14)
|
||||
|
||||
#define STK_CTRL *(volatile uint32_t*)(0xE000E010)
|
||||
#define STK_LOAD *(volatile uint32_t*)(0xE000E014)
|
||||
|
||||
volatile bool flag = false;
|
||||
|
||||
void SysTick_Handler()
|
||||
{
|
||||
flag = true;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
// GPIO Port D Clock Enable
|
||||
RCC_AHB1ENR_BIT_GPIODEN = 1;
|
||||
// GPIO Port D Pin 15 down to 12 Push/Pull Output
|
||||
GPIOD_MODER = 0x55000000;
|
||||
// Set green and red LEDs
|
||||
GPIOD_ODR = 0x5000;
|
||||
|
||||
// SysTick enable with interupt and clk source to AHB/8
|
||||
STK_CTRL = (1<<1) | 1;
|
||||
STK_LOAD = 500000; // 0.5 sec / (8 MHz / 8)
|
||||
// Do forever:
|
||||
while (1)
|
||||
{
|
||||
// Wait a moment
|
||||
while (!flag)
|
||||
{
|
||||
__asm__(" WFI"); // sleep until SysTick
|
||||
}
|
||||
flag = false;
|
||||
// Flip all LEDs
|
||||
GPIOD_ODR ^= 0xF000;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
> C) Why must the flag variable be defined as volatile?
|
||||
|
||||
becouse the compiler doesn't know when `flag` changes. Without `volatile` optimisations can think it does not change at all.
|
||||
|
||||
|
||||
|
||||
## assignment 3.4
|
||||
|
||||
```c
|
||||
#include <stdint.h>
|
||||
#include <stm32f4xx.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
volatile bool flag = false;
|
||||
|
||||
void SysTick_Handler()
|
||||
{
|
||||
flag = true;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
// GPIO Port D Clock Enable
|
||||
RCC->AHB1ENR = RCC_AHB1ENR_GPIODEN;
|
||||
// GPIO Port D Pin 15 down to 12 Push/Pull Output
|
||||
GPIOD->MODER = GPIO_MODER_MODER12_0
|
||||
| GPIO_MODER_MODER13_0
|
||||
| GPIO_MODER_MODER14_0
|
||||
| GPIO_MODER_MODER15_0;
|
||||
// Set green and red LEDs
|
||||
GPIOD->ODR = GPIO_ODR_OD12 | GPIO_ODR_OD14;
|
||||
|
||||
// SysTick enable with interupt and clk source to AHB/8
|
||||
SysTick->CTRL = SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk;
|
||||
SysTick->LOAD = 500000; // 0.5 sec / (8 MHz / 8)
|
||||
|
||||
// Do forever:
|
||||
while (1)
|
||||
{
|
||||
// Wait a moment
|
||||
while (!flag)
|
||||
{
|
||||
__asm__(" WFI"); // sleep until SysTick
|
||||
}
|
||||
flag = false;
|
||||
// Flip all LEDs
|
||||
GPIOD->ODR ^= GPIO_ODR_OD12
|
||||
| GPIO_ODR_OD13
|
||||
| GPIO_ODR_OD14
|
||||
| GPIO_ODR_OD15;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## assignment 3.5
|
||||
|
||||
```c
|
||||
#include <stdint.h>
|
||||
#include <stm32f4xx.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
volatile bool flag = false;
|
||||
|
||||
void SysTick_Handler()
|
||||
{
|
||||
flag = true;
|
||||
}
|
||||
|
||||
enum STATE {
|
||||
STATE_GREEN,
|
||||
STATE_ORANGE,
|
||||
STATE_RED
|
||||
};
|
||||
|
||||
int main(void)
|
||||
{
|
||||
// GPIO Port D Clock Enable
|
||||
RCC->AHB1ENR = RCC_AHB1ENR_GPIODEN;
|
||||
// GPIO Port D Pin 15 down to 12 Push/Pull Output
|
||||
GPIOD->MODER = GPIO_MODER_MODER12_0
|
||||
| GPIO_MODER_MODER13_0
|
||||
| GPIO_MODER_MODER14_0
|
||||
| GPIO_MODER_MODER15_0;
|
||||
// Set green and red LEDs
|
||||
GPIOD->ODR = GPIO_ODR_OD12 | GPIO_ODR_OD14;
|
||||
|
||||
// SysTick enable with interupt and clk source to AHB/8
|
||||
SysTick->CTRL = SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk;
|
||||
SysTick->LOAD = 500000; // 0.5 sec / (8 MHz / 8)
|
||||
|
||||
// time of each color in half seconds
|
||||
const uint32_t time_green = 10; // 5 seconds
|
||||
const uint32_t time_orange = 2; // 1 seconds
|
||||
const uint32_t time_red = 8; // 4 seconds
|
||||
|
||||
uint32_t timer = time_green;
|
||||
enum STATE State = STATE_GREEN;
|
||||
|
||||
// Do forever:
|
||||
while (1)
|
||||
{
|
||||
// Wait a moment
|
||||
while (!flag)
|
||||
{
|
||||
__asm__(" WFI"); // sleep until SysTick
|
||||
}
|
||||
flag = false;
|
||||
|
||||
timer--;
|
||||
if (timer == 0)
|
||||
{
|
||||
// turn off all leds
|
||||
GPIOD->ODR &= ~(GPIO_ODR_OD12
|
||||
| GPIO_ODR_OD13
|
||||
| GPIO_ODR_OD14
|
||||
| GPIO_ODR_OD15);
|
||||
switch (State) {
|
||||
case STATE_GREEN:
|
||||
State = STATE_ORANGE;
|
||||
GPIOD->ODR |= GPIO_ODR_OD13;
|
||||
timer = time_orange;
|
||||
break;
|
||||
case STATE_ORANGE:
|
||||
State = STATE_RED;
|
||||
GPIOD->ODR |= GPIO_ODR_OD14;
|
||||
timer = time_red;
|
||||
break;
|
||||
case STATE_RED:
|
||||
State = STATE_GREEN;
|
||||
GPIOD->ODR |= GPIO_ODR_OD12;
|
||||
timer = time_green;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## assignment 3.6
|
||||
|
||||
```c
|
||||
#include <stdint.h>
|
||||
#include <stm32f4xx.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
volatile uint32_t ISR_Ticks = 0;
|
||||
|
||||
struct TASK {
|
||||
void* fn,
|
||||
uint32_t counter,
|
||||
uint32_t counter_rst
|
||||
};
|
||||
|
||||
uint8_t Tasks_len = 0;
|
||||
struct TASK Tasks[8];
|
||||
|
||||
void SysTick_Handler()
|
||||
{
|
||||
ISR_Ticks++;
|
||||
}
|
||||
|
||||
bool addTask(void* fn, uint32_t counter)
|
||||
{
|
||||
if (Tasks_len >= 8) {
|
||||
return false;
|
||||
}
|
||||
Tasks[Task_len].fn = fn;
|
||||
Tasks[Task_len].counter = counter;
|
||||
Tasks[Task_len].counter_rst = counter;
|
||||
Tasks_len++;
|
||||
return true;
|
||||
}
|
||||
|
||||
void taskGreen()
|
||||
{
|
||||
GPIOD->ODR ^= GPIO_ODR_OD12;
|
||||
}
|
||||
|
||||
void taskOrange()
|
||||
{
|
||||
GPIOD->ODR ^= GPIO_ODR_OD13;
|
||||
}
|
||||
|
||||
void taskRed()
|
||||
{
|
||||
GPIOD->ODR ^= GPIO_ODR_OD14;
|
||||
}
|
||||
|
||||
void taskBlue()
|
||||
{
|
||||
GPIOD->ODR ^= GPIO_ODR_OD15;
|
||||
}
|
||||
|
||||
enum STATE {
|
||||
STATE_GREEN,
|
||||
STATE_ORANGE,
|
||||
STATE_RED
|
||||
};
|
||||
|
||||
int main(void)
|
||||
{
|
||||
// GPIO Port D Clock Enable
|
||||
RCC->AHB1ENR = RCC_AHB1ENR_GPIODEN;
|
||||
// GPIO Port D Pin 15 down to 12 Push/Pull Output
|
||||
GPIOD->MODER = GPIO_MODER_MODER12_0
|
||||
| GPIO_MODER_MODER13_0
|
||||
| GPIO_MODER_MODER14_0
|
||||
| GPIO_MODER_MODER15_0;
|
||||
// Set all leds off
|
||||
GPIOD->ODR = 0;
|
||||
|
||||
|
||||
// SysTick enable with interupt and clk source to AHB/8
|
||||
SysTick->CTRL = SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk;
|
||||
SysTick->LOAD = 1000; // 1 ms / (8 MHz / 8)
|
||||
|
||||
addTask(*taskGreen, 200);
|
||||
addTask(*taskOrange, 500);
|
||||
addTask(*taskRed, 750);
|
||||
addTask(*taskBlue, 300);
|
||||
|
||||
// Do forever:
|
||||
while (1)
|
||||
{
|
||||
// Wait a moment
|
||||
while (ISR_Ticks != 0)
|
||||
{
|
||||
__asm__(" WFI"); // sleep until SysTick
|
||||
}
|
||||
uint32_t ticks = ISR_Ticks;
|
||||
ISR_Ticks = 0;
|
||||
|
||||
for (uint8_t int=0; i<Tasks_len; i++)
|
||||
{
|
||||
if (Tasks[i].counter > ticks)
|
||||
{
|
||||
Tasks[i].counter -= ticks;
|
||||
}
|
||||
else
|
||||
{
|
||||
Tasks[i].counter = 0;
|
||||
}
|
||||
}
|
||||
|
||||
for (uint8_t int=0; i<Tasks_len; i++)
|
||||
{
|
||||
if (Tasks[i].counter == 0)
|
||||
{
|
||||
(&(Tasks[i].fn))();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
1
wiki
Submodule
1
wiki
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit ac9f6543bc2e182a14b2467046fc28cffcf97af8
|
||||
Loading…
x
Reference in New Issue
Block a user