├── .github ├── FUNDING.yml ├── ISSUE_TEMPLATE │ ├── config.yml │ ├── c_enhancement_feature.yml │ ├── a_questions.yml │ └── b_bug_report.yml └── pull_request_template.md ├── docs ├── video_pic.jpg └── PicoDroCircuitDiagram.jpg ├── .gitignore ├── .vscode ├── settings.json └── launch.json ├── src ├── qdec │ ├── QuadratureDecoder.pio │ ├── QuadratureDecoder.cpp │ ├── QuadratureDecoder.h │ └── LICENSE.txt └── main.cpp ├── CMakeLists.txt ├── README.md └── LICENSE.txt /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: MrGreensWorkshop 2 | patreon: MrGreensWorkshop 3 | ko_fi: MrGreensWorkshop 4 | -------------------------------------------------------------------------------- /docs/video_pic.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MrGreensWorkshop/RasPiPicoSDK_PicoDRO/HEAD/docs/video_pic.jpg -------------------------------------------------------------------------------- /docs/PicoDroCircuitDiagram.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MrGreensWorkshop/RasPiPicoSDK_PicoDRO/HEAD/docs/PicoDroCircuitDiagram.jpg -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # this will handle to macos hidden folders 2 | # ignore all starts with .* except .git and so on 3 | .* 4 | !.git* 5 | !.editorconfig 6 | !.vscode/launch.json 7 | !.vscode/settings.json 8 | 9 | # build folder 10 | /build* 11 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: Feature request 4 | url: https://github.com/MrGreensWorkshop/RasPiPicoSDK_PicoDRO/discussions/new?category=feature-requests 5 | about: Please submit your Feature request here. 6 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Mr. Green's Workshop https://www.MrGreensWorkshop.com 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | { 7 | "terminal.integrated.env.osx": { 8 | "PICO_SDK_PATH": "${env:HOME}/pico-sdk" 9 | }, 10 | "terminal.integrated.env.linux": { 11 | "PICO_SDK_PATH": "${env:HOME}/pico-sdk" 12 | }, 13 | "terminal.integrated.env.windows": { 14 | "PICO_SDK_PATH": "${env:USERPROFILE}\\pico-sdk", 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Mr. Green's Workshop https://www.MrGreensWorkshop.com 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | { 7 | "version": "0.2.0", 8 | "configurations": [{ 9 | "name": "Pico SDK Debug", 10 | "device": "RP2040", 11 | "gdbPath": "arm-none-eabi-gdb", 12 | "cwd": "${workspaceRoot}", 13 | "executable": "build/PicoDRO.elf", 14 | "request": "launch", 15 | "type": "cortex-debug", 16 | "servertype": "openocd", 17 | "configFiles": [ 18 | "/interface/picoprobe.cfg", 19 | "/target/rp2040.cfg" 20 | ], 21 | "searchDir": ["${env:HOME}/openocd/tcl"], 22 | "svdFile": "${env:HOME}/pico-sdk/src/rp2040/hardware_regs/rp2040.svd", 23 | "runToEntryPoint": "main", 24 | "postRestartCommands": [ 25 | "break main", 26 | "continue" 27 | ] 28 | }] 29 | } 30 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/c_enhancement_feature.yml: -------------------------------------------------------------------------------- 1 | name: Enhancement or Feature 2 | description: Use this with related PR that you created 3 | title: "" 4 | labels: enhancement 5 | body: 6 | - type: markdown 7 | attributes: 8 | value: "### Thank you for contributing to this project!" 9 | - type: textarea 10 | attributes: 11 | label: Is this enhancement or feature is related to a problem? 12 | description: | 13 | Tip: You can attach images or log files by clicking this area to highlight it and then dragging files in. 14 | placeholder: A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 15 | validations: 16 | required: true 17 | - type: textarea 18 | attributes: 19 | label: Describe the solution you'd like 20 | placeholder: A clear and concise description of what you want to happen. 21 | validations: 22 | required: true 23 | - type: textarea 24 | attributes: 25 | label: Describe alternatives you've considered 26 | placeholder: A clear and concise description of any alternative solutions or features you've considered. 27 | validations: 28 | required: false 29 | - type: textarea 30 | attributes: 31 | label: Additional context 32 | placeholder: Add any other context or screenshots about the feature request here. 33 | validations: 34 | required: false 35 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/a_questions.yml: -------------------------------------------------------------------------------- 1 | name: Ask a Question 2 | description: Something is not going according to plan? 3 | title: "<title>" 4 | labels: "delete me" 5 | body: 6 | - type: checkboxes 7 | attributes: 8 | label: Please check these items before go any further 9 | description: Please search to see if an issue or discussion already exists for the problem you encountered. 10 | options: 11 | - label: I have watched [the related video](https://youtu.be/lGm3rTDp7nE) on YouTube. 12 | required: true 13 | - label: I have searched the existing [Issues](https://github.com/MrGreensWorkshop/RasPiPicoSDK_PicoDRO/issues/). 14 | required: true 15 | - label: I have searched the existing [Discussions](https://github.com/MrGreensWorkshop/RasPiPicoSDK_PicoDRO/discussions/). 16 | required: true 17 | - label: I have checked the existing Issues in the [QuadratureDecoder repo](https://github.com/adamgreen/QuadratureDecoder/issues/) and the answer was not there. 18 | required: true 19 | - type: markdown 20 | attributes: 21 | value: | 22 | Checked all above but still couldn't find an answer? 23 | #### [Click here to ask a question in Discussions](https://github.com/MrGreensWorkshop/RasPiPicoSDK_PicoDRO/discussions/new?category=problems) 24 | - type: dropdown 25 | id: t 26 | attributes: 27 | label: "." 28 | options: 29 | - . 30 | validations: 31 | required: true 32 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | #### About pull request 2 | - To get more insight, please check the related issue #XXX. 3 | 4 | #### What's changed to accomplish [problem / feature] described in issue 5 | <!-- Please provide a description of the changes proposed in the pull request --> 6 | 7 | Coding rule check is done [yes / no] 8 | 9 | <!-- 10 | For beginners 11 | 12 | - Please create an issue before creating a pull request. (You will find issue templates which guides you.) 13 | - Create a reference to your issue using #<issue number>. 14 | - A description of the changes proposed in the pull request. 15 | - Check questions and change it [a / b] to [a] or [b] 16 | --> 17 | 18 | <!-- 19 | #### Coding rule check 20 | 21 | Please make sure the following rules are followed 22 | 23 | 1. spaces and line breaks 24 | - rule : some code tools change all code syntax. Please make sure no spaces or line breaks have been added or removed unless it is related with the Pull Request 25 | - why : reviewing diff of codes gets a lot easier, because reviewers can pay attention to a code review. 26 | - rule : if .editorconfig file exist in this repo, please use editor that supports .editorconfig (https://editorconfig.org). This takes care of charset, line endings and indents. 27 | - why : reviewing diff of codes gets a lot easier, because reviewers can pay attention to a code review. 28 | 2. comments (for all programming languages) 29 | - rule : comments will be written on the top of the code lines, not the end of code line 30 | - why : reviewing diff of codes gets a lot easier, because reviewers can pay attention to a code review. 31 | --> 32 | -------------------------------------------------------------------------------- /src/qdec/QuadratureDecoder.pio: -------------------------------------------------------------------------------- 1 | /* Copyright 2021 Adam Green (https://github.com/adamgreen/) 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | */ 15 | 16 | ; Use the RP2040's PIO state machines to count quadrature encoder ticks. 17 | .program QuadratureDecoder 18 | 19 | ; Must start at 0 so that the following jump table can be jumped into with a 20 | ; 'mov pc, isr' instruction. 21 | .origin 0 22 | ; 16 element jump table based on 4-bit encoder last state and current state. 23 | jmp delta0 ; 00-00 24 | jmp minus1 ; 00-01 25 | jmp plus1 ; 00-10 26 | jmp delta0 ; 00-11 27 | jmp plus1 ; 01-00 28 | jmp delta0 ; 01-01 29 | jmp delta0 ; 01-10 30 | jmp minus1 ; 01-11 31 | jmp minus1 ; 10-00 32 | jmp delta0 ; 10-01 33 | jmp delta0 ; 10-10 34 | jmp plus1 ; 10-11 35 | jmp delta0 ; 11-00 36 | jmp plus1 ; 11-01 37 | jmp minus1 ; 11-10 38 | jmp delta0 ; 11-11 39 | 40 | ; Program actually starts here. 41 | .wrap_target 42 | delta0: 43 | public start: 44 | mov isr, null ; Make sure that the input shift register is cleared when table jumps to delta0. 45 | in y, 2 ; Upper 2-bits of address are formed from previous encoder pin readings 46 | mov y, pins ; Lower 2-bits of address are formed from current encoder pin readings. Save in Y as well. 47 | in y, 2 48 | mov pc, isr ; Jump into jump table which will then jump to delta0, minus1, or plus1 labels. 49 | minus1: 50 | jmp x-- output ; Decrement x 51 | jmp output 52 | plus1: 53 | mov x, ~x ; Increment x by calculating x=~(~x - 1) 54 | jmp x-- next2 55 | next2: 56 | mov x, ~x 57 | output: 58 | mov isr, x ; Push out updated counter. 59 | push noblock 60 | .wrap 61 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2022 Mr. Green's Workshop https://www.MrGreensWorkshop.com 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | # Set minimum CMake version 5 | cmake_minimum_required(VERSION 3.17) 6 | 7 | # Include the subsidiary .cmake file to get the SDK 8 | include($ENV{PICO_SDK_PATH}/external/pico_sdk_import.cmake) 9 | 10 | # Set the name and version of the project 11 | project(PicoDRO VERSION 1.0.0) 12 | 13 | # Set top source code folder 14 | set(SOURCE_FOLDER "src") 15 | 16 | # Set build type (options: 'Debug', 'Release', 'MinSizeRel', 'RelWithDebInfo') 17 | set(default_build_type "Release") 18 | 19 | # Set CMAKE_BUILD_TYPE 20 | set(CMAKE_BUILD_TYPE "${default_build_type}" CACHE STRING "Choose the type of build, options are: 'Debug', 'Release', 'MinSizeRel', 'RelWithDebInfo'." FORCE) 21 | 22 | # Initialize the SDK 23 | pico_sdk_init() 24 | 25 | # Add an executable target for the project 26 | add_executable(${PROJECT_NAME}) 27 | 28 | # Get all the pio files, when the glob value changes, cmake will run again and update the files 29 | file(GLOB_RECURSE pio_src CONFIGURE_DEPENDS "${SOURCE_FOLDER}/*.pio") 30 | 31 | # Convert List to String 32 | STRING(REPLACE ";" "\n" PIO_SRC_STR "${pio_src}") 33 | 34 | # Print the pio source file list 35 | message(STATUS "PIO code source files: \n${PIO_SRC_STR}") 36 | 37 | # If there are any PIO source files, include them to the build. 38 | if (NOT pio_src STREQUAL "") 39 | pico_generate_pio_header(${PROJECT_NAME} ${pio_src}) 40 | endif() 41 | 42 | # Get all C and C++ files, when the glob value changes, cmake will run again and update the files 43 | file(GLOB_RECURSE app_src CONFIGURE_DEPENDS "${SOURCE_FOLDER}/*.c" "${SOURCE_FOLDER}/*.cpp" ) 44 | 45 | # Convert List to String 46 | STRING(REPLACE ";" "\n" APP_SRC_STR "${app_src}") 47 | 48 | # Print the C and C++ source file list 49 | message(STATUS "C and C++ source files: \n${APP_SRC_STR}") 50 | 51 | # Add C and C++ source files to the build 52 | target_sources(${PROJECT_NAME} PRIVATE ${app_src}) 53 | 54 | # Link the Project to extra libraries 55 | target_link_libraries(${PROJECT_NAME} PRIVATE 56 | pico_stdlib 57 | hardware_pio 58 | hardware_dma 59 | ) 60 | 61 | # Including header files directly from project directory 62 | target_include_directories(${PROJECT_NAME} PRIVATE 63 | ${CMAKE_CURRENT_LIST_DIR} 64 | ) 65 | 66 | # Export binaries like hex, bin, and uf2 files. 67 | pico_add_extra_outputs(${PROJECT_NAME}) 68 | 69 | # Enable or Disable UART 70 | pico_enable_stdio_uart(${PROJECT_NAME} 0) 71 | 72 | # Enable or Disable USB CDC 73 | pico_enable_stdio_usb(${PROJECT_NAME} 1) 74 | 75 | # Disable DTR check for USB CDC connection 76 | add_definitions(-DPICO_STDIO_USB_CONNECTION_WITHOUT_DTR=1) 77 | 78 | # Set USB device as self powered device 79 | add_definitions(-DPICO_STDIO_USB_DEVICE_SELF_POWERED=1) 80 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/b_bug_report.yml: -------------------------------------------------------------------------------- 1 | name: Bug report 2 | description: Create a bug report to help us improve 3 | title: "<title>" 4 | labels: bug 5 | body: 6 | - type: markdown 7 | attributes: 8 | value: "## Thank you for contributing to this project!" 9 | - type: checkboxes 10 | attributes: 11 | label: Please check these items before go any further 12 | description: Please search to see if an issue already exists for the bug you encountered. 13 | options: 14 | - label: I have watched [the related video](https://youtu.be/lGm3rTDp7nE) on YouTube. 15 | required: true 16 | - label: I have searched the existing [Issues](https://github.com/MrGreensWorkshop/RasPiPicoSDK_PicoDRO/issues/). 17 | required: true 18 | - label: I have searched the existing [Discussions](https://github.com/MrGreensWorkshop/RasPiPicoSDK_PicoDRO/discussions/). 19 | required: true 20 | - label: I have checked the existing Issues in the [QuadratureDecoder repo](https://github.com/adamgreen/QuadratureDecoder/issues/) and the answer was not there. 21 | required: true 22 | - type: checkboxes 23 | attributes: 24 | label: Are you sure this is a bug? 25 | description: | 26 | The Issues in this repo is only used for 'Bug reports' or 'Feature requests'. 27 | If you are not sure if this is a bug or not, please ask a question from [Discussions](https://github.com/MrGreensWorkshop/RasPiPicoSDK_PicoDRO/issues/new?assignees=&labels=delete+me&template=a_questions.yml&title=%3Ctitle%3E). 28 | options: 29 | - label: I'm sure this is definitely a bug. 30 | required: true 31 | - type: textarea 32 | attributes: 33 | label: Describe the bug 34 | description: | 35 | A clear and concise description of what the bug is. 36 | Tip: You can attach images or log files by clicking this area to highlight it and then dragging files in. 37 | validations: 38 | required: true 39 | - type: textarea 40 | attributes: 41 | label: Expected Behavior 42 | description: A clear and concise description of what you expected to happen. 43 | validations: 44 | required: true 45 | - type: textarea 46 | attributes: 47 | label: Steps To Reproduce 48 | description: Steps to reproduce the behavior. 49 | #value: | 50 | placeholder: | 51 | 1. Go to '...' 52 | 2. Push the button when '...' 53 | 3. See the error 54 | validations: 55 | required: true 56 | - type: checkboxes 57 | attributes: 58 | label: Which device have you used? 59 | description: You may select more than one. 60 | options: 61 | - label: Raspberry Pi Pico 62 | required: false 63 | - label: Raspberry Pi Pico W (This project hasn't been tested on Raspberry Pi Pico W) 64 | required: false 65 | - type: textarea 66 | attributes: 67 | label: Anything else? 68 | description: | 69 | Links? References? Anything that will give us more context about the issue you are encountering! 70 | validations: 71 | required: false 72 | - type: markdown 73 | attributes: 74 | value: | 75 | Thank you for taking the time to fill out this bug report. 76 | -------------------------------------------------------------------------------- /src/main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Mr. Green's Workshop https://www.MrGreensWorkshop.com 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | /* PicoDRO 8 | * DIY digital readout with Linear scales using Raspberry Pi Pico 9 | */ 10 | 11 | #include <stdio.h> 12 | #include "qdec/QuadratureDecoder.h" 13 | 14 | #define LED_PIN PICO_DEFAULT_LED_PIN 15 | 16 | void flashLedOnce(void) { 17 | gpio_init(LED_PIN); 18 | gpio_set_dir(LED_PIN, GPIO_OUT); 19 | // Led ON 20 | gpio_put(LED_PIN, 1); 21 | sleep_ms(200); 22 | // Led OFF 23 | gpio_put(LED_PIN, 0); 24 | } 25 | 26 | int main(void) 27 | { 28 | QuadratureDecoder qdec; 29 | // As long as there are two pins in a row, any two pins can be assigned for each axis. 30 | // X:A X:B Y:A Y:B Z:A Z:B 31 | const char pinList[] = {16, 17, 18, 19, 20, 21}; 32 | const char pinCnt = sizeof(pinList); 33 | const char axisCnt = pinCnt / 2; 34 | const char axisNames[] = {'X', 'Y', 'Z'}; 35 | // readInterval < sendIntervalMin < sendIntervalMax 36 | // I didn't test the minimum response time of the system. 37 | // Time interval between encoder readings. (in milliseconds) 38 | const uint32_t readInterval = 9; 39 | // Minimum time interval between sending encoder values to the host when the encoder value has changed. (in milliseconds) 40 | const uint32_t sendIntervalMin = 10; 41 | // Maximum time interval between sending encoder values to the host when the encoder value has not changed. (in milliseconds) 42 | const uint32_t sendIntervalMax = 1000; 43 | 44 | int32_t stateMachineList[axisCnt]; 45 | int32_t axisValList[axisCnt]; 46 | int32_t axisValListOld[axisCnt]; 47 | 48 | stdio_init_all(); 49 | 50 | flashLedOnce(); 51 | 52 | qdec.init(pio0); 53 | 54 | int x = 0; 55 | for(int i = 0; i < pinCnt; i++) { 56 | gpio_init(pinList[i]); 57 | gpio_disable_pulls(pinList[i]); 58 | if (i % 2 == 0) { 59 | stateMachineList[x++] = qdec.addQuadratureEncoder(pinList[i]); 60 | } 61 | } 62 | 63 | absolute_time_t readIntervalTime = nil_time; 64 | absolute_time_t sendIntervalTime = nil_time; 65 | bool setNextIntervalFlg = false; 66 | while (1) { 67 | if (absolute_time_diff_us(get_absolute_time(), readIntervalTime) < 0) { 68 | for(int i = 0; i < axisCnt; i++) { 69 | axisValList[i] = qdec.getCount(stateMachineList[i]); 70 | 71 | if (axisValListOld[i] != axisValList[i]) { 72 | if (setNextIntervalFlg == false) { 73 | sendIntervalTime = make_timeout_time_ms(sendIntervalMin); 74 | setNextIntervalFlg = true; 75 | } 76 | axisValListOld[i] = axisValList[i]; 77 | } 78 | } 79 | readIntervalTime = make_timeout_time_ms(readInterval); 80 | } 81 | 82 | if (absolute_time_diff_us(get_absolute_time(), sendIntervalTime) < 0) { 83 | for(int i = 0; i < axisCnt; i++) { 84 | printf("%c%d;", axisNames[i], axisValList[i]); 85 | } 86 | sendIntervalTime = make_timeout_time_ms(sendIntervalMax); 87 | setNextIntervalFlg = false; 88 | } 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /src/qdec/QuadratureDecoder.cpp: -------------------------------------------------------------------------------- 1 | /* Copyright 2021 Adam Green (https://github.com/adamgreen/) 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | */ 15 | // Class to use the RP2040's PIO state machines to count quadrature encoder ticks. 16 | #include "QuadratureDecoder.h" 17 | #include <string.h> 18 | #include <QuadratureDecoder.pio.h> 19 | 20 | 21 | 22 | QuadratureDecoder::QuadratureDecoder() 23 | { 24 | m_pio = pio0; 25 | memset((void*)m_counters, 0, sizeof(m_counters)); 26 | memset(m_dmaChannels, 0, sizeof(m_dmaChannels)); 27 | } 28 | 29 | bool QuadratureDecoder::init(PIO pio) 30 | { 31 | if (!pio_can_add_program(pio, &QuadratureDecoder_program)) 32 | { 33 | return false; 34 | } 35 | 36 | m_pio = pio; 37 | pio_add_program(m_pio, &QuadratureDecoder_program); 38 | 39 | return true; 40 | } 41 | 42 | int32_t QuadratureDecoder::addQuadratureEncoder(uint32_t pinBase) 43 | { 44 | // Find an unused state machine in the PIO to run the code for counting this encoder. 45 | int32_t stateMachine = pio_claim_unused_sm(m_pio, false); 46 | if (stateMachine < 0) 47 | { 48 | // No free state machines so return a failure code. 49 | return -1; 50 | } 51 | 52 | // The code is always loaded at offset 0 because of its jump table. 53 | const uint programOffset = 0; 54 | pio_sm_config smConfig = QuadratureDecoder_program_get_default_config(programOffset); 55 | 56 | // Configure the state machine to run the quadrature decoder program. 57 | const bool shiftLeft = false; 58 | const bool noAutoPush = false; 59 | const uint threshhold = 32; 60 | // We want the ISR to shift to right when the pin values are shifted in. 61 | sm_config_set_in_shift(&smConfig, shiftLeft, noAutoPush, threshhold); 62 | sm_config_set_in_pins(&smConfig, pinBase); 63 | // Use the TX FIFO entries for RX since we don't use the TX path. This makes for an 8 element RX FIFO. 64 | sm_config_set_fifo_join(&smConfig, PIO_FIFO_JOIN_RX); 65 | pio_sm_init(m_pio, stateMachine, QuadratureDecoder_offset_start, &smConfig); 66 | 67 | int dmaChannel = dma_claim_unused_channel(false); 68 | if (dmaChannel < 0) 69 | { 70 | // No free DMA channels so return a failure code. 71 | return -1; 72 | } 73 | m_dmaChannels[stateMachine] = dmaChannel; 74 | 75 | // Configure DMA to just read the latest count from the state machine's RX FIFO and place it in the m_counters[] 76 | // element reserved for this encoder. 77 | dma_channel_config dmaConfig = dma_channel_get_default_config(dmaChannel); 78 | channel_config_set_read_increment(&dmaConfig, false); 79 | channel_config_set_write_increment(&dmaConfig, false); 80 | channel_config_set_dreq(&dmaConfig, pio_get_dreq(m_pio, stateMachine, false)); 81 | 82 | volatile uint32_t* pCounter = &m_counters[stateMachine]; 83 | dma_channel_configure(dmaChannel, &dmaConfig, 84 | pCounter, // Destination pointer 85 | &m_pio->rxf[stateMachine], // Source pointer 86 | DMA_MAX_TRANSFER_COUNT, // Largest possible number of transfers 87 | true // Start immediately 88 | ); 89 | 90 | // Initialize state machine registers. 91 | // Initialize the X register to an initial count of 0. 92 | *pCounter = 0; 93 | pio_sm_exec(m_pio, stateMachine, pio_encode_set(pio_x, *pCounter)); 94 | // Initialize the Y register to the current value of the pins. 95 | pio_sm_exec(m_pio, stateMachine, pio_encode_mov(pio_y, pio_pins)); 96 | 97 | // Now start the state machine to count quadrature encoder ticks. 98 | pio_sm_set_enabled(m_pio, stateMachine, true); 99 | 100 | return stateMachine; 101 | } 102 | -------------------------------------------------------------------------------- /src/qdec/QuadratureDecoder.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2021 Adam Green (https://github.com/adamgreen/) 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | */ 15 | // Class to use the RP2040's PIO state machines to count quadrature encoder ticks. 16 | #ifndef QUADRATURE_DECODER_H_ 17 | #define QUADRATURE_DECODER_H_ 18 | 19 | #include <pico/stdlib.h> 20 | #include <hardware/pio.h> 21 | #include <hardware/dma.h> 22 | 23 | 24 | class QuadratureDecoder 25 | { 26 | public: 27 | // Constructor just sets up object. Need to call init() and addQuadratureEncoder() methods to actually initiliaze 28 | // the PIO state machines to count quadrature encoder ticks in the background. 29 | QuadratureDecoder(); 30 | 31 | // Call this init() method once to load the assembly language code into the caller specified PIO (pio0 or pio1). 32 | // The assembly language program used for quadrature decoding contains a 16 element instruction jump table so it 33 | // needs to be loaded at offset 0 in the PIO and it only leaves a few free instruction slots, 4, after being 34 | // loaded. Once this method has been called, the addQuadratureEncoder() method can be called for each 35 | // quadrature encoder that need to be decoded. 36 | // pio - The PIO instance to be used, pio0 or pio1. 37 | // Returns true if everything was initialized successfully. 38 | // Returns false if the assembly language code fails to load into the specified PIO instance. 39 | bool init(PIO pio); 40 | 41 | // Call this method to register a set of quadrature encoder pins to be counted in the background. The maximum 42 | // number of encoders that can be registered will be limited to 4, the number of state machines per PIO 43 | // instance. 44 | // pinBase - The lowest numbered GPIO pin connected to the quadrature encoder. The other signal wire from 45 | // the encoder needs to be connected to the next highest GPIO pin (examples: pins 2&3, pins 3&4, etc). 46 | // Returns -1 if it failed to allocate the required state machine or DMA resources. 47 | // Returns a value >= 0 specifying the index to be used in future calls to the getCount() method. 48 | int32_t addQuadratureEncoder(uint32_t pinBase); 49 | 50 | // Call this method to get the current count for a quadrature encoder previously registered with the 51 | // addQuadratureEncoder() method. 52 | // index - An index value returned from a previous call to addQuadratureEncoder(). This specifies which of the 53 | // registered quadrature encoder counts you want. 54 | // Returns the accumulated counts so far for the specified quadrature encoder. 55 | inline int32_t getCount(int32_t index) 56 | { 57 | hard_assert ( index >= 0 && index < (int32_t)(sizeof(m_counters)/sizeof(m_counters[0])) ); 58 | int32_t count = m_counters[index]; 59 | restartDmaBeforeItStops(index); 60 | return count; 61 | } 62 | 63 | protected: 64 | enum { DMA_MAX_TRANSFER_COUNT = 0xFFFFFFFF, DMA_REFRESH_THRESHOLD = 0x80000000 }; 65 | 66 | // Can only queue up 0xFFFFFFFF DMA transfers at a time. Every once in awhile we will want to reset the 67 | // transfer count back to 0xFFFFFFFF so that it doesn't stop pulling the latest encoder counts from the PIO. 68 | inline void restartDmaBeforeItStops(int32_t index) 69 | { 70 | uint32_t dmaChannel = m_dmaChannels[index]; 71 | uint32_t dmaTransfersLeft = dma_channel_hw_addr(dmaChannel)->transfer_count; 72 | if (dmaTransfersLeft > DMA_REFRESH_THRESHOLD) 73 | { 74 | // There are still a lot of transfers left in this DMA operation so just return. 75 | return; 76 | } 77 | 78 | // Stopping the DMA channel and starting it again will cause it to use all of the original settings, 79 | // including the 0xFFFFFFFF transfer count. 80 | dma_channel_abort(dmaChannel); 81 | dma_channel_start(dmaChannel); 82 | } 83 | 84 | PIO m_pio; 85 | // The maximum quadrature encoders to be counted are limited by the number of state machines in the PIO. 86 | volatile uint32_t m_counters[NUM_PIO_STATE_MACHINES]; 87 | uint32_t m_dmaChannels[NUM_PIO_STATE_MACHINES]; 88 | 89 | }; 90 | 91 | #endif // QUADRATURE_DECODER_H_ 92 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## PicoDRO 2 | 3 | [<img src="https://img.shields.io/github/issues/MrGreensWorkshop/RasPiPicoSDK_PicoDRO" alt="GitHub issues" data-no-image-viewer>](https://github.com/MrGreensWorkshop/RasPiPicoSDK_PicoDRO/issues) 4 | [<img src="https://img.shields.io/github/forks/MrGreensWorkshop/RasPiPicoSDK_PicoDRO?style=flat" alt="GitHub forks" data-no-image-viewer>](https://github.com/MrGreensWorkshop/RasPiPicoSDK_PicoDRO/blob/main/README.md#readme) 5 | [<img src="https://img.shields.io/github/stars/MrGreensWorkshop/RasPiPicoSDK_PicoDRO?style=flat" alt="GitHub stars" data-no-image-viewer>](https://github.com/MrGreensWorkshop/RasPiPicoSDK_PicoDRO/blob/main/README.md#readme) 6 | [<img src="https://img.shields.io/github/license/MrGreensWorkshop/RasPiPicoSDK_PicoDRO" alt="GitHub license" data-no-image-viewer>](https://github.com/MrGreensWorkshop/RasPiPicoSDK_PicoDRO/blob/main/LICENSE.txt) 7 | [<img src="https://shields.io/badge/Github%20Sponsors-Support%20me-blue?logo=GitHub+Sponsors" alt="Support me on GitHub Sponsors" data-no-image-viewer>](https://github.com/sponsors/MrGreensWorkshop "Support me on GitHub Sponsors") 8 | [<img src="https://shields.io/badge/Patreon-Support%20me-blue?logo=Patreon" alt="Support me on Patreon" data-no-image-viewer>](https://patreon.com/MrGreensWorkshop "Support me on Patreon") 9 | [<img src="https://shields.io/badge/Ko--fi-Tip%20me-blue?logo=kofi" alt="Tip me via Ko-fi" data-no-image-viewer>](https://ko-fi.com/MrGreensWorkshop "Tip me via Ko-fi") 10 | 11 | --- 12 | 13 | [<img src="/docs/video_pic.jpg" max-height="250" alt="DIY digital readout with Linear scales using Raspberry Pi Pico">](https://youtu.be/lGm3rTDp7nE) 14 | 15 | ### Introduction 16 | 17 | You can make your own digital readout with Linear scales / encoders using Raspberry Pi Pico. Only linear scales with RS-422 output are currently supported. It is compatible with TouchDRO App V3 via USB. 18 | 19 | Thank you for considering [supporting my work!](#you-can-support-my-work) 20 | 21 | #### Background 22 | 23 | I was looking to add the DRO feature to my small milling machine. I wanted to use junky but good-condition parts to support the SDGs. I found a few linear scales at an online auction and bought them. Then I found the pinouts as I explained in [this video](https://youtu.be/LyS_wd5C0y0). 24 | 25 | ### Features 26 | 27 | - 3 axis support (X,Y,Z) 28 | - Adjustable read interval 29 | - Dynamic data refresh rate 30 | - Adjustable data refresh rate 31 | 32 | ### Compilation 33 | 34 | 1. Clone the repo as shown below, or [download latest release](https://github.com/MrGreensWorkshop/RasPiPicoSDK_PicoDRO/releases/latest). 35 | 36 | ```shell 37 | git clone https://github.com/MrGreensWorkshop/RasPiPicoSDK_PicoDRO.git 38 | ``` 39 | 1. Please make sure you are using the [Pico SDK v1.5.0](https://github.com/raspberrypi/pico-sdk/releases/tag/1.5.0) or later, because the implementations described below are necessary. 40 | - **Disabling DTR check for USB CDC**, As we are going to use TouchDro App, we need to disable the DTR check for the USB CDC connection. 41 | - **Setting as self-powered USB device**, Since the circuit is designed as a self-powered USB device, to tell the USB host that we are not draining power from it, we need to set the attribute called bmAttributes in the USB configuration descriptor. 42 | 1. Open the project in VS Code because it adds SDK to the environment string. (Check the [.vscode/settings.json](https://github.com/MrGreensWorkshop/RasPiPicoSDK_PicoDRO/blob/main/.vscode/settings.json) file for details.) 43 | - Or add PICO_SDK_PATH to your environment string. 44 | 1. Compile using build.sh 45 | ```shell 46 | chmod +x build.sh 47 | ./build.sh 48 | ``` 49 | - Or run 50 | ```shell 51 | cmake -B build -S . && make -j4 -C build 52 | ``` 53 | 54 | ### Running 55 | 56 | 1. Make sure you watch the video at the top of the page. 57 | 2. Build the circuit below. 58 | 59 | <img src="/docs/PicoDroCircuitDiagram.jpg" max-height="300" alt="DIY digital readout with Linear scales using Raspberry Pi Pico"> 60 | 61 | 3. Get the binary 62 | - You can compile the project and get the binary as explained above. 63 | - Or you can use precompiled binary files from the [latest release](https://github.com/MrGreensWorkshop/RasPiPicoSDK_PicoDRO/releases/latest), download the "binary.zip" and unzip. 64 | 1. Put the Raspberry Pi Pico into bootloader mode by pushing the bootsel button while plugging it into your computer. 65 | 1. Copy the `build/PicoDRO.uf2` file to the Raspberry Pi Pico either by dragging and dropping or using the `cp` command as shown below. 66 | 67 | | Linux | macOS | 68 | | :---- | ----- | 69 | | `cp build/PicoDRO.uf2 /media/<user>/RPI-RP2` | `cp build/PicoDRO.uf2 /Volumes/RPI-RP2` | 70 | 1. TouchDRO App V3 or higher version is required to use via USB, but it has not been released yet. But you can get the app by entering the Android test program. For details, please check the [official TouchDRO website](https://www.touchdro.com/resources/info/touchdro-v3.html#accessToBetaTesting). (Android 5.0 or higher is required.) 71 | 1. Download and Open the App. 72 | 1. To set USB as the default interface, please set `Settings > Use USB Connection` and set `USB Baud Rate` to `115200`. 73 | 1. To set resolution to 1.00 microns, please open `Settings > X Axis Settings > Resolution` and enter `25400` to set encoder steps per inch. 74 | 75 | ### Documentation 76 | 77 | Check out the video at the top of the page. 78 | 79 | ### Credits 80 | 81 | I want to thank all projects that gave me an opportunity to make this project possible. Please consider to support these projects too. 82 | 83 | - [QuadratureDecoder](https://github.com/adamgreen/QuadratureDecoder) This is a library that counts quadrature encoder signal transitions in the background using the RP2040's PIO and DMA hardware. 84 | - [TouchDRO Application](https://www.touchdro.com/resources/dro-manual/features.html) is a free Android application that provides all standard DRO features combined with easy to read high-resolution multi-touch display and superior computing power offered by modern phones and tablets. It is also ad-free. 85 | 86 | ### You Can Support My Work 87 | 88 | Creating projects like this takes a great amount of time. Much appreciated if you consider supporting me so that I can continue projects like this and creating new contents for everyone. 89 | 90 | - You can support me on [GitHub Sponsors](https://github.com/sponsors/MrGreensWorkshop "Support me on GitHub Sponsors") (monthly or one time) 91 | - You can be one of my patrons on [Patreon](https://patreon.com/MrGreensWorkshop "Be my Patron") (monthly) 92 | - You can tip me via [Ko-fi](https://ko-fi.com/MrGreensWorkshop "Tip Me via Ko-fi") (one time) 93 | 94 | ### Contribute 95 | 96 | Pull Requests are welcome. Please check the instructions in the Issues and Pull Request templates. 97 | <!-- 98 | ### Contributors 99 | 100 | Thank you for your contributions! 101 | --> 102 | ### License 103 | 104 | As it says in the [Apache License 2.0](https://github.com/MrGreensWorkshop/RasPiPicoSDK_PicoDRO/blob/main/LICENSE.txt), you can use my code anywhere as long as you include the license file and copyright notice. Also, state if you make any changes. 105 | 106 | `Copyright (c) 2022 Mr. Green's Workshop https://www.MrGreensWorkshop.com` 107 | 108 | ### Other Licenses 109 | 110 | This project incorporates libraries written below. Without these libraries, I couldn't make this project possible. 111 | 112 | | Library | file(s) | 113 | | :----------------------------------- | ------- | 114 | | [ QuadratureDecoder](https://github.com/adamgreen/QuadratureDecoder), Copyright 2021 Adam Green (https://github.com/adamgreen/). QuadratureDecoder is distributed under the terms of the Apache License Version 2.0. | [Qdec](https://github.com/MrGreensWorkshop/RasPiPicoSDK_PicoDRO/tree/cf4ea2f01e0efe79339fd23c5473e978ff1312fd/src/qdec) | 115 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /src/qdec/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | --------------------------------------------------------------------------------