-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpwm.cpp
More file actions
255 lines (218 loc) · 12.8 KB
/
pwm.cpp
File metadata and controls
255 lines (218 loc) · 12.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
/********************************************************************/
/* Description: GPTモジュールおよびPWM出力周りの設定 */
/* File: pwm.cpp */
/* Date: 2024/08/10 */
/* Author: Takashi YOSHIOKA */
/********************************************************************/
/********************************************************************/
/* ヘッダファイルのインクルード */
/********************************************************************/
#include <IRQManager.h>
#include "pwm.h"
#include "controlFunction.h"
#include "motorVar.h"
/********************************************************************/
/* 外部変数宣言 */
/********************************************************************/
extern motorVar_t motorVar;
/********************************************************************/
/* ソース内グローバルクラスの定義 */
/********************************************************************/
static GenericIrqCfg_t cfg;
/********************************************************************/
/* ソース内関数のプロトタイプ宣言 */
/********************************************************************/
static void MYISR_GPT5_INT(void);
/********************************************************************/
/* キャリア谷スキャン割り込み関数の外部宣言 */
/********************************************************************/
extern void carrier_valley_scan(void);
/********************************************************************/
/* Description: GPTモジュールおよびPWM出力周りの初期化 */
/* Function: setup_pwm_scan */
/* Arguments: なし */
/* Return value: なし */
/********************************************************************/
void setup_pwm_scan(void)
{
// disable module stop (POEG)
R_GPT_POEG0->POEGG = 0x00000018; // GPT Gr.A出力禁止, GTETRGAによる出力禁止許可, GTETRGA=Highレベルで出力禁止
R_GPT_POEG1->POEGG = 0x00000018; // GPT Gr.B出力禁止, 以降同上
// disable module stop (GPT)
R_GPT5->GTIOR_b.OAE = 0; // GTIOCA端子出力許可
R_GPT5->GTIOR_b.OBE = 0; // GTIOCB端子出力許可
R_GPT5->GTIOR_b.OADF = 0b10; // 出力禁止時0出力
R_GPT5->GTIOR_b.OBDF = 0b10; // 出力禁止時0出力
R_GPT6->GTIOR_b.OAE = 0;
R_GPT6->GTIOR_b.OBE = 0;
R_GPT6->GTIOR_b.OADF = 0b10;
R_GPT6->GTIOR_b.OBDF = 0b10;
R_GPT7->GTIOR_b.OAE = 0;
R_GPT7->GTIOR_b.OBE = 0;
R_GPT7->GTIOR_b.OADF = 0b10;
R_GPT7->GTIOR_b.OBDF = 0b10;
// set GPT timer mode
R_GPT5->GTCR_b.CST = 0; // stop timer count
R_GPT5->GTSSR_b.CSTRT = 1; // enable software count start
R_GPT5->GTCR_b.MD = 0b100; // TIMER_MODE_TRIANGLE_WAVE_SYMMETRIC_PWM
R_GPT5->GTCR_b.TPCS = 0b000; // PCLK/1
R_GPT6->GTCR_b.CST = 0;
R_GPT6->GTSSR_b.CSTRT = 1;
R_GPT6->GTCR_b.MD = 0b100;
R_GPT6->GTCR_b.TPCS = 0b000;
R_GPT7->GTCR_b.CST = 0;
R_GPT7->GTSSR_b.CSTRT = 1;
R_GPT7->GTCR_b.MD = 0b100;
R_GPT7->GTCR_b.TPCS = 0b000;
// set pwm freq. and timer count
R_GPT5->GTPR_b.GTPR = CARRIER_PERIOD_CYC;
R_GPT5->GTCNT_b.GTCNT = 0;
R_GPT6->GTPR_b.GTPR = CARRIER_PERIOD_CYC;
R_GPT6->GTCNT_b.GTCNT = 0;
R_GPT7->GTPR_b.GTPR = CARRIER_PERIOD_CYC;
R_GPT7->GTCNT_b.GTCNT = 0;
// set comparematch register and buffer register
R_GPT5->GTBER_b.CCRA = 0b01;
R_GPT5->GTCCR_b[0].GTCCR = INIT_DUTY_CYC + DEAD_TIME_CYC/2;
R_GPT5->GTCCR_b[2].GTCCR = INIT_DUTY_CYC + DEAD_TIME_CYC/2;
R_GPT6->GTBER_b.CCRA = 0b01;
R_GPT6->GTCCR_b[0].GTCCR = INIT_DUTY_CYC + DEAD_TIME_CYC/2;
R_GPT6->GTCCR_b[2].GTCCR = INIT_DUTY_CYC + DEAD_TIME_CYC/2;
R_GPT7->GTBER_b.CCRA = 0b01;
R_GPT7->GTCCR_b[0].GTCCR = INIT_DUTY_CYC + DEAD_TIME_CYC/2;
R_GPT7->GTCCR_b[2].GTCCR = INIT_DUTY_CYC + DEAD_TIME_CYC/2;
// set dead-time configuration
R_GPT5->GTDTCR_b.TDE = 1;
R_GPT5->GTDVU_b.GTDVU = DEAD_TIME_CYC;
R_GPT6->GTDTCR_b.TDE = 1;
R_GPT6->GTDVU_b.GTDVU = DEAD_TIME_CYC;
R_GPT7->GTDTCR_b.TDE = 1;
R_GPT7->GTDVU_b.GTDVU = DEAD_TIME_CYC;
// set port configuration
R_GPT5->GTIOR_b.OAHLD = 0; // カウント中:GTIOA設定に従う,カウント停止:OADFLT設定に従う
R_GPT5->GTIOR_b.OADFLT = 0; // カウント停止時0出力
R_GPT5->GTIOR_b.OBHLD = 0; //
R_GPT5->GTIOR_b.OBDFLT = 0; //
R_GPT6->GTIOR_b.OAHLD = 0; // カウント中:GTIOA設定に従う,カウント停止:OADFLT設定に従う
R_GPT6->GTIOR_b.OADFLT = 0; // カウント停止時0出力
R_GPT6->GTIOR_b.OBHLD = 0; //
R_GPT6->GTIOR_b.OBDFLT = 0; //
R_GPT7->GTIOR_b.OAHLD = 0; // カウント中:GTIOA設定に従う,カウント停止:OADFLT設定に従う
R_GPT7->GTIOR_b.OADFLT = 0; // カウント停止時0出力
R_GPT7->GTIOR_b.OBHLD = 0; //
R_GPT7->GTIOR_b.OBDFLT = 0; //
R_GPT5->GTIOR_b.GTIOA = 0b00111; // GTIOCA端子機能選択
R_GPT5->GTIOR_b.GTIOB = 0b11011; // GTIOCB端子機能選択
R_GPT5->GTIOR_b.OAE = 1; // GTIOCA端子出力許可
R_GPT5->GTIOR_b.OBE = 1; // GTIOCB端子出力許可
R_GPT6->GTIOR_b.GTIOA = 0b00111;
R_GPT6->GTIOR_b.GTIOB = 0b11011;
R_GPT6->GTIOR_b.OAE = 1;
R_GPT6->GTIOR_b.OBE = 1;
R_GPT7->GTIOR_b.GTIOA = 0b00111;
R_GPT7->GTIOR_b.GTIOB = 0b11011;
R_GPT7->GTIOR_b.OAE = 1;
R_GPT7->GTIOR_b.OBE = 1;
R_PMISC->PWPR_b.B0WI = 0;
R_PMISC->PWPR_b.PFSWE = 1;
R_PFS->PORT[1].PIN[0].PmnPFS_b.PMR = 0; // D19(P100)を汎用入出力に設定
R_PFS->PORT[1].PIN[1].PmnPFS_b.PMR = 0; // D18(P101)を汎用入出力に設定
R_PFS->PORT[1].PIN[0].PmnPFS_b.PDR = 0; // D19(P100)を入力端子として使用
R_PFS->PORT[1].PIN[1].PmnPFS_b.PDR = 0; // D18(P101)を入力端子として使用
R_PFS->PORT[1].PIN[0].PmnPFS_b.PSEL = 0x02; // D19(P100)をPOEGA端子として使用
R_PFS->PORT[1].PIN[1].PmnPFS_b.PSEL = 0x02; // D18(P101)をPOEGB端子として使用
R_PFS->PORT[1].PIN[0].PmnPFS_b.PMR = 1; // D19(P100)を周辺機能用の端子に設定
R_PFS->PORT[1].PIN[1].PmnPFS_b.PMR = 1; // D18(P101)を周辺機能用の端子に設定
R_PFS->PORT[6].PIN[9].PmnPFS_b.PMR = 0; // D74(P609)を汎用入出力に設定
R_PFS->PORT[6].PIN[10].PmnPFS_b.PMR = 0; // D73(P610)を汎用入出力に設定
R_PFS->PORT[6].PIN[9].PmnPFS_b.PDR = 1; // D74(P609)を出力端子として使用
R_PFS->PORT[6].PIN[10].PmnPFS_b.PDR = 1; // D73(P610)を出力端子として使用
R_PFS->PORT[6].PIN[9].PmnPFS_b.PSEL = 0x03; // D74(P609)をGPT端子として使用
R_PFS->PORT[6].PIN[10].PmnPFS_b.PSEL = 0x03;// D73(P610)をGPT端子として使用
R_PFS->PORT[6].PIN[9].PmnPFS_b.PMR = 1; // D74(P609)を周辺機能用の端子に設定
R_PFS->PORT[6].PIN[10].PmnPFS_b.PMR = 1; // D73(P610)を周辺機能用の端子に設定
R_PFS->PORT[6].PIN[1].PmnPFS_b.PMR = 0; // D70(P601)を汎用入出力に設定
R_PFS->PORT[6].PIN[0].PmnPFS_b.PMR = 0; // D69(P600)を汎用入出力に設定
R_PFS->PORT[6].PIN[1].PmnPFS_b.PDR = 1; // D70(P601)を出力端子として使用
R_PFS->PORT[6].PIN[0].PmnPFS_b.PDR = 1; // D69(P600)を出力端子として使用
R_PFS->PORT[6].PIN[1].PmnPFS_b.PSEL = 0x03; // D70(P601)をGPT端子として使用
R_PFS->PORT[6].PIN[0].PmnPFS_b.PSEL = 0x03; // D69(P600)をGPT端子として使用
R_PFS->PORT[6].PIN[1].PmnPFS_b.PMR = 1; // D70(P601)を周辺機能用の端子に設定
R_PFS->PORT[6].PIN[0].PmnPFS_b.PMR = 1; // D69(P600)を周辺機能用の端子に設定
R_PFS->PORT[6].PIN[3].PmnPFS_b.PMR = 0; // D72(P603)を汎用入出力に設定
R_PFS->PORT[6].PIN[2].PmnPFS_b.PMR = 0; // D71(P602)を汎用入出力に設定
R_PFS->PORT[6].PIN[3].PmnPFS_b.PDR = 1; // D72(P603)を出力端子として使用
R_PFS->PORT[6].PIN[2].PmnPFS_b.PDR = 1; // D71(P602)を出力端子として使用
R_PFS->PORT[6].PIN[3].PmnPFS_b.PSEL = 0x03; // D72(P603)をGPT端子として使用
R_PFS->PORT[6].PIN[2].PmnPFS_b.PSEL = 0x03; // D71(P602)をGPT端子として使用
R_PFS->PORT[6].PIN[3].PmnPFS_b.PMR = 1; // D72(P603)を周辺機能用の端子に設定
R_PFS->PORT[6].PIN[2].PmnPFS_b.PMR = 1; // D71(P602)を周辺機能用の端子に設定
R_PMISC->PWPR_b.PFSWE = 0;
R_PMISC->PWPR_b.B0WI = 1;
// 割り込み設定
cfg.irq = FSP_INVALID_VECTOR; // 良く分からんが固定値
cfg.ipl = 3; // 割り込み優先度 0(最高)-15(最低)
cfg.event = ELC_EVENT_GPT5_COUNTER_UNDERFLOW; // 割り込み要因としてGPT5アンダーフロー割り込みを指定
IRQManager::getInstance().addGenericInterrupt(cfg, MYISR_GPT5_INT); // 割り込み要因のセット
// timer count start
R_GPT_POEG0->POEGG_b.PIDF = 0; // なぜか出力禁止要求フラグが立っているのでクリアしておく
R_GPT_POEG1->POEGG_b.PIDF = 0;
R_GPT5->GTSTR = 0xE0; // GPT5-7カウントスタート (0x 1110 0000 = 0xE0)
}
/********************************************************************/
/* Description: 割り込みサービスルーチン(GPT5アンダーフロー割り込み) */
/* Function: MYISR_GPT5_INT */
/* Arguments: なし */
/* Return value: なし */
/********************************************************************/
void MYISR_GPT5_INT(void)
{
carrier_valley_scan(); // キャリア谷スキャン割り込み処理
R_ICU->IELSR_b[cfg.irq].IR = 0; // 割り込み要因フラグのクリア
}
/********************************************************************/
/* Description: デューティに応じたPWMパターンを出力 (三角波比較) */
/* Function: set_pwm_duty */
/* Arguments: VuRefArg - U相電圧指令 (-VDC/2[V] ~ VDC/2[V]) */
/* VvRefArg - V相電圧指令 (-VDC/2[V] ~ VDC/2[V]) */
/* VwRefArg - W相電圧指令 (-VDC/2[V] ~ VDC/2[V]) */
/* Return value: なし */
/********************************************************************/
void set_pwm_duty(float VuRefArg, float VvRefArg, float VwRefArg)
{
int32_t duty_cyc_u, duty_cyc_v, duty_cyc_w;
duty_cyc_u = (int32_t)(CARRIER_PERIOD_CYC*(0.5f - VuRefArg/motorVar.Vdc) + DEAD_TIME_CYC/2); // デッドタイム補償は暫定措置 (実際には相電流の向きに依存)
duty_cyc_v = (int32_t)(CARRIER_PERIOD_CYC*(0.5f - VvRefArg/motorVar.Vdc) + DEAD_TIME_CYC/2);
duty_cyc_w = (int32_t)(CARRIER_PERIOD_CYC*(0.5f - VwRefArg/motorVar.Vdc) + DEAD_TIME_CYC/2);
if ( duty_cyc_u > (CARRIER_PERIOD_CYC - 1) ) duty_cyc_u = CARRIER_PERIOD_CYC - 1; // こちらはMAX値でも問題ないが下限に合わせて1だけ狭める
if ( duty_cyc_u < 1 ) duty_cyc_u = 1; // 0だとパルスがバグるので下限を1に
if ( duty_cyc_v > (CARRIER_PERIOD_CYC - 1) ) duty_cyc_v = CARRIER_PERIOD_CYC - 1;
if ( duty_cyc_v < 1 ) duty_cyc_v = 1;
if ( duty_cyc_w > (CARRIER_PERIOD_CYC - 1) ) duty_cyc_w = CARRIER_PERIOD_CYC - 1;
if ( duty_cyc_w < 1 ) duty_cyc_w = 1;
R_GPT5->GTCCR_b[2].GTCCR = (uint16_t)(duty_cyc_u);
R_GPT6->GTCCR_b[2].GTCCR = (uint16_t)(duty_cyc_v);
R_GPT7->GTCCR_b[2].GTCCR = (uint16_t)(duty_cyc_w);
}
/********************************************************************/
/* Description: PWM出力の許可 */
/* Function: enable_pwm_out */
/* Arguments: なし */
/* Return value: なし */
/********************************************************************/
void enable_pwm_out(void)
{
R_GPT_POEG0->POEGG_b.SSF = 0; // GPTポート出力許可
R_GPT_POEG1->POEGG_b.SSF = 0;
}
/********************************************************************/
/* Description: PWM出力の禁止 */
/* Function: disable_pwm_out */
/* Arguments: なし */
/* Return value: なし */
/********************************************************************/
void disable_pwm_out(void)
{
R_GPT_POEG0->POEGG_b.SSF = 1; // GPTポート出力禁止
R_GPT_POEG1->POEGG_b.SSF = 1;
}