Browse Source

Initial support for Teensy-LC

main
PaulStoffregen 9 years ago
parent
commit
9b8d74c089
20 changed files with 1722 additions and 303 deletions
  1. +9
    -1
      teensy3/HardwareSerial.h
  2. +20
    -2
      teensy3/IntervalTimer.cpp
  3. +13
    -1
      teensy3/IntervalTimer.h
  4. +7
    -2
      teensy3/SPIFIFO.h
  5. +23
    -98
      teensy3/Tone.cpp
  6. +66
    -10
      teensy3/analog.c
  7. +329
    -42
      teensy3/avr_emulation.h
  8. +315
    -7
      teensy3/core_pins.h
  9. +224
    -1
      teensy3/kinetis.h
  10. +136
    -14
      teensy3/mk20dx128.c
  11. +110
    -0
      teensy3/mkl26z64.ld
  12. +53
    -9
      teensy3/pins_arduino.h
  13. +255
    -101
      teensy3/pins_teensy.c
  14. +49
    -0
      teensy3/ser_print.c
  15. +11
    -0
      teensy3/ser_print.h
  16. +56
    -3
      teensy3/serial1.c
  17. +6
    -0
      teensy3/serial2.c
  18. +6
    -0
      teensy3/serial3.c
  19. +29
    -7
      teensy3/touch.c
  20. +5
    -5
      teensy3/usb_dev.c

+ 9
- 1
teensy3/HardwareSerial.h View File

// bit7: actual data goes into 9th bit // bit7: actual data goes into 9th bit




#if defined(KINETISK)
#define BAUD2DIV(baud) (((F_CPU * 2) + ((baud) >> 1)) / (baud)) #define BAUD2DIV(baud) (((F_CPU * 2) + ((baud) >> 1)) / (baud))
#define BAUD2DIV2(baud) (((F_CPU * 2) + ((baud) >> 1)) / (baud))
#define BAUD2DIV3(baud) (((F_BUS * 2) + ((baud) >> 1)) / (baud)) #define BAUD2DIV3(baud) (((F_BUS * 2) + ((baud) >> 1)) / (baud))
#elif defined(KINETISL)
#define BAUD2DIV(baud) (((F_PLL / 2 / 16) + ((baud) >> 1)) / (baud))
#define BAUD2DIV2(baud) (((F_BUS / 16) + ((baud) >> 1)) / (baud))
#define BAUD2DIV3(baud) (((F_BUS / 16) + ((baud) >> 1)) / (baud))
#endif



// C language implementation // C language implementation
// //
class HardwareSerial2 : public HardwareSerial class HardwareSerial2 : public HardwareSerial
{ {
public: public:
virtual void begin(uint32_t baud) { serial2_begin(BAUD2DIV(baud)); }
virtual void begin(uint32_t baud) { serial2_begin(BAUD2DIV2(baud)); }
virtual void begin(uint32_t baud, uint32_t format) { virtual void begin(uint32_t baud, uint32_t format) {
serial2_begin(BAUD2DIV(baud)); serial2_begin(BAUD2DIV(baud));
serial2_format(format); } serial2_format(format); }

+ 20
- 2
teensy3/IntervalTimer.cpp View File

// so that they can auto-clear themselves and so the user can // so that they can auto-clear themselves and so the user can
// specify a custom ISR and reassign it as needed // specify a custom ISR and reassign it as needed
// ------------------------------------------------------------ // ------------------------------------------------------------
#if defined(KINETISK)
void pit0_isr() { PIT_TFLG0 = 1; IntervalTimer::PIT_ISR[0](); } void pit0_isr() { PIT_TFLG0 = 1; IntervalTimer::PIT_ISR[0](); }
void pit1_isr() { PIT_TFLG1 = 1; IntervalTimer::PIT_ISR[1](); } void pit1_isr() { PIT_TFLG1 = 1; IntervalTimer::PIT_ISR[1](); }
void pit2_isr() { PIT_TFLG2 = 1; IntervalTimer::PIT_ISR[2](); } void pit2_isr() { PIT_TFLG2 = 1; IntervalTimer::PIT_ISR[2](); }
void pit3_isr() { PIT_TFLG3 = 1; IntervalTimer::PIT_ISR[3](); } void pit3_isr() { PIT_TFLG3 = 1; IntervalTimer::PIT_ISR[3](); }


#elif defined(KINETISL)
void pit_isr() {
if (PIT_TFLG0) { PIT_TFLG0 = 1; IntervalTimer::PIT_ISR[0](); }
if (!IntervalTimer::PIT_enabled) return;
if (PIT_TFLG1) { PIT_TFLG1 = 1; IntervalTimer::PIT_ISR[1](); }
}
#endif





// ------------------------------------------------------------ // ------------------------------------------------------------
// point to the correct registers // point to the correct registers
PIT_LDVAL = &PIT_LDVAL0 + PIT_id * 4; PIT_LDVAL = &PIT_LDVAL0 + PIT_id * 4;
PIT_TCTRL = &PIT_TCTRL0 + PIT_id * 4; PIT_TCTRL = &PIT_TCTRL0 + PIT_id * 4;
IRQ_PIT_CH = IRQ_PIT_CH0 + PIT_id;
// point to the correct PIT ISR // point to the correct PIT ISR
PIT_ISR[PIT_id] = myISR; PIT_ISR[PIT_id] = myISR;
*PIT_TCTRL = 0; *PIT_TCTRL = 0;
*PIT_LDVAL = newValue; *PIT_LDVAL = newValue;
*PIT_TCTRL = 3; *PIT_TCTRL = 3;
#if defined(KINETISK)
IRQ_PIT_CH = IRQ_PIT_CH0 + PIT_id;
NVIC_SET_PRIORITY(IRQ_PIT_CH, nvic_priority); NVIC_SET_PRIORITY(IRQ_PIT_CH, nvic_priority);
NVIC_ENABLE_IRQ(IRQ_PIT_CH); NVIC_ENABLE_IRQ(IRQ_PIT_CH);
#elif defined(KINETISL)
NVIC_SET_PRIORITY(IRQ_PIT, nvic_priority); // TODO: use the higher of both channels, shared irq
NVIC_ENABLE_IRQ(IRQ_PIT);
#endif


} }


void IntervalTimer::stop_PIT() { void IntervalTimer::stop_PIT() {
// disable interrupt and PIT // disable interrupt and PIT
NVIC_DISABLE_IRQ(IRQ_PIT_CH);
*PIT_TCTRL = 0; *PIT_TCTRL = 0;
#if defined(KINETISK)
NVIC_DISABLE_IRQ(IRQ_PIT_CH);
#elif defined(KINETISL)
NVIC_DISABLE_IRQ(IRQ_PIT);
#endif
// free PIT for future use // free PIT for future use
PIT_used[PIT_id] = false; PIT_used[PIT_id] = false;

+ 13
- 1
teensy3/IntervalTimer.h View File

typedef void (*ISR)(); typedef void (*ISR)();
typedef volatile uint32_t* reg; typedef volatile uint32_t* reg;
enum {TIMER_OFF, TIMER_PIT}; enum {TIMER_OFF, TIMER_PIT};
#if defined(KINETISK)
static const uint8_t NUM_PIT = 4; static const uint8_t NUM_PIT = 4;
#elif defined(KINETISL)
static const uint8_t NUM_PIT = 2;
#endif
static const uint32_t MAX_PERIOD = UINT32_MAX / (F_BUS / 1000000.0); static const uint32_t MAX_PERIOD = UINT32_MAX / (F_BUS / 1000000.0);
static void enable_PIT(); static void enable_PIT();
static void disable_PIT(); static void disable_PIT();
static bool PIT_enabled; static bool PIT_enabled;
static bool PIT_used[NUM_PIT]; static bool PIT_used[NUM_PIT];
static ISR PIT_ISR[NUM_PIT];
bool allocate_PIT(uint32_t newValue); bool allocate_PIT(uint32_t newValue);
void start_PIT(uint32_t newValue); void start_PIT(uint32_t newValue);
void stop_PIT(); void stop_PIT();
nvic_priority = n; nvic_priority = n;
if (PIT_enabled) NVIC_SET_PRIORITY(IRQ_PIT_CH, n); if (PIT_enabled) NVIC_SET_PRIORITY(IRQ_PIT_CH, n);
} }
static ISR PIT_ISR[NUM_PIT];
#if defined(KINETISK)
friend void pit0_isr();
friend void pit1_isr();
friend void pit2_isr();
friend void pit3_isr();
#elif defined(KINETISL)
friend void pit_isr();
#endif
}; };





+ 7
- 2
teensy3/SPIFIFO.h View File



#include "avr_emulation.h" #include "avr_emulation.h"


#ifdef KINETISK

#if F_BUS == 60000000 #if F_BUS == 60000000
#define HAS_SPIFIFO #define HAS_SPIFIFO
#define SPI_CLOCK_24MHz (SPI_CTAR_PBR(1) | SPI_CTAR_BR(0) | SPI_CTAR_DBR) //(60 / 3) * ((1+1)/2) = 20 MHz #define SPI_CLOCK_24MHz (SPI_CTAR_PBR(1) | SPI_CTAR_BR(0) | SPI_CTAR_DBR) //(60 / 3) * ((1+1)/2) = 20 MHz
#define SPI_CLOCK_6MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(0) | SPI_CTAR_DBR) //(4 / 2) * ((1+1)/2) = 1 MHz #define SPI_CLOCK_6MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(0) | SPI_CTAR_DBR) //(4 / 2) * ((1+1)/2) = 1 MHz
#define SPI_CLOCK_4MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(0) | SPI_CTAR_DBR) //(4 / 2) * ((1+1)/2) = 1 MHz #define SPI_CLOCK_4MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(0) | SPI_CTAR_DBR) //(4 / 2) * ((1+1)/2) = 1 MHz


#endif
#endif // F_BUS

#endif // KINETISK


/* /*
#! /usr/bin/perl #! /usr/bin/perl
}; };
extern SPIFIFOclass SPIFIFO; extern SPIFIFOclass SPIFIFO;


#endif
#endif // HAS_SPIFIFO

#endif #endif

+ 23
- 98
teensy3/Tone.cpp View File

#include "HardwareSerial.h" #include "HardwareSerial.h"
#include "IntervalTimer.h" #include "IntervalTimer.h"


#if 1
// IntervalTimer based tone. This allows tone() to share the timers with other // IntervalTimer based tone. This allows tone() to share the timers with other
// libraries, rather than permanently hogging one PIT timer even for projects // libraries, rather than permanently hogging one PIT timer even for projects
// which never use tone(). Someday this single-tone implementation might be // which never use tone(). Someday this single-tone implementation might be


void tone_interrupt(void); void tone_interrupt(void);


#if defined(KINETISK)
#define TONE_CLEAR_PIN tone_reg[0] = 1
#define TONE_TOGGLE_PIN tone_reg[128] = 1
#define TONE_OUTPUT_PIN tone_reg[384] = 1

#elif defined(KINETISL)
static uint8_t tone_mask;
#define TONE_CLEAR_PIN tone_reg[0] = tone_mask
#define TONE_TOGGLE_PIN tone_reg[4] = tone_mask
#define TONE_OUTPUT_PIN __disable_irq(); tone_reg[12] |= tone_mask; __enable_irq()

#endif

void tone(uint8_t pin, uint16_t frequency, uint32_t duration) void tone(uint8_t pin, uint16_t frequency, uint32_t duration)
{ {
uint32_t count; uint32_t count;
tone_toggle_count = count; tone_toggle_count = count;
} else { } else {
// same pin, but a new frequency. // same pin, but a new frequency.
tone_reg[0] = 1; // clear pin
TONE_CLEAR_PIN; // clear pin
tone_timer.begin(tone_interrupt, usec); tone_timer.begin(tone_interrupt, usec);
} }
} else { } else {
if (tone_pin < CORE_NUM_DIGITAL) { if (tone_pin < CORE_NUM_DIGITAL) {
tone_reg[0] = 1; // clear pin
TONE_CLEAR_PIN; // clear pin
} }
tone_pin = pin; tone_pin = pin;
tone_reg = portClearRegister(pin); tone_reg = portClearRegister(pin);
tone_reg[0] = 1; // clear pin
tone_reg[384] = 1; // output mode;
#if defined(KINETISL)
tone_mask = digitalPinToBitMask(pin);
#endif
TONE_CLEAR_PIN; // clear pin
TONE_OUTPUT_PIN; // output mode;
*config = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1); *config = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1);
tone_toggle_count = count; tone_toggle_count = count;
tone_timer.begin(tone_interrupt, usec); tone_timer.begin(tone_interrupt, usec);
void tone_interrupt(void) void tone_interrupt(void)
{ {
if (tone_toggle_count) { if (tone_toggle_count) {
tone_reg[128] = 1; // toggle
TONE_TOGGLE_PIN; // toggle
if (tone_toggle_count < 0xFFFFFFFF) tone_toggle_count--; if (tone_toggle_count < 0xFFFFFFFF) tone_toggle_count--;
} else { } else {
tone_timer.end(); tone_timer.end();
tone_reg[0] = 0; // clear
TONE_CLEAR_PIN; // clear
tone_pin = 255; tone_pin = 255;
tone_frequency = 0; tone_frequency = 0;
} }
__disable_irq(); __disable_irq();
if (pin == tone_pin) { if (pin == tone_pin) {
tone_timer.end(); tone_timer.end();
tone_reg[0] = 0; // clear
TONE_CLEAR_PIN; // clear
tone_pin = 255; tone_pin = 255;
tone_frequency = 0; tone_frequency = 0;
} }
__enable_irq(); __enable_irq();
} }
#endif



#if 0
// Old PIT timer based tone(). This implementation is slightly more efficient,
// but it consumes one of the PIT timers, even for projects which never use tone().

static uint32_t tone_toggle_count;
static volatile uint8_t *tone_reg;
static uint8_t tone_pin;

void init_tone(void)
{
if (SIM_SCGC6 & SIM_SCGC6_PIT) return;
SIM_SCGC6 |= SIM_SCGC6_PIT; // TODO: use bitband for atomic read-mod-write
PIT_MCR = 0;
PIT_TCTRL3 = 0; // disabled
tone_pin = 255;
NVIC_ENABLE_IRQ(IRQ_PIT_CH3);
}

void tone(uint8_t pin, uint16_t frequency, uint32_t duration)
{
uint32_t count, load;
volatile uint32_t *config;

init_tone();
if (pin >= CORE_NUM_DIGITAL) return;
if (duration) {
count = (frequency * duration / 1000) * 2;
} else {
count = 0xFFFFFFFF;
}
load = (F_BUS / 2) / frequency;
config = portConfigRegister(pin);
__disable_irq();
if (pin != tone_pin) {
if (tone_pin < CORE_NUM_DIGITAL) {
tone_reg[0] = 1; // clear pin
}
tone_pin = pin;
tone_reg = portClearRegister(pin);
tone_reg[0] = 1; // clear pin
tone_reg[384] = 1; // output mode;
*config = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1);
}
tone_toggle_count = count;
if (PIT_LDVAL3 != load) {
PIT_TCTRL3 = 0;
PIT_LDVAL3 = load;
PIT_TCTRL3 = 3;
}
__enable_irq();
}

void pit3_isr(void)
{
PIT_TFLG3 = 1;

if (tone_toggle_count) {
tone_reg[128] = 1; // toggle
if (tone_toggle_count < 0xFFFFFFFF) tone_toggle_count--;
} else {
PIT_TCTRL3 = 0;
PIT_LDVAL3 = 0;
tone_reg[0] = 0; // clear
tone_pin = 255;
}
}

void noTone(uint8_t pin)
{
if (pin >= CORE_NUM_DIGITAL) return;
__disable_irq();
if (pin == tone_pin) {
PIT_TCTRL3 = 0;
PIT_LDVAL3 = 0;
tone_reg[0] = 0; // clear
tone_pin = 255;
}
__enable_irq();
}
#endif













+ 66
- 10
teensy3/analog.c View File

{ {
uint32_t num; uint32_t num;


#if defined(__MK20DX128__) || defined(__MK20DX256__)
VREF_TRM = 0x60; VREF_TRM = 0x60;
VREF_SC = 0xE1; // enable 1.2 volt ref VREF_SC = 0xE1; // enable 1.2 volt ref
#endif


if (analog_config_bits == 8) { if (analog_config_bits == 8) {
ADC0_CFG1 = ADC_CFG1_8BIT + ADC_CFG1_MODE(0); ADC0_CFG1 = ADC_CFG1_8BIT + ADC_CFG1_MODE(0);
#endif #endif
} }


#if defined(__MK20DX128__)
if (analog_reference_internal) {
ADC0_SC2 = ADC_SC2_REFSEL(1); // 1.2V ref
} else {
ADC0_SC2 = ADC_SC2_REFSEL(0); // vcc/ext ref
}
#elif defined(__MK20DX256__)
if (analog_reference_internal) { if (analog_reference_internal) {
ADC0_SC2 = ADC_SC2_REFSEL(1); // 1.2V ref ADC0_SC2 = ADC_SC2_REFSEL(1); // 1.2V ref
#if defined(__MK20DX256__)
ADC1_SC2 = ADC_SC2_REFSEL(1); // 1.2V ref ADC1_SC2 = ADC_SC2_REFSEL(1); // 1.2V ref
#endif
} else { } else {
ADC0_SC2 = ADC_SC2_REFSEL(0); // vcc/ext ref ADC0_SC2 = ADC_SC2_REFSEL(0); // vcc/ext ref
#if defined(__MK20DX256__)
ADC1_SC2 = ADC_SC2_REFSEL(0); // vcc/ext ref ADC1_SC2 = ADC_SC2_REFSEL(0); // vcc/ext ref
#endif
} }
#elif defined(__MKL26Z64__)
if (analog_reference_internal) {
ADC0_SC2 = ADC_SC2_REFSEL(0); // external AREF
} else {
ADC0_SC2 = ADC_SC2_REFSEL(1); // vcc
}
#endif


num = analog_num_average; num = analog_num_average;
if (num <= 1) { if (num <= 1) {
// VREFH/VREFL - connected as the primary reference option // VREFH/VREFL - connected as the primary reference option
// 1.2 V VREF_OUT - connected as the VALT reference option // 1.2 V VREF_OUT - connected as the VALT reference option


#if defined(__MK20DX128__) || defined(__MK20DX256__)
#define DEFAULT 0 #define DEFAULT 0
#define INTERNAL 2 #define INTERNAL 2
#define INTERNAL1V2 2 #define INTERNAL1V2 2
#define INTERNAL1V1 2 #define INTERNAL1V1 2
#define EXTERNAL 0 #define EXTERNAL 0


#elif defined(__MKL26Z64__)
#define DEFAULT 0
#define INTERNAL 0
#define EXTERNAL 1
#endif

void analogReference(uint8_t type) void analogReference(uint8_t type)
{ {
if (type) { if (type) {
// A19 30 C11 ADC1_SE7b 7 // A19 30 C11 ADC1_SE7b 7
// A20 31 E0 ADC1_SE4a 4+64 // A20 31 E0 ADC1_SE4a 4+64
}; };
#elif defined(__MKL26Z64__)
static const uint8_t channel2sc1a[] = {
5, 14, 8, 9, 13, 12, 6, 7, 15, 11,
0, 4+64, 23
};





#endif #endif




//serial_phex(pin); //serial_phex(pin);
//serial_print(" "); //serial_print(" ");


#if defined(__MK20DX128__)
if (pin <= 13) {
index = pin; // 0-13 refer to A0-A13
} else if (pin <= 23) {
index = pin - 14; // 14-23 are A0-A9
} else if (pin >= 34 && pin <= 40) {
index = pin - 24; // 34-37 are A10-A13, 38 is temp sensor,
// 39 is vref, 40 is unused analog pin
} else {
return 0;
}
#elif defined(__MK20DX256__)
if (pin <= 13) { if (pin <= 13) {
index = pin; // 0-13 refer to A0-A13 index = pin; // 0-13 refer to A0-A13
} else if (pin <= 23) { } else if (pin <= 23) {
index = pin - 14; // 14-23 are A0-A9 index = pin - 14; // 14-23 are A0-A9
#if defined(__MK20DX256__)
} else if (pin >= 26 && pin <= 31) { } else if (pin >= 26 && pin <= 31) {
index = pin - 9; // 26-31 are A15-A20 index = pin - 9; // 26-31 are A15-A20
#endif
} else if (pin >= 34 && pin <= 40) { } else if (pin >= 34 && pin <= 40) {
index = pin - 24; // 34-37 are A10-A13, 38 is temp sensor,
// 39 is vref, 40 is unused (A14 on Teensy 3.1)
index = pin - 24; // 34-37 are A10-A13, 38 is temp sensor,
// 39 is vref, 40 is A14
} else { } else {
return 0; // all others are invalid
return 0;
} }
#elif defined(__MKL26Z64__)
if (pin <= 12) {
index = pin; // 0-12 refer to A0-A12
} else if (pin >= 14 && pin <= 26) {
index = pin - 14; // 14-26 are A0-A12
} else {
return 0;
}

#endif


//serial_phex(index); //serial_phex(index);
//serial_print(" "); //serial_print(" ");
__disable_irq(); __disable_irq();
startADC0: startADC0:
//serial_print("startADC0\n"); //serial_print("startADC0\n");
#if defined(__MKL26Z64__)
if (channel & 0x40) {
ADC0_CFG2 &= ~ADC_CFG2_MUXSEL;
channel &= 0x3F;
} else {
ADC0_CFG2 |= ADC_CFG2_MUXSEL;
}
#endif
ADC0_SC1A = channel; ADC0_SC1A = channel;
analogReadBusyADC0 = 1; analogReadBusyADC0 = 1;
__enable_irq(); __enable_irq();

+ 329
- 42
teensy3/avr_emulation.h View File

#ifdef __cplusplus #ifdef __cplusplus


#define GPIO_BITBAND_ADDR(reg, bit) (((uint32_t)&(reg) - 0x40000000) * 32 + (bit) * 4 + 0x42000000) #define GPIO_BITBAND_ADDR(reg, bit) (((uint32_t)&(reg) - 0x40000000) * 32 + (bit) * 4 + 0x42000000)
#define GPIO_BITBAND(reg, bit) (*(uint32_t *)GPIO_BITBAND_ADDR((reg), (bit)))
#define CONFIG_PULLUP (PORT_PCR_MUX(1) | PORT_PCR_PE | PORT_PCR_PS) #define CONFIG_PULLUP (PORT_PCR_MUX(1) | PORT_PCR_PE | PORT_PCR_PS)
#define CONFIG_NOPULLUP (PORT_PCR_MUX(1)) #define CONFIG_NOPULLUP (PORT_PCR_MUX(1))


#if defined(KINETISK)
// bitband addressing for atomic access to data direction register
#define GPIO_SETBIT_ATOMIC(reg, bit) (*(uint32_t *)GPIO_BITBAND_ADDR((reg), (bit)) = 1)
#define GPIO_CLRBIT_ATOMIC(reg, bit) (*(uint32_t *)GPIO_BITBAND_ADDR((reg), (bit)) = 0)
#elif defined(KINETISL)
// bit manipulation engine for atomic access to data direction register
#define GPIO_SETBIT_ATOMIC(reg, bit) (*(uint32_t *)(((uint32_t)&(reg) - 0xF8000000) | 0x480FF000) = 1 << (bit))
#define GPIO_CLRBIT_ATOMIC(reg, bit) (*(uint32_t *)(((uint32_t)&(reg) - 0xF8000000) | 0x440FF000) = ~(1 << (bit)))
#endif


class PORTDemulation class PORTDemulation
{ {
public: public:
} }
private: private:
inline void set0() __attribute__((always_inline)) { inline void set0() __attribute__((always_inline)) {
GPIO_BITBAND(CORE_PIN0_DDRREG, CORE_PIN0_BIT) = 1;
GPIO_SETBIT_ATOMIC(CORE_PIN0_DDRREG, CORE_PIN0_BIT);
CORE_PIN0_CONFIG = CONFIG_PULLUP; CORE_PIN0_CONFIG = CONFIG_PULLUP;
} }
inline void set1() __attribute__((always_inline)) { inline void set1() __attribute__((always_inline)) {
GPIO_BITBAND(CORE_PIN1_DDRREG, CORE_PIN1_BIT) = 1;
GPIO_SETBIT_ATOMIC(CORE_PIN1_DDRREG, CORE_PIN1_BIT);
CORE_PIN1_CONFIG = CONFIG_PULLUP; CORE_PIN1_CONFIG = CONFIG_PULLUP;
} }
inline void set2() __attribute__((always_inline)) { inline void set2() __attribute__((always_inline)) {
GPIO_BITBAND(CORE_PIN2_DDRREG, CORE_PIN2_BIT) = 1;
GPIO_SETBIT_ATOMIC(CORE_PIN2_DDRREG, CORE_PIN2_BIT);
CORE_PIN2_CONFIG = CONFIG_PULLUP; CORE_PIN2_CONFIG = CONFIG_PULLUP;
} }
inline void set3() __attribute__((always_inline)) { inline void set3() __attribute__((always_inline)) {
GPIO_BITBAND(CORE_PIN3_DDRREG, CORE_PIN3_BIT) = 1;
GPIO_SETBIT_ATOMIC(CORE_PIN3_DDRREG, CORE_PIN3_BIT);
CORE_PIN3_CONFIG = CONFIG_PULLUP; CORE_PIN3_CONFIG = CONFIG_PULLUP;
} }
inline void set4() __attribute__((always_inline)) { inline void set4() __attribute__((always_inline)) {
GPIO_BITBAND(CORE_PIN4_DDRREG, CORE_PIN4_BIT) = 1;
GPIO_SETBIT_ATOMIC(CORE_PIN4_DDRREG, CORE_PIN4_BIT);
CORE_PIN4_CONFIG = CONFIG_PULLUP; CORE_PIN4_CONFIG = CONFIG_PULLUP;
} }
inline void set5() __attribute__((always_inline)) { inline void set5() __attribute__((always_inline)) {
GPIO_BITBAND(CORE_PIN5_DDRREG, CORE_PIN5_BIT) = 1;
GPIO_SETBIT_ATOMIC(CORE_PIN5_DDRREG, CORE_PIN5_BIT);
CORE_PIN5_CONFIG = CONFIG_PULLUP; CORE_PIN5_CONFIG = CONFIG_PULLUP;
} }
inline void set6() __attribute__((always_inline)) { inline void set6() __attribute__((always_inline)) {
GPIO_BITBAND(CORE_PIN6_DDRREG, CORE_PIN6_BIT) = 1;
GPIO_SETBIT_ATOMIC(CORE_PIN6_DDRREG, CORE_PIN6_BIT);
CORE_PIN6_CONFIG = CONFIG_PULLUP; CORE_PIN6_CONFIG = CONFIG_PULLUP;
} }
inline void set7() __attribute__((always_inline)) { inline void set7() __attribute__((always_inline)) {
GPIO_BITBAND(CORE_PIN7_DDRREG, CORE_PIN7_BIT) = 1;
GPIO_SETBIT_ATOMIC(CORE_PIN7_DDRREG, CORE_PIN7_BIT);
CORE_PIN7_CONFIG = CONFIG_PULLUP; CORE_PIN7_CONFIG = CONFIG_PULLUP;
} }
inline void clr0() __attribute__((always_inline)) { inline void clr0() __attribute__((always_inline)) {
CORE_PIN0_CONFIG = ((CORE_PIN0_PORTREG & CORE_PIN0_BITMASK) CORE_PIN0_CONFIG = ((CORE_PIN0_PORTREG & CORE_PIN0_BITMASK)
? CONFIG_PULLUP : CONFIG_NOPULLUP); ? CONFIG_PULLUP : CONFIG_NOPULLUP);
GPIO_BITBAND(CORE_PIN0_DDRREG, CORE_PIN0_BIT) = 0;
GPIO_CLRBIT_ATOMIC(CORE_PIN0_DDRREG, CORE_PIN0_BIT);
} }
inline void clr1() __attribute__((always_inline)) { inline void clr1() __attribute__((always_inline)) {
CORE_PIN1_CONFIG = ((CORE_PIN1_PORTREG & CORE_PIN1_BITMASK) CORE_PIN1_CONFIG = ((CORE_PIN1_PORTREG & CORE_PIN1_BITMASK)
? CONFIG_PULLUP : CONFIG_NOPULLUP); ? CONFIG_PULLUP : CONFIG_NOPULLUP);
GPIO_BITBAND(CORE_PIN1_DDRREG, CORE_PIN1_BIT) = 0;
GPIO_CLRBIT_ATOMIC(CORE_PIN1_DDRREG, CORE_PIN1_BIT);
} }
inline void clr2() __attribute__((always_inline)) { inline void clr2() __attribute__((always_inline)) {
CORE_PIN2_CONFIG = ((CORE_PIN2_PORTREG & CORE_PIN2_BITMASK) CORE_PIN2_CONFIG = ((CORE_PIN2_PORTREG & CORE_PIN2_BITMASK)
? CONFIG_PULLUP : CONFIG_NOPULLUP); ? CONFIG_PULLUP : CONFIG_NOPULLUP);
GPIO_BITBAND(CORE_PIN2_DDRREG, CORE_PIN2_BIT) = 0;
GPIO_CLRBIT_ATOMIC(CORE_PIN2_DDRREG, CORE_PIN2_BIT);
} }
inline void clr3() __attribute__((always_inline)) { inline void clr3() __attribute__((always_inline)) {
CORE_PIN3_CONFIG = ((CORE_PIN3_PORTREG & CORE_PIN3_BITMASK) CORE_PIN3_CONFIG = ((CORE_PIN3_PORTREG & CORE_PIN3_BITMASK)
? CONFIG_PULLUP : CONFIG_NOPULLUP); ? CONFIG_PULLUP : CONFIG_NOPULLUP);
GPIO_BITBAND(CORE_PIN3_DDRREG, CORE_PIN3_BIT) = 0;
GPIO_CLRBIT_ATOMIC(CORE_PIN3_DDRREG, CORE_PIN3_BIT);
} }
inline void clr4() __attribute__((always_inline)) { inline void clr4() __attribute__((always_inline)) {
CORE_PIN4_CONFIG = ((CORE_PIN4_PORTREG & CORE_PIN4_BITMASK) CORE_PIN4_CONFIG = ((CORE_PIN4_PORTREG & CORE_PIN4_BITMASK)
? CONFIG_PULLUP : CONFIG_NOPULLUP); ? CONFIG_PULLUP : CONFIG_NOPULLUP);
GPIO_BITBAND(CORE_PIN4_DDRREG, CORE_PIN4_BIT) = 0;
GPIO_CLRBIT_ATOMIC(CORE_PIN4_DDRREG, CORE_PIN4_BIT);
} }
inline void clr5() __attribute__((always_inline)) { inline void clr5() __attribute__((always_inline)) {
CORE_PIN5_CONFIG = ((CORE_PIN5_PORTREG & CORE_PIN5_BITMASK) CORE_PIN5_CONFIG = ((CORE_PIN5_PORTREG & CORE_PIN5_BITMASK)
? CONFIG_PULLUP : CONFIG_NOPULLUP); ? CONFIG_PULLUP : CONFIG_NOPULLUP);
GPIO_BITBAND(CORE_PIN5_DDRREG, CORE_PIN5_BIT) = 0;
GPIO_CLRBIT_ATOMIC(CORE_PIN5_DDRREG, CORE_PIN5_BIT);
} }
inline void clr6() __attribute__((always_inline)) { inline void clr6() __attribute__((always_inline)) {
CORE_PIN6_CONFIG = ((CORE_PIN6_PORTREG & CORE_PIN6_BITMASK) CORE_PIN6_CONFIG = ((CORE_PIN6_PORTREG & CORE_PIN6_BITMASK)
? CONFIG_PULLUP : CONFIG_NOPULLUP); ? CONFIG_PULLUP : CONFIG_NOPULLUP);
GPIO_BITBAND(CORE_PIN6_DDRREG, CORE_PIN6_BIT) = 0;
GPIO_CLRBIT_ATOMIC(CORE_PIN6_DDRREG, CORE_PIN6_BIT);
} }
inline void clr7() __attribute__((always_inline)) { inline void clr7() __attribute__((always_inline)) {
CORE_PIN7_CONFIG = ((CORE_PIN7_PORTREG & CORE_PIN7_BITMASK) CORE_PIN7_CONFIG = ((CORE_PIN7_PORTREG & CORE_PIN7_BITMASK)
? CONFIG_PULLUP : CONFIG_NOPULLUP); ? CONFIG_PULLUP : CONFIG_NOPULLUP);
GPIO_BITBAND(CORE_PIN7_DDRREG, CORE_PIN7_BIT) = 0;
GPIO_CLRBIT_ATOMIC(CORE_PIN7_DDRREG, CORE_PIN7_BIT);
} }
}; };


} }
private: private:
inline void set0() __attribute__((always_inline)) { inline void set0() __attribute__((always_inline)) {
GPIO_BITBAND(CORE_PIN8_DDRREG, CORE_PIN8_BIT) = 1;
GPIO_SETBIT_ATOMIC(CORE_PIN8_DDRREG, CORE_PIN8_BIT);
CORE_PIN8_CONFIG = CONFIG_PULLUP; CORE_PIN8_CONFIG = CONFIG_PULLUP;
} }
inline void set1() __attribute__((always_inline)) { inline void set1() __attribute__((always_inline)) {
GPIO_BITBAND(CORE_PIN9_DDRREG, CORE_PIN9_BIT) = 1;
GPIO_SETBIT_ATOMIC(CORE_PIN9_DDRREG, CORE_PIN9_BIT);
CORE_PIN9_CONFIG = CONFIG_PULLUP; CORE_PIN9_CONFIG = CONFIG_PULLUP;
} }
inline void set2() __attribute__((always_inline)) { inline void set2() __attribute__((always_inline)) {
GPIO_BITBAND(CORE_PIN10_DDRREG, CORE_PIN10_BIT) = 1;
GPIO_SETBIT_ATOMIC(CORE_PIN10_DDRREG, CORE_PIN10_BIT);
CORE_PIN10_CONFIG = CONFIG_PULLUP; CORE_PIN10_CONFIG = CONFIG_PULLUP;
} }
inline void set3() __attribute__((always_inline)) { inline void set3() __attribute__((always_inline)) {
GPIO_BITBAND(CORE_PIN11_DDRREG, CORE_PIN11_BIT) = 1;
GPIO_SETBIT_ATOMIC(CORE_PIN11_DDRREG, CORE_PIN11_BIT);
CORE_PIN11_CONFIG = CONFIG_PULLUP; CORE_PIN11_CONFIG = CONFIG_PULLUP;
} }
inline void set4() __attribute__((always_inline)) { inline void set4() __attribute__((always_inline)) {
GPIO_BITBAND(CORE_PIN12_DDRREG, CORE_PIN12_BIT) = 1;
GPIO_SETBIT_ATOMIC(CORE_PIN12_DDRREG, CORE_PIN12_BIT);
CORE_PIN12_CONFIG = CONFIG_PULLUP; CORE_PIN12_CONFIG = CONFIG_PULLUP;
} }
inline void set5() __attribute__((always_inline)) { inline void set5() __attribute__((always_inline)) {
GPIO_BITBAND(CORE_PIN13_DDRREG, CORE_PIN13_BIT) = 1;
GPIO_SETBIT_ATOMIC(CORE_PIN13_DDRREG, CORE_PIN13_BIT);
CORE_PIN13_CONFIG = CONFIG_PULLUP; CORE_PIN13_CONFIG = CONFIG_PULLUP;
} }
inline void clr0() __attribute__((always_inline)) { inline void clr0() __attribute__((always_inline)) {
CORE_PIN8_CONFIG = ((CORE_PIN8_PORTREG & CORE_PIN8_BITMASK) CORE_PIN8_CONFIG = ((CORE_PIN8_PORTREG & CORE_PIN8_BITMASK)
? CONFIG_PULLUP : CONFIG_NOPULLUP); ? CONFIG_PULLUP : CONFIG_NOPULLUP);
GPIO_BITBAND(CORE_PIN8_DDRREG, CORE_PIN8_BIT) = 0;
GPIO_CLRBIT_ATOMIC(CORE_PIN8_DDRREG, CORE_PIN8_BIT);
} }
inline void clr1() __attribute__((always_inline)) { inline void clr1() __attribute__((always_inline)) {
CORE_PIN9_CONFIG = ((CORE_PIN9_PORTREG & CORE_PIN9_BITMASK) CORE_PIN9_CONFIG = ((CORE_PIN9_PORTREG & CORE_PIN9_BITMASK)
? CONFIG_PULLUP : CONFIG_NOPULLUP); ? CONFIG_PULLUP : CONFIG_NOPULLUP);
GPIO_BITBAND(CORE_PIN9_DDRREG, CORE_PIN9_BIT) = 0;
GPIO_CLRBIT_ATOMIC(CORE_PIN9_DDRREG, CORE_PIN9_BIT);
} }
inline void clr2() __attribute__((always_inline)) { inline void clr2() __attribute__((always_inline)) {
CORE_PIN10_CONFIG = ((CORE_PIN10_PORTREG & CORE_PIN10_BITMASK) CORE_PIN10_CONFIG = ((CORE_PIN10_PORTREG & CORE_PIN10_BITMASK)
? CONFIG_PULLUP : CONFIG_NOPULLUP); ? CONFIG_PULLUP : CONFIG_NOPULLUP);
GPIO_BITBAND(CORE_PIN10_DDRREG, CORE_PIN10_BIT) = 0;
GPIO_CLRBIT_ATOMIC(CORE_PIN10_DDRREG, CORE_PIN10_BIT);
} }
inline void clr3() __attribute__((always_inline)) { inline void clr3() __attribute__((always_inline)) {
CORE_PIN11_CONFIG = ((CORE_PIN11_PORTREG & CORE_PIN11_BITMASK) CORE_PIN11_CONFIG = ((CORE_PIN11_PORTREG & CORE_PIN11_BITMASK)
? CONFIG_PULLUP : CONFIG_NOPULLUP); ? CONFIG_PULLUP : CONFIG_NOPULLUP);
GPIO_BITBAND(CORE_PIN11_DDRREG, CORE_PIN11_BIT) = 0;
GPIO_CLRBIT_ATOMIC(CORE_PIN11_DDRREG, CORE_PIN11_BIT);
} }
inline void clr4() __attribute__((always_inline)) { inline void clr4() __attribute__((always_inline)) {
CORE_PIN12_CONFIG = ((CORE_PIN12_PORTREG & CORE_PIN12_BITMASK) CORE_PIN12_CONFIG = ((CORE_PIN12_PORTREG & CORE_PIN12_BITMASK)
? CONFIG_PULLUP : CONFIG_NOPULLUP); ? CONFIG_PULLUP : CONFIG_NOPULLUP);
GPIO_BITBAND(CORE_PIN12_DDRREG, CORE_PIN12_BIT) = 0;
GPIO_CLRBIT_ATOMIC(CORE_PIN12_DDRREG, CORE_PIN12_BIT);
} }
inline void clr5() __attribute__((always_inline)) { inline void clr5() __attribute__((always_inline)) {
CORE_PIN13_CONFIG = ((CORE_PIN13_PORTREG & CORE_PIN13_BITMASK) CORE_PIN13_CONFIG = ((CORE_PIN13_PORTREG & CORE_PIN13_BITMASK)
? CONFIG_PULLUP : CONFIG_NOPULLUP); ? CONFIG_PULLUP : CONFIG_NOPULLUP);
GPIO_BITBAND(CORE_PIN13_DDRREG, CORE_PIN13_BIT) = 0;
GPIO_CLRBIT_ATOMIC(CORE_PIN13_DDRREG, CORE_PIN13_BIT);
} }
}; };


} }
private: private:
inline void set0() __attribute__((always_inline)) { inline void set0() __attribute__((always_inline)) {
GPIO_BITBAND(CORE_PIN14_DDRREG, CORE_PIN14_BIT) = 1;
GPIO_SETBIT_ATOMIC(CORE_PIN14_DDRREG, CORE_PIN14_BIT);
CORE_PIN14_CONFIG = CONFIG_PULLUP; CORE_PIN14_CONFIG = CONFIG_PULLUP;
} }
inline void set1() __attribute__((always_inline)) { inline void set1() __attribute__((always_inline)) {
GPIO_BITBAND(CORE_PIN15_DDRREG, CORE_PIN15_BIT) = 1;
GPIO_SETBIT_ATOMIC(CORE_PIN15_DDRREG, CORE_PIN15_BIT);
CORE_PIN15_CONFIG = CONFIG_PULLUP; CORE_PIN15_CONFIG = CONFIG_PULLUP;
} }
inline void set2() __attribute__((always_inline)) { inline void set2() __attribute__((always_inline)) {
GPIO_BITBAND(CORE_PIN16_DDRREG, CORE_PIN16_BIT) = 1;
GPIO_SETBIT_ATOMIC(CORE_PIN16_DDRREG, CORE_PIN16_BIT);
CORE_PIN16_CONFIG = CONFIG_PULLUP; CORE_PIN16_CONFIG = CONFIG_PULLUP;
} }
inline void set3() __attribute__((always_inline)) { inline void set3() __attribute__((always_inline)) {
GPIO_BITBAND(CORE_PIN17_DDRREG, CORE_PIN17_BIT) = 1;
GPIO_SETBIT_ATOMIC(CORE_PIN17_DDRREG, CORE_PIN17_BIT);
CORE_PIN17_CONFIG = CONFIG_PULLUP; CORE_PIN17_CONFIG = CONFIG_PULLUP;
} }
inline void set4() __attribute__((always_inline)) { inline void set4() __attribute__((always_inline)) {
GPIO_BITBAND(CORE_PIN18_DDRREG, CORE_PIN18_BIT) = 1;
GPIO_SETBIT_ATOMIC(CORE_PIN18_DDRREG, CORE_PIN18_BIT);
CORE_PIN18_CONFIG = CONFIG_PULLUP; CORE_PIN18_CONFIG = CONFIG_PULLUP;
} }
inline void set5() __attribute__((always_inline)) { inline void set5() __attribute__((always_inline)) {
GPIO_BITBAND(CORE_PIN19_DDRREG, CORE_PIN19_BIT) = 1;
GPIO_SETBIT_ATOMIC(CORE_PIN19_DDRREG, CORE_PIN19_BIT);
CORE_PIN19_CONFIG = CONFIG_PULLUP; CORE_PIN19_CONFIG = CONFIG_PULLUP;
} }
inline void clr0() __attribute__((always_inline)) { inline void clr0() __attribute__((always_inline)) {
CORE_PIN14_CONFIG = ((CORE_PIN14_PORTREG & CORE_PIN14_BITMASK) CORE_PIN14_CONFIG = ((CORE_PIN14_PORTREG & CORE_PIN14_BITMASK)
? CONFIG_PULLUP : CONFIG_NOPULLUP); ? CONFIG_PULLUP : CONFIG_NOPULLUP);
GPIO_BITBAND(CORE_PIN14_DDRREG, CORE_PIN14_BIT) = 0;
GPIO_CLRBIT_ATOMIC(CORE_PIN14_DDRREG, CORE_PIN14_BIT);
} }
inline void clr1() __attribute__((always_inline)) { inline void clr1() __attribute__((always_inline)) {
CORE_PIN15_CONFIG = ((CORE_PIN15_PORTREG & CORE_PIN15_BITMASK) CORE_PIN15_CONFIG = ((CORE_PIN15_PORTREG & CORE_PIN15_BITMASK)
? CONFIG_PULLUP : CONFIG_NOPULLUP); ? CONFIG_PULLUP : CONFIG_NOPULLUP);
GPIO_BITBAND(CORE_PIN15_DDRREG, CORE_PIN15_BIT) = 0;
GPIO_CLRBIT_ATOMIC(CORE_PIN15_DDRREG, CORE_PIN15_BIT);
} }
inline void clr2() __attribute__((always_inline)) { inline void clr2() __attribute__((always_inline)) {
CORE_PIN16_CONFIG = ((CORE_PIN16_PORTREG & CORE_PIN16_BITMASK) CORE_PIN16_CONFIG = ((CORE_PIN16_PORTREG & CORE_PIN16_BITMASK)
? CONFIG_PULLUP : CONFIG_NOPULLUP); ? CONFIG_PULLUP : CONFIG_NOPULLUP);
GPIO_BITBAND(CORE_PIN16_DDRREG, CORE_PIN16_BIT) = 0;
GPIO_CLRBIT_ATOMIC(CORE_PIN16_DDRREG, CORE_PIN16_BIT);
} }
inline void clr3() __attribute__((always_inline)) { inline void clr3() __attribute__((always_inline)) {
CORE_PIN17_CONFIG = ((CORE_PIN17_PORTREG & CORE_PIN17_BITMASK) CORE_PIN17_CONFIG = ((CORE_PIN17_PORTREG & CORE_PIN17_BITMASK)
? CONFIG_PULLUP : CONFIG_NOPULLUP); ? CONFIG_PULLUP : CONFIG_NOPULLUP);
GPIO_BITBAND(CORE_PIN17_DDRREG, CORE_PIN17_BIT) = 0;
GPIO_CLRBIT_ATOMIC(CORE_PIN17_DDRREG, CORE_PIN17_BIT);
} }
inline void clr4() __attribute__((always_inline)) { inline void clr4() __attribute__((always_inline)) {
CORE_PIN18_CONFIG = ((CORE_PIN18_PORTREG & CORE_PIN18_BITMASK) CORE_PIN18_CONFIG = ((CORE_PIN18_PORTREG & CORE_PIN18_BITMASK)
? CONFIG_PULLUP : CONFIG_NOPULLUP); ? CONFIG_PULLUP : CONFIG_NOPULLUP);
GPIO_BITBAND(CORE_PIN18_DDRREG, CORE_PIN18_BIT) = 0;
GPIO_CLRBIT_ATOMIC(CORE_PIN18_DDRREG, CORE_PIN18_BIT);
} }
inline void clr5() __attribute__((always_inline)) { inline void clr5() __attribute__((always_inline)) {
CORE_PIN19_CONFIG = ((CORE_PIN19_PORTREG & CORE_PIN19_BITMASK) CORE_PIN19_CONFIG = ((CORE_PIN19_PORTREG & CORE_PIN19_BITMASK)
? CONFIG_PULLUP : CONFIG_NOPULLUP); ? CONFIG_PULLUP : CONFIG_NOPULLUP);
GPIO_BITBAND(CORE_PIN19_DDRREG, CORE_PIN19_BIT) = 0;
GPIO_CLRBIT_ATOMIC(CORE_PIN19_DDRREG, CORE_PIN19_BIT);
} }
}; };


#define SPI2X 0 // SPI2X: Double SPI Speed Bit #define SPI2X 0 // SPI2X: Double SPI Speed Bit
// SPI Data Register ­ SPDR // SPI Data Register ­ SPDR



class SPCRemulation; class SPCRemulation;
class SPSRemulation; class SPSRemulation;
class SPDRemulation; class SPDRemulation;


#if defined(KINETISK)

class SPCRemulation class SPCRemulation
{ {
public: public:
extern SPDRemulation SPDR; extern SPDRemulation SPDR;







#elif defined(KINETISL)

// SPI Control Register ­ SPCR
//#define SPIE 7 // SPI Interrupt Enable - not supported
//#define SPE 6 // SPI Enable
//#define DORD 5 // DORD: Data Order
//#define MSTR 4 // MSTR: Master/Slave Select
//#define CPOL 3 // CPOL: Clock Polarity
//#define CPHA 2 // CPHA: Clock Phase
//#define SPR1 1 // Clock: 3 = 125 kHz, 2 = 250 kHz, 1 = 1 MHz, 0->4 MHz
//#define SPR0 0
// SPI Status Register ­ SPSR
//#define SPIF 7 // SPIF: SPI Interrupt Flag
//#define WCOL 6 // WCOL: Write COLlision Flag - not implemented
//#define SPI2X 0 // SPI2X: Double SPI Speed Bit
// SPI Data Register ­ SPDR


class SPCRemulation
{
public:
inline SPCRemulation & operator = (int val) __attribute__((always_inline)) {
uint32_t sim4 = SIM_SCGC4;
if (!(sim4 & SIM_SCGC4_SPI0)) {
SIM_SCGC4 = sim4 | SIM_SCGC4_SPI0;
SPI0_BR = SPI_BR_SPR(0) | SPI_BR_SPPR(1);
}
uint32_t c1 = 0;
if (val & (1<<DORD)) c1 |= SPI_C1_LSBFE;
if (val & (1<<CPOL)) c1 |= SPI_C1_CPOL;
if (val & (1<<CPHA)) c1 |= SPI_C1_CPHA;
if (val & (1<<MSTR)) c1 |= SPI_C1_MSTR;
if (val & (1<<SPE)) c1 |= SPI_C1_SPE;
SPI0_C1 = c1;
SPI0_C2 = 0;
uint32_t br = SPI0_BR & 0x10;
switch (val & 3) {
case 0: SPI0_BR = br | SPI_BR_SPR(0); break;
case 1: SPI0_BR = br | SPI_BR_SPR(2); break;
case 2: SPI0_BR = br | SPI_BR_SPR(4); break;
default: SPI0_BR = br | SPI_BR_SPR(5); break;
}
if (val & (1<<SPE)) enable_pins();
else disable_pins();
return *this;
}
inline SPCRemulation & operator |= (int val) __attribute__((always_inline)) {
uint32_t sim4 = SIM_SCGC4;
if (!(sim4 & SIM_SCGC4_SPI0)) {
SIM_SCGC4 = sim4 | SIM_SCGC4_SPI0;
SPI0_BR = SPI_BR_SPR(0) | SPI_BR_SPPR(1);
}
uint32_t c1 = SPI0_C1;
if (val & (1<<DORD)) c1 |= SPI_C1_LSBFE;
if (val & (1<<CPOL)) c1 |= SPI_C1_CPOL;
if (val & (1<<CPHA)) c1 |= SPI_C1_CPHA;
if (val & (1<<MSTR)) c1 |= SPI_C1_MSTR;
if (val & (1<<SPE)) {
enable_pins();
c1 |= SPI_C1_SPE;
}
SPI0_C1 = c1;
SPI0_C2 = 0;
val &= 3;
if (val) {
uint32_t br = SPI0_BR;
uint32_t bits = baud2avr(br) | val;
br &= 0x10;
switch (bits) {
case 0: SPI0_BR = br | SPI_BR_SPR(0); break;
case 1: SPI0_BR = br | SPI_BR_SPR(2); break;
case 2: SPI0_BR = br | SPI_BR_SPR(4); break;
default: SPI0_BR = br | SPI_BR_SPR(5); break;
}
}
return *this;
}
inline SPCRemulation & operator &= (int val) __attribute__((always_inline)) {
uint32_t sim4 = SIM_SCGC4;
if (!(sim4 & SIM_SCGC4_SPI0)) {
SIM_SCGC4 = sim4 | SIM_SCGC4_SPI0;
SPI0_BR = SPI_BR_SPR(0) | SPI_BR_SPPR(1);
}
uint32_t c1 = SPI0_C1;
if (!(val & (1<<DORD))) c1 &= ~SPI_C1_LSBFE;
if (!(val & (1<<CPOL))) c1 &= ~SPI_C1_CPOL;
if (!(val & (1<<CPHA))) c1 &= ~SPI_C1_CPHA;
if (!(val & (1<<MSTR))) c1 &= ~SPI_C1_MSTR;
if (!(val & (1<<SPE))) {
disable_pins();
c1 &= ~SPI_C1_SPE;
}
SPI0_C1 = c1;
SPI0_C2 = 0;
val &= 3;
if (val < 3) {
uint32_t br = SPI0_BR;
uint32_t bits = baud2avr(br) & val;
br &= 0x10;
switch (bits) {
case 0: SPI0_BR = br | SPI_BR_SPR(0); break;
case 1: SPI0_BR = br | SPI_BR_SPR(2); break;
case 2: SPI0_BR = br | SPI_BR_SPR(4); break;
default: SPI0_BR = br | SPI_BR_SPR(5); break;
}
}
return *this;
}
inline int operator & (int val) const __attribute__((always_inline)) {
int ret = 0;
uint32_t sim4 = SIM_SCGC4;
if (!(sim4 & SIM_SCGC4_SPI0)) {
SIM_SCGC4 = sim4 | SIM_SCGC4_SPI0;
SPI0_BR = SPI_BR_SPR(0) | SPI_BR_SPPR(1);
}
uint32_t c1 = SPI0_C1;
if ((val & (1<<DORD)) && (c1 & SPI_C1_LSBFE)) ret |= (1<<DORD);
if ((val & (1<<CPOL)) && (c1 & SPI_C1_CPOL)) ret |= (1<<CPOL);
if ((val & (1<<CPHA)) && (c1 & SPI_C1_CPHA)) ret |= (1<<CPHA);
if ((val & (1<<MSTR)) && (c1 & SPI_C1_MSTR)) ret |= (1<<MSTR);
if ((val & (1<<SPE)) && (c1 & SPI_C1_SPE)) ret |= (1<<SPE);
uint32_t bits = baud2avr(SPI0_BR);
if ((val & (1<<SPR1)) && (bits & (1<<SPR1))) ret |= (1<<SPR1);
if ((val & (1<<SPR0)) && (bits & (1<<SPR0))) ret |= (1<<SPR0);
return ret;
}
operator int () const __attribute__((always_inline)) {
int ret = 0;
uint32_t sim4 = SIM_SCGC4;
if (!(sim4 & SIM_SCGC4_SPI0)) {
SIM_SCGC4 = sim4 | SIM_SCGC4_SPI0;
SPI0_BR = SPI_BR_SPR(0) | SPI_BR_SPPR(1);
}
uint32_t c1 = SPI0_C1;
if ((c1 & SPI_C1_LSBFE)) ret |= (1<<DORD);
if ((c1 & SPI_C1_CPOL)) ret |= (1<<CPOL);
if ((c1 & SPI_C1_CPHA)) ret |= (1<<CPHA);
if ((c1 & SPI_C1_MSTR)) ret |= (1<<MSTR);
if ((c1 & SPI_C1_SPE)) ret |= (1<<SPE);
ret |= baud2avr(SPI0_BR);
return ret;
}
inline void setMOSI(uint8_t pin) __attribute__((always_inline)) {
}
inline void setMISO(uint8_t pin) __attribute__((always_inline)) {
}
inline void setSCK(uint8_t pin) __attribute__((always_inline)) {
}
friend class SPSRemulation;
friend class SPIFIFOclass;
private:
static inline uint32_t baud2avr(uint32_t br) __attribute__((always_inline)) {
br &= 15;
if (br == 0) return 0;
if (br <= 2) return 1;
if (br <= 4) return 2;
return 3;
}
static uint8_t pinout;
public:
inline void enable_pins(void) __attribute__((always_inline)) {
//serial_print("enable_pins\n");
CORE_PIN11_CONFIG = PORT_PCR_MUX(2); // MOSI = 11 (PTC6)
CORE_PIN12_CONFIG = PORT_PCR_MUX(2); // MISO = 12 (PTC7)
CORE_PIN13_CONFIG = PORT_PCR_MUX(2); // SCK = 13 (PTC5)
}
inline void disable_pins(void) __attribute__((always_inline)) {
//serial_print("disable_pins\n");
CORE_PIN11_CONFIG = PORT_PCR_SRE | PORT_PCR_MUX(1);
CORE_PIN12_CONFIG = PORT_PCR_SRE | PORT_PCR_MUX(1);
CORE_PIN13_CONFIG = PORT_PCR_SRE | PORT_PCR_MUX(1);
}
};
extern SPCRemulation SPCR;


class SPSRemulation
{
public:
inline SPSRemulation & operator = (int val) __attribute__((always_inline)) {
if (val & (1<<SPI2X)) {
SPI0_BR &= ~0x10;
} else {
SPI0_BR |= 0x10;
}
return *this;
}
inline SPSRemulation & operator |= (int val) __attribute__((always_inline)) {
if (val & (1<<SPI2X)) SPI0_BR &= ~0x10;
return *this;
}
inline SPSRemulation & operator &= (int val) __attribute__((always_inline)) {
if (!(val & (1<<SPI2X))) SPI0_BR |= 0x10;
return *this;
}
inline int operator & (int val) const __attribute__((always_inline)) {
int ret = 0;
if ((val & (1<<SPIF)) && (SPI0_S & SPI_S_SPRF)) ret = (1<<SPIF);
if ((val & (1<<SPI2X)) && (!(SPI0_BR & 0x10))) ret |= (1<<SPI2X);
return ret;
}
operator int () const __attribute__((always_inline)) {
int ret = 0;
if ((SPI0_S & SPI_S_SPRF)) ret = (1<<SPIF);
if (!(SPI0_BR & 0x10)) ret |= (1<<SPI2X);
return ret;
}
};
extern SPSRemulation SPSR;


class SPDRemulation
{
public:
inline SPDRemulation & operator = (int val) __attribute__((always_inline)) {
if ((SPI0_S & SPI_S_SPTEF)) {
uint32_t tmp __attribute__((unused)) = SPI0_DL;
}
SPI0_DL = val;
return *this;
}
operator int () const __attribute__((always_inline)) {
return SPI0_DL & 255;
}
};
extern SPDRemulation SPDR;


#endif // KINETISK








class SREGemulation class SREGemulation
{ {
public: public:
// 84062840 // 84062840
// 322111 // 322111
// 17395173 // 17395173
#if defined(__MK20DX128__) || defined(__MK20DX256__)
#define EIMSK_pA 0x01000018 // pins 3, 4, 24 #define EIMSK_pA 0x01000018 // pins 3, 4, 24
#define EIMSK_pB 0x020F0003 // pins 0, 1, 16-19, 25 #define EIMSK_pB 0x020F0003 // pins 0, 1, 16-19, 25
#define EIMSK_pC 0x78C0BE00 // pins 9-13, 15, 22, 23, 27-30 #define EIMSK_pC 0x78C0BE00 // pins 9-13, 15, 22, 23, 27-30
}; };
extern EIMSKemulation EIMSK; extern EIMSKemulation EIMSK;


#elif defined(__MKL26Z64__)

#define EIMSK_pA 0x00000018 // pins 3, 4, 24
#define EIMSK_pC 0x00C0BE00 // pins 9-13, 15, 22, 23
#define EIMSK_pD 0x003041E4 // pins 2, 5-8, 14, 20, 21

class EIMSKemulation // used by Adafruit_nRF8001
{
public:
operator int () const __attribute__((always_inline)) {
int mask = 0;
volatile const uint32_t *icer = &NVIC_ICER0;
if (icer[IRQ_PORTA >> 5] & (1 << (IRQ_PORTA & 31))) mask |= EIMSK_pA;
if (icer[IRQ_PORTCD >> 5] & (1 << (IRQ_PORTCD & 31))) mask |= (EIMSK_pC | EIMSK_pD);
return mask;
}
inline EIMSKemulation & operator |= (int val) __attribute__((always_inline)) {
if (val & EIMSK_pA) NVIC_ENABLE_IRQ(IRQ_PORTA);
if (val & (EIMSK_pC | EIMSK_pD)) NVIC_ENABLE_IRQ(IRQ_PORTCD);
return *this;
}
inline EIMSKemulation & operator &= (int val) __attribute__((always_inline)) {
uint32_t n = val;
if ((n | ~EIMSK_pA) != 0xFFFFFFFF) NVIC_DISABLE_IRQ(IRQ_PORTA);
if ((n | ~(EIMSK_pC | EIMSK_pD)) != 0xFFFFFFFF) NVIC_DISABLE_IRQ(IRQ_PORTCD);
return *this;
}
};
extern EIMSKemulation EIMSK;

#endif



// these are not intended for public consumption... // these are not intended for public consumption...
#undef GPIO_BITBAND_ADDR #undef GPIO_BITBAND_ADDR
#undef GPIO_BITBAND
#undef CONFIG_PULLUP #undef CONFIG_PULLUP
#undef CONFIG_NOPULLUP #undef CONFIG_NOPULLUP
#undef GPIO_SETBIT_ATOMIC
#undef GPIO_CLRBIT_ATOMIC


#endif // __cplusplus #endif // __cplusplus



+ 315
- 7
teensy3/core_pins.h View File

// A2 FTM0_CH7 SWD Trace // A2 FTM0_CH7 SWD Trace
// A3 FTM0_CH0 SWD Data // A3 FTM0_CH0 SWD Data


#if defined(__MK20DX128__)
#define CORE_NUM_TOTAL_PINS 34 #define CORE_NUM_TOTAL_PINS 34
#define CORE_NUM_DIGITAL 34 #define CORE_NUM_DIGITAL 34
#define CORE_NUM_INTERRUPT 34 #define CORE_NUM_INTERRUPT 34
#if defined(__MK20DX128__)
#define CORE_NUM_ANALOG 14 #define CORE_NUM_ANALOG 14
#define CORE_NUM_PWM 10 #define CORE_NUM_PWM 10
#elif defined(__MK20DX256__) #elif defined(__MK20DX256__)
#define CORE_NUM_TOTAL_PINS 34
#define CORE_NUM_DIGITAL 34
#define CORE_NUM_INTERRUPT 34
#define CORE_NUM_ANALOG 21 #define CORE_NUM_ANALOG 21
#define CORE_NUM_PWM 12 #define CORE_NUM_PWM 12
#elif defined(__MKL26Z64__)
#define CORE_NUM_TOTAL_PINS 27
#define CORE_NUM_DIGITAL 27
#define CORE_NUM_INTERRUPT 18
#define CORE_NUM_ANALOG 13
#define CORE_NUM_PWM 10
#endif #endif


#if defined(__MK20DX128__) || defined(__MK20DX256__)

#define CORE_PIN0_BIT 16 #define CORE_PIN0_BIT 16
#define CORE_PIN1_BIT 17 #define CORE_PIN1_BIT 17
#define CORE_PIN2_BIT 0 #define CORE_PIN2_BIT 0
#define CORE_INT_EVERY_PIN 1 #define CORE_INT_EVERY_PIN 1




#elif defined(__MKL26Z64__)

#define CORE_PIN0_BIT 16
#define CORE_PIN1_BIT 17
#define CORE_PIN2_BIT 0
#define CORE_PIN3_BIT 1
#define CORE_PIN4_BIT 2
#define CORE_PIN5_BIT 7
#define CORE_PIN6_BIT 4
#define CORE_PIN7_BIT 2
#define CORE_PIN8_BIT 3
#define CORE_PIN9_BIT 3
#define CORE_PIN10_BIT 4
#define CORE_PIN11_BIT 6
#define CORE_PIN12_BIT 7
#define CORE_PIN13_BIT 5
#define CORE_PIN14_BIT 1
#define CORE_PIN15_BIT 0
#define CORE_PIN16_BIT 0
#define CORE_PIN17_BIT 1
#define CORE_PIN18_BIT 3
#define CORE_PIN19_BIT 2
#define CORE_PIN20_BIT 5
#define CORE_PIN21_BIT 6
#define CORE_PIN22_BIT 1
#define CORE_PIN23_BIT 2
#define CORE_PIN24_BIT 20
#define CORE_PIN25_BIT 21
#define CORE_PIN26_BIT 30

#define CORE_PIN0_BITMASK (1<<(CORE_PIN0_BIT))
#define CORE_PIN1_BITMASK (1<<(CORE_PIN1_BIT))
#define CORE_PIN2_BITMASK (1<<(CORE_PIN2_BIT))
#define CORE_PIN3_BITMASK (1<<(CORE_PIN3_BIT))
#define CORE_PIN4_BITMASK (1<<(CORE_PIN4_BIT))
#define CORE_PIN5_BITMASK (1<<(CORE_PIN5_BIT))
#define CORE_PIN6_BITMASK (1<<(CORE_PIN6_BIT))
#define CORE_PIN7_BITMASK (1<<(CORE_PIN7_BIT))
#define CORE_PIN8_BITMASK (1<<(CORE_PIN8_BIT))
#define CORE_PIN9_BITMASK (1<<(CORE_PIN9_BIT))
#define CORE_PIN10_BITMASK (1<<(CORE_PIN10_BIT))
#define CORE_PIN11_BITMASK (1<<(CORE_PIN11_BIT))
#define CORE_PIN12_BITMASK (1<<(CORE_PIN12_BIT))
#define CORE_PIN13_BITMASK (1<<(CORE_PIN13_BIT))
#define CORE_PIN14_BITMASK (1<<(CORE_PIN14_BIT))
#define CORE_PIN15_BITMASK (1<<(CORE_PIN15_BIT))
#define CORE_PIN16_BITMASK (1<<(CORE_PIN16_BIT))
#define CORE_PIN17_BITMASK (1<<(CORE_PIN17_BIT))
#define CORE_PIN18_BITMASK (1<<(CORE_PIN18_BIT))
#define CORE_PIN19_BITMASK (1<<(CORE_PIN19_BIT))
#define CORE_PIN20_BITMASK (1<<(CORE_PIN20_BIT))
#define CORE_PIN21_BITMASK (1<<(CORE_PIN21_BIT))
#define CORE_PIN22_BITMASK (1<<(CORE_PIN22_BIT))
#define CORE_PIN23_BITMASK (1<<(CORE_PIN23_BIT))
#define CORE_PIN24_BITMASK (1<<(CORE_PIN24_BIT))
#define CORE_PIN25_BITMASK (1<<(CORE_PIN25_BIT))
#define CORE_PIN26_BITMASK (1<<(CORE_PIN26_BIT))

#define CORE_PIN0_PORTREG FGPIOB_PDOR
#define CORE_PIN1_PORTREG FGPIOB_PDOR
#define CORE_PIN2_PORTREG FGPIOD_PDOR
#define CORE_PIN3_PORTREG FGPIOA_PDOR
#define CORE_PIN4_PORTREG FGPIOA_PDOR
#define CORE_PIN5_PORTREG FGPIOD_PDOR
#define CORE_PIN6_PORTREG FGPIOD_PDOR
#define CORE_PIN7_PORTREG FGPIOD_PDOR
#define CORE_PIN8_PORTREG FGPIOD_PDOR
#define CORE_PIN9_PORTREG FGPIOC_PDOR
#define CORE_PIN10_PORTREG FGPIOC_PDOR
#define CORE_PIN11_PORTREG FGPIOC_PDOR
#define CORE_PIN12_PORTREG FGPIOC_PDOR
#define CORE_PIN13_PORTREG FGPIOC_PDOR
#define CORE_PIN14_PORTREG FGPIOD_PDOR
#define CORE_PIN15_PORTREG FGPIOC_PDOR
#define CORE_PIN16_PORTREG FGPIOB_PDOR
#define CORE_PIN17_PORTREG FGPIOB_PDOR
#define CORE_PIN18_PORTREG FGPIOB_PDOR
#define CORE_PIN19_PORTREG FGPIOB_PDOR
#define CORE_PIN20_PORTREG FGPIOD_PDOR
#define CORE_PIN21_PORTREG FGPIOD_PDOR
#define CORE_PIN22_PORTREG FGPIOC_PDOR
#define CORE_PIN23_PORTREG FGPIOC_PDOR
#define CORE_PIN24_PORTREG FGPIOE_PDOR
#define CORE_PIN25_PORTREG FGPIOE_PDOR
#define CORE_PIN26_PORTREG FGPIOE_PDOR

#define CORE_PIN0_PORTSET FGPIOB_PSOR
#define CORE_PIN1_PORTSET FGPIOB_PSOR
#define CORE_PIN2_PORTSET FGPIOD_PSOR
#define CORE_PIN3_PORTSET FGPIOA_PSOR
#define CORE_PIN4_PORTSET FGPIOA_PSOR
#define CORE_PIN5_PORTSET FGPIOD_PSOR
#define CORE_PIN6_PORTSET FGPIOD_PSOR
#define CORE_PIN7_PORTSET FGPIOD_PSOR
#define CORE_PIN8_PORTSET FGPIOD_PSOR
#define CORE_PIN9_PORTSET FGPIOC_PSOR
#define CORE_PIN10_PORTSET FGPIOC_PSOR
#define CORE_PIN11_PORTSET FGPIOC_PSOR
#define CORE_PIN12_PORTSET FGPIOC_PSOR
#define CORE_PIN13_PORTSET FGPIOC_PSOR
#define CORE_PIN14_PORTSET FGPIOD_PSOR
#define CORE_PIN15_PORTSET FGPIOC_PSOR
#define CORE_PIN16_PORTSET FGPIOB_PSOR
#define CORE_PIN17_PORTSET FGPIOB_PSOR
#define CORE_PIN18_PORTSET FGPIOB_PSOR
#define CORE_PIN19_PORTSET FGPIOB_PSOR
#define CORE_PIN20_PORTSET FGPIOD_PSOR
#define CORE_PIN21_PORTSET FGPIOD_PSOR
#define CORE_PIN22_PORTSET FGPIOC_PSOR
#define CORE_PIN23_PORTSET FGPIOC_PSOR
#define CORE_PIN24_PORTSET FGPIOE_PSOR
#define CORE_PIN25_PORTSET FGPIOE_PSOR
#define CORE_PIN26_PORTSET FGPIOE_PSOR

#define CORE_PIN0_PORTCLEAR FGPIOB_PCOR
#define CORE_PIN1_PORTCLEAR FGPIOB_PCOR
#define CORE_PIN2_PORTCLEAR FGPIOD_PCOR
#define CORE_PIN3_PORTCLEAR FGPIOA_PCOR
#define CORE_PIN4_PORTCLEAR FGPIOA_PCOR
#define CORE_PIN5_PORTCLEAR FGPIOD_PCOR
#define CORE_PIN6_PORTCLEAR FGPIOD_PCOR
#define CORE_PIN7_PORTCLEAR FGPIOD_PCOR
#define CORE_PIN8_PORTCLEAR FGPIOD_PCOR
#define CORE_PIN9_PORTCLEAR FGPIOC_PCOR
#define CORE_PIN10_PORTCLEAR FGPIOC_PCOR
#define CORE_PIN11_PORTCLEAR FGPIOC_PCOR
#define CORE_PIN12_PORTCLEAR FGPIOC_PCOR
#define CORE_PIN13_PORTCLEAR FGPIOC_PCOR
#define CORE_PIN14_PORTCLEAR FGPIOD_PCOR
#define CORE_PIN15_PORTCLEAR FGPIOC_PCOR
#define CORE_PIN16_PORTCLEAR FGPIOB_PCOR
#define CORE_PIN17_PORTCLEAR FGPIOB_PCOR
#define CORE_PIN18_PORTCLEAR FGPIOB_PCOR
#define CORE_PIN19_PORTCLEAR FGPIOB_PCOR
#define CORE_PIN20_PORTCLEAR FGPIOD_PCOR
#define CORE_PIN21_PORTCLEAR FGPIOD_PCOR
#define CORE_PIN22_PORTCLEAR FGPIOC_PCOR
#define CORE_PIN23_PORTCLEAR FGPIOC_PCOR
#define CORE_PIN24_PORTCLEAR FGPIOE_PCOR
#define CORE_PIN25_PORTCLEAR FGPIOE_PCOR
#define CORE_PIN26_PORTCLEAR FGPIOE_PCOR

#define CORE_PIN0_DDRREG FGPIOB_PDDR
#define CORE_PIN1_DDRREG FGPIOB_PDDR
#define CORE_PIN2_DDRREG FGPIOD_PDDR
#define CORE_PIN3_DDRREG FGPIOA_PDDR
#define CORE_PIN4_DDRREG FGPIOA_PDDR
#define CORE_PIN5_DDRREG FGPIOD_PDDR
#define CORE_PIN6_DDRREG FGPIOD_PDDR
#define CORE_PIN7_DDRREG FGPIOD_PDDR
#define CORE_PIN8_DDRREG FGPIOD_PDDR
#define CORE_PIN9_DDRREG FGPIOC_PDDR
#define CORE_PIN10_DDRREG FGPIOC_PDDR
#define CORE_PIN11_DDRREG FGPIOC_PDDR
#define CORE_PIN12_DDRREG FGPIOC_PDDR
#define CORE_PIN13_DDRREG FGPIOC_PDDR
#define CORE_PIN14_DDRREG FGPIOD_PDDR
#define CORE_PIN15_DDRREG FGPIOC_PDDR
#define CORE_PIN16_DDRREG FGPIOB_PDDR
#define CORE_PIN17_DDRREG FGPIOB_PDDR
#define CORE_PIN18_DDRREG FGPIOB_PDDR
#define CORE_PIN19_DDRREG FGPIOB_PDDR
#define CORE_PIN20_DDRREG FGPIOD_PDDR
#define CORE_PIN21_DDRREG FGPIOD_PDDR
#define CORE_PIN22_DDRREG FGPIOC_PDDR
#define CORE_PIN23_DDRREG FGPIOC_PDDR
#define CORE_PIN24_DDRREG FGPIOE_PDDR
#define CORE_PIN25_DDRREG FGPIOE_PDDR
#define CORE_PIN26_DDRREG FGPIOE_PDDR

#define CORE_PIN0_PINREG FGPIOB_PDIR
#define CORE_PIN1_PINREG FGPIOB_PDIR
#define CORE_PIN2_PINREG FGPIOD_PDIR
#define CORE_PIN3_PINREG FGPIOA_PDIR
#define CORE_PIN4_PINREG FGPIOA_PDIR
#define CORE_PIN5_PINREG FGPIOD_PDIR
#define CORE_PIN6_PINREG FGPIOD_PDIR
#define CORE_PIN7_PINREG FGPIOD_PDIR
#define CORE_PIN8_PINREG FGPIOD_PDIR
#define CORE_PIN9_PINREG FGPIOC_PDIR
#define CORE_PIN10_PINREG FGPIOC_PDIR
#define CORE_PIN11_PINREG FGPIOC_PDIR
#define CORE_PIN12_PINREG FGPIOC_PDIR
#define CORE_PIN13_PINREG FGPIOC_PDIR
#define CORE_PIN14_PINREG FGPIOD_PDIR
#define CORE_PIN15_PINREG FGPIOC_PDIR
#define CORE_PIN16_PINREG FGPIOB_PDIR
#define CORE_PIN17_PINREG FGPIOB_PDIR
#define CORE_PIN18_PINREG FGPIOB_PDIR
#define CORE_PIN19_PINREG FGPIOB_PDIR
#define CORE_PIN20_PINREG FGPIOD_PDIR
#define CORE_PIN21_PINREG FGPIOD_PDIR
#define CORE_PIN22_PINREG FGPIOC_PDIR
#define CORE_PIN23_PINREG FGPIOC_PDIR
#define CORE_PIN24_PINREG FGPIOE_PDIR
#define CORE_PIN25_PINREG FGPIOE_PDIR
#define CORE_PIN26_PINREG FGPIOE_PDIR

#define CORE_PIN0_CONFIG PORTB_PCR16
#define CORE_PIN1_CONFIG PORTB_PCR17
#define CORE_PIN2_CONFIG PORTD_PCR0
#define CORE_PIN3_CONFIG PORTA_PCR1
#define CORE_PIN4_CONFIG PORTA_PCR2
#define CORE_PIN5_CONFIG PORTD_PCR7
#define CORE_PIN6_CONFIG PORTD_PCR4
#define CORE_PIN7_CONFIG PORTD_PCR2
#define CORE_PIN8_CONFIG PORTD_PCR3
#define CORE_PIN9_CONFIG PORTC_PCR3
#define CORE_PIN10_CONFIG PORTC_PCR4
#define CORE_PIN11_CONFIG PORTC_PCR6
#define CORE_PIN12_CONFIG PORTC_PCR7
#define CORE_PIN13_CONFIG PORTC_PCR5
#define CORE_PIN14_CONFIG PORTD_PCR1
#define CORE_PIN15_CONFIG PORTC_PCR0
#define CORE_PIN16_CONFIG PORTB_PCR0
#define CORE_PIN17_CONFIG PORTB_PCR1
#define CORE_PIN18_CONFIG PORTB_PCR3
#define CORE_PIN19_CONFIG PORTB_PCR2
#define CORE_PIN20_CONFIG PORTD_PCR5
#define CORE_PIN21_CONFIG PORTD_PCR6
#define CORE_PIN22_CONFIG PORTC_PCR1
#define CORE_PIN23_CONFIG PORTC_PCR2
#define CORE_PIN24_CONFIG PORTE_PCR20
#define CORE_PIN25_CONFIG PORTE_PCR21
#define CORE_PIN26_CONFIG PORTE_PCR30

#define CORE_ADC0_PIN 14
#define CORE_ADC1_PIN 15
#define CORE_ADC2_PIN 16
#define CORE_ADC3_PIN 17
#define CORE_ADC4_PIN 18
#define CORE_ADC5_PIN 19
#define CORE_ADC6_PIN 20
#define CORE_ADC7_PIN 21
#define CORE_ADC8_PIN 22
#define CORE_ADC9_PIN 23
#define CORE_ADC10_PIN 24
#define CORE_ADC11_PIN 25
#define CORE_ADC12_PIN 26

#define CORE_RXD0_PIN 0
#define CORE_TXD0_PIN 1
#define CORE_RXD1_PIN 9
#define CORE_TXD1_PIN 10
#define CORE_RXD2_PIN 7
#define CORE_TXD2_PIN 8

#define CORE_INT2_PIN 2
#define CORE_INT3_PIN 3
#define CORE_INT4_PIN 4
#define CORE_INT5_PIN 5
#define CORE_INT6_PIN 6
#define CORE_INT7_PIN 7
#define CORE_INT8_PIN 8
#define CORE_INT9_PIN 9
#define CORE_INT10_PIN 10
#define CORE_INT11_PIN 11
#define CORE_INT12_PIN 12
#define CORE_INT13_PIN 13
#define CORE_INT14_PIN 14
#define CORE_INT15_PIN 15
#define CORE_INT20_PIN 20
#define CORE_INT21_PIN 21
#define CORE_INT22_PIN 22
#define CORE_INT23_PIN 23


#endif






#ifdef __cplusplus #ifdef __cplusplus
CORE_PIN25_PORTSET = CORE_PIN25_BITMASK; CORE_PIN25_PORTSET = CORE_PIN25_BITMASK;
} else if (pin == 26) { } else if (pin == 26) {
CORE_PIN26_PORTSET = CORE_PIN26_BITMASK; CORE_PIN26_PORTSET = CORE_PIN26_BITMASK;
} else if (pin == 27) {
}
#if defined(CORE_PIN27_PORTSET)
else if (pin == 27) {
CORE_PIN27_PORTSET = CORE_PIN27_BITMASK; CORE_PIN27_PORTSET = CORE_PIN27_BITMASK;
} else if (pin == 28) { } else if (pin == 28) {
CORE_PIN28_PORTSET = CORE_PIN28_BITMASK; CORE_PIN28_PORTSET = CORE_PIN28_BITMASK;
} else if (pin == 33) { } else if (pin == 33) {
CORE_PIN33_PORTSET = CORE_PIN33_BITMASK; CORE_PIN33_PORTSET = CORE_PIN33_BITMASK;
} }
#endif
} else { } else {
if (pin == 0) { if (pin == 0) {
CORE_PIN0_PORTCLEAR = CORE_PIN0_BITMASK; CORE_PIN0_PORTCLEAR = CORE_PIN0_BITMASK;
CORE_PIN25_PORTCLEAR = CORE_PIN25_BITMASK; CORE_PIN25_PORTCLEAR = CORE_PIN25_BITMASK;
} else if (pin == 26) { } else if (pin == 26) {
CORE_PIN26_PORTCLEAR = CORE_PIN26_BITMASK; CORE_PIN26_PORTCLEAR = CORE_PIN26_BITMASK;
} else if (pin == 27) {
}
#if defined(CORE_PIN27_PORTCLEAR)
else if (pin == 27) {
CORE_PIN27_PORTCLEAR = CORE_PIN27_BITMASK; CORE_PIN27_PORTCLEAR = CORE_PIN27_BITMASK;
} else if (pin == 28) { } else if (pin == 28) {
CORE_PIN28_PORTCLEAR = CORE_PIN28_BITMASK; CORE_PIN28_PORTCLEAR = CORE_PIN28_BITMASK;
} else if (pin == 33) { } else if (pin == 33) {
CORE_PIN33_PORTCLEAR = CORE_PIN33_BITMASK; CORE_PIN33_PORTCLEAR = CORE_PIN33_BITMASK;
} }
#endif
} }
} else { } else {
if (val) { if (val) {
*portSetRegister(pin) = 1;
*portSetRegister(pin) = digitalPinToBitMask(pin);
} else { } else {
*portClearRegister(pin) = 1;
*portClearRegister(pin) = digitalPinToBitMask(pin);
} }
} }
} }
return (CORE_PIN25_PINREG & CORE_PIN25_BITMASK) ? 1 : 0; return (CORE_PIN25_PINREG & CORE_PIN25_BITMASK) ? 1 : 0;
} else if (pin == 26) { } else if (pin == 26) {
return (CORE_PIN26_PINREG & CORE_PIN26_BITMASK) ? 1 : 0; return (CORE_PIN26_PINREG & CORE_PIN26_BITMASK) ? 1 : 0;
} else if (pin == 27) {
}
#if defined(CORE_PIN27_PINREG)
else if (pin == 27) {
return (CORE_PIN27_PINREG & CORE_PIN27_BITMASK) ? 1 : 0; return (CORE_PIN27_PINREG & CORE_PIN27_BITMASK) ? 1 : 0;
} else if (pin == 28) { } else if (pin == 28) {
return (CORE_PIN28_PINREG & CORE_PIN28_BITMASK) ? 1 : 0; return (CORE_PIN28_PINREG & CORE_PIN28_BITMASK) ? 1 : 0;
return (CORE_PIN32_PINREG & CORE_PIN32_BITMASK) ? 1 : 0; return (CORE_PIN32_PINREG & CORE_PIN32_BITMASK) ? 1 : 0;
} else if (pin == 33) { } else if (pin == 33) {
return (CORE_PIN33_PINREG & CORE_PIN33_BITMASK) ? 1 : 0; return (CORE_PIN33_PINREG & CORE_PIN33_BITMASK) ? 1 : 0;
} else {
}
#endif
else {
return 0; return 0;
} }
} else { } else {
#if defined(KINETISK)
return *portInputRegister(pin); return *portInputRegister(pin);
#else
return (*portInputRegister(pin) & digitalPinToBitMask(pin)) ? 1 : 0;
#endif
} }
} }


void analogReadAveraging(unsigned int num); void analogReadAveraging(unsigned int num);
void analog_init(void); void analog_init(void);



#if defined(__MK20DX128__) || defined(__MK20DX256__)
#define DEFAULT 0 #define DEFAULT 0
#define INTERNAL 2 #define INTERNAL 2
#define INTERNAL1V2 2 #define INTERNAL1V2 2
#define INTERNAL1V1 2 #define INTERNAL1V1 2
#define EXTERNAL 0 #define EXTERNAL 0


#elif defined(__MKL26Z64__)
#define DEFAULT 0
#define INTERNAL 0
#define EXTERNAL 1
#endif


int touchRead(uint8_t pin); int touchRead(uint8_t pin);




#if F_CPU < 24000000 #if F_CPU < 24000000
"nop" "\n\t" "nop" "\n\t"
#endif #endif
#ifdef KINETISL
"sub %0, #1" "\n\t"
#else
"subs %0, #1" "\n\t" "subs %0, #1" "\n\t"
#endif
"bne L_%=_delayMicroseconds" "\n" "bne L_%=_delayMicroseconds" "\n"
: "+r" (n) : : "+r" (n) :
); );

+ 224
- 1
teensy3/kinetis.h View File

}; };
#define NVIC_NUM_INTERRUPTS 46 #define NVIC_NUM_INTERRUPTS 46
#define DMA_NUM_CHANNELS 4 #define DMA_NUM_CHANNELS 4
#define KINETISK
#define KINETISK_UART0 #define KINETISK_UART0
#define KINETISK_UART0_FIFO #define KINETISK_UART0_FIFO
#define KINETISK_UART1 #define KINETISK_UART1
}; };
#define NVIC_NUM_INTERRUPTS 95 #define NVIC_NUM_INTERRUPTS 95
#define DMA_NUM_CHANNELS 16 #define DMA_NUM_CHANNELS 16
#define KINETISK
#define KINETISK_UART0 #define KINETISK_UART0
#define KINETISK_UART0_FIFO #define KINETISK_UART0_FIFO
#define KINETISK_UART1 #define KINETISK_UART1
#define KINETISK_UART1_FIFO #define KINETISK_UART1_FIFO
#define KINETISK_UART2 #define KINETISK_UART2


#elif defined(__MKL26Z64__)
enum IRQ_NUMBER_t {
IRQ_DMA_CH0 = 0,
IRQ_DMA_CH1 = 1,
IRQ_DMA_CH2 = 2,
IRQ_DMA_CH3 = 3,
IRQ_FTFA = 5,
IRQ_LOW_VOLTAGE = 6,
IRQ_LLWU = 7,
IRQ_I2C0 = 8,
IRQ_I2C1 = 9,
IRQ_SPI0 = 10,
IRQ_SPI1 = 11,
IRQ_UART0_STATUS = 12,
IRQ_UART1_STATUS = 13,
IRQ_UART2_STATUS = 14,
IRQ_ADC0 = 15,
IRQ_CMP0 = 16,
IRQ_FTM0 = 17,
IRQ_FTM1 = 18,
IRQ_FTM2 = 19,
IRQ_RTC_ALARM = 20,
IRQ_RTC_SECOND = 21,
IRQ_PIT = 22,
IRQ_I2S0 = 23,
IRQ_USBOTG = 24,
IRQ_DAC0 = 25,
IRQ_TSI = 26,
IRQ_MCG = 27,
IRQ_LPTMR = 28,
IRQ_SOFTWARE = 29, // TODO: verify this works
IRQ_PORTA = 30,
IRQ_PORTCD = 31
};
#define NVIC_NUM_INTERRUPTS 32
#define DMA_NUM_CHANNELS 4
#define KINETISL
#define KINETISL_UART0
#define KINETISL_UART1
#define KINETISL_UART2

#endif // end of board-specific definitions #endif // end of board-specific definitions




#if (F_CPU == 168000000) #if (F_CPU == 168000000)
#define F_PLL 168000000
#define F_BUS 56000000 #define F_BUS 56000000
#define F_MEM 33600000 #define F_MEM 33600000
#elif (F_CPU == 144000000) #elif (F_CPU == 144000000)
#define F_PLL 144000000
#define F_BUS 48000000 #define F_BUS 48000000
#define F_MEM 28800000 #define F_MEM 28800000
#elif (F_CPU == 120000000) #elif (F_CPU == 120000000)
#define F_PLL 120000000
#define F_BUS 60000000 #define F_BUS 60000000
#define F_MEM 24000000 #define F_MEM 24000000
#elif (F_CPU == 96000000) #elif (F_CPU == 96000000)
#define F_PLL 96000000
#define F_BUS 48000000 #define F_BUS 48000000
#define F_MEM 24000000 #define F_MEM 24000000
#elif (F_CPU == 72000000) #elif (F_CPU == 72000000)
#define F_PLL 72000000
#define F_BUS 36000000 #define F_BUS 36000000
#define F_MEM 24000000 #define F_MEM 24000000
#elif (F_CPU == 48000000) #elif (F_CPU == 48000000)
#define F_PLL 96000000
#if defined(KINETISK)
#define F_BUS 48000000 #define F_BUS 48000000
#elif defined(KINETISL)
#define F_BUS 24000000
#endif
#define F_MEM 24000000 #define F_MEM 24000000
#elif (F_CPU == 24000000) #elif (F_CPU == 24000000)
#define F_PLL 96000000
#define F_BUS 24000000 #define F_BUS 24000000
#define F_MEM 24000000 #define F_MEM 24000000
#elif (F_CPU == 16000000) #elif (F_CPU == 16000000)
#define F_PLL 96000000
#define F_BUS 16000000 #define F_BUS 16000000
#define F_MEM 16000000 #define F_MEM 16000000
#elif (F_CPU == 8000000) #elif (F_CPU == 8000000)
#define F_PLL 96000000
#define F_BUS 8000000 #define F_BUS 8000000
#define F_MEM 8000000 #define F_MEM 8000000
#elif (F_CPU == 4000000) #elif (F_CPU == 4000000)
#define F_PLL 96000000
#define F_BUS 4000000 #define F_BUS 4000000
#define F_MEM 4000000 #define F_MEM 4000000
#elif (F_CPU == 2000000) #elif (F_CPU == 2000000)
#define F_PLL 2000000
#define F_BUS 2000000 #define F_BUS 2000000
#define F_MEM 1000000 #define F_MEM 1000000
#endif #endif
#define SIM_SOPT1 (*(volatile uint32_t *)0x40047000) // System Options Register 1 #define SIM_SOPT1 (*(volatile uint32_t *)0x40047000) // System Options Register 1
#define SIM_SOPT1CFG (*(volatile uint32_t *)0x40047004) // SOPT1 Configuration Register #define SIM_SOPT1CFG (*(volatile uint32_t *)0x40047004) // SOPT1 Configuration Register
#define SIM_SOPT2 (*(volatile uint32_t *)0x40048004) // System Options Register 2 #define SIM_SOPT2 (*(volatile uint32_t *)0x40048004) // System Options Register 2
#define SIM_SOPT2_UART0SRC(n) (uint32_t)(((n) & 3) << 26) // UART0 Clock Source, 0=off, 1=FLL/PLL, 2=OSCERCLK, 3=MCGIRCLK
#define SIM_SOPT2_TPMSRC(n) (uint32_t)(((n) & 3) << 24) // TPM Clock Source, 0=off, 1=FLL/PLL, 2=OSCERCLK, 3=MCGIRCLK
#define SIM_SOPT2_USBSRC ((uint32_t)0x00040000) // 0=USB_CLKIN, 1=FFL/PLL #define SIM_SOPT2_USBSRC ((uint32_t)0x00040000) // 0=USB_CLKIN, 1=FFL/PLL
#define SIM_SOPT2_PLLFLLSEL ((uint32_t)0x00010000) // 0=FLL, 1=PLL #define SIM_SOPT2_PLLFLLSEL ((uint32_t)0x00010000) // 0=FLL, 1=PLL
#define SIM_SOPT2_TRACECLKSEL ((uint32_t)0x00001000) // 0=MCGOUTCLK, 1=CPU #define SIM_SOPT2_TRACECLKSEL ((uint32_t)0x00001000) // 0=MCGOUTCLK, 1=CPU
#define SIM_SCGC4_I2C0 ((uint32_t)0x00000040) // I2C0 Clock Gate Control #define SIM_SCGC4_I2C0 ((uint32_t)0x00000040) // I2C0 Clock Gate Control
#define SIM_SCGC4_CMT ((uint32_t)0x00000004) // CMT Clock Gate Control #define SIM_SCGC4_CMT ((uint32_t)0x00000004) // CMT Clock Gate Control
#define SIM_SCGC4_EWM ((uint32_t)0x00000002) // EWM Clock Gate Control #define SIM_SCGC4_EWM ((uint32_t)0x00000002) // EWM Clock Gate Control
#ifdef KINETISL
#define SIM_SCGC4_SPI1 ((uint32_t)0x00800000) //
#define SIM_SCGC4_SPI0 ((uint32_t)0x00400000) //
#endif
#define SIM_SCGC5 (*(volatile uint32_t *)0x40048038) // System Clock Gating Control Register 5 #define SIM_SCGC5 (*(volatile uint32_t *)0x40048038) // System Clock Gating Control Register 5
#define SIM_SCGC5_PORTE ((uint32_t)0x00002000) // Port E Clock Gate Control #define SIM_SCGC5_PORTE ((uint32_t)0x00002000) // Port E Clock Gate Control
#define SIM_SCGC5_PORTD ((uint32_t)0x00001000) // Port D Clock Gate Control #define SIM_SCGC5_PORTD ((uint32_t)0x00001000) // Port D Clock Gate Control
#define SIM_SCGC6_ADC0 ((uint32_t)0x08000000) // ADC0 Clock Gate Control #define SIM_SCGC6_ADC0 ((uint32_t)0x08000000) // ADC0 Clock Gate Control
#define SIM_SCGC6_FTM1 ((uint32_t)0x02000000) // FTM1 Clock Gate Control #define SIM_SCGC6_FTM1 ((uint32_t)0x02000000) // FTM1 Clock Gate Control
#define SIM_SCGC6_FTM0 ((uint32_t)0x01000000) // FTM0 Clock Gate Control #define SIM_SCGC6_FTM0 ((uint32_t)0x01000000) // FTM0 Clock Gate Control
#define SIM_SCGC6_TPM2 ((uint32_t)0x04000000) // FTM1 Clock Gate Control
#define SIM_SCGC6_TPM1 ((uint32_t)0x02000000) // FTM1 Clock Gate Control
#define SIM_SCGC6_TPM0 ((uint32_t)0x01000000) // FTM0 Clock Gate Control
#define SIM_SCGC6_PIT ((uint32_t)0x00800000) // PIT Clock Gate Control #define SIM_SCGC6_PIT ((uint32_t)0x00800000) // PIT Clock Gate Control
#define SIM_SCGC6_PDB ((uint32_t)0x00400000) // PDB Clock Gate Control #define SIM_SCGC6_PDB ((uint32_t)0x00400000) // PDB Clock Gate Control
#define SIM_SCGC6_USBDCD ((uint32_t)0x00200000) // USB DCD Clock Gate Control #define SIM_SCGC6_USBDCD ((uint32_t)0x00200000) // USB DCD Clock Gate Control
#define SIM_SCGC6_CRC ((uint32_t)0x00040000) // CRC Clock Gate Control #define SIM_SCGC6_CRC ((uint32_t)0x00040000) // CRC Clock Gate Control
#define SIM_SCGC6_I2S ((uint32_t)0x00008000) // I2S Clock Gate Control #define SIM_SCGC6_I2S ((uint32_t)0x00008000) // I2S Clock Gate Control
#ifdef KINETISK
#define SIM_SCGC6_SPI1 ((uint32_t)0x00002000) // SPI1 Clock Gate Control #define SIM_SCGC6_SPI1 ((uint32_t)0x00002000) // SPI1 Clock Gate Control
#define SIM_SCGC6_SPI0 ((uint32_t)0x00001000) // SPI0 Clock Gate Control #define SIM_SCGC6_SPI0 ((uint32_t)0x00001000) // SPI0 Clock Gate Control
#endif
#define SIM_SCGC6_FLEXCAN0 ((uint32_t)0x00000010) // FlexCAN0 Clock Gate Control #define SIM_SCGC6_FLEXCAN0 ((uint32_t)0x00000010) // FlexCAN0 Clock Gate Control
#define SIM_SCGC6_DMAMUX ((uint32_t)0x00000002) // DMA Mux Clock Gate Control #define SIM_SCGC6_DMAMUX ((uint32_t)0x00000002) // DMA Mux Clock Gate Control
#define SIM_SCGC6_FTFL ((uint32_t)0x00000001) // Flash Memory Clock Gate Control #define SIM_SCGC6_FTFL ((uint32_t)0x00000001) // Flash Memory Clock Gate Control
#define SIM_UIDMH (*(const uint32_t *)0x40048058) // Unique Identification Register Mid-High #define SIM_UIDMH (*(const uint32_t *)0x40048058) // Unique Identification Register Mid-High
#define SIM_UIDML (*(const uint32_t *)0x4004805C) // Unique Identification Register Mid Low #define SIM_UIDML (*(const uint32_t *)0x4004805C) // Unique Identification Register Mid Low
#define SIM_UIDL (*(const uint32_t *)0x40048060) // Unique Identification Register Low #define SIM_UIDL (*(const uint32_t *)0x40048060) // Unique Identification Register Low
#define SIM_COPC (*(volatile uint32_t *)0x40048100) // COP Control Register (SIM_COPC)
#define SIM_SRVCOP (*(volatile uint32_t *)0x40048104) // Service COP Register (SIM_SRVCOP)


// Chapter 13: Reset Control Module (RCM) // Chapter 13: Reset Control Module (RCM)
#define RCM_SRS0 (*(volatile uint8_t *)0x4007F000) // System Reset Status Register 0 #define RCM_SRS0 (*(volatile uint8_t *)0x4007F000) // System Reset Status Register 0
#define LLWU_RST (*(volatile uint8_t *)0x4007C00A) // LLWU Reset Enable register #define LLWU_RST (*(volatile uint8_t *)0x4007C00A) // LLWU Reset Enable register


// Chapter 17: Miscellaneous Control Module (MCM) // Chapter 17: Miscellaneous Control Module (MCM)
#if defined(KINETISK)
#define MCM_PLASC (*(volatile uint16_t *)0xE0080008) // Crossbar Switch (AXBS) Slave Configuration #define MCM_PLASC (*(volatile uint16_t *)0xE0080008) // Crossbar Switch (AXBS) Slave Configuration
#define MCM_PLAMC (*(volatile uint16_t *)0xE008000A) // Crossbar Switch (AXBS) Master Configuration #define MCM_PLAMC (*(volatile uint16_t *)0xE008000A) // Crossbar Switch (AXBS) Master Configuration
#define MCM_PLACR (*(volatile uint32_t *)0xE008000C) // Crossbar Switch (AXBS) Control Register (MK20DX128) #define MCM_PLACR (*(volatile uint32_t *)0xE008000C) // Crossbar Switch (AXBS) Control Register (MK20DX128)
#define MCM_CR_SRAMLAP(n) ((uint32_t)(((n) & 0x03) << 28)) // SRAM_L priority, 0=RR, 1=favor DMA, 2=CPU, 3=DMA #define MCM_CR_SRAMLAP(n) ((uint32_t)(((n) & 0x03) << 28)) // SRAM_L priority, 0=RR, 1=favor DMA, 2=CPU, 3=DMA
#define MCM_CR_SRAMUWP ((uint32_t)0x04000000) // SRAM_U write protect #define MCM_CR_SRAMUWP ((uint32_t)0x04000000) // SRAM_U write protect
#define MCM_CR_SRAMUAP(n) ((uint32_t)(((n) & 0x03) << 24)) // SRAM_U priority, 0=RR, 1=favor DMA, 2=CPU, 3=DMA #define MCM_CR_SRAMUAP(n) ((uint32_t)(((n) & 0x03) << 24)) // SRAM_U priority, 0=RR, 1=favor DMA, 2=CPU, 3=DMA
#elif defined(KINETISL)
#define MCM_PLASC (*(volatile uint16_t *)0xF0003008) // Crossbar Switch (AXBS) Slave Configuration
#define MCM_PLAMC (*(volatile uint16_t *)0xF000300A) // Crossbar Switch (AXBS) Master Configuration
#define MCM_PLACR (*(volatile uint32_t *)0xF000300C) // Platform Control Register
#define MCM_CPO (*(volatile uint32_t *)0xF0003040) // Compute Operation Control Register
#endif


// Crossbar Switch (AXBS) - only programmable on MK20DX256 // Crossbar Switch (AXBS) - only programmable on MK20DX256
#define AXBS_PRS0 (*(volatile uint32_t *)0x40004000) // Priority Registers Slave 0 #define AXBS_PRS0 (*(volatile uint32_t *)0x40004000) // Priority Registers Slave 0
#define FTM1_INVCTRL (*(volatile uint32_t *)0x40039090) // FTM Inverting Control #define FTM1_INVCTRL (*(volatile uint32_t *)0x40039090) // FTM Inverting Control
#define FTM1_SWOCTRL (*(volatile uint32_t *)0x40039094) // FTM Software Output Control #define FTM1_SWOCTRL (*(volatile uint32_t *)0x40039094) // FTM Software Output Control
#define FTM1_PWMLOAD (*(volatile uint32_t *)0x40039098) // FTM PWM Load #define FTM1_PWMLOAD (*(volatile uint32_t *)0x40039098) // FTM PWM Load

#if defined(KINETISK)
#define FTM2_SC (*(volatile uint32_t *)0x400B8000) // Status And Control #define FTM2_SC (*(volatile uint32_t *)0x400B8000) // Status And Control
#define FTM2_CNT (*(volatile uint32_t *)0x400B8004) // Counter #define FTM2_CNT (*(volatile uint32_t *)0x400B8004) // Counter
#define FTM2_MOD (*(volatile uint32_t *)0x400B8008) // Modulo #define FTM2_MOD (*(volatile uint32_t *)0x400B8008) // Modulo
#define FTM2_INVCTRL (*(volatile uint32_t *)0x400B8090) // FTM Inverting Control #define FTM2_INVCTRL (*(volatile uint32_t *)0x400B8090) // FTM Inverting Control
#define FTM2_SWOCTRL (*(volatile uint32_t *)0x400B8094) // FTM Software Output Control #define FTM2_SWOCTRL (*(volatile uint32_t *)0x400B8094) // FTM Software Output Control
#define FTM2_PWMLOAD (*(volatile uint32_t *)0x400B8098) // FTM PWM Load #define FTM2_PWMLOAD (*(volatile uint32_t *)0x400B8098) // FTM PWM Load
#elif defined(KINETISL)
#define FTM2_SC (*(volatile uint32_t *)0x4003A000) // Status And Control
#define FTM2_CNT (*(volatile uint32_t *)0x4003A004) // Counter
#define FTM2_MOD (*(volatile uint32_t *)0x4003A008) // Modulo
#define FTM2_C0SC (*(volatile uint32_t *)0x4003A00C) // Channel 0 Status And Control
#define FTM2_C0V (*(volatile uint32_t *)0x4003A010) // Channel 0 Value
#define FTM2_C1SC (*(volatile uint32_t *)0x4003A014) // Channel 1 Status And Control
#define FTM2_C1V (*(volatile uint32_t *)0x4003A018) // Channel 1 Value
#define FTM2_STATUS (*(volatile uint32_t *)0x4003A050) // Capture And Compare Status
#define FTM2_CONF (*(volatile uint32_t *)0x4003A084) // Configuration
#endif


// Chapter 36: Periodic Interrupt Timer (PIT) // Chapter 36: Periodic Interrupt Timer (PIT)
#define PIT_MCR (*(volatile uint32_t *)0x40037000) // PIT Module Control Register #define PIT_MCR (*(volatile uint32_t *)0x40037000) // PIT Module Control Register
#define USBDCD_TIMER1 (*(volatile uint32_t *)0x40035014) // TIMER1 register #define USBDCD_TIMER1 (*(volatile uint32_t *)0x40035014) // TIMER1 register
#define USBDCD_TIMER2 (*(volatile uint32_t *)0x40035018) // TIMER2 register #define USBDCD_TIMER2 (*(volatile uint32_t *)0x40035018) // TIMER2 register


#if defined(KINETISK)
// Chapter 43: SPI (DSPI) // Chapter 43: SPI (DSPI)
typedef struct __attribute__((packed)) { typedef struct __attribute__((packed)) {
volatile uint32_t MCR; // 0 volatile uint32_t MCR; // 0
#define SPI0_RXFR2 (*(volatile uint32_t *)0x4002C084) // DSPI Receive FIFO Registers #define SPI0_RXFR2 (*(volatile uint32_t *)0x4002C084) // DSPI Receive FIFO Registers
#define SPI0_RXFR3 (*(volatile uint32_t *)0x4002C088) // DSPI Receive FIFO Registers #define SPI0_RXFR3 (*(volatile uint32_t *)0x4002C088) // DSPI Receive FIFO Registers


#elif defined(KINETISL)
#define SPI0_S (*(volatile uint8_t *)0x40076000) // Status
#define SPI_S_SPRF ((uint8_t)0x80) // Read Buffer Full Flag
#define SPI_S_SPMF ((uint8_t)0x40) // Match Flag
#define SPI_S_SPTEF ((uint8_t)0x20) // Transmit Buffer Empty Flag
#define SPI_S_MODF ((uint8_t)0x10) // Fault Flag
#define SPI_S_RNFULLF ((uint8_t)0x08) // Receive FIFO nearly full flag
#define SPI_S_TNEAREF ((uint8_t)0x04) // Transmit FIFO nearly empty flag
#define SPI_S_TXFULLF ((uint8_t)0x02) // Transmit FIFO full flag
#define SPI_S_RFIFOEF ((uint8_t)0x01) // Read FIFO empty flag
#define SPI0_BR (*(volatile uint8_t *)0x40076001) // Baud Rate
#define SPI_BR_SPPR(n) (((n) & 7) << 4) // Prescale = N+1
#define SPI_BR_SPR(n) (((n) & 15) << 0) // Baud Rate Divisor = 2^(N+1) : 0-8 -> 2 to 512
#define SPI0_C2 (*(volatile uint8_t *)0x40076002) // Control Register 2
#define SPI_C2_SPMIE ((uint8_t)0x80) // Match Interrupt Enable
#define SPI_C2_SPIMODE ((uint8_t)0x40) // 0 = 8 bit mode, 1 = 16 bit mode
#define SPI_C2_TXDMAE ((uint8_t)0x20) // Transmit DMA enable
#define SPI_C2_MODFEN ((uint8_t)0x10) // Master Mode-Fault Function Enable
#define SPI_C2_BIDIROE ((uint8_t)0x08) // Bidirectional Mode Output Enable
#define SPI_C2_RXDMAE ((uint8_t)0x04) // Receive DMA enable
#define SPI_C2_SPISWAI ((uint8_t)0x02) // SPI Stop in Wait Mode
#define SPI_C2_SPC0 ((uint8_t)0x01) // SPI Pin Control, 0=normal, 1=single bidirectional
#define SPI0_C1 (*(volatile uint8_t *)0x40076003) // Control Register 1
#define SPI_C1_SPIE ((uint8_t)0x80) // Interrupt Enable
#define SPI_C1_SPE ((uint8_t)0x40) // SPI System Enable
#define SPI_C1_SPTIE ((uint8_t)0x20) // Transmit Interrupt Enable
#define SPI_C1_MSTR ((uint8_t)0x10) // Master/Slave Mode: 0=slave, 1=master
#define SPI_C1_CPOL ((uint8_t)0x08) // Clock Polarity
#define SPI_C1_CPHA ((uint8_t)0x04) // Clock Phase
#define SPI_C1_SSOE ((uint8_t)0x02) // Slave Select Output Enable
#define SPI_C1_LSBFE ((uint8_t)0x01) // LSB First: 0=MSB First, 1=LSB First
#define SPI0_ML (*(volatile uint8_t *)0x40076004) // Match Low
#define SPI0_MH (*(volatile uint8_t *)0x40076005) // Match High
#define SPI0_DL (*(volatile uint8_t *)0x40076006) // Data Low
#define SPI0_DH (*(volatile uint8_t *)0x40076007) // Data High
#define SPI0_CI (*(volatile uint8_t *)0x4007600A) // clear interrupt
#define SPI_CI_TXFERR ((uint8_t)0x80) // Transmit FIFO error flag
#define SPI_CI_RXFERR ((uint8_t)0x40) // Receive FIFO error flag
#define SPI_CI_TXFOF ((uint8_t)0x20) // Transmit FIFO overflow flag
#define SPI_CI_RXFOF ((uint8_t)0x10) // Receive FIFO overflow flag
#define SPI_CI_TNEAREFCI ((uint8_t)0x08) // Transmit FIFO nearly empty flag clear interrupt
#define SPI_CI_RNFULLFCI ((uint8_t)0x04) // Receive FIFO nearly full flag clear interrupt
#define SPI_CI_SPTEFCI ((uint8_t)0x02) // Transmit FIFO empty flag clear interrupt
#define SPI_CI_SPRFCI ((uint8_t)0x01) // Receive FIFO full flag clear interrupt
#define SPI0_C3 (*(volatile uint8_t *)0x4007600B) // Control Register 3
#define SPI_C3_TNEAREF_MARK ((uint8_t)0x20) // Transmit FIFO nearly empty watermark
#define SPI_C3_RNFULLF_MARK ((uint8_t)0x10) // Receive FIFO nearly full watermark
#define SPI_C3_INTCLR ((uint8_t)0x08) // Interrupt clearing mechanism select
#define SPI_C3_TNEARIEN ((uint8_t)0x04) // Transmit FIFO nearly empty interrupt enable
#define SPI_C3_RNFULLIEN ((uint8_t)0x02) // Receive FIFO nearly full interrupt enable
#define SPI_C3_FIFOMODE ((uint8_t)0x01) // FIFO mode enable
#define SPI1_S (*(volatile uint8_t *)0x40077000) // Status
#define SPI1_BR (*(volatile uint8_t *)0x40077001) // Baud Rate
#define SPI1_C2 (*(volatile uint8_t *)0x40077002) // Control Register 2
#define SPI1_C1 (*(volatile uint8_t *)0x40077003) // Control Register 1
#define SPI1_ML (*(volatile uint8_t *)0x40077004) // Match Low
#define SPI1_MH (*(volatile uint8_t *)0x40077005) // Match High
#define SPI1_DL (*(volatile uint8_t *)0x40077006) // Data Low
#define SPI1_DH (*(volatile uint8_t *)0x40077007) // Data High
#define SPI1_CI (*(volatile uint8_t *)0x4007700A) // clear interrupt
#define SPI1_C3 (*(volatile uint8_t *)0x4007700B) // Control Register 3
#endif


// Chapter 44: Inter-Integrated Circuit (I2C) // Chapter 44: Inter-Integrated Circuit (I2C)
#define I2C0_A1 (*(volatile uint8_t *)0x40066000) // I2C Address Register 1 #define I2C0_A1 (*(volatile uint8_t *)0x40066000) // I2C Address Register 1
#define I2C0_F (*(volatile uint8_t *)0x40066001) // I2C Frequency Divider register #define I2C0_F (*(volatile uint8_t *)0x40066001) // I2C Frequency Divider register
#define GPIOE_PDIR (*(volatile uint32_t *)0x400FF110) // Port Data Input Register #define GPIOE_PDIR (*(volatile uint32_t *)0x400FF110) // Port Data Input Register
#define GPIOE_PDDR (*(volatile uint32_t *)0x400FF114) // Port Data Direction Register #define GPIOE_PDDR (*(volatile uint32_t *)0x400FF114) // Port Data Direction Register


#if defined(KINETISL)
#define FGPIOA_PDOR (*(volatile uint32_t *)0xF8000000) // Port Data Output Register
#define FGPIOA_PSOR (*(volatile uint32_t *)0xF8000004) // Port Set Output Register
#define FGPIOA_PCOR (*(volatile uint32_t *)0xF8000008) // Port Clear Output Register
#define FGPIOA_PTOR (*(volatile uint32_t *)0xF800000C) // Port Toggle Output Register
#define FGPIOA_PDIR (*(volatile uint32_t *)0xF8000010) // Port Data Input Register
#define FGPIOA_PDDR (*(volatile uint32_t *)0xF8000014) // Port Data Direction Register
#define FGPIOB_PDOR (*(volatile uint32_t *)0xF8000040) // Port Data Output Register
#define FGPIOB_PSOR (*(volatile uint32_t *)0xF8000044) // Port Set Output Register
#define FGPIOB_PCOR (*(volatile uint32_t *)0xF8000048) // Port Clear Output Register
#define FGPIOB_PTOR (*(volatile uint32_t *)0xF800004C) // Port Toggle Output Register
#define FGPIOB_PDIR (*(volatile uint32_t *)0xF8000050) // Port Data Input Register
#define FGPIOB_PDDR (*(volatile uint32_t *)0xF8000054) // Port Data Direction Register
#define FGPIOC_PDOR (*(volatile uint32_t *)0xF8000080) // Port Data Output Register
#define FGPIOC_PSOR (*(volatile uint32_t *)0xF8000084) // Port Set Output Register
#define FGPIOC_PCOR (*(volatile uint32_t *)0xF8000088) // Port Clear Output Register
#define FGPIOC_PTOR (*(volatile uint32_t *)0xF800008C) // Port Toggle Output Register
#define FGPIOC_PDIR (*(volatile uint32_t *)0xF8000090) // Port Data Input Register
#define FGPIOC_PDDR (*(volatile uint32_t *)0xF8000094) // Port Data Direction Register
#define FGPIOD_PDOR (*(volatile uint32_t *)0xF80000C0) // Port Data Output Register
#define FGPIOD_PSOR (*(volatile uint32_t *)0xF80000C4) // Port Set Output Register
#define FGPIOD_PCOR (*(volatile uint32_t *)0xF80000C8) // Port Clear Output Register
#define FGPIOD_PTOR (*(volatile uint32_t *)0xF80000CC) // Port Toggle Output Register
#define FGPIOD_PDIR (*(volatile uint32_t *)0xF80000D0) // Port Data Input Register
#define FGPIOD_PDDR (*(volatile uint32_t *)0xF80000D4) // Port Data Direction Register
#define FGPIOE_PDOR (*(volatile uint32_t *)0xF8000100) // Port Data Output Register
#define FGPIOE_PSOR (*(volatile uint32_t *)0xF8000104) // Port Set Output Register
#define FGPIOE_PCOR (*(volatile uint32_t *)0xF8000108) // Port Clear Output Register
#define FGPIOE_PTOR (*(volatile uint32_t *)0xF800010C) // Port Toggle Output Register
#define FGPIOE_PDIR (*(volatile uint32_t *)0xF8000110) // Port Data Input Register
#define FGPIOE_PDDR (*(volatile uint32_t *)0xF8000114) // Port Data Direction Register
#endif

// Chapter 48: Touch sense input (TSI) // Chapter 48: Touch sense input (TSI)
#if defined(KINETISK)
#define TSI0_GENCS (*(volatile uint32_t *)0x40045000) // General Control and Status Register #define TSI0_GENCS (*(volatile uint32_t *)0x40045000) // General Control and Status Register
#define TSI_GENCS_LPCLKS ((uint32_t)0x10000000) // #define TSI_GENCS_LPCLKS ((uint32_t)0x10000000) //
#define TSI_GENCS_LPSCNITV(n) (((n) & 15) << 24) // #define TSI_GENCS_LPSCNITV(n) (((n) & 15) << 24) //
#define TSI0_CNTR13 (*(volatile uint32_t *)0x40045118) // Counter Register #define TSI0_CNTR13 (*(volatile uint32_t *)0x40045118) // Counter Register
#define TSI0_CNTR15 (*(volatile uint32_t *)0x4004511C) // Counter Register #define TSI0_CNTR15 (*(volatile uint32_t *)0x4004511C) // Counter Register
#define TSI0_THRESHOLD (*(volatile uint32_t *)0x40045120) // Low Power Channel Threshold Register #define TSI0_THRESHOLD (*(volatile uint32_t *)0x40045120) // Low Power Channel Threshold Register
#elif defined(KINETISL)
#define TSI0_GENCS (*(volatile uint32_t *)0x40045000) // General Control and Status
#define TSI_GENCS_OUTRGF ((uint32_t)0x80000000) // Out of Range Flag
#define TSI_GENCS_ESOR ((uint32_t)0x10000000) // End-of-scan or Out-of-Range Interrupt Selection
#define TSI_GENCS_MODE(n) (((n) & 15) << 24) // analog modes & status
#define TSI_GENCS_REFCHRG(n) (((n) & 7) << 21) // reference charge and discharge current
#define TSI_GENCS_DVOLT(n) (((n) & 3) << 19) // voltage rails
#define TSI_GENCS_EXTCHRG(n) (((n) & 7) << 16) // electrode charge and discharge current
#define TSI_GENCS_PS(n) (((n) & 7) << 13) // prescaler
#define TSI_GENCS_NSCN(n) (((n) & 31) << 8) // scan number
#define TSI_GENCS_TSIEN ((uint32_t)0x00000080) // Enable
#define TSI_GENCS_TSIIEN ((uint32_t)0x00000040) // Interrupt Enable
#define TSI_GENCS_STPE ((uint32_t)0x00000020) // STOP Enable
#define TSI_GENCS_STM ((uint32_t)0x00000010) // Trigger Mode
#define TSI_GENCS_SCNIP ((uint32_t)0x00000008) // Scan In Progress Status
#define TSI_GENCS_EOSF ((uint32_t)0x00000004) // End of Scan Flag
#define TSI_GENCS_CURSW ((uint32_t)0x00000002) // current sources swapped
#define TSI0_DATA (*(volatile uint32_t *)0x40045004) // Data
#define TSI_DATA_TSICH(n) (((n) & 15) << 28) // channel
#define TSI_DATA_DMAEN ((uint32_t)0x00800000) // DMA Transfer Enabled
#define TSI_DATA_SWTS ((uint32_t)0x00400000) // Software Trigger Start
#define TSI_DATA_TSICNT(n) (((n) & 65535) << 0) // Conversion Counter Value
#define TSI0_TSHD (*(volatile uint32_t *)0x40045008) // Threshold
#define TSI_TSHD_THRESH(n) (((n) & 65535) << 16) // High wakeup threshold
#define TSI_TSHD_THRESL(n) (((n) & 65535) << 0) // Low wakeup threshold
#endif


// Nested Vectored Interrupt Controller, Table 3-4 & ARMv7 ref, appendix B3.4 (page 750) // Nested Vectored Interrupt Controller, Table 3-4 & ARMv7 ref, appendix B3.4 (page 750)
#define NVIC_ENABLE_IRQ(n) (*((volatile uint32_t *)0xE000E100 + ((n) >> 5)) = (1 << ((n) & 31))) #define NVIC_ENABLE_IRQ(n) (*((volatile uint32_t *)0xE000E100 + ((n) >> 5)) = (1 << ((n) & 31)))
// 0 = highest priority // 0 = highest priority
// Cortex-M4: 0,16,32,48,64,80,96,112,128,144,160,176,192,208,224,240 // Cortex-M4: 0,16,32,48,64,80,96,112,128,144,160,176,192,208,224,240
// Cortex-M0: 0,64,128,192 // Cortex-M0: 0,64,128,192
#ifdef KINETISK
#define NVIC_SET_PRIORITY(irqnum, priority) (*((volatile uint8_t *)0xE000E400 + (irqnum)) = (uint8_t)(priority)) #define NVIC_SET_PRIORITY(irqnum, priority) (*((volatile uint8_t *)0xE000E400 + (irqnum)) = (uint8_t)(priority))
#define NVIC_GET_PRIORITY(irqnum) (*((uint8_t *)0xE000E400 + (irqnum))) #define NVIC_GET_PRIORITY(irqnum) (*((uint8_t *)0xE000E400 + (irqnum)))

#else
#define NVIC_SET_PRIORITY(irqnum, priority) (*((uint32_t *)0xE000E400 + ((irqnum) >> 2)) = (*((uint32_t *)0xE000E400 + ((irqnum) >> 2)) & (~(0xFF << (8 * ((irqnum) & 3))))) | (((priority) & 0xFF) << (8 * ((irqnum) & 3))))
#define NVIC_GET_PRIORITY(irqnum) (*((uint32_t *)0xE000E400 + ((irqnum) >> 2)) >> (8 * ((irqnum) & 3)) & 255)
#endif






extern void can0_wakeup_isr(void); extern void can0_wakeup_isr(void);
extern void i2s0_tx_isr(void); extern void i2s0_tx_isr(void);
extern void i2s0_rx_isr(void); extern void i2s0_rx_isr(void);
extern void i2s0_isr(void);
extern void uart0_lon_isr(void); extern void uart0_lon_isr(void);
extern void uart0_status_isr(void); extern void uart0_status_isr(void);
extern void uart0_error_isr(void); extern void uart0_error_isr(void);
extern void pit1_isr(void); extern void pit1_isr(void);
extern void pit2_isr(void); extern void pit2_isr(void);
extern void pit3_isr(void); extern void pit3_isr(void);
extern void pit_isr(void);
extern void pdb_isr(void); extern void pdb_isr(void);
extern void usb_isr(void); extern void usb_isr(void);
extern void usb_charge_isr(void); extern void usb_charge_isr(void);
extern void portc_isr(void); extern void portc_isr(void);
extern void portd_isr(void); extern void portd_isr(void);
extern void porte_isr(void); extern void porte_isr(void);
extern void portcd_isr(void);
extern void software_isr(void); extern void software_isr(void);


extern void (* _VectorsRam[NVIC_NUM_INTERRUPTS+16])(void); extern void (* _VectorsRam[NVIC_NUM_INTERRUPTS+16])(void);

+ 136
- 14
teensy3/mk20dx128.c View File

*/ */


#include "kinetis.h" #include "kinetis.h"

//#include "core_pins.h" // testing only
//#include "ser_print.h" // testing only


extern unsigned long _stext; extern unsigned long _stext;
extern unsigned long _etext; extern unsigned long _etext;


void fault_isr(void) void fault_isr(void)
{ {
#if 0
uint32_t addr;
digitalWriteFast(15, HIGH);
ser_print("\nfault: \n??: ");
asm("ldr %0, [sp, #52]" : "=r" (addr) ::);
ser_print_hex32(addr);
ser_print("\n??: ");
asm("ldr %0, [sp, #48]" : "=r" (addr) ::);
ser_print_hex32(addr);
ser_print("\n??: ");
asm("ldr %0, [sp, #44]" : "=r" (addr) ::);
ser_print_hex32(addr);
ser_print("\npsr:");
asm("ldr %0, [sp, #40]" : "=r" (addr) ::);
ser_print_hex32(addr);
ser_print("\nadr:");
asm("ldr %0, [sp, #36]" : "=r" (addr) ::);
ser_print_hex32(addr);
ser_print("\nlr: ");
asm("ldr %0, [sp, #32]" : "=r" (addr) ::);
ser_print_hex32(addr);
ser_print("\nr12:");
asm("ldr %0, [sp, #28]" : "=r" (addr) ::);
ser_print_hex32(addr);
ser_print("\nr3: ");
asm("ldr %0, [sp, #24]" : "=r" (addr) ::);
ser_print_hex32(addr);
ser_print("\nr2: ");
asm("ldr %0, [sp, #20]" : "=r" (addr) ::);
ser_print_hex32(addr);
ser_print("\nr1: ");
asm("ldr %0, [sp, #16]" : "=r" (addr) ::);
ser_print_hex32(addr);
ser_print("\nr0: ");
asm("ldr %0, [sp, #12]" : "=r" (addr) ::);
ser_print_hex32(addr);
ser_print("\nr4: ");
asm("ldr %0, [sp, #8]" : "=r" (addr) ::);
ser_print_hex32(addr);
ser_print("\nlr: ");
asm("ldr %0, [sp, #4]" : "=r" (addr) ::);
ser_print_hex32(addr);
ser_print("\n");
asm("ldr %0, [sp, #0]" : "=r" (addr) ::);
#endif
while (1) { while (1) {
// keep polling some communication while in fault // keep polling some communication while in fault
// mode, so we don't completely die. // mode, so we don't completely die.
} }


void nmi_isr(void) __attribute__ ((weak, alias("unused_isr"))); void nmi_isr(void) __attribute__ ((weak, alias("unused_isr")));
void hard_fault_isr(void) __attribute__ ((weak, alias("unused_isr")));
void memmanage_fault_isr(void) __attribute__ ((weak, alias("unused_isr")));
void bus_fault_isr(void) __attribute__ ((weak, alias("unused_isr")));
void usage_fault_isr(void) __attribute__ ((weak, alias("unused_isr")));
void hard_fault_isr(void) __attribute__ ((weak, alias("fault_isr")));
void memmanage_fault_isr(void) __attribute__ ((weak, alias("fault_isr")));
void bus_fault_isr(void) __attribute__ ((weak, alias("fault_isr")));
void usage_fault_isr(void) __attribute__ ((weak, alias("fault_isr")));
void svcall_isr(void) __attribute__ ((weak, alias("unused_isr"))); void svcall_isr(void) __attribute__ ((weak, alias("unused_isr")));
void debugmonitor_isr(void) __attribute__ ((weak, alias("unused_isr"))); void debugmonitor_isr(void) __attribute__ ((weak, alias("unused_isr")));
void pendablesrvreq_isr(void) __attribute__ ((weak, alias("unused_isr"))); void pendablesrvreq_isr(void) __attribute__ ((weak, alias("unused_isr")));
void can0_wakeup_isr(void) __attribute__ ((weak, alias("unused_isr"))); void can0_wakeup_isr(void) __attribute__ ((weak, alias("unused_isr")));
void i2s0_tx_isr(void) __attribute__ ((weak, alias("unused_isr"))); void i2s0_tx_isr(void) __attribute__ ((weak, alias("unused_isr")));
void i2s0_rx_isr(void) __attribute__ ((weak, alias("unused_isr"))); void i2s0_rx_isr(void) __attribute__ ((weak, alias("unused_isr")));
void i2s0_isr(void) __attribute__ ((weak, alias("unused_isr")));
void uart0_lon_isr(void) __attribute__ ((weak, alias("unused_isr"))); void uart0_lon_isr(void) __attribute__ ((weak, alias("unused_isr")));
void uart0_status_isr(void) __attribute__ ((weak, alias("unused_isr"))); void uart0_status_isr(void) __attribute__ ((weak, alias("unused_isr")));
void uart0_error_isr(void) __attribute__ ((weak, alias("unused_isr"))); void uart0_error_isr(void) __attribute__ ((weak, alias("unused_isr")));
void cmt_isr(void) __attribute__ ((weak, alias("unused_isr"))); void cmt_isr(void) __attribute__ ((weak, alias("unused_isr")));
void rtc_alarm_isr(void) __attribute__ ((weak, alias("unused_isr"))); void rtc_alarm_isr(void) __attribute__ ((weak, alias("unused_isr")));
void rtc_seconds_isr(void) __attribute__ ((weak, alias("unused_isr"))); void rtc_seconds_isr(void) __attribute__ ((weak, alias("unused_isr")));
void pit_isr(void) __attribute__ ((weak, alias("unused_isr")));
void pit0_isr(void) __attribute__ ((weak, alias("unused_isr"))); void pit0_isr(void) __attribute__ ((weak, alias("unused_isr")));
void pit1_isr(void) __attribute__ ((weak, alias("unused_isr"))); void pit1_isr(void) __attribute__ ((weak, alias("unused_isr")));
void pit2_isr(void) __attribute__ ((weak, alias("unused_isr"))); void pit2_isr(void) __attribute__ ((weak, alias("unused_isr")));
void portc_isr(void) __attribute__ ((weak, alias("unused_isr"))); void portc_isr(void) __attribute__ ((weak, alias("unused_isr")));
void portd_isr(void) __attribute__ ((weak, alias("unused_isr"))); void portd_isr(void) __attribute__ ((weak, alias("unused_isr")));
void porte_isr(void) __attribute__ ((weak, alias("unused_isr"))); void porte_isr(void) __attribute__ ((weak, alias("unused_isr")));
void portcd_isr(void) __attribute__ ((weak, alias("unused_isr")));
void software_isr(void) __attribute__ ((weak, alias("unused_isr"))); void software_isr(void) __attribute__ ((weak, alias("unused_isr")));


#if defined(__MK20DX128__) #if defined(__MK20DX128__)
__attribute__ ((section(".dmabuffers"), used, aligned(256))) __attribute__ ((section(".dmabuffers"), used, aligned(256)))
#else
#elif defined(__MK20DX256__)
__attribute__ ((section(".dmabuffers"), used, aligned(512))) __attribute__ ((section(".dmabuffers"), used, aligned(512)))
#elif defined(__MKL26Z64__)
__attribute__ ((section(".dmabuffers"), used, aligned(256)))
#endif #endif
void (* _VectorsRam[NVIC_NUM_INTERRUPTS+16])(void); void (* _VectorsRam[NVIC_NUM_INTERRUPTS+16])(void);


unused_isr, // 108 -- unused_isr, // 108 --
unused_isr, // 109 -- unused_isr, // 109 --
software_isr, // 110 Software interrupt software_isr, // 110 Software interrupt
#elif defined(__MKL26Z64__)
dma_ch0_isr, // 16 DMA channel 0 transfer complete
dma_ch1_isr, // 17 DMA channel 1 transfer complete
dma_ch2_isr, // 18 DMA channel 2 transfer complete
dma_ch3_isr, // 19 DMA channel 3 transfer complete
unused_isr, // 20 --
flash_cmd_isr, // 21 Flash Memory Command complete
low_voltage_isr, // 22 Low-voltage detect/warning
wakeup_isr, // 23 Low Leakage Wakeup
i2c0_isr, // 24 I2C0
i2c1_isr, // 25 I2C1
spi0_isr, // 26 SPI0
spi1_isr, // 27 SPI1
uart0_status_isr, // 28 UART0 status & error
uart1_status_isr, // 29 UART1 status & error
uart2_status_isr, // 30 UART2 status & error
adc0_isr, // 31 ADC0
cmp0_isr, // 32 CMP0
ftm0_isr, // 33 FTM0
ftm1_isr, // 34 FTM1
ftm2_isr, // 35 FTM2
rtc_alarm_isr, // 36 RTC Alarm interrupt
rtc_seconds_isr, // 37 RTC Seconds interrupt
pit_isr, // 38 PIT Both Channels
i2s0_isr, // 39 I2S0 Transmit & Receive
usb_isr, // 40 USB OTG
dac0_isr, // 41 DAC0
tsi0_isr, // 42 TSI0
mcg_isr, // 43 MCG
lptmr_isr, // 44 Low Power Timer
software_isr, // 45 Software interrupt
porta_isr, // 46 Pin detect (Port A)
portcd_isr, // 47 Pin detect (Port C and D)
#endif #endif
}; };


//void usb_isr(void)
//{
//}


__attribute__ ((section(".flashconfig"), used)) __attribute__ ((section(".flashconfig"), used))
const uint8_t flashconfigbytes[16] = { const uint8_t flashconfigbytes[16] = {
extern void rtc_set(unsigned long t); extern void rtc_set(unsigned long t);




static void startup_default_early_hook(void) { WDOG_STCTRLH = WDOG_STCTRLH_ALLOWUPDATE; }
static void startup_default_early_hook(void) {
#if defined(KINETISK)
WDOG_STCTRLH = WDOG_STCTRLH_ALLOWUPDATE;
#elif defined(KINETISL)
SIM_COPC = 0; // disable the watchdog
#endif
}
static void startup_default_late_hook(void) {} static void startup_default_late_hook(void) {}
void startup_early_hook(void) __attribute__ ((weak, alias("startup_default_early_hook"))); void startup_early_hook(void) __attribute__ ((weak, alias("startup_default_early_hook")));
void startup_late_hook(void) __attribute__ ((weak, alias("startup_default_late_hook"))); void startup_late_hook(void) __attribute__ ((weak, alias("startup_default_late_hook")));



__attribute__ ((section(".startup"))) __attribute__ ((section(".startup")))
void ResetHandler(void) void ResetHandler(void)
{ {
#if F_CPU <= 2000000 #if F_CPU <= 2000000
volatile int n; volatile int n;
#endif #endif
//volatile int count;


#ifdef KINETISK
WDOG_UNLOCK = WDOG_UNLOCK_SEQ1; WDOG_UNLOCK = WDOG_UNLOCK_SEQ1;
WDOG_UNLOCK = WDOG_UNLOCK_SEQ2; WDOG_UNLOCK = WDOG_UNLOCK_SEQ2;
__asm__ volatile ("nop"); __asm__ volatile ("nop");
__asm__ volatile ("nop"); __asm__ volatile ("nop");
#endif
// programs using the watchdog timer or needing to initialize hardware as // programs using the watchdog timer or needing to initialize hardware as
// early as possible can implement startup_early_hook() // early as possible can implement startup_early_hook()
startup_early_hook(); startup_early_hook();
SIM_SCGC3 = SIM_SCGC3_ADC1 | SIM_SCGC3_FTM2; SIM_SCGC3 = SIM_SCGC3_ADC1 | SIM_SCGC3_FTM2;
SIM_SCGC5 = 0x00043F82; // clocks active to all GPIO SIM_SCGC5 = 0x00043F82; // clocks active to all GPIO
SIM_SCGC6 = SIM_SCGC6_RTC | SIM_SCGC6_FTM0 | SIM_SCGC6_FTM1 | SIM_SCGC6_ADC0 | SIM_SCGC6_FTFL; SIM_SCGC6 = SIM_SCGC6_RTC | SIM_SCGC6_FTM0 | SIM_SCGC6_FTM1 | SIM_SCGC6_ADC0 | SIM_SCGC6_FTFL;
#elif defined(__MKL26Z64__)
SIM_SCGC4 = SIM_SCGC4_USBOTG | 0xF0000030;
SIM_SCGC5 = 0x00003F82; // clocks active to all GPIO
SIM_SCGC6 = SIM_SCGC6_ADC0 | SIM_SCGC6_TPM0 | SIM_SCGC6_TPM1 | SIM_SCGC6_TPM2 | SIM_SCGC6_FTFL;
#endif #endif
#if 0
// testing only, enable ser_print
SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0) | SIM_CLKDIV1_OUTDIV4(1);
MCG_C4 |= MCG_C4_DMX32 | MCG_C4_DRST_DRS(1);
SIM_SOPT2 = SIM_SOPT2_UART0SRC(1) | SIM_SOPT2_TPMSRC(1);
SIM_SCGC4 |= 0x00000400;
UART0_BDH = 0;
UART0_BDL = 26; // 115200 at 48 MHz
UART0_C2 = UART_C2_TE;
PORTB_PCR17 = PORT_PCR_MUX(3);
#endif
#ifdef KINETISK
// if the RTC oscillator isn't enabled, get it started early // if the RTC oscillator isn't enabled, get it started early
if (!(RTC_CR & RTC_CR_OSCE)) { if (!(RTC_CR & RTC_CR_OSCE)) {
RTC_SR = 0; RTC_SR = 0;
RTC_CR = RTC_CR_SC16P | RTC_CR_SC4P | RTC_CR_OSCE; RTC_CR = RTC_CR_SC16P | RTC_CR_SC4P | RTC_CR_OSCE;
} }

#endif
// release I/O pins hold, if we woke up from VLLS mode // release I/O pins hold, if we woke up from VLLS mode
if (PMC_REGSC & PMC_REGSC_ACKISO) PMC_REGSC |= PMC_REGSC_ACKISO; if (PMC_REGSC & PMC_REGSC_ACKISO) PMC_REGSC |= PMC_REGSC_ACKISO;


while ((MCG_S & MCG_S_IREFST) != 0) ; while ((MCG_S & MCG_S_IREFST) != 0) ;
// wait for MCGOUT to use oscillator // wait for MCGOUT to use oscillator
while ((MCG_S & MCG_S_CLKST_MASK) != MCG_S_CLKST(2)) ; while ((MCG_S & MCG_S_CLKST_MASK) != MCG_S_CLKST(2)) ;

// now in FBE mode // now in FBE mode
// C1[CLKS] bits are written to 10 // C1[CLKS] bits are written to 10
// C1[IREFS] bit is written to 0 // C1[IREFS] bit is written to 0
// now we're in PBE mode // now we're in PBE mode
#endif #endif
#endif #endif

// now program the clock dividers // now program the clock dividers
#if F_CPU == 168000000 #if F_CPU == 168000000
// config divisors: 168 MHz core, 56 MHz bus, 33.6 MHz flash, USB = 168 * 2 / 7 // config divisors: 168 MHz core, 56 MHz bus, 33.6 MHz flash, USB = 168 * 2 / 7
SIM_CLKDIV2 = SIM_CLKDIV2_USBDIV(2) | SIM_CLKDIV2_USBFRAC; SIM_CLKDIV2 = SIM_CLKDIV2_USBDIV(2) | SIM_CLKDIV2_USBFRAC;
#elif F_CPU == 48000000 #elif F_CPU == 48000000
// config divisors: 48 MHz core, 48 MHz bus, 24 MHz flash, USB = 96 / 2 // config divisors: 48 MHz core, 48 MHz bus, 24 MHz flash, USB = 96 / 2
#if defined(KINETISK)
SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(1) | SIM_CLKDIV1_OUTDIV2(1) | SIM_CLKDIV1_OUTDIV4(3); SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(1) | SIM_CLKDIV1_OUTDIV2(1) | SIM_CLKDIV1_OUTDIV4(3);
SIM_CLKDIV2 = SIM_CLKDIV2_USBDIV(1); SIM_CLKDIV2 = SIM_CLKDIV2_USBDIV(1);
#elif defined(KINETISL)
SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(1) | SIM_CLKDIV1_OUTDIV4(1);
#endif
#elif F_CPU == 24000000 #elif F_CPU == 24000000
// config divisors: 24 MHz core, 24 MHz bus, 24 MHz flash, USB = 96 / 2 // config divisors: 24 MHz core, 24 MHz bus, 24 MHz flash, USB = 96 / 2
#if defined(KINETISK)
SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(3) | SIM_CLKDIV1_OUTDIV2(3) | SIM_CLKDIV1_OUTDIV4(3); SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(3) | SIM_CLKDIV1_OUTDIV2(3) | SIM_CLKDIV1_OUTDIV4(3);
SIM_CLKDIV2 = SIM_CLKDIV2_USBDIV(1); SIM_CLKDIV2 = SIM_CLKDIV2_USBDIV(1);
#elif defined(KINETISL)
SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(3) | SIM_CLKDIV1_OUTDIV4(0);
#endif
#elif F_CPU == 16000000 #elif F_CPU == 16000000
// config divisors: 16 MHz core, 16 MHz bus, 16 MHz flash // config divisors: 16 MHz core, 16 MHz bus, 16 MHz flash
SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0) | SIM_CLKDIV1_OUTDIV2(0) | SIM_CLKDIV1_OUTDIV4(0); SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0) | SIM_CLKDIV1_OUTDIV2(0) | SIM_CLKDIV1_OUTDIV4(0);
while ((MCG_S & MCG_S_CLKST_MASK) != MCG_S_CLKST(3)) ; while ((MCG_S & MCG_S_CLKST_MASK) != MCG_S_CLKST(3)) ;
// now we're in PEE mode // now we're in PEE mode
// USB uses PLL clock, trace is CPU clock, CLKOUT=OSCERCLK0 // USB uses PLL clock, trace is CPU clock, CLKOUT=OSCERCLK0
SIM_SOPT2 = SIM_SOPT2_USBSRC | SIM_SOPT2_PLLFLLSEL | SIM_SOPT2_TRACECLKSEL | SIM_SOPT2_CLKOUTSEL(6);
#if defined(KINETISK)
SIM_SOPT2 = SIM_SOPT2_USBSRC | SIM_SOPT2_PLLFLLSEL | SIM_SOPT2_TRACECLKSEL
| SIM_SOPT2_CLKOUTSEL(6);
#elif defined(KINETISL)
SIM_SOPT2 = SIM_SOPT2_USBSRC | SIM_SOPT2_PLLFLLSEL | SIM_SOPT2_CLKOUTSEL(6)
| SIM_SOPT2_UART0SRC(1) | SIM_SOPT2_TPMSRC(1);
#endif
#else #else
SIM_SOPT2 = SIM_SOPT2_TRACECLKSEL | SIM_SOPT2_CLKOUTSEL(3); SIM_SOPT2 = SIM_SOPT2_TRACECLKSEL | SIM_SOPT2_CLKOUTSEL(3);
#endif #endif
__enable_irq(); __enable_irq();


_init_Teensyduino_internal_(); _init_Teensyduino_internal_();
#if defined(KINETISK)
if (RTC_SR & RTC_SR_TIF) { if (RTC_SR & RTC_SR_TIF) {
// TODO: this should probably set the time more agressively, if // TODO: this should probably set the time more agressively, if
// we could reliably detect the first reboot after programming. // we could reliably detect the first reboot after programming.
rtc_set(TIME_T); rtc_set(TIME_T);
} }
#endif
__libc_init_array(); __libc_init_array();


startup_late_hook(); startup_late_hook();

+ 110
- 0
teensy3/mkl26z64.ld View File

/* Teensyduino Core Library
* http://www.pjrc.com/teensy/
* Copyright (c) 2014 PJRC.COM, 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:
*
* 1. The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* 2. If the Software is incorporated into a build system that allows
* selection among a list of target devices, then similar target
* devices manufactured by PJRC.COM must be included in the list of
* target devices and selectable in the same manner.
*
* 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.
*/

MEMORY
{
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 60K
RAM (rwx) : ORIGIN = 0x1FFFF800, LENGTH = 8K
}


SECTIONS
{
.text : {
. = 0;
KEEP(*(.vectors))
*(.startup*)
/* TODO: does linker detect startup overflow onto flashconfig? */
. = 0x400;
KEEP(*(.flashconfig*))
*(.text*)
*(.rodata*)
. = ALIGN(4);
KEEP(*(.init))
. = ALIGN(4);
__preinit_array_start = .;
KEEP (*(.preinit_array))
__preinit_array_end = .;
__init_array_start = .;
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array))
__init_array_end = .;
} > FLASH = 0xFF

.ARM.exidx : {
__exidx_start = .;
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
__exidx_end = .;
} > FLASH
_etext = .;

.usbdescriptortable (NOLOAD) : {
/* . = ORIGIN(RAM); */
. = ALIGN(512);
*(.usbdescriptortable*)
} > RAM

.dmabuffers (NOLOAD) : {
. = ALIGN(4);
*(.dmabuffers*)
} > RAM

.usbbuffers (NOLOAD) : {
. = ALIGN(4);
*(.usbbuffers*)
} > RAM

.data : AT (_etext) {
. = ALIGN(4);
_sdata = .;
*(.fastrun*)
*(.data*)
. = ALIGN(4);
_edata = .;
} > RAM

.noinit (NOLOAD) : {
*(.noinit*)
} > RAM

.bss : {
. = ALIGN(4);
_sbss = .;
*(.bss*)
*(COMMON)
. = ALIGN(4);
_ebss = .;
__bss_end = .;
} > RAM

_estack = ORIGIN(RAM) + LENGTH(RAM);
}



+ 53
- 9
teensy3/pins_arduino.h View File



#include <stdint.h> #include <stdint.h>


// A0-A9 are always digital 14-23, for Arduino compatibility
const static uint8_t A0 = 14; const static uint8_t A0 = 14;
const static uint8_t A1 = 15; const static uint8_t A1 = 15;
const static uint8_t A2 = 16; const static uint8_t A2 = 16;
const static uint8_t A7 = 21; const static uint8_t A7 = 21;
const static uint8_t A8 = 22; const static uint8_t A8 = 22;
const static uint8_t A9 = 23; const static uint8_t A9 = 23;
#if defined(__MK20DX128__)
const static uint8_t A10 = 34;
const static uint8_t A11 = 35;
const static uint8_t A12 = 36;
const static uint8_t A13 = 37;
#elif defined(__MK20DX256__)
const static uint8_t A10 = 34; const static uint8_t A10 = 34;
const static uint8_t A11 = 35; const static uint8_t A11 = 35;
const static uint8_t A12 = 36; const static uint8_t A12 = 36;
const static uint8_t A13 = 37; const static uint8_t A13 = 37;
const static uint8_t A14 = 40; const static uint8_t A14 = 40;

const static uint8_t A15 = 26; const static uint8_t A15 = 26;
const static uint8_t A16 = 27; const static uint8_t A16 = 27;
const static uint8_t A17 = 28; const static uint8_t A17 = 28;
const static uint8_t A18 = 29; const static uint8_t A18 = 29;
const static uint8_t A19 = 30; const static uint8_t A19 = 30;
const static uint8_t A20 = 31; const static uint8_t A20 = 31;
#elif defined(__MKL26Z64__)
const static uint8_t A10 = 24;
const static uint8_t A11 = 25;
const static uint8_t A12 = 26;
#endif


const static uint8_t SS = 10; const static uint8_t SS = 10;
const static uint8_t MOSI = 11; const static uint8_t MOSI = 11;
const static uint8_t SCL = 19; const static uint8_t SCL = 19;




#define NUM_DIGITAL_PINS 34
#define NUM_ANALOG_INPUTS 14
#define NUM_DIGITAL_PINS CORE_NUM_DIGITAL
#define NUM_ANALOG_INPUTS CORE_NUM_ANALOG


#define analogInputToDigitalPin(p) (((p) < 10) ? (p) + 14 : -1)
#define digitalPinHasPWM(p) (((p) >= 3 && (p) <= 6) || (p) == 9 || (p) == 10 || ((p) >= 20 && (p) <= 23))


#define NOT_AN_INTERRUPT -1 #define NOT_AN_INTERRUPT -1
#define digitalPinToInterrupt(p) ((p) < NUM_DIGITAL_PINS ? (p) : -1)




#if defined(__MK20DX128__)
#define analogInputToDigitalPin(p) (((p) <= 9) ? (p) + 14 : (((p) <= 13) ? (p) + 24 : -1))
#define digitalPinHasPWM(p) (((p) >= 3 && (p) <= 6) || (p) == 9 || (p) == 10 || ((p) >= 20 && (p) <= 23))
#define digitalPinToInterrupt(p) ((p) < NUM_DIGITAL_PINS ? (p) : -1)
#elif defined(__MK20DX256__)
#define analogInputToDigitalPin(p) (((p) <= 9) ? (p) + 14 : (((p) <= 13) ? (p) + 24 : (((p) == 14) ? 40 : (((p) <= 20) ? (p) + 11 : -1))))
#define digitalPinHasPWM(p) (((p) >= 3 && (p) <= 6) || (p) == 9 || (p) == 10 || ((p) >= 20 && (p) <= 23) || (p) == 25 || (p) == 32)
#define digitalPinToInterrupt(p) ((p) < NUM_DIGITAL_PINS ? (p) : -1)
#elif defined(__MKL26Z64__)
#define analogInputToDigitalPin(p) (((p) <= 9) ? (p) + 14 : (((p) <= 12) ? (p) + 14 : -1))
#define digitalPinHasPWM(p) ((p) == 3 || (p) == 4 || (p) == 6 || (p) == 9 || (p) == 10 || (p) <= 16 || (p) == 17 || (p) == 20 || (p) == 22 || (p) == 23)
#define digitalPinToInterrupt(p) ((((p) >= 2 && (p) <= 15) || ((p) >= 20 && (p) <= 23)) ? (p) : -1)
#endif


#if defined(KINETISK)
struct digital_pin_bitband_and_config_table_struct { struct digital_pin_bitband_and_config_table_struct {
volatile uint32_t *reg; volatile uint32_t *reg;
volatile uint32_t *config; volatile uint32_t *config;
}; };
extern const struct digital_pin_bitband_and_config_table_struct digital_pin_to_info_PGM[]; extern const struct digital_pin_bitband_and_config_table_struct digital_pin_to_info_PGM[];

// compatibility macros // compatibility macros
#define digitalPinToPort(pin) (pin) #define digitalPinToPort(pin) (pin)
#define digitalPinToBitMask(pin) (1) #define digitalPinToBitMask(pin) (1)
#define portInputRegister(pin) ((volatile uint8_t *)(digital_pin_to_info_PGM[(pin)].reg + 128)) #define portInputRegister(pin) ((volatile uint8_t *)(digital_pin_to_info_PGM[(pin)].reg + 128))
#define portModeRegister(pin) ((volatile uint8_t *)(digital_pin_to_info_PGM[(pin)].reg + 160)) #define portModeRegister(pin) ((volatile uint8_t *)(digital_pin_to_info_PGM[(pin)].reg + 160))
#define portConfigRegister(pin) ((volatile uint32_t *)(digital_pin_to_info_PGM[(pin)].config)) #define portConfigRegister(pin) ((volatile uint32_t *)(digital_pin_to_info_PGM[(pin)].config))


#define digitalPinToPortReg(pin) (portOutputRegister(pin)) #define digitalPinToPortReg(pin) (portOutputRegister(pin))
#define digitalPinToBit(pin) (1) #define digitalPinToBit(pin) (1)


#elif defined(KINETISL)
struct digital_pin_bitband_and_config_table_struct {
volatile uint8_t *reg;
volatile uint32_t *config;
uint8_t mask;
};
extern const struct digital_pin_bitband_and_config_table_struct digital_pin_to_info_PGM[];
// compatibility macros
#define digitalPinToPort(pin) (pin)
#define digitalPinToBitMask(pin) (digital_pin_to_info_PGM[(pin)].mask)
#define portOutputRegister(pin) ((digital_pin_to_info_PGM[(pin)].reg + 0))
#define portSetRegister(pin) ((digital_pin_to_info_PGM[(pin)].reg + 4))
#define portClearRegister(pin) ((digital_pin_to_info_PGM[(pin)].reg + 8))
#define portToggleRegister(pin) ((digital_pin_to_info_PGM[(pin)].reg + 12))
#define portInputRegister(pin) ((digital_pin_to_info_PGM[(pin)].reg + 16))
#define portModeRegister(pin) ((digital_pin_to_info_PGM[(pin)].reg + 20))
#define portConfigRegister(pin) ((digital_pin_to_info_PGM[(pin)].config))
#define digitalPinToPortReg(pin) (portOutputRegister(pin))
//#define digitalPinToBit(pin) (1)

#endif




#define NOT_ON_TIMER 0 #define NOT_ON_TIMER 0
static inline uint8_t digitalPinToTimer(uint8_t) __attribute__((always_inline, unused)); static inline uint8_t digitalPinToTimer(uint8_t) __attribute__((always_inline, unused));

+ 255
- 101
teensy3/pins_teensy.c View File

#include "pins_arduino.h" #include "pins_arduino.h"
#include "HardwareSerial.h" #include "HardwareSerial.h"


#if 0
// moved to pins_arduino.h
struct digital_pin_bitband_and_config_table_struct {
volatile uint32_t *reg;
volatile uint32_t *config;
};
const struct digital_pin_bitband_and_config_table_struct digital_pin_to_info_PGM[];

// compatibility macros
#define digitalPinToPort(pin) (pin)
#define digitalPinToBitMask(pin) (1)
#define portOutputRegister(pin) ((volatile uint8_t *)(digital_pin_to_info_PGM[(pin)].reg + 0))
#define portSetRegister(pin) ((volatile uint8_t *)(digital_pin_to_info_PGM[(pin)].reg + 32))
#define portClearRegister(pin) ((volatile uint8_t *)(digital_pin_to_info_PGM[(pin)].reg + 64))
#define portToggleRegister(pin) ((volatile uint8_t *)(digital_pin_to_info_PGM[(pin)].reg + 96))
#define portInputRegister(pin) ((volatile uint8_t *)(digital_pin_to_info_PGM[(pin)].reg + 128))
#define portModeRegister(pin) ((volatile uint8_t *)(digital_pin_to_info_PGM[(pin)].reg + 160))
#define portConfigRegister(pin) ((volatile uint32_t *)(digital_pin_to_info_PGM[(pin)].config))
#endif

//#define digitalPinToTimer(P) ( pgm_read_byte( digital_pin_to_timer_PGM + (P) ) )
//#define analogInPinToBit(P) (P)


#if defined(KINETISK)
#define GPIO_BITBAND_ADDR(reg, bit) (((uint32_t)&(reg) - 0x40000000) * 32 + (bit) * 4 + 0x42000000) #define GPIO_BITBAND_ADDR(reg, bit) (((uint32_t)&(reg) - 0x40000000) * 32 + (bit) * 4 + 0x42000000)
#define GPIO_BITBAND_PTR(reg, bit) ((uint32_t *)GPIO_BITBAND_ADDR((reg), (bit))) #define GPIO_BITBAND_PTR(reg, bit) ((uint32_t *)GPIO_BITBAND_ADDR((reg), (bit)))
//#define GPIO_SET_BIT(reg, bit) (*GPIO_BITBAND_PTR((reg), (bit)) = 1) //#define GPIO_SET_BIT(reg, bit) (*GPIO_BITBAND_PTR((reg), (bit)) = 1)
//#define GPIO_CLR_BIT(reg, bit) (*GPIO_BITBAND_PTR((reg), (bit)) = 0) //#define GPIO_CLR_BIT(reg, bit) (*GPIO_BITBAND_PTR((reg), (bit)) = 0)

const struct digital_pin_bitband_and_config_table_struct digital_pin_to_info_PGM[] = { const struct digital_pin_bitband_and_config_table_struct digital_pin_to_info_PGM[] = {
{GPIO_BITBAND_PTR(CORE_PIN0_PORTREG, CORE_PIN0_BIT), &CORE_PIN0_CONFIG}, {GPIO_BITBAND_PTR(CORE_PIN0_PORTREG, CORE_PIN0_BIT), &CORE_PIN0_CONFIG},
{GPIO_BITBAND_PTR(CORE_PIN1_PORTREG, CORE_PIN1_BIT), &CORE_PIN1_CONFIG}, {GPIO_BITBAND_PTR(CORE_PIN1_PORTREG, CORE_PIN1_BIT), &CORE_PIN1_CONFIG},
{GPIO_BITBAND_PTR(CORE_PIN33_PORTREG, CORE_PIN33_BIT), &CORE_PIN33_CONFIG} {GPIO_BITBAND_PTR(CORE_PIN33_PORTREG, CORE_PIN33_BIT), &CORE_PIN33_CONFIG}
}; };


#elif defined(KINETISL)
const struct digital_pin_bitband_and_config_table_struct digital_pin_to_info_PGM[] = {
{((volatile uint8_t *)&CORE_PIN0_PORTREG + (CORE_PIN0_BIT >> 3)), &CORE_PIN0_CONFIG, (1<<(CORE_PIN0_BIT & 7))},
{((volatile uint8_t *)&CORE_PIN1_PORTREG + (CORE_PIN1_BIT >> 3)), &CORE_PIN1_CONFIG, (1<<(CORE_PIN1_BIT & 7))},
{((volatile uint8_t *)&CORE_PIN2_PORTREG + (CORE_PIN2_BIT >> 3)), &CORE_PIN2_CONFIG, (1<<(CORE_PIN2_BIT & 7))},
{((volatile uint8_t *)&CORE_PIN3_PORTREG + (CORE_PIN3_BIT >> 3)), &CORE_PIN3_CONFIG, (1<<(CORE_PIN3_BIT & 7))},
{((volatile uint8_t *)&CORE_PIN4_PORTREG + (CORE_PIN4_BIT >> 3)), &CORE_PIN4_CONFIG, (1<<(CORE_PIN4_BIT & 7))},
{((volatile uint8_t *)&CORE_PIN5_PORTREG + (CORE_PIN5_BIT >> 3)), &CORE_PIN5_CONFIG, (1<<(CORE_PIN5_BIT & 7))},
{((volatile uint8_t *)&CORE_PIN6_PORTREG + (CORE_PIN6_BIT >> 3)), &CORE_PIN6_CONFIG, (1<<(CORE_PIN6_BIT & 7))},
{((volatile uint8_t *)&CORE_PIN7_PORTREG + (CORE_PIN7_BIT >> 3)), &CORE_PIN7_CONFIG, (1<<(CORE_PIN7_BIT & 7))},
{((volatile uint8_t *)&CORE_PIN8_PORTREG + (CORE_PIN8_BIT >> 3)), &CORE_PIN8_CONFIG, (1<<(CORE_PIN8_BIT & 7))},
{((volatile uint8_t *)&CORE_PIN9_PORTREG + (CORE_PIN9_BIT >> 3)), &CORE_PIN9_CONFIG, (1<<(CORE_PIN9_BIT & 7))},
{((volatile uint8_t *)&CORE_PIN10_PORTREG + (CORE_PIN10_BIT >> 3)), &CORE_PIN10_CONFIG, (1<<(CORE_PIN10_BIT & 7))},
{((volatile uint8_t *)&CORE_PIN11_PORTREG + (CORE_PIN11_BIT >> 3)), &CORE_PIN11_CONFIG, (1<<(CORE_PIN11_BIT & 7))},
{((volatile uint8_t *)&CORE_PIN12_PORTREG + (CORE_PIN12_BIT >> 3)), &CORE_PIN12_CONFIG, (1<<(CORE_PIN12_BIT & 7))},
{((volatile uint8_t *)&CORE_PIN13_PORTREG + (CORE_PIN13_BIT >> 3)), &CORE_PIN13_CONFIG, (1<<(CORE_PIN13_BIT & 7))},
{((volatile uint8_t *)&CORE_PIN14_PORTREG + (CORE_PIN14_BIT >> 3)), &CORE_PIN14_CONFIG, (1<<(CORE_PIN14_BIT & 7))},
{((volatile uint8_t *)&CORE_PIN15_PORTREG + (CORE_PIN15_BIT >> 3)), &CORE_PIN15_CONFIG, (1<<(CORE_PIN15_BIT & 7))},
{((volatile uint8_t *)&CORE_PIN16_PORTREG + (CORE_PIN16_BIT >> 3)), &CORE_PIN16_CONFIG, (1<<(CORE_PIN16_BIT & 7))},
{((volatile uint8_t *)&CORE_PIN17_PORTREG + (CORE_PIN17_BIT >> 3)), &CORE_PIN17_CONFIG, (1<<(CORE_PIN17_BIT & 7))},
{((volatile uint8_t *)&CORE_PIN18_PORTREG + (CORE_PIN18_BIT >> 3)), &CORE_PIN18_CONFIG, (1<<(CORE_PIN18_BIT & 7))},
{((volatile uint8_t *)&CORE_PIN19_PORTREG + (CORE_PIN19_BIT >> 3)), &CORE_PIN19_CONFIG, (1<<(CORE_PIN19_BIT & 7))},
{((volatile uint8_t *)&CORE_PIN20_PORTREG + (CORE_PIN20_BIT >> 3)), &CORE_PIN20_CONFIG, (1<<(CORE_PIN20_BIT & 7))},
{((volatile uint8_t *)&CORE_PIN21_PORTREG + (CORE_PIN21_BIT >> 3)), &CORE_PIN21_CONFIG, (1<<(CORE_PIN21_BIT & 7))},
{((volatile uint8_t *)&CORE_PIN22_PORTREG + (CORE_PIN22_BIT >> 3)), &CORE_PIN22_CONFIG, (1<<(CORE_PIN22_BIT & 7))},
{((volatile uint8_t *)&CORE_PIN23_PORTREG + (CORE_PIN23_BIT >> 3)), &CORE_PIN23_CONFIG, (1<<(CORE_PIN23_BIT & 7))},
{((volatile uint8_t *)&CORE_PIN24_PORTREG + (CORE_PIN24_BIT >> 3)), &CORE_PIN24_CONFIG, (1<<(CORE_PIN24_BIT & 7))},
{((volatile uint8_t *)&CORE_PIN25_PORTREG + (CORE_PIN25_BIT >> 3)), &CORE_PIN25_CONFIG, (1<<(CORE_PIN25_BIT & 7))},
{((volatile uint8_t *)&CORE_PIN26_PORTREG + (CORE_PIN26_BIT >> 3)), &CORE_PIN26_CONFIG, (1<<(CORE_PIN26_BIT & 7))}
};


#endif




typedef void (*voidFuncPtr)(void); typedef void (*voidFuncPtr)(void);
volatile static voidFuncPtr intFunc[CORE_NUM_DIGITAL]; volatile static voidFuncPtr intFunc[CORE_NUM_DIGITAL];

void init_pin_interrupts(void)
{
//SIM_SCGC5 = 0x00043F82; // clocks active to all GPIO
NVIC_ENABLE_IRQ(IRQ_PORTA);
NVIC_ENABLE_IRQ(IRQ_PORTB);
NVIC_ENABLE_IRQ(IRQ_PORTC);
NVIC_ENABLE_IRQ(IRQ_PORTD);
NVIC_ENABLE_IRQ(IRQ_PORTE);
// TODO: maybe these should be set to a lower priority
// so if the user puts lots of slow code on attachInterrupt
// fast interrupts will still be serviced quickly?
}
#if defined(KINETISK)
static void porta_interrupt(void);
static void portb_interrupt(void);
static void portc_interrupt(void);
static void portd_interrupt(void);
static void porte_interrupt(void);
#elif defined(KINETISL)
static void porta_interrupt(void);
static void portcd_interrupt(void);
#endif


void attachInterruptVector(enum IRQ_NUMBER_t irq, void (*function)(void)) void attachInterruptVector(enum IRQ_NUMBER_t irq, void (*function)(void))
{ {
mask = (mask << 16) | 0x01000000; mask = (mask << 16) | 0x01000000;
config = portConfigRegister(pin); config = portConfigRegister(pin);


#if defined(KINETISK)
attachInterruptVector(IRQ_PORTA, porta_interrupt);
attachInterruptVector(IRQ_PORTB, portb_interrupt);
attachInterruptVector(IRQ_PORTC, portc_interrupt);
attachInterruptVector(IRQ_PORTD, portd_interrupt);
attachInterruptVector(IRQ_PORTE, porte_interrupt);
#elif defined(KINETISL)
attachInterruptVector(IRQ_PORTA, porta_interrupt);
attachInterruptVector(IRQ_PORTCD, portcd_interrupt);
#endif
__disable_irq(); __disable_irq();
cfg = *config; cfg = *config;
cfg &= ~0x000F0000; // disable any previous interrupt cfg &= ~0x000F0000; // disable any previous interrupt
__enable_irq(); __enable_irq();
} }


#if defined(__MK20DX128__) || defined(__MK20DX256__)


void porta_isr(void)
static void porta_interrupt(void)
{ {
uint32_t isfr = PORTA_ISFR; uint32_t isfr = PORTA_ISFR;
PORTA_ISFR = isfr; PORTA_ISFR = isfr;
if ((isfr & CORE_PIN33_BITMASK) && intFunc[33]) intFunc[33](); if ((isfr & CORE_PIN33_BITMASK) && intFunc[33]) intFunc[33]();
} }


void portb_isr(void)
static void portb_interrupt(void)
{ {
uint32_t isfr = PORTB_ISFR; uint32_t isfr = PORTB_ISFR;
PORTB_ISFR = isfr; PORTB_ISFR = isfr;
if ((isfr & CORE_PIN32_BITMASK) && intFunc[32]) intFunc[32](); if ((isfr & CORE_PIN32_BITMASK) && intFunc[32]) intFunc[32]();
} }


void portc_isr(void)
static void portc_interrupt(void)
{ {
// TODO: these are inefficent. Use CLZ somehow.... // TODO: these are inefficent. Use CLZ somehow....
uint32_t isfr = PORTC_ISFR; uint32_t isfr = PORTC_ISFR;
if ((isfr & CORE_PIN30_BITMASK) && intFunc[30]) intFunc[30](); if ((isfr & CORE_PIN30_BITMASK) && intFunc[30]) intFunc[30]();
} }


void portd_isr(void)
static void portd_interrupt(void)
{ {
uint32_t isfr = PORTD_ISFR; uint32_t isfr = PORTD_ISFR;
PORTD_ISFR = isfr; PORTD_ISFR = isfr;
if ((isfr & CORE_PIN21_BITMASK) && intFunc[21]) intFunc[21](); if ((isfr & CORE_PIN21_BITMASK) && intFunc[21]) intFunc[21]();
} }


void porte_isr(void)
static void porte_interrupt(void)
{ {
uint32_t isfr = PORTE_ISFR; uint32_t isfr = PORTE_ISFR;
PORTE_ISFR = isfr; PORTE_ISFR = isfr;
if ((isfr & CORE_PIN31_BITMASK) && intFunc[31]) intFunc[31](); if ((isfr & CORE_PIN31_BITMASK) && intFunc[31]) intFunc[31]();
} }


#elif defined(__MKL26Z64__)

static void porta_interrupt(void)
{
uint32_t isfr = PORTA_ISFR;
PORTA_ISFR = isfr;
if ((isfr & CORE_PIN3_BITMASK) && intFunc[3]) intFunc[3]();
if ((isfr & CORE_PIN4_BITMASK) && intFunc[4]) intFunc[4]();
}

static void portcd_interrupt(void)
{
uint32_t isfr = PORTC_ISFR;
PORTC_ISFR = isfr;
if ((isfr & CORE_PIN9_BITMASK) && intFunc[9]) intFunc[9]();
if ((isfr & CORE_PIN10_BITMASK) && intFunc[10]) intFunc[10]();
if ((isfr & CORE_PIN11_BITMASK) && intFunc[11]) intFunc[11]();
if ((isfr & CORE_PIN12_BITMASK) && intFunc[12]) intFunc[12]();
if ((isfr & CORE_PIN13_BITMASK) && intFunc[13]) intFunc[13]();
if ((isfr & CORE_PIN15_BITMASK) && intFunc[15]) intFunc[15]();
if ((isfr & CORE_PIN22_BITMASK) && intFunc[22]) intFunc[22]();
if ((isfr & CORE_PIN23_BITMASK) && intFunc[23]) intFunc[23]();
isfr = PORTD_ISFR;
PORTD_ISFR = isfr;
if ((isfr & CORE_PIN2_BITMASK) && intFunc[2]) intFunc[2]();
if ((isfr & CORE_PIN5_BITMASK) && intFunc[5]) intFunc[5]();
if ((isfr & CORE_PIN6_BITMASK) && intFunc[6]) intFunc[6]();
if ((isfr & CORE_PIN7_BITMASK) && intFunc[7]) intFunc[7]();
if ((isfr & CORE_PIN8_BITMASK) && intFunc[8]) intFunc[8]();
if ((isfr & CORE_PIN14_BITMASK) && intFunc[14]) intFunc[14]();
if ((isfr & CORE_PIN20_BITMASK) && intFunc[20]) intFunc[20]();
if ((isfr & CORE_PIN21_BITMASK) && intFunc[21]) intFunc[21]();
}


#endif




unsigned long rtc_get(void) unsigned long rtc_get(void)


// create a default PWM at the same 488.28 Hz as Arduino Uno // create a default PWM at the same 488.28 Hz as Arduino Uno


#if F_BUS == 60000000
#if defined(KINETISK)
#define F_TIMER F_BUS
#elif defined(KINETISL)
#define F_TIMER (F_PLL/2)
#endif

#if F_TIMER == 60000000
#define DEFAULT_FTM_MOD (61440 - 1) #define DEFAULT_FTM_MOD (61440 - 1)
#define DEFAULT_FTM_PRESCALE 1 #define DEFAULT_FTM_PRESCALE 1
#elif F_BUS == 56000000
#elif F_TIMER == 56000000
#define DEFAULT_FTM_MOD (57344 - 1) #define DEFAULT_FTM_MOD (57344 - 1)
#define DEFAULT_FTM_PRESCALE 1 #define DEFAULT_FTM_PRESCALE 1
#elif F_BUS == 48000000
#elif F_TIMER == 48000000
#define DEFAULT_FTM_MOD (49152 - 1) #define DEFAULT_FTM_MOD (49152 - 1)
#define DEFAULT_FTM_PRESCALE 1 #define DEFAULT_FTM_PRESCALE 1
#elif F_BUS == 40000000
#elif F_TIMER == 40000000
#define DEFAULT_FTM_MOD (40960 - 1) #define DEFAULT_FTM_MOD (40960 - 1)
#define DEFAULT_FTM_PRESCALE 1 #define DEFAULT_FTM_PRESCALE 1
#elif F_BUS == 36000000
#elif F_TIMER == 36000000
#define DEFAULT_FTM_MOD (36864 - 1) #define DEFAULT_FTM_MOD (36864 - 1)
#define DEFAULT_FTM_PRESCALE 1 #define DEFAULT_FTM_PRESCALE 1
#elif F_BUS == 24000000
#elif F_TIMER == 24000000
#define DEFAULT_FTM_MOD (49152 - 1) #define DEFAULT_FTM_MOD (49152 - 1)
#define DEFAULT_FTM_PRESCALE 0 #define DEFAULT_FTM_PRESCALE 0
#elif F_BUS == 16000000
#elif F_TIMER == 16000000
#define DEFAULT_FTM_MOD (32768 - 1) #define DEFAULT_FTM_MOD (32768 - 1)
#define DEFAULT_FTM_PRESCALE 0 #define DEFAULT_FTM_PRESCALE 0
#elif F_BUS == 8000000
#elif F_TIMER == 8000000
#define DEFAULT_FTM_MOD (16384 - 1) #define DEFAULT_FTM_MOD (16384 - 1)
#define DEFAULT_FTM_PRESCALE 0 #define DEFAULT_FTM_PRESCALE 0
#elif F_BUS == 4000000
#elif F_TIMER == 4000000
#define DEFAULT_FTM_MOD (8192 - 1) #define DEFAULT_FTM_MOD (8192 - 1)
#define DEFAULT_FTM_PRESCALE 0 #define DEFAULT_FTM_PRESCALE 0
#elif F_BUS == 2000000
#elif F_TIMER == 2000000
#define DEFAULT_FTM_MOD (4096 - 1) #define DEFAULT_FTM_MOD (4096 - 1)
#define DEFAULT_FTM_PRESCALE 0 #define DEFAULT_FTM_PRESCALE 0
#endif #endif
//void init_pins(void) //void init_pins(void)
void _init_Teensyduino_internal_(void) void _init_Teensyduino_internal_(void)
{ {
init_pin_interrupts();

#if defined(__MK20DX128__) || defined(__MK20DX256__)
NVIC_ENABLE_IRQ(IRQ_PORTA);
NVIC_ENABLE_IRQ(IRQ_PORTB);
NVIC_ENABLE_IRQ(IRQ_PORTC);
NVIC_ENABLE_IRQ(IRQ_PORTD);
NVIC_ENABLE_IRQ(IRQ_PORTE);
#elif defined(__MKL26Z64__)
NVIC_ENABLE_IRQ(IRQ_PORTA);
NVIC_ENABLE_IRQ(IRQ_PORTCD);
#endif
//SIM_SCGC6 |= SIM_SCGC6_FTM0; // TODO: use bitband for atomic read-mod-write //SIM_SCGC6 |= SIM_SCGC6_FTM0; // TODO: use bitband for atomic read-mod-write
//SIM_SCGC6 |= SIM_SCGC6_FTM1; //SIM_SCGC6 |= SIM_SCGC6_FTM1;
FTM0_CNT = 0; FTM0_CNT = 0;
FTM0_C3SC = 0x28; FTM0_C3SC = 0x28;
FTM0_C4SC = 0x28; FTM0_C4SC = 0x28;
FTM0_C5SC = 0x28; FTM0_C5SC = 0x28;
#if defined(__MK20DX128__) || defined(__MK20DX256__)
FTM0_C6SC = 0x28; FTM0_C6SC = 0x28;
FTM0_C7SC = 0x28; FTM0_C7SC = 0x28;
#endif
FTM0_SC = FTM_SC_CLKS(1) | FTM_SC_PS(DEFAULT_FTM_PRESCALE); FTM0_SC = FTM_SC_CLKS(1) | FTM_SC_PS(DEFAULT_FTM_PRESCALE);
FTM1_CNT = 0; FTM1_CNT = 0;
FTM1_MOD = DEFAULT_FTM_MOD; FTM1_MOD = DEFAULT_FTM_MOD;
FTM1_C0SC = 0x28; FTM1_C0SC = 0x28;
FTM1_C1SC = 0x28; FTM1_C1SC = 0x28;
FTM1_SC = FTM_SC_CLKS(1) | FTM_SC_PS(DEFAULT_FTM_PRESCALE); FTM1_SC = FTM_SC_CLKS(1) | FTM_SC_PS(DEFAULT_FTM_PRESCALE);
#if defined(__MK20DX256__)
#if defined(__MK20DX256__) || defined(__MKL26Z64__)
FTM2_CNT = 0; FTM2_CNT = 0;
FTM2_MOD = DEFAULT_FTM_MOD; FTM2_MOD = DEFAULT_FTM_MOD;
FTM2_C0SC = 0x28; FTM2_C0SC = 0x28;
FTM2_C1SC = 0x28; FTM2_C1SC = 0x28;
FTM2_SC = FTM_SC_CLKS(1) | FTM_SC_PS(DEFAULT_FTM_PRESCALE); FTM2_SC = FTM_SC_CLKS(1) | FTM_SC_PS(DEFAULT_FTM_PRESCALE);
#endif #endif

analog_init(); analog_init();
//delay(100); // TODO: this is not necessary, right? //delay(100); // TODO: this is not necessary, right?
delay(4); delay(4);
} }




#if defined(__MK20DX128__)
#define FTM0_CH0_PIN 22
#define FTM0_CH1_PIN 23
#define FTM0_CH2_PIN 9
#define FTM0_CH3_PIN 10
#define FTM0_CH4_PIN 6
#define FTM0_CH5_PIN 20
#define FTM0_CH6_PIN 21
#define FTM0_CH7_PIN 5
#define FTM1_CH0_PIN 3
#define FTM1_CH1_PIN 4
#elif defined(__MK20DX256__)
#define FTM0_CH0_PIN 22
#define FTM0_CH1_PIN 23
#define FTM0_CH2_PIN 9
#define FTM0_CH3_PIN 10
#define FTM0_CH4_PIN 6
#define FTM0_CH5_PIN 20
#define FTM0_CH6_PIN 21
#define FTM0_CH7_PIN 5
#define FTM1_CH0_PIN 3
#define FTM1_CH1_PIN 4
#define FTM2_CH0_PIN 32
#define FTM2_CH1_PIN 25
#elif defined(__MKL26Z64__)
#define FTM0_CH0_PIN 22
#define FTM0_CH1_PIN 23
#define FTM0_CH2_PIN 9
#define FTM0_CH3_PIN 10
#define FTM0_CH4_PIN 6
#define FTM0_CH5_PIN 20
#define FTM1_CH0_PIN 16
#define FTM1_CH1_PIN 17
#define FTM2_CH0_PIN 3
#define FTM2_CH1_PIN 4
#endif
#define FTM_PINCFG(pin) FTM_PINCFG2(pin)
#define FTM_PINCFG2(pin) CORE_PIN ## pin ## _CONFIG


static uint8_t analog_write_res = 8; static uint8_t analog_write_res = 8;


//serial_print("analog_write_res = "); //serial_print("analog_write_res = ");
//serial_phex(analog_write_res); //serial_phex(analog_write_res);
//serial_print("\n"); //serial_print("\n");
if (pin == 3 || pin == 4) {
if (pin == FTM1_CH0_PIN || pin == FTM1_CH1_PIN) {
cval = ((uint32_t)val * (uint32_t)(FTM1_MOD + 1)) >> analog_write_res; cval = ((uint32_t)val * (uint32_t)(FTM1_MOD + 1)) >> analog_write_res;
#if defined(__MK20DX256__)
} else if (pin == 25 || pin == 32) {
#if defined(FTM2_CH0_PIN)
} else if (pin == FTM2_CH0_PIN || pin == FTM2_CH1_PIN) {
cval = ((uint32_t)val * (uint32_t)(FTM2_MOD + 1)) >> analog_write_res; cval = ((uint32_t)val * (uint32_t)(FTM2_MOD + 1)) >> analog_write_res;
#endif #endif
} else { } else {
//serial_phex32(cval); //serial_phex32(cval);
//serial_print("\n"); //serial_print("\n");
switch (pin) { switch (pin) {
case 3: // PTA12, FTM1_CH0
FTM1_C0V = cval;
CORE_PIN3_CONFIG = PORT_PCR_MUX(3) | PORT_PCR_DSE | PORT_PCR_SRE;
break;
case 4: // PTA13, FTM1_CH1
FTM1_C1V = cval;
CORE_PIN4_CONFIG = PORT_PCR_MUX(3) | PORT_PCR_DSE | PORT_PCR_SRE;
break;
case 5: // PTD7, FTM0_CH7
FTM0_C7V = cval;
CORE_PIN5_CONFIG = PORT_PCR_MUX(4) | PORT_PCR_DSE | PORT_PCR_SRE;
#ifdef FTM0_CH0_PIN
case FTM0_CH0_PIN: // PTC1, FTM0_CH0
FTM0_C0V = cval;
FTM_PINCFG(FTM0_CH0_PIN) = PORT_PCR_MUX(4) | PORT_PCR_DSE | PORT_PCR_SRE;
break; break;
case 6: // PTD4, FTM0_CH4
FTM0_C4V = cval;
CORE_PIN6_CONFIG = PORT_PCR_MUX(4) | PORT_PCR_DSE | PORT_PCR_SRE;
#endif
#ifdef FTM0_CH1_PIN
case FTM0_CH1_PIN: // PTC2, FTM0_CH1
FTM0_C1V = cval;
FTM_PINCFG(FTM0_CH1_PIN) = PORT_PCR_MUX(4) | PORT_PCR_DSE | PORT_PCR_SRE;
break; break;
case 9: // PTC3, FTM0_CH2
#endif
#ifdef FTM0_CH2_PIN
case FTM0_CH2_PIN: // PTC3, FTM0_CH2
FTM0_C2V = cval; FTM0_C2V = cval;
CORE_PIN9_CONFIG = PORT_PCR_MUX(4) | PORT_PCR_DSE | PORT_PCR_SRE;
FTM_PINCFG(FTM0_CH2_PIN) = PORT_PCR_MUX(4) | PORT_PCR_DSE | PORT_PCR_SRE;
break; break;
case 10: // PTC4, FTM0_CH3
#endif
#ifdef FTM0_CH3_PIN
case FTM0_CH3_PIN: // PTC4, FTM0_CH3
FTM0_C3V = cval; FTM0_C3V = cval;
CORE_PIN10_CONFIG = PORT_PCR_MUX(4) | PORT_PCR_DSE | PORT_PCR_SRE;
FTM_PINCFG(FTM0_CH3_PIN) = PORT_PCR_MUX(4) | PORT_PCR_DSE | PORT_PCR_SRE;
break;
#endif
#ifdef FTM0_CH4_PIN
case FTM0_CH4_PIN: // PTD4, FTM0_CH4
FTM0_C4V = cval;
FTM_PINCFG(FTM0_CH4_PIN) = PORT_PCR_MUX(4) | PORT_PCR_DSE | PORT_PCR_SRE;
break; break;
case 20: // PTD5, FTM0_CH5
#endif
#ifdef FTM0_CH5_PIN
case FTM0_CH5_PIN: // PTD5, FTM0_CH5
FTM0_C5V = cval; FTM0_C5V = cval;
CORE_PIN20_CONFIG = PORT_PCR_MUX(4) | PORT_PCR_DSE | PORT_PCR_SRE;
FTM_PINCFG(FTM0_CH5_PIN) = PORT_PCR_MUX(4) | PORT_PCR_DSE | PORT_PCR_SRE;
break; break;
case 21: // PTD6, FTM0_CH6
#endif
#ifdef FTM0_CH6_PIN
case FTM0_CH6_PIN: // PTD6, FTM0_CH6
FTM0_C6V = cval; FTM0_C6V = cval;
CORE_PIN21_CONFIG = PORT_PCR_MUX(4) | PORT_PCR_DSE | PORT_PCR_SRE;
FTM_PINCFG(FTM0_CH6_PIN) = PORT_PCR_MUX(4) | PORT_PCR_DSE | PORT_PCR_SRE;
break; break;
case 22: // PTC1, FTM0_CH0
FTM0_C0V = cval;
CORE_PIN22_CONFIG = PORT_PCR_MUX(4) | PORT_PCR_DSE | PORT_PCR_SRE;
#endif
#ifdef FTM0_CH7_PIN
case FTM0_CH7_PIN: // PTD7, FTM0_CH7
FTM0_C7V = cval;
FTM_PINCFG(FTM0_CH7_PIN) = PORT_PCR_MUX(4) | PORT_PCR_DSE | PORT_PCR_SRE;
break; break;
case 23: // PTC2, FTM0_CH1
FTM0_C1V = cval;
CORE_PIN23_CONFIG = PORT_PCR_MUX(4) | PORT_PCR_DSE | PORT_PCR_SRE;
#endif
#ifdef FTM1_CH0_PIN
case FTM1_CH0_PIN: // PTA12, FTM1_CH0
FTM1_C0V = cval;
FTM_PINCFG(FTM1_CH0_PIN) = PORT_PCR_MUX(3) | PORT_PCR_DSE | PORT_PCR_SRE;
break; break;
#if defined(__MK20DX256__)
case 32: // PTB18, FTM2_CH0
#endif
#ifdef FTM1_CH1_PIN
case FTM1_CH1_PIN: // PTA13, FTM1_CH1
FTM1_C1V = cval;
FTM_PINCFG(FTM1_CH1_PIN) = PORT_PCR_MUX(3) | PORT_PCR_DSE | PORT_PCR_SRE;
break;
#endif
#ifdef FTM2_CH0_PIN
case FTM2_CH0_PIN: // PTB18, FTM2_CH0
FTM2_C0V = cval; FTM2_C0V = cval;
CORE_PIN32_CONFIG = PORT_PCR_MUX(3) | PORT_PCR_DSE | PORT_PCR_SRE;
FTM_PINCFG(FTM2_CH0_PIN) = PORT_PCR_MUX(3) | PORT_PCR_DSE | PORT_PCR_SRE;
break; break;
case 25: // PTB19, FTM1_CH1
#endif
#ifdef FTM2_CH1_PIN
case FTM2_CH1_PIN: // PTB19, FTM1_CH1
FTM2_C1V = cval; FTM2_C1V = cval;
CORE_PIN25_CONFIG = PORT_PCR_MUX(3) | PORT_PCR_DSE | PORT_PCR_SRE;
FTM_PINCFG(FTM2_CH1_PIN) = PORT_PCR_MUX(3) | PORT_PCR_DSE | PORT_PCR_SRE;
break; break;
#endif #endif
default: default:
} }
} }



void analogWriteRes(uint32_t bits) void analogWriteRes(uint32_t bits)
{ {
if (bits < 1) { if (bits < 1) {
analog_write_res = bits; analog_write_res = bits;
} }



void analogWriteFrequency(uint8_t pin, uint32_t frequency) void analogWriteFrequency(uint8_t pin, uint32_t frequency)
{ {
uint32_t minfreq, prescale, mod; uint32_t minfreq, prescale, mod;
//serial_phex32(frequency); //serial_phex32(frequency);
//serial_print("\n"); //serial_print("\n");
for (prescale = 0; prescale < 7; prescale++) { for (prescale = 0; prescale < 7; prescale++) {
minfreq = (F_BUS >> 16) >> prescale;
minfreq = (F_TIMER >> 16) >> prescale;
if (frequency > minfreq) break; if (frequency > minfreq) break;
} }
//serial_print("F_BUS = ");
//serial_phex32(F_BUS >> prescale);
//serial_print("F_TIMER = ");
//serial_phex32(F_TIMER >> prescale);
//serial_print("\n"); //serial_print("\n");
//serial_print("prescale = "); //serial_print("prescale = ");
//serial_phex(prescale); //serial_phex(prescale);
//serial_print("\n"); //serial_print("\n");
//mod = ((F_BUS >> prescale) / frequency) - 1;
mod = (((F_BUS >> prescale) + (frequency >> 1)) / frequency) - 1;
//mod = ((F_TIMER >> prescale) / frequency) - 1;
mod = (((F_TIMER >> prescale) + (frequency >> 1)) / frequency) - 1;
if (mod > 65535) mod = 65535; if (mod > 65535) mod = 65535;
//serial_print("mod = "); //serial_print("mod = ");
//serial_phex32(mod); //serial_phex32(mod);
//serial_print("\n"); //serial_print("\n");
if (pin == 3 || pin == 4) {
if (pin == FTM1_CH0_PIN || pin == FTM1_CH1_PIN) {
FTM1_SC = 0; FTM1_SC = 0;
FTM1_CNT = 0; FTM1_CNT = 0;
FTM1_MOD = mod; FTM1_MOD = mod;
FTM1_SC = FTM_SC_CLKS(1) | FTM_SC_PS(prescale); FTM1_SC = FTM_SC_CLKS(1) | FTM_SC_PS(prescale);
} else if (pin == 5 || pin == 6 || pin == 9 || pin == 10 ||
(pin >= 20 && pin <= 23)) {
} else if (pin == FTM0_CH0_PIN || pin == FTM0_CH1_PIN
|| pin == FTM0_CH2_PIN || pin == FTM0_CH3_PIN
|| pin == FTM0_CH4_PIN || pin == FTM0_CH5_PIN
#ifdef FTM0_CH6_PIN
|| pin == FTM0_CH6_PIN || pin == FTM0_CH7_PIN
#endif
) {
FTM0_SC = 0; FTM0_SC = 0;
FTM0_CNT = 0; FTM0_CNT = 0;
FTM0_MOD = mod; FTM0_MOD = mod;
FTM0_SC = FTM_SC_CLKS(1) | FTM_SC_PS(prescale); FTM0_SC = FTM_SC_CLKS(1) | FTM_SC_PS(prescale);
} }
#if defined(__MK20DX256__)
else if (pin == 25 || pin == 32) {
#ifdef FTM2_CH0_PIN
else if (pin == FTM2_CH0_PIN || pin == FTM2_CH1_PIN) {
FTM2_SC = 0; FTM2_SC = 0;
FTM2_CNT = 0; FTM2_CNT = 0;
FTM2_MOD = mod; FTM2_MOD = mod;
void digitalWrite(uint8_t pin, uint8_t val) void digitalWrite(uint8_t pin, uint8_t val)
{ {
if (pin >= CORE_NUM_DIGITAL) return; if (pin >= CORE_NUM_DIGITAL) return;
#ifdef KINETISK
if (*portModeRegister(pin)) { if (*portModeRegister(pin)) {
if (val) { if (val) {
*portSetRegister(pin) = 1; *portSetRegister(pin) = 1;
} else { } else {
*portClearRegister(pin) = 1; *portClearRegister(pin) = 1;
} }
#else
if (*portModeRegister(pin) & digitalPinToBitMask(pin)) {
if (val) {
*portSetRegister(pin) = digitalPinToBitMask(pin);
} else {
*portClearRegister(pin) = digitalPinToBitMask(pin);
}
#endif
} else { } else {
volatile uint32_t *config = portConfigRegister(pin); volatile uint32_t *config = portConfigRegister(pin);
if (val) { if (val) {
uint8_t digitalRead(uint8_t pin) uint8_t digitalRead(uint8_t pin)
{ {
if (pin >= CORE_NUM_DIGITAL) return 0; if (pin >= CORE_NUM_DIGITAL) return 0;
#ifdef KINETISK
return *portInputRegister(pin); return *portInputRegister(pin);
#else
return (*portInputRegister(pin) & digitalPinToBitMask(pin)) ? 1 : 0;
#endif
} }




config = portConfigRegister(pin); config = portConfigRegister(pin);


if (mode == OUTPUT) { if (mode == OUTPUT) {
#ifdef KINETISK
*portModeRegister(pin) = 1; *portModeRegister(pin) = 1;
#else
*portModeRegister(pin) |= digitalPinToBitMask(pin); // TODO: atomic
#endif
*config = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1); *config = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1);
} else { } else {
#ifdef KINETISK
*portModeRegister(pin) = 0; *portModeRegister(pin) = 0;
#else
*portModeRegister(pin) &= ~digitalPinToBitMask(pin);
#endif
if (mode == INPUT) { if (mode == INPUT) {
*config = PORT_PCR_MUX(1); *config = PORT_PCR_MUX(1);
} else { } else {

+ 49
- 0
teensy3/ser_print.c View File

#include "kinetis.h"
#include "ser_print.h"

#ifdef KINETISL

// Simple polling-only Serial1 support for Teensy-LC

// this is really only useful for extremely low-level troubleshooting

void ser_write(uint8_t c)
{
while ((UART0_S1 & UART_S1_TDRE) == 0) /* wait */ ;
UART0_D = c;
}

void ser_print(const char *p)
{
while (*p) {
char c = *p++;
if (c == '\n') ser_write('\r');
ser_write(c);
}
}

static void ser_print_hex1(unsigned int n)
{
n &= 15;
if (n < 10) {
ser_write('0' + n);
} else {
ser_write('A' - 10 + n);
}
}

void ser_print_hex(unsigned int n)
{
ser_print_hex1(n >> 4);
ser_print_hex1(n);
}

void ser_print_hex32(unsigned int n)
{
ser_print_hex(n >> 24);
ser_print_hex(n >> 16);
ser_print_hex(n >> 8);
ser_print_hex(n);
}

#endif

+ 11
- 0
teensy3/ser_print.h View File


#ifdef __cplusplus
extern "C"{
#endif
void ser_print(const char *p);
void ser_print_hex(unsigned int n);
void ser_print_hex32(unsigned int n);
#ifdef __cplusplus
} // extern "C"
#endif


+ 56
- 3
teensy3/serial1.c View File

// UART0 and UART1 are clocked by F_CPU, UART2 is clocked by F_BUS // UART0 and UART1 are clocked by F_CPU, UART2 is clocked by F_BUS
// UART0 has 8 byte fifo, UART1 and UART2 have 1 byte buffer // UART0 has 8 byte fifo, UART1 and UART2 have 1 byte buffer


#ifdef KINETISK_UART0_FIFO
#define C2_ENABLE UART_C2_TE | UART_C2_RE | UART_C2_RIE | UART_C2_ILIE #define C2_ENABLE UART_C2_TE | UART_C2_RE | UART_C2_RIE | UART_C2_ILIE
#else
#define C2_ENABLE UART_C2_TE | UART_C2_RE | UART_C2_RIE
#endif
#define C2_TX_ACTIVE C2_ENABLE | UART_C2_TIE #define C2_TX_ACTIVE C2_ENABLE | UART_C2_TIE
#define C2_TX_COMPLETING C2_ENABLE | UART_C2_TCIE #define C2_TX_COMPLETING C2_ENABLE | UART_C2_TCIE
#define C2_TX_INACTIVE C2_ENABLE #define C2_TX_INACTIVE C2_ENABLE
transmitting = 0; transmitting = 0;
CORE_PIN0_CONFIG = PORT_PCR_PE | PORT_PCR_PS | PORT_PCR_PFE | PORT_PCR_MUX(3); CORE_PIN0_CONFIG = PORT_PCR_PE | PORT_PCR_PS | PORT_PCR_PFE | PORT_PCR_MUX(3);
CORE_PIN1_CONFIG = PORT_PCR_DSE | PORT_PCR_SRE | PORT_PCR_MUX(3); CORE_PIN1_CONFIG = PORT_PCR_DSE | PORT_PCR_SRE | PORT_PCR_MUX(3);
#if defined(KINETISK_UART0)
UART0_BDH = (divisor >> 13) & 0x1F; UART0_BDH = (divisor >> 13) & 0x1F;
UART0_BDL = (divisor >> 5) & 0xFF; UART0_BDL = (divisor >> 5) & 0xFF;
UART0_C4 = divisor & 0x1F; UART0_C4 = divisor & 0x1F;
//UART0_C1 = 0;
#ifdef KINETISK_UART0_FIFO
UART0_C1 = UART_C1_ILT; UART0_C1 = UART_C1_ILT;
UART0_TWFIFO = 2; // tx watermark, causes S1_TDRE to set UART0_TWFIFO = 2; // tx watermark, causes S1_TDRE to set
UART0_RWFIFO = 4; // rx watermark, causes S1_RDRF to set UART0_RWFIFO = 4; // rx watermark, causes S1_RDRF to set
UART0_PFIFO = UART_PFIFO_TXFE | UART_PFIFO_RXFE; UART0_PFIFO = UART_PFIFO_TXFE | UART_PFIFO_RXFE;
#else
UART0_C1 = 0;
UART0_PFIFO = 0;
#endif
#elif defined(KINETISL_UART1)
UART0_BDH = (divisor >> 8) & 0x1F;
UART0_BDL = divisor & 0xFF;
UART0_C1 = 0;
#endif
UART0_C2 = C2_TX_INACTIVE; UART0_C2 = C2_TX_INACTIVE;
NVIC_SET_PRIORITY(IRQ_UART0_STATUS, IRQ_PRIORITY); NVIC_SET_PRIORITY(IRQ_UART0_STATUS, IRQ_PRIORITY);
NVIC_ENABLE_IRQ(IRQ_UART0_STATUS); NVIC_ENABLE_IRQ(IRQ_UART0_STATUS);
UART0_C2 = C2_TX_ACTIVE; UART0_C2 = C2_TX_ACTIVE;
} }


#ifdef KINETISK_UART0_FIFO
void serial_write(const void *buf, unsigned int count) void serial_write(const void *buf, unsigned int count)
{ {
const uint8_t *p = (const uint8_t *)buf; const uint8_t *p = (const uint8_t *)buf;
} }
UART0_C2 = C2_TX_ACTIVE; UART0_C2 = C2_TX_ACTIVE;
} }
#else
void serial_write(const void *buf, unsigned int count)
{
const uint8_t *p = (const uint8_t *)buf;
while (count-- > 0) serial_putchar(*p++);
}
#endif


void serial_flush(void) void serial_flush(void)
{ {


void serial_clear(void) void serial_clear(void)
{ {
#ifdef KINETISK_UART0_FIFO
if (!(SIM_SCGC4 & SIM_SCGC4_UART0)) return; if (!(SIM_SCGC4 & SIM_SCGC4_UART0)) return;
UART0_C2 &= ~(UART_C2_RE | UART_C2_RIE | UART_C2_ILIE); UART0_C2 &= ~(UART_C2_RE | UART_C2_RIE | UART_C2_ILIE);
UART0_CFIFO = UART_CFIFO_RXFLUSH; UART0_CFIFO = UART_CFIFO_RXFLUSH;
UART0_C2 |= (UART_C2_RE | UART_C2_RIE | UART_C2_ILIE); UART0_C2 |= (UART_C2_RE | UART_C2_RIE | UART_C2_ILIE);
#endif
rx_buffer_head = rx_buffer_tail; rx_buffer_head = rx_buffer_tail;
} }




void uart0_status_isr(void) void uart0_status_isr(void)
{ {
uint32_t head, newhead, tail, n;
uint8_t avail, c;
uint32_t head, tail, n;
uint8_t c;
#ifdef KINETISK_UART0_FIFO
uint32_t newhead;
uint8_t avail;


if (UART0_S1 & (UART_S1_RDRF | UART_S1_IDLE)) { if (UART0_S1 & (UART_S1_RDRF | UART_S1_IDLE)) {
__disable_irq(); __disable_irq();
tx_buffer_tail = tail; tx_buffer_tail = tail;
if (UART0_S1 & UART_S1_TDRE) UART0_C2 = C2_TX_COMPLETING; if (UART0_S1 & UART_S1_TDRE) UART0_C2 = C2_TX_COMPLETING;
} }
#else
if (UART0_S1 & UART_S1_RDRF) {
n = UART0_D;
if (use9Bits && (UART0_C3 & 0x80)) n |= 0x100;
head = rx_buffer_head + 1;
if (head >= RX_BUFFER_SIZE) head = 0;
if (head != rx_buffer_tail) {
rx_buffer[head] = n;
rx_buffer_head = head;
}
}
c = UART0_C2;
if ((c & UART_C2_TIE) && (UART0_S1 & UART_S1_TDRE)) {
head = tx_buffer_head;
tail = tx_buffer_tail;
if (head == tail) {
UART0_C2 = C2_TX_COMPLETING;
} else {
if (++tail >= TX_BUFFER_SIZE) tail = 0;
n = tx_buffer[tail];
if (use9Bits) UART0_C3 = (UART0_C3 & ~0x40) | ((n & 0x100) >> 2);
UART0_D = n;
tx_buffer_tail = tail;
}
}
#endif
if ((c & UART_C2_TCIE) && (UART0_S1 & UART_S1_TC)) { if ((c & UART_C2_TCIE) && (UART0_S1 & UART_S1_TC)) {
transmitting = 0; transmitting = 0;
if (transmit_pin) *transmit_pin = 0; if (transmit_pin) *transmit_pin = 0;

+ 6
- 0
teensy3/serial2.c View File

transmitting = 0; transmitting = 0;
CORE_PIN9_CONFIG = PORT_PCR_PE | PORT_PCR_PS | PORT_PCR_PFE | PORT_PCR_MUX(3); CORE_PIN9_CONFIG = PORT_PCR_PE | PORT_PCR_PS | PORT_PCR_PFE | PORT_PCR_MUX(3);
CORE_PIN10_CONFIG = PORT_PCR_DSE | PORT_PCR_SRE | PORT_PCR_MUX(3); CORE_PIN10_CONFIG = PORT_PCR_DSE | PORT_PCR_SRE | PORT_PCR_MUX(3);
#if defined(KINETISK_UART1)
UART1_BDH = (divisor >> 13) & 0x1F; UART1_BDH = (divisor >> 13) & 0x1F;
UART1_BDL = (divisor >> 5) & 0xFF; UART1_BDL = (divisor >> 5) & 0xFF;
UART1_C4 = divisor & 0x1F; UART1_C4 = divisor & 0x1F;
#else #else
UART1_C1 = 0; UART1_C1 = 0;
UART1_PFIFO = 0; UART1_PFIFO = 0;
#endif
#elif defined(KINETISL_UART1)
UART1_BDH = (divisor >> 8) & 0x1F;
UART1_BDL = divisor & 0xFF;
UART1_C1 = 0;
#endif #endif
UART1_C2 = C2_TX_INACTIVE; UART1_C2 = C2_TX_INACTIVE;
NVIC_SET_PRIORITY(IRQ_UART1_STATUS, IRQ_PRIORITY); NVIC_SET_PRIORITY(IRQ_UART1_STATUS, IRQ_PRIORITY);

+ 6
- 0
teensy3/serial3.c View File

transmitting = 0; transmitting = 0;
CORE_PIN7_CONFIG = PORT_PCR_PE | PORT_PCR_PS | PORT_PCR_PFE | PORT_PCR_MUX(3); CORE_PIN7_CONFIG = PORT_PCR_PE | PORT_PCR_PS | PORT_PCR_PFE | PORT_PCR_MUX(3);
CORE_PIN8_CONFIG = PORT_PCR_DSE | PORT_PCR_SRE | PORT_PCR_MUX(3); CORE_PIN8_CONFIG = PORT_PCR_DSE | PORT_PCR_SRE | PORT_PCR_MUX(3);
#if defined(KINETISK_UART2)
UART2_BDH = (divisor >> 13) & 0x1F; UART2_BDH = (divisor >> 13) & 0x1F;
UART2_BDL = (divisor >> 5) & 0xFF; UART2_BDL = (divisor >> 5) & 0xFF;
UART2_C4 = divisor & 0x1F; UART2_C4 = divisor & 0x1F;
UART2_C1 = 0; UART2_C1 = 0;
UART2_PFIFO = 0; UART2_PFIFO = 0;
#elif defined(KINETISL_UART2)
UART2_BDH = (divisor >> 8) & 0x1F;
UART2_BDL = divisor & 0xFF;
UART2_C1 = 0;
#endif
UART2_C2 = C2_TX_INACTIVE; UART2_C2 = C2_TX_INACTIVE;
NVIC_SET_PRIORITY(IRQ_UART2_STATUS, IRQ_PRIORITY); NVIC_SET_PRIORITY(IRQ_UART2_STATUS, IRQ_PRIORITY);
NVIC_ENABLE_IRQ(IRQ_UART2_STATUS); NVIC_ENABLE_IRQ(IRQ_UART2_STATUS);

+ 29
- 7
teensy3/touch.c View File

#include "core_pins.h" #include "core_pins.h"
//#include "HardwareSerial.h" //#include "HardwareSerial.h"


#if defined(__MK20DX128__) || defined(__MK20DX256__)
// These settings give approx 0.02 pF sensitivity and 1200 pF range
// Lower current, higher number of scans, and higher prescaler
// increase sensitivity, but the trade-off is longer measurement
// time and decreased range.
#define CURRENT 2 // 0 to 15 - current to use, value is 2*(current+1)
#define NSCAN 9 // number of times to scan, 0 to 31, value is nscan+1
#define PRESCALE 2 // prescaler, 0 to 7 - value is 2^(prescaler+1)
static const uint8_t pin2tsi[] = { static const uint8_t pin2tsi[] = {
//0 1 2 3 4 5 6 7 8 9 //0 1 2 3 4 5 6 7 8 9
9, 10, 255, 255, 255, 255, 255, 255, 255, 255, 9, 10, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 11, 5 255, 255, 11, 5
}; };


// These settings give approx 0.02 pF sensitivity and 1200 pF range
// Lower current, higher number of scans, and higher prescaler
// increase sensitivity, but the trade-off is longer measurement
// time and decreased range.
#define CURRENT 2 // 0 to 15 - current to use, value is 2*(current+1)
#define NSCAN 9 // number of times to scan, 0 to 31, value is nscan+1
#define PRESCALE 2 // prescaler, 0 to 7 - value is 2^(prescaler+1)
#elif defined(__MKL26Z64__)
#define NSCAN 9
#define PRESCALE 2
static const uint8_t pin2tsi[] = {
//0 1 2 3 4 5 6 7 8 9
9, 10, 255, 2, 3, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 13, 0, 6, 8, 7,
255, 255, 14, 15, 255, 255, 255
};

#endif




// output is approx pF * 50 // output is approx pF * 50


*portConfigRegister(pin) = PORT_PCR_MUX(0); *portConfigRegister(pin) = PORT_PCR_MUX(0);
SIM_SCGC5 |= SIM_SCGC5_TSI; SIM_SCGC5 |= SIM_SCGC5_TSI;
#if defined(KINETISK)
TSI0_GENCS = 0; TSI0_GENCS = 0;
TSI0_PEN = (1 << ch); TSI0_PEN = (1 << ch);
TSI0_SCANC = TSI_SCANC_REFCHRG(3) | TSI_SCANC_EXTCHRG(CURRENT); TSI0_SCANC = TSI_SCANC_REFCHRG(3) | TSI_SCANC_EXTCHRG(CURRENT);
while (TSI0_GENCS & TSI_GENCS_SCNIP) ; // wait while (TSI0_GENCS & TSI_GENCS_SCNIP) ; // wait
delayMicroseconds(1); delayMicroseconds(1);
return *((volatile uint16_t *)(&TSI0_CNTR1) + ch); return *((volatile uint16_t *)(&TSI0_CNTR1) + ch);
#elif defined(KINETISL)
TSI0_GENCS = TSI_GENCS_REFCHRG(4) | TSI_GENCS_EXTCHRG(3) | TSI_GENCS_PS(PRESCALE)
| TSI_GENCS_NSCN(NSCAN) | TSI_GENCS_TSIEN | TSI_GENCS_EOSF;
TSI0_DATA = TSI_DATA_TSICH(ch) | TSI_DATA_SWTS;
delayMicroseconds(10);
while (TSI0_GENCS & TSI_GENCS_SCNIP) ; // wait
delayMicroseconds(1);
return TSI0_DATA & 0xFFFF;
#endif
} }





+ 5
- 5
teensy3/usb_dev.c View File

restart: restart:
status = USB0_ISTAT; status = USB0_ISTAT;


if ((status & USB_INTEN_SOFTOKEN /* 04 */ )) {
if ((status & USB_ISTAT_SOFTOK /* 04 */ )) {
if (usb_configuration) { if (usb_configuration) {
t = usb_reboot_timer; t = usb_reboot_timer;
if (t) { if (t) {
usb_flightsim_flush_callback(); usb_flightsim_flush_callback();
#endif #endif
} }
USB0_ISTAT = USB_INTEN_SOFTOKEN;
USB0_ISTAT = USB_ISTAT_SOFTOK;
} }


if ((status & USB_ISTAT_TOKDNE /* 08 */ )) { if ((status & USB_ISTAT_TOKDNE /* 08 */ )) {
SIM_SCGC4 |= SIM_SCGC4_USBOTG; SIM_SCGC4 |= SIM_SCGC4_USBOTG;


// reset USB module // reset USB module
USB0_USBTRC0 = USB_USBTRC_USBRESET;
while ((USB0_USBTRC0 & USB_USBTRC_USBRESET) != 0) ; // wait for reset to end
//USB0_USBTRC0 = USB_USBTRC_USBRESET;
//while ((USB0_USBTRC0 & USB_USBTRC_USBRESET) != 0) ; // wait for reset to end


// set desc table base addr // set desc table base addr
USB0_BDTPAGE1 = ((uint32_t)table) >> 8; USB0_BDTPAGE1 = ((uint32_t)table) >> 8;
USB0_ERRSTAT = 0xFF; USB0_ERRSTAT = 0xFF;
USB0_OTGISTAT = 0xFF; USB0_OTGISTAT = 0xFF;


USB0_USBTRC0 |= 0x40; // undocumented bit
//USB0_USBTRC0 |= 0x40; // undocumented bit


// enable USB // enable USB
USB0_CTL = USB_CTL_USBENSOFEN; USB0_CTL = USB_CTL_USBENSOFEN;

Loading…
Cancel
Save