Compare commits

...

25 Commits
r015 ... master

Author SHA1 Message Date
PaulStoffregen
54c4315c84 Update readme with SCLK overshoot info 2023-04-06 16:19:08 -07:00
Paul Stoffregen
73fa88476a
Merge pull request #20 from h4yn0nnym0u5e/warningfix/TD158
Fix warnings raised by gcc toolchain 11.3.1
2022-09-21 10:58:42 -07:00
Jonathan Oakley
82119a9138 Fix warnings raised by gcc toolchain 11.3.1 2022-09-21 16:30:33 +01:00
PaulStoffregen
ac4572cf57 Bump version to 0.16 2022-07-17 01:52:39 -07:00
PaulStoffregen
9b05d6a59a Update comments in Teensy_IMXRT.h 2022-02-25 07:41:36 -08:00
PaulStoffregen
e82dba6210 Add support for Teensy 4 2022-02-25 07:27:48 -08:00
PaulStoffregen
0c19010948 Rename examples to ino extension 2022-02-24 11:53:19 -08:00
Paul Stoffregen
597222e69d
Merge pull request #5 from aphelps/numtlcs
Allow NUM_TLCS to be specified with compile flags
2021-11-16 12:23:04 -08:00
Paul Stoffregen
092accd965
Merge pull request #13 from per1234/keywords-separator
Remove leading space from keywords.txt identifier tokens
2018-07-16 03:19:36 -07:00
per1234
8ae3cacb96
Remove leading space from keywords.txt identifier tokens
Each field of keywords.txt is separated by a single true tab. Leading spaces on a keyword identifier causes it to not be recognized by the Arduino IDE. On Arduino IDE 1.6.5 and newer an unrecognized keyword identifier causes the default editor.function.style highlighting to be used (as with KEYWORD2, KEYWORD3, LITERAL2).

Reference:
https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5:-Library-specification#keywords
2018-07-16 03:14:20 -07:00
PaulStoffregen
8285f02be0 Add issue template 2018-03-15 16:12:16 -07:00
PaulStoffregen
5820d022f3 Fix compile warning 2017-09-05 01:50:12 -07:00
PaulStoffregen
db6fca9763 Fix PROGMEM errors and warnings 2017-09-04 07:48:00 -07:00
Paul Stoffregen
839dbf0a21 Merge pull request #12 from per1234/keywords-separator
Use correct separator in keywords.txt
2017-09-02 10:51:37 -07:00
per1234
d2ee445d33 Use correct separator in keywords.txt
The Arduino IDE requires the use of a tab separator between the name and identifier. Without this tab the keyword is not highlighted.

Reference: https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5:-Library-specification#keywords
2017-09-02 09:01:06 -07:00
Paul Stoffregen
d701874e94 Merge pull request #10 from Jeff-Haas/master
Fixes for issue #9
2017-04-14 15:01:39 -07:00
Jeff-Haas
53fa214547 Updates for current Arduino IDE
Fixes bugs with AVR PROGMEM changes, introduced when Arduino IDE went to
1.6.x.  See details at:
https://github.com/arduino/Arduino/wiki/1.6-Frequently-Asked-Questions#errors-related-to-avr-progmem-changes
2017-04-13 23:21:34 -07:00
Jeff-Haas
181ae1de8f Revert "Revert "Updates for current Arduino IDE""
This reverts commit 66fc2402e4d71688b5fe745fe7813b88385f0aec.
2017-04-13 23:15:50 -07:00
Jeff-Haas
66fc2402e4 Revert "Updates for current Arduino IDE"
This reverts commit 89d8a53ddfefc7c03c7391c2947466021437bfcb.
2017-04-13 23:15:30 -07:00
Jeff-Haas
89d8a53ddf Updates for current Arduino IDE
Fixes bugs with AVR PROGMEM changes in Arduino IDE 1.6 or later.  Tested
with Arduino 1.8.2 and Sparkfun TLC5940 breakout.  Details at
https://github.com/arduino/Arduino/wiki/1.6-Frequently-Asked-Questions#errors-related-to-avr-progmem-changes
2017-04-13 23:01:06 -07:00
PaulStoffregen
87051f1118 Also support Teensy 3.5 2016-12-12 06:26:15 -08:00
Paul Stoffregen
3fa2a6d848 Merge pull request #8 from patrick-radius/master
Add constant for Teensy 3.6
2016-12-12 06:23:32 -08:00
patrick-radius
22ac6f5f6f Add constant for Teensy 3.6 2016-12-12 10:11:29 +01:00
Adam Phelps
93235a0b7f Allow NUM_TLCS to be specified with compile flags 2016-08-23 09:13:19 -07:00
PaulStoffregen
fc38a581b2 Fix library.properties 2015-03-26 18:36:41 -07:00
21 changed files with 216 additions and 54 deletions

View File

@ -1,4 +1,4 @@
#Tlc5940 Library#
# Tlc5940 Library
16 channel PWM LED driver based on the Texas Instruments TLC5940 chip.
@ -11,3 +11,9 @@ http://playground.arduino.cc/Learning/TLC5940
https://github.com/PaulStoffregen/Tlc5940
![Tlc5940 with Teensy 2.0](http://www.pjrc.com/teensy/td_libs_Tlc5940_1.jpg)
The TLC5940 chip SCK pin is sensitive to signal overshoot. When used with
Teensy 4.0 or other high speed hardware, especially if using long wires, you
may need to add a resistor inline with the SCLK signal.
https://forum.pjrc.com/threads/71009?p=323766&viewfull=1#post323766

View File

@ -71,13 +71,20 @@ ISR(TIMER1_OVF_vect)
}
#elif defined(__arm__) && defined(TEENSYDUINO)
#if defined(__IMXRT1062__)
void flexpwm42_isr(void)
{
FLEXPWM4_SM2STS = FLEXPWM_SMSTS_RF;
Tlc5940_interrupt();
}
#else
void ftm1_isr(void)
{
uint32_t sc = FTM1_SC;
if (sc & 0x80) FTM1_SC = sc & 0x7F;
Tlc5940_interrupt();
}
#endif
#endif
/** \defgroup ReqVPRG_ENABLED Functions that Require VPRG_ENABLED
@ -162,6 +169,31 @@ void Tlc5940::init(uint16_t initialValue)
TCCR1B |= _BV(CS10); // no prescale, (start pwm output)
#elif defined(__arm__) && defined(TEENSYDUINO)
#if defined(__IMXRT1062__)
/* Teensy 4.0, 4.1, MicroMod */
clear_pin(XLAT_DDR, XLAT_PIN);
analogWriteFrequency(5, 4000000);
analogWrite(5, 128);
const uint32_t newdiv = (uint32_t)((float)F_BUS_ACTUAL / 4 / 1000 + 0.5f);
FLEXPWM4_MCTRL |= FLEXPWM_MCTRL_CLDOK(4);
FLEXPWM4_SM2CTRL = FLEXPWM_SMCTRL_FULL | FLEXPWM_SMCTRL_PRSC(2); // 3146
FLEXPWM4_SM2VAL0 = newdiv - 1;
FLEXPWM4_SM2VAL1 = newdiv - 1;
FLEXPWM4_SM2VAL2 = newdiv - 7; // pin 2 = FlexPWM4_2_A = BLANK
FLEXPWM4_SM2VAL3 = newdiv - 1;
FLEXPWM4_SM2VAL4 = newdiv - 6; // pin 3 = FlexPWM4_2_B = XLAT
FLEXPWM4_SM2VAL5 = newdiv - 2;
FLEXPWM4_OUTEN = FLEXPWM_OUTEN_PWMA_EN(4) | FLEXPWM_OUTEN_PWMB_EN(4);
FLEXPWM4_MCTRL |= FLEXPWM_MCTRL_LDOK(4);
CORE_PIN2_CONFIG = 1;
CORE_PIN2_PADCONFIG = IOMUXC_PAD_DSE(7);
CORE_PIN3_PADCONFIG = IOMUXC_PAD_DSE(7);
FLEXPWM4_SM2INTEN = 0;
FLEXPWM4_SM2STS = 0x3FFF;
attachInterruptVector(IRQ_FLEXPWM4_2, flexpwm42_isr);
NVIC_ENABLE_IRQ(IRQ_FLEXPWM4_2);
#else
/* Teensy 3.0, 3.1, 3.2, 3.5, 3.6 */
clear_pin(XLAT_DDR, XLAT_PIN);
SIM_SCGC4 |= SIM_SCGC4_CMT;
CMT_MSC = 0;
@ -185,6 +217,7 @@ void Tlc5940::init(uint16_t initialValue)
FTM1_SC = FTM_SC_CLKS(1) | FTM_SC_CPWMS;
NVIC_ENABLE_IRQ(IRQ_FTM1);
CORE_PIN4_CONFIG = PORT_PCR_MUX(3)|PORT_PCR_DSE|PORT_PCR_SRE;
#endif
#endif
update();
}

View File

@ -50,10 +50,17 @@
#define disable_XLAT_pulses() TCCR1A = _BV(COM1B1)
#elif defined(__arm__) && defined(TEENSYDUINO)
#if defined(__IMXRT1062__)
#define set_XLAT_interrupt() FLEXPWM4_SM2STS = FLEXPWM_SMSTS_RF; FLEXPWM4_SM2INTEN = FLEXPWM_SMINTEN_RIE;
#define clear_XLAT_interrupt() FLEXPWM4_SM2INTEN = 0;
#define enable_XLAT_pulses() CORE_PIN3_CONFIG = 1;
#define disable_XLAT_pulses() CORE_PIN3_CONFIG = 5;
#else
#define set_XLAT_interrupt() FTM1_SC = FTM_SC_CLKS(1) | FTM_SC_CPWMS | FTM_SC_TOIE | (FTM1_SC & FTM_SC_PS(7))
#define clear_XLAT_interrupt() FTM1_SC = FTM_SC_CLKS(1) | FTM_SC_CPWMS | (FTM1_SC & FTM_SC_PS(7))
#define enable_XLAT_pulses() CORE_PIN3_CONFIG = PORT_PCR_MUX(3)|PORT_PCR_DSE|PORT_PCR_SRE
#define disable_XLAT_pulses() CORE_PIN3_CONFIG = PORT_PCR_MUX(1)|PORT_PCR_DSE|PORT_PCR_SRE
#endif
#endif

64
docs/issue_template.md Normal file
View File

@ -0,0 +1,64 @@
Please use this form only to report code defects or bugs.
For any question, even questions directly pertaining to this code, post your question on the forums related to the board you are using.
Arduino: forum.arduino.cc
Teensy: forum.pjrc.com
ESP8266: www.esp8266.com
ESP32: www.esp32.com
Adafruit Feather/Metro/Trinket: forums.adafruit.com
Particle Photon: community.particle.io
If you are experiencing trouble but not certain of the cause, or need help using this code, ask on the appropriate forum. This is not the place to ask for support or help, even directly related to this code. Only use this form you are certain you have discovered a defect in this code!
Please verify the problem occurs when using the very latest version, using the newest version of Arduino and any other related software.
----------------------------- Remove above -----------------------------
### Description
Describe your problem.
### Steps To Reproduce Problem
Please give detailed instructions needed for anyone to attempt to reproduce the problem.
### Hardware & Software
Board
Shields / modules used
Arduino IDE version
Teensyduino version (if using Teensy)
Version info & package name (from Tools > Boards > Board Manager)
Operating system & version
Any other software or hardware?
### Arduino Sketch
```cpp
// Change the code below by your sketch (please try to give the smallest code which demonstrates the problem)
#include <Arduino.h>
// libraries: give links/details so anyone can compile your code for the same result
void setup() {
}
void loop() {
}
```
### Errors or Incorrect Output
If you see any errors or incorrect output, please show it here. Please use copy & paste to give an exact copy of the message. Details matter, so please show (not merely describe) the actual message or error exactly as it appears.

View File

@ -40,7 +40,7 @@ void loop()
Plays an animation in the "background".
Don't call Tlc.update() while this is running.
You can check if this is done with !tlc_onUpdateFinished */
tlc_playAnimation(ani_arduino, ANI_ARDUINO_FRAMES, 3);
tlc_playAnimation(ani_arduino, ANI_ARDUINO_FRAMES, 3); // Default is 3
// If you don't want to do anything until it's finished, use:

View File

@ -1,5 +1,5 @@
#define ANI_ARDUINO_FRAMES 80
uint8_t ani_arduino[NUM_TLCS * 24 * ANI_ARDUINO_FRAMES] PROGMEM = {
const uint8_t ani_arduino[NUM_TLCS * 24 * ANI_ARDUINO_FRAMES] PROGMEM = {
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,6,176,206,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,65,10,64,247,15,240,255,
0,0,0,0,0,0,0,0,0,0,0,0,1,160,122,13,192,255,15,240,254,11,192,89,

View File

@ -24,11 +24,14 @@
The pattern below will only work with 1 TLC. Copy + Paste the 4 lines
inside the curly brackets for each additional TLC. */
uint8_t gsArray1[NUM_TLCS * 24] PROGMEM = {
GS_DUO((4095 * 16)/16, (4095 * 15)/16), GS_DUO((4095 * 14)/16, (4095 * 13)/16),
GS_DUO((4095 * 12)/16, (4095 * 11)/16), GS_DUO((4095 * 10)/16, (4095 * 9)/16),
GS_DUO((4095 * 8)/16, (4095 * 7)/16), GS_DUO((4095 * 6)/16, (4095 * 5)/16),
GS_DUO((4095 * 4)/16, (4095 * 3)/16), GS_DUO((4095 * 2)/16, (4095 * 1)/16),
const unsigned int TlcMax = 4095;
const uint8_t gsArray1[NUM_TLCS * 24] PROGMEM = {
GS_DUO((TlcMax * 16)/16, (TlcMax * 15)/16), GS_DUO((TlcMax * 14)/16, (TlcMax * 13)/16),
GS_DUO((TlcMax * 12)/16, (TlcMax * 11)/16), GS_DUO((TlcMax * 10)/16, (TlcMax * 9)/16),
GS_DUO((TlcMax * 8)/16, (TlcMax * 7)/16), GS_DUO((TlcMax * 6)/16, (TlcMax * 5)/16),
GS_DUO((TlcMax * 4)/16, (TlcMax * 3)/16), GS_DUO((TlcMax * 2)/16, (TlcMax * 1)/16),
};
void setup()

View File

@ -1,5 +1,5 @@
name=Tlc5940
version=r015
version=0.16
author=Paul Stoffregen
maintainer=Paul Stoffregen
sentence=Use the Texas Instruments TLC5940 16-channel LED Driver

37
pinouts/Teensy_IMXRT.h Normal file
View File

@ -0,0 +1,37 @@
#ifndef TLC_Teensy_IMXRT_h
#define TLC_Teensy_IMXRT_h
// bitbang I/O is plenty fast on Teensy 4
// and avoids SPI sharing problems
#ifdef DATA_TRANSFER_MODE
#undef DATA_TRANSFER_MODE
#endif
#define DATA_TRANSFER_MODE TLC_BITBANG
// Teensy pin 6 -> SIN (TLC pin 26)
#define DEFAULT_BB_SIN_PIN 6
#define DEFAULT_BB_SIN_PORT 6
#define DEFAULT_BB_SIN_DDR 6
// Teensy pin 7 -> SCLK (TLC pin 25)
#define DEFAULT_BB_SCLK_PIN 7
#define DEFAULT_BB_SCLK_PORT 7
#define DEFAULT_BB_SCLK_DDR 7
// FlexPWM4_2_B (Teensy pin 3) -> XLAT (TLC pin 24)
#define XLAT_PIN 3
#define XLAT_PORT 3
#define XLAT_DDR 3
// FlexPWM4_2_A (Teensy pin 2) -> BLANK (TLC pin 23)
#define BLANK_PIN 2
#define BLANK_PORT 2
#define BLANK_DDR 2
// PWM (Teensy pin 5) -> GSCLK (TLC pin 18)
#define GSCLK_PIN 5
#define GSCLK_PORT 5
#define GSCLK_DDR 5
#endif

View File

@ -113,11 +113,17 @@
#include "Teensypp_xxx6.h"
#elif defined (__MK20DX128__) \
|| defined (__MK20DX256__)
|| defined (__MK20DX256__) \
|| defined (__MK64FX512__) \
|| defined (__MK66FX1M0__)
/* Teensy 3.0 & 3.1 */
/* Teensy 3.0 & 3.1 & 3.2 & 3.5 & 3.6*/
#include "Teensy_KinetisK20.h"
#elif defined (__IMXRT1062__)
/* Teensy 4.0, 4.1, MicroMod */
#include "Teensy_IMXRT.h"
#else
#error "Unknown Chip!"

View File

@ -8,7 +8,9 @@
#define output_pin(ddr, pin) ddr |= _BV(pin)
#define pullup_pin(ddr, port, pin) ddr &= ~_BV(pin); port |= _BV(pin)
#elif defined(TEENSYDUINO)
#if F_CPU > 48000000
#if F_CPU > 120000000
#define pulse_pin(port, pin) delayNanoseconds(10); digitalWriteFast(pin, HIGH); delayNanoseconds(20); digitalWriteFast(pin, LOW)
#elif F_CPU > 48000000
#define pulse_pin(port, pin) digitalWriteFast(pin, HIGH); asm("nop"); digitalWriteFast(pin, LOW)
#else
#define pulse_pin(port, pin) digitalWriteFast(pin, HIGH); digitalWriteFast(pin, LOW)

View File

@ -30,7 +30,7 @@
#include "tlc_progmem_utils.h"
/** The currently playing animation */
prog_uint8_t *tlc_currentAnimation;
const uint8_t *tlc_currentAnimation;
/** The number of frames in the current animation */
volatile uint16_t tlc_animationFrames;
/** The number of PWM periods to display each frame - 1 */
@ -39,11 +39,11 @@ volatile uint16_t tlc_animationPeriodsPerFrame;
volatile uint16_t tlc_animationPeriodsWait;
volatile void tlc_animationXLATCallback(void);
void tlc_playAnimation(prog_uint8_t *animation, uint16_t frames, uint16_t periodsPerFrame);
void tlc_playAnimation(const uint8_t /* PROGMEM */ *animation, uint16_t frames, uint16_t periodsPerFrame);
/** \addtogroup ExtendedFunctions
\code #include "tlc_animations.h" \endcode
- void tlc_playAnimation(prog_uint8_t *animation, uint16_t frames,
- void tlc_playAnimation(const uint8_t PROGMEM *animation, uint16_t frames,
uint16_t periodsPerFrame) - plays an animation from progmem. */
/* @{ */
@ -55,7 +55,7 @@ void tlc_playAnimation(prog_uint8_t *animation, uint16_t frames, uint16_t period
\param periodsPerFrame number of PWM periods to wait between each frame
(0 means play the animation as fast as possible).
The default PWM period for a 16MHz clock is 1.024ms. */
void tlc_playAnimation(prog_uint8_t *animation, uint16_t frames, uint16_t periodsPerFrame)
void tlc_playAnimation(const uint8_t /* PROGMEM */ *animation, uint16_t frames, uint16_t periodsPerFrame)
{
tlc_currentAnimation = animation;
tlc_animationFrames = frames;

View File

@ -52,7 +52,9 @@
of the first TLC to the SIN (TLC pin 26) of the next. The rest of the pins
are attached normally.
\note Each TLC needs it's own IREF resistor */
#ifndef NUM_TLCS
#define NUM_TLCS 1
#endif
/** Determines how data should be transfered to the TLCs. Bit-banging can use
any two i/o pins, but the hardware SPI is faster.
@ -158,7 +160,9 @@
/** Arranges 2 grayscale values (0 - 4095) in the packed array format (3 bytes).
This is for array initializers only: the output is three comma seperated
8-bit values. */
#define GS_DUO(a, b) ((a) >> 4), ((a) << 4) | ((b) >> 8), (b)
//#define GS_DUO(a, b) ((a) >> 4), ((a) << 4) | ((b) >> 8), (b)
#define GS_DUO(a, b) (uint8_t)((a) >> 4), (uint8_t)((a) << 4) | (uint8_t)((b) >> 8), (uint8_t)(b)
#if VPRG_ENABLED

View File

@ -26,17 +26,17 @@
#include "Tlc5940.h"
#include "pinouts/pin_functions.h"
void tlc_setGSfromProgmem(prog_uint8_t *gsArray);
void tlc_setGSfromProgmem(const uint8_t /*PROGMEM*/ *gsArray);
#if VPRG_ENABLED
void tlc_setDCfromProgmem(prog_uint8_t *dcArray);
void tlc_setDCfromProgmem(const uint8_t /*PROGMEM*/ *dcArray);
#endif
/** \addtogroup ExtendedFunctions
\code #include "tlc_progmem_utils.h" \endcode
- void tlc_setGSfromProgmem(prog_uint8_t *gsArray) - copies the progmem
- void tlc_setGSfromProgmem(const uint8_t PROGMEM *gsArray) - copies the progmem
grayscale to current grayscale array. Requires a
\link Tlc5940::update Tlc.update() \endlink.
- void tlc_setDCfromProgmem(prog_uint8_t *dcArray) - shifts the data from a
- void tlc_setDCfromProgmem(const uint8_t PROGMEM *dcArray) - shifts the data from a
progmem dot correction array (doesn't need an update). */
/* @{ */
@ -44,7 +44,7 @@ void tlc_setDCfromProgmem(prog_uint8_t *dcArray);
any data: call Tlc.update(). An example:
\code
#include "tlc_progmem_utils.h"
prog_uint8_t gsArray1[NUM_TLCS * 24] = {
const uint8_t PROGMEM gsArray1[NUM_TLCS * 24] = {
GS_DUO((4095 * 16)/16, (4095 * 15)/16), GS_DUO((4095 * 14)/16, (4095 * 13)/16),
GS_DUO((4095 * 12)/16, (4095 * 11)/16), GS_DUO((4095 * 10)/16, (4095 * 9)/16),
GS_DUO((4095 * 8)/16, (4095 * 7)/16), GS_DUO((4095 * 6)/16, (4095 * 5)/16),
@ -62,9 +62,9 @@ Tlc.update();
The format of the grayscale array is explained in #tlc_GSData.
\param gsArray A progmem array of grayscale data. */
void tlc_setGSfromProgmem(prog_uint8_t *gsArray)
void tlc_setGSfromProgmem(const uint8_t /*PROGMEM*/ *gsArray)
{
prog_uint8_t *gsArrayp = gsArray;
const uint8_t /*PROGMEM*/ *gsArrayp = gsArray;
uint8_t *gsDatap = tlc_GSData;
while (gsDatap < tlc_GSData + NUM_TLCS * 24) {
*gsDatap++ = pgm_read_byte(gsArrayp++);
@ -78,14 +78,14 @@ void tlc_setGSfromProgmem(prog_uint8_t *gsArray)
/** \addtogroup ReqVPRG_ENABLED
From tlc_progmem_utils.h:
- tlc_setDCfromProgmem(prog_uint8_t *dcArray) - shifts the data from a
- tlc_setDCfromProgmem(const uint8_t PROGMEM *dcArray) - shifts the data from a
progmem dot correction array (doesn't need an update). */
/* @{ */
/** Sets the dot correction data from an array in progmem. An example:
\code
#include "tlc_progmem_utils.h"
prog_uint8_t dcArray1[NUM_TLCS * 12] = {
const uint8_t PROGMEM dcArray1[NUM_TLCS * 12] = {
DC_QUARTET(32, 63, 32, 63), DC_QUARTET(32, 63, 32, 63),
DC_QUARTET(32, 63, 32, 63), DC_QUARTET(32, 63, 32, 63),
};
@ -103,12 +103,12 @@ tlc_setDCfromProgmem(dcArray1);
\param dcArray A progmem array of dot correction data to be shifted out.
\see \link Tlc5940::setAllDC Tlc.setAllDC \endlink */
void tlc_setDCfromProgmem(prog_uint8_t *dcArray)
void tlc_setDCfromProgmem(const uint8_t PROGMEM *dcArray)
{
tlc_dcModeStart();
prog_uint8_t *p = dcArray;
prog_uint8_t *dcArrayEnd = dcArray + NUM_TLCS * 12;
const uint8_t PROGMEM *p = dcArray;
const uint8_t PROGMEM *dcArrayEnd = dcArray + NUM_TLCS * 12;
while (p < dcArrayEnd) {
tlc_shift8(pgm_read_byte(p++));
}

View File

@ -97,7 +97,7 @@ void tlc_initServos(uint8_t initAngle)
#elif defined(__arm__) && defined(TEENSYDUINO)
//clear_XLAT_interrupt();
uint32_t sc = FTM1_SC;
uint32_t sc __attribute__ ((unused)) = FTM1_SC;
FTM1_SC = 0; // stop timer
CMT_MSC = 0;
CMT_CGH1 = TLC_TIMER_TEENSY3_SERVO_CGH1;