diff --git a/Tlc5940.cpp b/Tlc5940.cpp index 4f850b5..99fbdf8 100644 --- a/Tlc5940.cpp +++ b/Tlc5940.cpp @@ -19,14 +19,9 @@ /** \file Tlc5940 class functions. */ -#include -#include - -#include "tlc_config.h" #include "Tlc5940.h" +#include "pinouts/pin_functions.h" -/** Pulses a pin - high then low. */ -#define pulse_pin(port, pin) port |= _BV(pin); port &= ~_BV(pin) /** This will be true (!= 0) if update was just called and the data has not been latched in yet. */ @@ -58,7 +53,7 @@ uint8_t tlc_GSData[NUM_TLCS * 24]; static uint8_t firstGSInput; /** Interrupt called after an XLAT pulse to prevent more XLAT pulses. */ -ISR(TIMER1_OVF_vect) +static inline void Tlc5940_interrupt(void) { disable_XLAT_pulses(); clear_XLAT_interrupt(); @@ -69,6 +64,12 @@ ISR(TIMER1_OVF_vect) } } +#if defined(__AVR__) +ISR(TIMER1_OVF_vect) { Tlc5940_interrupt(); } +#elif defined(__avr__) && defined(TEENSYDUINO) + +#endif + /** \defgroup ReqVPRG_ENABLED Functions that Require VPRG_ENABLED Functions that require VPRG_ENABLED == 1. You can enable VPRG by changing @@ -92,18 +93,18 @@ ISR(TIMER1_OVF_vect) void Tlc5940::init(uint16_t initialValue) { /* Pin Setup */ - XLAT_DDR |= _BV(XLAT_PIN); - BLANK_DDR |= _BV(BLANK_PIN); - GSCLK_DDR |= _BV(GSCLK_PIN); + output_pin(XLAT_DDR, XLAT_PIN); + output_pin(BLANK_DDR, BLANK_PIN); + output_pin(GSCLK_DDR, GSCLK_PIN); #if VPRG_ENABLED - VPRG_DDR |= _BV(VPRG_PIN); - VPRG_PORT &= ~_BV(VPRG_PIN); // grayscale mode (VPRG low) + output_pin(VPRG_DDR, VPRG_PIN); + clear_pin(VPRG_PORT, VPRG_PIN); // grayscale mode (VPRG low) #endif #if XERR_ENABLED XERR_DDR &= ~_BV(XERR_PIN); // XERR as input XERR_PORT |= _BV(XERR_PIN); // enable pull-up resistor #endif - BLANK_PORT |= _BV(BLANK_PIN); // leave blank high (until the timers start) + set_pin(BLANK_PORT, BLANK_PIN); // leave blank high (until the timers start) tlc_shift8_init(); @@ -116,7 +117,7 @@ void Tlc5940::init(uint16_t initialValue) /* Timer Setup */ - +#if defined(__AVR__) /* Timer 1 - BLANK / XLAT */ TCCR1A = _BV(COM1B1); // non inverting, output on OC1B, BLANK TCCR1B = _BV(WGM13); // Phase/freq correct PWM, ICR1 top @@ -150,6 +151,10 @@ void Tlc5940::init(uint16_t initialValue) TCCR2B |= _BV(CS20); // no prescale, (start pwm output) #endif TCCR1B |= _BV(CS10); // no prescale, (start pwm output) + +#elif defined(__avr__) && defined(TEENSYDUINO) + +#endif update(); } @@ -304,9 +309,9 @@ uint8_t Tlc5940::readXERR(void) /** Sets all the bit-bang pins to output */ void tlc_shift8_init(void) { - SIN_DDR |= _BV(SIN_PIN); // SIN as output - SCLK_DDR |= _BV(SCLK_PIN); // SCLK as output - SCLK_PORT &= ~_BV(SCLK_PIN); + output_pin(SIN_DDR, SIN_PIN); // SIN as output + output_pin(SCLK_DDR, SCLK_PIN); // SCLK as output + clear_pin(SCLK_PORT, SCLK_PIN); } /** Shifts a byte out, MSB first */ @@ -314,9 +319,9 @@ void tlc_shift8(uint8_t byte) { for (uint8_t bit = 0x80; bit; bit >>= 1) { if (bit & byte) { - SIN_PORT |= _BV(SIN_PIN); + set_pin(SIN_PORT, SIN_PIN); } else { - SIN_PORT &= ~_BV(SIN_PIN); + clear_pin(SIN_PORT, SIN_PIN); } pulse_pin(SCLK_PORT, SCLK_PIN); } @@ -327,11 +332,11 @@ void tlc_shift8(uint8_t byte) /** Initializes the SPI module to double speed (f_osc / 2) */ void tlc_shift8_init(void) { - SIN_DDR |= _BV(SIN_PIN); // SPI MOSI as output - SCLK_DDR |= _BV(SCLK_PIN); // SPI SCK as output - TLC_SS_DDR |= _BV(TLC_SS_PIN); // SPI SS as output + output_pin(SIN_DDR, SIN_PIN); // SPI MOSI as output + output_pin(SCLK_DDR, SCLK_PIN); // SPI SCK as output + output_pin(TLC_SS_DDR, TLC_SS_PIN); // SPI SS as output - SCLK_PORT &= ~_BV(SCLK_PIN); + clear_pin(SCLK_PORT, SCLK_PIN); SPSR = _BV(SPI2X); // double speed (f_osc / 2) SPCR = _BV(SPE) // enable SPI @@ -356,13 +361,13 @@ void tlc_dcModeStart(void) disable_XLAT_pulses(); // ensure that no latches happen clear_XLAT_interrupt(); // (in case this was called right after update) tlc_needXLAT = 0; - VPRG_PORT |= _BV(VPRG_PIN); // dot correction mode + set_pin(VPRG_PORT, VPRG_PIN); // dot correction mode } /** Switches back to grayscale mode. */ void tlc_dcModeStop(void) { - VPRG_PORT &= ~_BV(VPRG_PIN); // back to grayscale mode + clear_pin(VPRG_PORT, VPRG_PIN); // back to grayscale mode firstGSInput = 1; } diff --git a/Tlc5940.h b/Tlc5940.h index 9b5ae0e..7e30a30 100644 --- a/Tlc5940.h +++ b/Tlc5940.h @@ -22,9 +22,10 @@ /** \file Tlc5940 library header file. */ -#include +#include #include "tlc_config.h" +#if defined(__AVR__) #ifdef TLC_ATMEGA_8_H /** Enables the Timer1 Overflow interrupt, which will fire after an XLAT @@ -48,6 +49,19 @@ /** Disables the output of XLAT pulses */ #define disable_XLAT_pulses() TCCR1A = _BV(COM1B1) +#elif defined(__arm__) && defined(TEENSYDUINO) + +#define set_XLAT_interrupt() +#define clear_XLAT_interrupt() +#define enable_XLAT_pulses() +#define disable_XLAT_pulses() + +#endif + + + + + extern volatile uint8_t tlc_needXLAT; extern volatile void (*tlc_onUpdateFinished)(void); extern uint8_t tlc_GSData[NUM_TLCS * 24]; diff --git a/pinouts/Teensy_KinetisK20.h b/pinouts/Teensy_KinetisK20.h new file mode 100644 index 0000000..a9887cf --- /dev/null +++ b/pinouts/Teensy_KinetisK20.h @@ -0,0 +1,38 @@ +#ifndef TLC_Teensy_xxU4_h +#define TLC_Teensy_xxU4_h + +#if DATA_TRANSFER_MODE == TLC_BITBANG +#error "If you want bitbang mode, insert pin defs here" +#endif + +// MOSI (Teensy pin 11) -> SIN (TLC pin 26) +#define TLC_MOSI_PIN 11 +#define TLC_MOSI_PORT 11 +#define TLC_MOSI_DDR 11 + +// SCK (Teensy pin 13) -> SCLK (TLC pin 25) +#define TLC_SCK_PIN 13 +#define TLC_SCK_PORT 13 +#define TLC_SCK_DDR 13 + +// SS (Teensy pin 10) +#define TLC_SS_PIN 10 +#define TLC_SS_DDR 10 + +// FTM1_CH0 (Teensy pin 3) -> XLAT (TLC pin 24) +#define XLAT_PIN 3 +#define XLAT_PORT 3 +#define XLAT_DDR 3 + +// FTM1_CH1 (Teensy pin 4) -> BLANK (TLC pin 23) +#define BLANK_PIN 4 +#define BLANK_PORT 4 +#define BLANK_DDR 4 + +// CMTOUT (Teensy pin 5) -> GSCLK (TLC pin 18) +#define GSCLK_PIN 5 +#define GSCLK_PORT 5 +#define GSCLK_DDR 5 + +#endif + diff --git a/pinouts/chip_includes.h b/pinouts/chip_includes.h index 7dc1a6f..fea47ab 100644 --- a/pinouts/chip_includes.h +++ b/pinouts/chip_includes.h @@ -22,7 +22,9 @@ /** \file Includes the chip-specfic defaults and pin definitions. */ +#ifdef __AVR__ #include +#endif #ifndef PB0 #define PB0 PORTB0 @@ -110,6 +112,13 @@ /* Teensy++ 2.0 */ #include "Teensypp_xxx6.h" +#elif defined (__MK20DX128__) \ + || defined (__MK20DX256__) + +/* Teensy 3.0 & 3.1 */ +#include "Teensy_KinetisK20.h" + + #else #error "Unknown Chip!" #endif diff --git a/pinouts/pin_functions.h b/pinouts/pin_functions.h new file mode 100644 index 0000000..5a716a1 --- /dev/null +++ b/pinouts/pin_functions.h @@ -0,0 +1,24 @@ +#ifndef TLC_pin_functions_h +#define TLC_pin_functions_h + +#if defined(__AVR__) + #define pulse_pin(port, pin) port |= _BV(pin); port &= ~_BV(pin) + #define set_pin(port, pin) port |= _BV(pin) + #define clear_pin(port, pin) port &= ~_BV(pin) + #define output_pin(ddr, pin) ddr |= _BV(pin) + #define pullup_pin(ddr, port, pin) ddr &= ~_BV(pin); port |= _BV(pin) +#elif defined(TEENSYDUINO) + #define pulse_pin(port, pin) digitalWriteFast(pin, LOW); digitalWriteFast(pin, HIGH) + #define set_pin(port, pin) digitalWriteFast(pin, HIGH) + #define clear_pin(port, pin) digitalWriteFast(pin, LOW) + #define output_pin(ddr, pin) pinMode(pin, OUTPUT) + #define pullup_pin(ddr, port, pin) pinMode(pin, INPUT_PULLUP) +#else + #define pulse_pin(port, pin) digitalWrite(pin, LOW); digitalWrite(pin, HIGH) + #define set_pin(port, pin) digitalWrite(pin, HIGH) + #define clear_pin(port, pin) digitalWrite(pin, LOW) + #define output_pin(ddr, pin) pinMode(pin, OUTPUT) + #define pullup_pin(ddr, port, pin) pinMode(pin, INPUT_PULLUP) +#endif + +#endif diff --git a/tlc_progmem_utils.h b/tlc_progmem_utils.h index dd648fb..e87406e 100644 --- a/tlc_progmem_utils.h +++ b/tlc_progmem_utils.h @@ -23,11 +23,8 @@ PROGMEM utility functions for setting grayscale or dot correction data from PROGMEM. See the UsingProgmem Example for an example. */ -#include -#include - -#include "tlc_config.h" #include "Tlc5940.h" +#include "pinouts/pin_functions.h" void tlc_setGSfromProgmem(prog_uint8_t *gsArray); #if VPRG_ENABLED @@ -115,8 +112,7 @@ void tlc_setDCfromProgmem(prog_uint8_t *dcArray) while (p < dcArrayEnd) { tlc_shift8(pgm_read_byte(p++)); } - XLAT_PORT |= _BV(XLAT_PIN); - XLAT_PORT &= ~_BV(XLAT_PIN); + pulse_pin(XLAT_PORT, XLAT_PIN); tlc_dcModeStop(); }