// 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); } |
// 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; |
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 | |||||
}; | }; | ||||
#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 |
#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 | |||||
{ | { | ||||
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(); |
#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 | ||||
// 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) : | ||||
); | ); |
}; | }; | ||||
#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); |
*/ | */ | ||||
#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(); |
/* 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); | |||||
} | |||||
#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)); |
#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 { |
#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 |
#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 | |||||
// 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; |
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); |
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); |
#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 | |||||
} | } | ||||
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; |