├── cpp ├── lib │ ├── usart │ │ └── usart.cpp │ ├── gpio │ │ ├── gpio.cpp │ │ └── gpio.hpp │ ├── dma │ │ ├── dma.cpp │ │ ├── dma_channel.cpp │ │ ├── dma.hpp │ │ └── dma_channel.hpp │ ├── system │ │ ├── system.cpp │ │ └── system.hpp │ └── rcc │ │ └── rcc.hpp ├── .gitignore ├── .vscode │ ├── c_cpp_properties.json │ └── launch.json ├── stm32f1.ld ├── src │ ├── main.cpp │ └── startup_stm32f103.cpp ├── include │ ├── cmsis_version.h │ ├── system_stm32f1xx.h │ └── cmsis_compiler.h ├── Makefile └── README.md ├── .gitignore ├── docs ├── flow.png ├── label.png ├── no-label.png ├── output.jpg ├── github-cover.png ├── uart.drawio └── flow.drawio ├── dma-1shot ├── docs │ ├── out_echo.png │ ├── out_one_shot.png │ └── out_115200_circ.png ├── include │ ├── stm32f103xb.h │ ├── dma.h │ ├── timer.h │ ├── cmsis_version.h │ ├── main.h │ ├── system_stm32f1xx.h │ ├── startup_stm32f1.h │ └── cmsis_compiler.h ├── .gitignore ├── .vscode │ ├── c_cpp_properties.json │ └── launch.json ├── src │ ├── timer.c │ ├── main.c │ └── startup_stm32f1.c ├── stm32f1.ld ├── Makefile └── README.md ├── dma-echo ├── docs │ ├── out_echo.png │ ├── out_one_shot.png │ └── out_115200_circ.png ├── include │ ├── stm32f103xb.h │ ├── timer.h │ ├── cmsis_version.h │ ├── main.h │ ├── system_stm32f1xx.h │ ├── startup_stm32f1.h │ └── cmsis_compiler.h ├── .gitignore ├── .vscode │ ├── c_cpp_properties.json │ └── launch.json ├── src │ ├── timer.c │ ├── startup_stm32f1.c │ └── main.c ├── stm32f1.ld ├── Makefile └── README.md ├── polling ├── include │ ├── stm32f103xb.h │ ├── timer.h │ ├── uart.h │ ├── cmsis_version.h │ └── system_stm32f1xx.h ├── .vscode │ ├── settings.json │ ├── extensions.json │ ├── c_cpp_properties.json │ └── launch.json ├── src │ ├── timer.c │ ├── uart.c │ └── main.c ├── Makefile ├── STM32F103C8TX_FLASH.ld └── README.md ├── dma-circular ├── docs │ ├── out_echo.png │ ├── out_one_shot.png │ └── out_115200_circ.png ├── include │ ├── stm32f103xb.h │ ├── timer.h │ ├── cmsis_version.h │ ├── main.h │ ├── system_stm32f1xx.h │ └── startup_stm32f1.h ├── .gitignore ├── .vscode │ ├── c_cpp_properties.json │ └── launch.json ├── src │ ├── timer.c │ ├── main.c │ └── startup_stm32f1.c ├── stm32f1.ld ├── Makefile └── README.md └── README.md /cpp/lib/usart/usart.cpp: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /cpp/.gitignore: -------------------------------------------------------------------------------- 1 | .s 2 | .d 3 | .o 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | .DS_Store 3 | .cortex-debug* 4 | *.bkp 5 | *.dtmp 6 | 7 | -------------------------------------------------------------------------------- /docs/flow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/csrohit/stm32-uart/HEAD/docs/flow.png -------------------------------------------------------------------------------- /docs/label.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/csrohit/stm32-uart/HEAD/docs/label.png -------------------------------------------------------------------------------- /docs/no-label.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/csrohit/stm32-uart/HEAD/docs/no-label.png -------------------------------------------------------------------------------- /docs/output.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/csrohit/stm32-uart/HEAD/docs/output.jpg -------------------------------------------------------------------------------- /docs/github-cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/csrohit/stm32-uart/HEAD/docs/github-cover.png -------------------------------------------------------------------------------- /dma-1shot/docs/out_echo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/csrohit/stm32-uart/HEAD/dma-1shot/docs/out_echo.png -------------------------------------------------------------------------------- /dma-echo/docs/out_echo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/csrohit/stm32-uart/HEAD/dma-echo/docs/out_echo.png -------------------------------------------------------------------------------- /polling/include/stm32f103xb.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/csrohit/stm32-uart/HEAD/polling/include/stm32f103xb.h -------------------------------------------------------------------------------- /dma-1shot/docs/out_one_shot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/csrohit/stm32-uart/HEAD/dma-1shot/docs/out_one_shot.png -------------------------------------------------------------------------------- /dma-1shot/include/stm32f103xb.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/csrohit/stm32-uart/HEAD/dma-1shot/include/stm32f103xb.h -------------------------------------------------------------------------------- /dma-circular/docs/out_echo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/csrohit/stm32-uart/HEAD/dma-circular/docs/out_echo.png -------------------------------------------------------------------------------- /dma-echo/docs/out_one_shot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/csrohit/stm32-uart/HEAD/dma-echo/docs/out_one_shot.png -------------------------------------------------------------------------------- /dma-echo/include/stm32f103xb.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/csrohit/stm32-uart/HEAD/dma-echo/include/stm32f103xb.h -------------------------------------------------------------------------------- /dma-1shot/docs/out_115200_circ.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/csrohit/stm32-uart/HEAD/dma-1shot/docs/out_115200_circ.png -------------------------------------------------------------------------------- /dma-circular/docs/out_one_shot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/csrohit/stm32-uart/HEAD/dma-circular/docs/out_one_shot.png -------------------------------------------------------------------------------- /dma-circular/include/stm32f103xb.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/csrohit/stm32-uart/HEAD/dma-circular/include/stm32f103xb.h -------------------------------------------------------------------------------- /dma-echo/docs/out_115200_circ.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/csrohit/stm32-uart/HEAD/dma-echo/docs/out_115200_circ.png -------------------------------------------------------------------------------- /dma-circular/docs/out_115200_circ.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/csrohit/stm32-uart/HEAD/dma-circular/docs/out_115200_circ.png -------------------------------------------------------------------------------- /dma-echo/.gitignore: -------------------------------------------------------------------------------- 1 | # build files 2 | build 3 | 4 | # vscode files 5 | settings.json 6 | .cortex-debug* 7 | 8 | # draw.io files 9 | *.bkp 10 | *.dtmp 11 | 12 | # mac files 13 | .DS_Store 14 | -------------------------------------------------------------------------------- /dma-1shot/.gitignore: -------------------------------------------------------------------------------- 1 | # build files 2 | build 3 | 4 | # vscode files 5 | settings.json 6 | .cortex-debug* 7 | 8 | # draw.io files 9 | *.bkp 10 | *.dtmp 11 | 12 | # mac files 13 | .DS_Store 14 | -------------------------------------------------------------------------------- /dma-circular/.gitignore: -------------------------------------------------------------------------------- 1 | # build files 2 | build 3 | 4 | # vscode files 5 | settings.json 6 | .cortex-debug* 7 | 8 | # draw.io files 9 | *.bkp 10 | *.dtmp 11 | 12 | # mac files 13 | .DS_Store 14 | -------------------------------------------------------------------------------- /polling/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "files.associations": { 3 | "stdint.h": "c", 4 | "lcd.h": "c", 5 | "string.h": "c", 6 | "stdio.h": "c", 7 | "features.h": "c" 8 | } 9 | } -------------------------------------------------------------------------------- /polling/src/timer.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | 4 | 5 | volatile uint32_t msTicks = 0; 6 | 7 | inline void SysTick_Handler(void) 8 | { 9 | msTicks++; 10 | } 11 | 12 | void delay(uint32_t ms) 13 | { 14 | uint32_t expected_ticks = msTicks + ms; 15 | while (msTicks < expected_ticks) 16 | { 17 | __asm("nop"); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /polling/include/timer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | /** 5 | * @brief Stores number of systick interrupts 6 | * 7 | */ 8 | extern volatile uint32_t msTicks; 9 | 10 | 11 | /** 12 | * @brief Add blocking delay 13 | * 14 | * @param ms delay in milliseconds 15 | */ 16 | void delay(uint32_t ms); 17 | 18 | 19 | /** 20 | * @brief Interrupt handler function 21 | * 22 | */ 23 | void SysTick_Handler(void); -------------------------------------------------------------------------------- /dma-echo/.vscode/c_cpp_properties.json: -------------------------------------------------------------------------------- 1 | { 2 | "configurations": [ 3 | { 4 | "name": "STM32", 5 | "includePath": [ 6 | "${workspaceFolder}/**" 7 | ], 8 | "defines": [ 9 | "STM32F103xB" 10 | ], 11 | "compilerPath": "/Applications/ARM/bin/arm-none-eabi-gcc", 12 | "cStandard": "gnu17", 13 | "cppStandard": "gnu++17", 14 | "intelliSenseMode": "gcc-arm" 15 | } 16 | ], 17 | "version": 4 18 | } -------------------------------------------------------------------------------- /dma-1shot/.vscode/c_cpp_properties.json: -------------------------------------------------------------------------------- 1 | { 2 | "configurations": [ 3 | { 4 | "name": "STM32", 5 | "includePath": [ 6 | "${workspaceFolder}/**" 7 | ], 8 | "defines": [ 9 | "STM32F103xB" 10 | ], 11 | "compilerPath": "/Applications/ARM/bin/arm-none-eabi-gcc", 12 | "cStandard": "gnu17", 13 | "cppStandard": "gnu++17", 14 | "intelliSenseMode": "gcc-arm" 15 | } 16 | ], 17 | "version": 4 18 | } -------------------------------------------------------------------------------- /dma-circular/.vscode/c_cpp_properties.json: -------------------------------------------------------------------------------- 1 | { 2 | "configurations": [ 3 | { 4 | "name": "STM32", 5 | "includePath": [ 6 | "${workspaceFolder}/**" 7 | ], 8 | "defines": [ 9 | "STM32F103xB" 10 | ], 11 | "compilerPath": "/Applications/ARM/bin/arm-none-eabi-gcc", 12 | "cStandard": "gnu17", 13 | "cppStandard": "gnu++17", 14 | "intelliSenseMode": "gcc-arm" 15 | } 16 | ], 17 | "version": 4 18 | } -------------------------------------------------------------------------------- /polling/.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | // See https://go.microsoft.com/fwlink/?LinkId=827846 to learn about workspace recommendations. 3 | // Extension identifier format: ${publisher}.${name}. Example: vscode.csharp 4 | 5 | // List of extensions which should be recommended for users of this workspace. 6 | "recommendations": [ 7 | "marus25.cortex-debug", 8 | "ms-vscode.cpptools", 9 | ], 10 | // List of extensions recommended by VS Code that should not be recommended for users of this workspace. 11 | "unwantedRecommendations": [ 12 | 13 | ] 14 | } -------------------------------------------------------------------------------- /cpp/lib/gpio/gpio.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file gpio.cpp 3 | * @author Rohit Nimkar (nehalnimkar@gmail.com) 4 | * @brief Definitions of non inline functions related to GPIO functionality 5 | * @version 1.2 6 | * @date 2022-12-07 7 | * 8 | * @copyright Copyright (c) 2022 9 | * @attention 10 | * 11 | * This software component is licensed by Rohit Nimkar under BSD 3-Clause license, 12 | * the "License"; You may not use this file except in compliance with the 13 | * License. You may obtain a copy of the License at: opensource.org/licenses/BSD-3-Clause 14 | * 15 | */ 16 | -------------------------------------------------------------------------------- /polling/src/uart.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | 5 | void USART1_putc(char c) 6 | { 7 | // wait for tx data register to be empty 8 | while (!(USART1->SR & USART_SR_TXE)) 9 | ; 10 | USART1->DR = 0x000000ff & c; 11 | } 12 | 13 | void USART1_puts(const char *ch) 14 | { 15 | while (*ch) 16 | { 17 | USART1_putc(*ch); 18 | ch++; 19 | } 20 | } 21 | 22 | void USART1_IRQHandler(void) 23 | { 24 | if (USART1->SR & USART_SR_RXNE) 25 | { 26 | // this clears RXNE flag 27 | USART1_putc(USART1->DR & 0xff); 28 | } 29 | } -------------------------------------------------------------------------------- /cpp/lib/dma/dma.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file dma.cpp 3 | * @author Rohit Nimkar (nehalnimkar@gmail.com) 4 | * @brief Definitions of non inline functions related to DMA 5 | * @version 1.2 6 | * @date 2022-12-07 7 | * 8 | * @copyright Copyright (c) 2022 9 | * @attention 10 | * 11 | * This software component is licensed by Rohit Nimkar under BSD 3-Clause license, 12 | * the "License"; You may not use this file except in compliance with the 13 | * License. You may obtain a copy of the License at: opensource.org/licenses/BSD-3-Clause 14 | * 15 | */ 16 | 17 | #include 18 | 19 | 20 | // DMA *DMA1 = (DMA *)(DMA::DMA1_BASE); -------------------------------------------------------------------------------- /cpp/.vscode/c_cpp_properties.json: -------------------------------------------------------------------------------- 1 | { 2 | "configurations": [ 3 | { 4 | "name": "STM32", 5 | "includePath": [ 6 | "${workspaceFolder}/**", 7 | "${workspaceFolder}/lib/usart", 8 | "${workspaceFolder}/lib/**" 9 | ], 10 | "defines": [ 11 | "STM32F103xB" 12 | ], 13 | "compilerPath": "/Applications/ARM/bin/arm-none-eabi-gcc", 14 | "cStandard": "gnu17", 15 | "cppStandard": "gnu++17", 16 | "intelliSenseMode": "gcc-arm" 17 | } 18 | ], 19 | "version": 4 20 | } -------------------------------------------------------------------------------- /polling/.vscode/c_cpp_properties.json: -------------------------------------------------------------------------------- 1 | { 2 | "configurations": [ 3 | { 4 | "name": "Mac", 5 | "includePath": [ 6 | "${workspaceFolder}/**", 7 | "${workspaceFolder}/include", 8 | "/Applications/ARM/arm-none-eabi/include" 9 | ], 10 | "defines": [ 11 | "STM32F103xB" 12 | ], 13 | "macFrameworkPath": [], 14 | "compilerPath": "/Applications/ARM/bin/arm-none-eabi-gcc", 15 | "cStandard": "gnu17", 16 | "cppStandard": "gnu++14", 17 | "intelliSenseMode": "macos-gcc-arm" 18 | } 19 | ], 20 | "version": 4 21 | } -------------------------------------------------------------------------------- /cpp/lib/dma/dma_channel.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file dma_channel.cpp 3 | * @author Rohit Nimkar (nehalnimkar@gmail.com) 4 | * @brief Definitions of non inline functions related to dma channel 5 | * @version 1.2 6 | * @date 2022-12-07 7 | * 8 | * @copyright Copyright (c) 2022 9 | * @attention 10 | * 11 | * This software component is licensed by Rohit Nimkar under BSD 3-Clause license, 12 | * the "License"; You may not use this file except in compliance with the 13 | * License. You may obtain a copy of the License at: opensource.org/licenses/BSD-3-Clause 14 | * 15 | */ 16 | 17 | #include 18 | 19 | 20 | // DMA_Channel *DMA1_Channel5 = (DMA_Channel *)DMA::AHBPERIPH_BASE + 0x00000058UL; 21 | -------------------------------------------------------------------------------- /cpp/lib/system/system.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file system.cpp 3 | * @author Rohit Nimkar (nehalnimkar@gmail.com) 4 | * @brief Global function definitions 5 | * @version 1.2 6 | * @date 2022-12-07 7 | * 8 | * @copyright Copyright (c) 2022 9 | * @attention 10 | * 11 | * This software component is licensed by Rohit Nimkar under BSD 3-Clause license, 12 | * the "License"; You may not use this file except in compliance with the 13 | * License. You may obtain a copy of the License at: opensource.org/licenses/BSD-3-Clause 14 | * 15 | */ 16 | 17 | 18 | #include 19 | 20 | 21 | uint32_t Core::clock = 8000000U; 22 | volatile uint32_t Core::ms_ticks = 0; 23 | 24 | void SysTick_Handler(void){ 25 | Core::ms_ticks ++; 26 | } 27 | -------------------------------------------------------------------------------- /cpp/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "Cortex Debug", 9 | "cwd": "${workspaceFolder}", 10 | "executable": "./build/blink.elf", 11 | "request": "launch", 12 | "type": "cortex-debug", 13 | "runToEntryPoint": "main", 14 | "servertype": "openocd", 15 | "configFiles": [ 16 | "interface/stlink.cfg", 17 | "target/stm32f1x.cfg" 18 | ], 19 | "svdFile": "${workspaceFolder}/STM32F103.svd" 20 | } 21 | ] 22 | } -------------------------------------------------------------------------------- /polling/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "Cortex Debug", 9 | "cwd": "${workspaceFolder}", 10 | "executable": "./build/blink.elf", 11 | "request": "launch", 12 | "type": "cortex-debug", 13 | "runToEntryPoint": "main", 14 | "servertype": "openocd", 15 | "configFiles": [ 16 | "interface/stlink.cfg", 17 | "target/stm32f1x.cfg" 18 | ], 19 | "svdFile": "${workspaceFolder}/STM32F103.svd" 20 | } 21 | ] 22 | } -------------------------------------------------------------------------------- /dma-1shot/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "Cortex Debug", 9 | "cwd": "${workspaceFolder}", 10 | "executable": "./build/dma-usart.elf", 11 | "request": "launch", 12 | "type": "cortex-debug", 13 | "runToEntryPoint": "main", 14 | "servertype": "openocd", 15 | "configFiles": [ 16 | "interface/stlink.cfg", 17 | "target/stm32f1x.cfg" 18 | ], 19 | "svdFile": "${workspaceFolder}/STM32F103.svd" 20 | } 21 | ] 22 | } -------------------------------------------------------------------------------- /dma-echo/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "Cortex Debug", 9 | "cwd": "${workspaceFolder}", 10 | "executable": "./build/dma-usart.elf", 11 | "request": "launch", 12 | "type": "cortex-debug", 13 | "runToEntryPoint": "main", 14 | "servertype": "openocd", 15 | "configFiles": [ 16 | "interface/stlink.cfg", 17 | "target/stm32f1x.cfg" 18 | ], 19 | "svdFile": "${workspaceFolder}/STM32F103.svd" 20 | } 21 | ] 22 | } -------------------------------------------------------------------------------- /dma-circular/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "Cortex Debug", 9 | "cwd": "${workspaceFolder}", 10 | "executable": "./build/dma-usart.elf", 11 | "request": "launch", 12 | "type": "cortex-debug", 13 | "runToEntryPoint": "main", 14 | "servertype": "openocd", 15 | "configFiles": [ 16 | "interface/stlink.cfg", 17 | "target/stm32f1x.cfg" 18 | ], 19 | "svdFile": "${workspaceFolder}/STM32F103.svd" 20 | } 21 | ] 22 | } -------------------------------------------------------------------------------- /dma-1shot/src/timer.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file timer.c 3 | * @author Rohit Nimkar (nehalnimkar@gmail.com) 4 | * @brief Function definitions related to delay and SysTick timer 5 | * @version 1.2 6 | * @date 2022-12-07 7 | * 8 | * @copyright Copyright (c) 2022 9 | * @attention 10 | * 11 | * This software component is licensed by Rohit Nimkar under BSD 3-Clause license, 12 | * the "License"; You may not use this file except in compliance with the 13 | * License. You may obtain a copy of the License at: opensource.org/licenses/BSD-3-Clause 14 | * 15 | */ 16 | #include 17 | 18 | volatile uint32_t msTicks = 0; 19 | 20 | void SysTick_Handler(void) 21 | { 22 | msTicks++; 23 | } 24 | 25 | void delay(uint32_t ms) 26 | { 27 | uint32_t expected_ticks = msTicks + ms; 28 | while (msTicks < expected_ticks) 29 | { 30 | __asm("nop"); 31 | } 32 | } -------------------------------------------------------------------------------- /dma-echo/src/timer.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file timer.c 3 | * @author Rohit Nimkar (nehalnimkar@gmail.com) 4 | * @brief Function definitions related to delay and SysTick timer 5 | * @version 1.2 6 | * @date 2022-12-07 7 | * 8 | * @copyright Copyright (c) 2022 9 | * @attention 10 | * 11 | * This software component is licensed by Rohit Nimkar under BSD 3-Clause license, 12 | * the "License"; You may not use this file except in compliance with the 13 | * License. You may obtain a copy of the License at: opensource.org/licenses/BSD-3-Clause 14 | * 15 | */ 16 | #include 17 | 18 | volatile uint32_t msTicks = 0; 19 | 20 | void SysTick_Handler(void) 21 | { 22 | msTicks++; 23 | } 24 | 25 | void delay(uint32_t ms) 26 | { 27 | uint32_t expected_ticks = msTicks + ms; 28 | while (msTicks < expected_ticks) 29 | { 30 | __asm("nop"); 31 | } 32 | } -------------------------------------------------------------------------------- /dma-circular/src/timer.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file timer.c 3 | * @author Rohit Nimkar (nehalnimkar@gmail.com) 4 | * @brief Function definitions related to delay and SysTick timer 5 | * @version 1.2 6 | * @date 2022-12-07 7 | * 8 | * @copyright Copyright (c) 2022 9 | * @attention 10 | * 11 | * This software component is licensed by Rohit Nimkar under BSD 3-Clause license, 12 | * the "License"; You may not use this file except in compliance with the 13 | * License. You may obtain a copy of the License at: opensource.org/licenses/BSD-3-Clause 14 | * 15 | */ 16 | #include 17 | 18 | volatile uint32_t msTicks = 0; 19 | 20 | void SysTick_Handler(void) 21 | { 22 | msTicks++; 23 | } 24 | 25 | void delay(uint32_t ms) 26 | { 27 | uint32_t expected_ticks = msTicks + ms; 28 | while (msTicks < expected_ticks) 29 | { 30 | __asm("nop"); 31 | } 32 | } -------------------------------------------------------------------------------- /cpp/lib/dma/dma.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file dma.hpp 3 | * @author Rohit Nimkar (nehalnimkar@gmail.com) 4 | * @brief Declaration of functionality related to dma 5 | * @version 1.2 6 | * @date 2022-12-07 7 | * 8 | * @copyright Copyright (c) 2022 9 | * @attention 10 | * 11 | * This software component is licensed by Rohit Nimkar under BSD 3-Clause license, 12 | * the "License"; You may not use this file except in compliance with the 13 | * License. You may obtain a copy of the License at: opensource.org/licenses/BSD-3-Clause 14 | * 15 | */ 16 | 17 | 18 | #include 19 | #pragma once 20 | class DMA 21 | { 22 | public: 23 | constexpr static uint32_t PeripheralBase = 0x40000000UL; 24 | constexpr static uint32_t AHBBase = PeripheralBase + 0x00020000UL; 25 | constexpr static uint32_t DMA1Base = AHBBase + 0x00000000UL; 26 | 27 | private: 28 | volatile uint32_t ISR; 29 | volatile uint32_t IFCR; 30 | 31 | public: 32 | }; 33 | -------------------------------------------------------------------------------- /cpp/lib/system/system.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file system.hpp 3 | * @author Rohit Nimkar (nehalnimkar@gmail.com) 4 | * @brief Declaration of functionality related to global functions 5 | * @version 1.2 6 | * @date 2022-12-07 7 | * 8 | * @copyright Copyright (c) 2022 9 | * @attention 10 | * 11 | * This software component is licensed by Rohit Nimkar under BSD 3-Clause license, 12 | * the "License"; You may not use this file except in compliance with the 13 | * License. You may obtain a copy of the License at: opensource.org/licenses/BSD-3-Clause 14 | * 15 | */ 16 | 17 | #include 18 | 19 | #pragma once 20 | 21 | namespace Core 22 | { 23 | extern uint32_t clock; 24 | extern volatile uint32_t ms_ticks; 25 | } // namespace Core 26 | 27 | static inline void delay_ms(uint32_t ms) 28 | { 29 | uint64_t final = ms + Core::ms_ticks; 30 | while (Core::ms_ticks < final) 31 | { 32 | __asm("nop"); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /cpp/stm32f1.ld: -------------------------------------------------------------------------------- 1 | ENTRY(Reset_Handler) 2 | 3 | MEMORY 4 | { 5 | FLASH(rx):ORIGIN =0x08000000,LENGTH =64K 6 | SRAM(rwx):ORIGIN =0x20000000,LENGTH =20K 7 | } 8 | 9 | SECTIONS 10 | { 11 | 12 | .isr_vector : 13 | { 14 | *(.isr_vector) 15 | . = ALIGN(4); 16 | }> FLASH 17 | 18 | .text : 19 | { 20 | *(.text) 21 | *(.text.*) 22 | *(.init) 23 | *(.fini) 24 | *(.rodata) 25 | *(.rodata.*) 26 | . = ALIGN(4); 27 | _etext = .; 28 | }> FLASH 29 | 30 | _la_data = LOADADDR(.data); 31 | 32 | .data : 33 | { 34 | _sdata = .; 35 | *(.data) 36 | *(.data.*) 37 | . = ALIGN(4); 38 | _edata = .; 39 | }> SRAM AT> FLASH 40 | 41 | .bss : 42 | { 43 | _sbss = .; 44 | __bss_start__ = _sbss; 45 | *(.bss) 46 | *(.bss.*) 47 | *(COMMON) 48 | . = ALIGN(4); 49 | _ebss = .; 50 | __bss_end__ = _ebss; 51 | . = ALIGN(4); 52 | end = .; 53 | __end__ = .; 54 | }> SRAM 55 | PROVIDE(_stack_top = ORIGIN(SRAM) + LENGTH(SRAM)); 56 | } 57 | -------------------------------------------------------------------------------- /dma-1shot/include/dma.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file dma.h 3 | * @author Rohit Nimkar (nehalnimkar@gmail.com) 4 | * @brief Function declarations and inline function definitions for DMA peripheral 5 | * @version 1.2 6 | * @date 2022-12-07 7 | * 8 | * @copyright Copyright (c) 2022 9 | * @attention 10 | * 11 | * This software component is licensed by Rohit Nimkar under BSD 3-Clause license, 12 | * the "License"; You may not use this file except in compliance with the 13 | * License. You may obtain a copy of the License at: opensource.org/licenses/BSD-3-Clause 14 | * 15 | */ 16 | 17 | #include 18 | 19 | #ifndef __DMA_H__ 20 | #define __DMA_H__ 21 | typedef enum 22 | { 23 | DISABLE, 24 | ENABLE 25 | } dma_channel_cmd_t; 26 | 27 | inline void dma_channel_cmd(DMA_Channel_TypeDef *ch, dma_channel_cmd_t cmd) 28 | { 29 | if(cmd == ENABLE){ 30 | ch->CCR |= DMA_CCR_EN; 31 | }else{ 32 | ch->CCR &= ~DMA_CCR_EN; 33 | } 34 | } 35 | 36 | inline void dma_channel_reload(DMA_Channel_TypeDef *ch, uint32_t new_count){ 37 | ch->CNDTR = new_count; 38 | } 39 | 40 | #endif -------------------------------------------------------------------------------- /cpp/src/main.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file main.cpp 3 | * @author Rohit Nimkar (nehalnimkar@gmail.com) 4 | * @brief Main program body 5 | * @version 1.2 6 | * @date 2022-12-07 7 | * 8 | * @copyright Copyright (c) 2022 9 | * @attention 10 | * 11 | * This software component is licensed by Rohit Nimkar under BSD 3-Clause license, 12 | * the "License"; You may not use this file except in compliance with the 13 | * License. You may obtain a copy of the License at: opensource.org/licenses/BSD-3-Clause 14 | * 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | const char *msg = "Hello World\r\n\0"; 23 | 24 | int main(void) 25 | { 26 | USART &ttl = *new (USART::Usart1) USART; 27 | 28 | ttl.set_baudrate(USART::BR_9600); 29 | ttl.setTransmitterState(USART::Enabled); 30 | ttl.setUsartState(USART::Enabled); 31 | 32 | int ret = SysTick_Config(8000); 33 | if (ret < 0) 34 | while (1) 35 | ; 36 | 37 | while (1) 38 | { 39 | ttl.tx_str(msg); 40 | 41 | delay_ms(2000U); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /cpp/lib/rcc/rcc.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file rcc.hpp 3 | * @author Rohit Nimkar (nehalnimkar@gmail.com) 4 | * @brief Declaration of functionality related to Reset and clock configuration 5 | * @version 1.2 6 | * @date 2022-12-07 7 | * 8 | * @copyright Copyright (c) 2022 9 | * @attention 10 | * 11 | * This software component is licensed by Rohit Nimkar under BSD 3-Clause license, 12 | * the "License"; You may not use this file except in compliance with the 13 | * License. You may obtain a copy of the License at: opensource.org/licenses/BSD-3-Clause 14 | * 15 | */ 16 | 17 | #include 18 | #pragma once 19 | 20 | class RCC 21 | { 22 | private: 23 | volatile uint32_t CR; 24 | volatile uint32_t CFGR; 25 | volatile uint32_t CIR; 26 | volatile uint32_t APB2RSTR; 27 | volatile uint32_t APB1RSTR; 28 | volatile uint32_t AHBENR; 29 | volatile uint32_t APB2ENR; 30 | volatile uint32_t APB1ENR; 31 | volatile uint32_t BDCR; 32 | volatile uint32_t CSR; 33 | public: 34 | RCC(/* args */); 35 | ~RCC(); 36 | }; 37 | 38 | RCC::RCC(/* args */) 39 | { 40 | } 41 | 42 | RCC::~RCC() 43 | { 44 | } 45 | -------------------------------------------------------------------------------- /dma-1shot/include/timer.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file dma.h 3 | * @author Rohit Nimkar (nehalnimkar@gmail.com) 4 | * @brief Function declarations and inline function definitions for timing related functions 5 | * @version 1.2 6 | * @date 2022-12-07 7 | * 8 | * @copyright Copyright (c) 2022 9 | * @attention 10 | * 11 | * This software component is licensed by Rohit Nimkar under BSD 3-Clause license, 12 | * the "License"; You may not use this file except in compliance with the 13 | * License. You may obtain a copy of the License at: opensource.org/licenses/BSD-3-Clause 14 | * 15 | */ 16 | 17 | #include 18 | 19 | #ifndef __TIMER_H__ 20 | #define __TIMER_H__ 21 | 22 | /** 23 | * @brief Stores number of systick interrupts 24 | * 25 | */ 26 | extern volatile uint32_t msTicks; 27 | 28 | /** 29 | * @brief Generate delay in milloseconds 30 | * 31 | * @param ms number of milliseconds 32 | */ 33 | void delay(uint32_t ms); 34 | 35 | /** 36 | * @brief Interrupt handler for systick timer 37 | * should not be made inline as address of this handler is to be placed in the vector table 38 | */ 39 | void SysTick_Handler(void); 40 | 41 | #endif -------------------------------------------------------------------------------- /dma-echo/include/timer.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file dma.h 3 | * @author Rohit Nimkar (nehalnimkar@gmail.com) 4 | * @brief Function declarations and inline function definitions for timing related functions 5 | * @version 1.2 6 | * @date 2022-12-07 7 | * 8 | * @copyright Copyright (c) 2022 9 | * @attention 10 | * 11 | * This software component is licensed by Rohit Nimkar under BSD 3-Clause license, 12 | * the "License"; You may not use this file except in compliance with the 13 | * License. You may obtain a copy of the License at: opensource.org/licenses/BSD-3-Clause 14 | * 15 | */ 16 | 17 | #include 18 | 19 | #ifndef __TIMER_H__ 20 | #define __TIMER_H__ 21 | 22 | /** 23 | * @brief Stores number of systick interrupts 24 | * 25 | */ 26 | extern volatile uint32_t msTicks; 27 | 28 | /** 29 | * @brief Generate delay in milloseconds 30 | * 31 | * @param ms number of milliseconds 32 | */ 33 | void delay(uint32_t ms); 34 | 35 | /** 36 | * @brief Interrupt handler for systick timer 37 | * should not be made inline as address of this handler is to be placed in the vector table 38 | */ 39 | void SysTick_Handler(void); 40 | 41 | #endif -------------------------------------------------------------------------------- /dma-circular/include/timer.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file dma.h 3 | * @author Rohit Nimkar (nehalnimkar@gmail.com) 4 | * @brief Function declarations and inline function definitions for timing related functions 5 | * @version 1.2 6 | * @date 2022-12-07 7 | * 8 | * @copyright Copyright (c) 2022 9 | * @attention 10 | * 11 | * This software component is licensed by Rohit Nimkar under BSD 3-Clause license, 12 | * the "License"; You may not use this file except in compliance with the 13 | * License. You may obtain a copy of the License at: opensource.org/licenses/BSD-3-Clause 14 | * 15 | */ 16 | 17 | #include 18 | 19 | #ifndef __TIMER_H__ 20 | #define __TIMER_H__ 21 | 22 | /** 23 | * @brief Stores number of systick interrupts 24 | * 25 | */ 26 | extern volatile uint32_t msTicks; 27 | 28 | /** 29 | * @brief Generate delay in milloseconds 30 | * 31 | * @param ms number of milliseconds 32 | */ 33 | void delay(uint32_t ms); 34 | 35 | /** 36 | * @brief Interrupt handler for systick timer 37 | * should not be made inline as address of this handler is to be placed in the vector table 38 | */ 39 | void SysTick_Handler(void); 40 | 41 | #endif -------------------------------------------------------------------------------- /polling/src/main.c: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file : main.c 4 | * @author : Rohit Nimkar 5 | * @brief : Main program body 6 | ****************************************************************************** 7 | * @attention 8 | * 9 | * This software component is licensed by Rohit Nimkar under BSD 3-Clause license, 10 | * the "License"; You may not use this file except in compliance with the 11 | * License. You may obtain a copy of the License at: 12 | * opensource.org/licenses/BSD-3-Clause 13 | * 14 | ****************************************************************************** 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | #include 22 | #include 23 | 24 | char msg[28]; 25 | 26 | int main(void) 27 | { 28 | USART1_init(9600U); 29 | 30 | int ret = SysTick_Config(SystemCoreClock/1000); 31 | if (ret < 0) 32 | while (1) 33 | ; 34 | 35 | while (1) 36 | { 37 | sprintf(msg, "Time elapsed: %lu ms\r\n", msTicks); 38 | USART1_puts(msg); 39 | delay(5000U); 40 | } 41 | 42 | 43 | } 44 | -------------------------------------------------------------------------------- /polling/include/uart.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | /** 4 | * @brief Initialize USART1 peripheral 5 | * 6 | * @param baudrate baudrate to be configurate 7 | */ 8 | static inline void USART1_init(uint32_t baudrate) 9 | { 10 | // enable clock for GPIOA and USART1 11 | RCC->APB2ENR |= RCC_APB2ENR_USART1EN | RCC_APB2ENR_IOPAEN; 12 | 13 | // reset pin configurations for PA9 and PA10 14 | GPIOA->CRH &= ~(GPIO_CRH_MODE10 | GPIO_CRH_MODE9 | GPIO_CRH_CNF10 | GPIO_CRH_CNF9); 15 | 16 | // PA9 as Output@50Hz Alternate function 17 | GPIOA->CRH |= GPIO_CRH_MODE9_0 | GPIO_CRH_MODE9_1 | GPIO_CRH_CNF9_1; 18 | 19 | // PA10 as floating input 20 | GPIOA->CRH |= GPIO_CRH_CNF10_0; 21 | 22 | uint32_t baud = (uint32_t)(SystemCoreClock / baudrate); 23 | 24 | USART1->BRR = baud; 25 | 26 | // transmitter enable, receiver enable, receiver interrupt enable and USART enable 27 | USART1->CR1 = USART_CR1_TE | USART_CR1_RE | USART_CR1_RXNEIE | USART_CR1_UE; 28 | 29 | // enable USART1 interrupt 30 | NVIC_EnableIRQ(USART1_IRQn); 31 | } 32 | 33 | /** 34 | * @brief Transmit 1 character 35 | * 36 | * @param c character to be transmitted 37 | */ 38 | void USART1_putch(char c); 39 | 40 | /** 41 | * @brief Transmit string 42 | * 43 | * @param str pointer to the string 44 | */ 45 | void USART1_puts(const char *str); 46 | 47 | /** 48 | * @brief Interrupt service routine for USART1 related interrupts 49 | * 50 | */ 51 | void USART1_IRQHandler(void); -------------------------------------------------------------------------------- /dma-1shot/stm32f1.ld: -------------------------------------------------------------------------------- 1 | /** 2 | * @file stm32f1.ld 3 | * @author Rohit Nimkar (nehalnimkar@gmail.com) 4 | * @brief Linker script for stm32f103c8t6 micro-controller 5 | * @version 1.2 6 | * @date 2022-12-07 7 | * 8 | * @copyright Copyright (c) 2022 9 | * @attention 10 | * 11 | * This software component is licensed by Rohit Nimkar under BSD 3-Clause license, 12 | * the "License"; You may not use this file except in compliance with the 13 | * License. You may obtain a copy of the License at: opensource.org/licenses/BSD-3-Clause 14 | * 15 | */ 16 | 17 | ENTRY(Reset_Handler) 18 | 19 | MEMORY 20 | { 21 | FLASH(rx):ORIGIN =0x08000000,LENGTH =64K 22 | SRAM(rwx):ORIGIN =0x20000000,LENGTH =20K 23 | } 24 | 25 | SECTIONS 26 | { 27 | 28 | .isr_vector : 29 | { 30 | KEEP(*(.isr_vector)); 31 | . = ALIGN(4); 32 | }> FLASH 33 | 34 | .text : 35 | { 36 | *(.text) 37 | *(.text.*) 38 | *(.init) 39 | *(.fini) 40 | *(.rodata) 41 | *(.rodata.*) 42 | . = ALIGN(4); 43 | _etext = .; 44 | }> FLASH 45 | 46 | _la_data = LOADADDR(.data); 47 | 48 | .data : 49 | { 50 | _sdata = .; 51 | *(.data) 52 | *(.data.*) 53 | . = ALIGN(4); 54 | _edata = .; 55 | }> SRAM AT> FLASH 56 | 57 | .bss : 58 | { 59 | _sbss = .; 60 | __bss_start__ = _sbss; 61 | *(.bss) 62 | *(.bss.*) 63 | *(COMMON) 64 | . = ALIGN(4); 65 | _ebss = .; 66 | __bss_end__ = _ebss; 67 | . = ALIGN(4); 68 | end = .; 69 | __end__ = .; 70 | }> SRAM 71 | PROVIDE(_stack_top = ORIGIN(SRAM) + LENGTH(SRAM)); 72 | } 73 | -------------------------------------------------------------------------------- /dma-echo/stm32f1.ld: -------------------------------------------------------------------------------- 1 | /** 2 | * @file stm32f1.ld 3 | * @author Rohit Nimkar (nehalnimkar@gmail.com) 4 | * @brief Linker script for stm32f103c8t6 micro-controller 5 | * @version 1.2 6 | * @date 2022-12-07 7 | * 8 | * @copyright Copyright (c) 2022 9 | * @attention 10 | * 11 | * This software component is licensed by Rohit Nimkar under BSD 3-Clause license, 12 | * the "License"; You may not use this file except in compliance with the 13 | * License. You may obtain a copy of the License at: opensource.org/licenses/BSD-3-Clause 14 | * 15 | */ 16 | 17 | ENTRY(Reset_Handler) 18 | 19 | MEMORY 20 | { 21 | FLASH(rx):ORIGIN =0x08000000,LENGTH =64K 22 | SRAM(rwx):ORIGIN =0x20000000,LENGTH =20K 23 | } 24 | 25 | SECTIONS 26 | { 27 | 28 | .isr_vector : 29 | { 30 | KEEP(*(.isr_vector)); 31 | . = ALIGN(4); 32 | }> FLASH 33 | 34 | .text : 35 | { 36 | *(.text) 37 | *(.text.*) 38 | *(.init) 39 | *(.fini) 40 | *(.rodata) 41 | *(.rodata.*) 42 | . = ALIGN(4); 43 | _etext = .; 44 | }> FLASH 45 | 46 | _la_data = LOADADDR(.data); 47 | 48 | .data : 49 | { 50 | _sdata = .; 51 | *(.data) 52 | *(.data.*) 53 | . = ALIGN(4); 54 | _edata = .; 55 | }> SRAM AT> FLASH 56 | 57 | .bss : 58 | { 59 | _sbss = .; 60 | __bss_start__ = _sbss; 61 | *(.bss) 62 | *(.bss.*) 63 | *(COMMON) 64 | . = ALIGN(4); 65 | _ebss = .; 66 | __bss_end__ = _ebss; 67 | . = ALIGN(4); 68 | end = .; 69 | __end__ = .; 70 | }> SRAM 71 | PROVIDE(_stack_top = ORIGIN(SRAM) + LENGTH(SRAM)); 72 | } 73 | -------------------------------------------------------------------------------- /dma-circular/stm32f1.ld: -------------------------------------------------------------------------------- 1 | /** 2 | * @file stm32f1.ld 3 | * @author Rohit Nimkar (nehalnimkar@gmail.com) 4 | * @brief Linker script for stm32f103c8t6 micro-controller 5 | * @version 1.2 6 | * @date 2022-12-07 7 | * 8 | * @copyright Copyright (c) 2022 9 | * @attention 10 | * 11 | * This software component is licensed by Rohit Nimkar under BSD 3-Clause license, 12 | * the "License"; You may not use this file except in compliance with the 13 | * License. You may obtain a copy of the License at: opensource.org/licenses/BSD-3-Clause 14 | * 15 | */ 16 | 17 | ENTRY(Reset_Handler) 18 | 19 | MEMORY 20 | { 21 | FLASH(rx):ORIGIN =0x08000000,LENGTH =64K 22 | SRAM(rwx):ORIGIN =0x20000000,LENGTH =20K 23 | } 24 | 25 | SECTIONS 26 | { 27 | 28 | .isr_vector : 29 | { 30 | KEEP(*(.isr_vector)); 31 | . = ALIGN(4); 32 | }> FLASH 33 | 34 | .text : 35 | { 36 | *(.text) 37 | *(.text.*) 38 | *(.init) 39 | *(.fini) 40 | *(.rodata) 41 | *(.rodata.*) 42 | . = ALIGN(4); 43 | _etext = .; 44 | }> FLASH 45 | 46 | _la_data = LOADADDR(.data); 47 | 48 | .data : 49 | { 50 | _sdata = .; 51 | *(.data) 52 | *(.data.*) 53 | . = ALIGN(4); 54 | _edata = .; 55 | }> SRAM AT> FLASH 56 | 57 | .bss : 58 | { 59 | _sbss = .; 60 | __bss_start__ = _sbss; 61 | *(.bss) 62 | *(.bss.*) 63 | *(COMMON) 64 | . = ALIGN(4); 65 | _ebss = .; 66 | __bss_end__ = _ebss; 67 | . = ALIGN(4); 68 | end = .; 69 | __end__ = .; 70 | }> SRAM 71 | PROVIDE(_stack_top = ORIGIN(SRAM) + LENGTH(SRAM)); 72 | } 73 | -------------------------------------------------------------------------------- /docs/uart.drawio: -------------------------------------------------------------------------------- 1 | 7VlNc+smFP01WjojkGTHS38kr51J53kad5quOsTCMlNZuAg/y/31BQksISTLcfyxePEiERe4wDmHqwtyvMk6+8bQZvUbDXHsQDfMHG/qQOgPofgrDfvC4AXKEDESFiZQGl7Jf1gZXWXdkhCnRkNOaczJxjQuaJLgBTdsiDG6M5staWyOukERtgyvCxTb1j9JyFeF9REOSvsvmEQrPTLoD4uaNdKN1UrSFQrprmLynhxvwijlxdM6m+BYYqdxKfo9t9QeJsZwwk/psPz17e/vb/OX4XQbRoizINj3esAr3PxA8VatWM2W7zUEEaPbjWqGGcdZE/DoXTd37YmBw3KFTDBdY872ooly9Kh6aIUMVHlX4u1rr6sq1tqIFMfRwXUJg3hQSHwElUE3KgKUJMTSC3C88W5FOH7doIWs3YmdIGwrvo5V9ZImXGkb6PKExpTlvjw3/wl7yhn9B+uahCZYNiZxXDO1slFF/QjhrVz0oElGzx88BDYdfhMdwaHp5Qmx+BjLJ+jOiOz8GWpCwoR8CU1kLU55DXDBDnhHAEOLnZy3/tPo2eZzmf+uwlOFBdC0KfrX2hN9i4LZaGhBL9bJTXxPlTSKSSQ5iPFSepCYERGGR8q8JmEoB2mksyTctcl4zn/mJhxecw8NzS0E7HDWGM2uRZwdy2YjPdgXc8eYg3bkuylzjxZz35Lwi7hu4vw7b7kTkiqchCOZnorSIkZpShYmhya+OCP8rfL8l3x+GASqOM0qddO9LiRiLW/VQtENBrpc9stLumMxWRxamXEtoxMLolu2wN0vbo5YhI/xCzvfdkEDgdrGcIw4+WFOt4lVNcKMErGQg3qgW5NPPbEslql6VVPsuqOgJZXVjgocLEe5yA7LPl93/pm6S8W8+KflCM+T4+BLjjUVgZocg3Pl2K+HxdvKMbh4GGyRUJeCmvV6XK4XVB08UXUtx+TbqA74pliCc4MgqL+MbxwEAeyW3bWvNOo7r+lO47bHNxuUP17Hvfn8xcLmYxcb5lEZB8B3GxLCw4HYOkKPobr6aGWjOzdsidb6SgPcGfqhBf3vmYX6z5HFH2cKGHvm3udm7bjC2/yLt27e7n1qBvZl4c97bP4Icfc+NYMTji/pCm3k4zLGmUocxxc50tQgb2NGZ5Lgjpnk8Utht5Gyy+SIfv2gXH9nnpoj+o/3PZkA+zbbgf2YK+bzHFCT3/93Kz/RjcvvNBVTRZvaKB300lxKI9EAgE2WNy079SP5f/5d1M4melyxjmLootZSvtTPC3rHsaliHYwWQkuYHQtHDItJqZxWynIjwc3hDsZOMHU6v1IdNkFrPDolcT6y9dtTOPcBeIFnvmY+p2jTi+5Al8sUf1Bxolh+xC2al1/Cvaf/AQ== -------------------------------------------------------------------------------- /polling/Makefile: -------------------------------------------------------------------------------- 1 | TARGET := uart 2 | # debug build?Release 3 | BUILD_TYPE = Debug 4 | BUILD_DIR:= build 5 | 6 | TRIPLE = arm-none-eabi 7 | CC = ${TRIPLE}-gcc 8 | LD = ${TRIPLE}-ld 9 | AS = ${TRIPLE}-as 10 | GDB = ${TRIPLE}-gdb 11 | OBJCOPY = ${TRIPLE}-objcopy 12 | 13 | INCFLAGS := -Iinclude 14 | CFLAGS := -mcpu=cortex-m3 -mfloat-abi=soft -mthumb --specs=nano.specs $(INCFLAGS) -std=gnu11 -Os -Wall -fstack-usage -fdata-sections -ffunction-sections -DSTM32F103xB 15 | ASFLAGS := -mcpu=cortex-m3 -mfloat-abi=soft -mthumb --specs=nano.specs $(INCFLAGS) -x assembler-with-cpp 16 | LDFLAGS := -mcpu=cortex-m3 -mfloat-abi=soft -mthumb --specs=nosys.specs $(INCFLAGS) 17 | 18 | # add debug flags if build type is debug 19 | ifeq ($(BUILD_TYPE), Debug) 20 | CFLAGS += -g -gdwarf-2 21 | endif 22 | 23 | # Generate dependency information 24 | CFLAGS += -MMD -MP 25 | ASLAGS += -MMD -MP 26 | 27 | SRC_DIR := src 28 | SRCS := $(shell find $(SRC_DIR) -name '*.c') 29 | OBJS := $(BUILD_DIR)/$(SRC_DIR)/startup_stm32f103c8tx.o $(SRCS:%.c=$(BUILD_DIR)/%.o) 30 | 31 | $(BUILD_DIR)/$(TARGET).elf: $(OBJS) STM32F103C8TX_FLASH.ld 32 | $(CC) $(LDFLAGS) -o $@ $(OBJS) -T"STM32F103C8TX_FLASH.ld" -Wl,-Map="$(BUILD_DIR)/$(TARGET).map" -Wl,--gc-sections -static -Wl,--start-group -lc -lm -Wl,--end-group 33 | 34 | $(BUILD_DIR)/%.o: %.c 35 | @mkdir -p $(dir $@) 36 | @$(CC) $(CFLAGS) -c $< -o $@ 37 | @echo "CC " $< " ==> " $@ 38 | 39 | $(BUILD_DIR)/%.o: %.s 40 | @mkdir -p $(dir $@) 41 | @$(CC) $(ASFLAGS) -c $< -o $@ 42 | @echo "AS " $< " ==> " $@ 43 | 44 | flash: 45 | openocd -d2 -f interface/stlink.cfg -c "transport select hla_swd" -f target/stm32f1x.cfg -c "program {$(BUILD_DIR)/$(TARGET).elf} verify reset; shutdown;" 46 | 47 | all: $(BUILD_DIR)/$(TARGET).elf 48 | 49 | clean: 50 | rm -rf $(BUILD_DIR) 51 | -------------------------------------------------------------------------------- /cpp/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 | -------------------------------------------------------------------------------- /polling/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 | -------------------------------------------------------------------------------- /dma-1shot/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 | -------------------------------------------------------------------------------- /dma-circular/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 | -------------------------------------------------------------------------------- /dma-echo/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 | -------------------------------------------------------------------------------- /dma-1shot/include/main.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file main.h 3 | * @author Rohit Nimkar (nehalnimkar@gmail.com) 4 | * @brief Header file for the functions used in the main.c source file 5 | * @version 1.2 6 | * @date 2022-12-07 7 | * 8 | * @copyright Copyright (c) 2022 9 | * @attention 10 | * 11 | * This software component is licensed by Rohit Nimkar under BSD 3-Clause license, 12 | * the "License"; You may not use this file except in compliance with the 13 | * License. You may obtain a copy of the License at: opensource.org/licenses/BSD-3-Clause 14 | * 15 | */ 16 | 17 | #ifndef __MAIN_H__ 18 | 19 | #define __MAIN_H__ 20 | int main(void); 21 | 22 | /** 23 | * @brief enable clock for dma1 peripheral registers 24 | */ 25 | void dma1_clock_enable(void); 26 | /** 27 | * @brief Configure DMA1 channel 4 to work with USART1 transmitter 28 | * It reads from memory and writes to USART data register 29 | */ 30 | void dma_usart_tx_init(void); 31 | 32 | /** 33 | * @brief Configure DMA1 channel 5 to work with USART1 receiver 34 | * It reads from USART data register and writes to memory 35 | */ 36 | void dma_usart_rx_init(void); 37 | 38 | /** 39 | * @brief Enable DMA to accept request for channel 4 40 | */ 41 | void dma_usart_tx_enable(void); 42 | 43 | /** 44 | * @brief Disable DMA to accept request for Channel 4 45 | * 46 | */ 47 | void dma_usart_tx_disable(void); 48 | 49 | /** 50 | * @brief Enable DMA to accept request for channel 5 51 | */ 52 | void dma_usart_rx_enable(void); 53 | 54 | /** 55 | * @brief Disable DMA to accept request for Channel 5 56 | * 57 | */ 58 | void dma_usart_rx_disable(void); 59 | 60 | /** 61 | * @brief Configure USART1 on PA9 and PA10 62 | * Enable Transmitter with DMA 63 | */ 64 | void usart1_init(void); 65 | 66 | /** 67 | * @brief Enable USART1 prescalers and output 68 | */ 69 | void usart1_enable(void); 70 | 71 | /** 72 | * @brief Interrupt handler for DMA channel 4 73 | * 74 | */ 75 | void DMA1_Channel4_IRQHandler(void); 76 | 77 | /** 78 | * @brief Interrupt handler for DMA channel 4 79 | * 80 | */ 81 | void DMA1_Channel5_IRQHandler(void); 82 | 83 | #endif -------------------------------------------------------------------------------- /dma-echo/include/main.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file main.h 3 | * @author Rohit Nimkar (nehalnimkar@gmail.com) 4 | * @brief Header file for the functions used in the main.c source file 5 | * @version 1.2 6 | * @date 2022-12-07 7 | * 8 | * @copyright Copyright (c) 2022 9 | * @attention 10 | * 11 | * This software component is licensed by Rohit Nimkar under BSD 3-Clause license, 12 | * the "License"; You may not use this file except in compliance with the 13 | * License. You may obtain a copy of the License at: opensource.org/licenses/BSD-3-Clause 14 | * 15 | */ 16 | 17 | #ifndef __MAIN_H__ 18 | 19 | #define __MAIN_H__ 20 | int main(void); 21 | 22 | /** 23 | * @brief enable clock for dma1 peripheral registers 24 | */ 25 | void dma1_clock_enable(void); 26 | /** 27 | * @brief Configure DMA1 channel 4 to work with USART1 transmitter 28 | * It reads from memory and writes to USART data register 29 | */ 30 | void dma_usart_tx_init(void); 31 | 32 | /** 33 | * @brief Configure DMA1 channel 5 to work with USART1 receiver 34 | * It reads from USART data register and writes to memory 35 | */ 36 | void dma_usart_rx_init(void); 37 | 38 | /** 39 | * @brief Enable DMA to accept request for channel 4 40 | */ 41 | void dma_usart_tx_enable(void); 42 | 43 | /** 44 | * @brief Disable DMA to accept request for Channel 4 45 | * 46 | */ 47 | void dma_usart_tx_disable(void); 48 | 49 | /** 50 | * @brief Enable DMA to accept request for channel 5 51 | */ 52 | void dma_usart_rx_enable(void); 53 | 54 | /** 55 | * @brief Disable DMA to accept request for Channel 5 56 | * 57 | */ 58 | void dma_usart_rx_disable(void); 59 | 60 | /** 61 | * @brief Configure USART1 on PA9 and PA10 62 | * Enable Transmitter with DMA 63 | */ 64 | void usart1_init(void); 65 | 66 | /** 67 | * @brief Enable USART1 prescalers and output 68 | */ 69 | void usart1_enable(void); 70 | 71 | /** 72 | * @brief Interrupt handler for DMA channel 4 73 | * 74 | */ 75 | void DMA1_Channel4_IRQHandler(void); 76 | 77 | /** 78 | * @brief Interrupt handler for DMA channel 4 79 | * 80 | */ 81 | void DMA1_Channel5_IRQHandler(void); 82 | 83 | #endif -------------------------------------------------------------------------------- /dma-circular/include/main.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file main.h 3 | * @author Rohit Nimkar (nehalnimkar@gmail.com) 4 | * @brief Header file for the functions used in the main.c source file 5 | * @version 1.2 6 | * @date 2022-12-07 7 | * 8 | * @copyright Copyright (c) 2022 9 | * @attention 10 | * 11 | * This software component is licensed by Rohit Nimkar under BSD 3-Clause license, 12 | * the "License"; You may not use this file except in compliance with the 13 | * License. You may obtain a copy of the License at: opensource.org/licenses/BSD-3-Clause 14 | * 15 | */ 16 | 17 | #ifndef __MAIN_H__ 18 | 19 | #define __MAIN_H__ 20 | int main(void); 21 | 22 | /** 23 | * @brief enable clock for dma1 peripheral registers 24 | */ 25 | void dma1_clock_enable(void); 26 | /** 27 | * @brief Configure DMA1 channel 4 to work with USART1 transmitter 28 | * It reads from memory and writes to USART data register 29 | */ 30 | void dma_usart_tx_init(void); 31 | 32 | /** 33 | * @brief Configure DMA1 channel 5 to work with USART1 receiver 34 | * It reads from USART data register and writes to memory 35 | */ 36 | void dma_usart_rx_init(void); 37 | 38 | /** 39 | * @brief Enable DMA to accept request for channel 4 40 | */ 41 | void dma_usart_tx_enable(void); 42 | 43 | /** 44 | * @brief Disable DMA to accept request for Channel 4 45 | * 46 | */ 47 | void dma_usart_tx_disable(void); 48 | 49 | /** 50 | * @brief Enable DMA to accept request for channel 5 51 | */ 52 | void dma_usart_rx_enable(void); 53 | 54 | /** 55 | * @brief Disable DMA to accept request for Channel 5 56 | * 57 | */ 58 | void dma_usart_rx_disable(void); 59 | 60 | /** 61 | * @brief Configure USART1 on PA9 and PA10 62 | * Enable Transmitter with DMA 63 | */ 64 | void usart1_init(void); 65 | 66 | /** 67 | * @brief Enable USART1 prescalers and output 68 | */ 69 | void usart1_enable(void); 70 | 71 | /** 72 | * @brief Interrupt handler for DMA channel 4 73 | * 74 | */ 75 | void DMA1_Channel4_IRQHandler(void); 76 | 77 | /** 78 | * @brief Interrupt handler for DMA channel 4 79 | * 80 | */ 81 | void DMA1_Channel5_IRQHandler(void); 82 | 83 | #endif -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Blue Pill UART communication 2 | 3 | ![Build Passing](https://img.shields.io/badge/build-passing-brightgreen) [![GPLv3 License](https://img.shields.io/badge/License-GPL%20v3-yellow.svg)](https://opensource.org/licenses/) 4 | 5 | Programming the UART1 peripheral in STM32F1 controller for bi-directional communication. Echo characters received from UART and transmit time elapsed since boot every 5 seconds. 6 | 7 | ## Project Variant 8 | 9 | STM32F1 Blue pill is a versatile board and can be programmed in various ways. I have created following variations of this project which differs in programming language, use of RTOS and framework. Clone the repository and follow steps mentioned in the respective variations for building and flashing. 10 | 11 | 1. [Polling](polling) 12 | 2. [DMA in Circular Mode](dma-circular) 13 | 3. [DMA in 1 Shot Mode](dma-1shot) 14 | 4. [DMA in Echo Mode](dma-echo) 15 | 5. [C++ project](cpp) 16 | 17 | ## USART 18 | 19 | The controller has 3 USART peropherals with varying functionality. The peripheral registers can be accessed as half word (16 bit) as well as words (32 bit).\ 20 | This project uses USART1 with pinc PA9 and PA10 for demonstration. 21 | 22 | ## Hardware Setup 23 | 24 | Connect the board with host through USB to TTL converter (FTDI board in our case). The connections are described as follows. 25 | 26 | | Pin on Blue Pill | Pin on FTDI | 27 | |------------------ |------------- | 28 | | PA9 | Rx | 29 | | PA10 | Tx | 30 | | Gnd | Gnd | 31 | 32 | ![Connection diagram for USART1](https://github.com/csrohit/bluepill-uart/blob/main/docs/label.png "Pin connection diagram for usart1") 33 | 34 | ## Output 35 | 36 | The application prints time elapsed since boot in interval of 5 seconds. Configure serial onitor on host for 9600 baudrate to be able to read and write to blue pill using uart. Following output can be observed on UART.\ 37 | ![Output on Serial monitor](https://github.com/csrohit/bluepill-uart/blob/main/docs/output.jpg "Serial messages printed on monitor") 38 | 39 | ## Debug 40 | 41 | Click in `Run and Debug` option in VsCode sidebar. Then launch `Cortex Debug` target. 42 | 43 | Happy debugging.... 44 | -------------------------------------------------------------------------------- /cpp/include/system_stm32f1xx.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file system_stm32f10x.h 4 | * @author MCD Application Team 5 | * @brief CMSIS Cortex-M3 Device Peripheral Access Layer System Header File. 6 | ****************************************************************************** 7 | * @attention 8 | * 9 | *

© Copyright (c) 2017 STMicroelectronics. 10 | * All rights reserved.

11 | * 12 | * This software component is licensed by ST under BSD 3-Clause license, 13 | * the "License"; You may not use this file except in compliance with the 14 | * License. You may obtain a copy of the License at: 15 | * opensource.org/licenses/BSD-3-Clause 16 | * 17 | ****************************************************************************** 18 | */ 19 | 20 | /** @addtogroup CMSIS 21 | * @{ 22 | */ 23 | 24 | /** @addtogroup stm32f10x_system 25 | * @{ 26 | */ 27 | 28 | /** 29 | * @brief Define to prevent recursive inclusion 30 | */ 31 | #ifndef __SYSTEM_STM32F10X_H 32 | #define __SYSTEM_STM32F10X_H 33 | 34 | #ifdef __cplusplus 35 | extern "C" { 36 | #endif 37 | 38 | /** @addtogroup STM32F10x_System_Includes 39 | * @{ 40 | */ 41 | 42 | /** 43 | * @} 44 | */ 45 | 46 | 47 | /** @addtogroup STM32F10x_System_Exported_types 48 | * @{ 49 | */ 50 | 51 | extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */ 52 | extern const uint8_t AHBPrescTable[16U]; /*!< AHB prescalers table values */ 53 | extern const uint8_t APBPrescTable[8U]; /*!< APB prescalers table values */ 54 | 55 | /** 56 | * @} 57 | */ 58 | 59 | /** @addtogroup STM32F10x_System_Exported_Constants 60 | * @{ 61 | */ 62 | 63 | /** 64 | * @} 65 | */ 66 | 67 | /** @addtogroup STM32F10x_System_Exported_Macros 68 | * @{ 69 | */ 70 | 71 | /** 72 | * @} 73 | */ 74 | 75 | /** @addtogroup STM32F10x_System_Exported_Functions 76 | * @{ 77 | */ 78 | 79 | extern void SystemInit(void); 80 | extern void SystemCoreClockUpdate(void); 81 | /** 82 | * @} 83 | */ 84 | 85 | #ifdef __cplusplus 86 | } 87 | #endif 88 | 89 | #endif /*__SYSTEM_STM32F10X_H */ 90 | 91 | /** 92 | * @} 93 | */ 94 | 95 | /** 96 | * @} 97 | */ 98 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 99 | -------------------------------------------------------------------------------- /dma-1shot/include/system_stm32f1xx.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file system_stm32f10x.h 4 | * @author MCD Application Team 5 | * @brief CMSIS Cortex-M3 Device Peripheral Access Layer System Header File. 6 | ****************************************************************************** 7 | * @attention 8 | * 9 | *

© Copyright (c) 2017 STMicroelectronics. 10 | * All rights reserved.

11 | * 12 | * This software component is licensed by ST under BSD 3-Clause license, 13 | * the "License"; You may not use this file except in compliance with the 14 | * License. You may obtain a copy of the License at: 15 | * opensource.org/licenses/BSD-3-Clause 16 | * 17 | ****************************************************************************** 18 | */ 19 | 20 | /** @addtogroup CMSIS 21 | * @{ 22 | */ 23 | 24 | /** @addtogroup stm32f10x_system 25 | * @{ 26 | */ 27 | 28 | /** 29 | * @brief Define to prevent recursive inclusion 30 | */ 31 | #ifndef __SYSTEM_STM32F10X_H 32 | #define __SYSTEM_STM32F10X_H 33 | 34 | #ifdef __cplusplus 35 | extern "C" { 36 | #endif 37 | 38 | /** @addtogroup STM32F10x_System_Includes 39 | * @{ 40 | */ 41 | 42 | /** 43 | * @} 44 | */ 45 | 46 | 47 | /** @addtogroup STM32F10x_System_Exported_types 48 | * @{ 49 | */ 50 | 51 | extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */ 52 | extern const uint8_t AHBPrescTable[16U]; /*!< AHB prescalers table values */ 53 | extern const uint8_t APBPrescTable[8U]; /*!< APB prescalers table values */ 54 | 55 | /** 56 | * @} 57 | */ 58 | 59 | /** @addtogroup STM32F10x_System_Exported_Constants 60 | * @{ 61 | */ 62 | 63 | /** 64 | * @} 65 | */ 66 | 67 | /** @addtogroup STM32F10x_System_Exported_Macros 68 | * @{ 69 | */ 70 | 71 | /** 72 | * @} 73 | */ 74 | 75 | /** @addtogroup STM32F10x_System_Exported_Functions 76 | * @{ 77 | */ 78 | 79 | extern void SystemInit(void); 80 | extern void SystemCoreClockUpdate(void); 81 | /** 82 | * @} 83 | */ 84 | 85 | #ifdef __cplusplus 86 | } 87 | #endif 88 | 89 | #endif /*__SYSTEM_STM32F10X_H */ 90 | 91 | /** 92 | * @} 93 | */ 94 | 95 | /** 96 | * @} 97 | */ 98 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 99 | -------------------------------------------------------------------------------- /dma-echo/include/system_stm32f1xx.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file system_stm32f10x.h 4 | * @author MCD Application Team 5 | * @brief CMSIS Cortex-M3 Device Peripheral Access Layer System Header File. 6 | ****************************************************************************** 7 | * @attention 8 | * 9 | *

© Copyright (c) 2017 STMicroelectronics. 10 | * All rights reserved.

11 | * 12 | * This software component is licensed by ST under BSD 3-Clause license, 13 | * the "License"; You may not use this file except in compliance with the 14 | * License. You may obtain a copy of the License at: 15 | * opensource.org/licenses/BSD-3-Clause 16 | * 17 | ****************************************************************************** 18 | */ 19 | 20 | /** @addtogroup CMSIS 21 | * @{ 22 | */ 23 | 24 | /** @addtogroup stm32f10x_system 25 | * @{ 26 | */ 27 | 28 | /** 29 | * @brief Define to prevent recursive inclusion 30 | */ 31 | #ifndef __SYSTEM_STM32F10X_H 32 | #define __SYSTEM_STM32F10X_H 33 | 34 | #ifdef __cplusplus 35 | extern "C" { 36 | #endif 37 | 38 | /** @addtogroup STM32F10x_System_Includes 39 | * @{ 40 | */ 41 | 42 | /** 43 | * @} 44 | */ 45 | 46 | 47 | /** @addtogroup STM32F10x_System_Exported_types 48 | * @{ 49 | */ 50 | 51 | extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */ 52 | extern const uint8_t AHBPrescTable[16U]; /*!< AHB prescalers table values */ 53 | extern const uint8_t APBPrescTable[8U]; /*!< APB prescalers table values */ 54 | 55 | /** 56 | * @} 57 | */ 58 | 59 | /** @addtogroup STM32F10x_System_Exported_Constants 60 | * @{ 61 | */ 62 | 63 | /** 64 | * @} 65 | */ 66 | 67 | /** @addtogroup STM32F10x_System_Exported_Macros 68 | * @{ 69 | */ 70 | 71 | /** 72 | * @} 73 | */ 74 | 75 | /** @addtogroup STM32F10x_System_Exported_Functions 76 | * @{ 77 | */ 78 | 79 | extern void SystemInit(void); 80 | extern void SystemCoreClockUpdate(void); 81 | /** 82 | * @} 83 | */ 84 | 85 | #ifdef __cplusplus 86 | } 87 | #endif 88 | 89 | #endif /*__SYSTEM_STM32F10X_H */ 90 | 91 | /** 92 | * @} 93 | */ 94 | 95 | /** 96 | * @} 97 | */ 98 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 99 | -------------------------------------------------------------------------------- /polling/include/system_stm32f1xx.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file system_stm32f10x.h 4 | * @author MCD Application Team 5 | * @brief CMSIS Cortex-M3 Device Peripheral Access Layer System Header File. 6 | ****************************************************************************** 7 | * @attention 8 | * 9 | *

© Copyright (c) 2017 STMicroelectronics. 10 | * All rights reserved.

11 | * 12 | * This software component is licensed by ST under BSD 3-Clause license, 13 | * the "License"; You may not use this file except in compliance with the 14 | * License. You may obtain a copy of the License at: 15 | * opensource.org/licenses/BSD-3-Clause 16 | * 17 | ****************************************************************************** 18 | */ 19 | 20 | /** @addtogroup CMSIS 21 | * @{ 22 | */ 23 | 24 | /** @addtogroup stm32f10x_system 25 | * @{ 26 | */ 27 | 28 | /** 29 | * @brief Define to prevent recursive inclusion 30 | */ 31 | #ifndef __SYSTEM_STM32F10X_H 32 | #define __SYSTEM_STM32F10X_H 33 | 34 | #ifdef __cplusplus 35 | extern "C" { 36 | #endif 37 | 38 | /** @addtogroup STM32F10x_System_Includes 39 | * @{ 40 | */ 41 | 42 | /** 43 | * @} 44 | */ 45 | 46 | 47 | /** @addtogroup STM32F10x_System_Exported_types 48 | * @{ 49 | */ 50 | 51 | extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */ 52 | extern const uint8_t AHBPrescTable[16U]; /*!< AHB prescalers table values */ 53 | extern const uint8_t APBPrescTable[8U]; /*!< APB prescalers table values */ 54 | 55 | /** 56 | * @} 57 | */ 58 | 59 | /** @addtogroup STM32F10x_System_Exported_Constants 60 | * @{ 61 | */ 62 | 63 | /** 64 | * @} 65 | */ 66 | 67 | /** @addtogroup STM32F10x_System_Exported_Macros 68 | * @{ 69 | */ 70 | 71 | /** 72 | * @} 73 | */ 74 | 75 | /** @addtogroup STM32F10x_System_Exported_Functions 76 | * @{ 77 | */ 78 | 79 | extern void SystemInit(void); 80 | extern void SystemCoreClockUpdate(void); 81 | /** 82 | * @} 83 | */ 84 | 85 | #ifdef __cplusplus 86 | } 87 | #endif 88 | 89 | #endif /*__SYSTEM_STM32F10X_H */ 90 | 91 | /** 92 | * @} 93 | */ 94 | 95 | /** 96 | * @} 97 | */ 98 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 99 | -------------------------------------------------------------------------------- /dma-circular/include/system_stm32f1xx.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file system_stm32f10x.h 4 | * @author MCD Application Team 5 | * @brief CMSIS Cortex-M3 Device Peripheral Access Layer System Header File. 6 | ****************************************************************************** 7 | * @attention 8 | * 9 | *

© Copyright (c) 2017 STMicroelectronics. 10 | * All rights reserved.

11 | * 12 | * This software component is licensed by ST under BSD 3-Clause license, 13 | * the "License"; You may not use this file except in compliance with the 14 | * License. You may obtain a copy of the License at: 15 | * opensource.org/licenses/BSD-3-Clause 16 | * 17 | ****************************************************************************** 18 | */ 19 | 20 | /** @addtogroup CMSIS 21 | * @{ 22 | */ 23 | 24 | /** @addtogroup stm32f10x_system 25 | * @{ 26 | */ 27 | 28 | /** 29 | * @brief Define to prevent recursive inclusion 30 | */ 31 | #ifndef __SYSTEM_STM32F10X_H 32 | #define __SYSTEM_STM32F10X_H 33 | 34 | #ifdef __cplusplus 35 | extern "C" { 36 | #endif 37 | 38 | /** @addtogroup STM32F10x_System_Includes 39 | * @{ 40 | */ 41 | 42 | /** 43 | * @} 44 | */ 45 | 46 | 47 | /** @addtogroup STM32F10x_System_Exported_types 48 | * @{ 49 | */ 50 | 51 | extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */ 52 | extern const uint8_t AHBPrescTable[16U]; /*!< AHB prescalers table values */ 53 | extern const uint8_t APBPrescTable[8U]; /*!< APB prescalers table values */ 54 | 55 | /** 56 | * @} 57 | */ 58 | 59 | /** @addtogroup STM32F10x_System_Exported_Constants 60 | * @{ 61 | */ 62 | 63 | /** 64 | * @} 65 | */ 66 | 67 | /** @addtogroup STM32F10x_System_Exported_Macros 68 | * @{ 69 | */ 70 | 71 | /** 72 | * @} 73 | */ 74 | 75 | /** @addtogroup STM32F10x_System_Exported_Functions 76 | * @{ 77 | */ 78 | 79 | extern void SystemInit(void); 80 | extern void SystemCoreClockUpdate(void); 81 | /** 82 | * @} 83 | */ 84 | 85 | #ifdef __cplusplus 86 | } 87 | #endif 88 | 89 | #endif /*__SYSTEM_STM32F10X_H */ 90 | 91 | /** 92 | * @} 93 | */ 94 | 95 | /** 96 | * @} 97 | */ 98 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 99 | -------------------------------------------------------------------------------- /dma-circular/src/main.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file main.c 3 | * @author Rohit Nimkar (nehalnimkar@gmail.com) 4 | * @brief Main program body 5 | * @version 1.2 6 | * @date 2022-12-07 7 | * 8 | * @copyright Copyright (c) 2022 9 | * @attention 10 | * 11 | * This software component is licensed by Rohit Nimkar under BSD 3-Clause license, 12 | * the "License"; You may not use this file except in compliance with the 13 | * License. You may obtain a copy of the License at: opensource.org/licenses/BSD-3-Clause 14 | * 15 | */ 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | const char * msg = "Hello world\r\n\0"; 23 | 24 | void dma1_clock_enable(void) 25 | { 26 | RCC->AHBENR |= RCC_AHBENR_DMA1EN; 27 | } 28 | 29 | void dma_usart_tx_init(void) 30 | { 31 | // USART TX is mapped to DMA1 channel 4 32 | // set peripheral address to USART data register 33 | DMA1_Channel4->CPAR = (uint32_t)&USART1->DR; 34 | 35 | // set memory address to address of string 36 | DMA1_Channel4->CMAR = (uint32_t)msg; 37 | 38 | // set number od dma transactions 39 | DMA1_Channel4->CNDTR = 13; 40 | 41 | // set priprity to lowest value 42 | DMA1_Channel4->CCR &= ~(DMA_CCR_PL_0 | DMA_CCR_PL_1); 43 | 44 | // set data transfer direction - memory -> peripheral 45 | DMA1_Channel4->CCR |= DMA_CCR_DIR; 46 | 47 | // set memory address size to 8 bits (Address is incremented by this much) 48 | DMA1_Channel4->CCR &= ~(DMA_CCR_MSIZE_0 | DMA_CCR_MSIZE_0); 49 | 50 | // set peripheral size to 8 bits (Has no effect as this is not incremented) 51 | DMA1_Channel4->CCR &= ~(DMA_CCR_PSIZE_0 | DMA_CCR_PSIZE_0); 52 | 53 | // set memory address incement by 1byte 54 | DMA1_Channel4->CCR |= DMA_CCR_MINC; 55 | 56 | // disable increment mode on peripheral address 57 | DMA1_Channel4->CCR &= ~DMA_CCR_PINC; 58 | 59 | // enable circular mode 60 | DMA1_Channel4->CCR |= DMA_CCR_CIRC; 61 | 62 | // enable interrpt after full transfer 63 | DMA1_Channel4->CCR |= DMA_CCR_TCIE; 64 | } 65 | 66 | void dma_usart_tx_enable(void) 67 | { 68 | DMA1_Channel4->CCR |= DMA_CCR_EN; 69 | } 70 | 71 | void usart1_init(void) 72 | { 73 | // enable clock for GPIOA and USART1 74 | RCC->APB2ENR |= RCC_APB2ENR_USART1EN | RCC_APB2ENR_IOPAEN; 75 | 76 | // reset pin configurations for PA9 and PA10 77 | GPIOA->CRH &= ~(GPIO_CRH_MODE10 | GPIO_CRH_MODE9 | GPIO_CRH_CNF10 | GPIO_CRH_CNF9); 78 | 79 | // PA9 as Output@50Hz Alternate function 80 | GPIOA->CRH |= GPIO_CRH_MODE9_0 | GPIO_CRH_MODE9_1 | GPIO_CRH_CNF9_1; 81 | 82 | // PA10 as floating input 83 | GPIOA->CRH |= GPIO_CRH_CNF10_0; 84 | 85 | // set baud rate as 9600 86 | uint32_t baud = (uint32_t)(SystemCoreClock / 115200); 87 | USART1->BRR = baud; 88 | 89 | // Enable transmitter 90 | USART1->CR1 |= USART_CR1_TE; 91 | 92 | // Enable DMA mode for transmitter 93 | USART1->CR3 |= USART_CR3_DMAT; 94 | } 95 | 96 | void usart1_enable(void) 97 | { 98 | USART1->CR1 |= USART_CR1_UE; 99 | } 100 | 101 | int main(void) 102 | { 103 | dma1_clock_enable(); 104 | usart1_init(); 105 | dma_usart_tx_init(); 106 | dma_usart_tx_enable(); 107 | usart1_enable(); 108 | while (1); 109 | } -------------------------------------------------------------------------------- /docs/flow.drawio: -------------------------------------------------------------------------------- 1 | 7V1bd6M4Ev41fmwddEeP6XS6d/YyO5t0n+nelzkEE5sd27gx7sT761eEi0GSjYzBkF47D7EKIUD11adSqYQn+Hb58in21vN/RNNgMUHO9GWCP0wQgoxx+S+V7HIJEjiTzOJwmsv2gofwv0EudHLpNpwGm1rFJIoWSbiuC/1otQr8pCbz4jh6rld7ihb1q669WaAJHnxvoUt/D6fJPJO6iO/lfwnC2by4MmQiO7L0isr5k2zm3jR6rojw3QTfxlGUZN+WL7fBIu29ol+y8z4eOFreWBysEpsTtji5/9dcfPnb98ePn/75V/zxCX9+B3Nt/PAW2/yJ87tNdkUXxNF2NQ3SVuAEv3+eh0nwsPb89Oiz1LqUzZPlIj+8SeLoz7KrUCm5jRZRLCWraCVPfP8ULhaKyIv9XP1clvLbCuIkeDn4wLDsRgnAIFoGSbyTVfITaNHzOfYQy8vPe0VC5ObCeUWLjORCL0fPrGx838HyS97HJ/Q3sujvmezw9cHnz4HuPRbVnVP7hQla7xeu94vApm5BHXTLDXon/vg+T/x/76a734Pv/vx2/Q5qvfL+5ov853wKVkHsJRInZ6GyCrcJwk9PT8j3NWzKI1P2yCgz4vgpWiUP+fUdWZaKSLxQ3l5efj2eARi6JYKrajmOCFXVB/WH3TquTbBmBvV1AWqj9pCmvS93neprSgN3Skz6ctEjZiPXF0G6gkys05t+dM75/CLLD/PwKZH/42AWbpLgamJ7lUHabGL8kiqkugrvP1xtbM+JuK4wSKmuMWjQGO1LY9xsdH60XC+CRIo+6uqbR8vH7aaFrQXsgK1x8eg441YdZHV3BBroEhKD6mBv7ojQB7SHm/vPf/yykjQZb9dJt1RJ07+8yyvy7GNSK3v9jFutqpeCqUGtFx0GC/OvmuRtt5p0/cBsiI8uJXSshlgYnnF+dFENGUhTtuSkX9OSA6+cmU3ZcJ0zCbEc7kph95MA3bruv/56d9WeITDBndFpT5+Ba8oKVtObNKImS/7C22xCv66jPXOmvRm8hMnX/Ej6/VsqBzQvfXipVPuwKwor+Sxfq4XKWWlxf9prqTivWddn6nYTbWM/sGCuxItnQWJhJsG0FnfUsVLBAj3it8bBwkvCH/VopQke+RV+i8JVUokFIQgcSBmq8wnFDAjKqJzlYAGxQ+vtZt2RN1UNOSqtU4GAK5wTW8/6UGtdYs/bVaqt0wobDfllF55hDHpAo+67y/OvnqD9YOXU6Y66Q3uCiHTOdiVz7cnqW42rzMxVsOSeGb9VONPMksOzHbIkOzgqrsOcApWKIBU1KiKkHdPJIRwIeYFa40LSXNomJtxFzHG5Fc91xWJYd8i6Ajk8bXguQX6CK9A7yBvBi43gtfEFBgW5KwBzFSC6BFRgyERLkGOMgIOhakIIAVhr/rIw1wfrnrgcNsB8eF62dULN0B4KskhC1iUqeUJBQQannJ7dlqBlDtAdXCihXHJ+itzLYpZdqfkSOIfjmmzBdLKleQlyEgYK5kyhjtrhHAoIiDbVggyDCsrlfM8K6JebaxFTUPaX6/Lx5ODSFsL69OmisydiMeL62/hHqa0LBI5k4bcgDuUDlgp6u8EkIg64no2EJwaltzTao3qHBGFAqvTWMpRk9GsJx7UZlp3neZjcDjwXqxsgJs7RW9Xq84b64mh9+SW74255V1/j1Ix4M/fW6deULZsodxrGgZ+E0UqWpU5TuP1cQXuoZhMasuaMuYS9pYRYzO/PoOHTabBNLKtt3OxENTd7ivwA5TaS9aCUS1SqEQrabOkVSe9RZW7iAlaJjfXCrURdCnOOc6VWX016VuvT0+pjeFp9JM6sTy7A9a6ePXZ/TQA8yvZMWbMwpUaY7Lo3p9vVQwb313wyo+oUEzbmk5nS2/vLJ3P1vBZNWf8vMcoCyI1DcsFaIwnecMQBVCcgXQUpueBgTAFKYeFbtgVsuwDlKdGANwRy6KBxoZxSgCEiIv+ooco0ll5Z0FScQlu4uxQDXl5DCH7SVQaPWQp9Q8V9x9n4bzST9ICXPnw2vjC4T19/vbsGmqtpiYrPO3igWVi4TdcYVUWDfGwxqnJ407KCr1xZjIXqdGX4LHzHYpPyOQs8Z7qCbytXrlBv2xDkYIlEDHA53ym8NF730XCaUlRZelGat573uEBPD5aXBbQy97Gb+pwaeVQip6RhkUapThvilOJo9X7CfNCxSGvtwm7b5pi8MbtFloY7spR+AR3gVD6wF8OFGKhLvdyFoJpKe25a/4G5o7oC0GC4av0my3XJIKaru7r31y0H7acySs6MccuBuKxT5TaT83XPQbN71EzH44qoQUwAoVrWNHV5FzyMHAI40/dvIcny1bQbKyrujs0skkvaJYW9Lcwia9/fGZfzjzgDRM/JljgD1TWJluHfA62Xa67dw9Ssxt4IecRJ2FqCS3dop5Zg54MiW090QaITKsYsdX/VtvGFiNioOos4zs+3itcjwoVtOlm2/jearDD1tQHW+7exAzTPRTbfYvd2V5DuceduHdK8EdNpSU06vzxoG7FIhk0KV6bT5Ubvk/e3UEfbvYuoAEc27/YMRT2rToPiCLZBjJFGB/UAOM0i2zSPj+E6VyIJqcpe1rZvvjiwB6DraBhXr0OPR7e0+g3RM46P1j87GmYEUn+7I091W8ZA8YPZidsRc3MugBD7pSRW53Cehqv3/vdl3Qmr9x5JxRXqjeJkHs2ilbe420sVtO3r/D2K1jkg/xMkyS4HhbdNojpcD2DqkqRsu8UsU5AOSmu0nfX+bIuMkB5WplErovhJpvXENog1rKOJmL4ihREClezc1q+9wEALVrVzPU/eeqisI6OG4R26Z9ZnFxjeLRZCerBhDM8y4rceuRg0IEFdZgiNHY8jWHsXBAJoeKsCr4eq1X3HXfnf6ub8Jv+bnFn/EgZqfD0aWyQ5cCfpsnSxHMy+b9MfMJEIxvz1rypis/T/4+5dCqFoHqanrsLln15ctCfvL2syq6oRQRK8JCZXyeLnRBbhLE309IPVqzW/T1ePQ99b3OQHluF0+uq9mRbMrfbCagZ81s+VQDVs55oyAU0bl7DimFt4W7K4/+WZDDf7H/DBd/8D -------------------------------------------------------------------------------- /dma-1shot/src/main.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file main.c 3 | * @author Rohit Nimkar (nehalnimkar@gmail.com) 4 | * @brief Main program body 5 | * @version 1.2 6 | * @date 2022-12-07 7 | * 8 | * @copyright Copyright (c) 2022 9 | * @attention 10 | * 11 | * This software component is licensed by Rohit Nimkar under BSD 3-Clause license, 12 | * the "License"; You may not use this file except in compliance with the 13 | * License. You may obtain a copy of the License at: opensource.org/licenses/BSD-3-Clause 14 | * 15 | */ 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | const char *msg = "Hello world\r\n\0"; 23 | 24 | void dma1_clock_enable(void) 25 | { 26 | RCC->AHBENR |= RCC_AHBENR_DMA1EN; 27 | } 28 | 29 | void dma_usart_tx_init(void) 30 | { 31 | // USART TX is mapped to DMA1 channel 4 32 | // set peripheral address to USART data register 33 | DMA1_Channel4->CPAR = (uint32_t)&USART1->DR; 34 | 35 | // set memory address to address of string 36 | DMA1_Channel4->CMAR = (uint32_t)msg; 37 | 38 | // set number od dma transactions 39 | DMA1_Channel4->CNDTR = 13; 40 | 41 | // set memory address incement by 1byte 42 | DMA1_Channel4->CCR |= DMA_CCR_MINC; 43 | 44 | // enable circular mode 45 | // DMA1_Channel4->CCR |= DMA_CCR_CIRC; 46 | 47 | // set data transfer direction - memory -> peripheral 48 | DMA1_Channel4->CCR |= DMA_CCR_DIR; 49 | 50 | // enable transmission complete interrupt 51 | DMA1_Channel4->CCR |= DMA_CCR_TCIE; 52 | } 53 | 54 | void dma_usart_tx_enable(void) 55 | { 56 | DMA1_Channel4->CCR |= DMA_CCR_EN; 57 | } 58 | 59 | void dma_usart_tx_disable(void) 60 | { 61 | DMA1_Channel4->CCR &= ~DMA_CCR_EN; 62 | } 63 | 64 | void DMA1_Channel4_IRQHandler(void) 65 | { 66 | if (DMA1->ISR & DMA_ISR_TCIF4) 67 | { 68 | // clear interrupt flasg 69 | DMA1->IFCR |= DMA_IFCR_CGIF4; 70 | dma_usart_tx_disable(); 71 | } 72 | } 73 | 74 | void usart1_init(void) 75 | { 76 | // enable clock for GPIOA and USART1 77 | RCC->APB2ENR |= RCC_APB2ENR_USART1EN | RCC_APB2ENR_IOPAEN; 78 | 79 | // reset pin configurations for PA9 and PA10 80 | GPIOA->CRH &= ~(GPIO_CRH_MODE10 | GPIO_CRH_MODE9 | GPIO_CRH_CNF10 | GPIO_CRH_CNF9); 81 | 82 | // PA9 as Output@50Hz Alternate function 83 | GPIOA->CRH |= GPIO_CRH_MODE9_0 | GPIO_CRH_MODE9_1 | GPIO_CRH_CNF9_1; 84 | 85 | // PA10 as floating input 86 | GPIOA->CRH |= GPIO_CRH_CNF10_0; 87 | 88 | // set baud rate as 9600 89 | uint32_t baud = (uint32_t)(SystemCoreClock / 115200); 90 | USART1->BRR = baud; 91 | 92 | // Enable transmitter 93 | USART1->CR1 |= USART_CR1_TE; 94 | 95 | // Enable DMA mode for transmitter 96 | USART1->CR3 |= USART_CR3_DMAT; 97 | } 98 | 99 | void usart1_enable(void) 100 | { 101 | USART1->CR1 |= USART_CR1_UE; 102 | } 103 | 104 | int main(void) 105 | { 106 | SysTick_Config(SystemCoreClock/1000); 107 | 108 | dma1_clock_enable(); 109 | usart1_init(); 110 | dma_usart_tx_init(); 111 | dma_usart_tx_enable(); 112 | usart1_enable(); 113 | 114 | // enable interrupt for channel 4 115 | NVIC_EnableIRQ(DMA1_Channel4_IRQn); 116 | 117 | dma_usart_tx_enable(); 118 | 119 | usart1_enable(); 120 | 121 | while (1) 122 | { 123 | delay(2000); 124 | 125 | // reload no. of transactions 126 | DMA1_Channel4->CNDTR = 13; 127 | dma_usart_tx_enable(); 128 | } 129 | } -------------------------------------------------------------------------------- /cpp/Makefile: -------------------------------------------------------------------------------- 1 | TARGET = cpp-usart 2 | 3 | 4 | # Configure micro-controller 5 | MCU_FAMILY = STM32F103xB 6 | LDSCRIPT = stm32f1.ld 7 | CPU = cortex-m3 8 | INSTR_SET = thumb 9 | FLOAT_ABI = soft 10 | 11 | # compiler option 12 | OPT := -Os 13 | CSTD ?= c11 14 | CXXSTD := c++17 15 | 16 | # Project specific configuration 17 | BUILD_DIR := build 18 | BUILD_TYPE ?= Release 19 | SRC_DIR := src lib/system 20 | INC_DIRS = include lib/usart lib/system 21 | 22 | 23 | PREFIX ?= arm-none-eabi 24 | CC := $(PREFIX)-gcc 25 | CXX := $(PREFIX)-g++ 26 | LD := $(PREFIX)-gcc 27 | AR := $(PREFIX)-ar 28 | AS := $(PREFIX)-as 29 | SIZE := $(PREFIX)-size 30 | OBJCOPY := $(PREFIX)-objcopy 31 | OBJDUMP := $(PREFIX)-objdump 32 | GDB := $(PREFIX)-gdb 33 | 34 | # collect source files and generate object files 35 | SRCS := $(shell find $(SRC_DIR) -name '*.cpp' -or -name '*.c') 36 | OBJS := $(addsuffix .o,$(basename $(SRCS))) # replace .c with .o 37 | OBJS := $(addprefix $(BUILD_DIR)/,$(OBJS)) # replace .c with .o 38 | ASMS = $(addsuffix .s,$(basename $(OBJS))) # replace .c with .o 39 | 40 | 41 | # Define stm32 family macro 42 | DEFS += -D$(MCU_FAMILY) 43 | 44 | # header library include flsgs 45 | INC_FLAGS = $(addprefix -I,$(INC_DIRS)) 46 | 47 | 48 | # Target-specific flags 49 | CPU_FLAGS ?= -mfloat-abi=$(FLOAT_ABI) -m$(INSTR_SET) -mcpu=$(CPU) 50 | CPPFLAGS ?=$(DEFS) $(INC_FLAGS) -MMD 51 | 52 | ifeq ($(BUILD_TYPE), Debug) 53 | CFLAGS += -g -gdwarf-2 54 | CXXFLAGS += -g -gdwarf-2 55 | LDFLAGS += -g -gdwarf-2 56 | 57 | else 58 | CFLAGS += $(OPT) 59 | CXXFLAGS += $(OPT) 60 | ASFLAGS += $(OPT) 61 | endif 62 | 63 | # Do not link stdlib with executable 64 | CFLAGS += -nostdlib -fno-tree-loop-distribute-patterns -fdata-sections -ffunction-sections 65 | CXXFLAGS += -nostdlib -fno-tree-loop-distribute-patterns -fdata-sections -ffunction-sections -fno-exceptions -fno-rtti 66 | LDFLAGS += -nostdlib -fno-tree-loop-distribute-patterns 67 | 68 | 69 | # Warning options for C and CXX compiler 70 | CFLAGS += -Wall -Wextra -Wundef -Wshadow -Wredundant-decls -Wmissing-prototypes -Wstrict-prototypes 71 | CXXFLAGS += -Wall -Wextra -Wundef -Wshadow -Wredundant-decls -Werror 72 | 73 | # -Weffc++ 74 | 75 | LDFLAGS += -T $(LDSCRIPT) 76 | LDFLAGS += -Wl,-Map=$(basename $@).map,--gc-sections,-cref,--print-memory-usage 77 | 78 | all : size bin list 79 | size : $(BUILD_DIR)/$(TARGET).size 80 | elf : $(BUILD_DIR)/$(TARGET).elf 81 | bin : $(BUILD_DIR)/$(TARGET).bin 82 | hex : $(BUILD_DIR)/$(TARGET).hex 83 | srec : $(BUILD_DIR)/$(TARGET).srec 84 | list : $(BUILD_DIR)/$(TARGET).list 85 | 86 | asm : $(ASMS) 87 | 88 | # binary file to flash on target 89 | %.bin: %.elf 90 | @echo "COPY " $< " => " $@ 91 | @$(OBJCOPY) -Obinary $(*).elf $(*).bin 92 | 93 | # executable object files for debugging 94 | %.hex: %.elf 95 | $(OBJCOPY) -Oihex $(*).elf $(*).hex 96 | 97 | %.srec: %.elf 98 | $(OBJCOPY) -Osrec $(*).elf $(*).srec 99 | 100 | %.list: %.elf 101 | $(OBJDUMP) -S $(*).elf > $(*).list 102 | 103 | %.size: %.elf 104 | @echo "Section wise usage: " 105 | @$(SIZE) $< 106 | 107 | $(BUILD_DIR)/%.s:%.cpp 108 | @mkdir -p $(dir $@) 109 | @echo "AS" $< " ==> " $@ 110 | @$(CXX) $(CPU_FLAGS) $(CPPFLAGS) $(CXXLAGS) -o $@ -S $< 111 | 112 | $(BUILD_DIR)/%.o:%.c 113 | @mkdir -p $(dir $@) 114 | @echo "CC" $< " ==> " $@ 115 | @$(CC) $(CPU_FLAGS) $(CPPFLAGS) $(CFLAGS) -o $@ -c $< 116 | 117 | $(BUILD_DIR)/%.o:%.cpp 118 | @mkdir -p $(dir $@) 119 | @echo "CXX" $< " ==> " $@ 120 | @$(CXX) $(CPU_FLAGS) $(CPPFLAGS) $(CXXFLAGS) -o $@ -c $< 121 | 122 | $(BUILD_DIR)/$(TARGET).elf: $(OBJS) 123 | @echo "Linking sources into "$@ 124 | @$(CC) $(CPU_FLAGS) $(LDFLAGS) -o $@ $^ 125 | 126 | 127 | flash: bin 128 | st-flash write $(BUILD_DIR)/$(TARGET).bin 0x8000000 129 | 130 | clean: 131 | rm -rf build 132 | 133 | 134 | -include $(OBJS:%.o=%.d) 135 | -------------------------------------------------------------------------------- /dma-echo/src/startup_stm32f1.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file startup_stm32f1.c 3 | * @author Rohit Nimkar (nehalnimkar@gmail.com) 4 | * @brief startup declarations and function for the STM32F1 series controllers 5 | * See: RM0008 10.1.2 Interrupt and exception vectors, Table 63. Vector table for other STM32F10xxx devices 6 | * 7 | * @version 1.2 8 | * @date 2022-12-07 9 | * 10 | * @copyright Copyright (c) 2022 11 | * @attention 12 | * 13 | * This software component is licensed by Rohit Nimkar under BSD 3-Clause license, 14 | * the "License"; You may not use this file except in compliance with the 15 | * License. You may obtain a copy of the License at: opensource.org/licenses/BSD-3-Clause 16 | * 17 | */ 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | // Define the vector table 25 | uint32_t vectors[] __attribute__((section(".isr_vector"))) = { 26 | (uint32_t)&_stack_top, 27 | (uint32_t)Reset_Handler, 28 | (uint32_t)NMI_Handler, 29 | (uint32_t)HardFault_Handler, 30 | (uint32_t)MemManage_Handler, 31 | (uint32_t)BusFault_Handler, 32 | (uint32_t)UsageFault_Handler, 33 | 0, // reserved 34 | 0, // reserved 35 | 0, // reserved 36 | 0, // reserved 37 | (uint32_t)SVC_Handler, 38 | (uint32_t)DebugMon_Handler, 39 | 0, // reserved 40 | (uint32_t)PendSV_Handler, 41 | (uint32_t)SysTick_Handler, 42 | (uint32_t)WWDG_IRQHandler, 43 | (uint32_t)PVD_IRQHandler, 44 | (uint32_t)TAMP_STAMP_IRQHandler, 45 | (uint32_t)RTC_WKUP_IRQHandler, 46 | 0, // Flash global interrupt 47 | (uint32_t)RCC_IRQHandler, 48 | (uint32_t)EXTI0_IRQHandler, 49 | (uint32_t)EXTI1_IRQHandler, 50 | (uint32_t)EXTI2_IRQHandler, 51 | (uint32_t)EXTI3_IRQHandler, 52 | (uint32_t)EXTI4_IRQHandler, 53 | (uint32_t)DMA1_Channel1_IRQHandler, 54 | (uint32_t)DMA1_Channel2_IRQHandler, 55 | (uint32_t)DMA1_Channel3_IRQHandler, 56 | (uint32_t)DMA1_Channel4_IRQHandler, 57 | (uint32_t)DMA1_Channel5_IRQHandler, 58 | (uint32_t)DMA1_Channel6_IRQHandler, 59 | (uint32_t)DMA1_Channel7_IRQHandler, 60 | (uint32_t)ADC_IRQHandler, 61 | (uint32_t)USB_HP_CAN_TX_IRQHandler, 62 | (uint32_t)USB_LP_CAN_RX0_IRQHandler, 63 | (uint32_t)CAN_RX1_IRQHandler, 64 | (uint32_t)CAN_SCE_IRQHandler, 65 | (uint32_t)EXTI9_5_IRQHandler, 66 | (uint32_t)TIM1_BRK_IRQHandler, 67 | (uint32_t)TIM1_UP_IRQHandler, 68 | (uint32_t)TIM1_TRG_COM_IRQHandler, 69 | (uint32_t)TIM1_CC_IRQHandler, 70 | (uint32_t)TIM2_IRQHandler, 71 | (uint32_t)TIM3_IRQHandler, 72 | (uint32_t)TIM4_IRQHandler, 73 | (uint32_t)I2C1_EV_IRQHandler, 74 | (uint32_t)I2C1_ER_IRQHandler, 75 | (uint32_t)I2C2_EV_IRQHandler, 76 | (uint32_t)I2C2_ER_IRQHandler, 77 | (uint32_t)SPI1_IRQHandler, 78 | (uint32_t)SPI2_IRQHandler, 79 | (uint32_t)USART1_IRQHandler, 80 | (uint32_t)USART2_IRQHandler, 81 | (uint32_t)USART3_IRQHandler, 82 | (uint32_t)EXTI15_10_IRQHandler, 83 | (uint32_t)RTC_Alarm_IRQHandler, 84 | (uint32_t)USB_Wakeup_IRQHandler 85 | }; 86 | 87 | 88 | void Default_Handler(void) 89 | { 90 | while (1) 91 | ; 92 | } 93 | 94 | 95 | void __attribute__((noreturn)) Reset_Handler(void) 96 | { 97 | // copy .data section to SRAM 98 | uint32_t *start_sram = (uint32_t *)&_sdata; 99 | uint32_t *start_flash = (uint32_t *)&_la_data; 100 | while (start_sram < (uint32_t *)&_edata) 101 | { 102 | *start_sram++ = *start_flash++; 103 | } 104 | 105 | // copy .bss section to SRAM 106 | uint32_t *start_bss = (uint32_t *)&_sbss; 107 | while (start_bss < (uint32_t *)&_ebss) 108 | { 109 | *start_bss++ = 0; 110 | } 111 | 112 | // set value of SystemCoreClock variable 113 | SystemCoreClockUpdate(); 114 | 115 | // Call main function 116 | main(); 117 | 118 | // loop continuously 119 | while (1) 120 | { 121 | __asm("nop"); 122 | } 123 | 124 | } -------------------------------------------------------------------------------- /dma-1shot/Makefile: -------------------------------------------------------------------------------- 1 | TARGET = dma-usart 2 | 3 | 4 | # Configure micro-controller 5 | MCU_FAMILY = STM32F103xB 6 | LDSCRIPT = stm32f1.ld 7 | CPU = cortex-m3 8 | INSTR_SET = thumb 9 | FLOAT_ABI = soft 10 | 11 | # compiler option 12 | OPT := -Os 13 | CSTD ?= gnu11 14 | CXXSTD := gnu++17 15 | 16 | # Project specific configuration 17 | BUILD_DIR := build 18 | BUILD_TYPE ?= Debug 19 | SRC_DIR := src 20 | INC_DIRS := include 21 | 22 | 23 | PREFIX ?= arm-none-eabi 24 | CC := $(PREFIX)-gcc 25 | CXX := $(PREFIX)-g++ 26 | LD := $(PREFIX)-gcc 27 | AR := $(PREFIX)-ar 28 | AS := $(PREFIX)-as 29 | SIZE := $(PREFIX)-size 30 | OBJCOPY := $(PREFIX)-objcopy 31 | OBJDUMP := $(PREFIX)-objdump 32 | GDB := $(PREFIX)-gdb 33 | 34 | # collect source files and generate object files 35 | SRCS := $(shell find $(SRC_DIR) -name '*.cpp' -or -name '*.c') 36 | OBJS := $(addsuffix .o,$(basename $(SRCS))) # replace .c with .o 37 | OBJS := $(addprefix $(BUILD_DIR)/,$(OBJS)) # replace .c with .o 38 | ASMS := $(addsuffix .s,$(basename $(OBJS))) 39 | 40 | # Define stm32 family macro 41 | DEFS +=-D$(MCU_FAMILY) 42 | 43 | # header library include flsgs 44 | INC_FLAGS =$(addprefix -I,$(INC_DIRS)) 45 | 46 | 47 | # Target-specific flags 48 | CPU_FLAGS ?=-mfloat-abi=$(FLOAT_ABI) -m$(INSTR_SET) -mcpu=$(CPU) 49 | CPPFLAGS ?=$(DEFS) $(INC_FLAGS) -MMD 50 | 51 | # optiomization level according to build type 52 | ifeq ($(BUILD_TYPE), Debug) 53 | CFLAGS += -g -gdwarf-2 54 | CXXFLAGS += -g -gdwarf-2 55 | LDFLAGS += -g -gdwarf-2 56 | else 57 | CFLAGS += $(OPT) 58 | CXXFLAGS += $(OPT) 59 | ASFLAGS += $(OPT) 60 | endif 61 | 62 | # Do not link stdlib with executable 63 | CFLAGS += -nostdlib -fno-tree-loop-distribute-patterns -fdata-sections -ffunction-sections 64 | CXXFLAGS += -nostdlib -fno-tree-loop-distribute-patterns -fdata-sections -ffunction-sections -fno-exceptions -fno-rtti 65 | LDFLAGS += -nostdlib 66 | 67 | 68 | # Warning options for C and CXX compiler 69 | CFLAGS += -Wall -Wextra -Wundef -Wshadow -Wredundant-decls -Wmissing-prototypes -Wstrict-prototypes 70 | CXXFLAGS += -Wall -Wextra -Wundef -Wshadow -Wredundant-decls -Weffc++ -Werror 71 | 72 | # Linker options 73 | LDFLAGS += -T $(LDSCRIPT) 74 | LDFLAGS += -Wl,-Map=$(basename $@).map,--gc-sections,-cref,--print-memory-usage 75 | 76 | all : size bin 77 | size : $(BUILD_DIR)/$(TARGET).size 78 | elf : $(BUILD_DIR)/$(TARGET).elf 79 | bin : $(BUILD_DIR)/$(TARGET).bin 80 | hex : $(BUILD_DIR)/$(TARGET).hex 81 | srec : $(BUILD_DIR)/$(TARGET).srec 82 | list : $(BUILD_DIR)/$(TARGET).list 83 | asm : $(ASMS) 84 | 85 | # binary file to flash on target 86 | %.bin: %.elf 87 | @echo "COPY " $< " => " $@ 88 | @$(OBJCOPY) -Obinary $(*).elf $(*).bin 89 | 90 | # executable object files for debugging 91 | %.hex: %.elf 92 | $(OBJCOPY) -Oihex $(*).elf $(*).hex 93 | 94 | %.srec: %.elf 95 | $(OBJCOPY) -Osrec $(*).elf $(*).srec 96 | 97 | %.list: %.elf 98 | $(OBJDUMP) -S $(*).elf > $(*).list 99 | 100 | %.size: %.elf 101 | @echo "Section wise usage: " 102 | @$(SIZE) $< 103 | 104 | # Build assembly files 105 | $(BUILD_DIR)/%.s:%.c 106 | @mkdir -p $(dir $@) 107 | @echo "AS" $< " ==> " $@ 108 | @$(CC) $(CPU_FLAGS) $(CPPFLAGS) $(CFLAGS) -o $@ -S $< 109 | 110 | $(BUILD_DIR)/%.s:%.cpp 111 | @mkdir -p $(dir $@) 112 | @echo "AS" $< " ==> " $@ 113 | @$(CXX) $(CPU_FLAGS) $(CPPFLAGS) $(CXXFLAGS) -o $@ -S $< 114 | 115 | # Object files 116 | $(BUILD_DIR)/%.o:%.c 117 | @mkdir -p $(dir $@) 118 | @echo "CC" $< " ==> " $@ 119 | @$(CC) $(CPU_FLAGS) $(CPPFLAGS) $(CFLAGS) -o $@ -c $< 120 | 121 | $(BUILD_DIR)/%.o:%.cpp 122 | @mkdir -p $(dir $@) 123 | @echo "CXX" $< " ==> " $@ 124 | @$(CXX) $(CPU_FLAGS) $(CPPFLAGS) $(CXXFLAGS) -o $@ -c $< 125 | 126 | # final executable object file 127 | $(BUILD_DIR)/$(TARGET).elf: $(OBJS) $(LDSCRIPT) 128 | @echo "Linking sources into "$@ 129 | $(CC) $(CPU_FLAGS) $(LDFLAGS) -o $@ $(OBJS) 130 | 131 | # upload binary to stm32 132 | flash: bin 133 | st-flash write $(BUILD_DIR)/$(TARGET).bin 0x8000000 134 | 135 | # remove generated files 136 | clean: 137 | rm -rf build 138 | 139 | # include generated rules 140 | -include $(OBJS:%.o=%.d) -------------------------------------------------------------------------------- /dma-echo/Makefile: -------------------------------------------------------------------------------- 1 | TARGET = dma-usart 2 | 3 | 4 | # Configure micro-controller 5 | MCU_FAMILY = STM32F103xB 6 | LDSCRIPT = stm32f1.ld 7 | CPU = cortex-m3 8 | INSTR_SET = thumb 9 | FLOAT_ABI = soft 10 | 11 | # compiler option 12 | OPT := -Os 13 | CSTD ?= gnu11 14 | CXXSTD := gnu++17 15 | 16 | # Project specific configuration 17 | BUILD_DIR := build 18 | BUILD_TYPE ?= Debug 19 | SRC_DIR := src 20 | INC_DIRS := include 21 | 22 | 23 | PREFIX ?= arm-none-eabi 24 | CC := $(PREFIX)-gcc 25 | CXX := $(PREFIX)-g++ 26 | LD := $(PREFIX)-gcc 27 | AR := $(PREFIX)-ar 28 | AS := $(PREFIX)-as 29 | SIZE := $(PREFIX)-size 30 | OBJCOPY := $(PREFIX)-objcopy 31 | OBJDUMP := $(PREFIX)-objdump 32 | GDB := $(PREFIX)-gdb 33 | 34 | # collect source files and generate object files 35 | SRCS := $(shell find $(SRC_DIR) -name '*.cpp' -or -name '*.c') 36 | OBJS := $(addsuffix .o,$(basename $(SRCS))) # replace .c with .o 37 | OBJS := $(addprefix $(BUILD_DIR)/,$(OBJS)) # replace .c with .o 38 | ASMS := $(addsuffix .s,$(basename $(OBJS))) 39 | 40 | # Define stm32 family macro 41 | DEFS +=-D$(MCU_FAMILY) 42 | 43 | # header library include flsgs 44 | INC_FLAGS =$(addprefix -I,$(INC_DIRS)) 45 | 46 | 47 | # Target-specific flags 48 | CPU_FLAGS ?=-mfloat-abi=$(FLOAT_ABI) -m$(INSTR_SET) -mcpu=$(CPU) 49 | CPPFLAGS ?=$(DEFS) $(INC_FLAGS) -MMD 50 | 51 | # optiomization level according to build type 52 | ifeq ($(BUILD_TYPE), Debug) 53 | CFLAGS += -g -gdwarf-2 54 | CXXFLAGS += -g -gdwarf-2 55 | LDFLAGS += -g -gdwarf-2 56 | else 57 | CFLAGS += $(OPT) 58 | CXXFLAGS += $(OPT) 59 | ASFLAGS += $(OPT) 60 | endif 61 | 62 | # Do not link stdlib with executable 63 | CFLAGS += -nostdlib -fno-tree-loop-distribute-patterns -fdata-sections -ffunction-sections 64 | CXXFLAGS += -nostdlib -fno-tree-loop-distribute-patterns -fdata-sections -ffunction-sections -fno-exceptions -fno-rtti 65 | LDFLAGS += -nostdlib 66 | 67 | 68 | # Warning options for C and CXX compiler 69 | CFLAGS += -Wall -Wextra -Wundef -Wshadow -Wredundant-decls -Wmissing-prototypes -Wstrict-prototypes 70 | CXXFLAGS += -Wall -Wextra -Wundef -Wshadow -Wredundant-decls -Weffc++ -Werror 71 | 72 | # Linker options 73 | LDFLAGS += -T $(LDSCRIPT) 74 | LDFLAGS += -Wl,-Map=$(basename $@).map,--gc-sections,-cref,--print-memory-usage 75 | 76 | all : size bin 77 | size : $(BUILD_DIR)/$(TARGET).size 78 | elf : $(BUILD_DIR)/$(TARGET).elf 79 | bin : $(BUILD_DIR)/$(TARGET).bin 80 | hex : $(BUILD_DIR)/$(TARGET).hex 81 | srec : $(BUILD_DIR)/$(TARGET).srec 82 | list : $(BUILD_DIR)/$(TARGET).list 83 | asm : $(ASMS) 84 | 85 | # binary file to flash on target 86 | %.bin: %.elf 87 | @echo "COPY " $< " => " $@ 88 | @$(OBJCOPY) -Obinary $(*).elf $(*).bin 89 | 90 | # executable object files for debugging 91 | %.hex: %.elf 92 | $(OBJCOPY) -Oihex $(*).elf $(*).hex 93 | 94 | %.srec: %.elf 95 | $(OBJCOPY) -Osrec $(*).elf $(*).srec 96 | 97 | %.list: %.elf 98 | $(OBJDUMP) -S $(*).elf > $(*).list 99 | 100 | %.size: %.elf 101 | @echo "Section wise usage: " 102 | @$(SIZE) $< 103 | 104 | # Build assembly files 105 | $(BUILD_DIR)/%.s:%.c 106 | @mkdir -p $(dir $@) 107 | @echo "AS" $< " ==> " $@ 108 | @$(CC) $(CPU_FLAGS) $(CPPFLAGS) $(CFLAGS) -o $@ -S $< 109 | 110 | $(BUILD_DIR)/%.s:%.cpp 111 | @mkdir -p $(dir $@) 112 | @echo "AS" $< " ==> " $@ 113 | @$(CXX) $(CPU_FLAGS) $(CPPFLAGS) $(CXXFLAGS) -o $@ -S $< 114 | 115 | # Object files 116 | $(BUILD_DIR)/%.o:%.c 117 | @mkdir -p $(dir $@) 118 | @echo "CC" $< " ==> " $@ 119 | @$(CC) $(CPU_FLAGS) $(CPPFLAGS) $(CFLAGS) -o $@ -c $< 120 | 121 | $(BUILD_DIR)/%.o:%.cpp 122 | @mkdir -p $(dir $@) 123 | @echo "CXX" $< " ==> " $@ 124 | @$(CXX) $(CPU_FLAGS) $(CPPFLAGS) $(CXXFLAGS) -o $@ -c $< 125 | 126 | # final executable object file 127 | $(BUILD_DIR)/$(TARGET).elf: $(OBJS) $(LDSCRIPT) 128 | @echo "Linking sources into "$@ 129 | @$(CC) $(CPU_FLAGS) $(LDFLAGS) -o $@ $(OBJS) 130 | 131 | # upload binary to stm32 132 | flash: bin 133 | st-flash write $(BUILD_DIR)/$(TARGET).bin 0x8000000 134 | 135 | # remove generated files 136 | clean: 137 | rm -rf build 138 | 139 | # include generated rules 140 | -include $(OBJS:%.o=%.d) -------------------------------------------------------------------------------- /dma-circular/Makefile: -------------------------------------------------------------------------------- 1 | TARGET = dma-usart 2 | 3 | 4 | # Configure micro-controller 5 | MCU_FAMILY = STM32F103xB 6 | LDSCRIPT = stm32f1.ld 7 | CPU = cortex-m3 8 | INSTR_SET = thumb 9 | FLOAT_ABI = soft 10 | 11 | # compiler option 12 | OPT := -Os 13 | CSTD ?= gnu11 14 | CXXSTD := gnu++17 15 | 16 | # Project specific configuration 17 | BUILD_DIR := build 18 | BUILD_TYPE ?= Debug 19 | SRC_DIR := src 20 | INC_DIRS := include 21 | 22 | 23 | PREFIX ?= arm-none-eabi 24 | CC := $(PREFIX)-gcc 25 | CXX := $(PREFIX)-g++ 26 | LD := $(PREFIX)-gcc 27 | AR := $(PREFIX)-ar 28 | AS := $(PREFIX)-as 29 | SIZE := $(PREFIX)-size 30 | OBJCOPY := $(PREFIX)-objcopy 31 | OBJDUMP := $(PREFIX)-objdump 32 | GDB := $(PREFIX)-gdb 33 | 34 | # collect source files and generate object files 35 | SRCS := $(shell find $(SRC_DIR) -name '*.cpp' -or -name '*.c') 36 | OBJS := $(addsuffix .o,$(basename $(SRCS))) # replace .c with .o 37 | OBJS := $(addprefix $(BUILD_DIR)/,$(OBJS)) # replace .c with .o 38 | ASMS := $(addsuffix .s,$(basename $(OBJS))) 39 | 40 | # Define stm32 family macro 41 | DEFS +=-D$(MCU_FAMILY) 42 | 43 | # header library include flsgs 44 | INC_FLAGS =$(addprefix -I,$(INC_DIRS)) 45 | 46 | 47 | # Target-specific flags 48 | CPU_FLAGS ?=-mfloat-abi=$(FLOAT_ABI) -m$(INSTR_SET) -mcpu=$(CPU) 49 | CPPFLAGS ?=$(DEFS) $(INC_FLAGS) -MMD 50 | 51 | # optiomization level according to build type 52 | ifeq ($(BUILD_TYPE), Debug) 53 | CFLAGS += -g -gdwarf-2 54 | CXXFLAGS += -g -gdwarf-2 55 | LDFLAGS += -g -gdwarf-2 56 | else 57 | CFLAGS += $(OPT) 58 | CXXFLAGS += $(OPT) 59 | ASFLAGS += $(OPT) 60 | endif 61 | 62 | # Do not link stdlib with executable 63 | CFLAGS += -nostdlib -fno-tree-loop-distribute-patterns -fdata-sections -ffunction-sections 64 | CXXFLAGS += -nostdlib -fno-tree-loop-distribute-patterns -fdata-sections -ffunction-sections -fno-exceptions -fno-rtti 65 | LDFLAGS += -nostdlib 66 | 67 | 68 | # Warning options for C and CXX compiler 69 | CFLAGS += -Wall -Wextra -Wundef -Wshadow -Wredundant-decls -Wmissing-prototypes -Wstrict-prototypes 70 | CXXFLAGS += -Wall -Wextra -Wundef -Wshadow -Wredundant-decls -Weffc++ -Werror 71 | 72 | # Linker options 73 | LDFLAGS += -T $(LDSCRIPT) 74 | LDFLAGS += -Wl,-Map=$(basename $@).map,--gc-sections,-cref,--print-memory-usage 75 | 76 | all : size bin 77 | size : $(BUILD_DIR)/$(TARGET).size 78 | elf : $(BUILD_DIR)/$(TARGET).elf 79 | bin : $(BUILD_DIR)/$(TARGET).bin 80 | hex : $(BUILD_DIR)/$(TARGET).hex 81 | srec : $(BUILD_DIR)/$(TARGET).srec 82 | list : $(BUILD_DIR)/$(TARGET).list 83 | asm : $(ASMS) 84 | 85 | # binary file to flash on target 86 | %.bin: %.elf 87 | @echo "COPY " $< " => " $@ 88 | @$(OBJCOPY) -Obinary $(*).elf $(*).bin 89 | 90 | # executable object files for debugging 91 | %.hex: %.elf 92 | $(OBJCOPY) -Oihex $(*).elf $(*).hex 93 | 94 | %.srec: %.elf 95 | $(OBJCOPY) -Osrec $(*).elf $(*).srec 96 | 97 | %.list: %.elf 98 | $(OBJDUMP) -S $(*).elf > $(*).list 99 | 100 | %.size: %.elf 101 | @echo "Section wise usage: " 102 | @$(SIZE) $< 103 | 104 | # Build assembly files 105 | $(BUILD_DIR)/%.s:%.c 106 | @mkdir -p $(dir $@) 107 | @echo "AS" $< " ==> " $@ 108 | @$(CC) $(CPU_FLAGS) $(CPPFLAGS) $(CFLAGS) -o $@ -S $< 109 | 110 | $(BUILD_DIR)/%.s:%.cpp 111 | @mkdir -p $(dir $@) 112 | @echo "AS" $< " ==> " $@ 113 | @$(CXX) $(CPU_FLAGS) $(CPPFLAGS) $(CXXFLAGS) -o $@ -S $< 114 | 115 | # Object files 116 | $(BUILD_DIR)/%.o:%.c 117 | @mkdir -p $(dir $@) 118 | @echo "CC" $< " ==> " $@ 119 | @$(CC) $(CPU_FLAGS) $(CPPFLAGS) $(CFLAGS) -o $@ -c $< 120 | 121 | $(BUILD_DIR)/%.o:%.cpp 122 | @mkdir -p $(dir $@) 123 | @echo "CXX" $< " ==> " $@ 124 | @$(CXX) $(CPU_FLAGS) $(CPPFLAGS) $(CXXFLAGS) -o $@ -c $< 125 | 126 | # final executable object file 127 | $(BUILD_DIR)/$(TARGET).elf: $(OBJS) $(LDSCRIPT) 128 | @echo "Linking sources into "$@ 129 | $(CC) $(CPU_FLAGS) $(LDFLAGS) -o $@ $(OBJS) 130 | 131 | # upload binary to stm32 132 | flash: bin 133 | st-flash write $(BUILD_DIR)/$(TARGET).bin 0x8000000 134 | 135 | # remove generated files 136 | clean: 137 | rm -rf build 138 | 139 | # include generated rules 140 | -include $(OBJS:%.o=%.d) -------------------------------------------------------------------------------- /dma-echo/src/main.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file main.c 3 | * @author Rohit Nimkar (nehalnimkar@gmail.com) 4 | * @brief Main program body 5 | * @version 1.2 6 | * @date 2022-12-07 7 | * 8 | * @copyright Copyright (c) 2022 9 | * @attention 10 | * 11 | * This software component is licensed by Rohit Nimkar under BSD 3-Clause license, 12 | * the "License"; You may not use this file except in compliance with the 13 | * License. You may obtain a copy of the License at: opensource.org/licenses/BSD-3-Clause 14 | * 15 | */ 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | #define RX_LEN 10 23 | #define TX_LEN RX_LEN + 2 24 | 25 | char msg[TX_LEN]; 26 | 27 | void DMA1_Channel4_IRQHandler(void) 28 | { 29 | if (DMA1->ISR & DMA_ISR_TCIF4) 30 | { 31 | // clear interrupt flasg 32 | DMA1->IFCR |= DMA_IFCR_CGIF4; 33 | dma_usart_tx_disable(); 34 | dma_usart_rx_enable(); 35 | } 36 | } 37 | 38 | void DMA1_Channel5_IRQHandler(void) 39 | { 40 | if (DMA1->ISR & DMA_ISR_TCIF5) 41 | { 42 | // clear interrupt flasg 43 | DMA1->IFCR |= DMA_IFCR_CGIF5; 44 | dma_usart_rx_disable(); 45 | dma_usart_tx_enable(); 46 | } 47 | } 48 | 49 | 50 | int main(void) 51 | { 52 | // add newline and carriage return characters at the end of received data 53 | msg[RX_LEN] = '\r'; 54 | msg[RX_LEN + 1] = '\n'; 55 | 56 | // initialize systick timer 57 | SysTick_Config(SystemCoreClock / 1000); 58 | 59 | // enable clock for dma 60 | dma1_clock_enable(); 61 | 62 | // initialize usart, dma tx and dma rx 63 | usart1_init(); 64 | dma_usart_tx_init(); 65 | dma_usart_rx_init(); 66 | 67 | // enable interrupt for channel 4 and channel 5 68 | NVIC_EnableIRQ(DMA1_Channel4_IRQn); 69 | NVIC_EnableIRQ(DMA1_Channel5_IRQn); 70 | 71 | // enable usart. dma rx 72 | dma_usart_rx_enable(); 73 | usart1_enable(); 74 | 75 | while (1) 76 | { 77 | delay(2000); 78 | } 79 | 80 | } 81 | 82 | void dma1_clock_enable(void) 83 | { 84 | RCC->AHBENR |= RCC_AHBENR_DMA1EN; 85 | } 86 | 87 | /* DMA transmitter */ 88 | void dma_usart_tx_init(void) 89 | { 90 | // USART TX is mapped to DMA1 channel 4 91 | // set peripheral address to USART data register 92 | DMA1_Channel4->CPAR = (uint32_t)&USART1->DR; 93 | 94 | // set memory address to address of string 95 | DMA1_Channel4->CMAR = (uint32_t)msg; 96 | 97 | // set memory address incement by 1byte 98 | DMA1_Channel4->CCR |= DMA_CCR_MINC; 99 | 100 | // set data transfer direction - memory -> peripheral 101 | DMA1_Channel4->CCR |= DMA_CCR_DIR; 102 | 103 | // enable transmission complete interrupt 104 | DMA1_Channel4->CCR |= DMA_CCR_TCIE; 105 | } 106 | 107 | void dma_usart_tx_enable(void) 108 | { 109 | DMA1_Channel4->CNDTR = TX_LEN; 110 | DMA1_Channel4->CCR |= DMA_CCR_EN; 111 | } 112 | 113 | void dma_usart_tx_disable(void) 114 | { 115 | DMA1_Channel4->CCR &= ~DMA_CCR_EN; 116 | } 117 | 118 | /* DMA receiver */ 119 | void dma_usart_rx_init(void) 120 | { 121 | // USART RX is mapped to DMA1 channel 5 122 | // set peripheral address to USART data register 123 | DMA1_Channel5->CPAR = (uint32_t)&USART1->DR; 124 | 125 | // set memory address to address of string 126 | DMA1_Channel5->CMAR = (uint32_t)msg; 127 | 128 | // set memory address incement by 1byte 129 | DMA1_Channel5->CCR |= DMA_CCR_MINC; 130 | 131 | // set data transfer direction - peripheral -> memory 132 | DMA1_Channel5->CCR &= ~DMA_CCR_DIR; 133 | 134 | // enable transmission complete interrupt 135 | DMA1_Channel5->CCR |= DMA_CCR_TCIE; 136 | } 137 | 138 | void dma_usart_rx_enable(void) 139 | { 140 | DMA1_Channel5->CNDTR = RX_LEN; 141 | DMA1_Channel5->CCR |= DMA_CCR_EN; 142 | } 143 | 144 | void dma_usart_rx_disable(void) 145 | { DMA1_Channel5->CCR &= ~DMA_CCR_EN; 146 | } 147 | 148 | /* USART */ 149 | void usart1_init(void) 150 | { 151 | // enable clock for GPIOA and USART1 152 | RCC->APB2ENR |= RCC_APB2ENR_USART1EN | RCC_APB2ENR_IOPAEN; 153 | 154 | // reset pin configurations for PA9 and PA10 155 | GPIOA->CRH &= ~(GPIO_CRH_MODE10 | GPIO_CRH_MODE9 | GPIO_CRH_CNF10 | GPIO_CRH_CNF9); 156 | 157 | // PA9 as Output@50Hz Alternate function 158 | GPIOA->CRH |= GPIO_CRH_MODE9_0 | GPIO_CRH_MODE9_1 | GPIO_CRH_CNF9_1; 159 | 160 | // PA10 as floating input 161 | GPIOA->CRH |= GPIO_CRH_CNF10_0; 162 | 163 | // set baud rate as 9600 164 | uint32_t baud = (uint32_t)(SystemCoreClock / 115200); 165 | USART1->BRR = baud; 166 | 167 | // Enable transmitter and receiver 168 | USART1->CR1 |= USART_CR1_TE | USART_CR1_RE; 169 | 170 | // Enable DMA mode for transmitter and receiver 171 | USART1->CR3 |= USART_CR3_DMAT | USART_CR3_DMAR; 172 | } 173 | 174 | void usart1_enable(void) 175 | { 176 | USART1->CR1 |= USART_CR1_UE; 177 | } -------------------------------------------------------------------------------- /dma-circular/src/startup_stm32f1.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file startup_stm32f1.c 3 | * @author Rohit Nimkar (nehalnimkar@gmail.com) 4 | * @brief startup declarations and function for the STM32F1 series controllers 5 | * See: RM0008 10.1.2 Interrupt and exception vectors, Table 63. Vector table for other STM32F10xxx devices 6 | * 7 | * @version 1.2 8 | * @date 2022-12-07 9 | * 10 | * @copyright Copyright (c) 2022 11 | * @attention 12 | * 13 | * This software component is licensed by Rohit Nimkar under BSD 3-Clause license, 14 | * the "License"; You may not use this file except in compliance with the 15 | * License. You may obtain a copy of the License at: opensource.org/licenses/BSD-3-Clause 16 | * 17 | */ 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | // Define the vector table 25 | uint32_t vectors[] __attribute__((section(".isr_vector"))) = { 26 | (uint32_t)&_stack_top, 27 | (uint32_t)Reset_Handler, 28 | (uint32_t)NMI_Handler, 29 | (uint32_t)HardFault_Handler, 30 | (uint32_t)MemManage_Handler, 31 | (uint32_t)BusFault_Handler, 32 | (uint32_t)UsageFault_Handler, 33 | 0, // reserved 34 | 0, // reserved 35 | 0, // reserved 36 | 0, // reserved 37 | (uint32_t)SVC_Handler, 38 | (uint32_t)DebugMon_Handler, 39 | 0, // reserved 40 | (uint32_t)PendSV_Handler, 41 | (uint32_t)SysTick_Handler, 42 | (uint32_t)WWDG_IRQHandler, 43 | (uint32_t)PVD_IRQHandler, 44 | (uint32_t)TAMP_STAMP_IRQHandler, 45 | (uint32_t)RTC_WKUP_IRQHandler, 46 | 0, // Flash global interrupt 47 | (uint32_t)RCC_IRQHandler, 48 | (uint32_t)EXTI0_IRQHandler, 49 | (uint32_t)EXTI1_IRQHandler, 50 | (uint32_t)EXTI2_IRQHandler, 51 | (uint32_t)EXTI3_IRQHandler, 52 | (uint32_t)EXTI4_IRQHandler, 53 | (uint32_t)DMA1_Channel1_IRQHandler, 54 | (uint32_t)DMA1_Channel2_IRQHandler, 55 | (uint32_t)DMA1_Channel3_IRQHandler, 56 | (uint32_t)DMA1_Channel4_IRQHandler, 57 | (uint32_t)DMA1_Channel5_IRQHandler, 58 | (uint32_t)DMA1_Channel6_IRQHandler, 59 | (uint32_t)DMA1_Channel7_IRQHandler, 60 | (uint32_t)ADC_IRQHandler, 61 | (uint32_t)USB_HP_CAN_TX_IRQHandler, 62 | (uint32_t)USB_LP_CAN_RX0_IRQHandler, 63 | (uint32_t)CAN_RX1_IRQHandler, 64 | (uint32_t)CAN_SCE_IRQHandler, 65 | (uint32_t)EXTI9_5_IRQHandler, 66 | (uint32_t)TIM1_BRK_IRQHandler, 67 | (uint32_t)TIM1_UP_IRQHandler, 68 | (uint32_t)TIM1_TRG_COM_IRQHandler, 69 | (uint32_t)TIM1_CC_IRQHandler, 70 | (uint32_t)TIM2_IRQHandler, 71 | (uint32_t)TIM3_IRQHandler, 72 | (uint32_t)TIM4_IRQHandler, 73 | (uint32_t)I2C1_EV_IRQHandler, 74 | (uint32_t)I2C1_ER_IRQHandler, 75 | (uint32_t)I2C2_EV_IRQHandler, 76 | (uint32_t)I2C2_ER_IRQHandler, 77 | (uint32_t)SPI1_IRQHandler, 78 | (uint32_t)SPI2_IRQHandler, 79 | (uint32_t)USART1_IRQHandler, 80 | (uint32_t)USART2_IRQHandler, 81 | (uint32_t)USART3_IRQHandler, 82 | (uint32_t)EXTI15_10_IRQHandler, 83 | (uint32_t)RTC_Alarm_IRQHandler, 84 | (uint32_t)USB_Wakeup_IRQHandler, 85 | (uint32_t)TIM8_BRK_IRQHandler, 86 | (uint32_t)TIM8_UP_IRQHandler, 87 | (uint32_t)TIM8_TRG_COM_IRQHandler, 88 | (uint32_t)TIM8_CC_IRQHandler, 89 | (uint32_t)ADC3_IRQHandler, 90 | (uint32_t)FSMC_IRQHandler, 91 | (uint32_t)SDIO_IRQHandler, 92 | (uint32_t)TIM5_IRQHandler, 93 | (uint32_t)SPI3_IRQHandler, 94 | (uint32_t)UART4_IRQHandler, 95 | (uint32_t)UART5_IRQHandler, 96 | (uint32_t)TIM6_IRQHandler, 97 | (uint32_t)TIM7_IRQHandler, 98 | (uint32_t)DMA2_Channel1_IRQHandler, 99 | (uint32_t)DMA2_Channel2_IRQHandler, 100 | (uint32_t)DMA2_Channel3_IRQHandler, 101 | (uint32_t)DMA2_Channel4_5_IRQHandler, 102 | }; 103 | 104 | 105 | void Default_Handler(void) 106 | { 107 | while (1) 108 | ; 109 | } 110 | 111 | 112 | void __attribute__((noreturn)) Reset_Handler(void) 113 | { 114 | // copy .data section to SRAM 115 | uint32_t *start_sram = (uint32_t *)&_sdata; 116 | uint32_t *start_flash = (uint32_t *)&_la_data; 117 | while (start_sram < (uint32_t *)&_edata) 118 | { 119 | *start_sram++ = *start_flash++; 120 | } 121 | 122 | // copy .bss section to SRAM 123 | uint32_t *start_bss = (uint32_t *)&_sbss; 124 | while (start_bss < (uint32_t *)&_ebss) 125 | { 126 | *start_bss++ = 0; 127 | } 128 | 129 | // set value of SystemCoreClock variable 130 | SystemCoreClockUpdate(); 131 | 132 | // Call main function 133 | main(); 134 | 135 | // loop continuously 136 | while (1) 137 | { 138 | __asm("nop"); 139 | } 140 | 141 | } -------------------------------------------------------------------------------- /dma-1shot/src/startup_stm32f1.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file startup_stm32f1.c 3 | * @author Rohit Nimkar (nehalnimkar@gmail.com) 4 | * @brief startup declarations and function for the STM32F1 series controllers 5 | * See: RM0008 10.1.2 Interrupt and exception vectors, Table 63. Vector table for other STM32F10xxx devices 6 | * 7 | * @version 1.2 8 | * @date 2022-12-07 9 | * 10 | * @copyright Copyright (c) 2022 11 | * @attention 12 | * 13 | * This software component is licensed by Rohit Nimkar under BSD 3-Clause license, 14 | * the "License"; You may not use this file except in compliance with the 15 | * License. You may obtain a copy of the License at: opensource.org/licenses/BSD-3-Clause 16 | * 17 | */ 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | // Define the vector table 25 | uint32_t vectors[] __attribute__((section(".isr_vector"))) = { 26 | (uint32_t)&_stack_top, 27 | (uint32_t)Reset_Handler, 28 | (uint32_t)NMI_Handler, 29 | (uint32_t)HardFault_Handler, 30 | (uint32_t)MemManage_Handler, 31 | (uint32_t)BusFault_Handler, 32 | (uint32_t)UsageFault_Handler, 33 | 0, // reserved 34 | 0, // reserved 35 | 0, // reserved 36 | 0, // reserved 37 | (uint32_t)SVC_Handler, 38 | (uint32_t)DebugMon_Handler, 39 | 0, // reserved 40 | (uint32_t)PendSV_Handler, 41 | (uint32_t)SysTick_Handler, 42 | (uint32_t)WWDG_IRQHandler, 43 | (uint32_t)PVD_IRQHandler, 44 | (uint32_t)TAMP_STAMP_IRQHandler, 45 | (uint32_t)RTC_WKUP_IRQHandler, 46 | 0, // Flash global interrupt 47 | (uint32_t)RCC_IRQHandler, 48 | (uint32_t)EXTI0_IRQHandler, 49 | (uint32_t)EXTI1_IRQHandler, 50 | (uint32_t)EXTI2_IRQHandler, 51 | (uint32_t)EXTI3_IRQHandler, 52 | (uint32_t)EXTI4_IRQHandler, 53 | (uint32_t)DMA1_Channel1_IRQHandler, 54 | (uint32_t)DMA1_Channel2_IRQHandler, 55 | (uint32_t)DMA1_Channel3_IRQHandler, 56 | (uint32_t)DMA1_Channel4_IRQHandler, 57 | (uint32_t)DMA1_Channel5_IRQHandler, 58 | (uint32_t)DMA1_Channel6_IRQHandler, 59 | (uint32_t)DMA1_Channel7_IRQHandler, 60 | (uint32_t)ADC_IRQHandler, 61 | (uint32_t)USB_HP_CAN_TX_IRQHandler, 62 | (uint32_t)USB_LP_CAN_RX0_IRQHandler, 63 | (uint32_t)CAN_RX1_IRQHandler, 64 | (uint32_t)CAN_SCE_IRQHandler, 65 | (uint32_t)EXTI9_5_IRQHandler, 66 | (uint32_t)TIM1_BRK_IRQHandler, 67 | (uint32_t)TIM1_UP_IRQHandler, 68 | (uint32_t)TIM1_TRG_COM_IRQHandler, 69 | (uint32_t)TIM1_CC_IRQHandler, 70 | (uint32_t)TIM2_IRQHandler, 71 | (uint32_t)TIM3_IRQHandler, 72 | (uint32_t)TIM4_IRQHandler, 73 | (uint32_t)I2C1_EV_IRQHandler, 74 | (uint32_t)I2C1_ER_IRQHandler, 75 | (uint32_t)I2C2_EV_IRQHandler, 76 | (uint32_t)I2C2_ER_IRQHandler, 77 | (uint32_t)SPI1_IRQHandler, 78 | (uint32_t)SPI2_IRQHandler, 79 | (uint32_t)USART1_IRQHandler, 80 | (uint32_t)USART2_IRQHandler, 81 | (uint32_t)USART3_IRQHandler, 82 | (uint32_t)EXTI15_10_IRQHandler, 83 | (uint32_t)RTC_Alarm_IRQHandler, 84 | (uint32_t)USB_Wakeup_IRQHandler, 85 | (uint32_t)TIM8_BRK_IRQHandler, 86 | (uint32_t)TIM8_UP_IRQHandler, 87 | (uint32_t)TIM8_TRG_COM_IRQHandler, 88 | (uint32_t)TIM8_CC_IRQHandler, 89 | (uint32_t)ADC3_IRQHandler, 90 | (uint32_t)FSMC_IRQHandler, 91 | (uint32_t)SDIO_IRQHandler, 92 | (uint32_t)TIM5_IRQHandler, 93 | (uint32_t)SPI3_IRQHandler, 94 | (uint32_t)UART4_IRQHandler, 95 | (uint32_t)UART5_IRQHandler, 96 | (uint32_t)TIM6_IRQHandler, 97 | (uint32_t)TIM7_IRQHandler, 98 | (uint32_t)DMA2_Channel1_IRQHandler, 99 | (uint32_t)DMA2_Channel2_IRQHandler, 100 | (uint32_t)DMA2_Channel3_IRQHandler, 101 | (uint32_t)DMA2_Channel4_5_IRQHandler, 102 | }; 103 | 104 | 105 | void __attribute__((noreturn)) Default_Handler(void) 106 | { 107 | while (1) 108 | ; 109 | } 110 | 111 | 112 | void __attribute__((noreturn)) Reset_Handler(void) 113 | { 114 | // copy .data section to SRAM 115 | uint32_t *start_sram = (uint32_t *)&_sdata; 116 | uint32_t *start_flash = (uint32_t *)&_la_data; 117 | while (start_sram < (uint32_t *)&_edata) 118 | { 119 | *start_sram++ = *start_flash++; 120 | } 121 | 122 | // copy .bss section to SRAM 123 | uint32_t *start_bss = (uint32_t *)&_sbss; 124 | while (start_bss < (uint32_t *)&_ebss) 125 | { 126 | *start_bss++ = 0; 127 | } 128 | 129 | // set value of SystemCoreClock variable 130 | SystemCoreClockUpdate(); 131 | 132 | // Call main function 133 | main(); 134 | 135 | // loop continuously 136 | while (1) 137 | { 138 | __asm("nop"); 139 | } 140 | 141 | } -------------------------------------------------------------------------------- /dma-1shot/README.md: -------------------------------------------------------------------------------- 1 | # USART communication using DMA in 1-shot mode 2 | 3 | Communication between PC and STM32 using USART and DMA peripherals. 4 | 5 | Transmit data using USART1 and DMA in the one-shot mode without interruption of CPU. The DMA is restarted after every 2 seconds. This project does not require any IDE like CubeIde, any text editor will work including notepad and vim. For a better debugging experience, VSCode is preferred. 6 | 7 | ![Build Passing](https://img.shields.io/badge/build-passing-brightgreen) [![GPLv3 License](https://img.shields.io/badge/License-GPL%20v3-yellow.svg)](https://opensource.org/licenses/) 8 | 9 | ## Dependencies 10 | 11 | * make 12 | Make utility is required for configuring and building this project. You can install make on Linux by running the command: 13 | 14 | ```bash 15 | # for Debian-based Linux distros 16 | sudo apt install build-essential 17 | 18 | # for macOS 19 | xcode-select --install 20 | 21 | # for macOS using brew formulae 22 | brew install make 23 | ``` 24 | 25 | * gcc-arm-none-eabi toolchain 26 | ARM cross-platform toolchain is required to build applications for arm MCUs. The toolchain can be installed by running the following command: 27 | 28 | ```bash 29 | # for Debian-based Linux distros 30 | sudo apt install gcc-arm-none-eabi 31 | 32 | # for macOS 33 | brew install --cask gcc-arm-embedded 34 | ``` 35 | 36 | * openocd 37 | It is an Open On Circuit Debugging tool used to flash and debug arm microcontrollers. You can install openocd on Linux by running the command: 38 | 39 | ```bash 40 | # for Debian-based Linux distros 41 | sudo apt install openocd -y 42 | 43 | # for macOS 44 | brew install openocd 45 | ``` 46 | 47 | * stlink-tools 48 | This program is required for uploading binaries to the STM32 boards. You can install stlink tools by running the command: 49 | 50 | ```bash 51 | # for Debian-based Linux distros 52 | sudo apt install stlink-tools 53 | 54 | # for macOS 55 | brew install stlink 56 | ``` 57 | 58 | * Cortex Debug extension 59 | This extension for VSCode helps debug the application on Blue Pill. The contents of registers as well as memory are visible in the context menu. Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter. 60 | 61 | ```bash 62 | ext install marus25.cortex-debug 63 | ``` 64 | 65 | ## Project Structure 66 | 67 | * `src` directory contains all source files for the project 68 | * `include` directory contains all header files for the project 69 | 70 | ### Source file description 71 | 72 | * `stm32f1.ld` - linker script for stm32f103 73 | * `src/main.c` - main application code 74 | * `src/startup_stm32f1.c` - boot sequence for arm cortex-m3 processors 75 | * `src/system_stm32f1xx.c` - clock configuration and system initialization functions 76 | 77 | ## Run Locally 78 | 79 | Running the project is super easy. Just clone, build and flash. Clone this project using the **Code** button above. 80 | 81 | ### Configuration 82 | 83 | All the configuration required for building this project is given below. 84 | 85 | 1. Build output directory 86 | In `Makefile`, the output directory can be configured using the variable `BUILD_DIR`. 87 | 88 | 2. Build type 89 | In `Makefile`, the build type can be configured using the variable`BUILD_TYPE`. Possible values are `Debug` and `Release`. 90 | 91 | 3. Binary name 92 | In `Makefile`, the output binary name can be configured using the `TARGET` variable. 93 | ** update the target name in the `executable` property `.vscode/launch.json` for the debugger to work. 94 | 95 | ### Build 96 | 97 | Run the following command in the terminal to generate flashable binaries for the blue pill board. Build files will be written to **Build Output Directory** as configured. 98 | 99 | ```bash 100 | make 101 | ``` 102 | 103 | ## Flash 104 | 105 | 1. Connect Stlink to PC and blue pill board using SWD headers. 106 | 2. Put the blue pill board in programming mode *(optional)*. 107 | The *Boot0* jumper is set to *0*, set it to *1* and reset the device. 108 | 3. Run the following to flash the board with binary. 109 | 110 | ```bash 111 | make flash 112 | ``` 113 | 114 | 4. Done. 115 | 116 | ## Hardware Setup 117 | 118 | Connect the board with a host through a USB to TTL converter (FTDI board in our case). The connections are described as follows. 119 | 120 | | Pin on Blue Pill | Pin on FTDI | 121 | |------------------ |------------- | 122 | | PA9 | Rx | 123 | | PA10 | Tx | 124 | | Gnd | Gnd | 125 | 126 | ![Connection diagram for USART1](../docs/label.png "Pin connection diagram for usart1") 127 | 128 | ## Output 129 | 130 | "Hello, world" messages are visible on the terminal arriving every 2 seconds as seen below. 131 | ![Serial prompt at 115200 baudrate](docs/out_one_shot.png "Output on terminal") 132 | 133 | ## Debug 134 | 135 | Click on `Run and Debug` option in the VsCode sidebar. Then launch the `Cortex Debug` target. 136 | -------------------------------------------------------------------------------- /dma-echo/README.md: -------------------------------------------------------------------------------- 1 | # USART communication using DMA in Echo mode 2 | 3 | Communication between PC and STM32 using USART and DMA peripherals. 4 | 5 | Transmit data using USART1 and DMA in echo mode without interruption of CPU. DMA will accept 10 bytes from UART and echo back the same along with a carriage return and newline character. This project does not require any IDE like CubeIde, any text editor will work including notepad and vim. For better debugging experience, VSCode is preferred. 6 | 7 | ![Build Passing](https://img.shields.io/badge/build-passing-brightgreen) [![GPLv3 License](https://img.shields.io/badge/License-GPL%20v3-yellow.svg)](https://opensource.org/licenses/) 8 | 9 | ## Dependencies 10 | 11 | * make 12 | Make utility is required for configuring and building this project. You can install make on Linux by running the command: 13 | 14 | ```bash 15 | # for Debian-based Linux distros 16 | sudo apt install build-essential 17 | 18 | # for macOS 19 | xcode-select --install 20 | 21 | # for macOS using brew formulae 22 | brew install make 23 | ``` 24 | 25 | * gcc-arm-none-eabi toolchain 26 | ARM cross-platform toolchain is required to build applications for arm MCUs. The toolchain can be installed by running the following command: 27 | 28 | ```bash 29 | # for Debian-based Linux distros 30 | sudo apt install gcc-arm-none-eabi 31 | 32 | # for macOS 33 | brew install --cask gcc-arm-embedded 34 | ``` 35 | 36 | * openocd 37 | It is an Open On Circuit Debugging tool used to flash and debug arm microcontrollers. You can install openocd on Linux by running the command: 38 | 39 | ```bash 40 | # for Debian-based Linux distros 41 | sudo apt install openocd -y 42 | 43 | # for macOS 44 | brew install openocd 45 | ``` 46 | 47 | * stlink-tools 48 | This program is required for uploading binaries to the STM32 boards. You can install stlink tools by running the command: 49 | 50 | ```bash 51 | # for Debian-based Linux distros 52 | sudo apt install stlink-tools 53 | 54 | # for macOS 55 | brew install stlink 56 | ``` 57 | 58 | * Cortex Debug extension 59 | This extension for VSCode helps debug the application on Blue Pill. The contents of registers as well as memory are visible in the context menu. Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter. 60 | 61 | ```bash 62 | ext install marus25.cortex-debug 63 | ``` 64 | 65 | ## Project Structure 66 | 67 | * `src` directory contains all source files for the project 68 | * `include` directory contains all header files for the project 69 | 70 | ### Source file description 71 | 72 | * `stm32f1.ld` - linker script for stm32f103 73 | * `src/main.c` - main application code 74 | * `src/startup_stm32f1.c` - boot sequence for arm cortex-m3 processors 75 | * `src/system_stm32f1xx.c` - clock configuration and system initialization functions 76 | 77 | ## Run Locally 78 | 79 | Running the project is super easy. Just clone, build and flash. Clone this project using the **Code** button above. 80 | 81 | ### Configuration 82 | 83 | All the configuration required for building this project is given below. 84 | 85 | 1. Build output directory 86 | In `Makefile`, the output directory can be configured using the variable `BUILD_DIR`. 87 | 88 | 2. Build type 89 | In `Makefile`, the build type can be configured using the variable`BUILD_TYPE`. Possible values are `Debug` and `Release`. 90 | 91 | 3. Binary name 92 | In `Makefile`, the output binary name can be configured using the `TARGET` variable. 93 | ** update the target name in the `executable` property `.vscode/launch.json` for the debugger to work. 94 | 95 | ### Build 96 | 97 | Run the following command in the terminal to generate flashable binaries for the blue pill board. Build files will be written to **Build Output Directory** as configured. 98 | 99 | ```bash 100 | make 101 | ``` 102 | 103 | ## Flash 104 | 105 | 1. Connect Stlink to PC and blue pill board using SWD headers. 106 | 2. Put the blue pill board in programming mode *(optional)*. 107 | The *Boot0* jumper is set to *0*, set it to *1* and reset the device. 108 | 3. Run the following to flash the board with binary. 109 | 110 | ```bash 111 | make flash 112 | ``` 113 | 114 | 4. Done. 115 | 116 | ## Hardware Setup 117 | 118 | Connect the board with a host through a USB to TTL converter (FTDI board in our case). The connections are described as follows. 119 | 120 | | Pin on Blue Pill | Pin on FTDI | 121 | |------------------ |------------- | 122 | | PA9 | Rx | 123 | | PA10 | Tx | 124 | | Gnd | Gnd | 125 | 126 | ![Connection diagram for USART1](../docs/label.png "Pin connection diagram for usart1") 127 | 128 | ## Output 129 | 130 | Enter 10 bytes on the serial prompt, the controller will echo the same characters and place the cursor on the new line. 131 | ![Serial prompt at 115200 baudrate](docs/out_echo.png "Output on terminal") 132 | 133 | ## Debug 134 | 135 | Click on `Run and Debug` option in the VsCode sidebar. Then launch the `Cortex Debug` target. 136 | -------------------------------------------------------------------------------- /dma-echo/include/startup_stm32f1.h: -------------------------------------------------------------------------------- 1 | #include 2 | #ifndef __STARTUP_STM32F1_H__ 3 | #define __STARTUP_STM32F1_H__ 4 | 5 | /** 6 | * @brief Ending boundry of .text section in SRAM 7 | * This address does not belong to .text section 8 | */ 9 | extern uint32_t _etext; 10 | 11 | /** 12 | * @brief Starting address of .data section in SRAM 13 | */ 14 | extern uint32_t _sdata; 15 | 16 | /** 17 | * @brief Ending boundry of .data section in SRAM 18 | * This address does not belong to .data section 19 | */ 20 | extern uint32_t _edata; 21 | 22 | /** 23 | * @brief Starting address of .data section in FLASH 24 | */ 25 | extern uint32_t _la_data; 26 | 27 | /** 28 | * @brief Starting address of .bss section in SRAM 29 | */ 30 | extern uint32_t _sbss; 31 | 32 | /** 33 | * @brief Ending boundry of .bss section in SRAM 34 | * This address does not belong to .bss section 35 | */ 36 | extern uint32_t _ebss; 37 | 38 | /** 39 | * @brief Address to be set in the main stack pointer 40 | */ 41 | extern uint32_t _stack_top; 42 | 43 | void __attribute__((noreturn)) Reset_Handler(void); 44 | void Default_Handler(void); 45 | 46 | void __attribute__((weak, alias("Default_Handler"))) NMI_Handler(void); 47 | void __attribute__((weak, alias("Default_Handler"))) HardFault_Handler(void); 48 | void __attribute__((weak, alias("Default_Handler"))) MemManage_Handler(void); 49 | void __attribute__((weak, alias("Default_Handler"))) BusFault_Handler(void); 50 | void __attribute__((weak, alias("Default_Handler"))) UsageFault_Handler(void); 51 | void __attribute__((weak, alias("Default_Handler"))) SVC_Handler(void); 52 | void __attribute__((weak, alias("Default_Handler"))) DebugMon_Handler(void); 53 | void __attribute__((weak, alias("Default_Handler"))) PendSV_Handler(void); 54 | void __attribute__((weak, alias("Default_Handler"))) SysTick_Handler(void); 55 | void __attribute__((weak, alias("Default_Handler"))) WWDG_IRQHandler(void); 56 | void __attribute__((weak, alias("Default_Handler"))) PVD_IRQHandler(void); 57 | void __attribute__((weak, alias("Default_Handler"))) TAMP_STAMP_IRQHandler(void); 58 | void __attribute__((weak, alias("Default_Handler"))) RTC_WKUP_IRQHandler(void); 59 | void __attribute__((weak, alias("Default_Handler"))) RCC_IRQHandler(void); 60 | void __attribute__((weak, alias("Default_Handler"))) EXTI0_IRQHandler(void); 61 | void __attribute__((weak, alias("Default_Handler"))) EXTI1_IRQHandler(void); 62 | void __attribute__((weak, alias("Default_Handler"))) EXTI2_IRQHandler(void); 63 | void __attribute__((weak, alias("Default_Handler"))) EXTI3_IRQHandler(void); 64 | void __attribute__((weak, alias("Default_Handler"))) EXTI4_IRQHandler(void); 65 | void __attribute__((weak, alias("Default_Handler"))) DMA1_Channel1_IRQHandler(void); 66 | void __attribute__((weak, alias("Default_Handler"))) DMA1_Channel2_IRQHandler(void); 67 | void __attribute__((weak, alias("Default_Handler"))) DMA1_Channel3_IRQHandler(void); 68 | void __attribute__((weak, alias("Default_Handler"))) DMA1_Channel4_IRQHandler(void); 69 | void __attribute__((weak, alias("Default_Handler"))) DMA1_Channel5_IRQHandler(void); 70 | void __attribute__((weak, alias("Default_Handler"))) DMA1_Channel6_IRQHandler(void); 71 | void __attribute__((weak, alias("Default_Handler"))) DMA1_Channel7_IRQHandler(void); 72 | void __attribute__((weak, alias("Default_Handler"))) ADC_IRQHandler(void); 73 | void __attribute__((weak, alias("Default_Handler"))) USB_HP_CAN_TX_IRQHandler(void); 74 | void __attribute__((weak, alias("Default_Handler"))) USB_LP_CAN_RX0_IRQHandler(void); 75 | void __attribute__((weak, alias("Default_Handler"))) CAN_RX1_IRQHandler(void); 76 | void __attribute__((weak, alias("Default_Handler"))) CAN_SCE_IRQHandler(void); 77 | void __attribute__((weak, alias("Default_Handler"))) EXTI9_5_IRQHandler(void); 78 | void __attribute__((weak, alias("Default_Handler"))) TIM1_BRK_IRQHandler(void); 79 | void __attribute__((weak, alias("Default_Handler"))) TIM1_UP_IRQHandler(void); 80 | void __attribute__((weak, alias("Default_Handler"))) TIM1_TRG_COM_IRQHandler(void); 81 | void __attribute__((weak, alias("Default_Handler"))) TIM1_CC_IRQHandler(void); 82 | void __attribute__((weak, alias("Default_Handler"))) TIM2_IRQHandler(void); 83 | void __attribute__((weak, alias("Default_Handler"))) TIM3_IRQHandler(void); 84 | void __attribute__((weak, alias("Default_Handler"))) TIM4_IRQHandler(void); 85 | void __attribute__((weak, alias("Default_Handler"))) I2C1_EV_IRQHandler(void); 86 | void __attribute__((weak, alias("Default_Handler"))) I2C1_ER_IRQHandler(void); 87 | void __attribute__((weak, alias("Default_Handler"))) I2C2_EV_IRQHandler(void); 88 | void __attribute__((weak, alias("Default_Handler"))) I2C2_ER_IRQHandler(void); 89 | void __attribute__((weak, alias("Default_Handler"))) SPI1_IRQHandler(void); 90 | void __attribute__((weak, alias("Default_Handler"))) SPI2_IRQHandler(void); 91 | void __attribute__((weak, alias("Default_Handler"))) USART1_IRQHandler(void); 92 | void __attribute__((weak, alias("Default_Handler"))) USART2_IRQHandler(void); 93 | void __attribute__((weak, alias("Default_Handler"))) USART3_IRQHandler(void); 94 | void __attribute__((weak, alias("Default_Handler"))) EXTI15_10_IRQHandler(void); 95 | void __attribute__((weak, alias("Default_Handler"))) RTC_Alarm_IRQHandler(void); 96 | void __attribute__((weak, alias("Default_Handler"))) USB_Wakeup_IRQHandler(void); 97 | #endif -------------------------------------------------------------------------------- /dma-circular/README.md: -------------------------------------------------------------------------------- 1 | # USART communication using DMA in Circular mode 2 | 3 | Communication between PC and STM32 using USART and DMA peripherals. 4 | 5 | Transmit data using USART1 and DMA in the circular mode without interruption of CPU. This project does not require any IDE like CubeIde, any text editor will work including notepad and vim. For better debugging experience, VSCode is preferred. 6 | 7 | ![Build Passing](https://img.shields.io/badge/build-passing-brightgreen) [![GPLv3 License](https://img.shields.io/badge/License-GPL%20v3-yellow.svg)](https://opensource.org/licenses/) 8 | # USART communication using DMA in echo mode 9 | 10 | Communication between PC and STM32 using USART and DMA peripherals. 11 | 12 | Transmit data using USART1 and DMA in echo mode without interruption of CPU. DMA will accept 10 bytes from UART and echo back the same along with a carriage return and newline character. This project does not require any IDE like CubeIde, any text editor will work including notepad, vim. For better debugging experience, VSCode is preferred. 13 | 14 | ## Dependencies 15 | 16 | * make 17 | Make utility is required for configuring and building this project. You can install make on Linux by running the command: 18 | 19 | ```bash 20 | # for Debian-based Linux distros 21 | sudo apt install build-essential 22 | 23 | # for macOS 24 | xcode-select --install 25 | 26 | # for macOS using brew formulae 27 | brew install make 28 | ``` 29 | 30 | * gcc-arm-none-eabi toolchain 31 | ARM cross-platform toolchain is required to build applications for arm MCUs. The toolchain can be installed by running the following command: 32 | 33 | ```bash 34 | # for Debian-based Linux distros 35 | sudo apt install gcc-arm-none-eabi 36 | 37 | # for macOS 38 | brew install --cask gcc-arm-embedded 39 | ``` 40 | 41 | * openocd 42 | It is an Open On Circuit Debugging tool used to flash and debug arm microcontrollers. You can install openocd on Linux by running the command: 43 | 44 | ```bash 45 | # for Debian-based Linux distros 46 | sudo apt install openocd -y 47 | 48 | # for macOS 49 | brew install openocd 50 | ``` 51 | 52 | * stlink-tools 53 | This program is required for uploading binaries to the STM32 boards. You can install stlink tools by running the command: 54 | 55 | ```bash 56 | # for Debian-based Linux distros 57 | sudo apt install stlink-tools 58 | 59 | # for macOS 60 | brew install stlink 61 | ``` 62 | 63 | * Cortex Debug extension 64 | This extension for VSCode helps debug the application on Blue Pill. The contents of registers as well as memory are visible in the context menu. Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter. 65 | 66 | ```bash 67 | ext install marus25.cortex-debug 68 | ``` 69 | 70 | ## Project Structure 71 | 72 | * `src` directory contains all source files for the project 73 | * `include` directory contains all header files for the project 74 | 75 | ### Source file description 76 | 77 | * `stm32f1.ld` - linker script for stm32f103 78 | * `src/main.c` - main application code 79 | * `src/startup_stm32f1.c` - boot sequence for arm cortex-m3 processors 80 | * `src/system_stm32f1xx.c` - clock configuration and system initialization functions 81 | 82 | ## Run Locally 83 | 84 | Running the project is super easy. Just clone, build and flash. Clone this project using the **Code** button above. 85 | 86 | ### Configuration 87 | 88 | All the configuration required for building this project is given below. 89 | 90 | 1. Build output directory 91 | In `Makefile`, the output directory can be configured using the variable `BUILD_DIR`. 92 | 93 | 2. Build type 94 | In `Makefile`, the build type can be configured using the variable`BUILD_TYPE`. Possible values are `Debug` and `Release`. 95 | 96 | 3. Binary name 97 | In `Makefile`, the output binary name can be configured using the `TARGET` variable. 98 | ** update the target name in the `executable` property `.vscode/launch.json` for the debugger to work. 99 | 100 | ### Build 101 | 102 | Run the following command in the terminal to generate flashable binaries for the blue pill board. Build files will be written to **Build Output Directory** as configured. 103 | 104 | ```bash 105 | make 106 | ``` 107 | 108 | ## Flash 109 | 110 | 1. Connect Stlink to PC and blue pill board using SWD headers. 111 | 2. Put the blue pill board in programming mode *(optional)*. 112 | The *Boot0* jumper is set to *0*, set it to *1* and reset the device. 113 | 3. Run the following to flash the board with binary. 114 | 115 | ```bash 116 | make flash 117 | ``` 118 | 119 | 4. Done. 120 | 121 | ## Hardware Setup 122 | 123 | Connect the board with a host through a USB to TTL converter (FTDI board in our case). The connections are described as follows. 124 | 125 | | Pin on Blue Pill | Pin on FTDI | 126 | |------------------ |------------- | 127 | | PA9 | Rx | 128 | | PA10 | Tx | 129 | | Gnd | Gnd | 130 | 131 | ![Connection diagram for USART1](../docs/label.png "Pin connection diagram for usart1") 132 | 133 | ## Output 134 | 135 | "Hello world" messages are visible on the terminal arriving continuously dues to circular mode of operation as seen below. 136 | ![Serial prompt at 115200 baudrate](docs/out_115200_circ.png "Output on terminal") 137 | 138 | ## Debug 139 | 140 | Click on `Run and Debug` option in the VsCode sidebar. Then launch the `Cortex Debug` target. 141 | 142 | -------------------------------------------------------------------------------- /cpp/README.md: -------------------------------------------------------------------------------- 1 | # DMA operation with USART1 in C++ 2 | 3 | Achieve USART communication with DMA in Circular, 1shot and Echo mode. The complete development flow is independent of any IDE or tools. This project code can be editied on any text editor and uploaded to the board using drivers provided by STMicro-electronics. 4 | 5 | 6 | ## Dependencies 7 | 8 | * **make**\ 9 | Make utility is required for configuring and building this project. You can install make on linux by running command: 10 | 11 | ```bash 12 | sudo apt install build-essential 13 | ``` 14 | 15 | * **gcc-arm-none-eabi toolchain**\ 16 | ARM cross-platform toolchain is required to build applications for arm mcus. Toolchain can be installed by running following command: 17 | 18 | ```bash 19 | sudo apt install gcc-arm-none-eabi 20 | ``` 21 | 22 | * **openocd**\ 23 | It is an Open On Circuit Debugging tool used to flash and debug arm micro controllers. You can install openocd on linux by running command: 24 | 25 | ```bash 26 | sudo apt install openocd -y 27 | ``` 28 | 29 | * **st-link**\ 30 | This package is provided by STMicro-electronics for flashing the binary on the micro-controller 31 | 32 | ```bash 33 | sudo apt install stlink 34 | ``` 35 | 36 | * **Cortex Debug extension**\ 37 | This extension for VSCode is helpful for debugging the application on Blue Pill. The contents of registers as well as memory are visible in the context menu. 38 | Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter. 39 | 40 | ```bash 41 | ext install marus25.cortex-debug 42 | ``` 43 | 44 | ## Project Structure 45 | 46 | * `src` directory contains all source files for the project 47 | * `include` directory contains all header files for the project 48 | 49 | ### Source file description 50 | 51 | * `stm31f1.ld` - linker script for STM32F103 MCU 52 | * `src\main.cpp` - application code 53 | * `src\startup_stm32f103.cpp` - startup script in cpp 54 | * `include\gpio.hpp` - slibrary for handling gpio functions 55 | * `system_stm32f1xx.c` - clock configuration and system initialization functions 56 | * `STM32F103.svd` - contains the description of the system contained in Arm Cortex-M processor-based microcontrollers, in particular, the memory mapped registers of peripherals. 57 | 58 | ## Run Locally 59 | 60 | Running the project is super easy. Just clone, build, and flash. 61 | 62 | ### Clone the project 63 | 64 | 1. Using https 65 | 66 | ```bash 67 | git clone https://github.com/csrohit/stm32-startup-cpp.git 68 | cd stm32-startup-cpp 69 | ``` 70 | 71 | 2. Using ssh 72 | 73 | ```bash 74 | git clone git@github.com:csrohit/stm32-startup-cpp.git 75 | cd stm32-startup-cpp 76 | ``` 77 | 78 | ## Configuration 79 | 80 | All the configuration required for building this project is given below. 81 | 82 | 1. Build output directory 83 | In `Makefile`, output directory can be configured using variable `BUILD_DIR`. 84 | 85 | 2. Binary name 86 | In `Makefile`, the name of binary can be configured using variable `TARGET`. 87 | 88 | 3. MCU 89 | In `Makefile`, the target mcu can be selected by seting the following flags/variables 90 | * `MCU_FAMILY`: Specifies the family, it used to define a maco for inclusion of header files 91 | * `LD_SCRIPT`: Specifies path to linker script of the target controller 92 | * `INSTR_SET`: Specifies the instruction set to use. e.g. `thumb`, `arm`, etc 93 | * `FLOAT_ABI`: Specifies the floating point implementation 94 | * `CPU`: Specifies the processor on the MCU. e.g. `cortex-m3`, `cortex-m4`, etc 95 | 96 | ## Build 97 | 98 | Run following command in terminal to generate flashable binaries for blue pill board. Build files will be written to **Build Output Directory** as configured. 99 | 100 | ```bash 101 | make all 102 | ``` 103 | 104 | ## Flash 105 | 106 | 1. Connect STlink to PC and blue pill board using swd headers. 107 | 2. Put blue pill board in programming mode. 108 | 3. Run following to flash board with binary. 109 | 110 | ```C 111 | make flash 112 | ``` 113 | 114 | Output 115 | 116 | Onboard led connected to Pin C13 can be observed to be blinking every second. 117 | 118 | ## Debug 119 | 120 | 1. Run the following make command to build the program using debugging flags 121 | 122 | ```bash 123 | make debug 124 | ``` 125 | 126 | 2. Flash the controller using following command 127 | 128 | ```bash 129 | make flash 130 | ``` 131 | 132 | 3. Click in Run and Debug option in VsCode sidebar. Then launch Cortex Debug target. 133 | 134 | Happy debugging.... 135 | 136 | ### Dependency option 137 | -M 138 | Outputs a rule suitable for makefile, does not compile the file 139 | The generated rule does not have a command 140 | 141 | -MM 142 | Outputs a rule suitable for makefile, does not compile the file. 143 | In the dependencies only include user files, do not include system header files 144 | 145 | -MT/-MQ (-MM -MT abc.o) => change the target 146 | This changes the name of the target 147 | -MT => generates the same string as provided 148 | -MQ => replaces value of the make variable in the target (expansation) 149 | 150 | -MD => D represents that the preprocessor output should be generated as a side effect and the main compilation happens 151 | If -o options is specified then it is taken as name for the preprocessor output with .d 152 | else name of input file is taken with extensions as .d 153 | To override the name of the pre-processor output file -MF option should be used -------------------------------------------------------------------------------- /polling/STM32F103C8TX_FLASH.ld: -------------------------------------------------------------------------------- 1 | /* 2 | ****************************************************************************** 3 | ** 4 | ** @file : LinkerScript.ld 5 | ** 6 | ** @author : Auto-generated by STM32CubeIDE 7 | ** 8 | ** @brief : Linker script for STM32F103C8Tx Device from STM32F1 series 9 | ** 64Kbytes FLASH 10 | ** 20Kbytes 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) 2022 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 | 35 | /* Entry Point */ 36 | ENTRY(Reset_Handler) 37 | 38 | /* Highest address of the user mode stack */ 39 | _estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ 40 | 41 | _Min_Heap_Size = 0x200; /* required amount of heap */ 42 | _Min_Stack_Size = 0x400; /* required amount of stack */ 43 | 44 | /* Memories definition */ 45 | MEMORY 46 | { 47 | RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 20K 48 | FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 64K 49 | } 50 | 51 | /* Sections */ 52 | SECTIONS 53 | { 54 | /* The startup code into "FLASH" Rom type memory */ 55 | .isr_vector : 56 | { 57 | . = ALIGN(4); 58 | KEEP(*(.isr_vector)) /* Startup code */ 59 | . = ALIGN(4); 60 | } >FLASH 61 | 62 | /* The program code and other data into "FLASH" Rom type memory */ 63 | .text : 64 | { 65 | . = ALIGN(4); 66 | *(.text) /* .text sections (code) */ 67 | *(.text*) /* .text* sections (code) */ 68 | *(.glue_7) /* glue arm to thumb code */ 69 | *(.glue_7t) /* glue thumb to arm code */ 70 | *(.eh_frame) 71 | 72 | KEEP (*(.init)) 73 | KEEP (*(.fini)) 74 | 75 | . = ALIGN(4); 76 | _etext = .; /* define a global symbols at end of code */ 77 | } >FLASH 78 | 79 | /* Constant data into "FLASH" Rom type memory */ 80 | .rodata : 81 | { 82 | . = ALIGN(4); 83 | *(.rodata) /* .rodata sections (constants, strings, etc.) */ 84 | *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ 85 | . = ALIGN(4); 86 | } >FLASH 87 | 88 | .ARM.extab : { 89 | . = ALIGN(4); 90 | *(.ARM.extab* .gnu.linkonce.armextab.*) 91 | . = ALIGN(4); 92 | } >FLASH 93 | 94 | .ARM : { 95 | . = ALIGN(4); 96 | __exidx_start = .; 97 | *(.ARM.exidx*) 98 | __exidx_end = .; 99 | . = ALIGN(4); 100 | } >FLASH 101 | 102 | .preinit_array : 103 | { 104 | . = ALIGN(4); 105 | PROVIDE_HIDDEN (__preinit_array_start = .); 106 | KEEP (*(.preinit_array*)) 107 | PROVIDE_HIDDEN (__preinit_array_end = .); 108 | . = ALIGN(4); 109 | } >FLASH 110 | 111 | .init_array : 112 | { 113 | . = ALIGN(4); 114 | PROVIDE_HIDDEN (__init_array_start = .); 115 | KEEP (*(SORT(.init_array.*))) 116 | KEEP (*(.init_array*)) 117 | PROVIDE_HIDDEN (__init_array_end = .); 118 | . = ALIGN(4); 119 | } >FLASH 120 | 121 | .fini_array : 122 | { 123 | . = ALIGN(4); 124 | PROVIDE_HIDDEN (__fini_array_start = .); 125 | KEEP (*(SORT(.fini_array.*))) 126 | KEEP (*(.fini_array*)) 127 | PROVIDE_HIDDEN (__fini_array_end = .); 128 | . = ALIGN(4); 129 | } >FLASH 130 | 131 | /* Used by the startup to initialize data */ 132 | _sidata = LOADADDR(.data); 133 | 134 | /* Initialized data sections into "RAM" Ram type memory */ 135 | .data : 136 | { 137 | . = ALIGN(4); 138 | _sdata = .; /* create a global symbol at data start */ 139 | *(.data) /* .data sections */ 140 | *(.data*) /* .data* sections */ 141 | *(.RamFunc) /* .RamFunc sections */ 142 | *(.RamFunc*) /* .RamFunc* sections */ 143 | 144 | . = ALIGN(4); 145 | _edata = .; /* define a global symbol at data end */ 146 | 147 | } >RAM AT> FLASH 148 | 149 | /* Uninitialized data section into "RAM" Ram type memory */ 150 | . = ALIGN(4); 151 | .bss : 152 | { 153 | /* This is used by the startup in order to initialize the .bss section */ 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" Ram type memory 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 | /* Remove information from the compiler libraries */ 177 | /DISCARD/ : 178 | { 179 | libc.a ( * ) 180 | libm.a ( * ) 181 | libgcc.a ( * ) 182 | } 183 | 184 | .ARM.attributes 0 : { *(.ARM.attributes) } 185 | } 186 | -------------------------------------------------------------------------------- /dma-circular/include/startup_stm32f1.h: -------------------------------------------------------------------------------- 1 | #include 2 | #ifndef __STARTUP_STM32F1_H__ 3 | #define __STARTUP_STM32F1_H__ 4 | 5 | /** 6 | * @brief Ending boundry of .text section in SRAM 7 | * This address does not belong to .text section 8 | */ 9 | extern uint32_t _etext; 10 | 11 | /** 12 | * @brief Starting address of .data section in SRAM 13 | */ 14 | extern uint32_t _sdata; 15 | 16 | /** 17 | * @brief Ending boundry of .data section in SRAM 18 | * This address does not belong to .data section 19 | */ 20 | extern uint32_t _edata; 21 | 22 | /** 23 | * @brief Starting address of .data section in FLASH 24 | */ 25 | extern uint32_t _la_data; 26 | 27 | /** 28 | * @brief Starting address of .bss section in SRAM 29 | */ 30 | extern uint32_t _sbss; 31 | 32 | /** 33 | * @brief Ending boundry of .bss section in SRAM 34 | * This address does not belong to .bss section 35 | */ 36 | extern uint32_t _ebss; 37 | 38 | /** 39 | * @brief Address to be set in the main stack pointer 40 | */ 41 | extern uint32_t _stack_top; 42 | 43 | void __attribute__((noreturn)) Reset_Handler(void); 44 | void Default_Handler(void); 45 | 46 | void __attribute__((weak, alias("Default_Handler"))) NMI_Handler(void); 47 | void __attribute__((weak, alias("Default_Handler"))) HardFault_Handler(void); 48 | void __attribute__((weak, alias("Default_Handler"))) MemManage_Handler(void); 49 | void __attribute__((weak, alias("Default_Handler"))) BusFault_Handler(void); 50 | void __attribute__((weak, alias("Default_Handler"))) UsageFault_Handler(void); 51 | void __attribute__((weak, alias("Default_Handler"))) SVC_Handler(void); 52 | void __attribute__((weak, alias("Default_Handler"))) DebugMon_Handler(void); 53 | void __attribute__((weak, alias("Default_Handler"))) PendSV_Handler(void); 54 | void __attribute__((weak, alias("Default_Handler"))) SysTick_Handler(void); 55 | void __attribute__((weak, alias("Default_Handler"))) WWDG_IRQHandler(void); 56 | void __attribute__((weak, alias("Default_Handler"))) PVD_IRQHandler(void); 57 | void __attribute__((weak, alias("Default_Handler"))) TAMP_STAMP_IRQHandler(void); 58 | void __attribute__((weak, alias("Default_Handler"))) RTC_WKUP_IRQHandler(void); 59 | void __attribute__((weak, alias("Default_Handler"))) RCC_IRQHandler(void); 60 | void __attribute__((weak, alias("Default_Handler"))) EXTI0_IRQHandler(void); 61 | void __attribute__((weak, alias("Default_Handler"))) EXTI1_IRQHandler(void); 62 | void __attribute__((weak, alias("Default_Handler"))) EXTI2_IRQHandler(void); 63 | void __attribute__((weak, alias("Default_Handler"))) EXTI3_IRQHandler(void); 64 | void __attribute__((weak, alias("Default_Handler"))) EXTI4_IRQHandler(void); 65 | void __attribute__((weak, alias("Default_Handler"))) DMA1_Channel1_IRQHandler(void); 66 | void __attribute__((weak, alias("Default_Handler"))) DMA1_Channel2_IRQHandler(void); 67 | void __attribute__((weak, alias("Default_Handler"))) DMA1_Channel3_IRQHandler(void); 68 | void __attribute__((weak, alias("Default_Handler"))) DMA1_Channel4_IRQHandler(void); 69 | void __attribute__((weak, alias("Default_Handler"))) DMA1_Channel5_IRQHandler(void); 70 | void __attribute__((weak, alias("Default_Handler"))) DMA1_Channel6_IRQHandler(void); 71 | void __attribute__((weak, alias("Default_Handler"))) DMA1_Channel7_IRQHandler(void); 72 | void __attribute__((weak, alias("Default_Handler"))) ADC_IRQHandler(void); 73 | void __attribute__((weak, alias("Default_Handler"))) USB_HP_CAN_TX_IRQHandler(void); 74 | void __attribute__((weak, alias("Default_Handler"))) USB_LP_CAN_RX0_IRQHandler(void); 75 | void __attribute__((weak, alias("Default_Handler"))) CAN_RX1_IRQHandler(void); 76 | void __attribute__((weak, alias("Default_Handler"))) CAN_SCE_IRQHandler(void); 77 | void __attribute__((weak, alias("Default_Handler"))) EXTI9_5_IRQHandler(void); 78 | void __attribute__((weak, alias("Default_Handler"))) TIM1_BRK_IRQHandler(void); 79 | void __attribute__((weak, alias("Default_Handler"))) TIM1_UP_IRQHandler(void); 80 | void __attribute__((weak, alias("Default_Handler"))) TIM1_TRG_COM_IRQHandler(void); 81 | void __attribute__((weak, alias("Default_Handler"))) TIM1_CC_IRQHandler(void); 82 | void __attribute__((weak, alias("Default_Handler"))) TIM2_IRQHandler(void); 83 | void __attribute__((weak, alias("Default_Handler"))) TIM3_IRQHandler(void); 84 | void __attribute__((weak, alias("Default_Handler"))) TIM4_IRQHandler(void); 85 | void __attribute__((weak, alias("Default_Handler"))) I2C1_EV_IRQHandler(void); 86 | void __attribute__((weak, alias("Default_Handler"))) I2C1_ER_IRQHandler(void); 87 | void __attribute__((weak, alias("Default_Handler"))) I2C2_EV_IRQHandler(void); 88 | void __attribute__((weak, alias("Default_Handler"))) I2C2_ER_IRQHandler(void); 89 | void __attribute__((weak, alias("Default_Handler"))) SPI1_IRQHandler(void); 90 | void __attribute__((weak, alias("Default_Handler"))) SPI2_IRQHandler(void); 91 | void __attribute__((weak, alias("Default_Handler"))) USART1_IRQHandler(void); 92 | void __attribute__((weak, alias("Default_Handler"))) USART2_IRQHandler(void); 93 | void __attribute__((weak, alias("Default_Handler"))) USART3_IRQHandler(void); 94 | void __attribute__((weak, alias("Default_Handler"))) EXTI15_10_IRQHandler(void); 95 | void __attribute__((weak, alias("Default_Handler"))) RTC_Alarm_IRQHandler(void); 96 | void __attribute__((weak, alias("Default_Handler"))) USB_Wakeup_IRQHandler(void); 97 | void __attribute__((weak, alias("Default_Handler"))) TIM8_BRK_IRQHandler(void); 98 | void __attribute__((weak, alias("Default_Handler"))) TIM8_UP_IRQHandler(void); 99 | void __attribute__((weak, alias("Default_Handler"))) TIM8_TRG_COM_IRQHandler(void); 100 | void __attribute__((weak, alias("Default_Handler"))) TIM8_CC_IRQHandler(void); 101 | void __attribute__((weak, alias("Default_Handler"))) ADC3_IRQHandler(void); 102 | void __attribute__((weak, alias("Default_Handler"))) FSMC_IRQHandler(void); 103 | void __attribute__((weak, alias("Default_Handler"))) SDIO_IRQHandler(void); 104 | void __attribute__((weak, alias("Default_Handler"))) TIM5_IRQHandler(void); 105 | void __attribute__((weak, alias("Default_Handler"))) SPI3_IRQHandler(void); 106 | void __attribute__((weak, alias("Default_Handler"))) UART4_IRQHandler(void); 107 | void __attribute__((weak, alias("Default_Handler"))) UART5_IRQHandler(void); 108 | void __attribute__((weak, alias("Default_Handler"))) TIM6_IRQHandler(void); 109 | void __attribute__((weak, alias("Default_Handler"))) TIM7_IRQHandler(void); 110 | void __attribute__((weak, alias("Default_Handler"))) DMA2_Channel1_IRQHandler(void); 111 | void __attribute__((weak, alias("Default_Handler"))) DMA2_Channel2_IRQHandler(void); 112 | void __attribute__((weak, alias("Default_Handler"))) DMA2_Channel3_IRQHandler(void); 113 | void __attribute__((weak, alias("Default_Handler"))) DMA2_Channel4_5_IRQHandler(void); 114 | #endif -------------------------------------------------------------------------------- /dma-1shot/include/startup_stm32f1.h: -------------------------------------------------------------------------------- 1 | #include 2 | #ifndef __STARTUP_STM32F1_H__ 3 | #define __STARTUP_STM32F1_H__ 4 | 5 | /** 6 | * @brief Ending boundry of .text section in SRAM 7 | * This address does not belong to .text section 8 | */ 9 | extern uint32_t _etext; 10 | 11 | /** 12 | * @brief Starting address of .data section in SRAM 13 | */ 14 | extern uint32_t _sdata; 15 | 16 | /** 17 | * @brief Ending boundry of .data section in SRAM 18 | * This address does not belong to .data section 19 | */ 20 | extern uint32_t _edata; 21 | 22 | /** 23 | * @brief Starting address of .data section in FLASH 24 | */ 25 | extern uint32_t _la_data; 26 | 27 | /** 28 | * @brief Starting address of .bss section in SRAM 29 | */ 30 | extern uint32_t _sbss; 31 | 32 | /** 33 | * @brief Ending boundry of .bss section in SRAM 34 | * This address does not belong to .bss section 35 | */ 36 | extern uint32_t _ebss; 37 | 38 | /** 39 | * @brief Address to be set in the main stack pointer 40 | */ 41 | extern uint32_t _stack_top; 42 | 43 | void __attribute__((noreturn)) Reset_Handler(void); 44 | void __attribute__((noreturn)) Default_Handler(void); 45 | 46 | void __attribute__((weak, alias("Default_Handler"))) NMI_Handler(void); 47 | void __attribute__((weak, alias("Default_Handler"))) HardFault_Handler(void); 48 | void __attribute__((weak, alias("Default_Handler"))) MemManage_Handler(void); 49 | void __attribute__((weak, alias("Default_Handler"))) BusFault_Handler(void); 50 | void __attribute__((weak, alias("Default_Handler"))) UsageFault_Handler(void); 51 | void __attribute__((weak, alias("Default_Handler"))) SVC_Handler(void); 52 | void __attribute__((weak, alias("Default_Handler"))) DebugMon_Handler(void); 53 | void __attribute__((weak, alias("Default_Handler"))) PendSV_Handler(void); 54 | void __attribute__((weak, alias("Default_Handler"))) SysTick_Handler(void); 55 | void __attribute__((weak, alias("Default_Handler"))) WWDG_IRQHandler(void); 56 | void __attribute__((weak, alias("Default_Handler"))) PVD_IRQHandler(void); 57 | void __attribute__((weak, alias("Default_Handler"))) TAMP_STAMP_IRQHandler(void); 58 | void __attribute__((weak, alias("Default_Handler"))) RTC_WKUP_IRQHandler(void); 59 | void __attribute__((weak, alias("Default_Handler"))) RCC_IRQHandler(void); 60 | void __attribute__((weak, alias("Default_Handler"))) EXTI0_IRQHandler(void); 61 | void __attribute__((weak, alias("Default_Handler"))) EXTI1_IRQHandler(void); 62 | void __attribute__((weak, alias("Default_Handler"))) EXTI2_IRQHandler(void); 63 | void __attribute__((weak, alias("Default_Handler"))) EXTI3_IRQHandler(void); 64 | void __attribute__((weak, alias("Default_Handler"))) EXTI4_IRQHandler(void); 65 | void __attribute__((weak, alias("Default_Handler"))) DMA1_Channel1_IRQHandler(void); 66 | void __attribute__((weak, alias("Default_Handler"))) DMA1_Channel2_IRQHandler(void); 67 | void __attribute__((weak, alias("Default_Handler"))) DMA1_Channel3_IRQHandler(void); 68 | void __attribute__((weak, alias("Default_Handler"))) DMA1_Channel4_IRQHandler(void); 69 | void __attribute__((weak, alias("Default_Handler"))) DMA1_Channel5_IRQHandler(void); 70 | void __attribute__((weak, alias("Default_Handler"))) DMA1_Channel6_IRQHandler(void); 71 | void __attribute__((weak, alias("Default_Handler"))) DMA1_Channel7_IRQHandler(void); 72 | void __attribute__((weak, alias("Default_Handler"))) ADC_IRQHandler(void); 73 | void __attribute__((weak, alias("Default_Handler"))) USB_HP_CAN_TX_IRQHandler(void); 74 | void __attribute__((weak, alias("Default_Handler"))) USB_LP_CAN_RX0_IRQHandler(void); 75 | void __attribute__((weak, alias("Default_Handler"))) CAN_RX1_IRQHandler(void); 76 | void __attribute__((weak, alias("Default_Handler"))) CAN_SCE_IRQHandler(void); 77 | void __attribute__((weak, alias("Default_Handler"))) EXTI9_5_IRQHandler(void); 78 | void __attribute__((weak, alias("Default_Handler"))) TIM1_BRK_IRQHandler(void); 79 | void __attribute__((weak, alias("Default_Handler"))) TIM1_UP_IRQHandler(void); 80 | void __attribute__((weak, alias("Default_Handler"))) TIM1_TRG_COM_IRQHandler(void); 81 | void __attribute__((weak, alias("Default_Handler"))) TIM1_CC_IRQHandler(void); 82 | void __attribute__((weak, alias("Default_Handler"))) TIM2_IRQHandler(void); 83 | void __attribute__((weak, alias("Default_Handler"))) TIM3_IRQHandler(void); 84 | void __attribute__((weak, alias("Default_Handler"))) TIM4_IRQHandler(void); 85 | void __attribute__((weak, alias("Default_Handler"))) I2C1_EV_IRQHandler(void); 86 | void __attribute__((weak, alias("Default_Handler"))) I2C1_ER_IRQHandler(void); 87 | void __attribute__((weak, alias("Default_Handler"))) I2C2_EV_IRQHandler(void); 88 | void __attribute__((weak, alias("Default_Handler"))) I2C2_ER_IRQHandler(void); 89 | void __attribute__((weak, alias("Default_Handler"))) SPI1_IRQHandler(void); 90 | void __attribute__((weak, alias("Default_Handler"))) SPI2_IRQHandler(void); 91 | void __attribute__((weak, alias("Default_Handler"))) USART1_IRQHandler(void); 92 | void __attribute__((weak, alias("Default_Handler"))) USART2_IRQHandler(void); 93 | void __attribute__((weak, alias("Default_Handler"))) USART3_IRQHandler(void); 94 | void __attribute__((weak, alias("Default_Handler"))) EXTI15_10_IRQHandler(void); 95 | void __attribute__((weak, alias("Default_Handler"))) RTC_Alarm_IRQHandler(void); 96 | void __attribute__((weak, alias("Default_Handler"))) USB_Wakeup_IRQHandler(void); 97 | void __attribute__((weak, alias("Default_Handler"))) TIM8_BRK_IRQHandler(void); 98 | void __attribute__((weak, alias("Default_Handler"))) TIM8_UP_IRQHandler(void); 99 | void __attribute__((weak, alias("Default_Handler"))) TIM8_TRG_COM_IRQHandler(void); 100 | void __attribute__((weak, alias("Default_Handler"))) TIM8_CC_IRQHandler(void); 101 | void __attribute__((weak, alias("Default_Handler"))) ADC3_IRQHandler(void); 102 | void __attribute__((weak, alias("Default_Handler"))) FSMC_IRQHandler(void); 103 | void __attribute__((weak, alias("Default_Handler"))) SDIO_IRQHandler(void); 104 | void __attribute__((weak, alias("Default_Handler"))) TIM5_IRQHandler(void); 105 | void __attribute__((weak, alias("Default_Handler"))) SPI3_IRQHandler(void); 106 | void __attribute__((weak, alias("Default_Handler"))) UART4_IRQHandler(void); 107 | void __attribute__((weak, alias("Default_Handler"))) UART5_IRQHandler(void); 108 | void __attribute__((weak, alias("Default_Handler"))) TIM6_IRQHandler(void); 109 | void __attribute__((weak, alias("Default_Handler"))) TIM7_IRQHandler(void); 110 | void __attribute__((weak, alias("Default_Handler"))) DMA2_Channel1_IRQHandler(void); 111 | void __attribute__((weak, alias("Default_Handler"))) DMA2_Channel2_IRQHandler(void); 112 | void __attribute__((weak, alias("Default_Handler"))) DMA2_Channel3_IRQHandler(void); 113 | void __attribute__((weak, alias("Default_Handler"))) DMA2_Channel4_5_IRQHandler(void); 114 | #endif -------------------------------------------------------------------------------- /cpp/lib/gpio/gpio.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | /** 4 | * @file gpio.hpp 5 | * @author Rohit Nimkar (nehalnimkar@gmail.com) 6 | * @brief Declaration of functionality related to GPIO 7 | * @version 1.2 8 | * @date 2022-12-07 9 | * 10 | * @copyright Copyright (c) 2022 11 | * @attention 12 | * 13 | * This software component is licensed by Rohit Nimkar under BSD 3-Clause license, 14 | * the "License"; You may not use this file except in compliance with the 15 | * License. You may obtain a copy of the License at: opensource.org/licenses/BSD-3-Clause 16 | * 17 | */ 18 | 19 | 20 | #include 21 | #include 22 | 23 | #pragma once 24 | class GPIO 25 | { 26 | public: 27 | enum PIN : uint8_t; 28 | enum PIN_STATE : uint8_t; 29 | enum MODE : uint8_t; 30 | enum CNF : uint8_t; 31 | 32 | private: 33 | PIN pin; 34 | GPIO_TypeDef *PORT; 35 | 36 | public: 37 | /** 38 | * @brief GPIO port pins 39 | * 40 | */ 41 | enum PIN : uint8_t 42 | { 43 | PIN_0 = (uint8_t)0x0000, /* GPIO pin 0 */ 44 | PIN_1 = (uint8_t)0x0001, /* GPIO pin 1 */ 45 | PIN_2 = (uint8_t)0x0002, /* GPIO pin 2 */ 46 | PIN_3 = (uint8_t)0x0003, /* GPIO pin 3 */ 47 | PIN_4 = (uint8_t)0x0004, /* GPIO pin 4 */ 48 | PIN_5 = (uint8_t)0x0005, /* GPIO pin 5 */ 49 | PIN_6 = (uint8_t)0x0006, /* GPIO pin 6 */ 50 | PIN_7 = (uint8_t)0x0007, /* GPIO pin 7 */ 51 | PIN_8 = (uint8_t)0x0008, /* GPIO pin 8 */ 52 | PIN_9 = (uint8_t)0x0009, /* GPIO pin 9 */ 53 | PIN_10 = (uint8_t)0x000A, /* GPIO pin 10 */ 54 | PIN_11 = (uint8_t)0x000B, /* GPIO pin 11 */ 55 | PIN_12 = (uint8_t)0x000C, /* GPIO pin 12 */ 56 | PIN_13 = (uint8_t)0x000D, /* GPIO pin 13 */ 57 | PIN_14 = (uint8_t)0x000E, /* GPIO pin 14 */ 58 | PIN_15 = (uint8_t)0x000F, /* GPIO pin 15 */ 59 | PIN_ALL = (uint8_t)0xffff /* Select all gpio pins */ 60 | }; 61 | 62 | /** 63 | * @brief GPIO logical pin state 64 | * 65 | */ 66 | enum PIN_STATE : uint8_t 67 | { 68 | LOW = (uint8_t)0x00, /* Pin state logical LOW */ 69 | HIGH = (uint8_t)0x01 /* Pin state logical HIGH */ 70 | }; 71 | 72 | enum MODE : uint8_t 73 | { 74 | INPUT = (uint8_t)0b00, 75 | OUTPUT_10MHZ, 76 | OUTPUT_2MHZ, 77 | OUTPUT_50MHZ 78 | }; 79 | 80 | enum CNF : uint8_t 81 | { 82 | INPUT_ANALOG = (uint8_t)0b00, 83 | INPUT_FLOATING, 84 | INPUT_PULLUP_DOWN, 85 | INPUT_RESERVED, 86 | OUTPUT_PUSH_PULL = (uint8_t)0b00, 87 | OUTPUT_OPEN_DRAIN, 88 | OUTPUT_ALT_PUSH_PULL, 89 | OUTPUT_ALT_OPEN_DRAIN 90 | }; 91 | 92 | GPIO() : pin{PIN_0}, PORT{nullptr} 93 | { 94 | } 95 | 96 | GPIO(GPIO_TypeDef *port) : pin{PIN_0}, PORT{port} 97 | { 98 | } 99 | 100 | GPIO(const GPIO &gpio) : pin{gpio.pin}, PORT{gpio.PORT} 101 | { 102 | } 103 | 104 | GPIO &operator=(const GPIO &gpio); 105 | 106 | /** 107 | * @brief Construct a new GPIO object 108 | * 109 | * @param port POinter to port base address 110 | * @param newPin pin number 111 | */ 112 | GPIO(GPIO_TypeDef *port, PIN newPin) : pin{newPin}, PORT{port} {} 113 | 114 | /** 115 | * @brief Enable Clock source for GPIO port 116 | * @param port GPIO port instance 117 | */ 118 | constexpr static void enable_port(GPIO_TypeDef *port); 119 | 120 | /** 121 | * @brief Destroy the GPIO object 122 | */ 123 | ~GPIO(); 124 | 125 | /** 126 | * @brief Write HIGH logic to GPIO 127 | */ 128 | void high(); 129 | static void high(GPIO_TypeDef *port, PIN newPin); 130 | 131 | /** 132 | * @brief Write LOW logic to GPIO 133 | */ 134 | void low(); 135 | static void low(GPIO_TypeDef *port, PIN newPin); 136 | 137 | /** 138 | * @brief Toggle GPIO 139 | */ 140 | void toggle(); 141 | static void toggle(GPIO_TypeDef *port, PIN newPin); 142 | 143 | /** 144 | * @brief Set the state of GPIO pin 145 | * @param state new state to be set 146 | */ 147 | void write(PIN_STATE state); 148 | static void write(GPIO_TypeDef *port, PIN newPin, PIN_STATE state); 149 | 150 | void setMode(MODE mode); 151 | static void setMode(GPIO_TypeDef *port, PIN newPin, MODE mode); 152 | 153 | void setConfig(CNF cnf); 154 | static void setConfig(GPIO_TypeDef *port, PIN newPin, CNF cnf); 155 | }; 156 | 157 | inline GPIO &GPIO::operator=(const GPIO &gpio) 158 | { 159 | this->pin = gpio.pin; 160 | this->PORT = gpio.PORT; 161 | return *this; 162 | } 163 | 164 | constexpr inline void GPIO::enable_port(GPIO_TypeDef *port) 165 | { 166 | if (port == GPIOA) 167 | { 168 | RCC->APB2ENR |= RCC_APB2ENR_IOPAEN; 169 | } 170 | else if (port == GPIOB) 171 | { 172 | RCC->APB2ENR |= RCC_APB2ENR_IOPBEN; 173 | } 174 | else if (port == GPIOC) 175 | { 176 | RCC->APB2ENR |= RCC_APB2ENR_IOPCEN; 177 | } 178 | } 179 | 180 | inline void GPIO::setMode(MODE mode) 181 | { 182 | setMode(PORT, pin, mode); 183 | }; 184 | inline void GPIO::setMode(GPIO_TypeDef *port, PIN newPin, MODE mode) 185 | { 186 | if (newPin < PIN_8) 187 | { 188 | port->CRL &= ~(0b11 << (newPin << 2)); 189 | port->CRL |= mode << (newPin << 2); 190 | } 191 | else 192 | { 193 | port->CRH &= ~(0b11 << ((newPin - 8) << 2)); 194 | port->CRH |= mode << ((newPin - 8) << 2); 195 | } 196 | } 197 | inline void GPIO::setConfig(CNF config) 198 | { 199 | setConfig(PORT, pin, config); 200 | } 201 | inline void GPIO::setConfig(GPIO_TypeDef *port, PIN newPin, CNF config) 202 | { 203 | if (newPin < PIN_8) 204 | { 205 | port->CRL &= ~(0b11 << ((newPin << 2) + 2)); 206 | port->CRL |= config << ((newPin << 2) + 2); 207 | } 208 | else 209 | { 210 | port->CRH &= ~(0b11 << (((newPin - 8) << 2) + 2)); 211 | port->CRH |= config << (((newPin - 8) << 2) + 2); 212 | } 213 | } 214 | 215 | inline void GPIO::toggle() { this->PORT->ODR ^= 1 << this->pin; } 216 | inline void GPIO::toggle(GPIO_TypeDef *port, PIN newPin) { port->ODR ^= 1 << newPin; } 217 | 218 | inline void GPIO::write(PIN_STATE state) 219 | { 220 | if (state == HIGH) 221 | { 222 | high(); 223 | } 224 | else 225 | { 226 | low(); 227 | } 228 | }; 229 | inline void GPIO::write(GPIO_TypeDef *port, PIN newPin, PIN_STATE state) 230 | { 231 | if (state == HIGH) 232 | { 233 | high(port, newPin); 234 | } 235 | else 236 | { 237 | low(port, newPin); 238 | } 239 | }; 240 | 241 | inline void GPIO::high() { this->PORT->BSRR = 1 << this->pin; }; 242 | inline void GPIO::high(GPIO_TypeDef *port, PIN newPin) { port->BSRR = 1 << newPin; }; 243 | 244 | inline void GPIO::low() { this->PORT->BRR = 1 << this->pin; }; 245 | inline void GPIO::low(GPIO_TypeDef *port, PIN newPin) { port->BRR = 1 << newPin; }; 246 | -------------------------------------------------------------------------------- /polling/README.md: -------------------------------------------------------------------------------- 1 | # Blue Pill UART communication - Bare metal project in Embedded C 2 | 3 | ![Build Passing](https://img.shields.io/badge/build-passing-brightgreen) [![GPLv3 License](https://img.shields.io/badge/License-GPL%20v3-yellow.svg)](https://opensource.org/licenses/) 4 | 5 | Programming the UART1 peripheral in STM32F1 controller for bi-directional communication. Echo characters received from UART and transmit time elapsed since boot every 5 seconds. 6 | 7 | ## USART 8 | 9 | The controller has 3 USART peropherals with varying functionality. The peripheral registers can be accessed as half word (16 bit) as well as words (32 bit).\ 10 | This project uses USART1 with pinc PA9 and PA10 for demonstration. 11 | 12 | ## Hardware Setup 13 | 14 | Connect the board with host through USB to TTL converter (FTDI board in our case). The connections are described as follows. 15 | 16 | | Pin on Blue Pill | Pin on FTDI | 17 | |------------------ |------------- | 18 | | PA9 | Rx | 19 | | PA10 | Tx | 20 | | Gnd | Gnd | 21 | 22 | ![Connection diagram for USART1](https://github.com/csrohit/bluepill-uart/blob/main/docs/label.png "Pin connection diagram for usart1") 23 | 24 | 25 | ## Project Structure 26 | 27 | * `src` directory contains all source files for the project 28 | * `include` directory contains all header files for the project 29 | 30 | ### Source file description 31 | 32 | * `STM32F103C8TX_FLASH.ld` - linker script for generating elf file. 33 | * `src/main.c` - entry point of application and main code body. 34 | * `src/uart.c` - Contains definition of non-inline functions for uart. 35 | * `src/timer.c` - Contains definition of non-inline functions for SysTick timer. 36 | * `src/startup_stm32f103c8tx.s` - assembly startup script for blue pill board. 37 | * `include/uart.h` - Contains definitions of inline functions and declaration of all functions for uart. 38 | * `include/uart.h` - Contains definitions of inline functions and declarations of all functions for SysTick timer. 39 | * `system_stm32f1xx.c` - clock configuration and system initialization functions. 40 | * `STM32F103.svd` - contains the description of the system contained in Arm Cortex-M processor-based microcontrollers, in particular, the memory mapped registers of peripherals. 41 | 42 | 43 | ## Control flow 44 | 45 | The initialisation function accomplishes following tasks 46 | 47 | 1. Enables clock signal for USART1 peripheral as well as GPIO Port A, both are connected with APB2 bus. 48 | 49 | ```C 50 | RCC->APB2ENR |= RCC_APB2ENR_USART1EN | RCC_APB2ENR_IOPAEN; 51 | ``` 52 | 53 | 2. Reset mode and configuration for PA9 and PA10. 54 | 55 | ```C 56 | GPIOA->CRH &= ~(GPIO_CRH_MODE10 | GPIO_CRH_MODE9 | GPIO_CRH_CNF10 | GPIO_CRH_CNF9); 57 | ``` 58 | 59 | 3. Set appropriate mode and configuration for PA9 and PA10. 60 | * PA9 as push-pull output at 50MHz speed. 61 | * PA10 as floating input. 62 | 63 | ```C 64 | GPIOA->CRH |= GPIO_CRH_MODE9_0 | GPIO_CRH_MODE9_1 | GPIO_CRH_CNF9_1; 65 | GPIOA->CRH |= GPIO_CRH_CNF10_0; 66 | ``` 67 | 68 | 4. Calculate and set baud rate values in register. 69 | 70 | ```C 71 | uint32_t baud = (uint32_t)(SystemCoreClock / baudrate); 72 | USART1->BRR = baud; 73 | ``` 74 | 75 | 5. Enable transmitter, receiver, receiver interrupt and USART1 clock. 76 | 77 | ```C 78 | USART1->CR1 = USART_CR1_TE | USART_CR1_RE | USART_CR1_RXNEIE | USART_CR1_UE; 79 | ``` 80 | 81 | 6. Enable interrupt for USART1 82 | 83 | ```C 84 | NVIC_EnableIRQ(USART1_IRQn); 85 | ``` 86 | 87 | ![Control Flow Diagram](https://github.com/csrohit/bluepill-uart/blob/main/docs/github-cover.png "Control flow diagram for usart") 88 | 89 | ### Function description 90 | 91 | 1. `USART1_puts()` - prints a string to USART1. 92 | 2. `USART1_putc()` - waits for the transmit data register (`TDR`) to be empty and loads new character in it. 93 | 3. `USART1_IRQHandler()` - Interrupt service routine for USART1 related interrupts. If `RXNE` is set i.e. receiver not empty interrupt then it echoes the character back to usart. 94 | 95 | ## Project Working 96 | 97 | The application prints time elapsed since boot in interval of 5 seconds. Configure serial onitor on host for 9600 baudrate to be able to read and write to blue pill using uart. The expected output is displayed in the *Output* section. 98 | 99 | ## Dependencies 100 | 101 | * **make**\ 102 | Make utility is required for configuring and building this project. You can install make on linux by running command: 103 | 104 | ```bash 105 | # for debian/ubuntu 106 | sudo apt install build-essential 107 | 108 | # for macos 109 | brew install make 110 | ``` 111 | 112 | * **gcc-arm-none-eabi toolchain**\ 113 | ARM cross-platform toolchain is required to build applications for arm mcus. Toolchain can be installed by running following command: 114 | 115 | ```bash 116 | sudo apt install gcc-arm-none-eabi 117 | ``` 118 | * For mac, visit [ARM Downloads](https://developer.arm.com/downloads/-/gnu-rm) page to install arm embedded toolchain. 119 | 120 | * **openocd**\ 121 | It is an Open On Circuit Debugging tool used to flash and debug arm micro controllers. You can install openocd on linux by running command: 122 | 123 | ```bash 124 | # for debian/ubuntu 125 | sudo apt install openocd -y 126 | 127 | # for macos 128 | brew install openocd 129 | ``` 130 | 131 | * **Cortex Debug extension**\ 132 | This extension for VSCode is helpful for debugging the application on Blue Pill. The contents of registers as well as memory are visible in the context menu. 133 | Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter. 134 | 135 | ```bash 136 | ext install marus25.cortex-debug 137 | ``` 138 | 139 | ## Run Locally 140 | 141 | Running the project is super easy. Just clone, build, and flash. 142 | 143 | ### Clone the project 144 | 145 | 1. Using https 146 | 147 | ```bash 148 | git clone git@github.com:csrohit/bluepill-uart.git 149 | cd bluepill-uart/baremetal 150 | ``` 151 | 152 | 2. Using ssh 153 | 154 | ```bash 155 | git clone git@github.com:csrohit/bluepill-uart.git 156 | cd bluepill-uart/baremetal 157 | ``` 158 | 159 | ### Configuration 160 | 161 | All the configuration required for building this project is given below. 162 | 163 | 1. Build output directory 164 | In `Makefile`, output directory can be configured using variable `BUILD_DIR`. 165 | 166 | 2. Build type 167 | In `Makefile`, build type can be configured using variable`DEBUG`. Possible values are `Debug` and `Release`. 168 | 169 | 170 | ### Build 171 | 172 | Run following command in terminal to generate flashable binaries for blue pill board. Build files will be written to **Build Output Directory** as configured. 173 | 174 | ```bash 175 | make all 176 | ``` 177 | 178 | ### Flash 179 | 180 | 1. Connect STlink to PC and blue pill board using swd headers. 181 | 2. Put blue pill board in programming mode. 182 | 3. Run following to flash board with binary. 183 | 184 | ```bash 185 | make flash 186 | ``` 187 | 188 | ## Output 189 | 190 | The following output should be available on serial monitor. 191 | 192 | ![Output on Serial monitor](https://github.com/csrohit/bluepill-uart/blob/main/docs/output.jpg "Serial messages printed on monitor") 193 | 194 | 195 | ## Debug 196 | 197 | Click in `Run and Debug` option in VsCode sidebar. Then launch `Cortex Debug` target. 198 | 199 | Happy debugging.... 200 | -------------------------------------------------------------------------------- /cpp/src/startup_stm32f103.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file startup_stm32f1.cpp 3 | * @author Rohit Nimkar (nehalnimkar@gmail.com) 4 | * @brief startup declarations and function for the STM32F1 series controllers 5 | * See: RM0008 10.1.2 Interrupt and exception vectors, Table 63. Vector table for other STM32F10xxx devices 6 | * 7 | * @version 1.2 8 | * @date 2022-12-07 9 | * 10 | * @copyright Copyright (c) 2022 11 | * @attention 12 | * 13 | * This software component is licensed by Rohit Nimkar under BSD 3-Clause license, 14 | * the "License"; You may not use this file except in compliance with the 15 | * License. You may obtain a copy of the License at: opensource.org/licenses/BSD-3-Clause 16 | * 17 | */ 18 | 19 | 20 | #include 21 | 22 | 23 | extern uint32_t _etext; 24 | extern uint32_t _sdata; 25 | extern uint32_t _edata; 26 | extern uint32_t _la_data; 27 | 28 | extern uint32_t _sbss; 29 | extern uint32_t _ebss; 30 | extern uint32_t _stack_top; 31 | 32 | int main(void); 33 | 34 | extern "C" 35 | { 36 | /** 37 | * @brief Infinite while loop 38 | * 39 | */ 40 | [[noreturn]] void Reset_Handler(void); 41 | 42 | /** 43 | * @brief Initialize .data and .bss sections, call CMSIS systemInit and main functions 44 | */ 45 | void Default_Handler(void); 46 | } 47 | 48 | // Weak function prototypes for the vector table so that they can easily be redefined 49 | void NMI_Handler(void) __attribute__((weak, alias("Default_Handler"))); 50 | void HardFault_Handler(void) __attribute__((weak, alias("Default_Handler"))); 51 | void MemManage_Handler(void) __attribute__((weak, alias("Default_Handler"))); 52 | void BusFault_Handler(void) __attribute__((weak, alias("Default_Handler"))); 53 | void UsageFault_Handler(void) __attribute__((weak, alias("Default_Handler"))); 54 | void SVC_Handler(void) __attribute__((weak, alias("Default_Handler"))); 55 | void DebugMon_Handler(void) __attribute__((weak, alias("Default_Handler"))); 56 | void PendSV_Handler(void) __attribute__((weak, alias("Default_Handler"))); 57 | void SysTick_Handler(void) __attribute__((weak, alias("Default_Handler"))); 58 | void WWDG_IRQHandler(void) __attribute__((weak, alias("Default_Handler"))); 59 | void PVD_IRQHandler(void) __attribute__((weak, alias("Default_Handler"))); 60 | void TAMP_STAMP_IRQHandler(void) __attribute__((weak, alias("Default_Handler"))); 61 | void RTC_WKUP_IRQHandler(void) __attribute__((weak, alias("Default_Handler"))); 62 | void RCC_IRQHandler(void) __attribute__((weak, alias("Default_Handler"))); 63 | void EXTI0_IRQHandler(void) __attribute__((weak, alias("Default_Handler"))); 64 | void EXTI1_IRQHandler(void) __attribute__((weak, alias("Default_Handler"))); 65 | void EXTI2_IRQHandler(void) __attribute__((weak, alias("Default_Handler"))); 66 | void EXTI3_IRQHandler(void) __attribute__((weak, alias("Default_Handler"))); 67 | void EXTI4_IRQHandler(void) __attribute__((weak, alias("Default_Handler"))); 68 | void DMA1_Channel1_IRQHandler(void) __attribute__((weak, alias("Default_Handler"))); 69 | void DMA1_Channel2_IRQHandler(void) __attribute__((weak, alias("Default_Handler"))); 70 | void DMA1_Channel3_IRQHandler(void) __attribute__((weak, alias("Default_Handler"))); 71 | void DMA1_Channel4_IRQHandler(void) __attribute__((weak, alias("Default_Handler"))); 72 | void DMA1_Channel5_IRQHandler(void) __attribute__((weak, alias("Default_Handler"))); 73 | void DMA1_Channel6_IRQHandler(void) __attribute__((weak, alias("Default_Handler"))); 74 | void DMA1_Channel7_IRQHandler(void) __attribute__((weak, alias("Default_Handler"))); 75 | void ADC_IRQHandler(void) __attribute__((weak, alias("Default_Handler"))); 76 | void USB_HP_CAN_TX_IRQHandler(void) __attribute__((weak, alias("Default_Handler"))); 77 | void USB_LP_CAN_RX0_IRQHandler(void) __attribute__((weak, alias("Default_Handler"))); 78 | void CAN_RX1_IRQHandler(void) __attribute__((weak, alias("Default_Handler"))); 79 | void CAN_SCE_IRQHandler(void) __attribute__((weak, alias("Default_Handler"))); 80 | void EXTI9_5_IRQHandler(void) __attribute__((weak, alias("Default_Handler"))); 81 | void TIM1_BRK_IRQHandler(void) __attribute__((weak, alias("Default_Handler"))); 82 | void TIM1_UP_IRQHandler(void) __attribute__((weak, alias("Default_Handler"))); 83 | void TIM1_TRG_COM_IRQHandler(void) __attribute__((weak, alias("Default_Handler"))); 84 | void TIM1_CC_IRQHandler(void) __attribute__((weak, alias("Default_Handler"))); 85 | void TIM2_IRQHandler(void) __attribute__((weak, alias("Default_Handler"))); 86 | void TIM3_IRQHandler(void) __attribute__((weak, alias("Default_Handler"))); 87 | void TIM4_IRQHandler(void) __attribute__((weak, alias("Default_Handler"))); 88 | void I2C1_EV_IRQHandler(void) __attribute__((weak, alias("Default_Handler"))); 89 | void I2C1_ER_IRQHandler(void) __attribute__((weak, alias("Default_Handler"))); 90 | void I2C2_EV_IRQHandler(void) __attribute__((weak, alias("Default_Handler"))); 91 | void I2C2_ER_IRQHandler(void) __attribute__((weak, alias("Default_Handler"))); 92 | void SPI1_IRQHandler(void) __attribute__((weak, alias("Default_Handler"))); 93 | void SPI2_IRQHandler(void) __attribute__((weak, alias("Default_Handler"))); 94 | void USART1_IRQHandler(void) __attribute__((weak, alias("Default_Handler"))); 95 | void USART2_IRQHandler(void) __attribute__((weak, alias("Default_Handler"))); 96 | void USART3_IRQHandler(void) __attribute__((weak, alias("Default_Handler"))); 97 | void EXTI15_10_IRQHandler(void) __attribute__((weak, alias("Default_Handler"))); 98 | void RTC_Alarm_IRQHandler(void) __attribute__((weak, alias("Default_Handler"))); 99 | void USB_Wakeup_IRQHandler(void) __attribute__((weak, alias("Default_Handler"))); 100 | 101 | // Define the veector table 102 | uint32_t vectors[] __attribute__((section(".isr_vector"))) = { 103 | (uint32_t)&_stack_top, 104 | (uint32_t)Reset_Handler, 105 | (uint32_t)NMI_Handler, 106 | (uint32_t)HardFault_Handler, 107 | (uint32_t)MemManage_Handler, 108 | (uint32_t)BusFault_Handler, 109 | (uint32_t)UsageFault_Handler, 110 | 0, // reserved 111 | 0, // reserved 112 | 0, // reserved 113 | 0, // reserved 114 | (uint32_t)SVC_Handler, 115 | (uint32_t)DebugMon_Handler, 116 | 0, // reserved 117 | (uint32_t)PendSV_Handler, 118 | (uint32_t)SysTick_Handler, 119 | (uint32_t)WWDG_IRQHandler, 120 | (uint32_t)PVD_IRQHandler, 121 | (uint32_t)TAMP_STAMP_IRQHandler, 122 | (uint32_t)RTC_WKUP_IRQHandler, 123 | 0, // Flash global interrupt 124 | (uint32_t)RCC_IRQHandler, 125 | (uint32_t)EXTI0_IRQHandler, 126 | (uint32_t)EXTI1_IRQHandler, 127 | (uint32_t)EXTI2_IRQHandler, 128 | (uint32_t)EXTI3_IRQHandler, 129 | (uint32_t)EXTI4_IRQHandler, 130 | (uint32_t)DMA1_Channel1_IRQHandler, 131 | (uint32_t)DMA1_Channel2_IRQHandler, 132 | (uint32_t)DMA1_Channel3_IRQHandler, 133 | (uint32_t)DMA1_Channel4_IRQHandler, 134 | (uint32_t)DMA1_Channel5_IRQHandler, 135 | (uint32_t)DMA1_Channel6_IRQHandler, 136 | (uint32_t)DMA1_Channel7_IRQHandler, 137 | (uint32_t)ADC_IRQHandler, 138 | (uint32_t)USB_HP_CAN_TX_IRQHandler, 139 | (uint32_t)USB_LP_CAN_RX0_IRQHandler, 140 | (uint32_t)CAN_RX1_IRQHandler, 141 | (uint32_t)CAN_SCE_IRQHandler, 142 | (uint32_t)EXTI9_5_IRQHandler, 143 | (uint32_t)TIM1_BRK_IRQHandler, 144 | (uint32_t)TIM1_UP_IRQHandler, 145 | (uint32_t)TIM1_TRG_COM_IRQHandler, 146 | (uint32_t)TIM1_CC_IRQHandler, 147 | (uint32_t)TIM2_IRQHandler, 148 | (uint32_t)TIM3_IRQHandler, 149 | (uint32_t)TIM4_IRQHandler, 150 | (uint32_t)I2C1_EV_IRQHandler, 151 | (uint32_t)I2C1_ER_IRQHandler, 152 | (uint32_t)I2C2_EV_IRQHandler, 153 | (uint32_t)I2C2_ER_IRQHandler, 154 | (uint32_t)SPI1_IRQHandler, 155 | (uint32_t)SPI2_IRQHandler, 156 | (uint32_t)USART1_IRQHandler, 157 | (uint32_t)USART2_IRQHandler, 158 | (uint32_t)USART3_IRQHandler, 159 | (uint32_t)EXTI15_10_IRQHandler, 160 | (uint32_t)RTC_Alarm_IRQHandler, 161 | (uint32_t)USB_Wakeup_IRQHandler 162 | }; 163 | 164 | 165 | void Default_Handler(void) 166 | { 167 | while (1) 168 | ; 169 | } 170 | 171 | // Command: reset memory and restart user program 172 | [[noreturn]] void Reset_Handler(void) 173 | { 174 | 175 | uint32_t *start_sram = (uint32_t *)&_sdata; 176 | uint32_t *start_flash = (uint32_t *)&_la_data; 177 | while (start_sram < (uint32_t *)&_edata) 178 | { 179 | *start_sram++ = *start_flash++; 180 | } 181 | 182 | uint32_t *start_bss = (uint32_t *)&_sbss; 183 | while (start_bss < (uint32_t *)&_ebss) 184 | { 185 | *start_bss++ = 0; 186 | } 187 | 188 | // now invoke main 189 | main(); 190 | while (1) 191 | { 192 | __asm("nop"); 193 | } 194 | } -------------------------------------------------------------------------------- /cpp/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 | -------------------------------------------------------------------------------- /cpp/lib/dma/dma_channel.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file dma_channel.hpp 3 | * @author Rohit Nimkar (nehalnimkar@gmail.com) 4 | * @brief Declaration of functionality related to dma channel 5 | * @version 1.2 6 | * @date 2022-12-07 7 | * 8 | * @copyright Copyright (c) 2022 9 | * @attention 10 | * 11 | * This software component is licensed by Rohit Nimkar under BSD 3-Clause license, 12 | * the "License"; You may not use this file except in compliance with the 13 | * License. You may obtain a copy of the License at: opensource.org/licenses/BSD-3-Clause 14 | * 15 | */ 16 | #include 17 | #include "dma.hpp" 18 | #include 19 | #include 20 | #pragma once 21 | 22 | class DMA_Channel 23 | { 24 | private: 25 | public: 26 | // constexpr static 27 | typedef uint8_t dir_t; 28 | constexpr static dir_t PeripheralToMemory = 0; 29 | constexpr static dir_t MemoryToPeripheral = 1; 30 | 31 | typedef uint8_t mem_peri_size_t; 32 | constexpr static mem_peri_size_t BIT_8 = 0x00; 33 | constexpr static mem_peri_size_t BIT_16 = 0x01; 34 | constexpr static mem_peri_size_t BIT_32 = 0x02; 35 | 36 | typedef uint8_t prio_t; 37 | constexpr static prio_t LOW = 0x00; 38 | constexpr static prio_t MEDIUM = 0x01; 39 | constexpr static prio_t HIGH = 0x02; 40 | constexpr static prio_t VERYHIGH = 0x03; 41 | 42 | typedef uint32_t intr_t; 43 | constexpr static intr_t TransferComplete = DMA_CCR_TCIE; 44 | constexpr static intr_t HalfTransferComplete = DMA_CCR_HTIE; 45 | constexpr static intr_t TransferError = DMA_CCR_TEIE; 46 | 47 | private: 48 | /** 49 | * @brief Channel Configuration register 50 | */ 51 | volatile uint32_t CCR; 52 | 53 | /** 54 | * @brief Number of data to be transferred (0 up to 65535). 55 | * This register can only be written when the channel is disabled. 56 | * Once the channel is enabled, this register is read-only, indicating the remaining bytes to be transmitted. 57 | * 58 | * This register decrements after each DMA transfer. 59 | * Once the transfer is completed, this register can either stay at zero or be reloaded automatically by the value previously programmed if the channel is configured in auto- reload mode. 60 | * 61 | * If this register is zero, no transaction can be served whether the channel is enabled or not. 62 | */ 63 | volatile uint32_t CNDTR; 64 | 65 | /** 66 | * @brief Channel Peripheral address register 67 | * Base address of the peripheral data register from/to which the data will be read/written. 68 | * When PSIZE is 01 (16-bit), the PA[0] bit is ignored. Access is automatically aligned to a half- word address. 69 | * When PSIZE is 10 (32-bit), PA[1:0] are ignored. Access is automatically aligned to a word address. 70 | * 71 | */ 72 | volatile uint32_t *CPAR; 73 | 74 | /** 75 | * @brief Channel Memory address register 76 | * Base address of the memory area from/to which the data will be read/written. 77 | * When MSIZE is 01 (16-bit), the MA[0] bit is ignored. Access is automatically aligned to a half-word address. 78 | * When MSIZE is 10 (32-bit), MA[1:0] are ignored. Access is automatically aligned to a word address. 79 | * 80 | */ 81 | volatile uint32_t *CMAR; 82 | 83 | public: 84 | /** 85 | * @brief Get the instance DMA channel 86 | * 87 | * @param dma_channel_base Base address of the DMA channel 88 | * @return DMA_Channel* pointer to the DMA_Channel object 89 | */ 90 | inline static DMA_Channel *get_instance(DMA_Channel_TypeDef *dma_channel_base) 91 | { 92 | return static_cast(static_cast(dma_channel_base)); 93 | } 94 | 95 | /** 96 | * @brief Reload the pe ding transactions value register 97 | * 98 | * @param value value to be reloaded into the counter 99 | */ 100 | constexpr inline void reload(uint16_t value) 101 | { 102 | CNDTR = 0x0000ffff & value; 103 | } 104 | 105 | /** 106 | * @brief Start the DMA channel to accept the requests from memory/peripheral 107 | */ 108 | inline void start() 109 | { 110 | CCR |= DMA_CCR_EN; 111 | } 112 | 113 | /** 114 | * @brief Stop the DMA from accepting trnasction requests from memory/peripherals 115 | */ 116 | inline void stop() 117 | { 118 | this->CCR |= DMA_CCR_EN; 119 | } 120 | 121 | /** 122 | * @brief Set the peripheral address for DMA Channel 123 | * 124 | * @param address address of the peripheral data register 125 | */ 126 | inline void setPeripheralAddress(uint32_t *address) 127 | { 128 | this->CPAR = address; 129 | } 130 | 131 | /** 132 | * @brief Set the memory address for DMA Channel 133 | * @param address starting address of the memory 134 | */ 135 | inline void setMemoryAddress(uint32_t *address) 136 | { 137 | this->CMAR = address; 138 | } 139 | 140 | /** 141 | * @brief Enable interrupt for the DMA channel 142 | * @param interrupt interrupt to be enabled 143 | */ 144 | inline void enableInterrupt(intr_t interrupt) 145 | { 146 | uint32_t bits = 0; 147 | if ((interrupt & TransferComplete) > 0) 148 | { 149 | bits |= DMA_CCR_TCIE; 150 | } 151 | 152 | if ((interrupt & TransferError) > 0) 153 | { 154 | bits |= DMA_CCR_TEIE; 155 | } 156 | 157 | if ((interrupt & HalfTransferComplete) > 0) 158 | { 159 | bits |= DMA_CCR_HTIE; 160 | } 161 | 162 | this->CCR |= bits; 163 | } 164 | 165 | /** 166 | * @brief Disable the interrupt for the DMA Channel 167 | * @param interrupt interrupt to be disabled 168 | */ 169 | inline void disableInterrupt(intr_t interrupt) 170 | { 171 | uint32_t bits = 0; 172 | if (interrupt & TransferComplete) 173 | { 174 | bits |= DMA_CCR_TCIE; 175 | } 176 | 177 | if (interrupt & TransferError) 178 | { 179 | bits |= DMA_CCR_TEIE; 180 | } 181 | 182 | if (interrupt & HalfTransferComplete) 183 | { 184 | bits |= DMA_CCR_HTIE; 185 | } 186 | 187 | this->CCR &= ~bits; 188 | } 189 | 190 | /** 191 | * @brief Set the transfer direction for the transaction 192 | * The direction can be Memory to Peripheral or from Peripheral to Memory 193 | * @param direction the direction of the DMA Transaction 194 | */ 195 | inline void setTransferDirection(dir_t direction) 196 | { 197 | if (direction == PeripheralToMemory) 198 | { 199 | this->CCR &= ~DMA_CCR_DIR; 200 | } 201 | else 202 | { 203 | this->CCR |= DMA_CCR_DIR; 204 | } 205 | } 206 | 207 | /** 208 | * @brief Enable DMA Channel in circular mode 209 | * After the number of transations pending reaches 0, the initial number of transactions is reloaded. 210 | * The memory and peripheral address are reloaded to the initial values and transaction starts again 211 | */ 212 | inline void enableCircularMode() 213 | { 214 | this->CCR |= DMA_CCR_CIRC; 215 | } 216 | 217 | /** 218 | * @brief Disable circular mode 219 | * DMA stops after the current transaction is completed 220 | */ 221 | inline void disableCircularMode() 222 | { 223 | this->CCR &= ~DMA_CCR_CIRC; 224 | } 225 | 226 | /** 227 | * @brief Enable memory to memory mode 228 | */ 229 | inline void enableMem2MemMode() 230 | { 231 | CCR |= DMA_CCR_MEM2MEM; 232 | } 233 | 234 | /** 235 | * @brief Disable memory to memory mode 236 | */ 237 | inline void disableMem2MemMode() 238 | { 239 | CCR &= ~DMA_CCR_MEM2MEM; 240 | } 241 | 242 | /** 243 | * @brief Enable peripheral increment mode 244 | * After every transfter the peripheral address is incremented by the specified increment value 245 | */ 246 | inline void enablePeripheralIncrementMode() 247 | { 248 | this->CCR |= DMA_CCR_PINC; 249 | } 250 | 251 | /** 252 | * @brief Disable peripheral increment mode 253 | * The peripheral address remains same for all the transactions 254 | */ 255 | inline void disablePeripheralIncrementMode() 256 | { 257 | this->CCR &= ~DMA_CCR_PINC; 258 | } 259 | /** 260 | * @brief Enable memory increment mode 261 | * After every transfter the memory address is incremented by the specified increment value 262 | */ 263 | inline void enableMemoryIncrementMode() 264 | { 265 | this->CCR |= DMA_CCR_MINC; 266 | } 267 | /** 268 | * @brief Disable memory increment mode 269 | * The memory address remains same for all the transactions 270 | */ 271 | inline void disableMemoryIncrementMode() 272 | { 273 | this->CCR &= ~DMA_CCR_MINC; 274 | } 275 | 276 | /** 277 | * @brief Set the peripheral size 278 | * If enabled the peripheral address will be incremented by this number 279 | * @param size size of the peripheral 280 | */ 281 | inline void set_peripheral_size(mem_peri_size_t size) 282 | { 283 | this->CCR &= DMA_CCR_PSIZE; 284 | this->CCR |= (size & 0b11) << DMA_CCR_PSIZE_Pos; 285 | } 286 | /** 287 | * @brief Set the memory size 288 | * If enabled the memory address will be incremented by this number 289 | * @param size size of the memory 290 | */ 291 | inline void set_memory_size(mem_peri_size_t size) 292 | { 293 | this->CCR &= DMA_CCR_MSIZE; 294 | this->CCR |= (size & 0b11) << DMA_CCR_MSIZE_Pos; 295 | } 296 | 297 | /** 298 | * @brief Set the channel priority level 299 | * The conflicts between the different DMA channels are reolved according tho the assigned priority 300 | * @param prio priority for the channel 301 | */ 302 | inline void set_priority(prio_t prio) 303 | { 304 | this->CCR &= ~DMA_CCR_PL; 305 | this->CCR |= (prio & 0b11) << DMA_CCR_PL_Pos; 306 | } 307 | }; 308 | 309 | static_assert(sizeof(DMA_Channel) == 16, "Invalid size"); -------------------------------------------------------------------------------- /dma-1shot/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 | -------------------------------------------------------------------------------- /dma-echo/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 | --------------------------------------------------------------------------------