|
|
@@ -31,10 +31,6 @@ |
|
|
|
#include "core_pins.h" |
|
|
|
//#include "HardwareSerial.h" |
|
|
|
|
|
|
|
#if defined(__MK64FX512__) || defined(__MK66FX1M0__) // ugly hack for now... |
|
|
|
#define __MK20DX256__ |
|
|
|
#endif |
|
|
|
|
|
|
|
static uint8_t calibrating; |
|
|
|
static uint8_t analog_right_shift = 0; |
|
|
|
static uint8_t analog_config_bits = 10; |
|
|
@@ -111,28 +107,28 @@ void analog_init(void) |
|
|
|
if (analog_config_bits == 8) { |
|
|
|
ADC0_CFG1 = ADC_CFG1_8BIT + ADC_CFG1_MODE(0); |
|
|
|
ADC0_CFG2 = ADC_CFG2_MUXSEL + ADC_CFG2_ADLSTS(3); |
|
|
|
#if defined(__MK20DX256__) |
|
|
|
#ifdef HAS_KINETIS_ADC1 |
|
|
|
ADC1_CFG1 = ADC_CFG1_8BIT + ADC_CFG1_MODE(0); |
|
|
|
ADC1_CFG2 = ADC_CFG2_MUXSEL + ADC_CFG2_ADLSTS(3); |
|
|
|
#endif |
|
|
|
} else if (analog_config_bits == 10) { |
|
|
|
ADC0_CFG1 = ADC_CFG1_10BIT + ADC_CFG1_MODE(2) + ADC_CFG1_ADLSMP; |
|
|
|
ADC0_CFG2 = ADC_CFG2_MUXSEL + ADC_CFG2_ADLSTS(3); |
|
|
|
#if defined(__MK20DX256__) |
|
|
|
#ifdef HAS_KINETIS_ADC1 |
|
|
|
ADC1_CFG1 = ADC_CFG1_10BIT + ADC_CFG1_MODE(2) + ADC_CFG1_ADLSMP; |
|
|
|
ADC1_CFG2 = ADC_CFG2_MUXSEL + ADC_CFG2_ADLSTS(3); |
|
|
|
#endif |
|
|
|
} else if (analog_config_bits == 12) { |
|
|
|
ADC0_CFG1 = ADC_CFG1_12BIT + ADC_CFG1_MODE(1) + ADC_CFG1_ADLSMP; |
|
|
|
ADC0_CFG2 = ADC_CFG2_MUXSEL + ADC_CFG2_ADLSTS(2); |
|
|
|
#if defined(__MK20DX256__) |
|
|
|
#ifdef HAS_KINETIS_ADC1 |
|
|
|
ADC1_CFG1 = ADC_CFG1_12BIT + ADC_CFG1_MODE(1) + ADC_CFG1_ADLSMP; |
|
|
|
ADC1_CFG2 = ADC_CFG2_MUXSEL + ADC_CFG2_ADLSTS(2); |
|
|
|
#endif |
|
|
|
} else { |
|
|
|
ADC0_CFG1 = ADC_CFG1_16BIT + ADC_CFG1_MODE(3) + ADC_CFG1_ADLSMP; |
|
|
|
ADC0_CFG2 = ADC_CFG2_MUXSEL + ADC_CFG2_ADLSTS(2); |
|
|
|
#if defined(__MK20DX256__) |
|
|
|
#ifdef HAS_KINETIS_ADC1 |
|
|
|
ADC1_CFG1 = ADC_CFG1_16BIT + ADC_CFG1_MODE(3) + ADC_CFG1_ADLSMP; |
|
|
|
ADC1_CFG2 = ADC_CFG2_MUXSEL + ADC_CFG2_ADLSTS(2); |
|
|
|
#endif |
|
|
@@ -144,7 +140,7 @@ void analog_init(void) |
|
|
|
} else { |
|
|
|
ADC0_SC2 = ADC_SC2_REFSEL(0); // vcc/ext ref |
|
|
|
} |
|
|
|
#elif defined(__MK20DX256__) |
|
|
|
#elif defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__) |
|
|
|
if (analog_reference_internal) { |
|
|
|
ADC0_SC2 = ADC_SC2_REFSEL(1); // 1.2V ref |
|
|
|
ADC1_SC2 = ADC_SC2_REFSEL(1); // 1.2V ref |
|
|
@@ -163,27 +159,27 @@ void analog_init(void) |
|
|
|
num = analog_num_average; |
|
|
|
if (num <= 1) { |
|
|
|
ADC0_SC3 = ADC_SC3_CAL; // begin cal |
|
|
|
#if defined(__MK20DX256__) |
|
|
|
#ifdef HAS_KINETIS_ADC1 |
|
|
|
ADC1_SC3 = ADC_SC3_CAL; // begin cal |
|
|
|
#endif |
|
|
|
} else if (num <= 4) { |
|
|
|
ADC0_SC3 = ADC_SC3_CAL + ADC_SC3_AVGE + ADC_SC3_AVGS(0); |
|
|
|
#if defined(__MK20DX256__) |
|
|
|
#ifdef HAS_KINETIS_ADC1 |
|
|
|
ADC1_SC3 = ADC_SC3_CAL + ADC_SC3_AVGE + ADC_SC3_AVGS(0); |
|
|
|
#endif |
|
|
|
} else if (num <= 8) { |
|
|
|
ADC0_SC3 = ADC_SC3_CAL + ADC_SC3_AVGE + ADC_SC3_AVGS(1); |
|
|
|
#if defined(__MK20DX256__) |
|
|
|
#ifdef HAS_KINETIS_ADC1 |
|
|
|
ADC1_SC3 = ADC_SC3_CAL + ADC_SC3_AVGE + ADC_SC3_AVGS(1); |
|
|
|
#endif |
|
|
|
} else if (num <= 16) { |
|
|
|
ADC0_SC3 = ADC_SC3_CAL + ADC_SC3_AVGE + ADC_SC3_AVGS(2); |
|
|
|
#if defined(__MK20DX256__) |
|
|
|
#ifdef HAS_KINETIS_ADC1 |
|
|
|
ADC1_SC3 = ADC_SC3_CAL + ADC_SC3_AVGE + ADC_SC3_AVGS(2); |
|
|
|
#endif |
|
|
|
} else { |
|
|
|
ADC0_SC3 = ADC_SC3_CAL + ADC_SC3_AVGE + ADC_SC3_AVGS(3); |
|
|
|
#if defined(__MK20DX256__) |
|
|
|
#ifdef HAS_KINETIS_ADC1 |
|
|
|
ADC1_SC3 = ADC_SC3_CAL + ADC_SC3_AVGE + ADC_SC3_AVGS(3); |
|
|
|
#endif |
|
|
|
} |
|
|
@@ -195,12 +191,12 @@ static void wait_for_cal(void) |
|
|
|
uint16_t sum; |
|
|
|
|
|
|
|
//serial_print("wait_for_cal\n"); |
|
|
|
#if defined(__MK20DX128__) |
|
|
|
while (ADC0_SC3 & ADC_SC3_CAL) { |
|
|
|
#if defined(HAS_KINETIS_ADC0) && defined(HAS_KINETIS_ADC1) |
|
|
|
while ((ADC0_SC3 & ADC_SC3_CAL) || (ADC1_SC3 & ADC_SC3_CAL)) { |
|
|
|
// wait |
|
|
|
} |
|
|
|
#elif defined(__MK20DX256__) |
|
|
|
while ((ADC0_SC3 & ADC_SC3_CAL) || (ADC1_SC3 & ADC_SC3_CAL)) { |
|
|
|
#elif defined(HAS_KINETIS_ADC0) |
|
|
|
while (ADC0_SC3 & ADC_SC3_CAL) { |
|
|
|
// wait |
|
|
|
} |
|
|
|
#endif |
|
|
@@ -219,7 +215,7 @@ static void wait_for_cal(void) |
|
|
|
//serial_print("ADC0_MG = "); |
|
|
|
//serial_phex16(sum); |
|
|
|
//serial_print("\n"); |
|
|
|
#if defined(__MK20DX256__) |
|
|
|
#ifdef HAS_KINETIS_ADC1 |
|
|
|
sum = ADC1_CLPS + ADC1_CLP4 + ADC1_CLP3 + ADC1_CLP2 + ADC1_CLP1 + ADC1_CLP0; |
|
|
|
sum = (sum / 2) | 0x8000; |
|
|
|
ADC1_PG = sum; |
|
|
@@ -236,7 +232,7 @@ static void wait_for_cal(void) |
|
|
|
// VREFH/VREFL - connected as the primary reference option |
|
|
|
// 1.2 V VREF_OUT - connected as the VALT reference option |
|
|
|
|
|
|
|
#if defined(__MK20DX128__) || defined(__MK20DX256__) |
|
|
|
#if defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__) |
|
|
|
#define DEFAULT 0 |
|
|
|
#define INTERNAL 2 |
|
|
|
#define INTERNAL1V2 2 |
|
|
@@ -257,7 +253,7 @@ void analogReference(uint8_t type) |
|
|
|
analog_reference_internal = 1; |
|
|
|
if (calibrating) { |
|
|
|
ADC0_SC3 = 0; // cancel cal |
|
|
|
#if defined(__MK20DX256__) |
|
|
|
#ifdef HAS_KINETIS_ADC1 |
|
|
|
ADC1_SC3 = 0; // cancel cal |
|
|
|
#endif |
|
|
|
} |
|
|
@@ -269,7 +265,7 @@ void analogReference(uint8_t type) |
|
|
|
analog_reference_internal = 0; |
|
|
|
if (calibrating) { |
|
|
|
ADC0_SC3 = 0; // cancel cal |
|
|
|
#if defined(__MK20DX256__) |
|
|
|
#ifdef HAS_KINETIS_ADC1 |
|
|
|
ADC1_SC3 = 0; // cancel cal |
|
|
|
#endif |
|
|
|
} |
|
|
@@ -336,6 +332,8 @@ static const uint8_t channel2sc1a[] = { |
|
|
|
5, 14, 8, 9, 13, 12, 6, 7, 15, 4, |
|
|
|
0, 19, 3, 19+128, 26, 18+128, 23, |
|
|
|
5+192, 5+128, 4+128, 6+128, 7+128, 4+192 |
|
|
|
// +64 -> use muxA |
|
|
|
// +128 -> use ADC1 |
|
|
|
// A15 26 E1 ADC1_SE5a 5+64 |
|
|
|
// A16 27 C9 ADC1_SE5b 5 |
|
|
|
// A17 28 C8 ADC1_SE4b 4 |
|
|
@@ -348,15 +346,33 @@ static const uint8_t channel2sc1a[] = { |
|
|
|
5, 14, 8, 9, 13, 12, 6, 7, 15, 11, |
|
|
|
0, 4+64, 23, 26, 27 |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
#elif defined(__MK64FX512__) || defined(__MK66FX1M0__) |
|
|
|
static const uint8_t channel2sc1a[] = { |
|
|
|
5, 14, 8, 9, 13, 12, 6, 7, 15, 4, // A0-A9 |
|
|
|
3, 19+128, // A10-A11 |
|
|
|
// A10 ADC1_DP0/ADC0_DP3 |
|
|
|
// A11 ADC1_DM0/ADC0_DM3 |
|
|
|
14+128, 15+128, 17, 18, 4+128, 5+128, 6+128, 7+128, 17+128, // A12-A20 |
|
|
|
// A12 PTB10 ADC1_SE14 |
|
|
|
// A13 PTB11 ADC1_SE15 |
|
|
|
// A14 PTE24 ADC0_SE17 |
|
|
|
// A15 PTE25 ADC0_SE18 |
|
|
|
// A16 PTC8 ADC1_SE4b |
|
|
|
// A17 PTC9 ADC1_SE5b |
|
|
|
// A18 PTC10 ADC1_SE6b |
|
|
|
// A19 PTC11 ADC1_SE7b |
|
|
|
// A20 PTA17 ADC1_SE17 |
|
|
|
23, 23+128, 26, 18+128 // A21-A22, temp sensor, vref |
|
|
|
// A21 DAC0 ADC0_SE23 |
|
|
|
// A22 DAC1 ADC1_SE23 |
|
|
|
}; |
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// TODO: perhaps this should store the NVIC priority, so it works recursively? |
|
|
|
static volatile uint8_t analogReadBusyADC0 = 0; |
|
|
|
#if defined(__MK20DX256__) |
|
|
|
#ifdef HAS_KINETIS_ADC1 |
|
|
|
static volatile uint8_t analogReadBusyADC1 = 0; |
|
|
|
#endif |
|
|
|
|
|
|
@@ -392,6 +408,20 @@ int analogRead(uint8_t pin) |
|
|
|
} else { |
|
|
|
return 0; |
|
|
|
} |
|
|
|
#elif defined(__MK64FX512__) || defined(__MK66FX1M0__) |
|
|
|
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 >= 31 && pin <= 39) { |
|
|
|
index = pin - 19; // 31-39 are A12-A20 |
|
|
|
} else if (pin >= 40 && pin <= 41) { |
|
|
|
index = pin - 30; // 40-41 are A10-A11 |
|
|
|
} else if (pin >= 42 && pin <= 45) { |
|
|
|
index = pin - 21; // 42-43 are A21-A22, 44 is temp sensor, 45 is vref |
|
|
|
} else { |
|
|
|
return 0; |
|
|
|
} |
|
|
|
#elif defined(__MKL26Z64__) |
|
|
|
if (pin <= 12) { |
|
|
|
index = pin; // 0-12 refer to A0-A12 |
|
|
@@ -418,7 +448,7 @@ int analogRead(uint8_t pin) |
|
|
|
if (calibrating) wait_for_cal(); |
|
|
|
//pin = 5; // PTD1/SE5b, pin 14, analog 0 |
|
|
|
|
|
|
|
#if defined(__MK20DX256__) |
|
|
|
#ifdef HAS_KINETIS_ADC1 |
|
|
|
if (channel & 0x80) goto beginADC1; |
|
|
|
#endif |
|
|
|
|
|
|
@@ -453,11 +483,11 @@ startADC0: |
|
|
|
yield(); |
|
|
|
} |
|
|
|
|
|
|
|
#if defined(__MK20DX256__) |
|
|
|
#ifdef HAS_KINETIS_ADC1 |
|
|
|
beginADC1: |
|
|
|
__disable_irq(); |
|
|
|
startADC1: |
|
|
|
//serial_print("startADC0\n"); |
|
|
|
//serial_print("startADC1\n"); |
|
|
|
// ADC1_CFG2[MUXSEL] bit selects between ADCx_SEn channels a and b. |
|
|
|
if (channel & 0x40) { |
|
|
|
ADC1_CFG2 &= ~ADC_CFG2_MUXSEL; |
|
|
@@ -490,7 +520,7 @@ startADC1: |
|
|
|
|
|
|
|
void analogWriteDAC0(int val) |
|
|
|
{ |
|
|
|
#if defined(__MK20DX256__) |
|
|
|
#if defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__) |
|
|
|
SIM_SCGC2 |= SIM_SCGC2_DAC0; |
|
|
|
if (analog_reference_internal) { |
|
|
|
DAC0_C0 = DAC_C0_DACEN; // 1.2V ref is DACREF_1 |