11#include " teensy4_mcu.h"
22#include " ../../../drivers/hardware_specific/teensy/teensy4_mcu.h"
3+ // #include "../../../common/lowpass_filter.h"
34#include " ../../../common/foc_utils.h"
45
56// if defined
67// - Teensy 4.0
78// - Teensy 4.1
89#if defined(__arm__) && defined(CORE_TEENSY) && ( defined(__IMXRT1062__) || defined(ARDUINO_TEENSY40) || defined(ARDUINO_TEENSY41) || defined(ARDUINO_TEENSY_MICROMOD) )
910
10- // function finding the TRIG event given the flexpwm timer and the submodule
11- // returning -1 if the submodule is not valid or no trigger is available
12- // allowing flexpwm1-4 and submodule 0-3
13- //
14- // the flags are defined in the imxrt.h file
15- // https://github.com/PaulStoffregen/cores/blob/dd6aa8419ee173a0a6593eab669fbff54ed85f48/teensy4/imxrt.h#L9662
16- int flexpwm_submodule_to_trig (IMXRT_FLEXPWM_t* flexpwm, int submodule){
17- if (submodule <0 && submodule > 3 ) return -1 ;
18- if (flexpwm == &IMXRT_FLEXPWM1){
19- return XBARA1_IN_FLEXPWM1_PWM1_OUT_TRIG0 + submodule;
20- }else if (flexpwm == &IMXRT_FLEXPWM2){
21- return XBARA1_IN_FLEXPWM2_PWM1_OUT_TRIG0 + submodule;
22- }else if (flexpwm == &IMXRT_FLEXPWM3){
23- return XBARA1_IN_FLEXPWM3_PWM1_OUT_TRIG0 + submodule;
24- }else if (flexpwm == &IMXRT_FLEXPWM4){
25- return XBARA1_IN_FLEXPWM4_PWM1_OUT_TRIG0 + submodule;
26- }
27- return -1 ;
28- }
11+ // #define TEENSY4_ADC_INTERRUPT_DEBUG
12+
2913
14+ // #define _BANDWIDTH_CS 10000.0f // [Hz] bandwidth for the current sense
3015volatile uint32_t val0, val1, val2;
3116
17+ // LowPassFilter lp1 = LowPassFilter(1.0/_BANDWIDTH_CS);
18+ // LowPassFilter lp2 = LowPassFilter(1.0/_BANDWIDTH_CS);
19+ // LowPassFilter lp3 = LowPassFilter(1.0/_BANDWIDTH_CS);
20+
3221void read_currents (uint32_t *a, uint32_t *b, uint32_t *c=nullptr ){
3322 *a = val0;
3423 *b = val1;
@@ -38,24 +27,32 @@ void read_currents(uint32_t *a, uint32_t*b, uint32_t *c=nullptr){
3827// interrupt service routine for the ADC_ETC0
3928// reading the ADC values and clearing the interrupt
4029void adcetc0_isr () {
30+ #ifdef TEENSY4_ADC_INTERRUPT_DEBUG
4131 digitalWrite (30 ,HIGH);
32+ #endif
4233 // page 3509 , section 66.5.1.3.3
4334 ADC_ETC_DONE0_1_IRQ |= 1 ; // clear Done0 for trg0 at 1st bit
44- val0 = ADC_ETC_TRIG0_RESULT_1_0 & 4095 ;
35+ // val0 = lp1(ADC_ETC_TRIG0_RESULT_1_0 & 4095);
36+ val0 = (ADC_ETC_TRIG0_RESULT_1_0 & 4095 );
37+ // val1 = lp2((ADC_ETC_TRIG0_RESULT_1_0 >> 16) & 4095);
4538 val1 = (ADC_ETC_TRIG0_RESULT_1_0 >> 16 ) & 4095 ;
46- asm ( " dsb " );
39+ # ifdef TEENSY4_ADC_INTERRUPT_DEBUG
4740 digitalWrite (30 ,LOW);
41+ #endif
4842}
4943
5044
5145void adcetc1_isr () {
52- digitalWrite (30 ,HIGH);
46+ #ifdef TEENSY4_ADC_INTERRUPT_DEBUG
47+ digitalWrite (30 ,HIGH);
48+ #endif
5349 // page 3509 , section 66.5.1.3.3
5450 ADC_ETC_DONE0_1_IRQ |= 1 << 16 ; // clear Done1 for trg0 at 16th bit
5551 val2 = ADC_ETC_TRIG0_RESULT_3_2 & 4095 ;
56- // val2 = (ADC_ETC_TRIG0_RESULT_3_2 >> 16) & 4095;
57- asm (" dsb" );
58- digitalWrite (30 ,LOW);
52+ // val2 = lp3( ADC_ETC_TRIG0_RESULT_3_2 & 4095);
53+ #ifdef TEENSY4_ADC_INTERRUPT_DEBUG
54+ digitalWrite (30 ,LOW);
55+ #endif
5956}
6057
6158// function initializing the ADC2
@@ -65,7 +62,7 @@ void adc1_init(int pin1, int pin2, int pin3=NOT_SET) {
6562 ADC1_CFG = ADC_CFG_OVWREN // Allow overwriting of the next converted Data onto the existing
6663 | ADC_CFG_ADICLK (0 ) // input clock select - IPG clock
6764 | ADC_CFG_MODE (2 ) // 12-bit conversion 0 8-bit conversion 1 10-bit conversion 2 12-bit conversion
68- | ADC_CFG_ADIV (1 ) // Input clock / 2 (0 for /1, 1 for /2 and 2 for / 4)
65+ | ADC_CFG_ADIV (2 ) // Input clock / 2 (0 for /1, 1 for /2 and 2 for / 4) (1 is faster and maybe with some filtering could provide better results but 2 for now )
6966 | ADC_CFG_ADSTS (0 ) // Sample period (ADC clocks) = 3 if ADLSMP=0b
7067 | ADC_CFG_ADHSC // High speed operation
7168 | ADC_CFG_ADTRG; // Hardware trigger selected
@@ -91,7 +88,7 @@ void adc2_init(){
9188 ADC1_CFG = ADC_CFG_OVWREN // Allow overwriting of the next converted Data onto the existing
9289 | ADC_CFG_ADICLK (0 ) // input clock select - IPG clock
9390 | ADC_CFG_MODE (2 ) // 12-bit conversion 0 8-bit conversion 1 10-bit conversion 2 12-bit conversion
94- | ADC_CFG_ADIV (1 ) // Input clock / 2 (0 for /1, 1 for /2 and 2 for / 4)
91+ | ADC_CFG_ADIV (2 ) // Input clock / 2 (0 for /1, 1 for /2 and 2 for / 4)
9592 | ADC_CFG_ADSTS (0 ) // Sample period (ADC clocks) = 3 if ADLSMP=0b
9693 | ADC_CFG_ADHSC // High speed operation
9794 | ADC_CFG_ADTRG; // Hardware trigger selected
@@ -140,22 +137,6 @@ void adc_etc_init(int pin1, int pin2, int pin3=NOT_SET) {
140137 }
141138}
142139
143- void xbar_connect (unsigned int input, unsigned int output)
144- {
145- if (input >= 88 ) return ;
146- if (output >= 132 ) return ;
147- volatile uint16_t *xbar = &XBARA1_SEL0 + (output / 2 );
148- uint16_t val = *xbar;
149- if (!(output & 1 )) {
150- val = (val & 0xFF00 ) | input;
151- } else {
152- val = (val & 0x00FF ) | (input << 8 );
153- }
154- *xbar = val;
155- }
156- void xbar_init () {
157- CCM_CCGR2 |= CCM_CCGR2_XBAR1 (CCM_CCGR_ON); // turn clock on for xbara1
158- }
159140
160141
161142// function reading an ADC value and returning the read voltage
@@ -178,9 +159,10 @@ float _readADCVoltageLowSide(const int pinA, const void* cs_params){
178159// cannot do much but
179160void * _configureADCLowSide (const void * driver_params, const int pinA,const int pinB,const int pinC){
180161 _UNUSED (driver_params);
181- // _UNUSED(pinC);
182162
163+ #ifdef TEENSY4_ADC_INTERRUPT_DEBUG
183164 pinMode (30 ,OUTPUT);
165+ #endif
184166
185167 if ( _isset (pinA) ) pinMode (pinA, INPUT);
186168 if ( _isset (pinB) ) pinMode (pinB, INPUT);
@@ -196,9 +178,6 @@ void* _configureADCLowSide(const void* driver_params, const int pinA,const int p
196178
197179
198180 adc1_init (pins[0 ], pins[1 ], pins[2 ]);
199- SIMPLEFOC_DEBUG (" pins: " ,pins[0 ]);
200- SIMPLEFOC_DEBUG (" pins: " ,pins[1 ]);
201- SIMPLEFOC_DEBUG (" pins: " ,pins[2 ]);
202181 adc_etc_init (pins[0 ], pins[1 ], pins[2 ]);
203182
204183 xbar_init ();
@@ -223,12 +202,29 @@ void _driverSyncLowSide(void* driver_params, void* cs_params){
223202 // allow theFlexPWM to trigger the ADC_ETC
224203 xbar_connect ((uint32_t )xbar_trig_pwm, XBARA1_OUT_ADC_ETC_TRIG00); // FlexPWM to adc_etc
225204
205+ // setup the ADC_ETC trigger to be triggered by the FlexPWM channel 1 (val1)
206+ // This val1 interrupt on match is in the center of the PWM
207+ flexpwm->SM [submodule].TCTRL = FLEXPWM_SMTCTRL_OUT_TRIG_EN (1 <<1 );
208+
209+
210+ // if needed the interrupt can be moved to some other point in the PWM cycle by using an addional val register example: VAL4
226211 // setup the ADC_ETC trigger to be triggered by the FlexPWM channel 4 (val4)
227- flexpwm->SM [submodule].TCTRL = FLEXPWM_SMTCTRL_OUT_TRIG_EN (1 <<4 );
212+ // flexpwm->SM[submodule].TCTRL = FLEXPWM_SMTCTRL_OUT_TRIG_EN(1<<4);
228213 // setup this val4 for interrupt on match for ADC sync
229214 // this code assumes that the val4 is not used for anything else!
230215 // reading two ADC takes about 2.5us. So put the interrupt 2.5us befor the center
231- flexpwm->SM [submodule].VAL4 = -int (2.5e-6 *par->pwm_frequency *flexpwm->SM [submodule].VAL1 ) ; // 2.5us before center
216+ // flexpwm->SM[submodule].VAL4 = int(flexpwm->SM[submodule].VAL1*(1.0f - 2.5e-6*par->pwm_frequency)) ; // 2.5us before center
217+
218+
219+ #ifdef TEENSY4_ADC_INTERRUPT_DEBUG
220+ // pin 4 observes out trigger line for 'scope
221+ xbar_connect (xbar_trig_pwm, XBARA1_OUT_IOMUX_XBAR_INOUT08) ;
222+ IOMUXC_GPR_GPR6 |= IOMUXC_GPR_GPR6_IOMUXC_XBAR_DIR_SEL_8 ; // select output mode for INOUT8
223+ // Select alt 3 for EMC_06 (XBAR), rather than original 5 (GPIO)
224+ CORE_PIN4_CONFIG = 3 ; // shorthand for IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_06 = 3 ;
225+ // turn up drive & speed as very short pulse
226+ IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_06 = IOMUXC_PAD_DSE (7 ) | IOMUXC_PAD_SPEED (3 ) | IOMUXC_PAD_SRE ;
227+ #endif
232228
233229}
234230
0 commit comments