├── section-05 ├── README.md ├── hardware_filtering │ ├── figures │ │ ├── lpf.JPG │ │ ├── lpf_bode.JPG │ │ ├── lpf_tran_sim.JPG │ │ ├── square_wave.JPG │ │ ├── square_wave_2.JPG │ │ ├── square_wave_3.JPG │ │ ├── square_wave_4.JPG │ │ ├── square_wave_5.JPG │ │ ├── tinker_cad_adc.JPG │ │ ├── square_wave_1khz.JPG │ │ └── square_wave_1khz_bode.JPG │ ├── digital_filtering.md │ └── analog_filtering.md └── WORK.md ├── section-01 ├── c-exercises │ ├── main.c │ └── test.c ├── examples │ ├── example │ ├── example.o │ ├── example.bc │ ├── example.c │ └── example.s ├── blinky │ ├── Drivers │ │ ├── CMSIS │ │ │ ├── Device │ │ │ │ └── ST │ │ │ │ │ └── STM32F0xx │ │ │ │ │ ├── Include │ │ │ │ │ ├── stm32f0xx.h │ │ │ │ │ └── system_stm32f0xx.h │ │ │ │ │ └── LICENSE.txt │ │ │ └── Include │ │ │ │ ├── cmsis_version.h │ │ │ │ ├── tz_context.h │ │ │ │ └── cmsis_compiler.h │ │ └── STM32F0xx_HAL_Driver │ │ │ ├── LICENSE.txt │ │ │ ├── Inc │ │ │ ├── stm32f0xx_hal_cortex.h │ │ │ ├── stm32f0xx_hal_pwr.h │ │ │ ├── stm32f0xx_hal_def.h │ │ │ └── stm32f0xx_hal_i2c_ex.h │ │ │ └── Src │ │ │ └── stm32f0xx_hal_pwr_ex.c │ ├── Core │ │ ├── Inc │ │ │ ├── stm32f0xx_it.h │ │ │ └── main.h │ │ └── Src │ │ │ ├── sysmem.c │ │ │ ├── syscalls.c │ │ │ ├── stm32f0xx_hal_msp.c │ │ │ ├── stm32f0xx_it.c │ │ │ ├── main.c │ │ │ └── system_stm32f0xx.c │ ├── blinky.ioc │ ├── Makefile │ ├── stm32f030r8tx_flash.ld │ └── .mxproject ├── projects │ ├── circularbuffer.md │ ├── minishell.md │ └── memorytracker.md └── WORK.md ├── section-02 ├── s-exercises │ ├── exercise1to3 │ │ ├── work.txt │ │ ├── gpio.h │ │ └── gpio.s │ └── exercise4 │ │ └── vault.elf └── WORK.md ├── assets ├── 0 │ ├── msys2.png │ └── githubflow.png ├── 1 │ ├── mmiozoom.png │ ├── mmiolarge.png │ └── Compilation-Process-in-C.png ├── 2 │ ├── apbmmio.png │ ├── endianness.png │ └── mmio_stm32.png └── 3 │ ├── pwm.png │ ├── aliasing.png │ ├── CAN-wiring.png │ ├── PWMExample.png │ ├── i2c_frame.png │ ├── i2c_wiring.png │ ├── spi_mode0.png │ ├── uart_frame.png │ ├── uart_wiring.png │ ├── Bus-Signaling.png │ ├── CAN-FD-frame.png │ ├── CAN-transceiver.png │ ├── nyquistfrequency.png │ ├── spi_muli_slave.png │ ├── serialconnections.png │ └── parallelconnections.png ├── .github ├── CODEOWNERS ├── ISSUE_TEMPLATE │ ├── feature_request.md │ ├── bug_report.md │ └── documentation-update.md └── CONTRIBUTING.md ├── .gitattributes ├── section-final-proj └── WORK.md ├── .gitignore ├── section-04 ├── WORK.md └── README.md ├── section-03 └── WORK.md ├── section-00 └── WORK.md ├── README.md └── SETUP.md /section-05/README.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /section-01/c-exercises/main.c: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /section-01/c-exercises/test.c: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /section-02/s-exercises/exercise1to3/work.txt: -------------------------------------------------------------------------------- 1 | Put your code here in this directory, not this file. -------------------------------------------------------------------------------- /assets/3/pwm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DallasFormulaRacing/embedded-onboarding/HEAD/assets/3/pwm.png -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @wxkim 2 | 3 | /section-03/ @alexshidagoatnocap @schommie 4 | /section-05/ @eagle3781 5 | -------------------------------------------------------------------------------- /assets/0/msys2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DallasFormulaRacing/embedded-onboarding/HEAD/assets/0/msys2.png -------------------------------------------------------------------------------- /assets/1/mmiozoom.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DallasFormulaRacing/embedded-onboarding/HEAD/assets/1/mmiozoom.png -------------------------------------------------------------------------------- /assets/2/apbmmio.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DallasFormulaRacing/embedded-onboarding/HEAD/assets/2/apbmmio.png -------------------------------------------------------------------------------- /assets/3/aliasing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DallasFormulaRacing/embedded-onboarding/HEAD/assets/3/aliasing.png -------------------------------------------------------------------------------- /assets/0/githubflow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DallasFormulaRacing/embedded-onboarding/HEAD/assets/0/githubflow.png -------------------------------------------------------------------------------- /assets/1/mmiolarge.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DallasFormulaRacing/embedded-onboarding/HEAD/assets/1/mmiolarge.png -------------------------------------------------------------------------------- /assets/2/endianness.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DallasFormulaRacing/embedded-onboarding/HEAD/assets/2/endianness.png -------------------------------------------------------------------------------- /assets/2/mmio_stm32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DallasFormulaRacing/embedded-onboarding/HEAD/assets/2/mmio_stm32.png -------------------------------------------------------------------------------- /assets/3/CAN-wiring.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DallasFormulaRacing/embedded-onboarding/HEAD/assets/3/CAN-wiring.png -------------------------------------------------------------------------------- /assets/3/PWMExample.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DallasFormulaRacing/embedded-onboarding/HEAD/assets/3/PWMExample.png -------------------------------------------------------------------------------- /assets/3/i2c_frame.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DallasFormulaRacing/embedded-onboarding/HEAD/assets/3/i2c_frame.png -------------------------------------------------------------------------------- /assets/3/i2c_wiring.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DallasFormulaRacing/embedded-onboarding/HEAD/assets/3/i2c_wiring.png -------------------------------------------------------------------------------- /assets/3/spi_mode0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DallasFormulaRacing/embedded-onboarding/HEAD/assets/3/spi_mode0.png -------------------------------------------------------------------------------- /assets/3/uart_frame.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DallasFormulaRacing/embedded-onboarding/HEAD/assets/3/uart_frame.png -------------------------------------------------------------------------------- /assets/3/uart_wiring.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DallasFormulaRacing/embedded-onboarding/HEAD/assets/3/uart_wiring.png -------------------------------------------------------------------------------- /assets/3/Bus-Signaling.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DallasFormulaRacing/embedded-onboarding/HEAD/assets/3/Bus-Signaling.png -------------------------------------------------------------------------------- /assets/3/CAN-FD-frame.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DallasFormulaRacing/embedded-onboarding/HEAD/assets/3/CAN-FD-frame.png -------------------------------------------------------------------------------- /assets/3/CAN-transceiver.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DallasFormulaRacing/embedded-onboarding/HEAD/assets/3/CAN-transceiver.png -------------------------------------------------------------------------------- /assets/3/nyquistfrequency.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DallasFormulaRacing/embedded-onboarding/HEAD/assets/3/nyquistfrequency.png -------------------------------------------------------------------------------- /assets/3/spi_muli_slave.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DallasFormulaRacing/embedded-onboarding/HEAD/assets/3/spi_muli_slave.png -------------------------------------------------------------------------------- /section-01/examples/example: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DallasFormulaRacing/embedded-onboarding/HEAD/section-01/examples/example -------------------------------------------------------------------------------- /section-01/examples/example.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DallasFormulaRacing/embedded-onboarding/HEAD/section-01/examples/example.o -------------------------------------------------------------------------------- /assets/3/serialconnections.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DallasFormulaRacing/embedded-onboarding/HEAD/assets/3/serialconnections.png -------------------------------------------------------------------------------- /section-01/examples/example.bc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DallasFormulaRacing/embedded-onboarding/HEAD/section-01/examples/example.bc -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.md linguist-language=Markdown 2 | *.o linguist-language=C 3 | *.i linguist-language=C 4 | *.s linguist-language=Assembly 5 | -------------------------------------------------------------------------------- /assets/3/parallelconnections.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DallasFormulaRacing/embedded-onboarding/HEAD/assets/3/parallelconnections.png -------------------------------------------------------------------------------- /assets/1/Compilation-Process-in-C.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DallasFormulaRacing/embedded-onboarding/HEAD/assets/1/Compilation-Process-in-C.png -------------------------------------------------------------------------------- /section-02/s-exercises/exercise4/vault.elf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DallasFormulaRacing/embedded-onboarding/HEAD/section-02/s-exercises/exercise4/vault.elf -------------------------------------------------------------------------------- /section-05/hardware_filtering/figures/lpf.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DallasFormulaRacing/embedded-onboarding/HEAD/section-05/hardware_filtering/figures/lpf.JPG -------------------------------------------------------------------------------- /section-05/hardware_filtering/figures/lpf_bode.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DallasFormulaRacing/embedded-onboarding/HEAD/section-05/hardware_filtering/figures/lpf_bode.JPG -------------------------------------------------------------------------------- /section-05/hardware_filtering/figures/lpf_tran_sim.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DallasFormulaRacing/embedded-onboarding/HEAD/section-05/hardware_filtering/figures/lpf_tran_sim.JPG -------------------------------------------------------------------------------- /section-05/hardware_filtering/figures/square_wave.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DallasFormulaRacing/embedded-onboarding/HEAD/section-05/hardware_filtering/figures/square_wave.JPG -------------------------------------------------------------------------------- /section-05/hardware_filtering/figures/square_wave_2.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DallasFormulaRacing/embedded-onboarding/HEAD/section-05/hardware_filtering/figures/square_wave_2.JPG -------------------------------------------------------------------------------- /section-05/hardware_filtering/figures/square_wave_3.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DallasFormulaRacing/embedded-onboarding/HEAD/section-05/hardware_filtering/figures/square_wave_3.JPG -------------------------------------------------------------------------------- /section-05/hardware_filtering/figures/square_wave_4.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DallasFormulaRacing/embedded-onboarding/HEAD/section-05/hardware_filtering/figures/square_wave_4.JPG -------------------------------------------------------------------------------- /section-05/hardware_filtering/figures/square_wave_5.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DallasFormulaRacing/embedded-onboarding/HEAD/section-05/hardware_filtering/figures/square_wave_5.JPG -------------------------------------------------------------------------------- /section-05/hardware_filtering/figures/tinker_cad_adc.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DallasFormulaRacing/embedded-onboarding/HEAD/section-05/hardware_filtering/figures/tinker_cad_adc.JPG -------------------------------------------------------------------------------- /section-05/hardware_filtering/figures/square_wave_1khz.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DallasFormulaRacing/embedded-onboarding/HEAD/section-05/hardware_filtering/figures/square_wave_1khz.JPG -------------------------------------------------------------------------------- /section-05/hardware_filtering/figures/square_wave_1khz_bode.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DallasFormulaRacing/embedded-onboarding/HEAD/section-05/hardware_filtering/figures/square_wave_1khz_bode.JPG -------------------------------------------------------------------------------- /section-01/blinky/Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f0xx.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DallasFormulaRacing/embedded-onboarding/HEAD/section-01/blinky/Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f0xx.h -------------------------------------------------------------------------------- /section-02/s-exercises/exercise1to3/gpio.h: -------------------------------------------------------------------------------- 1 | #ifndef MYGPIO_H 2 | #define MYGPIO_H 3 | 4 | #include 5 | 6 | void my_gpio_init(uint32_t port, uint32_t pin, uint32_t mode); 7 | void my_gpio_toggle(uint32_t port, uint32_t pin); 8 | void my_hal_delay(uint32_t delay); 9 | 10 | #endif -------------------------------------------------------------------------------- /section-01/blinky/Drivers/CMSIS/Device/ST/STM32F0xx/LICENSE.txt: -------------------------------------------------------------------------------- 1 | This software component is provided to you as part of a software package and 2 | applicable license terms are in the Package_license file. If you received this 3 | software component outside of a package or without applicable license terms, 4 | the terms of the Apache-2.0 license shall apply. 5 | You may obtain a copy of the Apache-2.0 at: 6 | https://opensource.org/licenses/Apache-2.0 7 | -------------------------------------------------------------------------------- /section-01/blinky/Drivers/STM32F0xx_HAL_Driver/LICENSE.txt: -------------------------------------------------------------------------------- 1 | This software component is provided to you as part of a software package and 2 | applicable license terms are in the Package_license file. If you received this 3 | software component outside of a package or without applicable license terms, 4 | the terms of the BSD-3-Clause license shall apply. 5 | You may obtain a copy of the BSD-3-Clause at: 6 | https://opensource.org/licenses/BSD-3-Clause 7 | -------------------------------------------------------------------------------- /section-final-proj/WORK.md: -------------------------------------------------------------------------------- 1 | ~~# Final project: Acceleration Pedal Position Simulator~~ 2 | 3 | ## There is no final project this semester. 4 | 5 | In lieu of this, all sections are required. 6 | 7 | This is subject to change in future semesters. Should a final project be required in the future, members who have already completed it prior to its addition will not be asked to complete it again. 8 | 9 | Please ensure your fork is public and ready to be graded. 10 | 11 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: "[Feature]" 5 | labels: enhancement 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Problem statement: what's wrong with it?** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Ideal situation: describe the solution you'd like.** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Proposed solutions: describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: "[Bug]" 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Environment in which this bug occurred (please complete the following information):** 27 | - Operating system: 28 | - Compiler: 29 | - Text Editor/IDE: 30 | 31 | **Additional context** 32 | Add any other context about the problem here. 33 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/documentation-update.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Documentation update 3 | about: Suggest improvements, corrections, or additions to the existing documentation. 4 | title: "[Docs]" 5 | labels: documentation 6 | assignees: '' 7 | 8 | --- 9 | 10 | **What does the documentation currently state or lack?** 11 | Please paste the relevant snippet if possible. 12 | 13 | **Suggested Change or Improvement.** 14 | Clearly explain and justify your proposed update, clarification, or addition. 15 | 16 | **Documentation Impact** 17 | How significant is this update to the overall understanding of the tutorial? 18 | - Minor (grammar, formatting, small typo) 19 | - Moderate (clarification, additional example, rewording) 20 | - Major (missing explanation, incorrect or obsolete information, structural change) 21 | 22 | **Additional context** 23 | Add any other context or screenshots about the feature request here. 24 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Object files 5 | *.o 6 | *.ko 7 | *.obj 8 | *.elf 9 | 10 | # Do not ignore example.o, as it is used in the examples. 11 | !section-01/examples/example.o 12 | 13 | # Linker output 14 | *.ilk 15 | *.map 16 | *.exp 17 | 18 | # Precompiled Headers 19 | *.gch 20 | *.pch 21 | 22 | # Libraries 23 | *.lib 24 | *.a 25 | *.la 26 | *.lo 27 | 28 | # Shared objects (inc. Windows DLLs) 29 | *.dll 30 | *.so 31 | *.so.* 32 | *.dylib 33 | 34 | # Executables 35 | *.exe 36 | *.out 37 | *.app 38 | *.i*86 39 | *.x86_64 40 | *.hex 41 | 42 | # Debug files 43 | *.dSYM/ 44 | *.su 45 | *.idb 46 | *.pdb 47 | 48 | # Kernel Module Compile Results 49 | *.mod* 50 | *.cmd 51 | .tmp_versions/ 52 | modules.order 53 | Module.symvers 54 | Mkfile.old 55 | dkms.conf 56 | 57 | .vscode/ 58 | 59 | # Customs 60 | 61 | section-02/s-exercises/exercise4/vault.c 62 | section-02/s-exercises/exercise4/Makefile 63 | !section-02/s-exercises/exercise4/vault.elf -------------------------------------------------------------------------------- /section-01/examples/example.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | // This define macro will disappear after preprocessing 5 | #define add(x, y) ((x) + (y)) 6 | 7 | // This is a simple C program that prints "Hello, world!" and 8 | // lists any command-line arguments provided by the user. 9 | 10 | int main(int argc, char **argv) { 11 | printf("Hello, world!\n"); 12 | printf("The sum of 3 and 4 is: %d\n", add(3, 4)); 13 | // Check if any command-line arguments were provided 14 | 15 | // This will be removed by the preprocessor as well, 16 | // it will turn into a single line with no conditionals 17 | #ifdef DEBUG 18 | printf("Debug mode is enabled.\n"); 19 | #else 20 | printf("Debug mode is disabled.\n"); 21 | #endif 22 | 23 | if (argc > 1) { 24 | printf("You provided %d argument(s):\n", argc - 1); 25 | for (int i = 1; i < argc; i++) { 26 | printf("Argument %d: %s\n", i, argv[i]); 27 | } 28 | } else { 29 | printf("No additional arguments provided.\n"); 30 | } 31 | 32 | // All is good. 33 | return 0; 34 | } -------------------------------------------------------------------------------- /section-01/blinky/Drivers/CMSIS/Include/cmsis_version.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************//** 2 | * @file cmsis_version.h 3 | * @brief CMSIS Core(M) Version definitions 4 | * @version V5.0.2 5 | * @date 19. April 2017 6 | ******************************************************************************/ 7 | /* 8 | * Copyright (c) 2009-2017 ARM Limited. All rights reserved. 9 | * 10 | * SPDX-License-Identifier: Apache-2.0 11 | * 12 | * Licensed under the Apache License, Version 2.0 (the License); you may 13 | * not use this file except in compliance with the License. 14 | * You may obtain a copy of the License at 15 | * 16 | * www.apache.org/licenses/LICENSE-2.0 17 | * 18 | * Unless required by applicable law or agreed to in writing, software 19 | * distributed under the License is distributed on an AS IS BASIS, WITHOUT 20 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 21 | * See the License for the specific language governing permissions and 22 | * limitations under the License. 23 | */ 24 | 25 | #if defined ( __ICCARM__ ) 26 | #pragma system_include /* treat file as system include file for MISRA check */ 27 | #elif defined (__clang__) 28 | #pragma clang system_header /* treat file as system include file */ 29 | #endif 30 | 31 | #ifndef __CMSIS_VERSION_H 32 | #define __CMSIS_VERSION_H 33 | 34 | /* CMSIS Version definitions */ 35 | #define __CM_CMSIS_VERSION_MAIN ( 5U) /*!< [31:16] CMSIS Core(M) main version */ 36 | #define __CM_CMSIS_VERSION_SUB ( 1U) /*!< [15:0] CMSIS Core(M) sub version */ 37 | #define __CM_CMSIS_VERSION ((__CM_CMSIS_VERSION_MAIN << 16U) | \ 38 | __CM_CMSIS_VERSION_SUB ) /*!< CMSIS Core(M) version number */ 39 | #endif 40 | -------------------------------------------------------------------------------- /section-01/blinky/Core/Inc/stm32f0xx_it.h: -------------------------------------------------------------------------------- 1 | /* USER CODE BEGIN Header */ 2 | /** 3 | ****************************************************************************** 4 | * @file stm32f0xx_it.h 5 | * @brief This file contains the headers of the interrupt handlers. 6 | ****************************************************************************** 7 | * @attention 8 | * 9 | * Copyright (c) 2025 STMicroelectronics. 10 | * All rights reserved. 11 | * 12 | * This software is licensed under terms that can be found in the LICENSE file 13 | * in the root directory of this software component. 14 | * If no LICENSE file comes with this software, it is provided AS-IS. 15 | * 16 | ****************************************************************************** 17 | */ 18 | /* USER CODE END Header */ 19 | 20 | /* Define to prevent recursive inclusion -------------------------------------*/ 21 | #ifndef __STM32F0xx_IT_H 22 | #define __STM32F0xx_IT_H 23 | 24 | #ifdef __cplusplus 25 | extern "C" { 26 | #endif 27 | 28 | /* Private includes ----------------------------------------------------------*/ 29 | /* USER CODE BEGIN Includes */ 30 | 31 | /* USER CODE END Includes */ 32 | 33 | /* Exported types ------------------------------------------------------------*/ 34 | /* USER CODE BEGIN ET */ 35 | 36 | /* USER CODE END ET */ 37 | 38 | /* Exported constants --------------------------------------------------------*/ 39 | /* USER CODE BEGIN EC */ 40 | 41 | /* USER CODE END EC */ 42 | 43 | /* Exported macro ------------------------------------------------------------*/ 44 | /* USER CODE BEGIN EM */ 45 | 46 | /* USER CODE END EM */ 47 | 48 | /* Exported functions prototypes ---------------------------------------------*/ 49 | void NMI_Handler(void); 50 | void HardFault_Handler(void); 51 | void SVC_Handler(void); 52 | void PendSV_Handler(void); 53 | void SysTick_Handler(void); 54 | /* USER CODE BEGIN EFP */ 55 | 56 | /* USER CODE END EFP */ 57 | 58 | #ifdef __cplusplus 59 | } 60 | #endif 61 | 62 | #endif /* __STM32F0xx_IT_H */ 63 | -------------------------------------------------------------------------------- /section-04/WORK.md: -------------------------------------------------------------------------------- 1 | # Work for section 04 2 | 3 | Estimated completion time: 1 days. 4 | 5 | Do all of your work in this directory (but not in this file) so that it can be easily reviewed by a senior member later. 6 | 7 | You should constantly be referring back to the reading or other external sources. It is not expected of you to complete all the exercises in this unaided. 8 | 9 | ## Exercise 1: Create Two Tasks with Different Priorities 10 | 11 | **Objective:** Understand task creation and priority scheduling. 12 | 13 | **Steps:** 14 | 15 | - Create Task A (high priority) and Task B (low priority). 16 | - Task A toggles an LED every 200 ms. 17 | - Task B toggles a different LED every 500 ms. 18 | - Observe the behavior. 19 | 20 | **Expected Outcome:** The higher-priority task (Task A) preempts the lower-priority task (Task B). 21 | 22 | ## Exercise 2: Implement a Simple Delay 23 | 24 | **Objective:** Learn to use RTOS delay functions. 25 | 26 | **Steps:** 27 | 28 | - Create a single task that prints “Hello RTOS” every 1 second. 29 | - Use `vTaskDelay()` (FreeRTOS) or an equivalent delay function. 30 | 31 | **Expected Outcome:** The task prints periodically without blocking the CPU. 32 | 33 | ## Exercise 3: Mutual Exclusion with a Semaphore 34 | 35 | **Objective:** Practice synchronization. 36 | 37 | **Steps:** 38 | 39 | - Create two tasks that increment a shared counter. 40 | - Use a binary semaphore to ensure only one task accesses the counter at a time. 41 | 42 | **Expected Outcome:** The counter increments correctly without race conditions. 43 | 44 | ## Exercise 4: Task Notification 45 | 46 | **Objective:** Learn inter-task signaling. 47 | 48 | **Steps:** 49 | 50 | - Create two tasks: Producer and Consumer. 51 | - Producer generates a number every 500 ms. 52 | - Producer notifies Consumer using task notifications to process the number. 53 | 54 | **Expected Outcome:** Consumer runs only when signaled by Producer. 55 | 56 | ## Exercise 5: Queue Communication 57 | 58 | **Objective:** Understand queues for inter-task data transfer. 59 | 60 | **Steps:** 61 | 62 | - Create a queue to hold integers. 63 | - Task A sends numbers 1–10 to the queue. 64 | - Task B receives numbers from the queue and prints them. 65 | 66 | **Expected Outcome:** Data is transferred safely between tasks. 67 | -------------------------------------------------------------------------------- /section-02/s-exercises/exercise1to3/gpio.s: -------------------------------------------------------------------------------- 1 | // DO NOT edit below 2 | .syntax unified 3 | .thumb 4 | // DO NOT edit above 5 | 6 | // FIND IN DATASHEET REGISTER MAP 7 | .equ RCC_BASE, ??? // RCC base address 8 | .equ RCC_AHBENR, RCC_BASE + ??? // AHB Peripheral enable register 9 | .equ GPIO_MODER, ??? // GPIO mode register offset 10 | .equ GPIO_ODR, ??? // GPIO output data register offset 11 | 12 | .global my_gpio_init 13 | .global my_gpio_toggle 14 | .global my_hal_delay 15 | 16 | // !!! dont be afraid to look at the C implementation for help !!! 17 | // dont over think it!! nothing is here to trick you !! 18 | 19 | .thumb_func 20 | my_gpio_init: 21 | ldr r3, =??? // We have to enable some clock thing to init GPIOs 22 | ldr r4, [r3] 23 | orr r4, r4, #(1 << ???) // Find the correct bit position to enable the RCC 24 | str r4, [r3] 25 | 26 | // r0: port base, r1: pin, r2: mode 27 | lsl r3, r1, #1 28 | mov r4, #3 29 | lsl r4, r4, r3 30 | 31 | ldr r5, [r0, #???] // what register are we modifying to set the mode? 32 | ??? r5, r5, r4 // clear the 2 bits first 33 | lsl r6, r2, r3 34 | orr r5, r5, r6 35 | str r5, [r0, #???] // write back to the what register 36 | 37 | ??? // branch link register 38 | 39 | .thumb_func 40 | my_gpio_toggle: 41 | // r0 = port base 42 | // r1 = pin number 43 | 44 | ldr r2, [r0, #???] // read output data register 45 | movs r3, #1 46 | ??? r3, r3, r1 // create bitmask for pin using bit shift 47 | ??? r2, r2, r3 // what logic element toggles something? 48 | str r2, [r0, #???] // write back to what register? 49 | 50 | bx lr // branch link register = return to caller 51 | 52 | .thumb_func 53 | my_hal_delay: 54 | // r0 = delay in ms 55 | 56 | ms: 57 | movs r1, #??? // adjust based on system clock frq [CONSTANT] 58 | 59 | cnt: 60 | ??? r1, r1, #1 // count down or count up? which instruction mnemonic supports that? 61 | ??? cnt // loop until done, what branch condition do we want? 62 | 63 | subs r0, r0, #1 64 | bne ms 65 | 66 | bx lr 67 | -------------------------------------------------------------------------------- /.github/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing Guidelines 2 | 3 | Thank you for your interest in contributing to this onboarding tutorial project. Your input helps improve the experience for future embedded systems team members and ensures the technical accuracy and clarity of our training materials. 4 | 5 | ## Contribution Overview 6 | 7 | This project is a collection of structured tutorials designed to familiarize new members with the fundamental concepts, tools, and workflows used by our embedded systems teams. Contributions should maintain the clarity, accuracy, and pedagogical value of the existing content. 8 | 9 | ## How to Contribute 10 | 11 | ### 1. Reporting Issues 12 | If you encounter: 13 | - **Minor issues** (typos, small formatting errors): 14 | Please create a GitHub issue. If they are not critical, there's no need to submit a pull request immediately. 15 | 16 | - **Major issues** (technical inaccuracies, broken content, other urgencies): 17 | Please create a GitHub issue. Direct message the author/maintainer first. Make a pull request if you feel this is urgent enough. 18 | 19 | ### 2. Suggesting Improvements 20 | - If you have an idea for improving the content, structure, or difficulty balance of the tutorials, open a GitHub issue describing your suggestion. 21 | - If you have already implemented improvements, you may submit a pull request. Please use a **appropriately named branch** and open the PR against the `main` branch. 22 | 23 | ### 3. Creating Pull Requests 24 | - Ensure your changes are relevant, well-tested (if applicable), and maintain the formatting standards of the repository. 25 | - Include a clear description of the changes in the PR body. 26 | - Reference any related issues by number. 27 | 28 | ### 4. Style and Content Guidelines 29 | - Keep explanations concise but informative. 30 | - Use proper code formatting and markdown syntax. 31 | - Align your additions with the tone and technical depth of the existing sections. 32 | - When adding new tutorials or subtopics, include: 33 | - A **title** 34 | - A **difficulty level** 35 | - Clear **learning outcomes** 36 | 37 | ## Repository Structure 38 | 39 | Each section in the tutorial series is carefully curated and labeled with difficulty and learning outcomes. Please follow the existing structure when adding or editing content. 40 | 41 | ## Contact 42 | 43 | For complex questions or larger contributions, feel free to reach out directly before initiating major changes. 44 | 45 | I (the author) can be reached via: 46 | - Discord: `__wxkim__` 47 | - Email: `wkim@utdallas.edu` 48 | 49 | --- 50 | 51 | Thank you for helping improve our onboarding process and educational materials for embedded systems team members. 52 | -------------------------------------------------------------------------------- /section-03/WORK.md: -------------------------------------------------------------------------------- 1 | # Section 3 Work 2 | 3 | > **DISCLAIMER:** This work section is not a full guide or walkthrough on how to configure the settings in STM32CubeMX, ***and every board model may have a different setup process***. You may need to use external resources in order to complete these exercises. 4 | 5 | ## Exercise 1: Using a Button to Turn On an LED 6 | 7 | In this exercise, you will read a input from a button and output to a LED using GPIO pins in your main loop. 8 | 9 | You will need to generate a new project using ```Access the Board Selector``` and search for the ```NUCLEO-F030R8``` in the ```Commercial Part Number``` bar, and initialize all peripherals as default. You will then need to find the GPIO pins connected to the blue user button and LED in your ```.ioc``` file using STM32CubeMX. 10 | 11 | > Note: It is VERY important to keep your code within the ```/* USER CODE BEGIN */``` comments, otherwise your code will be deleted when you update your ```.ioc``` file. 12 | 13 | Using the ```HAL_GPIO_ReadPin()``` and ```HAL_GPIO_WritePin()``` functions, have the LED turn on when the button is pressed and off when the button is not pressed. 14 | 15 | ## Exercise 2: Using Button Interrupts to Turn On an LED 16 | 17 | In this exercise, you will learn how to use interrupts to turn on the LED using the button as opposed to polling in Exercise 1. 18 | 19 | To set up an interrupt pin, open up your ```.ioc``` file in STM32CubeMX. You will need to configure the GPIO mode on the pin corresponding to your button in ```External Interrupt Mode with Falling Edge Trigger Detection``` 20 | 21 | You will need to use the ```HAL_GPIO_EXTI_Callback()``` function, preferrably after the ```/* USER CODE BEGIN 4 */``` section. 22 | 23 | ## Exercise 3: Reading Analog Voltages with the ADC using DMA 24 | 25 | In this exercise, you will use the ADC, timers, and DMA peripherals to read voltages from an external source such as a wavegen, DC power supply, or another microcontroller. 26 | 27 | The ADC will need to run at 10kHz. This can be done by attaching and configuring a timer peripheral to the ADC in STM32CubeMX. 28 | 29 | You will also need to use DMA writing. Make sure that ```Continuous Conversion Mode``` and ```DMA Continuous Requests``` are enabled. The DMA mode should be ```Circular``` as you want to continuously collect data after the buffer is full. You will need to use the ```HAL_ADC_ConvCpltCallback()``` to process the raw ADC data and convert it to a voltage. Setting up a double-buffer is not required, but encouraged. 30 | 31 | You will need to find a way to display the converted voltage values either through the **Live Expressions** tab under the debugging session, or the **Serial Wire Viewer**. -------------------------------------------------------------------------------- /section-01/blinky/Core/Inc/main.h: -------------------------------------------------------------------------------- 1 | /* USER CODE BEGIN Header */ 2 | /** 3 | ****************************************************************************** 4 | * @file : main.h 5 | * @brief : Header for main.c file. 6 | * This file contains the common defines of the application. 7 | ****************************************************************************** 8 | * @attention 9 | * 10 | * Copyright (c) 2025 STMicroelectronics. 11 | * All rights reserved. 12 | * 13 | * This software is licensed under terms that can be found in the LICENSE file 14 | * in the root directory of this software component. 15 | * If no LICENSE file comes with this software, it is provided AS-IS. 16 | * 17 | ****************************************************************************** 18 | */ 19 | /* USER CODE END Header */ 20 | 21 | /* Define to prevent recursive inclusion -------------------------------------*/ 22 | #ifndef __MAIN_H 23 | #define __MAIN_H 24 | 25 | #ifdef __cplusplus 26 | extern "C" { 27 | #endif 28 | 29 | /* Includes ------------------------------------------------------------------*/ 30 | #include "stm32f0xx_hal.h" 31 | 32 | /* Private includes ----------------------------------------------------------*/ 33 | /* USER CODE BEGIN Includes */ 34 | 35 | /* USER CODE END Includes */ 36 | 37 | /* Exported types ------------------------------------------------------------*/ 38 | /* USER CODE BEGIN ET */ 39 | 40 | /* USER CODE END ET */ 41 | 42 | /* Exported constants --------------------------------------------------------*/ 43 | /* USER CODE BEGIN EC */ 44 | 45 | /* USER CODE END EC */ 46 | 47 | /* Exported macro ------------------------------------------------------------*/ 48 | /* USER CODE BEGIN EM */ 49 | 50 | /* USER CODE END EM */ 51 | 52 | /* Exported functions prototypes ---------------------------------------------*/ 53 | void Error_Handler(void); 54 | 55 | /* USER CODE BEGIN EFP */ 56 | 57 | /* USER CODE END EFP */ 58 | 59 | /* Private defines -----------------------------------------------------------*/ 60 | #define B1_Pin GPIO_PIN_13 61 | #define B1_GPIO_Port GPIOC 62 | #define USART_TX_Pin GPIO_PIN_2 63 | #define USART_TX_GPIO_Port GPIOA 64 | #define USART_RX_Pin GPIO_PIN_3 65 | #define USART_RX_GPIO_Port GPIOA 66 | #define LD2_Pin GPIO_PIN_5 // <---- Here from the blinky instructions? 67 | #define LD2_GPIO_Port GPIOA // <---- Here from the blinky instructions? 68 | #define TMS_Pin GPIO_PIN_13 69 | #define TMS_GPIO_Port GPIOA 70 | #define TCK_Pin GPIO_PIN_14 71 | #define TCK_GPIO_Port GPIOA 72 | 73 | /* USER CODE BEGIN Private defines */ 74 | 75 | /* USER CODE END Private defines */ 76 | 77 | #ifdef __cplusplus 78 | } 79 | #endif 80 | 81 | #endif /* __MAIN_H */ 82 | -------------------------------------------------------------------------------- /section-01/blinky/Drivers/CMSIS/Device/ST/STM32F0xx/Include/system_stm32f0xx.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file system_stm32f0xx.h 4 | * @author MCD Application Team 5 | * @brief CMSIS Cortex-M0 Device System Source File for STM32F0xx devices. 6 | ****************************************************************************** 7 | * @attention 8 | * 9 | * Copyright (c) 2016 STMicroelectronics. 10 | * All rights reserved. 11 | * 12 | * This software is licensed under terms that can be found in the LICENSE file 13 | * in the root directory of this software component. 14 | * If no LICENSE file comes with this software, it is provided AS-IS. 15 | * 16 | ****************************************************************************** 17 | */ 18 | /** @addtogroup CMSIS 19 | * @{ 20 | */ 21 | 22 | /** @addtogroup stm32f0xx_system 23 | * @{ 24 | */ 25 | 26 | /** 27 | * @brief Define to prevent recursive inclusion 28 | */ 29 | #ifndef __SYSTEM_STM32F0XX_H 30 | #define __SYSTEM_STM32F0XX_H 31 | 32 | #ifdef __cplusplus 33 | extern "C" { 34 | #endif 35 | 36 | /** @addtogroup STM32F0xx_System_Includes 37 | * @{ 38 | */ 39 | 40 | /** 41 | * @} 42 | */ 43 | 44 | 45 | /** @addtogroup STM32F0xx_System_Exported_types 46 | * @{ 47 | */ 48 | /* This variable is updated in three ways: 49 | 1) by calling CMSIS function SystemCoreClockUpdate() 50 | 3) by calling HAL API function HAL_RCC_GetHCLKFreq() 51 | 3) by calling HAL API function HAL_RCC_ClockConfig() 52 | Note: If you use this function to configure the system clock; then there 53 | is no need to call the 2 first functions listed above, since SystemCoreClock 54 | variable is updated automatically. 55 | */ 56 | extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */ 57 | extern const uint8_t AHBPrescTable[16]; /*!< AHB prescalers table values */ 58 | extern const uint8_t APBPrescTable[8]; /*!< APB prescalers table values */ 59 | 60 | /** 61 | * @} 62 | */ 63 | 64 | /** @addtogroup STM32F0xx_System_Exported_Constants 65 | * @{ 66 | */ 67 | 68 | /** 69 | * @} 70 | */ 71 | 72 | /** @addtogroup STM32F0xx_System_Exported_Macros 73 | * @{ 74 | */ 75 | 76 | /** 77 | * @} 78 | */ 79 | 80 | /** @addtogroup STM32F0xx_System_Exported_Functions 81 | * @{ 82 | */ 83 | 84 | extern void SystemInit(void); 85 | extern void SystemCoreClockUpdate(void); 86 | /** 87 | * @} 88 | */ 89 | 90 | #ifdef __cplusplus 91 | } 92 | #endif 93 | 94 | #endif /*__SYSTEM_STM32F0XX_H */ 95 | 96 | /** 97 | * @} 98 | */ 99 | 100 | /** 101 | * @} 102 | */ 103 | 104 | -------------------------------------------------------------------------------- /section-01/blinky/Core/Src/sysmem.c: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file sysmem.c 4 | * @author Generated by STM32CubeMX 5 | * @brief System Memory calls file 6 | * 7 | * For more information about which C functions 8 | * need which of these lowlevel functions 9 | * please consult the newlib libc manual 10 | ****************************************************************************** 11 | * @attention 12 | * 13 | * Copyright (c) 2024 STMicroelectronics. 14 | * All rights reserved. 15 | * 16 | * This software is licensed under terms that can be found in the LICENSE file 17 | * in the root directory of this software component. 18 | * If no LICENSE file comes with this software, it is provided AS-IS. 19 | * 20 | ****************************************************************************** 21 | */ 22 | 23 | /* Includes */ 24 | #include 25 | #include 26 | 27 | /** 28 | * Pointer to the current high watermark of the heap usage 29 | */ 30 | static uint8_t *__sbrk_heap_end = NULL; 31 | 32 | /** 33 | * @brief _sbrk() allocates memory to the newlib heap and is used by malloc 34 | * and others from the C library 35 | * 36 | * @verbatim 37 | * ############################################################################ 38 | * # .data # .bss # newlib heap # MSP stack # 39 | * # # # # Reserved by _Min_Stack_Size # 40 | * ############################################################################ 41 | * ^-- RAM start ^-- _end _estack, RAM end --^ 42 | * @endverbatim 43 | * 44 | * This implementation starts allocating at the '_end' linker symbol 45 | * The '_Min_Stack_Size' linker symbol reserves a memory for the MSP stack 46 | * The implementation considers '_estack' linker symbol to be RAM end 47 | * NOTE: If the MSP stack, at any point during execution, grows larger than the 48 | * reserved size, please increase the '_Min_Stack_Size'. 49 | * 50 | * @param incr Memory size 51 | * @return Pointer to allocated memory 52 | */ 53 | void *_sbrk(ptrdiff_t incr) 54 | { 55 | extern uint8_t _end; /* Symbol defined in the linker script */ 56 | extern uint8_t _estack; /* Symbol defined in the linker script */ 57 | extern uint32_t _Min_Stack_Size; /* Symbol defined in the linker script */ 58 | const uint32_t stack_limit = (uint32_t)&_estack - (uint32_t)&_Min_Stack_Size; 59 | const uint8_t *max_heap = (uint8_t *)stack_limit; 60 | uint8_t *prev_heap_end; 61 | 62 | /* Initialize heap end at first call */ 63 | if (NULL == __sbrk_heap_end) 64 | { 65 | __sbrk_heap_end = &_end; 66 | } 67 | 68 | /* Protect heap from growing into the reserved MSP stack */ 69 | if (__sbrk_heap_end + incr > max_heap) 70 | { 71 | errno = ENOMEM; 72 | return (void *)-1; 73 | } 74 | 75 | prev_heap_end = __sbrk_heap_end; 76 | __sbrk_heap_end += incr; 77 | 78 | return (void *)prev_heap_end; 79 | } 80 | -------------------------------------------------------------------------------- /section-01/projects/circularbuffer.md: -------------------------------------------------------------------------------- 1 | # 1. Circular Buffer Library 2 | 3 | ## Goal: Implement a fixed-size integer ring buffer 4 | 5 | ## Required Features: 6 | 7 | Buffer must support the following functions: 8 | 9 | ```C 10 | cb_init(size) 11 | 12 | cb_push(val) 13 | 14 | cb_pop() 15 | 16 | cb_peek() 17 | 18 | cb_is_empty() / cb_is_full() 19 | ``` 20 | 21 | Internally use an array + head/tail tracking 22 | 23 | Must support wraparound indexing 24 | 25 | Optional bonus: Implement buffer overwrite-on-full behavior 26 | 27 | ## Test Harness: 28 | 29 | Write a main.c that: 30 | 31 | - Initializes the buffer 32 | 33 | - Pushes several values 34 | 35 | - Pops them in order and prints 36 | 37 | - Asserts proper full/empty behavior 38 | 39 | Use print statements to show internal behavior as well. 40 | 41 | ### Instructions and requirements that apply to all projects: 42 | 43 | - You must link your project as a submodule within your forked copy of the repository 44 | 45 | - Your code must be modular. You must write header files for each source file you write. You must also keep source files in a subdirectory called `src` and header files in a subdirectory called `inc`. 46 | 47 | - This goes without saying, but you may only use the C language. 48 | 49 | - If you so choose, you may use inline assembly. This is optional. 50 | - You must have comments. Minimum 1 multi-line comment per function. 51 | 52 | - You must use the _Make_ build system and you must write your own `makefile`. Requirements for build system: 53 | 54 | - It must place build output files in a subdirectory called `build`. 55 | - It should support `make clean`, which cleans the `build` folder. 56 | - It should support `make run`, which runs the built executable. 57 | 58 | - Create a GitHub Actions workflow in `.github/workflows/build.yml`. Your workflow must: 59 | 60 | - Run on `ubuntu-latest` 61 | 62 | - Perform the following: 63 | 64 | - Checkout the repository 65 | 66 | - Initialize and update submodules 67 | 68 | - Run make and confirm a clean build 69 | 70 | - (Optional bonus) Run make run and check for expected output 71 | 72 | - You must have a minimum of 7 **well-named, significant** commits. If you think your project can be finished under 7 commits, it is not hard enough. 73 | 74 | - Pull requests for merging features on branches is not required. 75 | 76 | - Create a `README.md` that aptly describes what your project does. Your `README.md` must also contain **all** of the following: 77 | 78 | - A directory tree: use the `tree` command line tool 79 | - A short explanation of each module 80 | 81 | - If you need help, I have created an example project that satisfies all of the conditions (except module explanations and comments). View it [here](https://github.com/wxkim/julia). 82 | 83 | - Note: Your project should be significantly **less** complex than the example. 84 | 85 | - Finally, your project must work. It should build, and functionality error should be minimal, if not zero. 86 | - You do not have to make this project cross-platform. 87 | -------------------------------------------------------------------------------- /section-01/blinky/Drivers/CMSIS/Include/tz_context.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * @file tz_context.h 3 | * @brief Context Management for Armv8-M TrustZone 4 | * @version V1.0.1 5 | * @date 10. January 2018 6 | ******************************************************************************/ 7 | /* 8 | * Copyright (c) 2017-2018 Arm Limited. All rights reserved. 9 | * 10 | * SPDX-License-Identifier: Apache-2.0 11 | * 12 | * Licensed under the Apache License, Version 2.0 (the License); you may 13 | * not use this file except in compliance with the License. 14 | * You may obtain a copy of the License at 15 | * 16 | * www.apache.org/licenses/LICENSE-2.0 17 | * 18 | * Unless required by applicable law or agreed to in writing, software 19 | * distributed under the License is distributed on an AS IS BASIS, WITHOUT 20 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 21 | * See the License for the specific language governing permissions and 22 | * limitations under the License. 23 | */ 24 | 25 | #if defined ( __ICCARM__ ) 26 | #pragma system_include /* treat file as system include file for MISRA check */ 27 | #elif defined (__clang__) 28 | #pragma clang system_header /* treat file as system include file */ 29 | #endif 30 | 31 | #ifndef TZ_CONTEXT_H 32 | #define TZ_CONTEXT_H 33 | 34 | #include 35 | 36 | #ifndef TZ_MODULEID_T 37 | #define TZ_MODULEID_T 38 | /// \details Data type that identifies secure software modules called by a process. 39 | typedef uint32_t TZ_ModuleId_t; 40 | #endif 41 | 42 | /// \details TZ Memory ID identifies an allocated memory slot. 43 | typedef uint32_t TZ_MemoryId_t; 44 | 45 | /// Initialize secure context memory system 46 | /// \return execution status (1: success, 0: error) 47 | uint32_t TZ_InitContextSystem_S (void); 48 | 49 | /// Allocate context memory for calling secure software modules in TrustZone 50 | /// \param[in] module identifies software modules called from non-secure mode 51 | /// \return value != 0 id TrustZone memory slot identifier 52 | /// \return value 0 no memory available or internal error 53 | TZ_MemoryId_t TZ_AllocModuleContext_S (TZ_ModuleId_t module); 54 | 55 | /// Free context memory that was previously allocated with \ref TZ_AllocModuleContext_S 56 | /// \param[in] id TrustZone memory slot identifier 57 | /// \return execution status (1: success, 0: error) 58 | uint32_t TZ_FreeModuleContext_S (TZ_MemoryId_t id); 59 | 60 | /// Load secure context (called on RTOS thread context switch) 61 | /// \param[in] id TrustZone memory slot identifier 62 | /// \return execution status (1: success, 0: error) 63 | uint32_t TZ_LoadContext_S (TZ_MemoryId_t id); 64 | 65 | /// Store secure context (called on RTOS thread context switch) 66 | /// \param[in] id TrustZone memory slot identifier 67 | /// \return execution status (1: success, 0: error) 68 | uint32_t TZ_StoreContext_S (TZ_MemoryId_t id); 69 | 70 | #endif // TZ_CONTEXT_H 71 | -------------------------------------------------------------------------------- /section-01/examples/example.s: -------------------------------------------------------------------------------- 1 | .section __TEXT,__text,regular,pure_instructions 2 | .build_version macos, 15, 0 sdk_version 15, 5 3 | .globl _main ; -- Begin function main 4 | .p2align 2 5 | _main: ; @main 6 | .cfi_startproc 7 | ; %bb.0: 8 | sub sp, sp, #64 9 | stp x29, x30, [sp, #48] ; 16-byte Folded Spill 10 | add x29, sp, #48 11 | .cfi_def_cfa w29, 16 12 | .cfi_offset w30, -8 13 | .cfi_offset w29, -16 14 | stur wzr, [x29, #-4] 15 | stur w0, [x29, #-8] 16 | stur x1, [x29, #-16] 17 | adrp x0, l_.str@PAGE 18 | add x0, x0, l_.str@PAGEOFF 19 | bl _printf 20 | mov x9, sp 21 | mov x8, #7 ; =0x7 22 | str x8, [x9] 23 | adrp x0, l_.str.1@PAGE 24 | add x0, x0, l_.str.1@PAGEOFF 25 | bl _printf 26 | adrp x0, l_.str.2@PAGE 27 | add x0, x0, l_.str.2@PAGEOFF 28 | bl _printf 29 | ldur w8, [x29, #-8] 30 | subs w8, w8, #1 31 | b.le LBB0_6 32 | b LBB0_1 33 | LBB0_1: 34 | ldur w8, [x29, #-8] 35 | mov w9, #1 ; =0x1 36 | str w9, [sp, #24] ; 4-byte Folded Spill 37 | subs w10, w8, #1 38 | mov x9, sp 39 | ; implicit-def: $x8 40 | mov x8, x10 41 | str x8, [x9] 42 | adrp x0, l_.str.3@PAGE 43 | add x0, x0, l_.str.3@PAGEOFF 44 | bl _printf 45 | ldr w8, [sp, #24] ; 4-byte Folded Reload 46 | stur w8, [x29, #-20] 47 | b LBB0_2 48 | LBB0_2: ; =>This Inner Loop Header: Depth=1 49 | ldur w8, [x29, #-20] 50 | ldur w9, [x29, #-8] 51 | subs w8, w8, w9 52 | b.ge LBB0_5 53 | b LBB0_3 54 | LBB0_3: ; in Loop: Header=BB0_2 Depth=1 55 | ldur w8, [x29, #-20] 56 | mov x10, x8 57 | ldur x8, [x29, #-16] 58 | ldursw x9, [x29, #-20] 59 | ldr x8, [x8, x9, lsl #3] 60 | mov x9, sp 61 | str x10, [x9] 62 | str x8, [x9, #8] 63 | adrp x0, l_.str.4@PAGE 64 | add x0, x0, l_.str.4@PAGEOFF 65 | bl _printf 66 | b LBB0_4 67 | LBB0_4: ; in Loop: Header=BB0_2 Depth=1 68 | ldur w8, [x29, #-20] 69 | add w8, w8, #1 70 | stur w8, [x29, #-20] 71 | b LBB0_2 72 | LBB0_5: 73 | b LBB0_7 74 | LBB0_6: 75 | adrp x0, l_.str.5@PAGE 76 | add x0, x0, l_.str.5@PAGEOFF 77 | bl _printf 78 | b LBB0_7 79 | LBB0_7: 80 | mov w0, #0 ; =0x0 81 | ldp x29, x30, [sp, #48] ; 16-byte Folded Reload 82 | add sp, sp, #64 83 | ret 84 | .cfi_endproc 85 | ; -- End function 86 | .section __TEXT,__cstring,cstring_literals 87 | l_.str: ; @.str 88 | .asciz "Hello, world!\n" 89 | 90 | l_.str.1: ; @.str.1 91 | .asciz "The sum of 3 and 4 is: %d\n" 92 | 93 | l_.str.2: ; @.str.2 94 | .asciz "Debug mode is disabled.\n" 95 | 96 | l_.str.3: ; @.str.3 97 | .asciz "You provided %d argument(s):\n" 98 | 99 | l_.str.4: ; @.str.4 100 | .asciz "Argument %d: %s\n" 101 | 102 | l_.str.5: ; @.str.5 103 | .asciz "No additional arguments provided.\n" 104 | 105 | .subsections_via_symbols 106 | -------------------------------------------------------------------------------- /section-01/projects/minishell.md: -------------------------------------------------------------------------------- 1 | # 3. Mini Shell 2 | 3 | ## Goal: Interactive REPL that dispatches commands based on string input 4 | 5 | A read–eval–print loop (REPL), also termed an interactive toplevel or language shell, is a simple interactive computer programming environment that takes single user inputs, executes them, and returns the result to the user; a program written in a REPL environment is executed piecewise. 6 | 7 | ## Required Features: 8 | 9 | Maintain a command table: 10 | 11 | ```C 12 | typedef struct { 13 | const char* name; 14 | void (*func)(void); 15 | } command_t; 16 | ``` 17 | 18 | Implement at least: 19 | 20 | - help: list all commands 21 | 22 | - greet: print greeting 23 | 24 | - add: take two user-input ints and print sum 25 | 26 | - exit: exit loop 27 | 28 | Use fgets() and strcmp() to interpret commands 29 | 30 | Run in a loop until exit 31 | 32 | Add timestamp and uptime 33 | 34 | Optional: ASCII art commands 35 | 36 | ## Test Harness: 37 | 38 | Show interaction. 39 | 40 | Use print statements to demonstrate internal behavior. 41 | 42 | ### Instructions and requirements that apply to all projects: 43 | 44 | - You must link your project as a submodule within your forked copy of the repository 45 | 46 | - Your code must be modular. You must write header files for each source file you write. You must also keep source files in a subdirectory called `src` and header files in a subdirectory called `inc`. 47 | 48 | - This goes without saying, but you may only use the C language. 49 | 50 | - If you so choose, you may use inline assembly. This is optional. 51 | - You must have comments. Minimum 1 multi-line comment per function. 52 | 53 | - You must use the _Make_ build system and you must write your own `makefile`. Requirements for build system: 54 | 55 | - It must place build output files in a subdirectory called `build`. 56 | - It should support `make clean`, which cleans the `build` folder. 57 | - It should support `make run`, which runs the built executable. 58 | 59 | - Create a GitHub Actions workflow in `.github/workflows/build.yml`. Your workflow must: 60 | 61 | - Run on `ubuntu-latest` 62 | 63 | - Perform the following: 64 | 65 | - Checkout the repository 66 | 67 | - Initialize and update submodules 68 | 69 | - Run make and confirm a clean build 70 | 71 | - (Optional bonus) Run make run and check for expected output 72 | 73 | - You must have a minimum of 7 **well-named, significant** commits. If you think your project can be finished under 7 commits, it is not hard enough. 74 | 75 | - Pull requests for merging features on branches is not required. 76 | 77 | - Create a `README.md` that aptly describes what your project does. Your `README.md` must also contain **all** of the following: 78 | 79 | - A directory tree: use the `tree` command line tool 80 | - A short explanation of each module 81 | 82 | - If you need help, I have created an example project that satisfies all of the conditions (except module explanations and comments). View it [here](https://github.com/wxkim/julia). 83 | 84 | - Note: Your project should be significantly **less** complex than the example. 85 | 86 | - Finally, your project must work. It should build, and functionality error should be minimal, if not zero. 87 | - You do not have to make this project cross-platform. 88 | -------------------------------------------------------------------------------- /section-05/WORK.md: -------------------------------------------------------------------------------- 1 | # Work for section 05 2 | 3 | The tasks listed in this document also exist in the reading. 4 | There will be some additional tasks and more specific instructions in this document. 5 | 6 | # Analog Filtering Exercises 7 | 8 | ## Exercise 1: Fourier Series Visualization 9 | Using Desmos, graph the fourier series given by the expression: 10 | $$f(x)=\lim_{a\to\infty}\sum_{n=1}^{a}\frac{\sin((2n-1)2\pi x)}{2n-1}$$ 11 | - When you put this into desmos, drop the limit and use $a$ as a parameter. 12 | - As you increase the value of $a$, you should see the waveform make a better approximation of a square wave. 13 | 14 | You should be able to copy and paste the following into desmos, then press enter: 15 | ```f(x)=\sum_{n=1}^{a}\frac{\sin((2n-1)2\pi x)}{2n-1}``` 16 | 17 | You should see a slider appear for the variable $a$. 18 | 19 | ## Exercise 2: Experiment with Filtering 20 | Build and experiment with your own low pass filter. You can do any of the following: 21 | - Build the filter in EveryCircuit 22 | - Build it in LT Spice 23 | - Build it in the real world 24 | 25 | # Digital Filtering Exercises 26 | 27 | ## Exercise 1 28 | 29 | In tinkercad, write a program to sample a signal using the ADC on an arduino. 30 | Here is some example code: 31 | ``` c++ 32 | #define DEL 100 33 | #define NUM 1000 34 | 35 | void setup() 36 | { 37 | Serial.begin(115200); 38 | int aout = 0; 39 | 40 | for (int i=0; i 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | 34 | /* Variables */ 35 | extern int __io_putchar(int ch) __attribute__((weak)); 36 | extern int __io_getchar(void) __attribute__((weak)); 37 | 38 | 39 | char *__env[1] = { 0 }; 40 | char **environ = __env; 41 | 42 | 43 | /* Functions */ 44 | void initialise_monitor_handles() 45 | { 46 | } 47 | 48 | int _getpid(void) 49 | { 50 | return 1; 51 | } 52 | 53 | int _kill(int pid, int sig) 54 | { 55 | (void)pid; 56 | (void)sig; 57 | errno = EINVAL; 58 | return -1; 59 | } 60 | 61 | void _exit (int status) 62 | { 63 | _kill(status, -1); 64 | while (1) {} /* Make sure we hang here */ 65 | } 66 | 67 | __attribute__((weak)) int _read(int file, char *ptr, int len) 68 | { 69 | (void)file; 70 | int DataIdx; 71 | 72 | for (DataIdx = 0; DataIdx < len; DataIdx++) 73 | { 74 | *ptr++ = __io_getchar(); 75 | } 76 | 77 | return len; 78 | } 79 | 80 | __attribute__((weak)) int _write(int file, char *ptr, int len) 81 | { 82 | (void)file; 83 | int DataIdx; 84 | 85 | for (DataIdx = 0; DataIdx < len; DataIdx++) 86 | { 87 | __io_putchar(*ptr++); 88 | } 89 | return len; 90 | } 91 | 92 | int _close(int file) 93 | { 94 | (void)file; 95 | return -1; 96 | } 97 | 98 | 99 | int _fstat(int file, struct stat *st) 100 | { 101 | (void)file; 102 | st->st_mode = S_IFCHR; 103 | return 0; 104 | } 105 | 106 | int _isatty(int file) 107 | { 108 | (void)file; 109 | return 1; 110 | } 111 | 112 | int _lseek(int file, int ptr, int dir) 113 | { 114 | (void)file; 115 | (void)ptr; 116 | (void)dir; 117 | return 0; 118 | } 119 | 120 | int _open(char *path, int flags, ...) 121 | { 122 | (void)path; 123 | (void)flags; 124 | /* Pretend like we always fail */ 125 | return -1; 126 | } 127 | 128 | int _wait(int *status) 129 | { 130 | (void)status; 131 | errno = ECHILD; 132 | return -1; 133 | } 134 | 135 | int _unlink(char *name) 136 | { 137 | (void)name; 138 | errno = ENOENT; 139 | return -1; 140 | } 141 | 142 | int _times(struct tms *buf) 143 | { 144 | (void)buf; 145 | return -1; 146 | } 147 | 148 | int _stat(char *file, struct stat *st) 149 | { 150 | (void)file; 151 | st->st_mode = S_IFCHR; 152 | return 0; 153 | } 154 | 155 | int _link(char *old, char *new) 156 | { 157 | (void)old; 158 | (void)new; 159 | errno = EMLINK; 160 | return -1; 161 | } 162 | 163 | int _fork(void) 164 | { 165 | errno = EAGAIN; 166 | return -1; 167 | } 168 | 169 | int _execve(char *name, char **argv, char **env) 170 | { 171 | (void)name; 172 | (void)argv; 173 | (void)env; 174 | errno = ENOMEM; 175 | return -1; 176 | } 177 | -------------------------------------------------------------------------------- /section-01/projects/memorytracker.md: -------------------------------------------------------------------------------- 1 | # 2. Memory Tracker 2 | 3 | ## Goal: Simulate and track dynamic memory allocations using structs 4 | 5 | You’ll build a simple system that logs every memory allocation made, stores their metadata, and allows manual deletion by ID. This helps you practice pointers, dynamic arrays, and memory-safe programming. 6 | 7 | ## Required Features: 8 | 9 | Define a struct: 10 | 11 | ```C 12 | typedef struct { 13 | int id; // Unique identifier for this allocation 14 | size_t size; // Size in bytes 15 | void* addr; // Address returned by malloc 16 | } allocation_t; 17 | ``` 18 | 19 | ### Implement at least: 20 | 21 | `add_allocation`: Allocates memory and stores metadata in a dynamic array 22 | 23 | `remove_allocation`: Frees memory and removes the corresponding struct by ID 24 | 25 | `print_allocations`: Lists all active allocations with address and size 26 | 27 | ### Internally: 28 | 29 | Use `malloc` and `free` for memory 30 | 31 | Use `realloc` to grow the dynamic array of `allocation_t` 32 | 33 | Manually shift array elements when removing 34 | 35 | Use simple integer IDs to track which allocation is which. 36 | 37 | # Test Harness: 38 | 39 | In `main()`, hardcode a sequence of operations: 40 | 41 | - Add 3 allocations 42 | 43 | - Print all 44 | 45 | - Remove one by ID 46 | 47 | - Print again 48 | 49 | - Free all at the end 50 | 51 | - Optional Features: 52 | 53 | - Add lookup by ID function 54 | 55 | - Automatically assign IDs 56 | 57 | - Add safety checks for double-free or invalid IDs 58 | 59 | ### Instructions and requirements that apply to all projects: 60 | 61 | - You must link your project as a submodule within your forked copy of the repository 62 | 63 | - Your code must be modular. You must write header files for each source file you write. You must also keep source files in a subdirectory called `src` and header files in a subdirectory called `inc`. 64 | 65 | - This goes without saying, but you may only use the C language. 66 | 67 | - If you so choose, you may use inline assembly. This is optional. 68 | - You must have comments. Minimum 1 multi-line comment per function. 69 | 70 | - You must use the _Make_ build system and you must write your own `makefile`. Requirements for build system: 71 | 72 | - It must place build output files in a subdirectory called `build`. 73 | - It should support `make clean`, which cleans the `build` folder. 74 | - It should support `make run`, which runs the built executable. 75 | 76 | - Create a GitHub Actions workflow in `.github/workflows/build.yml`. Your workflow must: 77 | 78 | - Run on `ubuntu-latest` 79 | 80 | - Perform the following: 81 | 82 | - Checkout the repository 83 | 84 | - Initialize and update submodules 85 | 86 | - Run make and confirm a clean build 87 | 88 | - (Optional bonus) Run make run and check for expected output 89 | 90 | - You must have a minimum of 7 **well-named, significant** commits. If you think your project can be finished under 7 commits, it is not hard enough. 91 | 92 | - Pull requests for merging features on branches is not required. 93 | 94 | - Create a `README.md` that aptly describes what your project does. Your `README.md` must also contain **all** of the following: 95 | 96 | - A directory tree: use the `tree` command line tool 97 | - A short explanation of each module 98 | 99 | - If you need help, I have created an example project that satisfies all of the conditions (except module explanations and comments). View it [here](https://github.com/wxkim/julia). 100 | 101 | - Note: Your project should be significantly **less** complex than the example. 102 | 103 | - Finally, your project must work. It should build, and functionality error should be minimal, if not zero. 104 | - You do not have to make this project cross-platform. 105 | -------------------------------------------------------------------------------- /section-00/WORK.md: -------------------------------------------------------------------------------- 1 | # Work for section 00 2 | 3 | Estimated completion time: 1 hour. 4 | 5 | ## 0. Before you start: 6 | 7 | While not required, we recommend you buy your own microcontroller to test out certain parts of the onboarding as you go along. 8 | 9 | Many of the tutorials are written around this microcontroller: the `STM32F030R8` chip on the `NUCLEO-F030R8` board package. They're about $11. 10 | 11 | You can buy one here: [Buy NUCLEO-F030R8 at Digikey](https://www.digikey.com/en/products/detail/stmicroelectronics/NUCLEO-F030R8/4695526). 12 | 13 | As an engineering student, it's good to have one on hand anyways. 14 | 15 | ## 1. Make a GitHub account if you don't have one. 16 | 17 | Use whatever email you prefer. If you lose access to the account and email, your work will be very hard to recover. 18 | 19 | ## 2. From the website, fork this repository to your account. 20 | 21 | From the website: https://github.com/DallasFormulaRacing/embedded-onboarding 22 | 23 | ## 3. Install git. 24 | 25 | There are mamy ways to do this. As long as it makes it to your `usr/bin` or can run from the terminal, it will work. 26 | 27 | ## 4. Using your terminal skills, navigate to a directory of your choosing. 28 | 29 | Make sure this directory is safe, accessible, and ideally, built into your computer (not an external device). 30 | 31 | You will clone the forked repository into this directory in this next step so make sure you're okay with having the repository here. 32 | 33 | ## 5. Set up your local git creditials. 34 | 35 | Git will sometimes need credentials from the user in order to perform operations. Also, GitHub stopped accepting password-based HTTPS. You’ll need a [personal access token](https://github.com/settings/tokens). 36 | 37 | ## 6. Clone the repository to your local. 38 | 39 | Make sure its the right one; not the template. Open this in the website or in VSCode. On VSCode, you can press CTRL+SHIFT+V or CMD+SHIFT+V to enter Markdown preview mode. 40 | 41 | ## 7. Submit for Section 00 42 | 43 | Check your work: 44 | 45 | Run `git status` in the directory of the repo. You shouldnt get any errors. 46 | 47 | Run `git remote -v` in the directory. You should get links to repositories that **have your username in them**. If the link says `github.com/DallasFormulaRacing/...`, you got it wrong. 48 | 49 | ### -> TO DO <- 50 | 51 | 1\. Use your terminal skills and create a file called `submit.md` **inside** the `section-00` folder (if youre not reading this on github.com, you're in it already). 52 | 53 | 2\. Inside that file `submit.md` answer the following questions: 54 | 55 | - Run a command line terminal that does both of the following: 56 | - lists **all** files in the parent directory (`..`) **and** 57 | - only prints files that match the expression `\.git`. 58 | - What command did you run? 59 | 60 | - After running that command, you should see 3 (or 4) files. What files do you see? 61 | 62 | 3\. Use the Git command-line tools to 63 | 64 | - First check the `status` of your repository's git to make sure you didn't touch anything you shouldn't have. Only the appropriate files should show up here. 65 | 66 | - Then `add` your changes to a stage that you made to this repository. 67 | 68 | - Then `commit` those changes with an appropriate message. 69 | 70 | - Finally, `push` to the origin to finalize your work here. 71 | 72 | - Don't be afraid to look this up if you have to. 73 | 74 | 4\. You are done with section 0. 75 | 76 | - Open this repository in an editor of your choice. I recommend VS Code. 77 | 78 | # References: 79 | 80 | [1] https://git-scm.com/docs/gitcredentials 81 | 82 | # Most Common Mistakes 83 | 84 | - **Cloning the template instead of your fork** 85 | 86 | Check the URL. It should have _your_ GitHub username in it. 87 | 88 | - **Skipping Git config** 89 | 90 | If your commits show up as “unknown” or can’t be pushed, it’s probably because you didn’t set your name/email or your credentials are wrong. 91 | 92 | - **Trying to use Git without installing it** 93 | 94 | Install git. 95 | 96 | - **Cloning into a weird directory** 97 | 98 | Network drives, external drives, or synced folders (like OneDrive or iCloud) are not recommended for this. Use your local disk. 99 | 100 | - **Running `rm -rf` (or any command for that matter) without thinking** 101 | 102 | Do not do this. Never run a command before knowing exactly what it does. 103 | -------------------------------------------------------------------------------- /section-01/blinky/Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_cortex.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file stm32f0xx_hal_cortex.h 4 | * @author MCD Application Team 5 | * @brief Header file of CORTEX HAL module. 6 | ****************************************************************************** 7 | * @attention 8 | * 9 | * Copyright (c) 2016 STMicroelectronics. 10 | * All rights reserved. 11 | * 12 | * This software is licensed under terms that can be found in the LICENSE file in 13 | * the root directory of this software component. 14 | * If no LICENSE file comes with this software, it is provided AS-IS. 15 | * 16 | ****************************************************************************** 17 | */ 18 | 19 | /* Define to prevent recursive inclusion -------------------------------------*/ 20 | #ifndef __STM32F0xx_HAL_CORTEX_H 21 | #define __STM32F0xx_HAL_CORTEX_H 22 | 23 | #ifdef __cplusplus 24 | extern "C" { 25 | #endif 26 | 27 | /* Includes ------------------------------------------------------------------*/ 28 | #include "stm32f0xx_hal_def.h" 29 | 30 | /** @addtogroup STM32F0xx_HAL_Driver 31 | * @{ 32 | */ 33 | 34 | /** @addtogroup CORTEX CORTEX 35 | * @{ 36 | */ 37 | /* Exported types ------------------------------------------------------------*/ 38 | /* Exported constants --------------------------------------------------------*/ 39 | 40 | /** @defgroup CORTEX_Exported_Constants CORTEX Exported Constants 41 | * @{ 42 | */ 43 | 44 | /** @defgroup CORTEX_SysTick_clock_source CORTEX SysTick clock source 45 | * @{ 46 | */ 47 | #define SYSTICK_CLKSOURCE_HCLK_DIV8 (0x00000000U) 48 | #define SYSTICK_CLKSOURCE_HCLK (0x00000004U) 49 | 50 | /** 51 | * @} 52 | */ 53 | 54 | /** 55 | * @} 56 | */ 57 | 58 | /* Exported Macros -----------------------------------------------------------*/ 59 | 60 | /* Exported functions --------------------------------------------------------*/ 61 | /** @addtogroup CORTEX_Exported_Functions CORTEX Exported Functions 62 | * @{ 63 | */ 64 | /** @addtogroup CORTEX_Exported_Functions_Group1 Initialization and de-initialization functions 65 | * @brief Initialization and Configuration functions 66 | * @{ 67 | */ 68 | /* Initialization and de-initialization functions *******************************/ 69 | void HAL_NVIC_SetPriority(IRQn_Type IRQn,uint32_t PreemptPriority, uint32_t SubPriority); 70 | void HAL_NVIC_EnableIRQ(IRQn_Type IRQn); 71 | void HAL_NVIC_DisableIRQ(IRQn_Type IRQn); 72 | void HAL_NVIC_SystemReset(void); 73 | uint32_t HAL_SYSTICK_Config(uint32_t TicksNumb); 74 | /** 75 | * @} 76 | */ 77 | 78 | /** @addtogroup CORTEX_Exported_Functions_Group2 Peripheral Control functions 79 | * @brief Cortex control functions 80 | * @{ 81 | */ 82 | 83 | /* Peripheral Control functions *************************************************/ 84 | uint32_t HAL_NVIC_GetPriority(IRQn_Type IRQn); 85 | uint32_t HAL_NVIC_GetPendingIRQ(IRQn_Type IRQn); 86 | void HAL_NVIC_SetPendingIRQ(IRQn_Type IRQn); 87 | void HAL_NVIC_ClearPendingIRQ(IRQn_Type IRQn); 88 | void HAL_SYSTICK_CLKSourceConfig(uint32_t CLKSource); 89 | void HAL_SYSTICK_IRQHandler(void); 90 | void HAL_SYSTICK_Callback(void); 91 | /** 92 | * @} 93 | */ 94 | 95 | /** 96 | * @} 97 | */ 98 | 99 | /* Private types -------------------------------------------------------------*/ 100 | /* Private variables ---------------------------------------------------------*/ 101 | /* Private constants ---------------------------------------------------------*/ 102 | /* Private macros ------------------------------------------------------------*/ 103 | /** @defgroup CORTEX_Private_Macros CORTEX Private Macros 104 | * @{ 105 | */ 106 | #define IS_NVIC_PREEMPTION_PRIORITY(PRIORITY) ((PRIORITY) < 0x4) 107 | 108 | #define IS_NVIC_DEVICE_IRQ(IRQ) ((IRQ) >= 0x00) 109 | 110 | #define IS_SYSTICK_CLK_SOURCE(SOURCE) (((SOURCE) == SYSTICK_CLKSOURCE_HCLK) || \ 111 | ((SOURCE) == SYSTICK_CLKSOURCE_HCLK_DIV8)) 112 | /** 113 | * @} 114 | */ 115 | 116 | /** 117 | * @} 118 | */ 119 | 120 | /** 121 | * @} 122 | */ 123 | 124 | #ifdef __cplusplus 125 | } 126 | #endif 127 | 128 | #endif /* __STM32F0xx_HAL_CORTEX_H */ 129 | 130 | 131 | 132 | -------------------------------------------------------------------------------- /section-01/blinky/Core/Src/stm32f0xx_hal_msp.c: -------------------------------------------------------------------------------- 1 | /* USER CODE BEGIN Header */ 2 | /** 3 | ****************************************************************************** 4 | * @file stm32f0xx_hal_msp.c 5 | * @brief This file provides code for the MSP Initialization 6 | * and de-Initialization codes. 7 | ****************************************************************************** 8 | * @attention 9 | * 10 | * Copyright (c) 2025 STMicroelectronics. 11 | * All rights reserved. 12 | * 13 | * This software is licensed under terms that can be found in the LICENSE file 14 | * in the root directory of this software component. 15 | * If no LICENSE file comes with this software, it is provided AS-IS. 16 | * 17 | ****************************************************************************** 18 | */ 19 | /* USER CODE END Header */ 20 | 21 | /* Includes ------------------------------------------------------------------*/ 22 | #include "main.h" 23 | /* USER CODE BEGIN Includes */ 24 | 25 | /* USER CODE END Includes */ 26 | 27 | /* Private typedef -----------------------------------------------------------*/ 28 | /* USER CODE BEGIN TD */ 29 | 30 | /* USER CODE END TD */ 31 | 32 | /* Private define ------------------------------------------------------------*/ 33 | /* USER CODE BEGIN Define */ 34 | 35 | /* USER CODE END Define */ 36 | 37 | /* Private macro -------------------------------------------------------------*/ 38 | /* USER CODE BEGIN Macro */ 39 | 40 | /* USER CODE END Macro */ 41 | 42 | /* Private variables ---------------------------------------------------------*/ 43 | /* USER CODE BEGIN PV */ 44 | 45 | /* USER CODE END PV */ 46 | 47 | /* Private function prototypes -----------------------------------------------*/ 48 | /* USER CODE BEGIN PFP */ 49 | 50 | /* USER CODE END PFP */ 51 | 52 | /* External functions --------------------------------------------------------*/ 53 | /* USER CODE BEGIN ExternalFunctions */ 54 | 55 | /* USER CODE END ExternalFunctions */ 56 | 57 | /* USER CODE BEGIN 0 */ 58 | 59 | /* USER CODE END 0 */ 60 | /** 61 | * Initializes the Global MSP. 62 | */ 63 | void HAL_MspInit(void) 64 | { 65 | 66 | /* USER CODE BEGIN MspInit 0 */ 67 | 68 | /* USER CODE END MspInit 0 */ 69 | 70 | __HAL_RCC_SYSCFG_CLK_ENABLE(); 71 | __HAL_RCC_PWR_CLK_ENABLE(); 72 | 73 | /* System interrupt init*/ 74 | 75 | /* USER CODE BEGIN MspInit 1 */ 76 | 77 | /* USER CODE END MspInit 1 */ 78 | } 79 | 80 | /** 81 | * @brief UART MSP Initialization 82 | * This function configures the hardware resources used in this example 83 | * @param huart: UART handle pointer 84 | * @retval None 85 | */ 86 | void HAL_UART_MspInit(UART_HandleTypeDef* huart) 87 | { 88 | GPIO_InitTypeDef GPIO_InitStruct = {0}; 89 | if(huart->Instance==USART2) 90 | { 91 | /* USER CODE BEGIN USART2_MspInit 0 */ 92 | 93 | /* USER CODE END USART2_MspInit 0 */ 94 | /* Peripheral clock enable */ 95 | __HAL_RCC_USART2_CLK_ENABLE(); 96 | 97 | __HAL_RCC_GPIOA_CLK_ENABLE(); 98 | /**USART2 GPIO Configuration 99 | PA2 ------> USART2_TX 100 | PA3 ------> USART2_RX 101 | */ 102 | GPIO_InitStruct.Pin = USART_TX_Pin|USART_RX_Pin; 103 | GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; 104 | GPIO_InitStruct.Pull = GPIO_NOPULL; 105 | GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; 106 | GPIO_InitStruct.Alternate = GPIO_AF1_USART2; 107 | HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); 108 | 109 | /* USER CODE BEGIN USART2_MspInit 1 */ 110 | 111 | /* USER CODE END USART2_MspInit 1 */ 112 | 113 | } 114 | 115 | } 116 | 117 | /** 118 | * @brief UART MSP De-Initialization 119 | * This function freeze the hardware resources used in this example 120 | * @param huart: UART handle pointer 121 | * @retval None 122 | */ 123 | void HAL_UART_MspDeInit(UART_HandleTypeDef* huart) 124 | { 125 | if(huart->Instance==USART2) 126 | { 127 | /* USER CODE BEGIN USART2_MspDeInit 0 */ 128 | 129 | /* USER CODE END USART2_MspDeInit 0 */ 130 | /* Peripheral clock disable */ 131 | __HAL_RCC_USART2_CLK_DISABLE(); 132 | 133 | /**USART2 GPIO Configuration 134 | PA2 ------> USART2_TX 135 | PA3 ------> USART2_RX 136 | */ 137 | HAL_GPIO_DeInit(GPIOA, USART_TX_Pin|USART_RX_Pin); 138 | 139 | /* USER CODE BEGIN USART2_MspDeInit 1 */ 140 | 141 | /* USER CODE END USART2_MspDeInit 1 */ 142 | } 143 | 144 | } 145 | 146 | /* USER CODE BEGIN 1 */ 147 | 148 | /* USER CODE END 1 */ 149 | -------------------------------------------------------------------------------- /section-01/blinky/Core/Src/stm32f0xx_it.c: -------------------------------------------------------------------------------- 1 | /* USER CODE BEGIN Header */ 2 | /** 3 | ****************************************************************************** 4 | * @file stm32f0xx_it.c 5 | * @brief Interrupt Service Routines. 6 | ****************************************************************************** 7 | * @attention 8 | * 9 | * Copyright (c) 2025 STMicroelectronics. 10 | * All rights reserved. 11 | * 12 | * This software is licensed under terms that can be found in the LICENSE file 13 | * in the root directory of this software component. 14 | * If no LICENSE file comes with this software, it is provided AS-IS. 15 | * 16 | ****************************************************************************** 17 | */ 18 | /* USER CODE END Header */ 19 | 20 | /* Includes ------------------------------------------------------------------*/ 21 | #include "main.h" 22 | #include "stm32f0xx_it.h" 23 | /* Private includes ----------------------------------------------------------*/ 24 | /* USER CODE BEGIN Includes */ 25 | /* USER CODE END Includes */ 26 | 27 | /* Private typedef -----------------------------------------------------------*/ 28 | /* USER CODE BEGIN TD */ 29 | 30 | /* USER CODE END TD */ 31 | 32 | /* Private define ------------------------------------------------------------*/ 33 | /* USER CODE BEGIN PD */ 34 | 35 | /* USER CODE END PD */ 36 | 37 | /* Private macro -------------------------------------------------------------*/ 38 | /* USER CODE BEGIN PM */ 39 | 40 | /* USER CODE END PM */ 41 | 42 | /* Private variables ---------------------------------------------------------*/ 43 | /* USER CODE BEGIN PV */ 44 | 45 | /* USER CODE END PV */ 46 | 47 | /* Private function prototypes -----------------------------------------------*/ 48 | /* USER CODE BEGIN PFP */ 49 | 50 | /* USER CODE END PFP */ 51 | 52 | /* Private user code ---------------------------------------------------------*/ 53 | /* USER CODE BEGIN 0 */ 54 | 55 | /* USER CODE END 0 */ 56 | 57 | /* External variables --------------------------------------------------------*/ 58 | 59 | /* USER CODE BEGIN EV */ 60 | 61 | /* USER CODE END EV */ 62 | 63 | /******************************************************************************/ 64 | /* Cortex-M0 Processor Interruption and Exception Handlers */ 65 | /******************************************************************************/ 66 | /** 67 | * @brief This function handles Non maskable interrupt. 68 | */ 69 | void NMI_Handler(void) 70 | { 71 | /* USER CODE BEGIN NonMaskableInt_IRQn 0 */ 72 | 73 | /* USER CODE END NonMaskableInt_IRQn 0 */ 74 | /* USER CODE BEGIN NonMaskableInt_IRQn 1 */ 75 | while (1) 76 | { 77 | } 78 | /* USER CODE END NonMaskableInt_IRQn 1 */ 79 | } 80 | 81 | /** 82 | * @brief This function handles Hard fault interrupt. 83 | */ 84 | void HardFault_Handler(void) 85 | { 86 | /* USER CODE BEGIN HardFault_IRQn 0 */ 87 | 88 | /* USER CODE END HardFault_IRQn 0 */ 89 | while (1) 90 | { 91 | /* USER CODE BEGIN W1_HardFault_IRQn 0 */ 92 | /* USER CODE END W1_HardFault_IRQn 0 */ 93 | } 94 | } 95 | 96 | /** 97 | * @brief This function handles System service call via SWI instruction. 98 | */ 99 | void SVC_Handler(void) 100 | { 101 | /* USER CODE BEGIN SVC_IRQn 0 */ 102 | 103 | /* USER CODE END SVC_IRQn 0 */ 104 | /* USER CODE BEGIN SVC_IRQn 1 */ 105 | 106 | /* USER CODE END SVC_IRQn 1 */ 107 | } 108 | 109 | /** 110 | * @brief This function handles Pendable request for system service. 111 | */ 112 | void PendSV_Handler(void) 113 | { 114 | /* USER CODE BEGIN PendSV_IRQn 0 */ 115 | 116 | /* USER CODE END PendSV_IRQn 0 */ 117 | /* USER CODE BEGIN PendSV_IRQn 1 */ 118 | 119 | /* USER CODE END PendSV_IRQn 1 */ 120 | } 121 | 122 | /** 123 | * @brief This function handles System tick timer. 124 | */ 125 | void SysTick_Handler(void) 126 | { 127 | /* USER CODE BEGIN SysTick_IRQn 0 */ 128 | 129 | /* USER CODE END SysTick_IRQn 0 */ 130 | HAL_IncTick(); 131 | /* USER CODE BEGIN SysTick_IRQn 1 */ 132 | 133 | /* USER CODE END SysTick_IRQn 1 */ 134 | } 135 | 136 | /******************************************************************************/ 137 | /* STM32F0xx Peripheral Interrupt Handlers */ 138 | /* Add here the Interrupt Handlers for the used peripherals. */ 139 | /* For the available peripheral interrupt handler names, */ 140 | /* please refer to the startup file (startup_stm32f0xx.s). */ 141 | /******************************************************************************/ 142 | 143 | /* USER CODE BEGIN 1 */ 144 | 145 | /* USER CODE END 1 */ 146 | -------------------------------------------------------------------------------- /section-01/blinky/blinky.ioc: -------------------------------------------------------------------------------- 1 | #MicroXplorer Configuration settings - do not modify 2 | CAD.formats= 3 | CAD.pinconfig= 4 | CAD.provider= 5 | File.Version=6 6 | KeepUserPlacement=false 7 | Mcu.CPN=STM32F030R8T6 8 | Mcu.Family=STM32F0 9 | Mcu.IP0=NVIC 10 | Mcu.IP1=RCC 11 | Mcu.IP2=SYS 12 | Mcu.IP3=USART2 13 | Mcu.IPNb=4 14 | Mcu.Name=STM32F030R8Tx 15 | Mcu.Package=LQFP64 16 | Mcu.Pin0=PC13 17 | Mcu.Pin1=PC14-OSC32_IN 18 | Mcu.Pin2=PC15-OSC32_OUT 19 | Mcu.Pin3=PF0-OSC_IN 20 | Mcu.Pin4=PF1-OSC_OUT 21 | Mcu.Pin5=PA2 22 | Mcu.Pin6=PA3 23 | Mcu.Pin7=PA5 24 | Mcu.Pin8=PA13 25 | Mcu.Pin9=PA14 26 | Mcu.PinsNb=10 27 | Mcu.ThirdPartyNb=0 28 | Mcu.UserConstants= 29 | Mcu.UserName=STM32F030R8Tx 30 | MxCube.Version=6.13.0 31 | MxDb.Version=DB.6.0.130 32 | NVIC.ForceEnableDMAVector=true 33 | NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false 34 | NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false 35 | NVIC.PendSV_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false 36 | NVIC.SVC_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:true 37 | NVIC.SysTick_IRQn=true\:0\:0\:true\:false\:true\:true\:true\:false 38 | PA13.GPIOParameters=GPIO_Label 39 | PA13.GPIO_Label=TMS 40 | PA13.Locked=true 41 | PA13.Mode=Serial_Wire 42 | PA13.Signal=SYS_SWDIO 43 | PA14.GPIOParameters=GPIO_Label 44 | PA14.GPIO_Label=TCK 45 | PA14.Locked=true 46 | PA14.Mode=Serial_Wire 47 | PA14.Signal=SYS_SWCLK 48 | PA2.GPIOParameters=GPIO_Speed,GPIO_PuPd,GPIO_Label,GPIO_Mode 49 | PA2.GPIO_Label=USART_TX 50 | PA2.GPIO_Mode=GPIO_MODE_AF_PP 51 | PA2.GPIO_PuPd=GPIO_NOPULL 52 | PA2.GPIO_Speed=GPIO_SPEED_FREQ_LOW 53 | PA2.Locked=true 54 | PA2.Mode=Asynchronous 55 | PA2.Signal=USART2_TX 56 | PA3.GPIOParameters=GPIO_Speed,GPIO_PuPd,GPIO_Label,GPIO_Mode 57 | PA3.GPIO_Label=USART_RX 58 | PA3.GPIO_Mode=GPIO_MODE_AF_PP 59 | PA3.GPIO_PuPd=GPIO_NOPULL 60 | PA3.GPIO_Speed=GPIO_SPEED_FREQ_LOW 61 | PA3.Locked=true 62 | PA3.Mode=Asynchronous 63 | PA3.Signal=USART2_RX 64 | PA5.GPIOParameters=GPIO_Speed,GPIO_PuPd,GPIO_Label,GPIO_Mode 65 | PA5.GPIO_Label=LD2 [Green Led] 66 | PA5.GPIO_Mode=GPIO_MODE_OUTPUT_PP 67 | PA5.GPIO_PuPd=GPIO_NOPULL 68 | PA5.GPIO_Speed=GPIO_SPEED_FREQ_LOW 69 | PA5.Locked=true 70 | PA5.Signal=GPIO_Output 71 | PC13.GPIOParameters=GPIO_Label,GPIO_ModeDefaultEXTI 72 | PC13.GPIO_Label=B1 [Blue PushButton] 73 | PC13.GPIO_ModeDefaultEXTI=GPIO_MODE_IT_FALLING 74 | PC13.Locked=true 75 | PC13.Signal=GPXTI13 76 | PC14-OSC32_IN.Locked=true 77 | PC14-OSC32_IN.Mode=LSE-External-Oscillator 78 | PC14-OSC32_IN.Signal=RCC_OSC32_IN 79 | PC15-OSC32_OUT.Locked=true 80 | PC15-OSC32_OUT.Mode=LSE-External-Oscillator 81 | PC15-OSC32_OUT.Signal=RCC_OSC32_OUT 82 | PF0-OSC_IN.Locked=true 83 | PF0-OSC_IN.Mode=HSE-External-Clock-Source 84 | PF0-OSC_IN.Signal=RCC_OSC_IN 85 | PF1-OSC_OUT.Locked=true 86 | PF1-OSC_OUT.Signal=RCC_OSC_OUT 87 | PinOutPanel.RotationAngle=0 88 | ProjectManager.AskForMigrate=true 89 | ProjectManager.BackupPrevious=false 90 | ProjectManager.CompilerOptimize=6 91 | ProjectManager.ComputerToolchain=false 92 | ProjectManager.CoupleFile=false 93 | ProjectManager.CustomerFirmwarePackage= 94 | ProjectManager.DefaultFWLocation=true 95 | ProjectManager.DeletePrevious=true 96 | ProjectManager.DeviceId=STM32F030R8Tx 97 | ProjectManager.FirmwarePackage=STM32Cube FW_F0 V1.11.5 98 | ProjectManager.FreePins=false 99 | ProjectManager.HalAssertFull=false 100 | ProjectManager.HeapSize=0x200 101 | ProjectManager.KeepUserCode=true 102 | ProjectManager.LastFirmware=true 103 | ProjectManager.LibraryCopy=1 104 | ProjectManager.MainLocation=Core/Src 105 | ProjectManager.MultiThreaded=true 106 | ProjectManager.NoMain=false 107 | ProjectManager.PreviousToolchain= 108 | ProjectManager.ProjectBuild=false 109 | ProjectManager.ProjectFileName=blinky.ioc 110 | ProjectManager.ProjectName=blinky 111 | ProjectManager.ProjectStructure= 112 | ProjectManager.RegisterCallBack= 113 | ProjectManager.StackSize=0x400 114 | ProjectManager.TargetToolchain=Makefile 115 | ProjectManager.ThreadSafeStrategy= 116 | ProjectManager.ToolChainLocation= 117 | ProjectManager.UAScriptAfterPath= 118 | ProjectManager.UAScriptBeforePath= 119 | ProjectManager.UnderRoot=false 120 | ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_USART2_UART_Init-USART2-false-HAL-true 121 | RCC.AHBFreq_Value=48000000 122 | RCC.APB1Freq_Value=48000000 123 | RCC.APB1TimFreq_Value=48000000 124 | RCC.FCLKCortexFreq_Value=48000000 125 | RCC.FamilyName=M 126 | RCC.HCLKFreq_Value=48000000 127 | RCC.IPParameters=AHBFreq_Value,APB1Freq_Value,APB1TimFreq_Value,FCLKCortexFreq_Value,FamilyName,HCLKFreq_Value,MCOFreq_Value,PLLCLKFreq_Value,PLLMCOFreq_Value,PLLMUL,SYSCLKFreq_VALUE,SYSCLKSource,TimSysFreq_Value,USART1Freq_Value 128 | RCC.MCOFreq_Value=48000000 129 | RCC.PLLCLKFreq_Value=48000000 130 | RCC.PLLMCOFreq_Value=24000000 131 | RCC.PLLMUL=RCC_PLL_MUL12 132 | RCC.SYSCLKFreq_VALUE=48000000 133 | RCC.SYSCLKSource=RCC_SYSCLKSOURCE_PLLCLK 134 | RCC.TimSysFreq_Value=48000000 135 | RCC.USART1Freq_Value=48000000 136 | SH.GPXTI13.0=GPIO_EXTI13 137 | SH.GPXTI13.ConfNb=1 138 | USART2.IPParameters=VirtualMode-Asynchronous 139 | USART2.VirtualMode-Asynchronous=VM_ASYNC 140 | board=NUCLEO-F030R8 141 | boardIOC=true 142 | -------------------------------------------------------------------------------- /section-02/WORK.md: -------------------------------------------------------------------------------- 1 | # Work for section 02 2 | 3 | Estimated completion time: 2 days. 4 | 5 | Do all of your work in this directory (but not in this file) so that it can be easily reviewed by a senior member later. 6 | 7 | You should constantly be referring back to the reading or other external sources. It is not expected of you to complete all the exercises in this unaided. 8 | 9 | ## Exercise 1: DIY HAL in C 10 | 11 | Remember blinking the LED in the last section? 12 | 13 | Find this function in the HAL files: `void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init)`. 14 | 15 | Delete the generated definition within the C file. Rewrite your own definition of it in C. You should be able to test it by seeing if it compiles, and if it actually blinks the LED. 16 | 17 | Do the exact same for `void HAL_GPIO_WritePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState)` and `void HAL_GPIO_TogglePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)`. 18 | 19 | ## Exercise 2: DIY HAL in Asm 20 | 21 | Write your own GPIO Init, GPIO toggle, and HAL Delay in assembly. The total length of the assembly file should not more than 70 lines. 22 | 23 | The goal of this exercise is to help you understand that HAL functionality ultimately reduces to bitwise manipulation of certain peripheral registers. 24 | 25 | Read carefully: 26 | 27 | A starter `gpio.s` assembly source file has been provided. It has been tested on an STM32L4. (Not the STM32F0, which is what you should use). There are multiple missing statements in the file. You must fill in the blanks as necessary to get the LED (whichever one you want, recommend a User LED and not a power LED) blinking. 28 | 29 | While there are missing words or numbers, there are no missing lines. You do not need to write separate lines of assembly. 30 | 31 | An accompanying `gpio.h` header file has also been provided. You do not need to edit it. 32 | 33 | These standalone files will not function properly. You are responsible for moving the source file into `Core/Src` and the header file into `Core/Inc`. You are also responsible for editing your Makefile to account for a new source file. 34 | 35 | Your main function should look like this: 36 | 37 | ```C 38 | int main(void) 39 | { 40 | my_gpio_init(GPIOA_BASE, 5, 0x01); 41 | 42 | while(1) { 43 | my_gpio_toggle(GPIOA_BASE, 5); 44 | my_hal_delay(100); 45 | } 46 | } 47 | ``` 48 | 49 | You should then see your LED blink. 50 | 51 | What did you learn? Explain each line of assembly (no complete sentences, just what it does and why). Write your response in another file in this directory. 52 | 53 | Ensure both compile. 54 | 55 | ## Exercise 3: Interrupts and Callbacks 56 | 57 | Pt 1: Follow this tutorial: https://wiki.st.com/stm32mcu/wiki/Getting_started_with_EXTI 58 | 59 | Pt 2: Follow this tutorial: https://community.st.com/t5/stm32-mcus/how-to-use-register-callbacks-in-stm32/ta-p/580499 60 | 61 | Do the equivalent for the F030RE8 board, as the tutorials follow intructions for another board. 62 | 63 | ## Exercise 4: Capture the bug 64 | 65 | > [!IMPORTANT] 66 | > This exercise is experimental. You may run into OS-compatibility issues. 67 | 68 | Welcome to the last exercise! This is a capture-the-flag style mini-game which will require you to hunt for hidden symbols. 69 | 70 | You are given a black-box-esque ELF binary named `vault`. Embedded within the executable and linkable regions is a secret message. 71 | 72 | You must extract this secret message and decode it using `gdb`, `nm`, and `objdump`. You are only allowed to use those 3. You will use all 3 binary analysis tools. 73 | 74 | Because this was assembled and compiled for x86, you do not need a board for this. 75 | 76 | If you are on an ARM based computer (e.g. Macbook), please contact me. 77 | 78 | When you find the flag, make a text file in the `exercise4` directory and paste the flag token there. Then, in that same text file, paste all the commands you ran and explain what each one does. 79 | 80 | You are now finished with section 2. 81 | 82 | > [!IMPORTANT] 83 | > Hints below, attempt at least twice before opening them. 84 | 85 |
86 | Hint 1 87 | 88 | Some keywords to look for: 89 | `win`, `flag`, `vault`, `printf` 90 | 91 |
92 | 93 |
94 | Hint 2 95 | 96 | Use pipes and regex checkers to narrow down what you are looking for. These were covered in section 00. Use that in conjunction with `nm` and `objdump`. 97 | 98 | From the `grep` manual page: 99 | 100 | > Context Line Control : 101 | 102 | `-A NUM, --after-context=NUM` : 103 | Print NUM lines of trailing context after matching lines. 104 | Places a line containing a group separator (--) between 105 | contiguous groups of matches. With the -o or 106 | --only-matching option, this has no effect and a warning is 107 | given. 108 | 109 |
110 | 111 |
112 | Hint 3 113 | 114 | You should use `nm` to first list all of your symbols. There are red herrings designed to distract you. The flag message (the one you are looking for) is denoted by `flag{MESSAGE_TO_LOOK_FOR}`. 115 | 116 | Then you should use `gdb` to read the disassembly. 117 | 118 |
119 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # About 2 | 3 | A collection of tutorials to help with the onboarding process for the embedded systems teams. The tutorials serve to familiarize new members to the tools and skills the embedded teams use on a daily basis. All of the concepts in here are something a member should be able to understand to be a successful member on the team. 4 | 5 | These were created due to the need for an industry-ready embedded systems tutorial that succinctly provides the necessary context and lays the foundation for systems programming in a sequential and structured manner. They follow a learning progression inspired by Bloom’s Taxonomy, moving from conceptually remembering to understanding to applying, and then, finally, to creating. 6 | 7 | #### _Consider giving this repository a ☆ if you found it helpful!_ 8 | 9 | ## Disclosure 10 | 11 | 1\. This onboarding is designed to guide you and not spoonfeed you. You are encouraged to actively engage with the presented material, look up unfamiliar terms and consult external resources like Google, datasheets, technical manuals, and vendor websites. 12 | 13 | 2\. Feel free to use ChatGPT or other generative AI assistants WITH DISCRETION. You are only cheating yourself by blindly copy-pasting, and AI is not an acceptable substitute for understanding. 14 | 15 | 3\. You will not be assigned a project upon completion of this tutorial if 16 | 17 | a) your work is not genuinely yours, or 18 | 19 | b) you do not pass a knowledge check at the end, or 20 | 21 | c) you demonstrate that you should not be allowed to operate independently in this team. 22 | 23 | > [!IMPORTANT] 24 | > Make sure you read this: 25 | 26 | This tutorial set assumes a \*NIX environment (operating system). This includes: 27 | 28 | - macOS (this tutorial was developed on macOS) 29 | - all Linux distributions which includes but is not limited to 30 | 31 | - Arch 32 | - Ubuntu 33 | - Debian 34 | 35 | - freeBSD and openBSD 36 | 37 | All further instructions are written under the assumption that your environment is [POSIX compliant](https://stackoverflow.com/questions/1780599/what-is-the-meaning-of-posix). 38 | 39 | If you're using Windows, you'll need a compatible environment to follow along effectively. I recommend one of the following: 40 | 41 | 1. Using MSYS2's MINGW64 environment: This provides a Unix-like shell for Windows. 42 | 43 | 2. **Windows Subsystem for Linux (WSL): Provides a native Linux environment on Windows. Suitable for most development workflows. (Recommended) ** 44 | 45 | 3. Dual Boot Setup: Install Linux alongside Windows and choose your operating system at startup. 46 | > Note: If you are setting up a dual boot alongside Windows, make sure you have access to your Microsoft account because you will need to your Bitlocker decryption key otherwise you will lose all your data. 47 | 48 | You can read more [here](https://github.com/DallasFormulaRacing/embedded-onboarding/wiki/DEnvironment). 49 | 50 | You can also see the Windows setup [guide](SETUP.md) I wrote when we migrated from CubeIDE to VSCode. 51 | 52 | ## Table of Contents 53 | 54 | | Section | Title | Difficulty | Learning Outcomes | 55 | | ------- | ------------------------------ | ---------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | 56 | | 00 | Introduction & Version Control | - | Basic grasp of embedded programming and an full understanding of git. | 57 | | 01 | The C Language | + | Fundamental C programming concepts: control structures, pointers, structs, memory, basic data structures, volatile and weak. | 58 | | 02 | Computer Architecture | +++ | Understanding of registers, compiler process, linking, RAM, stack and heap memory, working knowledge of ARMv8 assembly. | 59 | | 03 | Peripherals and Protocols | ++ | Interfacing with external modules. Know and understand CAN, I2C, SPI, GPIO. Know how to utilize DMA. Using the STM32 HAL to interface with peripherals. | 60 | | 04 | Operating Systems | +++ | Understanding of inner workings of operating systems, RTOS. Know how and what a scheduler does and works. Know how processes and threads work with each other. Understand parallelism and concurrency. Understand interrupts. | 61 | | 05 | Hardware and Signal Processing | ++++ | Analog and digital signals and converting between the two. Basics of EMI mitigation. Signal processing and filtering basics. Introduction to filtering. CMSIS libraries. Debugging with JTAG and OpenOCD. Creating the IOC and pinout. | 62 | | 06 | Final Project | +++ | Create a rudimentary data acquisition system; no hardware design required. Send information with print over UART. | 63 | 64 | 65 | 66 | ## References 67 | 68 | \*not in any particular order 69 | 70 | [OpenSTM32](https://www.openstm32.org/HomePage) 71 | [CMake]() 72 | [Makefile]() 73 | []() 74 | []() 75 | []() 76 | []() 77 | 78 | ## Acknowledgements 79 | -------------------------------------------------------------------------------- /section-01/blinky/Makefile: -------------------------------------------------------------------------------- 1 | ########################################################################################################################## 2 | # File automatically-generated by tool: [projectgenerator] version: [4.5.0-RC5] date: [Thu Jul 17 15:19:51 CDT 2025] 3 | ########################################################################################################################## 4 | 5 | # ------------------------------------------------ 6 | # Generic Makefile (based on gcc) 7 | # 8 | # ChangeLog : 9 | # 2017-02-10 - Several enhancements + project update mode 10 | # 2015-07-22 - first version 11 | # ------------------------------------------------ 12 | 13 | ###################################### 14 | # target 15 | ###################################### 16 | TARGET = blinky 17 | 18 | 19 | ###################################### 20 | # building variables 21 | ###################################### 22 | # debug build? 23 | DEBUG = 1 24 | # optimization 25 | OPT = -Og 26 | 27 | 28 | ####################################### 29 | # paths 30 | ####################################### 31 | # Build path 32 | BUILD_DIR = build 33 | 34 | ###################################### 35 | # source 36 | ###################################### 37 | # C sources 38 | C_SOURCES = \ 39 | Core/Src/main.c \ 40 | Core/Src/stm32f0xx_it.c \ 41 | Core/Src/stm32f0xx_hal_msp.c \ 42 | Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_uart.c \ 43 | Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_uart_ex.c \ 44 | Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.c \ 45 | Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.c \ 46 | Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.c \ 47 | Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.c \ 48 | Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.c \ 49 | Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.c \ 50 | Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.c \ 51 | Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.c \ 52 | Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.c \ 53 | Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.c \ 54 | Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.c \ 55 | Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.c \ 56 | Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.c \ 57 | Core/Src/system_stm32f0xx.c \ 58 | Core/Src/sysmem.c \ 59 | Core/Src/syscalls.c 60 | 61 | # ASM sources 62 | ASM_SOURCES = \ 63 | startup_stm32f030x8.s 64 | 65 | # ASM sources 66 | ASMM_SOURCES = 67 | 68 | 69 | ####################################### 70 | # binaries 71 | ####################################### 72 | PREFIX = arm-none-eabi- 73 | # The gcc compiler bin path can be either defined in make command via GCC_PATH variable (> make GCC_PATH=xxx) 74 | # either it can be added to the PATH environment variable. 75 | ifdef GCC_PATH 76 | CC = $(GCC_PATH)/$(PREFIX)gcc 77 | AS = $(GCC_PATH)/$(PREFIX)gcc -x assembler-with-cpp 78 | CP = $(GCC_PATH)/$(PREFIX)objcopy 79 | SZ = $(GCC_PATH)/$(PREFIX)size 80 | else 81 | CC = $(PREFIX)gcc 82 | AS = $(PREFIX)gcc -x assembler-with-cpp 83 | CP = $(PREFIX)objcopy 84 | SZ = $(PREFIX)size 85 | endif 86 | HEX = $(CP) -O ihex 87 | BIN = $(CP) -O binary -S 88 | 89 | ####################################### 90 | # CFLAGS 91 | ####################################### 92 | # cpu 93 | CPU = -mcpu=cortex-m0 94 | 95 | # fpu 96 | # NONE for Cortex-M0/M0+/M3 97 | 98 | # float-abi 99 | 100 | 101 | # mcu 102 | MCU = $(CPU) -mthumb $(FPU) $(FLOAT-ABI) 103 | 104 | # macros for gcc 105 | # AS defines 106 | AS_DEFS = 107 | 108 | # C defines 109 | C_DEFS = \ 110 | -DUSE_HAL_DRIVER \ 111 | -DSTM32F030x8 112 | 113 | 114 | # AS includes 115 | AS_INCLUDES = 116 | 117 | # C includes 118 | C_INCLUDES = \ 119 | -ICore/Inc \ 120 | -IDrivers/STM32F0xx_HAL_Driver/Inc \ 121 | -IDrivers/STM32F0xx_HAL_Driver/Inc/Legacy \ 122 | -IDrivers/CMSIS/Device/ST/STM32F0xx/Include \ 123 | -IDrivers/CMSIS/Include 124 | 125 | 126 | # compile gcc flags 127 | ASFLAGS = $(MCU) $(AS_DEFS) $(AS_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sections 128 | 129 | CFLAGS += $(MCU) $(C_DEFS) $(C_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sections 130 | 131 | ifeq ($(DEBUG), 1) 132 | CFLAGS += -g -gdwarf-2 133 | endif 134 | 135 | 136 | # Generate dependency information 137 | CFLAGS += -MMD -MP -MF"$(@:%.o=%.d)" 138 | 139 | 140 | ####################################### 141 | # LDFLAGS 142 | ####################################### 143 | # link script 144 | LDSCRIPT = stm32f030r8tx_flash.ld 145 | 146 | # libraries 147 | LIBS = -lc -lm -lnosys 148 | LIBDIR = 149 | LDFLAGS = $(MCU) -specs=nano.specs -T$(LDSCRIPT) $(LIBDIR) $(LIBS) -Wl,-Map=$(BUILD_DIR)/$(TARGET).map,--cref -Wl,--gc-sections 150 | 151 | # default action: build all 152 | all: $(BUILD_DIR)/$(TARGET).elf $(BUILD_DIR)/$(TARGET).hex $(BUILD_DIR)/$(TARGET).bin 153 | 154 | 155 | ####################################### 156 | # build the application 157 | ####################################### 158 | # list of objects 159 | OBJECTS = $(addprefix $(BUILD_DIR)/,$(notdir $(C_SOURCES:.c=.o))) 160 | vpath %.c $(sort $(dir $(C_SOURCES))) 161 | # list of ASM program objects 162 | OBJECTS += $(addprefix $(BUILD_DIR)/,$(notdir $(ASM_SOURCES:.s=.o))) 163 | vpath %.s $(sort $(dir $(ASM_SOURCES))) 164 | OBJECTS += $(addprefix $(BUILD_DIR)/,$(notdir $(ASMM_SOURCES:.S=.o))) 165 | vpath %.S $(sort $(dir $(ASMM_SOURCES))) 166 | 167 | $(BUILD_DIR)/%.o: %.c Makefile | $(BUILD_DIR) 168 | $(CC) -c $(CFLAGS) -Wa,-a,-ad,-alms=$(BUILD_DIR)/$(notdir $(<:.c=.lst)) $< -o $@ 169 | 170 | $(BUILD_DIR)/%.o: %.s Makefile | $(BUILD_DIR) 171 | $(AS) -c $(CFLAGS) $< -o $@ 172 | $(BUILD_DIR)/%.o: %.S Makefile | $(BUILD_DIR) 173 | $(AS) -c $(CFLAGS) $< -o $@ 174 | 175 | $(BUILD_DIR)/$(TARGET).elf: $(OBJECTS) Makefile 176 | $(CC) $(OBJECTS) $(LDFLAGS) -o $@ 177 | $(SZ) $@ 178 | 179 | $(BUILD_DIR)/%.hex: $(BUILD_DIR)/%.elf | $(BUILD_DIR) 180 | $(HEX) $< $@ 181 | 182 | $(BUILD_DIR)/%.bin: $(BUILD_DIR)/%.elf | $(BUILD_DIR) 183 | $(BIN) $< $@ 184 | 185 | $(BUILD_DIR): 186 | mkdir $@ 187 | 188 | ####################################### 189 | # clean up 190 | ####################################### 191 | clean: 192 | -rm -fR $(BUILD_DIR) 193 | 194 | ####################################### 195 | # dependencies 196 | ####################################### 197 | -include $(wildcard $(BUILD_DIR)/*.d) 198 | 199 | # *** EOF *** -------------------------------------------------------------------------------- /section-01/blinky/stm32f030r8tx_flash.ld: -------------------------------------------------------------------------------- 1 | /* 2 | ****************************************************************************** 3 | ** 4 | 5 | ** File : LinkerScript.ld 6 | ** 7 | ** Author : STM32CubeMX 8 | ** 9 | ** Abstract : Linker script for STM32F030R8Tx series 10 | ** 64Kbytes FLASH and 8Kbytes RAM 11 | ** 12 | ** Set heap size, stack size and stack location according 13 | ** to application requirements. 14 | ** 15 | ** Set memory bank area and size if external memory is used. 16 | ** 17 | ** Target : STMicroelectronics STM32 18 | ** 19 | ** Distribution: The file is distributed “as is,” without any warranty 20 | ** of any kind. 21 | ** 22 | ***************************************************************************** 23 | ** @attention 24 | ** 25 | **

© COPYRIGHT(c) 2019 STMicroelectronics

26 | ** 27 | ** Redistribution and use in source and binary forms, with or without modification, 28 | ** are permitted provided that the following conditions are met: 29 | ** 1. Redistributions of source code must retain the above copyright notice, 30 | ** this list of conditions and the following disclaimer. 31 | ** 2. Redistributions in binary form must reproduce the above copyright notice, 32 | ** this list of conditions and the following disclaimer in the documentation 33 | ** and/or other materials provided with the distribution. 34 | ** 3. Neither the name of STMicroelectronics nor the names of its contributors 35 | ** may be used to endorse or promote products derived from this software 36 | ** without specific prior written permission. 37 | ** 38 | ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 39 | ** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 40 | ** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 41 | ** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 42 | ** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 43 | ** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 44 | ** SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 45 | ** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 46 | ** OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 47 | ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 48 | ** 49 | ***************************************************************************** 50 | */ 51 | 52 | /* Entry Point */ 53 | ENTRY(Reset_Handler) 54 | 55 | /* Highest address of the user mode stack */ 56 | _estack = ORIGIN(RAM) + LENGTH(RAM); /* end of RAM */ 57 | /* Generate a link error if heap and stack don't fit into RAM */ 58 | _Min_Heap_Size = 0x200; /* required amount of heap */ 59 | _Min_Stack_Size = 0x400; /* required amount of stack */ 60 | 61 | /* Specify the memory areas */ 62 | MEMORY 63 | { 64 | RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 8K 65 | FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 64K 66 | } 67 | 68 | /* Define output sections */ 69 | SECTIONS 70 | { 71 | /* The startup code goes first into FLASH */ 72 | .isr_vector : 73 | { 74 | . = ALIGN(4); 75 | KEEP(*(.isr_vector)) /* Startup code */ 76 | . = ALIGN(4); 77 | } >FLASH 78 | 79 | /* The program code and other data goes into FLASH */ 80 | .text : 81 | { 82 | . = ALIGN(4); 83 | *(.text) /* .text sections (code) */ 84 | *(.text*) /* .text* sections (code) */ 85 | *(.glue_7) /* glue arm to thumb code */ 86 | *(.glue_7t) /* glue thumb to arm code */ 87 | *(.eh_frame) 88 | 89 | KEEP (*(.init)) 90 | KEEP (*(.fini)) 91 | 92 | . = ALIGN(4); 93 | _etext = .; /* define a global symbols at end of code */ 94 | } >FLASH 95 | 96 | /* Constant data goes into FLASH */ 97 | .rodata : 98 | { 99 | . = ALIGN(4); 100 | *(.rodata) /* .rodata sections (constants, strings, etc.) */ 101 | *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ 102 | . = ALIGN(4); 103 | } >FLASH 104 | 105 | .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH 106 | .ARM : { 107 | __exidx_start = .; 108 | *(.ARM.exidx*) 109 | __exidx_end = .; 110 | } >FLASH 111 | 112 | .preinit_array : 113 | { 114 | PROVIDE_HIDDEN (__preinit_array_start = .); 115 | KEEP (*(.preinit_array*)) 116 | PROVIDE_HIDDEN (__preinit_array_end = .); 117 | } >FLASH 118 | .init_array : 119 | { 120 | PROVIDE_HIDDEN (__init_array_start = .); 121 | KEEP (*(SORT(.init_array.*))) 122 | KEEP (*(.init_array*)) 123 | PROVIDE_HIDDEN (__init_array_end = .); 124 | } >FLASH 125 | .fini_array : 126 | { 127 | PROVIDE_HIDDEN (__fini_array_start = .); 128 | KEEP (*(SORT(.fini_array.*))) 129 | KEEP (*(.fini_array*)) 130 | PROVIDE_HIDDEN (__fini_array_end = .); 131 | } >FLASH 132 | 133 | /* used by the startup to initialize data */ 134 | _sidata = LOADADDR(.data); 135 | 136 | /* Initialized data sections goes into RAM, load LMA copy after code */ 137 | .data : 138 | { 139 | . = ALIGN(4); 140 | _sdata = .; /* create a global symbol at data start */ 141 | *(.data) /* .data sections */ 142 | *(.data*) /* .data* sections */ 143 | 144 | . = ALIGN(4); 145 | _edata = .; /* define a global symbol at data end */ 146 | } >RAM AT> FLASH 147 | 148 | 149 | /* Uninitialized data section */ 150 | . = ALIGN(4); 151 | .bss : 152 | { 153 | /* This is used by the startup in order to initialize the .bss secion */ 154 | _sbss = .; /* define a global symbol at bss start */ 155 | __bss_start__ = _sbss; 156 | *(.bss) 157 | *(.bss*) 158 | *(COMMON) 159 | 160 | . = ALIGN(4); 161 | _ebss = .; /* define a global symbol at bss end */ 162 | __bss_end__ = _ebss; 163 | } >RAM 164 | 165 | /* User_heap_stack section, used to check that there is enough RAM left */ 166 | ._user_heap_stack : 167 | { 168 | . = ALIGN(8); 169 | PROVIDE ( end = . ); 170 | PROVIDE ( _end = . ); 171 | . = . + _Min_Heap_Size; 172 | . = . + _Min_Stack_Size; 173 | . = ALIGN(8); 174 | } >RAM 175 | 176 | 177 | 178 | /* Remove information from the standard libraries */ 179 | /DISCARD/ : 180 | { 181 | libc.a ( * ) 182 | libm.a ( * ) 183 | libgcc.a ( * ) 184 | } 185 | 186 | } 187 | 188 | 189 | -------------------------------------------------------------------------------- /section-01/blinky/Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file stm32f0xx_hal_pwr.h 4 | * @author MCD Application Team 5 | * @brief Header file of PWR HAL module. 6 | ****************************************************************************** 7 | * @attention 8 | * 9 | * Copyright (c) 2016 STMicroelectronics. 10 | * All rights reserved. 11 | * 12 | * This software is licensed under terms that can be found in the LICENSE file 13 | * in the root directory of this software component. 14 | * If no LICENSE file comes with this software, it is provided AS-IS. 15 | * 16 | ****************************************************************************** 17 | */ 18 | 19 | /* Define to prevent recursive inclusion -------------------------------------*/ 20 | #ifndef __STM32F0xx_HAL_PWR_H 21 | #define __STM32F0xx_HAL_PWR_H 22 | 23 | #ifdef __cplusplus 24 | extern "C" { 25 | #endif 26 | 27 | /* Includes ------------------------------------------------------------------*/ 28 | #include "stm32f0xx_hal_def.h" 29 | 30 | /** @addtogroup STM32F0xx_HAL_Driver 31 | * @{ 32 | */ 33 | 34 | /** @addtogroup PWR PWR 35 | * @{ 36 | */ 37 | 38 | /* Exported types ------------------------------------------------------------*/ 39 | /* Exported constants --------------------------------------------------------*/ 40 | 41 | /** @defgroup PWR_Exported_Constants PWR Exported Constants 42 | * @{ 43 | */ 44 | 45 | /** @defgroup PWR_Regulator_state_in_STOP_mode PWR Regulator state in STOP mode 46 | * @{ 47 | */ 48 | #define PWR_MAINREGULATOR_ON (0x00000000U) 49 | #define PWR_LOWPOWERREGULATOR_ON PWR_CR_LPDS 50 | 51 | #define IS_PWR_REGULATOR(REGULATOR) (((REGULATOR) == PWR_MAINREGULATOR_ON) || \ 52 | ((REGULATOR) == PWR_LOWPOWERREGULATOR_ON)) 53 | /** 54 | * @} 55 | */ 56 | 57 | /** @defgroup PWR_SLEEP_mode_entry PWR SLEEP mode entry 58 | * @{ 59 | */ 60 | #define PWR_SLEEPENTRY_WFI ((uint8_t)0x01U) 61 | #define PWR_SLEEPENTRY_WFE ((uint8_t)0x02U) 62 | #define IS_PWR_SLEEP_ENTRY(ENTRY) (((ENTRY) == PWR_SLEEPENTRY_WFI) || ((ENTRY) == PWR_SLEEPENTRY_WFE)) 63 | /** 64 | * @} 65 | */ 66 | 67 | /** @defgroup PWR_STOP_mode_entry PWR STOP mode entry 68 | * @{ 69 | */ 70 | #define PWR_STOPENTRY_WFI ((uint8_t)0x01U) 71 | #define PWR_STOPENTRY_WFE ((uint8_t)0x02U) 72 | #define IS_PWR_STOP_ENTRY(ENTRY) (((ENTRY) == PWR_STOPENTRY_WFI) || ((ENTRY) == PWR_STOPENTRY_WFE)) 73 | /** 74 | * @} 75 | */ 76 | 77 | 78 | /** 79 | * @} 80 | */ 81 | 82 | /* Exported macro ------------------------------------------------------------*/ 83 | /** @defgroup PWR_Exported_Macro PWR Exported Macro 84 | * @{ 85 | */ 86 | 87 | /** @brief Check PWR flag is set or not. 88 | * @param __FLAG__ specifies the flag to check. 89 | * This parameter can be one of the following values: 90 | * @arg PWR_FLAG_WU: Wake Up flag. This flag indicates that a wakeup event 91 | * was received from the WKUP pin or from the RTC alarm (Alarm A), 92 | * RTC Tamper event, RTC TimeStamp event or RTC Wakeup. 93 | * An additional wakeup event is detected if the WKUP pin is enabled 94 | * (by setting the EWUP bit) when the WKUP pin level is already high. 95 | * @arg PWR_FLAG_SB: StandBy flag. This flag indicates that the system was 96 | * resumed from StandBy mode. 97 | * @arg PWR_FLAG_PVDO: PVD Output. This flag is valid only if PVD is enabled 98 | * by the HAL_PWR_EnablePVD() function. The PVD is stopped by Standby mode 99 | * For this reason, this bit is equal to 0 after Standby or reset 100 | * until the PVDE bit is set. 101 | * Warning: this Flag is not available on STM32F030x8 products 102 | * @arg PWR_FLAG_VREFINTRDY: This flag indicates that the internal reference 103 | * voltage VREFINT is ready. 104 | * Warning: this Flag is not available on STM32F030x8 products 105 | * @retval The new state of __FLAG__ (TRUE or FALSE). 106 | */ 107 | #define __HAL_PWR_GET_FLAG(__FLAG__) ((PWR->CSR & (__FLAG__)) == (__FLAG__)) 108 | 109 | /** @brief Clear the PWR's pending flags. 110 | * @param __FLAG__ specifies the flag to clear. 111 | * This parameter can be one of the following values: 112 | * @arg PWR_FLAG_WU: Wake Up flag 113 | * @arg PWR_FLAG_SB: StandBy flag 114 | */ 115 | #define __HAL_PWR_CLEAR_FLAG(__FLAG__) (PWR->CR |= (__FLAG__) << 2U) 116 | 117 | 118 | /** 119 | * @} 120 | */ 121 | 122 | /* Include PWR HAL Extension module */ 123 | #include "stm32f0xx_hal_pwr_ex.h" 124 | 125 | /* Exported functions --------------------------------------------------------*/ 126 | 127 | /** @addtogroup PWR_Exported_Functions PWR Exported Functions 128 | * @{ 129 | */ 130 | 131 | /** @addtogroup PWR_Exported_Functions_Group1 Initialization and de-initialization functions 132 | * @{ 133 | */ 134 | 135 | /* Initialization and de-initialization functions *****************************/ 136 | void HAL_PWR_DeInit(void); 137 | 138 | /** 139 | * @} 140 | */ 141 | 142 | /** @addtogroup PWR_Exported_Functions_Group2 Peripheral Control functions 143 | * @{ 144 | */ 145 | 146 | /* Peripheral Control functions **********************************************/ 147 | void HAL_PWR_EnableBkUpAccess(void); 148 | void HAL_PWR_DisableBkUpAccess(void); 149 | 150 | /* WakeUp pins configuration functions ****************************************/ 151 | void HAL_PWR_EnableWakeUpPin(uint32_t WakeUpPinx); 152 | void HAL_PWR_DisableWakeUpPin(uint32_t WakeUpPinx); 153 | 154 | /* Low Power modes configuration functions ************************************/ 155 | void HAL_PWR_EnterSTOPMode(uint32_t Regulator, uint8_t STOPEntry); 156 | void HAL_PWR_EnterSLEEPMode(uint32_t Regulator, uint8_t SLEEPEntry); 157 | void HAL_PWR_EnterSTANDBYMode(void); 158 | 159 | void HAL_PWR_EnableSleepOnExit(void); 160 | void HAL_PWR_DisableSleepOnExit(void); 161 | void HAL_PWR_EnableSEVOnPend(void); 162 | void HAL_PWR_DisableSEVOnPend(void); 163 | 164 | /** 165 | * @} 166 | */ 167 | 168 | /** 169 | * @} 170 | */ 171 | 172 | /** 173 | * @} 174 | */ 175 | 176 | /** 177 | * @} 178 | */ 179 | 180 | #ifdef __cplusplus 181 | } 182 | #endif 183 | 184 | 185 | #endif /* __STM32F0xx_HAL_PWR_H */ 186 | -------------------------------------------------------------------------------- /section-04/README.md: -------------------------------------------------------------------------------- 1 | > Tags: Operating Systems, RTOS, Embedded, Scheduling, Mutex, Semaphore 2 | 3 | # Operating Systems 4 | 5 | This section introduces the fundamentals of operating systems, with a focus on embedded and real-time systems. You will learn about system calls, the kernel, scheduling, concurrency, and synchronization mechanisms such as mutexes and semaphores. 6 | 7 | ## 0. What is an Operating System? 8 | 9 | An Operating System (OS) is a collection of software services that bridge the gap between hardware and software. For example, when a high-level program prompts the user for input or displays graphics, it relies on OS routines to handle these operations. 10 | 11 | ## 0.1 System Calls (Syscalls) 12 | 13 | System calls are the interface between user programs and the OS. They allow user-space programs to request services from the OS, such as input/output, file access, or network communication. For example, when your program displays data on the screen, the code generated by the compiler will include (among other things) system calls to the OS to handle this output. 14 | 15 | **In summary:** 16 | 17 | - User programs run in a sandbox and can only access their own memory and functions. 18 | - To interact with the outside world (screen, files, sound, network), a program must use system calls. 19 | 20 | ## 0.2 The Kernel 21 | 22 | The kernel is the core of the operating system. It has complete control over the system and manages hardware resources. The kernel is typically loaded after the bootloader during system startup. 23 | 24 | > [!NOTE] 25 | > For more on kernel-level security, see [kernel-level anticheats](https://gist.github.com/stdNullPtr/2998eacb71ae925515360410af6f0a32). 26 | 27 | Further reading: https://cpu.land/ 28 | 29 | ## 1. Types of Operating Systems 30 | 31 | ### 1.1 General Purpose Operating Systems 32 | 33 | General purpose operating systems are designed for desktops, laptops, and servers. Their main goal is to prioritize fairness, making sure that all applications eventually get access to system resources. Some common examples of general purpose operating systems are Windows, Linux, and macOS. 34 | 35 | ### 1.2 Real-Time Operating Systems (RTOS) 36 | 37 | Real-time operating systems are designed for embedded systems and devices that have strict timing deadlines. These systems prioritize determinism, which means that tasks must run within specific timing guarantees. Real-time operating systems are commonly used in automotive electronics, robotics, aerospace, and Internet of Things (IoT) devices. 38 | 39 | So at this point, you may be asking yourself the million dollar question: 40 | 41 | # Why Use an RTOS Instead of Just a While Loop? 42 | 43 | A simple infinite `while` loop works for basic embedded projects with few tasks and loose timing. However, as complexity grows, this approach quickly becomes unmanageable. An RTOS solves these issues by providing: 44 | 45 | - **Task Scheduling:** Built-in real-time scheduler manages timing and task priorities, making code more predictable and maintainable. 46 | - **Modularity:** Code is organized into independent tasks, reducing interdependencies and simplifying testing, collaboration, and code reuse. 47 | - **Efficiency:** Tasks can block on events, eliminating wasteful polling and enabling low-power operation when idle. 48 | - **Flexible Interrupt Handling:** Processing can be deferred to tasks, keeping interrupt handlers short and system responsive. 49 | - **Mixed Workloads:** Supports periodic, event-driven, and continuous tasks, meeting both hard and soft real-time requirements. 50 | 51 | ## 2. Key Features of an RTOS 52 | 53 | The scheduler is a key feature of any operating system. It divides CPU time into slices and determines which task should run at any given moment. Most operating systems use priority-based execution, where the highest-priority task runs first at each tick of the system timer. Even on a single-core CPU, the operating system rapidly switches between tasks, creating the illusion that multiple tasks are running at the same time. This is known as the concurrency illusion. 54 | 55 | ## 3. Tasks, Threads, and Processes 56 | 57 | These three concepts are fundamental to understanding how operating systems manage work: 58 | 59 | - **Task:** In embedded and RTOS contexts, a "task" is a unit of work scheduled by the OS, similar to a lightweight thread. For example, reading sensor data or handling communication can each be a separate task. 60 | 61 | - **Thread:** A thread is the smallest sequence of programmed instructions that can be managed independently by the scheduler. Threads within the same process share memory and resources but have their own program counter and stack. 62 | 63 | - **Process:** A process is an independent program in execution, with its own memory space and resources. A process can contain multiple threads that work together to perform tasks. 64 | 65 | ## 4. Tick Timer and Context Switching 66 | 67 | The tick timer is a hardware timer that interrupts the CPU at fixed intervals, much like a metronome keeps time in music. At each tick, the scheduler evaluates the priorities of all tasks and decides which one should run next. When the operating system switches from one task to another, it performs a context switch. This means the system saves the current task's CPU registers, program counter, and local variables, and then restores these values for the next task to run. 68 | 69 | ## 5. Synchronization: Mutexes and Semaphores 70 | 71 | ### 5.1 Mutex 72 | 73 | A mutex is a synchronization tool that ensures only one thread can enter a protected section of code at a time. It uses atomic instructions, which means the operation cannot be split up or interrupted. This is important for protecting critical sections: parts of the code that must run from start to finish without interruption. If multiple threads try to access a critical section at the same time, they can corrupt shared variables. Mutexes prevent this from happening. 74 | 75 | ### 5.2 Semaphore 76 | 77 | A semaphore is a counter that controls access for multiple threads. For example, imagine a room (the critical section) that allows up to three people (threads) inside at once. There are three keys (the semaphore count), and each person must take a key to enter. If all the keys are taken, anyone else who wants to enter must wait until a key is returned. This is how semaphores help manage access to shared resources. 78 | 79 | ## 6. Scheduling Issues 80 | 81 | Priority inversion happens when a low-priority task holds a mutex, and a high-priority task has to wait for it. This problem can be solved with a technique called priority inheritance, where the low-priority task temporarily inherits the higher priority. Starvation occurs when some tasks never get CPU time because higher-priority tasks are always running. This can be fixed by "aging," which means gradually raising the priority of tasks that have been waiting a long time. Deadlock is a situation where tasks are stuck waiting on each other, so nothing can proceed. One way to break a deadlock is to use timeouts, which halt all the tasks and try again later. 82 | 83 | ## 7. FreeRTOS 84 | 85 | ## 8. Further Reading 86 | 87 | - [RTOS Fundamentals](https://freertos.org/Documentation/01-FreeRTOS-quick-start/01-Beginners-guide/01-RTOS-fundamentals) 88 | -------------------------------------------------------------------------------- /section-01/blinky/Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_def.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file stm32f0xx_hal_def.h 4 | * @author MCD Application Team 5 | * @brief This file contains HAL common defines, enumeration, macros and 6 | * structures definitions. 7 | ****************************************************************************** 8 | * @attention 9 | * 10 | * Copyright (c) 2016 STMicroelectronics. 11 | * All rights reserved. 12 | * 13 | * This software is licensed under terms that can be found in the LICENSE file 14 | * in the root directory of this software component. 15 | * If no LICENSE file comes with this software, it is provided AS-IS. 16 | * 17 | ****************************************************************************** 18 | */ 19 | 20 | /* Define to prevent recursive inclusion -------------------------------------*/ 21 | #ifndef __STM32F0xx_HAL_DEF 22 | #define __STM32F0xx_HAL_DEF 23 | 24 | #ifdef __cplusplus 25 | extern "C" { 26 | #endif 27 | 28 | /* Includes ------------------------------------------------------------------*/ 29 | #include "stm32f0xx.h" 30 | #include "Legacy/stm32_hal_legacy.h" 31 | #include 32 | 33 | /* Exported types ------------------------------------------------------------*/ 34 | 35 | /** 36 | * @brief HAL Status structures definition 37 | */ 38 | typedef enum 39 | { 40 | HAL_OK = 0x00U, 41 | HAL_ERROR = 0x01U, 42 | HAL_BUSY = 0x02U, 43 | HAL_TIMEOUT = 0x03U 44 | } HAL_StatusTypeDef; 45 | 46 | /** 47 | * @brief HAL Lock structures definition 48 | */ 49 | typedef enum 50 | { 51 | HAL_UNLOCKED = 0x00U, 52 | HAL_LOCKED = 0x01U 53 | } HAL_LockTypeDef; 54 | 55 | /* Exported macro ------------------------------------------------------------*/ 56 | 57 | #if !defined(UNUSED) 58 | #define UNUSED(X) (void)X /* To avoid gcc/g++ warnings */ 59 | #endif /* UNUSED */ 60 | 61 | #define HAL_MAX_DELAY 0xFFFFFFFFU 62 | 63 | #define HAL_IS_BIT_SET(REG, BIT) (((REG) & (BIT)) == (BIT)) 64 | #define HAL_IS_BIT_CLR(REG, BIT) (((REG) & (BIT)) == 0U) 65 | 66 | #define __HAL_LINKDMA(__HANDLE__, __PPP_DMA_FIELD__, __DMA_HANDLE__) \ 67 | do{ \ 68 | (__HANDLE__)->__PPP_DMA_FIELD__ = &(__DMA_HANDLE__); \ 69 | (__DMA_HANDLE__).Parent = (__HANDLE__); \ 70 | } while(0U) 71 | 72 | /** @brief Reset the Handle's State field. 73 | * @param __HANDLE__ specifies the Peripheral Handle. 74 | * @note This macro can be used for the following purpose: 75 | * - When the Handle is declared as local variable; before passing it as parameter 76 | * to HAL_PPP_Init() for the first time, it is mandatory to use this macro 77 | * to set to 0 the Handle's "State" field. 78 | * Otherwise, "State" field may have any random value and the first time the function 79 | * HAL_PPP_Init() is called, the low level hardware initialization will be missed 80 | * (i.e. HAL_PPP_MspInit() will not be executed). 81 | * - When there is a need to reconfigure the low level hardware: instead of calling 82 | * HAL_PPP_DeInit() then HAL_PPP_Init(), user can make a call to this macro then HAL_PPP_Init(). 83 | * In this later function, when the Handle's "State" field is set to 0, it will execute the function 84 | * HAL_PPP_MspInit() which will reconfigure the low level hardware. 85 | * @retval None 86 | */ 87 | #define __HAL_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = 0U) 88 | 89 | #if (USE_RTOS == 1U) 90 | /* Reserved for future use */ 91 | #error " USE_RTOS should be 0 in the current HAL release " 92 | #else 93 | #define __HAL_LOCK(__HANDLE__) \ 94 | do{ \ 95 | if((__HANDLE__)->Lock == HAL_LOCKED) \ 96 | { \ 97 | return HAL_BUSY; \ 98 | } \ 99 | else \ 100 | { \ 101 | (__HANDLE__)->Lock = HAL_LOCKED; \ 102 | } \ 103 | }while (0U) 104 | 105 | #define __HAL_UNLOCK(__HANDLE__) \ 106 | do{ \ 107 | (__HANDLE__)->Lock = HAL_UNLOCKED; \ 108 | }while (0U) 109 | #endif /* USE_RTOS */ 110 | 111 | #if defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) /* ARM Compiler V6 */ 112 | #ifndef __weak 113 | #define __weak __attribute__((weak)) 114 | #endif 115 | #ifndef __packed 116 | #define __packed __attribute__((packed)) 117 | #endif 118 | #elif defined ( __GNUC__ ) && !defined (__CC_ARM) /* GNU Compiler */ 119 | #ifndef __weak 120 | #define __weak __attribute__((weak)) 121 | #endif /* __weak */ 122 | #ifndef __packed 123 | #define __packed __attribute__((__packed__)) 124 | #endif /* __packed */ 125 | #endif /* __GNUC__ */ 126 | 127 | 128 | /* Macro to get variable aligned on 4-bytes, for __ICCARM__ the directive "#pragma data_alignment=4" must be used instead */ 129 | #if defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) /* ARM Compiler V6 */ 130 | #ifndef __ALIGN_BEGIN 131 | #define __ALIGN_BEGIN 132 | #endif 133 | #ifndef __ALIGN_END 134 | #define __ALIGN_END __attribute__ ((aligned (4))) 135 | #endif 136 | #elif defined ( __GNUC__ ) && !defined (__CC_ARM) /* GNU Compiler */ 137 | #ifndef __ALIGN_END 138 | #define __ALIGN_END __attribute__ ((aligned (4))) 139 | #endif /* __ALIGN_END */ 140 | #ifndef __ALIGN_BEGIN 141 | #define __ALIGN_BEGIN 142 | #endif /* __ALIGN_BEGIN */ 143 | #else 144 | #ifndef __ALIGN_END 145 | #define __ALIGN_END 146 | #endif /* __ALIGN_END */ 147 | #ifndef __ALIGN_BEGIN 148 | #if defined (__CC_ARM) /* ARM Compiler V5*/ 149 | #define __ALIGN_BEGIN __align(4) 150 | #elif defined (__ICCARM__) /* IAR Compiler */ 151 | #define __ALIGN_BEGIN 152 | #endif /* __CC_ARM */ 153 | #endif /* __ALIGN_BEGIN */ 154 | #endif /* __GNUC__ */ 155 | 156 | /** 157 | * @brief __NOINLINE definition 158 | */ 159 | #if defined ( __CC_ARM ) || (defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)) || defined ( __GNUC__ ) 160 | /* ARM V4/V5 and V6 & GNU Compiler 161 | ------------------------------- 162 | */ 163 | #define __NOINLINE __attribute__ ( (noinline) ) 164 | 165 | #elif defined ( __ICCARM__ ) 166 | /* ICCARM Compiler 167 | --------------- 168 | */ 169 | #define __NOINLINE _Pragma("optimize = no_inline") 170 | 171 | #endif 172 | 173 | #ifdef __cplusplus 174 | } 175 | #endif 176 | 177 | #endif /* ___STM32F0xx_HAL_DEF */ 178 | 179 | 180 | -------------------------------------------------------------------------------- /section-01/blinky/.mxproject: -------------------------------------------------------------------------------- 1 | [PreviousGenFiles] 2 | AdvancedFolderStructure=true 3 | HeaderFileListSize=3 4 | HeaderFiles#0=../Core/Inc/stm32f0xx_it.h 5 | HeaderFiles#1=../Core/Inc/stm32f0xx_hal_conf.h 6 | HeaderFiles#2=../Core/Inc/main.h 7 | HeaderFolderListSize=1 8 | HeaderPath#0=../Core/Inc 9 | HeaderFiles=; 10 | SourceFileListSize=3 11 | SourceFiles#0=../Core/Src/stm32f0xx_it.c 12 | SourceFiles#1=../Core/Src/stm32f0xx_hal_msp.c 13 | SourceFiles#2=../Core/Src/main.c 14 | SourceFolderListSize=1 15 | SourcePath#0=../Core/Src 16 | SourceFiles=; 17 | 18 | [PreviousLibFiles] 19 | LibFiles=Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_uart.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_usart.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_uart_ex.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_rcc.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc_ex.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_bus.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_crs.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_system.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_utils.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_def.h;Drivers/STM32F0xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c_ex.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio_ex.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_gpio.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma_ex.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_dma.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_cortex.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_cortex.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr_ex.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_pwr.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash_ex.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_exti.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_exti.h;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_uart.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_uart_ex.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.c;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_uart.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_usart.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_uart_ex.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_rcc.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc_ex.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_bus.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_crs.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_system.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_utils.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_def.h;Drivers/STM32F0xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c_ex.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio_ex.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_gpio.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma_ex.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_dma.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_cortex.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_cortex.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr_ex.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_pwr.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash_ex.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_exti.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_exti.h;Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f030x8.h;Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f0xx.h;Drivers/CMSIS/Device/ST/STM32F0xx/Include/system_stm32f0xx.h;Drivers/CMSIS/Device/ST/STM32F0xx/Include/system_stm32f0xx.h;Drivers/CMSIS/Device/ST/STM32F0xx/Source/Templates/system_stm32f0xx.c;Drivers/CMSIS/Include/core_cm7.h;Drivers/CMSIS/Include/tz_context.h;Drivers/CMSIS/Include/core_cm3.h;Drivers/CMSIS/Include/cmsis_compiler.h;Drivers/CMSIS/Include/cmsis_armclang.h;Drivers/CMSIS/Include/mpu_armv7.h;Drivers/CMSIS/Include/cmsis_armcc.h;Drivers/CMSIS/Include/core_cm4.h;Drivers/CMSIS/Include/core_cm0.h;Drivers/CMSIS/Include/cmsis_iccarm.h;Drivers/CMSIS/Include/core_armv8mml.h;Drivers/CMSIS/Include/core_sc000.h;Drivers/CMSIS/Include/core_cm1.h;Drivers/CMSIS/Include/mpu_armv8.h;Drivers/CMSIS/Include/core_sc300.h;Drivers/CMSIS/Include/cmsis_gcc.h;Drivers/CMSIS/Include/cmsis_version.h;Drivers/CMSIS/Include/core_cm23.h;Drivers/CMSIS/Include/core_cm33.h;Drivers/CMSIS/Include/core_cm0plus.h;Drivers/CMSIS/Include/core_armv8mbl.h; 20 | 21 | [PreviousUsedMakefileFiles] 22 | SourceFiles=Core/Src/main.c;Core/Src/stm32f0xx_it.c;Core/Src/stm32f0xx_hal_msp.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_uart.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_uart_ex.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.c;Drivers/CMSIS/Device/ST/STM32F0xx/Source/Templates/system_stm32f0xx.c;Core/Src/system_stm32f0xx.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_uart.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_uart_ex.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.c;Drivers/CMSIS/Device/ST/STM32F0xx/Source/Templates/system_stm32f0xx.c;Core/Src/system_stm32f0xx.c;;; 23 | HeaderPath=Drivers/STM32F0xx_HAL_Driver/Inc;Drivers/STM32F0xx_HAL_Driver/Inc/Legacy;Drivers/CMSIS/Device/ST/STM32F0xx/Include;Drivers/CMSIS/Include;Core/Inc; 24 | CDefines=USE_HAL_DRIVER;STM32F030x8;USE_HAL_DRIVER;USE_HAL_DRIVER; 25 | 26 | -------------------------------------------------------------------------------- /section-01/blinky/Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c_ex.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file stm32f0xx_hal_i2c_ex.h 4 | * @author MCD Application Team 5 | * @brief Header file of I2C HAL Extended module. 6 | ****************************************************************************** 7 | * @attention 8 | * 9 | * Copyright (c) 2016 STMicroelectronics. 10 | * All rights reserved. 11 | * 12 | * This software is licensed under terms that can be found in the LICENSE file 13 | * in the root directory of this software component. 14 | * If no LICENSE file comes with this software, it is provided AS-IS. 15 | * 16 | ****************************************************************************** 17 | */ 18 | 19 | /* Define to prevent recursive inclusion -------------------------------------*/ 20 | #ifndef STM32F0xx_HAL_I2C_EX_H 21 | #define STM32F0xx_HAL_I2C_EX_H 22 | 23 | #ifdef __cplusplus 24 | extern "C" { 25 | #endif 26 | 27 | /* Includes ------------------------------------------------------------------*/ 28 | #include "stm32f0xx_hal_def.h" 29 | 30 | /** @addtogroup STM32F0xx_HAL_Driver 31 | * @{ 32 | */ 33 | 34 | /** @addtogroup I2CEx 35 | * @{ 36 | */ 37 | 38 | /* Exported types ------------------------------------------------------------*/ 39 | /* Exported constants --------------------------------------------------------*/ 40 | 41 | /** @defgroup I2CEx_Exported_Constants I2C Extended Exported Constants 42 | * @{ 43 | */ 44 | 45 | /** @defgroup I2CEx_Analog_Filter I2C Extended Analog Filter 46 | * @{ 47 | */ 48 | #define I2C_ANALOGFILTER_ENABLE 0x00000000U 49 | #define I2C_ANALOGFILTER_DISABLE I2C_CR1_ANFOFF 50 | /** 51 | * @} 52 | */ 53 | 54 | /** @defgroup I2CEx_FastModePlus I2C Extended Fast Mode Plus 55 | * @{ 56 | */ 57 | #define I2C_FMP_NOT_SUPPORTED 0xAAAA0000U /*!< Fast Mode Plus not supported */ 58 | #if defined(SYSCFG_CFGR1_I2C_FMP_PA9) 59 | #define I2C_FASTMODEPLUS_PA9 SYSCFG_CFGR1_I2C_FMP_PA9 /*!< Enable Fast Mode Plus on PA9 */ 60 | #define I2C_FASTMODEPLUS_PA10 SYSCFG_CFGR1_I2C_FMP_PA10 /*!< Enable Fast Mode Plus on PA10 */ 61 | #else 62 | #define I2C_FASTMODEPLUS_PA9 (uint32_t)(0x00000001U | I2C_FMP_NOT_SUPPORTED) /*!< Fast Mode Plus PA9 not supported */ 63 | #define I2C_FASTMODEPLUS_PA10 (uint32_t)(0x00000002U | I2C_FMP_NOT_SUPPORTED) /*!< Fast Mode Plus PA10 not supported */ 64 | #endif /* SYSCFG_CFGR1_I2C_FMP_PA9 */ 65 | #define I2C_FASTMODEPLUS_PB6 SYSCFG_CFGR1_I2C_FMP_PB6 /*!< Enable Fast Mode Plus on PB6 */ 66 | #define I2C_FASTMODEPLUS_PB7 SYSCFG_CFGR1_I2C_FMP_PB7 /*!< Enable Fast Mode Plus on PB7 */ 67 | #define I2C_FASTMODEPLUS_PB8 SYSCFG_CFGR1_I2C_FMP_PB8 /*!< Enable Fast Mode Plus on PB8 */ 68 | #define I2C_FASTMODEPLUS_PB9 SYSCFG_CFGR1_I2C_FMP_PB9 /*!< Enable Fast Mode Plus on PB9 */ 69 | #if defined(SYSCFG_CFGR1_I2C_FMP_I2C1) 70 | #define I2C_FASTMODEPLUS_I2C1 SYSCFG_CFGR1_I2C_FMP_I2C1 /*!< Enable Fast Mode Plus on I2C1 pins */ 71 | #else 72 | #define I2C_FASTMODEPLUS_I2C1 (uint32_t)(0x00000100U | I2C_FMP_NOT_SUPPORTED) /*!< Fast Mode Plus I2C1 not supported */ 73 | #endif /* SYSCFG_CFGR1_I2C_FMP_I2C1 */ 74 | #if defined(SYSCFG_CFGR1_I2C_FMP_I2C2) 75 | #define I2C_FASTMODEPLUS_I2C2 SYSCFG_CFGR1_I2C_FMP_I2C2 /*!< Enable Fast Mode Plus on I2C2 pins */ 76 | #else 77 | #define I2C_FASTMODEPLUS_I2C2 (uint32_t)(0x00000200U | I2C_FMP_NOT_SUPPORTED) /*!< Fast Mode Plus I2C2 not supported */ 78 | #endif /* SYSCFG_CFGR1_I2C_FMP_I2C2 */ 79 | /** 80 | * @} 81 | */ 82 | 83 | /** 84 | * @} 85 | */ 86 | 87 | /* Exported macro ------------------------------------------------------------*/ 88 | /* Exported functions --------------------------------------------------------*/ 89 | 90 | /** @addtogroup I2CEx_Exported_Functions I2C Extended Exported Functions 91 | * @{ 92 | */ 93 | 94 | /** @addtogroup I2CEx_Exported_Functions_Group1 Extended features functions 95 | * @brief Extended features functions 96 | * @{ 97 | */ 98 | 99 | /** @addtogroup I2CEx_Exported_Functions_Group1 Filter Mode Functions 100 | * @{ 101 | */ 102 | HAL_StatusTypeDef HAL_I2CEx_ConfigAnalogFilter(I2C_HandleTypeDef *hi2c, 103 | uint32_t AnalogFilter); 104 | HAL_StatusTypeDef HAL_I2CEx_ConfigDigitalFilter(I2C_HandleTypeDef *hi2c, 105 | uint32_t DigitalFilter); 106 | /** 107 | * @} 108 | */ 109 | #if defined(I2C_CR1_WUPEN) 110 | 111 | /** @addtogroup I2CEx_Exported_Functions_Group2 WakeUp Mode Functions 112 | * @{ 113 | */ 114 | HAL_StatusTypeDef HAL_I2CEx_EnableWakeUp(I2C_HandleTypeDef *hi2c); 115 | HAL_StatusTypeDef HAL_I2CEx_DisableWakeUp(I2C_HandleTypeDef *hi2c); 116 | /** 117 | * @} 118 | */ 119 | #endif /* I2C_CR1_WUPEN */ 120 | 121 | /** @addtogroup I2CEx_Exported_Functions_Group3 Fast Mode Plus Functions 122 | * @{ 123 | */ 124 | void HAL_I2CEx_EnableFastModePlus(uint32_t ConfigFastModePlus); 125 | void HAL_I2CEx_DisableFastModePlus(uint32_t ConfigFastModePlus); 126 | /** 127 | * @} 128 | */ 129 | 130 | /* Private constants ---------------------------------------------------------*/ 131 | /** @defgroup I2CEx_Private_Constants I2C Extended Private Constants 132 | * @{ 133 | */ 134 | 135 | /** 136 | * @} 137 | */ 138 | 139 | /* Private macros ------------------------------------------------------------*/ 140 | /** @defgroup I2CEx_Private_Macro I2C Extended Private Macros 141 | * @{ 142 | */ 143 | #define IS_I2C_ANALOG_FILTER(FILTER) (((FILTER) == I2C_ANALOGFILTER_ENABLE) || \ 144 | ((FILTER) == I2C_ANALOGFILTER_DISABLE)) 145 | 146 | #define IS_I2C_DIGITAL_FILTER(FILTER) ((FILTER) <= 0x0000000FU) 147 | 148 | #define IS_I2C_FASTMODEPLUS(__CONFIG__) ((((__CONFIG__) & I2C_FMP_NOT_SUPPORTED) != I2C_FMP_NOT_SUPPORTED) && \ 149 | ((((__CONFIG__) & (I2C_FASTMODEPLUS_PA9)) == I2C_FASTMODEPLUS_PA9) || \ 150 | (((__CONFIG__) & (I2C_FASTMODEPLUS_PA10)) == I2C_FASTMODEPLUS_PA10) || \ 151 | (((__CONFIG__) & (I2C_FASTMODEPLUS_PB6)) == I2C_FASTMODEPLUS_PB6) || \ 152 | (((__CONFIG__) & (I2C_FASTMODEPLUS_PB7)) == I2C_FASTMODEPLUS_PB7) || \ 153 | (((__CONFIG__) & (I2C_FASTMODEPLUS_PB8)) == I2C_FASTMODEPLUS_PB8) || \ 154 | (((__CONFIG__) & (I2C_FASTMODEPLUS_PB9)) == I2C_FASTMODEPLUS_PB9) || \ 155 | (((__CONFIG__) & (I2C_FASTMODEPLUS_I2C1)) == I2C_FASTMODEPLUS_I2C1) || \ 156 | (((__CONFIG__) & (I2C_FASTMODEPLUS_I2C2)) == I2C_FASTMODEPLUS_I2C2))) 157 | /** 158 | * @} 159 | */ 160 | 161 | /* Private Functions ---------------------------------------------------------*/ 162 | /** @defgroup I2CEx_Private_Functions I2C Extended Private Functions 163 | * @{ 164 | */ 165 | /* Private functions are defined in stm32f0xx_hal_i2c_ex.c file */ 166 | /** 167 | * @} 168 | */ 169 | 170 | /** 171 | * @} 172 | */ 173 | 174 | /** 175 | * @} 176 | */ 177 | 178 | /** 179 | * @} 180 | */ 181 | 182 | /** 183 | * @} 184 | */ 185 | 186 | #ifdef __cplusplus 187 | } 188 | #endif 189 | 190 | #endif /* STM32F0xx_HAL_I2C_EX_H */ 191 | -------------------------------------------------------------------------------- /section-05/hardware_filtering/digital_filtering.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | This document assumes you have read `analog_filtering.md`. 4 | Digital filtering is a conceptual extension of analog filtering, since it requires a stronger understanding of the calculus that drives the process of filtering. 5 | 6 | Digital filtering is the process of filtering in the *digital domain*. 7 | The general idea is to sample a voltage with an ADC through time, then mathematically process it to filter out noise. 8 | The purpose of filtering in the digital domain is to build filters that are not possible to build with analog components. 9 | 10 | Digital filters can be built to have special properties that are advantageous to the application. 11 | These properties include: 12 | - Linear phase response 13 | - Ideal or arbitrary magnitude response 14 | 15 | # Digital Filter Implementations 16 | 17 | ## Mathematical Relationship between the Input and Output Voltage 18 | The most important result from the section on the Mathematical Basis for Digital Filtering is the following mathematical algorithm: 19 | 20 | $$v_{out}(n)=\sum_{i=0}^{a}v_{in}(i)h(n-i)$$ 21 | 22 | $$v_{out}(n) = v_{in}(0)h(a) + v_{in}(1)h(a-1) + \cdots +v(a)h(0)$$ 23 | 24 | This shows the relationship between the input voltage, the transfer function (aka the filter kernel $h(n)$ ). 25 | This mathematical process is called a *convolution*, which is a series of *Multiply and Accumulate* operations. 26 | See the Mathematical Basis for Digital Filtering section for details. 27 | 28 | ## Data Flow through a Digital Filter 29 | 30 | Here are the steps that describe how data is processed in a digital filter: 31 | 32 | 1. Data populates an $a$ point long buffer. 33 | 2. While data is filling the buffer, invalid convolutions are being computed, so these outputs are discarded. 34 | 3. When the buffer is full, the MAC is performed on the entire buffer with the entire filter kernel. 35 | 4. When this happens, the first valid $v_{out}(n)$ point is created. 36 | 5. This buffer is a First In, First Out (FIFO) buffer, so after the first valid complete MAC, the next $v_{in}$ point is shifted into the buffer, knocking the first one out. 37 | 6. The next MAC is performed, and this process repeats every time the ADC produces a new sample. 38 | 39 | ## Implementations on the DFR Team 40 | 41 | On the DFR team, the CMSIS library is used to compute the digital filters. 42 | The filter kernel is hard coded, and a pointer to the kernel data is passed to a function in the CMSIS library that convolves the provided kernel with the input data. 43 | 44 | # Analog to Digital Converters 45 | 46 | Analog to Digital Converters (ADCs) have one job: measure an analog signal at regular intervals and record the data. 47 | To understand this process better, imagine you are sitting on the side of the road, and you take a video of the cars going by. 48 | You might be aware of the camera's *frame rate*, which refers to the number of "pictures" per second that the camera is capturing. 49 | An ADC works much the same way in that is has a *sampling rate*. 50 | 51 | This sampling rate is a very important design consideration due to the *nyquist theorem*, which is mentioned in the `analog_filtering.md` file. 52 | It also affects the design of the digital filter and anti-aliasing filter. 53 | 54 | ## Challenge: Digitize a Signal 55 | 56 | In tinkercad, write a program to sample a signal using the ADC on an arduino. 57 | Here is some example code: 58 | ``` c++ 59 | #define DEL 100 60 | #define NUM 1000 61 | 62 | void setup() 63 | { 64 | Serial.begin(115200); 65 | int aout = 0; 66 | 67 | for (int i=0; i _Do **not** install Git manually from the Git website._ 34 | 35 | Windows: `pacman -S mingw-w64-x86_64-tools-git ` 36 | 37 | MacOS: `brew install git ` 38 | 39 | Linux: `sudo apt install git` 40 | 41 | ### **OpenOCD** - Used for flashing and debugging. Install it using the appropriate package manager by running a command in your terminal. 42 | 43 | Windows: `pacman -S mingw-w64-x86_64-openocd ` 44 | 45 | MacOS: `brew install openocd` 46 | 47 | Linux: `sudo apt install openocd` 48 | 49 | ### **Arm-Embedded Toolchain** - A collection of tools used to develop software for ARM Cortex MCUs. Install using the same process as OpenOCD. 50 | 51 | Windows: `pacman -S mingw-w64-x86_64-arm-none-eabi-gcc ` 52 | 53 | MacOS: `brew install --cask gcc-arm-embedded ` 54 | 55 | Linux: `sudo apt install gcc-arm-none-eabi binutils-arm-none-eabi` 56 | 57 | ### **Make** - Automates the build process using a Makefile. 58 | 59 | Windows: `pacman -S mingw-w64-x86_64-make ` 60 | 61 | MacOS:`brew install make ` 62 | 63 | Linux: `sudo apt install make` 64 | 65 | ### **Cmake** - Generates build systems for projects that require cross-compilation. 66 | 67 | Windows: `pacman -S mingw-w64-x86_64-cmake ` 68 | 69 | MacOS: `brew install cmake ` 70 | 71 | Linux: `sudo apt update; sudo apt install cmake` 72 | 73 | ### **Ninja** - Lightweight and fast builder 74 | 75 | Windows: `pacman -S mingw-w64-x86_64-ninja ` 76 | 77 | MacOS: `brew install ninja ` 78 | 79 | Linux: `sudo apt update; sudo apt install ninja-build` 80 | 81 | ### **ST-Link** - Flashes the firmware to STM32 microcontrollers and enables debugging. 82 | 83 | Windows: `pacman -S mingw-w64-x86_64-stlink ` 84 | 85 | MacOS: `brew install stlink ` 86 | 87 | Linux: `sudo apt install stlink-tools` 88 | 89 | > Windows: also download [ST Drivers for Windows](https://www.st.com/en/development-tools/stsw-link009.html) 90 | 91 | ### **Clangd** - A language server and compiler backend that makes your job 10x easier. 92 | 93 | Windows: `pacman -S mingw-w64-x86_64-clang ` 94 | 95 | MacOS: `brew install llvm ` 96 | 97 | Linux: `sudo apt install clangd` 98 | 99 | ### **Python3** - CMake and other tools may use this as a dependency. Just in case. 100 | 101 | Windows: `pacman -S mingw-w64-x86_64-python ` 102 | 103 | MacOS: `brew install python ` 104 | 105 | Linux: `sudo apt install python3` 106 | 107 | ### **Known Errors and Fixes:** 108 | 109 | If you run into any installation issues, double check the command here: 110 | Windows: [https://packages.msys2.org/queue?build_type=mingw64](https://packages.msys2.org/queue?build_type=mingw64) 111 | MacOS: [https://formulae.brew.sh/](https://formulae.brew.sh/) 112 | Linux: [https://packages.ubuntu.com/](https://packages.ubuntu.com/) 113 | 114 | > This section will be expanded to continuously address any issues encountered 115 | 116 | ## **2. Configuring your PATH variable** 117 | 118 | _Your $PATH tells your shell where to look for binaries. One of the consequences of having inaccurate $PATH variables is that shell will not be able to find and execute programs without a full $PATH._ 119 | 120 | > For this guide's sake, Unix refers to both macOS (OS X) and any Linux distribution. 121 | 122 | **Windows:** Follow the instructions from [this article](https://www.architectryan.com/2018/03/17/add-to-the-path-on-windows-10/) to add `C:\msys64\mingw64\bin` and `C:msys64\usr\bin` and other tools to PATH. If system environment does not work, try adding to local user. Also, add git to path the same way, if you haven’t already. 123 | 124 | **MacOS:** Use a text editor to add the following line to your shell’s configuration file (e.g., .bashrc, .zshrc): `export PATH="/opt/homebrew/bin:$PATH"`. 125 | 126 | **Linux:** edit `~/.profile` (or `~/.bash_profile`), similar to MacOS. 127 | 128 | Note: the install location may differ for you, so update your environment variable as necessary. 129 | 130 | Make sure everything works by running ` --version` for each tool in the list. 131 | Then run `which ` or `where` for Unix or Windows, respectively. 132 | They should return their paths. 133 | 134 | Additionally, Unix users may run `echo $PATH` to verify each binary installation location is in the path. For Windows, `echo $env:Path`. 135 | 136 | Linux users may need udev rules to flash via USB. Please see [this guide on configuring udev](https://medium.com/@darshankt/setting-up-the-udev-rules-for-connecting-multiple-external-devices-through-usb-in-linux-28c110cf9251). 137 | 138 | Restart your computer. 139 | 140 | ## **3. Run and Flash** 141 | 142 | 1. Clone repo. 143 | 2. Open in VSCode. Make sure the workspace path is the root of the directory. 144 | 145 | 3. Connect H7 Nucleo board via USB to USBC. 146 | 147 | 4. Press CTRL + SHIFT + P. Then select “Tasks: Run Task”. Select “Run All”. 148 | 149 | - Alternatively, just press CTRL + SHIFT + **B** to immediately run “Tasks: Run Build Task”. 150 | 151 | ## **4. Further Readings** 152 | 153 | _If you have questions about how something works or want to learn more._ 154 | 155 | - Intro to Unix Commands: [Essential Unix Commands - GeeksforGeeks](https://www.geeksforgeeks.org/essential-linuxunix-commands/) 156 | - What is git?: [Git](https://git-scm.com/) 157 | - Git commands: [Git cheat sheet | Atlassian Git Tutorial](https://www.atlassian.com/git/tutorials/atlassian-git-cheatsheet) 158 | - SUDO: [sudo(8): Linux man page](https://linux.die.net/man/8/sudo) 159 | - MinGW: [MinGW-w64 - for 32 and 64 bit Windows / Wiki2 / History](https://sourceforge.net/p/mingw-w64/wiki2/History/) 160 | - MSYS2: [MSYS2 | Main](https://www.msys2.org/) 161 | - CMake: [CMake Documentation](https://cmake.org/documentation/), [Intro to CMake](https://youtu.be/7YcbaupsY8I?si=NXbNFzKYfwoqY7wG) 162 | - Makefile: [What is Makefile?](https://opensource.com/article/18/8/what-how-makefile) 163 | - Ninja: [Ninja](https://ninja-build.org/) 164 | - Clangd: [What is clangd?](https://clangd.llvm.org/) 165 | - About VSCode tasks: [Integrate with External Tools via Tasks](https://code.visualstudio.com/docs/editor/tasks) 166 | - What is $PATH?: [PATH (variable) - Wikipedia](), [PATH | Microsoft Learn]() 167 | 168 | ## **5. References, Sources** 169 | 170 | [1] “STM32 development and debugging using VSCode - Stm32World Wiki,” _Stm32world.com_, 2024. https://stm32world.com/wiki/STM32_development_and_debugging_using_VSCode (accessed Mar. 6, 2025). 171 | 172 | [2] “STSW-LINK009 - STMicroelectronics,” _STMicroelectronics_, 2025. https://www.st.com/en/development-tools/stsw-link009.html#documentation (accessed Mar. 10, 2025). 173 | 174 | [3] irvingywang, RoboMaster-Club, “GitHub - RoboMaster-Club/Onboarding-Project-1: Part 1 of an onboarding project which introduces students to embedded development and GPIO with STM32.,” _GitHub_, 2024. https://github.com/RoboMaster-Club/Onboarding-Project-1 (accessed Mar. 11, 2025). 175 | 176 | [4] “Add to the PATH on Windows 10 and Windows 11 | Architect Ryan,” _Architectryan.com_, 2018. https://www.architectryan.com/2018/03/17/add-to-the-path-on-windows-10/ (accessed Mar. 17, 2025). 177 | 178 | ‌[5] Eka Susilo, Youtube, “Step-by-Step: STM32 Development Environment with OpenOCD and Visual Studio Code (Linux)” 2025. https://youtu.be/FNDp1G0bYoU?si=MS14O9iSGExgvvjv (accessed Mar. 17, 2025). 179 | 180 | ‌ 181 | -------------------------------------------------------------------------------- /section-05/hardware_filtering/analog_filtering.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | The purpose of filtering a signal is to get rid of noise. 4 | The process of "analog filtering" is the use of *reactive* components to influence the spectrum of a signal (and thus get rid of noise). 5 | Reactive components are components that store energy such as capacitors and inductors. 6 | 7 | 8 | This will document not be a comprehensive overview by any means, but should provide enough information to give you a general idea of how analog filtering works. 9 | 10 | NOTE: Please read this document before reading `digital_filtering.md`. 11 | 12 | # Signal Spectra 13 | 14 | When it comes to filtering, the most important question to ask is, "what am I filtering?" 15 | To answer this question, we look to the classic example of a square wave. 16 | 17 | To understand what filtering is, you must accept the notion that periodic signals are composed of a infinite sum of sinusoids, as described by the function's *Fourier Series*. 18 | 19 | ## Fourier Series 20 | 21 | The *Fourier Series* is a specific mathematical representation of a periodic function. 22 | 23 | Any periodic function can be described as a linear combination (sum) of sinusoids. 24 | As an example, here is a square wave centered at the ground potential: 25 | 26 | ![img](figures/square_wave.JPG) 27 | 28 | This function is described by an infinite sum of sinusoids: 29 | 30 | $$f(x)=\lim_{a\to\infty}\sum_{n=1}^{a}\frac{\sin((2x-1)2\pi x)}{2x-1}$$ 31 | 32 | This can be more simply written as: 33 | 34 | $$f(x)=\lim_{a\to\infty}\sum_{n=1}^{a}\frac{1}{n}\sin(2\pi nx)$$ 35 | 36 | Where $n$ is a positive odd integer. 37 | 38 | If we let $a=1$, we see that this is the first sinusoid of the square wave, or more precisely, the *first harmonic*, whose frequency is at the *fundamental frequency* of the square wave. 39 | 40 | ![img](figures/square_wave_2.JPG) 41 | 42 | Notice how the waveform evolves as we add more harmonics. If we let $a=2$: 43 | 44 | ![img](figures/square_wave_3.JPG) 45 | 46 | If we let $a=4$: 47 | 48 | ![img](figures/square_wave_4.JPG) 49 | 50 | If we let $a=10$: 51 | 52 | ![img](figures/square_wave_5.JPG) 53 | 54 | From this series of graphs, it is clear to see that as $a\to\infty$, the graph better approximates a square wave. 55 | 56 | Below is a 1 kHz square wave: 57 | 58 | ![img](figures/square_wave_1khz.JPG) 59 | 60 | By applying what is known as the *Fourier Transform*, we can get a plot that tells us what sinusoids exist in a signal: 61 | 62 | ![img](figures/square_wave_1khz_bode.JPG) 63 | 64 | This graph shows us what the *spectrum* of the signal is. 65 | At each peak, it shows us the relative amplitude of each sinusoid at their respective frequencies. 66 | You may also think of each peak as a term in the fourier series, the amplitude and frequency of which will correspond to the graph. 67 | 68 | ## So, What am I Filtering? 69 | 70 | When you put a square wave through a low pass filter, you are attenuating the higher frequency elements of the signal, and you loose the sharpness of the square wave. The effects are shown below: 71 | 72 | ![img](figures/lpf_tran_sim.JPG) 73 | 74 | The input voltage is the red waveform, and the output voltage is the green waveform. 75 | The edges of the waveform are rounded off because the high frequency elements of the waveform have been attenuated. 76 | 77 | # Filters and Frequency Response 78 | 79 | Now that you have some understanding of what the spectrum of a signal is, we can scratch the surface of filtering using analog devices. 80 | 81 | ## RC Low Pass Filters 82 | 83 | The purpose of filtering is to rid a signal of unwanted noise. 84 | One of the most common types of filters is the *RC low pass* filter. 85 | The filter is an *RC* filter because it uses exclusively resistors and capacitors. 86 | The filter is called a *low pass* filter because it only allows low frequency energy to pass through it. 87 | 88 | Here is an example of a low pass filter drawn up in LT Spice: 89 | 90 | ![img](figures/lpf.JPG) 91 | 92 | The voltage source represents the input of the filter, and the connection point between R2 and C2 is the output of the filter. 93 | 94 | ## Bode Plots 95 | 96 | We study the performance of filters using a *Bode Plot* as shown below. This bode plot is graphed when LT Spice simulates the circuit presented previously. 97 | 98 | ![img](figures/lpf_bode.JPG) 99 | 100 | The bode plot is a representation of the filter's *frequency response*. That is, how the output compares to the input as a function of frequency. The is also commonly referred to as the spectrum of the *impulse response*. 101 | 102 | As before, the horizontal axis is frequency. The vertical axis however, is in decibels (dB). The reasons for this will become apparent later. There are two curves in the graph. The solid line represents the *magnitude*, and the faded line represents the *phase* response. 103 | For our purposes, we will only focus on the magnitude response of a filter. 104 | 105 | At the low end of the spectrum, we see that the magnitude plot shows 0 dB. 106 | This means the signal is not *attenuated* by the filter, or that is is passed through without a drop in amplitude. 107 | This will be mathematically formalized in terms of a *transfer function* later. 108 | As the frequency increases beyond a critical point (-3 dBs), the signal becomes *attenuated* (the amplitude is reduced). 109 | The higher the frequency, the more strongly attenuated it becomes when it tries to pass through the filter. 110 | In other words, the higher the frequency, the more strongly the filter attenuates the signals. 111 | 112 | ## Transfer Functions and Decibels 113 | 114 | The bode plot is derived from the application of kirchhoff's laws. 115 | This derivation is outside the scope of this work, but the point of the mathematics is to arrive at an expression for the output voltage $V_{out}$ and the input voltage $V_{in}$. 116 | 117 | Recall that the purpose of the bode plot is to compare the input to the output as a function of frequency. This gives rise to the concept of the *transfer function* ($H$), which is defined as the ratio of the output voltage to the input voltage: 118 | 119 | $$H=\frac{V_{out}}{V_{in}}$$ 120 | 121 | The magnitude response is written in dBs, and is defined as: 122 | 123 | $$20\log_{10}|H|$$ 124 | 125 | Note that when the input is equal to the output: 126 | $$|H|=1\therefore20\log_{10}|H|=0 \text{ dB}$$ 127 | 128 | The transfer function $H$ is defined in the frequency domain, which means $H$ is a function of frequency. Therefore it is commonly written as $H(\omega)$ or $H(s)$ 129 | 130 | # Applications 131 | 132 | Now that we have discussed the basics of analog filtering, we are ready to discuss where it is applied on the DFR team. 133 | 134 | ## Anti-Aliasing Filters 135 | 136 | On the DFR team, analog filters are specifically designed to support *Analog to Digital Converters* (ADCs), which are devices that digitize an analog signal. 137 | When we want to digitize a signal, our goal it to sample the signal repeatedly so that we know what the voltage is as it varies with time. 138 | Since we cannot store an infinite amount of data and we cannot sample the signal infinitely fast, we are constrained to a sampling rate. 139 | 140 | Since we are constrained by how fast we can sample, we are also constrained by what frequencies we can represent in the digital domain. 141 | Specifically, the maximum frequency we can faithfully represent using an ADC is at half the *sampling rate* ($f_s$). 142 | For example, if I sample a signal at 100 Sa/s, I can only faithfully represent signals up to 50 Hz. This is known as the *nyquist theorem*, and that maximum frequency is what I will refer to as the *nyquist frequency* ($f_n$). 143 | 144 | $$f_n=\frac{f_s}{2}$$ 145 | 146 | When energy beyond this frequency exits in the signal, it shows up in the digital domain as an *alias* of itself. This alias shows up as energy between 0 and $f_n$ Hz, which is added noise that prevents us from reconstructing the signal correctly. 147 | 148 | To get around this problem, we use *Anti-Aliasing Filters*, which are low pass RC filters when used on the DFR team. 149 | 150 | To design the filter, you consider the *quantization step* of your ADC. 151 | This is derived from the *resolution* of the ADC: 152 | 153 | $$q=\frac{1}{2^n}$$ 154 | 155 | Where $n$ is the resolution of the ADC, typically 12 to 16 bits. (So $n=12$ or $n=16$ on a typical ADC). Use this number to determine how hard your filter must attenuate energy at the nyquist frequency. 156 | In dBs, the quantization step is represented as: 157 | 158 | $$A=20\log_{10}(q)$$ 159 | 160 | For example, if you have a 16 bit ADC and are sampling at 80 MHz: 161 | 162 | $$f_n=\frac{80M\text{ Hz}}{2}=40M\text{ Hz}$$ 163 | 164 | Where $M=10^6$ 165 | 166 | Then you must attenuate everything at 40 MHz or more at least: 167 | 168 | $$20\log_{10}\left(\frac{1}{2^{16}}\right)=-96\text{ dB}$$ 169 | 170 | Which is possible with the following circuit: 171 | 172 | ![img](figures/lpf.JPG) 173 | 174 | # Challenge 175 | 176 | Build and experiment with your own low pass filter. You can do any combination of the following: 177 | - Build the filter in EveryCircuit 178 | - Build it in LT Spice 179 | - Build it in the real world 180 | -------------------------------------------------------------------------------- /section-01/WORK.md: -------------------------------------------------------------------------------- 1 | # Work for section 01 2 | 3 | Estimated completion time: 2 days. 4 | 5 | Do all of your work in this directory (but not in this file) so that it can be easily reviewed by a senior member later. 6 | 7 | You should constantly be referring back to the reading or other external sources. It is not expected of you to complete all the exercises in this unaided. 8 | 9 | This section is probably the longest section as it covers the fundamentals. 10 | 11 | Before you start, set up your environment if you haven't done so already. Go to `SETUP.md` at the root of the repo. 12 | 13 | > This tutorial assumes you are at least familiar with general programming concepts and syntax. 14 | 15 | ## Exercise 1: Hello World and compiling with `gcc` 16 | 17 | 1. Make a c file. Title it appropriately. 18 | 2. Inside your main function, write a function that prints `Hello, World!` to `stdout`. 19 | 3. Compile and run. 20 | 4. Take this easy exercise as an opprtunity to fix your toolchain, compiler settings, IDE settings and more. 21 | 5. Bonus: Swap to integers using pointers. 22 | 23 | ## Exercise 1.1: Improving code 24 | 25 | Recall the matrix example from the reading. 26 | 27 | ```C 28 | matrix_t matrix_transpose(matrix_t m) { 29 | matrix_t mt = create_matrix(m.cols, m.rows); //<- assume this has been implemented 30 | 31 | for (int i = 0; i < m.rows; ++i) { 32 | for (int j = 0; j < m.cols; ++j) { 33 | mt.data[j * m.rows + i] = m.data[i * m.cols + j]; 34 | } 35 | } 36 | 37 | return mt; 38 | } 39 | ``` 40 | 41 | How would you improve this code? 42 | 43 | ## Exercise 2: FizzBuzz 44 | 45 | 1. Inside the file you used for exercise 1, make a function with signature ` FizzBuzz` 46 | 2. The function takes one `int n` as an argument, and returns nothing 47 | 48 | - If `n` is divisible by 3, print `Fizz`. 49 | - If `n` is divisible by 5, print `Buzz`. 50 | - If `n` is divisible by both 3 and 5, print `FizzBuzz` 51 | - If `n` is not divisible by either, print nothing. 52 | 53 | 3. Dynamically allocate an `int` array using pointer notation of size 20. 54 | 4. Populate the array with numbers from 1 to 20. 55 | 5. In `main`, run the function `FizzBuzz` on the array. 56 | 6. Also in main, write a `for-loop` on `FuzzBuzz` from 1 to 30. 57 | 7. Distinguish each output using print statements. 58 | 59 | ## Exercise 3: Function pointer practice 60 | 61 | 1. Do this in the same C file as (1) and (2). 62 | 2. `qsort` is a C standard library function that implements a sorting algorithm for arrays of arbitrary objects according to a user-provided comparison function. 63 | - Write the user-provided three-way comparison function for `int` data type. 64 | - A three-way comparison takes two values `A` and `B` belonging to a type with a total order and determines whether `A < B`, `A = B`, or `A > B` in a single operation. 65 | 3. Call `qsort` on the dynamically allocated buffer from exercise 2 to sort it in descending order (20, 19, ... 1). 66 | 67 | ## Exercise 4: Blinky 68 | 69 | > First embedded code! 70 | 71 | #### In this exercise, you’ll blink the user LED using STM32 HAL functions: 72 | 73 | 1. Navigate to the `blinky` subdirectory. Some definitions: 74 | 75 | - Hardware Abstraction Layer (HAL): A software layer that allows your application to directly interact with the hardware of the microcontroller. 76 | 77 | - General Purpose Input/Output (GPIO): Pins on a microcontroller that can be configured as either inputs or outputs. They can be set to high (on) or low (off). 78 | 79 | - Think of GPIOs like a neighborhood: 80 | 81 | - A GPIO port (e.g., GPIOA, GPIOB, etc.) is like a street. 82 | 83 | - Each pin (e.g., PIN_5, PIN_13) is like a house on that street. 84 | 85 | 2. Go to `Core -> Src -> main.c`. Scroll down to line 100, inside the infinite while loop. You will write all of your code in there. Do not write code outside the while loop. Do not write code outside the `main.c` file. 86 | 87 | 3. Now go to `Drivers -> STM32F0xx_HAL_Driver -> Src -> stm32f0xx_hal_gpio.c`. 88 | 89 | 4. Scroll down to around line 415. Find the function 90 | 91 | ```C 92 | void HAL_GPIO_WritePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState) 93 | ``` 94 | 95 | 5. Now go to `Drivers -> STM32F0xx_HAL_Driver -> Src -> stm32f0xx_hal.c` 96 | 97 | 6. Scroll down to around line 359. Find the function 98 | 99 | ```C 100 | __weak void HAL_Delay(uint32_t Delay) 101 | ``` 102 | 103 | 7. Go to `Drivers -> STM32F0xx_HAL_Driver -> Inc -> stm32f0xx_hal_gpio.h`. At line 67, you will see the defined `enum` for the different `GPIO_PinState`s. 104 | 105 | - `GPIO_PIN_RESET` means setting the pin to low. 106 | - `GPIO_PIN_SET` means setting the pin to high. 107 | 108 | 8. Go back to the while loop in `main.c`. Consider the 2 functions you looked at earlier: `HAL_GPIO_WritePin(...)` and `HAL_Delay(...)`. 109 | 110 | 9. Go to `blinky.ioc` and search for `LD2` (line 65). This is your user LED. Remember the pin. Go to `Core -> Inc -> main.h` and remember which GPIO port and pin is mapped for `LD2`. Confirm that it looks like: 111 | 112 | ```C 113 | #define LD2_Pin GPIO_PIN_5 114 | #define LD2_GPIO_Port GPIOA 115 | ``` 116 | 117 | 10. Program the microcontroller such that the user LED blinks on 500 ms, then turns off for 500ms, then turns back on for 500ms and repeats this infinitely. 118 | 119 | 11. The NUCLEO-F030R8 is the hardware that this exercise targets. DFR has 3 in the shop; come see/talk to me to borrow it. You may also buy your own from this [DIGIKEY link](https://www.digikey.com/en/products/detail/stmicroelectronics/NUCLEO-F030R8/4695526?gad_campaignid=20243136172). They are about $12. 120 | 121 | 12. How to flash: 122 | 123 | - When you build the blinky project via `make`, it will output an `.elf` file. This is an "**E**xecutable and **L**inkable **F**ormat". 124 | - Connect your board via USB. Run `st-info --probe` to verify the connection. 125 | - Run the following: `st-flash write build/blinky.elf 0x80000000` 126 | - Run `st-flash reset` if it doesn't work. 127 | 128 | Remember to install the `stlink-tools` via: 129 | 130 | ```sh 131 | sudo apt install stlink-tools # Linux 132 | brew install stlink # macOS 133 | ``` 134 | 135 | --- 136 | 137 | > Footnote: You are encouraged to seek out more C programming tutorials before you move on to the final project. 138 | 139 | ## Final project for this section 140 | 141 | ### Choose a project idea from any of the following: 142 | 143 | 1. Circular Buffer Library 144 | 2. Memory Tracker 145 | 3. Mini Shell 146 | 147 | Implementation, design, and details are all up to you. Get creative! 148 | 149 | If you aren't sure, I recommend the circular buffer library as a starting point. If that sounds boring to you, try something else. 150 | 151 | #### Look at `projects` folder for more info on each idea. 152 | 153 | ### Instructions and requirements that apply to all projects: 154 | 155 | - You must link your project as a submodule within your forked copy of the repository 156 | 157 | - Your code must be modular. You must write header files for each source file you write. You must also keep source files in a subdirectory called `src` and header files in a subdirectory called `inc`. 158 | 159 | - This goes without saying, but you may only use the C language. 160 | 161 | - If you so choose, you may use inline assembly. This is optional. 162 | - You must have comments. Minimum 1 multi-line comment per function. 163 | 164 | - You must use the _Make_ build system and you must write your own `makefile`. Requirements for build system: 165 | 166 | - It must place build output files in a subdirectory called `build`. 167 | - It should support `make clean`, which cleans the `build` folder. 168 | - It should support `make run`, which runs the built executable. 169 | 170 | - Create a GitHub Actions workflow in `.github/workflows/build.yml`. Your workflow must: 171 | 172 | - Run on `ubuntu-latest` 173 | 174 | - Perform the following: 175 | 176 | - Checkout the repository 177 | 178 | - Initialize and update submodules 179 | 180 | - Run make and confirm a clean build 181 | 182 | - (Optional bonus) Run make run and check for expected output 183 | 184 | - You must have a minimum of 7 **well-named, significant** commits. If you think your project can be finished under 7 commits, it is not hard enough. 185 | 186 | - Pull requests for merging features on branches is not required. 187 | - Commit naming convention as outlined [here](https://www.conventionalcommits.org/en/v1.0.0/#summary) 188 | - Pull request naming convention as outlined [here](https://github.com/mozilla-mobile/firefox-ios/wiki/Pull-Request-Naming-Guide) 189 | - PRs are optional, but follow this naming convention outside of this tutorial, too. 190 | 191 | - Create a `README.md` that aptly describes what your project does. Your `README.md` must also contain **all** of the following: 192 | 193 | - A directory tree: use the `tree` command line tool 194 | - A short explanation of each module 195 | 196 | - If you need help, I have created an example project that satisfies all of the conditions (except module explanations and comments). View it [here](https://github.com/wxkim/julia). 197 | 198 | - Note: Your project should be significantly **less** complex than the example. 199 | 200 | - Finally, your project must work. It should build, and functionality error should be minimal, if not zero. 201 | - You do not have to make this project cross-platform. 202 | -------------------------------------------------------------------------------- /section-01/blinky/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.c: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file stm32f0xx_hal_pwr_ex.c 4 | * @author MCD Application Team 5 | * @brief Extended PWR HAL module driver. 6 | * This file provides firmware functions to manage the following 7 | * functionalities of the Power Controller (PWR) peripheral: 8 | * + Extended Initialization and de-initialization functions 9 | * + Extended Peripheral Control functions 10 | * 11 | ****************************************************************************** 12 | * @attention 13 | * 14 | * Copyright (c) 2016 STMicroelectronics. 15 | * All rights reserved. 16 | * 17 | * This software is licensed under terms that can be found in the LICENSE file 18 | * in the root directory of this software component. 19 | * If no LICENSE file comes with this software, it is provided AS-IS. 20 | * 21 | ****************************************************************************** 22 | */ 23 | 24 | /* Includes ------------------------------------------------------------------*/ 25 | #include "stm32f0xx_hal.h" 26 | 27 | /** @addtogroup STM32F0xx_HAL_Driver 28 | * @{ 29 | */ 30 | 31 | /** @defgroup PWREx PWREx 32 | * @brief PWREx HAL module driver 33 | * @{ 34 | */ 35 | 36 | #ifdef HAL_PWR_MODULE_ENABLED 37 | 38 | /* Private typedef -----------------------------------------------------------*/ 39 | /* Private define ------------------------------------------------------------*/ 40 | /** @defgroup PWREx_Private_Constants PWREx Private Constants 41 | * @{ 42 | */ 43 | #define PVD_MODE_IT (0x00010000U) 44 | #define PVD_MODE_EVT (0x00020000U) 45 | #define PVD_RISING_EDGE (0x00000001U) 46 | #define PVD_FALLING_EDGE (0x00000002U) 47 | /** 48 | * @} 49 | */ 50 | 51 | /* Private macro -------------------------------------------------------------*/ 52 | /* Private variables ---------------------------------------------------------*/ 53 | /* Private function prototypes -----------------------------------------------*/ 54 | /* Exported functions ---------------------------------------------------------*/ 55 | 56 | /** @defgroup PWREx_Exported_Functions PWREx Exported Functions 57 | * @{ 58 | */ 59 | 60 | /** @defgroup PWREx_Exported_Functions_Group1 Peripheral Extended Control Functions 61 | * @brief Extended Peripheral Control functions 62 | * 63 | @verbatim 64 | 65 | =============================================================================== 66 | ##### Peripheral extended control functions ##### 67 | =============================================================================== 68 | 69 | *** PVD configuration *** 70 | ========================= 71 | [..] 72 | (+) The PVD is used to monitor the VDD power supply by comparing it to a 73 | threshold selected by the PVD Level (PLS[2:0] bits in the PWR_CR). 74 | (+) A PVDO flag is available to indicate if VDD/VDDA is higher or lower 75 | than the PVD threshold. This event is internally connected to the EXTI 76 | line16 and can generate an interrupt if enabled. This is done through 77 | HAL_PWR_ConfigPVD(), HAL_PWR_EnablePVD() functions. 78 | (+) The PVD is stopped in Standby mode. 79 | -@- PVD is not available on STM32F030x4/x6/x8 80 | 81 | *** VDDIO2 Monitor Configuration *** 82 | ==================================== 83 | [..] 84 | (+) VDDIO2 monitor is used to monitor the VDDIO2 power supply by comparing it 85 | to VREFInt Voltage 86 | (+) This monitor is internally connected to the EXTI line31 87 | and can generate an interrupt if enabled. This is done through 88 | HAL_PWREx_EnableVddio2Monitor() function. 89 | -@- VDDIO2 is available on STM32F07x/09x/04x 90 | 91 | @endverbatim 92 | * @{ 93 | */ 94 | 95 | #if defined (STM32F031x6) || defined (STM32F051x8) || \ 96 | defined (STM32F071xB) || defined (STM32F091xC) || \ 97 | defined (STM32F042x6) || defined (STM32F072xB) 98 | /** 99 | * @brief Configures the voltage threshold detected by the Power Voltage Detector(PVD). 100 | * @param sConfigPVD pointer to an PWR_PVDTypeDef structure that contains the configuration 101 | * information for the PVD. 102 | * @note Refer to the electrical characteristics of your device datasheet for 103 | * more details about the voltage threshold corresponding to each 104 | * detection level. 105 | * @retval None 106 | */ 107 | void HAL_PWR_ConfigPVD(PWR_PVDTypeDef *sConfigPVD) 108 | { 109 | /* Check the parameters */ 110 | assert_param(IS_PWR_PVD_LEVEL(sConfigPVD->PVDLevel)); 111 | assert_param(IS_PWR_PVD_MODE(sConfigPVD->Mode)); 112 | 113 | /* Set PLS[7:5] bits according to PVDLevel value */ 114 | MODIFY_REG(PWR->CR, PWR_CR_PLS, sConfigPVD->PVDLevel); 115 | 116 | /* Clear any previous config. Keep it clear if no event or IT mode is selected */ 117 | __HAL_PWR_PVD_EXTI_DISABLE_EVENT(); 118 | __HAL_PWR_PVD_EXTI_DISABLE_IT(); 119 | __HAL_PWR_PVD_EXTI_DISABLE_RISING_EDGE();__HAL_PWR_PVD_EXTI_DISABLE_FALLING_EDGE(); 120 | 121 | /* Configure interrupt mode */ 122 | if((sConfigPVD->Mode & PVD_MODE_IT) == PVD_MODE_IT) 123 | { 124 | __HAL_PWR_PVD_EXTI_ENABLE_IT(); 125 | } 126 | 127 | /* Configure event mode */ 128 | if((sConfigPVD->Mode & PVD_MODE_EVT) == PVD_MODE_EVT) 129 | { 130 | __HAL_PWR_PVD_EXTI_ENABLE_EVENT(); 131 | } 132 | 133 | /* Configure the edge */ 134 | if((sConfigPVD->Mode & PVD_RISING_EDGE) == PVD_RISING_EDGE) 135 | { 136 | __HAL_PWR_PVD_EXTI_ENABLE_RISING_EDGE(); 137 | } 138 | 139 | if((sConfigPVD->Mode & PVD_FALLING_EDGE) == PVD_FALLING_EDGE) 140 | { 141 | __HAL_PWR_PVD_EXTI_ENABLE_FALLING_EDGE(); 142 | } 143 | } 144 | 145 | /** 146 | * @brief Enables the Power Voltage Detector(PVD). 147 | * @retval None 148 | */ 149 | void HAL_PWR_EnablePVD(void) 150 | { 151 | PWR->CR |= (uint32_t)PWR_CR_PVDE; 152 | } 153 | 154 | /** 155 | * @brief Disables the Power Voltage Detector(PVD). 156 | * @retval None 157 | */ 158 | void HAL_PWR_DisablePVD(void) 159 | { 160 | PWR->CR &= ~((uint32_t)PWR_CR_PVDE); 161 | } 162 | 163 | /** 164 | * @brief This function handles the PWR PVD interrupt request. 165 | * @note This API should be called under the PVD_IRQHandler() or PVD_VDDIO2_IRQHandler(). 166 | * @retval None 167 | */ 168 | void HAL_PWR_PVD_IRQHandler(void) 169 | { 170 | /* Check PWR exti flag */ 171 | if(__HAL_PWR_PVD_EXTI_GET_FLAG() != RESET) 172 | { 173 | /* PWR PVD interrupt user callback */ 174 | HAL_PWR_PVDCallback(); 175 | 176 | /* Clear PWR Exti pending bit */ 177 | __HAL_PWR_PVD_EXTI_CLEAR_FLAG(); 178 | } 179 | } 180 | 181 | /** 182 | * @brief PWR PVD interrupt callback 183 | * @retval None 184 | */ 185 | __weak void HAL_PWR_PVDCallback(void) 186 | { 187 | /* NOTE : This function Should not be modified, when the callback is needed, 188 | the HAL_PWR_PVDCallback could be implemented in the user file 189 | */ 190 | } 191 | 192 | #endif /* defined (STM32F031x6) || defined (STM32F051x8) || */ 193 | /* defined (STM32F071xB) || defined (STM32F091xC) || */ 194 | /* defined (STM32F042x6) || defined (STM32F072xB) */ 195 | 196 | #if defined (STM32F042x6) || defined (STM32F048xx) || \ 197 | defined (STM32F071xB) || defined (STM32F072xB) || defined (STM32F078xx) || \ 198 | defined (STM32F091xC) || defined (STM32F098xx) 199 | /** 200 | * @brief Enable VDDIO2 monitor: enable Exti 31 and falling edge detection. 201 | * @note If Exti 31 is enable correlty and VDDIO2 voltage goes below Vrefint, 202 | an interrupt is generated Irq line 1. 203 | NVIS has to be enable by user. 204 | * @retval None 205 | */ 206 | void HAL_PWREx_EnableVddio2Monitor(void) 207 | { 208 | __HAL_PWR_VDDIO2_EXTI_ENABLE_IT(); 209 | __HAL_PWR_VDDIO2_EXTI_ENABLE_FALLING_EDGE(); 210 | } 211 | 212 | /** 213 | * @brief Disable the Vddio2 Monitor. 214 | * @retval None 215 | */ 216 | void HAL_PWREx_DisableVddio2Monitor(void) 217 | { 218 | __HAL_PWR_VDDIO2_EXTI_DISABLE_IT(); 219 | __HAL_PWR_VDDIO2_EXTI_DISABLE_FALLING_EDGE(); 220 | 221 | } 222 | 223 | /** 224 | * @brief This function handles the PWR Vddio2 monitor interrupt request. 225 | * @note This API should be called under the VDDIO2_IRQHandler() PVD_VDDIO2_IRQHandler(). 226 | * @retval None 227 | */ 228 | void HAL_PWREx_Vddio2Monitor_IRQHandler(void) 229 | { 230 | /* Check PWR exti flag */ 231 | if(__HAL_PWR_VDDIO2_EXTI_GET_FLAG() != RESET) 232 | { 233 | /* PWR Vddio2 monitor interrupt user callback */ 234 | HAL_PWREx_Vddio2MonitorCallback(); 235 | 236 | /* Clear PWR Exti pending bit */ 237 | __HAL_PWR_VDDIO2_EXTI_CLEAR_FLAG(); 238 | } 239 | } 240 | 241 | /** 242 | * @brief PWR Vddio2 Monitor interrupt callback 243 | * @retval None 244 | */ 245 | __weak void HAL_PWREx_Vddio2MonitorCallback(void) 246 | { 247 | /* NOTE : This function Should not be modified, when the callback is needed, 248 | the HAL_PWREx_Vddio2MonitorCallback could be implemented in the user file 249 | */ 250 | } 251 | 252 | #endif /* defined (STM32F042x6) || defined (STM32F048xx) || \ 253 | defined (STM32F071xB) || defined (STM32F072xB) || defined (STM32F078xx) || \ 254 | defined (STM32F091xC) || defined (STM32F098xx) */ 255 | 256 | /** 257 | * @} 258 | */ 259 | 260 | /** 261 | * @} 262 | */ 263 | 264 | #endif /* HAL_PWR_MODULE_ENABLED */ 265 | /** 266 | * @} 267 | */ 268 | 269 | /** 270 | * @} 271 | */ 272 | -------------------------------------------------------------------------------- /section-01/blinky/Core/Src/system_stm32f0xx.c: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file system_stm32f0xx.c 4 | * @author MCD Application Team 5 | * @brief CMSIS Cortex-M0 Device Peripheral Access Layer System Source File. 6 | * 7 | * 1. This file provides two functions and one global variable to be called from 8 | * user application: 9 | * - SystemInit(): This function is called at startup just after reset and 10 | * before branch to main program. This call is made inside 11 | * the "startup_stm32f0xx.s" file. 12 | * 13 | * - SystemCoreClock variable: Contains the core clock (HCLK), it can be used 14 | * by the user application to setup the SysTick 15 | * timer or configure other parameters. 16 | * 17 | * - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must 18 | * be called whenever the core clock is changed 19 | * during program execution. 20 | * 21 | * 22 | ****************************************************************************** 23 | * @attention 24 | * 25 | * Copyright (c) 2016 STMicroelectronics. 26 | * All rights reserved. 27 | * 28 | * This software is licensed under terms that can be found in the LICENSE file 29 | * in the root directory of this software component. 30 | * If no LICENSE file comes with this software, it is provided AS-IS. 31 | * 32 | ****************************************************************************** 33 | */ 34 | /** @addtogroup CMSIS 35 | * @{ 36 | */ 37 | 38 | /** @addtogroup stm32f0xx_system 39 | * @{ 40 | */ 41 | 42 | /** @addtogroup STM32F0xx_System_Private_Includes 43 | * @{ 44 | */ 45 | 46 | #include "stm32f0xx.h" 47 | 48 | /** 49 | * @} 50 | */ 51 | 52 | /** @addtogroup STM32F0xx_System_Private_TypesDefinitions 53 | * @{ 54 | */ 55 | 56 | /** 57 | * @} 58 | */ 59 | 60 | /** @addtogroup STM32F0xx_System_Private_Defines 61 | * @{ 62 | */ 63 | #if !defined (HSE_VALUE) 64 | #define HSE_VALUE ((uint32_t)8000000) /*!< Default value of the External oscillator in Hz. 65 | This value can be provided and adapted by the user application. */ 66 | #endif /* HSE_VALUE */ 67 | 68 | #if !defined (HSI_VALUE) 69 | #define HSI_VALUE ((uint32_t)8000000) /*!< Default value of the Internal oscillator in Hz. 70 | This value can be provided and adapted by the user application. */ 71 | #endif /* HSI_VALUE */ 72 | 73 | #if !defined (HSI48_VALUE) 74 | #define HSI48_VALUE ((uint32_t)48000000) /*!< Default value of the HSI48 Internal oscillator in Hz. 75 | This value can be provided and adapted by the user application. */ 76 | #endif /* HSI48_VALUE */ 77 | /** 78 | * @} 79 | */ 80 | 81 | /** @addtogroup STM32F0xx_System_Private_Macros 82 | * @{ 83 | */ 84 | 85 | /** 86 | * @} 87 | */ 88 | 89 | /** @addtogroup STM32F0xx_System_Private_Variables 90 | * @{ 91 | */ 92 | /* This variable is updated in three ways: 93 | 1) by calling CMSIS function SystemCoreClockUpdate() 94 | 2) by calling HAL API function HAL_RCC_GetHCLKFreq() 95 | 3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency 96 | Note: If you use this function to configure the system clock; then there 97 | is no need to call the 2 first functions listed above, since SystemCoreClock 98 | variable is updated automatically. 99 | */ 100 | uint32_t SystemCoreClock = 8000000; 101 | 102 | const uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9}; 103 | const uint8_t APBPrescTable[8] = {0, 0, 0, 0, 1, 2, 3, 4}; 104 | 105 | /** 106 | * @} 107 | */ 108 | 109 | /** @addtogroup STM32F0xx_System_Private_FunctionPrototypes 110 | * @{ 111 | */ 112 | 113 | /** 114 | * @} 115 | */ 116 | 117 | /** @addtogroup STM32F0xx_System_Private_Functions 118 | * @{ 119 | */ 120 | 121 | /** 122 | * @brief Setup the microcontroller system 123 | * @param None 124 | * @retval None 125 | */ 126 | void SystemInit(void) 127 | { 128 | /* NOTE :SystemInit(): This function is called at startup just after reset and 129 | before branch to main program. This call is made inside 130 | the "startup_stm32f0xx.s" file. 131 | User can setups the default system clock (System clock source, PLL Multiplier 132 | and Divider factors, AHB/APBx prescalers and Flash settings). 133 | */ 134 | } 135 | 136 | /** 137 | * @brief Update SystemCoreClock variable according to Clock Register Values. 138 | * The SystemCoreClock variable contains the core clock (HCLK), it can 139 | * be used by the user application to setup the SysTick timer or configure 140 | * other parameters. 141 | * 142 | * @note Each time the core clock (HCLK) changes, this function must be called 143 | * to update SystemCoreClock variable value. Otherwise, any configuration 144 | * based on this variable will be incorrect. 145 | * 146 | * @note - The system frequency computed by this function is not the real 147 | * frequency in the chip. It is calculated based on the predefined 148 | * constant and the selected clock source: 149 | * 150 | * - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*) 151 | * 152 | * - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(**) 153 | * 154 | * - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**) 155 | * or HSI_VALUE(*) multiplied/divided by the PLL factors. 156 | * 157 | * - If SYSCLK source is HSI48, SystemCoreClock will contain the HSI48_VALUE(***) 158 | * 159 | * (*) HSI_VALUE is a constant defined in stm32f0xx_hal_conf.h file (default value 160 | * 8 MHz) but the real value may vary depending on the variations 161 | * in voltage and temperature. 162 | * 163 | * (**) HSE_VALUE is a constant defined in stm32f0xx_hal_conf.h file (its value 164 | * depends on the application requirements), user has to ensure that HSE_VALUE 165 | * is same as the real frequency of the crystal used. Otherwise, this function 166 | * may have wrong result. 167 | * 168 | * (***) HSI48_VALUE is a constant defined in stm32f0xx_hal_conf.h file (default value 169 | * 48 MHz) but the real value may vary depending on the variations 170 | * in voltage and temperature. 171 | * 172 | * - The result of this function could be not correct when using fractional 173 | * value for HSE crystal. 174 | * 175 | * @param None 176 | * @retval None 177 | */ 178 | void SystemCoreClockUpdate (void) 179 | { 180 | uint32_t tmp = 0, pllmull = 0, pllsource = 0, predivfactor = 0; 181 | 182 | /* Get SYSCLK source -------------------------------------------------------*/ 183 | tmp = RCC->CFGR & RCC_CFGR_SWS; 184 | 185 | switch (tmp) 186 | { 187 | case RCC_CFGR_SWS_HSI: /* HSI used as system clock */ 188 | SystemCoreClock = HSI_VALUE; 189 | break; 190 | case RCC_CFGR_SWS_HSE: /* HSE used as system clock */ 191 | SystemCoreClock = HSE_VALUE; 192 | break; 193 | case RCC_CFGR_SWS_PLL: /* PLL used as system clock */ 194 | /* Get PLL clock source and multiplication factor ----------------------*/ 195 | pllmull = RCC->CFGR & RCC_CFGR_PLLMUL; 196 | pllsource = RCC->CFGR & RCC_CFGR_PLLSRC; 197 | pllmull = ( pllmull >> 18) + 2; 198 | predivfactor = (RCC->CFGR2 & RCC_CFGR2_PREDIV) + 1; 199 | 200 | if (pllsource == RCC_CFGR_PLLSRC_HSE_PREDIV) 201 | { 202 | /* HSE used as PLL clock source : SystemCoreClock = HSE/PREDIV * PLLMUL */ 203 | SystemCoreClock = (HSE_VALUE/predivfactor) * pllmull; 204 | } 205 | #if defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx) || defined(STM32F091xC) || defined(STM32F098xx) 206 | else if (pllsource == RCC_CFGR_PLLSRC_HSI48_PREDIV) 207 | { 208 | /* HSI48 used as PLL clock source : SystemCoreClock = HSI48/PREDIV * PLLMUL */ 209 | SystemCoreClock = (HSI48_VALUE/predivfactor) * pllmull; 210 | } 211 | #endif /* STM32F042x6 || STM32F048xx || STM32F071xB || STM32F072xB || STM32F078xx || STM32F091xC || STM32F098xx */ 212 | else 213 | { 214 | #if defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F070x6) \ 215 | || defined(STM32F078xx) || defined(STM32F071xB) || defined(STM32F072xB) \ 216 | || defined(STM32F070xB) || defined(STM32F091xC) || defined(STM32F098xx) || defined(STM32F030xC) 217 | /* HSI used as PLL clock source : SystemCoreClock = HSI/PREDIV * PLLMUL */ 218 | SystemCoreClock = (HSI_VALUE/predivfactor) * pllmull; 219 | #else 220 | /* HSI used as PLL clock source : SystemCoreClock = HSI/2 * PLLMUL */ 221 | SystemCoreClock = (HSI_VALUE >> 1) * pllmull; 222 | #endif /* STM32F042x6 || STM32F048xx || STM32F070x6 || 223 | STM32F071xB || STM32F072xB || STM32F078xx || STM32F070xB || 224 | STM32F091xC || STM32F098xx || STM32F030xC */ 225 | } 226 | break; 227 | default: /* HSI used as system clock */ 228 | SystemCoreClock = HSI_VALUE; 229 | break; 230 | } 231 | /* Compute HCLK clock frequency ----------------*/ 232 | /* Get HCLK prescaler */ 233 | tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4)]; 234 | /* HCLK clock frequency */ 235 | SystemCoreClock >>= tmp; 236 | } 237 | 238 | /** 239 | * @} 240 | */ 241 | 242 | /** 243 | * @} 244 | */ 245 | 246 | /** 247 | * @} 248 | */ 249 | 250 | -------------------------------------------------------------------------------- /section-01/blinky/Drivers/CMSIS/Include/cmsis_compiler.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************//** 2 | * @file cmsis_compiler.h 3 | * @brief CMSIS compiler generic header file 4 | * @version V5.0.4 5 | * @date 10. January 2018 6 | ******************************************************************************/ 7 | /* 8 | * Copyright (c) 2009-2018 Arm Limited. All rights reserved. 9 | * 10 | * SPDX-License-Identifier: Apache-2.0 11 | * 12 | * Licensed under the Apache License, Version 2.0 (the License); you may 13 | * not use this file except in compliance with the License. 14 | * You may obtain a copy of the License at 15 | * 16 | * www.apache.org/licenses/LICENSE-2.0 17 | * 18 | * Unless required by applicable law or agreed to in writing, software 19 | * distributed under the License is distributed on an AS IS BASIS, WITHOUT 20 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 21 | * See the License for the specific language governing permissions and 22 | * limitations under the License. 23 | */ 24 | 25 | #ifndef __CMSIS_COMPILER_H 26 | #define __CMSIS_COMPILER_H 27 | 28 | #include 29 | 30 | /* 31 | * Arm Compiler 4/5 32 | */ 33 | #if defined ( __CC_ARM ) 34 | #include "cmsis_armcc.h" 35 | 36 | 37 | /* 38 | * Arm Compiler 6 (armclang) 39 | */ 40 | #elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) 41 | #include "cmsis_armclang.h" 42 | 43 | 44 | /* 45 | * GNU Compiler 46 | */ 47 | #elif defined ( __GNUC__ ) 48 | #include "cmsis_gcc.h" 49 | 50 | 51 | /* 52 | * IAR Compiler 53 | */ 54 | #elif defined ( __ICCARM__ ) 55 | #include 56 | 57 | 58 | /* 59 | * TI Arm Compiler 60 | */ 61 | #elif defined ( __TI_ARM__ ) 62 | #include 63 | 64 | #ifndef __ASM 65 | #define __ASM __asm 66 | #endif 67 | #ifndef __INLINE 68 | #define __INLINE inline 69 | #endif 70 | #ifndef __STATIC_INLINE 71 | #define __STATIC_INLINE static inline 72 | #endif 73 | #ifndef __STATIC_FORCEINLINE 74 | #define __STATIC_FORCEINLINE __STATIC_INLINE 75 | #endif 76 | #ifndef __NO_RETURN 77 | #define __NO_RETURN __attribute__((noreturn)) 78 | #endif 79 | #ifndef __USED 80 | #define __USED __attribute__((used)) 81 | #endif 82 | #ifndef __WEAK 83 | #define __WEAK __attribute__((weak)) 84 | #endif 85 | #ifndef __PACKED 86 | #define __PACKED __attribute__((packed)) 87 | #endif 88 | #ifndef __PACKED_STRUCT 89 | #define __PACKED_STRUCT struct __attribute__((packed)) 90 | #endif 91 | #ifndef __PACKED_UNION 92 | #define __PACKED_UNION union __attribute__((packed)) 93 | #endif 94 | #ifndef __UNALIGNED_UINT32 /* deprecated */ 95 | struct __attribute__((packed)) T_UINT32 { uint32_t v; }; 96 | #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) 97 | #endif 98 | #ifndef __UNALIGNED_UINT16_WRITE 99 | __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; 100 | #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void*)(addr))->v) = (val)) 101 | #endif 102 | #ifndef __UNALIGNED_UINT16_READ 103 | __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; 104 | #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) 105 | #endif 106 | #ifndef __UNALIGNED_UINT32_WRITE 107 | __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; 108 | #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) 109 | #endif 110 | #ifndef __UNALIGNED_UINT32_READ 111 | __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; 112 | #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) 113 | #endif 114 | #ifndef __ALIGNED 115 | #define __ALIGNED(x) __attribute__((aligned(x))) 116 | #endif 117 | #ifndef __RESTRICT 118 | #warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored. 119 | #define __RESTRICT 120 | #endif 121 | 122 | 123 | /* 124 | * TASKING Compiler 125 | */ 126 | #elif defined ( __TASKING__ ) 127 | /* 128 | * The CMSIS functions have been implemented as intrinsics in the compiler. 129 | * Please use "carm -?i" to get an up to date list of all intrinsics, 130 | * Including the CMSIS ones. 131 | */ 132 | 133 | #ifndef __ASM 134 | #define __ASM __asm 135 | #endif 136 | #ifndef __INLINE 137 | #define __INLINE inline 138 | #endif 139 | #ifndef __STATIC_INLINE 140 | #define __STATIC_INLINE static inline 141 | #endif 142 | #ifndef __STATIC_FORCEINLINE 143 | #define __STATIC_FORCEINLINE __STATIC_INLINE 144 | #endif 145 | #ifndef __NO_RETURN 146 | #define __NO_RETURN __attribute__((noreturn)) 147 | #endif 148 | #ifndef __USED 149 | #define __USED __attribute__((used)) 150 | #endif 151 | #ifndef __WEAK 152 | #define __WEAK __attribute__((weak)) 153 | #endif 154 | #ifndef __PACKED 155 | #define __PACKED __packed__ 156 | #endif 157 | #ifndef __PACKED_STRUCT 158 | #define __PACKED_STRUCT struct __packed__ 159 | #endif 160 | #ifndef __PACKED_UNION 161 | #define __PACKED_UNION union __packed__ 162 | #endif 163 | #ifndef __UNALIGNED_UINT32 /* deprecated */ 164 | struct __packed__ T_UINT32 { uint32_t v; }; 165 | #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) 166 | #endif 167 | #ifndef __UNALIGNED_UINT16_WRITE 168 | __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; 169 | #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) 170 | #endif 171 | #ifndef __UNALIGNED_UINT16_READ 172 | __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; 173 | #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) 174 | #endif 175 | #ifndef __UNALIGNED_UINT32_WRITE 176 | __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; 177 | #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) 178 | #endif 179 | #ifndef __UNALIGNED_UINT32_READ 180 | __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; 181 | #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) 182 | #endif 183 | #ifndef __ALIGNED 184 | #define __ALIGNED(x) __align(x) 185 | #endif 186 | #ifndef __RESTRICT 187 | #warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored. 188 | #define __RESTRICT 189 | #endif 190 | 191 | 192 | /* 193 | * COSMIC Compiler 194 | */ 195 | #elif defined ( __CSMC__ ) 196 | #include 197 | 198 | #ifndef __ASM 199 | #define __ASM _asm 200 | #endif 201 | #ifndef __INLINE 202 | #define __INLINE inline 203 | #endif 204 | #ifndef __STATIC_INLINE 205 | #define __STATIC_INLINE static inline 206 | #endif 207 | #ifndef __STATIC_FORCEINLINE 208 | #define __STATIC_FORCEINLINE __STATIC_INLINE 209 | #endif 210 | #ifndef __NO_RETURN 211 | // NO RETURN is automatically detected hence no warning here 212 | #define __NO_RETURN 213 | #endif 214 | #ifndef __USED 215 | #warning No compiler specific solution for __USED. __USED is ignored. 216 | #define __USED 217 | #endif 218 | #ifndef __WEAK 219 | #define __WEAK __weak 220 | #endif 221 | #ifndef __PACKED 222 | #define __PACKED @packed 223 | #endif 224 | #ifndef __PACKED_STRUCT 225 | #define __PACKED_STRUCT @packed struct 226 | #endif 227 | #ifndef __PACKED_UNION 228 | #define __PACKED_UNION @packed union 229 | #endif 230 | #ifndef __UNALIGNED_UINT32 /* deprecated */ 231 | @packed struct T_UINT32 { uint32_t v; }; 232 | #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) 233 | #endif 234 | #ifndef __UNALIGNED_UINT16_WRITE 235 | __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; 236 | #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) 237 | #endif 238 | #ifndef __UNALIGNED_UINT16_READ 239 | __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; 240 | #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) 241 | #endif 242 | #ifndef __UNALIGNED_UINT32_WRITE 243 | __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; 244 | #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) 245 | #endif 246 | #ifndef __UNALIGNED_UINT32_READ 247 | __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; 248 | #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) 249 | #endif 250 | #ifndef __ALIGNED 251 | #warning No compiler specific solution for __ALIGNED. __ALIGNED is ignored. 252 | #define __ALIGNED(x) 253 | #endif 254 | #ifndef __RESTRICT 255 | #warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored. 256 | #define __RESTRICT 257 | #endif 258 | 259 | 260 | #else 261 | #error Unknown compiler. 262 | #endif 263 | 264 | 265 | #endif /* __CMSIS_COMPILER_H */ 266 | 267 | --------------------------------------------------------------------------------