SimpleFOClibrary 2.4.0
Loading...
Searching...
No Matches
renesas.cpp
Go to the documentation of this file.
1
2#include "./renesas.h"
3
4#if defined(ARDUINO_UNOR4_WIFI) || defined(ARDUINO_UNOR4_MINIMA)
5
6
7#pragma message("")
8#pragma message("SimpleFOC: compiling for Arduino/Renesas (UNO R4)")
9#pragma message("")
10
11
12
14#include "FspTimer.h"
15
16#define GPT_OPEN (0x00475054ULL)
17
18/*
19 We use the GPT timers, there are 2 channels (32 bit) + 6 channels (16 bit)
20 Each channel has 2 outputs (GTIOCAx and GTIOCBx) which can be complimentary.
21
22 So each timer channel can handle one half-bridge, using either a single (3-PWM) or
23 two complimentary PWM signals (6-PWM).
24
25 For 1-PWM through 4-PWM, we need as many channels as PWM signals, and we can use
26 either output A or B of the timer (we can set the polarity) - but not both.
27
28 For 6-PWM we need 3 channels, and use both outputs A and B of each channel, then
29 we can do hardware dead-time.
30 Or we can use seperate channels for high and low side, with software dead-time.
31 Each phase can be either hardware (1 channel) or software (2 channels) dead-time
32 individually, they don't all have to be one or the other.
33
34 Selected channels can be started together, so we can keep the phases in sync for
35 low-side current sensing and software 6-PWM.
36
37 The event system should permit low side current sensing without needing interrupts,
38 but this will be handled by the current sense driver.
39
40 Supported:
41 - arbitrary PWM frequencies between 1Hz (minimum we can set with our integer based API)
42 and around 48kHz (more would be possible but the range will be low)
43 - PWM range at 24kHz (default) is 1000
44 - PWM range at 48kHz is 500
45 - polarity setting is supported, in all modes
46 - phase state setting is supported, in 3-PWM, 6-PWM hardware dead-time and 6-PWM software dead-time
47
48 TODOs:
49 - change setDutyCycle to use register access for speed
50 - add event system support for low-side current sensing
51 - perhaps add support to reserve timers used also in
52 Arduino Pwm.h code, for compatibility with analogWrite()
53 - check if there is a better way for phase-state setting
54 */
55
56
57// track which channels are used
58bool channel_used[GPT_HOWMANY] = { false };
59
60
61struct RenesasTimerConfig {
62 timer_cfg_t timer_cfg;
63 gpt_instance_ctrl_t ctrl;
64 gpt_extended_cfg_t ext_cfg;
65 gpt_extended_pwm_cfg_t pwm_cfg;
66 gpt_io_pin_t duty_pin;
67};
68
69struct ClockDivAndRange {
70 timer_source_div_t clk_div;
71 uint32_t range;
72};
73
74ClockDivAndRange getClockDivAndRange(uint32_t pwm_frequency, uint8_t timer_channel) {
75 ClockDivAndRange result;
76 uint32_t max_count = (timer_channel < GTP32_HOWMANY)? 4294967295 : 65535;
77 uint32_t freq_hz = R_FSP_SystemClockHzGet(FSP_PRIV_CLOCK_PCLKD);
78 float range = (float) freq_hz / ((float) pwm_frequency * 2.0f);
79 if(range / 1.0 < max_count) {
80 result.range = (uint32_t) (range / 1.0);
81 result.clk_div = TIMER_SOURCE_DIV_1;
82 }
83 else if (range / 2.0 < max_count) {
84 result.range = (uint32_t) (range / 2.0);
85 result.clk_div = TIMER_SOURCE_DIV_2;
86 }
87 else if(range / 4.0 < max_count) {
88 result.range = (uint32_t) (range / 4.0);
89 result.clk_div = TIMER_SOURCE_DIV_4;
90 }
91 else if(range / 8.0 < max_count) {
92 result.range = (uint32_t) (range / 8.0 );
93 result.clk_div = TIMER_SOURCE_DIV_8;
94 }
95 else if(range / 16.0 < max_count) {
96 result.range = (uint32_t) (range / 16.0 );
97 result.clk_div = TIMER_SOURCE_DIV_16;
98 }
99 else if (range / 32.0 < max_count) {
100 result.range = (uint32_t) (range / 32.0 );
101 result.clk_div = TIMER_SOURCE_DIV_32;
102 }
103 else if(range / 64.0 < max_count) {
104 result.range = (uint32_t) (range / 64.0 );
105 result.clk_div = TIMER_SOURCE_DIV_64;
106 }
107 else if(range / 128.0 < max_count) {
108 result.range = (uint32_t) (range / 128.0 );
109 result.clk_div = TIMER_SOURCE_DIV_128;
110 }
111 else if(range / 256.0 < max_count) {
112 result.range = (uint32_t) (range / 256.0 );
113 result.clk_div = TIMER_SOURCE_DIV_256;
114 }
115 else if(range / 512.0 < max_count) {
116 result.range = (uint32_t) (range / 512.0 );
117 result.clk_div = TIMER_SOURCE_DIV_512;
118 }
119 else if(range / 1024.0 < max_count) {
120 result.range = (uint32_t) (range / 1024.0 );
121 result.clk_div = TIMER_SOURCE_DIV_1024;
122 }
123 else {
124 #if !defined(SIMPLEFOC_DISABLE_DEBUG)
125 SimpleFOCDebug::println("DRV: PWM frequency too low");
126 #endif
127 }
128 return result;
129};
130
131
132bool configureTimerPin(RenesasHardwareDriverParams* params, uint8_t index, bool active_high, bool complementary = false, bool complementary_active_high = true) {
133 uint8_t pin = params->pins[index];
134 uint8_t pin_C;
135 std::array<uint16_t, 3> pinCfgs = getPinCfgs(pin, PIN_CFG_REQ_PWM);
136 std::array<uint16_t, 3> pinCfgs_C;
137 if(pinCfgs[0] == 0) {
138 SIMPLEFOC_DEBUG("DRV: no PWM on pin ", pin);
139 return false;
140 }
141 if (IS_PIN_AGT_PWM(pinCfgs[0])) {
142 SIMPLEFOC_DEBUG("DRV: AGT timer not supported");
143 return false;
144 }
145 // get the timer channel
146 uint8_t timer_channel = GET_CHANNEL(pinCfgs[0]);
147 // check its not used
148 if (channel_used[timer_channel]) {
149 SIMPLEFOC_DEBUG("DRV: channel in use: ", timer_channel);
150 return false;
151 }
152
153 if (complementary) {
154 pin_C = params->pins[index+1];
155 pinCfgs_C = getPinCfgs(pin_C, PIN_CFG_REQ_PWM);
156 if(pinCfgs_C[0] == 0) {
157 SIMPLEFOC_DEBUG("DRV: no PWM on pin ", pin_C);
158 return false;
159 }
160 if (IS_PIN_AGT_PWM(pinCfgs_C[0]) || GET_CHANNEL(pinCfgs_C[0])!=timer_channel) {
161 SIMPLEFOC_DEBUG("DRV: comp. channel different");
162 return false;
163 }
164 }
165 TimerPWMChannel_t pwm_output = IS_PWM_ON_A(pinCfgs[0]) ? CHANNEL_A : CHANNEL_B;
166 if (complementary) {
167 TimerPWMChannel_t pwm_output_C = IS_PWM_ON_A(pinCfgs_C[0]) ? CHANNEL_A : CHANNEL_B;
168 if (pwm_output_C != CHANNEL_A || pwm_output != CHANNEL_B) {
169 SIMPLEFOC_DEBUG("DRV: output A/B mismatch");
170 return false;
171 }
172 }
173
174 // configure GPIO pin
175 fsp_err_t err = R_IOPORT_PinCfg(&g_ioport_ctrl, g_pin_cfg[pin].pin, (uint32_t) (IOPORT_CFG_PERIPHERAL_PIN | IOPORT_PERIPHERAL_GPT1));
176 if ((err == FSP_SUCCESS) && complementary)
177 err = R_IOPORT_PinCfg(&g_ioport_ctrl, g_pin_cfg[pin_C].pin, (uint32_t) (IOPORT_CFG_PERIPHERAL_PIN | IOPORT_PERIPHERAL_GPT1));
178 if (err != FSP_SUCCESS) {
179 SIMPLEFOC_DEBUG("DRV: pin config failed");
180 return false;
181 }
182
183
184 // configure timer channel - frequency / top value
185 ClockDivAndRange timings = getClockDivAndRange(params->pwm_frequency, timer_channel);
186 #if defined(SIMPLEFOC_RENESAS_DEBUG) && !defined(SIMPLEFOC_DISABLE_DEBUG)
187 SimpleFOCDebug::println("---PWM Config---");
188 SimpleFOCDebug::println("DRV: pwm pin: ", pin);
189 if (complementary)
190 SimpleFOCDebug::println("DRV: compl. pin: ", pin_C);
191 SimpleFOCDebug::println("DRV: pwm channel: ", timer_channel);
192 SimpleFOCDebug::print("DRV: pwm A/B: "); SimpleFOCDebug::println(complementary?"A+B":((pwm_output==CHANNEL_A)?"A":"B"));
193 SimpleFOCDebug::println("DRV: pwm freq: ", (int)params->pwm_frequency);
194 SimpleFOCDebug::println("DRV: pwm range: ", (int)timings.range);
195 SimpleFOCDebug::println("DRV: pwm clkdiv: ", timings.clk_div);
196 #endif
197
198 RenesasTimerConfig* t = new RenesasTimerConfig();
199 // configure timer channel - count mode
200 t->timer_cfg.channel = timer_channel;
201 t->timer_cfg.mode = TIMER_MODE_TRIANGLE_WAVE_SYMMETRIC_PWM;
202 t->timer_cfg.source_div = timings.clk_div;
203 t->timer_cfg.period_counts = timings.range;
204 t->timer_cfg.duty_cycle_counts = 0;
205 t->timer_cfg.p_callback = nullptr;
206 t->timer_cfg.p_context = nullptr;
207 t->timer_cfg.p_extend = &(t->ext_cfg);
208 t->timer_cfg.cycle_end_ipl = BSP_IRQ_DISABLED;
209 t->timer_cfg.cycle_end_irq = FSP_INVALID_VECTOR;
210
211 t->ext_cfg.p_pwm_cfg = &(t->pwm_cfg);
212 t->ext_cfg.capture_a_ipl = BSP_IRQ_DISABLED;
213 t->ext_cfg.capture_a_irq = FSP_INVALID_VECTOR;
214 t->ext_cfg.capture_b_ipl = BSP_IRQ_DISABLED;
215 t->ext_cfg.capture_b_irq = FSP_INVALID_VECTOR;
216 t->pwm_cfg.trough_ipl = BSP_IRQ_DISABLED;
217 t->pwm_cfg.trough_irq = FSP_INVALID_VECTOR;
218 t->pwm_cfg.poeg_link = GPT_POEG_LINK_POEG0;
219 t->pwm_cfg.output_disable = GPT_OUTPUT_DISABLE_NONE;
220 t->pwm_cfg.adc_trigger = GPT_ADC_TRIGGER_NONE;
221 t->pwm_cfg.dead_time_count_up = 0;
222 t->pwm_cfg.dead_time_count_down = 0;
223 t->pwm_cfg.adc_a_compare_match = 0;
224 t->pwm_cfg.adc_b_compare_match = 0;
225 t->pwm_cfg.interrupt_skip_source = GPT_INTERRUPT_SKIP_SOURCE_NONE;
226 t->pwm_cfg.interrupt_skip_count = GPT_INTERRUPT_SKIP_COUNT_0;
227 t->pwm_cfg.interrupt_skip_adc = GPT_INTERRUPT_SKIP_ADC_NONE;
228 t->pwm_cfg.gtioca_disable_setting = GPT_GTIOC_DISABLE_PROHIBITED;
229 t->pwm_cfg.gtiocb_disable_setting = GPT_GTIOC_DISABLE_PROHIBITED;
230 // configure dead-time if both outputs are used
231 if (complementary) {
232 uint32_t dt = params->dead_zone * timings.range;
233 t->pwm_cfg.dead_time_count_up = dt;
234 t->pwm_cfg.dead_time_count_down = dt;
235 }
236
237 // configure timer channel - outputs and polarity
238 t->ext_cfg.gtior_setting.gtior = 0L;
239 if (!complementary) {
240 if(pwm_output == CHANNEL_A) {
241 t->duty_pin = GPT_IO_PIN_GTIOCA;
242 t->ext_cfg.gtioca.output_enabled = true;
243 t->ext_cfg.gtiocb.output_enabled = false;
244 t->ext_cfg.gtior_setting.gtior_b.gtioa = 0x03 | (active_high ? 0x00 : 0x10);
245 t->ext_cfg.gtior_setting.gtior_b.oadflt = active_high ? 0x00 : 0x01;
246 // t->ext_cfg.gtior_setting.gtior_b.oahld = 0x0;
247 // t->ext_cfg.gtior_setting.gtior_b.oadf = 0x0;
248 // t->ext_cfg.gtior_setting.gtior_b.nfaen = 0x0;
249 }
250 else {
251 t->duty_pin = GPT_IO_PIN_GTIOCB;
252 t->ext_cfg.gtiocb.output_enabled = true;
253 t->ext_cfg.gtioca.output_enabled = false;
254 t->ext_cfg.gtior_setting.gtior_b.gtiob = 0x03 | (active_high ? 0x00 : 0x10);
255 t->ext_cfg.gtior_setting.gtior_b.obdflt = active_high ? 0x00 : 0x01;
256 }
257 }
258 else {
259 t->duty_pin = GPT_IO_PIN_GTIOCA_AND_GTIOCB;
260 t->ext_cfg.gtioca.output_enabled = true;
261 t->ext_cfg.gtiocb.output_enabled = true;
262 t->ext_cfg.gtior_setting.gtior_b.gtioa = 0x03 | (!complementary_active_high ? 0x00 : 0x10);
263 t->ext_cfg.gtior_setting.gtior_b.oadflt = !complementary_active_high ? 0x00 : 0x01;
264 t->ext_cfg.gtior_setting.gtior_b.gtiob = 0x03 | (active_high ? 0x00 : 0x10);
265 t->ext_cfg.gtior_setting.gtior_b.obdflt = active_high ? 0x00 : 0x01;
266 }
267 memset(&(t->ctrl), 0, sizeof(gpt_instance_ctrl_t));
268 err = R_GPT_Open(&(t->ctrl),&(t->timer_cfg));
269 if ((err != FSP_ERR_ALREADY_OPEN) && (err != FSP_SUCCESS)) {
270 SIMPLEFOC_DEBUG("DRV: open failed");
271 return false;
272 }
273 if (err == FSP_ERR_ALREADY_OPEN) {
274 #if !defined(SIMPLEFOC_DISABLE_DEBUG)
275 SimpleFOCDebug::println("DRV: timer already open");
276 #endif
277 return false;
278 }
279
280 err = R_GPT_PeriodSet(&(t->ctrl), t->timer_cfg.period_counts);
281 if (err != FSP_SUCCESS) {
282 SIMPLEFOC_DEBUG("DRV: period set failed");
283 return false;
284 }
285 err = R_GPT_OutputEnable(&(t->ctrl), t->duty_pin);
286 if (err != FSP_SUCCESS) {
287 SIMPLEFOC_DEBUG("DRV: pin enable failed");
288 return false;
289 }
290
291 channel_used[timer_channel] = true;
292 params->timer_config[index] = t;
293 params->channels[index] = timer_channel;
294 if (complementary) {
295 params->timer_config[index+1] = t;
296 params->channels[index+1] = timer_channel;
297 }
298
299 return true;
300}
301
302
303// start the timer channels for the motor, synchronously
304bool startTimerChannels(RenesasHardwareDriverParams* params, int num_channels) {
305 uint32_t mask = 0;
306 for (int i = 0; i < num_channels; i++) {
307 // RenesasTimerConfig* t = params->timer_config[i];
308 // if (R_GPT_Start(&(t->ctrl)) != FSP_SUCCESS) {
309 // SIMPLEFOC_DEBUG("DRV: timer start failed");
310 // return false;
311 // }
312 mask |= (1 << params->channels[i]);
313#if defined(SIMPLEFOC_RENESAS_DEBUG) && !defined(SIMPLEFOC_DISABLE_DEBUG)
314 SimpleFOCDebug::println("DRV: starting timer: ", params->channels[i]);
315#endif
316 }
317 params->timer_config[0]->ctrl.p_reg->GTSTR |= mask;
318 #if defined(SIMPLEFOC_RENESAS_DEBUG) && !defined(SIMPLEFOC_DISABLE_DEBUG)
319 SimpleFOCDebug::println("DRV: timers started");
320 #endif
321 return true;
322}
323
324
325// check if the given pins are on the same timer channel
326bool isHardware6Pwm(const int pin1, const int pin2) {
327 std::array<uint16_t, 3> pinCfgs1 = getPinCfgs(pin1, PIN_CFG_REQ_PWM);
328 std::array<uint16_t, 3> pinCfgs2 = getPinCfgs(pin2, PIN_CFG_REQ_PWM);
329 if(pinCfgs1[0] == 0 || pinCfgs2[0] == 0)
330 return false;
331 if (IS_PIN_AGT_PWM(pinCfgs1[0]) || IS_PIN_AGT_PWM(pinCfgs2[0]))
332 return false;
333 uint8_t timer_channel1 = GET_CHANNEL(pinCfgs1[0]);
334 uint8_t timer_channel2 = GET_CHANNEL(pinCfgs2[0]);
335 return timer_channel1==timer_channel2;
336}
337
338
339
340void* _configure1PWM(long pwm_frequency, const int pinA) {
341 RenesasHardwareDriverParams* params = new RenesasHardwareDriverParams;
342 params->pins[0] = pinA;
343 params->pwm_frequency = (pwm_frequency==NOT_SET)?RENESAS_DEFAULT_PWM_FREQUENCY:pwm_frequency;
344 bool success = true;
345 success = configureTimerPin(params, 0, SIMPLEFOC_PWM_ACTIVE_HIGH);
346 if (success)
347 success = startTimerChannels(params, 1);
348 if (!success)
350 return params;
351}
352
353
354void* _configure2PWM(long pwm_frequency,const int pinA, const int pinB) {
355 RenesasHardwareDriverParams* params = new RenesasHardwareDriverParams;
356 params->pins[0] = pinA; params->pins[1] = pinB;
357 params->pwm_frequency = (pwm_frequency==NOT_SET)?RENESAS_DEFAULT_PWM_FREQUENCY:pwm_frequency;
358 bool success = true;
359 success = configureTimerPin(params, 0, SIMPLEFOC_PWM_ACTIVE_HIGH);
360 success &= configureTimerPin(params, 1, SIMPLEFOC_PWM_ACTIVE_HIGH);
361 if (!success)
362 success &= startTimerChannels(params, 2);
363 if (!success)
365 return params;
366}
367
368
369void* _configure3PWM(long pwm_frequency,const int pinA, const int pinB, const int pinC) {
370 RenesasHardwareDriverParams* params = new RenesasHardwareDriverParams;
371 params->pins[0] = pinA; params->pins[1] = pinB; params->pins[2] = pinC;
372 params->pwm_frequency = (pwm_frequency==NOT_SET)?RENESAS_DEFAULT_PWM_FREQUENCY:pwm_frequency;
373 bool success = true;
374 success = configureTimerPin(params, 0, SIMPLEFOC_PWM_ACTIVE_HIGH);
375 success &= configureTimerPin(params, 1, SIMPLEFOC_PWM_ACTIVE_HIGH);
376 success &= configureTimerPin(params, 2, SIMPLEFOC_PWM_ACTIVE_HIGH);
377 if (success)
378 success = startTimerChannels(params, 3);
379 if (!success)
381 return params;
382}
383
384
385void* _configure4PWM(long pwm_frequency, const int pin1A, const int pin1B, const int pin2A, const int pin2B) {
386 RenesasHardwareDriverParams* params = new RenesasHardwareDriverParams;
387 params->pins[0] = pin1A; params->pins[1] = pin1B; params->pins[2] = pin2A; params->pins[3] = pin2B;
388 params->pwm_frequency = (pwm_frequency==NOT_SET)?RENESAS_DEFAULT_PWM_FREQUENCY:pwm_frequency;
389 bool success = true;
390 success = configureTimerPin(params, 0, SIMPLEFOC_PWM_ACTIVE_HIGH);
391 success &= configureTimerPin(params, 1, SIMPLEFOC_PWM_ACTIVE_HIGH);
392 success &= configureTimerPin(params, 2, SIMPLEFOC_PWM_ACTIVE_HIGH);
393 success &= configureTimerPin(params, 3, SIMPLEFOC_PWM_ACTIVE_HIGH);
394 if (success)
395 success = startTimerChannels(params, 4);
396 if (!success)
398 return params;
399}
400
401
402void* _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){
403 RenesasHardwareDriverParams* params = new RenesasHardwareDriverParams;
404 params->pins[0] = pinA_h; params->pins[1] = pinA_l; params->pins[2] = pinB_h; params->pins[3] = pinB_l; params->pins[4] = pinC_h; params->pins[5] = pinC_l;
405 params->pwm_frequency = (pwm_frequency==NOT_SET)?RENESAS_DEFAULT_PWM_FREQUENCY:pwm_frequency;
406 params->dead_zone = (dead_zone==NOT_SET)?RENESAS_DEFAULT_DEAD_ZONE:dead_zone;
407
408 bool success = true;
409 if (isHardware6Pwm(pinA_h, pinA_l))
410 success &= configureTimerPin(params, 0, SIMPLEFOC_PWM_HIGHSIDE_ACTIVE_HIGH, true, SIMPLEFOC_PWM_LOWSIDE_ACTIVE_HIGH);
411 else {
412 success &= configureTimerPin(params, 0, SIMPLEFOC_PWM_HIGHSIDE_ACTIVE_HIGH);
413 success &= configureTimerPin(params, 1, !SIMPLEFOC_PWM_LOWSIDE_ACTIVE_HIGH); // reverse polarity on low side gives desired active high/low behaviour
414 }
415
416 if (isHardware6Pwm(pinB_h, pinB_l))
417 success &= configureTimerPin(params, 2, SIMPLEFOC_PWM_HIGHSIDE_ACTIVE_HIGH, true, SIMPLEFOC_PWM_LOWSIDE_ACTIVE_HIGH);
418 else {
419 success &= configureTimerPin(params, 2, SIMPLEFOC_PWM_HIGHSIDE_ACTIVE_HIGH);
420 success &= configureTimerPin(params, 3, !SIMPLEFOC_PWM_LOWSIDE_ACTIVE_HIGH);
421 }
422
423 if (isHardware6Pwm(pinC_h, pinC_l))
424 success &= configureTimerPin(params, 4, SIMPLEFOC_PWM_HIGHSIDE_ACTIVE_HIGH, true, SIMPLEFOC_PWM_LOWSIDE_ACTIVE_HIGH);
425 else {
426 success &= configureTimerPin(params, 4, SIMPLEFOC_PWM_HIGHSIDE_ACTIVE_HIGH);
427 success &= configureTimerPin(params, 5, !SIMPLEFOC_PWM_LOWSIDE_ACTIVE_HIGH);
428 }
429
430 if (success)
431 success = startTimerChannels(params, 6);
432 if (!success)
434 return params;
435}
436
437
438
439
440void _writeDutyCycle1PWM(float dc_a, void* params){
441 RenesasTimerConfig* t = ((RenesasHardwareDriverParams*)params)->timer_config[0];
442 uint32_t duty_cycle_counts = (uint32_t)(dc_a * (float)(t->timer_cfg.period_counts));
443 if (R_GPT_DutyCycleSet(&(t->ctrl), duty_cycle_counts, t->duty_pin) != FSP_SUCCESS) {
444 // error
445 }
446}
447
448
449void _writeDutyCycle2PWM(float dc_a, float dc_b, void* params){
450 RenesasTimerConfig* t = ((RenesasHardwareDriverParams*)params)->timer_config[0];
451 uint32_t duty_cycle_counts = (uint32_t)(dc_a * (float)(t->timer_cfg.period_counts));
452 if (R_GPT_DutyCycleSet(&(t->ctrl), duty_cycle_counts, t->duty_pin) != FSP_SUCCESS) {
453 // error
454 }
455 t = ((RenesasHardwareDriverParams*)params)->timer_config[1];
456 duty_cycle_counts = (uint32_t)(dc_b * (float)(t->timer_cfg.period_counts));
457 if (R_GPT_DutyCycleSet(&(t->ctrl), duty_cycle_counts, t->duty_pin) != FSP_SUCCESS) {
458 // error
459 }
460}
461
462
463void _writeDutyCycle3PWM(float dc_a, float dc_b, float dc_c, void* params){
464 RenesasTimerConfig* t = ((RenesasHardwareDriverParams*)params)->timer_config[0];
465 uint32_t duty_cycle_counts = (uint32_t)(dc_a * (float)(t->timer_cfg.period_counts));
466 if (R_GPT_DutyCycleSet(&(t->ctrl), duty_cycle_counts, t->duty_pin) != FSP_SUCCESS) {
467 // error
468 }
469 t = ((RenesasHardwareDriverParams*)params)->timer_config[1];
470 duty_cycle_counts = (uint32_t)(dc_b * (float)(t->timer_cfg.period_counts));
471 if (R_GPT_DutyCycleSet(&(t->ctrl), duty_cycle_counts, t->duty_pin) != FSP_SUCCESS) {
472 // error
473 }
474 t = ((RenesasHardwareDriverParams*)params)->timer_config[2];
475 duty_cycle_counts = (uint32_t)(dc_c * (float)(t->timer_cfg.period_counts));
476 if (R_GPT_DutyCycleSet(&(t->ctrl), duty_cycle_counts, t->duty_pin) != FSP_SUCCESS) {
477 // error
478 }
479}
480
481
482void _writeDutyCycle4PWM(float dc_1a, float dc_1b, float dc_2a, float dc_2b, void* params){
483 RenesasTimerConfig* t = ((RenesasHardwareDriverParams*)params)->timer_config[0];
484 uint32_t duty_cycle_counts = (uint32_t)(dc_1a * (float)(t->timer_cfg.period_counts));
485 if (R_GPT_DutyCycleSet(&(t->ctrl), duty_cycle_counts, t->duty_pin) != FSP_SUCCESS) {
486 // error
487 }
488 t = ((RenesasHardwareDriverParams*)params)->timer_config[1];
489 duty_cycle_counts = (uint32_t)(dc_1b * (float)(t->timer_cfg.period_counts));
490 if (R_GPT_DutyCycleSet(&(t->ctrl), duty_cycle_counts, t->duty_pin) != FSP_SUCCESS) {
491 // error
492 }
493 t = ((RenesasHardwareDriverParams*)params)->timer_config[2];
494 duty_cycle_counts = (uint32_t)(dc_2a * (float)(t->timer_cfg.period_counts));
495 if (R_GPT_DutyCycleSet(&(t->ctrl), duty_cycle_counts, t->duty_pin) != FSP_SUCCESS) {
496 // error
497 }
498 t = ((RenesasHardwareDriverParams*)params)->timer_config[3];
499 duty_cycle_counts = (uint32_t)(dc_2b * (float)(t->timer_cfg.period_counts));
500 if (R_GPT_DutyCycleSet(&(t->ctrl), duty_cycle_counts, t->duty_pin) != FSP_SUCCESS) {
501 // error
502 }
503}
504
505
506
507void _setSinglePhaseState(RenesasTimerConfig* hi, RenesasTimerConfig* lo, PhaseState state) {
508 gpt_gtior_setting_t gtior;
509 gtior.gtior = hi->ctrl.p_reg->GTIOR;
510 bool on = (state==PHASE_ON) || (state==PHASE_HI);
511
512 if (hi->duty_pin == GPT_IO_PIN_GTIOCA_AND_GTIOCB) {
513 bool ch = false;
514 if (gtior.gtior_b.obe != on) {
515 gtior.gtior_b.obe = on;
516 ch = true;
517 } // B is high side
518 on = (state==PHASE_ON) || (state==PHASE_LO);
519 if (gtior.gtior_b.oae != on) {
520 gtior.gtior_b.oae = on;
521 ch = true;
522 }
523 if (ch)
524 hi->ctrl.p_reg->GTIOR = gtior.gtior;
525 return;
526 }
527
528 if (hi->duty_pin == GPT_IO_PIN_GTIOCA) {
529 if (gtior.gtior_b.oae != on) {
530 gtior.gtior_b.oae = on;
531 hi->ctrl.p_reg->GTIOR = gtior.gtior;
532 }
533 }
534 else if (hi->duty_pin == GPT_IO_PIN_GTIOCB) {
535 if (gtior.gtior_b.obe != on) {
536 gtior.gtior_b.obe = on;
537 hi->ctrl.p_reg->GTIOR = gtior.gtior;
538 }
539 }
540
541 gtior.gtior = lo->ctrl.p_reg->GTIOR;
542 on = (state==PHASE_ON) || (state==PHASE_LO);
543 if (lo->duty_pin == GPT_IO_PIN_GTIOCA) {
544 if (gtior.gtior_b.oae != on) {
545 gtior.gtior_b.oae = on;
546 lo->ctrl.p_reg->GTIOR = gtior.gtior;
547 }
548 }
549 else if (lo->duty_pin == GPT_IO_PIN_GTIOCB) {
550 if (gtior.gtior_b.obe != on) {
551 gtior.gtior_b.obe = on;
552 lo->ctrl.p_reg->GTIOR = gtior.gtior;
553 }
554 }
555
556}
557
558
559void _writeDutyCycle6PWM(float dc_a, float dc_b, float dc_c, PhaseState *phase_state, void* params){
560 RenesasTimerConfig* t = ((RenesasHardwareDriverParams*)params)->timer_config[0];
561 RenesasTimerConfig* t1 = ((RenesasHardwareDriverParams*)params)->timer_config[1];
562 uint32_t dt = (uint32_t)(((RenesasHardwareDriverParams*)params)->dead_zone * (float)(t->timer_cfg.period_counts));
563 uint32_t duty_cycle_counts = (uint32_t)(dc_a * (float)(t->timer_cfg.period_counts));
564 bool hw_deadtime = ((RenesasHardwareDriverParams*)params)->channels[0] == ((RenesasHardwareDriverParams*)params)->channels[1];
565 uint32_t dt_act = (duty_cycle_counts>0 && !hw_deadtime)?dt:0;
566 _setSinglePhaseState(t, t1, phase_state[0]);
567 if (R_GPT_DutyCycleSet(&(t->ctrl), duty_cycle_counts - dt_act, t->duty_pin) != FSP_SUCCESS) {
568 // error
569 }
570 if (!hw_deadtime) {
571 if (R_GPT_DutyCycleSet(&(t1->ctrl), duty_cycle_counts + dt_act, t1->duty_pin) != FSP_SUCCESS) {
572 // error
573 }
574 }
575
576 t = ((RenesasHardwareDriverParams*)params)->timer_config[2];
577 t1 = ((RenesasHardwareDriverParams*)params)->timer_config[3];
578 duty_cycle_counts = (uint32_t)(dc_b * (float)(t->timer_cfg.period_counts));
579 hw_deadtime = ((RenesasHardwareDriverParams*)params)->channels[2] == ((RenesasHardwareDriverParams*)params)->channels[3];
580 dt_act = (duty_cycle_counts>0 && !hw_deadtime)?dt:0;
581 _setSinglePhaseState(t, t1, phase_state[1]);
582 if (R_GPT_DutyCycleSet(&(t->ctrl), duty_cycle_counts - dt_act, t->duty_pin) != FSP_SUCCESS) {
583 // error
584 }
585 if (!hw_deadtime) {
586 if (R_GPT_DutyCycleSet(&(t1->ctrl), duty_cycle_counts + dt_act, t1->duty_pin) != FSP_SUCCESS) {
587 // error
588 }
589 }
590
591 t = ((RenesasHardwareDriverParams*)params)->timer_config[4];
592 t1 = ((RenesasHardwareDriverParams*)params)->timer_config[5];
593 duty_cycle_counts = (uint32_t)(dc_c * (float)(t->timer_cfg.period_counts));
594 hw_deadtime = ((RenesasHardwareDriverParams*)params)->channels[4] == ((RenesasHardwareDriverParams*)params)->channels[5];
595 dt_act = (duty_cycle_counts>0 && !hw_deadtime)?dt:0;
596 _setSinglePhaseState(t, t1, phase_state[2]);
597 if (R_GPT_DutyCycleSet(&(t->ctrl), duty_cycle_counts, t->duty_pin) != FSP_SUCCESS) {
598 // error
599 }
600 if (!hw_deadtime) {
601 if (R_GPT_DutyCycleSet(&(t1->ctrl), duty_cycle_counts + dt_act, t1->duty_pin) != FSP_SUCCESS) {
602 // error
603 }
604 }
605
606}
607
608#endif
PhaseState
Definition FOCDriver.h:7
@ PHASE_HI
Definition FOCDriver.h:10
@ PHASE_ON
Definition FOCDriver.h:9
@ PHASE_LO
Definition FOCDriver.h:11
#define SIMPLEFOC_DEBUG(msg,...)
static void print(const char *msg)
static void println()
const int const int const int pinC
GenericCurrentSenseParams * params
#define SIMPLEFOC_PWM_ACTIVE_HIGH
void * _configure4PWM(long pwm_frequency, const int pin1A, const int pin1B, const int pin2A, const int pin2B)
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)
void * _configure2PWM(long pwm_frequency, const int pinA, const int pinB)
void _writeDutyCycle2PWM(float dc_a, float dc_b, void *params)
void _writeDutyCycle1PWM(float dc_a, void *params)
#define SIMPLEFOC_DRIVER_INIT_FAILED
void _writeDutyCycle4PWM(float dc_1a, float dc_1b, float dc_2a, float dc_2b, void *params)
void * _configure3PWM(long pwm_frequency, const int pinA, const int pinB, const int pinC)
#define SIMPLEFOC_PWM_LOWSIDE_ACTIVE_HIGH
void _writeDutyCycle6PWM(float dc_a, float dc_b, float dc_c, PhaseState *phase_state, void *params)
void * _configure1PWM(long pwm_frequency, const int pinA)
#define SIMPLEFOC_PWM_HIGHSIDE_ACTIVE_HIGH
void _writeDutyCycle3PWM(float dc_a, float dc_b, float dc_c, void *params)
float const int const int const int pinB_h
float const int const int const int const int pinB_l
const int const int pin1B
const int const int const int pin2A
float const int const int const int const int const int pinC_h
float float float dc_2b
float float PhaseState * phase_state
float const int const int const int const int const int const int pinC_l
float const int const int pinA_l
const int const int const int const int pin2B
#define NOT_SET
Definition foc_utils.h:34