1
+ #include " teensy_mcu.h"
2
+
3
+ // if defined
4
+ // - Teensy 3.0 MK20DX128
5
+ // - Teensy 3.1/3.2 MK20DX256
6
+ // - Teensy 3.5 MK20DX128
7
+ // - Teensy LC MKL26Z64
8
+ // - Teensy 3.5 MK64FX512
9
+ // - Teensy 3.6 MK66FX1M0
10
+ #if defined(__arm__) && defined(CORE_TEENSY) && (defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MKL26Z64__) || defined(__MK64FX512__) || defined(__MK66FX1M0__))
11
+
12
+
13
+ // pin definition from https://github.com/PaulStoffregen/cores/blob/286511f3ec849a6c9e0ec8b73ad6a2fada52e44c/teensy3/pins_teensy.c
14
+ #if defined(__MK20DX128__)
15
+ #define FTM0_CH0_PIN 22
16
+ #define FTM0_CH1_PIN 23
17
+ #define FTM0_CH2_PIN 9
18
+ #define FTM0_CH3_PIN 10
19
+ #define FTM0_CH4_PIN 6
20
+ #define FTM0_CH5_PIN 20
21
+ #define FTM0_CH6_PIN 21
22
+ #define FTM0_CH7_PIN 5
23
+ #define FTM1_CH0_PIN 3
24
+ #define FTM1_CH1_PIN 4
25
+ #elif defined(__MK20DX256__)
26
+ #define FTM0_CH0_PIN 22
27
+ #define FTM0_CH1_PIN 23
28
+ #define FTM0_CH2_PIN 9
29
+ #define FTM0_CH3_PIN 10
30
+ #define FTM0_CH4_PIN 6
31
+ #define FTM0_CH5_PIN 20
32
+ #define FTM0_CH6_PIN 21
33
+ #define FTM0_CH7_PIN 5
34
+ #define FTM1_CH0_PIN 3
35
+ #define FTM1_CH1_PIN 4
36
+ #define FTM2_CH0_PIN 32
37
+ #define FTM2_CH1_PIN 25
38
+ #elif defined(__MKL26Z64__)
39
+ #define FTM0_CH0_PIN 22
40
+ #define FTM0_CH1_PIN 23
41
+ #define FTM0_CH2_PIN 9
42
+ #define FTM0_CH3_PIN 10
43
+ #define FTM0_CH4_PIN 6
44
+ #define FTM0_CH5_PIN 20
45
+ #define FTM1_CH0_PIN 16
46
+ #define FTM1_CH1_PIN 17
47
+ #define FTM2_CH0_PIN 3
48
+ #define FTM2_CH1_PIN 4
49
+ #elif defined(__MK64FX512__)
50
+ #define FTM0_CH0_PIN 22
51
+ #define FTM0_CH1_PIN 23
52
+ #define FTM0_CH2_PIN 9
53
+ #define FTM0_CH3_PIN 10
54
+ #define FTM0_CH4_PIN 6
55
+ #define FTM0_CH5_PIN 20
56
+ #define FTM0_CH6_PIN 21
57
+ #define FTM0_CH7_PIN 5
58
+ #define FTM1_CH0_PIN 3
59
+ #define FTM1_CH1_PIN 4
60
+ #define FTM2_CH0_PIN 29
61
+ #define FTM2_CH1_PIN 30
62
+ #define FTM3_CH0_PIN 2
63
+ #define FTM3_CH1_PIN 14
64
+ #define FTM3_CH2_PIN 7
65
+ #define FTM3_CH3_PIN 8
66
+ #define FTM3_CH4_PIN 35
67
+ #define FTM3_CH5_PIN 36
68
+ #define FTM3_CH6_PIN 37
69
+ #define FTM3_CH7_PIN 38
70
+ #elif defined(__MK66FX1M0__)
71
+ #define FTM0_CH0_PIN 22
72
+ #define FTM0_CH1_PIN 23
73
+ #define FTM0_CH2_PIN 9
74
+ #define FTM0_CH3_PIN 10
75
+ #define FTM0_CH4_PIN 6
76
+ #define FTM0_CH5_PIN 20
77
+ #define FTM0_CH6_PIN 21
78
+ #define FTM0_CH7_PIN 5
79
+ #define FTM1_CH0_PIN 3
80
+ #define FTM1_CH1_PIN 4
81
+ #define FTM2_CH0_PIN 29
82
+ #define FTM2_CH1_PIN 30
83
+ #define FTM3_CH0_PIN 2
84
+ #define FTM3_CH1_PIN 14
85
+ #define FTM3_CH2_PIN 7
86
+ #define FTM3_CH3_PIN 8
87
+ #define FTM3_CH4_PIN 35
88
+ #define FTM3_CH5_PIN 36
89
+ #define FTM3_CH6_PIN 37
90
+ #define FTM3_CH7_PIN 38
91
+ #define TPM1_CH0_PIN 16
92
+ #define TPM1_CH1_PIN 17
93
+ #endif
94
+
95
+ int _findTimer ( const int Ah, const int Al, const int Bh, const int Bl, const int Ch, const int Cl){
96
+
97
+ if ((Ah == FTM0_CH0_PIN && Al == FTM0_CH1_PIN) ||
98
+ (Ah == FTM0_CH2_PIN && Al == FTM0_CH3_PIN) ||
99
+ (Ah == FTM0_CH4_PIN && Al == FTM0_CH5_PIN) ){
100
+ if ((Bh == FTM0_CH0_PIN && Bl == FTM0_CH1_PIN) ||
101
+ (Bh == FTM0_CH2_PIN && Bl == FTM0_CH3_PIN) ||
102
+ (Bh == FTM0_CH4_PIN && Bl == FTM0_CH5_PIN) ){
103
+ if ((Ch == FTM0_CH0_PIN && Cl == FTM0_CH1_PIN) ||
104
+ (Ch == FTM0_CH2_PIN && Cl == FTM0_CH3_PIN) ||
105
+ (Ch == FTM0_CH4_PIN && Cl == FTM0_CH5_PIN) ){
106
+ // timer FTM0
107
+ return 0 ;
108
+ }
109
+ }
110
+ }
111
+
112
+ #ifdef FTM3_SC // if the board has FTM3 timer
113
+ if ((Ah == FTM3_CH0_PIN && Al == FTM3_CH1_PIN) ||
114
+ (Ah == FTM3_CH2_PIN && Al == FTM3_CH3_PIN) ||
115
+ (Ah == FTM3_CH4_PIN && Al == FTM3_CH5_PIN) ){
116
+ if ((Bh == FTM3_CH0_PIN && Bl == FTM3_CH1_PIN) ||
117
+ (Bh == FTM3_CH2_PIN && Bl == FTM3_CH3_PIN) ||
118
+ (Bh == FTM3_CH4_PIN && Bl == FTM3_CH5_PIN) ){
119
+ if ((Ch == FTM3_CH0_PIN && Cl == FTM3_CH1_PIN) ||
120
+ (Ch == FTM3_CH2_PIN && Cl == FTM3_CH3_PIN) ||
121
+ (Ch == FTM3_CH4_PIN && Cl == FTM3_CH5_PIN) ){
122
+ // timer FTM3
123
+ return 3 ;
124
+ }
125
+ }
126
+ }
127
+ #endif
128
+
129
+ return -1 ;
130
+
131
+ }
132
+
133
+
134
+ // function setting the high pwm frequency to the supplied pins
135
+ // - Stepper motor - 6PWM setting
136
+ // - hardware specific
137
+ void * _configure6PWM (long pwm_frequency, float dead_zone, const int pinA_h, const int pinA_l, const int pinB_h, const int pinB_l, const int pinC_h, const int pinC_l) {
138
+ if (!pwm_frequency || !_isset (pwm_frequency) ) pwm_frequency = _PWM_FREQUENCY; // default frequency 25khz
139
+ else pwm_frequency = _constrain (pwm_frequency, 0 , _PWM_FREQUENCY_MAX); // constrain to 50kHz max
140
+ unsigned long pwm_freq = 4 *pwm_frequency; // center-aligned pwm has 4 times lower freq
141
+ _setHighFrequency (pwm_freq, pinA_h);
142
+ _setHighFrequency (pwm_freq, pinA_l);
143
+ _setHighFrequency (pwm_freq, pinB_h);
144
+ _setHighFrequency (pwm_freq, pinB_l);
145
+ _setHighFrequency (pwm_freq, pinC_h);
146
+ _setHighFrequency (pwm_freq, pinC_l);
147
+
148
+ GenericDriverParams* params = new GenericDriverParams {
149
+ .pins = { pinA_h,pinA_l, pinB_h,pinB_l, pinC_h, pinC_l },
150
+ .pwm_frequency = pwm_frequency
151
+ };
152
+
153
+
154
+ int timer = _findTimer (pinA_h,pinA_l,pinB_h,pinB_l,pinC_h,pinC_l);
155
+ if (timer<0 ) return SIMPLEFOC_DRIVER_INIT_FAILED;
156
+
157
+
158
+
159
+ // find the best combination of prescalers and counter value
160
+ double dead_time = dead_zone/pwm_freq;
161
+ int prescaler = 1 ; // initial prescaler (1,4 or 16)
162
+ double count = 1 ; // inital count (1 - 63)
163
+ for (; prescaler<=16 ; prescaler*=4 ){
164
+ count = dead_time*((double )F_CPU)/((double )prescaler);
165
+ if (count < 64 ) break ; // found the solution
166
+ }
167
+ count = _constrain (count, 1 , 63 );
168
+
169
+ // configure the timer
170
+ if (timer==0 ){
171
+ // Configure FTM0
172
+ // // inverting and deadtime insertion for FTM1
173
+ FTM0_COMBINE = 0x00121212 ; // 0x2 - complemetary mode, 0x1 - dead timer insertion enabled
174
+
175
+ // Deadtime config
176
+ FTM0_DEADTIME = (int )count; // set counter - 1-63
177
+ FTM0_DEADTIME |= ((prescaler>1 ) << 7 ) | ((prescaler>4 ) << 6 ); // set prescaler (0b01 - 1, 0b10 - 4, 0b11 - 16)
178
+
179
+ // configure center aligned PWM
180
+ FTM0_SC = 0x00000028 ; // 0x2 - center-alignment, 0x8 - fixed clock freq
181
+ }else if (timer==3 ){
182
+ // Configure FTM3
183
+ // inverting and deadtime insertion for FTM1
184
+ FTM3_COMBINE = 0x00121212 ; // 0x2 - complemetary mode, 0x1 - dead timer insertion enabled
185
+
186
+ // Deadtime config
187
+ FTM3_DEADTIME = (int )count; // set counter - 1-63
188
+ FTM3_DEADTIME |= ((prescaler>1 ) << 7 ) | ((prescaler>4 ) << 6 ); // set prescaler (0b01 - 1, 0b10 - 4, 0b11 - 16)
189
+
190
+ // configure center aligned PWM
191
+ FTM3_SC = 0x00000028 ; // 0x2 - center-alignment, 0x8 - fixed clock freq
192
+ }
193
+
194
+ return params;
195
+ }
196
+
197
+
198
+
199
+ // function setting the pwm duty cycle to the hardware
200
+ // - Stepper motor - 6PWM setting
201
+ // - hardware specific
202
+ void _writeDutyCycle6PWM (float dc_a, float dc_b, float dc_c, void * params){
203
+ // transform duty cycle from [0,1] to [0,255]
204
+ // phase A
205
+ analogWrite (((GenericDriverParams*)params)->pins [0 ], 255 .0f *dc_a);
206
+ analogWrite (((GenericDriverParams*)params)->pins [1 ], 255 .0f *dc_a);
207
+
208
+ // phase B
209
+ analogWrite (((GenericDriverParams*)params)->pins [2 ], 255 .0f *dc_b);
210
+ analogWrite (((GenericDriverParams*)params)->pins [3 ], 255 .0f *dc_b);
211
+
212
+ // phase C
213
+ analogWrite (((GenericDriverParams*)params)->pins [4 ], 255 .0f *dc_c);
214
+ analogWrite (((GenericDriverParams*)params)->pins [5 ], 255 .0f *dc_c);
215
+ }
216
+ #endif
0 commit comments