Teensy 4.0 which pins for which ADC

Status
Not open for further replies.
@KurtE
Working on the clock module now - not sure I am doing it right I will post when I get done. Trying to understand as I go then next up I think is the Compare which is a bit more complicated since the DAC out are on pins 26 (ACMP3) or 27 (ACMP4) - see @manitou's repository https://github.com/manitou48/teensy4
 
@mjs513 @manitou... Yep I did clone that project down to my disk as well and I am curious about how one sets up to do DMA from the ADC at a specific input rate.

That is with my always never completed well monitor stuff on T3.6, I setup using ADC with DMA using the PDB stuff, where I would tell the ADC to convert at 50*60 samples per second (so get 50 samples per AC cycle)...
SO how do I do the same with T4....
@manitou has example sketch using ADC ADC_ETC XBAR PIT - which in readme says so far sketch does not work... But wondering if this is what is needed to get there?
 
In the past, I've found it useful to set up the ADC to continually (as fast as possible) DMA a value into a single location. Then just read that location whenever your code needs an analog read. More consistent with what people get with digital reads, creating faster running code with with less overhead than threads or interrupts. So +1 on DMA being useful.
 
@KurtE
Got the hack working, now you have more options than you can shake a stick for adc clock speed. Only thing I need to fix is:
Code:
	//ADC1
	//NOTE:  Only works once - have to change ADIV and ADICLK to get current
	//value first then do the negation and then the reset.
	ADC1_CFG = (ADC1_CFG & (~ADC_CFG_ADIV(1)) & (~ADC_CFG_ADICLK(3))) | adc_cfg_div;
	//calibrating = 1;
	while (ADC1_GC & ADC_GC_CAL) ;
	//calibrating = 0;	
	ADC2_CFG = (ADC2_CFG & (~ADC_CFG_ADIV(1)) & (~ADC_CFG_ADICLK(3))) | adc_cfg_div;
	//calibrating = 1;
	while (ADC2_GC & ADC_GC_CAL) ;
	//calibrating = 0;

Here are the files:
View attachment ADCL_t4-master.zip

I called it in setup like:
Code:
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");

  adc = new ADCL;
  adc->setAdcClockSpeed(ADC_CONVERSION_SPEED::ADACK_20_0_H);
}
This is actually the default config.
The options equate to:
Code:
    VERY_LOW_SPEED, /*!< IPG/16. */
    LOW_SPEED, /*!< IPG/8. */
    MED_SPEED, /*!< IPG/4 */
    HIGH_SPEED_16BITS, /*!< is guaranteed to be the highest possible speed within specs for all resolutions (lower than or equal to 12 MHz). */
    HIGH_SPEED, /*!<IPG/2 */
    VERY_HIGH_SPEED, /*!< may be out of specs, IPG */
//Supposed lower noise for the ADC
	ADACK_1_25_N, /*!< 1.25 MHz asynchronous ADC clock (independent of the global clocks F_CPU or F_BUS), Normal Mode*/
	ADACK_2_5_N,  /*!< 2.5 MHz asynchronous ADC clock (independent of the global clocks F_CPU or F_BUS), Normal Mode*/
	ADACK_5_0_N, /*!< 5.0 MHz asynchronous ADC clock (independent of the global clocks F_CPU or F_BUS), Normal Mode*/
	ADACK_10_0_N, /*!< 10.0 MHz asynchronous ADC clock (independent of the global clocks F_CPU or F_BUS), Normal Mode*/
	ADACK_2_5_H,  /*!< 2.5 MHz asynchronous ADC clock (independent of the global clocks F_CPU or F_BUS), High Speed*/
	ADACK_5_0_H, /*!< 5.0 MHz asynchronous ADC clock (independent of the global clocks F_CPU or F_BUS), High Speed*/
	ADACK_10_0_H, /*!< 10.0 MHz asynchronous ADC clock (independent of the global clocks F_CPU or F_BUS), High Speed*/
	ADACK_20_0_H /*!< 20.0 MHz asynchronous ADC clock (independent of the global clocks F_CPU or F_BUS), High Speed*/

OK - more coffee
 
Hi @mjs513 - Yep more coffee (Feel free to PR it)! You probably know more about all of this than I do!

@jonr - DMA does not look too hard to add here... Again @manitou has example app, which I will try out soon
 
Good Morning @KurtE - days are all beginning to merge into one.

Solved my issue to get the current bits for adiv and clk and incorporated into the function. I also just pushed it to GitHub.

Cheers.
 
@mjs513, @PaulStoffregen @manitou, ...

Thought I would see how hard it is to do ADC using DMA at some specific sampling rate, Example for trying to guess if an power is running to a well pump, so with T3.6 I setup to read at 3000 samples per second(So get 50 samples per AC cycle...)...
This use ADC with PDB and DMA...

Should be a piece of cake...

Not sure yet I may try simpler version first of simply try to put in the DMA support. I know that @manitou has a sketch... Should hopefully not be heard to adapt ...

But to do the conversions at a specific time, my Nth pass through document, and now seeing @manitou other example sketch, I believe that, to do this,

You need something like:
a) PIT timer which sets up to timing stuff for you
b) an ADC_ETC (External Trigger Control) that you setup one of them that is configured to point to your ADC number and channel and ADC using the ADC_ETC as it's channel.
c) XBAR1 setup where you setup to MAP from the PIT timer you choose to map the PIT timer to the ADC_ETC object
...

Easy... What could go wrong ;)

Especially with simple things like in the example sketch: xbar_connect(56, 103); // pit to adc_etc

You start off saying WTF... what is 56 and 103?

First 56 which from sketch I know is some form of INPUT and 103 some form of output.
It you look at Table 3-4 (Page 62) We find that:
Code:
PIT_TRIGGER0 XBAR1_IN56

So it is a trigger from PIT...

Likewise 103 - Table 3-7, (page 70)
Code:
XBAR1_OUT103 ADC_ETC_TRIG00
So it is setup to be ETC Trigger 0...

Next question is, is there some place that these magic numbers are defined? And/Or should they be?
i.e. should be be some either #defines and/or enum declares like:
Code:
#define XBAR1_IN_PIT_TRIGGER0 56
#define XBAR1_OUT_ADC_ETC_TRIG00 103
If so should these be part of imxrt.h?

Or would the be part of enum/class or like so instead of above you might be XBAR1_IN::pIT_TRIGGER0 ?

Also there are probably a lot more magic numbers to decode here as well!

Just wondering... Also I do very much appreciate all of these examples! THANKS!
 
@mjs513 - will take a look..

Here is a sublimetext mucked with table for XBar1...

Wonder this would be valid/reasonable addition for imxrt.h? And if so do I need to do XBAR2...
Code:
// XBAR1 Inputs and Outputs
#define XBAR1_IN_LOGIC_LOW 0
#define XBAR1_IN_LOGIC_HIGH 1
#define XBAR1_IN_IOMUX_XBAR_IN02 2
#define XBAR1_IN_IOMUX_XBAR_IN03 3
#define XBAR1_IN_IOMUX_XBAR_INOUT04 4
#define XBAR1_IN_IOMUX_XBAR_INOUT05 5
#define XBAR1_IN_IOMUX_XBAR_INOUT06 6
#define XBAR1_IN_IOMUX_XBAR_INOUT07 7
#define XBAR1_IN_IOMUX_XBAR_INOUT08 8
#define XBAR1_IN_IOMUX_XBAR_INOUT09 9
#define XBAR1_IN_IOMUX_XBAR_INOUT10 10
#define XBAR1_IN_IOMUX_XBAR_INOUT11 11
#define XBAR1_IN_IOMUX_XBAR_INOUT12 12
#define XBAR1_IN_IOMUX_XBAR_INOUT13 13
#define XBAR1_IN_IOMUX_XBAR_INOUT14 14
#define XBAR1_IN_IOMUX_XBAR_INOUT15 15
#define XBAR1_IN_IOMUX_XBAR_INOUT16 16
#define XBAR1_IN_IOMUX_XBAR_INOUT17 17
#define XBAR1_IN_IOMUX_XBAR_INOUT18 18
#define XBAR1_IN_IOMUX_XBAR_INOUT19 19
#define XBAR1_IN_IOMUX_XBAR_IN20 20
#define XBAR1_IN_IOMUX_XBAR_IN21 21
#define XBAR1_IN_IOMUX_XBAR_IN22 22
#define XBAR1_IN_IOMUX_XBAR_IN23 23
#define XBAR1_IN_IOMUX_XBAR_IN24 24
#define XBAR1_IN_IOMUX_XBAR_IN25 25
#define XBAR1_IN_ACMP1_OUT 26
#define XBAR1_IN_ACMP2_OUT 27
#define XBAR1_IN_ACMP3_OUT 28
#define XBAR1_IN_ACMP4_OUT 29
//#define XBAR1_IN_Reserved 30
//#define XBAR1_IN_Reserved 31
#define XBAR1_IN_QTIMER3_TIMER0 32
#define XBAR1_IN_QTIMER3_TIMER1 33
#define XBAR1_IN_QTIMER3_TIMER2 34
#define XBAR1_IN_QTIMER3_TIMER3 35
#define XBAR1_IN_QTIMER4_TIMER0 36
#define XBAR1_IN_QTIMER4_TIMER1 37
#define XBAR1_IN_QTIMER4_TIMER2 38
#define XBAR1_IN_QTIMER4_TIMER3 39
#define XBAR1_IN_FLEXPWM1_PWM1_OUT_TRIG0 40
#define XBAR1_IN_FLEXPWM1_PWM1_OUT_TRIG1 40
#define XBAR1_IN_FLEXPWM1_PWM2_OUT_TRIG0 41
#define XBAR1_IN_FLEXPWM1_PWM2_OUT_TRIG1 41
#define XBAR1_IN_FLEXPWM1_PWM3_OUT_TRIG0 42
#define XBAR1_IN_FLEXPWM1_PWM3_OUT_TRIG1 42
#define XBAR1_IN_FLEXPWM1_PWM4_OUT_TRIG0 43
#define XBAR1_IN_FLEXPWM1_PWM4_OUT_TRIG1 43
#define XBAR1_IN_FLEXPWM2_PWM1_OUT_TRIG0 44
#define XBAR1_IN_FLEXPWM2_PWM1_OUT_TRIG1 44
#define XBAR1_IN_FLEXPWM2_PWM2_OUT_TRIG0 45
#define XBAR1_IN_FLEXPWM2_PWM2_OUT_TRIG1 45
#define XBAR1_IN_FLEXPWM2_PWM3_OUT_TRIG0 46
#define XBAR1_IN_FLEXPWM2_PWM3_OUT_TRIG1 46
#define XBAR1_IN_FLEXPWM2_PWM4_OUT_TRIG0 47
#define XBAR1_IN_FLEXPWM2_PWM4_OUT_TRIG1 47
#define XBAR1_IN_FLEXPWM3_PWM1_OUT_TRIG0 48
#define XBAR1_IN_FLEXPWM3_PWM1_OUT_TRIG1 48
#define XBAR1_IN_FLEXPWM3_PWM2_OUT_TRIG0 49
#define XBAR1_IN_FLEXPWM3_PWM2_OUT_TRIG1 49
#define XBAR1_IN_FLEXPWM3_PWM3_OUT_TRIG0 50
#define XBAR1_IN_FLEXPWM3_PWM3_OUT_TRIG1 50
#define XBAR1_IN_FLEXPWM3_PWM4_OUT_TRIG0 51
#define XBAR1_IN_FLEXPWM3_PWM4_OUT_TRIG1 51
#define XBAR1_IN_FLEXPWM4_PWM1_OUT_TRIG0 52
#define XBAR1_IN_FLEXPWM4_PWM1_OUT_TRIG1 52
#define XBAR1_IN_FLEXPWM4_PWM2_OUT_TRIG0 53
#define XBAR1_IN_FLEXPWM4_PWM2_OUT_TRIG1 53
#define XBAR1_IN_FLEXPWM4_PWM3_OUT_TRIG0 54
#define XBAR1_IN_FLEXPWM4_PWM3_OUT_TRIG1 54
#define XBAR1_IN_FLEXPWM4_PWM4_OUT_TRIG0 55
#define XBAR1_IN_FLEXPWM4_PWM4_OUT_TRIG1 55
#define XBAR1_IN_PIT_TRIGGER0 56
#define XBAR1_IN_PIT_TRIGGER1 57
#define XBAR1_IN_PIT_TRIGGER2 58
#define XBAR1_IN_PIT_TRIGGER3 59
#define XBAR1_IN_ENC1_POS_MATCH 60
#define XBAR1_IN_ENC2_POS_MATCH 61
#define XBAR1_IN_ENC3_POS_MATCH 62
#define XBAR1_IN_ENC4_POS_MATCH 63
#define XBAR1_IN_DMA_DONE0 64
#define XBAR1_IN_DMA_DONE1 65
#define XBAR1_IN_DMA_DONE2 66
#define XBAR1_IN_DMA_DONE3 67
#define XBAR1_IN_DMA_DONE4 68
#define XBAR1_IN_DMA_DONE5 69
#define XBAR1_IN_DMA_DONE6 70
#define XBAR1_IN_DMA_DONE7 71
#define XBAR1_IN_AOI1_OUT0 72
#define XBAR1_IN_AOI1_OUT1 73
#define XBAR1_IN_AOI1_OUT2 74
#define XBAR1_IN_AOI1_OUT3 75
#define XBAR1_IN_AOI2_OUT0 76
#define XBAR1_IN_AOI2_OUT1 77
#define XBAR1_IN_AOI2_OUT2 78
#define XBAR1_IN_AOI2_OUT3 79
#define XBAR1_IN_ADC_ETC0_COCO0 80
#define XBAR1_IN_ADC_ETC0_COCO1 81
#define XBAR1_IN_ADC_ETC0_COCO2 82
#define XBAR1_IN_ADC_ETC0_COCO3 83
#define XBAR1_IN_ADC_ETC1_COCO0 84
#define XBAR1_IN_ADC_ETC1_COCO1 85
#define XBAR1_IN_ADC_ETC1_COCO2 86
#define XBAR1_IN_ADC_ETC1_COCO3 87

#define XBAR1_OUT_DMA_CH_MUX_REQ30 0
#define XBAR1_OUT_DMA_CH_MUX_REQ31 1
#define XBAR1_OUT_DMA_CH_MUX_REQ94 2
#define XBAR1_OUT_DMA_CH_MUX_REQ95 3
#define XBAR1_OUT_IOMUX_XBAR_INOUT04 4
#define XBAR1_OUT_IOMUX_XBAR_INOUT05 5
#define XBAR1_OUT_IOMUX_XBAR_INOUT06 6
#define XBAR1_OUT_IOMUX_XBAR_INOUT07 7
#define XBAR1_OUT_IOMUX_XBAR_INOUT08 8
#define XBAR1_OUT_IOMUX_XBAR_INOUT09 9
#define XBAR1_OUT_IOMUX_XBAR_INOUT10 10
#define XBAR1_OUT_IOMUX_XBAR_INOUT11 11
#define XBAR1_OUT_IOMUX_XBAR_INOUT12 12
#define XBAR1_OUT_IOMUX_XBAR_INOUT13 13
#define XBAR1_OUT_IOMUX_XBAR_INOUT14 14
#define XBAR1_OUT_IOMUX_XBAR_INOUT15 15
#define XBAR1_OUT_IOMUX_XBAR_INOUT16 16
#define XBAR1_OUT_IOMUX_XBAR_INOUT17 17
#define XBAR1_OUT_IOMUX_XBAR_INOUT18 18
#define XBAR1_OUT_IOMUX_XBAR_INOUT19 19
#define XBAR1_OUT_ACMP1_SAMPLE 20
#define XBAR1_OUT_ACMP2_SAMPLE 21
#define XBAR1_OUT_ACMP3_SAMPLE 22
#define XBAR1_OUT_ACMP4_SAMPLE 23
//#define XBAR1_OUT_Reserved 24
//#define XBAR1_OUT_Reserved 25
#define XBAR1_OUT_FLEXPWM1_PWM0_EXTA 26
#define XBAR1_OUT_FLEXPWM1_PWM1_EXTA 27
#define XBAR1_OUT_FLEXPWM1_PWM2_EXTA 28
#define XBAR1_OUT_FLEXPWM1_PWM3_EXTA 29
#define XBAR1_OUT_FLEXPWM1_PWM0_EXT_SYNC 30
#define XBAR1_OUT_FLEXPWM1_PWM1_EXT_SYNC 31
#define XBAR1_OUT_FLEXPWM1_PWM2_EXT_SYNC 32
#define XBAR1_OUT_FLEXPWM1_PWM3_EXT_SYNC 33
#define XBAR1_OUT_FLEXPWM1_EXT_CLK 34
#define XBAR1_OUT_FLEXPWM1_FAULT0 35
#define XBAR1_OUT_FLEXPWM1_FAULT1 36
#define XBAR1_OUT_FLEXPWM1_FAULT2 37
#define XBAR1_OUT_FLEXPWM2_FAULT2 37
#define XBAR1_OUT_FLEXPWM3_FAULT2 37
#define XBAR1_OUT_FLEXPWM4_FAULT2 37
#define XBAR1_OUT_FLEXPWM1_FAULT3 38
#define XBAR1_OUT_FLEXPWM2_FAULT3 38
#define XBAR1_OUT_FLEXPWM3_FAULT3 38
#define XBAR1_OUT_FLEXPWM4_FAULT3 38
#define XBAR1_OUT_FLEXPWM1_EXT_FORCE 39
#define XBAR1_OUT_FLEXPWM2_PWM0_EXTA 40
#define XBAR1_OUT_FLEXPWM3_PWM0_EXTA 40
#define XBAR1_OUT_FLEXPWM4_PWM0_EXTA 40
#define XBAR1_OUT_FLEXPWM2_PWM1_EXTA 41
#define XBAR1_OUT_FLEXPWM3_PWM1_EXTA 41
#define XBAR1_OUT_FLEXPWM4_PWM1_EXTA 41
#define XBAR1_OUT_FLEXPWM2_PWM2_EXTA 42
#define XBAR1_OUT_FLEXPWM3_PWM2_EXTA 42
#define XBAR1_OUT_FLEXPWM4_PWM2_EXTA 42
#define XBAR1_OUT_FLEXPWM2_PWM3_EXTA 43
#define XBAR1_OUT_FLEXPWM3_PWM3_EXTA 43
#define XBAR1_OUT_FLEXPWM4_PWM3_EXTA 43
#define XBAR1_OUT_FLEXPWM2_PWM0_EXT_SYNC 44
#define XBAR1_OUT_FLEXPWM2_PWM1_EXT_SYNC 45
#define XBAR1_OUT_FLEXPWM2_PWM2_EXT_SYNC 46
#define XBAR1_OUT_FLEXPWM2_PWM3_EXT_SYNC 47
#define XBAR1_OUT_FLEXPWM2_EXT_CLK 48
#define XBAR1_OUT_FLEXPWM3_EXT_CLK 48
#define XBAR1_OUT_FLEXPWM4_EXT_CLK 48
#define XBAR1_OUT_FLEXPWM2_FAULT0 49
#define XBAR1_OUT_FLEXPWM2_FAULT1 50
#define XBAR1_OUT_FLEXPWM2_EXT_FORCE 51
#define XBAR1_OUT_FLEXPWM3_EXT_SYNC0 52
#define XBAR1_OUT_FLEXPWM3_EXT_SYNC1 53
#define XBAR1_OUT_FLEXPWM3_EXT_SYNC2 54
#define XBAR1_OUT_FLEXPWM3_EXT_SYNC3 55
#define XBAR1_OUT_FLEXPWM3_FAULT0 56
#define XBAR1_OUT_FLEXPWM3_FAULT1 57
#define XBAR1_OUT_FLEXPWM3_EXT_FORCE 58
#define XBAR1_OUT_FLEXPWM4_EXT_SYNC0 59
#define XBAR1_OUT_FLEXPWM4_EXT_SYNC1 60
#define XBAR1_OUT_FLEXPWM4_EXT_SYNC2 61
#define XBAR1_OUT_FLEXPWM4_EXT_SYNC3 62
#define XBAR1_OUT_FLEXPWM4_FAULT0 63
#define XBAR1_OUT_FLEXPWM4_FAULT1 64
#define XBAR1_OUT_FLEXPWM4_EXT_FORCE 65
#define XBAR1_OUT_ENC1_PHASEA_INPUT 66
#define XBAR1_OUT_ENC1_PHASEB_INPUT 67
#define XBAR1_OUT_ENC1_INDEX 68
#define XBAR1_OUT_ENC1_HOME 69
#define XBAR1_OUT_ENC1_TRIGGER 70
#define XBAR1_OUT_ENC2_PHASEA_INPUT 71
#define XBAR1_OUT_ENC2_PHASEB_INPUT 72
#define XBAR1_OUT_ENC2_INDEX 73
#define XBAR1_OUT_ENC2_HOME 74
#define XBAR1_OUT_ENC2_TRIGGER 75
#define XBAR1_OUT_ENC3_PHASEA_INPUT 76
#define XBAR1_OUT_ENC3_PHASEB_INPUT 77
#define XBAR1_OUT_ENC3_INDEX 78
#define XBAR1_OUT_ENC3_HOME 79
#define XBAR1_OUT_ENC3_TRIGGER 80
#define XBAR1_OUT_ENC4_PHASEA_INPUT 81
#define XBAR1_OUT_ENC4_PHASEB_INPUT 82
#define XBAR1_OUT_ENC4_INDEX 83
#define XBAR1_OUT_ENC4_HOME 84
#define XBAR1_OUT_ENC4_TRIGGER 85
#define XBAR1_OUT_QTIMER1_TIMER0 86
#define XBAR1_OUT_QTIMER1_TIMER1 87
#define XBAR1_OUT_QTIMER1_TIMER2 88
#define XBAR1_OUT_QTIMER1_TIMER3 89
#define XBAR1_OUT_QTIMER2_TIMER0 90
#define XBAR1_OUT_QTIMER2_TIMER1 91
#define XBAR1_OUT_QTIMER2_TIMER2 92
#define XBAR1_OUT_QTIMER2_TIMER3 93
#define XBAR1_OUT_QTIMER3_TIMER0 94
#define XBAR1_OUT_QTIMER3_TIMER1 95
#define XBAR1_OUT_QTIMER3_TIMER2 96
#define XBAR1_OUT_QTIMER3_TIMER3 97
#define XBAR1_OUT_QTIMER4_TIMER0 98
#define XBAR1_OUT_QTIMER4_TIMER1 99
#define XBAR1_OUT_QTIMER4_TIMER2 100
#define XBAR1_OUT_QTIMER4_TIMER3 101
#define XBAR1_OUT_EWM_EWM_IN 102
#define XBAR1_OUT_ADC_ETC_TRIG00 103
#define XBAR1_OUT_ADC_ETC_TRIG01 104
#define XBAR1_OUT_ADC_ETC_TRIG02 105
#define XBAR1_OUT_ADC_ETC_TRIG03 106
#define XBAR1_OUT_ADC_ETC_TRIG10 107
#define XBAR1_OUT_ADC_ETC_TRIG11 108
#define XBAR1_OUT_ADC_ETC_TRIG12 109
#define XBAR1_OUT_ADC_ETC_TRIG13 110
#define XBAR1_OUT_LPI2C1_TRG_INPUT 111
#define XBAR1_OUT_LPI2C2_TRG_INPUT 112
#define XBAR1_OUT_LPI2C3_TRG_INPUT 113
#define XBAR1_OUT_LPI2C4_TRG_INPUT 114
#define XBAR1_OUT_LPSPI1_TRG_INPUT 115
#define XBAR1_OUT_LPSPI2_TRG_INPUT 116
#define XBAR1_OUT_LPSPI3_TRG_INPUT 117
#define XBAR1_OUT_LPSPI4_TRG_INPUT 118
#define XBAR1_OUT_LPUART1_TRG_INPUT 119
#define XBAR1_OUT_LPUART2_TRG_INPUT 120
#define XBAR1_OUT_LPUART3_TRG_INPUT 121
#define XBAR1_OUT_LPUART4_TRG_INPUT 122
#define XBAR1_OUT_LPUART5_TRG_INPUT 123
#define XBAR1_OUT_LPUART6_TRG_INPUT 124
#define XBAR1_OUT_LPUART7_TRG_INPUT 125
#define XBAR1_OUT_LPUART8_TRG_INPUT 126
#define XBAR1_OUT_FLEXIO1_TRIGGER_IN0 127
#define XBAR1_OUT_FLEXIO1_TRIGGER_IN1 128
#define XBAR1_OUT_FLEXIO2_TRIGGER_IN0 129
#define XBAR1_OUT_FLEXIO2_TRIGGER_IN1 130
//#define XBAR1_OUT_Reserved 131

// XBAR2 Inputs and Outputs
#define XBAR2_IN_LOGIC_LOW 0
#define XBAR2_IN_LOGIC_HIGH 1
//#define XBAR2_IN_Reserved 2
//#define XBAR2_IN_Reserved 3
//#define XBAR2_IN_Reserved 4
//#define XBAR2_IN_Reserved 5
#define XBAR2_IN_ACMP1_OUT 6
#define XBAR2_IN_ACMP2_OUT 7
#define XBAR2_IN_ACMP3_OUT 8
#define XBAR2_IN_ACMP4_OUT 9
//#define XBAR2_IN_Reserved 10
//#define XBAR2_IN_Reserved 11
#define XBAR2_IN_QTIMER3_TIMER0 12
#define XBAR2_IN_QTIMER3_TIMER1 13
#define XBAR2_IN_QTIMER3_TIMER2 14
#define XBAR2_IN_QTIMER3_TIMER3 15
#define XBAR2_IN_QTIMER4_TIMER0 16
#define XBAR2_IN_QTIMER4_TIMER1 17
#define XBAR2_IN_QTIMER4_TIMER2 18
#define XBAR2_IN_QTIMER4_TIMER3 19
#define XBAR2_IN_FLEXPWM1_PWM1_OUT_TRIG0 20
#define XBAR2_IN_FLEXPWM1_PWM1_OUT_TRIG1 20
#define XBAR2_IN_FLEXPWM1_PWM2_OUT_TRIG0 21
#define XBAR2_IN_FLEXPWM1_PWM2_OUT_TRIG1 21
#define XBAR2_IN_FLEXPWM1_PWM3_OUT_TRIG0 22
#define XBAR2_IN_FLEXPWM1_PWM3_OUT_TRIG1 22
#define XBAR2_IN_FLEXPWM1_PWM4_OUT_TRIG0 23
#define XBAR2_IN_FLEXPWM1_PWM4_OUT_TRIG1 23
#define XBAR2_IN_FLEXPWM2_PWM1_OUT_TRIG0 24
#define XBAR2_IN_FLEXPWM2_PWM1_OUT_TRIG1 24
#define XBAR2_IN_FLEXPWM2_PWM2_OUT_TRIG0 25
#define XBAR2_IN_FLEXPWM2_PWM2_OUT_TRIG1 25
#define XBAR2_IN_FLEXPWM2_PWM3_OUT_TRIG0 26
#define XBAR2_IN_FLEXPWM2_PWM3_OUT_TRIG1 26
#define XBAR2_IN_FLEXPWM2_PWM4_OUT_TRIG0 27
#define XBAR2_IN_FLEXPWM2_PWM4_OUT_TRIG1 27
#define XBAR2_IN_FLEXPWM3_PWM1_OUT_TRIG0 28
#define XBAR2_IN_FLEXPWM3_PWM1_OUT_TRIG1 28
#define XBAR2_IN_FLEXPWM3_PWM2_OUT_TRIG0 29
#define XBAR2_IN_FLEXPWM3_PWM2_OUT_TRIG1 29
#define XBAR2_IN_FLEXPWM3_PWM3_OUT_TRIG0 30
#define XBAR2_IN_FLEXPWM3_PWM3_OUT_TRIG1 30
#define XBAR2_IN_FLEXPWM3_PWM4_OUT_TRIG0 31
#define XBAR2_IN_FLEXPWM3_PWM4_OUT_TRIG1 31
#define XBAR2_IN_FLEXPWM4_PWM1_OUT_TRIG0 32
#define XBAR2_IN_FLEXPWM4_PWM1_OUT_TRIG1 32
#define XBAR2_IN_FLEXPWM4_PWM2_OUT_TRIG0 33
#define XBAR2_IN_FLEXPWM4_PWM2_OUT_TRIG1 33
#define XBAR2_IN_FLEXPWM4_PWM3_OUT_TRIG0 34
#define XBAR2_IN_FLEXPWM4_PWM3_OUT_TRIG1 34
#define XBAR2_IN_FLEXPWM4_PWM4_OUT_TRIG0 35
#define XBAR2_IN_FLEXPWM4_PWM4_OUT_TRIG1 35
#define XBAR2_IN_PIT_TRIGGER0 36
#define XBAR2_IN_PIT_TRIGGER1 37
#define XBAR2_IN_ADC_ETC0_COCO0 38
#define XBAR2_IN_ADC_ETC0_COCO1 39
#define XBAR2_IN_ADC_ETC0_COCO2 40
#define XBAR2_IN_ADC_ETC0_COCO3 41
#define XBAR2_IN_ADC_ETC1_COCO0 42
#define XBAR2_IN_ADC_ETC1_COCO1 43
#define XBAR2_IN_ADC_ETC1_COCO2 44
#define XBAR2_IN_ADC_ETC1_COCO3 45
#define XBAR2_IN_ENC1_POS_MATCH 46
#define XBAR2_IN_ENC2_POS_MATCH 47
#define XBAR2_IN_ENC3_POS_MATCH 48
#define XBAR2_IN_ENC4_POS_MATCH 49
#define XBAR2_IN_DMA_DONE0 50
#define XBAR2_IN_DMA_DONE1 51
#define XBAR2_IN_DMA_DONE2 52
#define XBAR2_IN_DMA_DONE3 53
#define XBAR2_IN_DMA_DONE4 54
#define XBAR2_IN_DMA_DONE5 55
#define XBAR2_IN_DMA_DONE6 56
#define XBAR2_IN_DMA_DONE7 57

#define XBAR2_OUT_AOI1_IN00 0
#define XBAR2_OUT_AOI1_IN01 1
#define XBAR2_OUT_AOI1_IN02 2
#define XBAR2_OUT_AOI1_IN03 3
#define XBAR2_OUT_AOI1_IN04 4
#define XBAR2_OUT_AOI1_IN05 5
#define XBAR2_OUT_AOI1_IN06 6
#define XBAR2_OUT_AOI1_IN07 7
#define XBAR2_OUT_AOI1_IN08 8
#define XBAR2_OUT_AOI1_IN09 9
#define XBAR2_OUT_AOI1_IN10 10
#define XBAR2_OUT_AOI1_IN11 11
#define XBAR2_OUT_AOI1_IN12 12
#define XBAR2_OUT_AOI1_IN13 13
#define XBAR2_OUT_AOI1_IN14 14

// XBAR3 Inputs and Outputs
#define XBAR3_IN_LOGIC_LOW 0
#define XBAR3_IN_LOGIC_HIGH 1
//#define XBAR3_IN_Reserved 2
//#define XBAR3_IN_Reserved 3
//#define XBAR3_IN_Reserved 4
//#define XBAR3_IN_Reserved 5
#define XBAR3_IN_ACMP1_OUT 6
#define XBAR3_IN_ACMP2_OUT 7
#define XBAR3_IN_ACMP3_OUT 8
#define XBAR3_IN_ACMP4_OUT 9
//#define XBAR3_IN_Reserved 10
//#define XBAR3_IN_Reserved 11
#define XBAR3_IN_QTIMER3_TIMER0 12
#define XBAR3_IN_QTIMER3_TIMER1 13
#define XBAR3_IN_QTIMER3_TIMER2 14
#define XBAR3_IN_QTIMER3_TIMER3 15
#define XBAR3_IN_QTIMER4_TIMER0 16
#define XBAR3_IN_QTIMER4_TIMER1 17
#define XBAR3_IN_QTIMER4_TIMER2 18
#define XBAR3_IN_QTIMER4_TIMER3 19
#define XBAR3_IN_FLEXPWM1_PWM1_OUT_TRIG0 20
#define XBAR3_IN_FLEXPWM1_PWM2_OUT_TRIG0 21
#define XBAR3_IN_FLEXPWM1_PWM3_OUT_TRIG0 22
#define XBAR3_IN_FLEXPWM1_PWM4_OUT_TRIG0 23
#define XBAR3_IN_FLEXPWM2_PWM1_OUT_TRIG0 24
#define XBAR3_IN_FLEXPWM2_PWM2_OUT_TRIG0 25
#define XBAR3_IN_FLEXPWM2_PWM3_OUT_TRIG0 26
#define XBAR3_IN_FLEXPWM2_PWM4_OUT_TRIG0 27
#define XBAR3_IN_FLEXPWM3_PWM1_OUT_TRIG0 28
#define XBAR3_IN_FLEXPWM3_PWM2_OUT_TRIG0 29
#define XBAR3_IN_FLEXPWM3_PWM3_OUT_TRIG0 30
#define XBAR3_IN_FLEXPWM3_PWM4_OUT_TRIG0 31
#define XBAR3_IN_FLEXPWM4_PWM1_OUT_TRIG0 32
#define XBAR3_IN_FLEXPWM4_PWM2_OUT_TRIG0 33
#define XBAR3_IN_FLEXPWM4_PWM3_OUT_TRIG0 34
#define XBAR3_IN_FLEXPWM4_PWM4_OUT_TRIG0 35
#define XBAR3_IN_PIT_TRIGGER0 36
#define XBAR3_IN_PIT_TRIGGER1 37
#define XBAR3_IN_ADC_ETC0_COCO0 38
#define XBAR3_IN_ADC_ETC0_COCO1 39
#define XBAR3_IN_ADC_ETC0_COCO2 40
#define XBAR3_IN_ADC_ETC0_COCO3 41
#define XBAR3_IN_ADC_ETC1_COCO0 42
#define XBAR3_IN_ADC_ETC1_COCO1 43
#define XBAR3_IN_ADC_ETC1_COCO2 44
#define XBAR3_IN_ADC_ETC1_COCO3 45
#define XBAR3_IN_ENC1_POS_MATCH 46
#define XBAR3_IN_ENC2_POS_MATCH 47
#define XBAR3_IN_ENC3_POS_MATCH 48
#define XBAR3_IN_ENC4_POS_MATCH 49
#define XBAR3_IN_DMA_DONE0 50
#define XBAR3_IN_DMA_DONE1 51
#define XBAR3_IN_DMA_DONE2 52
#define XBAR3_IN_DMA_DONE3 53
#define XBAR3_IN_DMA_DONE4 54
#define XBAR3_IN_DMA_DONE5 55
#define XBAR3_IN_DMA_DONE6 56
#define XBAR3_IN_DMA_DONE7 57

#define XBAR3_OUT_AOI2_IN00 0
#define XBAR3_OUT_AOI2_IN01 1
#define XBAR3_OUT_AOI2_IN02 2
#define XBAR3_OUT_AOI2_IN03 3
#define XBAR3_OUT_AOI2_IN04 4
#define XBAR3_OUT_AOI2_IN05 5
#define XBAR3_OUT_AOI2_IN06 6
#define XBAR3_OUT_AOI2_IN07 7
#define XBAR3_OUT_AOI2_IN08 8
#define XBAR3_OUT_AOI2_IN09 9
#define XBAR3_OUT_AOI2_IN10 10
#define XBAR3_OUT_AOI2_IN11 11
#define XBAR3_OUT_AOI2_IN12 12
#define XBAR3_OUT_AOI2_IN13 13
#define XBAR3_OUT_AOI2_IN14 14
#define XBAR3_OUT_AOI2_IN15 15

EDIT: Added 2 and 3 since I was at it?
 
Last edited:
@KurtE

Sorry for the delay but its probably not a bad idea. As we get more into the pins configs it will save from having to copy it in the libs all the time.

Glad you added xbara2 and xbara3. So far haven't had need of them but you never know when.
 
@mjs513 - Not a problem, I have been distracted with other stuff today... Did not get much more done yet. Right now busy with three dog circus
 
@KurtE - I can only imagine :). Enjoy. Getting back to looking at CMP again. So probably will work on it tomorrow - getting late now.
 
@KurtE et.al.

Added the ADC compare piece of the puzzle. Only tested on case for comparing on one value. Still needs some work - since I think I messed upped what pins are on what adc in code. Need a break - been at it all morning - sleep and then more coffee.
 
@mjs513 - Still totally distracted :D Hopefully later today I will maybe have the opportunity to concentrate a little.

I probably should start off hacking something up, but I find myself wanting to generalize things. Like mapping Analog input to which XBAR input and output. Or how to allocate a PIT timer or how to allocate an ADC_ETC entry...
 
@mjs513 - I see that you added some stuff...

Note: I just pushed up a new branch DMA_SUPPORT -
Where I am trying get some of the examples to be able to build and then hopefully work like the ringBufferDMA test app.

I now created ADCL_Module objects which can do some sub set of stuff.

I created an ADC_Module_t structure which like the other I may try to add to imxrt_h file...

Again I have not tried running any of it yet, but if you are curious...
 
@KurtE
Yep added some stuff - basically the equivalent Compare functions for ACMP3 and ACMP4. Only tested a small piece of it. Think there is only one more easy piece to put in and that for adc offsets. Ran out of steam and started feeling bad again.

I looked at the branch and saw you put in the DMA stuff - and the module structure.

Will finish that off - should I start another branch for that change or just add it to the master or DMA branch.
 
@mjs513 - Hope you are doing well.

As for new branch/master/DMA.. hard to say, I started new branch as there are at least the two of us, and did not want to break everything yet.

I am trying to decide for example get us closer to the actual ADC library stuff, with the module stuff...

That is currently functions look like:
Code:
int ADCL::analogRead(uint8_t pin, int8_t adc_num)
{
  if (pin > sizeof(t4_pin_to_channel)) return ADC_ERROR_VALUE;
  // I believe all the calibration should be done by now
  uint8_t ch = t4_pin_to_channel[pin];
  switch (adc_num) {
    case 0:
      if (ch & 0x80) return ADC_ERROR_VALUE;  // does not handle this pin
      break;
    case 1:
      if (ch & 0x40) return ADC_ERROR_VALUE;  // does not handle this pin
      break;
    default:
      adc_num =  (ch & 0x80) ? 1 : 0;
  }
  if (adc_num == 0) {
    ADC1_HC0 = ch & 0x3f;
    while (!(ADC1_HS & ADC_HS_COCO0)) ; // wait
    return ADC1_R0;
  } else {
    ADC2_HC0 = ch & 0x3f;
    while (!(ADC2_HS & ADC_HS_COCO0)) ; // wait
    return ADC2_R0;
  }
}
But this can now be changed to:
Code:
int ADCL::analogRead(uint8_t pin, int8_t adc_num)
{
  return adc_num? _adc1.analogRead(pin) : _adc0.analogRead(pin);
}

Tried running DMA code, nothing happening... Now debugging
 
@KurtE
Though I had a problem with the compare code the after an hour or so realized I forgot to make a change in to use ACMP4 for the results. So code seems to be working.

As for the branches I will stick to the master to add the offset codes just to keep things straight - might be easier for you to combine later.

As for the module stuff - was confused on what he was doing - took a while.
 
@KurtE

Just added the last of the basic ADC functions, setOffset, to the base class.

Started looking at using the ADC_test sketch for some of this. But lost on checking errors. Not sure this is correct or will work. Advice.

Code:
    if (adc->adc0->fail_flag != ADC_ERROR::COMPARISON) {
        Serial.println("Comparison didn't fail.");
        adc->adc0->printError();
        pass_test = false;
    }
    adc->adc0->resetError();
 
@KurtE
Interesting thing I just found out during testing using on the CMP function.

Since ACMP is on pins 26 and 27 you have to change the resolution on the adc1 (ADC4) to match the what resolution you are using with the ADC library otherwise it defaults to what is the startup resolution if you try and do an analogRead of the ACMP pin. However, the comparison still works at what ever resolution you set in the sketch for the ADC#.

The second thing is if I try read the input pin to the ACMP, in this case A3, and print it, the sketch hangs after a couple of seconds.

Here is a test sketch you want to try:
Code:
#if !defined(__IMXRT1062__)  // Teensy 4.x
#error "Only runs on T4"
#endif
#include <ADCL_t4.h>

ADCL *adc;
uint8_t inp_pin = A3;
int8_t resolution = 12;

void setup() {
  // put your setup code here, to run once:
  while (!Serial && millis() < 5000) ;
  Serial.begin(115200);
  Serial.println("Quick and dirty T4 Analog compare stuff");

  adc = new ADCL;
  
  adc->setResolution(resolution, 0);
  //since cmp pins are on adc4 we have to change the resoultion
  adc->setResolution(resolution, 1);
  adc->enableCompare(ADCL::ACMP3, inp_pin);  //A3
  //analogReadRes(12);
  /*  Call it after changing the resolution
  *  Use with interrupts or poll conversion completion with isComplete()
  * 1.  compare true if the result is less than the value1. (greaterThan=0. mode0)
  * 2.  compare true if the result is greater than or equal to value1.
  * greaterThan=1. mode1)
  */
  adc->enableCompareValue(0, 4090, 1);

  /*  the range given by (lowerLimit, upperLimit),including (inclusive=1) the limits or not (inclusive=0).
  *
  *  1.  Value1 <= Value2, compare true if the result is less than value1 
  *  OR the result is Greater than value2. (inclusive = 0, insideRange = 0, mode2)
  *  2.  Value1 >  Value2, compare true if the result is less than value1 
  *  AND the result is Greater than value2. (inclusive = 0, insideRange = 1, mode3)
  *  3.  Value1 <= Value2, compare true if the result is greater than 
  *  OR equal to value1 AND the result is less than or equal to value2.   (inclusive = 1, insideRange = 1, mode4)
  *  4.  Value1 >  Value2, compare true if the result is greater than 
  *  OR equal to value1 OR the result is less than or equal to value2.   (inclusive = 1, insideRange = 0, mode5)
  */
  //adc->enableCompareRange(adc_num, lowerLimit, upperLimit, insideRange, inclusive);
}

void loop() {
  // put your main code here, to run repeatedly:
  int value;
  value = adc->getAdcCompareRes(ADCL::ACMP3);
  Serial.printf("Read from function: %d\n",value);   // COUT low bit
  value = adc->analogRead(ADCL::ACMP3);
  Serial.printf("Read Analog Cmp Pin: %d\n",value);  //analog cmp pin for ACMP3
  //Note: reading and printing the input pin seems to hang the sketch
  //value = adc->analogRead(inp_pin, 0);
  //Serial.printf("Read Input Pin: %d\n",value);  //input pin for example
  Serial.println();
  delay(100);
}
 
@mjs513 - I will merge in some of my stuff soon, to master. It has some of the stuff for adc->adc0 (or 1) but so far I have not added in all of the error stuff.

Made some progress on the DMA stuff, The DMA ISR function is being called... But it is unclear how this is supposed to work with the ring buffer DMA test. Things like, who clears the DMA Interrupt? Who stops the DMA from running...

Also see, another set of functionality I have not put in at all yet, the calls like startContinuous...

As for testing all of this stuff. So far manly doing with setting high or low or resistor divider. Probably look for a few pots. also might be good to write a quick and dirty sketch for a T3.x, that outputs to a DAC, for me maybe something like a sine wave centered at 1.6v at 60 hz, that you controls the amplitude ...

But first to put in other pieces.
 
@mjs513 - Hopefully I did not screw up everything, but I merged in the DMA branch...

Still not totally functional yet, but it also has a lot changes for housecleaning.

That is I moved most of the functionality out of ADCL_t4.cpp and into ADCL_module_t4.cpp...

This included moving a lot of the defines out of the ADCL_t4.h into -> module like it is in the main ADC library.

It now has the error functions/defines in module, although so far I don't think anything is actually setting those values.

Again keeping my fingers crossed!

EDIT: I know I semi-screwed up the main functions like adc->analogRead(pin);
Where you did not specify which pin...

Will take a pass through, right now adding the continuous functions as well.
 
Last edited:
@mjs513 - fixed (I hope) the problems I mentioned in the last message, like adc->analogRead(pin);
Will now check to see if valid pin on any ADC if so it will use the first valid one (i.e. if in my table does not have the 0x80 bit set it uses the logical adc0 (which in our case is ADC1_) else it uses adc1 (ADC2_)...

Added in the startContinuous functions, need to test...

Made some of the setting of values to be atomic (__disable_irq()... __enable_irq()

Updated some of the functions, that if you passed in invalid pin, sets the error state...
 
@KurtE

Sorry for the delay. I downloaded the latest and greatest and going to have to change the enabling of the compare function. Decided to add this to the code as a test:
Code:
  analogWriteFrequency(14, 60;
  analogWrite(14, 127);

Yes I know its a square wave but found that my thinking on enabling the compare was wrong. Was following the example but that is if you using the ACMP module, dummy that I am. Realized this morning so going to make a couple of changes and test based on the update repository. Then to go on to other things
 
I know there are probably easier ways and maybe I will play around some more with it, but as for test sketch, can always use Audio library. Example one I just setup to run on T3.5 (or 6)...

Code:
#include <Audio.h>

// GUItool: begin automatically generated code
AudioSynthWaveform       waveform1;      //xy=110,75
AudioOutputAnalogStereo  audioOutput;
AudioConnection          patchCord1(waveform1, 0, audioOutput, 0);
AudioConnection          patchCord2(waveform1, 0, audioOutput, 1);
// GUItool: end automatically generated code

void setup() {
  AudioMemory(15);
  audioOutput.analogReference(DEFAULT);
  waveform1.begin(WAVEFORM_SINE);
  waveform1.frequency(60);
  waveform1.amplitude(0.99);
}

void loop() {
}

Right now Dac1 and DAC2 are the same...

Could maybe setup two Waveforms, maybe hook up a couple of pots and then could change the amplitude...

Only thing with this is I forgot how slow it is on my machine to build with Audio library!
screenshot.jpg
 
Status
Not open for further replies.
Back
Top