Ver código fonte

Fix analogRead on K66

teensy4-core
PaulStoffregen 8 anos atrás
pai
commit
6856d4eedc
3 arquivos alterados com 69 adições e 31 exclusões
  1. +2
    -2
      keywords.txt
  2. +59
    -29
      teensy3/analog.c
  3. +8
    -0
      teensy3/kinetis.h

+ 2
- 2
keywords.txt Ver arquivo

@@ -75,8 +75,8 @@ digitalPinToInterrupt KEYWORD2

# Teensy 3.x advanced pin states
OUTPUT_OPENDRAIN LITERAL1
INPUT_PULLUP LITERAL1
INPUT_PULLDOWN LITERAL1
INPUT_PULLUP LITERAL1
INPUT_PULLDOWN LITERAL1

# String functions
copy KEYWORD2

+ 59
- 29
teensy3/analog.c Ver arquivo

@@ -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

+ 8
- 0
teensy3/kinetis.h Ver arquivo

@@ -136,6 +136,7 @@ enum IRQ_NUMBER_t {
#define HAS_KINETISK_UART2
#define HAS_KINETIS_I2C0
#define HAS_KINETIS_LLWU_16CH
#define HAS_KINETIS_ADC0

// Teensy 3.1
#elif defined(__MK20DX256__)
@@ -273,6 +274,8 @@ enum IRQ_NUMBER_t {
#define HAS_KINETIS_I2C0
#define HAS_KINETIS_I2C1
#define HAS_KINETIS_LLWU_16CH
#define HAS_KINETIS_ADC0
#define HAS_KINETIS_ADC1

// Teensy-LC
#elif defined(__MKL26Z64__)
@@ -361,6 +364,7 @@ enum IRQ_NUMBER_t {
#define HAS_KINETIS_I2C1
#define HAS_KINETIS_I2C1_STOPF
#define HAS_KINETIS_LLWU_16CH
#define HAS_KINETIS_ADC0


#elif defined(__MK64FX512__)
@@ -536,6 +540,8 @@ enum IRQ_NUMBER_t {
#define HAS_KINETIS_I2C2_STOPF
#define HAS_KINETIS_LLWU_32CH
#define HAS_KINETIS_MPU
#define HAS_KINETIS_ADC0
#define HAS_KINETIS_ADC1


#elif defined(__MK66FX1M0__)
@@ -735,6 +741,8 @@ enum IRQ_NUMBER_t {
#define HAS_KINETIS_I2C3_STOPF
#define HAS_KINETIS_LLWU_32CH
#define HAS_KINETIS_MPU
#define HAS_KINETIS_ADC0
#define HAS_KINETIS_ADC1




Carregando…
Cancelar
Salvar