# Stm32 Tutorial
- [NCRL_hackmd](https://hackmd.io/6OnKZUSkRd2wwnXzdQjXsA?view)
- [NCRL_video](https://www.youtube.com/watch?v=HlAw-NBprQk&list=PLe8KWt_uj6-MP0VAuhI_jwjfT6QTO4jBG&index=1)
- [NCRL_example](https://github.com/shengwen-tw/stm32f4-examples)
- [Develop Environment Setup](https://c-shengwen-tw.gitbook.io/ncrl-flight-controller/guide/development-environment?fbclid=IwAR28Afm-zPUvVhX_YtfErMcRYPclOvfknNt3BVCdR1-72E1E4-ZYQd--0JI)
- [成大资工wiki](http://wiki.csie.ncku.edu.tw/embedded/GPIO)
- [成大嵌入式系统教材](http://wiki.csie.ncku.edu.tw/embedded/Lab19/stm32-prog.pdf)
- [data sheet](https://www.st.com/resource/en/datasheet/stm32f415rg.pdf)
- [github library](https://github.com/espruino/Espruino/tree/master/targetlibs/stm32f4/lib)
## Table of Content
[TOC]
## Lecture 1
**STM32產品線概要**
<!--  -->


- 补充:
- ARM Cortox-A for cellphone market
- ARM Cortex-M for micro controller market
- ARM Cortex-R between Cortox-A and Cortex-M
- the device we use: STM32F407
- feature:
- MCU with 168 MHz/210 DMIPS
- Arm Cortex -M4 core + floating point unit (FPU)
- 封装: stm32f407 VGT6U
- Not the strongest, but the fittest will survive.
**Device Overview (Page.20 in data sheet)**

**AMBA匯流排介绍**

1. Advanced High-performance Bus (AHB) (适用于连接系统中的高速模组)
2. Advanced System Bus (ASB) (功能同AHB,但性能略差于AHB)
3. Advanced Peripheral Bus (APB) (用于低功耗的周边硬体模组,适用于低速模组)
**Clock**

## Lecture 2
**GPIO 用途 (in register)**

- moder:
- input, output for digital io
- analog for alalog io
- alternate function for periphery usage
- Set Moder of GPIO(stored in register of CPU)

- OType (output type)
- push-pull and open-drain

- [reference](http://cary1120.blogspot.com/2013/11/open-drain-push-pull.html)
- [reference](https://tfing.blogspot.com/2019/10/gpio-input-pull-uppull-downoutput-push.html)
- PuPd (pull up or pull down)

- OSpeed (output speed)
- example:

**practical transformation when changing moder**

- [Schmitt trigger](https://zh.wikipedia.org/wiki/%E6%96%BD%E5%AF%86%E7%89%B9%E8%A7%A6%E5%8F%91%E5%99%A8)
**What is Memory Mapped IO (MMIO)**

[example to control LED](https://github.com/shengwen-tw/stm32f4-examples/blob/master/firmware/peripheral/gpio_led/main.c)
## Lecture 3
[Linux Coding Style](https://github.com/torvalds/linux/blob/master/Documentation/process/coding-style.rst)
**git project**
```sh=
# create a git project directory
mkdir (project name)
# init your directory
cd (project name)
git init # it will create a .git file
# setup your git user information
git config --global user.name "user name"
git config --global user.email "email address"
# add your new file
git add (your file)
# commit
git commit -m "what you want to said"
# cheke current status
git status
#view history modification
sudo apt install tig
tig
```

[reference](https://ithelp.ithome.com.tw/articles/10156301)
[reference](https://medium.com/@brianwu291/basic-git-command-line-collections-2242c03c870ehttps://medium.com/@brianwu291/basic-git-command-line-collections-2242c03c870e)
**gcc**
```sh=
gcc -g -o ${target name} ${file name} # -o 可指定编译后的可执行档名称(预设是a.out)
# -g 可加入符号表(用于除错)
```
**debug**
use gdb
```sh=
# start gdb
gdb -q (path of file) # gdb -q ./hello.elf
```
in gdb
```sh=
# open file
file (path of file) # file ./hello.elf
# view variance
list (variance) # list main
# run
run
# break point
b (行数) # b 12
# modify the value of variance / print
p (variance = ?) # p num = 90
# go ito function for the details / step
s
# next step
n
# continue to next break point
c
```
**deep copy and shallow copy**
```c=
include <stdio.h>
include <stdint.h>
/* deep copy */
int face_detection(uint8_t img[100][100])
{
img[5][5] = 100;
return 0;
}
int main(void)
{
uint8_t img[100][100] = {0};
int ret = face_detection(img);
print("%d", img[5][5]);
return 0;
}
```
```c=
include <stdio.h>
include <stdint.h>
/* shallow copy */
int face_detection(unit8_t *img)
{
*(img + 5*100 + 5) = 100;
return 0;
}
int main(void)
{
uint8_t img[100][100] = {0};
int ret = face_detection((uint8_t *)img);
printf("%d", img[5][5]);
return 0;
}
```
## Lecture 4
**UART - Universal Asynchronous Reciever/Transmitter**
**USART - Universal Synchronous Asynchronous Reciever/Transmitter**
[detail](http://wiki.csie.ncku.edu.tw/embedded/USART)
通讯协定 RS-232


**Pin fot TX RX in stm32f4**

**use usart to recieve and translate data in stm32**
[example for using usart](https://github.com/shengwen-tw/stm32f4-examples/tree/master/firmware/peripheral/usart)
- enable clock tree
- enable clock tree of GPIO portC
- enable clock tree of USART3
- enable the alternate function of GPIO
- initialize
- initial port
- initial USART

**Interrupt in stm32**
```sh=
# check what interrupt you can use
vi starup_stm32f4xx.s
# under external interrupts
```
- clock: 168MHz
[example to use SysTick_Handler to count](https://github.com/shengwen-tw/stm32f4-examples/tree/master/firmware/peripheral/systick)
**Functions of Files**

- lib: 在编译器link時需要明顯地指出.o文件名,這對於編譯很不方便,所以我們要給中間目標文件打個包,在Windows下這種包叫“庫文件”(Library File),也就是 .lib 文件。
- *.f (header file): 标头档
- *.c (source file): 直接编辑的原文件(c/c++)。
- *.o (object file): source file被compiled后产生的中间代码文件。
- *.s : source file被compiled后产生的组合语言文件。
- *.elf : source file被compiled后产生的可执行档,另外可用于gdb除错时引入的档案。
- *.bin : 将资料传入stm32时所需要的档案。
- *.ld : ?
- makefile : 需要大量编译source file时可直接使用的脚本。
## Lecture 6
**MMIO**
**DMA**
## Lecture 7
**PWM (Pulse Width Modulation)**

**Use PWM in stm32**
- enable clock tree
- enable clock tree of GPIO portD
- enable clock tree of TIM
- enable the alternate function of GPIO
- initialize
- initial port
- initial time period, time prescaler (除频器) and time countermode
- initial PWM

**Clock in stm32CubeIDE**

- internal clock source (RC circuit)
- LSI (low speed internally) : 32kHz
- HSI (high speed internally) : 16MHz
- not accurate, becuase of its physical limit
- external clock source (quartz crystal resonator)
- LSE (low speed externally) : 0 - 1000 kHz
- HSE (high speed externally) : 4 - 26 MHz
- more accurate, but more energy consumption
- [PLL (Phase-locked loops)](https://zh.wikipedia.org/wiki/%E9%94%81%E7%9B%B8%E7%8E%AF)
- if you want to enable external clock source in stm32CubeIDE
- under Pinout & Configuration -> System Core -> (check) RCC(reset clock control) -> High Speed Clock (or High Speed Clock) -> Crystal/Ceramic Resonator
- set the value according to your hardware (we set 8)
- 
- 
- adjust other arguements
- 
- purple colors means your arguement violate its constraints
- after adjusting
- 
- complement
- the input frequency of HSE in stm32f407 is 8MHz, so we define PLL_M is 8 in system_stm32f4xx.c.
- [参考资料](https://lolikitty.pixnet.net/blog/post/142926586)
[参考资料](https://blog.csdn.net/tcjy1000/article/details/50554312)
- example
- /home/ncrl/stm_ws/stm32f4-examples/firmware/peripheral/gpio_led/lib/CMSIS/system_stm32f4xx.c

- result of APB1 timer clock

- /home/ncrl/stm_ws/stm32f4-examples/firmware/peripheral/pwm/main.c

TIM_CounterMode_Up 上数计时器
每经过一个executing period, counter会+1。
- therefore, the executing frequency = frequancy of APB1 / (Period_Counter * Prescaler)
the executing fequency = 84000000 / (1680 * 500) = 100 (Hz)
the executing period = 10 ms
[example for using PWM](https://github.com/shengwen-tw/stm32f4-examples/tree/master/firmware/peripheral/pwm)

## Lecture 8 and Lecture 9
### FreeRTOS (free real-time operating system)
###### [官方原始码](https://sourceforge.net/projects/freertos/)
Realitime:
如果有一個任務需要執行,實時作業系統會馬上(在較短時間內)執行該任務,不會有較長的延時。
Schedule:
按照排序執行、管理系統資源
Introduce:
FreeRTOS 是一個相對其他作業系統而言較小的作業系統。最小化的 FreeRTOS 核心僅包括 3 個 .c 文件(tasks.c、queue.c、list.c)和少數標頭檔,總共不到 9000 行程式碼,還包括了註解和空行。一個典型的編譯後 binary(二進位碼)小於 10 KB。
FreeRTOS 的程式碼可以分為三個主要區塊:
- task:
- 任務是擁有優先權的用戶所定義的 C 函數。task.c 和 task.h 負責所有關於建立、排程和維護任務的繁重工作。
- communication:
- 任務間可以互相通訊則更為重要!FreeRTOS 核心程式碼大約有 40% 是用來處理通訊的。queue.c 和 queue.h 負責處理 FreeRTOS 的通訊,任務和中斷(interrupt)使用佇列(佇列,queue)互相發送數據,並且使用 semaphore 和 mutex 來派發 critical section 的使用信號。
- hardware interface:
- 根据不同的硬体(arm, intel, IBM ...),软体与硬体间的沟通都不一样。
**Task**
- example
```c=
void task1()
{
int digitStatus = 1;
while(1) {
GPIO_WriteBit(GPIOD, GPIO_Pin_12, digitStatus);
GPIO_WriteBit(GPIOD, GPIO_Pin_13, digitStatus);
digitStatus = (digitStatus + 1) % 2;
vTaskDelay(MILLI_SECOND_TICK * 1000);
}
}
void task2()
{
int digitStatus = 1;
while(1) {
GPIO_WriteBit(GPIOD, GPIO_Pin_14, digitStatus);
GPIO_WriteBit(GPIOD, GPIO_Pin_15, digitStatus);
digitStatus = (digitStatus + 1) % 2;
vTaskDelay(MILLI_SECOND_TICK * 1000);
}
}
int main()
{
init_GPIO();
xTaskCreate(task1, "task1", 256, NULL, tskIDLE_PRIORITY + 2, NULL);
xTaskCreate(task2, "task2", 256, NULL, tskIDLE_PRIORITY + 1, NULL);
vTaskStartScheduler();
return 0;
}
```
- explanation
- xTaskCreate(function_pointer, task_name, memory_size, NULL, priority, NULL)
- memory_size单位為word(在不同硬体平台中,实际大小不一样),这裡大小為4Bytes。
- 在freertos中,priority值越大,优先度越高。(在stm32中,priority值越小,优先度越高。)
- 排程器 vTaskStartScheduler() : 决定哪个task被执行,哪个task不要被执行。
- scheduler对于资源(记忆体)的使用权限( kernel > user )。

- SysTick决定什么时候schedule应该接受context switch的指令,将CPU资源给予task或从task拿回CPU资源。
- context switch : Context switch 是指 task A 要交出 CPU 使用權給 task B 時,OS 會將 task A 當前的狀態和暫存器內的資料存放到記憶體,再將先前 task B 的狀態從記憶體讀取至暫存器的過程。
**mutex 互斥锁 (用于资源管理)**
互斥锁是一种特殊的二值信号量,用于控制在两个或多个任务间访问共享资源。

- 优先权反转
**semaphore (用于资源同步)**
semaphore可以是binary型态或者是counter型态。(在freertos中,semaphore跟mutex是一样的,只有API不一样而已。)
* 事件技计数
* 资源管理
**deadlock**
当两个任务都在等待被对方持有的资源时,两个任务都无法再继续执行,这种情况就被称为死锁。
**schedule**
每个task都会被schedule定义成不同state
task

- Ready:準備好要執行的狀態
- Running:正在由 CPU 執行的狀態
- Blocked:等待中的狀態(通常是在等待某個事件)
- Suspended:等待中的狀態(透過 API 來要求退出排程)
## Lecture 10
**logic analyzer**
[saleae官网](https://www.saleae.com/)

```sh=
# start logic
cd /home/ncrl/Downloads/Logic 1.2.18 (64-bit)
sudo ./Logic
```
**NCRL - Flight Controller**

## Others
**compile**
```sh=
gcc (file name)
```
options:
* -c : 只把程序做成obj文件。 ex: gcc -c (file name)
* -o : 定义gcc编译出来的档案名称(预设是a.out)。 ex: gcc -o hello.exe hello.c
* -g : 只是编译器,在编译的时候,产生调试信息。
**make file**
* [make file学习教程](https://blog.xuite.net/tzeng015/twblog/113272267-Makefile%E5%AD%B8%E7%BF%92%E6%95%99%E7%A8%8B%3A+%E8%B7%9F%E6%88%91%E4%B8%80%E8%B5%B7%E5%AF%AB+Makefile)
* [make file学习教程](https://hackmd.io/@sysprog/SySTMXPvl)
**grep 基本用法**
[UNIX 常用指令 - grep](https://marco79423.net/articles/unix-%E5%B8%B8%E7%94%A8%E6%8C%87%E4%BB%A4-grep/)
**SPI**
[参考网址](https://www.coderbridge.com/@bcewang/8d4643dff39e4dc4aadd022ac8fac517)
[参考网址](http://www.ec66.com/article/list.asp?indexid=4538)
[参考网址](https://youboook.pixnet.net/blog/post/98305922)
[SPI Standard Driver Library](https://www.st.com/resource/en/user_manual/dm00023896-description-of-stm32f2xx-standard-peripheral-library-stmicroelectronics.pdf)
###### tags: `ncrl` `stm32`