SimpleFOClibrary 2.4.0
Loading...
Searching...
No Matches
drivers/hardware_specific/esp32/esp32_mcpwm_mcu.cpp
Go to the documentation of this file.
2
3#if defined(ESP_H) && defined(ARDUINO_ARCH_ESP32) && defined(SOC_MCPWM_SUPPORTED) && !defined(SIMPLEFOC_ESP32_USELEDC)
4
5#pragma message("")
6#pragma message("SimpleFOC: compiling for ESP32 MCPWM driver")
7#pragma message("")
8
9
10int esp32_gpio_nr(int pin) {
11 #if defined(BOARD_HAS_PIN_REMAP) && !defined(BOARD_USES_HW_GPIO_NUMBERS)
12 return digitalPinToGPIONumber(pin);
13 #else
14 return pin;
15 #endif
16}
17
18
19// function setting the high pwm frequency to the supplied pins
20// - DC motor - 1PWM setting
21// - hardware specific
22void* _configure1PWM(long pwm_frequency, const int pinA) {
23 if(!pwm_frequency || !_isset(pwm_frequency) ) pwm_frequency = _PWM_FREQUENCY; // default frequency 25hz
24 else pwm_frequency = _constrain(pwm_frequency, 0, _PWM_FREQUENCY_MAX); // constrain to 40kHz max
25
26 int group, timer;
27 if(!_findBestGroup(1, pwm_frequency, &group, &timer)) {
28 SIMPLEFOC_ESP32_DRV_DEBUG("Not enough pins available for 1PWM!");
30 }
31 SIMPLEFOC_ESP32_DRV_DEBUG("Configuring 1PWM in group: "+String(group)+" on timer: "+String(timer));
32 // configure the timer
33 int pins[1] = { esp32_gpio_nr(pinA) };
34 return _configurePinsMCPWM(pwm_frequency, group, timer, 1, pins);
35}
36
37
38// function setting the high pwm frequency to the supplied pins
39// - Stepper motor - 2PWM setting
40// - hardware specific
41void* _configure2PWM(long pwm_frequency, const int pinA, const int pinB) {
42 if(!pwm_frequency || !_isset(pwm_frequency) ) pwm_frequency = _PWM_FREQUENCY; // default frequency 25hz
43 else pwm_frequency = _constrain(pwm_frequency, 0, _PWM_FREQUENCY_MAX); // constrain to 40kHz max
44
45 int group, timer;
46 int ret = _findBestGroup(2, pwm_frequency, &group, &timer);
47 if(!ret) {
48 SIMPLEFOC_ESP32_DRV_DEBUG("Not enough pins available for 2PWM!");
50 }
51 if(ret == 1){
52 // configure the 2pwm on only one group
53 SIMPLEFOC_ESP32_DRV_DEBUG("Configuring 2PWM in group: "+String(group)+" on timer: "+String(timer));
54 // configure the timer
55 int pins[2] = { esp32_gpio_nr(pinA), esp32_gpio_nr(pinB) };
56 return _configurePinsMCPWM(pwm_frequency, group, timer, 2, pins);
57 }else{
58 SIMPLEFOC_ESP32_DRV_DEBUG("Configuring 2PWM as two 1PWM drivers");
59 ESP32MCPWMDriverParams* params[2];
60
61 // the code is a bit huge for what it does
62 // it just instantiates two 2PMW drivers and combines the returned params
63 int pins[2][1] = {{pinA}, {pinB}};
64 for(int i =0; i<2; i++){
65 int timer = _findLastTimer(i); //find last created timer in group i
66 SIMPLEFOC_ESP32_DRV_DEBUG("Configuring 1PWM in group: "+String(i)+" on timer: "+String(timer));
67 void* p = _configurePinsMCPWM(pwm_frequency, i, timer, 1, pins[i]);
69 SIMPLEFOC_ESP32_DRV_DEBUG("Error configuring 1PWM");
71 }else{
72 params[i] = (ESP32MCPWMDriverParams*)p;
73 }
74 }
75 // combine the driver parameters
76 ESP32MCPWMDriverParams* ret_params = new ESP32MCPWMDriverParams{
77 .pwm_frequency = params[0]->pwm_frequency,
78 .group_id = 2, // both groups
79 };
80 for(int i =0; i<2; i++){
81 ret_params->timers[i] = params[i]->timers[0];
82 ret_params->oper[i] = params[i]->oper[0];
83 ret_params->comparator[i] = params[i]->comparator[0];
84 ret_params->generator[i] = params[i]->generator[0];
85 }
86 ret_params->mcpwm_period = params[0]->mcpwm_period;
87 return ret_params;
88 }
89}
90
91// function setting the high pwm frequency to the supplied pins
92// - BLDC motor - 3PWM setting
93// - hardware specific
94void* _configure3PWM(long pwm_frequency, const int pinA, const int pinB, const int pinC) {
95 if(!pwm_frequency || !_isset(pwm_frequency) ) pwm_frequency = _PWM_FREQUENCY; // default frequency 25hz
96 else pwm_frequency = _constrain(pwm_frequency, 0, _PWM_FREQUENCY_MAX); // constrain to 40kHz max
97
98 int group, timer;
99 if(!_findBestGroup(3, pwm_frequency, &group, &timer)) {
100 SIMPLEFOC_ESP32_DRV_DEBUG("Not enough pins available for 3PWM!");
102 }
103 SIMPLEFOC_ESP32_DRV_DEBUG("Configuring 3PWM in group: "+String(group)+" on timer: "+String(timer));
104 // configure the timer
105 int pins[3] = { esp32_gpio_nr(pinA), esp32_gpio_nr(pinB), esp32_gpio_nr(pinC) };
106 return _configurePinsMCPWM(pwm_frequency, group, timer, 3, pins);
107}
108
109
110
111// function setting the high pwm frequency to the supplied pins
112// - Stepper motor - 4PWM setting
113// - hardware specific
114void* _configure4PWM(long pwm_frequency,const int pinA, const int pinB, const int pinC, const int pinD){
115 if(!pwm_frequency || !_isset(pwm_frequency) ) pwm_frequency = _PWM_FREQUENCY; // default frequency 25hz
116 else pwm_frequency = _constrain(pwm_frequency, 0, _PWM_FREQUENCY_MAX); // constrain to 40kHz max
117
118 int group, timer;
119 int ret = _findBestGroup(4, pwm_frequency, &group, &timer);
120 if(!ret) {
121 SIMPLEFOC_ESP32_DRV_DEBUG("Not enough pins available for 4PWM!");
123 }
124 if(ret == 1){
125 SIMPLEFOC_ESP32_DRV_DEBUG("Configuring 4PWM in group: "+String(group)+" on timer: "+String(timer));
126 // configure the timer
127 int pins[4] = {pinA, pinB, pinC, pinD};
128 return _configurePinsMCPWM(pwm_frequency, group, timer, 4, pins);
129 }else{
130 SIMPLEFOC_ESP32_DRV_DEBUG("Configuring 4PWM as two 2PWM drivers");
131 ESP32MCPWMDriverParams* params[2];
132
133 // the code is a bit huge for what it does
134 // it just instantiates two 2PMW drivers and combines the returned params
135 int pins[2][2] = {{ esp32_gpio_nr(pinA), esp32_gpio_nr(pinB) },{ esp32_gpio_nr(pinC), esp32_gpio_nr(pinD) }};
136 for(int i =0; i<2; i++){
137 int timer = _findNextTimer(i); //find next available timer in group i
138 SIMPLEFOC_ESP32_DRV_DEBUG("Configuring 2PWM in group: "+String(i)+" on timer: "+String(timer));
139 void* p = _configurePinsMCPWM(pwm_frequency, i, timer, 2, pins[i]);
141 SIMPLEFOC_ESP32_DRV_DEBUG("Error configuring 2PWM");
143 }else{
144 params[i] = (ESP32MCPWMDriverParams*)p;
145 }
146 }
147 // combine the driver parameters
148 ESP32MCPWMDriverParams* ret_params = new ESP32MCPWMDriverParams{
149 .pwm_frequency = params[0]->pwm_frequency,
150 .group_id = 2, // both groups
151 .timers = {params[0]->timers[0], params[1]->timers[0]},
152 .oper = {params[0]->oper[0], params[1]->oper[0]}
153 };
154 for(int i =0; i<4; i++){
155 ret_params->comparator[i] = params[(int)floor(i/2)]->comparator[i%2];
156 ret_params->generator[i] = params[(int)floor(i/2)]->generator[i%2];
157 }
158 ret_params->mcpwm_period = params[0]->mcpwm_period;
159 return ret_params;
160 }
161}
162
163
164void* _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){
165 if(!pwm_frequency || !_isset(pwm_frequency) ) pwm_frequency = _PWM_FREQUENCY; // default frequency 25hz
166 else pwm_frequency = _constrain(pwm_frequency, 0, _PWM_FREQUENCY_MAX); // constrain to 40kHz max
167
168 int group, timer;
169 if(!_findBestGroup(6, pwm_frequency, &group, &timer)) {
170 SIMPLEFOC_ESP32_DRV_DEBUG("Not enough pins available for 6PWM!");
172 }
173 SIMPLEFOC_ESP32_DRV_DEBUG("Configuring 6PWM in group: "+String(group)+" on timer: "+String(timer));
174 // configure the timer
175 int pins[6] = { esp32_gpio_nr(pinA_h), esp32_gpio_nr(pinA_l), esp32_gpio_nr(pinB_h), esp32_gpio_nr(pinB_l), esp32_gpio_nr(pinC_h), esp32_gpio_nr(pinC_l) };
176 return _configure6PWMPinsMCPWM(pwm_frequency, group, timer, dead_zone, pins);
177}
178
179// function setting the pwm duty cycle to the hardware
180// - BLDC motor - 3PWM setting
181void IRAM_ATTR _writeDutyCycle3PWM(float dc_a, float dc_b, float dc_c, void* params){
182 _setDutyCycle(((ESP32MCPWMDriverParams*)params)->comparator[0], ((ESP32MCPWMDriverParams*)params)->mcpwm_period, dc_a);
183 _setDutyCycle(((ESP32MCPWMDriverParams*)params)->comparator[1], ((ESP32MCPWMDriverParams*)params)->mcpwm_period, dc_b);
184 _setDutyCycle(((ESP32MCPWMDriverParams*)params)->comparator[2], ((ESP32MCPWMDriverParams*)params)->mcpwm_period, dc_c);
185}
186
187// function setting the pwm duty cycle to the hardware
188// - DCMotor -1PWM setting
189// - hardware specific
190void IRAM_ATTR _writeDutyCycle1PWM(float dc_a, void* params){
191 _setDutyCycle(((ESP32MCPWMDriverParams*)params)->comparator[0], ((ESP32MCPWMDriverParams*)params)->mcpwm_period, dc_a);
192}
193
194// function setting the pwm duty cycle to the hardware
195// - Stepper motor - 2PWM setting
196// - hardware specific
197void IRAM_ATTR _writeDutyCycle2PWM(float dc_a, float dc_b, void* params){
198 _setDutyCycle(((ESP32MCPWMDriverParams*)params)->comparator[0], ((ESP32MCPWMDriverParams*)params)->mcpwm_period, dc_a);
199 _setDutyCycle(((ESP32MCPWMDriverParams*)params)->comparator[1], ((ESP32MCPWMDriverParams*)params)->mcpwm_period, dc_b);
200}
201
202
203
204// function setting the pwm duty cycle to the hardware
205// - Stepper motor - 4PWM setting
206// - hardware specific
207void IRAM_ATTR _writeDutyCycle4PWM(float dc_1a, float dc_1b, float dc_2a, float dc_2b, void* params){
208 // se the PWM on the slot timers
209 _setDutyCycle(((ESP32MCPWMDriverParams*)params)->comparator[0], ((ESP32MCPWMDriverParams*)params)->mcpwm_period, dc_1a);
210 _setDutyCycle(((ESP32MCPWMDriverParams*)params)->comparator[1], ((ESP32MCPWMDriverParams*)params)->mcpwm_period, dc_1b);
211 _setDutyCycle(((ESP32MCPWMDriverParams*)params)->comparator[2], ((ESP32MCPWMDriverParams*)params)->mcpwm_period, dc_2a);
212 _setDutyCycle(((ESP32MCPWMDriverParams*)params)->comparator[3], ((ESP32MCPWMDriverParams*)params)->mcpwm_period, dc_2b);
213}
214
215void IRAM_ATTR _writeDutyCycle6PWM(float dc_a, float dc_b, float dc_c, PhaseState *phase_state, void* params){
216#if SIMPLEFOC_ESP32_HW_DEADTIME == true
217 _setDutyCycle(((ESP32MCPWMDriverParams*)params)->comparator[0], ((ESP32MCPWMDriverParams*)params)->mcpwm_period, dc_a);
218 _setDutyCycle(((ESP32MCPWMDriverParams*)params)->comparator[1], ((ESP32MCPWMDriverParams*)params)->mcpwm_period, dc_b);
219 _setDutyCycle(((ESP32MCPWMDriverParams*)params)->comparator[2], ((ESP32MCPWMDriverParams*)params)->mcpwm_period, dc_c);
220
221 // set the phase state
222 _forcePhaseState(((ESP32MCPWMDriverParams*)params)->generator[0], ((ESP32MCPWMDriverParams*)params)->generator[1], phase_state[0]);
223 _forcePhaseState(((ESP32MCPWMDriverParams*)params)->generator[2], ((ESP32MCPWMDriverParams*)params)->generator[3], phase_state[1]);
224 _forcePhaseState(((ESP32MCPWMDriverParams*)params)->generator[4], ((ESP32MCPWMDriverParams*)params)->generator[5], phase_state[2]);
225#else
226 uint32_t period = ((ESP32MCPWMDriverParams*)params)->mcpwm_period;
227 const float dead_zone = (float)((ESP32MCPWMDriverParams*)params)->dead_zone * 0.5f;
228 _setDutyCycle(((ESP32MCPWMDriverParams*)params)->comparator[0], period, (phase_state[0] == PHASE_ON || phase_state[0] == PHASE_HI) ? dc_a-dead_zone : 0.0f);
229 _setDutyCycle(((ESP32MCPWMDriverParams*)params)->comparator[1], period, (phase_state[0] == PHASE_ON || phase_state[0] == PHASE_LO) ? dc_a+dead_zone : 1.0f);
230 _setDutyCycle(((ESP32MCPWMDriverParams*)params)->comparator[2], period, (phase_state[1] == PHASE_ON || phase_state[1] == PHASE_HI) ? dc_b-dead_zone : 0.0f);
231 _setDutyCycle(((ESP32MCPWMDriverParams*)params)->comparator[3], period, (phase_state[1] == PHASE_ON || phase_state[1] == PHASE_LO) ? dc_b+dead_zone : 1.0f);
232 _setDutyCycle(((ESP32MCPWMDriverParams*)params)->comparator[4], period, (phase_state[2] == PHASE_ON || phase_state[2] == PHASE_HI) ? dc_c-dead_zone : 0.0f);
233 _setDutyCycle(((ESP32MCPWMDriverParams*)params)->comparator[5], period, (phase_state[2] == PHASE_ON || phase_state[2] == PHASE_LO) ? dc_c+dead_zone : 1.0f);
234#endif
235}
236#endif
PhaseState
Definition FOCDriver.h:7
@ PHASE_HI
Definition FOCDriver.h:10
@ PHASE_ON
Definition FOCDriver.h:9
@ PHASE_LO
Definition FOCDriver.h:11
const int const int const int pinC
GenericCurrentSenseParams * params
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)
void _writeDutyCycle6PWM(float dc_a, float dc_b, float dc_c, PhaseState *phase_state, void *params)
void * _configure1PWM(long pwm_frequency, const int pinA)
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
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
#define _isset(a)
Definition foc_utils.h:13
#define _constrain(amt, low, high)
Definition foc_utils.h:11