├── .clang-format ├── .github └── workflows │ └── releaseSTM32_Expander.yml ├── .gitignore ├── Arduino_Expander ├── .gitignore ├── .vscode │ └── extensions.json ├── README.md ├── include │ ├── README │ ├── gpio_pin.h │ └── gpiomap.h ├── platformio.ini ├── src │ ├── gpio_pin.cpp │ ├── gpiomap.cpp │ └── main.cpp └── test │ └── README ├── DisplayToTerminal ├── .gitignore ├── .vscode │ └── extensions.json ├── README.md ├── include │ └── README ├── platformio.ini ├── src │ └── main.cpp └── test │ └── README ├── LICENSE ├── LilyGo_T_S3 ├── .gitignore ├── arduino_settings.png ├── include │ ├── fnc.h │ └── pin_config.h ├── pinout.png ├── platformio.ini └── src │ └── main.cpp ├── Playlist ├── .gitignore ├── .vscode │ └── extensions.json ├── README.md ├── include │ └── README ├── platformio.ini ├── src │ └── main.cpp └── test │ └── README ├── README.md ├── RunLED ├── .gitignore ├── README.md ├── include │ └── README ├── platformio.ini ├── src │ └── main.cpp └── test │ └── README ├── STM32_Expander ├── .gitignore ├── .vscode │ └── extensions.json ├── CubeMX │ ├── .clang-format │ ├── .mxproject │ ├── Core │ │ ├── Inc │ │ │ └── stm32f1xx_hal_conf.h │ │ └── Src │ │ │ └── system_stm32f1xx.c │ ├── Drivers │ │ ├── CMSIS │ │ │ ├── Device │ │ │ │ └── ST │ │ │ │ │ └── STM32F1xx │ │ │ │ │ ├── Include │ │ │ │ │ ├── stm32f103xb.h │ │ │ │ │ ├── stm32f1xx.h │ │ │ │ │ └── system_stm32f1xx.h │ │ │ │ │ └── LICENSE.txt │ │ │ ├── Include │ │ │ │ ├── cmsis_armcc.h │ │ │ │ ├── cmsis_armclang.h │ │ │ │ ├── cmsis_compiler.h │ │ │ │ ├── cmsis_gcc.h │ │ │ │ ├── cmsis_iccarm.h │ │ │ │ ├── cmsis_version.h │ │ │ │ ├── core_armv8mbl.h │ │ │ │ ├── core_armv8mml.h │ │ │ │ ├── core_cm0.h │ │ │ │ ├── core_cm0plus.h │ │ │ │ ├── core_cm1.h │ │ │ │ ├── core_cm23.h │ │ │ │ ├── core_cm3.h │ │ │ │ ├── core_cm33.h │ │ │ │ ├── core_cm4.h │ │ │ │ ├── core_cm7.h │ │ │ │ ├── core_sc000.h │ │ │ │ ├── core_sc300.h │ │ │ │ ├── mpu_armv7.h │ │ │ │ ├── mpu_armv8.h │ │ │ │ └── tz_context.h │ │ │ └── LICENSE.txt │ │ └── STM32F1xx_HAL_Driver │ │ │ ├── Inc │ │ │ ├── Legacy │ │ │ │ └── stm32_hal_legacy.h │ │ │ ├── stm32f1xx_hal.h │ │ │ ├── stm32f1xx_hal_cortex.h │ │ │ ├── stm32f1xx_hal_def.h │ │ │ ├── stm32f1xx_hal_dma.h │ │ │ ├── stm32f1xx_hal_dma_ex.h │ │ │ ├── stm32f1xx_hal_exti.h │ │ │ ├── stm32f1xx_hal_flash.h │ │ │ ├── stm32f1xx_hal_flash_ex.h │ │ │ ├── stm32f1xx_hal_gpio.h │ │ │ ├── stm32f1xx_hal_gpio_ex.h │ │ │ ├── stm32f1xx_hal_pwr.h │ │ │ ├── stm32f1xx_hal_rcc.h │ │ │ ├── stm32f1xx_hal_rcc_ex.h │ │ │ ├── stm32f1xx_hal_tim.h │ │ │ ├── stm32f1xx_hal_tim_ex.h │ │ │ ├── stm32f1xx_hal_uart.h │ │ │ ├── stm32f1xx_ll_bus.h │ │ │ ├── stm32f1xx_ll_cortex.h │ │ │ ├── stm32f1xx_ll_dma.h │ │ │ ├── stm32f1xx_ll_exti.h │ │ │ ├── stm32f1xx_ll_gpio.h │ │ │ ├── stm32f1xx_ll_pwr.h │ │ │ ├── stm32f1xx_ll_rcc.h │ │ │ ├── stm32f1xx_ll_system.h │ │ │ ├── stm32f1xx_ll_tim.h │ │ │ ├── stm32f1xx_ll_usart.h │ │ │ └── stm32f1xx_ll_utils.h │ │ │ ├── LICENSE.txt │ │ │ └── Src │ │ │ ├── stm32f1xx_hal.c │ │ │ ├── stm32f1xx_hal_cortex.c │ │ │ ├── stm32f1xx_hal_dma.c │ │ │ ├── stm32f1xx_hal_exti.c │ │ │ ├── stm32f1xx_hal_flash.c │ │ │ ├── stm32f1xx_hal_flash_ex.c │ │ │ ├── stm32f1xx_hal_gpio.c │ │ │ ├── stm32f1xx_hal_gpio_ex.c │ │ │ ├── stm32f1xx_hal_pwr.c │ │ │ ├── stm32f1xx_hal_rcc.c │ │ │ ├── stm32f1xx_hal_rcc_ex.c │ │ │ ├── stm32f1xx_hal_tim.c │ │ │ ├── stm32f1xx_hal_tim_ex.c │ │ │ └── stm32f1xx_hal_uart.c │ ├── Makefile │ ├── STM32F103C8Tx_FLASH.ld │ ├── USART1_DMAv3.ioc │ ├── USART1_DMAv3.pdf │ ├── USART1_DMAv3.txt │ └── startup_stm32f103xb.S ├── git-version.py ├── platformio.ini └── src │ ├── app.c │ ├── boards │ ├── airedale_v1_1 │ │ └── gpiomap.c │ ├── protov0 │ │ └── gpiomap.c │ └── protov1 │ │ └── gpiomap.c │ ├── dma_uart.c │ ├── dma_uart.h │ ├── gpio_pin.c │ ├── gpio_pin.h │ ├── gpiomap.h │ ├── pwm_pin.c │ ├── pwm_pin.h │ ├── system.c │ ├── system.h │ └── version.c └── lib ├── .clang-format └── Expander └── src ├── Expander.c ├── Expander.h ├── pin.c ├── pin.h └── pinmode.h /.clang-format: -------------------------------------------------------------------------------- 1 | --- 2 | AccessModifierOffset: '-4' 3 | AlignAfterOpenBracket: Align 4 | AlignConsecutiveAssignments: 'true' 5 | AlignConsecutiveDeclarations: 'true' 6 | AlignEscapedNewlines: Right 7 | AlignOperands: 'true' 8 | AlignTrailingComments: 'true' 9 | AllowShortBlocksOnASingleLine: 'true' 10 | AllowShortCaseLabelsOnASingleLine: 'false' 11 | AllowShortFunctionsOnASingleLine: Inline 12 | AllowShortIfStatementsOnASingleLine: 'false' 13 | AllowShortLoopsOnASingleLine: 'false' 14 | AlwaysBreakBeforeMultilineStrings: 'false' 15 | AlwaysBreakTemplateDeclarations: 'true' 16 | BinPackArguments: 'false' 17 | BinPackParameters: 'false' 18 | BreakBeforeBinaryOperators: None 19 | BraceWrapping: 20 | AfterClass: 'true' 21 | AfterControlStatement: 'true' 22 | AfterEnum: 'true' 23 | AfterFunction: 'true' 24 | AfterNamespace: 'true' 25 | AfterObjCDeclaration: 'true' 26 | AfterStruct: 'true' 27 | AfterUnion: 'true' 28 | AfterExternBlock: 'true' 29 | BeforeCatch: 'true' 30 | BeforeElse: 'true' 31 | SplitEmptyFunction: 'false' 32 | SplitEmptyRecord: 'false' 33 | SplitEmptyNamespace: 'false' 34 | BreakBeforeInheritanceComma: 'true' 35 | BreakBeforeTernaryOperators: 'false' 36 | BreakConstructorInitializers: AfterColon 37 | BreakInheritanceList: AfterColon 38 | ColumnLimit: '140' 39 | CommentPragmas: '^ :: ' 40 | CompactNamespaces: 'false' 41 | Cpp11BracedListStyle: 'false' 42 | FixNamespaceComments: 'false' 43 | IncludeCategories: 44 | - Regex: '^".*' 45 | Priority: 1 46 | - Regex: '^"(.*)/' 47 | Priority: 2 48 | - Regex: '^<(.*)/' 49 | Priority: 3 50 | - Regex: '.*' 51 | Priority: 4 52 | IncludeBlocks: Regroup 53 | IndentCaseLabels: 'true' 54 | IndentPPDirectives: AfterHash 55 | IndentWidth: '4' 56 | IndentWrappedFunctionNames: 'true' 57 | JavaScriptQuotes: Leave 58 | KeepEmptyLinesAtTheStartOfBlocks: 'false' 59 | Language: Cpp 60 | MaxEmptyLinesToKeep: '1' 61 | NamespaceIndentation: All 62 | PenaltyBreakBeforeFirstCallParameter: 7 63 | PenaltyBreakAssignment: 8 64 | PenaltyBreakComment: 200 65 | PenaltyBreakFirstLessLess: 50 66 | PenaltyBreakString: 100 67 | PenaltyBreakTemplateDeclaration: 10 68 | PenaltyExcessCharacter: 10 69 | PenaltyReturnTypeOnItsOwnLine: 1000000 70 | PointerAlignment: Left 71 | ReflowComments: 'false' 72 | SortIncludes: 'false' 73 | SortUsingDeclarations: 'true' 74 | SpaceAfterTemplateKeyword: 'true' 75 | SpaceBeforeAssignmentOperators: 'true' 76 | SpaceBeforeCpp11BracedList: 'true' 77 | SpaceBeforeCtorInitializerColon: 'true' 78 | SpaceBeforeInheritanceColon: 'true' 79 | SpaceBeforeParens: ControlStatements 80 | SpaceBeforeRangeBasedForLoopColon: 'true' 81 | SpaceInEmptyParentheses: 'false' 82 | SpacesBeforeTrailingComments: '2' 83 | SpacesInAngles: 'false' 84 | SpacesInCStyleCastParentheses: 'false' 85 | SpacesInContainerLiterals: 'false' 86 | SpacesInParentheses: 'false' 87 | SpacesInSquareBrackets: 'false' 88 | Standard: Cpp11 89 | TabWidth: '4' 90 | UseTab: Never 91 | 92 | ... 93 | -------------------------------------------------------------------------------- /.github/workflows/releaseSTM32_Expander.yml: -------------------------------------------------------------------------------- 1 | name: STM32_Expander Release Builder 2 | 3 | permissions: 4 | contents: write 5 | 6 | on: 7 | workflow_dispatch: 8 | inputs: 9 | tag: 10 | description: 'Release version' 11 | required: true 12 | 13 | jobs: 14 | build: 15 | runs-on: ubuntu-latest 16 | 17 | steps: 18 | - uses: actions/checkout@v4 19 | - uses: actions/cache@v4 20 | with: 21 | path: | 22 | ~/.cache/pip 23 | ~/.platformio/.cache 24 | key: ${{ runner.os }}-pio 25 | - uses: actions/setup-python@v5 26 | with: 27 | python-version: '3.11' 28 | - name: Install PlatformIO Core 29 | run: pip install --upgrade platformio 30 | - name: Set release version 31 | run: | 32 | git config user.email "wmb@firmworks.com" 33 | git config user.name "Mitch Bradley" 34 | git tag "${{ github.event.inputs.tag }}" -a -m "Release test" 35 | - name: Build PlatformIO Project 36 | run: cd STM32_Expander && pio run 37 | - name: Create zip archive 38 | run: | 39 | cd STM32_Expander 40 | cat src/version.c 41 | rm -rf release 42 | mkdir release 43 | cd .pio/build 44 | for d in `ls -d */|sed -e s,/,,`; do zip -r ../../release/STM32_Expander_${{ github.event.inputs.tag }}.zip $d/firmware.bin; done 45 | - name: Create release 46 | uses: softprops/action-gh-release@v1 47 | with: 48 | tag_name: ${{ github.event.inputs.tag }} 49 | files: | 50 | STM32_Expander/release/* 51 | draft: True 52 | #- name: Upload binary artifact 53 | # uses: actions/upload-artifact@v4 54 | # with: 55 | # name: airedale_v1_1_firmware 56 | # path: STM32_Expander/.pio/build/airedale_v1_1/firmware.* 57 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .pio 2 | .vscode 3 | *~ 4 | *.o 5 | *.d 6 | *.lst 7 | *.map 8 | build 9 | junk 10 | STM32_Expander/.vscode/extensions.json 11 | STM32_Expander/.vscode/extensions.json 12 | -------------------------------------------------------------------------------- /Arduino_Expander/.gitignore: -------------------------------------------------------------------------------- 1 | .pio 2 | .vscode 3 | *~ 4 | *.o 5 | *.d 6 | *.lst 7 | *.map 8 | build 9 | -------------------------------------------------------------------------------- /Arduino_Expander/.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | // See http://go.microsoft.com/fwlink/?LinkId=827846 3 | // for the documentation about the extensions.json format 4 | "recommendations": [ 5 | "platformio.platformio-ide" 6 | ], 7 | "unwantedRecommendations": [ 8 | "ms-vscode.cpptools-extension-pack" 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /Arduino_Expander/README.md: -------------------------------------------------------------------------------- 1 | # IO Expander 2 | 3 | This is an IO expander device that lets an auxiliary MCU provide 4 | additional IO for a FluidNC system. It connects to FluidNC 5 | via a UART. When an expander GPIO changes state, the expander 6 | sends and events to FluidNC via the UART. Those events can 7 | be assigned to FluidNC input pin functions like control pins 8 | and limits pins. Expander GPIOs as FluidNC outputs. When 9 | FluidNC wants to change an output state, it sends a UART message 10 | to the expander. 11 | 12 | The code uses the Arduino framework as the interface to 13 | MCU-dependent hardware, so many different types of MCUs 14 | can be used for the expander without changing the code. 15 | 16 | ## Wiring 17 | 18 | Connect a secondary UART on the FluidNC controller to the UART 19 | on the MCU. Connect MCU Tx to FluidNC Rx and vice versa. If the MCU 20 | has 5V IO, you will need level conversion on the MCU Tx to FluidNC Rx 21 | line. It could be just a resistive voltage divider like this: 22 | 23 | MCU Tx ---XXXX------ FluidNC Rx 24 | 2.2K | 25 | resistor X 26 | X 3.3K resistor 27 | X 28 | | 29 | MCU GND --------------FluidNC GND 30 | 31 | 32 | If the MCU has 3.3V IO, you can connect directly with no level shifting. 33 | 34 | The FluidNC Tx to MCU Rx line typically can be directly connected, 35 | since a 3.3V output can drive a 5V input safely and effectively. 36 | 37 | ## Example FluidNC Config Section 38 | 39 | ```yaml 40 | uart1: 41 | txd_pin: gpio.17 42 | rxd_pin: gpio.16 43 | baud: 115200 44 | mode: 8N1 45 | uart_channel1: 46 | uart_num: 1 47 | report_interval_ms: 400 48 | control: 49 | safety_door_pin: uart_channel1.3:low:pu 50 | coolant: 51 | mist_pin: uart_channe1.7 52 | ``` 53 | 54 | ## Assigning UART Pins 55 | 56 | On the FluidNC controller you can assign the UART pins that connect to the expander in the config file; just change gpio.17 and gpio.16 in the example above. 57 | 58 | On the MCU, the Arduino framework assigns IO pins to the primary UART according to a board definition file. platformio.ini has "env:" sections for various MCUs. Each such env: section has a "board =" line that selects a particular board that has that MCU. Set that line to the name of a board that is compatible with the one you are using. Ask the internet for help if you don't understand that. 59 | 60 | On some MCUs, the primary UART is also connected to a USB-Serial chip so it can be connected to a PC. It is often possible to connect that primary UART directly to another computer, if the USB-serial lines are isolated with resistors to permit the other computer to overdrive the MCU's Rx line. 61 | 62 | ## Assigning Expander IO Pins 63 | 64 | To assign an input pin function to an expander pin, use the syntax "uart_channel., with additional attributes like :low or :pu as necessary. The example above assigns IO Expander pin 3 as an input, connected via UART 1, to the safety door function, active low with pullup enabled. It also assigns IO Expander pin 7 as an output, to control mist coolant. 65 | 66 | The pin numbering on the expander corresponds to the Arduino digital pin numbering for the MCU in question. If you need to change that, you can edit the file src/gpiomap.cpp to create a custom version of the gpios[] array, initializing the array so that the expander pin number (array index) maps to the Arduino pin number that you prefer. 67 | 68 | ## Compiling 69 | 70 | * Install PlatformIO according to instructions on the Web. You can use any IDE/editing environment that you like. Many people use PlatformIO under VSCode, but it also works with many other editors. 71 | * Edit platformio.ini and set "default_envs" to the name of the MCU you want to use. The name should match one of the "env:" values in platformio.ini 72 | * Click the IDE's "Upload" button, or execute "pio run -t upload" if you are running PlatformIO from the command line. 73 | * Connect a serial monitor program to the primary UART of the MCU. It should display a message whenever the FluidNC state changes (Idle, Cycle, Hold, etc). 74 | 75 | ## Adding Other MCUs 76 | 77 | The platformio.ini file has [env:XXX] sections for several MCUs, including an AVR, various ESP32s, and an STM32. You can add an additional section for any device and board that the Arduino framework supports. 78 | -------------------------------------------------------------------------------- /Arduino_Expander/include/README: -------------------------------------------------------------------------------- 1 | 2 | This directory is intended for project header files. 3 | 4 | A header file is a file containing C declarations and macro definitions 5 | to be shared between several project source files. You request the use of a 6 | header file in your project source file (C, C++, etc) located in `src` folder 7 | by including it, with the C preprocessing directive `#include'. 8 | 9 | ```src/main.c 10 | 11 | #include "header.h" 12 | 13 | int main (void) 14 | { 15 | ... 16 | } 17 | ``` 18 | 19 | Including a header file produces the same results as copying the header file 20 | into each source file that needs it. Such copying would be time-consuming 21 | and error-prone. With a header file, the related declarations appear 22 | in only one place. If they need to be changed, they can be changed in one 23 | place, and programs that include the header file will automatically use the 24 | new version when next recompiled. The header file eliminates the labor of 25 | finding and changing all the copies as well as the risk that a failure to 26 | find one copy will result in inconsistencies within a program. 27 | 28 | In C, the usual convention is to give header files names that end with `.h'. 29 | It is most portable to use only letters, digits, dashes, and underscores in 30 | header file names, and at most one dot. 31 | 32 | Read more about using header files in official GCC documentation: 33 | 34 | * Include Syntax 35 | * Include Operation 36 | * Once-Only Headers 37 | * Computed Includes 38 | 39 | https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html 40 | -------------------------------------------------------------------------------- /Arduino_Expander/include/gpio_pin.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Mitch Bradley 2 | // Use of this source code is governed by a GPLv3 license that can be found in the LICENSE file. 3 | 4 | #pragma once 5 | #ifdef __cplusplus 6 | extern "C" { 7 | #endif 8 | 9 | #include "pinmode.h" 10 | 11 | // The internals of this struct are MCU-specific 12 | typedef struct { 13 | // Implementation for STM32 HAL 14 | uint32_t pin_num; 15 | bool pwm_capable; 16 | } gpio_pin_t; 17 | 18 | // This API is MCU-independent 19 | int set_gpio(gpio_pin_t* gpio, bool high); 20 | bool get_gpio(gpio_pin_t* gpio); 21 | int set_pwm(gpio_pin_t* gpio, int32_t numerator, uint32_t denominator); 22 | void deinit_gpio(gpio_pin_t* gpio); 23 | bool set_gpio_mode(gpio_pin_t* gpio, pin_mode_t pinmode); 24 | 25 | #ifdef __cplusplus 26 | } 27 | #endif 28 | -------------------------------------------------------------------------------- /Arduino_Expander/include/gpiomap.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Mitch Bradley 2 | // Use of this source code is governed by a GPLv3 license that can be found in the LICENSE file. 3 | 4 | #pragma once 5 | 6 | #include "pin.h" 7 | #include 8 | 9 | #ifdef __cplusplus 10 | extern "C" { 11 | #endif 12 | 13 | extern pin_t gpios[]; 14 | 15 | extern void init_gpiomap(); 16 | 17 | #define n_pins NUM_DIGITAL_PINS 18 | 19 | #ifdef __cplusplus 20 | } 21 | #endif 22 | -------------------------------------------------------------------------------- /Arduino_Expander/platformio.ini: -------------------------------------------------------------------------------- 1 | ; PlatformIO Project Configuration File 2 | ; 3 | ; Build options: build flags, source filter 4 | ; Upload options: custom upload port, speed and extra flags 5 | ; Library options: dependencies, extra library storages 6 | ; Advanced options: extra scripting 7 | ; 8 | ; Please visit documentation for the other options and examples 9 | ; https://docs.platformio.org/page/projectconf.html 10 | 11 | [platformio] 12 | ;default_envs = megaatmega2560 13 | lib_dir = ../lib 14 | 15 | [env] 16 | framework = arduino 17 | monitor_speed = 115200 18 | lib_deps = https://github.com/MitchBradley/GrblParser 19 | build_flags = 20 | -Iinclude 21 | 22 | [env:nano] 23 | platform = atmelavr 24 | board = nanoatmega328 25 | upload_port = COM7 26 | monitor_port = COM7 27 | 28 | [env:megaatmega2560] 29 | platform = atmelavr 30 | board = megaatmega2560 31 | upload_port = COM7 32 | monitor_port = COM7 33 | 34 | [env:esp32] 35 | platform = espressif32 36 | board = esp32dev 37 | 38 | [env:esp32s2] 39 | platform = espressif32 40 | board = nodemcu-32s2 41 | 42 | [env:esp32s3] 43 | platform = espressif32 44 | board = esp32-s3-devkitc-1 45 | 46 | [env:esp32c3] 47 | platform = espressif32 48 | board = esp32-c3-devkitc-02 49 | 50 | [env:esp8266] 51 | platform = espressif8266 52 | board = d1_mini 53 | 54 | [env:stm32] 55 | platform = ststm32 56 | board = bluepill_f103c6 57 | -------------------------------------------------------------------------------- /Arduino_Expander/src/gpio_pin.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Mitch Bradley 2 | // Use of this source code is governed by a GPLv3 license that can be found in the LICENSE file. 3 | 4 | // This file implements the low-level interface to GPIO pins that is used by 5 | // the intermediate-level interface defined in lib/Expander/src/pin.{c,h} 6 | // The intention is to encapsulate the platform-dependent GPIO API as tightly 7 | // as possible. 8 | // This implementation is for the Arduino framework 9 | 10 | #include "gpio_pin.h" 11 | #include "gpiomap.h" 12 | 13 | #ifdef __cplusplus 14 | extern "C" { 15 | #endif 16 | 17 | int set_gpio(gpio_pin_t* gpio, bool high) { 18 | digitalWrite(gpio->pin_num, high); 19 | return true; 20 | } 21 | bool get_gpio(gpio_pin_t* gpio) { 22 | return digitalRead(gpio->pin_num); 23 | } 24 | int set_pwm(gpio_pin_t* gpio, int32_t numerator, uint32_t denominator) { 25 | // uint32_t pwm_val = 255 * numerator / denominator; // map 0.0-100.0 to 0 to 255 26 | // analogWrite(stm_pin_num, pwm_val); 27 | return true; 28 | } 29 | void deinit_gpio(gpio_pin_t* gpio) { 30 | pinMode(gpio->pin_num, INPUT); 31 | } 32 | bool set_gpio_mode(gpio_pin_t* gpio, pin_mode_t pinmode) { 33 | if (pinmode & PIN_OUTPUT) { 34 | pinMode(gpio->pin_num, OUTPUT); 35 | 36 | digitalWrite(gpio->pin_num, !!(pinmode & PIN_ACTIVELOW)); 37 | } 38 | if (pinmode & PIN_PWM) { 39 | if (!gpio->pwm_capable) { 40 | return false; 41 | } 42 | #ifdef INPUT_ANALOG 43 | pinMode(gpio->pin_num, INPUT_ANALOG); 44 | return true; 45 | #else 46 | return false; 47 | #endif 48 | } 49 | if (pinmode & PIN_INPUT) { 50 | uint32_t mode; 51 | if (pinmode & PIN_PULLUP) { 52 | mode = INPUT_PULLUP; 53 | } else if (pinmode & PIN_PULLDOWN) { 54 | #ifdef INPUT_PULLDOWN 55 | mode = INPUT_PULLDOWN; 56 | #else 57 | return false; 58 | #endif 59 | } else { 60 | mode = INPUT; 61 | } 62 | pinMode(gpio->pin_num, mode); 63 | return true; 64 | } 65 | return false; 66 | } 67 | 68 | #ifdef __cplusplus 69 | } 70 | #endif 71 | -------------------------------------------------------------------------------- /Arduino_Expander/src/gpiomap.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Mitch Bradley 2 | // Use of this source code is governed by a GPLv3 license that can be found in the LICENSE file. 3 | 4 | #include "pin.h" 5 | #include "gpiomap.h" 6 | 7 | // The pins table maps io numbers (the table index) to 8 | // device-specific and board-specific pin numbers 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | 14 | pin_t gpios[NUM_DIGITAL_PINS]; 15 | 16 | #ifndef pinIsAnalogInput 17 | # define pinIsAnalogInput(i) false 18 | #endif 19 | 20 | void init_gpiomap() { 21 | for (size_t i = 0; i < NUM_DIGITAL_PINS; i++) { 22 | gpio_pin_t gpio = { i, pinIsAnalogInput(i) }; 23 | gpios[i].gpio = gpio; 24 | } 25 | } 26 | 27 | #ifdef __cplusplus 28 | } 29 | #endif 30 | -------------------------------------------------------------------------------- /Arduino_Expander/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "Expander.h" 3 | #include "gpio_pin.h" 4 | #include "gpiomap.h" 5 | 6 | #define FNCSerial Serial // connects STM32 to ESP32 and FNC 7 | #ifdef USE_DEBUG_SERIAL 8 | # define DebugSerial Serial2 // connects STM32 to Debug terminal 9 | #endif 10 | 11 | // Interface routines for GrblParser 12 | 13 | // Receive a byte from the serial port connected to FluidNC 14 | int fnc_getchar() { 15 | if (FNCSerial.available()) { 16 | return FNCSerial.read(); 17 | } 18 | return -1; 19 | } 20 | // Send a byte to the serial port connected to FluidNC 21 | void fnc_putchar(uint8_t c) { 22 | FNCSerial.write(c); 23 | } 24 | 25 | // Return a value that increments every millisecond 26 | int milliseconds() { 27 | return millis(); 28 | } 29 | 30 | // Perform extra operations after the normal polling for input from FluidNC 31 | void poll_extra() { 32 | #ifdef DebugSerial 33 | while (DebugSerial.available()) { 34 | uint8_t c = DebugSerial.read(); 35 | fnc_putchar(c); 36 | collect(c); // for testing from debug terminal 37 | } 38 | #endif 39 | 40 | expander_poll(); 41 | } 42 | 43 | void setup() { 44 | init_gpiomap(); 45 | 46 | #ifdef LEDPBUILTIN 47 | pinMode(LED_BUILTIN, OUTPUT); 48 | #endif 49 | FNCSerial.begin(115200); 50 | #ifdef DebugSerial 51 | DebugSerial.begin(115200); 52 | #endif 53 | fnc_wait_ready(); // Synchronize to FluidNC 54 | } 55 | void loop() { 56 | fnc_poll(); 57 | } 58 | -------------------------------------------------------------------------------- /Arduino_Expander/test/README: -------------------------------------------------------------------------------- 1 | 2 | This directory is intended for PlatformIO Test Runner and project tests. 3 | 4 | Unit Testing is a software testing method by which individual units of 5 | source code, sets of one or more MCU program modules together with associated 6 | control data, usage procedures, and operating procedures, are tested to 7 | determine whether they are fit for use. Unit testing finds problems early 8 | in the development cycle. 9 | 10 | More information about PlatformIO Unit Testing: 11 | - https://docs.platformio.org/en/latest/advanced/unit-testing/index.html 12 | -------------------------------------------------------------------------------- /DisplayToTerminal/.gitignore: -------------------------------------------------------------------------------- 1 | .pio 2 | .vscode 3 | *~ 4 | *.o 5 | *.d 6 | *.lst 7 | *.map 8 | build 9 | -------------------------------------------------------------------------------- /DisplayToTerminal/.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | // See http://go.microsoft.com/fwlink/?LinkId=827846 3 | // for the documentation about the extensions.json format 4 | "recommendations": [ 5 | "platformio.platformio-ide" 6 | ], 7 | "unwantedRecommendations": [ 8 | "ms-vscode.cpptools-extension-pack" 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /DisplayToTerminal/README.md: -------------------------------------------------------------------------------- 1 | # Display to Terminal Pendant 2 | 3 | This pendant requires a microcontroller with two UARTs. The first 4 | UART displays information to a user via a serial monitor program. 5 | The second UART connects to a FluidNC controller. 6 | 7 | This example pendant is probably not useful directly, but it is very 8 | simple. It illustrates how to make a UART connection 9 | between FluidNC and an MCU, without being distracted by details of 10 | other displays or IO devices. It also shows the basic usage of 11 | the GrblParser class for decoding GRBL protocol messages. 12 | 13 | ## Wiring 14 | 15 | Connect a secondary UART on the FluidNC controller to a secondary UART 16 | on the MCU. Connect MCU Tx to FluidNC Rx and vice versa. If the MCU 17 | has 5V IO, you will need level conversion on the MCU Tx to FluidNC Rx 18 | line. It could be just a resistive voltage divider like this: 19 | 20 | MCU Tx ---XXXX------ FluidNC Rx 21 | 2.2K | 22 | resistor X 23 | X 3.3K resistor 24 | X 25 | | 26 | MCU GND --------------FluidNC GND 27 | 28 | 29 | If the MCU has 3.3V IO, you can connect directly with no level shifting. 30 | 31 | The FluidNC Tx to MCU Rx line typically can be directly connected, 32 | since a 3.3V output can drive a 5V input safely and effectively. 33 | 34 | ## Example FluidNC Config Section 35 | 36 | ```yaml 37 | uart1: 38 | txd_pin: gpio.17 39 | rxd_pin: gpio.16 40 | baud: 115200 41 | mode: 8N1 42 | uart_channel1: 43 | uart_num: 1 44 | report_interval_ms: 400 45 | ``` 46 | 47 | ## Assigning UART Pins 48 | 49 | On the FluidNC controller you can assign the UART pins in the config file; just change gpio.17 and gpio.16 in the example above. 50 | 51 | On the MCU, the Arduino framework assigns IO pins to the secondary UART according to a board definition file. platformio.ini has "env:" sections for various MCUs. Each such env: section has a "board =" line that selects a particular board that has that MCU. Set that line to the name of a board that is compatible with the one you are using. Ask the internet for help if you don't understand that. 52 | 53 | ## Compiling 54 | 55 | * Install PlatformIO according to instructions on the Web. You can use any IDE/editing environment that you like. Many people use PlatformIO under VSCode, but it also works with many other editors. 56 | * Edit platformio.ini and set "default_envs" to the name of the MCU you want to use. The name should match one of the "env:" values in platformio.ini 57 | * Click the IDE's "Upload" button, or execute "pio run -t upload" if you are running PlatformIO from the command line. 58 | * Connect a serial monitor program to the primary UART of the MCU. It should display a message whenever the FluidNC state changes (Idle, Cycle, Hold, etc). 59 | -------------------------------------------------------------------------------- /DisplayToTerminal/include/README: -------------------------------------------------------------------------------- 1 | 2 | This directory is intended for project header files. 3 | 4 | A header file is a file containing C declarations and macro definitions 5 | to be shared between several project source files. You request the use of a 6 | header file in your project source file (C, C++, etc) located in `src` folder 7 | by including it, with the C preprocessing directive `#include'. 8 | 9 | ```src/main.c 10 | 11 | #include "header.h" 12 | 13 | int main (void) 14 | { 15 | ... 16 | } 17 | ``` 18 | 19 | Including a header file produces the same results as copying the header file 20 | into each source file that needs it. Such copying would be time-consuming 21 | and error-prone. With a header file, the related declarations appear 22 | in only one place. If they need to be changed, they can be changed in one 23 | place, and programs that include the header file will automatically use the 24 | new version when next recompiled. The header file eliminates the labor of 25 | finding and changing all the copies as well as the risk that a failure to 26 | find one copy will result in inconsistencies within a program. 27 | 28 | In C, the usual convention is to give header files names that end with `.h'. 29 | It is most portable to use only letters, digits, dashes, and underscores in 30 | header file names, and at most one dot. 31 | 32 | Read more about using header files in official GCC documentation: 33 | 34 | * Include Syntax 35 | * Include Operation 36 | * Once-Only Headers 37 | * Computed Includes 38 | 39 | https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html 40 | -------------------------------------------------------------------------------- /DisplayToTerminal/platformio.ini: -------------------------------------------------------------------------------- 1 | ; PlatformIO Project Configuration File 2 | ; 3 | ; Build options: build flags, source filter 4 | ; Upload options: custom upload port, speed and extra flags 5 | ; Library options: dependencies, extra library storages 6 | ; Advanced options: extra scripting 7 | ; 8 | ; Please visit documentation for the other options and examples 9 | ; https://docs.platformio.org/page/projectconf.html 10 | 11 | [platformio] 12 | default_envs = megaatmega2560 13 | 14 | [env] 15 | framework = arduino 16 | monitor_speed = 115200 17 | lib_deps = https://github.com/MitchBradley/GrblParser 18 | build_flags = -DE4_POS_T 19 | 20 | [env:megaatmega2560] 21 | platform = atmelavr 22 | board = megaatmega2560 23 | upload_port = COM7 24 | monitor_port = COM7 25 | 26 | [env:esp32] 27 | platform = espressif32 28 | board = esp32dev 29 | 30 | [env:esp32s2] 31 | platform = espressif32 32 | board = nodemcu-32s2 33 | 34 | [env:esp32s3] 35 | platform = espressif32 36 | board = esp32-s3-devkitc-1 37 | 38 | [env:esp32c3] 39 | platform = espressif32 40 | board = esp32-c3-devkitc-02 41 | 42 | [env:esp8266] 43 | platform = espressif8266 44 | board = d1_mini 45 | 46 | [env:stm32] 47 | platform = ststm32 48 | board = bluepill_f103c6 49 | -------------------------------------------------------------------------------- /DisplayToTerminal/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "GrblParserC.h" 3 | 4 | extern "C" void fnc_putchar(uint8_t c) { 5 | Serial1.write(c); 6 | } 7 | 8 | extern "C" int fnc_getchar() { 9 | if (Serial1.available()) { 10 | return Serial1.read(); 11 | } 12 | return -1; 13 | } 14 | 15 | extern "C" void debug_putchar(char c) { 16 | Serial.print(c); 17 | } 18 | extern "C" void debug_print(const char* msg) { 19 | Serial.print(msg); 20 | } 21 | extern "C" void debug_println(const char* msg) { 22 | Serial.println(msg); 23 | } 24 | 25 | extern "C" void show_state(const char* state) { 26 | Serial.print(state); 27 | } 28 | extern "C" void show_dro(const pos_t* axes, const pos_t* wcos, bool isMpos, bool* limits, size_t n_axis) { 29 | char delim = ' '; 30 | for (size_t i = 0; i < n_axis; i++) { 31 | debug_putchar(delim); 32 | delim = ','; 33 | String a(axes[i]); 34 | debug_print(a.c_str()); 35 | } 36 | debug_println(""); 37 | } 38 | extern "C" void end_status_report() { 39 | debug_println(""); 40 | } 41 | extern "C" int milliseconds() { 42 | return millis(); 43 | } 44 | extern "C" void poll_extra() { 45 | #ifdef SEND_CONSOLE_DATA 46 | while (Serial.available()) { 47 | char c = Serial.read(); 48 | if (c != '\r') { 49 | fnc_putchar(c); 50 | } 51 | } 52 | #endif 53 | } 54 | 55 | void setup() { 56 | Serial.begin(115200); 57 | Serial1.begin(115200); 58 | fnc_wait_ready(); 59 | fnc_putchar('?'); // Initial status report 60 | fnc_send_line("$G", 1000); // Initial modes report 61 | } 62 | // #define ECHO_RX_DATA 63 | // #define SEND_CONSOLE_DATA 64 | void loop() { 65 | fnc_poll(); 66 | } 67 | -------------------------------------------------------------------------------- /DisplayToTerminal/test/README: -------------------------------------------------------------------------------- 1 | 2 | This directory is intended for PlatformIO Test Runner and project tests. 3 | 4 | Unit Testing is a software testing method by which individual units of 5 | source code, sets of one or more MCU program modules together with associated 6 | control data, usage procedures, and operating procedures, are tested to 7 | determine whether they are fit for use. Unit testing finds problems early 8 | in the development cycle. 9 | 10 | More information about PlatformIO Unit Testing: 11 | - https://docs.platformio.org/en/latest/advanced/unit-testing/index.html 12 | -------------------------------------------------------------------------------- /LilyGo_T_S3/.gitignore: -------------------------------------------------------------------------------- 1 | .pio 2 | .vscode 3 | *~ 4 | *.o 5 | *.d 6 | *.lst 7 | *.map 8 | build 9 | -------------------------------------------------------------------------------- /LilyGo_T_S3/arduino_settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bdring/PendantsForFluidNC/320abd6fb509cd806d1a9ff08472a64dc7e0c971/LilyGo_T_S3/arduino_settings.png -------------------------------------------------------------------------------- /LilyGo_T_S3/include/pin_config.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define DISP_WIDTH 320 4 | #define DISP_HEIGHT 170 5 | 6 | /*ESP32S3*/ 7 | #define PIN_LCD_BL 38 8 | 9 | #define PIN_LCD_D0 39 10 | #define PIN_LCD_D1 40 11 | #define PIN_LCD_D2 41 12 | #define PIN_LCD_D3 42 13 | #define PIN_LCD_D4 45 14 | #define PIN_LCD_D5 46 15 | #define PIN_LCD_D6 47 16 | #define PIN_LCD_D7 48 17 | 18 | #define PIN_POWER_ON 15 19 | 20 | #define PIN_LCD_RES 5 21 | #define PIN_LCD_CS 6 22 | #define PIN_LCD_DC 7 23 | #define PIN_LCD_WR 8 24 | #define PIN_LCD_RD 9 25 | 26 | #define PIN_BUTTON_1 0 27 | #define PIN_BUTTON_2 14 28 | #define PIN_BAT_VOLT 4 29 | 30 | #define PIN_IIC_SCL 17 31 | #define PIN_IIC_SDA 18 32 | 33 | #define PIN_TOUCH_INT 16 34 | #define PIN_TOUCH_RES 21 35 | 36 | #define RX1_PIN 17 37 | #define TX1_PIN 18 38 | -------------------------------------------------------------------------------- /LilyGo_T_S3/pinout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bdring/PendantsForFluidNC/320abd6fb509cd806d1a9ff08472a64dc7e0c971/LilyGo_T_S3/pinout.png -------------------------------------------------------------------------------- /LilyGo_T_S3/platformio.ini: -------------------------------------------------------------------------------- 1 | [platformio] 2 | lib_dir = ../lib 3 | 4 | [env] 5 | framework = arduino 6 | monitor_speed = 115200 7 | lib_deps = 8 | TFT_eSPI=https://github.com/Bodmer/TFT_eSPI 9 | https://github.com/MitchBradley/GrblParser 10 | 11 | [env:esp32] 12 | platform = espressif32 13 | board = lilygo-t-display-s3 14 | -------------------------------------------------------------------------------- /LilyGo_T_S3/src/main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * 4 | * Note: If the USB is not connected this program locks up when that serial port is used. 5 | * Maybe there are some floating pins that generate data. 6 | */ 7 | 8 | #include "Arduino.h" 9 | #include "GrblParserC.h" 10 | #include "pin_config.h" 11 | #include "fnc.h" 12 | #include "TFT_eSPI.h" 13 | 14 | #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0) 15 | # error "The current version is not supported for the time being, please use a version below Arduino ESP32 3.0" 16 | #endif 17 | 18 | #define FNCSerial Serial1 19 | #define DebugSerial Serial 20 | 21 | /* The product now has two screens, and the initialization code needs a small change in the new version. The LCD_MODULE_CMD_1 is used to define the 22 | switch macro. */ 23 | #define LCD_MODULE_CMD_1 24 | #define ECHO_RX_DATA 25 | //#define DEBUG_USB 26 | 27 | TFT_eSPI tft = TFT_eSPI(); 28 | TFT_eSprite sprite1 = TFT_eSprite(&tft); // Used to prevent flickering 29 | 30 | // local copies so we can do one update function 31 | String myState = "No data..."; 32 | float myAxes[MAX_N_AXIS] = { 0 }; 33 | int my_n_axis = 3; 34 | bool myLimits[MAX_N_AXIS] = { false }; 35 | bool myProbe = false; 36 | bool use_mm = true; 37 | 38 | void updateDisplay(); 39 | 40 | #if defined(LCD_MODULE_CMD_1) 41 | typedef struct { 42 | uint8_t cmd; 43 | uint8_t data[14]; 44 | uint8_t len; 45 | } lcd_cmd_t; 46 | 47 | lcd_cmd_t lcd_st7789v[] = { 48 | { 0x11, { 0 }, 0 | 0x80 }, 49 | { 0x3A, { 0X05 }, 1 }, 50 | { 0xB2, { 0X0B, 0X0B, 0X00, 0X33, 0X33 }, 5 }, 51 | { 0xB7, { 0X75 }, 1 }, 52 | { 0xBB, { 0X28 }, 1 }, 53 | { 0xC0, { 0X2C }, 1 }, 54 | { 0xC2, { 0X01 }, 1 }, 55 | { 0xC3, { 0X1F }, 1 }, 56 | { 0xC6, { 0X13 }, 1 }, 57 | { 0xD0, { 0XA7 }, 1 }, 58 | { 0xD0, { 0XA4, 0XA1 }, 2 }, 59 | { 0xD6, { 0XA1 }, 1 }, 60 | { 0xE0, { 0XF0, 0X05, 0X0A, 0X06, 0X06, 0X03, 0X2B, 0X32, 0X43, 0X36, 0X11, 0X10, 0X2B, 0X32 }, 14 }, 61 | { 0xE1, { 0XF0, 0X08, 0X0C, 0X0B, 0X09, 0X24, 0X2B, 0X22, 0X43, 0X38, 0X15, 0X16, 0X2F, 0X37 }, 14 }, 62 | }; 63 | #endif 64 | 65 | extern "C" void show_state(const char* state) { 66 | myState = state; 67 | updateDisplay(); 68 | } 69 | 70 | extern "C" void show_dro(const pos_t* axes, const pos_t* wcos, bool isMpos, bool* limits, size_t n_axis) { 71 | my_n_axis = n_axis; 72 | for (int i = 0; i < n_axis; i++) { 73 | myAxes[i] = axes[i]; 74 | } 75 | for (int i = 0; i < n_axis; i++) { 76 | myLimits[i] = limits[i]; 77 | } 78 | updateDisplay(); // TO DO reduce the number of these 79 | } 80 | 81 | extern "C" void show_limits(bool probe, const bool* limits, size_t n_axis) { 82 | // limits done with DROs 83 | if (myProbe != probe) { 84 | myProbe = probe; 85 | } 86 | updateDisplay(); 87 | } 88 | 89 | extern "C" int fnc_getchar() { 90 | if (FNCSerial.available()) { 91 | return FNCSerial.read(); 92 | } 93 | return -1; 94 | } 95 | extern "C" void fnc_putchar(uint8_t c) { 96 | FNCSerial.write(c); 97 | } 98 | extern "C" void debug_putchar(char c) { 99 | DebugSerial.write(c); 100 | } 101 | extern "C" int milliseconds() { 102 | return millis(); 103 | } 104 | 105 | void setup() { 106 | pinMode(PIN_POWER_ON, OUTPUT); 107 | digitalWrite(PIN_POWER_ON, HIGH); 108 | pinMode(PIN_BUTTON_2, INPUT); // active low has physical pullup and RC 109 | 110 | #ifdef DEBUG_USB 111 | DebugSerial.begin(115200); // used for debugging 112 | delay(2000); // delay to allow USB connection of PC to connect 113 | Serial.println("Begin T-Display-S3"); 114 | #endif 115 | 116 | FNCSerial.begin(115200, SERIAL_8N1, RX1_PIN, TX1_PIN); // connected to FluidNC 117 | 118 | tft.begin(); 119 | tft.setRotation(3); 120 | tft.setSwapBytes(true); 121 | 122 | sprite1.setColorDepth(16); 123 | sprite1.createSprite(DISP_WIDTH, DISP_HEIGHT); 124 | sprite1.fillSprite(TFT_BLACK); 125 | 126 | #if defined(LCD_MODULE_CMD_1) 127 | for (uint8_t i = 0; i < (sizeof(lcd_st7789v) / sizeof(lcd_cmd_t)); i++) { 128 | tft.writecommand(lcd_st7789v[i].cmd); 129 | for (int j = 0; j < (lcd_st7789v[i].len & 0x7f); j++) { 130 | tft.writedata(lcd_st7789v[i].data[j]); 131 | } 132 | 133 | if (lcd_st7789v[i].len & 0x80) { 134 | delay(120); 135 | } 136 | } 137 | #endif 138 | 139 | #if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0) 140 | ledcSetup(0, 2000, 8); 141 | ledcAttachPin(PIN_LCD_BL, 0); 142 | ledcWrite(0, 255); 143 | #else 144 | ledcAttach(PIN_LCD_BL, 200, 8); 145 | ledcWrite(PIN_LCD_BL, 255); 146 | #endif 147 | 148 | tft.fillRect(0, 0, DISP_WIDTH, DISP_HEIGHT, TFT_BLACK); 149 | //tft.drawString("FluidNC Channel pendant", 0 , 0, 4); 150 | 151 | tft.pushImage(0, 0, 320, 170, logo); 152 | delay(2000); 153 | 154 | updateDisplay(); 155 | 156 | fnc_wait_ready(); // Synchronize with FluidNC 157 | fnc_putchar('?'); // Initial status report 158 | } 159 | 160 | void loop() { 161 | fnc_poll(); 162 | } 163 | 164 | void readButtons() { 165 | if (!digitalRead(PIN_BUTTON_2)) { 166 | if (myState == "Run") { 167 | debug_putchar('!'); 168 | fnc_putchar('!'); 169 | } else if (myState.startsWith("Hold")) { 170 | debug_putchar('~'); 171 | fnc_putchar('~'); 172 | } 173 | delay(50); 174 | while (!digitalRead(PIN_BUTTON_2)) {} 175 | delay(50); 176 | } 177 | } 178 | 179 | String DRO_format(int axis, float val) { 180 | String format; 181 | char buf[12]; 182 | int len; 183 | String DRO; 184 | String axesNames = "XYZABC"; 185 | 186 | if (use_mm) { 187 | format = "% 4.2f"; 188 | } else { 189 | format = "% 3.3f"; 190 | } 191 | 192 | len = sprintf(buf, format.c_str(), val); 193 | 194 | DRO = buf; 195 | 196 | while (DRO.length() < 9) { 197 | DRO = " " + DRO; 198 | } 199 | 200 | DRO = axesNames.substring(axis, axis + 1) + DRO; 201 | return DRO; 202 | } 203 | 204 | void drawCheckbox(int x, int y, int width, bool checked, String label) { 205 | if (checked) { 206 | sprite1.fillRect(x, y, width, width, TFT_GREEN); 207 | } else { 208 | sprite1.drawRect(x, y, width, width, TFT_GREEN); 209 | } 210 | 211 | sprite1.drawString(label, x + width + 5, y, 4); 212 | } 213 | 214 | void updateDisplay() { 215 | char buf[12]; 216 | String axesNames = "XYZABC"; 217 | 218 | sprite1.fillSprite(TFT_BLACK); 219 | 220 | if (myState == "Alarm") { 221 | sprite1.setTextColor(TFT_RED, TFT_BLACK); 222 | } else if (myState.startsWith("Hold")) { 223 | sprite1.setTextColor(TFT_YELLOW, TFT_BLACK); 224 | } else { 225 | sprite1.setTextColor(TFT_GREEN, TFT_BLACK); 226 | } 227 | 228 | sprite1.drawString(myState, 0, 0, 4); 229 | drawCheckbox(150, 0, 18, myProbe, "Probe"); 230 | 231 | for (int i = 0; i < my_n_axis; i++) { 232 | sprite1.drawString(DRO_format(i, myAxes[i]), 0, 26 + i * 24, 4); 233 | drawCheckbox(150, 26 + i * 24, 18, myLimits[i], "Limit"); 234 | } 235 | 236 | sprite1.pushSprite(0, 0); 237 | } 238 | 239 | extern "C" void poll_extra() { 240 | #ifdef DEBUG_USB 241 | while (DebugSerial.available()) { 242 | char c = DebugSerial.read(); 243 | if (c != '\r') { 244 | debug_putchar(c); 245 | putchar(c); 246 | } 247 | } 248 | #endif 249 | readButtons(); 250 | } 251 | -------------------------------------------------------------------------------- /Playlist/.gitignore: -------------------------------------------------------------------------------- 1 | .pio 2 | .vscode 3 | *~ 4 | *.o 5 | *.d 6 | *.lst 7 | *.map 8 | build 9 | -------------------------------------------------------------------------------- /Playlist/.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | // See http://go.microsoft.com/fwlink/?LinkId=827846 3 | // for the documentation about the extensions.json format 4 | "recommendations": [ 5 | "platformio.platformio-ide" 6 | ], 7 | "unwantedRecommendations": [ 8 | "ms-vscode.cpptools-extension-pack" 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /Playlist/README.md: -------------------------------------------------------------------------------- 1 | # Playlist Pendant 2 | 3 | This pendant requires a microcontroller with one UART connected to a FluidNC controller. 4 | It repetitely runs a playlist of files on the SD card. The list of files is 5 | hardcoded in the program. The program illustrates how to tell FluidNC to run 6 | a program and how to tell that a running program is complete. 7 | 8 | ## Wiring 9 | 10 | Connect a secondary UART on the FluidNC controller to the primary UART 11 | on the MCU. Connect MCU Tx to FluidNC Rx and vice versa. If the MCU 12 | has 5V IO, you will need level conversion on the MCU Tx to FluidNC Rx 13 | line. It could be just a resistive voltage divider like this: 14 | 15 | MCU Tx ---XXXX------ FluidNC Rx 16 | 2.2K | 17 | resistor X 18 | X 3.3K resistor 19 | X 20 | | 21 | MCU GND --------------FluidNC GND 22 | 23 | 24 | If the MCU has 3.3V IO, you can connect directly with no level shifting. 25 | 26 | The FluidNC Tx to MCU Rx line typically can be directly connected, 27 | since a 3.3V output can drive a 5V input safely and effectively. 28 | 29 | ## Example FluidNC Config Section 30 | 31 | ```yaml 32 | uart1: 33 | txd_pin: gpio.17 34 | rxd_pin: gpio.16 35 | baud: 115200 36 | mode: 8N1 37 | uart_channel1: 38 | uart_num: 1 39 | report_interval_ms: 400 40 | all_messages: false 41 | ``` 42 | 43 | ## Assigning UART Pins 44 | 45 | On the FluidNC controller you can assign the UART pins in the config file; just change gpio.17 and gpio.16 in the example above. 46 | 47 | On the MCU, the Arduino framework assigns IO pins to the primary UART according to a board definition file. platformio.ini has "env:" sections for various MCUs. Each such env: section has a "board =" line that selects a particular board that has that MCU. Set that line to the name of a board that is compatible with the one you are using. Ask the internet for help if you don't understand that. 48 | 49 | On some MCUs, the primary UART is also connected to a USB-Serial chip so it can be connected to a PC. It is often possible to connect that primary UART directly to another computer, if the USB-serial lines are isolated with resistors to permit the other computer to overdrive the MCU's Rx line. 50 | 51 | ## Compiling 52 | 53 | * Install PlatformIO according to instructions on the Web. You can use any IDE/editing environment that you like. Many people use PlatformIO under VSCode, but it also works with many other editors. 54 | * Edit platformio.ini and set "default_envs" to the name of the MCU you want to use. The name should match one of the "env:" values in platformio.ini 55 | * Click the IDE's "Upload" button, or execute "pio run -t upload" if you are running PlatformIO from the command line. 56 | * Connect a serial monitor program to the primary UART of the MCU. It should display a message whenever the FluidNC state changes (Idle, Cycle, Hold, etc). 57 | -------------------------------------------------------------------------------- /Playlist/include/README: -------------------------------------------------------------------------------- 1 | 2 | This directory is intended for project header files. 3 | 4 | A header file is a file containing C declarations and macro definitions 5 | to be shared between several project source files. You request the use of a 6 | header file in your project source file (C, C++, etc) located in `src` folder 7 | by including it, with the C preprocessing directive `#include'. 8 | 9 | ```src/main.c 10 | 11 | #include "header.h" 12 | 13 | int main (void) 14 | { 15 | ... 16 | } 17 | ``` 18 | 19 | Including a header file produces the same results as copying the header file 20 | into each source file that needs it. Such copying would be time-consuming 21 | and error-prone. With a header file, the related declarations appear 22 | in only one place. If they need to be changed, they can be changed in one 23 | place, and programs that include the header file will automatically use the 24 | new version when next recompiled. The header file eliminates the labor of 25 | finding and changing all the copies as well as the risk that a failure to 26 | find one copy will result in inconsistencies within a program. 27 | 28 | In C, the usual convention is to give header files names that end with `.h'. 29 | It is most portable to use only letters, digits, dashes, and underscores in 30 | header file names, and at most one dot. 31 | 32 | Read more about using header files in official GCC documentation: 33 | 34 | * Include Syntax 35 | * Include Operation 36 | * Once-Only Headers 37 | * Computed Includes 38 | 39 | https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html 40 | -------------------------------------------------------------------------------- /Playlist/platformio.ini: -------------------------------------------------------------------------------- 1 | ; PlatformIO Project Configuration File 2 | ; 3 | ; Build options: build flags, source filter 4 | ; Upload options: custom upload port, speed and extra flags 5 | ; Library options: dependencies, extra library storages 6 | ; Advanced options: extra scripting 7 | ; 8 | ; Please visit documentation for the other options and examples 9 | ; https://docs.platformio.org/page/projectconf.html 10 | 11 | [platformio] 12 | default_envs = megaatmega2560 13 | lib_dir = ../lib 14 | 15 | [env] 16 | framework = arduino 17 | monitor_speed = 115200 18 | lib_deps = https://github.com/MitchBradley/GrblParser 19 | 20 | [env:nano] 21 | ; The nano build currently fails due to not fitting in FLASH 22 | platform = atmelavr 23 | board = nanoatmega168 24 | upload_port = COM7 25 | monitor_port = COM7 26 | 27 | [env:megaatmega2560] 28 | platform = atmelavr 29 | board = megaatmega2560 30 | 31 | [env:esp32] 32 | platform = espressif32 33 | board = esp32dev 34 | 35 | [env:esp32s2] 36 | platform = espressif32 37 | board = nodemcu-32s2 38 | 39 | [env:esp32s3] 40 | platform = espressif32 41 | board = esp32-s3-devkitc-1 42 | 43 | [env:esp32c3] 44 | platform = espressif32 45 | board = esp32-c3-devkitc-02 46 | 47 | [env:esp8266] 48 | platform = espressif8266 49 | board = d1_mini 50 | 51 | [env:stm32] 52 | platform = ststm32 53 | board = bluepill_f103c6 54 | -------------------------------------------------------------------------------- /Playlist/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "GrblParserC.h" 3 | 4 | #define FNCSerial Serial 5 | 6 | // Cycle through the files named in this list 7 | const char* playlist[] = { "file1.nc", "file2.nc", "file3.nc" }; 8 | size_t next_file = 0; 9 | 10 | void start_next_run() { 11 | if (next_file == sizeof(playlist) / sizeof(*playlist)) { 12 | next_file = 0; 13 | } 14 | String msg("$SD/Run="); 15 | msg += playlist[next_file++]; 16 | fnc_send_line(msg.c_str(), 1000); 17 | } 18 | 19 | bool program_sent = false; 20 | String last_state = ""; 21 | String last_filename = ""; 22 | 23 | extern "C" void show_state(const char* state) { 24 | String this_state = state; 25 | // Wait until the program has been sent and the state changes 26 | // from Run to Idle. After the program has been sent, it 27 | // usually takes some time before its last few lines finish running. 28 | if (program_sent && this_state == "Idle" && last_state == "Run") { 29 | start_next_run(); 30 | program_sent = false; 31 | } 32 | last_state = this_state; 33 | } 34 | 35 | extern "C" void show_file(const char* filename, file_percent_t percent) { 36 | // When we stop seeing SD: fields in the status report 37 | // after having just seen one, we know that the file has 38 | // been sent. It might still be running though, since 39 | // GCode commands can take awhile to finish. 40 | if (last_filename != "" && *filename == '\0') { 41 | program_sent = true; 42 | } 43 | last_filename = filename; 44 | } 45 | extern "C" int fnc_getchar() { 46 | if (FNCSerial.available()) { 47 | return FNCSerial.read(); 48 | } 49 | return -1; 50 | } 51 | int milliseconds() { 52 | return millis(); 53 | } 54 | 55 | extern "C" void fnc_putchar(uint8_t c) { 56 | FNCSerial.write(c); 57 | } 58 | 59 | void setup() { 60 | FNCSerial.begin(115200); 61 | fnc_wait_ready(); 62 | fnc_putchar('?'); // Initial status report 63 | start_next_run(); 64 | } 65 | void loop() { 66 | fnc_poll(); 67 | } 68 | -------------------------------------------------------------------------------- /Playlist/test/README: -------------------------------------------------------------------------------- 1 | 2 | This directory is intended for PlatformIO Test Runner and project tests. 3 | 4 | Unit Testing is a software testing method by which individual units of 5 | source code, sets of one or more MCU program modules together with associated 6 | control data, usage procedures, and operating procedures, are tested to 7 | determine whether they are fit for use. Unit testing finds problems early 8 | in the development cycle. 9 | 10 | More information about PlatformIO Unit Testing: 11 | - https://docs.platformio.org/en/latest/advanced/unit-testing/index.html 12 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PendantsForFluidNC 2 | Pendants for controlling FluidNC CNC firmware 3 | 4 | This is a collection of example "pendant" programs showing how to 5 | program a auxiliary microcontroller or other computer to interact 6 | with a FluidNC CNC controller. FluidNC uses the [GRBL serial 7 | line protocol](https://github.com/gnea/grbl/wiki/Grbl-v1.1-Interface) 8 | for control and status. Unlike classic GRBL controllers which 9 | speak that serial protocol on only one serial port, 10 | FluidNC can have multiple "channels" simultaneously speaking 11 | the serial protocol. The additional channels can include 12 | extra serial ports, TCP/Telnet connections, and TCP/WebSocket 13 | connections. 14 | 15 | Another serial port (UART) is an excellent way to connect an auxiliary 16 | microcontroller (MCU). Every MCU has at least one UART, and most have 17 | two or more. A UART needs only two signal lines and in some use 18 | cases only one. Most MCU UARTs can operate at least as fast as 19 | 115200 baud (10K characters per second) and some can go up to 20 | 1Mbaud (100K characters per second) or more. That is typically 21 | fast enough for a lot of interesting use cases. 22 | 23 | ## What is a Pendant? 24 | 25 | In addition to the main operator's console, traditional CNC machines 26 | often included an auxiliary control box that hung from a cable near 27 | the machine. Those boxes were called "pendants" because they were 28 | hanging or suspended from overhead. Typically pendants could perform a 29 | subset of the most common operations like jogging and job 30 | start/pause/stop. Thus the word "pendant" has come to mean any small 31 | auxilary control for a CNC machine. 32 | 33 | A FluidNC Pendant that is implemented on a small MCU can be very 34 | inexpensive, since suitable MCUs can cost in the range of $1 to a few 35 | dollars. The packaging and user-facing I/O devices (small displays, 36 | pushbuttons, etc) are likely to dominate the cost. 37 | 38 | ## What Can FluidNC Pendants Do? 39 | 40 | In principle, a FluidNC Pendant could do anything that a traditional 41 | GCode Sender program can do, limited only by the resources of the 42 | MCU on which it is implemented. Typically, a given pendant will 43 | only do a targeted subset of the possibilities, because otherwise 44 | it would be just another sender requiring a full computer. Some 45 | examples of small-pendant use cases include: 46 | 47 | * Running "playlists" for art machines 48 | * Jog controllers 49 | * Input expansion 50 | * Extra displays like light towers or OLEDs, to show machine state 51 | 52 | ## How Do I Use This Code? 53 | 54 | This code is a collection of examples to help you develop your own 55 | custom pendants. Many of the examples can be compiled for several 56 | different MCUs, including various ESP32 variants, AVR Arduinos and 57 | some ARM MCUs. We expect that you will start with an example that 58 | is similar to your desired gadget and modify/extend it for your needs. 59 | We do not provide free consultation for doing that. 60 | 61 | One of the basic components that is useful for display pendants is 62 | the GrblParser class. GrblParser decodes standard GRBL protocol 63 | report messages and calls user-supplied code to display the information 64 | therein. 65 | 66 | ## Support 67 | 68 | This code is not supported. It is provided as a courtesy to help 69 | you get started. If you have ideas for new features, please implement 70 | them yourself or contract with someone to do so. 71 | -------------------------------------------------------------------------------- /RunLED/.gitignore: -------------------------------------------------------------------------------- 1 | .pio 2 | .vscode 3 | *~ 4 | *.o 5 | *.d 6 | *.lst 7 | *.map 8 | build 9 | -------------------------------------------------------------------------------- /RunLED/README.md: -------------------------------------------------------------------------------- 1 | # Display to Terminal Pendant 2 | 3 | This pendant requires a microcontroller with one UART and a 4 | single LED identified by the Arduino LED_BUILTIN macro. The 5 | UART connects to a FluidNC controller and the LED lights when 6 | the FluidNC controller is in Cycle state (moving). 7 | 8 | This example pendant could be extended to show additional 9 | states by adding more LEDs or by using a multicolor LED. 10 | 11 | ## Wiring 12 | 13 | Connect a secondary UART on the FluidNC controller to the primary UART 14 | on the MCU. Connect MCU Tx to FluidNC Rx and vice versa. If the MCU 15 | has 5V IO, you will need level conversion on the MCU Tx to FluidNC Rx 16 | line. It could be just a resistive voltage divider like this: 17 | 18 | MCU Tx ---XXXX------ FluidNC Rx 19 | 2.2K | 20 | resistor X 21 | X 3.3K resistor 22 | X 23 | | 24 | MCU GND --------------FluidNC GND 25 | 26 | 27 | If the MCU has 3.3V IO, you can connect directly with no level shifting. 28 | 29 | The FluidNC Tx to MCU Rx line typically can be directly connected, 30 | since a 3.3V output can drive a 5V input safely and effectively. 31 | 32 | ## Example FluidNC Config Section 33 | 34 | ```yaml 35 | uart1: 36 | txd_pin: gpio.17 37 | rxd_pin: gpio.16 38 | baud: 115200 39 | mode: 8N1 40 | uart_channel1: 41 | uart_num: 1 42 | report_interval_ms: 400 43 | ``` 44 | 45 | ## Assigning UART Pins 46 | 47 | On the FluidNC controller you can assign the UART pins in the config file; just change gpio.17 and gpio.16 in the example above. 48 | 49 | On the MCU, the Arduino framework assigns IO pins to the primary UART according to a board definition file. platformio.ini has "env:" sections for various MCUs. Each such env: section has a "board =" line that selects a particular board that has that MCU. Set that line to the name of a board that is compatible with the one you are using. Ask the internet for help if you don't understand that. 50 | 51 | On some MCUs, the primary UART is also connected to a USB-Serial chip so it can be connected to a PC. It is often possible to connect that primary UART directly to another computer, if the USB-serial lines are isolated with resistors to permit the other computer to overdrive the MCU's Rx line. 52 | 53 | ## Compiling 54 | 55 | * Install PlatformIO according to instructions on the Web. You can use any IDE/editing environment that you like. Many people use PlatformIO under VSCode, but it also works with many other editors. 56 | * Edit platformio.ini and set "default_envs" to the name of the MCU you want to use. The name should match one of the "env:" values in platformio.ini 57 | * Click the IDE's "Upload" button, or execute "pio run -t upload" if you are running PlatformIO from the command line. 58 | * Connect a serial monitor program to the primary UART of the MCU. It should display a message whenever the FluidNC state changes (Idle, Cycle, Hold, etc). 59 | -------------------------------------------------------------------------------- /RunLED/include/README: -------------------------------------------------------------------------------- 1 | 2 | This directory is intended for project header files. 3 | 4 | A header file is a file containing C declarations and macro definitions 5 | to be shared between several project source files. You request the use of a 6 | header file in your project source file (C, C++, etc) located in `src` folder 7 | by including it, with the C preprocessing directive `#include'. 8 | 9 | ```src/main.c 10 | 11 | #include "header.h" 12 | 13 | int main (void) 14 | { 15 | ... 16 | } 17 | ``` 18 | 19 | Including a header file produces the same results as copying the header file 20 | into each source file that needs it. Such copying would be time-consuming 21 | and error-prone. With a header file, the related declarations appear 22 | in only one place. If they need to be changed, they can be changed in one 23 | place, and programs that include the header file will automatically use the 24 | new version when next recompiled. The header file eliminates the labor of 25 | finding and changing all the copies as well as the risk that a failure to 26 | find one copy will result in inconsistencies within a program. 27 | 28 | In C, the usual convention is to give header files names that end with `.h'. 29 | It is most portable to use only letters, digits, dashes, and underscores in 30 | header file names, and at most one dot. 31 | 32 | Read more about using header files in official GCC documentation: 33 | 34 | * Include Syntax 35 | * Include Operation 36 | * Once-Only Headers 37 | * Computed Includes 38 | 39 | https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html 40 | -------------------------------------------------------------------------------- /RunLED/platformio.ini: -------------------------------------------------------------------------------- 1 | ; PlatformIO Project Configuration File 2 | ; 3 | ; Build options: build flags, source filter 4 | ; Upload options: custom upload port, speed and extra flags 5 | ; Library options: dependencies, extra library storages 6 | ; Advanced options: extra scripting 7 | ; 8 | ; Please visit documentation for the other options and examples 9 | ; https://docs.platformio.org/page/projectconf.html 10 | 11 | [platformio] 12 | default_envs = megaatmega2560 13 | lib_dir = ../lib 14 | 15 | [env] 16 | framework = arduino 17 | monitor_speed = 115200 18 | lib_deps = https://github.com/MitchBradley/GrblParser 19 | 20 | [env:megaatmega2560] 21 | framework = arduino 22 | platform = atmelavr 23 | board = megaatmega2560 24 | upload_port = COM7 25 | monitor_port = COM7 26 | 27 | [env:esp32] 28 | platform = espressif32 29 | board = esp32dev 30 | 31 | [env:esp32s2] 32 | platform = espressif32 33 | board = nodemcu-32s2 34 | 35 | [env:esp32s3] 36 | platform = espressif32 37 | board = esp32-s3-devkitc-1 38 | 39 | [env:esp32c3] 40 | platform = espressif32 41 | board = esp32-c3-devkitc-02 42 | 43 | [env:esp8266] 44 | platform = espressif8266 45 | board = d1_mini 46 | 47 | [env:stm32] 48 | platform = ststm32 49 | board = bluepill_f103c6 50 | -------------------------------------------------------------------------------- /RunLED/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "GrblParserC.h" 3 | 4 | #define UART Serial1 5 | 6 | extern "C" void show_state(const char* state) { 7 | digitalWrite(LED_BUILTIN, (strcmp(state, "Run") == 0) ? HIGH : LOW); 8 | } 9 | 10 | extern "C" int fnc_getchar() { 11 | if (UART.available()) { 12 | return UART.read(); 13 | } 14 | return -1; 15 | } 16 | 17 | int milliseconds() { 18 | return millis(); 19 | } 20 | 21 | extern "C" void fnc_putchar(uint8_t c) { 22 | UART.write(c); 23 | } 24 | 25 | void setup() { 26 | pinMode(LED_BUILTIN, OUTPUT); 27 | UART.begin(115200); 28 | fnc_wait_ready(); // Synchronize to FluidNC 29 | fnc_putchar('?'); // Initial status report 30 | } 31 | void loop() { 32 | fnc_poll(); 33 | } 34 | -------------------------------------------------------------------------------- /RunLED/test/README: -------------------------------------------------------------------------------- 1 | 2 | This directory is intended for PlatformIO Test Runner and project tests. 3 | 4 | Unit Testing is a software testing method by which individual units of 5 | source code, sets of one or more MCU program modules together with associated 6 | control data, usage procedures, and operating procedures, are tested to 7 | determine whether they are fit for use. Unit testing finds problems early 8 | in the development cycle. 9 | 10 | More information about PlatformIO Unit Testing: 11 | - https://docs.platformio.org/en/latest/advanced/unit-testing/index.html 12 | -------------------------------------------------------------------------------- /STM32_Expander/.gitignore: -------------------------------------------------------------------------------- 1 | .pio 2 | .vscode 3 | *~ 4 | *.o 5 | *.d 6 | *.lst 7 | *.map 8 | build 9 | -------------------------------------------------------------------------------- /STM32_Expander/.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | // See http://go.microsoft.com/fwlink/?LinkId=827846 3 | // for the documentation about the extensions.json format 4 | "recommendations": [ 5 | "platformio.platformio-ide" 6 | ], 7 | "unwantedRecommendations": [ 8 | "ms-vscode.cpptools-extension-pack" 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /STM32_Expander/CubeMX/.clang-format: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bdring/PendantsForFluidNC/320abd6fb509cd806d1a9ff08472a64dc7e0c971/STM32_Expander/CubeMX/.clang-format -------------------------------------------------------------------------------- /STM32_Expander/CubeMX/.mxproject: -------------------------------------------------------------------------------- 1 | [PreviousLibFiles] 2 | LibFiles=Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_tim.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_tim_ex.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_tim.h;Drivers\STM32F1xx_HAL_Driver\Inc\Legacy\stm32_hal_legacy.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_def.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_rcc.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_rcc_ex.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_bus.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_rcc.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_system.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_utils.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_gpio.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_gpio_ex.h;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_gpio_ex.c;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_gpio.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_dma_ex.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_dma.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_dma.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_cortex.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_cortex.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_pwr.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_pwr.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_flash.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_flash_ex.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_exti.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_exti.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_uart.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_usart.h;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_tim.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_tim_ex.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_rcc.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_rcc_ex.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_gpio.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_dma.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_cortex.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_pwr.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_flash.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_flash_ex.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_exti.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_uart.c;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_tim.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_tim_ex.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_tim.h;Drivers\STM32F1xx_HAL_Driver\Inc\Legacy\stm32_hal_legacy.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_def.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_rcc.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_rcc_ex.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_bus.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_rcc.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_system.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_utils.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_gpio.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_gpio_ex.h;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_gpio_ex.c;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_gpio.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_dma_ex.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_dma.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_dma.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_cortex.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_cortex.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_pwr.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_pwr.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_flash.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_flash_ex.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_exti.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_exti.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_uart.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_usart.h;Drivers\CMSIS\Device\ST\STM32F1xx\Include\stm32f103xb.h;Drivers\CMSIS\Device\ST\STM32F1xx\Include\stm32f1xx.h;Drivers\CMSIS\Device\ST\STM32F1xx\Include\system_stm32f1xx.h;Drivers\CMSIS\Device\ST\STM32F1xx\Source\Templates\system_stm32f1xx.c;Drivers\CMSIS\Include\cmsis_armcc.h;Drivers\CMSIS\Include\cmsis_armclang.h;Drivers\CMSIS\Include\cmsis_compiler.h;Drivers\CMSIS\Include\cmsis_gcc.h;Drivers\CMSIS\Include\cmsis_iccarm.h;Drivers\CMSIS\Include\cmsis_version.h;Drivers\CMSIS\Include\core_armv8mbl.h;Drivers\CMSIS\Include\core_armv8mml.h;Drivers\CMSIS\Include\core_cm0.h;Drivers\CMSIS\Include\core_cm0plus.h;Drivers\CMSIS\Include\core_cm1.h;Drivers\CMSIS\Include\core_cm23.h;Drivers\CMSIS\Include\core_cm3.h;Drivers\CMSIS\Include\core_cm33.h;Drivers\CMSIS\Include\core_cm4.h;Drivers\CMSIS\Include\core_cm7.h;Drivers\CMSIS\Include\core_sc000.h;Drivers\CMSIS\Include\core_sc300.h;Drivers\CMSIS\Include\mpu_armv7.h;Drivers\CMSIS\Include\mpu_armv8.h;Drivers\CMSIS\Include\tz_context.h; 3 | 4 | [PreviousUsedMakefileFiles] 5 | SourceFiles=Core\Src\main.c;Core\Src\gpio.c;Core\Src\dma.c;Core\Src\tim.c;Core\Src\usart.c;Core\Src\stm32f1xx_it.c;Core\Src\stm32f1xx_hal_msp.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_gpio_ex.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_tim.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_tim_ex.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_rcc.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_rcc_ex.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_gpio.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_dma.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_cortex.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_pwr.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_flash.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_flash_ex.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_exti.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_uart.c;Drivers\CMSIS\Device\ST\STM32F1xx\Source\Templates\system_stm32f1xx.c;Core\Src\system_stm32f1xx.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_gpio_ex.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_tim.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_tim_ex.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_rcc.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_rcc_ex.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_gpio.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_dma.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_cortex.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_pwr.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_flash.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_flash_ex.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_exti.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_uart.c;Drivers\CMSIS\Device\ST\STM32F1xx\Source\Templates\system_stm32f1xx.c;Core\Src\system_stm32f1xx.c;;; 6 | HeaderPath=Drivers\STM32F1xx_HAL_Driver\Inc;Drivers\STM32F1xx_HAL_Driver\Inc\Legacy;Drivers\CMSIS\Device\ST\STM32F1xx\Include;Drivers\CMSIS\Include;Core\Inc; 7 | CDefines=USE_HAL_DRIVER;STM32F103xB;USE_HAL_DRIVER;USE_HAL_DRIVER; 8 | 9 | [PreviousGenFiles] 10 | AdvancedFolderStructure=true 11 | HeaderFileListSize=7 12 | HeaderFiles#0=..\Core\Inc\gpio.h 13 | HeaderFiles#1=..\Core\Inc\dma.h 14 | HeaderFiles#2=..\Core\Inc\tim.h 15 | HeaderFiles#3=..\Core\Inc\usart.h 16 | HeaderFiles#4=..\Core\Inc\stm32f1xx_it.h 17 | HeaderFiles#5=..\Core\Inc\stm32f1xx_hal_conf.h 18 | HeaderFiles#6=..\Core\Inc\main.h 19 | HeaderFolderListSize=1 20 | HeaderPath#0=..\Core\Inc 21 | HeaderFiles=; 22 | SourceFileListSize=7 23 | SourceFiles#0=..\Core\Src\gpio.c 24 | SourceFiles#1=..\Core\Src\dma.c 25 | SourceFiles#2=..\Core\Src\tim.c 26 | SourceFiles#3=..\Core\Src\usart.c 27 | SourceFiles#4=..\Core\Src\stm32f1xx_it.c 28 | SourceFiles#5=..\Core\Src\stm32f1xx_hal_msp.c 29 | SourceFiles#6=..\Core\Src\main.c 30 | SourceFolderListSize=1 31 | SourcePath#0=..\Core\Src 32 | SourceFiles=; 33 | 34 | -------------------------------------------------------------------------------- /STM32_Expander/CubeMX/Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f1xx.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file stm32f1xx.h 4 | * @author MCD Application Team 5 | * @brief CMSIS STM32F1xx Device Peripheral Access Layer Header File. 6 | * 7 | * The file is the unique include file that the application programmer 8 | * is using in the C source code, usually in main.c. This file contains: 9 | * - Configuration section that allows to select: 10 | * - The STM32F1xx device used in the target application 11 | * - To use or not the peripheral's drivers in application code(i.e. 12 | * code will be based on direct access to peripheral's registers 13 | * rather than drivers API), this option is controlled by 14 | * "#define USE_HAL_DRIVER" 15 | * 16 | ****************************************************************************** 17 | * @attention 18 | * 19 | * Copyright (c) 2017-2021 STMicroelectronics. 20 | * All rights reserved. 21 | * 22 | * This software is licensed under terms that can be found in the LICENSE file 23 | * in the root directory of this software component. 24 | * If no LICENSE file comes with this software, it is provided AS-IS. 25 | * 26 | ****************************************************************************** 27 | */ 28 | 29 | /** @addtogroup CMSIS 30 | * @{ 31 | */ 32 | 33 | /** @addtogroup stm32f1xx 34 | * @{ 35 | */ 36 | 37 | #ifndef __STM32F1XX_H 38 | #define __STM32F1XX_H 39 | 40 | #ifdef __cplusplus 41 | extern "C" { 42 | #endif /* __cplusplus */ 43 | 44 | /** @addtogroup Library_configuration_section 45 | * @{ 46 | */ 47 | 48 | /** 49 | * @brief STM32 Family 50 | */ 51 | #if !defined (STM32F1) 52 | #define STM32F1 53 | #endif /* STM32F1 */ 54 | 55 | /* Uncomment the line below according to the target STM32L device used in your 56 | application 57 | */ 58 | 59 | #if !defined (STM32F100xB) && !defined (STM32F100xE) && !defined (STM32F101x6) && \ 60 | !defined (STM32F101xB) && !defined (STM32F101xE) && !defined (STM32F101xG) && !defined (STM32F102x6) && !defined (STM32F102xB) && !defined (STM32F103x6) && \ 61 | !defined (STM32F103xB) && !defined (STM32F103xE) && !defined (STM32F103xG) && !defined (STM32F105xC) && !defined (STM32F107xC) 62 | /* #define STM32F100xB */ /*!< STM32F100C4, STM32F100R4, STM32F100C6, STM32F100R6, STM32F100C8, STM32F100R8, STM32F100V8, STM32F100CB, STM32F100RB and STM32F100VB */ 63 | /* #define STM32F100xE */ /*!< STM32F100RC, STM32F100VC, STM32F100ZC, STM32F100RD, STM32F100VD, STM32F100ZD, STM32F100RE, STM32F100VE and STM32F100ZE */ 64 | /* #define STM32F101x6 */ /*!< STM32F101C4, STM32F101R4, STM32F101T4, STM32F101C6, STM32F101R6 and STM32F101T6 Devices */ 65 | /* #define STM32F101xB */ /*!< STM32F101C8, STM32F101R8, STM32F101T8, STM32F101V8, STM32F101CB, STM32F101RB, STM32F101TB and STM32F101VB */ 66 | /* #define STM32F101xE */ /*!< STM32F101RC, STM32F101VC, STM32F101ZC, STM32F101RD, STM32F101VD, STM32F101ZD, STM32F101RE, STM32F101VE and STM32F101ZE */ 67 | /* #define STM32F101xG */ /*!< STM32F101RF, STM32F101VF, STM32F101ZF, STM32F101RG, STM32F101VG and STM32F101ZG */ 68 | /* #define STM32F102x6 */ /*!< STM32F102C4, STM32F102R4, STM32F102C6 and STM32F102R6 */ 69 | /* #define STM32F102xB */ /*!< STM32F102C8, STM32F102R8, STM32F102CB and STM32F102RB */ 70 | /* #define STM32F103x6 */ /*!< STM32F103C4, STM32F103R4, STM32F103T4, STM32F103C6, STM32F103R6 and STM32F103T6 */ 71 | /* #define STM32F103xB */ /*!< STM32F103C8, STM32F103R8, STM32F103T8, STM32F103V8, STM32F103CB, STM32F103RB, STM32F103TB and STM32F103VB */ 72 | /* #define STM32F103xE */ /*!< STM32F103RC, STM32F103VC, STM32F103ZC, STM32F103RD, STM32F103VD, STM32F103ZD, STM32F103RE, STM32F103VE and STM32F103ZE */ 73 | /* #define STM32F103xG */ /*!< STM32F103RF, STM32F103VF, STM32F103ZF, STM32F103RG, STM32F103VG and STM32F103ZG */ 74 | /* #define STM32F105xC */ /*!< STM32F105R8, STM32F105V8, STM32F105RB, STM32F105VB, STM32F105RC and STM32F105VC */ 75 | /* #define STM32F107xC */ /*!< STM32F107RB, STM32F107VB, STM32F107RC and STM32F107VC */ 76 | #endif 77 | 78 | /* Tip: To avoid modifying this file each time you need to switch between these 79 | devices, you can define the device in your toolchain compiler preprocessor. 80 | */ 81 | 82 | #if !defined (USE_HAL_DRIVER) 83 | /** 84 | * @brief Comment the line below if you will not use the peripherals drivers. 85 | In this case, these drivers will not be included and the application code will 86 | be based on direct access to peripherals registers 87 | */ 88 | /*#define USE_HAL_DRIVER */ 89 | #endif /* USE_HAL_DRIVER */ 90 | 91 | /** 92 | * @brief CMSIS Device version number 93 | */ 94 | #define __STM32F1_CMSIS_VERSION_MAIN (0x04) /*!< [31:24] main version */ 95 | #define __STM32F1_CMSIS_VERSION_SUB1 (0x03) /*!< [23:16] sub1 version */ 96 | #define __STM32F1_CMSIS_VERSION_SUB2 (0x04) /*!< [15:8] sub2 version */ 97 | #define __STM32F1_CMSIS_VERSION_RC (0x00) /*!< [7:0] release candidate */ 98 | #define __STM32F1_CMSIS_VERSION ((__STM32F1_CMSIS_VERSION_MAIN << 24)\ 99 | |(__STM32F1_CMSIS_VERSION_SUB1 << 16)\ 100 | |(__STM32F1_CMSIS_VERSION_SUB2 << 8 )\ 101 | |(__STM32F1_CMSIS_VERSION_RC)) 102 | 103 | /** 104 | * @} 105 | */ 106 | 107 | /** @addtogroup Device_Included 108 | * @{ 109 | */ 110 | 111 | #if defined(STM32F100xB) 112 | #include "stm32f100xb.h" 113 | #elif defined(STM32F100xE) 114 | #include "stm32f100xe.h" 115 | #elif defined(STM32F101x6) 116 | #include "stm32f101x6.h" 117 | #elif defined(STM32F101xB) 118 | #include "stm32f101xb.h" 119 | #elif defined(STM32F101xE) 120 | #include "stm32f101xe.h" 121 | #elif defined(STM32F101xG) 122 | #include "stm32f101xg.h" 123 | #elif defined(STM32F102x6) 124 | #include "stm32f102x6.h" 125 | #elif defined(STM32F102xB) 126 | #include "stm32f102xb.h" 127 | #elif defined(STM32F103x6) 128 | #include "stm32f103x6.h" 129 | #elif defined(STM32F103xB) 130 | #include "stm32f103xb.h" 131 | #elif defined(STM32F103xE) 132 | #include "stm32f103xe.h" 133 | #elif defined(STM32F103xG) 134 | #include "stm32f103xg.h" 135 | #elif defined(STM32F105xC) 136 | #include "stm32f105xc.h" 137 | #elif defined(STM32F107xC) 138 | #include "stm32f107xc.h" 139 | #else 140 | #error "Please select first the target STM32F1xx device used in your application (in stm32f1xx.h file)" 141 | #endif 142 | 143 | /** 144 | * @} 145 | */ 146 | 147 | /** @addtogroup Exported_types 148 | * @{ 149 | */ 150 | typedef enum 151 | { 152 | RESET = 0, 153 | SET = !RESET 154 | } FlagStatus, ITStatus; 155 | 156 | typedef enum 157 | { 158 | DISABLE = 0, 159 | ENABLE = !DISABLE 160 | } FunctionalState; 161 | #define IS_FUNCTIONAL_STATE(STATE) (((STATE) == DISABLE) || ((STATE) == ENABLE)) 162 | 163 | typedef enum 164 | { 165 | SUCCESS = 0U, 166 | ERROR = !SUCCESS 167 | } ErrorStatus; 168 | 169 | /** 170 | * @} 171 | */ 172 | 173 | 174 | /** @addtogroup Exported_macros 175 | * @{ 176 | */ 177 | #define SET_BIT(REG, BIT) ((REG) |= (BIT)) 178 | 179 | #define CLEAR_BIT(REG, BIT) ((REG) &= ~(BIT)) 180 | 181 | #define READ_BIT(REG, BIT) ((REG) & (BIT)) 182 | 183 | #define CLEAR_REG(REG) ((REG) = (0x0)) 184 | 185 | #define WRITE_REG(REG, VAL) ((REG) = (VAL)) 186 | 187 | #define READ_REG(REG) ((REG)) 188 | 189 | #define MODIFY_REG(REG, CLEARMASK, SETMASK) WRITE_REG((REG), (((READ_REG(REG)) & (~(CLEARMASK))) | (SETMASK))) 190 | 191 | #define POSITION_VAL(VAL) (__CLZ(__RBIT(VAL))) 192 | 193 | /* Use of CMSIS compiler intrinsics for register exclusive access */ 194 | /* Atomic 32-bit register access macro to set one or several bits */ 195 | #define ATOMIC_SET_BIT(REG, BIT) \ 196 | do { \ 197 | uint32_t val; \ 198 | do { \ 199 | val = __LDREXW((__IO uint32_t *)&(REG)) | (BIT); \ 200 | } while ((__STREXW(val,(__IO uint32_t *)&(REG))) != 0U); \ 201 | } while(0) 202 | 203 | /* Atomic 32-bit register access macro to clear one or several bits */ 204 | #define ATOMIC_CLEAR_BIT(REG, BIT) \ 205 | do { \ 206 | uint32_t val; \ 207 | do { \ 208 | val = __LDREXW((__IO uint32_t *)&(REG)) & ~(BIT); \ 209 | } while ((__STREXW(val,(__IO uint32_t *)&(REG))) != 0U); \ 210 | } while(0) 211 | 212 | /* Atomic 32-bit register access macro to clear and set one or several bits */ 213 | #define ATOMIC_MODIFY_REG(REG, CLEARMSK, SETMASK) \ 214 | do { \ 215 | uint32_t val; \ 216 | do { \ 217 | val = (__LDREXW((__IO uint32_t *)&(REG)) & ~(CLEARMSK)) | (SETMASK); \ 218 | } while ((__STREXW(val,(__IO uint32_t *)&(REG))) != 0U); \ 219 | } while(0) 220 | 221 | /* Atomic 16-bit register access macro to set one or several bits */ 222 | #define ATOMIC_SETH_BIT(REG, BIT) \ 223 | do { \ 224 | uint16_t val; \ 225 | do { \ 226 | val = __LDREXH((__IO uint16_t *)&(REG)) | (BIT); \ 227 | } while ((__STREXH(val,(__IO uint16_t *)&(REG))) != 0U); \ 228 | } while(0) 229 | 230 | /* Atomic 16-bit register access macro to clear one or several bits */ 231 | #define ATOMIC_CLEARH_BIT(REG, BIT) \ 232 | do { \ 233 | uint16_t val; \ 234 | do { \ 235 | val = __LDREXH((__IO uint16_t *)&(REG)) & ~(BIT); \ 236 | } while ((__STREXH(val,(__IO uint16_t *)&(REG))) != 0U); \ 237 | } while(0) 238 | 239 | /* Atomic 16-bit register access macro to clear and set one or several bits */ 240 | #define ATOMIC_MODIFYH_REG(REG, CLEARMSK, SETMASK) \ 241 | do { \ 242 | uint16_t val; \ 243 | do { \ 244 | val = (__LDREXH((__IO uint16_t *)&(REG)) & ~(CLEARMSK)) | (SETMASK); \ 245 | } while ((__STREXH(val,(__IO uint16_t *)&(REG))) != 0U); \ 246 | } while(0) 247 | 248 | 249 | /** 250 | * @} 251 | */ 252 | 253 | #if defined (USE_HAL_DRIVER) 254 | #include "stm32f1xx_hal.h" 255 | #endif /* USE_HAL_DRIVER */ 256 | 257 | 258 | #ifdef __cplusplus 259 | } 260 | #endif /* __cplusplus */ 261 | 262 | #endif /* __STM32F1xx_H */ 263 | /** 264 | * @} 265 | */ 266 | 267 | /** 268 | * @} 269 | */ 270 | 271 | 272 | 273 | 274 | -------------------------------------------------------------------------------- /STM32_Expander/CubeMX/Drivers/CMSIS/Device/ST/STM32F1xx/Include/system_stm32f1xx.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file system_stm32f1xx.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-2021 STMicroelectronics. 10 | * All rights reserved. 11 | * 12 | * This software is licensed under terms that can be found in the LICENSE file 13 | * in the root directory of this software component. 14 | * If no LICENSE file comes with this software, it is provided AS-IS. 15 | * 16 | ****************************************************************************** 17 | */ 18 | 19 | /** @addtogroup CMSIS 20 | * @{ 21 | */ 22 | 23 | /** @addtogroup stm32f10x_system 24 | * @{ 25 | */ 26 | 27 | /** 28 | * @brief Define to prevent recursive inclusion 29 | */ 30 | #ifndef __SYSTEM_STM32F10X_H 31 | #define __SYSTEM_STM32F10X_H 32 | 33 | #ifdef __cplusplus 34 | extern "C" { 35 | #endif 36 | 37 | /** @addtogroup STM32F10x_System_Includes 38 | * @{ 39 | */ 40 | 41 | /** 42 | * @} 43 | */ 44 | 45 | 46 | /** @addtogroup STM32F10x_System_Exported_types 47 | * @{ 48 | */ 49 | 50 | extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */ 51 | extern const uint8_t AHBPrescTable[16U]; /*!< AHB prescalers table values */ 52 | extern const uint8_t APBPrescTable[8U]; /*!< APB prescalers table values */ 53 | 54 | /** 55 | * @} 56 | */ 57 | 58 | /** @addtogroup STM32F10x_System_Exported_Constants 59 | * @{ 60 | */ 61 | 62 | /** 63 | * @} 64 | */ 65 | 66 | /** @addtogroup STM32F10x_System_Exported_Macros 67 | * @{ 68 | */ 69 | 70 | /** 71 | * @} 72 | */ 73 | 74 | /** @addtogroup STM32F10x_System_Exported_Functions 75 | * @{ 76 | */ 77 | 78 | extern void SystemInit(void); 79 | extern void SystemCoreClockUpdate(void); 80 | /** 81 | * @} 82 | */ 83 | 84 | #ifdef __cplusplus 85 | } 86 | #endif 87 | 88 | #endif /*__SYSTEM_STM32F10X_H */ 89 | 90 | /** 91 | * @} 92 | */ 93 | 94 | /** 95 | * @} 96 | */ 97 | -------------------------------------------------------------------------------- /STM32_Expander/CubeMX/Drivers/CMSIS/Device/ST/STM32F1xx/LICENSE.txt: -------------------------------------------------------------------------------- 1 | This software component is provided to you as part of a software package and 2 | applicable license terms are in the Package_license file. If you received this 3 | software component outside of a package or without applicable license terms, 4 | the terms of the Apache-2.0 license shall apply. 5 | You may obtain a copy of the Apache-2.0 at: 6 | https://opensource.org/licenses/Apache-2.0 7 | -------------------------------------------------------------------------------- /STM32_Expander/CubeMX/Drivers/CMSIS/Include/cmsis_compiler.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************//** 2 | * @file cmsis_compiler.h 3 | * @brief CMSIS compiler generic header file 4 | * @version V5.0.4 5 | * @date 10. January 2018 6 | ******************************************************************************/ 7 | /* 8 | * Copyright (c) 2009-2018 Arm Limited. All rights reserved. 9 | * 10 | * SPDX-License-Identifier: Apache-2.0 11 | * 12 | * Licensed under the Apache License, Version 2.0 (the License); you may 13 | * not use this file except in compliance with the License. 14 | * You may obtain a copy of the License at 15 | * 16 | * www.apache.org/licenses/LICENSE-2.0 17 | * 18 | * Unless required by applicable law or agreed to in writing, software 19 | * distributed under the License is distributed on an AS IS BASIS, WITHOUT 20 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 21 | * See the License for the specific language governing permissions and 22 | * limitations under the License. 23 | */ 24 | 25 | #ifndef __CMSIS_COMPILER_H 26 | #define __CMSIS_COMPILER_H 27 | 28 | #include 29 | 30 | /* 31 | * Arm Compiler 4/5 32 | */ 33 | #if defined ( __CC_ARM ) 34 | #include "cmsis_armcc.h" 35 | 36 | 37 | /* 38 | * Arm Compiler 6 (armclang) 39 | */ 40 | #elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) 41 | #include "cmsis_armclang.h" 42 | 43 | 44 | /* 45 | * GNU Compiler 46 | */ 47 | #elif defined ( __GNUC__ ) 48 | #include "cmsis_gcc.h" 49 | 50 | 51 | /* 52 | * IAR Compiler 53 | */ 54 | #elif defined ( __ICCARM__ ) 55 | #include 56 | 57 | 58 | /* 59 | * TI Arm Compiler 60 | */ 61 | #elif defined ( __TI_ARM__ ) 62 | #include 63 | 64 | #ifndef __ASM 65 | #define __ASM __asm 66 | #endif 67 | #ifndef __INLINE 68 | #define __INLINE inline 69 | #endif 70 | #ifndef __STATIC_INLINE 71 | #define __STATIC_INLINE static inline 72 | #endif 73 | #ifndef __STATIC_FORCEINLINE 74 | #define __STATIC_FORCEINLINE __STATIC_INLINE 75 | #endif 76 | #ifndef __NO_RETURN 77 | #define __NO_RETURN __attribute__((noreturn)) 78 | #endif 79 | #ifndef __USED 80 | #define __USED __attribute__((used)) 81 | #endif 82 | #ifndef __WEAK 83 | #define __WEAK __attribute__((weak)) 84 | #endif 85 | #ifndef __PACKED 86 | #define __PACKED __attribute__((packed)) 87 | #endif 88 | #ifndef __PACKED_STRUCT 89 | #define __PACKED_STRUCT struct __attribute__((packed)) 90 | #endif 91 | #ifndef __PACKED_UNION 92 | #define __PACKED_UNION union __attribute__((packed)) 93 | #endif 94 | #ifndef __UNALIGNED_UINT32 /* deprecated */ 95 | struct __attribute__((packed)) T_UINT32 { uint32_t v; }; 96 | #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) 97 | #endif 98 | #ifndef __UNALIGNED_UINT16_WRITE 99 | __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; 100 | #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void*)(addr))->v) = (val)) 101 | #endif 102 | #ifndef __UNALIGNED_UINT16_READ 103 | __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; 104 | #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) 105 | #endif 106 | #ifndef __UNALIGNED_UINT32_WRITE 107 | __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; 108 | #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) 109 | #endif 110 | #ifndef __UNALIGNED_UINT32_READ 111 | __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; 112 | #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) 113 | #endif 114 | #ifndef __ALIGNED 115 | #define __ALIGNED(x) __attribute__((aligned(x))) 116 | #endif 117 | #ifndef __RESTRICT 118 | #warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored. 119 | #define __RESTRICT 120 | #endif 121 | 122 | 123 | /* 124 | * TASKING Compiler 125 | */ 126 | #elif defined ( __TASKING__ ) 127 | /* 128 | * The CMSIS functions have been implemented as intrinsics in the compiler. 129 | * Please use "carm -?i" to get an up to date list of all intrinsics, 130 | * Including the CMSIS ones. 131 | */ 132 | 133 | #ifndef __ASM 134 | #define __ASM __asm 135 | #endif 136 | #ifndef __INLINE 137 | #define __INLINE inline 138 | #endif 139 | #ifndef __STATIC_INLINE 140 | #define __STATIC_INLINE static inline 141 | #endif 142 | #ifndef __STATIC_FORCEINLINE 143 | #define __STATIC_FORCEINLINE __STATIC_INLINE 144 | #endif 145 | #ifndef __NO_RETURN 146 | #define __NO_RETURN __attribute__((noreturn)) 147 | #endif 148 | #ifndef __USED 149 | #define __USED __attribute__((used)) 150 | #endif 151 | #ifndef __WEAK 152 | #define __WEAK __attribute__((weak)) 153 | #endif 154 | #ifndef __PACKED 155 | #define __PACKED __packed__ 156 | #endif 157 | #ifndef __PACKED_STRUCT 158 | #define __PACKED_STRUCT struct __packed__ 159 | #endif 160 | #ifndef __PACKED_UNION 161 | #define __PACKED_UNION union __packed__ 162 | #endif 163 | #ifndef __UNALIGNED_UINT32 /* deprecated */ 164 | struct __packed__ T_UINT32 { uint32_t v; }; 165 | #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) 166 | #endif 167 | #ifndef __UNALIGNED_UINT16_WRITE 168 | __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; 169 | #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) 170 | #endif 171 | #ifndef __UNALIGNED_UINT16_READ 172 | __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; 173 | #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) 174 | #endif 175 | #ifndef __UNALIGNED_UINT32_WRITE 176 | __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; 177 | #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) 178 | #endif 179 | #ifndef __UNALIGNED_UINT32_READ 180 | __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; 181 | #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) 182 | #endif 183 | #ifndef __ALIGNED 184 | #define __ALIGNED(x) __align(x) 185 | #endif 186 | #ifndef __RESTRICT 187 | #warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored. 188 | #define __RESTRICT 189 | #endif 190 | 191 | 192 | /* 193 | * COSMIC Compiler 194 | */ 195 | #elif defined ( __CSMC__ ) 196 | #include 197 | 198 | #ifndef __ASM 199 | #define __ASM _asm 200 | #endif 201 | #ifndef __INLINE 202 | #define __INLINE inline 203 | #endif 204 | #ifndef __STATIC_INLINE 205 | #define __STATIC_INLINE static inline 206 | #endif 207 | #ifndef __STATIC_FORCEINLINE 208 | #define __STATIC_FORCEINLINE __STATIC_INLINE 209 | #endif 210 | #ifndef __NO_RETURN 211 | // NO RETURN is automatically detected hence no warning here 212 | #define __NO_RETURN 213 | #endif 214 | #ifndef __USED 215 | #warning No compiler specific solution for __USED. __USED is ignored. 216 | #define __USED 217 | #endif 218 | #ifndef __WEAK 219 | #define __WEAK __weak 220 | #endif 221 | #ifndef __PACKED 222 | #define __PACKED @packed 223 | #endif 224 | #ifndef __PACKED_STRUCT 225 | #define __PACKED_STRUCT @packed struct 226 | #endif 227 | #ifndef __PACKED_UNION 228 | #define __PACKED_UNION @packed union 229 | #endif 230 | #ifndef __UNALIGNED_UINT32 /* deprecated */ 231 | @packed struct T_UINT32 { uint32_t v; }; 232 | #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) 233 | #endif 234 | #ifndef __UNALIGNED_UINT16_WRITE 235 | __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; 236 | #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) 237 | #endif 238 | #ifndef __UNALIGNED_UINT16_READ 239 | __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; 240 | #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) 241 | #endif 242 | #ifndef __UNALIGNED_UINT32_WRITE 243 | __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; 244 | #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) 245 | #endif 246 | #ifndef __UNALIGNED_UINT32_READ 247 | __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; 248 | #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) 249 | #endif 250 | #ifndef __ALIGNED 251 | #warning No compiler specific solution for __ALIGNED. __ALIGNED is ignored. 252 | #define __ALIGNED(x) 253 | #endif 254 | #ifndef __RESTRICT 255 | #warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored. 256 | #define __RESTRICT 257 | #endif 258 | 259 | 260 | #else 261 | #error Unknown compiler. 262 | #endif 263 | 264 | 265 | #endif /* __CMSIS_COMPILER_H */ 266 | 267 | -------------------------------------------------------------------------------- /STM32_Expander/CubeMX/Drivers/CMSIS/Include/cmsis_version.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************//** 2 | * @file cmsis_version.h 3 | * @brief CMSIS Core(M) Version definitions 4 | * @version V5.0.2 5 | * @date 19. April 2017 6 | ******************************************************************************/ 7 | /* 8 | * Copyright (c) 2009-2017 ARM Limited. All rights reserved. 9 | * 10 | * SPDX-License-Identifier: Apache-2.0 11 | * 12 | * Licensed under the Apache License, Version 2.0 (the License); you may 13 | * not use this file except in compliance with the License. 14 | * You may obtain a copy of the License at 15 | * 16 | * www.apache.org/licenses/LICENSE-2.0 17 | * 18 | * Unless required by applicable law or agreed to in writing, software 19 | * distributed under the License is distributed on an AS IS BASIS, WITHOUT 20 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 21 | * See the License for the specific language governing permissions and 22 | * limitations under the License. 23 | */ 24 | 25 | #if defined ( __ICCARM__ ) 26 | #pragma system_include /* treat file as system include file for MISRA check */ 27 | #elif defined (__clang__) 28 | #pragma clang system_header /* treat file as system include file */ 29 | #endif 30 | 31 | #ifndef __CMSIS_VERSION_H 32 | #define __CMSIS_VERSION_H 33 | 34 | /* CMSIS Version definitions */ 35 | #define __CM_CMSIS_VERSION_MAIN ( 5U) /*!< [31:16] CMSIS Core(M) main version */ 36 | #define __CM_CMSIS_VERSION_SUB ( 1U) /*!< [15:0] CMSIS Core(M) sub version */ 37 | #define __CM_CMSIS_VERSION ((__CM_CMSIS_VERSION_MAIN << 16U) | \ 38 | __CM_CMSIS_VERSION_SUB ) /*!< CMSIS Core(M) version number */ 39 | #endif 40 | -------------------------------------------------------------------------------- /STM32_Expander/CubeMX/Drivers/CMSIS/Include/tz_context.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * @file tz_context.h 3 | * @brief Context Management for Armv8-M TrustZone 4 | * @version V1.0.1 5 | * @date 10. January 2018 6 | ******************************************************************************/ 7 | /* 8 | * Copyright (c) 2017-2018 Arm Limited. All rights reserved. 9 | * 10 | * SPDX-License-Identifier: Apache-2.0 11 | * 12 | * Licensed under the Apache License, Version 2.0 (the License); you may 13 | * not use this file except in compliance with the License. 14 | * You may obtain a copy of the License at 15 | * 16 | * www.apache.org/licenses/LICENSE-2.0 17 | * 18 | * Unless required by applicable law or agreed to in writing, software 19 | * distributed under the License is distributed on an AS IS BASIS, WITHOUT 20 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 21 | * See the License for the specific language governing permissions and 22 | * limitations under the License. 23 | */ 24 | 25 | #if defined ( __ICCARM__ ) 26 | #pragma system_include /* treat file as system include file for MISRA check */ 27 | #elif defined (__clang__) 28 | #pragma clang system_header /* treat file as system include file */ 29 | #endif 30 | 31 | #ifndef TZ_CONTEXT_H 32 | #define TZ_CONTEXT_H 33 | 34 | #include 35 | 36 | #ifndef TZ_MODULEID_T 37 | #define TZ_MODULEID_T 38 | /// \details Data type that identifies secure software modules called by a process. 39 | typedef uint32_t TZ_ModuleId_t; 40 | #endif 41 | 42 | /// \details TZ Memory ID identifies an allocated memory slot. 43 | typedef uint32_t TZ_MemoryId_t; 44 | 45 | /// Initialize secure context memory system 46 | /// \return execution status (1: success, 0: error) 47 | uint32_t TZ_InitContextSystem_S (void); 48 | 49 | /// Allocate context memory for calling secure software modules in TrustZone 50 | /// \param[in] module identifies software modules called from non-secure mode 51 | /// \return value != 0 id TrustZone memory slot identifier 52 | /// \return value 0 no memory available or internal error 53 | TZ_MemoryId_t TZ_AllocModuleContext_S (TZ_ModuleId_t module); 54 | 55 | /// Free context memory that was previously allocated with \ref TZ_AllocModuleContext_S 56 | /// \param[in] id TrustZone memory slot identifier 57 | /// \return execution status (1: success, 0: error) 58 | uint32_t TZ_FreeModuleContext_S (TZ_MemoryId_t id); 59 | 60 | /// Load secure context (called on RTOS thread context switch) 61 | /// \param[in] id TrustZone memory slot identifier 62 | /// \return execution status (1: success, 0: error) 63 | uint32_t TZ_LoadContext_S (TZ_MemoryId_t id); 64 | 65 | /// Store secure context (called on RTOS thread context switch) 66 | /// \param[in] id TrustZone memory slot identifier 67 | /// \return execution status (1: success, 0: error) 68 | uint32_t TZ_StoreContext_S (TZ_MemoryId_t id); 69 | 70 | #endif // TZ_CONTEXT_H 71 | -------------------------------------------------------------------------------- /STM32_Expander/CubeMX/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_def.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file stm32f1xx_hal_def.h 4 | * @author MCD Application Team 5 | * @brief This file contains HAL common defines, enumeration, macros and 6 | * structures definitions. 7 | ****************************************************************************** 8 | * @attention 9 | * 10 | * Copyright (c) 2017 STMicroelectronics. 11 | * All rights reserved. 12 | * 13 | * This software is licensed under terms that can be found in the LICENSE file 14 | * in the root directory of this software component. 15 | * If no LICENSE file comes with this software, it is provided AS-IS. 16 | * 17 | ****************************************************************************** 18 | */ 19 | 20 | /* Define to prevent recursive inclusion -------------------------------------*/ 21 | #ifndef __STM32F1xx_HAL_DEF 22 | #define __STM32F1xx_HAL_DEF 23 | 24 | #ifdef __cplusplus 25 | extern "C" { 26 | #endif 27 | 28 | /* Includes ------------------------------------------------------------------*/ 29 | #include "stm32f1xx.h" 30 | #include "Legacy/stm32_hal_legacy.h" 31 | #include 32 | 33 | /* Exported types ------------------------------------------------------------*/ 34 | 35 | /** 36 | * @brief HAL Status structures definition 37 | */ 38 | typedef enum 39 | { 40 | HAL_OK = 0x00U, 41 | HAL_ERROR = 0x01U, 42 | HAL_BUSY = 0x02U, 43 | HAL_TIMEOUT = 0x03U 44 | } HAL_StatusTypeDef; 45 | 46 | /** 47 | * @brief HAL Lock structures definition 48 | */ 49 | typedef enum 50 | { 51 | HAL_UNLOCKED = 0x00U, 52 | HAL_LOCKED = 0x01U 53 | } HAL_LockTypeDef; 54 | 55 | /* Exported macro ------------------------------------------------------------*/ 56 | #define HAL_MAX_DELAY 0xFFFFFFFFU 57 | 58 | #define HAL_IS_BIT_SET(REG, BIT) (((REG) & (BIT)) != 0U) 59 | #define HAL_IS_BIT_CLR(REG, BIT) (((REG) & (BIT)) == 0U) 60 | 61 | #define __HAL_LINKDMA(__HANDLE__, __PPP_DMA_FIELD__, __DMA_HANDLE__) \ 62 | do{ \ 63 | (__HANDLE__)->__PPP_DMA_FIELD__ = &(__DMA_HANDLE__); \ 64 | (__DMA_HANDLE__).Parent = (__HANDLE__); \ 65 | } while(0U) 66 | 67 | #if !defined(UNUSED) 68 | #define UNUSED(X) (void)X /* To avoid gcc/g++ warnings */ 69 | #endif /* UNUSED */ 70 | 71 | /** @brief Reset the Handle's State field. 72 | * @param __HANDLE__ specifies the Peripheral Handle. 73 | * @note This macro can be used for the following purpose: 74 | * - When the Handle is declared as local variable; before passing it as parameter 75 | * to HAL_PPP_Init() for the first time, it is mandatory to use this macro 76 | * to set to 0 the Handle's "State" field. 77 | * Otherwise, "State" field may have any random value and the first time the function 78 | * HAL_PPP_Init() is called, the low level hardware initialization will be missed 79 | * (i.e. HAL_PPP_MspInit() will not be executed). 80 | * - When there is a need to reconfigure the low level hardware: instead of calling 81 | * HAL_PPP_DeInit() then HAL_PPP_Init(), user can make a call to this macro then HAL_PPP_Init(). 82 | * In this later function, when the Handle's "State" field is set to 0, it will execute the function 83 | * HAL_PPP_MspInit() which will reconfigure the low level hardware. 84 | * @retval None 85 | */ 86 | #define __HAL_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = 0U) 87 | 88 | #if (USE_RTOS == 1U) 89 | /* Reserved for future use */ 90 | #error "USE_RTOS should be 0 in the current HAL release" 91 | #else 92 | #define __HAL_LOCK(__HANDLE__) \ 93 | do{ \ 94 | if((__HANDLE__)->Lock == HAL_LOCKED) \ 95 | { \ 96 | return HAL_BUSY; \ 97 | } \ 98 | else \ 99 | { \ 100 | (__HANDLE__)->Lock = HAL_LOCKED; \ 101 | } \ 102 | }while (0U) 103 | 104 | #define __HAL_UNLOCK(__HANDLE__) \ 105 | do{ \ 106 | (__HANDLE__)->Lock = HAL_UNLOCKED; \ 107 | }while (0U) 108 | #endif /* USE_RTOS */ 109 | 110 | #if defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) /* ARM Compiler V6 */ 111 | #ifndef __weak 112 | #define __weak __attribute__((weak)) 113 | #endif 114 | #ifndef __packed 115 | #define __packed __attribute__((packed)) 116 | #endif 117 | #elif defined ( __GNUC__ ) && !defined (__CC_ARM) /* GNU Compiler */ 118 | #ifndef __weak 119 | #define __weak __attribute__((weak)) 120 | #endif /* __weak */ 121 | #ifndef __packed 122 | #define __packed __attribute__((__packed__)) 123 | #endif /* __packed */ 124 | #endif /* __GNUC__ */ 125 | 126 | 127 | /* Macro to get variable aligned on 4-bytes, for __ICCARM__ the directive "#pragma data_alignment=4" must be used instead */ 128 | #if defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) /* ARM Compiler V6 */ 129 | #ifndef __ALIGN_BEGIN 130 | #define __ALIGN_BEGIN 131 | #endif 132 | #ifndef __ALIGN_END 133 | #define __ALIGN_END __attribute__ ((aligned (4))) 134 | #endif 135 | #elif defined ( __GNUC__ ) && !defined (__CC_ARM) /* GNU Compiler */ 136 | #ifndef __ALIGN_END 137 | #define __ALIGN_END __attribute__ ((aligned (4))) 138 | #endif /* __ALIGN_END */ 139 | #ifndef __ALIGN_BEGIN 140 | #define __ALIGN_BEGIN 141 | #endif /* __ALIGN_BEGIN */ 142 | #else 143 | #ifndef __ALIGN_END 144 | #define __ALIGN_END 145 | #endif /* __ALIGN_END */ 146 | #ifndef __ALIGN_BEGIN 147 | #if defined (__CC_ARM) /* ARM Compiler V5*/ 148 | #define __ALIGN_BEGIN __align(4) 149 | #elif defined (__ICCARM__) /* IAR Compiler */ 150 | #define __ALIGN_BEGIN 151 | #endif /* __CC_ARM */ 152 | #endif /* __ALIGN_BEGIN */ 153 | #endif /* __GNUC__ */ 154 | 155 | 156 | /** 157 | * @brief __RAM_FUNC definition 158 | */ 159 | #if defined ( __CC_ARM ) || (defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)) 160 | /* ARM Compiler V4/V5 and V6 161 | -------------------------- 162 | RAM functions are defined using the toolchain options. 163 | Functions that are executed in RAM should reside in a separate source module. 164 | Using the 'Options for File' dialog you can simply change the 'Code / Const' 165 | area of a module to a memory space in physical RAM. 166 | Available memory areas are declared in the 'Target' tab of the 'Options for Target' 167 | dialog. 168 | */ 169 | #define __RAM_FUNC 170 | 171 | #elif defined ( __ICCARM__ ) 172 | /* ICCARM Compiler 173 | --------------- 174 | RAM functions are defined using a specific toolchain keyword "__ramfunc". 175 | */ 176 | #define __RAM_FUNC __ramfunc 177 | 178 | #elif defined ( __GNUC__ ) 179 | /* GNU Compiler 180 | ------------ 181 | RAM functions are defined using a specific toolchain attribute 182 | "__attribute__((section(".RamFunc")))". 183 | */ 184 | #define __RAM_FUNC __attribute__((section(".RamFunc"))) 185 | 186 | #endif 187 | 188 | /** 189 | * @brief __NOINLINE definition 190 | */ 191 | #if defined ( __CC_ARM ) || (defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)) || defined ( __GNUC__ ) 192 | /* ARM V4/V5 and V6 & GNU Compiler 193 | ------------------------------- 194 | */ 195 | #define __NOINLINE __attribute__ ( (noinline) ) 196 | 197 | #elif defined ( __ICCARM__ ) 198 | /* ICCARM Compiler 199 | --------------- 200 | */ 201 | #define __NOINLINE _Pragma("optimize = no_inline") 202 | 203 | #endif 204 | 205 | #ifdef __cplusplus 206 | } 207 | #endif 208 | 209 | #endif /* ___STM32F1xx_HAL_DEF */ 210 | 211 | 212 | -------------------------------------------------------------------------------- /STM32_Expander/CubeMX/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_flash.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file stm32f1xx_hal_flash.h 4 | * @author MCD Application Team 5 | * @brief Header file of Flash HAL module. 6 | ****************************************************************************** 7 | * @attention 8 | * 9 | * Copyright (c) 2016 STMicroelectronics. 10 | * All rights reserved. 11 | * 12 | * This software is licensed under terms that can be found in the LICENSE file in 13 | * the root directory of this software component. 14 | * If no LICENSE file comes with this software, it is provided AS-IS. 15 | ****************************************************************************** 16 | */ 17 | 18 | /* Define to prevent recursive inclusion -------------------------------------*/ 19 | #ifndef __STM32F1xx_HAL_FLASH_H 20 | #define __STM32F1xx_HAL_FLASH_H 21 | 22 | #ifdef __cplusplus 23 | extern "C" { 24 | #endif 25 | 26 | /* Includes ------------------------------------------------------------------*/ 27 | #include "stm32f1xx_hal_def.h" 28 | 29 | /** @addtogroup STM32F1xx_HAL_Driver 30 | * @{ 31 | */ 32 | 33 | /** @addtogroup FLASH 34 | * @{ 35 | */ 36 | 37 | /** @addtogroup FLASH_Private_Constants 38 | * @{ 39 | */ 40 | #define FLASH_TIMEOUT_VALUE 50000U /* 50 s */ 41 | /** 42 | * @} 43 | */ 44 | 45 | /** @addtogroup FLASH_Private_Macros 46 | * @{ 47 | */ 48 | 49 | #define IS_FLASH_TYPEPROGRAM(VALUE) (((VALUE) == FLASH_TYPEPROGRAM_HALFWORD) || \ 50 | ((VALUE) == FLASH_TYPEPROGRAM_WORD) || \ 51 | ((VALUE) == FLASH_TYPEPROGRAM_DOUBLEWORD)) 52 | 53 | #if defined(FLASH_ACR_LATENCY) 54 | #define IS_FLASH_LATENCY(__LATENCY__) (((__LATENCY__) == FLASH_LATENCY_0) || \ 55 | ((__LATENCY__) == FLASH_LATENCY_1) || \ 56 | ((__LATENCY__) == FLASH_LATENCY_2)) 57 | 58 | #else 59 | #define IS_FLASH_LATENCY(__LATENCY__) ((__LATENCY__) == FLASH_LATENCY_0) 60 | #endif /* FLASH_ACR_LATENCY */ 61 | /** 62 | * @} 63 | */ 64 | 65 | /* Exported types ------------------------------------------------------------*/ 66 | /** @defgroup FLASH_Exported_Types FLASH Exported Types 67 | * @{ 68 | */ 69 | 70 | /** 71 | * @brief FLASH Procedure structure definition 72 | */ 73 | typedef enum 74 | { 75 | FLASH_PROC_NONE = 0U, 76 | FLASH_PROC_PAGEERASE = 1U, 77 | FLASH_PROC_MASSERASE = 2U, 78 | FLASH_PROC_PROGRAMHALFWORD = 3U, 79 | FLASH_PROC_PROGRAMWORD = 4U, 80 | FLASH_PROC_PROGRAMDOUBLEWORD = 5U 81 | } FLASH_ProcedureTypeDef; 82 | 83 | /** 84 | * @brief FLASH handle Structure definition 85 | */ 86 | typedef struct 87 | { 88 | __IO FLASH_ProcedureTypeDef ProcedureOnGoing; /*!< Internal variable to indicate which procedure is ongoing or not in IT context */ 89 | 90 | __IO uint32_t DataRemaining; /*!< Internal variable to save the remaining pages to erase or half-word to program in IT context */ 91 | 92 | __IO uint32_t Address; /*!< Internal variable to save address selected for program or erase */ 93 | 94 | __IO uint64_t Data; /*!< Internal variable to save data to be programmed */ 95 | 96 | HAL_LockTypeDef Lock; /*!< FLASH locking object */ 97 | 98 | __IO uint32_t ErrorCode; /*!< FLASH error code 99 | This parameter can be a value of @ref FLASH_Error_Codes */ 100 | } FLASH_ProcessTypeDef; 101 | 102 | /** 103 | * @} 104 | */ 105 | 106 | /* Exported constants --------------------------------------------------------*/ 107 | /** @defgroup FLASH_Exported_Constants FLASH Exported Constants 108 | * @{ 109 | */ 110 | 111 | /** @defgroup FLASH_Error_Codes FLASH Error Codes 112 | * @{ 113 | */ 114 | 115 | #define HAL_FLASH_ERROR_NONE 0x00U /*!< No error */ 116 | #define HAL_FLASH_ERROR_PROG 0x01U /*!< Programming error */ 117 | #define HAL_FLASH_ERROR_WRP 0x02U /*!< Write protection error */ 118 | #define HAL_FLASH_ERROR_OPTV 0x04U /*!< Option validity error */ 119 | 120 | /** 121 | * @} 122 | */ 123 | 124 | /** @defgroup FLASH_Type_Program FLASH Type Program 125 | * @{ 126 | */ 127 | #define FLASH_TYPEPROGRAM_HALFWORD 0x01U /*!ACR |= FLASH_ACR_HLFCYA) 181 | 182 | /** 183 | * @brief Disable the FLASH half cycle access. 184 | * @note half cycle access can only be used with a low-frequency clock of less than 185 | 8 MHz that can be obtained with the use of HSI or HSE but not of PLL. 186 | * @retval None 187 | */ 188 | #define __HAL_FLASH_HALF_CYCLE_ACCESS_DISABLE() (FLASH->ACR &= (~FLASH_ACR_HLFCYA)) 189 | 190 | /** 191 | * @} 192 | */ 193 | 194 | #if defined(FLASH_ACR_LATENCY) 195 | /** @defgroup FLASH_EM_Latency FLASH Latency 196 | * @brief macros to handle FLASH Latency 197 | * @{ 198 | */ 199 | 200 | /** 201 | * @brief Set the FLASH Latency. 202 | * @param __LATENCY__ FLASH Latency 203 | * The value of this parameter depend on device used within the same series 204 | * @retval None 205 | */ 206 | #define __HAL_FLASH_SET_LATENCY(__LATENCY__) (FLASH->ACR = (FLASH->ACR&(~FLASH_ACR_LATENCY)) | (__LATENCY__)) 207 | 208 | 209 | /** 210 | * @brief Get the FLASH Latency. 211 | * @retval FLASH Latency 212 | * The value of this parameter depend on device used within the same series 213 | */ 214 | #define __HAL_FLASH_GET_LATENCY() (READ_BIT((FLASH->ACR), FLASH_ACR_LATENCY)) 215 | 216 | /** 217 | * @} 218 | */ 219 | 220 | #endif /* FLASH_ACR_LATENCY */ 221 | /** @defgroup FLASH_Prefetch FLASH Prefetch 222 | * @brief macros to handle FLASH Prefetch buffer 223 | * @{ 224 | */ 225 | /** 226 | * @brief Enable the FLASH prefetch buffer. 227 | * @retval None 228 | */ 229 | #define __HAL_FLASH_PREFETCH_BUFFER_ENABLE() (FLASH->ACR |= FLASH_ACR_PRFTBE) 230 | 231 | /** 232 | * @brief Disable the FLASH prefetch buffer. 233 | * @retval None 234 | */ 235 | #define __HAL_FLASH_PREFETCH_BUFFER_DISABLE() (FLASH->ACR &= (~FLASH_ACR_PRFTBE)) 236 | 237 | /** 238 | * @} 239 | */ 240 | 241 | /** 242 | * @} 243 | */ 244 | 245 | /* Include FLASH HAL Extended module */ 246 | #include "stm32f1xx_hal_flash_ex.h" 247 | 248 | /* Exported functions --------------------------------------------------------*/ 249 | /** @addtogroup FLASH_Exported_Functions 250 | * @{ 251 | */ 252 | 253 | /** @addtogroup FLASH_Exported_Functions_Group1 254 | * @{ 255 | */ 256 | /* IO operation functions *****************************************************/ 257 | HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t Address, uint64_t Data); 258 | HAL_StatusTypeDef HAL_FLASH_Program_IT(uint32_t TypeProgram, uint32_t Address, uint64_t Data); 259 | 260 | /* FLASH IRQ handler function */ 261 | void HAL_FLASH_IRQHandler(void); 262 | /* Callbacks in non blocking modes */ 263 | void HAL_FLASH_EndOfOperationCallback(uint32_t ReturnValue); 264 | void HAL_FLASH_OperationErrorCallback(uint32_t ReturnValue); 265 | 266 | /** 267 | * @} 268 | */ 269 | 270 | /** @addtogroup FLASH_Exported_Functions_Group2 271 | * @{ 272 | */ 273 | /* Peripheral Control functions ***********************************************/ 274 | HAL_StatusTypeDef HAL_FLASH_Unlock(void); 275 | HAL_StatusTypeDef HAL_FLASH_Lock(void); 276 | HAL_StatusTypeDef HAL_FLASH_OB_Unlock(void); 277 | HAL_StatusTypeDef HAL_FLASH_OB_Lock(void); 278 | void HAL_FLASH_OB_Launch(void); 279 | 280 | /** 281 | * @} 282 | */ 283 | 284 | /** @addtogroup FLASH_Exported_Functions_Group3 285 | * @{ 286 | */ 287 | /* Peripheral State and Error functions ***************************************/ 288 | uint32_t HAL_FLASH_GetError(void); 289 | 290 | /** 291 | * @} 292 | */ 293 | 294 | /** 295 | * @} 296 | */ 297 | 298 | /* Private function -------------------------------------------------*/ 299 | /** @addtogroup FLASH_Private_Functions 300 | * @{ 301 | */ 302 | HAL_StatusTypeDef FLASH_WaitForLastOperation(uint32_t Timeout); 303 | #if defined(FLASH_BANK2_END) 304 | HAL_StatusTypeDef FLASH_WaitForLastOperationBank2(uint32_t Timeout); 305 | #endif /* FLASH_BANK2_END */ 306 | 307 | /** 308 | * @} 309 | */ 310 | 311 | /** 312 | * @} 313 | */ 314 | 315 | /** 316 | * @} 317 | */ 318 | 319 | #ifdef __cplusplus 320 | } 321 | #endif 322 | 323 | #endif /* __STM32F1xx_HAL_FLASH_H */ 324 | 325 | 326 | -------------------------------------------------------------------------------- /STM32_Expander/CubeMX/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_tim_ex.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file stm32f1xx_hal_tim_ex.h 4 | * @author MCD Application Team 5 | * @brief Header file of TIM HAL Extended module. 6 | ****************************************************************************** 7 | * @attention 8 | * 9 | * Copyright (c) 2016 STMicroelectronics. 10 | * All rights reserved. 11 | * 12 | * This software is licensed under terms that can be found in the LICENSE file 13 | * in the root directory of this software component. 14 | * If no LICENSE file comes with this software, it is provided AS-IS. 15 | * 16 | ****************************************************************************** 17 | */ 18 | 19 | /* Define to prevent recursive inclusion -------------------------------------*/ 20 | #ifndef STM32F1xx_HAL_TIM_EX_H 21 | #define STM32F1xx_HAL_TIM_EX_H 22 | 23 | #ifdef __cplusplus 24 | extern "C" { 25 | #endif 26 | 27 | /* Includes ------------------------------------------------------------------*/ 28 | #include "stm32f1xx_hal_def.h" 29 | 30 | /** @addtogroup STM32F1xx_HAL_Driver 31 | * @{ 32 | */ 33 | 34 | /** @addtogroup TIMEx 35 | * @{ 36 | */ 37 | 38 | /* Exported types ------------------------------------------------------------*/ 39 | /** @defgroup TIMEx_Exported_Types TIM Extended Exported Types 40 | * @{ 41 | */ 42 | 43 | /** 44 | * @brief TIM Hall sensor Configuration Structure definition 45 | */ 46 | 47 | typedef struct 48 | { 49 | uint32_t IC1Polarity; /*!< Specifies the active edge of the input signal. 50 | This parameter can be a value of @ref TIM_Input_Capture_Polarity */ 51 | 52 | uint32_t IC1Prescaler; /*!< Specifies the Input Capture Prescaler. 53 | This parameter can be a value of @ref TIM_Input_Capture_Prescaler */ 54 | 55 | uint32_t IC1Filter; /*!< Specifies the input capture filter. 56 | This parameter can be a number between Min_Data = 0x0 and Max_Data = 0xF */ 57 | 58 | uint32_t Commutation_Delay; /*!< Specifies the pulse value to be loaded into the Capture Compare Register. 59 | This parameter can be a number between Min_Data = 0x0000 and Max_Data = 0xFFFF */ 60 | } TIM_HallSensor_InitTypeDef; 61 | /** 62 | * @} 63 | */ 64 | /* End of exported types -----------------------------------------------------*/ 65 | 66 | /* Exported constants --------------------------------------------------------*/ 67 | /** @defgroup TIMEx_Exported_Constants TIM Extended Exported Constants 68 | * @{ 69 | */ 70 | 71 | /** @defgroup TIMEx_Remap TIM Extended Remapping 72 | * @{ 73 | */ 74 | /** 75 | * @} 76 | */ 77 | 78 | /** 79 | * @} 80 | */ 81 | /* End of exported constants -------------------------------------------------*/ 82 | 83 | /* Exported macro ------------------------------------------------------------*/ 84 | /** @defgroup TIMEx_Exported_Macros TIM Extended Exported Macros 85 | * @{ 86 | */ 87 | 88 | /** 89 | * @} 90 | */ 91 | /* End of exported macro -----------------------------------------------------*/ 92 | 93 | /* Private macro -------------------------------------------------------------*/ 94 | /** @defgroup TIMEx_Private_Macros TIM Extended Private Macros 95 | * @{ 96 | */ 97 | 98 | /** 99 | * @} 100 | */ 101 | /* End of private macro ------------------------------------------------------*/ 102 | 103 | /* Exported functions --------------------------------------------------------*/ 104 | /** @addtogroup TIMEx_Exported_Functions TIM Extended Exported Functions 105 | * @{ 106 | */ 107 | 108 | /** @addtogroup TIMEx_Exported_Functions_Group1 Extended Timer Hall Sensor functions 109 | * @brief Timer Hall Sensor functions 110 | * @{ 111 | */ 112 | /* Timer Hall Sensor functions **********************************************/ 113 | HAL_StatusTypeDef HAL_TIMEx_HallSensor_Init(TIM_HandleTypeDef *htim, const TIM_HallSensor_InitTypeDef *sConfig); 114 | HAL_StatusTypeDef HAL_TIMEx_HallSensor_DeInit(TIM_HandleTypeDef *htim); 115 | 116 | void HAL_TIMEx_HallSensor_MspInit(TIM_HandleTypeDef *htim); 117 | void HAL_TIMEx_HallSensor_MspDeInit(TIM_HandleTypeDef *htim); 118 | 119 | /* Blocking mode: Polling */ 120 | HAL_StatusTypeDef HAL_TIMEx_HallSensor_Start(TIM_HandleTypeDef *htim); 121 | HAL_StatusTypeDef HAL_TIMEx_HallSensor_Stop(TIM_HandleTypeDef *htim); 122 | /* Non-Blocking mode: Interrupt */ 123 | HAL_StatusTypeDef HAL_TIMEx_HallSensor_Start_IT(TIM_HandleTypeDef *htim); 124 | HAL_StatusTypeDef HAL_TIMEx_HallSensor_Stop_IT(TIM_HandleTypeDef *htim); 125 | /* Non-Blocking mode: DMA */ 126 | HAL_StatusTypeDef HAL_TIMEx_HallSensor_Start_DMA(TIM_HandleTypeDef *htim, uint32_t *pData, uint16_t Length); 127 | HAL_StatusTypeDef HAL_TIMEx_HallSensor_Stop_DMA(TIM_HandleTypeDef *htim); 128 | /** 129 | * @} 130 | */ 131 | 132 | /** @addtogroup TIMEx_Exported_Functions_Group2 Extended Timer Complementary Output Compare functions 133 | * @brief Timer Complementary Output Compare functions 134 | * @{ 135 | */ 136 | /* Timer Complementary Output Compare functions *****************************/ 137 | /* Blocking mode: Polling */ 138 | HAL_StatusTypeDef HAL_TIMEx_OCN_Start(TIM_HandleTypeDef *htim, uint32_t Channel); 139 | HAL_StatusTypeDef HAL_TIMEx_OCN_Stop(TIM_HandleTypeDef *htim, uint32_t Channel); 140 | 141 | /* Non-Blocking mode: Interrupt */ 142 | HAL_StatusTypeDef HAL_TIMEx_OCN_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel); 143 | HAL_StatusTypeDef HAL_TIMEx_OCN_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel); 144 | 145 | /* Non-Blocking mode: DMA */ 146 | HAL_StatusTypeDef HAL_TIMEx_OCN_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, const uint32_t *pData, 147 | uint16_t Length); 148 | HAL_StatusTypeDef HAL_TIMEx_OCN_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel); 149 | /** 150 | * @} 151 | */ 152 | 153 | /** @addtogroup TIMEx_Exported_Functions_Group3 Extended Timer Complementary PWM functions 154 | * @brief Timer Complementary PWM functions 155 | * @{ 156 | */ 157 | /* Timer Complementary PWM functions ****************************************/ 158 | /* Blocking mode: Polling */ 159 | HAL_StatusTypeDef HAL_TIMEx_PWMN_Start(TIM_HandleTypeDef *htim, uint32_t Channel); 160 | HAL_StatusTypeDef HAL_TIMEx_PWMN_Stop(TIM_HandleTypeDef *htim, uint32_t Channel); 161 | 162 | /* Non-Blocking mode: Interrupt */ 163 | HAL_StatusTypeDef HAL_TIMEx_PWMN_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel); 164 | HAL_StatusTypeDef HAL_TIMEx_PWMN_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel); 165 | /* Non-Blocking mode: DMA */ 166 | HAL_StatusTypeDef HAL_TIMEx_PWMN_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, const uint32_t *pData, 167 | uint16_t Length); 168 | HAL_StatusTypeDef HAL_TIMEx_PWMN_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel); 169 | /** 170 | * @} 171 | */ 172 | 173 | /** @addtogroup TIMEx_Exported_Functions_Group4 Extended Timer Complementary One Pulse functions 174 | * @brief Timer Complementary One Pulse functions 175 | * @{ 176 | */ 177 | /* Timer Complementary One Pulse functions **********************************/ 178 | /* Blocking mode: Polling */ 179 | HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Start(TIM_HandleTypeDef *htim, uint32_t OutputChannel); 180 | HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Stop(TIM_HandleTypeDef *htim, uint32_t OutputChannel); 181 | 182 | /* Non-Blocking mode: Interrupt */ 183 | HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Start_IT(TIM_HandleTypeDef *htim, uint32_t OutputChannel); 184 | HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Stop_IT(TIM_HandleTypeDef *htim, uint32_t OutputChannel); 185 | /** 186 | * @} 187 | */ 188 | 189 | /** @addtogroup TIMEx_Exported_Functions_Group5 Extended Peripheral Control functions 190 | * @brief Peripheral Control functions 191 | * @{ 192 | */ 193 | /* Extended Control functions ************************************************/ 194 | HAL_StatusTypeDef HAL_TIMEx_ConfigCommutEvent(TIM_HandleTypeDef *htim, uint32_t InputTrigger, 195 | uint32_t CommutationSource); 196 | HAL_StatusTypeDef HAL_TIMEx_ConfigCommutEvent_IT(TIM_HandleTypeDef *htim, uint32_t InputTrigger, 197 | uint32_t CommutationSource); 198 | HAL_StatusTypeDef HAL_TIMEx_ConfigCommutEvent_DMA(TIM_HandleTypeDef *htim, uint32_t InputTrigger, 199 | uint32_t CommutationSource); 200 | HAL_StatusTypeDef HAL_TIMEx_MasterConfigSynchronization(TIM_HandleTypeDef *htim, 201 | const TIM_MasterConfigTypeDef *sMasterConfig); 202 | HAL_StatusTypeDef HAL_TIMEx_ConfigBreakDeadTime(TIM_HandleTypeDef *htim, 203 | const TIM_BreakDeadTimeConfigTypeDef *sBreakDeadTimeConfig); 204 | HAL_StatusTypeDef HAL_TIMEx_RemapConfig(TIM_HandleTypeDef *htim, uint32_t Remap); 205 | /** 206 | * @} 207 | */ 208 | 209 | /** @addtogroup TIMEx_Exported_Functions_Group6 Extended Callbacks functions 210 | * @brief Extended Callbacks functions 211 | * @{ 212 | */ 213 | /* Extended Callback **********************************************************/ 214 | void HAL_TIMEx_CommutCallback(TIM_HandleTypeDef *htim); 215 | void HAL_TIMEx_CommutHalfCpltCallback(TIM_HandleTypeDef *htim); 216 | void HAL_TIMEx_BreakCallback(TIM_HandleTypeDef *htim); 217 | /** 218 | * @} 219 | */ 220 | 221 | /** @addtogroup TIMEx_Exported_Functions_Group7 Extended Peripheral State functions 222 | * @brief Extended Peripheral State functions 223 | * @{ 224 | */ 225 | /* Extended Peripheral State functions ***************************************/ 226 | HAL_TIM_StateTypeDef HAL_TIMEx_HallSensor_GetState(const TIM_HandleTypeDef *htim); 227 | HAL_TIM_ChannelStateTypeDef HAL_TIMEx_GetChannelNState(const TIM_HandleTypeDef *htim, uint32_t ChannelN); 228 | /** 229 | * @} 230 | */ 231 | 232 | /** 233 | * @} 234 | */ 235 | /* End of exported functions -------------------------------------------------*/ 236 | 237 | /* Private functions----------------------------------------------------------*/ 238 | /** @addtogroup TIMEx_Private_Functions TIM Extended Private Functions 239 | * @{ 240 | */ 241 | void TIMEx_DMACommutationCplt(DMA_HandleTypeDef *hdma); 242 | void TIMEx_DMACommutationHalfCplt(DMA_HandleTypeDef *hdma); 243 | /** 244 | * @} 245 | */ 246 | /* End of private functions --------------------------------------------------*/ 247 | 248 | /** 249 | * @} 250 | */ 251 | 252 | /** 253 | * @} 254 | */ 255 | 256 | #ifdef __cplusplus 257 | } 258 | #endif 259 | 260 | 261 | #endif /* STM32F1xx_HAL_TIM_EX_H */ 262 | -------------------------------------------------------------------------------- /STM32_Expander/CubeMX/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_utils.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file stm32f1xx_ll_utils.h 4 | * @author MCD Application Team 5 | * @brief Header file of UTILS LL module. 6 | ****************************************************************************** 7 | * @attention 8 | * 9 | * Copyright (c) 2016 STMicroelectronics. 10 | * All rights reserved. 11 | * 12 | * This software is licensed under terms that can be found in the LICENSE file 13 | * in the root directory of this software component. 14 | * If no LICENSE file comes with this software, it is provided AS-IS. 15 | * 16 | ****************************************************************************** 17 | @verbatim 18 | ============================================================================== 19 | ##### How to use this driver ##### 20 | ============================================================================== 21 | [..] 22 | The LL UTILS driver contains a set of generic APIs that can be 23 | used by user: 24 | (+) Device electronic signature 25 | (+) Timing functions 26 | (+) PLL configuration functions 27 | 28 | @endverbatim 29 | ****************************************************************************** 30 | */ 31 | 32 | /* Define to prevent recursive inclusion -------------------------------------*/ 33 | #ifndef __STM32F1xx_LL_UTILS_H 34 | #define __STM32F1xx_LL_UTILS_H 35 | 36 | #ifdef __cplusplus 37 | extern "C" { 38 | #endif 39 | 40 | /* Includes ------------------------------------------------------------------*/ 41 | #include "stm32f1xx.h" 42 | 43 | /** @addtogroup STM32F1xx_LL_Driver 44 | * @{ 45 | */ 46 | 47 | /** @defgroup UTILS_LL UTILS 48 | * @{ 49 | */ 50 | 51 | /* Private types -------------------------------------------------------------*/ 52 | /* Private variables ---------------------------------------------------------*/ 53 | 54 | /* Private constants ---------------------------------------------------------*/ 55 | /** @defgroup UTILS_LL_Private_Constants UTILS Private Constants 56 | * @{ 57 | */ 58 | 59 | /* Max delay can be used in LL_mDelay */ 60 | #define LL_MAX_DELAY 0xFFFFFFFFU 61 | 62 | /** 63 | * @brief Unique device ID register base address 64 | */ 65 | #define UID_BASE_ADDRESS UID_BASE 66 | 67 | /** 68 | * @brief Flash size data register base address 69 | */ 70 | #define FLASHSIZE_BASE_ADDRESS FLASHSIZE_BASE 71 | 72 | /** 73 | * @} 74 | */ 75 | 76 | /* Private macros ------------------------------------------------------------*/ 77 | /** @defgroup UTILS_LL_Private_Macros UTILS Private Macros 78 | * @{ 79 | */ 80 | /** 81 | * @} 82 | */ 83 | /* Exported types ------------------------------------------------------------*/ 84 | /** @defgroup UTILS_LL_ES_INIT UTILS Exported structures 85 | * @{ 86 | */ 87 | /** 88 | * @brief UTILS PLL structure definition 89 | */ 90 | typedef struct 91 | { 92 | uint32_t PLLMul; /*!< Multiplication factor for PLL VCO input clock. 93 | This parameter can be a value of @ref RCC_LL_EC_PLL_MUL 94 | 95 | This feature can be modified afterwards using unitary function 96 | @ref LL_RCC_PLL_ConfigDomain_SYS(). */ 97 | 98 | uint32_t Prediv; /*!< Division factor for HSE used as PLL clock source. 99 | This parameter can be a value of @ref RCC_LL_EC_PREDIV_DIV 100 | 101 | This feature can be modified afterwards using unitary function 102 | @ref LL_RCC_PLL_ConfigDomain_SYS(). */ 103 | } LL_UTILS_PLLInitTypeDef; 104 | 105 | /** 106 | * @brief UTILS System, AHB and APB buses clock configuration structure definition 107 | */ 108 | typedef struct 109 | { 110 | uint32_t AHBCLKDivider; /*!< The AHB clock (HCLK) divider. This clock is derived from the system clock (SYSCLK). 111 | This parameter can be a value of @ref RCC_LL_EC_SYSCLK_DIV 112 | 113 | This feature can be modified afterwards using unitary function 114 | @ref LL_RCC_SetAHBPrescaler(). */ 115 | 116 | uint32_t APB1CLKDivider; /*!< The APB1 clock (PCLK1) divider. This clock is derived from the AHB clock (HCLK). 117 | This parameter can be a value of @ref RCC_LL_EC_APB1_DIV 118 | 119 | This feature can be modified afterwards using unitary function 120 | @ref LL_RCC_SetAPB1Prescaler(). */ 121 | 122 | uint32_t APB2CLKDivider; /*!< The APB2 clock (PCLK2) divider. This clock is derived from the AHB clock (HCLK). 123 | This parameter can be a value of @ref RCC_LL_EC_APB2_DIV 124 | 125 | This feature can be modified afterwards using unitary function 126 | @ref LL_RCC_SetAPB2Prescaler(). */ 127 | 128 | } LL_UTILS_ClkInitTypeDef; 129 | 130 | /** 131 | * @} 132 | */ 133 | 134 | /* Exported constants --------------------------------------------------------*/ 135 | /** @defgroup UTILS_LL_Exported_Constants UTILS Exported Constants 136 | * @{ 137 | */ 138 | 139 | /** @defgroup UTILS_EC_HSE_BYPASS HSE Bypass activation 140 | * @{ 141 | */ 142 | #define LL_UTILS_HSEBYPASS_OFF 0x00000000U /*!< HSE Bypass is not enabled */ 143 | #define LL_UTILS_HSEBYPASS_ON 0x00000001U /*!< HSE Bypass is enabled */ 144 | /** 145 | * @} 146 | */ 147 | 148 | /** 149 | * @} 150 | */ 151 | 152 | /* Exported macro ------------------------------------------------------------*/ 153 | 154 | /* Exported functions --------------------------------------------------------*/ 155 | /** @defgroup UTILS_LL_Exported_Functions UTILS Exported Functions 156 | * @{ 157 | */ 158 | 159 | /** @defgroup UTILS_EF_DEVICE_ELECTRONIC_SIGNATURE DEVICE ELECTRONIC SIGNATURE 160 | * @{ 161 | */ 162 | 163 | /** 164 | * @brief Get Word0 of the unique device identifier (UID based on 96 bits) 165 | * @retval UID[31:0] 166 | */ 167 | __STATIC_INLINE uint32_t LL_GetUID_Word0(void) 168 | { 169 | return (uint32_t)(READ_REG(*((uint32_t *)UID_BASE_ADDRESS))); 170 | } 171 | 172 | /** 173 | * @brief Get Word1 of the unique device identifier (UID based on 96 bits) 174 | * @retval UID[63:32] 175 | */ 176 | __STATIC_INLINE uint32_t LL_GetUID_Word1(void) 177 | { 178 | return (uint32_t)(READ_REG(*((uint32_t *)(UID_BASE_ADDRESS + 4U)))); 179 | } 180 | 181 | /** 182 | * @brief Get Word2 of the unique device identifier (UID based on 96 bits) 183 | * @retval UID[95:64] 184 | */ 185 | __STATIC_INLINE uint32_t LL_GetUID_Word2(void) 186 | { 187 | return (uint32_t)(READ_REG(*((uint32_t *)(UID_BASE_ADDRESS + 8U)))); 188 | } 189 | 190 | /** 191 | * @brief Get Flash memory size 192 | * @note This bitfield indicates the size of the device Flash memory expressed in 193 | * Kbytes. As an example, 0x040 corresponds to 64 Kbytes. 194 | * @retval FLASH_SIZE[15:0]: Flash memory size 195 | */ 196 | __STATIC_INLINE uint32_t LL_GetFlashSize(void) 197 | { 198 | return (uint16_t)(READ_REG(*((uint32_t *)FLASHSIZE_BASE_ADDRESS))); 199 | } 200 | 201 | 202 | /** 203 | * @} 204 | */ 205 | 206 | /** @defgroup UTILS_LL_EF_DELAY DELAY 207 | * @{ 208 | */ 209 | 210 | /** 211 | * @brief This function configures the Cortex-M SysTick source of the time base. 212 | * @param HCLKFrequency HCLK frequency in Hz (can be calculated thanks to RCC helper macro) 213 | * @note When a RTOS is used, it is recommended to avoid changing the SysTick 214 | * configuration by calling this function, for a delay use rather osDelay RTOS service. 215 | * @param Ticks Number of ticks 216 | * @retval None 217 | */ 218 | __STATIC_INLINE void LL_InitTick(uint32_t HCLKFrequency, uint32_t Ticks) 219 | { 220 | /* Configure the SysTick to have interrupt in 1ms time base */ 221 | SysTick->LOAD = (uint32_t)((HCLKFrequency / Ticks) - 1UL); /* set reload register */ 222 | SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ 223 | SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | 224 | SysTick_CTRL_ENABLE_Msk; /* Enable the Systick Timer */ 225 | } 226 | 227 | void LL_Init1msTick(uint32_t HCLKFrequency); 228 | void LL_mDelay(uint32_t Delay); 229 | 230 | /** 231 | * @} 232 | */ 233 | 234 | /** @defgroup UTILS_EF_SYSTEM SYSTEM 235 | * @{ 236 | */ 237 | 238 | void LL_SetSystemCoreClock(uint32_t HCLKFrequency); 239 | #if defined(FLASH_ACR_LATENCY) 240 | ErrorStatus LL_SetFlashLatency(uint32_t Frequency); 241 | #endif /* FLASH_ACR_LATENCY */ 242 | ErrorStatus LL_PLL_ConfigSystemClock_HSI(LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct, 243 | LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct); 244 | ErrorStatus LL_PLL_ConfigSystemClock_HSE(uint32_t HSEFrequency, uint32_t HSEBypass, 245 | LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct, LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct); 246 | #if defined(RCC_PLL2_SUPPORT) 247 | ErrorStatus LL_PLL_ConfigSystemClock_PLL2(uint32_t HSEFrequency, uint32_t HSEBypass, LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct, 248 | LL_UTILS_PLLInitTypeDef *UTILS_PLL2InitStruct, LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct); 249 | #endif /* RCC_PLL2_SUPPORT */ 250 | /** 251 | * @} 252 | */ 253 | 254 | /** 255 | * @} 256 | */ 257 | 258 | /** 259 | * @} 260 | */ 261 | 262 | /** 263 | * @} 264 | */ 265 | 266 | #ifdef __cplusplus 267 | } 268 | #endif 269 | 270 | #endif /* __STM32F1xx_LL_UTILS_H */ 271 | -------------------------------------------------------------------------------- /STM32_Expander/CubeMX/Drivers/STM32F1xx_HAL_Driver/LICENSE.txt: -------------------------------------------------------------------------------- 1 | This software component is provided to you as part of a software package and 2 | applicable license terms are in the Package_license file. If you received this 3 | software component outside of a package or without applicable license terms, 4 | the terms of the BSD-3-Clause license shall apply. 5 | You may obtain a copy of the BSD-3-Clause at: 6 | https://opensource.org/licenses/BSD-3-Clause 7 | -------------------------------------------------------------------------------- /STM32_Expander/CubeMX/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio_ex.c: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file stm32f1xx_hal_gpio_ex.c 4 | * @author MCD Application Team 5 | * @brief GPIO Extension HAL module driver. 6 | * This file provides firmware functions to manage the following 7 | * functionalities of the General Purpose Input/Output (GPIO) extension peripheral. 8 | * + Extended features functions 9 | * 10 | ****************************************************************************** 11 | * @attention 12 | * 13 | * Copyright (c) 2016 STMicroelectronics. 14 | * All rights reserved. 15 | * 16 | * This software is licensed under terms that can be found in the LICENSE file 17 | * in the root directory of this software component. 18 | * If no LICENSE file comes with this software, it is provided AS-IS. 19 | * 20 | ****************************************************************************** 21 | @verbatim 22 | ============================================================================== 23 | ##### GPIO Peripheral extension features ##### 24 | ============================================================================== 25 | [..] GPIO module on STM32F1 family, manage also the AFIO register: 26 | (+) Possibility to use the EVENTOUT Cortex feature 27 | 28 | ##### How to use this driver ##### 29 | ============================================================================== 30 | [..] This driver provides functions to use EVENTOUT Cortex feature 31 | (#) Configure EVENTOUT Cortex feature using the function HAL_GPIOEx_ConfigEventout() 32 | (#) Activate EVENTOUT Cortex feature using the HAL_GPIOEx_EnableEventout() 33 | (#) Deactivate EVENTOUT Cortex feature using the HAL_GPIOEx_DisableEventout() 34 | 35 | @endverbatim 36 | ****************************************************************************** 37 | */ 38 | 39 | /* Includes ------------------------------------------------------------------*/ 40 | #include "stm32f1xx_hal.h" 41 | 42 | /** @addtogroup STM32F1xx_HAL_Driver 43 | * @{ 44 | */ 45 | 46 | /** @defgroup GPIOEx GPIOEx 47 | * @brief GPIO HAL module driver 48 | * @{ 49 | */ 50 | 51 | #ifdef HAL_GPIO_MODULE_ENABLED 52 | 53 | /** @defgroup GPIOEx_Exported_Functions GPIOEx Exported Functions 54 | * @{ 55 | */ 56 | 57 | /** @defgroup GPIOEx_Exported_Functions_Group1 Extended features functions 58 | * @brief Extended features functions 59 | * 60 | @verbatim 61 | ============================================================================== 62 | ##### Extended features functions ##### 63 | ============================================================================== 64 | [..] This section provides functions allowing to: 65 | (+) Configure EVENTOUT Cortex feature using the function HAL_GPIOEx_ConfigEventout() 66 | (+) Activate EVENTOUT Cortex feature using the HAL_GPIOEx_EnableEventout() 67 | (+) Deactivate EVENTOUT Cortex feature using the HAL_GPIOEx_DisableEventout() 68 | 69 | @endverbatim 70 | * @{ 71 | */ 72 | 73 | /** 74 | * @brief Configures the port and pin on which the EVENTOUT Cortex signal will be connected. 75 | * @param GPIO_PortSource Select the port used to output the Cortex EVENTOUT signal. 76 | * This parameter can be a value of @ref GPIOEx_EVENTOUT_PORT. 77 | * @param GPIO_PinSource Select the pin used to output the Cortex EVENTOUT signal. 78 | * This parameter can be a value of @ref GPIOEx_EVENTOUT_PIN. 79 | * @retval None 80 | */ 81 | void HAL_GPIOEx_ConfigEventout(uint32_t GPIO_PortSource, uint32_t GPIO_PinSource) 82 | { 83 | /* Verify the parameters */ 84 | assert_param(IS_AFIO_EVENTOUT_PORT(GPIO_PortSource)); 85 | assert_param(IS_AFIO_EVENTOUT_PIN(GPIO_PinSource)); 86 | 87 | /* Apply the new configuration */ 88 | MODIFY_REG(AFIO->EVCR, (AFIO_EVCR_PORT) | (AFIO_EVCR_PIN), (GPIO_PortSource) | (GPIO_PinSource)); 89 | } 90 | 91 | /** 92 | * @brief Enables the Event Output. 93 | * @retval None 94 | */ 95 | void HAL_GPIOEx_EnableEventout(void) 96 | { 97 | SET_BIT(AFIO->EVCR, AFIO_EVCR_EVOE); 98 | } 99 | 100 | /** 101 | * @brief Disables the Event Output. 102 | * @retval None 103 | */ 104 | void HAL_GPIOEx_DisableEventout(void) 105 | { 106 | CLEAR_BIT(AFIO->EVCR, AFIO_EVCR_EVOE); 107 | } 108 | 109 | /** 110 | * @} 111 | */ 112 | 113 | /** 114 | * @} 115 | */ 116 | 117 | #endif /* HAL_GPIO_MODULE_ENABLED */ 118 | 119 | /** 120 | * @} 121 | */ 122 | 123 | /** 124 | * @} 125 | */ 126 | 127 | -------------------------------------------------------------------------------- /STM32_Expander/CubeMX/Makefile: -------------------------------------------------------------------------------- 1 | ########################################################################################################################## 2 | # File automatically-generated by tool: [projectgenerator] version: [4.2.0-B44] date: [Fri Feb 21 10:14:29 HST 2025] 3 | ########################################################################################################################## 4 | 5 | # ------------------------------------------------ 6 | # Generic Makefile (based on gcc) 7 | # 8 | # ChangeLog : 9 | # 2017-02-10 - Several enhancements + project update mode 10 | # 2015-07-22 - first version 11 | # ------------------------------------------------ 12 | 13 | ###################################### 14 | # target 15 | ###################################### 16 | TARGET = USART1_DMAv3 17 | 18 | 19 | ###################################### 20 | # building variables 21 | ###################################### 22 | # debug build? 23 | DEBUG = 1 24 | # optimization 25 | OPT = -Og 26 | 27 | 28 | ####################################### 29 | # paths 30 | ####################################### 31 | # Build path 32 | BUILD_DIR = build 33 | 34 | ###################################### 35 | # source 36 | ###################################### 37 | # C sources 38 | C_SOURCES = \ 39 | Core/Src/main.c \ 40 | Core/Src/gpio.c \ 41 | Core/Src/dma.c \ 42 | Core/Src/tim.c \ 43 | Core/Src/usart.c \ 44 | Core/Src/stm32f1xx_it.c \ 45 | Core/Src/stm32f1xx_hal_msp.c \ 46 | Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio_ex.c \ 47 | Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim.c \ 48 | Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim_ex.c \ 49 | Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal.c \ 50 | Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc.c \ 51 | Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc_ex.c \ 52 | Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio.c \ 53 | Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_dma.c \ 54 | Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_cortex.c \ 55 | Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_pwr.c \ 56 | Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_flash.c \ 57 | Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_flash_ex.c \ 58 | Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_exti.c \ 59 | Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_uart.c \ 60 | Core/Src/system_stm32f1xx.c 61 | 62 | # ASM sources 63 | ASM_SOURCES = \ 64 | startup_stm32f103xb.s 65 | 66 | # ASM sources 67 | ASMM_SOURCES = 68 | 69 | 70 | ####################################### 71 | # binaries 72 | ####################################### 73 | PREFIX = arm-none-eabi- 74 | # The gcc compiler bin path can be either defined in make command via GCC_PATH variable (> make GCC_PATH=xxx) 75 | # either it can be added to the PATH environment variable. 76 | ifdef GCC_PATH 77 | CC = $(GCC_PATH)/$(PREFIX)gcc 78 | AS = $(GCC_PATH)/$(PREFIX)gcc -x assembler-with-cpp 79 | CP = $(GCC_PATH)/$(PREFIX)objcopy 80 | SZ = $(GCC_PATH)/$(PREFIX)size 81 | else 82 | CC = $(PREFIX)gcc 83 | AS = $(PREFIX)gcc -x assembler-with-cpp 84 | CP = $(PREFIX)objcopy 85 | SZ = $(PREFIX)size 86 | endif 87 | HEX = $(CP) -O ihex 88 | BIN = $(CP) -O binary -S 89 | 90 | ####################################### 91 | # CFLAGS 92 | ####################################### 93 | # cpu 94 | CPU = -mcpu=cortex-m3 95 | 96 | # fpu 97 | # NONE for Cortex-M0/M0+/M3 98 | 99 | # float-abi 100 | 101 | 102 | # mcu 103 | MCU = $(CPU) -mthumb $(FPU) $(FLOAT-ABI) 104 | 105 | # macros for gcc 106 | # AS defines 107 | AS_DEFS = 108 | 109 | # C defines 110 | C_DEFS = \ 111 | -DUSE_HAL_DRIVER \ 112 | -DSTM32F103xB 113 | 114 | 115 | # AS includes 116 | AS_INCLUDES = 117 | 118 | # C includes 119 | C_INCLUDES = \ 120 | -ICore/Inc \ 121 | -IDrivers/STM32F1xx_HAL_Driver/Inc \ 122 | -IDrivers/STM32F1xx_HAL_Driver/Inc/Legacy \ 123 | -IDrivers/CMSIS/Device/ST/STM32F1xx/Include \ 124 | -IDrivers/CMSIS/Include 125 | 126 | 127 | # compile gcc flags 128 | ASFLAGS = $(MCU) $(AS_DEFS) $(AS_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sections 129 | 130 | CFLAGS += $(MCU) $(C_DEFS) $(C_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sections 131 | 132 | ifeq ($(DEBUG), 1) 133 | CFLAGS += -g -gdwarf-2 134 | endif 135 | 136 | 137 | # Generate dependency information 138 | CFLAGS += -MMD -MP -MF"$(@:%.o=%.d)" 139 | 140 | 141 | ####################################### 142 | # LDFLAGS 143 | ####################################### 144 | # link script 145 | LDSCRIPT = STM32F103C8Tx_FLASH.ld 146 | 147 | # libraries 148 | LIBS = -lc -lm -lnosys 149 | LIBDIR = 150 | LDFLAGS = $(MCU) -specs=nano.specs -T$(LDSCRIPT) $(LIBDIR) $(LIBS) -Wl,-Map=$(BUILD_DIR)/$(TARGET).map,--cref -Wl,--gc-sections 151 | 152 | # default action: build all 153 | all: $(BUILD_DIR)/$(TARGET).elf $(BUILD_DIR)/$(TARGET).hex $(BUILD_DIR)/$(TARGET).bin 154 | 155 | 156 | ####################################### 157 | # build the application 158 | ####################################### 159 | # list of objects 160 | OBJECTS = $(addprefix $(BUILD_DIR)/,$(notdir $(C_SOURCES:.c=.o))) 161 | vpath %.c $(sort $(dir $(C_SOURCES))) 162 | # list of ASM program objects 163 | OBJECTS += $(addprefix $(BUILD_DIR)/,$(notdir $(ASM_SOURCES:.s=.o))) 164 | vpath %.s $(sort $(dir $(ASM_SOURCES))) 165 | OBJECTS += $(addprefix $(BUILD_DIR)/,$(notdir $(ASMM_SOURCES:.S=.o))) 166 | vpath %.S $(sort $(dir $(ASMM_SOURCES))) 167 | 168 | $(BUILD_DIR)/%.o: %.c Makefile | $(BUILD_DIR) 169 | $(CC) -c $(CFLAGS) -Wa,-a,-ad,-alms=$(BUILD_DIR)/$(notdir $(<:.c=.lst)) $< -o $@ 170 | 171 | $(BUILD_DIR)/%.o: %.s Makefile | $(BUILD_DIR) 172 | $(AS) -c $(CFLAGS) $< -o $@ 173 | $(BUILD_DIR)/%.o: %.S Makefile | $(BUILD_DIR) 174 | $(AS) -c $(CFLAGS) $< -o $@ 175 | 176 | $(BUILD_DIR)/$(TARGET).elf: $(OBJECTS) Makefile 177 | $(CC) $(OBJECTS) $(LDFLAGS) -o $@ 178 | $(SZ) $@ 179 | 180 | $(BUILD_DIR)/%.hex: $(BUILD_DIR)/%.elf | $(BUILD_DIR) 181 | $(HEX) $< $@ 182 | 183 | $(BUILD_DIR)/%.bin: $(BUILD_DIR)/%.elf | $(BUILD_DIR) 184 | $(BIN) $< $@ 185 | 186 | $(BUILD_DIR): 187 | mkdir $@ 188 | 189 | ####################################### 190 | # clean up 191 | ####################################### 192 | clean: 193 | -rm -fR $(BUILD_DIR) 194 | 195 | ####################################### 196 | # dependencies 197 | ####################################### 198 | -include $(wildcard $(BUILD_DIR)/*.d) 199 | 200 | # *** EOF *** 201 | -------------------------------------------------------------------------------- /STM32_Expander/CubeMX/STM32F103C8Tx_FLASH.ld: -------------------------------------------------------------------------------- 1 | /* 2 | ****************************************************************************** 3 | ** 4 | 5 | ** File : LinkerScript.ld 6 | ** 7 | ** Author : STM32CubeMX 8 | ** 9 | ** Abstract : Linker script for STM32F103C8Tx series 10 | ** 64Kbytes FLASH and 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) 2019 STMicroelectronics

26 | ** 27 | ** Redistribution and use in source and binary forms, with or without modification, 28 | ** are permitted provided that the following conditions are met: 29 | ** 1. Redistributions of source code must retain the above copyright notice, 30 | ** this list of conditions and the following disclaimer. 31 | ** 2. Redistributions in binary form must reproduce the above copyright notice, 32 | ** this list of conditions and the following disclaimer in the documentation 33 | ** and/or other materials provided with the distribution. 34 | ** 3. Neither the name of STMicroelectronics nor the names of its contributors 35 | ** may be used to endorse or promote products derived from this software 36 | ** without specific prior written permission. 37 | ** 38 | ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 39 | ** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 40 | ** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 41 | ** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 42 | ** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 43 | ** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 44 | ** SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 45 | ** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 46 | ** OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 47 | ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 48 | ** 49 | ***************************************************************************** 50 | */ 51 | 52 | /* Entry Point */ 53 | ENTRY(Reset_Handler) 54 | 55 | /* Highest address of the user mode stack */ 56 | _estack = ORIGIN(RAM) + LENGTH(RAM); /* end of RAM */ 57 | /* Generate a link error if heap and stack don't fit into RAM */ 58 | _Min_Heap_Size = 0x200; /* required amount of heap */ 59 | _Min_Stack_Size = 0x400; /* required amount of stack */ 60 | 61 | /* Specify the memory areas */ 62 | MEMORY 63 | { 64 | RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 20K 65 | FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 64K 66 | } 67 | 68 | /* Define output sections */ 69 | SECTIONS 70 | { 71 | /* The startup code goes first into FLASH */ 72 | .isr_vector : 73 | { 74 | . = ALIGN(4); 75 | KEEP(*(.isr_vector)) /* Startup code */ 76 | . = ALIGN(4); 77 | } >FLASH 78 | 79 | /* The program code and other data goes into FLASH */ 80 | .text : 81 | { 82 | . = ALIGN(4); 83 | *(.text) /* .text sections (code) */ 84 | *(.text*) /* .text* sections (code) */ 85 | *(.glue_7) /* glue arm to thumb code */ 86 | *(.glue_7t) /* glue thumb to arm code */ 87 | *(.eh_frame) 88 | 89 | KEEP (*(.init)) 90 | KEEP (*(.fini)) 91 | 92 | . = ALIGN(4); 93 | _etext = .; /* define a global symbols at end of code */ 94 | } >FLASH 95 | 96 | /* Constant data goes into FLASH */ 97 | .rodata : 98 | { 99 | . = ALIGN(4); 100 | *(.rodata) /* .rodata sections (constants, strings, etc.) */ 101 | *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ 102 | . = ALIGN(4); 103 | } >FLASH 104 | 105 | .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH 106 | .ARM : { 107 | __exidx_start = .; 108 | *(.ARM.exidx*) 109 | __exidx_end = .; 110 | } >FLASH 111 | 112 | .preinit_array : 113 | { 114 | PROVIDE_HIDDEN (__preinit_array_start = .); 115 | KEEP (*(.preinit_array*)) 116 | PROVIDE_HIDDEN (__preinit_array_end = .); 117 | } >FLASH 118 | .init_array : 119 | { 120 | PROVIDE_HIDDEN (__init_array_start = .); 121 | KEEP (*(SORT(.init_array.*))) 122 | KEEP (*(.init_array*)) 123 | PROVIDE_HIDDEN (__init_array_end = .); 124 | } >FLASH 125 | .fini_array : 126 | { 127 | PROVIDE_HIDDEN (__fini_array_start = .); 128 | KEEP (*(SORT(.fini_array.*))) 129 | KEEP (*(.fini_array*)) 130 | PROVIDE_HIDDEN (__fini_array_end = .); 131 | } >FLASH 132 | 133 | /* used by the startup to initialize data */ 134 | _sidata = LOADADDR(.data); 135 | 136 | /* Initialized data sections goes into RAM, load LMA copy after code */ 137 | .data : 138 | { 139 | . = ALIGN(4); 140 | _sdata = .; /* create a global symbol at data start */ 141 | *(.data) /* .data sections */ 142 | *(.data*) /* .data* sections */ 143 | 144 | . = ALIGN(4); 145 | _edata = .; /* define a global symbol at data end */ 146 | } >RAM AT> FLASH 147 | 148 | 149 | /* Uninitialized data section */ 150 | . = ALIGN(4); 151 | .bss : 152 | { 153 | /* This is used by the startup in order to initialize the .bss secion */ 154 | _sbss = .; /* define a global symbol at bss start */ 155 | __bss_start__ = _sbss; 156 | *(.bss) 157 | *(.bss*) 158 | *(COMMON) 159 | 160 | . = ALIGN(4); 161 | _ebss = .; /* define a global symbol at bss end */ 162 | __bss_end__ = _ebss; 163 | } >RAM 164 | 165 | /* User_heap_stack section, used to check that there is enough RAM left */ 166 | ._user_heap_stack : 167 | { 168 | . = ALIGN(8); 169 | PROVIDE ( end = . ); 170 | PROVIDE ( _end = . ); 171 | . = . + _Min_Heap_Size; 172 | . = . + _Min_Stack_Size; 173 | . = ALIGN(8); 174 | } >RAM 175 | 176 | 177 | 178 | /* Remove information from the standard libraries */ 179 | /DISCARD/ : 180 | { 181 | libc.a ( * ) 182 | libm.a ( * ) 183 | libgcc.a ( * ) 184 | } 185 | 186 | .ARM.attributes 0 : { *(.ARM.attributes) } 187 | } 188 | 189 | 190 | -------------------------------------------------------------------------------- /STM32_Expander/CubeMX/USART1_DMAv3.ioc: -------------------------------------------------------------------------------- 1 | #MicroXplorer Configuration settings - do not modify 2 | CAD.formats= 3 | CAD.pinconfig= 4 | CAD.provider= 5 | Dma.Request0=USART1_RX 6 | Dma.Request1=USART2_RX 7 | Dma.RequestsNb=2 8 | Dma.USART1_RX.0.Direction=DMA_PERIPH_TO_MEMORY 9 | Dma.USART1_RX.0.Instance=DMA1_Channel5 10 | Dma.USART1_RX.0.MemDataAlignment=DMA_MDATAALIGN_BYTE 11 | Dma.USART1_RX.0.MemInc=DMA_MINC_ENABLE 12 | Dma.USART1_RX.0.Mode=DMA_CIRCULAR 13 | Dma.USART1_RX.0.PeriphDataAlignment=DMA_PDATAALIGN_BYTE 14 | Dma.USART1_RX.0.PeriphInc=DMA_PINC_DISABLE 15 | Dma.USART1_RX.0.Priority=DMA_PRIORITY_LOW 16 | Dma.USART1_RX.0.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority 17 | Dma.USART2_RX.1.Direction=DMA_PERIPH_TO_MEMORY 18 | Dma.USART2_RX.1.Instance=DMA1_Channel6 19 | Dma.USART2_RX.1.MemDataAlignment=DMA_MDATAALIGN_BYTE 20 | Dma.USART2_RX.1.MemInc=DMA_MINC_ENABLE 21 | Dma.USART2_RX.1.Mode=DMA_NORMAL 22 | Dma.USART2_RX.1.PeriphDataAlignment=DMA_PDATAALIGN_BYTE 23 | Dma.USART2_RX.1.PeriphInc=DMA_PINC_DISABLE 24 | Dma.USART2_RX.1.Priority=DMA_PRIORITY_LOW 25 | Dma.USART2_RX.1.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority 26 | File.Version=6 27 | GPIO.groupedBy=Group By Peripherals 28 | KeepUserPlacement=false 29 | Mcu.CPN=STM32F103C8T6 30 | Mcu.Family=STM32F1 31 | Mcu.IP0=DMA 32 | Mcu.IP1=NVIC 33 | Mcu.IP2=RCC 34 | Mcu.IP3=SYS 35 | Mcu.IP4=TIM1 36 | Mcu.IP5=TIM2 37 | Mcu.IP6=TIM3 38 | Mcu.IP7=TIM4 39 | Mcu.IP8=USART1 40 | Mcu.IP9=USART2 41 | Mcu.IPNb=10 42 | Mcu.Name=STM32F103C(8-B)Tx 43 | Mcu.Package=LQFP48 44 | Mcu.Pin0=PD0-OSC_IN 45 | Mcu.Pin1=PD1-OSC_OUT 46 | Mcu.Pin10=PB0 47 | Mcu.Pin11=PB1 48 | Mcu.Pin12=PB10 49 | Mcu.Pin13=PB11 50 | Mcu.Pin14=PB13 51 | Mcu.Pin15=PB14 52 | Mcu.Pin16=PB15 53 | Mcu.Pin17=PA8 54 | Mcu.Pin18=PA9 55 | Mcu.Pin19=PA10 56 | Mcu.Pin2=PA0-WKUP 57 | Mcu.Pin20=PA11 58 | Mcu.Pin21=PA12 59 | Mcu.Pin22=PA13 60 | Mcu.Pin23=PA14 61 | Mcu.Pin24=PB6 62 | Mcu.Pin25=PB7 63 | Mcu.Pin26=PB8 64 | Mcu.Pin27=PB9 65 | Mcu.Pin28=VP_SYS_VS_Systick 66 | Mcu.Pin29=VP_TIM1_VS_ClockSourceINT 67 | Mcu.Pin3=PA1 68 | Mcu.Pin4=PA2 69 | Mcu.Pin5=PA3 70 | Mcu.Pin6=PA4 71 | Mcu.Pin7=PA5 72 | Mcu.Pin8=PA6 73 | Mcu.Pin9=PA7 74 | Mcu.PinsNb=30 75 | Mcu.ThirdPartyNb=0 76 | Mcu.UserConstants= 77 | Mcu.UserName=STM32F103C8Tx 78 | MxCube.Version=6.10.0 79 | MxDb.Version=DB.6.0.100 80 | NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false 81 | NVIC.DMA1_Channel5_IRQn=true\:0\:0\:false\:false\:true\:false\:true\:true 82 | NVIC.DMA1_Channel6_IRQn=true\:0\:0\:false\:false\:true\:false\:true\:true 83 | NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false 84 | NVIC.ForceEnableDMAVector=true 85 | NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false 86 | NVIC.MemoryManagement_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false 87 | NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false 88 | NVIC.PendSV_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false 89 | NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4 90 | NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false 91 | NVIC.SysTick_IRQn=true\:15\:0\:false\:false\:true\:false\:true\:false 92 | NVIC.USART2_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true 93 | NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false 94 | PA0-WKUP.Locked=true 95 | PA0-WKUP.Signal=S_TIM2_CH1_ETR 96 | PA1.Locked=true 97 | PA1.Signal=GPIO_Output 98 | PA10.Locked=true 99 | PA10.Mode=Asynchronous 100 | PA10.Signal=USART1_RX 101 | PA11.Locked=true 102 | PA11.Signal=GPIO_Input 103 | PA12.Locked=true 104 | PA12.Signal=GPIO_Input 105 | PA13.Locked=true 106 | PA13.Mode=Serial_Wire 107 | PA13.Signal=SYS_JTMS-SWDIO 108 | PA14.Locked=true 109 | PA14.Mode=Serial_Wire 110 | PA14.Signal=SYS_JTCK-SWCLK 111 | PA2.Mode=Asynchronous 112 | PA2.Signal=USART2_TX 113 | PA3.Mode=Asynchronous 114 | PA3.Signal=USART2_RX 115 | PA4.Locked=true 116 | PA4.Signal=GPIO_Input 117 | PA5.Locked=true 118 | PA5.Signal=GPIO_Input 119 | PA6.Locked=true 120 | PA6.Signal=S_TIM3_CH1 121 | PA7.Locked=true 122 | PA7.Signal=GPIO_Output 123 | PA8.Locked=true 124 | PA8.Signal=S_TIM1_CH1 125 | PA9.Locked=true 126 | PA9.Mode=Asynchronous 127 | PA9.Signal=USART1_TX 128 | PB0.Locked=true 129 | PB0.Signal=GPIO_Output 130 | PB1.Locked=true 131 | PB1.Signal=GPIO_Input 132 | PB10.Locked=true 133 | PB10.Signal=GPIO_Input 134 | PB11.Locked=true 135 | PB11.Signal=GPIO_Input 136 | PB13.Locked=true 137 | PB13.Signal=GPIO_Input 138 | PB14.Locked=true 139 | PB14.Signal=GPIO_Input 140 | PB15.Locked=true 141 | PB15.Signal=GPIO_Input 142 | PB6.Locked=true 143 | PB6.Signal=GPIO_Output 144 | PB7.Locked=true 145 | PB7.Signal=GPIO_Output 146 | PB8.Locked=true 147 | PB8.Signal=S_TIM4_CH3 148 | PB9.Locked=true 149 | PB9.Signal=S_TIM4_CH4 150 | PD0-OSC_IN.Mode=HSE-External-Oscillator 151 | PD0-OSC_IN.Signal=RCC_OSC_IN 152 | PD1-OSC_OUT.Mode=HSE-External-Oscillator 153 | PD1-OSC_OUT.Signal=RCC_OSC_OUT 154 | PinOutPanel.RotationAngle=0 155 | ProjectManager.AskForMigrate=true 156 | ProjectManager.BackupPrevious=false 157 | ProjectManager.CompilerOptimize=6 158 | ProjectManager.ComputerToolchain=false 159 | ProjectManager.CoupleFile=true 160 | ProjectManager.CustomerFirmwarePackage= 161 | ProjectManager.DefaultFWLocation=true 162 | ProjectManager.DeletePrevious=true 163 | ProjectManager.DeviceId=STM32F103C8Tx 164 | ProjectManager.FirmwarePackage=STM32Cube FW_F1 V1.8.5 165 | ProjectManager.FreePins=false 166 | ProjectManager.HalAssertFull=false 167 | ProjectManager.HeapSize=0x200 168 | ProjectManager.KeepUserCode=true 169 | ProjectManager.LastFirmware=false 170 | ProjectManager.LibraryCopy=1 171 | ProjectManager.MainLocation=Core/Src 172 | ProjectManager.NoMain=false 173 | ProjectManager.PreviousToolchain= 174 | ProjectManager.ProjectBuild=false 175 | ProjectManager.ProjectFileName=USART1_DMAv3.ioc 176 | ProjectManager.ProjectName=USART1_DMAv3 177 | ProjectManager.ProjectStructure= 178 | ProjectManager.RegisterCallBack= 179 | ProjectManager.StackSize=0x400 180 | ProjectManager.TargetToolchain=Makefile 181 | ProjectManager.ToolChainLocation= 182 | ProjectManager.UAScriptAfterPath= 183 | ProjectManager.UAScriptBeforePath= 184 | ProjectManager.UnderRoot=false 185 | ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_DMA_Init-DMA-false-HAL-true,4-MX_USART2_UART_Init-USART2-false-HAL-true,5-MX_USART1_UART_Init-USART1-false-HAL-true,6-MX_TIM1_Init-TIM1-false-HAL-true,7-MX_TIM2_Init-TIM2-false-HAL-true,8-MX_TIM3_Init-TIM3-false-HAL-true,9-MX_TIM4_Init-TIM4-false-HAL-true 186 | RCC.ADCFreqValue=8000000 187 | RCC.AHBFreq_Value=16000000 188 | RCC.APB1Freq_Value=16000000 189 | RCC.APB1TimFreq_Value=16000000 190 | RCC.APB2Freq_Value=16000000 191 | RCC.APB2TimFreq_Value=16000000 192 | RCC.FCLKCortexFreq_Value=16000000 193 | RCC.FamilyName=M 194 | RCC.HCLKFreq_Value=16000000 195 | RCC.IPParameters=ADCFreqValue,AHBFreq_Value,APB1Freq_Value,APB1TimFreq_Value,APB2Freq_Value,APB2TimFreq_Value,FCLKCortexFreq_Value,FamilyName,HCLKFreq_Value,MCOFreq_Value,PLLCLKFreq_Value,PLLMCOFreq_Value,PLLMUL,SYSCLKFreq_VALUE,SYSCLKSource,TimSysFreq_Value,USBFreq_Value 196 | RCC.MCOFreq_Value=16000000 197 | RCC.PLLCLKFreq_Value=16000000 198 | RCC.PLLMCOFreq_Value=8000000 199 | RCC.PLLMUL=RCC_PLL_MUL4 200 | RCC.SYSCLKFreq_VALUE=16000000 201 | RCC.SYSCLKSource=RCC_SYSCLKSOURCE_PLLCLK 202 | RCC.TimSysFreq_Value=16000000 203 | RCC.USBFreq_Value=16000000 204 | SH.S_TIM1_CH1.0=TIM1_CH1,PWM Generation1 CH1 205 | SH.S_TIM1_CH1.ConfNb=1 206 | SH.S_TIM2_CH1_ETR.0=TIM2_CH1,PWM Generation1 CH1 207 | SH.S_TIM2_CH1_ETR.ConfNb=1 208 | SH.S_TIM3_CH1.0=TIM3_CH1,PWM Generation1 CH1 209 | SH.S_TIM3_CH1.ConfNb=1 210 | SH.S_TIM4_CH3.0=TIM4_CH3,PWM Generation3 CH3 211 | SH.S_TIM4_CH3.ConfNb=1 212 | SH.S_TIM4_CH4.0=TIM4_CH4,PWM Generation4 CH4 213 | SH.S_TIM4_CH4.ConfNb=1 214 | TIM1.AutoReloadPreload=TIM_AUTORELOAD_PRELOAD_ENABLE 215 | TIM1.Channel-PWM\ Generation1\ CH1=TIM_CHANNEL_1 216 | TIM1.IPParameters=Channel-PWM Generation1 CH1,Period,AutoReloadPreload,Pulse-PWM Generation1 CH1,OCPolarity_1 217 | TIM1.OCPolarity_1=TIM_OCPOLARITY_HIGH 218 | TIM1.Period=1023 219 | TIM1.Pulse-PWM\ Generation1\ CH1=512 220 | TIM2.Channel-PWM\ Generation1\ CH1=TIM_CHANNEL_1 221 | TIM2.IPParameters=Channel-PWM Generation1 CH1 222 | TIM3.Channel-PWM\ Generation1\ CH1=TIM_CHANNEL_1 223 | TIM3.IPParameters=Channel-PWM Generation1 CH1 224 | TIM4.Channel-PWM\ Generation3\ CH3=TIM_CHANNEL_3 225 | TIM4.Channel-PWM\ Generation4\ CH4=TIM_CHANNEL_4 226 | TIM4.IPParameters=Channel-PWM Generation4 CH4,Channel-PWM Generation3 CH3,Prescaler,Period,Pulse-PWM Generation3 CH3,Pulse-PWM Generation4 CH4 227 | TIM4.Period=1023 228 | TIM4.Prescaler=3 229 | TIM4.Pulse-PWM\ Generation3\ CH3=256 230 | TIM4.Pulse-PWM\ Generation4\ CH4=128 231 | USART1.BaudRate=921600 232 | USART1.IPParameters=VirtualMode,BaudRate 233 | USART1.VirtualMode=VM_ASYNC 234 | USART2.BaudRate=921600 235 | USART2.IPParameters=VirtualMode,BaudRate 236 | USART2.VirtualMode=VM_ASYNC 237 | VP_SYS_VS_Systick.Mode=SysTick 238 | VP_SYS_VS_Systick.Signal=SYS_VS_Systick 239 | VP_TIM1_VS_ClockSourceINT.Mode=Internal 240 | VP_TIM1_VS_ClockSourceINT.Signal=TIM1_VS_ClockSourceINT 241 | board=custom 242 | -------------------------------------------------------------------------------- /STM32_Expander/CubeMX/USART1_DMAv3.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bdring/PendantsForFluidNC/320abd6fb509cd806d1a9ff08472a64dc7e0c971/STM32_Expander/CubeMX/USART1_DMAv3.pdf -------------------------------------------------------------------------------- /STM32_Expander/CubeMX/USART1_DMAv3.txt: -------------------------------------------------------------------------------- 1 | Configuration USART1_DMAv3 2 | STM32CubeMX 6.10.0 3 | Date 02/21/2025 4 | MCU STM32F103C8Tx 5 | 6 | 7 | 8 | PERIPHERALS MODES FUNCTIONS PINS 9 | RCC Crystal/Ceramic Resonator RCC_OSC_IN PD0-OSC_IN 10 | RCC Crystal/Ceramic Resonator RCC_OSC_OUT PD1-OSC_OUT 11 | SYS Serial Wire SYS_JTCK-SWCLK PA14 12 | SYS Serial Wire SYS_JTMS-SWDIO PA13 13 | SYS SysTick SYS_VS_Systick VP_SYS_VS_Systick 14 | TIM1 Internal Clock TIM1_VS_ClockSourceINT VP_TIM1_VS_ClockSourceINT 15 | TIM1 PWM Generation CH1 TIM1_CH1 PA8 16 | TIM2 PWM Generation CH1 TIM2_CH1 PA0-WKUP 17 | TIM3 PWM Generation CH1 TIM3_CH1 PA6 18 | TIM4 PWM Generation CH4 TIM4_CH4 PB9 19 | USART1 Asynchronous USART1_RX PA10 20 | USART1 Asynchronous USART1_TX PA9 21 | USART2 Asynchronous USART2_RX PA3 22 | USART2 Asynchronous USART2_TX PA2 23 | 24 | 25 | 26 | Pin Nb PINs FUNCTIONs LABELs 27 | 5 PD0-OSC_IN RCC_OSC_IN 28 | 6 PD1-OSC_OUT RCC_OSC_OUT 29 | 10 PA0-WKUP TIM2_CH1 30 | 11 PA1 GPIO_Output 31 | 12 PA2 USART2_TX 32 | 13 PA3 USART2_RX 33 | 14 PA4 GPIO_Input 34 | 15 PA5 GPIO_Input 35 | 16 PA6 TIM3_CH1 36 | 17 PA7 GPIO_Output 37 | 18 PB0 GPIO_Output 38 | 19 PB1 GPIO_Input 39 | 21 PB10 GPIO_Input 40 | 22 PB11 GPIO_Input 41 | 26 PB13 GPIO_Input 42 | 27 PB14 GPIO_Input 43 | 28 PB15 GPIO_Input 44 | 29 PA8 TIM1_CH1 45 | 30 PA9 USART1_TX 46 | 31 PA10 USART1_RX 47 | 32 PA11 GPIO_Input 48 | 33 PA12 GPIO_Input 49 | 34 PA13 SYS_JTMS-SWDIO 50 | 37 PA14 SYS_JTCK-SWCLK 51 | 42 PB6 GPIO_Output 52 | 43 PB7 GPIO_Output 53 | 45 PB8 GPIO_Output 54 | 46 PB9 TIM4_CH4 55 | PERIPHERALS MODES FUNCTIONS PINS 56 | RCC Crystal/Ceramic Resonator RCC_OSC_IN PD0-OSC_IN 57 | RCC Crystal/Ceramic Resonator RCC_OSC_OUT PD1-OSC_OUT 58 | SYS Serial Wire SYS_JTCK-SWCLK PA14 59 | SYS Serial Wire SYS_JTMS-SWDIO PA13 60 | SYS SysTick SYS_VS_Systick VP_SYS_VS_Systick 61 | TIM1 Internal Clock TIM1_VS_ClockSourceINT VP_TIM1_VS_ClockSourceINT 62 | TIM1 PWM Generation CH1 TIM1_CH1 PA8 63 | TIM2 PWM Generation CH1 TIM2_CH1 PA0-WKUP 64 | TIM3 PWM Generation CH1 TIM3_CH1 PA6 65 | TIM4 PWM Generation CH4 TIM4_CH4 PB9 66 | USART1 Asynchronous USART1_RX PA10 67 | USART1 Asynchronous USART1_TX PA9 68 | USART2 Asynchronous USART2_RX PA3 69 | USART2 Asynchronous USART2_TX PA2 70 | 71 | 72 | 73 | Pin Nb PINs FUNCTIONs LABELs 74 | 5 PD0-OSC_IN RCC_OSC_IN 75 | 6 PD1-OSC_OUT RCC_OSC_OUT 76 | 10 PA0-WKUP TIM2_CH1 77 | 11 PA1 GPIO_Output 78 | 12 PA2 USART2_TX 79 | 13 PA3 USART2_RX 80 | 14 PA4 GPIO_Input 81 | 15 PA5 GPIO_Input 82 | 16 PA6 TIM3_CH1 83 | 17 PA7 GPIO_Output 84 | 18 PB0 GPIO_Output 85 | 19 PB1 GPIO_Input 86 | 21 PB10 GPIO_Input 87 | 22 PB11 GPIO_Input 88 | 26 PB13 GPIO_Input 89 | 27 PB14 GPIO_Input 90 | 28 PB15 GPIO_Input 91 | 29 PA8 TIM1_CH1 92 | 30 PA9 USART1_TX 93 | 31 PA10 USART1_RX 94 | 32 PA11 GPIO_Input 95 | 33 PA12 GPIO_Input 96 | 34 PA13 SYS_JTMS-SWDIO 97 | 37 PA14 SYS_JTCK-SWCLK 98 | 42 PB6 GPIO_Output 99 | 43 PB7 GPIO_Output 100 | 45 PB8 GPIO_Output 101 | 46 PB9 TIM4_CH4 102 | 103 | 104 | 105 | SOFTWARE PROJECT 106 | 107 | Project Settings : 108 | Project Name : USART1_DMAv3 109 | Project Folder : C:\Users\wmb\Documents\PlatformIO\Projects\USART1_DMAv3 110 | Toolchain / IDE : Makefile 111 | Firmware Package Name and Version : STM32Cube FW_F1 V1.8.5 112 | 113 | 114 | Code Generation Settings : 115 | STM32Cube MCU packages and embedded software packs : Copy only the necessary library files 116 | Generate peripheral initialization as a pair of '.c/.h' files per peripheral : Yes 117 | Backup previously generated files when re-generating : No 118 | Delete previously generated files when not re-generated : Yes 119 | Set all free pins as analog (to optimize the power consumption) : No 120 | 121 | 122 | Toolchains Settings : 123 | Compiler Optimizations : 124 | 125 | 126 | 127 | 128 | 129 | -------------------------------------------------------------------------------- /STM32_Expander/git-version.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | import filecmp, tempfile, shutil, os 3 | 4 | # Thank you https://docs.platformio.org/en/latest/projectconf/section_env_build.html ! 5 | 6 | gitFail = False 7 | try: 8 | subprocess.check_call(["git", "status"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) 9 | except: 10 | gitFail = True 11 | 12 | if gitFail: 13 | tag = "" 14 | rev = " (noGit)" 15 | url = " (noGit)" 16 | else: 17 | try: 18 | tag = ( 19 | subprocess.check_output(["git", "describe", "--tags", "--abbrev=0"], stderr=subprocess.DEVNULL) 20 | .strip() 21 | .decode("utf-8") 22 | ) 23 | except: 24 | tag = "" 25 | 26 | # Check to see if the head commit exactly matches a tag. 27 | # If so, the revision is "release", otherwise it is BRANCH-COMMIT 28 | try: 29 | subprocess.check_call(["git", "describe", "--tags", "--exact"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) 30 | rev = '' 31 | except: 32 | branchname = ( 33 | subprocess.check_output(["git", "rev-parse", "--abbrev-ref", "HEAD"]) 34 | .strip() 35 | .decode("utf-8") 36 | ) 37 | revision = ( 38 | subprocess.check_output(["git", "rev-parse", "--short", "HEAD"]) 39 | .strip() 40 | .decode("utf-8") 41 | ) 42 | modified = ( 43 | subprocess.check_output(["git", "status", "-uno", "-s"]) 44 | .strip() 45 | .decode("utf-8") 46 | ) 47 | if modified: 48 | dirty = "-dirty" 49 | else: 50 | dirty = "" 51 | rev = "%s-%s%s" % (branchname, revision, dirty) 52 | 53 | url = ( 54 | subprocess.check_output(["git", "config", "--get", "remote.origin.url"]) 55 | .strip() 56 | .decode("utf-8") 57 | ) 58 | 59 | if tag == "": 60 | git_info = rev 61 | else: 62 | git_info = tag 63 | 64 | git_url = url 65 | 66 | provisional = "src/version.cx" 67 | final = "src/version.c" 68 | with open(provisional, "w") as fp: 69 | fp.write('const char* fw_version = \"' + git_info + '\";\n') 70 | fp.write('const char* git_url = \"' + git_url + '\";\n') 71 | 72 | if not os.path.exists(final): 73 | # No version.cpp so rename version.cxx to version.cpp 74 | os.rename(provisional, final) 75 | elif not filecmp.cmp(provisional, final): 76 | # version.cxx differs from version.cpp so get rid of the 77 | # old .cpp and rename .cxx to .cpp 78 | os.remove(final) 79 | os.rename(provisional, final) 80 | else: 81 | # The existing version.cpp is the same as the new version.cxx 82 | # so we can just leave the old version.cpp in place and get 83 | # rid of version.cxx 84 | os.remove(provisional) 85 | -------------------------------------------------------------------------------- /STM32_Expander/platformio.ini: -------------------------------------------------------------------------------- 1 | ; PlatformIO Project Configuration File 2 | 3 | [platformio] 4 | default_envs = airedale_v1_1 5 | src_dir = . 6 | lib_dir = ../lib 7 | 8 | [env:base] 9 | lib_deps = https://github.com/MitchBradley/GrblParser 10 | ; lib_deps = https://github.com/MitchBradley/FluidNCExpanderProtocol 11 | monitor_speed = 115200 12 | platform = ststm32 13 | board = genericSTM32F103C8 14 | debug_tool = stlink 15 | board_build.ldscript = CubeMX/STM32F103C8Tx_FLASH.ld 16 | ;upload_protocol=serial 17 | build_src_filter = 18 | +<**/*.c> 19 | +<**/*.S> 20 | -<**/Drivers/CMSIS/*> 21 | -<**/CubeMX-save/*> 22 | - 23 | build_flags = 24 | !python git-version.py 25 | ; -DSTARTUP_DEBUG 26 | -DFNC_BAUD=1000000 27 | -DPASSTHROUGH_BAUD=1000000 28 | -DUSE_HAL_DRIVER 29 | -DSTM32F103xB 30 | -Isrc 31 | -ICubeMX/Core/Inc 32 | -ICubeMX/Drivers/STM32F1xx_HAL_Driver/Inc 33 | -ICubeMX/Drivers/STM32F1xx_HAL_Driver/Inc/Legacy 34 | -ICubeMX/Drivers/CMSIS/Device/ST/STM32F1xx/Include 35 | -ICubeMX/Drivers/CMSIS/Include 36 | -specs=nano.specs 37 | -lgcc 38 | -ffunction-sections 39 | -fdata-sections 40 | -Wl,--gc-sections 41 | -Wl,-Map=app.map,--cref 42 | 43 | [env:airedale_v1_1] 44 | extends=env:base 45 | build_src_filter = ${env:base.build_src_filter} + 46 | 47 | -------------------------------------------------------------------------------- /STM32_Expander/src/app.c: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Mitch Bradley 2 | // Use of this source code is governed by a GPLv3 license that can be found in the LICENSE file. 3 | 4 | #include "Expander.h" 5 | #include "stm32f1xx_hal.h" 6 | #include "string.h" 7 | #include "pwm_pin.h" 8 | #include "gpio_pin.h" 9 | #include "dma_uart.h" 10 | #include "system.h" 11 | #include "gpiomap.h" 12 | #ifdef STARTUP_DEBUG 13 | # define DEBUG_PIN 8 14 | # define GH set_output(DEBUG_PIN, 1, 0); 15 | # define GL set_output(DEBUG_PIN, 0, 0); 16 | #endif 17 | 18 | int pass_getchar() { 19 | return dma_getchar(1); 20 | } 21 | 22 | void pass_print(const char* msg) { 23 | dma_print(1, msg); 24 | } 25 | 26 | void pass_println(const char* msg) { 27 | pass_print(msg); 28 | pass_print("\n"); 29 | } 30 | 31 | // Interface routines for GrblParser 32 | 33 | // Receive a byte from the serial port connected to FluidNC 34 | int fnc_getchar() { 35 | return dma_getchar(0); 36 | } 37 | 38 | // Send a byte to the serial port connected to FluidNC 39 | void fnc_putchar(uint8_t c) { 40 | dma_putchar(0, c); 41 | } 42 | 43 | // Return a value that increments every millisecond 44 | int milliseconds() { 45 | return HAL_GetTick(); 46 | } 47 | 48 | // Perform extra operations after the normal polling for input from FluidNC 49 | void poll_extra() { 50 | int c; 51 | while ((c = pass_getchar()) != -1) { 52 | if (c != '\0') { // Suppress nulls that can be caused by pendant startup messages at the wrong baud rate 53 | fnc_putchar(c); 54 | } 55 | } 56 | 57 | expander_poll(); 58 | } 59 | 60 | // Handle IO Expander messages 61 | void handle_report(char* report) { 62 | if (!expander_handle_command(report)) { 63 | pass_println(report); 64 | } 65 | } 66 | 67 | // void handle_signon(char* version, char* arguments) { } 68 | 69 | extern TIM_HandleTypeDef htim5; 70 | 71 | void delay_ms(uint32_t ms) { 72 | HAL_Delay(ms); 73 | } 74 | // Application initialization, called from main() in CubeMX/Core/Src/main.c after 75 | // the basic driver setup code that CubeMX generated has finished. 76 | void setup() { 77 | HAL_MspInit(); 78 | SystemClock_Config(); 79 | init_from_gpiomap(); 80 | init_dma_uart(0, FNC_BAUD, GPIOA, GPIO_PIN_9, GPIOA, GPIO_PIN_10); 81 | while (dma_getchar(0) != -1) { 82 | // Drain the FluidNC buffer 83 | } 84 | init_dma_uart(1, PASSTHROUGH_BAUD, GPIOA, GPIO_PIN_2, GPIOA, GPIO_PIN_3); 85 | while (dma_getchar(1) != -1) { 86 | // Drain the pass-through buffer 87 | } 88 | 89 | #ifdef STARTUP_DEBUG 90 | set_pin_mode(DEBUG_PIN, PIN_OUTPUT); 91 | GH; 92 | delay_ms(500); 93 | GL; 94 | delay_ms(500); 95 | GH; 96 | delay_ms(500); 97 | GL; 98 | #endif 99 | expander_start(); 100 | ready(); 101 | fnc_wait_ready(); 102 | } 103 | 104 | int main() { 105 | setup(); 106 | while (1) { 107 | fnc_poll(); 108 | } 109 | return 0; 110 | } 111 | -------------------------------------------------------------------------------- /STM32_Expander/src/boards/airedale_v1_1/gpiomap.c: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Mitch Bradley 2 | // Use of this source code is governed by a GPLv3 license that can be found in the LICENSE file. 3 | 4 | #include "pin.h" 5 | 6 | const char* board_name = "Airedale v1.1"; 7 | 8 | // This table maps io numbers (the table index) to 9 | // device-specific and board-specific pin numbers 10 | 11 | // clang-format off 12 | pin_t gpios[] = { 13 | // port num capabilities TIM ch io_num usage 14 | { .gpio = { GPIOA, GPIO_PIN_4, IN|PU|PD, 0, 0 } }, // 0 I0 15 | { .gpio = { GPIOA, GPIO_PIN_5, IN|PU|PD, 0, 0 } }, // 1 I1 16 | { .gpio = { GPIOB, GPIO_PIN_0, IN|PU|PD, 3, 3 } }, // 2 I2 17 | { .gpio = { GPIOB, GPIO_PIN_10, IN|PU|PD, 2, 3 } }, // 3 I3 18 | { .gpio = { GPIOA, GPIO_PIN_12, IN|PU|PD, 0, 0 } }, // 4 I4 19 | { .gpio = { GPIOB, GPIO_PIN_14, IN|PU|PD, 0, 0 } }, // 5 I5 20 | { .gpio = { GPIOB, GPIO_PIN_12, IN|PU|PD, 0, 0 } }, // 6 I6 21 | { .gpio = { GPIOB, GPIO_PIN_13, IN|PU|PD, 0, 0 } }, // 7 I7 22 | { .gpio = { GPIOA, GPIO_PIN_8, OUT|PWM, 1, 1 } }, // 8 O0 23 | { .gpio = { GPIOA, GPIO_PIN_0, OUT|PWM, 2, 1 } }, // 9 O1 24 | { .gpio = { GPIOA, GPIO_PIN_6, OUT|PWM, 3, 1 } }, // 10 O2 25 | { .gpio = { GPIOB, GPIO_PIN_6, OUT|PWM, 4, 1 } }, // 11 O3 26 | { .gpio = { GPIOA, GPIO_PIN_11, OUT|PWM, 1, 4 } }, // 12 O4 27 | { .gpio = { GPIOB, GPIO_PIN_11, OUT|PWM, 2, 4 } }, // 13 O5 28 | { .gpio = { GPIOB, GPIO_PIN_1, OUT|PWM, 3, 4 } }, // 14 O6 29 | { .gpio = { GPIOB, GPIO_PIN_9, OUT|PWM, 4, 4 } }, // 15 O7 30 | { .gpio = { GPIOA, GPIO_PIN_1, OUT|PWM, 2, 2 } }, // 16 FET0 31 | { .gpio = { GPIOA, GPIO_PIN_7, OUT|PWM, 3, 2 } }, // 17 FET1 32 | { .gpio = { GPIOB, GPIO_PIN_5, OUT, 0, 0 } }, // 18 RGB_LED RED 33 | { .gpio = { GPIOB, GPIO_PIN_4, OUT, 0, 0 } }, // 19 RGB_LED GREEN 34 | { .gpio = { GPIOB, GPIO_PIN_3, OUT, 0, 0 } }, // 20 RGB_LED BLUE 35 | }; 36 | // PB3, PB4, and PB5 can do PWM but it requires AF remapping which we 37 | // do not support 38 | 39 | const int n_pins = sizeof(gpios) / sizeof(gpios[0]); 40 | 41 | #define RED_LED 18 42 | #define GREEN_LED 19 43 | #define BLUE_LED 20 44 | 45 | static void init_leds() { 46 | set_pin_mode(18, PIN_OUTPUT|PIN_ACTIVELOW); 47 | set_pin_mode(19, PIN_OUTPUT|PIN_ACTIVELOW); 48 | set_pin_mode(20, PIN_OUTPUT|PIN_ACTIVELOW); 49 | } 50 | static void set_leds(bool red, bool green, bool blue) { 51 | set_output(RED_LED, red, 0); 52 | set_output(GREEN_LED, green, 0); 53 | set_output(BLUE_LED, blue, 0); 54 | } 55 | 56 | void expander_rst() { 57 | deinit_all_pins(); 58 | init_leds(); 59 | set_leds(0,0,1); // Blue 60 | } 61 | 62 | void ready() { 63 | init_leds(); 64 | set_leds(1,1,1); // White 65 | } 66 | -------------------------------------------------------------------------------- /STM32_Expander/src/boards/protov0/gpiomap.c: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Mitch Bradley 2 | // Use of this source code is governed by a GPLv3 license that can be found in the LICENSE file. 3 | 4 | #include "pin.h" 5 | 6 | // This table maps io numbers (the table index) to 7 | // device-specific and board-specific pin numbers 8 | 9 | // clang-format off 10 | pin_t gpios[] = { 11 | // port num capabilities io_num 12 | { .gpio = { GPIOA, GPIO_PIN_4, IN|PU|PD } }, // 0 13 | { .gpio = { GPIOA, GPIO_PIN_5, IN|PU|PD } }, // 1 14 | { .gpio = { GPIOA, GPIO_PIN_8, OUT|PWM } }, // 2 15 | { .gpio = { GPIOA, GPIO_PIN_11, IN|PU|PD } }, // 3 16 | { .gpio = { GPIOA, GPIO_PIN_12, IN|PU|PD } }, // 4 17 | { .gpio = { GPIOB, GPIO_PIN_6, OUT|PWM } }, // 5 18 | { .gpio = { GPIOB, GPIO_PIN_7, OUT|PWM } }, // 6 19 | { .gpio = { GPIOB, GPIO_PIN_8, OUT|PWM } }, // 7 20 | { .gpio = { GPIOB, GPIO_PIN_9, OUT|PWM } }, // 8 21 | { .gpio = { GPIOB, GPIO_PIN_10, IN|PU|PD } }, // 9 22 | { .gpio = { GPIOB, GPIO_PIN_11, IN|PU|PD } }, // 10 23 | { .gpio = { GPIOB, GPIO_PIN_14, IN|PU|PD } }, // 11 24 | { .gpio = { GPIOB, GPIO_PIN_15, IN|PU|PD } }, // 12 25 | { .gpio = { GPIOC, GPIO_PIN_13, IN|PU|PD } }, // 13 26 | { .gpio = { GPIOA, GPIO_PIN_0, OUT|PWM } }, // 14 27 | { .gpio = { GPIOA, GPIO_PIN_1, OUT|PWM } }, // 15 28 | { .gpio = { GPIOA, GPIO_PIN_6, OUT|PWM } }, // 16 29 | { .gpio = { GPIOA, GPIO_PIN_7, OUT|PWM } }, // 17 30 | { .gpio = { GPIOB, GPIO_PIN_0, OUT|PWM } }, // 18 31 | { .gpio = { GPIOB, GPIO_PIN_1, OUT|PWM } }, // 19 32 | }; 33 | 34 | const int n_pins = sizeof(gpios) / sizeof(gpios[0]); 35 | -------------------------------------------------------------------------------- /STM32_Expander/src/boards/protov1/gpiomap.c: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Mitch Bradley 2 | // Use of this source code is governed by a GPLv3 license that can be found in the LICENSE file. 3 | 4 | #include "pin.h" 5 | 6 | // This table maps io numbers (the table index) to 7 | // device-specific and board-specific pin numbers 8 | 9 | pin_t gpios[] = { 10 | // port num capabilities TIM ch io_num usage PWM 11 | { .gpio = { GPIOB, GPIO_PIN_10, IN | PU | PD, 2, 3 } }, // 0 I0 2-3 12 | { .gpio = { GPIOB, GPIO_PIN_11, IN | PU | PD, 2, 4 } }, // 1 I1 2-4 13 | { .gpio = { GPIOB, GPIO_PIN_14, IN | PU | PD, 1, 2 } }, // 2 I2 1-2N 14 | { .gpio = { GPIOB, GPIO_PIN_15, IN | PU | PD, 1, 3 } }, // 3 I3 1-3N 15 | { .gpio = { GPIOA, GPIO_PIN_4, IN | PU | PD, 0, 0 } }, // 4 I4 x 16 | { .gpio = { GPIOA, GPIO_PIN_5, IN | PU | PD, 0, 0 } }, // 5 I5 x 17 | { .gpio = { GPIOA, GPIO_PIN_11, IN | PU | PD, 1, 4 } }, // 6 I6 1-4 18 | { .gpio = { GPIOA, GPIO_PIN_12, IN | PU | PD, 0, 0 } }, // 7 I7 x 19 | { .gpio = { GPIOA, GPIO_PIN_8, OUT | PWM, 1, 1 } }, // 8 O0 1-1 20 | { .gpio = { GPIOB, GPIO_PIN_6, OUT | PWM, 4, 1 } }, // 9 O1 4-1 21 | { .gpio = { GPIOB, GPIO_PIN_7, OUT | PWM, 4, 2 } }, // 10 O2 4-2 22 | { .gpio = { GPIOB, GPIO_PIN_8, OUT | PWM, 4, 3 } }, // 11 O3 4-3 23 | { .gpio = { GPIOB, GPIO_PIN_9, OUT | PWM, 4, 4 } }, // 12 O4 4-4 24 | { .gpio = { GPIOA, GPIO_PIN_0, OUT | PWM, 2, 1 } }, // 13 O5 2-1 25 | { .gpio = { GPIOA, GPIO_PIN_1, OUT | PWM, 2, 2 } }, // 14 O6 2-2 26 | { .gpio = { GPIOA, GPIO_PIN_6, OUT | PWM, 3, 1 } }, // 15 O7 3-1 27 | { .gpio = { GPIOA, GPIO_PIN_7, OUT | PWM, 3, 2 } }, // 16 FET0 3-2 28 | { .gpio = { GPIOB, GPIO_PIN_0, OUT | PWM, 3, 3 } }, // 17 FET1 3-3 29 | }; 30 | 31 | const int n_pins = sizeof(gpios) / sizeof(gpios[0]); 32 | -------------------------------------------------------------------------------- /STM32_Expander/src/dma_uart.c: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 Mitch Bradley 2 | // Use of this source code is governed by a GPLv3 license that can be found in the LICENSE file. 3 | 4 | // STM32 UART driver using DMA for reception 5 | 6 | #include "gpio_pin.h" // gpio_clock_enable() 7 | #include "dma_uart.h" 8 | #include 9 | 10 | // DMA ring buffers 11 | #define UART1_DMA_LEN 4096 12 | uint8_t uart1_dma_buf[UART1_DMA_LEN]; 13 | 14 | #define UART2_DMA_LEN 4096 15 | uint8_t uart2_dma_buf[UART2_DMA_LEN]; 16 | 17 | typedef struct { 18 | UART_HandleTypeDef huart; 19 | DMA_HandleTypeDef hdma; 20 | int last_dma_count; 21 | int dma_len; 22 | uint8_t* dma_buf; 23 | } dma_uart_t; 24 | 25 | dma_uart_t dma_uarts[2] = { 26 | { .huart = { .Instance = USART1 }, .last_dma_count = UART1_DMA_LEN, .dma_len = UART1_DMA_LEN, .dma_buf = uart1_dma_buf }, 27 | { .huart = { .Instance = USART2 }, .last_dma_count = UART2_DMA_LEN, .dma_len = UART2_DMA_LEN, .dma_buf = uart2_dma_buf }, 28 | }; 29 | 30 | void init_dma_uart(int uart_num, int baud, GPIO_TypeDef* tx_port, uint16_t tx_pin, GPIO_TypeDef* rx_port, uint16_t rx_pin) { 31 | dma_uart_t* dma_uart = &dma_uarts[uart_num]; 32 | 33 | UART_HandleTypeDef* huart = &(dma_uart->huart); 34 | 35 | __HAL_RCC_DMA1_CLK_ENABLE(); 36 | 37 | DMA_HandleTypeDef* hdma = &(dma_uart->hdma); 38 | 39 | switch (uart_num) { 40 | case 0: 41 | __HAL_RCC_USART1_CLK_ENABLE(); 42 | hdma->Instance = DMA1_Channel5; 43 | HAL_NVIC_SetPriority(DMA1_Channel5_IRQn, 0, 0); 44 | HAL_NVIC_EnableIRQ(DMA1_Channel5_IRQn); 45 | break; 46 | case 1: 47 | __HAL_RCC_USART2_CLK_ENABLE(); 48 | hdma->Instance = DMA1_Channel6; 49 | HAL_NVIC_SetPriority(DMA1_Channel6_IRQn, 0, 0); 50 | HAL_NVIC_EnableIRQ(DMA1_Channel6_IRQn); 51 | break; 52 | default: 53 | return; 54 | } 55 | 56 | gpio_clock_enable(tx_port); 57 | gpio_clock_enable(rx_port); 58 | 59 | GPIO_InitTypeDef gpiomode; 60 | 61 | gpiomode.Pin = tx_pin; 62 | gpiomode.Mode = GPIO_MODE_AF_PP; 63 | gpiomode.Speed = GPIO_SPEED_FREQ_HIGH; 64 | HAL_GPIO_Init(tx_port, &gpiomode); 65 | 66 | gpiomode.Pin = rx_pin; 67 | gpiomode.Mode = GPIO_MODE_INPUT; 68 | gpiomode.Pull = GPIO_NOPULL; 69 | HAL_GPIO_Init(rx_port, &gpiomode); 70 | 71 | huart->Init.BaudRate = baud; 72 | huart->Init.WordLength = UART_WORDLENGTH_8B; 73 | huart->Init.StopBits = UART_STOPBITS_1; 74 | huart->Init.Parity = UART_PARITY_NONE; 75 | huart->Init.Mode = UART_MODE_TX_RX; 76 | huart->Init.HwFlowCtl = UART_HWCONTROL_NONE; 77 | huart->Init.OverSampling = UART_OVERSAMPLING_16; 78 | if (HAL_UART_Init(huart) != HAL_OK) { 79 | return; 80 | } 81 | 82 | hdma->Init.Direction = DMA_PERIPH_TO_MEMORY; 83 | hdma->Init.PeriphInc = DMA_PINC_DISABLE; 84 | hdma->Init.MemInc = DMA_MINC_ENABLE; 85 | hdma->Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; 86 | hdma->Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; 87 | hdma->Init.Mode = DMA_CIRCULAR; 88 | hdma->Init.Priority = DMA_PRIORITY_LOW; 89 | if (HAL_DMA_Init(hdma) != HAL_OK) { 90 | return; 91 | } 92 | 93 | // This is an expansion of __HAL_LINKDMA that takes a dma handle pointer 94 | huart->hdmarx = hdma; 95 | hdma->Parent = huart; 96 | // __HAL_LINKDMA(huart, hdmarx, hdma); 97 | 98 | dma_uart->last_dma_count = dma_uart->dma_len; 99 | HAL_UART_Receive_DMA(huart, dma_uart->dma_buf, dma_uart->dma_len); 100 | } 101 | 102 | void dma_print(int uart_num, const char* msg) { 103 | HAL_UART_Transmit(&(dma_uarts[uart_num].huart), (uint8_t*)msg, strlen(msg), 1000); 104 | } 105 | void dma_putchar(int uart_num, uint8_t c) { 106 | HAL_UART_Transmit(&(dma_uarts[uart_num].huart), &c, 1, HAL_MAX_DELAY); 107 | } 108 | int dma_getchar(int uart_num) { 109 | dma_uart_t* dma_uart = &dma_uarts[uart_num]; 110 | // The DMA-mode HAL UART driver receives data to a ring buffer. 111 | // We chase the buffer pointer and pull out the data. 112 | int last = dma_uart->last_dma_count; 113 | int this = __HAL_DMA_GET_COUNTER(dma_uart->huart.hdmarx); 114 | int count = last - this; 115 | if (count < 0) { 116 | count += dma_uart->dma_len; 117 | } 118 | if (count) { 119 | uint8_t c = dma_uart->dma_buf[dma_uart->dma_len - dma_uart->last_dma_count]; 120 | --dma_uart->last_dma_count; 121 | if (dma_uart->last_dma_count < 0) { 122 | dma_uart->last_dma_count += dma_uart->dma_len; 123 | } 124 | return c; 125 | } 126 | return -1; 127 | } 128 | 129 | void DMA1_Channel5_IRQHandler(void) { 130 | HAL_DMA_IRQHandler(&(dma_uarts[0].hdma)); 131 | } 132 | 133 | void DMA1_Channel6_IRQHandler(void) { 134 | HAL_DMA_IRQHandler(&(dma_uarts[1].hdma)); 135 | } 136 | -------------------------------------------------------------------------------- /STM32_Expander/src/dma_uart.h: -------------------------------------------------------------------------------- 1 | #include "stm32f1xx_hal.h" 2 | #include 3 | 4 | void init_dma_uart(int uart_num, int baud, GPIO_TypeDef* tx_port, uint16_t tx_pin, GPIO_TypeDef* rx_port, uint16_t rx_pin); 5 | void dma_print(int uart_num, const char* msg); 6 | void dma_putchar(int uart_num, uint8_t c); 7 | int dma_getchar(int uart_num); 8 | -------------------------------------------------------------------------------- /STM32_Expander/src/gpio_pin.c: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Mitch Bradley 2 | // Use of this source code is governed by a GPLv3 license that can be found in the LICENSE file. 3 | 4 | // This file implements the low-level interface to GPIO pins that is used by 5 | // the intermediate-level interface defined in lib/Expander/src/pin.{c,h} 6 | // The intention is to encapsulate the platform-dependent GPIO API as tightly 7 | // as possible. 8 | // This implementation is for the STM32 HAL driver. 9 | 10 | #include "gpio_pin.h" 11 | #include "pwm_pin.h" 12 | #include "gpiomap.h" 13 | 14 | int set_gpio(gpio_pin_t* gpio, bool high) { 15 | GPIO_PinState pinstate = high ? GPIO_PIN_SET : GPIO_PIN_RESET; 16 | HAL_GPIO_WritePin(gpio->port, gpio->pin_num, pinstate); 17 | return true; 18 | } 19 | bool get_gpio(gpio_pin_t* gpio) { 20 | GPIO_PinState pinval = HAL_GPIO_ReadPin(gpio->port, gpio->pin_num); 21 | return pinval == GPIO_PIN_SET; 22 | } 23 | int set_pwm(gpio_pin_t* gpio, int32_t numerator, uint32_t denominator) { 24 | PWM_Duty(gpio, numerator); 25 | return true; 26 | } 27 | void deinit_gpio(gpio_pin_t* gpio) { 28 | HAL_GPIO_DeInit(gpio->port, gpio->pin_num); 29 | } 30 | bool set_gpio_mode(gpio_pin_t* gpio, pin_mode_t pinmode) { 31 | GPIO_InitTypeDef gpiomode; 32 | gpiomode.Pin = gpio->pin_num; 33 | gpiomode.Speed = GPIO_SPEED_FREQ_HIGH; 34 | 35 | if (pinmode & PIN_OUTPUT) { 36 | if (!(gpio->capabilities & OUT)) { 37 | return false; 38 | } 39 | gpiomode.Mode = GPIO_MODE_OUTPUT_PP; 40 | gpiomode.Pull = GPIO_NOPULL; 41 | HAL_GPIO_Init(gpio->port, &gpiomode); 42 | 43 | // The initial state of an output pin is its inactive state 44 | GPIO_PinState pinstate = (pinmode & PIN_ACTIVELOW) ? GPIO_PIN_SET : GPIO_PIN_RESET; 45 | HAL_GPIO_WritePin(gpio->port, gpio->pin_num, pinstate); 46 | return true; 47 | } 48 | if (pinmode & PIN_PWM) { 49 | if (!(gpio->capabilities & PWM)) { 50 | return false; 51 | } 52 | return PWM_Init(gpio, pinmode >> PIN_FREQ_SHIFT, pinmode & PIN_ACTIVELOW); 53 | // gpiomode.Pull = GPIO_NOPULL; 54 | // gpiomode.Mode = GPIO_MODE_ANALOG; 55 | // HAL_GPIO_Init(gpio->port, &gpiomode); 56 | } 57 | if (pinmode & PIN_INPUT) { 58 | if (!(gpio->capabilities & IN)) { 59 | return false; 60 | } 61 | gpiomode.Mode = GPIO_MODE_INPUT; 62 | if (pinmode & PIN_PULLUP) { 63 | if (!(gpio->capabilities & PU)) { 64 | return false; 65 | } 66 | gpiomode.Pull = GPIO_PULLUP; 67 | } else if (pinmode & PIN_PULLDOWN) { 68 | if (!(gpio->capabilities & PD)) { 69 | return false; 70 | } 71 | gpiomode.Pull = GPIO_PULLDOWN; 72 | } else { 73 | gpiomode.Pull = GPIO_NOPULL; 74 | } 75 | HAL_GPIO_Init(gpio->port, &gpiomode); 76 | 77 | // attachInterrupt(digitalPinToInterrupt(stm_pin_num), pin_interrupt, CHANGE); 78 | return true; 79 | } 80 | return false; 81 | } 82 | void gpio_clock_enable(GPIO_TypeDef* port) { 83 | if (port == GPIOA) { 84 | __HAL_RCC_GPIOA_CLK_ENABLE(); 85 | } else if (port == GPIOB) { 86 | __HAL_RCC_GPIOB_CLK_ENABLE(); 87 | } else if (port == GPIOC) { 88 | __HAL_RCC_GPIOC_CLK_ENABLE(); 89 | } else if (port == GPIOD) { 90 | __HAL_RCC_GPIOD_CLK_ENABLE(); 91 | } 92 | } 93 | 94 | void init_gpio(gpio_pin_t* gpio) { 95 | gpio_clock_enable(gpio->port); 96 | if (gpio->capabilities & OUT) { 97 | set_gpio_mode(gpio, PIN_OUTPUT); 98 | } else if (gpio->capabilities & IN) { 99 | set_gpio_mode(gpio, PIN_INPUT); 100 | } 101 | } 102 | void init_from_gpiomap() { 103 | for (int i = 0; i < n_pins; i++) { 104 | gpio_pin_t* gpio = &(gpios[i].gpio); 105 | if (gpio->capabilities & (IN | OUT)) { 106 | init_gpio(gpio); 107 | } 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /STM32_Expander/src/gpio_pin.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Mitch Bradley 2 | // Use of this source code is governed by a GPLv3 license that can be found in the LICENSE file. 3 | 4 | #pragma once 5 | #include 6 | #include "pinmode.h" 7 | #include "stm32f1xx_hal.h" 8 | 9 | // The internals of this struct are MCU-specific 10 | typedef struct { 11 | // Implementation for STM32 HAL 12 | GPIO_TypeDef* port; 13 | uint16_t pin_num; 14 | uint8_t capabilities; 15 | uint8_t timer_num; 16 | uint8_t timer_channel; 17 | } gpio_pin_t; 18 | 19 | // This API is MCU-independent 20 | int set_gpio(gpio_pin_t* gpio, bool high); 21 | bool get_gpio(gpio_pin_t* gpio); 22 | int set_pwm(gpio_pin_t* gpio, int32_t numerator, uint32_t denominator); 23 | void deinit_gpio(gpio_pin_t* gpio); 24 | void deinit_pwm(gpio_pin_t* gpio); 25 | bool set_gpio_mode(gpio_pin_t* gpio, pin_mode_t pinmode); 26 | void init_gpio(gpio_pin_t* gpio); 27 | void gpio_clock_enable(GPIO_TypeDef* port); 28 | void init_from_gpiomap(); 29 | -------------------------------------------------------------------------------- /STM32_Expander/src/gpiomap.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Mitch Bradley 2 | // Use of this source code is governed by a GPLv3 license that can be found in the LICENSE file. 3 | 4 | #pragma once 5 | 6 | #include "pin.h" 7 | 8 | extern pin_t gpios[]; 9 | 10 | extern const int n_pins; 11 | 12 | extern const char* fw_version; 13 | extern const char* board_name; 14 | 15 | void ready(); 16 | -------------------------------------------------------------------------------- /STM32_Expander/src/pwm_pin.c: -------------------------------------------------------------------------------- 1 | #include "pin.h" 2 | #include "gpiomap.h" 3 | 4 | #define MAX_TIMER_NUM 4 5 | TIM_HandleTypeDef timer_handles[MAX_TIMER_NUM + 1]; 6 | TIM_TypeDef* timers[] = { 0, TIM1, TIM2, TIM3, TIM4 }; 7 | uint32_t timer_channels[] = { 0, TIM_CHANNEL_1, TIM_CHANNEL_2, TIM_CHANNEL_3, TIM_CHANNEL_4 }; 8 | uint16_t timer_divisors[MAX_TIMER_NUM + 1] = { 0 }; 9 | 10 | #define TIMER_CLOCK 60000000 11 | #define TIMER_RESOLUTION 999 12 | 13 | bool Timer_Init(int timer_num, int frequency) { 14 | if (timer_num < 1 || timer_num > 4) { 15 | return false; 16 | } 17 | 18 | switch (timer_num) { 19 | case 1: 20 | __HAL_RCC_TIM1_CLK_ENABLE(); 21 | break; 22 | case 2: 23 | __HAL_RCC_TIM2_CLK_ENABLE(); 24 | break; 25 | case 3: 26 | __HAL_RCC_TIM3_CLK_ENABLE(); 27 | break; 28 | case 4: 29 | __HAL_RCC_TIM4_CLK_ENABLE(); 30 | break; 31 | default: 32 | return false; 33 | } 34 | 35 | TIM_ClockConfigTypeDef sClockSourceConfig = { 0 }; 36 | TIM_MasterConfigTypeDef sMasterConfig = { 0 }; 37 | 38 | uint32_t max_frequency = TIMER_CLOCK / TIMER_RESOLUTION; 39 | uint32_t divisor = max_frequency / frequency; 40 | 41 | if (divisor == 0) { 42 | divisor = 1; 43 | } 44 | uint32_t existing_divisor = timer_divisors[timer_num]; 45 | if (existing_divisor != 0) { // This TIM is already configured 46 | // If the requested divisor is the same as the existing one, 47 | // we can just use the existing setup for this timer. 48 | // Otherwise we fail due to conflicting divisors for 49 | // different channels 50 | return existing_divisor == divisor; 51 | } 52 | 53 | TIM_HandleTypeDef* handle = &timer_handles[timer_num]; 54 | 55 | handle->Instance = timers[timer_num]; 56 | handle->Init.Prescaler = divisor - 1; 57 | handle->Init.CounterMode = TIM_COUNTERMODE_UP; 58 | handle->Init.Period = TIMER_RESOLUTION; 59 | handle->Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; 60 | handle->Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE; 61 | if (HAL_TIM_Base_Init(handle) != HAL_OK) { 62 | return false; 63 | } 64 | sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; 65 | if (HAL_TIM_ConfigClockSource(handle, &sClockSourceConfig) != HAL_OK) { 66 | return false; 67 | } 68 | if (HAL_TIM_PWM_Init(handle) != HAL_OK) { 69 | return false; 70 | } 71 | sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; 72 | sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; 73 | if (HAL_TIMEx_MasterConfigSynchronization(handle, &sMasterConfig) != HAL_OK) { 74 | return false; 75 | } 76 | timer_divisors[timer_num] = divisor; 77 | return true; 78 | } 79 | bool PWM_Init(gpio_pin_t* gpio, uint32_t frequency, bool invert) { 80 | uint8_t timer_num = gpio->timer_num; 81 | if (!Timer_Init(timer_num, frequency)) { 82 | return false; 83 | } 84 | uint32_t channel = timer_channels[gpio->timer_channel]; 85 | TIM_HandleTypeDef* handle = &timer_handles[timer_num]; 86 | 87 | HAL_TIM_PWM_Stop(handle, channel); 88 | 89 | TIM_OC_InitTypeDef sConfigOC = { 0 }; 90 | 91 | sConfigOC.OCMode = TIM_OCMODE_PWM1; 92 | sConfigOC.Pulse = 0; 93 | sConfigOC.OCPolarity = invert ? TIM_OCPOLARITY_LOW : TIM_OCPOLARITY_HIGH; 94 | sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; 95 | if (HAL_TIM_PWM_ConfigChannel(handle, &sConfigOC, channel) != HAL_OK) { 96 | return false; 97 | } 98 | 99 | GPIO_TypeDef* port = gpio->port; 100 | if (port == GPIOA) { 101 | __HAL_RCC_GPIOA_CLK_ENABLE(); 102 | } else if (port == GPIOB) { 103 | __HAL_RCC_GPIOB_CLK_ENABLE(); 104 | } else if (port == GPIOC) { 105 | __HAL_RCC_GPIOC_CLK_ENABLE(); 106 | } else if (port == GPIOD) { 107 | __HAL_RCC_GPIOD_CLK_ENABLE(); 108 | } else if (port == GPIOE) { 109 | __HAL_RCC_GPIOE_CLK_ENABLE(); 110 | } else { 111 | return false; 112 | } 113 | 114 | GPIO_InitTypeDef GPIO_InitStruct = { 0 }; 115 | GPIO_InitStruct.Pin = gpio->pin_num; 116 | GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; 117 | GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; 118 | HAL_GPIO_Init(port, &GPIO_InitStruct); 119 | 120 | return HAL_TIM_PWM_Start(handle, channel) == HAL_OK; 121 | } 122 | void deinit_pwm(gpio_pin_t* gpio) { 123 | uint8_t timer_num = gpio->timer_num; 124 | timer_divisors[timer_num] = 0; 125 | uint32_t channel = timer_channels[gpio->timer_channel]; 126 | TIM_HandleTypeDef* handle = &timer_handles[timer_num]; 127 | HAL_TIM_PWM_Stop(handle, channel); 128 | } 129 | 130 | void PWM_Duty(gpio_pin_t* gpio, uint32_t duty) { 131 | uint8_t timer_num = gpio->timer_num; 132 | TIM_HandleTypeDef* handle = &timer_handles[timer_num]; 133 | switch (gpio->timer_channel) { 134 | case 1: 135 | handle->Instance->CCR1 = duty; 136 | break; 137 | case 2: 138 | handle->Instance->CCR2 = duty; 139 | break; 140 | case 3: 141 | handle->Instance->CCR3 = duty; 142 | break; 143 | case 4: 144 | handle->Instance->CCR4 = duty; 145 | break; 146 | } 147 | } 148 | -------------------------------------------------------------------------------- /STM32_Expander/src/pwm_pin.h: -------------------------------------------------------------------------------- 1 | #include "pin.h" 2 | bool PWM_Init(gpio_pin_t* gpio, uint32_t frequency, bool invert); 3 | void PWM_Duty(gpio_pin_t* gpio, uint32_t duty); 4 | -------------------------------------------------------------------------------- /STM32_Expander/src/system.c: -------------------------------------------------------------------------------- 1 | #include "stm32f1xx_hal.h" 2 | 3 | void Error_Handler(void) { 4 | __disable_irq(); 5 | while (1) {} 6 | } 7 | 8 | void HAL_MspInit(void) { 9 | __HAL_RCC_AFIO_CLK_ENABLE(); 10 | __HAL_RCC_PWR_CLK_ENABLE(); 11 | 12 | __HAL_AFIO_REMAP_SWJ_NOJTAG(); 13 | } 14 | 15 | /** 16 | * @brief System Clock Configuration 17 | * @retval None 18 | */ 19 | void SystemClock_Config(void) { 20 | RCC_OscInitTypeDef RCC_OscInitStruct = { 0 }; 21 | RCC_ClkInitTypeDef RCC_ClkInitStruct = { 0 }; 22 | 23 | /** Initializes the RCC Oscillators according to the specified parameters 24 | * in the RCC_OscInitTypeDef structure. 25 | */ 26 | RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI; 27 | RCC_OscInitStruct.HSIState = RCC_HSI_ON; 28 | RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; 29 | RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; 30 | RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI_DIV2; 31 | RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL15; 32 | if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { 33 | Error_Handler(); 34 | } 35 | 36 | /** Initializes the CPU, AHB and APB buses clocks 37 | */ 38 | RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2; 39 | RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; 40 | RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; 41 | RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; 42 | RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; 43 | 44 | if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK) { 45 | Error_Handler(); 46 | } 47 | } 48 | 49 | void NMI_Handler(void) { 50 | while (1) {} 51 | } 52 | void HardFault_Handler(void) { 53 | while (1) {} 54 | } 55 | void MemManage_Handler(void) { 56 | while (1) {} 57 | } 58 | void BusFault_Handler(void) { 59 | while (1) {} 60 | } 61 | void UsageFault_Handler(void) { 62 | while (1) {} 63 | } 64 | void SVC_Handler(void) {} 65 | void DebugMon_Handler(void) {} 66 | void PendSV_Handler(void) {} 67 | void SysTick_Handler(void) { 68 | HAL_IncTick(); 69 | } 70 | -------------------------------------------------------------------------------- /STM32_Expander/src/system.h: -------------------------------------------------------------------------------- 1 | void HAL_MspInit(void); 2 | void Error_Handler(void); 3 | void SystemClock_Config(void); 4 | -------------------------------------------------------------------------------- /STM32_Expander/src/version.c: -------------------------------------------------------------------------------- 1 | const char* fw_version = "v1.0"; 2 | -------------------------------------------------------------------------------- /lib/.clang-format: -------------------------------------------------------------------------------- 1 | --- 2 | AccessModifierOffset: '-4' 3 | AlignAfterOpenBracket: Align 4 | AlignConsecutiveAssignments: 'true' 5 | AlignConsecutiveDeclarations: 'true' 6 | AlignEscapedNewlines: Right 7 | AlignOperands: 'true' 8 | AlignTrailingComments: 'true' 9 | AllowShortBlocksOnASingleLine: 'true' 10 | AllowShortCaseLabelsOnASingleLine: 'false' 11 | AllowShortFunctionsOnASingleLine: Inline 12 | AllowShortIfStatementsOnASingleLine: 'false' 13 | AllowShortLoopsOnASingleLine: 'false' 14 | AlwaysBreakBeforeMultilineStrings: 'false' 15 | AlwaysBreakTemplateDeclarations: 'true' 16 | BinPackArguments: 'false' 17 | BinPackParameters: 'false' 18 | BreakBeforeBinaryOperators: None 19 | BraceWrapping: 20 | AfterClass: 'true' 21 | AfterControlStatement: 'true' 22 | AfterEnum: 'true' 23 | AfterFunction: 'true' 24 | AfterNamespace: 'true' 25 | AfterObjCDeclaration: 'true' 26 | AfterStruct: 'true' 27 | AfterUnion: 'true' 28 | AfterExternBlock: 'true' 29 | BeforeCatch: 'true' 30 | BeforeElse: 'true' 31 | SplitEmptyFunction: 'false' 32 | SplitEmptyRecord: 'false' 33 | SplitEmptyNamespace: 'false' 34 | BreakBeforeInheritanceComma: 'true' 35 | BreakBeforeTernaryOperators: 'false' 36 | BreakConstructorInitializers: AfterColon 37 | BreakInheritanceList: AfterColon 38 | ColumnLimit: '140' 39 | CommentPragmas: '^ :: ' 40 | CompactNamespaces: 'false' 41 | Cpp11BracedListStyle: 'false' 42 | FixNamespaceComments: 'false' 43 | IncludeCategories: 44 | - Regex: '^".*' 45 | Priority: 1 46 | - Regex: '^"(.*)/' 47 | Priority: 2 48 | - Regex: '^<(.*)/' 49 | Priority: 3 50 | - Regex: '.*' 51 | Priority: 4 52 | IncludeBlocks: Regroup 53 | IndentCaseLabels: 'true' 54 | IndentPPDirectives: AfterHash 55 | IndentWidth: '4' 56 | IndentWrappedFunctionNames: 'true' 57 | JavaScriptQuotes: Leave 58 | KeepEmptyLinesAtTheStartOfBlocks: 'false' 59 | Language: Cpp 60 | MaxEmptyLinesToKeep: '1' 61 | NamespaceIndentation: All 62 | PenaltyBreakBeforeFirstCallParameter: 7 63 | PenaltyBreakAssignment: 8 64 | PenaltyBreakComment: 200 65 | PenaltyBreakFirstLessLess: 50 66 | PenaltyBreakString: 100 67 | PenaltyBreakTemplateDeclaration: 10 68 | PenaltyExcessCharacter: 10 69 | PenaltyReturnTypeOnItsOwnLine: 1000000 70 | PointerAlignment: Left 71 | ReflowComments: 'false' 72 | SortIncludes: 'false' 73 | SortUsingDeclarations: 'true' 74 | SpaceAfterTemplateKeyword: 'true' 75 | SpaceBeforeAssignmentOperators: 'true' 76 | SpaceBeforeCpp11BracedList: 'true' 77 | SpaceBeforeCtorInitializerColon: 'true' 78 | SpaceBeforeInheritanceColon: 'true' 79 | SpaceBeforeParens: ControlStatements 80 | SpaceBeforeRangeBasedForLoopColon: 'true' 81 | SpaceInEmptyParentheses: 'false' 82 | SpacesBeforeTrailingComments: '2' 83 | SpacesInAngles: 'false' 84 | SpacesInCStyleCastParentheses: 'false' 85 | SpacesInContainerLiterals: 'false' 86 | SpacesInParentheses: 'false' 87 | SpacesInSquareBrackets: 'false' 88 | Standard: Cpp11 89 | TabWidth: '4' 90 | UseTab: Never 91 | 92 | ... 93 | -------------------------------------------------------------------------------- /lib/Expander/src/Expander.c: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Mitch Bradley 2 | // Use of this source code is governed by a GPLv3 license that can be found in the LICENSE file. 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include "pin.h" 10 | 11 | #ifdef __cplusplus 12 | extern "C" { 13 | #endif 14 | 15 | // The integer value for 16 | // pin low reports is 0x100 to 0x13f, and for 17 | // pin high reports is 0x140 to 0x17f 18 | // In UTF8, 0x100 to 0x13f encodes to 0xC4 0x80+N 19 | // and 0x140 to 0x17f encodes to 0xC5 0x80+N 20 | const uint8_t PinLowUTF8Prefix = 0xC4; 21 | const uint8_t PinHighUTF8Prefix = 0xC5; 22 | 23 | void expander_start() { 24 | fnc_realtime(RST); 25 | } 26 | 27 | // With no arguments, return an ACK for okay 28 | void expander_ack() { 29 | fnc_realtime(ACK); 30 | } 31 | 32 | void expander_nak(const char* msg) { 33 | debug_print("[MSG:ERR: "); 34 | debug_print(msg); 35 | debug_println("]"); 36 | fnc_realtime(NAK); 37 | } 38 | 39 | void expander_pin_msg(uint8_t pin_num, bool active) { 40 | // UTF8 encoding 41 | fnc_putchar(active ? PinHighUTF8Prefix : PinLowUTF8Prefix); 42 | fnc_putchar(0x80 + pin_num); 43 | } 44 | 45 | pin_mode_t parse_io_mode(char* params) { 46 | pin_mode_t mode = 0; 47 | for (char* rest; *params; params = rest) { 48 | split(params, &rest, ','); 49 | if (strcasecmp(params, "low") == 0) { 50 | mode |= PIN_ACTIVELOW; 51 | continue; 52 | } 53 | if (strcasecmp(params, "out") == 0) { 54 | mode |= PIN_OUTPUT; 55 | continue; 56 | } 57 | if (strcasecmp(params, "in") == 0) { 58 | mode |= PIN_INPUT; 59 | continue; 60 | } 61 | if (strcasecmp(params, "pwm") == 0) { 62 | mode |= PIN_PWM; 63 | continue; 64 | } 65 | if (strcasecmp(params, "pu") == 0) { 66 | mode |= PIN_PULLUP; 67 | continue; 68 | } 69 | if (strcasecmp(params, "pd") == 0) { 70 | mode |= PIN_PULLDOWN; 71 | continue; 72 | } 73 | if (strncasecmp(params, "frequency=", strlen("frequency=")) == 0) { 74 | int freq = atoi(params + strlen("frequency=")); 75 | mode |= freq << PIN_FREQ_SHIFT; 76 | continue; 77 | } 78 | } 79 | return mode; 80 | } 81 | 82 | static void trim(char** str) { 83 | char* s = *str; 84 | while (isspace(*s)) { 85 | ++s; 86 | } 87 | char* p = s + strlen(s); 88 | while (p != s && isspace(p[-1])) { 89 | --p; 90 | } 91 | *p = '\0'; 92 | *str = s; 93 | } 94 | 95 | static void expander_ack_nak(bool okay, const char* errmsg) { 96 | if (okay) { 97 | expander_ack(); 98 | } else { 99 | expander_nak(errmsg); 100 | } 101 | } 102 | 103 | void expander_feedback(const char* msg, int timeout_ms) { 104 | char line[128] = "(EXP,"; 105 | strcat(line, msg); 106 | strcat(line, ")"); 107 | fnc_send_line(line, timeout_ms); 108 | } 109 | 110 | void expander_report_info() { 111 | char msg[120] = "BOARD:"; 112 | strcat(msg, board_name); 113 | strcat(msg, ",FW:"); 114 | strcat(msg, fw_version); 115 | expander_feedback(msg, 10); 116 | } 117 | 118 | #define PinLowFirst 0x100 119 | #define PinLowLast 0x13f 120 | #define PinHighFirst 0x140 121 | #define PinHighLast 0x17f 122 | #define SetPWM 0x10000 123 | void handle_extended_command(uint32_t cmd) { 124 | uint32_t value; 125 | int pin_num; 126 | if (cmd >= SetPWM) { 127 | value = cmd - SetPWM; 128 | pin_num = value >> 10; 129 | value = value & 0x3ff; 130 | } else if (cmd >= PinLowFirst && cmd < PinLowLast) { 131 | value = 0; 132 | pin_num = cmd - PinLowFirst; 133 | } else if (cmd >= PinHighFirst && cmd < PinHighLast) { 134 | value = 1; 135 | pin_num = cmd - PinHighFirst; 136 | } else { 137 | return; 138 | } 139 | int fail = set_output(pin_num, value, 1000); 140 | if (fail) { 141 | expander_nak("Cannot set output"); 142 | } 143 | } 144 | 145 | bool expander_handle_command(char* command) { 146 | size_t len = strlen(command); 147 | if (!len) { 148 | return false; 149 | } 150 | if (strcmp(command, "[MSG:RST]") == 0) { 151 | expander_rst(); 152 | return false; // This message is not specific to the expander 153 | } 154 | 155 | if (command[len - 1] != ']') { 156 | return false; 157 | } 158 | 159 | // EXP operation examples: 160 | // [EXP: io.N=out,low] 161 | // [EXP: io.N=inp,pu] 162 | // [EXP: io.N=pwm] 163 | if (strncmp(command, "[EXP:", 5) != 0) { 164 | return false; 165 | } 166 | // Now we know that the command is for the expander so it is okay to modify the string 167 | command[len - 1] = '\0'; 168 | 169 | char* pinspec; 170 | split(command, &pinspec, ':'); 171 | 172 | if (strcmp(pinspec, "ID") == 0) { 173 | expander_report_info(); 174 | } 175 | 176 | char* params; 177 | split(pinspec, ¶ms, '='); 178 | 179 | trim(&pinspec); // Remove leading and trailing blanks 180 | trim(¶ms); // Remove leading and trailing blanks 181 | 182 | size_t prefixlen = strlen("io."); 183 | if (strncmp(pinspec, "io.", prefixlen) != 0) { 184 | expander_nak("Missing io. specifier"); 185 | return true; 186 | } 187 | 188 | char* pin_str = pinspec + prefixlen; 189 | int pin_num = atoi(pin_str); // Will be 0 if pin_str is "*" 190 | 191 | bool res = expander_ini(pin_num, parse_io_mode(params)); 192 | expander_ack_nak(res, "EXP Error"); 193 | if (res) { 194 | expander_get(pin_num); 195 | } 196 | return true; 197 | } 198 | 199 | // Implement these to handle expander IO messages 200 | bool __attribute__((weak)) expander_rst() { 201 | deinit_all_pins(); 202 | return true; 203 | } 204 | bool __attribute__((weak)) expander_ini(uint8_t pin_num, pin_mode_t pinmode) { 205 | int fail = set_pin_mode(pin_num, pinmode); 206 | return fail == fail_none; 207 | } 208 | bool __attribute__((weak)) expander_get_all() { 209 | update_all_pins(); 210 | read_all_pins(expander_pin_msg); 211 | return true; 212 | } 213 | bool __attribute__((weak)) expander_get(uint8_t pin_num) { 214 | read_pin(expander_pin_msg, pin_num); 215 | return true; 216 | } 217 | bool __attribute__((weak)) expander_set(uint8_t pin_num, int32_t numerator, uint32_t denominator) { 218 | return set_output(pin_num, numerator, denominator) == fail_none; 219 | } 220 | 221 | void __attribute__((weak)) expander_poll() { 222 | read_all_pins(expander_pin_msg); 223 | } 224 | 225 | #ifdef __cplusplus 226 | } 227 | #endif 228 | -------------------------------------------------------------------------------- /lib/Expander/src/Expander.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Mitch Bradley 2 | // Use of this source code is governed by a GPLv3 license that can be found in the LICENSE file. 3 | 4 | #pragma once 5 | 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | 10 | #include "GrblParserC.h" 11 | #include "pinmode.h" 12 | 13 | // IO expander API 14 | 15 | // expander_handle_command() handles IO Expander MSG: messages. 16 | // The app must call it from the implementation of handle_msg() 17 | extern bool expander_handle_command(char* command); 18 | 19 | // expander_poll() checks for GPIO input pin changes 20 | // The app must call it from poll_extra() unless GPIO changes 21 | // are handled via interrupts 22 | extern void expander_poll(); 23 | 24 | // The following are called when IO Expander messages are parsed. 25 | // Normally these are automatically implemented to refer to pin functions, 26 | // but they are weak definitions so the app can override them if necessary. 27 | 28 | // MSG:RST 29 | extern bool expander_rst(); 30 | 31 | // MSG:EXP io.n=mode 32 | extern bool expander_ini(uint8_t pin_num, pin_mode_t pinmode); 33 | 34 | // Automatic 35 | extern bool expander_get(uint8_t pin_num); 36 | 37 | // Invoked by Realtime code 38 | extern bool expander_set(uint8_t pin_num, int32_t numerator, uint32_t denominator); 39 | 40 | extern void expander_start(); 41 | 42 | extern void expander_report_info(); 43 | 44 | extern const char* fw_version; 45 | extern const char* board_name; 46 | 47 | #ifdef __cplusplus 48 | } 49 | #endif 50 | -------------------------------------------------------------------------------- /lib/Expander/src/pin.c: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Mitch Bradley 2 | // Use of this source code is governed by a GPLv3 license that can be found in the LICENSE file. 3 | 4 | #include "pin.h" 5 | #include "gpiomap.h" 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | extern int milliseconds(); 12 | 13 | static int pin_limit = 0; 14 | 15 | void init_pin(uint8_t pin_num) { 16 | if (pin_num >= n_pins) { 17 | return; 18 | } 19 | pin_t* pin = &gpios[pin_num]; 20 | pin->initialized = false; 21 | pin->active_low = false; 22 | pin->type = pin_type_none; 23 | pin->last_value = -1; // unknown 24 | pin->debounce_ms = 100; // default 25 | pin->last_change_millis = 0; 26 | } 27 | 28 | int set_output(uint8_t pin_num, int32_t numerator, uint32_t denominator) { 29 | if (pin_num >= n_pins) { 30 | return fail_invalid_pin; 31 | } 32 | pin_t* pin = &gpios[pin_num]; 33 | if (!pin->initialized) { 34 | return fail_not_initialized; 35 | } 36 | 37 | if (pin->type == pin_type_output) { 38 | bool is_high = (numerator != 0) ^ pin->active_low; 39 | set_gpio(&pin->gpio, is_high); 40 | return fail_none; 41 | } 42 | if (pin->type == pin_type_PWM) { 43 | if (numerator < 0 || (uint32_t)numerator > denominator) { 44 | return fail_range; 45 | } 46 | set_pwm(&pin->gpio, numerator, denominator); 47 | return fail_none; 48 | } 49 | return fail_not_capable; 50 | } 51 | 52 | bool pin_changed(uint8_t pin_num) { // return true if value has changed 53 | if (pin_num >= n_pins) { 54 | return false; 55 | } 56 | pin_t* pin = &gpios[pin_num]; 57 | 58 | if (pin->type != pin_type_input) { 59 | return false; 60 | } 61 | 62 | int new_value = get_gpio(&pin->gpio) ^ pin->active_low; 63 | 64 | if (new_value != pin->last_value) { 65 | if ((int)(milliseconds() - pin->last_change_millis) > (int)pin->debounce_ms) { 66 | pin->last_value = new_value; 67 | pin->last_change_millis = milliseconds(); // maybe use for debouncing 68 | return true; 69 | } 70 | } 71 | 72 | return false; 73 | } 74 | void force_pin_update(uint8_t pin_num) { 75 | if (pin_num >= n_pins) { 76 | return; 77 | } 78 | pin_t* pin = &gpios[pin_num]; 79 | pin->last_value = -1; 80 | } 81 | void deinit_pin(uint8_t pin_num) { 82 | if (pin_num >= n_pins) { 83 | return; 84 | } 85 | pin_t* pin = &gpios[pin_num]; 86 | if (pin->initialized) { 87 | if (pin->type == pin_type_PWM) { 88 | deinit_pwm(&pin->gpio); 89 | } else { 90 | deinit_gpio(&pin->gpio); 91 | } 92 | pin->initialized = false; 93 | pin->active_low = false; 94 | pin->type = pin_type_none; 95 | pin->last_value = -1; // unknown 96 | pin->debounce_ms = 100; // default 97 | pin->last_change_millis = 0; 98 | } 99 | } 100 | 101 | int set_pin_mode(uint8_t pin_num, pin_mode_t pinmode) { 102 | if (pin_num >= n_pins) { 103 | return fail_invalid_pin; 104 | } 105 | pin_t* pin = &gpios[pin_num]; 106 | 107 | // for now we assume all pins can input and output. Some can do PWM 108 | 109 | pin->active_low = pinmode & PIN_ACTIVELOW; 110 | 111 | if (pinmode & PIN_PWM) { 112 | pin->type = pin_type_PWM; 113 | } else if (pinmode & PIN_OUTPUT) { 114 | pin->type = pin_type_output; 115 | } else if (pinmode & PIN_INPUT) { 116 | pin->last_value = -1; // reset to unknown value 117 | pin->type = pin_type_input; 118 | } else { 119 | return fail_unknown_parameter; 120 | } 121 | if (set_gpio_mode(&pin->gpio, pinmode)) { 122 | pin->initialized = true; 123 | if (pin_num >= pin_limit) { 124 | pin_limit = pin_num + 1; 125 | } 126 | return fail_none; 127 | } 128 | return fail_not_capable; 129 | } 130 | 131 | void init_all_pins() { 132 | pin_limit = 0; 133 | for (size_t pin_num = 0; pin_num < n_pins; pin_num++) { 134 | init_pin(pin_num); 135 | } 136 | } 137 | void update_all_pins() { 138 | for (size_t pin_num = 0; pin_num < pin_limit; pin_num++) { 139 | force_pin_update(pin_num); 140 | } 141 | } 142 | void deinit_all_pins() { 143 | for (size_t pin_num = 0; pin_num < n_pins; pin_num++) { 144 | deinit_pin(pin_num); 145 | } 146 | } 147 | void read_pin(pin_msg_t send_msg, uint8_t pin_num) { 148 | if (pin_num >= pin_limit) { 149 | return; 150 | } 151 | pin_t* pin = &gpios[pin_num]; 152 | if (pin->type == pin_type_input) { 153 | if (pin_changed(pin_num)) { 154 | send_msg(pin_num, pin->last_value == 1); 155 | } 156 | } 157 | } 158 | void read_all_pins(pin_msg_t send_msg) { 159 | for (size_t pin_num = 0; pin_num < pin_limit; pin_num++) { 160 | read_pin(send_msg, pin_num); 161 | } 162 | } 163 | 164 | #ifdef __cplusplus 165 | } 166 | #endif 167 | -------------------------------------------------------------------------------- /lib/Expander/src/pin.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Mitch Bradley 2 | // Use of this source code is governed by a GPLv3 license that can be found in the LICENSE file. 3 | 4 | #pragma once 5 | 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | 10 | #include 11 | #include 12 | #include "gpio_pin.h" 13 | 14 | typedef void (*pin_msg_t)(uint8_t pin_num, bool active); 15 | 16 | // This file is independent of any particular MCU or board, 17 | // but the details inside the "gpio_pin_t" type depend on the MCU. 18 | 19 | enum pin_type_t { 20 | pin_type_none = 0, 21 | pin_type_input = 1, 22 | pin_type_output = 2, 23 | pin_type_PWM = 3, 24 | }; 25 | 26 | enum FailCodes { 27 | fail_none = 0, // no problem 28 | fail_not_initialized = 1, 29 | fail_not_capable = 2, // Pin cannot be initialized this way 30 | fail_range = 3, // set value out of range 31 | fail_unknown_parameter = 4, 32 | fail_invalid_pin = 5, 33 | }; 34 | 35 | typedef struct { 36 | gpio_pin_t gpio; 37 | 38 | bool initialized; 39 | bool active_low; 40 | uint16_t type; 41 | int last_value; 42 | int debounce_ms; 43 | int last_change_millis; 44 | } pin_t; 45 | 46 | void init_pin(uint8_t pin_num); 47 | void force_pin_update(uint8_t pin_num); 48 | void deinit_pin(uint8_t pin_num); 49 | int set_pin_mode(uint8_t pin_num, pin_mode_t pinmode); 50 | int set_output(uint8_t pin_num, int32_t numerator, uint32_t denominator); 51 | bool pin_changed(uint8_t pin_num); 52 | void read_pin(pin_msg_t send_msg, uint8_t pin_num); 53 | 54 | void init_all_pins(); 55 | void update_all_pins(); 56 | void deinit_all_pins(); 57 | void read_all_pins(pin_msg_t send_msg); 58 | 59 | #ifdef __cplusplus 60 | } 61 | #endif 62 | -------------------------------------------------------------------------------- /lib/Expander/src/pinmode.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Mitch Bradley 2 | // Use of this source code is governed by a GPLv3 license that can be found in the LICENSE file. 3 | 4 | #pragma once 5 | 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | 10 | #include 11 | 12 | typedef uint32_t pin_mode_t; 13 | 14 | #define PIN_INPUT (1 << 0) 15 | #define PIN_OUTPUT (1 << 1) 16 | #define PIN_PWM (1 << 2) 17 | #define PIN_PULLUP (1 << 3) 18 | #define PIN_PULLDOWN (1 << 4) 19 | #define PIN_ACTIVELOW (1 << 5) 20 | 21 | #define IN PIN_INPUT 22 | #define OUT PIN_OUTPUT 23 | #define PWM PIN_PWM 24 | #define PU PIN_PULLUP 25 | #define PD PIN_PULLDOWN 26 | 27 | #define PIN_FREQ_SHIFT 8 28 | 29 | #ifdef __cplusplus 30 | } 31 | #endif 32 | --------------------------------------------------------------------------------