diff --git a/.gitignore b/.gitignore index da8d1e2..73adc3e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ .vscode/settings.json +.pio +.DS_Store \ No newline at end of file diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json deleted file mode 100644 index 46cf7f4..0000000 --- a/.vscode/c_cpp_properties.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "configurations": [ - { - "name": "Win32", - "includePath": [ - "${workspaceFolder}/**" - ], - "defines": [ - "_DEBUG", - "UNICODE", - "_UNICODE" - ], - "cStandard": "c17", - "cppStandard": "c++17", - "intelliSenseMode": "windows-msvc-x64" - } - ], - "version": 4 -} \ No newline at end of file diff --git a/ASTRA/IMU/README.md b/ASTRA/IMU/README.md new file mode 100644 index 0000000..8393aae --- /dev/null +++ b/ASTRA/IMU/README.md @@ -0,0 +1,5 @@ +# PLEASE READ + +This code is for the driver of the IMU. The structure used to be that this github repository was a submodule of the ASTRAFlightSoftware Repository. +However, this caused confusion among new developers on how to actually update the IMU driver. We no longer use this submodule structure, and thus, the code +for the IMU in this repository is unused and out of date. It is kept here only for old branches in ASTRAFlightSoftware. Do not use this code for any other reason. diff --git a/ASTRA/IMU/include/LSM6DS_LIS3MDL.h b/ASTRA/IMU/include/LSM6DS_LIS3MDL.h index d9bb782..460fbb6 100644 --- a/ASTRA/IMU/include/LSM6DS_LIS3MDL.h +++ b/ASTRA/IMU/include/LSM6DS_LIS3MDL.h @@ -3,7 +3,10 @@ LSM6DS_LIS3MDL.h Description: Header file for sensor-setup function definitions Author: Vincent Palmerio, (Original: https://github.com/adafruit/Adafruit_AHRS/blob/master/examples/calibrated_orientation/calibrated_orientation.ino) + + Last updated: 11/4/2023 + */ #ifndef LSM6DS_LIS3MDL diff --git a/ASTRA/IMU/src/IMU.cpp b/ASTRA/IMU/src/IMU.cpp index aeda5b1..7de6f9c 100644 --- a/ASTRA/IMU/src/IMU.cpp +++ b/ASTRA/IMU/src/IMU.cpp @@ -6,13 +6,25 @@ IMU.cpp Description: Function definititions for declarations in IMU.h Author: Vincent Palmerio -Last updated: 11/4/2023 + */ -float roll, pitch, heading = 0; + +Eigen::VectorXd linearAccelVector(3); +float linearAccelX, linearAccelY, linearAccelZ = 0; +float roll, pitch, yaw = 0; float gx, gy, gz = 0; //degrees per second on gyro float qw, qx, qy, qz = 0; //quaternarion +float* getValues() { + float* values = (float*)malloc(3 * sizeof(float)); + values[0] = roll; + values[1] = pitch; + values[2] = yaw; + return values; +} + + //loads a predetermined calibration into the EEPROM int loadPresetCalibration() { //Magnetic Hard Offset @@ -44,10 +56,16 @@ int loadPresetCalibration() { } -int initalizeIMU() { + +int initializeIMU() { Serial.begin(115200); while (!Serial) yield(); + for (int i = 0; i < linearAccelVector.size(); i++) { + linearAccelVector(i) = 0; + } + + if (!cal.begin()) { //Failed to initialize calibration helper #if defined(ASTRA_FULL_DEBUG) or defined(ASTRA_IMU_DEBUG) @@ -101,9 +119,10 @@ int updateIMU() { // Gyroscope needs to be converted from Rad/s to Degree/s // the rest are not unit-important - gx = gyro.gyro.x * SENSORS_RADS_TO_DPS; - gy = gyro.gyro.y * SENSORS_RADS_TO_DPS; - gz = gyro.gyro.z * SENSORS_RADS_TO_DPS; + + gx = gyro.gyro.x; //* SENSORS_RADS_TO_DPS; //omega x + gy = gyro.gyro.y; //* SENSORS_RADS_TO_DPS; //omega y + gz = gyro.gyro.z; //* SENSORS_RADS_TO_DPS; //omega z // Update the SensorFusion filter filter.update(gx, gy, gz, @@ -113,19 +132,22 @@ int updateIMU() { // print the heading, pitch and roll roll = filter.getRoll(); pitch = filter.getPitch(); - heading = filter.getYaw(); + yaw = filter.getYaw(); //float qw, qx, qy, qz; filter.getQuaternion(&qw, &qx, &qy, &qz); -#if defined(ASTRA_FULL_DEBUG) or defined(ASTRA_IMU_DEBUG) + filter.getLinearAcceleration(&linearAccelX, &linearAccelY, &linearAccelZ); //"a" - linear acceleration - Serial.print("I2C took "); Serial.print(millis()-timestamp); Serial.println(" ms"); + linearAccelVector << linearAccelX, linearAccelY, linearAccelZ; - Serial.print("Update took "); Serial.print(millis()-timestamp); Serial.println(" ms"); +#if defined(ASTRA_FULL_DEBUG) or defined(ASTRA_IMU_DEBUG) + + //Serial.print("I2C took "); Serial.print(millis()-timestamp); Serial.println(" ms"); + //Serial.print("Update took "); Serial.print(millis()-timestamp); Serial.println(" ms"); Serial.print("Raw: "); Serial.print(accel.acceleration.x, 4); Serial.print(", "); Serial.print(accel.acceleration.y, 4); Serial.print(", "); @@ -152,7 +174,8 @@ int updateIMU() { Serial.print(qy, 4); Serial.print(", "); Serial.println(qz, 4); - Serial.print("Took "); Serial.print(millis()-timestamp); Serial.println(" ms"); + //Serial.print("Took "); Serial.print(millis()-timestamp); Serial.println(" ms"); + #endif diff --git a/ASTRA/IMU/src/IMU.h b/ASTRA/IMU/src/IMU.h index b9863f6..c521952 100644 --- a/ASTRA/IMU/src/IMU.h +++ b/ASTRA/IMU/src/IMU.h @@ -3,7 +3,9 @@ IMU.h - Header file for the IMU Driver Description: Contains all functions and variables to interact with the IMU Author: Vincent Palmerio + Last updated: 11/4/2023 + */ #ifndef IMU_H @@ -16,6 +18,9 @@ Last updated: 11/4/2023 #include #include + +#include + //uncomment to print data to console for just IMU //#define ASTRA_IMU_DEBUG @@ -43,16 +48,23 @@ Last updated: 11/4/2023 //#define AHRS_DEBUG_OUTPUT -extern float roll, pitch, heading; +extern float* values; +extern float roll, pitch, yaw; +extern Eigen::VectorXd linearAccelVector; +extern float linearAccelX, linearAccelY, linearAccelZ; + extern float gx, gy, gz; //degrees per second on gyro extern float qw, qx, qy, qz; //quaternarion // slower == better quality output static Adafruit_NXPSensorFusion filter; // slowest -extern int initalizeIMU(); + +extern int initializeIMU(); extern int updateIMU(); extern int loadPresetCalibration(); +extern float* getValues(); + #endif diff --git a/ASTRA/error/DriverError.h b/ASTRA/error/DriverError.h index f4e0a2b..e1a5ff5 100644 --- a/ASTRA/error/DriverError.h +++ b/ASTRA/error/DriverError.h @@ -2,8 +2,10 @@ DriverError.h - Error Header/Constants File for Drivers Description: Error Constants for all Driver Errors that occur Author: Vincent Palmerio + Created: 10/2/2023 Last updated: 10/2/2023 + */ #ifndef DRIVER_ERROR_H diff --git a/ASTRA/testing/IMU_Debug/platformio.ini b/ASTRA/testing/IMU_Debug/platformio.ini index 38b79c6..d8839c7 100644 --- a/ASTRA/testing/IMU_Debug/platformio.ini +++ b/ASTRA/testing/IMU_Debug/platformio.ini @@ -14,6 +14,8 @@ board = teensy41 framework = arduino lib_extra_dirs = ../../IMU lib_deps = + + hideakitai/ArduinoEigen@^0.3.0 adafruit/Adafruit LSM6DS@^4.7.0 adafruit/Adafruit LIS3MDL@^1.2.1 adafruit/Adafruit AHRS@^2.3.3 diff --git a/ASTRA/testing/IMU_Debug/src/main.cpp b/ASTRA/testing/IMU_Debug/src/main.cpp index 30d457f..5ce8438 100644 --- a/ASTRA/testing/IMU_Debug/src/main.cpp +++ b/ASTRA/testing/IMU_Debug/src/main.cpp @@ -1,11 +1,65 @@ #include "../../../IMU/src/IMU.h" + +/* +main.cpp +Description: Main file for running testing code for the IMU driver +Author: Vincent Palmerio +*/ + +Adafruit_LSM6DSOX sox; + void setup() { - initalizeIMU(); + initializeIMU(); + + if (!sox.begin_I2C()) { + // if (!sox.begin_SPI(LSM_CS)) { + // if (!sox.begin_SPI(LSM_CS, LSM_SCK, LSM_MISO, LSM_MOSI)) { + // Serial.println("Failed to find LSM6DSOX chip"); + while (1) { + delay(10); + } + } } void loop() { + updateIMU(); - Serial.print("test"); - Serial.print(heading); + Serial.print("Fusion values: "); + Serial.print(yaw); + Serial.print(" "); + Serial.print(roll); + Serial.print(" "); + Serial.print(pitch); + Serial.println(); + + + sensors_event_t accel; + sensors_event_t gyro; + sensors_event_t temp; + sox.getEvent(&accel, &gyro, &temp); + + Serial.print(millis(),7); + Serial.print(","); + + Serial.print(temp.temperature,7); + Serial.print(","); + + /* Display the results (acceleration is measured in m/s^2) */ + Serial.print(accel.acceleration.x,7); + Serial.print(","); + Serial.print(accel.acceleration.y,7); + Serial.print(","); + Serial.print(accel.acceleration.z,7); + Serial.print(","); + + /* Display the results (rotation is measured in rad/s) */ + Serial.print(gyro.gyro.x,7); + Serial.print(","); + Serial.print(gyro.gyro.y,7); + Serial.print(","); + Serial.print(gyro.gyro.z,7); + Serial.println(); + + } \ No newline at end of file diff --git a/README.md b/README.md index 508ffa0..4027e46 100644 --- a/README.md +++ b/README.md @@ -1 +1,46 @@ -# Avionics +![Logo](https://purdueseds.space/wp-content/uploads/2022/02/PSP-ActiveControls-1Color-White.svg) + +# Active Controls Avionics Repository + +Welcome to the AC Avionics Repository! + +This Repo is organized into the following project folders: +ASTRA, DAQ, Ground_Station, and Lander + +Most folders in this repository will have two subfolders: /lib and /src +### /lib +This folder is used for libraries and dependencies associated with the code in /src. +### /src +This folder is used for storing c++ files. + +## ASTRA +This folder holds all low-level code associated with the ASTRA project. + +### /IMU +This folder is dedicated to IMU drivers +### /Barometer +This folder is dedicated to Barometer drivers +### /ESC +This folder is dedicated to ESC drivers +### /BMS +This folder is dedicated to BMS drivers +### /error +This folder is associated with the error codes that can occur on any drivers. It is meant to be an easy look up for all driver error codes. + +## DAQ +This folder holds all code associated with test stands and setups that require data aquisition. + +### /Loadcell +This folder is dedicated to the -Insert Model Here- Loadcell +### /Thrust_Stand +This folder is dedicated to the Thrust Stand +### /Torque_Stand +This folder is dedicated to the Torque Stand +### /Mag_Encoders +This folder is dedicated to magnetic encoders + +## Ground_Station +This folder holds all code associated with the Ground Base Station. + +## Lander +This folder holds all low-level code associated with the Lander project. diff --git a/lib/HX711-master/.gitignore b/lib/HX711-master/.gitignore deleted file mode 100644 index e66e203..0000000 --- a/lib/HX711-master/.gitignore +++ /dev/null @@ -1,20 +0,0 @@ -# Compiled Object files -*.slo -*.lo -*.o - -# Compiled Dynamic libraries -*.so -*.dylib - -# Compiled Static libraries -*.lai -*.la -*.a - -# IDE metadata -/.idea - -# PlatformIO virtualenv and pioenv -/.venv* -/.pioenvs diff --git a/lib/HX711-master/.travis.yml b/lib/HX711-master/.travis.yml deleted file mode 100644 index 39935f4..0000000 --- a/lib/HX711-master/.travis.yml +++ /dev/null @@ -1,17 +0,0 @@ -language: python -python: - - "2.7" - -# Cache PlatformIO packages using Travis CI container-based infrastructure -sudo: false -cache: - directories: - - "~/.platformio" - -install: - - pip install -U platformio - -script: - - platformio ci --board=megaatmega2560 --lib="." examples/HX711_full_example - - platformio ci --board=megaatmega2560 --lib="." examples/HX711_timeout_example - - platformio run diff --git a/lib/HX711-master/CMakeLists.txt b/lib/HX711-master/CMakeLists.txt deleted file mode 100644 index 4261fdd..0000000 --- a/lib/HX711-master/CMakeLists.txt +++ /dev/null @@ -1,4 +0,0 @@ - -idf_component_register(SRCS "src/HX711.cpp" - INCLUDE_DIRS "src" - REQUIRES "arduino") diff --git a/lib/HX711-master/CONTRIBUTORS.md b/lib/HX711-master/CONTRIBUTORS.md deleted file mode 100644 index 4118ea4..0000000 --- a/lib/HX711-master/CONTRIBUTORS.md +++ /dev/null @@ -1,20 +0,0 @@ -# HX711 library contributors - -Listed in the order of appearance. - -- Weihong Guan: First steps -- Bogdan Necula: Making it real -- Zachary J. Fields: Performance improvements on AVR. Simplify read logic. -- Rodrigo Wirth: Support to read the current `get_offset` and `get_scale` -- Ulrich Wolf: Move pin definition out of constructor -- Alexander Wilms: Improve documentation -- David Holland-Moritz: Improve interrupt safety on AVR -- Geert Roumen et al.: ESP32 support -- Thomas O Fredericks: Support for Teensy 3.2 and non-blocking readings -- Ahmad Elbadri: Improve ESP8266 stability -- Andreas Motl: Spring cleaning, multiarch support -- Clemens Gruber: Hardware testing -- Many bits and pieces by countless people from the community, - see also "doc/backlog.rst" in the repository. - -Thanks a bunch! diff --git a/lib/HX711-master/LICENSE b/lib/HX711-master/LICENSE deleted file mode 100644 index 5a5ebbf..0000000 --- a/lib/HX711-master/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2018 Bogdan Necula - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/lib/HX711-master/Makefile b/lib/HX711-master/Makefile deleted file mode 100644 index 12d3c88..0000000 --- a/lib/HX711-master/Makefile +++ /dev/null @@ -1,62 +0,0 @@ -# ============ -# Main targets -# ============ - - -# ------------- -# Configuration -# ------------- - -$(eval venvpath := .venv2) -$(eval pip := $(venvpath)/bin/pip) -$(eval python := $(venvpath)/bin/python) -$(eval platformio := $(venvpath)/bin/platformio) - -# Setup Python virtualenv -setup-virtualenv: - @test -e $(python) || `command -v virtualenv` --python=python3 $(venvpath) - - -# ---------- -# PlatformIO -# ---------- - -install-platformio: setup-virtualenv - @$(pip) install platformio --quiet - -build-all: install-platformio - @$(platformio) run - -build-env: install-platformio - @$(platformio) run --environment $(environment) - - -# Note: This are legacy build targets, the new ones are defined through `platformio.ini`. - -ci-all: install-platformio - # atmelavr - $(platformio) ci --board=megaatmega2560 --lib="." examples/HX711_basic_example - $(platformio) ci --board=megaatmega2560 --lib="." examples/HX711_timeout_example - $(platformio) ci --board=megaatmega2560 --lib="." examples/HX711_full_example - - # atmelavr - $(MAKE) ci-basic board=feather328p - - # espressif8266 - $(MAKE) ci-basic board=huzzah - - # espressif32 - $(MAKE) ci-basic board=lopy4 - - # atmelsam - $(MAKE) ci-basic board=adafruit_feather_m0 - $(MAKE) ci-basic board=adafruit_feather_m4 - - # bluepill - $(MAKE) ci-basic board=bluepill_f103c8 - -ci-basic: - $(platformio) ci --board=$(board) --lib="." examples/HX711_basic_example --verbose - -clean: - $(platformio) run -t clean diff --git a/lib/HX711-master/README.md b/lib/HX711-master/README.md deleted file mode 100644 index 3c35c8e..0000000 --- a/lib/HX711-master/README.md +++ /dev/null @@ -1,215 +0,0 @@ -# HX711 -An Arduino library to interface the [Avia Semiconductor HX711 24-Bit Analog-to-Digital Converter (ADC)] -for reading load cells / weight scales. - -It supports the architectures `atmelavr`, `espressif8266`, `espressif32`, -`atmelsam`, `teensy` and `ststm32` by corresponding [PlatformIO] targets. - -[Avia Semiconductor HX711 24-Bit Analog-to-Digital Converter (ADC)]: http://www.dfrobot.com/image/data/SEN0160/hx711_english.pdf -[PlatformIO]: https://platformio.org/ - - -## Synopsis - -### Blocking mode -The library is usually used in blocking mode, i.e. it will wait for the -hardware becoming available before returning a reading. - -```c++ -#include "HX711.h" -HX711 loadcell; - -// 1. HX711 circuit wiring -const int LOADCELL_DOUT_PIN = 2; -const int LOADCELL_SCK_PIN = 3; - -// 2. Adjustment settings -const long LOADCELL_OFFSET = 50682624; -const long LOADCELL_DIVIDER = 5895655; - -// 3. Initialize library -loadcell.begin(LOADCELL_DOUT_PIN, LOADCELL_SCK_PIN); -loadcell.set_scale(LOADCELL_DIVIDER); -loadcell.set_offset(LOADCELL_OFFSET); - -// 4. Acquire reading -Serial.print("Weight: "); -Serial.println(loadcell.get_units(10), 2); -``` - -### Non-blocking mode -It is also possible to define a maximum timeout to wait for the hardware -to be initialized. This won't send the program into a spinlock when the -scale is disconnected and will probably also account for hardware failures. -``` -// 4. Acquire reading without blocking -if (loadcell.wait_ready_timeout(1000)) { - long reading = loadcell.get_units(10); - Serial.print("Weight: "); - Serial.println(reading, 2); -} else { - Serial.println("HX711 not found."); -} -``` - - -## FAQ -https://github.com/bogde/HX711/blob/master/doc/faq.md - - -## More examples -See `examples` directory in this repository. - - -## HAL support -- [Arduino AVR core](https://github.com/arduino/ArduinoCore-avr) -- [Arduino core for ESP8266](https://github.com/esp8266/Arduino) -- [Arduino core for ESP32](https://github.com/espressif/arduino-esp32) -- [Arduino core for SAMD21](https://github.com/arduino/ArduinoCore-samd) (untested) -- [Arduino core for SAMD51](https://github.com/adafruit/ArduinoCore-samd) (untested) -- [Arduino core for STM32](https://github.com/stm32duino/Arduino_Core_STM32) -- [Arduino Core for Adafruit Bluefruit nRF52 Boards](https://github.com/adafruit/Adafruit_nRF52_Arduino) - - -## Hardware support -The library has been tested successfully on the following hardware. - -- [ATmega328]: Arduino Uno -- [ESP8266]: WeMos D1 mini, Adafruit HUZZAH -- [ESP32]: ESP32 DEVKIT V1, Heltec WiFi Kit 32, Adafruit Feather HUZZAH32 -- [STM32 F1] ([Cortex-M3]): STM32F103C8T6 STM32 Blue Pill Board -- [nRF52]: Adafruit Feather nRF52840 Express - -Thanks, @bogde and @ClemensGruber! - -[ATmega328]: https://en.wikipedia.org/wiki/ATmega328 -[ESP8266]: https://en.wikipedia.org/wiki/ESP8266 -[ESP32]: https://en.wikipedia.org/wiki/ESP32 -[STM32 F1]: https://en.wikipedia.org/wiki/STM32#STM32_F1 -[Cortex-M3]: https://en.wikipedia.org/wiki/ARM_Cortex-M#Cortex-M3 -[nRF52]: https://infocenter.nordicsemi.com/index.jsp?topic=%2Fstruct_nrf52%2Fstruct%2Fnrf52.html - - -## Features -1. It provides a `tare()` function, which "resets" the scale to 0. Many other - implementations calculate the tare weight when the ADC is initialized only. - I needed a way to be able to set the tare weight at any time. - **Use case**: Place an empty container on the scale, call `tare()` to reset - the readings to 0, fill the container and get the weight of the content. - -2. It provides a `power_down()` function, to put the ADC into a low power mode. - According to the datasheet, - > When PD_SCK pin changes from low to high and stays at high - > for longer than 60μs, HX711 enters power down mode. - - **Use case**: Battery-powered scales. Accordingly, there is a `power_up()` - function to get the chip out of the low power mode. - -3. It has a `set_gain(byte gain)` function that allows you to set the gain factor - and select the channel. According to the datasheet, - > Channel A can be programmed with a gain of 128 or 64, corresponding to - a full-scale differential input voltage of ±20mV or ±40mV respectively, when - a 5V supply is connected to AVDD analog power supply pin. Channel B has - a fixed gain of 32. - - The same function is used to select the channel A or channel B, by passing - 128 or 64 for channel A, or 32 for channel B as the parameter. The default - value is 128, which means "channel A with a gain factor of 128", so one can - simply call `set_gain()`. - - This function is also called from the initializer method `begin()`. - -4. The `get_value()` and `get_units()` functions can receive an extra parameter "times", - and they will return the average of multiple readings instead of a single reading. - - -## How to calibrate your load cell -1. Call `set_scale()` with no parameter. -2. Call `tare()` with no parameter. -3. Place a known weight on the scale and call `get_units(10)`. -4. Divide the result in step 3 to your known weight. You should - get about the parameter you need to pass to `set_scale()`. -5. Adjust the parameter in step 4 until you get an accurate reading. - - -## Build - -### All architectures -This will spawn a Python virtualenv in the current directory, -install `platformio` into it and then execute `platformio run`, -effectively building for all environments defined in `platformio.ini`. - - make build-all - -#### Result -``` -Environment feather_328 [SUCCESS] -Environment atmega_2560 [SUCCESS] -Environment huzzah [SUCCESS] -Environment lopy4 [SUCCESS] -Environment teensy31 [SUCCESS] -Environment teensy36 [SUCCESS] -Environment feather_m0 [SUCCESS] -Environment arduino_due [SUCCESS] -Environment feather_m4 [SUCCESS] -Environment bluepill [SUCCESS] -Environment adafruit_feather_nrf52840 [SUCCESS] -``` - -#### Details -https://gist.github.com/amotl/5ed6b3eb1fcd2bc78552b218b426f6aa - - -### Specific architecture -You can run a build for a specific architecture by specifying -the appropriate platform label on the command line. - - # Build for LoPy4 - make build-env environment=lopy4 - - # Build for Feather M0 - make build-env environment=feather_m0 - - -## Deprecation warning -This library received some spring-cleaning in February 2019 (#123), -removing the pin definition within the constructor completely, as -this was not timing safe. (#29) Please use the new initialization -flavor as outlined in the example above. - - -## Credits -Thanks to Weihong Guan who started the first version of this library in 2012 -already (see [[arduino|module]Hx711 electronic scale kit](http://aguegu.net/?p=1327), -[sources](https://github.com/aguegu/ardulibs/tree/master/hx711)), Bogdan Necula -who took over in 2014 and last but not least all others who contributed to this -library over the course of the last years, see also `CONTRIBUTORS.rst` in this -repository. - -#### See also -- https://item.taobao.com/item.htm?id=18121631630 -- https://item.taobao.com/item.htm?id=544769386300 - - -## Similar libraries -There are other libraries around, enjoy: - -- https://github.com/olkal/HX711_ADC -- https://github.com/queuetue/Q2-HX711-Arduino-Library - - ---- - -## Appendix - -### Considerations about real world effects caused by physics -You should consider getting into the details of strain-gauge load cell -sensors when expecting reasonable results. The range of topics is from -sufficient and stable power supply, using the proper excitation voltage -to the Seebeck effect and temperature compensation. - -See also: -- [Overview about real world effects](https://community.hiveeyes.org/t/analog-vs-digital-signal-gain-amplifiers/380/6) -- [Thermoelectric effect](https://en.wikipedia.org/wiki/Thermoelectric_effect) (Seebeck effect) -- Temperature compensation: [Resource collection](https://community.hiveeyes.org/t/temperaturkompensation-fur-waage-hardware-firmware/115), [DIY research](https://community.hiveeyes.org/t/temperaturkompensation-fur-waage-notig-datensammlung/245) -- [Power management for HX711](https://community.hiveeyes.org/t/stromversorgung-hx711/893) diff --git a/lib/HX711-master/doc/faq.md b/lib/HX711-master/doc/faq.md deleted file mode 100644 index 57700f7..0000000 --- a/lib/HX711-master/doc/faq.md +++ /dev/null @@ -1,22 +0,0 @@ -# Frequently Asked Questions - -## 1. no matching function for call to 'HX711::HX711(const int&, const int&)' - -I'm getting the following error: - -```exit status 1 no matching function for call to 'HX711::HX711(const int&, const int&)'``` - -The new interface is that the begin(...) method will obtain the pin parameters. So instead of using: -``` -HX711 scale(LOADCELL_DOUT_PIN, LOADCELL_SCK_PIN); -``` -Use: -``` -HX711 scale; -``` -And then in ```void setup() { ... }``` initialize the pins like this: -``` -scale.begin(LOADCELL_DOUT_PIN, LOADCELL_SCK_PIN); -``` -Please refer to this example for more details: -https://github.com/bogde/HX711/blob/master/examples/HX711_basic_example/HX711_basic_example.ino#L7-L12 diff --git a/lib/HX711-master/doc/notes.md b/lib/HX711-master/doc/notes.md deleted file mode 100644 index 5242aba..0000000 --- a/lib/HX711-master/doc/notes.md +++ /dev/null @@ -1,92 +0,0 @@ -# HX711 library notes - - -## Backlog -- [o] Get library into https://www.arduinolibraries.info/ and https://platformio.org/ -- [o] Maybe use constructor-based initialization again? - It does not necessarily need to starting talking to the hardware yet! -- [o] Unify critical sections / interrupt disabling between platforms? - https://github.com/esp8266/Arduino/issues/2218 -- [o] Check out https://github.com/mmarchetti/DirectIO - -### Scan more forks - -- https://github.com/bigujun/HX711 -- https://github.com/OpenCamper/HX711 -- https://github.com/compugician/HX711-multi -- https://github.com/CasualTriangle/HX711-multi -- https://github.com/joeybane/HX711-multi -- https://github.com/polmes/HX711-multi -- https://github.com/knifter/HX711 - -See also - -- https://github.com/newAM/LoadCellOccupany - - -### Add links to pin mappings of popular chips -- https://stackoverflow.com/questions/42022000/which-pins-should-i-take-for-i2c-on-arduino-uno/42022566 -- https://www.arduino.cc/en/Hacking/PinMapping32u4 -- https://www.arduino.cc/en/Hacking/PinMappingSAM3X -- https://www.avdweb.nl/arduino/samd21/samd21-variant -- https://techtutorialsx.com/2017/04/02/esp8266-nodemcu-pin-mappings/ -- https://github.com/esp8266/Arduino/issues/584 -- https://www.arduino.cc/en/Hacking/Atmega168Hardware -- https://www.arduino.cc/en/Hacking/PinMapping168 - - ---- - - -# Spring-cleaning issue summary - -https://github.com/hiveeyes/HX711/tree/spring-cleaning - -## AVR -- [x] AVR interrupt safety - https://github.com/bogde/HX711/pull/62 - -## ARM/SAMD - -### Teensy 3.x -- [x] Thomas O Fredericks - https://github.com/bogde/HX711/pull/96 - -### Arduino Due -- [x] Drop a line at https://github.com/aguegu/ardulibs/issues/3 re. support for Arduino Due - -## Espressif - -### ESP8266 arch pragma / yield definition woes -- [x] https://github.com/bogde/HX711/issues/119 -- [x] https://github.com/bogde/HX711/issues/114 - -### ESP8266 constructor initialization freezes -- [x] https://github.com/bogde/HX711/issues/29 -- [x] https://github.com/bogde/HX711/pull/40 -- [x] https://github.com/bogde/HX711/pull/113 -- [x] https://github.com/bogde/HX711/pull/53 -- [x] https://github.com/bogde/HX711/pull/122 -- [x] https://github.com/bogde/HX711/issues/89 - -### ESP8266 WDT -- [o] https://github.com/bogde/HX711/issues/67 -- [x] https://github.com/bogde/HX711/issues/73 -- [x] https://github.com/bogde/HX711/pull/81 -- [x] https://github.com/bogde/HX711/pull/86 -- [x] https://github.com/bogde/HX711/issues/120 -- [x] https://github.com/bogde/HX711/issues/101 -- [o] https://github.com/Skaronator/ESP8266-Load-Cell/issues/6 -- [x] Q: Would `delay(1)` be better than `delay(0)`? - A: even delay(0) will work. Should be as often as you can spare, but not more than 100ms let's say - -- https://github.com/esp8266/Arduino/issues/2240#issuecomment-230874704 - -### ESP8266 lacking pin mapping -- [x] https://github.com/bruhautomation/ESP-MQTT-JSON-Multisensor/issues/14 -- [x] https://github.com/witnessmenow/simple-arduino-crypto-display/issues/2 -- [x] https://github.com/wemos/D1_mini_Examples/issues/21 -- [x] https://github.com/esp8266/Arduino/blob/master/variants/nodemcu/pins_arduino.h - -### ESP32 too fast -- [x] https://github.com/lemio/HX711 -- [x] https://github.com/bogde/HX711/issues/75 diff --git a/lib/HX711-master/doc/platformio-howto.md b/lib/HX711-master/doc/platformio-howto.md deleted file mode 100644 index 7557689..0000000 --- a/lib/HX711-master/doc/platformio-howto.md +++ /dev/null @@ -1,39 +0,0 @@ -# PlatformIO howto - -https://platformio.org/ - - -List installed platforms - - platformio platform list - - -List available boards - - platformio boards - - -Run specific build - - platformio ci --board=megaatmega2560 --lib="." examples/HX711_full_example - - -Run specific environment - - platformio run --environment lopy4 - - -Build all environments - - platformio run - -"Make clean" for all environments - - platformio run -t clean - - -Dump specific build environment - - platformio run --environment lopy4 --target envdump - -See slot `CPPDEFINES`. diff --git a/lib/HX711-master/examples/HX711_basic_example/HX711_basic_example.ino b/lib/HX711-master/examples/HX711_basic_example/HX711_basic_example.ino deleted file mode 100644 index 3ccca60..0000000 --- a/lib/HX711-master/examples/HX711_basic_example/HX711_basic_example.ino +++ /dev/null @@ -1,26 +0,0 @@ -#include "HX711.h" - -// HX711 circuit wiring -const int LOADCELL_DOUT_PIN = 2; -const int LOADCELL_SCK_PIN = 3; - -HX711 scale; - -void setup() { - Serial.begin(57600); - scale.begin(LOADCELL_DOUT_PIN, LOADCELL_SCK_PIN); -} - -void loop() { - - if (scale.is_ready()) { - long reading = scale.read(); - Serial.print("HX711 reading: "); - Serial.println(reading); - } else { - Serial.println("HX711 not found."); - } - - delay(1000); - -} diff --git a/lib/HX711-master/examples/HX711_full_example/HX711_full_example.ino b/lib/HX711-master/examples/HX711_full_example/HX711_full_example.ino deleted file mode 100644 index ed39e25..0000000 --- a/lib/HX711-master/examples/HX711_full_example/HX711_full_example.ino +++ /dev/null @@ -1,78 +0,0 @@ -/** - * - * HX711 library for Arduino - example file - * https://github.com/bogde/HX711 - * - * MIT License - * (c) 2018 Bogdan Necula - * -**/ -#include "HX711.h" - - -// HX711 circuit wiring -const int LOADCELL_DOUT_PIN = 2; -const int LOADCELL_SCK_PIN = 3; - - -HX711 scale; - -void setup() { - Serial.begin(38400); - Serial.println("HX711 Demo"); - - Serial.println("Initializing the scale"); - - // Initialize library with data output pin, clock input pin and gain factor. - // Channel selection is made by passing the appropriate gain: - // - With a gain factor of 64 or 128, channel A is selected - // - With a gain factor of 32, channel B is selected - // By omitting the gain factor parameter, the library - // default "128" (Channel A) is used here. - scale.begin(LOADCELL_DOUT_PIN, LOADCELL_SCK_PIN); - - Serial.println("Before setting up the scale:"); - Serial.print("read: \t\t"); - Serial.println(scale.read()); // print a raw reading from the ADC - - Serial.print("read average: \t\t"); - Serial.println(scale.read_average(20)); // print the average of 20 readings from the ADC - - Serial.print("get value: \t\t"); - Serial.println(scale.get_value(5)); // print the average of 5 readings from the ADC minus the tare weight (not set yet) - - Serial.print("get units: \t\t"); - Serial.println(scale.get_units(5), 1); // print the average of 5 readings from the ADC minus tare weight (not set) divided - // by the SCALE parameter (not set yet) - - scale.set_scale(2280.f); // this value is obtained by calibrating the scale with known weights; see the README for details - scale.tare(); // reset the scale to 0 - - Serial.println("After setting up the scale:"); - - Serial.print("read: \t\t"); - Serial.println(scale.read()); // print a raw reading from the ADC - - Serial.print("read average: \t\t"); - Serial.println(scale.read_average(20)); // print the average of 20 readings from the ADC - - Serial.print("get value: \t\t"); - Serial.println(scale.get_value(5)); // print the average of 5 readings from the ADC minus the tare weight, set with tare() - - Serial.print("get units: \t\t"); - Serial.println(scale.get_units(5), 1); // print the average of 5 readings from the ADC minus tare weight, divided - // by the SCALE parameter set with set_scale - - Serial.println("Readings:"); -} - -void loop() { - Serial.print("one reading:\t"); - Serial.print(scale.get_units(), 1); - Serial.print("\t| average:\t"); - Serial.println(scale.get_units(10), 1); - - scale.power_down(); // put the ADC in sleep mode - delay(5000); - scale.power_up(); -} diff --git a/lib/HX711-master/examples/HX711_retry_example/HX711_retry_example.ino b/lib/HX711-master/examples/HX711_retry_example/HX711_retry_example.ino deleted file mode 100644 index 659a3f2..0000000 --- a/lib/HX711-master/examples/HX711_retry_example/HX711_retry_example.ino +++ /dev/null @@ -1,26 +0,0 @@ -#include "HX711.h" - -// HX711 circuit wiring -const int LOADCELL_DOUT_PIN = 2; -const int LOADCELL_SCK_PIN = 3; - -HX711 scale; - -void setup() { - Serial.begin(57600); - scale.begin(LOADCELL_DOUT_PIN, LOADCELL_SCK_PIN); -} - -void loop() { - - if (scale.wait_ready_retry(10)) { - long reading = scale.read(); - Serial.print("HX711 reading: "); - Serial.println(reading); - } else { - Serial.println("HX711 not found."); - } - - delay(1500); - -} diff --git a/lib/HX711-master/examples/HX711_timeout_example/HX711_timeout_example.ino b/lib/HX711-master/examples/HX711_timeout_example/HX711_timeout_example.ino deleted file mode 100644 index 5e9a669..0000000 --- a/lib/HX711-master/examples/HX711_timeout_example/HX711_timeout_example.ino +++ /dev/null @@ -1,26 +0,0 @@ -#include "HX711.h" - -// HX711 circuit wiring -const int LOADCELL_DOUT_PIN = 2; -const int LOADCELL_SCK_PIN = 3; - -HX711 scale; - -void setup() { - Serial.begin(57600); - scale.begin(LOADCELL_DOUT_PIN, LOADCELL_SCK_PIN); -} - -void loop() { - - if (scale.wait_ready_timeout(1000)) { - long reading = scale.read(); - Serial.print("HX711 reading: "); - Serial.println(reading); - } else { - Serial.println("HX711 not found."); - } - - delay(1500); - -} diff --git a/lib/HX711-master/keywords.txt b/lib/HX711-master/keywords.txt deleted file mode 100644 index c0a5369..0000000 --- a/lib/HX711-master/keywords.txt +++ /dev/null @@ -1,30 +0,0 @@ -####################################### -# HX711 -####################################### - -####################################### -# Datatypes (KEYWORD1) -####################################### - -HX711 KEYWORD1 - -####################################### -# Methods and Functions (KEYWORD2) -####################################### - -is_ready KEYWORD2 -set_gain KEYWORD2 -read_average KEYWORD2 -get_value KEYWORD2 -get_units KEYWORD2 -tare KEYWORD2 -set_scale KEYWORD2 -get_scale KEYWORD2 -set_offset KEYWORD2 -get_offset KEYWORD2 -power_down KEYWORD2 -power_up KEYWORD2 - -####################################### -# Constants (LITERAL1) -####################################### \ No newline at end of file diff --git a/lib/HX711-master/library.json b/lib/HX711-master/library.json deleted file mode 100644 index 6758649..0000000 --- a/lib/HX711-master/library.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "name": "HX711", - "keywords": "hx711, scale, weight", - "description": "An Arduino library to interface the Avia Semiconductor HX711 24-Bit Analog-to-Digital Converter (ADC) for Weight Scales.", - "repository": { - "type": "git", - "url": "https://github.com/bogde/HX711.git" - }, - "version": "0.7.5", - "exclude": "tests", - "examples": "examples/*/*.ino", - "frameworks": "arduino", - "platforms": [ - "atmelavr", - "espressif8266", - "espressif32", - "atmelsam", - "ststm32" - ] -} diff --git a/lib/HX711-master/library.properties b/lib/HX711-master/library.properties deleted file mode 100644 index 03315e0..0000000 --- a/lib/HX711-master/library.properties +++ /dev/null @@ -1,8 +0,0 @@ -name=HX711 Arduino Library -version=0.7.5 -author=Bogdan Necula , Andreas Motl -maintainer=Bogdan Necula -sentence=Library to interface the Avia Semiconductor HX711 ADC. -paragraph=An Arduino library to interface the Avia Semiconductor HX711 24-Bit Analog-to-Digital Converter (ADC) for reading load cells / weight scales. -category=Sensors -url=https://github.com/bogde/HX711 diff --git a/lib/HX711-master/platformio.ini b/lib/HX711-master/platformio.ini deleted file mode 100644 index e4a09f6..0000000 --- a/lib/HX711-master/platformio.ini +++ /dev/null @@ -1,132 +0,0 @@ -; PlatformIO Project Configuration File -; -; Build options: build flags, source filter -; Upload options: custom upload port, speed and extra flags -; Library options: dependencies, extra library storages -; Advanced options: extra scripting -; -; Please visit documentation for the other options and examples -; https://docs.platformio.org/page/projectconf.html - -[platformio] -src_dir = examples/HX711_basic_example -include_dir = src - -[config] -build_flags = - -D VERSION=0.7.5 - -D DEBUG=1 - -src_filter = - +<*> - +<../../src/*.cpp> - - -[env:feather_328] -platform = atmelavr -framework = arduino -board = feather328p - -; Build options -build_flags = ${config.build_flags} -src_filter = ${config.src_filter} - - -[env:atmega_2560] -platform = atmelavr -framework = arduino -board = megaatmega2560 - -; Build options -build_flags = ${config.build_flags} -src_filter = ${config.src_filter} - - -[env:huzzah] -platform = espressif8266 -framework = arduino -board = huzzah - -; Build options -build_flags = ${config.build_flags} -src_filter = ${config.src_filter} - - -[env:lopy4] -platform = espressif32 -framework = arduino -board = lopy4 - -; Build options -build_flags = ${config.build_flags} -src_filter = ${config.src_filter} - - -[env:teensy31] -platform = teensy -framework = arduino -board = teensy31 - -; Build options -build_flags = ${config.build_flags} -src_filter = ${config.src_filter} - - -[env:teensy36] -platform = teensy -framework = arduino -board = teensy36 - -; Build options -build_flags = ${config.build_flags} -src_filter = ${config.src_filter} - - -[env:feather_m0] -platform = atmelsam -framework = arduino -board = adafruit_feather_m0 - -; Build options -build_flags = ${config.build_flags} -src_filter = ${config.src_filter} - - -[env:arduino_due] -platform = atmelsam -framework = arduino -board = dueUSB - -; Build options -build_flags = ${config.build_flags} -src_filter = ${config.src_filter} - - -[env:feather_m4] -platform = atmelsam -framework = arduino -board = adafruit_feather_m4 - -; Build options -build_flags = ${config.build_flags} -src_filter = ${config.src_filter} - - -[env:bluepill] -platform = ststm32 -framework = arduino -board = bluepill_f103c8 - -; Build options -;build_flags = ${config.build_flags} -src_filter = ${config.src_filter} - - -[env:adafruit_feather_nrf52840] -platform = nordicnrf52 -framework = arduino -board = adafruit_feather_nrf52840 - -; Build options -build_flags = ${config.build_flags} -src_filter = ${config.src_filter} \ No newline at end of file diff --git a/lib/HX711-master/src/HX711.cpp b/lib/HX711-master/src/HX711.cpp deleted file mode 100644 index f0f2be1..0000000 --- a/lib/HX711-master/src/HX711.cpp +++ /dev/null @@ -1,278 +0,0 @@ -/** - * - * HX711 library for Arduino - * https://github.com/bogde/HX711 - * - * MIT License - * (c) 2018 Bogdan Necula - * -**/ -#include -#include "HX711.h" - -// TEENSYDUINO has a port of Dean Camera's ATOMIC_BLOCK macros for AVR to ARM Cortex M3. -#define HAS_ATOMIC_BLOCK (defined(ARDUINO_ARCH_AVR) || defined(TEENSYDUINO)) - -// Whether we are running on either the ESP8266 or the ESP32. -#define ARCH_ESPRESSIF (defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32)) - -// Whether we are actually running on FreeRTOS. -#define IS_FREE_RTOS defined(ARDUINO_ARCH_ESP32) - -// Define macro designating whether we're running on a reasonable -// fast CPU and so should slow down sampling from GPIO. -#define FAST_CPU \ - ( \ - ARCH_ESPRESSIF || \ - defined(ARDUINO_ARCH_SAM) || defined(ARDUINO_ARCH_SAMD) || \ - defined(ARDUINO_ARCH_STM32) || defined(TEENSYDUINO) \ - ) - -#if HAS_ATOMIC_BLOCK -// Acquire AVR-specific ATOMIC_BLOCK(ATOMIC_RESTORESTATE) macro. -#include -#endif - -#if FAST_CPU -// Make shiftIn() be aware of clockspeed for -// faster CPUs like ESP32, Teensy 3.x and friends. -// See also: -// - https://github.com/bogde/HX711/issues/75 -// - https://github.com/arduino/Arduino/issues/6561 -// - https://community.hiveeyes.org/t/using-bogdans-canonical-hx711-library-on-the-esp32/539 -uint8_t shiftInSlow(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder) { - uint8_t value = 0; - uint8_t i; - - for(i = 0; i < 8; ++i) { - digitalWrite(clockPin, HIGH); - delayMicroseconds(1); - if(bitOrder == LSBFIRST) - value |= digitalRead(dataPin) << i; - else - value |= digitalRead(dataPin) << (7 - i); - digitalWrite(clockPin, LOW); - delayMicroseconds(1); - } - return value; -} -#define SHIFTIN_WITH_SPEED_SUPPORT(data,clock,order) shiftInSlow(data,clock,order) -#else -#define SHIFTIN_WITH_SPEED_SUPPORT(data,clock,order) shiftIn(data,clock,order) -#endif - -#if ARCH_ESPRESSIF -// ESP8266 doesn't read values between 0x20000 and 0x30000 when DOUT is pulled up. -#define DOUT_MODE INPUT -#else -#define DOUT_MODE INPUT_PULLUP -#endif - - -HX711::HX711() { -} - -HX711::~HX711() { -} - -void HX711::begin(byte dout, byte pd_sck, byte gain) { - PD_SCK = pd_sck; - DOUT = dout; - - pinMode(PD_SCK, OUTPUT); - pinMode(DOUT, DOUT_MODE); - - set_gain(gain); -} - -bool HX711::is_ready() { - return digitalRead(DOUT) == LOW; -} - -void HX711::set_gain(byte gain) { - switch (gain) { - case 128: // channel A, gain factor 128 - GAIN = 1; - break; - case 64: // channel A, gain factor 64 - GAIN = 3; - break; - case 32: // channel B, gain factor 32 - GAIN = 2; - break; - } - -} - -long HX711::read() { - - // Wait for the chip to become ready. - wait_ready(); - - // Define structures for reading data into. - unsigned long value = 0; - uint8_t data[3] = { 0 }; - uint8_t filler = 0x00; - - // Protect the read sequence from system interrupts. If an interrupt occurs during - // the time the PD_SCK signal is high it will stretch the length of the clock pulse. - // If the total pulse time exceeds 60 uSec this will cause the HX711 to enter - // power down mode during the middle of the read sequence. While the device will - // wake up when PD_SCK goes low again, the reset starts a new conversion cycle which - // forces DOUT high until that cycle is completed. - // - // The result is that all subsequent bits read by shiftIn() will read back as 1, - // corrupting the value returned by read(). The ATOMIC_BLOCK macro disables - // interrupts during the sequence and then restores the interrupt mask to its previous - // state after the sequence completes, insuring that the entire read-and-gain-set - // sequence is not interrupted. The macro has a few minor advantages over bracketing - // the sequence between `noInterrupts()` and `interrupts()` calls. - #if HAS_ATOMIC_BLOCK - ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { - - #elif IS_FREE_RTOS - // Begin of critical section. - // Critical sections are used as a valid protection method - // against simultaneous access in vanilla FreeRTOS. - // Disable the scheduler and call portDISABLE_INTERRUPTS. This prevents - // context switches and servicing of ISRs during a critical section. - portMUX_TYPE mux = portMUX_INITIALIZER_UNLOCKED; - portENTER_CRITICAL(&mux); - - #else - // Disable interrupts. - noInterrupts(); - #endif - - // Pulse the clock pin 24 times to read the data. - data[2] = SHIFTIN_WITH_SPEED_SUPPORT(DOUT, PD_SCK, MSBFIRST); - data[1] = SHIFTIN_WITH_SPEED_SUPPORT(DOUT, PD_SCK, MSBFIRST); - data[0] = SHIFTIN_WITH_SPEED_SUPPORT(DOUT, PD_SCK, MSBFIRST); - - // Set the channel and the gain factor for the next reading using the clock pin. - for (unsigned int i = 0; i < GAIN; i++) { - digitalWrite(PD_SCK, HIGH); - #if ARCH_ESPRESSIF - delayMicroseconds(1); - #endif - digitalWrite(PD_SCK, LOW); - #if ARCH_ESPRESSIF - delayMicroseconds(1); - #endif - } - - #if IS_FREE_RTOS - // End of critical section. - portEXIT_CRITICAL(&mux); - - #elif HAS_ATOMIC_BLOCK - } - - #else - // Enable interrupts again. - interrupts(); - #endif - - // Replicate the most significant bit to pad out a 32-bit signed integer - if (data[2] & 0x80) { - filler = 0xFF; - } else { - filler = 0x00; - } - - // Construct a 32-bit signed integer - value = ( static_cast(filler) << 24 - | static_cast(data[2]) << 16 - | static_cast(data[1]) << 8 - | static_cast(data[0]) ); - - return static_cast(value); -} - -void HX711::wait_ready(unsigned long delay_ms) { - // Wait for the chip to become ready. - // This is a blocking implementation and will - // halt the sketch until a load cell is connected. - while (!is_ready()) { - // Probably will do no harm on AVR but will feed the Watchdog Timer (WDT) on ESP. - // https://github.com/bogde/HX711/issues/73 - delay(delay_ms); - } -} - -bool HX711::wait_ready_retry(int retries, unsigned long delay_ms) { - // Wait for the chip to become ready by - // retrying for a specified amount of attempts. - // https://github.com/bogde/HX711/issues/76 - int count = 0; - while (count < retries) { - if (is_ready()) { - return true; - } - delay(delay_ms); - count++; - } - return false; -} - -bool HX711::wait_ready_timeout(unsigned long timeout, unsigned long delay_ms) { - // Wait for the chip to become ready until timeout. - // https://github.com/bogde/HX711/pull/96 - unsigned long millisStarted = millis(); - while (millis() - millisStarted < timeout) { - if (is_ready()) { - return true; - } - delay(delay_ms); - } - return false; -} - -long HX711::read_average(byte times) { - long sum = 0; - for (byte i = 0; i < times; i++) { - sum += read(); - // Probably will do no harm on AVR but will feed the Watchdog Timer (WDT) on ESP. - // https://github.com/bogde/HX711/issues/73 - delay(0); - } - return sum / times; -} - -double HX711::get_value(byte times) { - return read_average(times) - OFFSET; -} - -float HX711::get_units(byte times) { - return get_value(times) / SCALE; -} - -void HX711::tare(byte times) { - double sum = read_average(times); - set_offset(sum); -} - -void HX711::set_scale(float scale) { - SCALE = scale; -} - -float HX711::get_scale() { - return SCALE; -} - -void HX711::set_offset(long offset) { - OFFSET = offset; -} - -long HX711::get_offset() { - return OFFSET; -} - -void HX711::power_down() { - digitalWrite(PD_SCK, LOW); - digitalWrite(PD_SCK, HIGH); -} - -void HX711::power_up() { - digitalWrite(PD_SCK, LOW); -} diff --git a/lib/HX711-master/src/HX711.h b/lib/HX711-master/src/HX711.h deleted file mode 100644 index 9814891..0000000 --- a/lib/HX711-master/src/HX711.h +++ /dev/null @@ -1,91 +0,0 @@ -/** - * - * HX711 library for Arduino - * https://github.com/bogde/HX711 - * - * MIT License - * (c) 2018 Bogdan Necula - * -**/ -#ifndef HX711_h -#define HX711_h - -#if ARDUINO >= 100 -#include "Arduino.h" -#else -#include "WProgram.h" -#endif - -class HX711 -{ - private: - byte PD_SCK; // Power Down and Serial Clock Input Pin - byte DOUT; // Serial Data Output Pin - byte GAIN; // amplification factor - long OFFSET = 0; // used for tare weight - float SCALE = 1; // used to return weight in grams, kg, ounces, whatever - - public: - - HX711(); - - virtual ~HX711(); - - // Initialize library with data output pin, clock input pin and gain factor. - // Channel selection is made by passing the appropriate gain: - // - With a gain factor of 64 or 128, channel A is selected - // - With a gain factor of 32, channel B is selected - // The library default is "128" (Channel A). - void begin(byte dout, byte pd_sck, byte gain = 128); - - // Check if HX711 is ready - // from the datasheet: When output data is not ready for retrieval, digital output pin DOUT is high. Serial clock - // input PD_SCK should be low. When DOUT goes to low, it indicates data is ready for retrieval. - bool is_ready(); - - // Wait for the HX711 to become ready - void wait_ready(unsigned long delay_ms = 0); - bool wait_ready_retry(int retries = 3, unsigned long delay_ms = 0); - bool wait_ready_timeout(unsigned long timeout = 1000, unsigned long delay_ms = 0); - - // set the gain factor; takes effect only after a call to read() - // channel A can be set for a 128 or 64 gain; channel B has a fixed 32 gain - // depending on the parameter, the channel is also set to either A or B - void set_gain(byte gain = 128); - - // waits for the chip to be ready and returns a reading - long read(); - - // returns an average reading; times = how many times to read - long read_average(byte times = 10); - - // returns (read_average() - OFFSET), that is the current value without the tare weight; times = how many readings to do - double get_value(byte times = 1); - - // returns get_value() divided by SCALE, that is the raw value divided by a value obtained via calibration - // times = how many readings to do - float get_units(byte times = 1); - - // set the OFFSET value for tare weight; times = how many times to read the tare value - void tare(byte times = 10); - - // set the SCALE value; this value is used to convert the raw data to "human readable" data (measure units) - void set_scale(float scale = 1.f); - - // get the current SCALE - float get_scale(); - - // set OFFSET, the value that's subtracted from the actual reading (tare weight) - void set_offset(long offset = 0); - - // get the current OFFSET - long get_offset(); - - // puts the chip into power down mode - void power_down(); - - // wakes up the chip after power down mode - void power_up(); -}; - -#endif /* HX711_h */ diff --git a/lib/Servo-master/.codespellrc b/lib/Servo-master/.codespellrc deleted file mode 100644 index 101edae..0000000 --- a/lib/Servo-master/.codespellrc +++ /dev/null @@ -1,7 +0,0 @@ -# See: https://github.com/codespell-project/codespell#using-a-config-file -[codespell] -# In the event of a false positive, add the problematic word, in all lowercase, to a comma-separated list here: -ignore-words-list = , -check-filenames = -check-hidden = -skip = ./.git diff --git a/lib/Servo-master/.github/dependabot.yml b/lib/Servo-master/.github/dependabot.yml deleted file mode 100644 index fa738ec..0000000 --- a/lib/Servo-master/.github/dependabot.yml +++ /dev/null @@ -1,12 +0,0 @@ -# See: https://docs.github.com/en/github/administering-a-repository/configuration-options-for-dependency-updates#about-the-dependabotyml-file -version: 2 - -updates: - # Configure check for outdated GitHub Actions actions in workflows. - # See: https://docs.github.com/en/github/administering-a-repository/keeping-your-actions-up-to-date-with-dependabot - - package-ecosystem: github-actions - directory: / # Check the repository's workflows under /.github/workflows/ - schedule: - interval: daily - labels: - - "topic: infrastructure" diff --git a/lib/Servo-master/.github/workflows/check-arduino.yml b/lib/Servo-master/.github/workflows/check-arduino.yml deleted file mode 100644 index 3e0d26c..0000000 --- a/lib/Servo-master/.github/workflows/check-arduino.yml +++ /dev/null @@ -1,28 +0,0 @@ -name: Check Arduino - -# See: https://docs.github.com/en/free-pro-team@latest/actions/reference/events-that-trigger-workflows -on: - push: - pull_request: - schedule: - # Run every Tuesday at 8 AM UTC to catch breakage caused by new rules added to Arduino Lint. - - cron: "0 8 * * TUE" - workflow_dispatch: - repository_dispatch: - -jobs: - lint: - runs-on: ubuntu-latest - - steps: - - name: Checkout repository - uses: actions/checkout@v3 - - - name: Arduino Lint - uses: arduino/arduino-lint-action@v1 - with: - compliance: specification - library-manager: update - # Always use this setting for official repositories. Remove for 3rd party projects. - official: true - project-type: library diff --git a/lib/Servo-master/.github/workflows/compile-examples.yml b/lib/Servo-master/.github/workflows/compile-examples.yml deleted file mode 100644 index b4f8039..0000000 --- a/lib/Servo-master/.github/workflows/compile-examples.yml +++ /dev/null @@ -1,90 +0,0 @@ -name: Compile Examples - -# See: https://docs.github.com/en/free-pro-team@latest/actions/reference/events-that-trigger-workflows -on: - push: - paths: - - ".github/workflows/compile-examples.yml" - - "examples/**" - - "src/**" - pull_request: - paths: - - ".github/workflows/compile-examples.yml" - - "examples/**" - - "src/**" - schedule: - # Run every Tuesday at 8 AM UTC to catch breakage caused by changes to external resources (libraries, platforms). - - cron: "0 8 * * TUE" - workflow_dispatch: - repository_dispatch: - -jobs: - build: - name: ${{ matrix.board.fqbn }} - runs-on: ubuntu-latest - - env: - SKETCHES_REPORTS_PATH: sketches-reports - - strategy: - fail-fast: false - - matrix: - board: - - fqbn: arduino:avr:nano - platforms: | - - name: arduino:avr - - fqbn: arduino:avr:mega - platforms: | - - name: arduino:avr - - fqbn: arduino:avr:leonardo - platforms: | - - name: arduino:avr - - fqbn: arduino:megaavr:nona4809 - platforms: | - - name: arduino:megaavr - - fqbn: arduino:sam:arduino_due_x_dbg - platforms: | - - name: arduino:sam - - fqbn: arduino:samd:mkrzero - platforms: | - - name: arduino:samd - - fqbn: arduino:mbed_portenta:envie_m4 - platforms: | - - name: arduino:mbed_portenta - - fqbn: arduino:mbed_portenta:envie_m7 - platforms: | - - name: arduino:mbed_portenta - - fqbn: arduino:mbed_nano:nano33ble - platforms: | - - name: arduino:mbed_nano - - fqbn: arduino:mbed_nano:nanorp2040connect - platforms: | - - name: arduino:mbed_nano - - steps: - - name: Checkout repository - uses: actions/checkout@v3 - - - name: Compile examples - uses: arduino/compile-sketches@v1 - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - fqbn: ${{ matrix.board.fqbn }} - platforms: ${{ matrix.board.platforms }} - libraries: | - # Install the library from the local path. - - source-path: ./ - # Additional library dependencies can be listed here. - # See: https://github.com/arduino/compile-sketches#libraries - sketch-paths: | - - examples - enable-deltas-report: true - sketches-report-path: ${{ env.SKETCHES_REPORTS_PATH }} - - - name: Save sketches report as workflow artifact - uses: actions/upload-artifact@v2 - with: - if-no-files-found: error - path: ${{ env.SKETCHES_REPORTS_PATH }} - name: ${{ env.SKETCHES_REPORTS_PATH }} diff --git a/lib/Servo-master/.github/workflows/report-size-deltas.yml b/lib/Servo-master/.github/workflows/report-size-deltas.yml deleted file mode 100644 index 652be5d..0000000 --- a/lib/Servo-master/.github/workflows/report-size-deltas.yml +++ /dev/null @@ -1,24 +0,0 @@ -name: Report Size Deltas - -# See: https://docs.github.com/en/free-pro-team@latest/actions/reference/events-that-trigger-workflows -on: - push: - paths: - - ".github/workflows/report-size-deltas.yml" - schedule: - # Run at the minimum interval allowed by GitHub Actions. - # Note: GitHub Actions periodically has outages which result in workflow failures. - # In this event, the workflows will start passing again once the service recovers. - - cron: "*/5 * * * *" - workflow_dispatch: - repository_dispatch: - -jobs: - report: - runs-on: ubuntu-latest - steps: - - name: Comment size deltas reports to PRs - uses: arduino/report-size-deltas@v1 - with: - # The name of the workflow artifact created by the sketch compilation workflow - sketches-reports-source: sketches-reports diff --git a/lib/Servo-master/.github/workflows/spell-check.yml b/lib/Servo-master/.github/workflows/spell-check.yml deleted file mode 100644 index 3f6b03f..0000000 --- a/lib/Servo-master/.github/workflows/spell-check.yml +++ /dev/null @@ -1,22 +0,0 @@ -name: Spell Check - -# See: https://docs.github.com/en/free-pro-team@latest/actions/reference/events-that-trigger-workflows -on: - push: - pull_request: - schedule: - # Run every Tuesday at 8 AM UTC to catch new misspelling detections resulting from dictionary updates. - - cron: "0 8 * * TUE" - workflow_dispatch: - repository_dispatch: - -jobs: - spellcheck: - runs-on: ubuntu-latest - - steps: - - name: Checkout repository - uses: actions/checkout@v3 - - - name: Spell check - uses: codespell-project/actions-codespell@master diff --git a/lib/Servo-master/.github/workflows/sync-labels.yml b/lib/Servo-master/.github/workflows/sync-labels.yml deleted file mode 100644 index 4ea5755..0000000 --- a/lib/Servo-master/.github/workflows/sync-labels.yml +++ /dev/null @@ -1,138 +0,0 @@ -# Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/sync-labels.md -name: Sync Labels - -# See: https://docs.github.com/en/actions/reference/events-that-trigger-workflows -on: - push: - paths: - - ".github/workflows/sync-labels.ya?ml" - - ".github/label-configuration-files/*.ya?ml" - pull_request: - paths: - - ".github/workflows/sync-labels.ya?ml" - - ".github/label-configuration-files/*.ya?ml" - schedule: - # Run daily at 8 AM UTC to sync with changes to shared label configurations. - - cron: "0 8 * * *" - workflow_dispatch: - repository_dispatch: - -env: - CONFIGURATIONS_FOLDER: .github/label-configuration-files - CONFIGURATIONS_ARTIFACT: label-configuration-files - -jobs: - check: - runs-on: ubuntu-latest - - steps: - - name: Checkout repository - uses: actions/checkout@v3 - - - name: Download JSON schema for labels configuration file - id: download-schema - uses: carlosperate/download-file-action@v1 - with: - file-url: https://raw.githubusercontent.com/arduino/tooling-project-assets/main/workflow-templates/assets/sync-labels/arduino-tooling-gh-label-configuration-schema.json - location: ${{ runner.temp }}/label-configuration-schema - - - name: Install JSON schema validator - run: | - sudo npm install \ - --global \ - ajv-cli \ - ajv-formats - - - name: Validate local labels configuration - run: | - # See: https://github.com/ajv-validator/ajv-cli#readme - ajv validate \ - --all-errors \ - -c ajv-formats \ - -s "${{ steps.download-schema.outputs.file-path }}" \ - -d "${{ env.CONFIGURATIONS_FOLDER }}/*.{yml,yaml}" - - download: - needs: check - runs-on: ubuntu-latest - - strategy: - matrix: - filename: - # Filenames of the shared configurations to apply to the repository in addition to the local configuration. - # https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/assets/sync-labels - - universal.yml - - steps: - - name: Download - uses: carlosperate/download-file-action@v1 - with: - file-url: https://raw.githubusercontent.com/arduino/tooling-project-assets/main/workflow-templates/assets/sync-labels/${{ matrix.filename }} - - - name: Pass configuration files to next job via workflow artifact - uses: actions/upload-artifact@v2 - with: - path: | - *.yaml - *.yml - if-no-files-found: error - name: ${{ env.CONFIGURATIONS_ARTIFACT }} - - sync: - needs: download - runs-on: ubuntu-latest - - steps: - - name: Set environment variables - run: | - # See: https://docs.github.com/en/actions/reference/workflow-commands-for-github-actions#setting-an-environment-variable - echo "MERGED_CONFIGURATION_PATH=${{ runner.temp }}/labels.yml" >> "$GITHUB_ENV" - - - name: Determine whether to dry run - id: dry-run - if: > - github.event_name == 'pull_request' || - ( - ( - github.event_name == 'push' || - github.event_name == 'workflow_dispatch' - ) && - github.ref != format('refs/heads/{0}', github.event.repository.default_branch) - ) - run: | - # Use of this flag in the github-label-sync command will cause it to only check the validity of the - # configuration. - echo "::set-output name=flag::--dry-run" - - - name: Checkout repository - uses: actions/checkout@v3 - - - name: Download configuration files artifact - uses: actions/download-artifact@v2 - with: - name: ${{ env.CONFIGURATIONS_ARTIFACT }} - path: ${{ env.CONFIGURATIONS_FOLDER }} - - - name: Remove unneeded artifact - uses: geekyeggo/delete-artifact@v1 - with: - name: ${{ env.CONFIGURATIONS_ARTIFACT }} - - - name: Merge label configuration files - run: | - # Merge all configuration files - shopt -s extglob - cat "${{ env.CONFIGURATIONS_FOLDER }}"/*.@(yml|yaml) > "${{ env.MERGED_CONFIGURATION_PATH }}" - - - name: Install github-label-sync - run: sudo npm install --global github-label-sync - - - name: Sync labels - env: - GITHUB_ACCESS_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - # See: https://github.com/Financial-Times/github-label-sync - github-label-sync \ - --labels "${{ env.MERGED_CONFIGURATION_PATH }}" \ - ${{ steps.dry-run.outputs.flag }} \ - ${{ github.repository }} diff --git a/lib/Servo-master/LICENSE.txt b/lib/Servo-master/LICENSE.txt deleted file mode 100644 index 8000a6f..0000000 --- a/lib/Servo-master/LICENSE.txt +++ /dev/null @@ -1,504 +0,0 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 2.1, February 1999 - - Copyright (C) 1991, 1999 Free Software Foundation, Inc. - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -[This is the first released version of the Lesser GPL. It also counts - as the successor of the GNU Library Public License, version 2, hence - the version number 2.1.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Lesser General Public License, applies to some -specially designated software packages--typically libraries--of the -Free Software Foundation and other authors who decide to use it. You -can use it too, but we suggest you first think carefully about whether -this license or the ordinary General Public License is the better -strategy to use in any particular case, based on the explanations below. - - When we speak of free software, we are referring to freedom of use, -not price. Our General Public Licenses are designed to make sure that -you have the freedom to distribute copies of free software (and charge -for this service if you wish); that you receive source code or can get -it if you want it; that you can change the software and use pieces of -it in new free programs; and that you are informed that you can do -these things. - - To protect your rights, we need to make restrictions that forbid -distributors to deny you these rights or to ask you to surrender these -rights. These restrictions translate to certain responsibilities for -you if you distribute copies of the library or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link other code with the library, you must provide -complete object files to the recipients, so that they can relink them -with the library after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - We protect your rights with a two-step method: (1) we copyright the -library, and (2) we offer you this license, which gives you legal -permission to copy, distribute and/or modify the library. - - To protect each distributor, we want to make it very clear that -there is no warranty for the free library. Also, if the library is -modified by someone else and passed on, the recipients should know -that what they have is not the original version, so that the original -author's reputation will not be affected by problems that might be -introduced by others. - - Finally, software patents pose a constant threat to the existence of -any free program. We wish to make sure that a company cannot -effectively restrict the users of a free program by obtaining a -restrictive license from a patent holder. Therefore, we insist that -any patent license obtained for a version of the library must be -consistent with the full freedom of use specified in this license. - - Most GNU software, including some libraries, is covered by the -ordinary GNU General Public License. This license, the GNU Lesser -General Public License, applies to certain designated libraries, and -is quite different from the ordinary General Public License. We use -this license for certain libraries in order to permit linking those -libraries into non-free programs. - - When a program is linked with a library, whether statically or using -a shared library, the combination of the two is legally speaking a -combined work, a derivative of the original library. The ordinary -General Public License therefore permits such linking only if the -entire combination fits its criteria of freedom. The Lesser General -Public License permits more lax criteria for linking other code with -the library. - - We call this license the "Lesser" General Public License because it -does Less to protect the user's freedom than the ordinary General -Public License. It also provides other free software developers Less -of an advantage over competing non-free programs. These disadvantages -are the reason we use the ordinary General Public License for many -libraries. However, the Lesser license provides advantages in certain -special circumstances. - - For example, on rare occasions, there may be a special need to -encourage the widest possible use of a certain library, so that it becomes -a de-facto standard. To achieve this, non-free programs must be -allowed to use the library. A more frequent case is that a free -library does the same job as widely used non-free libraries. In this -case, there is little to gain by limiting the free library to free -software only, so we use the Lesser General Public License. - - In other cases, permission to use a particular library in non-free -programs enables a greater number of people to use a large body of -free software. For example, permission to use the GNU C Library in -non-free programs enables many more people to use the whole GNU -operating system, as well as its variant, the GNU/Linux operating -system. - - Although the Lesser General Public License is Less protective of the -users' freedom, it does ensure that the user of a program that is -linked with the Library has the freedom and the wherewithal to run -that program using a modified version of the Library. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, whereas the latter must -be combined with the library in order to run. - - GNU LESSER GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library or other -program which contains a notice placed by the copyright holder or -other authorized party saying it may be distributed under the terms of -this Lesser General Public License (also called "this License"). -Each licensee is addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control compilation -and installation of the library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also combine or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (1) uses at run time a - copy of the library already present on the user's computer system, - rather than copying library functions into the executable, and (2) - will operate properly with a modified version of the library, if - the user installs one, as long as the modified version is - interface-compatible with the version that the work was made with. - - c) Accompany the work with a written offer, valid for at - least three years, to give the same user the materials - specified in Subsection 6a, above, for a charge no more - than the cost of performing this distribution. - - d) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - e) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the materials to be distributed need not include anything that is -normally distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library is void, and will automatically terminate your -rights under this License. However, parties who have received copies, -or rights, from you under this License will not have their licenses -terminated so long as such parties remain in full compliance. - - 9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties with -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply, -and the section as a whole is intended to apply in other circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may add -an explicit geographical distribution limitation excluding those countries, -so that distribution is permitted only in or among countries not thus -excluded. In such case, this License incorporates the limitation as if -written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Lesser General Public License from time to time. -Such new versions will be similar in spirit to the present version, -but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU -FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms of the -ordinary General Public License). - - To apply these terms, attach the following notices to the library. It is -safest to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least the -"copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - USA - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the library, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James Random - Hacker. - - , 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! diff --git a/lib/Servo-master/README.adoc b/lib/Servo-master/README.adoc deleted file mode 100644 index b16b16b..0000000 --- a/lib/Servo-master/README.adoc +++ /dev/null @@ -1,13 +0,0 @@ -:repository-owner: arduino-libraries -:repository-name: Servo - -= {repository-name} Library for Arduino = - -image:https://github.com/{repository-owner}/{repository-name}/actions/workflows/check-arduino.yml/badge.svg["Check Arduino status", link="https://github.com/{repository-owner}/{repository-name}/actions/workflows/check-arduino.yml"] -image:https://github.com/{repository-owner}/{repository-name}/actions/workflows/compile-examples.yml/badge.svg["Compile Examples status", link="https://github.com/{repository-owner}/{repository-name}/actions/workflows/compile-examples.yml"] -image:https://github.com/{repository-owner}/{repository-name}/actions/workflows/spell-check.yml/badge.svg["Spell Check status", link="https://github.com/{repository-owner}/{repository-name}/actions/workflows/spell-check.yml"] - -This library allows an Arduino board to control RC (hobby) servo motors. - -For more information about this library please visit us at -https://www.arduino.cc/reference/en/libraries/servo/ diff --git a/lib/Servo-master/docs/api.md b/lib/Servo-master/docs/api.md deleted file mode 100644 index fc54c9d..0000000 --- a/lib/Servo-master/docs/api.md +++ /dev/null @@ -1,181 +0,0 @@ -# Servo library - -## Methods - -### `attach()` - -Attach the Servo variable to a pin. Note that in Arduino 0016 and earlier, the Servo library supports servos on only two pins: 9 and 10. - -#### Syntax - -``` -servo.attach(pin) -servo.attach(pin, min, max) -``` - -#### Parameters - -* _servo_: a variable of type `Servo` -* _pin_: the number of the pin that the servo is attached to -* _min_ (optional): the pulse width, in microseconds, corresponding to the minimum (0 degree) angle on the servo (defaults to 544) -* _max_ (optional): the pulse width, in microseconds, corresponding to the maximum (180 degree) angle on the servo (defaults to 2400) - -#### Example - -``` -#include - -Servo myservo; - -void setup() -{ - myservo.attach(9); -} - -void loop() {} -``` - -#### See also - -* [attached()](#attached) -* [detach()](#detach) - -### `write()` - -Writes a value to the servo, controlling the shaft accordingly. On a standard servo, this will set the angle of the shaft (in degrees), moving the shaft to that orientation. On a continuous rotation servo, this will set the speed of the servo (with 0 being full-speed in one direction, 180 being full speed in the other, and a value near 90 being no movement). - -#### Syntax - -``` -servo.write(angle) -``` - -#### Parameters - -* _servo_: a variable of type Servo -* _angle_: the value to write to the servo, from 0 to 180 - -#### Example - -```` -#include - -Servo myservo; - -void setup() -{ - myservo.attach(9); - myservo.write(90); // set servo to mid-point -} - -void loop() {} -```` -#### See also - -* [attach()](#attach) -* [read()](#read) - -### `writeMicroseconds()` - -Writes a value in microseconds (us) to the servo, controlling the shaft accordingly. On a standard servo, this will set the angle of the shaft. On standard servos a parameter value of 1000 is fully counter-clockwise, 2000 is fully clockwise, and 1500 is in the middle. - -Note that some manufactures do not follow this standard very closely so that servos often respond to values between 700 and 2300. Feel free to increase these endpoints until the servo no longer continues to increase its range. Note however that attempting to drive a servo past its endpoints (often indicated by a growling sound) is a high-current state, and should be avoided. - -Continuous-rotation servos will respond to the writeMicrosecond function in an analogous manner to the write function. - -#### Syntax - -```` -servo.writeMicroseconds(us) -```` - -#### Parameters - -* _servo_: a variable of type Servo -* _us_: the value of the parameter in microseconds (int) - -#### Example - -```` -#include - -Servo myservo; - -void setup() -{ - myservo.attach(9); - myservo.writeMicroseconds(1500); // set servo to mid-point -} - -void loop() {} -```` - -#### See also - -* [attach()](#attach) -* [read()](#read) - - -### `read()` - -Read the current angle of the servo (the value passed to the last call to [write()](#write)). - -#### Syntax - -```` -servo.read() -```` - -#### Parameters - -* _servo_: a variable of type `Servo` - -#### Returns - -The angle of the servo, from 0 to 180 degrees. - -#### See also - -* [write()](#write) - -### `attached()` - -Check whether the Servo variable is attached to a pin. - -#### Syntax - -``` -servo.attached() -``` - -#### Parameters - -* _servo_: a variable of type `Servo` - -#### Returns - -`true` if the servo is attached to pin; `false` otherwise. - -#### See also - -* [attach()](#attach) -* [detach()](#detach) - -### `detach()` - -Detach the Servo variable from its pin. If all Servo variables are detached, then pins 9 and 10 can be used for PWM output with [analogWrite()](https://www.arduino.cc/reference/en/language/functions/analog-io/analogwrite/). - -#### Syntax - -``` -servo.detach() -``` - -#### Parameters - -* _servo_: a variable of type `Servo` - -#### See also - -* [attach()](#attach) -* [attached()](#attached) diff --git a/lib/Servo-master/docs/readme.md b/lib/Servo-master/docs/readme.md deleted file mode 100644 index b986b14..0000000 --- a/lib/Servo-master/docs/readme.md +++ /dev/null @@ -1,21 +0,0 @@ -# Servo library - - -This library allows an Arduino board to control RC (hobby) servo motors. Servos have integrated gears and a shaft that can be precisely controlled. Standard servos allow the shaft to be positioned at various angles, usually between 0 and 180 degrees. Continuous rotation servos allow the rotation of the shaft to be set to various speeds. - -The Servo library supports up to 12 motors on most Arduino boards and 48 on the Arduino Mega. On boards other than the Mega, use of the library disables `analogWrite()` (PWM) functionality on pins 9 and 10, whether or not there is a Servo on those pins. On the Mega, up to 12 servos can be used without interfering with PWM functionality; use of 12 to 23 motors will disable PWM on pins 11 and 12. - -To use this library: - -``` -#include -``` - -## Circuit - -Servo motors have three wires: power, ground, and signal. The power wire is typically red, and should be connected to the 5V pin on the Arduino board. The ground wire is typically black or brown and should be connected to a ground pin on the Arduino board. The signal pin is typically yellow, orange or white and should be connected to a digital pin on the Arduino board. Note that servos draw considerable power, so if you need to drive more than one or two, you'll probably need to power them from a separate supply (i.e. not the 5V pin on your Arduino). Be sure to connect the grounds of the Arduino and external power supply together. - -## Examples - -* [Knob](https://www.arduino.cc/en/Tutorial/Knob): control the shaft of a servo motor by turning a potentiometer -* [Sweep](https://www.arduino.cc/en/Tutorial/LibraryExamples/Sweep): sweeps the shaft of a servo motor back and forth diff --git a/lib/Servo-master/examples/Knob/Knob.ino b/lib/Servo-master/examples/Knob/Knob.ino deleted file mode 100644 index 0015a46..0000000 --- a/lib/Servo-master/examples/Knob/Knob.ino +++ /dev/null @@ -1,26 +0,0 @@ -/* - Controlling a servo position using a potentiometer (variable resistor) - by Michal Rinott - - modified on 8 Nov 2013 - by Scott Fitzgerald - http://www.arduino.cc/en/Tutorial/Knob -*/ - -#include - -Servo myservo; // create servo object to control a servo - -int potpin = A0; // analog pin used to connect the potentiometer -int val; // variable to read the value from the analog pin - -void setup() { - myservo.attach(9); // attaches the servo on pin 9 to the servo object -} - -void loop() { - val = analogRead(potpin); // reads the value of the potentiometer (value between 0 and 1023) - val = map(val, 0, 1023, 0, 180); // scale it for use with the servo (value between 0 and 180) - myservo.write(val); // sets the servo position according to the scaled value - delay(15); // waits for the servo to get there -} diff --git a/lib/Servo-master/examples/Knob/images/knob_BB.png b/lib/Servo-master/examples/Knob/images/knob_BB.png deleted file mode 100644 index af398f3..0000000 Binary files a/lib/Servo-master/examples/Knob/images/knob_BB.png and /dev/null differ diff --git a/lib/Servo-master/examples/Knob/images/knob_schem.png b/lib/Servo-master/examples/Knob/images/knob_schem.png deleted file mode 100644 index a3825ad..0000000 Binary files a/lib/Servo-master/examples/Knob/images/knob_schem.png and /dev/null differ diff --git a/lib/Servo-master/examples/Knob/readme.md b/lib/Servo-master/examples/Knob/readme.md deleted file mode 100644 index 7dc37dd..0000000 --- a/lib/Servo-master/examples/Knob/readme.md +++ /dev/null @@ -1,35 +0,0 @@ -# Knob - -Control the position of a RC (hobby) [servo motor](http://en.wikipedia.org/wiki/Servo_motor#RC_servos) with your Arduino and a potentiometer. - -This example makes use of the Arduino `Servo` library. - -## Hardware Required - -* an Arduino board -* Servo motor -* 10k ohm potentiometer -* hook-up wires - -## Circuit - -Servo motors have three wires: power, ground, and signal. The power wire is typically red, and should be connected to the 5V pin on the Arduino board. The ground wire is typically black or brown and should be connected to a ground pin on the board. The signal pin is typically yellow or orange and should be connected to pin 9 on the board. - -The potentiometer should be wired so that its two outer pins are connected to power (+5V) and ground, and its middle pin is connected to analog input 0 on the board. - -![](images/knob_BB.png) - -(Images developed using Fritzing. For more circuit examples, see the [Fritzing project page](http://fritzing.org/projects/)) - -## Schematic - -![](images/knob_schem.png) - -## See also - -* [attach()](/docs/api.md#attach) -* [write()](/docs/api.md#write) -* [map()](https://www.arduino.cc/en/Reference/Map) -* [analogRead()](https://www.arduino.cc/en/Reference/AnalogRead) -* [Servo library reference](/docs/readme.md) -* [Sweep](../Sweep) - Sweep the shaft of a servo motor back and forth diff --git a/lib/Servo-master/examples/Sweep/Sweep.ino b/lib/Servo-master/examples/Sweep/Sweep.ino deleted file mode 100644 index e988bbd..0000000 --- a/lib/Servo-master/examples/Sweep/Sweep.ino +++ /dev/null @@ -1,31 +0,0 @@ -/* Sweep - by BARRAGAN - This example code is in the public domain. - - modified 8 Nov 2013 - by Scott Fitzgerald - https://www.arduino.cc/en/Tutorial/LibraryExamples/Sweep -*/ - -#include - -Servo myservo; // create servo object to control a servo -// twelve servo objects can be created on most boards - -int pos = 0; // variable to store the servo position - -void setup() { - myservo.attach(9); // attaches the servo on pin 9 to the servo object -} - -void loop() { - for (pos = 0; pos <= 180; pos += 1) { // goes from 0 degrees to 180 degrees - // in steps of 1 degree - myservo.write(pos); // tell servo to go to position in variable 'pos' - delay(15); // waits 15 ms for the servo to reach the position - } - for (pos = 180; pos >= 0; pos -= 1) { // goes from 180 degrees to 0 degrees - myservo.write(pos); // tell servo to go to position in variable 'pos' - delay(15); // waits 15 ms for the servo to reach the position - } -} diff --git a/lib/Servo-master/examples/Sweep/images/sweep_bb.png b/lib/Servo-master/examples/Sweep/images/sweep_bb.png deleted file mode 100644 index 336eb11..0000000 Binary files a/lib/Servo-master/examples/Sweep/images/sweep_bb.png and /dev/null differ diff --git a/lib/Servo-master/examples/Sweep/images/sweep_schem.png b/lib/Servo-master/examples/Sweep/images/sweep_schem.png deleted file mode 100644 index beac2fe..0000000 Binary files a/lib/Servo-master/examples/Sweep/images/sweep_schem.png and /dev/null differ diff --git a/lib/Servo-master/examples/Sweep/readme.md b/lib/Servo-master/examples/Sweep/readme.md deleted file mode 100644 index bb07d5a..0000000 --- a/lib/Servo-master/examples/Sweep/readme.md +++ /dev/null @@ -1,29 +0,0 @@ -# Sweep - -Sweeps the shaft of a RC [servo motor](http://en.wikipedia.org/wiki/Servo_motor#RC_servos) back and forth across 180 degrees. - -## Hardware Required - -* Arduino Board -* Servo Motor -* Hook-up wires - -## Circuit - -Servo motors have three wires: power, ground, and signal. The power wire is typically red, and should be connected to the 5V pin on the Arduino board. The ground wire is typically black or brown and should be connected to a ground pin on the board. The signal pin is typically yellow, orange or white and should be connected to pin 9 on the board. - -![](images/sweep_bb.png) - -(Images developed using Fritzing. For more circuit examples, see the [Fritzing project page](http://fritzing.org/projects/)) - -## Schematic - -![](images/sweep_schem.png) - -## See also - -* [attach()](/docs/api.md#attach) -* [write()](/docs/api.md#write) -* [map()](https://www.arduino.cc/en/Reference/Map) -* [Servo library reference](/docs/readme.md) -* [Knob](../Knob) - Control the position of a servo with a potentiometer diff --git a/lib/Servo-master/keywords.txt b/lib/Servo-master/keywords.txt deleted file mode 100644 index 0a7ca1e..0000000 --- a/lib/Servo-master/keywords.txt +++ /dev/null @@ -1,24 +0,0 @@ -####################################### -# Syntax Coloring Map Servo -####################################### - -####################################### -# Datatypes (KEYWORD1) -####################################### - -Servo KEYWORD1 Servo - -####################################### -# Methods and Functions (KEYWORD2) -####################################### -attach KEYWORD2 -detach KEYWORD2 -write KEYWORD2 -read KEYWORD2 -attached KEYWORD2 -writeMicroseconds KEYWORD2 -readMicroseconds KEYWORD2 - -####################################### -# Constants (LITERAL1) -####################################### diff --git a/lib/Servo-master/library.properties b/lib/Servo-master/library.properties deleted file mode 100644 index 57d24c8..0000000 --- a/lib/Servo-master/library.properties +++ /dev/null @@ -1,9 +0,0 @@ -name=Servo -version=1.1.8 -author=Michael Margolis, Arduino -maintainer=Arduino -sentence=Allows Arduino boards to control a variety of servo motors. -paragraph=This library can control a great number of servos.
It makes careful use of timers: the library can control 12 servos using only 1 timer.
On the Arduino Due you can control up to 60 servos. -category=Device Control -url=https://www.arduino.cc/reference/en/libraries/servo/ -architectures=avr,megaavr,sam,samd,nrf52,stm32f4,mbed,mbed_nano,mbed_portenta,mbed_rp2040 diff --git a/lib/Servo-master/src/Servo.h b/lib/Servo-master/src/Servo.h deleted file mode 100644 index 53ecb8e..0000000 --- a/lib/Servo-master/src/Servo.h +++ /dev/null @@ -1,123 +0,0 @@ -/* - Servo.h - Interrupt driven Servo library for Arduino using 16 bit timers- Version 2 - Copyright (c) 2009 Michael Margolis. All right reserved. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -/* - A servo is activated by creating an instance of the Servo class passing - the desired pin to the attach() method. - The servos are pulsed in the background using the value most recently - written using the write() method. - - Note that analogWrite of PWM on pins associated with the timer are - disabled when the first servo is attached. - Timers are seized as needed in groups of 12 servos - 24 servos use two - timers, 48 servos will use four. - The sequence used to seize timers is defined in timers.h - - The methods are: - - Servo - Class for manipulating servo motors connected to Arduino pins. - - attach(pin ) - Attaches a servo motor to an I/O pin. - attach(pin, min, max ) - Attaches to a pin setting min and max values in microseconds - default min is 544, max is 2400 - - write() - Sets the servo angle in degrees. (invalid angle that is valid as pulse in microseconds is treated as microseconds) - writeMicroseconds() - Sets the servo pulse width in microseconds - read() - Gets the last written servo pulse width as an angle between 0 and 180. - readMicroseconds() - Gets the last written servo pulse width in microseconds. (was read_us() in first release) - attached() - Returns true if there is a servo attached. - detach() - Stops an attached servos from pulsing its I/O pin. - */ - -#ifndef Servo_h -#define Servo_h - -#include - -/* - * Defines for 16 bit timers used with Servo library - * - * If _useTimerX is defined then TimerX is a 16 bit timer on the current board - * timer16_Sequence_t enumerates the sequence that the timers should be allocated - * _Nbr_16timers indicates how many 16 bit timers are available. - */ - -// Architecture specific include -#if defined(ARDUINO_ARCH_AVR) -#include "avr/ServoTimers.h" -#elif defined(ARDUINO_ARCH_SAM) -#include "sam/ServoTimers.h" -#elif defined(ARDUINO_ARCH_SAMD) -#include "samd/ServoTimers.h" -#elif defined(ARDUINO_ARCH_STM32F4) -#include "stm32f4/ServoTimers.h" -#elif defined(ARDUINO_ARCH_NRF52) -#include "nrf52/ServoTimers.h" -#elif defined(ARDUINO_ARCH_MEGAAVR) -#include "megaavr/ServoTimers.h" -#elif defined(ARDUINO_ARCH_MBED) -#include "mbed/ServoTimers.h" -#else -#error "This library only supports boards with an AVR, SAM, SAMD, NRF52 or STM32F4 processor." -#endif - -#define Servo_VERSION 2 // software version of this library - -#define MIN_PULSE_WIDTH 544 // the shortest pulse sent to a servo -#define MAX_PULSE_WIDTH 2400 // the longest pulse sent to a servo -#define DEFAULT_PULSE_WIDTH 1500 // default pulse width when servo is attached -#define REFRESH_INTERVAL 20000 // minimum time to refresh servos in microseconds - -#define SERVOS_PER_TIMER 12 // the maximum number of servos controlled by one timer -#define MAX_SERVOS (_Nbr_16timers * SERVOS_PER_TIMER) - -#define INVALID_SERVO 255 // flag indicating an invalid servo index - -#if !defined(ARDUINO_ARCH_STM32F4) - -typedef struct { - uint8_t nbr :6 ; // a pin number from 0 to 63 - uint8_t isActive :1 ; // true if this channel is enabled, pin not pulsed if false -} ServoPin_t ; - -typedef struct { - ServoPin_t Pin; - volatile unsigned int ticks; -} servo_t; - -class Servo -{ -public: - Servo(); - uint8_t attach(int pin); // attach the given pin to the next free channel, sets pinMode, returns channel number or INVALID_SERVO if failure - uint8_t attach(int pin, int min, int max); // as above but also sets min and max values for writes. - void detach(); - void write(int value); // if value is < 200 its treated as an angle, otherwise as pulse width in microseconds - void writeMicroseconds(int value); // Write pulse width in microseconds - int read(); // returns current pulse width as an angle between 0 and 180 degrees - int readMicroseconds(); // returns current pulse width in microseconds for this servo (was read_us() in first release) - bool attached(); // return true if this servo is attached, otherwise false -private: - uint8_t servoIndex; // index into the channel data for this servo - int8_t min; // minimum is this value times 4 added to MIN_PULSE_WIDTH - int8_t max; // maximum is this value times 4 added to MAX_PULSE_WIDTH -}; - -#endif -#endif diff --git a/lib/Servo-master/src/avr/Servo.cpp b/lib/Servo-master/src/avr/Servo.cpp deleted file mode 100644 index 11fecc5..0000000 --- a/lib/Servo-master/src/avr/Servo.cpp +++ /dev/null @@ -1,317 +0,0 @@ -/* - Servo.cpp - Interrupt driven Servo library for Arduino using 16 bit timers- Version 2 - Copyright (c) 2009 Michael Margolis. All right reserved. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if defined(ARDUINO_ARCH_AVR) - -#include -#include - -#include "Servo.h" - -#define usToTicks(_us) (( clockCyclesPerMicrosecond()* _us) / 8) // converts microseconds to tick (assumes prescale of 8) // 12 Aug 2009 -#define ticksToUs(_ticks) (( (unsigned)_ticks * 8)/ clockCyclesPerMicrosecond() ) // converts from ticks back to microseconds - - -#define TRIM_DURATION 2 // compensation ticks to trim adjust for digitalWrite delays // 12 August 2009 - -//#define NBR_TIMERS (MAX_SERVOS / SERVOS_PER_TIMER) - -static servo_t servos[MAX_SERVOS]; // static array of servo structures -static volatile int8_t Channel[_Nbr_16timers ]; // counter for the servo being pulsed for each timer (or -1 if refresh interval) - -uint8_t ServoCount = 0; // the total number of attached servos - - -// convenience macros -#define SERVO_INDEX_TO_TIMER(_servo_nbr) ((timer16_Sequence_t)(_servo_nbr / SERVOS_PER_TIMER)) // returns the timer controlling this servo -#define SERVO_INDEX_TO_CHANNEL(_servo_nbr) (_servo_nbr % SERVOS_PER_TIMER) // returns the index of the servo on this timer -#define SERVO_INDEX(_timer,_channel) ((_timer*SERVOS_PER_TIMER) + _channel) // macro to access servo index by timer and channel -#define SERVO(_timer,_channel) (servos[SERVO_INDEX(_timer,_channel)]) // macro to access servo class by timer and channel - -#define SERVO_MIN() (MIN_PULSE_WIDTH - this->min * 4) // minimum value in us for this servo -#define SERVO_MAX() (MAX_PULSE_WIDTH - this->max * 4) // maximum value in us for this servo - -/************ static functions common to all instances ***********************/ - -static inline void handle_interrupts(timer16_Sequence_t timer, volatile uint16_t *TCNTn, volatile uint16_t* OCRnA) -{ - if( Channel[timer] < 0 ) - *TCNTn = 0; // channel set to -1 indicated that refresh interval completed so reset the timer - else{ - if( SERVO_INDEX(timer,Channel[timer]) < ServoCount && SERVO(timer,Channel[timer]).Pin.isActive == true ) - digitalWrite( SERVO(timer,Channel[timer]).Pin.nbr,LOW); // pulse this channel low if activated - } - - Channel[timer]++; // increment to the next channel - if( SERVO_INDEX(timer,Channel[timer]) < ServoCount && Channel[timer] < SERVOS_PER_TIMER) { - *OCRnA = *TCNTn + SERVO(timer,Channel[timer]).ticks; - if(SERVO(timer,Channel[timer]).Pin.isActive == true) // check if activated - digitalWrite( SERVO(timer,Channel[timer]).Pin.nbr,HIGH); // its an active channel so pulse it high - } - else { - // finished all channels so wait for the refresh period to expire before starting over - if( ((unsigned)*TCNTn) + 4 < usToTicks(REFRESH_INTERVAL) ) // allow a few ticks to ensure the next OCR1A not missed - *OCRnA = (unsigned int)usToTicks(REFRESH_INTERVAL); - else - *OCRnA = *TCNTn + 4; // at least REFRESH_INTERVAL has elapsed - Channel[timer] = -1; // this will get incremented at the end of the refresh period to start again at the first channel - } -} - -#ifndef WIRING // Wiring pre-defines signal handlers so don't define any if compiling for the Wiring platform -// Interrupt handlers for Arduino -#if defined(_useTimer1) -SIGNAL (TIMER1_COMPA_vect) -{ - handle_interrupts(_timer1, &TCNT1, &OCR1A); -} -#endif - -#if defined(_useTimer3) -SIGNAL (TIMER3_COMPA_vect) -{ - handle_interrupts(_timer3, &TCNT3, &OCR3A); -} -#endif - -#if defined(_useTimer4) -SIGNAL (TIMER4_COMPA_vect) -{ - handle_interrupts(_timer4, &TCNT4, &OCR4A); -} -#endif - -#if defined(_useTimer5) -SIGNAL (TIMER5_COMPA_vect) -{ - handle_interrupts(_timer5, &TCNT5, &OCR5A); -} -#endif - -#elif defined WIRING -// Interrupt handlers for Wiring -#if defined(_useTimer1) -void Timer1Service() -{ - handle_interrupts(_timer1, &TCNT1, &OCR1A); -} -#endif -#if defined(_useTimer3) -void Timer3Service() -{ - handle_interrupts(_timer3, &TCNT3, &OCR3A); -} -#endif -#endif - - -static void initISR(timer16_Sequence_t timer) -{ -#if defined (_useTimer1) - if(timer == _timer1) { - TCCR1A = 0; // normal counting mode - TCCR1B = _BV(CS11); // set prescaler of 8 - TCNT1 = 0; // clear the timer count -#if defined(__AVR_ATmega8__)|| defined(__AVR_ATmega128__) - TIFR |= _BV(OCF1A); // clear any pending interrupts - TIMSK |= _BV(OCIE1A) ; // enable the output compare interrupt -#else - // here if not ATmega8 or ATmega128 - TIFR1 |= _BV(OCF1A); // clear any pending interrupts - TIMSK1 |= _BV(OCIE1A) ; // enable the output compare interrupt -#endif -#if defined(WIRING) - timerAttach(TIMER1OUTCOMPAREA_INT, Timer1Service); -#endif - } -#endif - -#if defined (_useTimer3) - if(timer == _timer3) { - TCCR3A = 0; // normal counting mode - TCCR3B = _BV(CS31); // set prescaler of 8 - TCNT3 = 0; // clear the timer count -#if defined(__AVR_ATmega128__) - TIFR |= _BV(OCF3A); // clear any pending interrupts - ETIMSK |= _BV(OCIE3A); // enable the output compare interrupt -#else - TIFR3 = _BV(OCF3A); // clear any pending interrupts - TIMSK3 = _BV(OCIE3A) ; // enable the output compare interrupt -#endif -#if defined(WIRING) - timerAttach(TIMER3OUTCOMPAREA_INT, Timer3Service); // for Wiring platform only -#endif - } -#endif - -#if defined (_useTimer4) - if(timer == _timer4) { - TCCR4A = 0; // normal counting mode - TCCR4B = _BV(CS41); // set prescaler of 8 - TCNT4 = 0; // clear the timer count - TIFR4 = _BV(OCF4A); // clear any pending interrupts - TIMSK4 = _BV(OCIE4A) ; // enable the output compare interrupt - } -#endif - -#if defined (_useTimer5) - if(timer == _timer5) { - TCCR5A = 0; // normal counting mode - TCCR5B = _BV(CS51); // set prescaler of 8 - TCNT5 = 0; // clear the timer count - TIFR5 = _BV(OCF5A); // clear any pending interrupts - TIMSK5 = _BV(OCIE5A) ; // enable the output compare interrupt - } -#endif -} - -static void finISR(timer16_Sequence_t timer) -{ - //disable use of the given timer -#if defined WIRING // Wiring - if(timer == _timer1) { - #if defined(__AVR_ATmega1281__)||defined(__AVR_ATmega2561__) - TIMSK1 &= ~_BV(OCIE1A) ; // disable timer 1 output compare interrupt - #else - TIMSK &= ~_BV(OCIE1A) ; // disable timer 1 output compare interrupt - #endif - timerDetach(TIMER1OUTCOMPAREA_INT); - } - else if(timer == _timer3) { - #if defined(__AVR_ATmega1281__)||defined(__AVR_ATmega2561__) - TIMSK3 &= ~_BV(OCIE3A); // disable the timer3 output compare A interrupt - #else - ETIMSK &= ~_BV(OCIE3A); // disable the timer3 output compare A interrupt - #endif - timerDetach(TIMER3OUTCOMPAREA_INT); - } -#else - //For Arduino - in future: call here to a currently undefined function to reset the timer - (void) timer; // squash "unused parameter 'timer' [-Wunused-parameter]" warning -#endif -} - -static boolean isTimerActive(timer16_Sequence_t timer) -{ - // returns true if any servo is active on this timer - for(uint8_t channel=0; channel < SERVOS_PER_TIMER; channel++) { - if(SERVO(timer,channel).Pin.isActive == true) - return true; - } - return false; -} - - -/****************** end of static functions ******************************/ - -Servo::Servo() -{ - if( ServoCount < MAX_SERVOS) { - this->servoIndex = ServoCount++; // assign a servo index to this instance - servos[this->servoIndex].ticks = usToTicks(DEFAULT_PULSE_WIDTH); // store default values - 12 Aug 2009 - } - else - this->servoIndex = INVALID_SERVO ; // too many servos -} - -uint8_t Servo::attach(int pin) -{ - return this->attach(pin, MIN_PULSE_WIDTH, MAX_PULSE_WIDTH); -} - -uint8_t Servo::attach(int pin, int min, int max) -{ - if(this->servoIndex < MAX_SERVOS ) { - pinMode( pin, OUTPUT) ; // set servo pin to output - servos[this->servoIndex].Pin.nbr = pin; - // todo min/max check: abs(min - MIN_PULSE_WIDTH) /4 < 128 - this->min = (MIN_PULSE_WIDTH - min)/4; //resolution of min/max is 4 us - this->max = (MAX_PULSE_WIDTH - max)/4; - // initialize the timer if it has not already been initialized - timer16_Sequence_t timer = SERVO_INDEX_TO_TIMER(servoIndex); - if(isTimerActive(timer) == false) - initISR(timer); - servos[this->servoIndex].Pin.isActive = true; // this must be set after the check for isTimerActive - } - return this->servoIndex ; -} - -void Servo::detach() -{ - servos[this->servoIndex].Pin.isActive = false; - timer16_Sequence_t timer = SERVO_INDEX_TO_TIMER(servoIndex); - if(isTimerActive(timer) == false) { - finISR(timer); - } -} - -void Servo::write(int value) -{ - if(value < MIN_PULSE_WIDTH) - { // treat values less than 544 as angles in degrees (valid values in microseconds are handled as microseconds) - if(value < 0) value = 0; - if(value > 180) value = 180; - value = map(value, 0, 180, SERVO_MIN(), SERVO_MAX()); - } - this->writeMicroseconds(value); -} - -void Servo::writeMicroseconds(int value) -{ - // calculate and store the values for the given channel - byte channel = this->servoIndex; - if( (channel < MAX_SERVOS) ) // ensure channel is valid - { - if( value < SERVO_MIN() ) // ensure pulse width is valid - value = SERVO_MIN(); - else if( value > SERVO_MAX() ) - value = SERVO_MAX(); - - value = value - TRIM_DURATION; - value = usToTicks(value); // convert to ticks after compensating for interrupt overhead - 12 Aug 2009 - - uint8_t oldSREG = SREG; - cli(); - servos[channel].ticks = value; - SREG = oldSREG; - } -} - -int Servo::read() // return the value as degrees -{ - return map( this->readMicroseconds()+1, SERVO_MIN(), SERVO_MAX(), 0, 180); -} - -int Servo::readMicroseconds() -{ - unsigned int pulsewidth; - if( this->servoIndex != INVALID_SERVO ) - pulsewidth = ticksToUs(servos[this->servoIndex].ticks) + TRIM_DURATION ; // 12 aug 2009 - else - pulsewidth = 0; - - return pulsewidth; -} - -bool Servo::attached() -{ - return servos[this->servoIndex].Pin.isActive ; -} - -#endif // ARDUINO_ARCH_AVR diff --git a/lib/Servo-master/src/avr/ServoTimers.h b/lib/Servo-master/src/avr/ServoTimers.h deleted file mode 100644 index 8a35c59..0000000 --- a/lib/Servo-master/src/avr/ServoTimers.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - Servo.h - Interrupt driven Servo library for Arduino using 16 bit timers- Version 2 - Copyright (c) 2009 Michael Margolis. All right reserved. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -/* - * Defines for 16 bit timers used with Servo library - * - * If _useTimerX is defined then TimerX is a 16 bit timer on the current board - * timer16_Sequence_t enumerates the sequence that the timers should be allocated - * _Nbr_16timers indicates how many 16 bit timers are available. - */ - -/** - * AVR Only definitions - * -------------------- - */ - -// Say which 16 bit timers can be used and in what order -#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) -#define _useTimer5 -#define _useTimer1 -#define _useTimer3 -#define _useTimer4 -typedef enum { _timer5, _timer1, _timer3, _timer4, _Nbr_16timers } timer16_Sequence_t; - -#elif defined(__AVR_ATmega32U4__) -#define _useTimer1 -typedef enum { _timer1, _Nbr_16timers } timer16_Sequence_t; - -#elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__) -#define _useTimer3 -#define _useTimer1 -typedef enum { _timer3, _timer1, _Nbr_16timers } timer16_Sequence_t; - -#elif defined(__AVR_ATmega128__) || defined(__AVR_ATmega1281__) || defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega2561__) -#define _useTimer3 -#define _useTimer1 -typedef enum { _timer3, _timer1, _Nbr_16timers } timer16_Sequence_t; - -#else // everything else -#define _useTimer1 -typedef enum { _timer1, _Nbr_16timers } timer16_Sequence_t; -#endif diff --git a/lib/Servo-master/src/mbed/Servo.cpp b/lib/Servo-master/src/mbed/Servo.cpp deleted file mode 100644 index efb67f9..0000000 --- a/lib/Servo-master/src/mbed/Servo.cpp +++ /dev/null @@ -1,139 +0,0 @@ -#if defined(ARDUINO_ARCH_MBED) - -#include -#include -#include - -#if defined __has_include -# if __has_include ("pinDefinitions.h") -# include "pinDefinitions.h" -# endif -#endif - -class ServoImpl { - mbed::DigitalOut *pin; - mbed::Timeout timeout; // calls a callback once when a timeout expires - mbed::Ticker ticker; // calls a callback repeatedly with a timeout - -public: - ServoImpl(PinName _pin) { - pin = new mbed::DigitalOut(_pin); - } - - ~ServoImpl() { - ticker.detach(); - timeout.detach(); - delete pin; - } - - void start(uint32_t duration_us) { - duration = duration_us; - ticker.attach(mbed::callback(this, &ServoImpl::call), 0.02f); - } - - void call() { - timeout.attach(mbed::callback(this, &ServoImpl::toggle), duration / 1e6); - toggle(); - } - - void toggle() { - *pin = !*pin; - } - - int32_t duration = -1; -}; - -static ServoImpl* servos[MAX_SERVOS]; // static array of servo structures -uint8_t ServoCount = 0; // the total number of attached servos - -#define SERVO_MIN() (MIN_PULSE_WIDTH - this->min) // minimum value in us for this servo -#define SERVO_MAX() (MAX_PULSE_WIDTH - this->max) // maximum value in us for this servo - -#define TRIM_DURATION 15 //callback overhead (35 us) -> 15 us if toggle() is called after starting the timeout - -Servo::Servo() -{ - if (ServoCount < MAX_SERVOS) { - this->servoIndex = ServoCount++; - } else { - this->servoIndex = INVALID_SERVO; // too many servos - } -} - -uint8_t Servo::attach(int pin) -{ - return this->attach(pin, MIN_PULSE_WIDTH, MAX_PULSE_WIDTH); -} - -uint8_t Servo::attach(int pin, int min, int max) -{ - pinMode(pin, OUTPUT); // set servo pin to output - servos[this->servoIndex] = new ServoImpl(digitalPinToPinName(pin)); - - this->min = (MIN_PULSE_WIDTH - min); - this->max = (MAX_PULSE_WIDTH - max); - return this->servoIndex; -} - -void Servo::detach() -{ - delete servos[this->servoIndex]; - servos[this->servoIndex] = NULL; -} - -void Servo::write(int value) -{ - // treat values less than 544 as angles in degrees (valid values in microseconds are handled as microseconds) - if (value < MIN_PULSE_WIDTH) - { - if (value < 0) - value = 0; - else if (value > 180) - value = 180; - - value = map(value, 0, 180, SERVO_MIN(), SERVO_MAX()); - } - writeMicroseconds(value); -} - -void Servo::writeMicroseconds(int value) -{ - if (!servos[this->servoIndex]) { - return; - } - // calculate and store the values for the given channel - byte channel = this->servoIndex; - if( (channel < MAX_SERVOS) ) // ensure channel is valid - { - if (value < SERVO_MIN()) // ensure pulse width is valid - value = SERVO_MIN(); - else if (value > SERVO_MAX()) - value = SERVO_MAX(); - - value = value - TRIM_DURATION; - if (servos[this->servoIndex]->duration == -1) { - servos[this->servoIndex]->start(value); - } - servos[this->servoIndex]->duration = value; - } -} - -int Servo::read() // return the value as degrees -{ - return map(readMicroseconds(), SERVO_MIN(), SERVO_MAX(), 0, 180); -} - -int Servo::readMicroseconds() -{ - if (!servos[this->servoIndex]) { - return 0; - } - return servos[this->servoIndex]->duration; -} - -bool Servo::attached() -{ - return servos[this->servoIndex] != NULL; -} - -#endif diff --git a/lib/Servo-master/src/mbed/ServoTimers.h b/lib/Servo-master/src/mbed/ServoTimers.h deleted file mode 100644 index 47f226f..0000000 --- a/lib/Servo-master/src/mbed/ServoTimers.h +++ /dev/null @@ -1 +0,0 @@ -#define _Nbr_16timers 32 diff --git a/lib/Servo-master/src/megaavr/Servo.cpp b/lib/Servo-master/src/megaavr/Servo.cpp deleted file mode 100644 index 59b3e44..0000000 --- a/lib/Servo-master/src/megaavr/Servo.cpp +++ /dev/null @@ -1,214 +0,0 @@ -#if defined(ARDUINO_ARCH_MEGAAVR) - -#include -#include - -#define usToTicks(_us) ((clockCyclesPerMicrosecond() / 16 * _us) / 4) // converts microseconds to tick -#define ticksToUs(_ticks) (((unsigned) _ticks * 16) / (clockCyclesPerMicrosecond() / 4)) // converts from ticks back to microseconds - -#define TRIM_DURATION 5 // compensation ticks to trim adjust for digitalWrite delays - -static servo_t servos[MAX_SERVOS]; // static array of servo structures - -uint8_t ServoCount = 0; // the total number of attached servos - -static volatile int8_t currentServoIndex[_Nbr_16timers]; // index for the servo being pulsed for each timer (or -1 if refresh interval) - -// convenience macros -#define SERVO_INDEX_TO_TIMER(_servo_nbr) ((timer16_Sequence_t)(_servo_nbr / SERVOS_PER_TIMER)) // returns the timer controlling this servo -#define SERVO_INDEX_TO_CHANNEL(_servo_nbr) (_servo_nbr % SERVOS_PER_TIMER) // returns the index of the servo on this timer -#define SERVO_INDEX(_timer,_channel) ((_timer*SERVOS_PER_TIMER) + _channel) // macro to access servo index by timer and channel -#define SERVO(_timer,_channel) (servos[SERVO_INDEX(_timer,_channel)]) // macro to access servo class by timer and channel - -#define SERVO_MIN() (MIN_PULSE_WIDTH - this->min * 4) // minimum value in us for this servo -#define SERVO_MAX() (MAX_PULSE_WIDTH - this->max * 4) // maximum value in us for this servo - -#undef REFRESH_INTERVAL -#define REFRESH_INTERVAL 16000 - -void ServoHandler(int timer) -{ - if (currentServoIndex[timer] < 0) { - // Write compare register - _timer->CCMP = 0; - } else { - if (SERVO_INDEX(timer, currentServoIndex[timer]) < ServoCount && SERVO(timer, currentServoIndex[timer]).Pin.isActive == true) { - digitalWrite(SERVO(timer, currentServoIndex[timer]).Pin.nbr, LOW); // pulse this channel low if activated - } - } - - // Select the next servo controlled by this timer - currentServoIndex[timer]++; - - if (SERVO_INDEX(timer, currentServoIndex[timer]) < ServoCount && currentServoIndex[timer] < SERVOS_PER_TIMER) { - if (SERVO(timer, currentServoIndex[timer]).Pin.isActive == true) { // check if activated - digitalWrite(SERVO(timer, currentServoIndex[timer]).Pin.nbr, HIGH); // it's an active channel so pulse it high - } - - // Get the counter value - uint16_t tcCounterValue = 0; //_timer->CCMP; - _timer->CCMP = (uint16_t) (tcCounterValue + SERVO(timer, currentServoIndex[timer]).ticks); - } - else { - // finished all channels so wait for the refresh period to expire before starting over - - // Get the counter value - uint16_t tcCounterValue = _timer->CCMP; - - if (tcCounterValue + 4UL < usToTicks(REFRESH_INTERVAL)) { // allow a few ticks to ensure the next OCR1A not missed - _timer->CCMP = (uint16_t) usToTicks(REFRESH_INTERVAL); - } - else { - _timer->CCMP = (uint16_t) (tcCounterValue + 4UL); // at least REFRESH_INTERVAL has elapsed - } - - currentServoIndex[timer] = -1; // this will get incremented at the end of the refresh period to start again at the first channel - } - - /* Clear flag */ - _timer->INTFLAGS = TCB_CAPT_bm; -} - -#if defined USE_TIMERB0 -ISR(TCB0_INT_vect) -#elif defined USE_TIMERB1 -ISR(TCB1_INT_vect) -#elif defined USE_TIMERB2 -ISR(TCB2_INT_vect) -#endif -{ - ServoHandler(0); -} - -static void initISR(timer16_Sequence_t timer) -{ - //TCA0.SINGLE.CTRLA = (TCA_SINGLE_CLKSEL_DIV16_gc) | (TCA_SINGLE_ENABLE_bm); - - _timer->CTRLA = TCB_CLKSEL_CLKTCA_gc; - // Timer to Periodic interrupt mode - // This write will also disable any active PWM outputs - _timer->CTRLB = TCB_CNTMODE_INT_gc; - // Enable interrupt - _timer->INTCTRL = TCB_CAPTEI_bm; - // Enable timer - _timer->CTRLA |= TCB_ENABLE_bm; -} - -static void finISR(timer16_Sequence_t timer) -{ - // Disable interrupt - _timer->INTCTRL = 0; -} - -static boolean isTimerActive(timer16_Sequence_t timer) -{ - // returns true if any servo is active on this timer - for(uint8_t channel=0; channel < SERVOS_PER_TIMER; channel++) { - if(SERVO(timer,channel).Pin.isActive == true) - return true; - } - return false; -} - -/****************** end of static functions ******************************/ - -Servo::Servo() -{ - if (ServoCount < MAX_SERVOS) { - this->servoIndex = ServoCount++; // assign a servo index to this instance - servos[this->servoIndex].ticks = usToTicks(DEFAULT_PULSE_WIDTH); // store default values - } else { - this->servoIndex = INVALID_SERVO; // too many servos - } -} - -uint8_t Servo::attach(int pin) -{ - return this->attach(pin, MIN_PULSE_WIDTH, MAX_PULSE_WIDTH); -} - -uint8_t Servo::attach(int pin, int min, int max) -{ - timer16_Sequence_t timer; - - if (this->servoIndex < MAX_SERVOS) { - pinMode(pin, OUTPUT); // set servo pin to output - servos[this->servoIndex].Pin.nbr = pin; - // todo min/max check: abs(min - MIN_PULSE_WIDTH) /4 < 128 - this->min = (MIN_PULSE_WIDTH - min)/4; //resolution of min/max is 4 us - this->max = (MAX_PULSE_WIDTH - max)/4; - // initialize the timer if it has not already been initialized - timer = SERVO_INDEX_TO_TIMER(servoIndex); - if (isTimerActive(timer) == false) { - initISR(timer); - } - servos[this->servoIndex].Pin.isActive = true; // this must be set after the check for isTimerActive - } - return this->servoIndex; -} - -void Servo::detach() -{ - timer16_Sequence_t timer; - - servos[this->servoIndex].Pin.isActive = false; - timer = SERVO_INDEX_TO_TIMER(servoIndex); - if(isTimerActive(timer) == false) { - finISR(timer); - } -} - -void Servo::write(int value) -{ - // treat values less than 544 as angles in degrees (valid values in microseconds are handled as microseconds) - if (value < MIN_PULSE_WIDTH) - { - if (value < 0) - value = 0; - else if (value > 180) - value = 180; - - value = map(value, 0, 180, SERVO_MIN(), SERVO_MAX()); - } - writeMicroseconds(value); -} - -void Servo::writeMicroseconds(int value) -{ - // calculate and store the values for the given channel - byte channel = this->servoIndex; - if( (channel < MAX_SERVOS) ) // ensure channel is valid - { - if (value < SERVO_MIN()) // ensure pulse width is valid - value = SERVO_MIN(); - else if (value > SERVO_MAX()) - value = SERVO_MAX(); - - value = value - TRIM_DURATION; - value = usToTicks(value); // convert to ticks after compensating for interrupt overhead - servos[channel].ticks = value; - } -} - -int Servo::read() // return the value as degrees -{ - return map(readMicroseconds()+1, SERVO_MIN(), SERVO_MAX(), 0, 180); -} - -int Servo::readMicroseconds() -{ - unsigned int pulsewidth; - if (this->servoIndex != INVALID_SERVO) - pulsewidth = ticksToUs(servos[this->servoIndex].ticks) + TRIM_DURATION; - else - pulsewidth = 0; - - return pulsewidth; -} - -bool Servo::attached() -{ - return servos[this->servoIndex].Pin.isActive; -} - -#endif diff --git a/lib/Servo-master/src/megaavr/ServoTimers.h b/lib/Servo-master/src/megaavr/ServoTimers.h deleted file mode 100644 index 56746dc..0000000 --- a/lib/Servo-master/src/megaavr/ServoTimers.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - Copyright (c) 2018 Arduino LLC. All right reserved. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -/* - * Defines for 16 bit timers used with Servo library - * - */ - -#ifndef __SERVO_TIMERS_H__ -#define __SERVO_TIMERS_H__ - -#include - -//#define USE_TIMERB1 // interferes with PWM on pin 3 -#define USE_TIMERB2 // interferes with PWM on pin 11 -//#define USE_TIMERB0 // interferes with PWM on pin 6 - -#if !defined(USE_TIMERB1) && !defined(USE_TIMERB2) && !defined(USE_TIMERB0) - # error "No timers allowed for Servo" - /* Please uncomment a timer above and rebuild */ -#endif - -static volatile TCB_t* _timer = -#if defined(USE_TIMERB0) -&TCB0; -#endif -#if defined(USE_TIMERB1) -&TCB1; -#endif -#if defined(USE_TIMERB2) -&TCB2; -#endif - -typedef enum { - timer0, - _Nbr_16timers } timer16_Sequence_t; - - -#endif /* __SERVO_TIMERS_H__ */ diff --git a/lib/Servo-master/src/nrf52/Servo.cpp b/lib/Servo-master/src/nrf52/Servo.cpp deleted file mode 100644 index 72bd504..0000000 --- a/lib/Servo-master/src/nrf52/Servo.cpp +++ /dev/null @@ -1,134 +0,0 @@ -/* - Copyright (c) 2016 Arduino. All right reserved. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#if defined(ARDUINO_ARCH_NRF52) - -#include -#include - - -static servo_t servos[MAX_SERVOS]; // static array of servo structures - -uint8_t ServoCount = 0; // the total number of attached servos - - - -uint32_t group_pins[3][NRF_PWM_CHANNEL_COUNT]={{NRF_PWM_PIN_NOT_CONNECTED, NRF_PWM_PIN_NOT_CONNECTED, NRF_PWM_PIN_NOT_CONNECTED, NRF_PWM_PIN_NOT_CONNECTED}, {NRF_PWM_PIN_NOT_CONNECTED, NRF_PWM_PIN_NOT_CONNECTED, NRF_PWM_PIN_NOT_CONNECTED, NRF_PWM_PIN_NOT_CONNECTED}, {NRF_PWM_PIN_NOT_CONNECTED, NRF_PWM_PIN_NOT_CONNECTED, NRF_PWM_PIN_NOT_CONNECTED, NRF_PWM_PIN_NOT_CONNECTED}}; -static uint16_t seq_values[3][NRF_PWM_CHANNEL_COUNT]={{0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}; - -Servo::Servo() -{ - if (ServoCount < MAX_SERVOS) { - this->servoIndex = ServoCount++; // assign a servo index to this instance - } else { - this->servoIndex = INVALID_SERVO; // too many servos - } - -} - -uint8_t Servo::attach(int pin) -{ - - return this->attach(pin, 0, 2500); -} - - -uint8_t Servo::attach(int pin, int min, int max) -{ - int servo_min, servo_max; - if (this->servoIndex < MAX_SERVOS) { - pinMode(pin, OUTPUT); // set servo pin to output - servos[this->servoIndex].Pin.nbr = pin; - - if(min < servo_min) min = servo_min; - if (max > servo_max) max = servo_max; - this->min = min; - this->max = max; - - servos[this->servoIndex].Pin.isActive = true; - - } - return this->servoIndex; -} - -void Servo::detach() -{ - servos[this->servoIndex].Pin.isActive = false; -} - - -void Servo::write(int value) -{ - if (value < 0) - value = 0; - else if (value > 180) - value = 180; - value = map(value, 0, 180, MIN_PULSE, MAX_PULSE); - - writeMicroseconds(value); -} - - -void Servo::writeMicroseconds(int value) -{ - uint8_t channel, instance; - uint8_t pin = servos[this->servoIndex].Pin.nbr; - //instance of PWM module is MSB - look at VWariant.h - instance=(g_APinDescription[pin].ulPWMChannel & 0xF0)/16; - //index of PWM channel is LSB - look at VWariant.h - channel=g_APinDescription[pin].ulPWMChannel & 0x0F; - group_pins[instance][channel]=g_APinDescription[pin].ulPin; - NRF_PWM_Type * PWMInstance = instance == 0 ? NRF_PWM0 : (instance == 1 ? NRF_PWM1 : NRF_PWM2); - //configure PWM instance and enable it - seq_values[instance][channel]= value | 0x8000; - nrf_pwm_sequence_t const seq={ - seq_values[instance], - NRF_PWM_VALUES_LENGTH(seq_values), - 0, - 0 - }; - nrf_pwm_pins_set(PWMInstance, group_pins[instance]); - nrf_pwm_enable(PWMInstance); - nrf_pwm_configure(PWMInstance, NRF_PWM_CLK_125kHz, NRF_PWM_MODE_UP, 2500); // 20ms - 50Hz - nrf_pwm_decoder_set(PWMInstance, NRF_PWM_LOAD_INDIVIDUAL, NRF_PWM_STEP_AUTO); - nrf_pwm_sequence_set(PWMInstance, 0, &seq); - nrf_pwm_loop_set(PWMInstance, 0UL); - nrf_pwm_task_trigger(PWMInstance, NRF_PWM_TASK_SEQSTART0); -} - -int Servo::read() // return the value as degrees -{ - return map(readMicroseconds(), MIN_PULSE, MAX_PULSE, 0, 180); -} - -int Servo::readMicroseconds() -{ - uint8_t channel, instance; - uint8_t pin=servos[this->servoIndex].Pin.nbr; - instance=(g_APinDescription[pin].ulPWMChannel & 0xF0)/16; - channel=g_APinDescription[pin].ulPWMChannel & 0x0F; - // remove the 16th bit we added before - return seq_values[instance][channel] & 0x7FFF; -} - -bool Servo::attached() -{ - return servos[this->servoIndex].Pin.isActive; -} - -#endif // ARDUINO_ARCH_NRF52 diff --git a/lib/Servo-master/src/nrf52/ServoTimers.h b/lib/Servo-master/src/nrf52/ServoTimers.h deleted file mode 100644 index f4fc176..0000000 --- a/lib/Servo-master/src/nrf52/ServoTimers.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - Copyright (c) 2016 Arduino. All right reserved. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -/* - * nRF52 doesn't use timer, but PWM. This file include definitions to keep - * compatibility with the Servo library standards. - */ - -#ifndef __SERVO_TIMERS_H__ -#define __SERVO_TIMERS_H__ - -/** - * nRF52 only definitions - * --------------------- - */ - -#define MIN_PULSE 55 -#define MAX_PULSE 284 - -// define one timer in order to have MAX_SERVOS = 12 -typedef enum { _timer1, _Nbr_16timers } timer16_Sequence_t; - -#endif // __SERVO_TIMERS_H__ diff --git a/lib/Servo-master/src/sam/Servo.cpp b/lib/Servo-master/src/sam/Servo.cpp deleted file mode 100644 index df5058f..0000000 --- a/lib/Servo-master/src/sam/Servo.cpp +++ /dev/null @@ -1,282 +0,0 @@ -/* - Copyright (c) 2013 Arduino LLC. All right reserved. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#if defined(ARDUINO_ARCH_SAM) - -#include -#include - -#define usToTicks(_us) (( clockCyclesPerMicrosecond() * _us) / 32) // converts microseconds to tick -#define ticksToUs(_ticks) (( (unsigned)_ticks * 32)/ clockCyclesPerMicrosecond() ) // converts from ticks back to microseconds - -#define TRIM_DURATION 2 // compensation ticks to trim adjust for digitalWrite delays - -static servo_t servos[MAX_SERVOS]; // static array of servo structures - -uint8_t ServoCount = 0; // the total number of attached servos - -static volatile int8_t Channel[_Nbr_16timers ]; // counter for the servo being pulsed for each timer (or -1 if refresh interval) - -// convenience macros -#define SERVO_INDEX_TO_TIMER(_servo_nbr) ((timer16_Sequence_t)(_servo_nbr / SERVOS_PER_TIMER)) // returns the timer controlling this servo -#define SERVO_INDEX_TO_CHANNEL(_servo_nbr) (_servo_nbr % SERVOS_PER_TIMER) // returns the index of the servo on this timer -#define SERVO_INDEX(_timer,_channel) ((_timer*SERVOS_PER_TIMER) + _channel) // macro to access servo index by timer and channel -#define SERVO(_timer,_channel) (servos[SERVO_INDEX(_timer,_channel)]) // macro to access servo class by timer and channel - -#define SERVO_MIN() (MIN_PULSE_WIDTH - this->min * 4) // minimum value in us for this servo -#define SERVO_MAX() (MAX_PULSE_WIDTH - this->max * 4) // maximum value in us for this servo - -/************ static functions common to all instances ***********************/ - -//------------------------------------------------------------------------------ -/// Interrupt handler for the TC0 channel 1. -//------------------------------------------------------------------------------ -void Servo_Handler(timer16_Sequence_t timer, Tc *pTc, uint8_t channel); -#if defined (_useTimer1) -void HANDLER_FOR_TIMER1(void) { - Servo_Handler(_timer1, TC_FOR_TIMER1, CHANNEL_FOR_TIMER1); -} -#endif -#if defined (_useTimer2) -void HANDLER_FOR_TIMER2(void) { - Servo_Handler(_timer2, TC_FOR_TIMER2, CHANNEL_FOR_TIMER2); -} -#endif -#if defined (_useTimer3) -void HANDLER_FOR_TIMER3(void) { - Servo_Handler(_timer3, TC_FOR_TIMER3, CHANNEL_FOR_TIMER3); -} -#endif -#if defined (_useTimer4) -void HANDLER_FOR_TIMER4(void) { - Servo_Handler(_timer4, TC_FOR_TIMER4, CHANNEL_FOR_TIMER4); -} -#endif -#if defined (_useTimer5) -void HANDLER_FOR_TIMER5(void) { - Servo_Handler(_timer5, TC_FOR_TIMER5, CHANNEL_FOR_TIMER5); -} -#endif - -void Servo_Handler(timer16_Sequence_t timer, Tc *tc, uint8_t channel) -{ - // clear interrupt - tc->TC_CHANNEL[channel].TC_SR; - if (Channel[timer] < 0) { - tc->TC_CHANNEL[channel].TC_CCR |= TC_CCR_SWTRG; // channel set to -1 indicated that refresh interval completed so reset the timer - } else { - if (SERVO_INDEX(timer,Channel[timer]) < ServoCount && SERVO(timer,Channel[timer]).Pin.isActive == true) { - digitalWrite(SERVO(timer,Channel[timer]).Pin.nbr, LOW); // pulse this channel low if activated - } - } - - Channel[timer]++; // increment to the next channel - if( SERVO_INDEX(timer,Channel[timer]) < ServoCount && Channel[timer] < SERVOS_PER_TIMER) { - tc->TC_CHANNEL[channel].TC_RA = tc->TC_CHANNEL[channel].TC_CV + SERVO(timer,Channel[timer]).ticks; - if(SERVO(timer,Channel[timer]).Pin.isActive == true) { // check if activated - digitalWrite( SERVO(timer,Channel[timer]).Pin.nbr,HIGH); // its an active channel so pulse it high - } - } - else { - // finished all channels so wait for the refresh period to expire before starting over - if( (tc->TC_CHANNEL[channel].TC_CV) + 4 < usToTicks(REFRESH_INTERVAL) ) { // allow a few ticks to ensure the next OCR1A not missed - tc->TC_CHANNEL[channel].TC_RA = (unsigned int)usToTicks(REFRESH_INTERVAL); - } - else { - tc->TC_CHANNEL[channel].TC_RA = tc->TC_CHANNEL[channel].TC_CV + 4; // at least REFRESH_INTERVAL has elapsed - } - Channel[timer] = -1; // this will get incremented at the end of the refresh period to start again at the first channel - } -} - -static void _initISR(Tc *tc, uint32_t channel, uint32_t id, IRQn_Type irqn) -{ - pmc_enable_periph_clk(id); - TC_Configure(tc, channel, - TC_CMR_TCCLKS_TIMER_CLOCK3 | // MCK/32 - TC_CMR_WAVE | // Waveform mode - TC_CMR_WAVSEL_UP_RC ); // Counter running up and reset when equals to RC - - /* 84 MHz, MCK/32, for 1.5 ms: 3937 */ - TC_SetRA(tc, channel, 2625); // 1ms - - /* Configure and enable interrupt */ - NVIC_EnableIRQ(irqn); - // TC_IER_CPAS: RA Compare - tc->TC_CHANNEL[channel].TC_IER = TC_IER_CPAS; - - // Enables the timer clock and performs a software reset to start the counting - TC_Start(tc, channel); -} - -static void initISR(timer16_Sequence_t timer) -{ -#if defined (_useTimer1) - if (timer == _timer1) - _initISR(TC_FOR_TIMER1, CHANNEL_FOR_TIMER1, ID_TC_FOR_TIMER1, IRQn_FOR_TIMER1); -#endif -#if defined (_useTimer2) - if (timer == _timer2) - _initISR(TC_FOR_TIMER2, CHANNEL_FOR_TIMER2, ID_TC_FOR_TIMER2, IRQn_FOR_TIMER2); -#endif -#if defined (_useTimer3) - if (timer == _timer3) - _initISR(TC_FOR_TIMER3, CHANNEL_FOR_TIMER3, ID_TC_FOR_TIMER3, IRQn_FOR_TIMER3); -#endif -#if defined (_useTimer4) - if (timer == _timer4) - _initISR(TC_FOR_TIMER4, CHANNEL_FOR_TIMER4, ID_TC_FOR_TIMER4, IRQn_FOR_TIMER4); -#endif -#if defined (_useTimer5) - if (timer == _timer5) - _initISR(TC_FOR_TIMER5, CHANNEL_FOR_TIMER5, ID_TC_FOR_TIMER5, IRQn_FOR_TIMER5); -#endif -} - -static void finISR(timer16_Sequence_t timer) -{ -#if defined (_useTimer1) - TC_Stop(TC_FOR_TIMER1, CHANNEL_FOR_TIMER1); -#endif -#if defined (_useTimer2) - TC_Stop(TC_FOR_TIMER2, CHANNEL_FOR_TIMER2); -#endif -#if defined (_useTimer3) - TC_Stop(TC_FOR_TIMER3, CHANNEL_FOR_TIMER3); -#endif -#if defined (_useTimer4) - TC_Stop(TC_FOR_TIMER4, CHANNEL_FOR_TIMER4); -#endif -#if defined (_useTimer5) - TC_Stop(TC_FOR_TIMER5, CHANNEL_FOR_TIMER5); -#endif -} - - -static boolean isTimerActive(timer16_Sequence_t timer) -{ - // returns true if any servo is active on this timer - for(uint8_t channel=0; channel < SERVOS_PER_TIMER; channel++) { - if(SERVO(timer,channel).Pin.isActive == true) - return true; - } - return false; -} - -/****************** end of static functions ******************************/ - -Servo::Servo() -{ - if (ServoCount < MAX_SERVOS) { - this->servoIndex = ServoCount++; // assign a servo index to this instance - servos[this->servoIndex].ticks = usToTicks(DEFAULT_PULSE_WIDTH); // store default values - } else { - this->servoIndex = INVALID_SERVO; // too many servos - } -} - -uint8_t Servo::attach(int pin) -{ - return this->attach(pin, MIN_PULSE_WIDTH, MAX_PULSE_WIDTH); -} - -uint8_t Servo::attach(int pin, int min, int max) -{ - timer16_Sequence_t timer; - - if (this->servoIndex < MAX_SERVOS) { - pinMode(pin, OUTPUT); // set servo pin to output - servos[this->servoIndex].Pin.nbr = pin; - // todo min/max check: abs(min - MIN_PULSE_WIDTH) /4 < 128 - this->min = (MIN_PULSE_WIDTH - min)/4; //resolution of min/max is 4 us - this->max = (MAX_PULSE_WIDTH - max)/4; - // initialize the timer if it has not already been initialized - timer = SERVO_INDEX_TO_TIMER(servoIndex); - if (isTimerActive(timer) == false) { - initISR(timer); - } - servos[this->servoIndex].Pin.isActive = true; // this must be set after the check for isTimerActive - } - return this->servoIndex; -} - -void Servo::detach() -{ - timer16_Sequence_t timer; - - servos[this->servoIndex].Pin.isActive = false; - timer = SERVO_INDEX_TO_TIMER(servoIndex); - if(isTimerActive(timer) == false) { - finISR(timer); - } -} - -void Servo::write(int value) -{ - // treat values less than 544 as angles in degrees (valid values in microseconds are handled as microseconds) - if (value < MIN_PULSE_WIDTH) - { - if (value < 0) - value = 0; - else if (value > 180) - value = 180; - - value = map(value, 0, 180, SERVO_MIN(), SERVO_MAX()); - } - writeMicroseconds(value); -} - -void Servo::writeMicroseconds(int value) -{ - // calculate and store the values for the given channel - byte channel = this->servoIndex; - if( (channel < MAX_SERVOS) ) // ensure channel is valid - { - if (value < SERVO_MIN()) // ensure pulse width is valid - value = SERVO_MIN(); - else if (value > SERVO_MAX()) - value = SERVO_MAX(); - - value = value - TRIM_DURATION; - value = usToTicks(value); // convert to ticks after compensating for interrupt overhead - servos[channel].ticks = value; - } -} - -int Servo::read() // return the value as degrees -{ - return map(readMicroseconds()+1, SERVO_MIN(), SERVO_MAX(), 0, 180); -} - -int Servo::readMicroseconds() -{ - unsigned int pulsewidth; - if (this->servoIndex != INVALID_SERVO) - pulsewidth = ticksToUs(servos[this->servoIndex].ticks) + TRIM_DURATION; - else - pulsewidth = 0; - - return pulsewidth; -} - -bool Servo::attached() -{ - return servos[this->servoIndex].Pin.isActive; -} - -#endif // ARDUINO_ARCH_SAM diff --git a/lib/Servo-master/src/sam/ServoTimers.h b/lib/Servo-master/src/sam/ServoTimers.h deleted file mode 100644 index a7ee258..0000000 --- a/lib/Servo-master/src/sam/ServoTimers.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - Copyright (c) 2013 Arduino LLC. All right reserved. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -/* - * Defines for 16 bit timers used with Servo library - * - * If _useTimerX is defined then TimerX is a 16 bit timer on the current board - * timer16_Sequence_t enumerates the sequence that the timers should be allocated - * _Nbr_16timers indicates how many 16 bit timers are available. - */ - -/** - * SAM Only definitions - * -------------------- - */ - -// For SAM3X: -#define _useTimer1 -#define _useTimer2 -#define _useTimer3 -#define _useTimer4 -#define _useTimer5 - -/* - TC0, chan 0 => TC0_Handler - TC0, chan 1 => TC1_Handler - TC0, chan 2 => TC2_Handler - TC1, chan 0 => TC3_Handler - TC1, chan 1 => TC4_Handler - TC1, chan 2 => TC5_Handler - TC2, chan 0 => TC6_Handler - TC2, chan 1 => TC7_Handler - TC2, chan 2 => TC8_Handler - */ - -#if defined (_useTimer1) -#define TC_FOR_TIMER1 TC1 -#define CHANNEL_FOR_TIMER1 0 -#define ID_TC_FOR_TIMER1 ID_TC3 -#define IRQn_FOR_TIMER1 TC3_IRQn -#define HANDLER_FOR_TIMER1 TC3_Handler -#endif -#if defined (_useTimer2) -#define TC_FOR_TIMER2 TC1 -#define CHANNEL_FOR_TIMER2 1 -#define ID_TC_FOR_TIMER2 ID_TC4 -#define IRQn_FOR_TIMER2 TC4_IRQn -#define HANDLER_FOR_TIMER2 TC4_Handler -#endif -#if defined (_useTimer3) -#define TC_FOR_TIMER3 TC1 -#define CHANNEL_FOR_TIMER3 2 -#define ID_TC_FOR_TIMER3 ID_TC5 -#define IRQn_FOR_TIMER3 TC5_IRQn -#define HANDLER_FOR_TIMER3 TC5_Handler -#endif -#if defined (_useTimer4) -#define TC_FOR_TIMER4 TC0 -#define CHANNEL_FOR_TIMER4 2 -#define ID_TC_FOR_TIMER4 ID_TC2 -#define IRQn_FOR_TIMER4 TC2_IRQn -#define HANDLER_FOR_TIMER4 TC2_Handler -#endif -#if defined (_useTimer5) -#define TC_FOR_TIMER5 TC0 -#define CHANNEL_FOR_TIMER5 0 -#define ID_TC_FOR_TIMER5 ID_TC0 -#define IRQn_FOR_TIMER5 TC0_IRQn -#define HANDLER_FOR_TIMER5 TC0_Handler -#endif - -typedef enum { _timer1, _timer2, _timer3, _timer4, _timer5, _Nbr_16timers } timer16_Sequence_t ; diff --git a/lib/Servo-master/src/samd/Servo.cpp b/lib/Servo-master/src/samd/Servo.cpp deleted file mode 100644 index d8e2ec4..0000000 --- a/lib/Servo-master/src/samd/Servo.cpp +++ /dev/null @@ -1,297 +0,0 @@ -/* - Copyright (c) 2015 Arduino LLC. All right reserved. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#if defined(ARDUINO_ARCH_SAMD) - -#include -#include - -#define usToTicks(_us) ((clockCyclesPerMicrosecond() * _us) / 16) // converts microseconds to tick -#define ticksToUs(_ticks) (((unsigned) _ticks * 16) / clockCyclesPerMicrosecond()) // converts from ticks back to microseconds - -#define TRIM_DURATION 5 // compensation ticks to trim adjust for digitalWrite delays - -static servo_t servos[MAX_SERVOS]; // static array of servo structures - -uint8_t ServoCount = 0; // the total number of attached servos - -static volatile int8_t currentServoIndex[_Nbr_16timers]; // index for the servo being pulsed for each timer (or -1 if refresh interval) - -// convenience macros -#define SERVO_INDEX_TO_TIMER(_servo_nbr) ((timer16_Sequence_t)(_servo_nbr / SERVOS_PER_TIMER)) // returns the timer controlling this servo -#define SERVO_INDEX_TO_CHANNEL(_servo_nbr) (_servo_nbr % SERVOS_PER_TIMER) // returns the index of the servo on this timer -#define SERVO_INDEX(_timer,_channel) ((_timer*SERVOS_PER_TIMER) + _channel) // macro to access servo index by timer and channel -#define SERVO(_timer,_channel) (servos[SERVO_INDEX(_timer,_channel)]) // macro to access servo class by timer and channel - -#define SERVO_MIN() (MIN_PULSE_WIDTH - this->min * 4) // minimum value in us for this servo -#define SERVO_MAX() (MAX_PULSE_WIDTH - this->max * 4) // maximum value in us for this servo - -#define WAIT_TC16_REGS_SYNC(x) while(x->COUNT16.STATUS.bit.SYNCBUSY); - -/************ static functions common to all instances ***********************/ - -void Servo_Handler(timer16_Sequence_t timer, Tc *pTc, uint8_t channel, uint8_t intFlag); -#if defined (_useTimer1) -void HANDLER_FOR_TIMER1(void) { - Servo_Handler(_timer1, TC_FOR_TIMER1, CHANNEL_FOR_TIMER1, INTFLAG_BIT_FOR_TIMER_1); -} -#endif -#if defined (_useTimer2) -void HANDLER_FOR_TIMER2(void) { - Servo_Handler(_timer2, TC_FOR_TIMER2, CHANNEL_FOR_TIMER2, INTFLAG_BIT_FOR_TIMER_2); -} -#endif - -void Servo_Handler(timer16_Sequence_t timer, Tc *tc, uint8_t channel, uint8_t intFlag) -{ - if (currentServoIndex[timer] < 0) { - tc->COUNT16.COUNT.reg = (uint16_t) 0; - WAIT_TC16_REGS_SYNC(tc) - } else { - if (SERVO_INDEX(timer, currentServoIndex[timer]) < ServoCount && SERVO(timer, currentServoIndex[timer]).Pin.isActive == true) { - digitalWrite(SERVO(timer, currentServoIndex[timer]).Pin.nbr, LOW); // pulse this channel low if activated - } - } - - // Select the next servo controlled by this timer - currentServoIndex[timer]++; - - if (SERVO_INDEX(timer, currentServoIndex[timer]) < ServoCount && currentServoIndex[timer] < SERVOS_PER_TIMER) { - if (SERVO(timer, currentServoIndex[timer]).Pin.isActive == true) { // check if activated - digitalWrite(SERVO(timer, currentServoIndex[timer]).Pin.nbr, HIGH); // it's an active channel so pulse it high - } - - // Get the counter value - uint16_t tcCounterValue = tc->COUNT16.COUNT.reg; - WAIT_TC16_REGS_SYNC(tc) - - tc->COUNT16.CC[channel].reg = (uint16_t) (tcCounterValue + SERVO(timer, currentServoIndex[timer]).ticks); - WAIT_TC16_REGS_SYNC(tc) - } - else { - // finished all channels so wait for the refresh period to expire before starting over - - // Get the counter value - uint16_t tcCounterValue = tc->COUNT16.COUNT.reg; - WAIT_TC16_REGS_SYNC(tc) - - if (tcCounterValue + 4UL < usToTicks(REFRESH_INTERVAL)) { // allow a few ticks to ensure the next OCR1A not missed - tc->COUNT16.CC[channel].reg = (uint16_t) usToTicks(REFRESH_INTERVAL); - } - else { - tc->COUNT16.CC[channel].reg = (uint16_t) (tcCounterValue + 4UL); // at least REFRESH_INTERVAL has elapsed - } - WAIT_TC16_REGS_SYNC(tc) - - currentServoIndex[timer] = -1; // this will get incremented at the end of the refresh period to start again at the first channel - } - - // Clear the interrupt - tc->COUNT16.INTFLAG.reg = intFlag; -} - -static inline void resetTC (Tc* TCx) -{ - // Disable TCx - TCx->COUNT16.CTRLA.reg &= ~TC_CTRLA_ENABLE; - WAIT_TC16_REGS_SYNC(TCx) - - // Reset TCx - TCx->COUNT16.CTRLA.reg = TC_CTRLA_SWRST; - WAIT_TC16_REGS_SYNC(TCx) - while (TCx->COUNT16.CTRLA.bit.SWRST); -} - -static void _initISR(Tc *tc, uint8_t channel, uint32_t id, IRQn_Type irqn, uint8_t gcmForTimer, uint8_t intEnableBit) -{ - // Enable GCLK for timer 1 (timer counter input clock) - GCLK->CLKCTRL.reg = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID(gcmForTimer)); - while (GCLK->STATUS.bit.SYNCBUSY); - - // Reset the timer - // TODO this is not the right thing to do if more than one channel per timer is used by the Servo library - resetTC(tc); - - // Set timer counter mode to 16 bits - tc->COUNT16.CTRLA.reg |= TC_CTRLA_MODE_COUNT16; - - // Set timer counter mode as normal PWM - tc->COUNT16.CTRLA.reg |= TC_CTRLA_WAVEGEN_NPWM; - - // Set the prescaler factor to GCLK_TC/16. At nominal 48 MHz GCLK_TC this is 3000 ticks per millisecond - tc->COUNT16.CTRLA.reg |= TC_CTRLA_PRESCALER_DIV16; - - // Count up - tc->COUNT16.CTRLBCLR.bit.DIR = 1; - WAIT_TC16_REGS_SYNC(tc) - - // First interrupt request after 1 ms - tc->COUNT16.CC[channel].reg = (uint16_t) usToTicks(1000UL); - WAIT_TC16_REGS_SYNC(tc) - - // Configure interrupt request - // TODO this should be changed if more than one channel per timer is used by the Servo library - NVIC_DisableIRQ(irqn); - NVIC_ClearPendingIRQ(irqn); - NVIC_SetPriority(irqn, 0); - NVIC_EnableIRQ(irqn); - - // Enable the match channel interrupt request - tc->COUNT16.INTENSET.reg = intEnableBit; - - // Enable the timer and start it - tc->COUNT16.CTRLA.reg |= TC_CTRLA_ENABLE; - WAIT_TC16_REGS_SYNC(tc) -} - -static void initISR(timer16_Sequence_t timer) -{ -#if defined (_useTimer1) - if (timer == _timer1) - _initISR(TC_FOR_TIMER1, CHANNEL_FOR_TIMER1, ID_TC_FOR_TIMER1, IRQn_FOR_TIMER1, GCM_FOR_TIMER_1, INTENSET_BIT_FOR_TIMER_1); -#endif -#if defined (_useTimer2) - if (timer == _timer2) - _initISR(TC_FOR_TIMER2, CHANNEL_FOR_TIMER2, ID_TC_FOR_TIMER2, IRQn_FOR_TIMER2, GCM_FOR_TIMER_2, INTENSET_BIT_FOR_TIMER_2); -#endif -} - -static void finISR(timer16_Sequence_t timer) -{ -#if defined (_useTimer1) - // Disable the match channel interrupt request - TC_FOR_TIMER1->COUNT16.INTENCLR.reg = INTENCLR_BIT_FOR_TIMER_1; -#endif -#if defined (_useTimer2) - // Disable the match channel interrupt request - TC_FOR_TIMER2->COUNT16.INTENCLR.reg = INTENCLR_BIT_FOR_TIMER_2; -#endif -} - -static boolean isTimerActive(timer16_Sequence_t timer) -{ - // returns true if any servo is active on this timer - for(uint8_t channel=0; channel < SERVOS_PER_TIMER; channel++) { - if(SERVO(timer,channel).Pin.isActive == true) - return true; - } - return false; -} - -/****************** end of static functions ******************************/ - -Servo::Servo() -{ - if (ServoCount < MAX_SERVOS) { - this->servoIndex = ServoCount++; // assign a servo index to this instance - servos[this->servoIndex].ticks = usToTicks(DEFAULT_PULSE_WIDTH); // store default values - } else { - this->servoIndex = INVALID_SERVO; // too many servos - } -} - -uint8_t Servo::attach(int pin) -{ - return this->attach(pin, MIN_PULSE_WIDTH, MAX_PULSE_WIDTH); -} - -uint8_t Servo::attach(int pin, int min, int max) -{ - timer16_Sequence_t timer; - - if (this->servoIndex < MAX_SERVOS) { - pinMode(pin, OUTPUT); // set servo pin to output - servos[this->servoIndex].Pin.nbr = pin; - // todo min/max check: abs(min - MIN_PULSE_WIDTH) /4 < 128 - this->min = (MIN_PULSE_WIDTH - min)/4; //resolution of min/max is 4 us - this->max = (MAX_PULSE_WIDTH - max)/4; - // initialize the timer if it has not already been initialized - timer = SERVO_INDEX_TO_TIMER(servoIndex); - if (isTimerActive(timer) == false) { - initISR(timer); - } - servos[this->servoIndex].Pin.isActive = true; // this must be set after the check for isTimerActive - } - return this->servoIndex; -} - -void Servo::detach() -{ - timer16_Sequence_t timer; - - servos[this->servoIndex].Pin.isActive = false; - timer = SERVO_INDEX_TO_TIMER(servoIndex); - if(isTimerActive(timer) == false) { - finISR(timer); - } -} - -void Servo::write(int value) -{ - // treat values less than 544 as angles in degrees (valid values in microseconds are handled as microseconds) - if (value < MIN_PULSE_WIDTH) - { - if (value < 0) - value = 0; - else if (value > 180) - value = 180; - - value = map(value, 0, 180, SERVO_MIN(), SERVO_MAX()); - } - writeMicroseconds(value); -} - -void Servo::writeMicroseconds(int value) -{ - // calculate and store the values for the given channel - byte channel = this->servoIndex; - if( (channel < MAX_SERVOS) ) // ensure channel is valid - { - if (value < SERVO_MIN()) // ensure pulse width is valid - value = SERVO_MIN(); - else if (value > SERVO_MAX()) - value = SERVO_MAX(); - - value = value - TRIM_DURATION; - value = usToTicks(value); // convert to ticks after compensating for interrupt overhead - servos[channel].ticks = value; - } -} - -int Servo::read() // return the value as degrees -{ - return map(readMicroseconds()+1, SERVO_MIN(), SERVO_MAX(), 0, 180); -} - -int Servo::readMicroseconds() -{ - unsigned int pulsewidth; - if (this->servoIndex != INVALID_SERVO) - pulsewidth = ticksToUs(servos[this->servoIndex].ticks) + TRIM_DURATION; - else - pulsewidth = 0; - - return pulsewidth; -} - -bool Servo::attached() -{ - return servos[this->servoIndex].Pin.isActive; -} - -#endif // ARDUINO_ARCH_SAMD diff --git a/lib/Servo-master/src/samd/ServoTimers.h b/lib/Servo-master/src/samd/ServoTimers.h deleted file mode 100644 index 0b18f60..0000000 --- a/lib/Servo-master/src/samd/ServoTimers.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - Copyright (c) 2015 Arduino LLC. All right reserved. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -/* - * Defines for 16 bit timers used with Servo library - * - * If _useTimerX is defined then TimerX is a 16 bit timer on the current board - * timer16_Sequence_t enumerates the sequence that the timers should be allocated - * _Nbr_16timers indicates how many 16 bit timers are available. - */ - -#ifndef __SERVO_TIMERS_H__ -#define __SERVO_TIMERS_H__ - -/** - * SAMD Only definitions - * --------------------- - */ - -// For SAMD: -#define _useTimer1 -//#define _useTimer2 // <- TODO do not activate until the code in Servo.cpp has been changed in order - // to manage more than one channel per timer on the SAMD architecture - -#if defined (_useTimer1) -#define TC_FOR_TIMER1 TC4 -#define CHANNEL_FOR_TIMER1 0 -#define INTENSET_BIT_FOR_TIMER_1 TC_INTENSET_MC0 -#define INTENCLR_BIT_FOR_TIMER_1 TC_INTENCLR_MC0 -#define INTFLAG_BIT_FOR_TIMER_1 TC_INTFLAG_MC0 -#define ID_TC_FOR_TIMER1 ID_TC4 -#define IRQn_FOR_TIMER1 TC4_IRQn -#define HANDLER_FOR_TIMER1 TC4_Handler -#define GCM_FOR_TIMER_1 GCM_TC4_TC5 -#endif -#if defined (_useTimer2) -#define TC_FOR_TIMER2 TC4 -#define CHANNEL_FOR_TIMER2 1 -#define INTENSET_BIT_FOR_TIMER_2 TC_INTENSET_MC1 -#define INTENCLR_BIT_FOR_TIMER_2 TC_INTENCLR_MC1 -#define ID_TC_FOR_TIMER2 ID_TC4 -#define IRQn_FOR_TIMER2 TC4_IRQn -#define HANDLER_FOR_TIMER2 TC4_Handler -#define GCM_FOR_TIMER_2 GCM_TC4_TC5 -#endif - -typedef enum { -#if defined (_useTimer1) - _timer1, -#endif -#if defined (_useTimer2) - _timer2, -#endif - _Nbr_16timers } timer16_Sequence_t; - -#endif // __SERVO_TIMERS_H__ diff --git a/lib/Servo-master/src/stm32f4/Servo.cpp b/lib/Servo-master/src/stm32f4/Servo.cpp deleted file mode 100644 index 01d05d9..0000000 --- a/lib/Servo-master/src/stm32f4/Servo.cpp +++ /dev/null @@ -1,194 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010, LeafLabs, LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -#if defined(ARDUINO_ARCH_STM32F4) - -#include "ServoTimers.h" - -#include "boards.h" -#include "io.h" -#include "pwm.h" -#include "math.h" - -// 20 millisecond period config. For a 1-based prescaler, -// -// (prescaler * overflow / CYC_MSEC) msec = 1 timer cycle = 20 msec -// => prescaler * overflow = 20 * CYC_MSEC -// -// This picks the smallest prescaler that allows an overflow < 2^16. -#define MAX_OVERFLOW ((1 << 16) - 1) -#define CYC_MSEC (1000 * CYCLES_PER_MICROSECOND) -#define TAU_MSEC 20 -#define TAU_USEC (TAU_MSEC * 1000) -#define TAU_CYC (TAU_MSEC * CYC_MSEC) -#define SERVO_PRESCALER (TAU_CYC / MAX_OVERFLOW + 1) -#define SERVO_OVERFLOW ((uint16)round((double)TAU_CYC / SERVO_PRESCALER)) - -// Unit conversions -#define US_TO_COMPARE(us) ((uint16)map((us), 0, TAU_USEC, 0, SERVO_OVERFLOW)) -#define COMPARE_TO_US(c) ((uint32)map((c), 0, SERVO_OVERFLOW, 0, TAU_USEC)) -#define ANGLE_TO_US(a) ((uint16)(map((a), this->minAngle, this->maxAngle, \ - this->minPW, this->maxPW))) -#define US_TO_ANGLE(us) ((int16)(map((us), this->minPW, this->maxPW, \ - this->minAngle, this->maxAngle))) - -Servo::Servo() { - this->resetFields(); -} - -bool Servo::attach(uint8 pin, uint16 minPW, uint16 maxPW, int16 minAngle, int16 maxAngle) -{ - // SerialUSB.begin(115200); - // SerialUSB.println(MAX_OVERFLOW); - - - timer_dev *tdev = PIN_MAP[pin].timer_device; - - analogWriteResolution(16); - - int prescaler = 6; - int overflow = 65400; - int minPW_correction = 300; - int maxPW_correction = 300; - - pinMode(pin, OUTPUT); - - - if (tdev == NULL) { - // don't reset any fields or ASSERT(0), to keep driving any - // previously attach()ed servo. - return false; - } - - if ( (tdev == TIMER1) || (tdev == TIMER8) || (tdev == TIMER10) || (tdev == TIMER11)) - { - prescaler = 54; - overflow = 65400; - minPW_correction = 40; - maxPW_correction = 50; - } - - if ( (tdev == TIMER2) || (tdev == TIMER3) || (tdev == TIMER4) || (tdev == TIMER5) ) - { - prescaler = 6; - overflow = 64285; - minPW_correction = 370; - maxPW_correction = 350; - } - - if ( (tdev == TIMER6) || (tdev == TIMER7) ) - { - prescaler = 6; - overflow = 65400; - minPW_correction = 0; - maxPW_correction = 0; - } - - if ( (tdev == TIMER9) || (tdev == TIMER12) || (tdev == TIMER13) || (tdev == TIMER14) ) - { - prescaler = 6; - overflow = 65400; - minPW_correction = 30; - maxPW_correction = 0; - } - - if (this->attached()) { - this->detach(); - } - - this->pin = pin; - this->minPW = (minPW + minPW_correction); - this->maxPW = (maxPW + maxPW_correction); - this->minAngle = minAngle; - this->maxAngle = maxAngle; - - timer_pause(tdev); - timer_set_prescaler(tdev, prescaler); // prescaler is 1-based - timer_set_reload(tdev, overflow); - timer_generate_update(tdev); - timer_resume(tdev); - - return true; -} - -bool Servo::detach() { - if (!this->attached()) { - return false; - } - - timer_dev *tdev = PIN_MAP[this->pin].timer_device; - uint8 tchan = PIN_MAP[this->pin].timer_channel; - timer_set_mode(tdev, tchan, TIMER_DISABLED); - - this->resetFields(); - - return true; -} - -void Servo::write(int degrees) { - degrees = constrain(degrees, this->minAngle, this->maxAngle); - this->writeMicroseconds(ANGLE_TO_US(degrees)); -} - -int Servo::read() const { - int a = US_TO_ANGLE(this->readMicroseconds()); - // map() round-trips in a weird way we mostly correct for here; - // the round-trip is still sometimes off-by-one for write(1) and - // write(179). - return a == this->minAngle || a == this->maxAngle ? a : a + 1; -} - -void Servo::writeMicroseconds(uint16 pulseWidth) { - if (!this->attached()) { - ASSERT(0); - return; - } - pulseWidth = constrain(pulseWidth, this->minPW, this->maxPW); - analogWrite(this->pin, US_TO_COMPARE(pulseWidth)); -} - -uint16 Servo::readMicroseconds() const { - if (!this->attached()) { - ASSERT(0); - return 0; - } - - stm32_pin_info pin_info = PIN_MAP[this->pin]; - uint16 compare = timer_get_compare(pin_info.timer_device, - pin_info.timer_channel); - - return COMPARE_TO_US(compare); -} - -void Servo::resetFields(void) { - this->pin = NOT_ATTACHED; - this->minAngle = MIN_ANGLE; - this->maxAngle = MAX_ANGLE; - this->minPW = MIN_PULSE_WIDTH; - this->maxPW = MAX_PULSE_WIDTH; -} - -#endif diff --git a/lib/Servo-master/src/stm32f4/ServoTimers.h b/lib/Servo-master/src/stm32f4/ServoTimers.h deleted file mode 100644 index 53bd647..0000000 --- a/lib/Servo-master/src/stm32f4/ServoTimers.h +++ /dev/null @@ -1,207 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010, LeafLabs, LLC. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - - /* - * Arduino srl - www.arduino.org - * 2017 Feb 23: Edited by Francesco Alessi (alfran) - francesco@arduino.org - */ -#ifndef _SERVO_H_ -#define _SERVO_H_ - -#include "types.h" -#include "timer.h" - -#include "wiring.h" /* hack for IDE compile */ - -/* - * Note on Arduino compatibility: - * - * In the Arduino implementation, PWM is done "by hand" in the sense - * that timer channels are hijacked in groups and an ISR is set which - * toggles Servo::attach()ed pins using digitalWrite(). - * - * While this scheme allows any pin to drive a servo, it chews up - * cycles and complicates the programmer's notion of when a particular - * timer channel will be in use. - * - * This implementation only allows Servo instances to attach() to pins - * that already have a timer channel associated with them, and just - * uses pwmWrite() to drive the wave. - * - * This introduces an incompatibility: while the Arduino - * implementation of attach() returns the affected channel on success - * and 0 on failure, this one returns true on success and false on - * failure. - * - * RC Servos expect a pulse every 20 ms. Since periods are set for - * entire timers, rather than individual channels, attach()ing a Servo - * to a pin can interfere with other pins associated with the same - * timer. As always, your board's pin map is your friend. - */ - -// Pin number of unattached pins -#define NOT_ATTACHED (-1) - -#define _Nbr_16timers 14 // Number of STM32F469 Timers -#define SERVOS_PER_TIMER 4 // Number of timer channels - - -// Default min/max pulse widths (in microseconds) and angles (in -// degrees). Values chosen for Arduino compatibility. These values -// are part of the public API; DO NOT CHANGE THEM. -#define MIN_ANGLE 0 -#define MAX_ANGLE 180 - -#define MIN_PULSE_WIDTH 544 // the shortest pulse sent to a servo -#define MAX_PULSE_WIDTH 2400 // the longest pulse sent to a servo - -/** Class for interfacing with RC servomotors. */ -class Servo { -public: - /** - * @brief Construct a new Servo instance. - * - * The new instance will not be attached to any pin. - */ - Servo(); - - /** - * @brief Associate this instance with a servomotor whose input is - * connected to pin. - * - * If this instance is already attached to a pin, it will be - * detached before being attached to the new pin. This function - * doesn't detach any interrupt attached with the pin's timer - * channel. - * - * @param pin Pin connected to the servo pulse wave input. This - * pin must be capable of PWM output. - * - * @param minPulseWidth Minimum pulse width to write to pin, in - * microseconds. This will be associated - * with a minAngle degree angle. Defaults to - * SERVO_DEFAULT_MIN_PW = 544. - * - * @param maxPulseWidth Maximum pulse width to write to pin, in - * microseconds. This will be associated - * with a maxAngle degree angle. Defaults to - * SERVO_DEFAULT_MAX_PW = 2400. - * - * @param minAngle Target angle (in degrees) associated with - * minPulseWidth. Defaults to - * SERVO_DEFAULT_MIN_ANGLE = 0. - * - * @param maxAngle Target angle (in degrees) associated with - * maxPulseWidth. Defaults to - * SERVO_DEFAULT_MAX_ANGLE = 180. - * - * @sideeffect May set pinMode(pin, PWM). - * - * @return true if successful, false when pin doesn't support PWM. - */ - - bool attach(uint8 pin, - uint16 minPulseWidth=MIN_PULSE_WIDTH, - uint16 maxPulseWidth=MAX_PULSE_WIDTH, - int16 minAngle=MIN_ANGLE, - int16 maxAngle=MAX_ANGLE); - /** - * @brief Stop driving the servo pulse train. - * - * If not currently attached to a motor, this function has no effect. - * - * @return true if this call did anything, false otherwise. - */ - bool detach(); - - /** - * @brief Set the servomotor target angle. - * - * @param angle Target angle, in degrees. If the target angle is - * outside the range specified at attach() time, it - * will be clamped to lie in that range. - * - * @see Servo::attach() - */ - void write(int angle); - - /** - * @brief Set the pulse width, in microseconds. - * - * @param pulseWidth Pulse width to send to the servomotor, in - * microseconds. If outside of the range - * specified at attach() time, it is clamped to - * lie in that range. - * - * @see Servo::attach() - */ - void writeMicroseconds(uint16 pulseWidth); - - /** - * Get the servomotor's target angle, in degrees. This will - * lie inside the range specified at attach() time. - * - * @see Servo::attach() - */ - int read() const; - - /** - * Get the current pulse width, in microseconds. This will - * lie within the range specified at attach() time. - * - * @see Servo::attach() - */ - uint16 readMicroseconds() const; - - - /** - * @brief Check if this instance is attached to a servo. - * @return true if this instance is attached to a servo, false otherwise. - * @see Servo::attachedPin() - */ - bool attached() const { return this->pin != NOT_ATTACHED; } - - /** - * @brief Get the pin this instance is attached to. - * @return Pin number if currently attached to a pin, NOT_ATTACHED - * otherwise. - * @see Servo::attach() - */ - int attachedPin() const { return this->pin; } - -private: - int16 pin; - uint16 minPW; - uint16 maxPW; - int16 minAngle; - int16 maxAngle; - - void resetFields(void); -}; - - - -#endif /* _SERVO_H_ */ diff --git a/lib/TeensyThreads-master/TeensyThreads-asm.S b/lib/TeensyThreads-master/TeensyThreads-asm.S deleted file mode 100644 index 7a031be..0000000 --- a/lib/TeensyThreads-master/TeensyThreads-asm.S +++ /dev/null @@ -1,187 +0,0 @@ -/* - * Threads-asm.S - Library for threading on the Teensy. - * - ******************* - * - * Copyright 2017 by Fernando Trias. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, - * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING - * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - ******************* - * - * context_switch() changes the context to a new thread. It follows this strategy: - * - * 1. Abort if called from within an interrupt (unless using PIT) - * 2. Save registers r4-r11 to the current thread state (s0-s31 for FPU) - * 3. If not running on MSP, save PSP to the current thread state - * 4. Get the next running thread state - * 5. Restore r4-r11 from thread state (s0-s31 for FPU) - * 6. Set MSP or PSP depending on state - * 7. Switch MSP/PSP on return - * - * Notes: - * - Cortex-M has two stack pointers, MSP and PSP, which we alternate. See the - * reference manual under the Exception Model section. - * - I tried coding this in asm embedded in Threads.cpp but the compiler - * optimizations kept changing my code and removing lines so I have to use - * a separate assembly file. But if you try it, make sure to declare the - * function "naked" so the stack pointer SP is not modified when called. - * This means you can't use local variables, which are stored in stack. - * Try to turn optimizations off using optimize("O0") (which doesn't really - * turn off all optimizations). - * - Function can be called from systick_isr() or from the PIT timer (implemented - * by IntervalTimer) - * - If using systick, we override the default systick_isr() in order - * to preserve the stack and LR. If using PIT, we override the pitX_isr() for - * the same reason. - * - Since Systick can be called from within another interrupt, for simplicity, we - * check for this and abort. - * - Teensy uses MSP for it's main thread; we preserve that. Alternatively, we - * could have used PSP for all threads, including main, and reserve MSP for - * interrupts only. This would simplify the code slightly, but could introduce - * incompatabilities. - * - If this interrupt is nested within another interrupt, all kinds of bad - * things can happen. This is especially true if usb_isr() is active. In theory - * we should be able to do a switch even within an interrupt, but in my - * tests, it would not work reliably. - * - If using the PIT interrupt, it's priority is set to 255 (the lowest) so it - * cannot interrupt an interrupt. - */ - - .syntax unified - .align 2 - .thumb - - .global context_switch_direct - .thumb_func -context_switch_direct: - CPSID I - // Call here to force a context switch, so we skip checking the tick counter. - B call_direct - - .global context_switch_direct_active - .thumb_func -context_switch_direct_active: - CPSID I - // Call here to force a context switch, so we skip checking the tick counter. - B call_direct_active - - .global context_switch_pit_isr - .thumb_func -context_switch_pit_isr: - CPSID I - LDR r0, =context_timer_flag // acknowledge the interrupt by - LDR r0, [r0] // getting the pointer to the pointer - MOVS r1, #1 // - STR r1, [r0] // and setting to 1 - B context_switch_check // now go do the context switch - - .global context_switch - .thumb_func -context_switch: - - // Disable all interrupts; if we get interrupted during a context switch this - // could corrupt the system. - CPSID I - - // Did we interrupt another interrupt? If so, don't switch. Switching would - // wreck the system. In theory, we could reschedule the switch until the - // other interrupt is done. Or we could do a more sophisticated switch, but the - // easiest thing is to just ignore this condition. - CMP lr, #0xFFFFFFF1 // this means we interrupted an interrupt - BEQ to_exit // so don't do anything until next time - CMP lr, #0xFFFFFFE1 // this means we interrupted an interrupt with FPU - BEQ to_exit // so don't do anything until next time - -context_switch_check: - - // Count down number of ticks we should stay in thread - LDR r0, =currentCount // get the tick count (address to variable) - LDR r1, [r0] // get the value from the address - CMP r1, #0 // is it 0? - BEQ call_direct // if so, thread is done, so switch - SUB r1, #1 // otherwise, subtract 1 tick - STR r1, [r0] // and put it back - B to_exit // and quit until next context_switch - -call_direct: - - // Just do the context-switch (even if it's not time) - LDR r0, =currentActive // If the thread isn't active, skip it - LDR r0, [r0] - CMP r0, #1 - BNE to_exit - -call_direct_active: - - // Save the r4-r11 registers; (r0-r3,r12 are saved by the interrupt handler). - // Most thread libraries save this to the thread stack. I don't for simplicity - // and to make debugging easier. Since the Teensy doesn't have a debugging port, - // it's hard to examine the stack so this is easier. - LDR r0, =currentSave // get the address of the pointer - LDR r0, [r0] // get the pointer itself - STMIA r0!, {r4-r11,lr} // save r4-r11 to buffer - -#ifdef __ARM_PCS_VFP // compile if using FPU - VSTMIA r0!, {s0-s31} // save all FPU registers - VMRS r1, FPSCR // and FPU app status register - STMIA r0!, {r1} -#endif - - // Are we running on thread 0, which is MSP? - // It so, there is no need to save the stack pointer because MSP is never changed. - // If not, save the stack pointer. - LDR r0, =currentMSP // get the address of the variable - LDR r0, [r0] // get value from address - CMP r0, #0 // it is 0? This means it's PSP - BNE current_is_msp // not 0, so MSP, we can skip saving SP - MRS r0, psp // get the PSP value - LDR r1, =currentSP // get the address of our save variable - STR r0, [r1] // and store the PSP value there - current_is_msp: - - BL loadNextThread; // set the state to next running thread - - // Restore the r4-r11 registers from the saved thread - LDR r0, =currentSave // get address of pointer save buffer - LDR r0, [r0] // get the actual pointer - LDMIA r0!, {r4-r11,lr} // and restore r4-r11 & lr from save buffer - -#ifdef __ARM_PCS_VFP // compile if using FPU - VLDMIA r0!, {s0-s31} // restore all FPU registers - LDMIA r0!, {r1} // and the FP app status register - VMSR FPSCR, r1 -#endif - - // Setting LR causes the handler to switch MSP/PSP when returning. - // Switching to MSP? no need to restore MSP. - AND lr, lr, #0x10 // return stack with FP bit? - ORR lr, lr, #0xFFFFFFE9 // add basic LR bits - LDR r0, =currentMSP // get address of the variable - LDR r0, [r0] // get the actual value - CMP r0, #0 // is it 0? Then it's PSP - BNE to_exit // it's not 0, so it's MSP, all done - // if it's PSP, we need to switch PSP - LDR r0, =currentSP // get address of stack pointer - LDR r0, [r0] // get the actual value - MSR psp, r0 // save it to PSP - ORR lr, lr, #0b100 // set the PSP context switch - -to_exit: - // Re-enable interrupts - CPSIE I - // Return. The CPU will change MSP/PSP as needed based on LR - BX lr diff --git a/lib/TeensyThreads-master/TeensyThreads.cpp b/lib/TeensyThreads-master/TeensyThreads.cpp deleted file mode 100644 index 67d95c9..0000000 --- a/lib/TeensyThreads-master/TeensyThreads.cpp +++ /dev/null @@ -1,865 +0,0 @@ -/* - * Threads.cpp - Library for threading on the Teensy. - * - ******************* - * - * Copyright 2017 by Fernando Trias. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, - * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING - * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - ******************* - */ -#include "TeensyThreads.h" -#include -#include - -#ifndef __IMXRT1062__ - -#include -IntervalTimer context_timer; - -#endif - -Threads threads; - -unsigned int time_start; -unsigned int time_end; - -#define __flush_cpu() __asm__ volatile("DMB"); - -// These variables are used by the assembly context_switch() function. -// They are copies or pointers to data in Threads and ThreadInfo -// and put here seperately in order to simplify the code. -extern "C" { - int currentUseSystick; // using Systick vs PIT/GPT - int currentActive; // state of the system (first, start, stop) - int currentCount; - ThreadInfo *currentThread; // the thread currently running - void *currentSave; - int currentMSP; // Stack pointers to save - void *currentSP; - void loadNextThread() { - threads.getNextThread(); - } -} - -const int overflow_stack_size = 8; - -extern "C" void stack_overflow_default_isr() { - currentThread->flags = Threads::ENDED; -} -extern "C" void stack_overflow_isr(void) __attribute__ ((weak, alias("stack_overflow_default_isr"))); - -extern unsigned long _estack; // the main thread 0 stack - -// static void threads_svcall_isr(void); -// static void threads_systick_isr(void); - -IsrFunction Threads::save_systick_isr; -IsrFunction Threads::save_svcall_isr; - -/* - * Teensy 3: - * Replace the SysTick interrupt for our context switching. Note that - * this function is "naked" meaning it does not save it's registers - * on the stack. This is so we can preserve the stack of the caller. - * - * Interrupts will save r0-r4 in the stack and since this function - * is short and simple, it should only use those registers. In the - * future, this should be coded in assembly to make sure. - */ -extern volatile uint32_t systick_millis_count; -extern "C" void systick_isr(); -void __attribute((naked, noinline)) threads_systick_isr(void) -{ - if (Threads::save_systick_isr) { - asm volatile("push {r0-r4,lr}"); - (*Threads::save_systick_isr)(); - asm volatile("pop {r0-r4,lr}"); - } - - // TODO: Teensyduino 1.38 calls MillisTimer::runFromTimer() from SysTick - if (currentUseSystick) { - // we branch in order to preserve LR and the stack - __asm volatile("b context_switch"); - } - __asm volatile("bx lr"); -} - -void __attribute((naked, noinline)) threads_svcall_isr(void) -{ - if (Threads::save_svcall_isr) { - asm volatile("push {r0-r4,lr}"); - (*Threads::save_svcall_isr)(); - asm volatile("pop {r0-r4,lr}"); - } - - // Get the right stack so we can extract the PC (next instruction) - // and then see the SVC calling instruction number - __asm volatile("TST lr, #4 \n" - "ITE EQ \n" - "MRSEQ r0, msp \n" - "MRSNE r0, psp \n"); - register unsigned int *rsp __asm("r0"); - unsigned int svc = ((uint8_t*)rsp[6])[-2]; - if (svc == Threads::SVC_NUMBER) { - __asm volatile("b context_switch_direct"); - } - else if (svc == Threads::SVC_NUMBER_ACTIVE) { - currentActive = Threads::STARTED; - __asm volatile("b context_switch_direct_active"); - } - __asm volatile("bx lr"); -} - -#ifdef __IMXRT1062__ - -/* - * - * Teensy 4: - * Use unused GPT timers for context switching - */ - -extern "C" void unused_interrupt_vector(void); - -static void __attribute((naked, noinline)) gpt1_isr() { - GPT1_SR |= GPT_SR_OF1; // clear set bit - __asm volatile ("dsb"); // see github bug #20 by manitou48 - __asm volatile("b context_switch"); -} - -static void __attribute((naked, noinline)) gpt2_isr() { - GPT2_SR |= GPT_SR_OF1; // clear set bit - __asm volatile ("dsb"); // see github bug #20 by manitou48 - __asm volatile("b context_switch"); -} - -bool gtp1_init(unsigned int microseconds) -{ - // Initialization code derived from @manitou48. - // See https://github.com/manitou48/teensy4/blob/master/gpt_isr.ino - // See https://forum.pjrc.com/threads/54265-Teensy-4-testing-mbed-NXP-MXRT1050-EVKB-(600-Mhz-M7)?p=193217&viewfull=1#post193217 - - // keep track of which GPT timer we are using - static int gpt_number = 0; - - // not configured yet, so find an inactive GPT timer - if (gpt_number == 0) { - if (! NVIC_IS_ENABLED(IRQ_GPT1)) { - attachInterruptVector(IRQ_GPT1, &gpt1_isr); - NVIC_SET_PRIORITY(IRQ_GPT1, 255); - NVIC_ENABLE_IRQ(IRQ_GPT1); - gpt_number = 1; - } - else if (! NVIC_IS_ENABLED(IRQ_GPT2)) { - attachInterruptVector(IRQ_GPT2, &gpt2_isr); - NVIC_SET_PRIORITY(IRQ_GPT2, 255); - NVIC_ENABLE_IRQ(IRQ_GPT2); - gpt_number = 2; - } - else { - // if neither timer is free, we fail - return false; - } - } - - switch (gpt_number) { - case 1: - CCM_CCGR1 |= CCM_CCGR1_GPT1_BUS(CCM_CCGR_ON) ; // enable GPT1 module - GPT1_CR = 0; // disable timer - GPT1_PR = 23; // prescale: divide by 24 so 1 tick = 1 microsecond at 24MHz - GPT1_OCR1 = microseconds - 1; // compare value - GPT1_SR = 0x3F; // clear all prior status - GPT1_IR = GPT_IR_OF1IE; // use first timer - GPT1_CR = GPT_CR_EN | GPT_CR_CLKSRC(1) ; // set to peripheral clock (24MHz) - break; - case 2: - CCM_CCGR1 |= CCM_CCGR1_GPT1_BUS(CCM_CCGR_ON) ; // enable GPT1 module - GPT2_CR = 0; // disable timer - GPT2_PR = 23; // prescale: divide by 24 so 1 tick = 1 microsecond at 24MHz - GPT2_OCR1 = microseconds - 1; // compare value - GPT2_SR = 0x3F; // clear all prior status - GPT2_IR = GPT_IR_OF1IE; // use first timer - GPT2_CR = GPT_CR_EN | GPT_CR_CLKSRC(1) ; // set to peripheral clock (24MHz) - break; - default: - return false; - } - - return true; -} - -#endif - -/*************************************************/ -/**\name UTILITIES FUNCTIONS */ -/*************************************************/ -/** - * \brief Convert thead state to printable string - */ -char * _util_state_2_string(int state){ - static char _state[Threads::UTIL_STATE_NAME_DESCRIPTION_LENGTH]; - memset(_state, 0, sizeof(_state)); - - switch (state) - { - case 0: - sprintf(_state, "EMPTY"); - break; - case 1: - sprintf(_state, "RUNNING"); - break; - case 2: - sprintf(_state, "ENDED"); - break; - case 3: - sprintf(_state, "ENDING"); - break; - case 4: - sprintf(_state, "SUSPENDED"); - break; - default: - sprintf(_state, "%d", state); - break; - } - - return _state; -} - -/*************************************************/ -/**\name CLASS THREAD */ -/*************************************************/ -Threads::Threads() : current_thread(0), thread_count(0), thread_error(0) { - // initilize thread slots to empty - for(int i=1; isave; - currentMSP = 1; - currentSP = 0; - currentCount = Threads::DEFAULT_TICKS; - currentActive = FIRST_RUN; - threadp[0]->flags = RUNNING; - threadp[0]->ticks = DEFAULT_TICKS; - threadp[0]->stack = (uint8_t*)&_estack - DEFAULT_STACK0_SIZE; - threadp[0]->stack_size = DEFAULT_STACK0_SIZE; - setStackMarker(threadp[0]->stack); - -#ifdef __IMXRT1062__ - - // commandeer SVCall & use GTP1 Interrupt - save_svcall_isr = _VectorsRam[11]; - if (save_svcall_isr == unused_interrupt_vector) save_svcall_isr = 0; - _VectorsRam[11] = threads_svcall_isr; - - currentUseSystick = 0; // disable Systick calls - gtp1_init(1000); // tick every millisecond - -#else - - currentUseSystick = 1; - - // commandeer the SVCall & SysTick Exceptions - save_svcall_isr = _VectorsRam[11]; - if (save_svcall_isr == unused_isr) save_svcall_isr = 0; - _VectorsRam[11] = threads_svcall_isr; - - save_systick_isr = _VectorsRam[15]; - if (save_systick_isr == unused_isr) save_systick_isr = 0; - _VectorsRam[15] = threads_systick_isr; - -#ifdef DEBUG -#if defined(__MK20DX256__) || defined(__MK20DX128__) - ARM_DEMCR |= ARM_DEMCR_TRCENA; // Make ssure Cycle Counter active - ARM_DWT_CTRL |= ARM_DWT_CTRL_CYCCNTENA; -#endif -#endif - -#endif -} - -/* - * start() - Begin threading - */ -int Threads::start(int prev_state) { - __disable_irq(); - int old_state = currentActive; - if (prev_state == -1) prev_state = STARTED; - currentActive = prev_state; - __enable_irq(); - return old_state; -} - -/* - * stop() - Stop threading, even if active. - * - * If threads have already started, this should be called sparingly - * because it could destabalize the system if thread 0 is stopped. - */ -int Threads::stop() { - __disable_irq(); - int old_state = currentActive; - currentActive = STOPPED; - __enable_irq(); - return old_state; -} - -/* - * getNextThread() - Find next running thread - * - * This will also set the context_switcher() state variables - */ -void Threads::getNextThread() { - -#ifdef DEBUG - // Keep track of the number of cycles expended by each thread. - // See @dfragster: https://forum.pjrc.com/threads/41504-Teensy-3-x-multithreading-library-first-release?p=213086#post213086 - currentThread->cyclesAccum += ARM_DWT_CYCCNT - currentThread->cyclesStart; -#endif - - // First, save the currentSP set by context_switch - currentThread->sp = currentSP; - - // did we overflow the stack (don't check thread 0)? - // allow an extra 8 bytes for a call to the ISR and one additional call or variable - if (current_thread && ((uint8_t*)currentThread->sp - currentThread->stack <= overflow_stack_size)) { - stack_overflow_isr(); - } - - // Find the next running thread - while(1) { - current_thread++; - if (current_thread >= MAX_THREADS) { - current_thread = 0; // thread 0 is MSP; always active so return - break; - } - if (threadp[current_thread] && threadp[current_thread]->flags == RUNNING) break; - } - currentCount = threadp[current_thread]->ticks; - - currentThread = threadp[current_thread]; - currentSave = &threadp[current_thread]->save; - currentMSP = (current_thread==0?1:0); - currentSP = threadp[current_thread]->sp; - -#ifdef DEBUG - currentThread->cyclesStart = ARM_DWT_CYCCNT; -#endif -} - -/* - * Empty placeholder for IntervalTimer class - */ -static void context_pit_empty() {} - -/* - * Store the PIT timer flag register for use in assembly - */ -volatile uint32_t *context_timer_flag; - -/* - * Defined in assembly code - */ -extern "C" void context_switch_pit_isr(); - -/* - * Stop using the SysTick interrupt and start using - * the IntervalTimer timer. The parameter is the number of microseconds - * for each tick. - */ -int Threads::setMicroTimer(int tick_microseconds) -{ -#ifdef __IMXRT1062__ - - gtp1_init(tick_microseconds); - -#else - -/* - * Implementation strategy suggested by @tni in Teensy Forums; see - * https://forum.pjrc.com/threads/41504-Teensy-3-x-multithreading-library-first-release - */ - - // lowest priority so we don't interrupt other interrupts - context_timer.priority(255); - // start timer with dummy fuction - if (context_timer.begin(context_pit_empty, tick_microseconds) == 0) { - // failed to set the timer! - return 0; - } - currentUseSystick = 0; // disable Systick calls - - // get the PIT number [0-3] (IntervalTimer overrides IRQ_NUMBER_t op) - int number = (IRQ_NUMBER_t)context_timer - IRQ_PIT_CH0; - // calculate number of uint32_t per PIT; should be 4. - // Not hard-coded in case this changes in future CPUs. - const int width = (PIT_TFLG1 - PIT_TFLG0) / sizeof(uint32_t); - // get the right flag to ackowledge PIT interrupt - context_timer_flag = &PIT_TFLG0 + (width * number); - attachInterruptVector(context_timer, context_switch_pit_isr); - -#endif - - return 1; -} - -/* - * Set each time slice to be 'microseconds' long - */ -int Threads::setSliceMicros(int microseconds) -{ - setMicroTimer(microseconds); - setDefaultTimeSlice(1); - return 1; -} - -/* - * Set each time slice to be 'milliseconds' long - */ -int Threads::setSliceMillis(int milliseconds) -{ - if (currentUseSystick) { - setDefaultTimeSlice(milliseconds); - } - else { - // if we're using the PIT, we should probably really disable it and - // re-establish the systick timer; but this is easier for now - setSliceMicros(milliseconds * 1000); - } - return 1; -} - -/* - * del_process() - This is called when the task returns - * - * Turns thread off. Thread continues running until next call to - * context_switch() at which point it all stops. The while(1) statement - * just stalls until such time. - */ -void Threads::del_process(void) -{ - int old_state = threads.stop(); - ThreadInfo *me = threads.threadp[threads.current_thread]; - // Would love to delete stack here but the thread doesn't - // end now. It continues until the next tick. - // if (me->my_stack) { - // delete[] me->stack; - // me->stack = 0; - // } - threads.thread_count--; - me->flags = ENDED; //clear the flags so thread can stop and be reused - threads.start(old_state); - while(1); // just in case, keep working until context change when execution will not return to this thread -} - -/* - * Set a marker at memory so we can detect memory overruns - */ - -const uint32_t thread_marker = 0xDEADDEAD; - -void Threads::setStackMarker(void *stack) -{ - uint32_t *m = (uint32_t*)stack; - *m = thread_marker; -} - -/* - * Users call this function to see if stack has been corrupted - */ -int Threads::testStackMarkers(int *threadid) -{ - for (int i=0; i < MAX_THREADS; i++) { - if (threadp[i] == NULL) continue; - if (threadp[i]->flags == RUNNING) { - uint32_t *m = (uint32_t*)threadp[i]->stack; - if (*m != thread_marker) { - if (threadid) *threadid = i; - return -1; - } - } - } - return 0; -} - -/* - * Initializes a thread's stack. Called when thread is created - */ -void *Threads::loadstack(ThreadFunction p, void * arg, void *stackaddr, int stack_size) -{ - interrupt_stack_t * process_frame = (interrupt_stack_t *)((uint8_t*)stackaddr + stack_size - sizeof(interrupt_stack_t) - overflow_stack_size); - process_frame->r0 = (uint32_t)arg; - process_frame->r1 = 0; - process_frame->r2 = 0; - process_frame->r3 = 0; - process_frame->r12 = 0; - process_frame->lr = (uint32_t)Threads::del_process; - process_frame->pc = ((uint32_t)p); - process_frame->xpsr = 0x1000000; - uint8_t *ret = (uint8_t*)process_frame; - // ret -= sizeof(software_stack_t); // uncomment this if we are saving R4-R11 to the stack - return (void*)ret; -} - -/* - * Add a new thread to the queue. - * add_thread(fund, arg) - * - * fund : is a function pointer. The function prototype is: - * void *func(void *param) - * arg : is a void pointer that is passed as the first parameter - * of the function. In the example above, arg is passed - * as param. - * stack_size : the size of the buffer pointed to by stack. If - * it is 0, then "stack" must also be 0. If so, the function - * will allocate the default stack size of the heap using new(). - * stack : pointer to new data stack of size stack_size. If this is 0, - * then it will allocate a stack on the heap using new() of size - * stack_size. If stack_size is 0, a default size will be used. - * return: an integer ID to be used for other calls - */ -int Threads::addThread(ThreadFunction p, void * arg, int stack_size, void *stack) -{ - int old_state = stop(); - if (stack_size == -1) stack_size = DEFAULT_STACK_SIZE; - for (int i=1; i < MAX_THREADS; i++) { - if (threadp[i] == NULL) { // empty thread, so fill it - threadp[i] = new ThreadInfo(); - } - if (threadp[i]->flags == ENDED || threadp[i]->flags == EMPTY) { // free thread - ThreadInfo *tp = threadp[i]; // working on this thread - if (tp->stack && tp->my_stack) { - delete[] tp->stack; - } - if (stack==0) { - stack = new uint8_t[stack_size]; - tp->my_stack = 1; - } - else { - tp->my_stack = 0; - } - setStackMarker(stack); - tp->stack = (uint8_t*)stack; - tp->stack_size = stack_size; - void *psp = loadstack(p, arg, tp->stack, tp->stack_size); - tp->sp = psp; - tp->ticks = DEFAULT_TICKS; - tp->flags = RUNNING; - tp->save.lr = 0xFFFFFFF9; - -#ifdef DEBUG - tp->cyclesStart = ARM_DWT_CYCCNT; - tp->cyclesAccum = 0; -#endif - - currentActive = old_state; - thread_count++; - if (old_state == STARTED || old_state == FIRST_RUN) start(); - return i; - } - } - if (old_state == STARTED) start(); - return -1; -} - -int Threads::getState(int id) -{ - return threadp[id]->flags; -} - -int Threads::setState(int id, int state) -{ - threadp[id]->flags = state; - return state; -} - -int Threads::wait(int id, unsigned int timeout_ms) -{ - unsigned int start = millis(); - // need to store state in temp volatile memory for optimizer. - // "while (thread[id].flags != RUNNING)" will be optimized away - volatile int state; - while (1) { - if (timeout_ms != 0 && millis() - start > timeout_ms) return -1; - state = threadp[id]->flags; - if (state != RUNNING) break; - yield(); - } - return id; -} - -int Threads::kill(int id) -{ - threadp[id]->flags = ENDED; - return id; -} - -int Threads::suspend(int id) -{ - threadp[id]->flags = SUSPENDED; - return id; -} - -int Threads::restart(int id) -{ - threadp[id]->flags = RUNNING; - return id; -} - -void Threads::setTimeSlice(int id, unsigned int ticks) -{ - threadp[id]->ticks = ticks - 1; -} - -void Threads::setDefaultTimeSlice(unsigned int ticks) -{ - DEFAULT_TICKS = ticks - 1; -} - -void Threads::setDefaultStackSize(unsigned int bytes_size) -{ - DEFAULT_STACK_SIZE = bytes_size; -} - -void Threads::yield() { - __asm volatile("svc %0" : : "i"(Threads::SVC_NUMBER)); -} - -void Threads::yield_and_start() { - __asm volatile("svc %0" : : "i"(Threads::SVC_NUMBER_ACTIVE)); -} - -void Threads::delay(int millisecond) { - int mx = millis(); - while((int)millis() - mx < millisecond) yield(); -} - -/* - * Experimental code for putting CPU into sleep mode during delays - */ - -void Threads::setSleepCallback(ThreadFunctionSleep callback) -{ - enter_sleep_callback = callback; -} - -void Threads::delay_us(int microsecond){ - int mx = micros(); - while ((int)micros() - mx < microsecond) yield(); -} - -void Threads::idle() { - volatile bool needs_run[thread_count]; - volatile int i, j; - volatile int task_id_ends; - - if (enter_sleep_callback==NULL) return; - - __disable_irq(); - task_id_ends = -1; - //get lowest sleep interval from sleeping tasks into task_id_ends - for (i = 0; i < thread_count; i++) { - //sort by ending time first - for (j = i + 1; j < thread_count; ++j) { - if (! threadp[i]) continue; - if (threadp[i]->sleep_time_till_end_tick > threadp[j]->sleep_time_till_end_tick) { - //if end time soonest - if (getState(i+1) == SUSPENDED) { - task_id_ends = j; //store next task - } - } - } - } - if (task_id_ends==-1) return; - - //set the sleeping time to substractor - int subtractor = threadp[task_id_ends]->sleep_time_till_end_tick; - - if (subtractor > 0) { - //if sleep is needed - volatile int time_spent_asleep = enter_sleep_callback(subtractor); - //store new data based on time spent asleep - for (i = 0; i < thread_count; i++) { - if (! threadp[i]) continue; - needs_run[i] = 0; - if (getState(i+1) == SUSPENDED) { - threadp[i]->sleep_time_till_end_tick -= time_spent_asleep; //substract sleep time - //time to run? - if (threadp[i]->sleep_time_till_end_tick <= 0) { - needs_run[i] = 1; - } else { - needs_run[i] = 0; - } - } - } - //for each thread when slept, resume if needed - for (i = 0; i < thread_count; i++) { - if (! threadp[i]) continue; - if (needs_run[i]) { - setState(i+1, RUNNING); - threadp[i]->sleep_time_till_end_tick = 60000; - } - } - } - __enable_irq(); - yield(); -} - -void Threads::sleep(int ms) { - int i = id(); - if (getState(i) == RUNNING) { - __disable_irq(); - threadp[i-1]->sleep_time_till_end_tick = ms; - setState(i, SUSPENDED); - __enable_irq(); - yield(); - } -} - -/* End of experimental code */ - -int Threads::id() { - volatile int ret; - __disable_irq(); - ret = current_thread; - __enable_irq(); - return ret; -} - -int Threads::getStackUsed(int id) { - return threadp[id]->stack + threadp[id]->stack_size - (uint8_t*)threadp[id]->sp; -} - -int Threads::getStackRemaining(int id) { - return (uint8_t*)threadp[id]->sp - threadp[id]->stack; -} - -char *Threads::threadsInfo(void) -{ - static char _buffer[Threads::UTIL_TRHEADS_BUFFER_LENGTH]; - uint _buffer_cursor = 0; - _buffer_cursor = sprintf(_buffer, "_____\n"); - for (int each_thread = 0; each_thread < thread_count; each_thread++) - { - if (threadp[each_thread] != NULL) - { - _buffer_cursor += sprintf(_buffer + _buffer_cursor, "%d:", each_thread); - _buffer_cursor += sprintf(_buffer + _buffer_cursor, "Stack size:%d|", - threadp[each_thread]->stack_size); - _buffer_cursor += sprintf(_buffer + _buffer_cursor, "Used:%d|Remains:%d|", - getStackUsed(each_thread), - getStackRemaining(each_thread)); - char *_thread_state = _util_state_2_string(threadp[each_thread]->flags); - _buffer_cursor += sprintf(_buffer + _buffer_cursor, "State:%s|", - _thread_state); -#ifdef DEBUG - _buffer_cursor += sprintf(_buffer + _buffer_cursor, "cycles:%lu\n", - threadp[each_thread]->cyclesAccum); -#else - _buffer_cursor += sprintf(_buffer + _buffer_cursor, "\n"); -#endif - } - } - return _buffer; -} - -#ifdef DEBUG -unsigned long Threads::getCyclesUsed(int id) { - stop(); - unsigned long ret = threadp[id]->cyclesAccum; - start(); - return ret; -} -#endif - -/* - * On creation, stop threading and save state - */ -Threads::Suspend::Suspend() { - __disable_irq(); - save_state = currentActive; - currentActive = 0; - __enable_irq(); -} - -/* - * On destruction, restore threading state - */ -Threads::Suspend::~Suspend() { - __disable_irq(); - currentActive = save_state; - __enable_irq(); -} - -int Threads::Mutex::getState() { - int p = threads.stop(); - int ret = state; - threads.start(p); - return ret; -} - -int __attribute__ ((noinline)) Threads::Mutex::lock(unsigned int timeout_ms) { - if (try_lock()) return 1; // we're good, so avoid more checks - - uint32_t start = systick_millis_count; - while (1) { - if (try_lock()) return 1; - if (timeout_ms && (systick_millis_count - start > timeout_ms)) return 0; - if (waitthread==-1) { // can hold 1 thread suspend until unlock - int p = threads.stop(); - waitthread = threads.current_thread; - waitcount = currentCount; - threads.suspend(waitthread); - threads.start(p); - } - threads.yield(); - } - __flush_cpu(); - return 0; -} - -int Threads::Mutex::try_lock() { - int p = threads.stop(); - if (state == 0) { - state = 1; - threads.start(p); - return 1; - } - threads.start(p); - return 0; -} - -int __attribute__ ((noinline)) Threads::Mutex::unlock() { - int p = threads.stop(); - if (state==1) { - state = 0; - if (waitthread >= 0) { // reanimate a suspended thread waiting for unlock - threads.restart(waitthread); - waitthread = -1; - __flush_cpu(); - threads.yield_and_start(); - return 1; - } - } - __flush_cpu(); - threads.start(p); - return 1; -} diff --git a/lib/TeensyThreads-master/TeensyThreads.h b/lib/TeensyThreads-master/TeensyThreads.h deleted file mode 100644 index 8b67de1..0000000 --- a/lib/TeensyThreads-master/TeensyThreads.h +++ /dev/null @@ -1,445 +0,0 @@ -/* - * Threads.h - Library for threading on the Teensy. - * - ******************* - * - * Copyright 2017 by Fernando Trias. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, - * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING - * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - ******************* - * - * Multithreading library for Teensy board. - * See Threads.cpp for explanation of internal functions. - * - * A global variable "threads" of type Threads will be created - * to provide all threading functions. See example below: - * - * #include - * - * volatile int count = 0; - * - * void thread_func(int data){ - * while(1) count++; - * } - * - * void setup() { - * threads.addThread(thread_func, 0); - * } - * - * void loop() { - * Serial.print(count); - * } - * - * Alternatively, you can use the std::threads class defined - * by C++11 - * - * #include - * - * volatile int count = 0; - * - * void thread_func(){ - * while(1) count++; - * } - * - * void setup() { - * std::thead th1(thread_func); - * th1.detach(); - * } - * - * void loop() { - * Serial.print(count); - * } - * - */ - -#ifndef _THREADS_H -#define _THREADS_H - -#include -#include - -/* Enabling debugging information allows access to: - * getCyclesUsed() - */ -// #define DEBUG - -extern "C" { - void context_switch(void); - void context_switch_direct(void); - void context_switch_pit_isr(void); - void loadNextThread(); - void stack_overflow_isr(void); - void threads_svcall_isr(void); - void threads_systick_isr(void); -} - -// The stack frame saved by the interrupt -typedef struct { - uint32_t r0; - uint32_t r1; - uint32_t r2; - uint32_t r3; - uint32_t r12; - uint32_t lr; - uint32_t pc; - uint32_t xpsr; -} interrupt_stack_t; - -// The stack frame saved by the context switch -typedef struct { - uint32_t r4; - uint32_t r5; - uint32_t r6; - uint32_t r7; - uint32_t r8; - uint32_t r9; - uint32_t r10; - uint32_t r11; - uint32_t lr; -#ifdef __ARM_PCS_VFP - uint32_t s0; - uint32_t s1; - uint32_t s2; - uint32_t s3; - uint32_t s4; - uint32_t s5; - uint32_t s6; - uint32_t s7; - uint32_t s8; - uint32_t s9; - uint32_t s10; - uint32_t s11; - uint32_t s12; - uint32_t s13; - uint32_t s14; - uint32_t s15; - uint32_t s16; - uint32_t s17; - uint32_t s18; - uint32_t s19; - uint32_t s20; - uint32_t s21; - uint32_t s22; - uint32_t s23; - uint32_t s24; - uint32_t s25; - uint32_t s26; - uint32_t s27; - uint32_t s28; - uint32_t s29; - uint32_t s30; - uint32_t s31; - uint32_t fpscr; -#endif -} software_stack_t; - -// The state of each thread (including thread 0) -class ThreadInfo { - public: - int stack_size; - uint8_t *stack=0; - int my_stack = 0; - software_stack_t save; - volatile int flags = 0; - void *sp; - int ticks; - volatile int sleep_time_till_end_tick; // Per-task sleep time -#ifdef DEBUG - unsigned long cyclesStart; // On T_4 the CycCnt is always active - on T_3.x it currently is not - unless Audio starts it AFAIK - unsigned long cyclesAccum; -#endif -}; - -extern "C" void unused_isr(void); - -typedef void (*ThreadFunction)(void*); -typedef void (*ThreadFunctionInt)(int); -typedef void (*ThreadFunctionNone)(); -typedef int (*ThreadFunctionSleep)(int); - -typedef void (*IsrFunction)(); - -/* - * Threads handles all the threading interaction with users. It gets - * instantiated in a global variable "threads". - */ -class Threads { -public: - // The maximum number of threads is hard-coded to simplify - // the implementation. See notes of ThreadInfo. - int DEFAULT_TICKS = 10; - int DEFAULT_STACK_SIZE = 1024; - static const int MAX_THREADS = 16; - static const int DEFAULT_STACK0_SIZE = 10240; // estimate for thread 0? - static const int DEFAULT_TICK_MICROSECONDS = 100; - static const int UTIL_STATE_NAME_DESCRIPTION_LENGTH = 24; - static const int UTIL_TRHEADS_BUFFER_LENGTH = 1024; - - - // State of threading system - static const int STARTED = 1; - static const int STOPPED = 2; - static const int FIRST_RUN = 3; - - // State of individual threads - static const int EMPTY = 0; - static const int RUNNING = 1; - static const int ENDED = 2; - static const int ENDING = 3; - static const int SUSPENDED = 4; - - static const int SVC_NUMBER = 0x21; - static const int SVC_NUMBER_ACTIVE = 0x22; - -protected: - int current_thread; - int thread_count; - int thread_error; - - /* - * The maximum number of threads is hard-coded. Alternatively, we could implement - * a linked list which would mean using up less memory for a small number of - * threads while allowing an unlimited number of possible threads. This would - * probably not slow down thread switching too much, but it would introduce - * complexity and possibly bugs. So to simplifiy for now, we use an array. - * But in the future, a linked list might be more appropriate. - */ - ThreadInfo *threadp[MAX_THREADS]; - // This used to be allocated statically, as below. Kept for reference in case of bugs. - // ThreadInfo thread[MAX_THREADS]; - - ThreadFunctionSleep enter_sleep_callback = NULL; - -public: // public for debugging - static IsrFunction save_systick_isr; - static IsrFunction save_svcall_isr; - -public: - Threads(); - - // Create a new thread for function "p", passing argument "arg". If stack is 0, - // stack allocated on heap. Function "p" has form "void p(void *)". - int addThread(ThreadFunction p, void * arg=0, int stack_size=-1, void *stack=0); - // For: void f(int) - int addThread(ThreadFunctionInt p, int arg=0, int stack_size=-1, void *stack=0) { - return addThread((ThreadFunction)p, (void*)arg, stack_size, stack); - } - // For: void f() - int addThread(ThreadFunctionNone p, int arg=0, int stack_size=-1, void *stack=0) { - return addThread((ThreadFunction)p, (void*)arg, stack_size, stack); - } - - // Get the state; see class constants. Can be EMPTY, RUNNING, etc. - int getState(int id); - // Explicityly set a state. See getState(). Call with care. - int setState(int id, int state); - // Wait until thread returns up to timeout_ms milliseconds. If ms is 0, wait - // indefinitely. - int wait(int id, unsigned int timeout_ms = 0); - // If using sleep, please run this in infinite loop - void idle(); - // Suspend execution of current thread for ms milliseconds - void sleep(int ms); - // Permanently stop a running thread. Thread will end on the next thread slice tick. - int kill(int id); - // Suspend a thread (on the next slice tick). Can be restarted with restart(). - int suspend(int id); - // Restart a suspended thread. - int restart(int id); - // Set the slice length time in ticks for a thread (1 tick = 1 millisecond, unless using MicroTimer) - void setTimeSlice(int id, unsigned int ticks); - // Set the slice length time in ticks for all new threads (1 tick = 1 millisecond, unless using MicroTimer) - void setDefaultTimeSlice(unsigned int ticks); - // Set the stack size for new threads in bytes - void setDefaultStackSize(unsigned int bytes_size); - // Use the microsecond timer provided by IntervalTimer & PIT; instead of 1 tick = 1 millisecond, - // 1 tick will be the number of microseconds provided (default is 100 microseconds) - int setMicroTimer(int tick_microseconds = DEFAULT_TICK_MICROSECONDS); - // Simple function to set each time slice to be 'milliseconds' long - int setSliceMillis(int milliseconds); - // Set each time slice to be 'microseconds' long - int setSliceMicros(int microseconds); - // Set sleep callback function - void setSleepCallback(ThreadFunctionSleep callback); - - // Get the id of the currently running thread - int id(); - int getStackUsed(int id); - int getStackRemaining(int id); - char* threadsInfo(void); -#ifdef DEBUG - unsigned long getCyclesUsed(int id); -#endif - - // Yield current thread's remaining time slice to the next thread, causing immediate - // context switch - static void yield(); - // Wait for milliseconds using yield(), giving other slices your wait time - void delay(int millisecond); - // Wait for microseconds using yield(), giving other slices your wait time - void delay_us(int microsecond); - - // Start/restart threading system; returns previous state: STARTED, STOPPED, FIRST_RUN - // can pass the previous state to restore - int start(int old_state = -1); - // Stop threading system; returns previous state: STARTED, STOPPED, FIRST_RUN - int stop(); - - // Test all stack markers; if ok return 0; problems, return -1 and set *threadid to id - int testStackMarkers(int *threadid = NULL); - - // Allow these static functions and classes to access our members - friend void context_switch(void); - friend void context_switch_direct(void); - friend void context_pit_isr(void); - friend void threads_systick_isr(void); - friend void threads_svcall_isr(void); - friend void loadNextThread(); - friend class ThreadLock; - -protected: - void getNextThread(); - void *loadstack(ThreadFunction p, void * arg, void *stackaddr, int stack_size); - static void force_switch_isr(); - void setStackMarker(void *stack); - -private: - static void del_process(void); - void yield_and_start(); - -public: - class Mutex { - private: - volatile int state = 0; - volatile int waitthread = -1; - volatile int waitcount = 0; - public: - int getState(); // get the lock state; 1=locked; 0=unlocked - int lock(unsigned int timeout_ms = 0); // lock, optionally waiting up to timeout_ms milliseconds - int try_lock(); // if lock available, get it and return 1; otherwise return 0 - int unlock(); // unlock if locked - }; - - class Scope { - private: - Mutex *r; - public: - Scope(Mutex& m) { r = &m; r->lock(); } - ~Scope() { r->unlock(); } - }; - - class Suspend { - private: - int save_state; - public: - Suspend(); // Stop threads and save thread state - ~Suspend(); // Restore saved state - }; - - template class GrabTemp { - private: - Mutex *lkp; - public: - C *me; - GrabTemp(C *obj, Mutex *lk) { me = obj; lkp=lk; lkp->lock(); } - ~GrabTemp() { lkp->unlock(); } - C &get() { return *me; } - }; - - template class Grab { - private: - Mutex lk; - T *me; - public: - Grab(T &t) { me = &t; } - GrabTemp grab() { return GrabTemp(me, &lk); } - operator T&() { return grab().get(); } - T *operator->() { return grab().me; } - Mutex &getLock() { return lk; } - }; - -#define ThreadWrap(OLDOBJ, NEWOBJ) Threads::Grab NEWOBJ(OLDOBJ); -#define ThreadClone(NEWOBJ) (NEWOBJ.grab().get()) - -}; - - -extern Threads threads; - -/* - * Rudimentary compliance to C++11 class - * - * See http://www.cplusplus.com/reference/thread/thread/ - * - * Example: - * int x; - * void thread_func() { x++; } - * int main() { - * std::thread(thread_func); - * } - * - */ -namespace std { - class thread { - private: - int id; // internal thread id - int destroy; // flag to kill thread on instance destruction - public: - // By casting all (args...) to (void*), if there are more than one args, the compiler - // will fail to find a matching function. This fancy template just allows any kind of - // function to match. - template explicit thread(F&& f, Args&&... args) { - id = threads.addThread((ThreadFunction)f, (void*)args...); - destroy = 1; - } - // If thread has not been detached when destructor called, then thread must end - ~thread() { - if (destroy) threads.kill(id); - } - // Threads are joinable until detached per definition, but in this implementation - // that's not so. We emulate expected behavior anyway. - bool joinable() { return destroy==1; } - // Once detach() is called, thread runs until it terminates; otherwise it terminates - // when destructor called. - void detach() { destroy = 0; } - // In theory, the thread merges with the running thread; if we just wait until - // termination, it's basically the same thing except it's slower because - // there are two threads running instead of one. Close enough. - void join() { threads.wait(id); } - // Get the unique thread id. - int get_id() { return id; } - }; - - class mutex { - private: - Threads::Mutex mx; - public: - void lock() { mx.lock(); } - bool try_lock() { return mx.try_lock(); } - void unlock() { mx.unlock(); } - }; - - template class lock_guard { - private: - cMutex *r; - public: - explicit lock_guard(cMutex& m) { r = &m; r->lock(); } - ~lock_guard() { r->unlock(); } - }; -} - -#endif diff --git a/lib/TeensyThreads-master/TeensyThreads.zip b/lib/TeensyThreads-master/TeensyThreads.zip deleted file mode 100644 index 793954b..0000000 Binary files a/lib/TeensyThreads-master/TeensyThreads.zip and /dev/null differ diff --git a/lib/TeensyThreads-master/examples/Blink/Blink.ino b/lib/TeensyThreads-master/examples/Blink/Blink.ino deleted file mode 100644 index d42bf27..0000000 --- a/lib/TeensyThreads-master/examples/Blink/Blink.ino +++ /dev/null @@ -1,36 +0,0 @@ -#include -#include "TeensyThreads.h" - -const int LED = 13; - -volatile int blinkcode = 0; - -void blinkthread() { - while(1) { - if (blinkcode) { - for (int i=0; i -#include -#include - -#include "TeensyThreads.h" -SnoozeTimer timer; -SnoozeBlock config(timer); - -const int LED = 13; -const int UserLED = 2; - -//your sleeping funcion -int enter_sleep(int ms) { - timer.setTimer(ms);//set sleep time in milliseconds - Snooze.hibernate( config ); //go to actual sleep - //additional, one can use the RTC or a low power timer - //to calculate actual time spent asleep and return the - //value to the scheduler to calculate better times. - return ms; -} - -void heartbeat() { - while (1) { - threads.sleep(3000); - digitalWriteFast(LED, !digitalRead(LED)); - } -} - -void fastbeat() { - while (1) { - threads.sleep(1555); - digitalWriteFast(UserLED, !digitalRead(UserLED)); - } -} - -void setup() { - pinMode(2, OUTPUT); - digitalWriteFast(2, LOW); - pinMode(LED, OUTPUT); - digitalWriteFast(LED, LOW); - delay(2000); - threads.addThread(heartbeat); - threads.addThread(fastbeat); - while(1) { - threads.idle(); - //custom infinite loop - } -} -void loop() { - //i prefer to prevent the main loop from running as it causes CPU overhead because USB and other event handlers.. -} diff --git a/lib/TeensyThreads-master/examples/Print/Print.ino b/lib/TeensyThreads-master/examples/Print/Print.ino deleted file mode 100644 index 3c4adf2..0000000 --- a/lib/TeensyThreads-master/examples/Print/Print.ino +++ /dev/null @@ -1,16 +0,0 @@ -#include - -volatile long int count = 0; - -void thread_func(int inc) { - while(1) count += inc; -} - -void setup() { - threads.addThread(thread_func, 1); -} - -void loop() { - Serial.println(count); - threads.delay(1000); -} diff --git a/lib/TeensyThreads-master/examples/Runnable/LED.cpp b/lib/TeensyThreads-master/examples/Runnable/LED.cpp deleted file mode 100644 index baebe25..0000000 --- a/lib/TeensyThreads-master/examples/Runnable/LED.cpp +++ /dev/null @@ -1,66 +0,0 @@ -/* - * File Purpose - * Implementing LED.h functions - */ - -#include "Arduino.h" -#include "LED.h" - -// Initial constructor. Sets the pin, pinmode, and sets initial state as false -LED::LED(uint8_t pin) -{ - this->pin = pin; - state = false; - pinMode(pin, OUTPUT); - - this->duration = 0; - this->period = 0; - this->duty = 0; -} - -LED::~LED(){} - -// Turns on the LED and changes state to true. Volatile so it can be run in thread -void LED::turnOn() volatile -{ - digitalWrite(pin, HIGH); - state = true; -} - -// Turns off the LED and changes state to false. Volatile so it can be run in thread -void LED::turnOff() volatile -{ - digitalWrite(pin, LOW); - state = false; -} - -// This function emulates a PWM signal. But used not for controlling voltage but blinking. -void LED::runTarget(void *arg) -{ - // Casting the derived object so it can be used within the static runnable functions - LED* thisobj = static_cast(arg); - - float elapsedDuration = duration; - do - { - thisobj->turnOn(); - threads.delay(period * (duty / 100)); - thisobj->turnOff(); - threads.delay((period * (1 - (duty / 100)))); - - // For quick example, just assuming that thread delay will equal to exact execution time - elapsedDuration -= period; - } while(elapsedDuration > 0); -} - -// Start thread that will last for duration duration, period period, and duty duty -void LED::startBlinking(float duration, float period, float duty) -{ - this->duration = duration; - this->period = period; - this->duty = duty; - - // Start thread - blinkThread = new std::thread(&Runnable::runThread, this); - blinkThread->detach(); -} \ No newline at end of file diff --git a/lib/TeensyThreads-master/examples/Runnable/LED.h b/lib/TeensyThreads-master/examples/Runnable/LED.h deleted file mode 100644 index 36ca867..0000000 --- a/lib/TeensyThreads-master/examples/Runnable/LED.h +++ /dev/null @@ -1,47 +0,0 @@ -#ifndef LED_H -#define LED_H - -/* - * File Purpose - * The purpose of this file is to create a simple interface for turning on and off an led - * And for threading led function so that you can make an led blink for a specified amount of duty at any frequency - */ - -#include -#include -#include "Runnable.h" - -class LED : public Runnable{ -private: - // Digital pin - uint8_t pin; - - // Track state so the program knows if the LED is ON or OFF - bool state; - - // Timing Variables - float duration; - float period; - float duty; - - // Thread object - std::thread *blinkThread; - -protected: - // Runnable function that we need to implement - void runTarget(void *arg); - -public: - // Constructor/Destructor - LED(uint8_t pin); - ~LED(); - - // Turn on and off LED, volatile for threading use - void turnOn() volatile; - void turnOff() volatile; - - // Start thread that will last for duration - void startBlinking(float duration, float period, float duty); -}; - -#endif // LED_H diff --git a/lib/TeensyThreads-master/examples/Runnable/README.txt b/lib/TeensyThreads-master/examples/Runnable/README.txt deleted file mode 100644 index b9036d4..0000000 --- a/lib/TeensyThreads-master/examples/Runnable/README.txt +++ /dev/null @@ -1,4 +0,0 @@ -The purpose of this example is to demonstrate how to use TeensyThreads as part of std and implement it such that a class could easily implement threading without much overhead -The Runnable.h file is an abstract definition of how to use threads -Any class that dervives from Runnable just needs to implement the runTarget(void *args) and start the thread. -This specific example extends an example LED class such that an LED object can be constructed to blink for some duration, at some period, with some duty cycle \ No newline at end of file diff --git a/lib/TeensyThreads-master/examples/Runnable/Runnable.h b/lib/TeensyThreads-master/examples/Runnable/Runnable.h deleted file mode 100644 index 3c41380..0000000 --- a/lib/TeensyThreads-master/examples/Runnable/Runnable.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef RUNNABLE_H -#define RUNNABLE_H - -/* - * File Purpose - * This is an abstract class that is reusable to allow for easy defintion of a runnable function for std::thread - */ - -class Runnable{ -private: -protected: - virtual void runTarget(void *arg) = 0; -public: - virtual ~Runnable(){} - - static void runThread(void *arg) - { - Runnable *_runnable = static_cast (arg); - _runnable->runTarget(arg); - } -}; - -#endif // RUNNABLE_H diff --git a/lib/TeensyThreads-master/examples/Runnable/main.ino b/lib/TeensyThreads-master/examples/Runnable/main.ino deleted file mode 100644 index 9385eae..0000000 --- a/lib/TeensyThreads-master/examples/Runnable/main.ino +++ /dev/null @@ -1,47 +0,0 @@ -// Example for blinking multiple LEDs - -#include "LED.h" - -// Pins for LED objects -const int pinLED = 13; -// const int pinLED1 = 3; -// const int pinLED2 = 4; -// ... - -// LED Objects -LED* led; -// LED* led1; -// LED* led2; -// ... - -// Timing variables -const int blinkForMSeconds = 10000; -const int blinkPeriodMSeconds = 1000; -const int blinkDuty = 90; -// const int blinkForMSeconds1 = 20000; -// const int blinkPeriodMSeconds1 = 500; -// const int blinkDuty1 = 25; -// const int blinkForMSeconds2 = 5000; -// const int blinkPeriodMSeconds2 = 1500; -// const int blinkDuty2 = 75; -// ... - -void setup(){ - delay(1000); - - led = new LED(pinLED); - // led1 = new LED(pinLED1); - // led2 = new LED(pinLED2); - // ... - - // Start threads - led->startBlinking(blinkForMSeconds, blinkPeriodMSeconds, blinkDuty); - //led1->startBlinking(blinkForMSeconds1, blinkPeriodMSeconds1, blinkDuty1); - //led2->startBlinking(blinkForMSeconds2, blinkPeriodMSeconds2, blinkDuty2)); - // ... - -} - -void loop(){ - // Implement main as needed -} diff --git a/lib/TeensyThreads-master/examples/Tests/Tests.ino b/lib/TeensyThreads-master/examples/Tests/Tests.ino deleted file mode 100644 index 3424ac3..0000000 --- a/lib/TeensyThreads-master/examples/Tests/Tests.ino +++ /dev/null @@ -1,403 +0,0 @@ -#include - -#include "TeensyThreads.h" - -volatile int p1 = 0; -volatile int p2 = 0; -volatile int p3 = 0; -volatile int p4 = 0; - -void my_priv_func1(int data){ - p1 = 0; - data *= 1000; // convert sec to ms; - int mx = millis(); - while(1) { - p1++; - if ((int)millis() - mx > data) break; - } -} - -void my_priv_func2() { - p2 = 0; - while(1) p2++; -} - -void my_priv_func3() { - p3 = 0; - while(1) p3++; -} - -void my_priv_func_lock(void *lock) { - Threads::Mutex *m = (Threads::Mutex *) lock; - p4 = 0; - m->lock(); - uint32_t mx = millis(); - while(millis() - mx < 500) p1++; - m->unlock(); -} - -Threads::Mutex count_lock; -volatile int count1 = 0; -volatile int count2 = 0; -volatile int count3 = 0; - -void lock_test1() { - while(1) { - count_lock.lock(); - for(int i=0; i<500; i++) count1++; - count_lock.unlock(); - } -} - -void lock_test2() { - while(1) { - count_lock.lock(); - for(int i=0; i<1000; i++) count2++; - count_lock.unlock(); - } -} - -void lock_test3() { - while(1) { - count_lock.lock(); - for(int i=0; i<100; i++) count3++; - count_lock.unlock(); - } -} - -int ratio_test(int a, int b, float r) { - float f = (float)a / (float)b; - if (a < b) f = 1.0/f; - if (f > r) return 1; - return 0; -} - - -void showp() { - Serial.print(p1); - Serial.print(" "); - Serial.print(p2); - Serial.print(" "); - Serial.print(p3); - Serial.println(); -} - -int id1, id2, id3; - -void delay2(uint32_t ms) -{ - int mx = millis(); - while(millis() - mx < ms); -} - -#define delayx delay - - -class subtest { -public: -int value; -void h(int x) { value = x; } -int test(Threads::Mutex *lk) { return lk->getState(); } -int getValue() { return value; } -} subinst; - -class WireTest { -public: -bool beginTransaction() { return 1; } -bool endTransaction() { return 1; } -bool other() { return 1; } -}; - -int stack_fault = 0; -int stack_id = 0; - -void stack_overflow_isr(void) { - stack_fault = 1; - threads.kill(threads.id()); -} - -// turn off optimizations or the optimizer will remove the recursion because -// it is smart enough to know it doesn't do anything -void __attribute__((optimize("O0"))) recursive_thread(int level) { - if (stack_fault) return; - char x[128]; // use up some stack space - delay(20); - recursive_thread(level+1); -} - -void runtest() { - int save_p; - int save_time; - float rate; - - // benchmark with no threading - my_priv_func1(1); - save_time = p1; - - Serial.print("CPU speed consistency "); - my_priv_func1(1); - rate = (float)p1 / (float)save_time; - if (rate < 1.2 && rate > 0.8) Serial.println("OK"); - else Serial.println("***FAIL***"); - - Serial.print("Test thread start "); - id1 = threads.addThread(my_priv_func1, 1); - delayx(300); - if (p1 != 0) Serial.println("OK"); - else Serial.println("***FAIL***"); - - Serial.print("Test thread run state "); - if (threads.getState(id1) == Threads::RUNNING) Serial.println("OK"); - else Serial.println("***FAIL***"); - - Serial.print("Test thread return "); - delayx(1000); - save_p = p1; - delayx(300); - if (p1 != 0 && p1 == save_p) Serial.println("OK"); - else Serial.println("***FAIL***"); - - Serial.print("Test thread speed "); - rate = (float)p1 / (float)save_time; - if (rate < 0.7 && rate > 0.3) Serial.println("OK"); - else Serial.println("***FAIL***"); - - Serial.print("Speed no threads: "); - Serial.println(save_time); - Serial.print("Speed 1 thread: "); - Serial.println(p1); - Serial.print("Ratio: "); - Serial.println(rate); - - Serial.print("Test set time slice "); - id1 = threads.addThread(my_priv_func1, 1); - delayx(2000); - save_p = p1; - id1 = threads.addThread(my_priv_func1, 1); - threads.setTimeSlice(id1, 200); - delayx(2000); - float expected = (float)save_p * 2.0*200.0 / ((float)threads.DEFAULT_TICKS + 200.0); - rate = (float)p1 / (float)expected; - if (rate > 0.9 && rate < 1.1) Serial.println("OK"); - else Serial.println("***FAIL***"); - - Serial.print("Speed default ticks: "); - Serial.println(save_p); - Serial.print("Speed 200 ticks: "); - Serial.println(p1); - Serial.print("Expected: "); - Serial.println(expected); - Serial.print("Ratio with expected: "); - Serial.println(rate); - - Serial.print("Test delay yield "); - id1 = threads.addThread(my_priv_func1, 1); - threads.delay(1100); - rate = (float)p1 / (float)save_time; - if (rate > 0.7 && rate < 1.4) Serial.println("OK"); - else Serial.println("***FAIL***"); - - Serial.print("Yield wait ratio: "); - Serial.println(rate); - - Serial.print("Test thread end state "); - if (threads.getState(id1) == Threads::ENDED) Serial.println("OK"); - else Serial.println("***FAIL***"); - - Serial.print("Test thread reinitialize "); - p2 = 0; - id2 = threads.addThread(my_priv_func2); - delayx(200); - if (p2 != 0) Serial.println("OK"); - else Serial.println("***FAIL***"); - - Serial.print("Test stack usage "); - int sz = threads.getStackUsed(id2); - // Seria.println(sz); - if (sz>=40 && sz<=48) Serial.println("OK"); - else Serial.println("***FAIL***"); - - Serial.print("Test thread suspend "); - delayx(200); - threads.suspend(id2); - delayx(200); - save_p = p2; - delayx(200); - if (p2 != 0 && p2 == save_p) Serial.println("OK"); - else Serial.println("***FAIL***"); - - Serial.print("Test thread restart "); - p2 = 0; - threads.restart(id2); - delayx(1000); - if (p2 != 0) Serial.println("OK"); - else Serial.println("***FAIL***"); - - Serial.print("Test thread stop "); - threads.stop(); - delayx(200); - p2 = 0; - delayx(200); - if (p2 == 0) Serial.println("OK"); - else Serial.println("***FAIL***"); - - Serial.print("Test thread start "); - threads.start(); - delayx(200); - if (p2 != 0) Serial.println("OK"); - else Serial.println("***FAIL***"); - - Serial.print("Test thread wait "); - id3 = threads.addThread(my_priv_func1, 1); - int time = millis(); - int r = threads.wait(id3); - delayx(100); - time = millis() - time; - if (r==id3) Serial.println("OK"); - else Serial.println("***FAIL***"); - - Serial.print("Test thread wait time "); - if (time > 1000 && time < 2000) Serial.println("OK"); - else Serial.println("***FAIL***"); - - Serial.print("Test thread kill "); - id3 = threads.addThread(my_priv_func1, 2); - delayx(300); - threads.kill(id3); - delayx(300); - save_p = p1; - delayx(300); - if (save_p==p1) Serial.println("OK"); - else Serial.println("***FAIL***"); - - delayx(1000); - - Serial.print("Test std::thread scope "); - { - std::thread th2(my_priv_func3); - delayx(500); - } - delayx(500); - save_p = p3; - delayx(500); - if (p3 != 0 && p3 == save_p) Serial.println("OK"); - else Serial.println("***FAIL***"); - - Serial.print("Test basic lock "); - id1 = threads.addThread(my_priv_func1, 2); - delayx(500); - { - Threads::Suspend lock; - save_p = p1; - delayx(500); - if (save_p == p1) Serial.println("OK"); - else Serial.println("***FAIL***"); - } - - Serial.print("Test basic unlock "); - delayx(500); - if (save_p != p1) Serial.println("OK"); - else Serial.println("***FAIL***"); - - - Serial.print("Test mutex lock state "); - Threads::Mutex mx; - mx.lock(); - r = mx.try_lock(); - if (r == 0) Serial.println("OK"); - else Serial.println("***FAIL***"); - - Serial.print("Test mutex lock thread "); - id1 = threads.addThread(my_priv_func_lock, &mx); - delayx(200); - if (p4 == 0) Serial.println("OK"); - else Serial.println("***FAIL***"); - - Serial.print("Test mutex unlock "); - mx.unlock(); - delayx(500); - if (p1 != 0) Serial.println("OK"); - else Serial.println("***FAIL***"); - - Serial.print("Test fast locks "); - id1 = threads.addThread(lock_test1); - id2 = threads.addThread(lock_test2); - id3 = threads.addThread(lock_test3); - delayx(3000); - threads.kill(id1); - threads.kill(id2); - threads.kill(id3); - if (ratio_test(count1, count2, 1.2)) Serial.println("***FAIL***"); - //else if (ratio_test(count1, count3, 1.2)) Serial.println("***FAIL***"); - else Serial.println("OK"); - - Serial.print(count1); - Serial.print(" "); - Serial.print(count2); - Serial.print(" "); - Serial.print(count3); - Serial.println(); - - Serial.print("Test std::mutex lock "); - std::mutex g_mutex; - { - std::lock_guard lock(g_mutex); - if (g_mutex.try_lock() == 0) Serial.println("OK"); - else Serial.println("***FAIL***"); - } - - Serial.print("Test std::mutex unlock "); - if (g_mutex.try_lock() == 1) Serial.println("OK"); - else Serial.println("***FAIL***"); - g_mutex.unlock(); - - Serial.print("Test Grab init "); - subinst.h(10); - ThreadWrap(subinst, sub2); - #define subinst ThreadClone(sub2) - if(subinst.getValue() == 10) Serial.println("OK"); - else Serial.println("***FAIL***"); - - Serial.print("Test Grab set "); - subinst.h(25); - if(subinst.getValue() == 25) Serial.println("OK"); - else Serial.println("***FAIL***"); - - Serial.print("Test Grab lock "); - if (subinst.test(&(sub2.getLock())) == 1) Serial.println("OK"); - else Serial.println("***FAIL***"); - - Serial.print("Test thread stack overflow "); - uint8_t *mstack = new uint8_t[1024]; - stack_id = threads.addThread(recursive_thread, 0, 512, mstack+512); - threads.delay(2000); - threads.kill(stack_id); - if (stack_fault) Serial.println("OK"); - else Serial.println("***FAIL***"); - delete[] mstack; -} - -void runloop() { - static int timeloop = millis(); - static int mx = 0; - static int count = 0; - if (millis() - mx > 5000) { - Serial.print(count); - Serial.print(": "); - Serial.print((millis() - timeloop)/1000); - Serial.print(" sec "); - showp(); - count++; - mx = millis(); - } -} - -void setup() { - delay(1000); - runtest(); - Serial.println("Test infinite loop (will not end)"); -} - -void loop() { - runloop(); -} diff --git a/lib/TeensyThreads-master/keywords.txt b/lib/TeensyThreads-master/keywords.txt deleted file mode 100644 index 3ab80dc..0000000 --- a/lib/TeensyThreads-master/keywords.txt +++ /dev/null @@ -1,3 +0,0 @@ -thread KEYWORD1 -multithreading KEYWORD2 -Teensy KEYWORD3 \ No newline at end of file diff --git a/lib/TeensyThreads-master/library.properties b/lib/TeensyThreads-master/library.properties deleted file mode 100644 index 728e56c..0000000 --- a/lib/TeensyThreads-master/library.properties +++ /dev/null @@ -1,10 +0,0 @@ -name=TeensyThreads -version=1.0.2 -author=Fernando Trias -maintainer=Fernando Trias -sentence=Pre-emptive threads for the Teensy 3 and 4 platform from PJRC. -paragraph=Threads allows two or more functions to appear to run simultanously with minimal changes to the code. This library supports threading directly (without needing RTOS install) by adding an "#include". -category=Other -url=https://github.com/ftrias/TeensyThreads -architectures=* -includes=TeensyThreads.h diff --git a/lib/TeensyThreads-master/license.txt b/lib/TeensyThreads-master/license.txt deleted file mode 100644 index 671b481..0000000 --- a/lib/TeensyThreads-master/license.txt +++ /dev/null @@ -1,16 +0,0 @@ -Copyright 2017 by Fernando Trias - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software -and associated documentation files (the "Software"), to deal in the Software without restriction, -including without limitation the rights to use, copy, modify, merge, publish, distribute, -sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or -substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/lib/TeensyThreads-master/readme.md b/lib/TeensyThreads-master/readme.md deleted file mode 100644 index b502138..0000000 --- a/lib/TeensyThreads-master/readme.md +++ /dev/null @@ -1,360 +0,0 @@ -Teensy Threading Library -=================================================== - -Teensy Threading Library implements preemptive threads for the Teensy 3 & 4 -platform from [PJRC](https://www.pjrc.com/teensy/index.html). It supports a -native interface and a `std::thread` interface. - -Official repsitory https://github.com/ftrias/TeensyThreads - -Simple example ------------------------------- - -```C++ -#include -volatile int count = 0; -void thread_func(int data){ - while(1) count += data; -} -void setup() { - threads.addThread(thread_func, 1); -} -void loop() { - Serial.println(count); -} -``` - -Or using std::thread - -```C++ -#include -volatile int count = 0; -void thread_func(int data){ - while(1) count += data; -} -void setup() { - std::thread th1(thread_func, 1); - th1.detach(); -} -void loop() { - Serial.println(count); -} -``` - -Install ------------------------------ -The easiest way to get started is to download the ZIP file from this repository and install it in Arduino using the menu `Sketch` / `Include Library` / `Add .ZIP Library`. - -You can then review the Examples provided `File` / `Examples` / `TeensyThreads`. - -Usage ------------------------------ -First, include the library with - -```C++ -#include -``` - -A global variable `threads` of `class Threads` will be created and used to -control the threading action. The library is hard-coded to support up to 16 threads, -but this may be changed in the source code of Threads.cpp. - -Threads are created by `threads.addThread()` with parameters: - ->`int addThread(func, arg, stack_size, stack)` -> ->- Returns an ID number or -1 for failure -> ->- **func** : function to call to perform thread work. This has the form of `void f(void *arg)` or `void f(int arg)` or `void f()` -> ->- **arg** : (optional) the `arg` passed to `func` when it starts. -> ->- **stack_size** : (optional) the size of the thread stack. If stack_size is 0 or missing, then 1024 is used. -> ->- **stack** : (optional) pointer to a buffer to use as stack. If stack is 0 or missing, then the buffer is allocated from the heap. - -All threads start immediately and run until the function terminates (usually with -a return). - -Once a thread ends because the function returns, then the thread will be reused -by a new function. - -If a stack has been allocated by the library and not supplied by the caller, it -will be freed when a new thread is added, not when it terminates. If the stack -was supplied by the caller, the caller must free it if needed. - -The following members of `class Threads` control threads. Items in all caps -are constants in `Threads` and are accessed as in `Threads::EMPTY`. - -Threads | Description ---- | --- -int id(); | Get the id of the currently running thread -int getState(int id); | Get the state; see class constants. Can be EMPTY, RUNNING, ENDED, SUSPENDED. -int wait(int id, unsigned int timeout_ms = 0) | Wait until thread ends, up to timeout_ms milliseconds. If 0, wait indefinitely. -int kill(int id) | Permanently stop a running thread. Thread will end on the next thread slice tick. -int suspend(int id) |Suspend a thread (on the next slice tick). Can be restarted with restart(). -int restart(int id); | Restart a suspended thread. -int setSliceMillis(int milliseconds) | Set each time slice to be 'milliseconds' long -int setSliceMicros(int microseconds) | Set each time slice to be 'microseconds' long -void yield() | Yield current thread's remaining time slice to the next thread, causing immedidate context switch -void delay(int millisecond) | Wait for milliseconds using yield(), giving other slices your wait time -int start(int new_state = -1) | Start/restart threading system; returns previous state. Optionally pass STARTED, STOPPED, FIRST_RUN to restore a different state. -int stop() | Stop threading system; returns previous state: STARTED, STOPPED, FIRST_RUN -**Advanced functions** | -void setDefaultStackSize(unsigned int bytes_size) | Set the stack size for new threads in bytes -void setTimeSlice(int id, unsigned int ticks) | Set the slice length time in ticks for a thread (1 tick = 1 millisecond, unless using MicroTimer) -void setDefaultTimeSlice(unsigned int ticks) |Set the slice length time in ticks for all new threads (1 tick = 1 millisecond, unless using MicroTimer) -int setMicroTimer(int tick_microseconds = DEFAULT_TICK_MICROSECONDS) | use the microsecond timer provided by IntervalTimer & PIT; instead of 1 tick = 1 millisecond, 1 tick will be the number of microseconds provided (default is 100 microseconds) -**Power saving** | -void idle() | called in main loop to execute sleep, etc. -void sleep(int ms) | suspend CPU for ms milliseconds. Must call `setSleepCallback()` first. -void setSleepCallback(int (*)(int)) | Set sleep callback function that puts CPU to sleep - - -In addition, the Threads class has a member class for mutexes (or locks): - -Threads::Mutex | Description ---- | --- -int getState() | Get the lock state; 1+=locked; 0=unlocked -int lock(unsigned int timeout_ms = 0) | Lock, optionally waiting up to timeout_ms milliseconds -int try_lock() | If lock available, get it and return 1; otherwise return 0 -int unlock() | Unlock if locked - -When possible, it's best to use `Threads::Scope` instead of `Threads::Mutex` to ensure orderly locking and unlocking. - -Threads::Scope | Description ---- | --- -Scope(Mutex& m) | On creation, mutex is locked -~Scope() | On descruction, it is unlocked - -```C++ - // example of manual locking/unlocking - Threads::Mutex mylock; - mylock.lock(); - x = 1; - mylock.unlock(); - - // example of automatic locking/unlocking - if (y) { - Threads::Scope m(mylock); // lock on creation - x = 2; - } // unlock at end of scope -``` - -Usage notes ------------------------------ - -The optimizer sometimes has strange side effects because it thinks variables -can't be changed within code. For example, if one thread modifies a variable -and another thread checks for it, the second thread's check may be optimized -away. Here is an example: - -```C++ -// BUGGY CODE -int state = 0; // this should be "volatile int state" -void thread1() { state = processData(); } -void run() { - while (state < 100) { // this line changed to 'if' - // do something - } -} -``` - -In the code above, seeing that `state` is not changed in the loop, the -optimizer will convert the `while (state<100)` into an `if` statement. Adding -`volatile` to the declaration of `int state` will usually remedy this (as in -`volatile int state`). - -```C++ -// CORRECT CODE -volatile int state = 0; -void thread1() { state = processData(); } -void run() { - while (state < 100) { // this line changed to 'if' - // do something - } -} -``` - -Locking ------------------------------ - -Because the Teensy libraries are not usually thread-safe, it's best to only use -one library in one thread. For example, if using the Wire library, it should -always be used in a single thread. If this cannot be done, then all uses -should be surrounded by locks. - -For example: - -```C++ - Threads::Mutex wire_lock; - - void init() - { - Threads::Scope scope(wire_lock); - Wire.beginTransmission(17); - Wire.write(0x1F); - Wire.write(0x31); - Wire.endTransmission(); - } -``` - -Experimental: For widely used libraries like Serial, adding locks may require -vast changes to the code. Because of this, the library provides a helper class -and set of macros to encapsulate all method calls with a lock. An example -illustrates its use: - -```C++ -// this method is experimental -ThreadWrap(Serial, SerialXtra); -#define Serial ThreadClone(SerialXtra) - -int thread_func() -{ - Serial.println("begin"); -} -``` - -In the code above, every time `Serial` is used, it will first lock a mutex, -then call the desired method, then unlock the mutex. This shortcut will only -work on all the code located below the `#define` line. More information -about the mechanics can be found by looking at the source code. - - -Alternative std::thread interface ------------------------------ - -The library also supports the construction of minimal `std::thread` as used -in C++11. `std::thread` always allocates its own stack of the default size. In -addition, a minimal `std::mutex` and `std::lock_guard` are also implemented. -See http://www.cplusplus.com/reference/thread/thread/ - -Example: - -```C++ -void run() { - std::thread first(thread_func); - first.detach(); -} -``` - -The following members are implemented: - -```C++ -namespace std { - class thread { - bool joinable(); - void detach(); - void join(); - int get_id(); - } - class mutex { - void lock(); - bool try_lock(); - void unlock(); - }; - template class lock_guard { - lock_guard(Mutex& m); - } -} -``` - -Notes on implementation ------------------------------ - -Threads take turns on the CPU and are switched by the `context_switch()` -function, written in assembly. This function is called by the SysTick ISR. The -library overrides the default `systick_isr()` to accomplish switching. On the -Teensy by default, each tick is 1 millisecond long. By default, each thread -runs for 100 ticks, or 100 milliseconds, but this can be changed by -`setTimeSlice()`. - -Much of the Teensy core software is thread-safe, but not all. When in doubt, -stop and restart threading in critical areas. In general, functions that share -global variables or state should not be called on different threads at the -same time. For example, don't use Serial in two different threads -simultaneously; it's ok to make calls on different threads at different times. - -The code comments on the source code give some technical explanation of the -context switch process: - -```C -/* - * context_switch() changes the context to a new thread. It follows this strategy: - * - * 1. Abort if called from within an interrupt - * 2. Save registers r4-r11 to the current thread state (s0-s31 is using FPU) - * 3. If not running on MSP, save PSP to the current thread state - * 4. Get the next running thread state - * 5. Restore r4-r11 from thread state (s0-s31 for FPU) - * 6. Set MSP or PSP depending on state - * 7. Switch MSP/PSP on return - * - * Notes: - * - Cortex-M4 has two stack pointers, MSP and PSP, which I alternate. See the - * CPU reference manual under the Exception Model section. - * - I tried coding this in asm embedded in Threads.cpp but the compiler - * optimizations kept changing my code and removing lines so I have to use - * a separate assembly file. But if you try C++, make sure to declare the - * function "naked" so the stack pointer SP is not modified when called. - * This means you can't use local variables, which are stored in stack. - * Also turn optimizations off using optimize("O0"). - * - Function is called from systick_isr (also naked) via a branch. Again, this is - * to preserve the stack and LR. I override the default systick_isr(). - * - Since Systick can be called from within another interrupt, I check - * for this and abort. - * - Teensy uses MSP for it's main thread; I preserve that. Alternatively, I - * could have used PSP for all threads, including main, and reserve MSP for - * interrupts only. This would simplify the code slightly, but could introduce - * incompatabilities. - * - If this interrupt is nested within another interrupt, all kinds of bad - * things can happen. This is especially true if usb_isr() is active. In theory - * we should be able to do a switch even within an interrupt, but in my - * tests, it would not work reliably. - */ -``` - -Todo ------------------------------ - -- Optimize assembler and other switching code. -- Support unlimited threads. -- Check for stack overflow during context_change() to aid in debugging; -or have a stack that grows automatically if it gets close filling. -- Fully implement the new C++11 std::thread or POSIX threads. - See http://www.cplusplus.com/reference/thread/thread/. - -Changes ------------------------------ - -Revision 0.2: March 2017 -1. Change default time slice to 10 milliseconds -2. Add setDefaultTimeSlice(), setDefaultStackSize(). -3. Support slices smaller than 1 ms using IntervalTimer; see setMicroTimer(). -4. Rename to use TeensyThreads.h to avoid conflicts - -Revision 0.3: April 2017 -1. Rename Threads::Lock to Threads::Suspend -2. Add setSliceMicros() and setSliceMillis() -3. "lock" will suspend blocking thread until "unlock" and then give thread priority -4. Add ThreadWrap macro and supporting classes -5. Support linking with LTO (link time optimization) - -Revision 0.4: July 2017 -1. Make ThreadInfo dynamic, saving memory for unused threads - -Other ------------------------------ - -See this thread for development discussion: - -https://forum.pjrc.com/threads/41504-Teensy-3-x-multithreading-library-first-release - -This project came about because I was coding a Teensy application with multiple -things happening at the same time, wistfully reminiscing about multithreading -available in other OSs. I searched for threading tools, but found nothing for my -situation. This combined with boredom and abundant free time resulting in -complete overkill for the solution and thus this implementation of preemptive -threads. - -Copyright 2017 by Fernando Trias. See license.txt for details. diff --git a/lib/TeensyTimerTool-master/.clang-format b/lib/TeensyTimerTool-master/.clang-format deleted file mode 100644 index 9600f32..0000000 --- a/lib/TeensyTimerTool-master/.clang-format +++ /dev/null @@ -1,47 +0,0 @@ ---- -Standard: Cpp11 -BasedOnStyle: LLVM - -IndentWidth: 4 -TabWidth: 4 -AccessModifierOffset: -3 -ColumnLimit: 0 -UseTab: Never - -AllowShortIfStatementsOnASingleLine: WithoutElse -AllowShortLoopsOnASingleLine : true -AllowShortBlocksOnASingleLine: true -AllowShortCaseLabelsOnASingleLine: true -AllowShortEnumsOnASingleLine: true - -IndentCaseLabels: true - -PointerAlignment: Right - -AlignTrailingComments: true -AlignConsecutiveAssignments: true -AlignOperands : AlignAfterOperator - -NamespaceIndentation: All -FixNamespaceComments: true - -CompactNamespaces: true - -BreakBeforeBraces: Custom -BraceWrapping: - AfterStruct: true - AfterClass: true - AfterControlStatement: true - AfterNamespace: true - AfterFunction: true - AfterUnion: true - AfterExternBlock: false - AfterEnum: false - BeforeElse: false - SplitEmptyFunction: false - SplitEmptyRecord: true - SplitEmptyNamespace: true - -AlwaysBreakTemplateDeclarations: No - -IncludeBlocks: Merge diff --git a/lib/TeensyTimerTool-master/.gitignore b/lib/TeensyTimerTool-master/.gitignore deleted file mode 100644 index ec31aa0..0000000 --- a/lib/TeensyTimerTool-master/.gitignore +++ /dev/null @@ -1,37 +0,0 @@ -*.mk - -# Prerequisites -*.d - -# Compiled Object files -*.slo -*.lo -*.o -*.obj -*.hex -*.lst - -# Precompiled Headers -*.gch -*.pch - -# Compiled Dynamic libraries -*.so -*.dylib -*.dll - -# Fortran module files -*.mod -*.smod - -# Compiled Static libraries -*.lai -*.la -*.a -*.lib - -# Executables -*.exe -*.out -*.app -*.elf diff --git a/lib/TeensyTimerTool-master/LICENSE b/lib/TeensyTimerTool-master/LICENSE deleted file mode 100644 index 00b7427..0000000 --- a/lib/TeensyTimerTool-master/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2019 Lutz Niggl - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/lib/TeensyTimerTool-master/README.md b/lib/TeensyTimerTool-master/README.md deleted file mode 100644 index 0202484..0000000 --- a/lib/TeensyTimerTool-master/README.md +++ /dev/null @@ -1,7 +0,0 @@ -# TeensyTimerTool - -The TeensyTimerTool is a library that provides a generic, easy to use interface to the hardware timers of the PJRC Teensy boards. In addition, it provides up to 20 highly efficient software timers that use the same interface. All timers can be used in periodic and one-shot mode. Currently the library supports the ARM T3.X and T4.0 boards. - -- This way to the corresponding PJRC **[forum post](https://forum.pjrc.com/threads/59112-TeensyTimerTool)** -- This way to the documentation in the **[TeensyTimerTool WIKI](https://github.com/luni64/TeensyTimerTool/wiki)** - diff --git a/lib/TeensyTimerTool-master/assets/FTM0_8CH.jpg b/lib/TeensyTimerTool-master/assets/FTM0_8CH.jpg deleted file mode 100644 index 077c650..0000000 Binary files a/lib/TeensyTimerTool-master/assets/FTM0_8CH.jpg and /dev/null differ diff --git a/lib/TeensyTimerTool-master/examples/.gitignore b/lib/TeensyTimerTool-master/examples/.gitignore deleted file mode 100644 index 4d99dd0..0000000 --- a/lib/TeensyTimerTool-master/examples/.gitignore +++ /dev/null @@ -1,7 +0,0 @@ -# vsTeensy Stuff -**/.vsteensy -**/.vscode -**/makefile - - - diff --git a/lib/TeensyTimerTool-master/examples/01_Basic/ArrayOfTimers/ArrayOfTimers.ino b/lib/TeensyTimerTool-master/examples/01_Basic/ArrayOfTimers/ArrayOfTimers.ino deleted file mode 100644 index 9b20e26..0000000 --- a/lib/TeensyTimerTool-master/examples/01_Basic/ArrayOfTimers/ArrayOfTimers.ino +++ /dev/null @@ -1,31 +0,0 @@ -#include "TeensyTimerTool.h" -using namespace TeensyTimerTool; - - - -//Timer t[]{FTM0, FTM0, FTM2}; // two channels from FTM0, one from FTM2 -//Timer t[3]; // use 3 timers from the pool -OneShotTimer t[]{FTM0, FTM0, FTM0, FTM0, FTM0, FTM0, FTM0, FTM0}; // all 8 channels of FTM0 - -constexpr unsigned nrOfTimers = sizeof(t) / sizeof(t[0]); - -void setup() -{ - // setup timers, use lambdas as callbacks - for (unsigned i = 0; i < nrOfTimers; i++) - { - pinMode(i, OUTPUT); - t[i].begin([i] { digitalWriteFast(i, LOW); }); // callback resets pin to LOW - } -} - - -void loop() -{ - for (unsigned i = 0; i < nrOfTimers; i++) - { - digitalWriteFast(i, HIGH); - t[i].trigger(50 * (i + 1)); // 50, 100, 150 ... µs - } - delay(1); -} diff --git a/lib/TeensyTimerTool-master/examples/01_Basic/ArrayOfTimers/README.md b/lib/TeensyTimerTool-master/examples/01_Basic/ArrayOfTimers/README.md deleted file mode 100644 index 2ee08f0..0000000 --- a/lib/TeensyTimerTool-master/examples/01_Basic/ArrayOfTimers/README.md +++ /dev/null @@ -1,3 +0,0 @@ -Measured output of the example sketch - -![Output](./../../assets/FTM0_8CH.jpg) \ No newline at end of file diff --git a/lib/TeensyTimerTool-master/examples/01_Basic/HelloOneShot/HelloOneShot.ino b/lib/TeensyTimerTool-master/examples/01_Basic/HelloOneShot/HelloOneShot.ino deleted file mode 100644 index f11fa1d..0000000 --- a/lib/TeensyTimerTool-master/examples/01_Basic/HelloOneShot/HelloOneShot.ino +++ /dev/null @@ -1,26 +0,0 @@ -#include "Arduino.h" -#include "TeensyTimerTool.h" - -using namespace TeensyTimerTool; - -void callback() -{ - digitalWriteFast(LED_BUILTIN, LOW); // switch off LED -} - - -OneShotTimer timer1; // generate a timer from the pool (Pool: 2xGPT, 16xTMR(QUAD), 20xTCK) - -void setup() -{ - pinMode(LED_BUILTIN,OUTPUT); - timer1.begin(callback); -} - -void loop() -{ - digitalWriteFast(LED_BUILTIN, HIGH); - timer1.trigger(10'000); // switch of after 10ms - - delay(500); -} diff --git a/lib/TeensyTimerTool-master/examples/01_Basic/HelloPeriodic/HelloPeriodic.ino b/lib/TeensyTimerTool-master/examples/01_Basic/HelloPeriodic/HelloPeriodic.ino deleted file mode 100644 index e4ecc97..0000000 --- a/lib/TeensyTimerTool-master/examples/01_Basic/HelloPeriodic/HelloPeriodic.ino +++ /dev/null @@ -1,29 +0,0 @@ -/******************************************************** - * Basic usage of the timer - * - * Generates a timer from the timer pool and - * starts it with a period of 250ms. - * The timer callback simply toggles the built in LED - * - ********************************************************/ - -#include "TeensyTimerTool.h" - -using namespace TeensyTimerTool; - -void callback() -{ - digitalWriteFast(LED_BUILTIN, !digitalReadFast(LED_BUILTIN)); -} - -PeriodicTimer t1; // generate a timer from the pool (Pool: 2xGPT, 16xTMR(QUAD), 20xTCK) - -void setup() -{ - pinMode(LED_BUILTIN,OUTPUT); - t1.begin(callback, 250'000); // 250ms -} - -void loop() -{ -} diff --git a/lib/TeensyTimerTool-master/examples/01_Basic/MoreTimers/MoreTimers.ino b/lib/TeensyTimerTool-master/examples/01_Basic/MoreTimers/MoreTimers.ino deleted file mode 100644 index fba91cb..0000000 --- a/lib/TeensyTimerTool-master/examples/01_Basic/MoreTimers/MoreTimers.ino +++ /dev/null @@ -1,55 +0,0 @@ -//----------------------- -// REQUIRES T4.x -//----------------------- - -#include "TeensyTimerTool.h" - -using namespace TeensyTimerTool; - -PeriodicTimer t1(TCK); // Tick-Timer does not use any hardware timer (20 32bit channels) -PeriodicTimer t2(TMR1); // First channel on TMR1 aka QUAD timer module. (TMR1 - TMR4, four 16bit channels each) -PeriodicTimer t3(GPT1); // GPT1 module (one 32bit channel per module) -OneShotTimer t4(TMR1); // Second channel on TMR1 - -// Callbacks =================================================================================== - -void pulse200ns() -{ - digitalWriteFast(1, HIGH); - delayNanoseconds(200); - digitalWriteFast(1, LOW); -} - -void pulse400ns() -{ - digitalWriteFast(2, HIGH); - delayNanoseconds(400); - digitalWriteFast(2, LOW); -} - -void LED_ON() -{ - digitalWriteFast(LED_BUILTIN, HIGH); // LED On - t4.trigger(10'000); // trigger t4 to switch of after 10ms -} - -void LED_OFF() -{ - digitalWriteFast(LED_BUILTIN, LOW); -} - -//================================================================================================ - -void setup() -{ - for (unsigned pin = 0; pin <= 13; pin++) pinMode(pin, OUTPUT); - - t1.begin(pulse200ns, 50'000); // 200ns pulse every 500 ms - t2.begin(pulse400ns, 100); // 400ns pulse every 100 µs - t3.begin(LED_ON, 1'000'000); // Switch LED on every second - t4.begin(LED_OFF); // One shot timer to switch LED Off -} - -void loop() -{ -} diff --git a/lib/TeensyTimerTool-master/examples/01_Basic/RTC_Timer/RTC_Timer.ino b/lib/TeensyTimerTool-master/examples/01_Basic/RTC_Timer/RTC_Timer.ino deleted file mode 100644 index b24ca2c..0000000 --- a/lib/TeensyTimerTool-master/examples/01_Basic/RTC_Timer/RTC_Timer.ino +++ /dev/null @@ -1,33 +0,0 @@ -// Uses the built in Real Time Clock (RTC) as timebase. -// The sketch calculates the relative drift of the main 24MHz crystal relative to the 32.768kHz RTC crystal. -// Requires a T4.x board - -#include "Arduino.h" -#include "TeensyTimerTool.h" -using namespace TeensyTimerTool; - -PeriodicTimer t1(TCK_RTC); - -constexpr uint32_t period = 500'000; //µs - -void callback() -{ - static uint32_t start = micros(); - static uint32_t idx = 0; - - uint32_t now = micros() - start; - uint32_t expected = idx++ * period; - int32_t delta = now - expected; - float drift = 1E6 * delta / expected; // ppm - - Serial.printf("t: %d µs, rel. drift: %.2f ppm\n", now, drift); -} - -void setup() -{ - t1.begin(callback, period); -} - -void loop() -{ -} diff --git a/lib/TeensyTimerTool-master/examples/01_Basic/UsingChronoDurations1/UsingChronoDurations1.ino b/lib/TeensyTimerTool-master/examples/01_Basic/UsingChronoDurations1/UsingChronoDurations1.ino deleted file mode 100644 index fb33295..0000000 --- a/lib/TeensyTimerTool-master/examples/01_Basic/UsingChronoDurations1/UsingChronoDurations1.ino +++ /dev/null @@ -1,34 +0,0 @@ -#include "TeensyTimerTool.h" -using namespace TeensyTimerTool; - -PeriodicTimer t1(TCK); -PeriodicTimer t2(TCK); - -void isr1() -{ - Serial.printf("called @: %u ms\n", millis()); -} - -void isr2() -{ - digitalToggleFast(LED_BUILTIN); -} - -void isr3() -{ - digitalWriteFast(0,HIGH); - delayMicroseconds(10); - digitalWriteFast(0, LOW); -} - -void setup() -{ - pinMode(LED_BUILTIN, OUTPUT); - - t1.begin(isr1, 5.02s); // instead of 5020000 (µs) - t2.begin(isr2, 25ms); // instead of 25000 (µs) -} - -void loop() -{ -} diff --git a/lib/TeensyTimerTool-master/examples/01_Basic/UsingChronoDurations2/UsingChronoDurations2.ino b/lib/TeensyTimerTool-master/examples/01_Basic/UsingChronoDurations2/UsingChronoDurations2.ino deleted file mode 100644 index 401c0da..0000000 --- a/lib/TeensyTimerTool-master/examples/01_Basic/UsingChronoDurations2/UsingChronoDurations2.ino +++ /dev/null @@ -1,33 +0,0 @@ -#include "TeensyTimerTool.h" -using namespace TeensyTimerTool; - -OneShotTimer timer[]{TCK, TCK, TCK, TCK}; // 4 one-shot-timers -PeriodicTimer pt1; // 1 periodic timer -unsigned t_0; // start time - -void isr() -{ - Serial.printf("called @: %u ms\n", millis() - t_0); -} - -void setup() -{ - while (!Serial) {} // wait for PC to connect the virtual serial port - - for (OneShotTimer& t : timer) // for the sake of simplicity, attach the same isr to all timers in array - { - t.begin(isr); - } - - timer[0].trigger(10ms); // 10 ms - timer[1].trigger(0.5s + 10ms); // 510 ms - timer[2].trigger(2.5 * 0.3s + 20'000us / 2); // 760 ms - timer[3].trigger(milliseconds(50) + microseconds(5000)); // 55ms - t_0 = millis(); - - pt1.begin([] { digitalToggleFast(LED_BUILTIN); }, 0.5s); -} - -void loop() -{ -} diff --git a/lib/TeensyTimerTool-master/examples/02_Advanced/CallbackWithParams/CallbackWithParams.ino b/lib/TeensyTimerTool-master/examples/02_Advanced/CallbackWithParams/CallbackWithParams.ino deleted file mode 100644 index c359b35..0000000 --- a/lib/TeensyTimerTool-master/examples/02_Advanced/CallbackWithParams/CallbackWithParams.ino +++ /dev/null @@ -1,29 +0,0 @@ -#include "TeensyTimerTool.h" - -using namespace TeensyTimerTool; - -void callback(int& someInt, int cnt) // this callback has context, i.e. parameter -{ - for (int i = 0; i < cnt; i++) // when called, print out someInt cnt times - { - Serial.print(someInt); - Serial.print(" | "); - } - Serial.println(); -} - -//============================================================== - -PeriodicTimer t; -int number = 0; - -void setup() -{ - t.begin([] { callback(number, 5); }, 50ms); -} - -void loop() -{ - number++; // change every second - delay(1000); -} \ No newline at end of file diff --git a/lib/TeensyTimerTool-master/examples/02_Advanced/CapturingLambdas/CapturingLambdas.ino b/lib/TeensyTimerTool-master/examples/02_Advanced/CapturingLambdas/CapturingLambdas.ino deleted file mode 100644 index 0219f64..0000000 --- a/lib/TeensyTimerTool-master/examples/02_Advanced/CapturingLambdas/CapturingLambdas.ino +++ /dev/null @@ -1,24 +0,0 @@ - -#include "TeensyTimerTool.h" - -using namespace TeensyTimerTool; - -// Array of 10 tick timers -PeriodicTimer timer[]{ - TCK, TCK, TCK, TCK, TCK, - TCK, TCK, TCK, TCK, TCK}; - -void onTimer(int nr){ - Serial.printf("Timer #%d at %d\n", nr, millis()); -} - -void setup(){ - // start all 10 timers with random period. Pass timer number to callback - for (int i = 0; i < 10; i++) - { - timer[i].begin([i] { onTimer(i); }, random(100'000, 900'000)); - } -} - -void loop(){ -} diff --git a/lib/TeensyTimerTool-master/examples/02_Advanced/UsingLambdas/UsingLambdas.ino b/lib/TeensyTimerTool-master/examples/02_Advanced/UsingLambdas/UsingLambdas.ino deleted file mode 100644 index 254c2d1..0000000 --- a/lib/TeensyTimerTool-master/examples/02_Advanced/UsingLambdas/UsingLambdas.ino +++ /dev/null @@ -1,19 +0,0 @@ - -#include "TeensyTimerTool.h" -using namespace TeensyTimerTool; - -OneShotTimer timer; - -void setup() -{ - pinMode(LED_BUILTIN, OUTPUT); - - timer.begin([] { digitalWriteFast(LED_BUILTIN, LOW); }); -} - -void loop() -{ - digitalWriteFast(LED_BUILTIN, HIGH); // switch on LED - timer.trigger(25'000); // switch off after 25ms - delay(1'000); // repeat every second -} diff --git a/lib/TeensyTimerTool-master/examples/03_Applications/DoubleExposure/DoubleExposure.ino b/lib/TeensyTimerTool-master/examples/03_Applications/DoubleExposure/DoubleExposure.ino deleted file mode 100644 index d3e3a48..0000000 --- a/lib/TeensyTimerTool-master/examples/03_Applications/DoubleExposure/DoubleExposure.ino +++ /dev/null @@ -1,38 +0,0 @@ -#include "SystemController.h" - -// --> Uncomment if you have a control voltage on the pot pin <-- -// #include "ResponsiveAnalogRead.h" -// constexpr unsigned potPin = A0; -// ResponsiveAnalogRead pot(potPin, false); - -SystemController sysControl; - -void setup() -{ - sysControl.begin(); - - sysControl.setExposureDelay(250); // set exposure delay (time between two exposures) to 250 µs - sysControl.shoot(); // do a manual exposure - delay(10); - sysControl.setExposureDelay(500); // same with 500µs delay between exposures - sysControl.shoot(); - - sysControl.continuosMode(true); // start continuously shooting - delay(1000); - sysControl.continuosMode(false); // stop after one second - - delay(500); - sysControl.continuosMode(true); // start again -} - -void loop() -{ - // --> Uncomment if you have a control voltage on the pot pin <-- - // pot.update(); - // if (pot.hasChanged()) - // { - // unsigned expDelay = map(pot.getValue(), 0, 1023, 100, 500); // 0-3.3V analog value, maps to 100-500 - // controller.setExposureDelay(expDelay); - // Serial.printf("Exposure Delay: %u µs\n", expDelay); - // } -} diff --git a/lib/TeensyTimerTool-master/examples/03_Applications/DoubleExposure/LaserController.h b/lib/TeensyTimerTool-master/examples/03_Applications/DoubleExposure/LaserController.h deleted file mode 100644 index fcdb72a..0000000 --- a/lib/TeensyTimerTool-master/examples/03_Applications/DoubleExposure/LaserController.h +++ /dev/null @@ -1,32 +0,0 @@ -#pragma once -#include "PulseGenerator.h" -#include "TeensyTimerTool.h" - -class LaserController -{ - public: - void begin(unsigned preTriggerPin, unsigned triggerPin, unsigned camPin); - void shoot(); - - protected: - PulseGenerator preTrigger, trigger, camera; -}; - -void LaserController::begin(unsigned preTriggerPin, unsigned triggerPin, unsigned camPin) -{ - preTrigger.begin(preTriggerPin); - trigger.begin(triggerPin); - camera.begin(camPin); -} - -void LaserController::shoot() -{ - constexpr float t_warmup = 140 - 5.5; - constexpr float t_p = 10 - 3; - constexpr float t_camDelay = 130 - 7.5; - constexpr float t_int = 30 - 3; - - preTrigger.schedulePulse(0, t_p); // immediately generate the pretrigger pulse - trigger.schedulePulse(t_warmup, t_p); // schedule the trigger pulse to start after the warmup time - camera.schedulePulse(t_camDelay, t_int); // schedule the cam pulse after the camDelay time -} diff --git a/lib/TeensyTimerTool-master/examples/03_Applications/DoubleExposure/PulseGenerator.h b/lib/TeensyTimerTool-master/examples/03_Applications/DoubleExposure/PulseGenerator.h deleted file mode 100644 index 9a1ff34..0000000 --- a/lib/TeensyTimerTool-master/examples/03_Applications/DoubleExposure/PulseGenerator.h +++ /dev/null @@ -1,61 +0,0 @@ -#pragma once - -#include "Arduino.h" -#include "TeensyTimerTool.h" - -class PulseGenerator -{ - public: - PulseGenerator(); // constructor, initializes non hardware related stuff - void begin(unsigned pin); // initializes hardware related stuff - void schedulePulse(float delay, float width); // schedules a 'width µs' wide pulse after a waiting time of 'delay µs'. Non blocking. - - protected: - TeensyTimerTool::OneShotTimer pulseTimer; // used for generating the pulses - void callback(); - - uint32_t pin; - float width; -}; - - - -void PulseGenerator::begin(unsigned pin) -{ - this->pin = pin; - pinMode(pin, OUTPUT); - digitalWriteFast(pin, LOW); - - pulseTimer.begin([this] { this->callback(); }); -} - -void PulseGenerator::schedulePulse(float delay, float _width) -{ - width = _width; // the timer callback needs to know the pulse width to generate the pulse - - if (delay != 0) - { - pulseTimer.trigger(delay); // this triggers the oneShot timer to fire after 'delay µs' - } - else //delay == 0, directly generate the pulse - { - digitalWriteFast(pin, HIGH); - pulseTimer.trigger(width); // this triggers the oneShotTimer to fire after 'width µs' - } -} - -void PulseGenerator::callback() -{ - if (digitalReadFast(pin) == LOW) - { - digitalWriteFast(pin, HIGH); - pulseTimer.trigger(width); // re-trigger - } else - { - digitalWriteFast(pin, LOW); - } -} - -PulseGenerator::PulseGenerator() - : pulseTimer(TeensyTimerTool::FTM0) // use one of the 8 FTM0 channels -{} \ No newline at end of file diff --git a/lib/TeensyTimerTool-master/examples/03_Applications/DoubleExposure/README.md b/lib/TeensyTimerTool-master/examples/03_Applications/DoubleExposure/README.md deleted file mode 100644 index bec8308..0000000 --- a/lib/TeensyTimerTool-master/examples/03_Applications/DoubleExposure/README.md +++ /dev/null @@ -1 +0,0 @@ -### See https://github.com/luni64/TeensyTimerTool/wiki/Double-Exposure-Laser-Illuminator for a description of this example. diff --git a/lib/TeensyTimerTool-master/examples/03_Applications/DoubleExposure/SystemController.h b/lib/TeensyTimerTool-master/examples/03_Applications/DoubleExposure/SystemController.h deleted file mode 100644 index c9091b2..0000000 --- a/lib/TeensyTimerTool-master/examples/03_Applications/DoubleExposure/SystemController.h +++ /dev/null @@ -1,62 +0,0 @@ -#pragma once -#include "LaserController.h" -#include "TeensyTimerTool.h" - -class SystemController -{ - public: - SystemController(); - inline void begin(); - inline void shoot(); - - inline void continuosMode(bool on); - inline void setExposureDelay(unsigned delay); - - protected: - TeensyTimerTool::PeriodicTimer mainTimer; - LaserController lCtrl1, lCtrl2; - unsigned exposureDelay = 300; -}; - -SystemController::SystemController() - : mainTimer(TeensyTimerTool::TCK) {} // construct the main 15Hz timer, we use a TCK here - -void SystemController::begin() -{ - constexpr unsigned repetitionRate = 15; // Hz - - constexpr unsigned preTrig1_pin = 1; - constexpr unsigned trig1_pin = 2; - constexpr unsigned preTrig2_pin = 3; - constexpr unsigned trig2_pin = 4; - constexpr unsigned cam_pin = 5; - - lCtrl1.begin(preTrig1_pin, trig1_pin, cam_pin); - lCtrl2.begin(preTrig2_pin, trig2_pin, cam_pin); - - mainTimer.begin([this] { this->shoot(); }, 1E6 / repetitionRate, false); // attach callback but don't start yet -} - -void SystemController::shoot() -{ - elapsedMicros stopwatch = 0; - lCtrl1.shoot(); - while (stopwatch < exposureDelay) { yield(); } - lCtrl2.shoot(); -} - -void SystemController::continuosMode(bool on) -{ - if (on) - { - mainTimer.start(); - } else - { - mainTimer.stop(); - } -} - -void SystemController::setExposureDelay(unsigned delay) -{ - exposureDelay = max(100u, min(500u, delay)); // limit to 100-500 µs -} diff --git a/lib/TeensyTimerTool-master/examples/99_Misc/PinInformation/.clang-format b/lib/TeensyTimerTool-master/examples/99_Misc/PinInformation/.clang-format deleted file mode 100644 index fe7aa54..0000000 --- a/lib/TeensyTimerTool-master/examples/99_Misc/PinInformation/.clang-format +++ /dev/null @@ -1,42 +0,0 @@ ---- -Standard: Cpp11 -BasedOnStyle: LLVM - -IndentWidth: 4 -TabWidth: 4 -AccessModifierOffset: -3 -ColumnLimit: 0 -UseTab: Never - -AllowShortIfStatementsOnASingleLine: true -AllowShortLoopsOnASingleLine : true -AllowShortBlocksOnASingleLine: true -IndentCaseLabels: true - -PointerAlignment: Left - -AlignTrailingComments: true - -NamespaceIndentation: All -FixNamespaceComments: false - -IndentPPDirectives: AfterHash - -CompactNamespaces: true - -BreakBeforeBraces: Custom -BraceWrapping: - AfterStruct: true - AfterClass: true - AfterControlStatement: true - AfterNamespace: true - AfterFunction: true - AfterUnion: true - AfterExternBlock: false - AfterEnum: false - BeforeElse: false - SplitEmptyFunction: false - SplitEmptyRecord: true - SplitEmptyNamespace: true - -IncludeBlocks: Merge diff --git a/lib/TeensyTimerTool-master/examples/99_Misc/PinInformation/.gitignore b/lib/TeensyTimerTool-master/examples/99_Misc/PinInformation/.gitignore deleted file mode 100644 index bb38888..0000000 --- a/lib/TeensyTimerTool-master/examples/99_Misc/PinInformation/.gitignore +++ /dev/null @@ -1,18 +0,0 @@ -# build -.vsteensy/** -.vscode/** -makefile - -# dependency files -*.d - -# output and binaries -*.slo -*.lo -*.o -*.obj -*.hex -*.lst -*.elf -*.a - diff --git a/lib/TeensyTimerTool-master/examples/99_Misc/PinInformation/GPIO_Info.h b/lib/TeensyTimerTool-master/examples/99_Misc/PinInformation/GPIO_Info.h deleted file mode 100644 index 819930d..0000000 --- a/lib/TeensyTimerTool-master/examples/99_Misc/PinInformation/GPIO_Info.h +++ /dev/null @@ -1,39 +0,0 @@ -#pragma once - -#include "core_pins.h" -#include - -struct GPIO_Info_t -{ - inline GPIO_Info_t(unsigned pin); - const uintptr_t pinCfg; - const unsigned gpioPortNr; - const unsigned gpioBitNr; - - char name[20]; -}; - -//====================================================================================== -#if defined(KINETISK) || defined(KINETISL) - -GPIO_Info_t::GPIO_Info_t(unsigned pin) - : pinCfg((uintptr_t)digital_pin_to_info_PGM[pin].config), // address of pin config register - gpioPortNr((pinCfg - (uintptr_t)&PORTA_PCR0) / 0x1000), // cfg base addresses are 4kB aligned staring with PORTA_PCR0 - gpioBitNr((pinCfg & 0xFFF) / 4) // each bit has to 4 consecutive 32bit cfg registers -{ - snprintf(name, 20, "GPIO%d_%02d", gpioPortNr, gpioBitNr); -} - -//====================================================================================== -#elif defined(ARDUINO_TEENSY40) || defined(ARDUINO_TEENSY41) || defined(ARDUINO_TEENSY_MICROMOD) - - -GPIO_Info_t::GPIO_Info_t(unsigned pin) - : pinCfg((uintptr_t)digital_pin_to_info_PGM[pin].reg), // address of pin config register - gpioPortNr((pinCfg - (uintptr_t)&IMXRT_GPIO6) / 0x4000 + 6), // cfg base addresses are 4kB aligned staring with PORTA_PCR0 - gpioBitNr(__builtin_ffs(digital_pin_to_info_PGM[pin].mask) - 1) // each bit has to 4 consecutive 32bit cfg registers -{ - snprintf(name, 20, "GPIO%d_%02d", gpioPortNr, gpioBitNr); -} - -#endif \ No newline at end of file diff --git a/lib/TeensyTimerTool-master/examples/99_Misc/PinInformation/PWM_TimerInfo.c b/lib/TeensyTimerTool-master/examples/99_Misc/PinInformation/PWM_TimerInfo.c deleted file mode 100644 index 9a01feb..0000000 --- a/lib/TeensyTimerTool-master/examples/99_Misc/PinInformation/PWM_TimerInfo.c +++ /dev/null @@ -1,213 +0,0 @@ -#include "core_pins.h" - -/***** - * Unlike Teensy 4.x there is no information array in the core for the T3.x series - * We thus build the corresponding array from copies of the pin definitions in core_pins.h - *****/ - - -#if defined(ARDUINO_TEENSYLC) - -const int PwmTimerModule[CORE_NUM_DIGITAL] = { - [0 ... CORE_NUM_DIGITAL - 1] = -1, - [CORE_TPM0_CH0_PIN] = 0, - [CORE_TPM0_CH1_PIN] = 0, - [CORE_TPM0_CH2_PIN] = 0, - [CORE_TPM0_CH3_PIN] = 0, - [CORE_TPM0_CH4_PIN] = 0, - [CORE_TPM0_CH5_PIN] = 0, - [CORE_TPM1_CH0_PIN] = 1, - [CORE_TPM1_CH1_PIN] = 1, - [CORE_TPM2_CH0_PIN] = 2, - [CORE_TPM2_CH1_PIN] = 2, -}; - -const int PwmTimerType[CORE_NUM_DIGITAL] = { - [0 ... CORE_NUM_DIGITAL - 1] = 0, - [CORE_TPM0_CH0_PIN] = 2, - [CORE_TPM0_CH1_PIN] = 2, - [CORE_TPM0_CH2_PIN] = 2, - [CORE_TPM0_CH3_PIN] = 2, - [CORE_TPM0_CH4_PIN] = 2, - [CORE_TPM0_CH5_PIN] = 2, - [CORE_TPM1_CH0_PIN] = 2, - [CORE_TPM1_CH1_PIN] = 2, - [CORE_TPM2_CH0_PIN] = 2, - [CORE_TPM2_CH1_PIN] = 2, -}; - -//=========================================================================================== -#elif defined(ARDUINO_TEENSY30) - -const int PwmTimerModule[CORE_NUM_DIGITAL] = { - [0 ... CORE_NUM_DIGITAL - 1] = -1, - [CORE_FTM0_CH0_PIN] = 0, - [CORE_FTM0_CH1_PIN] = 0, - [CORE_FTM0_CH2_PIN] = 0, - [CORE_FTM0_CH3_PIN] = 0, - [CORE_FTM0_CH4_PIN] = 0, - [CORE_FTM0_CH5_PIN] = 0, - [CORE_FTM0_CH6_PIN] = 0, - [CORE_FTM0_CH7_PIN] = 0, - [CORE_FTM1_CH0_PIN] = 1, - [CORE_FTM1_CH1_PIN] = 1, -}; - -const int PwmTimerType[CORE_NUM_DIGITAL] = { - [0 ... CORE_NUM_DIGITAL - 1] = 0, - [CORE_FTM0_CH0_PIN] = 1, - [CORE_FTM0_CH1_PIN] = 1, - [CORE_FTM0_CH2_PIN] = 1, - [CORE_FTM0_CH3_PIN] = 1, - [CORE_FTM0_CH4_PIN] = 1, - [CORE_FTM0_CH5_PIN] = 1, - [CORE_FTM0_CH6_PIN] = 1, - [CORE_FTM0_CH7_PIN] = 1, - [CORE_FTM1_CH0_PIN] = 1, - [CORE_FTM1_CH1_PIN] = 1, -}; - -//=========================================================================================== -#elif defined(__MK20DX256__) -const int PwmTimerModule[CORE_NUM_DIGITAL] = { - [0 ... CORE_NUM_DIGITAL - 1] = -1, - [CORE_FTM0_CH0_PIN] = 0, - [CORE_FTM0_CH1_PIN] = 0, - [CORE_FTM0_CH0_PIN] = 0, - [CORE_FTM0_CH1_PIN] = 0, - [CORE_FTM0_CH2_PIN] = 0, - [CORE_FTM0_CH3_PIN] = 0, - [CORE_FTM0_CH4_PIN] = 0, - [CORE_FTM0_CH5_PIN] = 0, - [CORE_FTM0_CH6_PIN] = 0, - [CORE_FTM0_CH7_PIN] = 0, - [CORE_FTM1_CH0_PIN] = 1, - [CORE_FTM1_CH1_PIN] = 1, - [CORE_FTM2_CH0_PIN] = 2, - [CORE_FTM2_CH1_PIN] = 2, -}; - -//=========================================================================================== -const int PwmTimerType[CORE_NUM_DIGITAL] = { - [0 ... CORE_NUM_DIGITAL - 1] = 0, - [CORE_FTM0_CH0_PIN] = 1, - [CORE_FTM0_CH1_PIN] = 1, - [CORE_FTM0_CH0_PIN] = 1, - [CORE_FTM0_CH1_PIN] = 1, - [CORE_FTM0_CH2_PIN] = 1, - [CORE_FTM0_CH3_PIN] = 1, - [CORE_FTM0_CH4_PIN] = 1, - [CORE_FTM0_CH5_PIN] = 1, - [CORE_FTM0_CH6_PIN] = 1, - [CORE_FTM0_CH7_PIN] = 1, - [CORE_FTM1_CH0_PIN] = 1, - [CORE_FTM1_CH1_PIN] = 1, - [CORE_FTM2_CH0_PIN] = 1, - [CORE_FTM2_CH1_PIN] = 1, -}; - -//=========================================================================================== -#elif defined(ARDUINO_TEENSY35) -const int PwmTimerModule[CORE_NUM_DIGITAL] = { - [0 ... CORE_NUM_DIGITAL - 1] = -1, - [CORE_FTM0_CH0_PIN] = 0, - [CORE_FTM0_CH1_PIN] = 0, - [CORE_FTM0_CH2_PIN] = 0, - [CORE_FTM0_CH3_PIN] = 0, - [CORE_FTM0_CH4_PIN] = 0, - [CORE_FTM0_CH5_PIN] = 0, - [CORE_FTM0_CH6_PIN] = 0, - [CORE_FTM0_CH7_PIN] = 0, - [CORE_FTM1_CH0_PIN] = 1, - [CORE_FTM1_CH1_PIN] = 1, - [CORE_FTM2_CH0_PIN] = 2, - [CORE_FTM2_CH1_PIN] = 2, - [CORE_FTM3_CH0_PIN] = 3, - [CORE_FTM3_CH1_PIN] = 3, - [CORE_FTM3_CH2_PIN] = 3, - [CORE_FTM3_CH3_PIN] = 3, - [CORE_FTM3_CH4_PIN] = 3, - [CORE_FTM3_CH5_PIN] = 3, - [CORE_FTM3_CH6_PIN] = 3, - [CORE_FTM3_CH7_PIN] = 3, -}; - -const int PwmTimerType[CORE_NUM_DIGITAL] = { - [0 ... CORE_NUM_DIGITAL - 1] = 0, - [CORE_FTM0_CH0_PIN] = 1, - [CORE_FTM0_CH1_PIN] = 1, - [CORE_FTM0_CH2_PIN] = 1, - [CORE_FTM0_CH3_PIN] = 1, - [CORE_FTM0_CH4_PIN] = 1, - [CORE_FTM0_CH5_PIN] = 1, - [CORE_FTM0_CH6_PIN] = 1, - [CORE_FTM0_CH7_PIN] = 1, - [CORE_FTM1_CH0_PIN] = 1, - [CORE_FTM1_CH1_PIN] = 1, - [CORE_FTM2_CH0_PIN] = 1, - [CORE_FTM2_CH1_PIN] = 1, - [CORE_FTM3_CH0_PIN] = 1, - [CORE_FTM3_CH1_PIN] = 1, - [CORE_FTM3_CH2_PIN] = 1, - [CORE_FTM3_CH3_PIN] = 1, - [CORE_FTM3_CH4_PIN] = 1, - [CORE_FTM3_CH5_PIN] = 1, - [CORE_FTM3_CH6_PIN] = 1, - [CORE_FTM3_CH7_PIN] = 1, -}; - -//=========================================================================================== -#elif defined(ARDUINO_TEENSY36) -const int PwmTimerModule[CORE_NUM_DIGITAL] = { - [0 ... CORE_NUM_DIGITAL - 1] = -1, - [CORE_FTM0_CH0_PIN] = 0, - [CORE_FTM0_CH1_PIN] = 0, - [CORE_FTM0_CH2_PIN] = 0, - [CORE_FTM0_CH3_PIN] = 0, - [CORE_FTM0_CH4_PIN] = 0, - [CORE_FTM0_CH5_PIN] = 0, - [CORE_FTM0_CH6_PIN] = 0, - [CORE_FTM0_CH7_PIN] = 0, - [CORE_FTM1_CH0_PIN] = 1, - [CORE_FTM1_CH1_PIN] = 1, - [CORE_FTM2_CH0_PIN] = 2, - [CORE_FTM2_CH1_PIN] = 2, - [CORE_FTM3_CH0_PIN] = 3, - [CORE_FTM3_CH1_PIN] = 3, - [CORE_FTM3_CH2_PIN] = 3, - [CORE_FTM3_CH3_PIN] = 3, - [CORE_FTM3_CH4_PIN] = 3, - [CORE_FTM3_CH5_PIN] = 3, - [CORE_FTM3_CH6_PIN] = 3, - [CORE_FTM3_CH7_PIN] = 3, - [CORE_TPM1_CH0_PIN] = 1, - [CORE_TPM1_CH1_PIN] = 1, -}; - -const int PwmTimerType[CORE_NUM_DIGITAL] = { - [0 ... CORE_NUM_DIGITAL - 1] = 0, - [CORE_FTM0_CH0_PIN] = 1, - [CORE_FTM0_CH1_PIN] = 1, - [CORE_FTM0_CH2_PIN] = 1, - [CORE_FTM0_CH3_PIN] = 1, - [CORE_FTM0_CH4_PIN] = 1, - [CORE_FTM0_CH5_PIN] = 1, - [CORE_FTM0_CH6_PIN] = 1, - [CORE_FTM0_CH7_PIN] = 1, - [CORE_FTM1_CH0_PIN] = 1, - [CORE_FTM1_CH1_PIN] = 1, - [CORE_FTM2_CH0_PIN] = 1, - [CORE_FTM2_CH1_PIN] = 1, - [CORE_FTM3_CH0_PIN] = 1, - [CORE_FTM3_CH1_PIN] = 1, - [CORE_FTM3_CH2_PIN] = 1, - [CORE_FTM3_CH3_PIN] = 1, - [CORE_FTM3_CH4_PIN] = 1, - [CORE_FTM3_CH5_PIN] = 1, - [CORE_FTM3_CH6_PIN] = 1, - [CORE_FTM3_CH7_PIN] = 1, - [CORE_TPM1_CH0_PIN] = 2, - [CORE_TPM1_CH1_PIN] = 2, -}; - -#endif diff --git a/lib/TeensyTimerTool-master/examples/99_Misc/PinInformation/PWM_TimerInfo.h b/lib/TeensyTimerTool-master/examples/99_Misc/PinInformation/PWM_TimerInfo.h deleted file mode 100644 index 148d17e..0000000 --- a/lib/TeensyTimerTool-master/examples/99_Misc/PinInformation/PWM_TimerInfo.h +++ /dev/null @@ -1,62 +0,0 @@ -#pragma once - -#include "core_pins.h" -#include - -struct PWM_TimerInfo_t -{ - inline PWM_TimerInfo_t(unsigned _pin = 0); - unsigned type; - unsigned module; - char name[20]; -}; - -//=========================================================================================================== -#if defined(ARDUINO_TEENSY40) || defined(ARDUINO_TEENSY41) || defined(ARDUINO_TEENSY_MICROMOD) - -// holds core info about used pwm timers. Struct is defined in pwm.c. -// There is no header declaring it. So, we need to do this here: -struct pwm_pin_info_struct -{ - uint8_t type; // 0=no pwm, 1=flexpwm, 2=quad - uint8_t module; // 0-3, 0-3 - uint8_t channel; // 0=X, 1=A, 2=B - uint8_t muxval; // -}; -extern pwm_pin_info_struct pwm_pin_info[]; // This array holds the pwm timer info - -PWM_TimerInfo_t::PWM_TimerInfo_t(unsigned pin) -{ - constexpr char timerNames[][9] = {"FLEX_PWM", "QUAD"}; - - type = pwm_pin_info[pin].type; - module = (pwm_pin_info[pin].module >> 4) + 1; - - if (type != 0) - snprintf(name, 20, "%s%d", timerNames[type - 1], module); - else - snprintf(name, 20, "no pwm"); -} - -//=========================================================================================================== -#elif defined(ARDUINO_TEENSYLC) || \ - defined(ARDUINO_TEENSY30) || defined(ARDUINO_TEENSY32) || \ - defined(ARDUINO_TEENSY35) || defined(ARDUINO_TEENSY36) - -extern "C" const int PwmTimerModule[CORE_NUM_DIGITAL]; -extern "C" const int PwmTimerType[CORE_NUM_DIGITAL]; - -PWM_TimerInfo_t::PWM_TimerInfo_t(unsigned pin) -{ - constexpr char timerNames[][9] = {"FTM", "TPM"}; - - type = PwmTimerType[pin]; - module = PwmTimerModule[pin]; - - if (type != 0) - snprintf(name, 20, "%s%d", timerNames[type - 1], module); - else - snprintf(name, 20, "none"); -} - -#endif \ No newline at end of file diff --git a/lib/TeensyTimerTool-master/examples/99_Misc/PinInformation/PinInfo.h b/lib/TeensyTimerTool-master/examples/99_Misc/PinInformation/PinInfo.h deleted file mode 100644 index 0821167..0000000 --- a/lib/TeensyTimerTool-master/examples/99_Misc/PinInformation/PinInfo.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -#include "GPIO_Info.h" -#include "PWM_TimerInfo.h" - -struct PinInfo -{ - inline PinInfo(unsigned _pin) - : pin(_pin), - gpioInfo(pin), - pwmTimerInfo(pin) - {} - - const unsigned pin; - const GPIO_Info_t gpioInfo; - const PWM_TimerInfo_t pwmTimerInfo; -}; diff --git a/lib/TeensyTimerTool-master/examples/99_Misc/PinInformation/PinInformation.ino b/lib/TeensyTimerTool-master/examples/99_Misc/PinInformation/PinInformation.ino deleted file mode 100644 index 3e2eb76..0000000 --- a/lib/TeensyTimerTool-master/examples/99_Misc/PinInformation/PinInformation.ino +++ /dev/null @@ -1,57 +0,0 @@ -#include "Arduino.h" - -#include "PinInfo.h" -#include - -void printPins(PinInfo* pins[], unsigned nrOfPins); - -void setup() -{ - while (!Serial) {} - - // setup an array containing info for all digital pins - PinInfo* pins[CORE_NUM_DIGITAL]; - for (unsigned i = 0; i < CORE_NUM_DIGITAL; i++) - { - pins[i] = new PinInfo(i); - } - - // Print out info sorted by pin numbers - Serial.println("-------------------------------"); - Serial.println(" Sorted by pin number"); - printPins(pins, CORE_NUM_DIGITAL); - - Serial.println("\n-------------------------------"); - Serial.println(" Sorted by PWM timer"); - std::sort(pins, pins + CORE_NUM_DIGITAL, [](PinInfo* a, PinInfo* b) { - if (a->pwmTimerInfo.type < b->pwmTimerInfo.type) return false; - if (a->pwmTimerInfo.type > b->pwmTimerInfo.type) return true; - if (a->pwmTimerInfo.module < b->pwmTimerInfo.module) return true; - return false; - }); - printPins(pins, CORE_NUM_DIGITAL); - - Serial.println("\n-------------------------------"); - Serial.println(" Sorted by GPIO register: "); - std::sort(pins, pins + CORE_NUM_DIGITAL, [](PinInfo* a, PinInfo* b) { - if (a->gpioInfo.gpioPortNr < b->gpioInfo.gpioPortNr) return true; - if (a->gpioInfo.gpioPortNr > b->gpioInfo.gpioPortNr) return false; - if (a->gpioInfo.gpioBitNr < b->gpioInfo.gpioBitNr) return true; - return false; - }); - printPins(pins, CORE_NUM_DIGITAL); -} - -void loop() {} - -// Helpers ------------------------------------------------------- - -void printPins(PinInfo* pins[], unsigned nrOfPins) -{ - Serial.println("Pin | GPIO Reg | PWM timer"); - Serial.println("----|------------|-------------"); - for (unsigned i = 0; i < nrOfPins; i++) - { - Serial.printf("%02d | %-9s | %-10s\n", pins[i]->pin, pins[i]->gpioInfo.name, pins[i]->pwmTimerInfo.name); - } -} diff --git a/lib/TeensyTimerTool-master/examples/99_Misc/PinInformation/boards.txt b/lib/TeensyTimerTool-master/examples/99_Misc/PinInformation/boards.txt deleted file mode 100644 index 17b59a7..0000000 --- a/lib/TeensyTimerTool-master/examples/99_Misc/PinInformation/boards.txt +++ /dev/null @@ -1,1569 +0,0 @@ -menu.usb=USB Type -menu.speed=CPU Speed -menu.opt=Optimize -menu.keys=Keyboard Layout - - -teensy41.name=Teensy 4.1 -teensy41.upload.maximum_size=8126464 -teensy41.build.board=TEENSY41 -teensy41.build.flags.ld=-Wl,--gc-sections,--relax "-T{build.core.path}/imxrt1062_t41.ld" -teensy41.upload.maximum_data_size=524288 -#teensy41.upload.maximum_data_size=1048576 -teensy41.upload.tool=teensyloader -teensy41.upload.protocol=halfkay -teensy41.build.core=teensy4 -teensy41.build.mcu=imxrt1062 -teensy41.build.warn_data_percentage=99 -teensy41.build.toolchain=arm/bin/ -teensy41.build.command.gcc=arm-none-eabi-gcc -teensy41.build.command.g++=arm-none-eabi-g++ -teensy41.build.command.ar=arm-none-eabi-gcc-ar -teensy41.build.command.objcopy=arm-none-eabi-objcopy -teensy41.build.command.objdump=arm-none-eabi-objdump -teensy41.build.command.linker=arm-none-eabi-gcc -teensy41.build.command.size=arm-none-eabi-size -teensy41.build.flags.common=-g -Wall -ffunction-sections -fdata-sections -nostdlib -teensy41.build.flags.dep=-MMD -teensy41.build.flags.optimize=-Os -teensy41.build.flags.cpu=-mthumb -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -teensy41.build.flags.defs=-D__IMXRT1062__ -DTEENSYDUINO=153 -teensy41.build.flags.cpp=-std=gnu++14 -fno-exceptions -fpermissive -fno-rtti -fno-threadsafe-statics -felide-constructors -Wno-error=narrowing -teensy41.build.flags.c= -teensy41.build.flags.S=-x assembler-with-cpp -teensy41.build.flags.libs=-larm_cortexM7lfsp_math -lm -lstdc++ -teensy41.serial.restart_cmd=false -teensy41.menu.usb.serial=Serial -teensy41.menu.usb.serial.build.usbtype=USB_SERIAL -teensy41.menu.usb.serial2=Dual Serial -teensy41.menu.usb.serial2.build.usbtype=USB_DUAL_SERIAL -teensy41.menu.usb.serial3=Triple Serial -teensy41.menu.usb.serial3.build.usbtype=USB_TRIPLE_SERIAL -teensy41.menu.usb.keyboard=Keyboard -teensy41.menu.usb.keyboard.build.usbtype=USB_KEYBOARDONLY -teensy41.menu.usb.keyboard.fake_serial=teensy_gateway -teensy41.menu.usb.touch=Keyboard + Touch Screen -teensy41.menu.usb.touch.build.usbtype=USB_TOUCHSCREEN -teensy41.menu.usb.touch.fake_serial=teensy_gateway -teensy41.menu.usb.hidtouch=Keyboard + Mouse + Touch Screen -teensy41.menu.usb.hidtouch.build.usbtype=USB_HID_TOUCHSCREEN -teensy41.menu.usb.hidtouch.fake_serial=teensy_gateway -teensy41.menu.usb.hid=Keyboard + Mouse + Joystick -teensy41.menu.usb.hid.build.usbtype=USB_HID -teensy41.menu.usb.hid.fake_serial=teensy_gateway -teensy41.menu.usb.serialhid=Serial + Keyboard + Mouse + Joystick -teensy41.menu.usb.serialhid.build.usbtype=USB_SERIAL_HID -teensy41.menu.usb.midi=MIDI -teensy41.menu.usb.midi.build.usbtype=USB_MIDI -teensy41.menu.usb.midi.fake_serial=teensy_gateway -teensy41.menu.usb.midi4=MIDIx4 -teensy41.menu.usb.midi4.build.usbtype=USB_MIDI4 -teensy41.menu.usb.midi4.fake_serial=teensy_gateway -teensy41.menu.usb.midi16=MIDIx16 -teensy41.menu.usb.midi16.build.usbtype=USB_MIDI16 -teensy41.menu.usb.midi16.fake_serial=teensy_gateway -teensy41.menu.usb.serialmidi=Serial + MIDI -teensy41.menu.usb.serialmidi.build.usbtype=USB_MIDI_SERIAL -teensy41.menu.usb.serialmidi4=Serial + MIDIx4 -teensy41.menu.usb.serialmidi4.build.usbtype=USB_MIDI4_SERIAL -teensy41.menu.usb.serialmidi16=Serial + MIDIx16 -teensy41.menu.usb.serialmidi16.build.usbtype=USB_MIDI16_SERIAL -teensy41.menu.usb.audio=Audio -teensy41.menu.usb.audio.build.usbtype=USB_AUDIO -teensy41.menu.usb.audio.fake_serial=teensy_gateway -teensy41.menu.usb.serialmidiaudio=Serial + MIDI + Audio -teensy41.menu.usb.serialmidiaudio.build.usbtype=USB_MIDI_AUDIO_SERIAL -teensy41.menu.usb.serialmidi16audio=Serial + MIDIx16 + Audio -teensy41.menu.usb.serialmidi16audio.build.usbtype=USB_MIDI16_AUDIO_SERIAL -teensy41.menu.usb.mtp=MTP Disk (Experimental) -teensy41.menu.usb.mtp.build.usbtype=USB_MTPDISK -teensy41.menu.usb.mtp.fake_serial=teensy_gateway -teensy41.menu.usb.rawhid=Raw HID -teensy41.menu.usb.rawhid.build.usbtype=USB_RAWHID -teensy41.menu.usb.rawhid.fake_serial=teensy_gateway -teensy41.menu.usb.flightsim=Flight Sim Controls -teensy41.menu.usb.flightsim.build.usbtype=USB_FLIGHTSIM -teensy41.menu.usb.flightsim.fake_serial=teensy_gateway -teensy41.menu.usb.flightsimjoystick=Flight Sim Controls + Joystick -teensy41.menu.usb.flightsimjoystick.build.usbtype=USB_FLIGHTSIM_JOYSTICK -teensy41.menu.usb.flightsimjoystick.fake_serial=teensy_gateway -#teensy41.menu.usb.disable=No USB -#teensy41.menu.usb.disable.build.usbtype=USB_DISABLED - -teensy41.menu.speed.600=600 MHz -teensy41.menu.speed.528=528 MHz -teensy41.menu.speed.450=450 MHz -teensy41.menu.speed.396=396 MHz -teensy41.menu.speed.150=150 MHz -teensy41.menu.speed.24=24 MHz -teensy41.menu.speed.720=720 MHz (overclock) -teensy41.menu.speed.816=816 MHz (overclock) -teensy41.menu.speed.912=912 MHz (overclock, cooling req'd) -teensy41.menu.speed.960=960 MHz (overclock, cooling req'd) -teensy41.menu.speed.1008=1.008 GHz (overclock, cooling req'd) -teensy41.menu.speed.1008.build.fcpu=1008000000 -teensy41.menu.speed.960.build.fcpu=960000000 -teensy41.menu.speed.912.build.fcpu=912000000 -teensy41.menu.speed.816.build.fcpu=816000000 -teensy41.menu.speed.720.build.fcpu=720000000 -teensy41.menu.speed.600.build.fcpu=600000000 -teensy41.menu.speed.528.build.fcpu=528000000 -teensy41.menu.speed.450.build.fcpu=450000000 -teensy41.menu.speed.396.build.fcpu=396000000 -teensy41.menu.speed.150.build.fcpu=150000000 -teensy41.menu.speed.24.build.fcpu=24000000 - -teensy41.menu.opt.o2std=Faster -teensy41.menu.opt.o2std.build.flags.optimize=-O2 -teensy41.menu.opt.o2std.build.flags.ldspecs= -#teensy41.menu.opt.o2lto=Faster with LTO -#teensy41.menu.opt.o2lto.build.flags.optimize=-O2 -flto -fno-fat-lto-objects -#teensy41.menu.opt.o2lto.build.flags.ldspecs=-fuse-linker-plugin -teensy41.menu.opt.o1std=Fast -teensy41.menu.opt.o1std.build.flags.optimize=-O1 -teensy41.menu.opt.o1std.build.flags.ldspecs= -#teensy41.menu.opt.o1lto=Fast with LTO -#teensy41.menu.opt.o1lto.build.flags.optimize=-O1 -flto -fno-fat-lto-objects -#teensy41.menu.opt.o1lto.build.flags.ldspecs=-fuse-linker-plugin -teensy41.menu.opt.o3std=Fastest -teensy41.menu.opt.o3std.build.flags.optimize=-O3 -teensy41.menu.opt.o3std.build.flags.ldspecs= -#teensy41.menu.opt.o3purestd=Fastest + pure-code -#teensy41.menu.opt.o3purestd.build.flags.optimize=-O3 -mpure-code -D__PURE_CODE__ -#teensy41.menu.opt.o3purestd.build.flags.ldspecs= -#teensy41.menu.opt.o3lto=Fastest with LTO -#teensy41.menu.opt.o3lto.build.flags.optimize=-O3 -flto -fno-fat-lto-objects -#teensy41.menu.opt.o3lto.build.flags.ldspecs=-fuse-linker-plugin -#teensy41.menu.opt.o3purelto=Fastest + pure-code with LTO -#teensy41.menu.opt.o3purelto.build.flags.optimize=-O3 -mpure-code -D__PURE_CODE__ -flto -fno-fat-lto-objects -#teensy41.menu.opt.o3purelto.build.flags.ldspecs=-fuse-linker-plugin -teensy41.menu.opt.ogstd=Debug -teensy41.menu.opt.ogstd.build.flags.optimize=-Og -teensy41.menu.opt.ogstd.build.flags.ldspecs= -#teensy41.menu.opt.oglto=Debug with LTO -#teensy41.menu.opt.oglto.build.flags.optimize=-Og -flto -fno-fat-lto-objects -#teensy41.menu.opt.oglto.build.flags.ldspecs=-fuse-linker-plugin -teensy41.menu.opt.osstd=Smallest Code -teensy41.menu.opt.osstd.build.flags.optimize=-Os --specs=nano.specs -teensy41.menu.opt.osstd.build.flags.ldspecs= -#teensy41.menu.opt.oslto=Smallest Code with LTO -#teensy41.menu.opt.oslto.build.flags.optimize=-Os -flto -fno-fat-lto-objects --specs=nano.specs -#teensy41.menu.opt.oslto.build.flags.ldspecs=-fuse-linker-plugin - -teensy41.menu.keys.en-us=US English -teensy41.menu.keys.en-us.build.keylayout=US_ENGLISH -teensy41.menu.keys.fr-ca=Canadian French -teensy41.menu.keys.fr-ca.build.keylayout=CANADIAN_FRENCH -teensy41.menu.keys.xx-ca=Canadian Multilingual -teensy41.menu.keys.xx-ca.build.keylayout=CANADIAN_MULTILINGUAL -teensy41.menu.keys.cz-cz=Czech -teensy41.menu.keys.cz-cz.build.keylayout=CZECH -teensy41.menu.keys.da-da=Danish -teensy41.menu.keys.da-da.build.keylayout=DANISH -teensy41.menu.keys.fi-fi=Finnish -teensy41.menu.keys.fi-fi.build.keylayout=FINNISH -teensy41.menu.keys.fr-fr=French -teensy41.menu.keys.fr-fr.build.keylayout=FRENCH -teensy41.menu.keys.fr-be=French Belgian -teensy41.menu.keys.fr-be.build.keylayout=FRENCH_BELGIAN -teensy41.menu.keys.fr-ch=French Swiss -teensy41.menu.keys.fr-ch.build.keylayout=FRENCH_SWISS -teensy41.menu.keys.de-de=German -teensy41.menu.keys.de-de.build.keylayout=GERMAN -teensy41.menu.keys.de-dm=German (Mac) -teensy41.menu.keys.de-dm.build.keylayout=GERMAN_MAC -teensy41.menu.keys.de-ch=German Swiss -teensy41.menu.keys.de-ch.build.keylayout=GERMAN_SWISS -teensy41.menu.keys.is-is=Icelandic -teensy41.menu.keys.is-is.build.keylayout=ICELANDIC -teensy41.menu.keys.en-ie=Irish -teensy41.menu.keys.en-ie.build.keylayout=IRISH -teensy41.menu.keys.it-it=Italian -teensy41.menu.keys.it-it.build.keylayout=ITALIAN -teensy41.menu.keys.no-no=Norwegian -teensy41.menu.keys.no-no.build.keylayout=NORWEGIAN -teensy41.menu.keys.pt-pt=Portuguese -teensy41.menu.keys.pt-pt.build.keylayout=PORTUGUESE -teensy41.menu.keys.pt-br=Portuguese Brazilian -teensy41.menu.keys.pt-br.build.keylayout=PORTUGUESE_BRAZILIAN -teensy41.menu.keys.rs-rs=Serbian (Latin Only) -teensy41.menu.keys.rs-rs.build.keylayout=SERBIAN_LATIN_ONLY -teensy41.menu.keys.es-es=Spanish -teensy41.menu.keys.es-es.build.keylayout=SPANISH -teensy41.menu.keys.es-mx=Spanish Latin America -teensy41.menu.keys.es-mx.build.keylayout=SPANISH_LATIN_AMERICA -teensy41.menu.keys.sv-se=Swedish -teensy41.menu.keys.sv-se.build.keylayout=SWEDISH -teensy41.menu.keys.tr-tr=Turkish (partial) -teensy41.menu.keys.tr-tr.build.keylayout=TURKISH -teensy41.menu.keys.en-gb=United Kingdom -teensy41.menu.keys.en-gb.build.keylayout=UNITED_KINGDOM -teensy41.menu.keys.usint=US International -teensy41.menu.keys.usint.build.keylayout=US_INTERNATIONAL - - - -teensy40.name=Teensy 4.0 -teensy40.upload.maximum_size=2031616 -teensy40.build.board=TEENSY40 -teensy40.build.flags.ld=-Wl,--gc-sections,--relax "-T{build.core.path}/imxrt1062.ld" -teensy40.upload.maximum_data_size=524288 -#teensy40.upload.maximum_data_size=1048576 -teensy40.upload.tool=teensyloader -teensy40.upload.protocol=halfkay -teensy40.build.core=teensy4 -teensy40.build.mcu=imxrt1062 -teensy40.build.warn_data_percentage=99 -teensy40.build.toolchain=arm/bin/ -teensy40.build.command.gcc=arm-none-eabi-gcc -teensy40.build.command.g++=arm-none-eabi-g++ -teensy40.build.command.ar=arm-none-eabi-gcc-ar -teensy40.build.command.objcopy=arm-none-eabi-objcopy -teensy40.build.command.objdump=arm-none-eabi-objdump -teensy40.build.command.linker=arm-none-eabi-gcc -teensy40.build.command.size=arm-none-eabi-size -teensy40.build.flags.common=-g -Wall -ffunction-sections -fdata-sections -nostdlib -teensy40.build.flags.dep=-MMD -teensy40.build.flags.optimize=-Os -teensy40.build.flags.cpu=-mthumb -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -teensy40.build.flags.defs=-D__IMXRT1062__ -DTEENSYDUINO=153 -teensy40.build.flags.cpp=-std=gnu++14 -fno-exceptions -fpermissive -fno-rtti -fno-threadsafe-statics -felide-constructors -Wno-error=narrowing -teensy40.build.flags.c= -teensy40.build.flags.S=-x assembler-with-cpp -teensy40.build.flags.libs=-larm_cortexM7lfsp_math -lm -lstdc++ -teensy40.serial.restart_cmd=false -teensy40.menu.usb.serial=Serial -teensy40.menu.usb.serial.build.usbtype=USB_SERIAL -teensy40.menu.usb.serial2=Dual Serial -teensy40.menu.usb.serial2.build.usbtype=USB_DUAL_SERIAL -teensy40.menu.usb.serial3=Triple Serial -teensy40.menu.usb.serial3.build.usbtype=USB_TRIPLE_SERIAL -teensy40.menu.usb.keyboard=Keyboard -teensy40.menu.usb.keyboard.build.usbtype=USB_KEYBOARDONLY -teensy40.menu.usb.keyboard.fake_serial=teensy_gateway -teensy40.menu.usb.touch=Keyboard + Touch Screen -teensy40.menu.usb.touch.build.usbtype=USB_TOUCHSCREEN -teensy40.menu.usb.touch.fake_serial=teensy_gateway -teensy40.menu.usb.hidtouch=Keyboard + Mouse + Touch Screen -teensy40.menu.usb.hidtouch.build.usbtype=USB_HID_TOUCHSCREEN -teensy40.menu.usb.hidtouch.fake_serial=teensy_gateway -teensy40.menu.usb.hid=Keyboard + Mouse + Joystick -teensy40.menu.usb.hid.build.usbtype=USB_HID -teensy40.menu.usb.hid.fake_serial=teensy_gateway -teensy40.menu.usb.serialhid=Serial + Keyboard + Mouse + Joystick -teensy40.menu.usb.serialhid.build.usbtype=USB_SERIAL_HID -teensy40.menu.usb.midi=MIDI -teensy40.menu.usb.midi.build.usbtype=USB_MIDI -teensy40.menu.usb.midi.fake_serial=teensy_gateway -teensy40.menu.usb.midi4=MIDIx4 -teensy40.menu.usb.midi4.build.usbtype=USB_MIDI4 -teensy40.menu.usb.midi4.fake_serial=teensy_gateway -teensy40.menu.usb.midi16=MIDIx16 -teensy40.menu.usb.midi16.build.usbtype=USB_MIDI16 -teensy40.menu.usb.midi16.fake_serial=teensy_gateway -teensy40.menu.usb.serialmidi=Serial + MIDI -teensy40.menu.usb.serialmidi.build.usbtype=USB_MIDI_SERIAL -teensy40.menu.usb.serialmidi4=Serial + MIDIx4 -teensy40.menu.usb.serialmidi4.build.usbtype=USB_MIDI4_SERIAL -teensy40.menu.usb.serialmidi16=Serial + MIDIx16 -teensy40.menu.usb.serialmidi16.build.usbtype=USB_MIDI16_SERIAL -teensy40.menu.usb.audio=Audio -teensy40.menu.usb.audio.build.usbtype=USB_AUDIO -teensy40.menu.usb.audio.fake_serial=teensy_gateway -teensy40.menu.usb.serialmidiaudio=Serial + MIDI + Audio -teensy40.menu.usb.serialmidiaudio.build.usbtype=USB_MIDI_AUDIO_SERIAL -teensy40.menu.usb.serialmidi16audio=Serial + MIDIx16 + Audio -teensy40.menu.usb.serialmidi16audio.build.usbtype=USB_MIDI16_AUDIO_SERIAL -teensy40.menu.usb.mtp=MTP Disk (Experimental) -teensy40.menu.usb.mtp.build.usbtype=USB_MTPDISK -teensy40.menu.usb.mtp.fake_serial=teensy_gateway -teensy40.menu.usb.rawhid=Raw HID -teensy40.menu.usb.rawhid.build.usbtype=USB_RAWHID -teensy40.menu.usb.rawhid.fake_serial=teensy_gateway -teensy40.menu.usb.flightsim=Flight Sim Controls -teensy40.menu.usb.flightsim.build.usbtype=USB_FLIGHTSIM -teensy40.menu.usb.flightsim.fake_serial=teensy_gateway -teensy40.menu.usb.flightsimjoystick=Flight Sim Controls + Joystick -teensy40.menu.usb.flightsimjoystick.build.usbtype=USB_FLIGHTSIM_JOYSTICK -teensy40.menu.usb.flightsimjoystick.fake_serial=teensy_gateway -#teensy40.menu.usb.disable=No USB -#teensy40.menu.usb.disable.build.usbtype=USB_DISABLED - -teensy40.menu.speed.600=600 MHz -teensy40.menu.speed.528=528 MHz -teensy40.menu.speed.450=450 MHz -teensy40.menu.speed.396=396 MHz -teensy40.menu.speed.150=150 MHz -teensy40.menu.speed.24=24 MHz -teensy40.menu.speed.720=720 MHz (overclock) -teensy40.menu.speed.816=816 MHz (overclock) -teensy40.menu.speed.912=912 MHz (overclock, cooling req'd) -teensy40.menu.speed.960=960 MHz (overclock, cooling req'd) -teensy40.menu.speed.1008=1.008 GHz (overclock, cooling req'd) -teensy40.menu.speed.1008.build.fcpu=1008000000 -teensy40.menu.speed.960.build.fcpu=960000000 -teensy40.menu.speed.912.build.fcpu=912000000 -teensy40.menu.speed.816.build.fcpu=816000000 -teensy40.menu.speed.720.build.fcpu=720000000 -teensy40.menu.speed.600.build.fcpu=600000000 -teensy40.menu.speed.528.build.fcpu=528000000 -teensy40.menu.speed.450.build.fcpu=450000000 -teensy40.menu.speed.396.build.fcpu=396000000 -teensy40.menu.speed.150.build.fcpu=150000000 -teensy40.menu.speed.24.build.fcpu=24000000 - -teensy40.menu.opt.o2std=Faster -teensy40.menu.opt.o2std.build.flags.optimize=-O2 -teensy40.menu.opt.o2std.build.flags.ldspecs= -#teensy40.menu.opt.o2lto=Faster with LTO -#teensy40.menu.opt.o2lto.build.flags.optimize=-O2 -flto -fno-fat-lto-objects -#teensy40.menu.opt.o2lto.build.flags.ldspecs=-fuse-linker-plugin -teensy40.menu.opt.o1std=Fast -teensy40.menu.opt.o1std.build.flags.optimize=-O1 -teensy40.menu.opt.o1std.build.flags.ldspecs= -#teensy40.menu.opt.o1lto=Fast with LTO -#teensy40.menu.opt.o1lto.build.flags.optimize=-O1 -flto -fno-fat-lto-objects -#teensy40.menu.opt.o1lto.build.flags.ldspecs=-fuse-linker-plugin -teensy40.menu.opt.o3std=Fastest -teensy40.menu.opt.o3std.build.flags.optimize=-O3 -teensy40.menu.opt.o3std.build.flags.ldspecs= -#teensy40.menu.opt.o3purestd=Fastest + pure-code -#teensy40.menu.opt.o3purestd.build.flags.optimize=-O3 -mpure-code -D__PURE_CODE__ -#teensy40.menu.opt.o3purestd.build.flags.ldspecs= -#teensy40.menu.opt.o3lto=Fastest with LTO -#teensy40.menu.opt.o3lto.build.flags.optimize=-O3 -flto -fno-fat-lto-objects -#teensy40.menu.opt.o3lto.build.flags.ldspecs=-fuse-linker-plugin -#teensy40.menu.opt.o3purelto=Fastest + pure-code with LTO -#teensy40.menu.opt.o3purelto.build.flags.optimize=-O3 -mpure-code -D__PURE_CODE__ -flto -fno-fat-lto-objects -#teensy40.menu.opt.o3purelto.build.flags.ldspecs=-fuse-linker-plugin -teensy40.menu.opt.ogstd=Debug -teensy40.menu.opt.ogstd.build.flags.optimize=-Og -teensy40.menu.opt.ogstd.build.flags.ldspecs= -#teensy40.menu.opt.oglto=Debug with LTO -#teensy40.menu.opt.oglto.build.flags.optimize=-Og -flto -fno-fat-lto-objects -#teensy40.menu.opt.oglto.build.flags.ldspecs=-fuse-linker-plugin -teensy40.menu.opt.osstd=Smallest Code -teensy40.menu.opt.osstd.build.flags.optimize=-Os --specs=nano.specs -teensy40.menu.opt.osstd.build.flags.ldspecs= -#teensy40.menu.opt.oslto=Smallest Code with LTO -#teensy40.menu.opt.oslto.build.flags.optimize=-Os -flto -fno-fat-lto-objects --specs=nano.specs -#teensy40.menu.opt.oslto.build.flags.ldspecs=-fuse-linker-plugin - -teensy40.menu.keys.en-us=US English -teensy40.menu.keys.en-us.build.keylayout=US_ENGLISH -teensy40.menu.keys.fr-ca=Canadian French -teensy40.menu.keys.fr-ca.build.keylayout=CANADIAN_FRENCH -teensy40.menu.keys.xx-ca=Canadian Multilingual -teensy40.menu.keys.xx-ca.build.keylayout=CANADIAN_MULTILINGUAL -teensy40.menu.keys.cz-cz=Czech -teensy40.menu.keys.cz-cz.build.keylayout=CZECH -teensy40.menu.keys.da-da=Danish -teensy40.menu.keys.da-da.build.keylayout=DANISH -teensy40.menu.keys.fi-fi=Finnish -teensy40.menu.keys.fi-fi.build.keylayout=FINNISH -teensy40.menu.keys.fr-fr=French -teensy40.menu.keys.fr-fr.build.keylayout=FRENCH -teensy40.menu.keys.fr-be=French Belgian -teensy40.menu.keys.fr-be.build.keylayout=FRENCH_BELGIAN -teensy40.menu.keys.fr-ch=French Swiss -teensy40.menu.keys.fr-ch.build.keylayout=FRENCH_SWISS -teensy40.menu.keys.de-de=German -teensy40.menu.keys.de-de.build.keylayout=GERMAN -teensy40.menu.keys.de-dm=German (Mac) -teensy40.menu.keys.de-dm.build.keylayout=GERMAN_MAC -teensy40.menu.keys.de-ch=German Swiss -teensy40.menu.keys.de-ch.build.keylayout=GERMAN_SWISS -teensy40.menu.keys.is-is=Icelandic -teensy40.menu.keys.is-is.build.keylayout=ICELANDIC -teensy40.menu.keys.en-ie=Irish -teensy40.menu.keys.en-ie.build.keylayout=IRISH -teensy40.menu.keys.it-it=Italian -teensy40.menu.keys.it-it.build.keylayout=ITALIAN -teensy40.menu.keys.no-no=Norwegian -teensy40.menu.keys.no-no.build.keylayout=NORWEGIAN -teensy40.menu.keys.pt-pt=Portuguese -teensy40.menu.keys.pt-pt.build.keylayout=PORTUGUESE -teensy40.menu.keys.pt-br=Portuguese Brazilian -teensy40.menu.keys.pt-br.build.keylayout=PORTUGUESE_BRAZILIAN -teensy40.menu.keys.rs-rs=Serbian (Latin Only) -teensy40.menu.keys.rs-rs.build.keylayout=SERBIAN_LATIN_ONLY -teensy40.menu.keys.es-es=Spanish -teensy40.menu.keys.es-es.build.keylayout=SPANISH -teensy40.menu.keys.es-mx=Spanish Latin America -teensy40.menu.keys.es-mx.build.keylayout=SPANISH_LATIN_AMERICA -teensy40.menu.keys.sv-se=Swedish -teensy40.menu.keys.sv-se.build.keylayout=SWEDISH -teensy40.menu.keys.tr-tr=Turkish (partial) -teensy40.menu.keys.tr-tr.build.keylayout=TURKISH -teensy40.menu.keys.en-gb=United Kingdom -teensy40.menu.keys.en-gb.build.keylayout=UNITED_KINGDOM -teensy40.menu.keys.usint=US International -teensy40.menu.keys.usint.build.keylayout=US_INTERNATIONAL - - -teensy36.name=Teensy 3.6 -teensy36.upload.maximum_size=1048576 -teensy36.upload.maximum_data_size=262144 -teensy36.upload.tool=teensyloader -teensy36.upload.protocol=halfkay -teensy36.build.board=TEENSY36 -teensy36.build.core=teensy3 -teensy36.build.mcu=mk66fx1m0 -teensy36.build.warn_data_percentage=99 -teensy36.build.toolchain=arm/bin/ -teensy36.build.command.gcc=arm-none-eabi-gcc -teensy36.build.command.g++=arm-none-eabi-g++ -teensy36.build.command.ar=arm-none-eabi-gcc-ar -teensy36.build.command.objcopy=arm-none-eabi-objcopy -teensy36.build.command.objdump=arm-none-eabi-objdump -teensy36.build.command.linker=arm-none-eabi-gcc -teensy36.build.command.size=arm-none-eabi-size -teensy36.build.flags.common=-g -Wall -ffunction-sections -fdata-sections -nostdlib -teensy36.build.flags.dep=-MMD -teensy36.build.flags.optimize=-Os -teensy36.build.flags.cpu=-mthumb -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -fsingle-precision-constant -teensy36.build.flags.defs=-D__MK66FX1M0__ -DTEENSYDUINO=153 -teensy36.build.flags.cpp=-fno-exceptions -fpermissive -felide-constructors -std=gnu++14 -Wno-error=narrowing -fno-rtti -teensy36.build.flags.c= -teensy36.build.flags.S=-x assembler-with-cpp -teensy36.build.flags.ld=-Wl,--gc-sections,--relax,--defsym=__rtc_localtime={extra.time.local} "-T{build.core.path}/mk66fx1m0.ld" -teensy36.build.flags.libs=-larm_cortexM4lf_math -lm -lstdc++ -teensy36.serial.restart_cmd=false -teensy36.menu.usb.serial=Serial -teensy36.menu.usb.serial.build.usbtype=USB_SERIAL -teensy36.menu.usb.serial2=Dual Serial -teensy36.menu.usb.serial2.build.usbtype=USB_DUAL_SERIAL -teensy36.menu.usb.serial3=Triple Serial -teensy36.menu.usb.serial3.build.usbtype=USB_TRIPLE_SERIAL -teensy36.menu.usb.keyboard=Keyboard -teensy36.menu.usb.keyboard.build.usbtype=USB_KEYBOARDONLY -teensy36.menu.usb.keyboard.fake_serial=teensy_gateway -teensy36.menu.usb.touch=Keyboard + Touch Screen -teensy36.menu.usb.touch.build.usbtype=USB_TOUCHSCREEN -teensy36.menu.usb.touch.fake_serial=teensy_gateway -teensy36.menu.usb.hidtouch=Keyboard + Mouse + Touch Screen -teensy36.menu.usb.hidtouch.build.usbtype=USB_HID_TOUCHSCREEN -teensy36.menu.usb.hidtouch.fake_serial=teensy_gateway -teensy36.menu.usb.hid=Keyboard + Mouse + Joystick -teensy36.menu.usb.hid.build.usbtype=USB_HID -teensy36.menu.usb.hid.fake_serial=teensy_gateway -teensy36.menu.usb.serialhid=Serial + Keyboard + Mouse + Joystick -teensy36.menu.usb.serialhid.build.usbtype=USB_SERIAL_HID -teensy36.menu.usb.midi=MIDI -teensy36.menu.usb.midi.build.usbtype=USB_MIDI -teensy36.menu.usb.midi.fake_serial=teensy_gateway -teensy36.menu.usb.midi4=MIDIx4 -teensy36.menu.usb.midi4.build.usbtype=USB_MIDI4 -teensy36.menu.usb.midi4.fake_serial=teensy_gateway -teensy36.menu.usb.midi16=MIDIx16 -teensy36.menu.usb.midi16.build.usbtype=USB_MIDI16 -teensy36.menu.usb.midi16.fake_serial=teensy_gateway -teensy36.menu.usb.serialmidi=Serial + MIDI -teensy36.menu.usb.serialmidi.build.usbtype=USB_MIDI_SERIAL -teensy36.menu.usb.serialmidi4=Serial + MIDIx4 -teensy36.menu.usb.serialmidi4.build.usbtype=USB_MIDI4_SERIAL -teensy36.menu.usb.serialmidi16=Serial + MIDIx16 -teensy36.menu.usb.serialmidi16.build.usbtype=USB_MIDI16_SERIAL -teensy36.menu.usb.audio=Audio -teensy36.menu.usb.audio.build.usbtype=USB_AUDIO -teensy36.menu.usb.audio.fake_serial=teensy_gateway -teensy36.menu.usb.serialmidiaudio=Serial + MIDI + Audio -teensy36.menu.usb.serialmidiaudio.build.usbtype=USB_MIDI_AUDIO_SERIAL -teensy36.menu.usb.serialmidi16audio=Serial + MIDIx16 + Audio -teensy36.menu.usb.serialmidi16audio.build.usbtype=USB_MIDI16_AUDIO_SERIAL -teensy36.menu.usb.mtp=MTP Disk (Experimental) -teensy36.menu.usb.mtp.build.usbtype=USB_MTPDISK -teensy36.menu.usb.mtp.fake_serial=teensy_gateway -teensy36.menu.usb.rawhid=Raw HID -teensy36.menu.usb.rawhid.build.usbtype=USB_RAWHID -teensy36.menu.usb.rawhid.fake_serial=teensy_gateway -teensy36.menu.usb.flightsim=Flight Sim Controls -teensy36.menu.usb.flightsim.build.usbtype=USB_FLIGHTSIM -teensy36.menu.usb.flightsim.fake_serial=teensy_gateway -teensy36.menu.usb.flightsimjoystick=Flight Sim Controls + Joystick -teensy36.menu.usb.flightsimjoystick.build.usbtype=USB_FLIGHTSIM_JOYSTICK -teensy36.menu.usb.flightsimjoystick.fake_serial=teensy_gateway -teensy36.menu.usb.everything=All of the Above -teensy36.menu.usb.everything.build.usbtype=USB_EVERYTHING -teensy36.menu.usb.disable=No USB -teensy36.menu.usb.disable.build.usbtype=USB_DISABLED - -teensy36.menu.speed.180=180 MHz -teensy36.menu.speed.168=168 MHz -teensy36.menu.speed.144=144 MHz -teensy36.menu.speed.120=120 MHz -teensy36.menu.speed.96=96 MHz -teensy36.menu.speed.72=72 MHz -teensy36.menu.speed.48=48 MHz -teensy36.menu.speed.24=24 MHz -teensy36.menu.speed.16=16 MHz (No USB) -teensy36.menu.speed.8=8 MHz (No USB) -teensy36.menu.speed.4=4 MHz (No USB) -teensy36.menu.speed.2=2 MHz (No USB) -teensy36.menu.speed.192=192 MHz (overclock) -teensy36.menu.speed.216=216 MHz (overclock) -teensy36.menu.speed.240=240 MHz (overclock) -teensy36.menu.speed.256=256 MHz (overclock) -teensy36.menu.speed.256.build.fcpu=256000000 -teensy36.menu.speed.240.build.fcpu=240000000 -teensy36.menu.speed.216.build.fcpu=216000000 -teensy36.menu.speed.192.build.fcpu=192000000 -teensy36.menu.speed.180.build.fcpu=180000000 -teensy36.menu.speed.168.build.fcpu=168000000 -teensy36.menu.speed.144.build.fcpu=144000000 -teensy36.menu.speed.120.build.fcpu=120000000 -teensy36.menu.speed.96.build.fcpu=96000000 -teensy36.menu.speed.72.build.fcpu=72000000 -teensy36.menu.speed.48.build.fcpu=48000000 -teensy36.menu.speed.24.build.fcpu=24000000 -teensy36.menu.speed.16.build.fcpu=16000000 -teensy36.menu.speed.8.build.fcpu=8000000 -teensy36.menu.speed.4.build.fcpu=4000000 -teensy36.menu.speed.2.build.fcpu=2000000 - -teensy36.menu.opt.o2std=Faster -teensy36.menu.opt.o2std.build.flags.optimize=-O2 -teensy36.menu.opt.o2std.build.flags.ldspecs= -teensy36.menu.opt.o2lto=Faster with LTO -teensy36.menu.opt.o2lto.build.flags.optimize=-O2 -flto -fno-fat-lto-objects -teensy36.menu.opt.o2lto.build.flags.ldspecs=-fuse-linker-plugin -teensy36.menu.opt.o1std=Fast -teensy36.menu.opt.o1std.build.flags.optimize=-O1 -teensy36.menu.opt.o1std.build.flags.ldspecs= -teensy36.menu.opt.o1lto=Fast with LTO -teensy36.menu.opt.o1lto.build.flags.optimize=-O1 -flto -fno-fat-lto-objects -teensy36.menu.opt.o1lto.build.flags.ldspecs=-fuse-linker-plugin -teensy36.menu.opt.o3std=Fastest -teensy36.menu.opt.o3std.build.flags.optimize=-O3 -teensy36.menu.opt.o3std.build.flags.ldspecs= -teensy36.menu.opt.o3purestd=Fastest + pure-code -teensy36.menu.opt.o3purestd.build.flags.optimize=-O3 -mpure-code -D__PURE_CODE__ -teensy36.menu.opt.o3purestd.build.flags.ldspecs= -teensy36.menu.opt.o3lto=Fastest with LTO -teensy36.menu.opt.o3lto.build.flags.optimize=-O3 -flto -fno-fat-lto-objects -teensy36.menu.opt.o3lto.build.flags.ldspecs=-fuse-linker-plugin -teensy36.menu.opt.o3purelto=Fastest + pure-code with LTO -teensy36.menu.opt.o3purelto.build.flags.optimize=-O3 -mpure-code -D__PURE_CODE__ -flto -fno-fat-lto-objects -teensy36.menu.opt.o3purelto.build.flags.ldspecs=-fuse-linker-plugin -teensy36.menu.opt.ogstd=Debug -teensy36.menu.opt.ogstd.build.flags.optimize=-Og -teensy36.menu.opt.ogstd.build.flags.ldspecs= -teensy36.menu.opt.oglto=Debug with LTO -teensy36.menu.opt.oglto.build.flags.optimize=-Og -flto -fno-fat-lto-objects -teensy36.menu.opt.oglto.build.flags.ldspecs=-fuse-linker-plugin -teensy36.menu.opt.osstd=Smallest Code -teensy36.menu.opt.osstd.build.flags.optimize=-Os --specs=nano.specs -teensy36.menu.opt.osstd.build.flags.ldspecs= -teensy36.menu.opt.oslto=Smallest Code with LTO -teensy36.menu.opt.oslto.build.flags.optimize=-Os -flto -fno-fat-lto-objects --specs=nano.specs -teensy36.menu.opt.oslto.build.flags.ldspecs=-fuse-linker-plugin - -teensy36.menu.keys.en-us=US English -teensy36.menu.keys.en-us.build.keylayout=US_ENGLISH -teensy36.menu.keys.fr-ca=Canadian French -teensy36.menu.keys.fr-ca.build.keylayout=CANADIAN_FRENCH -teensy36.menu.keys.xx-ca=Canadian Multilingual -teensy36.menu.keys.xx-ca.build.keylayout=CANADIAN_MULTILINGUAL -teensy36.menu.keys.cz-cz=Czech -teensy36.menu.keys.cz-cz.build.keylayout=CZECH -teensy36.menu.keys.da-da=Danish -teensy36.menu.keys.da-da.build.keylayout=DANISH -teensy36.menu.keys.fi-fi=Finnish -teensy36.menu.keys.fi-fi.build.keylayout=FINNISH -teensy36.menu.keys.fr-fr=French -teensy36.menu.keys.fr-fr.build.keylayout=FRENCH -teensy36.menu.keys.fr-be=French Belgian -teensy36.menu.keys.fr-be.build.keylayout=FRENCH_BELGIAN -teensy36.menu.keys.fr-ch=French Swiss -teensy36.menu.keys.fr-ch.build.keylayout=FRENCH_SWISS -teensy36.menu.keys.de-de=German -teensy36.menu.keys.de-de.build.keylayout=GERMAN -teensy36.menu.keys.de-dm=German (Mac) -teensy36.menu.keys.de-dm.build.keylayout=GERMAN_MAC -teensy36.menu.keys.de-ch=German Swiss -teensy36.menu.keys.de-ch.build.keylayout=GERMAN_SWISS -teensy36.menu.keys.is-is=Icelandic -teensy36.menu.keys.is-is.build.keylayout=ICELANDIC -teensy36.menu.keys.en-ie=Irish -teensy36.menu.keys.en-ie.build.keylayout=IRISH -teensy36.menu.keys.it-it=Italian -teensy36.menu.keys.it-it.build.keylayout=ITALIAN -teensy36.menu.keys.no-no=Norwegian -teensy36.menu.keys.no-no.build.keylayout=NORWEGIAN -teensy36.menu.keys.pt-pt=Portuguese -teensy36.menu.keys.pt-pt.build.keylayout=PORTUGUESE -teensy36.menu.keys.pt-br=Portuguese Brazilian -teensy36.menu.keys.pt-br.build.keylayout=PORTUGUESE_BRAZILIAN -teensy36.menu.keys.rs-rs=Serbian (Latin Only) -teensy36.menu.keys.rs-rs.build.keylayout=SERBIAN_LATIN_ONLY -teensy36.menu.keys.es-es=Spanish -teensy36.menu.keys.es-es.build.keylayout=SPANISH -teensy36.menu.keys.es-mx=Spanish Latin America -teensy36.menu.keys.es-mx.build.keylayout=SPANISH_LATIN_AMERICA -teensy36.menu.keys.sv-se=Swedish -teensy36.menu.keys.sv-se.build.keylayout=SWEDISH -teensy36.menu.keys.tr-tr=Turkish (partial) -teensy36.menu.keys.tr-tr.build.keylayout=TURKISH -teensy36.menu.keys.en-gb=United Kingdom -teensy36.menu.keys.en-gb.build.keylayout=UNITED_KINGDOM -teensy36.menu.keys.usint=US International -teensy36.menu.keys.usint.build.keylayout=US_INTERNATIONAL - - -teensy35.name=Teensy 3.5 -teensy35.upload.maximum_size=524288 -teensy35.upload.maximum_data_size=262136 -teensy35.upload.tool=teensyloader -teensy35.upload.protocol=halfkay -teensy35.build.board=TEENSY35 -teensy35.build.core=teensy3 -teensy35.build.mcu=mk64fx512 -teensy35.build.warn_data_percentage=98 -teensy35.build.toolchain=arm/bin/ -teensy35.build.command.gcc=arm-none-eabi-gcc -teensy35.build.command.g++=arm-none-eabi-g++ -teensy35.build.command.ar=arm-none-eabi-gcc-ar -teensy35.build.command.objcopy=arm-none-eabi-objcopy -teensy35.build.command.objdump=arm-none-eabi-objdump -teensy35.build.command.linker=arm-none-eabi-gcc -teensy35.build.command.size=arm-none-eabi-size -teensy35.build.flags.common=-g -Wall -ffunction-sections -fdata-sections -nostdlib -teensy35.build.flags.dep=-MMD -teensy35.build.flags.optimize=-Os -teensy35.build.flags.cpu=-mthumb -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -fsingle-precision-constant -teensy35.build.flags.defs=-D__MK64FX512__ -DTEENSYDUINO=153 -teensy35.build.flags.cpp=-fno-exceptions -fpermissive -felide-constructors -std=gnu++14 -Wno-error=narrowing -fno-rtti -teensy35.build.flags.c= -teensy35.build.flags.S=-x assembler-with-cpp -teensy35.build.flags.ld=-Wl,--gc-sections,--relax,--defsym=__rtc_localtime={extra.time.local} "-T{build.core.path}/mk64fx512.ld" -teensy35.build.flags.libs=-larm_cortexM4lf_math -lm -lstdc++ -teensy35.serial.restart_cmd=false -teensy35.menu.usb.serial=Serial -teensy35.menu.usb.serial.build.usbtype=USB_SERIAL -teensy35.menu.usb.serial2=Dual Serial -teensy35.menu.usb.serial2.build.usbtype=USB_DUAL_SERIAL -teensy35.menu.usb.serial3=Triple Serial -teensy35.menu.usb.serial3.build.usbtype=USB_TRIPLE_SERIAL -teensy35.menu.usb.keyboard=Keyboard -teensy35.menu.usb.keyboard.build.usbtype=USB_KEYBOARDONLY -teensy35.menu.usb.keyboard.fake_serial=teensy_gateway -teensy35.menu.usb.touch=Keyboard + Touch Screen -teensy35.menu.usb.touch.build.usbtype=USB_TOUCHSCREEN -teensy35.menu.usb.touch.fake_serial=teensy_gateway -teensy35.menu.usb.hidtouch=Keyboard + Mouse + Touch Screen -teensy35.menu.usb.hidtouch.build.usbtype=USB_HID_TOUCHSCREEN -teensy35.menu.usb.hidtouch.fake_serial=teensy_gateway -teensy35.menu.usb.hid=Keyboard + Mouse + Joystick -teensy35.menu.usb.hid.build.usbtype=USB_HID -teensy35.menu.usb.hid.fake_serial=teensy_gateway -teensy35.menu.usb.serialhid=Serial + Keyboard + Mouse + Joystick -teensy35.menu.usb.serialhid.build.usbtype=USB_SERIAL_HID -teensy35.menu.usb.midi=MIDI -teensy35.menu.usb.midi.build.usbtype=USB_MIDI -teensy35.menu.usb.midi.fake_serial=teensy_gateway -teensy35.menu.usb.midi4=MIDIx4 -teensy35.menu.usb.midi4.build.usbtype=USB_MIDI4 -teensy35.menu.usb.midi4.fake_serial=teensy_gateway -teensy35.menu.usb.midi16=MIDIx16 -teensy35.menu.usb.midi16.build.usbtype=USB_MIDI16 -teensy35.menu.usb.midi16.fake_serial=teensy_gateway -teensy35.menu.usb.serialmidi=Serial + MIDI -teensy35.menu.usb.serialmidi.build.usbtype=USB_MIDI_SERIAL -teensy35.menu.usb.serialmidi4=Serial + MIDIx4 -teensy35.menu.usb.serialmidi4.build.usbtype=USB_MIDI4_SERIAL -teensy35.menu.usb.serialmidi16=Serial + MIDIx16 -teensy35.menu.usb.serialmidi16.build.usbtype=USB_MIDI16_SERIAL -teensy35.menu.usb.audio=Audio -teensy35.menu.usb.audio.build.usbtype=USB_AUDIO -teensy35.menu.usb.audio.fake_serial=teensy_gateway -teensy35.menu.usb.serialmidiaudio=Serial + MIDI + Audio -teensy35.menu.usb.serialmidiaudio.build.usbtype=USB_MIDI_AUDIO_SERIAL -teensy35.menu.usb.serialmidi16audio=Serial + MIDIx16 + Audio -teensy35.menu.usb.serialmidi16audio.build.usbtype=USB_MIDI16_AUDIO_SERIAL -teensy35.menu.usb.mtp=MTP Disk (Experimental) -teensy35.menu.usb.mtp.build.usbtype=USB_MTPDISK -teensy35.menu.usb.mtp.fake_serial=teensy_gateway -teensy35.menu.usb.rawhid=Raw HID -teensy35.menu.usb.rawhid.build.usbtype=USB_RAWHID -teensy35.menu.usb.rawhid.fake_serial=teensy_gateway -teensy35.menu.usb.flightsim=Flight Sim Controls -teensy35.menu.usb.flightsim.build.usbtype=USB_FLIGHTSIM -teensy35.menu.usb.flightsim.fake_serial=teensy_gateway -teensy35.menu.usb.flightsimjoystick=Flight Sim Controls + Joystick -teensy35.menu.usb.flightsimjoystick.build.usbtype=USB_FLIGHTSIM_JOYSTICK -teensy35.menu.usb.flightsimjoystick.fake_serial=teensy_gateway -teensy35.menu.usb.everything=All of the Above -teensy35.menu.usb.everything.build.usbtype=USB_EVERYTHING -teensy35.menu.usb.disable=No USB -teensy35.menu.usb.disable.build.usbtype=USB_DISABLED - -teensy35.menu.speed.120=120 MHz -teensy35.menu.speed.96=96 MHz -teensy35.menu.speed.72=72 MHz -teensy35.menu.speed.48=48 MHz -teensy35.menu.speed.24=24 MHz -teensy35.menu.speed.16=16 MHz (No USB) -teensy35.menu.speed.8=8 MHz (No USB) -teensy35.menu.speed.4=4 MHz (No USB) -teensy35.menu.speed.2=2 MHz (No USB) -teensy35.menu.speed.144=144 MHz (overclock) -teensy35.menu.speed.168=168 MHz (overclock) -teensy35.menu.speed.168.build.fcpu=168000000 -teensy35.menu.speed.144.build.fcpu=144000000 -teensy35.menu.speed.120.build.fcpu=120000000 -teensy35.menu.speed.96.build.fcpu=96000000 -teensy35.menu.speed.72.build.fcpu=72000000 -teensy35.menu.speed.48.build.fcpu=48000000 -teensy35.menu.speed.24.build.fcpu=24000000 -teensy35.menu.speed.16.build.fcpu=16000000 -teensy35.menu.speed.8.build.fcpu=8000000 -teensy35.menu.speed.4.build.fcpu=4000000 -teensy35.menu.speed.2.build.fcpu=2000000 - -teensy35.menu.opt.o2std=Faster -teensy35.menu.opt.o2std.build.flags.optimize=-O2 -teensy35.menu.opt.o2std.build.flags.ldspecs= -teensy35.menu.opt.o2lto=Faster with LTO -teensy35.menu.opt.o2lto.build.flags.optimize=-O2 -flto -fno-fat-lto-objects -teensy35.menu.opt.o2lto.build.flags.ldspecs=-fuse-linker-plugin -teensy35.menu.opt.o1std=Fast -teensy35.menu.opt.o1std.build.flags.optimize=-O1 -teensy35.menu.opt.o1std.build.flags.ldspecs= -teensy35.menu.opt.o1lto=Fast with LTO -teensy35.menu.opt.o1lto.build.flags.optimize=-O1 -flto -fno-fat-lto-objects -teensy35.menu.opt.o1lto.build.flags.ldspecs=-fuse-linker-plugin -teensy35.menu.opt.o3std=Fastest -teensy35.menu.opt.o3std.build.flags.optimize=-O3 -teensy35.menu.opt.o3std.build.flags.ldspecs= -teensy35.menu.opt.o3purestd=Fastest + pure-code -teensy35.menu.opt.o3purestd.build.flags.optimize=-O3 -mpure-code -D__PURE_CODE__ -teensy35.menu.opt.o3purestd.build.flags.ldspecs= -teensy35.menu.opt.o3lto=Fastest with LTO -teensy35.menu.opt.o3lto.build.flags.optimize=-O3 -flto -fno-fat-lto-objects -teensy35.menu.opt.o3lto.build.flags.ldspecs=-fuse-linker-plugin -teensy35.menu.opt.o3purelto=Fastest + pure-code with LTO -teensy35.menu.opt.o3purelto.build.flags.optimize=-O3 -mpure-code -D__PURE_CODE__ -flto -fno-fat-lto-objects -teensy35.menu.opt.o3purelto.build.flags.ldspecs=-fuse-linker-plugin -teensy35.menu.opt.ogstd=Debug -teensy35.menu.opt.ogstd.build.flags.optimize=-Og -teensy35.menu.opt.ogstd.build.flags.ldspecs= -teensy35.menu.opt.oglto=Debug with LTO -teensy35.menu.opt.oglto.build.flags.optimize=-Og -flto -fno-fat-lto-objects -teensy35.menu.opt.oglto.build.flags.ldspecs=-fuse-linker-plugin -teensy35.menu.opt.osstd=Smallest Code -teensy35.menu.opt.osstd.build.flags.optimize=-Os --specs=nano.specs -teensy35.menu.opt.osstd.build.flags.ldspecs= -teensy35.menu.opt.oslto=Smallest Code with LTO -teensy35.menu.opt.oslto.build.flags.optimize=-Os -flto -fno-fat-lto-objects --specs=nano.specs -teensy35.menu.opt.oslto.build.flags.ldspecs=-fuse-linker-plugin - -teensy35.menu.keys.en-us=US English -teensy35.menu.keys.en-us.build.keylayout=US_ENGLISH -teensy35.menu.keys.fr-ca=Canadian French -teensy35.menu.keys.fr-ca.build.keylayout=CANADIAN_FRENCH -teensy35.menu.keys.xx-ca=Canadian Multilingual -teensy35.menu.keys.xx-ca.build.keylayout=CANADIAN_MULTILINGUAL -teensy35.menu.keys.cz-cz=Czech -teensy35.menu.keys.cz-cz.build.keylayout=CZECH -teensy35.menu.keys.da-da=Danish -teensy35.menu.keys.da-da.build.keylayout=DANISH -teensy35.menu.keys.fi-fi=Finnish -teensy35.menu.keys.fi-fi.build.keylayout=FINNISH -teensy35.menu.keys.fr-fr=French -teensy35.menu.keys.fr-fr.build.keylayout=FRENCH -teensy35.menu.keys.fr-be=French Belgian -teensy35.menu.keys.fr-be.build.keylayout=FRENCH_BELGIAN -teensy35.menu.keys.fr-ch=French Swiss -teensy35.menu.keys.fr-ch.build.keylayout=FRENCH_SWISS -teensy35.menu.keys.de-de=German -teensy35.menu.keys.de-de.build.keylayout=GERMAN -teensy35.menu.keys.de-dm=German (Mac) -teensy35.menu.keys.de-dm.build.keylayout=GERMAN_MAC -teensy35.menu.keys.de-ch=German Swiss -teensy35.menu.keys.de-ch.build.keylayout=GERMAN_SWISS -teensy35.menu.keys.is-is=Icelandic -teensy35.menu.keys.is-is.build.keylayout=ICELANDIC -teensy35.menu.keys.en-ie=Irish -teensy35.menu.keys.en-ie.build.keylayout=IRISH -teensy35.menu.keys.it-it=Italian -teensy35.menu.keys.it-it.build.keylayout=ITALIAN -teensy35.menu.keys.no-no=Norwegian -teensy35.menu.keys.no-no.build.keylayout=NORWEGIAN -teensy35.menu.keys.pt-pt=Portuguese -teensy35.menu.keys.pt-pt.build.keylayout=PORTUGUESE -teensy35.menu.keys.pt-br=Portuguese Brazilian -teensy35.menu.keys.pt-br.build.keylayout=PORTUGUESE_BRAZILIAN -teensy35.menu.keys.rs-rs=Serbian (Latin Only) -teensy35.menu.keys.rs-rs.build.keylayout=SERBIAN_LATIN_ONLY -teensy35.menu.keys.es-es=Spanish -teensy35.menu.keys.es-es.build.keylayout=SPANISH -teensy35.menu.keys.es-mx=Spanish Latin America -teensy35.menu.keys.es-mx.build.keylayout=SPANISH_LATIN_AMERICA -teensy35.menu.keys.sv-se=Swedish -teensy35.menu.keys.sv-se.build.keylayout=SWEDISH -teensy35.menu.keys.tr-tr=Turkish (partial) -teensy35.menu.keys.tr-tr.build.keylayout=TURKISH -teensy35.menu.keys.en-gb=United Kingdom -teensy35.menu.keys.en-gb.build.keylayout=UNITED_KINGDOM -teensy35.menu.keys.usint=US International -teensy35.menu.keys.usint.build.keylayout=US_INTERNATIONAL - - -teensy31.name=Teensy 3.2 / 3.1 -teensy31.upload.maximum_size=262144 -teensy31.upload.maximum_data_size=65536 -teensy31.upload.tool=teensyloader -teensy31.upload.protocol=halfkay -teensy31.build.board=TEENSY32 -teensy31.build.core=teensy3 -teensy31.build.mcu=mk20dx256 -teensy31.build.warn_data_percentage=97 -teensy31.build.toolchain=arm/bin/ -teensy31.build.command.gcc=arm-none-eabi-gcc -teensy31.build.command.g++=arm-none-eabi-g++ -teensy31.build.command.ar=arm-none-eabi-gcc-ar -teensy31.build.command.objcopy=arm-none-eabi-objcopy -teensy31.build.command.objdump=arm-none-eabi-objdump -teensy31.build.command.linker=arm-none-eabi-gcc -teensy31.build.command.size=arm-none-eabi-size -teensy31.build.flags.common=-g -Wall -ffunction-sections -fdata-sections -nostdlib -teensy31.build.flags.dep=-MMD -teensy31.build.flags.optimize=-Os -teensy31.build.flags.cpu=-mthumb -mcpu=cortex-m4 -fsingle-precision-constant -teensy31.build.flags.defs=-D__MK20DX256__ -DTEENSYDUINO=153 -teensy31.build.flags.cpp=-fno-exceptions -fpermissive -felide-constructors -std=gnu++14 -Wno-error=narrowing -fno-rtti -teensy31.build.flags.c= -teensy31.build.flags.S=-x assembler-with-cpp -teensy31.build.flags.ld=-Wl,--gc-sections,--relax,--defsym=__rtc_localtime={extra.time.local} "-T{build.core.path}/mk20dx256.ld" -teensy31.build.flags.libs=-larm_cortexM4l_math -lm -lstdc++ -teensy31.serial.restart_cmd=false -teensy31.menu.usb.serial=Serial -teensy31.menu.usb.serial.build.usbtype=USB_SERIAL -teensy31.menu.usb.serial2=Dual Serial -teensy31.menu.usb.serial2.build.usbtype=USB_DUAL_SERIAL -teensy31.menu.usb.serial3=Triple Serial -teensy31.menu.usb.serial3.build.usbtype=USB_TRIPLE_SERIAL -teensy31.menu.usb.keyboard=Keyboard -teensy31.menu.usb.keyboard.build.usbtype=USB_KEYBOARDONLY -teensy31.menu.usb.keyboard.fake_serial=teensy_gateway -teensy31.menu.usb.touch=Keyboard + Touch Screen -teensy31.menu.usb.touch.build.usbtype=USB_TOUCHSCREEN -teensy31.menu.usb.touch.fake_serial=teensy_gateway -teensy31.menu.usb.hidtouch=Keyboard + Mouse + Touch Screen -teensy31.menu.usb.hidtouch.build.usbtype=USB_HID_TOUCHSCREEN -teensy31.menu.usb.hidtouch.fake_serial=teensy_gateway -teensy31.menu.usb.hid=Keyboard + Mouse + Joystick -teensy31.menu.usb.hid.build.usbtype=USB_HID -teensy31.menu.usb.hid.fake_serial=teensy_gateway -teensy31.menu.usb.serialhid=Serial + Keyboard + Mouse + Joystick -teensy31.menu.usb.serialhid.build.usbtype=USB_SERIAL_HID -teensy31.menu.usb.midi=MIDI -teensy31.menu.usb.midi.build.usbtype=USB_MIDI -teensy31.menu.usb.midi.fake_serial=teensy_gateway -teensy31.menu.usb.midi4=MIDIx4 -teensy31.menu.usb.midi4.build.usbtype=USB_MIDI4 -teensy31.menu.usb.midi4.fake_serial=teensy_gateway -teensy31.menu.usb.midi16=MIDIx16 -teensy31.menu.usb.midi16.build.usbtype=USB_MIDI16 -teensy31.menu.usb.midi16.fake_serial=teensy_gateway -teensy31.menu.usb.serialmidi=Serial + MIDI -teensy31.menu.usb.serialmidi.build.usbtype=USB_MIDI_SERIAL -teensy31.menu.usb.serialmidi4=Serial + MIDIx4 -teensy31.menu.usb.serialmidi4.build.usbtype=USB_MIDI4_SERIAL -teensy31.menu.usb.serialmidi16=Serial + MIDIx16 -teensy31.menu.usb.serialmidi16.build.usbtype=USB_MIDI16_SERIAL -teensy31.menu.usb.audio=Audio -teensy31.menu.usb.audio.build.usbtype=USB_AUDIO -teensy31.menu.usb.audio.fake_serial=teensy_gateway -teensy31.menu.usb.serialmidiaudio=Serial + MIDI + Audio -teensy31.menu.usb.serialmidiaudio.build.usbtype=USB_MIDI_AUDIO_SERIAL -teensy31.menu.usb.serialmidi16audio=Serial + MIDIx16 + Audio -teensy31.menu.usb.serialmidi16audio.build.usbtype=USB_MIDI16_AUDIO_SERIAL -teensy31.menu.usb.mtp=MTP Disk (Experimental) -teensy31.menu.usb.mtp.build.usbtype=USB_MTPDISK -teensy31.menu.usb.mtp.fake_serial=teensy_gateway -teensy31.menu.usb.rawhid=Raw HID -teensy31.menu.usb.rawhid.build.usbtype=USB_RAWHID -teensy31.menu.usb.rawhid.fake_serial=teensy_gateway -teensy31.menu.usb.flightsim=Flight Sim Controls -teensy31.menu.usb.flightsim.build.usbtype=USB_FLIGHTSIM -teensy31.menu.usb.flightsim.fake_serial=teensy_gateway -teensy31.menu.usb.flightsimjoystick=Flight Sim Controls + Joystick -teensy31.menu.usb.flightsimjoystick.build.usbtype=USB_FLIGHTSIM_JOYSTICK -teensy31.menu.usb.flightsimjoystick.fake_serial=teensy_gateway -teensy31.menu.usb.everything=All of the Above -teensy31.menu.usb.everything.build.usbtype=USB_EVERYTHING -teensy31.menu.usb.disable=No USB -teensy31.menu.usb.disable.build.usbtype=USB_DISABLED - -teensy31.menu.speed.96=96 MHz (overclock) -teensy31.menu.speed.72=72 MHz -teensy31.menu.speed.48=48 MHz -teensy31.menu.speed.24=24 MHz -teensy31.menu.speed.16=16 MHz (No USB) -teensy31.menu.speed.8=8 MHz (No USB) -teensy31.menu.speed.4=4 MHz (No USB) -teensy31.menu.speed.2=2 MHz (No USB) -teensy31.menu.speed.120=120 MHz (overclock) -#uncomment these if you want to try faster overclocking -#teensy31.menu.speed.144=144 MHz (overclock) -#teensy31.menu.speed.168=168 MHz (overclock) -teensy31.menu.speed.168.build.fcpu=168000000 -teensy31.menu.speed.144.build.fcpu=144000000 -teensy31.menu.speed.120.build.fcpu=120000000 -teensy31.menu.speed.96.build.fcpu=96000000 -teensy31.menu.speed.72.build.fcpu=72000000 -teensy31.menu.speed.48.build.fcpu=48000000 -teensy31.menu.speed.24.build.fcpu=24000000 -teensy31.menu.speed.16.build.fcpu=16000000 -teensy31.menu.speed.8.build.fcpu=8000000 -teensy31.menu.speed.4.build.fcpu=4000000 -teensy31.menu.speed.2.build.fcpu=2000000 - -teensy31.menu.opt.o2std=Faster -teensy31.menu.opt.o2std.build.flags.optimize=-O2 -teensy31.menu.opt.o2std.build.flags.ldspecs= -teensy31.menu.opt.o2lto=Faster with LTO -teensy31.menu.opt.o2lto.build.flags.optimize=-O2 -flto -fno-fat-lto-objects -teensy31.menu.opt.o2lto.build.flags.ldspecs=-fuse-linker-plugin -teensy31.menu.opt.o1std=Fast -teensy31.menu.opt.o1std.build.flags.optimize=-O1 -teensy31.menu.opt.o1std.build.flags.ldspecs= -teensy31.menu.opt.o1lto=Fast with LTO -teensy31.menu.opt.o1lto.build.flags.optimize=-O1 -flto -fno-fat-lto-objects -teensy31.menu.opt.o1lto.build.flags.ldspecs=-fuse-linker-plugin -teensy31.menu.opt.o3std=Fastest -teensy31.menu.opt.o3std.build.flags.optimize=-O3 -teensy31.menu.opt.o3std.build.flags.ldspecs= -teensy31.menu.opt.o3purestd=Fastest + pure-code -teensy31.menu.opt.o3purestd.build.flags.optimize=-O3 -mpure-code -D__PURE_CODE__ -teensy31.menu.opt.o3purestd.build.flags.ldspecs= -teensy31.menu.opt.o3lto=Fastest with LTO -teensy31.menu.opt.o3lto.build.flags.optimize=-O3 -flto -fno-fat-lto-objects -teensy31.menu.opt.o3lto.build.flags.ldspecs=-fuse-linker-plugin -teensy31.menu.opt.o3purelto=Fastest + pure-code with LTO -teensy31.menu.opt.o3purelto.build.flags.optimize=-O3 -mpure-code -D__PURE_CODE__ -flto -fno-fat-lto-objects -teensy31.menu.opt.o3purelto.build.flags.ldspecs=-fuse-linker-plugin -teensy31.menu.opt.ogstd=Debug -teensy31.menu.opt.ogstd.build.flags.optimize=-Og -teensy31.menu.opt.ogstd.build.flags.ldspecs= -teensy31.menu.opt.oglto=Debug with LTO -teensy31.menu.opt.oglto.build.flags.optimize=-Og -flto -fno-fat-lto-objects -teensy31.menu.opt.oglto.build.flags.ldspecs=-fuse-linker-plugin -teensy31.menu.opt.osstd=Smallest Code -teensy31.menu.opt.osstd.build.flags.optimize=-Os --specs=nano.specs -teensy31.menu.opt.osstd.build.flags.ldspecs= -teensy31.menu.opt.oslto=Smallest Code with LTO -teensy31.menu.opt.oslto.build.flags.optimize=-Os -flto -fno-fat-lto-objects --specs=nano.specs -teensy31.menu.opt.oslto.build.flags.ldspecs=-fuse-linker-plugin - -teensy31.menu.keys.en-us=US English -teensy31.menu.keys.en-us.build.keylayout=US_ENGLISH -teensy31.menu.keys.fr-ca=Canadian French -teensy31.menu.keys.fr-ca.build.keylayout=CANADIAN_FRENCH -teensy31.menu.keys.xx-ca=Canadian Multilingual -teensy31.menu.keys.xx-ca.build.keylayout=CANADIAN_MULTILINGUAL -teensy31.menu.keys.cz-cz=Czech -teensy31.menu.keys.cz-cz.build.keylayout=CZECH -teensy31.menu.keys.da-da=Danish -teensy31.menu.keys.da-da.build.keylayout=DANISH -teensy31.menu.keys.fi-fi=Finnish -teensy31.menu.keys.fi-fi.build.keylayout=FINNISH -teensy31.menu.keys.fr-fr=French -teensy31.menu.keys.fr-fr.build.keylayout=FRENCH -teensy31.menu.keys.fr-be=French Belgian -teensy31.menu.keys.fr-be.build.keylayout=FRENCH_BELGIAN -teensy31.menu.keys.fr-ch=French Swiss -teensy31.menu.keys.fr-ch.build.keylayout=FRENCH_SWISS -teensy31.menu.keys.de-de=German -teensy31.menu.keys.de-de.build.keylayout=GERMAN -teensy31.menu.keys.de-dm=German (Mac) -teensy31.menu.keys.de-dm.build.keylayout=GERMAN_MAC -teensy31.menu.keys.de-ch=German Swiss -teensy31.menu.keys.de-ch.build.keylayout=GERMAN_SWISS -teensy31.menu.keys.is-is=Icelandic -teensy31.menu.keys.is-is.build.keylayout=ICELANDIC -teensy31.menu.keys.en-ie=Irish -teensy31.menu.keys.en-ie.build.keylayout=IRISH -teensy31.menu.keys.it-it=Italian -teensy31.menu.keys.it-it.build.keylayout=ITALIAN -teensy31.menu.keys.no-no=Norwegian -teensy31.menu.keys.no-no.build.keylayout=NORWEGIAN -teensy31.menu.keys.pt-pt=Portuguese -teensy31.menu.keys.pt-pt.build.keylayout=PORTUGUESE -teensy31.menu.keys.pt-br=Portuguese Brazilian -teensy31.menu.keys.pt-br.build.keylayout=PORTUGUESE_BRAZILIAN -teensy31.menu.keys.rs-rs=Serbian (Latin Only) -teensy31.menu.keys.rs-rs.build.keylayout=SERBIAN_LATIN_ONLY -teensy31.menu.keys.es-es=Spanish -teensy31.menu.keys.es-es.build.keylayout=SPANISH -teensy31.menu.keys.es-mx=Spanish Latin America -teensy31.menu.keys.es-mx.build.keylayout=SPANISH_LATIN_AMERICA -teensy31.menu.keys.sv-se=Swedish -teensy31.menu.keys.sv-se.build.keylayout=SWEDISH -teensy31.menu.keys.tr-tr=Turkish (partial) -teensy31.menu.keys.tr-tr.build.keylayout=TURKISH -teensy31.menu.keys.en-gb=United Kingdom -teensy31.menu.keys.en-gb.build.keylayout=UNITED_KINGDOM -teensy31.menu.keys.usint=US International -teensy31.menu.keys.usint.build.keylayout=US_INTERNATIONAL - -teensy31.vid.0=0x16C0 -teensy31.vid.1=0x16C0 -teensy31.vid.2=0x16C0 -teensy31.vid.3=0x16C0 -teensy31.vid.4=0x16C0 -teensy31.pid.0=0x0483 -teensy31.pid.1=0x0487 -teensy31.pid.2=0x0489 -teensy31.pid.3=0x048A -teensy31.pid.4=0x0476 - -teensy30.name=Teensy 3.0 -teensy30.upload.maximum_size=131072 -teensy30.upload.maximum_data_size=16384 -teensy30.upload.tool=teensyloader -teensy30.upload.protocol=halfkay -teensy30.build.board=TEENSY30 -teensy30.build.core=teensy3 -teensy30.build.mcu=mk20dx128 -teensy30.build.warn_data_percentage=94 -teensy30.build.toolchain=arm/bin/ -teensy30.build.command.gcc=arm-none-eabi-gcc -teensy30.build.command.g++=arm-none-eabi-g++ -teensy30.build.command.ar=arm-none-eabi-gcc-ar -teensy30.build.command.objcopy=arm-none-eabi-objcopy -teensy30.build.command.objdump=arm-none-eabi-objdump -teensy30.build.command.linker=arm-none-eabi-gcc -teensy30.build.command.size=arm-none-eabi-size -teensy30.build.flags.common=-g -Wall -ffunction-sections -fdata-sections -nostdlib -teensy30.build.flags.dep=-MMD -teensy30.build.flags.optimize=-Os -teensy30.build.flags.cpu=-mthumb -mcpu=cortex-m4 -fsingle-precision-constant -teensy30.build.flags.defs=-D__MK20DX128__ -DTEENSYDUINO=153 -teensy30.build.flags.cpp=-fno-exceptions -fpermissive -felide-constructors -std=gnu++14 -Wno-error=narrowing -fno-rtti -teensy30.build.flags.c= -teensy30.build.flags.S=-x assembler-with-cpp -teensy30.build.flags.ld=-Wl,--gc-sections,--relax,--defsym=__rtc_localtime={extra.time.local} "-T{build.core.path}/mk20dx128.ld" -teensy30.build.flags.ldspecs=--specs=nano.specs -teensy30.build.flags.libs=-larm_cortexM4l_math -lm -lstdc++ -teensy30.serial.restart_cmd=false - -teensy30.menu.usb.serial=Serial -teensy30.menu.usb.serial.build.usbtype=USB_SERIAL -teensy30.menu.usb.keyboard=Keyboard -teensy30.menu.usb.keyboard.build.usbtype=USB_KEYBOARDONLY -teensy30.menu.usb.keyboard.fake_serial=teensy_gateway -teensy30.menu.usb.hid=Keyboard + Mouse + Joystick -teensy30.menu.usb.hid.build.usbtype=USB_HID -teensy30.menu.usb.hid.fake_serial=teensy_gateway -teensy30.menu.usb.serialhid=Serial + Keyboard + Mouse + Joystick -teensy30.menu.usb.serialhid.build.usbtype=USB_SERIAL_HID -teensy30.menu.usb.touch=Keyboard + Touch Screen -teensy30.menu.usb.touch.build.usbtype=USB_TOUCHSCREEN -teensy30.menu.usb.touch.fake_serial=teensy_gateway -teensy30.menu.usb.midi=MIDI -teensy30.menu.usb.midi.build.usbtype=USB_MIDI -teensy30.menu.usb.midi.fake_serial=teensy_gateway -teensy30.menu.usb.midi4=MIDIx4 -teensy30.menu.usb.midi4.build.usbtype=USB_MIDI4 -teensy30.menu.usb.midi4.fake_serial=teensy_gateway -teensy30.menu.usb.serialmidi=Serial + MIDI -teensy30.menu.usb.serialmidi.build.usbtype=USB_MIDI_SERIAL -teensy30.menu.usb.serialmidi4=Serial + MIDIx4 -teensy30.menu.usb.serialmidi4.build.usbtype=USB_MIDI4_SERIAL -teensy30.menu.usb.audio=Audio -teensy30.menu.usb.audio.build.usbtype=USB_AUDIO -teensy30.menu.usb.audio.fake_serial=teensy_gateway -teensy30.menu.usb.serialmidiaudio=Serial + MIDI + Audio -teensy30.menu.usb.serialmidiaudio.build.usbtype=USB_MIDI_AUDIO_SERIAL -teensy30.menu.usb.mtp=MTP Disk (Experimental) -teensy30.menu.usb.mtp.build.usbtype=USB_MTPDISK -teensy30.menu.usb.mtp.fake_serial=teensy_gateway -teensy30.menu.usb.rawhid=Raw HID -teensy30.menu.usb.rawhid.build.usbtype=USB_RAWHID -teensy30.menu.usb.rawhid.fake_serial=teensy_gateway -teensy30.menu.usb.flightsim=Flight Sim Controls -teensy30.menu.usb.flightsim.build.usbtype=USB_FLIGHTSIM -teensy30.menu.usb.flightsim.fake_serial=teensy_gateway -teensy30.menu.usb.disable=No USB -teensy30.menu.usb.disable.build.usbtype=USB_DISABLED - -teensy30.menu.speed.96=96 MHz (overclock) -teensy30.menu.speed.48=48 MHz -teensy30.menu.speed.24=24 MHz -teensy30.menu.speed.96.build.fcpu=96000000 -teensy30.menu.speed.48.build.fcpu=48000000 -teensy30.menu.speed.24.build.fcpu=24000000 - -teensy30.menu.opt.o2std=Faster -teensy30.menu.opt.o2std.build.flags.optimize=-O2 -teensy30.menu.opt.o2std.build.flags.ldspecs= -teensy30.menu.opt.o2lto=Faster with LTO -teensy30.menu.opt.o2lto.build.flags.optimize=-O2 -flto -fno-fat-lto-objects -teensy30.menu.opt.o2lto.build.flags.ldspecs=-fuse-linker-plugin -teensy30.menu.opt.o1std=Fast -teensy30.menu.opt.o1std.build.flags.optimize=-O1 -teensy30.menu.opt.o1std.build.flags.ldspecs= -teensy30.menu.opt.o1lto=Fast with LTO -teensy30.menu.opt.o1lto.build.flags.optimize=-O1 -flto -fno-fat-lto-objects -teensy30.menu.opt.o1lto.build.flags.ldspecs=-fuse-linker-plugin -teensy30.menu.opt.o3std=Fastest -teensy30.menu.opt.o3std.build.flags.optimize=-O3 -teensy30.menu.opt.o3std.build.flags.ldspecs= -teensy30.menu.opt.o3lto=Fastest with LTO -teensy30.menu.opt.o3lto.build.flags.optimize=-O3 -flto -fno-fat-lto-objects -teensy30.menu.opt.o3lto.build.flags.ldspecs=-fuse-linker-plugin -teensy30.menu.opt.ogstd=Debug -teensy30.menu.opt.ogstd.build.flags.optimize=-Og -teensy30.menu.opt.ogstd.build.flags.ldspecs= -teensy30.menu.opt.oglto=Debug with LTO -teensy30.menu.opt.oglto.build.flags.optimize=-Og -flto -fno-fat-lto-objects -teensy30.menu.opt.oglto.build.flags.ldspecs=-fuse-linker-plugin -teensy30.menu.opt.osstd=Smallest Code -teensy30.menu.opt.osstd.build.flags.optimize=-Os --specs=nano.specs -teensy30.menu.opt.osstd.build.flags.ldspecs= -teensy30.menu.opt.oslto=Smallest Code with LTO -teensy30.menu.opt.oslto.build.flags.optimize=-Os -flto -fno-fat-lto-objects --specs=nano.specs -teensy30.menu.opt.oslto.build.flags.ldspecs=-fuse-linker-plugin - -teensy30.menu.keys.en-us=US English -teensy30.menu.keys.en-us.build.keylayout=US_ENGLISH -teensy30.menu.keys.fr-ca=Canadian French -teensy30.menu.keys.fr-ca.build.keylayout=CANADIAN_FRENCH -teensy30.menu.keys.xx-ca=Canadian Multilingual -teensy30.menu.keys.xx-ca.build.keylayout=CANADIAN_MULTILINGUAL -teensy30.menu.keys.cz-cz=Czech -teensy30.menu.keys.cz-cz.build.keylayout=CZECH -teensy30.menu.keys.da-da=Danish -teensy30.menu.keys.da-da.build.keylayout=DANISH -teensy30.menu.keys.fi-fi=Finnish -teensy30.menu.keys.fi-fi.build.keylayout=FINNISH -teensy30.menu.keys.fr-fr=French -teensy30.menu.keys.fr-fr.build.keylayout=FRENCH -teensy30.menu.keys.fr-be=French Belgian -teensy30.menu.keys.fr-be.build.keylayout=FRENCH_BELGIAN -teensy30.menu.keys.fr-ch=French Swiss -teensy30.menu.keys.fr-ch.build.keylayout=FRENCH_SWISS -teensy30.menu.keys.de-de=German -teensy30.menu.keys.de-de.build.keylayout=GERMAN -teensy30.menu.keys.de-dm=German (Mac) -teensy30.menu.keys.de-dm.build.keylayout=GERMAN_MAC -teensy30.menu.keys.de-ch=German Swiss -teensy30.menu.keys.de-ch.build.keylayout=GERMAN_SWISS -teensy30.menu.keys.is-is=Icelandic -teensy30.menu.keys.is-is.build.keylayout=ICELANDIC -teensy30.menu.keys.en-ie=Irish -teensy30.menu.keys.en-ie.build.keylayout=IRISH -teensy30.menu.keys.it-it=Italian -teensy30.menu.keys.it-it.build.keylayout=ITALIAN -teensy30.menu.keys.no-no=Norwegian -teensy30.menu.keys.no-no.build.keylayout=NORWEGIAN -teensy30.menu.keys.pt-pt=Portuguese -teensy30.menu.keys.pt-pt.build.keylayout=PORTUGUESE -teensy30.menu.keys.pt-br=Portuguese Brazilian -teensy30.menu.keys.pt-br.build.keylayout=PORTUGUESE_BRAZILIAN -teensy30.menu.keys.rs-rs=Serbian (Latin Only) -teensy30.menu.keys.rs-rs.build.keylayout=SERBIAN_LATIN_ONLY -teensy30.menu.keys.es-es=Spanish -teensy30.menu.keys.es-es.build.keylayout=SPANISH -teensy30.menu.keys.es-mx=Spanish Latin America -teensy30.menu.keys.es-mx.build.keylayout=SPANISH_LATIN_AMERICA -teensy30.menu.keys.sv-se=Swedish -teensy30.menu.keys.sv-se.build.keylayout=SWEDISH -teensy30.menu.keys.tr-tr=Turkish (partial) -teensy30.menu.keys.tr-tr.build.keylayout=TURKISH -teensy30.menu.keys.en-gb=United Kingdom -teensy30.menu.keys.en-gb.build.keylayout=UNITED_KINGDOM -teensy30.menu.keys.usint=US International -teensy30.menu.keys.usint.build.keylayout=US_INTERNATIONAL - - -teensyLC.name=Teensy LC -teensyLC.upload.maximum_size=63488 -teensyLC.upload.maximum_data_size=8192 -teensyLC.upload.tool=teensyloader -teensyLC.upload.protocol=halfkay -teensyLC.build.board=TEENSYLC -teensyLC.build.core=teensy3 -teensyLC.build.mcu=mkl26z64 -teensyLC.build.warn_data_percentage=88 -teensyLC.build.toolchain=arm/bin/ -teensyLC.build.command.gcc=arm-none-eabi-gcc -teensyLC.build.command.g++=arm-none-eabi-g++ -teensyLC.build.command.ar=arm-none-eabi-gcc-ar -teensyLC.build.command.objcopy=arm-none-eabi-objcopy -teensyLC.build.command.objdump=arm-none-eabi-objdump -teensyLC.build.command.linker=arm-none-eabi-gcc -teensyLC.build.command.size=arm-none-eabi-size -teensyLC.build.flags.common=-g -Wall -ffunction-sections -fdata-sections -nostdlib -teensyLC.build.flags.dep=-MMD -teensyLC.build.flags.cpu=-mthumb -mcpu=cortex-m0plus -fsingle-precision-constant -teensyLC.build.flags.defs=-D__MKL26Z64__ -DTEENSYDUINO=153 -teensyLC.build.flags.cpp=-fno-exceptions -fpermissive -felide-constructors -std=gnu++14 -Wno-error=narrowing -fno-rtti -teensyLC.build.flags.c= -teensyLC.build.flags.S=-x assembler-with-cpp -teensyLC.build.flags.ld=-Wl,--gc-sections,--relax,--defsym=__rtc_localtime={extra.time.local} "-T{build.core.path}/mkl26z64.ld" -teensyLC.build.flags.libs=-larm_cortexM0l_math -lm -lstdc++ -teensyLC.serial.restart_cmd=false -teensyLC.menu.usb.serial=Serial -teensyLC.menu.usb.serial.build.usbtype=USB_SERIAL -teensyLC.menu.usb.serial2=Dual Serial -teensyLC.menu.usb.serial2.build.usbtype=USB_DUAL_SERIAL -teensyLC.menu.usb.serial3=Triple Serial -teensyLC.menu.usb.serial3.build.usbtype=USB_TRIPLE_SERIAL -teensyLC.menu.usb.keyboard=Keyboard -teensyLC.menu.usb.keyboard.build.usbtype=USB_KEYBOARDONLY -teensyLC.menu.usb.keyboard.fake_serial=teensy_gateway -teensyLC.menu.usb.hid=Keyboard + Mouse + Joystick -teensyLC.menu.usb.hid.build.usbtype=USB_HID -teensyLC.menu.usb.hid.fake_serial=teensy_gateway -teensyLC.menu.usb.serialhid=Serial + Keyboard + Mouse + Joystick -teensyLC.menu.usb.serialhid.build.usbtype=USB_SERIAL_HID -teensyLC.menu.usb.touch=Keyboard + Touch Screen -teensyLC.menu.usb.touch.build.usbtype=USB_TOUCHSCREEN -teensyLC.menu.usb.touch.fake_serial=teensy_gateway -teensyLC.menu.usb.midi=MIDI -teensyLC.menu.usb.midi.build.usbtype=USB_MIDI -teensyLC.menu.usb.midi.fake_serial=teensy_gateway -teensyLC.menu.usb.midi4=MIDIx4 -teensyLC.menu.usb.midi4.build.usbtype=USB_MIDI4 -teensyLC.menu.usb.midi4.fake_serial=teensy_gateway -teensyLC.menu.usb.serialmidi=Serial + MIDI -teensyLC.menu.usb.serialmidi.build.usbtype=USB_MIDI_SERIAL -teensyLC.menu.usb.serialmidi4=Serial + MIDIx4 -teensyLC.menu.usb.serialmidi4.build.usbtype=USB_MIDI4_SERIAL -teensyLC.menu.usb.mtp=MTP Disk (Experimental) -teensyLC.menu.usb.mtp.build.usbtype=USB_MTPDISK -teensyLC.menu.usb.mtp.fake_serial=teensy_gateway -teensyLC.menu.usb.rawhid=Raw HID -teensyLC.menu.usb.rawhid.build.usbtype=USB_RAWHID -teensyLC.menu.usb.rawhid.fake_serial=teensy_gateway -teensyLC.menu.usb.flightsim=Flight Sim Controls -teensyLC.menu.usb.flightsim.build.usbtype=USB_FLIGHTSIM -teensyLC.menu.usb.flightsim.fake_serial=teensy_gateway -teensyLC.menu.usb.disable=No USB -teensyLC.menu.usb.disable.build.usbtype=USB_DISABLED - -teensyLC.menu.speed.48=48 MHz -teensyLC.menu.speed.24=24 MHz -teensyLC.menu.speed.48.build.fcpu=48000000 -teensyLC.menu.speed.24.build.fcpu=24000000 - -teensyLC.menu.opt.osstd=Smallest Code -teensyLC.menu.opt.osstd.build.flags.optimize=-Os --specs=nano.specs -teensyLC.menu.opt.osstd.build.flags.ldspecs= -teensyLC.menu.opt.oslto=Smallest Code with LTO -teensyLC.menu.opt.oslto.build.flags.optimize=-Os -flto -fno-fat-lto-objects --specs=nano.specs -teensyLC.menu.opt.oslto.build.flags.ldspecs=-fuse-linker-plugin -teensyLC.menu.opt.ogstd=Debug -teensyLC.menu.opt.ogstd.build.flags.optimize=-Og -teensyLC.menu.opt.ogstd.build.flags.ldspecs= -teensyLC.menu.opt.oglto=Debug with LTO -teensyLC.menu.opt.oglto.build.flags.optimize=-Og -flto -fno-fat-lto-objects -teensyLC.menu.opt.oglto.build.flags.ldspecs=-fuse-linker-plugin -teensyLC.menu.opt.o3std=Fastest -teensyLC.menu.opt.o3std.build.flags.optimize=-O3 -teensyLC.menu.opt.o3std.build.flags.ldspecs= -teensyLC.menu.opt.o3lto=Fastest with LTO -teensyLC.menu.opt.o3lto.build.flags.optimize=-O3 -flto -fno-fat-lto-objects -teensyLC.menu.opt.o3lto.build.flags.ldspecs=-fuse-linker-plugin -teensyLC.menu.opt.o2std=Faster -teensyLC.menu.opt.o2std.build.flags.optimize=-O2 -teensyLC.menu.opt.o2std.build.flags.ldspecs= -teensyLC.menu.opt.o2lto=Faster with LTO -teensyLC.menu.opt.o2lto.build.flags.optimize=-O2 -flto -fno-fat-lto-objects -teensyLC.menu.opt.o2lto.build.flags.ldspecs=-fuse-linker-plugin -teensyLC.menu.opt.o1std=Fast -teensyLC.menu.opt.o1std.build.flags.optimize=-O1 -teensyLC.menu.opt.o1std.build.flags.ldspecs= -teensyLC.menu.opt.o1lto=Fast with LTO -teensyLC.menu.opt.o1lto.build.flags.optimize=-O1 -flto -fno-fat-lto-objects -teensyLC.menu.opt.o1lto.build.flags.ldspecs=-fuse-linker-plugin - -teensyLC.menu.keys.en-us=US English -teensyLC.menu.keys.en-us.build.keylayout=US_ENGLISH -teensyLC.menu.keys.fr-ca=Canadian French -teensyLC.menu.keys.fr-ca.build.keylayout=CANADIAN_FRENCH -teensyLC.menu.keys.xx-ca=Canadian Multilingual -teensyLC.menu.keys.xx-ca.build.keylayout=CANADIAN_MULTILINGUAL -teensyLC.menu.keys.cz-cz=Czech -teensyLC.menu.keys.cz-cz.build.keylayout=CZECH -teensyLC.menu.keys.da-da=Danish -teensyLC.menu.keys.da-da.build.keylayout=DANISH -teensyLC.menu.keys.fi-fi=Finnish -teensyLC.menu.keys.fi-fi.build.keylayout=FINNISH -teensyLC.menu.keys.fr-fr=French -teensyLC.menu.keys.fr-fr.build.keylayout=FRENCH -teensyLC.menu.keys.fr-be=French Belgian -teensyLC.menu.keys.fr-be.build.keylayout=FRENCH_BELGIAN -teensyLC.menu.keys.fr-ch=French Swiss -teensyLC.menu.keys.fr-ch.build.keylayout=FRENCH_SWISS -teensyLC.menu.keys.de-de=German -teensyLC.menu.keys.de-de.build.keylayout=GERMAN -teensyLC.menu.keys.de-dm=German (Mac) -teensyLC.menu.keys.de-dm.build.keylayout=GERMAN_MAC -teensyLC.menu.keys.de-ch=German Swiss -teensyLC.menu.keys.de-ch.build.keylayout=GERMAN_SWISS -teensyLC.menu.keys.is-is=Icelandic -teensyLC.menu.keys.is-is.build.keylayout=ICELANDIC -teensyLC.menu.keys.en-ie=Irish -teensyLC.menu.keys.en-ie.build.keylayout=IRISH -teensyLC.menu.keys.it-it=Italian -teensyLC.menu.keys.it-it.build.keylayout=ITALIAN -teensyLC.menu.keys.no-no=Norwegian -teensyLC.menu.keys.no-no.build.keylayout=NORWEGIAN -teensyLC.menu.keys.pt-pt=Portuguese -teensyLC.menu.keys.pt-pt.build.keylayout=PORTUGUESE -teensyLC.menu.keys.pt-br=Portuguese Brazilian -teensyLC.menu.keys.pt-br.build.keylayout=PORTUGUESE_BRAZILIAN -teensyLC.menu.keys.rs-rs=Serbian (Latin Only) -teensyLC.menu.keys.rs-rs.build.keylayout=SERBIAN_LATIN_ONLY -teensyLC.menu.keys.es-es=Spanish -teensyLC.menu.keys.es-es.build.keylayout=SPANISH -teensyLC.menu.keys.es-mx=Spanish Latin America -teensyLC.menu.keys.es-mx.build.keylayout=SPANISH_LATIN_AMERICA -teensyLC.menu.keys.sv-se=Swedish -teensyLC.menu.keys.sv-se.build.keylayout=SWEDISH -teensyLC.menu.keys.tr-tr=Turkish (partial) -teensyLC.menu.keys.tr-tr.build.keylayout=TURKISH -teensyLC.menu.keys.en-gb=United Kingdom -teensyLC.menu.keys.en-gb.build.keylayout=UNITED_KINGDOM -teensyLC.menu.keys.usint=US International -teensyLC.menu.keys.usint.build.keylayout=US_INTERNATIONAL - - -teensypp2.name=Teensy++ 2.0 -teensypp2.upload.maximum_size=130048 -teensypp2.upload.maximum_data_size=8192 -teensypp2.upload.tool=teensyloader -teensypp2.upload.protocol=halfkay -teensypp2.build.board=TEENSY2PP -teensypp2.build.core=teensy -teensypp2.build.mcu=at90usb1286 -teensypp2.build.warn_data_percentage=94 -teensypp2.build.toolchain=avr/bin/ -teensypp2.build.command.gcc=avr-gcc -teensypp2.build.command.g++=avr-g++ -teensypp2.build.command.ar=avr-ar -teensypp2.build.command.objcopy=avr-objcopy -teensypp2.build.command.objdump=avr-objdump -teensypp2.build.command.linker=avr-gcc -teensypp2.build.command.size=avr-size -teensypp2.build.flags.common=-g -Wall -ffunction-sections -fdata-sections -teensypp2.build.flags.dep=-MMD -teensypp2.build.flags.optimize=-Os -teensypp2.build.flags.cpu=-mmcu=at90usb1286 -teensypp2.build.flags.defs=-DTEENSYDUINO=153 -DARDUINO_ARCH_AVR -teensypp2.build.flags.cpp=-fno-exceptions -fpermissive -felide-constructors -std=gnu++11 -teensypp2.build.flags.c= -teensypp2.build.flags.S=-x assembler-with-cpp -teensypp2.build.flags.ld=-Wl,--gc-sections,--relax -teensypp2.build.flags.ldspecs= -teensypp2.build.flags.libs=-lm -teensypp2.build.serial_number=true -teensypp2.serial.restart_cmd=true - -teensypp2.menu.usb.serial=Serial -teensypp2.menu.usb.serial.build.usbtype=USB_SERIAL -teensypp2.menu.usb.hid=Keyboard + Mouse + Joystick -teensypp2.menu.usb.hid.build.usbtype=USB_HID -teensypp2.menu.usb.hid.fake_serial=teensy_gateway -teensypp2.menu.usb.serialhid=Serial + Keyboard + Mouse + Joystick -teensypp2.menu.usb.serialhid.build.usbtype=USB_SERIAL_HID -teensypp2.menu.usb.int_disk=Disk(Internal) + Keyboard -teensypp2.menu.usb.int_disk.build.usbtype=USB_DISK -teensypp2.menu.usb.int_disk.fake_serial=teensy_gateway -teensypp2.menu.usb.int_disk.build.elfpatch=mktinyfat -teensypp2.menu.usb.sd_disk=Disk(SD Card) + Keyboard -teensypp2.menu.usb.sd_disk.build.usbtype=USB_DISK_SDFLASH -teensypp2.menu.usb.sd_disk.fake_serial=teensy_gateway -teensypp2.menu.usb.midi=MIDI -teensypp2.menu.usb.midi.build.usbtype=USB_MIDI -teensypp2.menu.usb.midi.fake_serial=teensy_gateway -teensypp2.menu.usb.rawhid=Raw HID -teensypp2.menu.usb.rawhid.build.usbtype=USB_RAWHID -teensypp2.menu.usb.rawhid.fake_serial=teensy_gateway -teensypp2.menu.usb.flightsim=Flight Sim Controls -teensypp2.menu.usb.flightsim.build.usbtype=USB_FLIGHTSIM -teensypp2.menu.usb.flightsim.fake_serial=teensy_gateway -teensypp2.menu.speed.16=16 MHz -teensypp2.menu.speed.8=8 MHz -teensypp2.menu.speed.4=4 MHz -teensypp2.menu.speed.2=2 MHz -teensypp2.menu.speed.1=1 MHz -teensypp2.menu.speed.16.build.fcpu=16000000L -teensypp2.menu.speed.8.build.fcpu=8000000L -teensypp2.menu.speed.4.build.fcpu=4000000L -teensypp2.menu.speed.2.build.fcpu=2000000L -teensypp2.menu.speed.1.build.fcpu=1000000L - -teensypp2.menu.keys.en-us=US English -teensypp2.menu.keys.en-us.build.keylayout=US_ENGLISH -teensypp2.menu.keys.fr-ca=Canadian French -teensypp2.menu.keys.fr-ca.build.keylayout=CANADIAN_FRENCH -teensypp2.menu.keys.xx-ca=Canadian Multilingual -teensypp2.menu.keys.xx-ca.build.keylayout=CANADIAN_MULTILINGUAL -teensypp2.menu.keys.cz-cz=Czech -teensypp2.menu.keys.cz-cz.build.keylayout=CZECH -teensypp2.menu.keys.da-da=Danish -teensypp2.menu.keys.da-da.build.keylayout=DANISH -teensypp2.menu.keys.fi-fi=Finnish -teensypp2.menu.keys.fi-fi.build.keylayout=FINNISH -teensypp2.menu.keys.fr-fr=French -teensypp2.menu.keys.fr-fr.build.keylayout=FRENCH -teensypp2.menu.keys.fr-be=French Belgian -teensypp2.menu.keys.fr-be.build.keylayout=FRENCH_BELGIAN -teensypp2.menu.keys.fr-ch=French Swiss -teensypp2.menu.keys.fr-ch.build.keylayout=FRENCH_SWISS -teensypp2.menu.keys.de-de=German -teensypp2.menu.keys.de-de.build.keylayout=GERMAN -teensypp2.menu.keys.de-dm=German (Mac) -teensypp2.menu.keys.de-dm.build.keylayout=GERMAN_MAC -teensypp2.menu.keys.de-ch=German Swiss -teensypp2.menu.keys.de-ch.build.keylayout=GERMAN_SWISS -teensypp2.menu.keys.is-is=Icelandic -teensypp2.menu.keys.is-is.build.keylayout=ICELANDIC -teensypp2.menu.keys.en-ie=Irish -teensypp2.menu.keys.en-ie.build.keylayout=IRISH -teensypp2.menu.keys.it-it=Italian -teensypp2.menu.keys.it-it.build.keylayout=ITALIAN -teensypp2.menu.keys.no-no=Norwegian -teensypp2.menu.keys.no-no.build.keylayout=NORWEGIAN -teensypp2.menu.keys.pt-pt=Portuguese -teensypp2.menu.keys.pt-pt.build.keylayout=PORTUGUESE -teensypp2.menu.keys.pt-br=Portuguese Brazilian -teensypp2.menu.keys.pt-br.build.keylayout=PORTUGUESE_BRAZILIAN -teensypp2.menu.keys.rs-rs=Serbian (Latin Only) -teensypp2.menu.keys.rs-rs.build.keylayout=SERBIAN_LATIN_ONLY -teensypp2.menu.keys.es-es=Spanish -teensypp2.menu.keys.es-es.build.keylayout=SPANISH -teensypp2.menu.keys.es-mx=Spanish Latin America -teensypp2.menu.keys.es-mx.build.keylayout=SPANISH_LATIN_AMERICA -teensypp2.menu.keys.sv-se=Swedish -teensypp2.menu.keys.sv-se.build.keylayout=SWEDISH -teensypp2.menu.keys.tr-tr=Turkish (partial) -teensypp2.menu.keys.tr-tr.build.keylayout=TURKISH -teensypp2.menu.keys.en-gb=United Kingdom -teensypp2.menu.keys.en-gb.build.keylayout=UNITED_KINGDOM -teensypp2.menu.keys.usint=US International -teensypp2.menu.keys.usint.build.keylayout=US_INTERNATIONAL - - -teensy2.name=Teensy 2.0 -teensy2.upload.maximum_size=32256 -teensy2.upload.maximum_data_size=2560 -teensy2.upload.tool=teensyloader -teensy2.upload.protocol=halfkay -teensy2.build.board=TEENSY2 -teensy2.build.core=teensy -teensy2.build.mcu=atmega32u4 -teensy2.build.warn_data_percentage=80 -teensy2.build.toolchain=avr/bin/ -teensy2.build.command.gcc=avr-gcc -teensy2.build.command.g++=avr-g++ -teensy2.build.command.ar=avr-ar -teensy2.build.command.objcopy=avr-objcopy -teensy2.build.command.objdump=avr-objdump -teensy2.build.command.linker=avr-gcc -teensy2.build.command.size=avr-size -teensy2.build.flags.common=-g -Wall -ffunction-sections -fdata-sections -teensy2.build.flags.dep=-MMD -teensy2.build.flags.optimize=-Os -teensy2.build.flags.cpu=-mmcu=atmega32u4 -teensy2.build.flags.defs=-DTEENSYDUINO=153 -DARDUINO_ARCH_AVR -teensy2.build.flags.cpp=-fno-exceptions -fpermissive -felide-constructors -std=gnu++11 -teensy2.build.flags.c= -teensy2.build.flags.S=-x assembler-with-cpp -teensy2.build.flags.ld=-Wl,--gc-sections,--relax -teensy2.build.flags.ldspecs= -teensy2.build.flags.libs=-lm -teensy2.build.serial_number=true -teensy2.serial.restart_cmd=true - -teensy2.menu.usb.serial=Serial -teensy2.menu.usb.serial.build.usbtype=USB_SERIAL -teensy2.menu.usb.hid=Keyboard + Mouse + Joystick -teensy2.menu.usb.hid.build.usbtype=USB_HID -teensy2.menu.usb.hid.fake_serial=teensy_gateway -teensy2.menu.usb.serialhid=Serial + Keyboard + Mouse + Joystick -teensy2.menu.usb.serialhid.build.usbtype=USB_SERIAL_HID -teensy2.menu.usb.int_disk=Disk(Internal) + Keyboard -teensy2.menu.usb.int_disk.build.usbtype=USB_DISK -teensy2.menu.usb.int_disk.fake_serial=teensy_gateway -teensy2.menu.usb.int_disk.build.elfpatch=mktinyfat -teensy2.menu.usb.sd_disk=Disk(SD Card) + Keyboard -teensy2.menu.usb.sd_disk.build.usbtype=USB_DISK_SDFLASH -teensy2.menu.usb.sd_disk.fake_serial=teensy_gateway -teensy2.menu.usb.midi=MIDI -teensy2.menu.usb.midi.build.usbtype=USB_MIDI -teensy2.menu.usb.midi.fake_serial=teensy_gateway -teensy2.menu.usb.rawhid=Raw HID -teensy2.menu.usb.rawhid.build.usbtype=USB_RAWHID -teensy2.menu.usb.rawhid.fake_serial=teensy_gateway -teensy2.menu.usb.flightsim=Flight Sim Controls -teensy2.menu.usb.flightsim.build.usbtype=USB_FLIGHTSIM -teensy2.menu.usb.flightsim.fake_serial=teensy_gateway -teensy2.menu.speed.16=16 MHz -teensy2.menu.speed.8=8 MHz -teensy2.menu.speed.4=4 MHz -teensy2.menu.speed.2=2 MHz -teensy2.menu.speed.1=1 MHz -teensy2.menu.speed.16.build.fcpu=16000000L -teensy2.menu.speed.8.build.fcpu=8000000L -teensy2.menu.speed.4.build.fcpu=4000000L -teensy2.menu.speed.2.build.fcpu=2000000L -teensy2.menu.speed.1.build.fcpu=1000000L - -teensy2.menu.keys.en-us=US English -teensy2.menu.keys.en-us.build.keylayout=US_ENGLISH -teensy2.menu.keys.fr-ca=Canadian French -teensy2.menu.keys.fr-ca.build.keylayout=CANADIAN_FRENCH -teensy2.menu.keys.xx-ca=Canadian Multilingual -teensy2.menu.keys.xx-ca.build.keylayout=CANADIAN_MULTILINGUAL -teensy2.menu.keys.cz-cz=Czech -teensy2.menu.keys.cz-cz.build.keylayout=CZECH -teensy2.menu.keys.da-da=Danish -teensy2.menu.keys.da-da.build.keylayout=DANISH -teensy2.menu.keys.fi-fi=Finnish -teensy2.menu.keys.fi-fi.build.keylayout=FINNISH -teensy2.menu.keys.fr-fr=French -teensy2.menu.keys.fr-fr.build.keylayout=FRENCH -teensy2.menu.keys.fr-be=French Belgian -teensy2.menu.keys.fr-be.build.keylayout=FRENCH_BELGIAN -teensy2.menu.keys.fr-ch=French Swiss -teensy2.menu.keys.fr-ch.build.keylayout=FRENCH_SWISS -teensy2.menu.keys.de-de=German -teensy2.menu.keys.de-de.build.keylayout=GERMAN -teensy2.menu.keys.de-dm=German (Mac) -teensy2.menu.keys.de-dm.build.keylayout=GERMAN_MAC -teensy2.menu.keys.de-ch=German Swiss -teensy2.menu.keys.de-ch.build.keylayout=GERMAN_SWISS -teensy2.menu.keys.is-is=Icelandic -teensy2.menu.keys.is-is.build.keylayout=ICELANDIC -teensy2.menu.keys.en-ie=Irish -teensy2.menu.keys.en-ie.build.keylayout=IRISH -teensy2.menu.keys.it-it=Italian -teensy2.menu.keys.it-it.build.keylayout=ITALIAN -teensy2.menu.keys.no-no=Norwegian -teensy2.menu.keys.no-no.build.keylayout=NORWEGIAN -teensy2.menu.keys.pt-pt=Portuguese -teensy2.menu.keys.pt-pt.build.keylayout=PORTUGUESE -teensy2.menu.keys.pt-br=Portuguese Brazilian -teensy2.menu.keys.pt-br.build.keylayout=PORTUGUESE_BRAZILIAN -teensy2.menu.keys.rs-rs=Serbian (Latin Only) -teensy2.menu.keys.rs-rs.build.keylayout=SERBIAN_LATIN_ONLY -teensy2.menu.keys.es-es=Spanish -teensy2.menu.keys.es-es.build.keylayout=SPANISH -teensy2.menu.keys.es-mx=Spanish Latin America -teensy2.menu.keys.es-mx.build.keylayout=SPANISH_LATIN_AMERICA -teensy2.menu.keys.sv-se=Swedish -teensy2.menu.keys.sv-se.build.keylayout=SWEDISH -teensy2.menu.keys.tr-tr=Turkish (partial) -teensy2.menu.keys.tr-tr.build.keylayout=TURKISH -teensy2.menu.keys.en-gb=United Kingdom -teensy2.menu.keys.en-gb.build.keylayout=UNITED_KINGDOM -teensy2.menu.keys.usint=US International -teensy2.menu.keys.usint.build.keylayout=US_INTERNATIONAL - - diff --git a/lib/TeensyTimerTool-master/library.json b/lib/TeensyTimerTool-master/library.json deleted file mode 100644 index 989e67c..0000000 --- a/lib/TeensyTimerTool-master/library.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "name": "TeensyTimerTool", - "version": "1.1.0", - "keywords": "teensy, pjrc, timer, quad, gpt, tmr, pit, imxrt1062", - "description": "TeensyTimerTool is a library that provides a generic, easy to use interface to the hardware timers of the PJRC Teensy boards. In addition, it provides up to 20 highly efficient software timers that use the same interface. All timers can be used in periodic and one-shot mode. Currently the library supports the ARM T3.X and T4.0 boards. You can either pick a free timer from a pool or specify exactly which of the available hardware or software timer modules you want to use.", - "repository": - { - "type": "git", - "url": "https://github.com/luni64/TeensyTimerTool" - }, - "authors": - { - "name": "luni64", - "url": "https://github.com/luni64", - "maintainer": true - }, - "homepage": "https://github.com/luni64/TeensyTimerTool", - "frameworks": "arduino", - "platforms": "Teensy" -} diff --git a/lib/TeensyTimerTool-master/library.properties b/lib/TeensyTimerTool-master/library.properties deleted file mode 100644 index 3c51f05..0000000 --- a/lib/TeensyTimerTool-master/library.properties +++ /dev/null @@ -1,10 +0,0 @@ -name=TeensyTimerTool -version=1.1.0 -author=luni64 -maintainer=luni64 -sentence=Generic Interface to Teensy Timers -paragraph= TeensyTimerTool is a library that provides a generic, easy to use interface to the hardware timers (FTM, GPT, QUAD, PIT) of the PJRC Teensy boards. In addition, it provides up to 20 highly efficient software timers based on the cycle counter or the RTC (32 and 64bit) that use the same interface. All timers can be used in periodic and one-shot mode. Currently the library supports the ARM T3.X and T4.0 boards. You can either pick a free timer from a pool or specify exactly which of the available hardware or software timer modules you want to use. -category=Timing -url=https://github.com/luni64/TeensyTimerTool -architectures=* -includes=TeensyTimerTool.h diff --git a/lib/TeensyTimerTool-master/src/API/Timer.cpp b/lib/TeensyTimerTool-master/src/API/Timer.cpp deleted file mode 100644 index f15b7ea..0000000 --- a/lib/TeensyTimerTool-master/src/API/Timer.cpp +++ /dev/null @@ -1,10 +0,0 @@ -#include "timer.h" -#include "config.h" - -namespace TeensyTimerTool -{ - Timer::Timer(TimerGenerator *generator) - : BaseTimer(generator, true) - { - } -} // namespace TeensyTimerTool diff --git a/lib/TeensyTimerTool-master/src/API/baseTimer.cpp b/lib/TeensyTimerTool-master/src/API/baseTimer.cpp deleted file mode 100644 index 2652c39..0000000 --- a/lib/TeensyTimerTool-master/src/API/baseTimer.cpp +++ /dev/null @@ -1,30 +0,0 @@ -#include "baseTimer.h" -//#include "Arduino.h" -#include "types.h" - -namespace TeensyTimerTool -{ - - BaseTimer::BaseTimer(TimerGenerator *generator, bool periodic) - : timerGenerator(generator) - { - this->timerGenerator = generator; - this->timerChannel = nullptr; - this->isPeriodic = periodic; - } - - BaseTimer::~BaseTimer() - { - if (timerChannel != nullptr) - { - delete timerChannel; - } - } - - errorCode BaseTimer::setPrescaler(int psc) - { - this->prescaler = psc; - return errorCode::OK; - } - -} // namespace TeensyTimerTool \ No newline at end of file diff --git a/lib/TeensyTimerTool-master/src/API/baseTimer.h b/lib/TeensyTimerTool-master/src/API/baseTimer.h deleted file mode 100644 index 45b8eaa..0000000 --- a/lib/TeensyTimerTool-master/src/API/baseTimer.h +++ /dev/null @@ -1,115 +0,0 @@ -#pragma once - -#include "Arduino.h" -#include "ErrorHandling/error_codes.h" -#include "ITimerChannel.h" -#include "helpers.h" -#include - -#if defined(USE_TIME_LITERALS) -//#include "frequency.h" -#include -#include -using namespace std::chrono_literals; -using namespace std::chrono; -#endif - -namespace TeensyTimerTool -{ - class BaseTimer - { - public: - template - inline errorCode begin(callback_t callback, period_t period, bool start = true); - inline errorCode setPrescaler(int psc); - inline errorCode end(); - inline errorCode start(); - inline errorCode stop(); - - inline float getMaxPeriod() const; - inline float getRemainingTime() const; - - protected: - BaseTimer(TimerGenerator *generator, bool periodic); - virtual ~BaseTimer(); - - TimerGenerator *timerGenerator; - ITimerChannel *timerChannel; - bool isPeriodic; - uint32_t prescaler = 0; - }; - - // INLINE IMPLEMENTATION ================================================ - - template - errorCode BaseTimer::begin(callback_t callback, period_t p, bool start) - { - float period = period2us(p); // transform from any period type to microseconds (float) - - if (callback == nullptr) return postError(errorCode::callback); - if (isPeriodic && period == 0) return postError(errorCode::reload); - - if (timerChannel == nullptr) - { - if (timerGenerator != nullptr) // use timer passed in during construction - { - timerChannel = timerGenerator(); - if (timerChannel == nullptr) return postError(errorCode::noFreeChannel); - } else //find the next free timer - { - for (unsigned i = 0; timerChannel == nullptr && i < timerCnt; i++) - { - timerChannel = timerPool[i](); - } - } - if (timerChannel == nullptr) return postError(errorCode::noFreeModule); - } - - errorCode result = timerChannel->begin(callback, period, isPeriodic); - - if (result == errorCode::OK) - { - if (isPeriodic && start) timerChannel->start(); - } - return postError(result); - } - - errorCode BaseTimer::end() - { - return postError(errorCode::notImplemented); - } - - errorCode BaseTimer::start() - { - if (timerChannel) - return postError(timerChannel->start()); - - return postError(errorCode::notInitialized); - } - - errorCode BaseTimer::stop() - { - if (timerChannel) - return postError(timerChannel->stop()); - - return postError(errorCode::notInitialized); - } - - float BaseTimer::getMaxPeriod() const - { - if (timerChannel != nullptr) - return timerChannel->getMaxPeriod(); - - postError(errorCode::notInitialized); - return NAN; - } - - float BaseTimer::getRemainingTime() const - { - if (timerChannel != nullptr) - return timerChannel->getRemainingTime(); - - postError(errorCode::notInitialized); - return NAN; - } -} // namespace TeensyTimerTool \ No newline at end of file diff --git a/lib/TeensyTimerTool-master/src/API/oneShotTimer.h b/lib/TeensyTimerTool-master/src/API/oneShotTimer.h deleted file mode 100644 index 367c215..0000000 --- a/lib/TeensyTimerTool-master/src/API/oneShotTimer.h +++ /dev/null @@ -1,57 +0,0 @@ -#pragma once - -#include "ErrorHandling/error_codes.h" -#include "baseTimer.h" -#include "type_traits" - -namespace TeensyTimerTool -{ - class OneShotTimer : public BaseTimer - { - public: - inline OneShotTimer(TimerGenerator *generator = nullptr); - - inline errorCode begin(callback_t cb); - template errorCode trigger(T delay); - template errorCode triggerDirect(T reload); - template errorCode getTriggerReload(float delay, T *reload); - }; - - // Implementation ================================================ - - OneShotTimer::OneShotTimer(TimerGenerator *generator) - : BaseTimer(generator, false) - {} - - errorCode OneShotTimer::begin(callback_t callback) - { - return BaseTimer::begin(callback, 0, false); - } - - template - errorCode OneShotTimer::trigger(period_t delay) - { - if (timerChannel) - return postError(timerChannel->trigger(period2us(delay))); - - return postError(errorCode::notInitialized); - } - - template - errorCode OneShotTimer::triggerDirect(T reload) - { - if (timerChannel) - return postError(timerChannel->triggerDirect(reload)); - - return postError(errorCode::notInitialized); - } - - template - errorCode OneShotTimer::getTriggerReload(float delay, T *reload) - { - if (timerChannel) - return postError(timerChannel->getTriggerReload(delay, reload)); - - return postError(errorCode::notInitialized); - } -} // namespace TeensyTimerTool \ No newline at end of file diff --git a/lib/TeensyTimerTool-master/src/API/periodicTimer.h b/lib/TeensyTimerTool-master/src/API/periodicTimer.h deleted file mode 100644 index 921e020..0000000 --- a/lib/TeensyTimerTool-master/src/API/periodicTimer.h +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once - -#include "baseTimer.h" - -namespace TeensyTimerTool -{ - class PeriodicTimer : public BaseTimer - { - public: - PeriodicTimer(TimerGenerator *generator = nullptr) : BaseTimer(generator, true) {} - - template - inline errorCode setPeriod(period_t p) { return postError(timerChannel->setPeriod(period2us(p))); }; - - template - inline errorCode setNextPeriod(period_t p) { return postError(timerChannel->setNextPeriod(period2us(p))); }; - }; - - // IMPLEMENTATION ===================================================================== - -} // namespace TeensyTimerTool \ No newline at end of file diff --git a/lib/TeensyTimerTool-master/src/API/timer.h b/lib/TeensyTimerTool-master/src/API/timer.h deleted file mode 100644 index 7cf3954..0000000 --- a/lib/TeensyTimerTool-master/src/API/timer.h +++ /dev/null @@ -1,33 +0,0 @@ -#pragma once -#include "ErrorHandling/error_codes.h" -#include "ITimerChannel.h" -#include "baseTimer.h" -#include "types.h" - -namespace TeensyTimerTool -{ - class [[deprecated("Consider using PeriodicTimer or OneShotTimer instead")]] Timer : public BaseTimer - { - public: - Timer(TimerGenerator *gen = nullptr); - - inline errorCode beginPeriodic(callback_t cb, uint32_t period) - { - isPeriodic = true; - return BaseTimer::begin(cb, period, true); - } - inline errorCode beginOneShot(callback_t cb) - { - isPeriodic = false; - return BaseTimer::begin(cb, 0, false); - } - inline void trigger(uint32_t delay); - }; - - // IMPLEMENTATION ======================================================= - - void Timer::trigger(const uint32_t delay) - { - timerChannel->trigger(delay); - } -} // namespace TeensyTimerTool diff --git a/lib/TeensyTimerTool-master/src/ErrorHandling/error_codes.h b/lib/TeensyTimerTool-master/src/ErrorHandling/error_codes.h deleted file mode 100644 index a4c8aac..0000000 --- a/lib/TeensyTimerTool-master/src/ErrorHandling/error_codes.h +++ /dev/null @@ -1,38 +0,0 @@ -#pragma once - -namespace TeensyTimerTool -{ - enum class errorCode { - OK = 0, - - // Warnings - periodOverflow = -100, - wrongType = -101, - triggeredLate = -102, //warn if new setted period is shorter than elapsed time - - //General errors - argument = 100, - callback = 101, - reload = 102, - noFreeModule = 103, - noFreeChannel = 104, // requested module has no free channel - notImplemented = 105, // timer does not support this feature - notInitialized = 106, - - // GTP Errors - GTP_err = 200, - GTP_err2 = 201, - - //TMR Errors - TMR_err = 300, - TMR_err2 = 301, - - //FTM Errors - FTM_err = 400, - FTM_err2 = 401, - - //TCK Errors - TCK_err = 900, - TCK_err2 = 901, - }; -} \ No newline at end of file diff --git a/lib/TeensyTimerTool-master/src/ErrorHandling/error_handler.cpp b/lib/TeensyTimerTool-master/src/ErrorHandling/error_handler.cpp deleted file mode 100644 index 125ace2..0000000 --- a/lib/TeensyTimerTool-master/src/ErrorHandling/error_handler.cpp +++ /dev/null @@ -1,79 +0,0 @@ -#include "error_handler.h" -#include "core_pins.h" -#include "types.h" - -namespace TeensyTimerTool -{ - ErrorHandler::ErrorHandler(Stream &s) : stream(s) - { - pinMode(LED_BUILTIN, OUTPUT); - } - - void ErrorHandler::operator()(errorCode code) const - { - const char *txt; - - switch (code) - { - case errorCode::OK: - txt = "OK"; - break; - - // warnings - case errorCode::periodOverflow: - txt = "Period overflow. Period was set to maximum value"; - break; - case errorCode::wrongType: - txt = "Wrong parameter type"; - break; - - // general errors - case errorCode::reload: - txt = "Period must not be zero"; - break; - case errorCode::noFreeChannel: - txt = "Timer module has no free channel"; - break; - case errorCode::noFreeModule: - txt = "Timer pool contains no free timer"; - break; - case errorCode::notImplemented: - txt = "Function not implemented for this timer"; - break; - case errorCode::notInitialized: - txt = "Timer not initialized or available. Did you call begin?"; - break; - - default: - txt = "Unknown error"; - break; - } - - if ((int)code < 0) // in case of warnings we return after printing - { - stream.printf("W-%i: %s\n", -(int)code, txt); - return; - } - - stream.printf("E-%i: %s\n", (int)code, txt); // in case of errors we don't return - while (true) - { - digitalWriteFast(LED_BUILTIN, !digitalReadFast(LED_BUILTIN)); - delay(50); - } - } - - errorFunc_t errFunc; - - errorCode postError(errorCode e) - { - if (errFunc != nullptr && e != errorCode::OK) errFunc(e); - return e; - } - - void attachErrFunc(errorFunc_t _errFunc) - { - errFunc = _errFunc; - } - -} // namespace TeensyTimerTool \ No newline at end of file diff --git a/lib/TeensyTimerTool-master/src/ErrorHandling/error_handler.h b/lib/TeensyTimerTool-master/src/ErrorHandling/error_handler.h deleted file mode 100644 index aac06e3..0000000 --- a/lib/TeensyTimerTool-master/src/ErrorHandling/error_handler.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -#include "Stream.h" -#include "error_codes.h" - -namespace TeensyTimerTool -{ - class ErrorHandler - { - public: - ErrorHandler(Stream &s); - void operator()(errorCode code) const; - - protected: - Stream &stream; - }; -} // namespace TeensyTimerTool \ No newline at end of file diff --git a/lib/TeensyTimerTool-master/src/ITimerChannel.h b/lib/TeensyTimerTool-master/src/ITimerChannel.h deleted file mode 100644 index 95ac616..0000000 --- a/lib/TeensyTimerTool-master/src/ITimerChannel.h +++ /dev/null @@ -1,50 +0,0 @@ -#pragma once - -#include "types.h" -#include - -namespace TeensyTimerTool -{ - class ITimerChannel - { - public: - virtual errorCode begin(callback_t callback, float period, bool oneShot) = 0; - virtual errorCode trigger(float delay) = 0; - virtual errorCode triggerDirect(uint32_t reload) { return postError(errorCode::notImplemented); }; - virtual errorCode triggerDirect(uint64_t reload) { return postError(errorCode::notImplemented); }; - virtual errorCode getTriggerReload(float delay, uint32_t *reload) { return postError(errorCode::notImplemented); }; - virtual errorCode getTriggerReload(float delay, uint64_t *reload) { return postError(errorCode::notImplemented); }; - - virtual errorCode start() = 0; - virtual errorCode stop() = 0; - - virtual errorCode setPrescaler(int psc) { return postError(errorCode::notImplemented); } - - virtual float getMaxPeriod() const = 0; - virtual float getRemainingTime() const { postError(errorCode::notImplemented); return NAN; } - virtual errorCode setPeriod(float microSeconds) { return postError(errorCode::notImplemented); }; - virtual errorCode setNextPeriod(float microSeconds) { return postError(errorCode::notImplemented); }; - virtual uint32_t getPeriod() { return 0; } - - inline void setCallback(callback_t); - - virtual ~ITimerChannel(){}; - - protected: - inline ITimerChannel(callback_t *cbStorage = nullptr); - callback_t *pCallback; - }; - - // IMPLEMENTATION ==================================================== - - ITimerChannel::ITimerChannel(callback_t *cbStorage) - { - this->pCallback = cbStorage; - } - - void ITimerChannel::setCallback(callback_t cb) - { - *pCallback = cb; - } - -} // namespace TeensyTimerTool \ No newline at end of file diff --git a/lib/TeensyTimerTool-master/src/TeensyTimerTool.h b/lib/TeensyTimerTool-master/src/TeensyTimerTool.h deleted file mode 100644 index d917c64..0000000 --- a/lib/TeensyTimerTool-master/src/TeensyTimerTool.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once - -#include "API/oneShotTimer.h" -#include "API/periodicTimer.h" -#include "API/timer.h" -#include "ErrorHandling/error_handler.h" -#include "config.h" - -static_assert(TEENSYDUINO >= 150, "This library requires Teensyduino > 1.5"); \ No newline at end of file diff --git a/lib/TeensyTimerTool-master/src/TimerModules/FTM/FTM.h b/lib/TeensyTimerTool-master/src/TimerModules/FTM/FTM.h deleted file mode 100644 index 0d6b07d..0000000 --- a/lib/TeensyTimerTool-master/src/TimerModules/FTM/FTM.h +++ /dev/null @@ -1,95 +0,0 @@ -#pragma once -#include "FTM_Channel.h" -#include "FTM_Info.h" - -namespace TeensyTimerTool -{ - template - class FTM_t - { - public: - inline static ITimerChannel *getTimer(); - FTM_t() = delete; - - private: - static bool isInitialized; - inline static void isr() FASTRUN; - - static constexpr unsigned maxChannel = FTM_Info::nrOfChannels; - static FTM_ChannelInfo channelInfo[maxChannel]; - static FTM_r_t * const r; - - static_assert(moduleNr < 4, "Module number < 4 required"); - }; - - // IMPLEMENTATION ================================================================== - - template - ITimerChannel *FTM_t::getTimer() - { - if (!isInitialized) - { - r->SC = FTM_SC_CLKS(0b00); // Disable clock - r->MOD = 0xFFFF; // Set full counter range - r->CNT = 0; - - for (unsigned chNr = 0; chNr < maxChannel; chNr++) // init channels - { - channelInfo[chNr].isReserved = false; - channelInfo[chNr].callback = nullptr; - channelInfo[chNr].chRegs = &r->CH[chNr]; - channelInfo[chNr].ticksPerMicrosecond = 1E-6f * F_BUS / (1 << FTM_Info::prescale); - - r->CH[chNr].SC &= ~FTM_CSC_CHF; // FTM requires to clear flag by setting bit to 0 - r->CH[chNr].SC &= ~FTM_CSC_CHIE; // Disable channel interupt - r->CH[chNr].SC = FTM_CSC_MSA; - } - r->SC = FTM_SC_CLKS(0b01) | FTM_SC_PS(FTM_Info::prescale); // Start clock - attachInterruptVector(FTM_Info::irqNumber, isr); // prepare isr and nvic, don't yet enable interrupts - NVIC_ENABLE_IRQ(FTM_Info::irqNumber); - isInitialized = true; - } - - for (unsigned chNr = 0; chNr < maxChannel; chNr++) - { - if (!channelInfo[chNr].isReserved) - { - channelInfo[chNr].isReserved = true; - return new FTM_Channel(r, &channelInfo[chNr]); - } - } - return nullptr; - } - - template - void FTM_t::isr() - { - for (unsigned i = 0; i < maxChannel; i++) - { - FTM_ChannelInfo *ci = &channelInfo[i]; // pre resolving the references turns out to be slightly faster - FTM_CH_t *cr = ci->chRegs; - if ((cr->SC & (FTM_CSC_CHIE | FTM_CSC_CHF)) == (FTM_CSC_CHIE | FTM_CSC_CHF)) // only handle if channel is active (CHIE set) and overflowed (CHF set) - { - if (ci->isPeriodic) - { - cr->SC &= ~FTM_CSC_CHF; // clear channel flag - cr->CV = r->CNT + ci->reload; // set compare value to 'reload' counts ahead of counter - } else - { - cr->SC &= ~FTM_CSC_CHIE; //disable interrupt in on shot mode - } - ci->callback(); - } - } - } - - template - FTM_ChannelInfo FTM_t::channelInfo[maxChannel]; - - template - bool FTM_t::isInitialized = false; - - template - FTM_r_t* const FTM_t::r = (FTM_r_t *)FTM_Info::baseAdr; -} // namespace TeensyTimerTool - diff --git a/lib/TeensyTimerTool-master/src/TimerModules/FTM/FTM_Channel.h b/lib/TeensyTimerTool-master/src/TimerModules/FTM/FTM_Channel.h deleted file mode 100644 index 68ed25a..0000000 --- a/lib/TeensyTimerTool-master/src/TimerModules/FTM/FTM_Channel.h +++ /dev/null @@ -1,121 +0,0 @@ -#pragma once - -#include "Arduino.h" -#include "FTM_ChannelInfo.h" -#include "FTM_Info.h" -#include "ITimerChannel.h" - -namespace TeensyTimerTool -{ - class FTM_Channel : public ITimerChannel - { - public: - inline FTM_Channel(FTM_r_t *regs, FTM_ChannelInfo *ci); - inline virtual ~FTM_Channel(); - - inline float getMaxPeriod() const override; - - inline errorCode begin(callback_t cb, float period, bool periodic) { return doBegin(cb, period, periodic); } ///hacky improve in later version - inline errorCode begin(callback_t cb, uint32_t period, bool periodic) { return doBegin(cb, period, periodic); }; - - inline errorCode trigger(float tcnt) override FASTRUN; - inline errorCode triggerDirect(uint32_t reload) override FASTRUN; - inline errorCode getTriggerReload(float delay, uint32_t *reload) override; - - inline errorCode start() override; - inline errorCode stop() override; - - inline uint16_t ticksFromMicros(float micros); - - // inline void setPeriod(uint32_t) {} - - protected: - FTM_ChannelInfo *ci; - FTM_r_t *regs; - callback_t *pCallback = nullptr; - - template - inline errorCode doBegin(callback_t cb, period_t period, bool periodic); - }; - - // IMPLEMENTATION ============================================== - - FTM_Channel::FTM_Channel(FTM_r_t *regs, FTM_ChannelInfo *channelInfo) - : ITimerChannel(nullptr) - { - this->regs = regs; - this->ci = channelInfo; - } - - template - errorCode FTM_Channel::doBegin(callback_t callback, period_t period, bool periodic) - { - ci->isPeriodic = periodic; - ci->reload = ticksFromMicros(period); - ci->callback = callback; - - return errorCode::OK; - } - - errorCode FTM_Channel::start() - { - ci->chRegs->CV = regs->CNT + ci->reload; // compare value (current counter + pReload) - ci->chRegs->SC &= ~FTM_CSC_CHF; // reset timer flag - ci->chRegs->SC = FTM_CSC_MSA | FTM_CSC_CHIE; // enable interrupts - return errorCode::OK; - } - - errorCode FTM_Channel::stop() - { - ci->chRegs->SC &= ~FTM_CSC_CHIE; // enable interrupts - ci->chRegs->SC &= ~FTM_CSC_CHF; // reset timer flag - - return errorCode::OK; - } - - errorCode FTM_Channel::getTriggerReload(float delay, uint32_t *reload) - { - *reload = ticksFromMicros(delay); - return errorCode::OK; - } - - errorCode FTM_Channel::trigger(float delay) - { - return triggerDirect(ticksFromMicros(delay)); - } - - errorCode FTM_Channel::triggerDirect(uint32_t reload) - { - uint32_t cv = regs->CNT + reload + 1; // calc early to minimize error - ci->chRegs->SC &= ~FTM_CSC_CHF; // Reset timer flag - // - regs->SC &= ~FTM_SC_CLKS_MASK; // need to switch off clock to immediately set new CV - ci->chRegs->CV = cv; // compare value (current counter + pReload) - regs->SC |= FTM_SC_CLKS(0b01); // restart clock - // - ci->chRegs->SC = FTM_CSC_MSA | FTM_CSC_CHIE; // enable interrupts - - return errorCode::OK; - } - - float FTM_Channel::getMaxPeriod() const - { - return (0xFFFF * 1E-6f) / ci->ticksPerMicrosecond; // max period in seconds - } - - uint16_t FTM_Channel::ticksFromMicros(float micros) - { - uint32_t rl = ci->ticksPerMicrosecond * micros; - if (rl > 0xFFFF) - { - postError(errorCode::periodOverflow); // warning only, continues with clipped value - rl = 0xFFFF; - } - return rl; - } - - FTM_Channel::~FTM_Channel() - { - } - -} // namespace TeensyTimerTool diff --git a/lib/TeensyTimerTool-master/src/TimerModules/FTM/FTM_ChannelInfo.h b/lib/TeensyTimerTool-master/src/TimerModules/FTM/FTM_ChannelInfo.h deleted file mode 100644 index 052cb96..0000000 --- a/lib/TeensyTimerTool-master/src/TimerModules/FTM/FTM_ChannelInfo.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -#include "FTM_Info.h" -#include "types.h" - -namespace TeensyTimerTool -{ - struct FTM_ChannelInfo - { - bool isReserved; - bool isPeriodic; - callback_t callback; - uint32_t reload; - FTM_CH_t *chRegs; - float ticksPerMicrosecond; - }; -} // namespace TeensyTimerTool \ No newline at end of file diff --git a/lib/TeensyTimerTool-master/src/TimerModules/FTM/FTM_Info.h b/lib/TeensyTimerTool-master/src/TimerModules/FTM/FTM_Info.h deleted file mode 100644 index a4beb2c..0000000 --- a/lib/TeensyTimerTool-master/src/TimerModules/FTM/FTM_Info.h +++ /dev/null @@ -1,109 +0,0 @@ -#pragma once - -#include "boardDef.h" -#include - -// All information in this header is calculated at compile time. -// FTM_Info will not generate any code - -namespace TeensyTimerTool -{ - typedef struct // FTM & TPM Channels - { - volatile uint32_t SC; - volatile uint32_t CV; - } FTM_CH_t; - - typedef struct // FTM register block (this layout is compatible to a TPM register block) - { - volatile uint32_t SC; - volatile uint32_t CNT; - volatile uint32_t MOD; - FTM_CH_t CH[8]; - volatile uint32_t CNTIN; - volatile uint32_t STATUS; - volatile uint32_t MODE; - volatile uint32_t SYNC; - volatile uint32_t OUTINIT; - volatile uint32_t OUTMASK; - volatile uint32_t COMBINE; - volatile uint32_t DEADTIME; - volatile uint32_t EXTTRIG; - volatile uint32_t POL; - volatile uint32_t FMS; - volatile uint32_t FILTER; - volatile uint32_t FLTCTRL; - volatile uint32_t QDCTRL; - volatile uint32_t CONF; - volatile uint32_t FLTPOL; - volatile uint32_t SYNCONF; - volatile uint32_t INVCTRL; - volatile uint32_t SWOCTRL; - volatile uint32_t PWMLOAD; - } FTM_r_t; - - //======================================================================= - // using a static class instead of namespace here to reduce namespace pollution - // (anonymous namespace doesn't make sense for header only class) - - template - class FTM_Info - { - private: -#if defined(ARDUINO_TEENSYLC) - static constexpr unsigned boardNr = 0; -#elif defined(ARDUINO_TEENSY30) - static constexpr unsigned boardNr = 1; -#elif defined(ARDUINO_TEENSY31) || defined(ARDUINO_TEENSY32) - static constexpr unsigned boardNr = 2; -#elif defined(ARDUINO_TEENSY35) - static constexpr unsigned boardNr = 3; -#elif defined(ARDUINO_TEENSY36) - static constexpr unsigned boardNr = 4; -#else -#error Board not valid -#endif - - static constexpr int IRQ_Numbers[][4]{ - //FTM0 FTM1 FTM2 FTM3 - {0, 0, 0, 0}, // Teensy LC - {25, 26, 0, 0}, // Teensy 3.0 - {62, 63, 64, 0}, // Teensy 3.1/3.2 - {42, 43, 44, 71}, // Teensy 3.5 - {42, 43, 44, 71}, // Teensy 3.6 - }; - - static constexpr int FTM_NrOfChannels[]{ - 8, // FTM0 - 2, // FTM1 - 2, // FTM2 - 8, // FTM3 - }; - - static constexpr uintptr_t FTM_BaseAdr[] // can't use defines from kinetis.h since, depending on board, not all are always defined. - { - 0x4003'8000, // FTM0 - 0x4003'9000, // FTM1 - 0x400B'8000, // FTM2 - 0x400B'9000, // FTM3 - }; - - static constexpr unsigned FTM_Prescale = - FTM_DEFAULT_PSC[module] < 0 || FTM_DEFAULT_PSC[module] > 7 ? // prescale value to roughly get 2 ticks per µs - ( - F_BUS > 120'000'000 ? 0b111 : F_BUS > 60'000'000 ? 0b110 - : F_BUS > 30'000'000 ? 0b101 - : F_BUS > 15'000'000 ? 0b100 - : F_BUS > 8'000'000 ? 0b011 - : F_BUS > 4'000'000 ? 0b010 - : F_BUS > 2'000'000 ? 0b001 - : 0b000) - : FTM_DEFAULT_PSC[module]; - - public: - static constexpr uintptr_t baseAdr = FTM_BaseAdr[module]; - static constexpr IRQ_NUMBER_t irqNumber = (IRQ_NUMBER_t)IRQ_Numbers[boardNr][module]; - static constexpr unsigned nrOfChannels = FTM_NrOfChannels[module]; - static constexpr unsigned prescale = FTM_Prescale; - }; -} // namespace TeensyTimerTool \ No newline at end of file diff --git a/lib/TeensyTimerTool-master/src/TimerModules/GPT/GPT.h b/lib/TeensyTimerTool-master/src/TimerModules/GPT/GPT.h deleted file mode 100644 index 1377536..0000000 --- a/lib/TeensyTimerTool-master/src/TimerModules/GPT/GPT.h +++ /dev/null @@ -1,89 +0,0 @@ -#pragma once - -#include "GPTChannel.h" -//#include "Arduino.h" - -namespace TeensyTimerTool -{ - template - class GPT_t - { - public: - static ITimerChannel *getTimer(); - static void end(); - - protected: - static bool isInitialized; - static void isr(); - static callback_t callback; - static GptChannel *channel; - - // the following is calculated at compile time - static constexpr IRQ_NUMBER_t irq = moduleNr == 0 ? IRQ_GPT1 : IRQ_GPT2; - static IMXRT_GPT_t *const pGPT; - static_assert(moduleNr < 2, "Wrong GPT Number"); - }; - - // IMPLEMENTATION =========================================================================== - - template - IMXRT_GPT_t *const GPT_t::pGPT = reinterpret_cast(moduleNr == 0 ? &IMXRT_GPT1 : &IMXRT_GPT2); - - template - ITimerChannel *GPT_t::getTimer() - { - if (!isInitialized) - { - isInitialized = true; - - if (moduleNr == 0) // GPT1 clock settings - CCM_CCGR1 |= CCM_CCGR1_GPT1_BUS(CCM_CCGR_ON) | CCM_CCGR1_GPT1_SERIAL(CCM_CCGR_ON); // - else // GPT2 - CCM_CCGR0 |= CCM_CCGR0_GPT2_BUS(CCM_CCGR_ON) | CCM_CCGR0_GPT2_SERIAL(CCM_CCGR_ON); // - // - if (USE_GPT_PIT_150MHz) // timer clock setting from config.h - CCM_CSCMR1 &= ~CCM_CSCMR1_PERCLK_CLK_SEL; // use F_BUS - else // - CCM_CSCMR1 |= CCM_CSCMR1_PERCLK_CLK_SEL; // use 24MHz - // - pGPT->CR = GPT_CR_CLKSRC(0x001) | GPT_CR_ENMOD; // stopped, restart mode and peripheral clock source - - attachInterruptVector(irq, isr); - NVIC_ENABLE_IRQ(irq); - - channel = new GptChannel(pGPT, &callback); - return channel; - } - return nullptr; - } - - template - void GPT_t::isr() - { - if (!channel->periodic) - pGPT->CR &= ~GPT_CR_EN; // stop timer in one shot mode - // - pGPT->SR = 0x3F; // reset all interrupt flags - callback(); // we only enabled the OF1 interrupt-> no need to find out which interrupt was actually called - asm volatile("dsb"); // wait until register changes propagated through the cache - } - - template - void GPT_t::end() - { - //Serial.printf("end %d\n", tmoduleNr); - NVIC_DISABLE_IRQ(irq); - pGPT->CR = 0; - callback = nullptr; - isInitialized = false; - } - - template - bool GPT_t::isInitialized = false; - - template - callback_t GPT_t::callback = nullptr; - - template - GptChannel *GPT_t::channel = nullptr; -} // namespace TeensyTimerTool \ No newline at end of file diff --git a/lib/TeensyTimerTool-master/src/TimerModules/GPT/GPTChannel.cpp b/lib/TeensyTimerTool-master/src/TimerModules/GPT/GPTChannel.cpp deleted file mode 100644 index e01ed69..0000000 --- a/lib/TeensyTimerTool-master/src/TimerModules/GPT/GPTChannel.cpp +++ /dev/null @@ -1,24 +0,0 @@ -#if defined(ARDUINO_TEENSY40) || defined(ARDUINO_TEENSY41) || defined(ARDUINO_TEENSY_MICROMOD) - -#include "GPTChannel.h" -#include "GPT.h" -//#include "Arduino.h" - -namespace TeensyTimerTool -{ - GptChannel::~GptChannel() - { - stop(); - setCallback(nullptr); - - if (regs == (IMXRT_GPT_t *)&IMXRT_GPT1) - GPT_t<0>::end(); - - else if (regs == (IMXRT_GPT_t *)&IMXRT_GPT2) - GPT_t<1>::end(); - else - postError(errorCode::GTP_err); - } -} // namespace TeensyTimerTool - -#endif \ No newline at end of file diff --git a/lib/TeensyTimerTool-master/src/TimerModules/GPT/GPTChannel.h b/lib/TeensyTimerTool-master/src/TimerModules/GPT/GPTChannel.h deleted file mode 100644 index 3ca482b..0000000 --- a/lib/TeensyTimerTool-master/src/TimerModules/GPT/GPTChannel.h +++ /dev/null @@ -1,129 +0,0 @@ -#pragma once -#include "Arduino.h" -#include "GPTmap.h" -#include "ITimerChannel.h" -#include "core_pins.h" - -namespace TeensyTimerTool -{ - class GptChannel : public ITimerChannel - { - public: - inline GptChannel(IMXRT_GPT_t *, callback_t *); - virtual ~GptChannel(); - - inline errorCode begin(callback_t cb, float tcnt, bool periodic) override; - inline errorCode start() override; - inline errorCode stop() override; - - inline errorCode trigger(float delay) override; - inline errorCode triggerDirect(uint32_t delay) override; - inline errorCode getTriggerReload(float delay, uint32_t *reload) override; - - inline errorCode setNextPeriod(float us) override; - inline errorCode setPeriod(float us) override; - - inline float getMaxPeriod() const override { return getMaxMicros() / 1E6; } - - bool periodic; - - protected: - inline uint32_t us2ticks(float micros) const; - inline float getMaxMicros() const; - - IMXRT_GPT_t *regs; - //uint32_t reload; - float clock; - }; - - // IMPLEMENTATION ============================================== - - GptChannel::GptChannel(IMXRT_GPT_t *registers, callback_t *cbStorage) - : ITimerChannel(cbStorage), regs(registers) - { - clock = (CCM_CSCMR1 & CCM_CSCMR1_PERCLK_CLK_SEL) ? 24 : (F_BUS_ACTUAL / 1000000); - } - - errorCode GptChannel::begin(callback_t cb, float period, bool periodic) - { - this->periodic = periodic; - if (periodic) - { - regs->OCR1 = us2ticks(period); - } - setCallback(cb); - - return errorCode::OK; - } - - errorCode GptChannel::start() - { - regs->SR = 0x3F; // clear all interupt flags - regs->IR = GPT_IR_OF1IE; // enable OF1 interrupt - regs->CR |= GPT_CR_EN; // enable timer - return errorCode::OK; - } - - errorCode GptChannel::stop() - { - regs->CR &= ~GPT_CR_EN; // disable timer - regs->IR = 0; - return errorCode::OK; - } - - errorCode GptChannel::trigger(float delay) //should be optimized somehow - { - return triggerDirect(us2ticks(delay)); - } - - errorCode GptChannel::triggerDirect(uint32_t reload) - { - regs->SR = 0x3F; // clear all interupt flags - regs->IR = GPT_IR_OF1IE; // enable OF1 interrupt - regs->OCR1 = reload; // set overflow value - regs->CR |= GPT_CR_EN; // enable timer - - return errorCode::OK; - } - - errorCode GptChannel::getTriggerReload(float delay, uint32_t *reload) - { - *reload = us2ticks(delay); - return errorCode::OK; - } - - uint32_t GptChannel::us2ticks(float micros) const - { - if (micros > getMaxMicros()) - { - micros = getMaxPeriod(); - postError(errorCode::periodOverflow); - } - return (uint32_t)(clock * micros) - 1; - } - - float GptChannel::getMaxMicros() const - { - return (float)0xFFFF'FFFE / clock; - } - - errorCode GptChannel::setNextPeriod(float us) - { - return errorCode::notImplemented; - } - - errorCode GptChannel::setPeriod(float us) // not good, will generate one too long period if called before cnt == oldPeriod - { // need to redo the timing using free running timer to get setPeriod and setNewPeriod working correctly - uint32_t newPeriod = us2ticks(us); - // uint32_t now = regs->CNT; - - // if (now > newPeriod) - // { - // (*pCallback)(); // might generate reentrance issues, not a good idea... - // } - - regs->OCR1 = newPeriod; - return errorCode::OK; - } - -} // namespace TeensyTimerTool \ No newline at end of file diff --git a/lib/TeensyTimerTool-master/src/TimerModules/GPT/GPTmap.h b/lib/TeensyTimerTool-master/src/TimerModules/GPT/GPTmap.h deleted file mode 100644 index cf62ea4..0000000 --- a/lib/TeensyTimerTool-master/src/TimerModules/GPT/GPTmap.h +++ /dev/null @@ -1,32 +0,0 @@ -#pragma once - -#include "imxrt.h" -#include - -namespace TeensyTimerTool -{ - struct IMXRT_GPT_t - { - //51.7.1 GPT Control Register - volatile uint32_t CR; - //51.7.2 GPT Prescaler Register(GPTx_PR) - volatile uint32_t PR; - //51.7.3 GPT Status Register(GPTx_SR) - volatile uint32_t SR; - //51.7.4 GPT Interrupt Register(GPTx_IR) - volatile uint32_t IR; - //51.7.5 GPT Output Compare Register (GPTx_OCR1) - volatile uint32_t OCR1; - //51.7.6 GPT Output Compare Register (GPTx_OCR2) - volatile uint32_t OCR2; - //51.7.7 GPT Output Compare Register (GPTx_OCR3) - volatile uint32_t OCR3; - //51.7.8 GPT Input Capture Register 1 (GPTx_ICR1) - volatile uint32_t ICR1; - //51.7.9 GPT Input Capture Register 1 (GPTx_ICR2) - volatile uint32_t ICR2; - //51.7.10 GPT Counter Register (GPTx_CNT) - volatile uint32_t CNT; - }; - -} // namespace TeensyTimerTool \ No newline at end of file diff --git a/lib/TeensyTimerTool-master/src/TimerModules/PIT4/PIT.cpp b/lib/TeensyTimerTool-master/src/TimerModules/PIT4/PIT.cpp deleted file mode 100644 index 3229750..0000000 --- a/lib/TeensyTimerTool-master/src/TimerModules/PIT4/PIT.cpp +++ /dev/null @@ -1,13 +0,0 @@ -#if defined(ARDUINO_TEENSY40) || defined(ARDUINO_TEENSY41) || defined(ARDUINO_TEENSY_MICROMOD) - -#include "PIT.h" - -namespace TeensyTimerTool -{ - bool PIT_t::isInitialized = false; - PITChannel PIT_t::channel[4] = {{0}, {1}, {2}, {3}}; - - uint32_t PITChannel::clockFactor = 1; -} // namespace TeensyTimerTool - -#endif \ No newline at end of file diff --git a/lib/TeensyTimerTool-master/src/TimerModules/PIT4/PIT.h b/lib/TeensyTimerTool-master/src/TimerModules/PIT4/PIT.h deleted file mode 100644 index 50720cd..0000000 --- a/lib/TeensyTimerTool-master/src/TimerModules/PIT4/PIT.h +++ /dev/null @@ -1,70 +0,0 @@ -#pragma once - -#include "PITChannel.h" - -namespace TeensyTimerTool -{ - class PIT_t - { - public: - inline static ITimerChannel *getTimer(); - - protected: - static bool isInitialized; - static void isr(); - static PITChannel channel[4]; - }; - - // IMPLEMENTATION =========================================================================== - - ITimerChannel *PIT_t::getTimer() - { - if (!isInitialized) - { - isInitialized = true; - - CCM_CCGR1 |= CCM_CCGR1_PIT(CCM_CCGR_ON); - PIT_MCR = 1; - - if (USE_GPT_PIT_150MHz) // timer clock setting from config.h - CCM_CSCMR1 &= ~CCM_CSCMR1_PERCLK_CLK_SEL; // FBus (usually 150MHz) - else - CCM_CSCMR1 |= CCM_CSCMR1_PERCLK_CLK_SEL; // 24MHz - - attachInterruptVector(IRQ_PIT, isr); - NVIC_ENABLE_IRQ(IRQ_PIT); - } - - for (unsigned i = 0; i < 4; i++) - { - if (channel[i].callback == nullptr) return &channel[i]; - } - return nullptr; - } - - inline void PIT_t::isr() - { - if (IMXRT_PIT_CHANNELS[0].TFLG) - { - IMXRT_PIT_CHANNELS[0].TFLG = 1; - channel[0].isr(); - } - if (IMXRT_PIT_CHANNELS[1].TFLG) - { - IMXRT_PIT_CHANNELS[1].TFLG = 1; - channel[1].isr(); - } - if (IMXRT_PIT_CHANNELS[2].TFLG) - { - IMXRT_PIT_CHANNELS[2].TFLG = 1; - channel[2].isr(); - } - if (IMXRT_PIT_CHANNELS[3].TFLG) - { - IMXRT_PIT_CHANNELS[3].TFLG = 1; - channel[3].isr(); - } - - asm volatile("dsb"); //wait until register changes propagated through the cache - } -} // namespace TeensyTimerTool diff --git a/lib/TeensyTimerTool-master/src/TimerModules/PIT4/PITChannel.h b/lib/TeensyTimerTool-master/src/TimerModules/PIT4/PITChannel.h deleted file mode 100644 index a018990..0000000 --- a/lib/TeensyTimerTool-master/src/TimerModules/PIT4/PITChannel.h +++ /dev/null @@ -1,151 +0,0 @@ -#pragma once - -#include "Arduino.h" -#include "ITimerChannel.h" - -namespace TeensyTimerTool -{ - class PIT_t; - - class PITChannel : public ITimerChannel - { - public: - inline PITChannel(unsigned nr); - inline virtual ~PITChannel(); - - inline errorCode begin(callback_t cb, float tcnt, bool periodic) override; - //inline errorCode begin(callback_t cb, uint32_t tcnt, bool periodic) override; - inline errorCode start() override; - inline errorCode stop() override; - - //inline errorCode trigger(uint32_t) override; - inline errorCode trigger(float) override; - inline errorCode setNextPeriod(float us) override; - inline errorCode setPeriod(float us) override; - - inline float getMaxPeriod() const override; - - bool isPeriodic; - - protected: - //IMXRT_GPT_t* regs; - //uint32_t reload; - - inline void isr(); - - PITChannel() = delete; - PITChannel(const PITChannel &) = delete; - - const unsigned chNr; - callback_t callback = nullptr; - - static uint32_t clockFactor; - - friend PIT_t; - }; - - // IMPLEMENTATION ============================================== - - PITChannel::PITChannel(unsigned nr) - : ITimerChannel(nullptr), chNr(nr) - { - callback = nullptr; - clockFactor = (CCM_CSCMR1 & CCM_CSCMR1_PERCLK_CLK_SEL) ? 24 : (F_BUS_ACTUAL / 1000000); - } - - errorCode PITChannel::begin(callback_t cb, float micros, bool periodic) - { - isPeriodic = periodic; - callback = cb; - - if (isPeriodic) - { - IMXRT_PIT_CHANNELS[chNr].TCTRL = 0; - IMXRT_PIT_CHANNELS[chNr].TFLG = 1; - - setNextPeriod(micros); - // float tmp = micros * clockFactor; - // if (tmp > 0xFFFF'FFFF) - // { - // postError(errorCode::periodOverflow); - // IMXRT_PIT_CHANNELS[chNr].LDVAL = 0xFFFF'FFFE; - // } else - // { - // IMXRT_PIT_CHANNELS[chNr].LDVAL = (uint32_t)tmp - 1; - // } - } - return errorCode::OK; - } - - errorCode PITChannel::start() - { - IMXRT_PIT_CHANNELS[chNr].TCTRL = PIT_TCTRL_TEN | PIT_TCTRL_TIE; - return errorCode::OK; - } - - errorCode PITChannel::stop() - { - IMXRT_PIT_CHANNELS[chNr].TCTRL = 0; - return errorCode::OK; - } - - errorCode PITChannel::setNextPeriod(float us) - { - float cts = us * clockFactor; - if (cts > 0xFFFF'FFFF) - { - postError(errorCode::periodOverflow); - IMXRT_PIT_CHANNELS[chNr].LDVAL = 0xFFFF'FFFE; - } else - { - IMXRT_PIT_CHANNELS[chNr].LDVAL = (uint32_t)cts - 1; - } - return errorCode::OK; - } - - errorCode PITChannel::setPeriod(float us) - { - stop(); // need to stop/start timer to change current period (see ch 53.9.5.4) - setNextPeriod(us); - start(); - return errorCode::OK; - } - - void PITChannel::isr() - { - if (callback != nullptr) - { - callback(); - if (!isPeriodic) IMXRT_PIT_CHANNELS[chNr].TCTRL = 0; // switch off timer - } - } - - PITChannel::~PITChannel() - { - callback = nullptr; - } - - errorCode PITChannel::trigger(float delay) //should be optimized somehow - { - IMXRT_PIT_CHANNELS[chNr].TCTRL = 0; - IMXRT_PIT_CHANNELS[chNr].TFLG = 1; - - float tmp = delay * clockFactor; - if (tmp > 0xFFFF'FFFF) - { - postError(errorCode::periodOverflow); - IMXRT_PIT_CHANNELS[chNr].LDVAL = 0xFFFF'FFFE; - } else - IMXRT_PIT_CHANNELS[chNr].LDVAL = (uint32_t)tmp - 1; - - start(); - - return errorCode::OK; - } - - float PITChannel::getMaxPeriod() const - { - return (float)0xFFFF'FFFE / clockFactor / 1'000'000; - } - -} // namespace TeensyTimerTool \ No newline at end of file diff --git a/lib/TeensyTimerTool-master/src/TimerModules/TCK/TCK.cpp b/lib/TeensyTimerTool-master/src/TimerModules/TCK/TCK.cpp deleted file mode 100644 index a42bc77..0000000 --- a/lib/TeensyTimerTool-master/src/TimerModules/TCK/TCK.cpp +++ /dev/null @@ -1,40 +0,0 @@ -#include "config.h" - -#if defined(TEENSYDUINO) - -#include "TCK.h" - -namespace TeensyTimerTool -{ - bool TCK_t::isInitialized = false; - TckChannelBase *TCK_t::channels[NR_OF_TCK_TIMERS]; -} // namespace TeensyTimerTool - -//---------------------------------------------------------------------- -#if YIELD_TYPE == YIELD_OPTIMIZED - -void yield() -{ - TeensyTimerTool::TCK_t::tick(); -} - -//---------------------------------------------------------------------- -#elif YIELD_TYPE == YIELD_STANDARD - -#include "EventResponder.h" - -namespace TeensyTimerTool -{ - static EventResponder er; - - void initYieldHook() - { - er.attach([](EventResponderRef r) { - TeensyTimerTool::TCK_t::tick(); - r.triggerEvent(); - }); - er.triggerEvent(); - } -} // namespace TeensyTimerTool -#endif -#endif diff --git a/lib/TeensyTimerTool-master/src/TimerModules/TCK/TCK.h b/lib/TeensyTimerTool-master/src/TimerModules/TCK/TCK.h deleted file mode 100644 index c697187..0000000 --- a/lib/TeensyTimerTool-master/src/TimerModules/TCK/TCK.h +++ /dev/null @@ -1,83 +0,0 @@ -#pragma once - -//#include "Arduino.h" -#include "TckChannel.h" -#include "core_pins.h" - -namespace TeensyTimerTool -{ - extern const unsigned NR_OF_TCK_TIMERS; - - class TCK_t - { - public: - template - static inline ITimerChannel *getTimer(); - static inline void removeTimer(TckChannelBase *); - static inline void tick(); - - protected: - static bool isInitialized; - static TckChannelBase *channels[NR_OF_TCK_TIMERS]; - }; - - // IMPLEMENTATION ================================================================== - - template - ITimerChannel *TCK_t::getTimer() - { - if (!isInitialized) - { - for (unsigned chNr = 0; chNr < NR_OF_TCK_TIMERS; chNr++) - { - channels[chNr] = nullptr; - } - isInitialized = true; - - // start the cycle counter if not already running - if (ARM_DWT_CYCCNT == ARM_DWT_CYCCNT) - { - ARM_DEMCR |= ARM_DEMCR_TRCENA; - ARM_DWT_CTRL |= ARM_DWT_CTRL_CYCCNTENA; - } - -// initialize the yield hook -#if defined(TEENSYDUINO) && YIELD_TYPE == YIELD_STANDARD - extern void initYieldHook(); - initYieldHook(); -#endif - } - for (unsigned chNr = 0; chNr < NR_OF_TCK_TIMERS; chNr++) - { - if (channels[chNr] == nullptr) - { - channels[chNr] = new TckChannel(); - return channels[chNr]; - } - } - return nullptr; - } - - void TCK_t::removeTimer(TckChannelBase *channel) - { - for (unsigned chNr = 0; chNr < NR_OF_TCK_TIMERS; chNr++) - { - if (channels[chNr] == channel) - { - channels[chNr] = nullptr; - break; - } - } - } - - void TCK_t::tick() - { - for (unsigned i = 0; i < NR_OF_TCK_TIMERS; i++) - { - if (channels[i] != nullptr) - { - channels[i]->tick(); - } - } - } -} // namespace TeensyTimerTool diff --git a/lib/TeensyTimerTool-master/src/TimerModules/TCK/TckChannel.h b/lib/TeensyTimerTool-master/src/TimerModules/TCK/TckChannel.h deleted file mode 100644 index 89274fc..0000000 --- a/lib/TeensyTimerTool-master/src/TimerModules/TCK/TckChannel.h +++ /dev/null @@ -1,145 +0,0 @@ -#pragma once - -//#include "Arduino.h" -#include "ErrorHandling/error_codes.h" -#include "TckChannelBase.h" - -namespace TeensyTimerTool -{ - template // tckCounter is the underlying counter, e.g. 32bit cycle counter, RTC counter, micros counter etc - class TckChannel : public TckChannelBase - { - using counter_t = typename tckCounter::counter_t; // use the counter type (uint32_t, unit64_t...) of the used tckCounter class - - public: - TckChannel(); - - inline errorCode begin(callback_t cb, float period, bool periodic) override; - inline errorCode start() override; - inline errorCode stop() override; - - inline errorCode trigger(float delay_us) override; - inline errorCode triggerDirect(counter_t reload) override; - inline errorCode getTriggerReload(float delay, counter_t *reload) override; - - inline errorCode setNextPeriod(float us) override; - inline errorCode setPeriod(float us) override; - - float getMaxPeriod() const override { return tckCounter::getMaxMicros() / 1E6f; } // seconds - float getRemainingTime() const override { return (currentPeriod - (tckCounter::getCount() - startCnt)) / (float)TTT_F_CPU; } - - protected: - inline bool tick(); - callback_t callback; - counter_t startCnt, currentPeriod, nextPeriod; - - bool periodic; - bool triggered; - }; - - // IMPLEMENTATION ============================================== - - template - TckChannel::TckChannel() - { - triggered = false; - } - - template - errorCode TckChannel::begin(callback_t cb, float period, bool periodic) - { - this->triggered = false; - - this->periodic = periodic; - if (periodic) - { - this->currentPeriod = tckCounter::us2ticks(period); - this->nextPeriod = this->currentPeriod; - } - this->callback = cb; - - return errorCode::OK; - } - - template - errorCode TckChannel::start() - { - this->startCnt = tckCounter::getCount(); - this->triggered = true; - return errorCode::OK; - } - - template - errorCode TckChannel::stop() - { - this->triggered = false; - return errorCode::OK; - } - - template - errorCode TckChannel::triggerDirect(counter_t reload) - { - this->startCnt = tckCounter::getCount(); - this->nextPeriod = reload; - this->currentPeriod = this->nextPeriod; - this->triggered = true; - return errorCode::OK; - } - - template - errorCode TckChannel::trigger(float delay) // µs - { - return triggerDirect(tckCounter::us2ticks(delay)); - } - - template - errorCode TckChannel::getTriggerReload(float delay, counter_t *reload) - { - *reload = tckCounter::us2ticks(delay); - return errorCode::OK; - } - - template - errorCode TckChannel::setNextPeriod(float us) - { - nextPeriod = tckCounter::us2ticks(us); - return errorCode::OK; - } - - template - errorCode TckChannel::setPeriod(float us) - { - counter_t newPeriod = tckCounter::us2ticks(us); - counter_t now = tckCounter::getCount(); - - if (now - startCnt >= newPeriod) // new period already expired - { // - startCnt = now; // -> restart cycle but, - callback(); // since expired, invoke callback now - } // - currentPeriod = newPeriod; // in any case next callback will - nextPeriod = newPeriod; // be invoked after newly set period - return errorCode::OK; - } - - template - bool TckChannel::tick() - { - static bool lock = false; - counter_t now = tckCounter::getCount(); - if (!lock && this->currentPeriod != 0 && this->triggered && (now - this->startCnt) >= this->currentPeriod) - { - lock = true; - this->startCnt += currentPeriod; - this->currentPeriod = nextPeriod; // update period if it was changed during current cycle. - this->triggered = this->periodic; // i.e., stays triggerd if periodic, stops if oneShot - callback(); - lock = false; - return true; - } else - { - return false; - } - } - -} // namespace TeensyTimerTool diff --git a/lib/TeensyTimerTool-master/src/TimerModules/TCK/TckChannelBase.cpp b/lib/TeensyTimerTool-master/src/TimerModules/TCK/TckChannelBase.cpp deleted file mode 100644 index 0eeebe8..0000000 --- a/lib/TeensyTimerTool-master/src/TimerModules/TCK/TckChannelBase.cpp +++ /dev/null @@ -1,15 +0,0 @@ -#if defined(TEENSYDUINO) - -#include "TckChannelBase.h" -#include "Arduino.h" -#include "TCK.h" - -namespace TeensyTimerTool -{ - TckChannelBase::~TckChannelBase() - { - TCK_t::removeTimer(this); - } -} // namespace TeensyTimerTool - -#endif \ No newline at end of file diff --git a/lib/TeensyTimerTool-master/src/TimerModules/TCK/TckChannelBase.h b/lib/TeensyTimerTool-master/src/TimerModules/TCK/TckChannelBase.h deleted file mode 100644 index 79b834e..0000000 --- a/lib/TeensyTimerTool-master/src/TimerModules/TCK/TckChannelBase.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -#include "../../ITimerChannel.h" - -namespace TeensyTimerTool -{ - class TckChannelBase : public ITimerChannel - { - public: - virtual bool tick() = 0; - virtual ~TckChannelBase(); - }; -} \ No newline at end of file diff --git a/lib/TeensyTimerTool-master/src/TimerModules/TCK/tickCounters.cpp b/lib/TeensyTimerTool-master/src/TimerModules/TCK/tickCounters.cpp deleted file mode 100644 index 8802010..0000000 --- a/lib/TeensyTimerTool-master/src/TimerModules/TCK/tickCounters.cpp +++ /dev/null @@ -1,103 +0,0 @@ - -#include "tickCounters.h" -#include "Arduino.h" -#include "types.h" -#include "boardDef.h" - -namespace TeensyTimerTool -{ - //--------------------------------------------------------------------- - // CycleCounter32 - - uint32_t CycleCounter32::getCount() - { - return ARM_DWT_CYCCNT; - } - - uint32_t CycleCounter32::us2ticks(float us) - { - return us * (TTT_F_CPU / 1E6f); - } - - float CycleCounter32::getMaxMicros() - { - return 5E6; //Can't use full 2^32 *1.66ns =7.2s range since we need some headroom to detect reaching target. This works if we call tick() at least once per 2 seconds - } - - //--------------------------------------------------------------------- - // CycleCounter64 - - uint64_t CycleCounter64::getCount() - { - static uint32_t lastCyCnt = ARM_DWT_CYCCNT; - static uint32_t curHIGH = 0; - - uint32_t now = ARM_DWT_CYCCNT; - if (now < lastCyCnt) - { - curHIGH++; - } - lastCyCnt = now; - return ((uint64_t)curHIGH << 32) | now; - } - - uint64_t CycleCounter64::us2ticks(float us) - { - return us * (TTT_F_CPU / 1E6f); - } - - float CycleCounter64::getMaxMicros() - { - return 2E16f; //~630 years can't use full 2^64 *1.66ns range since we need some headroom to detect reaching target. - } - - //------------------------------------------------------------------ - // MicrosCounter - - uint32_t MicrosCounter::getCount() - { - return micros(); - } - - uint32_t MicrosCounter::us2ticks(float us) - { - return us; - } - - float MicrosCounter::getMaxMicros() - { - return 70 * 60 * 1E6; // 70min, can't use full 2^32 µs = 72min range since we need some headroom to detect reaching target. This works if we call tick() at least once per 2min - } - -#if defined(TTT_TEENSY4X) - //------------------------------------------------------------------ - // RtcCounter - - uint64_t RtcCounter::getCount() - { - uint32_t hi1 = SNVS_HPRTCMR, lo1 = SNVS_HPRTCLR; - while (true) - { - uint32_t hi2 = SNVS_HPRTCMR, lo2 = SNVS_HPRTCLR; - if (lo1 == lo2 && hi1 == hi2) - { - return (uint64_t)hi2 << 32 | lo2; - } - hi1 = hi2; - lo1 = lo2; - } - } - - uint64_t RtcCounter::us2ticks(float us) - { - return us * (32'768 / 1E6f); - } - - float RtcCounter::getMaxMicros() - { - return 2E16f; // ~630 years - } - -#endif - -} // namespace TeensyTimerTool \ No newline at end of file diff --git a/lib/TeensyTimerTool-master/src/TimerModules/TCK/tickCounters.h b/lib/TeensyTimerTool-master/src/TimerModules/TCK/tickCounters.h deleted file mode 100644 index 225ea1b..0000000 --- a/lib/TeensyTimerTool-master/src/TimerModules/TCK/tickCounters.h +++ /dev/null @@ -1,68 +0,0 @@ -#pragma once - -#include - -namespace TeensyTimerTool -{ - class CycleCounterBase - { - protected: - CycleCounterBase(); - }; - - //--------------------------------------------------------------------- - // Software counter based on the 32bit ARM cycle counter - // Resolution 1/FCPU_ACTUAL (1.66ns @600MHz) - // - struct CycleCounter32 : CycleCounterBase - { - using counter_t = uint32_t; - - static counter_t getCount(); - static uint32_t us2ticks(float us); - static float getMaxMicros(); - }; - - //--------------------------------------------------------------------- - // Software counter based on a 64bit extension of - // the ARM cycle counter - // Resolution 1/FCPU_ACTUAL (6.66ns @600MHz) - // - struct CycleCounter64 : CycleCounterBase - { - using counter_t = uint64_t; - - static uint64_t getCount(); - static uint64_t us2ticks(float us); - static float getMaxMicros(); - }; - - //------------------------------------------------------------------ - // Software counter based on the 64bit period counter - // of the built in real time clock (RTC). - // Resolution: 1/32768s (30.5 µs) - // - struct RtcCounter - { - using counter_t = uint64_t; - - static counter_t getCount(); - static counter_t us2ticks(float us); - static float getMaxMicros(); - }; - - //------------------------------------------------------------------ - // Fallback counter for boards without cycle counter - // E.g. Teensy LC - // Resolution: 1 µs - // - struct MicrosCounter - { - using counter_t = uint32_t; - - static counter_t getCount(); - static counter_t us2ticks(float us); - static float getMaxMicros(); - }; - -} // namespace TeensyTimerTool \ No newline at end of file diff --git a/lib/TeensyTimerTool-master/src/TimerModules/TMR/TMR.h b/lib/TeensyTimerTool-master/src/TimerModules/TMR/TMR.h deleted file mode 100644 index 2e1e526..0000000 --- a/lib/TeensyTimerTool-master/src/TimerModules/TMR/TMR.h +++ /dev/null @@ -1,104 +0,0 @@ -#pragma once - -#include "TMRChannel.h" -#include "imxrt.h" - -namespace TeensyTimerTool -{ - template - class TMR_t - { - public: - static ITimerChannel *getTimer(); - - protected: - static bool isInitialized; - static void isr(); - static callback_t callbacks[4]; - - // the following is calculated at compile time - static constexpr IRQ_NUMBER_t irq = moduleNr == 0 ? IRQ_QTIMER1 : moduleNr == 1 ? IRQ_QTIMER2 - : moduleNr == 2 ? IRQ_QTIMER3 - : IRQ_QTIMER4; - static IMXRT_TMR_t *const pTMR; - static IMXRT_TMR_CH_t *const pCH0; - static IMXRT_TMR_CH_t *const pCH1; - static IMXRT_TMR_CH_t *const pCH2; - static IMXRT_TMR_CH_t *const pCH3; - - static_assert(moduleNr < 4, "Module number < 4 required"); - }; - - // IMPLEMENTATION ================================================================== - - template IMXRT_TMR_t *const TMR_t::pTMR = moduleNr == 0 ? &IMXRT_TMR1 : moduleNr == 1 ? &IMXRT_TMR2 - : moduleNr == 2 ? &IMXRT_TMR3 - : &IMXRT_TMR4; - template IMXRT_TMR_CH_t *const TMR_t::pCH0 = &pTMR->CH[0]; - template IMXRT_TMR_CH_t *const TMR_t::pCH1 = &pTMR->CH[1]; - template IMXRT_TMR_CH_t *const TMR_t::pCH2 = &pTMR->CH[2]; - template IMXRT_TMR_CH_t *const TMR_t::pCH3 = &pTMR->CH[3]; - - template - ITimerChannel *TMR_t::getTimer() - { - if (!isInitialized) - { - for (unsigned chNr = 0; chNr < 4; chNr++) - { - pTMR->CH[chNr].CTRL = 0x0000; - callbacks[chNr] = nullptr; - } - attachInterruptVector(irq, isr); // start - NVIC_ENABLE_IRQ(irq); - isInitialized = true; - return new TMRChannel(pCH0, &callbacks[0]); - } - - for (unsigned chNr = 0; chNr < 4; chNr++) - { - IMXRT_TMR_CH_t *pCh = &pTMR->CH[chNr]; - if (pCh->CTRL == 0x0000) - { - return new TMRChannel(pCh, &callbacks[chNr]); - } - } - return nullptr; - } - - template - void TMR_t::isr() - { - // no loop to gain some time by avoiding indirections and pointer calculations - if (callbacks[0] != nullptr && pCH0->CSCTRL & TMR_CSCTRL_TCF1) - { - pCH0->CSCTRL &= ~TMR_CSCTRL_TCF1; - callbacks[0](); - } - - if (callbacks[1] != nullptr && pCH1->CSCTRL & TMR_CSCTRL_TCF1) - { - pCH1->CSCTRL &= ~TMR_CSCTRL_TCF1; - callbacks[1](); - } - - if (callbacks[2] != nullptr && pCH2->CSCTRL & TMR_CSCTRL_TCF1) - { - pCH2->CSCTRL &= ~TMR_CSCTRL_TCF1; - callbacks[2](); - } - - if (callbacks[3] != nullptr && pCH3->CSCTRL & TMR_CSCTRL_TCF1) - { - pCH3->CSCTRL &= ~TMR_CSCTRL_TCF1; - callbacks[3](); - } - asm volatile("dsb"); //wait until register changes propagated through the cache - } - - template - bool TMR_t::isInitialized = false; - - template - callback_t TMR_t::callbacks[4]; -} // namespace TeensyTimerTool diff --git a/lib/TeensyTimerTool-master/src/TimerModules/TMR/TMRChannel.h b/lib/TeensyTimerTool-master/src/TimerModules/TMR/TMRChannel.h deleted file mode 100644 index 0e45de9..0000000 --- a/lib/TeensyTimerTool-master/src/TimerModules/TMR/TMRChannel.h +++ /dev/null @@ -1,188 +0,0 @@ -#pragma once -#include "../../ITimerChannel.h" -//#include "Arduino.h" -#include "ErrorHandling/error_codes.h" -#include "config.h" -#include "imxrt.h" -#include - -namespace TeensyTimerTool -{ - class TMRChannel : public ITimerChannel - { - public: - inline TMRChannel(IMXRT_TMR_CH_t *regs, callback_t *cbStorage); - inline virtual ~TMRChannel(); - - inline errorCode begin(callback_t cb, float tcnt, bool periodic) override; - inline errorCode start() override; - inline errorCode stop() override; - - inline errorCode trigger(float tcnt) override; - inline float getMaxPeriod() const override; - - inline errorCode setPeriod(float us) override; - inline errorCode setNextPeriod(float us) override; - inline void setPrescaler(uint32_t psc); // psc 0..7 -> prescaler: 1..128 - - protected: - IMXRT_TMR_CH_t *regs; - callback_t **pCallback = nullptr; - float pscValue; - uint32_t pscBits; - - errorCode us2Ticks(const float us, uint16_t *ticks) const; - inline float_t counterToMicrosecond(const float_t cnt) const; - }; - - // IMPLEMENTATION ============================================== - - TMRChannel::TMRChannel(IMXRT_TMR_CH_t *regs, callback_t *cbStorage) - : ITimerChannel(cbStorage) - { - this->regs = regs; - setPrescaler(TMR_DEFAULT_PSC); - } - - TMRChannel::~TMRChannel() - { - regs->CTRL = 0x0000; // stop timer and mark it free - } - - errorCode TMRChannel::start() - { - regs->CNTR = 0x0000; - - regs->CSCTRL &= ~TMR_CSCTRL_TCF1; - regs->CSCTRL |= TMR_CSCTRL_TCF1EN; - return errorCode::OK; - } - - errorCode TMRChannel::stop() - { - regs->CSCTRL &= ~TMR_CSCTRL_TCF1EN; - return errorCode::OK; - } - - errorCode TMRChannel::begin(callback_t cb, float period, bool periodic) - { - uint16_t reload; - errorCode status = us2Ticks(period, &reload); - - regs->CTRL = 0x0000; - regs->LOAD = 0x0000; - regs->COMP1 = reload; - regs->CMPLD1 = reload; - regs->CNTR = 0x0000; - regs->CSCTRL = TMR_CSCTRL_CL1(1); - setCallback(cb); - - if (!periodic) - regs->CTRL = TMR_CTRL_CM(1) | TMR_CTRL_PCS(pscBits) | TMR_CTRL_ONCE | TMR_CTRL_LENGTH; - - else - regs->CTRL = TMR_CTRL_CM(1) | TMR_CTRL_PCS(pscBits) | TMR_CTRL_LENGTH; - - start(); - return status; - } - - errorCode TMRChannel::trigger(float us) // quick and dirty, should be optimized - { - // const float_t t = us2Ticks(tcnt); - // uint16_t reload = t > 0xFFFF ? 0xFFFF : (uint16_t)t; - - uint16_t reload; - errorCode status = us2Ticks(us, &reload); - - regs->CTRL = 0x0000; - regs->LOAD = 0x0000; - regs->COMP1 = reload; - regs->CMPLD1 = reload; - regs->CNTR = 0x0000; - - regs->CSCTRL &= ~TMR_CSCTRL_TCF1; - regs->CSCTRL |= TMR_CSCTRL_TCF1EN; - - regs->CTRL = TMR_CTRL_CM(1) | TMR_CTRL_PCS(pscBits) | TMR_CTRL_ONCE | TMR_CTRL_LENGTH; - - return status; - } - - void TMRChannel::setPrescaler(uint32_t psc) // psc 0..7 -> prescaler: 1..128 - { - pscValue = 1 << (psc & 0b0111); - pscBits = 0b1000 | (psc & 0b0111); - } - - float TMRChannel::getMaxPeriod() const - { - return pscValue / 150'000'000.0f * 0xFFFE; - } - - errorCode TMRChannel::setNextPeriod(float us) - { - uint16_t reload; - errorCode status = us2Ticks(us, &reload); - regs->CMPLD1 = reload; - return status; - } - - // errorCode TMRChannel::_setCurrentPeriod(const uint16_t cnt) - // { - - // regs->COMP1 = cnt; - - // //Do we need to wait some cycle for IP bus to update here / cache flush? - // //asm volatile("dsb"); - - // if (regs->CNTR > cnt) - // { - // //if counter alrready went over setted value force a triggering - // regs->CNTR = cnt; - // return errorCode::triggeredLate; - // } - - // else - // { - // return errorCode::OK; - // } - // } - - errorCode TMRChannel::setPeriod(float us) - { - uint16_t newReload; - errorCode status = us2Ticks(us, &newReload); - - regs->CMPLD1 = newReload; // counter will load this value to COMP1 at next trigger - // - noInterrupts(); // interrupting this code could lead to wrong cntr settings - if (regs->CNTR > newReload) // already too late for new period - regs->CNTR = regs->COMP1; // -> force trigger; will also load COMP1 with value from CMPLD1 - else // not too late - regs->COMP1 = newReload; // -> change current compare value to new one (counter _might_ be > newReload in between.. watch and fix if necessary) - interrupts(); - - return status; - } - - errorCode TMRChannel::us2Ticks(const float us, uint16_t *ticks) const - { - constexpr uint16_t maxTicks = 0xFFFE; - - float tmpTicks = us * 150.0f / pscValue; - if (tmpTicks > maxTicks) - { - *ticks = maxTicks; - return errorCode::periodOverflow; - } - *ticks = (uint16_t)tmpTicks; - return errorCode::OK; - } - - float_t TMRChannel::counterToMicrosecond(const float_t cnt) const - { - return cnt * pscValue / 150.0f; - } - -} // namespace TeensyTimerTool diff --git a/lib/TeensyTimerTool-master/src/boardDef.h b/lib/TeensyTimerTool-master/src/boardDef.h deleted file mode 100644 index 115a3a4..0000000 --- a/lib/TeensyTimerTool-master/src/boardDef.h +++ /dev/null @@ -1,67 +0,0 @@ -#pragma once -#include - -namespace TeensyTimerTool -{ - class ITimerChannel; - using TimerGenerator = ITimerChannel*(); //returns a pointer to a free timer channel or nullptr - - // TEENSYDUINO ========================================================================== - #if defined(TEENSYDUINO) - #if defined(ARDUINO_TEENSY40) || defined(ARDUINO_TEENSY41) || defined(ARDUINO_TEENSY_MICROMOD) - #define TTT_TEENSY4X - #elif defined(ARDUINO_TEENSY30) || defined(ARDUINO_TEENSY31) || defined(ARDUINO_TEENSY32) || defined(ARDUINO_TEENSY35) || defined(ARDUINO_TEENSY36) - #define TTT_TEENSY3X - #endif - - #if defined(ARDUINO_TEENSYLC) - extern TimerGenerator *const TCK; - - #elif defined(ARDUINO_TEENSY30) - extern TimerGenerator *const FTM0, * const FTM1; - extern TimerGenerator *const TCK, * const TCK32, * const TCK64; - - #elif defined(ARDUINO_TEENSY31) || defined(ARDUINO_TEENSY32) - extern TimerGenerator *const FTM0, * const FTM1, * const FTM2; - extern TimerGenerator *const TCK, * const TCK32, * const TCK64; - - - #elif defined(ARDUINO_TEENSY35) - extern TimerGenerator *const FTM0, * const FTM1, * const FTM2, * const FTM3, * const FTM4; - extern TimerGenerator *const TCK, * const TCK32, * const TCK64; - - #elif defined(ARDUINO_TEENSY36) - extern TimerGenerator *const FTM0, *const FTM1, *const FTM2, *const FTM3, *const FTM4; - extern TimerGenerator *const TCK, * const TCK32, * const TCK64; - - #elif defined(TTT_TEENSY4X) - extern TimerGenerator *const TMR1, *const TMR2, *const TMR3, *const TMR4; - extern TimerGenerator *const GPT1, *const GPT2; - extern TimerGenerator *const PIT; - extern TimerGenerator *const TCK, * const TCK32, * const TCK64, *const TCK_RTC; - - #else - #error BOARD NOT SUPPORTED - #endif - - #define YIELD_NONE 0 - #define YIELD_STANDARD 1 - #define YIELD_OPTIMIZED 2 - - constexpr int PSC_AUTO = -1; - constexpr int PSC_1 = 0; - constexpr int PSC_2 = 1; - constexpr int PSC_4 = 2; - constexpr int PSC_8 = 3; - constexpr int PSC_16 = 4; - constexpr int PSC_32 = 5; - constexpr int PSC_64 = 6; - constexpr int PSC_128 = 7; - - extern void(* const tick)(); - - - #else - # error "Board not supported" - #endif -} \ No newline at end of file diff --git a/lib/TeensyTimerTool-master/src/config.cpp b/lib/TeensyTimerTool-master/src/config.cpp deleted file mode 100644 index d7b47f3..0000000 --- a/lib/TeensyTimerTool-master/src/config.cpp +++ /dev/null @@ -1,88 +0,0 @@ -#include "config.h" -#include "TimerModules/TCK/TCK.h" -#include "TimerModules/TCK/tickCounters.h" -#include "boardDef.h" - -using tick_t = void (*)(); - -#if defined(ARDUINO_TEENSY40) || defined(ARDUINO_TEENSY41) || defined(ARDUINO_TEENSY_MICROMOD) -#include "TimerModules/GPT/GPT.h" -#include "TimerModules/PIT4/PIT.h" -#include "TimerModules/TMR/TMR.h" - -namespace TeensyTimerTool -{ - TimerGenerator *const TMR1 = TMR_t<0>::getTimer; - TimerGenerator *const TMR2 = TMR_t<1>::getTimer; - TimerGenerator *const TMR3 = TMR_t<2>::getTimer; - TimerGenerator *const TMR4 = TMR_t<3>::getTimer; - - TimerGenerator *const GPT1 = GPT_t<0>::getTimer; - TimerGenerator *const GPT2 = GPT_t<1>::getTimer; - - TimerGenerator *const PIT = PIT_t::getTimer; - - TimerGenerator *const TCK = TCK_t::getTimer; - TimerGenerator *const TCK32 = TCK_t::getTimer; // same as TCK - TimerGenerator *const TCK64 = TCK_t::getTimer; - TimerGenerator *const TCK_RTC = TCK_t::getTimer; - - constexpr tick_t tick = &TCK_t::tick; -} // namespace TeensyTimerTool - -#elif defined(ARDUINO_TEENSY35) || defined(ARDUINO_TEENSY36) -#include "TimerModules/FTM/FTM.h" - -namespace TeensyTimerTool -{ - TimerGenerator *const TCK = TCK_t::getTimer; - TimerGenerator *const TCK32 = TCK_t::getTimer; // same as TCK - TimerGenerator *const TCK64 = TCK_t::getTimer; - - TimerGenerator *const FTM0 = FTM_t<0>::getTimer; - TimerGenerator *const FTM1 = FTM_t<1>::getTimer; - TimerGenerator *const FTM2 = FTM_t<2>::getTimer; - TimerGenerator *const FTM3 = FTM_t<3>::getTimer; - TimerGenerator *const FTM4 = FTM_t<3>::getTimer; - - constexpr tick_t tick = &TCK_t::tick; -} // namespace TeensyTimerTool - -#elif defined(ARDUINO_TEENSY31) || defined(ARDUINO_TEENSY32) -#include "TimerModules/FTM/FTM.h" - -namespace TeensyTimerTool -{ - TimerGenerator *const TCK = TCK_t::getTimer; - TimerGenerator *const TCK32 = TCK_t::getTimer; // same as TCK - TimerGenerator *const TCK64 = TCK_t::getTimer; - - TimerGenerator *const FTM0 = FTM_t<0>::getTimer; - TimerGenerator *const FTM1 = FTM_t<1>::getTimer; - TimerGenerator *const FTM2 = FTM_t<2>::getTimer; - constexpr tick_t tick = &TCK_t::tick; -} // namespace TeensyTimerTool - -#elif defined(ARDUINO_TEENSY30) -#include "TimerModules/FTM/FTM.h" - -namespace TeensyTimerTool -{ - TimerGenerator *const TCK = TCK_t::getTimer; - TimerGenerator *const TCK32 = TCK_t::getTimer; // same as TCK - TimerGenerator *const TCK64 = TCK_t::getTimer; - - TimerGenerator *const FTM0 = FTM_t<0>::getTimer; - TimerGenerator *const FTM1 = FTM_t<1>::getTimer; - constexpr tick_t tick = &TCK_t::tick; -} // namespace TeensyTimerTool - -#elif defined(ARDUINO_TEENSYLC) - -namespace TeensyTimerTool -{ - TimerGenerator *const TCK = TCK_t::getTimer; - constexpr tick_t tick = &TCK_t::tick; -} // namespace TeensyTimerTool - -#endif diff --git a/lib/TeensyTimerTool-master/src/config.h b/lib/TeensyTimerTool-master/src/config.h deleted file mode 100644 index d74a5dd..0000000 --- a/lib/TeensyTimerTool-master/src/config.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -#if __has_include("userConfig.h") -#include "userConfig.h" -#else -#include "defaultConfig.h" -#endif diff --git a/lib/TeensyTimerTool-master/src/defaultConfig.h b/lib/TeensyTimerTool-master/src/defaultConfig.h deleted file mode 100644 index 917ce68..0000000 --- a/lib/TeensyTimerTool-master/src/defaultConfig.h +++ /dev/null @@ -1,92 +0,0 @@ -#pragma once - -#include "boardDef.h" -namespace TeensyTimerTool -{ -//-------------------------------------------------------------------------------------------- -// Timer pool defintion -// Add, and sort and remove to define the timer pool. Timers will be allocted from left to right - -#if defined(ARDUINO_TEENSY_MICROMOD) - TimerGenerator* const timerPool[] = {GPT1, GPT2, TMR1, TMR2, TMR3, TMR4, TCK}; - -#elif defined(ARDUINO_TEENSY40) - TimerGenerator* const timerPool[] = {GPT1, GPT2, TMR1, TMR2, TMR3, TMR4, TCK}; - -#elif defined(ARDUINO_TEENSY41) - TimerGenerator* const timerPool[] = {GPT1, GPT2, TMR1, TMR2, TMR3, TMR4, TCK}; - -#elif defined(ARDUINO_TEENSY36) - TimerGenerator* const timerPool[] = {FTM0, FTM1, FTM2, FTM3, FTM4, TCK}; - -#elif defined(ARDUINO_TEENSY35) - TimerGenerator* const timerPool[] = {FTM0, FTM1, FTM2, FTM3, TCK}; - -#elif defined(ARDUINO_TEENSY31) || defined(ARDUINO_TEENSY32) - TimerGenerator* const timerPool[] = {FTM0, FTM1, FTM2, TCK}; - -#elif defined(ARDUINO_TEENSY30) - TimerGenerator* const timerPool[] = {FTM0, FTM1, TCK}; - -#elif defined(ARDUINO_TEENSYLC) - TimerGenerator* const timerPool[] = {TCK}; - -#elif defined(ESP32) - TimerGenerator* const timerPool[] = {TCK}; - -#elif defined(UNO) - TimerGenerator* const timerPool[] = {TCK}; -#endif - constexpr unsigned timerCnt = sizeof(timerPool) / sizeof(timerPool[0]); - -//-------------------------------------------------------------------------------------------- -// Default settings for various timers - -// TMR (QUAD) - constexpr int TMR_DEFAULT_PSC = PSC_128; // Allowed prescaling values: PSC_1, PSC_2, PSC_4 ... PSC_128, clock = 150MHz - -// FTM - constexpr int FTM_DEFAULT_PSC[] = // Allowed prescaling values: PSC_AUTO, PSC_1, PSC_2, PSC_4 ... PSC_128, clock = FBUS - { // (PSC_AUTO adjusts prescaler to get roughly 2 timer ticks per µs) - /*FTM0*/ PSC_AUTO, - /*FTM1*/ PSC_AUTO, - /*FTM2*/ PSC_AUTO, - /*FTM3*/ PSC_AUTO - }; - - -// GPT & PID - constexpr bool USE_GPT_PIT_150MHz = false;// changes the clock source for GPT and PIT from 24MHz (standard) to 150MHz, might have side effects! - -// TCK - constexpr unsigned NR_OF_TCK_TIMERS = 20; // How many TCK timers shall be available - - #define YIELD_TYPE YIELD_STANDARD // Select the required yield strategy from the list below - // YIELD_NONE: lib doesn't touch yield. Make sure to call TeensyTimerTool::tick as often as possible - // YIELD_STANDARD: uses the standard yield function and adds a call to TeensyTimerTool::tick(). Lots of overhead in yield... - // YIELD_OPTIMIZED: generate an optimized yield which only calls TeensyTimerTool::Tick() (recommended if you don't use SerialEvents) - - - - -//-------------------------------------------------------------------------------------------- -// Callback type -// Uncomment if you prefer function pointer callbacks instead of std::function callbacks - -// #define PLAIN_VANILLA_CALLBACKS - - -//-------------------------------------------------------------------------------------------- -// Use c++14 time literals (e.g. 3.4s, 50ms, _kHz...) for time inputs. Periods without literals are -// interpreted as microseconds. -// Comment the following line if you don't want this. - - #define USE_TIME_LITERALS - - -//-------------------------------------------------------------------------------------------- -// Advanced Features -// Uncomment if you need access to advanced features - -// #define ENABLE_ADVANCED_FEATURES -} \ No newline at end of file diff --git a/lib/TeensyTimerTool-master/src/frequency.h.deactivated b/lib/TeensyTimerTool-master/src/frequency.h.deactivated deleted file mode 100644 index 832056c..0000000 --- a/lib/TeensyTimerTool-master/src/frequency.h.deactivated +++ /dev/null @@ -1,406 +0,0 @@ -// -*- C++ -*- - -// Copyright (C) 2008-2015 Free Software Foundation, Inc. -// -// This file is part of the GNU ISO C++ Library. This library is free -// software; you can redistribute it and/or modify it under the -// terms of the GNU General Public License as published by the -// Free Software Foundation; either version 3, or (at your option) -// any later version. - -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// Under Section 7 of GPL version 3, you are granted additional -// permissions described in the GCC Runtime Library Exception, version -// 3.1, as published by the Free Software Foundation. - -// You should have received a copy of the GNU General Public License and -// a copy of the GCC Runtime Library Exception along with this program; -// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -// . - -#pragma once - -#include -#include -#include -#include - -using std::common_type; -using std::enable_if; -using std::is_convertible; -using std::ratio; -using std::ratio_divide; - -namespace TeensyTimerTool -{ - template > - struct frequency; - - template - struct __frequency_common_type_wrapper - { - private: - typedef std::__static_gcd<_Period1::num, _Period2::num> __gcd_num; - typedef std::__static_gcd<_Period1::den, _Period2::den> __gcd_den; - typedef typename _CT::type __cr; - typedef ratio<__gcd_num::value, - (_Period1::den / __gcd_den::value) * _Period2::den> - __r; - - public: - typedef std::__success_type> type; - }; - - template - struct __frequency_common_type_wrapper - { - typedef std::__failure_type type; - }; -} - -namespace std -{ - template - struct common_type, TeensyTimerTool::frequency<_Rep2, _Period2>> - : public TeensyTimerTool::__frequency_common_type_wrapper>::type, _Period1, _Period2>::type - { - }; -} - -namespace TeensyTimerTool -{ - using namespace std::chrono; - - // Primary template for frequency_cast impl. - template - struct __frequency_cast_impl - { - template - static constexpr _ToDur - __cast(const frequency<_Rep, _Period>& __d) - { - typedef typename _ToDur::rep __to_rep; - return _ToDur(static_cast<__to_rep>(static_cast<_CR>(__d.count()) * static_cast<_CR>(_CF::num) / static_cast<_CR>(_CF::den))); - } - }; - - template - struct __frequency_cast_impl<_ToDur, _CF, _CR, true, true> - { - template - static constexpr _ToDur - __cast(const frequency<_Rep, _Period>& __d) - { - typedef typename _ToDur::rep __to_rep; - return _ToDur(static_cast<__to_rep>(__d.count())); - } - }; - - template - struct __frequency_cast_impl<_ToDur, _CF, _CR, true, false> - { - template - static constexpr _ToDur - __cast(const frequency<_Rep, _Period>& __d) - { - typedef typename _ToDur::rep __to_rep; - return _ToDur(static_cast<__to_rep>( - static_cast<_CR>(__d.count()) / static_cast<_CR>(_CF::den))); - } - }; - - template - struct __frequency_cast_impl<_ToDur, _CF, _CR, false, true> - { - template - static constexpr _ToDur - __cast(const frequency<_Rep, _Period>& __d) - { - typedef typename _ToDur::rep __to_rep; - return _ToDur(static_cast<__to_rep>( - static_cast<_CR>(__d.count()) * static_cast<_CR>(_CF::num))); - } - }; - - template - struct __is_frequency - : std::false_type - { - }; - - template - struct __is_frequency> - : std::true_type - { - }; - - /// duration_cast - template - constexpr typename enable_if<__is_frequency<_ToDur>::value, _ToDur>::type duration_cast(const frequency<_Rep, _Period>& __d) - { - typedef typename _ToDur::period __to_period; - typedef typename _ToDur::rep __to_rep; - typedef ratio_divide<_Period, __to_period> __cf; - typedef typename common_type<__to_rep, _Rep, intmax_t>::type __cr; - typedef __frequency_cast_impl<_ToDur, __cf, __cr, __cf::num == 1, __cf::den == 1> __dc; - - return __dc::__cast(__d); - } - - /// frequency - template - struct frequency - { - typedef _Rep rep; - typedef _Period period; - - static_assert(!__is_frequency<_Rep>::value, "rep cannot be a frequency"); - static_assert(std::chrono::__is_ratio<_Period>::value, "period must be a specialization of ratio"); - static_assert(_Period::num > 0, "period must be positive"); - - // 20.11.5.1 construction / copy / destroy - constexpr frequency() = default; - - // NB: Make constexpr implicit. This cannot be explicitly - // constexpr, as any UDT that is not a literal type with a - // constexpr copy constructor will be ill-formed. - frequency(const frequency&) = default; - - template ::value && (std::chrono::treat_as_floating_point::value || !std::chrono::treat_as_floating_point<_Rep2>::value)>::type> - constexpr explicit frequency(const _Rep2& __rep) - : __r(static_cast(__rep)) - { - } - - template ::value || (ratio_divide<_Period2, period>::den == 1 && !treat_as_floating_point<_Rep2>::value)>::type> - constexpr frequency(const frequency<_Rep2, _Period2>& __d) - : __r(duration_cast(__d).count()) {} - - ~frequency() = default; - frequency& operator=(const frequency&) = default; - - // 20.11.5.2 observer - constexpr rep count() const { return __r; } - - constexpr frequency operator+() const { return *this; } - constexpr frequency operator-() const { return frequency(-__r); } - - frequency& operator++() - { - ++__r; - return *this; - } - - frequency operator++(int) - { - return frequency(__r++); - } - - frequency& operator--() - { - --__r; - return *this; - } - - frequency - operator--(int) - { - return frequency(__r--); - } - - frequency& - operator+=(const frequency& __d) - { - __r += __d.count(); - return *this; - } - - frequency& - operator-=(const frequency& __d) - { - __r -= __d.count(); - return *this; - } - - frequency& - operator*=(const rep& __rhs) - { - __r *= __rhs; - return *this; - } - - frequency& - operator/=(const rep& __rhs) - { - __r /= __rhs; - return *this; - } - - // DR 934. - template - typename enable_if::value, - frequency&>::type - operator%=(const rep& __rhs) - { - __r %= __rhs; - return *this; - } - - template - typename enable_if::value, - frequency&>::type - operator%=(const frequency& __d) - { - __r %= __d.count(); - return *this; - } - - // 20.11.5.4 special values - static constexpr frequency - zero() - { - return frequency(duration_values::zero()); - } - - static constexpr frequency - min() - { - return frequency(duration_values::min()); - } - - static constexpr frequency - max() - { - return frequency(duration_values::max()); - } - - private: - rep __r; - }; - - template - constexpr typename common_type, frequency<_Rep2, _Period2>>::type operator+(const frequency<_Rep1, _Period1>& __lhs, const frequency<_Rep2, _Period2>& __rhs) - { - typedef frequency<_Rep1, _Period1> __dur1; - typedef frequency<_Rep2, _Period2> __dur2; - typedef typename common_type<__dur1, __dur2>::type __cd; - return __cd(__cd(__lhs).count() + __cd(__rhs).count()); - } - - template - constexpr typename common_type, frequency<_Rep2, _Period2>>::type operator-(const frequency<_Rep1, _Period1>& __lhs, const frequency<_Rep2, _Period2>& __rhs) - { - typedef frequency<_Rep1, _Period1> __dur1; - typedef frequency<_Rep2, _Period2> __dur2; - typedef typename common_type<__dur1, __dur2>::type __cd; - return __cd(__cd(__lhs).count() - __cd(__rhs).count()); - } - - template - constexpr frequency::type, _Period> operator*(const frequency<_Rep1, _Period>& __d, const _Rep2& __s) - { - typedef frequency::type, _Period> __cd; - return __cd(__cd(__d).count() * __s); - } - - template - constexpr frequency::type, _Period> operator*(const _Rep1& __s, const frequency<_Rep2, _Period>& __d) - { - return __d * __s; - } - - template - constexpr frequency::value, _Rep2>::type>::type, _Period> operator/(const frequency<_Rep1, _Period>& __d, const _Rep2& __s) - { - typedef frequency::type, _Period> __cd; - return __cd(__cd(__d).count() / __s); - } - - template - constexpr typename common_type<_Rep1, _Rep2>::type operator/(const frequency<_Rep1, _Period1>& __lhs, const frequency<_Rep2, _Period2>& __rhs) - { - typedef frequency<_Rep1, _Period1> __dur1; - typedef frequency<_Rep2, _Period2> __dur2; - typedef typename common_type<__dur1, __dur2>::type __cd; - return __cd(__lhs).count() / __cd(__rhs).count(); - } - - // DR 934. - template - constexpr frequency::value, _Rep2>::type>::type, _Period> operator%(const frequency<_Rep1, _Period>& __d, const _Rep2& __s) - { - typedef frequency::type, _Period> __cd; - return __cd(__cd(__d).count() % __s); - } - - template - constexpr typename common_type, frequency<_Rep2, _Period2>>::type operator%(const frequency<_Rep1, _Period1>& __lhs, const frequency<_Rep2, _Period2>& __rhs) - { - typedef frequency<_Rep1, _Period1> __dur1; - typedef frequency<_Rep2, _Period2> __dur2; - typedef typename common_type<__dur1, __dur2>::type __cd; - return __cd(__cd(__lhs).count() % __cd(__rhs).count()); - } - - // comparisons - template - constexpr bool operator==(const frequency<_Rep1, _Period1>& __lhs, const frequency<_Rep2, _Period2>& __rhs) - { - typedef frequency<_Rep1, _Period1> __dur1; - typedef frequency<_Rep2, _Period2> __dur2; - typedef typename common_type<__dur1, __dur2>::type __ct; - return __ct(__lhs).count() == __ct(__rhs).count(); - } - - template - constexpr bool operator<(const frequency<_Rep1, _Period1>& __lhs, const frequency<_Rep2, _Period2>& __rhs) - { - typedef frequency<_Rep1, _Period1> __dur1; - typedef frequency<_Rep2, _Period2> __dur2; - typedef typename common_type<__dur1, __dur2>::type __ct; - return __ct(__lhs).count() < __ct(__rhs).count(); - } - - template - constexpr bool operator!=(const frequency<_Rep1, _Period1>& __lhs, const frequency<_Rep2, _Period2>& __rhs) - { - return !(__lhs == __rhs); - } - - template - constexpr bool operator<=(const frequency<_Rep1, _Period1>& __lhs, const frequency<_Rep2, _Period2>& __rhs) - { - return !(__rhs < __lhs); - } - - template - constexpr bool operator>(const frequency<_Rep1, _Period1>& __lhs, const frequency<_Rep2, _Period2>& __rhs) - { - return __rhs < __lhs; - } - - template - constexpr bool operator>=(const frequency<_Rep1, _Period1>& __lhs, const frequency<_Rep2, _Period2>& __rhs) - { - return !(__lhs < __rhs); - } - - using hertz = frequency; - using kilohertz = frequency; - using megahertz = frequency; - using gigahertz = frequency; - - constexpr hertz operator""_Hz(long double hz) { return hertz{hz}; } - constexpr hertz operator""_Hz(uint64_t hz) { return hertz{hz}; } - constexpr kilohertz operator""_kHz(long double kHz) { return kilohertz{kHz}; } - constexpr kilohertz operator""_kHz(uint64_t kHz) { return kilohertz{kHz}; } - constexpr megahertz operator""_MHz(long double MHz) { return megahertz{MHz}; } - constexpr megahertz operator""_MHz(uint64_t MHz) { return megahertz{MHz}; } - constexpr gigahertz operator""_GHz(long double GHz) { return gigahertz{GHz}; } - constexpr gigahertz operator""_GHz(uint64_t GHz) { return gigahertz{GHz}; } -} diff --git a/lib/TeensyTimerTool-master/src/helpers.h b/lib/TeensyTimerTool-master/src/helpers.h deleted file mode 100644 index 1a8a90f..0000000 --- a/lib/TeensyTimerTool-master/src/helpers.h +++ /dev/null @@ -1,36 +0,0 @@ -#pragma once - -#include "config.h" -#include - -#if defined(USE_TIME_LITERALS) -#include -#endif - -namespace TeensyTimerTool -{ - //-------------------------------------------------------------- - // Transform arithmetic, period and frequency values to float - // For constant inputs the transformations are calculated at compile time - - // Arithmetic types - template ::value, int> * = nullptr> - float constexpr period2us(period_t v) - { - return (float)v; - } - -#if defined(USE_TIME_LITERALS) - - // Duration types (s, ms, ns...) - template ::value, int> * = nullptr> - float constexpr period2us(period_t v) - { - using namespace std::chrono; - return (duration_cast>(v).count()); - } - - -#endif - -} // namespace TeensyTimerTool \ No newline at end of file diff --git a/lib/TeensyTimerTool-master/src/staticFunctional.h b/lib/TeensyTimerTool-master/src/staticFunctional.h deleted file mode 100644 index ac407de..0000000 --- a/lib/TeensyTimerTool-master/src/staticFunctional.h +++ /dev/null @@ -1,292 +0,0 @@ -/** - * Based on code found here: - * https://www.c-plusplus.net/forum/topic/344451/std-function-und-std-bind-durch-einfachere-eigene-variante-ersetzen-signal-slot/17 - * - **/ - -// as usual, Arduino macros clash with the standard library -#pragma push_macro("F") -#undef F -#pragma push_macro("min") -#undef min -#pragma push_macro("max") -#undef max - -#include -#include - -namespace staticFunctional -{ - -// we need to supply some utilities for toolchains < c++17 -#if (__cplusplus <= 201402L) - - // std::launder ================================================== - template - [[nodiscard]] constexpr _Tp* - launder(_Tp* __p) noexcept - { - return __builtin_launder(__p); - } - - // The program is ill-formed if T is a function type or - // (possibly cv-qualified) void. - template - void launder(_Ret (*)(_Args...)) = delete; - - template - void launder(_Ret (*)(_Args......)) = delete; - - void launder(void*) = delete; - void launder(const void*) = delete; - void launder(volatile void*) = delete; - void launder(const volatile void*) = delete; - - // invoke_result_t ================================================== - template - using invoke_result_t = typename std::__invoke_result::type; - - // decay_t ========================================================== - template - using decay_t = typename std::decay::type; - -#else // resort to the standard versions for >= c++17 - using std::decay_t; - using std::invoke_result_t; - using std::launder; -#endif - - template - class function; - - template - class function - { - struct InvokerBase - { - virtual R operator()(void const*, Args...) const = 0; - virtual void destroy(void*) = 0; - virtual void copy(void const*, void*, void*) const = 0; - virtual void move(void*, void*, void*) const = 0; - }; - - template - struct Invoker : InvokerBase - { - static_assert(sizeof(F) <= N, "memory error"); - - R operator()(void const* p, Args... args) const override - { - return (*(F const*)p)(std::forward(args)...); - } - void destroy(void* p) override - { - launder((F*)p)->~F(); - } - void copy(void const* s, void* d, void* invoker_d) const override - { - new (d) F(*launder((F const*)s)); - new (invoker_d) Invoker; - } - void move(void* s, void* d, void* invoker_d) const override - { - new (d) F(std::move(*launder((F*)s))); - new (invoker_d) Invoker; - } - }; - - typename std::aligned_storage::type _storage; - typename std::aligned_storage), alignof(Invoker)>::type _invoker_storage; - - InvokerBase const& _invoker_base() const noexcept - { - return *launder((InvokerBase*)&_invoker_storage); - } - InvokerBase& _invoker_base() noexcept - { - return *launder((InvokerBase*)&_invoker_storage); - } - bool _empty = true; - - void _clear() - { - if (!empty()) - { - _invoker_base().destroy(&_storage); - _empty = true; - } - } - - template - struct _is_callable - { - // static const bool value = std::is_convertible, Args...>, R>::value; - static const bool value = true; // hack, need to fix that... - }; - - template - struct _participate - { - static const bool value = _is_callable>::value && !std::is_same, function>::value; - }; - - template - struct _is_function_spec : std::false_type - { - }; - template - struct _is_function_spec> : std::true_type - { - }; - - // template - // void _emplace(F f) - // { - // using T = decay_t; - // if constexpr (std::is_pointer::value || std::is_member_function_pointer::value || _is_function_spec{}) - // if (!f) - // return; - - // static_assert(sizeof(Invoker) <= sizeof(_invoker_storage), "Memory"); - // new (&_storage) F(std::move(f)); - // new (&_invoker_storage) Invoker; - // _empty = false; - // } - // .................................................................................... - // original _emplace uses "constexpr if" which does not exist in c++11 -> replace by SFINAE version - - template - typename std::enable_if>::value || std::is_member_function_pointer>::value || _is_function_spec>{}, void>::type - _emplace(F f) - { - if (!f) return; - - static_assert(sizeof(Invoker) <= sizeof(_invoker_storage), "Memory"); - new (&_storage) F(std::move(f)); - new (&_invoker_storage) Invoker; - _empty = false; - } - - template - typename std::enable_if>::value || std::is_member_function_pointer>::value || _is_function_spec>{}), void>::type - _emplace(F f) - { - static_assert(sizeof(Invoker) <= sizeof(_invoker_storage), "Memory"); - new (&_storage) F(std::move(f)); - new (&_invoker_storage) Invoker; - _empty = false; - } - - public: - using result_type = R; - - function() noexcept = default; - function(std::nullptr_t) noexcept {} - - function(function&& other) : _empty(other.empty()) - { - if (!empty()) - other._invoker_base().move(&other._storage, &_storage, &_invoker_storage); - } - - function(function const& other) : _empty(other.empty()) - { - if (!empty()) - other._invoker_base().copy(&other._storage, &_storage, &_invoker_storage); - } - - template ::value>::type> - function(F&& f) : _empty(false) - { - _emplace(std::forward(f)); - } - - ~function() - { - _clear(); - } - - bool empty() const noexcept { return _empty; } - operator bool() const noexcept { return !empty(); } - - function& operator=(function const& other) - { - _clear(); - _empty = other.empty(); - if (!empty()) - other._invoker_base().copy(&other._storage, &_storage, &_invoker_storage); - return *this; - } - - function& operator=(function&& other) - { - _clear(); - _empty = other.empty(); - if (!empty()) - other._invoker_base().move(&other._storage, &_storage, &_invoker_storage); - return *this; - } - - function& operator=(std::nullptr_t) - { - _clear(); - return *this; - } - - template ::value>::type> - function& operator=(F&& f) - { - _clear(); - _emplace(std::forward(f)); - return *this; - } - - template - function& operator=(std::reference_wrapper f) - { - _clear(); - _emplace(f.get()); - return *this; - } - - void swap(function& other) - { - std::swap(*this, other); // Best that can be done. - } - - R operator()(Args... args) const - { - return _invoker_base()(&_storage, std::forward(args)...); - } - }; - - template - bool operator==(function const& f, std::nullptr_t) noexcept - { - return !f; - } - template - bool operator==(std::nullptr_t, function const& f) noexcept - { - return !f; - } - template - bool operator!=(function const& f, std::nullptr_t) noexcept - { - return f; - } - template - bool operator!=(std::nullptr_t, function const& f) noexcept - { - return f; - } - - template - void swap(function& lhs, function& rhs) - { - lhs.swap(rhs); - } -} -#pragma pop_macro("max") -#pragma pop_macro("min") -#pragma pop_macro("F") diff --git a/lib/TeensyTimerTool-master/src/types.h b/lib/TeensyTimerTool-master/src/types.h deleted file mode 100644 index 3ca9426..0000000 --- a/lib/TeensyTimerTool-master/src/types.h +++ /dev/null @@ -1,37 +0,0 @@ -#pragma once -#include "Arduino.h" -#include "ErrorHandling/error_codes.h" -#include "config.h" - -// we can not use staticFunctional with too old compilers -#if not defined(PLAIN_VANILLA_CALLBACKS) - #if (__GNUC__ < 7) - #warning "can't use staticFunctional with GCC < V7! Fallback to function pointer callbacks" - #else - #define USE_MODERN_CALLBACKS - #include "staticFunctional.h" - #endif -#endif -namespace TeensyTimerTool -{ - #if defined(USE_MODERN_CALLBACKS) - using staticFunctional::function; - using callback_t = function; - using errorFunc_t = function; - - extern void attachErrFunc(errorFunc_t); - extern errorCode postError(errorCode); - #else - using callback_t = void (*)(); - using errorFunc_t = void (*)(errorCode); - - extern void attachErrFunc(errorFunc_t); - extern errorCode postError(errorCode); - #endif - - #if defined(TTT_TEENSY4X) - #define TTT_F_CPU F_CPU_ACTUAL - #else - #define TTT_F_CPU F_CPU - #endif -} // namespace TeensyTimerTool \ No newline at end of file diff --git a/lib/TeensyTimerTool-master/test/main.cpp b/lib/TeensyTimerTool-master/test/main.cpp deleted file mode 100644 index 1a145de..0000000 --- a/lib/TeensyTimerTool-master/test/main.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include "Arduino.h" - -// General ============================================================================================= -//#include "../lib/TeensyTimerTool/examples/01_Basic/HelloPeriodic/HelloPeriodic.ino" -//#include "../lib/TeensyTimerTool/examples/01_Basic/HelloOneShot/HelloOneShot.ino" -//#include "../lib/TeensyTimerTool/examples/01_Basic/UsingChronoDurations1/UsingChronoDurations1.ino" -//#include "../lib/TeensyTimerTool/examples/01_Basic/UsingChronoDurations2/UsingChronoDurations2.ino" -//#include "../lib/TeensyTimerTool/examples/02_Advanced/CallbackWithParams/CallbackWithParams.ino" -//#include "../lib/TeensyTimerTool/examples/02_Advanced/UsingLambdas/UsingLambdas.ino" - -//T3.x ================================================================================================ -//#include "../lib/TeensyTimerTool/examples/03_Applications/DoubleExposure/DoubleExposure.ino" - -//T4.x ================================================================================================ -//#include "../lib/TeensyTimerTool/examples/01_Basic/MoreTimers/MoreTimers.ino" -//#include "../lib/TeensyTimerTool/examples/01_Basic/RTC_Timer/RTC_Timer.ino" -//#include "../lib/TeensyTimerTool/examples/99_Misc/PinInformation/PinInformation.ino" diff --git a/lib/teensyshot-master/.gitignore b/lib/teensyshot-master/.gitignore deleted file mode 100644 index d8a6a12..0000000 --- a/lib/teensyshot-master/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ - -.DS_Store -host/host diff --git a/lib/teensyshot-master/Arda/dma_v1.ino b/lib/teensyshot-master/Arda/dma_v1.ino deleted file mode 100644 index 68f00fa..0000000 --- a/lib/teensyshot-master/Arda/dma_v1.ino +++ /dev/null @@ -1,178 +0,0 @@ -#include "DMAChannel.h" -#include - -IntervalTimer timer; - -DMAChannel dma; -DMAChannel dma2; -DMAChannel dma3; -DMAChannel dma4; -DMAChannel dma5; -DMAChannel dma6; - -const uint16_t short_pulse = uint64_t(F_BUS) * 625 / 1000000000; -const uint16_t long_pulse = uint64_t(F_BUS) * 1250 / 1000000000; -const uint16_t bit_length = uint64_t(F_BUS) * 1670 / 1000000000; - -std::array dma_source = { - short_pulse, long_pulse, - short_pulse, long_pulse, - short_pulse, long_pulse, - short_pulse, long_pulse, - short_pulse, long_pulse, - short_pulse, long_pulse, - short_pulse, long_pulse, - short_pulse, long_pulse, - 0, 0 -}; - -std::array dma_source2 = { - short_pulse, long_pulse, - short_pulse, long_pulse, - short_pulse, long_pulse, - short_pulse, long_pulse, - short_pulse, long_pulse, - short_pulse, long_pulse, - short_pulse, long_pulse, - short_pulse, long_pulse, - 0, 0 -}; - -std::array dma_source3 = { - short_pulse, long_pulse, - short_pulse, long_pulse, - short_pulse, long_pulse, - short_pulse, long_pulse, - short_pulse, long_pulse, - short_pulse, long_pulse, - short_pulse, long_pulse, - short_pulse, long_pulse, - 0, 0 -}; - -std::array dma_source4 = { - short_pulse, long_pulse, - short_pulse, long_pulse, - short_pulse, long_pulse, - short_pulse, long_pulse, - short_pulse, long_pulse, - short_pulse, long_pulse, - short_pulse, long_pulse, - short_pulse, long_pulse, - 0, 0 -}; - -std::array dma_source5 = { - short_pulse, long_pulse, - short_pulse, long_pulse, - short_pulse, long_pulse, - short_pulse, long_pulse, - short_pulse, long_pulse, - short_pulse, long_pulse, - short_pulse, long_pulse, - short_pulse, long_pulse, - 0, 0 -}; - -std::array dma_source6 = { - short_pulse, long_pulse, - short_pulse, long_pulse, - short_pulse, long_pulse, - short_pulse, long_pulse, - short_pulse, long_pulse, - short_pulse, long_pulse, - short_pulse, long_pulse, - short_pulse, long_pulse, - 0, 0 -}; - -void myISR() { - dma.clearInterrupt(); - FTM0_SC = 0; // disable FTM0 -} - -void setup() { - setupDMA(); - - timer.begin(myFunc, 200); - - // FTM0_SC = FTM_SC_CLKS(1); // enable timer with busclock -} - -void loop() { -} - -void myFunc() { - FTM0_SC = FTM_SC_CLKS(1); -} - - -void setupDMA() { - CORE_PIN22_CONFIG = PORT_PCR_MUX(4) | PORT_PCR_DSE | PORT_PCR_SRE; // FTM0_CH0 - CORE_PIN23_CONFIG = PORT_PCR_MUX(4) | PORT_PCR_DSE | PORT_PCR_SRE; // FTM0_CH1 - CORE_PIN9_CONFIG = PORT_PCR_MUX(4) | PORT_PCR_DSE | PORT_PCR_SRE; // FTM0_CH2 - CORE_PIN10_CONFIG = PORT_PCR_MUX(4) | PORT_PCR_DSE | PORT_PCR_SRE; // FTM0_CH3 - CORE_PIN6_CONFIG = PORT_PCR_MUX(4) | PORT_PCR_DSE | PORT_PCR_SRE; // FTM0_CH4 - CORE_PIN20_CONFIG = PORT_PCR_MUX(4) | PORT_PCR_DSE | PORT_PCR_SRE; // FTM0_CH5 - - // CORE_PIN5_CONFIG = PORT_PCR_MUX(4) | PORT_PCR_DSE | PORT_PCR_SRE; - - dma.sourceBuffer(dma_source.data(), sizeof(dma_source)); - dma.destination((uint16_t&) FTM0_C0V); - dma.triggerAtHardwareEvent(DMAMUX_SOURCE_FTM0_CH7); - dma.interruptAtCompletion(); - dma.attachInterrupt(myISR); - dma.enable(); - - dma2.sourceBuffer(dma_source2.data(), sizeof(dma_source2)); - dma2.destination((uint16_t&) FTM0_C1V); - dma2.triggerAtTransfersOf(dma); - dma2.triggerAtCompletionOf(dma); - dma2.enable(); - - dma3.sourceBuffer(dma_source3.data(), sizeof(dma_source3)); - dma3.destination((uint16_t&) FTM0_C2V); - dma3.triggerAtTransfersOf(dma2); - dma3.triggerAtCompletionOf(dma2); - dma3.enable(); - - dma4.sourceBuffer(dma_source4.data(), sizeof(dma_source4)); - dma4.destination((uint16_t&) FTM0_C3V); - dma4.triggerAtTransfersOf(dma3); - dma4.triggerAtCompletionOf(dma3); - dma4.enable(); - - dma5.sourceBuffer(dma_source5.data(), sizeof(dma_source5)); - dma5.destination((uint16_t&) FTM0_C4V); - dma5.triggerAtTransfersOf(dma4); - dma5.triggerAtCompletionOf(dma4); - dma5.enable(); - - dma6.sourceBuffer(dma_source6.data(), sizeof(dma_source6)); - dma6.destination((uint16_t&) FTM0_C5V); - dma6.triggerAtTransfersOf(dma5); - dma6.triggerAtCompletionOf(dma5); - dma6.enable(); - - FTM0_C0SC = FTM_CSC_MSB | FTM_CSC_ELSB | FTM_CSC_CHIE; - FTM0_C0V = 0; - FTM0_C1SC = FTM_CSC_MSB | FTM_CSC_ELSB | FTM_CSC_CHIE; - FTM0_C1V = 0; - FTM0_C2SC = FTM_CSC_MSB | FTM_CSC_ELSB | FTM_CSC_CHIE; - FTM0_C2V = 0; - FTM0_C3SC = FTM_CSC_MSB | FTM_CSC_ELSB | FTM_CSC_CHIE; - FTM0_C3V = 0; - FTM0_C4SC = FTM_CSC_MSB | FTM_CSC_ELSB | FTM_CSC_CHIE; - FTM0_C4V = 0; - FTM0_C5SC = FTM_CSC_MSB | FTM_CSC_ELSB | FTM_CSC_CHIE; - FTM0_C5V = 0; - - FTM0_C7SC = FTM_CSC_CHIE | FTM_CSC_DMA | FTM_CSC_MSA | FTM_CSC_ELSA; // output compare, enable DMA trigger - FTM0_C7V = 0; - - - FTM0_SC = 0; // disable FTM0 - FTM0_CNT = 0; // contains the FTM counter value - FTM0_MOD = bit_length; // the modulo value for the FTM counter - FTM0_CNTIN = 0; // counter initial value -} diff --git a/lib/teensyshot-master/Arda/dshot_simple_api/.gitignore b/lib/teensyshot-master/Arda/dshot_simple_api/.gitignore deleted file mode 100644 index f152028..0000000 --- a/lib/teensyshot-master/Arda/dshot_simple_api/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -.pio -.pioenvs -.piolibdeps -.clang_complete -.gcc-flags.json diff --git a/lib/teensyshot-master/Arda/dshot_simple_api/include/dshot_api.h b/lib/teensyshot-master/Arda/dshot_simple_api/include/dshot_api.h deleted file mode 100644 index b295dad..0000000 --- a/lib/teensyshot-master/Arda/dshot_simple_api/include/dshot_api.h +++ /dev/null @@ -1,56 +0,0 @@ -#ifndef DHOT_API_H -#define DHOT_API_H - -#include -#include "DMAChannel.h" - -#define DSHOT_FREQ 500 - -#define TLM_LENGTH 10 -#define DSHOT_LENGTH 16 -#define DMA_LENGTH 18 - -//const uint16_t SP = uint64_t(F_BUS) * 625 / 1000000000; //short pulse -//const uint16_t LP = uint64_t(F_BUS) * 1250 / 1000000000; // long pulse -//const uint16_t BIT_LENGTH = uint64_t(F_BUS) * 1670 / 1000000000; -// F_BUS is 60MHz -#define SP 37 -#define LP 75 -#define BIT_LENGTH 100 - -#define DEFAULT_MODE 0 -#define ARMING_MODE 1 -#define SEND_COMMAND_MODE 2 -#define STOP_MODE 3 - -struct TlmData { - uint8_t temperature; - uint16_t voltage; - uint16_t current; - uint16_t consumption; - uint16_t rpm; - bool crcCheck; -}; - -void readTlm(); -uint16_t getRpm(); -void startDshot(); -bool isTlmAvailable(); -void resetTlmFlag(); -void armingMotor(); -void enable3d(); -void disable3d(); -void setControlLoopFrequency(uint16_t freq); -void enableTlm(); -void disableTlm(); -void setThrottle(uint16_t newThrottle); -void stopMotor(); - -void sendDshot(); -void ISR_timer(); -void ISR_DMA(); -void setupDMA(); -uint8_t updateCrc8(uint8_t crc, uint8_t crc_seed); -uint8_t calculateCrc8(const uint8_t *Buf, const uint8_t BufLen); - -#endif diff --git a/lib/teensyshot-master/Arda/dshot_simple_api/platformio.ini b/lib/teensyshot-master/Arda/dshot_simple_api/platformio.ini deleted file mode 100644 index ae5443d..0000000 --- a/lib/teensyshot-master/Arda/dshot_simple_api/platformio.ini +++ /dev/null @@ -1,14 +0,0 @@ -; PlatformIO Project Configuration File -; -; Build options: build flags, source filter -; Upload options: custom upload port, speed and extra flags -; Library options: dependencies, extra library storages -; Advanced options: extra scripting -; -; Please visit documentation for the other options and examples -; https://docs.platformio.org/page/projectconf.html - -[env:teensy35] -platform = teensy -board = teensy35 -framework = arduino diff --git a/lib/teensyshot-master/Arda/dshot_simple_api/src/dshot_api.cpp b/lib/teensyshot-master/Arda/dshot_simple_api/src/dshot_api.cpp deleted file mode 100644 index 56f7d4d..0000000 --- a/lib/teensyshot-master/Arda/dshot_simple_api/src/dshot_api.cpp +++ /dev/null @@ -1,244 +0,0 @@ -#include -#include "dshot_api.h" - -DMAChannel dma; -volatile uint16_t dma_source[DMA_LENGTH]; -volatile uint16_t dataToSend; - - -volatile bool flagTlm = false; -volatile bool requestTlm = false; -volatile uint16_t throttle; - -volatile uint8_t mode = DEFAULT_MODE; - -volatile long counter = 0; -volatile bool armed = false; -volatile bool commandSent = false; - -IntervalTimer timer; - -struct TlmData tlmData; - -void readTlm() { - noInterrupts(); - if (isTlmAvailable()) { - resetTlmFlag(); - interrupts(); - static uint8_t bufferTlm[TLM_LENGTH]; - while (Serial1.available() < TLM_LENGTH); - // noInterrupts(); - for (int i = 0; i < TLM_LENGTH; i++) { - bufferTlm[i] = Serial1.read(); - } - tlmData.temperature = bufferTlm[0]; - tlmData.voltage = (bufferTlm[1] << 8) | bufferTlm[2]; - tlmData.current = (bufferTlm[3] << 8) | bufferTlm[4]; - tlmData.consumption = (bufferTlm[5] << 8) | bufferTlm[6]; - tlmData.rpm = (bufferTlm[7] << 8) | bufferTlm[8]; - tlmData.crcCheck = bufferTlm[9] == calculateCrc8(bufferTlm, TLM_LENGTH-1); - - /* TODO: stat for crcError */ - if (tlmData.crcCheck) { - /* no error */ - } else { - /* crc error */ - } - /*for (int i = 0; i < TLM_LENGTH; i++) { // for debug - Serial.print(bufferTlm[i]); - Serial.print(" "); - } - Serial.println();*/ - } else { - interrupts(); - } -} - -uint16_t getRpm() { - return tlmData.rpm; -} - -void startDshot() { - setupDMA(); - delay(100); - disableTlm(); -} - -bool isTlmAvailable() { - return flagTlm; -} - -void resetTlmFlag() { - flagTlm = false; -} - -void armingMotor() { - if (!armed) { - mode = ARMING_MODE; - throttle = 0; - timer.begin(ISR_timer, 2000); // 2ms (500Hz) - while (!armed); - noInterrupts(); - mode = DEFAULT_MODE; - interrupts(); - } -} - -void enable3d() { - uint16_t copyThrottle = throttle; - noInterrupts(); - mode = SEND_COMMAND_MODE; - throttle = 10; - interrupts(); - while(!commandSent); - noInterrupts(); - commandSent = false; - throttle = 12; - interrupts(); - while(!commandSent); - noInterrupts(); - commandSent = false; - mode = DEFAULT_MODE; - throttle = copyThrottle; - interrupts(); -} - -void disable3d() { - uint16_t copyThrottle = throttle; - noInterrupts(); - mode = SEND_COMMAND_MODE; - throttle = 9; - interrupts(); - while(!commandSent); - noInterrupts(); - commandSent = false; - throttle = 12; - interrupts(); - while(!commandSent); - noInterrupts(); - commandSent = false; - mode = DEFAULT_MODE; - throttle = copyThrottle; - interrupts(); -} - -void setControlLoopFrequency(uint16_t freq) { - timer.update(1000000 / freq); -} - -void enableTlm() { - if (!requestTlm) { - noInterrupts(); - requestTlm = true; - interrupts(); - } -} - -void disableTlm() { - if (requestTlm) { - noInterrupts(); - requestTlm = false; - interrupts(); - } -} - -void setThrottle(uint16_t newThrottle) { - // maybe add saturation - if (armed) { - noInterrupts(); - throttle = newThrottle; - requestTlm = true; - interrupts(); - } -} - -void stopMotor() { - throttle = 0; - mode = STOP_MODE; -} - - - - -void sendDshot() { - dataToSend = uint16_t((throttle << 5)) | uint16_t((requestTlm << 4)); - dataToSend |= ((dataToSend >> 4) ^ (dataToSend >> 8) ^ (dataToSend >> 12)) & 0x0f; // crc - for (int i = 0; i < DSHOT_LENGTH; i++) { - dma_source[i] = (dataToSend & (1 << (DSHOT_LENGTH - 1 - i))) ? LP : SP; - } - FTM0_SC = FTM_SC_CLKS(1); - if (requestTlm) { - flagTlm = true; - } -} - -// modify this function for control loop -void ISR_timer() { - /* TODO: add PID control */ - // throttle = ...; - - sendDshot(); - if (mode == ARMING_MODE) { - if (!armed && ++counter > 10) { - armed = true; - counter = 0; - } - } else if (mode == SEND_COMMAND_MODE) { - if (!commandSent && counter <= 10) { - counter++; - } - if (!commandSent && counter > 10) { - commandSent = true; - counter = 0; - } - } -} - -void ISR_DMA() { - dma.clearInterrupt(); - FTM0_SC = 0; - while (Serial1.available()) { - Serial1.read(); - } -} - -void setupDMA() { - CORE_PIN9_CONFIG = PORT_PCR_MUX(4) | PORT_PCR_DSE | PORT_PCR_SRE; - - dma.sourceBuffer(dma_source, sizeof(dma_source)); - dma.destination((uint16_t&) FTM0_C2V); - dma.triggerAtHardwareEvent(DMAMUX_SOURCE_FTM0_CH7); - dma.interruptAtCompletion(); - dma.attachInterrupt(ISR_DMA); - dma.enable(); - - FTM0_C2SC = FTM_CSC_MSB | FTM_CSC_ELSB; // edge-aligned pwm output - FTM0_C2V = 0; - FTM0_C7SC = FTM_CSC_CHIE | FTM_CSC_DMA | FTM_CSC_MSA | FTM_CSC_ELSA; - FTM0_C7V = 0; - - FTM0_SC = 0; - FTM0_CNT = 0; - FTM0_MOD = BIT_LENGTH; - FTM0_CNTIN = 0; -} - -uint8_t updateCrc8(uint8_t crc, uint8_t crc_seed) { - uint8_t crc_u = crc; - crc_u ^= crc_seed; - - for (int i = 0; i < 8; i++) { - crc_u = ( crc_u & 0x80 ) ? 0x7 ^ ( crc_u << 1 ) : ( crc_u << 1 ); - } - - return (crc_u); -} - -uint8_t calculateCrc8(const uint8_t *Buf, const uint8_t BufLen) { - uint8_t crc = 0; - for (int i = 0; i < BufLen; i++) { - crc = updateCrc8(Buf[i], crc); - } - - return crc; -} diff --git a/lib/teensyshot-master/Arda/dshot_simple_api/src/main.cpp b/lib/teensyshot-master/Arda/dshot_simple_api/src/main.cpp deleted file mode 100644 index 248ecfc..0000000 --- a/lib/teensyshot-master/Arda/dshot_simple_api/src/main.cpp +++ /dev/null @@ -1,40 +0,0 @@ -#include -#include "dshot_api.h" - -bool flagErr = false; - -uint8_t bufferTlm[TLM_LENGTH]; - -void setup() { - // configuring serial communications - Serial.begin(115200); // communicating over usb - Serial1.begin(115200); // communicating over UART1 - while(!Serial); // waits for the usb communication to be established - delay(100); - Serial.println("start"); // for debug - - startDshot(); // sets the DMA up and disables telemetry for initialization - - armingMotor(); // arms the motor by sending 0 command at least 10 times - delay(500); // for debug - giving time to esc to say "ARMED" - - enable3d(); // enables the 3D flight mode - setControlLoopFrequency(DSHOT_FREQ); // sets the control loop frequency for rpm control - enableTlm(); // enables the telemetry -} - -void loop() { - if (Serial.available()) { - String sentThrottle = ""; - char temp; - while (Serial.available()) { - temp = Serial.read(); - if (temp != '\n') { - sentThrottle += temp; - } - } - setThrottle(sentThrottle.toInt()); // updates the throttle value - } - - readTlm(); -} diff --git a/lib/teensyshot-master/ESCPID/AWPID.cpp b/lib/teensyshot-master/ESCPID/AWPID.cpp deleted file mode 100644 index d3cfa91..0000000 --- a/lib/teensyshot-master/ESCPID/AWPID.cpp +++ /dev/null @@ -1,219 +0,0 @@ -/* - * AWPID: Anti-windup PID API - * - * Note: Best viewed using Arduino IDE with tab space = 2 - * - * Authors: Jacques Gangloff - * Date: May 2019 - */ - -#define AWPID_FILTERED_MES - -// Includes -#include -#include -#include "AWPID.h" - -// Global variables -float AWPID_Kp[AWPID_MAX_NB]; // Proportional gain -float AWPID_Ki[AWPID_MAX_NB]; // Integral gain -float AWPID_Kd[AWPID_MAX_NB]; // Derivative gain -float AWPID_f[AWPID_MAX_NB]; // Pole of the derivative term lowpass filter -float AWPID_Min[AWPID_MAX_NB]; // Lower saturation -float AWPID_Max[AWPID_MAX_NB]; // Upper saturation -float AWPID_u0[AWPID_MAX_NB]; // Control signal before saturation -float AWPID_e0[AWPID_MAX_NB]; // Error signal -float AWPID_e1[AWPID_MAX_NB]; // Last sample error signal -float AWPID_ui0[AWPID_MAX_NB]; // Integral term -float AWPID_ui1[AWPID_MAX_NB]; // Last sample integral term -float AWPID_ud0[AWPID_MAX_NB]; // Derivative term -float AWPID_ud1[AWPID_MAX_NB]; // Last sample derivative term -#ifdef AWPID_FILTERED_MES -float AWPID_me1[AWPID_MAX_NB]; // Last sample measurement -uint8_t AWPID_minit[AWPID_MAX_NB]; // Init flag for mes history -#endif -uint8_t AWPID_n = 0; // Number of initialized PIDs - -// -// Initialisation of the PID parametrs -// -// Nb: number of controllers -// Kp: proportional gain -// Ki: integral gain -// Kd: derivative gain -// f: derivative filter pole -// ( 0 < f < 1, if f == 1, derivative action is cancelled) -// Sat: saturation (>0) -// -// Controller equation: -// -// C(z) = Kp + Ki z / ( z - 1 ) + Kd( z - 1 ) / (z - f ) -// -void AWPID_init( uint8_t n, - float *Kp, - float *Ki, - float *Kd, - float *f, - float *Min, - float *Max - ) { - - int i; - - if ( n <= AWPID_MAX_NB ) - AWPID_n = n; - else - AWPID_n = AWPID_MAX_NB; - - for ( i = 0; i < AWPID_n; i++ ) { - - // Definition of the PID tuning parameters - AWPID_Kp[i] = Kp[i]; - AWPID_Ki[i] = Ki[i]; - AWPID_Kd[i] = Kd[i]; - AWPID_f[i] = f[i]; - AWPID_Min[i] = Min[i]; - AWPID_Max[i] = Max[i]; - - // Initialisation of the PID internal variables - AWPID_u0[i] = 0.0; - - AWPID_e0[i] = 0.0; - AWPID_e1[i] = 0.0; - - AWPID_ui0[i] = 0.0; - AWPID_ui1[i] = 0.0; - - AWPID_ud0[i] = 0.0; - AWPID_ud1[i] = 0.0; - - #ifdef AWPID_FILTERED_MES - AWPID_me1[i] = 0.0; - AWPID_minit[i] = 0; - #endif - } - - return; - } - -// -// Reset internal variables of the PID -// -void AWPID_reset( void ) { - int i; - - for ( i = 0; i < AWPID_n; i++ ) { - // Initialisation of the PID internal variables - AWPID_u0[i] = 0.0; - - AWPID_e0[i] = 0.0; - AWPID_e1[i] = 0.0; - - AWPID_ui0[i] = 0.0; - AWPID_ui1[i] = 0.0; - - AWPID_ud0[i] = 0.0; - AWPID_ud1[i] = 0.0; - - #ifdef AWPID_FILTERED_MES - AWPID_me1[i] = 0.0; - AWPID_minit[i] = 0; - #endif - } -} - -// -// Computation of the ith control signal -// -void AWPID_control( uint8_t i, - float Reference, - float Measurement, - float *Control ) { - - if ( i >= AWPID_n ) - return; - - // Computation of the error - AWPID_e1[i] = AWPID_e0[i]; - AWPID_e0[i] = Reference - Measurement; - - // Computation of the derivative term - AWPID_ud1[i] = AWPID_ud0[i]; - #ifdef AWPID_FILTERED_MES - if ( AWPID_minit[i] == 0 ) { - AWPID_me1[i] = Measurement; - AWPID_minit[i] = 1; - } - AWPID_ud0[i] = AWPID_f[i] * AWPID_ud1[i] - - AWPID_Kd[i] * ( Measurement - AWPID_me1[i] ); - AWPID_me1[i] = Measurement; - #else - AWPID_ud0[i] = AWPID_f[i] * AWPID_ud1[i] + - AWPID_Kd[i] * ( AWPID_e0[i] - AWPID_e1[i] ); - #endif - - // Integral term computation - - AWPID_ui1[i] = AWPID_ui0[i]; - - // Anti-windup only if the integral gain is non null - if ( AWPID_Ki[i] ) { - - AWPID_u0[i] = AWPID_Kp[i] * AWPID_e0[i] + - AWPID_ud0[i] + - AWPID_ui1[i] + AWPID_Ki[i] * AWPID_e0[i]; - - // No saturation - if ( ( AWPID_u0[i] <= AWPID_Max[i] ) && ( AWPID_u0[i] >= AWPID_Min[i] ) ) - AWPID_ui0[i] = AWPID_ui1[i] + AWPID_Kp[i] * AWPID_Ki[i] * AWPID_e0[i]; - - // Upper limit saturation: recalculation of the integral term - // With this adjusment, the control signal equals exactly the saturation - if ( AWPID_u0[i] > AWPID_Max[i] ) - AWPID_ui0[i] = ( AWPID_Max[i] - - ( AWPID_Kp[i] * AWPID_e0[i] + AWPID_ud0[i] ) ); - - // Lower limit saturation: recalculation of the integral term - // With this adjusment, the control signal equals exactly the saturation - if ( AWPID_u0[i] < AWPID_Min[i] ) - AWPID_ui0[i] = ( AWPID_Min[i] - - ( AWPID_Kp[i] * AWPID_e0[i] + AWPID_ud0[i] ) ); - } - - // Control signal computation - *Control = AWPID_Kp[i] * AWPID_e0[i] + AWPID_ud0[i] + AWPID_ui0[i]; - - // Saturation - if ( *Control > AWPID_Max[i] ) - *Control = AWPID_Max[i]; - - if ( *Control < AWPID_Min[i] ) - *Control = AWPID_Min[i]; - - return; - } - -// -// Tuning of the ith PID. -// Can be called on-the-fly. -// -void AWPID_tune( uint8_t i, - float Kp, - float Ki, - float Kd, - float f, - float Min, - float Max - ) { - if ( i >= AWPID_n ) - return; - - // Definition of the PID tuning parameters - AWPID_Kp[i] = Kp; - AWPID_Ki[i] = Ki; - AWPID_Kd[i] = Kd; - AWPID_f[i] = f; - AWPID_Min[i] = Min; - AWPID_Max[i] = Max; - -} diff --git a/lib/teensyshot-master/ESCPID/AWPID.h b/lib/teensyshot-master/ESCPID/AWPID.h deleted file mode 100644 index bad215d..0000000 --- a/lib/teensyshot-master/ESCPID/AWPID.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Definitions for AWPID.cpp - * - */ - -#ifndef __AWPID_H -#define __AWPID_H - -// Defines -#define AWPID_MAX_NB 6 // Maximum number of PIDs - -// Function prototypes -void AWPID_init( uint8_t, float*, float*, float*, float*, float*, float* ); -void AWPID_reset( void ); -void AWPID_control( uint8_t, float, float, float* ); -void AWPID_tune( uint8_t, float, float, float, float, float, float ); - -#endif diff --git a/lib/teensyshot-master/ESCPID/DSHOT.cpp b/lib/teensyshot-master/ESCPID/DSHOT.cpp deleted file mode 100644 index b467945..0000000 --- a/lib/teensyshot-master/ESCPID/DSHOT.cpp +++ /dev/null @@ -1,400 +0,0 @@ -/* - * DSHOT: Generation of up to 6 DSHOT signals using DMA - * - * Note: Best viewed using Arduino IDE with tab space = 2 - * - * Authors: Arda Yiğit and Jacques Gangloff - * Date: May 2019 - */ - -// Includes -#include -#include "DMAChannel.h" -#include "DSHOT.h" - -/* - * Constants - */ - -#if defined(__IMXRT1062__) // teensy 4.0 - #define F_TMR F_BUS_ACTUAL -#else // teensy 3.5 - #define F_TMR F_BUS -#endif - -/* Defining DSHOT600 timings expressed in F_TMR periods - * DSHOT600 has the following timings: - * - * 1670ns - * ---------> - * ______ - * 1 bit : | |___| - * 1250ns - * ____ - * 0 bit : | |_____| - * 625ns - * - * On the teensy 3.5, F_TMR == 60000000 (60MHz) - * On the teensy 4.0, F_TMR == 600000000 (600Mhz) - */ -const uint16_t DSHOT_short_pulse = uint64_t(F_TMR) * DSHOT_SP_DURATION / 1000000000; // DSHOT short pulse duration (nb of F_BUS periods) -const uint16_t DSHOT_long_pulse = uint64_t(F_TMR) * DSHOT_LP_DURATION / 1000000000; // DSHOT long pulse duration (nb of F_BUS periods) -const uint16_t DSHOT_bit_length = uint64_t(F_TMR) * DSHOT_BT_DURATION / 1000000000; // DSHOT bit duration (nb of F_BUS periods) - -/* - * Global variables - */ - -// Number of initialized DSHOT outputs -uint8_t DSHOT_n; - -#if defined(__IMXRT1062__) // teensy 4.0 - -// DMA eFlexPWM modules -volatile IMXRT_FLEXPWM_t *DSHOT_mods[DSHOT_NB_DMA_CHAN] = { &IMXRT_FLEXPWM2, - &IMXRT_FLEXPWM1, - &IMXRT_FLEXPWM1, - &IMXRT_FLEXPWM4, - &IMXRT_FLEXPWM4, - &IMXRT_FLEXPWM2 - }; - -// DMA eFlexPWM submodules -volatile uint8_t DSHOT_sm[DSHOT_NB_DMA_CHAN] = { 0, - 3, - 2, - 0, - 1, - 2 - }; - -// DMA eFlexPWM submodule PWM channel selector: A=0, B=1, X=2 -volatile uint8_t DSHOT_abx[DSHOT_NB_DMA_CHAN] = { 0, - 0, - 2, - 0, - 0, - 1 - }; - -// Output pins -volatile uint8_t DSHOT_pin[DSHOT_NB_DMA_CHAN] = { 4, - 8, - 24, - 22, - 23, - 9 - }; - -// Output pin ALT mux -volatile uint8_t DSHOT_pinmux[DSHOT_NB_DMA_CHAN] = { 1, - 6, - 4, - 1, - 1, - 2 - }; - -// DMA source -volatile uint8_t DSHOT_dmamux[DSHOT_NB_DMA_CHAN] = { DMAMUX_SOURCE_FLEXPWM2_WRITE0, - DMAMUX_SOURCE_FLEXPWM1_WRITE3, - DMAMUX_SOURCE_FLEXPWM1_WRITE2, - DMAMUX_SOURCE_FLEXPWM4_WRITE0, - DMAMUX_SOURCE_FLEXPWM4_WRITE1, - DMAMUX_SOURCE_FLEXPWM2_WRITE2 - }; - -#else // teensy 3.5 - -// DMA FTM channel values references -volatile uint32_t* DSHOT_DMA_chan_teensy[DSHOT_NB_DMA_CHAN] ={ &FTM0_C0V, - &FTM0_C1V, - &FTM0_C4V, - &FTM0_C5V, - &FTM0_C6V, - &FTM0_C7V }; - -// DMA FTM channel status and control register -volatile uint32_t* DSHOT_DMA_chsc_teensy[DSHOT_NB_DMA_CHAN] ={ &FTM0_C0SC, - &FTM0_C1SC, - &FTM0_C4SC, - &FTM0_C5SC, - &FTM0_C6SC, - &FTM0_C7SC }; - - -// Output pins -volatile uint32_t* DSHOT_DMA_pin_teensy[DSHOT_NB_DMA_CHAN] ={ &CORE_PIN22_CONFIG, - &CORE_PIN23_CONFIG, - &CORE_PIN6_CONFIG, - &CORE_PIN20_CONFIG, - &CORE_PIN21_CONFIG, - &CORE_PIN5_CONFIG }; - -#endif - -// DMA objects -DMAChannel dma[DSHOT_MAX_OUTPUTS]; - -// DMA data -volatile uint16_t DSHOT_dma_data[DSHOT_MAX_OUTPUTS][DSHOT_DMA_LENGTH]; - -#if defined(__IMXRT1062__) // teensy 4.0 - -/* - * DMA termination interrupt service routine (ISR) for each DMA channel - */ -#define DSHOT_DMA_interrupt_routine( DSHOT_CHANNEL ) \ -void DSHOT_DMA_interrupt_routine_ ## DSHOT_CHANNEL( void ) { \ - dma[DSHOT_CHANNEL].clearInterrupt( ); \ - (*DSHOT_mods[DSHOT_CHANNEL]).MCTRL &= FLEXPWM_MCTRL_RUN( 1 << DSHOT_sm[DSHOT_CHANNEL] ); \ -} - -DSHOT_DMA_interrupt_routine( 0 ); -DSHOT_DMA_interrupt_routine( 1 ); -DSHOT_DMA_interrupt_routine( 2 ); -DSHOT_DMA_interrupt_routine( 3 ); -DSHOT_DMA_interrupt_routine( 4 ); -DSHOT_DMA_interrupt_routine( 5 ); - -void (*DSHOT_DMA_ISR[6])() = { DSHOT_DMA_interrupt_routine_0, - DSHOT_DMA_interrupt_routine_1, - DSHOT_DMA_interrupt_routine_2, - DSHOT_DMA_interrupt_routine_3, - DSHOT_DMA_interrupt_routine_4, - DSHOT_DMA_interrupt_routine_5 - }; - -#else // teensy 3.5 - -/* - * DMA termination interrupt service routine (ISR) - */ -void DSHOT_DMA_interrupt_routine( void ) { - - dma[0].clearInterrupt( ); - - // Disable FTM0 - FTM0_SC = 0; -} - -#endif - -/* - * Initialize the DMA hardware in order to be able - * to generate 6 DSHOT outputs. - */ -void DSHOT_init( int n ) { - int i, j; - - if ( n <= DSHOT_MAX_OUTPUTS ) - DSHOT_n = n; - else - DSHOT_n = DSHOT_MAX_OUTPUTS; - - // Initialize DMA data - for ( i = 0; i < DSHOT_n; i++ ) { - for ( j = 0; j < DSHOT_DMA_LENGTH; j++ ) { - DSHOT_dma_data[i][j] = 0; - } - } - -#if defined(__IMXRT1062__) // teensy 4.0 - - // Configure pins on the board as DSHOT outputs - // These pins are configured as eFlexPWM (FLEXPWMn) PWM outputs - for ( i = 0; i < DSHOT_n; i++ ) { - *(portConfigRegister( DSHOT_pin[i] )) = DSHOT_pinmux[i]; - } - - // Configure eFlexPWM modules and submodules for PWM generation - // --- submodule specific registers --- - // INIT: initial counter value - // VAL0: PWM_X compare value - // VAL1: counter max value - // VAL2: must be 0 for edge-aligned PWM - // VAL3: PWM_A compare value - // VAL4: must be 0 for edge-aligned PWM - // VAL5: PWM_B compare value - // OCTRL: invert polarity of PWMq FLEXPWM_SMOCTRL_POLq - // DMAEN: FLEXPWM_SMDMAEN_VALDE to enable DMA - // --- module specific registers --- - // OUTEN: output enable for submodule n and PWM q FLEXPWM_OUTEN_PWMq_EN( 1 << n ) - for ( i = 0; i < DSHOT_n; i++ ) { - (*DSHOT_mods[i]).SM[DSHOT_sm[i]].INIT = 0; - (*DSHOT_mods[i]).SM[DSHOT_sm[i]].VAL0 = 0; - (*DSHOT_mods[i]).SM[DSHOT_sm[i]].VAL1 = DSHOT_bit_length; - (*DSHOT_mods[i]).SM[DSHOT_sm[i]].VAL2 = 0; - (*DSHOT_mods[i]).SM[DSHOT_sm[i]].VAL3 = 0; - (*DSHOT_mods[i]).SM[DSHOT_sm[i]].VAL4 = 0; - (*DSHOT_mods[i]).SM[DSHOT_sm[i]].VAL5 = 0; - if ( DSHOT_abx[i] == 2 ) { - (*DSHOT_mods[i]).SM[DSHOT_sm[i]].OCTRL = FLEXPWM_SMOCTRL_POLX; - (*DSHOT_mods[i]).OUTEN |= FLEXPWM_OUTEN_PWMX_EN(1 << DSHOT_sm[i]); - } else if ( DSHOT_abx[i] == 1 ) { - (*DSHOT_mods[i]).OUTEN |= FLEXPWM_OUTEN_PWMB_EN(1 << DSHOT_sm[i]); - } else { - (*DSHOT_mods[i]).OUTEN |= FLEXPWM_OUTEN_PWMA_EN(1 << DSHOT_sm[i]); - } - (*DSHOT_mods[i]).SM[DSHOT_sm[i]].DMAEN = FLEXPWM_SMDMAEN_VALDE; - } - - // Each DMA channel is linked to a unique eFlexPWM submodule - // DMA channels are triggered by independant hardware events - for ( i = 0; i < DSHOT_n; i++ ) { - dma[i].sourceBuffer( DSHOT_dma_data[i], DSHOT_DMA_LENGTH * sizeof( uint16_t ) ); - if ( DSHOT_abx[i] == 2 ) { - dma[i].destination( (uint16_t&) (*DSHOT_mods[i]).SM[DSHOT_sm[i]].VAL0 ); - } else if ( DSHOT_abx[i] == 1 ) { - dma[i].destination( (uint16_t&) (*DSHOT_mods[i]).SM[DSHOT_sm[i]].VAL5 ); - } else { - dma[i].destination( (uint16_t&) (*DSHOT_mods[i]).SM[DSHOT_sm[i]].VAL3 ); - } - dma[i].triggerAtHardwareEvent( DSHOT_dmamux[i] ); - dma[i].interruptAtCompletion( ); - dma[i].attachInterrupt( DSHOT_DMA_ISR[i] ); - dma[i].enable( ); - } - -#else - - // Configure pins on the board as DSHOT outputs - // These pins are configured as FlexTimer (FTM0) PWM outputs - // PORT_PCR_DSE: high current output - // PORT_PCR_SRE: slow slew rate - for ( i = 0; i < DSHOT_n; i++ ) { - *DSHOT_DMA_pin_teensy[i] = PORT_PCR_MUX(4) | PORT_PCR_DSE | PORT_PCR_SRE; - } - - // First DMA channel is the only one triggered by the bit clock - dma[0].sourceBuffer( DSHOT_dma_data[0], DSHOT_DMA_LENGTH * sizeof( uint16_t ) ); - dma[0].destination( (uint16_t&) *DSHOT_DMA_chan_teensy[0] ); - dma[0].triggerAtHardwareEvent( DMAMUX_SOURCE_FTM0_CH2 ); - dma[0].interruptAtCompletion( ); - dma[0].attachInterrupt( DSHOT_DMA_interrupt_routine ); - dma[0].enable( ); - - // Other DMA channels are trigered by the previoux DMA channel - for ( i = 1; i < DSHOT_n; i++ ) { - dma[i].sourceBuffer( DSHOT_dma_data[i], DSHOT_DMA_LENGTH * sizeof( uint16_t ) ); - dma[i].destination( (uint16_t&) *DSHOT_DMA_chan_teensy[i] ); - dma[i].triggerAtTransfersOf( dma[i-1] ); - dma[i].triggerAtCompletionOf( dma[i-1] ); - dma[i].enable( ); - } - - // FTM0_CNSC: status and control register - // FTM_CSC_MSB | FTM_CSC_ELSB: - // edge aligned PWM with high-true pulses - for ( i = 0; i < DSHOT_n; i++ ) { - *DSHOT_DMA_chsc_teensy[i] = FTM_CSC_MSB | FTM_CSC_ELSB; - } - - // FTM0_CNV = 0: initialize the counter channel N at 0 - for ( i = 0; i < DSHOT_n; i++ ) { - *DSHOT_DMA_chan_teensy[i] = 0; - } - - // FTM0 channel 2 is the main clock - // FTM_CSC_CHIE: enable interrupt - // FTM_CSC_DMA: enable DMA - // FTM_CSC_MSA: toggle output on match - // FTM0_C2V = 0: initialize the counter channel 2 at 0 - FTM0_C2SC = FTM_CSC_CHIE | FTM_CSC_DMA | FTM_CSC_MSA | FTM_CSC_ELSA; - FTM0_C2V = 0; - - // Initialize FTM0 - FTM0_SC = 0; // Disable FTM0 - FTM0_CNT = 0; // Contains the FTM counter value - FTM0_MOD = DSHOT_bit_length; // The modulo value for the FTM counter - FTM0_CNTIN = 0; // Counter initial value - -#endif - -} - -// -// Send the DSHOT signal through all the configured channels -// "cmd" points to the DSHOT_MAX_OUTPUTS DSHOT commands to send -// Telemetry is requested with "tlm", CRC bits are added -// -// Returns an error code in case of failure, 0 otherwise: -// -int DSHOT_send( uint16_t *cmd, uint8_t *tlm ) { - int i, j; - uint16_t data; - - // Initialize DMA buffers - for ( i = 0; i < DSHOT_n; i++ ) { - - // Check cmd value - if ( cmd[i] > DSHOT_MAX_VALUE ) { - return DSHOT_ERROR_RANGE; - } - - // Compute the packet to send - // 11 first MSB = command - // 12th MSB = telemetry request - // 4 LSB = CRC - data = ( cmd[i] << 5 ) | ( tlm[i] << 4 ); - data |= ( ( data >> 4 ) ^ ( data >> 8 ) ^ ( data >> 12 ) ) & 0x0f; - - // Generate DSHOT timings corresponding to the packet - for ( j = 0; j < DSHOT_DSHOT_LENGTH; j++ ) { - if ( data & ( 1 << ( DSHOT_DSHOT_LENGTH - 1 - j ) ) ) { - DSHOT_dma_data[i][j] = DSHOT_long_pulse; - } else { - DSHOT_dma_data[i][j] = DSHOT_short_pulse; - } - } - } - - // Clear error flag on all DMA channels - for ( i = 0; i < DSHOT_n; i++ ) { - dma[i].clearError( ); - } - -#if defined(__IMXRT1062__) // teensy 4.0 - - // Start DMA by activating the clocks - // Clocks are disabled again by the DMA ISRs - IMXRT_FLEXPWM2.MCTRL |= FLEXPWM_MCTRL_RUN(15); - IMXRT_FLEXPWM1.MCTRL |= FLEXPWM_MCTRL_RUN(15); - IMXRT_FLEXPWM4.MCTRL |= FLEXPWM_MCTRL_RUN(15); - /* - for ( i = 0; i < DSHOT_n; i++ ) { - (*DSHOT_mods[i]).MCTRL |= FLEXPWM_MCTRL_RUN( 1 << DSHOT_sm[i] ); - } -*/ -#else - - // Start DMA by activating the clock - // The clock is disabled again by the DMA interrupt on channel 0 - FTM0_SC = FTM_SC_CLKS(1); - -#endif - - // Wait the theoretical time needed by DMA + some margin - delayMicroseconds( (unsigned int)( ( DSHOT_BT_DURATION * ( DSHOT_DMA_LENGTH + DSHOT_DMA_MARGIN ) ) / 1000 ) ); - -#if !defined(__IMXRT1062__) // teensy 3.5 - - // Check if FMT0 was disabled by the DMA ISR - // Check only bits 3 and 4: non null if a clock source is set - // TODO: test this error code - if ( FTM0_SC & (3 << 3) ) { - return DSHOT_ERROR_TIMEOUT; - } - -#endif - - // Check if there is a DMA error - // TODO: test this error code - for ( i = 0; i < DSHOT_n; i++ ) { - if ( dma[i].error( ) ) { - return DSHOT_ERROR_DMA; - } - } - - return 0; -} diff --git a/lib/teensyshot-master/ESCPID/DSHOT.h b/lib/teensyshot-master/ESCPID/DSHOT.h deleted file mode 100644 index bb09972..0000000 --- a/lib/teensyshot-master/ESCPID/DSHOT.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Definitions for DSHOT.cpp - * - */ - -#ifndef __DSHOT_H -#define __DSHOT_H - -// Defines -#define DSHOT_MAX_OUTPUTS 6 // Maximum number of DSHOT outputs on teensy 3.5 -#define DSHOT_NB_DMA_CHAN 6 // Number of accessible DMA channels -#if DSHOT_NB_DMA_CHAN < DSHOT_MAX_OUTPUTS - #error ESCCMD_NB_UART should be >= DSHOT_MAX_OUTPUTS -#endif -#define DSHOT_DMA_LENGTH 18 // Number of steps of one DMA sequence (the two last values are zero) -#define DSHOT_DMA_MARGIN 2 // Number of additional bit duration to wait until checking if DMA is over -#define DSHOT_DSHOT_LENGTH 16 // Number of bits in a DSHOT sequence -#define DSHOT_BT_DURATION 1670 // Duration of 1 DSHOT600 bit in ns -#define DSHOT_LP_DURATION 1250 // Duration of a DSHOT600 long pulse in ns -#define DSHOT_SP_DURATION 625 // Duration of a DSHOT600 short pulse in ns -#define DSHOT_MAX_VALUE 2047 // Maximum DSHOT value - -#define DSHOT_ERROR_DMA -1 // DMA error -#define DSHOT_ERROR_TIMEOUT -2 // Timeout : DMA duration is abnormally great -#define DSHOT_ERROR_RANGE -3 // Value out of range -#define DSHOT_ERROR_INTERNAL -4 // Internal error - -// Function prototypes -void DSHOT_init( int ); -int DSHOT_send( uint16_t*, uint8_t* ); - -#endif diff --git a/lib/teensyshot-master/ESCPID/ESCCMD.cpp b/lib/teensyshot-master/ESCPID/ESCCMD.cpp deleted file mode 100644 index 81c1c80..0000000 --- a/lib/teensyshot-master/ESCPID/ESCCMD.cpp +++ /dev/null @@ -1,1164 +0,0 @@ -/* - * ESCCMD: ESC DSHOT command packets formating API - * - * Note: Best viewed using Arduino IDE with tab space = 2 - * - * Authors: Arda Yiğit and Jacques Gangloff - * Date: May 2019 - */ - -// Includes -#include -#include "DSHOT.h" -#include "ESCCMD.h" - -// ESC emulation -#define ESCCMD_ESC_EMULATION // Uncomment to activate ESC emulation -#define ESCCMD_ESC_EMU_PKT_LOSS // Uncomment to emulate packet loss -#define ESCCMD_ESC_FRACTION_PKTLOSS 300 // One out of x packets lost - -// Error handling -#define ESCCMD_ERROR( code ) { ESCCMD_last_error[i] = code; return code; } - -// -// Global variables -// -volatile uint8_t ESCCMD_n; // Number of initialized outputs - -volatile uint8_t ESCCMD_state[ESCCMD_MAX_ESC]; // Current state of the cmd subsystem -uint16_t ESCCMD_CRC_errors[ESCCMD_MAX_ESC]; // Overall number of CRC error since start -int8_t ESCCMD_last_error[ESCCMD_MAX_ESC]; // Last error code -uint16_t ESCCMD_cmd[ESCCMD_MAX_ESC]; // Last command -uint16_t ESCCMD_throttle_wd[ESCCMD_MAX_ESC]; // Throttle watchdog counter -uint8_t ESCCMD_tlm_deg[ESCCMD_MAX_ESC]; // ESC temperature (°C) -uint16_t ESCCMD_tlm_volt[ESCCMD_MAX_ESC]; // Voltage of the ESC power supply (0.01V) -uint16_t ESCCMD_tlm_amp[ESCCMD_MAX_ESC]; // ESC current (0.01A) -uint16_t ESCCMD_tlm_mah[ESCCMD_MAX_ESC]; // ESC consumption (mAh) -uint16_t ESCCMD_tlm_rpm[ESCCMD_MAX_ESC]; // ESC electrical rpm (100rpm) -uint8_t ESCCMD_tlm[ESCCMD_MAX_ESC]; // Set to 1 when asking for telemetry -uint8_t ESCCMD_tlm_pend[ESCCMD_MAX_ESC]; // Flag indicating a pending telemetry data request -uint8_t ESCCMD_tlm_valid[ESCCMD_MAX_ESC]; // Flag indicating the validity of telemetry data -uint8_t ESCCMD_tlm_lost_cnt[ESCCMD_MAX_ESC]; // Lost packet counter of telemetry data -uint64_t ESCCMD_tic_counter = 0; // Counts the number of clock iterations - -volatile uint16_t ESCCMD_tic_pend = 0; // Number of timer tic waiting for ackowledgement -volatile uint8_t ESCCMD_init_flag = 0; // Subsystem initialization flag -volatile uint8_t ESCCMD_timer_flag = 0; // Periodic loop enable/disable flag - -IntervalTimer ESCCMD_timer; // Timer object -HardwareSerial* ESCCMD_serial[ESCCMD_NB_UART] = { // Array of Serial objects - &Serial1, - &Serial2, - &Serial3, - &Serial4, - &Serial5, - &Serial6 }; -uint8_t ESCCMD_bufferTlm[ESCCMD_NB_UART][ESCCMD_TLM_LENGTH]; - -#ifdef ESCCMD_ESC_EMULATION -#define ESCCMD_EMU_TLM_MAX 5 // Max number of telemetry packets -#define ESCCMD_EMU_TLM_DEG 25 // Nominal temperature (deg) -#define ESCCMD_EMU_TLM_VOLT 1200 // Nominal voltage (0.01V) -#define ESCCMD_EMU_TLM_AMP 2500 // Nominal current (0.01A) -#define ESCCMD_EMU_TLM_MAH 1000 // Nominal consumption (mAh) -#define ESCCMD_EMU_TLM_RPM 10 // Nominal electrical rpm (100rpm) -#define ESCCMD_EMU_TLM_NOISE 3.0 // Percentge of emulated noise (%) -#define ESCCMD_EMU_MOTOR_KV 2600 // Kv of the emulated motor - -uint8_t ESCCMD_tlm_emu_nb[ESCCMD_MAX_ESC] = {}; // Number of available packets - -uint8_t ESCCMD_tlm_emu_deg[ESCCMD_EMU_TLM_MAX][ESCCMD_MAX_ESC]; -uint16_t ESCCMD_tlm_emu_volt[ESCCMD_EMU_TLM_MAX][ESCCMD_MAX_ESC]; -uint16_t ESCCMD_tlm_emu_amp[ESCCMD_EMU_TLM_MAX][ESCCMD_MAX_ESC]; -uint16_t ESCCMD_tlm_emu_mah[ESCCMD_EMU_TLM_MAX][ESCCMD_MAX_ESC]; -uint16_t ESCCMD_tlm_emu_rpm[ESCCMD_EMU_TLM_MAX][ESCCMD_MAX_ESC]; -#endif - - -// -// Initialization -// -void ESCCMD_init( uint8_t n ) { - static int i; - - if ( ESCCMD_init_flag ) - return; - - if ( n <= ESCCMD_MAX_ESC ) - ESCCMD_n = n; - else - ESCCMD_n = ESCCMD_MAX_ESC; - - // Initialize data arrays to zero - for ( i = 0; i < ESCCMD_n; i++ ) { - ESCCMD_state[i] = 0; - ESCCMD_CRC_errors[i] = 0; - ESCCMD_last_error[i] = 0; - ESCCMD_cmd[i] = 0; - ESCCMD_throttle_wd[i] = 0; - ESCCMD_tlm_deg[i] = 0; - ESCCMD_tlm_volt[i] = 0; - ESCCMD_tlm_amp[i] = 0; - ESCCMD_tlm_mah[i] = 0; - ESCCMD_tlm_rpm[i] = 0; - ESCCMD_tlm[i] = 0; - ESCCMD_tlm_pend[i] = 0; - ESCCMD_tlm_valid[i] = 0; - ESCCMD_tlm_lost_cnt[i]= 0; - } - - // Initialize telemetry UART channels - for ( i = 0; i < ESCCMD_n; i++ ) { - ESCCMD_serial[i]->begin( ESCCMD_TLM_UART_SPEED ); - } - - // Initialize DSHOT generation subsystem - DSHOT_init( ESCCMD_n ); - - // Set the initialization flag - ESCCMD_init_flag = 1; -} - -// -// Arm all ESCs -// -// Return values: see defines -// -int ESCCMD_arm_all( void ) { - static int i, k; - - // Check if everything is initialized - if ( !ESCCMD_init_flag ) - return ESCCMD_ERROR_INIT; - - // Check if all the ESCs are in the initial state - for ( i = 0; i < ESCCMD_n; i++ ) - if ( ESCCMD_state[i] & ESCCMD_STATE_ARMED ) - ESCCMD_ERROR( ESCCMD_ERROR_SEQ ) - - // Define stop command - for ( i = 0; i < ESCCMD_n; i++ ) { - ESCCMD_cmd[i] = DSHOT_CMD_MOTOR_STOP; - ESCCMD_tlm[i] = 0; - } - - // Send command ESCCMD_CMD_ARMING_REP times - for ( i = 0; i < ESCCMD_CMD_ARMING_REP; i++ ) { - - // Send DSHOT signal to all ESCs - if ( DSHOT_send( ESCCMD_cmd, ESCCMD_tlm ) ) { - for ( k = 0; k < ESCCMD_n; k++ ) - ESCCMD_last_error[k] = ESCCMD_ERROR_DSHOT; - return ESCCMD_ERROR_DSHOT; - } - - // Wait some time - delayMicroseconds( 2 * ESCCMD_CMD_DELAY ); - } - - // Set the arming flag - for ( i = 0; i < ESCCMD_n; i++ ) - ESCCMD_state[i] |= ESCCMD_STATE_ARMED; - - return 0; -} - -// -// Activate 3D mode -// -// Return values: see defines -// -int ESCCMD_3D_on( void ) { - static int i, k; - - // Check if everything is initialized - if ( !ESCCMD_init_flag ) - return ESCCMD_ERROR_INIT; - - // Check if timer is disabled - if ( ESCCMD_timer_flag ) - return ESCCMD_ERROR_PARAM; - - for ( i = 0; i < ESCCMD_n; i++ ) { - // Check if ESCs are stopped - if ( ESCCMD_state[i] & ESCCMD_STATE_START ) - ESCCMD_ERROR( ESCCMD_ERROR_SEQ ) - } - - // Define 3D on command - for ( i = 0; i < ESCCMD_n; i++ ) { - ESCCMD_cmd[i] = DSHOT_CMD_3D_MODE_ON; - ESCCMD_tlm[i] = 1; - } - - // Send command ESCCMD_CMD_REPETITION times - for ( i = 0; i < ESCCMD_CMD_REPETITION; i++ ) { - - // Send DSHOT signal to all ESCs - if ( DSHOT_send( ESCCMD_cmd, ESCCMD_tlm ) ) { - for ( k = 0; k < ESCCMD_n; k++ ) - ESCCMD_last_error[k] = ESCCMD_ERROR_DSHOT; - return ESCCMD_ERROR_DSHOT; - } - - // Wait some time - delayMicroseconds( ESCCMD_CMD_DELAY ); - } - - // Define save settings command - for ( i = 0; i < ESCCMD_n; i++ ) { - ESCCMD_cmd[i] = DSHOT_CMD_SAVE_SETTINGS; - ESCCMD_tlm[i] = 1; - } - - // Send command ESCCMD_CMD_REPETITION times - for ( i = 0; i < ESCCMD_CMD_REPETITION; i++ ) { - - // Send DSHOT signal to all ESCs - if ( DSHOT_send( ESCCMD_cmd, ESCCMD_tlm ) ) { - for ( k = 0; k < ESCCMD_n; k++ ) - ESCCMD_last_error[k] = ESCCMD_ERROR_DSHOT; - return ESCCMD_ERROR_DSHOT; - } - - // Wait some time - delayMicroseconds( ESCCMD_CMD_DELAY ); - } - - // Set the 3D mode flag - for ( i = 0; i < ESCCMD_n; i++ ) - ESCCMD_state[i] |= ESCCMD_STATE_3D; - - // Minimum delay before next command - delayMicroseconds( ESCCMD_CMD_SAVE_DELAY ); - - // Flush incoming serial buffers due to a transcient voltage - // appearing on Tx when saving, generating a 0xff serial byte - for ( i = 0; i < ESCCMD_n; i++ ) - ESCCMD_serial[i]->clear( ); - - // ESC is disarmed after previous delay - for ( i = 0; i < ESCCMD_n; i++ ) - ESCCMD_state[i] &= ~(ESCCMD_STATE_ARMED); - - return 0; -} - -// -// Deactivate 3D mode -// -// Return values: see defines -// -int ESCCMD_3D_off( void ) { - static int i, k; - - // Check if everything is initialized - if ( !ESCCMD_init_flag ) - return ESCCMD_ERROR_INIT; - - // Check if timer is disabled - if ( ESCCMD_timer_flag ) - return ESCCMD_ERROR_PARAM; - - for ( i = 0; i < ESCCMD_n; i++ ) { - // Check if ESCs are stopped - if ( ESCCMD_state[i] & ESCCMD_STATE_START ) - ESCCMD_ERROR( ESCCMD_ERROR_SEQ ) - } - - // Define 3D off command - for ( i = 0; i < ESCCMD_n; i++ ) { - ESCCMD_cmd[i] = DSHOT_CMD_3D_MODE_OFF; - ESCCMD_tlm[i] = 1; - } - - // Send command ESCCMD_CMD_REPETITION times - for ( i = 0; i < ESCCMD_CMD_REPETITION; i++ ) { - - // Send DSHOT signal to all ESCs - if ( DSHOT_send( ESCCMD_cmd, ESCCMD_tlm ) ) { - for ( k = 0; k < ESCCMD_n; k++ ) - ESCCMD_last_error[k] = ESCCMD_ERROR_DSHOT; - return ESCCMD_ERROR_DSHOT; - } - - // Wait some time - delayMicroseconds( ESCCMD_CMD_DELAY ); - } - - // Define save settings command - for ( i = 0; i < ESCCMD_n; i++ ) { - ESCCMD_cmd[i] = DSHOT_CMD_SAVE_SETTINGS; - ESCCMD_tlm[i] = 1; - } - - // Send command ESCCMD_CMD_REPETITION times - for ( i = 0; i < ESCCMD_CMD_REPETITION; i++ ) { - - // Send DSHOT signal to all ESCs - if ( DSHOT_send( ESCCMD_cmd, ESCCMD_tlm ) ) { - for ( k = 0; k < ESCCMD_n; k++ ) - ESCCMD_last_error[k] = ESCCMD_ERROR_DSHOT; - return ESCCMD_ERROR_DSHOT; - } - - // Wait some time - delayMicroseconds( ESCCMD_CMD_DELAY ); - } - - // Clear the 3D mode flag - for ( i = 0; i < ESCCMD_n; i++ ) - ESCCMD_state[i] &= ~(ESCCMD_STATE_3D); - - // Minimum delay before next command - delayMicroseconds( ESCCMD_CMD_SAVE_DELAY ); - - // Flush incoming serial buffers due to a transcient voltage - // appearing on Tx when saving, generating a 0xff serial byte - for ( i = 0; i < ESCCMD_n; i++ ) - ESCCMD_serial[i]->clear( ); - - // ESC is disarmed after previous delay - for ( i = 0; i < ESCCMD_n; i++ ) - ESCCMD_state[i] &= ~(ESCCMD_STATE_ARMED); - - return 0; -} - -// -// Start periodic loop. ESC should be armed. -// -// Return values: see defines -// -int ESCCMD_start_timer( void ) { - static int i; - - // Check if everything is initialized - if ( !ESCCMD_init_flag ) - return ESCCMD_ERROR_INIT; - - // Check if timer already started - if ( ESCCMD_timer_flag ) - return ESCCMD_ERROR_SEQ; - - // Checks - for ( i = 0; i < ESCCMD_n; i++ ) { - // Check if all the ESCs are armed - if ( !( ESCCMD_state[i] & ESCCMD_STATE_ARMED ) ) - ESCCMD_ERROR( ESCCMD_ERROR_SEQ ) - - // Check if ESCs are stopped - if ( ESCCMD_state[i] & ESCCMD_STATE_START ) - ESCCMD_ERROR( ESCCMD_ERROR_SEQ ) - } - - // Initialize ESC structure and clear UART input buffer - for ( i = 0; i < ESCCMD_n; i++ ) { - ESCCMD_cmd[i] = DSHOT_CMD_MOTOR_STOP; - ESCCMD_tlm[i] = 0; - ESCCMD_tlm_pend[i] = 0; - ESCCMD_tlm_lost_cnt[i] = 0; - ESCCMD_CRC_errors[i] = 0; - ESCCMD_last_error[i] = 0; - ESCCMD_throttle_wd[i] = ESCCMD_THWD_LEVEL; - ESCCMD_serial[i]->clear( ); - } - - ESCCMD_tic_pend = 0; - - // Initialize timer - ESCCMD_timer.begin( ESCCMD_ISR_timer, ESCCMD_TIMER_PERIOD ); - - // Raise the timer flag - ESCCMD_timer_flag = 1; - - return 0; -} - -// -// Stop periodic loop. ESC should be armed. -// -// Return values: see defines -// -int ESCCMD_stop_timer( void ) { - static int i; - - // Check if everything is initialized - if ( !ESCCMD_init_flag ) - return ESCCMD_ERROR_INIT; - - // Check if timer started - if ( !ESCCMD_timer_flag ) - return ESCCMD_ERROR_SEQ; - - // Stop timer - ESCCMD_timer.end(); - ESCCMD_timer_flag = 0; - - // Update ESC state - for ( i = 0; i < ESCCMD_n; i++ ) { - ESCCMD_cmd[i] = DSHOT_CMD_MOTOR_STOP; - ESCCMD_tlm[i] = 0; - ESCCMD_state[i] &= ~( ESCCMD_STATE_ARMED | ESCCMD_STATE_START ); - } - - return 0; -} - -// -// Define throttle of ESC number i: -// Default mode: 0 -> 1999 -// 3D mode : -999 -> 999 -// -int ESCCMD_throttle( uint8_t i, int16_t throttle ) { - static uint8_t local_state; - - // Check if everything is initialized - if ( !ESCCMD_init_flag ) - return ESCCMD_ERROR_INIT; - - // Check if motor is within range - if ( i >= ESCCMD_n ) - return ESCCMD_ERROR_PARAM; - - // Check if timer started - if ( !ESCCMD_timer_flag ) - ESCCMD_ERROR( ESCCMD_ERROR_SEQ ); - - // Define a local copy of the state - noInterrupts(); - local_state = ESCCMD_state[i]; - interrupts(); - - // Check if ESC is armed - if ( !( local_state & ESCCMD_STATE_ARMED ) ) - ESCCMD_ERROR( ESCCMD_ERROR_SEQ ) - - // Define throttle depending on the mode - if ( local_state & ESCCMD_STATE_3D ) { - // Check limits - if ( ( throttle < ESCCMD_MIN_3D_THROTTLE ) || ( throttle > ESCCMD_MAX_3D_THROTTLE )) - ESCCMD_ERROR( ESCCMD_ERROR_PARAM ) - - // 3D mode - // 48 - 1047 : positive direction (48 slowest) - // 1048 - 2047 : negative direction (1048 slowest) - if ( throttle >= 0 ) - ESCCMD_cmd[i] = DSHOT_CMD_MAX + 1 + throttle; - else - ESCCMD_cmd[i] = DSHOT_CMD_MAX + 1 + ESCCMD_MAX_3D_THROTTLE - throttle; - } - else { - - // Check limits - if ( ( throttle < 0 ) || ( throttle > ESCCMD_MAX_THROTTLE )) - ESCCMD_ERROR( ESCCMD_ERROR_PARAM ) - - // Default mode - ESCCMD_cmd[i] = DSHOT_CMD_MAX + 1 + throttle; - } - - // Switch start mode on only if needed - if ( !( local_state & ESCCMD_STATE_START ) ) { - noInterrupts(); - ESCCMD_state[i] |= ESCCMD_STATE_START; - interrupts(); - ESCCMD_tlm[i] = 1; - } - - // Reset the throttle watchdog - if ( ESCCMD_throttle_wd[i] >= ESCCMD_THWD_LEVEL ) { - // If watchdog was previously triggered: - // Clear UART input buffer - // Also clear pending errors, pending packets... - ESCCMD_serial[i]->clear( ); - ESCCMD_tlm_pend[i] = 0; - ESCCMD_tlm_lost_cnt[i] = 0; - ESCCMD_CRC_errors[i] = 0; - ESCCMD_last_error[i] = 0; - } - ESCCMD_throttle_wd[i] = 0; - - return 0; -} - -// -// Stop motor number i -// -int ESCCMD_stop( uint8_t i ) { - static uint8_t local_state; - - // Check if everything is initialized - if ( !ESCCMD_init_flag ) - return ESCCMD_ERROR_INIT; - - // Check if motor is within range - if ( i >= ESCCMD_n ) - return ESCCMD_ERROR_PARAM; - - // Check if timer started - if ( !ESCCMD_timer_flag ) - ESCCMD_ERROR( ESCCMD_ERROR_SEQ ); - - // Define a local copy of the state - noInterrupts(); - local_state = ESCCMD_state[i]; - interrupts(); - - // Check if ESC is armed - if ( !( local_state & ESCCMD_STATE_ARMED ) ) - ESCCMD_ERROR( ESCCMD_ERROR_SEQ ) - - // Set command to stop - ESCCMD_cmd[i] = DSHOT_CMD_MOTOR_STOP; - - // Switch start mode off only if needed - if ( local_state & ESCCMD_STATE_START ) { - noInterrupts(); - ESCCMD_state[i] &= ~ESCCMD_STATE_START; - interrupts(); - ESCCMD_tlm[i] = 0; - } - - return 0; -} - -// -// Return last error code of motor number i -// -int ESCCMD_read_err( uint8_t i, int8_t *err ) { - - // Check if everything is initialized - if ( !ESCCMD_init_flag ) - return ESCCMD_ERROR_INIT; - - // Check if motor is within range - if ( i >= ESCCMD_n ) - return ESCCMD_ERROR_PARAM; - - // Return error code - *err = ESCCMD_last_error[i]; - - // Clear error - ESCCMD_last_error[i] = 0; - - return 0; -} - -// -// Return last command code of motor number i -// -int ESCCMD_read_cmd( uint8_t i, uint16_t *cmd ) { - - // Check if everything is initialized - if ( !ESCCMD_init_flag ) - return ESCCMD_ERROR_INIT; - - // Check if motor is within range - if ( i >= ESCCMD_n ) - return ESCCMD_ERROR_PARAM; - - - *cmd = ESCCMD_cmd[i]; - - return 0; -} - -// -// Read telemetry status of ESC number i -// -int ESCCMD_read_tlm_status( uint8_t i ) { - static uint8_t local_state; - - // Check if everything is initialized - if ( !ESCCMD_init_flag ) - return ESCCMD_ERROR_INIT; - - // Check if motor is within range - if ( i >= ESCCMD_n ) - return ESCCMD_ERROR_PARAM; - - // Check if timer started - if ( !ESCCMD_timer_flag ) - ESCCMD_ERROR( ESCCMD_ERROR_SEQ ); - - // Define a local copy of the state - noInterrupts(); - local_state = ESCCMD_state[i]; - interrupts(); - - // Check if ESC is armed - if ( !( local_state & ESCCMD_STATE_ARMED ) ) - ESCCMD_ERROR( ESCCMD_ERROR_SEQ ) - - // Check if telemetry is valid and active - if ( ESCCMD_tlm_valid[i] && ESCCMD_tlm[i] ) { - return 0; - } - else - return ESCCMD_ERROR_TLM_INVAL; -} - -// -// Read temperature of motor number i -// Unit is degree Celsius -// -int ESCCMD_read_deg( uint8_t i, uint8_t *deg ) { - static uint8_t local_state; - - // Check if everything is initialized - if ( !ESCCMD_init_flag ) - return ESCCMD_ERROR_INIT; - - // Check if motor is within range - if ( i >= ESCCMD_n ) - return ESCCMD_ERROR_PARAM; - - // Check if timer started - if ( !ESCCMD_timer_flag ) - ESCCMD_ERROR( ESCCMD_ERROR_SEQ ); - - // Define a local copy of the state - noInterrupts(); - local_state = ESCCMD_state[i]; - interrupts(); - - // Check if ESC is armed - if ( !( local_state & ESCCMD_STATE_ARMED ) ) - ESCCMD_ERROR( ESCCMD_ERROR_SEQ ) - - // Check if telemetry is valid - if ( ESCCMD_tlm_valid[i] ) { - *deg = ESCCMD_tlm_deg[i]; - } - else - return ESCCMD_ERROR_TLM_INVAL; - - return 0; -} - -// -// Read dc power supply voltage of motor number i -// Unit is Volt -// -int ESCCMD_read_volt( uint8_t i, uint16_t *volt ) { - static uint8_t local_state; - - // Check if everything is initialized - if ( !ESCCMD_init_flag ) - return ESCCMD_ERROR_INIT; - - // Check if motor is within range - if ( i >= ESCCMD_n ) - return ESCCMD_ERROR_PARAM; - - // Check if timer started - if ( !ESCCMD_timer_flag ) - ESCCMD_ERROR( ESCCMD_ERROR_SEQ ); - - // Define a local copy of the state - noInterrupts(); - local_state = ESCCMD_state[i]; - interrupts(); - - // Check if ESC is armed - if ( !( local_state & ESCCMD_STATE_ARMED ) ) - ESCCMD_ERROR( ESCCMD_ERROR_SEQ ) - - // Check if telemetry is valid - if ( ESCCMD_tlm_valid[i] ) { - *volt = ESCCMD_tlm_volt[i]; - } - else - return ESCCMD_ERROR_TLM_INVAL; - - return 0; -} - -// -// Read current of motor number i -// Unit is Ampere -// -int ESCCMD_read_amp( uint8_t i, uint16_t *amp ) { - static uint8_t local_state; - - // Check if everything is initialized - if ( !ESCCMD_init_flag ) - return ESCCMD_ERROR_INIT; - - // Check if motor is within range - if ( i >= ESCCMD_n ) - return ESCCMD_ERROR_PARAM; - - // Check if timer started - if ( !ESCCMD_timer_flag ) - ESCCMD_ERROR( ESCCMD_ERROR_SEQ ); - - // Define a local copy of the state - noInterrupts(); - local_state = ESCCMD_state[i]; - interrupts(); - - // Check if ESC is armed - if ( !( local_state & ESCCMD_STATE_ARMED ) ) - ESCCMD_ERROR( ESCCMD_ERROR_SEQ ) - - // Check if telemetry is valid - if ( ESCCMD_tlm_valid[i] ) { - *amp = ESCCMD_tlm_amp[i]; - } - else - return ESCCMD_ERROR_TLM_INVAL; - - return 0; -} - -// -// Read consumption of motor number i -// Unit is milli Ampere.hour -// -int ESCCMD_read_mah( uint8_t i, uint16_t *mah ) { - static uint8_t local_state; - - // Check if everything is initialized - if ( !ESCCMD_init_flag ) - return ESCCMD_ERROR_INIT; - - // Check if motor is within range - if ( i >= ESCCMD_n ) - return ESCCMD_ERROR_PARAM; - - // Check if timer started - if ( !ESCCMD_timer_flag ) - ESCCMD_ERROR( ESCCMD_ERROR_SEQ ); - - // Define a local copy of the state - noInterrupts(); - local_state = ESCCMD_state[i]; - interrupts(); - - // Check if ESC is armed - if ( !( local_state & ESCCMD_STATE_ARMED ) ) - ESCCMD_ERROR( ESCCMD_ERROR_SEQ ) - - // Check if telemetry is valid - if ( ESCCMD_tlm_valid[i] ) { - *mah = ESCCMD_tlm_mah[i]; - } - else - return ESCCMD_ERROR_TLM_INVAL; - - return 0; -} - -// -// Read shaft rotational velocity of motor number i -// Unit is round per minute -// The sign of the measurement depends on the last throttle sign -// -int ESCCMD_read_rpm( uint8_t i, int16_t *rpm ) { - static uint8_t local_state; - - // Check if everything is initialized - if ( !ESCCMD_init_flag ) - return ESCCMD_ERROR_INIT; - - // Check if motor is within range - if ( i >= ESCCMD_n ) - return ESCCMD_ERROR_PARAM; - - // Check if timer started - if ( !ESCCMD_timer_flag ) - ESCCMD_ERROR( ESCCMD_ERROR_SEQ ); - - // Define a local copy of the state - noInterrupts(); - local_state = ESCCMD_state[i]; - interrupts(); - - // Check if ESC is armed - if ( !( local_state & ESCCMD_STATE_ARMED ) ) - ESCCMD_ERROR( ESCCMD_ERROR_SEQ ) - - // Check if telemetry is valid - if ( ESCCMD_tlm_valid[i] ) { - // Check current mode - if ( local_state & ESCCMD_STATE_3D ) { - // 3D mode - // 48 - 1047 : positive direction (48 slowest) - // 1048 - 2047 : negative direction (1048 slowest) - if ( ESCCMD_cmd[i] > DSHOT_CMD_MAX + 1 + ESCCMD_MAX_3D_THROTTLE ) - *rpm = -ESCCMD_tlm_rpm[i]; // 3D mode negative direction - else - *rpm = ESCCMD_tlm_rpm[i]; // 3D mode positive direction - } - else { - // Default mode - *rpm = ESCCMD_tlm_rpm[i]; - } - - // Convert electrical rpm * 100 into motor rpm * 10 - *rpm = ( *rpm * 10 * 2 ) / ESCCMD_TLM_NB_POLES; - } - else - return ESCCMD_ERROR_TLM_INVAL; - - return 0; -} - -// -// Read next serial packet -// -uint8_t *ESCCMD_read_packet( uint8_t i ) { - #ifndef ESCCMD_ESC_EMULATION - static int buffer_idx[ESCCMD_NB_UART] = { 0 }; - static int serial_ret; - #endif - - #ifdef ESCCMD_ESC_EMULATION - uint8_t *pt_c; - - // Check if a packet is available - if ( ESCCMD_tlm_emu_nb[i] ) { - - ESCCMD_tlm_emu_nb[i]--; - - pt_c = &ESCCMD_tlm_emu_deg[ESCCMD_tlm_emu_nb[i]][i]; - ESCCMD_bufferTlm[i][0] = pt_c[0]; - pt_c = (uint8_t*)&ESCCMD_tlm_emu_volt[ESCCMD_tlm_emu_nb[i]][i]; - ESCCMD_bufferTlm[i][1] = pt_c[1]; - ESCCMD_bufferTlm[i][2] = pt_c[0]; - pt_c = (uint8_t*)&ESCCMD_tlm_emu_amp[ESCCMD_tlm_emu_nb[i]][i]; - ESCCMD_bufferTlm[i][3] = pt_c[1]; - ESCCMD_bufferTlm[i][4] = pt_c[0]; - pt_c = (uint8_t*)&ESCCMD_tlm_emu_mah[ESCCMD_tlm_emu_nb[i]][i]; - ESCCMD_bufferTlm[i][5] = pt_c[1]; - ESCCMD_bufferTlm[i][6] = pt_c[0]; - pt_c = (uint8_t*)&ESCCMD_tlm_emu_rpm[ESCCMD_tlm_emu_nb[i]][i]; - ESCCMD_bufferTlm[i][7] = pt_c[1]; - ESCCMD_bufferTlm[i][8] = pt_c[0]; - ESCCMD_bufferTlm[i][9] = ESCCMD_crc8( ESCCMD_bufferTlm[i], ESCCMD_TLM_LENGTH - 1 ); - - return ESCCMD_bufferTlm[i]; - } - #else - // Read all bytes in rx buffer up to packet length - while ( ( ESCCMD_serial[i]->available( ) ) && - ( buffer_idx[i] < ESCCMD_TLM_LENGTH ) ) { - - serial_ret = ESCCMD_serial[i]->read( ); - - if ( serial_ret >= 0 ) { - ESCCMD_bufferTlm[i][buffer_idx[i]] = (uint8_t)serial_ret; - buffer_idx[i]++; - } - } - - // Check if a complete packet has arrived - if ( buffer_idx[i] == ESCCMD_TLM_LENGTH ) { - - // Reset byte index in packet buffer - buffer_idx[i] = 0; - - // Return pointer to buffer - return ESCCMD_bufferTlm[i]; - } - #endif - - return NULL; -} - -// -// Extract data from the current packet -// -int ESCCMD_extract_packet_data( uint8_t i ) { - - // Extract packet data - - ESCCMD_tlm_deg[i] = ESCCMD_bufferTlm[i][0]; - ESCCMD_tlm_volt[i] = ( ESCCMD_bufferTlm[i][1] << 8 ) | ESCCMD_bufferTlm[i][2]; - ESCCMD_tlm_amp[i] = ( ESCCMD_bufferTlm[i][3] << 8 ) | ESCCMD_bufferTlm[i][4]; - ESCCMD_tlm_mah[i] = ( ESCCMD_bufferTlm[i][5] << 8 ) | ESCCMD_bufferTlm[i][6]; - ESCCMD_tlm_rpm[i] = ( ESCCMD_bufferTlm[i][7] << 8 ) | ESCCMD_bufferTlm[i][8]; - ESCCMD_tlm_valid[i] = ( ESCCMD_bufferTlm[i][9] == ESCCMD_crc8( ESCCMD_bufferTlm[i], ESCCMD_TLM_LENGTH - 1 ) ); - - // If crc is invalid, increment crc error counter - // and flush UART buffer - if ( !ESCCMD_tlm_valid[i] ) { - - ESCCMD_CRC_errors[i]++; - - ESCCMD_last_error[i] = ESCCMD_ERROR_TLM_CRC; - - // Check for excessive CRC errors - if ( ESCCMD_CRC_errors[i] >= ESCCMD_TLM_MAX_CRC_ERR ) { - ESCCMD_last_error[i] = ESCCMD_ERROR_TLM_CRCMAX; - } - - // Flush UART incoming buffer - // If ESC is transmitting, need to wait for some byte(s) to come in - do { - ESCCMD_serial[i]->clear( ); - delayMicroseconds( ESCCMD_TLM_BYTE_TIME * 2 ); - } while ( ESCCMD_serial[i]->available( ) ); - - // Reset pending packet counter - ESCCMD_tlm_pend[i] = 0; - - // Reset lost packet counter - ESCCMD_tlm_lost_cnt[i] = 0; - - return ESCCMD_last_error[i]; - } - else { - // Make some verifications on the telemetry - - // Check for overtheating of the ESC - if ( ESCCMD_tlm_deg[i] >= ESCCMD_TLM_MAX_TEMP ) { - ESCCMD_last_error[i] = ESCCMD_ERROR_TLM_TEMP; - return ESCCMD_last_error[i]; - } - } - - return 0; -} - -#ifdef ESCCMD_ESC_EMULATION -// -// Emulate telemetry -// -void ESCCMD_emulate_tlm( uint8_t i ) { - static uint8_t local_state; - - // Bufferize emulated telemetry data - if ( ESCCMD_tlm_emu_nb[i] < ESCCMD_EMU_TLM_MAX ) { - if ( ESCCMD_tlm[i] ) { - ESCCMD_tlm_emu_deg[ESCCMD_tlm_emu_nb[i]][i] = (uint8_t)( ESCCMD_EMU_TLM_DEG * ( 1.0 + ESCCMD_EMU_TLM_NOISE / 100.0 * (float)( rand( ) - RAND_MAX / 2 ) / ( RAND_MAX / 2 ) ) ); - ESCCMD_tlm_emu_volt[ESCCMD_tlm_emu_nb[i]][i] = (uint16_t)( ESCCMD_EMU_TLM_VOLT * ( 1.0 + ESCCMD_EMU_TLM_NOISE / 100.0 * (float)( rand( ) - RAND_MAX / 2 ) / ( RAND_MAX / 2 ) ) ); - ESCCMD_tlm_emu_amp[ESCCMD_tlm_emu_nb[i]][i] = (uint16_t)( ESCCMD_EMU_TLM_AMP * ( 1.0 + ESCCMD_EMU_TLM_NOISE / 100.0 * (float)( rand( ) - RAND_MAX / 2 ) / ( RAND_MAX / 2 ) ) ); - ESCCMD_tlm_emu_mah[ESCCMD_tlm_emu_nb[i]][i] = (uint16_t)( ESCCMD_EMU_TLM_MAH * ( 1.0 + ESCCMD_EMU_TLM_NOISE / 100.0 * (float)( rand( ) - RAND_MAX / 2 ) / ( RAND_MAX / 2 ) ) ); - - // Define a local copy of the state - noInterrupts(); - local_state = ESCCMD_state[i]; - interrupts(); - - // Compute rpm according to throttle cmd - if ( local_state & ESCCMD_STATE_3D ) { - - // 3D mode - if ( ESCCMD_cmd[i] > DSHOT_CMD_MAX + 1 + ESCCMD_MAX_3D_THROTTLE ) { - // Negative direction - ESCCMD_tlm_emu_rpm[ESCCMD_tlm_emu_nb[i]][i] = (uint16_t)( (float)( ESCCMD_cmd[i] - ( DSHOT_CMD_MAX + 2 + ESCCMD_MAX_3D_THROTTLE ) ) / ESCCMD_MAX_3D_THROTTLE - * (float)( ESCCMD_EMU_TLM_VOLT / 100 ) * ESCCMD_EMU_MOTOR_KV - / 100.0 * ESCCMD_TLM_NB_POLES / 2 ); - } - else { - // Positive direction - ESCCMD_tlm_emu_rpm[ESCCMD_tlm_emu_nb[i]][i] = (uint16_t)( (float)( ESCCMD_cmd[i] - ( DSHOT_CMD_MAX + 1 ) ) / ESCCMD_MAX_3D_THROTTLE - * (float)( ESCCMD_EMU_TLM_VOLT / 100 ) * ESCCMD_EMU_MOTOR_KV - / 100.0 * ESCCMD_TLM_NB_POLES / 2 ); - } - } - else { - // Normal mode - ESCCMD_tlm_emu_rpm[ESCCMD_tlm_emu_nb[i]][i] = (uint16_t)( (float)( ESCCMD_cmd[i] - ( DSHOT_CMD_MAX + 1 ) ) / ESCCMD_MAX_THROTTLE - * (float)( ESCCMD_EMU_TLM_VOLT / 100 ) * ESCCMD_EMU_MOTOR_KV - / 100.0 * ESCCMD_TLM_NB_POLES / 2 ); - } - } - - // Increment tlm counter according to packet loss statistics - #ifdef ESCCMD_ESC_EMU_PKT_LOSS - if ( (int)( ( (float)rand( ) / (float)RAND_MAX * (float)ESCCMD_ESC_FRACTION_PKTLOSS ) ) ) { - ESCCMD_tlm_emu_nb[i]++; - } - #else - ESCCMD_tlm_emu_nb[i]++; - #endif - } -} -#endif - -// -// This routine should be called within the main loop -// Returns ESCCMD_TIC_OCCURED when a tic occurs, -// Return 0 otherwise. -// -int ESCCMD_tic( void ) { - static int i; - static uint16_t local_tic_pend; - - // Check if timer started - if ( !ESCCMD_timer_flag ) { - return 0; - } - - //// Read telemetry - - for ( i = 0; i < ESCCMD_n; i++ ) { - - // Process all available telemetry packets - while ( ESCCMD_read_packet( i ) ) { - - // Update pending packet counter - if ( ESCCMD_tlm_pend[i] ) { - ESCCMD_tlm_pend[i]--; - } - else { - // Spurious packet ? - ESCCMD_last_error[i] = ESCCMD_ERROR_TLM_PEND; - } - - // Extract packet data - ESCCMD_extract_packet_data( i ); - } - - // Check for exceeding packet pending - if ( ESCCMD_tlm_pend[i] > ESCCMD_TLM_MAX_PEND ) { - - // Packet is considered as lost: update packet lost counter - if ( ESCCMD_tlm_lost_cnt[i] >= ESCCMD_TLM_MAX_PKT_LOSS ) { - ESCCMD_last_error[i] = ESCCMD_ERROR_TLM_LOST; - } - else { - ESCCMD_tlm_lost_cnt[i]++; - } - - // Decrement packet pending counter - ESCCMD_tlm_pend[i]--; - } - } - - //// Process clock tics - - noInterrupts(); - local_tic_pend = ESCCMD_tic_pend; - interrupts(); - - if ( local_tic_pend ) { - - // Acknowledgement of one timer clock event - noInterrupts(); - ESCCMD_tic_pend--; - interrupts(); - - // Update counters - ESCCMD_tic_counter++; - - if ( !( ESCCMD_tic_counter % ESCCMD_TLM_PER ) ) { - - // Clear stat counters every ESCCMD_TLM_PER iterations - for ( i = 0; i < ESCCMD_n; i++ ) { - ESCCMD_tlm_lost_cnt[i] = 0; - ESCCMD_CRC_errors[i] = 0; - } - } - - // Check if everything is initialized - if ( !ESCCMD_init_flag ) { - for ( i = 0; i < ESCCMD_n; i++ ) { - ESCCMD_last_error[i] = ESCCMD_ERROR_INIT; - } - return ESCCMD_TIC_OCCURED; - } - - // Check if all ESC are armed - for ( i = 0; i < ESCCMD_n; i++ ) { - if ( !( ESCCMD_state[i] & ESCCMD_STATE_ARMED ) ) { - ESCCMD_last_error[i] = ESCCMD_ERROR_SEQ; - return ESCCMD_TIC_OCCURED; - } - } - - // Throttle watchdog - for ( i = 0; i < ESCCMD_n; i++ ) { - if ( ESCCMD_throttle_wd[i] >= ESCCMD_THWD_LEVEL ) { - // Watchdog triggered on ESC number i - ESCCMD_cmd[i] = DSHOT_CMD_MOTOR_STOP; - ESCCMD_tlm[i] = 0; - ESCCMD_last_error[i] = 0; - ESCCMD_tlm_lost_cnt[i] = 0; - ESCCMD_CRC_errors[i] = 0; - noInterrupts(); - ESCCMD_state[i] &= ~( ESCCMD_STATE_START ); - interrupts(); - } - else { - ESCCMD_throttle_wd[i]++; - } - } - - // Send current command - if ( DSHOT_send( ESCCMD_cmd, ESCCMD_tlm ) ) { - for ( i = 0; i < ESCCMD_n; i++ ) { - ESCCMD_last_error[i] = ESCCMD_ERROR_DSHOT; - } - } - else { - delayMicroseconds( ESCCMD_CMD_DELAY ); - - // Update telemetry packet pending counter - for ( i = 0; i < ESCCMD_n; i++ ) { - if ( ESCCMD_tlm[i] ) { - ESCCMD_tlm_pend[i]++; - #ifdef ESCCMD_ESC_EMULATION - ESCCMD_emulate_tlm( i ); - #endif - } - } - } - - // Inform caller that a clock tic occured - return ESCCMD_TIC_OCCURED; - } - - return 0; -} - -// -// crc8 calculation -// -uint8_t ESCCMD_update_crc8( uint8_t crc, uint8_t crc_seed ) { - static uint8_t crc_u; - - crc_u = crc; - crc_u ^= crc_seed; - - for ( int i = 0; i < 8; i++ ) { - crc_u = ( crc_u & 0x80 ) ? 0x7 ^ ( crc_u << 1 ) : ( crc_u << 1 ); - } - - return crc_u; -} - -uint8_t ESCCMD_crc8( uint8_t* buf, uint8_t buflen ) { - static uint8_t crc; - - crc = 0; - - for ( int i = 0; i < buflen; i++ ) { - crc = ESCCMD_update_crc8( buf[i], crc ); - } - - return crc; -} - -// -// Timer ISR -// -void ESCCMD_ISR_timer( void ) { - static int i; - - // Check for maximum missed tics (ESC watchdog timer = 250ms on a KISS ESC) - if ( ESCCMD_tic_pend >= ESCCMD_TIMER_MAX_MISS ) { - - // ESC watchdog switch to disarmed and stopped mode - for ( i = 0; i < ESCCMD_n; i++ ) { - ESCCMD_state[i] &= ~( ESCCMD_STATE_ARMED | ESCCMD_STATE_START ); - } - } - else { - ESCCMD_tic_pend++; - } -} diff --git a/lib/teensyshot-master/ESCPID/ESCCMD.h b/lib/teensyshot-master/ESCPID/ESCCMD.h deleted file mode 100644 index fe16254..0000000 --- a/lib/teensyshot-master/ESCPID/ESCCMD.h +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Global definitions for ESCCMD - * NB: Arduino IDE automatically adds prototypes of functions - * found in all .ino files. - * - */ - -#ifndef __ESCCMD_H -#define __ESCCMD_H - -// Defines -#define ESCCMD_MAX_ESC DSHOT_MAX_OUTPUTS // Max number of ESCs -#define ESCCMD_NB_UART 6 // Number of UARTS available -#if ESCCMD_NB_UART < ESCCMD_MAX_ESC - #error ESCCMD_NB_UART should be >= ESCCMD_MAX_ESC -#endif - -#define ESCCMD_STATE_ARMED 1 // Mask for the arming flag -#define ESCCMD_STATE_3D 2 // Mask for the default/3D mode -#define ESCCMD_STATE_START 4 // Mask for the motor start/stop bit - -#define ESCCMD_CMD_REPETITION 10 // Number of time commands have to be repeated to be acknowledged by ESC -#define ESCCMD_CMD_ARMING_REP 25 // Number of command repetition to arm -#define ESCCMD_CMD_DELAY 50 // Delay between two consecutive DSHOT transmissions (us) -#define ESCCMD_CMD_SAVE_DELAY 250000 // Minimum time to wait after a save command (us) - -#define ESCCMD_TIMER_PERIOD 2000 // Periodic loop period (us) -#define ESCCMD_ESC_WATCHDOG 250000 // ESC arming watchdog timer (us) -#define ESCCMD_TIMER_MAX_MISS ( ESCCMD_ESC_WATCHDOG / ESCCMD_TIMER_PERIOD ) - // Maximum missed tics before watchdog is triggered -#define ESCCMD_THWD_LEVEL 20 // Maximum number of periods without throttle refresh - -#define ESCCMD_TLM_UART_SPEED 115200 // Baudrate of the telemetry serial transmission -#define ESCCMD_TLM_BYTE_TIME 87 // Duration of one byte transmission (us) -#define ESCCMD_TLM_LENGTH 10 // Number of bytes in the telemetry packet -#define ESCCMD_TLM_MAX_PEND 1 // Maximum number of telemetry packet pending -#define ESCCMD_TLM_NB_POLES 14 // Number of motor poles -#define ESCCMD_TLM_MAX_TEMP 100 // Maximum ESC temperature (°C) -#define ESCCMD_TLM_MAX_CRC_ERR 5 // Maximum CRC errors (per ESCCMD_TLM_PER iterations) -#define ESCCMD_TLM_MAX_PKT_LOSS 50 // Maximum packet loss (per ESCCMD_TLM_PER iterations) -#define ESCCMD_TLM_PER 1000 // If 100, error thresholds are in percent - -#define ESCCMD_MAX_THROTTLE 1999 // Max default throttle value -#define ESCCMD_MAX_3D_THROTTLE 999 // Max 3D throttle value -#define ESCCMD_MIN_3D_THROTTLE -999 // Min 3D throttle value - -#define ESCCMD_BEEP_DURATION 50 // Duration of a beep (ms) -#define ESCCMD_ERROR_DSHOT -1 // DSHOT error -#define ESCCMD_ERROR_SEQ -2 // Invalid function call sequence error -#define ESCCMD_ERROR_INIT -3 // Call of non initialized function -#define ESCCMD_ERROR_PARAM -4 // Invalid parameter error -#define ESCCMD_ERROR_TLM_CRC -5 // CRC error in telemetry packet -#define ESCCMD_ERROR_TLM_INVAL -6 // Invalid telemetry error -#define ESCCMD_ERROR_TLM_PEND -7 // Maximum number of pending telemetry packet reached -#define ESCCMD_ERROR_TLM_TEMP -8 // Maximum ESC temperature reached -#define ESCCMD_ERROR_TLM_CRCMAX -9 // Maximum allowed CRC errors reached -#define ESCCMD_ERROR_TLM_LOST -10 // Lost packet(s) detected - -#define ESCCMD_TIC_OCCURED 1 // A new timer tic has occured - -// enums: borrowed from betaflight pwm_output.h -typedef enum { - DSHOT_CMD_MOTOR_STOP = 0, - DSHOT_CMD_BEACON1, - DSHOT_CMD_BEACON2, - DSHOT_CMD_BEACON3, - DSHOT_CMD_BEACON4, - DSHOT_CMD_BEACON5, - DSHOT_CMD_ESC_INFO, // V2 includes settings - DSHOT_CMD_SPIN_DIRECTION_1, - DSHOT_CMD_SPIN_DIRECTION_2, - DSHOT_CMD_3D_MODE_OFF, // 9 - DSHOT_CMD_3D_MODE_ON, // 10 - DSHOT_CMD_SETTINGS_REQUEST, // Currently not implemented - DSHOT_CMD_SAVE_SETTINGS, // 12 - DSHOT_CMD_SPIN_DIRECTION_NORMAL = 20, - DSHOT_CMD_SPIN_DIRECTION_REVERSED = 21, - DSHOT_CMD_LED0_ON, // BLHeli32 only - DSHOT_CMD_LED1_ON, // BLHeli32 only - DSHOT_CMD_LED2_ON, // BLHeli32 only - DSHOT_CMD_LED3_ON, // BLHeli32 only - DSHOT_CMD_LED0_OFF, // BLHeli32 only - DSHOT_CMD_LED1_OFF, // BLHeli32 only - DSHOT_CMD_LED2_OFF, // BLHeli32 only - DSHOT_CMD_LED3_OFF, // BLHeli32 only - DSHOT_CMD_AUDIO_STREAM_MODE_ON_OFF = 30, // KISS audio Stream mode on/Off - DSHOT_CMD_SILENT_MODE_ON_OFF = 31, // KISS silent Mode on/Off - DSHOT_CMD_SIGNAL_LINE_TELEMETRY_DISABLE = 32, - DSHOT_CMD_SIGNAL_LINE_CONTINUOUS_ERPM_TELEMETRY = 33, - DSHOT_CMD_MAX = 47 -} ESCCMD_codes; - -// Function prototypes -void ESCCMD_init( uint8_t ); -int ESCCMD_arm_all( void ); -int ESCCMD_3D_on( void ); -int ESCCMD_3D_off( void ); -int ESCCMD_start_timer( void ); -int ESCCMD_stop_timer( void ); -int ESCCMD_throttle( uint8_t, int16_t ); -int ESCCMD_stop( uint8_t ); -int ESCCMD_read_err( uint8_t, int8_t* ); -int ESCCMD_read_cmd( uint8_t, uint16_t* ); -int ESCCMD_read_tlm_status( uint8_t ); -int ESCCMD_read_deg( uint8_t, uint8_t* ); -int ESCCMD_read_volt( uint8_t, uint16_t* ); -int ESCCMD_read_amp( uint8_t, uint16_t* ); -int ESCCMD_read_mah( uint8_t, uint16_t* ); -int ESCCMD_read_rpm( uint8_t, int16_t* ); -uint8_t *ESCCMD_read_packet( uint8_t ); -int ESCCMD_extract_packet_data( uint8_t ); -int ESCCMD_tic( void ); -uint8_t ESCCMD_update_crc8( uint8_t, uint8_t ); -uint8_t ESCCMD_crc8( uint8_t*, uint8_t ); -void ESCCMD_ISR_timer( void ); - -#endif diff --git a/lib/teensyshot-master/ESCPID/ESCPID.h b/lib/teensyshot-master/ESCPID/ESCPID.h deleted file mode 100644 index 9bf5c44..0000000 --- a/lib/teensyshot-master/ESCPID/ESCPID.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Definitions for ESCPID.ino - * - */ - -#ifndef __ESCPID_H -#define __ESCPID_H - -// Defines -#define ESCPID_NB_ESC 2 // Number of ESCs -#define ESCPID_MAX_ESC 6 // Max number of ESCs - -#define ESCPID_USB_UART_SPEED 115200 // Baudrate of the teeensy USB serial link - -#define ESCPID_PID_P 400 // Default PID proportional gain -#define ESCPID_PID_I 1050 // Default PID integral gain -#define ESCPID_PID_D 1000 // Default PID derivative gain -#define ESCPID_PID_F 9900 // Default PID derivative filtering pole -#define ESCPID_PID_MIN 1 // Default PID min control input value -#define ESCPID_PID_MAX 300 // Default PID max control input value -#define ESCPID_PID_ADAPT_GAIN 0.0001 // Range adaptation gain for PID coefficient - -#define ESCPID_COMM_MAGIC 0x43305735 // Magic number: "teensy35" in leet speech -#define ESCPID_RESET_GAIN 0xffff // PIDf gain value that triggers teensy reset -#define ESCPID_RESET_DELAY 1500 // Delay between reception of reset cmd and effective reset (ms) -#define ESCPID_COMM_WD_LEVEL 20 // Maximum number of periods without reference refresh - -#define ESCPID_ERROR_MAGIC -1 // Magic number error code - -// Teensy->host communication data structure -// sizeof(ESCPID_comm)=64 to match USB 1.0 buffer size -typedef struct { - uint32_t magic; // Magic number - int8_t err[ESCPID_MAX_ESC]; // Last error number - uint8_t deg[ESCPID_MAX_ESC]; // ESC temperature (°C) - uint16_t cmd[ESCPID_MAX_ESC]; // Current ESC command value - uint16_t volt[ESCPID_MAX_ESC]; // Voltage of the ESC power supply (0.01V) - uint16_t amp[ESCPID_MAX_ESC]; // ESC current (0.01A) - int16_t rpm[ESCPID_MAX_ESC]; // Motor rpm (10 rpm) -} ESCPIDcomm_struct_t; - -// Host->teensy communication data structure -// sizeof(Host_comm)=64 to match USB 1.0 buffer size -typedef struct { - uint32_t magic; // Magic number - int16_t RPM_r[ESCPID_MAX_ESC]; // Velocity reference (10 rpm) - uint16_t PID_P[ESCPID_MAX_ESC]; // PID proportional gain - uint16_t PID_I[ESCPID_MAX_ESC]; // PID integral gain - uint16_t PID_D[ESCPID_MAX_ESC]; // PID derivative gain - uint16_t PID_f[ESCPID_MAX_ESC]; // PID filtering pole -} Hostcomm_struct_t; - -#endif diff --git a/lib/teensyshot-master/ESCPID/ESCPID.ino b/lib/teensyshot-master/ESCPID/ESCPID.ino deleted file mode 100644 index e395c4b..0000000 --- a/lib/teensyshot-master/ESCPID/ESCPID.ino +++ /dev/null @@ -1,255 +0,0 @@ -/* - * ESCPID: PID control of up to 6 ESCs using teensy 3.5 MCU - * - * Note: Best viewed using Arduino IDE with tab space = 2 - * - * Authors: Arda Yiğit and Jacques Gangloff - * Date: May 2019 - */ - -// Includes -#include -#include "DSHOT.h" -#include "ESCCMD.h" -#include "AWPID.h" -#include "ESCPID.h" - -// Globals -float ESCPID_Reference[ESCPID_NB_ESC] = {}; -float ESCPID_Measurement[ESCPID_NB_ESC] = {}; -float ESCPID_Control[ESCPID_NB_ESC] = {}; -uint16_t ESCPID_comm_wd = 0; - -float ESCPID_Kp[ESCPID_NB_ESC]; -float ESCPID_Ki[ESCPID_NB_ESC]; -float ESCPID_Kd[ESCPID_NB_ESC]; -float ESCPID_f[ESCPID_NB_ESC]; -float ESCPID_Min[ESCPID_NB_ESC]; -float ESCPID_Max[ESCPID_NB_ESC]; - -ESCPIDcomm_struct_t ESCPID_comm = { - ESCPID_COMM_MAGIC, - {}, - {}, - {}, - {}, - {}, - {} - }; -Hostcomm_struct_t Host_comm = { - ESCPID_COMM_MAGIC, - {}, - {}, - {}, - {}, - {} - }; - -// -// Manage communication with the host -// -int ESCPID_comm_update( void ) { - static int i; - static uint8_t *ptin = (uint8_t*)(&Host_comm), - *ptout = (uint8_t*)(&ESCPID_comm); - static int ret; - static int in_cnt = 0; - - ret = 0; - - // Read all incoming bytes available until incoming structure is complete - while( ( Serial.available( ) > 0 ) && - ( in_cnt < (int)sizeof( Host_comm ) ) ) - ptin[in_cnt++] = Serial.read( ); - - // Check if a complete incoming packet is available - if ( in_cnt == (int)sizeof( Host_comm ) ) { - - // Clear incoming bytes counter - in_cnt = 0; - - // Look for a reset command - // If first ESC has 0xffff for PID and f gains, reset teensy - if ( ( Host_comm.PID_P[0] == ESCPID_RESET_GAIN ) && - ( Host_comm.PID_I[0] == ESCPID_RESET_GAIN ) && - ( Host_comm.PID_D[0] == ESCPID_RESET_GAIN ) && - ( Host_comm.PID_f[0] == ESCPID_RESET_GAIN ) ) { - - // Give time to host to close serial port - delay( ESCPID_RESET_DELAY ); - - // Reset command - SCB_AIRCR = 0x05FA0004; - } - - // Check the validity of the magic number - if ( Host_comm.magic != ESCPID_COMM_MAGIC ) { - - // Flush input buffer - while ( Serial.available( ) ) - Serial.read( ); - - ret = ESCPID_ERROR_MAGIC; - } - else { - - // Valid packet received - - // Reset the communication watchdog - ESCPID_comm_wd = 0; - - // Update the reference - for ( i = 0; i < ESCPID_NB_ESC; i++ ) - ESCPID_Reference[i] = Host_comm.RPM_r[i]; - - // Update PID tuning parameters - for ( i = 0; i < ESCPID_NB_ESC; i++ ) { - - // Gain conversion from int to float - ESCPID_Kp[i] = ESCPID_PID_ADAPT_GAIN * Host_comm.PID_P[i]; - ESCPID_Ki[i] = ESCPID_PID_ADAPT_GAIN * Host_comm.PID_I[i]; - ESCPID_Kd[i] = ESCPID_PID_ADAPT_GAIN * Host_comm.PID_D[i]; - ESCPID_f[i] = ESCPID_PID_ADAPT_GAIN * Host_comm.PID_f[i]; - - // Update PID tuning - AWPID_tune( i, - ESCPID_Kp[i], - ESCPID_Ki[i], - ESCPID_Kd[i], - ESCPID_f[i], - ESCPID_Min[i], - ESCPID_Max[i] - ); - } - - // Update output data structure values - // If telemetry is invalid, data structure remains unmodified - for ( i = 0; i < ESCPID_NB_ESC; i++ ) { - ESCCMD_read_err( i, &ESCPID_comm.err[i] ); - ESCCMD_read_cmd( i, &ESCPID_comm.cmd[i] ); - ESCCMD_read_deg( i, &ESCPID_comm.deg[i] ); - ESCCMD_read_volt( i, &ESCPID_comm.volt[i] ); - ESCCMD_read_amp( i, &ESCPID_comm.amp[i] ); - ESCCMD_read_rpm( i, &ESCPID_comm.rpm[i] ); - } - - // Send data structure to host - Serial.write( ptout, sizeof( ESCPID_comm ) ); - - // Force immediate transmission - Serial.send_now( ); - } - } - - return ret; -} - -// -// Arduino setup function -// -void setup() { - int i; - - // Initialize USB serial link - Serial.begin( ESCPID_USB_UART_SPEED ); - - // Initialize PID gains - for ( i = 0; i < ESCPID_NB_ESC; i++ ) { - ESCPID_Kp[i] = ESCPID_PID_ADAPT_GAIN * ESCPID_PID_P; - ESCPID_Ki[i] = ESCPID_PID_ADAPT_GAIN * ESCPID_PID_I; - ESCPID_Kd[i] = ESCPID_PID_ADAPT_GAIN * ESCPID_PID_D; - ESCPID_f[i] = ESCPID_PID_ADAPT_GAIN * ESCPID_PID_F; - ESCPID_Min[i] = ESCPID_PID_MIN; - ESCPID_Max[i] = ESCPID_PID_MAX; - } - - // Initialize PID subsystem - AWPID_init( ESCPID_NB_ESC, - ESCPID_Kp, - ESCPID_Ki, - ESCPID_Kd, - ESCPID_f, - ESCPID_Min, - ESCPID_Max ); - - // Initialize the CMD subsystem - ESCCMD_init( ESCPID_NB_ESC ); - - // Arming ESCs - ESCCMD_arm_all( ); - - // Switch 3D mode on - ESCCMD_3D_on( ); - - // Arming ESCs - ESCCMD_arm_all( ); - - // Start periodic loop - ESCCMD_start_timer( ); - - // Stop all motors - for ( i = 0; i < ESCPID_NB_ESC; i++ ) { - ESCCMD_stop( i ); - } - - // Reference watchdog is initially triggered - ESCPID_comm_wd = ESCPID_COMM_WD_LEVEL; -} - -// -// Arduino main loop -// -void loop( ) { - static int i, ret; - - // Check for next timer event - ret = ESCCMD_tic( ); - - // Bidirectional serial exchange with host - ESCPID_comm_update( ); - - if ( ret == ESCCMD_TIC_OCCURED ) { - - // Process timer event - - // Read all measurements and compute current control signal - for ( i = 0; i < ESCPID_NB_ESC; i++ ) { - - // Compute control signal only if telemetry is valid - // In case of invalid telemetry, last control signal is sent - // If motor is stopped, don't update PID to avoid integral term windup - if ( !ESCCMD_read_tlm_status( i ) ) { - - // Update measurement - ESCPID_Measurement[i] = ESCPID_comm.rpm[i]; - - // Update control signal - if ( ESCPID_Reference[i] >= 0 ) - AWPID_control( i, - ESCPID_Reference[i], - ESCPID_Measurement[i], - &ESCPID_Control[i] ); - else { - AWPID_control( i, - -ESCPID_Reference[i], - -ESCPID_Measurement[i], - &ESCPID_Control[i] ); - ESCPID_Control[i] *= -1.0; - } - } - - // Send control signal if reference has been sufficiently refreshed - if ( ESCPID_comm_wd < ESCPID_COMM_WD_LEVEL ) { - ret = ESCCMD_throttle( i, (int16_t)ESCPID_Control[i] ); - } - else { - AWPID_reset( ); - } - } - - // Update watchdog - if ( ESCPID_comm_wd < ESCPID_COMM_WD_LEVEL ) { - ESCPID_comm_wd++; - } - } -} diff --git a/lib/teensyshot-master/LICENSE b/lib/teensyshot-master/LICENSE deleted file mode 100644 index f288702..0000000 --- a/lib/teensyshot-master/LICENSE +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. diff --git a/lib/teensyshot-master/README.md b/lib/teensyshot-master/README.md deleted file mode 100644 index 36c9c57..0000000 --- a/lib/teensyshot-master/README.md +++ /dev/null @@ -1,42 +0,0 @@ -# teensySHOT -- DSHOT communication with ESC using Teensy 3.5 or Teensy 4.0 development boards -- DSHOT600 is generated using DMA -- Telemetry is received through UART at 115200bps -- Velocity PID control running at 500Hz is implemented for up to 6 motors - -## File Description -- ESCPID: code running on the Teensy - - DSHOT.cpp: DSHOT600 communication. - - AWPID.cpp: Anti-Windup PID. - - ESCCMD.cpp: Bidirectional communication between Teensy and ESC. - - ESCPID.ino: main program. -- host: code running on a Linux platform connected to the teensy. -- docs: useful documentation (MCU datasheets, DSHOT command description, telemetry protocol explanation, PID description...). - -## API Description - -### Incoming data -Velocity reference and PID parameters. -### Out-coming Data -Data structure containing telemetry data, error code and last DSHOT command. -### Tunable Macros -- ESCCMD_ESC_EMULATION (ESCCMD.cpp): flag to enable or disable ESC emulation. When enabled, the telemetry data is emulated. Packet loss can also be emulated. This helps to debug the code without ESC. -- ESCPID_NB_ESC (ESCPID.h): define the number of ESCs that are handled by teensySHOT. -- ESCPID_PID_MAX (ESCPID.h): Maximum PID control value. The maximum allowed is 999. A lower value may limit the motor maximum RPM in case of controller instability. Start testing with a low value and when everything is ok, raise it to the max. - -## Wiring -teensySHOT can communicate with up to 6 ESCs. The following pins are to be used with the current version. It is possible to change some DSHOT pins using muxing options of the MCU (tutorial in progress). - - - - - - - - - -
Teensy 3.5 Teensy 4.0
DSHOT TLM/RX DSHOT TLM/RX
1 22 0 4 0
2 23 9 8 7
3 6 7 24 15
4 20 31 22 16
5 21 34 23 21
6 5 47 9 25
- -## Authors -- [Arda Yiğit](mailto:arda.yigit@unistra.fr): DMA programming and ESC communication -- [Jacques Gangloff](mailto:jacques.gangloff@unistra.fr): higher level API, debugging diff --git a/lib/teensyshot-master/_config.yml b/lib/teensyshot-master/_config.yml deleted file mode 100644 index c419263..0000000 --- a/lib/teensyshot-master/_config.yml +++ /dev/null @@ -1 +0,0 @@ -theme: jekyll-theme-cayman \ No newline at end of file diff --git a/lib/teensyshot-master/docs/BLHeli32 cmd.pdf b/lib/teensyshot-master/docs/BLHeli32 cmd.pdf deleted file mode 100644 index 1bb0a6d..0000000 Binary files a/lib/teensyshot-master/docs/BLHeli32 cmd.pdf and /dev/null differ diff --git a/lib/teensyshot-master/docs/K64P144M120SF5RM.pdf b/lib/teensyshot-master/docs/K64P144M120SF5RM.pdf deleted file mode 100644 index 4ff96d1..0000000 Binary files a/lib/teensyshot-master/docs/K64P144M120SF5RM.pdf and /dev/null differ diff --git a/lib/teensyshot-master/docs/KISS_telemetry.pdf b/lib/teensyshot-master/docs/KISS_telemetry.pdf deleted file mode 100644 index bb06197..0000000 Binary files a/lib/teensyshot-master/docs/KISS_telemetry.pdf and /dev/null differ diff --git a/lib/teensyshot-master/docs/PID AW explained.pdf b/lib/teensyshot-master/docs/PID AW explained.pdf deleted file mode 100644 index 1d77b7a..0000000 Binary files a/lib/teensyshot-master/docs/PID AW explained.pdf and /dev/null differ diff --git a/lib/teensyshot-master/docs/PID.pdf b/lib/teensyshot-master/docs/PID.pdf deleted file mode 100644 index b0f0dac..0000000 Binary files a/lib/teensyshot-master/docs/PID.pdf and /dev/null differ diff --git a/lib/teensyshot-master/docs/RT1060.pdf b/lib/teensyshot-master/docs/RT1060.pdf deleted file mode 100644 index 7b104f0..0000000 Binary files a/lib/teensyshot-master/docs/RT1060.pdf and /dev/null differ diff --git a/lib/teensyshot-master/docs/RT1060_eFlexPWM.pdf b/lib/teensyshot-master/docs/RT1060_eFlexPWM.pdf deleted file mode 100644 index fafd422..0000000 Binary files a/lib/teensyshot-master/docs/RT1060_eFlexPWM.pdf and /dev/null differ diff --git a/lib/teensyshot-master/docs/RT1060_pin_mux.pdf b/lib/teensyshot-master/docs/RT1060_pin_mux.pdf deleted file mode 100644 index 15452e1..0000000 Binary files a/lib/teensyshot-master/docs/RT1060_pin_mux.pdf and /dev/null differ diff --git a/lib/teensyshot-master/host/host.c b/lib/teensyshot-master/host/host.c deleted file mode 100644 index 707bb61..0000000 --- a/lib/teensyshot-master/host/host.c +++ /dev/null @@ -1,405 +0,0 @@ -/* - * Communication with ESCPID code running on teensy 3.5 - * JG, June 2019 - * To compile : gcc -Wall -o host host.c - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#if defined(__linux__) -#include -#include -#endif -#include "host.h" - -// Flags -#define HOST_STANDALONE // main is added - -#define HOST_MAX_DEVICES 5 // Max number of teensys - -// Defines -// Note on USB port <-> devices relationship on RPI 3b+: -// Bottom, away from RJ45 : platform-3f980000.usb-usb-0:1.2:1.0 -// Bottom, next RJ45 : platform-3f980000.usb-usb-0:1.1.3:1.0 -// Top, away from RJ45 : platform-3f980000.usb-usb-0:1.3:1.0 -// Top, next RJ45 : platform-3f980000.usb-usb-0:1.1.2:1.0 -//#define HOST_MODEMDEVICE "/dev/serial/by-path/platform-3f980000.usb-usb-0:1.2:1.0" -//#define HOST_MODEMDEVICE "/dev/serial/by-id/usb-Teensyduino_USB_Serial_4367700-if00" -//#define HOST_MODEMDEVICE "/dev/ttyACM0" -//#define HOST_MODEMDEVICE "/dev/tty.usbmodem43677001" -//#define HOST_MODEMDEVICE "/dev/tty.usbmodem54887501" -#define HOST_DEV_SERIALNB 4367700 // Serial number of the teensy -//#define HOST_DEV_SERIALNB 54887501 -#define HOST_DEV_SERIALLG 10 // Max length of a serial number - -#if defined(__linux__) -#define HOST_SERIAL_DEV_DIR "/dev/serial/by-id/" -#elif defined(__APPLE__) -#define HOST_SERIAL_DEV_DIR "/dev/" -#else -#define HOST_SERIAL_DEV_DIR "/dev/" -#endif - -#define HOST_BAUDRATE B115200 // Serial baudrate -#define HOST_READ_TIMEOUT 5 // Tenth of second -#define HOST_NB_PING 1000 // Nb roundtrip communication -#define HOST_STEP_REF 200 // Velocity reference step size (10 rpm motor) -#define HOST_PERIOD 10000 // Period of serial exchange (us) -#define HOST_STEP_PERIOD 100 // Duration of a step (intertions) - -// Globals -int Host_fd[HOST_MAX_DEVICES] = - { HOST_ERROR_FD, - HOST_ERROR_FD, - HOST_ERROR_FD, - HOST_ERROR_FD, - HOST_ERROR_FD }; // Serial port file descriptor - -char Host_devname[HOST_MAX_DEVICES][PATH_MAX] = - { "", - "", - "", - "", - "" }; // Serial port devname used to get fd with open - -struct termios Host_oldtio[HOST_MAX_DEVICES]; // Backup of initial tty configuration - -ESCPIDcomm_struct_t ESCPID_comm[HOST_MAX_DEVICES]; -Hostcomm_struct_t Host_comm[HOST_MAX_DEVICES]; - -// -// Get the device name from the device serial number -// -char *Host_name_from_serial( uint32_t serial_nb ) { - DIR *d; - struct dirent *dir; - char serial_nb_char[HOST_DEV_SERIALLG]; - static char portname[PATH_MAX]; - - // Convert serial number into string - snprintf( serial_nb_char, HOST_DEV_SERIALLG, "%d", serial_nb ); - - // Open directory where serial devices can be found - d = opendir( HOST_SERIAL_DEV_DIR ); - - // Look for a device name contining teensy serial number - if ( d ) { - - // Scan each file in the directory - while ( ( dir = readdir( d ) ) != NULL ) { - if ( strstr( dir->d_name, serial_nb_char ) ) { - - // A match is a device name containing the serial number - snprintf( portname, PATH_MAX, "%s%s", HOST_SERIAL_DEV_DIR, dir->d_name ); - return portname; - } - } - closedir( d ); - } - - return NULL; -} - -// -// Get the file descriptor index which device name contains -// specified serial number. -// Returns -1 if no matching fd is found. -// -int Host_get_fd( uint32_t serial_nb ) { - int i; - char serial_nb_char[HOST_DEV_SERIALLG]; - - // Convert serial number into string - snprintf( serial_nb_char, HOST_DEV_SERIALLG, "%d", serial_nb ); - - for ( i = 0; i < HOST_MAX_DEVICES; i++ ) - if ( Host_fd[i] != HOST_ERROR_FD ) - if ( strstr( Host_devname[i], serial_nb_char ) ) - return i; - - return HOST_ERROR_FD; -} - -// -// Initialize serial port -// -int Host_init_port( uint32_t serial_nb ) { - struct termios newtio; - int check_fd; - int i, fd_idx; - char *portname; - - // Check if device plugged in - portname = Host_name_from_serial( serial_nb ); - if ( !portname ) - return HOST_ERROR_DEV; - - // Open device - check_fd = open( portname, O_RDWR | O_NOCTTY | O_NONBLOCK ); - - if ( check_fd < 0 ) { - perror( portname ); - return HOST_ERROR_DEV; - } - - // Look for an empty slot to store the fd - for ( fd_idx = 0; fd_idx < HOST_MAX_DEVICES; fd_idx++ ) - if ( Host_fd[fd_idx] == HOST_ERROR_FD ) - break; - - // Close fd and throw an error if all slots are used - if ( fd_idx == HOST_MAX_DEVICES ) { - close( check_fd ); - return HOST_ERROR_MAX_DEV; - } - - // Store the fd and the corresponding devname - Host_fd[fd_idx] = check_fd; - strncpy( Host_devname[fd_idx], portname, PATH_MAX ); - - // Initialize corresponding data structure - for ( i = 0; i < ESCPID_MAX_ESC; i++ ) { - Host_comm[fd_idx].magic = ESCPID_COMM_MAGIC; - Host_comm[fd_idx].RPM_r[i] = 0; - Host_comm[fd_idx].PID_P[i] = ESCPID_PID_P; - Host_comm[fd_idx].PID_I[i] = ESCPID_PID_I; - Host_comm[fd_idx].PID_D[i] = ESCPID_PID_D; - Host_comm[fd_idx].PID_f[i] = ESCPID_PID_F; - } - - /* Save current port settings */ - tcgetattr( check_fd, &Host_oldtio[fd_idx] ); - - /* Define new settings */ - bzero( &newtio, sizeof(newtio) ); - cfmakeraw( &newtio ); - - newtio.c_cflag = HOST_BAUDRATE | CS8 | CLOCAL | CREAD; - newtio.c_iflag = IGNPAR; - newtio.c_oflag = 0; - newtio.c_lflag = 0; - newtio.c_cc[VTIME] = 0; - newtio.c_cc[VMIN] = 0; - - #if defined(__APPLE__) - cfsetispeed( &newtio, HOST_BAUDRATE ); - cfsetospeed( &newtio, HOST_BAUDRATE ); - #endif - - /* Apply the settings */ - tcflush( check_fd, TCIFLUSH ); - tcsetattr( check_fd, TCSANOW, &newtio ); - - return 0; -} - -// -// Release serial port -// -void Host_release_port( uint32_t serial_nb ) { - int fd_idx; - - // Get fd index from serial number - fd_idx = Host_get_fd( serial_nb ); - - if ( fd_idx != HOST_ERROR_FD ) { - // Restore initial settings if needed - tcsetattr( Host_fd[fd_idx], TCSANOW, &Host_oldtio[fd_idx] ); - close( Host_fd[fd_idx] ); - - // Clear fd and corresponding devname - Host_fd[fd_idx] = HOST_ERROR_FD; - strncpy( Host_devname[fd_idx], "", PATH_MAX ); - } -} - -// -// Manage communication with the teensy connected to portname -// -int Host_comm_update( uint32_t serial_nb, - int16_t *RPM_r, - uint16_t *PID_P, - uint16_t *PID_I, - uint16_t *PID_D, - uint16_t *PID_f, - ESCPIDcomm_struct_t **comm ) { - - int i, ret, res = 0, fd_idx; - uint8_t *pt_in; - struct timespec start, cur; - unsigned long long elapsed_us; - - // Get fd index - fd_idx = Host_get_fd( serial_nb ); - - // Check if fd index is valid - if ( fd_idx == HOST_ERROR_FD ) - return HOST_ERROR_FD; - - // Update output data structue - for ( i = 0; i < ESCPID_MAX_ESC; i++ ) { - Host_comm[fd_idx].RPM_r[i] = RPM_r[i]; - Host_comm[fd_idx].PID_P[i] = PID_P[i]; - Host_comm[fd_idx].PID_I[i] = PID_I[i]; - Host_comm[fd_idx].PID_D[i] = PID_D[i]; - Host_comm[fd_idx].PID_f[i] = PID_f[i]; - } - - // Send output structure - res = write( Host_fd[fd_idx], &Host_comm[fd_idx], sizeof( Host_comm[fd_idx] ) ); - if ( res < 0 ) { - perror( "write Host_comm" ); - return HOST_ERROR_WRITE_SER; - } - - // Flush output buffer - fsync( Host_fd[fd_idx] ); - - // Wait for response - - // Get current time - clock_gettime( CLOCK_MONOTONIC, &start ); - - // Reset byte counter and magic number - res = 0; - ESCPID_comm[fd_idx].magic = 0; - pt_in = (uint8_t*)(&ESCPID_comm[fd_idx]); - - do { - ret = read( Host_fd[fd_idx], &pt_in[res], 1 ); - - // Data received - if ( ret > 0 ) { - res += ret; - } - - // Read error - if ( ret < 0 ) - break; - - // Compute time elapsed - clock_gettime( CLOCK_MONOTONIC, &cur ); - elapsed_us = ( cur.tv_sec * 1e6 + cur.tv_nsec / 1e3 ) - - ( start.tv_sec * 1e6 + start.tv_nsec / 1e3 ); - - // Timeout - if ( elapsed_us / 100000 > HOST_READ_TIMEOUT ) - break; - - } while ( res < sizeof( ESCPID_comm[fd_idx] ) ); - - // Check response size - if ( res != sizeof( ESCPID_comm[fd_idx] ) ) { - fprintf( stderr, "Packet with bad size received.\n" ); - - // Flush input buffer - while ( ( ret = read( Host_fd[fd_idx], pt_in, 1 ) ) ) - if ( ret <= 0 ) - break; - - return HOST_ERROR_BAD_PK_SZ; - } - - // Check magic number - if ( ESCPID_comm[fd_idx].magic != ESCPID_COMM_MAGIC ) { - fprintf( stderr, "Invalid magic number.\n" ); - return HOST_ERROR_MAGIC; - } - - // Return pointer to ESCPID_comm structure - *comm = &ESCPID_comm[fd_idx]; - - // Print rountrip duration - #ifdef HOST_STANDALONE - fprintf( stderr, "Delay: %llu us\n", elapsed_us ); - #endif - - return 0; -} - -#ifdef HOST_STANDALONE -// -// main -// -int main( int argc, char *argv[] ) { - - int i, k, ret; - int16_t RPM_r[ESCPID_MAX_ESC]; - uint16_t PID_P[ESCPID_MAX_ESC]; - uint16_t PID_I[ESCPID_MAX_ESC]; - uint16_t PID_D[ESCPID_MAX_ESC]; - uint16_t PID_f[ESCPID_MAX_ESC]; - ESCPIDcomm_struct_t *comm; - - // Initialize tunable PID data - for ( i = 0; i < ESCPID_MAX_ESC; i++ ) { - RPM_r[i] = HOST_STEP_REF; - PID_P[i] = ESCPID_PID_P; - PID_I[i] = ESCPID_PID_I; - PID_D[i] = ESCPID_PID_D; - PID_f[i] = ESCPID_PID_F; - } - - // Initialize serial port - if ( Host_init_port( HOST_DEV_SERIALNB ) ) { - fprintf( stderr, "Error initializing serial port.\n" ); - exit( -1 ); - } - - // Testing roundtrip serial link duration - for ( i = 0; i < HOST_NB_PING; i++ ) { - - // Serial exchange with teensy - if ( ( ret = Host_comm_update( HOST_DEV_SERIALNB, - RPM_r, - PID_P, - PID_I, - PID_D, - PID_f, - &comm ) ) ) { - fprintf( stderr, "Error %d in Host_comm_update.\n", ret ); - break; - } - - // Display telemetry - for ( k = 0; k < ESCPID_NB_ESC; k++ ) - fprintf( stderr, - "#:%d.%d\terr:%d\tdeg:%d\tcmd:%d\tmV:%d\tmA:%d\trpm_r:%d\trpm:%d\n", - i, - k, - comm->err[k], - comm->deg[k], - comm->cmd[k], - comm->volt[k] * 10, - comm->amp[k] * 10, - RPM_r[k] * 10, - comm->rpm[k] * 10 ); - - // Update reference - if ( !( i % HOST_STEP_PERIOD ) ) - for ( k = 0; k < ESCPID_MAX_ESC; k++ ) - RPM_r[k] *= -1; - - // Wait loop period - usleep( HOST_PERIOD ); - } - - // Restoring serial port initial configuration - Host_release_port( HOST_DEV_SERIALNB ); - - return 0; -} -#endif diff --git a/lib/teensyshot-master/host/host.h b/lib/teensyshot-master/host/host.h deleted file mode 100644 index 7d2832b..0000000 --- a/lib/teensyshot-master/host/host.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Definitions for host.c - */ - -#ifndef __HOST_H -#define __HOST_H - -#include "../ESCPID/ESCPID.h" - -// Defines -#define HOST_ERROR_FD -1 // Non existant file descriptor -#define HOST_ERROR_DEV -2 // Non existant serial device -#define HOST_ERROR_MAX_DEV -3 // Maximum devices limit -#define HOST_ERROR_WRITE_SER -4 // Write error on serial -#define HOST_ERROR_BAD_PK_SZ -5 // Bad incoming packet size error -#define HOST_ERROR_MAGIC -6 // Bad magic number received - -// Prototypes -char *Host_name_from_serial( uint32_t ); -int Host_get_fd( uint32_t ); -int Host_init_port( uint32_t ); -void Host_release_port( uint32_t ); -int Host_comm_update( uint32_t, - int16_t*, - uint16_t*, - uint16_t*, - uint16_t*, - uint16_t*, - ESCPIDcomm_struct_t** ); - -#endif \ No newline at end of file diff --git a/src/testing/DiyShot/.gitignore b/src/testing/DiyShot/.gitignore deleted file mode 100644 index 89cc49c..0000000 --- a/src/testing/DiyShot/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -.pio -.vscode/.browse.c_cpp.db* -.vscode/c_cpp_properties.json -.vscode/launch.json -.vscode/ipch diff --git a/src/testing/DiyShot/.vscode/extensions.json b/src/testing/DiyShot/.vscode/extensions.json deleted file mode 100644 index 080e70d..0000000 --- a/src/testing/DiyShot/.vscode/extensions.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - // See http://go.microsoft.com/fwlink/?LinkId=827846 - // for the documentation about the extensions.json format - "recommendations": [ - "platformio.platformio-ide" - ], - "unwantedRecommendations": [ - "ms-vscode.cpptools-extension-pack" - ] -} diff --git a/src/testing/DiyShot/include/README b/src/testing/DiyShot/include/README deleted file mode 100644 index 194dcd4..0000000 --- a/src/testing/DiyShot/include/README +++ /dev/null @@ -1,39 +0,0 @@ - -This directory is intended for project header files. - -A header file is a file containing C declarations and macro definitions -to be shared between several project source files. You request the use of a -header file in your project source file (C, C++, etc) located in `src` folder -by including it, with the C preprocessing directive `#include'. - -```src/main.c - -#include "header.h" - -int main (void) -{ - ... -} -``` - -Including a header file produces the same results as copying the header file -into each source file that needs it. Such copying would be time-consuming -and error-prone. With a header file, the related declarations appear -in only one place. If they need to be changed, they can be changed in one -place, and programs that include the header file will automatically use the -new version when next recompiled. The header file eliminates the labor of -finding and changing all the copies as well as the risk that a failure to -find one copy will result in inconsistencies within a program. - -In C, the usual convention is to give header files names that end with `.h'. -It is most portable to use only letters, digits, dashes, and underscores in -header file names, and at most one dot. - -Read more about using header files in official GCC documentation: - -* Include Syntax -* Include Operation -* Once-Only Headers -* Computed Includes - -https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html diff --git a/src/testing/DiyShot/lib/README b/src/testing/DiyShot/lib/README deleted file mode 100644 index 6debab1..0000000 --- a/src/testing/DiyShot/lib/README +++ /dev/null @@ -1,46 +0,0 @@ - -This directory is intended for project specific (private) libraries. -PlatformIO will compile them to static libraries and link into executable file. - -The source code of each library should be placed in a an own separate directory -("lib/your_library_name/[here are source files]"). - -For example, see a structure of the following two libraries `Foo` and `Bar`: - -|--lib -| | -| |--Bar -| | |--docs -| | |--examples -| | |--src -| | |- Bar.c -| | |- Bar.h -| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html -| | -| |--Foo -| | |- Foo.c -| | |- Foo.h -| | -| |- README --> THIS FILE -| -|- platformio.ini -|--src - |- main.c - -and a contents of `src/main.c`: -``` -#include -#include - -int main (void) -{ - ... -} - -``` - -PlatformIO Library Dependency Finder will find automatically dependent -libraries scanning project source files. - -More information about PlatformIO Library Dependency Finder -- https://docs.platformio.org/page/librarymanager/ldf.html diff --git a/src/testing/DiyShot/platformio.ini b/src/testing/DiyShot/platformio.ini deleted file mode 100644 index 9e7bc5c..0000000 --- a/src/testing/DiyShot/platformio.ini +++ /dev/null @@ -1,15 +0,0 @@ -; PlatformIO Project Configuration File -; -; Build options: build flags, source filter -; Upload options: custom upload port, speed and extra flags -; Library options: dependencies, extra library storages -; Advanced options: extra scripting -; -; Please visit documentation for the other options and examples -; https://docs.platformio.org/page/projectconf.html - -[env:teensy41] -platform = teensy -board = teensy41 -framework = arduino -lib_deps = luni64/TeensyTimerTool@^1.1.0 diff --git a/src/testing/DiyShot/src/main.cpp b/src/testing/DiyShot/src/main.cpp deleted file mode 100644 index ce11890..0000000 --- a/src/testing/DiyShot/src/main.cpp +++ /dev/null @@ -1,21 +0,0 @@ -#include -#include -using namespace TeensyTimerTool; - -PeriodicTimer t1(GPT2); - -void callback() // toggle the LED -{ - digitalWriteFast(33, !digitalReadFast(33)); -} - -void setup() -{ - t1.begin(callback, 250ns); - - pinMode(33, OUTPUT); -} - -void loop() -{ -} \ No newline at end of file diff --git a/src/testing/DiyShot/test/README b/src/testing/DiyShot/test/README deleted file mode 100644 index 9b1e87b..0000000 --- a/src/testing/DiyShot/test/README +++ /dev/null @@ -1,11 +0,0 @@ - -This directory is intended for PlatformIO Test Runner and project tests. - -Unit Testing is a software testing method by which individual units of -source code, sets of one or more MCU program modules together with associated -control data, usage procedures, and operating procedures, are tested to -determine whether they are fit for use. Unit testing finds problems early -in the development cycle. - -More information about PlatformIO Unit Testing: -- https://docs.platformio.org/en/latest/advanced/unit-testing/index.html diff --git a/src/testing/ESC_emulation_test/.gitignore b/src/testing/ESC_emulation_test/.gitignore deleted file mode 100644 index 89cc49c..0000000 --- a/src/testing/ESC_emulation_test/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -.pio -.vscode/.browse.c_cpp.db* -.vscode/c_cpp_properties.json -.vscode/launch.json -.vscode/ipch diff --git a/src/testing/ESC_emulation_test/.vscode/extensions.json b/src/testing/ESC_emulation_test/.vscode/extensions.json deleted file mode 100644 index 080e70d..0000000 --- a/src/testing/ESC_emulation_test/.vscode/extensions.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - // See http://go.microsoft.com/fwlink/?LinkId=827846 - // for the documentation about the extensions.json format - "recommendations": [ - "platformio.platformio-ide" - ], - "unwantedRecommendations": [ - "ms-vscode.cpptools-extension-pack" - ] -} diff --git a/src/testing/ESC_emulation_test/include/README b/src/testing/ESC_emulation_test/include/README deleted file mode 100644 index 194dcd4..0000000 --- a/src/testing/ESC_emulation_test/include/README +++ /dev/null @@ -1,39 +0,0 @@ - -This directory is intended for project header files. - -A header file is a file containing C declarations and macro definitions -to be shared between several project source files. You request the use of a -header file in your project source file (C, C++, etc) located in `src` folder -by including it, with the C preprocessing directive `#include'. - -```src/main.c - -#include "header.h" - -int main (void) -{ - ... -} -``` - -Including a header file produces the same results as copying the header file -into each source file that needs it. Such copying would be time-consuming -and error-prone. With a header file, the related declarations appear -in only one place. If they need to be changed, they can be changed in one -place, and programs that include the header file will automatically use the -new version when next recompiled. The header file eliminates the labor of -finding and changing all the copies as well as the risk that a failure to -find one copy will result in inconsistencies within a program. - -In C, the usual convention is to give header files names that end with `.h'. -It is most portable to use only letters, digits, dashes, and underscores in -header file names, and at most one dot. - -Read more about using header files in official GCC documentation: - -* Include Syntax -* Include Operation -* Once-Only Headers -* Computed Includes - -https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html diff --git a/src/testing/ESC_emulation_test/lib/README b/src/testing/ESC_emulation_test/lib/README deleted file mode 100644 index 6debab1..0000000 --- a/src/testing/ESC_emulation_test/lib/README +++ /dev/null @@ -1,46 +0,0 @@ - -This directory is intended for project specific (private) libraries. -PlatformIO will compile them to static libraries and link into executable file. - -The source code of each library should be placed in a an own separate directory -("lib/your_library_name/[here are source files]"). - -For example, see a structure of the following two libraries `Foo` and `Bar`: - -|--lib -| | -| |--Bar -| | |--docs -| | |--examples -| | |--src -| | |- Bar.c -| | |- Bar.h -| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html -| | -| |--Foo -| | |- Foo.c -| | |- Foo.h -| | -| |- README --> THIS FILE -| -|- platformio.ini -|--src - |- main.c - -and a contents of `src/main.c`: -``` -#include -#include - -int main (void) -{ - ... -} - -``` - -PlatformIO Library Dependency Finder will find automatically dependent -libraries scanning project source files. - -More information about PlatformIO Library Dependency Finder -- https://docs.platformio.org/page/librarymanager/ldf.html diff --git a/src/testing/ESC_emulation_test/platformio.ini b/src/testing/ESC_emulation_test/platformio.ini deleted file mode 100644 index 6fae0ef..0000000 --- a/src/testing/ESC_emulation_test/platformio.ini +++ /dev/null @@ -1,16 +0,0 @@ -; PlatformIO Project Configuration File -; -; Build options: build flags, source filter -; Upload options: custom upload port, speed and extra flags -; Library options: dependencies, extra library storages -; Advanced options: extra scripting -; -; Please visit documentation for the other options and examples -; https://docs.platformio.org/page/projectconf.html - -[env:teensy41] -platform = teensy -board = teensy41 -framework = arduino -lib_extra_dirs = - C:\Users\anigo\OneDrive\Documents\PSP\AC\Avionics\lib\teensyshot-master diff --git a/src/testing/ESC_emulation_test/src/main.cpp b/src/testing/ESC_emulation_test/src/main.cpp deleted file mode 100644 index 364efa3..0000000 --- a/src/testing/ESC_emulation_test/src/main.cpp +++ /dev/null @@ -1,36 +0,0 @@ -#include -#include "ESCCMD.h" - -//MAKE SURE TO UNCOMMENT LINE 16 of ESCCMD.cpp BEFORE RUNNING! - -uint16_t volt = 10; -uint8_t deg; -uint16_t amp; -uint16_t mah; -int16_t rpm; - -void setup() { - // put your setup code here, to run once: - ESCCMD_init(0); - ESCCMD_arm_all(); - Serial.begin(9600); -} - -void loop() { - // put your main code here, to run repeatedly: - ESCCMD_throttle(0, 1000); - - ESCCMD_read_deg(0, °); - ESCCMD_read_volt(0, &volt); - ESCCMD_read_amp(0, &); - ESCCMD_read_rpm(0, &rpm); - ESCCMD_read_mah(0, &mah); - - Serial.print("Temp: "); Serial.println(deg); - Serial.print("Volt: "); Serial.println(volt); - Serial.print("Amp: "); Serial.println(amp); - Serial.print("RPM: "); Serial.println(rpm); - Serial.print("mAh: "); Serial.println(mah); - - delay(500); -} \ No newline at end of file diff --git a/src/testing/ESC_emulation_test/test/README b/src/testing/ESC_emulation_test/test/README deleted file mode 100644 index b94d089..0000000 --- a/src/testing/ESC_emulation_test/test/README +++ /dev/null @@ -1,11 +0,0 @@ - -This directory is intended for PlatformIO Unit Testing and project tests. - -Unit Testing is a software testing method by which individual units of -source code, sets of one or more MCU program modules together with associated -control data, usage procedures, and operating procedures, are tested to -determine whether they are fit for use. Unit testing finds problems early -in the development cycle. - -More information about PlatformIO Unit Testing: -- https://docs.platformio.org/page/plus/unit-testing.html diff --git a/src/testing/servo_test_project/.gitignore b/src/testing/servo_test_project/.gitignore deleted file mode 100644 index 89cc49c..0000000 --- a/src/testing/servo_test_project/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -.pio -.vscode/.browse.c_cpp.db* -.vscode/c_cpp_properties.json -.vscode/launch.json -.vscode/ipch diff --git a/src/testing/servo_test_project/.vscode/extensions.json b/src/testing/servo_test_project/.vscode/extensions.json deleted file mode 100644 index 080e70d..0000000 --- a/src/testing/servo_test_project/.vscode/extensions.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - // See http://go.microsoft.com/fwlink/?LinkId=827846 - // for the documentation about the extensions.json format - "recommendations": [ - "platformio.platformio-ide" - ], - "unwantedRecommendations": [ - "ms-vscode.cpptools-extension-pack" - ] -} diff --git a/src/testing/servo_test_project/include/README b/src/testing/servo_test_project/include/README deleted file mode 100644 index 194dcd4..0000000 --- a/src/testing/servo_test_project/include/README +++ /dev/null @@ -1,39 +0,0 @@ - -This directory is intended for project header files. - -A header file is a file containing C declarations and macro definitions -to be shared between several project source files. You request the use of a -header file in your project source file (C, C++, etc) located in `src` folder -by including it, with the C preprocessing directive `#include'. - -```src/main.c - -#include "header.h" - -int main (void) -{ - ... -} -``` - -Including a header file produces the same results as copying the header file -into each source file that needs it. Such copying would be time-consuming -and error-prone. With a header file, the related declarations appear -in only one place. If they need to be changed, they can be changed in one -place, and programs that include the header file will automatically use the -new version when next recompiled. The header file eliminates the labor of -finding and changing all the copies as well as the risk that a failure to -find one copy will result in inconsistencies within a program. - -In C, the usual convention is to give header files names that end with `.h'. -It is most portable to use only letters, digits, dashes, and underscores in -header file names, and at most one dot. - -Read more about using header files in official GCC documentation: - -* Include Syntax -* Include Operation -* Once-Only Headers -* Computed Includes - -https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html diff --git a/src/testing/servo_test_project/lib/README b/src/testing/servo_test_project/lib/README deleted file mode 100644 index 6debab1..0000000 --- a/src/testing/servo_test_project/lib/README +++ /dev/null @@ -1,46 +0,0 @@ - -This directory is intended for project specific (private) libraries. -PlatformIO will compile them to static libraries and link into executable file. - -The source code of each library should be placed in a an own separate directory -("lib/your_library_name/[here are source files]"). - -For example, see a structure of the following two libraries `Foo` and `Bar`: - -|--lib -| | -| |--Bar -| | |--docs -| | |--examples -| | |--src -| | |- Bar.c -| | |- Bar.h -| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html -| | -| |--Foo -| | |- Foo.c -| | |- Foo.h -| | -| |- README --> THIS FILE -| -|- platformio.ini -|--src - |- main.c - -and a contents of `src/main.c`: -``` -#include -#include - -int main (void) -{ - ... -} - -``` - -PlatformIO Library Dependency Finder will find automatically dependent -libraries scanning project source files. - -More information about PlatformIO Library Dependency Finder -- https://docs.platformio.org/page/librarymanager/ldf.html diff --git a/src/testing/servo_test_project/platformio.ini b/src/testing/servo_test_project/platformio.ini deleted file mode 100644 index 3430396..0000000 --- a/src/testing/servo_test_project/platformio.ini +++ /dev/null @@ -1,17 +0,0 @@ -; PlatformIO Project Configuration File -; -; Build options: build flags, source filter -; Upload options: custom upload port, speed and extra flags -; Library options: dependencies, extra library storages -; Advanced options: extra scripting -; -; Please visit documentation for the other options and examples -; https://docs.platformio.org/page/projectconf.html - -[platformio] -default_envs = teensy41 - -[env:teensy41] -platform = teensy -board = teensy41 -framework = arduino diff --git a/src/testing/servo_test_project/src/main.cpp b/src/testing/servo_test_project/src/main.cpp deleted file mode 100644 index 06c455e..0000000 --- a/src/testing/servo_test_project/src/main.cpp +++ /dev/null @@ -1,26 +0,0 @@ -#include -#include - -Servo servo; - -int pos = 0; - -void setup() { - // put your setup code here, to run once: - Serial.begin(115200); - Serial.println("Servo sweep"); - servo.attach(23); -} - -void loop() { - // put your main code here, to run repeatedly: - for (pos = 0; pos <= 180; pos += 1) { // goes from 0 degrees to 180 degrees - // in steps of 1 degree - servo.write(pos); // tell servo to go to position in variable 'pos' - delay(15); // waits 15 ms for the servo to reach the position - } - for (pos = 180; pos >= 0; pos -= 1) { // goes from 180 degrees to 0 degrees - servo.write(pos); // tell servo to go to position in variable 'pos' - delay(15); // waits 15 ms for the servo to reach the position - } -} \ No newline at end of file diff --git a/src/testing/servo_test_project/test/README b/src/testing/servo_test_project/test/README deleted file mode 100644 index b94d089..0000000 --- a/src/testing/servo_test_project/test/README +++ /dev/null @@ -1,11 +0,0 @@ - -This directory is intended for PlatformIO Unit Testing and project tests. - -Unit Testing is a software testing method by which individual units of -source code, sets of one or more MCU program modules together with associated -control data, usage procedures, and operating procedures, are tested to -determine whether they are fit for use. Unit testing finds problems early -in the development cycle. - -More information about PlatformIO Unit Testing: -- https://docs.platformio.org/page/plus/unit-testing.html