1
1
#include " teensy4_mcu.h"
2
2
#include " ../../../drivers/hardware_specific/teensy/teensy4_mcu.h"
3
+ // #include "../../../common/lowpass_filter.h"
3
4
#include " ../../../common/foc_utils.h"
4
5
5
6
// if defined
6
7
// - Teensy 4.0
7
8
// - Teensy 4.1
8
9
#if defined(__arm__) && defined(CORE_TEENSY) && ( defined(__IMXRT1062__) || defined(ARDUINO_TEENSY40) || defined(ARDUINO_TEENSY41) || defined(ARDUINO_TEENSY_MICROMOD) )
9
10
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
+
29
13
14
+ // #define _BANDWIDTH_CS 10000.0f // [Hz] bandwidth for the current sense
30
15
volatile uint32_t val0, val1, val2;
31
16
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
+
32
21
void read_currents (uint32_t *a, uint32_t *b, uint32_t *c=nullptr ){
33
22
*a = val0;
34
23
*b = val1;
@@ -38,24 +27,32 @@ void read_currents(uint32_t *a, uint32_t*b, uint32_t *c=nullptr){
38
27
// interrupt service routine for the ADC_ETC0
39
28
// reading the ADC values and clearing the interrupt
40
29
void adcetc0_isr () {
30
+ #ifdef TEENSY4_ADC_INTERRUPT_DEBUG
41
31
digitalWrite (30 ,HIGH);
32
+ #endif
42
33
// page 3509 , section 66.5.1.3.3
43
34
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);
45
38
val1 = (ADC_ETC_TRIG0_RESULT_1_0 >> 16 ) & 4095 ;
46
- asm ( " dsb " );
39
+ # ifdef TEENSY4_ADC_INTERRUPT_DEBUG
47
40
digitalWrite (30 ,LOW);
41
+ #endif
48
42
}
49
43
50
44
51
45
void adcetc1_isr () {
52
- digitalWrite (30 ,HIGH);
46
+ #ifdef TEENSY4_ADC_INTERRUPT_DEBUG
47
+ digitalWrite (30 ,HIGH);
48
+ #endif
53
49
// page 3509 , section 66.5.1.3.3
54
50
ADC_ETC_DONE0_1_IRQ |= 1 << 16 ; // clear Done1 for trg0 at 16th bit
55
51
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
59
56
}
60
57
61
58
// function initializing the ADC2
@@ -65,7 +62,7 @@ void adc1_init(int pin1, int pin2, int pin3=NOT_SET) {
65
62
ADC1_CFG = ADC_CFG_OVWREN // Allow overwriting of the next converted Data onto the existing
66
63
| ADC_CFG_ADICLK (0 ) // input clock select - IPG clock
67
64
| 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 )
69
66
| ADC_CFG_ADSTS (0 ) // Sample period (ADC clocks) = 3 if ADLSMP=0b
70
67
| ADC_CFG_ADHSC // High speed operation
71
68
| ADC_CFG_ADTRG; // Hardware trigger selected
@@ -91,7 +88,7 @@ void adc2_init(){
91
88
ADC1_CFG = ADC_CFG_OVWREN // Allow overwriting of the next converted Data onto the existing
92
89
| ADC_CFG_ADICLK (0 ) // input clock select - IPG clock
93
90
| 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)
95
92
| ADC_CFG_ADSTS (0 ) // Sample period (ADC clocks) = 3 if ADLSMP=0b
96
93
| ADC_CFG_ADHSC // High speed operation
97
94
| ADC_CFG_ADTRG; // Hardware trigger selected
@@ -140,22 +137,6 @@ void adc_etc_init(int pin1, int pin2, int pin3=NOT_SET) {
140
137
}
141
138
}
142
139
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
- }
159
140
160
141
161
142
// function reading an ADC value and returning the read voltage
@@ -178,9 +159,10 @@ float _readADCVoltageLowSide(const int pinA, const void* cs_params){
178
159
// cannot do much but
179
160
void * _configureADCLowSide (const void * driver_params, const int pinA,const int pinB,const int pinC){
180
161
_UNUSED (driver_params);
181
- // _UNUSED(pinC);
182
162
163
+ #ifdef TEENSY4_ADC_INTERRUPT_DEBUG
183
164
pinMode (30 ,OUTPUT);
165
+ #endif
184
166
185
167
if ( _isset (pinA) ) pinMode (pinA, INPUT);
186
168
if ( _isset (pinB) ) pinMode (pinB, INPUT);
@@ -196,9 +178,6 @@ void* _configureADCLowSide(const void* driver_params, const int pinA,const int p
196
178
197
179
198
180
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 ]);
202
181
adc_etc_init (pins[0 ], pins[1 ], pins[2 ]);
203
182
204
183
xbar_init ();
@@ -223,12 +202,29 @@ void _driverSyncLowSide(void* driver_params, void* cs_params){
223
202
// allow theFlexPWM to trigger the ADC_ETC
224
203
xbar_connect ((uint32_t )xbar_trig_pwm, XBARA1_OUT_ADC_ETC_TRIG00); // FlexPWM to adc_etc
225
204
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
226
211
// 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);
228
213
// setup this val4 for interrupt on match for ADC sync
229
214
// this code assumes that the val4 is not used for anything else!
230
215
// 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
232
228
233
229
}
234
230
0 commit comments