Teensy 4.0 which pins for which ADC

Status
Not open for further replies.
@KurtE
KurtE said:
First fix attempt:
Code:
ADC1_CFG = mode;
ADC2_CFG = mode1;
That appears to work, so I pushed the change up to github cores
@Paul - if you are looking it is in my currently pending PR in cores: https://github.com/PaulStoffregen/cores/pull/404
Nice catch and thanks for correcting. Checked Analog Resolution function to make sure that didn't have the same problem, but that was set up a bit differently so its ok.

Think there is a minor error in the analog init function as well, last few lines for ADC2:
Code:
	//ADC2
	ADC2_CFG = mode | ADC_HC_AIEN | ADC_CFG_ADHSC;
	ADC2_GC = avg | ADC_GC_CAL;		// begin cal
	calibrating = 1;
	[COLOR="#FF0000"]while (ADC1_GC & ADC_GC_CAL) ;[/COLOR]
	calibrating = 0;
Line is read probably should be:
Code:
while (ADC2_GC & ADC_GC_CAL) ;
To avoid issuing a second PR for analog.c maybe you can incorporate into your PR?

But that leads to another question with the wait_for_cal function. Right now its only setup for ADC1:
Code:
static void wait_for_cal(void)
{
	//printf("wait_for_cal\n");
	while (ADC1_GC & ADC_GC_CAL) ;
	// TODO: check CALF, but what do to about CAL failure?
	calibrating = 0;
	//printf("cal complete\n");
}
Technically shouldn't it also include ADC2:
Code:
static void wait_for_cal(void)
{
	//printf("wait_for_cal\n");
	while (ADC1_GC & ADC_GC_CAL) ;
	// TODO: check CALF, but what do to about CAL failure?
	calibrating = 0;
[COLOR="#FF0000"]	while (ADC2_GC & ADC_GC_CAL) ;
	calibrating = 0;[/COLOR]
	//printf("cal complete\n");
}
Red lines are added.
 
@mjs513, @PaulStoffregen - I updated my changes that I pushed to include the above.

Good catch on the init function looking at the wrong one.

I did update the wait_for_cal, sort of like you mentioned, except, I only added one line: while (ADC2_GC & ADC_GC_CAL) ;

I also removed the #if 0/#else #endif around what was originally in their for T4B1.

Note: on wait_for_cal - I don't think it can ever be called?
 
@KurtE
Yeah that's probably better change in wait_for_cal - couldn't sleep so jump on line while Theraflu was working :) That function is only used once in the analogRead function:
Code:
	if (calibrating) wait_for_cal();
Did a quick test of just reading A0 using res=8 and averaging = 4 and got 11usecs per read.

Was trying to change to short conversion time and high speed mode but seems to hang. Have to play more. If interested see page 3469. Must be missing another setting.
 
@mjs513 - Yep, my problem is, when is calibrating ever not 0?

The only places I see it ever set, is in the init function:
Code:
...
	//ADC1
	ADC1_CFG = mode | ADC_HC_AIEN | ADC_CFG_ADHSC;
	ADC1_GC = avg | ADC_GC_CAL;		// begin cal
	calibrating = 1;
	while (ADC1_GC & ADC_GC_CAL) ;
	calibrating = 0;
	//ADC2
	ADC2_CFG = mode | ADC_HC_AIEN | ADC_CFG_ADHSC;
	ADC2_GC = avg | ADC_GC_CAL;		// begin cal
	calibrating = 1;
	while (ADC2_GC & ADC_GC_CAL) ;
	calibrating = 0;

I thought maybe we missed setting it elsewhere in the code, but not sure where, as again only init sets, the ADC1/2_GC calibration bit?
 
@KurtE
To be honest was wondering myself. Since you are testing ADCx_GC & ADC_GC_CAL to see if cal is completed in a while loop calibration is completed when it comes out of the loop. Would think then calibration should always be calibration = 1? So just calling it should be sufficient - I think unless I am missing something.
 
@mjs513 - I think it, is either a hold over from T3.x analog code or, we ran into some issue, added code to init and...

That is I think we can either get rid of the line: if (calibrating) wait_for_cal();
AND the function or we can simplify the end of the init function to more like:
Code:
//ADC1
	ADC1_CFG = mode | ADC_HC_AIEN | ADC_CFG_ADHSC;
	ADC1_GC = avg | ADC_GC_CAL;		// begin cal
	//ADC2
	ADC2_CFG = mode | ADC_HC_AIEN | ADC_CFG_ADHSC;
	ADC2_GC = avg | ADC_GC_CAL;		// begin cal
	calibrating = 1;

As for your fast stuff, do you have example of what you tried?

Here is a hacked up version of the sketch part, which sets both resolution and averaging:
Code:
#if !defined(__IMXRT1062__)  // Teensy 4.x
#error "Only runs on T4"
#endif
#include "ADC4_lite.h"
void setup() {
  // put your setup code here, to run once:
  while (!Serial && millis() < 5000) ;
  Serial.begin(115200);
  Serial.println("Quick and dirty T4 Analog Read stuff");

}

typedef struct {
  uint8_t resolution;
  uint8_t averaging;
} analog_configs_t;

const analog_configs_t test_configs[] = {
  {8, 2}, {8, 4}, {8, 8}, {8, 16}, {8, 32},
  {10, 2}, {10, 4}, {10, 8}, {10, 16}, {10, 32},
  {12, 2}, {12, 4}, {12, 8}, {12, 16}, {12, 32}
};
uint8_t test_config_index = 0xff;



void loop() {
  test_config_index++;
  if (test_config_index == (sizeof(test_configs) / sizeof(test_configs[0]))) {
    test_config_index = 0;
  }

  T4AnalogReadRes(test_configs[test_config_index].resolution, 1);
  T4AnalogReadRes(test_configs[test_config_index].resolution, 2);
  T4AnalogReadAveraging(test_configs[test_config_index].averaging, 1);
  T4AnalogReadAveraging(test_configs[test_config_index].averaging, 2);
  //analogReadAveraging(averaging_count);

  // put your main code here, to run repeatedly:
  uint32_t t1 = micros();
  int a0 = analogRead(14);
  int a1 = analogRead(15);
  uint32_t t2 = micros();
  int a0_4 = T4AnalogRead(14, 1);
  int a1_4 = T4AnalogRead(15, 2);
  uint32_t t3 = micros();
  T4AnalogReadStart(14, 1);
  T4AnalogReadStart(15, 2);
  int a0_4C = T4AnalogReadComplete(1, true);
  int a1_4C = T4AnalogReadComplete(2, true);
  uint32_t t4 = micros();
  uint16_t a0_both, a1_both;
  T4AnalogReadBoth(14, a0_both, 15, a1_both);
  uint32_t t5 = micros();

  Serial.printf("%u:%u(%08x %08x)> %d %d %u : %d %d %u : %d %d %u : %u %u %u\n",
                test_configs[test_config_index].resolution, test_configs[test_config_index].averaging,
                ADC1_CFG, ADC1_GC,
                a0, a1, t2 - t1,
                a0_4, a1_4, t3 - t2,
                a0_4C, a1_4C, t4 - t3,
                a0_both, a1_both, t5 - t4);
  delay(500);
}

Example output:
Code:
8:2(000007a3 00000000)> 0 1 7 : 1 0 6 : 0 1 4 : 1 1 3
8:4(000007a3 00000020)> 4 5 22 : 5 4 23 : 4 5 11 : 5 5 12
8:8(000047a3 00000020)> 5 5 44 : 5 4 44 : 5 6 22 : 5 6 22
8:16(000087a3 00000020)> 6 6 86 : 6 5 88 : 6 6 44 : 6 6 44
8:32(0000c7a3 00000020)> 6 6 173 : 6 5 174 : 6 6 87 : 6 6 87
10:2(000006b7 00000000)> 1 2 10 : 2 4 10 : 0 2 5 : 4 2 5
10:4(000006b7 00000020)> 8 9 36 : 8 7 36 : 6 11 18 : 7 11 18
10:8(000046b7 00000020)> 9 10 70 : 9 8 71 : 8 12 35 : 8 12 36
10:16(000086b7 00000020)> 9 11 140 : 9 9 141 : 8 12 71 : 8 11 71
10:32(0000c6b7 00000020)> 10 11 279 : 9 9 280 : 9 11 141 : 9 11 141
12:2(000007bb 00000000)> 7 8 12 : 8 2 11 : 1 14 6 : 3 4 6
12:4(000007bb 00000020)> 23 27 42 : 23 20 42 : 18 33 22 : 19 33 21
12:8(000047bb 00000020)> 25 29 83 : 26 23 84 : 22 36 43 : 22 39 42
12:16(000087bb 00000020)> 27 32 166 : 27 25 167 : 23 37 84 : 23 37 85
12:32(0000c7bb 00000020)> 27 33 333 : 27 25 333 : 24 35 168 : 24 33 167
8:2(000007a3 00000000)> 0 1 7 : 1 0 6 : 0 1 4 : 1 1 3

Edit: Both analogs were floating... SO here is with one setup with simple resistor divider to 3.3/2 on one pin
Code:
8:2(000007a3 00000000)> 0 127 7 : 10 127 6 : 1 127 4 : 1 126 3
8:4(000007a3 00000020)> 4 128 23 : 7 129 23 : 5 129 11 : 5 129 12
8:8(000047a3 00000020)> 5 129 43 : 7 129 45 : 5 129 22 : 5 129 22
8:16(000087a3 00000020)> 6 129 87 : 6 129 88 : 6 129 44 : 6 129 44
8:32(0000c7a3 00000020)> 6 129 173 : 6 129 174 : 6 129 87 : 6 129 88
10:2(000006b7 00000000)> 1 507 10 : 20 508 10 : 1 515 5 : 4 508 5
10:4(000006b7 00000020)> 7 515 35 : 12 516 36 : 8 517 18 : 8 517 18
10:8(000046b7 00000020)> 9 517 71 : 11 517 71 : 9 517 35 : 9 517 36
10:16(000086b7 00000020)> 10 518 140 : 11 518 141 : 10 517 70 : 9 518 71
10:32(0000c6b7 00000020)> 10 518 279 : 10 518 280 : 9 517 141 : 10 517 141
12:2(000007bb 00000000)> 5 2032 12 : 62 2031 11 : 5 2030 6 : 4 2029 6
12:4(000007bb 00000020)> 23 2063 43 : 41 2064 42 : 21 2064 22 : 23 2065 21
12:8(000047bb 00000020)> 27 2069 83 : 33 2068 84 : 25 2071 43 : 26 2069 42
12:16(000087bb 00000020)> 28 2071 167 : 31 2071 167 : 27 2069 84 : 27 2068 84
12:32(0000c7bb 00000020)> 28 2073 332 : 29 2069 334 : 28 2073 167 : 28 2071 167
8:2(000007a3 00000000)> 0 126 7 : 10 126 6 : 1 127 4 : 1 127 3
8:4(000007a3 00000020)> 4 128 22 : 7 129 23 : 4 129 11 : 5 129 12
8:8(000047a3 00000020)> 5 129 44 : 7 129 45 : 5 129 22 : 5 129 22
8:16(000087a3 00000020)> 6 129 87 : 6 129 88 : 6 129 44 : 6 129 44
8:32(0000c7a3 00000020)> 6 129 172 : 6 129 174 : 6 129 88 : 6 129 87
 
@KurtE
Think you need to leave in the while(….) for doing the calibration. As for the wait_for_cal function we can probably get rid of it of just put the same lines of code in for calibration as in the init function and replace the line if(calibrating)…. with the init lines.

Those were probably left over from T3.x since it was that way with the original ananlog.c before the res and averaging functions were added.

This was the quick function I wrote for fast mode:
Code:
void setShortConvTime(uint8_t adc_num){
	uint32_t tmp32, mode;

	tmp32 = ADC_CFG_ADSTS(0); //set sample time duration to 2 clocks
	tmp32 |= ~ADC_CFG_ADLSMP; //set sample time to short
	tmp32 |= ADC_CFG_ADHSC;	  //set high speed conversion.
	
	if(adc_num == 1){
		ADC1_CFG |= tmp32;
	} else {
		ADC2_CGG |= tmp32;
	}
}
but as a quick hack for testing I changed this line in the analogReadRes for mode=10:

Code:
    mode = ADC_CFG_MODE(1) | ADC_CFG_ADSTS(0) | ~ADC_CFG_ADLSMP | ADC_CFG_ADHSC;

tried it this way too just in case:
Code:
    mode = ADC_CFG_MODE(1) | ADC_CFG_ADSTS(0) | (0<<4) | ADC_CFG_ADHSC;
since ADC_CFG_ADLSMP = (1<<4).
 
@mjs513 - Will probably leave init and the wait for calibrating alone (if it aint broken... )

In Your previous post, this line just feels wrong:
Code:
mode = ADC_CFG_MODE(1) | ADC_CFG_ADSTS(0)[COLOR="#FF0000"] | ~ADC_CFG_ADLSMP[/COLOR] | ADC_CFG_ADHSC;

i.e. looks like you are oring in every bit but ADC_CFG_ADLSMP

EDIT: Likewise in your function setShortConvTime
Code:
tmp32 |= ~ADC_CFG_ADLSMP; //set sample time to short
 
Last edited:
@mjs513 - Quick update: If you look at my previous post, with the updated test sketch that sets both the resolution and averaging.

And you look at the output line: 8:2(000007a3 00000000)> 0 127 7 : 10 127 6 : 1 127 4 : 1 126 3
We see that I have ADC2_CFG set to 0x7A3

So we have ADICLK(3) - Asynchronous clock
ADC2_CFG = ADICLK(3) | MODE(0) | ADIV(1) | ADLPC | ADSTS(3) | ADHSC

Now to see if that looks right - Will hack up another version for highest speed.
 
@mjs513 I hacked up my version of code to add in a mode to set the resolution to 0x88 and if so it is 8 fast...

Code:
Quick and dirty T4 Analog Read stuff
8:2(000007a3 00000000)> 3 127 6 : 10 127 7 : 1 126 3 : 1 127 4
8:4(000007a3 00000020)> 4 128 22 : 7 128 23 : 4 129 11 : 5 129 12
8:8(000047a3 00000020)> 5 129 44 : 7 129 44 : 5 129 22 : 5 129 23
8:16(000087a3 00000020)> 6 129 87 : 6 129 87 : 6 129 44 : 6 129 44
8:32(0000c7a3 00000020)> 6 129 174 : 6 129 174 : 6 129 87 : 6 129 88
a:2(000006b7 00000000)> 1 508 10 : 19 508 10 : 1 508 5 : 2 508 5
a:4(000006b7 00000020)> 8 516 36 : 12 516 36 : 8 517 18 : 8 518 19
a:8(000046b7 00000020)> 9 517 70 : 11 516 71 : 9 517 36 : 9 516 35
a:16(000086b7 00000020)> 10 518 141 : 11 517 140 : 9 517 71 : 9 518 71
a:32(0000c6b7 00000020)> 10 518 279 : 10 517 281 : 9 517 141 : 9 518 141
c:2(000007bb 00000000)> 6 2033 12 : 61 2031 11 : 4 2031 6 : 5 2033 6
c:4(000007bb 00000020)> 23 2062 42 : 36 2064 43 : 22 2064 21 : 23 2068 22
c:8(000047bb 00000020)> 26 2070 83 : 33 2063 85 : 25 2066 42 : 25 2066 42
c:16(000087bb 00000020)> 27 2072 167 : 30 2071 168 : 28 2071 84 : 27 2070 84
c:32(0000c7bb 00000020)> 29 2072 333 : 30 2073 334 : 28 2071 167 : 27 2071 168
88:2(000004a3 00000000)> 1 127 6 : 15 126 5 : 2 127 3 : 2 127 2
 

Attachments

  • T4_ADC_Lite-191203a.zip
    2.7 KB · Views: 66
@KurtE

Head is still in a fog but it looks like all you did was
Code:
ADC_CFG_ADSTS(3)
to
Code:
ADC_CFG_ADSTS(0)
,i.e., sample time duration from 17 to 2 clocks? Understand that part but then when I read the ADC chapter, pg 3469, was a bit different. All I can say is that the manual still confuses me. We don't have to put into high speed mode?
 
@mjs513 - Yep I just copied the 8 bit setup to a special 8 bit setup..
As I noticed that already the 8 bit mode did not turn on the ADLSMP bit, like 10 and 12 do...


Code:
void T4AnalogReadRes(unsigned int bits, uint8_t adc_num)
{
  uint32_t tmp32, mode;

  if (bits == 8) {
    // 8 bit conversion (17 clocks) plus 8 clocks for input settling
    mode = ADC_CFG_MODE(0) | ADC_CFG_ADSTS(3);
  [COLOR="#006400"]} else if (bits == 0x88)  {
    // 8 bit fast conversion
    mode = ADC_CFG_MODE(0) | ADC_CFG_ADSTS(0);[/COLOR]
  } else if (bits == 10) {
    // 10 bit conversion (17 clocks) plus 20 clocks for input settling
    mode = ADC_CFG_MODE(1) | ADC_CFG_ADSTS(2)[COLOR="#FF0000"] | ADC_CFG_ADLSMP[/COLOR];
  } else {
    // 12 bit conversion (25 clocks) plus 24 clocks for input settling
    mode = ADC_CFG_MODE(2) | ADC_CFG_ADSTS(3)[COLOR="#FF0000"] | ADC_CFG_ADLSMP[/COLOR];
  }

  if (adc_num == 1) {
    tmp32  = (ADC1_CFG & (0xFFFFFC00));
    tmp32 |= (ADC1_CFG & (0x03));  // ADICLK
    tmp32 |= (ADC1_CFG & (0xE0));  // ADIV & ADLPC

    tmp32 |= mode;
    ADC1_CFG = tmp32;
  } else {
    tmp32  = (ADC2_CFG & (0xFFFFFC00));
    tmp32 |= (ADC2_CFG & (0x03));  // ADICLK
    tmp32 |= (ADC2_CFG & (0xE0));  // ADIV & ADLPC
    tmp32 |= mode;
    ADC2_CFG = tmp32;
  }
}
I figured that the lines like: tmp32 = (ADC1_CFG & (0xFFFFFC00));
removed the ADC_CFG_ADLSMP bit (0x10) If it had been previously set.

But I did not set your high speed bit...

Hope you start feeling better!

Edit: as for understanding the chapter... I was simply taking your lead on what you wanted.

I would guess to fix your above function it should be:
Code:
void setShortConvTime(uint8_t adc_num){
	uint32_t tmp32, mode;

	tmp32 = ADC_CFG_ADSTS(0); //set sample time duration to 2 clocks
	tmp32 |= ADC_CFG_ADHSC;	  //set high speed conversion.
	
	if(adc_num == 1){
		ADC1_CFG  = (ADC1_CFG  & ~ADC_CFG_ADLSMP) | tmp32;
	} else {
		ADC2_CFG  = (ADC2_CFG  & ~ADC_CFG_ADLSMP) | tmp32;
	}
}
But I might be wrong...

2nd edit

Yep wrong... Need to clear the other ADSTS bits, maybe more like:

Code:
	ADC1_CFG  = (ADC1_CFG  & ~(ADC_CFG_ADLSMP|ADC_CFG_ADSTS(3) )) | tmp32;
 
Last edited:
@KurtE

Did a quick and dirty test with the following 2 functions added to the sketch:
Code:
void setShortConvTime(uint8_t adc_num){
  uint32_t tmp32, mode;

  tmp32 = ADC_CFG_ADSTS(0); //set sample time duration to 2 clocks
  tmp32 |= ADC_CFG_ADHSC;   //set high speed conversion.
  
  if(adc_num == 1){
    ADC1_CFG  = (ADC1_CFG  & ~(ADC_CFG_ADLSMP|ADC_CFG_ADSTS(3) )) | tmp32;
  } else {
    ADC2_CFG  = (ADC2_CFG  & ~(ADC_CFG_ADLSMP|ADC_CFG_ADSTS(3) )) | tmp32;
  }
}

void setShortConvTimeBoth(){
  uint32_t tmp32, mode;

  tmp32 = ADC_CFG_ADSTS(0); //set sample time duration to 2 clocks
  tmp32 |= ADC_CFG_ADHSC;   //set high speed conversion.
  
    ADC1_CFG  = (ADC1_CFG  & ~(ADC_CFG_ADLSMP|ADC_CFG_ADSTS(3) )) | tmp32;
    ADC2_CFG  = (ADC2_CFG  & ~(ADC_CFG_ADLSMP|ADC_CFG_ADSTS(3) )) | tmp32;
}

Only mod I did to your posted sketch was:
Code:
  T4AnalogReadRes(test_configs[test_config_index].resolution, 1);
  //setShortConvTime(1);
  T4AnalogReadRes(test_configs[test_config_index].resolution, 2);
  //setShortConvTime(2);
  setShortConvTimeBoth();
So without fast conversion:
Code:
8:2(000007a3 00000000)> 0 255 6 : 0 255 7 : 0 255 3 : 0 255 4
8:4(000007a3 00000020)> 0 255 22 : 0 255 23 : 0 255 12 : 0 255 11
8:8(000047a3 00000020)> 0 255 44 : 0 255 45 : 0 255 22 : 0 255 23
8:16(000087a3 00000020)> 0 255 87 : 0 255 88 : 0 255 45 : 0 255 44
8:32(0000c7a3 00000020)> 0 255 175 : 0 255 176 : 0 255 88 : 0 255 89
a:2(000006b7 00000000)> 0 1023 10 : 1 1023 10 : 1 1023 5 : 0 1023 5
a:4(000006b7 00000020)> 0 1023 36 : 0 1023 36 : 0 1023 18 : 0 1023 18
a:8(000046b7 00000020)> 0 1023 71 : 0 1023 71 : 0 1023 36 : 0 1023 36
a:16(000086b7 00000020)> 0 1023 141 : 0 1023 142 : 0 1023 71 : 0 1023 72
a:32(0000c6b7 00000020)> 0 1023 282 : 0 1023 284 : 0 1023 142 : 0 1023 143
c:2(000007bb 00000000)> 4 4095 12 : 3 4095 12 : 0 4095 5 : 1 4095 6
c:4(000007bb 00000020)> 1 4095 42 : 1 4095 43 : 0 4095 22 : 0 4095 21
c:8(000047bb 00000020)> 1 4095 84 : 0 4095 85 : 0 4095 42 : 0 4095 43
c:16(000087bb 00000020)> 0 4095 168 : 0 4095 169 : 0 4095 85 : 0 4095 85
c:32(0000c7bb 00000020)> 0 4095 336 : 0 4095 337 : 0 4095 169 : 0 4095 170
with fast conversion time:
Code:
Quick and dirty T4 Analog Read stuff

8:2(000004a3 00000000)> 0 255 5 : 0 255 5 : 0 255 3 : 0 255 3
8:4(000004a3 00000020)> 0 255 17 : 0 255 18 : 0 255 9 : 0 255 9
8:8(000044a3 00000020)> 0 255 34 : 0 255 35 : 0 255 17 : 0 255 17
8:16(000084a3 00000020)> 0 255 67 : 0 255 68 : 0 255 34 : 0 255 35
8:32(0000c4a3 00000020)> 0 255 134 : 0 255 135 : 0 255 68 : 0 255 68
a:2(000004a7 00000000)> 0 1023 6 : 0 1023 6 : 0 1023 3 : 0 1023 3
a:4(000004a7 00000020)> 0 1023 21 : 0 1023 21 : 0 1023 11 : 0 1023 10
a:8(000044a7 00000020)> 0 1023 41 : 0 1023 41 : 0 1023 21 : 0 1023 20
a:16(000084a7 00000020)> 0 1023 81 : 0 1023 81 : 0 1023 41 : 0 1023 41
a:32(0000c4a7 00000020)> 0 1023 161 : 0 1023 162 : 0 1023 81 : 0 1023 82
c:2(000004ab 00000000)> 0 4095 7 : 3 4095 6 : 3 4095 4 : 5 4095 4
c:4(000004ab 00000020)> 2 4095 24 : 1 4095 25 : 1 4095 12 : 0 4095 12
c:8(000044ab 00000020)> 1 4095 47 : 0 4095 48 : 0 4095 24 : 0 4095 24
c:16(000084ab 00000020)> 1 4095 94 : 0 4095 95 : 0 4095 47 : 0 4095 48
c:32(0000c4ab 00000020)> 0 4095 188 : 0 4095 189 : 0 4095 94 : 0 4095 95
not sure if adding 2 new functions would be better or just modify the existing analogReadRes function?
 
@mjs513 Good Morning,

Good question? Especially if the goal might be to get this functionality into core?

Or should we aim to be semi-aligned with the ADC library? The only place that I have played much with ADC was with well monitor stuff, which if forever never completed... Only interest comes when the well system breaks... Right now well is working so...

But in that one I am doing some DMA analog reading of the two channels and then process it, to get an idea of how much current is flowing through wires (is a pump running or not...)

Wonder if anyone has looked at DMA with Analog on T4 yet? I think on T3.x ADC library uses a timer as a trigger (may take a quick look)
 
@mjs513 - Thanks, I thought I remembered seeing something during beta..

Wondering with our hacking if we should repackage the test stuff to be more like: ADC Light?

That is to convert the stuff into an object like ADC4 and have methods like:

Code:
int value = adc->analogRead(A9);
int value = adc->analogRead(A9, ADC_0);
ADC::Sync_result result = adc->analogSyncRead(pin1, pin2);

startSingleRead
readSingle()...


adc->setSamplingSpeed(speed); // change the sampling speed
adc->setConversionSpeed(speed); // change the conversion speed
adc->setResolution(...

Again I am not a big user of it, so not sure how much of the Full ADC library that would be needed to be useful?
 
@KurtE
Good morning again :)

Think you are right about repackaging the test stuff. Make it look more like how the ADC.lib is organized in terms of function names.
 
@mjs513...

I have been playing around with a semi stripped down version of ADC, which for now I put up on github... I am not sure if it will stay or not...

But if you want a laugh...

https://github.com/KurtE/ADCL_t4

This includes a converted version of the example sketch.
 
Interesting, I can't get anything close to the < 1 usec conversions that I thought were possible. More like 2.5 usec per conversion, about teensy 3.2 speed.
 
@jonr - might be possible to get better. Right now the adc clock defaults to 20mhz. Not sure but if you change it to 40mhz it should be faster.
 
@jonr - @KurtE

To test my theory of the changing the ADC clock i first ran the sketch in @KurtE's new version of the library for a baseline:
Code:
[COLOR="#FF0000"]8:2:2:2(000005b3 00000000)> 255 6 7 : 255 0 8 : 255 1 4 : 255 1 4[/COLOR]
8:2:2:2(000005b3 00000000)> 255 6 7 : 255 0 8 : 255 1 4 : 255 1 4
8:4:2:2(000005b3 00000020)> 255 5 27 : 255 2 28 : 255 3 14 : 255 3 14
8:8:2:2(000045b3 00000020)> 255 4 53 : 255 3 55 : 255 3 27 : 255 3 27
8:16:2:2(000085b3 00000020)> 255 4 106 : 255 3 108 : 255 3 54 : 255 3 54
8:32:2:2(0000c5b3 00000020)> 255 4 212 : 255 3 214 : 255 3 107 : 255 3 107
a:2:2:2(000005b7 00000000)> 1022 27 8 : 1023 3 9 : 1023 5 4 : 1023 3 4
a:4:2:2(000005b7 00000020)> 1023 20 30 : 1023 10 31 : 1023 12 15 : 1023 11 16
a:8:2:2(000045b7 00000020)> 1023 18 60 : 1023 13 60 : 1023 12 31 : 1023 12 30
a:16:2:2(000085b7 00000020)> 1023 18 119 : 1023 12 119 : 1023 13 61 : 1023 13 60
a:32:2:2(0000c5b7 00000020)> 1023 17 237 : 1023 13 239 : 1023 13 120 : 1023 13 120
c:2:2:2(000005bb 00000000)> 4094 109 9 : 4093 10 9 : 4095 23 5 : 4094 18 5
c:4:2:2(000005bb 00000020)> 4092 76 33 : 4093 37 34 : 4093 47 17 : 4094 40 17
c:8:2:2(000045bb 00000020)> 4093 68 66 : 4093 44 66 : 4092 45 34 : 4093 45 34
c:16:2:2(000085bb 00000020)> 4093 64 131 : 4093 45 132 : 4093 46 67 : 4093 46 67
[COLOR="#FF0000"]c:32:2:2(0000c5bb 00000020)> 4093 61 262 : 4093 47 264 : 4093 47 132 : 4093 46 133[/COLOR]

Changing the clock source and keeping the max ADC freq at 20Mhz (see analog.c) and changing the "if 1" to "if 0" you can see their already is a large improvement. Oh - I also changed F_BUS to F_BUS_ACTUAL.
Code:
[COLOR="#FF0000"]8:2:2:2(000005d1 00000000)> 255 9 4 : 255 2 5 : 255 3 2 : 255 3 2[/COLOR]
8:2:2:2(000005d1 00000000)> 255 9 4 : 255 2 5 : 255 3 2 : 255 3 2
8:4:2:2(000005d1 00000020)> 255 9 15 : 255 5 15 : 255 7 8 : 255 7 8
8:8:2:2(000045d1 00000020)> 255 10 30 : 255 7 29 : 255 8 15 : 255 8 16
8:16:2:2(000085d1 00000020)> 255 9 59 : 255 7 58 : 255 8 30 : 255 8 30
8:32:2:2(0000c5d1 00000020)> 255 9 117 : 255 8 116 : 255 8 59 : 255 8 59
a:2:2:2(000005d5 00000000)> 1023 39 5 : 1023 9 4 : 1023 13 3 : 1023 14 3
a:4:2:2(000005d5 00000020)> 1023 37 17 : 1023 20 17 : 1023 27 9 : 1023 27 8
a:8:2:2(000045d5 00000020)> 1023 36 33 : 1023 25 33 : 1023 29 17 : 1023 29 17
a:16:2:2(000085d5 00000020)> 1023 36 65 : 1023 28 66 : 1023 30 33 : 1023 30 33
a:32:2:2(0000c5d5 00000020)> 1023 36 130 : 1023 29 131 : 1023 30 65 : 1023 30 66
c:2:2:2(000005d9 00000000)> 4095 158 5 : 4095 35 5 : 4095 48 3 : 4095 49 3
c:4:2:2(000005d9 00000020)> 4093 140 18 : 4094 75 19 : 4095 97 10 : 4094 97 9
c:8:2:2(000045d9 00000020)> 4094 134 36 : 4094 93 37 : 4094 105 19 : 4093 105 18
c:16:2:2(000085d9 00000020)> 4095 132 72 : 4094 101 73 : 4094 110 36 : 4094 109 36
[COLOR="#FF0000"]c:32:2:2(0000c5d9 00000020)> 4094 131 144 : 4094 105 144 : 4094 109 72 : 4094 111[/COLOR]

Changing the max ADC clock freq to 40Mhz you get a dramatic change:
Code:
[COLOR="#FF0000"]8:2:2:2(000005b1 00000000)> 255 12 2 : 255 6 2 : 255 7 2 : 255 8 1[/COLOR]
8:2:2:2(000005b1 00000000)> 255 12 2 : 255 6 3 : 255 7 1 : 255 7 1
8:4:2:2(000005b1 00000020)> 255 16 8 : 255 10 7 : 255 15 5 : 255 16 4
8:8:2:2(000045b1 00000020)> 255 18 15 : 255 13 15 : 255 18 8 : 255 17 7
8:16:2:2(000085b1 00000020)> 255 19 29 : 255 16 30 : 255 19 15 : 255 19 15
8:32:2:2(0000c5b1 00000020)> 255 20 58 : 255 18 59 : 255 19 29 : 255 19 30
a:2:2:2(000005b5 00000000)> 1023 50 2 : 1023 25 3 : 1023 29 1 : 1023 29 2
a:4:2:2(000005b5 00000020)> 1023 61 8 : 1023 38 9 : 1023 55 5 : 1023 56 4
a:8:2:2(000045b5 00000020)> 1023 68 17 : 1023 49 16 : 1023 63 9 : 1023 64 8
a:16:2:2(000085b5 00000020)> 1023 72 33 : 1023 60 33 : 1023 69 16 : 1023 68 17
a:32:2:2(0000c5b5 00000020)> 1023 75 65 : 1023 66 66 : 1023 70 32 : 1023 71 33
c:2:2:2(000005b9 00000000)> 4095 200 2 : 4094 94 3 : 4095 109 2 : 4095 107 1
c:4:2:2(000005b9 00000020)> 4094 231 9 : 4094 142 10 : 4095 205 5 : 4095 205 5
c:8:2:2(000045b9 00000020)> 4094 255 18 : 4094 182 19 : 4094 223 9 : 4094 224 10
c:16:2:2(000085b9 00000020)> 4094 266 36 : 4094 210 37 : 4094 231 18 : 4094 231 18
[COLOR="#FF0000"]c:32:2:2(0000c5b9 00000020)> 4094 275 72 : 4094 221 72 : 4094 231 37 : 4094 234 36[/COLOR]
This is just a quick and dirty. Tomorrow I will look at adding this to the lib unless @KurtE beats me to it.
 
@KurtE et.al.

Trying to understand a bit more about the ADC clocks. Understand about using the IPG clock (also more noisy) but a bit confused on the Async Clock (ADACK). According to RM the ADACK is a internal clock source of the ADC fine. But can't seem to find in the RM what that clock frequency is? Does anybody know?

In the ADC library he has it specified as:
Code:
internal asynchronous clock settings: fADK = 2.4, 4.0, 5.2 or 6.2 MHz
but not sure this is the same as for the T4.0 but who knows.
 
I believe from the IMXRT1060CEC.. pdf Page 62 (at least in the one I have)

ADC Asynchronous
Clock Source
ADHSC=0 fADACK — 10 — MHz tADACK = 1/fADACK
ADHSC=1 — 20 —

So 10 or 20 mhz
 
@KurtE
Thanks. Didn't look in that doc - thought that would have been in the RM as well.
 
@mjs513 - Me too, but when I did not find it in RM, decided to look.

Just pushed up a quick and dirty ReadMe.md file which is a copy of pedvide's Readme with a warning at top that this is a WIP and who knows what will happen to it...
Figured needed it as the original library has the Copyright statements...
 
Status
Not open for further replies.
Back
Top